Merge from Chromium at DEPS revision 269336

This commit was generated by merge_to_master.py.

Change-Id: I8b9c77f10eccd2a8b4c7ce373ffda18568af54ff
diff --git a/.DEPS.git b/.DEPS.git
index 04c5cda..83f0cc8 100644
--- a/.DEPS.git
+++ b/.DEPS.git
@@ -11,14 +11,14 @@
     'git_url':
          'https://chromium.googlesource.com',
     'webkit_rev':
-         '@11503209e25606867bdcaef9b003158d908ae1ac',
+         '@546906cbbe7771e845e0bab3ed9964c9557713ab',
     'angle_revision':
          '74697cf2064c0a2c0d7e1b1b28db439286766a05'
 }
 
 deps = {
     'src/breakpad/src':
-        Var('git_url') + '/external/google-breakpad/src.git@f4743a3ad3f12a01e9dfffe4959c4485ffd16d38',
+        Var('git_url') + '/external/google-breakpad/src.git@c7c6e51faeb9c1e8fbe285a1b28a5039b345f139',
     'src/chrome/browser/resources/pdf/html_office':
         Var('git_url') + '/chromium/html-office-public.git@eeff97614f65e0578529490d44d412032c3d7359',
     'src/chrome/test/data/extensions/api_test/permissions/nacl_enabled/bin':
@@ -32,7 +32,7 @@
     'src/media/cdm/ppapi/api':
         Var('git_url') + '/chromium/cdm.git@53f0c537a5cc685663a51d4d8d7eb6b323a3e802',
     'src/native_client':
-        Var('git_url') + '/native_client/src/native_client.git@a8e0335f84de3580437486dfa02484c989abbced',
+        Var('git_url') + '/native_client/src/native_client.git@13e2807ca7bce13863985ffe2761577d056ab2ac',
     'src/sdch/open-vcdiff':
         Var('git_url') + '/external/open-vcdiff.git@438f2a5be6d809bc21611a94cd37bfc8c28ceb33',
     'src/testing/gmock':
@@ -52,7 +52,7 @@
     'src/third_party/brotli/src':
         Var('git_url') + '/external/font-compression-reference.git@0829e37293abc2523a1d2b0f4d68ff7b5fcd8e01',
     'src/third_party/cacheinvalidation/src':
-        Var('git_url') + '/external/google-cache-invalidation-api/src.git@6cd2fc3c3f3b3c95870be4696e642d4c3f051b59',
+        Var('git_url') + '/external/google-cache-invalidation-api/src.git@bf41949f62d571cae38acf525fbc552537c6e74b',
     'src/third_party/clang_format/script':
         Var('git_url') + '/chromium/llvm-project/cfe/tools/clang-format.git@385fc3379dc95b67d601b4384b16b1ec0bf12361',
     'src/third_party/cld_2/src':
@@ -72,7 +72,7 @@
     'src/third_party/jsoncpp/source/src/lib_json':
         Var('git_url') + '/external/jsoncpp/jsoncpp/src/lib_json.git@a8caa51ba2f80971a45880425bf2ae864a786784',
     'src/third_party/leveldatabase/src':
-        Var('git_url') + '/external/leveldb.git@e9c65d24cda587bd317127f104bd0d52e8eea952',
+        Var('git_url') + '/external/leveldb.git@3f77584eb3f9754bbb7079070873ece3f30a1e6b',
     'src/third_party/libaddressinput/src':
         Var('git_url') + '/external/libaddressinput.git@3f7d76be9f572d8fdf512f4e2085109bc32a6128',
     'src/third_party/libc++/trunk':
@@ -82,7 +82,7 @@
     'src/third_party/libexif/sources':
         Var('git_url') + '/chromium/deps/libexif/sources.git@ed98343daabd7b4497f97fda972e132e6877c48a',
     'src/third_party/libjingle/source/talk':
-        Var('git_url') + '/external/webrtc/trunk/talk.git@9ca9ff24f68ef3eacf070a72a27e830aaea06a06',
+        Var('git_url') + '/external/webrtc/trunk/talk.git@a12d6916209195faf8848ebc7e6c0050766023b2',
     'src/third_party/libjpeg_turbo':
         Var('git_url') + '/chromium/deps/libjpeg_turbo.git@3395bcc26e390d2960d15020d4a4d27ae0c122fe',
     'src/third_party/libphonenumber/src/phonenumbers':
@@ -94,7 +94,7 @@
     'src/third_party/libsrtp':
         Var('git_url') + '/chromium/deps/libsrtp.git@2f2e557b809dc1dd7977098ad354a540f04beb4e',
     'src/third_party/libvpx':
-        Var('git_url') + '/chromium/deps/libvpx.git@693441efe611de7ca09c00f4e79776f604b689f4',
+        Var('git_url') + '/chromium/deps/libvpx.git@5be267a803bbe61e0f4f1d5d878e02d3623182bc',
     'src/third_party/libwebm/source':
         Var('git_url') + '/webm/libwebm.git@fb6b6e64444c637f27d103fd113e0c7bf4f107dd',
     'src/third_party/libyuv':
@@ -104,7 +104,7 @@
     'src/third_party/openmax_dl':
         Var('git_url') + '/external/webrtc/deps/third_party/openmax.git@cf42f62aae8cb9c9e0ed021ee6985affbe118677',
     'src/third_party/openssl':
-        Var('git_url') + '/chromium/deps/openssl.git@4070d9b9a2afcda81d3e883bbf94cc1be51c095a',
+        Var('git_url') + '/chromium/deps/openssl.git@55b9eb8eb546355b3d55945cf09a45a434cd796f',
     'src/third_party/opus/src':
         Var('git_url') + '/chromium/deps/opus.git@36fa2621472ebf5b859fd16bbdb749019c68cc69',
     'src/third_party/ots':
@@ -120,11 +120,11 @@
     'src/third_party/sfntly/cpp/src':
         Var('git_url') + '/external/sfntly/cpp/src.git@8f090032dd4f8f8908f338cc73bb840b788377f2',
     'src/third_party/skia/gyp':
-        Var('git_url') + '/external/skia/gyp.git@ad64fe80988d6bd5b1467ecfab1341bc71aab706',
+        Var('git_url') + '/external/skia/gyp.git@961f4e74a20aa05ef5a89b548b29a43a2edb7f42',
     'src/third_party/skia/include':
-        Var('git_url') + '/external/skia/include.git@394ec1d498fc2f93a45c150aa8ad24bec26c3760',
+        Var('git_url') + '/external/skia/include.git@c7557fbeb626b286d27a1b46b93da5a030df12b3',
     'src/third_party/skia/src':
-        Var('git_url') + '/external/skia/src.git@214ebc7146494e97143f9bf0d2392655148d8dde',
+        Var('git_url') + '/external/skia/src.git@1ffcf188ba353bf82876a8d55a127ea6e1dcb27a',
     'src/third_party/smhasher/src':
         Var('git_url') + '/external/smhasher.git@e87738e57558e0ec472b2fc3a643b838e5b6e88f',
     'src/third_party/snappy/src':
@@ -134,17 +134,17 @@
     'src/third_party/swig/Lib':
         Var('git_url') + '/chromium/deps/swig/Lib.git@f2a695d52e61e6a8d967731434f165ed400f0d69',
     'src/third_party/trace-viewer':
-        Var('git_url') + '/external/trace-viewer.git@2cdaa9933db2f6475f96703082b99b5e71d091af',
+        Var('git_url') + '/external/trace-viewer.git@bb07e14730e9b9fc515d3e2697416f1d8fc676a3',
     'src/third_party/usrsctp/usrsctplib':
         Var('git_url') + '/external/usrsctplib.git@368d86efa422ae7e549399f8c35783c0e80232f0',
     'src/third_party/webdriver/pylib':
         Var('git_url') + '/external/selenium/py.git@8212c8017c92a1ba740caf01c1acefb3674a6a44',
     'src/third_party/webgl/src':
-        Var('git_url') + '/external/khronosgroup/webgl.git@8f445334c2f13a6be762fbdc90c4d80397d31788',
+        Var('git_url') + '/external/khronosgroup/webgl.git@1700aa98cc8bc494b305d4ec1045797bc4030f45',
     'src/third_party/webpagereplay':
         Var('git_url') + '/external/web-page-replay.git@1cf80576c1c4beb6185af0ac70eb7379c5e8262b',
     'src/third_party/webrtc':
-        Var('git_url') + '/external/webrtc/trunk/webrtc.git@cfed80f78803395dd066261afb5c5d99e5048d5d',
+        Var('git_url') + '/external/webrtc/trunk/webrtc.git@e1f0419756d58f744f902fe62fa31da126c55abe',
     'src/third_party/yasm/source/patched-yasm':
         Var('git_url') + '/chromium/deps/yasm/patched-yasm.git@c960eb11ccda80b10ed50be39df4f0663b371d1d',
     'src/tools/deps2git':
@@ -152,20 +152,20 @@
     'src/tools/grit':
         Var('git_url') + '/external/grit-i18n.git@1370f19146300b010e054e20bd733e183ba6f30e',
     'src/tools/gyp':
-        Var('git_url') + '/external/gyp.git@9a184eea4849278fd557627adcf48cb8e2ff9f67',
+        Var('git_url') + '/external/gyp.git@54538a15d434b2668b5f16a0bb3d7e7c5b934834',
     'src/tools/page_cycler/acid3':
         Var('git_url') + '/chromium/deps/acid3.git@6be0a66a1ebd7ebc5abc1b2f405a945f6d871521',
     'src/tools/swarming_client':
-        Var('git_url') + '/external/swarming.client.git@66c1861d7bd0ee72150d1f78ad4fb48e0e9cfde6',
+        Var('git_url') + '/external/swarming.client.git@ae8085b09e6162b4ec869e430d7d09c16b32b433',
     'src/v8':
-        Var('git_url') + '/external/v8.git@3484964a86451e86dcf04be9bd8c0d76ee04f081',
+        Var('git_url') + '/external/v8.git@af6f699b0be532b73bc2f6c9e1cf40a57fa7e234',
 }
 
 deps_os = {
     'android':
     {
         'src/third_party/android_tools':
-            Var('git_url') + '/android_tools.git@c9390198d02bf6f52b9a46b519badaf1c565261a',
+            Var('git_url') + '/android_tools.git@bf45c76e0eb23b7b7a9d5f26b28c16983daa173b',
         'src/third_party/aosp':
             Var('git_url') + '/chromium/deps/aosp.git@bbafe5155dff86bbba1e92b42a073ffcfcfbf28c',
         'src/third_party/apache-mime4j':
@@ -254,7 +254,7 @@
         'src/third_party/mesa/src':
             None,
         'src/third_party/nss':
-            Var('git_url') + '/chromium/deps/nss.git@f773fe9013d5c903305c826d3c4cde3d6cc2e158',
+            Var('git_url') + '/chromium/deps/nss.git@b94fa6ec8c1be165a514ea05ff380996c2cbdeb6',
         'src/third_party/openmax_dl':
             None,
         'src/third_party/opus/src':
@@ -303,7 +303,7 @@
         'src/third_party/lighttpd':
             Var('git_url') + '/chromium/deps/lighttpd.git@9dfa55d15937a688a92cbf2b7a8621b0927d06eb',
         'src/third_party/nss':
-            Var('git_url') + '/chromium/deps/nss.git@f773fe9013d5c903305c826d3c4cde3d6cc2e158',
+            Var('git_url') + '/chromium/deps/nss.git@b94fa6ec8c1be165a514ea05ff380996c2cbdeb6',
         'src/third_party/pdfsqueeze':
             Var('git_url') + '/external/pdfsqueeze.git@5936b871e6a087b7e50d4cbcb122378d8a07499f',
         'src/third_party/swig/mac':
@@ -316,7 +316,7 @@
         'src/third_party/chromite':
             Var('git_url') + '/chromiumos/chromite.git@63193a4393f6e964bfca992bfb03e40183554f7d',
         'src/third_party/cros_system_api':
-            Var('git_url') + '/chromiumos/platform/system_api.git@b35e305e2348af2be22b633cfb25e176601cb821',
+            Var('git_url') + '/chromiumos/platform/system_api.git@826b4567a5f3b01e2f52022759990dac56c14ea6',
         'src/third_party/fontconfig/src':
             Var('git_url') + '/external/fontconfig.git@f16c3118e25546c1b749f9823c51827a60aeb5c1',
         'src/third_party/freetype2/src':
@@ -353,7 +353,7 @@
         'src/third_party/nacl_sdk_binaries':
             Var('git_url') + '/chromium/deps/nacl_sdk_binaries.git@759dfca03bdc774da7ecbf974f6e2b84f43699a5',
         'src/third_party/nss':
-            Var('git_url') + '/chromium/deps/nss.git@f773fe9013d5c903305c826d3c4cde3d6cc2e158',
+            Var('git_url') + '/chromium/deps/nss.git@b94fa6ec8c1be165a514ea05ff380996c2cbdeb6',
         'src/third_party/pefile':
             Var('git_url') + '/external/pefile.git@1ceaa279daa62b71e3431e58f68be6a96dd1519a',
         'src/third_party/perl':
@@ -401,8 +401,8 @@
          [
     'python',
     'src/build/download_nacl_toolchains.py',
-    '--no-arm-trusted',
-    '--keep'
+    '--exclude',
+    'arm_trusted'
 ],
     'pattern':
          '.',
diff --git a/.gitignore b/.gitignore
index f9dc728..3fd0eb1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -229,6 +229,7 @@
 /third_party/chromeos_text_input
 /third_party/chromite
 /third_party/clang_format/bin/*/*
+/third_party/clang_format/script
 !/third_party/clang_format/bin/*/*.sha1
 /third_party/cld_2/src
 /third_party/cros
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index fbb7ddc..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,460 +0,0 @@
-[submodule "breakpad/src"]
-	path = breakpad/src
-	url = https://chromium.googlesource.com/external/google-breakpad/src.git
-	os = all
-[submodule "build/util/support"]
-	path = build/util/support
-	url = 
-	os = ios
-[submodule "chrome/browser/resources/pdf/html_office"]
-	path = chrome/browser/resources/pdf/html_office
-	url = https://chromium.googlesource.com/chromium/html-office-public.git
-	os = all
-[submodule "chrome/installer/mac/third_party/xz/xz"]
-	path = chrome/installer/mac/third_party/xz/xz
-	url = https://chromium.googlesource.com/chromium/deps/xz.git
-	os = mac
-[submodule "chrome/test/data/extensions/api_test/permissions/nacl_enabled/bin"]
-	path = chrome/test/data/extensions/api_test/permissions/nacl_enabled/bin
-	url = https://chromium.googlesource.com/native_client/src/native_client/tests/prebuilt.git
-	os = all
-[submodule "chrome/test/data/perf/canvas_bench"]
-	path = chrome/test/data/perf/canvas_bench
-	url = https://chromium.googlesource.com/chromium/canvas_bench.git
-	os = all
-[submodule "chrome/test/data/perf/frame_rate/content"]
-	path = chrome/test/data/perf/frame_rate/content
-	url = https://chromium.googlesource.com/chromium/frame_rate/content.git
-	os = all
-[submodule "chrome/test/data/perf/third_party/octane"]
-	path = chrome/test/data/perf/third_party/octane
-	url = https://chromium.googlesource.com/external/octane-benchmark.git
-	os = all
-[submodule "chrome/tools/test/reference_build/chrome_linux"]
-	path = chrome/tools/test/reference_build/chrome_linux
-	url = https://chromium.googlesource.com/chromium/reference_builds/chrome_linux64.git
-	os = unix
-[submodule "chrome/tools/test/reference_build/chrome_mac"]
-	path = chrome/tools/test/reference_build/chrome_mac
-	url = https://chromium.googlesource.com/chromium/reference_builds/chrome_mac.git
-	os = mac
-[submodule "chrome/tools/test/reference_build/chrome_win"]
-	path = chrome/tools/test/reference_build/chrome_win
-	url = https://chromium.googlesource.com/chromium/reference_builds/chrome_win.git
-	os = win
-[submodule "media/cdm/ppapi/api"]
-	path = media/cdm/ppapi/api
-	url = https://chromium.googlesource.com/chromium/cdm.git
-	os = all
-[submodule "native_client"]
-	path = native_client
-	url = https://chromium.googlesource.com/native_client/src/native_client.git
-	os = all
-[submodule "sdch/open-vcdiff"]
-	path = sdch/open-vcdiff
-	url = https://chromium.googlesource.com/external/open-vcdiff.git
-	os = all
-[submodule "testing/gmock"]
-	path = testing/gmock
-	url = https://chromium.googlesource.com/external/googlemock.git
-	os = all
-[submodule "testing/gtest"]
-	path = testing/gtest
-	url = https://chromium.googlesource.com/external/googletest.git
-	os = all
-[submodule "testing/iossim/third_party/class-dump"]
-	path = testing/iossim/third_party/class-dump
-	url = https://chromium.googlesource.com/chromium/deps/class-dump.git
-	os = ios
-[submodule "third_party/WebKit"]
-	path = third_party/WebKit
-	url = https://chromium.googlesource.com/chromium/blink.git
-	os = all
-[submodule "third_party/android_tools"]
-	path = third_party/android_tools
-	url = https://chromium.googlesource.com/android_tools.git
-	os = android
-[submodule "third_party/angle"]
-	path = third_party/angle
-	url = https://chromium.googlesource.com/angle/angle.git
-	os = all
-[submodule "third_party/aosp"]
-	path = third_party/aosp
-	url = https://chromium.googlesource.com/chromium/deps/aosp.git
-	os = android
-[submodule "third_party/apache-mime4j"]
-	path = third_party/apache-mime4j
-	url = https://chromium.googlesource.com/chromium/deps/apache-mime4j.git
-	os = android
-[submodule "third_party/bidichecker"]
-	path = third_party/bidichecker
-	url = https://chromium.googlesource.com/external/bidichecker/lib.git
-	os = all
-[submodule "third_party/bison"]
-	path = third_party/bison
-	url = https://chromium.googlesource.com/chromium/deps/bison.git
-	os = win
-[submodule "third_party/brotli/src"]
-	path = third_party/brotli/src
-	url = https://chromium.googlesource.com/external/font-compression-reference.git
-	os = all
-[submodule "third_party/cacheinvalidation/src"]
-	path = third_party/cacheinvalidation/src
-	url = https://chromium.googlesource.com/external/google-cache-invalidation-api/src.git
-	os = all
-[submodule "third_party/chromite"]
-	path = third_party/chromite
-	url = https://chromium.googlesource.com/chromiumos/chromite.git
-	os = unix
-[submodule "third_party/clang_format/script"]
-	path = third_party/clang_format/script
-	url = https://chromium.googlesource.com/chromium/llvm-project/cfe/tools/clang-format.git
-	os = all
-[submodule "third_party/cld_2/src"]
-	path = third_party/cld_2/src
-	url = https://chromium.googlesource.com/external/cld2.git
-	os = all
-[submodule "third_party/cros_system_api"]
-	path = third_party/cros_system_api
-	url = https://chromium.googlesource.com/chromiumos/platform/system_api.git
-	os = unix
-[submodule "third_party/cygwin"]
-	path = third_party/cygwin
-	url = https://chromium.googlesource.com/chromium/deps/cygwin.git
-	os = win
-[submodule "third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille"]
-	path = third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille
-	url = https://chromium.googlesource.com/external/eyes-free/braille/client/src/com/googlecode/eyesfree/braille.git
-	os = android
-[submodule "third_party/ffmpeg"]
-	path = third_party/ffmpeg
-	url = https://chromium.googlesource.com/chromium/third_party/ffmpeg.git
-	os = all
-[submodule "third_party/findbugs"]
-	path = third_party/findbugs
-	url = https://chromium.googlesource.com/chromium/deps/findbugs.git
-	os = android
-[submodule "third_party/flac"]
-	path = third_party/flac
-	url = https://chromium.googlesource.com/chromium/deps/flac.git
-	os = all
-[submodule "third_party/fontconfig/src"]
-	path = third_party/fontconfig/src
-	url = https://chromium.googlesource.com/external/fontconfig.git
-	os = unix
-[submodule "third_party/freetype"]
-	path = third_party/freetype
-	url = https://chromium.googlesource.com/chromium/src/third_party/freetype.git
-	os = android
-[submodule "third_party/freetype2/src"]
-	path = third_party/freetype2/src
-	url = https://chromium.googlesource.com/chromium/src/third_party/freetype2.git
-	os = unix
-[submodule "third_party/gnu_binutils"]
-	path = third_party/gnu_binutils
-	url = https://chromium.googlesource.com/native_client/deps/third_party/gnu_binutils.git
-	os = win
-[submodule "third_party/google_toolbox_for_mac/src"]
-	path = third_party/google_toolbox_for_mac/src
-	url = https://chromium.googlesource.com/external/google-toolbox-for-mac.git
-	os = ios,mac
-[submodule "third_party/gperf"]
-	path = third_party/gperf
-	url = https://chromium.googlesource.com/chromium/deps/gperf.git
-	os = win
-[submodule "third_party/guava/src"]
-	path = third_party/guava/src
-	url = https://chromium.googlesource.com/external/guava-libraries.git
-	os = android
-[submodule "third_party/httpcomponents-client"]
-	path = third_party/httpcomponents-client
-	url = https://chromium.googlesource.com/chromium/deps/httpcomponents-client.git
-	os = android
-[submodule "third_party/httpcomponents-core"]
-	path = third_party/httpcomponents-core
-	url = https://chromium.googlesource.com/chromium/deps/httpcomponents-core.git
-	os = android
-[submodule "third_party/hunspell"]
-	path = third_party/hunspell
-	url = https://chromium.googlesource.com/chromium/deps/hunspell.git
-	os = all
-[submodule "third_party/hunspell_dictionaries"]
-	path = third_party/hunspell_dictionaries
-	url = https://chromium.googlesource.com/chromium/deps/hunspell_dictionaries.git
-	os = all
-[submodule "third_party/icu"]
-	path = third_party/icu
-	url = https://chromium.googlesource.com/chromium/deps/icu46.git
-	os = all
-[submodule "third_party/jarjar"]
-	path = third_party/jarjar
-	url = https://chromium.googlesource.com/chromium/deps/jarjar.git
-	os = android
-[submodule "third_party/jsoncpp/source/include"]
-	path = third_party/jsoncpp/source/include
-	url = https://chromium.googlesource.com/external/jsoncpp/jsoncpp/include.git
-	os = all
-[submodule "third_party/jsoncpp/source/src/lib_json"]
-	path = third_party/jsoncpp/source/src/lib_json
-	url = https://chromium.googlesource.com/external/jsoncpp/jsoncpp/src/lib_json.git
-	os = all
-[submodule "third_party/jsr-305/src"]
-	path = third_party/jsr-305/src
-	url = https://chromium.googlesource.com/external/jsr-305.git
-	os = android
-[submodule "third_party/leveldatabase/src"]
-	path = third_party/leveldatabase/src
-	url = https://chromium.googlesource.com/external/leveldb.git
-	os = all
-[submodule "third_party/libaddressinput/src"]
-	path = third_party/libaddressinput/src
-	url = https://chromium.googlesource.com/external/libaddressinput.git
-	os = all
-[submodule "third_party/libc++/trunk"]
-	path = third_party/libc++/trunk
-	url = https://chromium.googlesource.com/chromium/llvm-project/libcxx.git
-	os = all
-[submodule "third_party/libc++abi/trunk"]
-	path = third_party/libc++abi/trunk
-	url = https://chromium.googlesource.com/chromium/llvm-project/libcxxabi.git
-	os = all
-[submodule "third_party/libexif/sources"]
-	path = third_party/libexif/sources
-	url = https://chromium.googlesource.com/chromium/deps/libexif/sources.git
-	os = all
-[submodule "third_party/libjingle/source/talk"]
-	path = third_party/libjingle/source/talk
-	url = https://chromium.googlesource.com/external/webrtc/trunk/talk.git
-	os = all
-[submodule "third_party/libjpeg_turbo"]
-	path = third_party/libjpeg_turbo
-	url = https://chromium.googlesource.com/chromium/deps/libjpeg_turbo.git
-	os = all
-[submodule "third_party/liblouis/src"]
-	path = third_party/liblouis/src
-	url = https://chromium.googlesource.com/external/liblouis.git
-	os = unix
-[submodule "third_party/libphonenumber/src/phonenumbers"]
-	path = third_party/libphonenumber/src/phonenumbers
-	url = https://chromium.googlesource.com/external/libphonenumber/cpp/src/phonenumbers.git
-	os = all
-[submodule "third_party/libphonenumber/src/resources"]
-	path = third_party/libphonenumber/src/resources
-	url = https://chromium.googlesource.com/external/libphonenumber/resources.git
-	os = all
-[submodule "third_party/libphonenumber/src/test"]
-	path = third_party/libphonenumber/src/test
-	url = https://chromium.googlesource.com/external/libphonenumber/cpp/test.git
-	os = all
-[submodule "third_party/libsrtp"]
-	path = third_party/libsrtp
-	url = https://chromium.googlesource.com/chromium/deps/libsrtp.git
-	os = all
-[submodule "third_party/libvpx"]
-	path = third_party/libvpx
-	url = https://chromium.googlesource.com/chromium/deps/libvpx.git
-	os = all
-[submodule "third_party/libwebm/source"]
-	path = third_party/libwebm/source
-	url = https://chromium.googlesource.com/webm/libwebm.git
-	os = all
-[submodule "third_party/libyuv"]
-	path = third_party/libyuv
-	url = https://chromium.googlesource.com/external/libyuv.git
-	os = all
-[submodule "third_party/lighttpd"]
-	path = third_party/lighttpd
-	url = https://chromium.googlesource.com/chromium/deps/lighttpd.git
-	os = win,mac
-[submodule "third_party/lss"]
-	path = third_party/lss
-	url = https://chromium.googlesource.com/external/linux-syscall-support/lss.git
-	os = android,unix
-[submodule "third_party/mesa/src"]
-	path = third_party/mesa/src
-	url = https://chromium.googlesource.com/chromium/deps/mesa.git
-	os = all
-[submodule "third_party/mingw-w64/mingw/bin"]
-	path = third_party/mingw-w64/mingw/bin
-	url = https://chromium.googlesource.com/native_client/deps/third_party/mingw-w64/mingw/bin.git
-	os = win
-[submodule "third_party/nacl_sdk_binaries"]
-	path = third_party/nacl_sdk_binaries
-	url = https://chromium.googlesource.com/chromium/deps/nacl_sdk_binaries.git
-	os = win
-[submodule "third_party/nss"]
-	path = third_party/nss
-	url = https://chromium.googlesource.com/chromium/deps/nss.git
-	os = win,ios,mac
-[submodule "third_party/openmax_dl"]
-	path = third_party/openmax_dl
-	url = https://chromium.googlesource.com/external/webrtc/deps/third_party/openmax.git
-	os = all
-[submodule "third_party/openssl"]
-	path = third_party/openssl
-	url = https://chromium.googlesource.com/chromium/deps/openssl.git
-	os = all
-[submodule "third_party/opus/src"]
-	path = third_party/opus/src
-	url = https://chromium.googlesource.com/chromium/deps/opus.git
-	os = all
-[submodule "third_party/ots"]
-	path = third_party/ots
-	url = https://chromium.googlesource.com/external/ots.git
-	os = all
-[submodule "third_party/pdfsqueeze"]
-	path = third_party/pdfsqueeze
-	url = https://chromium.googlesource.com/external/pdfsqueeze.git
-	os = mac
-[submodule "third_party/pefile"]
-	path = third_party/pefile
-	url = https://chromium.googlesource.com/external/pefile.git
-	os = win
-[submodule "third_party/perl"]
-	path = third_party/perl
-	url = https://chromium.googlesource.com/chromium/deps/perl.git
-	os = win
-[submodule "third_party/psyco_win32"]
-	path = third_party/psyco_win32
-	url = https://chromium.googlesource.com/chromium/deps/psyco_win32.git
-	os = win
-[submodule "third_party/pyelftools"]
-	path = third_party/pyelftools
-	url = https://chromium.googlesource.com/chromiumos/third_party/pyelftools.git
-	os = unix
-[submodule "third_party/pyftpdlib/src"]
-	path = third_party/pyftpdlib/src
-	url = https://chromium.googlesource.com/external/pyftpdlib.git
-	os = all
-[submodule "third_party/pymox/src"]
-	path = third_party/pymox/src
-	url = 
-	os = ios
-[submodule "third_party/pywebsocket/src"]
-	path = third_party/pywebsocket/src
-	url = https://chromium.googlesource.com/external/pywebsocket/src.git
-	os = all
-[submodule "third_party/safe_browsing/testing"]
-	path = third_party/safe_browsing/testing
-	url = https://chromium.googlesource.com/external/google-safe-browsing/testing.git
-	os = all
-[submodule "third_party/scons-2.0.1"]
-	path = third_party/scons-2.0.1
-	url = https://chromium.googlesource.com/native_client/src/third_party/scons-2.0.1.git
-	os = all
-[submodule "third_party/sfntly/cpp/src"]
-	path = third_party/sfntly/cpp/src
-	url = https://chromium.googlesource.com/external/sfntly/cpp/src.git
-	os = all
-[submodule "third_party/skia/gyp"]
-	path = third_party/skia/gyp
-	url = https://chromium.googlesource.com/external/skia/gyp.git
-	os = all
-[submodule "third_party/skia/include"]
-	path = third_party/skia/include
-	url = https://chromium.googlesource.com/external/skia/include.git
-	os = all
-[submodule "third_party/skia/src"]
-	path = third_party/skia/src
-	url = https://chromium.googlesource.com/external/skia/src.git
-	os = all
-[submodule "third_party/smhasher/src"]
-	path = third_party/smhasher/src
-	url = https://chromium.googlesource.com/external/smhasher.git
-	os = all
-[submodule "third_party/snappy/src"]
-	path = third_party/snappy/src
-	url = https://chromium.googlesource.com/external/snappy.git
-	os = all
-[submodule "third_party/speex"]
-	path = third_party/speex
-	url = https://chromium.googlesource.com/chromium/deps/speex.git
-	os = all
-[submodule "third_party/swig/Lib"]
-	path = third_party/swig/Lib
-	url = https://chromium.googlesource.com/chromium/deps/swig/Lib.git
-	os = all
-[submodule "third_party/swig/linux"]
-	path = third_party/swig/linux
-	url = https://chromium.googlesource.com/chromium/deps/swig/linux.git
-	os = unix
-[submodule "third_party/swig/mac"]
-	path = third_party/swig/mac
-	url = https://chromium.googlesource.com/chromium/deps/swig/mac.git
-	os = mac
-[submodule "third_party/swig/win"]
-	path = third_party/swig/win
-	url = https://chromium.googlesource.com/chromium/deps/swig/win.git
-	os = win
-[submodule "third_party/syzygy/binaries"]
-	path = third_party/syzygy/binaries
-	url = https://chromium.googlesource.com/external/sawbuck/syzygy/binaries.git
-	os = win
-[submodule "third_party/trace-viewer"]
-	path = third_party/trace-viewer
-	url = https://chromium.googlesource.com/external/trace-viewer.git
-	os = all
-[submodule "third_party/undoview"]
-	path = third_party/undoview
-	url = https://chromium.googlesource.com/chromium/deps/undoview.git
-	os = unix
-[submodule "third_party/usrsctp/usrsctplib"]
-	path = third_party/usrsctp/usrsctplib
-	url = https://chromium.googlesource.com/external/usrsctplib.git
-	os = all
-[submodule "third_party/v8-i18n"]
-	path = third_party/v8-i18n
-	url = 
-	os = ios
-[submodule "third_party/webdriver/pylib"]
-	path = third_party/webdriver/pylib
-	url = https://chromium.googlesource.com/external/selenium/py.git
-	os = all
-[submodule "third_party/webgl"]
-	path = third_party/webgl
-	url = 
-	os = ios
-[submodule "third_party/webpagereplay"]
-	path = third_party/webpagereplay
-	url = https://chromium.googlesource.com/external/web-page-replay.git
-	os = all
-[submodule "third_party/webrtc"]
-	path = third_party/webrtc
-	url = https://chromium.googlesource.com/external/webrtc/trunk/webrtc.git
-	os = all
-[submodule "third_party/xdg-utils"]
-	path = third_party/xdg-utils
-	url = https://chromium.googlesource.com/chromium/deps/xdg-utils.git
-	os = unix
-[submodule "third_party/yasm/binaries"]
-	path = third_party/yasm/binaries
-	url = https://chromium.googlesource.com/chromium/deps/yasm/binaries.git
-	os = win
-[submodule "third_party/yasm/source/patched-yasm"]
-	path = third_party/yasm/source/patched-yasm
-	url = https://chromium.googlesource.com/chromium/deps/yasm/patched-yasm.git
-	os = all
-[submodule "tools/deps2git"]
-	path = tools/deps2git
-	url = https://chromium.googlesource.com/chromium/tools/deps2git.git
-	os = all
-[submodule "tools/grit"]
-	path = tools/grit
-	url = https://chromium.googlesource.com/external/grit-i18n.git
-	os = all
-[submodule "tools/gyp"]
-	path = tools/gyp
-	url = https://chromium.googlesource.com/external/gyp.git
-	os = all
-[submodule "tools/page_cycler/acid3"]
-	path = tools/page_cycler/acid3
-	url = https://chromium.googlesource.com/chromium/deps/acid3.git
-	os = all
-[submodule "tools/swarming_client"]
-	path = tools/swarming_client
-	url = https://chromium.googlesource.com/external/swarming.client.git
-	os = all
-[submodule "v8"]
-	path = v8
-	url = https://chromium.googlesource.com/external/v8.git
-	os = all
diff --git a/AUTHORS b/AUTHORS
index cae11d1..22a8488 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -16,6 +16,7 @@
 Adenilson Cavalcanti <a.cavalcanti@partner.samsung.com>
 Aditya Bhargava <heuristicist@gmail.com>
 Ajay Berwal <ajay.berwal@samsung.com>
+Ajith Kumar V <ajith.v@samsung.com>
 Alex Gartrell <agartrell@cmu.edu>
 Alex Scheele <alexscheele@gmail.com>
 Alexander Sulfrian <alexander@sulfrian.net>
@@ -35,9 +36,11 @@
 Andrew Tulloch <andrew@tullo.ch>
 Anish Patankar <anish.p@samsung.com>
 Antonio Gomes <a1.gomes@sisa.samsung.com>
+Arnaud Renevier <a.renevier@samsung.com>
 Arthur Lussos <developer0420@gmail.com>
 Arun Mankuzhi <arun.m@samsung.com>
 Arunprasad Rajkumar <ararunprasad@gmail.com>
+Attila Dusnoki <dati91@gmail.com>
 Avinaash Doreswamy <avi.nitk@samsung.com>
 Balazs Kelemen <b.kelemen@samsung.com>
 Behara Mani Shyam Patro <behara.ms@samsung.com>
@@ -55,11 +58,13 @@
 Bryan Donlan <bdonlan@gmail.com>
 Byungwoo Lee <bw80.lee@samsung.com>
 Caio Marcelo de Oliveira Filho <caio.de.oliveira.filho@intel.com>
+Caitlin Potter <caitpotter88@gmail.com>
 Catalin Badea <badea@adobe.com>
 Cem Kocagil <cem.kocagil@gmail.com>
 Chamal De Silva <chamalsl@yahoo.com>
 Chandra Shekar Vallala <brk376@motorola.com>
 Chang Shu <c.shu@samsung.com>
+ChangSeok Oh <shivamidow@gmail.com>
 Changbin Shao <changbin.shao@intel.com>
 Chaobin Zhang <zhchbin@gmail.com>
 Chris Harrelson <chrishtr@gmail.com>
@@ -150,6 +155,7 @@
 Jeado Ko <haibane84@gmail.com>
 Jesse Miller <jesse@jmiller.biz>
 Jesus Sanchez-Palencia <jesus.sanchez-palencia.fernandez.fil@intel.com>
+Jie Chen <jie.a.chen@intel.com>
 Jin Yang <jin.a.yang@intel.com>
 Jincheol Jo <jincheol.jo@navercorp.com>
 Jingwei Liu <kingweiliu@gmail.com>
@@ -220,6 +226,7 @@
 Max Perepelitsyn <pph34r@gmail.com>
 Max Vujovic <mvujovic@adobe.com>
 Michael Gilbert <floppymaster@gmail.com>
+Michael Schechter <mike.schechter@gmail.com>
 Michael Zugelder <michael@zugelder.org>
 Mihai Maerean <mmaerean@adobe.com>
 Mihai Tica <mihai.o.tica@gmail.com>
@@ -313,6 +320,7 @@
 Sean Bryant <sean@cyberwang.net>
 Seo Sanghyeon <sanxiyn@gmail.com>
 Seokju Kwon <seokju.kwon@gmail.com>
+Sergey Putilin <p.sergey@samsung.com>
 Sergio Carlos Morales Angeles <carloschilazo@gmail.com>
 Sergiy Byelozyorov <rryk.ua@gmail.com>
 Seshadri Mahalingam <seshadri.mahalingam@gmail.com>
diff --git a/BUILD.gn b/BUILD.gn
index b83fe92..beadcbc 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -49,6 +49,7 @@
     "//third_party/smhasher:pmurhash",
     "//third_party/WebKit/Source/wtf",
     "//third_party/zlib",
+    "//third_party:jpeg",
     "//tools/gn",
     "//ui/base:ui_base",
     "//ui/base/strings",
@@ -56,7 +57,6 @@
     "//ui/gfx",
     "//ui/resources",
     "//url",
-    "//v8:v8_base",
   ]
 
   if (is_linux) {
diff --git a/DEPS b/DEPS
index 74d4ea5..347f80a 100644
--- a/DEPS
+++ b/DEPS
@@ -23,19 +23,19 @@
   "libcxxabi_revision": "206024",
   "webkit_trunk": "http://src.chromium.org/blink/trunk",
   "nacl_trunk": "http://src.chromium.org/native_client/trunk",
-  "webkit_revision": "173042",
+  "webkit_revision": "173743",
   "chromium_git": "https://chromium.googlesource.com",
   "chromiumos_git": "https://chromium.googlesource.com/chromiumos",
   "skia_git": "https://skia.googlesource.com",
   "swig_revision": "230490",
-  "nacl_revision": "13106",
+  "nacl_revision": "13159",
   # After changing nacl_revision, run 'glient sync' and check native_client/DEPS
   # to update other nacl_*_revision's.
   "nacl_tools_revision": "13077",  # native_client/DEPS: tools_rev
   "google_toolbox_for_mac_revision": "662",
   "libaddressinput_revision": "176",
   "libphonenumber_revision": "621",
-  "libvpx_revision": "265970",
+  "libvpx_revision": "269083",
   "lss_revision": "26",
 
   # These two FFmpeg variables must be updated together.  One is used for SVN
@@ -45,27 +45,27 @@
 
   "sfntly_revision": "228",
   "lighttpd_revision": "33737",
-  "skia_revision": "14458",
-  "skia_hash": "6b127cd2b1b2cb4ab5ef995f2f8f937b24f6d682",
+  "skia_revision": "14592",
+  "skia_hash": "24f6e29fc133f1082c73e2a96f30bee92e3123aa",
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and V8 without interference from each other.
   "v8_branch": "trunk",
-  "v8_revision": "21064",
+  "v8_revision": "21152",
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling WebRTC
   # and V8 without interference from each other.
-  "webrtc_revision": "6029",
+  "webrtc_revision": "6085",
   "jsoncpp_revision": "248",
-  "nss_revision": "266724",
+  "nss_revision": "267366",
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
-  "swarming_revision": "66c1861d7bd0ee72150d1f78ad4fb48e0e9cfde6",
+  "swarming_revision": "ae8085b09e6162b4ec869e430d7d09c16b32b433",
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openssl
   # and whatever else without interference from each other.
-  "openssl_revision": "266682",
+  "openssl_revision": "267674",
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
@@ -74,7 +74,7 @@
 
 deps = {
   "src/breakpad/src":
-    (Var("googlecode_url") % "google-breakpad") + "/trunk/src@1322",
+    (Var("googlecode_url") % "google-breakpad") + "/trunk/src@1325",
 
   "src/sdch/open-vcdiff":
     (Var("googlecode_url") % "open-vcdiff") + "/trunk@42",
@@ -89,7 +89,7 @@
     Var("chromium_git") + "/angle/angle.git@" + Var("angle_revision"),
 
   "src/third_party/trace-viewer":
-    (Var("googlecode_url") % "trace-viewer") + "/trunk@1266",
+    (Var("googlecode_url") % "trace-viewer") + "/trunk@1267",
 
   "src/third_party/WebKit":
     Var("webkit_trunk") + "@" + Var("webkit_revision"),
@@ -119,10 +119,10 @@
 
   "src/third_party/cacheinvalidation/src":
     (Var("googlecode_url") % "google-cache-invalidation-api") +
-    "/trunk/src@330",
+    "/trunk/src@331",
 
   "src/third_party/leveldatabase/src":
-    (Var("googlecode_url") % "leveldb") + "/trunk@79",
+    (Var("googlecode_url") % "leveldb") + "/trunk@80",
 
   "src/third_party/libc++/trunk":
     Var("llvm_url") + "/libcxx/trunk@" + Var("libcxx_revision"),
@@ -137,7 +137,7 @@
     (Var("googlecode_url") % "grit-i18n") + "/trunk@167",
 
   "src/tools/gyp":
-    (Var("googlecode_url") % "gyp") + "/trunk@1895",
+    (Var("googlecode_url") % "gyp") + "/trunk@1918",
 
   "src/tools/swarming_client":
     Var("chromium_git") + "/external/swarming.client.git@" +
@@ -191,7 +191,7 @@
 
   "src/third_party/webgl/src":
     Var("chromium_git") +
-    "/external/khronosgroup/webgl.git@8f445334c2f13a6be762fbdc90c4d80397d31788",
+    "/external/khronosgroup/webgl.git@1700aa98cc8bc494b305d4ec1045797bc4030f45",
 
   "src/third_party/swig/Lib":
     "/trunk/deps/third_party/swig/Lib@" + Var("swig_revision"),
@@ -469,7 +469,7 @@
     # For Linux and Chromium OS.
     "src/third_party/cros_system_api":
       Var("chromiumos_git") + "/platform/system_api.git" +
-      "@b35e305e2348af2be22b633cfb25e176601cb821",
+      "@826b4567a5f3b01e2f52022759990dac56c14ea6",
 
     # Note that this is different from Android's freetype repo.
     "src/third_party/freetype2/src":
@@ -501,7 +501,7 @@
   "android": {
     "src/third_party/android_tools":
       Var("chromium_git") + "/android_tools.git" +
-      "@c9390198d02bf6f52b9a46b519badaf1c565261a",
+      "@bf45c76e0eb23b7b7a9d5f26b28c16983daa173b",
 
     "src/third_party/aosp":
       "/trunk/deps/third_party/aosp@148330",
@@ -588,8 +588,7 @@
     "pattern": ".",
     "action": [
         "python", "src/build/download_nacl_toolchains.py",
-         "--no-arm-trusted",
-         "--keep",
+        "--exclude", "arm_trusted",
     ],
   },
   {
diff --git a/GypAndroid.darwin-arm.mk b/GypAndroid.darwin-arm.mk
index 6d27de3..ddaf990 100644
--- a/GypAndroid.darwin-arm.mk
+++ b/GypAndroid.darwin-arm.mk
@@ -31,8 +31,13 @@
 include $(LOCAL_PATH)/components/autofill_core_common.target.darwin-arm.mk
 include $(LOCAL_PATH)/components/autofill_jni_headers.target.darwin-arm.mk
 include $(LOCAL_PATH)/components/autofill_regexes.target.darwin-arm.mk
+include $(LOCAL_PATH)/components/cdm_browser.target.darwin-arm.mk
+include $(LOCAL_PATH)/components/cdm_common.target.darwin-arm.mk
+include $(LOCAL_PATH)/components/cdm_renderer.target.darwin-arm.mk
 include $(LOCAL_PATH)/components/components_resources.target.darwin-arm.mk
 include $(LOCAL_PATH)/components/components_strings.target.darwin-arm.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_browser.target.darwin-arm.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_common.target.darwin-arm.mk
 include $(LOCAL_PATH)/components/navigation_interception.target.darwin-arm.mk
 include $(LOCAL_PATH)/components/navigation_interception_jni_headers.target.darwin-arm.mk
 include $(LOCAL_PATH)/components/os_crypt.target.darwin-arm.mk
@@ -165,11 +170,13 @@
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_resources_module.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_script_formatter_worker_module.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_search_module.target.darwin-arm.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_settings_module.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_source_frame_module.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_sources_module.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_temp_storage_shared_worker_module.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_timeline_module.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_devtools_css.target.darwin-arm.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_module_descriptors.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_extension_api.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_frontend_resources.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_html.target.darwin-arm.mk
@@ -192,8 +199,10 @@
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_minimal.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_skia_config.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/angle/src/commit_id.target.darwin-arm.mk
+include $(LOCAL_PATH)/third_party/angle/src/copy_scripts.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/angle/src/preprocessor.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/angle/src/translator.target.darwin-arm.mk
+include $(LOCAL_PATH)/third_party/angle/src/translator_lib.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/ashmem/ashmem.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/brotli/brotli.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/expat/expat.target.darwin-arm.mk
@@ -241,6 +250,8 @@
 include $(LOCAL_PATH)/third_party/mesa/mesa_headers.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/modp_b64/modp_b64.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/npapi/npapi.target.darwin-arm.mk
+include $(LOCAL_PATH)/third_party/openmax_dl/dl/openmax_dl.target.darwin-arm.mk
+include $(LOCAL_PATH)/third_party/openmax_dl/dl/openmax_dl_armv7.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/openssl/openssl.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/opus/opus.target.darwin-arm.mk
 include $(LOCAL_PATH)/third_party/ots/ots.target.darwin-arm.mk
diff --git a/GypAndroid.darwin-arm64.mk b/GypAndroid.darwin-arm64.mk
index 5325d69..db2237f 100644
--- a/GypAndroid.darwin-arm64.mk
+++ b/GypAndroid.darwin-arm64.mk
@@ -31,8 +31,13 @@
 include $(LOCAL_PATH)/components/autofill_core_common.target.darwin-arm64.mk
 include $(LOCAL_PATH)/components/autofill_jni_headers.target.darwin-arm64.mk
 include $(LOCAL_PATH)/components/autofill_regexes.target.darwin-arm64.mk
+include $(LOCAL_PATH)/components/cdm_browser.target.darwin-arm64.mk
+include $(LOCAL_PATH)/components/cdm_common.target.darwin-arm64.mk
+include $(LOCAL_PATH)/components/cdm_renderer.target.darwin-arm64.mk
 include $(LOCAL_PATH)/components/components_resources.target.darwin-arm64.mk
 include $(LOCAL_PATH)/components/components_strings.target.darwin-arm64.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_browser.target.darwin-arm64.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_common.target.darwin-arm64.mk
 include $(LOCAL_PATH)/components/navigation_interception.target.darwin-arm64.mk
 include $(LOCAL_PATH)/components/navigation_interception_jni_headers.target.darwin-arm64.mk
 include $(LOCAL_PATH)/components/os_crypt.target.darwin-arm64.mk
@@ -161,11 +166,13 @@
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_resources_module.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_script_formatter_worker_module.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_search_module.target.darwin-arm64.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_settings_module.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_source_frame_module.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_sources_module.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_temp_storage_shared_worker_module.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_timeline_module.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_devtools_css.target.darwin-arm64.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_module_descriptors.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_extension_api.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_frontend_resources.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_html.target.darwin-arm64.mk
@@ -187,8 +194,10 @@
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_minimal.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_skia_config.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/angle/src/commit_id.target.darwin-arm64.mk
+include $(LOCAL_PATH)/third_party/angle/src/copy_scripts.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/angle/src/preprocessor.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/angle/src/translator.target.darwin-arm64.mk
+include $(LOCAL_PATH)/third_party/angle/src/translator_lib.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/ashmem/ashmem.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/brotli/brotli.target.darwin-arm64.mk
 include $(LOCAL_PATH)/third_party/expat/expat.target.darwin-arm64.mk
diff --git a/GypAndroid.darwin-mips.mk b/GypAndroid.darwin-mips.mk
index 35aec2b..7276a7b 100644
--- a/GypAndroid.darwin-mips.mk
+++ b/GypAndroid.darwin-mips.mk
@@ -31,8 +31,13 @@
 include $(LOCAL_PATH)/components/autofill_core_common.target.darwin-mips.mk
 include $(LOCAL_PATH)/components/autofill_jni_headers.target.darwin-mips.mk
 include $(LOCAL_PATH)/components/autofill_regexes.target.darwin-mips.mk
+include $(LOCAL_PATH)/components/cdm_browser.target.darwin-mips.mk
+include $(LOCAL_PATH)/components/cdm_common.target.darwin-mips.mk
+include $(LOCAL_PATH)/components/cdm_renderer.target.darwin-mips.mk
 include $(LOCAL_PATH)/components/components_resources.target.darwin-mips.mk
 include $(LOCAL_PATH)/components/components_strings.target.darwin-mips.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_browser.target.darwin-mips.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_common.target.darwin-mips.mk
 include $(LOCAL_PATH)/components/navigation_interception.target.darwin-mips.mk
 include $(LOCAL_PATH)/components/navigation_interception_jni_headers.target.darwin-mips.mk
 include $(LOCAL_PATH)/components/os_crypt.target.darwin-mips.mk
@@ -161,11 +166,13 @@
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_resources_module.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_script_formatter_worker_module.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_search_module.target.darwin-mips.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_settings_module.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_source_frame_module.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_sources_module.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_temp_storage_shared_worker_module.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_timeline_module.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_devtools_css.target.darwin-mips.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_module_descriptors.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_extension_api.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_frontend_resources.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_html.target.darwin-mips.mk
@@ -187,8 +194,10 @@
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_minimal.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_skia_config.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/angle/src/commit_id.target.darwin-mips.mk
+include $(LOCAL_PATH)/third_party/angle/src/copy_scripts.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/angle/src/preprocessor.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/angle/src/translator.target.darwin-mips.mk
+include $(LOCAL_PATH)/third_party/angle/src/translator_lib.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/ashmem/ashmem.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/brotli/brotli.target.darwin-mips.mk
 include $(LOCAL_PATH)/third_party/expat/expat.target.darwin-mips.mk
diff --git a/GypAndroid.darwin-x86.mk b/GypAndroid.darwin-x86.mk
index 5bb32f3..c28ec0c 100644
--- a/GypAndroid.darwin-x86.mk
+++ b/GypAndroid.darwin-x86.mk
@@ -31,8 +31,13 @@
 include $(LOCAL_PATH)/components/autofill_core_common.target.darwin-x86.mk
 include $(LOCAL_PATH)/components/autofill_jni_headers.target.darwin-x86.mk
 include $(LOCAL_PATH)/components/autofill_regexes.target.darwin-x86.mk
+include $(LOCAL_PATH)/components/cdm_browser.target.darwin-x86.mk
+include $(LOCAL_PATH)/components/cdm_common.target.darwin-x86.mk
+include $(LOCAL_PATH)/components/cdm_renderer.target.darwin-x86.mk
 include $(LOCAL_PATH)/components/components_resources.target.darwin-x86.mk
 include $(LOCAL_PATH)/components/components_strings.target.darwin-x86.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_browser.target.darwin-x86.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_common.target.darwin-x86.mk
 include $(LOCAL_PATH)/components/navigation_interception.target.darwin-x86.mk
 include $(LOCAL_PATH)/components/navigation_interception_jni_headers.target.darwin-x86.mk
 include $(LOCAL_PATH)/components/os_crypt.target.darwin-x86.mk
@@ -170,11 +175,13 @@
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_resources_module.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_script_formatter_worker_module.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_search_module.target.darwin-x86.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_settings_module.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_source_frame_module.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_sources_module.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_temp_storage_shared_worker_module.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_timeline_module.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_devtools_css.target.darwin-x86.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_module_descriptors.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_extension_api.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_frontend_resources.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_html.target.darwin-x86.mk
@@ -196,8 +203,10 @@
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_minimal.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_skia_config.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/angle/src/commit_id.target.darwin-x86.mk
+include $(LOCAL_PATH)/third_party/angle/src/copy_scripts.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/angle/src/preprocessor.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/angle/src/translator.target.darwin-x86.mk
+include $(LOCAL_PATH)/third_party/angle/src/translator_lib.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/ashmem/ashmem.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/brotli/brotli.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/expat/expat.target.darwin-x86.mk
@@ -244,6 +253,7 @@
 include $(LOCAL_PATH)/third_party/mesa/mesa_headers.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/modp_b64/modp_b64.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/npapi/npapi.target.darwin-x86.mk
+include $(LOCAL_PATH)/third_party/openmax_dl/dl/openmax_dl.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/openssl/openssl.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/opus/opus.target.darwin-x86.mk
 include $(LOCAL_PATH)/third_party/ots/ots.target.darwin-x86.mk
diff --git a/GypAndroid.darwin-x86_64.mk b/GypAndroid.darwin-x86_64.mk
index fa03d24..451f866 100644
--- a/GypAndroid.darwin-x86_64.mk
+++ b/GypAndroid.darwin-x86_64.mk
@@ -31,8 +31,13 @@
 include $(LOCAL_PATH)/components/autofill_core_common.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/components/autofill_jni_headers.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/components/autofill_regexes.target.darwin-x86_64.mk
+include $(LOCAL_PATH)/components/cdm_browser.target.darwin-x86_64.mk
+include $(LOCAL_PATH)/components/cdm_common.target.darwin-x86_64.mk
+include $(LOCAL_PATH)/components/cdm_renderer.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/components/components_resources.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/components/components_strings.target.darwin-x86_64.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_browser.target.darwin-x86_64.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_common.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/components/navigation_interception.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/components/navigation_interception_jni_headers.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/components/os_crypt.target.darwin-x86_64.mk
@@ -170,11 +175,13 @@
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_resources_module.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_script_formatter_worker_module.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_search_module.target.darwin-x86_64.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_settings_module.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_source_frame_module.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_sources_module.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_temp_storage_shared_worker_module.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_timeline_module.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_devtools_css.target.darwin-x86_64.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_module_descriptors.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_extension_api.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_frontend_resources.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_html.target.darwin-x86_64.mk
@@ -196,8 +203,10 @@
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_minimal.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_skia_config.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/angle/src/commit_id.target.darwin-x86_64.mk
+include $(LOCAL_PATH)/third_party/angle/src/copy_scripts.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/angle/src/preprocessor.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/angle/src/translator.target.darwin-x86_64.mk
+include $(LOCAL_PATH)/third_party/angle/src/translator_lib.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/ashmem/ashmem.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/brotli/brotli.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/expat/expat.target.darwin-x86_64.mk
@@ -244,6 +253,7 @@
 include $(LOCAL_PATH)/third_party/mesa/mesa_headers.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/modp_b64/modp_b64.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/npapi/npapi.target.darwin-x86_64.mk
+include $(LOCAL_PATH)/third_party/openmax_dl/dl/openmax_dl.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/openssl/openssl.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/opus/opus.target.darwin-x86_64.mk
 include $(LOCAL_PATH)/third_party/ots/ots.target.darwin-x86_64.mk
diff --git a/GypAndroid.linux-arm.mk b/GypAndroid.linux-arm.mk
index 04c45bb..875b565 100644
--- a/GypAndroid.linux-arm.mk
+++ b/GypAndroid.linux-arm.mk
@@ -31,8 +31,13 @@
 include $(LOCAL_PATH)/components/autofill_core_common.target.linux-arm.mk
 include $(LOCAL_PATH)/components/autofill_jni_headers.target.linux-arm.mk
 include $(LOCAL_PATH)/components/autofill_regexes.target.linux-arm.mk
+include $(LOCAL_PATH)/components/cdm_browser.target.linux-arm.mk
+include $(LOCAL_PATH)/components/cdm_common.target.linux-arm.mk
+include $(LOCAL_PATH)/components/cdm_renderer.target.linux-arm.mk
 include $(LOCAL_PATH)/components/components_resources.target.linux-arm.mk
 include $(LOCAL_PATH)/components/components_strings.target.linux-arm.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_browser.target.linux-arm.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_common.target.linux-arm.mk
 include $(LOCAL_PATH)/components/navigation_interception.target.linux-arm.mk
 include $(LOCAL_PATH)/components/navigation_interception_jni_headers.target.linux-arm.mk
 include $(LOCAL_PATH)/components/os_crypt.target.linux-arm.mk
@@ -165,11 +170,13 @@
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_resources_module.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_script_formatter_worker_module.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_search_module.target.linux-arm.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_settings_module.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_source_frame_module.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_sources_module.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_temp_storage_shared_worker_module.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_timeline_module.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_devtools_css.target.linux-arm.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_module_descriptors.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_extension_api.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_frontend_resources.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_html.target.linux-arm.mk
@@ -192,8 +199,10 @@
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_minimal.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_skia_config.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/angle/src/commit_id.target.linux-arm.mk
+include $(LOCAL_PATH)/third_party/angle/src/copy_scripts.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/angle/src/preprocessor.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/angle/src/translator.target.linux-arm.mk
+include $(LOCAL_PATH)/third_party/angle/src/translator_lib.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/ashmem/ashmem.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/brotli/brotli.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/expat/expat.target.linux-arm.mk
@@ -241,6 +250,8 @@
 include $(LOCAL_PATH)/third_party/mesa/mesa_headers.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/modp_b64/modp_b64.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/npapi/npapi.target.linux-arm.mk
+include $(LOCAL_PATH)/third_party/openmax_dl/dl/openmax_dl.target.linux-arm.mk
+include $(LOCAL_PATH)/third_party/openmax_dl/dl/openmax_dl_armv7.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/openssl/openssl.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/opus/opus.target.linux-arm.mk
 include $(LOCAL_PATH)/third_party/ots/ots.target.linux-arm.mk
diff --git a/GypAndroid.linux-arm64.mk b/GypAndroid.linux-arm64.mk
index 04c9e35..3f3b001 100644
--- a/GypAndroid.linux-arm64.mk
+++ b/GypAndroid.linux-arm64.mk
@@ -31,8 +31,13 @@
 include $(LOCAL_PATH)/components/autofill_core_common.target.linux-arm64.mk
 include $(LOCAL_PATH)/components/autofill_jni_headers.target.linux-arm64.mk
 include $(LOCAL_PATH)/components/autofill_regexes.target.linux-arm64.mk
+include $(LOCAL_PATH)/components/cdm_browser.target.linux-arm64.mk
+include $(LOCAL_PATH)/components/cdm_common.target.linux-arm64.mk
+include $(LOCAL_PATH)/components/cdm_renderer.target.linux-arm64.mk
 include $(LOCAL_PATH)/components/components_resources.target.linux-arm64.mk
 include $(LOCAL_PATH)/components/components_strings.target.linux-arm64.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_browser.target.linux-arm64.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_common.target.linux-arm64.mk
 include $(LOCAL_PATH)/components/navigation_interception.target.linux-arm64.mk
 include $(LOCAL_PATH)/components/navigation_interception_jni_headers.target.linux-arm64.mk
 include $(LOCAL_PATH)/components/os_crypt.target.linux-arm64.mk
@@ -161,11 +166,13 @@
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_resources_module.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_script_formatter_worker_module.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_search_module.target.linux-arm64.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_settings_module.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_source_frame_module.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_sources_module.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_temp_storage_shared_worker_module.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_timeline_module.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_devtools_css.target.linux-arm64.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_module_descriptors.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_extension_api.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_frontend_resources.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_html.target.linux-arm64.mk
@@ -187,8 +194,10 @@
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_minimal.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_skia_config.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/angle/src/commit_id.target.linux-arm64.mk
+include $(LOCAL_PATH)/third_party/angle/src/copy_scripts.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/angle/src/preprocessor.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/angle/src/translator.target.linux-arm64.mk
+include $(LOCAL_PATH)/third_party/angle/src/translator_lib.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/ashmem/ashmem.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/brotli/brotli.target.linux-arm64.mk
 include $(LOCAL_PATH)/third_party/expat/expat.target.linux-arm64.mk
diff --git a/GypAndroid.linux-mips.mk b/GypAndroid.linux-mips.mk
index 01a0670..d144d35 100644
--- a/GypAndroid.linux-mips.mk
+++ b/GypAndroid.linux-mips.mk
@@ -31,8 +31,13 @@
 include $(LOCAL_PATH)/components/autofill_core_common.target.linux-mips.mk
 include $(LOCAL_PATH)/components/autofill_jni_headers.target.linux-mips.mk
 include $(LOCAL_PATH)/components/autofill_regexes.target.linux-mips.mk
+include $(LOCAL_PATH)/components/cdm_browser.target.linux-mips.mk
+include $(LOCAL_PATH)/components/cdm_common.target.linux-mips.mk
+include $(LOCAL_PATH)/components/cdm_renderer.target.linux-mips.mk
 include $(LOCAL_PATH)/components/components_resources.target.linux-mips.mk
 include $(LOCAL_PATH)/components/components_strings.target.linux-mips.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_browser.target.linux-mips.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_common.target.linux-mips.mk
 include $(LOCAL_PATH)/components/navigation_interception.target.linux-mips.mk
 include $(LOCAL_PATH)/components/navigation_interception_jni_headers.target.linux-mips.mk
 include $(LOCAL_PATH)/components/os_crypt.target.linux-mips.mk
@@ -161,11 +166,13 @@
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_resources_module.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_script_formatter_worker_module.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_search_module.target.linux-mips.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_settings_module.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_source_frame_module.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_sources_module.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_temp_storage_shared_worker_module.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_timeline_module.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_devtools_css.target.linux-mips.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_module_descriptors.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_extension_api.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_frontend_resources.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_html.target.linux-mips.mk
@@ -187,8 +194,10 @@
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_minimal.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_skia_config.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/angle/src/commit_id.target.linux-mips.mk
+include $(LOCAL_PATH)/third_party/angle/src/copy_scripts.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/angle/src/preprocessor.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/angle/src/translator.target.linux-mips.mk
+include $(LOCAL_PATH)/third_party/angle/src/translator_lib.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/ashmem/ashmem.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/brotli/brotli.target.linux-mips.mk
 include $(LOCAL_PATH)/third_party/expat/expat.target.linux-mips.mk
diff --git a/GypAndroid.linux-x86.mk b/GypAndroid.linux-x86.mk
index 030456a..127742b 100644
--- a/GypAndroid.linux-x86.mk
+++ b/GypAndroid.linux-x86.mk
@@ -31,8 +31,13 @@
 include $(LOCAL_PATH)/components/autofill_core_common.target.linux-x86.mk
 include $(LOCAL_PATH)/components/autofill_jni_headers.target.linux-x86.mk
 include $(LOCAL_PATH)/components/autofill_regexes.target.linux-x86.mk
+include $(LOCAL_PATH)/components/cdm_browser.target.linux-x86.mk
+include $(LOCAL_PATH)/components/cdm_common.target.linux-x86.mk
+include $(LOCAL_PATH)/components/cdm_renderer.target.linux-x86.mk
 include $(LOCAL_PATH)/components/components_resources.target.linux-x86.mk
 include $(LOCAL_PATH)/components/components_strings.target.linux-x86.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_browser.target.linux-x86.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_common.target.linux-x86.mk
 include $(LOCAL_PATH)/components/navigation_interception.target.linux-x86.mk
 include $(LOCAL_PATH)/components/navigation_interception_jni_headers.target.linux-x86.mk
 include $(LOCAL_PATH)/components/os_crypt.target.linux-x86.mk
@@ -170,11 +175,13 @@
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_resources_module.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_script_formatter_worker_module.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_search_module.target.linux-x86.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_settings_module.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_source_frame_module.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_sources_module.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_temp_storage_shared_worker_module.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_timeline_module.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_devtools_css.target.linux-x86.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_module_descriptors.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_extension_api.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_frontend_resources.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_html.target.linux-x86.mk
@@ -196,8 +203,10 @@
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_minimal.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_skia_config.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/angle/src/commit_id.target.linux-x86.mk
+include $(LOCAL_PATH)/third_party/angle/src/copy_scripts.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/angle/src/preprocessor.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/angle/src/translator.target.linux-x86.mk
+include $(LOCAL_PATH)/third_party/angle/src/translator_lib.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/ashmem/ashmem.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/brotli/brotli.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/expat/expat.target.linux-x86.mk
@@ -244,6 +253,7 @@
 include $(LOCAL_PATH)/third_party/mesa/mesa_headers.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/modp_b64/modp_b64.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/npapi/npapi.target.linux-x86.mk
+include $(LOCAL_PATH)/third_party/openmax_dl/dl/openmax_dl.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/openssl/openssl.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/opus/opus.target.linux-x86.mk
 include $(LOCAL_PATH)/third_party/ots/ots.target.linux-x86.mk
diff --git a/GypAndroid.linux-x86_64.mk b/GypAndroid.linux-x86_64.mk
index 72fc02e..c87335b 100644
--- a/GypAndroid.linux-x86_64.mk
+++ b/GypAndroid.linux-x86_64.mk
@@ -31,8 +31,13 @@
 include $(LOCAL_PATH)/components/autofill_core_common.target.linux-x86_64.mk
 include $(LOCAL_PATH)/components/autofill_jni_headers.target.linux-x86_64.mk
 include $(LOCAL_PATH)/components/autofill_regexes.target.linux-x86_64.mk
+include $(LOCAL_PATH)/components/cdm_browser.target.linux-x86_64.mk
+include $(LOCAL_PATH)/components/cdm_common.target.linux-x86_64.mk
+include $(LOCAL_PATH)/components/cdm_renderer.target.linux-x86_64.mk
 include $(LOCAL_PATH)/components/components_resources.target.linux-x86_64.mk
 include $(LOCAL_PATH)/components/components_strings.target.linux-x86_64.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_browser.target.linux-x86_64.mk
+include $(LOCAL_PATH)/components/data_reduction_proxy_common.target.linux-x86_64.mk
 include $(LOCAL_PATH)/components/navigation_interception.target.linux-x86_64.mk
 include $(LOCAL_PATH)/components/navigation_interception_jni_headers.target.linux-x86_64.mk
 include $(LOCAL_PATH)/components/os_crypt.target.linux-x86_64.mk
@@ -170,11 +175,13 @@
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_resources_module.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_script_formatter_worker_module.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_search_module.target.linux-x86_64.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_settings_module.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_source_frame_module.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_sources_module.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_temp_storage_shared_worker_module.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/build_timeline_module.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_devtools_css.target.linux-x86_64.mk
+include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/concatenated_module_descriptors.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_extension_api.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_frontend_resources.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/Source/devtools/devtools_html.target.linux-x86_64.mk
@@ -196,8 +203,10 @@
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_minimal.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/WebKit/public/blink_skia_config.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/angle/src/commit_id.target.linux-x86_64.mk
+include $(LOCAL_PATH)/third_party/angle/src/copy_scripts.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/angle/src/preprocessor.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/angle/src/translator.target.linux-x86_64.mk
+include $(LOCAL_PATH)/third_party/angle/src/translator_lib.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/ashmem/ashmem.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/brotli/brotli.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/expat/expat.target.linux-x86_64.mk
@@ -244,6 +253,7 @@
 include $(LOCAL_PATH)/third_party/mesa/mesa_headers.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/modp_b64/modp_b64.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/npapi/npapi.target.linux-x86_64.mk
+include $(LOCAL_PATH)/third_party/openmax_dl/dl/openmax_dl.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/openssl/openssl.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/opus/opus.target.linux-x86_64.mk
 include $(LOCAL_PATH)/third_party/ots/ots.target.linux-x86_64.mk
diff --git a/NOTICE b/NOTICE
index 8aace08..4809d6f 100644
--- a/NOTICE
+++ b/NOTICE
@@ -2639,6 +2639,21 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 // Copyright (C) 2002-2013 The ANGLE Project Authors. 
 // All rights reserved.
 //
@@ -4646,6 +4661,33 @@
    limitations under the License.
 
 
+Copyright (c) 1999, 2000, 2001, 2002
+Adel I. Mirzazhanov. All rights reserved
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ 
+     1.Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer. 
+     2.Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution. 
+     3.The name of the author may not be used to endorse or promote products
+       derived from this software without specific prior written permission. 
+ 		  
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN  NO  EVENT  SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES;  LOSS OF USE,  DATA,  OR  PROFITS;  OR BUSINESS
+INTERRUPTION)  HOWEVER  CAUSED  AND  ON  ANY  THEORY OF LIABILITY,
+WHETHER  IN  CONTRACT,   STRICT   LIABILITY,  OR  TORT  (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+		  
 Copyright (c) 2007-2013 IOLA and Ole Laursen
 
 Permission is hereby granted, free of charge, to any person
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index f6dbdef..073886a 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -1077,6 +1077,44 @@
       input_api, output_api, 'tools/android/checkstyle/chromium-style-5.0.xml')
 
 
+_DEPRECATED_CSS = [
+  # Values
+  ( "-webkit-box", "flex" ),
+  ( "-webkit-inline-box", "inline-flex" ),
+  ( "-webkit-flex", "flex" ),
+  ( "-webkit-inline-flex", "inline-flex" ),
+  ( "-webkit-min-content", "min-content" ),
+  ( "-webkit-max-content", "max-content" ),
+
+  # Properties
+  ( "-webkit-background-clip", "background-clip" ),
+  ( "-webkit-background-origin", "background-origin" ),
+  ( "-webkit-background-size", "background-size" ),
+  ( "-webkit-box-shadow", "box-shadow" ),
+
+  # Functions
+  ( "-webkit-gradient", "gradient" ),
+  ( "-webkit-repeating-gradient", "repeating-gradient" ),
+  ( "-webkit-linear-gradient", "linear-gradient" ),
+  ( "-webkit-repeating-linear-gradient", "repeating-linear-gradient" ),
+  ( "-webkit-radial-gradient", "radial-gradient" ),
+  ( "-webkit-repeating-radial-gradient", "repeating-radial-gradient" ),
+]
+
+def _CheckNoDeprecatedCSS(input_api, output_api):
+  """ Make sure that we don't use deprecated CSS
+      properties, functions or values. """
+  results = []
+  file_filter = lambda f: f.LocalPath().endswith('.css')
+  for fpath in input_api.AffectedFiles(file_filter=file_filter):
+    for line_num, line in fpath.ChangedContents():
+      for (deprecated_value, value) in _DEPRECATED_CSS:
+        if input_api.re.search(deprecated_value, line):
+          results.append(output_api.PresubmitError(
+              "%s:%d: Use of deprecated CSS %s, use %s instead" %
+              (fpath.LocalPath(), line_num, deprecated_value, value)))
+  return results
+
 def _CommonChecks(input_api, output_api):
   """Checks common to both upload and commit."""
   results = []
@@ -1112,6 +1150,7 @@
   results.extend(_CheckForAnonymousVariables(input_api, output_api))
   results.extend(_CheckCygwinShell(input_api, output_api))
   results.extend(_CheckUserActionUpdate(input_api, output_api))
+  results.extend(_CheckNoDeprecatedCSS(input_api, output_api))
 
   if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()):
     results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
@@ -1316,6 +1355,7 @@
       # TODO(maruel): An option would be to run 'sizes' but not count a failure
       # of this step as a try job failure.
       'android_aosp': ['compile'],
+      'android_chromium_gn_compile_rel': ['compile'],
       'android_clang_dbg': ['slave_steps'],
       'android_dbg': ['slave_steps'],
       'cros_x86': ['defaulttests'],
@@ -1338,6 +1378,7 @@
       'linux_chromium_chromeos_clang_dbg': ['defaulttests'],
       'linux_chromium_chromeos_rel': ['defaulttests'],
       'linux_chromium_compile_dbg': ['defaulttests'],
+      'linux_chromium_gn_rel': ['defaulttests'],
       'linux_chromium_rel': ['defaulttests'],
       'linux_chromium_clang_dbg': ['defaulttests'],
       'linux_gpu': ['defaulttests'],
@@ -1464,12 +1505,14 @@
     return GetDefaultTryConfigs(['ios_rel_device', 'ios_dbg_simulator'])
 
   builders = [
+      'android_chromium_gn_compile_rel',
       'android_clang_dbg',
       'android_dbg',
       'ios_dbg_simulator',
       'ios_rel_device',
       'linux_chromium_chromeos_rel',
       'linux_chromium_clang_dbg',
+      'linux_chromium_gn_rel',
       'linux_chromium_rel',
       'linux_gpu',
       'mac_chromium_compile_dbg',
diff --git a/WATCHLISTS b/WATCHLISTS
index d4a1d7e..1e6841f 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -482,6 +482,14 @@
                   '|chrome/browser/ui/gtk/panels'\
                   '|chrome/browser/ui/views/panels'
     },
+    'password_manager': {
+      'filepath': 'chrome/.*/password_'\
+                  '|chrome/browser/ui/passwords'\
+                  '|chrome/browser/ui/views/passwords'\
+                  '|chrome/test/data/password'\
+                  '|components/autofill.*password'
+                  '|components/password_'\
+    },
     'pepper_api': {
       'filepath': 'ppapi/api'\
                   '|ppapi/c',
@@ -829,7 +837,8 @@
              'ben+mojo@chromium.org',
              'darin@chromium.org',
              'qsr+mojo@chromium.org',
-             'viettrungluu+watch@chromium.org'],
+             'viettrungluu+watch@chromium.org',
+             'yzshen+watch@chromium.org'],
     'mouse_lock': ['scheib+watch@chromium.org'],
     'music_manager_private': ['gab+watch@chromium.org',
                               'erikwright+watch@chromium.org',
@@ -850,8 +859,8 @@
               'rjkroege@chromium.org'],
     'panels': ['dimich@chromium.org', 'jennb@chromium.org',
                'dcheng@chromium.org', 'jianli@chromium.org'],
-    'pepper_api': ['piman+watch@chromium.org',
-                   'ihf+watch@chromium.org', 'yzshen+watch@chromium.org',
+    'password_manager': ['mkwst+watchlist@chromium.org'],
+    'pepper_api': ['piman+watch@chromium.org', 'ihf+watch@chromium.org',
                    'yusukes+watch@chromium.org', 'raymes+watch@chromium.org',
                    'noelallen@chromium.org', 'binji+watch@chromium.org',
                    'nfullagar@chromium.org', 'teravest+watch@chromium.org',
diff --git a/android_webview/DEPS b/android_webview/DEPS
index 1ce4c33..91ac0f5 100644
--- a/android_webview/DEPS
+++ b/android_webview/DEPS
@@ -7,6 +7,7 @@
   # lib is the top-level target, and must remain a leaf in the dependency tree.
   "-android_webview/lib",
 
+  "+components/data_reduction_proxy",
   "+content/public/common",
   "+gpu",
   "+jni",
diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp
index bc28dc2..f84eccd 100644
--- a/android_webview/android_webview.gyp
+++ b/android_webview/android_webview.gyp
@@ -90,6 +90,9 @@
         '../android_webview/native/webview_native.gyp:webview_native',
         '../components/components.gyp:auto_login_parser',
         '../components/components.gyp:autofill_content_renderer',
+        '../components/components.gyp:cdm_browser',
+        '../components/components.gyp:cdm_renderer',
+        '../components/components.gyp:data_reduction_proxy_browser',
         '../components/components.gyp:navigation_interception',
         '../components/components.gyp:visitedlink_browser',
         '../components/components.gyp:visitedlink_renderer',
@@ -97,6 +100,7 @@
         '../content/content.gyp:content_app_both',
         '../gpu/gpu.gyp:command_buffer_service',
         '../gpu/gpu.gyp:gles2_implementation',
+        '../media/media.gyp:media',
         '../printing/printing.gyp:printing',
         '../skia/skia.gyp:skia',
         '../third_party/WebKit/public/blink.gyp:blink',
@@ -152,6 +156,9 @@
         'browser/browser_view_renderer_client.h',
         'browser/find_helper.cc',
         'browser/find_helper.h',
+        'browser/global_tile_manager.cc',
+        'browser/global_tile_manager.h',
+        'browser/global_tile_manager_client.h',
         'browser/gpu_memory_buffer_factory_impl.cc',
         'browser/gpu_memory_buffer_factory_impl.h',
         'browser/hardware_renderer.cc',
diff --git a/android_webview/android_webview_common.target.darwin-arm.mk b/android_webview/android_webview_common.target.darwin-arm.mk
index a49dd9b..5afdbd3 100644
--- a/android_webview/android_webview_common.target.darwin-arm.mk
+++ b/android_webview/android_webview_common.target.darwin-arm.mk
@@ -48,6 +48,7 @@
 	android_webview/browser/aw_web_preferences_populater.cc \
 	android_webview/browser/browser_view_renderer.cc \
 	android_webview/browser/find_helper.cc \
+	android_webview/browser/global_tile_manager.cc \
 	android_webview/browser/gpu_memory_buffer_factory_impl.cc \
 	android_webview/browser/hardware_renderer.cc \
 	android_webview/browser/icon_helper.cc \
@@ -96,7 +97,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -136,6 +136,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -146,11 +147,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -244,7 +240,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -284,6 +279,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -294,11 +290,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/android_webview_common.target.darwin-arm64.mk b/android_webview/android_webview_common.target.darwin-arm64.mk
index a7d39b0..3db30b1 100644
--- a/android_webview/android_webview_common.target.darwin-arm64.mk
+++ b/android_webview/android_webview_common.target.darwin-arm64.mk
@@ -48,6 +48,7 @@
 	android_webview/browser/aw_web_preferences_populater.cc \
 	android_webview/browser/browser_view_renderer.cc \
 	android_webview/browser/find_helper.cc \
+	android_webview/browser/global_tile_manager.cc \
 	android_webview/browser/gpu_memory_buffer_factory_impl.cc \
 	android_webview/browser/hardware_renderer.cc \
 	android_webview/browser/icon_helper.cc \
@@ -132,6 +133,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -142,11 +144,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -275,6 +272,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -285,11 +283,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/android_webview_common.target.darwin-mips.mk b/android_webview/android_webview_common.target.darwin-mips.mk
index d180f85..155f1d4 100644
--- a/android_webview/android_webview_common.target.darwin-mips.mk
+++ b/android_webview/android_webview_common.target.darwin-mips.mk
@@ -48,6 +48,7 @@
 	android_webview/browser/aw_web_preferences_populater.cc \
 	android_webview/browser/browser_view_renderer.cc \
 	android_webview/browser/find_helper.cc \
+	android_webview/browser/global_tile_manager.cc \
 	android_webview/browser/gpu_memory_buffer_factory_impl.cc \
 	android_webview/browser/hardware_renderer.cc \
 	android_webview/browser/icon_helper.cc \
@@ -135,6 +136,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -145,11 +147,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -282,6 +279,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -292,11 +290,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/android_webview_common.target.darwin-x86.mk b/android_webview/android_webview_common.target.darwin-x86.mk
index afb913e..120d6a9 100644
--- a/android_webview/android_webview_common.target.darwin-x86.mk
+++ b/android_webview/android_webview_common.target.darwin-x86.mk
@@ -48,6 +48,7 @@
 	android_webview/browser/aw_web_preferences_populater.cc \
 	android_webview/browser/browser_view_renderer.cc \
 	android_webview/browser/find_helper.cc \
+	android_webview/browser/global_tile_manager.cc \
 	android_webview/browser/gpu_memory_buffer_factory_impl.cc \
 	android_webview/browser/hardware_renderer.cc \
 	android_webview/browser/icon_helper.cc \
@@ -98,7 +99,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -137,6 +137,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -147,11 +148,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -246,7 +242,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -285,6 +280,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -295,11 +291,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/android_webview_common.target.darwin-x86_64.mk b/android_webview/android_webview_common.target.darwin-x86_64.mk
index db1931a..66331c3 100644
--- a/android_webview/android_webview_common.target.darwin-x86_64.mk
+++ b/android_webview/android_webview_common.target.darwin-x86_64.mk
@@ -48,6 +48,7 @@
 	android_webview/browser/aw_web_preferences_populater.cc \
 	android_webview/browser/browser_view_renderer.cc \
 	android_webview/browser/find_helper.cc \
+	android_webview/browser/global_tile_manager.cc \
 	android_webview/browser/gpu_memory_buffer_factory_impl.cc \
 	android_webview/browser/hardware_renderer.cc \
 	android_webview/browser/icon_helper.cc \
@@ -98,7 +99,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -137,6 +137,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -147,11 +148,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -246,7 +242,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -285,6 +280,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -295,11 +291,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/android_webview_common.target.linux-arm.mk b/android_webview/android_webview_common.target.linux-arm.mk
index a49dd9b..5afdbd3 100644
--- a/android_webview/android_webview_common.target.linux-arm.mk
+++ b/android_webview/android_webview_common.target.linux-arm.mk
@@ -48,6 +48,7 @@
 	android_webview/browser/aw_web_preferences_populater.cc \
 	android_webview/browser/browser_view_renderer.cc \
 	android_webview/browser/find_helper.cc \
+	android_webview/browser/global_tile_manager.cc \
 	android_webview/browser/gpu_memory_buffer_factory_impl.cc \
 	android_webview/browser/hardware_renderer.cc \
 	android_webview/browser/icon_helper.cc \
@@ -96,7 +97,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -136,6 +136,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -146,11 +147,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -244,7 +240,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -284,6 +279,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -294,11 +290,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/android_webview_common.target.linux-arm64.mk b/android_webview/android_webview_common.target.linux-arm64.mk
index a7d39b0..3db30b1 100644
--- a/android_webview/android_webview_common.target.linux-arm64.mk
+++ b/android_webview/android_webview_common.target.linux-arm64.mk
@@ -48,6 +48,7 @@
 	android_webview/browser/aw_web_preferences_populater.cc \
 	android_webview/browser/browser_view_renderer.cc \
 	android_webview/browser/find_helper.cc \
+	android_webview/browser/global_tile_manager.cc \
 	android_webview/browser/gpu_memory_buffer_factory_impl.cc \
 	android_webview/browser/hardware_renderer.cc \
 	android_webview/browser/icon_helper.cc \
@@ -132,6 +133,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -142,11 +144,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -275,6 +272,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -285,11 +283,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/android_webview_common.target.linux-mips.mk b/android_webview/android_webview_common.target.linux-mips.mk
index d180f85..155f1d4 100644
--- a/android_webview/android_webview_common.target.linux-mips.mk
+++ b/android_webview/android_webview_common.target.linux-mips.mk
@@ -48,6 +48,7 @@
 	android_webview/browser/aw_web_preferences_populater.cc \
 	android_webview/browser/browser_view_renderer.cc \
 	android_webview/browser/find_helper.cc \
+	android_webview/browser/global_tile_manager.cc \
 	android_webview/browser/gpu_memory_buffer_factory_impl.cc \
 	android_webview/browser/hardware_renderer.cc \
 	android_webview/browser/icon_helper.cc \
@@ -135,6 +136,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -145,11 +147,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -282,6 +279,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -292,11 +290,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/android_webview_common.target.linux-x86.mk b/android_webview/android_webview_common.target.linux-x86.mk
index afb913e..120d6a9 100644
--- a/android_webview/android_webview_common.target.linux-x86.mk
+++ b/android_webview/android_webview_common.target.linux-x86.mk
@@ -48,6 +48,7 @@
 	android_webview/browser/aw_web_preferences_populater.cc \
 	android_webview/browser/browser_view_renderer.cc \
 	android_webview/browser/find_helper.cc \
+	android_webview/browser/global_tile_manager.cc \
 	android_webview/browser/gpu_memory_buffer_factory_impl.cc \
 	android_webview/browser/hardware_renderer.cc \
 	android_webview/browser/icon_helper.cc \
@@ -98,7 +99,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -137,6 +137,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -147,11 +148,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -246,7 +242,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -285,6 +280,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -295,11 +291,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/android_webview_common.target.linux-x86_64.mk b/android_webview/android_webview_common.target.linux-x86_64.mk
index db1931a..66331c3 100644
--- a/android_webview/android_webview_common.target.linux-x86_64.mk
+++ b/android_webview/android_webview_common.target.linux-x86_64.mk
@@ -48,6 +48,7 @@
 	android_webview/browser/aw_web_preferences_populater.cc \
 	android_webview/browser/browser_view_renderer.cc \
 	android_webview/browser/find_helper.cc \
+	android_webview/browser/global_tile_manager.cc \
 	android_webview/browser/gpu_memory_buffer_factory_impl.cc \
 	android_webview/browser/hardware_renderer.cc \
 	android_webview/browser/icon_helper.cc \
@@ -98,7 +99,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -137,6 +137,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -147,11 +148,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -246,7 +242,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -285,6 +280,7 @@
 	'-DENABLE_MANAGED_USERS=1' \
 	'-DMOJO_USE_SYSTEM_IMPL' \
 	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DMEDIA_DISABLE_LIBVPX' \
 	'-DSK_ENABLE_INST_COUNT=0' \
 	'-DSK_SUPPORT_GPU=1' \
 	'-DGR_GL_CUSTOM_SETUP_HEADER="GrGLConfig_chrome.h"' \
@@ -295,11 +291,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/android_webview_pak.target.darwin-arm.mk b/android_webview/android_webview_pak.target.darwin-arm.mk
index 69ffdeb..8c4a2d3 100644
--- a/android_webview/android_webview_pak.target.darwin-arm.mk
+++ b/android_webview/android_webview_pak.target.darwin-arm.mk
@@ -20,6 +20,7 @@
 
 ### Rules for action "repack_android_webview_pack":
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/android_webview_pak.target.darwin-arm64.mk b/android_webview/android_webview_pak.target.darwin-arm64.mk
index 69ffdeb..8c4a2d3 100644
--- a/android_webview/android_webview_pak.target.darwin-arm64.mk
+++ b/android_webview/android_webview_pak.target.darwin-arm64.mk
@@ -20,6 +20,7 @@
 
 ### Rules for action "repack_android_webview_pack":
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/android_webview_pak.target.darwin-mips.mk b/android_webview/android_webview_pak.target.darwin-mips.mk
index 69ffdeb..8c4a2d3 100644
--- a/android_webview/android_webview_pak.target.darwin-mips.mk
+++ b/android_webview/android_webview_pak.target.darwin-mips.mk
@@ -20,6 +20,7 @@
 
 ### Rules for action "repack_android_webview_pack":
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/android_webview_pak.target.darwin-x86.mk b/android_webview/android_webview_pak.target.darwin-x86.mk
index 69ffdeb..8c4a2d3 100644
--- a/android_webview/android_webview_pak.target.darwin-x86.mk
+++ b/android_webview/android_webview_pak.target.darwin-x86.mk
@@ -20,6 +20,7 @@
 
 ### Rules for action "repack_android_webview_pack":
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/android_webview_pak.target.darwin-x86_64.mk b/android_webview/android_webview_pak.target.darwin-x86_64.mk
index 69ffdeb..8c4a2d3 100644
--- a/android_webview/android_webview_pak.target.darwin-x86_64.mk
+++ b/android_webview/android_webview_pak.target.darwin-x86_64.mk
@@ -20,6 +20,7 @@
 
 ### Rules for action "repack_android_webview_pack":
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/android_webview_pak.target.linux-arm.mk b/android_webview/android_webview_pak.target.linux-arm.mk
index 69ffdeb..8c4a2d3 100644
--- a/android_webview/android_webview_pak.target.linux-arm.mk
+++ b/android_webview/android_webview_pak.target.linux-arm.mk
@@ -20,6 +20,7 @@
 
 ### Rules for action "repack_android_webview_pack":
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/android_webview_pak.target.linux-arm64.mk b/android_webview/android_webview_pak.target.linux-arm64.mk
index 69ffdeb..8c4a2d3 100644
--- a/android_webview/android_webview_pak.target.linux-arm64.mk
+++ b/android_webview/android_webview_pak.target.linux-arm64.mk
@@ -20,6 +20,7 @@
 
 ### Rules for action "repack_android_webview_pack":
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/android_webview_pak.target.linux-mips.mk b/android_webview/android_webview_pak.target.linux-mips.mk
index 69ffdeb..8c4a2d3 100644
--- a/android_webview/android_webview_pak.target.linux-mips.mk
+++ b/android_webview/android_webview_pak.target.linux-mips.mk
@@ -20,6 +20,7 @@
 
 ### Rules for action "repack_android_webview_pack":
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/android_webview_pak.target.linux-x86.mk b/android_webview/android_webview_pak.target.linux-x86.mk
index 69ffdeb..8c4a2d3 100644
--- a/android_webview/android_webview_pak.target.linux-x86.mk
+++ b/android_webview/android_webview_pak.target.linux-x86.mk
@@ -20,6 +20,7 @@
 
 ### Rules for action "repack_android_webview_pack":
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/android_webview_pak.target.linux-x86_64.mk b/android_webview/android_webview_pak.target.linux-x86_64.mk
index 69ffdeb..8c4a2d3 100644
--- a/android_webview/android_webview_pak.target.linux-x86_64.mk
+++ b/android_webview/android_webview_pak.target.linux-x86_64.mk
@@ -20,6 +20,7 @@
 
 ### Rules for action "repack_android_webview_pack":
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview_apk/assets/webviewchromium.pak: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/android_webview_tests.gypi b/android_webview/android_webview_tests.gypi
index e6f1df3..b95d7bf 100644
--- a/android_webview/android_webview_tests.gypi
+++ b/android_webview/android_webview_tests.gypi
@@ -98,11 +98,14 @@
       'sources': [
         'browser/aw_cookie_access_policy_unittest.cc',
         'browser/aw_form_database_service_unittest.cc',
+        'browser/global_tile_manager_unittest.cc',
         'browser/net/android_stream_reader_url_request_job_unittest.cc',
         'browser/net/input_stream_reader_unittest.cc',
         'lib/main/webview_tests.cc',
         'native/aw_contents_client_bridge_unittest.cc',
         'native/input_stream_unittest.cc',
+        'native/permission/media_access_permission_request_unittest.cc',
+        'native/permission/permission_request_handler_unittest.cc',
         'native/state_serializer_unittest.cc',
       ],
     },
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS
index c4c14e1..417b2c9 100644
--- a/android_webview/browser/DEPS
+++ b/android_webview/browser/DEPS
@@ -11,6 +11,8 @@
   "+components/autofill/content/browser",
   "+components/autofill/core/browser",
   "+components/autofill/core/common",
+  "+components/cdm/browser",
+  "+components/data_reduction_proxy/browser",
   "+components/navigation_interception",
   "+components/user_prefs",
   "+components/visitedlink/browser",
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc
index 9ef21e5..e4a2a1d 100644
--- a/android_webview/browser/aw_browser_context.cc
+++ b/android_webview/browser/aw_browser_context.cc
@@ -15,6 +15,9 @@
 #include "base/prefs/pref_service.h"
 #include "base/prefs/pref_service_factory.h"
 #include "components/autofill/core/common/autofill_pref_names.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_prefs.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h"
 #include "components/user_prefs/user_prefs.h"
 #include "components/visitedlink/browser/visitedlink_master.h"
 #include "content/public/browser/browser_thread.h"
@@ -24,6 +27,7 @@
 
 using base::FilePath;
 using content::BrowserThread;
+using data_reduction_proxy::DataReductionProxySettings;
 
 namespace android_webview {
 
@@ -71,9 +75,21 @@
 
 void AwBrowserContext::PreMainMessageLoopRun() {
   cookie_store_ = CreateCookieStore(this);
+  DataReductionProxySettings::SetAllowed(true);
+  DataReductionProxySettings::SetPromoAllowed(false);
+  data_reduction_proxy_settings_.reset(
+      new DataReductionProxySettings());
+  data_reduction_proxy_settings_->set_fallback_allowed(false);
+
   url_request_context_getter_ =
       new AwURLRequestContextGetter(GetPath(), cookie_store_.get());
 
+  scoped_ptr<data_reduction_proxy::DataReductionProxyConfigurator>
+      configurator(new data_reduction_proxy::DataReductionProxyConfigTracker(
+          url_request_context_getter_->proxy_config_service(),
+          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
+  data_reduction_proxy_settings_->SetProxyConfigurator(configurator.Pass());
+
   visitedlink_master_.reset(
       new visitedlink::VisitedLinkMaster(this, this, false));
   visitedlink_master_->Init();
@@ -119,6 +135,10 @@
   return form_database_service_.get();
 }
 
+DataReductionProxySettings* AwBrowserContext::GetDataReductionProxySettings() {
+  return data_reduction_proxy_settings_.get();
+}
+
 // Create user pref service for autofill functionality.
 void AwBrowserContext::CreateUserPrefServiceIfNecessary() {
   if (user_pref_service_)
@@ -134,6 +154,8 @@
       autofill::prefs::kAutofillPositiveUploadRate, 0.0);
   pref_registry->RegisterDoublePref(
       autofill::prefs::kAutofillNegativeUploadRate, 0.0);
+  data_reduction_proxy::RegisterSimpleProfilePrefs(pref_registry);
+  data_reduction_proxy::RegisterPrefs(pref_registry);
 
   base::PrefServiceFactory pref_service_factory;
   pref_service_factory.set_user_prefs(make_scoped_refptr(new AwPrefStore()));
@@ -141,6 +163,15 @@
   user_pref_service_ = pref_service_factory.Create(pref_registry).Pass();
 
   user_prefs::UserPrefs::Set(this, user_pref_service_.get());
+
+  data_reduction_proxy_settings_->InitDataReductionProxySettings(
+      user_pref_service_.get(),
+      user_pref_service_.get(),
+      GetRequestContext());
+
+  //TODO(sgurun): Attach this to the API. It is currently hard coded in a
+  // disabled state.
+  data_reduction_proxy_settings_->SetDataReductionProxyEnabled(false);
 }
 
 base::FilePath AwBrowserContext::GetPath() const {
@@ -237,6 +268,11 @@
   return geolocation_permission_context_.get();
 }
 
+content::BrowserPluginGuestManagerDelegate*
+AwBrowserContext::GetGuestManagerDelegate() {
+  return NULL;
+}
+
 quota::SpecialStoragePolicy* AwBrowserContext::GetSpecialStoragePolicy() {
   // Intentionally returning NULL as 'Extensions' and 'Apps' not supported.
   return NULL;
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h
index d4d3734..94bbf4a 100644
--- a/android_webview/browser/aw_browser_context.h
+++ b/android_webview/browser/aw_browser_context.h
@@ -27,6 +27,10 @@
 class WebContents;
 }
 
+namespace data_reduction_proxy {
+class DataReductionProxySettings;
+}
+
 namespace net {
 class CookieStore;
 }
@@ -35,6 +39,8 @@
 class VisitedLinkMaster;
 }
 
+using data_reduction_proxy::DataReductionProxySettings;
+
 namespace android_webview {
 
 class AwFormDatabaseService;
@@ -74,6 +80,9 @@
   AwQuotaManagerBridge* GetQuotaManagerBridge();
 
   AwFormDatabaseService* GetFormDatabaseService();
+
+  DataReductionProxySettings* GetDataReductionProxySettings();
+
   void CreateUserPrefServiceIfNecessary();
 
   // content::BrowserContext implementation.
@@ -114,6 +123,8 @@
       GetDownloadManagerDelegate() OVERRIDE;
   virtual content::GeolocationPermissionContext*
       GetGeolocationPermissionContext() OVERRIDE;
+  virtual content::BrowserPluginGuestManagerDelegate*
+      GetGuestManagerDelegate() OVERRIDE;
   virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
 
   // visitedlink::VisitedLinkDelegate implementation.
@@ -139,6 +150,8 @@
 
   scoped_ptr<PrefService> user_pref_service_;
 
+  scoped_ptr<DataReductionProxySettings> data_reduction_proxy_settings_;
+
   DISALLOW_COPY_AND_ASSIGN(AwBrowserContext);
 };
 
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index db2dfa9..1ba73c7 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -18,6 +18,7 @@
 #include "android_webview/common/url_constants.h"
 #include "base/base_paths_android.h"
 #include "base/path_service.h"
+#include "components/cdm/browser/cdm_message_filter_android.h"
 #include "content/public/browser/access_token_store.h"
 #include "content/public/browser/browser_message_filter.h"
 #include "content/public/browser/browser_thread.h"
@@ -207,6 +208,7 @@
       host->GetID(), content::kFileScheme);
 
   host->AddFilter(new AwContentsMessageFilter(host->GetID()));
+  host->AddFilter(new cdm::CdmMessageFilterAndroid());
 }
 
 net::URLRequestContextGetter* AwContentBrowserClient::CreateRequestContext(
diff --git a/android_webview/browser/aw_login_delegate.cc b/android_webview/browser/aw_login_delegate.cc
index 90eafbe..d8d894b 100644
--- a/android_webview/browser/aw_login_delegate.cc
+++ b/android_webview/browser/aw_login_delegate.cc
@@ -4,9 +4,12 @@
 
 #include "android_webview/browser/aw_login_delegate.h"
 
+#include "android_webview/browser/aw_browser_context.h"
 #include "base/android/jni_android.h"
 #include "base/logging.h"
 #include "base/supports_user_data.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/resource_dispatcher_host.h"
@@ -22,6 +25,8 @@
 using content::ResourceDispatcherHost;
 using content::ResourceRequestInfo;
 using content::WebContents;
+using data_reduction_proxy::DataReductionProxyAuthRequestHandler;
+using data_reduction_proxy::DataReductionProxySettings;
 
 namespace {
 const char* kAuthAttemptsKey = "android_webview_auth_attempts";
@@ -91,6 +96,35 @@
       render_process_id_, render_frame_id_);
   WebContents* web_contents = WebContents::FromRenderFrameHost(
       render_frame_host);
+  AwBrowserContext* browser_context =
+      AwBrowserContext::FromWebContents(web_contents);
+  DataReductionProxySettings* drp_settings =
+      browser_context->GetDataReductionProxySettings();
+  if (drp_settings && drp_settings->IsDataReductionProxyEnabled()) {
+    // The data reduction proxy auth handler should only be reset on the first
+    // auth attempt, because it maintains internal state to cancel if there have
+    // been too many attempts.
+    if (!drp_auth_handler_.get()) {
+      drp_auth_handler_.reset(new DataReductionProxyAuthRequestHandler());
+    }
+    DCHECK(drp_auth_handler_.get());
+    base::string16 user, password;
+    DataReductionProxyAuthRequestHandler::TryHandleResult drp_result =
+        drp_auth_handler_->TryHandleAuthentication(
+            auth_info_.get(), &user, &password);
+    if (drp_result ==
+            DataReductionProxyAuthRequestHandler::TRY_HANDLE_RESULT_PROCEED) {
+      Proceed(user, password);
+      return;
+    }
+    if (drp_result ==
+            DataReductionProxyAuthRequestHandler::TRY_HANDLE_RESULT_CANCEL) {
+      Cancel();
+      return;
+    }
+    // Fall through if |drp_result| is IGNORE
+  }
+
   if (!aw_http_auth_handler_->HandleOnUIThread(web_contents)) {
     Cancel();
     return;
diff --git a/android_webview/browser/aw_login_delegate.h b/android_webview/browser/aw_login_delegate.h
index 7d13400..ba6c9e3 100644
--- a/android_webview/browser/aw_login_delegate.h
+++ b/android_webview/browser/aw_login_delegate.h
@@ -9,6 +9,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string16.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h"
 #include "content/public/browser/resource_dispatcher_host_login_delegate.h"
 
 namespace net {
@@ -16,6 +17,8 @@
 class URLRequest;
 }
 
+using data_reduction_proxy::DataReductionProxyAuthRequestHandler;
+
 namespace android_webview {
 
 class AwLoginDelegate :
@@ -44,6 +47,7 @@
   net::URLRequest* request_;
   int render_process_id_;
   int render_frame_id_;
+  scoped_ptr<DataReductionProxyAuthRequestHandler> drp_auth_handler_;
 };
 
 }  // namespace android_webview
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
index c6188e3..2fc8022 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -9,11 +9,15 @@
 #include "android_webview/public/browser/draw_gl.h"
 #include "base/android/jni_android.h"
 #include "base/auto_reset.h"
+#include "base/command_line.h"
 #include "base/debug/trace_event.h"
 #include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "content/public/browser/android/synchronous_compositor.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkPicture.h"
@@ -23,6 +27,8 @@
 using base::android::AttachCurrentThread;
 using base::android::JavaRef;
 using base::android::ScopedJavaLocalRef;
+using content::BrowserThread;
+using content::SynchronousCompositorMemoryPolicy;
 
 namespace android_webview {
 
@@ -30,6 +36,18 @@
 
 const int64 kFallbackTickTimeoutInMilliseconds = 20;
 
+// Used to calculate memory allocation. Determined experimentally.
+const size_t kMemoryMultiplier = 10;
+const size_t kBytesPerPixel = 4;
+const size_t kMemoryAllocationStep = 5 * 1024 * 1024;
+
+// Used to calculate tile allocation. Determined experimentally.
+const size_t kTileMultiplier = 12;
+const size_t kTileAllocationStep = 20;
+// This will be set by static function CalculateTileMemoryPolicy() during init.
+// See AwMainDelegate::BasicStartupComplete.
+size_t g_tile_area;
+
 class AutoResetWithLock {
  public:
   AutoResetWithLock(gfx::Vector2dF* scoped_variable,
@@ -57,6 +75,22 @@
 
 }  // namespace
 
+// static
+void BrowserViewRenderer::CalculateTileMemoryPolicy() {
+  CommandLine* cl = CommandLine::ForCurrentProcess();
+  const char kDefaultTileSize[] = "384";
+
+  if (!cl->HasSwitch(switches::kDefaultTileWidth))
+    cl->AppendSwitchASCII(switches::kDefaultTileWidth, kDefaultTileSize);
+
+  if (!cl->HasSwitch(switches::kDefaultTileHeight))
+    cl->AppendSwitchASCII(switches::kDefaultTileHeight, kDefaultTileSize);
+
+  size_t tile_size;
+  base::StringToSizeT(kDefaultTileSize, &tile_size);
+  g_tile_area = tile_size * tile_size;
+}
+
 BrowserViewRenderer::BrowserViewRenderer(
     BrowserViewRendererClient* client,
     SharedRendererState* shared_renderer_state,
@@ -80,7 +114,9 @@
       compositor_needs_continuous_invalidate_(false),
       block_invalidates_(false),
       width_(0),
-      height_(0) {
+      height_(0),
+      num_tiles_(0u),
+      num_bytes_(0u) {
   CHECK(web_contents_);
   content::SynchronousCompositor::SetClientForWebContents(web_contents_, this);
 
@@ -90,6 +126,98 @@
 
 BrowserViewRenderer::~BrowserViewRenderer() {
   content::SynchronousCompositor::SetClientForWebContents(web_contents_, NULL);
+  // OnDetachedFromWindow should be called before the destructor, so the memory
+  // policy should have already been updated.
+}
+
+// This function updates the cached memory policy in shared renderer state, as
+// well as the tile resource allocation in GlobalTileManager.
+void BrowserViewRenderer::TrimMemory(const int level, const bool visible) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  // Constants from Android ComponentCallbacks2.
+  enum {
+    TRIM_MEMORY_RUNNING_LOW = 10,
+    TRIM_MEMORY_UI_HIDDEN = 20,
+    TRIM_MEMORY_BACKGROUND = 40,
+  };
+
+  // Not urgent enough. TRIM_MEMORY_UI_HIDDEN is treated specially because
+  // it does not indicate memory pressure, but merely that the app is
+  // backgrounded.
+  if (level < TRIM_MEMORY_RUNNING_LOW || level == TRIM_MEMORY_UI_HIDDEN)
+    return;
+
+  // Do not release resources on view we expect to get DrawGL soon.
+  if (level < TRIM_MEMORY_BACKGROUND && visible)
+    return;
+
+  // Just set the memory limit to 0 and drop all tiles. This will be reset to
+  // normal levels in the next DrawGL call.
+  SynchronousCompositorMemoryPolicy zero_policy;
+  if (shared_renderer_state_->GetMemoryPolicy() == zero_policy)
+    return;
+
+  TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory");
+
+  RequestMemoryPolicy(zero_policy);
+  EnforceMemoryPolicyImmediately(zero_policy);
+}
+
+SynchronousCompositorMemoryPolicy
+BrowserViewRenderer::CalculateDesiredMemoryPolicy() {
+  SynchronousCompositorMemoryPolicy policy;
+  size_t width = draw_gl_input_.global_visible_rect.width();
+  size_t height = draw_gl_input_.global_visible_rect.height();
+  policy.bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height;
+  // Round up to a multiple of kMemoryAllocationStep.
+  policy.bytes_limit =
+      (policy.bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep;
+
+  size_t tiles = width * height * kTileMultiplier / g_tile_area;
+  // Round up to a multiple of kTileAllocationStep. The minimum number of tiles
+  // is also kTileAllocationStep.
+  tiles = (tiles / kTileAllocationStep + 1) * kTileAllocationStep;
+  policy.num_resources_limit = tiles;
+  return policy;
+}
+
+// This function updates the cached memory policy in shared renderer state, as
+// well as the tile resource allocation in GlobalTileManager.
+void BrowserViewRenderer::RequestMemoryPolicy(
+    SynchronousCompositorMemoryPolicy& new_policy) {
+  // This will be used in SetNumTiles.
+  num_bytes_ = new_policy.bytes_limit;
+
+  GlobalTileManager* manager = GlobalTileManager::GetInstance();
+
+  // The following line will call BrowserViewRenderer::SetTilesNum().
+  manager->RequestTiles(new_policy.num_resources_limit, tile_manager_key_);
+}
+
+void BrowserViewRenderer::SetNumTiles(size_t num_tiles,
+                                      bool effective_immediately) {
+  if (num_tiles == num_tiles_)
+    return;
+  num_tiles_ = num_tiles;
+
+  SynchronousCompositorMemoryPolicy new_policy;
+  new_policy.num_resources_limit = num_tiles_;
+  new_policy.bytes_limit = num_bytes_;
+  shared_renderer_state_->SetMemoryPolicy(new_policy);
+
+  if (effective_immediately)
+    EnforceMemoryPolicyImmediately(new_policy);
+}
+
+void BrowserViewRenderer::EnforceMemoryPolicyImmediately(
+    SynchronousCompositorMemoryPolicy new_policy) {
+  shared_renderer_state_->GetCompositor()->SetMemoryPolicy(new_policy);
+  ForceFakeCompositeSW();
+  shared_renderer_state_->SetMemoryPolicyDirty(false);
+}
+
+size_t BrowserViewRenderer::GetNumTiles() const {
+  return shared_renderer_state_->GetMemoryPolicy().num_resources_limit;
 }
 
 bool BrowserViewRenderer::OnDraw(jobject java_canvas,
@@ -106,10 +234,23 @@
     return false;
   if (is_hardware_canvas && attached_to_window_) {
     shared_renderer_state_->SetDrawGLInput(draw_gl_input_);
+
+    SynchronousCompositorMemoryPolicy old_policy =
+        shared_renderer_state_->GetMemoryPolicy();
+    SynchronousCompositorMemoryPolicy new_policy =
+        CalculateDesiredMemoryPolicy();
+    RequestMemoryPolicy(new_policy);
     // We should be performing a hardware draw here. If we don't have the
     // compositor yet or if RequestDrawGL fails, it means we failed this draw
     // and thus return false here to clear to background color for this draw.
-    return has_compositor_ && client_->RequestDrawGL(java_canvas, false);
+    bool did_draw_gl =
+        has_compositor_ && client_->RequestDrawGL(java_canvas, false);
+    if (did_draw_gl)
+      GlobalTileManager::GetInstance()->DidUse(tile_manager_key_);
+    else
+      RequestMemoryPolicy(old_policy);
+
+    return did_draw_gl;
   }
   // Perform a software draw
   return DrawSWInternal(java_canvas, clip);
@@ -154,7 +295,7 @@
   // Reset scroll back to the origin, will go back to the old
   // value when scroll_reset is out of scope.
   AutoResetWithLock scroll_reset(
-      &scroll_offset_dip_, gfx::Vector2dF(), scroll_offset_dip_lock_);
+      &scroll_offset_dip_, gfx::Vector2dF(), render_thread_lock_);
 
   SkPictureRecorder recorder;
   SkCanvas* rec_canvas = recorder.beginRecording(width, height, NULL, 0);
@@ -230,11 +371,18 @@
   attached_to_window_ = true;
   width_ = width;
   height_ = height;
+  tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this);
 }
 
 void BrowserViewRenderer::OnDetachedFromWindow() {
   TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow");
   attached_to_window_ = false;
+  SynchronousCompositorMemoryPolicy zero_policy;
+  RequestMemoryPolicy(zero_policy);
+  GlobalTileManager::GetInstance()->Remove(tile_manager_key_);
+  // The hardware resources are released in the destructor of hardware renderer,
+  // so we don't need to do it here.
+  // See AwContents::ReleaseHardwareDrawOnRenderThread(JNIEnv*, jobject).
 }
 
 bool BrowserViewRenderer::IsAttachedToWindow() const {
@@ -268,27 +416,33 @@
   DCHECK(ui_task_runner_->BelongsToCurrentThread());
   has_compositor_ = false;
   shared_renderer_state_->SetCompositorOnUiThread(NULL);
+  SynchronousCompositorMemoryPolicy zero_policy;
+  DCHECK(shared_renderer_state_->GetMemoryPolicy() == zero_policy);
 }
 
 void BrowserViewRenderer::SetContinuousInvalidate(bool invalidate) {
-  if (!ui_task_runner_->BelongsToCurrentThread()) {
-    ui_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&BrowserViewRenderer::SetContinuousInvalidate,
-                   ui_thread_weak_ptr_,
-                   invalidate));
+  {
+    base::AutoLock lock(render_thread_lock_);
+    if (compositor_needs_continuous_invalidate_ == invalidate)
+      return;
+
+    TRACE_EVENT_INSTANT1("android_webview",
+                         "BrowserViewRenderer::SetContinuousInvalidate",
+                         TRACE_EVENT_SCOPE_THREAD,
+                         "invalidate",
+                         invalidate);
+    compositor_needs_continuous_invalidate_ = invalidate;
+  }
+
+  if (ui_task_runner_->BelongsToCurrentThread()) {
+    EnsureContinuousInvalidation(false);
     return;
   }
-  if (compositor_needs_continuous_invalidate_ == invalidate)
-    return;
-
-  TRACE_EVENT_INSTANT1("android_webview",
-                       "BrowserViewRenderer::SetContinuousInvalidate",
-                       TRACE_EVENT_SCOPE_THREAD,
-                       "invalidate",
-                       invalidate);
-  compositor_needs_continuous_invalidate_ = invalidate;
-  EnsureContinuousInvalidation(false);
+  ui_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&BrowserViewRenderer::EnsureContinuousInvalidation,
+                 ui_thread_weak_ptr_,
+                 false));
 }
 
 void BrowserViewRenderer::SetDipScale(float dip_scale) {
@@ -324,7 +478,7 @@
   DCHECK_LE(scroll_offset_dip.y(), max_scroll_offset_dip_.y());
 
   {
-    base::AutoLock lock(scroll_offset_dip_lock_);
+    base::AutoLock lock(render_thread_lock_);
     if (scroll_offset_dip_ == scroll_offset_dip)
       return;
 
@@ -382,7 +536,7 @@
   }
 
   {
-    base::AutoLock lock(scroll_offset_dip_lock_);
+    base::AutoLock lock(render_thread_lock_);
     // TOOD(mkosiba): Add a DCHECK to say that this does _not_ get called during
     // DrawGl when http://crbug.com/249972 is fixed.
     if (scroll_offset_dip_ == scroll_offset_dip)
@@ -416,7 +570,7 @@
 }
 
 gfx::Vector2dF BrowserViewRenderer::GetTotalRootLayerScrollOffset() {
-  base::AutoLock lock(scroll_offset_dip_lock_);
+  base::AutoLock lock(render_thread_lock_);
   return scroll_offset_dip_;
 }
 
diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h
index da82fce..991075f 100644
--- a/android_webview/browser/browser_view_renderer.h
+++ b/android_webview/browser/browser_view_renderer.h
@@ -5,6 +5,8 @@
 #ifndef ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_H_
 #define ANDROID_WEBVIEW_BROWSER_BROWSER_VIEW_RENDERER_H_
 
+#include "android_webview/browser/global_tile_manager.h"
+#include "android_webview/browser/global_tile_manager_client.h"
 #include "android_webview/browser/shared_renderer_state.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/callback.h"
@@ -22,6 +24,7 @@
 namespace content {
 class ContentViewCore;
 class SynchronousCompositor;
+struct SynchronousCompositorMemoryPolicy;
 class WebContents;
 }
 
@@ -52,8 +55,11 @@
 
 // Interface for all the WebView-specific content rendering operations.
 // Provides software and hardware rendering and the Capture Picture API.
-class BrowserViewRenderer : public content::SynchronousCompositorClient {
+class BrowserViewRenderer : public content::SynchronousCompositorClient,
+                            public GlobalTileManagerClient {
  public:
+  static void CalculateTileMemoryPolicy();
+
   BrowserViewRenderer(
       BrowserViewRendererClient* client,
       SharedRendererState* shared_renderer_state,
@@ -101,10 +107,12 @@
   bool IsVisible() const;
   gfx::Rect GetScreenRect() const;
 
-  // Force invoke the compositor to run produce a 1x1 software frame that is
-  // immediately discarded. This is a hack to force invoke parts of the
-  // compositor that are not directly exposed here.
-  void ForceFakeCompositeSW();
+  // Set the memory policy in shared renderer state and request the tiles from
+  // GlobalTileManager. The actually amount of memory allowed by
+  // GlobalTileManager may not be equal to what's requested in |policy|.
+  void RequestMemoryPolicy(content::SynchronousCompositorMemoryPolicy& policy);
+
+  void TrimMemory(const int level, const bool visible);
 
   // SynchronousCompositorClient overrides
   virtual void DidInitializeCompositor(
@@ -127,6 +135,11 @@
                              gfx::Vector2dF latest_overscroll_delta,
                              gfx::Vector2dF current_fling_velocity) OVERRIDE;
 
+  // GlobalTileManagerClient overrides
+  virtual size_t GetNumTiles() const OVERRIDE;
+  virtual void SetNumTiles(size_t num_tiles,
+                           bool effective_immediately) OVERRIDE;
+
  private:
   // Checks the continuous invalidate and block invalidate state, and schedule
   // invalidates appropriately. If |force_invalidate| is true, then send a view
@@ -140,8 +153,17 @@
   // then we keep ticking the SynchronousCompositor so it can make progress.
   void FallbackTickFired();
 
+  // Force invoke the compositor to run produce a 1x1 software frame that is
+  // immediately discarded. This is a hack to force invoke parts of the
+  // compositor that are not directly exposed here.
+  void ForceFakeCompositeSW();
+
+  void EnforceMemoryPolicyImmediately(
+      content::SynchronousCompositorMemoryPolicy policy);
+
   gfx::Vector2d max_scroll_offset() const;
 
+  content::SynchronousCompositorMemoryPolicy CalculateDesiredMemoryPolicy();
   // For debug tracing or logging. Return the string representation of this
   // view renderer's state and the |draw_info| if provided.
   std::string ToString(AwDrawGLInfo* draw_info) const;
@@ -185,9 +207,6 @@
 
   DrawGLInput draw_gl_input_;
 
-  // TODO(boliu): This is a short term solution to support
-  // SynchronousCompositorClient methods called on non-UI thread.
-  base::Lock scroll_offset_dip_lock_;
   // Current scroll offset in CSS pixels.
   gfx::Vector2dF scroll_offset_dip_;
 
@@ -199,6 +218,19 @@
   // spot over a period of time).
   gfx::Vector2dF overscroll_rounding_error_;
 
+  GlobalTileManager::Key tile_manager_key_;
+
+  // The following 2 are used to construct a memory policy and set the memory
+  // policy on the shared_renderer_state_ atomically.
+  size_t num_tiles_;
+  size_t num_bytes_;
+
+  // TODO(boliu): This is a short term solution to support
+  // SynchronousCompositorClient methods called on RenderThread. This is only
+  // used on data that must be modified immediately instead of being posted
+  // back to UI.
+  base::Lock render_thread_lock_;
+
   DISALLOW_COPY_AND_ASSIGN(BrowserViewRenderer);
 };
 
diff --git a/android_webview/browser/global_tile_manager.cc b/android_webview/browser/global_tile_manager.cc
new file mode 100644
index 0000000..efc3039
--- /dev/null
+++ b/android_webview/browser/global_tile_manager.cc
@@ -0,0 +1,135 @@
+// 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.
+
+#include "android_webview/browser/global_tile_manager.h"
+#include "android_webview/browser/global_tile_manager_client.h"
+#include "base/lazy_instance.h"
+
+namespace android_webview {
+
+namespace {
+base::LazyInstance<GlobalTileManager>::Leaky g_tile_manager =
+    LAZY_INSTANCE_INITIALIZER;
+// The soft limit of the number of file descriptors per process is 1024 on
+// Android and gralloc buffers may not be the only thing that uses file
+// descriptors. For each tile, there is a gralloc buffer backing it, which
+// uses 2 FDs.
+const size_t kNumTilesLimit = 450;
+
+}  // namespace
+
+// static
+GlobalTileManager* GlobalTileManager::GetInstance() {
+  return g_tile_manager.Pointer();
+}
+
+void GlobalTileManager::Remove(Key key) {
+  DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+  DCHECK(mru_list_.end() != key);
+
+  total_allocated_tiles_ -= (*key)->GetNumTiles();
+  mru_list_.erase(key);
+  DCHECK(IsConsistent());
+}
+
+size_t GlobalTileManager::Evict(size_t desired_num_tiles, Key key) {
+  DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+  size_t total_evicted_tiles = 0;
+
+  // Evicts from the least recent drawn view, until the disired number of tiles
+  // can be reclaimed, or until we've evicted all inactive views.
+  ListType::reverse_iterator it;
+  for (it = mru_list_.rbegin(); it != mru_list_.rend(); it++) {
+    // key represents the view that requested the eviction, so we don't need to
+    // evict the requester itself. And we only evict the inactive views,
+    // which are all the views after the requester.
+    if (*it == *key)
+      break;
+
+    size_t evicted_tiles = (*it)->GetNumTiles();
+    (*it)->SetNumTiles(0, true);
+
+    total_evicted_tiles += evicted_tiles;
+    if (total_evicted_tiles >= desired_num_tiles)
+      break;
+  }
+
+  return total_evicted_tiles;
+}
+
+void GlobalTileManager::RequestTiles(size_t new_num_of_tiles, Key key) {
+  DCHECK(IsConsistent());
+  DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+  size_t old_num_of_tiles = (*key)->GetNumTiles();
+  size_t num_of_active_views = std::distance(mru_list_.begin(), key) + 1;
+  size_t tiles_per_view_limit;
+  if (num_of_active_views == 0)
+    tiles_per_view_limit = kNumTilesLimit;
+  else
+    tiles_per_view_limit = kNumTilesLimit / num_of_active_views;
+  new_num_of_tiles = std::min(new_num_of_tiles, tiles_per_view_limit);
+  size_t new_total_allocated_tiles =
+      total_allocated_tiles_ - old_num_of_tiles + new_num_of_tiles;
+  // Has enough tiles to satisfy the request.
+  if (new_total_allocated_tiles <= kNumTilesLimit) {
+    total_allocated_tiles_ = new_total_allocated_tiles;
+    (*key)->SetNumTiles(new_num_of_tiles, false);
+    return;
+  }
+
+  // Does not have enough tiles. Now evict other clients' tiles.
+  size_t tiles_left = kNumTilesLimit - total_allocated_tiles_;
+
+  size_t evicted_tiles = Evict(new_total_allocated_tiles - kNumTilesLimit, key);
+  if (evicted_tiles >= new_total_allocated_tiles - kNumTilesLimit) {
+    new_total_allocated_tiles -= evicted_tiles;
+    total_allocated_tiles_ = new_total_allocated_tiles;
+    (*key)->SetNumTiles(new_num_of_tiles, false);
+    return;
+  } else {
+    total_allocated_tiles_ = kNumTilesLimit;
+    (*key)->SetNumTiles(tiles_left + old_num_of_tiles + evicted_tiles, false);
+    return;
+  }
+}
+
+GlobalTileManager::Key GlobalTileManager::PushBack(
+    GlobalTileManagerClient* client) {
+  DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+  DCHECK(mru_list_.end() ==
+         std::find(mru_list_.begin(), mru_list_.end(), client));
+  mru_list_.push_back(client);
+  Key back = mru_list_.end();
+  back--;
+  return back;
+}
+
+void GlobalTileManager::DidUse(Key key) {
+  DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+  DCHECK(mru_list_.end() != key);
+
+  mru_list_.splice(mru_list_.begin(), mru_list_, key);
+}
+
+GlobalTileManager::GlobalTileManager() {
+  total_allocated_tiles_ = 0;
+}
+
+GlobalTileManager::~GlobalTileManager() {
+}
+
+bool GlobalTileManager::IsConsistent() const {
+  size_t total_tiles = 0;
+  ListType::const_iterator it;
+  for (it = mru_list_.begin(); it != mru_list_.end(); it++) {
+    total_tiles += (*it)->GetNumTiles();
+  }
+
+  bool is_consistent =
+      (total_tiles <= kNumTilesLimit && total_tiles == total_allocated_tiles_);
+
+  return is_consistent;
+}
+
+}  // namespace webview
diff --git a/android_webview/browser/global_tile_manager.h b/android_webview/browser/global_tile_manager.h
new file mode 100644
index 0000000..ca42230
--- /dev/null
+++ b/android_webview/browser/global_tile_manager.h
@@ -0,0 +1,73 @@
+// 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.
+
+#ifndef ANDROID_WEBVIEW_BROWSER_GLOBAL_TILE_MANAGER_H_
+#define ANDROID_WEBVIEW_BROWSER_GLOBAL_TILE_MANAGER_H_
+
+#include <list>
+#include "base/basictypes.h"
+#include "base/lazy_instance.h"
+#include "base/sequence_checker.h"
+#include "base/synchronization/lock.h"
+
+namespace android_webview {
+
+class GlobalTileManagerClient;
+
+// A global tile manager that keeps track of the number of tile resources. Each
+// tile needs file descriptors (typically 2) and there is a soft limit of 1024
+// file descriptors per Android process. The GlobalTileManager does not keep
+// track of how many tiles each individual view is actually using. The purpose
+// of GlobalTileManager is to behave gracefully (as in not crashing) when the
+// embedder of webview creates a lot of webviews and draw them at the same time.
+class GlobalTileManager {
+ private:
+  typedef std::list<GlobalTileManagerClient*> ListType;
+
+ public:
+  typedef ListType::iterator Key;
+  static GlobalTileManager* GetInstance();
+
+  // Requests the |num_of_tiles| from the available global pool. Calls
+  // GlobalTileManagerClient.SetNumTiles after the manager determines how many
+  // tiles are available for the client. If the number of tiles left is not
+  // enough to satisfy the request, the manager will evict tiles allocated to
+  // other clients.
+  void RequestTiles(size_t new_num_of_tiles, Key key);
+
+  Key PushBack(GlobalTileManagerClient* client);
+
+  // |key| must be already in manager. Move the tile manager client
+  // corresponding to |key| to most recent. This function should be called after
+  // RequestTiles.
+  void DidUse(Key key);
+
+  void Remove(Key key);
+
+ private:
+  friend struct base::DefaultLazyInstanceTraits<GlobalTileManager>;
+  GlobalTileManager();
+  ~GlobalTileManager();
+
+  // Continues evicting the inactive views until freeing up at least amount of
+  // tiles specified by |desired_num_tiles| to draw a view specified by |key|,
+  // or until all inactive views have been evicted. Returns the amount of
+  // memory that was actually evicted. This function is called when a
+  // request cannot be satisfied.
+  size_t Evict(size_t desired_num_tiles, Key key);
+
+  // Check that the sum of all client's tiles is equal to
+  // total_allocated_tiles_.
+  bool IsConsistent() const;
+
+  size_t total_allocated_tiles_;
+  ListType mru_list_;
+  base::SequenceChecker sequence_checker_;
+
+  DISALLOW_COPY_AND_ASSIGN(GlobalTileManager);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_GLOBAL_TILE_MANAGER_H_
diff --git a/android_webview/browser/global_tile_manager_client.h b/android_webview/browser/global_tile_manager_client.h
new file mode 100644
index 0000000..ec4dad6
--- /dev/null
+++ b/android_webview/browser/global_tile_manager_client.h
@@ -0,0 +1,26 @@
+// 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.
+
+#ifndef ANDROID_WEBVIEW_BROWSER_GLOBAL_TILE_MANAGER_CLIENT_H_
+#define ANDROID_WEBVIEW_BROWSER_GLOBAL_TILE_MANAGER_CLIENT_H_
+
+namespace android_webview {
+// GlobalTileManagerClient requests tile resources from GlobalTileManager.
+class GlobalTileManagerClient {
+ public:
+  // Get the number of tiles allocated to the client.
+  virtual size_t GetNumTiles() const = 0;
+
+  // Set the number of tiles allocated to the client. When
+  // |effective_immediately| is true, the client will enforce its tile policy
+  // immediately.
+  virtual void SetNumTiles(size_t num_tiles, bool effective_immediately) = 0;
+
+ protected:
+  virtual ~GlobalTileManagerClient() {}
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_GLOBAL_TILE_MANAGER_CLIENT_H_
diff --git a/android_webview/browser/global_tile_manager_unittest.cc b/android_webview/browser/global_tile_manager_unittest.cc
new file mode 100644
index 0000000..9f09084
--- /dev/null
+++ b/android_webview/browser/global_tile_manager_unittest.cc
@@ -0,0 +1,157 @@
+// 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.
+
+#include <algorithm>
+#include "android_webview/browser/global_tile_manager.h"
+#include "android_webview/browser/global_tile_manager_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+// This should be the same as the one defined global_tile_manager.cc
+const size_t kNumTilesLimit = 450;
+const size_t kDefaultNumTiles = 150;
+
+}  // namespace
+
+using android_webview::GlobalTileManager;
+using android_webview::GlobalTileManagerClient;
+using testing::Test;
+
+class MockGlobalTileManagerClient : public GlobalTileManagerClient {
+ public:
+  virtual size_t GetNumTiles() const OVERRIDE { return num_tiles_; }
+  virtual void SetNumTiles(size_t num_tiles,
+                           bool effective_immediately) OVERRIDE {
+    num_tiles_ = num_tiles;
+  }
+
+  MockGlobalTileManagerClient() {
+    num_tiles_ = 0;
+    tile_request_ = kDefaultNumTiles;
+    key_ = GlobalTileManager::GetInstance()->PushBack(this);
+  }
+
+  virtual ~MockGlobalTileManagerClient() {
+    GlobalTileManager::GetInstance()->Remove(key_);
+  }
+
+  size_t GetTileRequest() { return tile_request_; }
+  GlobalTileManager::Key GetKey() { return key_; }
+
+ private:
+  size_t num_tiles_;
+  size_t tile_request_;
+  GlobalTileManager::Key key_;
+};
+
+class GlobalTileManagerTest : public Test {
+ public:
+  virtual void SetUp() {}
+
+  GlobalTileManager* manager() { return GlobalTileManager::GetInstance(); }
+};
+
+TEST_F(GlobalTileManagerTest, RequestTilesUnderLimit) {
+  MockGlobalTileManagerClient clients[2];
+
+  for (size_t i = 0; i < 2; i++) {
+    manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
+    manager()->DidUse(clients[i].GetKey());
+
+    // Ensure clients get what they asked for when the manager is under tile
+    // limit.
+    EXPECT_EQ(clients[i].GetNumTiles(), kDefaultNumTiles);
+  }
+}
+
+TEST_F(GlobalTileManagerTest, EvictHappensWhenOverLimit) {
+  MockGlobalTileManagerClient clients[4];
+
+  for (size_t i = 0; i < 4; i++) {
+    manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
+    manager()->DidUse(clients[i].GetKey());
+  }
+
+  size_t total_tiles = 0;
+  for (size_t i = 0; i < 4; i++) {
+    total_tiles += clients[i].GetNumTiles();
+  }
+
+  // Ensure that eviction happened and kept the total number of tiles within
+  // kNumTilesLimit.
+  EXPECT_LE(total_tiles, kNumTilesLimit);
+}
+
+TEST_F(GlobalTileManagerTest, RandomizedStressRequests) {
+  MockGlobalTileManagerClient clients[100];
+  size_t index[100];
+  for (size_t i = 0; i < 100; i++) {
+    index[i] = i;
+  }
+
+  // Simulate a random request order of clients.
+  std::random_shuffle(&index[0], &index[99]);
+
+  for (size_t i = 0; i < 100; i++) {
+    size_t j = index[i];
+    manager()->RequestTiles(clients[j].GetTileRequest(), clients[j].GetKey());
+    manager()->DidUse(clients[j].GetKey());
+  }
+
+  size_t total_tiles = 0;
+  for (size_t i = 0; i < 100; i++) {
+    total_tiles += clients[i].GetNumTiles();
+  }
+
+  // Ensure that eviction happened and kept the total number of tiles within
+  // kNumTilesLimit.
+  EXPECT_LE(total_tiles, kNumTilesLimit);
+}
+
+TEST_F(GlobalTileManagerTest, FixedOrderedRequests) {
+  MockGlobalTileManagerClient clients[10];
+
+  // 10 clients requesting resources in a fixed order. Do that for 5 rounds.
+  for (int round = 0; round < 5; round++) {
+    for (size_t i = 0; i < 10; i++) {
+      manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
+      manager()->DidUse(clients[i].GetKey());
+    }
+  }
+
+  // Ensure that the total tiles are divided evenly among all clients.
+  for (size_t i = 0; i < 10; i++) {
+    EXPECT_EQ(clients[i].GetNumTiles(), kNumTilesLimit / 10);
+  }
+}
+
+TEST_F(GlobalTileManagerTest, FixedOrderedRequestsWithInactiveClients) {
+  MockGlobalTileManagerClient clients[20];
+
+  // 20 clients request resources.
+  for (size_t i = 0; i < 20; i++) {
+    manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
+    manager()->DidUse(clients[i].GetKey());
+  }
+
+  // Now the last 10 clients become inactive. Only the first 10 clients remain
+  // active resource requesters.
+  // 10 clients requesting resources in a fixed order. Do that for 5 rounds.
+  for (int round = 0; round < 5; round++) {
+    for (size_t i = 0; i < 10; i++) {
+      manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
+      manager()->DidUse(clients[i].GetKey());
+    }
+  }
+
+  // Ensure that the total tiles are divided evenly among all clients.
+  for (size_t i = 0; i < 10; i++) {
+    EXPECT_EQ(clients[i].GetNumTiles(), kNumTilesLimit / 10);
+  }
+
+  // Ensure that the inactive tiles are evicted.
+  for (size_t i = 11; i < 20; i++) {
+    EXPECT_EQ(clients[i].GetNumTiles(), 0u);
+  }
+}
diff --git a/android_webview/browser/gpu_memory_buffer_factory_impl.cc b/android_webview/browser/gpu_memory_buffer_factory_impl.cc
index 620fd5a..8be58c5 100644
--- a/android_webview/browser/gpu_memory_buffer_factory_impl.cc
+++ b/android_webview/browser/gpu_memory_buffer_factory_impl.cc
@@ -31,23 +31,9 @@
   }
 
   // Overridden from gfx::GpuMemoryBuffer:
-  virtual void* Map(gfx::GpuMemoryBuffer::AccessMode mode) OVERRIDE {
-    AwMapMode map_mode = MAP_READ_ONLY;
-    switch (mode) {
-      case GpuMemoryBuffer::READ_ONLY:
-        map_mode = MAP_READ_ONLY;
-        break;
-      case GpuMemoryBuffer::WRITE_ONLY:
-        map_mode = MAP_WRITE_ONLY;
-        break;
-      case GpuMemoryBuffer::READ_WRITE:
-        map_mode = MAP_READ_WRITE;
-        break;
-      default:
-        LOG(DFATAL) << "Unknown map mode: " << mode;
-    }
+  virtual void* Map() OVERRIDE {
     void* vaddr = NULL;
-    int err = g_gl_draw_functions->map(buffer_id_, map_mode, &vaddr);
+    int err = g_gl_draw_functions->map(buffer_id_, MAP_READ_WRITE, &vaddr);
     DCHECK(!err);
     mapped_ = true;
     return vaddr;
@@ -87,7 +73,8 @@
 gfx::GpuMemoryBuffer* GpuMemoryBufferFactoryImpl::CreateGpuMemoryBuffer(
     size_t width,
     size_t height,
-    unsigned internalformat) {
+    unsigned internalformat,
+    unsigned usage) {
   // For Android WebView we assume the |internalformat| will always be
   // GL_RGBA8_OES.
   CHECK_EQ(static_cast<GLenum>(GL_RGBA8_OES), internalformat);
diff --git a/android_webview/browser/gpu_memory_buffer_factory_impl.h b/android_webview/browser/gpu_memory_buffer_factory_impl.h
index a5d8988..b2c1feb 100644
--- a/android_webview/browser/gpu_memory_buffer_factory_impl.h
+++ b/android_webview/browser/gpu_memory_buffer_factory_impl.h
@@ -24,7 +24,8 @@
   virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(
       size_t width,
       size_t height,
-      unsigned internalformat) OVERRIDE;
+      unsigned internalformat,
+      unsigned usage) OVERRIDE;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferFactoryImpl);
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc
index c48e4c7..f1528ec 100644
--- a/android_webview/browser/hardware_renderer.cc
+++ b/android_webview/browser/hardware_renderer.cc
@@ -6,31 +6,21 @@
 
 #include "android_webview/browser/aw_gl_surface.h"
 #include "android_webview/browser/browser_view_renderer_client.h"
-#include "android_webview/browser/gl_view_renderer_manager.h"
 #include "android_webview/browser/scoped_app_gl_state_restore.h"
 #include "android_webview/public/browser/draw_gl.h"
-#include "base/command_line.h"
 #include "base/debug/trace_event.h"
 #include "base/strings/string_number_conversions.h"
+#include "content/public/browser/android/synchronous_compositor.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_switches.h"
 #include "gpu/command_buffer/service/shader_translator_cache.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/transform.h"
 
-using content::BrowserThread;
-
 namespace android_webview {
 
 namespace {
 
-// Used to calculate memory and resource allocation. Determined experimentally.
-const size_t g_memory_multiplier = 10;
-const size_t g_num_gralloc_limit = 150;
-const size_t kBytesPerPixel = 4;
-const size_t kMemoryAllocationStep = 5 * 1024 * 1024;
-
 base::LazyInstance<scoped_refptr<internal::DeferredGpuCommandService> >
     g_service = LAZY_INSTANCE_INITIALIZER;
 
@@ -39,7 +29,7 @@
 HardwareRenderer::HardwareRenderer(SharedRendererState* state)
     : shared_renderer_state_(state),
       last_egl_context_(eglGetCurrentContext()),
-      manager_key_(GLViewRendererManager::GetInstance()->PushBack(
+      renderer_manager_key_(GLViewRendererManager::GetInstance()->PushBack(
           shared_renderer_state_)) {
   DCHECK(last_egl_context_);
   if (!g_service.Get()) {
@@ -59,8 +49,8 @@
 }
 
 HardwareRenderer::~HardwareRenderer() {
-  GLViewRendererManager* mru = GLViewRendererManager::GetInstance();
-  mru->Remove(manager_key_);
+  GLViewRendererManager* render_manager = GLViewRendererManager::GetInstance();
+  render_manager->Remove(renderer_manager_key_);
 
   ScopedAppGLStateRestore state_restore(
       ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
@@ -72,7 +62,7 @@
 
 bool HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, DrawGLResult* result) {
   TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");
-  GLViewRendererManager::GetInstance()->DidDrawGL(manager_key_);
+  GLViewRendererManager::GetInstance()->DidDrawGL(renderer_manager_key_);
 
   // We need to watch if the current Android context has changed and enforce
   // a clean-up in the compositor.
@@ -94,18 +84,7 @@
 
   // Should only need to access SharedRendererState in kModeDraw and kModeSync.
   const DrawGLInput input = shared_renderer_state_->GetDrawGLInput();
-
-  // Update memory budget. This will no-op in compositor if the policy has not
-  // changed since last draw.
-  content::SynchronousCompositorMemoryPolicy policy;
-  policy.bytes_limit = g_memory_multiplier * kBytesPerPixel *
-                       input.global_visible_rect.width() *
-                       input.global_visible_rect.height();
-  // Round up to a multiple of kMemoryAllocationStep.
-  policy.bytes_limit =
-      (policy.bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep;
-  policy.num_resources_limit = g_num_gralloc_limit;
-  SetMemoryPolicy(policy);
+  SetCompositorMemoryPolicy();
 
   gl_surface_->SetBackingFrameBufferObject(
       state_restore.framebuffer_binding_ext());
@@ -142,68 +121,14 @@
   return did_draw;
 }
 
-bool HardwareRenderer::TrimMemory(int level, bool visible) {
-  // Constants from Android ComponentCallbacks2.
-  enum {
-    TRIM_MEMORY_RUNNING_LOW = 10,
-    TRIM_MEMORY_UI_HIDDEN = 20,
-    TRIM_MEMORY_BACKGROUND = 40,
-  };
-
-  // Not urgent enough. TRIM_MEMORY_UI_HIDDEN is treated specially because
-  // it does not indicate memory pressure, but merely that the app is
-  // backgrounded.
-  if (level < TRIM_MEMORY_RUNNING_LOW || level == TRIM_MEMORY_UI_HIDDEN)
-    return false;
-
-  // Do not release resources on view we expect to get DrawGL soon.
-  if (level < TRIM_MEMORY_BACKGROUND && visible)
-    return false;
-
-  if (!eglGetCurrentContext()) {
-    NOTREACHED();
-    return false;
+void HardwareRenderer::SetCompositorMemoryPolicy() {
+  if (shared_renderer_state_->IsMemoryPolicyDirty()) {
+    content::SynchronousCompositorMemoryPolicy policy =
+        shared_renderer_state_->GetMemoryPolicy();
+    // Memory policy is set by BrowserViewRenderer on UI thread.
+    shared_renderer_state_->GetCompositor()->SetMemoryPolicy(policy);
+    shared_renderer_state_->SetMemoryPolicyDirty(false);
   }
-
-  DCHECK_EQ(last_egl_context_, eglGetCurrentContext());
-
-  // Just set the memory limit to 0 and drop all tiles. This will be reset to
-  // normal levels in the next DrawGL call.
-  content::SynchronousCompositorMemoryPolicy policy;
-  policy.bytes_limit = 0;
-  policy.num_resources_limit = 0;
-  if (memory_policy_ == policy)
-    return false;
-
-  TRACE_EVENT0("android_webview", "HardwareRenderer::TrimMemory");
-  ScopedAppGLStateRestore state_restore(
-      ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
-  internal::ScopedAllowGL allow_gl;
-
-  SetMemoryPolicy(policy);
-  return true;
-}
-
-void HardwareRenderer::SetMemoryPolicy(
-    content::SynchronousCompositorMemoryPolicy& new_policy) {
-  if (memory_policy_ == new_policy)
-    return;
-
-  memory_policy_ = new_policy;
-  shared_renderer_state_->GetCompositor()->
-      SetMemoryPolicy(memory_policy_);
-}
-
-// static
-void HardwareRenderer::CalculateTileMemoryPolicy() {
-  CommandLine* cl = CommandLine::ForCurrentProcess();
-
-  const char kDefaultTileSize[] = "384";
-  if (!cl->HasSwitch(switches::kDefaultTileWidth))
-    cl->AppendSwitchASCII(switches::kDefaultTileWidth, kDefaultTileSize);
-
-  if (!cl->HasSwitch(switches::kDefaultTileHeight))
-    cl->AppendSwitchASCII(switches::kDefaultTileHeight, kDefaultTileSize);
 }
 
 namespace internal {
diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h
index 09580eb..b290058 100644
--- a/android_webview/browser/hardware_renderer.h
+++ b/android_webview/browser/hardware_renderer.h
@@ -12,7 +12,6 @@
 #include "base/lazy_instance.h"
 #include "base/memory/ref_counted.h"
 #include "base/threading/thread_local.h"
-#include "content/public/browser/android/synchronous_compositor.h"
 
 struct AwDrawGLInfo;
 
@@ -30,15 +29,12 @@
   explicit HardwareRenderer(SharedRendererState* state);
   ~HardwareRenderer();
 
-  static void CalculateTileMemoryPolicy();
-
   bool DrawGL(AwDrawGLInfo* draw_info, DrawGLResult* result);
-  bool TrimMemory(int level, bool visible);
 
  private:
   friend class internal::DeferredGpuCommandService;
 
-  void SetMemoryPolicy(content::SynchronousCompositorMemoryPolicy& new_policy);
+  void SetCompositorMemoryPolicy();
 
   SharedRendererState* shared_renderer_state_;
 
@@ -46,9 +42,8 @@
   EGLContext last_egl_context_;
 
   scoped_refptr<AwGLSurface> gl_surface_;
-  content::SynchronousCompositorMemoryPolicy memory_policy_;
 
-  GLViewRendererManager::Key manager_key_;
+  GLViewRendererManager::Key renderer_manager_key_;
 
   DISALLOW_COPY_AND_ASSIGN(HardwareRenderer);
 };
diff --git a/android_webview/browser/icon_helper.cc b/android_webview/browser/icon_helper.cc
index cc5ae42..8922a7e 100644
--- a/android_webview/browser/icon_helper.cc
+++ b/android_webview/browser/icon_helper.cc
@@ -57,7 +57,7 @@
     listener_->OnReceivedIcon(image_url, bitmaps[0]);
 }
 
-void IconHelper::DidUpdateFaviconURL(int32 page_id,
+void IconHelper::DidUpdateFaviconURL(
     const std::vector<content::FaviconURL>& candidates) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   for (std::vector<content::FaviconURL>::const_iterator i = candidates.begin();
diff --git a/android_webview/browser/icon_helper.h b/android_webview/browser/icon_helper.h
index 13caefe..f325450 100644
--- a/android_webview/browser/icon_helper.h
+++ b/android_webview/browser/icon_helper.h
@@ -42,7 +42,7 @@
   void SetListener(Listener* listener);
 
   // From WebContentsObserver
-  virtual void DidUpdateFaviconURL(int32 page_id,
+  virtual void DidUpdateFaviconURL(
       const std::vector<content::FaviconURL>& candidates) OVERRIDE;
   virtual void DidStartNavigationToPendingEntry(
       const GURL& url,
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc
index a6bd025..2850b44 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.cc
+++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -15,6 +15,9 @@
 #include "base/command_line.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/threading/sequenced_worker_pool.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h"
+#include "components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/cookie_store_factory.h"
@@ -34,6 +37,7 @@
 #include "net/url_request/url_request_context.h"
 
 using content::BrowserThread;
+using data_reduction_proxy::DataReductionProxySettings;
 
 namespace android_webview {
 
@@ -162,9 +166,11 @@
     const base::FilePath& partition_path, net::CookieStore* cookie_store)
     : partition_path_(partition_path),
       cookie_store_(cookie_store),
-      proxy_config_service_(net::ProxyService::CreateSystemProxyConfigService(
-          GetNetworkTaskRunner(),
-          NULL /* Ignored on Android */)) {
+      proxy_config_service_(new DataReductionProxyConfigService(
+          scoped_ptr<net::ProxyConfigService>(
+              net::ProxyService::CreateSystemProxyConfigService(
+                  GetNetworkTaskRunner(),
+                  NULL /* Ignored on Android */)).Pass())) {
   // CreateSystemProxyConfigService for Android must be called on main thread.
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
@@ -187,6 +193,12 @@
       AwContentBrowserClient::GetAcceptLangsImpl()));
   ApplyCmdlineOverridesToURLRequestContextBuilder(&builder);
 
+
+  builder.add_http_auth_handler_factory(
+      data_reduction_proxy::HttpAuthHandlerDataReductionProxy::Scheme(),
+      new data_reduction_proxy::HttpAuthHandlerDataReductionProxy::Factory(
+          DataReductionProxySettings::GetDataReductionProxies()));
+
   url_request_context_.reset(builder.Build());
   // TODO(mnaganov): Fix URLRequestContextBuilder to use proper threads.
   net::HttpNetworkSession::Params network_session_params;
@@ -202,6 +214,10 @@
           partition_path_.Append(FILE_PATH_LITERAL("Cache")),
           20 * 1024 * 1024,  // 20M
           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)));
+
+  DataReductionProxySettings::InitDataReductionProxySession(
+      main_cache->GetSession());
+
   main_http_factory_.reset(main_cache);
   url_request_context_->set_http_transaction_factory(main_cache);
   url_request_context_->set_cookie_store(cookie_store_);
@@ -232,4 +248,10 @@
   std::swap(protocol_handlers_, *protocol_handlers);
 }
 
+DataReductionProxyConfigService*
+AwURLRequestContextGetter::proxy_config_service() {
+  // TODO(bengr): return system config if data reduction proxy is disabled.
+  return proxy_config_service_.get();
+}
+
 }  // namespace android_webview
diff --git a/android_webview/browser/net/aw_url_request_context_getter.h b/android_webview/browser/net/aw_url_request_context_getter.h
index c16098e..cef79e9 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.h
+++ b/android_webview/browser/net/aw_url_request_context_getter.h
@@ -22,6 +22,12 @@
 class URLRequestJobFactory;
 }
 
+namespace data_reduction_proxy {
+class DataReductionProxyConfigService;
+}
+
+using data_reduction_proxy::DataReductionProxyConfigService;
+
 namespace android_webview {
 
 class AwNetworkDelegate;
@@ -38,6 +44,8 @@
   virtual scoped_refptr<base::SingleThreadTaskRunner>
       GetNetworkTaskRunner() const OVERRIDE;
 
+  DataReductionProxyConfigService* proxy_config_service();
+
  private:
   friend class AwBrowserContext;
   virtual ~AwURLRequestContextGetter();
@@ -55,7 +63,7 @@
   const base::FilePath partition_path_;
   scoped_refptr<net::CookieStore> cookie_store_;
   scoped_ptr<net::URLRequestContext> url_request_context_;
-  scoped_ptr<net::ProxyConfigService> proxy_config_service_;
+  scoped_ptr<DataReductionProxyConfigService> proxy_config_service_;
   scoped_ptr<net::URLRequestJobFactory> job_factory_;
   scoped_ptr<net::HttpTransactionFactory> main_http_factory_;
 
diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc
index ffc91ea..3483d63 100644
--- a/android_webview/browser/shared_renderer_state.cc
+++ b/android_webview/browser/shared_renderer_state.cc
@@ -21,6 +21,8 @@
       client_on_ui_(client),
       weak_factory_on_ui_thread_(this),
       ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()),
+      compositor_(NULL),
+      memory_policy_dirty_(false),
       hardware_initialized_(false) {
   DCHECK(ui_loop_->BelongsToCurrentThread());
   DCHECK(client_on_ui_);
@@ -59,6 +61,21 @@
   return compositor_;
 }
 
+void SharedRendererState::SetMemoryPolicy(
+    const content::SynchronousCompositorMemoryPolicy new_policy) {
+  base::AutoLock lock(lock_);
+  if (memory_policy_ != new_policy) {
+    memory_policy_ = new_policy;
+    memory_policy_dirty_ = true;
+  }
+}
+
+content::SynchronousCompositorMemoryPolicy
+SharedRendererState::GetMemoryPolicy() const {
+  base::AutoLock lock(lock_);
+  return memory_policy_;
+}
+
 void SharedRendererState::SetDrawGLInput(const DrawGLInput& input) {
   base::AutoLock lock(lock_);
   draw_gl_input_ = input;
@@ -102,4 +119,14 @@
   return hardware_initialized_;
 }
 
+void SharedRendererState::SetMemoryPolicyDirty(bool is_dirty) {
+  base::AutoLock lock(lock_);
+  memory_policy_dirty_ = is_dirty;
+}
+
+bool SharedRendererState::IsMemoryPolicyDirty() const {
+  base::AutoLock lock(lock_);
+  return memory_policy_dirty_;
+}
+
 }  // namespace android_webview
diff --git a/android_webview/browser/shared_renderer_state.h b/android_webview/browser/shared_renderer_state.h
index c2c1eee..9c90731 100644
--- a/android_webview/browser/shared_renderer_state.h
+++ b/android_webview/browser/shared_renderer_state.h
@@ -55,6 +55,12 @@
 
   // This function can be called on both UI and RT thread.
   content::SynchronousCompositor* GetCompositor();
+
+  void SetMemoryPolicy(const content::SynchronousCompositorMemoryPolicy policy);
+  content::SynchronousCompositorMemoryPolicy GetMemoryPolicy() const;
+
+  void SetMemoryPolicyDirty(bool is_dirty);
+  bool IsMemoryPolicyDirty() const;
   void SetDrawGLInput(const DrawGLInput& input);
   DrawGLInput GetDrawGLInput() const;
 
@@ -78,6 +84,10 @@
   // Accessed by both UI and RT thread.
   mutable base::Lock lock_;
   content::SynchronousCompositor* compositor_;
+  content::SynchronousCompositorMemoryPolicy memory_policy_;
+  // Set to true when SetMemoryPolicy called with a different memory policy.
+  // Set to false when memory policy is read and enforced to compositor.
+  bool memory_policy_dirty_;
   DrawGLInput draw_gl_input_;
   std::queue<base::Closure> closure_queue_;
   bool hardware_initialized_;
diff --git a/android_webview/buildbot/aosp_manifest.xml b/android_webview/buildbot/aosp_manifest.xml
index aa91a54..d363420 100644
--- a/android_webview/buildbot/aosp_manifest.xml
+++ b/android_webview/buildbot/aosp_manifest.xml
@@ -244,7 +244,7 @@
   <project path="frameworks/testing" name="platform/frameworks/testing" />
   <project path="frameworks/uiautomator" name="platform/frameworks/uiautomator" />
   <project path="frameworks/volley" name="platform/frameworks/volley" />
-  <project path="frameworks/webview" name="platform/frameworks/webview" revision="24c4a3d70e8a2f1001e100ac78c0c1673c5710c3" remote="aosp" />
+  <project path="frameworks/webview" name="platform/frameworks/webview" revision="d36825d5b76e90f1ef4f54676cdf34b3bacd043b" remote="aosp" />
   <project path="frameworks/wilhelm" name="platform/frameworks/wilhelm" />
   <project path="hardware/akm" name="platform/hardware/akm" />
   <project path="hardware/broadcom/libbt" name="platform/hardware/broadcom/libbt" groups="pdk" />
diff --git a/android_webview/common/devtools_instrumentation.h b/android_webview/common/devtools_instrumentation.h
index 822ffc1..5007cae 100644
--- a/android_webview/common/devtools_instrumentation.h
+++ b/android_webview/common/devtools_instrumentation.h
@@ -11,7 +11,7 @@
 namespace devtools_instrumentation {
 
 namespace internal {
-const char kCategory[] = "Java,devtools";
+const char kCategory[] = "Java,devtools,disabled-by-default-devtools.timeline";
 const char kEmbedderCallback[] = "EmbedderCallback";
 const char kCallbackNameArgument[] = "callbackName";
 }  // namespace internal
diff --git a/android_webview/java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java b/android_webview/java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java
index 490f29e..286d8c1 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java
@@ -58,7 +58,7 @@
                 });
         }
         mAutofillPopup.setAnchorRect(x, y, width, height);
-        mAutofillPopup.show(suggestions);
+        mAutofillPopup.filterAndShow(suggestions);
     }
 
     @CalledByNative
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
index d52ad4e..c6e8ae0 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
@@ -28,7 +28,6 @@
     private AwFormDatabase mFormDatabase;
     private HttpAuthDatabase mHttpAuthDatabase;
     private DefaultAndroidKeyStore mLocalKeyStore;
-    private ClientCertLookupTable mClientCertLookupTable;
 
     public AwBrowserContext(SharedPreferences sharedPreferences) {
         mSharedPreferences = sharedPreferences;
@@ -69,13 +68,6 @@
         return mLocalKeyStore;
     }
 
-    public ClientCertLookupTable getClientCertLookupTable() {
-        if (mClientCertLookupTable == null) {
-            mClientCertLookupTable = new ClientCertLookupTable();
-        }
-        return mClientCertLookupTable;
-    }
-
     /**
      * @see android.webkit.WebView#pauseTimers()
      */
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index f166d99..762b4b6 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -37,6 +37,7 @@
 
 import com.google.common.annotations.VisibleForTesting;
 
+import org.chromium.android_webview.permission.AwPermissionRequest;
 import org.chromium.base.CalledByNative;
 import org.chromium.base.JNINamespace;
 import org.chromium.base.ThreadUtils;
@@ -60,9 +61,8 @@
 import java.lang.annotation.Annotation;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.concurrent.Callable;
 
@@ -238,11 +238,6 @@
     // (ie before it is destroyed).
     private CleanupReference mCleanupReference;
 
-    // A list of references to native pointers where the Java counterpart has been
-    // destroyed, but are held here because they are waiting for onDetachFromWindow
-    // to release GL resources. This is cleared inside onDetachFromWindow.
-    private List<CleanupReference> mPendingDetachCleanupReferences;
-
     //--------------------------------------------------------------------------------------------
     private class IoThreadClientImpl implements AwContentsIoThreadClient {
         // All methods are called on the IO thread.
@@ -498,7 +493,7 @@
         mLayoutSizer.setDIPScale(mDIPScale);
         mWebContentsDelegate = new AwWebContentsDelegateAdapter(contentsClient, mContainerView);
         mContentsClientBridge = new AwContentsClientBridge(contentsClient,
-                mBrowserContext.getKeyStore(), mBrowserContext.getClientCertLookupTable());
+                mBrowserContext.getKeyStore(), AwContentsStatics.getClientCertLookupTable());
         mZoomControls = new AwZoomControls(this);
         mIoThreadClient = new IoThreadClientImpl();
         mInterceptNavigationDelegate = new InterceptNavigationDelegateImpl();
@@ -641,13 +636,17 @@
     }
 
     /**
-     * Deletes the native counterpart of this object. Normally happens immediately,
-     * but maybe deferred until the appropriate time for GL resource cleanup. Either way
-     * this is transparent to the caller: after this function returns the object is
-     * effectively dead and methods are no-ops.
+     * Deletes the native counterpart of this object.
      */
     public void destroy() {
         if (mCleanupReference != null) {
+            assert mNativeAwContents != 0;
+            // If we are attached, we have to call native detach to clean up
+            // hardware resources.
+            if (mIsAttachedToWindow) {
+                nativeOnDetachedFromWindow(mNativeAwContents);
+            }
+
             // We explicitly do not null out the mContentViewCore reference here
             // because ContentViewCore already has code to deal with the case
             // methods are called on it after it's been destroyed, and other
@@ -655,17 +654,7 @@
             mContentViewCore.destroy();
             mNativeAwContents = 0;
 
-            // We cannot destroy immediately if we are still attached to the window.
-            // Instead if we make sure to null out the native pointer so there is no more native
-            // calls, and delay the actual destroy until onDetachedFromWindow.
-            if (mIsAttachedToWindow) {
-                if (mPendingDetachCleanupReferences == null) {
-                    mPendingDetachCleanupReferences = new ArrayList<CleanupReference>();
-                }
-                mPendingDetachCleanupReferences.add(mCleanupReference);
-            } else {
-                mCleanupReference.cleanupNow();
-            }
+            mCleanupReference.cleanupNow();
             mCleanupReference = null;
         }
 
@@ -911,7 +900,7 @@
         Map<String, String> extraHeaders = params.getExtraHeaders();
         if (extraHeaders != null) {
             for (String header : extraHeaders.keySet()) {
-                if (REFERER.equals(header.toLowerCase())) {
+                if (REFERER.equals(header.toLowerCase(Locale.US))) {
                     params.setReferrer(new Referrer(extraHeaders.remove(header), 1));
                     params.setExtraHeaders(extraHeaders);
                     break;
@@ -1373,14 +1362,8 @@
         mContentViewCore.clearSslPreferences();
     }
 
-    /**
-     * @see android.webkit.WebView#clearClientCertPreferences()
-     */
-    public void clearClientCertPreferences() {
-        mBrowserContext.getClientCertLookupTable().clear();
-        if (mNativeAwContents == 0) return;
-        nativeClearClientCertPreferences(mNativeAwContents);
-    }
+    // TODO(sgurun) remove after this rolls in. To keep internal tree happy.
+    public void clearClientCertPreferences() { }
 
     /**
      * Method to return all hit test values relevant to public WebView API.
@@ -1599,6 +1582,10 @@
      */
     public void onAttachedToWindow() {
         if (mNativeAwContents == 0) return;
+        if (mIsAttachedToWindow) {
+            Log.w(TAG, "onAttachedToWindow called when already attached. Ignoring");
+            return;
+        }
         mIsAttachedToWindow = true;
 
         mContentViewCore.onAttachedToWindow();
@@ -1616,6 +1603,10 @@
      */
     @SuppressLint("MissingSuperCall")
     public void onDetachedFromWindow() {
+        if (!mIsAttachedToWindow) {
+            Log.w(TAG, "onDetachedFromWindow called when already detached. Ignoring");
+            return;
+        }
         mIsAttachedToWindow = false;
         hideAutofillPopup();
         if (mNativeAwContents != 0) {
@@ -1631,13 +1622,6 @@
         }
 
         mScrollAccessibilityHelper.removePostedCallbacks();
-
-        if (mPendingDetachCleanupReferences != null) {
-            for (int i = 0; i < mPendingDetachCleanupReferences.size(); ++i) {
-                mPendingDetachCleanupReferences.get(i).cleanupNow();
-            }
-            mPendingDetachCleanupReferences = null;
-        }
     }
 
     /**
@@ -1885,6 +1869,16 @@
     }
 
     @CalledByNative
+    private void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
+        mContentsClient.onPermissionRequest(awPermissionRequest);
+    }
+
+    @CalledByNative
+    private void onPermissionRequestCanceled(AwPermissionRequest awPermissionRequest) {
+        mContentsClient.onPermissionRequestCanceled(awPermissionRequest);
+    }
+
+    @CalledByNative
     public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
             boolean isDoneCounting) {
         mContentsClient.onFindResultReceived(activeMatchOrdinal, numberOfMatches, isDoneCounting);
@@ -2077,6 +2071,7 @@
     private static native long nativeGetAwDrawGLFunction();
     private static native int nativeGetNativeInstanceCount();
     private static native void nativeSetShouldDownloadFavicons();
+
     private native void nativeSetJavaPeers(long nativeAwContents, AwContents awContents,
             AwWebContentsDelegate webViewWebContentsDelegate,
             AwContentsClientBridge contentsClientBridge,
@@ -2139,6 +2134,4 @@
     private native void nativeTrimMemory(long nativeAwContents, int level, boolean visible);
 
     private native void nativeCreatePdfExporter(long nativeAwContents, AwPdfExporter awPdfExporter);
-
-    private native void nativeClearClientCertPreferences(long nativeAwContents);
 }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
index fa59347..e5ce027 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
@@ -17,6 +17,7 @@
 import android.webkit.ValueCallback;
 import android.webkit.WebChromeClient;
 
+import org.chromium.android_webview.permission.AwPermissionRequest;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.WebContentsObserverAndroid;
 import org.chromium.net.NetError;
@@ -189,6 +190,13 @@
 
     public abstract void onGeolocationPermissionsHidePrompt();
 
+    // TODO(michaelbai): Change the abstract once merged
+    public /*abstract*/ void onPermissionRequest(AwPermissionRequest awPermissionRequest) {}
+
+    // TODO(michaelbai): Change the abstract once merged
+    public /*abstract*/ void onPermissionRequestCanceled(
+            AwPermissionRequest awPermissionRequest) {}
+
     public abstract void onScaleChangedScaled(float oldScale, float newScale);
 
     protected abstract void handleJsAlert(String url, String message, JsResultReceiver receiver);
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
index 7b0bb40..d495ba9 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
@@ -147,6 +147,7 @@
         }
 
         private void provideResponse(AndroidPrivateKey androidKey, byte[][] certChain) {
+            if (mNativeContentsClientBridge == 0) return;
             nativeProvideClientCertificateResponse(mNativeContentsClientBridge, mId,
                     certChain, androidKey);
         }
@@ -197,6 +198,7 @@
     @CalledByNative
     protected void selectClientCertificate(final int id, final String[] keyTypes,
             byte[][] encodedPrincipals, final String host, final int port) {
+        assert mNativeContentsClientBridge != 0;
         ClientCertLookupTable.Cert cert = mLookupTable.getCertData(host, port);
         if (mLookupTable.isDenied(host, port)) {
             nativeProvideClientCertificateResponse(mNativeContentsClientBridge, id,
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
new file mode 100644
index 0000000..a7fd4f8
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
@@ -0,0 +1,60 @@
+// 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.android_webview;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+import org.chromium.base.ThreadUtils;
+
+import java.lang.Runnable;
+
+/**
+ * Implementations of various static methods, and also a home for static
+ * data structures that are meant to be shared between all webviews.
+ */
+@JNINamespace("android_webview")
+public class AwContentsStatics {
+
+    private static ClientCertLookupTable sClientCertLookupTable;
+
+    /**
+     * Return the client certificate lookup table.
+     */
+    public static ClientCertLookupTable getClientCertLookupTable() {
+        ThreadUtils.assertOnUiThread();
+        if (sClientCertLookupTable == null) {
+            sClientCertLookupTable = new ClientCertLookupTable();
+        }
+        return sClientCertLookupTable;
+    }
+
+    /**
+     * Clear client cert lookup table. Should only be called from UI thread.
+     */
+    public static void clearClientCertPreferences(Runnable callback) {
+        ThreadUtils.assertOnUiThread();
+        getClientCertLookupTable().clear();
+        nativeClearClientCertPreferences(callback);
+    }
+
+    @CalledByNative
+    private static void clientCertificatesCleared(Runnable callback) {
+        if (callback == null) return;
+        callback.run();
+    }
+
+    /**
+     * Set Data Reduction Proxy key for authentication.
+     */
+    public static void setDataReductionProxyKey(String key) {
+        nativeSetDataReductionProxyKey(key);
+    }
+
+    //--------------------------------------------------------------------------------------------
+    //  Native methods
+    //--------------------------------------------------------------------------------------------
+    private static native void nativeClearClientCertPreferences(Runnable callback);
+    private static native void nativeSetDataReductionProxyKey(String key);
+}
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSettings.java b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
index 84449e8..315e354 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwSettings.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
@@ -385,7 +385,9 @@
                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
                     @Override
                     public void run() {
-                        nativeUpdateInitialPageScaleLocked(mNativeAwSettings);
+                        if (mNativeAwSettings != 0) {
+                            nativeUpdateInitialPageScaleLocked(mNativeAwSettings);
+                        }
                     }
                 });
             }
@@ -467,7 +469,9 @@
                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
                     @Override
                     public void run() {
-                        nativeUpdateFormDataPreferencesLocked(mNativeAwSettings);
+                        if (mNativeAwSettings != 0) {
+                            nativeUpdateFormDataPreferencesLocked(mNativeAwSettings);
+                        }
                     }
                 });
             }
@@ -512,7 +516,9 @@
                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
                     @Override
                     public void run() {
-                        nativeUpdateUserAgentLocked(mNativeAwSettings);
+                        if (mNativeAwSettings != 0) {
+                            nativeUpdateUserAgentLocked(mNativeAwSettings);
+                        }
                     }
                 });
             }
@@ -544,8 +550,10 @@
                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
                     @Override
                     public void run() {
-                        updateWebkitPreferencesOnUiThreadLocked();
-                        nativeResetScrollAndScaleState(mNativeAwSettings);
+                        if (mNativeAwSettings != 0) {
+                            updateWebkitPreferencesOnUiThreadLocked();
+                            nativeResetScrollAndScaleState(mNativeAwSettings);
+                        }
                     }
                 });
             }
@@ -1481,7 +1489,9 @@
                 mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
                     @Override
                     public void run() {
-                        nativeUpdateRendererPreferencesLocked(mNativeAwSettings);
+                        if (mNativeAwSettings != 0) {
+                            nativeUpdateRendererPreferencesLocked(mNativeAwSettings);
+                        }
                     }
                 });
             }
@@ -1539,6 +1549,7 @@
     @CalledByNative
     private void updateEverything() {
         synchronized (mAwSettingsLock) {
+            assert mNativeAwSettings != 0;
             nativeUpdateEverythingLocked(mNativeAwSettings);
         }
     }
@@ -1546,6 +1557,7 @@
     @CalledByNative
     private void populateWebPreferences(long webPrefsPtr) {
         synchronized (mAwSettingsLock) {
+            assert mNativeAwSettings != 0;
             nativePopulateWebPreferencesLocked(mNativeAwSettings, webPrefsPtr);
         }
     }
@@ -1553,7 +1565,9 @@
     private void updateWebkitPreferencesOnUiThreadLocked() {
         assert mEventHandler.mHandler != null;
         ThreadUtils.assertOnUiThread();
-        nativeUpdateWebkitPreferencesLocked(mNativeAwSettings);
+        if (mNativeAwSettings != 0) {
+            nativeUpdateWebkitPreferencesLocked(mNativeAwSettings);
+        }
     }
 
     private native long nativeInit(long webContentsPtr);
diff --git a/android_webview/java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java b/android_webview/java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java
index 985fc42..7de5e3c 100644
--- a/android_webview/java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java
+++ b/android_webview/java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java
@@ -63,7 +63,7 @@
     private static WeakReference<ExternalVideoSurfaceContainer> sActiveContainer =
             new WeakReference<ExternalVideoSurfaceContainer>(null);
 
-    private final int mNativeExternalVideoSurfaceContainer;
+    private final long mNativeExternalVideoSurfaceContainer;
     private final ContentViewCore mContentViewCore;
     private int mPlayerId = INVALID_PLAYER_ID;
     private SurfaceView mSurfaceView;
@@ -85,7 +85,7 @@
      */
     public static class Factory {
         public ExternalVideoSurfaceContainer create(
-                int nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
+                long nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
             return new ExternalVideoSurfaceContainer(
                     nativeExternalVideoSurfaceContainer, contentViewCore);
         }
@@ -99,12 +99,12 @@
 
     @CalledByNative
     private static ExternalVideoSurfaceContainer create(
-            int nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
+            long nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
         return sFactory.create(nativeExternalVideoSurfaceContainer, contentViewCore);
     }
 
     protected ExternalVideoSurfaceContainer(
-            int nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
+            long nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
         assert contentViewCore != null;
         mNativeExternalVideoSurfaceContainer = nativeExternalVideoSurfaceContainer;
         mContentViewCore = contentViewCore;
diff --git a/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java b/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java
new file mode 100644
index 0000000..c622b95
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java
@@ -0,0 +1,89 @@
+// 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.android_webview.permission;
+
+import android.net.Uri;
+import android.util.Log;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+import org.chromium.base.ThreadUtils;
+
+/**
+ * This class wraps permission request in Chromium side, and can only be created
+ * by native side.
+ */
+@JNINamespace("android_webview")
+public class AwPermissionRequest {
+    private static String TAG = "AwPermissionRequest";
+
+    private Uri mOrigin;
+    private long mResources;
+    private boolean mProcessed;
+
+    // AwPermissionRequest native instance.
+    private long mNativeAwPermissionRequest;
+
+    @CalledByNative
+    private static AwPermissionRequest create(long nativeAwPermissionRequest, String url,
+            long resources) {
+        if (nativeAwPermissionRequest == 0) return null;
+        Uri origin = Uri.parse(url);
+        return new AwPermissionRequest(nativeAwPermissionRequest, origin, resources);
+    }
+
+    private AwPermissionRequest(long nativeAwPermissionRequest, Uri origin,
+            long resources) {
+        mNativeAwPermissionRequest = nativeAwPermissionRequest;
+        mOrigin = origin;
+        mResources = resources;
+    }
+
+    public Uri getOrigin() {
+        return mOrigin;
+    }
+
+    public long getResources() {
+        return mResources;
+    }
+
+    public void grant() {
+        validate();
+        if (mNativeAwPermissionRequest != 0)
+            nativeOnAccept(mNativeAwPermissionRequest, true);
+        mProcessed = true;
+    }
+
+    public void deny() {
+        validate();
+        if (mNativeAwPermissionRequest != 0)
+            nativeOnAccept(mNativeAwPermissionRequest, false);
+        mProcessed = true;
+    }
+
+    @CalledByNative
+    private void detachNativeInstance() {
+        mNativeAwPermissionRequest = 0;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        if (mNativeAwPermissionRequest == 0) return;
+        Log.e(TAG, "Neither grant() nor deny() has been called, "
+                + "the permission request is denied by default.");
+        deny();
+    }
+
+    private void validate() {
+        if (!ThreadUtils.runningOnUiThread())
+            throw new IllegalStateException(
+                    "Either grant() or deny() should be called on UI thread");
+
+        if (mProcessed)
+            throw new IllegalStateException("Either grant() or deny() has been already called.");
+    }
+
+    private native void nativeOnAccept(long nativeAwPermissionRequest, boolean allowed);
+}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsStaticsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsStaticsTest.java
new file mode 100644
index 0000000..fa8d0bd
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsStaticsTest.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.android_webview.test;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.android_webview.AwContentsStatics;
+import org.chromium.base.test.util.Feature;
+import org.chromium.content.browser.test.util.CallbackHelper;
+
+/**
+ * AwContentsStatics tests.
+ */
+public class AwContentsStaticsTest extends AwTestBase {
+
+    private static class ClearClientCertCallbackHelper extends CallbackHelper
+            implements Runnable {
+        @Override
+        public void run() {
+            notifyCalled();
+        }
+    }
+
+    @Feature({"AndroidWebView"})
+    @SmallTest
+    public void testClearClientCertPreferences() throws Throwable {
+        final ClearClientCertCallbackHelper callbackHelper = new ClearClientCertCallbackHelper();
+        int currentCallCount = callbackHelper.getCallCount();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Make sure calling clearClientCertPreferences with null callback does not
+                // cause a crash.
+                AwContentsStatics.clearClientCertPreferences(null);
+                AwContentsStatics.clearClientCertPreferences(callbackHelper);
+            }
+        });
+        callbackHelper.waitForCallback(currentCallCount);
+    }
+}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
index 46c9e5b..01a52a3 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
@@ -94,6 +94,8 @@
         }
     }
 
+    @LargeTest
+    @Feature({"AndroidWebView"})
     public void testCreateAndGcManyTimes() throws Throwable {
         final int CONCURRENT_INSTANCES = 4;
         final int REPETITIONS = 16;
@@ -134,6 +136,25 @@
         });
     }
 
+    @SmallTest
+    @Feature({"AndroidWebView"})
+    public void testUseAwSettingsAfterDestroy() throws Throwable {
+        AwTestContainerView awTestContainerView =
+                createAwTestContainerViewOnMainSync(mContentsClient);
+        AwSettings awSettings = getAwSettingsOnUiThread(awTestContainerView.getAwContents());
+        loadUrlSync(awTestContainerView.getAwContents(),
+                mContentsClient.getOnPageFinishedHelper(), CommonResources.ABOUT_HTML);
+        destroyAwContentsOnMainSync(awTestContainerView.getAwContents());
+
+        // AwSettings should still be usable even after native side is destroyed.
+        String newFontFamily = "serif";
+        awSettings.setStandardFontFamily(newFontFamily);
+        assertEquals(newFontFamily, awSettings.getStandardFontFamily());
+        boolean newBlockNetworkLoads = !awSettings.getBlockNetworkLoads();
+        awSettings.setBlockNetworkLoads(newBlockNetworkLoads);
+        assertEquals(newBlockNetworkLoads, awSettings.getBlockNetworkLoads());
+    }
+
     private int callDocumentHasImagesSync(final AwContents awContents)
             throws Throwable, InterruptedException {
         // Set up a container to hold the result object and a semaphore to
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
index e21e2e8..f307480 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -16,6 +16,8 @@
 import android.webkit.ValueCallback;
 import android.webkit.WebSettings;
 
+import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
+
 import org.apache.http.Header;
 import org.apache.http.HttpRequest;
 import org.chromium.android_webview.AwContents;
@@ -24,6 +26,7 @@
 import org.chromium.android_webview.InterceptedRequestData;
 import org.chromium.android_webview.test.util.CommonResources;
 import org.chromium.android_webview.test.util.ImagePageGenerator;
+import org.chromium.android_webview.test.util.VideoTestUtil;
 import org.chromium.android_webview.test.util.VideoTestWebServer;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
@@ -1723,8 +1726,12 @@
                 views.getClient1()));
     }
 
+    /*
     @SmallTest
     @Feature({"AndroidWebView", "Preferences"})
+    crbug.com/370950
+    */
+    @DisabledTest
     public void testFileUrlAccessWithTwoViews() throws Throwable {
         ViewPair views = createViews();
         runPerViewSettingsTest(
@@ -1732,8 +1739,12 @@
             new AwSettingsFileUrlAccessTestHelper(views.getContainer1(), views.getClient1(), 1));
     }
 
+    /*
     @SmallTest
     @Feature({"AndroidWebView", "Preferences"})
+    crbug.com/370950
+    */
+    @DisabledTest
     public void testContentUrlAccessWithTwoViews() throws Throwable {
         ViewPair views = createViews();
         runPerViewSettingsTest(
@@ -2543,14 +2554,14 @@
     */
     @DisabledTest
     public void testMediaPlaybackWithoutUserGesture() throws Throwable {
-        assertTrue(runVideoTest(false, -1));
+        assertTrue(VideoTestUtil.runVideoTest(this, false, WAIT_TIMEOUT_MS));
     }
 
     @SmallTest
     @Feature({"AndroidWebView", "Preferences"})
     public void testMediaPlaybackWithUserGesture() throws Throwable {
         // Wait for 5 second to see if video played.
-        assertFalse(runVideoTest(true, 5000));
+        assertFalse(VideoTestUtil.runVideoTest(this, true, scaleTimeout(5000)));
     }
 
     @SmallTest
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
index c476910..fd90331 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
@@ -17,8 +17,6 @@
 import org.chromium.android_webview.AwContentsClient;
 import org.chromium.android_webview.AwSettings;
 import org.chromium.android_webview.test.util.JSUtils;
-import org.chromium.android_webview.test.util.JavascriptEventObserver;
-import org.chromium.android_webview.test.util.VideoTestWebServer;
 import org.chromium.base.test.util.InMemorySharedPreferences;
 import org.chromium.content.browser.ContentSettings;
 import org.chromium.content.browser.LoadUrlParams;
@@ -37,8 +35,8 @@
  */
 public class AwTestBase
         extends ActivityInstrumentationTestCase2<AwTestRunnerActivity> {
-    protected static final long WAIT_TIMEOUT_MS = scaleTimeout(15000);
-    protected static final int CHECK_INTERVAL = 100;
+    public static final long WAIT_TIMEOUT_MS = scaleTimeout(15000);
+    public static final int CHECK_INTERVAL = 100;
     private static final String TAG = "AwTestBase";
 
     public AwTestBase() {
@@ -82,7 +80,7 @@
         return task.get();
     }
 
-    protected void enableJavaScriptOnUiThread(final AwContents awContents) {
+    public void enableJavaScriptOnUiThread(final AwContents awContents) {
         getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
@@ -91,7 +89,7 @@
         });
     }
 
-    protected void setNetworkAvailableOnUiThread(final AwContents awContents,
+    public void setNetworkAvailableOnUiThread(final AwContents awContents,
             final boolean networkUp) {
         getInstrumentation().runOnMainSync(new Runnable() {
             @Override
@@ -104,13 +102,13 @@
     /**
      * Loads url on the UI thread and blocks until onPageFinished is called.
      */
-    protected void loadUrlSync(final AwContents awContents,
+    public void loadUrlSync(final AwContents awContents,
                                CallbackHelper onPageFinishedHelper,
                                final String url) throws Exception {
         loadUrlSync(awContents, onPageFinishedHelper, url, null);
     }
 
-    protected void loadUrlSync(final AwContents awContents,
+    public void loadUrlSync(final AwContents awContents,
                                CallbackHelper onPageFinishedHelper,
                                final String url,
                                final Map<String, String> extraHeaders) throws Exception {
@@ -120,7 +118,7 @@
                 TimeUnit.MILLISECONDS);
     }
 
-    protected void loadUrlSyncAndExpectError(final AwContents awContents,
+    public void loadUrlSyncAndExpectError(final AwContents awContents,
             CallbackHelper onPageFinishedHelper,
             CallbackHelper onReceivedErrorHelper,
             final String url) throws Exception {
@@ -136,12 +134,12 @@
     /**
      * Loads url on the UI thread but does not block.
      */
-    protected void loadUrlAsync(final AwContents awContents,
+    public void loadUrlAsync(final AwContents awContents,
                                 final String url) throws Exception {
         loadUrlAsync(awContents, url, null);
     }
 
-    protected void loadUrlAsync(final AwContents awContents,
+    public void loadUrlAsync(final AwContents awContents,
                                 final String url,
                                 final Map<String, String> extraHeaders) {
         getInstrumentation().runOnMainSync(new Runnable() {
@@ -157,7 +155,7 @@
     /**
      * Posts url on the UI thread and blocks until onPageFinished is called.
      */
-    protected void postUrlSync(final AwContents awContents,
+    public void postUrlSync(final AwContents awContents,
             CallbackHelper onPageFinishedHelper, final String url,
             byte[] postData) throws Exception {
         int currentCallCount = onPageFinishedHelper.getCallCount();
@@ -169,7 +167,7 @@
     /**
      * Loads url on the UI thread but does not block.
      */
-    protected void postUrlAsync(final AwContents awContents,
+    public void postUrlAsync(final AwContents awContents,
             final String url, byte[] postData) throws Exception {
         class PostUrl implements Runnable {
             byte[] mPostData;
@@ -188,7 +186,7 @@
     /**
      * Loads data on the UI thread and blocks until onPageFinished is called.
      */
-    protected void loadDataSync(final AwContents awContents,
+    public void loadDataSync(final AwContents awContents,
                                 CallbackHelper onPageFinishedHelper,
                                 final String data, final String mimeType,
                                 final boolean isBase64Encoded) throws Exception {
@@ -198,7 +196,7 @@
                 TimeUnit.MILLISECONDS);
     }
 
-    protected void loadDataSyncWithCharset(final AwContents awContents,
+    public void loadDataSyncWithCharset(final AwContents awContents,
                                            CallbackHelper onPageFinishedHelper,
                                            final String data, final String mimeType,
                                            final boolean isBase64Encoded, final String charset)
@@ -218,7 +216,7 @@
     /**
      * Loads data on the UI thread but does not block.
      */
-    protected void loadDataAsync(final AwContents awContents, final String data,
+    public void loadDataAsync(final AwContents awContents, final String data,
                                  final String mimeType, final boolean isBase64Encoded)
             throws Exception {
         getInstrumentation().runOnMainSync(new Runnable() {
@@ -230,7 +228,7 @@
         });
     }
 
-    protected void loadDataWithBaseUrlSync(final AwContents awContents,
+    public void loadDataWithBaseUrlSync(final AwContents awContents,
             CallbackHelper onPageFinishedHelper, final String data, final String mimeType,
             final boolean isBase64Encoded, final String baseUrl,
             final String historyUrl) throws Throwable {
@@ -240,7 +238,7 @@
                 TimeUnit.MILLISECONDS);
     }
 
-    protected void loadDataWithBaseUrlAsync(final AwContents awContents,
+    public void loadDataWithBaseUrlAsync(final AwContents awContents,
             final String data, final String mimeType, final boolean isBase64Encoded,
             final String baseUrl, final String historyUrl) throws Throwable {
         runTestOnUiThread(new Runnable() {
@@ -255,7 +253,7 @@
     /**
      * Reloads the current page synchronously.
      */
-    protected void reloadSync(final AwContents awContents,
+    public void reloadSync(final AwContents awContents,
                               CallbackHelper onPageFinishedHelper) throws Exception {
         int currentCallCount = onPageFinishedHelper.getCallCount();
         getInstrumentation().runOnMainSync(new Runnable() {
@@ -287,12 +285,12 @@
         return new TestDependencyFactory();
     }
 
-    protected AwTestContainerView createAwTestContainerView(
+    public AwTestContainerView createAwTestContainerView(
             final AwContentsClient awContentsClient) {
         return createAwTestContainerView(awContentsClient, false);
     }
 
-    protected AwTestContainerView createAwTestContainerView(
+    public AwTestContainerView createAwTestContainerView(
             final AwContentsClient awContentsClient, boolean supportsLegacyQuirks) {
         AwTestContainerView testContainerView =
                 createDetachedAwTestContainerView(awContentsClient, supportsLegacyQuirks);
@@ -305,12 +303,12 @@
     private AwBrowserContext mBrowserContext =
             new AwBrowserContext(new InMemorySharedPreferences());
 
-    protected AwTestContainerView createDetachedAwTestContainerView(
+    public AwTestContainerView createDetachedAwTestContainerView(
             final AwContentsClient awContentsClient) {
         return createDetachedAwTestContainerView(awContentsClient, false);
     }
 
-    protected AwTestContainerView createDetachedAwTestContainerView(
+    public AwTestContainerView createDetachedAwTestContainerView(
             final AwContentsClient awContentsClient, boolean supportsLegacyQuirks) {
         final TestDependencyFactory testDependencyFactory = createTestDependencyFactory();
         final AwTestContainerView testContainerView =
@@ -323,12 +321,12 @@
         return testContainerView;
     }
 
-    protected AwTestContainerView createAwTestContainerViewOnMainSync(
+    public AwTestContainerView createAwTestContainerViewOnMainSync(
             final AwContentsClient client) throws Exception {
         return createAwTestContainerViewOnMainSync(client, false);
     }
 
-    protected AwTestContainerView createAwTestContainerViewOnMainSync(
+    public AwTestContainerView createAwTestContainerViewOnMainSync(
             final AwContentsClient client, final boolean supportsLegacyQuirks) throws Exception {
         final AtomicReference<AwTestContainerView> testContainerView =
                 new AtomicReference<AwTestContainerView>();
@@ -341,7 +339,7 @@
         return testContainerView.get();
     }
 
-    protected void destroyAwContentsOnMainSync(final AwContents awContents) {
+    public void destroyAwContentsOnMainSync(final AwContents awContents) {
         if (awContents == null) return;
         getInstrumentation().runOnMainSync(new Runnable() {
             @Override
@@ -351,7 +349,7 @@
         });
     }
 
-    protected String getTitleOnUiThread(final AwContents awContents) throws Exception {
+    public String getTitleOnUiThread(final AwContents awContents) throws Exception {
         return runTestOnUiThreadAndGetResult(new Callable<String>() {
             @Override
             public String call() throws Exception {
@@ -360,7 +358,7 @@
         });
     }
 
-    protected ContentSettings getContentSettingsOnUiThread(
+    public ContentSettings getContentSettingsOnUiThread(
             final AwContents awContents) throws Exception {
         return runTestOnUiThreadAndGetResult(new Callable<ContentSettings>() {
             @Override
@@ -370,7 +368,7 @@
         });
     }
 
-    protected AwSettings getAwSettingsOnUiThread(
+    public AwSettings getAwSettingsOnUiThread(
             final AwContents awContents) throws Exception {
         return runTestOnUiThreadAndGetResult(new Callable<AwSettings>() {
             @Override
@@ -384,7 +382,7 @@
      * Executes the given snippet of JavaScript code within the given ContentView. Returns the
      * result of its execution in JSON format.
      */
-    protected String executeJavaScriptAndWaitForResult(final AwContents awContents,
+    public String executeJavaScriptAndWaitForResult(final AwContents awContents,
             TestAwContentsClient viewClient, final String code) throws Exception {
         return JSUtils.executeJavaScriptAndWaitForResult(this, awContents,
                 viewClient.getOnEvaluateJavaScriptResultHelper(),
@@ -395,7 +393,7 @@
      * Wrapper around CriteriaHelper.pollForCriteria. This uses AwTestBase-specifc timeouts and
      * treats timeouts and exceptions as test failures automatically.
      */
-    protected static void poll(final Callable<Boolean> callable) throws Exception {
+    public static void poll(final Callable<Boolean> callable) throws Exception {
         assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
             @Override
             public boolean isSatisfied() {
@@ -412,7 +410,7 @@
     /**
      * Wrapper around {@link AwTestBase#poll()} but runs the callable on the UI thread.
      */
-    protected void pollOnUiThread(final Callable<Boolean> callable) throws Exception {
+    public void pollOnUiThread(final Callable<Boolean> callable) throws Exception {
         poll(new Callable<Boolean>() {
             @Override
             public Boolean call() throws Exception {
@@ -425,7 +423,7 @@
      * Clears the resource cache. Note that the cache is per-application, so this will clear the
      * cache for all WebViews used.
      */
-    protected void clearCacheOnUiThread(
+    public void clearCacheOnUiThread(
             final AwContents awContents,
             final boolean includeDiskFiles) throws Exception {
         getInstrumentation().runOnMainSync(new Runnable() {
@@ -439,7 +437,7 @@
     /**
      * Returns pure page scale.
      */
-    protected float getScaleOnUiThread(final AwContents awContents) throws Exception {
+    public float getScaleOnUiThread(final AwContents awContents) throws Exception {
         return runTestOnUiThreadAndGetResult(new Callable<Float>() {
             @Override
             public Float call() throws Exception {
@@ -451,7 +449,7 @@
     /**
      * Returns page scale multiplied by the screen density.
      */
-    protected float getPixelScaleOnUiThread(final AwContents awContents) throws Exception {
+    public float getPixelScaleOnUiThread(final AwContents awContents) throws Exception {
         return runTestOnUiThreadAndGetResult(new Callable<Float>() {
             @Override
             public Float call() throws Exception {
@@ -463,7 +461,7 @@
     /**
      * Returns whether a user can zoom the page in.
      */
-    protected boolean canZoomInOnUiThread(final AwContents awContents) throws Exception {
+    public boolean canZoomInOnUiThread(final AwContents awContents) throws Exception {
         return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
             @Override
             public Boolean call() throws Exception {
@@ -475,7 +473,7 @@
     /**
      * Returns whether a user can zoom the page out.
      */
-    protected boolean canZoomOutOnUiThread(final AwContents awContents) throws Exception {
+    public boolean canZoomOutOnUiThread(final AwContents awContents) throws Exception {
         return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
             @Override
             public Boolean call() throws Exception {
@@ -484,48 +482,4 @@
         });
     }
 
-    /**
-     * Run video test.
-     * @param requiredUserGesture the settings of MediaPlaybackRequiresUserGesture.
-     * @param waitTime time for waiting event happen, -1 means forever.
-     * @return true if the event happened,
-     * @throws Throwable throw exception if timeout.
-     */
-    protected boolean runVideoTest(final boolean requiredUserGesture, long waitTime)
-            throws Throwable {
-        final JavascriptEventObserver observer = new JavascriptEventObserver();
-        TestAwContentsClient client = new TestAwContentsClient();
-        final AwContents awContents = createAwTestContainerViewOnMainSync(client).getAwContents();
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                AwSettings awSettings = awContents.getSettings();
-                awSettings.setJavaScriptEnabled(true);
-                awSettings.setMediaPlaybackRequiresUserGesture(requiredUserGesture);
-                observer.register(awContents.getContentViewCore(), "javaObserver");
-            }
-        });
-        VideoTestWebServer webServer = new VideoTestWebServer(getActivity());
-        try {
-            String data = "<html><head><script>" +
-                "addEventListener('DOMContentLoaded', function() { " +
-                "  document.getElementById('video').addEventListener('play', function() { " +
-                "    javaObserver.notifyJava(); " +
-                "  }, false); " +
-                "}, false); " +
-                "</script></head><body>" +
-                "<video id='video' autoplay control src='" +
-                webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>";
-            loadDataAsync(awContents, data, "text/html", false);
-            if (waitTime == -1) {
-                observer.waitForEvent();
-                return true;
-            } else {
-                return observer.waitForEvent(waitTime);
-            }
-        } finally {
-            if (webServer != null && webServer.getTestWebServer() != null)
-                webServer.getTestWebServer().shutdown();
-        }
-    }
 }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ExternalVideoSurfaceContainerTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ExternalVideoSurfaceContainerTest.java
index ca4df0c..e4afe7c 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/ExternalVideoSurfaceContainerTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/ExternalVideoSurfaceContainerTest.java
@@ -8,6 +8,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import org.chromium.android_webview.ExternalVideoSurfaceContainer;
+import org.chromium.android_webview.test.util.VideoTestUtil;
 import org.chromium.base.CommandLine;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
@@ -55,7 +56,7 @@
         private int mPlayerId = INVALID_PLAYER_ID;
 
         public MockExternalVideoSurfaceContainer(
-                int nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
+                long nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
             super(nativeExternalVideoSurfaceContainer, contentViewCore);
         }
 
@@ -91,7 +92,7 @@
         ExternalVideoSurfaceContainer.setFactory(new ExternalVideoSurfaceContainer.Factory() {
             @Override
             public ExternalVideoSurfaceContainer create(
-                    int nativeContainer, ContentViewCore contentViewCore) {
+                    long nativeContainer, ContentViewCore contentViewCore) {
                 return new MockExternalVideoSurfaceContainer(nativeContainer, contentViewCore);
             }
         });
@@ -111,7 +112,7 @@
         int onRequestCallCount = mOnRequestExternalVideoSurface.getCallCount();
         int onPositionChangedCallCount = mOnExternalVideoSurfacePositionChanged.getCallCount();
 
-        assertTrue(runVideoTest(false, -1));
+        assertTrue(VideoTestUtil.runVideoTest(this, false, WAIT_TIMEOUT_MS));
 
         mOnRequestExternalVideoSurface.waitForCallback(onRequestCallCount);
         waitForVideoSizeChangeTo(mOnExternalVideoSurfacePositionChanged,
@@ -123,7 +124,7 @@
     public void testDisableVideoOverlayForEmbeddedVideo() throws Throwable {
         setUpMockExternalVideoSurfaceContainer();
 
-        assertTrue(runVideoTest(false, -1));
+        assertTrue(VideoTestUtil.runVideoTest(this, false, WAIT_TIMEOUT_MS));
 
         assertEquals(0, mOnRequestExternalVideoSurface.getCallCount());
         assertEquals(0, mOnExternalVideoSurfacePositionChanged.getCallCount());
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/TestAwContentsClient.java b/android_webview/javatests/src/org/chromium/android_webview/test/TestAwContentsClient.java
index ccd0da3..d96b5e7 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/TestAwContentsClient.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/TestAwContentsClient.java
@@ -14,7 +14,10 @@
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageStartedHelper;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnReceivedErrorHelper;
 
-class TestAwContentsClient extends NullContentsClient {
+/**
+ * AwContentsClient subclass used for testing.
+ */
+public class TestAwContentsClient extends NullContentsClient {
     private String mUpdatedTitle;
     private final OnPageStartedHelper mOnPageStartedHelper;
     private final OnPageFinishedHelper mOnPageFinishedHelper;
@@ -73,6 +76,9 @@
         return mAddMessageToConsoleHelper;
     }
 
+    /**
+     * Callback helper for onScaleChangedScaled.
+     */
     public static class OnScaleChangedHelper extends CallbackHelper {
         private float mPreviousScale;
         private float mCurrentScale;
@@ -227,6 +233,9 @@
         return false;
     }
 
+    /**
+     * Callback helper for onScaleChangedScaled.
+     */
     public static class AddMessageToConsoleHelper extends CallbackHelper {
         private int mLevel;
         private String mMessage;
@@ -267,6 +276,9 @@
         mOnScaleChangedHelper.notifyCalled(oldScale, newScale);
     }
 
+    /**
+     * Callback helper for onScaleChangedScaled.
+     */
     public static class PictureListenerHelper extends CallbackHelper {
         // Generally null, depending on |invalidationOnly| in enableOnNewPicture()
         private Picture mPicture;
@@ -287,6 +299,9 @@
         mPictureListenerHelper.notifyCalled(picture);
     }
 
+    /**
+     * Callback helper for onScaleChangedScaled.
+     */
     public static class ShouldOverrideUrlLoadingHelper extends CallbackHelper {
         private String mShouldOverrideUrlLoadingUrl;
         private String mPreviousShouldOverrideUrlLoadingUrl;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/util/VideoTestUtil.java b/android_webview/javatests/src/org/chromium/android_webview/test/util/VideoTestUtil.java
new file mode 100644
index 0000000..5df2a03
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/util/VideoTestUtil.java
@@ -0,0 +1,56 @@
+// 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.android_webview.test.util;
+
+import org.chromium.android_webview.AwContents;
+import org.chromium.android_webview.AwSettings;
+import org.chromium.android_webview.test.AwTestBase;
+import org.chromium.android_webview.test.TestAwContentsClient;
+
+/**
+ * Code shared between the various video tests.
+ */
+public class VideoTestUtil {
+    /**
+     * Run video test.
+     * @param testCase the test case instance we're going to run the test in.
+     * @param requiredUserGesture the settings of MediaPlaybackRequiresUserGesture.
+     * @return true if the event happened,
+     * @throws Throwable throw exception if timeout.
+     */
+   public static boolean runVideoTest(final AwTestBase testCase, final boolean requiredUserGesture,
+           long waitTime) throws Throwable {
+        final JavascriptEventObserver observer = new JavascriptEventObserver();
+        TestAwContentsClient client = new TestAwContentsClient();
+        final AwContents awContents =
+            testCase.createAwTestContainerViewOnMainSync(client).getAwContents();
+        testCase.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                AwSettings awSettings = awContents.getSettings();
+                awSettings.setJavaScriptEnabled(true);
+                awSettings.setMediaPlaybackRequiresUserGesture(requiredUserGesture);
+                observer.register(awContents.getContentViewCore(), "javaObserver");
+            }
+        });
+        VideoTestWebServer webServer = new VideoTestWebServer(testCase.getActivity());
+        try {
+            String data = "<html><head><script>" +
+                "addEventListener('DOMContentLoaded', function() { " +
+                "  document.getElementById('video').addEventListener('play', function() { " +
+                "    javaObserver.notifyJava(); " +
+                "  }, false); " +
+                "}, false); " +
+                "</script></head><body>" +
+                "<video id='video' autoplay control src='" +
+                webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>";
+            testCase.loadDataAsync(awContents, data, "text/html", false);
+            return observer.waitForEvent(waitTime);
+        } finally {
+            if (webServer != null && webServer.getTestWebServer() != null)
+                webServer.getTestWebServer().shutdown();
+        }
+    }
+}
diff --git a/android_webview/lib/main/aw_main_delegate.cc b/android_webview/lib/main/aw_main_delegate.cc
index 96be606..a71c0a6 100644
--- a/android_webview/lib/main/aw_main_delegate.cc
+++ b/android_webview/lib/main/aw_main_delegate.cc
@@ -5,8 +5,8 @@
 #include "android_webview/lib/main/aw_main_delegate.h"
 
 #include "android_webview/browser/aw_content_browser_client.h"
+#include "android_webview/browser/browser_view_renderer.h"
 #include "android_webview/browser/gpu_memory_buffer_factory_impl.h"
-#include "android_webview/browser/hardware_renderer.h"
 #include "android_webview/browser/scoped_allow_wait_for_legacy_web_view_api.h"
 #include "android_webview/lib/aw_browser_dependency_factory_impl.h"
 #include "android_webview/native/aw_geolocation_permission_context.h"
@@ -53,7 +53,7 @@
   gpu::InProcessCommandBuffer::SetGpuMemoryBufferFactory(
       gpu_memory_buffer_factory_.get());
 
-  HardwareRenderer::CalculateTileMemoryPolicy();
+  BrowserViewRenderer::CalculateTileMemoryPolicy();
 
   CommandLine* cl = CommandLine::ForCurrentProcess();
   cl->AppendSwitch(switches::kEnableBeginFrameScheduling);
diff --git a/android_webview/lib/main/webview_entry_point.cc b/android_webview/lib/main/webview_entry_point.cc
index 1eefd52..1aa1d27 100644
--- a/android_webview/lib/main/webview_entry_point.cc
+++ b/android_webview/lib/main/webview_entry_point.cc
@@ -49,10 +49,10 @@
 
   content::SetContentMainDelegate(new android_webview::AwMainDelegate());
 
-  // Initialize url_util here while we are still single-threaded, in case we use
+  // Initialize url lib here while we are still single-threaded, in case we use
   // CookieManager before initializing Chromium (which would normally have done
   // this). It's safe to call this multiple times.
-  url_util::Initialize();
+  url::Initialize();
 
   return JNI_VERSION_1_4;
 }
diff --git a/android_webview/lib/main/webview_tests.cc b/android_webview/lib/main/webview_tests.cc
index 2c8d29c..08109fe 100644
--- a/android_webview/lib/main/webview_tests.cc
+++ b/android_webview/lib/main/webview_tests.cc
@@ -2,8 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "android_webview/native/android_webview_jni_registrar.h"
+#include "base/android/jni_android.h"
 #include "base/test/test_suite.h"
 
 int main(int argc, char** argv) {
+  android_webview::RegisterJni(base::android::AttachCurrentThread());
   return base::TestSuite(argc, argv).Run();
 }
diff --git a/android_webview/libwebviewchromium.target.darwin-arm.mk b/android_webview/libwebviewchromium.target.darwin-arm.mk
index 805355e..245eade 100644
--- a/android_webview/libwebviewchromium.target.darwin-arm.mk
+++ b/android_webview/libwebviewchromium.target.darwin-arm.mk
@@ -76,6 +76,7 @@
 	$(call intermediates-dir-for,GYP,ui_gl_gl_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/gl_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,ui_gl_surface_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/surface_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_lib_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_lib_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_preprocessor_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_preprocessor_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gles2_cmd_helper_gyp,,,$(GYP_VAR_PREFIX))/gpu_gles2_cmd_helper_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gpu_config_gyp,,,$(GYP_VAR_PREFIX))/gpu_gpu_config_gyp.a \
@@ -147,6 +148,8 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_platform_make_platform_generated_gyp,,,$(GYP_VAR_PREFIX))/make_platform_generated.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_iccjpeg_iccjpeg_gyp,,,$(GYP_VAR_PREFIX))/third_party_iccjpeg_iccjpeg_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_harfbuzz_ng_harfbuzz_ng_gyp,,,$(GYP_VAR_PREFIX))/third_party_harfbuzz_ng_harfbuzz_ng_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_openmax_dl_dl_openmax_dl_gyp,,,$(GYP_VAR_PREFIX))/third_party_openmax_dl_dl_openmax_dl_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_openmax_dl_dl_openmax_dl_armv7_gyp,,,$(GYP_VAR_PREFIX))/third_party_openmax_dl_dl_openmax_dl_armv7_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_platform_blink_arm_neon_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_platform_blink_arm_neon_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_web_blink_web_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_web_blink_web_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_core_webcore_gyp,,,$(GYP_VAR_PREFIX))/webcore.stamp \
@@ -223,6 +226,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_frontend_protocol_sources_gyp,,,$(GYP_VAR_PREFIX))/frontend_protocol_sources.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_audits_module_gyp,,,$(GYP_VAR_PREFIX))/build_audits_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_core_module_gyp,,,$(GYP_VAR_PREFIX))/build_core_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_concatenated_module_descriptors_gyp,,,$(GYP_VAR_PREFIX))/concatenated_module_descriptors.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_console_module_gyp,,,$(GYP_VAR_PREFIX))/build_console_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_devices_module_gyp,,,$(GYP_VAR_PREFIX))/build_devices_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_elements_module_gyp,,,$(GYP_VAR_PREFIX))/build_elements_module.stamp \
@@ -232,6 +236,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_profiler_module_gyp,,,$(GYP_VAR_PREFIX))/build_profiler_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_resources_module_gyp,,,$(GYP_VAR_PREFIX))/build_resources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_search_module_gyp,,,$(GYP_VAR_PREFIX))/build_search_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_settings_module_gyp,,,$(GYP_VAR_PREFIX))/build_settings_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_source_frame_module_gyp,,,$(GYP_VAR_PREFIX))/build_source_frame_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_sources_module_gyp,,,$(GYP_VAR_PREFIX))/build_sources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_timeline_module_gyp,,,$(GYP_VAR_PREFIX))/build_timeline_module.stamp \
@@ -245,6 +250,7 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_surface_surface_gyp,,,$(GYP_VAR_PREFIX))/ui_surface_surface_gyp.a \
 	$(call intermediates-dir-for,GYP,webkit_webkit_strings_gyp,,,$(GYP_VAR_PREFIX))/webkit_strings.stamp \
 	$(call intermediates-dir-for,GYP,third_party_angle_src_commit_id_gyp,,,$(GYP_VAR_PREFIX))/commit_id.stamp \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,printing_printing_gyp,,,$(GYP_VAR_PREFIX))/printing_printing_gyp.a \
 	$(call intermediates-dir-for,GYP,printing_printing_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/printing_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,sandbox_sandbox_gyp,,,$(GYP_VAR_PREFIX))/sandbox.stamp \
@@ -328,6 +334,11 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,lib_core_neon_offsets,,,$(GYP_VAR_PREFIX))/lib_core_neon_offsets.a \
 	$(call intermediates-dir-for,GYP,third_party_webrtc_modules_audio_processing_gen_aecm_core_neon_offsets_h_gyp,,,$(GYP_VAR_PREFIX))/gen_aecm_core_neon_offsets_h.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_device_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_device_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_browser_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_common_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_common_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_renderer_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_renderer_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_browser_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_common_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_common_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_navigation_interception_gyp,,,$(GYP_VAR_PREFIX))/components_navigation_interception_gyp.a \
 	$(call intermediates-dir-for,GYP,components_navigation_interception_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/navigation_interception_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_visitedlink_browser_gyp,,,$(GYP_VAR_PREFIX))/components_visitedlink_browser_gyp.a \
@@ -365,7 +376,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -459,7 +469,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -622,6 +631,7 @@
 	ui_gfx_gfx_geometry_gyp \
 	ui_gl_gl_gyp \
 	third_party_angle_src_translator_gyp \
+	third_party_angle_src_translator_lib_gyp \
 	third_party_angle_src_preprocessor_gyp \
 	gpu_gles2_cmd_helper_gyp \
 	gpu_gpu_config_gyp \
@@ -673,6 +683,8 @@
 	v8_tools_gyp_v8_snapshot_gyp \
 	third_party_iccjpeg_iccjpeg_gyp \
 	third_party_harfbuzz_ng_harfbuzz_ng_gyp \
+	third_party_openmax_dl_dl_openmax_dl_gyp \
+	third_party_openmax_dl_dl_openmax_dl_armv7_gyp \
 	third_party_WebKit_Source_platform_blink_arm_neon_gyp \
 	third_party_WebKit_Source_web_blink_web_gyp \
 	third_party_WebKit_Source_core_webcore_dom_gyp \
@@ -782,6 +794,11 @@
 	third_party_webrtc_modules_audio_processing_neon_gyp \
 	lib_core_neon_offsets \
 	third_party_webrtc_modules_audio_device_gyp \
+	components_cdm_browser_gyp \
+	components_cdm_common_gyp \
+	components_cdm_renderer_gyp \
+	components_data_reduction_proxy_browser_gyp \
+	components_data_reduction_proxy_common_gyp \
 	components_navigation_interception_gyp \
 	components_visitedlink_browser_gyp \
 	components_visitedlink_common_gyp \
diff --git a/android_webview/libwebviewchromium.target.darwin-arm64.mk b/android_webview/libwebviewchromium.target.darwin-arm64.mk
index b5c7712..882ab6d 100644
--- a/android_webview/libwebviewchromium.target.darwin-arm64.mk
+++ b/android_webview/libwebviewchromium.target.darwin-arm64.mk
@@ -75,6 +75,7 @@
 	$(call intermediates-dir-for,GYP,ui_gl_gl_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/gl_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,ui_gl_surface_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/surface_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_lib_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_lib_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_preprocessor_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_preprocessor_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gles2_cmd_helper_gyp,,,$(GYP_VAR_PREFIX))/gpu_gles2_cmd_helper_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gpu_config_gyp,,,$(GYP_VAR_PREFIX))/gpu_gpu_config_gyp.a \
@@ -220,6 +221,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_frontend_protocol_sources_gyp,,,$(GYP_VAR_PREFIX))/frontend_protocol_sources.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_audits_module_gyp,,,$(GYP_VAR_PREFIX))/build_audits_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_core_module_gyp,,,$(GYP_VAR_PREFIX))/build_core_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_concatenated_module_descriptors_gyp,,,$(GYP_VAR_PREFIX))/concatenated_module_descriptors.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_console_module_gyp,,,$(GYP_VAR_PREFIX))/build_console_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_devices_module_gyp,,,$(GYP_VAR_PREFIX))/build_devices_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_elements_module_gyp,,,$(GYP_VAR_PREFIX))/build_elements_module.stamp \
@@ -229,6 +231,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_profiler_module_gyp,,,$(GYP_VAR_PREFIX))/build_profiler_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_resources_module_gyp,,,$(GYP_VAR_PREFIX))/build_resources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_search_module_gyp,,,$(GYP_VAR_PREFIX))/build_search_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_settings_module_gyp,,,$(GYP_VAR_PREFIX))/build_settings_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_source_frame_module_gyp,,,$(GYP_VAR_PREFIX))/build_source_frame_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_sources_module_gyp,,,$(GYP_VAR_PREFIX))/build_sources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_timeline_module_gyp,,,$(GYP_VAR_PREFIX))/build_timeline_module.stamp \
@@ -242,6 +245,7 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_surface_surface_gyp,,,$(GYP_VAR_PREFIX))/ui_surface_surface_gyp.a \
 	$(call intermediates-dir-for,GYP,webkit_webkit_strings_gyp,,,$(GYP_VAR_PREFIX))/webkit_strings.stamp \
 	$(call intermediates-dir-for,GYP,third_party_angle_src_commit_id_gyp,,,$(GYP_VAR_PREFIX))/commit_id.stamp \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,printing_printing_gyp,,,$(GYP_VAR_PREFIX))/printing_printing_gyp.a \
 	$(call intermediates-dir-for,GYP,printing_printing_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/printing_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,sandbox_sandbox_gyp,,,$(GYP_VAR_PREFIX))/sandbox.stamp \
@@ -313,6 +317,11 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_processing_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_processing_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audioproc_debug_proto_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audioproc_debug_proto_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_device_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_device_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_browser_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_common_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_common_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_renderer_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_renderer_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_browser_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_common_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_common_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_navigation_interception_gyp,,,$(GYP_VAR_PREFIX))/components_navigation_interception_gyp.a \
 	$(call intermediates-dir-for,GYP,components_navigation_interception_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/navigation_interception_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_visitedlink_browser_gyp,,,$(GYP_VAR_PREFIX))/components_visitedlink_browser_gyp.a \
@@ -588,6 +597,7 @@
 	ui_gfx_gfx_geometry_gyp \
 	ui_gl_gl_gyp \
 	third_party_angle_src_translator_gyp \
+	third_party_angle_src_translator_lib_gyp \
 	third_party_angle_src_preprocessor_gyp \
 	gpu_gles2_cmd_helper_gyp \
 	gpu_gpu_config_gyp \
@@ -737,6 +747,11 @@
 	third_party_webrtc_modules_audio_processing_gyp \
 	third_party_webrtc_modules_audioproc_debug_proto_gyp \
 	third_party_webrtc_modules_audio_device_gyp \
+	components_cdm_browser_gyp \
+	components_cdm_common_gyp \
+	components_cdm_renderer_gyp \
+	components_data_reduction_proxy_browser_gyp \
+	components_data_reduction_proxy_common_gyp \
 	components_navigation_interception_gyp \
 	components_visitedlink_browser_gyp \
 	components_visitedlink_common_gyp \
diff --git a/android_webview/libwebviewchromium.target.darwin-mips.mk b/android_webview/libwebviewchromium.target.darwin-mips.mk
index 2bc87bb..ee2fc6dc 100644
--- a/android_webview/libwebviewchromium.target.darwin-mips.mk
+++ b/android_webview/libwebviewchromium.target.darwin-mips.mk
@@ -75,6 +75,7 @@
 	$(call intermediates-dir-for,GYP,ui_gl_gl_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/gl_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,ui_gl_surface_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/surface_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_lib_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_lib_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_preprocessor_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_preprocessor_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gles2_cmd_helper_gyp,,,$(GYP_VAR_PREFIX))/gpu_gles2_cmd_helper_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gpu_config_gyp,,,$(GYP_VAR_PREFIX))/gpu_gpu_config_gyp.a \
@@ -220,6 +221,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_frontend_protocol_sources_gyp,,,$(GYP_VAR_PREFIX))/frontend_protocol_sources.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_audits_module_gyp,,,$(GYP_VAR_PREFIX))/build_audits_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_core_module_gyp,,,$(GYP_VAR_PREFIX))/build_core_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_concatenated_module_descriptors_gyp,,,$(GYP_VAR_PREFIX))/concatenated_module_descriptors.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_console_module_gyp,,,$(GYP_VAR_PREFIX))/build_console_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_devices_module_gyp,,,$(GYP_VAR_PREFIX))/build_devices_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_elements_module_gyp,,,$(GYP_VAR_PREFIX))/build_elements_module.stamp \
@@ -229,6 +231,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_profiler_module_gyp,,,$(GYP_VAR_PREFIX))/build_profiler_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_resources_module_gyp,,,$(GYP_VAR_PREFIX))/build_resources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_search_module_gyp,,,$(GYP_VAR_PREFIX))/build_search_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_settings_module_gyp,,,$(GYP_VAR_PREFIX))/build_settings_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_source_frame_module_gyp,,,$(GYP_VAR_PREFIX))/build_source_frame_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_sources_module_gyp,,,$(GYP_VAR_PREFIX))/build_sources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_timeline_module_gyp,,,$(GYP_VAR_PREFIX))/build_timeline_module.stamp \
@@ -242,6 +245,7 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_surface_surface_gyp,,,$(GYP_VAR_PREFIX))/ui_surface_surface_gyp.a \
 	$(call intermediates-dir-for,GYP,webkit_webkit_strings_gyp,,,$(GYP_VAR_PREFIX))/webkit_strings.stamp \
 	$(call intermediates-dir-for,GYP,third_party_angle_src_commit_id_gyp,,,$(GYP_VAR_PREFIX))/commit_id.stamp \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,printing_printing_gyp,,,$(GYP_VAR_PREFIX))/printing_printing_gyp.a \
 	$(call intermediates-dir-for,GYP,printing_printing_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/printing_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,sandbox_sandbox_gyp,,,$(GYP_VAR_PREFIX))/sandbox.stamp \
@@ -311,6 +315,11 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_processing_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_processing_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audioproc_debug_proto_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audioproc_debug_proto_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_device_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_device_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_browser_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_common_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_common_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_renderer_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_renderer_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_browser_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_common_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_common_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_navigation_interception_gyp,,,$(GYP_VAR_PREFIX))/components_navigation_interception_gyp.a \
 	$(call intermediates-dir-for,GYP,components_navigation_interception_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/navigation_interception_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_visitedlink_browser_gyp,,,$(GYP_VAR_PREFIX))/components_visitedlink_browser_gyp.a \
@@ -598,6 +607,7 @@
 	ui_gfx_gfx_geometry_gyp \
 	ui_gl_gl_gyp \
 	third_party_angle_src_translator_gyp \
+	third_party_angle_src_translator_lib_gyp \
 	third_party_angle_src_preprocessor_gyp \
 	gpu_gles2_cmd_helper_gyp \
 	gpu_gpu_config_gyp \
@@ -746,6 +756,11 @@
 	third_party_webrtc_modules_audio_processing_gyp \
 	third_party_webrtc_modules_audioproc_debug_proto_gyp \
 	third_party_webrtc_modules_audio_device_gyp \
+	components_cdm_browser_gyp \
+	components_cdm_common_gyp \
+	components_cdm_renderer_gyp \
+	components_data_reduction_proxy_browser_gyp \
+	components_data_reduction_proxy_common_gyp \
 	components_navigation_interception_gyp \
 	components_visitedlink_browser_gyp \
 	components_visitedlink_common_gyp \
diff --git a/android_webview/libwebviewchromium.target.darwin-x86.mk b/android_webview/libwebviewchromium.target.darwin-x86.mk
index 96104e8..a2c65e1 100644
--- a/android_webview/libwebviewchromium.target.darwin-x86.mk
+++ b/android_webview/libwebviewchromium.target.darwin-x86.mk
@@ -76,6 +76,7 @@
 	$(call intermediates-dir-for,GYP,ui_gl_gl_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/gl_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,ui_gl_surface_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/surface_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_lib_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_lib_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_preprocessor_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_preprocessor_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gles2_cmd_helper_gyp,,,$(GYP_VAR_PREFIX))/gpu_gles2_cmd_helper_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gpu_config_gyp,,,$(GYP_VAR_PREFIX))/gpu_gpu_config_gyp.a \
@@ -152,6 +153,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_platform_make_platform_generated_gyp,,,$(GYP_VAR_PREFIX))/make_platform_generated.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_iccjpeg_iccjpeg_gyp,,,$(GYP_VAR_PREFIX))/third_party_iccjpeg_iccjpeg_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_harfbuzz_ng_harfbuzz_ng_gyp,,,$(GYP_VAR_PREFIX))/third_party_harfbuzz_ng_harfbuzz_ng_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_openmax_dl_dl_openmax_dl_gyp,,,$(GYP_VAR_PREFIX))/third_party_openmax_dl_dl_openmax_dl_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_web_blink_web_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_web_blink_web_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_core_webcore_gyp,,,$(GYP_VAR_PREFIX))/webcore.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_core_webcore_dom_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_core_webcore_dom_gyp.a \
@@ -226,6 +228,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_frontend_protocol_sources_gyp,,,$(GYP_VAR_PREFIX))/frontend_protocol_sources.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_audits_module_gyp,,,$(GYP_VAR_PREFIX))/build_audits_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_core_module_gyp,,,$(GYP_VAR_PREFIX))/build_core_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_concatenated_module_descriptors_gyp,,,$(GYP_VAR_PREFIX))/concatenated_module_descriptors.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_console_module_gyp,,,$(GYP_VAR_PREFIX))/build_console_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_devices_module_gyp,,,$(GYP_VAR_PREFIX))/build_devices_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_elements_module_gyp,,,$(GYP_VAR_PREFIX))/build_elements_module.stamp \
@@ -235,6 +238,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_profiler_module_gyp,,,$(GYP_VAR_PREFIX))/build_profiler_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_resources_module_gyp,,,$(GYP_VAR_PREFIX))/build_resources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_search_module_gyp,,,$(GYP_VAR_PREFIX))/build_search_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_settings_module_gyp,,,$(GYP_VAR_PREFIX))/build_settings_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_source_frame_module_gyp,,,$(GYP_VAR_PREFIX))/build_source_frame_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_sources_module_gyp,,,$(GYP_VAR_PREFIX))/build_sources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_timeline_module_gyp,,,$(GYP_VAR_PREFIX))/build_timeline_module.stamp \
@@ -248,6 +252,7 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_surface_surface_gyp,,,$(GYP_VAR_PREFIX))/ui_surface_surface_gyp.a \
 	$(call intermediates-dir-for,GYP,webkit_webkit_strings_gyp,,,$(GYP_VAR_PREFIX))/webkit_strings.stamp \
 	$(call intermediates-dir-for,GYP,third_party_angle_src_commit_id_gyp,,,$(GYP_VAR_PREFIX))/commit_id.stamp \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,printing_printing_gyp,,,$(GYP_VAR_PREFIX))/printing_printing_gyp.a \
 	$(call intermediates-dir-for,GYP,printing_printing_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/printing_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,sandbox_sandbox_gyp,,,$(GYP_VAR_PREFIX))/sandbox.stamp \
@@ -328,6 +333,11 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audioproc_debug_proto_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audioproc_debug_proto_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_processing_sse2_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_processing_sse2_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_device_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_device_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_browser_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_common_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_common_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_renderer_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_renderer_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_browser_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_common_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_common_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_navigation_interception_gyp,,,$(GYP_VAR_PREFIX))/components_navigation_interception_gyp.a \
 	$(call intermediates-dir-for,GYP,components_navigation_interception_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/navigation_interception_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_visitedlink_browser_gyp,,,$(GYP_VAR_PREFIX))/components_visitedlink_browser_gyp.a \
@@ -367,7 +377,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -461,7 +470,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -618,6 +626,7 @@
 	ui_gfx_gfx_geometry_gyp \
 	ui_gl_gl_gyp \
 	third_party_angle_src_translator_gyp \
+	third_party_angle_src_translator_lib_gyp \
 	third_party_angle_src_preprocessor_gyp \
 	gpu_gles2_cmd_helper_gyp \
 	gpu_gpu_config_gyp \
@@ -673,6 +682,7 @@
 	v8_tools_gyp_v8_snapshot_gyp \
 	third_party_iccjpeg_iccjpeg_gyp \
 	third_party_harfbuzz_ng_harfbuzz_ng_gyp \
+	third_party_openmax_dl_dl_openmax_dl_gyp \
 	third_party_WebKit_Source_web_blink_web_gyp \
 	third_party_WebKit_Source_core_webcore_dom_gyp \
 	third_party_libxml_libxml_gyp \
@@ -780,6 +790,11 @@
 	third_party_webrtc_modules_audioproc_debug_proto_gyp \
 	third_party_webrtc_modules_audio_processing_sse2_gyp \
 	third_party_webrtc_modules_audio_device_gyp \
+	components_cdm_browser_gyp \
+	components_cdm_common_gyp \
+	components_cdm_renderer_gyp \
+	components_data_reduction_proxy_browser_gyp \
+	components_data_reduction_proxy_common_gyp \
 	components_navigation_interception_gyp \
 	components_visitedlink_browser_gyp \
 	components_visitedlink_common_gyp \
diff --git a/android_webview/libwebviewchromium.target.darwin-x86_64.mk b/android_webview/libwebviewchromium.target.darwin-x86_64.mk
index 38822a5..03bfa2c 100644
--- a/android_webview/libwebviewchromium.target.darwin-x86_64.mk
+++ b/android_webview/libwebviewchromium.target.darwin-x86_64.mk
@@ -76,6 +76,7 @@
 	$(call intermediates-dir-for,GYP,ui_gl_gl_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/gl_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,ui_gl_surface_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/surface_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_lib_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_lib_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_preprocessor_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_preprocessor_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gles2_cmd_helper_gyp,,,$(GYP_VAR_PREFIX))/gpu_gles2_cmd_helper_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gpu_config_gyp,,,$(GYP_VAR_PREFIX))/gpu_gpu_config_gyp.a \
@@ -152,6 +153,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_platform_make_platform_generated_gyp,,,$(GYP_VAR_PREFIX))/make_platform_generated.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_iccjpeg_iccjpeg_gyp,,,$(GYP_VAR_PREFIX))/third_party_iccjpeg_iccjpeg_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_harfbuzz_ng_harfbuzz_ng_gyp,,,$(GYP_VAR_PREFIX))/third_party_harfbuzz_ng_harfbuzz_ng_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_openmax_dl_dl_openmax_dl_gyp,,,$(GYP_VAR_PREFIX))/third_party_openmax_dl_dl_openmax_dl_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_web_blink_web_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_web_blink_web_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_core_webcore_gyp,,,$(GYP_VAR_PREFIX))/webcore.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_core_webcore_dom_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_core_webcore_dom_gyp.a \
@@ -226,6 +228,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_frontend_protocol_sources_gyp,,,$(GYP_VAR_PREFIX))/frontend_protocol_sources.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_audits_module_gyp,,,$(GYP_VAR_PREFIX))/build_audits_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_core_module_gyp,,,$(GYP_VAR_PREFIX))/build_core_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_concatenated_module_descriptors_gyp,,,$(GYP_VAR_PREFIX))/concatenated_module_descriptors.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_console_module_gyp,,,$(GYP_VAR_PREFIX))/build_console_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_devices_module_gyp,,,$(GYP_VAR_PREFIX))/build_devices_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_elements_module_gyp,,,$(GYP_VAR_PREFIX))/build_elements_module.stamp \
@@ -235,6 +238,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_profiler_module_gyp,,,$(GYP_VAR_PREFIX))/build_profiler_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_resources_module_gyp,,,$(GYP_VAR_PREFIX))/build_resources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_search_module_gyp,,,$(GYP_VAR_PREFIX))/build_search_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_settings_module_gyp,,,$(GYP_VAR_PREFIX))/build_settings_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_source_frame_module_gyp,,,$(GYP_VAR_PREFIX))/build_source_frame_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_sources_module_gyp,,,$(GYP_VAR_PREFIX))/build_sources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_timeline_module_gyp,,,$(GYP_VAR_PREFIX))/build_timeline_module.stamp \
@@ -248,6 +252,7 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_surface_surface_gyp,,,$(GYP_VAR_PREFIX))/ui_surface_surface_gyp.a \
 	$(call intermediates-dir-for,GYP,webkit_webkit_strings_gyp,,,$(GYP_VAR_PREFIX))/webkit_strings.stamp \
 	$(call intermediates-dir-for,GYP,third_party_angle_src_commit_id_gyp,,,$(GYP_VAR_PREFIX))/commit_id.stamp \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,printing_printing_gyp,,,$(GYP_VAR_PREFIX))/printing_printing_gyp.a \
 	$(call intermediates-dir-for,GYP,printing_printing_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/printing_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,sandbox_sandbox_gyp,,,$(GYP_VAR_PREFIX))/sandbox.stamp \
@@ -328,6 +333,11 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audioproc_debug_proto_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audioproc_debug_proto_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_processing_sse2_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_processing_sse2_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_device_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_device_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_browser_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_common_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_common_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_renderer_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_renderer_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_browser_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_common_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_common_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_navigation_interception_gyp,,,$(GYP_VAR_PREFIX))/components_navigation_interception_gyp.a \
 	$(call intermediates-dir-for,GYP,components_navigation_interception_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/navigation_interception_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_visitedlink_browser_gyp,,,$(GYP_VAR_PREFIX))/components_visitedlink_browser_gyp.a \
@@ -367,7 +377,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -461,7 +470,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -618,6 +626,7 @@
 	ui_gfx_gfx_geometry_gyp \
 	ui_gl_gl_gyp \
 	third_party_angle_src_translator_gyp \
+	third_party_angle_src_translator_lib_gyp \
 	third_party_angle_src_preprocessor_gyp \
 	gpu_gles2_cmd_helper_gyp \
 	gpu_gpu_config_gyp \
@@ -673,6 +682,7 @@
 	v8_tools_gyp_v8_snapshot_gyp \
 	third_party_iccjpeg_iccjpeg_gyp \
 	third_party_harfbuzz_ng_harfbuzz_ng_gyp \
+	third_party_openmax_dl_dl_openmax_dl_gyp \
 	third_party_WebKit_Source_web_blink_web_gyp \
 	third_party_WebKit_Source_core_webcore_dom_gyp \
 	third_party_libxml_libxml_gyp \
@@ -780,6 +790,11 @@
 	third_party_webrtc_modules_audioproc_debug_proto_gyp \
 	third_party_webrtc_modules_audio_processing_sse2_gyp \
 	third_party_webrtc_modules_audio_device_gyp \
+	components_cdm_browser_gyp \
+	components_cdm_common_gyp \
+	components_cdm_renderer_gyp \
+	components_data_reduction_proxy_browser_gyp \
+	components_data_reduction_proxy_common_gyp \
 	components_navigation_interception_gyp \
 	components_visitedlink_browser_gyp \
 	components_visitedlink_common_gyp \
diff --git a/android_webview/libwebviewchromium.target.linux-arm.mk b/android_webview/libwebviewchromium.target.linux-arm.mk
index 805355e..245eade 100644
--- a/android_webview/libwebviewchromium.target.linux-arm.mk
+++ b/android_webview/libwebviewchromium.target.linux-arm.mk
@@ -76,6 +76,7 @@
 	$(call intermediates-dir-for,GYP,ui_gl_gl_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/gl_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,ui_gl_surface_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/surface_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_lib_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_lib_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_preprocessor_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_preprocessor_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gles2_cmd_helper_gyp,,,$(GYP_VAR_PREFIX))/gpu_gles2_cmd_helper_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gpu_config_gyp,,,$(GYP_VAR_PREFIX))/gpu_gpu_config_gyp.a \
@@ -147,6 +148,8 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_platform_make_platform_generated_gyp,,,$(GYP_VAR_PREFIX))/make_platform_generated.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_iccjpeg_iccjpeg_gyp,,,$(GYP_VAR_PREFIX))/third_party_iccjpeg_iccjpeg_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_harfbuzz_ng_harfbuzz_ng_gyp,,,$(GYP_VAR_PREFIX))/third_party_harfbuzz_ng_harfbuzz_ng_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_openmax_dl_dl_openmax_dl_gyp,,,$(GYP_VAR_PREFIX))/third_party_openmax_dl_dl_openmax_dl_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_openmax_dl_dl_openmax_dl_armv7_gyp,,,$(GYP_VAR_PREFIX))/third_party_openmax_dl_dl_openmax_dl_armv7_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_platform_blink_arm_neon_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_platform_blink_arm_neon_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_web_blink_web_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_web_blink_web_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_core_webcore_gyp,,,$(GYP_VAR_PREFIX))/webcore.stamp \
@@ -223,6 +226,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_frontend_protocol_sources_gyp,,,$(GYP_VAR_PREFIX))/frontend_protocol_sources.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_audits_module_gyp,,,$(GYP_VAR_PREFIX))/build_audits_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_core_module_gyp,,,$(GYP_VAR_PREFIX))/build_core_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_concatenated_module_descriptors_gyp,,,$(GYP_VAR_PREFIX))/concatenated_module_descriptors.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_console_module_gyp,,,$(GYP_VAR_PREFIX))/build_console_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_devices_module_gyp,,,$(GYP_VAR_PREFIX))/build_devices_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_elements_module_gyp,,,$(GYP_VAR_PREFIX))/build_elements_module.stamp \
@@ -232,6 +236,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_profiler_module_gyp,,,$(GYP_VAR_PREFIX))/build_profiler_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_resources_module_gyp,,,$(GYP_VAR_PREFIX))/build_resources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_search_module_gyp,,,$(GYP_VAR_PREFIX))/build_search_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_settings_module_gyp,,,$(GYP_VAR_PREFIX))/build_settings_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_source_frame_module_gyp,,,$(GYP_VAR_PREFIX))/build_source_frame_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_sources_module_gyp,,,$(GYP_VAR_PREFIX))/build_sources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_timeline_module_gyp,,,$(GYP_VAR_PREFIX))/build_timeline_module.stamp \
@@ -245,6 +250,7 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_surface_surface_gyp,,,$(GYP_VAR_PREFIX))/ui_surface_surface_gyp.a \
 	$(call intermediates-dir-for,GYP,webkit_webkit_strings_gyp,,,$(GYP_VAR_PREFIX))/webkit_strings.stamp \
 	$(call intermediates-dir-for,GYP,third_party_angle_src_commit_id_gyp,,,$(GYP_VAR_PREFIX))/commit_id.stamp \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,printing_printing_gyp,,,$(GYP_VAR_PREFIX))/printing_printing_gyp.a \
 	$(call intermediates-dir-for,GYP,printing_printing_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/printing_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,sandbox_sandbox_gyp,,,$(GYP_VAR_PREFIX))/sandbox.stamp \
@@ -328,6 +334,11 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,lib_core_neon_offsets,,,$(GYP_VAR_PREFIX))/lib_core_neon_offsets.a \
 	$(call intermediates-dir-for,GYP,third_party_webrtc_modules_audio_processing_gen_aecm_core_neon_offsets_h_gyp,,,$(GYP_VAR_PREFIX))/gen_aecm_core_neon_offsets_h.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_device_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_device_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_browser_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_common_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_common_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_renderer_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_renderer_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_browser_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_common_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_common_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_navigation_interception_gyp,,,$(GYP_VAR_PREFIX))/components_navigation_interception_gyp.a \
 	$(call intermediates-dir-for,GYP,components_navigation_interception_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/navigation_interception_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_visitedlink_browser_gyp,,,$(GYP_VAR_PREFIX))/components_visitedlink_browser_gyp.a \
@@ -365,7 +376,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -459,7 +469,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -622,6 +631,7 @@
 	ui_gfx_gfx_geometry_gyp \
 	ui_gl_gl_gyp \
 	third_party_angle_src_translator_gyp \
+	third_party_angle_src_translator_lib_gyp \
 	third_party_angle_src_preprocessor_gyp \
 	gpu_gles2_cmd_helper_gyp \
 	gpu_gpu_config_gyp \
@@ -673,6 +683,8 @@
 	v8_tools_gyp_v8_snapshot_gyp \
 	third_party_iccjpeg_iccjpeg_gyp \
 	third_party_harfbuzz_ng_harfbuzz_ng_gyp \
+	third_party_openmax_dl_dl_openmax_dl_gyp \
+	third_party_openmax_dl_dl_openmax_dl_armv7_gyp \
 	third_party_WebKit_Source_platform_blink_arm_neon_gyp \
 	third_party_WebKit_Source_web_blink_web_gyp \
 	third_party_WebKit_Source_core_webcore_dom_gyp \
@@ -782,6 +794,11 @@
 	third_party_webrtc_modules_audio_processing_neon_gyp \
 	lib_core_neon_offsets \
 	third_party_webrtc_modules_audio_device_gyp \
+	components_cdm_browser_gyp \
+	components_cdm_common_gyp \
+	components_cdm_renderer_gyp \
+	components_data_reduction_proxy_browser_gyp \
+	components_data_reduction_proxy_common_gyp \
 	components_navigation_interception_gyp \
 	components_visitedlink_browser_gyp \
 	components_visitedlink_common_gyp \
diff --git a/android_webview/libwebviewchromium.target.linux-arm64.mk b/android_webview/libwebviewchromium.target.linux-arm64.mk
index b5c7712..882ab6d 100644
--- a/android_webview/libwebviewchromium.target.linux-arm64.mk
+++ b/android_webview/libwebviewchromium.target.linux-arm64.mk
@@ -75,6 +75,7 @@
 	$(call intermediates-dir-for,GYP,ui_gl_gl_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/gl_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,ui_gl_surface_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/surface_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_lib_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_lib_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_preprocessor_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_preprocessor_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gles2_cmd_helper_gyp,,,$(GYP_VAR_PREFIX))/gpu_gles2_cmd_helper_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gpu_config_gyp,,,$(GYP_VAR_PREFIX))/gpu_gpu_config_gyp.a \
@@ -220,6 +221,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_frontend_protocol_sources_gyp,,,$(GYP_VAR_PREFIX))/frontend_protocol_sources.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_audits_module_gyp,,,$(GYP_VAR_PREFIX))/build_audits_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_core_module_gyp,,,$(GYP_VAR_PREFIX))/build_core_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_concatenated_module_descriptors_gyp,,,$(GYP_VAR_PREFIX))/concatenated_module_descriptors.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_console_module_gyp,,,$(GYP_VAR_PREFIX))/build_console_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_devices_module_gyp,,,$(GYP_VAR_PREFIX))/build_devices_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_elements_module_gyp,,,$(GYP_VAR_PREFIX))/build_elements_module.stamp \
@@ -229,6 +231,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_profiler_module_gyp,,,$(GYP_VAR_PREFIX))/build_profiler_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_resources_module_gyp,,,$(GYP_VAR_PREFIX))/build_resources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_search_module_gyp,,,$(GYP_VAR_PREFIX))/build_search_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_settings_module_gyp,,,$(GYP_VAR_PREFIX))/build_settings_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_source_frame_module_gyp,,,$(GYP_VAR_PREFIX))/build_source_frame_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_sources_module_gyp,,,$(GYP_VAR_PREFIX))/build_sources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_timeline_module_gyp,,,$(GYP_VAR_PREFIX))/build_timeline_module.stamp \
@@ -242,6 +245,7 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_surface_surface_gyp,,,$(GYP_VAR_PREFIX))/ui_surface_surface_gyp.a \
 	$(call intermediates-dir-for,GYP,webkit_webkit_strings_gyp,,,$(GYP_VAR_PREFIX))/webkit_strings.stamp \
 	$(call intermediates-dir-for,GYP,third_party_angle_src_commit_id_gyp,,,$(GYP_VAR_PREFIX))/commit_id.stamp \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,printing_printing_gyp,,,$(GYP_VAR_PREFIX))/printing_printing_gyp.a \
 	$(call intermediates-dir-for,GYP,printing_printing_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/printing_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,sandbox_sandbox_gyp,,,$(GYP_VAR_PREFIX))/sandbox.stamp \
@@ -313,6 +317,11 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_processing_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_processing_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audioproc_debug_proto_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audioproc_debug_proto_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_device_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_device_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_browser_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_common_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_common_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_renderer_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_renderer_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_browser_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_common_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_common_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_navigation_interception_gyp,,,$(GYP_VAR_PREFIX))/components_navigation_interception_gyp.a \
 	$(call intermediates-dir-for,GYP,components_navigation_interception_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/navigation_interception_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_visitedlink_browser_gyp,,,$(GYP_VAR_PREFIX))/components_visitedlink_browser_gyp.a \
@@ -588,6 +597,7 @@
 	ui_gfx_gfx_geometry_gyp \
 	ui_gl_gl_gyp \
 	third_party_angle_src_translator_gyp \
+	third_party_angle_src_translator_lib_gyp \
 	third_party_angle_src_preprocessor_gyp \
 	gpu_gles2_cmd_helper_gyp \
 	gpu_gpu_config_gyp \
@@ -737,6 +747,11 @@
 	third_party_webrtc_modules_audio_processing_gyp \
 	third_party_webrtc_modules_audioproc_debug_proto_gyp \
 	third_party_webrtc_modules_audio_device_gyp \
+	components_cdm_browser_gyp \
+	components_cdm_common_gyp \
+	components_cdm_renderer_gyp \
+	components_data_reduction_proxy_browser_gyp \
+	components_data_reduction_proxy_common_gyp \
 	components_navigation_interception_gyp \
 	components_visitedlink_browser_gyp \
 	components_visitedlink_common_gyp \
diff --git a/android_webview/libwebviewchromium.target.linux-mips.mk b/android_webview/libwebviewchromium.target.linux-mips.mk
index 2bc87bb..ee2fc6dc 100644
--- a/android_webview/libwebviewchromium.target.linux-mips.mk
+++ b/android_webview/libwebviewchromium.target.linux-mips.mk
@@ -75,6 +75,7 @@
 	$(call intermediates-dir-for,GYP,ui_gl_gl_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/gl_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,ui_gl_surface_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/surface_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_lib_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_lib_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_preprocessor_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_preprocessor_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gles2_cmd_helper_gyp,,,$(GYP_VAR_PREFIX))/gpu_gles2_cmd_helper_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gpu_config_gyp,,,$(GYP_VAR_PREFIX))/gpu_gpu_config_gyp.a \
@@ -220,6 +221,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_frontend_protocol_sources_gyp,,,$(GYP_VAR_PREFIX))/frontend_protocol_sources.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_audits_module_gyp,,,$(GYP_VAR_PREFIX))/build_audits_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_core_module_gyp,,,$(GYP_VAR_PREFIX))/build_core_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_concatenated_module_descriptors_gyp,,,$(GYP_VAR_PREFIX))/concatenated_module_descriptors.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_console_module_gyp,,,$(GYP_VAR_PREFIX))/build_console_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_devices_module_gyp,,,$(GYP_VAR_PREFIX))/build_devices_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_elements_module_gyp,,,$(GYP_VAR_PREFIX))/build_elements_module.stamp \
@@ -229,6 +231,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_profiler_module_gyp,,,$(GYP_VAR_PREFIX))/build_profiler_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_resources_module_gyp,,,$(GYP_VAR_PREFIX))/build_resources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_search_module_gyp,,,$(GYP_VAR_PREFIX))/build_search_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_settings_module_gyp,,,$(GYP_VAR_PREFIX))/build_settings_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_source_frame_module_gyp,,,$(GYP_VAR_PREFIX))/build_source_frame_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_sources_module_gyp,,,$(GYP_VAR_PREFIX))/build_sources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_timeline_module_gyp,,,$(GYP_VAR_PREFIX))/build_timeline_module.stamp \
@@ -242,6 +245,7 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_surface_surface_gyp,,,$(GYP_VAR_PREFIX))/ui_surface_surface_gyp.a \
 	$(call intermediates-dir-for,GYP,webkit_webkit_strings_gyp,,,$(GYP_VAR_PREFIX))/webkit_strings.stamp \
 	$(call intermediates-dir-for,GYP,third_party_angle_src_commit_id_gyp,,,$(GYP_VAR_PREFIX))/commit_id.stamp \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,printing_printing_gyp,,,$(GYP_VAR_PREFIX))/printing_printing_gyp.a \
 	$(call intermediates-dir-for,GYP,printing_printing_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/printing_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,sandbox_sandbox_gyp,,,$(GYP_VAR_PREFIX))/sandbox.stamp \
@@ -311,6 +315,11 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_processing_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_processing_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audioproc_debug_proto_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audioproc_debug_proto_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_device_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_device_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_browser_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_common_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_common_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_renderer_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_renderer_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_browser_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_common_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_common_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_navigation_interception_gyp,,,$(GYP_VAR_PREFIX))/components_navigation_interception_gyp.a \
 	$(call intermediates-dir-for,GYP,components_navigation_interception_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/navigation_interception_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_visitedlink_browser_gyp,,,$(GYP_VAR_PREFIX))/components_visitedlink_browser_gyp.a \
@@ -598,6 +607,7 @@
 	ui_gfx_gfx_geometry_gyp \
 	ui_gl_gl_gyp \
 	third_party_angle_src_translator_gyp \
+	third_party_angle_src_translator_lib_gyp \
 	third_party_angle_src_preprocessor_gyp \
 	gpu_gles2_cmd_helper_gyp \
 	gpu_gpu_config_gyp \
@@ -746,6 +756,11 @@
 	third_party_webrtc_modules_audio_processing_gyp \
 	third_party_webrtc_modules_audioproc_debug_proto_gyp \
 	third_party_webrtc_modules_audio_device_gyp \
+	components_cdm_browser_gyp \
+	components_cdm_common_gyp \
+	components_cdm_renderer_gyp \
+	components_data_reduction_proxy_browser_gyp \
+	components_data_reduction_proxy_common_gyp \
 	components_navigation_interception_gyp \
 	components_visitedlink_browser_gyp \
 	components_visitedlink_common_gyp \
diff --git a/android_webview/libwebviewchromium.target.linux-x86.mk b/android_webview/libwebviewchromium.target.linux-x86.mk
index 96104e8..a2c65e1 100644
--- a/android_webview/libwebviewchromium.target.linux-x86.mk
+++ b/android_webview/libwebviewchromium.target.linux-x86.mk
@@ -76,6 +76,7 @@
 	$(call intermediates-dir-for,GYP,ui_gl_gl_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/gl_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,ui_gl_surface_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/surface_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_lib_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_lib_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_preprocessor_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_preprocessor_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gles2_cmd_helper_gyp,,,$(GYP_VAR_PREFIX))/gpu_gles2_cmd_helper_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gpu_config_gyp,,,$(GYP_VAR_PREFIX))/gpu_gpu_config_gyp.a \
@@ -152,6 +153,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_platform_make_platform_generated_gyp,,,$(GYP_VAR_PREFIX))/make_platform_generated.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_iccjpeg_iccjpeg_gyp,,,$(GYP_VAR_PREFIX))/third_party_iccjpeg_iccjpeg_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_harfbuzz_ng_harfbuzz_ng_gyp,,,$(GYP_VAR_PREFIX))/third_party_harfbuzz_ng_harfbuzz_ng_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_openmax_dl_dl_openmax_dl_gyp,,,$(GYP_VAR_PREFIX))/third_party_openmax_dl_dl_openmax_dl_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_web_blink_web_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_web_blink_web_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_core_webcore_gyp,,,$(GYP_VAR_PREFIX))/webcore.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_core_webcore_dom_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_core_webcore_dom_gyp.a \
@@ -226,6 +228,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_frontend_protocol_sources_gyp,,,$(GYP_VAR_PREFIX))/frontend_protocol_sources.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_audits_module_gyp,,,$(GYP_VAR_PREFIX))/build_audits_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_core_module_gyp,,,$(GYP_VAR_PREFIX))/build_core_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_concatenated_module_descriptors_gyp,,,$(GYP_VAR_PREFIX))/concatenated_module_descriptors.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_console_module_gyp,,,$(GYP_VAR_PREFIX))/build_console_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_devices_module_gyp,,,$(GYP_VAR_PREFIX))/build_devices_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_elements_module_gyp,,,$(GYP_VAR_PREFIX))/build_elements_module.stamp \
@@ -235,6 +238,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_profiler_module_gyp,,,$(GYP_VAR_PREFIX))/build_profiler_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_resources_module_gyp,,,$(GYP_VAR_PREFIX))/build_resources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_search_module_gyp,,,$(GYP_VAR_PREFIX))/build_search_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_settings_module_gyp,,,$(GYP_VAR_PREFIX))/build_settings_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_source_frame_module_gyp,,,$(GYP_VAR_PREFIX))/build_source_frame_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_sources_module_gyp,,,$(GYP_VAR_PREFIX))/build_sources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_timeline_module_gyp,,,$(GYP_VAR_PREFIX))/build_timeline_module.stamp \
@@ -248,6 +252,7 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_surface_surface_gyp,,,$(GYP_VAR_PREFIX))/ui_surface_surface_gyp.a \
 	$(call intermediates-dir-for,GYP,webkit_webkit_strings_gyp,,,$(GYP_VAR_PREFIX))/webkit_strings.stamp \
 	$(call intermediates-dir-for,GYP,third_party_angle_src_commit_id_gyp,,,$(GYP_VAR_PREFIX))/commit_id.stamp \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,printing_printing_gyp,,,$(GYP_VAR_PREFIX))/printing_printing_gyp.a \
 	$(call intermediates-dir-for,GYP,printing_printing_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/printing_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,sandbox_sandbox_gyp,,,$(GYP_VAR_PREFIX))/sandbox.stamp \
@@ -328,6 +333,11 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audioproc_debug_proto_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audioproc_debug_proto_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_processing_sse2_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_processing_sse2_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_device_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_device_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_browser_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_common_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_common_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_renderer_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_renderer_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_browser_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_common_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_common_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_navigation_interception_gyp,,,$(GYP_VAR_PREFIX))/components_navigation_interception_gyp.a \
 	$(call intermediates-dir-for,GYP,components_navigation_interception_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/navigation_interception_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_visitedlink_browser_gyp,,,$(GYP_VAR_PREFIX))/components_visitedlink_browser_gyp.a \
@@ -367,7 +377,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -461,7 +470,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -618,6 +626,7 @@
 	ui_gfx_gfx_geometry_gyp \
 	ui_gl_gl_gyp \
 	third_party_angle_src_translator_gyp \
+	third_party_angle_src_translator_lib_gyp \
 	third_party_angle_src_preprocessor_gyp \
 	gpu_gles2_cmd_helper_gyp \
 	gpu_gpu_config_gyp \
@@ -673,6 +682,7 @@
 	v8_tools_gyp_v8_snapshot_gyp \
 	third_party_iccjpeg_iccjpeg_gyp \
 	third_party_harfbuzz_ng_harfbuzz_ng_gyp \
+	third_party_openmax_dl_dl_openmax_dl_gyp \
 	third_party_WebKit_Source_web_blink_web_gyp \
 	third_party_WebKit_Source_core_webcore_dom_gyp \
 	third_party_libxml_libxml_gyp \
@@ -780,6 +790,11 @@
 	third_party_webrtc_modules_audioproc_debug_proto_gyp \
 	third_party_webrtc_modules_audio_processing_sse2_gyp \
 	third_party_webrtc_modules_audio_device_gyp \
+	components_cdm_browser_gyp \
+	components_cdm_common_gyp \
+	components_cdm_renderer_gyp \
+	components_data_reduction_proxy_browser_gyp \
+	components_data_reduction_proxy_common_gyp \
 	components_navigation_interception_gyp \
 	components_visitedlink_browser_gyp \
 	components_visitedlink_common_gyp \
diff --git a/android_webview/libwebviewchromium.target.linux-x86_64.mk b/android_webview/libwebviewchromium.target.linux-x86_64.mk
index 38822a5..03bfa2c 100644
--- a/android_webview/libwebviewchromium.target.linux-x86_64.mk
+++ b/android_webview/libwebviewchromium.target.linux-x86_64.mk
@@ -76,6 +76,7 @@
 	$(call intermediates-dir-for,GYP,ui_gl_gl_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/gl_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,ui_gl_surface_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/surface_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_translator_lib_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_translator_lib_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_angle_src_preprocessor_gyp,,,$(GYP_VAR_PREFIX))/third_party_angle_src_preprocessor_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gles2_cmd_helper_gyp,,,$(GYP_VAR_PREFIX))/gpu_gles2_cmd_helper_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,gpu_gpu_config_gyp,,,$(GYP_VAR_PREFIX))/gpu_gpu_config_gyp.a \
@@ -152,6 +153,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_platform_make_platform_generated_gyp,,,$(GYP_VAR_PREFIX))/make_platform_generated.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_iccjpeg_iccjpeg_gyp,,,$(GYP_VAR_PREFIX))/third_party_iccjpeg_iccjpeg_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_harfbuzz_ng_harfbuzz_ng_gyp,,,$(GYP_VAR_PREFIX))/third_party_harfbuzz_ng_harfbuzz_ng_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_openmax_dl_dl_openmax_dl_gyp,,,$(GYP_VAR_PREFIX))/third_party_openmax_dl_dl_openmax_dl_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_web_blink_web_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_web_blink_web_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_core_webcore_gyp,,,$(GYP_VAR_PREFIX))/webcore.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_WebKit_Source_core_webcore_dom_gyp,,,$(GYP_VAR_PREFIX))/third_party_WebKit_Source_core_webcore_dom_gyp.a \
@@ -226,6 +228,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_frontend_protocol_sources_gyp,,,$(GYP_VAR_PREFIX))/frontend_protocol_sources.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_audits_module_gyp,,,$(GYP_VAR_PREFIX))/build_audits_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_core_module_gyp,,,$(GYP_VAR_PREFIX))/build_core_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_concatenated_module_descriptors_gyp,,,$(GYP_VAR_PREFIX))/concatenated_module_descriptors.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_console_module_gyp,,,$(GYP_VAR_PREFIX))/build_console_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_devices_module_gyp,,,$(GYP_VAR_PREFIX))/build_devices_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_elements_module_gyp,,,$(GYP_VAR_PREFIX))/build_elements_module.stamp \
@@ -235,6 +238,7 @@
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_profiler_module_gyp,,,$(GYP_VAR_PREFIX))/build_profiler_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_resources_module_gyp,,,$(GYP_VAR_PREFIX))/build_resources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_search_module_gyp,,,$(GYP_VAR_PREFIX))/build_search_module.stamp \
+	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_settings_module_gyp,,,$(GYP_VAR_PREFIX))/build_settings_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_source_frame_module_gyp,,,$(GYP_VAR_PREFIX))/build_source_frame_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_sources_module_gyp,,,$(GYP_VAR_PREFIX))/build_sources_module.stamp \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_Source_devtools_build_timeline_module_gyp,,,$(GYP_VAR_PREFIX))/build_timeline_module.stamp \
@@ -248,6 +252,7 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_surface_surface_gyp,,,$(GYP_VAR_PREFIX))/ui_surface_surface_gyp.a \
 	$(call intermediates-dir-for,GYP,webkit_webkit_strings_gyp,,,$(GYP_VAR_PREFIX))/webkit_strings.stamp \
 	$(call intermediates-dir-for,GYP,third_party_angle_src_commit_id_gyp,,,$(GYP_VAR_PREFIX))/commit_id.stamp \
+	$(call intermediates-dir-for,GYP,third_party_angle_src_copy_scripts_gyp,,,$(GYP_VAR_PREFIX))/copy_scripts.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,printing_printing_gyp,,,$(GYP_VAR_PREFIX))/printing_printing_gyp.a \
 	$(call intermediates-dir-for,GYP,printing_printing_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/printing_jni_headers.stamp \
 	$(call intermediates-dir-for,GYP,sandbox_sandbox_gyp,,,$(GYP_VAR_PREFIX))/sandbox.stamp \
@@ -328,6 +333,11 @@
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audioproc_debug_proto_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audioproc_debug_proto_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_processing_sse2_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_processing_sse2_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,third_party_webrtc_modules_audio_device_gyp,,,$(GYP_VAR_PREFIX))/third_party_webrtc_modules_audio_device_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_browser_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_common_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_common_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_cdm_renderer_gyp,,,$(GYP_VAR_PREFIX))/components_cdm_renderer_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_browser_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_browser_gyp.a \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,components_data_reduction_proxy_common_gyp,,,$(GYP_VAR_PREFIX))/components_data_reduction_proxy_common_gyp.a \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_navigation_interception_gyp,,,$(GYP_VAR_PREFIX))/components_navigation_interception_gyp.a \
 	$(call intermediates-dir-for,GYP,components_navigation_interception_jni_headers_gyp,,,$(GYP_VAR_PREFIX))/navigation_interception_jni_headers.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,components_visitedlink_browser_gyp,,,$(GYP_VAR_PREFIX))/components_visitedlink_browser_gyp.a \
@@ -367,7 +377,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -461,7 +470,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -618,6 +626,7 @@
 	ui_gfx_gfx_geometry_gyp \
 	ui_gl_gl_gyp \
 	third_party_angle_src_translator_gyp \
+	third_party_angle_src_translator_lib_gyp \
 	third_party_angle_src_preprocessor_gyp \
 	gpu_gles2_cmd_helper_gyp \
 	gpu_gpu_config_gyp \
@@ -673,6 +682,7 @@
 	v8_tools_gyp_v8_snapshot_gyp \
 	third_party_iccjpeg_iccjpeg_gyp \
 	third_party_harfbuzz_ng_harfbuzz_ng_gyp \
+	third_party_openmax_dl_dl_openmax_dl_gyp \
 	third_party_WebKit_Source_web_blink_web_gyp \
 	third_party_WebKit_Source_core_webcore_dom_gyp \
 	third_party_libxml_libxml_gyp \
@@ -780,6 +790,11 @@
 	third_party_webrtc_modules_audioproc_debug_proto_gyp \
 	third_party_webrtc_modules_audio_processing_sse2_gyp \
 	third_party_webrtc_modules_audio_device_gyp \
+	components_cdm_browser_gyp \
+	components_cdm_common_gyp \
+	components_cdm_renderer_gyp \
+	components_data_reduction_proxy_browser_gyp \
+	components_data_reduction_proxy_common_gyp \
 	components_navigation_interception_gyp \
 	components_visitedlink_browser_gyp \
 	components_visitedlink_common_gyp \
diff --git a/android_webview/native/DEPS b/android_webview/native/DEPS
index d221dcd..ecc29cb 100644
--- a/android_webview/native/DEPS
+++ b/android_webview/native/DEPS
@@ -8,6 +8,7 @@
   "+components/autofill/content/browser",
   "+components/autofill/core/browser",
   "+components/autofill/core/common",
+  "+components/data_reduction_proxy/browser",
   "+components/navigation_interception",
   "+components/user_prefs",
   "+components/web_contents_delegate_android",
diff --git a/android_webview/native/android_webview_jni_registrar.cc b/android_webview/native/android_webview_jni_registrar.cc
index 24241d7..d219810 100644
--- a/android_webview/native/android_webview_jni_registrar.cc
+++ b/android_webview/native/android_webview_jni_registrar.cc
@@ -9,6 +9,7 @@
 #include "android_webview/native/aw_contents.h"
 #include "android_webview/native/aw_contents_client_bridge.h"
 #include "android_webview/native/aw_contents_io_thread_client_impl.h"
+#include "android_webview/native/aw_contents_statics.h"
 #include "android_webview/native/aw_dev_tools_server.h"
 #include "android_webview/native/aw_form_database.h"
 #include "android_webview/native/aw_http_auth_handler.h"
@@ -23,6 +24,7 @@
 #include "android_webview/native/input_stream_impl.h"
 #include "android_webview/native/intercepted_request_data_impl.h"
 #include "android_webview/native/java_browser_view_renderer_helper.h"
+#include "android_webview/native/permission/aw_permission_request.h"
 #include "base/android/jni_android.h"
 #include "base/android/jni_registrar.h"
 #include "base/debug/trace_event.h"
@@ -36,12 +38,14 @@
   { "AwContents", RegisterAwContents },
   { "AwContentsClientBridge", RegisterAwContentsClientBridge },
   { "AwContentsIoThreadClientImpl", RegisterAwContentsIoThreadClientImpl },
+  { "AwContentsStatics", RegisterAwContentsStatics },
   { "AwDevToolsServer", RegisterAwDevToolsServer },
   { "AwFormDatabase", RegisterAwFormDatabase },
   { "AwPicture", RegisterAwPicture },
   { "AwSettings", RegisterAwSettings },
   { "AwHttpAuthHandler", RegisterAwHttpAuthHandler },
   { "AwPdfExporter", RegisterAwPdfExporter },
+  { "AwPermissionRequest", RegisterAwPermissionRequest },
   { "AwQuotaManagerBridge", RegisterAwQuotaManagerBridge },
   { "AwResource", AwResource::RegisterAwResource },
   { "AwWebContentsDelegate", RegisterAwWebContentsDelegate },
diff --git a/android_webview/native/android_webview_native_jni.target.darwin-arm.mk b/android_webview/native/android_webview_native_jni.target.darwin-arm.mk
index 3653941..0d44811 100644
--- a/android_webview/native/android_webview_native_jni.target.darwin-arm.mk
+++ b/android_webview/native/android_webview_native_jni.target.darwin-arm.mk
@@ -18,8 +18,9 @@
 
 
 ### Generated for rule "android_webview_native_webview_native_gyp_android_webview_native_jni_target_generate_jni_headers":
-# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwContentsStatics.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java', '../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -59,7 +64,17 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsStatics.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -163,6 +190,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 
 GYP_GENERATED_OUTPUTS := \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h \
@@ -170,6 +206,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -182,7 +219,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 # Make sure our deps and generated files are built first.
 LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
@@ -193,6 +231,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -205,7 +244,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
@@ -226,7 +266,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -310,7 +349,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/android_webview/native/android_webview_native_jni.target.darwin-arm64.mk b/android_webview/native/android_webview_native_jni.target.darwin-arm64.mk
index 6a3d2e8..202212b 100644
--- a/android_webview/native/android_webview_native_jni.target.darwin-arm64.mk
+++ b/android_webview/native/android_webview_native_jni.target.darwin-arm64.mk
@@ -18,8 +18,9 @@
 
 
 ### Generated for rule "android_webview_native_webview_native_gyp_android_webview_native_jni_target_generate_jni_headers":
-# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwContentsStatics.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java', '../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -59,7 +64,17 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsStatics.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -163,6 +190,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 
 GYP_GENERATED_OUTPUTS := \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h \
@@ -170,6 +206,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -182,7 +219,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 # Make sure our deps and generated files are built first.
 LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
@@ -193,6 +231,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -205,7 +244,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
diff --git a/android_webview/native/android_webview_native_jni.target.darwin-mips.mk b/android_webview/native/android_webview_native_jni.target.darwin-mips.mk
index e194796..6e84695 100644
--- a/android_webview/native/android_webview_native_jni.target.darwin-mips.mk
+++ b/android_webview/native/android_webview_native_jni.target.darwin-mips.mk
@@ -18,8 +18,9 @@
 
 
 ### Generated for rule "android_webview_native_webview_native_gyp_android_webview_native_jni_target_generate_jni_headers":
-# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwContentsStatics.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java', '../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -59,7 +64,17 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsStatics.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -163,6 +190,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 
 GYP_GENERATED_OUTPUTS := \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h \
@@ -170,6 +206,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -182,7 +219,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 # Make sure our deps and generated files are built first.
 LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
@@ -193,6 +231,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -205,7 +244,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
diff --git a/android_webview/native/android_webview_native_jni.target.darwin-x86.mk b/android_webview/native/android_webview_native_jni.target.darwin-x86.mk
index 9a30c20..8288723 100644
--- a/android_webview/native/android_webview_native_jni.target.darwin-x86.mk
+++ b/android_webview/native/android_webview_native_jni.target.darwin-x86.mk
@@ -18,8 +18,9 @@
 
 
 ### Generated for rule "android_webview_native_webview_native_gyp_android_webview_native_jni_target_generate_jni_headers":
-# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwContentsStatics.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java', '../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -59,7 +64,17 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsStatics.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -163,6 +190,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 
 GYP_GENERATED_OUTPUTS := \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h \
@@ -170,6 +206,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -182,7 +219,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 # Make sure our deps and generated files are built first.
 LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
@@ -193,6 +231,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -205,7 +244,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
@@ -228,7 +268,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -312,7 +351,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/android_webview_native_jni.target.darwin-x86_64.mk b/android_webview/native/android_webview_native_jni.target.darwin-x86_64.mk
index 10de432..63f2521 100644
--- a/android_webview/native/android_webview_native_jni.target.darwin-x86_64.mk
+++ b/android_webview/native/android_webview_native_jni.target.darwin-x86_64.mk
@@ -18,8 +18,9 @@
 
 
 ### Generated for rule "android_webview_native_webview_native_gyp_android_webview_native_jni_target_generate_jni_headers":
-# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwContentsStatics.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java', '../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -59,7 +64,17 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsStatics.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -163,6 +190,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 
 GYP_GENERATED_OUTPUTS := \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h \
@@ -170,6 +206,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -182,7 +219,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 # Make sure our deps and generated files are built first.
 LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
@@ -193,6 +231,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -205,7 +244,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
@@ -228,7 +268,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -312,7 +351,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/android_webview_native_jni.target.linux-arm.mk b/android_webview/native/android_webview_native_jni.target.linux-arm.mk
index 3653941..0d44811 100644
--- a/android_webview/native/android_webview_native_jni.target.linux-arm.mk
+++ b/android_webview/native/android_webview_native_jni.target.linux-arm.mk
@@ -18,8 +18,9 @@
 
 
 ### Generated for rule "android_webview_native_webview_native_gyp_android_webview_native_jni_target_generate_jni_headers":
-# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwContentsStatics.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java', '../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -59,7 +64,17 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsStatics.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -163,6 +190,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 
 GYP_GENERATED_OUTPUTS := \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h \
@@ -170,6 +206,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -182,7 +219,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 # Make sure our deps and generated files are built first.
 LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
@@ -193,6 +231,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -205,7 +244,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
@@ -226,7 +266,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -310,7 +349,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/android_webview/native/android_webview_native_jni.target.linux-arm64.mk b/android_webview/native/android_webview_native_jni.target.linux-arm64.mk
index 6a3d2e8..202212b 100644
--- a/android_webview/native/android_webview_native_jni.target.linux-arm64.mk
+++ b/android_webview/native/android_webview_native_jni.target.linux-arm64.mk
@@ -18,8 +18,9 @@
 
 
 ### Generated for rule "android_webview_native_webview_native_gyp_android_webview_native_jni_target_generate_jni_headers":
-# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwContentsStatics.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java', '../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -59,7 +64,17 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsStatics.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -163,6 +190,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 
 GYP_GENERATED_OUTPUTS := \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h \
@@ -170,6 +206,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -182,7 +219,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 # Make sure our deps and generated files are built first.
 LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
@@ -193,6 +231,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -205,7 +244,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
diff --git a/android_webview/native/android_webview_native_jni.target.linux-mips.mk b/android_webview/native/android_webview_native_jni.target.linux-mips.mk
index e194796..6e84695 100644
--- a/android_webview/native/android_webview_native_jni.target.linux-mips.mk
+++ b/android_webview/native/android_webview_native_jni.target.linux-mips.mk
@@ -18,8 +18,9 @@
 
 
 ### Generated for rule "android_webview_native_webview_native_gyp_android_webview_native_jni_target_generate_jni_headers":
-# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwContentsStatics.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java', '../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -59,7 +64,17 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsStatics.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -163,6 +190,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 
 GYP_GENERATED_OUTPUTS := \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h \
@@ -170,6 +206,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -182,7 +219,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 # Make sure our deps and generated files are built first.
 LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
@@ -193,6 +231,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -205,7 +244,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
diff --git a/android_webview/native/android_webview_native_jni.target.linux-x86.mk b/android_webview/native/android_webview_native_jni.target.linux-x86.mk
index 9a30c20..8288723 100644
--- a/android_webview/native/android_webview_native_jni.target.linux-x86.mk
+++ b/android_webview/native/android_webview_native_jni.target.linux-x86.mk
@@ -18,8 +18,9 @@
 
 
 ### Generated for rule "android_webview_native_webview_native_gyp_android_webview_native_jni_target_generate_jni_headers":
-# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwContentsStatics.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java', '../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -59,7 +64,17 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsStatics.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -163,6 +190,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 
 GYP_GENERATED_OUTPUTS := \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h \
@@ -170,6 +206,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -182,7 +219,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 # Make sure our deps and generated files are built first.
 LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
@@ -193,6 +231,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -205,7 +244,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
@@ -228,7 +268,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -312,7 +351,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/android_webview_native_jni.target.linux-x86_64.mk b/android_webview/native/android_webview_native_jni.target.linux-x86_64.mk
index 10de432..63f2521 100644
--- a/android_webview/native/android_webview_native_jni.target.linux-x86_64.mk
+++ b/android_webview/native/android_webview_native_jni.target.linux-x86_64.mk
@@ -18,8 +18,9 @@
 
 
 ### Generated for rule "android_webview_native_webview_native_gyp_android_webview_native_jni_target_generate_jni_headers":
-# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/android_webview/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../java/src/org/chromium/android_webview/AndroidProtocolHandler.java', '../java/src/org/chromium/android_webview/AwAutofillManagerDelegate.java', '../java/src/org/chromium/android_webview/AwContents.java', '../java/src/org/chromium/android_webview/AwContentsClientBridge.java', '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java', '../java/src/org/chromium/android_webview/AwContentsStatics.java', '../java/src/org/chromium/android_webview/AwCookieManager.java', '../java/src/org/chromium/android_webview/AwDevToolsServer.java', '../java/src/org/chromium/android_webview/AwFormDatabase.java', '../java/src/org/chromium/android_webview/AwHttpAuthHandler.java', '../java/src/org/chromium/android_webview/AwPdfExporter.java', '../java/src/org/chromium/android_webview/AwPicture.java', '../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java', '../java/src/org/chromium/android_webview/AwResource.java', '../java/src/org/chromium/android_webview/AwSettings.java', '../java/src/org/chromium/android_webview/AwWebContentsDelegate.java', '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java', '../java/src/org/chromium/android_webview/InterceptedRequestData.java', '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java', '../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/android_webview/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwAutofillManagerDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -59,7 +64,17 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/AwContentsStatics.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwHttpAuthHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPdfExporter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwPicture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwQuotaManagerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwResource_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -163,6 +190,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
 
 
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h: $(LOCAL_PATH)/android_webview/java/src/org/chromium/android_webview/permission/AwPermissionRequest.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/android_webview/jni; cd $(gyp_local_path)/android_webview/native; ../../base/android/jni_generator/jni_generator.py --input_file ../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java --output_dir "$(gyp_shared_intermediate_dir)/android_webview/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../../android_webview/build/jarjar-rules.txt --ptr_type long
+
+
 
 GYP_GENERATED_OUTPUTS := \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AndroidProtocolHandler_jni.h \
@@ -170,6 +206,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -182,7 +219,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 # Make sure our deps and generated files are built first.
 LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
@@ -193,6 +231,7 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContents_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsClientBridge_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsIoThreadClient_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwContentsStatics_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwCookieManager_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwDevToolsServer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwFormDatabase_jni.h \
@@ -205,7 +244,8 @@
 	$(gyp_shared_intermediate_dir)/android_webview/jni/AwWebContentsDelegate_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/ExternalVideoSurfaceContainer_jni.h \
 	$(gyp_shared_intermediate_dir)/android_webview/jni/InterceptedRequestData_jni.h \
-	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h
+	$(gyp_shared_intermediate_dir)/android_webview/jni/JavaBrowserViewRendererHelper_jni.h \
+	$(gyp_shared_intermediate_dir)/android_webview/jni/AwPermissionRequest_jni.h
 
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
@@ -228,7 +268,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -312,7 +351,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/aw_autofill_manager_delegate.cc b/android_webview/native/aw_autofill_manager_delegate.cc
index 070e25e..93e04be 100644
--- a/android_webview/native/aw_autofill_manager_delegate.cc
+++ b/android_webview/native/aw_autofill_manager_delegate.cc
@@ -21,7 +21,6 @@
 #include "components/autofill/core/common/autofill_pref_names.h"
 #include "components/user_prefs/user_prefs.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "jni/AwAutofillManagerDelegate_jni.h"
 
 using base::android::AttachCurrentThread;
@@ -95,8 +94,7 @@
   delegate_ = delegate;
 
   // Convert element_bounds to be in screen space.
-  gfx::Rect client_area;
-  web_contents_->GetView()->GetContainerBounds(&client_area);
+  gfx::Rect client_area = web_contents_->GetContainerBounds();
   gfx::RectF element_bounds_in_screen_space =
       element_bounds + client_area.OffsetFromOrigin();
 
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index ee0e87b..6ca3ac5 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -24,6 +24,8 @@
 #include "android_webview/native/aw_picture.h"
 #include "android_webview/native/aw_web_contents_delegate.h"
 #include "android_webview/native/java_browser_view_renderer_helper.h"
+#include "android_webview/native/permission/aw_permission_request.h"
+#include "android_webview/native/permission/permission_request_handler.h"
 #include "android_webview/native/state_serializer.h"
 #include "android_webview/public/browser/draw_gl.h"
 #include "base/android/jni_android.h"
@@ -41,6 +43,7 @@
 #include "components/autofill/content/browser/content_autofill_driver.h"
 #include "components/autofill/core/browser/autofill_manager.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h"
 #include "components/navigation_interception/intercept_navigation_delegate.h"
 #include "content/public/browser/android/content_view_core.h"
 #include "content/public/browser/browser_thread.h"
@@ -54,7 +57,7 @@
 #include "content/public/common/renderer_preferences.h"
 #include "content/public/common/ssl_status.h"
 #include "jni/AwContents_jni.h"
-#include "net/cert/cert_database.h"
+#include "net/base/auth.h"
 #include "net/cert/x509_certificate.h"
 #include "third_party/skia/include/core/SkPicture.h"
 #include "ui/base/l10n/l10n_util_android.h"
@@ -75,6 +78,7 @@
 using base::android::JavaRef;
 using base::android::ScopedJavaGlobalRef;
 using base::android::ScopedJavaLocalRef;
+using data_reduction_proxy::DataReductionProxySettings;
 using navigation_interception::InterceptNavigationDelegate;
 using content::BrowserThread;
 using content::ContentViewCore;
@@ -125,11 +129,6 @@
       render_process_id, render_frame_id);
 }
 
-void NotifyClientCertificatesChanged() {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  net::CertDatabase::GetInstance()->OnAndroidKeyStoreChanged();
-}
-
 }  // namespace
 
 // static
@@ -169,8 +168,11 @@
   render_view_host_ext_.reset(
       new AwRenderViewHostExt(this, web_contents_.get()));
 
+  permission_request_handler_.reset(new PermissionRequestHandler(this));
+
   AwAutofillManagerDelegate* autofill_manager_delegate =
       AwAutofillManagerDelegate::FromWebContents(web_contents_.get());
+  InitDataReductionProxyIfNecessary();
   if (autofill_manager_delegate)
     InitAutofillIfNecessary(autofill_manager_delegate->GetSaveFormData());
 }
@@ -219,6 +221,12 @@
   }
 }
 
+void AwContents::InitDataReductionProxyIfNecessary() {
+  AwBrowserContext* browser_context =
+      AwBrowserContext::FromWebContents(web_contents_.get());
+  browser_context->CreateUserPrefServiceIfNecessary();
+}
+
 void AwContents::InitAutofillIfNecessary(bool enabled) {
   // Do not initialize if the feature is not enabled.
   if (!enabled)
@@ -518,6 +526,30 @@
   }
 }
 
+void AwContents::OnPermissionRequest(AwPermissionRequest* request) {
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> j_request = request->CreateJavaPeer();
+  ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
+  if (j_request.is_null() || j_ref.is_null()) {
+    permission_request_handler_->CancelRequest(
+        request->GetOrigin(), request->GetResources());
+    return;
+  }
+
+  Java_AwContents_onPermissionRequest(env, j_ref.obj(), j_request.obj());
+}
+
+void AwContents::OnPermissionRequestCanceled(AwPermissionRequest* request) {
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> j_request = request->GetJavaObject();
+  if (j_request.is_null())
+    return;
+
+  ScopedJavaLocalRef<jobject> j_ref = java_ref_.get(env);
+  Java_AwContents_onPermissionRequestCanceled(
+      env, j_ref.obj(), j_request.obj());
+}
+
 void AwContents::FindAllAsync(JNIEnv* env, jobject obj, jstring search_string) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   GetFindHelper()->FindAllAsync(ConvertJavaStringToUTF16(env, search_string));
@@ -762,10 +794,11 @@
 }
 
 void AwContents::ReleaseHardwareDrawOnRenderThread() {
-  DCHECK(hardware_renderer_);
-  DCHECK(shared_renderer_state_.IsHardwareInitialized());
   // No point in running any other commands if we released hardware already.
   shared_renderer_state_.ClearClosureQueue();
+  if (!shared_renderer_state_.IsHardwareInitialized())
+    return;
+
   hardware_renderer_.reset();
   shared_renderer_state_.SetHardwareInitialized(false);
 }
@@ -1012,13 +1045,6 @@
                                     extra_headers);
 }
 
-void AwContents::ClearClientCertPreferences(JNIEnv* env, jobject obj) {
-  content::BrowserThread::PostTask(
-      BrowserThread::IO,
-      FROM_HERE,
-      base::Bind(&NotifyClientCertificatesChanged));
-}
-
 void AwContents::SetJsOnlineProperty(JNIEnv* env,
                                      jobject obj,
                                      jboolean network_up) {
@@ -1030,28 +1056,12 @@
                             jobject obj,
                             jint level,
                             jboolean visible) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
   if (!shared_renderer_state_.IsHardwareInitialized())
     return;
 
-  shared_renderer_state_.AppendClosure(
-      base::Bind(&AwContents::TrimMemoryOnRenderThread,
-                 base::Unretained(this),
-                 level,
-                 visible));
-  RequestDrawGL(NULL, true);
-}
-
-void AwContents::TrimMemoryOnRenderThread(int level, bool visible) {
-  if (hardware_renderer_ && hardware_renderer_->TrimMemory(level, visible)) {
-    content::BrowserThread::PostTask(
-        content::BrowserThread::UI,
-        FROM_HERE,
-        base::Bind(&AwContents::ForceFakeComposite, ui_thread_weak_ptr_));
-  }
-}
-
-void AwContents::ForceFakeComposite() {
-  browser_view_renderer_.ForceFakeCompositeSW();
+  browser_view_renderer_.TrimMemory(level, visible);
 }
 
 void SetShouldDownloadFavicons(JNIEnv* env, jclass jclazz) {
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h
index 6c7d467..97f7250 100644
--- a/android_webview/native/aw_contents.h
+++ b/android_webview/native/aw_contents.h
@@ -16,6 +16,7 @@
 #include "android_webview/browser/icon_helper.h"
 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h"
 #include "android_webview/browser/shared_renderer_state.h"
+#include "android_webview/native/permission/permission_request_handler_client.h"
 #include "base/android/jni_weak_ref.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/callback_forward.h"
@@ -36,6 +37,7 @@
 class AwPdfExporter;
 class AwWebContentsDelegate;
 class HardwareRenderer;
+class PermissionRequestHandler;
 
 // Native side of java-class of same name.
 // Provides the ownership of and access to browser components required for
@@ -53,7 +55,8 @@
 class AwContents : public FindHelper::Listener,
                    public IconHelper::Listener,
                    public AwRenderViewHostExtClient,
-                   public BrowserViewRendererClient {
+                   public BrowserViewRendererClient,
+                   public PermissionRequestHandlerClient {
  public:
   // Returns the AwContents instance associated with |web_contents|, or NULL.
   static AwContents* FromWebContents(content::WebContents* web_contents);
@@ -128,9 +131,6 @@
 
   void DrawGL(AwDrawGLInfo* draw_info);
 
-  // TODO(sgurun) test this.
-  void ClearClientCertPreferences(JNIEnv* env, jobject obj);
-
   // Geolocation API support
   void ShowGeolocationPrompt(const GURL& origin, base::Callback<void(bool)>);
   void HideGeolocationPrompt(const GURL& origin);
@@ -139,6 +139,15 @@
                                  jboolean value,
                                  jstring origin);
 
+  // PermissionRequestHandlerClient implementation.
+  virtual void OnPermissionRequest(AwPermissionRequest* request) OVERRIDE;
+  virtual void OnPermissionRequestCanceled(
+      AwPermissionRequest* request) OVERRIDE;
+
+  PermissionRequestHandler* GetPermissionRequestHandler() {
+    return permission_request_handler_.get();
+  }
+
   // Find-in-page API and related methods.
   void FindAllAsync(JNIEnv* env, jobject obj, jstring search_string);
   void FindNext(JNIEnv* env, jobject obj, jboolean forward);
@@ -199,13 +208,12 @@
   void TrimMemory(JNIEnv* env, jobject obj, jint level, jboolean visible);
 
  private:
+  void InitDataReductionProxyIfNecessary();
   void InitAutofillIfNecessary(bool enabled);
   void DidDrawGL(const DrawGLResult& result);
-  void ForceFakeComposite();
 
   void InitializeHardwareDrawOnRenderThread();
   void ReleaseHardwareDrawOnRenderThread();
-  void TrimMemoryOnRenderThread(int level, bool visible);
 
   base::WeakPtrFactory<AwContents> weak_factory_on_ui_thread_;
   base::WeakPtr<AwContents> ui_thread_weak_ptr_;
@@ -222,6 +230,7 @@
   BrowserViewRenderer browser_view_renderer_;
   scoped_ptr<HardwareRenderer> hardware_renderer_;
   scoped_ptr<AwPdfExporter> pdf_exporter_;
+  scoped_ptr<PermissionRequestHandler> permission_request_handler_;
 
   // GURL is supplied by the content layer as requesting frame.
   // Callback is supplied by the content layer, and is invoked with the result
diff --git a/android_webview/native/aw_contents_io_thread_client_impl.cc b/android_webview/native/aw_contents_io_thread_client_impl.cc
index c863971..555cd83 100644
--- a/android_webview/native/aw_contents_io_thread_client_impl.cc
+++ b/android_webview/native/aw_contents_io_thread_client_impl.cc
@@ -112,7 +112,7 @@
 
   virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) OVERRIDE;
   virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) OVERRIDE;
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
  private:
   JavaObjectWeakGlobalRef jdelegate_;
@@ -142,7 +142,7 @@
   RfhToIoThreadClientMap::GetInstance()->Erase(GetRenderFrameHostIdPair(rfh));
 }
 
-void ClientMapEntryUpdater::WebContentsDestroyed(WebContents* web_contents) {
+void ClientMapEntryUpdater::WebContentsDestroyed() {
   delete this;
 }
 
diff --git a/android_webview/native/aw_contents_statics.cc b/android_webview/native/aw_contents_statics.cc
new file mode 100644
index 0000000..29453e6
--- /dev/null
+++ b/android_webview/native/aw_contents_statics.cc
@@ -0,0 +1,59 @@
+// 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.
+
+#include "android_webview/native/aw_contents_statics.h"
+
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/callback.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h"
+#include "content/public/browser/browser_thread.h"
+#include "jni/AwContentsStatics_jni.h"
+#include "net/cert/cert_database.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ConvertJavaStringToUTF8;
+using base::android::ScopedJavaGlobalRef;
+using content::BrowserThread;
+using data_reduction_proxy::DataReductionProxySettings;
+
+namespace android_webview {
+
+namespace {
+
+void ClientCertificatesCleared(ScopedJavaGlobalRef<jobject>* callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  JNIEnv* env = AttachCurrentThread();
+  Java_AwContentsStatics_clientCertificatesCleared(env, callback->obj());
+}
+
+void NotifyClientCertificatesChanged() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  net::CertDatabase::GetInstance()->OnAndroidKeyStoreChanged();
+}
+
+}  // namespace
+
+// static
+void ClearClientCertPreferences(JNIEnv* env, jclass, jobject callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  ScopedJavaGlobalRef<jobject>* j_callback = new ScopedJavaGlobalRef<jobject>();
+  j_callback->Reset(env, callback);
+  BrowserThread::PostTaskAndReply(
+      BrowserThread::IO,
+      FROM_HERE,
+      base::Bind(&NotifyClientCertificatesChanged),
+      base::Bind(&ClientCertificatesCleared, base::Owned(j_callback)));
+}
+
+// static
+void SetDataReductionProxyKey(JNIEnv* env, jclass, jstring key) {
+    DataReductionProxySettings::SetKey(ConvertJavaStringToUTF8(env, key));
+}
+
+bool RegisterAwContentsStatics(JNIEnv* env) {
+  return RegisterNativesImpl(env);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/native/aw_contents_statics.h b/android_webview/native/aw_contents_statics.h
new file mode 100644
index 0000000..0de5485
--- /dev/null
+++ b/android_webview/native/aw_contents_statics.h
@@ -0,0 +1,16 @@
+// 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.
+
+#ifndef ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_STATICS_H_
+#define ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_STATICS_H_
+
+#include <jni.h>
+
+namespace android_webview {
+
+bool RegisterAwContentsStatics(JNIEnv* env);
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_H_
diff --git a/android_webview/native/aw_dev_tools_server.cc b/android_webview/native/aw_dev_tools_server.cc
index fe3bffe..ab08ca5 100644
--- a/android_webview/native/aw_dev_tools_server.cc
+++ b/android_webview/native/aw_dev_tools_server.cc
@@ -42,8 +42,8 @@
   virtual std::string GetType() const OVERRIDE { return kTargetTypePage; }
   virtual std::string GetTitle() const OVERRIDE { return title_; }
   virtual std::string GetDescription() const OVERRIDE { return description_; }
-  virtual GURL GetUrl() const OVERRIDE { return url_; }
-  virtual GURL GetFaviconUrl() const OVERRIDE { return GURL(); }
+  virtual GURL GetURL() const OVERRIDE { return url_; }
+  virtual GURL GetFaviconURL() const OVERRIDE { return GURL(); }
   virtual base::TimeTicks GetLastActivityTime() const OVERRIDE {
     return last_activity_time_;
   }
diff --git a/android_webview/native/aw_settings.cc b/android_webview/native/aw_settings.cc
index 843ebf7..3779cd8 100644
--- a/android_webview/native/aw_settings.cc
+++ b/android_webview/native/aw_settings.cc
@@ -267,7 +267,7 @@
   UpdateEverything();
 }
 
-void AwSettings::WebContentsDestroyed(content::WebContents* web_contents) {
+void AwSettings::WebContentsDestroyed() {
   delete this;
 }
 
diff --git a/android_webview/native/aw_settings.h b/android_webview/native/aw_settings.h
index 95c0d9c..92bf658 100644
--- a/android_webview/native/aw_settings.h
+++ b/android_webview/native/aw_settings.h
@@ -46,8 +46,7 @@
   // WebContentsObserver overrides:
   virtual void RenderViewCreated(
       content::RenderViewHost* render_view_host) OVERRIDE;
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   bool accelerated_2d_canvas_disabled_by_switch_;
 
diff --git a/android_webview/native/aw_web_contents_delegate.cc b/android_webview/native/aw_web_contents_delegate.cc
index 3c5c40e..c91f6d3 100644
--- a/android_webview/native/aw_web_contents_delegate.cc
+++ b/android_webview/native/aw_web_contents_delegate.cc
@@ -8,6 +8,8 @@
 #include "android_webview/browser/find_helper.h"
 #include "android_webview/native/aw_contents.h"
 #include "android_webview/native/aw_contents_io_thread_client_impl.h"
+#include "android_webview/native/permission/media_access_permission_request.h"
+#include "android_webview/native/permission/permission_request_handler.h"
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
@@ -18,6 +20,7 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/file_chooser_params.h"
+#include "content/public/common/media_stream_request.h"
 #include "jni/AwWebContentsDelegate_jni.h"
 #include "ui/shell_dialogs/selected_file_info.h"
 
@@ -188,6 +191,22 @@
   }
 }
 
+void AwWebContentsDelegate::RequestMediaAccessPermission(
+    WebContents* web_contents,
+    const content::MediaStreamRequest& request,
+    const content::MediaResponseCallback& callback) {
+  AwContents* aw_contents = AwContents::FromWebContents(web_contents);
+  if (!aw_contents) {
+    callback.Run(content::MediaStreamDevices(),
+                 content::MEDIA_DEVICE_INVALID_STATE,
+                 scoped_ptr<content::MediaStreamUI>().Pass());
+    return;
+  }
+  aw_contents->GetPermissionRequestHandler()->SendRequest(
+      scoped_ptr<AwPermissionRequestDelegate>(
+          new MediaAccessPermissionRequest(request, callback)));
+}
+
 static void FilesSelectedInChooser(
     JNIEnv* env, jclass clazz,
     jint process_id, jint render_id, jint mode_flags,
diff --git a/android_webview/native/aw_web_contents_delegate.h b/android_webview/native/aw_web_contents_delegate.h
index 6f444a7..dce3fa7 100644
--- a/android_webview/native/aw_web_contents_delegate.h
+++ b/android_webview/native/aw_web_contents_delegate.h
@@ -49,6 +49,10 @@
 
   virtual void CloseContents(content::WebContents* source) OVERRIDE;
   virtual void ActivateContents(content::WebContents* contents) OVERRIDE;
+  virtual void RequestMediaAccessPermission(
+      content::WebContents* web_contents,
+      const content::MediaStreamRequest& request,
+      const content::MediaResponseCallback& callback) OVERRIDE;
 };
 
 bool RegisterAwWebContentsDelegate(JNIEnv* env);
diff --git a/android_webview/native/aw_web_contents_view_delegate.cc b/android_webview/native/aw_web_contents_view_delegate.cc
index 5c3db94..94f582a 100644
--- a/android_webview/native/aw_web_contents_view_delegate.cc
+++ b/android_webview/native/aw_web_contents_view_delegate.cc
@@ -6,7 +6,6 @@
 
 #include "content/public/browser/android/content_view_core.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/context_menu_params.h"
 
 namespace android_webview {
diff --git a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-arm.mk b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-arm.mk
index 339a7f7..8d09d6c 100644
--- a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-arm.mk
+++ b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-arm64.mk b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-arm64.mk
index ce3c062..2e01767 100644
--- a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-arm64.mk
+++ b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-mips.mk b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-mips.mk
index 75b826b..917c296 100644
--- a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-mips.mk
+++ b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-x86.mk b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-x86.mk
index 5471fb5..8604ffd 100644
--- a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-x86.mk
+++ b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-x86_64.mk b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-x86_64.mk
index 7b1954a..0b64671 100644
--- a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-x86_64.mk
+++ b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-arm.mk b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-arm.mk
index 339a7f7..8d09d6c 100644
--- a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-arm.mk
+++ b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-arm64.mk b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-arm64.mk
index ce3c062..2e01767 100644
--- a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-arm64.mk
+++ b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-mips.mk b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-mips.mk
index 75b826b..917c296 100644
--- a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-mips.mk
+++ b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-x86.mk b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-x86.mk
index 5471fb5..8604ffd 100644
--- a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-x86.mk
+++ b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-x86_64.mk b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-x86_64.mk
index 7b1954a..0b64671 100644
--- a/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-x86_64.mk
+++ b/android_webview/native/cancellation_signal_android_jar_jni_headers.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/CancellationSignal_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-arm.mk b/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-arm.mk
index c67e261..6611baf 100644
--- a/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-arm.mk
+++ b/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-arm64.mk b/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-arm64.mk
index 03a29a9..a3394dd 100644
--- a/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-arm64.mk
+++ b/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-mips.mk b/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-mips.mk
index 4a36095..d33e391 100644
--- a/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-mips.mk
+++ b/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-x86.mk b/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-x86.mk
index 9fb476b..08e75e5 100644
--- a/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-x86.mk
+++ b/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-x86_64.mk b/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-x86_64.mk
index a709baa..276c3a0 100644
--- a/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-x86_64.mk
+++ b/android_webview/native/input_stream_android_jar_jni_headers.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/input_stream_android_jar_jni_headers.target.linux-arm.mk b/android_webview/native/input_stream_android_jar_jni_headers.target.linux-arm.mk
index c67e261..6611baf 100644
--- a/android_webview/native/input_stream_android_jar_jni_headers.target.linux-arm.mk
+++ b/android_webview/native/input_stream_android_jar_jni_headers.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/android_webview/native/input_stream_android_jar_jni_headers.target.linux-arm64.mk b/android_webview/native/input_stream_android_jar_jni_headers.target.linux-arm64.mk
index 03a29a9..a3394dd 100644
--- a/android_webview/native/input_stream_android_jar_jni_headers.target.linux-arm64.mk
+++ b/android_webview/native/input_stream_android_jar_jni_headers.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/native/input_stream_android_jar_jni_headers.target.linux-mips.mk b/android_webview/native/input_stream_android_jar_jni_headers.target.linux-mips.mk
index 4a36095..d33e391 100644
--- a/android_webview/native/input_stream_android_jar_jni_headers.target.linux-mips.mk
+++ b/android_webview/native/input_stream_android_jar_jni_headers.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/android_webview/native/input_stream_android_jar_jni_headers.target.linux-x86.mk b/android_webview/native/input_stream_android_jar_jni_headers.target.linux-x86.mk
index 9fb476b..08e75e5 100644
--- a/android_webview/native/input_stream_android_jar_jni_headers.target.linux-x86.mk
+++ b/android_webview/native/input_stream_android_jar_jni_headers.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/input_stream_android_jar_jni_headers.target.linux-x86_64.mk b/android_webview/native/input_stream_android_jar_jni_headers.target.linux-x86_64.mk
index a709baa..276c3a0 100644
--- a/android_webview/native/input_stream_android_jar_jni_headers.target.linux-x86_64.mk
+++ b/android_webview/native/input_stream_android_jar_jni_headers.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/android_webview/jni/InputStream_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/android_webview/native/permission/aw_permission_request.cc b/android_webview/native/permission/aw_permission_request.cc
new file mode 100644
index 0000000..41b2449
--- /dev/null
+++ b/android_webview/native/permission/aw_permission_request.cc
@@ -0,0 +1,65 @@
+// 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.
+
+#include "android_webview/native/permission/aw_permission_request.h"
+
+#include "android_webview/native/permission/aw_permission_request_delegate.h"
+#include "base/android/jni_string.h"
+#include "jni/AwPermissionRequest_jni.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ConvertUTF8ToJavaString;
+using base::android::ScopedJavaGlobalRef;
+using base::android::ScopedJavaLocalRef;
+
+namespace android_webview {
+
+AwPermissionRequest::AwPermissionRequest(
+    scoped_ptr<AwPermissionRequestDelegate> delegate)
+    : delegate_(delegate.Pass()),
+      weak_factory_(this) {
+  DCHECK(delegate_.get());
+}
+
+AwPermissionRequest::~AwPermissionRequest() {
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> j_object = java_ref_.get(env);
+  if (j_object.is_null())
+    return;
+  Java_AwPermissionRequest_detachNativeInstance(env, j_object.obj());
+}
+
+void AwPermissionRequest::OnAccept(JNIEnv* env,
+                                   jobject jcaller,
+                                   jboolean accept) {
+  delegate_->NotifyRequestResult(accept);
+  delete this;
+}
+
+ScopedJavaLocalRef<jobject> AwPermissionRequest::CreateJavaPeer() {
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> j_object = Java_AwPermissionRequest_create(
+      env, reinterpret_cast<jlong>(this),
+      ConvertUTF8ToJavaString(env, GetOrigin().spec()).obj(), GetResources());
+  java_ref_ = JavaObjectWeakGlobalRef(env, j_object.obj());
+  return j_object;
+}
+
+ScopedJavaLocalRef<jobject> AwPermissionRequest::GetJavaObject() {
+  return java_ref_.get(AttachCurrentThread());
+}
+
+const GURL& AwPermissionRequest::GetOrigin() {
+  return delegate_->GetOrigin();
+}
+
+int64 AwPermissionRequest::GetResources() {
+  return delegate_->GetResources();
+}
+
+bool RegisterAwPermissionRequest(JNIEnv* env) {
+  return RegisterNativesImpl(env);
+}
+
+}  // namespace android_webivew
diff --git a/android_webview/native/permission/aw_permission_request.h b/android_webview/native/permission/aw_permission_request.h
new file mode 100644
index 0000000..e52e10d
--- /dev/null
+++ b/android_webview/native/permission/aw_permission_request.h
@@ -0,0 +1,70 @@
+// 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.
+
+#ifndef ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_H
+#define ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_H
+
+#include "base/android/jni_weak_ref.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/memory/weak_ptr.h"
+#include "url/gurl.h"
+
+namespace android_webview {
+
+class AwPermissionRequestDelegate;
+
+// This class wraps a permission request, it works with PermissionRequestHandler
+// and its' Java peer to represent the request to AwContentsClient.
+// The specific permission request should implement the
+// AwPermissionRequestDelegate interface, See MediaPermissionRequest.
+class AwPermissionRequest {
+ public:
+  // The definition must synced with Android's
+  // android.webkit.PermissionRequest.
+  enum Resource {
+    Geolocation = 1 << 0,
+    VideoCapture = 1 << 1,
+    AudioCapture = 1 << 2
+  };
+
+  // Take the ownership of |delegate|.
+  AwPermissionRequest(scoped_ptr<AwPermissionRequestDelegate> delegate);
+  virtual ~AwPermissionRequest();
+
+  base::WeakPtr<AwPermissionRequest> GetWeakPtr() {
+    return weak_factory_.GetWeakPtr();
+  }
+
+  // Create and return Java peer.
+  base::android::ScopedJavaLocalRef<jobject> CreateJavaPeer();
+
+  // Return the Java peer.
+  base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
+
+  // Invoked by Java peer when request is processed, |granted| indicates the
+  // request was granted or not.
+  void OnAccept(JNIEnv* env, jobject jcaller, jboolean granted);
+
+  // Return the origin which initiated the request.
+  const GURL& GetOrigin();
+
+  // Return the resources origin requested.
+  int64 GetResources();
+
+ private:
+  friend class TestAwPermissionRequest;
+
+  scoped_ptr<AwPermissionRequestDelegate> delegate_;
+  JavaObjectWeakGlobalRef java_ref_;
+
+  base::WeakPtrFactory<AwPermissionRequest> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwPermissionRequest);
+};
+
+bool RegisterAwPermissionRequest(JNIEnv* env);
+
+}  // namespace android_webivew
+
+#endif  // ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_H
diff --git a/android_webview/native/permission/aw_permission_request_delegate.cc b/android_webview/native/permission/aw_permission_request_delegate.cc
new file mode 100644
index 0000000..ed5309f
--- /dev/null
+++ b/android_webview/native/permission/aw_permission_request_delegate.cc
@@ -0,0 +1,13 @@
+// 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.
+
+#include "android_webview/native/permission/aw_permission_request_delegate.h"
+
+namespace android_webview {
+
+AwPermissionRequestDelegate::AwPermissionRequestDelegate() {}
+
+AwPermissionRequestDelegate::~AwPermissionRequestDelegate() {}
+
+}  // namespace android_webivew
diff --git a/android_webview/native/permission/aw_permission_request_delegate.h b/android_webview/native/permission/aw_permission_request_delegate.h
new file mode 100644
index 0000000..61402b3
--- /dev/null
+++ b/android_webview/native/permission/aw_permission_request_delegate.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_DELEGATE_H
+#define ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_DELEGATE_H
+
+#include "base/basictypes.h"
+#include "base/macros.h"
+#include "url/gurl.h"
+
+namespace android_webview {
+
+// The delegate interface to be implemented for a specific permission request.
+class AwPermissionRequestDelegate {
+ public:
+  AwPermissionRequestDelegate();
+  virtual ~AwPermissionRequestDelegate();
+
+  // Get the origin which initiated the permission request.
+  virtual const GURL& GetOrigin() = 0;
+
+  // Get the resources the origin wanted to access.
+  virtual int64 GetResources() = 0;
+
+  // Notify the permission request is allowed or not.
+  virtual void NotifyRequestResult(bool allowed) = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(AwPermissionRequestDelegate);
+};
+
+}  // namespace android_webivew
+
+#endif  // ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_DELEGATE_H
diff --git a/android_webview/native/permission/media_access_permission_request.cc b/android_webview/native/permission/media_access_permission_request.cc
new file mode 100644
index 0000000..6ef8c07
--- /dev/null
+++ b/android_webview/native/permission/media_access_permission_request.cc
@@ -0,0 +1,91 @@
+// 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.
+
+#include "android_webview/native/permission/media_access_permission_request.h"
+
+#include "android_webview/native/permission/aw_permission_request.h"
+#include "content/public/browser/media_capture_devices.h"
+
+using content::MediaCaptureDevices;
+using content::MediaStreamDevice;
+using content::MediaStreamDevices;
+
+namespace android_webview {
+
+namespace {
+
+// Return the device specified by |device_id| if exists, otherwise the first
+// available device is returned.
+const MediaStreamDevice* GetDeviceByIdOrFirstAvailable(
+    const MediaStreamDevices& devices,
+    const std::string& device_id) {
+  if (devices.empty())
+    return NULL;
+
+  if (!device_id.empty()) {
+    for (size_t i = 0; i < devices.size(); ++i) {
+      if (devices[i].id == device_id)
+        return &devices[i];
+    }
+  }
+
+  return &devices[0];
+}
+
+}  // namespace
+
+MediaAccessPermissionRequest::MediaAccessPermissionRequest(
+    const content::MediaStreamRequest& request,
+    const content::MediaResponseCallback& callback)
+    : request_(request),
+      callback_(callback) {
+}
+
+MediaAccessPermissionRequest::~MediaAccessPermissionRequest() {
+}
+
+void MediaAccessPermissionRequest::NotifyRequestResult(bool allowed) {
+  scoped_ptr<content::MediaStreamUI> ui;
+  MediaStreamDevices devices;
+  if (!allowed) {
+    callback_.Run(devices, content::MEDIA_DEVICE_PERMISSION_DENIED, ui.Pass());
+    return;
+  }
+
+  if (request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
+    const MediaStreamDevices& audio_devices = audio_test_devices_.empty()?
+        MediaCaptureDevices::GetInstance()->GetAudioCaptureDevices() :
+        audio_test_devices_;
+    const MediaStreamDevice* device = GetDeviceByIdOrFirstAvailable(
+        audio_devices, request_.requested_audio_device_id);
+    if (device)
+      devices.push_back(*device);
+  }
+
+  if (request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
+    const MediaStreamDevices& video_devices = video_test_devices_.empty()?
+        MediaCaptureDevices::GetInstance()->GetVideoCaptureDevices() :
+        video_test_devices_;
+    const MediaStreamDevice* device = GetDeviceByIdOrFirstAvailable(
+        video_devices, request_.requested_video_device_id);
+    if (device)
+      devices.push_back(*device);
+  }
+  callback_.Run(devices, devices.empty() ?
+                content::MEDIA_DEVICE_NO_HARDWARE : content::MEDIA_DEVICE_OK,
+                ui.Pass());
+}
+
+const GURL& MediaAccessPermissionRequest::GetOrigin() {
+  return request_.security_origin;
+}
+
+int64 MediaAccessPermissionRequest::GetResources() {
+  return (request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ?
+          AwPermissionRequest::AudioCapture : 0) |
+      (request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ?
+       AwPermissionRequest::VideoCapture : 0);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/native/permission/media_access_permission_request.h b/android_webview/native/permission/media_access_permission_request.h
new file mode 100644
index 0000000..1a4d482
--- /dev/null
+++ b/android_webview/native/permission/media_access_permission_request.h
@@ -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.
+
+#ifndef ANDROID_WEBVIEW_NATIVE_PERMISSION_MEDIA_ACCESS_PERMISSION_REQUEST_H
+#define ANDROID_WEBVIEW_NATIVE_PERMISSION_MEDIA_ACCESS_PERMISSION_REQUEST_H
+
+#include "android_webview/native/permission/aw_permission_request_delegate.h"
+#include "base/callback.h"
+#include "content/public/common/media_stream_request.h"
+
+namespace android_webview {
+
+// The AwPermissionRequestDelegate implementation for media access permission
+// request.
+class MediaAccessPermissionRequest : public AwPermissionRequestDelegate {
+ public:
+  MediaAccessPermissionRequest(const content::MediaStreamRequest& request,
+                               const content::MediaResponseCallback& callback);
+  virtual ~MediaAccessPermissionRequest();
+
+  // AwPermissionRequestDelegate implementation.
+  virtual const GURL& GetOrigin() OVERRIDE;
+  virtual int64 GetResources() OVERRIDE;
+  virtual void NotifyRequestResult(bool allowed) OVERRIDE;
+
+ private:
+  friend class TestMediaAccessPermissionRequest;
+
+  const content::MediaStreamRequest request_;
+  const content::MediaResponseCallback callback_;
+
+  // For test only.
+  content::MediaStreamDevices audio_test_devices_;
+  content::MediaStreamDevices video_test_devices_;
+
+  DISALLOW_COPY_AND_ASSIGN(MediaAccessPermissionRequest);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_NATIVE_PERMISSION_MEDIA_ACCESS_PERMISSION_REQUEST_H
diff --git a/android_webview/native/permission/media_access_permission_request_unittest.cc b/android_webview/native/permission/media_access_permission_request_unittest.cc
new file mode 100644
index 0000000..32a1906
--- /dev/null
+++ b/android_webview/native/permission/media_access_permission_request_unittest.cc
@@ -0,0 +1,139 @@
+// 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.
+
+#include "android_webview/native/permission/media_access_permission_request.h"
+#include "base/bind.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace android_webview {
+
+class TestMediaAccessPermissionRequest : public MediaAccessPermissionRequest {
+ public:
+  TestMediaAccessPermissionRequest(
+      const content::MediaStreamRequest& request,
+      const content::MediaResponseCallback& callback,
+      const content::MediaStreamDevices& audio_devices,
+      const content::MediaStreamDevices& video_devices)
+      : MediaAccessPermissionRequest(request, callback) {
+    audio_test_devices_ = audio_devices;
+    video_test_devices_ = video_devices;
+  }
+};
+
+class MediaAccessPermissionRequestTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    audio_device_id_ = "audio";
+    video_device_id_ = "video";
+    first_audio_device_id_ = "audio1";
+    first_video_device_id_ = "video1";
+  }
+
+  scoped_ptr<TestMediaAccessPermissionRequest> CreateRequest(
+      std::string audio_id,
+      std::string video_id) {
+    content::MediaStreamDevices audio_devices;
+    audio_devices.push_back(
+        content::MediaStreamDevice(content::MEDIA_DEVICE_AUDIO_CAPTURE,
+                                   first_audio_device_id_, "a2"));
+    audio_devices.push_back(
+        content::MediaStreamDevice(content::MEDIA_DEVICE_AUDIO_CAPTURE,
+                                   audio_device_id_, "a1"));
+
+    content::MediaStreamDevices video_devices;
+    video_devices.push_back(
+        content::MediaStreamDevice(content::MEDIA_DEVICE_VIDEO_CAPTURE,
+                                   first_video_device_id_, "v2"));
+    video_devices.push_back(
+        content::MediaStreamDevice(content::MEDIA_DEVICE_VIDEO_CAPTURE,
+                                   video_device_id_, "v1"));
+
+    GURL origin("https://www.google.com");
+    content::MediaStreamRequest request(
+        0, 0, 0, origin, false, content::MEDIA_GENERATE_STREAM, audio_id,
+        video_id, content::MEDIA_DEVICE_AUDIO_CAPTURE,
+        content::MEDIA_DEVICE_VIDEO_CAPTURE);
+
+    scoped_ptr<TestMediaAccessPermissionRequest> permission_request;
+    permission_request.reset(new TestMediaAccessPermissionRequest(
+        request,
+        base::Bind(&MediaAccessPermissionRequestTest::Callback,
+                   base::Unretained(this)),
+        audio_devices, video_devices));
+    return permission_request.Pass();
+  }
+
+  std::string audio_device_id_;
+  std::string video_device_id_;
+  std::string first_audio_device_id_;
+  std::string first_video_device_id_;
+  content::MediaStreamDevices devices_;
+  content::MediaStreamRequestResult result_;
+ private:
+  void Callback(
+      const content::MediaStreamDevices& devices,
+      content::MediaStreamRequestResult result,
+      scoped_ptr<content::MediaStreamUI> ui) {
+    devices_ = devices;
+    result_ = result;
+  }
+};
+
+TEST_F(MediaAccessPermissionRequestTest, TestGrantPermissionRequest) {
+  scoped_ptr<TestMediaAccessPermissionRequest> request =
+      CreateRequest(audio_device_id_, video_device_id_);
+  request->NotifyRequestResult(true);
+
+  EXPECT_EQ(2u, devices_.size());
+  EXPECT_EQ(content::MEDIA_DEVICE_OK, result_);
+
+  bool audio_exist = false;
+  bool video_exist = false;
+  for (content::MediaStreamDevices::iterator i = devices_.begin();
+       i != devices_.end(); ++i) {
+    if (i->type == content::MEDIA_DEVICE_AUDIO_CAPTURE &&
+        i->id == audio_device_id_) {
+      audio_exist = true;
+    } else if (i->type == content::MEDIA_DEVICE_VIDEO_CAPTURE &&
+               i->id == video_device_id_) {
+      video_exist = true;
+    }
+  }
+  EXPECT_TRUE(audio_exist);
+  EXPECT_TRUE(video_exist);
+}
+
+TEST_F(MediaAccessPermissionRequestTest, TestGrantPermissionRequestWithoutID) {
+  scoped_ptr<TestMediaAccessPermissionRequest> request =
+      CreateRequest(std::string(), std::string());
+  request->NotifyRequestResult(true);
+
+  EXPECT_EQ(2u, devices_.size());
+  EXPECT_EQ(content::MEDIA_DEVICE_OK, result_);
+
+  bool audio_exist = false;
+  bool video_exist = false;
+  for (content::MediaStreamDevices::iterator i = devices_.begin();
+       i != devices_.end(); ++i) {
+    if (i->type == content::MEDIA_DEVICE_AUDIO_CAPTURE &&
+        i->id == first_audio_device_id_) {
+      audio_exist = true;
+    } else if (i->type == content::MEDIA_DEVICE_VIDEO_CAPTURE &&
+               i->id == first_video_device_id_) {
+      video_exist = true;
+    }
+  }
+  EXPECT_TRUE(audio_exist);
+  EXPECT_TRUE(video_exist);
+}
+
+TEST_F(MediaAccessPermissionRequestTest, TestDenyPermissionRequest) {
+  scoped_ptr<TestMediaAccessPermissionRequest> request =
+      CreateRequest(std::string(), std::string());
+  request->NotifyRequestResult(false);
+  EXPECT_TRUE(devices_.empty());
+  EXPECT_EQ(content::MEDIA_DEVICE_PERMISSION_DENIED, result_);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/native/permission/permission_request_handler.cc b/android_webview/native/permission/permission_request_handler.cc
new file mode 100644
index 0000000..08b7431
--- /dev/null
+++ b/android_webview/native/permission/permission_request_handler.cc
@@ -0,0 +1,80 @@
+// 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.
+
+#include "android_webview/native/permission/permission_request_handler.h"
+
+#include "android_webview/native/permission/aw_permission_request.h"
+#include "android_webview/native/permission/aw_permission_request_delegate.h"
+#include "android_webview/native/permission/permission_request_handler_client.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/bind.h"
+
+using base::android::ScopedJavaLocalRef;
+
+namespace android_webview {
+
+PermissionRequestHandler::PermissionRequestHandler(
+    PermissionRequestHandlerClient* client)
+    : client_(client) {
+}
+
+PermissionRequestHandler::~PermissionRequestHandler() {
+  for (RequestIterator i = requests_.begin(); i != requests_.end(); ++i)
+    CancelRequest(i);
+}
+
+void PermissionRequestHandler::SendRequest(
+    scoped_ptr<AwPermissionRequestDelegate> request) {
+  AwPermissionRequest* aw_request = new AwPermissionRequest(request.Pass());
+  requests_.push_back(
+      base::WeakPtr<AwPermissionRequest>(aw_request->GetWeakPtr()));
+  client_->OnPermissionRequest(aw_request);
+  PruneRequests();
+}
+
+void PermissionRequestHandler::CancelRequest(const GURL& origin,
+                                             int64 resources) {
+  // The request list might have multiple requests with same origin and
+  // resources.
+  RequestIterator i = FindRequest(origin, resources);
+  while (i != requests_.end()) {
+    CancelRequest(i);
+    requests_.erase(i);
+    i = FindRequest(origin, resources);
+  }
+}
+
+PermissionRequestHandler::RequestIterator
+PermissionRequestHandler::FindRequest(const GURL& origin,
+                                      int64 resources) {
+  RequestIterator i;
+  for (i = requests_.begin(); i != requests_.end(); ++i) {
+    if (i->get() && i->get()->GetOrigin() == origin &&
+        i->get()->GetResources() == resources) {
+      break;
+    }
+  }
+  return i;
+}
+
+void PermissionRequestHandler::CancelRequest(RequestIterator i) {
+  if (i->get())
+    client_->OnPermissionRequestCanceled(i->get());
+  // The request's grant()/deny() could be called upon
+  // OnPermissionRequestCanceled. Delete AwPermissionRequest if it still
+  // exists.
+  if (i->get())
+    delete i->get();
+}
+
+void PermissionRequestHandler::PruneRequests() {
+  for (RequestIterator i = requests_.begin(); i != requests_.end();) {
+    if (!i->get())
+      i = requests_.erase(i);
+    else
+      ++i;
+  }
+}
+
+}  // namespace android_webivew
diff --git a/android_webview/native/permission/permission_request_handler.h b/android_webview/native/permission/permission_request_handler.h
new file mode 100644
index 0000000..d4d91b6
--- /dev/null
+++ b/android_webview/native/permission/permission_request_handler.h
@@ -0,0 +1,60 @@
+// 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.
+
+#ifndef ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_H
+#define ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_H
+
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "url/gurl.h"
+
+namespace android_webview {
+
+class AwPermissionRequest;
+class AwPermissionRequestDelegate;
+class PermissionRequestHandlerClient;
+
+// This class is used to send the permission requests, or cancel ongoing
+// requests.
+// It is owned by AwContents and has 1x1 mapping to AwContents. All methods
+// are running on UI thread.
+class PermissionRequestHandler {
+ public:
+  PermissionRequestHandler(PermissionRequestHandlerClient* aw_contents);
+  virtual ~PermissionRequestHandler();
+
+  // Send the given |request| to PermissionRequestHandlerClient.
+  void SendRequest(scoped_ptr<AwPermissionRequestDelegate> request);
+
+  // Cancel the ongoing request initiated by |origin| for accessing |resources|.
+  void CancelRequest(const GURL& origin, int64 resources);
+
+ private:
+  friend class TestPermissionRequestHandler;
+
+  typedef std::vector<base::WeakPtr<AwPermissionRequest> >::iterator
+      RequestIterator;
+
+  // Return the request initiated by |origin| for accessing |resources|.
+  RequestIterator FindRequest(const GURL& origin, int64 resources);
+
+  // Cancel the given request.
+  void CancelRequest(RequestIterator i);
+
+  // Remove the invalid requests from requests_.
+  void PruneRequests();
+
+  PermissionRequestHandlerClient* client_;
+
+  // A list of ongoing requests.
+  std::vector<base::WeakPtr<AwPermissionRequest> > requests_;
+
+  DISALLOW_COPY_AND_ASSIGN(PermissionRequestHandler);
+};
+
+}  // namespace android_webivew
+
+#endif  // ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_H
diff --git a/android_webview/native/permission/permission_request_handler_client.cc b/android_webview/native/permission/permission_request_handler_client.cc
new file mode 100644
index 0000000..5ec97e0
--- /dev/null
+++ b/android_webview/native/permission/permission_request_handler_client.cc
@@ -0,0 +1,13 @@
+// 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.
+
+#include "android_webview/native/permission/permission_request_handler_client.h"
+
+namespace android_webview {
+
+PermissionRequestHandlerClient::PermissionRequestHandlerClient() {}
+
+PermissionRequestHandlerClient::~PermissionRequestHandlerClient() {}
+
+}  // namespace android_webiew
diff --git a/android_webview/native/permission/permission_request_handler_client.h b/android_webview/native/permission/permission_request_handler_client.h
new file mode 100644
index 0000000..5ef44ca
--- /dev/null
+++ b/android_webview/native/permission/permission_request_handler_client.h
@@ -0,0 +1,23 @@
+// 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.
+
+#ifndef ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_CLIENT_H
+#define ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_CLIENT_H
+
+namespace android_webview {
+
+class AwPermissionRequest;
+
+class PermissionRequestHandlerClient {
+ public:
+  PermissionRequestHandlerClient();
+  virtual ~PermissionRequestHandlerClient();
+
+  virtual void OnPermissionRequest(AwPermissionRequest* request) = 0;
+  virtual void OnPermissionRequestCanceled(AwPermissionRequest* request) = 0;
+};
+
+}  // namespace android_webivew
+
+#endif  // ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_CLIENT_H
diff --git a/android_webview/native/permission/permission_request_handler_unittest.cc b/android_webview/native/permission/permission_request_handler_unittest.cc
new file mode 100644
index 0000000..2948dd9
--- /dev/null
+++ b/android_webview/native/permission/permission_request_handler_unittest.cc
@@ -0,0 +1,269 @@
+// 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.
+
+#include "android_webview/native/permission/aw_permission_request.h"
+#include "android_webview/native/permission/aw_permission_request_delegate.h"
+#include "android_webview/native/permission/permission_request_handler.h"
+#include "android_webview/native/permission/permission_request_handler_client.h"
+#include "base/bind.h"
+#include "base/callback.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace android_webview {
+
+class TestAwPermissionRequestDelegate : public AwPermissionRequestDelegate {
+ public:
+  TestAwPermissionRequestDelegate(
+      const GURL& origin, int64 resources, base::Callback<void(bool)> callback)
+      : origin_(origin),
+        resources_(resources),
+        callback_(callback) {}
+
+  // Get the origin which initiated the permission request.
+  virtual const GURL& GetOrigin() OVERRIDE {
+    return origin_;
+  }
+
+  // Get the resources the origin wanted to access.
+  virtual int64 GetResources() OVERRIDE {
+    return resources_;
+  }
+
+  // Notify the permission request is allowed or not.
+  virtual void NotifyRequestResult(bool allowed) OVERRIDE {
+    callback_.Run(allowed);
+  }
+
+ private:
+  GURL origin_;
+  int64 resources_;
+  base::Callback<void(bool)> callback_;
+};
+
+class TestPermissionRequestHandlerClient :
+      public PermissionRequestHandlerClient {
+ public:
+  struct Permission {
+    Permission()
+        :resources(0) {}
+    Permission(const GURL& origin, int64 resources)
+        : origin(origin),
+          resources(resources) {}
+    GURL origin;
+    int64 resources;
+  };
+
+  virtual void OnPermissionRequest(AwPermissionRequest* request) OVERRIDE {
+    request_ = request;
+    requested_permission_ =
+        Permission(request->GetOrigin(), request->GetResources());
+  }
+
+  virtual void OnPermissionRequestCanceled(
+      AwPermissionRequest* request) OVERRIDE{
+    canceled_permission_ =
+        Permission(request->GetOrigin(), request->GetResources());
+  }
+
+  AwPermissionRequest* request() {
+    return request_;
+  }
+
+  const Permission& requested_permission() {
+    return requested_permission_;
+  }
+
+  const Permission& canceled_permission() {
+    return canceled_permission_;
+  }
+
+  void Grant() {
+    request_->OnAccept(NULL, NULL, true);
+    request_ = NULL;
+  }
+
+  void Deny() {
+    request_->OnAccept(NULL, NULL, false);
+    request_ = NULL;
+  }
+
+ private:
+  AwPermissionRequest* request_;
+  Permission requested_permission_;
+  Permission canceled_permission_;
+};
+
+class TestPermissionRequestHandler : public PermissionRequestHandler {
+ public:
+  TestPermissionRequestHandler(PermissionRequestHandlerClient* client)
+      : PermissionRequestHandler(client) {
+  }
+
+  const std::vector<base::WeakPtr<AwPermissionRequest> > requests() {
+    return requests_;
+  }
+
+  void PruneRequests() {
+    return PermissionRequestHandler::PruneRequests();
+  }
+};
+
+class PermissionRequestHandlerTest : public testing::Test {
+ public:
+  PermissionRequestHandlerTest()
+      : handler_(&client_),
+        allowed_(false) {}
+
+  void NotifyRequestResult(bool allowed) {
+    allowed_ = allowed;
+  }
+
+ protected:
+  virtual void SetUp() OVERRIDE {
+    testing::Test::SetUp();
+    origin_ = GURL("http://www.google.com");
+    resources_ =
+        AwPermissionRequest::VideoCapture | AwPermissionRequest::AudioCapture;
+    delegate_.reset(
+        new TestAwPermissionRequestDelegate(
+            origin_, resources_, base::Bind(
+                &PermissionRequestHandlerTest::NotifyRequestResult,
+                base::Unretained(this))));
+  }
+
+  const GURL& origin() {
+    return origin_;
+  }
+
+  int64 resources() {
+    return resources_;
+  }
+
+  scoped_ptr<AwPermissionRequestDelegate> delegate() {
+    return delegate_.Pass();
+  }
+
+  TestPermissionRequestHandler* handler() {
+    return  &handler_;
+  }
+
+  TestPermissionRequestHandlerClient* client() {
+    return &client_;
+  }
+
+  bool allowed() {
+    return allowed_;
+  }
+
+ private:
+  GURL origin_;
+  int64 resources_;
+  scoped_ptr<AwPermissionRequestDelegate> delegate_;
+  TestPermissionRequestHandlerClient client_;
+  TestPermissionRequestHandler handler_;
+  bool allowed_;
+};
+
+TEST_F(PermissionRequestHandlerTest, TestPermissionGranted) {
+  handler()->SendRequest(delegate().Pass());
+  // Verify Handler store the request correctly.
+  ASSERT_EQ(1u, handler()->requests().size());
+  EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin());
+  EXPECT_EQ(resources(), handler()->requests()[0]->GetResources());
+
+  // Verify client's onPermissionRequest was called
+  EXPECT_EQ(origin(), client()->request()->GetOrigin());
+  EXPECT_EQ(resources(), client()->request()->GetResources());
+
+  // Simulate the grant request.
+  client()->Grant();
+  // Verify the request is notified as granted
+  EXPECT_TRUE(allowed());
+  handler()->PruneRequests();
+  // Verify the weak reference in handler was removed.
+  EXPECT_TRUE(handler()->requests().empty());
+}
+
+TEST_F(PermissionRequestHandlerTest, TestPermissionDenied) {
+  handler()->SendRequest(delegate().Pass());
+  // Verify Handler store the request correctly.
+  ASSERT_EQ(1u, handler()->requests().size());
+  EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin());
+  EXPECT_EQ(resources(), handler()->requests()[0]->GetResources());
+
+  // Verify client's onPermissionRequest was called
+  EXPECT_EQ(origin(), client()->request()->GetOrigin());
+  EXPECT_EQ(resources(), client()->request()->GetResources());
+
+  // Simulate the deny request.
+  client()->Deny();
+  // Verify the request is notified as granted
+  EXPECT_FALSE(allowed());
+  handler()->PruneRequests();
+  // Verify the weak reference in handler was removed.
+  EXPECT_TRUE(handler()->requests().empty());
+}
+
+TEST_F(PermissionRequestHandlerTest, TestMultiplePermissionRequest) {
+  GURL origin1 = GURL("http://a.google.com");
+  int64 resources1 = AwPermissionRequest::Geolocation;
+
+  scoped_ptr<AwPermissionRequestDelegate> delegate1;
+  delegate1.reset(new TestAwPermissionRequestDelegate(
+      origin1, resources1,
+      base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult,
+                 base::Unretained(this))));
+
+  // Send 1st request
+  handler()->SendRequest(delegate().Pass());
+  // Verify Handler store the request correctly.
+  ASSERT_EQ(1u, handler()->requests().size());
+  EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin());
+  EXPECT_EQ(resources(), handler()->requests()[0]->GetResources());
+  // Verify client's onPermissionRequest was called
+  EXPECT_EQ(origin(), client()->request()->GetOrigin());
+  EXPECT_EQ(resources(), client()->request()->GetResources());
+
+  // Send 2nd request
+  handler()->SendRequest(delegate1.Pass());
+  // Verify Handler store the request correctly.
+  ASSERT_EQ(2u, handler()->requests().size());
+  EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin());
+  EXPECT_EQ(resources(), handler()->requests()[0]->GetResources());
+  EXPECT_EQ(origin1, handler()->requests()[1]->GetOrigin());
+  EXPECT_EQ(resources1, handler()->requests()[1]->GetResources());
+  // Verify client's onPermissionRequest was called
+  EXPECT_EQ(origin1, client()->request()->GetOrigin());
+  EXPECT_EQ(resources1, client()->request()->GetResources());
+
+  // Send 3rd request which has same origin and resources as first one.
+  delegate1.reset(new TestAwPermissionRequestDelegate(origin(), resources(),
+      base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult,
+                 base::Unretained(this))));
+  handler()->SendRequest(delegate1.Pass());
+  // Verify Handler store the request correctly.
+  ASSERT_EQ(3u, handler()->requests().size());
+  EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin());
+  EXPECT_EQ(resources(), handler()->requests()[0]->GetResources());
+  EXPECT_EQ(origin1, handler()->requests()[1]->GetOrigin());
+  EXPECT_EQ(resources1, handler()->requests()[1]->GetResources());
+  EXPECT_EQ(origin(), handler()->requests()[2]->GetOrigin());
+  EXPECT_EQ(resources(), handler()->requests()[2]->GetResources());
+  // Verify client's onPermissionRequest was called
+  EXPECT_EQ(origin(), client()->request()->GetOrigin());
+  EXPECT_EQ(resources(), client()->request()->GetResources());
+
+  // Cancel the request.
+  handler()->CancelRequest(origin(), resources());
+  // Verify client's OnPermissionRequestCancled() was called.
+  EXPECT_EQ(origin(), client()->canceled_permission().origin);
+  EXPECT_EQ(resources(), client()->canceled_permission().resources);
+  // Verify Handler store the request correctly, the 1st and 3rd were removed.
+  handler()->PruneRequests();
+  ASSERT_EQ(1u, handler()->requests().size());
+  EXPECT_EQ(origin1, handler()->requests()[0]->GetOrigin());
+  EXPECT_EQ(resources1, handler()->requests()[0]->GetResources());
+}
+
+}  // android_webview
diff --git a/android_webview/native/webview_native.gyp b/android_webview/native/webview_native.gyp
index 9a1761b..d594142 100644
--- a/android_webview/native/webview_native.gyp
+++ b/android_webview/native/webview_native.gyp
@@ -46,6 +46,8 @@
         'aw_contents_client_bridge.h',
         'aw_contents_io_thread_client_impl.cc',
         'aw_contents_io_thread_client_impl.h',
+        'aw_contents_statics.cc',
+        'aw_contents_statics.h',
         'aw_dev_tools_server.cc',
         'aw_dev_tools_server.h',
         'aw_form_database.cc',
@@ -79,6 +81,16 @@
         'java_browser_view_renderer_helper.cc',
         'java_browser_view_renderer_helper.h',
         'net_init_native_callback.cc',
+        'permission/aw_permission_request.cc',
+        'permission/aw_permission_request.h',
+        'permission/aw_permission_request_delegate.cc',
+        'permission/aw_permission_request_delegate.h',
+        'permission/media_access_permission_request.cc',
+        'permission/media_access_permission_request.h',
+        'permission/permission_request_handler.cc',
+        'permission/permission_request_handler.h',
+        'permission/permission_request_handler_client.cc',
+        'permission/permission_request_handler_client.h',
         'state_serializer.cc',
         'state_serializer.h',
       ],
@@ -118,6 +130,7 @@
           '../java/src/org/chromium/android_webview/AwContents.java',
           '../java/src/org/chromium/android_webview/AwContentsClientBridge.java',
           '../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java',
+          '../java/src/org/chromium/android_webview/AwContentsStatics.java',
           '../java/src/org/chromium/android_webview/AwCookieManager.java',
           '../java/src/org/chromium/android_webview/AwDevToolsServer.java',
           '../java/src/org/chromium/android_webview/AwFormDatabase.java',
@@ -131,6 +144,7 @@
           '../java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java',
           '../java/src/org/chromium/android_webview/InterceptedRequestData.java',
           '../java/src/org/chromium/android_webview/JavaBrowserViewRendererHelper.java',
+          '../java/src/org/chromium/android_webview/permission/AwPermissionRequest.java',
       ],
       'variables': {
         'jni_gen_package': 'android_webview',
diff --git a/android_webview/native/webview_native.target.darwin-arm.mk b/android_webview/native/webview_native.target.darwin-arm.mk
index e50777d..16096b9 100644
--- a/android_webview/native/webview_native.target.darwin-arm.mk
+++ b/android_webview/native/webview_native.target.darwin-arm.mk
@@ -35,6 +35,7 @@
 	android_webview/native/aw_contents.cc \
 	android_webview/native/aw_contents_client_bridge.cc \
 	android_webview/native/aw_contents_io_thread_client_impl.cc \
+	android_webview/native/aw_contents_statics.cc \
 	android_webview/native/aw_dev_tools_server.cc \
 	android_webview/native/aw_form_database.cc \
 	android_webview/native/aw_geolocation_permission_context.cc \
@@ -52,6 +53,11 @@
 	android_webview/native/intercepted_request_data_impl.cc \
 	android_webview/native/java_browser_view_renderer_helper.cc \
 	android_webview/native/net_init_native_callback.cc \
+	android_webview/native/permission/aw_permission_request.cc \
+	android_webview/native/permission/aw_permission_request_delegate.cc \
+	android_webview/native/permission/media_access_permission_request.cc \
+	android_webview/native/permission/permission_request_handler.cc \
+	android_webview/native/permission/permission_request_handler_client.cc \
 	android_webview/native/state_serializer.cc
 
 
@@ -69,7 +75,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -119,11 +124,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -201,7 +201,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -251,11 +250,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/native/webview_native.target.darwin-arm64.mk b/android_webview/native/webview_native.target.darwin-arm64.mk
index 20e3219..443b22e 100644
--- a/android_webview/native/webview_native.target.darwin-arm64.mk
+++ b/android_webview/native/webview_native.target.darwin-arm64.mk
@@ -35,6 +35,7 @@
 	android_webview/native/aw_contents.cc \
 	android_webview/native/aw_contents_client_bridge.cc \
 	android_webview/native/aw_contents_io_thread_client_impl.cc \
+	android_webview/native/aw_contents_statics.cc \
 	android_webview/native/aw_dev_tools_server.cc \
 	android_webview/native/aw_form_database.cc \
 	android_webview/native/aw_geolocation_permission_context.cc \
@@ -52,6 +53,11 @@
 	android_webview/native/intercepted_request_data_impl.cc \
 	android_webview/native/java_browser_view_renderer_helper.cc \
 	android_webview/native/net_init_native_callback.cc \
+	android_webview/native/permission/aw_permission_request.cc \
+	android_webview/native/permission/aw_permission_request_delegate.cc \
+	android_webview/native/permission/media_access_permission_request.cc \
+	android_webview/native/permission/permission_request_handler.cc \
+	android_webview/native/permission/permission_request_handler_client.cc \
 	android_webview/native/state_serializer.cc
 
 
@@ -115,11 +121,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -242,11 +243,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/native/webview_native.target.darwin-mips.mk b/android_webview/native/webview_native.target.darwin-mips.mk
index f3e32d4..4e5fe9a 100644
--- a/android_webview/native/webview_native.target.darwin-mips.mk
+++ b/android_webview/native/webview_native.target.darwin-mips.mk
@@ -35,6 +35,7 @@
 	android_webview/native/aw_contents.cc \
 	android_webview/native/aw_contents_client_bridge.cc \
 	android_webview/native/aw_contents_io_thread_client_impl.cc \
+	android_webview/native/aw_contents_statics.cc \
 	android_webview/native/aw_dev_tools_server.cc \
 	android_webview/native/aw_form_database.cc \
 	android_webview/native/aw_geolocation_permission_context.cc \
@@ -52,6 +53,11 @@
 	android_webview/native/intercepted_request_data_impl.cc \
 	android_webview/native/java_browser_view_renderer_helper.cc \
 	android_webview/native/net_init_native_callback.cc \
+	android_webview/native/permission/aw_permission_request.cc \
+	android_webview/native/permission/aw_permission_request_delegate.cc \
+	android_webview/native/permission/media_access_permission_request.cc \
+	android_webview/native/permission/permission_request_handler.cc \
+	android_webview/native/permission/permission_request_handler_client.cc \
 	android_webview/native/state_serializer.cc
 
 
@@ -118,11 +124,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -249,11 +250,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/native/webview_native.target.darwin-x86.mk b/android_webview/native/webview_native.target.darwin-x86.mk
index bd3eebc..2e153a0 100644
--- a/android_webview/native/webview_native.target.darwin-x86.mk
+++ b/android_webview/native/webview_native.target.darwin-x86.mk
@@ -35,6 +35,7 @@
 	android_webview/native/aw_contents.cc \
 	android_webview/native/aw_contents_client_bridge.cc \
 	android_webview/native/aw_contents_io_thread_client_impl.cc \
+	android_webview/native/aw_contents_statics.cc \
 	android_webview/native/aw_dev_tools_server.cc \
 	android_webview/native/aw_form_database.cc \
 	android_webview/native/aw_geolocation_permission_context.cc \
@@ -52,6 +53,11 @@
 	android_webview/native/intercepted_request_data_impl.cc \
 	android_webview/native/java_browser_view_renderer_helper.cc \
 	android_webview/native/net_init_native_callback.cc \
+	android_webview/native/permission/aw_permission_request.cc \
+	android_webview/native/permission/aw_permission_request_delegate.cc \
+	android_webview/native/permission/media_access_permission_request.cc \
+	android_webview/native/permission/permission_request_handler.cc \
+	android_webview/native/permission/permission_request_handler_client.cc \
 	android_webview/native/state_serializer.cc
 
 
@@ -71,7 +77,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -119,11 +124,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -202,7 +202,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -250,11 +249,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/native/webview_native.target.darwin-x86_64.mk b/android_webview/native/webview_native.target.darwin-x86_64.mk
index f124d5f..f5fbc6c 100644
--- a/android_webview/native/webview_native.target.darwin-x86_64.mk
+++ b/android_webview/native/webview_native.target.darwin-x86_64.mk
@@ -35,6 +35,7 @@
 	android_webview/native/aw_contents.cc \
 	android_webview/native/aw_contents_client_bridge.cc \
 	android_webview/native/aw_contents_io_thread_client_impl.cc \
+	android_webview/native/aw_contents_statics.cc \
 	android_webview/native/aw_dev_tools_server.cc \
 	android_webview/native/aw_form_database.cc \
 	android_webview/native/aw_geolocation_permission_context.cc \
@@ -52,6 +53,11 @@
 	android_webview/native/intercepted_request_data_impl.cc \
 	android_webview/native/java_browser_view_renderer_helper.cc \
 	android_webview/native/net_init_native_callback.cc \
+	android_webview/native/permission/aw_permission_request.cc \
+	android_webview/native/permission/aw_permission_request_delegate.cc \
+	android_webview/native/permission/media_access_permission_request.cc \
+	android_webview/native/permission/permission_request_handler.cc \
+	android_webview/native/permission/permission_request_handler_client.cc \
 	android_webview/native/state_serializer.cc
 
 
@@ -71,7 +77,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -120,11 +125,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -204,7 +204,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -253,11 +252,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/native/webview_native.target.linux-arm.mk b/android_webview/native/webview_native.target.linux-arm.mk
index e50777d..16096b9 100644
--- a/android_webview/native/webview_native.target.linux-arm.mk
+++ b/android_webview/native/webview_native.target.linux-arm.mk
@@ -35,6 +35,7 @@
 	android_webview/native/aw_contents.cc \
 	android_webview/native/aw_contents_client_bridge.cc \
 	android_webview/native/aw_contents_io_thread_client_impl.cc \
+	android_webview/native/aw_contents_statics.cc \
 	android_webview/native/aw_dev_tools_server.cc \
 	android_webview/native/aw_form_database.cc \
 	android_webview/native/aw_geolocation_permission_context.cc \
@@ -52,6 +53,11 @@
 	android_webview/native/intercepted_request_data_impl.cc \
 	android_webview/native/java_browser_view_renderer_helper.cc \
 	android_webview/native/net_init_native_callback.cc \
+	android_webview/native/permission/aw_permission_request.cc \
+	android_webview/native/permission/aw_permission_request_delegate.cc \
+	android_webview/native/permission/media_access_permission_request.cc \
+	android_webview/native/permission/permission_request_handler.cc \
+	android_webview/native/permission/permission_request_handler_client.cc \
 	android_webview/native/state_serializer.cc
 
 
@@ -69,7 +75,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -119,11 +124,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -201,7 +201,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -251,11 +250,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/native/webview_native.target.linux-arm64.mk b/android_webview/native/webview_native.target.linux-arm64.mk
index 20e3219..443b22e 100644
--- a/android_webview/native/webview_native.target.linux-arm64.mk
+++ b/android_webview/native/webview_native.target.linux-arm64.mk
@@ -35,6 +35,7 @@
 	android_webview/native/aw_contents.cc \
 	android_webview/native/aw_contents_client_bridge.cc \
 	android_webview/native/aw_contents_io_thread_client_impl.cc \
+	android_webview/native/aw_contents_statics.cc \
 	android_webview/native/aw_dev_tools_server.cc \
 	android_webview/native/aw_form_database.cc \
 	android_webview/native/aw_geolocation_permission_context.cc \
@@ -52,6 +53,11 @@
 	android_webview/native/intercepted_request_data_impl.cc \
 	android_webview/native/java_browser_view_renderer_helper.cc \
 	android_webview/native/net_init_native_callback.cc \
+	android_webview/native/permission/aw_permission_request.cc \
+	android_webview/native/permission/aw_permission_request_delegate.cc \
+	android_webview/native/permission/media_access_permission_request.cc \
+	android_webview/native/permission/permission_request_handler.cc \
+	android_webview/native/permission/permission_request_handler_client.cc \
 	android_webview/native/state_serializer.cc
 
 
@@ -115,11 +121,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -242,11 +243,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/native/webview_native.target.linux-mips.mk b/android_webview/native/webview_native.target.linux-mips.mk
index f3e32d4..4e5fe9a 100644
--- a/android_webview/native/webview_native.target.linux-mips.mk
+++ b/android_webview/native/webview_native.target.linux-mips.mk
@@ -35,6 +35,7 @@
 	android_webview/native/aw_contents.cc \
 	android_webview/native/aw_contents_client_bridge.cc \
 	android_webview/native/aw_contents_io_thread_client_impl.cc \
+	android_webview/native/aw_contents_statics.cc \
 	android_webview/native/aw_dev_tools_server.cc \
 	android_webview/native/aw_form_database.cc \
 	android_webview/native/aw_geolocation_permission_context.cc \
@@ -52,6 +53,11 @@
 	android_webview/native/intercepted_request_data_impl.cc \
 	android_webview/native/java_browser_view_renderer_helper.cc \
 	android_webview/native/net_init_native_callback.cc \
+	android_webview/native/permission/aw_permission_request.cc \
+	android_webview/native/permission/aw_permission_request_delegate.cc \
+	android_webview/native/permission/media_access_permission_request.cc \
+	android_webview/native/permission/permission_request_handler.cc \
+	android_webview/native/permission/permission_request_handler_client.cc \
 	android_webview/native/state_serializer.cc
 
 
@@ -118,11 +124,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -249,11 +250,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/native/webview_native.target.linux-x86.mk b/android_webview/native/webview_native.target.linux-x86.mk
index bd3eebc..2e153a0 100644
--- a/android_webview/native/webview_native.target.linux-x86.mk
+++ b/android_webview/native/webview_native.target.linux-x86.mk
@@ -35,6 +35,7 @@
 	android_webview/native/aw_contents.cc \
 	android_webview/native/aw_contents_client_bridge.cc \
 	android_webview/native/aw_contents_io_thread_client_impl.cc \
+	android_webview/native/aw_contents_statics.cc \
 	android_webview/native/aw_dev_tools_server.cc \
 	android_webview/native/aw_form_database.cc \
 	android_webview/native/aw_geolocation_permission_context.cc \
@@ -52,6 +53,11 @@
 	android_webview/native/intercepted_request_data_impl.cc \
 	android_webview/native/java_browser_view_renderer_helper.cc \
 	android_webview/native/net_init_native_callback.cc \
+	android_webview/native/permission/aw_permission_request.cc \
+	android_webview/native/permission/aw_permission_request_delegate.cc \
+	android_webview/native/permission/media_access_permission_request.cc \
+	android_webview/native/permission/permission_request_handler.cc \
+	android_webview/native/permission/permission_request_handler_client.cc \
 	android_webview/native/state_serializer.cc
 
 
@@ -71,7 +77,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -119,11 +124,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -202,7 +202,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -250,11 +249,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/native/webview_native.target.linux-x86_64.mk b/android_webview/native/webview_native.target.linux-x86_64.mk
index f124d5f..f5fbc6c 100644
--- a/android_webview/native/webview_native.target.linux-x86_64.mk
+++ b/android_webview/native/webview_native.target.linux-x86_64.mk
@@ -35,6 +35,7 @@
 	android_webview/native/aw_contents.cc \
 	android_webview/native/aw_contents_client_bridge.cc \
 	android_webview/native/aw_contents_io_thread_client_impl.cc \
+	android_webview/native/aw_contents_statics.cc \
 	android_webview/native/aw_dev_tools_server.cc \
 	android_webview/native/aw_form_database.cc \
 	android_webview/native/aw_geolocation_permission_context.cc \
@@ -52,6 +53,11 @@
 	android_webview/native/intercepted_request_data_impl.cc \
 	android_webview/native/java_browser_view_renderer_helper.cc \
 	android_webview/native/net_init_native_callback.cc \
+	android_webview/native/permission/aw_permission_request.cc \
+	android_webview/native/permission/aw_permission_request_delegate.cc \
+	android_webview/native/permission/media_access_permission_request.cc \
+	android_webview/native/permission/permission_request_handler.cc \
+	android_webview/native/permission/permission_request_handler_client.cc \
 	android_webview/native/state_serializer.cc
 
 
@@ -71,7 +77,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -120,11 +125,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -204,7 +204,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -253,11 +252,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/android_webview/renderer/DEPS b/android_webview/renderer/DEPS
index a40a8a2..b5cbb48 100644
--- a/android_webview/renderer/DEPS
+++ b/android_webview/renderer/DEPS
@@ -4,6 +4,7 @@
   "+android_webview/renderer",
 
   "+components/autofill/content/renderer",
+  "+components/cdm/renderer",
   "+components/visitedlink/renderer",
 
   "+content/public/renderer",
diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc
index 87a855f..400d009 100644
--- a/android_webview/renderer/aw_content_renderer_client.cc
+++ b/android_webview/renderer/aw_content_renderer_client.cc
@@ -96,8 +96,8 @@
   // For HTTP schemes, only top-level navigations can be overridden. Similarly,
   // WebView Classic lets app override only top level about:blank navigations.
   // So we filter out non-top about:blank navigations here.
-  if (frame->parent() && (gurl.SchemeIs(content::kHttpScheme) ||
-                          gurl.SchemeIs(content::kHttpsScheme) ||
+  if (frame->parent() && (gurl.SchemeIs(url::kHttpScheme) ||
+                          gurl.SchemeIs(url::kHttpsScheme) ||
                           gurl.SchemeIs(content::kAboutScheme)))
     return false;
 
diff --git a/android_webview/renderer/aw_key_systems.cc b/android_webview/renderer/aw_key_systems.cc
index b276c88..fb17c01 100644
--- a/android_webview/renderer/aw_key_systems.cc
+++ b/android_webview/renderer/aw_key_systems.cc
@@ -3,45 +3,13 @@
 // found in the LICENSE file.
 
 #include "android_webview/renderer/aw_key_systems.h"
-
-#include <string>
-
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "content/public/common/eme_codec.h"
-#include "third_party/widevine/cdm/widevine_cdm_common.h"
-
-using content::KeySystemInfo;
-
-namespace {
-
-// Return |name|'s parent key system.
-std::string GetDirectParentName(const std::string& name) {
-  int last_period = name.find_last_of('.');
-  DCHECK_GT(last_period, 0);
-  return name.substr(0, last_period);
-}
-
-void AddWidevineWithCodecs(const std::string& key_system_name,
-                           bool add_parent_name,
-                           std::vector<KeySystemInfo>* concrete_key_systems) {
-  KeySystemInfo info(key_system_name);
-
-  if (add_parent_name)
-    info.parent_key_system = GetDirectParentName(key_system_name);
-
-  info.supported_codecs = content::EME_CODEC_MP4_ALL;
-
-  concrete_key_systems->push_back(info);
-}
-
-}  // namespace
+#include "components/cdm/renderer/widevine_key_systems.h"
 
 namespace android_webview {
 
 void AwAddKeySystems(
-    std::vector<KeySystemInfo>* key_systems_info) {
-  AddWidevineWithCodecs(kWidevineKeySystem, true, key_systems_info);
+    std::vector<content::KeySystemInfo>* key_systems_info) {
+  cdm::AddAndroidWidevine(key_systems_info);
 }
 
 }  // namespace android_webview
diff --git a/android_webview/renderer/aw_render_view_ext.cc b/android_webview/renderer/aw_render_view_ext.cc
index b12821e..033fce6 100644
--- a/android_webview/renderer/aw_render_view_ext.cc
+++ b/android_webview/renderer/aw_render_view_ext.cc
@@ -69,9 +69,10 @@
   const base::StringPiece spec(url.possibly_invalid_spec());
 
   if (spec.starts_with(prefix)) {
-    url_canon::RawCanonOutputW<1024> output;
-    url_util::DecodeURLEscapeSequences(spec.data() + prefix.length(),
-        spec.length() - prefix.length(), &output);
+    url::RawCanonOutputW<1024> output;
+    url::DecodeURLEscapeSequences(spec.data() + prefix.length(),
+                                  spec.length() - prefix.length(),
+                                  &output);
     std::string decoded_url = base::UTF16ToUTF8(
         base::string16(output.data(), output.length()));
     dest->assign(decoded_url.begin(), decoded_url.end());
diff --git a/android_webview/test/shell/AndroidManifest.xml b/android_webview/test/shell/AndroidManifest.xml
index b6ec63e..3c21ab8 100644
--- a/android_webview/test/shell/AndroidManifest.xml
+++ b/android_webview/test/shell/AndroidManifest.xml
@@ -36,4 +36,7 @@
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.WAKE_LOCK"/>
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+  <uses-permission android:name="android.permission.RECORD_AUDIO" />
+  <uses-permission android:name="android.permission.RECORD_VIDEO" />
+  <uses-permission android:name="android.permission.CAMERA" />
 </manifest>
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java
index f6488f4..b019d8a 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java
@@ -11,8 +11,12 @@
 import org.chromium.android_webview.AwBrowserProcess;
 import org.chromium.base.BaseSwitches;
 import org.chromium.base.CommandLine;
+import org.chromium.base.TraceEvent;
 import org.chromium.content.browser.ResourceExtractor;
 
+/**
+ * The android_webview shell Application subclass.
+ */
 public class AwShellApplication extends Application {
 
     private static final String TAG = "AwShellApplication";
@@ -38,5 +42,10 @@
         ResourceExtractor.setMandatoryPaksToExtract(MANDATORY_PAKS);
         ResourceExtractor.setExtractImplicitLocaleForTesting(false);
         AwBrowserProcess.loadLibrary();
+
+        if (CommandLine.getInstance().hasSwitch(AwShellSwitches.ENABLE_ATRACE)) {
+            Log.e(TAG, "Enabling Android trace.");
+            TraceEvent.setATraceEnabled(true);
+        }
     }
 }
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellSwitches.java b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellSwitches.java
new file mode 100644
index 0000000..2aceb92
--- /dev/null
+++ b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellSwitches.java
@@ -0,0 +1,18 @@
+// 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.android_webview.shell;
+
+/**
+ * Contains all of the command line switches that are specific to the test shell of
+ * the android_webview glue layer.
+ */
+public abstract class AwShellSwitches {
+    // Enables Android systrace path for Chrome traces.
+    public static final String ENABLE_ATRACE = "enable-atrace";
+
+    // Prevent instantiation.
+    private AwShellSwitches() {}
+}
+
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java b/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java
index 353250c..85c994b 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java
@@ -23,6 +23,7 @@
 import org.chromium.android_webview.InterceptedRequestData;
 import org.chromium.android_webview.JsPromptResultReceiver;
 import org.chromium.android_webview.JsResultReceiver;
+import org.chromium.android_webview.permission.AwPermissionRequest;
 import org.chromium.base.ThreadUtils;
 
 import java.security.Principal;
@@ -219,4 +220,13 @@
     public Bitmap getDefaultVideoPoster() {
         return null;
     }
+
+    @Override
+    public void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
+        awPermissionRequest.deny();
+    }
+
+    @Override
+    public void onPermissionRequestCanceled(AwPermissionRequest awPermissionRequest) {
+    }
 }
diff --git a/apps/app_lifetime_monitor.cc b/apps/app_lifetime_monitor.cc
index 34aa701..83a3c56 100644
--- a/apps/app_lifetime_monitor.cc
+++ b/apps/app_lifetime_monitor.cc
@@ -88,8 +88,6 @@
     NotifyAppActivated(app_window->extension_id());
 }
 
-void AppLifetimeMonitor::OnAppWindowIconChanged(AppWindow* app_window) {}
-
 void AppLifetimeMonitor::OnAppWindowRemoved(AppWindow* app_window) {
   AppWindowRegistry::AppWindowList windows =
       AppWindowRegistry::Get(app_window->browser_context())
diff --git a/apps/app_lifetime_monitor.h b/apps/app_lifetime_monitor.h
index fe63514..a9fed9c 100644
--- a/apps/app_lifetime_monitor.h
+++ b/apps/app_lifetime_monitor.h
@@ -63,7 +63,6 @@
 
   // AppWindowRegistry::Observer overrides:
   virtual void OnAppWindowAdded(AppWindow* app_window) OVERRIDE;
-  virtual void OnAppWindowIconChanged(AppWindow* app_window) OVERRIDE;
   virtual void OnAppWindowRemoved(AppWindow* app_window) OVERRIDE;
 
   // KeyedService overrides:
diff --git a/apps/app_shim/app_shim_host_manager_mac.h b/apps/app_shim/app_shim_host_manager_mac.h
index 615f80f..0e3a9d2 100644
--- a/apps/app_shim/app_shim_host_manager_mac.h
+++ b/apps/app_shim/app_shim_host_manager_mac.h
@@ -56,6 +56,11 @@
   // Called on the IO thread to begin listening for connections from app shims.
   void ListenOnIOThread();
 
+  // The AppShimHostManager is only initialized if the Chrome process
+  // successfully took the singleton lock. This prevents subsequent processes
+  // from deleting existing app shim socket files.
+  bool did_init_;
+
   base::FilePath directory_in_tmp_;
 
   scoped_ptr<IPC::ChannelFactory> factory_;
diff --git a/apps/app_shim/app_shim_host_manager_mac.mm b/apps/app_shim/app_shim_host_manager_mac.mm
index 26ae9b5..769b166 100644
--- a/apps/app_shim/app_shim_host_manager_mac.mm
+++ b/apps/app_shim/app_shim_host_manager_mac.mm
@@ -50,10 +50,13 @@
 
 }  // namespace
 
-AppShimHostManager::AppShimHostManager() {}
+AppShimHostManager::AppShimHostManager()
+    : did_init_(false) {}
 
 void AppShimHostManager::Init() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!did_init_);
+  did_init_ = true;
   apps::AppShimHandler::SetDefaultHandler(&extension_app_shim_handler_);
   BrowserThread::PostTask(
       BrowserThread::FILE, FROM_HERE,
@@ -61,8 +64,11 @@
 }
 
 AppShimHostManager::~AppShimHostManager() {
-  apps::AppShimHandler::SetDefaultHandler(NULL);
   factory_.reset();
+  if (!did_init_)
+    return;
+
+  apps::AppShimHandler::SetDefaultHandler(NULL);
   base::FilePath symlink_path;
   if (PathService::Get(chrome::DIR_USER_DATA, &symlink_path))
     symlink_path = symlink_path.Append(app_mode::kAppShimSocketSymlinkName);
diff --git a/apps/app_window.cc b/apps/app_window.cc
index cf20eea..a48f79d 100644
--- a/apps/app_window.cc
+++ b/apps/app_window.cc
@@ -31,8 +31,8 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/resource_dispatcher_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/media_stream_request.h"
+#include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/extensions_browser_client.h"
 #include "extensions/browser/process_manager.h"
@@ -231,7 +231,6 @@
                      Delegate* delegate,
                      const extensions::Extension* extension)
     : browser_context_(context),
-      extension_(extension),
       extension_id_(extension->id()),
       window_type_(WINDOW_TYPE_DEFAULT),
       delegate_(delegate),
@@ -280,7 +279,11 @@
 
   native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params));
 
-  if (!new_params.hidden) {
+  if (new_params.hidden) {
+    // Although the window starts hidden by default, calling Hide() here
+    // notifies observers of the window being hidden.
+    Hide();
+  } else {
     // Panels are not activated by default.
     Show(window_type_is_panel() || !new_params.focused ? SHOW_INACTIVE
                                                        : SHOW_ACTIVE);
@@ -322,7 +325,6 @@
     // We want to show the window only when the content has been painted. For
     // that to happen, we need to define a size for the content, otherwise the
     // layout will happen in a 0x0 area.
-    // Note: WebContents::GetView() is guaranteed to be non-null.
     gfx::Insets frame_insets = native_app_window_->GetFrameInsets();
     gfx::Rect initial_bounds = new_params.GetInitialWindowBounds(frame_insets);
     initial_bounds.Inset(frame_insets);
@@ -350,8 +352,12 @@
     content::WebContents* web_contents,
     const content::MediaStreamRequest& request,
     const content::MediaResponseCallback& callback) {
+  const extensions::Extension* extension = GetExtension();
+  if (!extension)
+    return;
+
   delegate_->RequestMediaAccessPermission(
-      web_contents, request, callback, extension());
+      web_contents, request, callback, extension);
 }
 
 WebContents* AppWindow::OpenURLFromTab(WebContents* source,
@@ -409,6 +415,10 @@
     content::WebContents* source,
     const content::NativeWebKeyboardEvent& event,
     bool* is_keyboard_shortcut) {
+  const extensions::Extension* extension = GetExtension();
+  if (!extension)
+    return false;
+
   // Here, we can handle a key event before the content gets it. When we are
   // fullscreen and it is not forced, we want to allow the user to leave
   // when ESC is pressed.
@@ -420,7 +430,7 @@
   if (event.windowsKeyCode == ui::VKEY_ESCAPE &&
       (fullscreen_types_ != FULLSCREEN_TYPE_NONE) &&
       ((fullscreen_types_ & FULLSCREEN_TYPE_FORCED) == 0) &&
-      !extension_->HasAPIPermission(APIPermission::kOverrideEscFullscreen)) {
+      !extension->HasAPIPermission(APIPermission::kOverrideEscFullscreen)) {
     Restore();
     return true;
   }
@@ -447,9 +457,13 @@
 void AppWindow::RequestToLockMouse(WebContents* web_contents,
                                    bool user_gesture,
                                    bool last_unlocked_by_target) {
+  const extensions::Extension* extension = GetExtension();
+  if (!extension)
+    return;
+
   bool has_permission = IsExtensionWithPermissionOrSuggestInConsole(
       APIPermission::kPointerLock,
-      extension_,
+      extension,
       web_contents->GetRenderViewHost());
 
   web_contents->GotResponseToLockMouseRequest(has_permission);
@@ -463,7 +477,7 @@
          event.type == blink::WebGestureEvent::GesturePinchEnd;
 }
 
-void AppWindow::DidFirstVisuallyNonEmptyPaint(int32 page_id) {
+void AppWindow::DidFirstVisuallyNonEmptyPaint() {
   first_paint_complete_ = true;
   if (show_on_first_paint_) {
     DCHECK(delayed_show_type_ == SHOW_ACTIVE ||
@@ -506,6 +520,12 @@
   return app_window_contents_->GetWebContents();
 }
 
+const extensions::Extension* AppWindow::GetExtension() const {
+  return extensions::ExtensionRegistry::Get(browser_context_)
+      ->enabled_extensions()
+      .GetByID(extension_id_);
+}
+
 NativeAppWindow* AppWindow::GetBaseWindow() { return native_app_window_.get(); }
 
 gfx::NativeWindow AppWindow::GetNativeWindow() {
@@ -519,13 +539,17 @@
 }
 
 base::string16 AppWindow::GetTitle() const {
+  base::string16 title;
+  const extensions::Extension* extension = GetExtension();
+  if (!extension)
+    return title;
+
   // WebContents::GetTitle() will return the page's URL if there's no <title>
   // specified. However, we'd prefer to show the name of the extension in that
   // case, so we directly inspect the NavigationEntry's title.
-  base::string16 title;
   if (!web_contents() || !web_contents()->GetController().GetActiveEntry() ||
       web_contents()->GetController().GetActiveEntry()->GetTitle().empty()) {
-    title = base::UTF8ToUTF16(extension()->name());
+    title = base::UTF8ToUTF16(extension->name());
   } else {
     title = web_contents()->GetTitle();
   }
@@ -672,6 +696,7 @@
       GetBaseWindow()->ShowInactive();
       break;
   }
+  AppWindowRegistry::Get(browser_context_)->AppWindowShown(this);
 }
 
 void AppWindow::Hide() {
@@ -681,6 +706,7 @@
   // show will not be delayed.
   show_on_first_paint_ = false;
   GetBaseWindow()->Hide();
+  AppWindowRegistry::Get(browser_context_)->AppWindowHidden(this);
 }
 
 void AppWindow::SetAlwaysOnTop(bool always_on_top) {
@@ -792,10 +818,15 @@
   const gfx::ImageSkia& default_icon =
       *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
           IDR_APP_DEFAULT_ICON);
+
+  const extensions::Extension* extension = GetExtension();
+  if (!extension)
+    return;
+
   app_icon_image_.reset(
       new extensions::IconImage(browser_context(),
-                                extension(),
-                                extensions::IconsInfo::GetIcons(extension()),
+                                extension,
+                                extensions::IconsInfo::GetIcons(extension),
                                 delegate_->PreferredIconSize(),
                                 default_icon,
                                 this));
@@ -905,10 +936,12 @@
   }
 #endif
 
+  const extensions::Extension* extension = GetExtension();
+  if (!extension)
+    return;
+
   if (!IsExtensionWithPermissionOrSuggestInConsole(
-           APIPermission::kFullscreen,
-           extension_,
-           source->GetRenderViewHost())) {
+          APIPermission::kFullscreen, extension, source->GetRenderViewHost())) {
     return;
   }
 
@@ -932,7 +965,7 @@
       const extensions::Extension* unloaded_extension =
           content::Details<extensions::UnloadedExtensionInfo>(details)
               ->extension;
-      if (extension_ == unloaded_extension)
+      if (extension_id_ == unloaded_extension->id())
         native_app_window_->Close();
       break;
     }
@@ -941,7 +974,7 @@
           content::Details<const extensions::InstalledExtensionInfo>(details)
               ->extension;
       DCHECK(installed_extension);
-      if (installed_extension->id() == extension_->id())
+      if (installed_extension->id() == extension_id())
         native_app_window_->UpdateShelfMenu();
       break;
     }
@@ -987,7 +1020,7 @@
       gfx::Screen::GetNativeScreen()->GetDisplayMatching(bounds).work_area();
   ui::WindowShowState window_state = native_app_window_->GetRestoredState();
   cache->SaveGeometry(
-      extension()->id(), window_key_, bounds, screen_bounds, window_state);
+      extension_id(), window_key_, bounds, screen_bounds, window_state);
 }
 
 void AppWindow::AdjustBoundsToBeVisibleOnScreen(
@@ -1043,7 +1076,7 @@
     gfx::Rect cached_bounds;
     gfx::Rect cached_screen_bounds;
     ui::WindowShowState cached_state = ui::SHOW_STATE_DEFAULT;
-    if (cache->GetGeometry(extension()->id(),
+    if (cache->GetGeometry(extension_id(),
                            params.window_key,
                            &cached_bounds,
                            &cached_screen_bounds,
diff --git a/apps/app_window.h b/apps/app_window.h
index aecd250..3fd5757 100644
--- a/apps/app_window.h
+++ b/apps/app_window.h
@@ -250,7 +250,6 @@
 
   const std::string& window_key() const { return window_key_; }
   const SessionID& session_id() const { return session_id_; }
-  const extensions::Extension* extension() const { return extension_; }
   const std::string& extension_id() const { return extension_id_; }
   content::WebContents* web_contents() const;
   WindowType window_type() const { return window_type_; }
@@ -264,6 +263,7 @@
   const gfx::Image& badge_icon() const { return badge_icon_; }
   const GURL& badge_icon_url() const { return badge_icon_url_; }
 
+  const extensions::Extension* GetExtension() const;
   NativeAppWindow* GetBaseWindow();
   gfx::NativeWindow GetNativeWindow();
 
@@ -405,7 +405,7 @@
       OVERRIDE;
 
   // content::WebContentsObserver implementation.
-  virtual void DidFirstVisuallyNonEmptyPaint(int32 page_id) OVERRIDE;
+  virtual void DidFirstVisuallyNonEmptyPaint() OVERRIDE;
 
   // content::NotificationObserver implementation.
   virtual void Observe(int type,
@@ -473,8 +473,6 @@
   // not own this object.
   content::BrowserContext* browser_context_;
 
-  // weak pointer - owned by ExtensionService.
-  const extensions::Extension* extension_;
   const std::string extension_id_;
 
   // Identifier that is used when saving and restoring geometry for this
diff --git a/apps/app_window_registry.cc b/apps/app_window_registry.cc
index b362a5b..cf4839a 100644
--- a/apps/app_window_registry.cc
+++ b/apps/app_window_registry.cc
@@ -35,7 +35,7 @@
   if (app_window->window_key().empty())
     return app_window->web_contents()->GetURL().possibly_invalid_spec();
 
-  std::string key = app_window->extension()->id();
+  std::string key = app_window->extension_id();
   key += ':';
   key += app_window->window_key();
   return key;
@@ -45,6 +45,25 @@
 
 namespace apps {
 
+void AppWindowRegistry::Observer::OnAppWindowAdded(AppWindow* app_window) {
+}
+
+void AppWindowRegistry::Observer::OnAppWindowIconChanged(
+    AppWindow* app_window) {
+}
+
+void AppWindowRegistry::Observer::OnAppWindowRemoved(AppWindow* app_window) {
+}
+
+void AppWindowRegistry::Observer::OnAppWindowHidden(AppWindow* app_window) {
+}
+
+void AppWindowRegistry::Observer::OnAppWindowShown(AppWindow* app_window) {
+}
+
+AppWindowRegistry::Observer::~Observer() {
+}
+
 AppWindowRegistry::AppWindowRegistry(content::BrowserContext* context)
     : context_(context),
       devtools_callback_(base::Bind(&AppWindowRegistry::OnDevToolsStateChanged,
@@ -77,6 +96,14 @@
   BringToFront(app_window);
 }
 
+void AppWindowRegistry::AppWindowHidden(AppWindow* app_window) {
+  FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowHidden(app_window));
+}
+
+void AppWindowRegistry::AppWindowShown(AppWindow* app_window) {
+  FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowShown(app_window));
+}
+
 void AppWindowRegistry::RemoveAppWindow(AppWindow* app_window) {
   const AppWindowList::iterator it =
       std::find(app_windows_.begin(), app_windows_.end(), app_window);
@@ -144,7 +171,7 @@
   for (AppWindowList::const_iterator i = app_windows_.begin();
        i != app_windows_.end();
        ++i) {
-    if ((*i)->extension()->id() == app_id) {
+    if ((*i)->extension_id() == app_id) {
       result = *i;
       if (result->GetBaseWindow()->IsActive())
         return result;
@@ -161,7 +188,7 @@
   for (AppWindowList::const_iterator i = app_windows_.begin();
        i != app_windows_.end();
        ++i) {
-    if ((*i)->extension()->id() == app_id && (*i)->window_key() == window_key) {
+    if ((*i)->extension_id() == app_id && (*i)->window_key() == window_key) {
       result = *i;
       if (result->GetBaseWindow()->IsActive())
         return result;
diff --git a/apps/app_window_registry.h b/apps/app_window_registry.h
index cc3ee35..a055e1b 100644
--- a/apps/app_window_registry.h
+++ b/apps/app_window_registry.h
@@ -32,14 +32,20 @@
   class Observer {
    public:
     // Called just after a app window was added.
-    virtual void OnAppWindowAdded(apps::AppWindow* app_window) = 0;
+    virtual void OnAppWindowAdded(apps::AppWindow* app_window);
     // Called when the window icon changes.
-    virtual void OnAppWindowIconChanged(apps::AppWindow* app_window) = 0;
+    virtual void OnAppWindowIconChanged(apps::AppWindow* app_window);
     // Called just after a app window was removed.
-    virtual void OnAppWindowRemoved(apps::AppWindow* app_window) = 0;
+    virtual void OnAppWindowRemoved(apps::AppWindow* app_window);
+    // Called just after a app window was hidden. This is different from
+    // window visibility as a minimize does not hide a window, but does make
+    // it not visible.
+    virtual void OnAppWindowHidden(apps::AppWindow* app_window);
+    // Called just after a app window was shown.
+    virtual void OnAppWindowShown(apps::AppWindow* app_window);
 
    protected:
-    virtual ~Observer() {}
+    virtual ~Observer();
   };
 
   typedef std::list<apps::AppWindow*> AppWindowList;
@@ -58,6 +64,8 @@
   void AppWindowIconChanged(apps::AppWindow* app_window);
   // Called by |app_window| when it is activated.
   void AppWindowActivated(apps::AppWindow* app_window);
+  void AppWindowHidden(apps::AppWindow* app_window);
+  void AppWindowShown(apps::AppWindow* app_window);
   void RemoveAppWindow(apps::AppWindow* app_window);
 
   void AddObserver(Observer* observer);
diff --git a/apps/shell/DEPS b/apps/shell/DEPS
index 8a9dc71..d1b37cd 100644
--- a/apps/shell/DEPS
+++ b/apps/shell/DEPS
@@ -16,17 +16,8 @@
   "+grit/app_shell_resources.h",
   "+grit/extensions_resources.h",
 
-  # TODO(yoz): Do not depend on Chrome resources.
-  "!grit/common_resources.h",
-
   # Real DEPS go in subdirectories, for example apps/shell/browser/DEPS.
   # Temporary exceptions for app_shell bring-up go here.
   # TODO(jamescook): Remove these. http://crbug.com/305404
   "!chrome/browser/chrome_notification_types.h",
-  "!chrome/common/extensions/api/generated_api.h",
-  "!chrome/common/extensions/api/generated_schemas.h",
-  "!chrome/common/extensions/permissions/chrome_api_permissions.h",
-  "!chrome/renderer/extensions/dispatcher.h",
-  "!chrome/renderer/extensions/extension_helper.h",
-  "!chrome/renderer/resource_bundle_source_map.h",
 ]
diff --git a/apps/shell/app_shell.gyp b/apps/shell/app_shell.gyp
index 1324ea5..3fc8152 100644
--- a/apps/shell/app_shell.gyp
+++ b/apps/shell/app_shell.gyp
@@ -67,17 +67,6 @@
       'type': 'static_library',
       'defines!': ['CONTENT_IMPLEMENTATION'],
       'dependencies': [
-        '<(DEPTH)/chrome/chrome.gyp:browser',
-        '<(DEPTH)/chrome/chrome.gyp:browser_extensions',
-        '<(DEPTH)/chrome/chrome.gyp:debugger',
-        '<(DEPTH)/chrome/chrome.gyp:plugin',
-        '<(DEPTH)/chrome/chrome.gyp:renderer',
-        '<(DEPTH)/chrome/chrome.gyp:utility',
-        '<(DEPTH)/chrome/chrome_resources.gyp:chrome_resources',
-        '<(DEPTH)/chrome/common/extensions/api/api.gyp:chrome_api',
-        '<(DEPTH)/third_party/WebKit/public/blink_devtools.gyp:blink_devtools_frontend_resources',
-        # TODO(rockot): Dependencies above this line are temporary.
-        # See http://crbug.com/359656.
         'app_shell_pak',
         '<(DEPTH)/apps/shell/common/api/api.gyp:shell_api',
         '<(DEPTH)/base/base.gyp:base',
@@ -128,6 +117,10 @@
         'browser/shell_extension_web_contents_observer.h',
         'browser/shell_extensions_browser_client.cc',
         'browser/shell_extensions_browser_client.h',
+        'browser/shell_network_controller_chromeos.cc',
+        'browser/shell_network_controller_chromeos.h',
+        'browser/shell_runtime_api_delegate.cc',
+        'browser/shell_runtime_api_delegate.h',
         'common/shell_app_runtime.cc',
         'common/shell_app_runtime.h',
         'common/shell_content_client.cc',
@@ -139,13 +132,17 @@
         'renderer/shell_custom_bindings.cc',
         'renderer/shell_custom_bindings.h',
         'renderer/shell_custom_bindings.js',
+        'renderer/shell_dispatcher_delegate.cc',
+        'renderer/shell_dispatcher_delegate.h',
         'renderer/shell_extensions_renderer_client.cc',
         'renderer/shell_extensions_renderer_client.h',
       ],
       'conditions': [
         ['chromeos==1', {
           'dependencies': [
+            '<(DEPTH)/chromeos/chromeos.gyp:chromeos',
             '<(DEPTH)/ui/chromeos/ui_chromeos.gyp:ui_chromeos',
+            '<(DEPTH)/ui/display/display.gyp:display',
           ],
         }],
       ],
diff --git a/apps/shell/app_shell_resources.grd b/apps/shell/app_shell_resources.grd
index 4e77d0d..236b488 100644
--- a/apps/shell/app_shell_resources.grd
+++ b/apps/shell/app_shell_resources.grd
@@ -8,6 +8,9 @@
   </outputs>
   <release seq="1">
     <includes>
+      <!-- Features specific to app_shell. -->
+      <include name="IDR_SHELL_EXTENSION_API_FEATURES" file="common\api\_api_features.json" type="BINDATA" />
+      
       <!-- Custom bindings for extension APIs. -->
       <include name="IDR_SHELL_CUSTOM_BINDINGS_JS" file="renderer\shell_custom_bindings.js" type="BINDATA" />
     </includes>
diff --git a/apps/shell/browser/DEPS b/apps/shell/browser/DEPS
index 5b49515..9d8d30b 100644
--- a/apps/shell/browser/DEPS
+++ b/apps/shell/browser/DEPS
@@ -1,6 +1,7 @@
 include_rules = [
   "+chromeos",
   "+components/user_prefs",
+  "+third_party/cros_system_api",
 
   # Override apps/DEPS to be more selective about content includes.
   "-content",
diff --git a/apps/shell/browser/api/shell/shell_api.cc b/apps/shell/browser/api/shell/shell_api.cc
index f06996c..c108b0f 100644
--- a/apps/shell/browser/api/shell/shell_api.cc
+++ b/apps/shell/browser/api/shell/shell_api.cc
@@ -21,6 +21,8 @@
 namespace apps {
 namespace {
 
+const char kInvalidArguments[] = "Invalid arguments";
+
 // Creates a function call result to send to the renderer.
 DictionaryValue* CreateResult(apps::ShellAppWindow* app_window) {
   int view_id = app_window->GetRenderViewRoutingID();
@@ -49,14 +51,14 @@
 ShellCreateWindowFunction::~ShellCreateWindowFunction() {
 }
 
-bool ShellCreateWindowFunction::RunImpl() {
+ExtensionFunction::ResponseAction ShellCreateWindowFunction::Run() {
   scoped_ptr<CreateWindow::Params> params(CreateWindow::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
   // Convert "main.html" to "chrome-extension:/<id>/main.html".
   GURL url = GetExtension()->GetResourceURL(params->url);
   if (!url.is_valid())
-    return false;
+    return RespondNow(Error(kInvalidArguments));
 
   // The desktop keeps ownership of the window.
   apps::ShellAppWindow* app_window =
@@ -65,11 +67,7 @@
   app_window->LoadURL(url);
 
   // Create the reply to send to the renderer.
-  DictionaryValue* result = CreateResult(app_window);
-  SetResult(result);
-
-  SendResponse(true /* success */);
-  return true;
+  return RespondNow(SingleArgument(CreateResult(app_window)));
 }
 
 }  // namespace apps
diff --git a/apps/shell/browser/api/shell/shell_api.h b/apps/shell/browser/api/shell/shell_api.h
index 209fc99..b572ce7 100644
--- a/apps/shell/browser/api/shell/shell_api.h
+++ b/apps/shell/browser/api/shell/shell_api.h
@@ -39,7 +39,7 @@
 
  private:
   virtual ~ShellCreateWindowFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual ResponseAction Run() OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(ShellCreateWindowFunction);
 };
diff --git a/apps/shell/browser/shell_app_window.cc b/apps/shell/browser/shell_app_window.cc
index 52b1f6a..8015ff5 100644
--- a/apps/shell/browser/shell_app_window.cc
+++ b/apps/shell/browser/shell_app_window.cc
@@ -8,7 +8,6 @@
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/view_type_utils.h"
 #include "extensions/common/extension_messages.h"
 #include "ipc/ipc_message_macros.h"
@@ -44,11 +43,11 @@
 void ShellAppWindow::LoadURL(const GURL& url) {
   content::NavigationController::LoadURLParams params(url);
   web_contents_->GetController().LoadURLWithParams(params);
-  web_contents_->GetView()->Focus();
+  web_contents_->Focus();
 }
 
 aura::Window* ShellAppWindow::GetNativeWindow() {
-  return web_contents_->GetView()->GetNativeView();
+  return web_contents_->GetNativeView();
 }
 
 int ShellAppWindow::GetRenderViewRoutingID() {
diff --git a/apps/shell/browser/shell_app_window_api.cc b/apps/shell/browser/shell_app_window_api.cc
new file mode 100644
index 0000000..de1012c
--- /dev/null
+++ b/apps/shell/browser/shell_app_window_api.cc
@@ -0,0 +1,85 @@
+// 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.
+
+#include "apps/shell/browser/shell_app_window_api.h"
+
+#include "apps/shell/browser/shell_app_window.h"
+#include "apps/shell/browser/shell_desktop_controller.h"
+#include "base/values.h"
+
+using base::DictionaryValue;
+
+namespace extensions {
+namespace {
+
+// Returns stub values for window bounds.
+DictionaryValue* CreateStubBoundsProperties() {
+  DictionaryValue* properties = new DictionaryValue;
+  properties->SetInteger("left", 0);
+  properties->SetInteger("top", 0);
+  properties->SetInteger("width", 0);
+  properties->SetInteger("height", 0);
+  return properties;
+}
+
+// Creates a function call result to send to the renderer.
+DictionaryValue* CreateResult(apps::ShellAppWindow* app_window) {
+  int view_id = app_window->GetRenderViewRoutingID();
+
+  DictionaryValue* result = new DictionaryValue;
+  result->Set("viewId", new base::FundamentalValue(view_id));
+  result->Set("injectTitlebar", new base::FundamentalValue(false));
+  result->Set("id", new base::StringValue("app_shell"));
+
+  // Add stub window property data.
+  result->SetBoolean("fullscreen", true);
+  result->SetBoolean("minimized", false);
+  result->SetBoolean("maximized", false);
+  result->SetBoolean("alwaysOnTop", false);
+  result->SetBoolean("hasFrameColor", false);
+  result->SetInteger("frameColor", 0);
+  result->Set("innerBounds", CreateStubBoundsProperties());
+  result->Set("outerBounds", CreateStubBoundsProperties());
+
+  return result;
+}
+
+}  // namespace
+
+ShellAppWindowCreateFunction::ShellAppWindowCreateFunction() {
+}
+
+ShellAppWindowCreateFunction::~ShellAppWindowCreateFunction() {
+}
+
+bool ShellAppWindowCreateFunction::RunAsync() {
+  // Arguments must contain a URL and may contain options and a callback.
+  if (args_->GetSize() < 1 || args_->GetSize() > 3)
+    return false;
+
+  // Extract the URL for the window contents, e.g. "main.html".
+  std::string url_string;
+  if (!args_->GetString(0, &url_string))
+    return false;
+
+  // Convert "main.html" to "chrome-extension:/<id>/main.html".
+  GURL url = GetExtension()->GetResourceURL(url_string);
+  if (!url.is_valid())
+    return false;
+
+  // The desktop keeps ownership of the window.
+  apps::ShellAppWindow* app_window =
+      apps::ShellDesktopController::instance()->CreateAppWindow(
+          browser_context());
+  app_window->LoadURL(url);
+
+  // Create the reply to send to the renderer.
+  DictionaryValue* result = CreateResult(app_window);
+  SetResult(result);
+
+  SendResponse(true /* success */);
+  return true;
+}
+
+}  // namespace extensions
diff --git a/apps/shell/browser/shell_app_window_api.h b/apps/shell/browser/shell_app_window_api.h
new file mode 100644
index 0000000..bb5eb37
--- /dev/null
+++ b/apps/shell/browser/shell_app_window_api.h
@@ -0,0 +1,31 @@
+// 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.
+
+#ifndef APPS_SHELL_BROWSER_SHELL_APP_WINDOW_API_H_
+#define APPS_SHELL_BROWSER_SHELL_APP_WINDOW_API_H_
+
+#include "base/compiler_specific.h"
+#include "extensions/browser/extension_function.h"
+
+namespace extensions {
+
+// A simplified implementation of the chrome.app.window.create() function for
+// app_shell. Opens a fullscreen window and invokes the window callback. Most
+// of the response is stub data, but the JS contentWindow is valid.
+class ShellAppWindowCreateFunction : public AsyncExtensionFunction {
+ public:
+  ShellAppWindowCreateFunction();
+
+  // Don't use the APP_WINDOW_CREATE histogram so we don't pollute the
+  // statistics for the real Chrome implementation.
+  DECLARE_EXTENSION_FUNCTION("app.window.create", UNKNOWN);
+
+ private:
+  virtual ~ShellAppWindowCreateFunction();
+  virtual bool RunAsync() OVERRIDE;
+};
+
+}  // namespace extensions
+
+#endif  // APPS_SHELL_BROWSER_SHELL_APP_WINDOW_API_H_
diff --git a/apps/shell/browser/shell_browser_main_parts.cc b/apps/shell/browser/shell_browser_main_parts.cc
index c886b74..be1c82d 100644
--- a/apps/shell/browser/shell_browser_main_parts.cc
+++ b/apps/shell/browser/shell_browser_main_parts.cc
@@ -24,6 +24,7 @@
 #include "ui/base/resource/resource_bundle.h"
 
 #if defined(OS_CHROMEOS)
+#include "apps/shell/browser/shell_network_controller_chromeos.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #endif
 
@@ -61,6 +62,7 @@
 void ShellBrowserMainParts::PostMainMessageLoopStart() {
 #if defined(OS_CHROMEOS)
   chromeos::DBusThreadManager::Initialize();
+  network_controller_.reset(new ShellNetworkController);
 #endif
 }
 
@@ -144,6 +146,7 @@
 
 void ShellBrowserMainParts::PostDestroyThreads() {
 #if defined(OS_CHROMEOS)
+  network_controller_.reset();
   chromeos::DBusThreadManager::Shutdown();
 #endif
 }
diff --git a/apps/shell/browser/shell_browser_main_parts.h b/apps/shell/browser/shell_browser_main_parts.h
index 8ae3fe4..4bc18b2 100644
--- a/apps/shell/browser/shell_browser_main_parts.h
+++ b/apps/shell/browser/shell_browser_main_parts.h
@@ -37,6 +37,10 @@
 class ShellDesktopController;
 class ShellExtensionsClient;
 
+#if defined(OS_CHROMEOS)
+class ShellNetworkController;
+#endif
+
 // Handles initialization of AppShell.
 class ShellBrowserMainParts : public content::BrowserMainParts,
                               public aura::WindowTreeHostObserver {
@@ -70,6 +74,9 @@
   // Creates and initializes the ExtensionSystem.
   void CreateExtensionSystem();
 
+#if defined(OS_CHROMEOS)
+  scoped_ptr<ShellNetworkController> network_controller_;
+#endif
   scoped_ptr<ShellDesktopController> desktop_controller_;
   scoped_ptr<ShellBrowserContext> browser_context_;
   scoped_ptr<ShellExtensionsClient> extensions_client_;
diff --git a/apps/shell/browser/shell_extension_system.cc b/apps/shell/browser/shell_extension_system.cc
index f6a3b85..fffba35 100644
--- a/apps/shell/browser/shell_extension_system.cc
+++ b/apps/shell/browser/shell_extension_system.cc
@@ -170,4 +170,8 @@
   return ready_;
 }
 
+ContentVerifier* ShellExtensionSystem::content_verifier() {
+  return NULL;
+}
+
 }  // namespace extensions
diff --git a/apps/shell/browser/shell_extension_system.h b/apps/shell/browser/shell_extension_system.h
index 7f39211..a287d2d 100644
--- a/apps/shell/browser/shell_extension_system.h
+++ b/apps/shell/browser/shell_extension_system.h
@@ -67,6 +67,7 @@
       const std::string& extension_id,
       const UnloadedExtensionInfo::Reason reason) OVERRIDE;
   virtual const OneShotEvent& ready() const OVERRIDE;
+  virtual ContentVerifier* content_verifier() OVERRIDE;
 
  private:
   content::BrowserContext* browser_context_;  // Not owned.
diff --git a/apps/shell/browser/shell_extensions_browser_client.cc b/apps/shell/browser/shell_extensions_browser_client.cc
index 769350c..343f6b5 100644
--- a/apps/shell/browser/shell_extensions_browser_client.cc
+++ b/apps/shell/browser/shell_extensions_browser_client.cc
@@ -7,11 +7,11 @@
 #include "apps/shell/browser/shell_app_sorting.h"
 #include "apps/shell/browser/shell_extension_system_factory.h"
 #include "apps/shell/browser/shell_extension_web_contents_observer.h"
+#include "apps/shell/browser/shell_runtime_api_delegate.h"
 #include "apps/shell/common/api/generated_api.h"
 #include "base/prefs/pref_service.h"
 #include "base/prefs/pref_service_factory.h"
 #include "base/prefs/testing_pref_store.h"
-#include "chrome/common/extensions/api/generated_api.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "components/user_prefs/user_prefs.h"
 #include "extensions/browser/api/extensions_api_client.h"
@@ -227,12 +227,14 @@
   // Register core extension-system APIs.
   extensions::core_api::GeneratedFunctionRegistry::RegisterAll(registry);
 
-  // TODO(rockot): Remove dependency on src/chrome once we have some core APIs
-  // moved out. Also clean up the comment below. See http://crbug.com/349042.
-  extensions::api::GeneratedFunctionRegistry::RegisterAll(registry);
-
   // Register chrome.shell APIs.
   apps::shell_api::GeneratedFunctionRegistry::RegisterAll(registry);
 }
 
+scoped_ptr<RuntimeAPIDelegate>
+ShellExtensionsBrowserClient::CreateRuntimeAPIDelegate(
+    content::BrowserContext* context) const {
+  return scoped_ptr<RuntimeAPIDelegate>(new apps::ShellRuntimeAPIDelegate());
+}
+
 }  // namespace extensions
diff --git a/apps/shell/browser/shell_extensions_browser_client.h b/apps/shell/browser/shell_extensions_browser_client.h
index 0862dd5..67e937d 100644
--- a/apps/shell/browser/shell_extensions_browser_client.h
+++ b/apps/shell/browser/shell_extensions_browser_client.h
@@ -73,6 +73,8 @@
   virtual ExtensionSystemProvider* GetExtensionSystemFactory() OVERRIDE;
   virtual void RegisterExtensionFunctions(
       ExtensionFunctionRegistry* registry) const OVERRIDE;
+  virtual scoped_ptr<RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
+      content::BrowserContext* context) const OVERRIDE;
 
  private:
   // The single BrowserContext for app_shell. Not owned.
diff --git a/apps/shell/browser/shell_network_controller_chromeos.cc b/apps/shell/browser/shell_network_controller_chromeos.cc
new file mode 100644
index 0000000..fd7fd42
--- /dev/null
+++ b/apps/shell/browser/shell_network_controller_chromeos.cc
@@ -0,0 +1,168 @@
+// 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.
+
+#include "apps/shell/browser/shell_network_controller_chromeos.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/strings/stringprintf.h"
+#include "base/time/time.h"
+#include "chromeos/network/network_connection_handler.h"
+#include "chromeos/network/network_handler.h"
+#include "chromeos/network/network_handler_callbacks.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/shill_property_util.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace apps {
+
+namespace {
+
+// Frequency at which networks should be scanned when not connected.
+const int kScanIntervalSec = 10;
+
+void HandleEnableWifiError(
+    const std::string& error_name,
+    scoped_ptr<base::DictionaryValue> error_data) {
+  LOG(WARNING) << "Unable to enable wifi: " << error_name;
+}
+
+// Returns a human-readable name for the network described by |state|.
+std::string GetNetworkName(const chromeos::NetworkState& state) {
+  return !state.name().empty() ? state.name() :
+      base::StringPrintf("[%s]", state.type().c_str());
+}
+
+// Returns true if shill is either connected or connecting to a network.
+bool IsConnectedOrConnecting() {
+  chromeos::NetworkStateHandler* state_handler =
+      chromeos::NetworkHandler::Get()->network_state_handler();
+  return state_handler->ConnectedNetworkByType(
+             chromeos::NetworkTypePattern::Default()) ||
+         state_handler->ConnectingNetworkByType(
+             chromeos::NetworkTypePattern::Default());
+}
+
+}  // namespace
+
+ShellNetworkController::ShellNetworkController()
+    : waiting_for_connection_result_(false),
+      weak_ptr_factory_(this) {
+  chromeos::NetworkHandler::Initialize();
+  chromeos::NetworkStateHandler* state_handler =
+      chromeos::NetworkHandler::Get()->network_state_handler();
+  DCHECK(state_handler);
+  state_handler->AddObserver(this, FROM_HERE);
+  state_handler->SetTechnologyEnabled(
+      chromeos::NetworkTypePattern::Primitive(shill::kTypeWifi),
+      true, base::Bind(&HandleEnableWifiError));
+
+  if (!IsConnectedOrConnecting()) {
+    RequestScan();
+    SetScanningEnabled(true);
+    ConnectIfUnconnected();
+  }
+}
+
+ShellNetworkController::~ShellNetworkController() {
+  chromeos::NetworkHandler::Get()->network_state_handler()->RemoveObserver(
+      this, FROM_HERE);
+  chromeos::NetworkHandler::Shutdown();
+}
+
+void ShellNetworkController::NetworkListChanged() {
+  VLOG(1) << "Network list changed";
+  ConnectIfUnconnected();
+}
+
+void ShellNetworkController::DefaultNetworkChanged(
+    const chromeos::NetworkState* state) {
+  if (state) {
+    VLOG(1) << "Default network state changed:"
+            << " name=" << GetNetworkName(*state)
+            << " path=" << state->path()
+            << " state=" << state->connection_state();
+  } else {
+    VLOG(1) << "Default network state changed: [no network]";
+  }
+
+  if (IsConnectedOrConnecting()) {
+    SetScanningEnabled(false);
+  } else {
+    SetScanningEnabled(true);
+    ConnectIfUnconnected();
+  }
+}
+
+void ShellNetworkController::SetScanningEnabled(bool enabled) {
+  const bool currently_enabled = scan_timer_.IsRunning();
+  if (enabled == currently_enabled)
+    return;
+
+  VLOG(1) << (enabled ? "Starting" : "Stopping") << " scanning";
+  if (enabled) {
+    scan_timer_.Start(FROM_HERE,
+                      base::TimeDelta::FromSeconds(kScanIntervalSec),
+                      this, &ShellNetworkController::RequestScan);
+  } else {
+    scan_timer_.Stop();
+  }
+}
+
+void ShellNetworkController::RequestScan() {
+  VLOG(1) << "Requesting scan";
+  chromeos::NetworkHandler::Get()->network_state_handler()->RequestScan();
+}
+
+// Attempts to connect to an available network if not already connecting or
+// connected.
+void ShellNetworkController::ConnectIfUnconnected() {
+  chromeos::NetworkHandler* handler = chromeos::NetworkHandler::Get();
+  DCHECK(handler);
+  if (waiting_for_connection_result_ || IsConnectedOrConnecting())
+    return;
+
+  chromeos::NetworkStateHandler::NetworkStateList state_list;
+  handler->network_state_handler()->GetNetworkListByType(
+      chromeos::NetworkTypePattern::WiFi(), &state_list);
+  for (chromeos::NetworkStateHandler::NetworkStateList::const_iterator it =
+       state_list.begin(); it != state_list.end(); ++it) {
+    const chromeos::NetworkState* state = *it;
+    DCHECK(state);
+    if (!state->connectable())
+      continue;
+
+    VLOG(1) << "Connecting to network " << GetNetworkName(*state)
+            << " with path " << state->path() << " and strength "
+            << state->signal_strength();
+    waiting_for_connection_result_ = true;
+    handler->network_connection_handler()->ConnectToNetwork(
+        state->path(),
+        base::Bind(&ShellNetworkController::HandleConnectionSuccess,
+                   weak_ptr_factory_.GetWeakPtr()),
+        base::Bind(&ShellNetworkController::HandleConnectionError,
+                   weak_ptr_factory_.GetWeakPtr()),
+        false /* check_error_state */);
+
+    return;
+  }
+
+  VLOG(1) << "Didn't find any connectable networks";
+}
+
+void ShellNetworkController::HandleConnectionSuccess() {
+  VLOG(1) << "Successfully connected to network";
+  waiting_for_connection_result_ = false;
+}
+
+void ShellNetworkController::HandleConnectionError(
+    const std::string& error_name,
+    scoped_ptr<base::DictionaryValue> error_data) {
+  LOG(WARNING) << "Unable to connect to network: " << error_name;
+  waiting_for_connection_result_ = false;
+}
+
+}  // namespace apps
diff --git a/apps/shell/browser/shell_network_controller_chromeos.h b/apps/shell/browser/shell_network_controller_chromeos.h
new file mode 100644
index 0000000..41317e2
--- /dev/null
+++ b/apps/shell/browser/shell_network_controller_chromeos.h
@@ -0,0 +1,66 @@
+// 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.
+
+#ifndef APPS_SHELL_BROWSER_SHELL_NETWORK_CONTROLLER_CHROMEOS_H_
+#define APPS_SHELL_BROWSER_SHELL_NETWORK_CONTROLLER_CHROMEOS_H_
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/timer/timer.h"
+#include "base/values.h"
+#include "chromeos/network/network_state_handler_observer.h"
+
+namespace apps {
+
+// Handles network-related tasks for app_shell on Chrome OS.
+class ShellNetworkController : public chromeos::NetworkStateHandlerObserver {
+ public:
+  // This class must be instantiated after chromeos::DBusThreadManager and
+  // destroyed before it.
+  ShellNetworkController();
+  virtual ~ShellNetworkController();
+
+  // chromeos::NetworkStateHandlerObserver overrides:
+  virtual void NetworkListChanged() OVERRIDE;
+  virtual void DefaultNetworkChanged(
+      const chromeos::NetworkState* state) OVERRIDE;
+
+ private:
+  // Controls whether scanning is performed periodically.
+  void SetScanningEnabled(bool enabled);
+
+  // Asks shill to scan for networks.
+  void RequestScan();
+
+  // If not currently connected or connecting, chooses a wireless network and
+  // asks shill to connect to it.
+  void ConnectIfUnconnected();
+
+  // Handles a successful or failed connection attempt.
+  void HandleConnectionSuccess();
+  void HandleConnectionError(
+      const std::string& error_name,
+      scoped_ptr<base::DictionaryValue> error_data);
+
+  // True when ConnectIfUnconnected() has asked shill to connect but the attempt
+  // hasn't succeeded or failed yet. This is tracked to avoid sending duplicate
+  // requests before chromeos::NetworkStateHandler has acknowledged the initial
+  // connection attempt.
+  bool waiting_for_connection_result_;
+
+  // Invokes RequestScan() periodically.
+  base::RepeatingTimer<ShellNetworkController> scan_timer_;
+
+  base::WeakPtrFactory<ShellNetworkController> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ShellNetworkController);
+};
+
+}  // namespace apps
+
+#endif  // APPS_SHELL_BROWSER_SHELL_NETWORK_CONTROLLER_CHROMEOS_H_
diff --git a/apps/shell/browser/shell_runtime_api_delegate.cc b/apps/shell/browser/shell_runtime_api_delegate.cc
new file mode 100644
index 0000000..fc475ba
--- /dev/null
+++ b/apps/shell/browser/shell_runtime_api_delegate.cc
@@ -0,0 +1,68 @@
+// 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.
+
+#include "apps/shell/browser/shell_runtime_api_delegate.h"
+
+#include "extensions/common/api/runtime.h"
+
+#if defined(OS_CHROMEOS)
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/power_manager_client.h"
+#endif
+
+using extensions::core_api::runtime::PlatformInfo;
+
+namespace apps {
+
+ShellRuntimeAPIDelegate::ShellRuntimeAPIDelegate() {
+}
+
+ShellRuntimeAPIDelegate::~ShellRuntimeAPIDelegate() {
+}
+
+void ShellRuntimeAPIDelegate::AddUpdateObserver(
+    extensions::UpdateObserver* observer) {
+}
+
+void ShellRuntimeAPIDelegate::RemoveUpdateObserver(
+    extensions::UpdateObserver* observer) {
+}
+
+base::Version ShellRuntimeAPIDelegate::GetPreviousExtensionVersion(
+    const extensions::Extension* extension) {
+  return base::Version();
+}
+
+void ShellRuntimeAPIDelegate::ReloadExtension(const std::string& extension_id) {
+}
+
+bool ShellRuntimeAPIDelegate::CheckForUpdates(
+    const std::string& extension_id,
+    const UpdateCheckCallback& callback) {
+  return false;
+}
+
+void ShellRuntimeAPIDelegate::OpenURL(const GURL& uninstall_url) {
+}
+
+bool ShellRuntimeAPIDelegate::GetPlatformInfo(PlatformInfo* info) {
+#if defined(OS_CHROMEOS)
+  info->os = PlatformInfo::OS_CROS_;
+#elif defined(OS_LINUX)
+  info->os = PlatformInfo::OS_LINUX_;
+#endif
+  return true;
+}
+
+bool ShellRuntimeAPIDelegate::RestartDevice(std::string* error_message) {
+// We allow chrome.runtime.restart() to request a device restart on ChromeOS.
+#if defined(OS_CHROMEOS)
+  chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
+  return true;
+#endif
+  *error_message = "Restart is only supported on ChromeOS.";
+  return false;
+}
+
+}  // namespace apps
diff --git a/apps/shell/browser/shell_runtime_api_delegate.h b/apps/shell/browser/shell_runtime_api_delegate.h
new file mode 100644
index 0000000..fcef1b7
--- /dev/null
+++ b/apps/shell/browser/shell_runtime_api_delegate.h
@@ -0,0 +1,38 @@
+// 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.
+
+#ifndef APPS_SHELL_BROWSER_SHELL_RUNTIME_API_DELEGATE_H_
+#define APPS_SHELL_BROWSER_SHELL_RUNTIME_API_DELEGATE_H_
+
+#include "base/macros.h"
+#include "extensions/browser/api/runtime/runtime_api_delegate.h"
+
+namespace apps {
+
+class ShellRuntimeAPIDelegate : public extensions::RuntimeAPIDelegate {
+ public:
+  ShellRuntimeAPIDelegate();
+  virtual ~ShellRuntimeAPIDelegate();
+
+  // extensions::RuntimeAPIDelegate implementation.
+  virtual void AddUpdateObserver(extensions::UpdateObserver* observer) OVERRIDE;
+  virtual void RemoveUpdateObserver(
+      extensions::UpdateObserver* observer) OVERRIDE;
+  virtual base::Version GetPreviousExtensionVersion(
+      const extensions::Extension* extension) OVERRIDE;
+  virtual void ReloadExtension(const std::string& extension_id) OVERRIDE;
+  virtual bool CheckForUpdates(const std::string& extension_id,
+                               const UpdateCheckCallback& callback) OVERRIDE;
+  virtual void OpenURL(const GURL& uninstall_url) OVERRIDE;
+  virtual bool GetPlatformInfo(
+      extensions::core_api::runtime::PlatformInfo* info) OVERRIDE;
+  virtual bool RestartDevice(std::string* error_message) OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ShellRuntimeAPIDelegate);
+};
+
+}  // namespace apps
+
+#endif  // APPS_SHELL_BROWSER_SHELL_RUNTIME_API_DELEGATE_H_
diff --git a/apps/shell/common/api/_api_features.json b/apps/shell/common/api/_api_features.json
new file mode 100644
index 0000000..9571ca8
--- /dev/null
+++ b/apps/shell/common/api/_api_features.json
@@ -0,0 +1,18 @@
+// 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.
+
+// This features file defines extension APIs implemented under src/apps/shell.
+// See extensions/common/features/* to understand this file, in particular
+// feature.h, simple_feature.h, and base_feature_provider.h.
+//
+// Note that specifying "web_page", "blessed_web_page", or "all" as a context
+// type will require manually updating chrome/renderer/resources/dispatcher.cc.
+
+{
+  "shell": {
+    "channel": "dev",
+    "contexts": ["blessed_extension"],
+    "extension_types": ["platform_app"]
+  }
+}
diff --git a/apps/shell/common/shell_extensions_client.cc b/apps/shell/common/shell_extensions_client.cc
index 4d08fc6..fe01ea3 100644
--- a/apps/shell/common/shell_extensions_client.cc
+++ b/apps/shell/common/shell_extensions_client.cc
@@ -5,9 +5,8 @@
 #include "apps/shell/common/shell_extensions_client.h"
 
 #include "apps/shell/common/api/generated_schemas.h"
+#include "base/lazy_instance.h"
 #include "base/logging.h"
-#include "chrome/common/extensions/api/generated_schemas.h"
-#include "chrome/common/extensions/permissions/chrome_api_permissions.h"
 #include "extensions/common/api/generated_schemas.h"
 #include "extensions/common/api/sockets/sockets_manifest_handler.h"
 #include "extensions/common/common_manifest_handlers.h"
@@ -19,9 +18,10 @@
 #include "extensions/common/features/simple_feature.h"
 #include "extensions/common/manifest_handler.h"
 #include "extensions/common/permissions/permission_message_provider.h"
+#include "extensions/common/permissions/permissions_info.h"
 #include "extensions/common/permissions/permissions_provider.h"
 #include "extensions/common/url_pattern_set.h"
-#include "grit/common_resources.h"
+#include "grit/app_shell_resources.h"
 #include "grit/extensions_resources.h"
 
 using extensions::APIPermissionInfo;
@@ -45,7 +45,7 @@
 }
 
 // TODO(jamescook): Refactor ChromePermissionsMessageProvider so we can share
-// code.
+// code. For now, this implementation does nothing.
 class ShellPermissionMessageProvider
     : public extensions::PermissionMessageProvider {
  public:
@@ -84,9 +84,13 @@
   DISALLOW_COPY_AND_ASSIGN(ShellPermissionMessageProvider);
 };
 
+base::LazyInstance<ShellPermissionMessageProvider>
+    g_permission_message_provider = LAZY_INSTANCE_INITIALIZER;
+
 }  // namespace
 
-ShellExtensionsClient::ShellExtensionsClient() {
+ShellExtensionsClient::ShellExtensionsClient()
+    : extensions_api_permissions_(extensions::ExtensionsAPIPermissions()) {
 }
 
 ShellExtensionsClient::~ShellExtensionsClient() {
@@ -102,49 +106,31 @@
 
   extensions::ManifestHandler::FinalizeRegistration();
   // TODO(jamescook): Do we need to whitelist any extensions?
-}
 
-const extensions::PermissionsProvider&
-ShellExtensionsClient::GetPermissionsProvider() const {
-  // TODO(jamescook): app_shell needs a way to use a subset of the Chrome
-  // extension Features and Permissions. In particular, the lists of Features
-  // (including API features, manifest features and permission features) are
-  // listed in JSON files from c/c/e/api that are included into Chrome's
-  // resources.pak (_api_features.json and _permission_features.json). The
-  // PermissionsProvider must match the set of permissions used by the features
-  // in those files.  We either need to make app_shell (and hence the extensions
-  // module) know about all possible permissions, or create a mechanism whereby
-  // we can build our own JSON files with only a subset of the data. For now,
-  // just provide all permissions Chrome knows about. Fixing this issue is
-  // http://crbug.com/339301
-  static extensions::ChromeAPIPermissions provider;
-  return provider;
+  extensions::PermissionsInfo::GetInstance()->AddProvider(
+      extensions_api_permissions_);
 }
 
 const extensions::PermissionMessageProvider&
 ShellExtensionsClient::GetPermissionMessageProvider() const {
   NOTIMPLEMENTED();
-  static ShellPermissionMessageProvider provider;
-  return provider;
+  return g_permission_message_provider.Get();
 }
 
 scoped_ptr<FeatureProvider> ShellExtensionsClient::CreateFeatureProvider(
     const std::string& name) const {
   extensions::JSONFeatureProviderSource source(name);
   if (name == "api") {
-    // TODO(yoz): Only include src/extensions resources.
     source.LoadJSON(IDR_EXTENSION_API_FEATURES);
-    source.LoadJSON(IDR_CHROME_EXTENSION_API_FEATURES);
+    source.LoadJSON(IDR_SHELL_EXTENSION_API_FEATURES);
     return scoped_ptr<FeatureProvider>(new BaseFeatureProvider(
         source.dictionary(), CreateFeature<extensions::APIFeature>));
   } else if (name == "manifest") {
     source.LoadJSON(IDR_EXTENSION_MANIFEST_FEATURES);
-    source.LoadJSON(IDR_CHROME_EXTENSION_MANIFEST_FEATURES);
     return scoped_ptr<FeatureProvider>(new BaseFeatureProvider(
         source.dictionary(), CreateFeature<extensions::ManifestFeature>));
   } else if (name == "permission") {
     source.LoadJSON(IDR_EXTENSION_PERMISSION_FEATURES);
-    source.LoadJSON(IDR_CHROME_EXTENSION_PERMISSION_FEATURES);
     return scoped_ptr<FeatureProvider>(new BaseFeatureProvider(
         source.dictionary(), CreateFeature<extensions::PermissionFeature>));
   } else {
@@ -190,18 +176,12 @@
   // moved out. See http://crbug.com/349042.
   // Special-case our simplified app.runtime implementation because we don't
   // have the Chrome app APIs available.
-  return extensions::api::GeneratedSchemas::IsGenerated(name) ||
-         extensions::core_api::GeneratedSchemas::IsGenerated(name) ||
+  return extensions::core_api::GeneratedSchemas::IsGenerated(name) ||
          apps::shell_api::GeneratedSchemas::IsGenerated(name);
 }
 
 base::StringPiece ShellExtensionsClient::GetAPISchema(
     const std::string& name) const {
-  // TODO(rockot): Remove dependency on src/chrome once we have some core APIs
-  // moved out. See http://crbug.com/349042.
-  if (extensions::api::GeneratedSchemas::IsGenerated(name))
-    return extensions::api::GeneratedSchemas::Get(name);
-
   // Schema for chrome.shell APIs.
   if (apps::shell_api::GeneratedSchemas::IsGenerated(name))
     return apps::shell_api::GeneratedSchemas::Get(name);
diff --git a/apps/shell/common/shell_extensions_client.h b/apps/shell/common/shell_extensions_client.h
index 79587c0..847b4a0 100644
--- a/apps/shell/common/shell_extensions_client.h
+++ b/apps/shell/common/shell_extensions_client.h
@@ -8,6 +8,7 @@
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "extensions/common/extensions_client.h"
+#include "extensions/common/permissions/extensions_api_permissions.h"
 
 namespace apps {
 
@@ -19,8 +20,6 @@
 
   // extensions::ExtensionsClient overrides:
   virtual void Initialize() OVERRIDE;
-  virtual const extensions::PermissionsProvider& GetPermissionsProvider() const
-      OVERRIDE;
   virtual const extensions::PermissionMessageProvider&
       GetPermissionMessageProvider() const OVERRIDE;
   virtual scoped_ptr<extensions::FeatureProvider> CreateFeatureProvider(
@@ -43,6 +42,8 @@
   virtual bool ShouldSuppressFatalErrors() const OVERRIDE;
 
  private:
+  const extensions::ExtensionsAPIPermissions extensions_api_permissions_;
+
   ScriptingWhitelist scripting_whitelist_;
 
   DISALLOW_COPY_AND_ASSIGN(ShellExtensionsClient);
diff --git a/apps/shell/renderer/shell_content_renderer_client.cc b/apps/shell/renderer/shell_content_renderer_client.cc
index 8c4befd..e0217fd 100644
--- a/apps/shell/renderer/shell_content_renderer_client.cc
+++ b/apps/shell/renderer/shell_content_renderer_client.cc
@@ -5,14 +5,15 @@
 #include "apps/shell/renderer/shell_content_renderer_client.h"
 
 #include "apps/shell/common/shell_extensions_client.h"
+#include "apps/shell/renderer/shell_dispatcher_delegate.h"
 #include "apps/shell/renderer/shell_extensions_renderer_client.h"
-#include "chrome/renderer/extensions/dispatcher.h"
-#include "chrome/renderer/extensions/extension_helper.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_frame_observer.h"
 #include "content/public/renderer/render_frame_observer_tracker.h"
 #include "content/public/renderer/render_thread.h"
 #include "extensions/common/extensions_client.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/extension_helper.h"
 
 using blink::WebFrame;
 using blink::WebString;
@@ -70,8 +71,11 @@
   extensions_renderer_client_.reset(new ShellExtensionsRendererClient);
   extensions::ExtensionsRendererClient::Set(extensions_renderer_client_.get());
 
+  extension_dispatcher_delegate_.reset(new ShellDispatcherDelegate());
+
   // Must be initialized after ExtensionsRendererClient.
-  extension_dispatcher_.reset(new extensions::Dispatcher());
+  extension_dispatcher_.reset(
+      new extensions::Dispatcher(extension_dispatcher_delegate_.get()));
   thread->AddObserver(extension_dispatcher_.get());
 
   // TODO(jamescook): Init WebSecurityPolicy for chrome-extension: schemes.
diff --git a/apps/shell/renderer/shell_content_renderer_client.h b/apps/shell/renderer/shell_content_renderer_client.h
index 4a34810..506704c 100644
--- a/apps/shell/renderer/shell_content_renderer_client.h
+++ b/apps/shell/renderer/shell_content_renderer_client.h
@@ -12,6 +12,7 @@
 
 namespace extensions {
 class Dispatcher;
+class DispatcherDelegate;
 }
 
 namespace apps {
@@ -43,6 +44,7 @@
  private:
   scoped_ptr<ShellExtensionsClient> extensions_client_;
   scoped_ptr<ShellExtensionsRendererClient> extensions_renderer_client_;
+  scoped_ptr<extensions::DispatcherDelegate> extension_dispatcher_delegate_;
   scoped_ptr<extensions::Dispatcher> extension_dispatcher_;
 
   DISALLOW_COPY_AND_ASSIGN(ShellContentRendererClient);
diff --git a/apps/shell/renderer/shell_dispatcher_delegate.cc b/apps/shell/renderer/shell_dispatcher_delegate.cc
new file mode 100644
index 0000000..7959a5c
--- /dev/null
+++ b/apps/shell/renderer/shell_dispatcher_delegate.cc
@@ -0,0 +1,35 @@
+// 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.
+
+#include "apps/shell/renderer/shell_dispatcher_delegate.h"
+
+#include "apps/shell/renderer/shell_custom_bindings.h"
+#include "extensions/renderer/module_system.h"
+#include "extensions/renderer/resource_bundle_source_map.h"
+#include "extensions/renderer/script_context.h"
+#include "grit/app_shell_resources.h"
+
+namespace apps {
+
+ShellDispatcherDelegate::ShellDispatcherDelegate() {
+}
+
+ShellDispatcherDelegate::~ShellDispatcherDelegate() {
+}
+
+void ShellDispatcherDelegate::RegisterNativeHandlers(
+    extensions::Dispatcher* dispatcher,
+    extensions::ModuleSystem* module_system,
+    extensions::ScriptContext* context) {
+  module_system->RegisterNativeHandler(
+      "shell_natives",
+      scoped_ptr<extensions::NativeHandler>(new ShellCustomBindings(context)));
+}
+
+void ShellDispatcherDelegate::PopulateSourceMap(
+    extensions::ResourceBundleSourceMap* source_map) {
+  source_map->RegisterSource("shell", IDR_SHELL_CUSTOM_BINDINGS_JS);
+}
+
+}  // namespace apps
diff --git a/apps/shell/renderer/shell_dispatcher_delegate.h b/apps/shell/renderer/shell_dispatcher_delegate.h
new file mode 100644
index 0000000..0bbb8f3
--- /dev/null
+++ b/apps/shell/renderer/shell_dispatcher_delegate.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef APPS_SHELL_RENDERER_SHELL_DISPATCHER_DELEGATE_H_
+#define APPS_SHELL_RENDERER_SHELL_DISPATCHER_DELEGATE_H_
+
+#include "base/macros.h"
+#include "extensions/renderer/default_dispatcher_delegate.h"
+
+namespace apps {
+
+// app_shell's implementation of DispatcherDelegate. This inherits the behavior
+// of the default delegate while augmenting its own script resources and native
+// native handlers.
+class ShellDispatcherDelegate : public extensions::DefaultDispatcherDelegate {
+ public:
+  ShellDispatcherDelegate();
+  virtual ~ShellDispatcherDelegate();
+
+  // DispatcherDelegate implementation.
+  virtual void RegisterNativeHandlers(
+      extensions::Dispatcher* dispatcher,
+      extensions::ModuleSystem* module_system,
+      extensions::ScriptContext* context) OVERRIDE;
+  virtual void PopulateSourceMap(
+      extensions::ResourceBundleSourceMap* source_map) OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ShellDispatcherDelegate);
+};
+
+}  // namespace apps
+
+#endif  // APPS_SHELL_RENDERER_SHELL_DISPATCHER_DELEGATE_H_
diff --git a/apps/shell/renderer/shell_extensions_renderer_client.cc b/apps/shell/renderer/shell_extensions_renderer_client.cc
index 039a970..c5de265 100644
--- a/apps/shell/renderer/shell_extensions_renderer_client.cc
+++ b/apps/shell/renderer/shell_extensions_renderer_client.cc
@@ -4,12 +4,6 @@
 
 #include "apps/shell/renderer/shell_extensions_renderer_client.h"
 
-#include "apps/shell/renderer/shell_custom_bindings.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/renderer/resource_bundle_source_map.h"
-#include "extensions/renderer/module_system.h"
-#include "grit/app_shell_resources.h"
-
 namespace apps {
 
 ShellExtensionsRendererClient::ShellExtensionsRendererClient() {}
@@ -28,17 +22,4 @@
   return 1;
 }
 
-void ShellExtensionsRendererClient::RegisterNativeHandlers(
-    extensions::ModuleSystem* module_system,
-    extensions::ScriptContext* context) {
-  module_system->RegisterNativeHandler(
-      "shell_natives",
-      scoped_ptr<extensions::NativeHandler>(new ShellCustomBindings(context)));
-}
-
-void ShellExtensionsRendererClient::PopulateSourceMap(
-    ResourceBundleSourceMap* source_map) {
-  source_map->RegisterSource("shell", IDR_SHELL_CUSTOM_BINDINGS_JS);
-}
-
 }  // namespace apps
diff --git a/apps/shell/renderer/shell_extensions_renderer_client.h b/apps/shell/renderer/shell_extensions_renderer_client.h
index e67d875..7b32f90 100644
--- a/apps/shell/renderer/shell_extensions_renderer_client.h
+++ b/apps/shell/renderer/shell_extensions_renderer_client.h
@@ -19,10 +19,6 @@
   // extensions::ExtensionsRendererClient implementation.
   virtual bool IsIncognitoProcess() const OVERRIDE;
   virtual int GetLowestIsolatedWorldId() const OVERRIDE;
-  virtual void RegisterNativeHandlers(
-      extensions::ModuleSystem* module_system,
-      extensions::ScriptContext* context) OVERRIDE;
-  virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) OVERRIDE;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ShellExtensionsRendererClient);
diff --git a/apps/ui/views/native_app_window_views.cc b/apps/ui/views/native_app_window_views.cc
index 04e7d9f..22c384e 100644
--- a/apps/ui/views/native_app_window_views.cc
+++ b/apps/ui/views/native_app_window_views.cc
@@ -9,7 +9,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/common/draggable_region.h"
 #include "third_party/skia/include/core/SkRegion.h"
 #include "ui/gfx/path.h"
@@ -233,7 +232,7 @@
     gfx::NativeView child,
     const gfx::Point& location) {
 #if defined(USE_AURA)
-  if (child->Contains(web_view_->web_contents()->GetView()->GetNativeView())) {
+  if (child->Contains(web_view_->web_contents()->GetNativeView())) {
     // App window should claim mouse events that fall within the draggable
     // region.
     return !draggable_region_.get() ||
diff --git a/apps/ui/web_contents_sizer.cc b/apps/ui/web_contents_sizer.cc
index 041187f..ab4e18a 100644
--- a/apps/ui/web_contents_sizer.cc
+++ b/apps/ui/web_contents_sizer.cc
@@ -5,7 +5,6 @@
 #include "apps/ui/web_contents_sizer.h"
 
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 #if defined(USE_AURA)
 #include "ui/aura/window.h"
@@ -18,7 +17,7 @@
 void ResizeWebContents(content::WebContents* web_contents,
                        const gfx::Size& new_size) {
 #if defined(USE_AURA)
-  aura::Window* window = web_contents->GetView()->GetNativeView();
+  aura::Window* window = web_contents->GetNativeView();
   window->SetBounds(gfx::Rect(window->bounds().origin(), new_size));
 #elif defined(OS_ANDROID)
   content::RenderWidgetHostView* view = web_contents->GetRenderWidgetHostView();
diff --git a/apps/ui/web_contents_sizer.mm b/apps/ui/web_contents_sizer.mm
index 8dd7cbd..f57d75c 100644
--- a/apps/ui/web_contents_sizer.mm
+++ b/apps/ui/web_contents_sizer.mm
@@ -7,13 +7,12 @@
 #import <Cocoa/Cocoa.h>
 
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 namespace apps {
 
 void ResizeWebContents(content::WebContents* web_contents,
                        const gfx::Size& new_size) {
-  NSView* view = web_contents->GetView()->GetNativeView();
+  NSView* view = web_contents->GetNativeView();
   NSRect old_wcv_frame = [view frame];
   CGFloat new_x = old_wcv_frame.origin.x;
   CGFloat new_y =
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc
index 93277ea..dbdc9e1 100644
--- a/ash/accelerators/accelerator_controller_unittest.cc
+++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "ash/accelerators/accelerator_controller.h"
+
 #include "ash/accelerators/accelerator_table.h"
 #include "ash/accessibility_delegate.h"
 #include "ash/ash_switches.h"
@@ -18,6 +19,7 @@
 #include "ash/test/display_manager_test_api.h"
 #include "ash/test/test_screenshot_delegate.h"
 #include "ash/test/test_shell_delegate.h"
+#include "ash/test/test_volume_control_delegate.h"
 #include "ash/volume_control_delegate.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_util.h"
@@ -69,55 +71,6 @@
   }
 };
 
-class DummyVolumeControlDelegate : public VolumeControlDelegate {
- public:
-  explicit DummyVolumeControlDelegate(bool consume)
-      : consume_(consume),
-        handle_volume_mute_count_(0),
-        handle_volume_down_count_(0),
-        handle_volume_up_count_(0) {
-  }
-  virtual ~DummyVolumeControlDelegate() {}
-
-  virtual bool HandleVolumeMute(const ui::Accelerator& accelerator) OVERRIDE {
-    ++handle_volume_mute_count_;
-    last_accelerator_ = accelerator;
-    return consume_;
-  }
-  virtual bool HandleVolumeDown(const ui::Accelerator& accelerator) OVERRIDE {
-    ++handle_volume_down_count_;
-    last_accelerator_ = accelerator;
-    return consume_;
-  }
-  virtual bool HandleVolumeUp(const ui::Accelerator& accelerator) OVERRIDE {
-    ++handle_volume_up_count_;
-    last_accelerator_ = accelerator;
-    return consume_;
-  }
-
-  int handle_volume_mute_count() const {
-    return handle_volume_mute_count_;
-  }
-  int handle_volume_down_count() const {
-    return handle_volume_down_count_;
-  }
-  int handle_volume_up_count() const {
-    return handle_volume_up_count_;
-  }
-  const ui::Accelerator& last_accelerator() const {
-    return last_accelerator_;
-  }
-
- private:
-  const bool consume_;
-  int handle_volume_mute_count_;
-  int handle_volume_down_count_;
-  int handle_volume_up_count_;
-  ui::Accelerator last_accelerator_;
-
-  DISALLOW_COPY_AND_ASSIGN(DummyVolumeControlDelegate);
-};
-
 class DummyBrightnessControlDelegate : public BrightnessControlDelegate {
  public:
   explicit DummyBrightnessControlDelegate(bool consume)
@@ -714,8 +667,8 @@
   const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
   const ui::Accelerator volume_up(ui::VKEY_VOLUME_UP, ui::EF_NONE);
   {
-    DummyVolumeControlDelegate* delegate =
-        new DummyVolumeControlDelegate(false);
+    TestVolumeControlDelegate* delegate =
+        new TestVolumeControlDelegate(false);
     ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
         scoped_ptr<VolumeControlDelegate>(delegate).Pass());
     EXPECT_EQ(0, delegate->handle_volume_mute_count());
@@ -732,7 +685,7 @@
     EXPECT_EQ(volume_up, delegate->last_accelerator());
   }
   {
-    DummyVolumeControlDelegate* delegate = new DummyVolumeControlDelegate(true);
+    TestVolumeControlDelegate* delegate = new TestVolumeControlDelegate(true);
     ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
         scoped_ptr<VolumeControlDelegate>(delegate).Pass());
     EXPECT_EQ(0, delegate->handle_volume_mute_count());
@@ -1190,8 +1143,8 @@
     EXPECT_TRUE(ProcessWithContext(volume_mute));
     EXPECT_TRUE(ProcessWithContext(volume_down));
     EXPECT_TRUE(ProcessWithContext(volume_up));
-    DummyVolumeControlDelegate* delegate =
-        new DummyVolumeControlDelegate(false);
+    TestVolumeControlDelegate* delegate =
+        new TestVolumeControlDelegate(false);
     ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
         scoped_ptr<VolumeControlDelegate>(delegate).Pass());
     EXPECT_EQ(0, delegate->handle_volume_mute_count());
@@ -1208,7 +1161,7 @@
     EXPECT_EQ(volume_up, delegate->last_accelerator());
   }
   {
-    DummyVolumeControlDelegate* delegate = new DummyVolumeControlDelegate(true);
+    TestVolumeControlDelegate* delegate = new TestVolumeControlDelegate(true);
     ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
         scoped_ptr<VolumeControlDelegate>(delegate).Pass());
     EXPECT_EQ(0, delegate->handle_volume_mute_count());
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc
index 10b568c..51b6324 100644
--- a/ash/accelerators/accelerator_table.cc
+++ b/ash/accelerators/accelerator_table.cc
@@ -329,6 +329,10 @@
   POWER_RELEASED,
   PREVIOUS_IME,
   PRINT_UI_HIERARCHIES,
+  ROTATE_SCREEN,
+  SCALE_UI_UP,
+  SCALE_UI_DOWN,
+  SCALE_UI_RESET,
   SHOW_KEYBOARD_OVERLAY,
   SWITCH_IME,
   TAKE_PARTIAL_SCREENSHOT,
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 8c9cfdf..1b8212a 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -161,23 +161,14 @@
         'first_run/first_run_helper_impl.h',
         'focus_cycler.cc',
         'focus_cycler.h',
-        'frame/caption_buttons/alternate_frame_size_button.cc',
-        'frame/caption_buttons/alternate_frame_size_button.h',
-        'frame/caption_buttons/alternate_frame_size_button_delegate.h',
-        'frame/caption_buttons/bubble_contents_button_row.cc',
-        'frame/caption_buttons/bubble_contents_button_row.h',
         'frame/caption_buttons/caption_button_types.h',
         'frame/caption_buttons/frame_caption_button.cc',
         'frame/caption_buttons/frame_caption_button.h',
         'frame/caption_buttons/frame_caption_button_container_view.cc',
         'frame/caption_buttons/frame_caption_button_container_view.h',
-        'frame/caption_buttons/frame_maximize_button.cc',
-        'frame/caption_buttons/frame_maximize_button.h',
-        'frame/caption_buttons/frame_maximize_button_observer.h',
-        'frame/caption_buttons/maximize_bubble_controller.cc',
-        'frame/caption_buttons/maximize_bubble_controller.h',
-        'frame/caption_buttons/maximize_bubble_controller_bubble.cc',
-        'frame/caption_buttons/maximize_bubble_controller_bubble.h',
+        'frame/caption_buttons/frame_size_button.cc',
+        'frame/caption_buttons/frame_size_button.h',
+        'frame/caption_buttons/frame_size_button_delegate.h',
         'frame/custom_frame_view_ash.cc',
         'frame/custom_frame_view_ash.h',
         'frame/frame_border_hit_test_controller.cc',
@@ -325,21 +316,21 @@
         'system/chromeos/audio/tray_audio_chromeos.h',
         'system/chromeos/audio/tray_audio_delegate_chromeos.cc',
         'system/chromeos/audio/tray_audio_delegate_chromeos.h',
-        'system/chromeos/enterprise/enterprise_domain_observer.h',
         'system/chromeos/bluetooth/bluetooth_notification_controller.cc',
         'system/chromeos/bluetooth/bluetooth_notification_controller.h',
         'system/chromeos/brightness/brightness_controller_chromeos.cc',
         'system/chromeos/brightness/brightness_controller_chromeos.h',
         'system/chromeos/brightness/tray_brightness.cc',
         'system/chromeos/brightness/tray_brightness.h',
-        'system/chromeos/enterprise/tray_enterprise.h',
+        'system/chromeos/enterprise/enterprise_domain_observer.h',
         'system/chromeos/enterprise/tray_enterprise.cc',
+        'system/chromeos/enterprise/tray_enterprise.h',
         'system/chromeos/keyboard_brightness_controller.cc',
         'system/chromeos/keyboard_brightness_controller.h',
-        'system/chromeos/label_tray_view.h',
         'system/chromeos/label_tray_view.cc',
-        'system/chromeos/managed/tray_locally_managed_user.h',
+        'system/chromeos/label_tray_view.h',
         'system/chromeos/managed/tray_locally_managed_user.cc',
+        'system/chromeos/managed/tray_locally_managed_user.h',
         'system/chromeos/network/network_connect.cc',
         'system/chromeos/network/network_connect.h',
         'system/chromeos/network/network_detailed_view.h',
@@ -441,6 +432,9 @@
         'system/tray/fixed_sized_scroll_view.h',
         'system/tray/hover_highlight_view.cc',
         'system/tray/hover_highlight_view.h',
+        'system/tray/media_security/media_capture_observer.h',
+        'system/tray/media_security/multi_profile_media_tray_item.cc',
+        'system/tray/media_security/multi_profile_media_tray_item.h',
         'system/tray/special_popup_row.cc',
         'system/tray/special_popup_row.h',
         'system/tray/system_tray.cc',
@@ -677,7 +671,6 @@
         'wm/workspace/multi_window_resize_controller.h',
         'wm/workspace/phantom_window_controller.cc',
         'wm/workspace/phantom_window_controller.h',
-        'wm/workspace/snap_types.h',
         'wm/workspace/two_step_edge_cycler.cc',
         'wm/workspace/two_step_edge_cycler.h',
         'wm/workspace/workspace_event_handler.cc',
@@ -729,6 +722,9 @@
             ['exclude', 'display/display_configurator_animation.h'],
             ['exclude', 'display/resolution_notification_controller.cc'],
             ['exclude', 'display/resolution_notification_controller.h'],
+	    ['exclude', 'system/tray/media_security/media_capture_observer.h'],
+	    ['exclude', 'system/tray/media_security/multi_profile_media_tray_item.cc'],
+	    ['exclude', 'system/tray/media_security/multi_profile_media_tray_item.h'],
           ],
         }],
       ],
@@ -836,6 +832,8 @@
         'test/test_system_tray_delegate.h',
         'test/test_user_wallpaper_delegate.cc',
         'test/test_user_wallpaper_delegate.h',
+        'test/test_volume_control_delegate.cc',
+        'test/test_volume_control_delegate.h',
         'test/ui_controls_factory_ash.cc',
         'test/ui_controls_factory_ash.h',
       ],
@@ -878,6 +876,7 @@
         '../ui/compositor/compositor.gyp:compositor_test_support',
         '../ui/events/events.gyp:events',
         '../ui/events/events.gyp:events_test_support',
+        '../ui/events/events.gyp:gesture_detection',
         '../ui/gfx/gfx.gyp:gfx',
         '../ui/gfx/gfx.gyp:gfx_geometry',
         '../ui/keyboard/keyboard.gyp:keyboard',
@@ -924,9 +923,8 @@
         'drag_drop/drag_drop_tracker_unittest.cc',
         'extended_desktop_unittest.cc',
         'focus_cycler_unittest.cc',
-        'frame/caption_buttons/alternate_frame_size_button_unittest.cc',
-        'frame/caption_buttons/frame_caption_button_container_view_unittest.cc',
-        'frame/caption_buttons/frame_maximize_button_unittest.cc',
+        'frame/caption_buttons/frame_caption_button_container_view_unittest.cc', 
+        'frame/caption_buttons/frame_size_button_unittest.cc',
         'frame/custom_frame_view_ash_unittest.cc',
         'frame/default_header_painter_unittest.cc',
         'host/ash_window_tree_host_x11_unittest.cc',
@@ -966,6 +964,7 @@
         'system/chromeos/tray_display_unittest.cc',
         'system/date/date_view_unittest.cc',
         'system/overview/overview_button_tray_unittest.cc',
+        'system/tray/media_security/multi_profile_media_tray_item_unittest.cc',
         'system/tray/system_tray_unittest.cc',
         'system/tray/tray_details_view_unittest.cc',
         'system/user/tray_user_unittest.cc',
@@ -1007,7 +1006,6 @@
         'wm/maximize_mode/workspace_backdrop_delegate.h',
         'wm/workspace/magnetism_matcher_unittest.cc',
         'wm/workspace/multi_window_resize_controller_unittest.cc',
-        'wm/workspace/phantom_window_controller_unittest.cc',
         'wm/workspace/workspace_event_handler_test_helper.cc',
         'wm/workspace/workspace_event_handler_test_helper.h',
         'wm/workspace/workspace_event_handler_unittest.cc',
@@ -1031,6 +1029,7 @@
             ['exclude', 'wm/workspace/workspace_window_resizer_unittest.cc'],
             ['exclude', 'sticky_keys/sticky_keys_overlay_unittest.cc'],
             ['exclude', 'sticky_keys/sticky_keys_unittest.cc'],
+	    ['exclude', 'system/tray/media_security/multi_profile_media_tray_item_unittest.cc'],
             ['exclude', 'autoclick/autoclick_unittest.cc'],
           ],
           'sources': [
@@ -1067,8 +1066,7 @@
             ['exclude', 'display/resolution_notification_controller_unittest.cc'],
           ],
         }],
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and component=="shared_library" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and component=="shared_library" and use_allocator!="none"', {
           'dependencies': [
             '<(DEPTH)/base/allocator/allocator.gyp:allocator',
           ],
@@ -1117,8 +1115,6 @@
       'sources': [
         '../content/app/startup_helper_win.cc',
         '../ui/views/test/test_views_delegate.cc',
-        'session/session_state_delegate_stub.cc',
-        'session/session_state_delegate_stub.h',
         'shell/app_list.cc',
         'shell/bubble.cc',
         'shell/content_client/shell_browser_main_parts.cc',
diff --git a/ash/ash_chromeos_strings.grdp b/ash/ash_chromeos_strings.grdp
index b0333ec..15a0fb7 100644
--- a/ash/ash_chromeos_strings.grdp
+++ b/ash/ash_chromeos_strings.grdp
@@ -305,6 +305,17 @@
     Stop
   </message>
 
+  <!-- Status tray media recording state strings. -->
+  <message name="IDS_ASH_STATUS_TRAY_MEDIA_RECORDING_AUDIO" desc="label used to indicate that the microphone is used by a background user">
+    Micropohne is in use.
+  </message>
+  <message name="IDS_ASH_STATUS_TRAY_MEDIA_RECORDING_VIDEO" desc="label used to indicate that the camera is used by a background user">
+    Camera is in use.
+  </message>
+  <message name="IDS_ASH_STATUS_TRAY_MEDIA_RECORDING_AUDIO_VIDEO" desc="label used to indicate that the camera and microphone are used by a background user">
+    Camera and microphone are in use.
+  </message>
+
   <!-- Status tray screen share strings. -->
   <message name="IDS_ASH_STATUS_TRAY_SCREEN_SHARE_STOP" desc="label used for screen sharing stop button">
     Stop
diff --git a/ash/ash_resources.gypi b/ash/ash_resources.gypi
index 5c2d62a..68d93ef 100644
--- a/ash/ash_resources.gypi
+++ b/ash/ash_resources.gypi
@@ -8,7 +8,7 @@
       'target_name': 'ash_resources',
       'type': 'none',
       'variables': {
-        'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/ash/ash_resources',
+        'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/ash/resources',
       },
       'actions': [
         {
@@ -19,11 +19,7 @@
           'includes': [ '../build/grit_action.gypi' ],
         },
       ],
-      'direct_dependent_settings': {
-        'include_dirs': [
-          '<(SHARED_INTERMEDIATE_DIR)/ash/ash_resources',
-        ],
-      },
+      'includes': [ '../build/grit_target.gypi' ],
     },
   ],
 }
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index 6a10965..07a6f3f 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -528,11 +528,11 @@
       </message>
 
       <message name="IDS_ASH_STATUS_TRAY_ROTATION_LOCK_AUTO" desc="The text shown in the tray menu when rotation is set to auto.">
-        Auto rotate
+        Rotation on (Tap here to change)
       </message>
 
       <message name="IDS_ASH_STATUS_TRAY_ROTATION_LOCK_LOCKED" desc="The text shown in the tray menu when rotation is set to locked.">
-        Rotation locked
+        Rotation locked (Tap here to change)
       </message>
 
       <message name="IDS_ASH_VIRTUAL_KEYBOARD_TRAY_ACCESSIBLE_NAME" desc="The accessible text for virtual keyboard icon in status tray.">
@@ -542,21 +542,6 @@
       <message name="IDS_ASH_NOTIFICATION_UNREAD_COUNT_NINE_PLUS" desc="The text shown in the notification icon for the unread count when the count is more than 9.">
         9+
       </message>
-      <message name="IDS_ASH_MAXIMIZE_WINDOW" desc="A help text to show that when the button gets clicked the window get maximized.">
-        Maximize
-      </message>
-      <message name="IDS_ASH_SNAP_WINDOW_RIGHT" desc="A help text to show that when the button gets clicked the window get snapped to the right side.">
-        Right
-      </message>
-      <message name="IDS_ASH_SNAP_WINDOW_LEFT" desc="A help text to show that when the button gets clicked the window get snapped to the left side.">
-        Left
-      </message>
-      <message name="IDS_ASH_RESTORE_WINDOW" desc="A help text to show that when the button gets clicked the window gets restored to its normal - non maximized - state.">
-        Restore
-      </message>
-      <message name="IDS_ASH_MINIMIZE_WINDOW" desc="A help text to show that when the button gets clicked the window gets minimized.">
-        Minimize
-      </message>
       <message name="IDS_ASH_DISPLAY_FAILURE_ON_MIRRORING" desc="An error message to show that the system failed to enter the mirroring mode.">
         Could not mirror displays since no supported resolutions found. Entered extended desktop instead.
       </message>
diff --git a/ash/ash_switches.cc b/ash/ash_switches.cc
index f6bfeda..acc29b1 100644
--- a/ash/ash_switches.cc
+++ b/ash/ash_switches.cc
@@ -38,20 +38,13 @@
 const char kAshDefaultWallpaperLarge[] = "ash-default-wallpaper-large";
 const char kAshDefaultWallpaperSmall[] = "ash-default-wallpaper-small";
 
-// Use the normal visual style for the caption buttons (minimize, maximize,
-// restore, close).
-const char kAshDisableAlternateFrameCaptionButtonStyle[] =
-    "ash-disable-alternate-caption-button";
-
 // Disable ability to dock windows at the desktop edge.
 const char kAshDisableDockedWindows[] = "ash-disable-docked-windows";
 
-// Use alternate visual style for the caption buttons (minimize, maximize,
-// restore, close). The alternate style:
-// - Adds a dedicated button for minimize.
-// - Removes the maximize button's help bubble.
-const char kAshEnableAlternateFrameCaptionButtonStyle[] =
-    "ash-enable-alternate-caption-button";
+// Enable the Touch Exploration Mode. Touch Exploration Mode will be turned on
+// automatically when spoken feedback is enabled when this flag is set.
+const char kAshEnableTouchExplorationMode[] =
+    "ash-enable-touch-exploration-mode";
 
 #if defined(OS_CHROMEOS)
 // Enables key bindings to scroll magnified screen.
@@ -117,11 +110,6 @@
 
 #endif
 
-bool UseAlternateFrameCaptionButtonStyle() {
-  return !CommandLine::ForCurrentProcess()->
-      HasSwitch(kAshDisableAlternateFrameCaptionButtonStyle);
-}
-
 bool UseDockedWindows() {
   return !CommandLine::ForCurrentProcess()->HasSwitch(kAshDisableDockedWindows);
 }
diff --git a/ash/ash_switches.h b/ash/ash_switches.h
index 1937440..e1be504 100644
--- a/ash/ash_switches.h
+++ b/ash/ash_switches.h
@@ -24,9 +24,8 @@
 ASH_EXPORT extern const char kAshDefaultWallpaperIsOem[];
 ASH_EXPORT extern const char kAshDefaultWallpaperLarge[];
 ASH_EXPORT extern const char kAshDefaultWallpaperSmall[];
-ASH_EXPORT extern const char kAshDisableAlternateFrameCaptionButtonStyle[];
 ASH_EXPORT extern const char kAshDisableDockedWindows[];
-ASH_EXPORT extern const char kAshEnableAlternateFrameCaptionButtonStyle[];
+ASH_EXPORT extern const char kAshEnableTouchExplorationMode[];
 #if defined(OS_CHROMEOS)
 ASH_EXPORT extern const char kAshEnableMagnifierKeyScroller[];
 #endif
@@ -46,10 +45,6 @@
 ASH_EXPORT extern const char kForceAshToDesktop[];
 #endif
 
-// Returns true if the alternate visual style for the caption buttons (minimize,
-// maximize, restore, close) should be used.
-ASH_EXPORT bool UseAlternateFrameCaptionButtonStyle();
-
 // Returns true if items can be dragged off the shelf to unpin.
 ASH_EXPORT bool UseDragOffShelf();
 
diff --git a/ash/ash_view_ids.h b/ash/ash_view_ids.h
new file mode 100644
index 0000000..61bf3cf
--- /dev/null
+++ b/ash/ash_view_ids.h
@@ -0,0 +1,18 @@
+// 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.
+
+#ifndef ASH_ASH_VIEW_IDS_H_
+#define ASH_ASH_VIEW_IDS_H_
+
+namespace ash {
+
+enum ViewID {
+  VIEW_ID_NONE = 10000,
+  VIEW_ID_MEDIA_TRAY_VIEW,
+  VIEW_ID_USER_VIEW_MEDIA_INDICATOR,
+};
+
+}  // namespace ash
+
+#endif  // ASH_ASH_VIEW_IDS_H_
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc
index 9ef0b9b..e08d793 100644
--- a/ash/drag_drop/drag_drop_controller_unittest.cc
+++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -24,6 +24,7 @@
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
 #include "ui/events/gestures/gesture_types.h"
+#include "ui/events/test/events_test_utils.h"
 #include "ui/gfx/animation/linear_animation.h"
 #include "ui/gfx/image/image_skia_rep.h"
 #include "ui/views/test/test_views_delegate.h"
@@ -282,8 +283,12 @@
       ui::EventTimeForNow(),
       ui::GestureEventDetails(gesture_type, 0, 0),
       1);
-  Shell::GetPrimaryRootWindow()->GetHost()->dispatcher()->DispatchGestureEvent(
-      &gesture_event);
+  ui::EventSource* event_source =
+      Shell::GetPrimaryRootWindow()->GetHost()->GetEventSource();
+  ui::EventSourceTestApi event_source_test(event_source);
+  ui::EventDispatchDetails details =
+      event_source_test.SendEventToProcessor(&gesture_event);
+  CHECK(!details.dispatcher_destroyed);
 }
 
 }  // namespace
diff --git a/ash/frame/caption_buttons/alternate_frame_size_button.cc b/ash/frame/caption_buttons/alternate_frame_size_button.cc
deleted file mode 100644
index 54799cb..0000000
--- a/ash/frame/caption_buttons/alternate_frame_size_button.cc
+++ /dev/null
@@ -1,284 +0,0 @@
-// Copyright 2013 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.
-
-#include "ash/frame/caption_buttons/alternate_frame_size_button.h"
-
-#include "ash/metrics/user_metrics_recorder.h"
-#include "ash/screen_util.h"
-#include "ash/shell.h"
-#include "ash/touch/touch_uma.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "ash/wm/wm_event.h"
-#include "ash/wm/workspace/phantom_window_controller.h"
-#include "base/i18n/rtl.h"
-#include "ui/gfx/vector2d.h"
-#include "ui/views/widget/widget.h"
-
-namespace {
-
-// The default delay between the user pressing the size button and the buttons
-// adjacent to the size button morphing into buttons for snapping left and
-// right.
-const int kSetButtonsToSnapModeDelayMs = 150;
-
-// The amount that a user can overshoot one of the caption buttons while in
-// "snap mode" and keep the button hovered/pressed.
-const int kMaxOvershootX = 200;
-const int kMaxOvershootY = 50;
-
-// Returns true if a mouse drag while in "snap mode" at |location_in_screen|
-// would hover/press |button| or keep it hovered/pressed.
-bool HitTestButton(const ash::FrameCaptionButton* button,
-                   const gfx::Point& location_in_screen) {
-  gfx::Rect expanded_bounds_in_screen = button->GetBoundsInScreen();
-  if (button->state() == views::Button::STATE_HOVERED ||
-      button->state() == views::Button::STATE_PRESSED) {
-    expanded_bounds_in_screen.Inset(-kMaxOvershootX, -kMaxOvershootY);
-  }
-  return expanded_bounds_in_screen.Contains(location_in_screen);
-}
-
-}  // namespace
-
-namespace ash {
-
-AlternateFrameSizeButton::AlternateFrameSizeButton(
-    views::ButtonListener* listener,
-    views::Widget* frame,
-    AlternateFrameSizeButtonDelegate* delegate)
-    : FrameCaptionButton(listener, CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE),
-      frame_(frame),
-      delegate_(delegate),
-      set_buttons_to_snap_mode_delay_ms_(kSetButtonsToSnapModeDelayMs),
-      in_snap_mode_(false),
-      snap_type_(SNAP_NONE) {
-}
-
-AlternateFrameSizeButton::~AlternateFrameSizeButton() {
-}
-
-bool AlternateFrameSizeButton::OnMousePressed(const ui::MouseEvent& event) {
-  // The minimize and close buttons are set to snap left and right when snapping
-  // is enabled. Do not enable snapping if the minimize button is not visible.
-  // The close button is always visible.
-  if (IsTriggerableEvent(event) &&
-      !in_snap_mode_ &&
-      delegate_->IsMinimizeButtonVisible()) {
-    StartSetButtonsToSnapModeTimer(event);
-  }
-  FrameCaptionButton::OnMousePressed(event);
-  return true;
-}
-
-bool AlternateFrameSizeButton::OnMouseDragged(const ui::MouseEvent& event) {
-  UpdateSnapType(event);
-  // By default a FrameCaptionButton reverts to STATE_NORMAL once the mouse
-  // leaves its bounds. Skip FrameCaptionButton's handling when
-  // |in_snap_mode_| == true because we want different behavior.
-  if (!in_snap_mode_)
-    FrameCaptionButton::OnMouseDragged(event);
-  return true;
-}
-
-void AlternateFrameSizeButton::OnMouseReleased(const ui::MouseEvent& event) {
-  if (!IsTriggerableEvent(event) || !CommitSnap(event))
-    FrameCaptionButton::OnMouseReleased(event);
-}
-
-void AlternateFrameSizeButton::OnMouseCaptureLost() {
-  SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_YES);
-  FrameCaptionButton::OnMouseCaptureLost();
-}
-
-void AlternateFrameSizeButton::OnMouseMoved(const ui::MouseEvent& event) {
-  // Ignore any synthetic mouse moves during a drag.
-  if (!in_snap_mode_)
-    FrameCaptionButton::OnMouseMoved(event);
-}
-
-void AlternateFrameSizeButton::OnGestureEvent(ui::GestureEvent* event) {
-  if (event->details().touch_points() > 1) {
-    SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_YES);
-    return;
-  }
-
-  if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
-    StartSetButtonsToSnapModeTimer(*event);
-    // Go through FrameCaptionButton's handling so that the button gets pressed.
-    FrameCaptionButton::OnGestureEvent(event);
-    return;
-  }
-
-  if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
-      event->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
-    UpdateSnapType(*event);
-    event->SetHandled();
-    return;
-  }
-
-  if (event->type() == ui::ET_GESTURE_TAP ||
-      event->type() == ui::ET_GESTURE_SCROLL_END ||
-      event->type() == ui::ET_SCROLL_FLING_START ||
-      event->type() == ui::ET_GESTURE_END) {
-    if (CommitSnap(*event)) {
-      if (event->type() == ui::ET_GESTURE_TAP) {
-        TouchUMA::GetInstance()->RecordGestureAction(
-            TouchUMA::GESTURE_FRAMEMAXIMIZE_TAP);
-      }
-      event->SetHandled();
-      return;
-    }
-  }
-
-  FrameCaptionButton::OnGestureEvent(event);
-}
-
-void AlternateFrameSizeButton::StartSetButtonsToSnapModeTimer(
-    const ui::LocatedEvent& event) {
-  set_buttons_to_snap_mode_timer_event_location_ = event.location();
-  if (set_buttons_to_snap_mode_delay_ms_ == 0) {
-    AnimateButtonsToSnapMode();
-  } else {
-    set_buttons_to_snap_mode_timer_.Start(
-        FROM_HERE,
-        base::TimeDelta::FromMilliseconds(set_buttons_to_snap_mode_delay_ms_),
-        this,
-        &AlternateFrameSizeButton::AnimateButtonsToSnapMode);
-  }
-}
-
-void AlternateFrameSizeButton::AnimateButtonsToSnapMode() {
-  SetButtonsToSnapMode(AlternateFrameSizeButtonDelegate::ANIMATE_YES);
-}
-
-void AlternateFrameSizeButton::SetButtonsToSnapMode(
-    AlternateFrameSizeButtonDelegate::Animate animate) {
-  in_snap_mode_ = true;
-
-  // When using a right-to-left layout the close button is left of the size
-  // button and the minimize button is right of the size button.
-  if (base::i18n::IsRTL()) {
-    delegate_->SetButtonIcons(CAPTION_BUTTON_ICON_RIGHT_SNAPPED,
-                              CAPTION_BUTTON_ICON_LEFT_SNAPPED,
-                              animate);
-  } else {
-    delegate_->SetButtonIcons(CAPTION_BUTTON_ICON_LEFT_SNAPPED,
-                              CAPTION_BUTTON_ICON_RIGHT_SNAPPED,
-                              animate);
-  }
-}
-
-void AlternateFrameSizeButton::UpdateSnapType(const ui::LocatedEvent& event) {
-  if (!in_snap_mode_) {
-    // Set the buttons adjacent to the size button to snap left and right early
-    // if the user drags past the drag threshold.
-    // |set_buttons_to_snap_mode_timer_| is checked to avoid entering the snap
-    // mode as a result of an unsupported drag type (e.g. only the right mouse
-    // button is pressed).
-    gfx::Vector2d delta(
-        event.location() - set_buttons_to_snap_mode_timer_event_location_);
-    if (!set_buttons_to_snap_mode_timer_.IsRunning() ||
-        !views::View::ExceededDragThreshold(delta)) {
-      return;
-    }
-    AnimateButtonsToSnapMode();
-  }
-
-  gfx::Point event_location_in_screen(event.location());
-  views::View::ConvertPointToScreen(this, &event_location_in_screen);
-  const FrameCaptionButton* to_hover =
-      GetButtonToHover(event_location_in_screen);
-  bool press_size_button =
-      to_hover || HitTestButton(this, event_location_in_screen);
-
-  if (to_hover) {
-    // Progress the minimize and close icon morph animations to the end if they
-    // are in progress.
-    SetButtonsToSnapMode(AlternateFrameSizeButtonDelegate::ANIMATE_NO);
-  }
-
-  delegate_->SetHoveredAndPressedButtons(
-      to_hover, press_size_button ? this : NULL);
-
-  snap_type_ = SNAP_NONE;
-  if (to_hover) {
-    switch (to_hover->icon()) {
-      case CAPTION_BUTTON_ICON_LEFT_SNAPPED:
-        snap_type_ = SNAP_LEFT;
-        break;
-      case CAPTION_BUTTON_ICON_RIGHT_SNAPPED:
-        snap_type_ = SNAP_RIGHT;
-        break;
-      case CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE:
-      case CAPTION_BUTTON_ICON_MINIMIZE:
-      case CAPTION_BUTTON_ICON_CLOSE:
-      case CAPTION_BUTTON_ICON_COUNT:
-        NOTREACHED();
-        break;
-    }
-  }
-
-  if (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT) {
-    aura::Window* window = frame_->GetNativeWindow();
-    if (!phantom_window_controller_.get()) {
-      phantom_window_controller_.reset(new PhantomWindowController(window));
-    }
-    gfx::Rect phantom_bounds_in_parent = (snap_type_ == SNAP_LEFT) ?
-        wm::GetDefaultLeftSnappedWindowBoundsInParent(window) :
-        wm::GetDefaultRightSnappedWindowBoundsInParent(window);
-    phantom_window_controller_->Show(ScreenUtil::ConvertRectToScreen(
-          window->parent(), phantom_bounds_in_parent));
-  } else {
-    phantom_window_controller_.reset();
-  }
-}
-
-const FrameCaptionButton* AlternateFrameSizeButton::GetButtonToHover(
-    const gfx::Point& event_location_in_screen) const {
-  const FrameCaptionButton* closest_button = delegate_->GetButtonClosestTo(
-      event_location_in_screen);
-  if ((closest_button->icon() == CAPTION_BUTTON_ICON_LEFT_SNAPPED ||
-       closest_button->icon() == CAPTION_BUTTON_ICON_RIGHT_SNAPPED) &&
-      HitTestButton(closest_button, event_location_in_screen)) {
-    return closest_button;
-  }
-  return NULL;
-}
-
-bool AlternateFrameSizeButton::CommitSnap(const ui::LocatedEvent& event) {
-  // The position of |event| may be different than the position of the previous
-  // event.
-  UpdateSnapType(event);
-
-  if (in_snap_mode_ &&
-      (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) {
-    wm::WindowState* window_state =
-        wm::GetWindowState(frame_->GetNativeWindow());
-    UserMetricsRecorder* metrics = Shell::GetInstance()->metrics();
-    const wm::WMEvent snap_event(
-        snap_type_ == SNAP_LEFT ?
-        wm::WM_EVENT_SNAP_LEFT : wm::WM_EVENT_SNAP_RIGHT);
-    window_state->OnWMEvent(&snap_event);
-    metrics->RecordUserMetricsAction(
-        snap_type_ == SNAP_LEFT ?
-        UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT :
-        UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT);
-    SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_NO);
-    return true;
-  }
-  SetButtonsToNormalMode(AlternateFrameSizeButtonDelegate::ANIMATE_YES);
-  return false;
-}
-
-void AlternateFrameSizeButton::SetButtonsToNormalMode(
-    AlternateFrameSizeButtonDelegate::Animate animate) {
-  in_snap_mode_ = false;
-  snap_type_ = SNAP_NONE;
-  set_buttons_to_snap_mode_timer_.Stop();
-  delegate_->SetButtonsToNormal(animate);
-  phantom_window_controller_.reset();
-}
-
-}  // namespace ash
diff --git a/ash/frame/caption_buttons/alternate_frame_size_button.h b/ash/frame/caption_buttons/alternate_frame_size_button.h
deleted file mode 100644
index e99d32f..0000000
--- a/ash/frame/caption_buttons/alternate_frame_size_button.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef ASH_FRAME_CAPTION_BUTTONS_ALTERNATE_FRAME_SIZE_BUTTON_H_
-#define ASH_FRAME_CAPTION_BUTTONS_ALTERNATE_FRAME_SIZE_BUTTON_H_
-
-#include "ash/ash_export.h"
-#include "ash/frame/caption_buttons/alternate_frame_size_button_delegate.h"
-#include "ash/frame/caption_buttons/frame_caption_button.h"
-#include "ash/wm/workspace/snap_types.h"
-#include "base/timer/timer.h"
-
-namespace views {
-class Widget;
-}
-
-namespace ash {
-class AlternateFrameSizeButtonDelegate;
-class PhantomWindowController;
-
-// The maximize/restore button when using the alternate button style.
-// When the mouse is pressed over the size button or the size button is touched:
-// - The minimize and close buttons are set to snap left and snap right
-//   respectively.
-// - The size button stays pressed while the mouse is over the buttons to snap
-//   left and to snap right. The button underneath the mouse is hovered.
-// When the drag terminates, the action for the button underneath the mouse
-// is executed. For the sake of simplicity, the size button is the event
-// handler for a click starting on the size button and the entire drag.
-class ASH_EXPORT AlternateFrameSizeButton : public FrameCaptionButton {
- public:
-  AlternateFrameSizeButton(views::ButtonListener* listener,
-                           views::Widget* frame,
-                           AlternateFrameSizeButtonDelegate* delegate);
-
-  virtual ~AlternateFrameSizeButton();
-
-  // views::CustomButton overrides:
-  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
-  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
-  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
-  virtual void OnMouseCaptureLost() OVERRIDE;
-  virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE;
-  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
-
-  void set_delay_to_set_buttons_to_snap_mode(int delay_ms) {
-    set_buttons_to_snap_mode_delay_ms_ = delay_ms;
-  }
-
- private:
-  // Starts |set_buttons_to_snap_mode_timer_|.
-  void StartSetButtonsToSnapModeTimer(const ui::LocatedEvent& event);
-
-  // Animates the buttons adjacent to the size button to snap left and right.
-  void AnimateButtonsToSnapMode();
-
-  // Sets the buttons adjacent to the size button to snap left and right.
-  // Passing in ANIMATE_NO progresses the animation (if any) to the end.
-  void SetButtonsToSnapMode(
-      AlternateFrameSizeButtonDelegate::Animate animate);
-
-  // Updates |snap_type_|, whether the size button is pressed and whether any
-  // other buttons are hovered.
-  void UpdateSnapType(const ui::LocatedEvent& event);
-
-  // Returns the button which should be hovered (if any) while in "snap mode"
-  // for |event_location_in_screen|.
-  const FrameCaptionButton* GetButtonToHover(
-      const gfx::Point& event_location_in_screen) const;
-
-  // Snaps |frame_| according to |snap_type_|. Returns true if |frame_| was
-  // snapped.
-  bool CommitSnap(const ui::LocatedEvent& event);
-
-  // Sets the buttons adjacent to the size button to minimize and close again.
-  // Clears any state set while snapping was enabled. |animate| indicates
-  // whether the buttons should animate back to their original icons.
-  void SetButtonsToNormalMode(
-      AlternateFrameSizeButtonDelegate::Animate animate);
-
-  // Widget that the size button acts on.
-  views::Widget* frame_;
-
-  // Not owned.
-  AlternateFrameSizeButtonDelegate* delegate_;
-
-  // Location of the event which started |set_buttons_to_snap_mode_timer_| in
-  // view coordinates.
-  gfx::Point set_buttons_to_snap_mode_timer_event_location_;
-
-  // The delay between the user pressing the size button and the buttons
-  // adjacent to the size button morphing into buttons for snapping left and
-  // right.
-  int set_buttons_to_snap_mode_delay_ms_;
-
-  base::OneShotTimer<AlternateFrameSizeButton> set_buttons_to_snap_mode_timer_;
-
-  // Whether the buttons adjacent to the size button snap the window left and
-  // right.
-  bool in_snap_mode_;
-
-  // The action to execute when the drag/click is ended. If
-  // |snap_type_| == SNAP_NONE, the size button's default action is run when the
-  // drag/click is ended.
-  SnapType snap_type_;
-
-  // Displays a preview of how the window's bounds will change as a result of
-  // snapping the window left or right. The preview is only visible if the snap
-  // left or snap right button is pressed.
-  scoped_ptr<PhantomWindowController> phantom_window_controller_;
-
-  DISALLOW_COPY_AND_ASSIGN(AlternateFrameSizeButton);
-};
-
-}  // namespace ash
-
-#endif  // ASH_FRAME_CAPTION_BUTTONS_ALTERNATE_FRAME_SIZE_BUTTON_H_
diff --git a/ash/frame/caption_buttons/alternate_frame_size_button_delegate.h b/ash/frame/caption_buttons/alternate_frame_size_button_delegate.h
deleted file mode 100644
index 050227b..0000000
--- a/ash/frame/caption_buttons/alternate_frame_size_button_delegate.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef ASH_FRAME_CAPTION_BUTTONS_ALTERNATE_FRAME_SIZE_BUTTON_DELEGATE_H_
-#define ASH_FRAME_CAPTION_BUTTONS_ALTERNATE_FRAME_SIZE_BUTTON_DELEGATE_H_
-
-#include "ash/ash_export.h"
-#include "ash/frame/caption_buttons/caption_button_types.h"
-
-namespace gfx {
-class Insets;
-class Point;
-class Vector2d;
-}
-
-namespace ash {
-class FrameCaptionButton;
-
-// Delegate interface for AlternateFrameSizeButton.
-class ASH_EXPORT AlternateFrameSizeButtonDelegate {
- public:
-  enum Animate {
-    ANIMATE_YES,
-    ANIMATE_NO
-  };
-
-  // Returns whether the minimize button is visible.
-  virtual bool IsMinimizeButtonVisible() const = 0;
-
-  // Reset the caption button views::Button::ButtonState back to normal. If
-  // |animate| is ANIMATE_YES, the buttons will crossfade back to their
-  // original icons.
-  virtual void SetButtonsToNormal(Animate animate) = 0;
-
-  // Sets the minimize and close button icons. The buttons will crossfade to
-  // their new icons if |animate| is ANIMATE_YES.
-  virtual void SetButtonIcons(CaptionButtonIcon minimize_button_icon,
-                              CaptionButtonIcon close_button_icon,
-                              Animate animate) = 0;
-
-  // Returns the button closest to |position_in_screen|.
-  virtual const FrameCaptionButton* GetButtonClosestTo(
-      const gfx::Point& position_in_screen) const = 0;
-
-  // Sets |to_hover| and |to_pressed| to STATE_HOVERED and STATE_PRESSED
-  // respectively. All other buttons are to set to STATE_NORMAL.
-  virtual void SetHoveredAndPressedButtons(
-      const FrameCaptionButton* to_hover,
-      const FrameCaptionButton* to_press) = 0;
-
- protected:
-  virtual ~AlternateFrameSizeButtonDelegate() {}
-};
-
-}  // namespace ash
-
-#endif  // ASH_FRAME_CAPTION_BUTTONS_ALTERNATE_FRAME_SIZE_BUTTON_DELEGATE_H_
diff --git a/ash/frame/caption_buttons/alternate_frame_size_button_unittest.cc b/ash/frame/caption_buttons/alternate_frame_size_button_unittest.cc
deleted file mode 100644
index 92c7bbc..0000000
--- a/ash/frame/caption_buttons/alternate_frame_size_button_unittest.cc
+++ /dev/null
@@ -1,478 +0,0 @@
-// Copyright 2013 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.
-
-#include "ash/frame/caption_buttons/alternate_frame_size_button.h"
-
-#include "ash/ash_switches.h"
-#include "ash/frame/caption_buttons/frame_caption_button.h"
-#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
-#include "ash/shell.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/wm/window_state.h"
-#include "base/command_line.h"
-#include "base/i18n/rtl.h"
-#include "grit/ash_resources.h"
-#include "ui/aura/test/event_generator.h"
-#include "ui/aura/window.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/events/gestures/gesture_configuration.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/screen.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_delegate.h"
-
-namespace ash {
-namespace test {
-
-namespace {
-
-class TestWidgetDelegate : public views::WidgetDelegateView {
- public:
-  TestWidgetDelegate() {}
-  virtual ~TestWidgetDelegate() {}
-
-  // Overridden from views::WidgetDelegate:
-  virtual views::View* GetContentsView() OVERRIDE {
-    return this;
-  }
-  virtual bool CanResize() const OVERRIDE {
-    return true;
-  }
-  virtual bool CanMaximize() const OVERRIDE {
-    return true;
-  }
-
-  ash::FrameCaptionButtonContainerView* caption_button_container() {
-    return caption_button_container_;
-  }
-
- private:
-  // Overridden from views::View:
-  virtual void Layout() OVERRIDE {
-    caption_button_container_->Layout();
-
-    // Right align the caption button container.
-    gfx::Size preferred_size = caption_button_container_->GetPreferredSize();
-    caption_button_container_->SetBounds(width() - preferred_size.width(), 0,
-        preferred_size.width(), preferred_size.height());
-  }
-
-  virtual void ViewHierarchyChanged(
-      const ViewHierarchyChangedDetails& details) OVERRIDE {
-    if (details.is_add && details.child == this) {
-      caption_button_container_ = new FrameCaptionButtonContainerView(
-          GetWidget(), FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
-
-      // Set arbitrary images for the container's buttons so that the buttons
-      // have non-empty sizes.
-      for (int icon = 0; icon < CAPTION_BUTTON_ICON_COUNT; ++icon) {
-        caption_button_container_->SetButtonImages(
-            static_cast<CaptionButtonIcon>(icon),
-            IDR_AURA_WINDOW_CONTROL_ICON_CLOSE,
-            IDR_AURA_WINDOW_CONTROL_ICON_CLOSE_I,
-            IDR_AURA_WINDOW_CONTROL_BACKGROUND_H,
-            IDR_AURA_WINDOW_CONTROL_BACKGROUND_P);
-      }
-
-      AddChildView(caption_button_container_);
-    }
-  }
-
-  // Not owned.
-  ash::FrameCaptionButtonContainerView* caption_button_container_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate);
-};
-
-}  // namespace
-
-class AlternateFrameSizeButtonTest : public AshTestBase {
- public:
-  AlternateFrameSizeButtonTest() {}
-  virtual ~AlternateFrameSizeButtonTest() {}
-
-  // Returns the center point of |view| in screen coordinates.
-  gfx::Point CenterPointInScreen(views::View* view) {
-    return view->GetBoundsInScreen().CenterPoint();
-  }
-
-  // Returns true if the window has |state_type|.
-  bool HasStateType(wm::WindowStateType state_type) const {
-    return window_state()->GetStateType() == state_type;
-  }
-
-  // Returns true if all three buttons are in the normal state.
-  bool AllButtonsInNormalState() const {
-    return minimize_button_->state() == views::Button::STATE_NORMAL &&
-        size_button_->state() == views::Button::STATE_NORMAL &&
-        close_button_->state() == views::Button::STATE_NORMAL;
-  }
-
-  // Creates a widget with |delegate|. The returned widget takes ownership of
-  // |delegate|.
-  views::Widget* CreateWidget(views::WidgetDelegate* delegate) {
-    views::Widget* widget = new views::Widget;
-    views::Widget::InitParams params(
-        views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
-    params.context = CurrentContext();
-    params.delegate = delegate;
-    params.bounds = gfx::Rect(10, 10, 100, 100);
-    widget->Init(params);
-    widget->Show();
-    return widget;
-  }
-
-  // AshTestBase overrides:
-  virtual void SetUp() OVERRIDE {
-    AshTestBase::SetUp();
-
-    CommandLine* command_line = CommandLine::ForCurrentProcess();
-    command_line->AppendSwitch(
-        switches::kAshEnableAlternateFrameCaptionButtonStyle);
-
-    TestWidgetDelegate* delegate = new TestWidgetDelegate();
-    window_state_ = ash::wm::GetWindowState(
-        CreateWidget(delegate)->GetNativeWindow());
-
-    FrameCaptionButtonContainerView::TestApi test(
-        delegate->caption_button_container());
-
-    minimize_button_ = test.minimize_button();
-    size_button_ = test.size_button();
-    static_cast<AlternateFrameSizeButton*>(
-        size_button_)->set_delay_to_set_buttons_to_snap_mode(0);
-    close_button_ = test.close_button();
-  }
-
-  ash::wm::WindowState* window_state() { return window_state_; }
-  const ash::wm::WindowState* window_state() const { return window_state_; }
-
-  FrameCaptionButton* minimize_button() { return minimize_button_; }
-  FrameCaptionButton* size_button() { return size_button_; }
-  FrameCaptionButton* close_button() { return close_button_; }
-
- private:
-  // Not owned.
-  ash::wm::WindowState* window_state_;
-  FrameCaptionButton* minimize_button_;
-  FrameCaptionButton* size_button_;
-  FrameCaptionButton* close_button_;
-
-  DISALLOW_COPY_AND_ASSIGN(AlternateFrameSizeButtonTest);
-};
-
-// Tests that pressing the left mouse button or tapping down on the size button
-// puts the button into the pressed state.
-TEST_F(AlternateFrameSizeButtonTest, PressedState) {
-  aura::test::EventGenerator& generator = GetEventGenerator();
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.PressLeftButton();
-  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
-  generator.ReleaseLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_EQ(views::Button::STATE_NORMAL, size_button()->state());
-
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.PressTouchId(3);
-  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
-  generator.ReleaseTouchId(3);
-  RunAllPendingInMessageLoop();
-  EXPECT_EQ(views::Button::STATE_NORMAL, size_button()->state());
-}
-
-// Tests that clicking on the size button toggles between the maximized and
-// normal state.
-TEST_F(AlternateFrameSizeButtonTest, ClickSizeButtonTogglesMaximize) {
-  EXPECT_FALSE(window_state()->IsMaximized());
-
-  aura::test::EventGenerator& generator = GetEventGenerator();
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.ClickLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(window_state()->IsMaximized());
-
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.ClickLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(window_state()->IsMaximized());
-
-  generator.GestureTapAt(CenterPointInScreen(size_button()));
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(window_state()->IsMaximized());
-
-  generator.GestureTapAt(CenterPointInScreen(size_button()));
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(window_state()->IsMaximized());
-}
-
-// Test that clicking + dragging to a button adjacent to the size button snaps
-// the window left or right.
-TEST_F(AlternateFrameSizeButtonTest, ButtonDrag) {
-  EXPECT_TRUE(window_state()->IsNormalStateType());
-
-  // 1) Test by dragging the mouse.
-  // Snap right.
-  aura::test::EventGenerator& generator = GetEventGenerator();
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.PressLeftButton();
-  generator.MoveMouseTo(CenterPointInScreen(close_button()));
-  generator.ReleaseLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
-
-  // Snap left.
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.PressLeftButton();
-  generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
-  generator.ReleaseLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
-
-  // 2) Test with scroll gestures.
-  // Snap right.
-  generator.GestureScrollSequence(
-      CenterPointInScreen(size_button()),
-      CenterPointInScreen(close_button()),
-      base::TimeDelta::FromMilliseconds(100),
-      3);
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
-
-  // Snap left.
-  generator.GestureScrollSequence(
-      CenterPointInScreen(size_button()),
-      CenterPointInScreen(minimize_button()),
-      base::TimeDelta::FromMilliseconds(100),
-      3);
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
-
-  // 3) Test with tap gestures.
-  const int touch_default_radius =
-      ui::GestureConfiguration::default_radius();
-  ui::GestureConfiguration::set_default_radius(0);
-  // Snap right.
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.PressMoveAndReleaseTouchTo(CenterPointInScreen(close_button()));
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
-  // Snap left.
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.PressMoveAndReleaseTouchTo(CenterPointInScreen(minimize_button()));
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
-  ui::GestureConfiguration::set_default_radius(touch_default_radius);
-}
-
-// Test that clicking, dragging, and overshooting the minimize button a bit
-// horizontally still snaps the window left.
-TEST_F(AlternateFrameSizeButtonTest, SnapLeftOvershootMinimize) {
-  EXPECT_TRUE(window_state()->IsNormalStateType());
-
-  aura::test::EventGenerator& generator = GetEventGenerator();
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-
-  generator.PressLeftButton();
-  // Move to the minimize button.
-  generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
-  // Overshoot the minimize button.
-  generator.MoveMouseBy(-minimize_button()->width(), 0);
-  generator.ReleaseLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
-}
-
-// Test that right clicking the size button has no effect.
-TEST_F(AlternateFrameSizeButtonTest, RightMouseButton) {
-  EXPECT_TRUE(window_state()->IsNormalStateType());
-
-  aura::test::EventGenerator& generator = GetEventGenerator();
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.PressRightButton();
-  generator.ReleaseRightButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(window_state()->IsNormalStateType());
-}
-
-// Test that upon releasing the mouse button after having pressed the size
-// button
-// - The state of all the caption buttons is reset.
-// - The icon displayed by all of the caption buttons is reset.
-TEST_F(AlternateFrameSizeButtonTest, ResetButtonsAfterClick) {
-  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
-  EXPECT_TRUE(AllButtonsInNormalState());
-
-  // Pressing the size button should result in the size button being pressed and
-  // the minimize and close button icons changing.
-  aura::test::EventGenerator& generator = GetEventGenerator();
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.PressLeftButton();
-  EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
-  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
-  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
-
-  // Dragging the mouse over the minimize button should hover the minimize
-  // button and the minimize and close button icons should stay changed.
-  generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
-  EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
-  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
-  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
-
-  // Release the mouse, snapping the window left.
-  generator.ReleaseLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
-
-  // None of the buttons should stay pressed and the buttons should have their
-  // regular icons.
-  EXPECT_TRUE(AllButtonsInNormalState());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
-
-  // Repeat test but release button where it does not affect the window's state
-  // because the code path is different.
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.PressLeftButton();
-  EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
-  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
-  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
-
-  const gfx::Rect& kWorkAreaBoundsInScreen =
-      ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
-  generator.MoveMouseTo(kWorkAreaBoundsInScreen.bottom_left());
-
-  // None of the buttons should be pressed because we are really far away from
-  // any of the caption buttons. The minimize and close button icons should
-  // be changed because the mouse is pressed.
-  EXPECT_TRUE(AllButtonsInNormalState());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
-
-  // Release the mouse. The window should stay snapped left.
-  generator.ReleaseLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
-
-  // The buttons should stay unpressed and the buttons should now have their
-  // regular icons.
-  EXPECT_TRUE(AllButtonsInNormalState());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
-}
-
-// Test that the size button is pressed whenever the snap left/right buttons
-// are hovered.
-TEST_F(AlternateFrameSizeButtonTest, SizeButtonPressedWhenSnapButtonHovered) {
-  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
-  EXPECT_TRUE(AllButtonsInNormalState());
-
-  // Pressing the size button should result in the size button being pressed and
-  // the minimize and close button icons changing.
-  aura::test::EventGenerator& generator = GetEventGenerator();
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.PressLeftButton();
-  EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
-  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
-  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
-
-  // Dragging the mouse over the minimize button (snap left button) should hover
-  // the minimize button and keep the size button pressed.
-  generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
-  EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
-  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
-  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
-
-  // Moving the mouse far away from the caption buttons and then moving it over
-  // the close button (snap right button) should hover the close button and
-  // keep the size button pressed.
-  const gfx::Rect& kWorkAreaBoundsInScreen =
-      ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
-  generator.MoveMouseTo(kWorkAreaBoundsInScreen.bottom_left());
-  EXPECT_TRUE(AllButtonsInNormalState());
-  generator.MoveMouseTo(CenterPointInScreen(close_button()));
-  EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
-  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
-  EXPECT_EQ(views::Button::STATE_HOVERED, close_button()->state());
-}
-
-class AlternateFrameSizeButtonTestRTL : public AlternateFrameSizeButtonTest {
- public:
-  AlternateFrameSizeButtonTestRTL() {}
-  virtual ~AlternateFrameSizeButtonTestRTL() {}
-
-  virtual void SetUp() OVERRIDE {
-    original_locale_ = l10n_util::GetApplicationLocale(std::string());
-    base::i18n::SetICUDefaultLocale("he");
-
-    AlternateFrameSizeButtonTest::SetUp();
-  }
-
-  virtual void TearDown() OVERRIDE {
-    AlternateFrameSizeButtonTest::TearDown();
-    base::i18n::SetICUDefaultLocale(original_locale_);
-  }
-
- private:
-  std::string original_locale_;
-
-  DISALLOW_COPY_AND_ASSIGN(AlternateFrameSizeButtonTestRTL);
-};
-
-// Test that clicking + dragging to a button adjacent to the size button presses
-// the correct button and snaps the window to the correct side.
-TEST_F(AlternateFrameSizeButtonTestRTL, ButtonDrag) {
-  // In RTL the close button should be left of the size button and the minimize
-  // button should be right of the size button.
-  ASSERT_LT(close_button()->GetBoundsInScreen().x(),
-            size_button()->GetBoundsInScreen().x());
-  ASSERT_LT(size_button()->GetBoundsInScreen().x(),
-            minimize_button()->GetBoundsInScreen().x());
-
-  // Test initial state.
-  EXPECT_TRUE(window_state()->IsNormalStateType());
-  EXPECT_TRUE(AllButtonsInNormalState());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
-
-  // Pressing the size button should swap the icons of the minimize and close
-  // buttons to icons for snapping right and for snapping left respectively.
-  aura::test::EventGenerator& generator = GetEventGenerator();
-  generator.MoveMouseTo(CenterPointInScreen(size_button()));
-  generator.PressLeftButton();
-  EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
-  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
-  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, close_button()->icon());
-
-  // Dragging over to the minimize button should press it.
-  generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
-  EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
-  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
-  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
-
-  // Releasing should snap the window right.
-  generator.ReleaseLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
-
-  // None of the buttons should stay pressed and the buttons should have their
-  // regular icons.
-  EXPECT_TRUE(AllButtonsInNormalState());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
-  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
-}
-
-}  // namespace test
-}  // namespace ash
diff --git a/ash/frame/caption_buttons/bubble_contents_button_row.cc b/ash/frame/caption_buttons/bubble_contents_button_row.cc
deleted file mode 100644
index 761beec..0000000
--- a/ash/frame/caption_buttons/bubble_contents_button_row.cc
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2013 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.
-
-#include "ash/frame/caption_buttons/bubble_contents_button_row.h"
-
-#include "ash/frame/caption_buttons/maximize_bubble_controller.h"
-#include "ash/frame/caption_buttons/maximize_bubble_controller_bubble.h"
-#include "grit/ash_resources.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/layout/box_layout.h"
-
-
-namespace ash {
-
-// BubbleDialogButton ---------------------------------------------------------
-
-// The image button gets overridden to be able to capture mouse hover events.
-// The constructor also assigns all button states and adds |this| as a child of
-// |button_row|.
-class BubbleDialogButton : public views::ImageButton {
- public:
-  explicit BubbleDialogButton(BubbleContentsButtonRow* button_row,
-                              int normal_image,
-                              int hovered_image,
-                              int pressed_image);
-  virtual ~BubbleDialogButton();
-
-  // views::ImageButton:
-  virtual void OnMouseCaptureLost() OVERRIDE;
-  virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
-  virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
-  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
-
- private:
-  // The creating class which needs to get notified in case of a hover event.
-  BubbleContentsButtonRow* button_row_;
-
-  DISALLOW_COPY_AND_ASSIGN(BubbleDialogButton);
-};
-
-BubbleDialogButton::BubbleDialogButton(
-    BubbleContentsButtonRow* button_row,
-    int normal_image,
-    int hovered_image,
-    int pressed_image)
-    : views::ImageButton(button_row),
-      button_row_(button_row) {
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  SetImage(views::CustomButton::STATE_NORMAL,
-           rb.GetImageSkiaNamed(normal_image));
-  SetImage(views::CustomButton::STATE_HOVERED,
-           rb.GetImageSkiaNamed(hovered_image));
-  SetImage(views::CustomButton::STATE_PRESSED,
-           rb.GetImageSkiaNamed(pressed_image));
-  button_row->AddChildView(this);
-}
-
-BubbleDialogButton::~BubbleDialogButton() {
-}
-
-void BubbleDialogButton::OnMouseCaptureLost() {
-  button_row_->ButtonHovered(NULL);
-  views::ImageButton::OnMouseCaptureLost();
-}
-
-void BubbleDialogButton::OnMouseEntered(const ui::MouseEvent& event) {
-  button_row_->ButtonHovered(this);
-  views::ImageButton::OnMouseEntered(event);
-}
-
-void BubbleDialogButton::OnMouseExited(const ui::MouseEvent& event) {
-  button_row_->ButtonHovered(NULL);
-  views::ImageButton::OnMouseExited(event);
-}
-
-bool BubbleDialogButton::OnMouseDragged(const ui::MouseEvent& event) {
-  if (!button_row_->bubble()->controller())
-    return false;
-
-  // Remove the phantom window when we leave the button.
-  gfx::Point screen_location(event.location());
-  View::ConvertPointToScreen(this, &screen_location);
-  if (!GetBoundsInScreen().Contains(screen_location))
-    button_row_->ButtonHovered(NULL);
-  else
-    button_row_->ButtonHovered(this);
-
-  // Pass the event on to the normal handler.
-  return views::ImageButton::OnMouseDragged(event);
-}
-
-
-// BubbleContentsButtonRow ----------------------------------------------------
-
-BubbleContentsButtonRow::BubbleContentsButtonRow(
-    MaximizeBubbleControllerBubble* bubble)
-    : bubble_(bubble),
-      left_button_(NULL),
-      minimize_button_(NULL),
-      right_button_(NULL) {
-  SetLayoutManager(new views::BoxLayout(
-      views::BoxLayout::kHorizontal, 0, 0,
-      MaximizeBubbleControllerBubble::kLayoutSpacing));
-  set_background(views::Background::CreateSolidBackground(
-      MaximizeBubbleControllerBubble::kBubbleBackgroundColor));
-
-  if (base::i18n::IsRTL()) {
-    AddMaximizeRightButton();
-    AddMinimizeButton();
-    AddMaximizeLeftButton();
-  } else {
-    AddMaximizeLeftButton();
-    AddMinimizeButton();
-    AddMaximizeRightButton();
-  }
-}
-
-BubbleContentsButtonRow::~BubbleContentsButtonRow() {
-}
-
-void BubbleContentsButtonRow::ButtonPressed(views::Button* sender,
-                                            const ui::Event& event) {
-  // While shutting down, the connection to the owner might already be broken.
-  if (!bubble_->controller())
-    return;
-  if (sender == left_button_) {
-    bubble_->controller()->OnButtonClicked(
-        (bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_LEFT) ?
-            SNAP_RESTORE : SNAP_LEFT);
-  } else if (sender == minimize_button_) {
-    bubble_->controller()->OnButtonClicked(SNAP_MINIMIZE);
-  } else {
-    DCHECK(sender == right_button_);
-    bubble_->controller()->OnButtonClicked(
-        (bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_RIGHT) ?
-            SNAP_RESTORE : SNAP_RIGHT);
-  }
-}
-
-void BubbleContentsButtonRow::ButtonHovered(BubbleDialogButton* sender) {
-  // While shutting down, the connection to the owner might already be broken.
-  if (!bubble_->controller())
-    return;
-  if (sender == left_button_) {
-    bubble_->controller()->OnButtonHover(
-        (bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_LEFT) ?
-            SNAP_RESTORE : SNAP_LEFT);
-  } else if (sender == minimize_button_) {
-    bubble_->controller()->OnButtonHover(SNAP_MINIMIZE);
-  } else if (sender == right_button_) {
-    bubble_->controller()->OnButtonHover(
-        (bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_RIGHT) ?
-            SNAP_RESTORE : SNAP_RIGHT);
-  } else {
-    bubble_->controller()->OnButtonHover(SNAP_NONE);
-  }
-}
-
-views::CustomButton* BubbleContentsButtonRow::GetButtonForUnitTest(
-    SnapType state) {
-  switch (state) {
-    case SNAP_LEFT:
-      return left_button_;
-    case SNAP_MINIMIZE:
-      return minimize_button_;
-    case SNAP_RIGHT:
-      return right_button_;
-    default:
-      NOTREACHED();
-      return NULL;
-  }
-}
-
-void BubbleContentsButtonRow::AddMaximizeLeftButton() {
-  if (bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_LEFT) {
-    left_button_ = new BubbleDialogButton(
-        this,
-        IDR_AURA_WINDOW_POSITION_LEFT_RESTORE,
-        IDR_AURA_WINDOW_POSITION_LEFT_RESTORE_H,
-        IDR_AURA_WINDOW_POSITION_LEFT_RESTORE_P);
-  } else {
-    left_button_ = new BubbleDialogButton(
-        this,
-        IDR_AURA_WINDOW_POSITION_LEFT,
-        IDR_AURA_WINDOW_POSITION_LEFT_H,
-        IDR_AURA_WINDOW_POSITION_LEFT_P);
-  }
-}
-
-void BubbleContentsButtonRow::AddMaximizeRightButton() {
-  if (bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_RIGHT) {
-    right_button_ = new BubbleDialogButton(
-        this,
-        IDR_AURA_WINDOW_POSITION_RIGHT_RESTORE,
-        IDR_AURA_WINDOW_POSITION_RIGHT_RESTORE_H,
-        IDR_AURA_WINDOW_POSITION_RIGHT_RESTORE_P);
-  } else {
-    right_button_ = new BubbleDialogButton(
-        this,
-        IDR_AURA_WINDOW_POSITION_RIGHT,
-        IDR_AURA_WINDOW_POSITION_RIGHT_H,
-        IDR_AURA_WINDOW_POSITION_RIGHT_P);
-  }
-}
-
-void BubbleContentsButtonRow::AddMinimizeButton() {
-  minimize_button_ = new BubbleDialogButton(
-      this,
-      IDR_AURA_WINDOW_POSITION_MIDDLE,
-      IDR_AURA_WINDOW_POSITION_MIDDLE_H,
-      IDR_AURA_WINDOW_POSITION_MIDDLE_P);
-}
-
-}  // namespace ash
diff --git a/ash/frame/caption_buttons/bubble_contents_button_row.h b/ash/frame/caption_buttons/bubble_contents_button_row.h
deleted file mode 100644
index e3bfc61..0000000
--- a/ash/frame/caption_buttons/bubble_contents_button_row.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef ASH_FRAME_CAPTION_BUTTONS_BUBBLE_CONTENTS_BUTTON_ROW_H_
-#define ASH_FRAME_CAPTION_BUTTONS_BUBBLE_CONTENTS_BUTTON_ROW_H_
-
-#include "ash/wm/workspace/snap_types.h"
-#include "ui/views/controls/button/button.h"
-
-namespace views {
-class CustomButton;
-}
-
-namespace ash {
-
-class BubbleDialogButton;
-class MaximizeBubbleControllerBubble;
-
-// A class that creates all buttons and puts them into a view.
-class BubbleContentsButtonRow : public views::View,
-                                public views::ButtonListener {
- public:
-  explicit BubbleContentsButtonRow(MaximizeBubbleControllerBubble* bubble);
-  virtual ~BubbleContentsButtonRow();
-
-  // views::ButtonListener:
-  virtual void ButtonPressed(views::Button* sender,
-                             const ui::Event& event) OVERRIDE;
-
-  // Called from BubbleDialogButton.
-  void ButtonHovered(BubbleDialogButton* sender);
-
-  // Added for unit test: Retrieve the button for an action.
-  // |state| can be either SNAP_LEFT, SNAP_RIGHT or SNAP_MINIMIZE.
-  views::CustomButton* GetButtonForUnitTest(SnapType state);
-
-  MaximizeBubbleControllerBubble* bubble() { return bubble_; }
-
- private:
-  // Functions to add the left and right maximize / restore buttons.
-  void AddMaximizeLeftButton();
-  void AddMaximizeRightButton();
-  void AddMinimizeButton();
-
-  // The owning object which gets notifications.
-  MaximizeBubbleControllerBubble* bubble_;
-
-  // The created buttons for our menu.
-  BubbleDialogButton* left_button_;
-  BubbleDialogButton* minimize_button_;
-  BubbleDialogButton* right_button_;
-
-  DISALLOW_COPY_AND_ASSIGN(BubbleContentsButtonRow);
-};
-
-}  // namespace ash
-
-#endif  // ASH_FRAME_CAPTION_BUTTONS_BUBBLE_CONTENTS_BUTTON_ROW_H_
diff --git a/ash/frame/caption_buttons/caption_button_types.h b/ash/frame/caption_buttons/caption_button_types.h
index b481a02..7cf625a 100644
--- a/ash/frame/caption_buttons/caption_button_types.h
+++ b/ash/frame/caption_buttons/caption_button_types.h
@@ -7,14 +7,6 @@
 
 namespace ash {
 
-// These are the types of maximization we know.
-enum MaximizeBubbleFrameState {
-  FRAME_STATE_NONE = 0,
-  FRAME_STATE_FULL = 1,  // This is the full maximized state.
-  FRAME_STATE_SNAP_LEFT = 2,
-  FRAME_STATE_SNAP_RIGHT = 3
-};
-
 // These are the icon types that a caption button can have. The size button's
 // action (SnapType) can be different from its icon.
 enum CaptionButtonIcon {
diff --git a/ash/frame/caption_buttons/frame_caption_button_container_view.cc b/ash/frame/caption_buttons/frame_caption_button_container_view.cc
index f533f14..06103f4 100644
--- a/ash/frame/caption_buttons/frame_caption_button_container_view.cc
+++ b/ash/frame/caption_buttons/frame_caption_button_container_view.cc
@@ -7,9 +7,8 @@
 #include <cmath>
 
 #include "ash/ash_switches.h"
-#include "ash/frame/caption_buttons/alternate_frame_size_button.h"
 #include "ash/frame/caption_buttons/frame_caption_button.h"
-#include "ash/frame/caption_buttons/frame_maximize_button.h"
+#include "ash/frame/caption_buttons/frame_size_button.h"
 #include "ash/metrics/user_metrics_recorder.h"
 #include "ash/shell.h"
 #include "grit/ui_strings.h"  // Accessibility names
@@ -48,23 +47,14 @@
       minimize_button_(NULL),
       size_button_(NULL),
       close_button_(NULL) {
-  bool alternate_style = switches::UseAlternateFrameCaptionButtonStyle();
-
   // Insert the buttons left to right.
   minimize_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MINIMIZE);
   minimize_button_->SetAccessibleName(
       l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE));
-  // Hide |minimize_button_| when using the non-alternate button style because
-  // |size_button_| is capable of minimizing in this case.
-  minimize_button_->SetVisible(
-      minimize_allowed == MINIMIZE_ALLOWED &&
-      (alternate_style || !frame_->widget_delegate()->CanMaximize()));
+  minimize_button_->SetVisible(minimize_allowed == MINIMIZE_ALLOWED);
   AddChildView(minimize_button_);
 
-  if (alternate_style)
-    size_button_ = new AlternateFrameSizeButton(this, frame, this);
-  else
-    size_button_ = new FrameMaximizeButton(this, frame);
+  size_button_ = new FrameSizeButton(this, frame, this);
   size_button_->SetAccessibleName(
       l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE));
   UpdateSizeButtonVisibility(false);
@@ -79,12 +69,6 @@
 FrameCaptionButtonContainerView::~FrameCaptionButtonContainerView() {
 }
 
-FrameMaximizeButton*
-FrameCaptionButtonContainerView::GetOldStyleSizeButton() {
-  return switches::UseAlternateFrameCaptionButtonStyle() ?
-      NULL : static_cast<FrameMaximizeButton*>(size_button_);
-}
-
 void FrameCaptionButtonContainerView::SetButtonImages(
     CaptionButtonIcon icon,
     int icon_image_id,
diff --git a/ash/frame/caption_buttons/frame_caption_button_container_view.h b/ash/frame/caption_buttons/frame_caption_button_container_view.h
index d50350e..d57695a 100644
--- a/ash/frame/caption_buttons/frame_caption_button_container_view.h
+++ b/ash/frame/caption_buttons/frame_caption_button_container_view.h
@@ -6,7 +6,7 @@
 #define ASH_FRAME_CAPTION_BUTTONS_FRAME_CAPTION_BUTTON_CONTAINER_VIEW_H_
 
 #include "ash/ash_export.h"
-#include "ash/frame/caption_buttons/alternate_frame_size_button_delegate.h"
+#include "ash/frame/caption_buttons/frame_size_button_delegate.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/view.h"
 
@@ -15,15 +15,13 @@
 }
 
 namespace ash {
-class FrameCaptionButton;
-class FrameMaximizeButton;
 
 // Container view for the frame caption buttons. It performs the appropriate
 // action when a caption button is clicked.
 class ASH_EXPORT FrameCaptionButtonContainerView
     : public views::View,
       public views::ButtonListener,
-      public AlternateFrameSizeButtonDelegate {
+      public FrameSizeButtonDelegate {
  public:
   static const char kViewClassName[];
 
@@ -66,10 +64,6 @@
     DISALLOW_COPY_AND_ASSIGN(TestApi);
   };
 
-  // Returns the size button if using the old caption button style, returns NULL
-  // otherwise.
-  FrameMaximizeButton* GetOldStyleSizeButton();
-
   // Sets the resource ids of the images to paint the button for |icon|. The
   // FrameCaptionButtonContainerView will keep track of the images to use for
   // |icon| even if none of the buttons currently use |icon|.
@@ -130,7 +124,7 @@
   virtual void ButtonPressed(views::Button* sender,
                              const ui::Event& event) OVERRIDE;
 
-  // AlternateFrameSizeButtonDelegate:
+  // FrameSizeButtonDelegate:
   virtual bool IsMinimizeButtonVisible() const OVERRIDE;
   virtual void SetButtonsToNormal(Animate animate) OVERRIDE;
   virtual void SetButtonIcons(CaptionButtonIcon minimize_button_icon,
diff --git a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
index c0317bf..acd72c8 100644
--- a/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
+++ b/ash/frame/caption_buttons/frame_caption_button_container_view_unittest.cc
@@ -4,12 +4,9 @@
 
 #include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
 
-#include "ash/ash_switches.h"
 #include "ash/frame/caption_buttons/frame_caption_button.h"
 #include "ash/test/ash_test_base.h"
-#include "base/command_line.h"
 #include "grit/ash_resources.h"
-#include "ui/aura/window_event_dispatcher.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
 
@@ -102,29 +99,10 @@
   DISALLOW_COPY_AND_ASSIGN(FrameCaptionButtonContainerViewTest);
 };
 
-class FrameCaptionButtonContainerViewTestOldStyle
-    : public FrameCaptionButtonContainerViewTest {
- public:
-  FrameCaptionButtonContainerViewTestOldStyle() {
-  }
-
-  virtual ~FrameCaptionButtonContainerViewTestOldStyle() {
-  }
-
-  virtual void SetUp() OVERRIDE {
-    FrameCaptionButtonContainerViewTest::SetUp();
-    CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kAshDisableAlternateFrameCaptionButtonStyle);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FrameCaptionButtonContainerViewTestOldStyle);
-};
-
 // Test how the allowed actions affect which caption buttons are visible.
-TEST_F(FrameCaptionButtonContainerViewTestOldStyle, ButtonVisibility) {
-  // The minimize button should be hidden when both minimizing and maximizing
-  // are allowed because the size button can do both.
+TEST_F(FrameCaptionButtonContainerViewTest, ButtonVisibility) {
+  // All the buttons should be visible when minimizing and maximizing are
+  // allowed.
   scoped_ptr<views::Widget> widget_can_maximize(
       CreateTestWidget(MAXIMIZE_ALLOWED));
   FrameCaptionButtonContainerView container1(widget_can_maximize.get(),
@@ -132,11 +110,11 @@
   SetMockImages(&container1);
   container1.Layout();
   FrameCaptionButtonContainerView::TestApi t1(&container1);
-  EXPECT_FALSE(t1.minimize_button()->visible());
+  EXPECT_TRUE(t1.minimize_button()->visible());
   EXPECT_TRUE(t1.size_button()->visible());
   EXPECT_TRUE(t1.close_button()->visible());
   EXPECT_TRUE(CheckButtonsAtEdges(
-      &container1, *t1.size_button(), *t1.close_button()));
+      &container1, *t1.minimize_button(), *t1.close_button()));
 
   // The minimize button should be visible when minimizing is allowed but
   // maximizing is disallowed.
@@ -167,43 +145,4 @@
       &container3, *t3.close_button(), *t3.close_button()));
 }
 
-class FrameCaptionButtonContainerViewTestAlternateStyle
-    : public FrameCaptionButtonContainerViewTest {
- public:
-  FrameCaptionButtonContainerViewTestAlternateStyle() {
-  }
-
-  virtual ~FrameCaptionButtonContainerViewTestAlternateStyle() {
-  }
-
-  virtual void SetUp() OVERRIDE {
-    FrameCaptionButtonContainerViewTest::SetUp();
-    CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kAshEnableAlternateFrameCaptionButtonStyle);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FrameCaptionButtonContainerViewTestAlternateStyle);
-};
-
-// Test how the alternate button style affects which buttons are visible in the
-// default case.
-TEST_F(FrameCaptionButtonContainerViewTestAlternateStyle, ButtonVisibility) {
-  // Both the minimize button and the maximize button should be visible when
-  // both minimizing and maximizing are allowed when using the alternate
-  // button style.
-  scoped_ptr<views::Widget> widget_can_maximize(
-      CreateTestWidget(MAXIMIZE_ALLOWED));
-  FrameCaptionButtonContainerView container(widget_can_maximize.get(),
-      FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
-  SetMockImages(&container);
-  container.Layout();
-  FrameCaptionButtonContainerView::TestApi t(&container);
-  EXPECT_TRUE(t.minimize_button()->visible());
-  EXPECT_TRUE(t.size_button()->visible());
-  EXPECT_TRUE(t.close_button()->visible());
-  EXPECT_TRUE(CheckButtonsAtEdges(
-      &container, *t.minimize_button(), *t.close_button()));
-}
-
 }  // namespace ash
diff --git a/ash/frame/caption_buttons/frame_maximize_button.cc b/ash/frame/caption_buttons/frame_maximize_button.cc
deleted file mode 100644
index dc28c7a..0000000
--- a/ash/frame/caption_buttons/frame_maximize_button.cc
+++ /dev/null
@@ -1,547 +0,0 @@
-// Copyright 2013 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.
-
-#include "ash/frame/caption_buttons/frame_maximize_button.h"
-
-#include "ash/frame/caption_buttons/frame_maximize_button_observer.h"
-#include "ash/frame/caption_buttons/maximize_bubble_controller.h"
-#include "ash/metrics/user_metrics_recorder.h"
-#include "ash/screen_util.h"
-#include "ash/shelf/shelf_widget.h"
-#include "ash/shell.h"
-#include "ash/touch/touch_uma.h"
-#include "ash/wm/window_animations.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "ash/wm/wm_event.h"
-#include "ash/wm/workspace/phantom_window_controller.h"
-#include "grit/ash_strings.h"
-#include "ui/aura/window.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/events/event.h"
-#include "ui/events/event_handler.h"
-#include "ui/gfx/image/image.h"
-#include "ui/gfx/screen.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/window/non_client_view.h"
-
-namespace ash {
-
-namespace {
-
-// Delay before forcing an update of the snap location.
-const int kUpdateDelayMS = 400;
-
-// The delay of the bubble appearance.
-const int kBubbleAppearanceDelayMS = 500;
-
-// The minimum sanp size in percent of the screen width.
-const int kMinSnapSizePercent = 50;
-}
-
-// EscapeEventFilter is installed on the RootWindow to track when the escape key
-// is pressed. We use an EventFilter for this as the FrameMaximizeButton
-// normally does not get focus.
-class FrameMaximizeButton::EscapeEventFilter : public ui::EventHandler {
- public:
-  explicit EscapeEventFilter(FrameMaximizeButton* button);
-  virtual ~EscapeEventFilter();
-
-  // EventFilter overrides:
-  virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE;
-
- private:
-  FrameMaximizeButton* button_;
-
-  DISALLOW_COPY_AND_ASSIGN(EscapeEventFilter);
-};
-
-FrameMaximizeButton::EscapeEventFilter::EscapeEventFilter(
-    FrameMaximizeButton* button)
-    : button_(button) {
-  Shell::GetInstance()->AddPreTargetHandler(this);
-}
-
-FrameMaximizeButton::EscapeEventFilter::~EscapeEventFilter() {
-  Shell::GetInstance()->RemovePreTargetHandler(this);
-}
-
-void FrameMaximizeButton::EscapeEventFilter::OnKeyEvent(
-    ui::KeyEvent* event) {
-  if (event->type() == ui::ET_KEY_PRESSED &&
-      event->key_code() == ui::VKEY_ESCAPE) {
-    button_->Cancel(false);
-  }
-}
-
-// FrameMaximizeButton ---------------------------------------------------------
-
-FrameMaximizeButton::FrameMaximizeButton(views::ButtonListener* listener,
-                                         views::Widget* frame)
-    : FrameCaptionButton(listener, CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE),
-      frame_(frame),
-      observing_frame_(false),
-      is_snap_enabled_(false),
-      exceeded_drag_threshold_(false),
-      snap_type_(SNAP_NONE),
-      bubble_appearance_delay_ms_(kBubbleAppearanceDelayMS) {
-}
-
-FrameMaximizeButton::~FrameMaximizeButton() {
-  // Before the window gets destroyed, the maximizer dialog needs to be shut
-  // down since it would otherwise call into a deleted object.
-  maximizer_.reset();
-  if (observing_frame_)
-    OnWindowDestroying(frame_->GetNativeWindow());
-}
-
-void FrameMaximizeButton::AddObserver(FrameMaximizeButtonObserver* observer) {
-  observer_list_.AddObserver(observer);
-}
-
-void FrameMaximizeButton::RemoveObserver(
-    FrameMaximizeButtonObserver* observer) {
-  observer_list_.RemoveObserver(observer);
-}
-
-void FrameMaximizeButton::SnapButtonHovered(SnapType type) {
-  // Make sure to only show hover operations when no button is pressed and
-  // a similar snap operation in progress does not get re-applied.
-  if (is_snap_enabled_ || type == snap_type_)
-    return;
-  // Prime the mouse location with the center of the (local) button.
-  press_location_ = gfx::Point(width() / 2, height() / 2);
-  // Then get an adjusted mouse position to initiate the effect.
-  gfx::Point location = press_location_;
-  switch (type) {
-    case SNAP_LEFT:
-      location.set_x(location.x() - width());
-      break;
-    case SNAP_RIGHT:
-      location.set_x(location.x() + width());
-      break;
-    case SNAP_MINIMIZE:
-      location.set_y(location.y() + height());
-      break;
-    case SNAP_RESTORE:
-      // Simulate a mouse button move over the according button.
-      if (GetMaximizeBubbleFrameState() == FRAME_STATE_SNAP_LEFT)
-        location.set_x(location.x() - width());
-      else if (GetMaximizeBubbleFrameState() == FRAME_STATE_SNAP_RIGHT)
-        location.set_x(location.x() + width());
-      break;
-    case SNAP_MAXIMIZE:
-      break;
-    case SNAP_NONE:
-      Cancel(true);
-      return;
-    default:
-      // We should not come here.
-      NOTREACHED();
-  }
-  UpdateSnap(location);
-}
-
-void FrameMaximizeButton::ExecuteSnapAndCloseMenu(SnapType snap_type) {
-  Cancel(true);
-  // Tell our menu to close.
-  maximizer_.reset();
-  snap_type_ = snap_type;
-  Snap();
-}
-
-void FrameMaximizeButton::OnMaximizeBubbleShown(views::Widget* bubble) {
-  FOR_EACH_OBSERVER(FrameMaximizeButtonObserver,
-                    observer_list_,
-                    OnMaximizeBubbleShown(bubble));
-}
-
-void FrameMaximizeButton::DestroyMaximizeMenu() {
-  Cancel(false);
-}
-
-void FrameMaximizeButton::OnWindowBoundsChanged(
-    aura::Window* window,
-    const gfx::Rect& old_bounds,
-    const gfx::Rect& new_bounds) {
-  Cancel(false);
-}
-
-void FrameMaximizeButton::OnWindowPropertyChanged(aura::Window* window,
-                                                  const void* key,
-                                                  intptr_t old) {
-  Cancel(false);
-}
-
-void FrameMaximizeButton::OnWindowDestroying(aura::Window* window) {
-  maximizer_.reset();
-  if (observing_frame_) {
-    CHECK_EQ(frame_->GetNativeWindow(), window);
-    frame_->GetNativeWindow()->RemoveObserver(this);
-    frame_->RemoveObserver(this);
-    observing_frame_ = false;
-  }
-}
-
-void FrameMaximizeButton::OnWidgetActivationChanged(views::Widget* widget,
-                                                    bool active) {
-  // Upon losing focus, the bubble menu and the phantom window should hide.
-  if (!active)
-    Cancel(false);
-}
-
-bool FrameMaximizeButton::OnMousePressed(const ui::MouseEvent& event) {
-  // If we are already in a mouse click / drag operation, a second button down
-  // call will cancel (this addresses crbug.com/143755).
-  if (is_snap_enabled_) {
-    Cancel(false);
-  } else {
-    is_snap_enabled_ = event.IsOnlyLeftMouseButton();
-    if (is_snap_enabled_)
-      ProcessStartEvent(event);
-  }
-  FrameCaptionButton::OnMousePressed(event);
-  return true;
-}
-
-void FrameMaximizeButton::OnMouseEntered(const ui::MouseEvent& event) {
-  FrameCaptionButton::OnMouseEntered(event);
-  if (!maximizer_) {
-    DCHECK(GetWidget());
-    if (!observing_frame_) {
-      observing_frame_ = true;
-      frame_->GetNativeWindow()->AddObserver(this);
-      frame_->AddObserver(this);
-    }
-    maximizer_.reset(new MaximizeBubbleController(
-        this,
-        GetMaximizeBubbleFrameState(),
-        bubble_appearance_delay_ms_));
-  }
-}
-
-void FrameMaximizeButton::OnMouseExited(const ui::MouseEvent& event) {
-  FrameCaptionButton::OnMouseExited(event);
-  // Remove the bubble menu when the button is not pressed and the mouse is not
-  // within the bubble.
-  if (!is_snap_enabled_ && maximizer_) {
-    if (maximizer_->GetBubbleWindow()) {
-      gfx::Point screen_location = Shell::GetScreen()->GetCursorScreenPoint();
-      if (!maximizer_->GetBubbleWindow()->GetBoundsInScreen().Contains(
-              screen_location)) {
-        maximizer_.reset();
-        // Make sure that all remaining snap hover states get removed.
-        SnapButtonHovered(SNAP_NONE);
-      }
-    } else {
-      // The maximize dialog does not show up immediately after creating the
-      // |maximizer_|. Destroy the dialog therefore before it shows up.
-      maximizer_.reset();
-    }
-  }
-}
-
-bool FrameMaximizeButton::OnMouseDragged(const ui::MouseEvent& event) {
-  if (is_snap_enabled_)
-    ProcessUpdateEvent(event);
-  return FrameCaptionButton::OnMouseDragged(event);
-}
-
-void FrameMaximizeButton::OnMouseReleased(const ui::MouseEvent& event) {
-  maximizer_.reset();
-  bool snap_was_enabled = is_snap_enabled_;
-  if (!ProcessEndEvent(event) && snap_was_enabled)
-    FrameCaptionButton::OnMouseReleased(event);
-  // At this point |this| might be already destroyed.
-}
-
-void FrameMaximizeButton::OnMouseCaptureLost() {
-  Cancel(false);
-  FrameCaptionButton::OnMouseCaptureLost();
-}
-
-void FrameMaximizeButton::OnGestureEvent(ui::GestureEvent* event) {
-  if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
-    is_snap_enabled_ = true;
-    ProcessStartEvent(*event);
-    event->SetHandled();
-    return;
-  }
-
-  if (event->type() == ui::ET_GESTURE_TAP ||
-      (event->type() == ui::ET_GESTURE_SCROLL_END && is_snap_enabled_) ||
-      event->type() == ui::ET_SCROLL_FLING_START) {
-    // The position of the event may have changed from the previous event (both
-    // for TAP and SCROLL_END). So it is necessary to update the snap-state for
-    // the current event.
-    ProcessUpdateEvent(*event);
-    if (event->type() == ui::ET_GESTURE_TAP) {
-      snap_type_ = SnapTypeForLocation(event->location());
-      TouchUMA::GetInstance()->RecordGestureAction(
-          TouchUMA::GESTURE_FRAMEMAXIMIZE_TAP);
-    }
-    ProcessEndEvent(*event);
-    event->SetHandled();
-    return;
-  }
-
-  if (is_snap_enabled_) {
-    if (event->type() == ui::ET_GESTURE_END &&
-        event->details().touch_points() == 1) {
-      // The position of the event may have changed from the previous event. So
-      // it is necessary to update the snap-state for the current event.
-      ProcessUpdateEvent(*event);
-      snap_type_ = SnapTypeForLocation(event->location());
-      ProcessEndEvent(*event);
-      event->SetHandled();
-      return;
-    }
-
-    if (event->type() == ui::ET_GESTURE_SCROLL_UPDATE ||
-        event->type() == ui::ET_GESTURE_SCROLL_BEGIN) {
-      ProcessUpdateEvent(*event);
-      event->SetHandled();
-      return;
-    }
-  }
-
-  FrameCaptionButton::OnGestureEvent(event);
-}
-
-void FrameMaximizeButton::SetVisible(bool visible) {
-  views::View::SetVisible(visible);
-}
-
-void FrameMaximizeButton::ProcessStartEvent(const ui::LocatedEvent& event) {
-  DCHECK(is_snap_enabled_);
-  // Prepare the help menu.
-  if (!maximizer_) {
-    maximizer_.reset(new MaximizeBubbleController(
-        this,
-        GetMaximizeBubbleFrameState(),
-        bubble_appearance_delay_ms_));
-  } else {
-    // If the menu did not show up yet, we delay it even a bit more.
-    maximizer_->DelayCreation();
-  }
-  InstallEventFilter();
-  snap_type_ = SNAP_NONE;
-  press_location_ = event.location();
-  exceeded_drag_threshold_ = false;
-  update_timer_.Start(
-      FROM_HERE,
-      base::TimeDelta::FromMilliseconds(kUpdateDelayMS),
-      this,
-      &FrameMaximizeButton::UpdateSnapFromEventLocation);
-}
-
-void FrameMaximizeButton::ProcessUpdateEvent(const ui::LocatedEvent& event) {
-  DCHECK(is_snap_enabled_);
-  if (!exceeded_drag_threshold_) {
-    exceeded_drag_threshold_ = views::View::ExceededDragThreshold(
-        event.location() - press_location_);
-  }
-  if (exceeded_drag_threshold_)
-    UpdateSnap(event.location());
-}
-
-bool FrameMaximizeButton::ProcessEndEvent(const ui::LocatedEvent& event) {
-  update_timer_.Stop();
-  UninstallEventFilter();
-  bool should_snap = is_snap_enabled_;
-  is_snap_enabled_ = false;
-
-  // Remove our help bubble.
-  maximizer_.reset();
-
-  if (!should_snap || snap_type_ == SNAP_NONE)
-    return false;
-
-  SetState(views::CustomButton::STATE_NORMAL);
-  // SetState will not call SchedulePaint() if state was already set to
-  // STATE_NORMAL during a drag.
-  SchedulePaint();
-  phantom_window_.reset();
-  Snap();
-  return true;
-}
-
-void FrameMaximizeButton::Cancel(bool keep_menu_open) {
-  if (!keep_menu_open) {
-    maximizer_.reset();
-    UninstallEventFilter();
-    is_snap_enabled_ = false;
-  }
-  phantom_window_.reset();
-  snap_type_ = SNAP_NONE;
-  update_timer_.Stop();
-  SchedulePaint();
-}
-
-void FrameMaximizeButton::InstallEventFilter() {
-  if (escape_event_filter_)
-    return;
-
-  escape_event_filter_.reset(new EscapeEventFilter(this));
-}
-
-void FrameMaximizeButton::UninstallEventFilter() {
-  escape_event_filter_.reset(NULL);
-}
-
-void FrameMaximizeButton::UpdateSnapFromEventLocation() {
-  // If the drag threshold has been exceeded the snap location is up to date.
-  if (exceeded_drag_threshold_)
-    return;
-  exceeded_drag_threshold_ = true;
-  UpdateSnap(press_location_);
-}
-
-void FrameMaximizeButton::UpdateSnap(const gfx::Point& location) {
-  SnapType type = SnapTypeForLocation(location);
-  if (type == snap_type_)
-    return;
-
-  snap_type_ = type;
-  SchedulePaint();
-
-  if (snap_type_ == SNAP_NONE) {
-    phantom_window_.reset();
-    return;
-  }
-
-  if (!phantom_window_) {
-    phantom_window_.reset(
-        new PhantomWindowController(frame_->GetNativeWindow()));
-  }
-  if (maximizer_) {
-    phantom_window_->set_phantom_below_window(maximizer_->GetBubbleWindow());
-    maximizer_->SetSnapType(snap_type_);
-  }
-  phantom_window_->Show(ScreenBoundsForType(snap_type_));
-}
-
-SnapType FrameMaximizeButton::SnapTypeForLocation(
-    const gfx::Point& location) const {
-  MaximizeBubbleFrameState maximize_type = GetMaximizeBubbleFrameState();
-  gfx::Vector2d delta(location - press_location_);
-  if (!views::View::ExceededDragThreshold(delta))
-    return maximize_type != FRAME_STATE_FULL ? SNAP_MAXIMIZE : SNAP_RESTORE;
-  if (delta.x() < 0 && delta.y() > delta.x() && delta.y() < -delta.x())
-    return maximize_type == FRAME_STATE_SNAP_LEFT ? SNAP_RESTORE : SNAP_LEFT;
-  if (delta.x() > 0 && delta.y() > -delta.x() && delta.y() < delta.x())
-    return maximize_type == FRAME_STATE_SNAP_RIGHT ? SNAP_RESTORE : SNAP_RIGHT;
-  if (delta.y() > 0)
-    return SNAP_MINIMIZE;
-  return maximize_type != FRAME_STATE_FULL ? SNAP_MAXIMIZE : SNAP_RESTORE;
-}
-
-gfx::Rect FrameMaximizeButton::ScreenBoundsForType(SnapType type) const {
-  aura::Window* window = frame_->GetNativeWindow();
-  switch (type) {
-    case SNAP_LEFT:
-      return ScreenUtil::ConvertRectToScreen(
-          window->parent(),
-          wm::GetDefaultLeftSnappedWindowBoundsInParent(window));
-    case SNAP_RIGHT:
-      return ScreenUtil::ConvertRectToScreen(
-          window->parent(),
-          wm::GetDefaultRightSnappedWindowBoundsInParent(window));
-    case SNAP_MAXIMIZE:
-      return ScreenUtil::ConvertRectToScreen(
-          window->parent(),
-          ScreenUtil::GetMaximizedWindowBoundsInParent(window));
-    case SNAP_MINIMIZE: {
-      gfx::Rect rect = GetMinimizeAnimationTargetBoundsInScreen(window);
-      if (!rect.IsEmpty()) {
-        // PhantomWindowController insets slightly, outset it so the phantom
-        // doesn't appear inset.
-        rect.Inset(-8, -8);
-      }
-      return rect;
-    }
-    case SNAP_RESTORE: {
-      wm::WindowState* window_state = wm::GetWindowState(window);
-      return window_state->HasRestoreBounds() ?
-          window_state->GetRestoreBoundsInScreen() :
-          frame_->GetWindowBoundsInScreen();
-    }
-    case SNAP_NONE:
-      NOTREACHED();
-  }
-  return gfx::Rect();
-}
-
-void FrameMaximizeButton::Snap() {
-  Shell* shell = Shell::GetInstance();
-  wm::WindowState* window_state = wm::GetWindowState(frame_->GetNativeWindow());
-  switch (snap_type_) {
-    case SNAP_LEFT: {
-      const wm::WMEvent event(wm::WM_EVENT_SNAP_LEFT);
-      window_state->OnWMEvent(&event);
-      shell->metrics()->RecordUserMetricsAction(
-          UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT);
-      break;
-    }
-    case SNAP_RIGHT: {
-      const wm::WMEvent event(wm::WM_EVENT_SNAP_RIGHT);
-      window_state->OnWMEvent(&event);
-      shell->metrics()->RecordUserMetricsAction(
-          UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT);
-      break;
-    }
-    case SNAP_MAXIMIZE:
-      frame_->Maximize();
-      shell->metrics()->RecordUserMetricsAction(
-          UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE);
-      break;
-    case SNAP_MINIMIZE:
-      frame_->Minimize();
-      shell->metrics()->RecordUserMetricsAction(
-          UMA_WINDOW_MAXIMIZE_BUTTON_MINIMIZE);
-      break;
-    case SNAP_RESTORE:
-      frame_->Restore();
-      shell->metrics()->RecordUserMetricsAction(
-          UMA_WINDOW_MAXIMIZE_BUTTON_RESTORE);
-      break;
-    case SNAP_NONE:
-      NOTREACHED();
-  }
-}
-
-MaximizeBubbleFrameState
-FrameMaximizeButton::GetMaximizeBubbleFrameState() const {
-  wm::WindowState* window_state =
-      wm::GetWindowState(frame_->GetNativeWindow());
-  // When there are no restore bounds, we are in normal mode.
-  if (!window_state->HasRestoreBounds())
-    return FRAME_STATE_NONE;
-  // The normal maximized test can be used.
-  if (frame_->IsMaximized())
-    return FRAME_STATE_FULL;
-  // For Left/right maximize we need to check the dimensions.
-  gfx::Rect bounds = frame_->GetWindowBoundsInScreen();
-  gfx::Rect screen = Shell::GetScreen()->GetDisplayNearestWindow(
-      frame_->GetNativeView()).work_area();
-  if (bounds.width() < (screen.width() * kMinSnapSizePercent) / 100)
-    return FRAME_STATE_NONE;
-  // We might still have a horizontally filled window at this point which we
-  // treat as no special state.
-  if (bounds.y() != screen.y() || bounds.height() != screen.height())
-    return FRAME_STATE_NONE;
-
-  // We have to be in a maximize mode at this point.
-  if (bounds.x() == screen.x())
-    return FRAME_STATE_SNAP_LEFT;
-  if (bounds.right() == screen.right())
-    return FRAME_STATE_SNAP_RIGHT;
-  // If we come here, it is likely caused by the fact that the
-  // "VerticalResizeDoubleClick" stored a restore rectangle. In that case
-  // we allow all maximize operations (and keep the restore rectangle).
-  return FRAME_STATE_NONE;
-}
-
-}  // namespace ash
diff --git a/ash/frame/caption_buttons/frame_maximize_button.h b/ash/frame/caption_buttons/frame_maximize_button.h
deleted file mode 100644
index 29d89e8..0000000
--- a/ash/frame/caption_buttons/frame_maximize_button.h
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef ASH_FRAME_CAPTION_BUTTONS_FRAME_MAXIMIZE_BUTTON_H_
-#define ASH_FRAME_CAPTION_BUTTONS_FRAME_MAXIMIZE_BUTTON_H_
-
-#include "ash/ash_export.h"
-#include "ash/frame/caption_buttons/caption_button_types.h"
-#include "ash/frame/caption_buttons/frame_caption_button.h"
-#include "ash/wm/workspace/snap_types.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/observer_list.h"
-#include "base/timer/timer.h"
-#include "ui/aura/window_observer.h"
-#include "ui/views/widget/widget_observer.h"
-
-namespace views {
-class Widget;
-}
-
-namespace ash {
-class FrameMaximizeButtonObserver;
-class MaximizeBubbleController;
-class PhantomWindowController;
-
-// Button used for the maximize control on the frame. Handles snapping logic.
-class ASH_EXPORT FrameMaximizeButton : public FrameCaptionButton,
-                                       public views::WidgetObserver,
-                                       public aura::WindowObserver {
- public:
-  FrameMaximizeButton(views::ButtonListener* listener,
-                      views::Widget* frame);
-  virtual ~FrameMaximizeButton();
-
-  void AddObserver(FrameMaximizeButtonObserver* observer);
-  void RemoveObserver(FrameMaximizeButtonObserver* observer);
-
-  // Updates |snap_type_| based on a a given snap type. This is used by
-  // external hover events from the button menu.
-  void SnapButtonHovered(SnapType type);
-
-  // The user clicked the |type| button and the action needs to be performed,
-  // which will at the same time close the window.
-  void ExecuteSnapAndCloseMenu(SnapType type);
-
-  // Called by the MaximizeBubbleController when the maximize bubble is shown.
-  void OnMaximizeBubbleShown(views::Widget* bubble);
-
-  // Remove the maximize menu from the screen (and destroy it).
-  void DestroyMaximizeMenu();
-
-  // Returns true when the user clicks and drags the button.
-  bool is_snap_enabled() const { return is_snap_enabled_; }
-
-  // WindowObserver overrides:
-  virtual void OnWindowBoundsChanged(aura::Window* window,
-                                     const gfx::Rect& old_bounds,
-                                     const gfx::Rect& new_bounds) OVERRIDE;
-  virtual void OnWindowPropertyChanged(aura::Window* window,
-                                       const void* key,
-                                       intptr_t old) OVERRIDE;
-  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
-
-  // WidgetObserver overrides:
-  virtual void OnWidgetActivationChanged(views::Widget* widget,
-                                        bool active) OVERRIDE;
-
-  // ImageButton overrides:
-  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
-  virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
-  virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
-  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
-  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
-  virtual void OnMouseCaptureLost() OVERRIDE;
-
-  // ui::EventHandler overrides:
-  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
-
-  // views::View overwrite:
-  virtual void SetVisible(bool visible) OVERRIDE;
-
-  // Unit test overwrite: Change the UI delay used for the bubble show up.
-  void set_bubble_appearance_delay_ms(int bubble_appearance_delay_ms) {
-    bubble_appearance_delay_ms_ = bubble_appearance_delay_ms;
-  }
-
-  // Unit test accessor for the maximize bubble.
-  MaximizeBubbleController* maximizer() { return maximizer_.get(); }
-
-  // Unit test to see if phantom window is open.
-  bool phantom_window_open() { return phantom_window_.get() != NULL; }
-
- private:
-  class EscapeEventFilter;
-
-  // Initializes the snap-gesture based on the event. This should only be called
-  // when the event is confirmed to have started a snap gesture.
-  void ProcessStartEvent(const ui::LocatedEvent& event);
-
-  // Updates the snap-state based on the current event. This should only be
-  // called after the snap gesture has already started.
-  void ProcessUpdateEvent(const ui::LocatedEvent& event);
-
-  // Returns true if the window was snapped. Returns false otherwise.
-  bool ProcessEndEvent(const ui::LocatedEvent& event);
-
-  // Cancels snap behavior. If |keep_menu_open| is set, a possibly opened
-  // bubble help will remain open.
-  void Cancel(bool keep_menu_open);
-
-  // Installs/uninstalls an EventFilter to track when escape is pressed.
-  void InstallEventFilter();
-  void UninstallEventFilter();
-
-  // Updates the snap position from the event location. This is invoked by
-  // |update_timer_|.
-  void UpdateSnapFromEventLocation();
-
-  // Updates |snap_type_| based on a mouse drag.
-  void UpdateSnap(const gfx::Point& location);
-
-  // Returns the type of snap based on the specified location.
-  SnapType SnapTypeForLocation(const gfx::Point& location) const;
-
-  // Returns the bounds of the resulting window for the specified type.
-  gfx::Rect ScreenBoundsForType(SnapType type) const;
-
-  // Snaps the window to the current snap position determined by |snap_type_|.
-  void Snap();
-
-  // Determine the maximize type of this window.
-  MaximizeBubbleFrameState GetMaximizeBubbleFrameState() const;
-
-  // Widget that the maximize button acts on. This is different than the widget
-  // which contains the button in the case of AppNonClientFrameViewAsh.
-  views::Widget* frame_;
-
-  // True if we have put observers on |frame_|.
-  bool observing_frame_;
-
-  // Renders the snap position.
-  scoped_ptr<PhantomWindowController> phantom_window_;
-
-  // Is snapping enabled? Set on press so that in drag we know whether we
-  // should show the snap locations.
-  bool is_snap_enabled_;
-
-  // Did the user drag far enough to trigger snapping?
-  bool exceeded_drag_threshold_;
-
-  // Location of the press.
-  gfx::Point press_location_;
-
-  // Current snap type.
-  SnapType snap_type_;
-
-  scoped_ptr<EscapeEventFilter> escape_event_filter_;
-
-  base::OneShotTimer<FrameMaximizeButton> update_timer_;
-
-  scoped_ptr<MaximizeBubbleController> maximizer_;
-
-  // The delay of the bubble appearance.
-  int bubble_appearance_delay_ms_;
-
-  ObserverList<FrameMaximizeButtonObserver> observer_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(FrameMaximizeButton);
-};
-
-}  // namespace ash
-
-#endif  // ASH_FRAME_CAPTION_BUTTONS_FRAME_MAXIMIZE_BUTTON_H_
diff --git a/ash/frame/caption_buttons/frame_maximize_button_observer.h b/ash/frame/caption_buttons/frame_maximize_button_observer.h
deleted file mode 100644
index 57bdd47..0000000
--- a/ash/frame/caption_buttons/frame_maximize_button_observer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef ASH_FRAME_CAPTION_BUTTONS_FRAME_MAXIMIZE_BUTTON_OBSERVER_H_
-#define ASH_FRAME_CAPTION_BUTTONS_FRAME_MAXIMIZE_BUTTON_OBSERVER_H_
-
-#include "ash/ash_export.h"
-
-namespace views {
-class Widget;
-}
-
-namespace ash {
-
-class ASH_EXPORT FrameMaximizeButtonObserver {
- public:
-  virtual ~FrameMaximizeButtonObserver() {}
-
-  // Called when the maximize button's help bubble is shown.
-  virtual void OnMaximizeBubbleShown(views::Widget* bubble) = 0;
-};
-
-}  // namespace ash
-
-#endif  // ASH_FRAME_CAPTION_BUTTONS_FRAME_MAXIMIZE_BUTTON_OBSERVER_H_
diff --git a/ash/frame/caption_buttons/frame_maximize_button_unittest.cc b/ash/frame/caption_buttons/frame_maximize_button_unittest.cc
deleted file mode 100644
index 06305d1..0000000
--- a/ash/frame/caption_buttons/frame_maximize_button_unittest.cc
+++ /dev/null
@@ -1,814 +0,0 @@
-// Copyright 2013 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.
-
-#include "ash/frame/caption_buttons/frame_maximize_button.h"
-
-#include "ash/ash_switches.h"
-#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
-#include "ash/frame/caption_buttons/maximize_bubble_controller.h"
-#include "ash/shell.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/wm/window_state.h"
-#include "ash/wm/window_util.h"
-#include "base/command_line.h"
-#include "grit/ash_resources.h"
-#include "ui/aura/client/focus_client.h"
-#include "ui/aura/test/event_generator.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_tree_host.h"
-#include "ui/events/event_processor.h"
-#include "ui/events/event_utils.h"
-#include "ui/events/gestures/gesture_configuration.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_delegate.h"
-
-namespace ash {
-namespace test {
-
-namespace {
-
-class CancelCallbackHandler {
- public:
-  CancelCallbackHandler(int update_events_before_cancel,
-                        FrameMaximizeButton* maximize_button) :
-      update_events_before_cancel_(update_events_before_cancel),
-      maximize_button_(maximize_button) {}
-  virtual ~CancelCallbackHandler() {}
-
-  void CountedCancelCallback(ui::EventType event_type,
-                             const gfx::Vector2dF& pos) {
-    if (event_type == ui::ET_GESTURE_SCROLL_UPDATE &&
-        !(--update_events_before_cancel_)) {
-      // Make sure that we are in the middle of a resizing operation, cancel it
-      // and then test that it is exited.
-      EXPECT_TRUE(maximize_button_->is_snap_enabled());
-      maximize_button_->DestroyMaximizeMenu();
-      EXPECT_FALSE(maximize_button_->is_snap_enabled());
-    }
-  }
-
- private:
-  // When this counter reaches 0, the gesture maximize action gets cancelled.
-  int update_events_before_cancel_;
-
-  // The maximize button which needs to get informed of the gesture termination.
-  FrameMaximizeButton* maximize_button_;
-
-  DISALLOW_COPY_AND_ASSIGN(CancelCallbackHandler);
-};
-
-class TestWidgetDelegate : public views::WidgetDelegateView {
- public:
-  TestWidgetDelegate() {}
-  virtual ~TestWidgetDelegate() {}
-
-  // views::WidgetDelegate overrides:
-  virtual views::View* GetContentsView() OVERRIDE {
-    return this;
-  }
-  virtual bool CanResize() const OVERRIDE {
-    return true;
-  }
-  virtual bool CanMaximize() const OVERRIDE {
-    return true;
-  }
-
-  ash::FrameCaptionButtonContainerView* caption_button_container() {
-    return caption_button_container_;
-  }
-
- private:
-  // Overridden from views::View:
-  virtual void Layout() OVERRIDE {
-    caption_button_container_->Layout();
-
-    // Right align the caption button container.
-    gfx::Size preferred_size = caption_button_container_->GetPreferredSize();
-    caption_button_container_->SetBounds(width() - preferred_size.width(), 0,
-        preferred_size.width(), preferred_size.height());
-  }
-
-  virtual void ViewHierarchyChanged(
-      const ViewHierarchyChangedDetails& details) OVERRIDE {
-    if (details.is_add && details.child == this) {
-      caption_button_container_ = new FrameCaptionButtonContainerView(
-          GetWidget(), FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
-
-      // Set arbitrary images for the container's buttons so that the buttons
-      // have non-empty sizes.
-      for (int icon = 0; icon < CAPTION_BUTTON_ICON_COUNT; ++icon) {
-        caption_button_container_->SetButtonImages(
-            static_cast<CaptionButtonIcon>(icon),
-            IDR_AURA_WINDOW_CONTROL_ICON_CLOSE,
-            IDR_AURA_WINDOW_CONTROL_ICON_CLOSE_I,
-            IDR_AURA_WINDOW_CONTROL_BACKGROUND_H,
-            IDR_AURA_WINDOW_CONTROL_BACKGROUND_P);
-      }
-
-      AddChildView(caption_button_container_);
-    }
-  }
-
-  // Not owned.
-  ash::FrameCaptionButtonContainerView* caption_button_container_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate);
-};
-
-}  // namespace
-
-class FrameMaximizeButtonTest : public ash::test::AshTestBase {
- public:
-  FrameMaximizeButtonTest() {}
-  virtual ~FrameMaximizeButtonTest() {}
-
-  // The returned widget takes ownership of |delegate|.
-  views::Widget* CreateWidget(views::WidgetDelegate* delegate) {
-    views::Widget::InitParams params(
-        views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
-    views::Widget* widget = new views::Widget;
-    params.context = CurrentContext();
-    params.delegate = delegate;
-    params.bounds = gfx::Rect(10, 10, 100, 100);
-    params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
-    widget->Init(params);
-    widget->Show();
-    return widget;
-  }
-
-  void CloseWidget() {
-    if (widget_)
-      widget_->CloseNow();
-    widget_ = NULL;
-  }
-
-  virtual void SetUp() OVERRIDE {
-    AshTestBase::SetUp();
-
-    CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kAshDisableAlternateFrameCaptionButtonStyle);
-
-    TestWidgetDelegate* delegate = new TestWidgetDelegate();
-    widget_ = CreateWidget(delegate);
-    FrameCaptionButtonContainerView* caption_button_container =
-        delegate->caption_button_container();
-
-    FrameCaptionButtonContainerView::TestApi test(caption_button_container);
-    maximize_button_ = static_cast<FrameMaximizeButton*>(
-        test.size_button());
-  }
-
-  virtual void TearDown() OVERRIDE {
-    CloseWidget();
-    AshTestBase::TearDown();
-  }
-
-  views::Widget* widget() { return widget_; }
-
-  FrameMaximizeButton* maximize_button() { return maximize_button_; }
-
- private:
-  views::Widget* widget_;
-  FrameMaximizeButton* maximize_button_;
-
-  DISALLOW_COPY_AND_ASSIGN(FrameMaximizeButtonTest);
-};
-
-// Tests that clicking on the resize-button toggles between maximize and normal
-// state.
-TEST_F(FrameMaximizeButtonTest, ResizeButtonToggleMaximize) {
-  wm::WindowState* window_state =
-      wm::GetWindowState(widget()->GetNativeWindow());
-  views::View* view = maximize_button();
-  gfx::Point center = view->GetBoundsInScreen().CenterPoint();
-
-  aura::test::EventGenerator generator(
-      window_state->window()->GetRootWindow(), center);
-
-  EXPECT_FALSE(window_state->IsMaximized());
-
-  generator.ClickLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(window_state->IsMaximized());
-
-  center = view->GetBoundsInScreen().CenterPoint();
-  generator.MoveMouseTo(center);
-  generator.ClickLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(window_state->IsMaximized());
-
-  generator.GestureTapAt(view->GetBoundsInScreen().CenterPoint());
-  EXPECT_TRUE(window_state->IsMaximized());
-
-  generator.GestureTapAt(view->GetBoundsInScreen().CenterPoint());
-  EXPECT_FALSE(window_state->IsMaximized());
-
-  generator.GestureTapDownAndUp(view->GetBoundsInScreen().CenterPoint());
-  EXPECT_TRUE(window_state->IsMaximized());
-
-  generator.GestureTapDownAndUp(view->GetBoundsInScreen().CenterPoint());
-  EXPECT_FALSE(window_state->IsMaximized());
-}
-
-#if defined(OS_WIN)
-// RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
-#define MAYBE_ResizeButtonDrag DISABLED_ResizeButtonDrag
-#else
-#define MAYBE_ResizeButtonDrag ResizeButtonDrag
-#endif
-
-// Tests that click+dragging on the resize-button tiles or minimizes the window.
-TEST_F(FrameMaximizeButtonTest, MAYBE_ResizeButtonDrag) {
-  aura::Window* window = widget()->GetNativeWindow();
-  views::View* view = maximize_button();
-  gfx::Point center = view->GetBoundsInScreen().CenterPoint();
-
-  aura::test::EventGenerator generator(window->GetRootWindow(), center);
-
-  wm::WindowState* window_state = wm::GetWindowState(window);
-  EXPECT_TRUE(window_state->IsNormalStateType());
-
-  // Snap right.
-  {
-    generator.PressLeftButton();
-    generator.MoveMouseBy(10, 0);
-    generator.ReleaseLeftButton();
-    RunAllPendingInMessageLoop();
-
-    EXPECT_FALSE(window_state->IsMaximized());
-    EXPECT_FALSE(window_state->IsMinimized());
-    EXPECT_EQ(wm::GetDefaultRightSnappedWindowBoundsInParent(window).ToString(),
-              window->bounds().ToString());
-  }
-
-  // Snap left.
-  {
-    center = view->GetBoundsInScreen().CenterPoint();
-    generator.MoveMouseTo(center);
-    generator.PressLeftButton();
-    generator.MoveMouseBy(-10, 0);
-    generator.ReleaseLeftButton();
-    RunAllPendingInMessageLoop();
-
-    EXPECT_FALSE(window_state->IsMaximized());
-    EXPECT_FALSE(window_state->IsMinimized());
-    EXPECT_EQ(wm::GetDefaultLeftSnappedWindowBoundsInParent(window).ToString(),
-              window->bounds().ToString());
-  }
-
-  // Minimize.
-  {
-    center = view->GetBoundsInScreen().CenterPoint();
-    generator.MoveMouseTo(center);
-    generator.PressLeftButton();
-    generator.MoveMouseBy(0, 10);
-    generator.ReleaseLeftButton();
-    RunAllPendingInMessageLoop();
-
-    EXPECT_TRUE(window_state->IsMinimized());
-  }
-
-  window_state->Restore();
-
-  // Now test the same behaviour for gesture events.
-
-  // Snap right.
-  {
-    center = view->GetBoundsInScreen().CenterPoint();
-    gfx::Point end = center;
-    end.Offset(80, 0);
-    generator.GestureScrollSequence(center, end,
-        base::TimeDelta::FromMilliseconds(100),
-        3);
-    RunAllPendingInMessageLoop();
-
-    EXPECT_FALSE(window_state->IsMaximized());
-    EXPECT_FALSE(window_state->IsMinimized());
-    // This is a short resizing distance and different touch behavior
-    // applies which leads in half of the screen being used.
-    EXPECT_EQ("400,0 400x553", window->bounds().ToString());
-  }
-
-  // Snap left.
-  {
-    center = view->GetBoundsInScreen().CenterPoint();
-    gfx::Point end = center;
-    end.Offset(-80, 0);
-    generator.GestureScrollSequence(center, end,
-        base::TimeDelta::FromMilliseconds(100),
-        3);
-    RunAllPendingInMessageLoop();
-
-    EXPECT_FALSE(window_state->IsMaximized());
-    EXPECT_FALSE(window_state->IsMinimized());
-    EXPECT_EQ(wm::GetDefaultLeftSnappedWindowBoundsInParent(window).ToString(),
-              window->bounds().ToString());
-  }
-
-  // Minimize.
-  {
-    center = view->GetBoundsInScreen().CenterPoint();
-    gfx::Point end = center;
-    end.Offset(0, 40);
-    generator.GestureScrollSequence(center, end,
-        base::TimeDelta::FromMilliseconds(100),
-        3);
-    RunAllPendingInMessageLoop();
-
-    EXPECT_TRUE(window_state->IsMinimized());
-  }
-
-  // Test with gesture events.
-}
-
-// Test that closing the (browser) window with an opened balloon does not
-// crash the system. In other words: Make sure that shutting down the frame
-// destroys the opened balloon in an orderly fashion.
-TEST_F(FrameMaximizeButtonTest, MaximizeButtonExternalShutDown) {
-  aura::Window* window = widget()->GetNativeWindow();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-  maximize_button->set_bubble_appearance_delay_ms(0);
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);
-
-  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
-  EXPECT_FALSE(maximize_button->maximizer());
-  EXPECT_TRUE(wm::GetWindowState(window)->IsNormalStateType());
-
-  // Move the mouse cursor over the button to bring up the maximizer bubble.
-  generator.MoveMouseTo(button_pos);
-  EXPECT_TRUE(maximize_button->maximizer());
-
-  // Even though the widget is closing the bubble menu should not crash upon
-  // its delayed destruction.
-  CloseWidget();
-}
-
-// Test that maximizing the browser after hovering in does not crash the system
-// when the observer gets removed in the bubble destruction process.
-TEST_F(FrameMaximizeButtonTest, MaximizeOnHoverThenClick) {
-  aura::Window* window = widget()->GetNativeWindow();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-  maximize_button->set_bubble_appearance_delay_ms(0);
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);
-
-  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
-  EXPECT_FALSE(maximize_button->maximizer());
-  EXPECT_TRUE(wm::GetWindowState(window)->IsNormalStateType());
-
-  // Move the mouse cursor over the button to bring up the maximizer bubble.
-  generator.MoveMouseTo(button_pos);
-  EXPECT_TRUE(maximize_button->maximizer());
-  generator.ClickLeftButton();
-  EXPECT_TRUE(wm::GetWindowState(window)->IsMaximized());
-}
-
-// Test that hovering over a button in the balloon dialog will show the phantom
-// window. Moving then away from the button will hide it again. Then check that
-// pressing and dragging the button itself off the button will also release the
-// phantom window.
-TEST_F(FrameMaximizeButtonTest, MaximizeLeftButtonDragOut) {
-  aura::Window* window = widget()->GetNativeWindow();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-  maximize_button->set_bubble_appearance_delay_ms(0);
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);
-
-  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
-  EXPECT_FALSE(maximize_button->maximizer());
-  EXPECT_TRUE(wm::GetWindowState(window)->IsNormalStateType());
-  EXPECT_FALSE(maximize_button->phantom_window_open());
-
-  // Move the mouse cursor over the button to bring up the maximizer bubble.
-  generator.MoveMouseTo(button_pos);
-  EXPECT_TRUE(maximize_button->maximizer());
-
-  // Move the mouse over the left maximize button.
-  gfx::Point left_max_pos = maximize_button->maximizer()->
-      GetButtonForUnitTest(SNAP_LEFT)->GetBoundsInScreen().CenterPoint();
-
-  generator.MoveMouseTo(left_max_pos);
-  // Expect the phantom window to be open.
-  EXPECT_TRUE(maximize_button->phantom_window_open());
-
-  // Move away to see the window being destroyed.
-  generator.MoveMouseTo(off_pos);
-  EXPECT_FALSE(maximize_button->phantom_window_open());
-
-  // Move back over the button.
-  generator.MoveMouseTo(button_pos);
-  generator.MoveMouseTo(left_max_pos);
-  EXPECT_TRUE(maximize_button->phantom_window_open());
-
-  // Press button and drag out of dialog.
-  generator.PressLeftButton();
-  generator.MoveMouseTo(off_pos);
-  generator.ReleaseLeftButton();
-
-  // Check that the phantom window is also gone.
-  EXPECT_FALSE(maximize_button->phantom_window_open());
-}
-
-// Test that clicking a button in the maximizer bubble (in this case the
-// maximize left button) will do the requested action.
-TEST_F(FrameMaximizeButtonTest, MaximizeLeftByButton) {
-  aura::Window* window = widget()->GetNativeWindow();
-
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-  maximize_button->set_bubble_appearance_delay_ms(0);
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);
-
-  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
-  EXPECT_FALSE(maximize_button->maximizer());
-  EXPECT_TRUE(wm::GetWindowState(window)->IsNormalStateType());
-  EXPECT_FALSE(maximize_button->phantom_window_open());
-
-  // Move the mouse cursor over the button to bring up the maximizer bubble.
-  generator.MoveMouseTo(button_pos);
-  EXPECT_TRUE(maximize_button->maximizer());
-
-  // Move the mouse over the left maximize button.
-  gfx::Point left_max_pos = maximize_button->maximizer()->
-      GetButtonForUnitTest(SNAP_LEFT)->GetBoundsInScreen().CenterPoint();
-  generator.MoveMouseTo(left_max_pos);
-  EXPECT_TRUE(maximize_button->phantom_window_open());
-  generator.ClickLeftButton();
-
-  EXPECT_FALSE(maximize_button->maximizer());
-  EXPECT_FALSE(maximize_button->phantom_window_open());
-
-  wm::WindowState* window_state = wm::GetWindowState(window);
-  EXPECT_FALSE(window_state->IsMaximized());
-  EXPECT_FALSE(window_state->IsMinimized());
-  EXPECT_EQ(wm::GetDefaultLeftSnappedWindowBoundsInParent(window).ToString(),
-            window->bounds().ToString());
-}
-
-// Test that the activation focus does not change when the bubble gets shown.
-TEST_F(FrameMaximizeButtonTest, MaximizeKeepFocus) {
-  aura::Window* window = widget()->GetNativeWindow();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-  maximize_button->set_bubble_appearance_delay_ms(0);
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);
-
-  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
-  EXPECT_FALSE(maximize_button->maximizer());
-  EXPECT_TRUE(wm::GetWindowState(window)->IsNormalStateType());
-
-  aura::Window* active =
-      aura::client::GetFocusClient(window)->GetFocusedWindow();
-
-  // Move the mouse cursor over the button to bring up the maximizer bubble.
-  generator.MoveMouseTo(button_pos);
-  EXPECT_TRUE(maximize_button->maximizer());
-
-  // Check that the focused window is still the same.
-  EXPECT_EQ(active, aura::client::GetFocusClient(window)->GetFocusedWindow());
-}
-
-TEST_F(FrameMaximizeButtonTest, MaximizeTap) {
-  aura::Window* window = widget()->GetNativeWindow();
-  aura::Window* root_window = window->GetRootWindow();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-
-  const int touch_default_radius =
-      ui::GestureConfiguration::default_radius();
-  ui::GestureConfiguration::set_default_radius(0);
-
-  ui::EventProcessor* dispatcher = root_window->GetHost()->event_processor();
-  const int kTouchId = 2;
-  ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
-                       button_pos,
-                       kTouchId,
-                       ui::EventTimeForNow());
-  ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
-  ASSERT_FALSE(details.dispatcher_destroyed);
-
-  button_pos.Offset(9, 8);
-  ui::TouchEvent release(
-      ui::ET_TOUCH_RELEASED,
-      button_pos,
-      kTouchId,
-      press.time_stamp() + base::TimeDelta::FromMilliseconds(50));
-  details = dispatcher->OnEventFromSource(&release);
-  ASSERT_FALSE(details.dispatcher_destroyed);
-
-  ui::GestureConfiguration::set_default_radius(touch_default_radius);
-}
-
-// Test that only the left button will activate the maximize button.
-TEST_F(FrameMaximizeButtonTest, OnlyLeftButtonMaximizes) {
-  aura::Window* window = widget()->GetNativeWindow();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-  maximize_button->set_bubble_appearance_delay_ms(0);
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);
-
-  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
-  EXPECT_FALSE(maximize_button->maximizer());
-  wm::WindowState* window_state = wm::GetWindowState(window);
-  EXPECT_TRUE(window_state->IsNormalStateType());
-  EXPECT_FALSE(window_state->IsMaximized());
-
-  // Move the mouse cursor over the button.
-  generator.MoveMouseTo(button_pos);
-  EXPECT_TRUE(maximize_button->maximizer());
-  EXPECT_FALSE(maximize_button->phantom_window_open());
-
-  // After pressing the left button the button should get triggered.
-  generator.PressLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_TRUE(maximize_button->is_snap_enabled());
-  EXPECT_FALSE(window_state->IsMaximized());
-
-  // Pressing the right button then should cancel the operation.
-  generator.PressRightButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(maximize_button->maximizer());
-
-  // After releasing the second button the window shouldn't be maximized.
-  generator.ReleaseRightButton();
-  generator.ReleaseLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(window_state->IsMaximized());
-
-  // Second experiment: Starting with right should also not trigger.
-  generator.MoveMouseTo(off_pos);
-  generator.MoveMouseTo(button_pos);
-  EXPECT_TRUE(maximize_button->maximizer());
-
-  // Pressing first the right button should not activate.
-  generator.PressRightButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(maximize_button->is_snap_enabled());
-
-  // Pressing then additionally the left button shouldn't activate either.
-  generator.PressLeftButton();
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(maximize_button->is_snap_enabled());
-  generator.ReleaseRightButton();
-  generator.ReleaseLeftButton();
-  EXPECT_FALSE(window_state->IsMaximized());
-}
-
-// Click a button of window maximize functionality.
-// If |snap_type| is SNAP_NONE the FrameMaximizeButton gets clicked, otherwise
-// the associated snap button.
-// |Window| is the window which owns the maximize button.
-// |maximize_button| is the FrameMaximizeButton which controls the window.
-void ClickMaxButton(
-    ash::FrameMaximizeButton* maximize_button,
-    aura::Window* window,
-    SnapType snap_type) {
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);
-
-  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
-  generator.MoveMouseTo(off_pos);
-  EXPECT_FALSE(maximize_button->maximizer());
-  EXPECT_FALSE(maximize_button->phantom_window_open());
-
-  // Move the mouse cursor over the button.
-  generator.MoveMouseTo(button_pos);
-  EXPECT_TRUE(maximize_button->maximizer());
-  EXPECT_FALSE(maximize_button->phantom_window_open());
-
-  if (snap_type != SNAP_NONE) {
-    gfx::Point left_max_pos = maximize_button->maximizer()->
-        GetButtonForUnitTest(snap_type)->GetBoundsInScreen().CenterPoint();
-    generator.MoveMouseTo(left_max_pos);
-    EXPECT_TRUE(maximize_button->phantom_window_open());
-  }
-  // After pressing the left button the button should get triggered.
-  generator.ClickLeftButton();
-  EXPECT_FALSE(maximize_button->maximizer());
-}
-
-// Test that the restore from left/right maximize is properly done.
-TEST_F(FrameMaximizeButtonTest, MaximizeLeftRestore) {
-  aura::Window* window = widget()->GetNativeWindow();
-  gfx::Rect initial_bounds = widget()->GetWindowBoundsInScreen();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-  maximize_button->set_bubble_appearance_delay_ms(0);
-
-  ClickMaxButton(maximize_button, window, SNAP_LEFT);
-  wm::WindowState* window_state = wm::GetWindowState(window);
-  // The window should not be maximized.
-  EXPECT_FALSE(window_state->IsMaximized());
-  // But the bounds should be different.
-  gfx::Rect new_bounds = widget()->GetWindowBoundsInScreen();
-  EXPECT_EQ(0, new_bounds.x());
-  EXPECT_EQ(0, new_bounds.y());
-
-  // Now click the same button again to see that it restores.
-  ClickMaxButton(maximize_button, window, SNAP_LEFT);
-  // But the bounds should be restored.
-  new_bounds = widget()->GetWindowBoundsInScreen();
-  EXPECT_EQ(new_bounds.x(), initial_bounds.x());
-  EXPECT_EQ(new_bounds.y(), initial_bounds.x());
-  EXPECT_EQ(new_bounds.width(), initial_bounds.width());
-  EXPECT_EQ(new_bounds.height(), initial_bounds.height());
-  // Make sure that there is no restore rectangle left.
-  EXPECT_FALSE(window_state->HasRestoreBounds());
-}
-
-// Maximize, left/right maximize and then restore should works.
-TEST_F(FrameMaximizeButtonTest, MaximizeMaximizeLeftRestore) {
-  aura::Window* window = widget()->GetNativeWindow();
-  gfx::Rect initial_bounds = widget()->GetWindowBoundsInScreen();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-  maximize_button->set_bubble_appearance_delay_ms(0);
-
-  ClickMaxButton(maximize_button, window, SNAP_NONE);
-
-  wm::WindowState* window_state = wm::GetWindowState(window);
-  EXPECT_TRUE(window_state->IsMaximized());
-
-  ClickMaxButton(maximize_button, window, SNAP_LEFT);
-  EXPECT_FALSE(window_state->IsMaximized());
-  gfx::Rect new_bounds = widget()->GetWindowBoundsInScreen();
-  EXPECT_EQ(0, new_bounds.x());
-  EXPECT_EQ(0, new_bounds.y());
-
-  // Now click the same button again to see that it restores.
-  ClickMaxButton(maximize_button, window, SNAP_LEFT);
-  RunAllPendingInMessageLoop();
-  // But the bounds should be restored.
-  new_bounds = widget()->GetWindowBoundsInScreen();
-  EXPECT_EQ(new_bounds.x(), initial_bounds.x());
-  EXPECT_EQ(new_bounds.y(), initial_bounds.x());
-  EXPECT_EQ(new_bounds.width(), initial_bounds.width());
-  EXPECT_EQ(new_bounds.height(), initial_bounds.height());
-  // Make sure that there is no restore rectangle left.
-  EXPECT_FALSE(window_state->HasRestoreBounds());
-}
-
-// Left/right maximize, maximize and then restore should work.
-TEST_F(FrameMaximizeButtonTest, MaximizeSnapLeftRestore) {
-  aura::Window* window = widget()->GetNativeWindow();
-  gfx::Rect initial_bounds = widget()->GetWindowBoundsInScreen();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-  maximize_button->set_bubble_appearance_delay_ms(0);
-
-  ClickMaxButton(maximize_button, window, SNAP_LEFT);
-
-  wm::WindowState* window_state = wm::GetWindowState(window);
-  EXPECT_FALSE(window_state->IsMaximized());
-
-  ClickMaxButton(maximize_button, window, SNAP_NONE);
-  EXPECT_TRUE(window_state->IsMaximized());
-
-  ClickMaxButton(maximize_button, window, SNAP_NONE);
-  EXPECT_FALSE(window_state->IsMaximized());
-  gfx::Rect new_bounds = widget()->GetWindowBoundsInScreen();
-  EXPECT_EQ(new_bounds.x(), initial_bounds.x());
-  EXPECT_EQ(new_bounds.y(), initial_bounds.x());
-  EXPECT_EQ(new_bounds.width(), initial_bounds.width());
-  EXPECT_EQ(new_bounds.height(), initial_bounds.height());
-  // Make sure that there is no restore rectangle left.
-  EXPECT_FALSE(window_state->HasRestoreBounds());
-}
-
-// Test that minimizing the window per keyboard closes the maximize bubble.
-TEST_F(FrameMaximizeButtonTest, MinimizePerKeyClosesBubble) {
-  aura::Window* window = widget()->GetNativeWindow();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);
-
-  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
-  generator.MoveMouseTo(off_pos);
-  EXPECT_FALSE(maximize_button->maximizer());
-
-  // Move the mouse cursor over the maximize button.
-  generator.MoveMouseTo(button_pos);
-  EXPECT_TRUE(maximize_button->maximizer());
-
-  // We simulate the keystroke by calling minimizeWindow directly.
-  wm::WindowState* window_state = wm::GetWindowState(window);
-  window_state->Minimize();
-
-  EXPECT_TRUE(window_state->IsMinimized());
-  EXPECT_FALSE(maximize_button->maximizer());
-}
-
-// Tests that dragging down on the maximize button minimizes the window.
-TEST_F(FrameMaximizeButtonTest, MaximizeButtonDragDownMinimizes) {
-  aura::Window* window = widget()->GetNativeWindow();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-
-  wm::WindowState* window_state = wm::GetWindowState(window);
-  // Drag down on a maximized window.
-  window_state->Maximize();
-  EXPECT_TRUE(window_state->IsMaximized());
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  gfx::Point off_pos(button_pos.x(), button_pos.y() + 100);
-
-  aura::test::EventGenerator generator(window->GetRootWindow());
-  generator.GestureScrollSequence(button_pos, off_pos,
-      base::TimeDelta::FromMilliseconds(0), 1);
-
-  EXPECT_TRUE(window_state->IsMinimized());
-  EXPECT_FALSE(maximize_button->maximizer());
-
-  // Drag down on a restored window.
-  window_state->Restore();
-
-  button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  off_pos = gfx::Point(button_pos.x(), button_pos.y() + 200);
-  generator.GestureScrollSequence(button_pos, off_pos,
-      base::TimeDelta::FromMilliseconds(10), 1);
-  EXPECT_TRUE(window_state->IsMinimized());
-  EXPECT_FALSE(maximize_button->maximizer());
-}
-
-// Tests that dragging Left and pressing ESC does properly abort.
-TEST_F(FrameMaximizeButtonTest, MaximizeButtonDragLeftEscapeExits) {
-  aura::Window* window = widget()->GetNativeWindow();
-  gfx::Rect initial_bounds = widget()->GetWindowBoundsInScreen();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  gfx::Point off_pos(button_pos.x() - button_pos.x() / 2, button_pos.y());
-
-  const int kGestureSteps = 10;
-  CancelCallbackHandler cancel_handler(kGestureSteps / 2, maximize_button);
-  aura::test::EventGenerator generator(window->GetRootWindow());
-  generator.GestureScrollSequenceWithCallback(
-      button_pos,
-      off_pos,
-      base::TimeDelta::FromMilliseconds(0),
-      kGestureSteps,
-      base::Bind(&CancelCallbackHandler::CountedCancelCallback,
-                 base::Unretained(&cancel_handler)));
-
-  // Check that there was no size change.
-  EXPECT_EQ(widget()->GetWindowBoundsInScreen().size().ToString(),
-            initial_bounds.size().ToString());
-  // Check that there is no phantom window left open.
-  EXPECT_FALSE(maximize_button->phantom_window_open());
-}
-
-// Test that hovering over a button in the maximizer bubble and switching
-// activation without moving the mouse properly aborts.
-TEST_F(FrameMaximizeButtonTest, LossOfActivationWhileMaximizeBubbleOpenAborts) {
-  aura::Window* window = widget()->GetNativeWindow();
-  ash::FrameMaximizeButton* maximize_button =
-      FrameMaximizeButtonTest::maximize_button();
-  maximize_button->set_bubble_appearance_delay_ms(0);
-
-  gfx::Rect initial_bounds = window->GetBoundsInScreen();
-  EXPECT_TRUE(wm::GetWindowState(window)->IsNormalStateType());
-  EXPECT_TRUE(widget()->IsActive());
-
-  // Move the mouse over the maximize button in order to bring up the maximizer
-  // bubble.
-  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
-  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);
-  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
-  generator.MoveMouseTo(button_pos);
-  EXPECT_TRUE(maximize_button->maximizer());
-
-  // Hover the mouse over the left maximize button in the maximizer bubble to
-  // show the phantom window.
-  gfx::Point left_max_pos = maximize_button->maximizer()->
-      GetButtonForUnitTest(SNAP_LEFT)->GetBoundsInScreen().CenterPoint();
-  generator.MoveMouseTo(left_max_pos);
-  EXPECT_TRUE(maximize_button->phantom_window_open());
-
-  // Change activation by creating a new window. This could be done via an
-  // accelerator. The root window takes ownership of |just_created|.
-  views::Widget* just_created = views::Widget::CreateWindowWithContextAndBounds(
-      NULL, widget()->GetNativeWindow(), gfx::Rect(100, 100));
-  just_created->Show();
-  just_created->Activate();
-  EXPECT_FALSE(widget()->IsActive());
-
-  // Test that we have properly reset the state of the now inactive window.
-  EXPECT_FALSE(maximize_button->maximizer());
-  EXPECT_FALSE(maximize_button->phantom_window_open());
-  EXPECT_TRUE(wm::GetWindowState(window)->IsNormalStateType());
-  EXPECT_EQ(initial_bounds.ToString(), window->GetBoundsInScreen().ToString());
-}
-
-}  // namespace test
-}  // namespace ash
diff --git a/ash/frame/caption_buttons/frame_size_button.cc b/ash/frame/caption_buttons/frame_size_button.cc
new file mode 100644
index 0000000..1399453
--- /dev/null
+++ b/ash/frame/caption_buttons/frame_size_button.cc
@@ -0,0 +1,284 @@
+// 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.
+
+#include "ash/frame/caption_buttons/frame_size_button.h"
+
+#include "ash/metrics/user_metrics_recorder.h"
+#include "ash/screen_util.h"
+#include "ash/shell.h"
+#include "ash/touch/touch_uma.h"
+#include "ash/wm/window_state.h"
+#include "ash/wm/window_util.h"
+#include "ash/wm/wm_event.h"
+#include "ash/wm/workspace/phantom_window_controller.h"
+#include "base/i18n/rtl.h"
+#include "ui/gfx/vector2d.h"
+#include "ui/views/widget/widget.h"
+
+namespace {
+
+// The default delay between the user pressing the size button and the buttons
+// adjacent to the size button morphing into buttons for snapping left and
+// right.
+const int kSetButtonsToSnapModeDelayMs = 150;
+
+// The amount that a user can overshoot one of the caption buttons while in
+// "snap mode" and keep the button hovered/pressed.
+const int kMaxOvershootX = 200;
+const int kMaxOvershootY = 50;
+
+// Returns true if a mouse drag while in "snap mode" at |location_in_screen|
+// would hover/press |button| or keep it hovered/pressed.
+bool HitTestButton(const ash::FrameCaptionButton* button,
+                   const gfx::Point& location_in_screen) {
+  gfx::Rect expanded_bounds_in_screen = button->GetBoundsInScreen();
+  if (button->state() == views::Button::STATE_HOVERED ||
+      button->state() == views::Button::STATE_PRESSED) {
+    expanded_bounds_in_screen.Inset(-kMaxOvershootX, -kMaxOvershootY);
+  }
+  return expanded_bounds_in_screen.Contains(location_in_screen);
+}
+
+}  // namespace
+
+namespace ash {
+
+FrameSizeButton::FrameSizeButton(
+    views::ButtonListener* listener,
+    views::Widget* frame,
+    FrameSizeButtonDelegate* delegate)
+    : FrameCaptionButton(listener, CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE),
+      frame_(frame),
+      delegate_(delegate),
+      set_buttons_to_snap_mode_delay_ms_(kSetButtonsToSnapModeDelayMs),
+      in_snap_mode_(false),
+      snap_type_(SNAP_NONE) {
+}
+
+FrameSizeButton::~FrameSizeButton() {
+}
+
+bool FrameSizeButton::OnMousePressed(const ui::MouseEvent& event) {
+  // The minimize and close buttons are set to snap left and right when snapping
+  // is enabled. Do not enable snapping if the minimize button is not visible.
+  // The close button is always visible.
+  if (IsTriggerableEvent(event) &&
+      !in_snap_mode_ &&
+      delegate_->IsMinimizeButtonVisible()) {
+    StartSetButtonsToSnapModeTimer(event);
+  }
+  FrameCaptionButton::OnMousePressed(event);
+  return true;
+}
+
+bool FrameSizeButton::OnMouseDragged(const ui::MouseEvent& event) {
+  UpdateSnapType(event);
+  // By default a FrameCaptionButton reverts to STATE_NORMAL once the mouse
+  // leaves its bounds. Skip FrameCaptionButton's handling when
+  // |in_snap_mode_| == true because we want different behavior.
+  if (!in_snap_mode_)
+    FrameCaptionButton::OnMouseDragged(event);
+  return true;
+}
+
+void FrameSizeButton::OnMouseReleased(const ui::MouseEvent& event) {
+  if (!IsTriggerableEvent(event) || !CommitSnap(event))
+    FrameCaptionButton::OnMouseReleased(event);
+}
+
+void FrameSizeButton::OnMouseCaptureLost() {
+  SetButtonsToNormalMode(FrameSizeButtonDelegate::ANIMATE_YES);
+  FrameCaptionButton::OnMouseCaptureLost();
+}
+
+void FrameSizeButton::OnMouseMoved(const ui::MouseEvent& event) {
+  // Ignore any synthetic mouse moves during a drag.
+  if (!in_snap_mode_)
+    FrameCaptionButton::OnMouseMoved(event);
+}
+
+void FrameSizeButton::OnGestureEvent(ui::GestureEvent* event) {
+  if (event->details().touch_points() > 1) {
+    SetButtonsToNormalMode(FrameSizeButtonDelegate::ANIMATE_YES);
+    return;
+  }
+
+  if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
+    StartSetButtonsToSnapModeTimer(*event);
+    // Go through FrameCaptionButton's handling so that the button gets pressed.
+    FrameCaptionButton::OnGestureEvent(event);
+    return;
+  }
+
+  if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
+      event->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
+    UpdateSnapType(*event);
+    event->SetHandled();
+    return;
+  }
+
+  if (event->type() == ui::ET_GESTURE_TAP ||
+      event->type() == ui::ET_GESTURE_SCROLL_END ||
+      event->type() == ui::ET_SCROLL_FLING_START ||
+      event->type() == ui::ET_GESTURE_END) {
+    if (CommitSnap(*event)) {
+      if (event->type() == ui::ET_GESTURE_TAP) {
+        TouchUMA::GetInstance()->RecordGestureAction(
+            TouchUMA::GESTURE_FRAMEMAXIMIZE_TAP);
+      }
+      event->SetHandled();
+      return;
+    }
+  }
+
+  FrameCaptionButton::OnGestureEvent(event);
+}
+
+void FrameSizeButton::StartSetButtonsToSnapModeTimer(
+    const ui::LocatedEvent& event) {
+  set_buttons_to_snap_mode_timer_event_location_ = event.location();
+  if (set_buttons_to_snap_mode_delay_ms_ == 0) {
+    AnimateButtonsToSnapMode();
+  } else {
+    set_buttons_to_snap_mode_timer_.Start(
+        FROM_HERE,
+        base::TimeDelta::FromMilliseconds(set_buttons_to_snap_mode_delay_ms_),
+        this,
+        &FrameSizeButton::AnimateButtonsToSnapMode);
+  }
+}
+
+void FrameSizeButton::AnimateButtonsToSnapMode() {
+  SetButtonsToSnapMode(FrameSizeButtonDelegate::ANIMATE_YES);
+}
+
+void FrameSizeButton::SetButtonsToSnapMode(
+    FrameSizeButtonDelegate::Animate animate) {
+  in_snap_mode_ = true;
+
+  // When using a right-to-left layout the close button is left of the size
+  // button and the minimize button is right of the size button.
+  if (base::i18n::IsRTL()) {
+    delegate_->SetButtonIcons(CAPTION_BUTTON_ICON_RIGHT_SNAPPED,
+                              CAPTION_BUTTON_ICON_LEFT_SNAPPED,
+                              animate);
+  } else {
+    delegate_->SetButtonIcons(CAPTION_BUTTON_ICON_LEFT_SNAPPED,
+                              CAPTION_BUTTON_ICON_RIGHT_SNAPPED,
+                              animate);
+  }
+}
+
+void FrameSizeButton::UpdateSnapType(const ui::LocatedEvent& event) {
+  if (!in_snap_mode_) {
+    // Set the buttons adjacent to the size button to snap left and right early
+    // if the user drags past the drag threshold.
+    // |set_buttons_to_snap_mode_timer_| is checked to avoid entering the snap
+    // mode as a result of an unsupported drag type (e.g. only the right mouse
+    // button is pressed).
+    gfx::Vector2d delta(
+        event.location() - set_buttons_to_snap_mode_timer_event_location_);
+    if (!set_buttons_to_snap_mode_timer_.IsRunning() ||
+        !views::View::ExceededDragThreshold(delta)) {
+      return;
+    }
+    AnimateButtonsToSnapMode();
+  }
+
+  gfx::Point event_location_in_screen(event.location());
+  views::View::ConvertPointToScreen(this, &event_location_in_screen);
+  const FrameCaptionButton* to_hover =
+      GetButtonToHover(event_location_in_screen);
+  bool press_size_button =
+      to_hover || HitTestButton(this, event_location_in_screen);
+
+  if (to_hover) {
+    // Progress the minimize and close icon morph animations to the end if they
+    // are in progress.
+    SetButtonsToSnapMode(FrameSizeButtonDelegate::ANIMATE_NO);
+  }
+
+  delegate_->SetHoveredAndPressedButtons(
+      to_hover, press_size_button ? this : NULL);
+
+  snap_type_ = SNAP_NONE;
+  if (to_hover) {
+    switch (to_hover->icon()) {
+      case CAPTION_BUTTON_ICON_LEFT_SNAPPED:
+        snap_type_ = SNAP_LEFT;
+        break;
+      case CAPTION_BUTTON_ICON_RIGHT_SNAPPED:
+        snap_type_ = SNAP_RIGHT;
+        break;
+      case CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE:
+      case CAPTION_BUTTON_ICON_MINIMIZE:
+      case CAPTION_BUTTON_ICON_CLOSE:
+      case CAPTION_BUTTON_ICON_COUNT:
+        NOTREACHED();
+        break;
+    }
+  }
+
+  if (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT) {
+    aura::Window* window = frame_->GetNativeWindow();
+    if (!phantom_window_controller_.get()) {
+      phantom_window_controller_.reset(new PhantomWindowController(window));
+    }
+    gfx::Rect phantom_bounds_in_parent = (snap_type_ == SNAP_LEFT) ?
+        wm::GetDefaultLeftSnappedWindowBoundsInParent(window) :
+        wm::GetDefaultRightSnappedWindowBoundsInParent(window);
+    phantom_window_controller_->Show(ScreenUtil::ConvertRectToScreen(
+          window->parent(), phantom_bounds_in_parent));
+  } else {
+    phantom_window_controller_.reset();
+  }
+}
+
+const FrameCaptionButton* FrameSizeButton::GetButtonToHover(
+    const gfx::Point& event_location_in_screen) const {
+  const FrameCaptionButton* closest_button = delegate_->GetButtonClosestTo(
+      event_location_in_screen);
+  if ((closest_button->icon() == CAPTION_BUTTON_ICON_LEFT_SNAPPED ||
+       closest_button->icon() == CAPTION_BUTTON_ICON_RIGHT_SNAPPED) &&
+      HitTestButton(closest_button, event_location_in_screen)) {
+    return closest_button;
+  }
+  return NULL;
+}
+
+bool FrameSizeButton::CommitSnap(const ui::LocatedEvent& event) {
+  // The position of |event| may be different than the position of the previous
+  // event.
+  UpdateSnapType(event);
+
+  if (in_snap_mode_ &&
+      (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) {
+    wm::WindowState* window_state =
+        wm::GetWindowState(frame_->GetNativeWindow());
+    UserMetricsRecorder* metrics = Shell::GetInstance()->metrics();
+    const wm::WMEvent snap_event(
+        snap_type_ == SNAP_LEFT ?
+        wm::WM_EVENT_SNAP_LEFT : wm::WM_EVENT_SNAP_RIGHT);
+    window_state->OnWMEvent(&snap_event);
+    metrics->RecordUserMetricsAction(
+        snap_type_ == SNAP_LEFT ?
+        UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT :
+        UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT);
+    SetButtonsToNormalMode(FrameSizeButtonDelegate::ANIMATE_NO);
+    return true;
+  }
+  SetButtonsToNormalMode(FrameSizeButtonDelegate::ANIMATE_YES);
+  return false;
+}
+
+void FrameSizeButton::SetButtonsToNormalMode(
+    FrameSizeButtonDelegate::Animate animate) {
+  in_snap_mode_ = false;
+  snap_type_ = SNAP_NONE;
+  set_buttons_to_snap_mode_timer_.Stop();
+  delegate_->SetButtonsToNormal(animate);
+  phantom_window_controller_.reset();
+}
+
+}  // namespace ash
diff --git a/ash/frame/caption_buttons/frame_size_button.h b/ash/frame/caption_buttons/frame_size_button.h
new file mode 100644
index 0000000..f1ac605
--- /dev/null
+++ b/ash/frame/caption_buttons/frame_size_button.h
@@ -0,0 +1,121 @@
+// 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.
+
+#ifndef ASH_FRAME_CAPTION_BUTTONS_FRAME_SIZE_BUTTON_H_
+#define ASH_FRAME_CAPTION_BUTTONS_FRAME_SIZE_BUTTON_H_
+
+#include "ash/ash_export.h"
+#include "ash/frame/caption_buttons/frame_caption_button.h"
+#include "ash/frame/caption_buttons/frame_size_button_delegate.h"
+#include "base/timer/timer.h"
+
+namespace views {
+class Widget;
+}
+
+namespace ash {
+class FrameSizeButtonDelegate;
+class PhantomWindowController;
+
+// The maximize/restore button.
+// When the mouse is pressed over the size button or the size button is touched:
+// - The minimize and close buttons are set to snap left and snap right
+//   respectively.
+// - The size button stays pressed while the mouse is over the buttons to snap
+//   left and to snap right. The button underneath the mouse is hovered.
+// When the drag terminates, the action for the button underneath the mouse
+// is executed. For the sake of simplicity, the size button is the event
+// handler for a click starting on the size button and the entire drag.
+class ASH_EXPORT FrameSizeButton : public FrameCaptionButton {
+ public:
+  FrameSizeButton(views::ButtonListener* listener,
+                  views::Widget* frame,
+                  FrameSizeButtonDelegate* delegate);
+
+  virtual ~FrameSizeButton();
+
+  // views::CustomButton overrides:
+  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
+  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
+  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
+  virtual void OnMouseCaptureLost() OVERRIDE;
+  virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE;
+  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
+
+  void set_delay_to_set_buttons_to_snap_mode(int delay_ms) {
+    set_buttons_to_snap_mode_delay_ms_ = delay_ms;
+  }
+
+ private:
+  enum SnapType {
+    SNAP_LEFT,
+    SNAP_RIGHT,
+    SNAP_NONE
+  };
+
+  // Starts |set_buttons_to_snap_mode_timer_|.
+  void StartSetButtonsToSnapModeTimer(const ui::LocatedEvent& event);
+
+  // Animates the buttons adjacent to the size button to snap left and right.
+  void AnimateButtonsToSnapMode();
+
+  // Sets the buttons adjacent to the size button to snap left and right.
+  // Passing in ANIMATE_NO progresses the animation (if any) to the end.
+  void SetButtonsToSnapMode(FrameSizeButtonDelegate::Animate animate);
+
+  // Updates |snap_type_|, whether the size button is pressed and whether any
+  // other buttons are hovered.
+  void UpdateSnapType(const ui::LocatedEvent& event);
+
+  // Returns the button which should be hovered (if any) while in "snap mode"
+  // for |event_location_in_screen|.
+  const FrameCaptionButton* GetButtonToHover(
+      const gfx::Point& event_location_in_screen) const;
+
+  // Snaps |frame_| according to |snap_type_|. Returns true if |frame_| was
+  // snapped.
+  bool CommitSnap(const ui::LocatedEvent& event);
+
+  // Sets the buttons adjacent to the size button to minimize and close again.
+  // Clears any state set while snapping was enabled. |animate| indicates
+  // whether the buttons should animate back to their original icons.
+  void SetButtonsToNormalMode(FrameSizeButtonDelegate::Animate animate);
+
+  // Widget that the size button acts on.
+  views::Widget* frame_;
+
+  // Not owned.
+  FrameSizeButtonDelegate* delegate_;
+
+  // Location of the event which started |set_buttons_to_snap_mode_timer_| in
+  // view coordinates.
+  gfx::Point set_buttons_to_snap_mode_timer_event_location_;
+
+  // The delay between the user pressing the size button and the buttons
+  // adjacent to the size button morphing into buttons for snapping left and
+  // right.
+  int set_buttons_to_snap_mode_delay_ms_;
+
+  base::OneShotTimer<FrameSizeButton> set_buttons_to_snap_mode_timer_;
+
+  // Whether the buttons adjacent to the size button snap the window left and
+  // right.
+  bool in_snap_mode_;
+
+  // The action to execute when the drag/click is ended. If
+  // |snap_type_| == SNAP_NONE, the size button's default action is run when the
+  // drag/click is ended.
+  SnapType snap_type_;
+
+  // Displays a preview of how the window's bounds will change as a result of
+  // snapping the window left or right. The preview is only visible if the snap
+  // left or snap right button is pressed.
+  scoped_ptr<PhantomWindowController> phantom_window_controller_;
+
+  DISALLOW_COPY_AND_ASSIGN(FrameSizeButton);
+};
+
+}  // namespace ash
+
+#endif  // ASH_FRAME_CAPTION_BUTTONS_FRAME_SIZE_BUTTON_H_
diff --git a/ash/frame/caption_buttons/frame_size_button_delegate.h b/ash/frame/caption_buttons/frame_size_button_delegate.h
new file mode 100644
index 0000000..ddccf16
--- /dev/null
+++ b/ash/frame/caption_buttons/frame_size_button_delegate.h
@@ -0,0 +1,58 @@
+// 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.
+
+#ifndef ASH_FRAME_CAPTION_BUTTONS_FRAME_SIZE_BUTTON_DELEGATE_H_
+#define ASH_FRAME_CAPTION_BUTTONS_FRAME_SIZE_BUTTON_DELEGATE_H_
+
+#include "ash/ash_export.h"
+#include "ash/frame/caption_buttons/caption_button_types.h"
+
+namespace gfx {
+class Insets;
+class Point;
+class Vector2d;
+}
+
+namespace ash {
+class FrameCaptionButton;
+
+// Delegate interface for FrameSizeButton.
+class ASH_EXPORT FrameSizeButtonDelegate {
+ public:
+  enum Animate {
+    ANIMATE_YES,
+    ANIMATE_NO
+  };
+
+  // Returns whether the minimize button is visible.
+  virtual bool IsMinimizeButtonVisible() const = 0;
+
+  // Reset the caption button views::Button::ButtonState back to normal. If
+  // |animate| is ANIMATE_YES, the buttons will crossfade back to their
+  // original icons.
+  virtual void SetButtonsToNormal(Animate animate) = 0;
+
+  // Sets the minimize and close button icons. The buttons will crossfade to
+  // their new icons if |animate| is ANIMATE_YES.
+  virtual void SetButtonIcons(CaptionButtonIcon minimize_button_icon,
+                              CaptionButtonIcon close_button_icon,
+                              Animate animate) = 0;
+
+  // Returns the button closest to |position_in_screen|.
+  virtual const FrameCaptionButton* GetButtonClosestTo(
+      const gfx::Point& position_in_screen) const = 0;
+
+  // Sets |to_hover| and |to_pressed| to STATE_HOVERED and STATE_PRESSED
+  // respectively. All other buttons are to set to STATE_NORMAL.
+  virtual void SetHoveredAndPressedButtons(
+      const FrameCaptionButton* to_hover,
+      const FrameCaptionButton* to_press) = 0;
+
+ protected:
+  virtual ~FrameSizeButtonDelegate() {}
+};
+
+}  // namespace ash
+
+#endif  // ASH_FRAME_CAPTION_BUTTONS_FRAME_SIZE_BUTTON_DELEGATE_H_
diff --git a/ash/frame/caption_buttons/frame_size_button_unittest.cc b/ash/frame/caption_buttons/frame_size_button_unittest.cc
new file mode 100644
index 0000000..74c8f14
--- /dev/null
+++ b/ash/frame/caption_buttons/frame_size_button_unittest.cc
@@ -0,0 +1,472 @@
+// 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.
+
+#include "ash/frame/caption_buttons/frame_size_button.h"
+
+#include "ash/frame/caption_buttons/frame_caption_button.h"
+#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
+#include "ash/shell.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/wm/window_state.h"
+#include "base/i18n/rtl.h"
+#include "grit/ash_resources.h"
+#include "ui/aura/test/event_generator.h"
+#include "ui/aura/window.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/events/gestures/gesture_configuration.h"
+#include "ui/gfx/display.h"
+#include "ui/gfx/screen.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_delegate.h"
+
+namespace ash {
+namespace test {
+
+namespace {
+
+class TestWidgetDelegate : public views::WidgetDelegateView {
+ public:
+  TestWidgetDelegate() {}
+  virtual ~TestWidgetDelegate() {}
+
+  // Overridden from views::WidgetDelegate:
+  virtual views::View* GetContentsView() OVERRIDE {
+    return this;
+  }
+  virtual bool CanResize() const OVERRIDE {
+    return true;
+  }
+  virtual bool CanMaximize() const OVERRIDE {
+    return true;
+  }
+
+  ash::FrameCaptionButtonContainerView* caption_button_container() {
+    return caption_button_container_;
+  }
+
+ private:
+  // Overridden from views::View:
+  virtual void Layout() OVERRIDE {
+    caption_button_container_->Layout();
+
+    // Right align the caption button container.
+    gfx::Size preferred_size = caption_button_container_->GetPreferredSize();
+    caption_button_container_->SetBounds(width() - preferred_size.width(), 0,
+        preferred_size.width(), preferred_size.height());
+  }
+
+  virtual void ViewHierarchyChanged(
+      const ViewHierarchyChangedDetails& details) OVERRIDE {
+    if (details.is_add && details.child == this) {
+      caption_button_container_ = new FrameCaptionButtonContainerView(
+          GetWidget(), FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
+
+      // Set arbitrary images for the container's buttons so that the buttons
+      // have non-empty sizes.
+      for (int icon = 0; icon < CAPTION_BUTTON_ICON_COUNT; ++icon) {
+        caption_button_container_->SetButtonImages(
+            static_cast<CaptionButtonIcon>(icon),
+            IDR_AURA_WINDOW_CONTROL_ICON_CLOSE,
+            IDR_AURA_WINDOW_CONTROL_ICON_CLOSE_I,
+            IDR_AURA_WINDOW_CONTROL_BACKGROUND_H,
+            IDR_AURA_WINDOW_CONTROL_BACKGROUND_P);
+      }
+
+      AddChildView(caption_button_container_);
+    }
+  }
+
+  // Not owned.
+  ash::FrameCaptionButtonContainerView* caption_button_container_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate);
+};
+
+}  // namespace
+
+class FrameSizeButtonTest : public AshTestBase {
+ public:
+  FrameSizeButtonTest() {}
+  virtual ~FrameSizeButtonTest() {}
+
+  // Returns the center point of |view| in screen coordinates.
+  gfx::Point CenterPointInScreen(views::View* view) {
+    return view->GetBoundsInScreen().CenterPoint();
+  }
+
+  // Returns true if the window has |state_type|.
+  bool HasStateType(wm::WindowStateType state_type) const {
+    return window_state()->GetStateType() == state_type;
+  }
+
+  // Returns true if all three buttons are in the normal state.
+  bool AllButtonsInNormalState() const {
+    return minimize_button_->state() == views::Button::STATE_NORMAL &&
+        size_button_->state() == views::Button::STATE_NORMAL &&
+        close_button_->state() == views::Button::STATE_NORMAL;
+  }
+
+  // Creates a widget with |delegate|. The returned widget takes ownership of
+  // |delegate|.
+  views::Widget* CreateWidget(views::WidgetDelegate* delegate) {
+    views::Widget* widget = new views::Widget;
+    views::Widget::InitParams params(
+        views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+    params.context = CurrentContext();
+    params.delegate = delegate;
+    params.bounds = gfx::Rect(10, 10, 100, 100);
+    widget->Init(params);
+    widget->Show();
+    return widget;
+  }
+
+  // AshTestBase overrides:
+  virtual void SetUp() OVERRIDE {
+    AshTestBase::SetUp();
+
+    TestWidgetDelegate* delegate = new TestWidgetDelegate();
+    window_state_ = ash::wm::GetWindowState(
+        CreateWidget(delegate)->GetNativeWindow());
+
+    FrameCaptionButtonContainerView::TestApi test(
+        delegate->caption_button_container());
+
+    minimize_button_ = test.minimize_button();
+    size_button_ = test.size_button();
+    static_cast<FrameSizeButton*>(
+        size_button_)->set_delay_to_set_buttons_to_snap_mode(0);
+    close_button_ = test.close_button();
+  }
+
+  ash::wm::WindowState* window_state() { return window_state_; }
+  const ash::wm::WindowState* window_state() const { return window_state_; }
+
+  FrameCaptionButton* minimize_button() { return minimize_button_; }
+  FrameCaptionButton* size_button() { return size_button_; }
+  FrameCaptionButton* close_button() { return close_button_; }
+
+ private:
+  // Not owned.
+  ash::wm::WindowState* window_state_;
+  FrameCaptionButton* minimize_button_;
+  FrameCaptionButton* size_button_;
+  FrameCaptionButton* close_button_;
+
+  DISALLOW_COPY_AND_ASSIGN(FrameSizeButtonTest);
+};
+
+// Tests that pressing the left mouse button or tapping down on the size button
+// puts the button into the pressed state.
+TEST_F(FrameSizeButtonTest, PressedState) {
+  aura::test::EventGenerator& generator = GetEventGenerator();
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.PressLeftButton();
+  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
+  generator.ReleaseLeftButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_EQ(views::Button::STATE_NORMAL, size_button()->state());
+
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.PressTouchId(3);
+  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
+  generator.ReleaseTouchId(3);
+  RunAllPendingInMessageLoop();
+  EXPECT_EQ(views::Button::STATE_NORMAL, size_button()->state());
+}
+
+// Tests that clicking on the size button toggles between the maximized and
+// normal state.
+TEST_F(FrameSizeButtonTest, ClickSizeButtonTogglesMaximize) {
+  EXPECT_FALSE(window_state()->IsMaximized());
+
+  aura::test::EventGenerator& generator = GetEventGenerator();
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.ClickLeftButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(window_state()->IsMaximized());
+
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.ClickLeftButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(window_state()->IsMaximized());
+
+  generator.GestureTapAt(CenterPointInScreen(size_button()));
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(window_state()->IsMaximized());
+
+  generator.GestureTapAt(CenterPointInScreen(size_button()));
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(window_state()->IsMaximized());
+}
+
+// Test that clicking + dragging to a button adjacent to the size button snaps
+// the window left or right.
+TEST_F(FrameSizeButtonTest, ButtonDrag) {
+  EXPECT_TRUE(window_state()->IsNormalStateType());
+
+  // 1) Test by dragging the mouse.
+  // Snap right.
+  aura::test::EventGenerator& generator = GetEventGenerator();
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.PressLeftButton();
+  generator.MoveMouseTo(CenterPointInScreen(close_button()));
+  generator.ReleaseLeftButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
+
+  // Snap left.
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.PressLeftButton();
+  generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
+  generator.ReleaseLeftButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
+
+  // 2) Test with scroll gestures.
+  // Snap right.
+  generator.GestureScrollSequence(
+      CenterPointInScreen(size_button()),
+      CenterPointInScreen(close_button()),
+      base::TimeDelta::FromMilliseconds(100),
+      3);
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
+
+  // Snap left.
+  generator.GestureScrollSequence(
+      CenterPointInScreen(size_button()),
+      CenterPointInScreen(minimize_button()),
+      base::TimeDelta::FromMilliseconds(100),
+      3);
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
+
+  // 3) Test with tap gestures.
+  const int touch_default_radius =
+      ui::GestureConfiguration::default_radius();
+  ui::GestureConfiguration::set_default_radius(0);
+  // Snap right.
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.PressMoveAndReleaseTouchTo(CenterPointInScreen(close_button()));
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
+  // Snap left.
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.PressMoveAndReleaseTouchTo(CenterPointInScreen(minimize_button()));
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
+  ui::GestureConfiguration::set_default_radius(touch_default_radius);
+}
+
+// Test that clicking, dragging, and overshooting the minimize button a bit
+// horizontally still snaps the window left.
+TEST_F(FrameSizeButtonTest, SnapLeftOvershootMinimize) {
+  EXPECT_TRUE(window_state()->IsNormalStateType());
+
+  aura::test::EventGenerator& generator = GetEventGenerator();
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+
+  generator.PressLeftButton();
+  // Move to the minimize button.
+  generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
+  // Overshoot the minimize button.
+  generator.MoveMouseBy(-minimize_button()->width(), 0);
+  generator.ReleaseLeftButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
+}
+
+// Test that right clicking the size button has no effect.
+TEST_F(FrameSizeButtonTest, RightMouseButton) {
+  EXPECT_TRUE(window_state()->IsNormalStateType());
+
+  aura::test::EventGenerator& generator = GetEventGenerator();
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.PressRightButton();
+  generator.ReleaseRightButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(window_state()->IsNormalStateType());
+}
+
+// Test that upon releasing the mouse button after having pressed the size
+// button
+// - The state of all the caption buttons is reset.
+// - The icon displayed by all of the caption buttons is reset.
+TEST_F(FrameSizeButtonTest, ResetButtonsAfterClick) {
+  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
+  EXPECT_TRUE(AllButtonsInNormalState());
+
+  // Pressing the size button should result in the size button being pressed and
+  // the minimize and close button icons changing.
+  aura::test::EventGenerator& generator = GetEventGenerator();
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.PressLeftButton();
+  EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
+  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
+  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
+
+  // Dragging the mouse over the minimize button should hover the minimize
+  // button and the minimize and close button icons should stay changed.
+  generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
+  EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
+  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
+  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
+
+  // Release the mouse, snapping the window left.
+  generator.ReleaseLeftButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
+
+  // None of the buttons should stay pressed and the buttons should have their
+  // regular icons.
+  EXPECT_TRUE(AllButtonsInNormalState());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
+
+  // Repeat test but release button where it does not affect the window's state
+  // because the code path is different.
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.PressLeftButton();
+  EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
+  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
+  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
+
+  const gfx::Rect& kWorkAreaBoundsInScreen =
+      ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
+  generator.MoveMouseTo(kWorkAreaBoundsInScreen.bottom_left());
+
+  // None of the buttons should be pressed because we are really far away from
+  // any of the caption buttons. The minimize and close button icons should
+  // be changed because the mouse is pressed.
+  EXPECT_TRUE(AllButtonsInNormalState());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
+
+  // Release the mouse. The window should stay snapped left.
+  generator.ReleaseLeftButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
+
+  // The buttons should stay unpressed and the buttons should now have their
+  // regular icons.
+  EXPECT_TRUE(AllButtonsInNormalState());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
+}
+
+// Test that the size button is pressed whenever the snap left/right buttons
+// are hovered.
+TEST_F(FrameSizeButtonTest, SizeButtonPressedWhenSnapButtonHovered) {
+  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
+  EXPECT_TRUE(AllButtonsInNormalState());
+
+  // Pressing the size button should result in the size button being pressed and
+  // the minimize and close button icons changing.
+  aura::test::EventGenerator& generator = GetEventGenerator();
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.PressLeftButton();
+  EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
+  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
+  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
+
+  // Dragging the mouse over the minimize button (snap left button) should hover
+  // the minimize button and keep the size button pressed.
+  generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
+  EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
+  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
+  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
+
+  // Moving the mouse far away from the caption buttons and then moving it over
+  // the close button (snap right button) should hover the close button and
+  // keep the size button pressed.
+  const gfx::Rect& kWorkAreaBoundsInScreen =
+      ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
+  generator.MoveMouseTo(kWorkAreaBoundsInScreen.bottom_left());
+  EXPECT_TRUE(AllButtonsInNormalState());
+  generator.MoveMouseTo(CenterPointInScreen(close_button()));
+  EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
+  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
+  EXPECT_EQ(views::Button::STATE_HOVERED, close_button()->state());
+}
+
+class FrameSizeButtonTestRTL : public FrameSizeButtonTest {
+ public:
+  FrameSizeButtonTestRTL() {}
+  virtual ~FrameSizeButtonTestRTL() {}
+
+  virtual void SetUp() OVERRIDE {
+    original_locale_ = l10n_util::GetApplicationLocale(std::string());
+    base::i18n::SetICUDefaultLocale("he");
+
+    FrameSizeButtonTest::SetUp();
+  }
+
+  virtual void TearDown() OVERRIDE {
+    FrameSizeButtonTest::TearDown();
+    base::i18n::SetICUDefaultLocale(original_locale_);
+  }
+
+ private:
+  std::string original_locale_;
+
+  DISALLOW_COPY_AND_ASSIGN(FrameSizeButtonTestRTL);
+};
+
+// Test that clicking + dragging to a button adjacent to the size button presses
+// the correct button and snaps the window to the correct side.
+TEST_F(FrameSizeButtonTestRTL, ButtonDrag) {
+  // In RTL the close button should be left of the size button and the minimize
+  // button should be right of the size button.
+  ASSERT_LT(close_button()->GetBoundsInScreen().x(),
+            size_button()->GetBoundsInScreen().x());
+  ASSERT_LT(size_button()->GetBoundsInScreen().x(),
+            minimize_button()->GetBoundsInScreen().x());
+
+  // Test initial state.
+  EXPECT_TRUE(window_state()->IsNormalStateType());
+  EXPECT_TRUE(AllButtonsInNormalState());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
+
+  // Pressing the size button should swap the icons of the minimize and close
+  // buttons to icons for snapping right and for snapping left respectively.
+  aura::test::EventGenerator& generator = GetEventGenerator();
+  generator.MoveMouseTo(CenterPointInScreen(size_button()));
+  generator.PressLeftButton();
+  EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
+  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
+  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, close_button()->icon());
+
+  // Dragging over to the minimize button should press it.
+  generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
+  EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
+  EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
+  EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
+
+  // Releasing should snap the window right.
+  generator.ReleaseLeftButton();
+  RunAllPendingInMessageLoop();
+  EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
+
+  // None of the buttons should stay pressed and the buttons should have their
+  // regular icons.
+  EXPECT_TRUE(AllButtonsInNormalState());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
+  EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
+}
+
+}  // namespace test
+}  // namespace ash
diff --git a/ash/frame/caption_buttons/maximize_bubble_controller.cc b/ash/frame/caption_buttons/maximize_bubble_controller.cc
deleted file mode 100644
index 9b353dd..0000000
--- a/ash/frame/caption_buttons/maximize_bubble_controller.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2013 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.
-
-#include "ash/frame/caption_buttons/maximize_bubble_controller.h"
-
-#include "ash/frame/caption_buttons/frame_maximize_button.h"
-#include "ash/frame/caption_buttons/maximize_bubble_controller_bubble.h"
-#include "base/timer/timer.h"
-
-
-namespace ash {
-
-MaximizeBubbleController::MaximizeBubbleController(
-    FrameMaximizeButton* frame_maximize_button,
-    MaximizeBubbleFrameState maximize_type,
-    int appearance_delay_ms)
-    : frame_maximize_button_(frame_maximize_button),
-      bubble_(NULL),
-      maximize_type_(maximize_type),
-      snap_type_for_creation_(SNAP_NONE),
-      appearance_delay_ms_(appearance_delay_ms) {
-  // Create the task which will create the bubble delayed.
-  base::OneShotTimer<MaximizeBubbleController>* new_timer =
-      new base::OneShotTimer<MaximizeBubbleController>();
-  // Note: Even if there was no delay time given, we need to have a timer.
-  new_timer->Start(
-      FROM_HERE,
-      base::TimeDelta::FromMilliseconds(
-          appearance_delay_ms_ ? appearance_delay_ms_ : 10),
-      this,
-      &MaximizeBubbleController::CreateBubble);
-  timer_.reset(new_timer);
-  if (!appearance_delay_ms_)
-    CreateBubble();
-}
-
-MaximizeBubbleController::~MaximizeBubbleController() {
-  // Note: The destructor only gets initiated through the owner.
-  timer_.reset();
-  if (bubble_) {
-    bubble_->ControllerRequestsCloseAndDelete();
-    bubble_ = NULL;
-  }
-}
-
-void MaximizeBubbleController::SetSnapType(SnapType snap_type) {
-  if (bubble_) {
-    bubble_->SetSnapType(snap_type);
-  } else {
-    // The bubble has not been created yet. This can occur if bubble creation is
-    // delayed.
-    snap_type_for_creation_ = snap_type;
-  }
-}
-
-aura::Window* MaximizeBubbleController::GetBubbleWindow() {
-  return bubble_ ? bubble_->GetBubbleWindow() : NULL;
-}
-
-void MaximizeBubbleController::DelayCreation() {
-  if (timer_.get() && timer_->IsRunning())
-    timer_->Reset();
-}
-
-void MaximizeBubbleController::OnButtonClicked(SnapType snap_type) {
-  frame_maximize_button_->ExecuteSnapAndCloseMenu(snap_type);
-}
-
-void MaximizeBubbleController::OnButtonHover(SnapType snap_type) {
-  frame_maximize_button_->SnapButtonHovered(snap_type);
-}
-
-views::CustomButton* MaximizeBubbleController::GetButtonForUnitTest(
-    SnapType state) {
-  return bubble_ ? bubble_->GetButtonForUnitTest(state) : NULL;
-}
-
-void MaximizeBubbleController::RequestDestructionThroughOwner() {
-  // Tell the parent to destroy us (if this didn't happen yet).
-  if (timer_) {
-    timer_.reset(NULL);
-    // Informs the owner that the menu is gone and requests |this| destruction.
-    frame_maximize_button_->DestroyMaximizeMenu();
-    // Note: After this call |this| is destroyed.
-  }
-}
-
-void MaximizeBubbleController::CreateBubble() {
-  if (!bubble_) {
-    bubble_ = new MaximizeBubbleControllerBubble(this, appearance_delay_ms_,
-                                                 snap_type_for_creation_);
-    frame_maximize_button_->OnMaximizeBubbleShown(bubble_->GetWidget());
-  }
-
-  timer_->Stop();
-}
-
-}  // namespace ash
diff --git a/ash/frame/caption_buttons/maximize_bubble_controller.h b/ash/frame/caption_buttons/maximize_bubble_controller.h
deleted file mode 100644
index 4ed03b8..0000000
--- a/ash/frame/caption_buttons/maximize_bubble_controller.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef ASH_FRAME_CAPTION_BUTTONS_MAXIMIZE_BUBBLE_CONTROLLER_H_
-#define ASH_FRAME_CAPTION_BUTTONS_MAXIMIZE_BUBBLE_CONTROLLER_H_
-
-#include "ash/ash_export.h"
-#include "ash/frame/caption_buttons/caption_button_types.h"
-#include "ash/wm/workspace/snap_types.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace aura {
-class Window;
-}
-
-namespace base {
-class Timer;
-}
-
-namespace views {
-class CustomButton;
-}
-
-namespace ash {
-
-class FrameMaximizeButton;
-class MaximizeBubbleControllerBubble;
-
-// A class which shows a helper UI for the maximize button after a delay.
-class ASH_EXPORT MaximizeBubbleController {
- public:
-  MaximizeBubbleController(FrameMaximizeButton* frame_maximize_button,
-                           MaximizeBubbleFrameState maximize_type,
-                           int appearance_delay_ms);
-  // Called from the outside to destroy the interface to the UI visuals.
-  // The visuals will then delete when possible (maybe asynchronously).
-  virtual ~MaximizeBubbleController();
-
-  // Update the UI visuals to reflect the previewed |snap_type| snapping state.
-  void SetSnapType(SnapType snap_type);
-
-  // To achieve proper Z-sorting with the snap animation, this window will be
-  // presented above the phantom window.
-  aura::Window* GetBubbleWindow();
-
-  // Reset the delay of the menu creation (if it was not created yet).
-  void DelayCreation();
-
-  // Called to tell the owning FrameMaximizeButton that a button was clicked.
-  void OnButtonClicked(SnapType snap_type);
-
-  // Called to tell the the owning FrameMaximizeButton that the hover status
-  // for a button has changed. |snap_type| can be either SNAP_LEFT, SNAP_RIGHT,
-  // SNAP_MINIMIZE or SNAP_NONE.
-  void OnButtonHover(SnapType snap_type);
-
-  // Get the owning FrameMaximizeButton.
-  FrameMaximizeButton* frame_maximize_button() {
-    return frame_maximize_button_;
-  }
-
-  // The status of the associated window: Maximized or normal.
-  MaximizeBubbleFrameState maximize_type() const { return maximize_type_; }
-
-  // A unit test function to return buttons of the sub menu. |state| can be
-  // either SNAP_LEFT, SNAP_RIGHT or SNAP_MINIMIZE.
-  views::CustomButton* GetButtonForUnitTest(SnapType state);
-
-  // Called from the the Bubble class to destroy itself: It tells the owning
-  // object that it will destroy itself asynchronously. The owner will then
-  // destroy |this|.
-  void RequestDestructionThroughOwner();
-
- private:
-  // The function which creates the bubble once the delay is elapsed.
-  void CreateBubble();
-
-  // The owning button which is also the anchor for the menu.
-  FrameMaximizeButton* frame_maximize_button_;
-
-  // The bubble menu.
-  MaximizeBubbleControllerBubble* bubble_;
-
-  // The current maximize state of the owning window.
-  const MaximizeBubbleFrameState maximize_type_;
-
-  // The snap type with which the bubble is created. This is needed because the
-  // creation of the bubble can be delayed and SetSnapType() may be called
-  // before the bubble is created.
-  SnapType snap_type_for_creation_;
-
-  // The timer for the delayed creation of the menu.
-  scoped_ptr<base::Timer> timer_;
-
-  // The appearance delay in ms (delay and fade in & fade out delay).
-  const int appearance_delay_ms_;
-
-  DISALLOW_COPY_AND_ASSIGN(MaximizeBubbleController);
-};
-
-}  // namespace ash
-
-#endif  // ASH_FRAME_CAPTION_BUTTONS_MAXIMIZE_BUBBLE_CONTROLLER_H_
diff --git a/ash/frame/caption_buttons/maximize_bubble_controller_bubble.cc b/ash/frame/caption_buttons/maximize_bubble_controller_bubble.cc
deleted file mode 100644
index e8188cd..0000000
--- a/ash/frame/caption_buttons/maximize_bubble_controller_bubble.cc
+++ /dev/null
@@ -1,510 +0,0 @@
-// Copyright 2013 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.
-
-#include "ash/frame/caption_buttons/maximize_bubble_controller_bubble.h"
-
-#include "ash/frame/caption_buttons/bubble_contents_button_row.h"
-#include "ash/frame/caption_buttons/frame_maximize_button.h"
-#include "ash/frame/caption_buttons/maximize_bubble_controller.h"
-#include "ash/metrics/user_metrics_recorder.h"
-#include "ash/shell.h"
-#include "ash/shell_window_ids.h"
-#include "grit/ash_strings.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/path.h"
-#include "ui/views/bubble/bubble_frame_view.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/mouse_watcher.h"
-#include "ui/wm/core/masked_window_targeter.h"
-
-namespace ash {
-
-// BubbleContentsView ---------------------------------------------------------
-
-// A class which creates the content of the bubble: The buttons, and the label.
-class BubbleContentsView : public views::View {
- public:
-  BubbleContentsView(MaximizeBubbleControllerBubble* bubble,
-                     SnapType initial_snap_type);
-  virtual ~BubbleContentsView();
-
-  // Set the label content to reflect the currently selected |snap_type|.
-  // This function can be executed through the frame maximize button as well as
-  // through hover operations.
-  void SetSnapType(SnapType snap_type);
-
-  // Added for unit test: Retrieve the button for an action.
-  // |state| can be either SNAP_LEFT, SNAP_RIGHT or SNAP_MINIMIZE.
-  views::CustomButton* GetButtonForUnitTest(SnapType state);
-
- private:
-  // The owning class.
-  MaximizeBubbleControllerBubble* bubble_;
-
-  // The object which owns all the buttons.
-  BubbleContentsButtonRow* buttons_view_;
-
-  // The label object which shows the user the selected action.
-  views::Label* label_view_;
-
-  DISALLOW_COPY_AND_ASSIGN(BubbleContentsView);
-};
-
-BubbleContentsView::BubbleContentsView(
-    MaximizeBubbleControllerBubble* bubble,
-    SnapType initial_snap_type)
-    : bubble_(bubble),
-      buttons_view_(NULL),
-      label_view_(NULL) {
-  SetLayoutManager(new views::BoxLayout(
-      views::BoxLayout::kVertical, 0, 0,
-      MaximizeBubbleControllerBubble::kLayoutSpacing));
-  set_background(views::Background::CreateSolidBackground(
-      MaximizeBubbleControllerBubble::kBubbleBackgroundColor));
-
-  buttons_view_ = new BubbleContentsButtonRow(bubble);
-  AddChildView(buttons_view_);
-
-  label_view_ = new views::Label();
-  SetSnapType(initial_snap_type);
-  label_view_->SetBackgroundColor(
-      MaximizeBubbleControllerBubble::kBubbleBackgroundColor);
-  const SkColor kBubbleTextColor = SK_ColorWHITE;
-  label_view_->SetEnabledColor(kBubbleTextColor);
-  const int kLabelSpacing = 4;
-  label_view_->SetBorder(
-      views::Border::CreateEmptyBorder(kLabelSpacing, 0, kLabelSpacing, 0));
-  AddChildView(label_view_);
-}
-
-BubbleContentsView::~BubbleContentsView() {
-}
-
-// Set the label content to reflect the currently selected |snap_type|.
-// This function can be executed through the frame maximize button as well as
-// through hover operations.
-void BubbleContentsView::SetSnapType(SnapType snap_type) {
-  if (!bubble_->controller())
-    return;
-
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  int id = 0;
-  switch (snap_type) {
-    case SNAP_LEFT:
-      id = IDS_ASH_SNAP_WINDOW_LEFT;
-      break;
-    case SNAP_RIGHT:
-      id = IDS_ASH_SNAP_WINDOW_RIGHT;
-      break;
-    case SNAP_MAXIMIZE:
-      DCHECK_NE(FRAME_STATE_FULL, bubble_->controller()->maximize_type());
-      id = IDS_ASH_MAXIMIZE_WINDOW;
-      break;
-    case SNAP_MINIMIZE:
-      id = IDS_ASH_MINIMIZE_WINDOW;
-      break;
-    case SNAP_RESTORE:
-      DCHECK_NE(FRAME_STATE_NONE, bubble_->controller()->maximize_type());
-      id = IDS_ASH_RESTORE_WINDOW;
-      break;
-    default:
-      // If nothing is selected, we automatically select the click operation.
-      id = bubble_->controller()->maximize_type() == FRAME_STATE_FULL ?
-               IDS_ASH_RESTORE_WINDOW : IDS_ASH_MAXIMIZE_WINDOW;
-      break;
-  }
-  label_view_->SetText(rb.GetLocalizedString(id));
-}
-
-views::CustomButton* BubbleContentsView::GetButtonForUnitTest(SnapType state) {
-  return buttons_view_->GetButtonForUnitTest(state);
-}
-
-
-// MaximizeBubbleBorder -------------------------------------------------------
-
-namespace {
-
-const int kLineWidth = 1;
-const int kArrowHeight = 10;
-const int kArrowWidth = 20;
-
-}  // namespace
-
-class MaximizeBubbleBorder : public views::BubbleBorder {
- public:
-  MaximizeBubbleBorder(views::View* content_view, views::View* anchor);
-
-  virtual ~MaximizeBubbleBorder() {}
-
-  // Get the mouse active area of the window.
-  void GetMask(gfx::Path* mask);
-
-  // views::BubbleBorder:
-  virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to,
-                              const gfx::Size& contents_size) const OVERRIDE;
-  virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE;
-  virtual gfx::Size GetMinimumSize() const OVERRIDE;
-
- private:
-  // Note: Animations can continue after then main window frame was destroyed.
-  // To avoid this problem, the owning screen metrics get extracted upon
-  // creation.
-  gfx::Size anchor_size_;
-  gfx::Point anchor_screen_origin_;
-  views::View* content_view_;
-
-  DISALLOW_COPY_AND_ASSIGN(MaximizeBubbleBorder);
-};
-
-MaximizeBubbleBorder::MaximizeBubbleBorder(views::View* content_view,
-                                           views::View* anchor)
-    : views::BubbleBorder(
-          views::BubbleBorder::TOP_RIGHT, views::BubbleBorder::NO_SHADOW,
-          MaximizeBubbleControllerBubble::kBubbleBackgroundColor),
-      anchor_size_(anchor->size()),
-      anchor_screen_origin_(0, 0),
-      content_view_(content_view) {
-  views::View::ConvertPointToScreen(anchor, &anchor_screen_origin_);
-  set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
-}
-
-void MaximizeBubbleBorder::GetMask(gfx::Path* mask) {
-  gfx::Insets inset = GetInsets();
-  // Note: Even though the tip could be added as activatable, it is left out
-  // since it would not change the action behavior in any way plus it makes
-  // more sense to keep the focus on the underlying button for clicks.
-  int left = inset.left() - kLineWidth;
-  int right = inset.left() + content_view_->width() + kLineWidth;
-  int top = inset.top() - kLineWidth;
-  int bottom = inset.top() + content_view_->height() + kLineWidth;
-  mask->moveTo(left, top);
-  mask->lineTo(right, top);
-  mask->lineTo(right, bottom);
-  mask->lineTo(left, bottom);
-  mask->lineTo(left, top);
-  mask->close();
-}
-
-gfx::Rect MaximizeBubbleBorder::GetBounds(
-    const gfx::Rect& position_relative_to,
-    const gfx::Size& contents_size) const {
-  gfx::Size border_size(contents_size);
-  gfx::Insets insets = GetInsets();
-  border_size.Enlarge(insets.width(), insets.height());
-
-  // Position the bubble to center the box on the anchor.
-  int x = (anchor_size_.width() - border_size.width()) / 2;
-  // Position the bubble under the anchor, overlapping the arrow with it.
-  int y = anchor_size_.height() - insets.top();
-
-  gfx::Point view_origin(x + anchor_screen_origin_.x(),
-                         y + anchor_screen_origin_.y());
-
-  return gfx::Rect(view_origin, border_size);
-}
-
-void MaximizeBubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) {
-  gfx::Insets inset = GetInsets();
-
-  // Draw the border line around everything.
-  int y = inset.top();
-  // Top
-  canvas->FillRect(gfx::Rect(inset.left(),
-                             y - kLineWidth,
-                             content_view_->width(),
-                             kLineWidth),
-                   MaximizeBubbleControllerBubble::kBubbleBackgroundColor);
-  // Bottom
-  canvas->FillRect(gfx::Rect(inset.left(),
-                             y + content_view_->height(),
-                             content_view_->width(),
-                             kLineWidth),
-                   MaximizeBubbleControllerBubble::kBubbleBackgroundColor);
-  // Left
-  canvas->FillRect(gfx::Rect(inset.left() - kLineWidth,
-                             y - kLineWidth,
-                             kLineWidth,
-                             content_view_->height() + 2 * kLineWidth),
-                   MaximizeBubbleControllerBubble::kBubbleBackgroundColor);
-  // Right
-  canvas->FillRect(gfx::Rect(inset.left() + content_view_->width(),
-                             y - kLineWidth,
-                             kLineWidth,
-                             content_view_->height() + 2 * kLineWidth),
-                   MaximizeBubbleControllerBubble::kBubbleBackgroundColor);
-
-  // Draw the arrow afterwards covering the border.
-  SkPath path;
-  path.incReserve(4);
-  // The center of the tip should be in the middle of the button.
-  int tip_x = inset.left() + content_view_->width() / 2;
-  int left_base_x = tip_x - kArrowWidth / 2;
-  int left_base_y = y;
-  int tip_y = left_base_y - kArrowHeight;
-  path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y));
-  path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y));
-  path.lineTo(SkIntToScalar(left_base_x + kArrowWidth),
-              SkIntToScalar(left_base_y));
-
-  SkPaint paint;
-  paint.setStyle(SkPaint::kFill_Style);
-  paint.setColor(MaximizeBubbleControllerBubble::kBubbleBackgroundColor);
-  canvas->DrawPath(path, paint);
-}
-
-gfx::Size MaximizeBubbleBorder::GetMinimumSize() const {
-  return gfx::Size(kLineWidth * 2 + kArrowWidth,
-                   std::max(kLineWidth, kArrowHeight) + kLineWidth);
-}
-
-namespace {
-
-// MaximizebubbleTargeter  -----------------------------------------------------
-
-// Window targeter used for the bubble.
-class MaximizeBubbleTargeter : public ::wm::MaskedWindowTargeter {
- public:
-  MaximizeBubbleTargeter(aura::Window* window,
-                         MaximizeBubbleBorder* border)
-      : ::wm::MaskedWindowTargeter(window),
-        border_(border) {
-  }
-
-  virtual ~MaximizeBubbleTargeter() {}
-
- private:
-  // ::wm::MaskedWindowTargeter:
-  virtual bool GetHitTestMask(aura::Window* window,
-                              gfx::Path* mask) const OVERRIDE {
-    border_->GetMask(mask);
-    return true;
-  }
-
-  MaximizeBubbleBorder* border_;
-
-  DISALLOW_COPY_AND_ASSIGN(MaximizeBubbleTargeter);
-};
-
-}  // namespace
-
-
-// BubbleMouseWatcherHost -----------------------------------------------------
-
-// The mouse watcher host which makes sure that the bubble does not get closed
-// while the mouse cursor is over the maximize button or the balloon content.
-// Note: This object gets destroyed when the MouseWatcher gets destroyed.
-class BubbleMouseWatcherHost: public views::MouseWatcherHost {
- public:
-  explicit BubbleMouseWatcherHost(MaximizeBubbleControllerBubble* bubble);
-  virtual ~BubbleMouseWatcherHost();
-
-  // views::MouseWatcherHost:
-  virtual bool Contains(const gfx::Point& screen_point,
-                        views::MouseWatcherHost::MouseEventType type) OVERRIDE;
- private:
-  MaximizeBubbleControllerBubble* bubble_;
-
-  DISALLOW_COPY_AND_ASSIGN(BubbleMouseWatcherHost);
-};
-
-BubbleMouseWatcherHost::BubbleMouseWatcherHost(
-    MaximizeBubbleControllerBubble* bubble)
-    : bubble_(bubble) {
-}
-
-BubbleMouseWatcherHost::~BubbleMouseWatcherHost() {
-}
-
-bool BubbleMouseWatcherHost::Contains(
-    const gfx::Point& screen_point,
-    views::MouseWatcherHost::MouseEventType type) {
-  return bubble_->Contains(screen_point, type);
-}
-
-
-// MaximizeBubbleControllerBubble ---------------------------------------------
-
-// static
-const SkColor MaximizeBubbleControllerBubble::kBubbleBackgroundColor =
-    0xFF141414;
-const int MaximizeBubbleControllerBubble::kLayoutSpacing = -1;
-
-MaximizeBubbleControllerBubble::MaximizeBubbleControllerBubble(
-    MaximizeBubbleController* owner,
-    int appearance_delay_ms,
-    SnapType initial_snap_type)
-    : views::BubbleDelegateView(owner->frame_maximize_button(),
-                                views::BubbleBorder::TOP_RIGHT),
-      shutting_down_(false),
-      owner_(owner),
-      contents_view_(NULL),
-      bubble_border_(NULL),
-      appearance_delay_ms_(appearance_delay_ms) {
-  set_margins(gfx::Insets());
-
-  // The window needs to be owned by the root so that the phantom window does
-  // not cover it upon animation.
-  aura::Window* parent = Shell::GetContainer(Shell::GetTargetRootWindow(),
-                                             kShellWindowId_ShelfContainer);
-  set_parent_window(parent);
-
-  set_notify_enter_exit_on_child(true);
-  set_adjust_if_offscreen(false);
-  SetPaintToLayer(true);
-  set_color(kBubbleBackgroundColor);
-  set_close_on_deactivate(false);
-  set_background(
-      views::Background::CreateSolidBackground(kBubbleBackgroundColor));
-
-  SetLayoutManager(new views::BoxLayout(
-      views::BoxLayout::kVertical, 0, 0, kLayoutSpacing));
-
-  contents_view_ = new BubbleContentsView(this, initial_snap_type);
-  AddChildView(contents_view_);
-
-  // Note that the returned widget has an observer which points to our
-  // functions.
-  views::Widget* bubble_widget = views::BubbleDelegateView::CreateBubble(this);
-  bubble_widget->set_focus_on_creation(false);
-
-  SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
-  bubble_widget->non_client_view()->frame_view()->set_background(NULL);
-
-  bubble_border_ = new MaximizeBubbleBorder(this, GetAnchorView());
-  GetBubbleFrameView()->SetBubbleBorder(
-      scoped_ptr<views::BubbleBorder>(bubble_border_));
-  GetBubbleFrameView()->set_background(NULL);
-
-  // Recalculate size with new border.
-  SizeToContents();
-
-  GetWidget()->Show();
-
-  aura::Window* window = bubble_widget->GetNativeWindow();
-  window->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
-      new MaximizeBubbleTargeter(window, bubble_border_)));
-
-  ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
-      ash::UMA_WINDOW_MAXIMIZE_BUTTON_SHOW_BUBBLE);
-
-  mouse_watcher_.reset(new views::MouseWatcher(
-      new BubbleMouseWatcherHost(this),
-      this));
-  mouse_watcher_->Start();
-}
-
-MaximizeBubbleControllerBubble::~MaximizeBubbleControllerBubble() {
-}
-
-aura::Window* MaximizeBubbleControllerBubble::GetBubbleWindow() {
-  return GetWidget()->GetNativeWindow();
-}
-
-gfx::Rect MaximizeBubbleControllerBubble::GetAnchorRect() {
-  if (!owner_)
-    return gfx::Rect();
-
-  gfx::Rect anchor_rect =
-      owner_->frame_maximize_button()->GetBoundsInScreen();
-  return anchor_rect;
-}
-
-bool MaximizeBubbleControllerBubble::CanActivate() const {
-  return false;
-}
-
-bool MaximizeBubbleControllerBubble::WidgetHasHitTestMask() const {
-  return bubble_border_ != NULL;
-}
-
-void MaximizeBubbleControllerBubble::GetWidgetHitTestMask(
-    gfx::Path* mask) const {
-  DCHECK(mask);
-  DCHECK(bubble_border_);
-  bubble_border_->GetMask(mask);
-}
-
-void MaximizeBubbleControllerBubble::MouseMovedOutOfHost() {
-  if (!owner_ || shutting_down_)
-    return;
-  // When we leave the bubble, we might be still be in gesture mode or over
-  // the maximize button. So only close if none of the other cases apply.
-  if (!owner_->frame_maximize_button()->is_snap_enabled()) {
-    gfx::Point screen_location = Shell::GetScreen()->GetCursorScreenPoint();
-    if (!owner_->frame_maximize_button()->GetBoundsInScreen().Contains(
-        screen_location)) {
-      owner_->RequestDestructionThroughOwner();
-    }
-  }
-}
-
-bool MaximizeBubbleControllerBubble::Contains(
-    const gfx::Point& screen_point,
-    views::MouseWatcherHost::MouseEventType type) {
-  if (!owner_ || shutting_down_)
-    return false;
-  bool inside_button =
-      owner_->frame_maximize_button()->GetBoundsInScreen().Contains(
-          screen_point);
-  if (!owner_->frame_maximize_button()->is_snap_enabled() && inside_button) {
-    SetSnapType(controller()->maximize_type() == FRAME_STATE_FULL ?
-        SNAP_RESTORE : SNAP_MAXIMIZE);
-    return true;
-  }
-  // Check if either a gesture is taking place (=> bubble stays no matter what
-  // the mouse does) or the mouse is over the maximize button or the bubble
-  // content.
-  return (owner_->frame_maximize_button()->is_snap_enabled() ||
-          inside_button ||
-          contents_view_->GetBoundsInScreen().Contains(screen_point));
-}
-
-gfx::Size MaximizeBubbleControllerBubble::GetPreferredSize() {
-  return contents_view_->GetPreferredSize();
-}
-
-void MaximizeBubbleControllerBubble::OnWidgetDestroying(views::Widget* widget) {
-  if (GetWidget() == widget) {
-    mouse_watcher_->Stop();
-
-    if (owner_) {
-      // If the bubble destruction was triggered by some other external
-      // influence then ourselves, the owner needs to be informed that the menu
-      // is gone.
-      shutting_down_ = true;
-      owner_->RequestDestructionThroughOwner();
-      owner_ = NULL;
-    }
-  }
-  BubbleDelegateView::OnWidgetDestroying(widget);
-}
-
-void MaximizeBubbleControllerBubble::ControllerRequestsCloseAndDelete() {
-  // This only gets called from the owning base class once it is deleted.
-  if (shutting_down_)
-    return;
-  shutting_down_ = true;
-  owner_ = NULL;
-
-  // Close the widget asynchronously after the hide animation is finished.
-  if (!appearance_delay_ms_)
-    GetWidget()->CloseNow();
-  else
-    GetWidget()->Close();
-}
-
-void MaximizeBubbleControllerBubble::SetSnapType(SnapType snap_type) {
-  if (contents_view_)
-    contents_view_->SetSnapType(snap_type);
-}
-
-views::CustomButton* MaximizeBubbleControllerBubble::GetButtonForUnitTest(
-    SnapType state) {
-  return contents_view_->GetButtonForUnitTest(state);
-}
-
-}  // namespace ash
diff --git a/ash/frame/caption_buttons/maximize_bubble_controller_bubble.h b/ash/frame/caption_buttons/maximize_bubble_controller_bubble.h
deleted file mode 100644
index f2e25d6..0000000
--- a/ash/frame/caption_buttons/maximize_bubble_controller_bubble.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef ASH_FRAME_CAPTION_BUTTONS_MAXIMIZE_BUBBLE_CONTROLLER_BUBBLE_H_
-#define ASH_FRAME_CAPTION_BUTTONS_MAXIMIZE_BUBBLE_CONTROLLER_BUBBLE_H_
-
-#include "ash/wm/workspace/snap_types.h"
-#include "ui/views/bubble/bubble_delegate.h"
-#include "ui/views/mouse_watcher.h"
-
-namespace views {
-class CustomButton;
-}
-
-namespace ash {
-
-class BubbleContentsView;
-class MaximizeBubbleBorder;
-class MaximizeBubbleController;
-
-// The class which creates and manages the bubble menu element.
-// It creates a 'bubble border' and the content accordingly.
-// Note: Since the phantom window will show animations on top of the maximize
-// button this menu gets created as a separate window and the phantom window
-// will be created underneath this window.
-class MaximizeBubbleControllerBubble : public views::BubbleDelegateView,
-                                       public views::MouseWatcherListener {
- public:
-  static const SkColor kBubbleBackgroundColor;
-  static const int kLayoutSpacing;  // The spacing between two buttons.
-
-  MaximizeBubbleControllerBubble(MaximizeBubbleController* owner,
-                                 int appearance_delay_ms,
-                                 SnapType initial_snap_type);
-  virtual ~MaximizeBubbleControllerBubble();
-
-  // The window of the menu under which the phantom window will get created.
-  aura::Window* GetBubbleWindow();
-
-  // Overridden from views::BubbleDelegateView.
-  virtual gfx::Rect GetAnchorRect() OVERRIDE;
-  virtual bool CanActivate() const OVERRIDE;
-
-  // Overridden from views::WidgetDelegateView.
-  virtual bool WidgetHasHitTestMask() const OVERRIDE;
-  virtual void GetWidgetHitTestMask(gfx::Path* mask) const OVERRIDE;
-
-  // Implementation of MouseWatcherListener.
-  virtual void MouseMovedOutOfHost() OVERRIDE;
-
-  // Implementation of MouseWatcherHost.
-  virtual bool Contains(const gfx::Point& screen_point,
-                        views::MouseWatcherHost::MouseEventType type);
-
-  // Overridden from views::View.
-  virtual gfx::Size GetPreferredSize() OVERRIDE;
-
-  // Overridden from views::Widget::Observer.
-  virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
-
-  // Called from the controller class to indicate that the menu should get
-  // destroyed.
-  virtual void ControllerRequestsCloseAndDelete();
-
-  // Called from the owning class to change the menu content to the given
-  // |snap_type| so that the user knows what is selected.
-  void SetSnapType(SnapType snap_type);
-
-  // Get the owning MaximizeBubbleController. This might return NULL in case
-  // of an asynchronous shutdown.
-  MaximizeBubbleController* controller() const { return owner_; }
-
-  // Added for unit test: Retrieve the button for an action.
-  // |state| can be either SNAP_LEFT, SNAP_RIGHT or SNAP_MINIMIZE.
-  views::CustomButton* GetButtonForUnitTest(SnapType state);
-
- private:
-  // True if the shut down has been initiated.
-  bool shutting_down_;
-
-  // Our owning class.
-  MaximizeBubbleController* owner_;
-
-  // The content accessor of the menu.
-  BubbleContentsView* contents_view_;
-
-  // The bubble border (weak reference).
-  MaximizeBubbleBorder* bubble_border_;
-
-  // The mouse watcher which takes care of out of window hover events.
-  scoped_ptr<views::MouseWatcher> mouse_watcher_;
-
-  // The fade delay - if 0 it will show / hide immediately.
-  const int appearance_delay_ms_;
-
-  DISALLOW_COPY_AND_ASSIGN(MaximizeBubbleControllerBubble);
-};
-
-}  // namespace ash
-
-#endif  // ASH_FRAME_CAPTION_BUTTONS_MAXIMIZE_BUBBLE_CONTROLLER_BUBBLE_H_
diff --git a/ash/frame/custom_frame_view_ash.cc b/ash/frame/custom_frame_view_ash.cc
index 8ab7e23..68bc36a 100644
--- a/ash/frame/custom_frame_view_ash.cc
+++ b/ash/frame/custom_frame_view_ash.cc
@@ -6,8 +6,6 @@
 
 #include "ash/ash_switches.h"
 #include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
-#include "ash/frame/caption_buttons/frame_maximize_button.h"
-#include "ash/frame/caption_buttons/frame_maximize_button_observer.h"
 #include "ash/frame/default_header_painter.h"
 #include "ash/frame/frame_border_hit_test_controller.h"
 #include "ash/frame/frame_util.h"
@@ -32,7 +30,6 @@
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
-#include "ui/views/widget/widget_deletion_observer.h"
 
 namespace {
 
@@ -127,7 +124,6 @@
 class CustomFrameViewAsh::HeaderView
     : public views::View,
       public ImmersiveFullscreenController::Delegate,
-      public FrameMaximizeButtonObserver,
       public ShellObserver {
  public:
   // |frame| is the widget that the caption buttons act on.
@@ -175,9 +171,6 @@
   virtual void SetVisibleFraction(double visible_fraction) OVERRIDE;
   virtual std::vector<gfx::Rect> GetVisibleBoundsInScreen() const OVERRIDE;
 
-  // FrameMaximizeButtonObserver:
-  virtual void OnMaximizeBubbleShown(views::Widget* bubble) OVERRIDE;
-
   // The widget that the caption buttons act on.
   views::Widget* frame_;
 
@@ -189,13 +182,6 @@
   // View which contains the window caption buttons.
   FrameCaptionButtonContainerView* caption_button_container_;
 
-  // The maximize bubble widget. |maximize_bubble_| may be non-NULL but have
-  // been already destroyed.
-  views::Widget* maximize_bubble_;
-
-  // Keeps track of whether |maximize_bubble_| is still alive.
-  scoped_ptr<views::WidgetDeletionObserver> maximize_bubble_lifetime_observer_;
-
   // The fraction of the header's height which is visible while in fullscreen.
   // This value is meaningless when not in fullscreen.
   double fullscreen_visible_fraction_;
@@ -208,7 +194,6 @@
       header_painter_(new ash::DefaultHeaderPainter),
       avatar_icon_(NULL),
       caption_button_container_(NULL),
-      maximize_bubble_(NULL),
       fullscreen_visible_fraction_(0) {
   // Unfortunately, there is no views::WidgetDelegate::CanMinimize(). Assume
   // that the window frame can be minimized if it can be maximized.
@@ -221,10 +206,6 @@
   caption_button_container_->UpdateSizeButtonVisibility(Shell::GetInstance()->
       IsMaximizeModeWindowManagerEnabled());
   AddChildView(caption_button_container_);
-  FrameMaximizeButton* frame_maximize_button =
-      caption_button_container_->GetOldStyleSizeButton();
-  if (frame_maximize_button)
-    frame_maximize_button->AddObserver(this);
 
   header_painter_->Init(frame_, this, NULL, caption_button_container_);
   UpdateAvatarIcon();
@@ -233,10 +214,6 @@
 }
 
 CustomFrameViewAsh::HeaderView::~HeaderView() {
-  FrameMaximizeButton* frame_maximize_button =
-      caption_button_container_->GetOldStyleSizeButton();
-  if (frame_maximize_button)
-    frame_maximize_button->RemoveObserver(this);
   Shell::GetInstance()->RemoveShellObserver(this);
 }
 
@@ -361,24 +338,10 @@
   std::vector<gfx::Rect> bounds_in_screen;
   bounds_in_screen.push_back(
       gfx::Rect(visible_origin_in_screen, visible_bounds.size()));
-  if (maximize_bubble_lifetime_observer_.get() &&
-      maximize_bubble_lifetime_observer_->IsWidgetAlive()) {
-    bounds_in_screen.push_back(maximize_bubble_->GetWindowBoundsInScreen());
-  }
   return bounds_in_screen;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// CustomFrameViewAsh::HeaderView, FrameMaximizeButtonObserver overrides:
-
-void CustomFrameViewAsh::HeaderView::OnMaximizeBubbleShown(
-    views::Widget* bubble) {
-  maximize_bubble_ = bubble;
-  maximize_bubble_lifetime_observer_.reset(
-      new views::WidgetDeletionObserver(bubble));
-}
-
-///////////////////////////////////////////////////////////////////////////////
 // CustomFrameViewAsh::OverlayView
 
 // View which takes up the entire widget and contains the HeaderView. HeaderView
diff --git a/ash/ime/infolist_window.cc b/ash/ime/infolist_window.cc
index e48e88e..c29d623 100644
--- a/ash/ime/infolist_window.cc
+++ b/ash/ime/infolist_window.cc
@@ -172,7 +172,6 @@
       title_font_list_(gfx::Font(kJapaneseFontName, kFontSizeDelta + 15)),
       description_font_list_(gfx::Font(kJapaneseFontName,
                                        kFontSizeDelta + 11)) {
-  set_move_with_anchor(true);
   set_margins(gfx::Insets());
 
   set_background(
diff --git a/ash/media_delegate.h b/ash/media_delegate.h
index 1dac059..4ea9a17 100644
--- a/ash/media_delegate.h
+++ b/ash/media_delegate.h
@@ -5,8 +5,19 @@
 #ifndef ASH_MEDIA_DELEGATE_H_
 #define ASH_MEDIA_DELEGATE_H_
 
+namespace content {
+class BrowserContext;
+}
+
 namespace ash {
 
+enum MediaCaptureState {
+  MEDIA_CAPTURE_NONE = 0,
+  MEDIA_CAPTURE_AUDIO = 1 << 0,
+  MEDIA_CAPTURE_VIDEO = 1 << 1,
+  MEDIA_CAPTURE_AUDIO_VIDEO = MEDIA_CAPTURE_AUDIO | MEDIA_CAPTURE_VIDEO,
+};
+
 // A delegate class to control media playback.
 class MediaDelegate {
  public:
@@ -20,6 +31,11 @@
 
   // Handles the Previous Track Media shortcut key.
   virtual void HandleMediaPrevTrack() = 0;
+
+  // Returns the current media recording state of web contents
+  // that belongs to the |context|.
+  virtual MediaCaptureState GetMediaCaptureState(
+      content::BrowserContext* context) = 0;
 };
 
 }  // namespace ash
diff --git a/ash/metrics/user_metrics_recorder.cc b/ash/metrics/user_metrics_recorder.cc
index a71271b..a44cc78 100644
--- a/ash/metrics/user_metrics_recorder.cc
+++ b/ash/metrics/user_metrics_recorder.cc
@@ -357,24 +357,12 @@
     case ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MINIMIZE:
       base::RecordAction(base::UserMetricsAction("MinButton_Clk"));
       break;
-    case ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE:
-      base::RecordAction(base::UserMetricsAction("MaxButton_Maximize"));
-      break;
     case ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT:
       base::RecordAction(base::UserMetricsAction("MaxButton_MaxLeft"));
       break;
     case ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT:
       base::RecordAction(base::UserMetricsAction("MaxButton_MaxRight"));
       break;
-    case ash::UMA_WINDOW_MAXIMIZE_BUTTON_MINIMIZE:
-      base::RecordAction(base::UserMetricsAction("MaxButton_Minimize"));
-      break;
-    case ash::UMA_WINDOW_MAXIMIZE_BUTTON_RESTORE:
-      base::RecordAction(base::UserMetricsAction("MaxButton_Restore"));
-      break;
-    case ash::UMA_WINDOW_MAXIMIZE_BUTTON_SHOW_BUBBLE:
-      base::RecordAction(base::UserMetricsAction("MaxButton_ShowBubble"));
-      break;
     case ash::UMA_WINDOW_OVERVIEW:
       base::RecordAction(
           base::UserMetricsAction("WindowSelector_Overview"));
diff --git a/ash/metrics/user_metrics_recorder.h b/ash/metrics/user_metrics_recorder.h
index 618b70f..98eb652 100644
--- a/ash/metrics/user_metrics_recorder.h
+++ b/ash/metrics/user_metrics_recorder.h
@@ -97,12 +97,8 @@
   UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MAXIMIZE,
   UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MINIMIZE,
   UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_RESTORE,
-  UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE,
   UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT,
   UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT,
-  UMA_WINDOW_MAXIMIZE_BUTTON_MINIMIZE,
-  UMA_WINDOW_MAXIMIZE_BUTTON_RESTORE,
-  UMA_WINDOW_MAXIMIZE_BUTTON_SHOW_BUBBLE,
 
   // Thumbnail sized overview of windows triggered. This is a subset of
   // UMA_WINDOW_SELECTION triggered by lingering during alt+tab cycles or
diff --git a/ash/resources/ash_resources.grd b/ash/resources/ash_resources.grd
index 1201745..825cade 100644
--- a/ash/resources/ash_resources.grd
+++ b/ash/resources/ash_resources.grd
@@ -77,6 +77,7 @@
 
       <structure type="chrome_scaled_image" name="IDR_AURA_WARNING_ICON" file="common/alert_small.png" />
 
+      <!-- TODO(oshima): Make following resources cros only -->
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_ACCESSIBILITY" file="cros/status/status_accessibility_mode.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK" file="cros/status/status_accessibility_dark.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_BLUETOOTH" file="cros/status/status_bluetooth.png" />
@@ -187,6 +188,8 @@
         <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NETWORK_VPN" file="cros/network/statusbar_vpn_dark.png" />
         <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NETWORK_VPN_BADGE" file="cros/network/statusbar_network_vpn_badge.png" />
         <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_NETWORK_WIRED" file="cros/network/statusbar_wired.png" />
+        <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_RECORDING" file="cros/status/status_recording.png" />
+        <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_RECORDING_RED" file="cros/status/status_recording_red.png" />
         <structure type="chrome_scaled_image" name="IDR_AURA_UBER_TRAY_VIRTUAL_KEYBOARD" file="cros/status/status_virtual_keyboard.png" />
       </if>
 
@@ -238,21 +241,6 @@
       <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_OVERVIEW_CLOSE_H" file="common/window_overview_close_hover.png" />
       <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_OVERVIEW_CLOSE_P" file="common/window_overview_close_pressed.png" />
 
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_LEFT" file="common/window_position_left_normal.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_LEFT_H" file="common/window_position_left_hover.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_LEFT_P" file="common/window_position_left_pressed.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_MIDDLE" file="common/window_position_middle_normal.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_MIDDLE_H" file="common/window_position_middle_hover.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_MIDDLE_P" file="common/window_position_middle_pressed.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_RIGHT" file="common/window_position_right_normal.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_RIGHT_H" file="common/window_position_right_hover.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_RIGHT_P" file="common/window_position_right_pressed.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_LEFT_RESTORE" file="common/window_position_left_normal_restore.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_LEFT_RESTORE_H" file="common/window_position_left_hover_restore.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_LEFT_RESTORE_P" file="common/window_position_left_pressed_restore.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_RIGHT_RESTORE" file="common/window_position_right_normal_restore.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_RIGHT_RESTORE_H" file="common/window_position_right_hover_restore.png" />
-      <structure type="chrome_scaled_image" name="IDR_AURA_WINDOW_POSITION_RIGHT_RESTORE_P" file="common/window_position_right_pressed_restore.png" />
       <structure type="chrome_scaled_image" name="IDR_AVATAR_HOLDER" file="cros/avatar_holder.png" />
       <structure type="chrome_scaled_image" name="IDR_AVATAR_HOLDER_MASK" file="cros/avatar_holder_mask.png" />
     </structures>
diff --git a/ash/resources/default_100_percent/common/window_position_left_hover.png b/ash/resources/default_100_percent/common/window_position_left_hover.png
deleted file mode 100644
index 420d392..0000000
--- a/ash/resources/default_100_percent/common/window_position_left_hover.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_left_hover_restore.png b/ash/resources/default_100_percent/common/window_position_left_hover_restore.png
deleted file mode 100644
index f94002b..0000000
--- a/ash/resources/default_100_percent/common/window_position_left_hover_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_left_normal.png b/ash/resources/default_100_percent/common/window_position_left_normal.png
deleted file mode 100644
index c082951..0000000
--- a/ash/resources/default_100_percent/common/window_position_left_normal.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_left_normal_restore.png b/ash/resources/default_100_percent/common/window_position_left_normal_restore.png
deleted file mode 100644
index 67312ab..0000000
--- a/ash/resources/default_100_percent/common/window_position_left_normal_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_left_pressed.png b/ash/resources/default_100_percent/common/window_position_left_pressed.png
deleted file mode 100644
index 4201d2a..0000000
--- a/ash/resources/default_100_percent/common/window_position_left_pressed.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_left_pressed_restore.png b/ash/resources/default_100_percent/common/window_position_left_pressed_restore.png
deleted file mode 100644
index 8841553..0000000
--- a/ash/resources/default_100_percent/common/window_position_left_pressed_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_middle_hover.png b/ash/resources/default_100_percent/common/window_position_middle_hover.png
deleted file mode 100644
index aaff1c5..0000000
--- a/ash/resources/default_100_percent/common/window_position_middle_hover.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_middle_normal.png b/ash/resources/default_100_percent/common/window_position_middle_normal.png
deleted file mode 100644
index 090b669..0000000
--- a/ash/resources/default_100_percent/common/window_position_middle_normal.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_middle_pressed.png b/ash/resources/default_100_percent/common/window_position_middle_pressed.png
deleted file mode 100644
index 66d29b0..0000000
--- a/ash/resources/default_100_percent/common/window_position_middle_pressed.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_right_hover.png b/ash/resources/default_100_percent/common/window_position_right_hover.png
deleted file mode 100644
index e424d95..0000000
--- a/ash/resources/default_100_percent/common/window_position_right_hover.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_right_hover_restore.png b/ash/resources/default_100_percent/common/window_position_right_hover_restore.png
deleted file mode 100644
index 7583d26..0000000
--- a/ash/resources/default_100_percent/common/window_position_right_hover_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_right_normal.png b/ash/resources/default_100_percent/common/window_position_right_normal.png
deleted file mode 100644
index d2c4479..0000000
--- a/ash/resources/default_100_percent/common/window_position_right_normal.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_right_normal_restore.png b/ash/resources/default_100_percent/common/window_position_right_normal_restore.png
deleted file mode 100644
index 9da0761..0000000
--- a/ash/resources/default_100_percent/common/window_position_right_normal_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_right_pressed.png b/ash/resources/default_100_percent/common/window_position_right_pressed.png
deleted file mode 100644
index 7fa9303..0000000
--- a/ash/resources/default_100_percent/common/window_position_right_pressed.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_100_percent/common/window_position_right_pressed_restore.png b/ash/resources/default_100_percent/common/window_position_right_pressed_restore.png
deleted file mode 100644
index 790ee0e..0000000
--- a/ash/resources/default_100_percent/common/window_position_right_pressed_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_left_hover.png b/ash/resources/default_200_percent/common/window_position_left_hover.png
deleted file mode 100644
index 4d79bb2..0000000
--- a/ash/resources/default_200_percent/common/window_position_left_hover.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_left_hover_restore.png b/ash/resources/default_200_percent/common/window_position_left_hover_restore.png
deleted file mode 100644
index 61c5387..0000000
--- a/ash/resources/default_200_percent/common/window_position_left_hover_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_left_normal.png b/ash/resources/default_200_percent/common/window_position_left_normal.png
deleted file mode 100644
index 58e21b9..0000000
--- a/ash/resources/default_200_percent/common/window_position_left_normal.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_left_normal_restore.png b/ash/resources/default_200_percent/common/window_position_left_normal_restore.png
deleted file mode 100644
index bba0ff4..0000000
--- a/ash/resources/default_200_percent/common/window_position_left_normal_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_left_pressed.png b/ash/resources/default_200_percent/common/window_position_left_pressed.png
deleted file mode 100644
index b7fae08..0000000
--- a/ash/resources/default_200_percent/common/window_position_left_pressed.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_left_pressed_restore.png b/ash/resources/default_200_percent/common/window_position_left_pressed_restore.png
deleted file mode 100644
index 0f9e0c9..0000000
--- a/ash/resources/default_200_percent/common/window_position_left_pressed_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_middle_hover.png b/ash/resources/default_200_percent/common/window_position_middle_hover.png
deleted file mode 100644
index fe65289..0000000
--- a/ash/resources/default_200_percent/common/window_position_middle_hover.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_middle_normal.png b/ash/resources/default_200_percent/common/window_position_middle_normal.png
deleted file mode 100644
index 0cda265..0000000
--- a/ash/resources/default_200_percent/common/window_position_middle_normal.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_middle_pressed.png b/ash/resources/default_200_percent/common/window_position_middle_pressed.png
deleted file mode 100644
index f664867..0000000
--- a/ash/resources/default_200_percent/common/window_position_middle_pressed.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_right_hover.png b/ash/resources/default_200_percent/common/window_position_right_hover.png
deleted file mode 100644
index e31c729..0000000
--- a/ash/resources/default_200_percent/common/window_position_right_hover.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_right_hover_restore.png b/ash/resources/default_200_percent/common/window_position_right_hover_restore.png
deleted file mode 100644
index e5a5be3..0000000
--- a/ash/resources/default_200_percent/common/window_position_right_hover_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_right_normal.png b/ash/resources/default_200_percent/common/window_position_right_normal.png
deleted file mode 100644
index 1a8e7a2..0000000
--- a/ash/resources/default_200_percent/common/window_position_right_normal.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_right_normal_restore.png b/ash/resources/default_200_percent/common/window_position_right_normal_restore.png
deleted file mode 100644
index 3cf2d4b..0000000
--- a/ash/resources/default_200_percent/common/window_position_right_normal_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_right_pressed.png b/ash/resources/default_200_percent/common/window_position_right_pressed.png
deleted file mode 100644
index b5e5336..0000000
--- a/ash/resources/default_200_percent/common/window_position_right_pressed.png
+++ /dev/null
Binary files differ
diff --git a/ash/resources/default_200_percent/common/window_position_right_pressed_restore.png b/ash/resources/default_200_percent/common/window_position_right_pressed_restore.png
deleted file mode 100644
index 62bb151..0000000
--- a/ash/resources/default_200_percent/common/window_position_right_pressed_restore.png
+++ /dev/null
Binary files differ
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 368dd92..2bcec0c 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -28,6 +28,7 @@
 #include "ash/switchable_windows.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/tray/system_tray_delegate.h"
+#include "ash/system/tray/system_tray_notifier.h"
 #include "ash/touch/touch_hud_debug.h"
 #include "ash/touch/touch_hud_projection.h"
 #include "ash/touch/touch_observer_hud.h"
@@ -74,7 +75,9 @@
 #include "ui/wm/public/window_types.h"
 
 #if defined(OS_CHROMEOS)
+#include "ash/system/tray_accessibility.h"
 #include "ash/wm/boot_splash_screen_chromeos.h"
+#include "ui/chromeos/touch_exploration_controller.h"
 #endif
 
 namespace ash {
@@ -257,6 +260,54 @@
   DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate);
 };
 
+#if defined(OS_CHROMEOS)
+// Responsible for initializing TouchExplorationController when spoken
+// feedback is on.
+class CrosAccessibilityObserver : public AccessibilityObserver {
+ public:
+  explicit CrosAccessibilityObserver(
+      RootWindowController* root_window_controller)
+      : root_window_controller_(root_window_controller) {
+    Shell::GetInstance()->system_tray_notifier()->
+        AddAccessibilityObserver(this);
+    UpdateTouchExplorationState();
+  }
+
+  virtual ~CrosAccessibilityObserver() {
+    SystemTrayNotifier* system_tray_notifier =
+        Shell::GetInstance()->system_tray_notifier();
+    if (system_tray_notifier)
+      system_tray_notifier->RemoveAccessibilityObserver(this);
+  }
+
+ private:
+  void UpdateTouchExplorationState() {
+    AccessibilityDelegate* delegate =
+        Shell::GetInstance()->accessibility_delegate();
+    bool enabled = delegate->IsSpokenFeedbackEnabled();
+
+    if (enabled && !touch_exploration_controller_.get()) {
+      touch_exploration_controller_.reset(
+          new ui::TouchExplorationController(
+              root_window_controller_->GetRootWindow()));
+    } else if (!enabled) {
+      touch_exploration_controller_.reset();
+    }
+  }
+
+  // Overridden from AccessibilityObserver.
+  virtual void OnAccessibilityModeChanged(
+      AccessibilityNotificationVisibility notify) OVERRIDE {
+    UpdateTouchExplorationState();
+  }
+
+  scoped_ptr<ui::TouchExplorationController> touch_exploration_controller_;
+  RootWindowController* root_window_controller_;
+
+  DISALLOW_COPY_AND_ASSIGN(CrosAccessibilityObserver);
+};
+#endif // OS_CHROMEOS
+
 }  // namespace
 
 void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) {
@@ -339,7 +390,14 @@
 }
 
 void RootWindowController::Shutdown() {
-  Shell::GetInstance()->RemoveShellObserver(this);
+  Shell* shell = Shell::GetInstance();
+  shell->RemoveShellObserver(this);
+
+#if defined(OS_CHROMEOS)
+  if (cros_accessibility_observer_) {
+    cros_accessibility_observer_.reset();
+  }
+#endif
 
   if (animating_wallpaper_controller_.get())
     animating_wallpaper_controller_->StopAnimating();
@@ -351,7 +409,7 @@
   // window list adding windows from the target root window's containers which
   // may have already gone away.
   if (Shell::GetTargetRootWindow() == root_window) {
-    Shell::GetInstance()->set_target_root_window(
+    shell->set_target_root_window(
         Shell::GetPrimaryRootWindow() == root_window
             ? NULL
             : Shell::GetPrimaryRootWindow());
@@ -738,6 +796,13 @@
     // Notify shell observers about new root window.
     shell->OnRootWindowAdded(root_window);
   }
+
+#if defined(OS_CHROMEOS)
+  if (CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kAshEnableTouchExplorationMode)) {
+    cros_accessibility_observer_.reset(new CrosAccessibilityObserver(this));
+  }
+#endif
 }
 
 void RootWindowController::InitLayoutManagers() {
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h
index 6199a5c..b7a059f 100644
--- a/ash/root_window_controller.h
+++ b/ash/root_window_controller.h
@@ -68,6 +68,7 @@
 
 #if defined(OS_CHROMEOS)
 class BootSplashScreen;
+class AccessibilityObserver;
 #endif
 
 // This class maintains the per root window state for ash. This class
@@ -293,8 +294,12 @@
   PanelLayoutManager* panel_layout_manager_;
 
   scoped_ptr<SystemBackgroundController> system_background_;
+
 #if defined(OS_CHROMEOS)
   scoped_ptr<BootSplashScreen> boot_splash_screen_;
+  // Responsible for initializing TouchExplorationController when spoken
+  // feedback is on.
+  scoped_ptr<AccessibilityObserver> cros_accessibility_observer_;
 #endif
 
   scoped_ptr<ScreenDimmer> screen_dimmer_;
diff --git a/ash/session/session_state_delegate_stub.cc b/ash/session/session_state_delegate_stub.cc
deleted file mode 100644
index 05bca13..0000000
--- a/ash/session/session_state_delegate_stub.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2013 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.
-
-#include "ash/session/session_state_delegate_stub.h"
-
-#include "ash/session/user_info.h"
-#include "ash/shell.h"
-#include "ash/shell/example_factory.h"
-#include "ash/shell_delegate.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/gfx/image/image_skia.h"
-
-namespace ash {
-namespace {
-
-class UserInfoStub : public UserInfo {
- public:
-  UserInfoStub() {}
-  virtual ~UserInfoStub() {}
-
-  // UserInfo:
-  virtual base::string16 GetDisplayName() const OVERRIDE {
-    return base::UTF8ToUTF16("stub-user");
-  }
-  virtual base::string16 GetGivenName() const OVERRIDE {
-    return base::UTF8ToUTF16("Stub");
-  }
-  virtual std::string GetEmail() const OVERRIDE {
-    return "stub-user@domain.com";
-  }
-  virtual std::string GetUserID() const OVERRIDE { return GetEmail(); }
-  virtual const gfx::ImageSkia& GetImage() const OVERRIDE {
-    return user_image_;
-  }
-
- private:
-  gfx::ImageSkia user_image_;
-
-  DISALLOW_COPY_AND_ASSIGN(UserInfoStub);
-};
-
-}  // namespace
-
-SessionStateDelegateStub::SessionStateDelegateStub()
-    : screen_locked_(false), user_info_(new UserInfoStub()) {
-}
-
-SessionStateDelegateStub::~SessionStateDelegateStub() {
-}
-
-content::BrowserContext* SessionStateDelegateStub::GetBrowserContextByIndex(
-    MultiProfileIndex index) {
-  return Shell::GetInstance()->delegate()->GetActiveBrowserContext();
-}
-
-content::BrowserContext* SessionStateDelegateStub::GetBrowserContextForWindow(
-    aura::Window* window) {
-  return Shell::GetInstance()->delegate()->GetActiveBrowserContext();
-}
-
-int SessionStateDelegateStub::GetMaximumNumberOfLoggedInUsers() const {
-  return 3;
-}
-
-int SessionStateDelegateStub::NumberOfLoggedInUsers() const {
-  return 1;
-}
-
-bool SessionStateDelegateStub::IsActiveUserSessionStarted() const {
-  return true;
-}
-
-bool SessionStateDelegateStub::CanLockScreen() const {
-  return true;
-}
-
-bool SessionStateDelegateStub::IsScreenLocked() const {
-  return screen_locked_;
-}
-
-bool SessionStateDelegateStub::ShouldLockScreenBeforeSuspending() const {
-  return false;
-}
-
-void SessionStateDelegateStub::LockScreen() {
-  shell::CreateLockScreen();
-  screen_locked_ = true;
-  Shell::GetInstance()->UpdateShelfVisibility();
-}
-
-void SessionStateDelegateStub::UnlockScreen() {
-  screen_locked_ = false;
-  Shell::GetInstance()->UpdateShelfVisibility();
-}
-
-bool SessionStateDelegateStub::IsUserSessionBlocked() const {
-  return !IsActiveUserSessionStarted() || IsScreenLocked();
-}
-
-SessionStateDelegate::SessionState SessionStateDelegateStub::GetSessionState()
-    const {
-  // Assume that if session is not active we're at login.
-  return IsActiveUserSessionStarted() ? SESSION_STATE_ACTIVE
-                                      : SESSION_STATE_LOGIN_PRIMARY;
-}
-
-const UserInfo* SessionStateDelegateStub::GetUserInfo(
-    MultiProfileIndex index) const {
-  return user_info_.get();
-}
-
-const UserInfo* SessionStateDelegateStub::GetUserInfo(
-    content::BrowserContext* context) const {
-  return user_info_.get();
-}
-
-bool SessionStateDelegateStub::ShouldShowAvatar(aura::Window* window) const {
-  return !user_info_->GetImage().isNull();
-}
-
-void SessionStateDelegateStub::SwitchActiveUser(const std::string& user_id) {
-}
-
-void SessionStateDelegateStub::CycleActiveUser(CycleUser cycle_user) {
-}
-
-void SessionStateDelegateStub::AddSessionStateObserver(
-    ash::SessionStateObserver* observer) {
-}
-
-void SessionStateDelegateStub::RemoveSessionStateObserver(
-    ash::SessionStateObserver* observer) {
-}
-
-}  // namespace ash
diff --git a/ash/session/session_state_delegate_stub.h b/ash/session/session_state_delegate_stub.h
deleted file mode 100644
index 5ce9cf3..0000000
--- a/ash/session/session_state_delegate_stub.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2013 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.
-
-#ifndef ASH_SESSION_SESSION_STATE_DELEGATE_STUB_H_
-#define ASH_SESSION_SESSION_STATE_DELEGATE_STUB_H_
-
-#include "ash/session/session_state_delegate.h"
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace ash {
-
-// Stub implementation of SessionStateDelegate for testing.
-class SessionStateDelegateStub : public SessionStateDelegate {
- public:
-  SessionStateDelegateStub();
-  virtual ~SessionStateDelegateStub();
-
-  // SessionStateDelegate:
-  virtual content::BrowserContext* GetBrowserContextByIndex(
-      MultiProfileIndex index) OVERRIDE;
-  virtual content::BrowserContext* GetBrowserContextForWindow(
-      aura::Window* window) OVERRIDE;
-  virtual int GetMaximumNumberOfLoggedInUsers() const OVERRIDE;
-  virtual int NumberOfLoggedInUsers() const OVERRIDE;
-  virtual bool IsActiveUserSessionStarted() const OVERRIDE;
-  virtual bool CanLockScreen() const OVERRIDE;
-  virtual bool IsScreenLocked() const OVERRIDE;
-  virtual bool ShouldLockScreenBeforeSuspending() const OVERRIDE;
-  virtual void LockScreen() OVERRIDE;
-  virtual void UnlockScreen() OVERRIDE;
-  virtual bool IsUserSessionBlocked() const OVERRIDE;
-  virtual SessionState GetSessionState() const OVERRIDE;
-  virtual const UserInfo* GetUserInfo(MultiProfileIndex index) const OVERRIDE;
-  virtual const UserInfo* GetUserInfo(
-      content::BrowserContext* context) const OVERRIDE;
-  virtual bool ShouldShowAvatar(aura::Window* window) const OVERRIDE;
-  virtual void SwitchActiveUser(const std::string& user_id) OVERRIDE;
-  virtual void CycleActiveUser(CycleUser cycle_user) OVERRIDE;
-  virtual void AddSessionStateObserver(
-      ash::SessionStateObserver* observer) OVERRIDE;
-  virtual void RemoveSessionStateObserver(
-      ash::SessionStateObserver* observer) OVERRIDE;
-
- private:
-  bool screen_locked_;
-
-  // A pseudo user info.
-  scoped_ptr<UserInfo> user_info_;
-
-  DISALLOW_COPY_AND_ASSIGN(SessionStateDelegateStub);
-};
-
-}  // namespace ash
-
-#endif  // ASH_SESSION_SESSION_STATE_DELEGATE_STUB_H_
diff --git a/ash/shelf/overflow_bubble_view.cc b/ash/shelf/overflow_bubble_view.cc
index 1aa025b..b165b2d 100644
--- a/ash/shelf/overflow_bubble_view.cc
+++ b/ash/shelf/overflow_bubble_view.cc
@@ -48,7 +48,6 @@
   set_background(NULL);
   set_color(SkColorSetARGB(kShelfBackgroundAlpha, 0, 0, 0));
   set_margins(gfx::Insets(kPadding, kPadding, kPadding, kPadding));
-  set_move_with_anchor(true);
   // Overflow bubble should not get focus. If it get focus when it is shown,
   // active state item is changed to running state.
   set_use_focusless(true);
diff --git a/ash/shelf/shelf_tooltip_manager.cc b/ash/shelf/shelf_tooltip_manager.cc
index ecfcaa3..cc80bdb 100644
--- a/ash/shelf/shelf_tooltip_manager.cc
+++ b/ash/shelf/shelf_tooltip_manager.cc
@@ -73,8 +73,6 @@
     views::BubbleBorder::Arrow arrow,
     ShelfTooltipManager* host)
     : views::BubbleDelegateView(anchor, arrow), host_(host) {
-  // Make sure that the bubble follows the animation of the shelf.
-  set_move_with_anchor(true);
   gfx::Insets insets = gfx::Insets(kArrowOffsetTopBottom,
                                    kArrowOffsetLeftRight,
                                    kArrowOffsetTopBottom,
diff --git a/ash/shell.cc b/ash/shell.cc
index 9f19b14..8bd4460 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -828,7 +828,7 @@
   // Env creates the compositor. Historically it seems to have been implicitly
   // initialized first by the ActivationController, but now that FocusController
   // no longer does this we need to do it explicitly.
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
 
   // The WindowModalityController needs to be at the front of the input event
   // pretarget handler list to ensure that it processes input events when modal
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc
index c487ba1..87d46e8 100644
--- a/ash/shell/app_list.cc
+++ b/ash/shell/app_list.cc
@@ -248,6 +248,10 @@
     return users_;
   }
 
+  virtual bool ShouldCenterWindow() const OVERRIDE {
+    return false;
+  }
+
   virtual app_list::AppListModel* GetModel() OVERRIDE { return model_.get(); }
 
   virtual app_list::SigninDelegate* GetSigninDelegate() OVERRIDE {
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc
index 2bf14e8..289d769 100644
--- a/ash/shell/shell_delegate_impl.cc
+++ b/ash/shell/shell_delegate_impl.cc
@@ -11,7 +11,7 @@
 #include "ash/media_delegate.h"
 #include "ash/new_window_delegate.h"
 #include "ash/session/session_state_delegate.h"
-#include "ash/session/session_state_delegate_stub.h"
+#include "ash/session/user_info.h"
 #include "ash/shell/context_menu.h"
 #include "ash/shell/example_factory.h"
 #include "ash/shell/keyboard_controller_proxy_stub.h"
@@ -21,6 +21,7 @@
 #include "ash/system/tray/default_system_tray_delegate.h"
 #include "ash/wm/window_state.h"
 #include "base/message_loop/message_loop.h"
+#include "base/strings/utf_string_conversions.h"
 #include "ui/aura/window.h"
 #include "ui/wm/core/input_method_event_filter.h"
 
@@ -33,6 +34,7 @@
   NewWindowDelegateImpl() {}
   virtual ~NewWindowDelegateImpl() {}
 
+  // NewWindowDelegate:
   virtual void NewTab() OVERRIDE {}
   virtual void NewWindow(bool incognito) OVERRIDE {
     ash::shell::ToplevelWindow::CreateParams create_params;
@@ -56,14 +58,115 @@
   MediaDelegateImpl() {}
   virtual ~MediaDelegateImpl() {}
 
+  // MediaDelegate:
   virtual void HandleMediaNextTrack() OVERRIDE {}
   virtual void HandleMediaPlayPause() OVERRIDE {}
   virtual void HandleMediaPrevTrack() OVERRIDE {}
+  virtual MediaCaptureState GetMediaCaptureState(
+      content::BrowserContext* context) OVERRIDE {
+    return MEDIA_CAPTURE_VIDEO;
+  }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MediaDelegateImpl);
 };
 
+class UserInfoImpl : public UserInfo {
+ public:
+  UserInfoImpl() {}
+  virtual ~UserInfoImpl() {}
+
+  // UserInfo:
+  virtual base::string16 GetDisplayName() const OVERRIDE {
+    return base::UTF8ToUTF16("stub-user");
+  }
+  virtual base::string16 GetGivenName() const OVERRIDE {
+    return base::UTF8ToUTF16("Stub");
+  }
+  virtual std::string GetEmail() const OVERRIDE {
+    return "stub-user@domain.com";
+  }
+  virtual std::string GetUserID() const OVERRIDE { return GetEmail(); }
+  virtual const gfx::ImageSkia& GetImage() const OVERRIDE {
+    return user_image_;
+  }
+
+ private:
+  gfx::ImageSkia user_image_;
+
+  DISALLOW_COPY_AND_ASSIGN(UserInfoImpl);
+};
+
+class SessionStateDelegateImpl : public SessionStateDelegate {
+ public:
+  SessionStateDelegateImpl()
+      : screen_locked_(false), user_info_(new UserInfoImpl()) {}
+
+  virtual ~SessionStateDelegateImpl() {}
+
+  // SessionStateDelegate:
+  virtual content::BrowserContext* GetBrowserContextByIndex(
+      MultiProfileIndex index) OVERRIDE {
+    return Shell::GetInstance()->delegate()->GetActiveBrowserContext();
+  }
+  virtual content::BrowserContext* GetBrowserContextForWindow(
+      aura::Window* window) OVERRIDE {
+    return Shell::GetInstance()->delegate()->GetActiveBrowserContext();
+  }
+  virtual int GetMaximumNumberOfLoggedInUsers() const OVERRIDE { return 3; }
+  virtual int NumberOfLoggedInUsers() const OVERRIDE {
+    // ash_shell has 2 users.
+    return 2;
+  }
+  virtual bool IsActiveUserSessionStarted() const OVERRIDE { return true; }
+  virtual bool CanLockScreen() const OVERRIDE { return true; }
+  virtual bool IsScreenLocked() const OVERRIDE { return screen_locked_; }
+  virtual bool ShouldLockScreenBeforeSuspending() const OVERRIDE {
+    return false;
+  }
+  virtual void LockScreen() OVERRIDE {
+    shell::CreateLockScreen();
+    screen_locked_ = true;
+    Shell::GetInstance()->UpdateShelfVisibility();
+  }
+  virtual void UnlockScreen() OVERRIDE {
+    screen_locked_ = false;
+    Shell::GetInstance()->UpdateShelfVisibility();
+  }
+  virtual bool IsUserSessionBlocked() const OVERRIDE {
+    return !IsActiveUserSessionStarted() || IsScreenLocked();
+  }
+  virtual SessionState GetSessionState() const OVERRIDE {
+    // Assume that if session is not active we're at login.
+    return IsActiveUserSessionStarted() ? SESSION_STATE_ACTIVE
+                                        : SESSION_STATE_LOGIN_PRIMARY;
+  }
+  virtual const UserInfo* GetUserInfo(MultiProfileIndex index) const OVERRIDE {
+    return user_info_.get();
+  }
+  virtual const UserInfo* GetUserInfo(
+      content::BrowserContext* context) const OVERRIDE {
+    return user_info_.get();
+  }
+  virtual bool ShouldShowAvatar(aura::Window* window) const OVERRIDE {
+    return !user_info_->GetImage().isNull();
+  }
+  virtual void SwitchActiveUser(const std::string& user_id) OVERRIDE {}
+  virtual void CycleActiveUser(CycleUser cycle_user) OVERRIDE {}
+  virtual void AddSessionStateObserver(
+      ash::SessionStateObserver* observer) OVERRIDE {}
+  virtual void RemoveSessionStateObserver(
+      ash::SessionStateObserver* observer) OVERRIDE {}
+
+ private:
+  bool screen_locked_;
+
+  // A pseudo user info.
+  scoped_ptr<UserInfo> user_info_;
+
+  DISALLOW_COPY_AND_ASSIGN(SessionStateDelegateImpl);
+};
+
 }  // namespace
 
 ShellDelegateImpl::ShellDelegateImpl()
@@ -149,7 +252,7 @@
 }
 
 ash::SessionStateDelegate* ShellDelegateImpl::CreateSessionStateDelegate() {
-  return new SessionStateDelegateStub;
+  return new SessionStateDelegateImpl;
 }
 
 ash::AccessibilityDelegate* ShellDelegateImpl::CreateAccessibilityDelegate() {
diff --git a/ash/system/ime/tray_ime.cc b/ash/system/ime/tray_ime.cc
index dd73065..3bd0296 100644
--- a/ash/system/ime/tray_ime.cc
+++ b/ash/system/ime/tray_ime.cc
@@ -23,6 +23,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
+#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_view_state.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/font.h"
@@ -34,6 +36,36 @@
 namespace ash {
 namespace tray {
 
+// A |HoverHighlightView| that uses bold or normal font depending on whetehr
+// it is selected.  This view exposes itself as a checkbox to the accessibility
+// framework.
+class SelectableHoverHighlightView : public HoverHighlightView {
+ public:
+  SelectableHoverHighlightView(ViewClickListener* listener,
+                               const base::string16& label,
+                               bool selected)
+      : HoverHighlightView(listener), selected_(selected) {
+    AddLabel(
+        label, gfx::ALIGN_LEFT, selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
+  }
+
+  virtual ~SelectableHoverHighlightView() {}
+
+ protected:
+  // Overridden from views::View.
+  virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE {
+    HoverHighlightView::GetAccessibleState(state);
+    state->role = ui::AX_ROLE_CHECK_BOX;
+    if (selected_)
+      state->AddStateFlag(ui::AX_STATE_CHECKED);
+  }
+
+ private:
+  bool selected_;
+
+  DISALLOW_COPY_AND_ASSIGN(SelectableHoverHighlightView);
+};
+
 class IMEDefaultView : public TrayItemMore {
  public:
   explicit IMEDefaultView(SystemTrayItem* owner)
@@ -99,11 +131,8 @@
     ime_map_.clear();
     CreateScrollableList();
     for (size_t i = 0; i < list.size(); i++) {
-      HoverHighlightView* container = new HoverHighlightView(this);
-      container->AddLabel(
-          list[i].name,
-          gfx::ALIGN_LEFT,
-          list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
+      HoverHighlightView* container = new SelectableHoverHighlightView(
+          this, list[i].name, list[i].selected);
       scroll_content()->AddChildView(container);
       ime_map_[container] = list[i].id;
     }
@@ -112,11 +141,8 @@
   void AppendIMEProperties(const IMEPropertyInfoList& property_list) {
     property_map_.clear();
     for (size_t i = 0; i < property_list.size(); i++) {
-      HoverHighlightView* container = new HoverHighlightView(this);
-      container->AddLabel(
-          property_list[i].name,
-          gfx::ALIGN_LEFT,
-          property_list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
+      HoverHighlightView* container = new SelectableHoverHighlightView(
+          this, property_list[i].name, property_list[i].selected);
       if (i == 0)
         container->SetBorder(views::Border::CreateSolidSidedBorder(
             1, 0, 0, 0, kBorderLightColor));
diff --git a/ash/system/tray/hover_highlight_view.h b/ash/system/tray/hover_highlight_view.h
index ee1bdd8..0797de6 100644
--- a/ash/system/tray/hover_highlight_view.h
+++ b/ash/system/tray/hover_highlight_view.h
@@ -59,12 +59,15 @@
 
   bool hover() const { return hover_; }
 
+ protected:
+  // Overridden from views::View.
+  virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
+
  private:
   // Overridden from ActionableView:
   virtual bool PerformAction(const ui::Event& event) OVERRIDE;
 
   // Overridden from views::View.
-  virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
   virtual gfx::Size GetPreferredSize() OVERRIDE;
   virtual int GetHeightForWidth(int width) OVERRIDE;
   virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
diff --git a/ash/system/tray/media_security/media_capture_observer.h b/ash/system/tray/media_security/media_capture_observer.h
new file mode 100644
index 0000000..9a217b2
--- /dev/null
+++ b/ash/system/tray/media_security/media_capture_observer.h
@@ -0,0 +1,23 @@
+// 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.
+
+#ifndef ASH_SYSTEM_CHROMEOS_MEDIA_SECURITY_MEDIA_CAPTURE_OBSERVER_H_
+#define ASH_SYSTEM_CHROMEOS_MEDIA_SECURITY_MEDIA_CAPTURE_OBSERVER_H_
+
+#include "ash/ash_export.h"
+
+namespace ash {
+
+class ASH_EXPORT MediaCaptureObserver {
+ public:
+  // Called when media capture state has changed.
+  virtual void OnMediaCaptureChanged() = 0;
+
+ protected:
+  virtual ~MediaCaptureObserver() {}
+};
+
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_CHROMEOS_MEDIA_SECURITY_MEDIA_CAPTURE_OBSERVER_H_
diff --git a/ash/system/tray/media_security/multi_profile_media_tray_item.cc b/ash/system/tray/media_security/multi_profile_media_tray_item.cc
new file mode 100644
index 0000000..7826fb7
--- /dev/null
+++ b/ash/system/tray/media_security/multi_profile_media_tray_item.cc
@@ -0,0 +1,85 @@
+// 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.
+
+#include "ash/system/tray/media_security/multi_profile_media_tray_item.h"
+
+#include "ash/ash_view_ids.h"
+#include "ash/media_delegate.h"
+#include "ash/session/session_state_delegate.h"
+#include "ash/shell.h"
+#include "ash/system/tray/media_security/media_capture_observer.h"
+#include "ash/system/tray/system_tray_notifier.h"
+#include "ash/system/tray/tray_item_view.h"
+#include "grit/ash_resources.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/layout/fill_layout.h"
+
+namespace ash {
+namespace tray {
+
+class MultiProfileMediaTrayView : public TrayItemView,
+                                  public MediaCaptureObserver {
+ public:
+  explicit MultiProfileMediaTrayView(SystemTrayItem* system_tray_item)
+      : TrayItemView(system_tray_item) {
+    SetLayoutManager(new views::FillLayout);
+    views::ImageView* icon = new views::ImageView;
+    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
+    icon->SetImage(
+        bundle.GetImageNamed(IDR_AURA_UBER_TRAY_RECORDING).ToImageSkia());
+    AddChildView(icon);
+    OnMediaCaptureChanged();
+    Shell::GetInstance()->system_tray_notifier()->AddMediaCaptureObserver(this);
+    set_id(VIEW_ID_MEDIA_TRAY_VIEW);
+  }
+
+  virtual ~MultiProfileMediaTrayView() {
+    Shell::GetInstance()->system_tray_notifier()->RemoveMediaCaptureObserver(
+        this);
+  }
+
+  // MediaCaptureObserver:
+  virtual void OnMediaCaptureChanged() OVERRIDE {
+    MediaDelegate* media_delegate = Shell::GetInstance()->media_delegate();
+    SessionStateDelegate* session_state_delegate =
+        Shell::GetInstance()->session_state_delegate();
+    // The user at 0 is the current desktop user.
+    for (MultiProfileIndex index = 1;
+         index < session_state_delegate->NumberOfLoggedInUsers();
+         ++index) {
+      content::BrowserContext* context =
+          session_state_delegate->GetBrowserContextByIndex(index);
+      if (media_delegate->GetMediaCaptureState(context) != MEDIA_CAPTURE_NONE) {
+        SetVisible(true);
+        return;
+      }
+    }
+    SetVisible(false);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MultiProfileMediaTrayView);
+};
+
+}  // namespace tray
+
+MultiProfileMediaTrayItem::MultiProfileMediaTrayItem(SystemTray* system_tray)
+    : SystemTrayItem(system_tray), tray_view_(NULL) {
+}
+
+MultiProfileMediaTrayItem::~MultiProfileMediaTrayItem() {
+}
+
+views::View* MultiProfileMediaTrayItem::CreateTrayView(
+    user::LoginStatus status) {
+  tray_view_ = new tray::MultiProfileMediaTrayView(this);
+  return tray_view_;
+}
+
+void MultiProfileMediaTrayItem::DestroyTrayView() {
+  tray_view_ = NULL;
+}
+
+}  // namespace ash
diff --git a/ash/system/tray/media_security/multi_profile_media_tray_item.h b/ash/system/tray/media_security/multi_profile_media_tray_item.h
new file mode 100644
index 0000000..038bf8d
--- /dev/null
+++ b/ash/system/tray/media_security/multi_profile_media_tray_item.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef ASH_SYSTEM_CHROMEOS_MULTI_PROFILE_MEDIA_TRAY_ITEM_H_
+#define ASH_SYSTEM_CHROMEOS_MULTI_PROFILE_MEDIA_TRAY_ITEM_H_
+
+#include "ash/system/tray/system_tray_item.h"
+#include "ui/message_center/notification_delegate.h"
+#include "ui/views/view.h"
+
+namespace ash {
+namespace tray {
+class MultiProfileMediaTrayView;
+}
+
+// The tray item for media recording.
+class ASH_EXPORT MultiProfileMediaTrayItem : public SystemTrayItem {
+ public:
+  explicit MultiProfileMediaTrayItem(SystemTray* system_tray);
+  virtual ~MultiProfileMediaTrayItem();
+
+  // SystemTrayItem:
+  virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE;
+  virtual void DestroyTrayView() OVERRIDE;
+
+ private:
+  tray::MultiProfileMediaTrayView* tray_view_;
+
+  DISALLOW_COPY_AND_ASSIGN(MultiProfileMediaTrayItem);
+};
+
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_CHROMEOS_MULTI_PROFILE_MEDIA_TRAY_ITEM_H_
diff --git a/ash/system/tray/media_security/multi_profile_media_tray_item_unittest.cc b/ash/system/tray/media_security/multi_profile_media_tray_item_unittest.cc
new file mode 100644
index 0000000..1dcfeaa
--- /dev/null
+++ b/ash/system/tray/media_security/multi_profile_media_tray_item_unittest.cc
@@ -0,0 +1,58 @@
+// 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.
+
+#include "ash/system/tray/media_security/multi_profile_media_tray_item.h"
+
+#include "ash/ash_view_ids.h"
+#include "ash/shell.h"
+#include "ash/system/status_area_widget.h"
+#include "ash/system/tray/system_tray.h"
+#include "ash/system/tray/system_tray_bubble.h"
+#include "ash/system/tray/tray_item_view.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/test/test_session_state_delegate.h"
+#include "ash/test/test_shell_delegate.h"
+#include "ui/views/bubble/tray_bubble_view.h"
+
+namespace ash {
+
+typedef test::AshTestBase MultiProfileMediaTrayItemTest;
+
+TEST_F(MultiProfileMediaTrayItemTest, NotifyMediaCaptureChange) {
+  TrayItemView::DisableAnimationsForTest();
+  test::TestShellDelegate* shell_delegate =
+      static_cast<test::TestShellDelegate*>(Shell::GetInstance()->delegate());
+  test::TestSessionStateDelegate* session_state_delegate =
+      static_cast<test::TestSessionStateDelegate*>(
+          Shell::GetInstance()->session_state_delegate());
+  session_state_delegate->set_logged_in_users(2);
+
+  SystemTray* system_tray = Shell::GetInstance()->GetPrimarySystemTray();
+  system_tray->ShowDefaultView(BUBBLE_CREATE_NEW);
+  views::View* in_user_view =
+      system_tray->GetSystemBubble()->bubble_view()->GetViewByID(
+          VIEW_ID_USER_VIEW_MEDIA_INDICATOR);
+
+  StatusAreaWidget* widget = system_tray->status_area_widget();
+  EXPECT_TRUE(widget->GetRootView()->visible());
+  views::View* tray_view =
+      widget->GetRootView()->GetViewByID(VIEW_ID_MEDIA_TRAY_VIEW);
+
+  EXPECT_FALSE(tray_view->visible());
+  EXPECT_FALSE(in_user_view->visible());
+
+  shell_delegate->SetMediaCaptureState(MEDIA_CAPTURE_AUDIO);
+  EXPECT_TRUE(tray_view->visible());
+  EXPECT_TRUE(in_user_view->visible());
+
+  shell_delegate->SetMediaCaptureState(MEDIA_CAPTURE_AUDIO_VIDEO);
+  EXPECT_TRUE(tray_view->visible());
+  EXPECT_TRUE(in_user_view->visible());
+
+  shell_delegate->SetMediaCaptureState(MEDIA_CAPTURE_NONE);
+  EXPECT_FALSE(tray_view->visible());
+  EXPECT_FALSE(in_user_view->visible());
+}
+
+}  // namespace ash
diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc
index 726bbf3..d8ac9a5 100644
--- a/ash/system/tray/system_tray.cc
+++ b/ash/system/tray/system_tray.cc
@@ -61,6 +61,7 @@
 #include "ash/system/chromeos/tray_caps_lock.h"
 #include "ash/system/chromeos/tray_display.h"
 #include "ash/system/chromeos/tray_tracing.h"
+#include "ash/system/tray/media_security/multi_profile_media_tray_item.h"
 #include "ui/message_center/message_center.h"
 #elif defined(OS_WIN)
 #include "ash/system/win/audio/tray_audio_win.h"
@@ -188,6 +189,7 @@
   AddTrayItem(new TrayDisplay(this));
   AddTrayItem(new ScreenCaptureTrayItem(this));
   AddTrayItem(new ScreenShareTrayItem(this));
+  AddTrayItem(new MultiProfileMediaTrayItem(this));
   AddTrayItem(new TrayAudioChromeOs(this));
   AddTrayItem(new TrayBrightness(this));
   AddTrayItem(new TrayCapsLock(this));
diff --git a/ash/system/tray/system_tray_notifier.cc b/ash/system/tray/system_tray_notifier.cc
index ed858c3..5801ce6 100644
--- a/ash/system/tray/system_tray_notifier.cc
+++ b/ash/system/tray/system_tray_notifier.cc
@@ -151,6 +151,16 @@
   enterprise_domain_observers_.RemoveObserver(observer);
 }
 
+void SystemTrayNotifier::AddMediaCaptureObserver(
+    MediaCaptureObserver* observer) {
+  media_capture_observers_.AddObserver(observer);
+}
+
+void SystemTrayNotifier::RemoveMediaCaptureObserver(
+    MediaCaptureObserver* observer) {
+  media_capture_observers_.RemoveObserver(observer);
+}
+
 void SystemTrayNotifier::AddScreenCaptureObserver(
     ScreenCaptureObserver* observer) {
   screen_capture_observers_.AddObserver(observer);
@@ -354,6 +364,11 @@
       OnEnterpriseDomainChanged());
 }
 
+void SystemTrayNotifier::NotifyMediaCaptureChanged() {
+  FOR_EACH_OBSERVER(
+      MediaCaptureObserver, media_capture_observers_, OnMediaCaptureChanged());
+}
+
 void SystemTrayNotifier::NotifyScreenCaptureStart(
     const base::Closure& stop_callback,
     const base::string16& sharing_app_name) {
diff --git a/ash/system/tray/system_tray_notifier.h b/ash/system/tray/system_tray_notifier.h
index 29cd9d2..6e6b03f 100644
--- a/ash/system/tray/system_tray_notifier.h
+++ b/ash/system/tray/system_tray_notifier.h
@@ -30,6 +30,7 @@
 #include "ash/system/chromeos/session/last_window_closed_observer.h"
 #include "ash/system/chromeos/session/logout_button_observer.h"
 #include "ash/system/chromeos/session/session_length_limit_observer.h"
+#include "ash/system/tray/media_security/media_capture_observer.h"
 #include "base/time/time.h"
 #endif
 
@@ -92,6 +93,9 @@
   void AddEnterpriseDomainObserver(EnterpriseDomainObserver* observer);
   void RemoveEnterpriseDomainObserver(EnterpriseDomainObserver* observer);
 
+  void AddMediaCaptureObserver(MediaCaptureObserver* observer);
+  void RemoveMediaCaptureObserver(MediaCaptureObserver* observer);
+
   void AddScreenCaptureObserver(ScreenCaptureObserver* observer);
   void RemoveScreenCaptureObserver(ScreenCaptureObserver* observer);
 
@@ -133,6 +137,7 @@
   void NotifyRequestToggleWifi();
   void NotifyOnCaptivePortalDetected(const std::string& service_path);
   void NotifyEnterpriseDomainChanged();
+  void NotifyMediaCaptureChanged();
   void NotifyScreenCaptureStart(const base::Closure& stop_callback,
                                 const base::string16& sharing_app_name);
   void NotifyScreenCaptureStop();
@@ -164,6 +169,7 @@
   ObserverList<NetworkPortalDetectorObserver>
       network_portal_detector_observers_;
   ObserverList<EnterpriseDomainObserver> enterprise_domain_observers_;
+  ObserverList<MediaCaptureObserver> media_capture_observers_;
   ObserverList<ScreenCaptureObserver> screen_capture_observers_;
   ObserverList<ScreenShareObserver> screen_share_observers_;
   ObserverList<LastWindowClosedObserver> last_window_closed_observers_;
diff --git a/ash/system/tray/system_tray_unittest.cc b/ash/system/tray/system_tray_unittest.cc
index 1a2d355..fbf2859 100644
--- a/ash/system/tray/system_tray_unittest.cc
+++ b/ash/system/tray/system_tray_unittest.cc
@@ -312,7 +312,7 @@
   RunAllPendingInMessageLoop();
   ASSERT_TRUE(test_item->notification_view() != NULL);
 
-  // Show the detailed view, ensure the notificaiton view remains.
+  // Show the detailed view, ensure the notification view remains.
   tray->ShowDetailedView(detailed_item, 0, false, BUBBLE_CREATE_NEW);
   RunAllPendingInMessageLoop();
   ASSERT_TRUE(detailed_item->detailed_view() != NULL);
diff --git a/ash/system/user/user_card_view.cc b/ash/system/user/user_card_view.cc
index af568ae..c1bdd15 100644
--- a/ash/system/user/user_card_view.cc
+++ b/ash/system/user/user_card_view.cc
@@ -11,6 +11,7 @@
 #include "ash/session/user_info.h"
 #include "ash/shell.h"
 #include "ash/system/tray/system_tray_delegate.h"
+#include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/user/config.h"
 #include "ash/system/user/rounded_image_view.h"
@@ -35,6 +36,14 @@
 #include "ui/views/controls/link_listener.h"
 #include "ui/views/layout/box_layout.h"
 
+#if defined(OS_CHROMEOS)
+#include "ash/ash_view_ids.h"
+#include "ash/media_delegate.h"
+#include "ash/system/tray/media_security/media_capture_observer.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/layout/fill_layout.h"
+#endif
+
 namespace ash {
 namespace tray {
 
@@ -46,6 +55,70 @@
 // and end of the user's display name in the public account user card's text.
 const base::char16 kDisplayNameMark[] = {0x2060, 0};
 
+#if defined(OS_CHROMEOS)
+class MediaIndicator : public views::View, public MediaCaptureObserver {
+ public:
+  explicit MediaIndicator(MultiProfileIndex index)
+      : index_(index), label_(new views::Label) {
+    SetLayoutManager(new views::FillLayout);
+    views::ImageView* icon = new views::ImageView;
+    icon->SetImage(ui::ResourceBundle::GetSharedInstance()
+                       .GetImageNamed(IDR_AURA_UBER_TRAY_RECORDING_RED)
+                       .ToImageSkia());
+    AddChildView(icon);
+    label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+    label_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+        ui::ResourceBundle::SmallFont));
+    OnMediaCaptureChanged();
+    Shell::GetInstance()->system_tray_notifier()->AddMediaCaptureObserver(this);
+    set_id(VIEW_ID_USER_VIEW_MEDIA_INDICATOR);
+  }
+
+  virtual ~MediaIndicator() {
+    Shell::GetInstance()->system_tray_notifier()->RemoveMediaCaptureObserver(
+        this);
+  }
+
+  // MediaCaptureObserver:
+  virtual void OnMediaCaptureChanged() OVERRIDE {
+    Shell* shell = Shell::GetInstance();
+    content::BrowserContext* context =
+        shell->session_state_delegate()->GetBrowserContextByIndex(index_);
+    MediaCaptureState state =
+        Shell::GetInstance()->media_delegate()->GetMediaCaptureState(context);
+    int res_id = 0;
+    switch (state) {
+      case MEDIA_CAPTURE_AUDIO_VIDEO:
+        res_id = IDS_ASH_STATUS_TRAY_MEDIA_RECORDING_AUDIO_VIDEO;
+        break;
+      case MEDIA_CAPTURE_AUDIO:
+        res_id = IDS_ASH_STATUS_TRAY_MEDIA_RECORDING_AUDIO;
+        break;
+      case MEDIA_CAPTURE_VIDEO:
+        res_id = IDS_ASH_STATUS_TRAY_MEDIA_RECORDING_VIDEO;
+        break;
+      case MEDIA_CAPTURE_NONE:
+        break;
+    }
+    SetMessage(res_id ? l10n_util::GetStringUTF16(res_id) : base::string16());
+  }
+
+  views::View* GetMessageView() { return label_; }
+
+  void SetMessage(const base::string16& message) {
+    SetVisible(!message.empty());
+    label_->SetText(message);
+    label_->SetVisible(!message.empty());
+  }
+
+ private:
+  MultiProfileIndex index_;
+  views::Label* label_;
+
+  DISALLOW_COPY_AND_ASSIGN(MediaIndicator);
+};
+#endif
+
 // The user details shown in public account mode. This is essentially a label
 // but with custom painting code as the text is styled with multiple colors and
 // contains a link.
@@ -301,7 +374,7 @@
                                   int multiprofile_index) {
   views::View* icon = CreateIcon(login_status, multiprofile_index);
   AddChildView(icon);
-  views::Label* username = NULL;
+  views::Label* user_name = NULL;
   SessionStateDelegate* delegate =
       Shell::GetInstance()->session_state_delegate();
   if (!multiprofile_index) {
@@ -313,12 +386,12 @@
       user_name_string = base::ASCIIToUTF16(
           delegate->GetUserInfo(multiprofile_index)->GetEmail());
     if (!user_name_string.empty()) {
-      username = new views::Label(user_name_string);
-      username->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+      user_name = new views::Label(user_name_string);
+      user_name->SetHorizontalAlignment(gfx::ALIGN_LEFT);
     }
   }
 
-  views::Label* additional = NULL;
+  views::Label* user_email = NULL;
   if (login_status != user::LOGGED_IN_GUEST &&
       (multiprofile_index || !IsMultiAccountSupportedAndUserActive())) {
     base::string16 user_email_string =
@@ -328,37 +401,55 @@
             : base::UTF8ToUTF16(
                   delegate->GetUserInfo(multiprofile_index)->GetEmail());
     if (!user_email_string.empty()) {
-      additional = new views::Label(user_email_string);
-      additional->SetFontList(
+      user_email = new views::Label(user_email_string);
+      user_email->SetFontList(
           ui::ResourceBundle::GetSharedInstance().GetFontList(
               ui::ResourceBundle::SmallFont));
-      additional->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+      user_email->SetHorizontalAlignment(gfx::ALIGN_LEFT);
     }
   }
 
   // Adjust text properties dependent on if it is an active or inactive user.
   if (multiprofile_index) {
     // Fade the text of non active users to 50%.
-    SkColor text_color = additional->enabled_color();
+    SkColor text_color = user_email->enabled_color();
     text_color = SkColorSetA(text_color, SkColorGetA(text_color) / 2);
-    if (additional)
-      additional->SetDisabledColor(text_color);
-    if (username)
-      username->SetDisabledColor(text_color);
+    if (user_email)
+      user_email->SetDisabledColor(text_color);
+    if (user_name)
+      user_name->SetDisabledColor(text_color);
   }
 
-  if (additional && username) {
+  if (user_email && user_name) {
     views::View* details = new views::View;
     details->SetLayoutManager(new views::BoxLayout(
         views::BoxLayout::kVertical, 0, kUserDetailsVerticalPadding, 0));
-    details->AddChildView(username);
-    details->AddChildView(additional);
+    details->AddChildView(user_name);
+    details->AddChildView(user_email);
     AddChildView(details);
   } else {
-    if (username)
-      AddChildView(username);
-    if (additional)
-      AddChildView(additional);
+    if (user_name)
+      AddChildView(user_name);
+    if (user_email) {
+#if defined(OS_CHROMEOS)
+      // Only non active user can have a media indicator.
+      MediaIndicator* media_indicator = new MediaIndicator(multiprofile_index);
+      views::View* email_indicator_view = new views::View;
+      email_indicator_view->SetLayoutManager(new views::BoxLayout(
+          views::BoxLayout::kHorizontal, 0, 0, kTrayPopupPaddingBetweenItems));
+      email_indicator_view->AddChildView(user_email);
+      email_indicator_view->AddChildView(media_indicator);
+
+      views::View* details = new views::View;
+      details->SetLayoutManager(new views::BoxLayout(
+          views::BoxLayout::kVertical, 0, kUserDetailsVerticalPadding, 0));
+      details->AddChildView(email_indicator_view);
+      details->AddChildView(media_indicator->GetMessageView());
+      AddChildView(details);
+#else
+      AddChildView(user_email);
+#endif
+    }
   }
 }
 
diff --git a/ash/system/user/user_view.cc b/ash/system/user/user_view.cc
index f5eb683..6707686 100644
--- a/ash/system/user/user_view.cc
+++ b/ash/system/user/user_view.cc
@@ -283,8 +283,8 @@
     int remaining_width = contents_area.width() - logout_area.width();
     if (IsMultiProfileSupportedAndUserActive() ||
         IsMultiAccountSupportedAndUserActive()) {
-      // In multiprofile case |user_card_view_| and |logout_button_| have to
-      // have the same height.
+      // In multiprofile/multiaccount case |user_card_view_| and
+      // |logout_button_| have to have the same height.
       int y = std::min(user_card_area.y(), logout_area.y());
       int height = std::max(user_card_area.height(), logout_area.height());
       logout_area.set_y(y);
diff --git a/ash/system/web_notification/web_notification_tray_unittest.cc b/ash/system/web_notification/web_notification_tray_unittest.cc
index d39d3c9..eaf9d06 100644
--- a/ash/system/web_notification/web_notification_tray_unittest.cc
+++ b/ash/system/web_notification/web_notification_tray_unittest.cc
@@ -332,11 +332,11 @@
   // even more, but still visible.
   GetSystemTray()->ShowNotificationView(test_item);
   EXPECT_TRUE(GetTray()->IsPopupVisible());
-  gfx::Rect work_area_with_tray_notificaiton = GetPopupWorkArea();
+  gfx::Rect work_area_with_tray_notification = GetPopupWorkArea();
   EXPECT_GT(work_area.size().GetArea(),
-            work_area_with_tray_notificaiton.size().GetArea());
+            work_area_with_tray_notification.size().GetArea());
   EXPECT_GT(work_area_with_tray.size().GetArea(),
-            work_area_with_tray_notificaiton.size().GetArea());
+            work_area_with_tray_notification.size().GetArea());
 
   // Close system tray, only system tray notifications.
   GetSystemTray()->ClickedOutsideBubble();
@@ -344,7 +344,7 @@
   gfx::Rect work_area_with_notification = GetPopupWorkArea();
   EXPECT_GT(work_area.size().GetArea(),
             work_area_with_notification.size().GetArea());
-  EXPECT_LT(work_area_with_tray_notificaiton.size().GetArea(),
+  EXPECT_LT(work_area_with_tray_notification.size().GetArea(),
             work_area_with_notification.size().GetArea());
 
   // Close the system tray notifications.
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc
index 5787568..9cf3488 100644
--- a/ash/test/ash_test_helper.cc
+++ b/ash/test/ash_test_helper.cc
@@ -138,7 +138,7 @@
 
 void AshTestHelper::RunAllPendingInMessageLoop() {
   DCHECK(base::MessageLoopForUI::current() == message_loop_);
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
   base::RunLoop run_loop;
   run_loop.RunUntilIdle();
 }
diff --git a/ash/test/display_manager_test_api.h b/ash/test/display_manager_test_api.h
index a3c506b..be5dbb9 100644
--- a/ash/test/display_manager_test_api.h
+++ b/ash/test/display_manager_test_api.h
@@ -23,8 +23,8 @@
 
   // Update the display configuration as given in |display_specs|. The format of
   // |display_spec| is a list of comma separated spec for each displays. Please
-  // refer to the comment in |aura::DisplayManager::CreateDisplayFromSpec| for
-  // the format of the display spec.
+  // refer to the comment in |ash::DisplayInfo::CreateFromSpec| for the format
+  // of the display spec.
   void UpdateDisplay(const std::string& display_specs);
 
   // Set the 1st display as an internal display and returns the display Id for
diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc
index 52962ee..2a6597d 100644
--- a/ash/test/test_shell_delegate.cc
+++ b/ash/test/test_shell_delegate.cc
@@ -27,11 +27,21 @@
 #include "ui/app_list/test/app_list_test_view_delegate.h"
 #include "ui/aura/window.h"
 
+#if defined(OS_CHROMEOS)
+#include "ash/system/tray/system_tray_notifier.h"
+#endif
+
 namespace ash {
 namespace test {
 namespace {
 
 class NewWindowDelegateImpl : public NewWindowDelegate {
+ public:
+  NewWindowDelegateImpl() {}
+  virtual ~NewWindowDelegateImpl() {}
+
+ private:
+  // NewWindowDelegate:
   virtual void NewTab() OVERRIDE {}
   virtual void NewWindow(bool incognito) OVERRIDE {}
   virtual void OpenFileManager() OVERRIDE {}
@@ -40,13 +50,30 @@
   virtual void ShowKeyboardOverlay() OVERRIDE {}
   virtual void ShowTaskManager() OVERRIDE {}
   virtual void OpenFeedbackPage() OVERRIDE {}
+
+  DISALLOW_COPY_AND_ASSIGN(NewWindowDelegateImpl);
 };
 
 class MediaDelegateImpl : public MediaDelegate {
  public:
+  MediaDelegateImpl() : state_(MEDIA_CAPTURE_NONE) {}
+  virtual ~MediaDelegateImpl() {}
+
+  void set_media_capture_state(MediaCaptureState state) { state_ = state; }
+
+ private:
+  // MediaDelegate:
   virtual void HandleMediaNextTrack() OVERRIDE {}
   virtual void HandleMediaPlayPause() OVERRIDE {}
   virtual void HandleMediaPrevTrack() OVERRIDE {}
+  virtual MediaCaptureState GetMediaCaptureState(
+      content::BrowserContext* context) OVERRIDE {
+    return state_;
+  }
+
+  MediaCaptureState state_;
+
+  DISALLOW_COPY_AND_ASSIGN(MediaDelegateImpl);
 };
 
 }  // namespace
@@ -161,8 +188,13 @@
   return base::string16();
 }
 
-TestSessionStateDelegate* TestShellDelegate::test_session_state_delegate() {
-  return test_session_state_delegate_;
+void TestShellDelegate::SetMediaCaptureState(MediaCaptureState state) {
+#if defined(OS_CHROMEOS)
+  Shell* shell = Shell::GetInstance();
+  static_cast<MediaDelegateImpl*>(shell->media_delegate())
+      ->set_media_capture_state(state);
+  shell->system_tray_notifier()->NotifyMediaCaptureChanged();
+#endif
 }
 
 }  // namespace test
diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h
index 1d8da2f..d92f80d 100644
--- a/ash/test/test_shell_delegate.h
+++ b/ash/test/test_shell_delegate.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "ash/media_delegate.h"
 #include "ash/shell_delegate.h"
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
@@ -63,7 +64,11 @@
 
   int num_exit_requests() const { return num_exit_requests_; }
 
-  TestSessionStateDelegate* test_session_state_delegate();
+  TestSessionStateDelegate* test_session_state_delegate() {
+    return test_session_state_delegate_;
+  }
+
+  void SetMediaCaptureState(MediaCaptureState state);
 
  private:
   int num_exit_requests_;
diff --git a/ash/test/test_volume_control_delegate.cc b/ash/test/test_volume_control_delegate.cc
new file mode 100644
index 0000000..7c5cad0
--- /dev/null
+++ b/ash/test/test_volume_control_delegate.cc
@@ -0,0 +1,40 @@
+// 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.
+
+#include "ash/test/test_volume_control_delegate.h"
+
+namespace ash {
+
+TestVolumeControlDelegate::TestVolumeControlDelegate(bool consume)
+    : consume_(consume),
+      handle_volume_mute_count_(0),
+      handle_volume_down_count_(0),
+      handle_volume_up_count_(0) {
+}
+
+TestVolumeControlDelegate::~TestVolumeControlDelegate() {
+}
+
+bool TestVolumeControlDelegate::HandleVolumeMute(
+    const ui::Accelerator& accelerator) {
+  ++handle_volume_mute_count_;
+  last_accelerator_ = accelerator;
+  return consume_;
+}
+
+bool TestVolumeControlDelegate::HandleVolumeDown(
+    const ui::Accelerator& accelerator) {
+  ++handle_volume_down_count_;
+  last_accelerator_ = accelerator;
+  return consume_;
+}
+
+bool TestVolumeControlDelegate::HandleVolumeUp(
+    const ui::Accelerator& accelerator) {
+  ++handle_volume_up_count_;
+  last_accelerator_ = accelerator;
+  return consume_;
+}
+
+}  // namespace ash
diff --git a/ash/test/test_volume_control_delegate.h b/ash/test/test_volume_control_delegate.h
new file mode 100644
index 0000000..85b3e5d
--- /dev/null
+++ b/ash/test/test_volume_control_delegate.h
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef ASH_TEST_TEST_VOLUME_CONTROL_DELEGATE_H_
+#define ASH_TEST_TEST_VOLUME_CONTROL_DELEGATE_H_
+
+#include "ash/volume_control_delegate.h"
+#include "ui/base/accelerators/accelerator.h"
+
+namespace ash {
+
+// A simple test double for a VolumeControlDelegate
+// Will count the number of times the HandleVolumeMute, HandleVolumeDown and
+// HandleVolumeUp methods are invoked.
+class TestVolumeControlDelegate : public ash::VolumeControlDelegate {
+ public:
+  explicit TestVolumeControlDelegate(bool consume);
+  virtual ~TestVolumeControlDelegate();
+
+  int handle_volume_mute_count() const {
+    return handle_volume_mute_count_;
+  }
+
+  int handle_volume_down_count() const {
+    return handle_volume_down_count_;
+  }
+
+  int handle_volume_up_count() const {
+    return handle_volume_up_count_;
+  }
+
+  const ui::Accelerator& last_accelerator() const {
+    return last_accelerator_;
+  }
+
+  // ash::VolumeControlDelegate:
+  virtual bool HandleVolumeMute(const ui::Accelerator& accelerator) OVERRIDE;
+  virtual bool HandleVolumeDown(const ui::Accelerator& accelerator) OVERRIDE;
+  virtual bool HandleVolumeUp(const ui::Accelerator& accelerator) OVERRIDE;
+
+ private:
+  // Keeps track of the return value that should be used for the methods
+  // inherited from VolumeControlDelegate
+  bool consume_;
+  int handle_volume_mute_count_;
+  int handle_volume_down_count_;
+  int handle_volume_up_count_;
+  ui::Accelerator last_accelerator_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestVolumeControlDelegate);
+};
+
+}  // namespace ash
+
+#endif  // ASH_TEST_TEST_VOLUME_CONTROL_DELEGATE_H_
diff --git a/ash/wm/app_list_controller.cc b/ash/wm/app_list_controller.cc
index bf631e7..45915c4 100644
--- a/ash/wm/app_list_controller.cc
+++ b/ash/wm/app_list_controller.cc
@@ -24,6 +24,7 @@
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/events/event.h"
 #include "ui/gfx/transform_util.h"
+#include "ui/keyboard/keyboard_controller.h"
 #include "ui/views/widget/widget.h"
 
 namespace ash {
@@ -113,6 +114,24 @@
   }
 }
 
+// Gets the point at the center of the display that a particular view is on.
+// This calculation excludes the virtual keyboard area.
+gfx::Point GetCenterOfDisplayForView(const views::View* view) {
+  gfx::Rect bounds = Shell::GetScreen()->GetDisplayNearestWindow(
+      view->GetWidget()->GetNativeView()).bounds();
+
+  // If the virtual keyboard is active, subtract it from the display bounds, so
+  // that the app list is centered in the non-keyboard area of the display.
+  // (Note that work_area excludes the keyboard, but it doesn't get updated
+  // until after this function is called.)
+  keyboard::KeyboardController* keyboard_controller =
+      keyboard::KeyboardController::GetInstance();
+  if (keyboard_controller && keyboard_controller->keyboard_visible())
+    bounds.Subtract(keyboard_controller->current_keyboard_bounds());
+
+  return bounds.CenterPoint();
+}
+
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -121,6 +140,7 @@
 AppListController::AppListController()
     : pagination_model_(new app_list::PaginationModel),
       is_visible_(false),
+      is_centered_(false),
       view_(NULL),
       should_snap_back_(false) {
   Shell::GetInstance()->AddShellObserver(this);
@@ -165,17 +185,21 @@
     aura::Window* root_window = window->GetRootWindow();
     aura::Window* container = GetRootWindowController(root_window)->
         GetContainer(kShellWindowId_AppListContainer);
-    if (app_list::switches::IsExperimentalAppListPositionEnabled()) {
-      // The experimental app list is centered over the primary display.
-      view->InitAsBubbleCenteredOnPrimaryDisplay(
-          NULL,
+    views::View* applist_button =
+        Shelf::ForWindow(container)->GetAppListButtonView();
+    is_centered_ = view->ShouldCenterWindow();
+    if (is_centered_) {
+      // The experimental app list is centered over the display of the app list
+      // button that was pressed (if triggered via keyboard, this is the display
+      // with the currently focused window).
+      view->InitAsBubbleAtFixedLocation(
+          container,
           pagination_model_.get(),
-          Shell::GetScreen(),
+          GetCenterOfDisplayForView(applist_button),
           views::BubbleBorder::FLOAT,
           true /* border_accepts_events */);
     } else {
-      gfx::Rect applist_button_bounds = Shelf::ForWindow(container)->
-          GetAppListButtonView()->GetBoundsInScreen();
+      gfx::Rect applist_button_bounds = applist_button->GetBoundsInScreen();
       // We need the location of the button within the local screen.
       applist_button_bounds = ScreenUtil::ConvertRectFromScreen(
           root_window,
@@ -225,6 +249,10 @@
   view_ = view;
   views::Widget* widget = view_->GetWidget();
   widget->AddObserver(this);
+  keyboard::KeyboardController* keyboard_controller =
+      keyboard::KeyboardController::GetInstance();
+  if (keyboard_controller)
+    keyboard_controller->AddObserver(this);
   Shell::GetInstance()->AddPreTargetHandler(this);
   Shelf::ForWindow(widget->GetNativeWindow())->AddIconObserver(this);
   widget->GetNativeView()->GetRootWindow()->AddObserver(this);
@@ -240,6 +268,10 @@
   views::Widget* widget = view_->GetWidget();
   widget->RemoveObserver(this);
   GetLayer(widget)->GetAnimator()->RemoveObserver(this);
+  keyboard::KeyboardController* keyboard_controller =
+      keyboard::KeyboardController::GetInstance();
+  if (keyboard_controller)
+    keyboard_controller->RemoveObserver(this);
   Shell::GetInstance()->RemovePreTargetHandler(this);
   Shelf::ForWindow(widget->GetNativeWindow())->RemoveIconObserver(this);
   widget->GetNativeView()->GetRootWindow()->RemoveObserver(this);
@@ -302,8 +334,13 @@
 }
 
 void AppListController::UpdateBounds() {
-  if (view_ && is_visible_)
-    view_->UpdateBounds();
+  if (!view_ || !is_visible_)
+    return;
+
+  view_->UpdateBounds();
+
+  if (is_centered_)
+    view_->SetAnchorPoint(GetCenterOfDisplayForView(view_));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -364,6 +401,13 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// AppListController, keyboard::KeyboardControllerObserver implementation:
+
+void AppListController::OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) {
+  UpdateBounds();
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // AppListController, ShellObserver implementation:
 void AppListController::OnShelfAlignmentChanged(aura::Window* root_window) {
   if (view_)
diff --git a/ash/wm/app_list_controller.h b/ash/wm/app_list_controller.h
index c2eb0ad..437cbb4 100644
--- a/ash/wm/app_list_controller.h
+++ b/ash/wm/app_list_controller.h
@@ -16,6 +16,7 @@
 #include "ui/compositor/layer_animation_observer.h"
 #include "ui/events/event_handler.h"
 #include "ui/gfx/rect.h"
+#include "ui/keyboard/keyboard_controller_observer.h"
 #include "ui/views/widget/widget_observer.h"
 
 namespace app_list {
@@ -42,6 +43,7 @@
                           public aura::WindowObserver,
                           public ui::ImplicitAnimationObserver,
                           public views::WidgetObserver,
+                          public keyboard::KeyboardControllerObserver,
                           public ShellObserver,
                           public ShelfIconObserver,
                           public app_list::PaginationModelObserver {
@@ -108,6 +110,9 @@
   // views::WidgetObserver overrides:
   virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
 
+  // KeyboardControllerObserver overrides:
+  virtual void OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) OVERRIDE;
+
   // ShellObserver overrides:
   virtual void OnShelfAlignmentChanged(aura::Window* root_window) OVERRIDE;
 
@@ -125,6 +130,9 @@
   // Whether we should show or hide app list widget.
   bool is_visible_;
 
+  // Whether the app list should remain centered.
+  bool is_centered_;
+
   // The AppListView this class manages, owned by its widget.
   app_list::AppListView* view_;
 
diff --git a/ash/wm/app_list_controller_unittest.cc b/ash/wm/app_list_controller_unittest.cc
index 9808d8b..7b467df 100644
--- a/ash/wm/app_list_controller_unittest.cc
+++ b/ash/wm/app_list_controller_unittest.cc
@@ -7,17 +7,41 @@
 #include "ash/test/ash_test_base.h"
 #include "ash/test/test_shell_delegate.h"
 #include "ash/wm/window_util.h"
+#include "base/command_line.h"
 #include "base/memory/scoped_ptr.h"
+#include "ui/app_list/app_list_switches.h"
 #include "ui/aura/test/event_generator.h"
 #include "ui/aura/test/test_windows.h"
 #include "ui/aura/window.h"
 
 namespace ash {
 
-typedef test::AshTestBase AppListControllerTest;
+// The parameter is true to test the centered app list, false for normal.
+// (The test name ends in "/0" for normal, "/1" for centered.)
+class AppListControllerTest : public test::AshTestBase,
+                              public ::testing::WithParamInterface<bool> {
+ public:
+  AppListControllerTest();
+  virtual ~AppListControllerTest();
+  virtual void SetUp() OVERRIDE;
+};
+
+AppListControllerTest::AppListControllerTest() {
+}
+
+AppListControllerTest::~AppListControllerTest() {
+}
+
+void AppListControllerTest::SetUp() {
+  AshTestBase::SetUp();
+  if (GetParam()) {
+    CommandLine* command_line = CommandLine::ForCurrentProcess();
+    command_line->AppendSwitch(app_list::switches::kEnableCenteredAppList);
+  }
+}
 
 // Tests that app launcher hides when focus moves to a normal window.
-TEST_F(AppListControllerTest, HideOnFocusOut) {
+TEST_P(AppListControllerTest, HideOnFocusOut) {
   Shell::GetInstance()->ToggleAppList(NULL);
   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
 
@@ -29,7 +53,7 @@
 
 // Tests that app launcher remains visible when focus is moved to a different
 // window in kShellWindowId_AppListContainer.
-TEST_F(AppListControllerTest, RemainVisibleWhenFocusingToApplistContainer) {
+TEST_P(AppListControllerTest, RemainVisibleWhenFocusingToApplistContainer) {
   Shell::GetInstance()->ToggleAppList(NULL);
   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
 
@@ -43,7 +67,7 @@
 }
 
 // Tests that clicking outside the app-list bubble closes it.
-TEST_F(AppListControllerTest, ClickOutsideBubbleClosesBubble) {
+TEST_P(AppListControllerTest, ClickOutsideBubbleClosesBubble) {
   Shell* shell = Shell::GetInstance();
   shell->ToggleAppList(NULL);
 
@@ -67,7 +91,7 @@
 }
 
 // Tests that clicking outside the app-list bubble closes it.
-TEST_F(AppListControllerTest, TapOutsideBubbleClosesBubble) {
+TEST_P(AppListControllerTest, TapOutsideBubbleClosesBubble) {
   Shell* shell = Shell::GetInstance();
   shell->ToggleAppList(NULL);
 
@@ -89,4 +113,32 @@
   EXPECT_FALSE(shell->GetAppListTargetVisibility());
 }
 
+// Tests opening the app launcher on a non-primary display, then deleting the
+// display.
+TEST_P(AppListControllerTest, NonPrimaryDisplay) {
+  if (!SupportsMultipleDisplays())
+    return;
+
+  // Set up a screen with two displays (horizontally adjacent).
+  UpdateDisplay("800x600,800x600");
+
+  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
+  ASSERT_EQ(2u, root_windows.size());
+  aura::Window* secondary_window = root_windows[1];
+  EXPECT_EQ("800,0 800x600", secondary_window->GetBoundsInScreen().ToString());
+
+  Shell::GetInstance()->ToggleAppList(secondary_window);
+  EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
+
+  // Remove the secondary display. Shouldn't crash (http://crbug.com/368990).
+  UpdateDisplay("800x600");
+
+  // Updating the displays should close the app list.
+  EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
+}
+
+INSTANTIATE_TEST_CASE_P(AppListControllerTestInstance,
+                        AppListControllerTest,
+                        ::testing::Bool());
+
 }  // namespace ash
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc
index a26e78c..ada7e36 100644
--- a/ash/wm/default_state.cc
+++ b/ash/wm/default_state.cc
@@ -459,6 +459,12 @@
     WindowState* window_state,
     WindowState::State* state_in_previous_mode) {
   WindowStateType previous_state_type = state_in_previous_mode->GetType();
+  if (previous_state_type == wm::WINDOW_STATE_TYPE_FULLSCREEN) {
+    // A state change should not move a window out of full screen since full
+    // screen is a "special mode" the user wanted to be in and should be
+    // respected as such.
+    state_type_ = wm::WINDOW_STATE_TYPE_FULLSCREEN;
+  }
   window_state->UpdateWindowShowStateFromStateType();
   window_state->NotifyPreStateTypeChange(previous_state_type);
 
diff --git a/ash/wm/dock/docked_window_layout_manager.cc b/ash/wm/dock/docked_window_layout_manager.cc
index daddd1f..ab738ea 100644
--- a/ash/wm/dock/docked_window_layout_manager.cc
+++ b/ash/wm/dock/docked_window_layout_manager.cc
@@ -590,8 +590,9 @@
   return DOCKED_ALIGNMENT_NONE;
 }
 
-bool DockedWindowLayoutManager::CanDockWindow(aura::Window* window,
-                                              SnapType edge) {
+bool DockedWindowLayoutManager::CanDockWindow(
+    aura::Window* window,
+    DockedAlignment desired_alignment) {
   if (!switches::UseDockedWindows())
     return false;
   // Don't allow interactive docking of windows with transient parents such as
@@ -622,16 +623,19 @@
     return false;
   // Cannot dock on the other size from an existing dock.
   const DockedAlignment alignment = CalculateAlignment();
-  if ((edge == SNAP_LEFT && alignment == DOCKED_ALIGNMENT_RIGHT) ||
-      (edge == SNAP_RIGHT && alignment == DOCKED_ALIGNMENT_LEFT)) {
+  if (desired_alignment != DOCKED_ALIGNMENT_NONE &&
+      alignment != DOCKED_ALIGNMENT_NONE &&
+      alignment != desired_alignment) {
     return false;
   }
   // Do not allow docking on the same side as shelf.
   ShelfAlignment shelf_alignment = SHELF_ALIGNMENT_BOTTOM;
   if (shelf_)
     shelf_alignment = shelf_->alignment();
-  if ((edge == SNAP_LEFT && shelf_alignment == SHELF_ALIGNMENT_LEFT) ||
-      (edge == SNAP_RIGHT && shelf_alignment == SHELF_ALIGNMENT_RIGHT)) {
+  if ((desired_alignment == DOCKED_ALIGNMENT_LEFT &&
+       shelf_alignment == SHELF_ALIGNMENT_LEFT) ||
+      (desired_alignment == DOCKED_ALIGNMENT_RIGHT &&
+       shelf_alignment == SHELF_ALIGNMENT_RIGHT)) {
     return false;
   }
   return true;
@@ -943,7 +947,7 @@
   const gfx::Rect work_area = display.work_area();
 
   // Evict the window if it can no longer be docked because of its height.
-  if (!CanDockWindow(window, SNAP_NONE)) {
+  if (!CanDockWindow(window, DOCKED_ALIGNMENT_NONE)) {
     UndockWindow(window);
     RecordUmaAction(DOCKED_ACTION_EVICT, DOCKED_ACTION_SOURCE_UNKNOWN);
     return;
diff --git a/ash/wm/dock/docked_window_layout_manager.h b/ash/wm/dock/docked_window_layout_manager.h
index 030d888..9a362a4 100644
--- a/ash/wm/dock/docked_window_layout_manager.h
+++ b/ash/wm/dock/docked_window_layout_manager.h
@@ -11,7 +11,6 @@
 #include "ash/wm/dock/dock_types.h"
 #include "ash/wm/dock/docked_window_layout_manager_observer.h"
 #include "ash/wm/window_state_observer.h"
-#include "ash/wm/workspace/snap_types.h"
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
@@ -119,7 +118,7 @@
 
   // Returns true when a window can be docked. Windows cannot be docked at the
   // edge used by the shelf or the edge opposite from existing dock.
-  bool CanDockWindow(aura::Window* window, SnapType edge);
+  bool CanDockWindow(aura::Window* window, DockedAlignment desired_alignment);
 
   aura::Window* dock_container() const { return dock_container_; }
 
diff --git a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
index d619fd5..33b8988 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
+++ b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
@@ -7,8 +7,10 @@
 #include "ash/accelerometer/accelerometer_controller.h"
 #include "ash/display/display_manager.h"
 #include "ash/shell.h"
+#include "ash/system/tray/system_tray_delegate.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/test/display_manager_test_api.h"
+#include "ash/test/test_volume_control_delegate.h"
 #include "ui/aura/test/event_generator.h"
 #include "ui/events/event_handler.h"
 #include "ui/gfx/vector3d_f.h"
@@ -327,6 +329,34 @@
   counter.reset();
 }
 
+// Tests that maximize mode does not block Volume Up & Down events.
+TEST_F(MaximizeModeControllerTest, AllowsVolumeControl) {
+  aura::Window* root = Shell::GetPrimaryRootWindow();
+  aura::test::EventGenerator event_generator(root, root);
+
+  TestVolumeControlDelegate* volume_delegate =
+      new TestVolumeControlDelegate(true);
+  ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate(
+      scoped_ptr<VolumeControlDelegate>(volume_delegate).Pass());
+
+  // Trigger maximize mode by opening to 270 to begin the test in maximize mode.
+  TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
+                             gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
+  ASSERT_TRUE(IsMaximizeModeStarted());
+
+  // Verify volume down button event is not blocked
+  ASSERT_EQ(0, volume_delegate->handle_volume_down_count());
+  event_generator.PressKey(ui::VKEY_VOLUME_DOWN, 0);
+  event_generator.ReleaseKey(ui::VKEY_VOLUME_DOWN, 0);
+  EXPECT_EQ(1, volume_delegate->handle_volume_down_count());
+
+  // Verify volume up event is not blocked
+  ASSERT_EQ(0, volume_delegate->handle_volume_up_count());
+  event_generator.PressKey(ui::VKEY_VOLUME_UP, 0);
+  event_generator.ReleaseKey(ui::VKEY_VOLUME_UP, 0);
+  EXPECT_EQ(1, volume_delegate->handle_volume_up_count());
+}
+
 TEST_F(MaximizeModeControllerTest, LaptopTest) {
   // Feeds in sample accelerometer data and verifies that there are no
   // transitions into touchview / maximize mode while shaking the device around
diff --git a/ash/wm/maximize_mode/maximize_mode_event_blocker.cc b/ash/wm/maximize_mode/maximize_mode_event_blocker.cc
index e283149..dd9fcde 100644
--- a/ash/wm/maximize_mode/maximize_mode_event_blocker.cc
+++ b/ash/wm/maximize_mode/maximize_mode_event_blocker.cc
@@ -8,6 +8,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "ui/aura/client/cursor_client.h"
 #include "ui/events/event_targeter.h"
+#include "ui/events/keycodes/keyboard_codes.h"
 
 namespace ash {
 
@@ -54,8 +55,19 @@
 ui::EventTarget* BlockKeyboardAndTouchpadTargeter::FindTargetForEvent(
     ui::EventTarget* root,
     ui::Event* event) {
-  if (event->HasNativeEvent() && (event->IsMouseEvent() || event->IsKeyEvent()))
-    return NULL;
+  if (event->HasNativeEvent()) {
+    if (event->IsMouseEvent())
+      return NULL;
+    if (event->IsKeyEvent()) {
+      // TODO(bruthig): Fix this to block rewritten volume keys
+      // (i.e. F9 and F10)  from the device's keyboard. https://crbug.com/368669
+      ui::KeyEvent* key_event = static_cast<ui::KeyEvent*>(event);
+      if (key_event->key_code() != ui::VKEY_VOLUME_DOWN &&
+          key_event->key_code() != ui::VKEY_VOLUME_UP) {
+        return NULL;
+      }
+    }
+  }
   return default_targeter_->FindTargetForEvent(root, event);
 }
 
diff --git a/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc b/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
index 56c6c53..6b1c244 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_manager_unittest.cc
@@ -13,8 +13,10 @@
 #include "ash/test/shell_test_api.h"
 #include "ash/wm/mru_window_tracker.h"
 #include "ash/wm/overview/window_selector_controller.h"
+#include "ash/wm/window_properties.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/wm_event.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "ui/aura/client/aura_constants.h"
@@ -58,6 +60,21 @@
         type, bounds, gfx::Size(), true, true);
   }
 
+  // Creates a window which also has a widget.
+  aura::Window* CreateWindowWithWidget(const gfx::Rect& bounds) {
+    views::Widget* widget = new views::Widget();
+    views::Widget::InitParams params;
+    params.context = CurrentContext();
+    // Note: The widget will get deleted with the window.
+    widget->Init(params);
+    widget->Show();
+    aura::Window* window = widget->GetNativeWindow();
+    window->SetBounds(bounds);
+    window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
+
+    return window;
+  }
+
   // Create the Maximized mode window manager.
   ash::MaximizeModeWindowManager* CreateMaximizeModeWindowManager() {
     EXPECT_FALSE(maximize_mode_window_manager());
@@ -392,6 +409,68 @@
   EXPECT_EQ(rect.ToString(), fixed_window->bounds().ToString());
 }
 
+// Create a string which consists of the bounds and the state for comparison.
+std::string GetPlacementString(const gfx::Rect& bounds,
+                               ui::WindowShowState state) {
+  return bounds.ToString() + base::StringPrintf(" %d", state);
+}
+
+// Retrieves the window's restore state override - if any - and returns it as a
+// string.
+std::string GetPlacementOverride(aura::Window* window) {
+  gfx::Rect* bounds = window->GetProperty(ash::kRestoreBoundsOverrideKey);
+  if (bounds) {
+    gfx::Rect restore_bounds = *bounds;
+    ui::WindowShowState restore_state =
+        window->GetProperty(ash::kRestoreShowStateOverrideKey);
+    return GetPlacementString(restore_bounds, restore_state);
+  }
+  return std::string();
+}
+
+// Test that the restore state will be kept at its original value for
+// session restauration purposes.
+TEST_F(MaximizeModeWindowManagerTest, TestRestoreIntegrety) {
+  gfx::Rect bounds(10, 10, 200, 50);
+  gfx::Size empty_size;
+  gfx::Rect empty_bounds;
+  scoped_ptr<aura::Window> normal_window(
+      CreateWindowWithWidget(bounds));
+  scoped_ptr<aura::Window> maximized_window(
+      CreateWindowWithWidget(bounds));
+  wm::GetWindowState(maximized_window.get())->Maximize();
+
+  EXPECT_EQ(std::string(), GetPlacementOverride(normal_window.get()));
+  EXPECT_EQ(std::string(), GetPlacementOverride(maximized_window.get()));
+
+  ash::MaximizeModeWindowManager* manager = CreateMaximizeModeWindowManager();
+  ASSERT_TRUE(manager);
+
+  // With the maximization the override states should be returned in its
+  // pre-maximized state.
+  EXPECT_EQ(GetPlacementString(bounds, ui::SHOW_STATE_NORMAL),
+            GetPlacementOverride(normal_window.get()));
+  EXPECT_EQ(GetPlacementString(bounds, ui::SHOW_STATE_MAXIMIZED),
+            GetPlacementOverride(maximized_window.get()));
+
+  // Changing a window's state now does not change the returned result.
+  wm::GetWindowState(maximized_window.get())->Minimize();
+  EXPECT_EQ(GetPlacementString(bounds, ui::SHOW_STATE_MAXIMIZED),
+            GetPlacementOverride(maximized_window.get()));
+
+  // Destroy the manager again and check that the overrides get reset.
+  DestroyMaximizeModeWindowManager();
+  EXPECT_EQ(std::string(), GetPlacementOverride(normal_window.get()));
+  EXPECT_EQ(std::string(), GetPlacementOverride(maximized_window.get()));
+
+  // Changing a window's state now does not bring the overrides back.
+  wm::GetWindowState(maximized_window.get())->Restore();
+  gfx::Rect new_bounds(10, 10, 200, 50);
+  maximized_window->SetBounds(new_bounds);
+
+  EXPECT_EQ(std::string(), GetPlacementOverride(maximized_window.get()));
+}
+
 // Test that windows which got created before the maximizer was created can be
 // destroyed while the maximizer is still running.
 TEST_F(MaximizeModeWindowManagerTest, PreCreateWindowsDeleteWhileActive) {
@@ -719,7 +798,8 @@
   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
 }
 
-// Check that full screen mode can be turned on in maximized mode.
+// Check that full screen mode can be turned on in maximized mode and remains
+// upon coming back.
 TEST_F(MaximizeModeWindowManagerTest, AllowFullScreenMode) {
   gfx::Rect rect(20, 140, 100, 100);
   scoped_ptr<aura::Window> w1(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
@@ -749,11 +829,76 @@
   EXPECT_FALSE(window_state->IsMaximized());
   EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
 
-  // With the destruction of the manager we should fall back to the old state.
+  // With the destruction of the manager we should remain in full screen.
   DestroyMaximizeModeWindowManager();
-  EXPECT_FALSE(window_state->IsFullscreen());
+  EXPECT_TRUE(window_state->IsFullscreen());
   EXPECT_FALSE(window_state->IsMaximized());
-  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->visibility_state());
+  EXPECT_EQ(SHELF_HIDDEN, shelf->visibility_state());
+}
+
+// Check that the full screen mode will stay active when the maximize mode is
+// ended.
+TEST_F(MaximizeModeWindowManagerTest,
+       FullScreenModeRemainsWhenCreatedInMaximizedMode) {
+  CreateMaximizeModeWindowManager();
+
+  gfx::Rect rect(20, 140, 100, 100);
+  scoped_ptr<aura::Window> w1(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
+  wm::WindowState* window_state = wm::GetWindowState(w1.get());
+  wm::WMEvent event_full_screen(wm::WM_EVENT_TOGGLE_FULLSCREEN);
+  window_state->OnWMEvent(&event_full_screen);
+  EXPECT_TRUE(window_state->IsFullscreen());
+
+  // After the maximize mode manager is ended, full screen will remain.
+  DestroyMaximizeModeWindowManager();
+  EXPECT_TRUE(window_state->IsFullscreen());
+}
+
+// Check that the full screen mode will stay active throughout a maximzied mode
+// session.
+TEST_F(MaximizeModeWindowManagerTest,
+       FullScreenModeRemainsThroughMaximizeModeSwitch) {
+  gfx::Rect rect(20, 140, 100, 100);
+  scoped_ptr<aura::Window> w1(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
+  wm::WindowState* window_state = wm::GetWindowState(w1.get());
+  wm::WMEvent event_full_screen(wm::WM_EVENT_TOGGLE_FULLSCREEN);
+  window_state->OnWMEvent(&event_full_screen);
+  EXPECT_TRUE(window_state->IsFullscreen());
+
+  CreateMaximizeModeWindowManager();
+  EXPECT_TRUE(window_state->IsFullscreen());
+  DestroyMaximizeModeWindowManager();
+  EXPECT_TRUE(window_state->IsFullscreen());
+}
+
+// Check that an empty window does not get restored to a tiny size.
+TEST_F(MaximizeModeWindowManagerTest,
+       CreateAndMaximizeInMaximizeModeShouldRetoreToGoodSizeGoingToDefault) {
+  CreateMaximizeModeWindowManager();
+  gfx::Rect rect;
+  scoped_ptr<aura::Window> w1(CreateWindow(ui::wm::WINDOW_TYPE_NORMAL, rect));
+  w1->Show();
+  wm::WindowState* window_state = wm::GetWindowState(w1.get());
+  EXPECT_TRUE(window_state->IsMaximized());
+
+  // There is a calling order in which the restore bounds can get set to an
+  // empty rectangle. We simulate this here.
+  window_state->SetRestoreBoundsInScreen(rect);
+  EXPECT_TRUE(window_state->GetRestoreBoundsInScreen().IsEmpty());
+
+  // Setting the window to a new size will physically not change the window,
+  // but the restore size should get updated so that a restore later on will
+  // return to this size.
+  gfx::Rect requested_bounds(10, 20, 50, 70);
+  w1->SetBounds(requested_bounds);
+  EXPECT_TRUE(window_state->IsMaximized());
+  EXPECT_EQ(requested_bounds.ToString(),
+            window_state->GetRestoreBoundsInScreen().ToString());
+
+  DestroyMaximizeModeWindowManager();
+
+  EXPECT_FALSE(window_state->IsMaximized());
+  EXPECT_EQ(w1->bounds().ToString(), requested_bounds.ToString());
 }
 
 // Check that snapping operations get ignored.
diff --git a/ash/wm/maximize_mode/maximize_mode_window_state.cc b/ash/wm/maximize_mode/maximize_mode_window_state.cc
index df98796..5c6623b 100644
--- a/ash/wm/maximize_mode/maximize_mode_window_state.cc
+++ b/ash/wm/maximize_mode/maximize_mode_window_state.cc
@@ -11,7 +11,7 @@
 #include "ash/wm/coordinate_conversion.h"
 #include "ash/wm/maximize_mode/maximize_mode_window_manager.h"
 #include "ash/wm/window_animations.h"
-#include "ash/wm/window_state.h"
+#include "ash/wm/window_properties.h"
 #include "ash/wm/window_state_delegate.h"
 #include "ash/wm/window_state_util.h"
 #include "ash/wm/window_util.h"
@@ -22,6 +22,8 @@
 #include "ui/aura/window_delegate.h"
 #include "ui/gfx/display.h"
 #include "ui/gfx/rect.h"
+#include "ui/views/view_constants_aura.h"
+#include "ui/views/widget/widget.h"
 
 namespace ash {
 namespace {
@@ -140,13 +142,17 @@
     case wm::WM_EVENT_SHOW_INACTIVE:
       return;
     case wm::WM_EVENT_SET_BOUNDS:
-      if (window_state->CanResize()) {
-        // In case the window is resizable and / or maximized we ignore the
-        // requested bounds change and resize to the biggest possible size.
-        UpdateBounds(window_state, true);
-      } else
-      if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED &&
-          current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED) {
+      if (current_state_type_ == wm::WINDOW_STATE_TYPE_MAXIMIZED) {
+        // Having a maximized window, it could have been created with an empty
+        // size and the caller should get his size upon leaving the maximized
+        // mode. As such we set the restore bounds to the requested bounds.
+        gfx::Rect bounds_in_parent =
+            (static_cast<const wm::SetBoundsEvent*>(event))->requested_bounds();
+        if (!bounds_in_parent.IsEmpty())
+          window_state->SetRestoreBoundsInParent(bounds_in_parent);
+      } else if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED &&
+                 current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED &&
+                 current_state_type_ != wm::WINDOW_STATE_TYPE_FULLSCREEN) {
         // In all other cases (except for minimized windows) we respect the
         // requested bounds and center it to a fully visible area on the screen.
         gfx::Rect bounds_in_parent =
@@ -186,6 +192,20 @@
     wm::WindowState::State* previous_state) {
   current_state_type_ = previous_state->GetType();
 
+  views::Widget* widget =
+      views::Widget::GetWidgetForNativeWindow(window_state->window());
+  if (widget) {
+    gfx::Rect bounds = widget->GetRestoredBounds();
+    if (!bounds.IsEmpty()) {
+      // We do not want to do a session restore to our window states. Therefore
+      // we tell the window to use the current default states instead.
+      window_state->window()->SetProperty(ash::kRestoreShowStateOverrideKey,
+                                          window_state->GetShowState());
+      window_state->window()->SetProperty(ash::kRestoreBoundsOverrideKey,
+          new gfx::Rect(widget->GetRestoredBounds()));
+    }
+  }
+
   // Initialize the state to a good preset.
   if (current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED &&
       current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED &&
@@ -199,6 +219,8 @@
 }
 
 void MaximizeModeWindowState::DetachState(wm::WindowState* window_state) {
+  // From now on, we can use the default session restore mechanism again.
+  window_state->window()->ClearProperty(ash::kRestoreBoundsOverrideKey);
   window_state->set_can_be_dragged(true);
 }
 
@@ -264,7 +286,12 @@
         !animated) {
       window_state->SetBoundsDirect(bounds_in_parent);
     } else {
-      window_state->SetBoundsDirectAnimated(bounds_in_parent);
+      // If we animate (to) maximized mode, we want to use the cross fade to
+      // avoid flashing.
+      if (window_state->IsMaximized())
+        window_state->SetBoundsDirectCrossFade(bounds_in_parent);
+      else
+        window_state->SetBoundsDirectAnimated(bounds_in_parent);
     }
   }
 }
diff --git a/ash/wm/system_modal_container_layout_manager.cc b/ash/wm/system_modal_container_layout_manager.cc
index 7ee1ef4..81ea8bb 100644
--- a/ash/wm/system_modal_container_layout_manager.cc
+++ b/ash/wm/system_modal_container_layout_manager.cc
@@ -4,6 +4,8 @@
 
 #include "ash/wm/system_modal_container_layout_manager.h"
 
+#include <cmath>
+
 #include "ash/session/session_state_delegate.h"
 #include "ash/shell.h"
 #include "ash/shell_window_ids.h"
@@ -15,6 +17,7 @@
 #include "ui/aura/client/capture_client.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
+#include "ui/aura/window_property.h"
 #include "ui/base/ui_base_switches_util.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animator.h"
@@ -27,8 +30,17 @@
 #include "ui/views/widget/widget.h"
 #include "ui/wm/core/compound_event_filter.h"
 
+DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(ASH_EXPORT, bool);
+
 namespace ash {
 
+// If this is set to true, the window will get centered.
+DEFINE_WINDOW_PROPERTY_KEY(bool, kCenteredKey, false);
+
+// The center point of the window can diverge this much from the center point
+// of the container to be kept centered upon resizing operations.
+const int kCenterPixelDelta = 32;
+
 ////////////////////////////////////////////////////////////////////////////////
 // SystemModalContainerLayoutManager, public:
 
@@ -87,6 +99,7 @@
     aura::Window* child,
     const gfx::Rect& requested_bounds) {
   SetChildBoundsDirect(child, requested_bounds);
+  child->SetProperty(kCenteredKey, DialogIsCentered(requested_bounds));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -232,14 +245,10 @@
 }
 
 void SystemModalContainerLayoutManager::PositionDialogsAfterWorkAreaResize() {
-  gfx::Rect valid_bounds = GetUsableDialogArea();
-
   if (!modal_windows_.empty()) {
     for (aura::Window::Windows::iterator it = modal_windows_.begin();
          it != modal_windows_.end(); ++it) {
-      gfx::Rect bounds = (*it)->bounds();
-      bounds.AdjustToFit(valid_bounds);
-      (*it)->SetBounds(bounds);
+      (*it)->SetBounds(GetCenteredAndOrFittedBounds(*it));
     }
   }
 }
@@ -263,4 +272,26 @@
   return valid_bounds;
 }
 
+gfx::Rect SystemModalContainerLayoutManager::GetCenteredAndOrFittedBounds(
+    const aura::Window* window) {
+  if (window->GetProperty(kCenteredKey)) {
+    // Keep the dialog centered if it was centered before.
+    gfx::Rect target_bounds = GetUsableDialogArea();
+    target_bounds.ClampToCenteredSize(window->bounds().size());
+    return target_bounds;
+  }
+  gfx::Rect target_bounds = window->bounds();
+  target_bounds.AdjustToFit(GetUsableDialogArea());
+  return target_bounds;
+}
+
+bool SystemModalContainerLayoutManager::DialogIsCentered(
+    const gfx::Rect& window_bounds) {
+  gfx::Point window_center = window_bounds.CenterPoint();
+  gfx::Point container_center = GetUsableDialogArea().CenterPoint();
+  return
+      std::abs(window_center.x() - container_center.x()) < kCenterPixelDelta &&
+      std::abs(window_center.y() - container_center.y()) < kCenterPixelDelta;
+}
+
 }  // namespace ash
diff --git a/ash/wm/system_modal_container_layout_manager.h b/ash/wm/system_modal_container_layout_manager.h
index 0f47b71..6350337 100644
--- a/ash/wm/system_modal_container_layout_manager.h
+++ b/ash/wm/system_modal_container_layout_manager.h
@@ -29,6 +29,8 @@
 namespace ash {
 
 // LayoutManager for the modal window container.
+// System modal windows which are centered on the screen will be kept centered
+// when the container size changes.
 class ASH_EXPORT SystemModalContainerLayoutManager
     : public aura::LayoutManager,
       public aura::WindowObserver,
@@ -85,6 +87,13 @@
   // Get the usable bounds rectangle for enclosed dialogs.
   gfx::Rect GetUsableDialogArea();
 
+  // Gets the new bounds for a |window| to use which are either centered (if the
+  // window was previously centered) or fitted to the screen.
+  gfx::Rect GetCenteredAndOrFittedBounds(const aura::Window* window);
+
+  // Returns true if |window_bounds| is centered.
+  bool DialogIsCentered(const gfx::Rect& window_bounds);
+
   aura::Window* modal_window() {
     return !modal_windows_.empty() ? modal_windows_.back() : NULL;
   }
diff --git a/ash/wm/system_modal_container_layout_manager_unittest.cc b/ash/wm/system_modal_container_layout_manager_unittest.cc
index ca79cef..9e6dbd0 100644
--- a/ash/wm/system_modal_container_layout_manager_unittest.cc
+++ b/ash/wm/system_modal_container_layout_manager_unittest.cc
@@ -431,6 +431,24 @@
   EXPECT_EQ(bounds, gfx::Rect(700, 500, 100, 100));
 }
 
+// Verifies that centered windows will remain centered after the visible screen
+// area changed.
+TEST_F(SystemModalContainerLayoutManagerTest, KeepCentered) {
+  GetModalContainer()->SetBounds(gfx::Rect(0, 0, 800, 600));
+  scoped_ptr<aura::Window> main(OpenTestWindowWithParent(GetModalContainer(),
+                                                         true));
+  // Center the window.
+  main->SetBounds(gfx::Rect((800 - 512) / 2, (600 - 256) / 2, 512, 256));
+
+  // We set now the bounds of the root window to something new which will
+  // Then trigger the reposition operation.
+  GetModalContainer()->SetBounds(gfx::Rect(0, 0, 1024, 768));
+
+  // The window should still be centered.
+  gfx::Rect bounds = main->bounds();
+  EXPECT_EQ(bounds.ToString(), gfx::Rect(256, 256, 512, 256).ToString());
+}
+
 TEST_F(SystemModalContainerLayoutManagerTest, ShowNormalBackgroundOrLocked) {
   scoped_ptr<aura::Window> parent(OpenToplevelTestWindow(false));
   scoped_ptr<aura::Window> modal_window(
diff --git a/ash/wm/window_properties.cc b/ash/wm/window_properties.cc
index 1689c90..2657e3a 100644
--- a/ash/wm/window_properties.cc
+++ b/ash/wm/window_properties.cc
@@ -8,9 +8,19 @@
 #include "ui/aura/window_property.h"
 
 DECLARE_WINDOW_PROPERTY_TYPE(ash::wm::WindowState*);
+DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(ASH_EXPORT, gfx::Rect*)
+DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(ASH_EXPORT, ui::WindowShowState)
 
 namespace ash {
 
+DEFINE_OWNED_WINDOW_PROPERTY_KEY(gfx::Rect,
+                                 kRestoreBoundsOverrideKey,
+                                 NULL);
+
+DEFINE_WINDOW_PROPERTY_KEY(ui::WindowShowState,
+                           kRestoreShowStateOverrideKey,
+                           ui::SHOW_STATE_DEFAULT);
+
 DEFINE_WINDOW_PROPERTY_KEY(bool, kStayInSameRootWindowKey, false);
 DEFINE_WINDOW_PROPERTY_KEY(bool, kUsesScreenCoordinatesKey, false);
 DEFINE_OWNED_WINDOW_PROPERTY_KEY(wm::WindowState,
diff --git a/ash/wm/window_properties.h b/ash/wm/window_properties.h
index c99d21d..c79b694 100644
--- a/ash/wm/window_properties.h
+++ b/ash/wm/window_properties.h
@@ -7,6 +7,7 @@
 
 #include "ash/ash_export.h"
 #include "ui/base/ui_base_types.h"
+#include "ui/gfx/rect.h"
 
 namespace aura {
 class Window;
@@ -24,6 +25,18 @@
 
 // Alphabetical sort.
 
+// A property key which stores the bounds to restore a window to. These take
+// preference over the current bounds/state. This is used by e.g. the always
+// maximized mode window manager.
+ASH_EXPORT extern const aura::WindowProperty<gfx::Rect*>* const
+    kRestoreBoundsOverrideKey;
+
+// A property key which stores the bounds to restore a window to. These take
+// preference over the current bounds/state if |kRestoreBoundsOverrideKey| is
+// set. This is used by e.g. the always maximized mode window manager.
+ASH_EXPORT extern const aura::WindowProperty<ui::WindowShowState>* const
+    kRestoreShowStateOverrideKey;
+
 // If this is set to true, the window stays in the same root window
 // even if the bounds outside of its root window is set.
 // This is exported as it's used in the tests.
diff --git a/ash/wm/workspace/phantom_window_controller.cc b/ash/wm/workspace/phantom_window_controller.cc
index ba95423..23121c0 100644
--- a/ash/wm/workspace/phantom_window_controller.cc
+++ b/ash/wm/workspace/phantom_window_controller.cc
@@ -6,18 +6,13 @@
 
 #include <math.h>
 
-#include "ash/ash_switches.h"
 #include "ash/shell.h"
 #include "ash/shell_window_ids.h"
 #include "ash/wm/coordinate_conversion.h"
 #include "grit/ash_resources.h"
-#include "third_party/skia/include/core/SkCanvas.h"
 #include "ui/aura/window.h"
-#include "ui/aura/window_event_dispatcher.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/skia_util.h"
 #include "ui/views/background.h"
 #include "ui/views/painter.h"
 #include "ui/views/view.h"
@@ -30,32 +25,27 @@
 const int kAnimationDurationMs = 200;
 
 // The size of the phantom window at the beginning of the show animation in
-// relation to the size of the phantom window at the end of the animation when
-// using the alternate caption button style.
-const float kAlternateStyleStartBoundsRatio = 0.85f;
+// relation to the size of the phantom window at the end of the animation.
+const float kStartBoundsRatio = 0.85f;
 
 // The amount of pixels that the phantom window's shadow should extend past
-// the bounds passed into Show(). There is no shadow when not using the
-// alternate caption button style.
-const int kAlternateStyleShadowThickness = 15;
+// the bounds passed into Show().
+const int kShadowThickness = 15;
 
-// The minimum size of a phantom window including the shadow when using the
-// alternate caption button style. The minimum size is derived from the size of
-// the IDR_AURA_PHANTOM_WINDOW image assets.
-const int kAlternateStyleMinSizeWithShadow = 100;
+// The minimum size of a phantom window including the shadow. The minimum size
+// is derived from the size of the IDR_AURA_PHANTOM_WINDOW image assets.
+const int kMinSizeWithShadow = 100;
 
 // Adjusts the phantom window's bounds so that the bounds:
 // - Include the size of the shadow.
-// - Have a size equal to or larger than the minimize phantom window size.
-gfx::Rect GetAdjustedBoundsForAlternateStyle(const gfx::Rect& bounds) {
+// - Have a size equal to or larger than the minimum phantom window size.
+gfx::Rect GetAdjustedBounds(const gfx::Rect& bounds) {
   int x_inset = std::max(
-      static_cast<int>(
-          ceil((kAlternateStyleMinSizeWithShadow - bounds.width()) / 2.0f)),
-      kAlternateStyleShadowThickness);
+      static_cast<int>(ceil((kMinSizeWithShadow - bounds.width()) / 2.0f)),
+      kShadowThickness);
   int y_inset = std::max(
-      static_cast<int>(
-          ceil((kAlternateStyleMinSizeWithShadow - bounds.height()) / 2.0f)),
-      kAlternateStyleShadowThickness);
+      static_cast<int>(ceil((kMinSizeWithShadow - bounds.height()) / 2.0f)),
+      kShadowThickness);
 
   gfx::Rect adjusted_bounds(bounds);
   adjusted_bounds.Inset(-x_inset, -y_inset);
@@ -79,161 +69,38 @@
   widget->SetBounds(new_bounds_in_screen);
 }
 
-// EdgePainter ----------------------------------------------------------------
-
-// Paints the background of the phantom window for window snapping.
-class EdgePainter : public views::Painter {
- public:
-  EdgePainter();
-  virtual ~EdgePainter();
-
-  // views::Painter:
-  virtual gfx::Size GetMinimumSize() const OVERRIDE;
-  virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(EdgePainter);
-};
-
-EdgePainter::EdgePainter() {
-}
-
-EdgePainter::~EdgePainter() {
-}
-
-gfx::Size EdgePainter::GetMinimumSize() const {
-  return gfx::Size();
-}
-
-void EdgePainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) {
-  const int kInsetSize = 4;
-  int x = kInsetSize;
-  int y = kInsetSize;
-  int w = size.width() - kInsetSize * 2;
-  int h = size.height() - kInsetSize * 2;
-  bool inset = (w > 0 && h > 0);
-  if (!inset) {
-    x = 0;
-    y = 0;
-    w = size.width();
-    h = size.height();
-  }
-  SkPaint paint;
-  paint.setColor(SkColorSetARGB(100, 0, 0, 0));
-  paint.setStyle(SkPaint::kFill_Style);
-  paint.setAntiAlias(true);
-  const int kRoundRectSize = 4;
-  canvas->sk_canvas()->drawRoundRect(
-      gfx::RectToSkRect(gfx::Rect(x, y, w, h)),
-      SkIntToScalar(kRoundRectSize), SkIntToScalar(kRoundRectSize), paint);
-  if (!inset)
-    return;
-
-  paint.setColor(SkColorSetARGB(200, 255, 255, 255));
-  paint.setStyle(SkPaint::kStroke_Style);
-  paint.setStrokeWidth(SkIntToScalar(2));
-  canvas->sk_canvas()->drawRoundRect(
-      gfx::RectToSkRect(gfx::Rect(x, y, w, h)), SkIntToScalar(kRoundRectSize),
-      SkIntToScalar(kRoundRectSize), paint);
-}
-
 }  // namespace
 
 // PhantomWindowController ----------------------------------------------------
 
 PhantomWindowController::PhantomWindowController(aura::Window* window)
-    : window_(window),
-      phantom_below_window_(NULL) {
+    : window_(window) {
 }
 
 PhantomWindowController::~PhantomWindowController() {
 }
 
 void PhantomWindowController::Show(const gfx::Rect& bounds_in_screen) {
-  if (switches::UseAlternateFrameCaptionButtonStyle())
-    ShowAlternate(bounds_in_screen);
-  else
-    ShowLegacy(bounds_in_screen);
-}
-
-void PhantomWindowController::ShowAlternate(const gfx::Rect& bounds_in_screen) {
-  gfx::Rect adjusted_bounds_in_screen =
-      GetAdjustedBoundsForAlternateStyle(bounds_in_screen);
+  gfx::Rect adjusted_bounds_in_screen = GetAdjustedBounds(bounds_in_screen);
   if (adjusted_bounds_in_screen == target_bounds_in_screen_)
     return;
   target_bounds_in_screen_ = adjusted_bounds_in_screen;
 
   gfx::Rect start_bounds_in_screen = target_bounds_in_screen_;
   int start_width = std::max(
-      kAlternateStyleMinSizeWithShadow,
-      static_cast<int>(
-          start_bounds_in_screen.width() * kAlternateStyleStartBoundsRatio));
+      kMinSizeWithShadow,
+      static_cast<int>(start_bounds_in_screen.width() * kStartBoundsRatio));
   int start_height = std::max(
-      kAlternateStyleMinSizeWithShadow,
-      static_cast<int>(
-          start_bounds_in_screen.height() * kAlternateStyleStartBoundsRatio));
+      kMinSizeWithShadow,
+      static_cast<int>(start_bounds_in_screen.height() * kStartBoundsRatio));
   start_bounds_in_screen.Inset(
       floor((start_bounds_in_screen.width() - start_width) / 2.0f),
       floor((start_bounds_in_screen.height() - start_height) / 2.0f));
-  phantom_widget_in_target_root_ = CreatePhantomWidget(
+  phantom_widget_ = CreatePhantomWidget(
       wm::GetRootWindowMatching(target_bounds_in_screen_),
       start_bounds_in_screen);
 
-  AnimateToBounds(phantom_widget_in_target_root_.get(),
-                  target_bounds_in_screen_);
-}
-
-void PhantomWindowController::ShowLegacy(const gfx::Rect& bounds_in_screen) {
-  if (bounds_in_screen == target_bounds_in_screen_)
-    return;
-  target_bounds_in_screen_ = bounds_in_screen;
-
-  gfx::Rect start_bounds_in_screen;
-  if (!phantom_widget_in_target_root_) {
-    start_bounds_in_screen = window_->GetBoundsInScreen();
-  } else {
-    start_bounds_in_screen =
-        phantom_widget_in_target_root_->GetWindowBoundsInScreen();
-  }
-
-  aura::Window* target_root =
-      wm::GetRootWindowMatching(target_bounds_in_screen_);
-  if (!phantom_widget_in_target_root_ ||
-      phantom_widget_in_target_root_->GetNativeWindow()->GetRootWindow() !=
-          target_root) {
-    phantom_widget_in_target_root_ =
-        CreatePhantomWidget(target_root, start_bounds_in_screen);
-  }
-  AnimateToBounds(phantom_widget_in_target_root_.get(),
-                  target_bounds_in_screen_);
-
-  // Create a secondary widget in a second screen if |start_bounds_in_screen|
-  // lies at least partially in another screen. This allows animations to start
-  // or restart in one root window and progress to another root.
-  aura::Window* start_root = wm::GetRootWindowMatching(start_bounds_in_screen);
-  if (start_root == target_root) {
-    aura::Window::Windows root_windows = Shell::GetAllRootWindows();
-    for (size_t i = 0; i < root_windows.size(); ++i) {
-      if (root_windows[i] != target_root &&
-          root_windows[i]->GetBoundsInScreen().Intersects(
-              start_bounds_in_screen)) {
-        start_root = root_windows[i];
-        break;
-      }
-    }
-  }
-  if (start_root == target_root) {
-    phantom_widget_in_start_root_.reset();
-  } else {
-    if (!phantom_widget_in_start_root_ ||
-        phantom_widget_in_start_root_->GetNativeWindow()->GetRootWindow() !=
-            start_root) {
-      phantom_widget_in_start_root_ =
-          CreatePhantomWidget(start_root, start_bounds_in_screen);
-    }
-    AnimateToBounds(phantom_widget_in_start_root_.get(),
-                    target_bounds_in_screen_);
-  }
+  AnimateToBounds(phantom_widget_.get(), target_bounds_in_screen_);
 }
 
 scoped_ptr<views::Widget> PhantomWindowController::CreatePhantomWidget(
@@ -256,18 +123,11 @@
   phantom_widget->GetNativeWindow()->SetName("PhantomWindow");
   phantom_widget->GetNativeWindow()->set_id(kShellWindowId_PhantomWindow);
   phantom_widget->SetBounds(bounds_in_screen);
-  if (phantom_below_window_)
-    phantom_widget->StackBelow(phantom_below_window_);
-  else
-    phantom_widget->StackAbove(window_);
+  phantom_widget->StackAbove(window_);
 
-  views::Painter* background_painter = NULL;
-  if (switches::UseAlternateFrameCaptionButtonStyle()) {
-    const int kImages[] = IMAGE_GRID(IDR_AURA_PHANTOM_WINDOW);
-    background_painter = views::Painter::CreateImageGridPainter(kImages);
-  } else {
-    background_painter = new EdgePainter;
-  }
+  const int kImages[] = IMAGE_GRID(IDR_AURA_PHANTOM_WINDOW);
+  views::Painter* background_painter =
+      views::Painter::CreateImageGridPainter(kImages);
   views::View* content_view = new views::View;
   content_view->set_background(
       views::Background::CreateBackgroundPainter(true, background_painter));
diff --git a/ash/wm/workspace/phantom_window_controller.h b/ash/wm/workspace/phantom_window_controller.h
index d62b135..11d6f95 100644
--- a/ash/wm/workspace/phantom_window_controller.h
+++ b/ash/wm/workspace/phantom_window_controller.h
@@ -30,52 +30,27 @@
   // Hides the phantom window without any animation.
   virtual ~PhantomWindowController();
 
-  // Animates the phantom window towards |bounds_in_screen|. The animation used
-  // depends on whether the alternate caption button style is used.
+  // Shows the phantom window and animates shrinking it to |bounds_in_screen|.
   void Show(const gfx::Rect& bounds_in_screen);
 
-  // If set, the phantom window is stacked below this window, otherwise it
-  // is stacked above the window passed to the constructor.
-  void set_phantom_below_window(aura::Window* phantom_below_window) {
-    phantom_below_window_ = phantom_below_window;
-  }
-
  private:
   friend class PhantomWindowControllerTest;
 
-  // Animates the phantom window towards |bounds_in_screen| when the alternate
-  // caption button style is used.
-  void ShowAlternate(const gfx::Rect& bounds_in_screen);
-
-  // Animates the phantom window towards |bounds_in_screen| when the legacy
-  // caption button style is used.
-  void ShowLegacy(const gfx::Rect& bounds_in_screen);
-
   // Creates, shows and returns a phantom widget at |bounds|
   // with kShellWindowId_ShelfContainer in |root_window| as a parent.
   scoped_ptr<views::Widget> CreatePhantomWidget(
       aura::Window* root_window,
       const gfx::Rect& bounds_in_screen);
 
-  // Window the phantom is placed beneath.
+  // Window that the phantom window is stacked above.
   aura::Window* window_;
 
-  // If set, the phantom window should get stacked below this window.
-  aura::Window* phantom_below_window_;
-
   // Target bounds (including the shadows if any) of the animation in screen
   // coordinates.
   gfx::Rect target_bounds_in_screen_;
 
-  // Phantom representation of the window which is in the root window matching
-  // |target_bounds_in_screen_|.
-  scoped_ptr<views::Widget> phantom_widget_in_target_root_;
-
-  // Phantom representation of the window which is in the root window matching
-  // the window's initial bounds. This allows animations to progress from one
-  // display to the other. NULL if the phantom window starts and ends in the
-  // same root window. Not used when using the alternate caption button style.
-  scoped_ptr<views::Widget> phantom_widget_in_start_root_;
+  // Phantom representation of the window.
+  scoped_ptr<views::Widget> phantom_widget_;
 
   DISALLOW_COPY_AND_ASSIGN(PhantomWindowController);
 };
diff --git a/ash/wm/workspace/phantom_window_controller_unittest.cc b/ash/wm/workspace/phantom_window_controller_unittest.cc
deleted file mode 100644
index fa637d8..0000000
--- a/ash/wm/workspace/phantom_window_controller_unittest.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// 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.
-
-#include "ash/wm/workspace/phantom_window_controller.h"
-
-#include "ash/ash_switches.h"
-#include "ash/shell.h"
-#include "ash/test/ash_test_base.h"
-#include "base/command_line.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/aura/window_observer.h"
-#include "ui/views/widget/widget.h"
-
-namespace ash {
-namespace {
-
-// Returns true if |window| is non-NULL and is visible.
-bool IsVisible(aura::Window* window) {
-  return window && window->IsVisible();
-}
-
-// Observes |window|'s deletion.
-class WindowDeletionObserver : public aura::WindowObserver {
- public:
-  WindowDeletionObserver(aura::Window* window) : window_(window) {
-    window_->AddObserver(this);
-  }
-
-  virtual ~WindowDeletionObserver() {
-    if (window_)
-      window_->RemoveObserver(this);
-  }
-
-  // Returns true if the window has not been deleted yet.
-  bool IsWindowAlive() {
-    return !!window_;
-  }
-
-  // aura::WindowObserver:
-  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
-    window_->RemoveObserver(this);
-    window_ = NULL;
-   }
-
- private:
-  aura::Window* window_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowDeletionObserver);
-};
-
-}  // namespace
-
-class PhantomWindowControllerTest : public ash::test::AshTestBase {
- public:
-  PhantomWindowControllerTest() {
-  }
-  virtual ~PhantomWindowControllerTest() {
-  }
-
-  // ash::test::AshTestBase:
-  virtual void SetUp() OVERRIDE {
-    ash::test::AshTestBase::SetUp();
-
-    window_ = CreateTestWindowInShellWithBounds(gfx::Rect(0, 0, 50, 60));
-    controller_.reset(new PhantomWindowController(window_));
-  }
-
-  void DeleteController() {
-    controller_.reset();
-  }
-
-  PhantomWindowController* controller() {
-    return controller_.get();
-  }
-
-  aura::Window* window() { return window_; }
-
-  aura::Window* phantom_window_in_target_root() {
-    return controller_->phantom_widget_in_target_root_ ?
-        controller_->phantom_widget_in_target_root_->GetNativeView() :
-        NULL;
-  }
-
-  aura::Window* phantom_window_in_start_root() {
-    return controller_->phantom_widget_in_start_root_ ?
-        controller_->phantom_widget_in_start_root_->GetNativeView() :
-        NULL;
-  }
-
- private:
-  aura::Window* window_;
-  scoped_ptr<PhantomWindowController> controller_;
-
-  DISALLOW_COPY_AND_ASSIGN(PhantomWindowControllerTest);
-};
-
-// Test that two phantom windows are used when animating to bounds at least
-// partially in another display when using the old caption button style.
-TEST_F(PhantomWindowControllerTest, OldCaptionButtonStyle) {
-  if (!SupportsMultipleDisplays())
-    return;
-
-  CommandLine::ForCurrentProcess()->AppendSwitch(
-      switches::kAshDisableAlternateFrameCaptionButtonStyle);
-  ASSERT_FALSE(switches::UseAlternateFrameCaptionButtonStyle());
-
-  UpdateDisplay("500x400,500x400");
-
-  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
-  EXPECT_EQ(root_windows[0], window()->GetRootWindow());
-
-  // Phantom preview only in the left screen.
-  controller()->Show(gfx::Rect(100, 100, 50, 60));
-  EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
-  EXPECT_FALSE(IsVisible(phantom_window_in_start_root()));
-  EXPECT_EQ(root_windows[0], phantom_window_in_target_root()->GetRootWindow());
-
-  // Move phantom preview into the right screen. Test that 2 windows got
-  // created.
-  controller()->Show(gfx::Rect(600, 100, 50, 60));
-  EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
-  EXPECT_TRUE(IsVisible(phantom_window_in_start_root()));
-  EXPECT_EQ(root_windows[1], phantom_window_in_target_root()->GetRootWindow());
-  EXPECT_EQ(root_windows[0], phantom_window_in_start_root()->GetRootWindow());
-
-  // Move phantom preview only in the right screen. Start window should close.
-  controller()->Show(gfx::Rect(700, 100, 50, 60));
-  EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
-  EXPECT_FALSE(IsVisible(phantom_window_in_start_root()));
-  EXPECT_EQ(root_windows[1], phantom_window_in_target_root()->GetRootWindow());
-
-  // Move phantom preview into the left screen. Start window should open.
-  controller()->Show(gfx::Rect(100, 100, 50, 60));
-  EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
-  EXPECT_TRUE(IsVisible(phantom_window_in_start_root()));
-  EXPECT_EQ(root_windows[0], phantom_window_in_target_root()->GetRootWindow());
-  EXPECT_EQ(root_windows[1], phantom_window_in_start_root()->GetRootWindow());
-
-  // Move phantom preview while in the left screen. Start window should close.
-  controller()->Show(gfx::Rect(200, 100, 50, 60));
-  EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
-  EXPECT_FALSE(IsVisible(phantom_window_in_start_root()));
-  EXPECT_EQ(root_windows[0], phantom_window_in_target_root()->GetRootWindow());
-
-  // Move phantom preview spanning both screens with most of the preview in the
-  // right screen. Two windows are created.
-  controller()->Show(gfx::Rect(495, 100, 50, 60));
-  EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
-  EXPECT_TRUE(IsVisible(phantom_window_in_start_root()));
-  EXPECT_EQ(root_windows[1], phantom_window_in_target_root()->GetRootWindow());
-  EXPECT_EQ(root_windows[0], phantom_window_in_start_root()->GetRootWindow());
-
-  // Move phantom preview back into the left screen. Phantom windows should
-  // swap.
-  controller()->Show(gfx::Rect(200, 100, 50, 60));
-  EXPECT_TRUE(IsVisible(phantom_window_in_target_root()));
-  EXPECT_TRUE(IsVisible(phantom_window_in_start_root()));
-  EXPECT_EQ(root_windows[0], phantom_window_in_target_root()->GetRootWindow());
-  EXPECT_EQ(root_windows[1], phantom_window_in_start_root()->GetRootWindow());
-
-  // Destroy phantom controller. Both windows should close.
-  WindowDeletionObserver target_deletion_observer(
-      phantom_window_in_target_root());
-  WindowDeletionObserver start_deletion_observer(
-      phantom_window_in_start_root());
-  DeleteController();
-  EXPECT_FALSE(target_deletion_observer.IsWindowAlive());
-  EXPECT_FALSE(start_deletion_observer.IsWindowAlive());
-}
-
-}  // namespace ash
diff --git a/ash/wm/workspace/snap_types.h b/ash/wm/workspace/snap_types.h
deleted file mode 100644
index 482a7dd..0000000
--- a/ash/wm/workspace/snap_types.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef ASH_WM_WORKSPACE_SNAP_TYPES_H_
-#define ASH_WM_WORKSPACE_SNAP_TYPES_H_
-
-namespace ash {
-
-// These are the window snap types which can be used for window resizing.
-// Their main use case is the class FrameMaximizeButton.
-enum SnapType {
-  SNAP_LEFT,
-  SNAP_RIGHT,
-  SNAP_MAXIMIZE,
-  SNAP_MINIMIZE,
-  SNAP_RESTORE,
-  SNAP_NONE
-};
-
-}  // namespace ash
-
-#endif  // ASH_WM_WORKSPACE_SNAP_TYPES_H_
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc
index 75fedaa..def6ee8 100644
--- a/ash/wm/workspace/workspace_window_resizer.cc
+++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -911,7 +911,11 @@
     }
   }
 
-  const bool can_dock = dock_layout_->CanDockWindow(GetTarget(), snap_type_) &&
+  DCHECK(snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT);
+  DockedAlignment desired_alignment = (snap_type_ == SNAP_LEFT) ?
+      DOCKED_ALIGNMENT_LEFT : DOCKED_ALIGNMENT_RIGHT;
+  const bool can_dock =
+      dock_layout_->CanDockWindow(GetTarget(), desired_alignment) &&
       dock_layout_->GetAlignmentOfWindow(GetTarget()) != DOCKED_ALIGNMENT_NONE;
   if (!can_dock) {
     // If the window cannot be docked, undock the window. This may change the
@@ -990,7 +994,7 @@
   }
 }
 
-SnapType WorkspaceWindowResizer::GetSnapType(
+WorkspaceWindowResizer::SnapType WorkspaceWindowResizer::GetSnapType(
     const gfx::Point& location) const {
   // TODO: this likely only wants total display area, not the area of a single
   // display.
diff --git a/ash/wm/workspace/workspace_window_resizer.h b/ash/wm/workspace/workspace_window_resizer.h
index d7d57d0..99a2df5 100644
--- a/ash/wm/workspace/workspace_window_resizer.h
+++ b/ash/wm/workspace/workspace_window_resizer.h
@@ -9,7 +9,6 @@
 
 #include "ash/wm/window_resizer.h"
 #include "ash/wm/workspace/magnetism_matcher.h"
-#include "ash/wm/workspace/snap_types.h"
 #include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/scoped_ptr.h"
@@ -69,6 +68,13 @@
  private:
   friend class WorkspaceWindowResizerTest;
 
+  // The edge to which the window should be snapped at the end of the drag.
+  enum SnapType {
+    SNAP_LEFT,
+    SNAP_RIGHT,
+    SNAP_NONE
+  };
+
   // Lays out the attached windows. |bounds| is the bounds of the main window.
   void LayoutAttachedWindows(gfx::Rect* bounds);
 
@@ -144,8 +150,9 @@
   // top of the z-order, and the rest directly underneath it.
   void RestackWindows();
 
-  // Returns the SnapType for the specified point. SNAP_NONE is used if no
-  // snapping should be used.
+  // Returns the edge to which the window should be snapped to if the user does
+  // no more dragging. SNAP_NONE is returned if the window should not be
+  // snapped.
   SnapType GetSnapType(const gfx::Point& location) const;
 
   // Returns true if |bounds_in_parent| are valid bounds for snapped state type
@@ -186,7 +193,7 @@
   // the user drags a window to the edge of the screen.
   scoped_ptr<TwoStepEdgeCycler> edge_cycler_;
 
-  // Last SnapType.
+  // The edge to which the window should be snapped to at the end of the drag.
   SnapType snap_type_;
 
   // Number of mouse moves since the last bounds change. Only used for phantom
diff --git a/athena/DEPS b/athena/DEPS
new file mode 100644
index 0000000..7193bf2
--- /dev/null
+++ b/athena/DEPS
@@ -0,0 +1,2 @@
+# Please do not add dependency to chrome/ and its subdirectories
+
diff --git a/athena/OWNERS b/athena/OWNERS
new file mode 100644
index 0000000..caabb9f
--- /dev/null
+++ b/athena/OWNERS
@@ -0,0 +1,4 @@
+ben@chromium.org
+mukai@chromium.org
+oshima@chromium.org
+sky@chromium.org
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 3d07813..28967db 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -111,7 +111,7 @@
     "cpu.cc",
     "cpu.h",
     "critical_closure.h",
-    "critical_closure_ios.mm",
+    "critical_closure_internal_ios.mm",
     "debug/alias.cc",
     "debug/alias.h",
     "debug/crash_logging.cc",
diff --git a/base/DEPS b/base/DEPS
index 648a573..becc92b 100644
--- a/base/DEPS
+++ b/base/DEPS
@@ -10,8 +10,9 @@
   "+third_party/modp_b64",
   "+third_party/tcmalloc",
 
-  # IPC is implicitly brought in from the root, and we don't want it.
+  # These are implicitly brought in from the root, and we don't want them.
   "-ipc",
+  "-url",
 
   # ICU dependendencies must be separate from the rest of base.
   "-i18n",
diff --git a/base/allocator/allocator_extension_thunks.target.darwin-arm.mk b/base/allocator/allocator_extension_thunks.target.darwin-arm.mk
index 37a79c4..8599452 100644
--- a/base/allocator/allocator_extension_thunks.target.darwin-arm.mk
+++ b/base/allocator/allocator_extension_thunks.target.darwin-arm.mk
@@ -40,7 +40,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -127,7 +126,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/allocator/allocator_extension_thunks.target.darwin-x86.mk b/base/allocator/allocator_extension_thunks.target.darwin-x86.mk
index f8ac07f..eab0b63 100644
--- a/base/allocator/allocator_extension_thunks.target.darwin-x86.mk
+++ b/base/allocator/allocator_extension_thunks.target.darwin-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/allocator/allocator_extension_thunks.target.darwin-x86_64.mk b/base/allocator/allocator_extension_thunks.target.darwin-x86_64.mk
index 780e341..3dbcf95 100644
--- a/base/allocator/allocator_extension_thunks.target.darwin-x86_64.mk
+++ b/base/allocator/allocator_extension_thunks.target.darwin-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/allocator/allocator_extension_thunks.target.linux-arm.mk b/base/allocator/allocator_extension_thunks.target.linux-arm.mk
index 37a79c4..8599452 100644
--- a/base/allocator/allocator_extension_thunks.target.linux-arm.mk
+++ b/base/allocator/allocator_extension_thunks.target.linux-arm.mk
@@ -40,7 +40,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -127,7 +126,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/allocator/allocator_extension_thunks.target.linux-x86.mk b/base/allocator/allocator_extension_thunks.target.linux-x86.mk
index f8ac07f..eab0b63 100644
--- a/base/allocator/allocator_extension_thunks.target.linux-x86.mk
+++ b/base/allocator/allocator_extension_thunks.target.linux-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/allocator/allocator_extension_thunks.target.linux-x86_64.mk b/base/allocator/allocator_extension_thunks.target.linux-x86_64.mk
index 780e341..3dbcf95 100644
--- a/base/allocator/allocator_extension_thunks.target.linux-x86_64.mk
+++ b/base/allocator/allocator_extension_thunks.target.linux-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/android/jni_array.cc b/base/android/jni_array.cc
index 96c5980..6c7ac5b 100644
--- a/base/android/jni_array.cc
+++ b/base/android/jni_array.cc
@@ -189,12 +189,13 @@
   jsize len = env->GetArrayLength(array);
   out->resize(len);
   for (jsize i = 0; i < len; ++i) {
-    jbyteArray bytes_array = static_cast<jbyteArray>(
-        env->GetObjectArrayElement(array, i));
-    jsize bytes_len = env->GetArrayLength(bytes_array);
-    jbyte* bytes = env->GetByteArrayElements(bytes_array, NULL);
+    ScopedJavaLocalRef<jbyteArray> bytes_array(
+        env, static_cast<jbyteArray>(
+            env->GetObjectArrayElement(array, i)));
+    jsize bytes_len = env->GetArrayLength(bytes_array.obj());
+    jbyte* bytes = env->GetByteArrayElements(bytes_array.obj(), NULL);
     (*out)[i].assign(reinterpret_cast<const char*>(bytes), bytes_len);
-    env->ReleaseByteArrayElements(bytes_array, bytes, JNI_ABORT);
+    env->ReleaseByteArrayElements(bytes_array.obj(), bytes, JNI_ABORT);
   }
 }
 
diff --git a/base/android/jni_generator/android_jar.classes b/base/android/jni_generator/android_jar.classes
new file mode 100644
index 0000000..7d412ce
--- /dev/null
+++ b/base/android/jni_generator/android_jar.classes
@@ -0,0 +1,98 @@
+java/lang/AbstractMethodError.class
+java/lang/AbstractStringBuilder.class
+java/lang/Appendable.class
+java/lang/ArithmeticException.class
+java/lang/ArrayIndexOutOfBoundsException.class
+java/lang/ArrayStoreException.class
+java/lang/AssertionError.class
+java/lang/AutoCloseable.class
+java/lang/Boolean.class
+java/lang/Byte.class
+java/lang/Character.class
+java/lang/Character$Subset.class
+java/lang/Character$UnicodeBlock.class
+java/lang/CharSequence.class
+java/lang/ClassCastException.class
+java/lang/ClassCircularityError.class
+java/lang/Class.class
+java/lang/ClassFormatError.class
+java/lang/ClassLoader.class
+java/lang/ClassNotFoundException.class
+java/lang/Cloneable.class
+java/lang/CloneNotSupportedException.class
+java/lang/Comparable.class
+java/lang/Compiler.class
+java/lang/Deprecated.class
+java/lang/Double.class
+java/lang/Enum.class
+java/lang/EnumConstantNotPresentException.class
+java/lang/Error.class
+java/lang/Exception.class
+java/lang/ExceptionInInitializerError.class
+java/lang/Float.class
+java/lang/IllegalAccessError.class
+java/lang/IllegalAccessException.class
+java/lang/IllegalArgumentException.class
+java/lang/IllegalMonitorStateException.class
+java/lang/IllegalStateException.class
+java/lang/IncompatibleClassChangeError.class
+java/lang/IndexOutOfBoundsException.class
+java/lang/InheritableThreadLocal.class
+java/lang/InstantiationError.class
+java/lang/InstantiationException.class
+java/lang/Integer.class
+java/lang/InternalError.class
+java/lang/InterruptedException.class
+java/lang/Iterable.class
+java/lang/LinkageError.class
+java/lang/Long.class
+java/lang/Math.class
+java/lang/NegativeArraySizeException.class
+java/lang/NoClassDefFoundError.class
+java/lang/NoSuchFieldError.class
+java/lang/NoSuchFieldException.class
+java/lang/NoSuchMethodError.class
+java/lang/NoSuchMethodException.class
+java/lang/NullPointerException.class
+java/lang/Number.class
+java/lang/NumberFormatException.class
+java/lang/Object.class
+java/lang/OutOfMemoryError.class
+java/lang/Override.class
+java/lang/Package.class
+java/lang/ProcessBuilder.class
+java/lang/Process.class
+java/lang/Readable.class
+java/lang/ReflectiveOperationException.class
+java/lang/Runnable.class
+java/lang/Runtime.class
+java/lang/RuntimeException.class
+java/lang/RuntimePermission.class
+java/lang/SafeVarargs.class
+java/lang/SecurityException.class
+java/lang/SecurityManager.class
+java/lang/Short.class
+java/lang/StackOverflowError.class
+java/lang/StackTraceElement.class
+java/lang/StrictMath.class
+java/lang/StringBuffer.class
+java/lang/StringBuilder.class
+java/lang/String.class
+java/lang/StringIndexOutOfBoundsException.class
+java/lang/SuppressWarnings.class
+java/lang/System.class
+java/lang/Thread.class
+java/lang/ThreadDeath.class
+java/lang/ThreadGroup.class
+java/lang/ThreadLocal.class
+java/lang/Thread$State.class
+java/lang/Thread$UncaughtExceptionHandler.class
+java/lang/Throwable.class
+java/lang/TypeNotPresentException.class
+java/lang/UnknownError.class
+java/lang/UnsatisfiedLinkError.class
+java/lang/UnsupportedClassVersionError.class
+java/lang/UnsupportedOperationException.class
+java/lang/VerifyError.class
+java/lang/VirtualMachineError.class
+java/lang/Void.class
diff --git a/base/android/jni_generator/golden_sample_for_tests_jni.h b/base/android/jni_generator/golden_sample_for_tests_jni.h
index b90bb9f..7dbf71e 100644
--- a/base/android/jni_generator/golden_sample_for_tests_jni.h
+++ b/base/android/jni_generator/golden_sample_for_tests_jni.h
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kInnerStructAClassPath[] =
@@ -92,8 +94,9 @@
 }
 
 static base::subtle::AtomicWord g_SampleForTests_javaMethod = 0;
-static jint Java_SampleForTests_javaMethod(JNIEnv* env, jobject obj, jint foo,
-    jint bar) {
+static jint Java_SampleForTests_javaMethod(JNIEnv* env, jobject obj,
+    JniIntWrapper foo,
+    JniIntWrapper bar) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_SampleForTests_clazz, 0);
@@ -112,7 +115,7 @@
 
   jint ret =
       env->CallIntMethod(obj,
-          method_id, foo, bar);
+          method_id, as_jint(foo), as_jint(bar));
   jni_generator::CheckException(env);
   return ret;
 }
@@ -188,7 +191,7 @@
 static base::subtle::AtomicWord g_InnerStructA_create = 0;
 static base::android::ScopedJavaLocalRef<jobject>
     Java_InnerStructA_create(JNIEnv* env, jlong l,
-    jint i,
+    JniIntWrapper i,
     jstring s) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, g_InnerStructA_clazz,
@@ -209,7 +212,7 @@
 
   jobject ret =
       env->CallStaticObjectMethod(g_InnerStructA_clazz,
-          method_id, l, i, s);
+          method_id, l, as_jint(i), s);
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
 }
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 885a6c3..df8b80f 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
@@ -71,6 +71,21 @@
 // directly call methods on the other side. It's much simpler than trying to amalgamate
 // java and stl containers.
 //
+// An important note about qualified class name resolution:
+// The generator doesn't compile the class and have little context about the
+// classes being passed through the JNI layers. It adds a few simple rules:
+//
+// - all classes are either explicitly imported, or they are assumed to be in
+// the same package.
+//
+// - Inner class needs to be done through an import and usage of the
+// outer class, so that the generator knows how to qualify it:
+// import foo.bar.Zoo;
+// void call(Zoo.Inner);
+//
+// - implicitly imported classes aren't supported, so in order to pass
+// things like Runnable, please import java.lang.Runnable;
+//
 // This JNINamespace annotation indicates that all native methods should be
 // generated inside this namespace, including the native class that this
 // object binds to.
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py
index 9984c2a..32d09f1 100755
--- a/base/android/jni_generator/jni_generator.py
+++ b/base/android/jni_generator/jni_generator.py
@@ -124,6 +124,14 @@
     return 'jobject'
 
 
+def JavaDataTypeToCForCalledByNativeParam(java_type):
+  """Returns a C datatype to be when calling from native."""
+  if java_type == 'int':
+    return 'JniIntWrapper'
+  else:
+    return JavaDataTypeToC(java_type)
+
+
 def JavaReturnValueToC(java_type):
   """Returns a valid C return value for the given java type."""
   java_pod_type_map = {
@@ -146,6 +154,7 @@
   _package = ''
   _inner_classes = []
   _remappings = []
+  _implicit_imports = []
 
   @staticmethod
   def SetFullyQualifiedClass(fully_qualified_class):
@@ -193,6 +202,7 @@
         'Ljava/lang/String',
         'Ljava/lang/Class',
     ]
+
     prefix = ''
     # Array?
     while param[-2:] == '[]':
@@ -246,11 +256,33 @@
                         (param, JniParams._package.replace('/', '.'),
                          outer.replace('/', '.')))
 
+    JniParams._CheckImplicitImports(param)
+
     # Type not found, falling back to same package as this class.
     return (prefix + 'L' +
             JniParams.RemapClassName(JniParams._package + '/' + param) + ';')
 
   @staticmethod
+  def _CheckImplicitImports(param):
+    # Ensure implicit imports, such as java.lang.*, are not being treated
+    # as being in the same package.
+    if not JniParams._implicit_imports:
+      # This file was generated from android.jar and lists
+      # all classes that are implicitly imported.
+      with file(os.path.join(os.path.dirname(sys.argv[0]),
+                             'android_jar.classes'), 'r') as f:
+        JniParams._implicit_imports = f.readlines()
+    for implicit_import in JniParams._implicit_imports:
+      implicit_import = implicit_import.strip().replace('.class', '')
+      implicit_import = implicit_import.replace('/', '.')
+      if implicit_import.endswith('.' + param):
+        raise SyntaxError('Ambiguous class (%s) can not be used directly '
+                          'by JNI.\nPlease import it, probably:\n\n'
+                          'import %s;' %
+                          (param, implicit_import))
+
+
+  @staticmethod
   def Signature(params, returns, wrap):
     """Returns the JNI signature for the given datatypes."""
     items = ['(']
@@ -672,6 +704,8 @@
 
 ${INCLUDES}
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 $CLASS_PATH_DEFINITIONS
@@ -932,9 +966,10 @@
                            for param in native.params])
 
   def GetCalledByNativeParamsInDeclaration(self, called_by_native):
-    return ',\n    '.join([JavaDataTypeToC(param.datatype) + ' ' +
-                           param.name
-                           for param in called_by_native.params])
+    return ',\n    '.join([
+        JavaDataTypeToCForCalledByNativeParam(param.datatype) + ' ' +
+        param.name
+        for param in called_by_native.params])
 
   def GetForwardDeclaration(self, native):
     template = Template("""
@@ -978,6 +1013,14 @@
     }
     return template.substitute(values)
 
+  def GetArgument(self, param):
+    return ('as_jint(' + param.name + ')'
+            if param.datatype == 'int' else param.name)
+
+  def GetArgumentsInCall(self, params):
+    """Return a string of arguments to call from native into Java"""
+    return [self.GetArgument(p) for p in params]
+
   def GetCalledByNativeValues(self, called_by_native):
     """Fills in necessary values for the CalledByNative methods."""
     if called_by_native.static or called_by_native.is_constructor:
@@ -992,7 +1035,7 @@
         called_by_native)
     if params_in_declaration:
       params_in_declaration = ', ' + params_in_declaration
-    params_in_call = ', '.join(param.name for param in called_by_native.params)
+    params_in_call = ', '.join(self.GetArgumentsInCall(called_by_native.params))
     if params_in_call:
       params_in_call = ', ' + params_in_call
     pre_call = ''
diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py
index 61d76c8..9e586f9 100755
--- a/base/android/jni_generator/jni_generator_tests.py
+++ b/base/android/jni_generator/jni_generator_tests.py
@@ -1010,6 +1010,29 @@
           TestOptions())
     self.assertRaises(SyntaxError, willRaise)
 
+  def testImplicitImport(self):
+    test_data = """
+    package org.chromium.android_webview;
+
+    %(IMPORT)s
+
+    @CalledByNative
+    private static void clientCertificatesCleared(Runnable callback) {
+        if (callbaback == null) return;
+        callback.run();
+    }
+    """
+    def generate(import_clause):
+      jni_generator.JNIFromJavaSource(
+          test_data % {'IMPORT': import_clause},
+          'org/chromium/android_webview/AwContentStatics',
+          TestOptions())
+    # Ensure it raises without the import.
+    self.assertRaises(SyntaxError, lambda: generate(''))
+
+    # Ensure it's fine with the import.
+    generate('import java.lang.Runnable;')
+
 
 if __name__ == '__main__':
   unittest.main()
diff --git a/base/android/jni_generator/testCalledByNatives.golden b/base/android/jni_generator/testCalledByNatives.golden
index 854275c..abdc507 100644
--- a/base/android/jni_generator/testCalledByNatives.golden
+++ b/base/android/jni_generator/testCalledByNatives.golden
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kTestJniClassPath[] = "org/chromium/TestJni";
@@ -29,7 +31,7 @@
 
 static base::subtle::AtomicWord g_TestJni_showConfirmInfoBar = 0;
 static base::android::ScopedJavaLocalRef<jobject>
-    Java_TestJni_showConfirmInfoBar(JNIEnv* env, jobject obj, jint
+    Java_TestJni_showConfirmInfoBar(JNIEnv* env, jobject obj, JniIntWrapper
     nativeInfoBar,
     jstring buttonOk,
     jstring buttonCancel,
@@ -56,14 +58,15 @@
 
   jobject ret =
       env->CallObjectMethod(obj,
-          method_id, nativeInfoBar, buttonOk, buttonCancel, title, icon);
+          method_id, as_jint(nativeInfoBar), buttonOk, buttonCancel, title,
+              icon);
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
 }
 
 static base::subtle::AtomicWord g_TestJni_showAutoLoginInfoBar = 0;
 static base::android::ScopedJavaLocalRef<jobject>
-    Java_TestJni_showAutoLoginInfoBar(JNIEnv* env, jobject obj, jint
+    Java_TestJni_showAutoLoginInfoBar(JNIEnv* env, jobject obj, JniIntWrapper
     nativeInfoBar,
     jstring realm,
     jstring account,
@@ -88,7 +91,7 @@
 
   jobject ret =
       env->CallObjectMethod(obj,
-          method_id, nativeInfoBar, realm, account, args);
+          method_id, as_jint(nativeInfoBar), realm, account, args);
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
 }
@@ -173,10 +176,10 @@
 static base::subtle::AtomicWord g_TestJni_activateHardwareAcceleration = 0;
 static void Java_TestJni_activateHardwareAcceleration(JNIEnv* env, jobject obj,
     jboolean activated,
-    jint iPid,
-    jint iType,
-    jint iPrimaryID,
-    jint iSecondaryID) {
+    JniIntWrapper iPid,
+    JniIntWrapper iType,
+    JniIntWrapper iPrimaryID,
+    JniIntWrapper iSecondaryID) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_TestJni_clazz);
@@ -197,13 +200,15 @@
       &g_TestJni_activateHardwareAcceleration);
 
      env->CallVoidMethod(obj,
-          method_id, activated, iPid, iType, iPrimaryID, iSecondaryID);
+          method_id, activated, as_jint(iPid), as_jint(iType),
+              as_jint(iPrimaryID), as_jint(iSecondaryID));
   jni_generator::CheckException(env);
 
 }
 
 static base::subtle::AtomicWord g_TestJni_uncheckedCall = 0;
-static void Java_TestJni_uncheckedCall(JNIEnv* env, jobject obj, jint iParam) {
+static void Java_TestJni_uncheckedCall(JNIEnv* env, jobject obj, JniIntWrapper
+    iParam) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_TestJni_clazz);
@@ -220,7 +225,7 @@
       &g_TestJni_uncheckedCall);
 
      env->CallVoidMethod(obj,
-          method_id, iParam);
+          method_id, as_jint(iParam));
 
 }
 
diff --git a/base/android/jni_generator/testConstantsFromJavaP.golden b/base/android/jni_generator/testConstantsFromJavaP.golden
index 2465c52..795bd54 100644
--- a/base/android/jni_generator/testConstantsFromJavaP.golden
+++ b/base/android/jni_generator/testConstantsFromJavaP.golden
@@ -1,4 +1,4 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
 
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kMotionEventClassPath[] = "android/view/MotionEvent";
@@ -136,34 +138,34 @@
     Java_MotionEvent_obtainAVME_J_J_I_I_LAVMEPP_LAVMEPC_I_I_F_F_I_I_I_I(JNIEnv*
     env, jlong p0,
     jlong p1,
-    jint p2,
-    jint p3,
+    JniIntWrapper p2,
+    JniIntWrapper p3,
     jobjectArray p4,
     jobjectArray p5,
-    jint p6,
-    jint p7,
+    JniIntWrapper p6,
+    JniIntWrapper p7,
     jfloat p8,
     jfloat p9,
-    jint p10,
-    jint p11,
-    jint p12,
-    jint p13) __attribute__ ((unused));
+    JniIntWrapper p10,
+    JniIntWrapper p11,
+    JniIntWrapper p12,
+    JniIntWrapper p13) __attribute__ ((unused));
 static base::android::ScopedJavaLocalRef<jobject>
     Java_MotionEvent_obtainAVME_J_J_I_I_LAVMEPP_LAVMEPC_I_I_F_F_I_I_I_I(JNIEnv*
     env, jlong p0,
     jlong p1,
-    jint p2,
-    jint p3,
+    JniIntWrapper p2,
+    JniIntWrapper p3,
     jobjectArray p4,
     jobjectArray p5,
-    jint p6,
-    jint p7,
+    JniIntWrapper p6,
+    JniIntWrapper p7,
     jfloat p8,
     jfloat p9,
-    jint p10,
-    jint p11,
-    jint p12,
-    jint p13) {
+    JniIntWrapper p10,
+    JniIntWrapper p11,
+    JniIntWrapper p12,
+    JniIntWrapper p13) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, g_MotionEvent_clazz,
       g_MotionEvent_clazz, NULL);
@@ -177,8 +179,9 @@
 
   jobject ret =
       env->CallStaticObjectMethod(g_MotionEvent_clazz,
-          method_id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12,
-              p13);
+          method_id, p0, p1, as_jint(p2), as_jint(p3), p4, p5, as_jint(p6),
+              as_jint(p7), p8, p9, as_jint(p10), as_jint(p11), as_jint(p12),
+              as_jint(p13));
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
 }
@@ -189,32 +192,32 @@
     Java_MotionEvent_obtainAVME_J_J_I_I_AI_LAVMEPC_I_F_F_I_I_I_I(JNIEnv* env,
     jlong p0,
     jlong p1,
-    jint p2,
-    jint p3,
+    JniIntWrapper p2,
+    JniIntWrapper p3,
     jintArray p4,
     jobjectArray p5,
-    jint p6,
+    JniIntWrapper p6,
     jfloat p7,
     jfloat p8,
-    jint p9,
-    jint p10,
-    jint p11,
-    jint p12) __attribute__ ((unused));
+    JniIntWrapper p9,
+    JniIntWrapper p10,
+    JniIntWrapper p11,
+    JniIntWrapper p12) __attribute__ ((unused));
 static base::android::ScopedJavaLocalRef<jobject>
     Java_MotionEvent_obtainAVME_J_J_I_I_AI_LAVMEPC_I_F_F_I_I_I_I(JNIEnv* env,
     jlong p0,
     jlong p1,
-    jint p2,
-    jint p3,
+    JniIntWrapper p2,
+    JniIntWrapper p3,
     jintArray p4,
     jobjectArray p5,
-    jint p6,
+    JniIntWrapper p6,
     jfloat p7,
     jfloat p8,
-    jint p9,
-    jint p10,
-    jint p11,
-    jint p12) {
+    JniIntWrapper p9,
+    JniIntWrapper p10,
+    JniIntWrapper p11,
+    JniIntWrapper p12) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, g_MotionEvent_clazz,
       g_MotionEvent_clazz, NULL);
@@ -228,7 +231,8 @@
 
   jobject ret =
       env->CallStaticObjectMethod(g_MotionEvent_clazz,
-          method_id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
+          method_id, p0, p1, as_jint(p2), as_jint(p3), p4, p5, as_jint(p6), p7,
+              p8, as_jint(p9), as_jint(p10), as_jint(p11), as_jint(p12));
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
 }
@@ -238,29 +242,29 @@
 static base::android::ScopedJavaLocalRef<jobject>
     Java_MotionEvent_obtainAVME_J_J_I_F_F_F_F_I_F_F_I_I(JNIEnv* env, jlong p0,
     jlong p1,
-    jint p2,
+    JniIntWrapper p2,
     jfloat p3,
     jfloat p4,
     jfloat p5,
     jfloat p6,
-    jint p7,
+    JniIntWrapper p7,
     jfloat p8,
     jfloat p9,
-    jint p10,
-    jint p11) __attribute__ ((unused));
+    JniIntWrapper p10,
+    JniIntWrapper p11) __attribute__ ((unused));
 static base::android::ScopedJavaLocalRef<jobject>
     Java_MotionEvent_obtainAVME_J_J_I_F_F_F_F_I_F_F_I_I(JNIEnv* env, jlong p0,
     jlong p1,
-    jint p2,
+    JniIntWrapper p2,
     jfloat p3,
     jfloat p4,
     jfloat p5,
     jfloat p6,
-    jint p7,
+    JniIntWrapper p7,
     jfloat p8,
     jfloat p9,
-    jint p10,
-    jint p11) {
+    JniIntWrapper p10,
+    JniIntWrapper p11) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, g_MotionEvent_clazz,
       g_MotionEvent_clazz, NULL);
@@ -274,7 +278,8 @@
 
   jobject ret =
       env->CallStaticObjectMethod(g_MotionEvent_clazz,
-          method_id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
+          method_id, p0, p1, as_jint(p2), p3, p4, p5, p6, as_jint(p7), p8, p9,
+              as_jint(p10), as_jint(p11));
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
 }
@@ -284,31 +289,31 @@
 static base::android::ScopedJavaLocalRef<jobject>
     Java_MotionEvent_obtainAVME_J_J_I_I_F_F_F_F_I_F_F_I_I(JNIEnv* env, jlong p0,
     jlong p1,
-    jint p2,
-    jint p3,
+    JniIntWrapper p2,
+    JniIntWrapper p3,
     jfloat p4,
     jfloat p5,
     jfloat p6,
     jfloat p7,
-    jint p8,
+    JniIntWrapper p8,
     jfloat p9,
     jfloat p10,
-    jint p11,
-    jint p12) __attribute__ ((unused));
+    JniIntWrapper p11,
+    JniIntWrapper p12) __attribute__ ((unused));
 static base::android::ScopedJavaLocalRef<jobject>
     Java_MotionEvent_obtainAVME_J_J_I_I_F_F_F_F_I_F_F_I_I(JNIEnv* env, jlong p0,
     jlong p1,
-    jint p2,
-    jint p3,
+    JniIntWrapper p2,
+    JniIntWrapper p3,
     jfloat p4,
     jfloat p5,
     jfloat p6,
     jfloat p7,
-    jint p8,
+    JniIntWrapper p8,
     jfloat p9,
     jfloat p10,
-    jint p11,
-    jint p12) {
+    JniIntWrapper p11,
+    JniIntWrapper p12) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, g_MotionEvent_clazz,
       g_MotionEvent_clazz, NULL);
@@ -322,7 +327,8 @@
 
   jobject ret =
       env->CallStaticObjectMethod(g_MotionEvent_clazz,
-          method_id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
+          method_id, p0, p1, as_jint(p2), as_jint(p3), p4, p5, p6, p7,
+              as_jint(p8), p9, p10, as_jint(p11), as_jint(p12));
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
 }
@@ -331,17 +337,17 @@
 static base::android::ScopedJavaLocalRef<jobject>
     Java_MotionEvent_obtainAVME_J_J_I_F_F_I(JNIEnv* env, jlong p0,
     jlong p1,
-    jint p2,
+    JniIntWrapper p2,
     jfloat p3,
     jfloat p4,
-    jint p5) __attribute__ ((unused));
+    JniIntWrapper p5) __attribute__ ((unused));
 static base::android::ScopedJavaLocalRef<jobject>
     Java_MotionEvent_obtainAVME_J_J_I_F_F_I(JNIEnv* env, jlong p0,
     jlong p1,
-    jint p2,
+    JniIntWrapper p2,
     jfloat p3,
     jfloat p4,
-    jint p5) {
+    JniIntWrapper p5) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, g_MotionEvent_clazz,
       g_MotionEvent_clazz, NULL);
@@ -355,7 +361,7 @@
 
   jobject ret =
       env->CallStaticObjectMethod(g_MotionEvent_clazz,
-          method_id, p0, p1, p2, p3, p4, p5);
+          method_id, p0, p1, as_jint(p2), p3, p4, as_jint(p5));
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
 }
@@ -474,9 +480,10 @@
 }
 
 static base::subtle::AtomicWord g_MotionEvent_setSource = 0;
-static void Java_MotionEvent_setSource(JNIEnv* env, jobject obj, jint p0)
-    __attribute__ ((unused));
-static void Java_MotionEvent_setSource(JNIEnv* env, jobject obj, jint p0) {
+static void Java_MotionEvent_setSource(JNIEnv* env, jobject obj, JniIntWrapper
+    p0) __attribute__ ((unused));
+static void Java_MotionEvent_setSource(JNIEnv* env, jobject obj, JniIntWrapper
+    p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz);
@@ -489,7 +496,7 @@
       &g_MotionEvent_setSource);
 
      env->CallVoidMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
 
 }
@@ -825,10 +832,10 @@
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getAxisValueF_I = 0;
-static jfloat Java_MotionEvent_getAxisValueF_I(JNIEnv* env, jobject obj, jint
-    p0) __attribute__ ((unused));
-static jfloat Java_MotionEvent_getAxisValueF_I(JNIEnv* env, jobject obj, jint
-    p0) {
+static jfloat Java_MotionEvent_getAxisValueF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getAxisValueF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -842,7 +849,7 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
@@ -870,9 +877,10 @@
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getPointerId = 0;
-static jint Java_MotionEvent_getPointerId(JNIEnv* env, jobject obj, jint p0)
-    __attribute__ ((unused));
-static jint Java_MotionEvent_getPointerId(JNIEnv* env, jobject obj, jint p0) {
+static jint Java_MotionEvent_getPointerId(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jint Java_MotionEvent_getPointerId(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -886,15 +894,16 @@
 
   jint ret =
       env->CallIntMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getToolType = 0;
-static jint Java_MotionEvent_getToolType(JNIEnv* env, jobject obj, jint p0)
-    __attribute__ ((unused));
-static jint Java_MotionEvent_getToolType(JNIEnv* env, jobject obj, jint p0) {
+static jint Java_MotionEvent_getToolType(JNIEnv* env, jobject obj, JniIntWrapper
+    p0) __attribute__ ((unused));
+static jint Java_MotionEvent_getToolType(JNIEnv* env, jobject obj, JniIntWrapper
+    p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -908,16 +917,16 @@
 
   jint ret =
       env->CallIntMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_findPointerIndex = 0;
-static jint Java_MotionEvent_findPointerIndex(JNIEnv* env, jobject obj, jint p0)
-    __attribute__ ((unused));
-static jint Java_MotionEvent_findPointerIndex(JNIEnv* env, jobject obj, jint p0)
-    {
+static jint Java_MotionEvent_findPointerIndex(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jint Java_MotionEvent_findPointerIndex(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -931,15 +940,16 @@
 
   jint ret =
       env->CallIntMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getXF_I = 0;
-static jfloat Java_MotionEvent_getXF_I(JNIEnv* env, jobject obj, jint p0)
-    __attribute__ ((unused));
-static jfloat Java_MotionEvent_getXF_I(JNIEnv* env, jobject obj, jint p0) {
+static jfloat Java_MotionEvent_getXF_I(JNIEnv* env, jobject obj, JniIntWrapper
+    p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getXF_I(JNIEnv* env, jobject obj, JniIntWrapper
+    p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -953,15 +963,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getYF_I = 0;
-static jfloat Java_MotionEvent_getYF_I(JNIEnv* env, jobject obj, jint p0)
-    __attribute__ ((unused));
-static jfloat Java_MotionEvent_getYF_I(JNIEnv* env, jobject obj, jint p0) {
+static jfloat Java_MotionEvent_getYF_I(JNIEnv* env, jobject obj, JniIntWrapper
+    p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getYF_I(JNIEnv* env, jobject obj, JniIntWrapper
+    p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -975,16 +986,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getPressureF_I = 0;
-static jfloat Java_MotionEvent_getPressureF_I(JNIEnv* env, jobject obj, jint p0)
-    __attribute__ ((unused));
-static jfloat Java_MotionEvent_getPressureF_I(JNIEnv* env, jobject obj, jint p0)
-    {
+static jfloat Java_MotionEvent_getPressureF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getPressureF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -998,15 +1009,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getSizeF_I = 0;
-static jfloat Java_MotionEvent_getSizeF_I(JNIEnv* env, jobject obj, jint p0)
-    __attribute__ ((unused));
-static jfloat Java_MotionEvent_getSizeF_I(JNIEnv* env, jobject obj, jint p0) {
+static jfloat Java_MotionEvent_getSizeF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getSizeF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1020,16 +1032,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getTouchMajorF_I = 0;
-static jfloat Java_MotionEvent_getTouchMajorF_I(JNIEnv* env, jobject obj, jint
-    p0) __attribute__ ((unused));
-static jfloat Java_MotionEvent_getTouchMajorF_I(JNIEnv* env, jobject obj, jint
-    p0) {
+static jfloat Java_MotionEvent_getTouchMajorF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getTouchMajorF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1043,16 +1055,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getTouchMinorF_I = 0;
-static jfloat Java_MotionEvent_getTouchMinorF_I(JNIEnv* env, jobject obj, jint
-    p0) __attribute__ ((unused));
-static jfloat Java_MotionEvent_getTouchMinorF_I(JNIEnv* env, jobject obj, jint
-    p0) {
+static jfloat Java_MotionEvent_getTouchMinorF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getTouchMinorF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1066,16 +1078,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getToolMajorF_I = 0;
-static jfloat Java_MotionEvent_getToolMajorF_I(JNIEnv* env, jobject obj, jint
-    p0) __attribute__ ((unused));
-static jfloat Java_MotionEvent_getToolMajorF_I(JNIEnv* env, jobject obj, jint
-    p0) {
+static jfloat Java_MotionEvent_getToolMajorF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getToolMajorF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1089,16 +1101,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getToolMinorF_I = 0;
-static jfloat Java_MotionEvent_getToolMinorF_I(JNIEnv* env, jobject obj, jint
-    p0) __attribute__ ((unused));
-static jfloat Java_MotionEvent_getToolMinorF_I(JNIEnv* env, jobject obj, jint
-    p0) {
+static jfloat Java_MotionEvent_getToolMinorF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getToolMinorF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1112,16 +1124,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getOrientationF_I = 0;
-static jfloat Java_MotionEvent_getOrientationF_I(JNIEnv* env, jobject obj, jint
-    p0) __attribute__ ((unused));
-static jfloat Java_MotionEvent_getOrientationF_I(JNIEnv* env, jobject obj, jint
-    p0) {
+static jfloat Java_MotionEvent_getOrientationF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getOrientationF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1135,18 +1147,18 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getAxisValueF_I_I = 0;
-static jfloat Java_MotionEvent_getAxisValueF_I_I(JNIEnv* env, jobject obj, jint
-    p0,
-    jint p1) __attribute__ ((unused));
-static jfloat Java_MotionEvent_getAxisValueF_I_I(JNIEnv* env, jobject obj, jint
-    p0,
-    jint p1) {
+static jfloat Java_MotionEvent_getAxisValueF_I_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0,
+    JniIntWrapper p1) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getAxisValueF_I_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0,
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1160,15 +1172,17 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), as_jint(p1));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getPointerCoords = 0;
-static void Java_MotionEvent_getPointerCoords(JNIEnv* env, jobject obj, jint p0,
+static void Java_MotionEvent_getPointerCoords(JNIEnv* env, jobject obj,
+    JniIntWrapper p0,
     jobject p1) __attribute__ ((unused));
-static void Java_MotionEvent_getPointerCoords(JNIEnv* env, jobject obj, jint p0,
+static void Java_MotionEvent_getPointerCoords(JNIEnv* env, jobject obj,
+    JniIntWrapper p0,
     jobject p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
@@ -1182,17 +1196,17 @@
       &g_MotionEvent_getPointerCoords);
 
      env->CallVoidMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), p1);
   jni_generator::CheckException(env);
 
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getPointerProperties = 0;
-static void Java_MotionEvent_getPointerProperties(JNIEnv* env, jobject obj, jint
-    p0,
+static void Java_MotionEvent_getPointerProperties(JNIEnv* env, jobject obj,
+    JniIntWrapper p0,
     jobject p1) __attribute__ ((unused));
-static void Java_MotionEvent_getPointerProperties(JNIEnv* env, jobject obj, jint
-    p0,
+static void Java_MotionEvent_getPointerProperties(JNIEnv* env, jobject obj,
+    JniIntWrapper p0,
     jobject p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
@@ -1206,7 +1220,7 @@
       &g_MotionEvent_getPointerProperties);
 
      env->CallVoidMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), p1);
   jni_generator::CheckException(env);
 
 }
@@ -1367,9 +1381,9 @@
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalEventTime = 0;
 static jlong Java_MotionEvent_getHistoricalEventTime(JNIEnv* env, jobject obj,
-    jint p0) __attribute__ ((unused));
+    JniIntWrapper p0) __attribute__ ((unused));
 static jlong Java_MotionEvent_getHistoricalEventTime(JNIEnv* env, jobject obj,
-    jint p0) {
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1383,16 +1397,16 @@
 
   jlong ret =
       env->CallLongMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalXF_I = 0;
-static jfloat Java_MotionEvent_getHistoricalXF_I(JNIEnv* env, jobject obj, jint
-    p0) __attribute__ ((unused));
-static jfloat Java_MotionEvent_getHistoricalXF_I(JNIEnv* env, jobject obj, jint
-    p0) {
+static jfloat Java_MotionEvent_getHistoricalXF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getHistoricalXF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1406,16 +1420,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalYF_I = 0;
-static jfloat Java_MotionEvent_getHistoricalYF_I(JNIEnv* env, jobject obj, jint
-    p0) __attribute__ ((unused));
-static jfloat Java_MotionEvent_getHistoricalYF_I(JNIEnv* env, jobject obj, jint
-    p0) {
+static jfloat Java_MotionEvent_getHistoricalYF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static jfloat Java_MotionEvent_getHistoricalYF_I(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1429,16 +1443,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalPressureF_I = 0;
 static jfloat Java_MotionEvent_getHistoricalPressureF_I(JNIEnv* env, jobject
-    obj, jint p0) __attribute__ ((unused));
+    obj, JniIntWrapper p0) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalPressureF_I(JNIEnv* env, jobject
-    obj, jint p0) {
+    obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1452,16 +1466,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalSizeF_I = 0;
 static jfloat Java_MotionEvent_getHistoricalSizeF_I(JNIEnv* env, jobject obj,
-    jint p0) __attribute__ ((unused));
+    JniIntWrapper p0) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalSizeF_I(JNIEnv* env, jobject obj,
-    jint p0) {
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1475,16 +1489,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalTouchMajorF_I = 0;
 static jfloat Java_MotionEvent_getHistoricalTouchMajorF_I(JNIEnv* env, jobject
-    obj, jint p0) __attribute__ ((unused));
+    obj, JniIntWrapper p0) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalTouchMajorF_I(JNIEnv* env, jobject
-    obj, jint p0) {
+    obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1498,16 +1512,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalTouchMinorF_I = 0;
 static jfloat Java_MotionEvent_getHistoricalTouchMinorF_I(JNIEnv* env, jobject
-    obj, jint p0) __attribute__ ((unused));
+    obj, JniIntWrapper p0) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalTouchMinorF_I(JNIEnv* env, jobject
-    obj, jint p0) {
+    obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1521,16 +1535,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalToolMajorF_I = 0;
 static jfloat Java_MotionEvent_getHistoricalToolMajorF_I(JNIEnv* env, jobject
-    obj, jint p0) __attribute__ ((unused));
+    obj, JniIntWrapper p0) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalToolMajorF_I(JNIEnv* env, jobject
-    obj, jint p0) {
+    obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1544,16 +1558,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalToolMinorF_I = 0;
 static jfloat Java_MotionEvent_getHistoricalToolMinorF_I(JNIEnv* env, jobject
-    obj, jint p0) __attribute__ ((unused));
+    obj, JniIntWrapper p0) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalToolMinorF_I(JNIEnv* env, jobject
-    obj, jint p0) {
+    obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1567,16 +1581,16 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalOrientationF_I = 0;
 static jfloat Java_MotionEvent_getHistoricalOrientationF_I(JNIEnv* env, jobject
-    obj, jint p0) __attribute__ ((unused));
+    obj, JniIntWrapper p0) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalOrientationF_I(JNIEnv* env, jobject
-    obj, jint p0) {
+    obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1590,18 +1604,18 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalAxisValueF_I_I = 0;
 static jfloat Java_MotionEvent_getHistoricalAxisValueF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) __attribute__ ((unused));
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalAxisValueF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) {
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1615,18 +1629,18 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), as_jint(p1));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalXF_I_I = 0;
 static jfloat Java_MotionEvent_getHistoricalXF_I_I(JNIEnv* env, jobject obj,
-    jint p0,
-    jint p1) __attribute__ ((unused));
+    JniIntWrapper p0,
+    JniIntWrapper p1) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalXF_I_I(JNIEnv* env, jobject obj,
-    jint p0,
-    jint p1) {
+    JniIntWrapper p0,
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1640,18 +1654,18 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), as_jint(p1));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalYF_I_I = 0;
 static jfloat Java_MotionEvent_getHistoricalYF_I_I(JNIEnv* env, jobject obj,
-    jint p0,
-    jint p1) __attribute__ ((unused));
+    JniIntWrapper p0,
+    JniIntWrapper p1) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalYF_I_I(JNIEnv* env, jobject obj,
-    jint p0,
-    jint p1) {
+    JniIntWrapper p0,
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1665,18 +1679,18 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), as_jint(p1));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalPressureF_I_I = 0;
 static jfloat Java_MotionEvent_getHistoricalPressureF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) __attribute__ ((unused));
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalPressureF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) {
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1690,18 +1704,18 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), as_jint(p1));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalSizeF_I_I = 0;
 static jfloat Java_MotionEvent_getHistoricalSizeF_I_I(JNIEnv* env, jobject obj,
-    jint p0,
-    jint p1) __attribute__ ((unused));
+    JniIntWrapper p0,
+    JniIntWrapper p1) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalSizeF_I_I(JNIEnv* env, jobject obj,
-    jint p0,
-    jint p1) {
+    JniIntWrapper p0,
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1715,18 +1729,18 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), as_jint(p1));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalTouchMajorF_I_I = 0;
 static jfloat Java_MotionEvent_getHistoricalTouchMajorF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) __attribute__ ((unused));
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalTouchMajorF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) {
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1740,18 +1754,18 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), as_jint(p1));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalTouchMinorF_I_I = 0;
 static jfloat Java_MotionEvent_getHistoricalTouchMinorF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) __attribute__ ((unused));
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalTouchMinorF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) {
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1765,18 +1779,18 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), as_jint(p1));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalToolMajorF_I_I = 0;
 static jfloat Java_MotionEvent_getHistoricalToolMajorF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) __attribute__ ((unused));
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalToolMajorF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) {
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1790,18 +1804,18 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), as_jint(p1));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalToolMinorF_I_I = 0;
 static jfloat Java_MotionEvent_getHistoricalToolMinorF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) __attribute__ ((unused));
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalToolMinorF_I_I(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1) {
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1815,18 +1829,18 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), as_jint(p1));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalOrientationF_I_I = 0;
 static jfloat Java_MotionEvent_getHistoricalOrientationF_I_I(JNIEnv* env,
-    jobject obj, jint p0,
-    jint p1) __attribute__ ((unused));
+    jobject obj, JniIntWrapper p0,
+    JniIntWrapper p1) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalOrientationF_I_I(JNIEnv* env,
-    jobject obj, jint p0,
-    jint p1) {
+    jobject obj, JniIntWrapper p0,
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1840,20 +1854,20 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1);
+          method_id, as_jint(p0), as_jint(p1));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalAxisValueF_I_I_I = 0;
 static jfloat Java_MotionEvent_getHistoricalAxisValueF_I_I_I(JNIEnv* env,
-    jobject obj, jint p0,
-    jint p1,
-    jint p2) __attribute__ ((unused));
+    jobject obj, JniIntWrapper p0,
+    JniIntWrapper p1,
+    JniIntWrapper p2) __attribute__ ((unused));
 static jfloat Java_MotionEvent_getHistoricalAxisValueF_I_I_I(JNIEnv* env,
-    jobject obj, jint p0,
-    jint p1,
-    jint p2) {
+    jobject obj, JniIntWrapper p0,
+    JniIntWrapper p1,
+    JniIntWrapper p2) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz, 0);
@@ -1867,19 +1881,19 @@
 
   jfloat ret =
       env->CallFloatMethod(obj,
-          method_id, p0, p1, p2);
+          method_id, as_jint(p0), as_jint(p1), as_jint(p2));
   jni_generator::CheckException(env);
   return ret;
 }
 
 static base::subtle::AtomicWord g_MotionEvent_getHistoricalPointerCoords = 0;
 static void Java_MotionEvent_getHistoricalPointerCoords(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1,
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1,
     jobject p2) __attribute__ ((unused));
 static void Java_MotionEvent_getHistoricalPointerCoords(JNIEnv* env, jobject
-    obj, jint p0,
-    jint p1,
+    obj, JniIntWrapper p0,
+    JniIntWrapper p1,
     jobject p2) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
@@ -1893,7 +1907,7 @@
       &g_MotionEvent_getHistoricalPointerCoords);
 
      env->CallVoidMethod(obj,
-          method_id, p0, p1, p2);
+          method_id, as_jint(p0), as_jint(p1), p2);
   jni_generator::CheckException(env);
 
 }
@@ -1921,9 +1935,10 @@
 }
 
 static base::subtle::AtomicWord g_MotionEvent_setEdgeFlags = 0;
-static void Java_MotionEvent_setEdgeFlags(JNIEnv* env, jobject obj, jint p0)
-    __attribute__ ((unused));
-static void Java_MotionEvent_setEdgeFlags(JNIEnv* env, jobject obj, jint p0) {
+static void Java_MotionEvent_setEdgeFlags(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) __attribute__ ((unused));
+static void Java_MotionEvent_setEdgeFlags(JNIEnv* env, jobject obj,
+    JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz);
@@ -1936,15 +1951,16 @@
       &g_MotionEvent_setEdgeFlags);
 
      env->CallVoidMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
 
 }
 
 static base::subtle::AtomicWord g_MotionEvent_setAction = 0;
-static void Java_MotionEvent_setAction(JNIEnv* env, jobject obj, jint p0)
-    __attribute__ ((unused));
-static void Java_MotionEvent_setAction(JNIEnv* env, jobject obj, jint p0) {
+static void Java_MotionEvent_setAction(JNIEnv* env, jobject obj, JniIntWrapper
+    p0) __attribute__ ((unused));
+static void Java_MotionEvent_setAction(JNIEnv* env, jobject obj, JniIntWrapper
+    p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz);
@@ -1957,7 +1973,7 @@
       &g_MotionEvent_setAction);
 
      env->CallVoidMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
 
 }
@@ -2034,14 +2050,14 @@
     jfloat p2,
     jfloat p3,
     jfloat p4,
-    jint p5) __attribute__ ((unused));
+    JniIntWrapper p5) __attribute__ ((unused));
 static void Java_MotionEvent_addBatchV_J_F_F_F_F_I(JNIEnv* env, jobject obj,
     jlong p0,
     jfloat p1,
     jfloat p2,
     jfloat p3,
     jfloat p4,
-    jint p5) {
+    JniIntWrapper p5) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz);
@@ -2054,7 +2070,7 @@
       &g_MotionEvent_addBatchV_J_F_F_F_F_I);
 
      env->CallVoidMethod(obj,
-          method_id, p0, p1, p2, p3, p4, p5);
+          method_id, p0, p1, p2, p3, p4, as_jint(p5));
   jni_generator::CheckException(env);
 
 }
@@ -2063,11 +2079,11 @@
 static void Java_MotionEvent_addBatchV_J_LAVMEPC_I(JNIEnv* env, jobject obj,
     jlong p0,
     jobjectArray p1,
-    jint p2) __attribute__ ((unused));
+    JniIntWrapper p2) __attribute__ ((unused));
 static void Java_MotionEvent_addBatchV_J_LAVMEPC_I(JNIEnv* env, jobject obj,
     jlong p0,
     jobjectArray p1,
-    jint p2) {
+    JniIntWrapper p2) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz);
@@ -2080,7 +2096,7 @@
       &g_MotionEvent_addBatchV_J_LAVMEPC_I);
 
      env->CallVoidMethod(obj,
-          method_id, p0, p1, p2);
+          method_id, p0, p1, as_jint(p2));
   jni_generator::CheckException(env);
 
 }
@@ -2111,10 +2127,10 @@
 
 static base::subtle::AtomicWord g_MotionEvent_actionToString = 0;
 static base::android::ScopedJavaLocalRef<jstring>
-    Java_MotionEvent_actionToString(JNIEnv* env, jint p0) __attribute__
+    Java_MotionEvent_actionToString(JNIEnv* env, JniIntWrapper p0) __attribute__
     ((unused));
 static base::android::ScopedJavaLocalRef<jstring>
-    Java_MotionEvent_actionToString(JNIEnv* env, jint p0) {
+    Java_MotionEvent_actionToString(JNIEnv* env, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, g_MotionEvent_clazz,
       g_MotionEvent_clazz, NULL);
@@ -2128,17 +2144,17 @@
 
   jstring ret =
       static_cast<jstring>(env->CallStaticObjectMethod(g_MotionEvent_clazz,
-          method_id, p0));
+          method_id, as_jint(p0)));
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jstring>(env, ret);
 }
 
 static base::subtle::AtomicWord g_MotionEvent_axisToString = 0;
 static base::android::ScopedJavaLocalRef<jstring>
-    Java_MotionEvent_axisToString(JNIEnv* env, jint p0) __attribute__
+    Java_MotionEvent_axisToString(JNIEnv* env, JniIntWrapper p0) __attribute__
     ((unused));
 static base::android::ScopedJavaLocalRef<jstring>
-    Java_MotionEvent_axisToString(JNIEnv* env, jint p0) {
+    Java_MotionEvent_axisToString(JNIEnv* env, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, g_MotionEvent_clazz,
       g_MotionEvent_clazz, NULL);
@@ -2152,7 +2168,7 @@
 
   jstring ret =
       static_cast<jstring>(env->CallStaticObjectMethod(g_MotionEvent_clazz,
-          method_id, p0));
+          method_id, as_jint(p0)));
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jstring>(env, ret);
 }
@@ -2181,9 +2197,9 @@
 
 static base::subtle::AtomicWord g_MotionEvent_writeToParcel = 0;
 static void Java_MotionEvent_writeToParcel(JNIEnv* env, jobject obj, jobject p0,
-    jint p1) __attribute__ ((unused));
+    JniIntWrapper p1) __attribute__ ((unused));
 static void Java_MotionEvent_writeToParcel(JNIEnv* env, jobject obj, jobject p0,
-    jint p1) {
+    JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_MotionEvent_clazz);
@@ -2196,7 +2212,7 @@
       &g_MotionEvent_writeToParcel);
 
      env->CallVoidMethod(obj,
-          method_id, p0, p1);
+          method_id, p0, as_jint(p1));
   jni_generator::CheckException(env);
 
 }
diff --git a/base/android/jni_generator/testEagerCalledByNativesOption.golden b/base/android/jni_generator/testEagerCalledByNativesOption.golden
index f57abee..4ff81ac 100644
--- a/base/android/jni_generator/testEagerCalledByNativesOption.golden
+++ b/base/android/jni_generator/testEagerCalledByNativesOption.golden
@@ -1,4 +1,4 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
 
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kTestClassPath[] = "org/chromium/example/jni_generator/Test";
@@ -36,15 +38,16 @@
 
 namespace {
 
-static void testMethodWithParam(JNIEnv* env, jobject obj, jint iParam) {
+static void testMethodWithParam(JNIEnv* env, jobject obj, JniIntWrapper iParam)
+    {
   env->CallVoidMethod(obj,
-      g_Test_testMethodWithParam, iParam);
+      g_Test_testMethodWithParam, as_jint(iParam));
 
 }
 
-static jint testStaticMethodWithParam(JNIEnv* env, jint iParam) {
+static jint testStaticMethodWithParam(JNIEnv* env, JniIntWrapper iParam) {
   jint ret = env->CallStaticIntMethod(g_Test_clazz,
-      g_Test_testStaticMethodWithParam, iParam);
+      g_Test_testStaticMethodWithParam, as_jint(iParam));
   return ret;
 }
 
diff --git a/base/android/jni_generator/testFromJavaP.golden b/base/android/jni_generator/testFromJavaP.golden
index d30acb1..34e2118 100644
--- a/base/android/jni_generator/testFromJavaP.golden
+++ b/base/android/jni_generator/testFromJavaP.golden
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kInputStreamClassPath[] = "java/io/InputStream";
@@ -70,9 +72,9 @@
 }
 
 static base::subtle::AtomicWord g_InputStream_mark = 0;
-static void Java_InputStream_mark(JNIEnv* env, jobject obj, jint p0)
+static void Java_InputStream_mark(JNIEnv* env, jobject obj, JniIntWrapper p0)
     __attribute__ ((unused));
-static void Java_InputStream_mark(JNIEnv* env, jobject obj, jint p0) {
+static void Java_InputStream_mark(JNIEnv* env, jobject obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_InputStream_clazz);
@@ -85,7 +87,7 @@
       &g_InputStream_mark);
 
      env->CallVoidMethod(obj,
-          method_id, p0);
+          method_id, as_jint(p0));
   jni_generator::CheckException(env);
 
 }
@@ -159,12 +161,12 @@
 static base::subtle::AtomicWord g_InputStream_readI_AB_I_I = 0;
 static jint Java_InputStream_readI_AB_I_I(JNIEnv* env, jobject obj, jbyteArray
     p0,
-    jint p1,
-    jint p2) __attribute__ ((unused));
+    JniIntWrapper p1,
+    JniIntWrapper p2) __attribute__ ((unused));
 static jint Java_InputStream_readI_AB_I_I(JNIEnv* env, jobject obj, jbyteArray
     p0,
-    jint p1,
-    jint p2) {
+    JniIntWrapper p1,
+    JniIntWrapper p2) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
       g_InputStream_clazz, 0);
@@ -178,7 +180,7 @@
 
   jint ret =
       env->CallIntMethod(obj,
-          method_id, p0, p1, p2);
+          method_id, p0, as_jint(p1), as_jint(p2));
   jni_generator::CheckException(env);
   return ret;
 }
diff --git a/base/android/jni_generator/testFromJavaPGenerics.golden b/base/android/jni_generator/testFromJavaPGenerics.golden
index 1ac340e..48582fd 100644
--- a/base/android/jni_generator/testFromJavaPGenerics.golden
+++ b/base/android/jni_generator/testFromJavaPGenerics.golden
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kHashSetClassPath[] = "java/util/HashSet";
diff --git a/base/android/jni_generator/testInnerClassNatives.golden b/base/android/jni_generator/testInnerClassNatives.golden
index 2bc2161..56a2e9b 100644
--- a/base/android/jni_generator/testInnerClassNatives.golden
+++ b/base/android/jni_generator/testInnerClassNatives.golden
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kTestJniClassPath[] = "org/chromium/TestJni";
diff --git a/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden b/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
index 6b85ea9..07b857f 100644
--- a/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
+++ b/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kMyOtherInnerClassClassPath[] =
diff --git a/base/android/jni_generator/testInnerClassNativesMultiple.golden b/base/android/jni_generator/testInnerClassNativesMultiple.golden
index 1341c89..6a7f04d 100644
--- a/base/android/jni_generator/testInnerClassNativesMultiple.golden
+++ b/base/android/jni_generator/testInnerClassNativesMultiple.golden
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kMyOtherInnerClassClassPath[] =
diff --git a/base/android/jni_generator/testJNIInitNativeNameOption.golden b/base/android/jni_generator/testJNIInitNativeNameOption.golden
index 54e7b28..0d5d3c6 100644
--- a/base/android/jni_generator/testJNIInitNativeNameOption.golden
+++ b/base/android/jni_generator/testJNIInitNativeNameOption.golden
@@ -1,4 +1,4 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
 
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kTestClassPath[] = "org/chromium/example/jni_generator/Test";
diff --git a/base/android/jni_generator/testJarJarRemapping.golden b/base/android/jni_generator/testJarJarRemapping.golden
index 26406e4..a4911d0 100644
--- a/base/android/jni_generator/testJarJarRemapping.golden
+++ b/base/android/jni_generator/testJarJarRemapping.golden
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kExampleClassPath[] = "com/test/jni_generator/Example";
diff --git a/base/android/jni_generator/testNatives.golden b/base/android/jni_generator/testNatives.golden
index de109e7..db69a5a 100644
--- a/base/android/jni_generator/testNatives.golden
+++ b/base/android/jni_generator/testNatives.golden
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kTestJniClassPath[] = "org/chromium/TestJni";
diff --git a/base/android/jni_generator/testNativesLong.golden b/base/android/jni_generator/testNativesLong.golden
index 24d4a15..25b5fad 100644
--- a/base/android/jni_generator/testNativesLong.golden
+++ b/base/android/jni_generator/testNativesLong.golden
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kTestJniClassPath[] = "org/chromium/TestJni";
diff --git a/base/android/jni_generator/testPureNativeMethodsOption.golden b/base/android/jni_generator/testPureNativeMethodsOption.golden
index e7f8d53..8d9ee9e 100644
--- a/base/android/jni_generator/testPureNativeMethodsOption.golden
+++ b/base/android/jni_generator/testPureNativeMethodsOption.golden
@@ -1,4 +1,4 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
 
@@ -14,6 +14,8 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 
+#include "base/android/jni_int_wrapper.h"
+
 // Step 1: forward declarations.
 namespace {
 const char kTestClassPath[] = "org/chromium/example/jni_generator/Test";
diff --git a/base/android/jni_int_wrapper.h b/base/android/jni_int_wrapper.h
new file mode 100644
index 0000000..fa0f3d5
--- /dev/null
+++ b/base/android/jni_int_wrapper.h
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef BASE_ANDROID_JNI_INT_WRAPPER_H_
+#define BASE_ANDROID_JNI_INT_WRAPPER_H_
+
+// Wrapper used to receive int when calling Java from native.
+// The wrapper disallows automatic conversion of long to int.
+// This is to avoid a common anti-pattern where a Java int is used
+// to receive a native pointer. Please use a Java long to receive
+// native pointers, so that the code works on both 32-bit and 64-bit
+// platforms. Note the wrapper allows other lossy conversions into
+// jint that could be consider anti-patterns, such as from size_t.
+
+// Checking is only done in debugging builds.
+
+#ifdef NDEBUG
+
+typedef jint JniIntWrapper;
+
+// This inline is sufficiently trivial that it does not change the
+// final code generated by g++.
+inline jint as_jint(JniIntWrapper wrapper) {
+  return wrapper;
+}
+
+#else
+
+class JniIntWrapper {
+ public:
+  JniIntWrapper() : i_(0) {}
+  JniIntWrapper(int i) : i_(i) {}
+  JniIntWrapper(const JniIntWrapper& ji) : i_(ji.i_) {}
+  template <class T> JniIntWrapper(const T& t) : i_(t) {}
+  jint as_jint() const { return i_; }
+ private:
+  // If you get an "is private" error at the line below it is because you used
+  // an implicit conversion to convert a long to an int when calling Java.
+  // We disallow this, as a common anti-pattern allows converting a native
+  // pointer (intptr_t) to a Java int. Please use a Java long to represent
+  // a native pointer. If you want a lossy conversion, please use an
+  // explicit conversion in your C++ code. Note an error is only seen when
+  // compiling on a 64-bit platform, as intptr_t is indistinguishable from
+  // int on 32-bit platforms.
+  JniIntWrapper(long);
+  jint i_;
+};
+
+inline jint as_jint(const JniIntWrapper& wrapper) {
+  return wrapper.as_jint();
+}
+
+#endif  // NDEBUG
+
+#endif  // BASE_ANDROID_JNI_INT_WRAPPER_H_
diff --git a/base/android/library_loader/library_loader_hooks.cc b/base/android/library_loader/library_loader_hooks.cc
index 0145eab..7947010 100644
--- a/base/android/library_loader/library_loader_hooks.cc
+++ b/base/android/library_loader/library_loader_hooks.cc
@@ -4,6 +4,7 @@
 
 #include "base/android/library_loader/library_loader_hooks.h"
 
+#include "base/android/jni_string.h"
 #include "base/at_exit.h"
 #include "base/metrics/histogram.h"
 #include "jni/LibraryLoader_jni.h"
@@ -61,7 +62,7 @@
 }
 
 jstring GetVersionNumber(JNIEnv* env, jclass clazz) {
-  return env->NewStringUTF(g_library_version_number);
+  return ConvertUTF8ToJavaString(env, g_library_version_number).Release();
 }
 
 static void RecordNativeLibraryHack(JNIEnv*, jclass, jboolean usedHack) {
diff --git a/base/atomicops_internals_arm_gcc.h b/base/atomicops_internals_arm_gcc.h
index 7c3d51d..e654afa 100644
--- a/base/atomicops_internals_arm_gcc.h
+++ b/base/atomicops_internals_arm_gcc.h
@@ -63,7 +63,7 @@
     defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || \
     defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
     defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \
-    defined(__ARM_ARCH_6KZ__) || defined(__ARM_ARCH_6T2__)
+    defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
 
 inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
                                          Atomic32 old_value,
diff --git a/base/base.gyp b/base/base.gyp
index 06ad10b..85f0a94 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -143,8 +143,7 @@
             ],
           },
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['use_allocator!="tcmalloc" and (use_allocator!="see_use_tcmalloc" or linux_use_tcmalloc==0)', {
+            ['use_allocator!="tcmalloc"', {
               'defines': [
                 'NO_TCMALLOC',
               ],
@@ -700,8 +699,7 @@
             'message_loop/message_pump_glib_unittest.cc',
           ]
         }],
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS == "linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS == "linux" and use_allocator!="none"', {
             'dependencies': [
               'allocator/allocator.gyp:allocator',
             ],
@@ -978,8 +976,7 @@
       'conditions': [
         ['use_custom_libcxx==1', {
           'dependencies!': [
-            '../third_party/libc++/libc++.gyp:libc++',
-            '../third_party/libc++abi/libc++abi.gyp:libc++abi',
+            '../third_party/libc++/libc++.gyp:libcxx_proxy',
           ],
         }],
       ],
diff --git a/base/base.gypi b/base/base.gypi
index 8110287..520f567 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -125,7 +125,7 @@
           'cpu.cc',
           'cpu.h',
           'critical_closure.h',
-          'critical_closure_ios.mm',
+          'critical_closure_internal_ios.mm',
           'debug/alias.cc',
           'debug/alias.h',
           'debug/crash_logging.cc',
@@ -137,7 +137,7 @@
           'debug/dump_without_crashing.cc',
           'debug/dump_without_crashing.h',
           'debug/gdi_debug_util_win.cc',
-          'debug/gdi_debug_util_win.h',        
+          'debug/gdi_debug_util_win.h',
           # This file depends on files from the 'allocator' target,
           # but this target does not depend on 'allocator' (see
           # allocator.gyp for details).
@@ -274,6 +274,8 @@
           'mac/mac_logging.cc',
           'mac/mac_util.h',
           'mac/mac_util.mm',
+          'mac/mach_logging.cc',
+          'mac/mach_logging.h',
           'mac/objc_property_releaser.h',
           'mac/objc_property_releaser.mm',
           'mac/os_crash_dumps.cc',
@@ -287,6 +289,8 @@
           'mac/scoped_launch_data.h',
           'mac/scoped_mach_port.cc',
           'mac/scoped_mach_port.h',
+          'mac/scoped_mach_vm.cc',
+          'mac/scoped_mach_vm.h',
           'mac/scoped_nsautorelease_pool.h',
           'mac/scoped_nsautorelease_pool.mm',
           'mac/scoped_nsexception_enabler.h',
diff --git a/base/base.target.darwin-arm.mk b/base/base.target.darwin-arm.mk
index 90bc616..c80bf7a 100644
--- a/base/base.target.darwin-arm.mk
+++ b/base/base.target.darwin-arm.mk
@@ -276,7 +276,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -365,7 +364,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base.target.darwin-x86.mk b/base/base.target.darwin-x86.mk
index 47c6b40..2a5f236 100644
--- a/base/base.target.darwin-x86.mk
+++ b/base/base.target.darwin-x86.mk
@@ -279,7 +279,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -368,7 +367,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base.target.darwin-x86_64.mk b/base/base.target.darwin-x86_64.mk
index edcc5ab..b21af61 100644
--- a/base/base.target.darwin-x86_64.mk
+++ b/base/base.target.darwin-x86_64.mk
@@ -279,7 +279,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -368,7 +367,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base.target.linux-arm.mk b/base/base.target.linux-arm.mk
index 90bc616..c80bf7a 100644
--- a/base/base.target.linux-arm.mk
+++ b/base/base.target.linux-arm.mk
@@ -276,7 +276,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -365,7 +364,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base.target.linux-x86.mk b/base/base.target.linux-x86.mk
index 47c6b40..2a5f236 100644
--- a/base/base.target.linux-x86.mk
+++ b/base/base.target.linux-x86.mk
@@ -279,7 +279,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -368,7 +367,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base.target.linux-x86_64.mk b/base/base.target.linux-x86_64.mk
index edcc5ab..b21af61 100644
--- a/base/base.target.linux-x86_64.mk
+++ b/base/base.target.linux-x86_64.mk
@@ -279,7 +279,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -368,7 +367,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_i18n.target.darwin-arm.mk b/base/base_i18n.target.darwin-arm.mk
index 11665f0..9bfad4e 100644
--- a/base/base_i18n.target.darwin-arm.mk
+++ b/base/base_i18n.target.darwin-arm.mk
@@ -59,7 +59,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -152,7 +151,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_i18n.target.darwin-x86.mk b/base/base_i18n.target.darwin-x86.mk
index 3d5883b..dc6b9c9 100644
--- a/base/base_i18n.target.darwin-x86.mk
+++ b/base/base_i18n.target.darwin-x86.mk
@@ -61,7 +61,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +153,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_i18n.target.darwin-x86_64.mk b/base/base_i18n.target.darwin-x86_64.mk
index 7419913..ee2b64d 100644
--- a/base/base_i18n.target.darwin-x86_64.mk
+++ b/base/base_i18n.target.darwin-x86_64.mk
@@ -61,7 +61,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +153,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_i18n.target.linux-arm.mk b/base/base_i18n.target.linux-arm.mk
index 11665f0..9bfad4e 100644
--- a/base/base_i18n.target.linux-arm.mk
+++ b/base/base_i18n.target.linux-arm.mk
@@ -59,7 +59,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -152,7 +151,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_i18n.target.linux-x86.mk b/base/base_i18n.target.linux-x86.mk
index 3d5883b..dc6b9c9 100644
--- a/base/base_i18n.target.linux-x86.mk
+++ b/base/base_i18n.target.linux-x86.mk
@@ -61,7 +61,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +153,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_i18n.target.linux-x86_64.mk b/base/base_i18n.target.linux-x86_64.mk
index 7419913..ee2b64d 100644
--- a/base/base_i18n.target.linux-x86_64.mk
+++ b/base/base_i18n.target.linux-x86_64.mk
@@ -61,7 +61,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +153,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_java_application_state.target.darwin-arm.mk b/base/base_java_application_state.target.darwin-arm.mk
index 4c483f4..e4d7ecc 100644
--- a/base/base_java_application_state.target.darwin-arm.mk
+++ b/base/base_java_application_state.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_application_state_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/application_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_java_application_state.target.darwin-arm64.mk b/base/base_java_application_state.target.darwin-arm64.mk
index 1b8db04..e3f7511 100644
--- a/base/base_java_application_state.target.darwin-arm64.mk
+++ b/base/base_java_application_state.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_application_state_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/application_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_java_application_state.target.darwin-mips.mk b/base/base_java_application_state.target.darwin-mips.mk
index b5bf779..a0dafc7 100644
--- a/base/base_java_application_state.target.darwin-mips.mk
+++ b/base/base_java_application_state.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_application_state_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/application_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_java_application_state.target.darwin-x86.mk b/base/base_java_application_state.target.darwin-x86.mk
index 47285e7..22d8281 100644
--- a/base/base_java_application_state.target.darwin-x86.mk
+++ b/base/base_java_application_state.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_application_state_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/application_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_java_application_state.target.darwin-x86_64.mk b/base/base_java_application_state.target.darwin-x86_64.mk
index cd8325a..2df4e8f 100644
--- a/base/base_java_application_state.target.darwin-x86_64.mk
+++ b/base/base_java_application_state.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_application_state_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/application_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_java_application_state.target.linux-arm.mk b/base/base_java_application_state.target.linux-arm.mk
index 4c483f4..e4d7ecc 100644
--- a/base/base_java_application_state.target.linux-arm.mk
+++ b/base/base_java_application_state.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_application_state_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/application_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_java_application_state.target.linux-arm64.mk b/base/base_java_application_state.target.linux-arm64.mk
index 1b8db04..e3f7511 100644
--- a/base/base_java_application_state.target.linux-arm64.mk
+++ b/base/base_java_application_state.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_application_state_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/application_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_java_application_state.target.linux-mips.mk b/base/base_java_application_state.target.linux-mips.mk
index b5bf779..a0dafc7 100644
--- a/base/base_java_application_state.target.linux-mips.mk
+++ b/base/base_java_application_state.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_application_state_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/application_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_java_application_state.target.linux-x86.mk b/base/base_java_application_state.target.linux-x86.mk
index 47285e7..22d8281 100644
--- a/base/base_java_application_state.target.linux-x86.mk
+++ b/base/base_java_application_state.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_application_state_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/application_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_java_application_state.target.linux-x86_64.mk b/base/base_java_application_state.target.linux-x86_64.mk
index cd8325a..2df4e8f 100644
--- a/base/base_java_application_state.target.linux-x86_64.mk
+++ b/base/base_java_application_state.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_application_state_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/application_state_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationState.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/ApplicationState.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_java_memory_pressure_level_list.target.darwin-arm.mk b/base/base_java_memory_pressure_level_list.target.darwin-arm.mk
index 03af96e..858c47a 100644
--- a/base/base_java_memory_pressure_level_list.target.darwin-arm.mk
+++ b/base/base_java_memory_pressure_level_list.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_memory_pressure_level_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'memory/memory_pressure_level_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/MemoryPressureLevelList.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_java_memory_pressure_level_list.target.darwin-arm64.mk b/base/base_java_memory_pressure_level_list.target.darwin-arm64.mk
index a1b2534..d2cfa52 100644
--- a/base/base_java_memory_pressure_level_list.target.darwin-arm64.mk
+++ b/base/base_java_memory_pressure_level_list.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_memory_pressure_level_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'memory/memory_pressure_level_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/MemoryPressureLevelList.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_java_memory_pressure_level_list.target.darwin-mips.mk b/base/base_java_memory_pressure_level_list.target.darwin-mips.mk
index cc83c53..4b409e0 100644
--- a/base/base_java_memory_pressure_level_list.target.darwin-mips.mk
+++ b/base/base_java_memory_pressure_level_list.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_memory_pressure_level_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'memory/memory_pressure_level_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/MemoryPressureLevelList.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_java_memory_pressure_level_list.target.darwin-x86.mk b/base/base_java_memory_pressure_level_list.target.darwin-x86.mk
index a9cb80e..e628622 100644
--- a/base/base_java_memory_pressure_level_list.target.darwin-x86.mk
+++ b/base/base_java_memory_pressure_level_list.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_memory_pressure_level_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'memory/memory_pressure_level_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/MemoryPressureLevelList.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_java_memory_pressure_level_list.target.darwin-x86_64.mk b/base/base_java_memory_pressure_level_list.target.darwin-x86_64.mk
index b89da55..597fbde 100644
--- a/base/base_java_memory_pressure_level_list.target.darwin-x86_64.mk
+++ b/base/base_java_memory_pressure_level_list.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_memory_pressure_level_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'memory/memory_pressure_level_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/MemoryPressureLevelList.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_java_memory_pressure_level_list.target.linux-arm.mk b/base/base_java_memory_pressure_level_list.target.linux-arm.mk
index 03af96e..858c47a 100644
--- a/base/base_java_memory_pressure_level_list.target.linux-arm.mk
+++ b/base/base_java_memory_pressure_level_list.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_memory_pressure_level_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'memory/memory_pressure_level_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/MemoryPressureLevelList.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_java_memory_pressure_level_list.target.linux-arm64.mk b/base/base_java_memory_pressure_level_list.target.linux-arm64.mk
index a1b2534..d2cfa52 100644
--- a/base/base_java_memory_pressure_level_list.target.linux-arm64.mk
+++ b/base/base_java_memory_pressure_level_list.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_memory_pressure_level_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'memory/memory_pressure_level_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/MemoryPressureLevelList.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_java_memory_pressure_level_list.target.linux-mips.mk b/base/base_java_memory_pressure_level_list.target.linux-mips.mk
index cc83c53..4b409e0 100644
--- a/base/base_java_memory_pressure_level_list.target.linux-mips.mk
+++ b/base/base_java_memory_pressure_level_list.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_memory_pressure_level_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'memory/memory_pressure_level_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/MemoryPressureLevelList.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_java_memory_pressure_level_list.target.linux-x86.mk b/base/base_java_memory_pressure_level_list.target.linux-x86.mk
index a9cb80e..e628622 100644
--- a/base/base_java_memory_pressure_level_list.target.linux-x86.mk
+++ b/base/base_java_memory_pressure_level_list.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_memory_pressure_level_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'memory/memory_pressure_level_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/MemoryPressureLevelList.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_java_memory_pressure_level_list.target.linux-x86_64.mk b/base/base_java_memory_pressure_level_list.target.linux-x86_64.mk
index b89da55..597fbde 100644
--- a/base/base_java_memory_pressure_level_list.target.linux-x86_64.mk
+++ b/base/base_java_memory_pressure_level_list.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_java_memory_pressure_level_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'memory/memory_pressure_level_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/src/org/chromium/base/MemoryPressureLevelList.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/base/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/base/MemoryPressureLevelList.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_jni_headers.target.darwin-arm.mk b/base/base_jni_headers.target.darwin-arm.mk
index f8e84fe..b1521df 100644
--- a/base/base_jni_headers.target.darwin-arm.mk
+++ b/base/base_jni_headers.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +117,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,6 +126,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -122,6 +135,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -130,6 +144,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -138,6 +153,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,7 +220,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -288,7 +303,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_jni_headers.target.darwin-arm64.mk b/base/base_jni_headers.target.darwin-arm64.mk
index 362cc8b..c32bdb4 100644
--- a/base/base_jni_headers.target.darwin-arm64.mk
+++ b/base/base_jni_headers.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +117,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,6 +126,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -122,6 +135,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -130,6 +144,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -138,6 +153,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_jni_headers.target.darwin-mips.mk b/base/base_jni_headers.target.darwin-mips.mk
index 0c716c2..64da039 100644
--- a/base/base_jni_headers.target.darwin-mips.mk
+++ b/base/base_jni_headers.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +117,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,6 +126,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -122,6 +135,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -130,6 +144,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -138,6 +153,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_jni_headers.target.darwin-x86.mk b/base/base_jni_headers.target.darwin-x86.mk
index 608de6c..0fd7ec1 100644
--- a/base/base_jni_headers.target.darwin-x86.mk
+++ b/base/base_jni_headers.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +117,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,6 +126,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -122,6 +135,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -130,6 +144,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -138,6 +153,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -206,7 +222,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -290,7 +305,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_jni_headers.target.darwin-x86_64.mk b/base/base_jni_headers.target.darwin-x86_64.mk
index 542bb1d..69b0e42 100644
--- a/base/base_jni_headers.target.darwin-x86_64.mk
+++ b/base/base_jni_headers.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +117,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,6 +126,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -122,6 +135,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -130,6 +144,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -138,6 +153,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -206,7 +222,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -290,7 +305,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_jni_headers.target.linux-arm.mk b/base/base_jni_headers.target.linux-arm.mk
index f8e84fe..b1521df 100644
--- a/base/base_jni_headers.target.linux-arm.mk
+++ b/base/base_jni_headers.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +117,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,6 +126,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -122,6 +135,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -130,6 +144,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -138,6 +153,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,7 +220,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -288,7 +303,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_jni_headers.target.linux-arm64.mk b/base/base_jni_headers.target.linux-arm64.mk
index 362cc8b..c32bdb4 100644
--- a/base/base_jni_headers.target.linux-arm64.mk
+++ b/base/base_jni_headers.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +117,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,6 +126,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -122,6 +135,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -130,6 +144,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -138,6 +153,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_jni_headers.target.linux-mips.mk b/base/base_jni_headers.target.linux-mips.mk
index 0c716c2..64da039 100644
--- a/base/base_jni_headers.target.linux-mips.mk
+++ b/base/base_jni_headers.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +117,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,6 +126,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -122,6 +135,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -130,6 +144,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -138,6 +153,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/base/base_jni_headers.target.linux-x86.mk b/base/base_jni_headers.target.linux-x86.mk
index 608de6c..0fd7ec1 100644
--- a/base/base_jni_headers.target.linux-x86.mk
+++ b/base/base_jni_headers.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +117,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,6 +126,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -122,6 +135,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -130,6 +144,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -138,6 +153,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -206,7 +222,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -290,7 +305,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_jni_headers.target.linux-x86_64.mk b/base/base_jni_headers.target.linux-x86_64.mk
index 542bb1d..69b0e42 100644
--- a/base/base_jni_headers.target.linux-x86_64.mk
+++ b/base/base_jni_headers.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/BuildInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CommandLine_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ContentUriUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/CpuFeatures_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PathUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +117,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/PowerMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,6 +126,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SystemMessageHandler_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -122,6 +135,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/SysUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -130,6 +144,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/ThreadUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -138,6 +153,7 @@
 
 
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/base/jni/TraceEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -206,7 +222,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -290,7 +305,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_prefs.target.darwin-arm.mk b/base/base_prefs.target.darwin-arm.mk
index bb7285d..4ac88b7 100644
--- a/base/base_prefs.target.darwin-arm.mk
+++ b/base/base_prefs.target.darwin-arm.mk
@@ -55,7 +55,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -142,7 +141,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_prefs.target.darwin-x86.mk b/base/base_prefs.target.darwin-x86.mk
index 229b7d2..5c9ad5d 100644
--- a/base/base_prefs.target.darwin-x86.mk
+++ b/base/base_prefs.target.darwin-x86.mk
@@ -57,7 +57,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_prefs.target.darwin-x86_64.mk b/base/base_prefs.target.darwin-x86_64.mk
index 4237368..4f34363 100644
--- a/base/base_prefs.target.darwin-x86_64.mk
+++ b/base/base_prefs.target.darwin-x86_64.mk
@@ -57,7 +57,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_prefs.target.linux-arm.mk b/base/base_prefs.target.linux-arm.mk
index bb7285d..4ac88b7 100644
--- a/base/base_prefs.target.linux-arm.mk
+++ b/base/base_prefs.target.linux-arm.mk
@@ -55,7 +55,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -142,7 +141,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_prefs.target.linux-x86.mk b/base/base_prefs.target.linux-x86.mk
index 229b7d2..5c9ad5d 100644
--- a/base/base_prefs.target.linux-x86.mk
+++ b/base/base_prefs.target.linux-x86.mk
@@ -57,7 +57,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_prefs.target.linux-x86_64.mk b/base/base_prefs.target.linux-x86_64.mk
index 4237368..4f34363 100644
--- a/base/base_prefs.target.linux-x86_64.mk
+++ b/base/base_prefs.target.linux-x86_64.mk
@@ -57,7 +57,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_static.target.darwin-arm.mk b/base/base_static.target.darwin-arm.mk
index 6e99300..aa884e3 100644
--- a/base/base_static.target.darwin-arm.mk
+++ b/base/base_static.target.darwin-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -126,7 +125,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_static.target.darwin-x86.mk b/base/base_static.target.darwin-x86.mk
index 4cc7fc2..75cee9c 100644
--- a/base/base_static.target.darwin-x86.mk
+++ b/base/base_static.target.darwin-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_static.target.darwin-x86_64.mk b/base/base_static.target.darwin-x86_64.mk
index db95a24..1aeda9f 100644
--- a/base/base_static.target.darwin-x86_64.mk
+++ b/base/base_static.target.darwin-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_static.target.linux-arm.mk b/base/base_static.target.linux-arm.mk
index 6e99300..aa884e3 100644
--- a/base/base_static.target.linux-arm.mk
+++ b/base/base_static.target.linux-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -126,7 +125,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/base_static.target.linux-x86.mk b/base/base_static.target.linux-x86.mk
index 4cc7fc2..75cee9c 100644
--- a/base/base_static.target.linux-x86.mk
+++ b/base/base_static.target.linux-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/base_static.target.linux-x86_64.mk b/base/base_static.target.linux-x86_64.mk
index db95a24..1aeda9f 100644
--- a/base/base_static.target.linux-x86_64.mk
+++ b/base/base_static.target.linux-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/cpu.cc b/base/cpu.cc
index 3fa9413..f18b8db 100644
--- a/base/cpu.cc
+++ b/base/cpu.cc
@@ -91,21 +91,28 @@
 
 #if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX))
 
+// Returns the string found in /proc/cpuinfo under the key "model name" or
+// "Processor". "model name" is used in Linux 3.8 and later (3.7 and later for
+// arm64) and is shown once per CPU. "Processor" is used in earler versions and
+// is shown only once at the top of /proc/cpuinfo regardless of the number CPUs.
 std::string ParseCpuInfo() {
-  const char kProcessorPrefix[] = "Processor";
-  std::string contents, cpu_brand;
+  const char kModelNamePrefix[] = "model name\t: ";
+  const char kProcessorPrefix[] = "Processor\t: ";
+  std::string contents;
   ReadFileToString(FilePath("/proc/cpuinfo"), &contents);
   DCHECK(!contents.empty());
+  std::string cpu_brand;
   if (!contents.empty()) {
     std::istringstream iss(contents);
     std::string line;
     while (std::getline(iss, line)) {
+      if (line.compare(0, strlen(kModelNamePrefix), kModelNamePrefix) == 0) {
+        cpu_brand.assign(line.substr(strlen(kModelNamePrefix)));
+        break;
+      }
       if (line.compare(0, strlen(kProcessorPrefix), kProcessorPrefix) == 0) {
-        size_t pos = line.find(": ");
-        if (pos != std::string::npos) {
-          cpu_brand.assign(line.substr(pos + 2));
-          break;
-        }
+        cpu_brand.assign(line.substr(strlen(kProcessorPrefix)));
+        break;
       }
     }
   }
diff --git a/base/critical_closure.h b/base/critical_closure.h
index ca51ed5..ac07911 100644
--- a/base/critical_closure.h
+++ b/base/critical_closure.h
@@ -7,9 +7,46 @@
 
 #include "base/callback.h"
 
+#if defined(OS_IOS)
+#include "base/bind.h"
+#include "base/ios/scoped_critical_action.h"
+#endif
+
 namespace base {
 
-// Returns a closure that will continue to run for a period of time when the
+namespace internal {
+
+#if defined(OS_IOS)
+// Returns true if multi-tasking is supported on this iOS device.
+bool IsMultiTaskingSupported();
+
+// This class wraps a closure so it can continue to run for a period of time
+// when the application goes to the background by using
+// |ios::ScopedCriticalAction|.
+template <typename R>
+class CriticalClosure {
+ public:
+  explicit CriticalClosure(const Callback<R(void)>& closure)
+      : closure_(closure) {}
+
+  ~CriticalClosure() {}
+
+  R Run() {
+    return closure_.Run();
+  }
+
+ private:
+  ios::ScopedCriticalAction critical_action_;
+  Callback<R(void)> closure_;
+
+  DISALLOW_COPY_AND_ASSIGN(CriticalClosure);
+};
+#endif  // defined(OS_IOS)
+
+}  // namespace internal
+
+// Returns a closure (which may return a result, but must not require any extra
+// arguments) that will continue to run for a period of time when the
 // application goes to the background if possible on platforms where
 // applications don't execute while backgrounded, otherwise the original task is
 // returned.
@@ -23,14 +60,20 @@
 // background running time, |MakeCriticalClosure| should be applied on them
 // before posting.
 #if defined(OS_IOS)
-base::Closure MakeCriticalClosure(const base::Closure& closure);
-#else
-inline base::Closure MakeCriticalClosure(const base::Closure& closure) {
+template <typename R>
+Callback<R(void)> MakeCriticalClosure(const Callback<R(void)>& closure) {
+  DCHECK(internal::IsMultiTaskingSupported());
+  return base::Bind(&internal::CriticalClosure<R>::Run,
+                    Owned(new internal::CriticalClosure<R>(closure)));
+}
+#else  // defined(OS_IOS)
+template <typename R>
+inline Callback<R(void)> MakeCriticalClosure(const Callback<R(void)>& closure) {
   // No-op for platforms where the application does not need to acquire
   // background time for closures to finish when it goes into the background.
   return closure;
 }
-#endif  // !defined(OS_IOS)
+#endif  // defined(OS_IOS)
 
 }  // namespace base
 
diff --git a/base/critical_closure_internal_ios.mm b/base/critical_closure_internal_ios.mm
new file mode 100644
index 0000000..b8fec14
--- /dev/null
+++ b/base/critical_closure_internal_ios.mm
@@ -0,0 +1,17 @@
+// 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.
+
+#include "base/critical_closure.h"
+
+#import <UIKit/UIKit.h>
+
+namespace base {
+namespace internal {
+
+bool IsMultiTaskingSupported() {
+  return [[UIDevice currentDevice] isMultitaskingSupported];
+}
+
+}  // namespace internal
+}  // namespace base
diff --git a/base/critical_closure_ios.mm b/base/critical_closure_ios.mm
deleted file mode 100644
index d605cad..0000000
--- a/base/critical_closure_ios.mm
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/critical_closure.h"
-
-#import <UIKit/UIKit.h>
-
-#include "base/bind.h"
-#include "base/ios/scoped_critical_action.h"
-#include "base/memory/ref_counted.h"
-
-namespace {
-
-// This class wraps a closure so it can continue to run for a period of time
-// when the application goes to the background by using
-// |base::ios::ScopedCriticalAction|.
-class CriticalClosure : public base::RefCountedThreadSafe<CriticalClosure> {
- public:
-  explicit CriticalClosure(base::Closure* closure) : closure_(closure) {
-  }
-
-  void Run() {
-    closure_->Run();
-  }
-
- private:
-  friend class base::RefCountedThreadSafe<CriticalClosure>;
-
-  virtual ~CriticalClosure() {}
-
-  base::ios::ScopedCriticalAction criticial_action_;
-  scoped_ptr<base::Closure> closure_;
-
-  DISALLOW_COPY_AND_ASSIGN(CriticalClosure);
-};
-
-}  // namespace
-
-namespace base {
-
-base::Closure MakeCriticalClosure(const base::Closure& closure) {
-  DCHECK([[UIDevice currentDevice] isMultitaskingSupported]);
-  scoped_refptr<CriticalClosure> critical_closure(
-      new CriticalClosure(new base::Closure(closure)));
-  return base::Bind(&CriticalClosure::Run, critical_closure.get());
-}
-
-}  // namespace base
diff --git a/base/debug/sanitizer_options.cc b/base/debug/sanitizer_options.cc
index e72f371..41f82b9 100644
--- a/base/debug/sanitizer_options.cc
+++ b/base/debug/sanitizer_options.cc
@@ -45,11 +45,12 @@
 // Chromium builds.
 const char kAsanDefaultOptions[] =
     "legacy_pthread_cond=1 malloc_context_size=5 strict_memcmp=0 "
-    "symbolize=false check_printf=1 use_sigaltstack=1";
+    "symbolize=false check_printf=1 use_sigaltstack=1 detect_leaks=0";
 #else
 // Default AddressSanitizer options for buildbots and non-official builds.
 const char *kAsanDefaultOptions =
-    "strict_memcmp=0 symbolize=false check_printf=1 use_sigaltstack=1";
+    "strict_memcmp=0 symbolize=false check_printf=1 use_sigaltstack=1 "
+    "detect_leaks=0";
 #endif  // GOOGLE_CHROME_BUILD
 
 #elif defined(OS_MACOSX)
@@ -60,6 +61,10 @@
 #if defined(OS_LINUX) || defined(OS_MACOSX)
 extern "C"
 __attribute__((no_sanitize_address))
+__attribute__((visibility("default")))
+// The function isn't referenced from the executable itself. Make sure it isn't
+// stripped by the linker.
+__attribute__((used))
 const char *__asan_default_options() {
   return kAsanDefaultOptions;
 }
diff --git a/base/debug/stack_trace.h b/base/debug/stack_trace.h
index e6887e6..7c2ac3c 100644
--- a/base/debug/stack_trace.h
+++ b/base/debug/stack_trace.h
@@ -53,7 +53,7 @@
   // Creates a stacktrace for an exception.
   // Note: this function will throw an import not found (StackWalk64) exception
   // on system without dbghelp 5.1.
-  StackTrace(_EXCEPTION_POINTERS* exception_pointers);
+  StackTrace(const _EXCEPTION_POINTERS* exception_pointers);
 #endif
 
   // Copying and assignment are allowed with the default functions.
diff --git a/base/debug/stack_trace_win.cc b/base/debug/stack_trace_win.cc
index eb35b6a..a3327af 100644
--- a/base/debug/stack_trace_win.cc
+++ b/base/debug/stack_trace_win.cc
@@ -211,22 +211,25 @@
 #pragma optimize("", on)
 #endif
 
-StackTrace::StackTrace(EXCEPTION_POINTERS* exception_pointers) {
+StackTrace::StackTrace(const EXCEPTION_POINTERS* exception_pointers) {
   // When walking an exception stack, we need to use StackWalk64().
   count_ = 0;
+  // StackWalk64() may modify context record passed to it, so we will
+  // use a copy.
+  CONTEXT context_record = *exception_pointers->ContextRecord;
   // Initialize stack walking.
   STACKFRAME64 stack_frame;
   memset(&stack_frame, 0, sizeof(stack_frame));
 #if defined(_WIN64)
   int machine_type = IMAGE_FILE_MACHINE_AMD64;
-  stack_frame.AddrPC.Offset = exception_pointers->ContextRecord->Rip;
-  stack_frame.AddrFrame.Offset = exception_pointers->ContextRecord->Rbp;
-  stack_frame.AddrStack.Offset = exception_pointers->ContextRecord->Rsp;
+  stack_frame.AddrPC.Offset = context_record.Rip;
+  stack_frame.AddrFrame.Offset = context_record.Rbp;
+  stack_frame.AddrStack.Offset = context_record.Rsp;
 #else
   int machine_type = IMAGE_FILE_MACHINE_I386;
-  stack_frame.AddrPC.Offset = exception_pointers->ContextRecord->Eip;
-  stack_frame.AddrFrame.Offset = exception_pointers->ContextRecord->Ebp;
-  stack_frame.AddrStack.Offset = exception_pointers->ContextRecord->Esp;
+  stack_frame.AddrPC.Offset = context_record.Eip;
+  stack_frame.AddrFrame.Offset = context_record.Ebp;
+  stack_frame.AddrStack.Offset = context_record.Esp;
 #endif
   stack_frame.AddrPC.Mode = AddrModeFlat;
   stack_frame.AddrFrame.Mode = AddrModeFlat;
@@ -235,7 +238,7 @@
                      GetCurrentProcess(),
                      GetCurrentThread(),
                      &stack_frame,
-                     exception_pointers->ContextRecord,
+                     &context_record,
                      NULL,
                      &SymFunctionTableAccess64,
                      &SymGetModuleBase64,
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
index 9acdf3e..175e9cd 100644
--- a/base/file_util_unittest.cc
+++ b/base/file_util_unittest.cc
@@ -805,7 +805,7 @@
   FileEnumerator f1(subdir_path, true, FileEnumerator::FILES);
   EXPECT_TRUE(PathExists(subdir_path));
   FindResultCollector c1(f1);
-  EXPECT_EQ(c1.size(), 0);
+  EXPECT_EQ(0, c1.size());
   EXPECT_FALSE(GetPosixFilePermissions(file_name, &mode));
 
   // Give the permissions to the directory.
@@ -817,7 +817,7 @@
   FileEnumerator f2(subdir_path, true, FileEnumerator::FILES);
   FindResultCollector c2(f2);
   EXPECT_TRUE(c2.HasFile(file_name));
-  EXPECT_EQ(c2.size(), 1);
+  EXPECT_EQ(1, c2.size());
 
   // Delete the file.
   EXPECT_TRUE(DeleteFile(subdir_path, true));
@@ -1788,8 +1788,8 @@
 TEST_F(FileUtilTest, FileEnumeratorTest) {
   // Test an empty directory.
   FileEnumerator f0(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
-  EXPECT_EQ(f0.Next().value(), FPL(""));
-  EXPECT_EQ(f0.Next().value(), FPL(""));
+  EXPECT_EQ(FPL(""), f0.Next().value());
+  EXPECT_EQ(FPL(""), f0.Next().value());
 
   // Test an empty directory, non-recursively, including "..".
   FileEnumerator f0_dotdot(temp_dir_.path(), false,
@@ -1825,7 +1825,7 @@
   EXPECT_TRUE(c1.HasFile(file2_abs));
   EXPECT_TRUE(c1.HasFile(dir2file));
   EXPECT_TRUE(c1.HasFile(dir2innerfile));
-  EXPECT_EQ(c1.size(), 4);
+  EXPECT_EQ(4, c1.size());
 
   // Only enumerate directories.
   FileEnumerator f2(temp_dir_.path(), true, FileEnumerator::DIRECTORIES);
@@ -1833,7 +1833,7 @@
   EXPECT_TRUE(c2.HasFile(dir1));
   EXPECT_TRUE(c2.HasFile(dir2));
   EXPECT_TRUE(c2.HasFile(dir2inner));
-  EXPECT_EQ(c2.size(), 3);
+  EXPECT_EQ(3, c2.size());
 
   // Only enumerate directories non-recursively.
   FileEnumerator f2_non_recursive(
@@ -1841,7 +1841,7 @@
   FindResultCollector c2_non_recursive(f2_non_recursive);
   EXPECT_TRUE(c2_non_recursive.HasFile(dir1));
   EXPECT_TRUE(c2_non_recursive.HasFile(dir2));
-  EXPECT_EQ(c2_non_recursive.size(), 2);
+  EXPECT_EQ(2, c2_non_recursive.size());
 
   // Only enumerate directories, non-recursively, including "..".
   FileEnumerator f2_dotdot(temp_dir_.path(), false,
@@ -1851,7 +1851,7 @@
   EXPECT_TRUE(c2_dotdot.HasFile(dir1));
   EXPECT_TRUE(c2_dotdot.HasFile(dir2));
   EXPECT_TRUE(c2_dotdot.HasFile(temp_dir_.path().Append(FPL(".."))));
-  EXPECT_EQ(c2_dotdot.size(), 3);
+  EXPECT_EQ(3, c2_dotdot.size());
 
   // Enumerate files and directories.
   FileEnumerator f3(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
@@ -1863,7 +1863,7 @@
   EXPECT_TRUE(c3.HasFile(dir2file));
   EXPECT_TRUE(c3.HasFile(dir2inner));
   EXPECT_TRUE(c3.HasFile(dir2innerfile));
-  EXPECT_EQ(c3.size(), 7);
+  EXPECT_EQ(7, c3.size());
 
   // Non-recursive operation.
   FileEnumerator f4(temp_dir_.path(), false, FILES_AND_DIRECTORIES);
@@ -1872,7 +1872,7 @@
   EXPECT_TRUE(c4.HasFile(dir2));
   EXPECT_TRUE(c4.HasFile(file1));
   EXPECT_TRUE(c4.HasFile(file2_abs));
-  EXPECT_EQ(c4.size(), 4);
+  EXPECT_EQ(4, c4.size());
 
   // Enumerate with a pattern.
   FileEnumerator f5(temp_dir_.path(), true, FILES_AND_DIRECTORIES, FPL("dir*"));
@@ -1882,7 +1882,7 @@
   EXPECT_TRUE(c5.HasFile(dir2file));
   EXPECT_TRUE(c5.HasFile(dir2inner));
   EXPECT_TRUE(c5.HasFile(dir2innerfile));
-  EXPECT_EQ(c5.size(), 5);
+  EXPECT_EQ(5, c5.size());
 
 #if defined(OS_WIN)
   {
@@ -1900,7 +1900,7 @@
       EXPECT_TRUE(c6.HasFile(inner2));
       EXPECT_TRUE(c6.HasFile(inner2.Append(FPL("innerfile.txt"))));
       EXPECT_TRUE(c6.HasFile(dir1.Append(FPL("dir2file.txt"))));
-      EXPECT_EQ(c6.size(), 3);
+      EXPECT_EQ(3, c6.size());
     }
 
     // No changes for non recursive operation.
@@ -1910,7 +1910,7 @@
     EXPECT_TRUE(c7.HasFile(dir2));
     EXPECT_TRUE(c7.HasFile(file1));
     EXPECT_TRUE(c7.HasFile(file2_abs));
-    EXPECT_EQ(c7.size(), 4);
+    EXPECT_EQ(4, c7.size());
 
     // Should not enumerate inside dir1 when using recursion.
     FileEnumerator f8(temp_dir_.path(), true, FILES_AND_DIRECTORIES);
@@ -1922,7 +1922,7 @@
     EXPECT_TRUE(c8.HasFile(dir2file));
     EXPECT_TRUE(c8.HasFile(dir2inner));
     EXPECT_TRUE(c8.HasFile(dir2innerfile));
-    EXPECT_EQ(c8.size(), 7);
+    EXPECT_EQ(7, c8.size());
   }
 #endif
 
@@ -1978,24 +1978,23 @@
   // Read the file with smaller buffer.
   int bytes_read_small = ReadFile(
       file_path, &small_buffer[0], static_cast<int>(small_buffer.size()));
-  EXPECT_EQ(bytes_read_small, static_cast<int>(small_buffer.size()));
+  EXPECT_EQ(static_cast<int>(small_buffer.size()), bytes_read_small);
   EXPECT_EQ(
-      std::string(small_buffer.begin(), small_buffer.end()),
-      std::string(kTestData.begin(), kTestData.begin() + small_buffer.size()));
+      std::string(kTestData.begin(), kTestData.begin() + small_buffer.size()),
+      std::string(small_buffer.begin(), small_buffer.end()));
 
   // Read the file with buffer which have exactly same size.
   int bytes_read_exact = ReadFile(
       file_path, &exact_buffer[0], static_cast<int>(exact_buffer.size()));
-  EXPECT_EQ(bytes_read_exact, static_cast<int>(kTestData.size()));
-  EXPECT_EQ(std::string(exact_buffer.begin(), exact_buffer.end()), kTestData);
+  EXPECT_EQ(static_cast<int>(kTestData.size()), bytes_read_exact);
+  EXPECT_EQ(kTestData, std::string(exact_buffer.begin(), exact_buffer.end()));
 
   // Read the file with larger buffer.
   int bytes_read_large = ReadFile(
       file_path, &large_buffer[0], static_cast<int>(large_buffer.size()));
-  EXPECT_EQ(bytes_read_large, static_cast<int>(kTestData.size()));
-  EXPECT_EQ(std::string(large_buffer.begin(),
-                        large_buffer.begin() + kTestData.size()),
-            kTestData);
+  EXPECT_EQ(static_cast<int>(kTestData.size()), bytes_read_large);
+  EXPECT_EQ(kTestData, std::string(large_buffer.begin(),
+                                   large_buffer.begin() + kTestData.size()));
 
   // Make sure the return value is -1 if the file doesn't exist.
   FilePath file_path_not_exist =
@@ -2081,7 +2080,7 @@
   // This timestamp is divisible by one day (in local timezone),
   // to make it work on FAT too.
   ASSERT_TRUE(Time::FromString("Wed, 16 Nov 1994, 00:00:00",
-                                     &access_time));
+                               &access_time));
 
   Time modification_time;
   // Note that this timestamp is divisible by two (seconds) - FAT stores
@@ -2092,10 +2091,10 @@
   ASSERT_TRUE(TouchFile(foobar, access_time, modification_time));
   File::Info file_info;
   ASSERT_TRUE(GetFileInfo(foobar, &file_info));
-  EXPECT_EQ(file_info.last_accessed.ToInternalValue(),
-            access_time.ToInternalValue());
-  EXPECT_EQ(file_info.last_modified.ToInternalValue(),
-            modification_time.ToInternalValue());
+  EXPECT_EQ(access_time.ToInternalValue(),
+            file_info.last_accessed.ToInternalValue());
+  EXPECT_EQ(modification_time.ToInternalValue(),
+            file_info.last_modified.ToInternalValue());
 }
 
 TEST_F(FileUtilTest, IsDirectoryEmpty) {
diff --git a/base/files/file.cc b/base/files/file.cc
index 2a2f843..da261d6 100644
--- a/base/files/file.cc
+++ b/base/files/file.cc
@@ -60,6 +60,8 @@
 }
 
 File::~File() {
+  // Go through the AssertIOAllowed logic.
+  Close();
 }
 
 File& File::operator=(RValue other) {
diff --git a/base/files/file_path.cc b/base/files/file_path.cc
index f5a9e5a..a8b2713 100644
--- a/base/files/file_path.cc
+++ b/base/files/file_path.cc
@@ -521,7 +521,7 @@
 }
 
 FilePath FilePath::AppendASCII(const StringPiece& component) const {
-  DCHECK(IsStringASCII(component));
+  DCHECK(base::IsStringASCII(component));
 #if defined(OS_WIN)
   return Append(ASCIIToUTF16(component.as_string()));
 #elif defined(OS_POSIX)
@@ -587,7 +587,7 @@
 }
 
 std::string FilePath::MaybeAsASCII() const {
-  if (IsStringASCII(path_))
+  if (base::IsStringASCII(path_))
     return path_;
   return std::string();
 }
@@ -632,7 +632,7 @@
 }
 
 std::string FilePath::MaybeAsASCII() const {
-  if (IsStringASCII(path_))
+  if (base::IsStringASCII(path_))
     return UTF16ToASCII(path_);
   return std::string();
 }
diff --git a/base/files/file_path.h b/base/files/file_path.h
index 5410e0d..008b9f5 100644
--- a/base/files/file_path.h
+++ b/base/files/file_path.h
@@ -321,8 +321,8 @@
   // separator.
   FilePath StripTrailingSeparators() const WARN_UNUSED_RESULT;
 
-  // Returns true if this FilePath contains any attempt to reference a parent
-  // directory (i.e. has a path component that is ".."
+  // Returns true if this FilePath contains an attempt to reference a parent
+  // directory (e.g. has a path component that is "..").
   bool ReferencesParent() const;
 
   // Return a Unicode human-readable version of this path.
diff --git a/base/files/file_proxy.cc b/base/files/file_proxy.cc
index b517761..fa04d7c 100644
--- a/base/files/file_proxy.cc
+++ b/base/files/file_proxy.cc
@@ -13,27 +13,38 @@
 #include "base/task_runner.h"
 #include "base/task_runner_util.h"
 
+namespace {
+
+void FileDeleter(base::File file) {
+}
+
+}  // namespace
+
 namespace base {
 
 class FileHelper {
  public:
    FileHelper(FileProxy* proxy, File file)
       : file_(file.Pass()),
-        proxy_(AsWeakPtr(proxy)),
-        error_(File::FILE_ERROR_FAILED) {
+        error_(File::FILE_ERROR_FAILED),
+        task_runner_(proxy->task_runner()),
+        proxy_(AsWeakPtr(proxy)) {
    }
 
    void PassFile() {
      if (proxy_)
        proxy_->SetFile(file_.Pass());
+     else if (file_.IsValid())
+       task_runner_->PostTask(FROM_HERE, Bind(&FileDeleter, Passed(&file_)));
    }
 
  protected:
   File file_;
-  WeakPtr<FileProxy> proxy_;
   File::Error error_;
 
  private:
+  scoped_refptr<TaskRunner> task_runner_;
+  WeakPtr<FileProxy> proxy_;
   DISALLOW_COPY_AND_ASSIGN(FileHelper);
 };
 
@@ -219,13 +230,12 @@
 
 }  // namespace
 
-FileProxy::FileProxy() : task_runner_(NULL) {
-}
-
 FileProxy::FileProxy(TaskRunner* task_runner) : task_runner_(task_runner) {
 }
 
 FileProxy::~FileProxy() {
+  if (file_.IsValid())
+    task_runner_->PostTask(FROM_HERE, Bind(&FileDeleter, Passed(&file_)));
 }
 
 bool FileProxy::CreateOrOpen(const FilePath& file_path,
diff --git a/base/files/file_proxy.h b/base/files/file_proxy.h
index f02960b..3c834f6 100644
--- a/base/files/file_proxy.h
+++ b/base/files/file_proxy.h
@@ -25,11 +25,8 @@
 // same rules of the equivalent File method, as they are implemented by bouncing
 // the operation to File using a TaskRunner.
 //
-// This class does NOT perform automatic proxying to close the underlying file
-// at destruction, which means that it may potentially close the file in the
-// wrong thread (the current thread). If that is not appropriate, the caller
-// must ensure that Close() is called, so that the operation happens on the
-// desired thread.
+// This class performs automatic proxying to close the underlying file at
+// destruction.
 //
 // The TaskRunner is in charge of any sequencing of the operations, but a single
 // operation can be proxied at a time, regardless of the use of a callback.
@@ -131,6 +128,7 @@
  private:
   friend class FileHelper;
   void SetFile(File file);
+  TaskRunner* task_runner() { return task_runner_.get(); }
 
   scoped_refptr<TaskRunner> task_runner_;
   File file_;
diff --git a/base/files/file_proxy_unittest.cc b/base/files/file_proxy_unittest.cc
index bb7e6c3..7748923 100644
--- a/base/files/file_proxy_unittest.cc
+++ b/base/files/file_proxy_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/threading/thread.h"
+#include "base/threading/thread_restrictions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
@@ -143,6 +144,21 @@
   EXPECT_FALSE(PathExists(test_path()));
 }
 
+TEST_F(FileProxyTest, CreateOrOpen_AbandonedCreate) {
+  bool prev = ThreadRestrictions::SetIOAllowed(false);
+  {
+    FileProxy proxy(file_task_runner());
+    proxy.CreateOrOpen(
+        test_path(),
+        File::FLAG_CREATE | File::FLAG_READ,
+        Bind(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
+  }
+  MessageLoop::current()->Run();
+  ThreadRestrictions::SetIOAllowed(prev);
+
+  EXPECT_TRUE(PathExists(test_path()));
+}
+
 TEST_F(FileProxyTest, Close) {
   // Creates a file.
   FileProxy proxy(file_task_runner());
diff --git a/base/mac/mac_logging.h b/base/mac/mac_logging.h
index ecd9b6b..02f205d 100644
--- a/base/mac/mac_logging.h
+++ b/base/mac/mac_logging.h
@@ -73,10 +73,10 @@
                 DLOG_IS_ON(severity) && (condition))
 
 #define OSSTATUS_DVLOG(verbose_level, status) \
-    LAZY_STREAM(OSSTATUS_VPLOG_STREAM(verbose_level, status), \
+    LAZY_STREAM(OSSTATUS_VLOG_STREAM(verbose_level, status), \
                 DVLOG_IS_ON(verbose_level))
 #define OSSTATUS_DVLOG_IF(verbose_level, condition, status) \
-    LAZY_STREAM(OSSTATUS_VPLOG_STREAM(verbose_level, status) \
+    LAZY_STREAM(OSSTATUS_VLOG_STREAM(verbose_level, status) \
                 DVLOG_IS_ON(verbose_level) && (condition))
 
 #define OSSTATUS_DCHECK(condition, status) \
diff --git a/base/mac/mach_logging.cc b/base/mac/mach_logging.cc
new file mode 100644
index 0000000..0ab6416
--- /dev/null
+++ b/base/mac/mach_logging.cc
@@ -0,0 +1,81 @@
+// 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.
+
+#include "base/mac/mach_logging.h"
+
+#include <servers/bootstrap.h>
+
+#include <iomanip>
+#include <string>
+
+#include "base/strings/stringprintf.h"
+
+namespace {
+
+std::string FormatMachErrorNumber(mach_error_t mach_err) {
+  // For the os/kern subsystem, give the error number in decimal as in
+  // <mach/kern_return.h>. Otherwise, give it in hexadecimal to make it easier
+  // to visualize the various bits. See <mach/error.h>.
+  if (mach_err >= 0 && mach_err < KERN_RETURN_MAX) {
+    return base::StringPrintf(" (%d)", mach_err);
+  }
+  return base::StringPrintf(" (0x%08x)", mach_err);
+}
+
+}  // namespace
+
+namespace logging {
+
+MachLogMessage::MachLogMessage(const char* file_path,
+                               int line,
+                               LogSeverity severity,
+                               mach_error_t mach_err)
+    : LogMessage(file_path, line, severity),
+      mach_err_(mach_err) {
+}
+
+MachLogMessage::~MachLogMessage() {
+  stream() << ": "
+           << mach_error_string(mach_err_)
+           << FormatMachErrorNumber(mach_err_);
+}
+
+BootstrapLogMessage::BootstrapLogMessage(const char* file_path,
+                                         int line,
+                                         LogSeverity severity,
+                                         kern_return_t bootstrap_err)
+    : LogMessage(file_path, line, severity),
+      bootstrap_err_(bootstrap_err) {
+}
+
+BootstrapLogMessage::~BootstrapLogMessage() {
+  stream() << ": "
+           << bootstrap_strerror(bootstrap_err_);
+
+  switch (bootstrap_err_) {
+    case BOOTSTRAP_SUCCESS:
+    case BOOTSTRAP_NOT_PRIVILEGED:
+    case BOOTSTRAP_NAME_IN_USE:
+    case BOOTSTRAP_UNKNOWN_SERVICE:
+    case BOOTSTRAP_SERVICE_ACTIVE:
+    case BOOTSTRAP_BAD_COUNT:
+    case BOOTSTRAP_NO_MEMORY:
+    case BOOTSTRAP_NO_CHILDREN: {
+      // Show known bootstrap errors in decimal because that's how they're
+      // defined in <servers/bootstrap.h>.
+      stream() << " (" << bootstrap_err_ << ")";
+      break;
+    }
+
+    default: {
+      // bootstrap_strerror passes unknown errors to mach_error_string, so
+      // format them as they would be if they were handled by
+      // MachErrorMessage.
+      stream() << FormatMachErrorNumber(bootstrap_err_);
+      break;
+    }
+  }
+}
+
+}  // namespace logging
diff --git a/base/mac/mach_logging.h b/base/mac/mach_logging.h
new file mode 100644
index 0000000..589dde2
--- /dev/null
+++ b/base/mac/mach_logging.h
@@ -0,0 +1,149 @@
+// 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.
+
+#ifndef BASE_MAC_MACH_LOGGING_H_
+#define BASE_MAC_MACH_LOGGING_H_
+
+#include <mach/mach.h>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+
+// Use the MACH_LOG family of macros along with a mach_error_t (kern_return_t)
+// containing a Mach error. The error value will be decoded so that logged
+// messages explain the error.
+//
+// Use the BOOTSTRAP_LOG family of macros specifically for errors that occur
+// while interoperating with the bootstrap subsystem. These errors will first
+// be looked up as bootstrap error messages. If no match is found, they will
+// be treated as generic Mach errors, as in MACH_LOG.
+//
+// Examples:
+//
+//   kern_return_t kr = mach_timebase_info(&info);
+//   if (kr != KERN_SUCCESS) {
+//     MACH_LOG(ERROR, kr) << "mach_timebase_info";
+//   }
+//
+//   kr = mach_vm_deallocate(task, address, size);
+//   MACH_DCHECK(kr == KERN_SUCCESS, kr) << "mach_vm_deallocate";
+
+namespace logging {
+
+class MachLogMessage : public logging::LogMessage {
+ public:
+  MachLogMessage(const char* file_path,
+                 int line,
+                 LogSeverity severity,
+                 mach_error_t mach_err);
+  ~MachLogMessage();
+
+ private:
+  mach_error_t mach_err_;
+
+  DISALLOW_COPY_AND_ASSIGN(MachLogMessage);
+};
+
+class BootstrapLogMessage : public logging::LogMessage {
+ public:
+  BootstrapLogMessage(const char* file_path,
+                      int line,
+                      LogSeverity severity,
+                      kern_return_t bootstrap_err);
+  ~BootstrapLogMessage();
+
+ private:
+  kern_return_t bootstrap_err_;
+
+  DISALLOW_COPY_AND_ASSIGN(BootstrapLogMessage);
+};
+
+}  // namespace logging
+
+#define MACH_LOG_STREAM(severity, mach_err) \
+    COMPACT_GOOGLE_LOG_EX_ ## severity(MachLogMessage, mach_err).stream()
+#define MACH_VLOG_STREAM(verbose_level, mach_err) \
+    logging::MachLogMessage(__FILE__, __LINE__, \
+                            -verbose_level, mach_err).stream()
+
+#define MACH_LOG(severity, mach_err) \
+    LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), LOG_IS_ON(severity))
+#define MACH_LOG_IF(severity, condition, mach_err) \
+    LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), \
+                LOG_IS_ON(severity) && (condition))
+
+#define MACH_VLOG(verbose_level, mach_err) \
+    LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
+                VLOG_IS_ON(verbose_level))
+#define MACH_VLOG_IF(verbose_level, condition, mach_err) \
+    LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
+                VLOG_IS_ON(verbose_level) && (condition))
+
+#define MACH_CHECK(condition, mach_err) \
+    LAZY_STREAM(MACH_LOG_STREAM(FATAL, mach_err), !(condition)) \
+    << "Check failed: " # condition << ". "
+
+#define MACH_DLOG(severity, mach_err) \
+    LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), DLOG_IS_ON(severity))
+#define MACH_DLOG_IF(severity, condition, mach_err) \
+    LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), \
+                DLOG_IS_ON(severity) && (condition))
+
+#define MACH_DVLOG(verbose_level, mach_err) \
+    LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
+                DVLOG_IS_ON(verbose_level))
+#define MACH_DVLOG_IF(verbose_level, condition, mach_err) \
+    LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err) \
+                DVLOG_IS_ON(verbose_level) && (condition))
+
+#define MACH_DCHECK(condition, mach_err) \
+    LAZY_STREAM(MACH_LOG_STREAM(FATAL, mach_err), \
+                DCHECK_IS_ON && !(condition)) \
+    << "Check failed: " # condition << ". "
+
+#define BOOTSTRAP_LOG_STREAM(severity, bootstrap_err) \
+    COMPACT_GOOGLE_LOG_EX_ ## severity(BootstrapLogMessage, \
+                                       bootstrap_err).stream()
+#define BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err) \
+    logging::BootstrapLogMessage(__FILE__, __LINE__, \
+                                 -verbose_level, bootstrap_err).stream()
+
+#define BOOTSTRAP_LOG(severity, bootstrap_err) \
+    LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, \
+                                     bootstrap_err), LOG_IS_ON(severity))
+#define BOOTSTRAP_LOG_IF(severity, condition, bootstrap_err) \
+    LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
+                LOG_IS_ON(severity) && (condition))
+
+#define BOOTSTRAP_VLOG(verbose_level, bootstrap_err) \
+    LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
+                VLOG_IS_ON(verbose_level))
+#define BOOTSTRAP_VLOG_IF(verbose_level, condition, bootstrap_err) \
+    LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
+                VLOG_IS_ON(verbose_level) && (condition))
+
+#define BOOTSTRAP_CHECK(condition, bootstrap_err) \
+    LAZY_STREAM(BOOTSTRAP_LOG_STREAM(FATAL, bootstrap_err), !(condition)) \
+    << "Check failed: " # condition << ". "
+
+#define BOOTSTRAP_DLOG(severity, bootstrap_err) \
+    LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
+                DLOG_IS_ON(severity))
+#define BOOTSTRAP_DLOG_IF(severity, condition, bootstrap_err) \
+    LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
+                DLOG_IS_ON(severity) && (condition))
+
+#define BOOTSTRAP_DVLOG(verbose_level, bootstrap_err) \
+    LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
+                DVLOG_IS_ON(verbose_level))
+#define BOOTSTRAP_DVLOG_IF(verbose_level, condition, bootstrap_err) \
+    LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err) \
+                DVLOG_IS_ON(verbose_level) && (condition))
+
+#define BOOTSTRAP_DCHECK(condition, bootstrap_err) \
+    LAZY_STREAM(BOOTSTRAP_LOG_STREAM(FATAL, bootstrap_err), \
+                DCHECK_IS_ON && !(condition)) \
+    << "Check failed: " # condition << ". "
+
+#endif  // BASE_MAC_MACH_LOGGING_H_
diff --git a/base/mac/scoped_mach_vm.cc b/base/mac/scoped_mach_vm.cc
new file mode 100644
index 0000000..a9055aa
--- /dev/null
+++ b/base/mac/scoped_mach_vm.cc
@@ -0,0 +1,33 @@
+// 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.
+
+#include "base/mac/scoped_mach_vm.h"
+
+namespace base {
+namespace mac {
+
+void ScopedMachVM::reset(mach_vm_address_t address, mach_vm_size_t size) {
+  DCHECK(address % PAGE_SIZE == 0);
+  DCHECK(size % PAGE_SIZE == 0);
+
+  if (size_) {
+    if (address_ < address) {
+      mach_vm_deallocate(mach_task_self(),
+                         address_,
+                         std::min(size_, address - address_));
+    }
+    if (address_ + size_ > address + size) {
+      mach_vm_address_t deallocate_start = std::max(address_, address + size);
+      mach_vm_deallocate(mach_task_self(),
+                         deallocate_start,
+                         address_ + size_ - deallocate_start);
+    }
+  }
+
+  address_ = address;
+  size_ = size;
+}
+
+}  // namespace mac
+}  // namespace base
diff --git a/base/mac/scoped_mach_vm.h b/base/mac/scoped_mach_vm.h
new file mode 100644
index 0000000..065b968
--- /dev/null
+++ b/base/mac/scoped_mach_vm.h
@@ -0,0 +1,93 @@
+// 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.
+
+#ifndef BASE_MAC_SCOPED_MACH_VM_H_
+#define BASE_MAC_SCOPED_MACH_VM_H_
+
+#include <mach/mach.h>
+#include <mach/mach_vm.h>
+
+#include <algorithm>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+
+// Use ScopedMachVM to supervise ownership of pages in the current process
+// through the Mach VM subsystem. Pages allocated with mach_vm_allocate can be
+// released when exiting a scope with ScopedMachVM.
+//
+// The Mach VM subsystem operates on a page-by-page basis, and a single VM
+// allocation managed by a ScopedMachVM object may span multiple pages. As far
+// as Mach is concerned, allocated pages may be deallocated individually. This
+// is in contrast to higher-level allocators such as malloc, where the base
+// address of an allocation implies the size of an allocated block.
+// Consequently, it is not sufficient to just pass the base address of an
+// allocation to ScopedMachVM, it also needs to know the size of the
+// allocation. To avoid any confusion, both the base address and size must
+// be page-aligned.
+//
+// When dealing with Mach VM, base addresses will naturally be page-aligned,
+// but user-specified sizes may not be. If there's a concern that a size is
+// not page-aligned, use the mach_vm_round_page macro to correct it.
+//
+// Example:
+//
+//   mach_vm_address_t address = 0;
+//   mach_vm_size_t size = 12345;  // This requested size is not page-aligned.
+//   kern_return_t kr =
+//       mach_vm_allocate(mach_task_self(), &address, size, VM_FLAGS_ANYWHERE);
+//   if (kr != KERN_SUCCESS) {
+//     return false;
+//   }
+//   ScopedMachVM vm_owner(address, mach_vm_round_page(size));
+
+namespace base {
+namespace mac {
+
+class ScopedMachVM {
+ public:
+  explicit ScopedMachVM(mach_vm_address_t address = 0, mach_vm_size_t size = 0)
+      : address_(address),
+        size_(size) {
+    DCHECK(address % PAGE_SIZE == 0);
+    DCHECK(size % PAGE_SIZE == 0);
+  }
+
+  ~ScopedMachVM() {
+    if (size_) {
+      mach_vm_deallocate(mach_task_self(), address_, size_);
+    }
+  }
+
+  void reset(mach_vm_address_t address = 0, mach_vm_size_t size = 0);
+
+  mach_vm_address_t address() const {
+    return address_;
+  }
+
+  mach_vm_size_t size() const {
+    return size_;
+  }
+
+  void swap(ScopedMachVM& that) {
+    std::swap(address_, that.address_);
+    std::swap(size_, that.size_);
+  }
+
+  void release() {
+    address_ = 0;
+    size_ = 0;
+  }
+
+ private:
+  mach_vm_address_t address_;
+  mach_vm_size_t size_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedMachVM);
+};
+
+}  // namespace mac
+}  // namespace base
+
+#endif  // BASE_MAC_SCOPED_MACH_VM_H_
diff --git a/base/memory/discardable_memory_manager.cc b/base/memory/discardable_memory_manager.cc
index 6ede8a3..468690b 100644
--- a/base/memory/discardable_memory_manager.cc
+++ b/base/memory/discardable_memory_manager.cc
@@ -14,11 +14,10 @@
 namespace internal {
 namespace {
 
-// This is admittedly pretty magical. It's approximately enough memory for four
+// This is admittedly pretty magical. It's approximately enough memory for eight
 // 2560x1600 images.
-static const size_t kDefaultMemoryLimit = 64 * 1024 * 1024;
-static const size_t kDefaultBytesToKeepUnderModeratePressure =
-    kDefaultMemoryLimit / 4;
+static const size_t kDefaultMemoryLimit = 128 * 1024 * 1024;
+static const size_t kDefaultBytesToKeepUnderModeratePressure = 12 * 1024 * 1024;
 
 }  // namespace
 
diff --git a/base/observer_list_unittest.cc b/base/observer_list_unittest.cc
index 57843f4..1bda3dc 100644
--- a/base/observer_list_unittest.cc
+++ b/base/observer_list_unittest.cc
@@ -443,7 +443,7 @@
 
   EXPECT_TRUE(b.added);
   // B's adder should not have been notified because it was added during
-  // notificaiton.
+  // notification.
   EXPECT_EQ(0, b.adder.total);
 
   // Notify again to make sure b's adder is notified.
@@ -467,7 +467,7 @@
 
   EXPECT_TRUE(b.added);
   // B's adder should not have been notified because it was added during
-  // notificaiton.
+  // notification.
   EXPECT_EQ(0, b.adder.total);
 
   // Notify again to make sure b's adder is notified.
diff --git a/base/path_service.cc b/base/path_service.cc
index 61488d6..75833db 100644
--- a/base/path_service.cc
+++ b/base/path_service.cc
@@ -233,13 +233,15 @@
 
 // static
 bool PathService::Override(int key, const FilePath& path) {
-  // Just call the full function with true for the value of |create|.
-  return OverrideAndCreateIfNeeded(key, path, true);
+  // Just call the full function with true for the value of |create|, and
+  // assume that |path| may not be absolute yet.
+  return OverrideAndCreateIfNeeded(key, path, false, true);
 }
 
 // static
 bool PathService::OverrideAndCreateIfNeeded(int key,
                                             const FilePath& path,
+                                            bool is_absolute,
                                             bool create) {
   PathData* path_data = GetPathData();
   DCHECK(path_data);
@@ -259,9 +261,12 @@
   }
 
   // We need to have an absolute path.
-  file_path = MakeAbsoluteFilePath(file_path);
-  if (file_path.empty())
-    return false;
+  if (!is_absolute) {
+    file_path = MakeAbsoluteFilePath(file_path);
+    if (file_path.empty())
+      return false;
+  }
+  DCHECK(file_path.IsAbsolute());
 
   base::AutoLock scoped_lock(path_data->lock);
 
diff --git a/base/path_service.h b/base/path_service.h
index 9759754..554eb9e 100644
--- a/base/path_service.h
+++ b/base/path_service.h
@@ -46,11 +46,18 @@
   // one test should not carry over to another.
   static bool Override(int key, const base::FilePath& path);
 
-  // This function does the same as PathService::Override but it takes an extra
-  // parameter |create| which guides whether the directory to be overriden must
+  // This function does the same as PathService::Override but it takes extra
+  // parameters:
+  // - |is_absolute| indicates that |path| has already been expanded into an
+  // absolute path, otherwise MakeAbsoluteFilePath() will be used. This is
+  // useful to override paths that may not exist yet, since MakeAbsoluteFilePath
+  // fails for those. Note that MakeAbsoluteFilePath also expands symbolic
+  // links, even if path.IsAbsolute() is already true.
+  // - |create| guides whether the directory to be overriden must
   // be created in case it doesn't exist already.
   static bool OverrideAndCreateIfNeeded(int key,
                                         const base::FilePath& path,
+                                        bool is_absolute,
                                         bool create);
 
   // To extend the set of supported keys, you can register a path provider,
diff --git a/base/path_service_unittest.cc b/base/path_service_unittest.cc
index d5296cf..7a70a89 100644
--- a/base/path_service_unittest.cc
+++ b/base/path_service_unittest.cc
@@ -147,7 +147,7 @@
 #endif
 }
 
-// test that all versions of the Override function of PathService do what they
+// Test that all versions of the Override function of PathService do what they
 // are supposed to do.
 TEST_F(PathServiceTest, Override) {
   int my_special_key = 666;
@@ -163,12 +163,41 @@
   // PathService::OverrideAndCreateIfNeeded should obey the |create| parameter.
   PathService::OverrideAndCreateIfNeeded(my_special_key,
                                          fake_cache_dir2,
+                                         false,
                                          false);
   EXPECT_FALSE(base::PathExists(fake_cache_dir2));
   EXPECT_TRUE(PathService::OverrideAndCreateIfNeeded(my_special_key,
                                                      fake_cache_dir2,
+                                                     false,
                                                      true));
   EXPECT_TRUE(base::PathExists(fake_cache_dir2));
+
+#if defined(OS_POSIX)
+  base::FilePath non_existent(
+      base::MakeAbsoluteFilePath(temp_dir.path()).AppendASCII("non_existent"));
+  EXPECT_TRUE(non_existent.IsAbsolute());
+  EXPECT_FALSE(base::PathExists(non_existent));
+#if !defined(OS_ANDROID)
+  // This fails because MakeAbsoluteFilePath fails for non-existent files.
+  // Earlier versions of Bionic libc don't fail for non-existent files, so
+  // skip this check on Android.
+  EXPECT_FALSE(PathService::OverrideAndCreateIfNeeded(my_special_key,
+                                                      non_existent,
+                                                      false,
+                                                      false));
+#endif
+  // This works because indicating that |non_existent| is absolute skips the
+  // internal MakeAbsoluteFilePath call.
+  EXPECT_TRUE(PathService::OverrideAndCreateIfNeeded(my_special_key,
+                                                     non_existent,
+                                                     true,
+                                                     false));
+  // Check that the path has been overridden and no directory was created.
+  EXPECT_FALSE(base::PathExists(non_existent));
+  base::FilePath path;
+  EXPECT_TRUE(PathService::Get(my_special_key, &path));
+  EXPECT_EQ(non_existent, path);
+#endif
 }
 
 // Check if multiple overrides can co-exist.
diff --git a/base/security_unittest.cc b/base/security_unittest.cc
index fa067c8..960bc20 100644
--- a/base/security_unittest.cc
+++ b/base/security_unittest.cc
@@ -78,9 +78,10 @@
 // The sanitizers' calloc dies on OOM instead of returning NULL.
 // The wrapper function in base/process_util_linux.cc that is used when we
 // compile without TCMalloc will just die on OOM instead of returning NULL.
-#if !defined(OS_WIN) && (defined(ADDRESS_SANITIZER) || \
-    defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
-    (defined(OS_LINUX) && defined(NO_TCMALLOC)))
+#if defined(ADDRESS_SANITIZER) || \
+    defined(MEMORY_SANITIZER) || \
+    defined(THREAD_SANITIZER) || \
+    (defined(OS_LINUX) && defined(NO_TCMALLOC))
   return true;
 #else
   return false;
diff --git a/base/strings/string_util.cc b/base/strings/string_util.cc
index e514ac1..0adb989 100644
--- a/base/strings/string_util.cc
+++ b/base/strings/string_util.cc
@@ -324,8 +324,6 @@
   return input.find_first_not_of(characters) == StringPiece16::npos;
 }
 
-}  // namespace base
-
 template<class STR>
 static bool DoIsStringASCII(const STR& str) {
   for (size_t i = 0; i < str.length(); i++) {
@@ -336,11 +334,11 @@
   return true;
 }
 
-bool IsStringASCII(const base::StringPiece& str) {
+bool IsStringASCII(const StringPiece& str) {
   return DoIsStringASCII(str);
 }
 
-bool IsStringASCII(const base::string16& str) {
+bool IsStringASCII(const string16& str) {
   return DoIsStringASCII(str);
 }
 
@@ -352,12 +350,14 @@
   while (char_index < src_len) {
     int32 code_point;
     CBU8_NEXT(src, char_index, src_len, code_point);
-    if (!base::IsValidCharacter(code_point))
+    if (!IsValidCharacter(code_point))
       return false;
   }
   return true;
 }
 
+}  // namespace base
+
 template<typename Iter>
 static inline bool DoLowerCaseEqualsASCII(Iter a_begin,
                                           Iter a_end,
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index 473deae..9478a0c 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -234,16 +234,6 @@
 BASE_EXPORT bool ContainsOnlyChars(const StringPiece16& input,
                                    const StringPiece16& characters);
 
-}  // namespace base
-
-#if defined(OS_WIN)
-#include "base/strings/string_util_win.h"
-#elif defined(OS_POSIX)
-#include "base/strings/string_util_posix.h"
-#else
-#error Define string operations appropriately for your platform
-#endif
-
 // Returns true if the specified string matches the criteria. How can a wide
 // string be 8-bit or UTF8? It contains only characters that are < 256 (in the
 // first case) or characters that use only 8-bits and whose 8-bit
@@ -256,8 +246,18 @@
 // there's a use case for just checking the structural validity, we have to
 // add a new function for that.
 BASE_EXPORT bool IsStringUTF8(const std::string& str);
-BASE_EXPORT bool IsStringASCII(const base::StringPiece& str);
-BASE_EXPORT bool IsStringASCII(const base::string16& str);
+BASE_EXPORT bool IsStringASCII(const StringPiece& str);
+BASE_EXPORT bool IsStringASCII(const string16& str);
+
+}  // namespace base
+
+#if defined(OS_WIN)
+#include "base/strings/string_util_win.h"
+#elif defined(OS_POSIX)
+#include "base/strings/string_util_posix.h"
+#else
+#error Define string operations appropriately for your platform
+#endif
 
 // Converts the elements of the given string.  This version uses a pointer to
 // clearly differentiate it from the non-pointer variant.
diff --git a/base/strings/utf_string_conversions.h b/base/strings/utf_string_conversions.h
index e12e8a7..13e0b71 100644
--- a/base/strings/utf_string_conversions.h
+++ b/base/strings/utf_string_conversions.h
@@ -50,11 +50,4 @@
 
 }  // namespace base
 
-// We are trying to get rid of wstring as much as possible, but it's too big a
-// mess to do it all at once.  These synonyms should be used when we really
-// should just be passing a string16 around, but we haven't finished porting
-// whatever module uses wstring and the conversion is being used as a stopgap.
-// This makes it easy to grep for the ones that should be removed.
-#define WideToUTF16Hack WideToUTF16
-
 #endif  // BASE_STRINGS_UTF_STRING_CONVERSIONS_H_
diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-arm.mk b/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-arm.mk
index 56ff854..361d97a 100644
--- a/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-arm.mk
+++ b/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-arm.mk
@@ -39,7 +39,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -126,7 +125,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-x86.mk b/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-x86.mk
index 2923266..748b662 100644
--- a/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-x86.mk
+++ b/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-x86.mk
@@ -41,7 +41,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-x86_64.mk b/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-x86_64.mk
index 151f9ec..59d7604 100644
--- a/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-x86_64.mk
+++ b/base/third_party/dynamic_annotations/dynamic_annotations.target.darwin-x86_64.mk
@@ -41,7 +41,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-arm.mk b/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-arm.mk
index 56ff854..361d97a 100644
--- a/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-arm.mk
+++ b/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-arm.mk
@@ -39,7 +39,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -126,7 +125,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86.mk b/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86.mk
index 2923266..748b662 100644
--- a/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86.mk
+++ b/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86.mk
@@ -41,7 +41,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86_64.mk b/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86_64.mk
index 151f9ec..59d7604 100644
--- a/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86_64.mk
+++ b/base/third_party/dynamic_annotations/dynamic_annotations.target.linux-x86_64.mk
@@ -41,7 +41,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/base/win/dllmain.cc b/base/win/dllmain.cc
index 9d2a6dc..907c7f4 100644
--- a/base/win/dllmain.cc
+++ b/base/win/dllmain.cc
@@ -54,9 +54,9 @@
 
 #endif  // _WIN64
 
-// Explicitly depend on tlssup.cc variable to bracket the list of TLS callbacks.
-extern "C" PIMAGE_TLS_CALLBACK __xl_a;
-extern "C" PIMAGE_TLS_CALLBACK __xl_z;
+// Explicitly depend on VC\crt\src\tlssup.c variables
+// to bracket the list of TLS callbacks.
+extern "C" PIMAGE_TLS_CALLBACK __xl_a, __xl_z;
 
 // extern "C" suppresses C++ name mangling so we know the symbol names for the
 // linker /INCLUDE:symbol pragmas above.
diff --git a/build/all.gyp b/build/all.gyp
index ac14c86..d3f558f 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -604,11 +604,10 @@
           'target_name': 'chromium_builder_webrtc',
           'type': 'none',
           'dependencies': [
-            'chromium_builder_qa',  # needed for perf pyauto tests
+            'chromium_builder_qa',  # TODO(phoglund): not sure if needed?
             '../chrome/chrome.gyp:browser_tests',
             '../content/content_shell_and_tests.gyp:content_browsertests',
             '../content/content_shell_and_tests.gyp:content_unittests',
-            '../third_party/libjingle/libjingle.gyp:peerconnection_server',
             '../third_party/webrtc/tools/tools.gyp:frame_analyzer',
             '../third_party/webrtc/tools/tools.gyp:rgba_to_i420_converter',
           ],
@@ -642,6 +641,7 @@
           'conditions': [
             ['OS!="win"', {
               'dependencies': [
+                '../net/net.gyp:hpack_fuzz_wrapper',
                 '../net/net.gyp:dns_fuzz_stub',
                 '../skia/skia.gyp:filter_fuzz_stub',
               ],
@@ -973,6 +973,7 @@
           'dependencies': [
             '../cc/cc_tests.gyp:cc_unittests',
             '../chrome/chrome.gyp:browser_tests',
+            '../chrome/chrome.gyp:crash_service',
             '../chrome/chrome.gyp:gcapi_test',
             '../chrome/chrome.gyp:installer_util_unittests',
             '../chrome/chrome.gyp:interactive_ui_tests',
@@ -1012,6 +1013,13 @@
             '../url/url.gyp:url_unittests',
             '../webkit/renderer/compositor_bindings/compositor_bindings_tests.gyp:webkit_compositor_bindings_unittests',
           ],
+          'conditions': [
+            ['target_arch=="ia32"', {
+              'dependencies': [
+                '../chrome/chrome.gyp:crash_service_win64',
+              ],
+            }],
+          ],
         },
         {
           'target_name': 'chromium_builder_win_cf',
@@ -1058,6 +1066,7 @@
             '../ipc/ipc.gyp:ipc_tests',
             '../jingle/jingle.gyp:jingle_unittests',
             '../media/media.gyp:media_unittests',
+            '../mojo/mojo.gyp:mojo',
             '../net/net.gyp:net_unittests',
             '../google_apis/gcm/gcm.gyp:gcm_unit_tests',
             '../gpu/gpu.gyp:gpu_unittests',
diff --git a/build/android/adb_profile_chrome.py b/build/android/adb_profile_chrome.py
index 37f250c..2e25d9c 100755
--- a/build/android/adb_profile_chrome.py
+++ b/build/android/adb_profile_chrome.py
@@ -5,6 +5,7 @@
 # found in the LICENSE file.
 
 import gzip
+import json
 import logging
 import optparse
 import os
@@ -53,6 +54,28 @@
   def __str__(self):
     return 'chrome trace'
 
+  @staticmethod
+  def GetCategories(device, package_info):
+    device.old_interface.BroadcastIntent(
+        package_info.package, 'GPU_PROFILER_LIST_CATEGORIES')
+    try:
+      json_category_list = device.old_interface.WaitForLogMatch(
+          re.compile(r'{"traceCategoriesList(.*)'), None, timeout=5).group(0)
+    except pexpect.TIMEOUT:
+      raise RuntimeError('Performance trace category list marker not found. '
+                         'Is the correct version of the browser running?')
+
+    record_categories = []
+    disabled_by_default_categories = []
+    json_data = json.loads(json_category_list)['traceCategoriesList']
+    for item in json_data:
+      if item.startswith('disabled-by-default'):
+        disabled_by_default_categories.append(item)
+      else:
+        record_categories.append(item)
+
+    return record_categories, disabled_by_default_categories
+
   def StartTracing(self, interval):
     self._trace_interval = interval
     self._device.old_interface.SyncLogCat()
@@ -324,7 +347,8 @@
                         'categories with comma-delimited wildcards, '
                         'e.g., "*", "cat1*,-cat1a". Omit this option to trace '
                         'Chrome\'s default categories. Chrome tracing can be '
-                        'disabled with "--categories=\'\'".',
+                        'disabled with "--categories=\'\'". Use "list" to see '
+                        'the available categories.',
                         metavar='CHROME_CATEGORIES', dest='chrome_categories',
                         default=_DEFAULT_CHROME_CATEGORIES)
   categories.add_option('-s', '--systrace', help='Capture a systrace with the '
@@ -383,6 +407,25 @@
   if len(devices) != 1:
     parser.error('Exactly 1 device much be attached.')
   device = device_utils.DeviceUtils(devices[0])
+  package_info = _GetSupportedBrowsers()[options.browser]
+
+  if options.chrome_categories in ['list', 'help']:
+    _PrintMessage('Collecting record categories list...', eol='')
+    record_categories = []
+    disabled_by_default_categories = []
+    record_categories, disabled_by_default_categories = \
+        ChromeTracingController.GetCategories(device, package_info)
+
+    _PrintMessage('done')
+    _PrintMessage('Record Categories:')
+    _PrintMessage('\n'.join('\t%s' % item \
+        for item in sorted(record_categories)))
+
+    _PrintMessage('\nDisabled by Default Categories:')
+    _PrintMessage('\n'.join('\t%s' % item \
+        for item in sorted(disabled_by_default_categories)))
+
+    return 0
 
   if options.systrace_categories in ['list', 'help']:
     _PrintMessage('\n'.join(SystraceController.GetCategories(device)))
@@ -394,7 +437,6 @@
 
   chrome_categories = _ComputeChromeCategories(options)
   systrace_categories = _ComputeSystraceCategories(options)
-  package_info = _GetSupportedBrowsers()[options.browser]
 
   if chrome_categories and 'webview' in systrace_categories:
     logging.warning('Using the "webview" category in systrace together with '
diff --git a/build/android/buildbot/bb_device_status_check.py b/build/android/buildbot/bb_device_status_check.py
index f9998f4..94c741f 100755
--- a/build/android/buildbot/bb_device_status_check.py
+++ b/build/android/buildbot/bb_device_status_check.py
@@ -65,16 +65,13 @@
 
   ac_power = _GetData('AC powered: (\w+)', battery)
   battery_level = _GetData('level: (\d+)', battery)
-  battery_temp = _GetData('temperature: (\d+)', battery,
-                          lambda x: float(x) / 10.0)
   imei_slice = _GetData('Device ID = (\d+)',
                         device_adb.old_interface.GetSubscriberInfo(),
                         lambda x: x[-6:])
   report = ['Device %s (%s)' % (serial, device_type),
             '  Build: %s (%s)' %
               (device_build, device_adb.old_interface.GetBuildFingerprint()),
-            '  Battery: %s%%' % battery_level,
-            '  Battery temp: %s' % battery_temp,
+            '  %s' % '\n  '.join(battery.split('\n')),
             '  IMEI slice: %s' % imei_slice,
             '  Wifi IP: %s' % device_adb.old_interface.GetWifiIP(),
             '']
diff --git a/build/android/buildbot/bb_device_steps.py b/build/android/buildbot/bb_device_steps.py
index dc2212b..d955298 100755
--- a/build/android/buildbot/bb_device_steps.py
+++ b/build/android/buildbot/bb_device_steps.py
@@ -569,12 +569,12 @@
 def LogcatDump(options):
   # Print logcat, kill logcat monitor
   bb_annotations.PrintNamedStep('logcat_dump')
-  logcat_file = os.path.join(CHROME_OUT_DIR, options.target, 'full_log')
+  logcat_file = os.path.join(CHROME_OUT_DIR, options.target, 'full_log.txt')
   RunCmd([SrcPath('build' , 'android', 'adb_logcat_printer.py'),
           '--output-path', logcat_file, LOGCAT_DIR])
   gs_path = MakeGSPath(options, 'chromium-android/logcat_dumps')
-  RunCmd([bb_utils.GSUTIL_PATH, '-h', 'Content-Type:text/plain',
-          'cp', logcat_file, 'gs://%s' % gs_path])
+  RunCmd([bb_utils.GSUTIL_PATH, 'cp', '-z', 'txt', logcat_file,
+          'gs://%s' % gs_path])
   bb_annotations.PrintLink('logcat dump', '%s/%s' % (GS_AUTH_URL, gs_path))
 
 
@@ -584,7 +584,7 @@
   Stack tool is run for logcat dump, optionally for ASAN.
   """
   bb_annotations.PrintNamedStep('Run stack tool with logcat dump')
-  logcat_file = os.path.join(CHROME_OUT_DIR, options.target, 'full_log')
+  logcat_file = os.path.join(CHROME_OUT_DIR, options.target, 'full_log.txt')
   RunCmd([os.path.join(CHROME_SRC_DIR, 'third_party', 'android_platform',
           'development', 'scripts', 'stack'),
           '--more-info', logcat_file])
diff --git a/build/android/findbugs_filter/findbugs_known_bugs.txt b/build/android/findbugs_filter/findbugs_known_bugs.txt
index 3b825a6..6372d53 100644
--- a/build/android/findbugs_filter/findbugs_known_bugs.txt
+++ b/build/android/findbugs_filter/findbugs_known_bugs.txt
@@ -23,13 +23,5 @@
 M V EI: org.chromium.chrome.browser.ChromeBrowserProvider$BookmarkNode.favicon() may expose internal representation by returning ChromeBrowserProvider$BookmarkNode.mFavicon  At ChromeBrowserProvider.java
 M V EI: org.chromium.chrome.browser.ChromeBrowserProvider$BookmarkNode.thumbnail() may expose internal representation by returning ChromeBrowserProvider$BookmarkNode.mThumbnail  At ChromeBrowserProvider.java
 M V EI: org.chromium.content.browser.LoadUrlParams.getPostData() may expose internal representation by returning LoadUrlParams.mPostData  At LoadUrlParams.java
-M V MS: org.chromium.content.browser.LoadUrlParams.LOAD_TYPE_BROWSER_INITIATED_HTTP_POST should be package protected  In LoadUrlParams.java
-M V MS: org.chromium.content.browser.LoadUrlParams.LOAD_TYPE_DATA isn't final and can't be protected from malicious code   In LoadUrlParams.java
-M V MS: org.chromium.content.browser.LoadUrlParams.LOAD_TYPE_DEFAULT should be package protected  In LoadUrlParams.java
-M V MS: org.chromium.content.browser.LoadUrlParams.UA_OVERRIDE_INHERIT should be package protected  In LoadUrlParams.java
-M V MS: org.chromium.content.browser.LoadUrlParams.UA_OVERRIDE_TRUE isn't final and can't be protected from malicious code   In LoadUrlParams.java
 M M LI: Incorrect lazy initialization of static field org.chromium.chrome.browser.sync.ProfileSyncService.sSyncSetupManager in org.chromium.chrome.browser.sync.ProfileSyncService.get(Context)  At ProfileSyncService.java
 M B OS: org.chromium.tools.binary_size.Addr2LineWorkerPool$Addr2LineWorker$Addr2LineTask.run() may fail to close stream  At Addr2LineWorkerPool.java
-M B RV: Exceptional return value of java.io.File.mkdirs() ignored in new org.chromium.tools.binary_size.NmDumper$Output(NmDumper)  At NmDumper.java
-M C CSM: Shouldn't use synchronized method, please narrow down the synchronization scope.  At NmDumper.java
-M D REC: Exception is caught when Exception is not thrown in org.chromium.tools.binary_size.Addr2LineWorkerPool$Addr2LineWorker$Addr2LineTask.run()  At Addr2LineWorkerPool.java
diff --git a/build/android/pylib/android_commands.py b/build/android/pylib/android_commands.py
index 0a710f9..64eedb1 100644
--- a/build/android/pylib/android_commands.py
+++ b/build/android/pylib/android_commands.py
@@ -1160,25 +1160,33 @@
 
     This is less efficient than SetFileContents.
     """
+    # TODO(skyostil): Remove this once it has been through all the bots.
+    for file_name in (AndroidCommands._TEMP_FILE_BASE_FMT,
+                      AndroidCommands._TEMP_SCRIPT_FILE_BASE_FMT):
+      self.RunShellCommand('rm ' + self.GetExternalStorage() + '/' +
+                           file_name.replace('%d', '*'))
+
     temp_file = self._GetDeviceTempFileName(AndroidCommands._TEMP_FILE_BASE_FMT)
     temp_script = self._GetDeviceTempFileName(
         AndroidCommands._TEMP_SCRIPT_FILE_BASE_FMT)
 
-    # Put the contents in a temporary file
-    self.SetFileContents(temp_file, contents)
-    # Create a script to copy the file contents to its final destination
-    self.SetFileContents(temp_script, 'cat %s > %s' % (temp_file, filename))
+    try:
+      # Put the contents in a temporary file
+      self.SetFileContents(temp_file, contents)
+      # Create a script to copy the file contents to its final destination
+      self.SetFileContents(temp_script, 'cat %s > %s' % (temp_file, filename))
 
-    command = 'sh %s' % temp_script
-    command_runner = self._GetProtectedFileCommandRunner()
-    if command_runner:
-      return command_runner(command)
-    else:
-      logging.warning('Could not set contents of protected file: %s' % filename)
-
-    # And remove the temporary files
-    self.RunShellCommand('rm ' + temp_file)
-    self.RunShellCommand('rm ' + temp_script)
+      command = 'sh %s' % temp_script
+      command_runner = self._GetProtectedFileCommandRunner()
+      if command_runner:
+        return command_runner(command)
+      else:
+        logging.warning(
+            'Could not set contents of protected file: %s' % filename)
+    finally:
+      # And remove the temporary files
+      self.RunShellCommand('rm ' + temp_file)
+      self.RunShellCommand('rm ' + temp_script)
 
   def RemovePushedFiles(self):
     """Removes all files pushed with PushIfNeeded() from the device."""
@@ -1891,17 +1899,21 @@
                                     'android',
                                     'pylib',
                                     'efficient_android_directory_copy.sh')
-    self._adb.Push(host_script_path, temp_script_file)
-    self.EnableAdbRoot
-    out = self.RunShellCommand('sh %s %s %s' % (temp_script_file, source, dest),
-                               timeout_time=120)
-    if self._device:
-      device_repr = self._device[-4:]
-    else:
-      device_repr = '????'
-    for line in out:
-      logging.info('[%s]> %s', device_repr, line)
-    self.RunShellCommand('rm %s' % temp_script_file)
+    try:
+      self._adb.Push(host_script_path, temp_script_file)
+      self.EnableAdbRoot()
+      out = self.RunShellCommand('sh %s %s %s' % (temp_script_file,
+                                                  source,
+                                                  dest),
+                                 timeout_time=120)
+      if self._device:
+        device_repr = self._device[-4:]
+      else:
+        device_repr = '????'
+      for line in out:
+        logging.info('[%s]> %s', device_repr, line)
+    finally:
+      self.RunShellCommand('rm %s' % temp_script_file)
 
   def _GetControlUsbChargingCommand(self):
     if self._control_usb_charging_command['cached']:
diff --git a/build/android/pylib/gtest/filter/content_browsertests_disabled b/build/android/pylib/gtest/filter/content_browsertests_disabled
index 2978ce0..c96ce6c 100644
--- a/build/android/pylib/gtest/filter/content_browsertests_disabled
+++ b/build/android/pylib/gtest/filter/content_browsertests_disabled
@@ -120,6 +120,3 @@
 
 # http://crbug.com/343604
 MSE_ClearKey/EncryptedMediaTest.ConfigChangeVideo/0
-
-# http://crbug.com/362852
-WebRtcBrowserTests/WebRtcBrowserTest.*
diff --git a/build/android/pylib/gtest/filter/webkit_unit_tests_disabled b/build/android/pylib/gtest/filter/webkit_unit_tests_disabled
index 3e34a00..1ffa325 100644
--- a/build/android/pylib/gtest/filter/webkit_unit_tests_disabled
+++ b/build/android/pylib/gtest/filter/webkit_unit_tests_disabled
@@ -16,5 +16,10 @@
 # Disabled until blink roll r151682
 DeferredImageDecoderTest.drawScaledIntoSkPicture
 
+# Disabled until blink roll r173540
+DeferredImageDecoderTest.decodeOnOtherThread
+DeferredImageDecoderTest.drawIntoSkPicture
+DeferredImageDecoderTest.drawIntoSkPictureProgressive
+
 # crbug.com/320005
 CoreAnimationCompositorAnimationsTest.ConvertTimingForCompositorIterationCount
diff --git a/build/common.gypi b/build/common.gypi
index f49174b..def3eaf 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -332,6 +332,8 @@
       'safe_browsing%': 1,
 
       # Speech input is compiled in by default. Set to 0 to disable.
+      # TODO(tommyw): Speech Input doesn't exist anymore. Clarify the scope
+      # of this flag (and probably rename it).
       'input_speech%': 1,
 
       # Notifications are compiled in by default. Set to 0 to disable.
@@ -480,9 +482,16 @@
       # Enables used resource whitelist generation; disabled by default.
       'enable_resource_whitelist_generation%': 0,
 
+      # Enable FILE support by default.
+      'disable_file_support%': 0,
+
       # Enable FTP support by default.
       'disable_ftp_support%': 0,
 
+      # Use native android functions in place of ICU.  Not supported by most
+      # components.
+      'use_icu_alternatives_on_android%': 0,
+
       # XInput2 multitouch support is enabled by default (use_xi2_mt=2).
       # Setting to zero value disables XI2 MT. When XI2 MT is enabled,
       # the input value also defines the required XI2 minor minimum version.
@@ -811,10 +820,7 @@
 
         ['OS=="linux" and target_arch=="arm" and chromeos==0', {
           # Set some defaults for arm/linux chrome builds
-          # TODO(dmikurube): Change the default of use_allocator to "none".
-          # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-          'linux_use_tcmalloc%': 0,
-          'use_allocator%': 'see_use_tcmalloc',
+          'use_allocator%': 'none',
           # sysroot needs to be an absolute path otherwise it generates
           # incorrect results when passed to pkg-config
           'sysroot%': '<!(cd <(DEPTH) && pwd -P)/arm-sysroot',
@@ -853,12 +859,12 @@
           'test_isolation_mode%': 'noop',
         }],
         # Whether Android ARM or x86 build uses OpenMAX DL FFT.
-        ['OS=="android" and ((target_arch=="arm" and arm_version >= 7) or target_arch=="ia32" or target_arch=="x64") and android_webview_build==0', {
-          # Currently only supported on Android ARMv7+, ia32 or x64
-          # without webview.  When enabled, this will also enable
-          # WebAudio support on Android ARM, ia32 and x64.  Default is
-          # enabled.  Whether WebAudio is actually available depends
-          # on runtime settings and flags.
+        ['OS=="android" and ((target_arch=="arm" and arm_version >= 7) or target_arch=="ia32" or target_arch=="x64")', {
+          # Currently only supported on Android ARMv7+, ia32 or x64.
+          # When enabled, this will also enable WebAudio support on
+          # Android ARM, ia32 and x64.  Default is enabled.  Whether
+          # WebAudio is actually available depends on runtime settings
+          # and flags.
           'use_openmax_dl_fft%': 1,
         }, {
           'use_openmax_dl_fft%': 0,
@@ -1038,7 +1044,9 @@
     'cld2_dynamic%': '<(cld2_dynamic)',
     'cld2_is_component%': '<(cld2_is_component)',
     'enable_captive_portal_detection%': '<(enable_captive_portal_detection)',
+    'disable_file_support%': '<(disable_file_support)',
     'disable_ftp_support%': '<(disable_ftp_support)',
+    'use_icu_alternatives_on_android%': '<(use_icu_alternatives_on_android)',
     'enable_task_manager%': '<(enable_task_manager)',
     'sas_dll_path%': '<(sas_dll_path)',
     'wix_path%': '<(wix_path)',
@@ -1211,15 +1219,8 @@
     'binutils_dir%': '',
 
     # Enable TCMalloc.
-    # TODO(dmikurube): Change Linux default of use_allocator to "tcmalloc".
-    # TODO(dmikurube): Change Android default of use_allocator to "none".
-    # TODO(dmikurube): Kill {linux|android}_use_tcmalloc. http://crbug.com/345554
-    # {linux|android}_use_tcmalloc are to be replaced with use_allocator.
-    # They are now used only if use_allocator=="see_use_tcmalloc" (default).
-    # TODO(dmikurube): Assert when {linux|android}_use_tcmalloc is explicitly specified.
-    'linux_use_tcmalloc%': 1,
-    'android_use_tcmalloc%': 0,
-    'use_allocator%': 'see_use_tcmalloc',
+    # Default of 'use_allocator' is set to 'none' if OS=='android' later.
+    'use_allocator%': 'tcmalloc',
 
     # Set to 1 to link against libgnome-keyring instead of using dlopen().
     'linux_link_gnome_keyring%': 0,
@@ -1449,10 +1450,7 @@
             'werror%': '',
             'disable_nacl%': 1,
             'nacl_untrusted_build%': 0,
-            # TODO(dmikurube): Change the default of use_allocator to "none".
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            'linux_use_tcmalloc%': 0,
-            'use_allocator%': 'see_use_tcmalloc',
+            'use_allocator%': 'none',
           }],
           ['OS=="linux" and target_arch=="mipsel"', {
             'sysroot%': '<(sysroot)',
@@ -1639,10 +1637,7 @@
         'input_speech%': 0,
         'java_bridge%': 1,
         'build_ffmpegsumo%': 0,
-        # TODO(dmikurube): Change the default of use_allocator to "none".
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        'linux_use_tcmalloc%': 0,
-        'use_allocator%': 'see_use_tcmalloc',
+        'use_allocator%': 'none',
 
         # Disable Native Client.
         'disable_nacl%': 1,
@@ -2002,6 +1997,12 @@
         ],
       }],
 
+      ['OS=="win"', {
+        # The Clang plugins don't currently work on Windows.
+        # TODO(hans): One day, this will work. (crbug.com/82385)
+        'clang_use_chrome_plugins%': 0,
+      }],
+
       # On valgrind bots, override the optimizer settings so we don't inline too
       # much and make the stacks harder to figure out.
       #
@@ -2026,10 +2027,7 @@
         'win_release_InlineFunctionExpansion': '0',
         'win_release_OmitFramePointers': '0',
 
-        # TODO(dmikurube): Change the default of use_allocator to "tcmalloc".
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        'linux_use_tcmalloc%': 1,
-        'use_allocator': 'see_use_tcmalloc',
+        'use_allocator': 'tcmalloc',
         'release_valgrind_build': 1,
         'werror': '',
         'component': 'static_library',
@@ -2105,9 +2103,11 @@
         'ozone_platform%': "test",
 
         # Enable built-in ozone platforms if ozone is enabled.
+        'ozone_platform_caca%': 0,
         'ozone_platform_dri%': 1,
         'ozone_platform_test%': 1,
       }, {  # use_ozone==0
+        'ozone_platform_caca%': 0,
         'ozone_platform_dri%': 0,
         'ozone_platform_test%': 0,
       }],
@@ -2280,8 +2280,7 @@
           '<(DEPTH)/build/mac/asan.gyp:asan_dynamic_runtime',
         ],
       }],
-      # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-      ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)) and clang_type_profiler==1', {
+      ['OS=="linux" and use_allocator!="none" and clang_type_profiler==1', {
         'cflags_cc!': ['-fno-rtti'],
         'cflags_cc+': [
           '-frtti',
@@ -2389,9 +2388,6 @@
       ['configuration_policy==1', {
         'defines': ['ENABLE_CONFIGURATION_POLICY'],
       }],
-      ['input_speech==1', {
-        'defines': ['ENABLE_INPUT_SPEECH'],
-      }],
       ['notifications==1', {
         'defines': ['ENABLE_NOTIFICATIONS'],
       }],
@@ -2500,6 +2496,12 @@
           'ENABLE_EGLIMAGE=1',
         ],
       }],
+      ['asan==1', {
+        'defines': [
+          'ADDRESS_SANITIZER',
+          'MEMORY_TOOL_REPLACES_ALLOCATOR',
+        ],
+      }],
       ['syzyasan==1', {
         # SyzyAsan needs /PROFILE turned on to produce appropriate pdbs.
         'msvs_settings': {
@@ -2605,9 +2607,15 @@
       ['enable_settings_app==1', {
         'defines': ['ENABLE_SETTINGS_APP=1'],
       }],
+      ['disable_file_support==1', {
+        'defines': ['DISABLE_FILE_SUPPORT=1'],
+      }],
       ['disable_ftp_support==1', {
         'defines': ['DISABLE_FTP_SUPPORT=1'],
       }],
+      ['use_icu_alternatives_on_android==1', {
+        'defines': ['USE_ICU_ALTERNATIVES_ON_ANDROID=1'],
+      }],
       ['enable_managed_users==1', {
         'defines': ['ENABLE_MANAGED_USERS=1'],
       }],
@@ -3375,9 +3383,6 @@
                 'conditions': [
                   # Use gold linker for Android ia32 target.
                   ['OS=="android"', {
-                    'cflags': [
-                      '-fuse-ld=gold',
-                    ],
                     'ldflags': [
                       '-fuse-ld=gold',
                     ],
@@ -3403,9 +3408,6 @@
                 'conditions': [
                   # Use gold linker for Android x64 target.
                   ['OS=="android"', {
-                    'cflags': [
-                      '-fuse-ld=gold',
-                    ],
                     'ldflags': [
                       '-fuse-ld=gold',
                     ],
@@ -3469,7 +3471,6 @@
                       # compiler (r5-r7). This can be verified using
                       # webkit_unit_tests' WTF.Checked_int8_t test.
                       '-fno-tree-sra',
-                      '-fuse-ld=gold',
                       '-Wno-psabi',
                     ],
                     # Android now supports .relro sections properly.
@@ -3497,7 +3498,6 @@
                           '-mthumb-interwork',
                           '-finline-limit=64',
                           '-fno-tree-sra',
-                          '-fuse-ld=gold',
                           '-Wno-psabi',
                         ],
                         'cflags': [
@@ -3713,9 +3713,6 @@
                 'ldflags': [
                   '-fsanitize=address',
                 ],
-                'defines': [
-                  'ADDRESS_SANITIZER',
-                ],
               }],
             ],
             'conditions': [
@@ -3809,8 +3806,7 @@
           }],
           ['use_custom_libcxx==1', {
             'dependencies': [
-              '<(DEPTH)/third_party/libc++/libc++.gyp:libc++',
-              '<(DEPTH)/third_party/libc++abi/libc++abi.gyp:libc++abi',
+              '<(DEPTH)/third_party/libc++/libc++.gyp:libcxx_proxy',
             ],
           }],
           ['order_profiling!=0 and (chromeos==1 or OS=="linux" or OS=="android")', {
@@ -3849,8 +3845,7 @@
               }],
             ],
           }],
-          # TODO(dmikurube): Kill {linux|android}_use_tcmalloc. http://crbug.com/345554
-          ['use_allocator!="tcmalloc" and (use_allocator!="see_use_tcmalloc" or ((OS=="linux" and linux_use_tcmalloc==0) or (OS=="android" and android_use_tcmalloc==0)))', {
+          ['use_allocator!="tcmalloc"', {
             'defines': ['NO_TCMALLOC'],
           }],
           ['linux_use_gold_flags==1', {
@@ -3892,9 +3887,6 @@
               ['gcc_version>=48', {
                 'target_conditions': [
                   ['_toolset=="target"', {
-                    'cflags': [
-                      '-fuse-ld=gold',
-                    ],
                     'ldflags': [
                       '-fuse-ld=gold',
                     ],
@@ -3904,9 +3896,6 @@
               ['host_gcc_version>=48', {
                 'target_conditions': [
                   ['_toolset=="host"', {
-                    'cflags': [
-                      '-fuse-ld=gold',
-                    ],
                     'ldflags': [
                       '-fuse-ld=gold',
                     ],
@@ -4449,10 +4438,6 @@
                 '-w',  # http://crbug.com/162783
               ],
             },
-            'defines': [
-              'ADDRESS_SANITIZER',
-              'MEMORY_TOOL_REPLACES_ALLOCATOR',
-            ],
           }],
           ['asan_coverage!=0', {
             'target_conditions': [
@@ -5056,7 +5041,7 @@
               'VCLinkerTool': {
                 'AdditionalLibraryDirectories': [
                   # TODO(hans): If make_clang_dir is absolute, this breaks.
-                  '<(DEPTH)/<(make_clang_dir)/lib/clang/3.5/lib/windows',
+                  '<(DEPTH)/<(make_clang_dir)/lib/clang/3.5.0/lib/windows',
                 ],
               },
               'target_conditions': [
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index 866c9a8..d83a221 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -24,12 +24,10 @@
   # TODO(brettw) most of these need to be parameterized.
   defines = [
       "CHROMIUM_BUILD",
-      "USE_LIBJPEG_TURBO=1",
       "ENABLE_ONE_CLICK_SIGNIN",
       "ENABLE_REMOTING=1",
       "ENABLE_WEBRTC=1",
       "ENABLE_CONFIGURATION_POLICY",
-      "ENABLE_INPUT_SPEECH",
       "ENABLE_NOTIFICATIONS",
       "ENABLE_EGLIMAGE=1",
       "ENABLE_TASK_MANAGER=1",
diff --git a/build/config/clang/BUILD.gn b/build/config/clang/BUILD.gn
index f96bc73..00fb9e0 100644
--- a/build/config/clang/BUILD.gn
+++ b/build/config/clang/BUILD.gn
@@ -32,7 +32,7 @@
 # compile with these so may want to remove this config.
 config("extra_warnings") {
   cflags = [
-    "-Wheader-hygiene"
+    "-Wheader-hygiene",
 
     # Warns when a const char[] is converted to bool.
     "-Wstring-conversion",
diff --git a/build/copy_test_data_ios.gypi b/build/copy_test_data_ios.gypi
index 56a222f..576a0f2 100644
--- a/build/copy_test_data_ios.gypi
+++ b/build/copy_test_data_ios.gypi
@@ -34,7 +34,12 @@
 
 {
   'inputs': [
-    '<!@pymod_do_main(copy_test_data_ios --inputs <(test_data_files))',
+    # The |-o <(test_data_prefix)| is ignored; it is there to work around a
+    # caching bug in gyp (https://code.google.com/p/gyp/issues/detail?id=112).
+    # It caches command output when the string is the same, so if two copy
+    # steps have the same relative paths, there can be bogus cache hits that
+    # cause compile failures unless something varies.
+    '<!@pymod_do_main(copy_test_data_ios -o <(test_data_prefix) --inputs <(test_data_files))',
   ],
   'outputs': [
     '<!@pymod_do_main(copy_test_data_ios -o <(PRODUCT_DIR)/<(_target_name).app/<(test_data_prefix) --outputs <(test_data_files))',
diff --git a/build/download_nacl_toolchains.py b/build/download_nacl_toolchains.py
index 3a4cb1b..4895c1a 100755
--- a/build/download_nacl_toolchains.py
+++ b/build/download_nacl_toolchains.py
@@ -17,16 +17,16 @@
   src_dir = os.path.dirname(script_dir)
   nacl_dir = os.path.join(src_dir, 'native_client')
   nacl_build_dir = os.path.join(nacl_dir, 'build')
-  download_script = os.path.join(nacl_build_dir, 'download_toolchains.py')
-  if not os.path.exists(download_script):
-    print "Can't find '%s'" % download_script
+  package_version_dir = os.path.join(nacl_build_dir, 'package_version')
+  package_version = os.path.join(package_version_dir, 'package_version.py')
+  if not os.path.exists(package_version):
+    print "Can't find '%s'" % package_version
     print 'Presumably you are intentionally building without NativeClient.'
     print 'Skipping NativeClient toolchain download.'
     sys.exit(0)
-  sys.path.insert(0, nacl_build_dir)
-  import download_toolchains
+  sys.path.insert(0, package_version_dir)
+  import package_version
 
-  # TODO (robertm): Finish getting PNaCl ready for prime time.
   # BUG:
   # We remove this --optional-pnacl argument, and instead replace it with
   # --no-pnacl for most cases.  However, if the bot name is an sdk
@@ -41,21 +41,17 @@
     if use_pnacl:
       print '\n*** DOWNLOADING PNACL TOOLCHAIN ***\n'
     else:
-      args.append('--no-pnacl')
+      args.extend(['--exclude', 'pnacl_newlib'])
 
   # Only download the ARM gcc toolchain if we are building for ARM
   # TODO(olonho): we need to invent more reliable way to get build
   # configuration info, to know if we're building for ARM.
-  if 'target_arch=arm' in os.environ.get('GYP_DEFINES', ''):
-      args.append('--arm-untrusted')
+  if 'target_arch=arm' not in os.environ.get('GYP_DEFINES', ''):
+      args.extend(['--exclude', 'nacl_arm_newlib'])
 
-  # Append the name of the file to use as a version and hash source.
-  # NOTE:  While not recommended, it is possible to redirect this file to
-  # a chrome location to avoid branching NaCl if just a toolchain needs
-  # to be bumped.
-  args.append(os.path.join(nacl_dir, 'TOOL_REVISIONS'))
-
-  download_toolchains.main(args)
+  args.append('sync')
+  args.append('--extract')
+  package_version.main(args)
   return 0
 
 
diff --git a/build/filename_rules.gypi b/build/filename_rules.gypi
index 001b975..8b49202 100644
--- a/build/filename_rules.gypi
+++ b/build/filename_rules.gypi
@@ -72,7 +72,7 @@
       ],
     }],
     ['<(toolkit_views)==0 or >(nacl_untrusted_build)==1', {
-      'sources/': [ ['exclude', '_views\\.(h|cc)$'] ]
+      'sources/': [ ['exclude', '_views(_browsertest|_unittest)?\\.(h|cc)$'] ]
     }],
     ['<(use_aura)==0 or >(nacl_untrusted_build)==1', {
       'sources/': [ ['exclude', '_aura(_browsertest|_unittest)?\\.(h|cc)$'],
diff --git a/build/gyp_chromium b/build/gyp_chromium
index 201e5a0..26028dc 100755
--- a/build/gyp_chromium
+++ b/build/gyp_chromium
@@ -277,6 +277,17 @@
   supplemental_includes = GetSupplementalFiles()
   gyp_vars_dict = GetGypVars(supplemental_includes)
 
+  # TODO(dmikurube): Remove these checks and messages after a while.
+  if ('linux_use_tcmalloc' in gyp_vars_dict or
+      'android_use_tcmalloc' in gyp_vars_dict):
+    print '*****************************************************************'
+    print '"linux_use_tcmalloc" and "android_use_tcmalloc" are deprecated!'
+    print '-----------------------------------------------------------------'
+    print 'You specify "linux_use_tcmalloc" or "android_use_tcmalloc" in'
+    print 'your GYP_DEFINES. Please switch them into "use_allocator" now.'
+    print 'See http://crbug.com/345554 for the details.'
+    print '*****************************************************************'
+
   # Automatically turn on crosscompile support for platforms that need it.
   # (The Chrome OS build sets CC_host / CC_target which implicitly enables
   # this mode.)
diff --git a/build/ios/grit_whitelist.txt b/build/ios/grit_whitelist.txt
index a9f660b..e7673e4 100644
--- a/build/ios/grit_whitelist.txt
+++ b/build/ios/grit_whitelist.txt
@@ -833,12 +833,6 @@
 IDS_SIGNED_IN_WITH_SYNC_DISABLED
 IDS_SIGNED_IN_WITH_SYNC_SUPPRESSED
 IDS_SIGNIN_ERROR_BUBBLE_VIEW_TITLE
-IDS_SPEECH_INPUT_ABORTED
-IDS_SPEECH_INPUT_MIC_ERROR
-IDS_SPEECH_INPUT_NET_ERROR
-IDS_SPEECH_INPUT_NO_MIC
-IDS_SPEECH_INPUT_NO_RESULTS
-IDS_SPEECH_INPUT_NO_SPEECH
 IDS_SSL_BLOCKING_PAGE_TITLE
 IDS_SYNC_ACCOUNT_SYNCING_TO_USER
 IDS_SYNC_ACCOUNT_SYNCING_TO_USER_WITH_MANAGE_LINK
diff --git a/build/util/LASTCHANGE b/build/util/LASTCHANGE
index 7eb6be5..f21b849 100644
--- a/build/util/LASTCHANGE
+++ b/build/util/LASTCHANGE
@@ -1 +1 @@
-LASTCHANGE=267519
+LASTCHANGE=269336
diff --git a/build/util/LASTCHANGE.blink b/build/util/LASTCHANGE.blink
index 47cd938..b18a46f 100644
--- a/build/util/LASTCHANGE.blink
+++ b/build/util/LASTCHANGE.blink
@@ -1 +1 @@
-LASTCHANGE=173042
+LASTCHANGE=173743
diff --git a/build/whitespace_file.txt b/build/whitespace_file.txt
index 57d555c..6cc0abe 100644
--- a/build/whitespace_file.txt
+++ b/build/whitespace_file.txt
@@ -88,3 +88,5 @@
 
 
 Hello from tutorial!
+
+I want a 1917 build and you will give me what I want.
diff --git a/cc/animation/animation.cc b/cc/animation/animation.cc
index 1af35d2..2e924ac 100644
--- a/cc/animation/animation.cc
+++ b/cc/animation/animation.cc
@@ -65,7 +65,7 @@
       run_state_(WaitingForTargetAvailability),
       iterations_(1),
       start_time_(0),
-      alternates_direction_(false),
+      direction_(Normal),
       time_offset_(0),
       needs_synchronized_start_time_(false),
       received_finished_event_(false),
@@ -176,8 +176,8 @@
       needs_synchronized_start_time())
     trimmed = time_offset_;
 
-  // Zero is always the start of the animation.
-  if (trimmed <= 0)
+  // Return 0 if we are before the start of the animation
+  if (trimmed < 0)
     return 0;
 
   // Always return zero if we have no iterations.
@@ -188,26 +188,32 @@
   if (curve_->Duration() <= 0)
     return 0;
 
-  // If less than an iteration duration, just return trimmed.
-  if (trimmed < curve_->Duration())
-    return trimmed;
-
-  // If greater than or equal to the total duration, return iteration duration.
-  if (iterations_ >= 0 && trimmed >= curve_->Duration() * iterations_) {
-    if (alternates_direction_ && !(iterations_ % 2))
-      return 0;
-    return curve_->Duration();
-  }
+  // check if we are past active interval
+  bool is_past_total_duration =
+      (iterations_ > 0 && trimmed >= curve_->Duration() * iterations_);
 
   // We need to know the current iteration if we're alternating.
-  int iteration = static_cast<int>(trimmed / curve_->Duration());
+  int iteration = 0;
 
-  // Calculate x where trimmed = x + n * curve_->Duration() for some positive
-  // integer n.
-  trimmed = fmod(trimmed, curve_->Duration());
+  // If we are past the active interval, return iteration duration.
+  if (is_past_total_duration) {
+    iteration = iterations_ - 1;
+    trimmed = curve_->Duration();
+  } else {
+    iteration = static_cast<int>(trimmed / curve_->Duration());
+    // Calculate x where trimmed = x + n * curve_->Duration() for some positive
+    // integer n.
+    trimmed = fmod(trimmed, curve_->Duration());
+  }
 
-  // If we're alternating and on an odd iteration, reverse the direction.
-  if (alternates_direction_ && iteration % 2 == 1)
+  // check if we are running the animation in reverse direction for the current
+  // iteration
+  bool reverse = (direction_ == Reverse) ||
+                 (direction_ == Alternate && iteration % 2 == 1) ||
+                 (direction_ == AlternateReverse && iteration % 2 == 0);
+
+  // if we are running the animation in reverse direction, reverse the result
+  if (reverse)
     return curve_->Duration() - trimmed;
 
   return trimmed;
@@ -223,7 +229,7 @@
   to_return->pause_time_ = pause_time_;
   to_return->total_paused_time_ = total_paused_time_;
   to_return->time_offset_ = time_offset_;
-  to_return->alternates_direction_ = alternates_direction_;
+  to_return->direction_ = direction_;
   DCHECK(!to_return->is_controlling_instance_);
   to_return->is_controlling_instance_ = true;
   return to_return.Pass();
diff --git a/cc/animation/animation.h b/cc/animation/animation.h
index ecc48b5..e4476ff 100644
--- a/cc/animation/animation.h
+++ b/cc/animation/animation.h
@@ -48,6 +48,8 @@
     TargetPropertyEnumSize
   };
 
+  enum Direction { Normal, Reverse, Alternate, AlternateReverse };
+
   static scoped_ptr<Animation> Create(scoped_ptr<AnimationCurve> curve,
                                       int animation_id,
                                       int group_id,
@@ -78,12 +80,8 @@
   void Suspend(double monotonic_time);
   void Resume(double monotonic_time);
 
-  // If alternates_direction is true, on odd numbered iterations we reverse the
-  // curve.
-  bool alternates_direction() const { return alternates_direction_; }
-  void set_alternates_direction(bool alternates) {
-    alternates_direction_ = alternates;
-  }
+  Direction direction() { return direction_; }
+  void set_direction(Direction direction) { direction_ = direction; }
 
   bool IsFinishedAt(double monotonic_time) const;
   bool is_finished() const {
@@ -158,7 +156,7 @@
   RunState run_state_;
   int iterations_;
   double start_time_;
-  bool alternates_direction_;
+  Direction direction_;
 
   // The time offset effectively pushes the start of the animation back in time.
   // This is used for resuming paused animations -- an animation is added with a
diff --git a/cc/animation/animation_unittest.cc b/cc/animation/animation_unittest.cc
index 8223cee..7768ceb 100644
--- a/cc/animation/animation_unittest.cc
+++ b/cc/animation/animation_unittest.cc
@@ -49,15 +49,89 @@
   EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(1.5));
 }
 
-TEST(AnimationTest, TrimTimeAlternating) {
+TEST(AnimationTest, TrimTimeReverse) {
   scoped_ptr<Animation> anim(CreateAnimation(-1));
-  anim->set_alternates_direction(true);
-  EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(0.0));
+  anim->set_direction(Animation::Reverse);
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0));
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.25));
   EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
-  EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1.0));
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.75));
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(1.0));
   EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1.25));
 }
 
+TEST(AnimationTest, TrimTimeAlternateInfiniteIterations) {
+  scoped_ptr<Animation> anim(CreateAnimation(-1));
+  anim->set_direction(Animation::Alternate);
+  EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(0.0));
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.25));
+  EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.75));
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(1.0));
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1.25));
+}
+
+TEST(AnimationTest, TrimTimeAlternateOneIteration) {
+  scoped_ptr<Animation> anim(CreateAnimation(1));
+  anim->set_direction(Animation::Alternate);
+  EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(0.0));
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.25));
+  EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.75));
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(1.0));
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(1.25));
+}
+
+TEST(AnimationTest, TrimTimeAlternateTwoIterations) {
+  scoped_ptr<Animation> anim(CreateAnimation(2));
+  anim->set_direction(Animation::Alternate);
+  EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(0.0));
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.25));
+  EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.75));
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(1.0));
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1.25));
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(1.75));
+  EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(2.0));
+  EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(2.25));
+}
+
+TEST(AnimationTest, TrimTimeAlternateReverseInfiniteIterations) {
+  scoped_ptr<Animation> anim(CreateAnimation(-1));
+  anim->set_direction(Animation::AlternateReverse);
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0));
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.25));
+  EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.75));
+  EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(1.0));
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(1.25));
+}
+
+TEST(AnimationTest, TrimTimeAlternateReverseOneIteration) {
+  scoped_ptr<Animation> anim(CreateAnimation(1));
+  anim->set_direction(Animation::AlternateReverse);
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0));
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.25));
+  EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.75));
+  EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(1.0));
+  EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(1.25));
+}
+
+TEST(AnimationTest, TrimTimeAlternateReverseTwoIterations) {
+  scoped_ptr<Animation> anim(CreateAnimation(2));
+  anim->set_direction(Animation::AlternateReverse);
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0));
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.25));
+  EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.75));
+  EXPECT_EQ(0.0, anim->TrimTimeToCurrentIteration(1.0));
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(1.25));
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1.75));
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(2.0));
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(2.25));
+}
+
 TEST(AnimationTest, TrimTimeStartTime) {
   scoped_ptr<Animation> anim(CreateAnimation(1));
   anim->set_start_time(4);
@@ -68,6 +142,17 @@
   EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(6.0));
 }
 
+TEST(AnimationTest, TrimTimeStartTimeReverse) {
+  scoped_ptr<Animation> anim(CreateAnimation(1));
+  anim->set_start_time(4);
+  anim->set_direction(Animation::Reverse);
+  EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(0.0));
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(4.0));
+  EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(4.5));
+  EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(5.0));
+  EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(6.0));
+}
+
 TEST(AnimationTest, TrimTimeTimeOffset) {
   scoped_ptr<Animation> anim(CreateAnimation(1));
   anim->set_time_offset(4);
@@ -78,6 +163,17 @@
   EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1.0));
 }
 
+TEST(AnimationTest, TrimTimeTimeOffsetReverse) {
+  scoped_ptr<Animation> anim(CreateAnimation(1));
+  anim->set_time_offset(4);
+  anim->set_start_time(4);
+  anim->set_direction(Animation::Reverse);
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0));
+  EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+  EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1.0));
+  EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1.0));
+}
+
 TEST(AnimationTest, TrimTimeNegativeTimeOffset) {
   scoped_ptr<Animation> anim(CreateAnimation(1));
   anim->set_time_offset(-4);
@@ -88,6 +184,17 @@
   EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(5.0));
 }
 
+TEST(AnimationTest, TrimTimeNegativeTimeOffsetReverse) {
+  scoped_ptr<Animation> anim(CreateAnimation(1));
+  anim->set_time_offset(-4);
+  anim->set_direction(Animation::Reverse);
+
+  EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(0.0));
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(4.0));
+  EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(4.5));
+  EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(5.0));
+}
+
 TEST(AnimationTest, TrimTimePauseResume) {
   scoped_ptr<Animation> anim(CreateAnimation(1));
   anim->SetRunState(Animation::Running, 0.0);
@@ -100,6 +207,19 @@
   EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1024.5));
 }
 
+TEST(AnimationTest, TrimTimePauseResumeReverse) {
+  scoped_ptr<Animation> anim(CreateAnimation(1));
+  anim->set_direction(Animation::Reverse);
+  anim->SetRunState(Animation::Running, 0.0);
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0));
+  EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+  anim->SetRunState(Animation::Paused, 0.25);
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1024.0));
+  anim->SetRunState(Animation::Running, 1024.0);
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1024.0));
+  EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1024.75));
+}
+
 TEST(AnimationTest, TrimTimeSuspendResume) {
   scoped_ptr<Animation> anim(CreateAnimation(1));
   anim->SetRunState(Animation::Running, 0.0);
@@ -112,6 +232,19 @@
   EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1024.5));
 }
 
+TEST(AnimationTest, TrimTimeSuspendResumeReverse) {
+  scoped_ptr<Animation> anim(CreateAnimation(1));
+  anim->set_direction(Animation::Reverse);
+  anim->SetRunState(Animation::Running, 0.0);
+  EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0));
+  EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.25));
+  anim->Suspend(0.75);
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(1024.0));
+  anim->Resume(1024);
+  EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(1024.0));
+  EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1024.25));
+}
+
 TEST(AnimationTest, TrimTimeZeroDuration) {
   scoped_ptr<Animation> anim(CreateAnimation(0, 0));
   anim->SetRunState(Animation::Running, 0.0);
diff --git a/cc/animation/layer_animation_controller.cc b/cc/animation/layer_animation_controller.cc
index 239a29a..58b26d7 100644
--- a/cc/animation/layer_animation_controller.cc
+++ b/cc/animation/layer_animation_controller.cc
@@ -26,7 +26,9 @@
       is_active_(false),
       last_tick_time_(0),
       value_provider_(NULL),
-      layer_animation_delegate_(NULL) {}
+      layer_animation_delegate_(NULL),
+      needs_to_start_animations_(false) {
+}
 
 LayerAnimationController::~LayerAnimationController() {
   if (registrar_)
@@ -126,7 +128,8 @@
   if (!HasValueObserver())
     return;
 
-  StartAnimations(monotonic_time);
+  if (needs_to_start_animations_)
+    StartAnimations(monotonic_time);
   TickAnimations(monotonic_time);
   last_tick_time_ = monotonic_time;
 }
@@ -210,7 +213,7 @@
   MarkFinishedAnimations(last_tick_time_);
   MarkAnimationsForDeletion(last_tick_time_, events);
 
-  if (start_ready_animations) {
+  if (needs_to_start_animations_ && start_ready_animations) {
     StartAnimations(last_tick_time_);
     PromoteStartedAnimations(last_tick_time_, events);
   }
@@ -242,6 +245,7 @@
 
 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
   animations_.push_back(animation.Pass());
+  needs_to_start_animations_ = true;
   UpdateActivation(NormalActivation);
 }
 
@@ -599,6 +603,8 @@
 }
 
 void LayerAnimationController::StartAnimations(double monotonic_time) {
+  DCHECK(needs_to_start_animations_);
+  needs_to_start_animations_ = false;
   // First collect running properties affecting each type of observer.
   TargetProperties blocked_properties_for_active_observers;
   TargetProperties blocked_properties_for_pending_observers;
@@ -663,6 +669,8 @@
             animations_[j]->SetRunState(Animation::Starting, monotonic_time);
           }
         }
+      } else {
+        needs_to_start_animations_ = true;
       }
     }
   }
diff --git a/cc/animation/layer_animation_controller.h b/cc/animation/layer_animation_controller.h
index c98a879..bf54a14 100644
--- a/cc/animation/layer_animation_controller.h
+++ b/cc/animation/layer_animation_controller.h
@@ -132,6 +132,10 @@
   // animations. Returns false if the maximum scale cannot be computed.
   bool MaximumScale(float* max_scale) const;
 
+  bool needs_to_start_animations_for_testing() {
+    return needs_to_start_animations_;
+  }
+
  protected:
   friend class base::RefCounted<LayerAnimationController>;
 
@@ -198,6 +202,10 @@
 
   AnimationDelegate* layer_animation_delegate_;
 
+  // Only try to start animations when new animations are added or when the
+  // previous attempt at starting animations failed to start all animations.
+  bool needs_to_start_animations_;
+
   DISALLOW_COPY_AND_ASSIGN(LayerAnimationController);
 };
 
diff --git a/cc/animation/layer_animation_controller_unittest.cc b/cc/animation/layer_animation_controller_unittest.cc
index a6a5363..e172f72 100644
--- a/cc/animation/layer_animation_controller_unittest.cc
+++ b/cc/animation/layer_animation_controller_unittest.cc
@@ -43,10 +43,15 @@
 
   EXPECT_FALSE(controller_impl->GetAnimation(Animation::Opacity));
 
+  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());
+  EXPECT_FALSE(controller_impl->needs_to_start_animations_for_testing());
+
   AddOpacityTransitionToController(controller.get(), 1, 0, 1, false);
+  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());
   int group_id = controller->GetAnimation(Animation::Opacity)->group();
 
   controller->PushAnimationUpdatesTo(controller_impl.get());
+  EXPECT_TRUE(controller_impl->needs_to_start_animations_for_testing());
   controller_impl->ActivateAnimations();
 
   EXPECT_TRUE(controller_impl->GetAnimation(group_id, Animation::Opacity));
@@ -421,8 +426,11 @@
       1,
       Animation::Opacity));
 
+  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());
   controller->AddAnimation(to_add.Pass());
+  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());
   controller->Animate(kInitialTickTime);
+  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());
   controller->UpdateState(true, events.get());
   EXPECT_TRUE(controller->HasActiveAnimation());
   EXPECT_EQ(0.f, dummy.opacity());
@@ -962,6 +970,8 @@
       LayerAnimationController::Create(0));
   controller->AddValueObserver(&dummy);
 
+  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());
+
   controller->AddAnimation(CreateAnimation(
       scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(),
       1,
@@ -972,12 +982,22 @@
       2,
       Animation::Opacity));
 
+  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());
+
   controller->Animate(kInitialTickTime);
+
+  // The second animation still needs to be started.
+  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());
+
   controller->UpdateState(true, events.get());
   EXPECT_TRUE(controller->HasActiveAnimation());
   EXPECT_EQ(0.f, dummy.opacity());
   controller->Animate(kInitialTickTime + 1.0);
+
+  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());
   controller->UpdateState(true, events.get());
+  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());
+
   EXPECT_TRUE(controller->HasActiveAnimation());
   EXPECT_EQ(1.f, dummy.opacity());
   controller->Animate(kInitialTickTime + 2.0);
@@ -1942,10 +1962,14 @@
       LayerAnimationController::Create(0));
   controller->AddValueObserver(&dummy);
 
+  EXPECT_FALSE(controller->needs_to_start_animations_for_testing());
   AddOpacityTransitionToController(controller.get(), 1, 0.5f, 1.f, false);
   int group_id = controller->GetAnimation(Animation::Opacity)->group();
+  EXPECT_TRUE(controller->needs_to_start_animations_for_testing());
 
+  EXPECT_FALSE(controller_impl->needs_to_start_animations_for_testing());
   controller->PushAnimationUpdatesTo(controller_impl.get());
+  EXPECT_TRUE(controller_impl->needs_to_start_animations_for_testing());
 
   EXPECT_TRUE(controller_impl->GetAnimation(group_id, Animation::Opacity));
   EXPECT_EQ(
@@ -1957,6 +1981,7 @@
                    ->affects_active_observers());
 
   controller_impl->Animate(kInitialTickTime);
+  EXPECT_FALSE(controller_impl->needs_to_start_animations_for_testing());
   controller_impl->UpdateState(true, events.get());
 
   // Since the animation hasn't been activated, it should still be Starting
diff --git a/cc/animation/scrollbar_animation_controller.cc b/cc/animation/scrollbar_animation_controller.cc
new file mode 100644
index 0000000..910a7d8
--- /dev/null
+++ b/cc/animation/scrollbar_animation_controller.cc
@@ -0,0 +1,96 @@
+// 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.
+
+#include "cc/animation/scrollbar_animation_controller.h"
+
+#include <algorithm>
+
+#include "base/time/time.h"
+
+namespace cc {
+
+ScrollbarAnimationController::ScrollbarAnimationController(
+    ScrollbarAnimationControllerClient* client,
+    base::TimeDelta delay_before_starting,
+    base::TimeDelta duration)
+    : client_(client),
+      delay_before_starting_(delay_before_starting),
+      duration_(duration),
+      is_animating_(false),
+      currently_scrolling_(false),
+      scroll_gesture_has_scrolled_(false),
+      weak_factory_(this) {
+}
+
+ScrollbarAnimationController::~ScrollbarAnimationController() {
+}
+
+void ScrollbarAnimationController::Animate(base::TimeTicks now) {
+  if (!is_animating_)
+    return;
+
+  if (last_awaken_time_.is_null())
+    last_awaken_time_ = now;
+
+  float progress = AnimationProgressAtTime(now);
+  RunAnimationFrame(progress);
+
+  if (is_animating_) {
+    delayed_scrollbar_fade_.Cancel();
+    client_->SetNeedsScrollbarAnimationFrame();
+  }
+}
+
+float ScrollbarAnimationController::AnimationProgressAtTime(
+    base::TimeTicks now) {
+  base::TimeDelta delta = now - last_awaken_time_;
+  float progress = delta.InSecondsF() / duration_.InSecondsF();
+  return std::max(std::min(progress, 1.f), 0.f);
+}
+
+void ScrollbarAnimationController::DidScrollBegin() {
+  currently_scrolling_ = true;
+}
+
+void ScrollbarAnimationController::DidScrollUpdate() {
+  StopAnimation();
+  delayed_scrollbar_fade_.Cancel();
+
+  // As an optimization, we avoid spamming fade delay tasks during active fast
+  // scrolls.  But if we're not within one, we need to post every scroll update.
+  if (!currently_scrolling_)
+    PostDelayedFade();
+  else
+    scroll_gesture_has_scrolled_ = true;
+}
+
+void ScrollbarAnimationController::DidScrollEnd() {
+  if (scroll_gesture_has_scrolled_) {
+    PostDelayedFade();
+    scroll_gesture_has_scrolled_ = false;
+  }
+
+  currently_scrolling_ = false;
+}
+
+void ScrollbarAnimationController::PostDelayedFade() {
+  delayed_scrollbar_fade_.Reset(
+      base::Bind(&ScrollbarAnimationController::StartAnimation,
+                 weak_factory_.GetWeakPtr()));
+  client_->PostDelayedScrollbarFade(delayed_scrollbar_fade_.callback(),
+                                    delay_before_starting_);
+}
+
+void ScrollbarAnimationController::StartAnimation() {
+  delayed_scrollbar_fade_.Cancel();
+  is_animating_ = true;
+  last_awaken_time_ = base::TimeTicks();
+  client_->SetNeedsScrollbarAnimationFrame();
+}
+
+void ScrollbarAnimationController::StopAnimation() {
+  is_animating_ = false;
+}
+
+}  // namespace cc
diff --git a/cc/animation/scrollbar_animation_controller.h b/cc/animation/scrollbar_animation_controller.h
index ecef4fb..ad7f631 100644
--- a/cc/animation/scrollbar_animation_controller.h
+++ b/cc/animation/scrollbar_animation_controller.h
@@ -5,30 +5,66 @@
 #ifndef CC_ANIMATION_SCROLLBAR_ANIMATION_CONTROLLER_H_
 #define CC_ANIMATION_SCROLLBAR_ANIMATION_CONTROLLER_H_
 
+#include "base/cancelable_callback.h"
+#include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "cc/base/cc_export.h"
 #include "ui/gfx/vector2d_f.h"
 
 namespace cc {
 
+class CC_EXPORT ScrollbarAnimationControllerClient {
+ public:
+  virtual ~ScrollbarAnimationControllerClient() {}
+
+  virtual void PostDelayedScrollbarFade(const base::Closure& start_fade,
+                                        base::TimeDelta delay) = 0;
+  virtual void SetNeedsScrollbarAnimationFrame() = 0;
+};
+
 // This abstract class represents the compositor-side analogy of
 // ScrollbarAnimator.  Individual platforms should subclass it to provide
 // specialized implementation.
 class CC_EXPORT ScrollbarAnimationController {
  public:
-  virtual ~ScrollbarAnimationController() {}
+  virtual ~ScrollbarAnimationController();
 
-  virtual bool IsAnimating() const = 0;
-  virtual base::TimeDelta DelayBeforeStart(base::TimeTicks now) const = 0;
+  void Animate(base::TimeTicks now);
 
-  virtual bool Animate(base::TimeTicks now) = 0;
-  virtual void DidScrollGestureBegin() = 0;
-  virtual void DidScrollGestureEnd(base::TimeTicks now) = 0;
-  virtual void DidMouseMoveOffScrollbar(base::TimeTicks now) = 0;
+  virtual void DidScrollBegin();
+  virtual void DidScrollUpdate();
+  virtual void DidScrollEnd();
+  virtual void DidMouseMoveOffScrollbar() {}
+  virtual void DidMouseMoveNear(float distance) {}
 
-  // Returns true if we should start an animation.
-  virtual bool DidScrollUpdate(base::TimeTicks now) = 0;
-  virtual bool DidMouseMoveNear(base::TimeTicks now, float distance) = 0;
+ protected:
+  ScrollbarAnimationController(ScrollbarAnimationControllerClient* client,
+                               base::TimeDelta delay_before_starting,
+                               base::TimeDelta duration);
+
+  virtual void RunAnimationFrame(float progress) = 0;
+
+  void StartAnimation();
+  void StopAnimation();
+
+ private:
+  // Returns how far through the animation we are as a progress value from
+  // 0 to 1.
+  float AnimationProgressAtTime(base::TimeTicks now);
+
+  void PostDelayedFade();
+
+  ScrollbarAnimationControllerClient* client_;
+  base::TimeTicks last_awaken_time_;
+  base::TimeDelta delay_before_starting_;
+  base::TimeDelta duration_;
+  bool is_animating_;
+
+  bool currently_scrolling_;
+  bool scroll_gesture_has_scrolled_;
+  base::CancelableClosure delayed_scrollbar_fade_;
+
+  base::WeakPtrFactory<ScrollbarAnimationController> weak_factory_;
 };
 
 }  // namespace cc
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade.cc b/cc/animation/scrollbar_animation_controller_linear_fade.cc
index 049b873..a7b220c 100644
--- a/cc/animation/scrollbar_animation_controller_linear_fade.cc
+++ b/cc/animation/scrollbar_animation_controller_linear_fade.cc
@@ -11,103 +11,36 @@
 namespace cc {
 
 scoped_ptr<ScrollbarAnimationControllerLinearFade>
-ScrollbarAnimationControllerLinearFade::Create(LayerImpl* scroll_layer,
-                                               base::TimeDelta fadeout_delay,
-                                               base::TimeDelta fadeout_length) {
+ScrollbarAnimationControllerLinearFade::Create(
+    LayerImpl* scroll_layer,
+    ScrollbarAnimationControllerClient* client,
+    base::TimeDelta delay_before_starting,
+    base::TimeDelta duration) {
   return make_scoped_ptr(new ScrollbarAnimationControllerLinearFade(
-      scroll_layer, fadeout_delay, fadeout_length));
+      scroll_layer, client, delay_before_starting, duration));
 }
 
 ScrollbarAnimationControllerLinearFade::ScrollbarAnimationControllerLinearFade(
     LayerImpl* scroll_layer,
-    base::TimeDelta fadeout_delay,
-    base::TimeDelta fadeout_length)
-    : ScrollbarAnimationController(),
-      scroll_layer_(scroll_layer),
-      scroll_gesture_in_progress_(false),
-      scroll_gesture_has_scrolled_(false),
-      fadeout_delay_(fadeout_delay),
-      fadeout_length_(fadeout_length) {}
+    ScrollbarAnimationControllerClient* client,
+    base::TimeDelta delay_before_starting,
+    base::TimeDelta duration)
+    : ScrollbarAnimationController(client, delay_before_starting, duration),
+      scroll_layer_(scroll_layer) {
+}
 
 ScrollbarAnimationControllerLinearFade::
     ~ScrollbarAnimationControllerLinearFade() {}
 
-bool ScrollbarAnimationControllerLinearFade::IsAnimating() const {
-  return !last_awaken_time_.is_null();
+void ScrollbarAnimationControllerLinearFade::RunAnimationFrame(float progress) {
+  ApplyOpacityToScrollbars(1.f - progress);
+  if (progress == 1.f)
+    StopAnimation();
 }
 
-base::TimeDelta ScrollbarAnimationControllerLinearFade::DelayBeforeStart(
-    base::TimeTicks now) const {
-  if (now > last_awaken_time_ + fadeout_delay_)
-    return base::TimeDelta();
-  return fadeout_delay_ - (now - last_awaken_time_);
-}
-
-bool ScrollbarAnimationControllerLinearFade::Animate(base::TimeTicks now) {
-  float opacity = OpacityAtTime(now);
-  ApplyOpacityToScrollbars(opacity);
-  if (!opacity)
-    last_awaken_time_ = base::TimeTicks();
-  return IsAnimating() && DelayBeforeStart(now) == base::TimeDelta();
-}
-
-void ScrollbarAnimationControllerLinearFade::DidScrollGestureBegin() {
-  scroll_gesture_in_progress_ = true;
-  scroll_gesture_has_scrolled_ = false;
-}
-
-void ScrollbarAnimationControllerLinearFade::DidScrollGestureEnd(
-    base::TimeTicks now) {
-  // The animation should not be triggered if no scrolling has occurred.
-  if (scroll_gesture_has_scrolled_)
-    last_awaken_time_ = now;
-  scroll_gesture_has_scrolled_ = false;
-  scroll_gesture_in_progress_ = false;
-}
-
-void ScrollbarAnimationControllerLinearFade::DidMouseMoveOffScrollbar(
-    base::TimeTicks now) {
-  // Ignore mouse move events.
-}
-
-bool ScrollbarAnimationControllerLinearFade::DidScrollUpdate(
-    base::TimeTicks now) {
-  ApplyOpacityToScrollbars(1.0f);
-  // The animation should only be activated if the scroll updated occurred
-  // programatically, outside the scope of a scroll gesture.
-  if (scroll_gesture_in_progress_) {
-    last_awaken_time_ = base::TimeTicks();
-    scroll_gesture_has_scrolled_ = true;
-    return false;
-  }
-
-  last_awaken_time_ = now;
-  return true;
-}
-
-bool ScrollbarAnimationControllerLinearFade::DidMouseMoveNear(
-    base::TimeTicks now, float distance) {
-  // Ignore mouse move events.
-  return false;
-}
-
-float ScrollbarAnimationControllerLinearFade::OpacityAtTime(
-    base::TimeTicks now) {
-  if (scroll_gesture_has_scrolled_)
-    return 1.0f;
-
-  if (last_awaken_time_.is_null())
-    return 0.0f;
-
-  base::TimeDelta delta = now - last_awaken_time_;
-
-  if (delta <= fadeout_delay_)
-    return 1.0f;
-  if (delta < fadeout_delay_ + fadeout_length_) {
-    return (fadeout_delay_ + fadeout_length_ - delta).InSecondsF() /
-           fadeout_length_.InSecondsF();
-  }
-  return 0.0f;
+void ScrollbarAnimationControllerLinearFade::DidScrollUpdate() {
+  ScrollbarAnimationController::DidScrollUpdate();
+  ApplyOpacityToScrollbars(1.f);
 }
 
 void ScrollbarAnimationControllerLinearFade::ApplyOpacityToScrollbars(
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade.h b/cc/animation/scrollbar_animation_controller_linear_fade.h
index 85cdada..1070049 100644
--- a/cc/animation/scrollbar_animation_controller_linear_fade.h
+++ b/cc/animation/scrollbar_animation_controller_linear_fade.h
@@ -17,40 +17,29 @@
  public:
   static scoped_ptr<ScrollbarAnimationControllerLinearFade> Create(
       LayerImpl* scroll_layer,
-      base::TimeDelta fadeout_delay,
-      base::TimeDelta fadeout_length);
+      ScrollbarAnimationControllerClient* client,
+      base::TimeDelta delay_before_starting,
+      base::TimeDelta duration);
 
   virtual ~ScrollbarAnimationControllerLinearFade();
 
-  // ScrollbarAnimationController overrides.
-  virtual bool IsAnimating() const OVERRIDE;
-  virtual base::TimeDelta DelayBeforeStart(base::TimeTicks now) const OVERRIDE;
-
-  virtual bool Animate(base::TimeTicks now) OVERRIDE;
-  virtual void DidScrollGestureBegin() OVERRIDE;
-  virtual void DidScrollGestureEnd(base::TimeTicks now) OVERRIDE;
-  virtual void DidMouseMoveOffScrollbar(base::TimeTicks now) OVERRIDE;
-  virtual bool DidScrollUpdate(base::TimeTicks now) OVERRIDE;
-  virtual bool DidMouseMoveNear(base::TimeTicks now, float distance) OVERRIDE;
+  virtual void DidScrollUpdate() OVERRIDE;
 
  protected:
-  ScrollbarAnimationControllerLinearFade(LayerImpl* scroll_layer,
-                                         base::TimeDelta fadeout_delay,
-                                         base::TimeDelta fadeout_length);
+  ScrollbarAnimationControllerLinearFade(
+      LayerImpl* scroll_layer,
+      ScrollbarAnimationControllerClient* client,
+      base::TimeDelta delay_before_starting,
+      base::TimeDelta duration);
+
+  virtual void RunAnimationFrame(float progress) OVERRIDE;
 
  private:
-  float OpacityAtTime(base::TimeTicks now);
+  float OpacityAtTime(base::TimeTicks now) const;
   void ApplyOpacityToScrollbars(float opacity);
 
   LayerImpl* scroll_layer_;
 
-  base::TimeTicks last_awaken_time_;
-  bool scroll_gesture_in_progress_;
-  bool scroll_gesture_has_scrolled_;
-
-  base::TimeDelta fadeout_delay_;
-  base::TimeDelta fadeout_length_;
-
   DISALLOW_COPY_AND_ASSIGN(ScrollbarAnimationControllerLinearFade);
 };
 
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc b/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc
index ea4b6e1..c503335 100644
--- a/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc
+++ b/cc/animation/scrollbar_animation_controller_linear_fade_unittest.cc
@@ -13,10 +13,20 @@
 namespace cc {
 namespace {
 
-class ScrollbarAnimationControllerLinearFadeTest : public testing::Test {
+class ScrollbarAnimationControllerLinearFadeTest
+    : public testing::Test,
+      public ScrollbarAnimationControllerClient {
  public:
   ScrollbarAnimationControllerLinearFadeTest()
-      : host_impl_(&proxy_, &shared_bitmap_manager_) {}
+      : host_impl_(&proxy_, &shared_bitmap_manager_), needs_frame_count_(0) {}
+
+  virtual void PostDelayedScrollbarFade(const base::Closure& start_fade,
+                                        base::TimeDelta delay) OVERRIDE {
+    start_fade_ = start_fade;
+  }
+  virtual void SetNeedsScrollbarAnimationFrame() OVERRIDE {
+    needs_frame_count_++;
+  }
 
  protected:
   virtual void SetUp() {
@@ -47,6 +57,7 @@
 
     scrollbar_controller_ = ScrollbarAnimationControllerLinearFade::Create(
         scroll_layer_ptr,
+        this,
         base::TimeDelta::FromSeconds(2),
         base::TimeDelta::FromSeconds(3));
   }
@@ -57,58 +68,55 @@
   scoped_ptr<ScrollbarAnimationControllerLinearFade> scrollbar_controller_;
   scoped_ptr<LayerImpl> clip_layer_;
   scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar_layer_;
+
+  base::Closure start_fade_;
+  int needs_frame_count_;
 };
 
 TEST_F(ScrollbarAnimationControllerLinearFadeTest, HiddenInBegin) {
+  scrollbar_layer_->SetOpacity(0.0f);
   scrollbar_controller_->Animate(base::TimeTicks());
   EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
+  EXPECT_EQ(0, needs_frame_count_);
 }
 
 TEST_F(ScrollbarAnimationControllerLinearFadeTest,
        HiddenAfterNonScrollingGesture) {
-  scrollbar_controller_->DidScrollGestureBegin();
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
-  EXPECT_FALSE(scrollbar_controller_->Animate(base::TimeTicks()));
-  EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
+  scrollbar_layer_->SetOpacity(0.0f);
+  scrollbar_controller_->DidScrollBegin();
 
   base::TimeTicks time;
   time += base::TimeDelta::FromSeconds(100);
-  EXPECT_FALSE(scrollbar_controller_->Animate(time));
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
-  scrollbar_controller_->DidScrollGestureEnd(time);
+  scrollbar_controller_->DidScrollEnd();
+
+  EXPECT_TRUE(start_fade_.Equals(base::Closure()));
 
   time += base::TimeDelta::FromSeconds(100);
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
-  EXPECT_FALSE(scrollbar_controller_->Animate(time));
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
+
+  EXPECT_EQ(0, needs_frame_count_);
 }
 
 TEST_F(ScrollbarAnimationControllerLinearFadeTest, AwakenByScrollingGesture) {
   base::TimeTicks time;
   time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->DidScrollGestureBegin();
-  scrollbar_controller_->Animate(time);
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
-  EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
+  scrollbar_controller_->DidScrollBegin();
 
-  EXPECT_FALSE(scrollbar_controller_->DidScrollUpdate(time));
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+  scrollbar_controller_->DidScrollUpdate();
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
 
+  EXPECT_TRUE(start_fade_.Equals(base::Closure()));
+
   time += base::TimeDelta::FromSeconds(100);
   scrollbar_controller_->Animate(time);
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
-  scrollbar_controller_->DidScrollGestureEnd(time);
+  scrollbar_controller_->DidScrollEnd();
+  start_fade_.Run();
 
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
-  EXPECT_EQ(2, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
-
-  time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->Animate(time);
-  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
-
-  time += base::TimeDelta::FromSeconds(1);
+  time += base::TimeDelta::FromSeconds(2);
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
 
@@ -122,15 +130,12 @@
 
   time += base::TimeDelta::FromSeconds(1);
 
-  scrollbar_controller_->DidScrollGestureBegin();
-  EXPECT_FALSE(scrollbar_controller_->DidScrollUpdate(time));
-  scrollbar_controller_->DidScrollGestureEnd(time);
+  scrollbar_controller_->DidScrollBegin();
+  scrollbar_controller_->DidScrollUpdate();
+  scrollbar_controller_->DidScrollEnd();
+  start_fade_.Run();
 
-  time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->Animate(time);
-  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
-
-  time += base::TimeDelta::FromSeconds(1);
+  time += base::TimeDelta::FromSeconds(2);
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
 
@@ -145,25 +150,23 @@
   time += base::TimeDelta::FromSeconds(1);
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
+
+  EXPECT_EQ(8, needs_frame_count_);
 }
 
 TEST_F(ScrollbarAnimationControllerLinearFadeTest, AwakenByProgrammaticScroll) {
   base::TimeTicks time;
   time += base::TimeDelta::FromSeconds(1);
-  EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
-  EXPECT_EQ(2, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+  scrollbar_controller_->DidScrollUpdate();
+  start_fade_.Run();
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
 
   time += base::TimeDelta::FromSeconds(1);
   scrollbar_controller_->Animate(time);
-  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
-  EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
-
-  time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->Animate(time);
-  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+  EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
+  scrollbar_controller_->DidScrollUpdate();
+  start_fade_.Run();
 
   time += base::TimeDelta::FromSeconds(1);
   scrollbar_controller_->Animate(time);
@@ -178,11 +181,8 @@
   EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
 
   time += base::TimeDelta::FromSeconds(1);
-  EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
-  time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->Animate(time);
-  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
-
+  scrollbar_controller_->DidScrollUpdate();
+  start_fade_.Run();
   time += base::TimeDelta::FromSeconds(1);
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
@@ -198,53 +198,56 @@
   time += base::TimeDelta::FromSeconds(1);
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
+
+  EXPECT_EQ(11, needs_frame_count_);
 }
 
 TEST_F(ScrollbarAnimationControllerLinearFadeTest,
        AnimationPreservedByNonScrollingGesture) {
   base::TimeTicks time;
   time += base::TimeDelta::FromSeconds(1);
-  EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+  scrollbar_controller_->DidScrollUpdate();
+  start_fade_.Run();
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
 
-  time += base::TimeDelta::FromSeconds(3);
+  time += base::TimeDelta::FromSeconds(1);
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
 
-  scrollbar_controller_->DidScrollGestureBegin();
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+  scrollbar_controller_->DidScrollBegin();
   EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
 
   time += base::TimeDelta::FromSeconds(1);
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
 
-  scrollbar_controller_->DidScrollGestureEnd(time);
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+  scrollbar_controller_->DidScrollEnd();
   EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
 
   time += base::TimeDelta::FromSeconds(1);
-  EXPECT_FALSE(scrollbar_controller_->Animate(time));
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
+
+  scrollbar_controller_->Animate(time);
+
+  EXPECT_EQ(4, needs_frame_count_);
 }
 
 TEST_F(ScrollbarAnimationControllerLinearFadeTest,
        AnimationOverriddenByScrollingGesture) {
   base::TimeTicks time;
   time += base::TimeDelta::FromSeconds(1);
-  EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+  scrollbar_controller_->DidScrollUpdate();
+  start_fade_.Run();
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
 
-  time += base::TimeDelta::FromSeconds(3);
+  time += base::TimeDelta::FromSeconds(1);
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
 
-  scrollbar_controller_->DidScrollGestureBegin();
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+  scrollbar_controller_->DidScrollBegin();
   EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
 
   time += base::TimeDelta::FromSeconds(1);
@@ -252,13 +255,11 @@
   EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
 
   time += base::TimeDelta::FromSeconds(1);
-  EXPECT_FALSE(scrollbar_controller_->DidScrollUpdate(time));
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+  scrollbar_controller_->DidScrollUpdate();
   EXPECT_FLOAT_EQ(1, scrollbar_layer_->opacity());
 
   time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->DidScrollGestureEnd(time);
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+  scrollbar_controller_->DidScrollEnd();
   EXPECT_FLOAT_EQ(1, scrollbar_layer_->opacity());
 }
 
diff --git a/cc/animation/scrollbar_animation_controller_thinning.cc b/cc/animation/scrollbar_animation_controller_thinning.cc
index 18a4959..892e307 100644
--- a/cc/animation/scrollbar_animation_controller_thinning.cc
+++ b/cc/animation/scrollbar_animation_controller_thinning.cc
@@ -4,8 +4,6 @@
 
 #include "cc/animation/scrollbar_animation_controller_thinning.h"
 
-#include <algorithm>
-
 #include "base/time/time.h"
 #include "cc/layers/layer_impl.h"
 #include "cc/layers/scrollbar_layer_impl_base.h"
@@ -14,40 +12,31 @@
 const float kIdleThicknessScale = 0.4f;
 const float kIdleOpacity = 0.7f;
 const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f;
-const int kDefaultAnimationDelay = 500;
-const int kDefaultAnimationDuration = 300;
 }
 
 namespace cc {
 
 scoped_ptr<ScrollbarAnimationControllerThinning>
-ScrollbarAnimationControllerThinning::Create(LayerImpl* scroll_layer) {
+ScrollbarAnimationControllerThinning::Create(
+    LayerImpl* scroll_layer,
+    ScrollbarAnimationControllerClient* client,
+    base::TimeDelta delay_before_starting,
+    base::TimeDelta duration) {
   return make_scoped_ptr(new ScrollbarAnimationControllerThinning(
-      scroll_layer,
-      base::TimeDelta::FromMilliseconds(kDefaultAnimationDelay),
-      base::TimeDelta::FromMilliseconds(kDefaultAnimationDuration)));
-}
-
-scoped_ptr<ScrollbarAnimationControllerThinning>
-ScrollbarAnimationControllerThinning::CreateForTest(LayerImpl* scroll_layer,
-    base::TimeDelta animation_delay, base::TimeDelta animation_duration) {
-  return make_scoped_ptr(new ScrollbarAnimationControllerThinning(
-      scroll_layer, animation_delay, animation_duration));
+      scroll_layer, client, delay_before_starting, duration));
 }
 
 ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning(
     LayerImpl* scroll_layer,
-    base::TimeDelta animation_delay,
-    base::TimeDelta animation_duration)
-    : ScrollbarAnimationController(),
+    ScrollbarAnimationControllerClient* client,
+    base::TimeDelta delay_before_starting,
+    base::TimeDelta duration)
+    : ScrollbarAnimationController(client, delay_before_starting, duration),
       scroll_layer_(scroll_layer),
       mouse_is_over_scrollbar_(false),
       mouse_is_near_scrollbar_(false),
       thickness_change_(NONE),
       opacity_change_(NONE),
-      should_delay_animation_(false),
-      animation_delay_(animation_delay),
-      animation_duration_(animation_duration),
       mouse_move_distance_to_trigger_animation_(
           kDefaultMouseMoveDistanceToTriggerAnimation) {
   ApplyOpacityAndThumbThicknessScale(kIdleOpacity, kIdleThicknessScale);
@@ -56,21 +45,7 @@
 ScrollbarAnimationControllerThinning::~ScrollbarAnimationControllerThinning() {
 }
 
-bool ScrollbarAnimationControllerThinning::IsAnimating() const {
-  return !last_awaken_time_.is_null();
-}
-
-base::TimeDelta ScrollbarAnimationControllerThinning::DelayBeforeStart(
-    base::TimeTicks now) const {
-  if (!should_delay_animation_)
-    return base::TimeDelta();
-  if (now > last_awaken_time_ + animation_delay_)
-    return base::TimeDelta();
-  return animation_delay_ - (now - last_awaken_time_);
-}
-
-bool ScrollbarAnimationControllerThinning::Animate(base::TimeTicks now) {
-  float progress = AnimationProgressAtTime(now);
+void ScrollbarAnimationControllerThinning::RunAnimationFrame(float progress) {
   float opacity = OpacityAtAnimationProgress(progress);
   float thumb_thickness_scale = ThumbThicknessScaleAtAnimationProgress(
       progress);
@@ -78,49 +53,35 @@
   if (progress == 1.f) {
     opacity_change_ = NONE;
     thickness_change_ = NONE;
-    last_awaken_time_ = base::TimeTicks();
+    StopAnimation();
   }
-  return IsAnimating() && DelayBeforeStart(now) == base::TimeDelta();
 }
 
-void ScrollbarAnimationControllerThinning::DidScrollGestureBegin() {
-}
-
-void ScrollbarAnimationControllerThinning::DidScrollGestureEnd(
-    base::TimeTicks now) {
-}
-
-void ScrollbarAnimationControllerThinning::DidMouseMoveOffScrollbar(
-    base::TimeTicks now) {
+void ScrollbarAnimationControllerThinning::DidMouseMoveOffScrollbar() {
   mouse_is_over_scrollbar_ = false;
   mouse_is_near_scrollbar_ = false;
-  last_awaken_time_ = now;
-  should_delay_animation_ = false;
   opacity_change_ = DECREASE;
   thickness_change_ = DECREASE;
+  StartAnimation();
 }
 
-bool ScrollbarAnimationControllerThinning::DidScrollUpdate(
-    base::TimeTicks now) {
+void ScrollbarAnimationControllerThinning::DidScrollUpdate() {
+  ScrollbarAnimationController::DidScrollUpdate();
   ApplyOpacityAndThumbThicknessScale(
     1, mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale);
 
-  last_awaken_time_ = now;
-  should_delay_animation_ = true;
   if (!mouse_is_over_scrollbar_)
     opacity_change_ = DECREASE;
-  return true;
 }
 
-bool ScrollbarAnimationControllerThinning::DidMouseMoveNear(
-    base::TimeTicks now, float distance) {
+void ScrollbarAnimationControllerThinning::DidMouseMoveNear(float distance) {
   bool mouse_is_over_scrollbar = distance == 0.0;
   bool mouse_is_near_scrollbar =
       distance < mouse_move_distance_to_trigger_animation_;
 
   if (mouse_is_over_scrollbar == mouse_is_over_scrollbar_ &&
       mouse_is_near_scrollbar == mouse_is_near_scrollbar_)
-    return false;
+    return;
 
   if (mouse_is_over_scrollbar_ != mouse_is_over_scrollbar) {
     mouse_is_over_scrollbar_ = mouse_is_over_scrollbar;
@@ -132,21 +93,7 @@
     thickness_change_ = mouse_is_near_scrollbar_ ? INCREASE : DECREASE;
   }
 
-  last_awaken_time_ = now;
-  should_delay_animation_ = false;
-  return true;
-}
-
-float ScrollbarAnimationControllerThinning::AnimationProgressAtTime(
-    base::TimeTicks now) {
-  if (last_awaken_time_.is_null())
-    return 1;
-
-  base::TimeDelta delta = now - last_awaken_time_;
-  if (should_delay_animation_)
-    delta -= animation_delay_;
-  float progress = delta.InSecondsF() / animation_duration_.InSecondsF();
-  return std::max(std::min(progress, 1.f), 0.f);
+  StartAnimation();
 }
 
 float ScrollbarAnimationControllerThinning::OpacityAtAnimationProgress(
diff --git a/cc/animation/scrollbar_animation_controller_thinning.h b/cc/animation/scrollbar_animation_controller_thinning.h
index 07b4515..c0c7a83 100644
--- a/cc/animation/scrollbar_animation_controller_thinning.h
+++ b/cc/animation/scrollbar_animation_controller_thinning.h
@@ -12,17 +12,16 @@
 namespace cc {
 class LayerImpl;
 
-// Scrollbar animation that partially fades and thins after an idle delay.
+// Scrollbar animation that partially fades and thins after an idle delay,
+// and reacts to mouse movements.
 class CC_EXPORT ScrollbarAnimationControllerThinning
     : public ScrollbarAnimationController {
  public:
   static scoped_ptr<ScrollbarAnimationControllerThinning> Create(
-      LayerImpl* scroll_layer);
-
-  static scoped_ptr<ScrollbarAnimationControllerThinning> CreateForTest(
       LayerImpl* scroll_layer,
-      base::TimeDelta animation_delay,
-      base::TimeDelta animation_duration);
+      ScrollbarAnimationControllerClient* client,
+      base::TimeDelta delay_before_starting,
+      base::TimeDelta duration);
 
   virtual ~ScrollbarAnimationControllerThinning();
 
@@ -32,21 +31,18 @@
   bool mouse_is_over_scrollbar() const { return mouse_is_over_scrollbar_; }
   bool mouse_is_near_scrollbar() const { return mouse_is_near_scrollbar_; }
 
-  // ScrollbarAnimationController overrides.
-  virtual bool IsAnimating() const OVERRIDE;
-  virtual base::TimeDelta DelayBeforeStart(base::TimeTicks now) const OVERRIDE;
-
-  virtual bool Animate(base::TimeTicks now) OVERRIDE;
-  virtual void DidScrollGestureBegin() OVERRIDE;
-  virtual void DidScrollGestureEnd(base::TimeTicks now) OVERRIDE;
-  virtual void DidMouseMoveOffScrollbar(base::TimeTicks now) OVERRIDE;
-  virtual bool DidScrollUpdate(base::TimeTicks now) OVERRIDE;
-  virtual bool DidMouseMoveNear(base::TimeTicks now, float distance) OVERRIDE;
+  virtual void DidScrollUpdate() OVERRIDE;
+  virtual void DidMouseMoveOffScrollbar() OVERRIDE;
+  virtual void DidMouseMoveNear(float distance) OVERRIDE;
 
  protected:
-  ScrollbarAnimationControllerThinning(LayerImpl* scroll_layer,
-                                       base::TimeDelta animation_delay,
-                                       base::TimeDelta animation_duration);
+  ScrollbarAnimationControllerThinning(
+      LayerImpl* scroll_layer,
+      ScrollbarAnimationControllerClient* client,
+      base::TimeDelta delay_before_starting,
+      base::TimeDelta duration);
+
+  virtual void RunAnimationFrame(float progress) OVERRIDE;
 
  private:
   // Describes whether the current animation should INCREASE (darken / thicken)
@@ -56,9 +52,6 @@
     INCREASE,
     DECREASE
   };
-  // Returns how far through the animation we are as a progress value from
-  // 0 to 1.
-  float AnimationProgressAtTime(base::TimeTicks now);
   float OpacityAtAnimationProgress(float progress);
   float ThumbThicknessScaleAtAnimationProgress(float progress);
   float AdjustScale(float new_value,
@@ -69,19 +62,12 @@
 
   LayerImpl* scroll_layer_;
 
-  base::TimeTicks last_awaken_time_;
   bool mouse_is_over_scrollbar_;
   bool mouse_is_near_scrollbar_;
   // Are we narrowing or thickening the bars.
   AnimationChange thickness_change_;
   // Are we darkening or lightening the bars.
   AnimationChange opacity_change_;
-  // Should the animation be delayed or start immediately.
-  bool should_delay_animation_;
-  // If |should_delay_animation_| is true, delay the animation by this amount.
-  base::TimeDelta animation_delay_;
-  // The time for the animation to run.
-  base::TimeDelta animation_duration_;
   // How close should the mouse be to the scrollbar before we thicken it.
   float mouse_move_distance_to_trigger_animation_;
 
diff --git a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
index ff036a6..c0ab515 100644
--- a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
+++ b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
@@ -13,11 +13,19 @@
 namespace cc {
 namespace {
 
-class ScrollbarAnimationControllerThinningTest : public testing::Test {
+class ScrollbarAnimationControllerThinningTest
+    : public testing::Test,
+      public ScrollbarAnimationControllerClient {
  public:
   ScrollbarAnimationControllerThinningTest()
       : host_impl_(&proxy_, &shared_bitmap_manager_) {}
 
+  virtual void PostDelayedScrollbarFade(const base::Closure& start_fade,
+                                        base::TimeDelta delay) OVERRIDE {
+    start_fade_ = start_fade;
+  }
+  virtual void SetNeedsScrollbarAnimationFrame() OVERRIDE {}
+
  protected:
   virtual void SetUp() {
     scoped_ptr<LayerImpl> scroll_layer =
@@ -46,8 +54,9 @@
     clip_layer_->SetBounds(gfx::Size(100, 100));
     scroll_layer_ptr->SetBounds(gfx::Size(50, 50));
 
-    scrollbar_controller_ = ScrollbarAnimationControllerThinning::CreateForTest(
+    scrollbar_controller_ = ScrollbarAnimationControllerThinning::Create(
         scroll_layer_ptr,
+        this,
         base::TimeDelta::FromSeconds(2),
         base::TimeDelta::FromSeconds(3));
   }
@@ -58,6 +67,8 @@
   scoped_ptr<ScrollbarAnimationControllerThinning> scrollbar_controller_;
   scoped_ptr<LayerImpl> clip_layer_;
   scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar_layer_;
+
+  base::Closure start_fade_;
 };
 
 // Check initialization of scrollbar.
@@ -72,31 +83,24 @@
 TEST_F(ScrollbarAnimationControllerThinningTest, AwakenByProgrammaticScroll) {
   base::TimeTicks time;
   time += base::TimeDelta::FromSeconds(1);
-  EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
-  EXPECT_EQ(2, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+  scrollbar_controller_->DidScrollUpdate();
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
   // Scrollbar doesn't change size if triggered by scroll.
   EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
 
+  start_fade_.Run();
+
   time += base::TimeDelta::FromSeconds(1);
-  EXPECT_EQ(1, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
 
   // Subsequent scroll restarts animation.
-  EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
-  EXPECT_EQ(2, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+  scrollbar_controller_->DidScrollUpdate();
 
-  time += base::TimeDelta::FromSeconds(1);
-  EXPECT_EQ(1, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
-  scrollbar_controller_->Animate(time);
-  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
-  EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
+  start_fade_.Run();
 
-  time += base::TimeDelta::FromSeconds(1);
-  EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+  time += base::TimeDelta::FromSeconds(2);
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
@@ -115,8 +119,6 @@
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
-
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
 }
 
 // Initiate a scroll when the pointer is already near the scrollbar. It should
@@ -125,22 +127,22 @@
   base::TimeTicks time;
   time += base::TimeDelta::FromSeconds(1);
 
-  scrollbar_controller_->DidMouseMoveNear(time, 1);
-  time += base::TimeDelta::FromSeconds(3);
+  scrollbar_controller_->DidMouseMoveNear(1);
   scrollbar_controller_->Animate(time);
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+  time += base::TimeDelta::FromSeconds(3);
+
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
 
-  EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
-  EXPECT_EQ(2, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+  scrollbar_controller_->DidScrollUpdate();
+  start_fade_.Run();
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
   // Scrollbar should still be thick.
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
 
   time += base::TimeDelta::FromSeconds(5);
   scrollbar_controller_->Animate(time);
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
   EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
 }
@@ -150,9 +152,8 @@
 TEST_F(ScrollbarAnimationControllerThinningTest, MouseNear) {
   base::TimeTicks time;
   time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->DidMouseMoveNear(time, 1);
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
-  EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+  scrollbar_controller_->DidMouseMoveNear(1);
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
 
@@ -171,19 +172,17 @@
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
 
   // Subsequent moves should not change anything.
-  scrollbar_controller_->DidMouseMoveNear(time, 1);
+  scrollbar_controller_->DidMouseMoveNear(1);
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
 
   // Now move away from bar.
   time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->DidMouseMoveNear(time, 26);
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
-  EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+  scrollbar_controller_->DidMouseMoveNear(26);
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
 
@@ -202,7 +201,6 @@
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
 }
 
 // Move the pointer over the scrollbar. Make sure it gets thick and dark
@@ -210,9 +208,8 @@
 TEST_F(ScrollbarAnimationControllerThinningTest, MouseOver) {
   base::TimeTicks time;
   time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->DidMouseMoveNear(time, 0);
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
-  EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+  scrollbar_controller_->DidMouseMoveNear(0);
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
 
@@ -231,19 +228,17 @@
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
 
   // Subsequent moves should not change anything.
-  scrollbar_controller_->DidMouseMoveNear(time, 0);
+  scrollbar_controller_->DidMouseMoveNear(0);
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
 
   // Now move away from bar.
   time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->DidMouseMoveNear(time, 26);
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
-  EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+  scrollbar_controller_->DidMouseMoveNear(26);
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
 
@@ -262,7 +257,6 @@
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
 }
 
 // First move the pointer near the scrollbar, then over it, then back near
@@ -271,9 +265,8 @@
 TEST_F(ScrollbarAnimationControllerThinningTest, MouseNearThenOver) {
   base::TimeTicks time;
   time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->DidMouseMoveNear(time, 1);
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
-  EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+  scrollbar_controller_->DidMouseMoveNear(1);
+  scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
 
@@ -282,12 +275,10 @@
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
 
   // Now move over.
-  scrollbar_controller_->DidMouseMoveNear(time, 0);
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
-  EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+  scrollbar_controller_->DidMouseMoveNear(0);
+  scrollbar_controller_->Animate(time);
 
   // Should animate to darkened.
   time += base::TimeDelta::FromSeconds(1);
@@ -304,24 +295,23 @@
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
-  EXPECT_FALSE(scrollbar_controller_->IsAnimating());
 
   // This is tricky. The DidMouseMoveOffScrollbar() is sent before the
   // subsequent DidMouseMoveNear(), if the mouse moves in that direction.
   // This results in the thumb thinning. We want to make sure that when the
   // thumb starts expanding it doesn't first narrow to the idle thinness.
   time += base::TimeDelta::FromSeconds(1);
-  scrollbar_controller_->DidMouseMoveOffScrollbar(time);
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+  scrollbar_controller_->DidMouseMoveOffScrollbar();
+  scrollbar_controller_->Animate(time);
 
   time += base::TimeDelta::FromSeconds(1);
   scrollbar_controller_->Animate(time);
   EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity());
   EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor());
 
-  scrollbar_controller_->DidMouseMoveNear(time, 1);
+  scrollbar_controller_->DidMouseMoveNear(1);
+  scrollbar_controller_->Animate(time);
   // A new animation is kicked off.
-  EXPECT_TRUE(scrollbar_controller_->IsAnimating());
 
   time += base::TimeDelta::FromSeconds(1);
   scrollbar_controller_->Animate(time);
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 6cee0f3..c7b1a50 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -52,6 +52,7 @@
         'animation/scroll_offset_animation_curve.cc',
         'animation/scroll_offset_animation_curve.h',
         'animation/scrollbar_animation_controller.h',
+        'animation/scrollbar_animation_controller.cc',
         'animation/scrollbar_animation_controller_linear_fade.cc',
         'animation/scrollbar_animation_controller_linear_fade.h',
         'animation/scrollbar_animation_controller_thinning.cc',
diff --git a/cc/cc.target.darwin-arm.mk b/cc/cc.target.darwin-arm.mk
index 7d7c851..aa42a17 100644
--- a/cc/cc.target.darwin-arm.mk
+++ b/cc/cc.target.darwin-arm.mk
@@ -36,6 +36,7 @@
 	cc/animation/keyframed_animation_curve.cc \
 	cc/animation/layer_animation_controller.cc \
 	cc/animation/scroll_offset_animation_curve.cc \
+	cc/animation/scrollbar_animation_controller.cc \
 	cc/animation/scrollbar_animation_controller_linear_fade.cc \
 	cc/animation/scrollbar_animation_controller_thinning.cc \
 	cc/animation/timing_function.cc \
@@ -241,7 +242,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -291,11 +291,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -371,7 +366,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -421,11 +415,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/cc/cc.target.darwin-arm64.mk b/cc/cc.target.darwin-arm64.mk
index ef9fe4a..6980cf1 100644
--- a/cc/cc.target.darwin-arm64.mk
+++ b/cc/cc.target.darwin-arm64.mk
@@ -36,6 +36,7 @@
 	cc/animation/keyframed_animation_curve.cc \
 	cc/animation/layer_animation_controller.cc \
 	cc/animation/scroll_offset_animation_curve.cc \
+	cc/animation/scrollbar_animation_controller.cc \
 	cc/animation/scrollbar_animation_controller_linear_fade.cc \
 	cc/animation/scrollbar_animation_controller_thinning.cc \
 	cc/animation/timing_function.cc \
@@ -287,11 +288,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -412,11 +408,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/cc/cc.target.darwin-mips.mk b/cc/cc.target.darwin-mips.mk
index c0a87ab..03133c7 100644
--- a/cc/cc.target.darwin-mips.mk
+++ b/cc/cc.target.darwin-mips.mk
@@ -36,6 +36,7 @@
 	cc/animation/keyframed_animation_curve.cc \
 	cc/animation/layer_animation_controller.cc \
 	cc/animation/scroll_offset_animation_curve.cc \
+	cc/animation/scrollbar_animation_controller.cc \
 	cc/animation/scrollbar_animation_controller_linear_fade.cc \
 	cc/animation/scrollbar_animation_controller_thinning.cc \
 	cc/animation/timing_function.cc \
@@ -290,11 +291,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -419,11 +415,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/cc/cc.target.darwin-x86.mk b/cc/cc.target.darwin-x86.mk
index fb6e2b0..ab7c995 100644
--- a/cc/cc.target.darwin-x86.mk
+++ b/cc/cc.target.darwin-x86.mk
@@ -36,6 +36,7 @@
 	cc/animation/keyframed_animation_curve.cc \
 	cc/animation/layer_animation_controller.cc \
 	cc/animation/scroll_offset_animation_curve.cc \
+	cc/animation/scrollbar_animation_controller.cc \
 	cc/animation/scrollbar_animation_controller_linear_fade.cc \
 	cc/animation/scrollbar_animation_controller_thinning.cc \
 	cc/animation/timing_function.cc \
@@ -243,7 +244,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -292,11 +292,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -373,7 +368,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -422,11 +416,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/cc/cc.target.darwin-x86_64.mk b/cc/cc.target.darwin-x86_64.mk
index 636012e..9c39dc6 100644
--- a/cc/cc.target.darwin-x86_64.mk
+++ b/cc/cc.target.darwin-x86_64.mk
@@ -36,6 +36,7 @@
 	cc/animation/keyframed_animation_curve.cc \
 	cc/animation/layer_animation_controller.cc \
 	cc/animation/scroll_offset_animation_curve.cc \
+	cc/animation/scrollbar_animation_controller.cc \
 	cc/animation/scrollbar_animation_controller_linear_fade.cc \
 	cc/animation/scrollbar_animation_controller_thinning.cc \
 	cc/animation/timing_function.cc \
@@ -243,7 +244,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -292,11 +292,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -373,7 +368,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -422,11 +416,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/cc/cc.target.linux-arm.mk b/cc/cc.target.linux-arm.mk
index 7d7c851..aa42a17 100644
--- a/cc/cc.target.linux-arm.mk
+++ b/cc/cc.target.linux-arm.mk
@@ -36,6 +36,7 @@
 	cc/animation/keyframed_animation_curve.cc \
 	cc/animation/layer_animation_controller.cc \
 	cc/animation/scroll_offset_animation_curve.cc \
+	cc/animation/scrollbar_animation_controller.cc \
 	cc/animation/scrollbar_animation_controller_linear_fade.cc \
 	cc/animation/scrollbar_animation_controller_thinning.cc \
 	cc/animation/timing_function.cc \
@@ -241,7 +242,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -291,11 +291,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -371,7 +366,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -421,11 +415,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/cc/cc.target.linux-arm64.mk b/cc/cc.target.linux-arm64.mk
index ef9fe4a..6980cf1 100644
--- a/cc/cc.target.linux-arm64.mk
+++ b/cc/cc.target.linux-arm64.mk
@@ -36,6 +36,7 @@
 	cc/animation/keyframed_animation_curve.cc \
 	cc/animation/layer_animation_controller.cc \
 	cc/animation/scroll_offset_animation_curve.cc \
+	cc/animation/scrollbar_animation_controller.cc \
 	cc/animation/scrollbar_animation_controller_linear_fade.cc \
 	cc/animation/scrollbar_animation_controller_thinning.cc \
 	cc/animation/timing_function.cc \
@@ -287,11 +288,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -412,11 +408,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/cc/cc.target.linux-mips.mk b/cc/cc.target.linux-mips.mk
index c0a87ab..03133c7 100644
--- a/cc/cc.target.linux-mips.mk
+++ b/cc/cc.target.linux-mips.mk
@@ -36,6 +36,7 @@
 	cc/animation/keyframed_animation_curve.cc \
 	cc/animation/layer_animation_controller.cc \
 	cc/animation/scroll_offset_animation_curve.cc \
+	cc/animation/scrollbar_animation_controller.cc \
 	cc/animation/scrollbar_animation_controller_linear_fade.cc \
 	cc/animation/scrollbar_animation_controller_thinning.cc \
 	cc/animation/timing_function.cc \
@@ -290,11 +291,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -419,11 +415,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/cc/cc.target.linux-x86.mk b/cc/cc.target.linux-x86.mk
index fb6e2b0..ab7c995 100644
--- a/cc/cc.target.linux-x86.mk
+++ b/cc/cc.target.linux-x86.mk
@@ -36,6 +36,7 @@
 	cc/animation/keyframed_animation_curve.cc \
 	cc/animation/layer_animation_controller.cc \
 	cc/animation/scroll_offset_animation_curve.cc \
+	cc/animation/scrollbar_animation_controller.cc \
 	cc/animation/scrollbar_animation_controller_linear_fade.cc \
 	cc/animation/scrollbar_animation_controller_thinning.cc \
 	cc/animation/timing_function.cc \
@@ -243,7 +244,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -292,11 +292,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -373,7 +368,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -422,11 +416,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/cc/cc.target.linux-x86_64.mk b/cc/cc.target.linux-x86_64.mk
index 636012e..9c39dc6 100644
--- a/cc/cc.target.linux-x86_64.mk
+++ b/cc/cc.target.linux-x86_64.mk
@@ -36,6 +36,7 @@
 	cc/animation/keyframed_animation_curve.cc \
 	cc/animation/layer_animation_controller.cc \
 	cc/animation/scroll_offset_animation_curve.cc \
+	cc/animation/scrollbar_animation_controller.cc \
 	cc/animation/scrollbar_animation_controller_linear_fade.cc \
 	cc/animation/scrollbar_animation_controller_thinning.cc \
 	cc/animation/timing_function.cc \
@@ -243,7 +244,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -292,11 +292,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -373,7 +368,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -422,11 +416,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index af73286..25fb760 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -172,8 +172,6 @@
       'test/fake_video_frame_provider.h',
       'test/geometry_test_utils.cc',
       'test/geometry_test_utils.h',
-      'test/gpu_rasterization_settings.h',
-      'test/hybrid_rasterization_settings.h',
       'test/test_in_process_context_provider.cc',
       'test/test_in_process_context_provider.h',
       'test/impl_side_painting_settings.h',
@@ -270,8 +268,7 @@
         [ 'os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"',
           {
             'conditions': [
-              # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-              [ '(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)',
+              [ 'use_allocator!="none"',
                 {
                   'dependencies': [
                     '../base/allocator/allocator.gyp:allocator',
@@ -330,8 +327,7 @@
           }
         ],
         # See http://crbug.com/162998#c4 for why this is needed.
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))',
+        ['OS=="linux" and use_allocator!="none"',
           {
             'dependencies': [
               '../base/allocator/allocator.gyp:allocator',
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h
index e78a8d1..7f35dda 100644
--- a/cc/input/input_handler.h
+++ b/cc/input/input_handler.h
@@ -127,6 +127,10 @@
   // Request another callback to InputHandlerClient::Animate().
   virtual void SetNeedsAnimate() = 0;
 
+  // Whether the layer under |viewport_point| is the currently scrolling layer.
+  virtual bool IsCurrentlyScrollingLayerAt(const gfx::Point& viewport_point,
+                                           ScrollInputType type) = 0;
+
   virtual bool HaveTouchEventHandlersAt(const gfx::Point& viewport_point) = 0;
 
   // Calling CreateLatencyInfoSwapPromiseMonitor() to get a scoped
diff --git a/cc/layers/content_layer.cc b/cc/layers/content_layer.cc
index 7e0bee8..14a5864 100644
--- a/cc/layers/content_layer.cc
+++ b/cc/layers/content_layer.cc
@@ -28,7 +28,10 @@
                                 const gfx::Rect& content_rect,
                                 gfx::RectF* opaque) {
   base::TimeTicks paint_start = base::TimeTicks::HighResNow();
-  client_->PaintContents(canvas, content_rect, opaque);
+  client_->PaintContents(canvas,
+                         content_rect,
+                         opaque,
+                         ContentLayerClient::GRAPHICS_CONTEXT_ENABLED);
   base::TimeTicks paint_end = base::TimeTicks::HighResNow();
   // The start and end times might be the same if the paint was very fast or if
   // our timer granularity is poor. Treat this as a very short time duration
@@ -163,7 +166,10 @@
 
   SkPictureRecorder recorder;
   SkCanvas* canvas = recorder.beginRecording(width, height, NULL, 0);
-  client_->PaintContents(canvas, gfx::Rect(width, height), &opaque);
+  client_->PaintContents(canvas,
+                         gfx::Rect(width, height),
+                         &opaque,
+                         ContentLayerClient::GRAPHICS_CONTEXT_ENABLED);
   skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording());
   return picture;
 }
diff --git a/cc/layers/content_layer_client.h b/cc/layers/content_layer_client.h
index 6a77dab..8271cd5 100644
--- a/cc/layers/content_layer_client.h
+++ b/cc/layers/content_layer_client.h
@@ -18,9 +18,15 @@
 
 class CC_EXPORT ContentLayerClient {
  public:
+  enum GraphicsContextStatus {
+    GRAPHICS_CONTEXT_DISABLED,
+    GRAPHICS_CONTEXT_ENABLED
+  };
+
   virtual void PaintContents(SkCanvas* canvas,
                              const gfx::Rect& clip,
-                             gfx::RectF* opaque) = 0;
+                             gfx::RectF* opaque,
+                             GraphicsContextStatus gc_status) = 0;
 
   // Called by the content layer during the update phase.
   // If the client paints LCD text, it may want to invalidate the layer.
diff --git a/cc/layers/content_layer_unittest.cc b/cc/layers/content_layer_unittest.cc
index 8770303..f450149 100644
--- a/cc/layers/content_layer_unittest.cc
+++ b/cc/layers/content_layer_unittest.cc
@@ -20,9 +20,11 @@
   explicit MockContentLayerClient(const gfx::Rect& opaque_layer_rect)
       : opaque_layer_rect_(opaque_layer_rect) {}
 
-  virtual void PaintContents(SkCanvas* canvas,
-                             const gfx::Rect& clip,
-                             gfx::RectF* opaque) OVERRIDE {
+  virtual void PaintContents(
+      SkCanvas* canvas,
+      const gfx::Rect& clip,
+      gfx::RectF* opaque,
+      ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
     *opaque = gfx::RectF(opaque_layer_rect_);
   }
   virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
diff --git a/cc/layers/delegated_frame_provider_unittest.cc b/cc/layers/delegated_frame_provider_unittest.cc
index a8e1683..0655cf3 100644
--- a/cc/layers/delegated_frame_provider_unittest.cc
+++ b/cc/layers/delegated_frame_provider_unittest.cc
@@ -44,10 +44,11 @@
 
   void AddTextureQuad(DelegatedFrameData* frame,
                       ResourceProvider::ResourceId resource_id) {
-    scoped_ptr<SharedQuadState> sqs = SharedQuadState::Create();
+    SharedQuadState* sqs =
+        frame->render_pass_list[0]->CreateAndAppendSharedQuadState();
     scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create();
     float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f};
-    quad->SetNew(sqs.get(),
+    quad->SetNew(sqs,
                  gfx::Rect(0, 0, 10, 10),
                  gfx::Rect(0, 0, 10, 10),
                  gfx::Rect(0, 0, 10, 10),
@@ -58,7 +59,6 @@
                  SK_ColorTRANSPARENT,
                  vertex_opacity,
                  false);
-    frame->render_pass_list[0]->shared_quad_state_list.push_back(sqs.Pass());
     frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>());
   }
 
diff --git a/cc/layers/delegated_renderer_layer_impl.cc b/cc/layers/delegated_renderer_layer_impl.cc
index 4556db6..f59e1f2 100644
--- a/cc/layers/delegated_renderer_layer_impl.cc
+++ b/cc/layers/delegated_renderer_layer_impl.cc
@@ -319,8 +319,8 @@
   if (!ShowDebugBorders())
     return;
 
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
 
   SkColor color;
   float border_width;
@@ -407,8 +407,8 @@
 
     if (delegated_quad->shared_quad_state != delegated_shared_quad_state) {
       delegated_shared_quad_state = delegated_quad->shared_quad_state;
-      output_shared_quad_state = quad_sink->UseSharedQuadState(
-          delegated_shared_quad_state->Copy());
+      output_shared_quad_state = quad_sink->CreateSharedQuadState();
+      output_shared_quad_state->CopyFrom(delegated_shared_quad_state);
 
       bool is_root_delegated_render_pass =
           delegated_render_pass == render_passes_in_draw_order_.back();
diff --git a/cc/layers/delegated_renderer_layer_impl_unittest.cc b/cc/layers/delegated_renderer_layer_impl_unittest.cc
index 7578e22..bf4b088 100644
--- a/cc/layers/delegated_renderer_layer_impl_unittest.cc
+++ b/cc/layers/delegated_renderer_layer_impl_unittest.cc
@@ -541,9 +541,8 @@
           RenderPass::Id(10, 7),
           child_pass_rect,
           gfx::Transform());
-      MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
-      SharedQuadState* shared_quad_state = quad_sink.UseSharedQuadState(
-          SharedQuadState::Create());
+      MockQuadCuller quad_sink(pass);
+      SharedQuadState* shared_quad_state = quad_sink.CreateSharedQuadState();
       shared_quad_state->SetAll(child_pass_transform,
                                 child_pass_content_bounds,
                                 child_pass_rect,
@@ -583,9 +582,8 @@
         RenderPass::Id(9, 6),
         root_pass_rect,
         gfx::Transform());
-    MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
-    SharedQuadState* shared_quad_state =
-        quad_sink.UseSharedQuadState(SharedQuadState::Create());
+    MockQuadCuller quad_sink(pass);
+    SharedQuadState* shared_quad_state = quad_sink.CreateSharedQuadState();
     shared_quad_state->SetAll(root_pass_transform,
                               root_pass_content_bounds,
                               root_pass_rect,
@@ -972,9 +970,8 @@
           RenderPass::Id(10, 7),
           child_pass_rect,
           gfx::Transform());
-      MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
-      SharedQuadState* shared_quad_state =
-          quad_sink.UseSharedQuadState(SharedQuadState::Create());
+      MockQuadCuller quad_sink(pass);
+      SharedQuadState* shared_quad_state = quad_sink.CreateSharedQuadState();
       shared_quad_state->SetAll(child_pass_transform,
                                 child_pass_content_bounds,
                                 child_pass_rect,
@@ -1012,9 +1009,8 @@
         RenderPass::Id(9, 6),
         root_pass_rect,
         gfx::Transform());
-    MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
-    SharedQuadState* shared_quad_state =
-        quad_sink.UseSharedQuadState(SharedQuadState::Create());
+    MockQuadCuller quad_sink(pass);
+    SharedQuadState* shared_quad_state = quad_sink.CreateSharedQuadState();
     shared_quad_state->SetAll(root_pass_transform,
                               root_pass_content_bounds,
                               root_pass_rect,
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc
index 957ad9a..6149a06 100644
--- a/cc/layers/heads_up_display_layer_impl.cc
+++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -110,8 +110,8 @@
   if (!hud_resource_->id())
     return;
 
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
 
   gfx::Rect quad_rect(content_bounds());
   gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect());
diff --git a/cc/layers/io_surface_layer_impl.cc b/cc/layers/io_surface_layer_impl.cc
index c40e05e..6d94c91 100644
--- a/cc/layers/io_surface_layer_impl.cc
+++ b/cc/layers/io_surface_layer_impl.cc
@@ -21,32 +21,19 @@
     : LayerImpl(tree_impl, id),
       io_surface_id_(0),
       io_surface_changed_(false),
-      io_surface_texture_id_(0),
       io_surface_resource_id_(0) {}
 
 IOSurfaceLayerImpl::~IOSurfaceLayerImpl() {
-  if (!io_surface_texture_id_)
-    return;
-
-  DestroyTexture();
+  DestroyResource();
 }
 
-void IOSurfaceLayerImpl::DestroyTexture() {
+void IOSurfaceLayerImpl::DestroyResource() {
   if (io_surface_resource_id_) {
     ResourceProvider* resource_provider =
         layer_tree_impl()->resource_provider();
     resource_provider->DeleteResource(io_surface_resource_id_);
     io_surface_resource_id_ = 0;
   }
-
-  if (io_surface_texture_id_) {
-    ContextProvider* context_provider =
-        layer_tree_impl()->output_surface()->context_provider().get();
-    // TODO(skaslev): Implement this path for software compositing.
-    if (context_provider)
-      context_provider->ContextGL()->DeleteTextures(1, &io_surface_texture_id_);
-    io_surface_texture_id_ = 0;
-  }
 }
 
 scoped_ptr<LayerImpl> IOSurfaceLayerImpl::CreateLayerImpl(
@@ -64,41 +51,13 @@
 
 bool IOSurfaceLayerImpl::WillDraw(DrawMode draw_mode,
                                   ResourceProvider* resource_provider) {
-  if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE)
+  if (draw_mode != DRAW_MODE_HARDWARE)
     return false;
 
   if (io_surface_changed_) {
-    ContextProvider* context_provider =
-        layer_tree_impl()->output_surface()->context_provider().get();
-    if (!context_provider) {
-      // TODO(skaslev): Implement this path for software compositing.
-      return false;
-    }
-
-    gpu::gles2::GLES2Interface* gl = context_provider->ContextGL();
-
-    // TODO(ernstm): Do this in a way that we can track memory usage.
-    if (!io_surface_texture_id_) {
-      gl->GenTextures(1, &io_surface_texture_id_);
-      io_surface_resource_id_ =
-          resource_provider->CreateResourceFromExternalTexture(
-              GL_TEXTURE_RECTANGLE_ARB,
-              io_surface_texture_id_);
-    }
-
-    GLC(gl, gl->BindTexture(GL_TEXTURE_RECTANGLE_ARB, io_surface_texture_id_));
-    gl->TexImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
-                                    io_surface_size_.width(),
-                                    io_surface_size_.height(),
-                                    io_surface_id_,
-                                    0);
-    // Do not check for error conditions. texImageIOSurface2DCHROMIUM() is
-    // supposed to hold on to the last good IOSurface if the new one is already
-    // closed. This is only a possibility during live resizing of plugins.
-    // However, it seems that this is not sufficient to completely guard against
-    // garbage being drawn. If this is found to be a significant issue, it may
-    // be necessary to explicitly tell the embedder when to free the surfaces it
-    // has allocated.
+    DestroyResource();
+    io_surface_resource_id_ = resource_provider->CreateResourceFromIOSurface(
+        io_surface_size_, io_surface_id_);
     io_surface_changed_ = false;
   }
 
@@ -107,8 +66,9 @@
 
 void IOSurfaceLayerImpl::AppendQuads(QuadSink* quad_sink,
                                      AppendQuadsData* append_quads_data) {
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
+
   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
 
   gfx::Rect quad_rect(content_bounds());
@@ -130,9 +90,9 @@
 }
 
 void IOSurfaceLayerImpl::ReleaseResources() {
-  // We don't have a valid texture ID in the new context; however,
+  // We don't have a valid resource ID in the new context; however,
   // the IOSurface is still valid.
-  DestroyTexture();
+  DestroyResource();
   io_surface_changed_ = true;
 }
 
diff --git a/cc/layers/io_surface_layer_impl.h b/cc/layers/io_surface_layer_impl.h
index efd7428..8ac9a25 100644
--- a/cc/layers/io_surface_layer_impl.h
+++ b/cc/layers/io_surface_layer_impl.h
@@ -37,14 +37,13 @@
  private:
   IOSurfaceLayerImpl(LayerTreeImpl* tree_impl, int id);
 
-  void DestroyTexture();
+  void DestroyResource();
 
   virtual const char* LayerTypeAsString() const OVERRIDE;
 
   unsigned io_surface_id_;
   gfx::Size io_surface_size_;
   bool io_surface_changed_;
-  unsigned io_surface_texture_id_;
   unsigned io_surface_resource_id_;
 
   DISALLOW_COPY_AND_ASSIGN(IOSurfaceLayerImpl);
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index befedf7..b746798 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -1043,6 +1043,10 @@
   return false;
 }
 
+bool Layer::IsSuitableForGpuRasterization() const {
+  return true;
+}
+
 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
   if (client_)
     return client_->TakeDebugInfo();
@@ -1082,7 +1086,10 @@
 }
 
 void Layer::OnTransformAnimated(const gfx::Transform& transform) {
+  if (transform_ == transform)
+    return;
   transform_ = transform;
+  transform_is_invertible_ = transform.IsInvertible();
 }
 
 void Layer::OnScrollOffsetAnimated(const gfx::Vector2dF& scroll_offset) {
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 5e4a401..7e7d286 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -363,6 +363,7 @@
   virtual void SetIsMask(bool is_mask) {}
   virtual void ReduceMemoryUsage() {}
   virtual void OnOutputSurfaceCreated() {}
+  virtual bool IsSuitableForGpuRasterization() const;
 
   virtual scoped_refptr<base::debug::ConvertableToTraceFormat> TakeDebugInfo();
 
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 3c50683..fd5ea31 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -9,8 +9,6 @@
 #include "base/strings/stringprintf.h"
 #include "cc/animation/animation_registrar.h"
 #include "cc/animation/scrollbar_animation_controller.h"
-#include "cc/animation/scrollbar_animation_controller_linear_fade.h"
-#include "cc/animation/scrollbar_animation_controller_thinning.h"
 #include "cc/base/math_util.h"
 #include "cc/debug/debug_colors.h"
 #include "cc/debug/layer_tree_debug_state.h"
@@ -245,8 +243,7 @@
     draw_properties_.render_surface->layer_list().clear();
 }
 
-scoped_ptr<SharedQuadState> LayerImpl::CreateSharedQuadState() const {
-  scoped_ptr<SharedQuadState> state = SharedQuadState::Create();
+void LayerImpl::PopulateSharedQuadState(SharedQuadState* state) const {
   state->SetAll(draw_properties_.target_space_transform,
                 draw_properties_.content_bounds,
                 draw_properties_.visible_content_rect,
@@ -254,7 +251,6 @@
                 draw_properties_.is_clipped,
                 draw_properties_.opacity,
                 blend_mode_);
-  return state.Pass();
 }
 
 bool LayerImpl::WillDraw(DrawMode draw_mode,
@@ -1320,14 +1316,8 @@
         ((layer_tree_impl()->total_page_scale_factor() >
           layer_tree_impl()->min_page_scale_factor()) ||
          !layer_tree_impl()->settings().use_pinch_zoom_scrollbars);
-    // Note that DidScrollUpdate() has the side-effect of setting the
-    // scrollbar's opacity to 1.0 even if the function returns false, so
-    // evaluate it last in the boolean expression.
-    bool should_animate = is_animatable_scrollbar &&
-                          scrollbar_animation_controller_->DidScrollUpdate(
-                              layer_tree_impl_->CurrentFrameTimeTicks());
-    if (should_animate)
-      layer_tree_impl_->StartScrollbarAnimation();
+    if (is_animatable_scrollbar)
+      scrollbar_animation_controller_->DidScrollUpdate();
   }
 }
 
@@ -1346,29 +1336,8 @@
   if (scrollbar_animation_controller_)
     return;
 
-  switch (layer_tree_impl_->settings().scrollbar_animator) {
-  case LayerTreeSettings::LinearFade: {
-    base::TimeDelta fadeout_delay = base::TimeDelta::FromMilliseconds(
-        layer_tree_impl_->settings().scrollbar_linear_fade_delay_ms);
-    base::TimeDelta fadeout_length = base::TimeDelta::FromMilliseconds(
-        layer_tree_impl_->settings().scrollbar_linear_fade_length_ms);
-
-    scrollbar_animation_controller_ =
-        ScrollbarAnimationControllerLinearFade::Create(
-            this, fadeout_delay, fadeout_length)
-            .PassAs<ScrollbarAnimationController>();
-    break;
-  }
-  case LayerTreeSettings::Thinning: {
-    scrollbar_animation_controller_ =
-        ScrollbarAnimationControllerThinning::Create(this)
-            .PassAs<ScrollbarAnimationController>();
-    break;
-  }
-  case LayerTreeSettings::NoAnimator:
-    NOTREACHED();
-    break;
-  }
+  scrollbar_animation_controller_ =
+      layer_tree_impl_->CreateScrollbarAnimationController(this);
 }
 
 void LayerImpl::ClearScrollbars() {
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index e712b7e..e84c669 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -158,7 +158,7 @@
 
   LayerTreeImpl* layer_tree_impl() const { return layer_tree_impl_; }
 
-  scoped_ptr<SharedQuadState> CreateSharedQuadState() const;
+  void PopulateSharedQuadState(SharedQuadState* state) const;
   // WillDraw must be called before AppendQuads. If WillDraw returns false,
   // AppendQuads and DidDraw will not be called. If WillDraw returns true,
   // DidDraw is guaranteed to be called before another WillDraw or before
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc
index 21cf4d2..e914857 100644
--- a/cc/layers/layer_unittest.cc
+++ b/cc/layers/layer_unittest.cc
@@ -835,6 +835,38 @@
   Mock::VerifyAndClearExpectations(layer_tree_host_.get());
 }
 
+TEST_F(LayerTest, TranformIsInvertibleAnimation) {
+  scoped_refptr<Layer> layer = Layer::Create();
+  scoped_ptr<LayerImpl> impl_layer =
+      LayerImpl::Create(host_impl_.active_tree(), 1);
+  EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1);
+  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
+  layer_tree_host_->SetRootLayer(layer);
+
+  EXPECT_TRUE(layer->transform_is_invertible());
+
+  gfx::Transform singular_transform;
+  singular_transform.Scale3d(
+      SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), SkDoubleToMScalar(0.0));
+
+  layer->SetTransform(singular_transform);
+  layer->PushPropertiesTo(impl_layer.get());
+
+  EXPECT_FALSE(layer->transform_is_invertible());
+  EXPECT_FALSE(impl_layer->transform_is_invertible());
+
+  gfx::Transform identity_transform;
+
+  layer->SetTransform(identity_transform);
+  static_cast<LayerAnimationValueObserver*>(layer)
+      ->OnTransformAnimated(singular_transform);
+  layer->PushPropertiesTo(impl_layer.get());
+  EXPECT_FALSE(layer->transform_is_invertible());
+  EXPECT_FALSE(impl_layer->transform_is_invertible());
+
+  Mock::VerifyAndClearExpectations(layer_tree_host_.get());
+}
+
 class LayerTreeHostFactory {
  public:
   LayerTreeHostFactory()
diff --git a/cc/layers/nine_patch_layer_impl.cc b/cc/layers/nine_patch_layer_impl.cc
index 95c286f..d0596ba 100644
--- a/cc/layers/nine_patch_layer_impl.cc
+++ b/cc/layers/nine_patch_layer_impl.cc
@@ -63,19 +63,13 @@
 }
 
 void NinePatchLayerImpl::CheckGeometryLimitations() {
-  // TODO(ccameron): the following "greater than or equal to" (GE) checks should
-  // be greater than (GT) to avoid degenerate nine-patches.  The relaxed
-  // condition "equal to" is a workaround for the overhang shadow use case and
-  // should be investigated further.
-
   // |border| is in layer space.  It cannot exceed the bounds of the layer.
-  DCHECK(!border_.size().IsEmpty());
   DCHECK_GE(bounds().width(), border_.width());
   DCHECK_GE(bounds().height(), border_.height());
 
   // Sanity Check on |border|
-  DCHECK_LT(border_.x(), border_.width());
-  DCHECK_LT(border_.y(), border_.height());
+  DCHECK_LE(border_.x(), border_.width());
+  DCHECK_LE(border_.y(), border_.height());
   DCHECK_GE(border_.x(), 0);
   DCHECK_GE(border_.y(), 0);
 
@@ -84,20 +78,14 @@
   DCHECK(gfx::Rect(image_bounds_).Contains(image_aperture_))
       << "image_bounds_ " << gfx::Rect(image_bounds_).ToString()
       << " image_aperture_ " << image_aperture_.ToString();
-
-  // Avoid the degenerate cases where the aperture touches the edge of the
-  // image.
-  DCHECK_LT(image_aperture_.width(), image_bounds_.width() - 1);
-  DCHECK_LT(image_aperture_.height(), image_bounds_.height() - 1);
-  DCHECK_GT(image_aperture_.x(), 0);
-  DCHECK_GT(image_aperture_.y(), 0);
 }
 
 void NinePatchLayerImpl::AppendQuads(QuadSink* quad_sink,
                                      AppendQuadsData* append_quads_data) {
   CheckGeometryLimitations();
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
+
   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
 
   if (!ui_resource_id_)
diff --git a/cc/layers/nine_patch_layer_impl_unittest.cc b/cc/layers/nine_patch_layer_impl_unittest.cc
index c40d915..28d1775 100644
--- a/cc/layers/nine_patch_layer_impl_unittest.cc
+++ b/cc/layers/nine_patch_layer_impl_unittest.cc
@@ -153,6 +153,66 @@
                            expected_quad_size);
 }
 
+TEST(NinePatchLayerImplTest, VerifyDrawQuadsWithEmptyPatches) {
+  // The top component of the 9-patch is empty, so there should be no quads for
+  // the top three components.
+  gfx::Size bitmap_size(100, 100);
+  gfx::Size layer_size(100, 100);
+  gfx::Rect aperture_rect(10, 0, 80, 90);
+  gfx::Rect border(10, 0, 20, 10);
+  bool fill_center = false;
+  size_t expected_quad_size = 5;
+  NinePatchLayerLayoutTest(bitmap_size,
+                           aperture_rect,
+                           layer_size,
+                           border,
+                           fill_center,
+                           expected_quad_size);
+
+  // The top and left components of the 9-patch are empty, so there should be no
+  // quads for the left and top components.
+  bitmap_size = gfx::Size(100, 100);
+  layer_size = gfx::Size(100, 100);
+  aperture_rect = gfx::Rect(0, 0, 90, 90);
+  border = gfx::Rect(0, 0, 10, 10);
+  fill_center = false;
+  expected_quad_size = 3;
+  NinePatchLayerLayoutTest(bitmap_size,
+                           aperture_rect,
+                           layer_size,
+                           border,
+                           fill_center,
+                           expected_quad_size);
+
+  // The aperture is the size of the bitmap and the center doesn't draw.
+  bitmap_size = gfx::Size(100, 100);
+  layer_size = gfx::Size(100, 100);
+  aperture_rect = gfx::Rect(0, 0, 100, 100);
+  border = gfx::Rect(0, 0, 0, 0);
+  fill_center = false;
+  expected_quad_size = 0;
+  NinePatchLayerLayoutTest(bitmap_size,
+                           aperture_rect,
+                           layer_size,
+                           border,
+                           fill_center,
+                           expected_quad_size);
+
+  // The aperture is the size of the bitmap and the center does draw.
+  bitmap_size = gfx::Size(100, 100);
+  layer_size = gfx::Size(100, 100);
+  aperture_rect = gfx::Rect(0, 0, 100, 100);
+  border = gfx::Rect(0, 0, 0, 0);
+  fill_center = true;
+  expected_quad_size = 1;
+  NinePatchLayerLayoutTest(bitmap_size,
+                           aperture_rect,
+                           layer_size,
+                           border,
+                           fill_center,
+                           expected_quad_size);
+}
+
 TEST(NinePatchLayerImplTest, Occlusion) {
   gfx::Size layer_size(1000, 1000);
   gfx::Size viewport_size(1000, 1000);
diff --git a/cc/layers/painted_scrollbar_layer_impl.cc b/cc/layers/painted_scrollbar_layer_impl.cc
index e4677f7..ac6ce4a 100644
--- a/cc/layers/painted_scrollbar_layer_impl.cc
+++ b/cc/layers/painted_scrollbar_layer_impl.cc
@@ -78,8 +78,9 @@
   gfx::Rect bounds_rect(bounds());
   gfx::Rect content_bounds_rect(content_bounds());
 
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
+
   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
 
   gfx::Rect thumb_quad_rect = ComputeThumbQuadRect();
diff --git a/cc/layers/picture_image_layer.cc b/cc/layers/picture_image_layer.cc
index c041936..a65ac8c 100644
--- a/cc/layers/picture_image_layer.cc
+++ b/cc/layers/picture_image_layer.cc
@@ -40,10 +40,12 @@
   SetNeedsDisplay();
 }
 
-void PictureImageLayer::PaintContents(SkCanvas* canvas,
-                                      const gfx::Rect& clip,
-                                      gfx::RectF* opaque) {
-  if (!canvas || !bitmap_.width() || !bitmap_.height())
+void PictureImageLayer::PaintContents(
+    SkCanvas* canvas,
+    const gfx::Rect& clip,
+    gfx::RectF* opaque,
+    ContentLayerClient::GraphicsContextStatus gc_status) {
+  if (!bitmap_.width() || !bitmap_.height())
     return;
 
   SkScalar content_to_layer_scale_x =
diff --git a/cc/layers/picture_image_layer.h b/cc/layers/picture_image_layer.h
index 1457a9f..69b89d1 100644
--- a/cc/layers/picture_image_layer.h
+++ b/cc/layers/picture_image_layer.h
@@ -28,7 +28,8 @@
   virtual void PaintContents(
       SkCanvas* canvas,
       const gfx::Rect& clip,
-      gfx::RectF* opaque) OVERRIDE;
+      gfx::RectF* opaque,
+      ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE;
   virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
   virtual bool FillsBoundsCompletely() const OVERRIDE;
 
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc
index c219230..18723c8 100644
--- a/cc/layers/picture_layer.cc
+++ b/cc/layers/picture_layer.cc
@@ -53,7 +53,7 @@
   }
 
   layer_impl->SetIsMask(is_mask_);
-  layer_impl->SetUseGpuRasterization(ShouldUseGpuRasterization());
+  layer_impl->SetUseGpuRasterization(layer_tree_host()->UseGpuRasterization());
 
   // Unlike other properties, invalidation must always be set on layer_impl.
   // See PictureLayerImpl::PushPropertiesTo for more details.
@@ -124,6 +124,7 @@
                            pile_invalidation_,
                            visible_layer_rect,
                            update_source_frame_number_,
+                           RecordingMode(),
                            rendering_stats_instrumentation());
   last_updated_visible_content_rect_ = visible_content_rect();
 
@@ -142,18 +143,15 @@
   is_mask_ = is_mask;
 }
 
-bool PictureLayer::ShouldUseGpuRasterization() const {
-  switch (layer_tree_host()->settings().rasterization_site) {
-    case LayerTreeSettings::CpuRasterization:
-      return false;
-    case LayerTreeSettings::HybridRasterization:
-      return layer_tree_host()->has_gpu_rasterization_trigger() &&
-             pile_->is_suitable_for_gpu_rasterization();
-    case LayerTreeSettings::GpuRasterization:
-      return true;
+Picture::RecordingMode PictureLayer::RecordingMode() const {
+  switch (layer_tree_host()->settings().recording_mode) {
+    case LayerTreeSettings::RecordNormally:
+      return Picture::RECORD_NORMALLY;
+    case LayerTreeSettings::RecordWithSkRecord:
+      return Picture::RECORD_WITH_SKRECORD;
   }
   NOTREACHED();
-  return false;
+  return Picture::RECORD_NORMALLY;
 }
 
 bool PictureLayer::SupportsLCDText() const {
@@ -173,11 +171,18 @@
 
   SkPictureRecorder recorder;
   SkCanvas* canvas = recorder.beginRecording(width, height, NULL, 0);
-  client_->PaintContents(canvas, gfx::Rect(width, height), &opaque);
+  client_->PaintContents(canvas,
+                         gfx::Rect(width, height),
+                         &opaque,
+                         ContentLayerClient::GRAPHICS_CONTEXT_ENABLED);
   skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording());
   return picture;
 }
 
+bool PictureLayer::IsSuitableForGpuRasterization() const {
+  return pile_->is_suitable_for_gpu_rasterization();
+}
+
 void PictureLayer::RunMicroBenchmark(MicroBenchmark* benchmark) {
   benchmark->RunOnLayer(this);
 }
diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h
index 184eea7..740bd85 100644
--- a/cc/layers/picture_layer.h
+++ b/cc/layers/picture_layer.h
@@ -35,12 +35,13 @@
   virtual void SetIsMask(bool is_mask) OVERRIDE;
   virtual bool SupportsLCDText() const OVERRIDE;
   virtual skia::RefPtr<SkPicture> GetPicture() const OVERRIDE;
+  virtual bool IsSuitableForGpuRasterization() const OVERRIDE;
 
   virtual void RunMicroBenchmark(MicroBenchmark* benchmark) OVERRIDE;
 
   ContentLayerClient* client() { return client_; }
 
-  bool ShouldUseGpuRasterization() const;
+  Picture::RecordingMode RecordingMode() const;
 
   PicturePile* GetPicturePileForTesting() const { return pile_.get(); }
 
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 5d3fb86..bd3b9dc 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -32,7 +32,14 @@
 // When creating a new tiling during pinch, snap to an existing
 // tiling's scale if the desired scale is within this ratio.
 const float kSnapToExistingTilingRatio = 0.2f;
-}
+
+// Estimate skewport 60 frames ahead for pre-rasterization on the CPU.
+const float kCpuSkewportTargetTimeInFrames = 60.0f;
+
+// Don't pre-rasterize on the GPU (except for kBackflingGuardDistancePixels in
+// TileManager::BinFromTilePriority).
+const float kGpuSkewportTargetTimeInFrames = 0.0f;
+}  // namespace
 
 namespace cc {
 
@@ -50,14 +57,14 @@
       raster_source_scale_(0.f),
       raster_contents_scale_(0.f),
       low_res_raster_contents_scale_(0.f),
-      raster_source_scale_was_animating_(false),
+      raster_source_scale_is_fixed_(false),
+      was_animating_transform_to_screen_(false),
       is_using_lcd_text_(tree_impl->settings().can_use_lcd_text),
       needs_post_commit_initialization_(true),
       should_update_tile_priorities_(false),
       should_use_low_res_tiling_(tree_impl->settings().create_low_res_tiling),
       use_gpu_rasterization_(false),
-      layer_needs_to_register_itself_(true),
-      uninitialized_tiles_required_for_activation_count_(0) {
+      layer_needs_to_register_itself_(true) {
 }
 
 PictureLayerImpl::~PictureLayerImpl() {
@@ -138,8 +145,8 @@
   gfx::Rect rect(visible_content_rect());
   gfx::Rect content_rect(content_bounds());
 
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
 
   if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
     AppendDebugBorderQuad(
@@ -407,7 +414,6 @@
                                  contents_scale_x(),
                                  current_frame_time_in_seconds);
 
-  uninitialized_tiles_required_for_activation_count_ = 0;
   if (layer_tree_impl()->IsPendingTree())
     MarkVisibleResourcesAsRequired();
 
@@ -420,13 +426,6 @@
     gfx::RectF layer_damage_rect =
         gfx::ScaleRect(tile->content_rect(), 1.f / tile->contents_scale());
     AddDamageRect(layer_damage_rect);
-
-    DCHECK_EQ(0, uninitialized_tiles_required_for_activation_count_);
-  } else if (layer_tree_impl()->IsPendingTree()) {
-    if (tile->required_for_activation()) {
-      DCHECK_GT(uninitialized_tiles_required_for_activation_count_, 0);
-      --uninitialized_tiles_required_for_activation_count_;
-    }
   }
 }
 
@@ -579,7 +578,12 @@
 }
 
 float PictureLayerImpl::GetSkewportTargetTimeInSeconds() const {
-  return layer_tree_impl()->settings().skewport_target_time_in_seconds;
+  float skewport_target_time_in_frames = ShouldUseGpuRasterization()
+                                             ? kGpuSkewportTargetTimeInFrames
+                                             : kCpuSkewportTargetTimeInFrames;
+  return skewport_target_time_in_frames *
+         layer_tree_impl()->begin_impl_frame_interval().InSecondsF() *
+         layer_tree_impl()->settings().skewport_target_time_multiplier;
 }
 
 int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const {
@@ -745,7 +749,7 @@
   return tile_version.get_resource_id();
 }
 
-void PictureLayerImpl::MarkVisibleResourcesAsRequired() {
+void PictureLayerImpl::MarkVisibleResourcesAsRequired() const {
   DCHECK(layer_tree_impl()->IsPendingTree());
   DCHECK(!layer_tree_impl()->needs_update_draw_properties());
   DCHECK(ideal_contents_scale_);
@@ -853,7 +857,7 @@
     const PictureLayerTiling* optional_twin_tiling,
     float contents_scale,
     const gfx::Rect& rect,
-    const Region& missing_region) {
+    const Region& missing_region) const {
   bool twin_had_missing_tile = false;
   for (PictureLayerTiling::CoverageIterator iter(tiling,
                                                  contents_scale,
@@ -880,10 +884,8 @@
         continue;
       }
     }
-    DCHECK(!tile->required_for_activation());
+
     tile->MarkRequiredForActivation();
-    if (!tile->IsReadyToDraw())
-      ++uninitialized_tiles_required_for_activation_count_;
   }
   return twin_had_missing_tile;
 }
@@ -977,15 +979,16 @@
         << "A layer with no tilings shouldn't have valid raster scales";
   }
 
-  // Store the value for the next time ShouldAdjustRasterScale is called.
-  raster_source_scale_was_animating_ = animating_transform_to_screen;
+  if (change_target_tiling) {
+    RecalculateRasterScales(animating_transform_to_screen,
+                            maximum_animation_contents_scale);
+  }
+
+  was_animating_transform_to_screen_ = animating_transform_to_screen;
 
   if (!change_target_tiling)
     return;
 
-  RecalculateRasterScales(animating_transform_to_screen,
-                          maximum_animation_contents_scale);
-
   PictureLayerTiling* high_res = NULL;
   PictureLayerTiling* low_res = NULL;
 
@@ -1032,12 +1035,7 @@
 
 bool PictureLayerImpl::ShouldAdjustRasterScale(
     bool animating_transform_to_screen) const {
-  // TODO(danakj): Adjust raster source scale closer to ideal source scale at
-  // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending
-  // tree. This will allow CSS scale changes to get re-rastered at an
-  // appropriate rate.
-
-  if (raster_source_scale_was_animating_ != animating_transform_to_screen)
+  if (was_animating_transform_to_screen_ != animating_transform_to_screen)
     return true;
 
   if (animating_transform_to_screen &&
@@ -1066,6 +1064,12 @@
   if (raster_device_scale_ != ideal_device_scale_)
     return true;
 
+  // When the source scale changes we want to match it, but not when animating
+  // or when we've fixed the scale in place.
+  if (!animating_transform_to_screen && !raster_source_scale_is_fixed_ &&
+      raster_source_scale_ != ideal_source_scale_)
+    return true;
+
   return false;
 }
 
@@ -1087,24 +1091,47 @@
 void PictureLayerImpl::RecalculateRasterScales(
     bool animating_transform_to_screen,
     float maximum_animation_contents_scale) {
-  raster_device_scale_ = ideal_device_scale_;
-  raster_source_scale_ = ideal_source_scale_;
+  float old_raster_contents_scale = raster_contents_scale_;
+  float old_raster_page_scale = raster_page_scale_;
+  float old_raster_source_scale = raster_source_scale_;
 
+  raster_device_scale_ = ideal_device_scale_;
+  raster_page_scale_ = ideal_page_scale_;
+  raster_source_scale_ = ideal_source_scale_;
+  raster_contents_scale_ = ideal_contents_scale_;
+
+  // If we're not animating, or leaving an animation, and the
+  // ideal_source_scale_ changes, then things are unpredictable, and we fix
+  // the raster_source_scale_ in place.
+  if (old_raster_source_scale && !animating_transform_to_screen &&
+      !was_animating_transform_to_screen_ &&
+      old_raster_source_scale != ideal_source_scale_)
+    raster_source_scale_is_fixed_ = true;
+
+  // TODO(danakj): Adjust raster source scale closer to ideal source scale at
+  // a throttled rate. Possibly make use of invalidation_.IsEmpty() on pending
+  // tree. This will allow CSS scale changes to get re-rastered at an
+  // appropriate rate.
+  if (raster_source_scale_is_fixed_) {
+    raster_contents_scale_ /= raster_source_scale_;
+    raster_source_scale_ = 1.f;
+  }
+
+  // During pinch we completely ignore the current ideal scale, and just use
+  // a multiple of the previous scale.
+  // TODO(danakj): This seems crazy, we should use the current ideal, no?
   bool is_pinching = layer_tree_impl()->PinchGestureActive();
-  if (!is_pinching || raster_contents_scale_ == 0.f) {
-    // When not pinching or when we have no previous scale, we use ideal scale:
-    raster_page_scale_ = ideal_page_scale_;
-    raster_contents_scale_ = ideal_contents_scale_;
-  } else {
+  if (is_pinching && old_raster_contents_scale) {
     // See ShouldAdjustRasterScale:
     // - When zooming out, preemptively create new tiling at lower resolution.
     // - When zooming in, approximate ideal using multiple of kMaxScaleRatio.
-    bool zooming_out = raster_page_scale_ > ideal_page_scale_;
+    bool zooming_out = old_raster_page_scale > ideal_page_scale_;
     float desired_contents_scale =
-        zooming_out ? raster_contents_scale_ / kMaxScaleRatioDuringPinch
-                    : raster_contents_scale_ * kMaxScaleRatioDuringPinch;
+        zooming_out ? old_raster_contents_scale / kMaxScaleRatioDuringPinch
+                    : old_raster_contents_scale * kMaxScaleRatioDuringPinch;
     raster_contents_scale_ = SnappedContentsScale(desired_contents_scale);
-    raster_page_scale_ = raster_contents_scale_ / raster_device_scale_;
+    raster_page_scale_ =
+        raster_contents_scale_ / raster_device_scale_ / raster_source_scale_;
   }
 
   raster_contents_scale_ =
@@ -1232,6 +1259,7 @@
   raster_source_scale_ = 0.f;
   raster_contents_scale_ = 0.f;
   low_res_raster_contents_scale_ = 0.f;
+  raster_source_scale_is_fixed_ = false;
 
   // When raster scales aren't valid, don't update tile priorities until
   // this layer has been updated via UpdateDrawProperties.
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index fc43b07..b559e3d 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -140,14 +140,6 @@
   WhichTree GetTree() const;
   bool IsOnActiveOrPendingTree() const;
 
-  // Return the count of tiles on this layer that meet both of the following
-  // conditions:
-  // 1. The tile is required for activation.
-  // 2. The tile needs initialization (ie, it's not ready to draw).
-  int UninitializedTilesRequiredForActivationCount() const {
-    return uninitialized_tiles_required_for_activation_count_;
-  }
-
  protected:
   friend class LayerRasterTileIterator;
 
@@ -171,13 +163,13 @@
   float SnappedContentsScale(float new_contents_scale);
   void UpdateLCDTextStatus(bool new_status);
   void ResetRasterScale();
-  void MarkVisibleResourcesAsRequired();
+  void MarkVisibleResourcesAsRequired() const;
   bool MarkVisibleTilesAsRequired(
       PictureLayerTiling* tiling,
       const PictureLayerTiling* optional_twin_tiling,
       float contents_scale,
       const gfx::Rect& rect,
-      const Region& missing_region);
+      const Region& missing_region) const;
 
   void DoPostCommitInitializationIfNeeded() {
     if (needs_post_commit_initialization_)
@@ -212,7 +204,8 @@
   float raster_contents_scale_;
   float low_res_raster_contents_scale_;
 
-  bool raster_source_scale_was_animating_;
+  bool raster_source_scale_is_fixed_;
+  bool was_animating_transform_to_screen_;
   bool is_using_lcd_text_;
   bool needs_post_commit_initialization_;
   // A sanity state check to make sure UpdateTilePriorities only gets called
@@ -229,8 +222,6 @@
   gfx::Size viewport_size_for_tile_priority_;
   gfx::Transform screen_space_transform_for_tile_priority_;
 
-  int uninitialized_tiles_required_for_activation_count_;
-
   friend class PictureLayer;
   DISALLOW_COPY_AND_ASSIGN(PictureLayerImpl);
 };
diff --git a/cc/layers/picture_layer_impl_perftest.cc b/cc/layers/picture_layer_impl_perftest.cc
index 5279c92..70befd9 100644
--- a/cc/layers/picture_layer_impl_perftest.cc
+++ b/cc/layers/picture_layer_impl_perftest.cc
@@ -10,6 +10,7 @@
 #include "cc/test/fake_picture_layer_impl.h"
 #include "cc/test/fake_picture_pile_impl.h"
 #include "cc/test/impl_side_painting_settings.h"
+#include "cc/test/lap_timer.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -25,11 +26,13 @@
 class PictureLayerImplPerfTest : public testing::Test {
  public:
   PictureLayerImplPerfTest()
-      : num_runs_(0),
-        proxy_(base::MessageLoopProxy::current()),
+      : proxy_(base::MessageLoopProxy::current()),
         host_impl_(ImplSidePaintingSettings(),
                    &proxy_,
-                   &shared_bitmap_manager_) {}
+                   &shared_bitmap_manager_),
+        timer_(kWarmupRuns,
+               base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
+               kTimeCheckInterval) {}
 
   virtual void SetUp() OVERRIDE {
     host_impl_.InitializeRenderer(
@@ -54,32 +57,13 @@
     pending_layer_->DoPostCommitInitializationIfNeeded();
   }
 
-  void EndTest() { elapsed_ = base::TimeTicks::HighResNow() - start_time_; }
-
-  bool DidRun() {
-    ++num_runs_;
-    if (num_runs_ == kWarmupRuns)
-      start_time_ = base::TimeTicks::HighResNow();
-
-    if (!start_time_.is_null() && (num_runs_ % kTimeCheckInterval) == 0) {
-      base::TimeDelta elapsed = base::TimeTicks::HighResNow() - start_time_;
-      if (elapsed >= base::TimeDelta::FromMilliseconds(kTimeLimitMillis)) {
-        elapsed_ = elapsed;
-        return false;
-      }
-    }
-    return true;
-  }
-
   void RunLayerRasterTileIteratorTest(const std::string& test_name,
                                       int num_tiles,
                                       const gfx::Size& viewport_size) {
-    start_time_ = base::TimeTicks();
-    num_runs_ = 0;
-
     host_impl_.SetViewportSize(viewport_size);
     host_impl_.pending_tree()->UpdateDrawProperties();
 
+    timer_.Reset();
     do {
       int count = num_tiles;
       for (PictureLayerImpl::LayerRasterTileIterator it(pending_layer_, false);
@@ -87,25 +71,23 @@
            ++it) {
         --count;
       }
-    } while (DidRun());
+      timer_.NextLap();
+    } while (!timer_.HasTimeLimitExpired());
 
     perf_test::PrintResult("layer_raster_tile_iterator",
                            "",
                            test_name,
-                           num_runs_ / elapsed_.InSecondsF(),
+                           timer_.LapsPerSecond(),
                            "runs/s",
                            true);
   }
 
  protected:
-  base::TimeTicks start_time_;
-  base::TimeDelta elapsed_;
-  int num_runs_;
-
   TestSharedBitmapManager shared_bitmap_manager_;
   FakeImplProxy proxy_;
   FakeLayerTreeHostImpl host_impl_;
   FakePictureLayerImpl* pending_layer_;
+  LapTimer timer_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(PictureLayerImplPerfTest);
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 9af89af..114c8a9 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -100,6 +100,8 @@
     SetupPendingTree(active_pile);
     ActivateTree();
     SetupPendingTree(pending_pile);
+    host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.f, 0.25f, 100.f);
+    host_impl_.active_tree()->SetPageScaleFactorAndLimits(1.f, 0.25f, 100.f);
   }
 
   void CreateHighLowResAndSetAllTilesVisible() {
@@ -695,43 +697,23 @@
   float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
   EXPECT_LT(low_res_factor, 1.f);
 
-  pending_layer_->CalculateContentsScale(1.3f,  // ideal contents scale
-                                         1.7f,  // device scale
-                                         3.2f,  // page scale
-                                         1.f,   // maximum animation scale
+  pending_layer_->CalculateContentsScale(6.f,  // ideal contents scale
+                                         3.f,  // device scale
+                                         2.f,  // page scale
+                                         1.f,  // maximum animation scale
                                          false,
                                          &result_scale_x,
                                          &result_scale_y,
                                          &result_bounds);
   ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
-  EXPECT_FLOAT_EQ(
-      1.3f,
-      pending_layer_->tilings()->tiling_at(0)->contents_scale());
-  EXPECT_FLOAT_EQ(
-      1.3f * low_res_factor,
-      pending_layer_->tilings()->tiling_at(1)->contents_scale());
-
-  // If we change the layer's CSS scale factor, then we should not get new
-  // tilings.
-  pending_layer_->CalculateContentsScale(1.8f,  // ideal contents scale
-                                         1.7f,  // device scale
-                                         3.2f,  // page scale
-                                         1.f,   // maximum animation scale
-                                         false,
-                                         &result_scale_x,
-                                         &result_scale_y,
-                                         &result_bounds);
-  ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
-  EXPECT_FLOAT_EQ(
-      1.3f,
-      pending_layer_->tilings()->tiling_at(0)->contents_scale());
-  EXPECT_FLOAT_EQ(
-      1.3f * low_res_factor,
-      pending_layer_->tilings()->tiling_at(1)->contents_scale());
+  EXPECT_FLOAT_EQ(6.f,
+                  pending_layer_->tilings()->tiling_at(0)->contents_scale());
+  EXPECT_FLOAT_EQ(6.f * low_res_factor,
+                  pending_layer_->tilings()->tiling_at(1)->contents_scale());
 
   // If we change the page scale factor, then we should get new tilings.
-  pending_layer_->CalculateContentsScale(1.8f,  // ideal contents scale
-                                         1.7f,  // device scale
+  pending_layer_->CalculateContentsScale(6.6f,  // ideal contents scale
+                                         3.f,   // device scale
                                          2.2f,  // page scale
                                          1.f,   // maximum animation scale
                                          false,
@@ -739,47 +721,41 @@
                                          &result_scale_y,
                                          &result_bounds);
   ASSERT_EQ(4u, pending_layer_->tilings()->num_tilings());
-  EXPECT_FLOAT_EQ(
-      1.8f,
-      pending_layer_->tilings()->tiling_at(0)->contents_scale());
-  EXPECT_FLOAT_EQ(
-      1.8f * low_res_factor,
-      pending_layer_->tilings()->tiling_at(2)->contents_scale());
+  EXPECT_FLOAT_EQ(6.6f,
+                  pending_layer_->tilings()->tiling_at(0)->contents_scale());
+  EXPECT_FLOAT_EQ(6.6f * low_res_factor,
+                  pending_layer_->tilings()->tiling_at(2)->contents_scale());
 
   // If we change the device scale factor, then we should get new tilings.
-  pending_layer_->CalculateContentsScale(1.9f,  // ideal contents scale
-                                         1.4f,  // device scale
-                                         2.2f,  // page scale
-                                         1.f,   // maximum animation scale
+  pending_layer_->CalculateContentsScale(7.26f,  // ideal contents scale
+                                         3.3f,   // device scale
+                                         2.2f,   // page scale
+                                         1.f,    // maximum animation scale
                                          false,
                                          &result_scale_x,
                                          &result_scale_y,
                                          &result_bounds);
   ASSERT_EQ(6u, pending_layer_->tilings()->num_tilings());
-  EXPECT_FLOAT_EQ(
-      1.9f,
-      pending_layer_->tilings()->tiling_at(0)->contents_scale());
-  EXPECT_FLOAT_EQ(
-      1.9f * low_res_factor,
-      pending_layer_->tilings()->tiling_at(3)->contents_scale());
+  EXPECT_FLOAT_EQ(7.26f,
+                  pending_layer_->tilings()->tiling_at(0)->contents_scale());
+  EXPECT_FLOAT_EQ(7.26f * low_res_factor,
+                  pending_layer_->tilings()->tiling_at(3)->contents_scale());
 
   // If we change the device scale factor, but end up at the same total scale
   // factor somehow, then we don't get new tilings.
-  pending_layer_->CalculateContentsScale(1.9f,  // ideal contents scale
-                                         2.2f,  // device scale
-                                         1.4f,  // page scale
-                                         1.f,   // maximum animation scale
+  pending_layer_->CalculateContentsScale(7.26f,  // ideal contents scale
+                                         2.2f,   // device scale
+                                         3.3f,   // page scale
+                                         1.f,    // maximum animation scale
                                          false,
                                          &result_scale_x,
                                          &result_scale_y,
                                          &result_bounds);
   ASSERT_EQ(6u, pending_layer_->tilings()->num_tilings());
-  EXPECT_FLOAT_EQ(
-      1.9f,
-      pending_layer_->tilings()->tiling_at(0)->contents_scale());
-  EXPECT_FLOAT_EQ(
-      1.9f * low_res_factor,
-      pending_layer_->tilings()->tiling_at(3)->contents_scale());
+  EXPECT_FLOAT_EQ(7.26f,
+                  pending_layer_->tilings()->tiling_at(0)->contents_scale());
+  EXPECT_FLOAT_EQ(7.26f * low_res_factor,
+                  pending_layer_->tilings()->tiling_at(3)->contents_scale());
 }
 
 TEST_F(PictureLayerImplTest, CreateTilingsEvenIfTwinHasNone) {
@@ -892,51 +868,45 @@
   // Set up the high and low res tilings before pinch zoom.
   SetupTrees(pending_pile, active_pile);
   EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
-  SetContentsScaleOnBothLayers(1.0f, 1.0f, 1.0f, 1.0f, false);
+  SetContentsScaleOnBothLayers(2.0f, 1.0f, 1.0f, 1.0f, false);
   float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
   EXPECT_EQ(2u, active_layer_->tilings()->num_tilings());
-  EXPECT_FLOAT_EQ(
-      1.0f,
-      active_layer_->tilings()->tiling_at(0)->contents_scale());
-  EXPECT_FLOAT_EQ(
-      1.0f * low_res_factor,
-      active_layer_->tilings()->tiling_at(1)->contents_scale());
+  EXPECT_FLOAT_EQ(2.0f,
+                  active_layer_->tilings()->tiling_at(0)->contents_scale());
+  EXPECT_FLOAT_EQ(2.0f * low_res_factor,
+                  active_layer_->tilings()->tiling_at(1)->contents_scale());
 
   // Start a pinch gesture.
   host_impl_.PinchGestureBegin();
 
   // Zoom out by a small amount. We should create a tiling at half
-  // the scale (1/kMaxScaleRatioDuringPinch).
-  SetContentsScaleOnBothLayers(0.90f, 1.0f, 0.9f, 1.0f, false);
+  // the scale (2/kMaxScaleRatioDuringPinch).
+  SetContentsScaleOnBothLayers(1.8f, 1.0f, 0.9f, 1.0f, false);
   EXPECT_EQ(3u, active_layer_->tilings()->num_tilings());
-  EXPECT_FLOAT_EQ(
-      1.0f,
-      active_layer_->tilings()->tiling_at(0)->contents_scale());
-  EXPECT_FLOAT_EQ(
-      0.5f,
-      active_layer_->tilings()->tiling_at(1)->contents_scale());
-  EXPECT_FLOAT_EQ(
-      1.0f * low_res_factor,
-      active_layer_->tilings()->tiling_at(2)->contents_scale());
+  EXPECT_FLOAT_EQ(2.0f,
+                  active_layer_->tilings()->tiling_at(0)->contents_scale());
+  EXPECT_FLOAT_EQ(1.0f,
+                  active_layer_->tilings()->tiling_at(1)->contents_scale());
+  EXPECT_FLOAT_EQ(2.0f * low_res_factor,
+                  active_layer_->tilings()->tiling_at(2)->contents_scale());
 
   // Zoom out further, close to our low-res scale factor. We should
   // use that tiling as high-res, and not create a new tiling.
   SetContentsScaleOnBothLayers(
-      low_res_factor, 1.0f, low_res_factor, 1.0f, false);
+      low_res_factor, 1.0f, low_res_factor / 2.0f, 1.0f, false);
   EXPECT_EQ(3u, active_layer_->tilings()->num_tilings());
 
   // Zoom in a lot now. Since we increase by increments of
-  // kMaxScaleRatioDuringPinch, this will first use 0.5, then 1.0
-  // and then finally create a new tiling at 2.0.
-  SetContentsScaleOnBothLayers(2.1f, 1.0f, 2.1f, 1.f, false);
+  // kMaxScaleRatioDuringPinch, this will first use 1.0, then 2.0
+  // and then finally create a new tiling at 4.0.
+  SetContentsScaleOnBothLayers(4.2f, 1.0f, 2.1f, 1.f, false);
   EXPECT_EQ(3u, active_layer_->tilings()->num_tilings());
-  SetContentsScaleOnBothLayers(2.1f, 1.0f, 2.1f, 1.f, false);
+  SetContentsScaleOnBothLayers(4.2f, 1.0f, 2.1f, 1.f, false);
   EXPECT_EQ(3u, active_layer_->tilings()->num_tilings());
-  SetContentsScaleOnBothLayers(2.1f, 1.0f, 2.1f, 1.f, false);
+  SetContentsScaleOnBothLayers(4.2f, 1.0f, 2.1f, 1.f, false);
   EXPECT_EQ(4u, active_layer_->tilings()->num_tilings());
-  EXPECT_FLOAT_EQ(
-      2.0f,
-      active_layer_->tilings()->tiling_at(0)->contents_scale());
+  EXPECT_FLOAT_EQ(4.0f,
+                  active_layer_->tilings()->tiling_at(0)->contents_scale());
 }
 
 TEST_F(PictureLayerImplTest, CleanUpTilings) {
@@ -960,8 +930,9 @@
 
   float device_scale = 1.7f;
   float page_scale = 3.2f;
+  float scale = 1.f;
 
-  SetContentsScaleOnBothLayers(1.f, device_scale, page_scale, 1.f, false);
+  SetContentsScaleOnBothLayers(scale, device_scale, page_scale, 1.f, false);
   ASSERT_EQ(2u, active_layer_->tilings()->num_tilings());
 
   // We only have ideal tilings, so they aren't removed.
@@ -969,8 +940,12 @@
   active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
   ASSERT_EQ(2u, active_layer_->tilings()->num_tilings());
 
+  host_impl_.PinchGestureBegin();
+
   // Changing the ideal but not creating new tilings.
-  SetContentsScaleOnBothLayers(1.5f, device_scale, page_scale, 1.f, false);
+  scale *= 1.5f;
+  page_scale *= 1.5f;
+  SetContentsScaleOnBothLayers(scale, device_scale, page_scale, 1.f, false);
   ASSERT_EQ(2u, active_layer_->tilings()->num_tilings());
 
   // The tilings are still our target scale, so they aren't removed.
@@ -978,8 +953,11 @@
   active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
   ASSERT_EQ(2u, active_layer_->tilings()->num_tilings());
 
+  host_impl_.PinchGestureEnd();
+
   // Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2.
-  page_scale = 1.2f;
+  scale /= 4.f;
+  page_scale /= 4.f;
   SetContentsScaleOnBothLayers(1.2f, device_scale, page_scale, 1.f, false);
   ASSERT_EQ(4u, active_layer_->tilings()->num_tilings());
   EXPECT_FLOAT_EQ(
@@ -1058,8 +1036,8 @@
 
 #define EXPECT_BOTH_EQ(expression, x)         \
   do {                                        \
-    EXPECT_EQ(pending_layer_->expression, x); \
-    EXPECT_EQ(active_layer_->expression, x);  \
+    EXPECT_EQ(x, pending_layer_->expression); \
+    EXPECT_EQ(x, active_layer_->expression);  \
   } while (false)
 
 TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) {
@@ -2279,5 +2257,45 @@
   }
 }
 
+TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) {
+  gfx::Size tile_size(host_impl_.settings().default_tile_size);
+  SetupDefaultTrees(tile_size);
+
+  float contents_scale = 2.f;
+  float device_scale = 1.f;
+  float page_scale = 1.f;
+  float maximum_animation_scale = 1.f;
+  bool animating_transform = false;
+
+  SetContentsScaleOnBothLayers(contents_scale,
+                               device_scale,
+                               page_scale,
+                               maximum_animation_scale,
+                               animating_transform);
+  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f);
+
+  // Changing the source scale without being in an animation will cause
+  // the layer to reset its source scale to 1.f.
+  contents_scale = 3.f;
+
+  SetContentsScaleOnBothLayers(contents_scale,
+                               device_scale,
+                               page_scale,
+                               maximum_animation_scale,
+                               animating_transform);
+  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f);
+
+  // Further changes to the source scale will no longer be reflected in the
+  // contents scale.
+  contents_scale = 0.5f;
+
+  SetContentsScaleOnBothLayers(contents_scale,
+                               device_scale,
+                               page_scale,
+                               maximum_animation_scale,
+                               animating_transform);
+  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f);
+}
+
 }  // namespace
 }  // namespace cc
diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc
index abbe869..bc52091 100644
--- a/cc/layers/picture_layer_unittest.cc
+++ b/cc/layers/picture_layer_unittest.cc
@@ -10,8 +10,6 @@
 #include "cc/test/fake_layer_tree_host.h"
 #include "cc/test/fake_picture_layer_impl.h"
 #include "cc/test/fake_proxy.h"
-#include "cc/test/gpu_rasterization_settings.h"
-#include "cc/test/hybrid_rasterization_settings.h"
 #include "cc/test/impl_side_painting_settings.h"
 #include "cc/trees/occlusion_tracker.h"
 #include "cc/trees/single_thread_proxy.h"
@@ -22,9 +20,11 @@
 
 class MockContentLayerClient : public ContentLayerClient {
  public:
-  virtual void PaintContents(SkCanvas* canvas,
-                             const gfx::Rect& clip,
-                             gfx::RectF* opaque) OVERRIDE {}
+  virtual void PaintContents(
+      SkCanvas* canvas,
+      const gfx::Rect& clip,
+      gfx::RectF* opaque,
+      ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {}
   virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
   virtual bool FillsBoundsCompletely() const OVERRIDE {
     return false;
@@ -69,85 +69,34 @@
   }
 }
 
-TEST(PictureLayerTest, ForcedCpuRaster) {
+TEST(PictureLayerTest, SuitableForGpuRasterization) {
   MockContentLayerClient client;
   scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
-
-  scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
-  host->SetRootLayer(layer);
-
-  // The default value is false.
-  EXPECT_FALSE(layer->ShouldUseGpuRasterization());
-
-  // Gpu rasterization cannot be enabled even with raster hint.
-  host->set_has_gpu_rasterization_trigger(true);
-  EXPECT_FALSE(layer->ShouldUseGpuRasterization());
-}
-
-TEST(PictureLayerTest, ForcedGpuRaster) {
-  MockContentLayerClient client;
-  scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
-
-  scoped_ptr<FakeLayerTreeHost> host =
-      FakeLayerTreeHost::Create(GpuRasterizationSettings());
-  host->SetRootLayer(layer);
-
-  // The default value is true.
-  EXPECT_TRUE(layer->ShouldUseGpuRasterization());
-
-  // Gpu rasterization cannot be disabled even with raster hint.
-  host->set_has_gpu_rasterization_trigger(false);
-  EXPECT_TRUE(layer->ShouldUseGpuRasterization());
-
-  // Gpu rasterization cannot be disabled even with skia veto.
   PicturePile* pile = layer->GetPicturePileForTesting();
+
+  // Layer is suitable for gpu rasterization by default.
   EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
-  pile->SetUnsuitableForGpuRasterizationForTesting();
-  EXPECT_TRUE(layer->ShouldUseGpuRasterization());
-}
-
-TEST(PictureLayerTest, HybridRaster) {
-  MockContentLayerClient client;
-  scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
-
-  scoped_ptr<FakeLayerTreeHost> host =
-      FakeLayerTreeHost::Create(HybridRasterizationSettings());
-  host->SetRootLayer(layer);
-
-  // The default value is false.
-  EXPECT_FALSE(layer->ShouldUseGpuRasterization());
-
-  // Gpu rasterization can be enabled.
-  host->set_has_gpu_rasterization_trigger(true);
-  EXPECT_TRUE(layer->ShouldUseGpuRasterization());
-
-  // Gpu rasterization can be disabled.
-  host->set_has_gpu_rasterization_trigger(false);
-  EXPECT_FALSE(layer->ShouldUseGpuRasterization());
-
-  // Gpu rasterization can be enabled again.
-  host->set_has_gpu_rasterization_trigger(true);
-  EXPECT_TRUE(layer->ShouldUseGpuRasterization());
-}
-
-TEST(PictureLayerTest, VetoGpuRaster) {
-  MockContentLayerClient client;
-  scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
-
-  scoped_ptr<FakeLayerTreeHost> host =
-      FakeLayerTreeHost::Create(HybridRasterizationSettings());
-  host->SetRootLayer(layer);
-
-  EXPECT_FALSE(layer->ShouldUseGpuRasterization());
-
-  host->set_has_gpu_rasterization_trigger(true);
-  EXPECT_TRUE(layer->ShouldUseGpuRasterization());
+  EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
 
   // Veto gpu rasterization.
-  PicturePile* pile = layer->GetPicturePileForTesting();
-  EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
   pile->SetUnsuitableForGpuRasterizationForTesting();
-  EXPECT_FALSE(layer->ShouldUseGpuRasterization());
+  EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
+  EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
+}
+
+TEST(PictureLayerTest, RecordingModes) {
+  MockContentLayerClient client;
+  scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
+
+  LayerTreeSettings settings;
+  scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(settings);
+  host->SetRootLayer(layer);
+  EXPECT_EQ(Picture::RECORD_NORMALLY, layer->RecordingMode());
+
+  settings.recording_mode = LayerTreeSettings::RecordWithSkRecord;
+  host = FakeLayerTreeHost::Create(settings);
+  host->SetRootLayer(layer);
+  EXPECT_EQ(Picture::RECORD_WITH_SKRECORD, layer->RecordingMode());
 }
 
 }  // namespace
diff --git a/cc/layers/quad_sink.h b/cc/layers/quad_sink.h
index 7312781..0b503e4 100644
--- a/cc/layers/quad_sink.h
+++ b/cc/layers/quad_sink.h
@@ -24,10 +24,9 @@
   virtual ~QuadSink() {}
 
   // Call this to add a SharedQuadState before appending quads that refer to it.
-  // Returns a pointer to the given SharedQuadState for convenience, that can be
-  // set on the quads to append.
-  virtual SharedQuadState* UseSharedQuadState(
-      scoped_ptr<SharedQuadState> shared_quad_state) = 0;
+  // Returns a pointer to the given SharedQuadState, that can be set on the
+  // quads to append.
+  virtual SharedQuadState* CreateSharedQuadState() = 0;
 
   virtual gfx::Rect UnoccludedContentRect(
       const gfx::Rect& content_rect,
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc
index fa7dcb8..3bce76f 100644
--- a/cc/layers/render_surface_impl.cc
+++ b/cc/layers/render_surface_impl.cc
@@ -150,8 +150,7 @@
   if (visible_content_rect.IsEmpty())
     return;
 
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(SharedQuadState::Create());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
   shared_quad_state->SetAll(draw_transform,
                             content_rect_.size(),
                             content_rect_,
diff --git a/cc/layers/render_surface_unittest.cc b/cc/layers/render_surface_unittest.cc
index 7056b1d..47ce276 100644
--- a/cc/layers/render_surface_unittest.cc
+++ b/cc/layers/render_surface_unittest.cc
@@ -107,17 +107,16 @@
   render_surface->SetClipRect(clip_rect);
   render_surface->SetDrawOpacity(1.f);
 
-  QuadList quad_list;
-  SharedQuadStateList shared_state_list;
-  MockQuadCuller mock_quad_culler(&quad_list, &shared_state_list);
+  scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+  MockQuadCuller mock_quad_culler(render_pass.get());
   AppendQuadsData append_quads_data;
 
   bool for_replica = false;
   render_surface->AppendQuads(
       &mock_quad_culler, &append_quads_data, for_replica, RenderPass::Id(2, 0));
 
-  ASSERT_EQ(1u, shared_state_list.size());
-  SharedQuadState* shared_quad_state = shared_state_list[0];
+  ASSERT_EQ(1u, render_pass->shared_quad_state_list.size());
+  SharedQuadState* shared_quad_state = render_pass->shared_quad_state_list[0];
 
   EXPECT_EQ(
       30.0,
diff --git a/cc/layers/scrollbar_layer_impl_base.cc b/cc/layers/scrollbar_layer_impl_base.cc
index dc9b92e..9db0254 100644
--- a/cc/layers/scrollbar_layer_impl_base.cc
+++ b/cc/layers/scrollbar_layer_impl_base.cc
@@ -31,7 +31,9 @@
 ScrollbarLayerImplBase::~ScrollbarLayerImplBase() {}
 
 void ScrollbarLayerImplBase::PushPropertiesTo(LayerImpl* layer) {
+  float active_opacity = layer->opacity();
   LayerImpl::PushPropertiesTo(layer);
+  layer->SetOpacity(active_opacity);
   DCHECK(layer->ToScrollbarLayer());
   layer->ToScrollbarLayer()->set_is_overlay_scrollbar(is_overlay_scrollbar_);
   PushScrollClipPropertiesTo(layer);
diff --git a/cc/layers/solid_color_layer_impl.cc b/cc/layers/solid_color_layer_impl.cc
index 2708af9..e60edd1 100644
--- a/cc/layers/solid_color_layer_impl.cc
+++ b/cc/layers/solid_color_layer_impl.cc
@@ -24,8 +24,9 @@
 
 void SolidColorLayerImpl::AppendQuads(QuadSink* quad_sink,
                                       AppendQuadsData* append_quads_data) {
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
+
   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
 
   // We create a series of smaller quads instead of just one large one so that
diff --git a/cc/layers/solid_color_scrollbar_layer_impl.cc b/cc/layers/solid_color_scrollbar_layer_impl.cc
index f579ea6..be2358c 100644
--- a/cc/layers/solid_color_scrollbar_layer_impl.cc
+++ b/cc/layers/solid_color_scrollbar_layer_impl.cc
@@ -57,7 +57,9 @@
                              is_overlay),
       thumb_thickness_(thumb_thickness),
       track_start_(track_start),
-      color_(tree_impl->settings().solid_color_scrollbar_color) {}
+      color_(tree_impl->settings().solid_color_scrollbar_color) {
+  SetOpacity(0.f);
+}
 
 void SolidColorScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) {
   ScrollbarLayerImplBase::PushPropertiesTo(layer);
@@ -94,8 +96,9 @@
 
 void SolidColorScrollbarLayerImpl::AppendQuads(QuadSink* quad_sink,
                            AppendQuadsData* append_quads_data) {
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
+
   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
 
   gfx::Rect thumb_quad_rect(ComputeThumbQuadRect());
diff --git a/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc b/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc
index ba82be5..480cd64 100644
--- a/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc
+++ b/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc
@@ -36,6 +36,8 @@
   scrollbar_layer_impl->SetCurrentPos(100.f / 4);
   scrollbar_layer_impl->SetMaximum(100);
   scrollbar_layer_impl->SetVisibleToTotalLengthRatio(1.f / 2);
+  // SolidColorScrollbarLayers construct with opacity = 0.f, so override.
+  scrollbar_layer_impl->SetOpacity(1.f);
 
   impl.CalcDrawProps(viewport_size);
 
diff --git a/cc/layers/surface_layer_impl.cc b/cc/layers/surface_layer_impl.cc
index 2f98805..3bfae2d 100644
--- a/cc/layers/surface_layer_impl.cc
+++ b/cc/layers/surface_layer_impl.cc
@@ -37,8 +37,9 @@
 
 void SurfaceLayerImpl::AppendQuads(QuadSink* quad_sink,
                                    AppendQuadsData* append_quads_data) {
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
+
   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
 
   if (!surface_id_)
diff --git a/cc/layers/texture_layer_impl.cc b/cc/layers/texture_layer_impl.cc
index 9cd94a3..5e65d72 100644
--- a/cc/layers/texture_layer_impl.cc
+++ b/cc/layers/texture_layer_impl.cc
@@ -143,8 +143,9 @@
                                    AppendQuadsData* append_quads_data) {
   DCHECK(external_texture_resource_ || valid_texture_copy_);
 
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
+
   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
 
   SkColor bg_color = blend_background_color_ ?
diff --git a/cc/layers/tiled_layer_impl.cc b/cc/layers/tiled_layer_impl.cc
index cc95a04..a510883 100644
--- a/cc/layers/tiled_layer_impl.cc
+++ b/cc/layers/tiled_layer_impl.cc
@@ -158,8 +158,9 @@
   DCHECK(!visible_content_rect().IsEmpty());
 
   gfx::Rect content_rect = visible_content_rect();
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
+
   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
 
   int left, top, right, bottom;
diff --git a/cc/layers/tiled_layer_impl_unittest.cc b/cc/layers/tiled_layer_impl_unittest.cc
index a92d024..2b18fff 100644
--- a/cc/layers/tiled_layer_impl_unittest.cc
+++ b/cc/layers/tiled_layer_impl_unittest.cc
@@ -67,8 +67,7 @@
     return layer.Pass();
   }
 
-  void GetQuads(QuadList* quads,
-                SharedQuadStateList* shared_states,
+  void GetQuads(RenderPass* render_pass,
                 const gfx::Size& tile_size,
                 const gfx::Size& layer_size,
                 LayerTilingData::BorderTexelOption border_texel_option,
@@ -78,7 +77,7 @@
     layer->draw_properties().visible_content_rect = visible_content_rect;
     layer->SetBounds(layer_size);
 
-    MockQuadCuller quad_culler(quads, shared_states);
+    MockQuadCuller quad_culler(render_pass);
     AppendQuadsData data;
     layer->AppendQuads(&quad_culler, &data);
   }
@@ -200,15 +199,14 @@
   void CoverageVisibleRectOnTileBoundaries(
       LayerTilingData::BorderTexelOption borders) {
     gfx::Size layer_size(1000, 1000);
-    QuadList quads;
-    SharedQuadStateList shared_states;
-    GetQuads(&quads,
-             &shared_states,
+    scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+    GetQuads(render_pass.get(),
              gfx::Size(100, 100),
              layer_size,
              borders,
              gfx::Rect(layer_size));
-    LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, gfx::Rect(layer_size));
+    LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass->quad_list,
+                                                 gfx::Rect(layer_size));
   }
 
   void CoverageVisibleRectIntersectsTiles(
@@ -219,30 +217,28 @@
     gfx::Rect visible_content_rect = gfx::BoundingRect(top_left, bottom_right);
 
     gfx::Size layer_size(250, 250);
-    QuadList quads;
-    SharedQuadStateList shared_states;
-    GetQuads(&quads,
-             &shared_states,
+    scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+    GetQuads(render_pass.get(),
              gfx::Size(50, 50),
              gfx::Size(250, 250),
              LayerTilingData::NO_BORDER_TEXELS,
              visible_content_rect);
-    LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, visible_content_rect);
+    LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass->quad_list,
+                                                 visible_content_rect);
   }
 
   void CoverageVisibleRectIntersectsBounds(
       LayerTilingData::BorderTexelOption borders) {
     gfx::Size layer_size(220, 210);
     gfx::Rect visible_content_rect(layer_size);
-    QuadList quads;
-    SharedQuadStateList shared_states;
-    GetQuads(&quads,
-             &shared_states,
+    scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+    GetQuads(render_pass.get(),
              gfx::Size(100, 100),
              layer_size,
              LayerTilingData::NO_BORDER_TEXELS,
              visible_content_rect);
-    LayerTestCommon::VerifyQuadsExactlyCoverRect(quads, visible_content_rect);
+    LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass->quad_list,
+                                                 visible_content_rect);
   }
 };
 WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectOnTileBoundaries);
@@ -254,17 +250,16 @@
 TEST_F(TiledLayerImplTest, TextureInfoForLayerNoBorders) {
   gfx::Size tile_size(50, 50);
   gfx::Size layer_size(250, 250);
-  QuadList quads;
-  SharedQuadStateList shared_states;
-  GetQuads(&quads,
-           &shared_states,
+  scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+  GetQuads(render_pass.get(),
            tile_size,
            layer_size,
            LayerTilingData::NO_BORDER_TEXELS,
            gfx::Rect(layer_size));
 
-  for (size_t i = 0; i < quads.size(); ++i) {
-    const TileDrawQuad* quad = TileDrawQuad::MaterialCast(quads[i]);
+  for (size_t i = 0; i < render_pass->quad_list.size(); ++i) {
+    const TileDrawQuad* quad =
+        TileDrawQuad::MaterialCast(render_pass->quad_list[i]);
 
     EXPECT_NE(0u, quad->resource_id) << LayerTestCommon::quad_string << i;
     EXPECT_EQ(gfx::RectF(gfx::PointF(), tile_size), quad->tex_coord_rect)
diff --git a/cc/layers/tiled_layer_unittest.cc b/cc/layers/tiled_layer_unittest.cc
index 35450b9..bc83743 100644
--- a/cc/layers/tiled_layer_unittest.cc
+++ b/cc/layers/tiled_layer_unittest.cc
@@ -122,7 +122,8 @@
     DebugScopedSetImplThreadAndMainThreadBlocked
         impl_thread_and_main_thread_blocked(proxy_);
     resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+        false);
     host_impl_ = make_scoped_ptr(
         new FakeLayerTreeHostImpl(proxy_, shared_bitmap_manager_.get()));
   }
diff --git a/cc/layers/ui_resource_layer_impl.cc b/cc/layers/ui_resource_layer_impl.cc
index 33392af..a5b563f 100644
--- a/cc/layers/ui_resource_layer_impl.cc
+++ b/cc/layers/ui_resource_layer_impl.cc
@@ -93,8 +93,9 @@
 
 void UIResourceLayerImpl::AppendQuads(QuadSink* quad_sink,
                                      AppendQuadsData* append_quads_data) {
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
+
   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
 
   if (!ui_resource_id_)
diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc
index e6e54a1..dad3159 100644
--- a/cc/layers/video_layer_impl.cc
+++ b/cc/layers/video_layer_impl.cc
@@ -128,8 +128,9 @@
                                  AppendQuadsData* append_quads_data) {
   DCHECK(frame_.get());
 
-  SharedQuadState* shared_quad_state =
-      quad_sink->UseSharedQuadState(CreateSharedQuadState());
+  SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+  PopulateSharedQuadState(shared_quad_state);
+
   AppendDebugBorderQuad(quad_sink, shared_quad_state, append_quads_data);
 
   gfx::Rect quad_rect(content_bounds());
@@ -183,6 +184,10 @@
       DCHECK_GE(frame_resources_.size(), 3u);
       if (frame_resources_.size() < 3u)
         break;
+      YUVVideoDrawQuad::ColorSpace color_space =
+          frame_->format() == media::VideoFrame::YV12J
+              ? YUVVideoDrawQuad::REC_601_JPEG
+              : YUVVideoDrawQuad::REC_601;
       gfx::RectF tex_coord_rect(
           tex_x_offset, tex_y_offset, tex_width_scale, tex_height_scale);
       scoped_ptr<YUVVideoDrawQuad> yuv_video_quad = YUVVideoDrawQuad::Create();
@@ -195,7 +200,8 @@
           frame_resources_[0],
           frame_resources_[1],
           frame_resources_[2],
-          frame_resources_.size() > 3 ? frame_resources_[3] : 0);
+          frame_resources_.size() > 3 ? frame_resources_[3] : 0,
+          color_space);
       quad_sink->Append(yuv_video_quad.PassAs<DrawQuad>());
       break;
     }
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index bb1ecbf..8e60f94 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -1777,9 +1777,12 @@
   // These values are magic numbers that are used in the transformation from YUV
   // to RGB color values.  They are taken from the following webpage:
   // http://www.fourcc.org/fccyvrgb.php
-  float yuv_to_rgb[9] = {1.164f, 1.164f, 1.164f, 0.0f, -.391f,
-                         2.018f, 1.596f, -.813f, 0.0f, };
-  GLC(gl_, gl_->UniformMatrix3fv(yuv_matrix_location, 1, 0, yuv_to_rgb));
+  float yuv_to_rgb_rec601[9] = {
+      1.164f, 1.164f, 1.164f, 0.0f, -.391f, 2.018f, 1.596f, -.813f, 0.0f,
+  };
+  float yuv_to_rgb_rec601_jpeg[9] = {
+      1.f, 1.f, 1.f, 0.0f, -.34414f, 1.772f, 1.402f, -.71414f, 0.0f,
+  };
 
   // These values map to 16, 128, and 128 respectively, and are computed
   // as a fraction over 256 (e.g. 16 / 256 = 0.0625).
@@ -1787,7 +1790,30 @@
   //   Y - 16   : Gives 16 values of head and footroom for overshooting
   //   U - 128  : Turns unsigned U into signed U [-128,127]
   //   V - 128  : Turns unsigned V into signed V [-128,127]
-  float yuv_adjust[3] = {-0.0625f, -0.5f, -0.5f, };
+  float yuv_adjust_rec601[3] = {
+      -0.0625f, -0.5f, -0.5f,
+  };
+
+  // Same as above, but without the head and footroom.
+  float yuv_adjust_rec601_jpeg[3] = {
+      0.0f, -0.5f, -0.5f,
+  };
+
+  float* yuv_to_rgb = NULL;
+  float* yuv_adjust = NULL;
+
+  switch (quad->color_space) {
+    case YUVVideoDrawQuad::REC_601:
+      yuv_to_rgb = yuv_to_rgb_rec601;
+      yuv_adjust = yuv_adjust_rec601;
+      break;
+    case YUVVideoDrawQuad::REC_601_JPEG:
+      yuv_to_rgb = yuv_to_rgb_rec601_jpeg;
+      yuv_adjust = yuv_adjust_rec601_jpeg;
+      break;
+  }
+
+  GLC(gl_, gl_->UniformMatrix3fv(yuv_matrix_location, 1, 0, yuv_to_rgb));
   GLC(gl_, gl_->Uniform3fv(yuv_adj_location, 1, yuv_adjust));
 
   SetShaderOpacity(quad->opacity(), alpha_location);
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index f82c06a..c5d729c 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -158,8 +158,8 @@
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ =
         ResourceProvider::Create(
-            output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1)
-            .Pass();
+            output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+            false).Pass();
     renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
                                                    &settings_,
                                                    output_surface_.get(),
@@ -191,8 +191,8 @@
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ =
         ResourceProvider::Create(
-            output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1)
-            .Pass();
+            output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+            false).Pass();
     renderer_.reset(new FakeRendererGL(&renderer_client_,
                                        &settings_,
                                        output_surface_.get(),
@@ -504,7 +504,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -540,7 +540,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -573,7 +573,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -619,7 +619,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -658,7 +658,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -739,7 +739,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -803,7 +803,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -882,7 +882,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   LayerTreeSettings settings;
   settings.should_clear_root_render_pass = false;
@@ -974,7 +974,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -1067,7 +1067,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   LayerTreeSettings settings;
   settings.partial_swap_enabled = true;
@@ -1252,7 +1252,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -1627,7 +1627,8 @@
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ =
         ResourceProvider::Create(
-            &output_surface_, shared_bitmap_manager_.get(), 0, false, 1).Pass();
+            &output_surface_, shared_bitmap_manager_.get(), 0, false, 1, false)
+            .Pass();
 
     renderer_.reset(new FakeRendererGL(&renderer_client_,
                                        &settings_,
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc
index 3b0c65a..69c11c0 100644
--- a/cc/output/overlay_unittest.cc
+++ b/cc/output/overlay_unittest.cc
@@ -111,9 +111,8 @@
                gfx::Transform(),
                has_transparent_background);
 
-  scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
+  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
   shared_state->opacity = 1.f;
-  pass->shared_quad_state_list.push_back(shared_state.Pass());
   return pass.Pass();
 }
 
@@ -213,7 +212,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      &output_surface, shared_bitmap_manager.get(), 0, false, 1));
+      &output_surface, shared_bitmap_manager.get(), 0, false, 1, false));
 
   scoped_ptr<DefaultOverlayProcessor> overlay_processor(
       new DefaultOverlayProcessor(&output_surface, resource_provider.get()));
@@ -232,7 +231,8 @@
 
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+        false);
 
     overlay_processor_.reset(new SingleOverlayProcessor(
         output_surface_.get(), resource_provider_.get()));
@@ -510,7 +510,8 @@
     output_surface_.reset(new OverlayOutputSurface(provider_));
     CHECK(output_surface_->BindToClient(&output_surface_client_));
     resource_provider_ =
-        ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1);
+        ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1,
+        false);
 
     provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind(
         &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_)));
diff --git a/cc/output/render_surface_filters.cc b/cc/output/render_surface_filters.cc
index 6160a93..34e056d 100644
--- a/cc/output/render_surface_filters.cc
+++ b/cc/output/render_surface_filters.cc
@@ -267,7 +267,7 @@
             SkAlphaThresholdFilter::Create(
                 op.region(), op.amount(), op.outer_threshold()));
         if (image_filter.get()) {
-          image_filter = skia::AdoptRef(new SkComposeImageFilter(
+          image_filter = skia::AdoptRef(SkComposeImageFilter::Create(
               alpha_filter.get(), image_filter.get()));
         } else {
           image_filter = alpha_filter;
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
index ce3abfa..291563b 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -48,15 +48,17 @@
   return pass.Pass();
 }
 
-scoped_ptr<SharedQuadState> CreateTestSharedQuadState(
-    gfx::Transform content_to_target_transform, const gfx::Rect& rect) {
+SharedQuadState* CreateTestSharedQuadState(
+    RenderPass* render_pass,
+    gfx::Transform content_to_target_transform,
+    const gfx::Rect& rect) {
   const gfx::Size content_bounds = rect.size();
   const gfx::Rect visible_content_rect = rect;
   const gfx::Rect clip_rect = rect;
   const bool is_clipped = false;
   const float opacity = 1.0f;
   const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
-  scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
+  SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
   shared_state->SetAll(content_to_target_transform,
                        content_bounds,
                        visible_content_rect,
@@ -64,10 +66,11 @@
                        is_clipped,
                        opacity,
                        blend_mode);
-  return shared_state.Pass();
+  return shared_state;
 }
 
-scoped_ptr<SharedQuadState> CreateTestSharedQuadStateClipped(
+SharedQuadState* CreateTestSharedQuadStateClipped(
+    RenderPass* render_pass,
     gfx::Transform content_to_target_transform,
     const gfx::Rect& rect,
     const gfx::Rect& clip_rect) {
@@ -76,7 +79,7 @@
   const bool is_clipped = true;
   const float opacity = 1.0f;
   const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
-  scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
+  SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
   shared_state->SetAll(content_to_target_transform,
                        content_bounds,
                        visible_content_rect,
@@ -84,7 +87,7 @@
                        is_clipped,
                        opacity,
                        blend_mode);
-  return shared_state.Pass();
+  return shared_state;
 }
 
 scoped_ptr<DrawQuad> CreateTestRenderPassDrawQuad(
@@ -205,11 +208,11 @@
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
 
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
 
   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
-  color_quad->SetNew(shared_state.get(), rect, rect, SK_ColorGREEN, false);
+  color_quad->SetNew(shared_state, rect, rect, SK_ColorGREEN, false);
 
   pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
 
@@ -230,25 +233,22 @@
   scoped_ptr<RenderPass> child_pass =
       CreateTestRenderPass(child_id, small_rect, gfx::Transform());
 
-  scoped_ptr<SharedQuadState> child_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), small_rect);
+  SharedQuadState* child_shared_state =
+      CreateTestSharedQuadState(child_pass.get(), gfx::Transform(), small_rect);
 
   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
-  color_quad->SetNew(
-      child_shared_state.get(), rect, rect, SK_ColorGREEN, false);
+  color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false);
   child_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
 
   RenderPass::Id root_id(1, 1);
   scoped_ptr<RenderPass> root_pass =
       CreateTestRenderPass(root_id, rect, gfx::Transform());
 
-  scoped_ptr<SharedQuadState> root_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* root_shared_state =
+      CreateTestSharedQuadState(root_pass.get(), gfx::Transform(), rect);
 
   scoped_ptr<DrawQuad> render_pass_quad =
-      CreateTestRenderPassDrawQuad(root_shared_state.get(),
-                                   small_rect,
-                                   child_id);
+      CreateTestRenderPassDrawQuad(root_shared_state, small_rect, child_id);
   root_pass->quad_list.push_back(render_pass_quad.PassAs<DrawQuad>());
 
   RenderPass* child_pass_ptr = child_pass.get();
@@ -270,20 +270,20 @@
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
 
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
 
-  scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad(
-      gfx::Rect(this->device_viewport_size_),
-      SkColorSetARGB(128, 0, 255, 0),  // Texel color.
-      SK_ColorTRANSPARENT,  // Background color.
-      true,  // Premultiplied alpha.
-      shared_state.get(),
-      this->resource_provider_.get());
+  scoped_ptr<TextureDrawQuad> texture_quad =
+      CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
+                                SkColorSetARGB(128, 0, 255, 0),  // Texel color.
+                                SK_ColorTRANSPARENT,  // Background color.
+                                true,                 // Premultiplied alpha.
+                                shared_state,
+                                this->resource_provider_.get());
   pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>());
 
   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
-  color_quad->SetNew(shared_state.get(), rect, rect, SK_ColorWHITE, false);
+  color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
   pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
 
   RenderPassList pass_list;
@@ -301,23 +301,23 @@
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
 
-  scoped_ptr<SharedQuadState> texture_quad_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* texture_quad_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
   texture_quad_state->opacity = 0.8f;
 
   scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad(
       gfx::Rect(this->device_viewport_size_),
       SkColorSetARGB(204, 120, 255, 120),  // Texel color.
-      SK_ColorGREEN,  // Background color.
-      true,  // Premultiplied alpha.
-      texture_quad_state.get(),
+      SK_ColorGREEN,                       // Background color.
+      true,                                // Premultiplied alpha.
+      texture_quad_state,
       this->resource_provider_.get());
   pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>());
 
-  scoped_ptr<SharedQuadState> color_quad_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* color_quad_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
-  color_quad->SetNew(color_quad_state.get(), rect, rect, SK_ColorWHITE, false);
+  color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
   pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
 
   RenderPassList pass_list;
@@ -336,20 +336,20 @@
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
 
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
 
-  scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad(
-      gfx::Rect(this->device_viewport_size_),
-      SkColorSetARGB(128, 0, 255, 0),  // Texel color.
-      SK_ColorTRANSPARENT,  // Background color.
-      false,  // Premultiplied alpha.
-      shared_state.get(),
-      this->resource_provider_.get());
+  scoped_ptr<TextureDrawQuad> texture_quad =
+      CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
+                                SkColorSetARGB(128, 0, 255, 0),  // Texel color.
+                                SK_ColorTRANSPARENT,  // Background color.
+                                false,                // Premultiplied alpha.
+                                shared_state,
+                                this->resource_provider_.get());
   pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>());
 
   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
-  color_quad->SetNew(shared_state.get(), rect, rect, SK_ColorWHITE, false);
+  color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
   pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
 
   RenderPassList pass_list;
@@ -368,23 +368,23 @@
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
 
-  scoped_ptr<SharedQuadState> texture_quad_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* texture_quad_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
   texture_quad_state->opacity = 0.8f;
 
   scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad(
       gfx::Rect(this->device_viewport_size_),
       SkColorSetARGB(204, 120, 255, 120),  // Texel color.
-      SK_ColorGREEN,  // Background color.
-      false,  // Premultiplied alpha.
-      texture_quad_state.get(),
+      SK_ColorGREEN,                       // Background color.
+      false,                               // Premultiplied alpha.
+      texture_quad_state,
       this->resource_provider_.get());
   pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>());
 
-  scoped_ptr<SharedQuadState> color_quad_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* color_quad_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
-  color_quad->SetNew(color_quad_state.get(), rect, rect, SK_ColorWHITE, false);
+  color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
   pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
 
   RenderPassList pass_list;
@@ -398,14 +398,12 @@
 
 class VideoGLRendererPixelTest : public GLRendererPixelTest {
  protected:
-  scoped_ptr<YUVVideoDrawQuad> CreateTestYUVVideoDrawQuad(
+  scoped_ptr<YUVVideoDrawQuad> CreateTestYUVVideoDrawQuad_Striped(
       SharedQuadState* shared_state,
       media::VideoFrame::Format format,
       bool is_transparent,
       const gfx::RectF& tex_coord_rect) {
-    const bool with_alpha = (format == media::VideoFrame::YV12A);
     const gfx::Rect rect(this->device_viewport_size_);
-    const gfx::Rect opaque_rect(0, 0, 0, 0);
 
     scoped_refptr<media::VideoFrame> video_frame =
         media::VideoFrame::CreateFrame(
@@ -435,6 +433,56 @@
         v_row[j] = (v_value += 5);
       }
     }
+    return CreateTestYUVVideoDrawQuad_FromVideoFrame(
+        shared_state, video_frame, is_transparent, tex_coord_rect);
+  }
+
+  scoped_ptr<YUVVideoDrawQuad> CreateTestYUVVideoDrawQuad_Solid(
+      SharedQuadState* shared_state,
+      media::VideoFrame::Format format,
+      bool is_transparent,
+      const gfx::RectF& tex_coord_rect,
+      uint8 y,
+      uint8 u,
+      uint8 v) {
+    const gfx::Rect rect(this->device_viewport_size_);
+
+    scoped_refptr<media::VideoFrame> video_frame =
+        media::VideoFrame::CreateFrame(
+            format, rect.size(), rect, rect.size(), base::TimeDelta());
+
+    // YUV values of a solid, constant, color. Useful for testing that color
+    // space/color range are being handled properly.
+    memset(video_frame->data(media::VideoFrame::kYPlane),
+           y,
+           video_frame->stride(media::VideoFrame::kYPlane) *
+               video_frame->rows(media::VideoFrame::kYPlane));
+    memset(video_frame->data(media::VideoFrame::kUPlane),
+           u,
+           video_frame->stride(media::VideoFrame::kUPlane) *
+               video_frame->rows(media::VideoFrame::kUPlane));
+    memset(video_frame->data(media::VideoFrame::kVPlane),
+           v,
+           video_frame->stride(media::VideoFrame::kVPlane) *
+               video_frame->rows(media::VideoFrame::kVPlane));
+
+    return CreateTestYUVVideoDrawQuad_FromVideoFrame(
+        shared_state, video_frame, is_transparent, tex_coord_rect);
+  }
+
+  scoped_ptr<YUVVideoDrawQuad> CreateTestYUVVideoDrawQuad_FromVideoFrame(
+      SharedQuadState* shared_state,
+      scoped_refptr<media::VideoFrame> video_frame,
+      bool is_transparent,
+      const gfx::RectF& tex_coord_rect) {
+    const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
+    const YUVVideoDrawQuad::ColorSpace color_space =
+        (video_frame->format() == media::VideoFrame::YV12J
+             ? YUVVideoDrawQuad::REC_601_JPEG
+             : YUVVideoDrawQuad::REC_601);
+    const gfx::Rect rect(this->device_viewport_size_);
+    const gfx::Rect opaque_rect(0, 0, 0, 0);
+
     if (with_alpha)
       memset(video_frame->data(media::VideoFrame::kAPlane),
              is_transparent ? 0 : 128,
@@ -446,8 +494,9 @@
             video_frame);
 
     EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
-    EXPECT_EQ(media::VideoFrame::NumPlanes(format), resources.mailboxes.size());
-    EXPECT_EQ(media::VideoFrame::NumPlanes(format),
+    EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
+              resources.mailboxes.size());
+    EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
               resources.release_callbacks.size());
 
     ResourceProvider::ResourceId y_resource =
@@ -482,7 +531,8 @@
                      y_resource,
                      u_resource,
                      v_resource,
-                     a_resource);
+                     a_resource,
+                     color_space);
     return yuv_quad.Pass();
   }
 
@@ -502,14 +552,14 @@
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
 
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
 
   scoped_ptr<YUVVideoDrawQuad> yuv_quad =
-      CreateTestYUVVideoDrawQuad(shared_state.get(),
-                                 media::VideoFrame::YV12,
-                                 false,
-                                 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f));
+      CreateTestYUVVideoDrawQuad_Striped(shared_state,
+                                         media::VideoFrame::YV12,
+                                         false,
+                                         gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f));
 
   pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
 
@@ -528,15 +578,15 @@
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
 
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
 
   // Intentionally sets frame format to I420 for testing coverage.
-  scoped_ptr<YUVVideoDrawQuad> yuv_quad =
-      CreateTestYUVVideoDrawQuad(shared_state.get(),
-                                 media::VideoFrame::I420,
-                                 false,
-                                 gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f));
+  scoped_ptr<YUVVideoDrawQuad> yuv_quad = CreateTestYUVVideoDrawQuad_Striped(
+      shared_state,
+      media::VideoFrame::I420,
+      false,
+      gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f));
 
   pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
 
@@ -549,25 +599,115 @@
       FuzzyPixelOffByOneComparator(true)));
 }
 
+TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
+  gfx::Rect rect(this->device_viewport_size_);
+
+  RenderPass::Id id(1, 1);
+  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
+
+  SharedQuadState* shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
+
+  // In MPEG color range YUV values of (15,128,128) should produce black.
+  scoped_ptr<YUVVideoDrawQuad> yuv_quad =
+      CreateTestYUVVideoDrawQuad_Solid(shared_state,
+                                       media::VideoFrame::YV12,
+                                       false,
+                                       gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
+                                       15,
+                                       128,
+                                       128);
+
+  pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
+
+  RenderPassList pass_list;
+  pass_list.push_back(pass.Pass());
+
+  // If we didn't get black out of the YUV values above, then we probably have a
+  // color range issue.
+  EXPECT_TRUE(this->RunPixelTest(&pass_list,
+                                 base::FilePath(FILE_PATH_LITERAL("black.png")),
+                                 FuzzyPixelOffByOneComparator(true)));
+}
+
+TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
+  gfx::Rect rect(this->device_viewport_size_);
+
+  RenderPass::Id id(1, 1);
+  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
+
+  SharedQuadState* shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
+
+  // YUV of (149,43,21) should be green (0,255,0) in RGB.
+  scoped_ptr<YUVVideoDrawQuad> yuv_quad =
+      CreateTestYUVVideoDrawQuad_Solid(shared_state,
+                                       media::VideoFrame::YV12J,
+                                       false,
+                                       gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
+                                       149,
+                                       43,
+                                       21);
+
+  pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
+
+  RenderPassList pass_list;
+  pass_list.push_back(pass.Pass());
+
+  EXPECT_TRUE(this->RunPixelTest(&pass_list,
+                                 base::FilePath(FILE_PATH_LITERAL("green.png")),
+                                 FuzzyPixelOffByOneComparator(true)));
+}
+
+TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
+  gfx::Rect rect(this->device_viewport_size_);
+
+  RenderPass::Id id(1, 1);
+  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
+
+  SharedQuadState* shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
+
+  // Dark grey in JPEG color range (in MPEG, this is black).
+  scoped_ptr<YUVVideoDrawQuad> yuv_quad =
+      CreateTestYUVVideoDrawQuad_Solid(shared_state,
+                                       media::VideoFrame::YV12J,
+                                       false,
+                                       gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
+                                       15,
+                                       128,
+                                       128);
+
+  pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
+
+  RenderPassList pass_list;
+  pass_list.push_back(pass.Pass());
+
+  EXPECT_TRUE(
+      this->RunPixelTest(&pass_list,
+                         base::FilePath(FILE_PATH_LITERAL("dark_grey.png")),
+                         FuzzyPixelOffByOneComparator(true)));
+}
+
 TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) {
   gfx::Rect rect(this->device_viewport_size_);
 
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
 
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
 
   scoped_ptr<YUVVideoDrawQuad> yuv_quad =
-      CreateTestYUVVideoDrawQuad(shared_state.get(),
-                                 media::VideoFrame::YV12A,
-                                 false,
-                                 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f));
+      CreateTestYUVVideoDrawQuad_Striped(shared_state,
+                                         media::VideoFrame::YV12A,
+                                         false,
+                                         gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f));
 
   pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
 
   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
-  color_quad->SetNew(shared_state.get(), rect, rect, SK_ColorWHITE, false);
+  color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
 
   pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
 
@@ -586,19 +726,19 @@
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
 
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
 
   scoped_ptr<YUVVideoDrawQuad> yuv_quad =
-      CreateTestYUVVideoDrawQuad(shared_state.get(),
-                                 media::VideoFrame::YV12A,
-                                 true,
-                                 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f));
+      CreateTestYUVVideoDrawQuad_Striped(shared_state,
+                                         media::VideoFrame::YV12A,
+                                         true,
+                                         gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f));
 
   pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
 
   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
-  color_quad->SetNew(shared_state.get(), rect, rect, SK_ColorBLACK, false);
+  color_quad->SetNew(shared_state, rect, rect, SK_ColorBLACK, false);
 
   pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
 
@@ -625,8 +765,8 @@
       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
 
   gfx::Transform content_to_target_transform;
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+  SharedQuadState* shared_state = CreateTestSharedQuadState(
+      child_pass.get(), content_to_target_transform, viewport_rect);
   shared_state->opacity = 0.5f;
 
   gfx::Rect blue_rect(0,
@@ -634,28 +774,27 @@
                       this->device_viewport_size_.width(),
                       this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(shared_state.get(), blue_rect, blue_rect, SK_ColorBLUE, false);
+  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
   gfx::Rect yellow_rect(0,
                         this->device_viewport_size_.height() / 2,
                         this->device_viewport_size_.width(),
                         this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
-  yellow->SetNew(
-      shared_state.get(), yellow_rect, yellow_rect, SK_ColorYELLOW, false);
+  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
 
-  scoped_ptr<SharedQuadState> blank_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+  SharedQuadState* blank_state = CreateTestSharedQuadState(
+      child_pass.get(), content_to_target_transform, viewport_rect);
 
   scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create();
   white->SetNew(
-      blank_state.get(), viewport_rect, viewport_rect, SK_ColorWHITE, false);
+      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
 
   child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
   child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
   child_pass->quad_list.push_back(white.PassAs<DrawQuad>());
 
-  scoped_ptr<SharedQuadState> pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect);
+  SharedQuadState* pass_shared_state =
+      CreateTestSharedQuadState(root_pass.get(), gfx::Transform(), pass_rect);
 
   SkScalar matrix[20];
   float amount = 0.5f;
@@ -682,7 +821,7 @@
 
   scoped_ptr<RenderPassDrawQuad> render_pass_quad =
       RenderPassDrawQuad::Create();
-  render_pass_quad->SetNew(pass_shared_state.get(),
+  render_pass_quad->SetNew(pass_shared_state,
                            pass_rect,
                            pass_rect,
                            child_pass_id,
@@ -721,8 +860,8 @@
       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
 
   gfx::Transform content_to_target_transform;
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+  SharedQuadState* shared_state = CreateTestSharedQuadState(
+      child_pass.get(), content_to_target_transform, viewport_rect);
   shared_state->opacity = 0.5f;
 
   gfx::Rect blue_rect(0,
@@ -730,35 +869,34 @@
                       this->device_viewport_size_.width(),
                       this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(shared_state.get(), blue_rect, blue_rect, SK_ColorBLUE, false);
+  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
   gfx::Rect yellow_rect(0,
                         this->device_viewport_size_.height() / 2,
                         this->device_viewport_size_.width(),
                         this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
-  yellow->SetNew(
-      shared_state.get(), yellow_rect, yellow_rect, SK_ColorYELLOW, false);
+  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
 
-  scoped_ptr<SharedQuadState> blank_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+  SharedQuadState* blank_state = CreateTestSharedQuadState(
+      child_pass.get(), content_to_target_transform, viewport_rect);
 
   scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create();
   white->SetNew(
-      blank_state.get(), viewport_rect, viewport_rect, SK_ColorWHITE, false);
+      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
 
   child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
   child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
   child_pass->quad_list.push_back(white.PassAs<DrawQuad>());
 
-  scoped_ptr<SharedQuadState> pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect);
+  SharedQuadState* pass_shared_state =
+      CreateTestSharedQuadState(root_pass.get(), gfx::Transform(), pass_rect);
 
   FilterOperations filters;
   filters.Append(FilterOperation::CreateSaturateFilter(0.5f));
 
   scoped_ptr<RenderPassDrawQuad> render_pass_quad =
       RenderPassDrawQuad::Create();
-  render_pass_quad->SetNew(pass_shared_state.get(),
+  render_pass_quad->SetNew(pass_shared_state,
                            pass_rect,
                            pass_rect,
                            child_pass_id,
@@ -795,8 +933,8 @@
       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
 
   gfx::Transform content_to_target_transform;
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+  SharedQuadState* shared_state = CreateTestSharedQuadState(
+      child_pass.get(), content_to_target_transform, viewport_rect);
   shared_state->opacity = 0.5f;
 
   gfx::Rect blue_rect(0,
@@ -804,28 +942,27 @@
                       this->device_viewport_size_.width(),
                       this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(shared_state.get(), blue_rect, blue_rect, SK_ColorBLUE, false);
+  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
   gfx::Rect yellow_rect(0,
                         this->device_viewport_size_.height() / 2,
                         this->device_viewport_size_.width(),
                         this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
-  yellow->SetNew(
-      shared_state.get(), yellow_rect, yellow_rect, SK_ColorYELLOW, false);
+  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
 
-  scoped_ptr<SharedQuadState> blank_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+  SharedQuadState* blank_state = CreateTestSharedQuadState(
+      child_pass.get(), content_to_target_transform, viewport_rect);
 
   scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create();
   white->SetNew(
-      blank_state.get(), viewport_rect, viewport_rect, SK_ColorWHITE, false);
+      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
 
   child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
   child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
   child_pass->quad_list.push_back(white.PassAs<DrawQuad>());
 
-  scoped_ptr<SharedQuadState> pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect);
+  SharedQuadState* pass_shared_state =
+      CreateTestSharedQuadState(root_pass.get(), gfx::Transform(), pass_rect);
 
   FilterOperations filters;
   filters.Append(FilterOperation::CreateGrayscaleFilter(1.f));
@@ -833,7 +970,7 @@
 
   scoped_ptr<RenderPassDrawQuad> render_pass_quad =
       RenderPassDrawQuad::Create();
-  render_pass_quad->SetNew(pass_shared_state.get(),
+  render_pass_quad->SetNew(pass_shared_state,
                            pass_rect,
                            pass_rect,
                            child_pass_id,
@@ -870,8 +1007,8 @@
       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
 
   gfx::Transform content_to_target_transform;
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+  SharedQuadState* shared_state = CreateTestSharedQuadState(
+      child_pass.get(), content_to_target_transform, viewport_rect);
   shared_state->opacity = 0.5f;
 
   gfx::Rect blue_rect(0,
@@ -879,28 +1016,27 @@
                       this->device_viewport_size_.width(),
                       this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(shared_state.get(), blue_rect, blue_rect, SK_ColorBLUE, false);
+  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
   gfx::Rect yellow_rect(0,
                         this->device_viewport_size_.height() / 2,
                         this->device_viewport_size_.width(),
                         this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
-  yellow->SetNew(
-      shared_state.get(), yellow_rect, yellow_rect, SK_ColorYELLOW, false);
+  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
 
-  scoped_ptr<SharedQuadState> blank_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+  SharedQuadState* blank_state = CreateTestSharedQuadState(
+      child_pass.get(), content_to_target_transform, viewport_rect);
 
   scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create();
   white->SetNew(
-      blank_state.get(), viewport_rect, viewport_rect, SK_ColorWHITE, false);
+      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
 
   child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
   child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
   child_pass->quad_list.push_back(white.PassAs<DrawQuad>());
 
-  scoped_ptr<SharedQuadState> pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect);
+  SharedQuadState* pass_shared_state =
+      CreateTestSharedQuadState(root_pass.get(), gfx::Transform(), pass_rect);
 
   SkScalar matrix[20];
   float amount = 0.5f;
@@ -930,7 +1066,7 @@
 
   scoped_ptr<RenderPassDrawQuad> render_pass_quad =
       RenderPassDrawQuad::Create();
-  render_pass_quad->SetNew(pass_shared_state.get(),
+  render_pass_quad->SetNew(pass_shared_state,
                            pass_rect,
                            pass_rect,
                            child_pass_id,
@@ -969,32 +1105,29 @@
       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
 
   gfx::Transform content_to_target_transform;
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+  SharedQuadState* shared_state = CreateTestSharedQuadState(
+      child_pass.get(), content_to_target_transform, viewport_rect);
 
   gfx::Rect blue_rect(0,
                       0,
                       this->device_viewport_size_.width(),
                       this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(shared_state.get(), blue_rect, blue_rect, SK_ColorBLUE, false);
+  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
   gfx::Rect yellow_rect(0,
                         this->device_viewport_size_.height() / 2,
                         this->device_viewport_size_.width(),
                         this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
-  yellow->SetNew(
-      shared_state.get(), yellow_rect, yellow_rect, SK_ColorYELLOW, false);
+  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
 
   child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
   child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
 
-  scoped_ptr<SharedQuadState> pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect);
-  root_pass->quad_list.push_back(
-      CreateTestRenderPassDrawQuad(pass_shared_state.get(),
-                                   pass_rect,
-                                   child_pass_id));
+  SharedQuadState* pass_shared_state =
+      CreateTestSharedQuadState(root_pass.get(), gfx::Transform(), pass_rect);
+  root_pass->quad_list.push_back(CreateTestRenderPassDrawQuad(
+      pass_shared_state, pass_rect, child_pass_id));
 
   RenderPassList pass_list;
   pass_list.push_back(child_pass.Pass());
@@ -1022,22 +1155,21 @@
       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
 
   gfx::Transform content_to_target_transform;
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+  SharedQuadState* shared_state = CreateTestSharedQuadState(
+      child_pass.get(), content_to_target_transform, viewport_rect);
 
   gfx::Rect blue_rect(0,
                       0,
                       this->device_viewport_size_.width(),
                       this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(shared_state.get(), blue_rect, blue_rect, SK_ColorBLUE, false);
+  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
   gfx::Rect yellow_rect(0,
                         this->device_viewport_size_.height() / 2,
                         this->device_viewport_size_.width(),
                         this->device_viewport_size_.height() / 2);
   scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
-  yellow->SetNew(
-      shared_state.get(), yellow_rect, yellow_rect, SK_ColorYELLOW, false);
+  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
 
   child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
   child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
@@ -1045,17 +1177,15 @@
   gfx::Transform aa_transform;
   aa_transform.Translate(0.5, 0.0);
 
-  scoped_ptr<SharedQuadState> pass_shared_state =
-      CreateTestSharedQuadState(aa_transform, pass_rect);
-  root_pass->quad_list.push_back(
-      CreateTestRenderPassDrawQuad(pass_shared_state.get(),
-                                   pass_rect,
-                                   child_pass_id));
+  SharedQuadState* pass_shared_state =
+      CreateTestSharedQuadState(root_pass.get(), aa_transform, pass_rect);
+  root_pass->quad_list.push_back(CreateTestRenderPassDrawQuad(
+      pass_shared_state, pass_rect, child_pass_id));
 
-  scoped_ptr<SharedQuadState> root_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), viewport_rect);
+  SharedQuadState* root_shared_state = CreateTestSharedQuadState(
+      root_pass.get(), gfx::Transform(), viewport_rect);
   scoped_ptr<SolidColorDrawQuad> background = SolidColorDrawQuad::Create();
-  background->SetNew(root_shared_state.get(),
+  background->SetNew(root_shared_state,
                      gfx::Rect(this->device_viewport_size_),
                      gfx::Rect(this->device_viewport_size_),
                      SK_ColorWHITE,
@@ -1082,24 +1212,21 @@
   RenderPass::Id root_pass_id(1, 1);
   scoped_ptr<RenderPass> root_pass =
       CreateTestRootRenderPass(root_pass_id, viewport_rect);
-  scoped_ptr<SharedQuadState> root_pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), viewport_rect);
+  SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState(
+      root_pass.get(), gfx::Transform(), viewport_rect);
 
   RenderPass::Id child_pass_id(2, 2);
   gfx::Transform transform_to_root;
   scoped_ptr<RenderPass> child_pass =
       CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
-  scoped_ptr<SharedQuadState> child_pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), viewport_rect);
+  SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState(
+      child_pass.get(), gfx::Transform(), viewport_rect);
 
   // The child render pass is just a green box.
   static const SkColor kCSSGreen = 0xff008000;
   scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create();
-  green->SetNew(child_pass_shared_state.get(),
-                viewport_rect,
-                viewport_rect,
-                kCSSGreen,
-                false);
+  green->SetNew(
+      child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false);
   child_pass->quad_list.push_back(green.PassAs<DrawQuad>());
 
   // Make a mask.
@@ -1149,7 +1276,7 @@
 
   // Set up a mask on the RenderPassDrawQuad.
   scoped_ptr<RenderPassDrawQuad> mask_quad = RenderPassDrawQuad::Create();
-  mask_quad->SetNew(root_pass_shared_state.get(),
+  mask_quad->SetNew(root_pass_shared_state,
                     sub_rect,
                     sub_rect,
                     child_pass_id,
@@ -1163,7 +1290,7 @@
 
   // White background behind the masked render pass.
   scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create();
-  white->SetNew(root_pass_shared_state.get(),
+  white->SetNew(root_pass_shared_state,
                 viewport_rect,
                 viewport_rect,
                 SK_ColorWHITE,
@@ -1203,27 +1330,28 @@
 
     // A non-visible quad in the filtering render pass.
     {
-      scoped_ptr<SharedQuadState> shared_state =
-          CreateTestSharedQuadState(identity_content_to_target_transform,
+      SharedQuadState* shared_state =
+          CreateTestSharedQuadState(filter_pass.get(),
+                                    identity_content_to_target_transform,
                                     filter_pass_content_rect_);
       scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
-      color_quad->SetNew(shared_state.get(),
+      color_quad->SetNew(shared_state,
                          filter_pass_content_rect_,
                          filter_pass_content_rect_,
                          SK_ColorTRANSPARENT,
                          false);
       filter_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
-      filter_pass->shared_quad_state_list.push_back(shared_state.Pass());
     }
 
     {
-      scoped_ptr<SharedQuadState> shared_state =
-          CreateTestSharedQuadState(filter_pass_to_target_transform_,
+      SharedQuadState* shared_state =
+          CreateTestSharedQuadState(filter_pass.get(),
+                                    filter_pass_to_target_transform_,
                                     filter_pass_content_rect_);
       scoped_ptr<RenderPassDrawQuad> filter_pass_quad =
           RenderPassDrawQuad::Create();
       filter_pass_quad->SetNew(
-          shared_state.get(),
+          shared_state,
           filter_pass_content_rect_,
           filter_pass_content_rect_,
           filter_pass_id,
@@ -1234,62 +1362,55 @@
           FilterOperations(),         // filters
           this->background_filters_);
       root_pass->quad_list.push_back(filter_pass_quad.PassAs<DrawQuad>());
-      root_pass->shared_quad_state_list.push_back(shared_state.Pass());
     }
 
     const int kColumnWidth = device_viewport_rect.width() / 3;
 
     gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
     for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
-      scoped_ptr<SharedQuadState> shared_state =
-          CreateTestSharedQuadState(identity_content_to_target_transform,
-                                    left_rect);
+      SharedQuadState* shared_state = CreateTestSharedQuadState(
+          root_pass.get(), identity_content_to_target_transform, left_rect);
       scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
       color_quad->SetNew(
-          shared_state.get(), left_rect, left_rect, SK_ColorGREEN, false);
+          shared_state, left_rect, left_rect, SK_ColorGREEN, false);
       root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
-      root_pass->shared_quad_state_list.push_back(shared_state.Pass());
       left_rect += gfx::Vector2d(0, left_rect.height() + 1);
     }
 
     gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
     for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
-      scoped_ptr<SharedQuadState> shared_state =
-          CreateTestSharedQuadState(identity_content_to_target_transform,
-                                    middle_rect);
+      SharedQuadState* shared_state = CreateTestSharedQuadState(
+          root_pass.get(), identity_content_to_target_transform, middle_rect);
       scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
       color_quad->SetNew(
-          shared_state.get(), middle_rect, middle_rect, SK_ColorRED, false);
+          shared_state, middle_rect, middle_rect, SK_ColorRED, false);
       root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
-      root_pass->shared_quad_state_list.push_back(shared_state.Pass());
       middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
     }
 
     gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
     for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
-      scoped_ptr<SharedQuadState> shared_state =
-          CreateTestSharedQuadState(identity_content_to_target_transform,
-                                    right_rect);
+      SharedQuadState* shared_state = CreateTestSharedQuadState(
+          root_pass.get(), identity_content_to_target_transform, right_rect);
       scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
       color_quad->SetNew(
-          shared_state.get(), right_rect, right_rect, SK_ColorBLUE, false);
+          shared_state, right_rect, right_rect, SK_ColorBLUE, false);
       root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
-      root_pass->shared_quad_state_list.push_back(shared_state.Pass());
       right_rect += gfx::Vector2d(0, right_rect.height() + 1);
     }
 
-    scoped_ptr<SharedQuadState> shared_state =
-        CreateTestSharedQuadState(identity_content_to_target_transform,
+    SharedQuadState* shared_state =
+        CreateTestSharedQuadState(root_pass.get(),
+                                  identity_content_to_target_transform,
                                   device_viewport_rect);
     scoped_ptr<SolidColorDrawQuad> background_quad =
         SolidColorDrawQuad::Create();
-    background_quad->SetNew(shared_state.get(),
+    background_quad->SetNew(shared_state,
                             device_viewport_rect,
                             device_viewport_rect,
                             SK_ColorWHITE,
                             false);
     root_pass->quad_list.push_back(background_quad.PassAs<DrawQuad>());
-    root_pass->shared_quad_state_list.push_back(shared_state.Pass());
 
     pass_list_.push_back(filter_pass.Pass());
     pass_list_.push_back(root_pass.Pass());
@@ -1366,10 +1487,10 @@
   gfx::Rect rect(this->device_viewport_size_);
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-  scoped_ptr<SharedQuadState> blue_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* blue_shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(blue_shared_state.get(), rect, rect, SK_ColorBLUE, false);
+  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
   pass->quad_list.push_back(blue.PassAs<DrawQuad>());
   pass->has_transparent_background = false;
   RenderPassList pass_list;
@@ -1389,10 +1510,10 @@
   gfx::Rect rect(this->device_viewport_size_);
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-  scoped_ptr<SharedQuadState> green_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* green_shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
   scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create();
-  green->SetNew(green_shared_state.get(), rect, rect, SK_ColorGREEN, false);
+  green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
   pass->quad_list.push_back(green.PassAs<DrawQuad>());
   RenderPassList pass_list;
   pass_list.push_back(pass.Pass());
@@ -1423,23 +1544,21 @@
       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
 
   gfx::Transform content_to_target_transform;
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+  SharedQuadState* shared_state = CreateTestSharedQuadState(
+      child_pass.get(), content_to_target_transform, viewport_rect);
 
   gfx::Rect blue_rect(0,
                       0,
                       this->device_viewport_size_.width(),
                       this->device_viewport_size_.height());
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(shared_state.get(), blue_rect, blue_rect, SK_ColorBLUE, false);
+  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
   child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
 
-  scoped_ptr<SharedQuadState> pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect);
-  root_pass->quad_list.push_back(
-      CreateTestRenderPassDrawQuad(pass_shared_state.get(),
-                                   pass_rect,
-                                   child_pass_id));
+  SharedQuadState* pass_shared_state =
+      CreateTestSharedQuadState(root_pass.get(), gfx::Transform(), pass_rect);
+  root_pass->quad_list.push_back(CreateTestRenderPassDrawQuad(
+      pass_shared_state, pass_rect, child_pass_id));
   RenderPassList pass_list;
   pass_list.push_back(child_pass.Pass());
   pass_list.push_back(root_pass.Pass());
@@ -1460,10 +1579,10 @@
   gfx::Rect rect(this->device_viewport_size_);
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-  scoped_ptr<SharedQuadState> blue_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* blue_shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(blue_shared_state.get(), rect, rect, SK_ColorBLUE, false);
+  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
   pass->quad_list.push_back(blue.PassAs<DrawQuad>());
   RenderPassList pass_list;
   pass_list.push_back(pass.Pass());
@@ -1483,30 +1602,30 @@
 
   gfx::Transform red_content_to_target_transform;
   red_content_to_target_transform.Rotate(10);
-  scoped_ptr<SharedQuadState> red_shared_state =
-      CreateTestSharedQuadState(red_content_to_target_transform, rect);
+  SharedQuadState* red_shared_state = CreateTestSharedQuadState(
+      pass.get(), red_content_to_target_transform, rect);
 
   scoped_ptr<SolidColorDrawQuad> red = SolidColorDrawQuad::Create();
-  red->SetNew(red_shared_state.get(), rect, rect, SK_ColorRED, false);
+  red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
 
   pass->quad_list.push_back(red.PassAs<DrawQuad>());
 
   gfx::Transform yellow_content_to_target_transform;
   yellow_content_to_target_transform.Rotate(5);
-  scoped_ptr<SharedQuadState> yellow_shared_state =
-      CreateTestSharedQuadState(yellow_content_to_target_transform, rect);
+  SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
+      pass.get(), yellow_content_to_target_transform, rect);
 
   scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
-  yellow->SetNew(yellow_shared_state.get(), rect, rect, SK_ColorYELLOW, false);
+  yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
 
   pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
 
   gfx::Transform blue_content_to_target_transform;
-  scoped_ptr<SharedQuadState> blue_shared_state =
-      CreateTestSharedQuadState(blue_content_to_target_transform, rect);
+  SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
+      pass.get(), blue_content_to_target_transform, rect);
 
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(blue_shared_state.get(), rect, rect, SK_ColorBLUE, false);
+  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
 
   pass->quad_list.push_back(blue.PassAs<DrawQuad>());
 
@@ -1534,31 +1653,31 @@
   red_content_to_target_transform.Scale(
       0.5f + 1.0f / (rect.width() * 2.0f),
       0.5f + 1.0f / (rect.height() * 2.0f));
-  scoped_ptr<SharedQuadState> red_shared_state =
-      CreateTestSharedQuadState(red_content_to_target_transform, rect);
+  SharedQuadState* red_shared_state = CreateTestSharedQuadState(
+      pass.get(), red_content_to_target_transform, rect);
 
   scoped_ptr<SolidColorDrawQuad> red = SolidColorDrawQuad::Create();
-  red->SetNew(red_shared_state.get(), rect, rect, SK_ColorRED, false);
+  red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
 
   pass->quad_list.push_back(red.PassAs<DrawQuad>());
 
   gfx::Transform yellow_content_to_target_transform;
   yellow_content_to_target_transform.Translate(25.5f, 25.5f);
   yellow_content_to_target_transform.Scale(0.5f, 0.5f);
-  scoped_ptr<SharedQuadState> yellow_shared_state =
-      CreateTestSharedQuadState(yellow_content_to_target_transform, rect);
+  SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
+      pass.get(), yellow_content_to_target_transform, rect);
 
   scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
-  yellow->SetNew(yellow_shared_state.get(), rect, rect, SK_ColorYELLOW, false);
+  yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
 
   pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
 
   gfx::Transform blue_content_to_target_transform;
-  scoped_ptr<SharedQuadState> blue_shared_state =
-      CreateTestSharedQuadState(blue_content_to_target_transform, rect);
+  SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
+      pass.get(), blue_content_to_target_transform, rect);
 
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(blue_shared_state.get(), rect, rect, SK_ColorBLUE, false);
+  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
 
   pass->quad_list.push_back(blue.PassAs<DrawQuad>());
 
@@ -1586,20 +1705,20 @@
   hole_content_to_target_transform.Scale(
       0.5f + 1.0f / (rect.width() * 2.0f),
       0.5f + 1.0f / (rect.height() * 2.0f));
-  scoped_ptr<SharedQuadState> hole_shared_state =
-      CreateTestSharedQuadState(hole_content_to_target_transform, rect);
+  SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
+      pass.get(), hole_content_to_target_transform, rect);
 
   scoped_ptr<SolidColorDrawQuad> hole = SolidColorDrawQuad::Create();
-  hole->SetAll(hole_shared_state.get(), rect, rect, rect, false,
-               SK_ColorTRANSPARENT, true);
+  hole->SetAll(
+      hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true);
   pass->quad_list.push_back(hole.PassAs<DrawQuad>());
 
   gfx::Transform green_content_to_target_transform;
-  scoped_ptr<SharedQuadState> green_shared_state =
-      CreateTestSharedQuadState(green_content_to_target_transform, rect);
+  SharedQuadState* green_shared_state = CreateTestSharedQuadState(
+      pass.get(), green_content_to_target_transform, rect);
 
   scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create();
-  green->SetNew(green_shared_state.get(), rect, rect, SK_ColorGREEN, false);
+  green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
 
   pass->quad_list.push_back(green.PassAs<DrawQuad>());
 
@@ -1624,24 +1743,24 @@
       0.0f,  0.3528f,  5.9737f,  9.5f,
       0.0f, -0.2250f, -0.9744f,  0.0f,
       0.0f,  0.0225f,  0.0974f,  1.0f);
-  scoped_ptr<SharedQuadState> red_shared_state =
-      CreateTestSharedQuadState(red_content_to_target_transform, red_rect);
+  SharedQuadState* red_shared_state = CreateTestSharedQuadState(
+      pass.get(), red_content_to_target_transform, red_rect);
   scoped_ptr<SolidColorDrawQuad> red = SolidColorDrawQuad::Create();
-  red->SetNew(red_shared_state.get(), red_rect, red_rect, SK_ColorRED, false);
+  red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false);
   pass->quad_list.push_back(red.PassAs<DrawQuad>());
 
   gfx::Rect green_rect(19, 7, 180, 10);
-  scoped_ptr<SharedQuadState> green_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), green_rect);
+  SharedQuadState* green_shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), green_rect);
   scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create();
   green->SetNew(
-      green_shared_state.get(), green_rect, green_rect, SK_ColorGREEN, false);
+      green_shared_state, green_rect, green_rect, SK_ColorGREEN, false);
   pass->quad_list.push_back(green.PassAs<DrawQuad>());
 
-  scoped_ptr<SharedQuadState> blue_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* blue_shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
   scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
-  blue->SetNew(blue_shared_state.get(), rect, rect, SK_ColorBLUE, false);
+  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
   pass->quad_list.push_back(blue.PassAs<DrawQuad>());
 
   RenderPassList pass_list;
@@ -1683,14 +1802,15 @@
   blue_content_to_target_transform.Translate(offset.x(), offset.y());
   gfx::RectF blue_scissor_rect = blue_clip_rect;
   blue_content_to_target_transform.TransformRect(&blue_scissor_rect);
-  scoped_ptr<SharedQuadState> blue_shared_state =
-      CreateTestSharedQuadStateClipped(blue_content_to_target_transform,
+  SharedQuadState* blue_shared_state =
+      CreateTestSharedQuadStateClipped(pass.get(),
+                                       blue_content_to_target_transform,
                                        blue_rect,
                                        gfx::ToEnclosingRect(blue_scissor_rect));
 
   scoped_ptr<PictureDrawQuad> blue_quad = PictureDrawQuad::Create();
 
-  blue_quad->SetNew(blue_shared_state.get(),
+  blue_quad->SetNew(blue_shared_state,
                     viewport,  // Intentionally bigger than clip.
                     gfx::Rect(),
                     viewport,
@@ -1711,11 +1831,11 @@
   green_pile->RerecordPile();
 
   gfx::Transform green_content_to_target_transform;
-  scoped_ptr<SharedQuadState> green_shared_state =
-      CreateTestSharedQuadState(green_content_to_target_transform, viewport);
+  SharedQuadState* green_shared_state = CreateTestSharedQuadState(
+      pass.get(), green_content_to_target_transform, viewport);
 
   scoped_ptr<PictureDrawQuad> green_quad = PictureDrawQuad::Create();
-  green_quad->SetNew(green_shared_state.get(),
+  green_quad->SetNew(green_shared_state,
                      viewport,
                      gfx::Rect(),
                      viewport,
@@ -1756,12 +1876,12 @@
   green_pile->RerecordPile();
 
   gfx::Transform green_content_to_target_transform;
-  scoped_ptr<SharedQuadState> green_shared_state =
-      CreateTestSharedQuadState(green_content_to_target_transform, viewport);
+  SharedQuadState* green_shared_state = CreateTestSharedQuadState(
+      pass.get(), green_content_to_target_transform, viewport);
   green_shared_state->opacity = 0.5f;
 
   scoped_ptr<PictureDrawQuad> green_quad = PictureDrawQuad::Create();
-  green_quad->SetNew(green_shared_state.get(),
+  green_quad->SetNew(green_shared_state,
                      viewport,
                      gfx::Rect(),
                      viewport,
@@ -1782,11 +1902,11 @@
   white_pile->RerecordPile();
 
   gfx::Transform white_content_to_target_transform;
-  scoped_ptr<SharedQuadState> white_shared_state =
-      CreateTestSharedQuadState(white_content_to_target_transform, viewport);
+  SharedQuadState* white_shared_state = CreateTestSharedQuadState(
+      pass.get(), white_content_to_target_transform, viewport);
 
   scoped_ptr<PictureDrawQuad> white_quad = PictureDrawQuad::Create();
-  white_quad->SetNew(white_shared_state.get(),
+  white_quad->SetNew(white_shared_state,
                      viewport,
                      gfx::Rect(),
                      viewport,
@@ -1857,11 +1977,11 @@
   pile->RerecordPile();
 
   gfx::Transform content_to_target_transform;
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(content_to_target_transform, viewport);
+  SharedQuadState* shared_state = CreateTestSharedQuadState(
+      pass.get(), content_to_target_transform, viewport);
 
   scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create();
-  quad->SetNew(shared_state.get(),
+  quad->SetNew(shared_state,
                viewport,
                gfx::Rect(),
                viewport,
@@ -1913,11 +2033,12 @@
   green_pile->add_draw_rect_with_paint(green_rect2, green_paint);
   green_pile->RerecordPile();
 
-  scoped_ptr<SharedQuadState> top_right_green_shared_quad_state =
-      CreateTestSharedQuadState(green_content_to_target_transform, viewport);
+  SharedQuadState* top_right_green_shared_quad_state =
+      CreateTestSharedQuadState(
+          pass.get(), green_content_to_target_transform, viewport);
 
   scoped_ptr<PictureDrawQuad> green_quad1 = PictureDrawQuad::Create();
-  green_quad1->SetNew(top_right_green_shared_quad_state.get(),
+  green_quad1->SetNew(top_right_green_shared_quad_state,
                       green_rect1,
                       gfx::Rect(),
                       green_rect1,
@@ -1930,7 +2051,7 @@
   pass->quad_list.push_back(green_quad1.PassAs<DrawQuad>());
 
   scoped_ptr<PictureDrawQuad> green_quad2 = PictureDrawQuad::Create();
-  green_quad2->SetNew(top_right_green_shared_quad_state.get(),
+  green_quad2->SetNew(top_right_green_shared_quad_state,
                       green_rect2,
                       gfx::Rect(),
                       green_rect2,
@@ -1947,12 +2068,14 @@
   gfx::Rect bottom_right_rect(
       gfx::Point(viewport.width() / 2, viewport.height() / 2),
       gfx::Size(viewport.width() / 2, viewport.height() / 2));
-  scoped_ptr<SharedQuadState> bottom_right_green_shared_state =
-      CreateTestSharedQuadStateClipped(
-          green_content_to_target_transform, viewport, bottom_right_rect);
+  SharedQuadState* bottom_right_green_shared_state =
+      CreateTestSharedQuadStateClipped(pass.get(),
+                                       green_content_to_target_transform,
+                                       viewport,
+                                       bottom_right_rect);
   scoped_ptr<SolidColorDrawQuad> bottom_right_color_quad =
       SolidColorDrawQuad::Create();
-  bottom_right_color_quad->SetNew(bottom_right_green_shared_state.get(),
+  bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
                                   viewport,
                                   viewport,
                                   SK_ColorGREEN,
@@ -2001,11 +2124,11 @@
   gfx::Transform content_to_target_transform;
   content_to_target_transform.Scale(10.0, 10.0);
   gfx::Rect quad_content_rect(gfx::Size(20, 20));
-  scoped_ptr<SharedQuadState> blue_shared_state =
-      CreateTestSharedQuadState(content_to_target_transform, quad_content_rect);
+  SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
+      pass.get(), content_to_target_transform, quad_content_rect);
 
   scoped_ptr<PictureDrawQuad> blue_quad = PictureDrawQuad::Create();
-  blue_quad->SetNew(blue_shared_state.get(),
+  blue_quad->SetNew(blue_shared_state,
                     quad_content_rect,
                     gfx::Rect(),
                     quad_content_rect,
@@ -2020,11 +2143,10 @@
   // Fill left half of viewport with green.
   gfx::Transform half_green_content_to_target_transform;
   gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
-  scoped_ptr<SharedQuadState> half_green_shared_state =
-      CreateTestSharedQuadState(half_green_content_to_target_transform,
-                                half_green_rect);
+  SharedQuadState* half_green_shared_state = CreateTestSharedQuadState(
+      pass.get(), half_green_content_to_target_transform, half_green_rect);
   scoped_ptr<SolidColorDrawQuad> half_color_quad = SolidColorDrawQuad::Create();
-  half_color_quad->SetNew(half_green_shared_state.get(),
+  half_color_quad->SetNew(half_green_shared_state,
                           half_green_rect,
                           half_green_rect,
                           SK_ColorGREEN,
@@ -2046,8 +2168,8 @@
   RenderPass::Id id(1, 1);
   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
 
-  scoped_ptr<SharedQuadState> shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect);
+  SharedQuadState* shared_state =
+      CreateTestSharedQuadState(pass.get(), gfx::Transform(), rect);
 
   gfx::Rect texture_rect(4, 4);
   SkPMColor colors[4] = {
@@ -2078,7 +2200,7 @@
   float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
   scoped_ptr<TextureDrawQuad> texture_quad = TextureDrawQuad::Create();
   texture_quad->SetNew(
-      shared_state.get(),
+      shared_state,
       gfx::Rect(this->device_viewport_size_),
       gfx::Rect(),
       gfx::Rect(this->device_viewport_size_),
diff --git a/cc/output/renderer_unittest.cc b/cc/output/renderer_unittest.cc
index c6185ec..f103baa 100644
--- a/cc/output/renderer_unittest.cc
+++ b/cc/output/renderer_unittest.cc
@@ -62,7 +62,8 @@
     output_surface_.reset(new OutputSurface(context_provider_));
     output_surface_->BindToClient(&output_surface_client_);
     resource_provider_ =
-        ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1);
+        ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1,
+        false);
     renderer_ = CreateRenderer<T>(&renderer_client_,
                                   &tree_settings_,
                                   output_surface_.get(),
diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc
index a80d052..af4343b 100644
--- a/cc/output/software_renderer_unittest.cc
+++ b/cc/output/software_renderer_unittest.cc
@@ -35,7 +35,8 @@
 
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+        false);
     renderer_ = SoftwareRenderer::Create(
         this, &settings_, output_surface_.get(), resource_provider());
   }
@@ -67,7 +68,12 @@
 
   InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
 
-  scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
+  RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1);
+  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
+  root_render_pass->SetNew(
+      root_render_pass_id, outer_rect, outer_rect, gfx::Transform());
+  SharedQuadState* shared_quad_state =
+      root_render_pass->CreateAndAppendSharedQuadState();
   shared_quad_state->SetAll(gfx::Transform(),
                             outer_size,
                             outer_rect,
@@ -75,16 +81,12 @@
                             false,
                             1.0,
                             SkXfermode::kSrcOver_Mode);
-  RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1);
-  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
-  root_render_pass->SetNew(
-      root_render_pass_id, outer_rect, outer_rect, gfx::Transform());
   scoped_ptr<SolidColorDrawQuad> outer_quad = SolidColorDrawQuad::Create();
   outer_quad->SetNew(
-      shared_quad_state.get(), outer_rect, outer_rect, SK_ColorYELLOW, false);
+      shared_quad_state, outer_rect, outer_rect, SK_ColorYELLOW, false);
   scoped_ptr<SolidColorDrawQuad> inner_quad = SolidColorDrawQuad::Create();
   inner_quad->SetNew(
-      shared_quad_state.get(), inner_rect, inner_rect, SK_ColorCYAN, false);
+      shared_quad_state, inner_rect, inner_rect, SK_ColorCYAN, false);
   inner_quad->visible_rect = visible_rect;
   root_render_pass->AppendQuad(inner_quad.PassAs<DrawQuad>());
   root_render_pass->AppendQuad(outer_quad.PassAs<DrawQuad>());
@@ -159,7 +161,12 @@
 
   gfx::Rect root_rect = outer_rect;
 
-  scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
+  RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1);
+  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
+  root_render_pass->SetNew(
+      root_render_pass_id, root_rect, root_rect, gfx::Transform());
+  SharedQuadState* shared_quad_state =
+      root_render_pass->CreateAndAppendSharedQuadState();
   shared_quad_state->SetAll(gfx::Transform(),
                             outer_size,
                             outer_rect,
@@ -167,12 +174,8 @@
                             false,
                             1.0,
                             SkXfermode::kSrcOver_Mode);
-  RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1);
-  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
-  root_render_pass->SetNew(
-      root_render_pass_id, root_rect, root_rect, gfx::Transform());
   scoped_ptr<TileDrawQuad> outer_quad = TileDrawQuad::Create();
-  outer_quad->SetNew(shared_quad_state.get(),
+  outer_quad->SetNew(shared_quad_state,
                      outer_rect,
                      outer_rect,
                      outer_rect,
@@ -181,7 +184,7 @@
                      outer_size,
                      false);
   scoped_ptr<TileDrawQuad> inner_quad = TileDrawQuad::Create();
-  inner_quad->SetNew(shared_quad_state.get(),
+  inner_quad->SetNew(shared_quad_state,
                      inner_rect,
                      inner_rect,
                      inner_rect,
@@ -248,7 +251,12 @@
 
   gfx::Rect root_rect(tile_size);
 
-  scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
+  RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1);
+  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
+  root_render_pass->SetNew(
+      root_render_pass_id, root_rect, root_rect, gfx::Transform());
+  SharedQuadState* shared_quad_state =
+      root_render_pass->CreateAndAppendSharedQuadState();
   shared_quad_state->SetAll(gfx::Transform(),
                             tile_size,
                             tile_rect,
@@ -256,12 +264,8 @@
                             false,
                             1.0,
                             SkXfermode::kSrcOver_Mode);
-  RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1);
-  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
-  root_render_pass->SetNew(
-      root_render_pass_id, root_rect, root_rect, gfx::Transform());
   scoped_ptr<TileDrawQuad> quad = TileDrawQuad::Create();
-  quad->SetNew(shared_quad_state.get(),
+  quad->SetNew(shared_quad_state,
                tile_rect,
                tile_rect,
                tile_rect,
diff --git a/cc/quads/draw_quad_unittest.cc b/cc/quads/draw_quad_unittest.cc
index 2b491f4..cb11609 100644
--- a/cc/quads/draw_quad_unittest.cc
+++ b/cc/quads/draw_quad_unittest.cc
@@ -594,16 +594,18 @@
   ResourceProvider::ResourceId u_plane_resource_id = 532;
   ResourceProvider::ResourceId v_plane_resource_id = 4;
   ResourceProvider::ResourceId a_plane_resource_id = 63;
+  YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601_JPEG;
   CREATE_SHARED_STATE();
 
-  CREATE_QUAD_7_NEW(YUVVideoDrawQuad,
+  CREATE_QUAD_8_NEW(YUVVideoDrawQuad,
                     opaque_rect,
                     visible_rect,
                     tex_coord_rect,
                     y_plane_resource_id,
                     u_plane_resource_id,
                     v_plane_resource_id,
-                    a_plane_resource_id);
+                    a_plane_resource_id,
+                    color_space);
   EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
   EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect);
   EXPECT_RECT_EQ(visible_rect, copy_quad->visible_rect);
@@ -612,19 +614,22 @@
   EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id);
   EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id);
   EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id);
+  EXPECT_EQ(color_space, copy_quad->color_space);
 
-  CREATE_QUAD_5_ALL(YUVVideoDrawQuad,
+  CREATE_QUAD_6_ALL(YUVVideoDrawQuad,
                     tex_coord_rect,
                     y_plane_resource_id,
                     u_plane_resource_id,
                     v_plane_resource_id,
-                    a_plane_resource_id);
+                    a_plane_resource_id,
+                    color_space);
   EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
   EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
   EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id);
   EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id);
   EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id);
   EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id);
+  EXPECT_EQ(color_space, copy_quad->color_space);
 }
 
 TEST(DrawQuadTest, CopyPictureDrawQuad) {
@@ -853,21 +858,24 @@
   ResourceProvider::ResourceId u_plane_resource_id = 532;
   ResourceProvider::ResourceId v_plane_resource_id = 4;
   ResourceProvider::ResourceId a_plane_resource_id = 63;
+  YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601_JPEG;
 
   CREATE_SHARED_STATE();
-  CREATE_QUAD_7_NEW(YUVVideoDrawQuad,
+  CREATE_QUAD_8_NEW(YUVVideoDrawQuad,
                     opaque_rect,
                     visible_rect,
                     tex_coord_rect,
                     y_plane_resource_id,
                     u_plane_resource_id,
                     v_plane_resource_id,
-                    a_plane_resource_id);
+                    a_plane_resource_id,
+                    color_space);
   EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
   EXPECT_EQ(y_plane_resource_id, quad_new->y_plane_resource_id);
   EXPECT_EQ(u_plane_resource_id, quad_new->u_plane_resource_id);
   EXPECT_EQ(v_plane_resource_id, quad_new->v_plane_resource_id);
   EXPECT_EQ(a_plane_resource_id, quad_new->a_plane_resource_id);
+  EXPECT_EQ(color_space, quad_new->color_space);
   EXPECT_EQ(4, IterateAndCount(quad_new.get()));
   EXPECT_EQ(y_plane_resource_id + 1, quad_new->y_plane_resource_id);
   EXPECT_EQ(u_plane_resource_id + 1, quad_new->u_plane_resource_id);
diff --git a/cc/quads/render_pass.cc b/cc/quads/render_pass.cc
index 3c8b481..535cb63 100644
--- a/cc/quads/render_pass.cc
+++ b/cc/quads/render_pass.cc
@@ -79,8 +79,9 @@
                       source->transform_to_root_target,
                       source->has_transparent_background);
     for (size_t i = 0; i < source->shared_quad_state_list.size(); ++i) {
-      copy_pass->shared_quad_state_list.push_back(
-          source->shared_quad_state_list[i]->Copy());
+      SharedQuadState* copy_shared_quad_state =
+          copy_pass->CreateAndAppendSharedQuadState();
+      copy_shared_quad_state->CopyFrom(source->shared_quad_state_list[i]);
     }
     for (size_t i = 0, sqs_i = 0; i < source->quad_list.size(); ++i) {
       while (source->quad_list[i]->shared_quad_state !=
@@ -168,4 +169,9 @@
   return value.PassAs<base::Value>();
 }
 
+SharedQuadState* RenderPass::CreateAndAppendSharedQuadState() {
+  shared_quad_state_list.push_back(SharedQuadState::Create());
+  return shared_quad_state_list.back();
+}
+
 }  // namespace cc
diff --git a/cc/quads/render_pass.h b/cc/quads/render_pass.h
index 1cbac05..4416ea8 100644
--- a/cc/quads/render_pass.h
+++ b/cc/quads/render_pass.h
@@ -88,6 +88,8 @@
 
   scoped_ptr<base::Value> AsValue() const;
 
+  SharedQuadState* CreateAndAppendSharedQuadState();
+
   // Uniquely identifies the render pass in the compositor's current frame.
   Id id;
 
diff --git a/cc/quads/render_pass_unittest.cc b/cc/quads/render_pass_unittest.cc
index f714dbe..7f723a4 100644
--- a/cc/quads/render_pass_unittest.cc
+++ b/cc/quads/render_pass_unittest.cc
@@ -79,7 +79,7 @@
   pass->copy_requests.push_back(CopyOutputRequest::CreateEmptyRequest());
 
   // Stick a quad in the pass, this should not get copied.
-  scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
+  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
   shared_state->SetAll(gfx::Transform(),
                        gfx::Size(),
                        gfx::Rect(),
@@ -87,7 +87,6 @@
                        false,
                        1,
                        SkXfermode::kSrcOver_Mode);
-  pass->AppendSharedQuadState(shared_state.Pass());
 
   scoped_ptr<CheckerboardDrawQuad> checkerboard_quad =
       CheckerboardDrawQuad::Create();
@@ -130,7 +129,7 @@
                has_transparent_background);
 
   // Two quads using one shared state.
-  scoped_ptr<SharedQuadState> shared_state1 = SharedQuadState::Create();
+  SharedQuadState* shared_state1 = pass->CreateAndAppendSharedQuadState();
   shared_state1->SetAll(gfx::Transform(),
                         gfx::Size(1, 1),
                         gfx::Rect(),
@@ -138,7 +137,6 @@
                         false,
                         1,
                         SkXfermode::kSrcOver_Mode);
-  pass->AppendSharedQuadState(shared_state1.Pass());
 
   scoped_ptr<CheckerboardDrawQuad> checkerboard_quad1 =
       CheckerboardDrawQuad::Create();
@@ -157,7 +155,7 @@
   pass->quad_list.push_back(checkerboard_quad2.PassAs<DrawQuad>());
 
   // And two quads using another shared state.
-  scoped_ptr<SharedQuadState> shared_state2 = SharedQuadState::Create();
+  SharedQuadState* shared_state2 = pass->CreateAndAppendSharedQuadState();
   shared_state2->SetAll(gfx::Transform(),
                         gfx::Size(2, 2),
                         gfx::Rect(),
@@ -165,7 +163,6 @@
                         false,
                         1,
                         SkXfermode::kSrcOver_Mode);
-  pass->AppendSharedQuadState(shared_state2.Pass());
 
   scoped_ptr<CheckerboardDrawQuad> checkerboard_quad3 =
       CheckerboardDrawQuad::Create();
@@ -198,7 +195,8 @@
                   contrib_transform_to_root,
                   contrib_has_transparent_background);
 
-  scoped_ptr<SharedQuadState> contrib_shared_state = SharedQuadState::Create();
+  SharedQuadState* contrib_shared_state =
+      contrib->CreateAndAppendSharedQuadState();
   contrib_shared_state->SetAll(gfx::Transform(),
                                gfx::Size(2, 2),
                                gfx::Rect(),
@@ -206,7 +204,6 @@
                                false,
                                1,
                                SkXfermode::kSrcOver_Mode);
-  contrib->AppendSharedQuadState(contrib_shared_state.Pass());
 
   scoped_ptr<CheckerboardDrawQuad> contrib_quad =
       CheckerboardDrawQuad::Create();
@@ -258,7 +255,7 @@
                has_transparent_background);
 
   // A shared state with a quad.
-  scoped_ptr<SharedQuadState> shared_state1 = SharedQuadState::Create();
+  SharedQuadState* shared_state1 = pass->CreateAndAppendSharedQuadState();
   shared_state1->SetAll(gfx::Transform(),
                         gfx::Size(1, 1),
                         gfx::Rect(),
@@ -266,7 +263,6 @@
                         false,
                         1,
                         SkXfermode::kSrcOver_Mode);
-  pass->AppendSharedQuadState(shared_state1.Pass());
 
   scoped_ptr<CheckerboardDrawQuad> checkerboard_quad1 =
       CheckerboardDrawQuad::Create();
@@ -277,7 +273,7 @@
   pass->quad_list.push_back(checkerboard_quad1.PassAs<DrawQuad>());
 
   // A shared state with no quads, they were culled.
-  scoped_ptr<SharedQuadState> shared_state2 = SharedQuadState::Create();
+  SharedQuadState* shared_state2 = pass->CreateAndAppendSharedQuadState();
   shared_state2->SetAll(gfx::Transform(),
                         gfx::Size(2, 2),
                         gfx::Rect(),
@@ -285,10 +281,9 @@
                         false,
                         1,
                         SkXfermode::kSrcOver_Mode);
-  pass->AppendSharedQuadState(shared_state2.Pass());
 
   // A second shared state with no quads.
-  scoped_ptr<SharedQuadState> shared_state3 = SharedQuadState::Create();
+  SharedQuadState* shared_state3 = pass->CreateAndAppendSharedQuadState();
   shared_state3->SetAll(gfx::Transform(),
                         gfx::Size(2, 2),
                         gfx::Rect(),
@@ -296,10 +291,9 @@
                         false,
                         1,
                         SkXfermode::kSrcOver_Mode);
-  pass->AppendSharedQuadState(shared_state3.Pass());
 
   // A last shared state with a quad again.
-  scoped_ptr<SharedQuadState> shared_state4 = SharedQuadState::Create();
+  SharedQuadState* shared_state4 = pass->CreateAndAppendSharedQuadState();
   shared_state4->SetAll(gfx::Transform(),
                         gfx::Size(2, 2),
                         gfx::Rect(),
@@ -307,7 +301,6 @@
                         false,
                         1,
                         SkXfermode::kSrcOver_Mode);
-  pass->AppendSharedQuadState(shared_state4.Pass());
 
   scoped_ptr<CheckerboardDrawQuad> checkerboard_quad2 =
       CheckerboardDrawQuad::Create();
diff --git a/cc/quads/shared_quad_state.cc b/cc/quads/shared_quad_state.cc
index 9ea3faa..3832886 100644
--- a/cc/quads/shared_quad_state.cc
+++ b/cc/quads/shared_quad_state.cc
@@ -27,6 +27,10 @@
   return make_scoped_ptr(new SharedQuadState(*this));
 }
 
+void SharedQuadState::CopyFrom(const SharedQuadState* other) {
+  *this = *other;
+}
+
 void SharedQuadState::SetAll(const gfx::Transform& content_to_target_transform,
                              const gfx::Size& content_bounds,
                              const gfx::Rect& visible_content_rect,
diff --git a/cc/quads/shared_quad_state.h b/cc/quads/shared_quad_state.h
index 42d977e..cf44381 100644
--- a/cc/quads/shared_quad_state.h
+++ b/cc/quads/shared_quad_state.h
@@ -28,6 +28,7 @@
   ~SharedQuadState();
 
   scoped_ptr<SharedQuadState> Copy() const;
+  void CopyFrom(const SharedQuadState* other);
 
   void SetAll(const gfx::Transform& content_to_target_transform,
               const gfx::Size& content_bounds,
diff --git a/cc/quads/yuv_video_draw_quad.cc b/cc/quads/yuv_video_draw_quad.cc
index ea56677..bb8ec73 100644
--- a/cc/quads/yuv_video_draw_quad.cc
+++ b/cc/quads/yuv_video_draw_quad.cc
@@ -29,7 +29,8 @@
                               unsigned y_plane_resource_id,
                               unsigned u_plane_resource_id,
                               unsigned v_plane_resource_id,
-                              unsigned a_plane_resource_id) {
+                              unsigned a_plane_resource_id,
+                              ColorSpace color_space) {
   bool needs_blending = false;
   DrawQuad::SetAll(shared_quad_state, DrawQuad::YUV_VIDEO_CONTENT, rect,
                    opaque_rect, visible_rect, needs_blending);
@@ -38,6 +39,7 @@
   this->u_plane_resource_id = u_plane_resource_id;
   this->v_plane_resource_id = v_plane_resource_id;
   this->a_plane_resource_id = a_plane_resource_id;
+  this->color_space = color_space;
 }
 
 void YUVVideoDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
@@ -49,7 +51,8 @@
                               unsigned y_plane_resource_id,
                               unsigned u_plane_resource_id,
                               unsigned v_plane_resource_id,
-                              unsigned a_plane_resource_id) {
+                              unsigned a_plane_resource_id,
+                              ColorSpace color_space) {
   DrawQuad::SetAll(shared_quad_state, DrawQuad::YUV_VIDEO_CONTENT, rect,
                    opaque_rect, visible_rect, needs_blending);
   this->tex_coord_rect = tex_coord_rect;
@@ -57,6 +60,7 @@
   this->u_plane_resource_id = u_plane_resource_id;
   this->v_plane_resource_id = v_plane_resource_id;
   this->a_plane_resource_id = a_plane_resource_id;
+  this->color_space = color_space;
 }
 
 void YUVVideoDrawQuad::IterateResources(
diff --git a/cc/quads/yuv_video_draw_quad.h b/cc/quads/yuv_video_draw_quad.h
index 65b35e0..c95681f 100644
--- a/cc/quads/yuv_video_draw_quad.h
+++ b/cc/quads/yuv_video_draw_quad.h
@@ -15,6 +15,12 @@
 
 class CC_EXPORT YUVVideoDrawQuad : public DrawQuad {
  public:
+  enum ColorSpace {
+    REC_601,       // SDTV standard with restricted "studio swing" color range.
+    REC_601_JPEG,  // Full color range [0, 255] variant of the above.
+    COLOR_SPACE_LAST = REC_601_JPEG
+  };
+
   virtual ~YUVVideoDrawQuad();
 
   static scoped_ptr<YUVVideoDrawQuad> Create();
@@ -27,7 +33,8 @@
               unsigned y_plane_resource_id,
               unsigned u_plane_resource_id,
               unsigned v_plane_resource_id,
-              unsigned a_plane_resource_id);
+              unsigned a_plane_resource_id,
+              ColorSpace color_space);
 
   void SetAll(const SharedQuadState* shared_quad_state,
               const gfx::Rect& rect,
@@ -38,13 +45,15 @@
               unsigned y_plane_resource_id,
               unsigned u_plane_resource_id,
               unsigned v_plane_resource_id,
-              unsigned a_plane_resource_id);
+              unsigned a_plane_resource_id,
+              ColorSpace color_space);
 
   gfx::RectF tex_coord_rect;
   unsigned y_plane_resource_id;
   unsigned u_plane_resource_id;
   unsigned v_plane_resource_id;
   unsigned a_plane_resource_id;
+  ColorSpace color_space;
 
   virtual void IterateResources(const ResourceIteratorCallback& callback)
       OVERRIDE;
diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc
index de6ff93..7147a15 100644
--- a/cc/resources/picture.cc
+++ b/cc/resources/picture.cc
@@ -273,17 +273,23 @@
                               &factory,
                               SkPicture::kUsePathBoundsForClip_RecordingFlag));
 
+  ContentLayerClient::GraphicsContextStatus graphics_context_status =
+      ContentLayerClient::GRAPHICS_CONTEXT_ENABLED;
+
   switch (recording_mode) {
     case RECORD_NORMALLY:
-      // Already setup for normal recording
+      // Already setup for normal recording.
       break;
     case RECORD_WITH_SK_NULL_CANVAS:
       canvas = skia::AdoptRef(SkCreateNullCanvas());
       break;
     case RECORD_WITH_PAINTING_DISABLED:
-      // Blink's GraphicsContext will disable painting when given a NULL
-      // canvas.
-      canvas.clear();
+      // We pass a disable flag through the paint calls when perfromance
+      // testing (the only time this case should ever arise) when we want to
+      // prevent the Blink GraphicsContext object from consuming any compute
+      // time.
+      canvas = skia::AdoptRef(SkCreateNullCanvas());
+      graphics_context_status = ContentLayerClient::GRAPHICS_CONTEXT_DISABLED;
       break;
     case RECORD_WITH_SKRECORD:
       recording.reset(new EXPERIMENTAL::SkRecording(layer_rect_.width(),
@@ -294,23 +300,21 @@
       NOTREACHED();
   }
 
-  if (canvas) {
-    canvas->save();
-    canvas->translate(SkFloatToScalar(-layer_rect_.x()),
-                      SkFloatToScalar(-layer_rect_.y()));
+  canvas->save();
+  canvas->translate(SkFloatToScalar(-layer_rect_.x()),
+                    SkFloatToScalar(-layer_rect_.y()));
 
-    SkRect layer_skrect = SkRect::MakeXYWH(layer_rect_.x(),
-                                           layer_rect_.y(),
-                                           layer_rect_.width(),
-                                           layer_rect_.height());
-    canvas->clipRect(layer_skrect);
-  }
+  SkRect layer_skrect = SkRect::MakeXYWH(layer_rect_.x(),
+                                         layer_rect_.y(),
+                                         layer_rect_.width(),
+                                         layer_rect_.height());
+  canvas->clipRect(layer_skrect);
 
   gfx::RectF opaque_layer_rect;
-  painter->PaintContents(canvas.get(), layer_rect_, &opaque_layer_rect);
+  painter->PaintContents(
+      canvas.get(), layer_rect_, &opaque_layer_rect, graphics_context_status);
 
-  if (canvas)
-    canvas->restore();
+  canvas->restore();
   picture_ = skia::AdoptRef(recorder.endRecording());
   DCHECK(picture_);
 
@@ -387,7 +391,8 @@
     SkDrawPictureCallback* callback,
     const Region& negated_content_region,
     float contents_scale) {
-  DCHECK(raster_thread_checker_.CalledOnValidThread());
+  if (!playback_)
+    DCHECK(raster_thread_checker_.CalledOnValidThread());
   TRACE_EVENT_BEGIN1(
       "cc",
       "Picture::Raster",
@@ -418,7 +423,8 @@
 }
 
 void Picture::Replay(SkCanvas* canvas) {
-  DCHECK(raster_thread_checker_.CalledOnValidThread());
+  if (!playback_)
+    DCHECK(raster_thread_checker_.CalledOnValidThread());
   TRACE_EVENT_BEGIN0("cc", "Picture::Replay");
   DCHECK(picture_);
 
@@ -436,8 +442,21 @@
 scoped_ptr<base::Value> Picture::AsValue() const {
   SkDynamicMemoryWStream stream;
 
-  // Serialize the picture.
-  picture_->serialize(&stream, &EncodeBitmap);
+  if (playback_) {
+    // SkPlayback can't serialize itself, so re-record into an SkPicture.
+    SkPictureRecorder recorder;
+    skia::RefPtr<SkCanvas> canvas(skia::SharePtr(recorder.beginRecording(
+        layer_rect_.width(),
+        layer_rect_.height(),
+        NULL,  // Default (no) bounding-box hierarchy is fastest.
+        SkPicture::kUsePathBoundsForClip_RecordingFlag)));
+    playback_->draw(canvas.get());
+    skia::RefPtr<SkPicture> picture(skia::AdoptRef(recorder.endRecording()));
+    picture->serialize(&stream, &EncodeBitmap);
+  } else {
+    // Serialize the picture.
+    picture_->serialize(&stream, &EncodeBitmap);
+  }
 
   // Encode the picture as base64.
   scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
diff --git a/cc/resources/picture.h b/cc/resources/picture.h
index 4761ca6..78833d1 100644
--- a/cc/resources/picture.h
+++ b/cc/resources/picture.h
@@ -75,8 +75,10 @@
 
   bool IsSuitableForGpuRasterization() const;
 
-  // Apply this scale and raster the negated region into the canvas. See comment
-  // in PicturePileImpl::RasterCommon for explanation on negated content region.
+  // Apply this scale and raster the negated region into the canvas.
+  // |negated_content_region| specifies the region to be clipped out of the
+  // raster operation, i.e., the parts of the canvas which will not get drawn
+  // to.
   int Raster(SkCanvas* canvas,
              SkDrawPictureCallback* callback,
              const Region& negated_content_region,
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index a3664e7..46792d0 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -20,6 +20,8 @@
 namespace cc {
 namespace {
 
+const float kSoonBorderDistanceInScreenPixels = 312.f;
+
 class TileEvictionOrder {
  public:
   explicit TileEvictionOrder(TreePriority tree_priority)
@@ -532,6 +534,25 @@
         resolution_, TilePriority::EVENTUALLY, distance_to_visible);
     tile->SetPriority(tree, priority);
   }
+
+  // Upgrade the priority on border tiles to be SOON.
+  current_soon_border_rect_ = visible_rect_in_content_space;
+  float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale;
+  current_soon_border_rect_.Inset(-border, -border, -border, -border);
+  for (TilingData::DifferenceIterator iter(
+           &tiling_data_, current_soon_border_rect_, skewport);
+       iter;
+       ++iter) {
+    TileMap::iterator find = tiles_.find(iter.index());
+    if (find == tiles_.end())
+      continue;
+    Tile* tile = find->second.get();
+
+    TilePriority priority(resolution_,
+                          TilePriority::SOON,
+                          tile->priority(tree).distance_to_visible);
+    tile->SetPriority(tree, priority);
+  }
 }
 
 void PictureLayerTiling::SetLiveTilesRect(
@@ -800,6 +821,7 @@
           tiling_->current_visible_rect_in_content_space_),
       skewport_in_content_space_(tiling_->current_skewport_),
       eventually_rect_in_content_space_(tiling_->current_eventually_rect_),
+      soon_border_rect_in_content_space_(tiling_->current_soon_border_rect_),
       tree_(tree),
       current_tile_(NULL),
       visible_iterator_(&tiling->tiling_data_,
@@ -808,7 +830,8 @@
       spiral_iterator_(&tiling->tiling_data_,
                        skewport_in_content_space_,
                        visible_rect_in_content_space_,
-                       visible_rect_in_content_space_) {
+                       visible_rect_in_content_space_),
+      skewport_processed_(false) {
   if (!visible_iterator_) {
     AdvancePhase();
     return;
@@ -866,8 +889,20 @@
       case TilePriority::SOON:
         ++spiral_iterator_;
         if (!spiral_iterator_) {
-          AdvancePhase();
-          return *this;
+          if (skewport_processed_) {
+            AdvancePhase();
+            return *this;
+          }
+          skewport_processed_ = true;
+          spiral_iterator_ = TilingData::SpiralDifferenceIterator(
+              &tiling_->tiling_data_,
+              soon_border_rect_in_content_space_,
+              skewport_in_content_space_,
+              visible_rect_in_content_space_);
+          if (!spiral_iterator_) {
+            AdvancePhase();
+            return *this;
+          }
         }
         next_index = spiral_iterator_.index();
         break;
diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h
index 92c2879..538117c 100644
--- a/cc/resources/picture_layer_tiling.h
+++ b/cc/resources/picture_layer_tiling.h
@@ -82,11 +82,13 @@
     gfx::Rect visible_rect_in_content_space_;
     gfx::Rect skewport_in_content_space_;
     gfx::Rect eventually_rect_in_content_space_;
+    gfx::Rect soon_border_rect_in_content_space_;
     WhichTree tree_;
 
     Tile* current_tile_;
     TilingData::Iterator visible_iterator_;
     TilingData::SpiralDifferenceIterator spiral_iterator_;
+    bool skewport_processed_;
   };
 
   class CC_EXPORT TilingEvictionTileIterator {
@@ -299,6 +301,7 @@
   gfx::Rect current_visible_rect_in_content_space_;
   gfx::Rect current_skewport_;
   gfx::Rect current_eventually_rect_;
+  gfx::Rect current_soon_border_rect_;
 
   std::vector<Tile*> eviction_tiles_cache_;
   bool eviction_tiles_cache_valid_;
diff --git a/cc/resources/picture_layer_tiling_perftest.cc b/cc/resources/picture_layer_tiling_perftest.cc
index 0e015b1..4ccef0a 100644
--- a/cc/resources/picture_layer_tiling_perftest.cc
+++ b/cc/resources/picture_layer_tiling_perftest.cc
@@ -4,6 +4,7 @@
 
 #include "cc/resources/picture_layer_tiling.h"
 #include "cc/test/fake_picture_layer_tiling_client.h"
+#include "cc/test/lap_timer.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/perf/perf_test.h"
@@ -18,7 +19,10 @@
 
 class PictureLayerTilingPerfTest : public testing::Test {
  public:
-  PictureLayerTilingPerfTest() : num_runs_(0) {}
+  PictureLayerTilingPerfTest()
+      : timer_(kWarmupRuns,
+               base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
+               kTimeCheckInterval) {}
 
   virtual void SetUp() OVERRIDE {
     picture_layer_tiling_client_.SetTileSize(gfx::Size(256, 256));
@@ -32,60 +36,38 @@
     picture_layer_tiling_.reset(NULL);
   }
 
-  void EndTest() {
-    elapsed_ = base::TimeTicks::HighResNow() - start_time_;
-  }
-
-  bool DidRun() {
-    ++num_runs_;
-    if (num_runs_ == kWarmupRuns)
-      start_time_ = base::TimeTicks::HighResNow();
-
-    if (!start_time_.is_null() && (num_runs_ % kTimeCheckInterval) == 0) {
-      base::TimeDelta elapsed = base::TimeTicks::HighResNow() - start_time_;
-      if (elapsed >= base::TimeDelta::FromMilliseconds(kTimeLimitMillis)) {
-        elapsed_ = elapsed;
-        return false;
-      }
-    }
-    return true;
-  }
-
   void RunInvalidateTest(const std::string& test_name, const Region& region) {
-    start_time_ = base::TimeTicks();
-    num_runs_ = 0;
+    timer_.Reset();
     do {
       picture_layer_tiling_->Invalidate(region);
-    } while (DidRun());
+      timer_.NextLap();
+    } while (!timer_.HasTimeLimitExpired());
 
-    perf_test::PrintResult("invalidation", "", test_name,
-                           num_runs_ / elapsed_.InSecondsF(), "runs/s", true);
+    perf_test::PrintResult(
+        "invalidation", "", test_name, timer_.LapsPerSecond(), "runs/s", true);
   }
 
   void RunUpdateTilePrioritiesStationaryTest(const std::string& test_name,
                                              const gfx::Transform& transform) {
-    start_time_ = base::TimeTicks();
-    num_runs_ = 0;
-
     gfx::Rect viewport_rect(0, 0, 1024, 768);
+
+    timer_.Reset();
     do {
       picture_layer_tiling_->UpdateTilePriorities(
-          ACTIVE_TREE, viewport_rect, 1.f, num_runs_ + 1);
-    } while (DidRun());
+          ACTIVE_TREE, viewport_rect, 1.f, timer_.NumLaps() + 1);
+      timer_.NextLap();
+    } while (!timer_.HasTimeLimitExpired());
 
     perf_test::PrintResult("update_tile_priorities_stationary",
                            "",
                            test_name,
-                           num_runs_ / elapsed_.InSecondsF(),
+                           timer_.LapsPerSecond(),
                            "runs/s",
                            true);
   }
 
   void RunUpdateTilePrioritiesScrollingTest(const std::string& test_name,
                                             const gfx::Transform& transform) {
-    start_time_ = base::TimeTicks();
-    num_runs_ = 0;
-
     gfx::Size viewport_size(1024, 768);
     gfx::Rect viewport_rect(viewport_size);
     int xoffsets[] = {10, 0, -10, 0};
@@ -93,9 +75,11 @@
     int offsetIndex = 0;
     int offsetCount = 0;
     const int maxOffsetCount = 1000;
+
+    timer_.Reset();
     do {
       picture_layer_tiling_->UpdateTilePriorities(
-          ACTIVE_TREE, viewport_rect, 1.f, num_runs_ + 1);
+          ACTIVE_TREE, viewport_rect, 1.f, timer_.NumLaps() + 1);
 
       viewport_rect = gfx::Rect(viewport_rect.x() + xoffsets[offsetIndex],
                                 viewport_rect.y() + yoffsets[offsetIndex],
@@ -106,12 +90,13 @@
         offsetCount = 0;
         offsetIndex = (offsetIndex + 1) % 4;
       }
-    } while (DidRun());
+      timer_.NextLap();
+    } while (!timer_.HasTimeLimitExpired());
 
     perf_test::PrintResult("update_tile_priorities_scrolling",
                            "",
                            test_name,
-                           num_runs_ / elapsed_.InSecondsF(),
+                           timer_.LapsPerSecond(),
                            "runs/s",
                            true);
   }
@@ -119,14 +104,13 @@
   void RunTilingRasterTileIteratorTest(const std::string& test_name,
                                        int num_tiles,
                                        const gfx::Rect& viewport) {
-    start_time_ = base::TimeTicks();
-    num_runs_ = 0;
-
     gfx::Size bounds(10000, 10000);
     picture_layer_tiling_ =
         PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
     picture_layer_tiling_->UpdateTilePriorities(
         ACTIVE_TREE, viewport, 1.0f, 1.0);
+
+    timer_.Reset();
     do {
       int count = num_tiles;
       for (PictureLayerTiling::TilingRasterTileIterator it(
@@ -135,12 +119,13 @@
            ++it) {
         --count;
       }
-    } while (DidRun());
+      timer_.NextLap();
+    } while (!timer_.HasTimeLimitExpired());
 
     perf_test::PrintResult("tiling_raster_tile_iterator",
                            "",
                            test_name,
-                           num_runs_ / elapsed_.InSecondsF(),
+                           timer_.LapsPerSecond(),
                            "runs/s",
                            true);
   }
@@ -149,9 +134,7 @@
   FakePictureLayerTilingClient picture_layer_tiling_client_;
   scoped_ptr<PictureLayerTiling> picture_layer_tiling_;
 
-  base::TimeTicks start_time_;
-  base::TimeDelta elapsed_;
-  int num_runs_;
+  LapTimer timer_;
 };
 
 TEST_F(PictureLayerTilingPerfTest, Invalidate) {
diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc
index 32a64eb..259301b 100644
--- a/cc/resources/picture_layer_tiling_set_unittest.cc
+++ b/cc/resources/picture_layer_tiling_set_unittest.cc
@@ -69,7 +69,7 @@
     scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
         new TestSharedBitmapManager());
     scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
-        output_surface.get(), shared_bitmap_manager.get(), 0, false, 1);
+        output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false);
 
     FakePictureLayerTilingClient client(resource_provider.get());
     client.SetTileSize(gfx::Size(256, 256));
diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc
index e1eddd7..3167c63 100644
--- a/cc/resources/picture_layer_tiling_unittest.cc
+++ b/cc/resources/picture_layer_tiling_unittest.cc
@@ -420,14 +420,14 @@
   scoped_ptr<TestablePictureLayerTiling> tiling;
 
   gfx::Rect viewport(0, 0, 100, 100);
-  gfx::Size layer_bounds(200, 200);
+  gfx::Size layer_bounds(1500, 1500);
 
   client.SetTileSize(gfx::Size(10, 10));
 
-  // Tiling at 0.25 scale: this should create 36 tiles (6x6) of size 10x10.
+  // Tiling at 0.25 scale: this should create 47x47 tiles of size 10x10.
   // The reason is that each tile has a one pixel border, so tile at (1, 2)
-  // for instance begins at (8, 16) pixels. So tile at (5, 5) will begin at
-  // (40, 40) and extend right to the end of 200 * 0.25 = 50 edge of the
+  // for instance begins at (8, 16) pixels. So tile at (46, 46) will begin at
+  // (368, 368) and extend to the end of 1500 * 0.25 = 375 edge of the
   // tiling.
   tiling = TestablePictureLayerTiling::Create(0.25f, layer_bounds, &client);
   gfx::Rect viewport_in_content_space =
@@ -435,23 +435,30 @@
 
   tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0);
 
+  gfx::Rect soon_rect = viewport;
+  soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
+  gfx::Rect soon_rect_in_content_space =
+      gfx::ToEnclosedRect(gfx::ScaleRect(soon_rect, 0.25f));
+
   // Sanity checks.
-  for (int i = 0; i < 6; ++i) {
-    for (int j = 0; j < 6; ++j) {
+  for (int i = 0; i < 47; ++i) {
+    for (int j = 0; j < 47; ++j) {
       EXPECT_TRUE(tiling->TileAt(i, j)) << "i: " << i << " j: " << j;
     }
   }
-  for (int i = 0; i < 7; ++i) {
-    EXPECT_FALSE(tiling->TileAt(i, 6)) << "i: " << i;
-    EXPECT_FALSE(tiling->TileAt(6, i)) << "i: " << i;
+  for (int i = 0; i < 47; ++i) {
+    EXPECT_FALSE(tiling->TileAt(i, 47)) << "i: " << i;
+    EXPECT_FALSE(tiling->TileAt(47, i)) << "i: " << i;
   }
 
   // No movement in the viewport implies that tiles will either be NOW
-  // or EVENTUALLY.
+  // or EVENTUALLY, with the exception of tiles that are between 0 and 312
+  // pixels away from the viewport, which will be in the SOON bin.
   bool have_now = false;
   bool have_eventually = false;
-  for (int i = 0; i < 6; ++i) {
-    for (int j = 0; j < 6; ++j) {
+  bool have_soon = false;
+  for (int i = 0; i < 47; ++i) {
+    for (int j = 0; j < 47; ++j) {
       Tile* tile = tiling->TileAt(i, j);
       TilePriority priority = tile->priority(ACTIVE_TREE);
 
@@ -459,6 +466,9 @@
         EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
         EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
         have_now = true;
+      } else if (soon_rect_in_content_space.Intersects(tile->content_rect())) {
+        EXPECT_EQ(TilePriority::SOON, priority.priority_bin);
+        have_soon = true;
       } else {
         EXPECT_EQ(TilePriority::EVENTUALLY, priority.priority_bin);
         EXPECT_GT(priority.distance_to_visible, 0.f);
@@ -468,6 +478,7 @@
   }
 
   EXPECT_TRUE(have_now);
+  EXPECT_TRUE(have_soon);
   EXPECT_TRUE(have_eventually);
 
   // Spot check some distances.
@@ -495,6 +506,11 @@
       gfx::ToEnclosedRect(gfx::ScaleRect(viewport, 0.25f));
   gfx::Rect skewport = tiling->ComputeSkewport(2.0, viewport_in_content_space);
 
+  soon_rect = viewport;
+  soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
+  soon_rect_in_content_space =
+      gfx::ToEnclosedRect(gfx::ScaleRect(soon_rect, 0.25f));
+
   EXPECT_EQ(0, skewport.x());
   EXPECT_EQ(10, skewport.y());
   EXPECT_EQ(25, skewport.width());
@@ -504,12 +520,12 @@
 
   have_now = false;
   have_eventually = false;
-  bool have_soon = false;
+  have_soon = false;
 
   // Viewport moved, so we expect to find some NOW tiles, some SOON tiles and
   // some EVENTUALLY tiles.
-  for (int i = 0; i < 6; ++i) {
-    for (int j = 0; j < 6; ++j) {
+  for (int i = 0; i < 47; ++i) {
+    for (int j = 0; j < 47; ++j) {
       Tile* tile = tiling->TileAt(i, j);
       TilePriority priority = tile->priority(ACTIVE_TREE);
 
@@ -519,7 +535,8 @@
         EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible) << "i: " << i
                                                            << " j: " << j;
         have_now = true;
-      } else if (skewport.Intersects(tile->content_rect())) {
+      } else if (skewport.Intersects(tile->content_rect()) ||
+                 soon_rect_in_content_space.Intersects(tile->content_rect())) {
         EXPECT_EQ(TilePriority::SOON, priority.priority_bin) << "i: " << i
                                                              << " j: " << j;
         EXPECT_GT(priority.distance_to_visible, 0.f) << "i: " << i
@@ -784,7 +801,10 @@
   scoped_ptr<TestablePictureLayerTiling> tiling;
 
   gfx::Rect viewport(50, 50, 100, 100);
-  gfx::Size layer_bounds(200, 200);
+  gfx::Size layer_bounds(800, 800);
+
+  gfx::Rect soon_rect = viewport;
+  soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
 
   client.SetTileSize(gfx::Size(30, 30));
 
@@ -797,7 +817,7 @@
   std::vector<Tile*> all_tiles = tiling->AllTilesForTesting();
 
   // Sanity check.
-  EXPECT_EQ(64u, all_tiles.size());
+  EXPECT_EQ(841u, all_tiles.size());
 
   // The explanation of each iteration is as follows:
   // 1. First iteration tests that we can get all of the tiles correctly.
@@ -849,9 +869,13 @@
                                new_priority.distance_to_visible;
           eventually_bin_order_correct_count += order_correct;
           eventually_bin_order_incorrect_count += !order_correct;
-        } else {
+        } else if (!soon_rect.Intersects(new_tile->content_rect()) &&
+                   !soon_rect.Intersects(last_tile->content_rect())) {
           EXPECT_LE(last_priority.distance_to_visible,
                     new_priority.distance_to_visible);
+          EXPECT_EQ(TilePriority::NOW, new_priority.priority_bin);
+        } else if (new_priority.distance_to_visible > 0.f) {
+          EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
         }
       }
       have_tiles[new_priority.priority_bin] = true;
@@ -871,10 +895,10 @@
     EXPECT_GT(eventually_bin_order_correct_count,
               eventually_bin_order_incorrect_count);
 
-    // We should have now and eventually tiles, but not soon tiles because the
-    // viewport is static.
+    // We should have now and eventually tiles, as well as soon tiles from
+    // the border region.
     EXPECT_TRUE(have_tiles[TilePriority::NOW]);
-    EXPECT_FALSE(have_tiles[TilePriority::SOON]);
+    EXPECT_TRUE(have_tiles[TilePriority::SOON]);
     EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
 
     EXPECT_EQ(unique_tiles.size(), all_tiles.size());
@@ -886,8 +910,8 @@
   scoped_ptr<TestablePictureLayerTiling> tiling;
 
   gfx::Rect viewport(50, 0, 100, 100);
-  gfx::Rect moved_viewport(50, 0, 100, 250);
-  gfx::Size layer_bounds(500, 500);
+  gfx::Rect moved_viewport(50, 0, 100, 500);
+  gfx::Size layer_bounds(1000, 1000);
 
   client.SetTileSize(gfx::Size(30, 30));
 
@@ -895,6 +919,9 @@
   tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0);
   tiling->UpdateTilePriorities(ACTIVE_TREE, moved_viewport, 1.0f, 2.0);
 
+  gfx::Rect soon_rect = moved_viewport;
+  soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
+
   // There are 3 bins in TilePriority.
   bool have_tiles[3] = {};
   Tile* last_tile = NULL;
@@ -921,9 +948,12 @@
                              new_priority.distance_to_visible;
         eventually_bin_order_correct_count += order_correct;
         eventually_bin_order_incorrect_count += !order_correct;
-      } else {
+      } else if (!soon_rect.Intersects(new_tile->content_rect()) &&
+                 !soon_rect.Intersects(last_tile->content_rect())) {
         EXPECT_LE(last_priority.distance_to_visible,
                   new_priority.distance_to_visible);
+      } else if (new_priority.distance_to_visible > 0.f) {
+        EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
       }
     }
     last_tile = new_tile;
@@ -948,7 +978,7 @@
   CHECK(output_surface->BindToClient(&output_surface_client));
   TestSharedBitmapManager shared_bitmap_manager;
   scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
-      output_surface.get(), &shared_bitmap_manager, 0, false, 1);
+      output_surface.get(), &shared_bitmap_manager, 0, false, 1, false);
 
   FakePictureLayerTilingClient client(resource_provider.get());
   scoped_ptr<TestablePictureLayerTiling> tiling;
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc
index 6637e4d..27c58a1 100644
--- a/cc/resources/picture_pile.cc
+++ b/cc/resources/picture_pile.cc
@@ -153,6 +153,7 @@
                          const Region& invalidation,
                          const gfx::Rect& visible_layer_rect,
                          int frame_number,
+                         Picture::RecordingMode recording_mode,
                          RenderingStatsInstrumentation* stats_instrumentation) {
   background_color_ = background_color;
   contents_opaque_ = contents_opaque;
@@ -243,7 +244,7 @@
                                   tile_grid_info_,
                                   gather_pixel_refs,
                                   num_raster_threads,
-                                  Picture::RECORD_NORMALLY);
+                                  recording_mode);
         // Note the '&&' with previous is-suitable state.
         // This means that once a picture-pile becomes unsuitable for gpu
         // rasterization due to some content, it will continue to be unsuitable
diff --git a/cc/resources/picture_pile.h b/cc/resources/picture_pile.h
index dbc3966..415bbdf 100644
--- a/cc/resources/picture_pile.h
+++ b/cc/resources/picture_pile.h
@@ -27,6 +27,7 @@
               const Region& invalidation,
               const gfx::Rect& visible_layer_rect,
               int frame_number,
+              Picture::RecordingMode recording_mode,
               RenderingStatsInstrumentation* stats_instrumentation);
 
   void set_slow_down_raster_scale_factor(int factor) {
diff --git a/cc/resources/picture_pile_unittest.cc b/cc/resources/picture_pile_unittest.cc
index 04b4c33..0387863 100644
--- a/cc/resources/picture_pile_unittest.cc
+++ b/cc/resources/picture_pile_unittest.cc
@@ -60,6 +60,7 @@
                          invalidation,
                          visible_layer_rect,
                          frame_number_,
+                         Picture::RECORD_NORMALLY,
                          &stats_instrumentation_);
   }
 
diff --git a/cc/resources/picture_unittest.cc b/cc/resources/picture_unittest.cc
index a3910c6..1367c5f 100644
--- a/cc/resources/picture_unittest.cc
+++ b/cc/resources/picture_unittest.cc
@@ -43,68 +43,75 @@
   tmp.reset(new base::StringValue("abc!@#$%"));
   scoped_refptr<Picture> invalid_picture =
       Picture::CreateFromValue(tmp.get());
-  EXPECT_TRUE(!invalid_picture.get());
+  EXPECT_FALSE(invalid_picture.get());
+
+  Picture::RecordingMode kRecordingModes[] = {Picture::RECORD_NORMALLY,
+                                              Picture::RECORD_WITH_SKRECORD};
 
   // Single full-size rect picture.
   content_layer_client.add_draw_rect(layer_rect, red_paint);
-  scoped_refptr<Picture> one_rect_picture =
-      Picture::Create(layer_rect,
-                      &content_layer_client,
-                      tile_grid_info,
-                      false,
-                      0,
-                      Picture::RECORD_NORMALLY);
-  scoped_ptr<base::Value> serialized_one_rect(
-      one_rect_picture->AsValue());
 
-  // Reconstruct the picture.
-  scoped_refptr<Picture> one_rect_picture_check =
-      Picture::CreateFromValue(serialized_one_rect.get());
-  EXPECT_TRUE(!!one_rect_picture_check.get());
+  for (size_t i = 0; i < arraysize(kRecordingModes); ++i) {
+    scoped_refptr<Picture> one_rect_picture =
+        Picture::Create(layer_rect,
+                        &content_layer_client,
+                        tile_grid_info,
+                        false,
+                        0,
+                        kRecordingModes[i]);
+    scoped_ptr<base::Value> serialized_one_rect(one_rect_picture->AsValue());
 
-  // Check for equivalence.
-  unsigned char one_rect_buffer[4 * 100 * 100] = {0};
-  DrawPicture(one_rect_buffer, layer_rect, one_rect_picture);
-  unsigned char one_rect_buffer_check[4 * 100 * 100] = {0};
-  DrawPicture(one_rect_buffer_check, layer_rect, one_rect_picture_check);
+    // Reconstruct the picture.
+    scoped_refptr<Picture> one_rect_picture_check =
+        Picture::CreateFromValue(serialized_one_rect.get());
+    EXPECT_TRUE(!!one_rect_picture_check.get());
 
-  EXPECT_EQ(one_rect_picture->LayerRect(),
-            one_rect_picture_check->LayerRect());
-  EXPECT_EQ(one_rect_picture->OpaqueRect(),
-            one_rect_picture_check->OpaqueRect());
-  EXPECT_TRUE(
-      memcmp(one_rect_buffer, one_rect_buffer_check, 4 * 100 * 100) == 0);
+    // Check for equivalence.
+    unsigned char one_rect_buffer[4 * 100 * 100] = {0};
+    DrawPicture(one_rect_buffer, layer_rect, one_rect_picture);
+    unsigned char one_rect_buffer_check[4 * 100 * 100] = {0};
+    DrawPicture(one_rect_buffer_check, layer_rect, one_rect_picture_check);
+
+    EXPECT_EQ(one_rect_picture->LayerRect(),
+              one_rect_picture_check->LayerRect());
+    EXPECT_EQ(one_rect_picture->OpaqueRect(),
+              one_rect_picture_check->OpaqueRect());
+    EXPECT_TRUE(memcmp(one_rect_buffer, one_rect_buffer_check, 4 * 100 * 100) ==
+                0);
+  }
 
   // Two rect picture.
   content_layer_client.add_draw_rect(gfx::Rect(25, 25, 50, 50), green_paint);
-  scoped_refptr<Picture> two_rect_picture =
-      Picture::Create(layer_rect,
-                      &content_layer_client,
-                      tile_grid_info,
-                      false,
-                      0,
-                      Picture::RECORD_NORMALLY);
 
-  scoped_ptr<base::Value> serialized_two_rect(
-      two_rect_picture->AsValue());
+  for (size_t i = 0; i < arraysize(kRecordingModes); ++i) {
+    scoped_refptr<Picture> two_rect_picture =
+        Picture::Create(layer_rect,
+                        &content_layer_client,
+                        tile_grid_info,
+                        false,
+                        0,
+                        Picture::RECORD_NORMALLY);
 
-  // Reconstruct the picture.
-  scoped_refptr<Picture> two_rect_picture_check =
-      Picture::CreateFromValue(serialized_two_rect.get());
-  EXPECT_TRUE(!!two_rect_picture_check.get());
+    scoped_ptr<base::Value> serialized_two_rect(two_rect_picture->AsValue());
 
-  // Check for equivalence.
-  unsigned char two_rect_buffer[4 * 100 * 100] = {0};
-  DrawPicture(two_rect_buffer, layer_rect, two_rect_picture);
-  unsigned char two_rect_buffer_check[4 * 100 * 100] = {0};
-  DrawPicture(two_rect_buffer_check, layer_rect, two_rect_picture_check);
+    // Reconstruct the picture.
+    scoped_refptr<Picture> two_rect_picture_check =
+        Picture::CreateFromValue(serialized_two_rect.get());
+    EXPECT_TRUE(!!two_rect_picture_check.get());
 
-  EXPECT_EQ(two_rect_picture->LayerRect(),
-            two_rect_picture_check->LayerRect());
-  EXPECT_EQ(two_rect_picture->OpaqueRect(),
-            two_rect_picture_check->OpaqueRect());
-  EXPECT_TRUE(
-      memcmp(two_rect_buffer, two_rect_buffer_check, 4 * 100 * 100) == 0);
+    // Check for equivalence.
+    unsigned char two_rect_buffer[4 * 100 * 100] = {0};
+    DrawPicture(two_rect_buffer, layer_rect, two_rect_picture);
+    unsigned char two_rect_buffer_check[4 * 100 * 100] = {0};
+    DrawPicture(two_rect_buffer_check, layer_rect, two_rect_picture_check);
+
+    EXPECT_EQ(two_rect_picture->LayerRect(),
+              two_rect_picture_check->LayerRect());
+    EXPECT_EQ(two_rect_picture->OpaqueRect(),
+              two_rect_picture_check->OpaqueRect());
+    EXPECT_TRUE(memcmp(two_rect_buffer, two_rect_buffer_check, 4 * 100 * 100) ==
+                0);
+  }
 }
 
 TEST(PictureTest, PixelRefIterator) {
@@ -463,6 +470,8 @@
                                                    0,
                                                    Picture::RECORD_NORMALLY);
   EXPECT_TRUE(content_layer_client.last_canvas() != NULL);
+  EXPECT_EQ(ContentLayerClient::GRAPHICS_CONTEXT_ENABLED,
+            content_layer_client.last_context_status());
   EXPECT_TRUE(picture);
 
   picture = Picture::Create(layer_rect,
@@ -472,6 +481,8 @@
                             0,
                             Picture::RECORD_WITH_SK_NULL_CANVAS);
   EXPECT_TRUE(content_layer_client.last_canvas() != NULL);
+  EXPECT_EQ(ContentLayerClient::GRAPHICS_CONTEXT_ENABLED,
+            content_layer_client.last_context_status());
   EXPECT_TRUE(picture);
 
   picture = Picture::Create(layer_rect,
@@ -480,7 +491,9 @@
                             false,
                             0,
                             Picture::RECORD_WITH_PAINTING_DISABLED);
-  EXPECT_EQ(NULL, content_layer_client.last_canvas());
+  EXPECT_TRUE(content_layer_client.last_canvas() != NULL);
+  EXPECT_EQ(ContentLayerClient::GRAPHICS_CONTEXT_DISABLED,
+            content_layer_client.last_context_status());
   EXPECT_TRUE(picture);
 
   picture = Picture::Create(layer_rect,
diff --git a/cc/resources/prioritized_resource_unittest.cc b/cc/resources/prioritized_resource_unittest.cc
index 7bbe70f..14eb317 100644
--- a/cc/resources/prioritized_resource_unittest.cc
+++ b/cc/resources/prioritized_resource_unittest.cc
@@ -29,7 +29,8 @@
     CHECK(output_surface_->BindToClient(&output_surface_client_));
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+        false);
   }
 
   virtual ~PrioritizedResourceTest() {
diff --git a/cc/resources/prioritized_tile_set_unittest.cc b/cc/resources/prioritized_tile_set_unittest.cc
index ebe144e..69fef52 100644
--- a/cc/resources/prioritized_tile_set_unittest.cc
+++ b/cc/resources/prioritized_tile_set_unittest.cc
@@ -57,7 +57,8 @@
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ =
         ResourceProvider::Create(
-            output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1)
+            output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+            false)
             .Pass();
     resource_pool_ = ResourcePool::Create(
         resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
diff --git a/cc/resources/raster_worker_pool_perftest.cc b/cc/resources/raster_worker_pool_perftest.cc
index ee3f359..0689e50 100644
--- a/cc/resources/raster_worker_pool_perftest.cc
+++ b/cc/resources/raster_worker_pool_perftest.cc
@@ -31,7 +31,8 @@
   // Overridden from gpu::gles2::GLES2Interface:
   virtual GLuint CreateImageCHROMIUM(GLsizei width,
                                      GLsizei height,
-                                     GLenum internalformat) OVERRIDE {
+                                     GLenum internalformat,
+                                     GLenum usage) OVERRIDE {
     return 1u;
   }
   virtual void GenBuffers(GLsizei n, GLuint* buffers) OVERRIDE {
@@ -157,8 +158,8 @@
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ =
         ResourceProvider::Create(
-            output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1)
-            .Pass();
+            output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+            false).Pass();
     staging_resource_pool_ = ResourcePool::Create(
         resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
   }
diff --git a/cc/resources/raster_worker_pool_unittest.cc b/cc/resources/raster_worker_pool_unittest.cc
index 32373a5..7a5f324 100644
--- a/cc/resources/raster_worker_pool_unittest.cc
+++ b/cc/resources/raster_worker_pool_unittest.cc
@@ -114,8 +114,8 @@
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ =
         ResourceProvider::Create(
-            output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1)
-            .Pass();
+            output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+            false).Pass();
     staging_resource_pool_ = ResourcePool::Create(
         resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
 
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index 3ce8d63..c49591c 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -431,8 +431,11 @@
 
 ResourceProvider::DirectRasterBuffer::DirectRasterBuffer(
     const Resource* resource,
-    ResourceProvider* resource_provider)
-    : RasterBuffer(resource, resource_provider), surface_generation_id_(0u) {}
+    ResourceProvider* resource_provider,
+    bool use_distance_field_text )
+    : RasterBuffer(resource, resource_provider),
+      surface_generation_id_(0u),
+      use_distance_field_text_(use_distance_field_text) {}
 
 ResourceProvider::DirectRasterBuffer::~DirectRasterBuffer() {}
 
@@ -466,8 +469,11 @@
         desc.fTextureHandle = resource()->gl_id;
         skia::RefPtr<GrTexture> gr_texture =
             skia::AdoptRef(gr_context->wrapBackendTexture(desc));
-        surface = skia::AdoptRef(
-            SkSurface::NewRenderTargetDirect(gr_texture->asRenderTarget()));
+        SkSurface::TextRenderMode text_render_mode =
+            use_distance_field_text_ ? SkSurface::kDistanceField_TextRenderMode
+                                     : SkSurface::kStandard_TextRenderMode;
+        surface = skia::AdoptRef(SkSurface::NewRenderTargetDirect(
+            gr_texture->asRenderTarget(), text_render_mode));
       }
       break;
     }
@@ -592,13 +598,15 @@
     SharedBitmapManager* shared_bitmap_manager,
     int highp_threshold_min,
     bool use_rgba_4444_texture_format,
-    size_t id_allocation_chunk_size) {
+    size_t id_allocation_chunk_size,
+    bool use_distance_field_text) {
   scoped_ptr<ResourceProvider> resource_provider(
       new ResourceProvider(output_surface,
                            shared_bitmap_manager,
                            highp_threshold_min,
                            use_rgba_4444_texture_format,
-                           id_allocation_chunk_size));
+                           id_allocation_chunk_size,
+                           use_distance_field_text));
 
   if (resource_provider->ContextGL())
     resource_provider->InitializeGL();
@@ -736,34 +744,27 @@
   return id;
 }
 
-ResourceProvider::ResourceId
-ResourceProvider::CreateResourceFromExternalTexture(
-    GLuint texture_target,
-    GLuint texture_id) {
+ResourceProvider::ResourceId ResourceProvider::CreateResourceFromIOSurface(
+    const gfx::Size& size,
+    unsigned io_surface_id) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  DCHECK(texture_target);
-  DCHECK(texture_id);
-  GLES2Interface* gl = ContextGL();
-  DCHECK(gl);
-  GLC(gl, gl->BindTexture(texture_target, texture_id));
-  GLC(gl, gl->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-  GLC(gl, gl->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-  GLC(gl,
-      gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-  GLC(gl,
-      gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-
   ResourceId id = next_id_++;
-  Resource resource(texture_id,
+  Resource resource(0,
                     gfx::Size(),
-                    Resource::External,
-                    texture_target,
+                    Resource::Internal,
+                    GL_TEXTURE_RECTANGLE_ARB,
                     GL_LINEAR,
-                    0,
+                    GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
                     GL_CLAMP_TO_EDGE,
                     TextureUsageAny,
                     RGBA_8888);
+  LazyCreate(&resource);
+  GLES2Interface* gl = ContextGL();
+  DCHECK(gl);
+  gl->BindTexture(GL_TEXTURE_RECTANGLE_ARB, resource.gl_id);
+  gl->TexImageIOSurface2DCHROMIUM(
+      GL_TEXTURE_RECTANGLE_ARB, size.width(), size.height(), io_surface_id, 0);
   resource.allocated = true;
   resources_[id] = resource;
   return id;
@@ -869,7 +870,8 @@
     DCHECK(gl);
     GLC(gl, gl->DeleteBuffers(1, &resource->gl_pixel_buffer_id));
   }
-  if (resource->mailbox.IsValid() && resource->origin == Resource::External) {
+  if (resource->origin == Resource::External) {
+    DCHECK(resource->mailbox.IsValid());
     GLuint sync_point = resource->mailbox.sync_point();
     if (resource->type == GLTexture) {
       DCHECK(resource->mailbox.IsTexture());
@@ -894,7 +896,7 @@
     }
     resource->release_callback.Run(sync_point, lost_resource);
   }
-  if (resource->gl_id && resource->origin != Resource::External) {
+  if (resource->gl_id) {
     GLES2Interface* gl = ContextGL();
     DCHECK(gl);
     GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
@@ -910,10 +912,6 @@
     DCHECK(resource->origin == Resource::Internal);
     delete[] resource->pixels;
   }
-  // We should never delete the texture for a resource created by
-  // CreateResourceFromExternalTexture().
-  DCHECK(!resource->gl_id || resource->origin == Resource::External);
-
   resources_.erase(it);
 }
 
@@ -1247,7 +1245,8 @@
                                    SharedBitmapManager* shared_bitmap_manager,
                                    int highp_threshold_min,
                                    bool use_rgba_4444_texture_format,
-                                   size_t id_allocation_chunk_size)
+                                   size_t id_allocation_chunk_size,
+                                   bool use_distance_field_text)
     : output_surface_(output_surface),
       shared_bitmap_manager_(shared_bitmap_manager),
       lost_output_surface_(false),
@@ -1262,7 +1261,8 @@
       best_texture_format_(RGBA_8888),
       use_rgba_4444_texture_format_(use_rgba_4444_texture_format),
       id_allocation_chunk_size_(id_allocation_chunk_size),
-      use_sync_query_(false) {
+      use_sync_query_(false),
+      use_distance_field_text_(use_distance_field_text) {
   DCHECK(output_surface_->HasClient());
   DCHECK(id_allocation_chunk_size_);
 }
@@ -1558,8 +1558,6 @@
         DCHECK(resource->gl_id);
         GLC(gl, gl->WaitSyncPointCHROMIUM(returned.sync_point));
       } else {
-        // Because CreateResourceFromExternalTexture() never be called,
-        // when enabling delegated compositor.
         DCHECK(!resource->gl_id);
         resource->mailbox.set_sync_point(returned.sync_point);
       }
@@ -1606,11 +1604,7 @@
   Resource* source = GetResource(id);
   DCHECK(!source->locked_for_write);
   DCHECK(!source->lock_for_read_count);
-  // Because CreateResourceFromExternalTexture() never be called,
-  // when enabling delegated compositor.
-  DCHECK(source->origin == Resource::Internal ||
-         source->origin == Resource::Delegated ||
-         (source->origin == Resource::External && source->mailbox.IsValid()));
+  DCHECK(source->origin != Resource::External || source->mailbox.IsValid());
   DCHECK(source->allocated);
   DCHECK_EQ(source->wrap_mode, GL_CLAMP_TO_EDGE);
   resource->id = id;
@@ -1757,7 +1751,7 @@
   Resource* resource = GetResource(id);
   if (!resource->direct_raster_buffer.get()) {
     resource->direct_raster_buffer.reset(
-        new DirectRasterBuffer(resource, this));
+        new DirectRasterBuffer(resource, this, use_distance_field_text_));
   }
   return resource->direct_raster_buffer->LockForWrite();
 }
@@ -2157,7 +2151,8 @@
   resource->image_id =
       gl->CreateImageCHROMIUM(resource->size.width(),
                               resource->size.height(),
-                              TextureToStorageFormat(resource->format));
+                              TextureToStorageFormat(resource->format),
+                              GL_IMAGE_MAP_CHROMIUM);
   DCHECK(resource->image_id);
 }
 
@@ -2187,8 +2182,8 @@
     GLES2Interface* gl = ContextGL();
     DCHECK(gl);
     // MapImageCHROMIUM should be called prior to GetImageParameterivCHROMIUM.
-    uint8_t* pixels = static_cast<uint8_t*>(
-        gl->MapImageCHROMIUM(resource->image_id, GL_READ_WRITE));
+    uint8_t* pixels =
+        static_cast<uint8_t*>(gl->MapImageCHROMIUM(resource->image_id));
     gl->GetImageParameterivCHROMIUM(
         resource->image_id, GL_IMAGE_ROWBYTES_CHROMIUM, stride);
     return pixels;
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
index cf1bb9b..1d991e2 100644
--- a/cc/resources/resource_provider.h
+++ b/cc/resources/resource_provider.h
@@ -75,7 +75,8 @@
       SharedBitmapManager* shared_bitmap_manager,
       int highp_threshold_min,
       bool use_rgba_4444_texture_format,
-      size_t id_allocation_chunk_size);
+      size_t id_allocation_chunk_size,
+      bool use_distance_field_text);
   virtual ~ResourceProvider();
 
   void InitializeSoftware();
@@ -125,10 +126,9 @@
                              ResourceFormat format);
 
   ResourceId CreateBitmap(const gfx::Size& size, GLint wrap_mode);
-  // Wraps an external texture into a GL resource.
-  ResourceId CreateResourceFromExternalTexture(
-      unsigned texture_target,
-      unsigned texture_id);
+  // Wraps an IOSurface into a GL resource.
+  ResourceId CreateResourceFromIOSurface(const gfx::Size& size,
+                                         unsigned io_surface_id);
 
   // Wraps an external texture mailbox into a GL resource.
   ResourceId CreateResourceFromTextureMailbox(
@@ -477,7 +477,8 @@
   class DirectRasterBuffer : public RasterBuffer {
    public:
     DirectRasterBuffer(const Resource* resource,
-                       ResourceProvider* resource_provider);
+                       ResourceProvider* resource_provider,
+                       bool use_distance_field_text);
     virtual ~DirectRasterBuffer();
 
    protected:
@@ -488,6 +489,7 @@
    private:
     skia::RefPtr<SkSurface> surface_;
     uint32_t surface_generation_id_;
+    const bool use_distance_field_text_;
 
     DISALLOW_COPY_AND_ASSIGN(DirectRasterBuffer);
   };
@@ -566,7 +568,8 @@
                    SharedBitmapManager* shared_bitmap_manager,
                    int highp_threshold_min,
                    bool use_rgba_4444_texture_format,
-                   size_t id_allocation_chunk_size);
+                   size_t id_allocation_chunk_size,
+                   bool use_distance_field_text);
 
   void CleanUpGLIfNeeded();
 
@@ -652,6 +655,8 @@
 
   bool use_sync_query_;
 
+  bool use_distance_field_text_;
+
   DISALLOW_COPY_AND_ASSIGN(ResourceProvider);
 };
 
diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc
index bffd07e..547bdbb 100644
--- a/cc/resources/resource_provider_unittest.cc
+++ b/cc/resources/resource_provider_unittest.cc
@@ -403,13 +403,15 @@
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
 
     resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+        false);
     child_resource_provider_ = ResourceProvider::Create(
         child_output_surface_.get(),
         shared_bitmap_manager_.get(),
         0,
         false,
-        1);
+        1,
+        false);
   }
 
   static void CollectResources(ReturnedResourceArray* array,
@@ -1112,7 +1114,8 @@
   CHECK(child_output_surface->BindToClient(&child_output_surface_client));
 
   scoped_ptr<ResourceProvider> child_resource_provider(ResourceProvider::Create(
-      child_output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      child_output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1,
+      false));
 
   gfx::Size size(1, 1);
   ResourceFormat format = RGBA_8888;
@@ -1592,7 +1595,8 @@
                                  shared_bitmap_manager.get(),
                                  0,
                                  false,
-                                 1));
+                                 1,
+                                 false));
 
     scoped_ptr<TextureStateTrackingContext> parent_context_owned(
         new TextureStateTrackingContext);
@@ -1608,7 +1612,8 @@
                                  shared_bitmap_manager.get(),
                                  0,
                                  false,
-                                 1));
+                                 1,
+                                 false));
 
     gfx::Size size(1, 1);
     ResourceFormat format = RGBA_8888;
@@ -2216,7 +2221,7 @@
   CHECK(output_surface->BindToClient(&output_surface_client));
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   gfx::Size size(1, 1);
   ResourceFormat format = RGBA_8888;
@@ -2297,7 +2302,7 @@
   CHECK(output_surface->BindToClient(&output_surface_client));
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   gfx::Size size(1, 1);
   ResourceFormat format = RGBA_8888;
@@ -2346,7 +2351,7 @@
   CHECK(output_surface->BindToClient(&output_surface_client));
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   gfx::Size size(1, 1);
   ResourceFormat format = RGBA_8888;
@@ -2400,7 +2405,7 @@
   CHECK(output_surface->BindToClient(&output_surface_client));
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
       base::Bind(&EmptyReleaseCallback));
@@ -2435,7 +2440,7 @@
   CHECK(output_surface->BindToClient(&output_surface_client));
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   unsigned texture_id = 1;
   uint32 sync_point = 30;
@@ -2499,7 +2504,7 @@
   CHECK(output_surface->BindToClient(&output_surface_client));
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   unsigned texture_id = 1;
   uint32 sync_point = 30;
@@ -2609,9 +2614,9 @@
                     GLsizei image_size,
                     const void* data));
   MOCK_METHOD1(waitAsyncTexImage2DCHROMIUM, void(GLenum));
-  MOCK_METHOD3(createImageCHROMIUM, GLuint(GLsizei, GLsizei, GLenum));
+  MOCK_METHOD4(createImageCHROMIUM, GLuint(GLsizei, GLsizei, GLenum, GLenum));
   MOCK_METHOD1(destroyImageCHROMIUM, void(GLuint));
-  MOCK_METHOD2(mapImageCHROMIUM, void*(GLuint, GLenum));
+  MOCK_METHOD1(mapImageCHROMIUM, void*(GLuint));
   MOCK_METHOD3(getImageParameterivCHROMIUM, void(GLuint, GLenum, GLint*));
   MOCK_METHOD1(unmapImageCHROMIUM, void(GLuint));
   MOCK_METHOD2(bindTexImage2DCHROMIUM, void(GLenum, GLint));
@@ -2637,7 +2642,7 @@
   CHECK(output_surface->BindToClient(&output_surface_client));
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   gfx::Size size(2, 2);
   gfx::Vector2d offset(0, 0);
@@ -2710,7 +2715,7 @@
   CHECK(output_surface->BindToClient(&output_surface_client));
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   gfx::Size size(2, 2);
   ResourceFormat format = RGBA_8888;
@@ -2747,7 +2752,7 @@
   CHECK(output_surface->BindToClient(&output_surface_client));
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   gfx::Size size(2, 2);
   ResourceFormat format = RGBA_8888;
@@ -2790,7 +2795,7 @@
   int texture_id = 123;
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   id = resource_provider->CreateResource(
       size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
@@ -2831,7 +2836,7 @@
   int texture_id = 123;
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   id = resource_provider->CreateResource(
       size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
@@ -2872,7 +2877,7 @@
   int texture_id = 123;
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   EXPECT_CALL(*context, NextTextureId()).WillRepeatedly(Return(texture_id));
 
@@ -2911,14 +2916,16 @@
   const unsigned kImageId = 234u;
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   id = resource_provider->CreateResource(
       size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
 
   const int kStride = 4;
   void* dummy_mapped_buffer_address = NULL;
-  EXPECT_CALL(*context, createImageCHROMIUM(kWidth, kHeight, GL_RGBA8_OES))
+  EXPECT_CALL(
+      *context,
+      createImageCHROMIUM(kWidth, kHeight, GL_RGBA8_OES, GL_IMAGE_MAP_CHROMIUM))
       .WillOnce(Return(kImageId))
       .RetiresOnSaturation();
   EXPECT_CALL(*context, getImageParameterivCHROMIUM(kImageId,
@@ -2926,7 +2933,7 @@
                                                     _))
       .WillOnce(SetArgPointee<2>(kStride))
       .RetiresOnSaturation();
-  EXPECT_CALL(*context, mapImageCHROMIUM(kImageId, GL_READ_WRITE))
+  EXPECT_CALL(*context, mapImageCHROMIUM(kImageId))
       .WillOnce(Return(dummy_mapped_buffer_address))
       .RetiresOnSaturation();
   resource_provider->MapImageRasterBuffer(id);
@@ -2956,7 +2963,7 @@
       getImageParameterivCHROMIUM(kImageId, GL_IMAGE_ROWBYTES_CHROMIUM, _))
       .WillOnce(SetArgPointee<2>(kStride))
       .RetiresOnSaturation();
-  EXPECT_CALL(*context, mapImageCHROMIUM(kImageId, GL_READ_WRITE))
+  EXPECT_CALL(*context, mapImageCHROMIUM(kImageId))
       .WillOnce(Return(dummy_mapped_buffer_address))
       .RetiresOnSaturation();
   resource_provider->MapImageRasterBuffer(id);
@@ -3003,7 +3010,7 @@
   const uint32_t kBadBeef = 0xbadbeef;
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   id = resource_provider->CreateResource(
       size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
@@ -3051,14 +3058,16 @@
   const unsigned kImageId = 234u;
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   source_id = resource_provider->CreateResource(
       size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
 
   const int kStride = 4;
   void* dummy_mapped_buffer_address = NULL;
-  EXPECT_CALL(*context, createImageCHROMIUM(kWidth, kHeight, GL_RGBA8_OES))
+  EXPECT_CALL(
+      *context,
+      createImageCHROMIUM(kWidth, kHeight, GL_RGBA8_OES, GL_IMAGE_MAP_CHROMIUM))
       .WillOnce(Return(kImageId))
       .RetiresOnSaturation();
   EXPECT_CALL(
@@ -3066,7 +3075,7 @@
       getImageParameterivCHROMIUM(kImageId, GL_IMAGE_ROWBYTES_CHROMIUM, _))
       .WillOnce(SetArgPointee<2>(kStride))
       .RetiresOnSaturation();
-  EXPECT_CALL(*context, mapImageCHROMIUM(kImageId, GL_READ_WRITE))
+  EXPECT_CALL(*context, mapImageCHROMIUM(kImageId))
       .WillOnce(Return(dummy_mapped_buffer_address))
       .RetiresOnSaturation();
   resource_provider->MapImageRasterBuffer(source_id);
@@ -3127,7 +3136,7 @@
   const uint32_t kBadBeef = 0xbadbeef;
 
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false));
 
   source_id = resource_provider->CreateResource(
       size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
@@ -3184,7 +3193,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
 
   CheckCreateResource(ResourceProvider::Bitmap, resource_provider.get(), NULL);
 
@@ -3221,7 +3230,8 @@
                                shared_bitmap_manager_.get(),
                                0,
                                false,
-                               1));
+                               1,
+                               false));
   int texture_id = 123;
 
   ResourceProvider::ResourceId id = resource_provider->CreateResource(
@@ -3255,7 +3265,8 @@
                                shared_bitmap_manager_.get(),
                                0,
                                false,
-                               1));
+                               1,
+                               false));
   int texture_id = 123;
   uint8_t pixels[8];
 
@@ -3314,7 +3325,8 @@
                                  shared_bitmap_manager.get(),
                                  0,
                                  false,
-                                 kTextureAllocationChunkSize));
+                                 kTextureAllocationChunkSize,
+                                 false));
 
     ResourceProvider::ResourceId id = resource_provider->CreateResource(
         size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
@@ -3332,7 +3344,8 @@
                                  shared_bitmap_manager.get(),
                                  0,
                                  false,
-                                 kTextureAllocationChunkSize));
+                                 kTextureAllocationChunkSize,
+                                 false));
 
     ResourceProvider::ResourceId id = resource_provider->CreateResource(
         size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
diff --git a/cc/resources/resource_update_controller_unittest.cc b/cc/resources/resource_update_controller_unittest.cc
index 44e65a5..0fb899d 100644
--- a/cc/resources/resource_update_controller_unittest.cc
+++ b/cc/resources/resource_update_controller_unittest.cc
@@ -126,7 +126,8 @@
 
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+        false);
   }
 
   void AppendFullUploadsOfIndexedTextureToUpdateQueue(int count,
diff --git a/cc/resources/scoped_resource_unittest.cc b/cc/resources/scoped_resource_unittest.cc
index 8c97d8e..5042221 100644
--- a/cc/resources/scoped_resource_unittest.cc
+++ b/cc/resources/scoped_resource_unittest.cc
@@ -22,7 +22,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
   scoped_ptr<ScopedResource> texture =
       ScopedResource::Create(resource_provider.get());
 
@@ -42,7 +42,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
   scoped_ptr<ScopedResource> texture =
       ScopedResource::Create(resource_provider.get());
   texture->Allocate(gfx::Size(30, 30),
@@ -66,7 +66,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
   {
     scoped_ptr<ScopedResource> texture =
         ScopedResource::Create(resource_provider.get());
@@ -102,7 +102,7 @@
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1));
+      output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
   {
     scoped_ptr<ScopedResource> texture =
         ScopedResource::Create(resource_provider.get());
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index eb389c5..4128650 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -338,13 +338,10 @@
 // Determine bin based on three categories of tiles: things we need now,
 // things we need soon, and eventually.
 inline ManagedTileBin BinFromTilePriority(const TilePriority& prio) {
-  const float kBackflingGuardDistancePixels = 314.0f;
-
   if (prio.priority_bin == TilePriority::NOW)
     return NOW_BIN;
 
-  if (prio.priority_bin == TilePriority::SOON ||
-      prio.distance_to_visible < kBackflingGuardDistancePixels)
+  if (prio.priority_bin == TilePriority::SOON)
     return SOON_BIN;
 
   if (prio.distance_to_visible == std::numeric_limits<float>::infinity())
@@ -675,8 +672,7 @@
     // should keep it in the prioritized tile set to ensure that AssignGpuMemory
     // can visit it.
     if (mts.bin == NEVER_BIN &&
-        !mts.tile_versions[mts.raster_mode].raster_task_ &&
-        !tile->required_for_activation()) {
+        !mts.tile_versions[mts.raster_mode].raster_task_) {
       FreeResourcesForTile(tile);
       continue;
     }
@@ -841,7 +837,6 @@
   size_t max_raster_bytes = max_raster_usage_bytes_ / 2;
   size_t raster_bytes = 0;
 
-  int processed_required_for_activation_tile_count = 0;
   unsigned schedule_priority = 1u;
   for (PrioritizedTileSet::Iterator it(tiles, true); it; ++it) {
     Tile* tile = *it;
@@ -861,8 +856,6 @@
     // If the tile is not needed, free it up.
     if (mts.bin == NEVER_BIN) {
       FreeResourcesForTile(tile);
-      if (tile->required_for_activation())
-        ++processed_required_for_activation_tile_count;
       continue;
     }
 
@@ -921,10 +914,8 @@
       hard_bytes_left -= tile_bytes;
       soft_bytes_left =
           (soft_bytes_left > tile_bytes) ? soft_bytes_left - tile_bytes : 0;
-      if (tile_version.resource_) {
-        DCHECK(tile->IsReadyToDraw());
+      if (tile_version.resource_)
         continue;
-      }
     }
 
     DCHECK(!tile_version.resource_);
@@ -943,30 +934,16 @@
 
     if (!can_schedule_tile) {
       all_tiles_that_need_to_be_rasterized_have_memory_ = false;
+      if (tile->required_for_activation())
+        all_tiles_required_for_activation_have_memory_ = false;
       it.DisablePriorityOrdering();
       continue;
     }
 
     raster_bytes = raster_bytes_if_rastered;
     tiles_that_need_to_be_rasterized->push_back(tile);
-    if (tile->required_for_activation())
-      ++processed_required_for_activation_tile_count;
   }
 
-  int total_required_for_activation_tile_count = 0;
-  for (std::vector<PictureLayerImpl*>::const_iterator it = layers_.begin();
-       it != layers_.end();
-       ++it) {
-    if ((*it)->GetTree() == PENDING_TREE) {
-      total_required_for_activation_tile_count +=
-          (*it)->UninitializedTilesRequiredForActivationCount();
-    }
-  }
-
-  all_tiles_required_for_activation_have_memory_ =
-      processed_required_for_activation_tile_count ==
-      total_required_for_activation_tile_count;
-
   // OOM reporting uses hard-limit, soft-OOM is normal depending on limit.
   ever_exceeded_memory_budget_ |= oomed_hard;
   if (ever_exceeded_memory_budget_) {
@@ -983,7 +960,7 @@
   memory_stats_from_last_assign_.bytes_allocated =
       hard_bytes_allocatable - hard_bytes_left;
   memory_stats_from_last_assign_.bytes_unreleasable =
-      hard_bytes_allocatable - bytes_releasable_;
+      resource_pool_->acquired_memory_usage_bytes() - bytes_releasable_;
   memory_stats_from_last_assign_.bytes_over = bytes_that_exceeded_memory_budget;
 }
 
diff --git a/cc/resources/tile_manager_perftest.cc b/cc/resources/tile_manager_perftest.cc
index e81270d..d16eba8 100644
--- a/cc/resources/tile_manager_perftest.cc
+++ b/cc/resources/tile_manager_perftest.cc
@@ -47,7 +47,8 @@
 
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+        false);
     resource_pool_ = ResourcePool::Create(
         resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
     size_t raster_task_limit_bytes = 32 * 1024 * 1024;  // 16-64MB in practice.
diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc
index d3f14ae..889a758 100644
--- a/cc/resources/tile_manager_unittest.cc
+++ b/cc/resources/tile_manager_unittest.cc
@@ -39,7 +39,8 @@
 
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+        output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+        false);
     resource_pool_ = ResourcePool::Create(
         resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
     tile_manager_ = make_scoped_ptr(new FakeTileManager(
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index 75a2adb..f971ae8 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -73,6 +73,7 @@
 
     // Unacceptable inputs. ¯\(°_o)/¯
     case media::VideoFrame::UNKNOWN:
+    case media::VideoFrame::NV12:
       break;
   }
   return false;
diff --git a/cc/resources/video_resource_updater_unittest.cc b/cc/resources/video_resource_updater_unittest.cc
index ed53eb9..05bcf22 100644
--- a/cc/resources/video_resource_updater_unittest.cc
+++ b/cc/resources/video_resource_updater_unittest.cc
@@ -28,7 +28,8 @@
     CHECK(output_surface3d_->BindToClient(&client_));
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     resource_provider3d_ = ResourceProvider::Create(
-        output_surface3d_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+        output_surface3d_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+        false);
   }
 
   scoped_refptr<media::VideoFrame> CreateTestYUVVideoFrame() {
diff --git a/cc/scheduler/delay_based_time_source.cc b/cc/scheduler/delay_based_time_source.cc
index 00515b7..c40e4e6 100644
--- a/cc/scheduler/delay_based_time_source.cc
+++ b/cc/scheduler/delay_based_time_source.cc
@@ -43,8 +43,10 @@
 }
 
 DelayBasedTimeSourceHighRes::DelayBasedTimeSourceHighRes(
-    base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner)
-    : DelayBasedTimeSource(interval, task_runner) {}
+    base::TimeDelta interval,
+    base::SingleThreadTaskRunner* task_runner)
+    : DelayBasedTimeSource(interval, task_runner) {
+}
 
 DelayBasedTimeSourceHighRes::~DelayBasedTimeSourceHighRes() {}
 
@@ -61,14 +63,17 @@
 }
 
 DelayBasedTimeSource::DelayBasedTimeSource(
-    base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner)
+    base::TimeDelta interval,
+    base::SingleThreadTaskRunner* task_runner)
     : client_(NULL),
       last_tick_time_(base::TimeTicks() - interval),
       current_parameters_(interval, base::TimeTicks()),
       next_parameters_(interval, base::TimeTicks()),
       active_(false),
       task_runner_(task_runner),
-      weak_factory_(this) {}
+      weak_factory_(this) {
+  DCHECK_GT(interval.ToInternalValue(), 0);
+}
 
 DelayBasedTimeSource::~DelayBasedTimeSource() {}
 
@@ -124,6 +129,7 @@
 
 void DelayBasedTimeSource::SetTimebaseAndInterval(base::TimeTicks timebase,
                                                   base::TimeDelta interval) {
+  DCHECK_GT(interval.ToInternalValue(), 0);
   next_parameters_.interval = interval;
   next_parameters_.tick_target = timebase;
 
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index 93815cb..88c8c74 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -394,7 +394,7 @@
 // If the scheduler is busy, we queue the BeginFrame to be handled later as
 // a BeginRetroFrame.
 void Scheduler::BeginFrame(const BeginFrameArgs& args) {
-  TRACE_EVENT0("cc", "Scheduler::BeginFrame");
+  TRACE_EVENT1("cc", "Scheduler::BeginFrame", "frame_time", args.frame_time);
   DCHECK(settings_.throttle_frame_production);
 
   bool should_defer_begin_frame;
@@ -443,13 +443,18 @@
   while (!begin_retro_frame_args_.empty() &&
          now > AdjustedBeginImplFrameDeadline(begin_retro_frame_args_.front(),
                                               draw_duration_estimate)) {
+    TRACE_EVENT1("cc",
+                 "Scheduler::BeginRetroFrame discarding",
+                 "frame_time",
+                 begin_retro_frame_args_.front().frame_time);
     begin_retro_frame_args_.pop_front();
   }
 
   if (begin_retro_frame_args_.empty()) {
     DCHECK(settings_.throttle_frame_production);
-    TRACE_EVENT_INSTANT0(
-        "cc", "Scheduler::BeginRetroFrames expired", TRACE_EVENT_SCOPE_THREAD);
+    TRACE_EVENT_INSTANT0("cc",
+                         "Scheduler::BeginRetroFrames all expired",
+                         TRACE_EVENT_SCOPE_THREAD);
   } else {
     BeginImplFrame(begin_retro_frame_args_.front());
     begin_retro_frame_args_.pop_front();
@@ -483,7 +488,8 @@
 // for a BeginMainFrame+activation to complete before it times out and draws
 // any asynchronous animation and scroll/pinch updates.
 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
-  TRACE_EVENT0("cc", "Scheduler::BeginImplFrame");
+  TRACE_EVENT1(
+      "cc", "Scheduler::BeginImplFrame", "frame_time", args.frame_time);
   DCHECK(state_machine_.begin_impl_frame_state() ==
          SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
   DCHECK(state_machine_.HasInitializedOutputSurface());
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
index 0ddaa30..3ed18f6 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -42,7 +42,6 @@
       has_pending_tree_(false),
       pending_tree_is_ready_for_activation_(false),
       active_tree_needs_first_draw_(false),
-      draw_if_possible_failed_(false),
       did_create_and_initialize_first_output_surface_(false),
       smoothness_takes_priority_(false),
       skip_next_begin_main_frame_to_reduce_latency_(false),
@@ -251,7 +250,6 @@
                           pending_tree_is_ready_for_activation_);
   minor_state->SetBoolean("active_tree_needs_first_draw",
                           active_tree_needs_first_draw_);
-  minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_);
   minor_state->SetBoolean("did_create_and_initialize_first_output_surface",
                           did_create_and_initialize_first_output_surface_);
   minor_state->SetBoolean("smoothness_takes_priority",
@@ -727,9 +725,6 @@
   // This post-commit work is common to both completed and aborted commits.
   pending_tree_is_ready_for_activation_ = false;
 
-  if (draw_if_possible_failed_)
-    last_frame_number_swap_performed_ = -1;
-
   if (continuous_painting_)
     needs_commit_ = true;
 }
@@ -789,11 +784,12 @@
     forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
   }
 
-  if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW)
+  if (!has_pending_tree_ &&
+      commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) {
     commit_state_ = COMMIT_STATE_IDLE;
+  }
 
   needs_redraw_ = false;
-  draw_if_possible_failed_ = false;
   active_tree_needs_first_draw_ = false;
 
   if (did_request_swap)
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h
index e7d05e6..ff032b6 100644
--- a/cc/scheduler/scheduler_state_machine.h
+++ b/cc/scheduler/scheduler_state_machine.h
@@ -270,7 +270,6 @@
 
   void AdvanceCurrentFrameNumber();
   bool HasSentBeginMainFrameThisFrame() const;
-  bool HasScheduledManageTilesThisFrame() const;
   bool HasUpdatedVisibleTilesThisFrame() const;
   bool HasSwappedThisFrame() const;
 
@@ -316,7 +315,6 @@
   bool has_pending_tree_;
   bool pending_tree_is_ready_for_activation_;
   bool active_tree_needs_first_draw_;
-  bool draw_if_possible_failed_;
   bool did_create_and_initialize_first_output_surface_;
   bool smoothness_takes_priority_;
   bool skip_next_begin_main_frame_to_reduce_latency_;
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
index 3dfe934..067f019 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -226,18 +226,32 @@
   state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
 
+  // Make sure that a draw of the active tree doesn't spuriously advance
+  // the commit state and unblock the next commit.
+  state.SetNeedsRedraw(true);
+  state.OnBeginImplFrameDeadline();
+  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
+  EXPECT_ACTION_UPDATE_STATE(
+      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
+  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+  EXPECT_EQ(state.CommitState(),
+            SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
+  EXPECT_TRUE(state.has_pending_tree());
+
   // Verify NotifyReadyToActivate unblocks activation, draw, and
   // commit in that order.
+  state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+
   state.NotifyReadyToActivate();
   EXPECT_ACTION_UPDATE_STATE(
       SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
+  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
   EXPECT_EQ(state.CommitState(),
             SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
 
   EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
   state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
   EXPECT_ACTION_UPDATE_STATE(
       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
   EXPECT_EQ(state.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE);
diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc
index 5b108bb..6b2178d 100644
--- a/cc/surfaces/surface_aggregator.cc
+++ b/cc/surfaces/surface_aggregator.cc
@@ -131,10 +131,12 @@
 }
 
 void SurfaceAggregator::CopySharedQuadState(
-    const SharedQuadState& source_sqs,
+    const SharedQuadState* source_sqs,
     const gfx::Transform& content_to_target_transform,
-    SharedQuadStateList* dest_sqs_list) {
-  scoped_ptr<SharedQuadState> copy_shared_quad_state = source_sqs.Copy();
+    RenderPass* dest_render_pass) {
+  SharedQuadState* copy_shared_quad_state =
+      dest_render_pass->CreateAndAppendSharedQuadState();
+  copy_shared_quad_state->CopyFrom(source_sqs);
   // content_to_target_transform contains any transformation that may exist
   // between the context that these quads are being copied from (i.e. the
   // surface's draw transform when aggregated from within a surface) to the
@@ -143,7 +145,6 @@
   // transform is not identity.
   copy_shared_quad_state->content_to_target_transform.ConcatTransform(
       content_to_target_transform);
-  dest_sqs_list->push_back(copy_shared_quad_state.Pass());
 }
 
 void SurfaceAggregator::CopyQuadsToPass(
@@ -167,9 +168,8 @@
       HandleSurfaceQuad(surface_quad, dest_pass);
     } else {
       if (quad->shared_quad_state != last_copied_source_shared_quad_state) {
-        CopySharedQuadState(*quad->shared_quad_state,
-                            content_to_target_transform,
-                            &dest_pass->shared_quad_state_list);
+        CopySharedQuadState(
+            quad->shared_quad_state, content_to_target_transform, dest_pass);
         last_copied_source_shared_quad_state = quad->shared_quad_state;
       }
       if (quad->material == DrawQuad::RENDER_PASS) {
diff --git a/cc/surfaces/surface_aggregator.h b/cc/surfaces/surface_aggregator.h
index 9ee3d11..4115bc3 100644
--- a/cc/surfaces/surface_aggregator.h
+++ b/cc/surfaces/surface_aggregator.h
@@ -33,9 +33,9 @@
 
   void HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
                          RenderPass* dest_pass);
-  void CopySharedQuadState(const SharedQuadState& source_sqs,
+  void CopySharedQuadState(const SharedQuadState* source_sqs,
                            const gfx::Transform& content_to_target_transform,
-                           SharedQuadStateList* dest_sqs_list);
+                           RenderPass* dest_render_pass);
   void CopyQuadsToPass(const QuadList& source_quad_list,
                        const SharedQuadStateList& source_shared_quad_state_list,
                        const gfx::Transform& content_to_target_transform,
diff --git a/cc/surfaces/surface_aggregator_test_helpers.cc b/cc/surfaces/surface_aggregator_test_helpers.cc
index 2ac3289..6706c50 100644
--- a/cc/surfaces/surface_aggregator_test_helpers.cc
+++ b/cc/surfaces/surface_aggregator_test_helpers.cc
@@ -34,7 +34,7 @@
   float opacity = 1.0;
   SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
 
-  scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
+  SharedQuadState* shared_quad_state = pass->CreateAndAppendSharedQuadState();
   shared_quad_state->SetAll(content_to_target_transform,
                             content_bounds,
                             visible_content_rect,
@@ -42,7 +42,6 @@
                             is_clipped,
                             opacity,
                             blend_mode);
-  pass->shared_quad_state_list.push_back(shared_quad_state.Pass());
 
   scoped_ptr<SurfaceDrawQuad> surface_quad = SurfaceDrawQuad::Create();
   gfx::Rect quad_rect = gfx::Rect(surface_size);
@@ -54,10 +53,9 @@
 }
 void AddTestRenderPassQuad(TestRenderPass* pass,
                            RenderPass::Id render_pass_id) {
-  MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
+  MockQuadCuller quad_sink(pass);
   gfx::Rect output_rect = gfx::Rect(0, 0, 5, 5);
-  SharedQuadState* shared_state =
-      quad_sink.UseSharedQuadState(SharedQuadState::Create());
+  SharedQuadState* shared_state = quad_sink.CreateSharedQuadState();
   shared_state->SetAll(gfx::Transform(),
                        output_rect.size(),
                        output_rect,
diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc
index 3f2fbd8..1809409 100644
--- a/cc/surfaces/surface_aggregator_unittest.cc
+++ b/cc/surfaces/surface_aggregator_unittest.cc
@@ -418,7 +418,7 @@
   float opacity = 1.f;
 
   bool force_anti_aliasing_off = false;
-  scoped_ptr<SharedQuadState> sqs = SharedQuadState::Create();
+  SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
   sqs->SetAll(content_to_target_transform,
               content_bounds,
               visible_content_rect,
@@ -426,7 +426,6 @@
               is_clipped,
               opacity,
               blend_mode);
-  pass->shared_quad_state_list.push_back(sqs.Pass());
 
   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
   color_quad->SetNew(pass->shared_quad_state_list.back(),
diff --git a/cc/surfaces/surfaces_pixeltest.cc b/cc/surfaces/surfaces_pixeltest.cc
index abcc532..3559d53 100644
--- a/cc/surfaces/surfaces_pixeltest.cc
+++ b/cc/surfaces/surfaces_pixeltest.cc
@@ -23,7 +23,8 @@
   SurfaceManager manager_;
 };
 
-scoped_ptr<SharedQuadState> CreateTestSharedQuadState(
+SharedQuadState* CreateAndAppendTestSharedQuadState(
+    RenderPass* render_pass,
     const gfx::Transform& transform,
     const gfx::Size& size) {
   const gfx::Size content_bounds = size;
@@ -32,7 +33,7 @@
   bool is_clipped = false;
   float opacity = 1.f;
   const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
-  scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
+  SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
   shared_state->SetAll(transform,
                        content_bounds,
                        visible_content_rect,
@@ -40,7 +41,7 @@
                        is_clipped,
                        opacity,
                        blend_mode);
-  return shared_state.Pass();
+  return shared_state;
 }
 
 // Draws a very simple frame with no surface references.
@@ -50,8 +51,8 @@
   scoped_ptr<RenderPass> pass = RenderPass::Create();
   pass->SetNew(id, rect, rect, gfx::Transform());
 
-  pass->shared_quad_state_list.push_back(
-      CreateTestSharedQuadState(gfx::Transform(), device_viewport_size_));
+  CreateAndAppendTestSharedQuadState(
+      pass.get(), gfx::Transform(), device_viewport_size_);
 
   scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
   bool force_anti_aliasing_off = false;
@@ -96,8 +97,8 @@
     scoped_ptr<RenderPass> pass = RenderPass::Create();
     pass->SetNew(id, rect, rect, gfx::Transform());
 
-    pass->shared_quad_state_list.push_back(
-        CreateTestSharedQuadState(gfx::Transform(), device_viewport_size_));
+    CreateAndAppendTestSharedQuadState(
+        pass.get(), gfx::Transform(), device_viewport_size_);
 
     scoped_ptr<SurfaceDrawQuad> surface_quad = SurfaceDrawQuad::Create();
     surface_quad->SetNew(pass->shared_quad_state_list.back(),
@@ -130,8 +131,8 @@
     scoped_ptr<RenderPass> pass = RenderPass::Create();
     pass->SetNew(id, rect, rect, gfx::Transform());
 
-    pass->shared_quad_state_list.push_back(
-        CreateTestSharedQuadState(gfx::Transform(), child_size));
+    CreateAndAppendTestSharedQuadState(
+        pass.get(), gfx::Transform(), child_size);
 
     scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
     bool force_anti_aliasing_off = false;
@@ -186,8 +187,8 @@
     pass->SetNew(id, rect, rect, gfx::Transform());
 
     gfx::Transform surface_transform;
-    pass->shared_quad_state_list.push_back(
-        CreateTestSharedQuadState(surface_transform, device_viewport_size_));
+    CreateAndAppendTestSharedQuadState(
+        pass.get(), surface_transform, device_viewport_size_);
 
     scoped_ptr<SurfaceDrawQuad> left_surface_quad = SurfaceDrawQuad::Create();
     left_surface_quad->SetNew(pass->shared_quad_state_list.back(),
@@ -197,8 +198,8 @@
     pass->quad_list.push_back(left_surface_quad.PassAs<DrawQuad>());
 
     surface_transform.Translate(100, 0);
-    pass->shared_quad_state_list.push_back(
-        CreateTestSharedQuadState(surface_transform, device_viewport_size_));
+    CreateAndAppendTestSharedQuadState(
+        pass.get(), surface_transform, device_viewport_size_);
 
     scoped_ptr<SurfaceDrawQuad> right_surface_quad = SurfaceDrawQuad::Create();
     right_surface_quad->SetNew(pass->shared_quad_state_list.back(),
@@ -222,8 +223,8 @@
     scoped_ptr<RenderPass> pass = RenderPass::Create();
     pass->SetNew(id, rect, rect, gfx::Transform());
 
-    pass->shared_quad_state_list.push_back(
-        CreateTestSharedQuadState(gfx::Transform(), child_size));
+    CreateAndAppendTestSharedQuadState(
+        pass.get(), gfx::Transform(), child_size);
 
     scoped_ptr<SolidColorDrawQuad> top_color_quad =
         SolidColorDrawQuad::Create();
@@ -259,8 +260,8 @@
     scoped_ptr<RenderPass> pass = RenderPass::Create();
     pass->SetNew(id, rect, rect, gfx::Transform());
 
-    pass->shared_quad_state_list.push_back(
-        CreateTestSharedQuadState(gfx::Transform(), child_size));
+    CreateAndAppendTestSharedQuadState(
+        pass.get(), gfx::Transform(), child_size);
 
     scoped_ptr<SolidColorDrawQuad> top_color_quad =
         SolidColorDrawQuad::Create();
diff --git a/cc/test/data/dark_grey.png b/cc/test/data/dark_grey.png
new file mode 100644
index 0000000..dd22983
--- /dev/null
+++ b/cc/test/data/dark_grey.png
Binary files differ
diff --git a/cc/test/fake_content_layer_client.cc b/cc/test/fake_content_layer_client.cc
index 3996654..9f75d89 100644
--- a/cc/test/fake_content_layer_client.cc
+++ b/cc/test/fake_content_layer_client.cc
@@ -15,11 +15,13 @@
 FakeContentLayerClient::~FakeContentLayerClient() {
 }
 
-void FakeContentLayerClient::PaintContents(SkCanvas* canvas,
-    const gfx::Rect& paint_rect, gfx::RectF* opaque_rect) {
+void FakeContentLayerClient::PaintContents(
+    SkCanvas* canvas,
+    const gfx::Rect& paint_rect,
+    gfx::RectF* opaque_rect,
+    ContentLayerClient::GraphicsContextStatus gc_status) {
   last_canvas_ = canvas;
-  if (!canvas)
-    return;
+  last_context_status_ = gc_status;
 
   if (paint_all_opaque_)
     *opaque_rect = paint_rect;
diff --git a/cc/test/fake_content_layer_client.h b/cc/test/fake_content_layer_client.h
index 1a5221f..cc8ddb6 100644
--- a/cc/test/fake_content_layer_client.h
+++ b/cc/test/fake_content_layer_client.h
@@ -27,9 +27,11 @@
   FakeContentLayerClient();
   virtual ~FakeContentLayerClient();
 
-  virtual void PaintContents(SkCanvas* canvas,
-                             const gfx::Rect& rect,
-                             gfx::RectF* opaque_rect) OVERRIDE;
+  virtual void PaintContents(
+      SkCanvas* canvas,
+      const gfx::Rect& rect,
+      gfx::RectF* opaque_rect,
+      ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE;
   virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
   virtual bool FillsBoundsCompletely() const OVERRIDE;
 
@@ -51,6 +53,10 @@
 
   SkCanvas* last_canvas() const { return last_canvas_; }
 
+  ContentLayerClient::GraphicsContextStatus last_context_status() const {
+    return last_context_status_;
+  }
+
  private:
   typedef std::vector<std::pair<gfx::RectF, SkPaint> > RectPaintVector;
   typedef std::vector<BitmapData> BitmapVector;
@@ -59,6 +65,7 @@
   RectPaintVector draw_rects_;
   BitmapVector draw_bitmaps_;
   SkCanvas* last_canvas_;
+  ContentLayerClient::GraphicsContextStatus last_context_status_;
 };
 
 }  // namespace cc
diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h
index 3944bf7..2f33b7a 100644
--- a/cc/test/fake_layer_tree_host_impl_client.h
+++ b/cc/test/fake_layer_tree_host_impl_client.h
@@ -39,8 +39,9 @@
   virtual void SendManagedMemoryStats() OVERRIDE {}
   virtual bool IsInsideDraw() OVERRIDE;
   virtual void RenewTreePriority() OVERRIDE {}
-  virtual void RequestScrollbarAnimationOnImplThread(base::TimeDelta)
-      OVERRIDE {}
+  virtual void PostDelayedScrollbarFadeOnImplThread(
+      const base::Closure& start_fade,
+      base::TimeDelta delay) OVERRIDE {}
   virtual void DidActivatePendingTree() OVERRIDE {}
   virtual void DidManageTiles() OVERRIDE {}
 };
diff --git a/cc/test/fake_tile_manager_client.h b/cc/test/fake_tile_manager_client.h
index 5e76e27..dd368b9 100644
--- a/cc/test/fake_tile_manager_client.h
+++ b/cc/test/fake_tile_manager_client.h
@@ -9,8 +9,6 @@
 
 namespace cc {
 
-class Tile;
-
 class FakeTileManagerClient : public TileManagerClient {
  public:
   virtual ~FakeTileManagerClient() {}
diff --git a/cc/test/gpu_rasterization_settings.h b/cc/test/gpu_rasterization_settings.h
deleted file mode 100644
index 97c5710..0000000
--- a/cc/test/gpu_rasterization_settings.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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.
-
-#ifndef CC_TEST_GPU_RASTERIZATION_SETTINGS_H_
-#define CC_TEST_GPU_RASTERIZATION_SETTINGS_H_
-
-#include "cc/trees/layer_tree_settings.h"
-
-namespace cc {
-
-class GpuRasterizationSettings : public LayerTreeSettings {
- public:
-  GpuRasterizationSettings() {
-    impl_side_painting = true;
-    rasterization_site = GpuRasterization;
-  }
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_GPU_RASTERIZATION_SETTINGS_H_
diff --git a/cc/test/hybrid_rasterization_settings.h b/cc/test/hybrid_rasterization_settings.h
deleted file mode 100644
index f99bfd2..0000000
--- a/cc/test/hybrid_rasterization_settings.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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.
-
-#ifndef CC_TEST_HYBRID_RASTERIZATION_SETTINGS_H_
-#define CC_TEST_HYBRID_RASTERIZATION_SETTINGS_H_
-
-#include "cc/trees/layer_tree_settings.h"
-
-namespace cc {
-
-class HybridRasterizationSettings : public LayerTreeSettings {
- public:
-  HybridRasterizationSettings() {
-    impl_side_painting = true;
-    rasterization_site = HybridRasterization;
-  }
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_HYBRID_RASTERIZATION_SETTINGS_H_
diff --git a/cc/test/lap_timer.cc b/cc/test/lap_timer.cc
index 04cc3d9..f9738fb 100644
--- a/cc/test/lap_timer.cc
+++ b/cc/test/lap_timer.cc
@@ -8,6 +8,16 @@
 
 namespace cc {
 
+namespace {
+
+base::TimeTicks Now() {
+  return base::TimeTicks::IsThreadNowSupported()
+             ? base::TimeTicks::ThreadNow()
+             : base::TimeTicks::HighResNow();
+}
+
+}  // namespace
+
 LapTimer::LapTimer(int warmup_laps,
                    base::TimeDelta time_limit,
                    int check_interval)
@@ -28,7 +38,9 @@
   Start();
 }
 
-void LapTimer::Start() { start_time_ = base::TimeTicks::HighResNow(); }
+void LapTimer::Start() {
+  start_time_ = Now();
+}
 
 bool LapTimer::IsWarmedUp() { return remaining_warmups_ <= 0; }
 
@@ -43,7 +55,7 @@
   ++num_laps_;
   --remaining_no_check_laps_;
   if (!remaining_no_check_laps_) {
-    base::TimeTicks now = base::TimeTicks::HighResNow();
+    base::TimeTicks now = Now();
     accumulator_ += now - start_time_;
     start_time_ = now;
     remaining_no_check_laps_ = check_interval_;
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 23b5276..60e8035 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -666,6 +666,10 @@
 scoped_ptr<OutputSurface> LayerTreeTest::CreateOutputSurface(bool fallback) {
   scoped_ptr<FakeOutputSurface> output_surface =
       CreateFakeOutputSurface(fallback);
+  if (output_surface) {
+    DCHECK_EQ(delegating_renderer_,
+              output_surface->capabilities().delegated_rendering);
+  }
   output_surface_ = output_surface.get();
   return output_surface.PassAs<OutputSurface>();
 }
diff --git a/cc/test/mock_quad_culler.cc b/cc/test/mock_quad_culler.cc
index 773430f..ddb5913 100644
--- a/cc/test/mock_quad_culler.cc
+++ b/cc/test/mock_quad_culler.cc
@@ -9,23 +9,19 @@
 
 namespace cc {
 
-MockQuadCuller::MockQuadCuller()
-    : active_quad_list_(&quad_list_storage_),
-      active_shared_quad_state_list_(&shared_quad_state_storage_) {}
+MockQuadCuller::MockQuadCuller() {
+  render_pass_storage_ = RenderPass::Create();
+  active_render_pass_ = render_pass_storage_.get();
+}
 
-MockQuadCuller::MockQuadCuller(
-    QuadList* external_quad_list,
-    SharedQuadStateList* external_shared_quad_state_list)
-    : active_quad_list_(external_quad_list),
-      active_shared_quad_state_list_(external_shared_quad_state_list) {}
+MockQuadCuller::MockQuadCuller(RenderPass* external_render_pass)
+    : active_render_pass_(external_render_pass) {
+}
 
 MockQuadCuller::~MockQuadCuller() {}
 
-SharedQuadState* MockQuadCuller::UseSharedQuadState(
-    scoped_ptr<SharedQuadState> shared_quad_state) {
-  SharedQuadState* raw_ptr = shared_quad_state.get();
-  active_shared_quad_state_list_->push_back(shared_quad_state.Pass());
-  return raw_ptr;
+SharedQuadState* MockQuadCuller::CreateSharedQuadState() {
+  return active_render_pass_->CreateAndAppendSharedQuadState();
 }
 
 gfx::Rect MockQuadCuller::UnoccludedContentRect(
@@ -63,7 +59,7 @@
 void MockQuadCuller::Append(scoped_ptr<DrawQuad> draw_quad) {
   DCHECK(!draw_quad->rect.IsEmpty());
   DCHECK(!draw_quad->visible_rect.IsEmpty());
-  active_quad_list_->push_back(draw_quad.Pass());
+  active_render_pass_->quad_list.push_back(draw_quad.Pass());
 }
 
 }  // namespace cc
diff --git a/cc/test/mock_quad_culler.h b/cc/test/mock_quad_culler.h
index 6e3436a..195eb5b 100644
--- a/cc/test/mock_quad_culler.h
+++ b/cc/test/mock_quad_culler.h
@@ -17,12 +17,10 @@
   MockQuadCuller();
   virtual ~MockQuadCuller();
 
-  MockQuadCuller(QuadList* external_quad_list,
-                 SharedQuadStateList* external_shared_quad_state_list);
+  explicit MockQuadCuller(RenderPass* external_render_pass);
 
   // QuadSink interface.
-  virtual SharedQuadState* UseSharedQuadState(
-      scoped_ptr<SharedQuadState> shared_quad_state) OVERRIDE;
+  virtual SharedQuadState* CreateSharedQuadState() OVERRIDE;
   virtual gfx::Rect UnoccludedContentRect(const gfx::Rect& content_rect,
                                           const gfx::Transform& draw_transform)
       OVERRIDE;
@@ -31,9 +29,9 @@
       const gfx::Transform& draw_transform) OVERRIDE;
   virtual void Append(scoped_ptr<DrawQuad> draw_quad) OVERRIDE;
 
-  const QuadList& quad_list() const { return *active_quad_list_; }
+  const QuadList& quad_list() const { return active_render_pass_->quad_list; }
   const SharedQuadStateList& shared_quad_state_list() const {
-    return *active_shared_quad_state_list_;
+    return active_render_pass_->shared_quad_state_list;
   }
 
   void set_occluded_target_rect(const gfx::Rect& occluded) {
@@ -46,15 +44,13 @@
   }
 
   void clear_lists() {
-    active_quad_list_->clear();
-    active_shared_quad_state_list_->clear();
+    active_render_pass_->quad_list.clear();
+    active_render_pass_->shared_quad_state_list.clear();
   }
 
  private:
-  QuadList* active_quad_list_;
-  QuadList quad_list_storage_;
-  SharedQuadStateList* active_shared_quad_state_list_;
-  SharedQuadStateList shared_quad_state_storage_;
+  scoped_ptr<RenderPass> render_pass_storage_;
+  RenderPass* active_render_pass_;
   gfx::Rect occluded_target_rect_;
   gfx::Rect occluded_target_rect_for_contributing_surface_;
 };
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index f716eea..ae2e998 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -110,7 +110,7 @@
 
   shared_bitmap_manager_.reset(new TestSharedBitmapManager());
   resource_provider_ = ResourceProvider::Create(
-      output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+      output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, false);
 
   texture_mailbox_deleter_ = make_scoped_ptr(
       new TextureMailboxDeleter(base::MessageLoopProxy::current()));
@@ -152,7 +152,7 @@
   output_surface_->BindToClient(output_surface_client_.get());
   shared_bitmap_manager_.reset(new TestSharedBitmapManager());
   resource_provider_ = ResourceProvider::Create(
-      output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+      output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, false);
   renderer_ =
       SoftwareRenderer::Create(
           this, &settings_, output_surface_.get(), resource_provider_.get())
diff --git a/cc/test/render_pass_test_common.cc b/cc/test/render_pass_test_common.cc
index 56e2b07..dd58b43 100644
--- a/cc/test/render_pass_test_common.cc
+++ b/cc/test/render_pass_test_common.cc
@@ -23,10 +23,6 @@
   quad_list.push_back(quad.Pass());
 }
 
-void TestRenderPass::AppendSharedQuadState(scoped_ptr<SharedQuadState> state) {
-  shared_quad_state_list.push_back(state.Pass());
-}
-
 void TestRenderPass::AppendOneOfEveryQuadType(
     ResourceProvider* resource_provider,
     RenderPass::Id child_pass) {
@@ -77,7 +73,7 @@
       resource_provider->best_texture_format());
   resource_provider->AllocateForTesting(resource7);
 
-  scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
+  SharedQuadState* shared_state = this->CreateAndAppendSharedQuadState();
   shared_state->SetAll(gfx::Transform(),
                        rect.size(),
                        rect,
@@ -88,18 +84,16 @@
 
   scoped_ptr<CheckerboardDrawQuad> checkerboard_quad =
       CheckerboardDrawQuad::Create();
-  checkerboard_quad->SetNew(
-      shared_state.get(), rect, visible_rect, SK_ColorRED);
+  checkerboard_quad->SetNew(shared_state, rect, visible_rect, SK_ColorRED);
   AppendQuad(checkerboard_quad.PassAs<DrawQuad>());
 
   scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
       DebugBorderDrawQuad::Create();
-  debug_border_quad->SetNew(
-      shared_state.get(), rect, visible_rect, SK_ColorRED, 1);
+  debug_border_quad->SetNew(shared_state, rect, visible_rect, SK_ColorRED, 1);
   AppendQuad(debug_border_quad.PassAs<DrawQuad>());
 
   scoped_ptr<IOSurfaceDrawQuad> io_surface_quad = IOSurfaceDrawQuad::Create();
-  io_surface_quad->SetNew(shared_state.get(),
+  io_surface_quad->SetNew(shared_state,
                           rect,
                           opaque_rect,
                           visible_rect,
@@ -111,7 +105,7 @@
   if (child_pass.layer_id) {
     scoped_ptr<RenderPassDrawQuad> render_pass_quad =
         RenderPassDrawQuad::Create();
-    render_pass_quad->SetNew(shared_state.get(),
+    render_pass_quad->SetNew(shared_state,
                              rect,
                              visible_rect,
                              child_pass,
@@ -125,7 +119,7 @@
 
     scoped_ptr<RenderPassDrawQuad> render_pass_replica_quad =
         RenderPassDrawQuad::Create();
-    render_pass_replica_quad->SetNew(shared_state.get(),
+    render_pass_replica_quad->SetNew(shared_state,
                                      rect,
                                      visible_rect,
                                      child_pass,
@@ -141,12 +135,12 @@
   scoped_ptr<SolidColorDrawQuad> solid_color_quad =
       SolidColorDrawQuad::Create();
   solid_color_quad->SetNew(
-      shared_state.get(), rect, visible_rect, SK_ColorRED, false);
+      shared_state, rect, visible_rect, SK_ColorRED, false);
   AppendQuad(solid_color_quad.PassAs<DrawQuad>());
 
   scoped_ptr<StreamVideoDrawQuad> stream_video_quad =
       StreamVideoDrawQuad::Create();
-  stream_video_quad->SetNew(shared_state.get(),
+  stream_video_quad->SetNew(shared_state,
                             rect,
                             opaque_rect,
                             visible_rect,
@@ -155,7 +149,7 @@
   AppendQuad(stream_video_quad.PassAs<DrawQuad>());
 
   scoped_ptr<TextureDrawQuad> texture_quad = TextureDrawQuad::Create();
-  texture_quad->SetNew(shared_state.get(),
+  texture_quad->SetNew(shared_state,
                        rect,
                        opaque_rect,
                        visible_rect,
@@ -169,7 +163,7 @@
   AppendQuad(texture_quad.PassAs<DrawQuad>());
 
   scoped_ptr<TileDrawQuad> scaled_tile_quad = TileDrawQuad::Create();
-  scaled_tile_quad->SetNew(shared_state.get(),
+  scaled_tile_quad->SetNew(shared_state,
                            rect,
                            opaque_rect,
                            visible_rect,
@@ -179,13 +173,14 @@
                            false);
   AppendQuad(scaled_tile_quad.PassAs<DrawQuad>());
 
-  scoped_ptr<SharedQuadState> transformed_state = shared_state->Copy();
+  SharedQuadState* transformed_state = this->CreateAndAppendSharedQuadState();
+  transformed_state->CopyFrom(shared_state);
   gfx::Transform rotation;
   rotation.Rotate(45);
   transformed_state->content_to_target_transform =
       transformed_state->content_to_target_transform * rotation;
   scoped_ptr<TileDrawQuad> transformed_tile_quad = TileDrawQuad::Create();
-  transformed_tile_quad->SetNew(transformed_state.get(),
+  transformed_tile_quad->SetNew(transformed_state,
                                 rect,
                                 opaque_rect,
                                 visible_rect,
@@ -195,7 +190,7 @@
                                 false);
   AppendQuad(transformed_tile_quad.PassAs<DrawQuad>());
 
-  scoped_ptr<SharedQuadState> shared_state2 = SharedQuadState::Create();
+  SharedQuadState* shared_state2 = this->CreateAndAppendSharedQuadState();
   shared_state->SetAll(gfx::Transform(),
                        rect.size(),
                        rect,
@@ -205,7 +200,7 @@
                        SkXfermode::kSrcOver_Mode);
 
   scoped_ptr<TileDrawQuad> tile_quad = TileDrawQuad::Create();
-  tile_quad->SetNew(shared_state2.get(),
+  tile_quad->SetNew(shared_state2,
                     rect,
                     opaque_rect,
                     visible_rect,
@@ -225,8 +220,9 @@
             resource_provider->best_texture_format());
     resource_provider->AllocateForTesting(plane_resources[i]);
   }
+  YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601;
   scoped_ptr<YUVVideoDrawQuad> yuv_quad = YUVVideoDrawQuad::Create();
-  yuv_quad->SetNew(shared_state2.get(),
+  yuv_quad->SetNew(shared_state2,
                    rect,
                    opaque_rect,
                    visible_rect,
@@ -234,12 +230,9 @@
                    plane_resources[0],
                    plane_resources[1],
                    plane_resources[2],
-                   plane_resources[3]);
+                   plane_resources[3],
+                   color_space);
   AppendQuad(yuv_quad.PassAs<DrawQuad>());
-
-  AppendSharedQuadState(shared_state.Pass());
-  AppendSharedQuadState(transformed_state.Pass());
-  AppendSharedQuadState(shared_state2.Pass());
 }
 
 }  // namespace cc
diff --git a/cc/test/render_pass_test_common.h b/cc/test/render_pass_test_common.h
index 651278f..24467ed 100644
--- a/cc/test/render_pass_test_common.h
+++ b/cc/test/render_pass_test_common.h
@@ -20,7 +20,6 @@
   }
 
   void AppendQuad(scoped_ptr<DrawQuad> quad);
-  void AppendSharedQuadState(scoped_ptr<SharedQuadState> state);
 
   void AppendOneOfEveryQuadType(ResourceProvider* resource_provider,
                                 RenderPass::Id child_pass);
diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc
index 8d0d955..e70919a 100644
--- a/cc/test/render_pass_test_utils.cc
+++ b/cc/test/render_pass_test_utils.cc
@@ -31,9 +31,8 @@
 SolidColorDrawQuad* AddQuad(TestRenderPass* pass,
                             const gfx::Rect& rect,
                             SkColor color) {
-  MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
-  SharedQuadState* shared_state =
-      quad_sink.UseSharedQuadState(SharedQuadState::Create());
+  MockQuadCuller quad_sink(pass);
+  SharedQuadState* shared_state = quad_sink.CreateSharedQuadState();
   shared_state->SetAll(gfx::Transform(),
                        rect.size(),
                        rect,
@@ -51,9 +50,8 @@
 SolidColorDrawQuad* AddClippedQuad(TestRenderPass* pass,
                                    const gfx::Rect& rect,
                                    SkColor color) {
-  MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
-  SharedQuadState* shared_state =
-      quad_sink.UseSharedQuadState(SharedQuadState::Create());
+  MockQuadCuller quad_sink(pass);
+  SharedQuadState* shared_state = quad_sink.CreateSharedQuadState();
   shared_state->SetAll(gfx::Transform(),
                        rect.size(),
                        rect,
@@ -72,9 +70,8 @@
                                        const gfx::Rect& rect,
                                        SkColor color,
                                        const gfx::Transform& transform) {
-  MockQuadCuller quad_sink(&pass->quad_list, &pass->shared_quad_state_list);
-  SharedQuadState* shared_state =
-      quad_sink.UseSharedQuadState(SharedQuadState::Create());
+  MockQuadCuller quad_sink(pass);
+  SharedQuadState* shared_state = quad_sink.CreateSharedQuadState();
   shared_state->SetAll(
       transform, rect.size(), rect, rect, false, 1, SkXfermode::kSrcOver_Mode);
   scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create();
@@ -86,11 +83,9 @@
 
 void AddRenderPassQuad(TestRenderPass* to_pass,
                        TestRenderPass* contributing_pass) {
-  MockQuadCuller quad_sink(&to_pass->quad_list,
-                           &to_pass->shared_quad_state_list);
+  MockQuadCuller quad_sink(to_pass);
   gfx::Rect output_rect = contributing_pass->output_rect;
-  SharedQuadState* shared_state =
-      quad_sink.UseSharedQuadState(SharedQuadState::Create());
+  SharedQuadState* shared_state = quad_sink.CreateSharedQuadState();
   shared_state->SetAll(gfx::Transform(),
                        output_rect.size(),
                        output_rect,
@@ -117,11 +112,9 @@
                        ResourceProvider::ResourceId mask_resource_id,
                        const FilterOperations& filters,
                        gfx::Transform transform) {
-  MockQuadCuller quad_sink(&to_pass->quad_list,
-                           &to_pass->shared_quad_state_list);
+  MockQuadCuller quad_sink(to_pass);
   gfx::Rect output_rect = contributing_pass->output_rect;
-  SharedQuadState* shared_state =
-      quad_sink.UseSharedQuadState(SharedQuadState::Create());
+  SharedQuadState* shared_state = quad_sink.CreateSharedQuadState();
   shared_state->SetAll(transform,
                        output_rect.size(),
                        output_rect,
diff --git a/cc/test/skia_common.cc b/cc/test/skia_common.cc
index 7d1c3b8..d91e707 100644
--- a/cc/test/skia_common.cc
+++ b/cc/test/skia_common.cc
@@ -21,7 +21,9 @@
   bitmap.installPixels(info, buffer, info.minRowBytes());
   SkCanvas canvas(bitmap);
   canvas.clipRect(gfx::RectToSkRect(layer_rect));
-  picture->Raster(&canvas, NULL, layer_rect, 1.0f);
+  // We're drawing the entire canvas, so the negated content region is empty.
+  gfx::Rect negated_content_region;
+  picture->Raster(&canvas, NULL, negated_content_region, 1.0f);
 }
 
 void CreateBitmap(const gfx::Size& size, const char* uri, SkBitmap* bitmap) {
diff --git a/cc/test/solid_color_content_layer_client.cc b/cc/test/solid_color_content_layer_client.cc
index c61f855..8c9de1c 100644
--- a/cc/test/solid_color_content_layer_client.cc
+++ b/cc/test/solid_color_content_layer_client.cc
@@ -12,9 +12,10 @@
 namespace cc {
 
 void SolidColorContentLayerClient::PaintContents(
-    SkCanvas* canvas, const gfx::Rect& rect, gfx::RectF* opaque_rect) {
-  if (!canvas)
-    return;
+    SkCanvas* canvas,
+    const gfx::Rect& rect,
+    gfx::RectF* opaque_rect,
+    ContentLayerClient::GraphicsContextStatus gc_status) {
   SkPaint paint;
   paint.setStyle(SkPaint::kFill_Style);
   paint.setColor(color_);
diff --git a/cc/test/solid_color_content_layer_client.h b/cc/test/solid_color_content_layer_client.h
index d854004..7c0ce6f 100644
--- a/cc/test/solid_color_content_layer_client.h
+++ b/cc/test/solid_color_content_layer_client.h
@@ -17,9 +17,11 @@
 
   // ContentLayerClient implementation.
   virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
-  virtual void PaintContents(SkCanvas* canvas,
-                             const gfx::Rect& rect,
-                             gfx::RectF* opaque_rect) OVERRIDE;
+  virtual void PaintContents(
+      SkCanvas* canvas,
+      const gfx::Rect& rect,
+      gfx::RectF* opaque_rect,
+      ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE;
   virtual bool FillsBoundsCompletely() const OVERRIDE;
 
  private:
diff --git a/cc/test/test_gles2_interface.cc b/cc/test/test_gles2_interface.cc
index 732c8a2..26055ba 100644
--- a/cc/test/test_gles2_interface.cc
+++ b/cc/test/test_gles2_interface.cc
@@ -275,16 +275,18 @@
 
 GLuint TestGLES2Interface::CreateImageCHROMIUM(GLsizei width,
                                                GLsizei height,
-                                               GLenum internalformat) {
-  return test_context_->createImageCHROMIUM(width, height, internalformat);
+                                               GLenum internalformat,
+                                               GLenum usage) {
+  return test_context_->createImageCHROMIUM(
+      width, height, internalformat, usage);
 }
 
 void TestGLES2Interface::DestroyImageCHROMIUM(GLuint image_id) {
   test_context_->destroyImageCHROMIUM(image_id);
 }
 
-void* TestGLES2Interface::MapImageCHROMIUM(GLuint image_id, GLenum access) {
-  return test_context_->mapImageCHROMIUM(image_id, access);
+void* TestGLES2Interface::MapImageCHROMIUM(GLuint image_id) {
+  return test_context_->mapImageCHROMIUM(image_id);
 }
 
 void TestGLES2Interface::GetImageParameterivCHROMIUM(GLuint image_id,
diff --git a/cc/test/test_gles2_interface.h b/cc/test/test_gles2_interface.h
index a52d73e..417bf4a 100644
--- a/cc/test/test_gles2_interface.h
+++ b/cc/test/test_gles2_interface.h
@@ -126,9 +126,10 @@
   virtual void WaitAsyncTexImage2DCHROMIUM(GLenum target) OVERRIDE;
   virtual GLuint CreateImageCHROMIUM(GLsizei width,
                                      GLsizei height,
-                                     GLenum internalformat) OVERRIDE;
+                                     GLenum internalformat,
+                                     GLenum usage) OVERRIDE;
   virtual void DestroyImageCHROMIUM(GLuint image_id) OVERRIDE;
-  virtual void* MapImageCHROMIUM(GLuint image_id, GLenum access) OVERRIDE;
+  virtual void* MapImageCHROMIUM(GLuint image_id) OVERRIDE;
   virtual void GetImageParameterivCHROMIUM(GLuint image_id,
                                            GLenum pname,
                                            GLint* params) OVERRIDE;
diff --git a/cc/test/test_web_graphics_context_3d.cc b/cc/test/test_web_graphics_context_3d.cc
index 59b7440..7d03c38 100644
--- a/cc/test/test_web_graphics_context_3d.cc
+++ b/cc/test/test_web_graphics_context_3d.cc
@@ -539,9 +539,10 @@
   return true;
 }
 
-GLuint TestWebGraphicsContext3D::createImageCHROMIUM(
-      GLsizei width, GLsizei height,
-      GLenum internalformat) {
+GLuint TestWebGraphicsContext3D::createImageCHROMIUM(GLsizei width,
+                                                     GLsizei height,
+                                                     GLenum internalformat,
+                                                     GLenum usage) {
   DCHECK_EQ(GL_RGBA8_OES, static_cast<int>(internalformat));
   GLuint image_id = NextImageId();
   base::AutoLock lock(namespace_->lock);
@@ -566,8 +567,7 @@
   *params = 0;
 }
 
-void* TestWebGraphicsContext3D::mapImageCHROMIUM(GLuint image_id,
-                                                 GLenum access) {
+void* TestWebGraphicsContext3D::mapImageCHROMIUM(GLuint image_id) {
   base::AutoLock lock(namespace_->lock);
   base::ScopedPtrHashMap<unsigned, Image>& images = namespace_->images;
   DCHECK_GT(images.count(image_id), 0u);
diff --git a/cc/test/test_web_graphics_context_3d.h b/cc/test/test_web_graphics_context_3d.h
index 56ffc85..ae32a27 100644
--- a/cc/test/test_web_graphics_context_3d.h
+++ b/cc/test/test_web_graphics_context_3d.h
@@ -234,12 +234,13 @@
 
   virtual GLuint createImageCHROMIUM(GLsizei width,
                                      GLsizei height,
-                                     GLenum internalformat);
+                                     GLenum internalformat,
+                                     GLenum usage);
   virtual void destroyImageCHROMIUM(GLuint image_id);
   virtual void getImageParameterivCHROMIUM(GLuint image_id,
                                            GLenum pname,
                                            GLint* params);
-  virtual void* mapImageCHROMIUM(GLuint image_id, GLenum access);
+  virtual void* mapImageCHROMIUM(GLuint image_id);
   virtual void unmapImageCHROMIUM(GLuint image_id);
   virtual void texImageIOSurface2DCHROMIUM(GLenum target,
                                            GLsizei width,
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 65d5dd6..7df3186 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -109,6 +109,7 @@
       max_page_scale_factor_(1.f),
       trigger_idle_updates_(true),
       has_gpu_rasterization_trigger_(false),
+      content_is_suitable_for_gpu_rasterization_(true),
       background_color_(SK_ColorWHITE),
       has_transparent_background_(false),
       partial_texture_update_requests_(0),
@@ -589,6 +590,10 @@
   if (hud_layer_.get())
     hud_layer_->RemoveFromParent();
 
+  // Reset gpu rasterization flag.
+  // This flag is sticky until a new tree comes along.
+  content_is_suitable_for_gpu_rasterization_ = true;
+
   SetNeedsFullTreeSync();
 }
 
@@ -608,6 +613,17 @@
   proxy_->SetDebugState(debug_state);
 }
 
+bool LayerTreeHost::UseGpuRasterization() const {
+  if (settings_.gpu_rasterization_forced) {
+    return true;
+  } else if (settings_.gpu_rasterization_enabled) {
+    return has_gpu_rasterization_trigger_ &&
+           content_is_suitable_for_gpu_rasterization_;
+  } else {
+    return false;
+  }
+}
+
 void LayerTreeHost::SetViewportSize(const gfx::Size& device_viewport_size) {
   if (device_viewport_size == device_viewport_size_)
     return;
@@ -982,6 +998,15 @@
       DCHECK(!it->paint_properties().bounds.IsEmpty());
       *did_paint_content |= it->Update(queue, &occlusion_tracker);
       *need_more_updates |= it->NeedMoreUpdates();
+      // Note the '&&' with previous is-suitable state.
+      // This means that once the layer-tree becomes unsuitable for gpu
+      // rasterization due to some content, it will continue to be unsuitable
+      // even if that content is replaced by gpu-friendly content.
+      // This is to avoid switching back-and-forth between gpu and sw
+      // rasterization which may be both bad for performance and visually
+      // jarring.
+      content_is_suitable_for_gpu_rasterization_ &=
+          it->IsSuitableForGpuRasterization();
     }
 
     occlusion_tracker.LeaveLayer(it);
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index b58ce39..380cc95 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -197,6 +197,7 @@
   void set_has_gpu_rasterization_trigger(bool has_trigger) {
     has_gpu_rasterization_trigger_ = has_trigger;
   }
+  bool UseGpuRasterization() const;
 
   void SetViewportSize(const gfx::Size& device_viewport_size);
   void SetOverdrawBottomHeight(float overdraw_bottom_height);
@@ -399,6 +400,7 @@
   gfx::Transform impl_transform_;
   bool trigger_idle_updates_;
   bool has_gpu_rasterization_trigger_;
+  bool content_is_suitable_for_gpu_rasterization_;
 
   SkColor background_color_;
   bool has_transparent_background_;
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 655b405..ba92d8d 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -1174,6 +1174,9 @@
   bool has_delegated_content = layer->HasDelegatedContent();
   int num_descendants_that_draw_content = 0;
 
+  layer->draw_properties().sorted_for_recursion = false;
+  layer->draw_properties().has_child_with_a_scroll_parent = false;
+
   if (!HasInvertibleOrAnimatedTransform(layer)) {
     // Layers with singular transforms should not be drawn, the whole subtree
     // can be skipped.
@@ -1188,9 +1191,6 @@
     num_descendants_that_draw_content = 1000;
   }
 
-  layer->draw_properties().sorted_for_recursion = false;
-  layer->draw_properties().has_child_with_a_scroll_parent = false;
-
   if (layer->clip_parent())
     recursive_data->num_unclipped_descendants++;
 
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index ad4f60b..a1210c4 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -229,9 +229,11 @@
  public:
   MockContentLayerClient() {}
   virtual ~MockContentLayerClient() {}
-  virtual void PaintContents(SkCanvas* canvas,
-                             const gfx::Rect& clip,
-                             gfx::RectF* opaque) OVERRIDE {}
+  virtual void PaintContents(
+      SkCanvas* canvas,
+      const gfx::Rect& clip,
+      gfx::RectF* opaque,
+      ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {}
   virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
   virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
 };
@@ -3025,6 +3027,34 @@
 }
 
 TEST_F(LayerTreeHostCommonTest,
+       SingularNonAnimatingTransformDoesNotPreventClearingDrawProperties) {
+  scoped_refptr<Layer> root = Layer::Create();
+
+  scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
+  host->SetRootLayer(root);
+
+  gfx::Transform identity_matrix;
+  gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+  ASSERT_FALSE(uninvertible_matrix.IsInvertible());
+
+  SetLayerPropertiesForTesting(root.get(),
+                               uninvertible_matrix,
+                               gfx::PointF(),
+                               gfx::PointF(),
+                               gfx::Size(100, 100),
+                               true,
+                               false);
+
+  root->draw_properties().sorted_for_recursion = true;
+
+  EXPECT_FALSE(root->TransformIsAnimating());
+
+  ExecuteCalculateDrawProperties(root.get());
+
+  EXPECT_FALSE(root->draw_properties().sorted_for_recursion);
+}
+
+TEST_F(LayerTreeHostCommonTest,
        DrawableAndVisibleContentRectsForLayersInClippedRenderSurface) {
   scoped_refptr<Layer> root = Layer::Create();
   scoped_refptr<Layer> render_surface1 = Layer::Create();
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 55cb2fb..9797c97 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -255,6 +255,7 @@
       overhang_ui_resource_id_(0),
       overdraw_bottom_height_(0.f),
       device_viewport_valid_for_tile_management_(true),
+      begin_impl_frame_interval_(BeginFrameArgs::DefaultInterval()),
       animation_registrar_(AnimationRegistrar::Create()),
       rendering_stats_instrumentation_(rendering_stats_instrumentation),
       micro_benchmark_controller_(this),
@@ -478,6 +479,27 @@
   client_->RenewTreePriority();
 }
 
+bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt(
+    const gfx::Point& viewport_point,
+    InputHandler::ScrollInputType type) {
+  if (!CurrentlyScrollingLayer())
+    return false;
+
+  if (!EnsureRenderSurfaceLayerList())
+    return false;
+
+  gfx::PointF device_viewport_point =
+      gfx::ScalePoint(viewport_point, device_scale_factor_);
+
+  LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
+      device_viewport_point, active_tree_->RenderSurfaceLayerList());
+
+  bool scroll_on_main_thread = false;
+  LayerImpl* scrolling_layer_impl = FindScrollLayerForDeviceViewportPoint(
+      device_viewport_point, type, layer_impl, &scroll_on_main_thread, NULL);
+  return CurrentlyScrollingLayer() == scrolling_layer_impl;
+}
+
 bool LayerTreeHostImpl::HaveTouchEventHandlersAt(
     const gfx::Point& viewport_point) {
   if (!settings_.touch_hit_testing)
@@ -568,10 +590,7 @@
     LayerImpl* layer,
     const OcclusionTracker<LayerImpl>& occlusion_tracker,
     AppendQuadsData* append_quads_data) {
-  QuadCuller quad_culler(&target_render_pass->quad_list,
-                         &target_render_pass->shared_quad_state_list,
-                         layer,
-                         occlusion_tracker);
+  QuadCuller quad_culler(target_render_pass, layer, occlusion_tracker);
   layer->AppendQuads(&quad_culler, append_quads_data);
 }
 
@@ -581,10 +600,7 @@
     const RenderPass* contributing_render_pass,
     const OcclusionTracker<LayerImpl>& occlusion_tracker,
     AppendQuadsData* append_quads_data) {
-  QuadCuller quad_culler(&target_render_pass->quad_list,
-                         &target_render_pass->shared_quad_state_list,
-                         layer,
-                         occlusion_tracker);
+  QuadCuller quad_culler(target_render_pass, layer, occlusion_tracker);
 
   bool is_replica = false;
   layer->render_surface()->AppendQuads(&quad_culler,
@@ -627,10 +643,7 @@
     screen_background_color_region.Intersect(root_scroll_layer_rect);
   }
 
-  QuadCuller quad_culler(&target_render_pass->quad_list,
-                         &target_render_pass->shared_quad_state_list,
-                         root_layer,
-                         occlusion_tracker);
+  QuadCuller quad_culler(target_render_pass, root_layer, occlusion_tracker);
 
   // Manually create the quad state for the gutter quads, as the root layer
   // doesn't have any bounds and so can't generate this itself.
@@ -639,8 +652,7 @@
 
   gfx::Rect root_target_rect = root_layer->render_surface()->content_rect();
   float opacity = 1.f;
-  SharedQuadState* shared_quad_state =
-      quad_culler.UseSharedQuadState(SharedQuadState::Create());
+  SharedQuadState* shared_quad_state = quad_culler.CreateSharedQuadState();
   shared_quad_state->SetAll(gfx::Transform(),
                             root_target_rect.size(),
                             root_target_rect,
@@ -1544,6 +1556,8 @@
   // Sample the frame time now. This time will be used for updating animations
   // when we draw.
   UpdateCurrentFrameTime();
+  // Cache the begin impl frame interval
+  begin_impl_frame_interval_ = args.interval;
 }
 
 gfx::SizeF LayerTreeHostImpl::ComputeInnerViewportContainerSize() const {
@@ -1764,14 +1778,15 @@
 
 ManagedMemoryPolicy LayerTreeHostImpl::ActualManagedMemoryPolicy() const {
   ManagedMemoryPolicy actual = cached_managed_memory_policy_;
-  // TODO(ernstm): The second condition disables pre-painting for all layers
-  // when GPU rasterization is enabled. Once we selectively enable GPU
-  // rasterization per layer, we also need to disable pre-painting selectively:
-  // crbug.com/335387
-  if (debug_state_.rasterize_only_visible_content ||
-      settings_.rasterization_site == LayerTreeSettings::GpuRasterization) {
+  // TODO(ernstm): NICE_TO_HAVE is currently triggered for forced GPU
+  // rasterization only. Change the trigger to LTHI::UseGpuRasterization, once
+  // that is implemented.
+  if (debug_state_.rasterize_only_visible_content) {
     actual.priority_cutoff_when_visible =
         gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY;
+  } else if (settings_.gpu_rasterization_forced) {
+    actual.priority_cutoff_when_visible =
+        gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
   }
 
   if (zero_budget_) {
@@ -1931,7 +1946,8 @@
                                shared_bitmap_manager_,
                                settings_.highp_threshold_min,
                                settings_.use_rgba_4444_textures,
-                               settings_.texture_id_allocation_chunk_size);
+                               settings_.texture_id_allocation_chunk_size,
+                               settings_.use_distance_field_text);
 
   if (output_surface->capabilities().deferred_gl_initialization)
     EnforceZeroBudget(true);
@@ -2134,7 +2150,7 @@
     InputHandler::ScrollInputType type,
     LayerImpl* layer_impl,
     bool* scroll_on_main_thread,
-    bool* has_ancestor_scroll_handler) const {
+    bool* optional_has_ancestor_scroll_handler) const {
   DCHECK(scroll_on_main_thread);
 
   // Walk up the hierarchy and look for a scrollable layer.
@@ -2159,18 +2175,26 @@
       return NULL;
     }
 
-    if (has_ancestor_scroll_handler &&
+    if (optional_has_ancestor_scroll_handler &&
         scroll_layer_impl->have_scroll_event_handlers())
-      *has_ancestor_scroll_handler = true;
+      *optional_has_ancestor_scroll_handler = true;
 
     if (status == ScrollStarted && !potentially_scrolling_layer_impl)
       potentially_scrolling_layer_impl = scroll_layer_impl;
   }
 
+  // Falling back to the root scroll layer ensures generation of root overscroll
+  // notifications while preventing scroll updates from being unintentionally
+  // forwarded to the main thread.
+  if (!potentially_scrolling_layer_impl)
+    potentially_scrolling_layer_impl = OuterViewportScrollLayer()
+                                           ? OuterViewportScrollLayer()
+                                           : InnerViewportScrollLayer();
+
   return potentially_scrolling_layer_impl;
 }
 
-// Similar to LayerImpl::HasAncestor, but takes into account scroll parents.
+// Similar to LayerImpl::HasAncestor, but walks up the scroll parents.
 static bool HasScrollAncestor(LayerImpl* child, LayerImpl* scroll_ancestor) {
   DCHECK(scroll_ancestor);
   for (LayerImpl* ancestor = child; ancestor;
@@ -2210,7 +2234,7 @@
   }
 
   bool scroll_on_main_thread = false;
-  LayerImpl* potentially_scrolling_layer_impl =
+  LayerImpl* scrolling_layer_impl =
       FindScrollLayerForDeviceViewportPoint(device_viewport_point,
                                             type,
                                             layer_impl,
@@ -2222,15 +2246,8 @@
     return ScrollOnMainThread;
   }
 
-  // If we want to send a DidOverscroll for this scroll it can't be ignored.
-  if (!potentially_scrolling_layer_impl)
-    potentially_scrolling_layer_impl = OuterViewportScrollLayer()
-                                           ? OuterViewportScrollLayer()
-                                           : InnerViewportScrollLayer();
-
-  if (potentially_scrolling_layer_impl) {
-    active_tree_->SetCurrentlyScrollingLayer(
-        potentially_scrolling_layer_impl);
+  if (scrolling_layer_impl) {
+    active_tree_->SetCurrentlyScrollingLayer(scrolling_layer_impl);
     should_bubble_scrolls_ = (type != NonBubblingGesture);
     wheel_scrolling_ = (type == Wheel);
     client_->RenewTreePriority();
@@ -2525,7 +2542,6 @@
   if (top_controls_manager_)
     top_controls_manager_->ScrollEnd();
   ClearCurrentlyScrollingLayer();
-  StartScrollbarAnimation();
 }
 
 InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() {
@@ -2589,10 +2605,8 @@
     ScrollbarAnimationController* animation_controller =
         scroll_layer_impl ? scroll_layer_impl->scrollbar_animation_controller()
                           : NULL;
-    if (animation_controller) {
-      animation_controller->DidMouseMoveOffScrollbar(CurrentFrameTimeTicks());
-      StartScrollbarAnimation();
-    }
+    if (animation_controller)
+      animation_controller->DidMouseMoveOffScrollbar();
     scroll_layer_id_when_mouse_over_scrollbar_ = 0;
   }
 
@@ -2621,10 +2635,8 @@
         std::min(distance_to_scrollbar,
                  DeviceSpaceDistanceToLayer(device_viewport_point, *it));
 
-  bool should_animate = animation_controller->DidMouseMoveNear(
-      CurrentFrameTimeTicks(), distance_to_scrollbar / device_scale_factor_);
-  if (should_animate)
-    StartScrollbarAnimation();
+  animation_controller->DidMouseMoveNear(distance_to_scrollbar /
+                                         device_scale_factor_);
 }
 
 bool LayerTreeHostImpl::HandleMouseOverScrollbar(LayerImpl* layer_impl,
@@ -2634,11 +2646,7 @@
     layer_impl = active_tree_->LayerById(scroll_layer_id);
     if (layer_impl && layer_impl->scrollbar_animation_controller()) {
       scroll_layer_id_when_mouse_over_scrollbar_ = scroll_layer_id;
-      bool should_animate =
-          layer_impl->scrollbar_animation_controller()->DidMouseMoveNear(
-              CurrentFrameTimeTicks(), 0);
-      if (should_animate)
-        StartScrollbarAnimation();
+      layer_impl->scrollbar_animation_controller()->DidMouseMoveNear(0);
     } else {
       scroll_layer_id_when_mouse_over_scrollbar_ = 0;
     }
@@ -2940,41 +2948,25 @@
 
   ScrollbarAnimationController* scrollbar_controller =
       layer->scrollbar_animation_controller();
-  if (scrollbar_controller && scrollbar_controller->Animate(time)) {
-    TRACE_EVENT_INSTANT0(
-        "cc",
-        "LayerTreeHostImpl::SetNeedsAnimate due to AnimateScrollbars",
-        TRACE_EVENT_SCOPE_THREAD);
-    SetNeedsAnimate();
-  }
+  if (scrollbar_controller)
+    scrollbar_controller->Animate(time);
 
   for (size_t i = 0; i < layer->children().size(); ++i)
     AnimateScrollbarsRecursive(layer->children()[i], time);
 }
 
-void LayerTreeHostImpl::StartScrollbarAnimation() {
-  TRACE_EVENT0("cc", "LayerTreeHostImpl::StartScrollbarAnimation");
-  StartScrollbarAnimationRecursive(RootLayer(), CurrentFrameTimeTicks());
+void LayerTreeHostImpl::PostDelayedScrollbarFade(
+    const base::Closure& start_fade,
+    base::TimeDelta delay) {
+  client_->PostDelayedScrollbarFadeOnImplThread(start_fade, delay);
 }
 
-void LayerTreeHostImpl::StartScrollbarAnimationRecursive(LayerImpl* layer,
-                                                         base::TimeTicks time) {
-  if (!layer)
-    return;
-
-  ScrollbarAnimationController* scrollbar_controller =
-      layer->scrollbar_animation_controller();
-  if (scrollbar_controller && scrollbar_controller->IsAnimating()) {
-    base::TimeDelta delay = scrollbar_controller->DelayBeforeStart(time);
-    if (delay > base::TimeDelta()) {
-      client_->RequestScrollbarAnimationOnImplThread(delay);
-    } else if (scrollbar_controller->Animate(time)) {
-      SetNeedsAnimate();
-    }
-  }
-
-  for (size_t i = 0; i < layer->children().size(); ++i)
-    StartScrollbarAnimationRecursive(layer->children()[i], time);
+void LayerTreeHostImpl::SetNeedsScrollbarAnimationFrame() {
+  TRACE_EVENT_INSTANT0(
+      "cc",
+      "LayerTreeHostImpl::SetNeedsRedraw due to scrollbar fade",
+      TRACE_EVENT_SCOPE_THREAD);
+  SetNeedsAnimate();
 }
 
 void LayerTreeHostImpl::SetTreePriority(TreePriority priority) {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index af74c37..d246a03 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -16,6 +16,7 @@
 #include "base/time/time.h"
 #include "cc/animation/animation_events.h"
 #include "cc/animation/animation_registrar.h"
+#include "cc/animation/scrollbar_animation_controller.h"
 #include "cc/base/cc_export.h"
 #include "cc/debug/micro_benchmark_controller_impl.h"
 #include "cc/input/input_handler.h"
@@ -90,7 +91,9 @@
   virtual void SendManagedMemoryStats() = 0;
   virtual bool IsInsideDraw() = 0;
   virtual void RenewTreePriority() = 0;
-  virtual void RequestScrollbarAnimationOnImplThread(base::TimeDelta delay) = 0;
+  virtual void PostDelayedScrollbarFadeOnImplThread(
+      const base::Closure& start_fade,
+      base::TimeDelta delay) = 0;
   virtual void DidActivatePendingTree() = 0;
   virtual void DidManageTiles() = 0;
 
@@ -106,6 +109,7 @@
       public TileManagerClient,
       public OutputSurfaceClient,
       public TopControlsManagerClient,
+      public ScrollbarAnimationControllerClient,
       public base::SupportsWeakPtr<LayerTreeHostImpl> {
  public:
   static scoped_ptr<LayerTreeHostImpl> Create(
@@ -141,8 +145,11 @@
                                        float page_scale,
                                        base::TimeDelta duration) OVERRIDE;
   virtual void SetNeedsAnimate() OVERRIDE;
-  virtual bool HaveTouchEventHandlersAt(const gfx::Point& viewport_port)
-      OVERRIDE;
+  virtual bool IsCurrentlyScrollingLayerAt(
+      const gfx::Point& viewport_point,
+      InputHandler::ScrollInputType type) OVERRIDE;
+  virtual bool HaveTouchEventHandlersAt(
+      const gfx::Point& viewport_port) OVERRIDE;
   virtual scoped_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor(
       ui::LatencyInfo* latency) OVERRIDE;
 
@@ -150,8 +157,6 @@
   virtual void DidChangeTopControlsPosition() OVERRIDE;
   virtual bool HaveRootScrollLayer() const OVERRIDE;
 
-  void StartScrollbarAnimation();
-
   struct CC_EXPORT FrameData : public RenderPassSink {
     FrameData();
     virtual ~FrameData();
@@ -228,6 +233,11 @@
   virtual void NotifyReadyToActivate() OVERRIDE;
   virtual void NotifyTileInitialized(const Tile* tile) OVERRIDE;
 
+  // ScrollbarAnimationControllerClient implementation.
+  virtual void PostDelayedScrollbarFade(const base::Closure& start_fade,
+                                        base::TimeDelta delay) OVERRIDE;
+  virtual void SetNeedsScrollbarAnimationFrame() OVERRIDE;
+
   // OutputSurfaceClient implementation.
   virtual void DeferredInitialize() OVERRIDE;
   virtual void ReleaseGL() OVERRIDE;
@@ -398,6 +408,11 @@
   void ResetCurrentFrameTimeForNextFrame();
   virtual base::TimeTicks CurrentFrameTimeTicks();
 
+  // Expected time between two begin impl frame calls.
+  base::TimeDelta begin_impl_frame_interval() const {
+    return begin_impl_frame_interval_;
+  }
+
   scoped_ptr<base::Value> AsValue() const { return AsValueWithFrame(NULL); }
   scoped_ptr<base::Value> AsValueWithFrame(FrameData* frame) const;
   scoped_ptr<base::Value> ActivationStateAsValue() const;
@@ -516,10 +531,10 @@
       InputHandler::ScrollInputType type,
       LayerImpl* layer_hit_by_point,
       bool* scroll_on_main_thread,
-      bool* has_ancestor_scroll_handler) const;
+      bool* optional_has_ancestor_scroll_handler) const;
   float DeviceSpaceDistanceToLayer(const gfx::PointF& device_viewport_point,
                                    LayerImpl* layer_impl);
-  void StartScrollbarAnimationRecursive(LayerImpl* layer, base::TimeTicks time);
+  void StartScrollbarFadeRecursive(LayerImpl* layer);
   void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy,
                               bool zero_budget);
   void EnforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy);
@@ -644,6 +659,9 @@
 
   base::TimeTicks current_frame_timeticks_;
 
+  // Expected time between two begin impl frame calls.
+  base::TimeDelta begin_impl_frame_interval_;
+
   scoped_ptr<AnimationRegistrar> animation_registrar_;
 
   RenderingStatsInstrumentation* rendering_stats_instrumentation_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 6044509..02f383f 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -155,8 +155,12 @@
   virtual void SendManagedMemoryStats() OVERRIDE {}
   virtual bool IsInsideDraw() OVERRIDE { return false; }
   virtual void RenewTreePriority() OVERRIDE {}
-  virtual void RequestScrollbarAnimationOnImplThread(base::TimeDelta delay)
-      OVERRIDE { requested_scrollbar_animation_delay_ = delay; }
+  virtual void PostDelayedScrollbarFadeOnImplThread(
+      const base::Closure& start_fade,
+      base::TimeDelta delay) OVERRIDE {
+    scrollbar_fade_start_ = start_fade;
+    requested_scrollbar_animation_delay_ = delay;
+  }
   virtual void DidActivatePendingTree() OVERRIDE {}
   virtual void DidManageTiles() OVERRIDE {}
 
@@ -404,6 +408,7 @@
   bool did_request_manage_tiles_;
   bool did_upload_visible_tile_;
   bool reduce_memory_result_;
+  base::Closure scrollbar_fade_start_;
   base::TimeDelta requested_scrollbar_animation_delay_;
   size_t current_limit_bytes_;
   int current_priority_cutoff_value_;
@@ -504,8 +509,14 @@
 
   EXPECT_EQ(InputHandler::ScrollStarted,
             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
+  EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
+                                                      InputHandler::Wheel));
   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
+  EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10),
+                                                      InputHandler::Wheel));
   host_impl_->ScrollEnd();
+  EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
+                                                       InputHandler::Wheel));
   EXPECT_TRUE(did_request_redraw_);
   EXPECT_TRUE(did_request_commit_);
 }
@@ -670,21 +681,35 @@
   EXPECT_EQ(InputHandler::ScrollOnMainThread,
             host_impl_->ScrollBegin(gfx::Point(25, 25),
                                     InputHandler::Wheel));
+  EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
+                                                       InputHandler::Wheel));
   EXPECT_EQ(InputHandler::ScrollOnMainThread,
             host_impl_->ScrollBegin(gfx::Point(25, 25),
                                     InputHandler::Gesture));
+  EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
+                                                       InputHandler::Gesture));
 
   // All scroll types outside this region should succeed.
   EXPECT_EQ(InputHandler::ScrollStarted,
             host_impl_->ScrollBegin(gfx::Point(75, 75),
                                     InputHandler::Wheel));
+  EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
+                                                      InputHandler::Gesture));
   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
+  EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
+                                                       InputHandler::Gesture));
   host_impl_->ScrollEnd();
+  EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
+                                                       InputHandler::Gesture));
   EXPECT_EQ(InputHandler::ScrollStarted,
             host_impl_->ScrollBegin(gfx::Point(75, 75),
                                     InputHandler::Gesture));
+  EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
+                                                      InputHandler::Gesture));
   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
   host_impl_->ScrollEnd();
+  EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
+                                                       InputHandler::Gesture));
 }
 
 TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
@@ -703,6 +728,8 @@
   EXPECT_EQ(InputHandler::ScrollStarted,
             host_impl_->ScrollBegin(gfx::Point(40, 10),
                                     InputHandler::Wheel));
+  EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10),
+                                                      InputHandler::Wheel));
   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1));
   host_impl_->ScrollEnd();
 
@@ -1340,6 +1367,7 @@
   scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar =                        \
       SolidColorScrollbarLayerImpl::Create(                                   \
           host_impl_->active_tree(), 4, VERTICAL, 10, 0, false, true);        \
+  EXPECT_FLOAT_EQ(0.f, scrollbar->opacity());                                 \
   scrollbar->SetScrollLayerById(2);                                           \
   scrollbar->SetClipLayerById(1);                                             \
                                                                               \
@@ -1356,27 +1384,22 @@
 TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) {
   LayerTreeSettings settings;
   settings.scrollbar_animator = LayerTreeSettings::LinearFade;
-  settings.scrollbar_linear_fade_delay_ms = 20;
-  settings.scrollbar_linear_fade_length_ms = 20;
+  settings.scrollbar_fade_delay_ms = 20;
+  settings.scrollbar_fade_duration_ms = 20;
 
   SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
 
   base::TimeTicks fake_now = gfx::FrameTime::Now();
-  host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
 
-  // If no scroll happened recently, StartScrollbarAnimation should have no
-  // effect.
-  host_impl_->StartScrollbarAnimation();
   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
   EXPECT_FALSE(did_request_redraw_);
 
-  // If no scroll happened during a scroll gesture, StartScrollbarAnimation
-  // should have no effect.
+  // If no scroll happened during a scroll gesture, it should have no effect.
   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
   host_impl_->ScrollEnd();
-  host_impl_->StartScrollbarAnimation();
   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
   EXPECT_FALSE(did_request_redraw_);
+  EXPECT_TRUE(scrollbar_fade_start_.Equals(base::Closure()));
 
   // After a scroll, a fade animation should be scheduled about 20ms from now.
   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
@@ -1384,89 +1407,65 @@
   host_impl_->ScrollEnd();
   did_request_redraw_ = false;
   did_request_animate_ = false;
-  host_impl_->StartScrollbarAnimation();
   EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
             requested_scrollbar_animation_delay_);
   EXPECT_FALSE(did_request_redraw_);
   EXPECT_FALSE(did_request_animate_);
   requested_scrollbar_animation_delay_ = base::TimeDelta();
+  scrollbar_fade_start_.Run();
+  host_impl_->Animate(fake_now);
 
   // After the fade begins, we should start getting redraws instead of a
   // scheduled animation.
   fake_now += base::TimeDelta::FromMilliseconds(25);
-  host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
-  host_impl_->StartScrollbarAnimation();
   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
   EXPECT_TRUE(did_request_animate_);
   did_request_animate_ = false;
 
-  // If no scroll happened recently, StartScrollbarAnimation should have no
-  // effect.
-  fake_now += base::TimeDelta::FromMilliseconds(25);
-  host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
-  host_impl_->StartScrollbarAnimation();
-  EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
-  EXPECT_FALSE(did_request_redraw_);
-
   // Setting the scroll offset outside a scroll should also cause the scrollbar
   // to appear and to schedule a fade.
   host_impl_->InnerViewportScrollLayer()->SetScrollOffset(gfx::Vector2d(5, 5));
-  host_impl_->StartScrollbarAnimation();
   EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
             requested_scrollbar_animation_delay_);
   EXPECT_FALSE(did_request_redraw_);
   EXPECT_FALSE(did_request_animate_);
   requested_scrollbar_animation_delay_ = base::TimeDelta();
-
-  // None of the above should have called CurrentFrameTimeTicks, so if we call
-  // it now we should get the current time.
-  fake_now += base::TimeDelta::FromMilliseconds(10);
-  host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
-  EXPECT_EQ(fake_now, host_impl_->CurrentFrameTimeTicks());
 }
 
 TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) {
   LayerTreeSettings settings;
   settings.scrollbar_animator = LayerTreeSettings::LinearFade;
-  settings.scrollbar_linear_fade_delay_ms = 20;
-  settings.scrollbar_linear_fade_length_ms = 20;
+  settings.scrollbar_fade_delay_ms = 20;
+  settings.scrollbar_fade_duration_ms = 20;
   settings.use_pinch_zoom_scrollbars = true;
 
   SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
 
   base::TimeTicks fake_now = gfx::FrameTime::Now();
-  host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
 
   host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
 
-  // If no scroll happened recently, StartScrollbarAnimation should have no
-  // effect.
-  host_impl_->StartScrollbarAnimation();
   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
   EXPECT_FALSE(did_request_animate_);
 
-  // If no scroll happened during a scroll gesture, StartScrollbarAnimation
-  // should have no effect.
+  // If no scroll happened during a scroll gesture, it should have no effect.
   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
   host_impl_->ScrollEnd();
-  host_impl_->StartScrollbarAnimation();
   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
   EXPECT_FALSE(did_request_animate_);
+  EXPECT_TRUE(scrollbar_fade_start_.Equals(base::Closure()));
 
   // After a scroll, no fade animation should be scheduled.
   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
   host_impl_->ScrollEnd();
   did_request_redraw_ = false;
-  host_impl_->StartScrollbarAnimation();
   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
   EXPECT_FALSE(did_request_animate_);
   requested_scrollbar_animation_delay_ = base::TimeDelta();
 
   // We should not see any draw requests.
   fake_now += base::TimeDelta::FromMilliseconds(25);
-  host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
-  host_impl_->StartScrollbarAnimation();
   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
   EXPECT_FALSE(did_request_animate_);
 
@@ -1478,24 +1477,24 @@
   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
   host_impl_->ScrollEnd();
   did_request_redraw_ = false;
-  host_impl_->StartScrollbarAnimation();
   EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
             requested_scrollbar_animation_delay_);
   EXPECT_FALSE(did_request_animate_);
   requested_scrollbar_animation_delay_ = base::TimeDelta();
+  scrollbar_fade_start_.Run();
 
   // After the fade begins, we should start getting redraws instead of a
   // scheduled animation.
   fake_now += base::TimeDelta::FromMilliseconds(25);
-  host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
-  host_impl_->StartScrollbarAnimation();
-  EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
+  host_impl_->Animate(fake_now);
   EXPECT_TRUE(did_request_animate_);
 }
 
 void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
     float device_scale_factor) {
   LayerTreeSettings settings;
+  settings.scrollbar_fade_delay_ms = 500;
+  settings.scrollbar_fade_duration_ms = 300;
   settings.scrollbar_animator = LayerTreeSettings::Thinning;
 
   gfx::Size viewport_size(300, 200);
@@ -3454,8 +3453,9 @@
       opaque_rect = opaque_content_rect_;
     gfx::Rect visible_quad_rect = quad_rect_;
 
-    SharedQuadState* shared_quad_state =
-        quad_sink->UseSharedQuadState(CreateSharedQuadState());
+    SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+    PopulateSharedQuadState(shared_quad_state);
+
     scoped_ptr<TileDrawQuad> test_blending_draw_quad = TileDrawQuad::Create();
     test_blending_draw_quad->SetNew(shared_quad_state,
                                     quad_rect_,
@@ -4235,8 +4235,8 @@
 
   virtual void AppendQuads(QuadSink* quad_sink,
                            AppendQuadsData* append_quads_data) OVERRIDE {
-    SharedQuadState* shared_quad_state =
-        quad_sink->UseSharedQuadState(CreateSharedQuadState());
+    SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState();
+    PopulateSharedQuadState(shared_quad_state);
 
     SkColor gray = SkColorSetRGB(100, 100, 100);
     gfx::Rect quad_rect(content_bounds());
@@ -5761,14 +5761,15 @@
       456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 1000);
   int everything_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
       gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING);
-  int required_only_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
-      gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY);
+  int allow_nice_to_have_cutoff_value =
+      ManagedMemoryPolicy::PriorityCutoffToValue(
+          gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE);
   int nothing_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
       gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING);
 
   // GPU rasterization should be disabled by default.
-  EXPECT_EQ(LayerTreeSettings::CpuRasterization,
-            host_impl_->settings().rasterization_site);
+  EXPECT_FALSE(host_impl_->settings().gpu_rasterization_enabled);
+  EXPECT_FALSE(host_impl_->settings().gpu_rasterization_forced);
 
   host_impl_->SetVisible(true);
   host_impl_->SetMemoryPolicy(policy1);
@@ -5786,14 +5787,14 @@
   // Now enable GPU rasterization and test if we get required only cutoff,
   // when visible.
   LayerTreeSettings settings;
-  settings.rasterization_site = LayerTreeSettings::GpuRasterization;
+  settings.gpu_rasterization_forced = true;
   host_impl_ = LayerTreeHostImpl::Create(
       settings, this, &proxy_, &stats_instrumentation_, NULL, 0);
 
   host_impl_->SetVisible(true);
   host_impl_->SetMemoryPolicy(policy1);
   EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
-  EXPECT_EQ(required_only_cutoff_value, current_priority_cutoff_value_);
+  EXPECT_EQ(allow_nice_to_have_cutoff_value, current_priority_cutoff_value_);
 
   host_impl_->SetVisible(false);
   EXPECT_EQ(0u, current_limit_bytes_);
@@ -6492,5 +6493,58 @@
             150u * 1024u * 1024u);
 }
 
+TEST_F(LayerTreeHostImplTest, UpdateTilesForMasksWithNoVisibleContent) {
+  gfx::Size bounds(100000, 100);
+
+  host_impl_->CreatePendingTree();
+
+  scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->pending_tree(), 1);
+
+  scoped_ptr<FakePictureLayerImpl> layer_with_mask =
+      FakePictureLayerImpl::Create(host_impl_->pending_tree(), 2);
+
+  layer_with_mask->SetBounds(bounds);
+
+  scoped_ptr<FakePictureLayerImpl> mask =
+      FakePictureLayerImpl::Create(host_impl_->pending_tree(), 3);
+
+  mask->SetIsMask(true);
+  mask->SetBounds(bounds);
+
+  FakePictureLayerImpl* pending_mask_content = mask.get();
+  layer_with_mask->SetMaskLayer(mask.PassAs<LayerImpl>());
+
+  scoped_ptr<FakePictureLayerImpl> child_of_layer_with_mask =
+      FakePictureLayerImpl::Create(host_impl_->pending_tree(), 4);
+
+  child_of_layer_with_mask->SetBounds(bounds);
+  child_of_layer_with_mask->SetDrawsContent(true);
+
+  layer_with_mask->AddChild(child_of_layer_with_mask.PassAs<LayerImpl>());
+
+  root->AddChild(layer_with_mask.PassAs<LayerImpl>());
+
+  host_impl_->pending_tree()->SetRootLayer(root.Pass());
+
+  gfx::Rect r1 = pending_mask_content->visible_rect_for_tile_priority();
+  ASSERT_EQ(0, r1.x());
+  ASSERT_EQ(0, r1.y());
+  ASSERT_EQ(0, r1.width());
+  ASSERT_EQ(0, r1.height());
+
+  host_impl_->ActivatePendingTree();
+
+  host_impl_->active_tree()->UpdateDrawProperties();
+
+  ASSERT_EQ(2u, host_impl_->active_tree()->RenderSurfaceLayerList().size());
+
+  FakePictureLayerImpl* active_mask_content =
+      static_cast<FakePictureLayerImpl*>(
+          host_impl_->active_tree()->root_layer()->children()[0]->mask_layer());
+  gfx::Rect r2 = active_mask_content->visible_rect_for_tile_priority();
+
+  ASSERT_TRUE(!r2.IsEmpty());
+}
+
 }  // namespace
 }  // namespace cc
diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc
index 913d63f..54c95da 100644
--- a/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -26,9 +26,11 @@
 
   virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
 
-  virtual void PaintContents(SkCanvas* canvas,
-                             const gfx::Rect& rect,
-                             gfx::RectF* opaque_rect) OVERRIDE {
+  virtual void PaintContents(
+      SkCanvas* canvas,
+      const gfx::Rect& rect,
+      gfx::RectF* opaque_rect,
+      ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
     SkPaint paint;
     paint.setStyle(SkPaint::kStroke_Style);
     paint.setStrokeWidth(SkIntToScalar(2));
@@ -84,7 +86,8 @@
   MaskContentLayerClient client;
   client.PaintContents(&canvas,
                        gfx::Rect(100, 100),
-                       NULL);
+                       NULL,
+                       ContentLayerClient::GRAPHICS_CONTEXT_ENABLED);
   mask->SetBitmap(bitmap);
 
   scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
diff --git a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
index 8f6242d..47964fd 100644
--- a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
+++ b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
@@ -41,15 +41,14 @@
     PictureLayerImpl* picture_layer = static_cast<PictureLayerImpl*>(
         host_impl->active_tree()->root_layer()->child_at(0));
 
-    QuadList quads;
-    SharedQuadStateList shared_states;
-    MockQuadCuller quad_culler(&quads, &shared_states);
+    scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+    MockQuadCuller quad_culler(render_pass.get());
 
     AppendQuadsData data;
     picture_layer->AppendQuads(&quad_culler, &data);
 
-    for (size_t i = 0; i < quads.size(); ++i)
-      EXPECT_EQ(quads[i]->material, DrawQuad::PICTURE_CONTENT);
+    for (size_t i = 0; i < render_pass->quad_list.size(); ++i)
+      EXPECT_EQ(render_pass->quad_list[i]->material, DrawQuad::PICTURE_CONTENT);
 
     // Triggers pixel readback and ends the test.
     LayerTreePixelTest::SwapBuffersOnThread(host_impl, result);
@@ -65,9 +64,11 @@
 
   virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
 
-  virtual void PaintContents(SkCanvas* canvas,
-                             const gfx::Rect& clip,
-                             gfx::RectF* opaque) OVERRIDE {
+  virtual void PaintContents(
+      SkCanvas* canvas,
+      const gfx::Rect& clip,
+      gfx::RectF* opaque,
+      ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
     *opaque = gfx::RectF(layer_rect_.width(), layer_rect_.height());
 
     SkPaint paint;
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 01c5a18..e8c629a 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -23,6 +23,8 @@
 #include "cc/output/copy_output_request.h"
 #include "cc/output/copy_output_result.h"
 #include "cc/output/output_surface.h"
+#include "cc/quads/draw_quad.h"
+#include "cc/quads/io_surface_draw_quad.h"
 #include "cc/resources/prioritized_resource.h"
 #include "cc/resources/prioritized_resource_manager.h"
 #include "cc/resources/resource_update_queue.h"
@@ -1240,8 +1242,11 @@
 
   void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
 
-  virtual void PaintContents(SkCanvas*, const gfx::Rect&,
-                             gfx::RectF*) OVERRIDE {
+  virtual void PaintContents(
+      SkCanvas* canvas,
+      const gfx::Rect& clip,
+      gfx::RectF* opaque,
+      ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
     // Set layer opacity to 0.
     if (test_layer_)
       test_layer_->SetOpacity(0.f);
@@ -2521,9 +2526,11 @@
     int paint_count() const { return paint_count_; }
     int lcd_notification_count() const { return lcd_notification_count_; }
 
-    virtual void PaintContents(SkCanvas* canvas,
-                               const gfx::Rect& clip,
-                               gfx::RectF* opaque) OVERRIDE {
+    virtual void PaintContents(
+        SkCanvas* canvas,
+        const gfx::Rect& clip,
+        gfx::RectF* opaque,
+        ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
       ++paint_count_;
     }
     virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
@@ -2762,9 +2769,11 @@
 
     void set_layer(Layer* layer) { layer_ = layer; }
 
-    virtual void PaintContents(SkCanvas* canvas,
-                               const gfx::Rect& clip,
-                               gfx::RectF* opaque) OVERRIDE {
+    virtual void PaintContents(
+        SkCanvas* canvas,
+        const gfx::Rect& clip,
+        gfx::RectF* opaque,
+        ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
       layer_->SetBounds(gfx::Size(2, 2));
     }
 
@@ -2837,6 +2846,8 @@
                                   GLenum type,
                                   GLintptr offset));
   MOCK_METHOD1(deleteTexture, void(GLenum texture));
+  MOCK_METHOD2(produceTextureCHROMIUM,
+               void(GLenum target, const GLbyte* mailbox));
 };
 
 class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
@@ -2847,8 +2858,13 @@
         new MockIOSurfaceWebGraphicsContext3D);
     mock_context_ = mock_context_owned.get();
 
-    return FakeOutputSurface::Create3d(
-        mock_context_owned.PassAs<TestWebGraphicsContext3D>());
+    if (delegating_renderer()) {
+      return FakeOutputSurface::CreateDelegating3d(
+          mock_context_owned.PassAs<TestWebGraphicsContext3D>());
+    } else {
+      return FakeOutputSurface::Create3d(
+          mock_context_owned.PassAs<TestWebGraphicsContext3D>());
+    }
   }
 
   virtual void SetupTree() OVERRIDE {
@@ -2863,6 +2879,7 @@
     io_surface_layer->SetBounds(gfx::Size(10, 10));
     io_surface_layer->SetAnchorPoint(gfx::PointF());
     io_surface_layer->SetIsDrawable(true);
+    io_surface_layer->SetContentsOpaque(true);
     io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
     layer_tree_host()->root_layer()->AddChild(io_surface_layer);
   }
@@ -2870,6 +2887,7 @@
   virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
 
   virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+    EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
     // In WillDraw, the IOSurfaceLayer sets up the io surface texture.
 
     EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
@@ -2885,6 +2903,10 @@
         .Times(1);
     EXPECT_CALL(*mock_context_,
                 texParameteri(GL_TEXTURE_RECTANGLE_ARB,
+                              GL_TEXTURE_POOL_CHROMIUM,
+                              GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
+    EXPECT_CALL(*mock_context_,
+                texParameteri(GL_TEXTURE_RECTANGLE_ARB,
                               GL_TEXTURE_WRAP_S,
                               GL_CLAMP_TO_EDGE)).Times(1);
     EXPECT_CALL(*mock_context_,
@@ -2907,13 +2929,32 @@
       LayerTreeHostImpl::FrameData* frame,
       DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
     Mock::VerifyAndClearExpectations(&mock_context_);
+    ResourceProvider* resource_provider = host_impl->resource_provider();
+    EXPECT_EQ(1u, resource_provider->num_resources());
+    CHECK_EQ(1u, frame->render_passes.size());
+    CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
+    const DrawQuad* quad = frame->render_passes[0]->quad_list[0];
+    CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
+    const IOSurfaceDrawQuad* io_surface_draw_quad =
+        IOSurfaceDrawQuad::MaterialCast(quad);
+    EXPECT_SIZE_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
+    EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
+    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
+              resource_provider->TargetForTesting(
+                  io_surface_draw_quad->io_surface_resource_id));
 
-    // The io surface layer's texture is drawn.
-    EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
     EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
         .Times(1);
-    EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
-        .Times(AtLeast(1));
+    if (delegating_renderer()) {
+      // The io surface layer's resource should be sent to the parent.
+      EXPECT_CALL(*mock_context_,
+                  produceTextureCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
+    } else {
+      // The io surface layer's texture is drawn.
+      EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
+      EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
+          .Times(AtLeast(1));
+    }
 
     return draw_result;
   }
@@ -2921,7 +2962,7 @@
   virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
     Mock::VerifyAndClearExpectations(&mock_context_);
 
-    EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(1);
+    EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
     EndTest();
   }
 
@@ -2932,9 +2973,7 @@
   gfx::Size io_surface_size_;
 };
 
-// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
-    LayerTreeHostTestIOSurfaceDrawing);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
 
 class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
  public:
@@ -3109,7 +3148,7 @@
   int last_source_frame_number_drawn_;
 };
 
-MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
+MULTI_THREAD_DIRECT_RENDERER_TEST_F(LayerTreeHostTestDeferredInitialize);
 
 // Test for UI Resource management.
 class LayerTreeHostTestUIResource : public LayerTreeHostTest {
@@ -4480,7 +4519,10 @@
     scoped_refptr<TestContextProvider> context_provider =
         TestContextProvider::Create();
     context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024);
-    return FakeOutputSurface::Create3d(context_provider);
+    if (delegating_renderer())
+      return FakeOutputSurface::CreateDelegating3d(context_provider);
+    else
+      return FakeOutputSurface::Create3d(context_provider);
   }
 
   virtual void SetupTree() OVERRIDE {
@@ -4660,9 +4702,14 @@
       second_context_provider_ = TestContextProvider::Create();
     }
 
-    scoped_ptr<FakeOutputSurface> output_surface(FakeOutputSurface::Create3d(
-        second_context_provider_ ? second_context_provider_
-                                 : first_context_provider_));
+    scoped_refptr<TestContextProvider> provider(second_context_provider_
+                                                    ? second_context_provider_
+                                                    : first_context_provider_);
+    scoped_ptr<FakeOutputSurface> output_surface;
+    if (delegating_renderer())
+      output_surface = FakeOutputSurface::CreateDelegating3d(provider);
+    else
+      output_surface = FakeOutputSurface::Create3d(provider);
     output_surface->SetMemoryPolicyToSetAtBind(
         make_scoped_ptr(new ManagedMemoryPolicy(
             second_context_provider_ ? second_output_surface_memory_limit_
@@ -4963,115 +5010,209 @@
 
 MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources);
 
-class LayerTreeHostTestHybridRasterizationSetting : public LayerTreeHostTest {
+class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
  protected:
   virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
     settings->impl_side_painting = true;
-    settings->rasterization_site = LayerTreeSettings::HybridRasterization;
+
+    EXPECT_FALSE(settings->gpu_rasterization_enabled);
+    EXPECT_FALSE(settings->gpu_rasterization_forced);
   }
 
   virtual void SetupTree() OVERRIDE {
     LayerTreeHostTest::SetupTree();
 
-    scoped_refptr<PictureLayer> parent = PictureLayer::Create(&client_);
-    parent->SetBounds(gfx::Size(10, 10));
-    layer_tree_host()->root_layer()->AddChild(parent);
+    scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
+    layer->SetBounds(gfx::Size(10, 10));
+    layer->SetIsDrawable(true);
+    layer_tree_host()->root_layer()->AddChild(layer);
+  }
 
-    scoped_refptr<Layer> child = PictureLayer::Create(&client_);
-    child->SetBounds(gfx::Size(10, 10));
-    parent->AddChild(child);
+  virtual void BeginTest() OVERRIDE {
+    Layer* root = layer_tree_host()->root_layer();
+    PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
+    PicturePile* pile = layer->GetPicturePileForTesting();
 
+    // Verify default values.
+    EXPECT_TRUE(root->IsSuitableForGpuRasterization());
+    EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
+    EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
+    EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
+    EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
+
+    // Setting gpu rasterization trigger does not enable gpu rasterization.
     layer_tree_host()->set_has_gpu_rasterization_trigger(true);
-  }
+    EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
+    EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
 
-  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+    PostSetNeedsCommitToMainThread();
+  }
 
   virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
     LayerImpl* root = host_impl->pending_tree()->root_layer();
-    PictureLayerImpl* parent =
+    PictureLayerImpl* layer_impl =
         static_cast<PictureLayerImpl*>(root->children()[0]);
-    PictureLayerImpl* child =
-        static_cast<PictureLayerImpl*>(parent->children()[0]);
 
-    EXPECT_TRUE(parent->ShouldUseGpuRasterization());
-    EXPECT_TRUE(child->ShouldUseGpuRasterization());
+    EXPECT_FALSE(layer_impl->ShouldUseGpuRasterization());
   }
 
   virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
     LayerImpl* root = host_impl->active_tree()->root_layer();
-    PictureLayerImpl* parent =
+    PictureLayerImpl* layer_impl =
         static_cast<PictureLayerImpl*>(root->children()[0]);
-    PictureLayerImpl* child =
-        static_cast<PictureLayerImpl*>(parent->children()[0]);
 
-    EXPECT_TRUE(parent->ShouldUseGpuRasterization());
-    EXPECT_TRUE(child->ShouldUseGpuRasterization());
+    EXPECT_FALSE(layer_impl->ShouldUseGpuRasterization());
     EndTest();
   }
 
   virtual void AfterTest() OVERRIDE {}
 
-  FakeContentLayerClient client_;
+  FakeContentLayerClient layer_client_;
 };
 
-MULTI_THREAD_TEST_F(LayerTreeHostTestHybridRasterizationSetting);
+MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
 
-class LayerTreeHostTestGpuRasterizationSetting : public LayerTreeHostTest {
+class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
  protected:
   virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
     settings->impl_side_painting = true;
-    settings->rasterization_site = LayerTreeSettings::GpuRasterization;
+
+    EXPECT_FALSE(settings->gpu_rasterization_enabled);
+    settings->gpu_rasterization_enabled = true;
   }
 
   virtual void SetupTree() OVERRIDE {
     LayerTreeHostTest::SetupTree();
 
-    scoped_refptr<PictureLayer> parent = PictureLayer::Create(&client_);
-    parent->SetBounds(gfx::Size(10, 10));
-    layer_tree_host()->root_layer()->AddChild(parent);
-
-    scoped_refptr<Layer> child = PictureLayer::Create(&client_);
-    child->SetBounds(gfx::Size(10, 10));
-    parent->AddChild(child);
-
-    layer_tree_host()->set_has_gpu_rasterization_trigger(false);
+    scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
+    layer->SetBounds(gfx::Size(10, 10));
+    layer->SetIsDrawable(true);
+    layer_tree_host()->root_layer()->AddChild(layer);
   }
 
-  virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+  virtual void BeginTest() OVERRIDE {
+    Layer* root = layer_tree_host()->root_layer();
+    PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
+    PicturePile* pile = layer->GetPicturePileForTesting();
+
+    // Verify default values.
+    EXPECT_TRUE(root->IsSuitableForGpuRasterization());
+    EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
+    EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
+    EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
+    EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
+
+    // Gpu rasterization trigger is relevant.
+    layer_tree_host()->set_has_gpu_rasterization_trigger(true);
+    EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
+    EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
+
+    // Content-based veto is relevant as well.
+    pile->SetUnsuitableForGpuRasterizationForTesting();
+    EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
+    EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
+    // Veto will take effect when layers are updated.
+    // The results will be verified after commit is completed below.
+    // Since we are manually marking picture pile as unsuitable,
+    // make sure that the layer gets a chance to update.
+    layer->SetNeedsDisplay();
+    PostSetNeedsCommitToMainThread();
+  }
 
   virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
     LayerImpl* root = host_impl->pending_tree()->root_layer();
-    PictureLayerImpl* parent =
+    PictureLayerImpl* layer_impl =
         static_cast<PictureLayerImpl*>(root->children()[0]);
-    PictureLayerImpl* child =
-        static_cast<PictureLayerImpl*>(parent->children()[0]);
 
-    // All layers should use GPU rasterization, regardless of whether a GPU
-    // rasterization hint has been set.
-    EXPECT_TRUE(parent->ShouldUseGpuRasterization());
-    EXPECT_TRUE(child->ShouldUseGpuRasterization());
+    EXPECT_FALSE(layer_impl->ShouldUseGpuRasterization());
   }
 
   virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
     LayerImpl* root = host_impl->active_tree()->root_layer();
-    PictureLayerImpl* parent =
+    PictureLayerImpl* layer_impl =
         static_cast<PictureLayerImpl*>(root->children()[0]);
-    PictureLayerImpl* child =
-        static_cast<PictureLayerImpl*>(parent->children()[0]);
 
-    // All layers should use GPU rasterization, regardless of whether a GPU
-    // rasterization hint has been set.
-    EXPECT_TRUE(parent->ShouldUseGpuRasterization());
-    EXPECT_TRUE(child->ShouldUseGpuRasterization());
+    EXPECT_FALSE(layer_impl->ShouldUseGpuRasterization());
     EndTest();
   }
 
   virtual void AfterTest() OVERRIDE {}
 
-  FakeContentLayerClient client_;
+  FakeContentLayerClient layer_client_;
 };
 
-MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationSetting);
+MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
+
+class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
+ protected:
+  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+    settings->impl_side_painting = true;
+
+    EXPECT_FALSE(settings->gpu_rasterization_forced);
+    settings->gpu_rasterization_forced = true;
+  }
+
+  virtual void SetupTree() OVERRIDE {
+    LayerTreeHostTest::SetupTree();
+
+    scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
+    layer->SetBounds(gfx::Size(10, 10));
+    layer->SetIsDrawable(true);
+    layer_tree_host()->root_layer()->AddChild(layer);
+  }
+
+  virtual void BeginTest() OVERRIDE {
+    Layer* root = layer_tree_host()->root_layer();
+    PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
+    PicturePile* pile = layer->GetPicturePileForTesting();
+
+    // Verify default values.
+    EXPECT_TRUE(root->IsSuitableForGpuRasterization());
+    EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
+    EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
+    EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
+
+    // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
+    EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
+    layer_tree_host()->set_has_gpu_rasterization_trigger(true);
+    EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
+    EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
+
+    // Content-based veto is irrelevant as well.
+    pile->SetUnsuitableForGpuRasterizationForTesting();
+    EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
+    EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
+    // Veto will take effect when layers are updated.
+    // The results will be verified after commit is completed below.
+    // Since we are manually marking picture pile as unsuitable,
+    // make sure that the layer gets a chance to update.
+    layer->SetNeedsDisplay();
+    PostSetNeedsCommitToMainThread();
+  }
+
+  virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+    LayerImpl* root = host_impl->pending_tree()->root_layer();
+    PictureLayerImpl* layer_impl =
+        static_cast<PictureLayerImpl*>(root->children()[0]);
+
+    EXPECT_TRUE(layer_impl->ShouldUseGpuRasterization());
+  }
+
+  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+    LayerImpl* root = host_impl->active_tree()->root_layer();
+    PictureLayerImpl* layer_impl =
+        static_cast<PictureLayerImpl*>(root->children()[0]);
+
+    EXPECT_TRUE(layer_impl->ShouldUseGpuRasterization());
+    EndTest();
+  }
+
+  virtual void AfterTest() OVERRIDE {}
+
+  FakeContentLayerClient layer_client_;
+};
+
+MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced);
 
 class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
  public:
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 84e324b..334368f 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -679,7 +679,8 @@
     child_output_surface_->BindToClient(&output_surface_client_);
     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     child_resource_provider_ = ResourceProvider::Create(
-        child_output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1);
+        child_output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
+        false);
   }
 
   static void EmptyReleaseCallback(unsigned sync_point, bool lost) {}
diff --git a/cc/trees/layer_tree_host_unittest_delegated.cc b/cc/trees/layer_tree_host_unittest_delegated.cc
index a6562ae..02f8db3 100644
--- a/cc/trees/layer_tree_host_unittest_delegated.cc
+++ b/cc/trees/layer_tree_host_unittest_delegated.cc
@@ -99,7 +99,8 @@
                       root_damage_rect,
                       gfx::Transform());
 
-    scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
+    SharedQuadState* shared_quad_state =
+        root_pass->CreateAndAppendSharedQuadState();
 
     gfx::Rect rect = root_output_rect;
     gfx::Rect opaque_rect = root_output_rect;
@@ -114,7 +115,7 @@
     bool flipped = false;
 
     scoped_ptr<TextureDrawQuad> invalid_draw_quad = TextureDrawQuad::Create();
-    invalid_draw_quad->SetNew(shared_quad_state.get(),
+    invalid_draw_quad->SetNew(shared_quad_state,
                               rect,
                               opaque_rect,
                               visible_rect,
@@ -127,8 +128,6 @@
                               flipped);
     root_pass->quad_list.push_back(invalid_draw_quad.PassAs<DrawQuad>());
 
-    root_pass->shared_quad_state_list.push_back(shared_quad_state.Pass());
-
     frame->render_pass_list.push_back(root_pass.Pass());
     return frame.Pass();
   }
@@ -148,10 +147,11 @@
 
   void AddTextureQuad(DelegatedFrameData* frame,
                       ResourceProvider::ResourceId resource_id) {
-    scoped_ptr<SharedQuadState> sqs = SharedQuadState::Create();
+    SharedQuadState* sqs =
+        frame->render_pass_list[0]->CreateAndAppendSharedQuadState();
     scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create();
     float vertex_opacity[4] = { 1.f, 1.f, 1.f, 1.f };
-    quad->SetNew(sqs.get(),
+    quad->SetNew(sqs,
                  gfx::Rect(0, 0, 10, 10),
                  gfx::Rect(0, 0, 10, 10),
                  gfx::Rect(0, 0, 10, 10),
@@ -162,7 +162,6 @@
                  SK_ColorTRANSPARENT,
                  vertex_opacity,
                  false);
-    frame->render_pass_list[0]->shared_quad_state_list.push_back(sqs.Pass());
     frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>());
   }
 
@@ -182,10 +181,11 @@
                  gfx::Transform());
     frame->render_pass_list.push_back(pass.Pass());
 
-    scoped_ptr<SharedQuadState> sqs = SharedQuadState::Create();
+    SharedQuadState* sqs =
+        frame->render_pass_list[0]->CreateAndAppendSharedQuadState();
     scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create();
 
-    quad->SetNew(sqs.get(),
+    quad->SetNew(sqs,
                  output_rect,
                  output_rect,
                  id,
@@ -195,7 +195,6 @@
                  gfx::Rect(0, 0, 1, 1),  // mask_uv_rect
                  filters,
                  background_filters);
-    frame->render_pass_list[0]->shared_quad_state_list.push_back(sqs.Pass());
     frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>());
   }
 
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index b68e1d5..465c9cc 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -7,6 +7,8 @@
 #include "base/debug/trace_event.h"
 #include "cc/animation/keyframed_animation_curve.h"
 #include "cc/animation/scrollbar_animation_controller.h"
+#include "cc/animation/scrollbar_animation_controller_linear_fade.h"
+#include "cc/animation/scrollbar_animation_controller_thinning.h"
 #include "cc/base/math_util.h"
 #include "cc/base/util.h"
 #include "cc/debug/traced_value.h"
@@ -256,10 +258,10 @@
   if (currently_scrolling_layer_ &&
       currently_scrolling_layer_->scrollbar_animation_controller())
     currently_scrolling_layer_->scrollbar_animation_controller()
-        ->DidScrollGestureEnd(CurrentFrameTimeTicks());
+        ->DidScrollEnd();
   currently_scrolling_layer_ = layer;
   if (layer && layer->scrollbar_animation_controller())
-    layer->scrollbar_animation_controller()->DidScrollGestureBegin();
+    layer->scrollbar_animation_controller()->DidScrollBegin();
 }
 
 void LayerTreeImpl::ClearCurrentlyScrollingLayer() {
@@ -486,11 +488,13 @@
              LayerIteratorType::Begin(&render_surface_layer_list_);
          it != end;
          ++it) {
-      if (!it.represents_itself())
-        continue;
       LayerImpl* layer = *it;
+      if (it.represents_itself())
+        layer->UpdateTilePriorities();
 
-      layer->UpdateTilePriorities();
+      if (!it.represents_contributing_render_surface())
+        continue;
+
       if (layer->mask_layer())
         layer->mask_layer()->UpdateTilePriorities();
       if (layer->replica_layer() && layer->replica_layer()->mask_layer())
@@ -686,6 +690,10 @@
   return layer_tree_host_impl_->CurrentFrameTimeTicks();
 }
 
+base::TimeDelta LayerTreeImpl::begin_impl_frame_interval() const {
+  return layer_tree_host_impl_->begin_impl_frame_interval();
+}
+
 void LayerTreeImpl::SetNeedsCommit() {
   layer_tree_host_impl_->SetNeedsCommit();
 }
@@ -694,8 +702,30 @@
   return layer_tree_host_impl_->DrawViewportSize();
 }
 
-void LayerTreeImpl::StartScrollbarAnimation() {
-  layer_tree_host_impl_->StartScrollbarAnimation();
+scoped_ptr<ScrollbarAnimationController>
+LayerTreeImpl::CreateScrollbarAnimationController(LayerImpl* scrolling_layer) {
+  DCHECK(settings().scrollbar_fade_delay_ms);
+  DCHECK(settings().scrollbar_fade_duration_ms);
+  base::TimeDelta delay =
+      base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_delay_ms);
+  base::TimeDelta duration =
+      base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_duration_ms);
+  switch (settings().scrollbar_animator) {
+    case LayerTreeSettings::LinearFade: {
+      return ScrollbarAnimationControllerLinearFade::Create(
+                 scrolling_layer, layer_tree_host_impl_, delay, duration)
+          .PassAs<ScrollbarAnimationController>();
+    }
+    case LayerTreeSettings::Thinning: {
+      return ScrollbarAnimationControllerThinning::Create(
+                 scrolling_layer, layer_tree_host_impl_, delay, duration)
+          .PassAs<ScrollbarAnimationController>();
+    }
+    case LayerTreeSettings::NoAnimator:
+      NOTREACHED();
+      break;
+  }
+  return scoped_ptr<ScrollbarAnimationController>();
 }
 
 void LayerTreeImpl::DidAnimateScrollOffset() {
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index e016f5e..bc488db 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -81,9 +81,11 @@
   int MaxTextureSize() const;
   bool PinchGestureActive() const;
   base::TimeTicks CurrentFrameTimeTicks() const;
+  base::TimeDelta begin_impl_frame_interval() const;
   void SetNeedsCommit();
   gfx::Size DrawViewportSize() const;
-  void StartScrollbarAnimation();
+  scoped_ptr<ScrollbarAnimationController> CreateScrollbarAnimationController(
+      LayerImpl* scrolling_layer);
   void DidAnimateScrollOffset();
 
   // Tree specific methods exposed to layer-impl tree.
diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc
index 98a509c..629b4e2 100644
--- a/cc/trees/layer_tree_settings.cc
+++ b/cc/trees/layer_tree_settings.cc
@@ -26,11 +26,13 @@
       accelerated_animation_enabled(true),
       can_use_lcd_text(true),
       should_clear_root_render_pass(true),
-      rasterization_site(CpuRasterization),
+      gpu_rasterization_enabled(false),
+      gpu_rasterization_forced(false),
+      recording_mode(RecordNormally),
       create_low_res_tiling(true),
       scrollbar_animator(NoAnimator),
-      scrollbar_linear_fade_delay_ms(300),
-      scrollbar_linear_fade_length_ms(300),
+      scrollbar_fade_delay_ms(0),
+      scrollbar_fade_duration_ms(0),
       solid_color_scrollbar_color(SK_ColorWHITE),
       calculate_top_controls_position(false),
       timeout_and_draw_when_animation_checkerboards(true),
@@ -50,7 +52,7 @@
       use_pinch_virtual_viewport(false),
       // At 256x256 tiles, 128 tiles cover an area of 2048x4096 pixels.
       max_tiles_for_interest_area(128),
-      skewport_target_time_in_seconds(1.0f),
+      skewport_target_time_multiplier(1.0f),
       skewport_extrapolation_limit_in_content_pixels(2000),
       max_unused_resource_memory_percentage(100),
       max_memory_for_prepaint_percentage(100),
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index 69eea91..8192b3d 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -30,13 +30,15 @@
   bool partial_swap_enabled;
   bool accelerated_animation_enabled;
   bool can_use_lcd_text;
+  bool use_distance_field_text;
   bool should_clear_root_render_pass;
-  enum RasterizationSite {
-    CpuRasterization,
-    HybridRasterization,
-    GpuRasterization,
+  bool gpu_rasterization_enabled;
+  bool gpu_rasterization_forced;
+  enum RecordingMode {
+    RecordNormally,
+    RecordWithSkRecord,
   };
-  RasterizationSite rasterization_site;
+  RecordingMode recording_mode;
   bool create_low_res_tiling;
 
   enum ScrollbarAnimator {
@@ -45,8 +47,8 @@
     Thinning,
   };
   ScrollbarAnimator scrollbar_animator;
-  int scrollbar_linear_fade_delay_ms;
-  int scrollbar_linear_fade_length_ms;
+  int scrollbar_fade_delay_ms;
+  int scrollbar_fade_duration_ms;
   SkColor solid_color_scrollbar_color;
   bool calculate_top_controls_position;
   bool timeout_and_draw_when_animation_checkerboards;
@@ -65,7 +67,7 @@
   bool use_pinch_zoom_scrollbars;
   bool use_pinch_virtual_viewport;
   size_t max_tiles_for_interest_area;
-  float skewport_target_time_in_seconds;
+  float skewport_target_time_multiplier;
   int skewport_extrapolation_limit_in_content_pixels;
   size_t max_unused_resource_memory_percentage;
   size_t max_memory_for_prepaint_percentage;
diff --git a/cc/trees/quad_culler.cc b/cc/trees/quad_culler.cc
index d828675..419a3dd 100644
--- a/cc/trees/quad_culler.cc
+++ b/cc/trees/quad_culler.cc
@@ -16,23 +16,17 @@
 
 namespace cc {
 
-QuadCuller::QuadCuller(QuadList* quad_list,
-                       SharedQuadStateList* shared_quad_state_list,
+QuadCuller::QuadCuller(RenderPass* render_pass,
                        const LayerImpl* layer,
                        const OcclusionTracker<LayerImpl>& occlusion_tracker)
-    : quad_list_(quad_list),
-      shared_quad_state_list_(shared_quad_state_list),
+    : render_pass_(render_pass),
       layer_(layer),
       occlusion_tracker_(occlusion_tracker),
       current_shared_quad_state_(NULL) {
 }
 
-SharedQuadState* QuadCuller::UseSharedQuadState(
-    scoped_ptr<SharedQuadState> shared_quad_state) {
-  // TODO(danakj): If all quads are culled for the shared_quad_state, we can
-  // drop it from the list.
-  current_shared_quad_state_ = shared_quad_state.get();
-  shared_quad_state_list_->push_back(shared_quad_state.Pass());
+SharedQuadState* QuadCuller::CreateSharedQuadState() {
+  current_shared_quad_state_ = render_pass_->CreateAndAppendSharedQuadState();
   return current_shared_quad_state_;
 }
 
@@ -52,11 +46,12 @@
 
 void QuadCuller::Append(scoped_ptr<DrawQuad> draw_quad) {
   DCHECK(draw_quad->shared_quad_state == current_shared_quad_state_);
-  DCHECK(!shared_quad_state_list_->empty());
-  DCHECK(shared_quad_state_list_->back() == current_shared_quad_state_);
+  DCHECK(!render_pass_->shared_quad_state_list.empty());
+  DCHECK(render_pass_->shared_quad_state_list.back() ==
+         current_shared_quad_state_);
   DCHECK(!draw_quad->rect.IsEmpty());
   DCHECK(!draw_quad->visible_rect.IsEmpty());
-  quad_list_->push_back(draw_quad.Pass());
+  render_pass_->quad_list.push_back(draw_quad.Pass());
 }
 
 }  // namespace cc
diff --git a/cc/trees/quad_culler.h b/cc/trees/quad_culler.h
index 6377b13..1a69cd4 100644
--- a/cc/trees/quad_culler.h
+++ b/cc/trees/quad_culler.h
@@ -7,25 +7,23 @@
 
 #include "cc/base/cc_export.h"
 #include "cc/layers/quad_sink.h"
-#include "cc/quads/render_pass.h"
 
 namespace cc {
 class LayerImpl;
+class RenderPass;
 class RenderSurfaceImpl;
 template <typename LayerType>
 class OcclusionTracker;
 
 class CC_EXPORT QuadCuller : public QuadSink {
  public:
-  QuadCuller(QuadList* quad_list,
-             SharedQuadStateList* shared_quad_state_list,
+  QuadCuller(RenderPass* render_pass,
              const LayerImpl* layer,
              const OcclusionTracker<LayerImpl>& occlusion_tracker);
   virtual ~QuadCuller() {}
 
   // QuadSink implementation.
-  virtual SharedQuadState* UseSharedQuadState(
-      scoped_ptr<SharedQuadState> shared_quad_state) OVERRIDE;
+  virtual SharedQuadState* CreateSharedQuadState() OVERRIDE;
   virtual gfx::Rect UnoccludedContentRect(const gfx::Rect& content_rect,
                                           const gfx::Transform& draw_transform)
       OVERRIDE;
@@ -35,8 +33,7 @@
   virtual void Append(scoped_ptr<DrawQuad> draw_quad) OVERRIDE;
 
  private:
-  QuadList* quad_list_;
-  SharedQuadStateList* shared_quad_state_list_;
+  RenderPass* render_pass_;
   const LayerImpl* layer_;
   const OcclusionTracker<LayerImpl>& occlusion_tracker_;
 
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index 8f682be..af40df3 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -79,8 +79,9 @@
   virtual void SendManagedMemoryStats() OVERRIDE;
   virtual bool IsInsideDraw() OVERRIDE;
   virtual void RenewTreePriority() OVERRIDE {}
-  virtual void RequestScrollbarAnimationOnImplThread(base::TimeDelta delay)
-      OVERRIDE {}
+  virtual void PostDelayedScrollbarFadeOnImplThread(
+      const base::Closure& start_fade,
+      base::TimeDelta delay) OVERRIDE {}
   virtual void DidActivatePendingTree() OVERRIDE {}
   virtual void DidManageTiles() OVERRIDE {}
   virtual void SetDebugState(const LayerTreeDebugState& debug_state) OVERRIDE {}
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index 9c97ef6..19cf3ba 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -1630,16 +1630,10 @@
   RenewTreePriority();
 }
 
-void ThreadProxy::RequestScrollbarAnimationOnImplThread(base::TimeDelta delay) {
-  Proxy::ImplThreadTaskRunner()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&ThreadProxy::StartScrollbarAnimationOnImplThread,
-                 impl_thread_weak_ptr_),
-      delay);
-}
-
-void ThreadProxy::StartScrollbarAnimationOnImplThread() {
-  impl().layer_tree_host_impl->StartScrollbarAnimation();
+void ThreadProxy::PostDelayedScrollbarFadeOnImplThread(
+    const base::Closure& start_fade,
+    base::TimeDelta delay) {
+  Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, start_fade, delay);
 }
 
 void ThreadProxy::DidActivatePendingTree() {
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index 381e2be..f91599e 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -100,8 +100,9 @@
   virtual void SendManagedMemoryStats() OVERRIDE;
   virtual bool IsInsideDraw() OVERRIDE;
   virtual void RenewTreePriority() OVERRIDE;
-  virtual void RequestScrollbarAnimationOnImplThread(base::TimeDelta delay)
-      OVERRIDE;
+  virtual void PostDelayedScrollbarFadeOnImplThread(
+      const base::Closure& start_fade,
+      base::TimeDelta delay) OVERRIDE;
   virtual void DidActivatePendingTree() OVERRIDE;
   virtual void DidManageTiles() OVERRIDE;
 
@@ -193,7 +194,6 @@
                            base::DictionaryValue* state) const;
   void RenewTreePriorityOnImplThread();
   void SetSwapUsedIncompleteTileOnImplThread(bool used_incomplete_tile);
-  void StartScrollbarAnimationOnImplThread();
   void MainThreadHasStoppedFlingingOnImplThread();
   void SetInputThrottledUntilCommitOnImplThread(bool is_throttled);
   void SetDebugStateOnImplThread(const LayerTreeDebugState& debug_state);
diff --git a/chrome/VERSION b/chrome/VERSION
index 830ba7a..2d2e97d 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=36
 MINOR=0
-BUILD=1969
+BUILD=1984
 PATCH=0
diff --git a/chrome/android/java/res/layout/four_button_menu_item.xml b/chrome/android/java/res/layout/four_button_menu_item.xml
new file mode 100644
index 0000000..abe580b
--- /dev/null
+++ b/chrome/android/java/res/layout/four_button_menu_item.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="top|start"
+    android:orientation="horizontal">
+
+    <ImageButton
+        android:id="@+id/button_one"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:background="?android:attr/selectableItemBackground"
+        android:scaleType="center" />
+
+    <View
+        android:layout_width="1dp"
+        android:layout_height="?android:attr/listPreferredItemHeightSmall"
+        android:background="?android:attr/listDivider" />
+
+    <ImageButton
+        android:id="@+id/button_two"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:background="?android:attr/selectableItemBackground"
+        android:scaleType="center" />
+
+    <View
+        android:layout_width="1dp"
+        android:layout_height="?android:attr/listPreferredItemHeightSmall"
+        android:background="?android:attr/listDivider" />
+
+    <ImageButton
+        android:id="@+id/button_three"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:background="?android:attr/selectableItemBackground"
+        android:scaleType="center" />
+    
+    <View
+        android:layout_width="1dp"
+        android:layout_height="?android:attr/listPreferredItemHeightSmall"
+        android:background="?android:attr/listDivider" />
+
+    <ImageButton
+        android:id="@+id/button_four"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:background="?android:attr/selectableItemBackground"
+        android:scaleType="center" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProvider.java
index 9e7f8b2..c12e656 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBrowserProvider.java
@@ -10,12 +10,10 @@
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.UriMatcher;
 import android.database.Cursor;
 import android.database.MatrixCursor;
-import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -1271,15 +1269,6 @@
         }
     }
 
-    /**
-     * Call to get the intent to create a bookmark shortcut on homescreen.
-     */
-    public static Intent getShortcutToBookmark(String url, String title, Bitmap favicon, int rValue,
-            int gValue, int bValue, Context context) {
-        return BookmarkUtils.createAddToHomeIntent(
-                context, url, title, favicon, rValue, gValue, bValue);
-    }
-
     @SuppressLint("NewApi")
     private void notifyChange(final Uri uri) {
         // If the calling user is different than current one, we need to post a
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/NativePage.java b/chrome/android/java/src/org/chromium/chrome/browser/NativePage.java
index ea210e7..ffc7e7e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/NativePage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/NativePage.java
@@ -4,7 +4,6 @@
 
 package org.chromium.chrome.browser;
 
-import android.graphics.Bitmap;
 import android.view.View;
 
 /**
@@ -29,7 +28,7 @@
     /**
      * @return The hostname for this page, e.g. "newtab" or "bookmarks".
      */
-    public String getHost();
+    String getHost();
 
     /**
      * @return The background color of the page.
@@ -39,20 +38,10 @@
     /**
      * Updates the native page based on the given url.
      */
-    public void updateForUrl(String url);
+    void updateForUrl(String url);
 
     /**
      * Called after a page has been removed from the view hierarchy and will no longer be used.
      */
-    public void destroy();
-
-    /**
-     * @return An unscaled screenshot of the page.
-     */
-    Bitmap getBitmap();
-
-    /**
-     * @return A screenshot of the page scaled to the specified size.
-     */
-    Bitmap getBitmap(int width, int height);
+    void destroy();
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java
index 916533b..7e43f06 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java
@@ -132,7 +132,7 @@
      * @param context The app context.
      */
     @CalledByNative
-    private static TtsPlatformImpl create(int nativeTtsPlatformImplAndroid,
+    private static TtsPlatformImpl create(long nativeTtsPlatformImplAndroid,
                                           Context context) {
         return new TtsPlatformImpl(nativeTtsPlatformImplAndroid, context);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
index cc59342..81cdd7c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
@@ -24,7 +24,7 @@
  * ListAdapter to customize the view of items in the list.
  */
 class AppMenuAdapter extends BaseAdapter {
-    private static final int VIEW_TYPE_COUNT = 3;
+    private static final int VIEW_TYPE_COUNT = 4;
 
     /**
      * Regular Android menu item that contains a title and an icon if icon is specified.
@@ -39,6 +39,10 @@
      * Menu item that has three buttons. Every one of these buttons is displayed as an icon.
      */
     private static final int THREE_BUTTON_MENU_ITEM = 2;
+    /**
+     * Menu item that has four buttons. Every one of these buttons is displayed as an icon.
+     */
+    private static final int FOUR_BUTTON_MENU_ITEM = 3;
 
     private final AppMenu mAppMenu;
     private final LayoutInflater mInflater;
@@ -65,7 +69,9 @@
     @Override
     public int getItemViewType(int position) {
         if (getItem(position).hasSubMenu()) {
-            if (getItem(position).getSubMenu().size() == 3) {
+            if (getItem(position).getSubMenu().size() == 4) {
+                return FOUR_BUTTON_MENU_ITEM;
+            } else if (getItem(position).getSubMenu().size() == 3) {
                 return THREE_BUTTON_MENU_ITEM;
             } else if (getItem(position).getSubMenu().size() == 2) {
                 return TITLE_BUTTON_MENU_ITEM;
@@ -142,6 +148,27 @@
                 convertView.setEnabled(false);
                 break;
             }
+            case FOUR_BUTTON_MENU_ITEM: {
+                FourButtonMenuItemViewHolder holder = null;
+                if (convertView == null) {
+                    holder = new FourButtonMenuItemViewHolder();
+                    convertView = mInflater.inflate(R.layout.four_button_menu_item, null);
+                    holder.buttonOne = (ImageButton) convertView.findViewById(R.id.button_one);
+                    holder.buttonTwo = (ImageButton) convertView.findViewById(R.id.button_two);
+                    holder.buttonThree = (ImageButton) convertView.findViewById(R.id.button_three);
+                    holder.buttonFour = (ImageButton) convertView.findViewById(R.id.button_four);
+                    convertView.setTag(holder);
+                } else {
+                    holder = (FourButtonMenuItemViewHolder) convertView.getTag();
+                }
+                setupImageButton(holder.buttonOne, item.getSubMenu().getItem(0));
+                setupImageButton(holder.buttonTwo, item.getSubMenu().getItem(1));
+                setupImageButton(holder.buttonThree, item.getSubMenu().getItem(2));
+                setupImageButton(holder.buttonFour, item.getSubMenu().getItem(3));
+                convertView.setFocusable(false);
+                convertView.setEnabled(false);
+                break;
+            }
             case TITLE_BUTTON_MENU_ITEM: {
                 TitleButtonMenuItemViewHolder holder = null;
                 if (convertView == null) {
@@ -206,6 +233,13 @@
         public ImageButton buttonThree;
     }
 
+    static class FourButtonMenuItemViewHolder {
+        public ImageButton buttonOne;
+        public ImageButton buttonTwo;
+        public ImageButton buttonThree;
+        public ImageButton buttonFour;
+    }
+
     static class TitleButtonMenuItemViewHolder {
         public Button title;
         public View divider;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerAndroid.java
index 76fc7b3..71f1c07 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerAndroid.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerAndroid.java
@@ -79,6 +79,7 @@
          * @param initialShippingGuid GUID of the initial shipping address selection in Autofill
          * @param initialCardGuid GUID of the initial credit card selection in Autofill
          * @param merchantDomain Scheme+origin for the originating web page, or null
+         * @param shippingCountries A list of allowed shipping countries, or null
          * @return The Autofill dialog that would later call into the delegate, or null
          */
         AutofillDialog createDialog(
@@ -90,7 +91,8 @@
                 final boolean initialChoiceIsAutofill, final String initialAccountName,
                 final String initialBillingGuid, final String initialShippingGuid,
                 final String initialCardGuid,
-                final String merchantDomain);
+                final String merchantDomain,
+                final String[] shippingCountries);
     }
 
     /**
@@ -111,7 +113,8 @@
             final boolean initialChoiceIsAutofill, final String initialWalletAccountName,
             final String initialBillingGuid, final String initialShippingGuid,
             final String initialCardGuid,
-            final String merchantDomain) {
+            final String merchantDomain,
+            final String[] shippingCountries) {
         mNativeDelegate = nativeAutofillDialogControllerAndroid;
 
         if (sDialogFactory == null) {
@@ -145,7 +148,8 @@
                 incognitoMode,
                 initialChoiceIsAutofill, initialWalletAccountName,
                 initialBillingGuid, initialShippingGuid, initialCardGuid,
-                merchantDomain);
+                merchantDomain,
+                shippingCountries);
         if (mDialog == null) {
             nativeDialogCancel(mNativeDelegate);
             return;
@@ -162,7 +166,8 @@
             final boolean initialChoiceIsAutofill, final String initialWalletAccountName,
             final String initialBillingGuid, final String initialShippingGuid,
             final String initialCreditCardGuid,
-            final String merchantDomain) {
+            final String merchantDomain,
+            final String[] shippingCountries) {
         return new AutofillDialogControllerAndroid(
                 nativeAutofillDialogControllerAndroid, windowAndroid,
                 requestFullBillingAddress, requestShippingAddress, requestPhoneNumbers,
@@ -170,7 +175,8 @@
                 initialChoiceIsAutofill, initialWalletAccountName,
                 initialBillingGuid, initialShippingGuid,
                 initialCreditCardGuid,
-                merchantDomain);
+                merchantDomain,
+                shippingCountries);
     }
 
     @CalledByNative
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogResult.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogResult.java
index 92f0cd8..ec15b2f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogResult.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogResult.java
@@ -75,38 +75,45 @@
     public static class ResultAddress {
         private final String mName;
         private final String mPhoneNumber;
-        private final String mAddress1;
-        private final String mAddress2;
-        private final String mCity;
-        private final String mState;
+        private final String mStreetAddress;
+        private final String mLocality;
+        private final String mDependentLocality;
+        private final String mAdministrativeArea;
         private final String mPostalCode;
+        private final String mSortingCode;
         private final String mCountryCode;
+        private final String mLanguageCode;
 
         /**
          * Creates a ResultAddress.
          * Any parameter can be empty or null.
          * @param name Full name
          * @param phoneNumber Phone number
-         * @param address1 Address line 1
-         * @param address2 Address line 2
-         * @param city City
-         * @param state State
+         * @param streetAddress Street address
+         * @param locality Locality / City
+         * @param dependentLocality Inner-city district / Suburb / Dependent locality
+         * @param administrativeArea Region / State
          * @param postalCode Postal code
+         * @param sortingCode Sorting code
          * @param countryCode Country code
+         * @param languageCode Language code
          */
         public ResultAddress(
                 String name, String phoneNumber,
-                String address1, String address2,
-                String city, String state, String postalCode,
-                String countryCode) {
+                String streetAddress,
+                String locality, String dependentLocality,
+                String administrativeArea, String postalCode, String sortingCode,
+                String countryCode, String languageCode) {
             mName = name;
             mPhoneNumber = phoneNumber;
-            mAddress1 = address1;
-            mAddress2 = address2;
-            mCity = city;
-            mState = state;
+            mStreetAddress = streetAddress;
+            mLocality = locality;
+            mDependentLocality = dependentLocality;
+            mAdministrativeArea = administrativeArea;
             mPostalCode = postalCode;
+            mSortingCode = sortingCode;
             mCountryCode = countryCode;
+            mLanguageCode = languageCode;
         }
 
         /**
@@ -126,35 +133,35 @@
         }
 
         /**
-         * @return Address line 1
+         * @return Street address
          */
         @CalledByNative("ResultAddress")
-        public String getAddress1() {
-            return mAddress1;
+        public String getStreetAddress() {
+            return mStreetAddress;
         }
 
         /**
-         * @return Address line 2
+         * @return Locality (city)
          */
         @CalledByNative("ResultAddress")
-        public String getAddress2() {
-            return mAddress2;
+        public String getLocality() {
+            return mLocality;
         }
 
         /**
-         * @return City
+         * @return Dependent locality (inner-city district / suburb)
          */
         @CalledByNative("ResultAddress")
-        public String getCity() {
-            return mCity;
+        public String getDependentLocality() {
+            return mDependentLocality;
         }
 
         /**
-         * @return State
+         * @return Administrative area (region / state)
          */
         @CalledByNative("ResultAddress")
-        public String getState() {
-            return mState;
+        public String getAdministrativeArea() {
+            return mAdministrativeArea;
         }
 
         /**
@@ -166,12 +173,28 @@
         }
 
         /**
+         * @return Sorting code
+         */
+        @CalledByNative("ResultAddress")
+        public String getSortingCode() {
+            return mSortingCode;
+        }
+
+        /**
          * @return Country code
          */
         @CalledByNative("ResultAddress")
         public String getCountryCode() {
             return mCountryCode;
         }
+
+        /**
+         * @return Language code
+         */
+        @CalledByNative("ResultAddress")
+        public String getLanguageCode() {
+            return mLanguageCode;
+        }
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
index 7c033b9..a0dd09b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
@@ -74,7 +74,7 @@
      */
     @CalledByNative
     private void show(AutofillSuggestion[] suggestions) {
-        if (mAutofillPopup != null) mAutofillPopup.show(suggestions);
+        if (mAutofillPopup != null) mAutofillPopup.filterAndShow(suggestions);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java
index a0f5d58..919a9d7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java
@@ -23,47 +23,67 @@
 @JNINamespace("autofill")
 public class PersonalDataManager {
 
+    /**
+     * Observer of PersonalDataManager events.
+     */
     public interface PersonalDataManagerObserver {
+        /**
+         * Called when the data is changed.
+         */
         public abstract void onPersonalDataChanged();
     }
 
+    /**
+     * Autofill address information.
+     */
     public static class AutofillProfile {
         private String mGUID;
         private String mOrigin;
         private String mFullName;
         private String mCompanyName;
-        private String mAddressLine1;
-        private String mAddressLine2;
-        private String mCity;
-        private String mState;
-        private String mZip;
+        private String mStreetAddress;
+        private String mRegion;
+        private String mLocality;
+        private String mDependentLocality;
+        private String mPostalCode;
+        private String mSortingCode;
         private String mCountry;
         private String mPhoneNumber;
         private String mEmailAddress;
+        private String mLanguageCode;
 
         @CalledByNative("AutofillProfile")
-        public static AutofillProfile create(String guid, String origin, String fullName,
-                String companyName, String addressLine1, String addressLine2, String city,
-                String state, String zip, String country, String phoneNumber, String emailAddress) {
-            return new AutofillProfile(guid, origin, fullName, companyName, addressLine1,
-                    addressLine2, city, state, zip, country, phoneNumber, emailAddress);
+        public static AutofillProfile create(String guid, String origin,
+                String fullName, String companyName,
+                String streetAddress, String region, String locality, String dependentLocality,
+                String postalCode, String sortingCode,
+                String country, String phoneNumber, String emailAddress, String languageCode) {
+            return new AutofillProfile(guid, origin, fullName, companyName,
+                    streetAddress,
+                    region, locality, dependentLocality,
+                    postalCode, sortingCode, country, phoneNumber, emailAddress, languageCode);
         }
 
         public AutofillProfile(String guid, String origin, String fullName, String companyName,
-                String addressLine1, String addressLine2, String city, String state,
-                String zip, String country, String phoneNumber, String emailAddress) {
+                String streetAddress,
+                String region,
+                String locality, String dependentLocality,
+                String postalCode, String sortingCode,
+                String country, String phoneNumber, String emailAddress, String languageCode) {
             mGUID = guid;
             mOrigin = origin;
             mFullName = fullName;
             mCompanyName = companyName;
-            mAddressLine1 = addressLine1;
-            mAddressLine2 = addressLine2;
-            mCity = city;
-            mState = state;
-            mZip = zip;
+            mStreetAddress = streetAddress;
+            mRegion = region;
+            mLocality = locality;
+            mDependentLocality = dependentLocality;
+            mPostalCode = postalCode;
+            mSortingCode = sortingCode;
             mCountry = country;
             mPhoneNumber = phoneNumber;
             mEmailAddress = emailAddress;
+            mLanguageCode = languageCode;
         }
 
         @CalledByNative("AutofillProfile")
@@ -87,28 +107,33 @@
         }
 
         @CalledByNative("AutofillProfile")
-        public String getAddressLine1() {
-            return mAddressLine1;
+        public String getStreetAddress() {
+            return mStreetAddress;
         }
 
         @CalledByNative("AutofillProfile")
-        public String getAddressLine2() {
-            return mAddressLine2;
+        public String getRegion() {
+            return mRegion;
         }
 
         @CalledByNative("AutofillProfile")
-        public String getCity() {
-            return mCity;
+        public String getLocality() {
+            return mLocality;
         }
 
         @CalledByNative("AutofillProfile")
-        public String getState() {
-            return mState;
+        public String getDependentLocality() {
+            return mDependentLocality;
         }
 
         @CalledByNative("AutofillProfile")
-        public String getZip() {
-            return mZip;
+        public String getPostalCode() {
+            return mPostalCode;
+        }
+
+        @CalledByNative("AutofillProfile")
+        public String getSortingCode() {
+            return mSortingCode;
         }
 
         @CalledByNative("AutofillProfile")
@@ -130,6 +155,11 @@
             return mEmailAddress;
         }
 
+        @CalledByNative("AutofillProfile")
+        public String getLanguageCode() {
+            return mLanguageCode;
+        }
+
         public void setGUID(String guid) {
             mGUID = guid;
         }
@@ -146,24 +176,28 @@
             mCompanyName = companyName;
         }
 
-        public void setAddressLine1(String addressLine1) {
-            mAddressLine1 = addressLine1;
+        public void setStreetAddress(String streetAddress) {
+            mStreetAddress = streetAddress;
         }
 
-        public void setAddressLine2(String addressLine2) {
-            mAddressLine2 = addressLine2;
+        public void setRegion(String region) {
+            mRegion = region;
         }
 
-        public void setCity(String city) {
-            mCity = city;
+        public void setLocality(String locality) {
+            mLocality = locality;
         }
 
-        public void setState(String state) {
-            mState = state;
+        public void setDependentLocality(String dependentLocality) {
+            mDependentLocality = dependentLocality;
         }
 
-        public void setZip(String zip) {
-            mZip = zip;
+        public void setPostalCode(String postalCode) {
+            mPostalCode = postalCode;
+        }
+
+        public void setSortingCode(String sortingCode) {
+            mSortingCode = sortingCode;
         }
 
         public void setCountry(String country) {
@@ -177,8 +211,15 @@
         public void setEmailAddress(String emailAddress) {
             mEmailAddress = emailAddress;
         }
+
+        public void setLanguageCode(String languageCode) {
+            mLanguageCode = languageCode;
+        }
     }
 
+    /**
+     * Autofill credit card information.
+     */
     public static class CreditCard {
         // Note that while some of these fields are numbers, they're predominantly read,
         // marshaled and compared as strings. To save conversions, we use strings everywhere.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
index 21ac8dc..c79c323 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -67,9 +67,9 @@
                     UrlUtilities.isDownloadableScheme(params.getSrcUrl()));
 
             if (mDelegate.canLoadOriginalImage()) {
-                menu.findItem(R.id.contextmenu_open_original_image_in_new_tab).setVisible(false);
-            } else {
                 menu.findItem(R.id.contextmenu_open_image_in_new_tab).setVisible(false);
+            } else {
+                menu.findItem(R.id.contextmenu_open_original_image_in_new_tab).setVisible(false);
             }
 
             final TemplateUrlService templateUrlServiceInstance = TemplateUrlService.getInstance();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/favicon/FaviconHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/favicon/FaviconHelper.java
index 445efb0..d04a290 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/favicon/FaviconHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/favicon/FaviconHelper.java
@@ -84,6 +84,30 @@
     }
 
     /**
+     * Fetches the first available favicon for a URL that exceeds the minimum size threshold.  If
+     * no favicons are larger (or equal) to the threshold, the largest favicon of any type is
+     * fetched.
+     *
+     * @param profile              Profile used for the FaviconService construction.
+     * @param pageUrl              The target Page URL to get the favicon.
+     * @param iconTypes            The list of icon types (each entry can be a bitmasked collection
+     *                             of types) that should be fetched in order.  As soon as one of
+     *                             the buckets exceeds the minimum size threshold, that favicon
+     *                             will be returned.
+     * @param minSizeThresholdPx   The size threshold (inclusive) used to early exit out fetching
+     *                             subsequent favicon types.
+     * @param faviconImageCallback The callback to be notified with the best matching favicon.
+     */
+    public void getLargestRawFaviconForUrl(
+            Profile profile, String pageUrl, int[] iconTypes, int minSizeThresholdPx,
+            FaviconImageCallback faviconImageCallback) {
+        assert mNativeFaviconHelper != 0;
+        nativeGetLargestRawFaviconForUrl(
+                mNativeFaviconHelper, profile, pageUrl, iconTypes, minSizeThresholdPx - 1,
+                faviconImageCallback);
+    }
+
+    /**
      * Return the dominant color of a given bitmap in {@link Color} format.
      * @param image The bitmap image to find the dominant color for.
      * @return The dominant color in {@link Color} format.
@@ -111,6 +135,9 @@
     private static native boolean nativeGetLocalFaviconImageForURL(long nativeFaviconHelper,
             Profile profile, String pageUrl, int iconTypes, int desiredSizeInDip,
             FaviconImageCallback faviconImageCallback);
+    private static native void nativeGetLargestRawFaviconForUrl(long nativeFaviconHelper,
+            Profile profile, String pageUrl, int[] iconTypes, int minSizeThresholdPx,
+            FaviconImageCallback faviconImageCallback);
     private static native Bitmap nativeGetSyncedFaviconImageForURL(long nativeFaviconHelper,
             Profile profile, String pageUrl);
     private static native int nativeGetDominantColorForBitmap(Bitmap image);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java
index 8c11af0..a378301 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java
@@ -38,6 +38,9 @@
     private static final String TAG = "InfoBarContainer";
     private static final long REATTACH_FADE_IN_MS = 250;
 
+    /**
+     * A listener for the InfoBar animation.
+     */
     public interface InfoBarAnimationListener {
         /**
          * Notifies the subscriber when an animation is completed.
@@ -210,15 +213,6 @@
         setVisibility(INVISIBLE);
     }
 
-    public InfoBar findInfoBar(int nativeInfoBar) {
-        for (InfoBar infoBar : mInfoBars) {
-            if (infoBar.ownsNativeInfoBar(nativeInfoBar)) {
-                return infoBar;
-            }
-        }
-        return null;
-    }
-
     /**
      * Adds an InfoBar to the view hierarchy.
      * @param infoBar InfoBar to add to the View hierarchy.
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb b/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb
index 581cd8d..de098c7 100644
--- a/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb
+++ b/chrome/android/java/strings/translations/android_chrome_strings_hr.xtb
@@ -6,7 +6,7 @@
 <translation id="5578795271662203820">Potraži sliku na usluzi <ph name="SEARCH_ENGINE"/></translation>
 <translation id="6831043979455480757">Prevedi</translation>
 <translation id="7644305409888602715">Prevođenje stranice na <ph name="SOURCE_LANGUAGE"/>...</translation>
-<translation id="7015922086425404465">Nabavite aplikaciju iz trgovine Google Play: <ph name="APP_ACTION"/></translation>
+<translation id="7015922086425404465">Preuzmite aplikaciju iz trgovine Google Play: <ph name="APP_ACTION"/></translation>
 <translation id="1491151370853475546">Ponovo učitaj ovu stranicu</translation>
 <translation id="641643625718530986">Ispis…</translation>
 <translation id="7658239707568436148">Odustani</translation>
@@ -38,7 +38,7 @@
 <translation id="907015151729920253">Pametna kartica</translation>
 <translation id="3063601790762993062">Spremi videozapis</translation>
 <translation id="6042308850641462728">Više</translation>
-<translation id="7267430310003164111">Odzivnik za nabavljanje aplikacije iz Trgovine Google Play. Naziv aplikacije: <ph name="APP_NAME"/>. Prosječna ocjena aplikacije: <ph name="APP_RATING"/>.</translation>
+<translation id="7267430310003164111">Pitanje o preuzimanju aplikacije iz Trgovine Google Play. Naziv aplikacije: <ph name="APP_NAME"/>. Prosječna ocjena aplikacije: <ph name="APP_RATING"/>.</translation>
 <translation id="4148957013307229264">Instaliranje...</translation>
 <translation id="3992315671621218278">Spremi vezu</translation>
 <translation id="8034522405403831421">Jezik ove stranice jest <ph name="SOURCE_LANGUAGE"/>. Želite li je prevesti na <ph name="TARGET_LANGUAGE"/>?</translation>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerTest.java
index 34d21e1..0e9342f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerTest.java
@@ -25,29 +25,45 @@
 public class AutofillDialogControllerTest extends ChromeShellTestBase {
     private static final String SWITCH_REDUCE_SECURITY_FOR_TESTING = "reduce-security-for-testing";
     private static final long DIALOG_CALLBACK_DELAY_MILLISECONDS = 50;
+
     private static final String TEST_NAME = "Joe Doe";
     private static final String TEST_PHONE = "(415)413-0703";
     private static final String TEST_PHONE_UNFORMATTED = "4154130703";
     private static final String TEST_EMAIL = "email@server.com";
+
     private static final String TEST_CC_NUMBER = "4111111111111111";
     private static final String TEST_CC_CSC = "123";
     private static final int TEST_CC_EXP_MONTH = 11;
     private static final int TEST_CC_EXP_YEAR = 2015;
+
     private static final String TEST_BILLING1 = "123 Main street";
     private static final String TEST_BILLING2 = "apt 456";
+    private static final String TEST_BILLING3 = "leave at the office";
+    private static final String TEST_BILLING_STREET =
+            TEST_BILLING1 + "\n" + TEST_BILLING2 + "\n" + TEST_BILLING3;
     private static final String TEST_BILLING_CITY = "Schenectady";
+    private static final String TEST_BILLING_DL = "";  // dependent locality
     private static final String TEST_BILLING_STATE = "NY";
     private static final String TEST_BILLING_ZIP = "12345";
+    private static final String TEST_BILLING_SORTING_CODE = "";  // sorting code
     private static final String TEST_BILLING_COUNTRY = "US";
+    private static final String TEST_BILLING_LANGUAGE = "";  // language
+
     private static final String TEST_SHIPPING_NAME = "Mister Receiver";
     private static final String TEST_SHIPPING_PHONE = "+46 8 713 99 99";
     private static final String TEST_SHIPPING_PHONE_UNFORMATTED = "4687139999";
     private static final String TEST_SHIPPING1 = "19 Farstaplan";
     private static final String TEST_SHIPPING2 = "Third floor";
+    private static final String TEST_SHIPPING3 = "please call first";
+    private static final String TEST_SHIPPING_STREET =
+            TEST_SHIPPING1 + "\n" + TEST_SHIPPING2 + "\n" + TEST_SHIPPING3;
     private static final String TEST_SHIPPING_CITY = "Farsta";
+    private static final String TEST_SHIPPING_DL = "";  // dependent locality
     private static final String TEST_SHIPPING_STATE = "Stockholm";
     private static final String TEST_SHIPPING_ZIP = "12346";
+    private static final String TEST_SHIPPING_SORTING_CODE = "";  // sorting code
     private static final String TEST_SHIPPING_COUNTRY = "SE";
+    private static final String TEST_SHIPPING_LANGUAGE = "";  // language
 
     private static final String HTML_PRELUDE = "<html>"
             + "<head>"
@@ -109,18 +125,20 @@
                 + "  <option value=\"2015\">2015</option>"
                 + "</select>"
                 + "<input id=\"id-cc-csc\" autocomplete=\"cc-csc\" value=\"W\">"
-                + "<select id=\"id-cc-country\" autocomplete=\"billing country\">"
-                + "  <option value=\"NL\" selected>Netherlands</option>"
-                + "  <option value=\"US\">United States</option>"
-                + "  <option value=\"SE\">Sweden</option>"
-                + "  <option value=\"RU\">Russia</option>"
-                + "</select>"
                 + "<input id=\"id-cc-zip\" autocomplete=\"billing postal-code\" value=\"W\">");
         if (requestFullBilling) {
             sb.append("<input id=\"id-cc-1\" autocomplete=\"billing address-line1\" value=\"W\">"
                     + "<input id=\"id-cc-2\" autocomplete=\"billing address-line2\" value=\"W\">"
+                    + "<textarea id=\"id-cc-str\""
+                    + "    autocomplete=\"billing street-address\">W</textarea>"
                     + "<input id=\"id-cc-city\" autocomplete=\"billing locality\" value=\"W\">"
-                    + "<input id=\"id-cc-state\" autocomplete=\"billing region\" value=\"W\">");
+                    + "<input id=\"id-cc-state\" autocomplete=\"billing region\" value=\"W\">"
+                    + "<select id=\"id-cc-country\" autocomplete=\"billing country\">"
+                    + "  <option value=\"NL\" selected>Netherlands</option>"
+                    + "  <option value=\"US\">United States</option>"
+                    + "  <option value=\"SE\">Sweden</option>"
+                    + "  <option value=\"RU\">Russia</option>"
+                    + "</select>");
         }
         sb.append("</fieldset>");
         if (requestShipping) {
@@ -129,6 +147,8 @@
                     + "<input id=\"id-h-name\" autocomplete=\"shipping name\" value=\"W\">"
                     + "<input id=\"id-h-1\" autocomplete=\"shipping address-line1\" value=\"W\">"
                     + "<input id=\"id-h-2\" autocomplete=\"shipping address-line2\" value=\"W\">"
+                    + "<textarea id=\"id-h-str\""
+                    + "    autocomplete=\"shipping street-address\">W</textarea>"
                     + "<input id=\"id-h-city\" autocomplete=\"shipping locality\" value=\"W\">"
                     + "<input id=\"id-h-state\" autocomplete=\"shipping region\" value=\"W\">"
                     + "<input id=\"id-h-zip\" autocomplete=\"shipping postal-code\" value=\"W\">"
@@ -344,7 +364,7 @@
                 + "  <option value=\"SE\">Sweden</option>"
                 + "  <option value=\"RU\">Russia</option>"
                 + "</select>",
-                TEST_BILLING_COUNTRY, "id", false, false, false);
+                TEST_BILLING_COUNTRY, "id", true, false, false);
     }
 
     @SmallTest
@@ -373,6 +393,14 @@
 
     @SmallTest
     @Feature({"autofill"})
+    public void testRacTypeBillingStreetAddress() throws InterruptedException, TimeoutException {
+        verifyOneFieldWithCc(
+                "<textarea id=\"id\" autocomplete=\"billing street-address\"></textarea>",
+                TEST_BILLING_STREET, "id", true, false, false);
+    }
+
+    @SmallTest
+    @Feature({"autofill"})
     public void testRacTypeBillingLocality() throws InterruptedException, TimeoutException {
         verifyOneFieldWithCc(
                 "<input id=\"id\" autocomplete=\"billing locality\">",
@@ -426,6 +454,14 @@
 
     @SmallTest
     @Feature({"autofill"})
+    public void testRacTypeShippingStreetAddress() throws InterruptedException, TimeoutException {
+        verifyOneFieldWithCc(
+                "<textarea id=\"id\" autocomplete=\"shipping street-address\"></textarea>",
+                TEST_SHIPPING_STREET, "id", false, true, false);
+    }
+
+    @SmallTest
+    @Feature({"autofill"})
     public void testRacTypeShippingLocality() throws InterruptedException, TimeoutException {
         verifyOneFieldWithCc(
                 "<input id=\"id\" autocomplete=\"shipping locality\">",
@@ -543,8 +579,6 @@
                 "" + TEST_CC_EXP_YEAR,
                 DOMUtils.getNodeValue(viewCore, "id-cc-exp-year"));
 
-        assertEquals("billing country did not match",
-                TEST_BILLING_COUNTRY, DOMUtils.getNodeValue(viewCore, "id-cc-country"));
         assertEquals("billing postal-code did not match",
                 TEST_BILLING_ZIP, DOMUtils.getNodeValue(viewCore, "id-cc-zip"));
 
@@ -553,10 +587,14 @@
                     TEST_BILLING1, DOMUtils.getNodeValue(viewCore, "id-cc-1"));
             assertEquals("billing address-line2 did not match",
                     TEST_BILLING2, DOMUtils.getNodeValue(viewCore, "id-cc-2"));
+            assertEquals("billing street-address did not match",
+                    TEST_BILLING_STREET, DOMUtils.getNodeValue(viewCore, "id-cc-str"));
             assertEquals("billing locality did not match",
                     TEST_BILLING_CITY, DOMUtils.getNodeValue(viewCore, "id-cc-city"));
             assertEquals("billing region did not match",
                     TEST_BILLING_STATE, DOMUtils.getNodeValue(viewCore, "id-cc-state"));
+            assertEquals("billing country did not match",
+                    TEST_BILLING_COUNTRY, DOMUtils.getNodeValue(viewCore, "id-cc-country"));
 
             if (requestPhoneNumbers) {
                 assertEquals("billing tel did not match",
@@ -574,6 +612,8 @@
                     TEST_SHIPPING1, DOMUtils.getNodeValue(viewCore, "id-h-1"));
             assertEquals("shipping address-line2 did not match",
                     TEST_SHIPPING2, DOMUtils.getNodeValue(viewCore, "id-h-2"));
+            assertEquals("shipping street-address did not match",
+                    TEST_SHIPPING_STREET, DOMUtils.getNodeValue(viewCore, "id-h-str"));
             assertEquals("shipping locality did not match",
                     TEST_SHIPPING_CITY, DOMUtils.getNodeValue(viewCore, "id-h-city"));
             assertEquals("shipping region did not match",
@@ -639,12 +679,16 @@
                         TEST_CC_NUMBER, TEST_CC_CSC),
                 new AutofillDialogResult.ResultAddress(
                         TEST_NAME, TEST_PHONE,
-                        TEST_BILLING1, TEST_BILLING2, TEST_BILLING_CITY, TEST_BILLING_STATE,
-                        TEST_BILLING_ZIP, TEST_BILLING_COUNTRY),
+                        TEST_BILLING_STREET,
+                        TEST_BILLING_CITY, TEST_BILLING_DL, TEST_BILLING_STATE,
+                        TEST_BILLING_ZIP, TEST_BILLING_SORTING_CODE, TEST_BILLING_COUNTRY,
+                        TEST_BILLING_LANGUAGE),
                 new AutofillDialogResult.ResultAddress(
                         TEST_SHIPPING_NAME, TEST_SHIPPING_PHONE,
-                        TEST_SHIPPING1, TEST_SHIPPING2, TEST_SHIPPING_CITY, TEST_SHIPPING_STATE,
-                        TEST_SHIPPING_ZIP, TEST_SHIPPING_COUNTRY));
+                        TEST_SHIPPING_STREET,
+                        TEST_SHIPPING_CITY, TEST_SHIPPING_DL, TEST_SHIPPING_STATE,
+                        TEST_SHIPPING_ZIP, TEST_SHIPPING_SORTING_CODE, TEST_SHIPPING_COUNTRY,
+                        TEST_SHIPPING_LANGUAGE));
         MockAutofillDialogController.installMockFactory(
                 DIALOG_CALLBACK_DELAY_MILLISECONDS,
                 result,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java
index 8abd24a..6e696f7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillPopupTest.java
@@ -38,27 +38,32 @@
     private static final String COMPANY_NAME = "Acme Inc.";
     private static final String ADDRESS_LINE1 = "1 Main";
     private static final String ADDRESS_LINE2 = "Apt A";
+    private static final String STREET_ADDRESS_TEXTAREA = ADDRESS_LINE1 + "\n" + ADDRESS_LINE2;
     private static final String CITY = "San Francisco";
+    private static final String DEPENDENT_LOCALITY = "";
     private static final String STATE = "CA";
     private static final String ZIP_CODE = "94102";
+    private static final String SORTING_CODE = "";
     private static final String COUNTRY = "US";
     private static final String PHONE_NUMBER = "4158889999";
     private static final String EMAIL = "john@acme.inc";
+    private static final String LANGUAGE_CODE = "";
     private static final String ORIGIN = "https://www.example.com";
 
     private static final String BASIC_PAGE_DATA = UrlUtils.encodeHtmlDataUri(
             "<html><head><meta name=\"viewport\"" +
             "content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0\" /></head>" +
             "<body><form method=\"POST\">" +
-            "<input type=\"text\" id=\"fn\" autocomplete=\"given-name\"><br>" +
-            "<input type=\"text\" id=\"ln\" autocomplete=\"family-name\"><br>" +
-            "<input type=\"text\" id=\"a1\" autocomplete=\"address-line1\"><br>" +
-            "<input type=\"text\" id=\"a2\" autocomplete=\"address-line2\"><br>" +
-            "<input type=\"text\" id=\"ct\" autocomplete=\"locality\"><br>" +
-            "<input type=\"text\" id=\"zc\" autocomplete=\"postal-code\"><br>" +
-            "<input type=\"text\" id=\"em\" autocomplete=\"email\"><br>" +
-            "<input type=\"text\" id=\"ph\" autocomplete=\"tel\"><br>" +
-            "<input type=\"text\" id=\"fx\" autocomplete=\"fax\"><br>" +
+            "<input type=\"text\" id=\"fn\" autocomplete=\"given-name\" /><br>" +
+            "<input type=\"text\" id=\"ln\" autocomplete=\"family-name\" /><br>" +
+            "<textarea id=\"sa\" autocomplete=\"street-address\"></textarea><br>" +
+            "<input type=\"text\" id=\"a1\" autocomplete=\"address-line1\" /><br>" +
+            "<input type=\"text\" id=\"a2\" autocomplete=\"address-line2\" /><br>" +
+            "<input type=\"text\" id=\"ct\" autocomplete=\"locality\" /><br>" +
+            "<input type=\"text\" id=\"zc\" autocomplete=\"postal-code\" /><br>" +
+            "<input type=\"text\" id=\"em\" autocomplete=\"email\" /><br>" +
+            "<input type=\"text\" id=\"ph\" autocomplete=\"tel\" /><br>" +
+            "<input type=\"text\" id=\"fx\" autocomplete=\"fax\" /><br>" +
             "<select id=\"co\" autocomplete=\"country\"><br>" +
             "<option value=\"BR\">Brazil</option>" +
             "<option value=\"US\">United States</option>" +
@@ -143,8 +148,11 @@
 
         // Add an Autofill profile.
         AutofillProfile profile = new AutofillProfile(
-                "" /* guid */, ORIGIN, FIRST_NAME + " " + LAST_NAME, COMPANY_NAME, ADDRESS_LINE1,
-                ADDRESS_LINE2, CITY, STATE, ZIP_CODE, COUNTRY, PHONE_NUMBER, EMAIL);
+                "" /* guid */, ORIGIN, FIRST_NAME + " " + LAST_NAME, COMPANY_NAME,
+                STREET_ADDRESS_TEXTAREA,
+                STATE, CITY, DEPENDENT_LOCALITY,
+                ZIP_CODE, SORTING_CODE, COUNTRY, PHONE_NUMBER, EMAIL,
+                LANGUAGE_CODE);
         mHelper.setProfile(profile);
         assertEquals(1, mHelper.getNumberOfProfiles());
 
@@ -163,7 +171,7 @@
         });
 
         waitForAnchorViewAdd(view);
-        View anchorView = view.findViewById(R.id.autofill_popup_window);
+        View anchorView = view.findViewById(R.id.dropdown_popup_window);
 
         assertTrue(anchorView.getTag() instanceof AutofillPopup);
         final AutofillPopup popup = (AutofillPopup) anchorView.getTag();
@@ -191,6 +199,8 @@
                 FIRST_NAME, DOMUtils.getNodeValue(viewCore, "fn"));
         assertEquals("Last name did not match",
                 LAST_NAME, DOMUtils.getNodeValue(viewCore, "ln"));
+        assertEquals("Street address (textarea) did not match",
+                STREET_ADDRESS_TEXTAREA, DOMUtils.getNodeValue(viewCore, "sa"));
         assertEquals("Address line 1 did not match",
                 ADDRESS_LINE1, DOMUtils.getNodeValue(viewCore, "a1"));
         assertEquals("Address line 2 did not match",
@@ -207,11 +217,12 @@
                 PHONE_NUMBER, DOMUtils.getNodeValue(viewCore, "ph"));
 
         final String profileFullName = FIRST_NAME + " " + LAST_NAME;
-        final int loggedEntries = 9;
+        final int loggedEntries = 10;
         assertEquals("Mismatched number of logged entries",
                 loggedEntries, mAutofillLoggedEntries.size());
         assertLogged(FIRST_NAME, profileFullName);
         assertLogged(LAST_NAME, profileFullName);
+        assertLogged(STREET_ADDRESS_TEXTAREA, profileFullName);
         assertLogged(ADDRESS_LINE1, profileFullName);
         assertLogged(ADDRESS_LINE2, profileFullName);
         assertLogged(CITY, profileFullName);
@@ -295,7 +306,7 @@
                 CriteriaHelper.pollForCriteria(new Criteria() {
                     @Override
                     public boolean isSatisfied() {
-                        return view.findViewById(R.id.autofill_popup_window) != null;
+                        return view.findViewById(R.id.dropdown_popup_window) != null;
                     }
                 }));
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java
index b7c097a..8bb4072 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java
@@ -108,7 +108,7 @@
         UiUtils.runOnUiThread(getActivity(), new Runnable() {
             @Override
             public void run() {
-                mAutofillPopup.show(suggestions);
+                mAutofillPopup.filterAndShow(suggestions);
             }
         });
         return CriteriaHelper.pollForCriteria(new Criteria() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/MockAutofillDialogController.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/MockAutofillDialogController.java
index f401c5e..063c9da 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/MockAutofillDialogController.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/MockAutofillDialogController.java
@@ -53,7 +53,8 @@
                     final String initialBillingGuid,
                     final String initialShippingGuid,
                     final String initialCardGuid,
-                    final String merchantDomain) {
+                    final String merchantDomain,
+                    final String[] shippingCountries) {
                 Assert.assertEquals("Full billing details flag doesn't match",
                         shouldRequestFullBilling, requestFullBillingAddress);
                 Assert.assertEquals("Shipping details flag doesn't match",
@@ -75,7 +76,8 @@
                         incognitoMode,
                         initialChoiceIsAutofill, initialWalletAccountName,
                         initialBillingGuid, initialShippingGuid, initialCardGuid,
-                        merchantDomain);
+                        merchantDomain,
+                        shippingCountries);
             }
         });
     }
@@ -96,7 +98,8 @@
             final boolean initialChoiceIsAutofill, final String initialWalletAccountName,
             final String initialBillingGuid, final String initialShippingGuid,
             final String initialCardGuid,
-            final String merchantDomain) {
+            final String merchantDomain,
+            final String[] shippingCountries) {
         mDelegate = delegate;
         mResult = result;
         mLastUsedChoiceIsAutofill = lastUsedChoiceIsAutofill;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/PersonalDataManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/PersonalDataManagerTest.java
index b2f8107..38a0b28 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/PersonalDataManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/PersonalDataManagerTest.java
@@ -35,38 +35,74 @@
     public void testAddAndEditProfiles() throws InterruptedException, ExecutionException {
         AutofillProfile profile = new AutofillProfile(
                 "" /* guid */, "https://www.example.com" /* origin */,
-                "John Smith", "Acme Inc.", "1 Main", "Apt A", "San Francisco", "CA",
-                "94102", "US", "4158889999", "john@acme.inc");
+                "John Smith", "Acme Inc.",
+                "1 Main\nApt A", "CA", "San Francisco", "",
+                "94102", "",
+                "US", "4158889999", "john@acme.inc", "");
         String profileOneGUID = mHelper.setProfile(profile);
         assertEquals(1, mHelper.getNumberOfProfiles());
 
         AutofillProfile profile2 = new AutofillProfile(
                 "" /* guid */, "http://www.example.com" /* origin */,
-                "John Hackock", "Acme Inc.", "1 Main", "Apt A", "San Francisco", "CA",
-                "94102", "US", "4158889999", "john@acme.inc");
+                "John Hackock", "Acme Inc.",
+                "1 Main\nApt A", "CA", "San Francisco", "",
+                "94102", "",
+                "US", "4158889999", "john@acme.inc", "");
         String profileTwoGUID = mHelper.setProfile(profile2);
         assertEquals(2, mHelper.getNumberOfProfiles());
 
         profile.setGUID(profileOneGUID);
         profile.setCountry("Canada");
         mHelper.setProfile(profile);
-        assertEquals("Should still have only two profile", 2, mHelper.getNumberOfProfiles());
+        assertEquals("Should still have only two profiles", 2, mHelper.getNumberOfProfiles());
 
         AutofillProfile storedProfile = mHelper.getProfile(profileOneGUID);
         assertEquals(profileOneGUID, storedProfile.getGUID());
         assertEquals("https://www.example.com", storedProfile.getOrigin());
         assertEquals("CA", storedProfile.getCountryCode());
-        assertEquals("San Francisco", storedProfile.getCity());
+        assertEquals("San Francisco", storedProfile.getLocality());
         assertNotNull(mHelper.getProfile(profileTwoGUID));
     }
 
     @SmallTest
     @Feature({"Autofill"})
+    public void testUpdateLanguageCodeInProfile() throws InterruptedException, ExecutionException {
+        AutofillProfile profile = new AutofillProfile(
+                "" /* guid */, "https://www.example.com" /* origin */,
+                "John Smith", "Acme Inc.",
+                "1 Main\nApt A", "CA", "San Francisco", "",
+                "94102", "",
+                "US", "4158889999", "john@acme.inc", "fr");
+        assertEquals("fr", profile.getLanguageCode());
+        String profileOneGUID = mHelper.setProfile(profile);
+        assertEquals(1, mHelper.getNumberOfProfiles());
+
+        AutofillProfile storedProfile = mHelper.getProfile(profileOneGUID);
+        assertEquals(profileOneGUID, storedProfile.getGUID());
+        assertEquals("fr", storedProfile.getLanguageCode());
+        assertEquals("US", storedProfile.getCountryCode());
+
+        profile.setGUID(profileOneGUID);
+        profile.setLanguageCode("en");
+        mHelper.setProfile(profile);
+
+        AutofillProfile storedProfile2 = mHelper.getProfile(profileOneGUID);
+        assertEquals(profileOneGUID, storedProfile2.getGUID());
+        assertEquals("en", storedProfile2.getLanguageCode());
+        assertEquals("US", storedProfile2.getCountryCode());
+        assertEquals("San Francisco", storedProfile2.getLocality());
+        assertEquals("https://www.example.com", storedProfile2.getOrigin());
+    }
+
+    @SmallTest
+    @Feature({"Autofill"})
     public void testAddAndDeleteProfile() throws InterruptedException, ExecutionException {
         AutofillProfile profile = new AutofillProfile(
                 "" /* guid */, "Chrome settings" /* origin */,
-                "John Smith", "Acme Inc.", "1 Main", "Apt A", "San Francisco", "CA",
-                "94102", "US", "4158889999", "john@acme.inc");
+                "John Smith", "Acme Inc.",
+                "1 Main\nApt A", "CA", "San Francisco", "",
+                "94102", "",
+                "US", "4158889999", "john@acme.inc", "");
         String profileOneGUID = mHelper.setProfile(profile);
         assertEquals(1, mHelper.getNumberOfProfiles());
 
@@ -125,14 +161,18 @@
         // getCountryCode() should return a country code.
         AutofillProfile profile1 = new AutofillProfile(
                 "" /* guid */, "https://www.example.com" /* origin */,
-                "John Smith", "Acme Inc.", "1 Main", "Apt A", "Montreal", "Quebec",
-                "H3B 2Y5", "Canada", "514-670-1234", "john@acme.inc");
+                "John Smith", "Acme Inc.",
+                "1 Main\nApt A", "Quebec", "Montreal", "",
+                "H3B 2Y5", "",
+                "Canada", "514-670-1234", "john@acme.inc", "");
         String profileGuid1 = mHelper.setProfile(profile1);
 
         AutofillProfile profile2 = new AutofillProfile(
                 "" /* guid */, "https://www.example.com" /* origin */,
-                "Greg Smith", "Ucme Inc.", "123 Bush", "Apt 125", "Montreal", "Quebec",
-                "H3B 2Y5", "CA", "514-670-4321", "greg@ucme.inc");
+                "Greg Smith", "Ucme Inc.",
+                "123 Bush\nApt 125", "Quebec", "Montreal", "",
+                "H3B 2Y5", "",
+                "CA", "514-670-4321", "greg@ucme.inc", "");
         String profileGuid2 = mHelper.setProfile(profile2);
 
         assertEquals(2, mHelper.getNumberOfProfiles());
diff --git a/chrome/android/shell/java/src/org/chromium/chrome/shell/TabManager.java b/chrome/android/shell/java/src/org/chromium/chrome/shell/TabManager.java
index 0032af4..b48a5bd 100644
--- a/chrome/android/shell/java/src/org/chromium/chrome/shell/TabManager.java
+++ b/chrome/android/shell/java/src/org/chromium/chrome/shell/TabManager.java
@@ -11,7 +11,10 @@
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
+import org.chromium.chrome.browser.EmptyTabObserver;
+import org.chromium.chrome.browser.Tab;
 import org.chromium.content.browser.ContentVideoViewClient;
+import org.chromium.content.browser.ContentView;
 import org.chromium.content.browser.ContentViewClient;
 import org.chromium.content.browser.ContentViewRenderView;
 import org.chromium.ui.base.WindowAndroid;
@@ -33,6 +36,7 @@
     private ChromeShellTab mCurrentTab;
 
     private String mStartupUrl = DEFAULT_URL;
+    private ContentView mCurrentContentView;
 
     /**
      * @param context The Context the view is running in.
@@ -122,11 +126,24 @@
         }
 
         mCurrentTab = tab;
+        mCurrentContentView = tab.getContentView();
+
+        mCurrentTab.addObserver(new EmptyTabObserver() {
+            @Override
+            public void onContentChanged(Tab tab) {
+                mContentViewHolder.removeView(mCurrentContentView);
+                setupContent(tab);
+            }
+        });
 
         mToolbar.showTab(mCurrentTab);
-        mContentViewHolder.addView(mCurrentTab.getContentView());
-        mContentViewRenderView.setCurrentContentViewCore(mCurrentTab.getContentViewCore());
-        mCurrentTab.getContentView().requestFocus();
-        mCurrentTab.getContentViewCore().onShow();
+        setupContent(mCurrentTab);
+    }
+
+    private void setupContent(Tab tab) {
+        mContentViewHolder.addView(tab.getContentView());
+        mContentViewRenderView.setCurrentContentViewCore(tab.getContentViewCore());
+        tab.getContentView().requestFocus();
+        tab.getContentViewCore().onShow();
     }
 }
diff --git a/chrome/app/bookmarks_strings.grdp b/chrome/app/bookmarks_strings.grdp
index a37a574..56d3c5f 100644
--- a/chrome/app/bookmarks_strings.grdp
+++ b/chrome/app/bookmarks_strings.grdp
@@ -324,15 +324,6 @@
   </if>
   <!-- End of Bookmarks Editor strings. -->
 
-  <!-- Begin of Bookmarks Prompt strings. -->
-  <message name="IDS_BOOKMARK_PROMPT_MESSAGE" desc="Message of bookmark prompt">
-    Like this site? Click here to bookmark it!
-  </message>
-  <message name="IDS_BOOKMARK_PROMPT_DISMISS" desc="Link for dismissing bookmark prompt">
-    Dismiss
-  </message>
-  <!-- End of Bookmarks Prompt strings. -->
-
   <!-- Begin of Bookmarks Manager strings. -->
   <message name="IDS_BOOKMARK_MANAGER_TITLE" desc="Title of the bookmark manager window.">
     Bookmark Manager
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h
index 5115b19..fdff03d 100644
--- a/chrome/app/chrome_command_ids.h
+++ b/chrome/app/chrome_command_ids.h
@@ -86,8 +86,8 @@
 #define IDC_EMAIL_PAGE_LOCATION         35006
 #define IDC_ADVANCED_PRINT              35007
 #define IDC_PRINT_TO_DESTINATION        35008
-#define IDC_BOOKMARK_PAGE_FROM_STAR     35009
-#define IDC_TRANSLATE_PAGE              35010
+#define IDC_TRANSLATE_PAGE              35009
+#define IDC_MANAGE_PASSWORDS_FOR_PAGE   35010
 
 // When adding a new encoding to this list, be sure to append it to the
 // EncodingMenuController::kValidEncodingIds array in
@@ -344,11 +344,6 @@
 // Context menu items in the status tray
 #define IDC_STATUS_TRAY_KEEP_CHROME_RUNNING_IN_BACKGROUND 51100
 
-// Context menu items for speech recognition
-#define IDC_SPEECH_INPUT_MENU 51200
-#define IDC_CONTENT_CONTEXT_SPEECH_INPUT_FILTER_PROFANITIES 51201
-#define IDC_CONTENT_CONTEXT_SPEECH_INPUT_ABOUT 51202
-
 // Context menu items for media stream status tray
 #define IDC_MEDIA_STREAM_DEVICE_STATUS_TRAY 51300
 #define IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_LIST_FIRST 51301
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index f8f76ff..2c29876 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -339,7 +339,7 @@
     std::string user_data_dir_string;
     scoped_ptr<base::Environment> environment(base::Environment::Create());
     if (environment->GetVar("CHROME_USER_DATA_DIR", &user_data_dir_string) &&
-        IsStringUTF8(user_data_dir_string)) {
+        base::IsStringUTF8(user_data_dir_string)) {
       user_data_dir = base::FilePath::FromUTF8Unsafe(user_data_dir_string);
     }
   }
@@ -350,7 +350,7 @@
 
   const bool specified_directory_was_invalid = !user_data_dir.empty() &&
       !PathService::OverrideAndCreateIfNeeded(chrome::DIR_USER_DATA,
-          user_data_dir, true);
+          user_data_dir, false, true);
   // Save inaccessible or invalid paths so the user may be prompted later.
   if (specified_directory_was_invalid)
     chrome::SetInvalidSpecifiedUserDataDir(user_data_dir);
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index bcff7a7..30e4a7b 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -429,6 +429,9 @@
   <message name="IDS_FILE_BROWSER_PASTE_BUTTON_LABEL" desc="Button Label.">
     Paste
   </message>
+  <message name="IDS_FILE_BROWSER_PASTE_INTO_FOLDER_BUTTON_LABEL" desc="Menu item label, pasting files into the selected folder.">
+    Paste into folder
+  </message>
   <message name="IDS_FILE_BROWSER_COPY_BUTTON_LABEL" desc="Button Label.">
     Copy
   </message>
@@ -1235,6 +1238,9 @@
   <message name="IDS_LANGUAGES_MEDIUM_LEN_NAME_KOREAN" desc="Medium length name for the input method for Korean which is show following the text: Your input method has changed to...">
     Korean
   </message>
+  <message name="IDS_LANGUAGES_MEDIUM_LEN_NAME_BRAILLE" desc="Medium length name for the input method for the hardware keyboard on a braille display. Shown after the text: Your input method has changed to...">
+    Braille
+  </message>
   <message name="IDS_KEYBOARD_SELECTION_SELECT" desc="Label for keyboard selection dropdown">
     Select your keyboard:
   </message>
@@ -1260,10 +1266,13 @@
     Bluetooth mouse paired
   </message>
   <message name="IDS_HID_DETECTION_PAIRED_BLUETOOTH_KEYBOARD" desc="Text shown on HID detection screen next to keyboard icon after Bluetooth keyboard is connected.">
-    "<ph name="DEVICE_NAME">%1<ex>Bluetooth Keyboard</ex></ph>" paired
+    "<ph name="DEVICE_NAME">$1<ex>Bluetooth Keyboard</ex></ph>" paired
   </message>
   <message name="IDS_HID_DETECTION_BLUETOOTH_REMOTE_PIN_CODE_REQUEST" desc="Bluetooth pairing message displayed on HID detection screen when pairing a Bluetooth keyboard.">
-    Type this code on "<ph name="DEVICE_NAME">%1<ex>Nexus S</ex></ph>" to pair:
+    Type this code on "<ph name="DEVICE_NAME">$1<ex>Nexus S</ex></ph>" to pair:
+  </message>
+  <message name="IDS_HID_DETECTION_DEFAULT_KEYBOARD_NAME" desc="Default keyboard name used at HID-detection labels and messages at HID-detection OOBE screen.">
+    Unknown keyboard
   </message>
   <message name="IDS_HID_DETECTION_BLUETOOTH_ENTER_KEY" meaning="Label on the button representing Enter key at the HID detection screen.">
     enter
@@ -1413,8 +1422,14 @@
   <message name="IDS_LOGIN_CONFIRM_PASSWORD_ERROR_TEXT" desc="Error text to show when the password typed by the user could not be verified.">
     Sorry, your password could not be verified. Please try again.
   </message>
-  <message name="IDS_LOGIN_FATAL_ERROR_MESSAGE" desc="Message to show when the authentication could not be completed.">
-    Something went wrong with signing in.<ph name="LINE_BREAK">&lt;br&gt;</ph>Please contact your administrator or try again.
+  <message name="IDS_LOGIN_FATAL_ERROR_TEXT_GENERIC" desc="Message to show when the authentication could not be completed due to an unspecified error.">
+    Something went wrong with signing in.
+  </message>
+  <message name="IDS_LOGIN_FATAL_ERROR_TEXT_INSECURE_URL" desc="Message to show when the authentication could not be completed because a redirect to an insecure URL was detected and blocked.">
+    Oops, couldn't sign you in. Sign-in failed because it was configured to use a non-secure URL (<ph name="BLOCKED_URL">$1<ex>http://www.example.com/login.html</ex></ph>).
+  </message>
+  <message name="IDS_LOGIN_FATAL_ERROR_INSTRUCTIONS" desc="Instructions shown below the error message when authentication could not be completed.">
+    Please contact your administrator or try again.
   </message>
   <message name="IDS_LOGIN_OFFLINE_EMAIL" desc="Email field text on the offline login screen. Note: should by the same as the one used on the Gaia sign-in page.">
     Email
@@ -4626,6 +4641,9 @@
   <message name="IDS_LOGIN_ERROR_AUTHENTICATING_2ND_TIME" desc="Couldn't sign in because password is invalid for the 2nd time">
     Sorry, your password still could not be verified. Note: if you changed your password recently, your new password will be applied once you sign out, please use the old password here.
   </message>
+  <message name="IDS_LOGIN_ERROR_AUTHENTICATING_2ND_TIME_SUPERVISED" desc="Supervised user couldn't sign in because password is invalid for the 2nd time">
+    Sorry, your password could not be verified. The manager of this supervised user may have changed the password recently. If so, the new password will be applied the next time you sign in. Try using your old password.
+  </message>
   <message name="IDS_LOGIN_ERROR_PASSWORD_CHANGED" desc="Couldn't log in because password specified matched as old one, but not new one (online) - password change has been detected.">
     Your password has changed. Please try again with your new password.
   </message>
@@ -5155,6 +5173,9 @@
   <message name="IDS_ENTERPRISE_ENROLLMENT_STATUS_REGISTRATION_FAILED" desc="Error message shown on the enrollment screen upon failed device registration.">
     Error when registering the device with the server: <ph name="CLIENT_ERROR">$1<ex>Failed to connect to the server</ex></ph>.
   </message>
+  <message name="IDS_ENTERPRISE_ENROLLMENT_STATUS_NO_STATE_KEYS" desc="Error message shown on the enrollment screen when the system failed to determine server-backed state keys.">
+    Oops!  The system failed to determine device identifiers for this device.
+  </message>
   <message name="IDS_ENTERPRISE_ENROLLMENT_STATUS_REGISTRATION_BAD_MODE" desc="Error message shown on the enrollment screen upon receiving a bad mode on device registration.">
     The supplied enrollment mode is not supported by this version of the operating system.  Please make sure you are running the newest version and try again.
   </message>
@@ -5195,6 +5216,9 @@
   <message name="IDS_ENTERPRISE_ENROLLMENT_AUTH_NETWORK_ERROR" desc="Error message to show when there is a network problem when authenticating for enrollment.">
     Oops!  A network communication problem occurred during authentication.  Please check your network connection and try again.
   </message>
+  <message name="IDS_ENTERPRISE_ENROLLMENT_AUTH_INSECURE_URL_ERROR" desc="Error message to show when a redirect to an insecure URL was detected and blocked when authenticating for enrollment.">
+    Oops!  Authentication failed because it was configured to use a non-secure URL (<ph name="BLOCKED_URL">$1<ex>http://www.example.com/login.html</ex></ph>).  Please contact your administrator.
+  </message>
   <message name="IDS_ENTERPRISE_AUTO_ENROLLMENT_BAD_MODE" desc="Error message to show when auto-enrollment is not supported for the enrollment mode supplied by the DMServer.">
     Oops!  Something went wrong while auto-enrolling this device.  Please try again from the sign-in screen using the Ctrl-Alt-E key combination, or contact your support representative.
   </message>
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index bb335a5..ca46a32 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -345,9 +345,6 @@
       <message name="IDS_BROWSER_HUNGBROWSER_MESSAGE" desc="Content of the dialog box shown when the browser is hung">
         Chromium is unresponsive. Relaunch now?
       </message>
-      <message name="IDS_IMPORT_PROGRESS_INFO" desc="Explanatory text for the importing progress dialog">
-        Chromium is now importing the following items from <ph name="BROWSER_COMPONENT">$1<ex>History</ex></ph>:
-      </message>
       <message name="IDS_IMPORT_FIND_YOUR_BOOKMARKS" desc="Helpful reminder for where to find imported bookmarks">
         Find your bookmarks in the Chromium menu or on the bookmarks bar.
       </message>
@@ -404,12 +401,11 @@
         </message>
       </if>
       <!-- Strings used to warn that an OS is not supported -->
-      <message name="IDS_UNSUPPORTED_OS_PRE_WIN_XP" desc="The text used to warn the user that Windows pre-XP is not supported">
-        Chromium requires Windows XP or later. Some features may not work.
-      </message>
-      <message name="IDS_UNSUPPORTED_OS" desc="The text used to warn the user that current OS is not supported">
-        Chromium does not support <ph name="OS_NAME">$1<ex>Windows 2000</ex></ph>.
-      </message>
+      <if expr="is_win">
+        <message name="IDS_UNSUPPORTED_OS_PRE_WIN_XP" desc="The text used to warn the user that Windows pre-XP is not supported">
+          Chromium requires Windows XP or later. Some features may not work.
+        </message>
+      </if>
       <if expr="not chromeos">
         <message name="IDS_OPTIONS_RELAUNCH_REQUIRED" desc="The message displayed for an option that requires a relaunch to take effect. This appears in a message box if an option is changed that requires a relaunch.">
           Please close all Chromium windows and relaunch Chromium for this change to take effect.
@@ -469,6 +465,9 @@
       <message name="IDS_CRASH_RECOVERY_CONTENT" desc="Text content telling the user the browser has crashed.">
         Whoa! Chromium has crashed. Relaunch now?
       </message>
+      <message name="IDS_PASSWORD_GENERATION_SUGGESTION" desc="Text shown next to a generated password describing it as a suggestion.">
+        Suggested by Chromium
+      </message>
       <if expr="not is_android">
         <message name="IDS_PASSWORD_MANAGER_SAVE_PASSWORD_PROMPT" desc="Info bar message to save a password">
           Do you want Chromium to save your password?
@@ -537,9 +536,6 @@
       <message name="IDS_OPTIONS_IMPROVE_BROWSING_EXPERIENCE" desc="The text in the options panel that describes how we use web services to improve browsing experience.">
         Chromium may use web services to improve your browsing experience.
       </message>
-      <message name="IDS_IMPORT_BOOKMARKS" desc="Explanatory text for the importing progress dialog when importing a bookmarks.html file from the bookmark manager">
-        Chromium is now importing Favorites/Bookmarks.
-      </message>
       <message name="IDS_OEM_MAIN_SHORTCUT_NAME" desc="Name of the desktop shortcut to start the application for OEM pre-installations.">
         Internet Browser
       </message>
@@ -773,7 +769,7 @@
       </message>
 
       <if expr="enable_extensions">
-        <message name="IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BODY" desc="Body of the dialog shown when suspicious extensions have been disabled">
+        <message name="IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BODY" desc="Body of the dialog shown when unsupported extensions have been disabled">
           To make Chromium safer, we disabled some extensions that aren't listed in the <ph name="IDS_EXTENSION_WEB_STORE_TITLE">$1<ex>Chrome Web Store</ex></ph> and may have been added without your knowledge.
         </message>
       </if>
@@ -841,7 +837,7 @@
 
       <!-- Account removal view in the avatar menu bubble -->
       <message name="IDS_PROFILES_ACCOUNT_REMOVAL_TEXT" desc="Main text of the account removal view when removing a secondary account.">
-        To remove your account, Chromium needs to restart. Make sure you've saved any open work before continuing.
+        After removing your account from Chromium, you may need to reload your open tabs to take effect.
       </message>
       <message name="IDS_PROFILES_PRIMARY_ACCOUNT_REMOVAL_TEXT" desc="Main text of the account removal view when removing a primary account.">
         You're using <ph name="PROFILE_EMAIL">$1<ex>jessica@gmail.com</ex></ph> to sync your Chromium stuff. To update your sync preference or to use Chromium without a Google account, visit <ph name="SETTINGS_LINK">$2<ex>settings</ex></ph>.
@@ -942,13 +938,14 @@
         </message>
       </if>
 
-      <message name="IDS_OPTIONS_PASSWORDS_MAC_WARNING" desc="The warning for OS X that passwords are shared across profiles in the keychain.">
-        On Mac, passwords are saved to your Keychain and may be accessed or synced by other Chromium users sharing this OS X account.
-      </message>
-
-      <message name="IDS_AUTOFILL_ADDRESS_BOOK_PROMPT_DESCRIPTION" desc="Text to show in dialog requesting permission to access the user's Address Book contents.">
-        Details from your contacts can help you fill out forms more quickly in Chromium.
-      </message>
+      <if expr="is_macosx">
+        <message name="IDS_OPTIONS_PASSWORDS_MAC_WARNING" desc="The warning for OS X that passwords are shared across profiles in the keychain.">
+          On Mac, passwords are saved to your Keychain and may be accessed or synced by other Chromium users sharing this OS X account.
+        </message>
+        <message name="IDS_AUTOFILL_ADDRESS_BOOK_PROMPT_DESCRIPTION" desc="Text to show in dialog requesting permission to access the user's Address Book contents.">
+          Details from your contacts can help you fill out forms more quickly in Chromium.
+        </message>
+      </if>
       <message name="IDS_AUTOFILL_CC_INFOBAR_TEXT" desc="Text to show in the Autofill credit card request infobar.">
         Do you want Chromium to save this credit card information for completing web forms?
       </message>
@@ -1202,16 +1199,6 @@
       <message name="IDS_UPGRADE_BUBBLE_REENABLE_TEXT" desc="Text for the upgrade bubble view full description.">
         Chromium could not update itself to the latest version, so you are missing out on awesome new features and security fixes. You need to update Chromium.
       </message>
-
-      <!-- chrome://ntp -->
-      <if expr="not is_android">
-        <message name="IDS_NEW_TAB_OTR_EXTENSIONS_MESSAGE"
-                 desc="Explanation in a new OTR window that extensions have been disabled while in OTR.">
-          Because Chromium does not control how extensions handle your personal data, all extensions have been disabled for incognito windows. You can reenable them individually in the
-          <ph name="BEGIN_LINK">&lt;a href="$1"&gt;</ph>extensions manager<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>.
-        </message>
-      </if>
-
     </messages>
   </release>
 </grit>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 4f3e6ff..8e94f45 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -2282,6 +2282,9 @@
       <message name="IDS_CREATE_SHORTCUTS_MENU_CHKBOX" desc="Label of the checkbox to create an application shortcut in the system's applications menu.">
         Applications menu
       </message>
+      <message name="IDS_CREATE_SHORTCUTS_APP_FOLDER_CHKBOX" desc="Label of the checkbox to create an application shortcut in the system's applications folder.">
+        Applications folder
+      </message>
       <message name="IDS_CREATE_SHORTCUTS_START_MENU_CHKBOX" desc="Label of the checkbox to create an application shortcut in the start menu.">
         Start menu
       </message>
@@ -4361,9 +4364,6 @@
       <message name="IDS_EXTENSION_PROMPT_WARNING_SIGNED_IN_DEVICES" desc="Permission string for access to privacy settings.">
         Access the list of your signed-in devices
       </message>
-      <message name="IDS_EXTENSION_PROMPT_WARNING_USB" desc="Permission string for access to USB devices.">
-        Access USB devices
-      </message>
       <message name="IDS_EXTENSION_PROMPT_WARNING_HID" desc="Permission string for access to HID devices.">
         Access input devices over USB and Bluetooth
       </message>
@@ -4519,18 +4519,19 @@
       <message name="IDS_EXTENSION_WEBGL_NOT_SUPPORTED" desc="Error message when an extension has a requirement for WebGL that the system does not support.">
         WebGL is not supported.
       </message>
-      <message name="IDS_EXTENSION_CSS3D_NOT_SUPPORTED" desc="Error message when an extension has a requirement for CSS3d that the system does not support.">
-        CSS3d is not supported.
-      </message>
       <message name="IDS_EXTENSION_NPAPI_NOT_SUPPORTED" desc="Error message when an extension has a requirement for plugins that the system does not support.">
         NPAPI plugins are not supported.
       </message>
-      <message name="IDS_EXTENSION_WINDOW_SHAPE_NOT_SUPPORTED" desc="Error message when an extension has a requirement for shaped windows that the system does not support.">
-        Shaped windows are not supported.
-      </message>
-      <message name="IDS_EXTENSION_CANT_INSTALL_IN_DEVICE_LOCAL_ACCOUNT" desc="Error message when a user tries to install or the administrator tries to force-install through policy an extension that is not allowed in a device-local account.">
-        <ph name="EXTENSION_NAME">$1<ex>Google Talk</ex></ph> (extension ID "<ph name="EXTENSION_ID">$2<ex>nckgahadagoaajjgafhacjanaoiihapd</ex></ph>") is not allowed in this type of session.
-      </message>
+      <if expr="not use_aura">
+        <message name="IDS_EXTENSION_WINDOW_SHAPE_NOT_SUPPORTED" desc="Error message when an extension has a requirement for shaped windows that the system does not support.">
+          Shaped windows are not supported.
+        </message>
+      </if>
+      <if expr="chromeos">
+        <message name="IDS_EXTENSION_CANT_INSTALL_IN_DEVICE_LOCAL_ACCOUNT" desc="Error message when a user tries to install or the administrator tries to force-install through policy an extension that is not allowed in a device-local account.">
+          <ph name="EXTENSION_NAME">$1<ex>Google Talk</ex></ph> (extension ID "<ph name="EXTENSION_ID">$2<ex>nckgahadagoaajjgafhacjanaoiihapd</ex></ph>") is not allowed in this type of session.
+        </message>
+      </if>
       <message name="IDS_EXTENSION_MOVE_DIRECTORY_TO_PROFILE_FAILED" desc="">
         Could not move extension directory into profile.
       </message>
@@ -4552,12 +4553,12 @@
       <message name="IDS_EXTENSION_INSTALL_UNEXPECTED_VERSION" desc="Error displayed during installation of a side-loaded app, extension, or theme when the version of the referenced extension does not match the version the developer declared during registration.">
         Expected version "<ph name="EXPECTED_VERSION">$1<ex>2.0</ex></ph>", but version was "<ph name="NEW_ID">$2<ex>1.0</ex></ph>".
       </message>
-      <message name="IDS_EXTENSION_INSTALL_DEPENDENCY_NOT_FOUND" desc="Error displayed during installation of an extension when an import dependency is not found.">
-        Required extension with ID "<ph name="IMPORT_ID">$1<ex>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</ex></ph>" and minimum version "<ph name="IMPORT_VERSION">$2<ex>1.0</ex></ph>" not found.
-      </message>
       <message name="IDS_EXTENSION_INSTALL_DEPENDENCY_NOT_SHARED_MODULE" desc="Error displayed during installation of an extension which tries to imports resources from an extension which is not a shared module.">
         Unable to import extension with ID "<ph name="IMPORT_ID">$1<ex>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</ex></ph>" because it is not a shared module.
       </message>
+      <message name="IDS_EXTENSION_INSTALL_DEPENDENCY_NOT_WHITELISTED" desc="Error displayed during installation of an extension which tries to imports resources from an extension, but it is not whitelisted to do so.">
+        Unable to import extension with ID "<ph name="IMPORT_ID">$1<ex>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</ex></ph>" because it is not allowed its whitelist.
+      </message>
       <message name="IDS_EXTENSION_INSTALL_KIOSK_MODE_ONLY" desc="Error displayed during installation of an app with 'kiosk_only' attribute but user is not in ChromeOS kiosk mode.">
         App with 'kiosk_only' manifest attribute must be installed in ChromeOS kiosk mode.
       </message>
@@ -4588,9 +4589,6 @@
       <message name="IDS_EXTENSION_LOAD_OPTIONS_PAGE_FAILED" desc="">
         Could not load options page '<ph name="OPTIONS_PAGE">$1<ex>page.html</ex></ph>'.
       </message>
-      <message name="IDS_EXTENSION_LOAD_INPUT_VIEW_FAILED" desc="">
-        Could not load input view '<ph name="INPUT_VIEW">$1<ex>page.html</ex></ph>'.
-      </message>
       <if expr="is_win">
         <message name="IDS_EXTENSION_UNPACK_FAILED" desc="On windows, it is possible to mount a disk without the root of that disk having a drive letter.  The sandbox does not support this. See crbug/49530 .">
           Can not unpack extension.  To safely unpack an extension, there must be a path to your profile directory that starts with a drive letter and does not contain a junction, mount point, or symlink.  No such path exists for your profile.
@@ -4640,9 +4638,11 @@
         We were unable to install:
       </message>
       <if expr="enable_extensions">
-        <message name="IDS_EXTENSION_INSTALLED_APP_INFO" desc="Text displayed inside a link when an app is installed. Clicking this link opens up the New Tab Page to show the app's icon.">
-          Show me
-        </message>
+        <if expr="is_macosx">
+          <message name="IDS_EXTENSION_INSTALLED_APP_INFO" desc="Text displayed inside a link when an app is installed. Clicking this link opens up the New Tab Page to show the app's icon.">
+            Show me
+          </message>
+        </if>
         <message name="IDS_EXTENSION_INSTALLED_PAGE_ACTION_INFO" desc="Text displayed in the InfoBubble which explains that the UI of this extension is a Page Action icon which may appear for some pages.">
           This icon will be visible when the extension can act on the current page.
         </message>
@@ -4659,15 +4659,21 @@
           To use this extension, type "<ph name="EXTENSION_KEYWORD">$1<ex>search</ex></ph>", then TAB, then your command or search.
         </message>
 
-        <message name="IDS_EXTENSION_INSTALLED_MANAGE_INFO" desc="Text displayed in the InfoBubble with instructions on how to find the chrome://extensions/ management page">
-          Manage your extensions by clicking Extensions in the Tools menu.
-        </message>
-        <message name="IDS_EXTENSION_INSTALLED_MANAGE_INFO_CHROMEOS" desc="Text displayed in the InfoBubble with instructions on how to find the chrome://extensions/ management page on ChromeOS">
-          Manage your extensions by clicking Extensions in the "More tools" menu.
-        </message>
-        <message name="IDS_EXTENSION_INSTALLED_MANAGE_INFO_MAC" desc="Text displayed in the InfoBubble with instructions on how to find the chrome://extensions/ management page on MAC OS X">
-          Manage your extensions by clicking Extensions in the Window menu.
-        </message>
+        <if expr="not chromeos and not is_macosx">
+          <message name="IDS_EXTENSION_INSTALLED_MANAGE_INFO" desc="Text displayed in the InfoBubble with instructions on how to find the chrome://extensions/ management page">
+            Manage your extensions by clicking Extensions in the Tools menu.
+          </message>
+        </if>
+        <if expr="chromeos">
+          <message name="IDS_EXTENSION_INSTALLED_MANAGE_INFO_CHROMEOS" desc="Text displayed in the InfoBubble with instructions on how to find the chrome://extensions/ management page on ChromeOS">
+            Manage your extensions by clicking Extensions in the "More tools" menu.
+          </message>
+        </if>
+        <if expr="is_macosx">
+          <message name="IDS_EXTENSION_INSTALLED_MANAGE_INFO_MAC" desc="Text displayed in the InfoBubble with instructions on how to find the chrome://extensions/ management page on MAC OS X">
+            Manage your extensions by clicking Extensions in the Window menu.
+          </message>
+        </if>
         <message name="IDS_EXTENSION_INSTALLED_MANAGE_SHORTCUTS" desc="Text for the link in the InfoBubble that opens the chrome://extensions page with the Configure Commands UI visible.">
           Manage shortcuts
         </message>
@@ -4701,21 +4707,12 @@
         <message name="IDS_EXTENSIONS_UPDATE_BUTTON" desc="Text for the 'Update extensions' button.">
           Update extensions now
         </message>
-        <message name="IDS_EXTENSIONS_APPS_DEV_TOOLS_PROMO_TEXT" desc="The text encouraging users to get the Apps Developer Tools.">
-          Chrome Apps &amp; Extensions Developer Tool is the new way to debug your apps and extensions.
-        </message>
-        <message name="IDS_EXTENSIONS_APPS_DEV_TOOLS_LINK_TEXT" desc="The text of the link to get the Apps Developer Tools.">
-          Visit website
+        <message name="IDS_EXTENSIONS_APPS_DEV_TOOLS_PROMO_HTML" desc="The text encouraging users to get the Apps Developer Tools.">
+          Try the new <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>Chrome Apps &amp; Extensions Developer Tool<ph name="END_LINK">&lt;/a&gt;</ph>.
         </message>
         <message name="IDS_EXTENSIONS_NONE_INSTALLED" desc="Text that lets the user know that no extensions are installed.">
           Boo... You have no extensions :-(
         </message>
-        <message name="IDS_EXTENSIONS_PERMISSIONS_HEADING" desc="Heading for permissions dialog in apps_devtools">
-          It can:
-        </message>
-        <message name="IDS_EXTENSIONS_PERMISSIONS_CLOSE" desc="Close button for permissions dialog in apps_devtools">
-          Close
-        </message>
         <message name="IDS_EXTENSIONS_NONE_INSTALLED_SUGGEST_GALLERY" desc="Text on next line after IDS_EXTENSIONS_NONE_INSTALLED that suggests the user look in the gallery for extensions to install.">
           Want to <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>browse the gallery<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph> instead?
         </message>
@@ -4922,24 +4919,12 @@
       <message name="IDS_EXTENSION_PACK_DIALOG_TITLE" desc="Title of pack extension dialog">
         Pack Extension
       </message>
-      <message name="IDS_EXTENSION_PACK_APP_DIALOG_TITLE" desc="Title of pack application dialog">
-        Pack Application
-      </message>
       <message name="IDS_EXTENSION_PACK_BUTTON" desc="Text of the pack extension button">
         Pack Extension
       </message>
-      <message name="IDS_EXTENSION_ADT_PACK_BUTTON" desc="Text of the pack button in apps developer tool.">
-        Pack
-      </message>
       <message name="IDS_EXTENSION_PACK_DIALOG_HEADING" desc="The heading of the pack extension dialog.">
         Select the root directory of the extension to pack. To update an extension, also select the private key file to reuse.
       </message>
-      <message name="IDS_EXTENSION_ADT_PACK_DIALOG_HEADING" desc="The heading of the pack extension dialog in the Apps Developer Tool.">
-        The packed extension and the private key will be written in the parent directory of the root directory of the extension to pack. To update an extension, select the private key file to reuse.
-      </message>
-      <message name="IDS_EXTENSION_ADT_PACK_APP_DIALOG_HEADING" desc="The heading of the pack application dialog in the Apps Developer Tool.">
-        The packed application and the private key will be written in the parent directory of the root directory of the application to pack. To update an application, select the private key file to reuse.
-      </message>
       <message name="IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL" desc="Label in the pack extension dialog for the control that lets the user select the extension to pack.">
         Extension root directory:
       </message>
@@ -5139,42 +5124,21 @@
       <message name="IDS_EXTENSION_EXTERNAL_INSTALL_PROMPT_ABORT_BUTTON" desc="Button on the external install prompt to remove an extension installed by a third party.">
         Remove from Chrome
       </message>
-      <message name="IDS_EXTENSIONS_DISABLED" desc="(Disabled) label next to the application name when the application is disabled.">
-        (Disabled)
-      </message>
-      <message name="IDS_EXTENSIONS_SHOW_LOGS" desc="Text for the link to show logs.">
-        Show Logs
-      </message>
-      <message name="IDS_EXTENSIONS_MORE_DETAILS" desc="Text for the link to show more details about the extension / app.">
-        More Details
-      </message>
-      <message name="IDS_EXTENSIONS_VERSION" desc="The Version label in front of the version number of the extension / app.">
-        Version
-      </message>
-      <message name="IDS_EXTENSIONS_DELETE" desc="Text for the link to delete the extension / app.">
-        Delete
-      </message>
-      <message name="IDS_EXTENSIONS_ADT_DELETE" desc="Text for the link to uninstall the extension / app.">
-        Uninstall
-      </message>
-      <message name="IDS_EXTENSIONS_PACK" desc="Text for the link to pack the extension / app.">
-        Pack
-      </message>
 
       <if expr="use_titlecase">
-        <message name="IDS_EXTENSIONS_SUSPICIOUS_DISABLED_TITLE" desc="In Title Case: Title of the dialog shown when suspicious extensions have been disabled">
-          Suspicious Extensions Disabled
+        <message name="IDS_EXTENSIONS_UNSUPPORTED_DISABLED_TITLE" desc="In Title Case: Title of the dialog shown when unsupported extensions have been disabled">
+          Unsupported Extensions Disabled
         </message>
       </if>
       <if expr="not use_titlecase">
-        <message name="IDS_EXTENSIONS_SUSPICIOUS_DISABLED_TITLE" desc="Title of the dialog shown when suspicious extensions have been disabled">
-          Suspicious extensions disabled
+        <message name="IDS_EXTENSIONS_UNSUPPORTED_DISABLED_TITLE" desc="Title of the dialog shown when unsupported extensions have been disabled">
+          Unsupported extensions disabled
         </message>
       </if>
-      <message name="IDS_EXTENSIONS_SUSPICIOUS_DISABLED_AND_N_MORE" desc="Used for a count of additional items in the IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BODY dialog shown when suspicious extensions have been disabled, if we could not fit them all in the dialog">
+      <message name="IDS_EXTENSIONS_DISABLED_AND_N_MORE" desc="Used for a count of additional items in the IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BODY dialog shown when unsupported extensions have been disabled, if we could not fit them all in the dialog">
         and <ph name="NUMBER_ADDITIONAL_DISABLED">$1<ex>5</ex></ph> more
       </message>
-      <message name="IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BUTTON" desc="Text of the button on the dialog shown when suspicious extensions have been disabled">
+      <message name="IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BUTTON" desc="Text of the button on the dialog shown when unsupported extensions have been disabled">
       OK, got it
       </message>
       <message name="IDS_EXTENSIONS_ADDED_WITHOUT_KNOWLEDGE" desc="Text shown in the extensions settings for items that might have been forcefully added to chrome without the user's knowledge">
@@ -5198,9 +5162,6 @@
       </message>
 
       <!-- Settings API bubble -->
-      <message name="IDS_EXTENSIONS_DISABLE_EXTENSIONS" desc="Text for the Disable Extensions (note: plural) button">
-        Disable Extensions
-      </message>
       <if expr="use_titlecase">
         <message name="IDS_EXTENSIONS_SETTINGS_API_TITLE_HOME_PAGE_BUBBLE" desc="In Title Case: Title of a bubble warning users that an extension has overridden their home page setting">
          Is This the Home Page You Were Expecting?
@@ -5267,10 +5228,10 @@
         ''' If you didn't want these changes, you can restore your previous settings.'''
       </message>
 
-      <message name="IDS_EXTENSIONS_SETTINGS_API_RESTORE_SETTINGS" desc="The button in the Settings API bubble that reverts the settings changes made by the extension and restores what the user had before.">
+      <message name="IDS_EXTENSION_CONTROLLED_RESTORE_SETTINGS" desc="The button in the extension controlled bubbles that reverts the settings changes made by the extension and restores what the user had before.">
         Restore settings
       </message>
-      <message name="IDS_EXTENSIONS_SETTINGS_API_KEEP_CHANGES" desc="The button in the Settings API bubble that cancels the bubble without action.">
+      <message name="IDS_EXTENSION_CONTROLLED_KEEP_CHANGES" desc="The button in the extension controlled bubbles that cancels the bubble without action.">
         Keep changes
       </message>
 
@@ -5630,13 +5591,6 @@
       <message name="IDS_FLAGS_IGNORE_GPU_BLACKLIST_DESCRIPTION" desc="Description of the 'Ignore GPU blacklist' lab.">
         Overrides the built-in software rendering list and enables GPU-acceleration on unsupported system configurations.
       </message>
-      <message name="IDS_FLAGS_DISABLE_GPU_VSYNC_NAME" desc="Name of the 'Disable GPU VSync' lab.">
-        Disable GPU VSync
-      </message>
-      <message name="IDS_FLAGS_DISABLE_GPU_VSYNC_DESCRIPTION" desc="Description of the 'Disable GPU VSync' lab.">
-        Disables synchronization with the display's vertical refresh rate when GPU rendering. This allows frame rates to exceed
-        60 hertz. While useful for benchmarking purposes, this also results in visual tearing during rapid screen updates.
-      </message>
       <message name="IDS_FLAGS_THREADED_COMPOSITING_MODE_NAME" desc="Name of the 'Threaded compositing mode' lab.">
         Threaded compositing
       </message>
@@ -5661,12 +5615,14 @@
       <message name="IDS_FLAGS_DISABLE_LAYER_SQUASHING_DESCRIPTION" desc="Description of the 'Disable layer squashing' lab.">
         Prevents the automatic combining of composited layers.
       </message>
-      <message name="IDS_FLAGS_ENABLE_DIRECT_WRITE_NAME" desc="Name of the 'Enable DirectWrite' lab.">
-        Enable DirectWrite
-      </message>
-      <message name="IDS_FLAGS_ENABLE_DIRECT_WRITE_DESCRIPTION" desc="Description of the 'Enable DirectWrite' lab.">
-        Enables the use of experimental DirectWrite font rendering system.
-      </message>
+      <if expr="is_win">
+        <message name="IDS_FLAGS_ENABLE_DIRECT_WRITE_NAME" desc="Name of the 'Enable DirectWrite' lab.">
+          Enable DirectWrite
+        </message>
+        <message name="IDS_FLAGS_ENABLE_DIRECT_WRITE_DESCRIPTION" desc="Description of the 'Enable DirectWrite' lab.">
+          Enables the use of experimental DirectWrite font rendering system.
+        </message>
+      </if>
       <message name="IDS_FLAGS_ENABLE_EXPERIMENTAL_CANVAS_FEATURES_NAME" desc="Name of the 'Enable experimental canvas features' lab.">
         Enable experimental canvas features
       </message>
@@ -5679,12 +5635,6 @@
       <message name="IDS_FLAGS_DISABLE_ACCELERATED_2D_CANVAS_DESCRIPTION" desc="Description of the 'Disable accelerated 2D canvas' lab.">
         Disables the use of the GPU to perform 2d canvas rendering and instead uses software rendering.
       </message>
-      <message name="IDS_FLAGS_DISABLE_DEFERRED_2D_CANVAS_NAME" desc="Name of the 'Disable deferred 2D canvas' lab.">
-        Disable deferred 2D canvas
-      </message>
-      <message name="IDS_FLAGS_DISABLE_DEFERRED_2D_CANVAS_DESCRIPTION" desc="Description of the 'Disable deferred 2D canvas' lab.">
-        Disables the deferral of 2d canvas rendering, causing draw operations to be completed immediately, before running the next javascript command.
-      </message>
       <message name="IDS_FLAGS_EXPERIMENTAL_EXTENSION_APIS_NAME" desc="Name of the 'Experimental Extension APIs' lab.">
         Experimental Extension APIs
       </message>
@@ -5739,61 +5689,26 @@
       <message name="IDS_FLAGS_DISABLE_HYPERLINK_AUDITING_DESCRIPTION" desc="Description of the 'Disable hyperlink auditing' lab.">
         Disable sending hyperlink auditing pings.
       </message>
-      <message name="IDS_FLAGS_EXPERIMENTAL_LOCATION_FEATURES_NAME" desc="Name of the 'Enable experimental location features' lab.">
-        Experimental location features
-      </message>
-      <if expr="is_android">
-        <message name="IDS_FLAGS_EXPERIMENTAL_LOCATION_FEATURES_DESCRIPTION" desc="Mobile: Description of the 'Enable experimental location features' lab.">
-          Enables experimental extensions to the geolocation feature. Includes using operating system location APIs (where available), and sending additional local network configuration data to the Google location service to provide higher accuracy positioning.
-        </message>
-      </if>
-      <if expr="not is_android">
-        <message name="IDS_FLAGS_EXPERIMENTAL_LOCATION_FEATURES_DESCRIPTION" desc="Description of the 'Enable experimental location features' lab.">
-          Enables experimental extensions to the geolocation feature to use operating system location APIs (where available).
-        </message>
-      </if>
-      <message name="IDS_FLAGS_STATIC_IP_CONFIG_NAME" desc="Name of the static ip config lab.">
-        Experimental static ip configuration
-      </message>
-      <message name="IDS_FLAGS_STATIC_IP_CONFIG_DESCRIPTION" desc="Description of the static ip config lab.">
-        Enables static ip configuration. May not work.
-      </message>
       <message name="IDS_FLAGS_NTP_SUGGESTIONS_PAGE_NAME" desc="Name of the 'Enable suggestions page' lab.">
         NTP Suggestions page
       </message>
       <message name="IDS_FLAGS_NTP_SUGGESTIONS_PAGE_DESCRIPTION" desc="Description of the 'Enable suggestions page' lab.">
         Add 'Suggestions' card to the new tab page, which suggests the pages to be opened.
       </message>
-      <message name="IDS_FLAGS_DISABLE_IME_MODE_INDICATOR" desc="Title for the flag to disable the new indicator for the active keyboard input mode.">
-        Disable the new indicator for the active keyboard input method
-      </message>
-      <message name="IDS_FLAGS_DISABLE_IME_MODE_INDICATOR_DESCRIPTION" desc="Description for the flag to disable the new indicator for the active keyboard input method.">
-        Disable the input method indicator shown near the caret when switching between keyboard input methods.
-      </message>
-      <message name="IDS_FLAGS_ENABLE_INSTANT_EXTENDED_API" desc="Title for the flag to enable the Instant extended API.">
-        Enable Instant Extended API
-      </message>
-      <message name="IDS_FLAGS_ENABLE_INSTANT_EXTENDED_API_DESCRIPTION" desc="Description for the flag to enable the Instant extended API.">
-        Enables the Instant Extended API which provides a deeper integration with your default search provider, including a renovated New Tab Page, extracting search query terms in the omnibox, a spruced-up omnibox dropdown and Instant previews of search results as you type in the omnibox.
-      </message>
-      <message name="IDS_FLAGS_ENABLE_NEW_NTP" desc="Title for the flag to enable the new NTP.">
-        Enable the new NTP.
-      </message>
-      <message name="IDS_FLAGS_ENABLE_NEW_NTP_DESCRIPTION" desc="Description for the flag to enable the new NTP.">
-        Whether or not the new style New Tab Page is enabled.
-      </message>
+      <if expr="is_android">
+        <message name="IDS_FLAGS_ENABLE_NEW_NTP" desc="Title for the flag to enable the new NTP.">
+          Enable the new NTP.
+        </message>
+        <message name="IDS_FLAGS_ENABLE_NEW_NTP_DESCRIPTION" desc="Description for the flag to enable the new NTP.">
+          Whether or not the new style New Tab Page is enabled.
+        </message>
+      </if>
       <message name="IDS_FLAGS_ENABLE_CONTEXTUAL_SEARCH" desc="Title for the flag to enable Contextual Search.">
         Enable Contextual Search.
       </message>
       <message name="IDS_FLAGS_ENABLE_CONTEXTUAL_SEARCH_DESCRIPTION" desc="Description for the flag to enable Contextual Search.">
         Whether or not Contextual Search is enabled.
       </message>
-      <message name="IDS_FLAGS_ENABLE_NO_TOUCH_TO_RENDERER_WHILE_SCROLLING_NAME" desc="Name of the flag that enables not sending touch events to renderer while scrolling.">
-        Enable not sending touch events to renderer while scrolling
-      </message>
-      <message name="IDS_FLAGS_ENABLE_NO_TOUCH_TO_RENDERER_WHILE_SCROLLING_DESCRIPTION" desc="Description of the flag to enable not sending touch events to renderer while scrolling.">
-        Enable not sending touch events to renderer while scrolling.
-      </message>
       <message name="IDS_FLAGS_ENABLE_GESTURE_TAP_HIGHLIGHTING_NAME" desc="Title for the flag to turn on gesture tap highlighting">
         Gesture Tap Highlighting
       </message>
@@ -5821,12 +5736,6 @@
       <message name="IDS_FLAGS_SHOW_AUTOFILL_TYPE_PREDICTIONS_DESCRIPTION" desc="Description for the flag to show Autofill field type predictions for all forms">
         Annotates web forms with Autofill field type predictions as placeholder text.
       </message>
-      <message name="IDS_FLAGS_DISABLE_NATIVE_AUTOFILL_UI_NAME" desc="Title for the flag to disable the native Autofill UI">
-        Disable native Autofill UI
-      </message>
-      <message name="IDS_FLAGS_DISABLE_NATIVE_AUTOFILL_UI_DESCRIPTION" desc="Description for the flag to disable the native Autofill UI">
-        The native Autofill popup UI is implemented in the browser process rather than in the renderer process.
-      </message>
       <message name="IDS_FLAGS_ENABLE_INTERACTIVE_AUTOCOMPLETE_NAME" desc="Name of the flag that enables an interactive autocomplete UI.">
         Enable interactive autocomplete
       </message>
@@ -5851,12 +5760,6 @@
       <message name="IDS_FLAGS_ENABLE_TOUCH_EDITING_DESCRIPTION" desc="Description of the flag to enable touch based text editing.">
         Touch editing can be initiated by tapping on a textfield or a selected text.
       </message>
-      <message name="IDS_FLAGS_ENABLE_EXPERIMENTAL_FORM_FILLING_NAME" desc="Title for the flag to enable experimental form filling">
-        Enable experimental form filling
-      </message>
-      <message name="IDS_FLAGS_ENABLE_EXPERIMENTAL_FORM_FILLING_DESCRIPTION" desc="Description for the flag to enable experimantal form filling feature">
-        Enable experimental form filling. Enables a collection of experimental features that make form filling easier.
-      </message>
       <message name="IDS_FLAGS_WALLET_SERVICE_USE_SANDBOX_NAME" desc="Title for the flag to use the Online Wallet sandbox servers (instead of production).">
         Use Wallet sandbox servers
       </message>
@@ -5878,76 +5781,12 @@
       <message name="IDS_FLAGS_SCROLL_END_EFFECT_DESCRIPTION" desc="Description for the flag that controls scroll end effect from vertical overscroll.">
         Experimental scroll end effect in response to vertical overscroll.
       </message>
-      <message name="IDS_FLAGS_ENABLE_SYNC_FAVICONS_NAME" desc="Title for the flag to enable the favicon sync datatype">
-        Enable favicon sync.
-      </message>
-      <message name="IDS_FLAGS_ENABLE_SYNC_FAVICONS_DESCRIPTION" desc="Description for the flag to enable the favicon sync datatype">
-        Enable syncing the set of recent favicons.
-      </message>
-      <message name="IDS_FLAGS_SYNC_KEYSTORE_ENCRYPTION_NAME" desc="Title for the flag to enable sync's keystore encryption options">
-        Enable sync keystore encryption.
-      </message>
-      <message name="IDS_FLAGS_SYNC_KEYSTORE_ENCRYPTION_DESCRIPTION" desc="Description for the flag to enable sync's keystore encryption options">
-        Switch to sync's new server supported encryption schema. Warning: this will modify your sync data, possibly making it unreadable to other clients.
-      </message>
-      <if expr="is_android">
-        <message name="IDS_FLAGS_SYNC_TYPED_URLS_NAME" desc="Mobile: Title for the flag to enable syncing the TypedUrl datatype">
-          Enable syncing typed URLs
-        </message>
-        <message name="IDS_FLAGS_SYNC_TYPED_URLS_DESCRIPTION" desc="Mobile: Description for the flag to enable syncing the TypedURL datatype">
-          Enable typed URLs in the sync settings. This allows syncing your typed URL history to other clients to assist in omnibox auto-completion.
-        </message>
-      </if>
-      <if expr="not is_android">
-        <message name="IDS_FLAGS_SYNC_TYPED_URLS_NAME" desc="Title for the flag to enable syncing the TypedUrl datatype">
-          Enable syncing History
-        </message>
-        <message name="IDS_FLAGS_SYNC_TYPED_URLS_DESCRIPTION" desc="Description for the flag to enable syncing the TypedURL datatype">
-          Enable History in the sync settings. This allows syncing your typed URL history and navigation history to other clients to assist in omnibox auto-completion and the history UI.
-        </message>
-      </if>
-      <message name="IDS_FLAGS_OMNIBOX_HISTORY_QUICK_PROVIDER_REORDER_FOR_INLINING_NAME" desc="Title for the flag for omnibox to reorder suggestions in HistoryQuickProvider to make an inlineable appear first">
-        Reorder results for inlining in HistoryQuickProvider
-      </message>
-      <message name="IDS_FLAGS_OMNIBOX_HISTORY_QUICK_PROVIDER_REORDER_FOR_INLINING_DESCRIPTION" desc="Description for the flag for omnibox to reorder suggestions in HistoryQuickProvider to make an inlineable appear first">
-        In omnibox autocomplete, reorder suggestions in HistoryQuickProvider to make an inlineable one appear first.
-      </message>
-      <message name="IDS_FLAGS_OMNIBOX_HISTORY_QUICK_PROVIDER_REORDER_FOR_INLINING_AUTOMATIC" desc="Option name for automatic selection of whether to allow HistoryQuickProvider to reorder suggestions to make an inlineable one appear first">
-        Automatic
-      </message>
-      <message name="IDS_FLAGS_OMNIBOX_HISTORY_QUICK_PROVIDER_REORDER_FOR_INLINING_ENABLED" desc="Option name to allow HistoryQuickProvider to reorder suggestions to make an inlineable one appear first">
-        Reorder
-      </message>
-      <message name="IDS_FLAGS_OMNIBOX_HISTORY_QUICK_PROVIDER_REORDER_FOR_INLINING_DISABLED" desc="Option name to disallow HistoryQuickProvider to reorder suggestions to make an inlineable one appear first">
-        Don't Reorder
-      </message>
-      <message name="IDS_FLAGS_OMNIBOX_INLINE_HISTORY_QUICK_PROVIDER_NAME" desc="Title for the flag for omnibox to prohibit the HistoryQuickProvider from inlining suggestions">
-        Inline HistoryQuickProvider suggestions
-      </message>
-      <message name="IDS_FLAGS_OMNIBOX_INLINE_HISTORY_QUICK_PROVIDER_DESCRIPTION" desc="Description for the flag for omnibox to prohibit the HistoryQuickProvider from inlining suggestions">
-        In omnibox autocomplete, allow inlining of matches coming from the HistoryQuickProvider.
-      </message>
-      <message name="IDS_FLAGS_OMNIBOX_INLINE_HISTORY_QUICK_PROVIDER_AUTOMATIC" desc="Option name for automatic selection of whether omnibox HistoryQuickProvider can inline suggestions.">
-        Automatic
-      </message>
-      <message name="IDS_FLAGS_OMNIBOX_INLINE_HISTORY_QUICK_PROVIDER_ALLOWED" desc="Option name to allow the omnibox HistoryQuickProvider to inline suggestions if it wants to.">
-        Allowed
-      </message>
-      <message name="IDS_FLAGS_OMNIBOX_INLINE_HISTORY_QUICK_PROVIDER_PROHIBITED" desc="Option name to prohibit omnibox HistoryQuickProvider from inlining suggestions ever.">
-        Prohibited
-      </message>
       <message name="IDS_FLAGS_ENABLE_PANELS_NAME" desc="Name of the 'Enable Panels' lab.">
         Enable Panels
       </message>
       <message name="IDS_FLAGS_ENABLE_PANELS_DESCRIPTION" desc="Description for the flag to enable Panel windows.">
         Enable Panel windows that open outside of the browser frame. Attempts to open a Panel will open a popup instead if not enabled. Panels are always enabled on the dev and canary channels.
       </message>
-      <message name="IDS_FLAGS_ENABLE_WEBGL_NAME" desc="Name of the 'Enable WebGL' lab.">
-        Enable WebGL
-      </message>
-      <message name="IDS_FLAGS_ENABLE_WEBGL_DESCRIPTION" desc="Description for the flag to enable WebGL.">
-        Enabling this option allows web applications to access the WebGL API.
-      </message>
       <message name="IDS_FLAGS_ENABLE_WEBGL_DRAFT_EXTENSIONS_NAME" desc="Name of the 'Enable WebGL Draft Extensions' flag.">
         Enable WebGL Draft Extensions
       </message>
@@ -6075,12 +5914,6 @@
       <message name="IDS_FLAGS_DISABLE_PREFIXED_ENCRYPTED_MEDIA_DESCRIPTION" desc="Description for the flag to disable the prefixed Encrypted Media Extensions APIs (e.g. webkitGenerateKeyRequest()).">
         Disable the experimental version of Encrypted Media Extensions on video and audio elements.
       </message>
-      <message name="IDS_FLAGS_ENCRYPTED_MEDIA_CANPLAYTYPE_OVERRIDE_NAME" desc="Title for the flag to override suppressed affirmative responses to canPlayType().">
-        Enable suppressed canPlayType() responses.
-      </message>
-      <message name="IDS_FLAGS_ENCRYPTED_MEDIA_CANPLAYTYPE_OVERRIDE_DESCRIPTION" desc="Description for the flag to override suppressed affirmative responses to canPlayType().">
-        Enable appropriate responses to canPlayType() for key systems that return the empty string by default.
-      </message>
       <if expr="is_android">
         <message name="IDS_FLAGS_DISABLE_INFOBAR_FOR_PROTECTED_MEDIA_IDENTIFIER_NAME" desc="Title for the flag to disable infobar popup for protected media identifier.">
           Disable infobar popup for protected media.
@@ -6095,36 +5928,20 @@
           Enable non-compositing decoding in MediaDrm by default for Encrypted Media Extensions.
         </message>
       </if>
-      <message name="IDS_FLAGS_ASH_AUTO_WINDOW_PLACEMENT_NAME" desc="Name for the option to enable/disable the auto window placement functionality.">
-        Automatic window placement.
-      </message>
-      <message name="IDS_FLAGS_ASH_AUTO_WINDOW_PLACEMENT_DESCRIPTION" desc="Description for the option to enable/disable the auto window placement functionality.">
-        Disable automatic window placement for one and two browser / app windows.
-      </message>
       <message name="IDS_FLAGS_DISABLE_GESTURE_REQUIREMENT_FOR_MEDIA_PLAYBACK_NAME" desc="Title for the flag to disable gesture requiment for media playback">
         Disable gesture requirement for media playback.
       </message>
       <message name="IDS_FLAGS_DISABLE_GESTURE_REQUIREMENT_FOR_MEDIA_PLAYBACK_DESCRIPTION" desc="Description for the flag to disable gesture requiment for media playback">
         Disable user gesture requirement for playing media elements. Activating this will allow autoplay to work.
       </message>
-      <message name="IDS_FLAGS_ASH_FRAME_CAPTION_BUTTON_STYLE_NAME" desc="Title for the flag for the alternate frame caption button style.">
-        Alternate frame caption button style
-      </message>
-      <message name="IDS_FLAGS_ASH_FRAME_CAPTION_BUTTON_STYLE_DESCRIPTION" desc="Description for the flag for the alternate frame caption button style.">
-        Enables an experimental visual style for the frame caption buttons (minimize, maximize, close).
-      </message>
-      <message name="IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_NAME" desc="Title for the flag which can be used to test the TouchView maximizing mode.">
-        Enable TouchView maximizing UI for testing
-      </message>
-      <message name="IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_DESCRIPTION" desc="Description for the flag to enable the TouchView testing mode.">
-        Enable Ctrl+Alt+Shift+8 to toggle the TouchView maximizing mode.
-      </message>
-      <message name="IDS_FLAGS_ENABLE_FULL_MULTI_PROFILE_MODE" desc="Title for the full multi profile mode flag.">
-        Enable side-by-side multi profile mode
-      </message>
-      <message name="IDS_FLAGS_ENABLE_FULL_MULTI_PROFILE_MODE_DESCRIPTION" desc="Title for the full multi profile mode flag.">
-        Enable side-by-side multi profile mode in which all browser and app windows share the same workspace.
-      </message>
+      <if expr="use_ash">
+        <message name="IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_NAME" desc="Title for the flag which can be used to test the TouchView maximizing mode.">
+          Enable TouchView maximizing UI for testing
+        </message>
+        <message name="IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_DESCRIPTION" desc="Description for the flag to enable the TouchView testing mode.">
+          Enable Ctrl+Alt+Shift+8 to toggle the TouchView maximizing mode.
+        </message>
+      </if>
       <message name="IDS_FLAGS_ENABLE_LOCALLY_MANAGED_USERS_NAME" desc="Title for the flag to enable supervised users.">
         Enable supervised users
       </message>
@@ -6225,18 +6042,22 @@
       <message name="IDS_FLAGS_SPELLCHECK_AUTOCORRECT_DESCRIPTION" desc="Description for the flag to force synchronous spellchecking.">
         Turn on autocorrection of text while typing. Synchronous spellchecking is not compatible with this feature.
       </message>
-      <message name="IDS_FLAGS_DOCKED_WINDOWS_NAME" desc="Name for the flag to disable docked windows feature.">
-        Disable docking of windows near screen edges.
-      </message>
-      <message name="IDS_FLAGS_DOCKED_WINDOWS_DESCRIPTION" desc="Description for the flag to disable docked windows feature.">
-        Turns off docking of windows near screen edges, a feature that provides an easier way to interact with panel and other small windows.
-      </message>
-      <message name="IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_NAME" desc="Name for the flag which allows to minimize a window upon launcher item click under certain conditions.">
-        Disallow shelf to minimize-on-click.
-      </message>
-      <message name="IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_DESCRIPTION" desc="Description for the flag which allows to minimize a window upon launcher item click under certain conditions.">
-        Disallow the shelf to minimize a window if a shelf item gets clicked which has only a single, already active, window associated with it.
-      </message>
+      <if expr="chromeos">
+        <message name="IDS_FLAGS_DOCKED_WINDOWS_NAME" desc="Name for the flag to disable docked windows feature.">
+          Disable docking of windows near screen edges.
+        </message>
+        <message name="IDS_FLAGS_DOCKED_WINDOWS_DESCRIPTION" desc="Description for the flag to disable docked windows feature.">
+          Turns off docking of windows near screen edges, a feature that provides an easier way to interact with panel and other small windows.
+        </message>
+      </if>
+      <if expr="use_ash">
+        <message name="IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_NAME" desc="Name for the flag which allows to minimize a window upon launcher item click under certain conditions.">
+          Disallow shelf to minimize-on-click.
+        </message>
+        <message name="IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_DESCRIPTION" desc="Description for the flag which allows to minimize a window upon launcher item click under certain conditions.">
+          Disallow the shelf to minimize a window if a shelf item gets clicked which has only a single, already active, window associated with it.
+        </message>
+      </if>
 
       <message name="IDS_FLAGS_SHOW_TOUCH_HUD_NAME" desc="Name for the flag to show a heads-up display for tracking touch-points.">
         Show HUD for touch points
@@ -6331,12 +6152,6 @@
       <message name="IDS_FLAGS_ENABLE_AUTOMATIC_PASSWORD_SAVING_DESCRIPTION" desc="Description of the flag to automatically save password.">
         Skip the passwords prompt and save passwords automatically.
       </message>
-      <message name="IDS_FLAGS_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_NAME" desc="Name of the flag for public suffix domain matching for autofill of passwords.">
-        Public suffix domain matching for autofill of passwords.
-      </message>
-      <message name="IDS_FLAGS_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_DESCRIPTION" desc="Description of flag to enable or disable public suffix domain matching for autofill of passwords.">
-        Enable or disable a feature which allows the user to select username/password combinations for domains that match the same public suffix registry domain.
-      </message>
       <message name="IDS_FLAGS_PASSWORD_MANAGER_REAUTHENTICATION_NAME" desc="Name of the flag for the password manager reauthentication option.">
         Disable Password Manager Reauthentication
       </message>
@@ -6373,12 +6188,14 @@
       <message name="IDS_FLAGS_ENABLE_SCREEN_CAPTURE_DESCRIPTION" desc="Description of flag to enable screen capture.">
         Allow web pages to request access to the screen contents via the getUserMedia() API.
       </message>
-      <message name="IDS_FLAGS_ENABLE_AVFOUNDATION_NAME" desc="Name of the flag to enable Mac AVFoundation.">
-        Enable use of Mac OS X AVFoundation APIs, instead of QTKit.
-      </message>
-      <message name="IDS_FLAGS_ENABLE_AVFOUNDATION_DESCRIPTION" desc="Description of flag to enable Mac AVFoundation.">
-        Enable AVFoundation use for video capture and video device monitoring on OS X >= 10.7. QTKit will be used otherwise.
-      </message>
+      <if expr="is_macosx">
+        <message name="IDS_FLAGS_ENABLE_AVFOUNDATION_NAME" desc="Name of the flag to enable Mac AVFoundation.">
+          Enable use of Mac OS X AVFoundation APIs, instead of QTKit.
+        </message>
+        <message name="IDS_FLAGS_ENABLE_AVFOUNDATION_DESCRIPTION" desc="Description of flag to enable Mac AVFoundation.">
+          Enable AVFoundation use for video capture and video device monitoring on OS X >= 10.7. QTKit will be used otherwise.
+        </message>
+      </if>
       <message name="IDS_FLAGS_ENABLE_APPS_DEVTOOL_APP_NAME" desc="Name of the flag to enable apps-devtools app.">
         Enable apps-devtool app.
       </message>
@@ -6405,6 +6222,12 @@
       <message name="IDS_FLAGS_LCD_TEXT_DESCRIPTION" desc="Description of about:flags option for LCD text.">
         If disabled, text is rendered with grayscale antialiasing instead of LCD (subpixel) when doing accelerated compositing.
       </message>
+      <message name="IDS_FLAGS_DISTANCE_FIELD_TEXT_NAME" desc="Name of about:flags option for distance field text.">
+        Enable distance field text
+      </message>
+      <message name="IDS_FLAGS_DISTANCE_FIELD_TEXT_DESCRIPTION" desc="Description of about:flags option for distance field text.">
+        If enabled, text is rendered with signed distance fields rather than bitmap alpha masks.
+      </message>
       <message name="IDS_FLAGS_DELEGATED_RENDERER_NAME" desc="Name of about:flags option for delegated renderer.">
         Delegated Renderer (AKA Übercompositor).
       </message>
@@ -6554,12 +6377,6 @@
           Enables a simplified and improved fullscreen experience on Mac.
         </message>
       </if>
-      <message name="IDS_FLAGS_ENABLE_TRANSLATE_SETTINGS_NAME" desc="Name of the flag to enable translate setting.">
-        Enable Translate settings.
-      </message>
-      <message name="IDS_FLAGS_ENABLE_TRANSLATE_SETTINGS_DESCRIPTION" desc="Description of the flag to translate setting.">
-        Enable Translate settings in chrome://settings/languages where the user can configure which language should be translated.
-      </message>
       <message name="IDS_FLAGS_RESET_APP_LIST_INSTALL_STATE_NAME" desc="Name of the flag to reset the app launcher install state.">
         Reset the App Launcher install state on every restart.
       </message>
@@ -6586,16 +6403,16 @@
           Enable the app info dialog. If enabled, the user will be able to select the 'App Info' context menu in the App Launcher to show the app info dialog for the selected app.
        </message>
         <message name="IDS_FLAGS_ENABLE_EXPERIMENTAL_APP_LIST_NAME" desc="Name of the flag to enable the experimental app launcher.">
-          Enable the experimental app launcher.
+          Enable the experimental App Launcher.
         </message>
         <message name="IDS_FLAGS_ENABLE_EXPERIMENTAL_APP_LIST_DESCRIPTION" desc="Description of the flag to enable the experimental app launcher.">
-          Enable the experimental version of the app launcher.
+          Enable the experimental version of the App Launcher.
         </message>
-        <message name="IDS_FLAGS_ENABLE_EXPERIMENTAL_APP_LIST_POSITION_NAME" desc="Name of the flag to enable the experimental app launcher position.">
-          Enable the experimental app launcher position.
+        <message name="IDS_FLAGS_ENABLE_CENTERED_APP_LIST_NAME" desc="Name of the flag to center the app launcher.">
+          Center the App Launcher.
         </message>
-        <message name="IDS_FLAGS_ENABLE_EXPERIMENTAL_APP_LIST_POSITION_DESCRIPTION" desc="Description of the flag to enable the experimental app launcher position.">
-          Positions the app launcher in the center of the screen with a landscape aspect. This will not enable other app launcher experiments.
+        <message name="IDS_FLAGS_ENABLE_CENTERED_APP_LIST_DESCRIPTION" desc="Description of the flag to center the app launcher and make it wide instead of tall.">
+          Positions the App Launcher in the center of the screen with a landscape aspect.
         </message>
       </if>
       <if expr="chromeos">
@@ -6612,18 +6429,6 @@
           If enabled, transitions during first-run tutorial are animated.
         </message>
       </if>
-      <message name="IDS_FLAGS_ENABLE_ACCELERATED_SCROLLABLE_FRAMES_NAME" desc="Name of the flag to enable accelerated scrollable frames.">
-        Enable accelerated scrollable frames.
-      </message>
-      <message name="IDS_FLAGS_ENABLE_ACCELERATED_SCROLLABLE_FRAMES_DESCRIPTION" desc="Description for the flag to enable accelerated scrollable frames.">
-        Enables accelerated compositing for scrollable frames.
-      </message>
-      <message name="IDS_FLAGS_ENABLE_COMPOSITED_SCROLLING_FOR_FRAMES_NAME" desc="Name of the flag to enable composited scrolling for frames.">
-        Enable composited scrolling for frames.
-      </message>
-      <message name="IDS_FLAGS_ENABLE_COMPOSITED_SCROLLING_FOR_FRAMES_DESCRIPTION" desc="Description for the flag to enable composited scrolling for frames.">
-        Enable accelerated scrolling by the compositer for frames.
-      </message>
       <message name="IDS_FLAGS_ENABLE_STREAMLINED_HOSTED_APPS_NAME" desc="Name of the flag to enable streamlined hosted apps.">
         Enable experimental streamlined hosted apps.
       </message>
@@ -6662,18 +6467,20 @@
           Always send click events immediate upon a tap, even when it's part of a double-tap gesture.  This speeds up navigation and other tap actions by 300ms on most pages, but means links and buttons must be avoided when double tapping to zoom.
         </message>
       </if>
-      <message name="IDS_FLAGS_ENABLE_TRANSLATE_NEW_UX_NAME" desc="Name of the flag to enable the new Translate UX.">
-        Enable the new Translate UX.
+      <if expr="is_macosx">
+        <message name="IDS_FLAGS_ENABLE_TRANSLATE_NEW_UX_NAME" desc="Name of the flag to enable the new Translate UX.">
+          Enable the new Translate UX.
+        </message>
+        <message name="IDS_FLAGS_ENABLE_TRANSLATE_NEW_UX_DESCRIPTION" desc="Description for the flag to enable the new Translate UX.">
+          Enable the new Translate bubble UX is offered instead of the infobar.
+        </message>
+      </if>
+      <message name="IDS_FLAGS_DISABLE_VIEWS_RECT_BASED_TARGETING_NAME" desc="Name of about:flags option to disable rect-based targeting in views">
+        Disable rect-based targeting in views
       </message>
-      <message name="IDS_FLAGS_ENABLE_TRANSLATE_NEW_UX_DESCRIPTION" desc="Description for the flag to enable the new Translate UX.">
-        Enable the new Translate bubble UX is offered instead of the infobar.
+      <message name="IDS_FLAGS_DISABLE_VIEWS_RECT_BASED_TARGETING_DESCRIPTION" desc="Description of about:flags option to disable rect-based targeting in views">
+        Disables rect-based targeting in views. Rect-based targeting uses a heuristic to determine the most probable target of a gesture, where the touch region is represented by a rectangle.
       </message>
-    <message name="IDS_FLAGS_DISABLE_VIEWS_RECT_BASED_TARGETING_NAME" desc="Name of about:flags option to disable rect-based targeting in views">
-      Disable rect-based targeting in views
-    </message>
-    <message name="IDS_FLAGS_DISABLE_VIEWS_RECT_BASED_TARGETING_DESCRIPTION" desc="Description of about:flags option to disable rect-based targeting in views">
-      Disables rect-based targeting in views. Rect-based targeting uses a heuristic to determine the most probable target of a gesture, where the touch region is represented by a rectangle.
-    </message>
       <message name="IDS_FLAGS_ENABLE_APPS_SHOW_ON_FIRST_PAINT_NAME" desc="Name of the flag to enable show-on-first-paint for apps.">
         Enable show-on-first-paint for apps.
       </message>
@@ -6728,12 +6535,6 @@
       <message name="IDS_FLAGS_SEARCH_BUTTON_IN_OMNIBOX_ENABLED" desc="Option in a drop-down menu to enable the display of the search button at all times (on all pages).">
         Enabled on all pages
       </message>
-      <message name="IDS_FLAGS_ENABLE_PASSWORD_BUBBLE_NAME" desc="Title for the flag to enable the manage passwords bubble feature.">
-        Enable Passwords Bubble
-      </message>
-      <message name="IDS_FLAGS_ENABLE_PASSWORD_BUBBLE_DESCRIPTION" desc="Description for the flag to enable the Manage Passwords Bubble feature.">
-        Enables the Passwords Bubble. The Passwords Bubble provides an easy way to store and manage passwords for a website. It replaced the infobad for saving passwords.
-      </message>
       <message name="IDS_FLAGS_ENABLE_PERMISSIONS_BUBBLES_NAME" desc="Title for the flag to enable showing permissions requests in bubbles.">
         Use Bubbles for Permission Requests
       </message>
@@ -6786,6 +6587,12 @@
       <message name="IDS_FLAGS_ENABLE_APPS_FILE_ASSOCIATIONS_DESCRIPTION" desc="Description for a flag to enable file associations for Chrome Apps.">
         Enable OS integration of file associations for Chrome Apps.
       </message>
+      <message name="IDS_FLAGS_TEXT_INPUT_FOCUS_MANAGER_NAME" desc="Title for the flag to enable the new text input focus manager.">
+        Experimental text input focus manager.
+      </message>
+      <message name="IDS_FLAGS_TEXT_INPUT_FOCUS_MANAGER_DESCRIPTION" desc="Description for the flag to enable the new text input focus manager.">
+        Enable an experimental focus manager to track text input clients.
+      </message>
 
       <!-- Crashes -->
       <message name="IDS_CRASHES_TITLE" desc="Title for the chrome://crashes page.">
@@ -7548,6 +7355,9 @@
         <message name="IDS_PASSWORD_MANAGER_SAVE_BUTTON" desc="Save button text for password manager">
           Save password
         </message>
+        <message name="IDS_PASSWORD_MANAGER_UNBLACKLIST_BUTTON" desc="Buton text to re-enable the password manager after blacklisting.">
+          Enable password manager
+        </message>
         <message name="IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON" desc="Button text for the 'Save Password' infobar's 'Never remember for this site' option">
           Never for this site
         </message>
@@ -7579,15 +7389,19 @@
         <message name="IDS_IMPORT_FROM_LABEL" desc="Label before profile select combo box">
           From:
         </message>
-        <message name="IDS_IMPORT_FROM_IE" desc="browser combo box: Microsoft Internet Explorer">
-          Microsoft Internet Explorer
-        </message>
+        <if expr="is_win">
+          <message name="IDS_IMPORT_FROM_IE" desc="browser combo box: Microsoft Internet Explorer">
+            Microsoft Internet Explorer
+          </message>
+        </if>
         <message name="IDS_IMPORT_FROM_FIREFOX" desc="browser combo box: Mozilla Firefox">
           Mozilla Firefox
         </message>
+        <!-- TODO(thestig) Should this be Linux only? Add #ifdefs to external_process_importer_client.cc -->
         <message name="IDS_IMPORT_FROM_ICEWEASEL" desc="browser combo box: Iceweasel">
           Iceweasel
         </message>
+        <!-- TODO(thestig) Should this be Mac or Win+Mac only? -->
         <message name="IDS_IMPORT_FROM_SAFARI" desc="browser combo box: Safari">
           Safari
         </message>
@@ -7623,46 +7437,37 @@
           Choose File
         </message>
 
-        <message name="IDS_IMPORTER_GOOGLE_LOGIN_TEXT" desc="The message to be displayed on dialog">
-          In order to import Toolbar bookmarks into Chrome, you must be signed in to your Google account.  Please sign in and try to import again.
-        </message>
         <message name="IDS_IMPORT_NO_PROFILE_FOUND" desc="Message displayed when we do not find any supported browser to import from.">
           No supported browser found
         </message>
-        <message name="IDS_IMPORT_PASSWORD_KEYCHAIN_WARNING" desc="Message displayed at the bottom of the Import Dialog for Safari on Mac OS">
-          Passwords saved in the Mac OS X Keychain will be used to help you sign in without typing.
-        </message>
-
-        <!-- Import progress popup -->
-        <message name="IDS_IMPORT_PROGRESS_TITLE" desc="Title for the importing progress dialog">
-          Importing
-        </message>
-
         <if expr="is_macosx">
-          <message name="IDS_IMPORT_SETTINGS_MENU_MAC" desc="The text label for the Import menu item.">
-            Import Bookmarks and Settings...
+          <message name="IDS_IMPORT_PASSWORD_KEYCHAIN_WARNING" desc="Message displayed at the bottom of the Import Dialog for Safari on Mac OS">
+            Passwords saved in the Mac OS X Keychain will be used to help you sign in without typing.
           </message>
         </if>
 
-        <message name="IDS_IMPORT_PROGRESS_STATUS_BOOKMARKS" desc="Import status for bookmarks">
-          Favorites/Bookmarks
-        </message>
-        <message name="IDS_IMPORT_PROGRESS_STATUS_SEARCH" desc="Import status for search engines">
-          Search settings
-        </message>
-        <message name="IDS_IMPORT_PROGRESS_STATUS_PASSWORDS" desc="Import status for passwords">
-          Saved passwords
-        </message>
-        <message name="IDS_IMPORT_PROGRESS_STATUS_HISTORY" desc="Import status for history">
-          Browsing history
-        </message>
-        <message name="IDS_IMPORT_PROGRESS_STATUS_COOKIES" desc="Import status for cookies">
-          Cookies
-        </message>
-        <message name="IDS_IMPORT_PROGRESS_STATUS_CANCEL" desc="Button text for import cancellation">
-          Stop import
-        </message>
-      </if>
+        <!-- Import progress popup -->
+        <if expr="is_macosx">
+          <message name="IDS_IMPORT_PROGRESS_TITLE" desc="Title for the importing progress dialog">
+            Importing
+          </message>
+          <message name="IDS_IMPORT_SETTINGS_MENU_MAC" desc="The text label for the Import menu item.">
+            Import Bookmarks and Settings...
+          </message>
+          <message name="IDS_IMPORT_PROGRESS_STATUS_BOOKMARKS" desc="Import status for bookmarks">
+            Favorites/Bookmarks
+          </message>
+          <message name="IDS_IMPORT_PROGRESS_STATUS_SEARCH" desc="Import status for search engines">
+            Search settings
+          </message>
+          <message name="IDS_IMPORT_PROGRESS_STATUS_PASSWORDS" desc="Import status for passwords">
+            Saved passwords
+          </message>
+          <message name="IDS_IMPORT_PROGRESS_STATUS_HISTORY" desc="Import status for history">
+            Browsing history
+          </message>
+        </if> <!-- is_macosx -->
+      </if> <!-- not is_android -->
 
       <!-- Confirm to quit panel -->
       <message name="IDS_CONFIRM_TO_QUIT_DESCRIPTION" desc="Instructions for how the user should confirm quitting.">
@@ -8722,10 +8527,10 @@
         Reload
       </message>
       <message name="IDS_ERRORPAGES_BUTTON_LOAD_STALE" desc="Label for the button on an error page to load a stale entry from the cache">
-        Load Stale Local Copy
+        Show saved copy
       </message>
       <message name="IDS_ERRORPAGES_BUTTON_LOAD_STALE_HELP" desc="Explanation for the BUTTON_LOAD_STALE button">
-        Load a known-to-be-out-of-date saved copy of this page.
+        Load a stale (i.e. known to be out of date) copy of this page.
       </message>
       <message name="IDS_ERRORPAGES_BUTTON_DIAGNOSE" desc="Label for the button that invokes the connection diagnostic tool on the error page">
         Diagnose errors...
@@ -8801,13 +8606,13 @@
         Contact your system administrator for more information.
       </message>
       <message name="IDS_ERRORPAGES_SUGGESTION_VISIT_GOOGLE_CACHE" desc="When a page fails to load, sometimes we viewing a version of the page cached on Google's servers.">
-        Access a <ph name="BEGIN_LINK">&lt;a jsvalues="href:urlCorrection"&gt;</ph>cached copy<ph name="END_LINK">&lt;/a&gt;</ph> of <ph name="URL">&lt;span jscontent="originalUrlForDisplay"&gt;&lt;/span&gt;<ex>www.hats-for-goats.com/shiny</ex></ph>
+        Access a <ph name="BEGIN_LINK">&lt;a jsvalues="href:urlCorrection;.jstdata:$this" onmousedown="linkClicked(this.jstdata)"&gt;</ph>cached copy<ph name="END_LINK">&lt;/a&gt;</ph> of <ph name="URL">&lt;span jscontent="originalUrlForDisplay"&gt;&lt;/span&gt;<ex>www.hats-for-goats.com/shiny</ex></ph>
       </message>
       <message name="IDS_ERRORPAGES_SUGGESTION_CORRECTED_URL" desc="When a page fails to load, sometimes we suggest different URL because we think the one the user entered had a typo.">
-        Did you mean <ph name="LINK">&lt;a jsvalues="href:urlCorrection" jscontent="urlCorrectionForDisplay"&gt;&lt;/a&gt;<ex>www.somewhere-spelled-correctly.com</ex></ph>?
+        Did you mean <ph name="LINK">&lt;a jsvalues="href:urlCorrection;.jstdata:$this" onmousedown="linkClicked(this.jstdata)" jscontent="urlCorrectionForDisplay"&gt;&lt;/a&gt;<ex>www.somewhere-spelled-correctly.com</ex></ph>?
       </message>
       <message name="IDS_ERRORPAGES_SUGGESTION_ALTERNATE_URL" desc="When a page fails to load, sometimes we suggest different URL (maybe a different page on the same site, or a site with similar content, for example).">
-        Go to <ph name="LINK">&lt;a jsvalues="href:urlCorrection" jscontent="urlCorrectionForDisplay"&gt;&lt;/a&gt;<ex>www.somewhere.com</ex></ph>
+        Go to <ph name="LINK">&lt;a jsvalues="href:urlCorrection;.jstdata:$this" onmousedown="linkClicked(this.jstdata)" jscontent="urlCorrectionForDisplay"&gt;&lt;/a&gt;<ex>www.somewhere.com</ex></ph>
       </message>
       <message name="IDS_ERRORPAGES_SUGGESTION_GOOGLE_SEARCH" desc="When a page fails to load, sometimes we suggest a specific Google search.  This appears just above a text input control.">
         Search on Google
@@ -9985,9 +9790,6 @@
         <message name="IDS_OPTIONS_PASSWORD_MANAGER_ENABLE" desc="The label of the password manager checkbox">
           Offer to save your web passwords.
         </message>
-        <message name="IDS_OPTIONS_PASSWORDS_MANAGE_PASSWORDS" desc="The label of the 'Manage saved passwords' button">
-          Manage saved passwords...
-        </message>
         <message name="IDS_OPTIONS_PASSWORDS_AUTOLOGIN" desc="The label of the 'autologinEnabled' checkbox">
           Offer to sign in to Google sites automatically with this account
         </message>
@@ -10036,41 +9838,14 @@
           Add a credit card
         </message>
 
-        <message name="IDS_AUTOFILL_FIELD_LABEL_FIRST_NAME" desc="The label of the first name entry.">
-          First name
-        </message>
-        <message name="IDS_AUTOFILL_FIELD_LABEL_MIDDLE_NAME" desc="The label of the middle name entry.">
-          Middle name(s)
-        </message>
-        <message name="IDS_AUTOFILL_FIELD_LABEL_LAST_NAME" desc="The label of the last name entry.">
-          Last name
-        </message>
         <message name="IDS_AUTOFILL_FIELD_LABEL_EMAIL" desc="The label of the Email entry.">
           Email
         </message>
-        <message name="IDS_AUTOFILL_FIELD_LABEL_COMPANY_NAME" desc="The label of the Company name entry.">
-          Company name
-        </message>
-        <message name="IDS_AUTOFILL_FIELD_LABEL_ADDRESS_LINE_1" desc="The label of the Address Line 1 entry.">
-          Address line 1
-        </message>
-        <message name="IDS_AUTOFILL_FIELD_LABEL_ADDRESS_LINE_2" desc="The label of the Address Line 2 entry.">
-          Address line 2
-        </message>
-        <message name="IDS_AUTOFILL_FIELD_LABEL_CITY" desc="The label of the City entry.">
-          City/Town
-        </message>
         <message name="IDS_AUTOFILL_FIELD_LABEL_PHONE" desc="The label of the Phone entry.">
           Phone
         </message>
-        <message name="IDS_AUTOFILL_FIELD_LABEL_ADD_FIRST_NAME" desc="The placeholder text of the first name field.">
-          Add first name
-        </message>
-        <message name="IDS_AUTOFILL_FIELD_LABEL_ADD_MIDDLE_NAME" desc="The placeholder text of the middle name field.">
-          Add middle name(s)
-        </message>
-        <message name="IDS_AUTOFILL_FIELD_LABEL_ADD_LAST_NAME" desc="The placeholder text of the last name field.">
-          Add last name
+        <message name="IDS_AUTOFILL_FIELD_LABEL_ADD_NAME" desc="The placeholder text of the recipient or contact name field.">
+          Add name
         </message>
         <message name="IDS_AUTOFILL_FIELD_LABEL_ADD_PHONE" desc="The placeholder text of the phone field.">
           Add phone number
@@ -10244,9 +10019,6 @@
         <message name="IDS_OPTIONS_SAFEBROWSING_ENABLEDOWNLOADFEEDBACK" desc="Checkbox label: should Chrome upload suspicious downloads to Safe Browsing">
           Send suspicious downloaded files to Google
         </message>
-        <message name="IDS_OPTIONS_SSL_CHECKREVOCATION" desc="The label of the 'Check for server certificate revocation' checkbox">
-          Check for server certificate revocation
-        </message>
 
         <if expr="chromeos">
           <message name="IDS_OPTIONS_FACTORY_RESET" desc="Name of the factory reset option on the chrome settings page">
@@ -10418,8 +10190,8 @@
       <message name="IDS_SETTINGS_SHOW_ADVANCED_SETTINGS" desc="Title for the link to show advanced settings.">
         Show advanced settings...
       </message>
-      <message name="IDS_OPTIONS_PASSWORDS_MANAGE_PASSWORDS_LINK" desc="The label of the 'Manage saved passwords' link">
-        Manage saved passwords
+      <message name="IDS_OPTIONS_PASSWORDS_MANAGE_PASSWORDS_LINK" desc="The label of the 'Manage passwords' link">
+        Manage passwords
       </message>
       <message name="IDS_OPTIONS_HOMEPAGE_TITLE" desc="The title of the home page overlay"  formatter_data="android_java">
         Home page
@@ -10444,24 +10216,6 @@
       <message name="IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC" desc="The placeholder/label text for credit card verification code in the requestAutocomplete dialog.">
         CVC
       </message>
-      <message name="IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARDHOLDER_NAME" desc="The placeholder/label text for cardholder full name in the requestAutocomplete dialog.">
-        Cardholder name
-      </message>
-      <message name="IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESSEE_NAME" desc="The placeholder/label text for addressee full name in the requestAutocomplete dialog.">
-        Name
-      </message>
-      <message name="IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1" desc="The placeholder/label text for address line 1 in the requestAutocomplete dialog.">
-        Street address
-      </message>
-      <message name="IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2" desc="The placeholder/label text for address line 2 in the requestAutocomplete dialog.">
-        Street address (optional)
-      </message>
-      <message name="IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY" desc="The placeholder/label text for locality (city) in the requestAutocomplete dialog.">
-        City
-      </message>
-      <message name="IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE" desc="The placeholder/label text for ZIP/postal code in the requestAutocomplete dialog.">
-        ZIP code
-      </message>
       <message name="IDS_AUTOFILL_DIALOG_PLACEHOLDER_PHONE_NUMBER" desc="The placeholder/label text for phone number in the requestAutocomplete dialog.">
         Phone number
       </message>
@@ -11044,7 +10798,7 @@
                desc="Title of the new tab page, this is only shown while loading, then the title comes from the page">
         New Tab
       </message>
-      
+
       <!-- Strings used for non-Android builds -->
       <if expr="not is_android">
         <message name="IDS_NEW_TAB_SUGGESTIONS"
@@ -11361,7 +11115,7 @@
         settings
       </message>
       <message name="IDS_PROFILES_ACCOUNT_REMOVAL_BUTTON" desc="Text of the ok button on the account removal view in the avatar menu bubble.">
-        Remove account and relaunch
+        Remove account
       </message>
       <message name="IDS_PROFILES_PREVIEW_ENABLED_TUTORIAL_TITLE" desc="Title of the tutorial card in the avatar menu bubble view shown when new profile management preview is enabled.">
         You're all set
@@ -11418,9 +11172,6 @@
           Learn More
         </message>
       </if>
-      <message name="IDS_PROFILES_PROFILE_CHANGE_PHOTO_BUTTON" desc="Button in the avatar menu bubble view used to change the photo for a profile.">
-        Change
-      </message>
       <message name="IDS_PROFILES_SWITCH_TO_PROFILE_ACCESSIBLE_NAME" desc="Description of the switch to profile button. This is used for accessibility.">
         Switch to user: <ph name="PROFILE_NAME">$1<ex>First user</ex></ph>
       </message>
@@ -12230,6 +11981,9 @@
         <message name="IDS_SYNC_STOP_SYNCING_EXPLANATION_LABEL" desc="The text to display below the 'Stop syncing this account' button on the options pane, explaining what the button does.">
           By disconnecting your Google Account from <ph name="PRODUCT_NAME">$1<ex>Chrome</ex></ph>, your data will remain on this computer but changes will no longer be synced to your Google Account. Data already stored in your Google Account will remain there until you remove it using <ph name="BEGIN_LINK">&lt;a href="$2" target=&quot;_blank&quot;&gt;<ex>&lt;a href="$2" target=&quot;_blank&quot;&gt;</ex></ph>Google Dashboard<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>.
         </message>
+        <message name="IDS_SYNC_STOP_DELETE_PROFILE_LABEL" desc="The text to display by the checkbox asking user whether to also delete profile when stopping sync.">
+          Also clear your history, bookmarks, settings, and other Chrome data stored on this device.
+        </message>
         <message name="IDS_SYNC_ADVANCED_OPTIONS" desc="The text in the link that brings up the sync configure screen in the new tab page new data type notification.">
           Advanced settings
         </message>
@@ -13199,6 +12953,9 @@
     <message name="IDS_MANAGE_PASSWORDS" desc="The title text that is used in the manage passwords bubble when a password is autofilled or after a user has stored a password.">
       Saved passwords for this site:
     </message>
+    <message name="IDS_MANAGE_PASSWORDS_BLACKLISTED" desc="The text that is used in the manage passwords bubble when the current site is blacklisted.">
+      The password manager is disabled for this site; no passwords are saved.
+    </message>
     <message name="IDS_MANAGE_PASSWORDS_NO_PASSWORDS" desc="The text that is used in the manage passwords bubble when all passwords have been deleted.">
       No passwords saved.
     </message>
@@ -13329,34 +13086,6 @@
        Keep using <ph name="CURRENT_GOOGLE_HOST">$1<ex>google.fr</ex></ph>
     </message>
 
-    <message name="IDS_SPEECH_INPUT_BUBBLE_HEADING" desc="First line in the content area of the speech input bubble. Instructs the user that they can start speaking.">
-      Speak now
-    </message>
-    <message name="IDS_SPEECH_INPUT_ABORTED" desc="Message shown when speech recognition is aborted (due to another request).">
-      Speech recognition was aborted.
-    </message>
-    <message name="IDS_SPEECH_INPUT_MIC_ERROR" desc="Message shown when audio recording failed with an error during speech recognition.">
-      There was a problem with your microphone.
-    </message>
-    <message name="IDS_SPEECH_INPUT_NO_MIC" desc="Message shown when speech recognizer could not find a suitable microphone or other audio input device.">
-      No microphone found.
-    </message>
-    <message name="IDS_SPEECH_INPUT_NO_SPEECH" desc="Message shown when speech recognizer detected no speech in the recorded audio.">
-      No speech heard.
-    </message>
-    <message name="IDS_SPEECH_INPUT_NO_RESULTS" desc="Message shown when speech recognizer returned zero results.">
-      Speech not recognized.
-    </message>
-    <message name="IDS_SPEECH_INPUT_TRY_AGAIN" desc="Text shown on a button to retry speech recognition">
-      Try again
-    </message>
-    <message name="IDS_SPEECH_INPUT_NET_ERROR" desc="Message shown when a network error occurred and no results were received from the recognition server.">
-      Connection to speech servers failed.
-    </message>
-    <message name="IDS_SPEECH_INPUT_MIC_SETTINGS" desc="Text displayed on a button or link to open the microphone settings window.">
-      Microphone settings
-    </message>
-
     <message name="IDS_IMAGE_FILES" desc="The description of the image file extensions in the select file dialog.">
       Image Files
     </message>
@@ -13474,9 +13203,11 @@
       <message name="IDS_PDF_BUBBLE_INSTALL_READER_LINK" desc="Title of the link to open a PDF with an unsupported feature in Adobe Reader">
         Install Adobe Reader
       </message>
-      <message name="IDS_PDF_BUBBLE_METRO_MODE_LINK" desc="Title of the link to restart Chrome on Windows 8 in metro mode when viewing a PDF with an unsupported feature.">
-        Relaunch Chrome on the desktop
-      </message>
+      <if expr="is_win">
+        <message name="IDS_PDF_BUBBLE_METRO_MODE_LINK" desc="Title of the link to restart Chrome on Windows 8 in metro mode when viewing a PDF with an unsupported feature.">
+          Relaunch Chrome on the desktop
+        </message>
+      </if>
       <message name="IDS_PDF_INFOBAR_QUESTION_ALWAYS_USE_READER" desc="Question asked on the info bar when a user opens a PDF with Reader and we want to ask them if they always want to use it for viewing PDF files.">
         Use Adobe Reader as your default PDF viewer?
       </message>
@@ -13968,6 +13699,12 @@
     <message name="IDS_FLAGS_ENABLE_OFFLINE_AUTO_RELOAD_DESCRIPTION" desc="Description of the flag to make pages which failed to load while offline auto-reload">
       Pages that fail to load while the browser is offline will be auto-reloaded when the browser is online again.
     </message>
+    <message name="IDS_FLAGS_ENABLE_OFFLINE_LOAD_STALE_NAME" desc="Name of the flag to enable offering users the option of loading a stale copy of a page when an error occurs.">
+      Enable Offline Load Stale Button
+    </message>
+    <message name="IDS_FLAGS_ENABLE_OFFLINE_LOAD_STALE_DESCRIPTION" desc="Description of the flag to enable offering users the option of loading a stale copy of a page when an error occurs.">
+      When a page fails to load, if a stale copy of the page exists in the browser, a button will be presented to allow the user to load that stale copy.
+    </message>
 
     <message name="IDS_FLAGS_ENABLE_VIRTUAL_KEYBOARD_NAME" desc="Name of about:flags option to turn on the virtual keyboard">
       Virtual Keyboard
@@ -13983,19 +13720,21 @@
       Enable virtual keyboard overscroll support.
     </message>
 
-    <message name="IDS_FLAGS_ENABLE_SWIPE_SELECTION_NAME" desc="Name of about:flags option to turn on swipe selection for the virtual keyboard">
-      Swipe Selection
-    </message>
-    <message name="IDS_FLAGS_ENABLE_SWIPE_SELECTION_DESCRIPTION" desc="Description of about:flags option to turn on swipe selection for the virtual keyboard">
-      Enable Swipe Selection support for the virtual keyboard. Unless the virtual keyboard is also enabled, this will do nothing.
-    </message>
+    <if expr="chromeos">
+      <message name="IDS_FLAGS_ENABLE_SWIPE_SELECTION_NAME" desc="Name of about:flags option to turn on swipe selection for the virtual keyboard">
+        Swipe Selection
+      </message>
+      <message name="IDS_FLAGS_ENABLE_SWIPE_SELECTION_DESCRIPTION" desc="Description of about:flags option to turn on swipe selection for the virtual keyboard">
+        Enable Swipe Selection support for the virtual keyboard. Unless the virtual keyboard is also enabled, this will do nothing.
+      </message>
 
-    <message name="IDS_FLAGS_ENABLE_INPUT_VIEW_NAME" desc="Name of about::flags option to enable IME extensions to override the virtual keyboard view">
-      Enable input views.
-    </message>
-    <message name="IDS_FLAGS_ENABLE_INPUT_VIEW_DESCRIPTION" desc="Description of about::flags option to enable IME extensions to override the virtual keyboard view">
-      Enable IME extensions to supply custom views for user input such as  virtual keyboards.
-    </message>
+      <message name="IDS_FLAGS_ENABLE_INPUT_VIEW_NAME" desc="Name of about::flags option to enable IME extensions to override the virtual keyboard view">
+        Enable input views.
+      </message>
+      <message name="IDS_FLAGS_ENABLE_INPUT_VIEW_DESCRIPTION" desc="Description of about::flags option to enable IME extensions to override the virtual keyboard view">
+        Enable IME extensions to supply custom views for user input such as  virtual keyboards.
+      </message>
+    </if>
 
     <!-- Simple Cache Backend experiment. -->
     <message name="IDS_FLAGS_ENABLE_SIMPLE_CACHE_BACKEND_NAME" desc="Name of about:flags option to turn on the Simple Cache Backend">
@@ -14300,9 +14039,6 @@
     </message>
 
     <!-- Password generation strings -->
-    <message name="IDS_PASSWORD_GENERATION_SUGGESTION" desc="Text shown next to a generated password describing it as a suggestion.">
-      Suggested
-    </message>
     <message name="IDS_PASSWORD_GENERATION_PROMPT" desc="Autofill dropdown text describing password generation. The text inside |bars| is link text.">
       Chrome will add this to your |saved passwords|.
     </message>
@@ -14564,24 +14300,26 @@
     </message>
 
     <!-- Zero suggest experiment flags -->
-    <message name="IDS_FLAGS_ZERO_SUGGEST_EXPERIMENT_NAME" desc="An about:flags experiment for zero suggest">
-      Zero Suggest
-    </message>
-    <message name="IDS_FLAGS_ZERO_SUGGEST_EXPERIMENT_DESCRIPTION" desc="Describes about:flags experiment options for zero suggest">
-      NOTE: Only works dev and canary channels. Turns on suggestions in the omnibox that are shown on focus before typing.
-    </message>
-    <message name="IDS_FLAGS_ZERO_SUGGEST_MOST_VISITED" desc="A choice in dropdown dialog on about:flags page for the most visited sites option">
-      Most visited
-    </message>
-    <message name="IDS_FLAGS_ZERO_SUGGEST_ETHER_SERP" desc="A choice in dropdown dialog on about:flags page to show zero suggest on http pages and Google.com">
-      Related URLs and Google.com searches
-    </message>
-    <message name="IDS_FLAGS_ZERO_SUGGEST_ETHER_NO_SERP" desc="A choice in dropdown dialog on about:flags page to show zero suggest on http pages only">
-      Related URLs only
-    </message>
-    <message name="IDS_FLAGS_ZERO_SUGGEST_PERSONALIZED" desc="A choice in dropdown dialog on about:flags page to show personalized zero-prefix suggestions">
-      Personalized
-    </message>
+    <if expr="is_android">
+      <message name="IDS_FLAGS_ZERO_SUGGEST_EXPERIMENT_NAME" desc="An about:flags experiment for zero suggest">
+        Zero Suggest
+      </message>
+      <message name="IDS_FLAGS_ZERO_SUGGEST_EXPERIMENT_DESCRIPTION" desc="Describes about:flags experiment options for zero suggest">
+        NOTE: Only works dev and canary channels. Turns on suggestions in the omnibox that are shown on focus before typing.
+      </message>
+      <message name="IDS_FLAGS_ZERO_SUGGEST_MOST_VISITED" desc="A choice in dropdown dialog on about:flags page for the most visited sites option">
+        Most visited
+      </message>
+      <message name="IDS_FLAGS_ZERO_SUGGEST_ETHER_SERP" desc="A choice in dropdown dialog on about:flags page to show zero suggest on http pages and Google.com">
+        Related URLs and Google.com searches
+      </message>
+      <message name="IDS_FLAGS_ZERO_SUGGEST_ETHER_NO_SERP" desc="A choice in dropdown dialog on about:flags page to show zero suggest on http pages only">
+        Related URLs only
+      </message>
+      <message name="IDS_FLAGS_ZERO_SUGGEST_PERSONALIZED" desc="A choice in dropdown dialog on about:flags page to show personalized zero-prefix suggestions">
+        Personalized
+      </message>
+    </if>
     <message name="IDS_FLAGS_DISABLE_IGNORE_AUTOCOMPLETE_OFF_NAME" desc="Name of the disable ignore autocomplete='off' lab">
       Disable ignore autocomplete='off'
     </message>
@@ -14620,7 +14358,7 @@
     <message name="IDS_FLAGS_ALLOW_INSECURE_WEBSOCKET_FROM_HTTPS_ORIGIN_DESCRIPTION" desc="Description to allow insecure WebSocket from https origin">
       This flag makes Chrome unsafe. Use this only if you understand what this does. Note that this flag may be removed without any notice. If enabled, frames with an https origin can use WebSockets with an insecure URL (ws://).
     </message>
-    
+
     <!-- Experiment flags to enable EmbeddedSearch API in the search results page -->
     <if expr="is_android">
     <message name="IDS_FLAGS_ENABLE_EMBEDDEDSEARCH_API_NAME" desc="An about::flags experiment title to enable EmbeddedSearch API in the search results page">
@@ -14630,6 +14368,34 @@
      If enabled, EmbeddedSearch API will be used to submit search queries in the search results page.
     </message>
     </if>
+
+    <!-- App install alerts flags -->
+    <message name="IDS_FLAGS_ENABLE_APP_INSTALL_ALERTS_NAME" desc="Title for the flag to allow app install alerts">
+      Enable app install alerts
+    </message>
+    <message name="IDS_FLAGS_ENABLE_APP_INSTALL_ALERTS_DESCRIPTION" desc="Description to allow app install alerts">
+      If enabled, websites will be parsed for app install alert meta tags.
+    </message>
+
+   <!-- Extension Content Verification -->
+    <message name="IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_NAME" desc="Name of the 'Extension Content Verification' flag">
+      Extension Content Verification
+    </message>
+    <message name="IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_DESCRIPTION" desc="Title for the flag to turn on verification of the contents of extensions from the webstore">
+      This flag can be used to turn on verification that the contents of the files on disk for extensions from the webstore match what they're expected to be. This can be used to turn on this feature if it would not otherwise have been turned on, but cannot be used to turn it off (because this setting can be tampered with by malware).
+    </message>
+
+    <message name="IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_BOOTSTRAP" desc="Description of the 'Extension Content Verification' bootstrap mode">
+      Bootstrap (get expected hashes, but do not enforce them)
+    </message>
+
+    <message name="IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_ENFORCE" desc="Description of the 'Extension Content Verification' enforce mode">
+      Enforce (try to get hashes, and enforce them if successful)
+    </message>
+
+    <message name="IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_ENFORCE_STRICT" desc="Description of the 'Extension Content Verification' enforce strict mode">
+      Enforce strict (hard fail if we can't get hashes)
+    </message>
   </messages>
   </release>
 </grit>
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index 2acf82a..d31e971 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -268,9 +268,6 @@
       <message name="IDS_BROWSER_HUNGBROWSER_MESSAGE" desc="Content of the dialog box shown when the browser is hung">
         Google Chrome is unresponsive. Relaunch now?
       </message>
-      <message name="IDS_IMPORT_PROGRESS_INFO" desc="Explanatory text for the importing progress dialog">
-        Google Chrome is now importing the following items from <ph name="BROWSER_COMPONENT">$1<ex>History</ex></ph>:
-      </message>
       <message name="IDS_IMPORT_FIND_YOUR_BOOKMARKS" desc="Helpful reminder for where to find imported bookmarks">
         Find your bookmarks in the Chrome menu or on the bookmarks bar.
       </message>
@@ -327,12 +324,11 @@
         </message>
       </if>
       <!-- Strings used to warn that an OS is not supported -->
-      <message name="IDS_UNSUPPORTED_OS_PRE_WIN_XP" desc="The text used to warn the user that Windows pre-XP is not supported">
-        Google Chrome requires Windows XP or later. Some features may not work.
-      </message>
-      <message name="IDS_UNSUPPORTED_OS" desc="The text used to warn the user that current OS is not supported">
-        Google Chrome does not support <ph name="OS_NAME">$1<ex>Windows 2000</ex></ph>.
-      </message>
+      <if expr="is_win">
+        <message name="IDS_UNSUPPORTED_OS_PRE_WIN_XP" desc="The text used to warn the user that Windows pre-XP is not supported">
+          Google Chrome requires Windows XP or later. Some features may not work.
+        </message>
+      </if>
       <if expr="not chromeos">
         <message name="IDS_OPTIONS_RELAUNCH_REQUIRED" desc="The message displayed for an option that requires a relaunch to take effect. This appears in a message box if an option is changed that requires a relaunch.">
           Please close all Google Chrome windows and relaunch it for this change to take effect.
@@ -392,6 +388,9 @@
       <message name="IDS_CRASH_RECOVERY_CONTENT" desc="Text content telling the user the browser has crashed.">
         Whoa! Google Chrome has crashed. Relaunch now?
       </message>
+      <message name="IDS_PASSWORD_GENERATION_SUGGESTION" desc="Text shown next to a generated password describing it as a suggestion.">
+        Suggested by Chrome
+      </message>
       <if expr="not is_android">
         <message name="IDS_PASSWORD_MANAGER_SAVE_PASSWORD_PROMPT" desc="Info bar message to save a password">
           Do you want Google Chrome to save your password?
@@ -461,9 +460,6 @@
       <message name="IDS_OPTIONS_IMPROVE_BROWSING_EXPERIENCE" desc="The text in the options panel that describes how we use web services to improve browsing experience.">
         Google Chrome may use web services to improve your browsing experience.
       </message>
-      <message name="IDS_IMPORT_BOOKMARKS" desc="Explanatory text for the importing progress dialog when importing a bookmarks.html file from the bookmark manager">
-        Google Chrome is now importing Favorites/Bookmarks.
-      </message>
       <message name="IDS_OEM_MAIN_SHORTCUT_NAME" desc="Name of the desktop shortcut to start the application for OEM pre-installations.">
         Internet Browser
       </message>
@@ -697,7 +693,7 @@
       </message>
 
       <if expr="enable_extensions">
-        <message name="IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BODY" desc="Body of the dialog shown when suspicious extensions have been disabled">
+        <message name="IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BODY" desc="Body of the dialog shown when unsupported extensions have been disabled">
           To make Chrome safer, we disabled some extensions that aren't listed in the <ph name="IDS_EXTENSION_WEB_STORE_TITLE">$1<ex>Chrome Web Store</ex></ph> and may have been added without your knowledge.
         </message>
       </if>
@@ -765,7 +761,7 @@
 
       <!-- Account removal view in the avatar menu bubble -->
       <message name="IDS_PROFILES_ACCOUNT_REMOVAL_TEXT" desc="Main text of the account removal view when removing a secondary account.">
-        To remove your account, Chrome needs to restart. Make sure you've saved any open work before continuing.
+        After removing your account from Chrome, you may need to reload your open tabs to take effect.
       </message>
       <message name="IDS_PROFILES_PRIMARY_ACCOUNT_REMOVAL_TEXT" desc="Main text of the account removal view when removing a primary account.">
         You're using <ph name="PROFILE_EMAIL">$1<ex>jessica@gmail.com</ex></ph> to sync your Chrome stuff. To update your sync preference or to use Chrome without a Google account, visit <ph name="SETTINGS_LINK">$2<ex>settings</ex></ph>.
@@ -866,13 +862,15 @@
         </message>
       </if>
 
-      <message name="IDS_OPTIONS_PASSWORDS_MAC_WARNING" desc="The warning for OS X that passwords are shared across profiles in the keychain.">
-        On Mac, passwords are saved to your Keychain and may be accessed or synced by other Chrome users sharing this OS X account.
-      </message>
+      <if expr="is_macosx">
+        <message name="IDS_OPTIONS_PASSWORDS_MAC_WARNING" desc="The warning for OS X that passwords are shared across profiles in the keychain.">
+          On Mac, passwords are saved to your Keychain and may be accessed or synced by other Chrome users sharing this OS X account.
+        </message>
+        <message name="IDS_AUTOFILL_ADDRESS_BOOK_PROMPT_DESCRIPTION" desc="Text to show in dialog requesting permission to access the user's Address Book contents.">
+          Details from your contacts can help you fill out forms more quickly in Chrome.
+        </message>
+      </if>
 
-      <message name="IDS_AUTOFILL_ADDRESS_BOOK_PROMPT_DESCRIPTION" desc="Text to show in dialog requesting permission to access the user's Address Book contents.">
-        Details from your contacts can help you fill out forms more quickly in Chrome.
-      </message>
       <message name="IDS_AUTOFILL_CC_INFOBAR_TEXT" desc="Text to show in the Autofill credit card request infobar.">
         Do you want Chrome to save this credit card information for completing web forms?
       </message>
@@ -1126,16 +1124,6 @@
       <message name="IDS_UPGRADE_BUBBLE_REENABLE_TEXT" desc="Text for the upgrade bubble view full description.">
         Chrome could not update itself to the latest version, so you are missing out on awesome new features and security fixes. You need to update Chrome.
       </message>
-
-      <!-- chrome://ntp -->
-      <if expr="not is_android">
-        <message name="IDS_NEW_TAB_OTR_EXTENSIONS_MESSAGE"
-                 desc="Explanation in a new OTR window that extensions have been disabled while in OTR.">
-          Because Google Chrome does not control how extensions handle your personal data, all extensions have been disabled for incognito windows. You can reenable them individually in the
-          <ph name="BEGIN_LINK">&lt;a href="$1"&gt;</ph>extensions manager<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>.
-        </message>
-      </if>
-
     </messages>
   </release>
 </grit>
diff --git a/chrome/app/nibs/SpeechRecognitionBubble.xib b/chrome/app/nibs/SpeechRecognitionBubble.xib
deleted file mode 100644
index 1ff4190..0000000
--- a/chrome/app/nibs/SpeechRecognitionBubble.xib
+++ /dev/null
@@ -1,825 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
-	<data>
-		<int key="IBDocument.SystemTarget">1070</int>
-		<string key="IBDocument.SystemVersion">12B19</string>
-		<string key="IBDocument.InterfaceBuilderVersion">2549</string>
-		<string key="IBDocument.AppKitVersion">1187</string>
-		<string key="IBDocument.HIToolboxVersion">624.00</string>
-		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
-			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
-			<string key="NS.object.0">2549</string>
-		</object>
-		<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
-			<bool key="EncodedWithXMLCoder">YES</bool>
-			<string>NSButton</string>
-			<string>NSButtonCell</string>
-			<string>NSCustomObject</string>
-			<string>NSCustomView</string>
-			<string>NSImageCell</string>
-			<string>NSImageView</string>
-			<string>NSTextField</string>
-			<string>NSTextFieldCell</string>
-			<string>NSView</string>
-			<string>NSWindowTemplate</string>
-		</object>
-		<object class="NSArray" key="IBDocument.PluginDependencies">
-			<bool key="EncodedWithXMLCoder">YES</bool>
-			<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-		</object>
-		<object class="NSMutableDictionary" key="IBDocument.Metadata">
-			<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
-			<integer value="1" key="NS.object.0"/>
-		</object>
-		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
-			<bool key="EncodedWithXMLCoder">YES</bool>
-			<object class="NSCustomObject" id="1021">
-				<string key="NSClassName">SpeechRecognitionWindowController</string>
-			</object>
-			<object class="NSCustomObject" id="1014">
-				<string key="NSClassName">FirstResponder</string>
-			</object>
-			<object class="NSCustomObject" id="1050">
-				<string key="NSClassName">NSApplication</string>
-			</object>
-			<object class="NSWindowTemplate" id="513744381">
-				<int key="NSWindowStyleMask">15</int>
-				<int key="NSWindowBacking">2</int>
-				<string key="NSWindowRect">{{196, 320}, {190, 190}}</string>
-				<int key="NSWTFlags">611847168</int>
-				<string key="NSWindowTitle">Window</string>
-				<string key="NSWindowClass">InfoBubbleWindow</string>
-				<nil key="NSViewClass"/>
-				<nil key="NSUserInterfaceItemIdentifier"/>
-				<object class="NSView" key="NSWindowView" id="414427165">
-					<reference key="NSNextResponder"/>
-					<int key="NSvFlags">256</int>
-					<object class="NSMutableArray" key="NSSubviews">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSCustomView" id="926910107">
-							<reference key="NSNextResponder" ref="414427165"/>
-							<int key="NSvFlags">301</int>
-							<object class="NSMutableArray" key="NSSubviews">
-								<bool key="EncodedWithXMLCoder">YES</bool>
-								<object class="NSButton" id="476113060">
-									<reference key="NSNextResponder" ref="926910107"/>
-									<int key="NSvFlags">268</int>
-									<string key="NSFrame">{{7, 113}, {96, 32}}</string>
-									<reference key="NSSuperview" ref="926910107"/>
-									<reference key="NSWindow"/>
-									<bool key="NSEnabled">YES</bool>
-									<object class="NSButtonCell" key="NSCell" id="607686812">
-										<int key="NSCellFlags">67108864</int>
-										<int key="NSCellFlags2">134217728</int>
-										<string key="NSContents">^IDS_SPEECH_INPUT_MIC_SETTINGS</string>
-										<object class="NSFont" key="NSSupport" id="487155245">
-											<string key="NSName">LucidaGrande</string>
-											<double key="NSSize">13</double>
-											<int key="NSfFlags">1044</int>
-										</object>
-										<reference key="NSControlView" ref="476113060"/>
-										<int key="NSButtonFlags">-2046672896</int>
-										<int key="NSButtonFlags2">134</int>
-										<string key="NSAlternateContents"/>
-										<string key="NSKeyEquivalent"/>
-										<int key="NSPeriodicDelay">200</int>
-										<int key="NSPeriodicInterval">25</int>
-									</object>
-									<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
-								</object>
-								<object class="NSButton" id="1038338233">
-									<reference key="NSNextResponder" ref="926910107"/>
-									<int key="NSvFlags">268</int>
-									<string key="NSFrame">{{14, 12}, {82, 32}}</string>
-									<reference key="NSSuperview" ref="926910107"/>
-									<reference key="NSWindow"/>
-									<bool key="NSEnabled">YES</bool>
-									<object class="NSButtonCell" key="NSCell" id="84459405">
-										<int key="NSCellFlags">67108864</int>
-										<int key="NSCellFlags2">134217728</int>
-										<string key="NSContents">^IDS_SPEECH_INPUT_TRY_AGAIN</string>
-										<reference key="NSSupport" ref="487155245"/>
-										<reference key="NSControlView" ref="1038338233"/>
-										<int key="NSButtonFlags">-2038284288</int>
-										<int key="NSButtonFlags2">129</int>
-										<string key="NSAlternateContents"/>
-										<string key="NSKeyEquivalent"/>
-										<int key="NSPeriodicDelay">200</int>
-										<int key="NSPeriodicInterval">25</int>
-									</object>
-									<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
-								</object>
-								<object class="NSButton" id="789820196">
-									<reference key="NSNextResponder" ref="926910107"/>
-									<int key="NSvFlags">268</int>
-									<string key="NSFrame">{{88, 12}, {88, 32}}</string>
-									<reference key="NSSuperview" ref="926910107"/>
-									<reference key="NSWindow"/>
-									<bool key="NSEnabled">YES</bool>
-									<object class="NSButtonCell" key="NSCell" id="541512844">
-										<int key="NSCellFlags">67108864</int>
-										<int key="NSCellFlags2">134217728</int>
-										<string key="NSContents">^IDS_CANCEL</string>
-										<reference key="NSSupport" ref="487155245"/>
-										<reference key="NSControlView" ref="789820196"/>
-										<int key="NSButtonFlags">-2038284288</int>
-										<int key="NSButtonFlags2">129</int>
-										<string key="NSAlternateContents"/>
-										<string key="NSKeyEquivalent"/>
-										<int key="NSPeriodicDelay">200</int>
-										<int key="NSPeriodicInterval">25</int>
-									</object>
-									<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
-								</object>
-								<object class="NSImageView" id="793691203">
-									<reference key="NSNextResponder" ref="926910107"/>
-									<int key="NSvFlags">268</int>
-									<object class="NSMutableSet" key="NSDragTypes">
-										<bool key="EncodedWithXMLCoder">YES</bool>
-										<object class="NSArray" key="set.sortedObjects">
-											<bool key="EncodedWithXMLCoder">YES</bool>
-											<string>Apple PDF pasteboard type</string>
-											<string>Apple PICT pasteboard type</string>
-											<string>Apple PNG pasteboard type</string>
-											<string>NSFilenamesPboardType</string>
-											<string>NeXT Encapsulated PostScript v1.2 pasteboard type</string>
-											<string>NeXT TIFF v4.0 pasteboard type</string>
-										</object>
-									</object>
-									<string key="NSFrame">{{69, 72}, {51, 51}}</string>
-									<reference key="NSSuperview" ref="926910107"/>
-									<reference key="NSWindow"/>
-									<bool key="NSEnabled">YES</bool>
-									<object class="NSImageCell" key="NSCell" id="709197696">
-										<int key="NSCellFlags">134217728</int>
-										<int key="NSCellFlags2">33587200</int>
-										<object class="NSCustomResource" key="NSContents">
-											<string key="NSClassName">NSImage</string>
-											<string key="NSResourceName">speech_input_recording</string>
-										</object>
-										<int key="NSAlign">0</int>
-										<int key="NSScale">0</int>
-										<int key="NSStyle">0</int>
-										<bool key="NSAnimates">NO</bool>
-									</object>
-									<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
-									<bool key="NSEditable">YES</bool>
-								</object>
-								<object class="NSTextField" id="530565492">
-									<reference key="NSNextResponder" ref="926910107"/>
-									<int key="NSvFlags">268</int>
-									<string key="NSFrame">{{17, 153}, {156, 17}}</string>
-									<reference key="NSSuperview" ref="926910107"/>
-									<reference key="NSWindow"/>
-									<bool key="NSEnabled">YES</bool>
-									<object class="NSTextFieldCell" key="NSCell" id="806350986">
-										<int key="NSCellFlags">67108864</int>
-										<int key="NSCellFlags2">138444800</int>
-										<string key="NSContents">^IDS_SPEECH_INPUT_BUBBLE_HEADING</string>
-										<object class="NSFont" key="NSSupport">
-											<string key="NSName">LucidaGrande</string>
-											<double key="NSSize">13</double>
-											<int key="NSfFlags">16</int>
-										</object>
-										<reference key="NSControlView" ref="530565492"/>
-										<object class="NSColor" key="NSBackgroundColor">
-											<int key="NSColorSpace">6</int>
-											<string key="NSCatalogName">System</string>
-											<string key="NSColorName">controlColor</string>
-											<object class="NSColor" key="NSColor">
-												<int key="NSColorSpace">3</int>
-												<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
-											</object>
-										</object>
-										<object class="NSColor" key="NSTextColor">
-											<int key="NSColorSpace">6</int>
-											<string key="NSCatalogName">System</string>
-											<string key="NSColorName">controlTextColor</string>
-											<object class="NSColor" key="NSColor">
-												<int key="NSColorSpace">3</int>
-												<bytes key="NSWhite">MAA</bytes>
-											</object>
-										</object>
-									</object>
-									<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
-								</object>
-							</object>
-							<string key="NSFrameSize">{190, 190}</string>
-							<reference key="NSSuperview" ref="414427165"/>
-							<reference key="NSWindow"/>
-							<string key="NSClassName">InfoBubbleView</string>
-						</object>
-					</object>
-					<string key="NSFrameSize">{190, 190}</string>
-					<reference key="NSSuperview"/>
-					<reference key="NSWindow"/>
-				</object>
-				<string key="NSScreenRect">{{0, 0}, {1680, 1028}}</string>
-				<string key="NSMaxSize">{10000000000000, 10000000000000}</string>
-				<bool key="NSWindowIsRestorable">YES</bool>
-			</object>
-			<object class="NSCustomObject" id="19393743">
-				<string key="NSClassName">ChromeUILocalizer</string>
-			</object>
-			<object class="NSCustomObject" id="184494044">
-				<string key="NSClassName">GTMUILocalizerAndLayoutTweaker</string>
-			</object>
-		</object>
-		<object class="IBObjectContainer" key="IBDocument.Objects">
-			<object class="NSMutableArray" key="connectionRecords">
-				<bool key="EncodedWithXMLCoder">YES</bool>
-				<object class="IBConnectionRecord">
-					<object class="IBOutletConnection" key="connection">
-						<string key="label">cancelButton_</string>
-						<reference key="source" ref="1021"/>
-						<reference key="destination" ref="789820196"/>
-					</object>
-					<int key="connectionID">829</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBOutletConnection" key="connection">
-						<string key="label">iconImage_</string>
-						<reference key="source" ref="1021"/>
-						<reference key="destination" ref="793691203"/>
-					</object>
-					<int key="connectionID">830</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBOutletConnection" key="connection">
-						<string key="label">window</string>
-						<reference key="source" ref="1021"/>
-						<reference key="destination" ref="513744381"/>
-					</object>
-					<int key="connectionID">833</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBActionConnection" key="connection">
-						<string key="label">cancel:</string>
-						<reference key="source" ref="1021"/>
-						<reference key="destination" ref="789820196"/>
-					</object>
-					<int key="connectionID">834</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBOutletConnection" key="connection">
-						<string key="label">bubble_</string>
-						<reference key="source" ref="1021"/>
-						<reference key="destination" ref="926910107"/>
-					</object>
-					<int key="connectionID">835</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBOutletConnection" key="connection">
-						<string key="label">instructionLabel_</string>
-						<reference key="source" ref="1021"/>
-						<reference key="destination" ref="530565492"/>
-					</object>
-					<int key="connectionID">836</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBOutletConnection" key="connection">
-						<string key="label">tryAgainButton_</string>
-						<reference key="source" ref="1021"/>
-						<reference key="destination" ref="1038338233"/>
-					</object>
-					<int key="connectionID">840</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBActionConnection" key="connection">
-						<string key="label">tryAgain:</string>
-						<reference key="source" ref="1021"/>
-						<reference key="destination" ref="1038338233"/>
-					</object>
-					<int key="connectionID">841</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBActionConnection" key="connection">
-						<string key="label">micSettings:</string>
-						<reference key="source" ref="1021"/>
-						<reference key="destination" ref="476113060"/>
-					</object>
-					<int key="connectionID">844</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBOutletConnection" key="connection">
-						<string key="label">micSettingsButton_</string>
-						<reference key="source" ref="1021"/>
-						<reference key="destination" ref="476113060"/>
-					</object>
-					<int key="connectionID">845</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBOutletConnection" key="connection">
-						<string key="label">delegate</string>
-						<reference key="source" ref="513744381"/>
-						<reference key="destination" ref="1021"/>
-					</object>
-					<int key="connectionID">828</int>
-				</object>
-				<object class="IBConnectionRecord">
-					<object class="IBOutletConnection" key="connection">
-						<string key="label">owner_</string>
-						<reference key="source" ref="19393743"/>
-						<reference key="destination" ref="1021"/>
-					</object>
-					<int key="connectionID">837</int>
-				</object>
-			</object>
-			<object class="IBMutableOrderedSet" key="objectRecords">
-				<object class="NSArray" key="orderedObjects">
-					<bool key="EncodedWithXMLCoder">YES</bool>
-					<object class="IBObjectRecord">
-						<int key="objectID">0</int>
-						<object class="NSArray" key="object" id="0">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-						</object>
-						<reference key="children" ref="1048"/>
-						<nil key="parent"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">-2</int>
-						<reference key="object" ref="1021"/>
-						<reference key="parent" ref="0"/>
-						<string key="objectName">File's Owner</string>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">-1</int>
-						<reference key="object" ref="1014"/>
-						<reference key="parent" ref="0"/>
-						<string key="objectName">First Responder</string>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">-3</int>
-						<reference key="object" ref="1050"/>
-						<reference key="parent" ref="0"/>
-						<string key="objectName">Application</string>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">367</int>
-						<reference key="object" ref="513744381"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="414427165"/>
-						</object>
-						<reference key="parent" ref="0"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">368</int>
-						<reference key="object" ref="414427165"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="926910107"/>
-						</object>
-						<reference key="parent" ref="513744381"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">818</int>
-						<reference key="object" ref="19393743"/>
-						<reference key="parent" ref="0"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">819</int>
-						<reference key="object" ref="184494044"/>
-						<reference key="parent" ref="0"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">825</int>
-						<reference key="object" ref="926910107"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="530565492"/>
-							<reference ref="793691203"/>
-							<reference ref="789820196"/>
-							<reference ref="1038338233"/>
-							<reference ref="476113060"/>
-						</object>
-						<reference key="parent" ref="414427165"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">811</int>
-						<reference key="object" ref="530565492"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="806350986"/>
-						</object>
-						<reference key="parent" ref="926910107"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">812</int>
-						<reference key="object" ref="806350986"/>
-						<reference key="parent" ref="530565492"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">815</int>
-						<reference key="object" ref="793691203"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="709197696"/>
-						</object>
-						<reference key="parent" ref="926910107"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">816</int>
-						<reference key="object" ref="709197696"/>
-						<reference key="parent" ref="793691203"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">813</int>
-						<reference key="object" ref="789820196"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="541512844"/>
-						</object>
-						<reference key="parent" ref="926910107"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">814</int>
-						<reference key="object" ref="541512844"/>
-						<reference key="parent" ref="789820196"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">838</int>
-						<reference key="object" ref="1038338233"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="84459405"/>
-						</object>
-						<reference key="parent" ref="926910107"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">839</int>
-						<reference key="object" ref="84459405"/>
-						<reference key="parent" ref="1038338233"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">842</int>
-						<reference key="object" ref="476113060"/>
-						<object class="NSMutableArray" key="children">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<reference ref="607686812"/>
-						</object>
-						<reference key="parent" ref="926910107"/>
-					</object>
-					<object class="IBObjectRecord">
-						<int key="objectID">843</int>
-						<reference key="object" ref="607686812"/>
-						<reference key="parent" ref="476113060"/>
-					</object>
-				</object>
-			</object>
-			<object class="NSMutableDictionary" key="flattenedProperties">
-				<bool key="EncodedWithXMLCoder">YES</bool>
-				<object class="NSArray" key="dict.sortedKeys">
-					<bool key="EncodedWithXMLCoder">YES</bool>
-					<string>-1.IBPluginDependency</string>
-					<string>-2.IBPluginDependency</string>
-					<string>-3.IBPluginDependency</string>
-					<string>367.IBPluginDependency</string>
-					<string>367.IBWindowTemplateEditedContentRect</string>
-					<string>367.NSWindowTemplate.visibleAtLaunch</string>
-					<string>368.IBPluginDependency</string>
-					<string>811.IBPluginDependency</string>
-					<string>812.IBPluginDependency</string>
-					<string>813.IBPluginDependency</string>
-					<string>814.IBPluginDependency</string>
-					<string>815.IBPluginDependency</string>
-					<string>816.IBPluginDependency</string>
-					<string>818.IBPluginDependency</string>
-					<string>819.IBPluginDependency</string>
-					<string>825.IBPluginDependency</string>
-					<string>838.IBPluginDependency</string>
-					<string>839.IBPluginDependency</string>
-					<string>842.IBPluginDependency</string>
-					<string>843.CustomClassName</string>
-					<string>843.IBPluginDependency</string>
-				</object>
-				<object class="NSArray" key="dict.values">
-					<bool key="EncodedWithXMLCoder">YES</bool>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>{{541, 417}, {190, 190}}</string>
-					<boolean value="NO"/>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-					<string>HyperlinkButtonCell</string>
-					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
-				</object>
-			</object>
-			<object class="NSMutableDictionary" key="unlocalizedProperties">
-				<bool key="EncodedWithXMLCoder">YES</bool>
-				<reference key="dict.sortedKeys" ref="0"/>
-				<reference key="dict.values" ref="0"/>
-			</object>
-			<nil key="activeLocalization"/>
-			<object class="NSMutableDictionary" key="localizations">
-				<bool key="EncodedWithXMLCoder">YES</bool>
-				<reference key="dict.sortedKeys" ref="0"/>
-				<reference key="dict.values" ref="0"/>
-			</object>
-			<nil key="sourceID"/>
-			<int key="maxID">845</int>
-		</object>
-		<object class="IBClassDescriber" key="IBDocument.Classes">
-			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
-				<bool key="EncodedWithXMLCoder">YES</bool>
-				<object class="IBPartialClassDescription">
-					<string key="className">BaseBubbleController</string>
-					<string key="superclassName">NSWindowController</string>
-					<object class="NSMutableDictionary" key="outlets">
-						<string key="NS.key.0">bubble_</string>
-						<string key="NS.object.0">InfoBubbleView</string>
-					</object>
-					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
-						<string key="NS.key.0">bubble_</string>
-						<object class="IBToOneOutletInfo" key="NS.object.0">
-							<string key="name">bubble_</string>
-							<string key="candidateClassName">InfoBubbleView</string>
-						</object>
-					</object>
-					<object class="IBClassDescriptionSource" key="sourceIdentifier">
-						<string key="majorKey">IBProjectSource</string>
-						<string key="minorKey">./Classes/BaseBubbleController.h</string>
-					</object>
-				</object>
-				<object class="IBPartialClassDescription">
-					<string key="className">ChromeEventProcessingWindow</string>
-					<string key="superclassName">UnderlayOpenGLHostingWindow</string>
-					<object class="IBClassDescriptionSource" key="sourceIdentifier">
-						<string key="majorKey">IBProjectSource</string>
-						<string key="minorKey">./Classes/ChromeEventProcessingWindow.h</string>
-					</object>
-				</object>
-				<object class="IBPartialClassDescription">
-					<string key="className">ChromeUILocalizer</string>
-					<string key="superclassName">GTMUILocalizer</string>
-					<object class="IBClassDescriptionSource" key="sourceIdentifier">
-						<string key="majorKey">IBProjectSource</string>
-						<string key="minorKey">./Classes/ChromeUILocalizer.h</string>
-					</object>
-				</object>
-				<object class="IBPartialClassDescription">
-					<string key="className">GTMUILocalizer</string>
-					<string key="superclassName">NSObject</string>
-					<object class="NSMutableDictionary" key="outlets">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSArray" key="dict.sortedKeys">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>otherObjectToLocalize_</string>
-							<string>owner_</string>
-							<string>yetAnotherObjectToLocalize_</string>
-						</object>
-						<object class="NSArray" key="dict.values">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>id</string>
-							<string>id</string>
-							<string>id</string>
-						</object>
-					</object>
-					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSArray" key="dict.sortedKeys">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>otherObjectToLocalize_</string>
-							<string>owner_</string>
-							<string>yetAnotherObjectToLocalize_</string>
-						</object>
-						<object class="NSArray" key="dict.values">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<object class="IBToOneOutletInfo">
-								<string key="name">otherObjectToLocalize_</string>
-								<string key="candidateClassName">id</string>
-							</object>
-							<object class="IBToOneOutletInfo">
-								<string key="name">owner_</string>
-								<string key="candidateClassName">id</string>
-							</object>
-							<object class="IBToOneOutletInfo">
-								<string key="name">yetAnotherObjectToLocalize_</string>
-								<string key="candidateClassName">id</string>
-							</object>
-						</object>
-					</object>
-					<object class="IBClassDescriptionSource" key="sourceIdentifier">
-						<string key="majorKey">IBProjectSource</string>
-						<string key="minorKey">./Classes/GTMUILocalizer.h</string>
-					</object>
-				</object>
-				<object class="IBPartialClassDescription">
-					<string key="className">GTMUILocalizerAndLayoutTweaker</string>
-					<string key="superclassName">NSObject</string>
-					<object class="NSMutableDictionary" key="outlets">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSArray" key="dict.sortedKeys">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>localizerOwner_</string>
-							<string>localizer_</string>
-							<string>uiObject_</string>
-						</object>
-						<object class="NSArray" key="dict.values">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>id</string>
-							<string>GTMUILocalizer</string>
-							<string>id</string>
-						</object>
-					</object>
-					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSArray" key="dict.sortedKeys">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>localizerOwner_</string>
-							<string>localizer_</string>
-							<string>uiObject_</string>
-						</object>
-						<object class="NSArray" key="dict.values">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<object class="IBToOneOutletInfo">
-								<string key="name">localizerOwner_</string>
-								<string key="candidateClassName">id</string>
-							</object>
-							<object class="IBToOneOutletInfo">
-								<string key="name">localizer_</string>
-								<string key="candidateClassName">GTMUILocalizer</string>
-							</object>
-							<object class="IBToOneOutletInfo">
-								<string key="name">uiObject_</string>
-								<string key="candidateClassName">id</string>
-							</object>
-						</object>
-					</object>
-					<object class="IBClassDescriptionSource" key="sourceIdentifier">
-						<string key="majorKey">IBProjectSource</string>
-						<string key="minorKey">./Classes/GTMUILocalizerAndLayoutTweaker.h</string>
-					</object>
-				</object>
-				<object class="IBPartialClassDescription">
-					<string key="className">HyperlinkButtonCell</string>
-					<string key="superclassName">NSButtonCell</string>
-					<object class="IBClassDescriptionSource" key="sourceIdentifier">
-						<string key="majorKey">IBProjectSource</string>
-						<string key="minorKey">./Classes/HyperlinkButtonCell.h</string>
-					</object>
-				</object>
-				<object class="IBPartialClassDescription">
-					<string key="className">InfoBubbleView</string>
-					<string key="superclassName">NSView</string>
-					<object class="IBClassDescriptionSource" key="sourceIdentifier">
-						<string key="majorKey">IBProjectSource</string>
-						<string key="minorKey">./Classes/InfoBubbleView.h</string>
-					</object>
-				</object>
-				<object class="IBPartialClassDescription">
-					<string key="className">InfoBubbleWindow</string>
-					<string key="superclassName">ChromeEventProcessingWindow</string>
-					<object class="IBClassDescriptionSource" key="sourceIdentifier">
-						<string key="majorKey">IBProjectSource</string>
-						<string key="minorKey">./Classes/InfoBubbleWindow.h</string>
-					</object>
-				</object>
-				<object class="IBPartialClassDescription">
-					<string key="className">SpeechRecognitionWindowController</string>
-					<string key="superclassName">BaseBubbleController</string>
-					<object class="NSMutableDictionary" key="actions">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSArray" key="dict.sortedKeys">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>cancel:</string>
-							<string>micSettings:</string>
-							<string>tryAgain:</string>
-						</object>
-						<object class="NSArray" key="dict.values">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>id</string>
-							<string>id</string>
-							<string>id</string>
-						</object>
-					</object>
-					<object class="NSMutableDictionary" key="actionInfosByName">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSArray" key="dict.sortedKeys">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>cancel:</string>
-							<string>micSettings:</string>
-							<string>tryAgain:</string>
-						</object>
-						<object class="NSArray" key="dict.values">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<object class="IBActionInfo">
-								<string key="name">cancel:</string>
-								<string key="candidateClassName">id</string>
-							</object>
-							<object class="IBActionInfo">
-								<string key="name">micSettings:</string>
-								<string key="candidateClassName">id</string>
-							</object>
-							<object class="IBActionInfo">
-								<string key="name">tryAgain:</string>
-								<string key="candidateClassName">id</string>
-							</object>
-						</object>
-					</object>
-					<object class="NSMutableDictionary" key="outlets">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSArray" key="dict.sortedKeys">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>cancelButton_</string>
-							<string>iconImage_</string>
-							<string>instructionLabel_</string>
-							<string>micSettingsButton_</string>
-							<string>myOutlet1</string>
-							<string>tryAgainButton_</string>
-						</object>
-						<object class="NSArray" key="dict.values">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>NSButton</string>
-							<string>NSImageView</string>
-							<string>NSTextField</string>
-							<string>NSButton</string>
-							<string>id</string>
-							<string>NSButton</string>
-						</object>
-					</object>
-					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
-						<bool key="EncodedWithXMLCoder">YES</bool>
-						<object class="NSArray" key="dict.sortedKeys">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<string>cancelButton_</string>
-							<string>iconImage_</string>
-							<string>instructionLabel_</string>
-							<string>micSettingsButton_</string>
-							<string>myOutlet1</string>
-							<string>tryAgainButton_</string>
-						</object>
-						<object class="NSArray" key="dict.values">
-							<bool key="EncodedWithXMLCoder">YES</bool>
-							<object class="IBToOneOutletInfo">
-								<string key="name">cancelButton_</string>
-								<string key="candidateClassName">NSButton</string>
-							</object>
-							<object class="IBToOneOutletInfo">
-								<string key="name">iconImage_</string>
-								<string key="candidateClassName">NSImageView</string>
-							</object>
-							<object class="IBToOneOutletInfo">
-								<string key="name">instructionLabel_</string>
-								<string key="candidateClassName">NSTextField</string>
-							</object>
-							<object class="IBToOneOutletInfo">
-								<string key="name">micSettingsButton_</string>
-								<string key="candidateClassName">NSButton</string>
-							</object>
-							<object class="IBToOneOutletInfo">
-								<string key="name">myOutlet1</string>
-								<string key="candidateClassName">id</string>
-							</object>
-							<object class="IBToOneOutletInfo">
-								<string key="name">tryAgainButton_</string>
-								<string key="candidateClassName">NSButton</string>
-							</object>
-						</object>
-					</object>
-					<object class="IBClassDescriptionSource" key="sourceIdentifier">
-						<string key="majorKey">IBProjectSource</string>
-						<string key="minorKey">./Classes/SpeechRecognitionWindowController.h</string>
-					</object>
-				</object>
-				<object class="IBPartialClassDescription">
-					<string key="className">UnderlayOpenGLHostingWindow</string>
-					<string key="superclassName">NSWindow</string>
-					<object class="IBClassDescriptionSource" key="sourceIdentifier">
-						<string key="majorKey">IBProjectSource</string>
-						<string key="minorKey">./Classes/UnderlayOpenGLHostingWindow.h</string>
-					</object>
-				</object>
-			</object>
-		</object>
-		<int key="IBDocument.localizationMode">0</int>
-		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
-		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
-			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
-			<real value="1070" key="NS.object.0"/>
-		</object>
-		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
-			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
-			<integer value="3000" key="NS.object.0"/>
-		</object>
-		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
-		<int key="IBDocument.defaultPropertyAccessControl">3</int>
-		<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
-			<string key="NS.key.0">speech_input_recording</string>
-			<string key="NS.object.0">{128, 128}</string>
-		</object>
-	</data>
-</archive>
diff --git a/chrome/app/resources/chromium_strings_am.xtb b/chrome/app/resources/chromium_strings_am.xtb
index 1cf109b..4b96bc5 100644
--- a/chrome/app/resources/chromium_strings_am.xtb
+++ b/chrome/app/resources/chromium_strings_am.xtb
@@ -7,7 +7,7 @@
 <translation id="5065199687811594072">Chromium የድር ቅጾችን ለማጠናቅቅ ይህን የክሬዲት ካርድ መረጃ እንዲያስቀምጥ ይፈልጋሉ?</translation>
 <translation id="6510925080656968729">Chromiumን ያራግፉ</translation>
 <translation id="2615699638672665509">ይህ ኮምፒውተር ሃርድዌሩ ከአሁን በኋላ ስለማይደገፍ በቅርቡ የChromium ዝማኔዎችን መቀበሉን ያቆማል።</translation>
-<translation id="6893813176749746474">Chromium ተዘምኗል፣ ግን ቢያንስ ለ30 ቀናት አልተጠቀሙበትም።</translation>
+<translation id="6893813176749746474">Chromium ተዘምኗል፣ ግን ቢያንስ ለ30 ቀኖች አልተጠቀሙበትም።</translation>
 <translation id="1550579416447684632">የChromium መተግበሪያዎችን አስጅምር</translation>
 <translation id="4267347018362241535">Chromium የመተግበሪያ አስጀማሪ ለChromium መተግበሪያዎች የተዘጋጀ በንጥል ቋሚ የመሳሪያ ሥርዓት ነው።</translation>
 <translation id="2770231113462710648">ነባሪ አሳሽን ወደዚህ ቀይር፦</translation>
diff --git a/chrome/app/resources/chromium_strings_de.xtb b/chrome/app/resources/chromium_strings_de.xtb
index 3f2634a..9768f5a 100644
--- a/chrome/app/resources/chromium_strings_de.xtb
+++ b/chrome/app/resources/chromium_strings_de.xtb
@@ -170,7 +170,7 @@
 <translation id="2966088006374919794">Chromium muss eine externe App zur Verarbeitung von <ph name="SCHEME"/>-Links starten. Der angeforderte Link ist <ph name="PROTOLINK"/>.</translation>
 <translation id="2558235863893655150">Möchten Sie, dass Chromium Ihr Passwort speichert?</translation>
 <translation id="1231416733874080281">Chromium-Menü anzeigen</translation>
-<translation id="5245781775140304270">Da Chromium nicht steuert, wie Erweiterungen mit Ihren personenbezogenen Daten umgehen, wurden für Inkognito-Fenster alle Erweiterungen deaktiviert. Sie können die Erweiterungen einzeln im <ph name="BEGIN_LINK"/>Erweiterungs-Manager<ph name="END_LINK"/> aktivieren.</translation>
+<translation id="5245781775140304270">Da Chromium nicht steuert, wie Erweiterungen mit Ihren personenbezogenen Daten umgehen, wurden für Inkognitofenster alle Erweiterungen deaktiviert. Sie können die Erweiterungen einzeln im <ph name="BEGIN_LINK"/>Erweiterungs-Manager<ph name="END_LINK"/> aktivieren.</translation>
 <translation id="5772805321386874569">Ein <ph name="BEGIN_BUTTON"/>Neustart<ph name="END_BUTTON"/> von Chromium ist erforderlich.</translation>
 <translation id="1688750314291223739">Richten Sie die Synchronisierung ein, um Ihre personalisierten Browserfunktionen online zu speichern und über Chromium auf jedem Computer darauf zuzugreifen.</translation>
 <translation id="8865765905101981392">Internetbrowser</translation>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb
index 3303656..2811a46 100644
--- a/chrome/app/resources/generated_resources_am.xtb
+++ b/chrome/app/resources/generated_resources_am.xtb
@@ -1815,6 +1815,7 @@
 <translation id="7724603315864178912">ቁረጥ</translation>
 <translation id="8456681095658380701">ልክ ያልሆነ ስም</translation>
 <translation id="3518086201899641494">የተያዥ መግቢያ በሮች ማሳውቂያዎች</translation>
+<translation id="3652052123500137959">የድምጽ ፍለጋን በመተግበሪያ ማስጀመሪያ ውስጥ አንቃ።</translation>
 <translation id="1976150099241323601">የደህንነት መሣሪያ ውስጥ ይግቡ</translation>
 <translation id="4120817667028078560">ዱካ በጣም ረጅም ነው</translation>
 <translation id="4938972461544498524">የመዳሰሻ ሰሌዳ ቅንብሮች</translation>
@@ -2927,6 +2928,7 @@
 <translation id="8443621894987748190">የመለያዎ ስዕልዎን ይምረጡ</translation>
 <translation id="7374461526650987610">የፕሮቶኮል ተቆጣጣሪዎች</translation>
 <translation id="2192505247865591433">ከ፦</translation>
+<translation id="8668997025496699314">የድምጽ ፍለጋን በመተግበሪያ ውስጥ ያንቁ። ከነቃ ተጠቃሚው በንግግር መፈለግ ይችላል።</translation>
 <translation id="4634771451598206121">እንደገና ይግቡ...</translation>
 <translation id="3475110616773907981">በኮምፒውተርዎና በጎበኟቸው ጣቢያዎች ያለ ውሂብ ሁሉ ይደርስበታል</translation>
 <translation id="1035590878859356651">ለዚህ ገጽ ዕልባት አብጅ...</translation>
@@ -3838,7 +3840,6 @@
 <translation id="3228279582454007836">ይህን ጣቢያ ከዛሬ በፊት ፈጽሞ ጎብኝተውት አያውቁም።</translation>
 <translation id="7027125358315426638">የውሂብ ጎታ ስም፦</translation>
 <translation id="4030383055268325496">&amp;አክልን ቀልብስ</translation>
-<translation id="5474648613967354713">የድምጽ ፍለጋን በመተግበሪያ አስጀማሪ ውስጥ አሰናክል።</translation>
 <translation id="5449716055534515760">&amp;መስኮት ዝጋ</translation>
 <translation id="3224239078034945833">የካናዳ ባለብዙ ቋንቋ</translation>
 <translation id="4875057836161716898">የግቤት እይታዎችን አንቃ።</translation>
@@ -4328,7 +4329,6 @@
 <translation id="1812514023095547458">ቀለም ይምረጡ</translation>
 <translation id="2487656424763972284">ቀላል ማስከፈት</translation>
 <translation id="7047998246166230966">ጠቋሚ</translation>
-<translation id="743268637741709136">በመተግበሪያ አስጀማሪ ውስጥ የድምጽ ፍለጋን ያሰናክሉ። ከተሰናከለ ተጠቃሚው በንግግር መፈለግ አይችልም።</translation>
 <translation id="3252266817569339921">ፈረንሳይኛ</translation>
 <translation id="2665717534925640469">ይህ ገጽ አሁን ሙሉ ማያ ገጽ ነው፣ እናም የመዳፊትዎ ጠቋሚን አሰናክሎታል።</translation>
 <translation id="3414952576877147120">መጠን፦</translation>
@@ -4812,7 +4812,7 @@
 <translation id="713122686776214250">&amp;ገጽ አክል...</translation>
 <translation id="4816492930507672669">ገጹን ይሙሉበት</translation>
 <translation id="1485015260175968628">አሁን እነዚህን ማድረግ ይችላል፦</translation>
-<translation id="7496192982082800780">ቀናት</translation>
+<translation id="7496192982082800780">ቀኖች</translation>
 <translation id="1122198203221319518">&amp;መሣሪያዎች</translation>
 <translation id="5143151113947480436">የሚገለብጡት እና የሚለጥፉት ውሂብ ይድረሱበት</translation>
 <translation id="6051028581720248124">ወደ FedEx Office በማተም የእነሱን <ph name="START_LINK"/>አገልግሎት ውል<ph name="END_LINK"/> ተቀብለዋል።</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb
index 8df1302..1940bcc 100644
--- a/chrome/app/resources/generated_resources_ar.xtb
+++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -1785,6 +1785,7 @@
 <translation id="7724603315864178912">قص</translation>
 <translation id="8456681095658380701">اسم غير صالح</translation>
 <translation id="3518086201899641494">إشعارات حول بوابات التقييد</translation>
+<translation id="3652052123500137959">‏تمكين البحث الصوتي في Launcher تطبيقات.</translation>
 <translation id="1976150099241323601">تسجيل الدخول إلى جهاز الأمان</translation>
 <translation id="4120817667028078560">المسار طويل جدًا</translation>
 <translation id="4938972461544498524">إعدادات لوحة اللمس</translation>
@@ -2868,6 +2869,7 @@
 <translation id="8443621894987748190">اختيار صورة حسابك</translation>
 <translation id="7374461526650987610">معالجات البروتوكول</translation>
 <translation id="2192505247865591433">من:</translation>
+<translation id="8668997025496699314">‏اعمل على تمكين البحث الصوتي في Launcher تطبيقات. في حالة تمكينه، سيتمكن المستخدم من البحث بالكلام.</translation>
 <translation id="4634771451598206121">تسجيل الدخول مرة أخرى...</translation>
 <translation id="3475110616773907981">الدخول إلى جميع البيانات على الكمبيوتر ومواقع الويب التي تنتقل إليها</translation>
 <translation id="1035590878859356651">حفظ هذه الصفحة كإشارة مرجعية...</translation>
@@ -3778,7 +3780,6 @@
 <translation id="3228279582454007836">لم يسبق لك زيارة هذا الموقع.</translation>
 <translation id="7027125358315426638">اسم قاعدة البيانات:</translation>
 <translation id="4030383055268325496">تراجع عن الإ&amp;ضافة</translation>
-<translation id="5474648613967354713">‏تعطيل البحث الصوتي في Launcher تطبيقات.</translation>
 <translation id="5449716055534515760">إغلاق &amp;النافذة</translation>
 <translation id="3224239078034945833">كندي متعدد اللغات</translation>
 <translation id="4875057836161716898">تمكين طرق عرض الإدخال</translation>
@@ -4267,7 +4268,6 @@
 <translation id="1812514023095547458">تحديد اللون</translation>
 <translation id="2487656424763972284">إلغاء القفل بسهولة</translation>
 <translation id="7047998246166230966">المؤشر</translation>
-<translation id="743268637741709136">‏تعطيل البحث الصوتي في Launcher تطبيقات. إذا تم تعطيله، فإن المستخدم لن يتمكن من البحث الصوتي.</translation>
 <translation id="3252266817569339921">الفرنسية</translation>
 <translation id="2665717534925640469">هذه الصفحة في وضع ملء الشاشة الآن وتم تعطيل مؤشر الماوس.</translation>
 <translation id="3414952576877147120">الحجم:</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb
index 3de8299..ea58776 100644
--- a/chrome/app/resources/generated_resources_bg.xtb
+++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -1786,6 +1786,7 @@
 <translation id="7724603315864178912">Изрязване</translation>
 <translation id="8456681095658380701">Невалидно име</translation>
 <translation id="3518086201899641494">Известия за портали за удостоверяване</translation>
+<translation id="3652052123500137959">Активиране на гласовото търсене в стартовия панел с приложения.</translation>
 <translation id="1976150099241323601">Вход в защитното устройство</translation>
 <translation id="4120817667028078560">Пътят е твърде дълъг</translation>
 <translation id="4938972461544498524">Настройки за сензорния панел</translation>
@@ -2877,6 +2878,7 @@
 <translation id="8443621894987748190">Изберете си снимка за профила</translation>
 <translation id="7374461526650987610">Манипулатори на протоколи</translation>
 <translation id="2192505247865591433">От:</translation>
+<translation id="8668997025496699314">Включване на гласовото търсене в стартовия панел с приложения. Ако е активирано, потребителят ще може да търси чрез говор.</translation>
 <translation id="4634771451598206121">Влизане отново...</translation>
 <translation id="3475110616773907981">Достъп до всички данни на компютъра ви и до посещаваните от вас уебсайтове</translation>
 <translation id="1035590878859356651">Запазване на отметка към тази страница...</translation>
@@ -3776,7 +3778,6 @@
 <translation id="3228279582454007836">До днес не сте посещавали изобщо този сайт.</translation>
 <translation id="7027125358315426638">Име на базата от данни:</translation>
 <translation id="4030383055268325496">&amp;Отмяна на добавянето</translation>
-<translation id="5474648613967354713">Деактивиране на гласовото търсене в стартовия панел за приложения.</translation>
 <translation id="5449716055534515760">Затваряне на &amp;прозореца</translation>
 <translation id="3224239078034945833">Канадска многоезична клавиатура</translation>
 <translation id="4875057836161716898">Активиране на изгледите при въвеждане.</translation>
@@ -4261,7 +4262,6 @@
 <translation id="1812514023095547458">Избор на цвят</translation>
 <translation id="2487656424763972284">Лесно отключване</translation>
 <translation id="7047998246166230966">Курсор</translation>
-<translation id="743268637741709136">Деактивирайте гласовото търсене в стартовия панел за приложения. Така потребителят няма да може да търси чрез говор.</translation>
 <translation id="3252266817569339921">Френска клавиатура</translation>
 <translation id="2665717534925640469">Тази страница сега е на цял екран и е деактивирала курсора на мишката ви.</translation>
 <translation id="3414952576877147120">Размер:</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb
index 5f999da..20f8da9 100644
--- a/chrome/app/resources/generated_resources_bn.xtb
+++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -1798,6 +1798,7 @@
 <translation id="7724603315864178912">ছেদন</translation>
 <translation id="8456681095658380701">অবৈধ নাম</translation>
 <translation id="3518086201899641494">ক্যাপটিভ পোর্টালগুলির সম্বন্ধে বিজ্ঞপ্তিগুলি</translation>
+<translation id="3652052123500137959">অ্যাপ্লিকেশান লঞ্চারে ভয়েস অনুসন্ধান সক্ষম করুন৷</translation>
 <translation id="1976150099241323601">সুরক্ষা ডিভাইসে সাইন করুন</translation>
 <translation id="4120817667028078560">পাথ অত্যন্ত বড়</translation>
 <translation id="4938972461544498524">টাচপ্যাড সেটিংস</translation>
@@ -2903,6 +2904,7 @@
 <translation id="8443621894987748190">আপনার অ্যাকাউন্ট ছবি চয়ন করুন</translation>
 <translation id="7374461526650987610">প্রোটোকল পরিচালনাকারী</translation>
 <translation id="2192505247865591433">থেকে:</translation>
+<translation id="8668997025496699314">অ্যাপ্লিকেশান লঞ্চারে ভয়েস অনুসন্ধান সক্ষম করুন৷ যদি সক্ষম করা থাকে তবে ব্যবহারকারী কথা বলে অনুসন্ধান করতে পারবেন৷</translation>
 <translation id="4634771451598206121">আবার সাইন ইন করুন...</translation>
 <translation id="3475110616773907981">আপনার কম্পিউটার  এবং আপনার দেখা ওয়েবসাইটগুলির সমস্ত ডেটা অ্যাক্সেস করুন</translation>
 <translation id="1035590878859356651">এই পৃষ্ঠাটি বুকমার্ক করুন...</translation>
@@ -3813,7 +3815,6 @@
 <translation id="3228279582454007836">আপনি আজকের আগে এই সাইটটি পরিদর্শন করেন নি৷</translation>
 <translation id="7027125358315426638">ডেটাবেসের নাম:</translation>
 <translation id="4030383055268325496">&amp;যোগ করাকে পূর্বাবস্থায় ফেরান</translation>
-<translation id="5474648613967354713">অ্যাপ্লিকেশান লঞ্চারে ভয়েস অনুসন্ধান অক্ষম করুন৷</translation>
 <translation id="5449716055534515760">Close Win&amp;dow</translation>
 <translation id="3224239078034945833">কানাডিয়ান বহুভাষিক</translation>
 <translation id="4875057836161716898">ইনপুট দৃশ্য সক্ষম করুন।</translation>
@@ -4302,7 +4303,6 @@
 <translation id="1812514023095547458">রঙ নির্বাচন করুন</translation>
 <translation id="2487656424763972284">সহজ আনলক</translation>
 <translation id="7047998246166230966">পয়েন্টার</translation>
-<translation id="743268637741709136">অ্যাপ্লিকেশান লঞ্চারে ভয়েস অনুসন্ধান অক্ষম করুন৷ যদি অক্ষম করা থাকে তবে ব্যবহারকারী কথা বলে অনুসন্ধান করতে পারবেন না৷</translation>
 <translation id="3252266817569339921">ফরাসী</translation>
 <translation id="2665717534925640469">এই পৃষ্ঠাটি এখন পূর্ণ স্ক্রীণে আছে এবং আপনার মাউস কার্সার অক্ষম করা হয়েছে৷</translation>
 <translation id="3414952576877147120">মাপ:</translation>
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb
index 744e35e..50c6d3e 100644
--- a/chrome/app/resources/generated_resources_ca.xtb
+++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -776,7 +776,7 @@
 <translation id="7528983820605922285">Administrador d'usuaris</translation>
 <translation id="657402800789773160">&amp;Torna a carregar aquesta pàgina</translation>
 <translation id="6163363155248589649">&amp;Normal</translation>
-<translation id="2399147786307302860">Configuració de sincronització avançada...</translation>
+<translation id="2399147786307302860">Configuració avançada de sincronització...</translation>
 <translation id="490074449735753175">Utilitza un servei web per solucionar els errors d'ortografia</translation>
 <translation id="7972714317346275248">PKCS #1 SHA-384 amb encriptació RSA</translation>
 <translation id="3020990233660977256">Número de sèrie: <ph name="SERIAL_NUMBER"/></translation>
@@ -1788,6 +1788,7 @@
 <translation id="7724603315864178912">Retalla</translation>
 <translation id="8456681095658380701">El nom no és vàlid</translation>
 <translation id="3518086201899641494">Notificacions sobre portals captius</translation>
+<translation id="3652052123500137959">Activa la cerca per veu al Menú d'aplicacions</translation>
 <translation id="1976150099241323601">Inici de sessió al dispositiu de seguretat</translation>
 <translation id="4120817667028078560">El camí és massa llarg</translation>
 <translation id="4938972461544498524">Configuració del ratolí tàctil</translation>
@@ -2881,6 +2882,7 @@
 <translation id="8443621894987748190">Trieu una foto per al compte</translation>
 <translation id="7374461526650987610">Gestors de protocol</translation>
 <translation id="2192505247865591433">De:</translation>
+<translation id="8668997025496699314">Activa la cerca per veu al Menú d'aplicacions. Si aquesta opció està activada, l'usuari podrà fer cerques mitjançant la veu.</translation>
 <translation id="4634771451598206121">Torna a iniciar la sessió...</translation>
 <translation id="3475110616773907981">Accedir a totes les dades de l'ordinador i dels llocs web que visiteu</translation>
 <translation id="1035590878859356651">Afegeix aquesta pàgina a les adreces d'interès...</translation>
@@ -3315,7 +3317,7 @@
 <translation id="3399055427338982746">No hi ha cap extensió sense empaquetar.</translation>
 <translation id="5818003990515275822">Coreà</translation>
 <translation id="4182252350869425879">Advertència: Lloc sospitós de pesca!</translation>
-<translation id="2453021845418314664">Configuració de sincronització avançada</translation>
+<translation id="2453021845418314664">Configuració avançada de sincronització</translation>
 <translation id="14720830734893704">Activa la compatibilitat del teclat virtual.</translation>
 <translation id="5458214261780477893">Dvorak</translation>
 <translation id="1185924365081634987">També podeu provar de <ph name="GUEST_SIGNIN_LINK_START"/>navegar com a convidat<ph name="GUEST_SIGNIN_LINK_END"/> per corregir aquest error de xarxa.</translation>
@@ -3793,7 +3795,6 @@
 <translation id="3228279582454007836">No has visitat mai abans aquest lloc.</translation>
 <translation id="7027125358315426638">Nom de la base de dades:</translation>
 <translation id="4030383055268325496">&amp;Desfés l'addició</translation>
-<translation id="5474648613967354713">Desactiva la cerca per veu al Menú d'aplicacions.</translation>
 <translation id="5449716055534515760">Tanca la &amp;finestra</translation>
 <translation id="3224239078034945833">Multilingüe canadenc</translation>
 <translation id="4875057836161716898">Activació de les visualitzacions d'introducció de text</translation>
@@ -4279,7 +4280,6 @@
 <translation id="1812514023095547458">Selecció de color</translation>
 <translation id="2487656424763972284">Desbloqueig fàcil</translation>
 <translation id="7047998246166230966">Busca</translation>
-<translation id="743268637741709136">Desactiva la cerca per veu al Menú d'aplicacions. Si està desactivada, l'usuari no podrà fer cerques per veu.</translation>
 <translation id="3252266817569339921">Francès</translation>
 <translation id="2665717534925640469">Aquesta pàgina es visualitza a pantalla completa i ha desactivat el cursor del ratolí.</translation>
 <translation id="3414952576877147120">Mida:</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb
index a896888..a1bbb1b 100644
--- a/chrome/app/resources/generated_resources_cs.xtb
+++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -1786,6 +1786,7 @@
 <translation id="7724603315864178912">Vyjmout</translation>
 <translation id="8456681095658380701">Neplatný název</translation>
 <translation id="3518086201899641494">Oznámení o captive portálech</translation>
+<translation id="3652052123500137959">Povolit hlasové vyhledávání ve spouštěči aplikací</translation>
 <translation id="1976150099241323601">Přihlášení do zabezpečeného zařízení</translation>
 <translation id="4120817667028078560">Cesta je příliš dlouhá</translation>
 <translation id="4938972461544498524">Nastavení touchpadu</translation>
@@ -2491,7 +2492,7 @@
 <translation id="2090060788959967905">Nebezpečí: malware.</translation>
 <translation id="2563185590376525700">Žába</translation>
 <translation id="2553340429761841190">Systému <ph name="PRODUCT_NAME"/> se nepodařilo připojit k síti <ph name="NETWORK_ID"/>. Vyberte jinou síť nebo to zkuste znovu.</translation>
-<translation id="2086712242472027775">Účet ve službě <ph name="PRODUCT_NAME"/> nefunguje. Kontaktujte správce domény nebo se přihlaste pomocí běžného účtu Google.</translation>
+<translation id="2086712242472027775">Účet ve službě <ph name="PRODUCT_NAME"/> nefunguje. Kontaktujte administrátora domény nebo se přihlaste pomocí běžného účtu Google.</translation>
 <translation id="1970103697564110434">Peněženka Google chrání vaši kartu</translation>
 <translation id="7222232353993864120">E-mailová adresa</translation>
 <translation id="2128531968068887769">Native Client</translation>
@@ -2883,6 +2884,7 @@
 <translation id="8443621894987748190">Zvolte obrázek účtu</translation>
 <translation id="7374461526650987610">Obslužné nástroje protokolů</translation>
 <translation id="2192505247865591433">Z aplikace:</translation>
+<translation id="8668997025496699314">Povolí hlasové vyhledávání ve spouštěči aplikací. Pokud je tato zásada povolena, uživatel bude moci vyhledávat hlasem.</translation>
 <translation id="4634771451598206121">Znovu přihlásit...</translation>
 <translation id="3475110616773907981">Získat přístup ke všem datům v počítači a na navštěvovaných webech</translation>
 <translation id="1035590878859356651">Přidat tuto stránku do záložek...</translation>
@@ -3795,7 +3797,6 @@
 <translation id="3228279582454007836">Tyto stránky jste dosud nenavštívili.</translation>
 <translation id="7027125358315426638">Název databáze:</translation>
 <translation id="4030383055268325496">&amp;Vrátit přidání zpět</translation>
-<translation id="5474648613967354713">Zakázat hlasové vyhledávání ve spouštěči aplikací</translation>
 <translation id="5449716055534515760">Zavřít okno</translation>
 <translation id="3224239078034945833">Kanadská vícejazyčná klávesnice</translation>
 <translation id="4875057836161716898">Povolit zobrazení vstupu</translation>
@@ -4281,7 +4282,6 @@
 <translation id="1812514023095547458">Výběr barvy</translation>
 <translation id="2487656424763972284">Snadné odemknutí</translation>
 <translation id="7047998246166230966">Kurzor</translation>
-<translation id="743268637741709136">Zakáže hlasové vyhledávání ve spouštěči aplikací. Pokud je tato zásada zakázána, uživatel bude moci vyhledávat hlasem.</translation>
 <translation id="3252266817569339921">Francouzská klávesnice</translation>
 <translation id="2665717534925640469">Stránka je nyní zobrazena na celou obrazovku a deaktivovala ukazatel myši.</translation>
 <translation id="3414952576877147120">Velikost:</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb
index e2fc87c..275311b 100644
--- a/chrome/app/resources/generated_resources_da.xtb
+++ b/chrome/app/resources/generated_resources_da.xtb
@@ -14,7 +14,7 @@
 <translation id="166179487779922818">Adgangskoden er for kort.</translation>
 <translation id="9048642391959913289">Hurtigere implementering af teksttilpasning.</translation>
 <translation id="2345460471437425338">Forkert certifikat til vært.</translation>
-<translation id="3688507211863392146">Skriv til filer og mapper, som du åbner i applikationen</translation>
+<translation id="3688507211863392146">Skrive til filer og mapper, som du åbner i applikationen</translation>
 <translation id="3595596368722241419">Batteri fuldt</translation>
 <translation id="8098352321677019742"><ph name="PRODUCT_NAME"/>-underretninger</translation>
 <translation id="8130276680150879341">Afbryd forbindelsen til privat netværk</translation>
@@ -176,7 +176,7 @@
 <translation id="8561096986926824116">Forbindelsen til
         <ph name="HOST_NAME"/>
         blev afbrudt af en ændring i netværksforbindelsen.</translation>
-<translation id="8804398419035066391">Kommuniker med andre websites</translation>
+<translation id="8804398419035066391">Kommunikere med andre websites</translation>
 <translation id="6023914116273780353">Tilpassede</translation>
 <translation id="7082055294850503883">Ignorer som standard CapsLock og indtastning af små bogstaver</translation>
 <translation id="4989966318180235467">Inspicer &amp;baggrundsside</translation>
@@ -1796,6 +1796,7 @@
 <translation id="7724603315864178912">Klip</translation>
 <translation id="8456681095658380701">Ugyldigt navn</translation>
 <translation id="3518086201899641494">Underretninger om captive portals</translation>
+<translation id="3652052123500137959">Aktivér stemmesøgning i applisten.</translation>
 <translation id="1976150099241323601">Log ind på sikkerhedsenhed</translation>
 <translation id="4120817667028078560">Stien er for lang</translation>
 <translation id="4938972461544498524">Indstillinger for touchpad</translation>
@@ -2889,6 +2890,7 @@
 <translation id="8443621894987748190">Vælg et billede til din konto</translation>
 <translation id="7374461526650987610">Protokolhåndtering</translation>
 <translation id="2192505247865591433">Fra:</translation>
+<translation id="8668997025496699314">Aktivér stemmesøgning i applisten. Hvis det aktiveres, vil brugeren kunne søge ved hjælp af stemmen.</translation>
 <translation id="4634771451598206121">Log ind igen...</translation>
 <translation id="3475110616773907981">Få adgang til alle data på din computer og de websites, som du besøger</translation>
 <translation id="1035590878859356651">Føj denne side til bogmærker ...</translation>
@@ -3343,7 +3345,7 @@
 <translation id="580886651983547002"><ph name="PRODUCT_NAME"/>
         kan ikke oprette forbindelse til websitet. Dette sker typisk pga. netværksproblemer,
         men det kan også skyldes en forkert konfigureret firewall eller proxyserver.</translation>
-<translation id="4387554346626014084">Aktivér synkronisering af Appliste. Dermed aktiveres også Mapper, hvor muligt (ikke OSX).</translation>
+<translation id="4387554346626014084">Aktivér synkronisering af Appliste. Dermed aktiveres også Mapper hvor muligt (ikke OSX).</translation>
 <translation id="5445557969380904478">Om talegenkendelse</translation>
 <translation id="4104400246019119780">Tak</translation>
 <translation id="3487007233252413104">anonym funktion</translation>
@@ -3799,7 +3801,6 @@
 <translation id="3228279582454007836">Du har ikke besøgt dette website før i dag.</translation>
 <translation id="7027125358315426638">Databasenavn:</translation>
 <translation id="4030383055268325496">&amp;Fortryd tilføjelse</translation>
-<translation id="5474648613967354713">Deaktiver stemmesøgning i applisten.</translation>
 <translation id="5449716055534515760">Luk vin&amp;due</translation>
 <translation id="3224239078034945833">Canadisk (flere sprog)</translation>
 <translation id="4875057836161716898">Aktivér indtastningsvisning</translation>
@@ -4284,7 +4285,6 @@
 <translation id="1812514023095547458">Vælg farve</translation>
 <translation id="2487656424763972284">Nem oplåsning</translation>
 <translation id="7047998246166230966">Markør</translation>
-<translation id="743268637741709136">Deaktiver stemmesøgning i applisten. Brugeren kan dermed ikke søge ved hjælp af stemmen.</translation>
 <translation id="3252266817569339921">Fransk</translation>
 <translation id="2665717534925640469">Denne side vises nu i fuld skærm og har deaktiveret din musemarkør.</translation>
 <translation id="3414952576877147120">Størrelse:</translation>
@@ -4800,7 +4800,7 @@
 <translation id="8775404590947523323">Din ændringer gemmes automatisk.<ph name="BREAKS"/>Hvis du gemmer en kopi af det oprindelige billede, skal du fjerne markeringen for &quot;Overskriv originalen&quot;</translation>
 <translation id="5208988882104884956">Halv bredde</translation>
 <translation id="1507170440449692343">Denne side er blokeret fra at få adgang til dit kamera.</translation>
-<translation id="4189406272289638749">Udvidelsen &lt;b&gt;<ph name="EXTENSION_NAME"/>&lt;/b&gt; kontrollerer denne indstilling.</translation>
+<translation id="4189406272289638749">Udvidelsen &lt;b&gt;<ph name="EXTENSION_NAME"/>&lt;/b&gt; styrer denne indstilling.</translation>
 <translation id="803771048473350947">Fil</translation>
 <translation id="6206311232642889873">Ko&amp;pier billede</translation>
 <translation id="5158983316805876233">Brug samme proxy for alle protokoller</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb
index a3766eb..f30c266 100644
--- a/chrome/app/resources/generated_resources_de.xtb
+++ b/chrome/app/resources/generated_resources_de.xtb
@@ -719,7 +719,7 @@
 <translation id="7794058097940213561">Gerät formatieren</translation>
 <translation id="1119069657431255176">Bzip2-komprimiertes Tar-Archiv</translation>
 <translation id="5379140238605961210">Zugriff auf das Mikrofon weiter blockieren</translation>
-<translation id="488785315393301722">Details anzeigen</translation>
+<translation id="488785315393301722">Details ansehen</translation>
 <translation id="4381849418013903196">Doppelpunkt</translation>
 <translation id="8368859634510605990">&amp;Alle Lesezeichen öffnen</translation>
 <translation id="1103523840287552314"><ph name="LANGUAGE"/> immer übersetzen</translation>
@@ -1125,7 +1125,7 @@
 <translation id="862750493060684461">CSS-Cache</translation>
 <translation id="8169977663846153645">Verbleibende Akkulaufzeit wird berechnet...</translation>
 <translation id="7690853182226561458">&amp;Ordner hinzufügen...</translation>
-<translation id="7968982339740310781">Details anzeigen</translation>
+<translation id="7968982339740310781">Details ansehen</translation>
 <translation id="2832519330402637498">Links oben</translation>
 <translation id="2726934403674109201">(insgesamt <ph name="COUNT"/>)</translation>
 <translation id="6204994989617056362">Die Erweiterung für die SSL-Aushandlung fehlte im sicheren Handshake. Für einige Websites, die die Aushandlungserweiterung bekanntermaßen unterstützen, benötigt Google Chrome einen sichereren Handshake zur Verhinderung einer Klasse bekannter Angriffe. Das Fehlen dieser Erweiterung deutet darauf hin, dass Ihre Verbindung abgefangen und manipuliert wurde.</translation>
@@ -1789,6 +1789,7 @@
 <translation id="7724603315864178912">Ausschneiden</translation>
 <translation id="8456681095658380701">Ungültiger Name</translation>
 <translation id="3518086201899641494">Benachrichtigungen zu Erfassungsportalen</translation>
+<translation id="3652052123500137959">Sprachsuche in der App-Übersicht aktivieren</translation>
 <translation id="1976150099241323601">In Sicherheitsgerät anmelden</translation>
 <translation id="4120817667028078560">Pfad zu lang</translation>
 <translation id="4938972461544498524">Touchpad-Einstellungen</translation>
@@ -2868,6 +2869,7 @@
 <translation id="8443621894987748190">Foto für Ihr Konto wählen</translation>
 <translation id="7374461526650987610">Protokoll-Handler</translation>
 <translation id="2192505247865591433">von</translation>
+<translation id="8668997025496699314">Sprachsuche in der App-Übersicht aktivieren. Wenn diese Funktion aktiviert ist, kann der Nutzer per Spracheingabe suchen.</translation>
 <translation id="4634771451598206121">Erneut anmelden...</translation>
 <translation id="3475110616773907981">Auf alle Daten auf Ihrem Computer und den von Ihnen besuchten Websites zugreifen</translation>
 <translation id="1035590878859356651">Diese Seite als Lesezeichen speichern</translation>
@@ -3273,7 +3275,7 @@
 <translation id="3286538390144397061">Jetzt neu starten</translation>
 <translation id="1464258312790801189">Meine Konten</translation>
 <translation id="163309982320328737">Anfängliche Zeichenbreite ist &quot;Voll&quot;.</translation>
-<translation id="6140948187512243695">Details anzeigen</translation>
+<translation id="6140948187512243695">Details ansehen</translation>
 <translation id="4841055638263130507">Mikrofon-Einstellungen</translation>
 <translation id="6965648386495488594">Port</translation>
 <translation id="7631887513477658702">Dateien dieses Typs &amp;immer öffnen</translation>
@@ -3571,7 +3573,7 @@
 <translation id="3290704484208221223">Prozent</translation>
 <translation id="5265562206369321422">Seit über einer Woche offline</translation>
 <translation id="6805647936811177813">Melden Sie sich in <ph name="TOKEN_NAME"/> an, um das Client-Zertifikat von <ph name="HOST_NAME"/> herunterzuladen.</translation>
-<translation id="6412931879992742813">Neues Inkognito-Fenster</translation>
+<translation id="6412931879992742813">Neues Inkognitofenster</translation>
 <translation id="1105117579475534983">Webseite blockiert</translation>
 <translation id="1673103856845176271">Auf die Datei konnte aus Sicherheitsgründen nicht zugegriffen werden.</translation>
 <translation id="1199232041627643649">Zum Beenden <ph name="KEY_EQUIVALENT"/> gedrückt halten</translation>
@@ -3770,7 +3772,6 @@
 <translation id="3228279582454007836">Sie haben diese Seite nie zuvor aufgerufen.</translation>
 <translation id="7027125358315426638">Datenbankname:</translation>
 <translation id="4030383055268325496">&amp;Hinzufügen rückgängig machen</translation>
-<translation id="5474648613967354713">Sprachsuche in der App-Übersicht deaktivieren</translation>
 <translation id="5449716055534515760">Fen&amp;ster schließen</translation>
 <translation id="3224239078034945833">Kanadisch – mehrsprachig</translation>
 <translation id="4875057836161716898">Eingabeansichten aktivieren</translation>
@@ -4255,7 +4256,6 @@
 <translation id="1812514023095547458">Farbe auswählen</translation>
 <translation id="2487656424763972284">Einfaches Entsperren</translation>
 <translation id="7047998246166230966">Mauszeiger</translation>
-<translation id="743268637741709136">Sprachsuche in der App-Übersicht deaktivieren. Wenn diese Funktion deaktiviert ist, können Nutzer keine Sprachsuche durchführen.</translation>
 <translation id="3252266817569339921">Französisch</translation>
 <translation id="2665717534925640469">Diese Seite wird nun im Vollbildmodus angezeigt und hat den Mauszeiger deaktiviert.</translation>
 <translation id="3414952576877147120">Größe:</translation>
@@ -5227,7 +5227,7 @@
 <translation id="6218364611373262432">Installationsstatus der App-Übersicht bei jedem Neustart zurücksetzen. Wenn diese Markierung gesetzt ist, merkt sich Chrome für den nächsten Start nicht, dass die Übersicht bereits installiert wurde. Dies dient zum Testen des Installationsablaufs der App-Übersicht.</translation>
 <translation id="4396124683129237657">Neue Kreditkarte...</translation>
 <translation id="4103763322291513355">Unter &lt;strong&gt;chrome://policy&lt;/strong&gt; finden Sie eine Liste der blockierten URLs und andere Richtlinien, die durch Ihren Systemadministrator erzwungen werden.</translation>
-<translation id="8799314737325793817">Weitere anzeigen...</translation>
+<translation id="8799314737325793817">Mehr anzeigen...</translation>
 <translation id="5826507051599432481">Allgemeiner Name (CN)</translation>
 <translation id="8914326144705007149">Sehr groß</translation>
 <translation id="5154702632169343078">Antragsteller</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb
index a4769c2..1d2e056 100644
--- a/chrome/app/resources/generated_resources_el.xtb
+++ b/chrome/app/resources/generated_resources_el.xtb
@@ -1799,6 +1799,7 @@
 <translation id="7724603315864178912">Αποκοπή</translation>
 <translation id="8456681095658380701">Μη έγκυρο όνομα</translation>
 <translation id="3518086201899641494">Ειδοποιήσεις σχετικά με πύλες υποδοχής</translation>
+<translation id="3652052123500137959">Ενεργοποίηση φωνητικής αναζήτησης στην Εφαρμογή εκκίνησης.</translation>
 <translation id="1976150099241323601">Σύνδεση στη Συσκευή ασφαλείας</translation>
 <translation id="4120817667028078560">Η διαδρομή είναι πάρα πολύ μεγάλη</translation>
 <translation id="4938972461544498524">Ρυθμίσεις επιφάνειας αφής</translation>
@@ -2898,6 +2899,7 @@
 <translation id="8443621894987748190">Επιλέξτε την εικόνα του λογαριασμού σας</translation>
 <translation id="7374461526650987610">Χειριστές πρωτοκόλλου</translation>
 <translation id="2192505247865591433">Από:</translation>
+<translation id="8668997025496699314">Ενεργοποίηση φωνητικής αναζήτησης στην Εφαρμογή εκκίνησης. Εάν ενεργοποιηθεί, ο χρήστης θα έχει δυνατότητα να πραγματοποιεί φωνητική αναζήτηση.</translation>
 <translation id="4634771451598206121">Συνδεθείτε ξανά...</translation>
 <translation id="3475110616773907981">Πρόσβαση σε όλα τα δεδομένα στον υπολογιστή σας και στους ιστότοπους που επισκέπτεστε</translation>
 <translation id="1035590878859356651">Δημιουργία σελιδοδείκτη για αυτήν τη σελίδα…</translation>
@@ -3809,7 +3811,6 @@
 <translation id="3228279582454007836">Δεν έχετε επισκεφθεί ποτέ αυτόν τον ιστότοπο.</translation>
 <translation id="7027125358315426638">Όνομα βάσης δεδομένων:</translation>
 <translation id="4030383055268325496">&amp;Αναίρεση προσθήκης</translation>
-<translation id="5474648613967354713">Απενεργοποίηση φωνητικής αναζήτησης στην Εφαρμογή εκκίνησης.</translation>
 <translation id="5449716055534515760">Κλείσιμο παραθύρου</translation>
 <translation id="3224239078034945833">Πολύγλωσσο Καναδά</translation>
 <translation id="4875057836161716898">Ενεργοποίηση προβολών εισόδου.</translation>
@@ -4297,7 +4298,6 @@
 <translation id="1812514023095547458">Επιλογή χρώματος</translation>
 <translation id="2487656424763972284">Εύκολο ξεκλείδωμα</translation>
 <translation id="7047998246166230966">Δείκτης</translation>
-<translation id="743268637741709136">Απενεργοποίηση της φωνητικής αναζήτησης στην Εφαρμογή εκκίνησης. Εάν απενεργοποιηθεί, ο χρήστης δεν θα μπορεί να πραγματοποιήσει φωνητική αναζήτηση.</translation>
 <translation id="3252266817569339921">Γαλλικά</translation>
 <translation id="2665717534925640469">Αυτή η σελίδα είναι τώρα σε πλήρη οθόνη και έχει απενεργοποιήσει τον δείκτη του ποντικιού σας.</translation>
 <translation id="3414952576877147120">Μέγεθος:</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb
index b89997e..942deae 100644
--- a/chrome/app/resources/generated_resources_en-GB.xtb
+++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -1804,6 +1804,7 @@
 <translation id="7724603315864178912">Cut</translation>
 <translation id="8456681095658380701">Invalid name</translation>
 <translation id="3518086201899641494">Notifications about captive portals</translation>
+<translation id="3652052123500137959">Enable voice search in the App Launcher.</translation>
 <translation id="1976150099241323601">Sign in to Security Device</translation>
 <translation id="4120817667028078560">Path too long</translation>
 <translation id="4938972461544498524">Touchpad settings</translation>
@@ -2900,6 +2901,7 @@
 <translation id="8443621894987748190">Choose your account picture</translation>
 <translation id="7374461526650987610">Protocol Handlers</translation>
 <translation id="2192505247865591433">From:</translation>
+<translation id="8668997025496699314">Enable voice search in the App Launcher. If enabled, the user will be able to search by speech.</translation>
 <translation id="4634771451598206121">Sign in again...</translation>
 <translation id="3475110616773907981">All data on your computer and the websites that you visit</translation>
 <translation id="1035590878859356651">Bookmark this page...</translation>
@@ -3812,7 +3814,6 @@
 <translation id="3228279582454007836">You have never visited this site before today.</translation>
 <translation id="7027125358315426638">Database Name:</translation>
 <translation id="4030383055268325496">&amp;Undo add</translation>
-<translation id="5474648613967354713">Disable voice search in the App Launcher.</translation>
 <translation id="5449716055534515760">Close Win&amp;dow</translation>
 <translation id="3224239078034945833">Canadian Multilingual</translation>
 <translation id="4875057836161716898">Enable input views.</translation>
@@ -4301,7 +4302,6 @@
 <translation id="1812514023095547458">Select Colour</translation>
 <translation id="2487656424763972284">Easy Unlock</translation>
 <translation id="7047998246166230966">Pointer</translation>
-<translation id="743268637741709136">Disable voice search in the App Launcher. If disabled, the user won't be able to search by speech.</translation>
 <translation id="3252266817569339921">French</translation>
 <translation id="2665717534925640469">This page is now full screen and has disabled your mouse cursor.</translation>
 <translation id="3414952576877147120">Size:</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb
index 6bd8cb2..c649697 100644
--- a/chrome/app/resources/generated_resources_es-419.xtb
+++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -1787,6 +1787,7 @@
 <translation id="7724603315864178912">Cortar</translation>
 <translation id="8456681095658380701">Nombre no válido</translation>
 <translation id="3518086201899641494">Notificaciones sobre portales cautivos</translation>
+<translation id="3652052123500137959">Habilitar búsqueda por voz en el Selector de aplicaciones</translation>
 <translation id="1976150099241323601">Acceder al dispositivo de seguridad</translation>
 <translation id="4120817667028078560">Ruta de acceso demasiado larga</translation>
 <translation id="4938972461544498524">Configuración del touchpad</translation>
@@ -2882,6 +2883,7 @@
 <translation id="8443621894987748190">Elige la imagen de tu cuenta.</translation>
 <translation id="7374461526650987610">Controladores de protocolos</translation>
 <translation id="2192505247865591433">De:</translation>
+<translation id="8668997025496699314">Permite habilitar la búsqueda por voz en el Selector de aplicaciones. Si se habilita, el usuario podrá realizar búsquedas por voz.</translation>
 <translation id="4634771451598206121">Volver a acceder...</translation>
 <translation id="3475110616773907981">Acceder a todos los datos de tu computadora y los sitios web que visitas</translation>
 <translation id="1035590878859356651">Agregar esta página a Marcadores…</translation>
@@ -3788,7 +3790,6 @@
 <translation id="3228279582454007836">No has visitado nunca este sitio.</translation>
 <translation id="7027125358315426638">Nombre de la base de datos:</translation>
 <translation id="4030383055268325496">&amp;Deshacer Agregar</translation>
-<translation id="5474648613967354713">Inhabilitar búsqueda por voz en el Selector de aplicaciones</translation>
 <translation id="5449716055534515760">Cerrar ven&amp;tana</translation>
 <translation id="3224239078034945833">Multilingüe (Canadá)</translation>
 <translation id="4875057836161716898">Habilitar vistas de entrada de texto</translation>
@@ -4273,7 +4274,6 @@
 <translation id="1812514023095547458">Seleccionar color</translation>
 <translation id="2487656424763972284">Desbloqueo sencillo</translation>
 <translation id="7047998246166230966">Puntero</translation>
-<translation id="743268637741709136">Inhabilita la búsqueda por voz en el Selector de aplicaciones. Si se inhabilita, el usuario no podrá hacer búsquedas por voz.</translation>
 <translation id="3252266817569339921">Francés</translation>
 <translation id="2665717534925640469">Esta página se está visualizando en pantalla completa y ha inhabilitado el cursor del mouse.</translation>
 <translation id="3414952576877147120">Tamaño:</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb
index ee1654c..8a9c818 100644
--- a/chrome/app/resources/generated_resources_es.xtb
+++ b/chrome/app/resources/generated_resources_es.xtb
@@ -1798,6 +1798,7 @@
 <translation id="7724603315864178912">Cortar</translation>
 <translation id="8456681095658380701">El nombre no es válido</translation>
 <translation id="3518086201899641494">Notificaciones sobre portales cautivos</translation>
+<translation id="3652052123500137959">Habilitar la búsqueda por voz en el menú de aplicaciones.</translation>
 <translation id="1976150099241323601">Iniciar sesión en al dispositivo de seguridad</translation>
 <translation id="4120817667028078560">Ruta demasiado larga</translation>
 <translation id="4938972461544498524">Configuración del panel táctil</translation>
@@ -2893,6 +2894,7 @@
 <translation id="8443621894987748190">Seleccionar la imagen de tu cuenta</translation>
 <translation id="7374461526650987610">Controladores de protocolos</translation>
 <translation id="2192505247865591433">De:</translation>
+<translation id="8668997025496699314">Habilita la búsqueda por voz en el menú de aplicaciones. Si se habilita, el usuario podrá hacer búsquedas por voz.</translation>
 <translation id="4634771451598206121">Volver a iniciar sesión...</translation>
 <translation id="3475110616773907981">Acceder a todos los datos de tu ordenador y los sitios web que consultes</translation>
 <translation id="1035590878859356651">Añadir esta página a marcadores…</translation>
@@ -3803,7 +3805,6 @@
 <translation id="3228279582454007836">No has visitado nunca este sitio.</translation>
 <translation id="7027125358315426638">Nombre de la base de datos:</translation>
 <translation id="4030383055268325496">&amp;Deshacer acción de añadir</translation>
-<translation id="5474648613967354713">Inhabilitar la búsqueda por voz en el menú de aplicaciones.</translation>
 <translation id="5449716055534515760">Cerrar &amp;ventana</translation>
 <translation id="3224239078034945833">Canadiense multilingüe</translation>
 <translation id="4875057836161716898">Habilitar vistas de introducción de texto.</translation>
@@ -4289,7 +4290,6 @@
 <translation id="1812514023095547458">Seleccionar color</translation>
 <translation id="2487656424763972284">Easy Unlock</translation>
 <translation id="7047998246166230966">Puntero</translation>
-<translation id="743268637741709136">Permite inhabilitar la búsqueda por voz en el menú de aplicaciones. Si se inhabilita, el usuario no podrá hacer búsquedas por voz.</translation>
 <translation id="3252266817569339921">Francés</translation>
 <translation id="2665717534925640469">Esta página se muestra ahora en pantalla completa y ha inhabilitado el cursor del ratón.</translation>
 <translation id="3414952576877147120">Tamaño:</translation>
diff --git a/chrome/app/resources/generated_resources_et.xtb b/chrome/app/resources/generated_resources_et.xtb
index 0d3690a..7dcd546 100644
--- a/chrome/app/resources/generated_resources_et.xtb
+++ b/chrome/app/resources/generated_resources_et.xtb
@@ -1801,6 +1801,7 @@
 <translation id="7724603315864178912">Lõika</translation>
 <translation id="8456681095658380701">Kehtetu nimi</translation>
 <translation id="3518086201899641494">Märguanded kontrollportaali kohta</translation>
+<translation id="3652052123500137959">Häälotsingu lubamine rakenduste käivitajas.</translation>
 <translation id="1976150099241323601">Turvaseadmesse sisselogimine</translation>
 <translation id="4120817667028078560">Tee on liiga pikk</translation>
 <translation id="4938972461544498524">Puuteplaadi seaded</translation>
@@ -2894,6 +2895,7 @@
 <translation id="8443621894987748190">Valige konto pilt</translation>
 <translation id="7374461526650987610">Protokollitöötlejad</translation>
 <translation id="2192505247865591433">Saatja:</translation>
+<translation id="8668997025496699314">Rakenduste käivitajas häälotsingu lubamine. Kui see on lubatud, saab kasutaja otsida häältoimingutega.</translation>
 <translation id="4634771451598206121">Logi uuesti sisse ...</translation>
 <translation id="3475110616773907981">Kõik arvutis olevad andmed ja külastatud veebisaidid</translation>
 <translation id="1035590878859356651">Lisa leht järjehoidjatesse ...</translation>
@@ -3805,7 +3807,6 @@
 <translation id="3228279582454007836">Täna pole te seda saiti varem külastanud.</translation>
 <translation id="7027125358315426638">Andmebaasi nimi:</translation>
 <translation id="4030383055268325496">&amp;Võta lisamine tagasi</translation>
-<translation id="5474648613967354713">Häälotsingu keelamine rakenduste käivitajas.</translation>
 <translation id="5449716055534515760">Sule &amp;aken</translation>
 <translation id="3224239078034945833">Kanada mitmekeelne</translation>
 <translation id="4875057836161716898">Luba sisendi kuvad.</translation>
@@ -4292,7 +4293,6 @@
 <translation id="1812514023095547458">Värvi valimine</translation>
 <translation id="2487656424763972284">Lihtne avamine</translation>
 <translation id="7047998246166230966">Kursor</translation>
-<translation id="743268637741709136">Häälotsingu keelamine rakenduste käivitajas. Kui see on keelatud, ei saa kasutaja häältoimingutega otsida.</translation>
 <translation id="3252266817569339921">Prantsuse</translation>
 <translation id="2665717534925640469">Leht on nüüd täisekraanil ja keelas teie hiirekursori.</translation>
 <translation id="3414952576877147120">Suurus:</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb
index 52d3add..25b89c0 100644
--- a/chrome/app/resources/generated_resources_fa.xtb
+++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -1787,6 +1787,7 @@
 <translation id="7724603315864178912">برش</translation>
 <translation id="8456681095658380701">نام نامعتبر</translation>
 <translation id="3518086201899641494">اعلان‌های مربوط به پورتال‌های محدود</translation>
+<translation id="3652052123500137959">فعال کردن جستجوی شفاهی در «راه‌انداز برنامه».</translation>
 <translation id="1976150099241323601">ورود به سیستم دستگاه امنیتی</translation>
 <translation id="4120817667028078560">مسیر بیش از حد طولانی است</translation>
 <translation id="4938972461544498524">تنظیمات صفحه لمسی</translation>
@@ -2882,6 +2883,7 @@
 <translation id="8443621894987748190">انتخاب عکس حساب خود</translation>
 <translation id="7374461526650987610">کنترل‌کننده‌های پروتکل</translation>
 <translation id="2192505247865591433">از:</translation>
+<translation id="8668997025496699314">جستجوی شفاهی را در «راه‌انداز برنامه» فعال می‌کند. اگر فعال باشد، کاربر قادر به جستجو با گفتار خواهد بود.</translation>
 <translation id="4634771451598206121">ورود مجدد به سیستم...</translation>
 <translation id="3475110616773907981">دسترسی به همه داده‌های رایانهٔ شما و وب سایت‌هایی که بازدید کرده‌اید</translation>
 <translation id="1035590878859356651">نشانک‌گذاری این صفحه...</translation>
@@ -3788,7 +3790,6 @@
 <translation id="3228279582454007836">شما امروز از این سایت بازدید نکرده‌اید.</translation>
 <translation id="7027125358315426638">نام پایگاه داده:</translation>
 <translation id="4030383055268325496">&amp;واگرد افزودن</translation>
-<translation id="5474648613967354713">جستجوی شفاهی را در راه‌انداز برنامه غیرفعال کنید.</translation>
 <translation id="5449716055534515760">بستن &amp;پنجره</translation>
 <translation id="3224239078034945833">چند زبانه کانادا</translation>
 <translation id="4875057836161716898">نماهای ورودی را فعال کنید.</translation>
@@ -4273,7 +4274,6 @@
 <translation id="1812514023095547458">انتخاب رنگ</translation>
 <translation id="2487656424763972284">باز کردن قفل آسان</translation>
 <translation id="7047998246166230966">اشاره‌گر</translation>
-<translation id="743268637741709136">جستجوی شفاهی را در راه‌انداز برنامه غیرفعال کنید. اگر غیرفعال شود، کاربر نمی‌تواند با گفتار جستجو کند.</translation>
 <translation id="3252266817569339921">فرانسوی</translation>
 <translation id="2665717534925640469">این صفحه اکنون در حالت تمام صفحه است و مکان‌نمای ماوس شما را غیرفعال می‌کند.</translation>
 <translation id="3414952576877147120">اندازه:</translation>
diff --git a/chrome/app/resources/generated_resources_fi.xtb b/chrome/app/resources/generated_resources_fi.xtb
index 1567f9c..15f6a56 100644
--- a/chrome/app/resources/generated_resources_fi.xtb
+++ b/chrome/app/resources/generated_resources_fi.xtb
@@ -169,7 +169,7 @@
 <translation id="320944863083113761">Ota käyttöön vierekkäinen moniprofiilitila</translation>
 <translation id="8901167484503907716">Sisääntulonäkymän <ph name="INPUT_VIEW"/> lataus epäonnistui.</translation>
 <translation id="5177479852722101802">Estä kameran ja mikrofonin käyttö edelleen</translation>
-<translation id="4422428420715047158">Verkkotunnus:</translation>
+<translation id="4422428420715047158">Verkkotunnus Google.com:</translation>
 <translation id="7788444488075094252">Kielet ja syöte</translation>
 <translation id="6723354935081862304">Tulosta Google Docsiin ja muihin pilvikohteisiin.  <ph name="BEGIN_LINK"/>Kirjaudu sisään<ph name="END_LINK"/> ja tulosta Google Cloud Printin avulla.</translation>
 <translation id="8561096986926824116">Yhteys osoitteeseen
@@ -1784,6 +1784,7 @@
 <translation id="7724603315864178912">Leikkaa</translation>
 <translation id="8456681095658380701">Nimi ei kelpaa</translation>
 <translation id="3518086201899641494">Captive portalien ilmoitukset</translation>
+<translation id="3652052123500137959">Ota puhehaku käyttöön sovelluksien käynnistysohjelmassa.</translation>
 <translation id="1976150099241323601">Kirjaudu sisään suojauslaitteeseen</translation>
 <translation id="4120817667028078560">Polku on liian pitkä</translation>
 <translation id="4938972461544498524">Kosketuslevyn asetukset</translation>
@@ -2863,6 +2864,7 @@
 <translation id="8443621894987748190">Valitse kuva tiliäsi varten</translation>
 <translation id="7374461526650987610">Protokollien käsittelijät</translation>
 <translation id="2192505247865591433">Lähettäjä:</translation>
+<translation id="8668997025496699314">Ota puhehaku käyttöön sovelluksien käynnistysohjelmassa. Jos asetus on käytössä, käyttäjät voivat tehdä puhehakuja.</translation>
 <translation id="4634771451598206121">Kirjaudu uudelleen sisään...</translation>
 <translation id="3475110616773907981">Käyttää kaikkia tietokoneesi ja käyttämiesi verkkosivustojen tietoja</translation>
 <translation id="1035590878859356651">Aseta sivu kirjanmerkiksi…</translation>
@@ -3770,7 +3772,6 @@
 <translation id="3228279582454007836">Et ole käynyt tässä sivustossa ennen tätä päivää.</translation>
 <translation id="7027125358315426638">Tietokannan nimi:</translation>
 <translation id="4030383055268325496">K&amp;umoa lisäys</translation>
-<translation id="5474648613967354713">Poista puhehaku käytöstä sovelluksien käynnistysohjelmassa.</translation>
 <translation id="5449716055534515760">&amp;Sulje ikkuna</translation>
 <translation id="3224239078034945833">Kanada, monikielinen</translation>
 <translation id="4875057836161716898">Ota syöttönäkymät käyttöön.</translation>
@@ -4253,7 +4254,6 @@
 <translation id="1812514023095547458">Valitse väri</translation>
 <translation id="2487656424763972284">Helppo lukituksen avaus</translation>
 <translation id="7047998246166230966">Osoitin</translation>
-<translation id="743268637741709136">Poista puhehaku käytöstä sovelluksien käynnistysohjelmassa. Jos asetus ei ole käytössä, käyttäjä ei voi tehdä puhehakuja.</translation>
 <translation id="3252266817569339921">ranska</translation>
 <translation id="2665717534925640469">Tämä sivu on nyt koko ruudun kokoinen ja on poistanut hiiren osoittimen käytöstä.</translation>
 <translation id="3414952576877147120">Koko:</translation>
@@ -4673,7 +4673,7 @@
 <translation id="3154429428035006212">Offline-tilassa yli kuukauden</translation>
 <translation id="4861833787540810454">&amp;Toista</translation>
 <translation id="5521010850848859697">Palvelin 2</translation>
-<translation id="9053020327624825007">Verkkotunnus <ph name="MANAGEMENT_DOMAIN"/> on merkinnyt tämän laitteen yrityshallintaan.</translation>
+<translation id="9053020327624825007">Verkkotunnus Google.com <ph name="MANAGEMENT_DOMAIN"/> on merkinnyt tämän laitteen yrityshallintaan.</translation>
 <translation id="6769712124046837540">Tulostinta lisätään…</translation>
 <translation id="2552545117464357659">Uudempi</translation>
 <translation id="7269802741830436641">Tällä verkkosivulla on uudelleenohjaussilmukka</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb
index 7d06dd0..189010c 100644
--- a/chrome/app/resources/generated_resources_fil.xtb
+++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -1804,6 +1804,7 @@
 <translation id="7724603315864178912">Cut</translation>
 <translation id="8456681095658380701">Di-wastong pangalan</translation>
 <translation id="3518086201899641494">Mga notification tungkol sa mga captive portal</translation>
+<translation id="3652052123500137959">I-enable ang paghahanap gamit ang boses sa App Launcher.</translation>
 <translation id="1976150099241323601">Mag-sign in sa Pangseguridad na Device</translation>
 <translation id="4120817667028078560">Masyadong mahaba ang path</translation>
 <translation id="4938972461544498524">Mga setting ng touchpad</translation>
@@ -2908,6 +2909,7 @@
 <translation id="8443621894987748190">Piliin ang larawan ng iyong account</translation>
 <translation id="7374461526650987610">Mga tagapangasiwa ng protocol</translation>
 <translation id="2192505247865591433">Mula:</translation>
+<translation id="8668997025496699314">I-enable ang paghahanap gamit ang boses sa App Launcher. Kung naka-enable, makakapaghanap ang user ayon sa speech.</translation>
 <translation id="4634771451598206121">Muling mag-sign in...</translation>
 <translation id="3475110616773907981">I-access ang lahat ng data sa iyong computer at sa mga website na iyong binibisita</translation>
 <translation id="1035590878859356651">I-bookmark ang pahinang ito...</translation>
@@ -3820,7 +3822,6 @@
 <translation id="3228279582454007836">Hindi mo binibisita ang site na ito bago ngayon.</translation>
 <translation id="7027125358315426638">Pangalan ng database:</translation>
 <translation id="4030383055268325496">&amp;I-undo ang pagdagdag</translation>
-<translation id="5474648613967354713">I-disable ang paghahanap gamit ang boses sa App Launcher.</translation>
 <translation id="5449716055534515760">Isara ang Win&amp;dow</translation>
 <translation id="3224239078034945833">Canadian Multilingual</translation>
 <translation id="4875057836161716898">I-enable ang mga view ng input.</translation>
@@ -4308,7 +4309,6 @@
 <translation id="1812514023095547458">Pumili ng Kulay</translation>
 <translation id="2487656424763972284">Easy Unlock</translation>
 <translation id="7047998246166230966">Pointer</translation>
-<translation id="743268637741709136">I-disable ang paghahanap gamit ang boses sa App Launcher. Kung naka-disable, hindi makakapaghanap ang user sa pamamagitan ng pagsasalita.</translation>
 <translation id="3252266817569339921">French</translation>
 <translation id="2665717534925640469">Nasa full screen na ngayon ang pahinang ito at hindi pinagana ang cursor ng iyong mouse.</translation>
 <translation id="3414952576877147120">Laki:</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb
index 1c4e5c3..fab5f77 100644
--- a/chrome/app/resources/generated_resources_fr.xtb
+++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -1800,6 +1800,7 @@
 <translation id="7724603315864178912">Couper</translation>
 <translation id="8456681095658380701">Ce nom n'est pas valide.</translation>
 <translation id="3518086201899641494">Notifications au sujet des portails captifs</translation>
+<translation id="3652052123500137959">Activer la recherche vocale dans le lanceur d'applications</translation>
 <translation id="1976150099241323601">Se connecter au dispositif de sécurité</translation>
 <translation id="4120817667028078560">Chemin d'accès trop long.</translation>
 <translation id="4938972461544498524">Paramètres du pavé tactile</translation>
@@ -2909,6 +2910,7 @@
 <translation id="8443621894987748190">Choix de l'image du compte</translation>
 <translation id="7374461526650987610">Gestionnaires de protocoles</translation>
 <translation id="2192505247865591433">De :</translation>
+<translation id="8668997025496699314">Activer la recherche vocale dans le lanceur d'applications. Si celle-ci est activée, l'utilisateur peut effectuer des recherches en énonçant ses requêtes.</translation>
 <translation id="4634771451598206121">Nouvelle connexion...</translation>
 <translation id="3475110616773907981">Accéder à toutes les données de votre ordinateur et aux sites Web que vous consultez</translation>
 <translation id="1035590878859356651">Ajouter cette page aux favoris…</translation>
@@ -3820,7 +3822,6 @@
 <translation id="3228279582454007836">Vous n'avez jamais visité ce site auparavant.</translation>
 <translation id="7027125358315426638">Nom de la base de données :</translation>
 <translation id="4030383055268325496">&amp;Annuler l'ajout</translation>
-<translation id="5474648613967354713">Désactiver la recherche vocale dans le lanceur d'applications</translation>
 <translation id="5449716055534515760">Fe&amp;rmer la fenêtre</translation>
 <translation id="3224239078034945833">Canadien multilingue</translation>
 <translation id="4875057836161716898">Activer les interfaces de saisie</translation>
@@ -4306,7 +4307,6 @@
 <translation id="1812514023095547458">Sélectionner une couleur</translation>
 <translation id="2487656424763972284">Easy Unlock</translation>
 <translation id="7047998246166230966">Curseur</translation>
-<translation id="743268637741709136">Désactiver la recherche vocale dans le lanceur d'applications. Si ce paramètre est désactivé, l'utilisateur ne peut pas effectuer de recherche vocale.</translation>
 <translation id="3252266817569339921">Français</translation>
 <translation id="2665717534925640469">Cette page est maintenant en mode plein écran et a désactivé le curseur de votre souris.</translation>
 <translation id="3414952576877147120">Taille :</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb
index 1588e19..fdd14fd 100644
--- a/chrome/app/resources/generated_resources_gu.xtb
+++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -1811,6 +1811,7 @@
 <translation id="7724603315864178912">કાપો</translation>
 <translation id="8456681095658380701">અમાન્ય નામ</translation>
 <translation id="3518086201899641494">કેપ્ટિવ પોર્ટલ્સ વિશે સૂચનાઓ</translation>
+<translation id="3652052123500137959">એપ લૉન્ચરમાં વૉઇસ શોધ સક્ષમ કરો.</translation>
 <translation id="1976150099241323601">સુરક્ષા ઉપકરણ પર સાઇન ઇન કરો </translation>
 <translation id="4120817667028078560">પાથ ખૂબ લાંબો છે</translation>
 <translation id="4938972461544498524">ટચપૅડ સેટિંગ્સ</translation>
@@ -2912,6 +2913,7 @@
 <translation id="8443621894987748190">તમારું એકાઉન્ટ ચિત્ર પસંદ કરો</translation>
 <translation id="7374461526650987610">પ્રોટોકોલ હેન્ડલર્સ</translation>
 <translation id="2192505247865591433">તરફથી:</translation>
+<translation id="8668997025496699314">એપ લૉન્ચરમાં વૉઇસ શોધ સક્ષમ કરો. જો સક્ષમ હોય, તો વપરાશકર્તા અવાજ દ્વારા શોધવા માટે સમર્થ હશે.</translation>
 <translation id="4634771451598206121">ફરીથી સાઇન ઇન કરો....</translation>
 <translation id="3475110616773907981">તમારા કમ્પ્યુટર પરનાં બધા ડેટા અને તમે મુલાકાત લો છો તે વેબસાઇટ્સને ઍક્સેસ કરો</translation>
 <translation id="1035590878859356651">આ પૃષ્ઠને બુકમાર્ક કરો...</translation>
@@ -3819,7 +3821,6 @@
 <translation id="3228279582454007836">તમે આજ પહેલાં ક્યારેય આ સાઇટની મુલાકાત લીધી નથી.</translation>
 <translation id="7027125358315426638">ડેટાબેસ નામ:</translation>
 <translation id="4030383055268325496">&amp;ઉમેરવું પૂર્વવત્ કરો</translation>
-<translation id="5474648613967354713">એપ લૉન્ચરમાં વૉઇસ શોધ અક્ષમ કરો.</translation>
 <translation id="5449716055534515760">Close Win&amp;dow</translation>
 <translation id="3224239078034945833">કેનેડિયન બહુભાષીય</translation>
 <translation id="4875057836161716898">ઇનપુટ દૃશ્યો સક્ષમ કરો.</translation>
@@ -4307,7 +4308,6 @@
 <translation id="1812514023095547458">રંગ પસંદ કરો</translation>
 <translation id="2487656424763972284">સરળ અનલૉક</translation>
 <translation id="7047998246166230966">પોઇન્ટર</translation>
-<translation id="743268637741709136">એપ લૉન્ચરમાં વૉઇસ શોધ અક્ષમ કરો. જો અક્ષમ હોય, તો વપરાશકર્તા અવાજ દ્વારા શોધવા માટે સમર્થ હશે નહીં.</translation>
 <translation id="3252266817569339921">ફ્રેન્ચ</translation>
 <translation id="2665717534925640469">આ હવે પૂર્ણ સ્ક્રીન છે અને તેણે તમારા માઉસ કર્સરને અક્ષમ કર્યું છે.</translation>
 <translation id="3414952576877147120">કદ:</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb
index 64ca305..8a14799 100644
--- a/chrome/app/resources/generated_resources_hi.xtb
+++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -1803,6 +1803,7 @@
 <translation id="7724603315864178912">काटें</translation>
 <translation id="8456681095658380701">अमान्‍य नाम</translation>
 <translation id="3518086201899641494">कैप्टिव पोर्टल के बारे में सूचनाएं</translation>
+<translation id="3652052123500137959">एप्लिकेशन लॉन्चर में बोलकर खोजना सक्षम करें.</translation>
 <translation id="1976150099241323601">सुरक्षा डिवाइस में प्रवेश करें</translation>
 <translation id="4120817667028078560">पथ बहुत बड़ा है</translation>
 <translation id="4938972461544498524">Touchpad सेटिंग</translation>
@@ -2920,6 +2921,7 @@
 <translation id="8443621894987748190">अपना खाता चित्र चुनें</translation>
 <translation id="7374461526650987610">प्रोटोकॉल हैंडलर</translation>
 <translation id="2192505247865591433">द्वारा:</translation>
+<translation id="8668997025496699314">एप्लिकेशन लॉन्चर में बोलकर खोजना सक्षम करें. यदि सक्षम है, तो उपयोगकर्ता बोलकर खोज कर सकेगा.</translation>
 <translation id="4634771451598206121">पुन: प्रवेश करें...</translation>
 <translation id="3475110616773907981">आपके कंप्यूटर और आपके द्वारा देखी जाने वाली वेबसाइटों के सभी डेटा तक पहुंचें</translation>
 <translation id="1035590878859356651">इस पृष्ठ को बुकमार्क करें...</translation>
@@ -3832,7 +3834,6 @@
 <translation id="3228279582454007836">आपने आज से पहले यह साइट कभी नहीं देखी है.</translation>
 <translation id="7027125358315426638">डेटाबेस नाम:</translation>
 <translation id="4030383055268325496">&amp;जोड़ना पूर्ववत करें</translation>
-<translation id="5474648613967354713">एप्लिकेशन लॉन्चर में बोलकर खोजना अक्षम करें.</translation>
 <translation id="5449716055534515760">विं&amp;डो बंद करें</translation>
 <translation id="3224239078034945833">कनाडियाई बहुभाषी</translation>
 <translation id="4875057836161716898">इनपुट दृश्यों को सक्षम करें.</translation>
@@ -4322,7 +4323,6 @@
 <translation id="1812514023095547458">रंग को चुनें</translation>
 <translation id="2487656424763972284">आसान अनलॉक</translation>
 <translation id="7047998246166230966">सूचक</translation>
-<translation id="743268637741709136">एप्लिकेशन लॉन्चर में बोलकर खोजना अक्षम करें. यदि अक्षम हो, तो उपयोगकर्ता बोलकर नहीं खोज सकेगा.</translation>
 <translation id="3252266817569339921">फ़्रेंच</translation>
 <translation id="2665717534925640469">यह पृष्ठ अब पूर्ण स्‍क्रीन है और आपका माउस कर्सर अक्षम कर दिया गया है.</translation>
 <translation id="3414952576877147120">आकार:</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb
index 4a73f01..be61ae8 100644
--- a/chrome/app/resources/generated_resources_hr.xtb
+++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -1780,6 +1780,7 @@
 <translation id="7724603315864178912">Izreži</translation>
 <translation id="8456681095658380701">Pogrešno ime</translation>
 <translation id="3518086201899641494">Obavijesti o obaveznim portalima za autentifikaciju</translation>
+<translation id="3652052123500137959">Omogući glasovno pretraživanje u Pokretaču aplikacija.</translation>
 <translation id="1976150099241323601">Prijavi se na sigurnosni uređaj</translation>
 <translation id="4120817667028078560">Putanja je predugačka</translation>
 <translation id="4938972461544498524">Postavke dodirne podloge</translation>
@@ -2872,6 +2873,7 @@
 <translation id="8443621894987748190">Odaberite sliku svog računa</translation>
 <translation id="7374461526650987610">Rukovatelji protokolima</translation>
 <translation id="2192505247865591433">Šalje:</translation>
+<translation id="8668997025496699314">Omogućuje glasovno pretraživanje u Pokretaču aplikacija. Ako je ta opcija omogućena, korisnik će moći pretraživati govorom.</translation>
 <translation id="4634771451598206121">Prijavite se ponovo...</translation>
 <translation id="3475110616773907981">pristupiti svim podacima na vašem računalu i web-lokacijama koje posjetite</translation>
 <translation id="1035590878859356651">Označi ovu stranicu...</translation>
@@ -3779,7 +3781,6 @@
 <translation id="3228279582454007836">Do danas niste posjetili ovu web lokaciju.</translation>
 <translation id="7027125358315426638">Naziv baze podataka:</translation>
 <translation id="4030383055268325496">&amp;Poništi dodavanje</translation>
-<translation id="5474648613967354713">Onemogući glasovno pretraživanje u Pokretaču aplikacija.</translation>
 <translation id="5449716055534515760">Close Win&amp;dow (Zatvori prozor)</translation>
 <translation id="3224239078034945833">kanadska (višejezična)</translation>
 <translation id="4875057836161716898">Omogućivanje prikaza unosa.</translation>
@@ -4264,7 +4265,6 @@
 <translation id="1812514023095547458">Odabir boje</translation>
 <translation id="2487656424763972284">Jednostavno otključavanje</translation>
 <translation id="7047998246166230966">Pokazivač</translation>
-<translation id="743268637741709136">Onemogućuje glasovno pretraživanje u Pokretaču aplikacija. Ako je ta opcija onemogućena, korisnik neće moći pretraživati govorom.</translation>
 <translation id="3252266817569339921">francuska</translation>
 <translation id="2665717534925640469">Ova je stranica sada na cijelom zaslonu i onemogućila je pokazivač miša.</translation>
 <translation id="3414952576877147120">Veličina:</translation>
diff --git a/chrome/app/resources/generated_resources_hu.xtb b/chrome/app/resources/generated_resources_hu.xtb
index ff07509..6740d9a 100644
--- a/chrome/app/resources/generated_resources_hu.xtb
+++ b/chrome/app/resources/generated_resources_hu.xtb
@@ -1783,6 +1783,7 @@
 <translation id="7724603315864178912">Kivágás</translation>
 <translation id="8456681095658380701">Érvénytelen név</translation>
 <translation id="3518086201899641494">Captive (előzetes hitelesítést igénylő) portálokkal kapcsolatos értesítések</translation>
+<translation id="3652052123500137959">Hangalapú keresés engedélyezése az Alkalmazásindítóban.</translation>
 <translation id="1976150099241323601">Bejelentkezés a biztonságos eszközre</translation>
 <translation id="4120817667028078560">Az elérési út túl hosszú</translation>
 <translation id="4938972461544498524">Érintőpad beállításai</translation>
@@ -2877,6 +2878,7 @@
 <translation id="8443621894987748190">Válassza ki képét a fiókjához</translation>
 <translation id="7374461526650987610">Protokollkezelők</translation>
 <translation id="2192505247865591433">Innen:</translation>
+<translation id="8668997025496699314">Hangalapú keresés engedélyezése az Alkalmazásindítóban. Ha engedélyezve van, a felhasználó kimondott parancsokkal kereshet.</translation>
 <translation id="4634771451598206121">Bejelentkezés újra...</translation>
 <translation id="3475110616773907981">Hozzáférés a számítógépen lévő összes adathoz és a felkeresett webhelyekhez</translation>
 <translation id="1035590878859356651">Hozzáadás a könyvjelzőkhöz...</translation>
@@ -3783,7 +3785,6 @@
 <translation id="3228279582454007836">A mai nap előtt még soha nem látogatta meg ezt a webhelyet.</translation>
 <translation id="7027125358315426638">Adatbázis neve:</translation>
 <translation id="4030383055268325496">&amp;Hozzáadás visszavonása</translation>
-<translation id="5474648613967354713">A hangalapú keresés letiltása az Alkalmazásindítóban.</translation>
 <translation id="5449716055534515760">A&amp;blak bezárása</translation>
 <translation id="3224239078034945833">kanadai többnyelvű</translation>
 <translation id="4875057836161716898">Beviteli nézetek engedélyezése.</translation>
@@ -4268,7 +4269,6 @@
 <translation id="1812514023095547458">Szín kiválasztása</translation>
 <translation id="2487656424763972284">Egyszerű feloldás</translation>
 <translation id="7047998246166230966">Mutató</translation>
-<translation id="743268637741709136">Hangalapú keresés letiltása az Alkalmazásindítóban. Ha le van tiltva, a felhasználó nem lesz képes kimondott parancsokkal keresni.</translation>
 <translation id="3252266817569339921">francia</translation>
 <translation id="2665717534925640469">Ez az oldal most teljes képernyős nézetben van, és letiltotta az egérmutatót.</translation>
 <translation id="3414952576877147120">Méret:</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb
index f980931..afec6a2 100644
--- a/chrome/app/resources/generated_resources_id.xtb
+++ b/chrome/app/resources/generated_resources_id.xtb
@@ -1787,6 +1787,7 @@
 <translation id="7724603315864178912">Potong</translation>
 <translation id="8456681095658380701">Nama tidak valid</translation>
 <translation id="3518086201899641494">Pemberitahuan tentang portal yang tertahan</translation>
+<translation id="3652052123500137959">Aktifkan penelusuran suara di Peluncur Aplikasi.</translation>
 <translation id="1976150099241323601">Masuk ke Peranti Keamanan</translation>
 <translation id="4120817667028078560">Jalur terlalu panjang</translation>
 <translation id="4938972461544498524">Setelan Touchpad</translation>
@@ -2882,6 +2883,7 @@
 <translation id="8443621894987748190">Pilih gambar akun Anda</translation>
 <translation id="7374461526650987610">Penangan protokol</translation>
 <translation id="2192505247865591433">Dari:</translation>
+<translation id="8668997025496699314">Mengaktifkan penelusuran suara di Peluncur Aplikasi. Jika diaktifkan, pengguna akan dapat menelusuri dengan ucapan.</translation>
 <translation id="4634771451598206121">Masuk lagi...</translation>
 <translation id="3475110616773907981">Mengakses semua data pada komputer dan situs web yang Anda kunjungi</translation>
 <translation id="1035590878859356651">Bookmark laman ini...</translation>
@@ -3792,7 +3794,6 @@
 <translation id="3228279582454007836">Anda belum pernah mengunjungi situs ini.</translation>
 <translation id="7027125358315426638">Nama basis data:</translation>
 <translation id="4030383055268325496">&amp;Urungkan penambahan</translation>
-<translation id="5474648613967354713">Nonaktifkan penelusuran suara dalam Peluncur Aplikasi</translation>
 <translation id="5449716055534515760">Tutup Jen&amp;dela</translation>
 <translation id="3224239078034945833">Multibahasa Kanada</translation>
 <translation id="4875057836161716898">Aktifkan tampilan masukan.</translation>
@@ -4277,7 +4278,6 @@
 <translation id="1812514023095547458">Pilih Warna</translation>
 <translation id="2487656424763972284">Easy Unlock</translation>
 <translation id="7047998246166230966">Penunjuk</translation>
-<translation id="743268637741709136">Menonaktifkan penelusuran suara dalam Peluncur Aplikasi. Jika dinonaktifkan, pengguna tidak akan dapat menelusuri dengan ucapan.</translation>
 <translation id="3252266817569339921">Prancis</translation>
 <translation id="2665717534925640469">Laman ini sekarang menjadi layar penuh dan telah menonaktifkan kursor mouse Anda.</translation>
 <translation id="3414952576877147120">Ukuran:</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb
index 7be7377..c82f66e 100644
--- a/chrome/app/resources/generated_resources_it.xtb
+++ b/chrome/app/resources/generated_resources_it.xtb
@@ -1772,6 +1772,7 @@
 <translation id="7724603315864178912">Taglia</translation>
 <translation id="8456681095658380701">Nome non valido</translation>
 <translation id="3518086201899641494">Notifiche relative a captive portal</translation>
+<translation id="3652052123500137959">Attiva ricerca vocale in Avvio applicazioni.</translation>
 <translation id="1976150099241323601">Accedi a dispositivo di sicurezza</translation>
 <translation id="4120817667028078560">Percorso troppo lungo</translation>
 <translation id="4938972461544498524">Impostazioni touchpad</translation>
@@ -2863,6 +2864,7 @@
 <translation id="8443621894987748190">Scegli la foto dell'account</translation>
 <translation id="7374461526650987610">Gestori di protocollo</translation>
 <translation id="2192505247865591433">Da:</translation>
+<translation id="8668997025496699314">Consente di attivare la ricerca vocale in Avvio applicazioni. Se l'opzione viene attivata, l'utente potrà eseguire ricerche vocali.</translation>
 <translation id="4634771451598206121">Esegui di nuovo l'accesso...</translation>
 <translation id="3475110616773907981">Accesso a tutti i dati sul computer e sui siti web visitati</translation>
 <translation id="1035590878859356651">Aggiungi questa pagina ai Preferiti...</translation>
@@ -3765,7 +3767,6 @@
 <translation id="3228279582454007836">Non hai mai visitato questo sito prima di oggi.</translation>
 <translation id="7027125358315426638">Nome database:</translation>
 <translation id="4030383055268325496">&amp;Annulla aggiunta</translation>
-<translation id="5474648613967354713">Disattiva ricerca vocale in Avvio applicazioni.</translation>
 <translation id="5449716055534515760">Chiu&amp;di finestra</translation>
 <translation id="3224239078034945833">Multilingue canadese</translation>
 <translation id="4875057836161716898">Attiva visualizzazioni metodi di immissione.</translation>
@@ -4248,7 +4249,6 @@
 <translation id="1812514023095547458">Seleziona colore</translation>
 <translation id="2487656424763972284">Sblocco facilitato</translation>
 <translation id="7047998246166230966">Puntatore</translation>
-<translation id="743268637741709136">Disattiva ricerca vocale in Avvio applicazioni. Se disattivi la funzione, l'utente non potrà eseguire ricerche utilizzando comandi vocali.</translation>
 <translation id="3252266817569339921">Francese</translation>
 <translation id="2665717534925640469">Questa pagina ora è a schermo intero e ha disattivato il puntatore del mouse.</translation>
 <translation id="3414952576877147120">Dimensioni:</translation>
@@ -4764,7 +4764,7 @@
 <translation id="8775404590947523323">Le modifiche vengono salvate automaticamente.<ph name="BREAKS"/>Per conservare una copia dell'immagine originale, deseleziona l'opzione &quot;Sovrascrivi originale&quot;.</translation>
 <translation id="5208988882104884956">Metà larghezza</translation>
 <translation id="1507170440449692343">A questa pagina è stato impedito l'accesso alla webcam.</translation>
-<translation id="4189406272289638749">Un'estensione, &lt;b&gt;<ph name="EXTENSION_NAME"/>&lt;/b&gt;, sta controllando questa impostazione.</translation>
+<translation id="4189406272289638749">Un'estensione, &lt;b&gt;<ph name="EXTENSION_NAME"/>&lt;/b&gt;, controlla questa impostazione.</translation>
 <translation id="803771048473350947">Archivio</translation>
 <translation id="6206311232642889873">Cop&amp;ia immagine</translation>
 <translation id="5158983316805876233">Usa lo stesso proxy per tutti i protocolli</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb
index 8a01494..14a4b5a 100644
--- a/chrome/app/resources/generated_resources_iw.xtb
+++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -1785,6 +1785,7 @@
 <translation id="7724603315864178912">חתוך</translation>
 <translation id="8456681095658380701">שם לא חוקי</translation>
 <translation id="3518086201899641494">הודעות על פורטל חובה</translation>
+<translation id="3652052123500137959">הפעל חיפוש קולי במפעיל היישומים.</translation>
 <translation id="1976150099241323601">היכנס אל התקן אבטחה</translation>
 <translation id="4120817667028078560">הנתיב ארוך מדי</translation>
 <translation id="4938972461544498524">הגדרות לוח מגע</translation>
@@ -2874,6 +2875,7 @@
 <translation id="8443621894987748190">בחר את תמונת החשבון</translation>
 <translation id="7374461526650987610">תוכניות לטיפול בפרוטוקולים</translation>
 <translation id="2192505247865591433">מ:</translation>
+<translation id="8668997025496699314">הפעל חיפוש קולי במפעיל היישומים. אם התכונה הזו מופעלת, המשתמש יוכל לחפש באמצעות דיבור.</translation>
 <translation id="4634771451598206121">היכנס שוב...</translation>
 <translation id="3475110616773907981">להיכנס לכל הנתונים במחשב שלך ובאתרים שבהם אתה מבקר</translation>
 <translation id="1035590878859356651">הוספת דף זה לסימניות...</translation>
@@ -3777,7 +3779,6 @@
 <translation id="3228279582454007836">מעולם לא ביקרת באתר זה קודם לכן.</translation>
 <translation id="7027125358315426638">שם מסד נתונים:</translation>
 <translation id="4030383055268325496">&amp;ביטול הוספה</translation>
-<translation id="5474648613967354713">השבת חיפוש קולי במפעיל היישומים.</translation>
 <translation id="5449716055534515760">סגור ח&amp;לון</translation>
 <translation id="3224239078034945833">קנדית - מרובת-שפות</translation>
 <translation id="4875057836161716898">הפעל תצוגות קלט.</translation>
@@ -4265,7 +4266,6 @@
 <translation id="1812514023095547458">בחר צבע</translation>
 <translation id="2487656424763972284">ביטול קל של נעילה</translation>
 <translation id="7047998246166230966">מצביע</translation>
-<translation id="743268637741709136">השבת חיפוש קולי במפעיל היישומים. אם אפשרות זו מושבתת, המשתמש לא יוכל לחפש באמצעות דיבור.</translation>
 <translation id="3252266817569339921">צרפתית</translation>
 <translation id="2665717534925640469">דף זה מוצג כעת במסך מלא והשבית את סמן העכבר שלך.</translation>
 <translation id="3414952576877147120">גודל:</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb
index 2f2813f..69f9d32 100644
--- a/chrome/app/resources/generated_resources_ja.xtb
+++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -1795,6 +1795,7 @@
 <translation id="7724603315864178912">切り取り</translation>
 <translation id="8456681095658380701">名前が無効です</translation>
 <translation id="3518086201899641494">キャプティブ ポータルに関する通知</translation>
+<translation id="3652052123500137959">アプリ ランチャーでの音声検索を有効にする</translation>
 <translation id="1976150099241323601">セキュリティ デバイスへのログイン</translation>
 <translation id="4120817667028078560">パスが長すぎます</translation>
 <translation id="4938972461544498524">トラックパッドの設定</translation>
@@ -2899,6 +2900,7 @@
 <translation id="8443621894987748190">アカウントの写真を選択</translation>
 <translation id="7374461526650987610">プロトコル ハンドラ</translation>
 <translation id="2192505247865591433">取得先:</translation>
+<translation id="8668997025496699314">アプリ ランチャーでの音声検索を有効にします。有効にした場合、ユーザーは音声で検索できるようになります。</translation>
 <translation id="4634771451598206121">もう一度ログインする...</translation>
 <translation id="3475110616773907981">パソコンおよびアクセスするウェブサイトのすべてのデータにアクセスする</translation>
 <translation id="1035590878859356651">このページをブックマークする…</translation>
@@ -3811,7 +3813,6 @@
 <translation id="3228279582454007836">このサイトにアクセスしたのは今日がはじめてです。</translation>
 <translation id="7027125358315426638">データベース名:</translation>
 <translation id="4030383055268325496">追加の取り消し(&amp;U)</translation>
-<translation id="5474648613967354713">アプリ ランチャーでの音声検索を無効にする。</translation>
 <translation id="5449716055534515760">ウィンドウを閉じる(&amp;D)</translation>
 <translation id="3224239078034945833">カナダ多言語</translation>
 <translation id="4875057836161716898">入力ビューを有効にする</translation>
@@ -4297,7 +4298,6 @@
 <translation id="1812514023095547458">色を選択</translation>
 <translation id="2487656424763972284">簡単ロック解除</translation>
 <translation id="7047998246166230966">ポインタ</translation>
-<translation id="743268637741709136">アプリ ランチャーでの音声検索を無効にします。無効にした場合、ユーザーは音声で検索できなくなります。</translation>
 <translation id="3252266817569339921">フランス語</translation>
 <translation id="2665717534925640469">現在このページは全画面表示で、マウス カーソルは無効になります。</translation>
 <translation id="3414952576877147120">サイズ:</translation>
diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb
index d35f51a..136be81 100644
--- a/chrome/app/resources/generated_resources_kn.xtb
+++ b/chrome/app/resources/generated_resources_kn.xtb
@@ -1798,6 +1798,7 @@
 <translation id="7724603315864178912">ಕತ್ತರಿಸು</translation>
 <translation id="8456681095658380701">ಅಮಾನ್ಯವಾದ ಹೆಸರು</translation>
 <translation id="3518086201899641494">ವಶದಲ್ಲಿರುವ ಪೋರ್ಟಲ್‌ಗಳ ಕುರಿತು ಅಧಿಸೂಚನೆಗಳು</translation>
+<translation id="3652052123500137959">ಅಪ್ಲಿಕೇಶನ್‌ ಲಾಂಚರ್‍‌ನಲ್ಲಿ ಧ್ವನಿ ಹುಡುಕಾಟವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ.</translation>
 <translation id="1976150099241323601">ಭದ್ರತಾ ಸಾಧನಕ್ಕೆ ಸೈನ್ ಇನ್ ಆಗಿರಿ</translation>
 <translation id="4120817667028078560">ಹಾದಿ ತುಂಬಾ ಉದ್ದವಾಗಿದೆ</translation>
 <translation id="4938972461544498524">ಟಚ್‌ಪ್ಯಾಡ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು</translation>
@@ -2888,6 +2889,7 @@
 <translation id="8443621894987748190">ನಿಮ್ಮ ಖಾತೆಯ ಚಿತ್ರವನ್ನು ಆರಿಸಿ</translation>
 <translation id="7374461526650987610">ಪ್ರೊಟೊಕಾಲ್ ಹ್ಯಾಂಡ್‌ಲರ್‌ಗಳು</translation>
 <translation id="2192505247865591433">ಇವರಿಂದ:</translation>
+<translation id="8668997025496699314">ಅಪ್ಲಿಕೇಶನ್ ಲಾಂಚರ್‌ನಲ್ಲಿ ಧ್ವನಿ ಹುಡುಕಾಟವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ. ಸಕ್ರಿಯಗೊಳಿಸಿದರೆ, ಬಳಕೆದಾರರಿಗೆ ತಮ್ಮ ಮಾತಿನ ಮೂಲಕ ಹುಡುಕಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ.</translation>
 <translation id="4634771451598206121">ಪುನಃ ಸೈನ್ ಇನ್  ಮಾಡಿ...</translation>
 <translation id="3475110616773907981">ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನಲ್ಲಿರುವ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಮತ್ತು ನೀವು ಭೇಟಿ ನೀಡಿರುವ ವೆಬ್‌ಸೈಟ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ</translation>
 <translation id="1035590878859356651">ಈ ಪುಟವನ್ನು ಬುಕ್‌ಮಾರ್ಕ್ ಮಾಡಿ...</translation>
@@ -3796,7 +3798,6 @@
 <translation id="3228279582454007836">ಈ ದಿನಕ್ಕಿಂತ ಮೊದಲೆ ನೀವು ಈ ಸೈಟ್‌ಗೆ ಭೇಟಿಯನ್ನು ಕೊಟ್ಟಿದ್ದೀರಿ.</translation>
 <translation id="7027125358315426638">ಡೇಟಾಬೇಸ್ ಹೆಸರು:</translation>
 <translation id="4030383055268325496">&amp;ಸೇರಿಸುವುದನ್ನು ರದ್ದುಗೊಳಿಸಿ</translation>
-<translation id="5474648613967354713">ಅಪ್ಲಿಕೇಶನ್‌ ಲಾಂಚರ್‍‌ನಲ್ಲಿ ಧ್ವನಿ ಹುಡುಕಾಟವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ.</translation>
 <translation id="5449716055534515760">&amp;ವಿಂಡೋ ಮುಚ್ಚಿರಿ</translation>
 <translation id="3224239078034945833">ಕೆನಡಾದ ಬಹುಭಾಷಾ</translation>
 <translation id="4875057836161716898">ಇನ್‌ಪುಟ್ ವೀಕ್ಷಣೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸು.</translation>
@@ -4283,7 +4284,6 @@
 <translation id="1812514023095547458">ಬಣ್ಣವನ್ನು ಆಯ್ಕೆಮಾಡಿ</translation>
 <translation id="2487656424763972284">ಸುಲಭ ಅನ್‌ಲಾಕ್</translation>
 <translation id="7047998246166230966">ಪಾಯಿಂಟರ್‌</translation>
-<translation id="743268637741709136">ಅಪ್ಲಿಕೇಶನ್‌ ಲಾಂಚರ್‍‌ನಲ್ಲಿ ಧ್ವನಿ ಹುಡುಕಾಟವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ. ಒಂದು ವೇಳೆ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಲ್ಲಿ, ಬಳಕೆದಾರರು ತಮ್ಮ ಭಾಷಣದ ಮೂಲಕ ಹುಡುಕಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ.</translation>
 <translation id="3252266817569339921">ಫ್ರೆಂಚ್</translation>
 <translation id="2665717534925640469">ಈ ಪುಟವು ಇದೀಗ ಪೂರ್ಣ ಪರದೆಯಾಗಿದೆ ಮತ್ತು ನಿಮ್ಮ ಮೌಸ್ ಕರ್ಸರ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದೆ.</translation>
 <translation id="3414952576877147120">ಗಾತ್ರ:</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb
index 0e28eff..633da52 100644
--- a/chrome/app/resources/generated_resources_ko.xtb
+++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -1807,6 +1807,7 @@
 <translation id="7724603315864178912">잘라내기</translation>
 <translation id="8456681095658380701">잘못된 이름입니다.</translation>
 <translation id="3518086201899641494">웹포털 인증 알림</translation>
+<translation id="3652052123500137959">앱 런처에서 음성검색을 사용 설정합니다.</translation>
 <translation id="1976150099241323601">보안 장치 로그인</translation>
 <translation id="4120817667028078560">경로가 너무 김</translation>
 <translation id="4938972461544498524">터치패드 설정</translation>
@@ -2906,6 +2907,7 @@
 <translation id="8443621894987748190">계정 사진 선택</translation>
 <translation id="7374461526650987610">프로토콜 핸들러</translation>
 <translation id="2192505247865591433">웹 브라우저</translation>
+<translation id="8668997025496699314">앱 런처에서 음성검색을 사용 설정합니다. 설정하면 사용자가 음성으로 검색할 수 있습니다.</translation>
 <translation id="4634771451598206121">다시 로그인...</translation>
 <translation id="3475110616773907981">컴퓨터 및 방문하는 웹사이트의 전체 데이터에 액세스</translation>
 <translation id="1035590878859356651">현재 페이지를 북마크에 추가...</translation>
@@ -3816,7 +3818,6 @@
 <translation id="3228279582454007836">이 페이지에 오늘 처음 방문했습니다.</translation>
 <translation id="7027125358315426638">데이터베이스 이름:</translation>
 <translation id="4030383055268325496">추가 실행 취소(&amp;U)</translation>
-<translation id="5474648613967354713">앱 런처에서 음성 검색을 사용 중지합니다.</translation>
 <translation id="5449716055534515760">창 닫기(&amp;D)</translation>
 <translation id="3224239078034945833">캐나다 다국어</translation>
 <translation id="4875057836161716898">입력 화면을 사용하도록 설정합니다.</translation>
@@ -4303,7 +4304,6 @@
 <translation id="1812514023095547458">색상 선택</translation>
 <translation id="2487656424763972284">간편 잠금 해제</translation>
 <translation id="7047998246166230966">포인터</translation>
-<translation id="743268637741709136">앱 런처에서 음성 검색을 사용 중지합니다. 사용 중지하면 사용자는 음성으로 검색할 수 없습니다.</translation>
 <translation id="3252266817569339921">프랑스어</translation>
 <translation id="2665717534925640469">페이지가 현재 전체화면으로 전환되었으며 마우스 커서를 사용 중지했습니다.</translation>
 <translation id="3414952576877147120">크기:</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb
index ebfb9cf..3beb314 100644
--- a/chrome/app/resources/generated_resources_lt.xtb
+++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -1009,7 +1009,7 @@
 <translation id="8847850603363009033">Įgalinkite „Ctrl“ + „Alt“ + „Shift“ + D, kad perjungtumėte „TouchView“ padidinimo režimą.</translation>
 <translation id="8352772353338965963">Pridėkite paskyrą prie kelių paskyrų. Visos paskyros, prie kurių prisijungta, gali būti pasiekiamos be slaptažodžio, todėl ši funkcija turėtų būti naudojama tik su patikimomis paskyromis.</translation>
 <translation id="8965158701501115465">Pasiekti ir ištrinti nuotraukas, muziką ir kitą mediją iš kompiuterio.</translation>
-<translation id="5361686177218315158">„Adobe Flash Player“ kameros ir mikrofono išimtys skirtingos.</translation>
+<translation id="5361686177218315158">„Adobe Flash“ leistuvės kameros ir mikrofono išimtys skirtingos.</translation>
 <translation id="5043766625767731235">Toliau blokuoti ne „sandbox“ (smėlio dėžės) technologijos papildinius</translation>
 <translation id="4667176955651319626">Blokuoti trečiųjų šalių slapukus ir svetainės duomenis</translation>
 <translation id="6686490380836145850">Uždaryti dešinėje esančius skirtukus</translation>
@@ -1805,6 +1805,7 @@
 <translation id="7724603315864178912">Iškirpti</translation>
 <translation id="8456681095658380701">Netinkamas pavadinimas</translation>
 <translation id="3518086201899641494">Pranešimai apie užvaldytus portalus</translation>
+<translation id="3652052123500137959">Įgalinkite paiešką balsu Programų paleidimo priemonėje.</translation>
 <translation id="1976150099241323601">Prisijungti prie apsaugos įrenginio</translation>
 <translation id="4120817667028078560">Kelias per ilgas</translation>
 <translation id="4938972461544498524">Jutiklinės dalies nustatymai</translation>
@@ -2914,6 +2915,7 @@
 <translation id="8443621894987748190">Pasirinkite paskyros paveikslėlį</translation>
 <translation id="7374461526650987610">„Protokolų“ doroklės</translation>
 <translation id="2192505247865591433">Nuo:</translation>
+<translation id="8668997025496699314">Įgalinkite paiešką balsu Programų paleidimo priemonėje. Jei ji įgalinta, naudotojas galės atlikti paiešką balsu.</translation>
 <translation id="4634771451598206121">Prisijungti dar kartą...</translation>
 <translation id="3475110616773907981">Pasiekti visus kompiuterio ir lankomų svetainių duomenis</translation>
 <translation id="1035590878859356651">Žymėti šį puslapį...</translation>
@@ -3164,7 +3166,7 @@
 <translation id="2857421400871862029">Paklausti, kai svetainėje bandoma išjungti pelės žymeklį (rekomenduojama)</translation>
 <translation id="1910721550319506122">Sveiki!</translation>
 <translation id="4035758313003622889">&amp;Užduočių tvarkyklė</translation>
-<translation id="6356936121715252359">„Adobe Flash Player“ saugojimo nustatymai...</translation>
+<translation id="6356936121715252359">„Adobe Flash“ leistuvės saugojimo nustatymai...</translation>
 <translation id="8874184842967597500">Neprisijungta</translation>
 <translation id="7313804056609272439">Įvesties vietnamiečių k. metodas (VNI)</translation>
 <translation id="8599675288025166194">Įgalinti eksperimentines efemeriškas programas, į kurias galima pateikti nuorodų.</translation>
@@ -3827,7 +3829,6 @@
 <translation id="3228279582454007836">Iki šios dienos nė karto nesilankėte šioje svetainėje.</translation>
 <translation id="7027125358315426638">Duomenų pavadinimas:</translation>
 <translation id="4030383055268325496">&amp;Anuliuoti pridėjimą</translation>
-<translation id="5474648613967354713">Išjungti paiešką balsu Programų paleidimo priemonėje.</translation>
 <translation id="5449716055534515760">Uždaryti lan&amp;gą</translation>
 <translation id="3224239078034945833">Kanadai skirta kelių kalbų</translation>
 <translation id="4875057836161716898">Įgalinti įvesties rodinius.</translation>
@@ -4315,7 +4316,6 @@
 <translation id="1812514023095547458">Pasirinkti spalvą</translation>
 <translation id="2487656424763972284">Lengvas atrakinimas</translation>
 <translation id="7047998246166230966">Žymeklis</translation>
-<translation id="743268637741709136">Išjungti paiešką balsu Programų paleidimo priemonėje. Jei ji išjungta, naudotojas negalės atlikti paieškos balsu.</translation>
 <translation id="3252266817569339921">Prancūzų</translation>
 <translation id="2665717534925640469">Šis puslapis dabar veikia viso ekrano režimu ir jame neleidžiamas pelės žymeklis.</translation>
 <translation id="3414952576877147120">Dydis:</translation>
@@ -4729,7 +4729,7 @@
 <translation id="636850387210749493">Įmonės registracija</translation>
 <translation id="4602466770786743961">Visada leisti <ph name="HOST"/> pasiekti fotoaparatą ir mikrofoną</translation>
 <translation id="852573274664085347">Redagavimą palietimu galima inicijuoti palietus teksto lauką arba pasirinktą tekstą.</translation>
-<translation id="2746106911980887717">„Adobe Flash Player“ kameros ir mikrofono nustatymai skirtingi.</translation>
+<translation id="2746106911980887717">„Adobe Flash“ leistuvės kameros ir mikrofono nustatymai skirtingi.</translation>
 <translation id="2799046819183570437">Leidžia atlikti bandomuosius išdėstymo tobulinimus, kad naudotojai galėtų patogiau naudoti jutiklinius ekranus.</translation>
 <translation id="932508678520956232">Spausdinimo pradėti nepavyko.</translation>
 <translation id="7953955868932471628">Valdyti sparčiuosius klavišus</translation>
diff --git a/chrome/app/resources/generated_resources_lv.xtb b/chrome/app/resources/generated_resources_lv.xtb
index b0d587e..289ad34 100644
--- a/chrome/app/resources/generated_resources_lv.xtb
+++ b/chrome/app/resources/generated_resources_lv.xtb
@@ -1798,6 +1798,7 @@
 <translation id="7724603315864178912">Izgriezt</translation>
 <translation id="8456681095658380701">Nederīgs nosaukums</translation>
 <translation id="3518086201899641494">Paziņojumi par caurlaides lapām</translation>
+<translation id="3652052123500137959">Funkcijas Balss meklēšana iespējošana lietotņu palaidējā.</translation>
 <translation id="1976150099241323601">Pierakstīties drošības ierīcē</translation>
 <translation id="4120817667028078560">Ceļš ir pārāk garš.</translation>
 <translation id="4938972461544498524">Skārienpaliktņa iestatījumi</translation>
@@ -2894,6 +2895,7 @@
 <translation id="8443621894987748190">Izvēlieties sava konta attēlu</translation>
 <translation id="7374461526650987610">Protokolu apdarinātāji</translation>
 <translation id="2192505247865591433">No:</translation>
+<translation id="8668997025496699314">Iespējojiet funkciju Balss meklēšana lietotņu palaidējā. Ja funkcija būs iespējota, lietotāji varēs meklēt ar balsi.</translation>
 <translation id="4634771451598206121">Pierakstīties vēlreiz...</translation>
 <translation id="3475110616773907981">Piekļūt visiem datiem jūsu datorā, kā arī jūsu apmeklētajām vietnēm</translation>
 <translation id="1035590878859356651">Saglabāt šo lapu kā grāmatzīmi...</translation>
@@ -3804,7 +3806,6 @@
 <translation id="3228279582454007836">Jūs neesat šo vietni apmeklējis iepriekš.</translation>
 <translation id="7027125358315426638">Datu bāzes nosaukums:</translation>
 <translation id="4030383055268325496">&amp;Atsaukt pievienošanu</translation>
-<translation id="5474648613967354713">Atspējot meklēšanu ar balsi lietotņu palaidējā</translation>
 <translation id="5449716055534515760">Aizvērt Win&amp;dow</translation>
 <translation id="3224239078034945833">Kanādas vairākvalodu</translation>
 <translation id="4875057836161716898">Iespējot ievades skatus.</translation>
@@ -4291,7 +4292,6 @@
 <translation id="1812514023095547458">Krāsas atlase</translation>
 <translation id="2487656424763972284">Vieglā atbloķēšana</translation>
 <translation id="7047998246166230966">Rādītājs</translation>
-<translation id="743268637741709136">Atspējot meklēšanu ar balsi lietotņu palaidējā. Pēc atspējošanas lietotājs nevarēs veikt meklēšanu ar balsi.</translation>
 <translation id="3252266817569339921">Franču</translation>
 <translation id="2665717534925640469">Šī lapa tagad ir redzama pilnekrāna režīmā un ir atspējojusi jūsu peles kursoru.</translation>
 <translation id="3414952576877147120">Lielums:</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb
index b62aca5..58a2d6b 100644
--- a/chrome/app/resources/generated_resources_ml.xtb
+++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -1433,7 +1433,7 @@
 <translation id="7791543448312431591">ചേര്‍ക്കൂ</translation>
 <translation id="8569764466147087991">തുറക്കുന്നതിന് ഒരു ഫയല്‍ തിരഞ്ഞെടുക്കുക</translation>
 <translation id="3010279545267083280">പാസ്‌വേഡ് ഇല്ലാതാക്കി</translation>
-<translation id="5086589117546410981">അവസാന നാമം ചേർക്കുക</translation>
+<translation id="5086589117546410981">പേരിന്റെ അവസാനഭാഗം ചേർക്കുക</translation>
 <translation id="4275663329226226506">മീഡിയ</translation>
 <translation id="8783027177343486886">തൽക്ഷണ വിപുലീകൃത API പ്രവർത്തനക്ഷമമാക്കുക</translation>
 <translation id="3093853184108622112"><ph name="WEBSITE_1"/>, <ph name="WEBSITE_2"/> എന്നിവയിലെ നിങ്ങളുടെ ഡാറ്റ ആക്‌സസ്സുചെയ്യുക</translation>
@@ -1814,6 +1814,7 @@
 <translation id="7724603315864178912">മുറിക്കുക</translation>
 <translation id="8456681095658380701">അസാധുവായ പേര്</translation>
 <translation id="3518086201899641494">ക്യാപ്‌റ്റീവ് പോർട്ടലുകളെക്കുറിച്ചുള്ള അറിയിപ്പുകൾ</translation>
+<translation id="3652052123500137959">അപ്ലിക്കേഷൻ ലോഞ്ചറിൽ വോയ്‌സ് തിരയൽ പ്രവർത്തനക്ഷമമാക്കുക.</translation>
 <translation id="1976150099241323601">സുരക്ഷാ ഉപാധിയിലേക്ക് പ്രവേശിക്കുക</translation>
 <translation id="4120817667028078560">പാത്ത് ദൈർഘ്യമേറിയതാണ്</translation>
 <translation id="4938972461544498524">ടച്ച്പാഡ് ക്രമീകരണങ്ങൾ</translation>
@@ -1895,7 +1896,7 @@
 <translation id="3326821416087822643"><ph name="FILE_NAME"/> zip ചെയ്യുന്നു...</translation>
 <translation id="3081104028562135154">വര്‍‌ദ്ധിപ്പിക്കുക</translation>
 <translation id="3734816294831429815"><ph name="SECONDS"/> നിമിഷങ്ങൾക്കുള്ളിൽ <ph name="PRODUCT_NAME"/> പുനരാരംഭിക്കും.</translation>
-<translation id="2728624657977418581">ആദ്യനാമം ചേർക്കുക</translation>
+<translation id="2728624657977418581">പേരിന്റെ ആദ്യഭാഗം ചേർക്കുക</translation>
 <translation id="8732030010853991079">ഈ ഐക്കണിൽ ക്ലിക്കുചെയ്‌ത് ഈ വിപുലീകരണം സജീവമാക്കുക.</translation>
 <translation id="32330993344203779">സംരംഭ കൈകാര്യത്തിനായി നിങ്ങളുടെ ഉപാധി വിജയകരമായി എന്‍‌റോള്‍ ചെയ്തിരിക്കുന്നു.</translation>
 <translation id="158917669717260118">നിങ്ങളുടെ കമ്പ്യൂട്ടർ സുഷുപ്‌തിയിൽ ആയതിനാലോ ഹൈബർനേറ്റ് മോഡിലായതിനാലോ വെബ്‌പേജ് ലോഡുചെയ്യാൻ കഴിയുന്നില്ല.  ഇത് സംഭവിക്കുമ്പോൾ, നെറ്റ്‌വർക്ക് കണക്ഷനുകൾ പ്രവർത്തനരഹിതമാകുകയും പുതിയ നെറ്റ്‌വർക്ക് അഭ്യർത്ഥനകൾ പരാജയപ്പെടുകയും ചെയ്യുന്നു.  പേജ് വീണ്ടും ലോഡുചെയ്യുന്നതിലൂടെ ഇത് പരിഹരിക്കപ്പെടും.</translation>
@@ -2912,6 +2913,7 @@
 <translation id="8443621894987748190">നിങ്ങളുടെ അക്കൗണ്ട് ചിത്രം തെരഞ്ഞെടുക്കുക</translation>
 <translation id="7374461526650987610">പ്രോട്ടോക്കോൾ ഹാൻഡ്‌ലറുകൾ</translation>
 <translation id="2192505247865591433">പ്രേഷിതാവ്:</translation>
+<translation id="8668997025496699314">അപ്ലിക്കേഷൻ ലോഞ്ചറിൽ വോയ്‌സ് തിരയൽ പ്രവർത്തനക്ഷമമാക്കുക. പ്രവർത്തനക്ഷമമാക്കിയെങ്കിൽ, സംഭാഷണം പ്രകാരം ഉപയോക്താവിന് തിരയാനാകും.</translation>
 <translation id="4634771451598206121">വീണ്ടും പ്രവേശിക്കുക...</translation>
 <translation id="3475110616773907981">നിങ്ങളുടെ കമ്പ്യൂട്ടറിലേയും സന്ദർശിക്കുന്ന വെബ്‌സൈറ്റുകളിലേയും എല്ലാ ഡാറ്റയും ആക്‌സസ്സുചെയ്യുക</translation>
 <translation id="1035590878859356651">ഈ പേജ് ബുക്ക്മാര്‍ക്ക് ചെയ്യുക...</translation>
@@ -3821,7 +3823,6 @@
 <translation id="3228279582454007836">ഇന്നത്തേതിന് മുമ്പ് നിങ്ങള്‍ ഈ സൈറ്റ് സന്ദര്‍ശിച്ചിട്ടില്ല.</translation>
 <translation id="7027125358315426638">ഡാറ്റാബേസിന്റെ പേര്:</translation>
 <translation id="4030383055268325496">&amp;ചേർക്കുന്നത് പഴയപടിയാക്കുക</translation>
-<translation id="5474648613967354713">അപ്ലിക്കേഷൻ ലോഞ്ചറിൽ വോയ്‌സ് തിരയൽ പ്രവർത്തനരഹിതമാക്കുക.</translation>
 <translation id="5449716055534515760">വി&amp;ന്‍ഡോ അടയ്ക്കുക</translation>
 <translation id="3224239078034945833">കനേഡിയൻ മൾട്ടിലിംഗ്വൽ</translation>
 <translation id="4875057836161716898">ഇൻപുട്ട് കാഴ്‌ചകൾ പ്രവർത്തനക്ഷമമാക്കുക.</translation>
@@ -4310,7 +4311,6 @@
 <translation id="1812514023095547458">വർണ്ണം തിരഞ്ഞെടുക്കുക</translation>
 <translation id="2487656424763972284">എളുപ്പത്തിൽ അൺലോക്കുചെയ്യൽ</translation>
 <translation id="7047998246166230966">പോയിന്റർ</translation>
-<translation id="743268637741709136">അപ്ലിക്കേഷൻ ലോഞ്ചറിൽ വോയ്‌സ് തിരയൽ പ്രവർത്തനരഹിതമാക്കുക. പ്രവർത്തനരഹിതമാക്കിയിട്ടുണ്ടെങ്കിൽ, സംഭാഷണം മുഖേന ഉപയോക്താവിന് തിരയാനാകില്ല.</translation>
 <translation id="3252266817569339921">ഫ്രഞ്ച്</translation>
 <translation id="2665717534925640469">ഈ പേജ് ഇപ്പോൾ പൂർണ സ്‌ക്രീനിലാണ് കൂടാതെ നിങ്ങളുടെ മൗസ് കഴ്‌സർ അപ്രാപ്‌തമാക്കി.</translation>
 <translation id="3414952576877147120">വലുപ്പം:</translation>
diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb
index e4f8764..2bee98d 100644
--- a/chrome/app/resources/generated_resources_mr.xtb
+++ b/chrome/app/resources/generated_resources_mr.xtb
@@ -1803,6 +1803,7 @@
 <translation id="7724603315864178912">कट करा</translation>
 <translation id="8456681095658380701">अवैध नाव</translation>
 <translation id="3518086201899641494">कॅप्टिव्ह पोर्टलविषयी सूचना</translation>
+<translation id="3652052123500137959">अ‍ॅप लाँचर मध्ये व्हॉइस शोध सक्षम करा.</translation>
 <translation id="1976150099241323601">सुरक्षा डिव्हाइसमध्ये साइन इन करा</translation>
 <translation id="4120817667028078560">पथ खूपच लांब आहे</translation>
 <translation id="4938972461544498524">टचपॅड सेटिंग्ज</translation>
@@ -2911,6 +2912,7 @@
 <translation id="8443621894987748190">आपल्‍या खात्याचे चित्र निवडा</translation>
 <translation id="7374461526650987610">प्रोटोकॉल हँडलर</translation>
 <translation id="2192505247865591433">द्वारा:</translation>
+<translation id="8668997025496699314">अनुप्रयोग लाँचर मध्ये व्हॉइस शोध सक्षम करा. सक्षम असल्यास, वापरकर्ता बोलून शोध घेण्यात सक्षम असेल.</translation>
 <translation id="4634771451598206121">पुन्हा साइन इन करा...</translation>
 <translation id="3475110616773907981">आपल्या संगणकावरील आणि आपण भेट देत असलेल्या वेबसाइट वरील सर्व डेटावर प्रवेश करा</translation>
 <translation id="1035590878859356651">या पृष्ठास बुकमार्क करा...</translation>
@@ -3820,7 +3822,6 @@
 <translation id="3228279582454007836">आपण यापूर्वी कधीही या साइटला भेट दिलेली नाही.</translation>
 <translation id="7027125358315426638">डेटाबेस नाव:</translation>
 <translation id="4030383055268325496">&amp;जोडा पूर्ववत करा</translation>
-<translation id="5474648613967354713">अ‍ॅप लाँचर मध्ये व्हॉइस शोध अक्षम करा.</translation>
 <translation id="5449716055534515760">विं&amp;डो बंद करा</translation>
 <translation id="3224239078034945833">कॅनडियन बहुभाषी</translation>
 <translation id="4875057836161716898">इनपुट दृश्य सक्षम करा.</translation>
@@ -4309,7 +4310,6 @@
 <translation id="1812514023095547458">रंग निवडा</translation>
 <translation id="2487656424763972284">सुलभ अनलॉक</translation>
 <translation id="7047998246166230966">पॉइंटर</translation>
-<translation id="743268637741709136">अॅप लाँचर मध्ये व्हॉइस शोध अक्षम करा. अक्षम असल्यास, वापरकर्ता उच्चारणाद्वारे शोध घेण्यास सक्षम होणार नाही.</translation>
 <translation id="3252266817569339921">फ्रेंच</translation>
 <translation id="2665717534925640469">हे पृष्‍ठ आता फुल स्क्रीन असून त्याने आपला माऊस कर्सर अक्षम केला आहे.</translation>
 <translation id="3414952576877147120">आकार:</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb
index 55ca807..aea2a9b 100644
--- a/chrome/app/resources/generated_resources_ms.xtb
+++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -1800,6 +1800,7 @@
 <translation id="7724603315864178912">Potong</translation>
 <translation id="8456681095658380701">Nama tidak sah</translation>
 <translation id="3518086201899641494">Pemberitahuan mengenai portal tawanan</translation>
+<translation id="3652052123500137959">Dayakan carian suara dalam Pelancar Apl.</translation>
 <translation id="1976150099241323601">Log masuk ke Peranti Keselamatan</translation>
 <translation id="4120817667028078560">Laluan terlalu panjang</translation>
 <translation id="4938972461544498524">Tetapan pad sentuh</translation>
@@ -2919,6 +2920,7 @@
 <translation id="8443621894987748190">Pilih gambar akaun anda</translation>
 <translation id="7374461526650987610">Pengendali protokol</translation>
 <translation id="2192505247865591433">Daripada:</translation>
+<translation id="8668997025496699314">Dayakan carian suara dalam Pelancar App. Jika didayakan, pengguna akan dapat mencari melalui ucapan.</translation>
 <translation id="4634771451598206121">Log masuk semula...</translation>
 <translation id="3475110616773907981">Akses semua data pada komputer anda dan tapak web yang anda lawati</translation>
 <translation id="1035590878859356651">Tanda halaman ini...</translation>
@@ -3830,7 +3832,6 @@
 <translation id="3228279582454007836">Anda tidak pernah melawati tapak ini sebelum hari ini.</translation>
 <translation id="7027125358315426638">Nama pangkalan data:</translation>
 <translation id="4030383055268325496">&amp;Buat asal tambahkan</translation>
-<translation id="5474648613967354713">Lumpuhkan carian suara dalam Pelancar Apl.</translation>
 <translation id="5449716055534515760">Tutup Te&amp;tingkap</translation>
 <translation id="3224239078034945833">Berbilang bahasa Kanada</translation>
 <translation id="4875057836161716898">Dayakan paparan input.</translation>
@@ -4319,7 +4320,6 @@
 <translation id="1812514023095547458">Pilih Warna</translation>
 <translation id="2487656424763972284">Buka Kunci Mudah</translation>
 <translation id="7047998246166230966">Penunjuk</translation>
-<translation id="743268637741709136">Lumpuhkan carian suara dalam Pelancar Apl. Jika dilumpuhkan, pengguna tidak akan dapat mencari menggunakan pertuturan.</translation>
 <translation id="3252266817569339921">Bahasa Perancis</translation>
 <translation id="2665717534925640469">Halaman ini kini dalam skrin penuh dan telah melumpuhkan kursor tetikus anda.</translation>
 <translation id="3414952576877147120">Saiz:</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb
index c801c4e..7137525 100644
--- a/chrome/app/resources/generated_resources_nl.xtb
+++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -1810,6 +1810,7 @@
 <translation id="7724603315864178912">Knip</translation>
 <translation id="8456681095658380701">Ongeldige naam</translation>
 <translation id="3518086201899641494">Meldingen over captive portals</translation>
+<translation id="3652052123500137959">Gesproken zoekopdracht inschakelen in de App Launcher.</translation>
 <translation id="1976150099241323601">Inloggen bij beveiligingsapparaat</translation>
 <translation id="4120817667028078560">Pad is te lang</translation>
 <translation id="4938972461544498524">Touchpadinstellingen</translation>
@@ -2916,6 +2917,7 @@
 <translation id="8443621894987748190">Kies je accountfoto</translation>
 <translation id="7374461526650987610">Protocolhandlers</translation>
 <translation id="2192505247865591433">Van:</translation>
+<translation id="8668997025496699314">Gesproken zoekopdracht inschakelen in de App Launcher. Als deze functie is ingeschakeld, kan de gebruiken gesproken zoekopdrachten uitvoeren.</translation>
 <translation id="4634771451598206121">Opnieuw inloggen...</translation>
 <translation id="3475110616773907981">Alle gegevens openen op je computer en de websites die je bezoekt</translation>
 <translation id="1035590878859356651">Bladwijzer voor deze pagina toevoegen...</translation>
@@ -3826,7 +3828,6 @@
 <translation id="3228279582454007836">Je bezoekt deze site vandaag voor het eerst.</translation>
 <translation id="7027125358315426638">Naam database:</translation>
 <translation id="4030383055268325496">&amp;Toevoegen ongedaan maken</translation>
-<translation id="5474648613967354713">Gesproken zoekopdracht uitschakelen in de App Launcher.</translation>
 <translation id="5449716055534515760">Ve&amp;nster sluiten</translation>
 <translation id="3224239078034945833">Canadees meertalig</translation>
 <translation id="4875057836161716898">Schakel invoerweergaven in.</translation>
@@ -4316,7 +4317,6 @@
 <translation id="1812514023095547458">Kleur selecteren</translation>
 <translation id="2487656424763972284">Eenvoudig ontgrendelen</translation>
 <translation id="7047998246166230966">Pijltje</translation>
-<translation id="743268637741709136">Gesproken zoekopdracht uitschakelen in de App Launcher. Als deze functie is uitgeschakeld, kan de gebruiker niet zoeken door te spreken.</translation>
 <translation id="3252266817569339921">Frans</translation>
 <translation id="2665717534925640469">Deze pagina wordt nu op volledig scherm weergegeven en heeft je muisaanwijzer uitgeschakeld.</translation>
 <translation id="3414952576877147120">Grootte:</translation>
diff --git a/chrome/app/resources/generated_resources_no.xtb b/chrome/app/resources/generated_resources_no.xtb
index 04128af..29d062b6 100644
--- a/chrome/app/resources/generated_resources_no.xtb
+++ b/chrome/app/resources/generated_resources_no.xtb
@@ -802,7 +802,7 @@
 <translation id="375841316537350618">Laster ned mellomtjenerskript ...</translation>
 <translation id="45400070127195133">Aktivering av dette alternativet tillater nettapper å bruke WebGL-utvidelsene som fortsatt er i utkaststatus.</translation>
 <translation id="4117553660243903041"><ph name="CLOUD_PRINT_NAME"/> lar deg bruke denne datamaskinens skrivere fra hvor som helst.</translation>
-<translation id="9169664750068251925">Alltid blokkér på dette nettstedet</translation>
+<translation id="9169664750068251925">Blokkér alltid på dette nettstedet</translation>
 <translation id="6406303162637086258">Simuler omstart av nettleseren</translation>
 <translation id="7428296649065852053">Tiden det tar å laste inn en nettside</translation>
 <translation id="8725178340343806893">Favoritter/bokmerker</translation>
@@ -1454,7 +1454,7 @@
 <translation id="996987097147224996">Trykk på Ctrl + mellomromstasten for å velge forrige inndatametode.</translation>
 <translation id="4240069395079660403"><ph name="PRODUCT_NAME"/> kan ikke vises på dette språket</translation>
 <translation id="747114903913869239">Feil: Kan ikke avkode etternavnet</translation>
-<translation id="7187885785158279764">Opphev filtilgangen</translation>
+<translation id="7187885785158279764">Opphev tilgangen til filer</translation>
 <translation id="3574210789297084292">logg på</translation>
 <translation id="1146204723345436916">Importer bokmerker fra HTML-fil</translation>
 <translation id="2113921862428609753">Informasjonstilgang til instans</translation>
@@ -1554,7 +1554,7 @@
 <translation id="825608351287166772">Sertifikater har en gyldighetsperiode, på linje med andre identitetsdokumenter (f.eks. pass). Sertifikatet som er presentert for nettleseren, er ikke gyldig ennå. Når et sertifikat er utenfor gyldighetsperioden, er det ikke påkrevd å vedlikeholde enkelte opplysninger om statusen for sertifikatet (om det er tilbakekalt og ikke lenger klarert). Det er dermed ikke mulig å verifisere at dette sertifikatet er pålitelig. Du bør ikke fortsette.</translation>
 <translation id="2381823505763074471">Logg av brukeren <ph name="PROFILE_USERNAME"/>.</translation>
 <translation id="3616113530831147358">Lyd</translation>
-<translation id="23030561267973084">«<ph name="EXTENSION_NAME"/>» har bedt om flere tillatelser.</translation>
+<translation id="23030561267973084">«<ph name="EXTENSION_NAME"/>» har bedt om ekstra tilgang.</translation>
 <translation id="6957887021205513506">Tjenersertifikatet ser ut til å være forfalsket.</translation>
 <translation id="8957709627709183338">Det er bare eieren av enheten som kan opprette overvåkede brukere.</translation>
 <translation id="8551494947769799688">Latvisk</translation>
@@ -1578,7 +1578,7 @@
 <translation id="8795668016723474529">Legg til kredittkort</translation>
 <translation id="5860033963881614850">Av</translation>
 <translation id="6575251558004911012">Spør når et nettsted krever tilgang til kameraet (anbefales)</translation>
-<translation id="4116663294526079822">Alltid tillat på dette nettstedet</translation>
+<translation id="4116663294526079822">Tillat alltid på dette nettstedet</translation>
 <translation id="7547317915858803630">Advarsel: <ph name="PRODUCT_NAME"/>-innstillingene dine lagres på en nettverksdisk. Dette kan forårsake forsinkelser, krasjer og til og med tap av data.</translation>
 <translation id="3956882961292411849">Laster inn opplysninger om mobildataplan. Vent litt.</translation>
 <translation id="689050928053557380">Kjøp dataplan</translation>
@@ -1788,6 +1788,7 @@
 <translation id="7724603315864178912">Klipp ut</translation>
 <translation id="8456681095658380701">Ugyldig navn</translation>
 <translation id="3518086201899641494">Varsler om autentiseringsportal</translation>
+<translation id="3652052123500137959">Aktiver talesøk i appvelgeren.</translation>
 <translation id="1976150099241323601">Logg på sikkerhetsenhet</translation>
 <translation id="4120817667028078560">Filbanen er for lang</translation>
 <translation id="4938972461544498524">Innstillinger for styreflate</translation>
@@ -2154,7 +2155,7 @@
 <translation id="707392107419594760">Velg tastatur:</translation>
 <translation id="8605503133013456784">Kunne ikke fjerne tilknytning til og koble fra «<ph name="DEVICE_NAME"/>».</translation>
 <translation id="2007404777272201486">Rapporter et problem</translation>
-<translation id="4366509400410520531">Tillates av deg</translation>
+<translation id="4366509400410520531">Tillatt av deg</translation>
 <translation id="2218947405056773815">Beklager. <ph name="API_NAME"/> støtte på et hinder.</translation>
 <translation id="6797509194603611336">åpne alle <ph name="PROTOCOL"/>-linker i stedet for <ph name="REPLACED_HANDLER_TITLE"/>?</translation>
 <translation id="1783075131180517613">Oppdater passordfrasen for synkronisering.</translation>
@@ -2890,13 +2891,14 @@
 <translation id="8443621894987748190">Velg bilde for konto</translation>
 <translation id="7374461526650987610">Protokollbehandlere</translation>
 <translation id="2192505247865591433">Fra:</translation>
+<translation id="8668997025496699314">Aktiver talesøk i appvelgeren. Hvis talesøk er aktivert, kan brukeren søke ved å snakke.</translation>
 <translation id="4634771451598206121">Logg på igjen</translation>
 <translation id="3475110616773907981">få tilgang til alle data på datamaskinen din og nettstedene du besøker</translation>
 <translation id="1035590878859356651">Legg til bokmerke for denne siden</translation>
 <translation id="3944266449990965865">Hele skjermen</translation>
 <translation id="942954117721265519">Det fins ingen bilder i denne katalogen.</translation>
 <translation id="671928215901716392">Lås skjerm</translation>
-<translation id="2241468422635044128">Tillatt ifølge utvidelsen</translation>
+<translation id="2241468422635044128">Tillatt av en utvidelse</translation>
 <translation id="3727187387656390258">Undersøk hurtigvindu</translation>
 <translation id="361106536627977100">Flash-data</translation>
 <translation id="569068482611873351">Importer</translation>
@@ -3556,7 +3558,7 @@
 <translation id="1834560242799653253">Retning:</translation>
 <translation id="7085070717976089605">Aktivert – skjuler inndata i multifunksjonsfeltet</translation>
 <translation id="6440616190620341629">Aktiver dekoding uten sammensetting i MediaDrm som standard for krypterte medieutvidelser.</translation>
-<translation id="8353683614194668312">Den kan</translation>
+<translation id="8353683614194668312">Den får følgende tilgang:</translation>
 <translation id="1047956942837015229">Sletter <ph name="COUNT"/> elementer ...</translation>
 <translation id="1531961661616401172">Aktiver eksperimentelle synkroniserte varsler.</translation>
 <translation id="7361039089383199231">$1 bytes</translation>
@@ -3633,7 +3635,7 @@
 <translation id="7439964298085099379">Høy kontrast-modusen er aktivert. Vil du installere Høy kontrast-utvidelsen vår og et mørkt tema?</translation>
 <translation id="9012607008263791152">Jeg forstår at dette nettstedet kan skade datamaskinen.</translation>
 <translation id="6640442327198413730">Bufferfeil</translation>
-<translation id="3788401245189148511">Den kan</translation>
+<translation id="3788401245189148511">Den får følgende tilgang:</translation>
 <translation id="8926518602592448999">Deaktiver utvidelser for utviklermodus</translation>
 <translation id="2902734494705624966">Amerikansk utvidet</translation>
 <translation id="5793220536715630615">K&amp;opier videoens nettadresse</translation>
@@ -3796,7 +3798,6 @@
 <translation id="3228279582454007836">Du har aldri besøkt dette nettstedet før i dag.</translation>
 <translation id="7027125358315426638">Databasenavn:</translation>
 <translation id="4030383055268325496">&amp;Angre tilleggingen</translation>
-<translation id="5474648613967354713">Deaktiver talesøk i appvelgeren.</translation>
 <translation id="5449716055534515760">Lukk vin&amp;du</translation>
 <translation id="3224239078034945833">Flerspråklig canadisk</translation>
 <translation id="4875057836161716898">Slå på inndatavisninger.</translation>
@@ -4023,7 +4024,7 @@
 <translation id="1084300930170237385">Informasjon om åpenhet</translation>
 <translation id="774465434535803574">Feil ved pakking av utvidelse</translation>
 <translation id="8200772114523450471">Fortsett</translation>
-<translation id="5750676294091770309">Blokkert av utvidelsen</translation>
+<translation id="5750676294091770309">Blokkert av en utvidelse</translation>
 <translation id="1302191857856401062">Gjør det mulig å bytte raskt mellom brukere i brukerbildemenyen.</translation>
 <translation id="7865978820218947446">Rediger bruker</translation>
 <translation id="523299859570409035">Unntak for varsler</translation>
@@ -4283,7 +4284,6 @@
 <translation id="1812514023095547458">Velg farge</translation>
 <translation id="2487656424763972284">Enkel opplåsing</translation>
 <translation id="7047998246166230966">Peker</translation>
-<translation id="743268637741709136">Deaktiver talesøk i appvelgeren. Når den er deaktivert, kan ikke brukeren søke med tale.</translation>
 <translation id="3252266817569339921">Fransk</translation>
 <translation id="2665717534925640469">Denne siden vises nå i fullskjermsvisning, og har deaktivert markøren din.</translation>
 <translation id="3414952576877147120">Størrelse:</translation>
@@ -4416,7 +4416,7 @@
 <translation id="421017592316736757">Du må ha Internett-tilkobling for å få tilgang til denne filen.</translation>
 <translation id="3423858849633684918">Start <ph name="PRODUCT_NAME"/> på nytt</translation>
 <translation id="1232569758102978740">Uten tittel</translation>
-<translation id="3489444618744432220">Tillatt ifølge retningslinjen</translation>
+<translation id="3489444618744432220">Tillatt av en retningslinje</translation>
 <translation id="3925247638945319984">Du har ingen nylig lagrede WebRTC-logger.</translation>
 <translation id="6626108645084335023">Venter på DNS-sonde.</translation>
 <translation id="1903219944620007795">Velg språk for å se tilgjengelige inndatametoder for tekst.</translation>
@@ -4764,7 +4764,7 @@
 <translation id="6380143666419481200">Godta og fortsett</translation>
 <translation id="713122686776214250">Legg til si&amp;de</translation>
 <translation id="4816492930507672669">Tilpass til siden</translation>
-<translation id="1485015260175968628">Den kan nå</translation>
+<translation id="1485015260175968628">Den har allerede følgende tilgang:</translation>
 <translation id="7496192982082800780">Dager</translation>
 <translation id="1122198203221319518">&amp;Verktøy</translation>
 <translation id="5143151113947480436">få tilgang til data du kopierer og limer inn</translation>
@@ -5100,7 +5100,7 @@
 <translation id="3268451620468152448">Åpne faner</translation>
 <translation id="4918086044614829423">Godta</translation>
 <translation id="4085298594534903246">JavaScript er blokkert på siden.</translation>
-<translation id="7825543042214876779">Blokkert av retningslinjen</translation>
+<translation id="7825543042214876779">Blokkert av en retningslinje</translation>
 <translation id="4341977339441987045">Blokker at nettsteder lagrer data på maskinen</translation>
 <translation id="806812017500012252">Sortér etter tittel</translation>
 <translation id="6518133107902771759">Bekreft</translation>
@@ -5196,7 +5196,7 @@
 <translation id="2050339315714019657">Stående</translation>
 <translation id="8273027367978594412">Når dette er aktivert, opprettes en gjestebruker i Chrome på skrivebordet.</translation>
 <translation id="6991128190741664836">Senere</translation>
-<translation id="8261490674758214762">De kan:</translation>
+<translation id="8261490674758214762">De får følgende tilgang:</translation>
 <translation id="8647750283161643317">Tilbakestill alle til standard</translation>
 <translation id="5112577000029535889">&amp;Utviklerverktøy</translation>
 <translation id="2301382460326681002">Utvidelsens rotkatalog er ugyldig.</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb
index 9fc1b5a..a25bb1b 100644
--- a/chrome/app/resources/generated_resources_pl.xtb
+++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -176,7 +176,7 @@
 <translation id="8561096986926824116">Połączenie z
         <ph name="HOST_NAME"/>
         zostało przerwane w wyniku zmiany w połączeniu sieciowym.</translation>
-<translation id="8804398419035066391">Komunikowanie się ze współpracującymi witrynami</translation>
+<translation id="8804398419035066391">Komunikować się ze współpracującymi witrynami</translation>
 <translation id="6023914116273780353">Spersonalizowane</translation>
 <translation id="7082055294850503883">Ignoruj stan klawisza CapsLock i domyślnie wprowadzaj małe litery</translation>
 <translation id="4989966318180235467">Sprawdź &amp;stronę tła</translation>
@@ -939,7 +939,7 @@
 <translation id="225943865679747347">Kod błędu: <ph name="ERROR_CODE"/></translation>
 <translation id="954888418274735665">Użyj globalnej wartości domyślnej (<ph name="PERMISSION_VALUE"/>)</translation>
 <translation id="904752364881701675">W lewym dolnym rogu</translation>
-<translation id="3589751314526435218">Dostęp do unikalnego identyfikatora tego komputera</translation>
+<translation id="3589751314526435218">Uzyskiwać dostęp do unikalnego identyfikatora tego komputera</translation>
 <translation id="3353984535370177728">Wybierz folder do przesłania</translation>
 <translation id="8943805475239098364">Chcesz wyszukiwać w <ph name="NEW_GOOGLE_HOST"/> zamiast <ph name="CURRENT_GOOGLE_HOST"/>?</translation>
 <translation id="6328639280570009161">Wyłącz przewidywanie działań sieciowych</translation>
@@ -1142,7 +1142,7 @@
 <translation id="192144045824434199">Włącz otwieranie okien paneli poza ramką przeglądarki. W przeciwnym razie przy próbie otwarcia panelu pojawia się wyskakujące okienko. Panele są zawsze włączone w wersji deweloperskiej i „canary”.</translation>
 <translation id="6344783595350022745">Wyczyść tekst</translation>
 <translation id="1426410128494586442">Tak</translation>
-<translation id="2359345697448000899">Możesz zarządzać zainstalowanymi rozszerzeniami, klikając Rozszerzenia w menu Narzędzia.</translation>
+<translation id="2359345697448000899">Aby zarządzać zainstalowanymi rozszerzeniami, kliknij Rozszerzenia w menu Narzędzia.</translation>
 <translation id="6725970970008349185">Liczba propozycji wyświetlanych na stronie</translation>
 <translation id="6513615899227776181">Wtyczka: <ph name="PLUGIN_NAME"/></translation>
 <translation id="6198252989419008588">Zmień kod PIN</translation>
@@ -1780,6 +1780,7 @@
 <translation id="7724603315864178912">Wytnij</translation>
 <translation id="8456681095658380701">Nieprawidłowa nazwa</translation>
 <translation id="3518086201899641494">Powiadomienia o portalach przechwytujących</translation>
+<translation id="3652052123500137959">Włącz wyszukiwanie głosowe w Menu z aplikacjami.</translation>
 <translation id="1976150099241323601">Zaloguj się do urządzenia zabezpieczającego</translation>
 <translation id="4120817667028078560">Zbyt długa ścieżka</translation>
 <translation id="4938972461544498524">Ustawienia touchpada</translation>
@@ -1861,7 +1862,7 @@
 <translation id="3081104028562135154">Zwiększ</translation>
 <translation id="3734816294831429815"><ph name="PRODUCT_NAME"/> zostanie uruchomiony ponownie za <ph name="SECONDS"/> s.</translation>
 <translation id="2728624657977418581">Dodaj imię</translation>
-<translation id="8732030010853991079">Użyj tego rozszerzenia, klikając tę ikonę</translation>
+<translation id="8732030010853991079">Aby użyć tego rozszerzenia, kliknij jego ikonę.</translation>
 <translation id="32330993344203779">Urządzenie zostało zarejestrowane do użytku w firmie.</translation>
 <translation id="158917669717260118">Nie można wczytać strony internetowej, ponieważ komputer przeszedł w tryb uśpienia lub hibernacji. Gdy to następuje, połączenia sieciowe są zamykane, a nowe żądania kończą się niepowodzeniem. Ponowne załadowanie strony powinno rozwiązać problem.</translation>
 <translation id="6316671927443834085">Nie można odłączyć od urządzenia „<ph name="DEVICE_NAME"/>”.</translation>
@@ -2281,7 +2282,7 @@
 <translation id="8449008133205184768">Wklej i dopasuj do stylu</translation>
 <translation id="4408427661507229495">nazwa sieci</translation>
 <translation id="5258266922137542658">PPAPI (w procesie)</translation>
-<translation id="5127881134400491887">Zarządzaj połączeniami sieciowymi</translation>
+<translation id="5127881134400491887">Zarządzać połączeniami sieciowymi</translation>
 <translation id="8028993641010258682">Rozmiar</translation>
 <translation id="8329978297633540474">Zwykły tekst</translation>
 <translation id="7704305437604973648">Zadanie</translation>
@@ -2566,7 +2567,7 @@
 <translation id="3264544094376351444">Czcionka bezszeryfowa</translation>
 <translation id="4628314759732363424">Zmień...</translation>
 <translation id="4569155249847375786">Zweryfikowane</translation>
-<translation id="5094721898978802975">Komunikowanie się ze współpracującymi aplikacjami natywnymi</translation>
+<translation id="5094721898978802975">Komunikować się ze współpracującymi aplikacjami natywnymi</translation>
 <translation id="1077946062898560804">Skonfiguruj aktualizacje automatyczne dla wszystkich użytkowników</translation>
 <translation id="3122496702278727796">Nie można utworzyć katalogu danych</translation>
 <translation id="6690751852586194791">Wybierz użytkownika nadzorowanego, którego chcesz dodać do tego urządzenia.</translation>
@@ -2876,6 +2877,7 @@
 <translation id="8443621894987748190">Wybierz zdjęcie dla konta</translation>
 <translation id="7374461526650987610">Obsługa protokołów</translation>
 <translation id="2192505247865591433">Z:</translation>
+<translation id="8668997025496699314">Włącza wyszukiwanie głosowe w Menu z aplikacjami. Po włączeniu użytkownik może wyszukiwać z użyciem mowy.</translation>
 <translation id="4634771451598206121">Zaloguj się ponownie</translation>
 <translation id="3475110616773907981">Uzyskiwać dostęp do wszystkich danych na tym komputerze i w odwiedzanych witrynach</translation>
 <translation id="1035590878859356651">Dodaj tę stronę do zakładek...</translation>
@@ -3355,7 +3357,7 @@
 <translation id="6607831829715835317">Więcej narzę&amp;dzi</translation>
 <translation id="2532589005999780174">Tryb wysokiego kontrastu</translation>
 <translation id="2805646850212350655">System szyfrowania plików firmy Microsoft</translation>
-<translation id="2643698698624765890">Możesz zarządzać zainstalowanymi rozszerzeniami, klikając Rozszerzenia w menu Okno.</translation>
+<translation id="2643698698624765890">Aby zarządzać zainstalowanymi rozszerzeniami, kliknij Rozszerzenia w menu Okno.</translation>
 <translation id="4846680374085650406">Przestrzegasz zaleceń administratora dotyczących tego ustawienia.</translation>
 <translation id="1974060860693918893">Zaawansowane</translation>
 <translation id="4509017836361568632">Odrzuć zdjęcie</translation>
@@ -3482,7 +3484,7 @@
 <translation id="4010065515774514159">Czynność wykonywana w przeglądarce</translation>
 <translation id="3733533226834394996">SHA-224</translation>
 <translation id="7295019613773647480">Włącz obsługę użytkowników nadzorowanych</translation>
-<translation id="2893389635995517838">Uzyskaj dostęp do zdjęć, muzyki i innych multimediów na komputerze.</translation>
+<translation id="2893389635995517838">Uzyskiwać dostęp do zdjęć, muzyki i innych multimediów na komputerze</translation>
 <translation id="2419414843209660528">Dodaj skrót do tej strony...</translation>
 <translation id="3529423920239848704">Sytuacje, w których <ph name="SHORT_PRODUCT_NAME"/> nie został prawidłowo zamknięty</translation>
 <translation id="7022562585984256452">Strona startowa została ustawiona.</translation>
@@ -3785,7 +3787,6 @@
 <translation id="3228279582454007836">Witryna nie była wcześniej odwiedzana.</translation>
 <translation id="7027125358315426638">Nazwa bazy danych:</translation>
 <translation id="4030383055268325496">&amp;Cofnij dodanie</translation>
-<translation id="5474648613967354713">Wyłącz wyszukiwanie głosowe w Menu z aplikacjami.</translation>
 <translation id="5449716055534515760">Zamknij o&amp;kno</translation>
 <translation id="3224239078034945833">kanadyjska klawiatura wielojęzyczna</translation>
 <translation id="4875057836161716898">Włącz widoki wprowadzania.</translation>
@@ -4066,7 +4067,7 @@
 <translation id="8276560076771292512">Opróżnij pamięć podręczną i wymuś ponowne załadowanie</translation>
 <translation id="9076523132036239772">Niestety, nie udało się zweryfikować Twojego adresu e-mail lub hasła. Najpierw nawiąż połączenie z siecią.</translation>
 <translation id="6965978654500191972">Urządzenie</translation>
-<translation id="1479356886123917758">Uzyskaj dostęp do zdjęć, muzyki i innych multimediów i zmieniaj je na komputerze.</translation>
+<translation id="1479356886123917758">Uzyskiwać dostęp do zdjęć, muzyki i innych multimediów i zmieniać je na komputerze</translation>
 <translation id="5295309862264981122">Potwierdź nawigację</translation>
 <translation id="718827667662449283">Wielka Brytania</translation>
 <translation id="2908999529399859069">Nie, anuluj</translation>
@@ -4082,7 +4083,7 @@
 <translation id="6120205520491252677">Przypnij tę stronę do ekranu startowego...</translation>
 <translation id="4190120546241260780">Aktywuj element 5 programu uruchamiającego</translation>
 <translation id="194030505837763158">Wejdź na <ph name="LINK"/></translation>
-<translation id="8272443605911821513">Możesz zarządzać zainstalowanymi rozszerzeniami, klikając Rozszerzenia w menu „Więcej narzędzi”.</translation>
+<translation id="8272443605911821513">Aby zarządzać zainstalowanymi rozszerzeniami, kliknij Rozszerzenia w menu Więcej narzędzi.</translation>
 <translation id="6905163627763043954">Wypróbuj</translation>
 <translation id="3510797500218907545">WiMAX</translation>
 <translation id="1104054824888299003">długie</translation>
@@ -4214,7 +4215,7 @@
 <translation id="8885905466771744233">Klucz prywatny dla określonego rozszerzenia już istnieje. Użyj ponownie tego klucza lub najpierw go usuń.</translation>
 <translation id="5425470845862293575">Włącza eksperymentalny system renderowania czcionek DirectWrite.</translation>
 <translation id="7583419135027754249">Zawsze wysyłaj zdarzenia kliknięcia natychmiast po kliknięciu, nawet jeśli są częścią gestu z dwukrotnym kliknięciem. Na większości stron przyspiesza to nawigację i inne działania kliknięcia o 300 ms, ale klikając dwukrotnie w celu powiększenia, trzeba omijać linki i przyciski.</translation>
-<translation id="2164561725439241890">Zapisywanie w plikach otwieranych w aplikacji</translation>
+<translation id="2164561725439241890">Zapisywć dane w plikach otwieranych w aplikacji</translation>
 <translation id="1196944142850240972">Uzyskiwać dostęp do Twoich danych we wszystkich witrynach</translation>
 <translation id="4100843820583867709">Prośba o udostępnienie ekranu w Google Talk</translation>
 <translation id="2406941037785138796">Wyłączenia</translation>
@@ -4270,7 +4271,6 @@
 <translation id="1812514023095547458">Wybierz kolor</translation>
 <translation id="2487656424763972284">Łatwe odblokowanie</translation>
 <translation id="7047998246166230966">Wskaźnik</translation>
-<translation id="743268637741709136">Wyłącza wyszukiwanie głosowe w menu z aplikacjami. Użytkownik nie może wtedy wyszukiwać z użyciem mowy.</translation>
 <translation id="3252266817569339921">francuski</translation>
 <translation id="2665717534925640469">Ta strona jest obecnie wyświetlana na pełnym ekranie i wyłączyła kursor myszy.</translation>
 <translation id="3414952576877147120">Rozmiar:</translation>
@@ -4509,7 +4509,7 @@
 <translation id="820791781874064845">Ta strona została zablokowana przez rozszerzenie.</translation>
 <translation id="2649120831653069427">Tęczanka</translation>
 <translation id="2781645665747935084">belgijska klawiatura</translation>
-<translation id="186612162884103683">„<ph name="EXTENSION"/>” może odczytywać oraz zapisywać pliki graficzne, wideo i dźwiękowe ze sprawdzonych lokalizacji.</translation>
+<translation id="186612162884103683">„<ph name="EXTENSION"/>” może odczytywać oraz zapisywać pliki graficzne, wideo i dźwiękowe z wybranych lokalizacji.</translation>
 <translation id="3021678814754966447">&amp;Wyświetl źródło ramki</translation>
 <translation id="8601206103050338563">Uwierzytelnianie klienta WWW TLS</translation>
 <translation id="1692799361700686467">Pliki cookie z wielu witryn są dozwolone.</translation>
diff --git a/chrome/app/resources/generated_resources_pt-BR.xtb b/chrome/app/resources/generated_resources_pt-BR.xtb
index 2db025d..7669bbb 100644
--- a/chrome/app/resources/generated_resources_pt-BR.xtb
+++ b/chrome/app/resources/generated_resources_pt-BR.xtb
@@ -1787,6 +1787,7 @@
 <translation id="7724603315864178912">Recortar</translation>
 <translation id="8456681095658380701">Nome inválido</translation>
 <translation id="3518086201899641494">Notificações sobre portais cativos</translation>
+<translation id="3652052123500137959">Ativar Pesquisa por voz no Acesso rápido aos apps.</translation>
 <translation id="1976150099241323601">Faça login no dispositivo seguro</translation>
 <translation id="4120817667028078560">Caminho muito longo</translation>
 <translation id="4938972461544498524">Configurações do touchpad</translation>
@@ -2882,6 +2883,7 @@
 <translation id="8443621894987748190">Escolher a foto para sua conta</translation>
 <translation id="7374461526650987610">Manipuladores de protocolo</translation>
 <translation id="2192505247865591433">De:</translation>
+<translation id="8668997025496699314">Ativa a Pesquisa por voz no Acesso rápido aos apps. Se ela for ativada, o usuário poderá fazer uma pesquisa por voz.</translation>
 <translation id="4634771451598206121">Fazer login novamente...</translation>
 <translation id="3475110616773907981">Acessar todos os dados de seu computador e dos sites que você visita</translation>
 <translation id="1035590878859356651">Adicionar esta página aos Favoritos...</translation>
@@ -3792,7 +3794,6 @@
 <translation id="3228279582454007836">É a primeira vez que você visita esse site.</translation>
 <translation id="7027125358315426638">Nome do banco de dados:</translation>
 <translation id="4030383055268325496">&amp;Desfazer adicionar</translation>
-<translation id="5474648613967354713">Desative pesquisa por voz no Acesso rápido aos apps.</translation>
 <translation id="5449716055534515760">Fechar jan&amp;ela</translation>
 <translation id="3224239078034945833">Canadense multilíngue</translation>
 <translation id="4875057836161716898">Ativar visualizações de entrada.</translation>
@@ -4277,7 +4278,6 @@
 <translation id="1812514023095547458">Selecionar cor</translation>
 <translation id="2487656424763972284">Desbloqueio facilitado</translation>
 <translation id="7047998246166230966">Ponteiro</translation>
-<translation id="743268637741709136">Desativa a pesquisa por voz no Acesso rápido aos apps. Se for desativada, não será possível realizar pesquisas por voz.</translation>
 <translation id="3252266817569339921">Francês</translation>
 <translation id="2665717534925640469">Esta página está em modo de tela inteira e desativou o cursor do mouse.</translation>
 <translation id="3414952576877147120">Tamanho:</translation>
diff --git a/chrome/app/resources/generated_resources_pt-PT.xtb b/chrome/app/resources/generated_resources_pt-PT.xtb
index c653d9e..df943e0 100644
--- a/chrome/app/resources/generated_resources_pt-PT.xtb
+++ b/chrome/app/resources/generated_resources_pt-PT.xtb
@@ -315,7 +315,7 @@
 <translation id="7393381084163773901">Morada</translation>
 <translation id="6980028882292583085">Alerta de JavaScript</translation>
 <translation id="577624874850706961">Pesquisar cookies</translation>
-<translation id="5494920125229734069">Seleccionar tudo</translation>
+<translation id="5494920125229734069">Selecionar tudo</translation>
 <translation id="2857834222104759979">O ficheiro de manifesto é inválido.</translation>
 <translation id="3868718841498638222">Mudou para o canal <ph name="CHANNEL_NAME"/>.</translation>
 <translation id="7931071620596053769">As páginas que se seguem deixaram de responder. Pode esperar pela respectiva resposta ou desactivá-las.</translation>
@@ -1797,6 +1797,7 @@
 <translation id="7724603315864178912">Cortar</translation>
 <translation id="8456681095658380701">Nome inválido</translation>
 <translation id="3518086201899641494">Notificações acerca de portais cativos</translation>
+<translation id="3652052123500137959">Ative a pesquisa por voz no Iniciador de Aplicações.</translation>
 <translation id="1976150099241323601">Iniciar sessão no Dispositivo de segurança</translation>
 <translation id="4120817667028078560">Caminho demasiado longo</translation>
 <translation id="4938972461544498524">Definições do touchpad</translation>
@@ -2893,6 +2894,7 @@
 <translation id="8443621894987748190">Escolha a fotografia da conta</translation>
 <translation id="7374461526650987610">Processadores de protocolos</translation>
 <translation id="2192505247865591433">De:</translation>
+<translation id="8668997025496699314">Ative a pesquisa por voz no Iniciador de Aplicações. Se esta opção estiver ativada, o utilizador poderá pesquisar oralmente.</translation>
 <translation id="4634771451598206121">Iniciar sessão novamente...</translation>
 <translation id="3475110616773907981">Aceder a todos os dados no seu computador e aos Websites que visitar</translation>
 <translation id="1035590878859356651">Adicionar esta página aos marcadores...</translation>
@@ -3802,7 +3804,6 @@
 <translation id="3228279582454007836">Nunca visitou este site antes do dia de hoje.</translation>
 <translation id="7027125358315426638">Nome da base de dados:</translation>
 <translation id="4030383055268325496">&amp;Anular adição</translation>
-<translation id="5474648613967354713">Desativar a pesquisa por voz no App Launcher.</translation>
 <translation id="5449716055534515760">Fechar &amp;Janela</translation>
 <translation id="3224239078034945833">Canadiano multilingue</translation>
 <translation id="4875057836161716898">Ativar vistas de introdução.</translation>
@@ -4287,7 +4288,6 @@
 <translation id="1812514023095547458">Selecionar a Cor</translation>
 <translation id="2487656424763972284">Desbloqueio fácil</translation>
 <translation id="7047998246166230966">Ponteiro</translation>
-<translation id="743268637741709136">Desativar a pesquisa por voz no App Launcher. Se estiver desativada, o utilizador não poderá pesquisar por voz.</translation>
 <translation id="3252266817569339921">Francês</translation>
 <translation id="2665717534925640469">Esta página está agora em ecrã inteiro e desativou o cursor do rato.</translation>
 <translation id="3414952576877147120">Tamanho:</translation>
@@ -4990,7 +4990,7 @@
 <translation id="6953771362519040711">Ativar esta opção fará com que RenderLayers, com uma transição na opacidade, na transformação ou na filtragem, tenha a sua própria camada composta.</translation>
 <translation id="5130080518784460891">Eten</translation>
 <translation id="1394853081832053657">Opções de reconhecimento de voz</translation>
-<translation id="5037676449506322593">Seleccionar tudo</translation>
+<translation id="5037676449506322593">Selecionar tudo</translation>
 <translation id="4124987746317609294">Intervalo de Tempo</translation>
 <translation id="1981905533439890161">Confirmar Nova Aplicação</translation>
 <translation id="7717014941119698257">A transferir: <ph name="STATUS"/></translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb
index 727c822..02cd1fd 100644
--- a/chrome/app/resources/generated_resources_ro.xtb
+++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -1798,6 +1798,7 @@
 <translation id="7724603315864178912">Decupați</translation>
 <translation id="8456681095658380701">Nume nevalid</translation>
 <translation id="3518086201899641494">Notificări despre portaluri captive</translation>
+<translation id="3652052123500137959">Activați căutarea vocală în Lansatorul de aplicații.</translation>
 <translation id="1976150099241323601">Conectați-vă la dispozitivul de securitate</translation>
 <translation id="4120817667028078560">Calea este prea lungă</translation>
 <translation id="4938972461544498524">Setări pentru touchpad</translation>
@@ -2907,6 +2908,7 @@
 <translation id="8443621894987748190">Alegeți fotografia pentru contul dvs.</translation>
 <translation id="7374461526650987610">Handlere pentru protocoale</translation>
 <translation id="2192505247865591433">Din:</translation>
+<translation id="8668997025496699314">Activează căutarea vocală în Lansatorul de aplicații. Dacă este activată, utilizatorii vor putea căuta vocal.</translation>
 <translation id="4634771451598206121">Conectați-vă din nou...</translation>
 <translation id="3475110616773907981">Accesează toate datele de pe computerul dvs. și de pe site-urile web pe care le vizitați</translation>
 <translation id="1035590878859356651">Marcați această pagină...</translation>
@@ -3817,7 +3819,6 @@
 <translation id="3228279582454007836">Nu ați accesat niciodată acest site până astăzi.</translation>
 <translation id="7027125358315426638">Nume bază de date:</translation>
 <translation id="4030383055268325496">&amp;Anulați adăugarea</translation>
-<translation id="5474648613967354713">Dezactivați căutarea vocală în Lansatorul de aplicații.</translation>
 <translation id="5449716055534515760">Închideți fe&amp;reastra</translation>
 <translation id="3224239078034945833">Canadiană multilingvă</translation>
 <translation id="4875057836161716898">Activați afișările pentru metoda de introducere a textului.</translation>
@@ -4303,7 +4304,6 @@
 <translation id="1812514023095547458">Selectați o culoare</translation>
 <translation id="2487656424763972284">Deblocare ușoară</translation>
 <translation id="7047998246166230966">Cursor</translation>
-<translation id="743268637741709136">Dezactivează căutarea vocală în Lansatorul de aplicații. Dacă este dezactivat, utilizatorii nu vor putea căuta vocal.</translation>
 <translation id="3252266817569339921">Franceză</translation>
 <translation id="2665717534925640469">Această pagină este acum pe ecran complet și a dezactivat cursorul mouse-ului.</translation>
 <translation id="3414952576877147120">Dimensiune:</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb
index 7fd2eda..2589092 100644
--- a/chrome/app/resources/generated_resources_ru.xtb
+++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -1788,6 +1788,7 @@
 <translation id="7724603315864178912">Вырезать</translation>
 <translation id="8456681095658380701">Недопустимое название</translation>
 <translation id="3518086201899641494">Уведомления об адаптивных порталах</translation>
+<translation id="3652052123500137959">Включить голосовой поиск в Панели приложений.</translation>
 <translation id="1976150099241323601">Вход в устройство безопасности</translation>
 <translation id="4120817667028078560">Слишком длинный путь</translation>
 <translation id="4938972461544498524">Настройки сенсорной панели</translation>
@@ -2881,6 +2882,7 @@
 <translation id="8443621894987748190">Выберите картинку аккаунта</translation>
 <translation id="7374461526650987610">Обработчики протоколов</translation>
 <translation id="2192505247865591433">Из:</translation>
+<translation id="8668997025496699314">Разрешает голосовой поиск в Панели приложений. Если этот параметр включен, пользователь может произносить поисковые запросы вслух.</translation>
 <translation id="4634771451598206121">Войти снова</translation>
 <translation id="3475110616773907981">Доступ ко всем данным на компьютере и посещенных веб-сайтах</translation>
 <translation id="1035590878859356651">Закладка для этой страницы...</translation>
@@ -3789,7 +3791,6 @@
 <translation id="3228279582454007836">Этот сайт не посещался до сегодняшнего дня.</translation>
 <translation id="7027125358315426638">Название базы данных:</translation>
 <translation id="4030383055268325496">&amp;Отменить добавление</translation>
-<translation id="5474648613967354713">Отключить голосовой поиск в Панели запуска приложений</translation>
 <translation id="5449716055534515760">Закрыть &amp;окно</translation>
 <translation id="3224239078034945833">Канадская (многоязычная)</translation>
 <translation id="4875057836161716898">Разрешить дополнительные методы ввода</translation>
@@ -4274,7 +4275,6 @@
 <translation id="1812514023095547458">Выберите цвет</translation>
 <translation id="2487656424763972284">Простая разблокировка</translation>
 <translation id="7047998246166230966">Указатель</translation>
-<translation id="743268637741709136">Отключить голосовой поиск в Панели запуска приложений. Пользователь не сможет вводить поисковые запросы, произнося их вслух.</translation>
 <translation id="3252266817569339921">Французская</translation>
 <translation id="2665717534925640469">Страница отображается в полноэкранном режиме и пытается скрыть указатель мыши.</translation>
 <translation id="3414952576877147120">Размер:</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb
index 70f6346..e8b46b5 100644
--- a/chrome/app/resources/generated_resources_sk.xtb
+++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -1799,6 +1799,7 @@
 <translation id="7724603315864178912">Vystrihnúť</translation>
 <translation id="8456681095658380701">Neplatný názov</translation>
 <translation id="3518086201899641494">Upozornenia na prihlasovacie portály</translation>
+<translation id="3652052123500137959">Povoliť hlasové vyhľadávanie v Spúšťači aplikácií.</translation>
 <translation id="1976150099241323601">Prihlásenie do zabezpečeného zariadenia</translation>
 <translation id="4120817667028078560">Cesta je príliš dlhá</translation>
 <translation id="4938972461544498524">Nastavenia touchpadu</translation>
@@ -2896,6 +2897,7 @@
 <translation id="8443621894987748190">Vyberte obrázok pre svoj účet</translation>
 <translation id="7374461526650987610">Obslužné nástroje protokolov</translation>
 <translation id="2192505247865591433">Od:</translation>
+<translation id="8668997025496699314">Povoliť hlasové vyhľadávanie v Spúšťači aplikácií. Ak je toto pravidlo povolené, používateľ bude môcť vyhľadávať hlasom.</translation>
 <translation id="4634771451598206121">Znova prihlásiť...</translation>
 <translation id="3475110616773907981">Pristupovať k všetkým údajom v počítači a navštíveným webovým stránkam</translation>
 <translation id="1035590878859356651">Vytvoriť záložku pre túto stránku...</translation>
@@ -3349,7 +3351,7 @@
 <translation id="580886651983547002">Aplikácii <ph name="PRODUCT_NAME"/>
         sa nepodarilo pripojiť k webovým stránkam.  Obyčajne to býva spôsobené problémami so sieťou,
         ale môže to byť aj výsledkom nesprávne nakonfigurovanej brány firewall alebo servera proxy.</translation>
-<translation id="4387554346626014084">Povoliť synchronizáciu Spúšťača aplikácií. Ak je k dispozícii funkcia zložiek, bude tiež povolená (platí pre všetky operačné systémy okrem OS X).</translation>
+<translation id="4387554346626014084">Povoliť synchronizáciu Spúšťača aplikácií. Ak je k dispozícii funkcia priečinkov, bude tiež povolená (platí pre všetky operačné systémy okrem OS X).</translation>
 <translation id="5445557969380904478">O rozpoznávaní hlasu</translation>
 <translation id="4104400246019119780">Ďakujeme!</translation>
 <translation id="3487007233252413104">anonymná funkcia</translation>
@@ -3808,7 +3810,6 @@
 <translation id="3228279582454007836">Túto stránku ste v minulosti nikdy nenavštívili.</translation>
 <translation id="7027125358315426638">Názov databázy:</translation>
 <translation id="4030383055268325496">&amp;Vrátiť späť pridanie</translation>
-<translation id="5474648613967354713">Zakázať hlasové vyhľadávanie v Spúšťači aplikácií.</translation>
 <translation id="5449716055534515760">Zavrieť o&amp;kno</translation>
 <translation id="3224239078034945833">Kanadská viacjazyčná klávesnica</translation>
 <translation id="4875057836161716898">Povoliť zobrazenie vstupu.</translation>
@@ -4295,7 +4296,6 @@
 <translation id="1812514023095547458">Vyberte farbu</translation>
 <translation id="2487656424763972284">Jednoduché odomknutie</translation>
 <translation id="7047998246166230966">Kurzor</translation>
-<translation id="743268637741709136">Zakázať hlasové vyhľadávanie v Spúšťači aplikácií. Ak je zakázané, používateľ nebude môcť vyhľadávať hlasom.</translation>
 <translation id="3252266817569339921">Francúzska klávesnica</translation>
 <translation id="2665717534925640469">Táto stránka je zobrazená na celú obrazovku a zakázala kurzor myši.</translation>
 <translation id="3414952576877147120">Veľkosť:</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb
index a769f95..a66457f 100644
--- a/chrome/app/resources/generated_resources_sl.xtb
+++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -1802,6 +1802,7 @@
 <translation id="7724603315864178912">Izreži</translation>
 <translation id="8456681095658380701">Neveljavno ime</translation>
 <translation id="3518086201899641494">Obvestila o portalih za preverjanje pristnosti</translation>
+<translation id="3652052123500137959">Omogočanje glasovnega iskanja v zaganjalniku aplikacij.</translation>
 <translation id="1976150099241323601">Prijava v varnostno napravo</translation>
 <translation id="4120817667028078560">Pot je predolga</translation>
 <translation id="4938972461544498524">Nastavitve sledilne ploščice</translation>
@@ -2907,6 +2908,7 @@
 <translation id="8443621894987748190">Izberite sliko za račun</translation>
 <translation id="7374461526650987610">Rutine za obravnavanje protokolov</translation>
 <translation id="2192505247865591433">Od:</translation>
+<translation id="8668997025496699314">Omogoči glasovno iskanje v zaganjalniku aplikacij. Če je omogočeno, lahko uporabnik išče z govorjenjem.</translation>
 <translation id="4634771451598206121">Prijavite se znova ...</translation>
 <translation id="3475110616773907981">Dostopajte do vseh podatkov v računalniku in na obiskanih spletnih mestih</translation>
 <translation id="1035590878859356651">Dodaj to stran med zaznamke ...</translation>
@@ -3361,7 +3363,7 @@
 <translation id="580886651983547002"><ph name="PRODUCT_NAME"/>
         ne more doseči spletnega mesta. To navadno povzročijo težave z omrežjem,
         lahko pa je tudi posledica napačno nastavljenega požarnega zidu ali proxyja.</translation>
-<translation id="4387554346626014084">Omogoči sinhronizacijo zaganjalnika aplikacij. S tem se omogočijo tudi Mape, kjer so na voljo (ne v sistemu OS X).</translation>
+<translation id="4387554346626014084">Omogoči sinhronizacijo zaganjalnika aplikacij. S tem se omogočijo tudi Mape, kadar so na voljo (ne v sistemu OS X).</translation>
 <translation id="5445557969380904478">O prepoznavanju govora</translation>
 <translation id="4104400246019119780">Hvala!</translation>
 <translation id="3487007233252413104">anonimna funkcija</translation>
@@ -3818,7 +3820,6 @@
 <translation id="3228279582454007836">Tega spletnega mesta pred današnjim dnem še nikoli niste obiskali.</translation>
 <translation id="7027125358315426638">Ime zbirke podatkov:</translation>
 <translation id="4030383055268325496">&amp;Razveljavi dodajanje</translation>
-<translation id="5474648613967354713">Onemogočanje glasovnega iskanja v zaganjalniku aplikacij.</translation>
 <translation id="5449716055534515760">Zapri &amp;okno</translation>
 <translation id="3224239078034945833">kanadščina (večjezična)</translation>
 <translation id="4875057836161716898">Omogoči vhodne poglede.</translation>
@@ -4304,7 +4305,6 @@
 <translation id="1812514023095547458">Izbira barve</translation>
 <translation id="2487656424763972284">Preprosto odklepanje</translation>
 <translation id="7047998246166230966">Kazalec</translation>
-<translation id="743268637741709136">Onemogoči glasovno iskanje v zaganjalniku aplikacij. Če je onemogočeno, uporabnik ne more iskati z izgovorjavo poizvedb.</translation>
 <translation id="3252266817569339921">francoščina</translation>
 <translation id="2665717534925640469">Ta stran je zdaj v celozaslonskem načinu in je onemogočila miškin kazalec.</translation>
 <translation id="3414952576877147120">Velikost:</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb
index d629c1e..ef31e44 100644
--- a/chrome/app/resources/generated_resources_sr.xtb
+++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -75,7 +75,7 @@
 <translation id="368260109873638734">Детаљи о проблемима на овом веб-сајту</translation>
 <translation id="7409233648990234464">Поново покрени и обави Powerwash</translation>
 <translation id="7428534988046001922">Управо су инсталиране следеће апликације:</translation>
-<translation id="787386463582943251">Додај адресу е-поште</translation>
+<translation id="787386463582943251">Додај имејл адресу</translation>
 <translation id="2833791489321462313">Захтевај лозинку при покретању из стања спавања</translation>
 <translation id="8208216423136871611">Не чувај</translation>
 <translation id="4405141258442788789">Временско ограничење операције је истекло.</translation>
@@ -162,7 +162,7 @@
 <translation id="620329680124578183">Не учитавај (препоручено)</translation>
 <translation id="6300924177400055566">Немате довољно простора на Google диску за чување датотеке „<ph name="FILE_NAME"/>“. Уклоните датотеке или <ph name="BEGIN_LINK"/>купите још складишног простора<ph name="END_LINK"/>.</translation>
 <translation id="9074739597929991885">Bluetooth</translation>
-<translation id="2653266418988778031">Уколико избришете сертификат ауторитета за издавање сертификата, прегледач више неће веровати сертификатима које је тај ауторитет издао.</translation>
+<translation id="2653266418988778031">Ако избришете сертификат ауторитета за издавање сертификата, прегледач више неће веровати сертификатима које је тај ауторитет издао.</translation>
 <translation id="583029793621630105">Алатка за растеризацију слике мапе (позната и као нулта копија)</translation>
 <translation id="4237357878101553356">Нисмо могли да верификујемо информације о налогу. |Реши овај проблем|</translation>
 <translation id="761324001449336633">Спакујте апликацију</translation>
@@ -202,7 +202,7 @@
 <translation id="551752069230578406">Додајемо штампач на налог – то ће можда мало да потраје...</translation>
 <translation id="2108058520826444209">Упозорење: Нисте повезани са серверима Новчаника за производњу. Издате картице ће бити неважеће.</translation>
 <translation id="4858913220355269194">Фриц</translation>
-<translation id="2231238007119540260">Уколико избришете серверски сертификат, враћате уобичајене безбедносне провере за тај сервер и захтевате да користи важећи сертификат.</translation>
+<translation id="2231238007119540260">Ако избришете серверски сертификат, враћате уобичајене безбедносне провере за тај сервер и захтевате да користи важећи сертификат.</translation>
 <translation id="6489433341782457580">За програмере: Користите услугу у заштићеном окружењу за позиве API-ја Новчаника за requestAutocomplete().</translation>
 <translation id="8186609076106987817">Сервер није могао да пронађе датотеку.</translation>
 <translation id="2846816712032308263">Омогућава брзо затварање картице/прозора – покреће js обрађивач onunload на картици независно од графичког корисничког интерфејса.</translation>
@@ -1060,7 +1060,7 @@
 <translation id="2441392884867482684">Ова страница је сада у режиму целог екрана и жели да онемогући курсор.</translation>
 <translation id="1049376040497900836">Догађаји током којих је верзија производа <ph name="SHORT_PRODUCT_NAME"/> промењена</translation>
 <translation id="1422780722984745882">Примљено је више различитих заглавља Location. То није дозвољено због заштите од напада цепањем HTTP одговора.</translation>
-<translation id="7787129790495067395">Тренутно користите приступну фразу. Уколико сте заборавили приступну фразу, можете да вратите синхронизацију на почетне вредности да бисте обрисали податке са Google-ових сервера помоћу Google контролне табле.</translation>
+<translation id="7787129790495067395">Тренутно користите приступну фразу. Ако сте заборавили приступну фразу, можете да вратите синхронизацију на почетне вредности да бисте обрисали податке са Google-ових сервера помоћу Google контролне табле.</translation>
 <translation id="2098305189700762159">Није пронађено</translation>
 <translation id="2521119273159503752">ИД евиденције</translation>
 <translation id="1273135602584709125">Откажи пријављивање за издање за предузећа</translation>
@@ -1512,7 +1512,7 @@
 <translation id="2149951639139208969">Отварање адресе у новој картици</translation>
 <translation id="8012382203418782830">Ова страница је преведена.</translation>
 <translation id="7256069811654036843">Врати ме назад!</translation>
-<translation id="4811502511369621968">Неважећа адреса е-поште. Проверите и покушајте поново.</translation>
+<translation id="4811502511369621968">Неважећа имејл адреса. Проверите и покушајте поново.</translation>
 <translation id="175196451752279553">П&amp;оново отвори затворену картицу</translation>
 <translation id="8602851771975208551">Други програм на рачунару је додао апликацију која може да промени начин на који Chrome функционише.</translation>
 <translation id="9154967591629748964">Максимални број плочица за област од интересовања</translation>
@@ -1611,7 +1611,7 @@
 <translation id="8121385576314601440">Подешавања Хангул метода уноса</translation>
 <translation id="2347476388323331511">Синхронизација није могућа</translation>
 <translation id="6986605181115043220">Упс, Синхронизација више не функционише. <ph name="BEGIN_LINK"/>Сазнајте више<ph name="END_LINK"/></translation>
-<translation id="8595751131238115030">Унесите адресу е-поште.</translation>
+<translation id="8595751131238115030">Унесите имејл адресу.</translation>
 <translation id="5379268888377976432">Опозови брисање</translation>
 <translation id="7416362041876611053">Непозната грешка на мрежи.</translation>
 <translation id="4250680216510889253">Не</translation>
@@ -1630,7 +1630,7 @@
 <translation id="5023943178135355362">Обрнуто померање <ph name="BEGIN_LINK"/>Сазнајте више<ph name="END_LINK"/></translation>
 <translation id="7378810950367401542">/</translation>
 <translation id="6426039856985689743">Онемогући податке за мобилне уређаје</translation>
-<translation id="539643935609409426">Да бисте сакрили приступ овом програму, потребно је да га деинсталирате помоћу аплета <ph name="CONTROL_PANEL_APPLET_NAME"/> на контролној табли.
+<translation id="539643935609409426">Да бисте сакрили приступ овом програму, треба да га деинсталирате помоћу аплета <ph name="CONTROL_PANEL_APPLET_NAME"/> на контролној табли.
 
 Желите ли да покренете <ph name="CONTROL_PANEL_APPLET_NAME"/>?</translation>
 <translation id="8571992327053899347">Корисник под надзором може да истражује веб уз вашу помоћ. Као менаџер корисника под надзором у Chrome-у, можете:
@@ -1800,6 +1800,7 @@
 <translation id="7724603315864178912">Исеци</translation>
 <translation id="8456681095658380701">Неважеће име</translation>
 <translation id="3518086201899641494">Обавештења о порталима за проверу</translation>
+<translation id="3652052123500137959">Омогући гласовну претрагу у Покретачу апликација.</translation>
 <translation id="1976150099241323601">Пријава на безбедносни уређај</translation>
 <translation id="4120817667028078560">Путања је предугачка</translation>
 <translation id="4938972461544498524">Подешавања тачпеда</translation>
@@ -1842,7 +1843,7 @@
 <translation id="7558050486864662801">Питај када сајт захтева приступ мом микрофону (препоручено)</translation>
 <translation id="8238649969398088015">Савет за помоћ</translation>
 <translation id="2350172092385603347">Коришћена је локализација, али параметар default_locale није наведен у манифесту.</translation>
-<translation id="8221729492052686226">Уколико нисте покренули овај захтев, могуће је да је он заправо покушај напада на систем. Ако нисте изричито покренули овај захтев, треба да кликнете на „Не ради ништа“.</translation>
+<translation id="8221729492052686226">Ако нисте покренули овај захтев, могуће је да је он заправо покушај напада на систем. Ако нисте изричито покренули овај захтев, треба да кликнете на „Не ради ништа“.</translation>
 <translation id="4956752588882954117">Страница je доступна за приказ.</translation>
 <translation id="1114202307280046356">Дијамант</translation>
 <translation id="4215350869199060536">Упс, имате недозвољене симболе у имену!</translation>
@@ -1898,7 +1899,7 @@
 <translation id="3254434849914415189">Изаберите подразумевану апликацију за датотеке <ph name="FILE_TYPE"/>:</translation>
 <translation id="4991420928586866460">Третирај тастере из горњег реда као функцијске тастере</translation>
 <translation id="4350019051035968019">Овај уређај не може да се региструје на домену коме припада ваш налог јер је означен као уређај којим управља други домен.</translation>
-<translation id="3699624789011381381">Адреса е-поште</translation>
+<translation id="3699624789011381381">Имејл адреса</translation>
 <translation id="5275799318132317934">У овом случају издавач је поништио сертификат представљен вашем прегледачу. То обично значи да је нарушен интегритет овог сертификата, као и да сертификат није поуздан.</translation>
 <translation id="7970236555047307207">Подударање домена са јавним суфиксима за аутоматско попуњавање лозинки.</translation>
 <translation id="7734269893462718857">Омогућено и постављено иза траке за локацију</translation>
@@ -1985,8 +1986,8 @@
 <translation id="8525306231823319788">Цео екран</translation>
 <translation id="5892507820957994680">Замењује листу за приказ уграђеног софтвера и омогућава GPU убрзање у неподржаним системским конфигурацијама.</translation>
 <translation id="255632937203580977">Обавештења о откривању уређаја</translation>
-<translation id="6122093587541546701">Адреса е-поште (опционално):</translation>
-<translation id="3058212636943679650">Уколико икада буде потребно да вратите оперативни систем рачунара биће вам потребна SD картица за обнављање или USB меморијски уређај.</translation>
+<translation id="6122093587541546701">Имејл адреса (опционално):</translation>
+<translation id="3058212636943679650">Ако икада буде потребно да вратите оперативни систем рачунара биће вам потребна SD картица за обнављање или USB меморијски уређај.</translation>
 <translation id="7238196028794870999">Настави дозвољавање додатних компоненти које су изван заштићеног окружења</translation>
 <translation id="7252661675567922360">Не учитавај</translation>
 <translation id="1983959805486816857">Када направите новог корисника под надзором, можете да управљате подешавањима у било ком тренутку са било ког уређаја на <ph name="MANAGEMENT_URL"/>.</translation>
@@ -2134,7 +2135,7 @@
 <translation id="1708338024780164500">(Неактивно)</translation>
 <translation id="6896758677409633944">Копирај</translation>
 <translation id="8986362086234534611">Заборави</translation>
-<translation id="5260508466980570042">Жао нам је, није било могуће верификовати адресу е-поште или лозинку. Покушајте поново.</translation>
+<translation id="5260508466980570042">Жао нам је, није било могуће верификовати имејл адресу или лозинку. Покушајте поново.</translation>
 <translation id="7887998671651498201">Следећа додатна компонента се не одазива: <ph name="PLUGIN_NAME"/>Желите ли да је зауставите?</translation>
 <translation id="4212108296677106246">Желите да верујете ауторитету „<ph name="CERTIFICATE_NAME"/>“ као ауторитету за издавање сертификата?</translation>
 <translation id="4320833726226688924">У овом случају, сертификат сервера или посредног овлашћеног издаваоца сертификата који се шаље у прегледач потписан је слабим алгоритмом, попут RSA-MD2. Недавна истраживања рачунарских стручњака показала су да је алгоритам потписа слабији него што се раније мислило па га у данашње време поуздани веб-сајтови ретко користе. Овај сертификат би могао да буде кривотворен.</translation>
@@ -2457,7 +2458,7 @@
 <translation id="2773223079752808209">Корисничка подршка</translation>
 <translation id="2143915448548023856">Подешавања екрана</translation>
 <translation id="1084824384139382525">Копирај адр&amp;есу везе</translation>
-<translation id="1221462285898798023">Покрените <ph name="PRODUCT_NAME"/> као нормални корисник. Да бисте га покренули као основни, потребно је да наведете алтернативни каталог корисничких података за чување информација о профилу.</translation>
+<translation id="1221462285898798023">Покрените <ph name="PRODUCT_NAME"/> као нормални корисник. Да бисте га покренули као основни, треба да наведете алтернативни каталог корисничких података за чување информација о профилу.</translation>
 <translation id="3220586366024592812">Процес конектора за <ph name="CLOUD_PRINT_NAME"/> је отказао. Желите ли поново да га покренете?</translation>
 <translation id="2379281330731083556">Штампај помоћу системског дијалога... <ph name="SHORTCUT_KEY"/></translation>
 <translation id="918765022965757994">Пријавите се на овај сајт помоћу адресе: <ph name="EMAIL_ADDRESS"/></translation>
@@ -2515,7 +2516,7 @@
 <translation id="2553340429761841190"><ph name="PRODUCT_NAME"/> није успео да се повеже са мрежом <ph name="NETWORK_ID"/>. Изаберите другу мрежу или покушајте поново.</translation>
 <translation id="2086712242472027775">Ваш налог не функционише на производу <ph name="PRODUCT_NAME"/>. Контактирајте администратора домена или се пријавите помоћу обичног Google налога.</translation>
 <translation id="1970103697564110434">Google новчаник штити картицу</translation>
-<translation id="7222232353993864120">Адреса е-поште</translation>
+<translation id="7222232353993864120">Имејл адреса</translation>
 <translation id="2128531968068887769">Native Client</translation>
 <translation id="7175353351958621980">Учитава се са:</translation>
 <translation id="7186367841673660872">Ова страница је преведена са језика:<ph name="ORIGINAL_LANGUAGE"/>на<ph name="LANGUAGE_LANGUAGE"/></translation>
@@ -2703,7 +2704,7 @@
         до ове грешке. Поновним учитавањем странице би требало да решите овај проблем, а
         исправним искључивањем прегледача би требало да га спречите у будућности.
         <ph name="LINE_BREAK"/>
-        Уколико се проблем и даље јавља, покушајте да обришете кеш. У неким случајевима, то
+        Ако се проблем и даље јавља, покушајте да обришете кеш. У неким случајевима, то
         може да буде и симптом скорог отказивања хардвера.</translation>
 <translation id="5154176924561037127">F8</translation>
 <translation id="5298219193514155779">Тему је направио/ла</translation>
@@ -2867,7 +2868,7 @@
 <translation id="3202578601642193415">Најновије</translation>
 <translation id="1398853756734560583">Увећај</translation>
 <translation id="1829129547161959350">Пингвин</translation>
-<translation id="8988255471271407508">Веб-страница није пронађена у кешу. Извесни ресурси, као што су странице генерисане из послатих података, могу безбедно да се учитају само из кеша. <ph name="LINE_BREAK"/> Узрок ове грешке такође може да буде оштећење кеша због неправилног искључивања. <ph name="LINE_BREAK"/> Уколико се проблем настави, покушајте да обришете кеш.</translation>
+<translation id="8988255471271407508">Веб-страница није пронађена у кешу. Извесни ресурси, као што су странице генерисане из послатих података, могу безбедно да се учитају само из кеша. <ph name="LINE_BREAK"/> Узрок ове грешке такође може да буде оштећење кеша због неправилног искључивања. <ph name="LINE_BREAK"/> Ако се проблем настави, покушајте да обришете кеш.</translation>
 <translation id="1653828314016431939">У реду – Поново покрени одмах</translation>
 <translation id="7364796246159120393">Одабери датотеку</translation>
 <translation id="6585283250473596934">Улазите у јавну сесију.</translation>
@@ -2905,6 +2906,7 @@
 <translation id="8443621894987748190">Изаберите слику за налог</translation>
 <translation id="7374461526650987610">Обрађивачи протокола</translation>
 <translation id="2192505247865591433">Од:</translation>
+<translation id="8668997025496699314">Омогућите гласовну претрагу у Покретачу апликација. Ако је омогућена, корисник ће моћи да претражује помоћу говора.</translation>
 <translation id="4634771451598206121">Пријави ме поново...</translation>
 <translation id="3475110616773907981">Приступ свим подацима на рачунару и веб сајтовима које посећујете</translation>
 <translation id="1035590878859356651">Обележи ову страницу...</translation>
@@ -2923,7 +2925,7 @@
 <translation id="6192792657125177640">Изузеци</translation>
 <translation id="5622158329259661758">Онемогућава коришћење GPU-а за приказивање 2D платна и уместо тога користи приказивање софтвера.</translation>
 <translation id="8670869118777164560">Овај додатак није успео да преусмери захтев мреже на <ph name="ATTEMPTED_REDIRECT_DESTINATION"/> пошто га је други додатак (<ph name="EXTENSION_NAME"/>) преусмерио на <ph name="ACTUAL_REDIRECT_DESTINATION"/>.</translation>
-<translation id="3654092442379740616">Грешка при синхронизацији: Производ <ph name="PRODUCT_NAME"/> је застарео и потребно је да га ажурирате.</translation>
+<translation id="3654092442379740616">Грешка при синхронизацији: Производ <ph name="PRODUCT_NAME"/> је застарео и треба да га ажурирате.</translation>
 <translation id="790040513076446191">Управљање подешавањима у вези са приватношћу</translation>
 <translation id="7260002739296185724">Омогућите коришћење AVFoundation-а за снимање видео снимака и надгледање видео уређаја на OS X &gt;= 10.7. У супротном користиће се QTKit.</translation>
 <translation id="1463985642028688653">блокирај</translation>
@@ -3089,7 +3091,7 @@
 <translation id="4788968718241181184">Вијетнамски метод уноса (TCVN6064)</translation>
 <translation id="3254409185687681395">Обележите ову страницу</translation>
 <translation id="5694501201003948907">Додавање ставки ($1) у zip датотеку...</translation>
-<translation id="8710160868773349942">Адреса е-поште: <ph name="EMAIL_ADDRESSES"/></translation>
+<translation id="8710160868773349942">Имејл адреса: <ph name="EMAIL_ADDRESSES"/></translation>
 <translation id="2677924368525077324">Омогући измену текста засновану на додиру</translation>
 <translation id="6081343346992541240">Омогући да се приказивачу не шаљу догађаји са додиром током померања</translation>
 <translation id="4057991113334098539">Активирање...</translation>
@@ -3188,7 +3190,7 @@
 <translation id="1408789165795197664">Напредне опције</translation>
 <translation id="1650709179466243265">Додавање www. и .com и отварање адресе</translation>
 <translation id="3700834376805760154">Идентитет организације <ph name="ORGANIZATION"/> у месту <ph name="LOCALITY"/> је верификовао/ла <ph name="ISSUER"/> и он може јавно да се провери.</translation>
-<translation id="436701661737309601">Издавач сертификата који није истекао одговоран је за одржавање нечега што се зове „листа опозива“. Ако сертификат буде у било ком тренутку компромитован, издавач може да га опозове ако га дода на листу опозива и тај сертификат више неће бити поуздан за прегледач. Одржавање статуса опозива се не захтева за истекле сертификате, тако да, иако је овај сертификат некада био важећи за веб сајт који посећујете, у овом тренутку није могуће одредити да ли је сертификат компромитован и због тога опозван, или остаје безбедан. Зато је немогуће рећи да ли комуницирате са легитимним веб сајтом или је сертификат компромитован и сада га поседује нападач са којим комуницирате.</translation>
+<translation id="436701661737309601">Издавач сертификата који није истекао одговоран је за одржавање нечега што се зове „листа опозива“. Ако сертификат буде у било ком тренутку компромитован, издавач може да га опозове ако га дода на листу опозива и тај сертификат више неће бити поуздан за прегледач. Одржавање статуса опозива се не захтева за истекле сертификате, па, иако је овај сертификат некада био важећи за веб сајт који посећујете, у овом тренутку није могуће одредити да ли је сертификат компромитован и због тога опозван, или остаје безбедан. Зато је немогуће рећи да ли комуницирате са легитимним веб сајтом или је сертификат компромитован и сада га поседује нападач са којим комуницирате.</translation>
 <translation id="4342311272543222243">Упс, грешка у вези са модулом поуздане платформе.</translation>
 <translation id="3727884750434605207">Омогућите уметање скрипти уместо основне Android приступачности.</translation>
 <translation id="1285484354230578868">Складиштите податке на налогу Google диска</translation>
@@ -3814,7 +3816,6 @@
 <translation id="3228279582454007836">Пре данашњег дана нисте посећивали овај сајт.</translation>
 <translation id="7027125358315426638">Назив базе података:</translation>
 <translation id="4030383055268325496">&amp;Опозови додавање</translation>
-<translation id="5474648613967354713">Онемогући гласовну претрагу у Покретачу апликација.</translation>
 <translation id="5449716055534515760">Close Win&amp;dow (Затвори прозор)</translation>
 <translation id="3224239078034945833">канадска вишејезична</translation>
 <translation id="4875057836161716898">Омогући прегледе уноса.</translation>
@@ -3860,7 +3861,7 @@
 <translation id="3140978158653201367">Потврда нове теме</translation>
 <translation id="8439506636278576865">Понуди превод страница на овом језику</translation>
 <translation id="5189060859917252173">Сертификат „<ph name="CERTIFICATE_NAME"/>“ представља ауторитет за издавање сертификата.</translation>
-<translation id="3785852283863272759">Пошаљи поруку е-поште са локацијом странице</translation>
+<translation id="3785852283863272759">Пошаљи имејл са локацијом странице</translation>
 <translation id="2255317897038918278">Microsoft означавање времена</translation>
 <translation id="3493881266323043047">Валидност</translation>
 <translation id="8380575322267254990"><ph name="BEGIN_BOLD"/>Прегледате као гост<ph name="END_BOLD"/>. Странице које видите у овом прозору се неће појављивати у историји прегледача и неће остављати друге трагове, попут колачића, на рачунару после одјављивања. Датотеке које преузмете и обележивачи које направите неће бити сачувани.
@@ -3909,7 +3910,7 @@
 <translation id="5765780083710877561">Опис:</translation>
 <translation id="1740044382983372319">Додатак је инсталиран</translation>
 <translation id="338583716107319301">Разделник</translation>
-<translation id="2079053412993822885">Уколико избришете неки свој сертификат, више нећете моћи да га користите да се идентификујете.</translation>
+<translation id="2079053412993822885">Ако избришете неки свој сертификат, више нећете моћи да га користите да се идентификујете.</translation>
 <translation id="7221869452894271364">Поново учитајте ову страницу</translation>
 <translation id="8446884382197647889">Сазнајте више</translation>
 <translation id="4366837566726634418">Комбинована искоришћеност дељене меморије за све процесе у вези са производом <ph name="SHORT_PRODUCT_NAME"/></translation>
@@ -3953,7 +3954,7 @@
 <translation id="5699533844376998780">Додатак „<ph name="EXTENSION_NAME"/>“ је додат.
 </translation>
 <translation id="4522331920508731608">Управљај галеријама</translation>
-<translation id="1430915738399379752">Штампање</translation>
+<translation id="1430915738399379752">Штампај</translation>
 <translation id="7999087758969799248">Стандардни метод уноса</translation>
 <translation id="8958084571232797708">Користи URL за аутоматску конфигурацију</translation>
 <translation id="2635276683026132559">Потписивање</translation>
@@ -4093,7 +4094,7 @@
 <translation id="8260864402787962391">Миш</translation>
 <translation id="1775135663370355363">Приказујемо историју са овог уређаја. <ph name="BEGIN_LINK"/>Сазнајте више<ph name="END_LINK"/></translation>
 <translation id="8276560076771292512">Испразни кеш и поново учитај са сервера</translation>
-<translation id="9076523132036239772">Жао нам је, није било могуће верификовати адресу е-поште или лозинку. Прво покушајте да се повежете са мрежом.</translation>
+<translation id="9076523132036239772">Жао нам је, није било могуће верификовати имејл адресу или лозинку. Прво покушајте да се повежете са мрежом.</translation>
 <translation id="6965978654500191972">Уређај</translation>
 <translation id="1479356886123917758">Приступ сликама, музици и другим медијима са рачунара и мењање тих медија.</translation>
 <translation id="5295309862264981122">Потврда навигације</translation>
@@ -4302,11 +4303,10 @@
 <translation id="1812514023095547458">Избор боја</translation>
 <translation id="2487656424763972284">Једноставно откључавање</translation>
 <translation id="7047998246166230966">Показивач</translation>
-<translation id="743268637741709136">Онемогућите гласовну претрагу у Покретачу апликација. Ако је онемогућите, корисник неће моћи да претражује помоћу говора.</translation>
 <translation id="3252266817569339921">француска</translation>
 <translation id="2665717534925640469">Ова страница је сада у режиму целог екрана и онемогућила је курсор.</translation>
 <translation id="3414952576877147120">Величина:</translation>
-<translation id="7009102566764819240">У наставку је наведена листа свих елемената странице који нису безбедни. Кликните на везу „Дијагностика“ да бисте добили више информација о малверу у оквиру одређеног извора. Уколико знате да је неки извор погрешно пријављен као извор који се бави „пецањем“, кликните на везу „Пријави грешку“.</translation>
+<translation id="7009102566764819240">У наставку је наведена листа свих елемената странице који нису безбедни. Кликните на везу „Дијагностика“ да бисте добили више информација о малверу у оквиру одређеног извора. Ако знате да је неки извор погрешно пријављен као извор који се бави „пецањем“, кликните на везу „Пријави грешку“.</translation>
 <translation id="3592260987370335752">&amp;Сазнајте више</translation>
 <translation id="4923417429809017348">Ова страница је преведена са непознатог језика на <ph name="LANGUAGE_LANGUAGE"/></translation>
 <translation id="3631337165634322335">Доленаведени изузеци примењују се само на тренутну сесију без архивирања.</translation>
@@ -4320,7 +4320,7 @@
 <translation id="7763146744708046348">Не обједињуј податке – ово може да буде споро!</translation>
 <translation id="5626134646977739690">Име:</translation>
 <translation id="4899837262951879307">Режим померања помоћу додира.</translation>
-<translation id="5854409662653665676">Уколико често имате проблеме, можете да пробате следеће да бисте решили проблем са овим модулом:</translation>
+<translation id="5854409662653665676">Ако често имате проблеме, можете да пробате следеће да бисте решили проблем са овим модулом:</translation>
 <translation id="3776796446459804932">Овај додатак крши смернице Chrome веб-продавнице.</translation>
 <translation id="3681007416295224113">Информације о сертификату</translation>
 <translation id="3046084099139788433">Активирање картице 7</translation>
@@ -4418,7 +4418,7 @@
 <translation id="5116628073786783676">Са&amp;чувај аудио снимак као...</translation>
 <translation id="6172346010137455972">Спремни сте.</translation>
 <translation id="2539507112146602356">Алтернативни стил дугмета за титлове у кадру</translation>
-<translation id="9166510596677678112">Пошаљите поруку е-поште овој особи</translation>
+<translation id="9166510596677678112">Пошаљите имејл овој особи</translation>
 <translation id="2557899542277210112">Ради брзог приступа, поставите обележиваче овде на траку са обележивачима.</translation>
 <translation id="2749881179542288782">Провери граматику и правопис</translation>
 <translation id="5105855035535475848">Закачи картице</translation>
@@ -5285,7 +5285,7 @@
 <translation id="8914326144705007149">Веома велика</translation>
 <translation id="5154702632169343078">Субјекат</translation>
 <translation id="2817861546829549432">Ако омогућите „Не прати“, то значи да ће захтев бити послат са саобраћајем прегледања. Било какав утицај зависи од тога да ли ће веб-сајт одговорити на захтев, као и како се захтев тумачи. На пример, неки веб-сајтови могу да одговарају на овај захтев тако што ће вам приказивати огласе који нису засновани на другим веб-сајтовима које сте посетили. Многи веб-сајтови ће и даље прикупљати и користити податке прегледања – на пример, да би побољшали безбедност и пружали садржај, услуге, огласе и препоруке, као и за генерисање статистике извештавања.</translation>
-<translation id="5228076606934445476">Нешто није у реду са уређајем. Да бисте исправили ову грешку, потребно је да поново покренете уређај и покушате поново.</translation>
+<translation id="5228076606934445476">Нешто није у реду са уређајем. Да бисте исправили ову грешку, треба да поново покренете уређај и покушате поново.</translation>
 <translation id="2273562597641264981">Оператер:</translation>
 <translation id="122082903575839559">Алгоритам потписа сертификата</translation>
 <translation id="9013587737291179248">Упс! Није могуће увести корисника под надзором. Проверите простор на хард-диску и дозволе и покушајте поново.</translation>
diff --git a/chrome/app/resources/generated_resources_sv.xtb b/chrome/app/resources/generated_resources_sv.xtb
index 33d72c3..33b8572 100644
--- a/chrome/app/resources/generated_resources_sv.xtb
+++ b/chrome/app/resources/generated_resources_sv.xtb
@@ -1805,6 +1805,7 @@
 <translation id="7724603315864178912">Klipp ut</translation>
 <translation id="8456681095658380701">Ogiltigt namn</translation>
 <translation id="3518086201899641494">Meddelanden om infångstportaler</translation>
+<translation id="3652052123500137959">Aktivera röstsökning i startprogrammet för appar.</translation>
 <translation id="1976150099241323601">Logga in på säkerhetsenhet</translation>
 <translation id="4120817667028078560">Sökvägen är för lång</translation>
 <translation id="4938972461544498524">Inställningar för styrplatta</translation>
@@ -2167,7 +2168,7 @@
 <translation id="2767649238005085901">Tryck på Retur om du vill gå framåt och på snabbmenyn om du vill visa historiken</translation>
 <translation id="8580634710208701824">Hämta ram igen</translation>
 <translation id="7606992457248886637">Auktoriteter</translation>
-<translation id="4197674956721858839">Val för zip-fil</translation>
+<translation id="4197674956721858839">Zippa markerade filer</translation>
 <translation id="707392107419594760">Välj tangentbord:</translation>
 <translation id="8605503133013456784">Det gick inte att koppla från och ta bort parkopplingen för <ph name="DEVICE_NAME"/>.</translation>
 <translation id="2007404777272201486">Rapportera ett problem...</translation>
@@ -2903,6 +2904,7 @@
 <translation id="8443621894987748190">Välj bild till ditt konto</translation>
 <translation id="7374461526650987610">Protokollhanterare</translation>
 <translation id="2192505247865591433">Från:</translation>
+<translation id="8668997025496699314">Aktivera röstsökning i startprogrammet för appar. Om röstsökning har aktiverats kan användaren tala in sin sökning.</translation>
 <translation id="4634771451598206121">Logga in igen ...</translation>
 <translation id="3475110616773907981">Få åtkomst till alla data på datorn och de webbplatser du besöker</translation>
 <translation id="1035590878859356651">Lägg till ett bokmärke för denna sida …</translation>
@@ -3815,7 +3817,6 @@
 <translation id="3228279582454007836">Du har aldrig besökt den här webbplatsen tidigare.</translation>
 <translation id="7027125358315426638">Databasnamn:</translation>
 <translation id="4030383055268325496">&amp;Ångra Lägg till</translation>
-<translation id="5474648613967354713">Inaktivera röstsökning i startprogrammet för appar.</translation>
 <translation id="5449716055534515760">Stäng fön&amp;ster</translation>
 <translation id="3224239078034945833">Kanadensiska (flerspråkig)</translation>
 <translation id="4875057836161716898">Aktivera inmatningsvyer.</translation>
@@ -4303,7 +4304,6 @@
 <translation id="1812514023095547458">Välj färg</translation>
 <translation id="2487656424763972284">Enkel upplåsning</translation>
 <translation id="7047998246166230966">Pekare</translation>
-<translation id="743268637741709136">Inaktivera röstsökning i startprogrammet för appar. När detta alternativ är inaktiverat kan användaren inte söka med hjälp av rösten.</translation>
 <translation id="3252266817569339921">Franska</translation>
 <translation id="2665717534925640469">Sidan visas nu i helskärm och har inaktiverat muspekaren.</translation>
 <translation id="3414952576877147120">Storlek:</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb
index 8370a66..49f5d5c 100644
--- a/chrome/app/resources/generated_resources_sw.xtb
+++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -95,7 +95,7 @@
 <translation id="7392118418926456391">Utambazaji wa Virusi Umeshindwa</translation>
 <translation id="1156689104822061371">Mpangilio wa kibodi:</translation>
 <translation id="4764776831041365478">Ukurasa wa wavuti ulio <ph name="URL"/> unaweza kuwa haupatikani kwa muda au unaweza kuwa umehamishwa kabisa hadi anwani mpya ya wavuti.</translation>
-<translation id="6156863943908443225">Kache ya hati</translation>
+<translation id="6156863943908443225">Akiba ya hati</translation>
 <translation id="4274187853770964845">Hitilafu ya Usawazishaji: Tafadhali simamisha na uanzishe upya Usawazishaji.</translation>
 <translation id="3045873480188610022">Kichupo Kipya - Kilichotembelewa Zaidi</translation>
 <translation id="6499114579475440437">Ingia katika akaunti ulipe kwa kutumia Google Wallet</translation>
@@ -478,7 +478,7 @@
 <translation id="2452539774207938933">Badili hadi kwa mtumiaji: <ph name="PROFILE_NAME"/></translation>
 <translation id="4700157086864140907">Google Chrome inaweza kutoa ukaguzi bora wa tahajia kwa kutuma unachocharaza katika kivinjari hadi kwenye seva ya Google, ikikuruhusu kutumia teknolojia hiyo hiyo ya kukagua tahajia inayotumiwa na utafutaji wa Google.</translation>
 <translation id="1880905663253319515">Futa cheti &quot;<ph name="CERTIFICATE_NAME"/>&quot;?</translation>
-<translation id="8546306075665861288">Kache ya picha</translation>
+<translation id="8546306075665861288">Akiba ya picha</translation>
 <translation id="5904093760909470684">Usanidi wa Proksi</translation>
 <translation id="5706551819490830015">Dhibiti anwani za utozaji...</translation>
 <translation id="3348643303702027858">Uundaji wa Media Fufuzi ya OS umeghairiwa.</translation>
@@ -1129,7 +1129,7 @@
 <translation id="8165208966034452696"><ph name="PLUGIN_NAME"/></translation>
 <translation id="4933484234309072027">chopeka kwenye <ph name="URL"/></translation>
 <translation id="5554720593229208774">Mamlaka ya Uthibitishaji wa Barua pepe</translation>
-<translation id="862750493060684461">Kache ya CSS</translation>
+<translation id="862750493060684461">Akiba ya CSS</translation>
 <translation id="8169977663846153645">Betri
 Inakokotoa muda unaosalia</translation>
 <translation id="7690853182226561458">Ongeza &amp;folda...</translation>
@@ -1144,7 +1144,7 @@
 <translation id="5301751748813680278">Unaingia kama Mgeni.</translation>
 <translation id="121827551500866099">Onyesha vipakuliwa vyote...</translation>
 <translation id="5949910269212525572">Haiwezi kutatua anwani DNS ya seva.</translation>
-<translation id="3115147772012638511">Inasubiri kache...</translation>
+<translation id="3115147772012638511">Inasubiri akiba...</translation>
 <translation id="257088987046510401">Mandhari</translation>
 <translation id="6771079623344431310">Haikuwezai kuunganisha kwenye seva mbadala</translation>
 <translation id="7740996059027112821">Wastani</translation>
@@ -1714,7 +1714,7 @@
 <translation id="8425755597197517046">&amp;Bandika na Utafute</translation>
 <translation id="6341850831632289108">Kifaa kitambue haswa ulipo</translation>
 <translation id="1093148655619282731">Maelezo ya cheti kilichoteuliwa</translation>
-<translation id="3003623123441819449">Kache ya CSS</translation>
+<translation id="3003623123441819449">Akiba ya CSS</translation>
 <translation id="7784067724422331729">Mipangilio ya usalama kwenye kompyuta yako imezuia faili hii.</translation>
 <translation id="3822265067668554284">Usiruhusu tovuti yoyote ifuatilie mahali halisi ulipo</translation>
 <translation id="2758939858455657368">Arifa, madirisha na mazungumzo ya baadaye yatagawanywa baina ya maeneo-kazi.</translation>
@@ -1799,6 +1799,7 @@
 <translation id="7724603315864178912">Kata</translation>
 <translation id="8456681095658380701">Jina batili</translation>
 <translation id="3518086201899641494">Arifa kuhusu tovuti za uthibitishaji</translation>
+<translation id="3652052123500137959">Washa kutafuta kwa kutamka katika Kifungua Programu.</translation>
 <translation id="1976150099241323601">Ingia kwenye Kifaa Salama</translation>
 <translation id="4120817667028078560">Kijia ni kirefu mno</translation>
 <translation id="4938972461544498524">Mipangilio ya padimguso</translation>
@@ -2528,7 +2529,7 @@
 <translation id="1529968269513889022">wiki iliyopita</translation>
 <translation id="5542132724887566711">Wasifu</translation>
 <translation id="7912145082919339430">Wakati <ph name="PLUGIN_NAME"/> imekamilisha kusakinisha, pakia upya ukurasa ili kuiamilisha.</translation>
-<translation id="5196117515621749903">Pakia upya kache ya kupuuza</translation>
+<translation id="5196117515621749903">Pakia upya huku ukipuuza akiba</translation>
 <translation id="5552632479093547648">Programu hasidi na hadaa zimetambuliwa!</translation>
 <translation id="2527591341887670429">Inatumia betri: <ph name="PRECENTAGE"/>%</translation>
 <translation id="2435248616906486374">Mtandao Umekatizwa</translation>
@@ -2690,9 +2691,9 @@
         <ph name="PRODUCT_NAME"/>
         inahifadhi kwa muda faili zilizopakuliwa kwenye diski. Wakati
         <ph name="PRODUCT_NAME"/>
-        haijafungwa vizuri, faili hizi zinaweza kuharibika, na kuleta hitilafu hii. Kupakia ukurasa upya kunapaswa kutatua suala hili, na kufunga vizuri kunapaswa kuizuia kufanyika tena katika siku zijazo.
+        haijafungwa vizuri, faili hizi zinaweza kuharibika na kuleta hitilafu hii. Kupakia ukurasa upya kunapaswa kutatua suala hili, na kufunga vizuri kunapaswa kuizuia hitilafu hii kutokea tena katika siku zijazo.
         <ph name="LINE_BREAK"/>
-        ikiwa tatizo litaendelea, jaribu kufuta kache. Katika hali nyingine, hii inaweza kuwa pia dalili ya maunzi kuanza kushindwa.</translation>
+        ikiwa tatizo litaendelea, jaribu kufuta yaliyo kwenye akiba. Katika hali nyingine, hii pia inaweza kuwa dalili ya maunzi kuanza kushindwa kufanya kazi.</translation>
 <translation id="5154176924561037127">F8</translation>
 <translation id="5298219193514155779">Mandhari imeunda na</translation>
 <translation id="6307722552931206656">Seva za majina za Google - <ph name="BEGIN_LINK"/>Pata maelezo zaidi<ph name="END_LINK"/></translation>
@@ -2897,6 +2898,7 @@
 <translation id="8443621894987748190">Chagua picha ya akaunti yako</translation>
 <translation id="7374461526650987610">Vishikizi vya itifaki</translation>
 <translation id="2192505247865591433">Kutoka:</translation>
+<translation id="8668997025496699314">Washa kutafuta kwa kutamka katika Kifungua Programu. Ikiwashwa, mtumiaji ataweza kutafuta kwa matamshi.</translation>
 <translation id="4634771451598206121">Ingia tena...</translation>
 <translation id="3475110616773907981">Fikia data yote kwenye kompyuta yako na tovuti utakazotembelea</translation>
 <translation id="1035590878859356651">Alamisha ukurasa huu...</translation>
@@ -3639,7 +3641,7 @@
 <translation id="2028531481946156667">Haingeweza kuanzisha mchakato wa uumbizaji.</translation>
 <translation id="7439964298085099379">Modi ya Mlinganuo wa Juu imewezeshwa. Je, ungependa kusakinisha kiendelezi chetu cha Mlinganuo wa Juu na mandhari yenye weusi?</translation>
 <translation id="9012607008263791152">Naelewa kuwa kutembelea tovuti hii kunaweza kudhuru kompyuta yako.</translation>
-<translation id="6640442327198413730">Kache inakosekana</translation>
+<translation id="6640442327198413730">Haipo kwenye Akiba</translation>
 <translation id="3788401245189148511">Ingeweza:</translation>
 <translation id="8926518602592448999">Zima Viendelezi vya Hali ya Msanidi Programu</translation>
 <translation id="2902734494705624966">Kimarekani kilichopanuliwa</translation>
@@ -3802,7 +3804,6 @@
 <translation id="3228279582454007836">Hujawahi kuutembelea tovuti hii kufikia leo.</translation>
 <translation id="7027125358315426638">Jina la hifadhidata:</translation>
 <translation id="4030383055268325496">Tendua kuongeza</translation>
-<translation id="5474648613967354713">Zima kutafuta kwa kutamka katika Kizindua Programu.</translation>
 <translation id="5449716055534515760">Funga Dirisha</translation>
 <translation id="3224239078034945833">Lugha nyingi za Kanada</translation>
 <translation id="4875057836161716898">Washa mwonekano wa zana za kuingiza data.</translation>
@@ -4291,7 +4292,6 @@
 <translation id="1812514023095547458">Chagua Rangi</translation>
 <translation id="2487656424763972284">Kufungua kwa Urahisi</translation>
 <translation id="7047998246166230966">Kionyeshi</translation>
-<translation id="743268637741709136">Zima kutafuta kwa kutamka katika Kifungua Programu. Ikizimwa, mtumiaji hataweza kutafuta kwa kutamka.</translation>
 <translation id="3252266817569339921">Kifaransa</translation>
 <translation id="2665717534925640469">Ukurasa huu sasa uko kwenye skrini nzima na umelemaza kishale cha kipanya chako.</translation>
 <translation id="3414952576877147120">Ukubwa:</translation>
@@ -4684,7 +4684,7 @@
 <translation id="2986010903908656993">Ukurasa huu umezuiwa usiwe na udhibiti kamili wa vifaa vya MIDI.</translation>
 <translation id="8323167517179506834">Charaza URL</translation>
 <translation id="4264549073314009907">Zuia utauazi unaozingatia Mteja Asili GDB kwa ruwaza</translation>
-<translation id="4786993863723020412">Hitilafu ya kusoma kache</translation>
+<translation id="4786993863723020412">Hitilafu ya kusoma akiba</translation>
 <translation id="6630452975878488444">Njia mkato ya uteuzi</translation>
 <translation id="2934522647674136521">Tumia GPU kufanya maudhui ya wavuti kuwa rasta. Inahitaji uchoraji wa upande wa impl.</translation>
 <translation id="8709969075297564489">Chunguza ubatilishwaji wa cheti cha seva...</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb
index 051537b..52bc478 100644
--- a/chrome/app/resources/generated_resources_ta.xtb
+++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -1790,6 +1790,7 @@
 <translation id="7724603315864178912">வெட்டு</translation>
 <translation id="8456681095658380701">தவறான பெயர்</translation>
 <translation id="3518086201899641494">கேப்டிவ் போர்ட்டல்கள் குறித்த அறிவிப்புகள்</translation>
+<translation id="3652052123500137959">பயன்பாட்டுத் துவக்கியில் குரல் தேடலை இயக்கு.</translation>
 <translation id="1976150099241323601">பாதுகாப்பு சாதனத்தில் உள்நுழைக</translation>
 <translation id="4120817667028078560">பாதை மிக நீளம்</translation>
 <translation id="4938972461544498524">டச்பேட் அமைப்புகள்</translation>
@@ -2886,6 +2887,7 @@
 <translation id="8443621894987748190">உங்கள் கணக்கு படத்தைத் தேர்வு செய்க</translation>
 <translation id="7374461526650987610">நெறிமுறை ஹேண்ட்லர்கள்</translation>
 <translation id="2192505247865591433">அனுப்புநர்:</translation>
+<translation id="8668997025496699314">பயன்பாட்டுத்  துவக்கியில் குரல் தேடலை இயக்கவும். இயக்கியிருந்தால், பேசுவதன் மூலம் பயனர் தேடலாம்.</translation>
 <translation id="4634771451598206121">மீண்டும் உள்நுழைக...</translation>
 <translation id="3475110616773907981">உங்கள் கணினி மற்றும் நீங்கள் பார்வையிடும் வலைத்தளங்களில் எல்லாத் தரவையும் அணுகலாம்</translation>
 <translation id="1035590878859356651">இந்தப் பக்கத்தை புக்மார்க் செய்...</translation>
@@ -3790,7 +3792,6 @@
 <translation id="3228279582454007836">இதற்கு முன்னர் இந்த தளத்தை நீங்கள் பார்வையிட்டதில்லை.</translation>
 <translation id="7027125358315426638">தரவுத்தளப் பெயர்:</translation>
 <translation id="4030383055268325496">&amp;சேர்த்தலைச் செயல்தவிர்</translation>
-<translation id="5474648613967354713">பயன்பாட்டுத் துவக்கியில் குரல் தேடலை முடக்கு.</translation>
 <translation id="5449716055534515760">Close Win&amp;dow</translation>
 <translation id="3224239078034945833">கனடியன் பன்மொழி</translation>
 <translation id="4875057836161716898">உள்ளீட்டு காட்சிகளை இயக்கு.</translation>
@@ -4275,7 +4276,6 @@
 <translation id="1812514023095547458">வண்ணத்தைத் தேர்ந்தெடு</translation>
 <translation id="2487656424763972284">எளிய திறத்தல்</translation>
 <translation id="7047998246166230966">பாயிண்டர்</translation>
-<translation id="743268637741709136">பயன்பாட்டுத் துவக்கியில் குரல் தேடலை முடக்குகிறது. முடக்கப்பட்டால், பேச்சுவடிவம் மூலம் பயனர் தேட முடியாது.</translation>
 <translation id="3252266817569339921">ஃபிரெஞ்சு</translation>
 <translation id="2665717534925640469">இந்தப் பக்கம் இப்போது முழுத்திரையில் உள்ளது. மேலும் உங்கள் இடஞ்சுட்டியை முடக்கியுள்ளது.</translation>
 <translation id="3414952576877147120">அளவு:</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb
index f036a6a..41d3192 100644
--- a/chrome/app/resources/generated_resources_te.xtb
+++ b/chrome/app/resources/generated_resources_te.xtb
@@ -1797,6 +1797,7 @@
 <translation id="7724603315864178912">కత్తిరించు</translation>
 <translation id="8456681095658380701">చెల్లని పేరు</translation>
 <translation id="3518086201899641494">క్యాప్టివ్ పోర్టల్‌ల గురించి నోటిఫికేషన్‌లు</translation>
+<translation id="3652052123500137959">అనువర్తన లాంచర్‌లో వాయిస్ శోధనను ప్రారంభించండి.</translation>
 <translation id="1976150099241323601">భద్రతా పరికరానికి సైన్ ఇన్ చెయ్యండి</translation>
 <translation id="4120817667028078560">పథం చాలా పొడవుగా ఉంది</translation>
 <translation id="4938972461544498524">టచ్‌ప్యాడ్ సెట్టింగ్‌లు</translation>
@@ -2899,6 +2900,7 @@
 <translation id="8443621894987748190">మీ ఖాతా చిత్రాన్ని ఎంచుకోండి</translation>
 <translation id="7374461526650987610">ప్రోటోకాల్ నిర్వాహకులు</translation>
 <translation id="2192505247865591433">నుండి:</translation>
+<translation id="8668997025496699314">అనువర్తన లాంచర్‌లో వాయిస్ శోధనను ప్రారంభించండి. అది ప్రారంభించబడితే, వినియోగదారు మాట్లాడటం ద్వారా శోధించగలుగుతారు.</translation>
 <translation id="4634771451598206121">మళ్ళీ సైన్ ఇన్ చెయ్యండి...</translation>
 <translation id="3475110616773907981">మీ కంప్యూటర్‌లో మరియు మీరు సందర్శించే వెబ్‌సైట్‌ల్లో మొత్తం డేటాను ప్రాప్యత చేయండి</translation>
 <translation id="1035590878859356651">ఈ పేజీని బుక్‌మార్క్ చేయి...</translation>
@@ -3807,7 +3809,6 @@
 <translation id="3228279582454007836">ఈ రోజుకు ముందు ఎప్పుడూ మీరు ఈ సైట్‌ను సందర్శించలేదు.</translation>
 <translation id="7027125358315426638">డేటాబేస్ పేరు:</translation>
 <translation id="4030383055268325496">&amp;జోడించడాన్ని రద్దు చేయి</translation>
-<translation id="5474648613967354713">అనువర్తన లాంచర్‌లో వాయిస్ శోధనను నిలిపివేయండి.</translation>
 <translation id="5449716055534515760">&amp;విండో మూసివెయ్యి</translation>
 <translation id="3224239078034945833">కెనడియన్ బహుభాష</translation>
 <translation id="4875057836161716898">ఇన్‌పుట్ వీక్షణలను ప్రారంభించండి.</translation>
@@ -4295,7 +4296,6 @@
 <translation id="1812514023095547458">రంగుని ఎంచుకోండి</translation>
 <translation id="2487656424763972284">సులభ అన్‌లాక్</translation>
 <translation id="7047998246166230966">పాయింటర్</translation>
-<translation id="743268637741709136">అనువర్తన లాంచర్‌లో వాయిస్ శోధనను నిలిపివేయండి. నిలిపివేయబడితే, వినియోగదారు ప్రసంగం ఆధారంగా శోధించలేరు.</translation>
 <translation id="3252266817569339921">ఫ్రెంచ్</translation>
 <translation id="2665717534925640469">ఇప్పుడు ఈ పేజీ పూర్తి స్క్రీన్ మరియు మీ మౌస్ కర్సర్‌ను ఆపివేసింది.</translation>
 <translation id="3414952576877147120">పరిమాణం:</translation>
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb
index 5c85443..b370161 100644
--- a/chrome/app/resources/generated_resources_th.xtb
+++ b/chrome/app/resources/generated_resources_th.xtb
@@ -243,7 +243,7 @@
 <translation id="8806101649440495124">นำโฟลเดอร์ออก</translation>
 <translation id="5780066559993805332">(ดีที่สุด)</translation>
 <translation id="3011284594919057757">เกี่ยวกับ Flash</translation>
-<translation id="971058943242239041">เปิดใช้งานการใช้เอลิเมนต์ HTML &quot;window-controls&quot; ในแอปแพคเกจ</translation>
+<translation id="971058943242239041">เปิดใช้งานการใช้เอลิเมนต์ HTML &quot;window-controls&quot; ในแอปแพ็กเกจ</translation>
 <translation id="7377169924702866686">Caps Lock เปิดอยู่</translation>
 <translation id="2565670301826831948">ความเร็วทัชแพด:</translation>
 <translation id="7348093485538360975">แป้นพิมพ์บนหน้าจอ</translation>
@@ -1778,6 +1778,7 @@
 <translation id="7724603315864178912">ตัด</translation>
 <translation id="8456681095658380701">ชื่อไม่ถูกต้อง</translation>
 <translation id="3518086201899641494">การแจ้งเตือนเกี่ยวกับ Captive Portal</translation>
+<translation id="3652052123500137959">เปิดใช้ค้นหาด้วยเสียงในเครื่องเรียกใช้งานแอป</translation>
 <translation id="1976150099241323601">ลงชื่อเข้าใช้อุปกรณ์รักษาความปลอดภัย</translation>
 <translation id="4120817667028078560">เส้นทางยาวเกินไป</translation>
 <translation id="4938972461544498524">การตั้งค่าทัชแพด</translation>
@@ -2402,7 +2403,7 @@
 <translation id="5656862584067297168">ได้รับจากอุปกรณ์อื่น</translation>
 <translation id="2615569600992945508">ไม่อนุญาตให้ไซต์ใดๆ ปิดใช้งานเคอร์เซอร์เมาส์</translation>
 <translation id="97050131796508678">มีมัลแวร์อยู่ข้างหน้า!</translation>
-<translation id="6176445580249884435">กรอบหน้าต่างรูปแบบดั้งเดิมสำหรับแอปแพคเกจ</translation>
+<translation id="6176445580249884435">กรอบหน้าต่างรูปแบบดั้งเดิมสำหรับแอปแพ็กเกจ</translation>
 <translation id="6459488832681039634">ใช้สิ่งที่เลือกเพื่อค้นหา</translation>
 <translation id="7006844981395428048">เสียง $1</translation>
 <translation id="8700934097952626751">คลิกเพื่อเริ่มค้นหาด้วยเสียง</translation>
@@ -2642,7 +2643,7 @@
 <translation id="5966707198760109579">สัปดาห์</translation>
 <translation id="7371490661692457119">ความกว้างไทล์เริ่มต้น</translation>
 <translation id="5148652308299789060">ปิดใช้งานซอฟต์แวร์แปลงรูปแบบภาพ 3 มิติ</translation>
-<translation id="1678382244942098700">ใช้การตกแต่งหน้าต่างรูปแบบดั้งเดิมสำหรับหน้าต่างแอปแพคเกจ</translation>
+<translation id="1678382244942098700">ใช้การตกแต่งหน้าต่างรูปแบบดั้งเดิมสำหรับหน้าต่างแอปแพ็กเกจ</translation>
 <translation id="1414648216875402825">คุณกำลังอัปเดตไปเป็น <ph name="PRODUCT_NAME"/> ในเวอร์ชันที่ไม่เสถียร ซึ่งมีคุณลักษณะที่ยังอยู่ระหว่างดำเนินการ จะมีข้อขัดข้องและข้อบกพร่องที่ไม่คาดคิดเกิดขึ้น โปรดดำเนินการต่อด้วยความระมัดระวัง</translation>
 <translation id="8382913212082956454">คัดลอก&amp;ที่อยู่อีเมล</translation>
 <translation id="7447930227192971403">เปิดใช้งานแท็บ 3</translation>
@@ -2859,6 +2860,7 @@
 <translation id="8443621894987748190">เลือกรูปให้บัญชีของคุณ</translation>
 <translation id="7374461526650987610">เครื่องจัดการโปรโตคอล</translation>
 <translation id="2192505247865591433">จาก:</translation>
+<translation id="8668997025496699314">เปิดใช้ค้นหาด้วยเสียงในเครื่องเรียกใช้งานแอป หากเปิดใช้ ผู้ใช้จะสามารถค้นหาโดยใช้เสียงพูด</translation>
 <translation id="4634771451598206121">ลงชื่อเข้าใช้อีกครั้ง...</translation>
 <translation id="3475110616773907981">เข้าถึงข้อมูลทั้งหมดบนคอมพิวเตอร์ของคุณและเว็บไซต์ที่คุณเข้าชม</translation>
 <translation id="1035590878859356651">บุ๊กมาร์กหน้านี้...</translation>
@@ -3215,7 +3217,7 @@
 <translation id="5990198433782424697">ส่วนขยายใน chrome:// URL</translation>
 <translation id="7456142309650173560">การพัฒนา</translation>
 <translation id="4605399136610325267">ไม่ได้เชื่อมต่ออินเทอร์เน็ต</translation>
-<translation id="2075807684181841992">เปิดใช้งานโดยใช้เอลิเมนต์ HTML &quot;adview&quot; ในแอปแพคเกจ</translation>
+<translation id="2075807684181841992">เปิดใช้งานโดยใช้เอลิเมนต์ HTML &quot;adview&quot; ในแอปแพ็กเกจ</translation>
 <translation id="978407797571588532">ไปที่
           <ph name="BEGIN_BOLD"/>
           เริ่ม &gt; แผงควบคุม &gt; การเชื่อมต่อเครือข่าย &gt; ตัวช่วยสร้างการเชื่อมต่อใหม่
@@ -3769,7 +3771,6 @@
 <translation id="3228279582454007836">คุณไม่เคยเข้าชมเว็บไซต์นี้เลยในวันนี้</translation>
 <translation id="7027125358315426638">ชื่อฐานข้อมูล:</translation>
 <translation id="4030383055268325496">&amp;เลิกทำการเพิ่ม</translation>
-<translation id="5474648613967354713">ปิดค้นหาด้วยเสียงในเครื่องเรียกใช้งานแอป</translation>
 <translation id="5449716055534515760">ปิดหน้าต่&amp;าง</translation>
 <translation id="3224239078034945833">แคนาดาแบบหลายภาษา</translation>
 <translation id="4875057836161716898">เปิดใช้มุมมองอินพุต</translation>
@@ -4253,7 +4254,6 @@
 <translation id="1812514023095547458">เลือกสี</translation>
 <translation id="2487656424763972284">การปลดล็อกอย่างง่าย</translation>
 <translation id="7047998246166230966">ตัวชี้</translation>
-<translation id="743268637741709136">ปิดค้นหาด้วยเสียงในเครื่องเรียกใช้งานแอป เมื่อปิดแล้ว ผู้ใช้จะไม่สามารถค้นหาโดยใช้เสียงพูด</translation>
 <translation id="3252266817569339921">ฝรั่งเศส</translation>
 <translation id="2665717534925640469">หน้าเว็บนี้แสดงแบบเต็มหน้าจออยู่และได้ปิดใช้งานเคอร์เซอร์เมาส์แล้ว</translation>
 <translation id="3414952576877147120">ขนาด:</translation>
@@ -4745,7 +4745,7 @@
 <translation id="6485131920355264772">การดึงข้อมูลพื้นที่ล้มเหลว</translation>
 <translation id="8007030362289124303">แบตเตอรี่ต่ำ</translation>
 <translation id="3790909017043401679">ป้อน PIN ของซิมการ์ด</translation>
-<translation id="1135328998467923690">แพคเกจไม่ถูกต้อง: &quot;<ph name="ERROR_CODE"/>&quot;</translation>
+<translation id="1135328998467923690">แพ็กเกจไม่ถูกต้อง: &quot;<ph name="ERROR_CODE"/>&quot;</translation>
 <translation id="2339120501444485379">ป้อนชื่อใหม่</translation>
 <translation id="1753682364559456262">จัดการการบล็อกภาพ...</translation>
 <translation id="6550675742724504774">ตัวเลือก</translation>
@@ -5096,7 +5096,7 @@
 <translation id="4361745360460842907">เปิดเป็นแท็บ</translation>
 <translation id="5238278114306905396">แอปพลิเคชัน &quot;<ph name="EXTENSION_NAME"/>&quot; ถูกนำออกโดยอัตโนมัติ</translation>
 <translation id="4538792345715658285">ติดตั้งโดยนโยบายขององค์กร</translation>
-<translation id="2988488679308982380">ไม่สามารถติดตั้งแพคเกจ: &quot;<ph name="ERROR_CODE"/>&quot;</translation>
+<translation id="2988488679308982380">ไม่สามารถติดตั้งแพ็กเกจ: &quot;<ph name="ERROR_CODE"/>&quot;</translation>
 <translation id="2396249848217231973">&amp;เลิกทำการลบ</translation>
 <translation id="55815574178531051">ใบรับรองที่ Chrome ได้รับมาระหว่างการพยายามเชื่อมต่อนี้ถูกเพิกถอน</translation>
 <translation id="6129953537138746214">ช่องว่าง</translation>
@@ -5260,7 +5260,7 @@
 <translation id="1979280758666859181">คุณกำลังเปลี่ยนเป็นช่องที่มี <ph name="PRODUCT_NAME"/> เวอร์ชันเก่ากว่า การเปลี่ยนช่องจะถูกนำมาใช้เมื่อเวอร์ชันของช่องตรงกับเวอร์ชันที่ติดตั้งอยู่ในอุปกรณ์ของคุณในปัจจุบัน</translation>
 <translation id="304009983491258911">เปลี่ยน PIN ของซิมการ์ด</translation>
 <translation id="4805288960364702561">เปิดใช้งาน API แบบขยายทันทีซึ่งมีการรวมเข้ากับผู้ให้บริการการค้นหาเริ่มต้นของคุณอย่างลึกล้ำยิ่งขึ้น รวมทั้งหน้าแท็บใหม่ที่ได้รับการปรับปรุง การดึงข้อความค้นหาในแถบอเนกประสงค์ แถบอเนกประสงค์แบบเลื่อนลงที่ได้รับการปรับแต่ง และพรีวิวค้นหาทันใจของผลการค้นหาขณะที่คุณพิมพ์ในแถบอเนกประสงค์</translation>
-<translation id="8636666366616799973">แพคเกจไม่ถูกต้อง รายละเอียด: &quot;<ph name="ERROR_MESSAGE"/>&quot;</translation>
+<translation id="8636666366616799973">แพ็กเกจไม่ถูกต้อง รายละเอียด: &quot;<ph name="ERROR_MESSAGE"/>&quot;</translation>
 <translation id="2045969484888636535">ปิดกั้นคุกกี้ต่อไป</translation>
 <translation id="8131740175452115882">ยืนยัน</translation>
 <translation id="7353601530677266744">บรรทัดคำสั่ง </translation>
diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb
index 75f191b..ec74fe0 100644
--- a/chrome/app/resources/generated_resources_tr.xtb
+++ b/chrome/app/resources/generated_resources_tr.xtb
@@ -1801,6 +1801,7 @@
 <translation id="7724603315864178912">Kes</translation>
 <translation id="8456681095658380701">Geçersiz ad</translation>
 <translation id="3518086201899641494">Doğrulama amacıyla yönlendirme yapan portallar ile ilgili bildirimler</translation>
+<translation id="3652052123500137959">Uygulama Başlatıcı'da sesli aramayı etkinleştir.</translation>
 <translation id="1976150099241323601">Güvenlik Cihazında oturum açın</translation>
 <translation id="4120817667028078560">Yol çok uzun</translation>
 <translation id="4938972461544498524">Dokunmatik yüzey ayarları</translation>
@@ -2905,6 +2906,7 @@
 <translation id="8443621894987748190">Hesap resminizi seçin</translation>
 <translation id="7374461526650987610">Protokol işleyicileri</translation>
 <translation id="2192505247865591433">Nereden:</translation>
+<translation id="8668997025496699314">Uygulama Başlatıcı'da sesli aramayı etkinleştir. Bu özellik etkinse kullanıcı konuşarak arama yapabilir.</translation>
 <translation id="4634771451598206121">Tekrar oturum açın...</translation>
 <translation id="3475110616773907981">Bilgisayarınızdaki ve ziyaret ettiğiniz web sitelerindeki tüm verilere erişme</translation>
 <translation id="1035590878859356651">Bu sayfaya yer işareti koy...</translation>
@@ -3817,7 +3819,6 @@
 <translation id="3228279582454007836">Bu siteyi bugün hiç ziyaret etmediniz.</translation>
 <translation id="7027125358315426638">Veritabanı adı:</translation>
 <translation id="4030383055268325496">Eklemeyi &amp;geri al</translation>
-<translation id="5474648613967354713">Uygulama Başlatıcı'da sesli aramayı devre dışı bırak.</translation>
 <translation id="5449716055534515760">Pencereyi &amp;Kapat</translation>
 <translation id="3224239078034945833">Çok Dilli Kanada</translation>
 <translation id="4875057836161716898">Giriş görünümlerini etkinleştirin.</translation>
@@ -4305,7 +4306,6 @@
 <translation id="1812514023095547458">Renk Seç</translation>
 <translation id="2487656424763972284">Kolay Kilit Açma</translation>
 <translation id="7047998246166230966">İşaretçi</translation>
-<translation id="743268637741709136">Uygulama Başlatıcı'da sesli aramayı devre dışı bırak. Devre dışı bırakıldığında, kullanıcı sesle arama yapamaz.</translation>
 <translation id="3252266817569339921">Fransızca</translation>
 <translation id="2665717534925640469">Bu sayfa artık tam ekran görüntüleniyor ve fare imlecinizi devre dışı bıraktı.</translation>
 <translation id="3414952576877147120">Boyut:</translation>
diff --git a/chrome/app/resources/generated_resources_uk.xtb b/chrome/app/resources/generated_resources_uk.xtb
index 50255e7..8db9179 100644
--- a/chrome/app/resources/generated_resources_uk.xtb
+++ b/chrome/app/resources/generated_resources_uk.xtb
@@ -1779,6 +1779,7 @@
 <translation id="7724603315864178912">Вирізати</translation>
 <translation id="8456681095658380701">Недійсне ім’я</translation>
 <translation id="3518086201899641494">Сповіщення про приєднані портали</translation>
+<translation id="3652052123500137959">Увімкнути голосовий пошук на панелі запуску додатків.</translation>
 <translation id="1976150099241323601">Увійти в пристрій безпеки</translation>
 <translation id="4120817667028078560">Шлях задовгий</translation>
 <translation id="4938972461544498524">Налаштування сенсорної панелі</translation>
@@ -2856,6 +2857,7 @@
 <translation id="8443621894987748190">Виберіть зображення з облікового запису</translation>
 <translation id="7374461526650987610">Обробники протоколів</translation>
 <translation id="2192505247865591433">Від:</translation>
+<translation id="8668997025496699314">Увімкнути голосовий пошук на панелі запуску додатків. Якщо ввімкнено, користувач зможе шукати голосом.</translation>
 <translation id="4634771451598206121">Увійти знову...</translation>
 <translation id="3475110616773907981">Отримувати доступ до всіх даних на вашому комп’ютері та веб-сайтах, які ви відвідуєте</translation>
 <translation id="1035590878859356651">Створити закладку для цієї сторінки…</translation>
@@ -3759,7 +3761,6 @@
 <translation id="3228279582454007836">Ви ніколи не відвідували цей сайт до сьогоднішнього дня</translation>
 <translation id="7027125358315426638">Назва бази даних:</translation>
 <translation id="4030383055268325496">&amp;Відмінити додавання</translation>
-<translation id="5474648613967354713">Вимкнути голосовий пошук на панелі запуску додатків.</translation>
 <translation id="5449716055534515760">Закрити вік&amp;но</translation>
 <translation id="3224239078034945833">Канадська (багатомовна)</translation>
 <translation id="4875057836161716898">Увімкнути вікна введення.</translation>
@@ -4243,7 +4244,6 @@
 <translation id="1812514023095547458">Вибрати колір</translation>
 <translation id="2487656424763972284">Швидке розблокування</translation>
 <translation id="7047998246166230966">Курсор</translation>
-<translation id="743268637741709136">Вимкнути голосовий пошук на панелі запуску додатків. Якщо вимкнути, користувач не зможе шукати за допомогою голосу.</translation>
 <translation id="3252266817569339921">Французька</translation>
 <translation id="2665717534925640469">Ця сторінка зараз відображається в повноекранному режимі та вимкнула курсор миші.</translation>
 <translation id="3414952576877147120">Розмір:</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb
index 39c1801..f876187 100644
--- a/chrome/app/resources/generated_resources_vi.xtb
+++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -1804,6 +1804,7 @@
 <translation id="7724603315864178912">Cắt</translation>
 <translation id="8456681095658380701">Tên không hợp lệ</translation>
 <translation id="3518086201899641494">Thông báo về cổng phát hiện</translation>
+<translation id="3652052123500137959">Bật tìm kiếm bằng giọng nói trong Trình khởi chạy ứng dụng.</translation>
 <translation id="1976150099241323601">Đăng nhập vào thiết bị bảo mật</translation>
 <translation id="4120817667028078560">Đường dẫn quá dài</translation>
 <translation id="4938972461544498524">Cài đặt bàn di chuột</translation>
@@ -2911,6 +2912,7 @@
 <translation id="8443621894987748190">Chọn ảnh tài khoản của bạn</translation>
 <translation id="7374461526650987610">Trình xử lý giao thức</translation>
 <translation id="2192505247865591433">Từ:</translation>
+<translation id="8668997025496699314">Bật tìm kiếm bằng giọng nói trong Trình khởi chạy ứng dụng. Nếu được bật, người dùng sẽ có thể tìm kiếm bằng giọng nói.</translation>
 <translation id="4634771451598206121">Đăng nhập lại...</translation>
 <translation id="3475110616773907981">Truy cập tất cả dữ liệu trên máy tính của bạn và trang web bạn truy cập</translation>
 <translation id="1035590878859356651">Đánh dấu trang này...</translation>
@@ -3365,7 +3367,7 @@
 <translation id="580886651983547002"><ph name="PRODUCT_NAME"/>
         không thể truy cập trang web.  Điều này thường do sự cố mạng,
         nhưng cũng có thể do việc định cấu hình sai tường lừa hoặc máy chủ proxy.</translation>
-<translation id="4387554346626014084">Bật Đồng bộ hóa trình khởi chạy ứng dụng. Thao tác này cũng bật Thư mục khi có thể (không phải OSX).</translation>
+<translation id="4387554346626014084">Bật Đồng bộ hóa trình chạy ứng dụng. Thao tác này cũng bật Thư mục khi có thể (không phải OSX).</translation>
 <translation id="5445557969380904478">Giới thiệu về nhận dạng giọng nói</translation>
 <translation id="4104400246019119780">Cảm ơn bạn!</translation>
 <translation id="3487007233252413104">chức năng ẩn danh</translation>
@@ -3823,7 +3825,6 @@
 <translation id="3228279582454007836">Bạn chưa bao giờ truy cập trang web này trước đó.</translation>
 <translation id="7027125358315426638">Tên cơ sở dữ liệu:</translation>
 <translation id="4030383055268325496">&amp;Hoàn tác thêm</translation>
-<translation id="5474648613967354713">Tắt tìm kiếm bằng giọng nói trong Trình chạy ứng dụng.</translation>
 <translation id="5449716055534515760">Đóng cửa &amp;sổ</translation>
 <translation id="3224239078034945833">Đa ngôn ngữ tiếng Canada</translation>
 <translation id="4875057836161716898">Bật chế độ xem thao tác nhập.</translation>
@@ -4309,7 +4310,6 @@
 <translation id="1812514023095547458">Chọn màu</translation>
 <translation id="2487656424763972284">Mở khóa dễ dàng</translation>
 <translation id="7047998246166230966">Con trỏ</translation>
-<translation id="743268637741709136">Tắt tìm kiếm bằng giọng nói trong Trình chạy ứng dụng. Nếu tính năng này bị tắt, người dùng sẽ không thể tìm kiếm bằng giọng nói.</translation>
 <translation id="3252266817569339921">Tiếng Pháp</translation>
 <translation id="2665717534925640469">Trang này hiện đang ở chế độ toàn màn hình và đã tắt con trỏ chuột của bạn.</translation>
 <translation id="3414952576877147120">Kích thước:</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb
index 4c5f114..b137141 100644
--- a/chrome/app/resources/generated_resources_zh-CN.xtb
+++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -1767,6 +1767,7 @@
 <translation id="7724603315864178912">剪切</translation>
 <translation id="8456681095658380701">名称无效</translation>
 <translation id="3518086201899641494">关于强制门户的通知</translation>
+<translation id="3652052123500137959">在应用启动器中启用语音搜索。</translation>
 <translation id="1976150099241323601">登录安全设备</translation>
 <translation id="4120817667028078560">路径过长</translation>
 <translation id="4938972461544498524">触控板设置</translation>
@@ -1984,7 +1985,7 @@
 <translation id="2916073183900451334">在网页上按 Tab 可突出显示链接以及表单字段</translation>
 <translation id="7772127298218883077">关于<ph name="PRODUCT_NAME"/></translation>
 <translation id="2090876986345970080">系统安全设置</translation>
-<translation id="3728067901555601989">OTP:</translation>
+<translation id="3728067901555601989">一次性密码:</translation>
 <translation id="3565831235433694786">启用D3D11</translation>
 <translation id="3475447146579922140">Google 电子表格</translation>
 <translation id="6856526171412069413">启用双指开合缩放。</translation>
@@ -2866,6 +2867,7 @@
 <translation id="8443621894987748190">选择您的帐户头像</translation>
 <translation id="7374461526650987610">协议处理程序</translation>
 <translation id="2192505247865591433">来源:</translation>
+<translation id="8668997025496699314">在应用启动器中启用语音搜索。如果您启用了此项,用户将能够通过语音进行搜索。</translation>
 <translation id="4634771451598206121">重新登录...</translation>
 <translation id="3475110616773907981">访问您计算机和访问过的网站上的所有数据</translation>
 <translation id="1035590878859356651">为此网页添加书签…</translation>
@@ -3771,7 +3773,6 @@
 <translation id="3228279582454007836">您以前从未访问过此网站。</translation>
 <translation id="7027125358315426638">数据库名称:</translation>
 <translation id="4030383055268325496">撤消添加(&amp;U)</translation>
-<translation id="5474648613967354713">在应用启动器中停用语音搜索。</translation>
 <translation id="5449716055534515760">关闭窗口(&amp;D)</translation>
 <translation id="3224239078034945833">加拿大多语言</translation>
 <translation id="4875057836161716898">启用输入视图。</translation>
@@ -4255,7 +4256,6 @@
 <translation id="1812514023095547458">选择颜色</translation>
 <translation id="2487656424763972284">轻松解锁</translation>
 <translation id="7047998246166230966">指针</translation>
-<translation id="743268637741709136">在应用启动器中停用语音搜索。如果您停用了此项,用户将无法进行语音搜索。</translation>
 <translation id="3252266817569339921">法语</translation>
 <translation id="2665717534925640469">此网页现处于全屏模式并已隐藏鼠标指针。</translation>
 <translation id="3414952576877147120">大小:</translation>
diff --git a/chrome/app/resources/generated_resources_zh-TW.xtb b/chrome/app/resources/generated_resources_zh-TW.xtb
index 1f6f3cc..5634b25 100644
--- a/chrome/app/resources/generated_resources_zh-TW.xtb
+++ b/chrome/app/resources/generated_resources_zh-TW.xtb
@@ -368,7 +368,7 @@
 <translation id="8363106484844966752">警告:您尚未啟用效能監控參數!系統只能顯示之前收集的資料。</translation>
 <translation id="6243774244933267674">無法與伺服器連線</translation>
 <translation id="2436707352762155834">最小值</translation>
-<translation id="5556206011531515970">按一下 [下一步] 以選擇您的預設瀏覽器。</translation>
+<translation id="5556206011531515970">按一下 [下一步] 選擇您的預設瀏覽器。</translation>
 <translation id="9041603713188951722">在視窗中顯示設定</translation>
 <translation id="8158300065514217730">登入即可匯入受監管的使用者</translation>
 <translation id="2789486458103222910">確定</translation>
@@ -1782,6 +1782,7 @@
 <translation id="7724603315864178912">剪下</translation>
 <translation id="8456681095658380701">名稱無效</translation>
 <translation id="3518086201899641494">認證網頁通知</translation>
+<translation id="3652052123500137959">在應用程式啟動器中啟用語音搜尋。</translation>
 <translation id="1976150099241323601">登入安全性裝置</translation>
 <translation id="4120817667028078560">路徑名稱過長</translation>
 <translation id="4938972461544498524">觸控板設定</translation>
@@ -1833,7 +1834,7 @@
 <translation id="894360074127026135">Netscape International Step-Up</translation>
 <translation id="8420060421540670057">顯示 Google 文件檔案</translation>
 <translation id="6075731018162044558">糟糕!系統無法為這個裝置取得長期 API 存取符記。</translation>
-<translation id="1201402288615127009">下一個</translation>
+<translation id="1201402288615127009">下一步</translation>
 <translation id="1335588927966684346">公用程式:</translation>
 <translation id="6182418440401923218">啟用傳送使用者意見回饋給拼字服務的實地試驗。</translation>
 <translation id="2710582058364740604">覆寫裝置顯示密度,強制使用高 DPI 模式和資源。</translation>
@@ -2063,7 +2064,7 @@
 <translation id="6466988389784393586">開啟所有書籤(&amp;O)</translation>
 <translation id="9193357432624119544">錯誤代碼:<ph name="ERROR_NAME"/></translation>
 <translation id="5288678174502918605">重新開啟先前關閉的分頁(&amp;E)</translation>
-<translation id="7238461040709361198">您上次使用這台電腦登入時已變更了「Google 帳戶」密碼。</translation>
+<translation id="7238461040709361198">自從您上次使用這台電腦登入之後,Google 帳戶的密碼已經變更。</translation>
 <translation id="1956050014111002555">檔案含有多個憑證,但全都無法匯入:</translation>
 <translation id="302620147503052030">顯示按鈕</translation>
 <translation id="1895658205118569222">關閉</translation>
@@ -2877,6 +2878,7 @@
 <translation id="8443621894987748190">選擇個人帳戶圖片</translation>
 <translation id="7374461526650987610">通訊協定處理常式</translation>
 <translation id="2192505247865591433">自:</translation>
+<translation id="8668997025496699314">在應用程式啟動器中啟用語音搜尋。啟用後,使用者即可透過語音進行搜尋。</translation>
 <translation id="4634771451598206121">重新登入...</translation>
 <translation id="3475110616773907981">存取您電腦上的所有資料與您造訪過的網站</translation>
 <translation id="1035590878859356651">將這個網頁加入書籤...</translation>
@@ -3787,7 +3789,6 @@
 <translation id="3228279582454007836">您在今天以前從未造訪過此網站。</translation>
 <translation id="7027125358315426638">資料庫名稱:</translation>
 <translation id="4030383055268325496">復原新增(&amp;U)</translation>
-<translation id="5474648613967354713">在應用程式啟動器中停用語音搜尋。</translation>
 <translation id="5449716055534515760">關閉視窗(&amp;D)</translation>
 <translation id="3224239078034945833">加拿大文 (多語言)</translation>
 <translation id="4875057836161716898">啟用輸入檢視模式。</translation>
@@ -4273,7 +4274,6 @@
 <translation id="1812514023095547458">選取顏色</translation>
 <translation id="2487656424763972284">簡易解鎖</translation>
 <translation id="7047998246166230966">指標裝置</translation>
-<translation id="743268637741709136">在應用程式啟動器中停用語音搜尋。停用後,使用者將無法透過語音進行搜尋。</translation>
 <translation id="3252266817569339921">法文</translation>
 <translation id="2665717534925640469">這個網頁已顯示為全螢幕,並停用了滑鼠游標。</translation>
 <translation id="3414952576877147120">空間大小:</translation>
diff --git a/chrome/app/resources/google_chrome_strings_am.xtb b/chrome/app/resources/google_chrome_strings_am.xtb
index 87850ab..70afc73 100644
--- a/chrome/app/resources/google_chrome_strings_am.xtb
+++ b/chrome/app/resources/google_chrome_strings_am.xtb
@@ -54,7 +54,7 @@
 <translation id="4149882025268051530">ጫኝው መዝገብ ለመበተን አልቻለም። እባክዎ Google Chromeን እንደገና ያውርዱ።</translation>
 <translation id="7054640471403081847">ይህ ኮምፒውተር ሃርድዌሩ ከአሁን በኋላ ስለማይደገፍ በቅርቡ የGoogle Chrome ዝማኔዎችን መቀበል ያቆማል።</translation>
 <translation id="6326709553577195251">መለያዎን ለማስወገድ Chrome ዳግም መጀመር አለበት። ከመቀጠልዎ በፊት ማንኛውንም ክፍት ስራ ማስቀመጥዎን ያረጋግጡ።</translation>
-<translation id="6989339256997917931">Google Chrome ተዘምኗል፣ ግን ቢያንስ ለ30 ቀናት አልተጠቀሙበትም።</translation>
+<translation id="6989339256997917931">Google Chrome ተዘምኗል፣ ግን ቢያንስ ለ30 ቀኖች አልተጠቀሙበትም።</translation>
 <translation id="7060865993964054389">Google Chrome የመተግበሪያ አስጀማሪ</translation>
 <translation id="1682634494516646069">Google Chrome የውሂብ አቃፊውን ማንበብ እና እሱ ላይ መጻፍ አይችልም፦
 
diff --git a/chrome/app/resources/google_chrome_strings_de.xtb b/chrome/app/resources/google_chrome_strings_de.xtb
index 0e709ca..de9489e 100644
--- a/chrome/app/resources/google_chrome_strings_de.xtb
+++ b/chrome/app/resources/google_chrome_strings_de.xtb
@@ -41,7 +41,7 @@
 <translation id="3555616473548901994">Deinstallation ist abgeschlossen.</translation>
 <translation id="4987308747895123092">Schließen Sie alle Google Chrome-Fenster einschließlich der Fenster im Windows 8-Modus und versuchen Sie es erneut.</translation>
 <translation id="568643307450491754">Ihre Lesezeichen finden Sie im Chrome-Menü oder in der Lesezeichenleiste.</translation>
-<translation id="55271449890419930">Da Google Chrome nicht steuert, wie Erweiterungen mit Ihren personenbezogenen Daten umgehen, wurden für Inkognito-Fenster alle Erweiterungen deaktiviert. Sie können die Erweiterungen einzeln im <ph name="BEGIN_LINK"/>Erweiterungs-Manager<ph name="END_LINK"/> aktivieren.</translation>
+<translation id="55271449890419930">Da Google Chrome nicht steuert, wie Erweiterungen mit Ihren personenbezogenen Daten umgehen, wurden für Inkognitofenster alle Erweiterungen deaktiviert. Sie können die Erweiterungen einzeln im <ph name="BEGIN_LINK"/>Erweiterungs-Manager<ph name="END_LINK"/> aktivieren.</translation>
 <translation id="8556340503434111824">Es gibt eine neue Version von Google Chrome, die schneller ist, als anderen zuvor.</translation>
 <translation id="4728575227883772061">Installation aufgrund von unbekanntem Fehler fehlgeschlagen. Falls Google Chrome bereits ausgeführt wird, schließen Sie es und versuchen Sie es erneut.</translation>
 <translation id="2082230140685103752">Starten Sie Google Chrome im Desktopmodus, um Chrome-Apps verwenden zu können.</translation>
diff --git a/chrome/app/resources/locale_settings.grd b/chrome/app/resources/locale_settings.grd
index 220f4f0..2bd98d4 100644
--- a/chrome/app/resources/locale_settings.grd
+++ b/chrome/app/resources/locale_settings.grd
@@ -380,15 +380,17 @@
         65
       </message>
 
-      <!-- The width of the make-default-in-metro dialog in characters. -->
-      <message name="IDS_METRO_FLOW_WIDTH_CHARS" use_name_for_id="true">
-        78
-      </message>
+      <if expr="is_win">
+        <!-- The width of the make-default-in-metro dialog in characters. -->
+        <message name="IDS_METRO_FLOW_WIDTH_CHARS" use_name_for_id="true">
+          78
+        </message>
 
-      <!-- The height of the make-default-in-metro dialog in characters. -->
-      <message name="IDS_METRO_FLOW_HEIGHT_LINES" use_name_for_id="true">
-        26
-      </message>
+        <!-- The height of the make-default-in-metro dialog in characters. -->
+        <message name="IDS_METRO_FLOW_HEIGHT_LINES" use_name_for_id="true">
+          26
+        </message>
+      </if>
 
       <!-- The width of the media galleries configuration dialog in characters. -->
       <message name="IDS_MEDIA_GALLERIES_DIALOG_CONTENT_WIDTH_CHARS" use_name_for_id="true">
diff --git a/chrome/app/theme/default_100_percent/common/blocked_save_passwords.png b/chrome/app/theme/default_100_percent/common/blocked_save_passwords.png
new file mode 100644
index 0000000..8e5ce21
--- /dev/null
+++ b/chrome/app/theme/default_100_percent/common/blocked_save_passwords.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_alien.png b/chrome/app/theme/default_100_percent/common/profile_avatar_alien.png
index 323cb55..53f630d 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_alien.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_alien.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_alien_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_alien_mac.png
index 01436ed..1e38d1d 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_alien_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_alien_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_awesome.png b/chrome/app/theme/default_100_percent/common/profile_avatar_awesome.png
index b351060..cfd895b 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_awesome.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_awesome.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_awesome_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_awesome_mac.png
index d1450cb..d9e989c 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_awesome_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_awesome_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_burger.png b/chrome/app/theme/default_100_percent/common/profile_avatar_burger.png
index 8b0c076..fdafa8a 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_burger.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_burger.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_burger_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_burger_mac.png
index 2f8f485..36ec0be 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_burger_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_burger_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_businessman.png b/chrome/app/theme/default_100_percent/common/profile_avatar_businessman.png
index 8262f75..c911580 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_businessman.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_businessman.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_businessman_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_businessman_mac.png
index 5d57a69..f291ee7 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_businessman_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_businessman_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_cat.png b/chrome/app/theme/default_100_percent/common/profile_avatar_cat.png
index 135fe06..1598ec6 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_cat.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_cat.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_cat_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_cat_mac.png
index c823a7d..c4f471c 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_cat_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_cat_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_cupcake.png b/chrome/app/theme/default_100_percent/common/profile_avatar_cupcake.png
index aa03378..7009f1b 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_cupcake.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_cupcake.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_cupcake_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_cupcake_mac.png
index f02a167..413efe0 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_cupcake_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_cupcake_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_dog.png b/chrome/app/theme/default_100_percent/common/profile_avatar_dog.png
index 735ae09..36bce9c 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_dog.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_dog.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_dog_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_dog_mac.png
index 60cbbe2..dc68338 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_dog_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_dog_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_flower.png b/chrome/app/theme/default_100_percent/common/profile_avatar_flower.png
index a53e6b5..763bff4 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_flower.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_flower.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_flower_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_flower_mac.png
index 7221587..cacced0 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_flower_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_flower_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic.png
index 0556fc2..490a160 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_aqua.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_aqua.png
index f65f12a..a3248c8 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_aqua.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_aqua.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_aqua_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_aqua_mac.png
index d68a5b3..be4653b 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_aqua_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_aqua_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_blue.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_blue.png
index ba18aa1..6a1f471 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_blue.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_blue.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_blue_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_blue_mac.png
index 98a8881..3c20af3 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_blue_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_blue_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_green.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_green.png
index 4a283ef..5f97f4b 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_green.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_green.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_green_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_green_mac.png
index 3faa47b..6c8038b 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_green_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_green_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_mac.png
index 985f814..8c44287 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_orange.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_orange.png
index 606c760..83a5615 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_orange.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_orange.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_orange_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_orange_mac.png
index 4b408ae..42a432b 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_orange_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_orange_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_purple.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_purple.png
index 440be3b..7f9ee7c 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_purple.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_purple.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_purple_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_purple_mac.png
index 23de26e..68b593e 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_purple_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_purple_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_red.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_red.png
index e951519..d4363d9 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_red.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_red.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_red_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_red_mac.png
index 10e5d6a..7394b14 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_red_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_red_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_yellow.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_yellow.png
index eb66077..b7f2673 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_yellow.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_yellow.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_yellow_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_yellow_mac.png
index fc851be..0880ed8 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_generic_yellow_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_generic_yellow_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_horse.png b/chrome/app/theme/default_100_percent/common/profile_avatar_horse.png
index 214b6f7..734eded 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_horse.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_horse.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_horse_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_horse_mac.png
index 71e844e..bff06fe 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_horse_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_horse_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_margarita.png b/chrome/app/theme/default_100_percent/common/profile_avatar_margarita.png
index a869435..d62c12d 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_margarita.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_margarita.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_margarita_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_margarita_mac.png
index b75e735..ef401f6 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_margarita_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_margarita_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_ninja.png b/chrome/app/theme/default_100_percent/common/profile_avatar_ninja.png
index 998255d..0b27760 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_ninja.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_ninja.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_ninja_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_ninja_mac.png
index a66b606..6325fc0 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_ninja_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_ninja_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_note.png b/chrome/app/theme/default_100_percent/common/profile_avatar_note.png
index 1344861..5924c8f 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_note.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_note.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_note_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_note_mac.png
index 0af47a9..5924c8f 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_note_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_note_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_pizza.png b/chrome/app/theme/default_100_percent/common/profile_avatar_pizza.png
index 991f1f5..68fbf6b 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_pizza.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_pizza.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_pizza_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_pizza_mac.png
index 4d90da9..7e2ad53 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_pizza_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_pizza_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_secret_agent.png b/chrome/app/theme/default_100_percent/common/profile_avatar_secret_agent.png
index 428f137..f6fdfc3 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_secret_agent.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_secret_agent.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_secret_agent_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_secret_agent_mac.png
index 98ddb8d..2763ebc 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_secret_agent_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_secret_agent_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_soccer.png b/chrome/app/theme/default_100_percent/common/profile_avatar_soccer.png
index a15b0f2..5ee7d49 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_soccer.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_soccer.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_soccer_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_soccer_mac.png
index a84a917..fd58e02 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_soccer_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_soccer_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_sun_cloud.png b/chrome/app/theme/default_100_percent/common/profile_avatar_sun_cloud.png
index c315d77..e8d4613 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_sun_cloud.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_sun_cloud.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_sun_cloud_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_sun_cloud_mac.png
index 90caaf9..49fa6c4 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_sun_cloud_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_sun_cloud_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_superhero.png b/chrome/app/theme/default_100_percent/common/profile_avatar_superhero.png
index 44305c6..bfe853c 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_superhero.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_superhero.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_superhero_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_superhero_mac.png
index feda81e..30111e0 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_superhero_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_superhero_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_volley_ball.png b/chrome/app/theme/default_100_percent/common/profile_avatar_volley_ball.png
index a0bf25e..cfb5515 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_volley_ball.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_volley_ball.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/profile_avatar_volley_ball_mac.png b/chrome/app/theme/default_100_percent/common/profile_avatar_volley_ball_mac.png
index fba4c6b..0004c6a 100644
--- a/chrome/app/theme/default_100_percent/common/profile_avatar_volley_ball_mac.png
+++ b/chrome/app/theme/default_100_percent/common/profile_avatar_volley_ball_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/question_hover.png b/chrome/app/theme/default_100_percent/common/profile_menu_question_hover.png
similarity index 100%
rename from chrome/app/theme/default_100_percent/common/question_hover.png
rename to chrome/app/theme/default_100_percent/common/profile_menu_question_hover.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/question_select.png b/chrome/app/theme/default_100_percent/common/profile_menu_question_select.png
similarity index 100%
rename from chrome/app/theme/default_100_percent/common/question_select.png
rename to chrome/app/theme/default_100_percent/common/profile_menu_question_select.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/question_stable.png b/chrome/app/theme/default_100_percent/common/profile_menu_question_stable.png
similarity index 100%
rename from chrome/app/theme/default_100_percent/common/question_stable.png
rename to chrome/app/theme/default_100_percent/common/profile_menu_question_stable.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/speech_input_mic_empty.png b/chrome/app/theme/default_100_percent/common/speech_input_mic_empty.png
deleted file mode 100644
index d17dc9c..0000000
--- a/chrome/app/theme/default_100_percent/common/speech_input_mic_empty.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/speech_input_mic_full.png b/chrome/app/theme/default_100_percent/common/speech_input_mic_full.png
deleted file mode 100644
index 247307c..0000000
--- a/chrome/app/theme/default_100_percent/common/speech_input_mic_full.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/speech_input_mic_mask.png b/chrome/app/theme/default_100_percent/common/speech_input_mic_mask.png
deleted file mode 100644
index 11696c0..0000000
--- a/chrome/app/theme/default_100_percent/common/speech_input_mic_mask.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/speech_input_mic_noise.png b/chrome/app/theme/default_100_percent/common/speech_input_mic_noise.png
deleted file mode 100644
index ef57c0d..0000000
--- a/chrome/app/theme/default_100_percent/common/speech_input_mic_noise.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/speech_input_spinner.png b/chrome/app/theme/default_100_percent/common/speech_input_spinner.png
deleted file mode 100644
index 108236b..0000000
--- a/chrome/app/theme/default_100_percent/common/speech_input_spinner.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/cros/bluetooth_pairing_keyboard.png b/chrome/app/theme/default_100_percent/cros/bluetooth_pairing_keyboard.png
new file mode 100644
index 0000000..81a1d66
--- /dev/null
+++ b/chrome/app/theme/default_100_percent/cros/bluetooth_pairing_keyboard.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/cros/bluetooth_pairing_mouse.png b/chrome/app/theme/default_100_percent/cros/bluetooth_pairing_mouse.png
new file mode 100644
index 0000000..ef03b28
--- /dev/null
+++ b/chrome/app/theme/default_100_percent/cros/bluetooth_pairing_mouse.png
Binary files differ
diff --git a/chrome/app/theme/default_100_percent/cros/bluetooth_pairing_tick.png b/chrome/app/theme/default_100_percent/cros/bluetooth_pairing_tick.png
new file mode 100644
index 0000000..ef8d773
--- /dev/null
+++ b/chrome/app/theme/default_100_percent/cros/bluetooth_pairing_tick.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/blocked_save_passwords.png b/chrome/app/theme/default_200_percent/common/blocked_save_passwords.png
new file mode 100644
index 0000000..30a5328
--- /dev/null
+++ b/chrome/app/theme/default_200_percent/common/blocked_save_passwords.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_alien.png b/chrome/app/theme/default_200_percent/common/profile_avatar_alien.png
index ef4614a..e84bf0b 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_alien.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_alien.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_alien_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_alien_mac.png
index 8e89f0c..5c30792 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_alien_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_alien_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_awesome.png b/chrome/app/theme/default_200_percent/common/profile_avatar_awesome.png
index f1edefc..281d004 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_awesome.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_awesome.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_awesome_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_awesome_mac.png
index e389cf0..c0dfd70 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_awesome_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_awesome_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_burger.png b/chrome/app/theme/default_200_percent/common/profile_avatar_burger.png
index c5bbff0..0d49f66 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_burger.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_burger.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_burger_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_burger_mac.png
index ff80017..3e75b3d 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_burger_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_burger_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_businessman.png b/chrome/app/theme/default_200_percent/common/profile_avatar_businessman.png
index c27ef6a..4ef3197 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_businessman.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_businessman.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_businessman_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_businessman_mac.png
index 8070fa4..d75e93b 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_businessman_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_businessman_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_cat.png b/chrome/app/theme/default_200_percent/common/profile_avatar_cat.png
index b6d2cab..c547eee 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_cat.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_cat.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_cat_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_cat_mac.png
index 19eb320..bbf08bd 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_cat_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_cat_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_cupcake.png b/chrome/app/theme/default_200_percent/common/profile_avatar_cupcake.png
index 6530507..85d47e0 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_cupcake.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_cupcake.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_cupcake_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_cupcake_mac.png
index 3c1d0bb..5303564 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_cupcake_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_cupcake_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_dog.png b/chrome/app/theme/default_200_percent/common/profile_avatar_dog.png
index c7c1642..86a92b1 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_dog.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_dog.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_dog_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_dog_mac.png
index 61696f3..8281214 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_dog_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_dog_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_flower.png b/chrome/app/theme/default_200_percent/common/profile_avatar_flower.png
index 20d50c6..e8f9b7e 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_flower.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_flower.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_flower_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_flower_mac.png
index 0474606..0aaf2db 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_flower_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_flower_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic.png
index 59e8609..4270df4 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_aqua.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_aqua.png
index 03e6511..2be4cdf 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_aqua.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_aqua.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_aqua_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_aqua_mac.png
index 7e58f64..d1db87a 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_aqua_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_aqua_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_blue.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_blue.png
index dd5ac05..0b4c8df 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_blue.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_blue.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_blue_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_blue_mac.png
index 95c30fe..836d0e6 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_blue_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_blue_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_green.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_green.png
index 0df3bd0..735d904 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_green.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_green.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_green_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_green_mac.png
index aa8836b..1073e70 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_green_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_green_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_mac.png
index da2755b..33a2149 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_orange.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_orange.png
index 03142be..d791bd4 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_orange.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_orange.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_orange_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_orange_mac.png
index 0e8242c..d4cf705 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_orange_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_orange_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_purple.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_purple.png
index d06996e..448aa1e 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_purple.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_purple.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_purple_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_purple_mac.png
index 215dbc6..3b3efa1 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_purple_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_purple_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_red.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_red.png
index 991439b..b91010d 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_red.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_red.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_red_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_red_mac.png
index 468b7cd..b5ad6d1 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_red_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_red_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_yellow.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_yellow.png
index b6b35fc..b1ea87f 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_yellow.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_yellow.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_yellow_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_yellow_mac.png
index 23ba330..0a7d2d8 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_generic_yellow_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_generic_yellow_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_horse.png b/chrome/app/theme/default_200_percent/common/profile_avatar_horse.png
index 3762217..f971827 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_horse.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_horse.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_horse_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_horse_mac.png
index a99ef3f..c57f858 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_horse_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_horse_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_margarita.png b/chrome/app/theme/default_200_percent/common/profile_avatar_margarita.png
index 049a5c4..f5ab84f 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_margarita.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_margarita.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_margarita_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_margarita_mac.png
index b5d780b..b7602c5 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_margarita_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_margarita_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_ninja.png b/chrome/app/theme/default_200_percent/common/profile_avatar_ninja.png
index e3f0a31..fbb2baf 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_ninja.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_ninja.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_ninja_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_ninja_mac.png
index b7debbe..62705d5 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_ninja_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_ninja_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_note.png b/chrome/app/theme/default_200_percent/common/profile_avatar_note.png
index 47dafd9..a03ab42 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_note.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_note.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_note_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_note_mac.png
index 8c0c521..f332c67 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_note_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_note_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_pizza.png b/chrome/app/theme/default_200_percent/common/profile_avatar_pizza.png
index a6da012..a99e282 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_pizza.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_pizza.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_pizza_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_pizza_mac.png
index e1c5334..6dcf26b 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_pizza_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_pizza_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_secret_agent.png b/chrome/app/theme/default_200_percent/common/profile_avatar_secret_agent.png
index d85a63a..d02edd3 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_secret_agent.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_secret_agent.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_secret_agent_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_secret_agent_mac.png
index 6f0307a..e1f135c 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_secret_agent_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_secret_agent_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_soccer.png b/chrome/app/theme/default_200_percent/common/profile_avatar_soccer.png
index f1937f2..04f06d5 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_soccer.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_soccer.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_soccer_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_soccer_mac.png
index ae8b205..fe7052c 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_soccer_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_soccer_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_sun_cloud.png b/chrome/app/theme/default_200_percent/common/profile_avatar_sun_cloud.png
index 0295e25..75bcb95 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_sun_cloud.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_sun_cloud.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_sun_cloud_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_sun_cloud_mac.png
index 28e20d5..115e3fe 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_sun_cloud_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_sun_cloud_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_superhero.png b/chrome/app/theme/default_200_percent/common/profile_avatar_superhero.png
index c54b5bc..2653e30 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_superhero.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_superhero.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_superhero_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_superhero_mac.png
index fe36ce1..d6f64a8 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_superhero_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_superhero_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_volley_ball.png b/chrome/app/theme/default_200_percent/common/profile_avatar_volley_ball.png
index ba83140..9289aa6 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_volley_ball.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_volley_ball.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/profile_avatar_volley_ball_mac.png b/chrome/app/theme/default_200_percent/common/profile_avatar_volley_ball_mac.png
index b215fd1..82516bd 100644
--- a/chrome/app/theme/default_200_percent/common/profile_avatar_volley_ball_mac.png
+++ b/chrome/app/theme/default_200_percent/common/profile_avatar_volley_ball_mac.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/question_hover.png b/chrome/app/theme/default_200_percent/common/profile_menu_question_hover.png
similarity index 100%
rename from chrome/app/theme/default_200_percent/common/question_hover.png
rename to chrome/app/theme/default_200_percent/common/profile_menu_question_hover.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/question_select.png b/chrome/app/theme/default_200_percent/common/profile_menu_question_select.png
similarity index 100%
rename from chrome/app/theme/default_200_percent/common/question_select.png
rename to chrome/app/theme/default_200_percent/common/profile_menu_question_select.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/question_stable.png b/chrome/app/theme/default_200_percent/common/profile_menu_question_stable.png
similarity index 100%
rename from chrome/app/theme/default_200_percent/common/question_stable.png
rename to chrome/app/theme/default_200_percent/common/profile_menu_question_stable.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/speech_input_mic_empty.png b/chrome/app/theme/default_200_percent/common/speech_input_mic_empty.png
deleted file mode 100644
index 9830ae1..0000000
--- a/chrome/app/theme/default_200_percent/common/speech_input_mic_empty.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/speech_input_mic_full.png b/chrome/app/theme/default_200_percent/common/speech_input_mic_full.png
deleted file mode 100644
index d7943de..0000000
--- a/chrome/app/theme/default_200_percent/common/speech_input_mic_full.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/speech_input_mic_mask.png b/chrome/app/theme/default_200_percent/common/speech_input_mic_mask.png
deleted file mode 100644
index 73211f3..0000000
--- a/chrome/app/theme/default_200_percent/common/speech_input_mic_mask.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/speech_input_mic_noise.png b/chrome/app/theme/default_200_percent/common/speech_input_mic_noise.png
deleted file mode 100644
index 37d53aa..0000000
--- a/chrome/app/theme/default_200_percent/common/speech_input_mic_noise.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/speech_input_spinner.png b/chrome/app/theme/default_200_percent/common/speech_input_spinner.png
deleted file mode 100644
index 4e78e79..0000000
--- a/chrome/app/theme/default_200_percent/common/speech_input_spinner.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/cros/bluetooth_pairing_keyboard.png b/chrome/app/theme/default_200_percent/cros/bluetooth_pairing_keyboard.png
new file mode 100644
index 0000000..934bbef
--- /dev/null
+++ b/chrome/app/theme/default_200_percent/cros/bluetooth_pairing_keyboard.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/cros/bluetooth_pairing_mouse.png b/chrome/app/theme/default_200_percent/cros/bluetooth_pairing_mouse.png
new file mode 100644
index 0000000..2c5eba6
--- /dev/null
+++ b/chrome/app/theme/default_200_percent/cros/bluetooth_pairing_mouse.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/cros/bluetooth_pairing_tick.png b/chrome/app/theme/default_200_percent/cros/bluetooth_pairing_tick.png
new file mode 100644
index 0000000..9241f59
--- /dev/null
+++ b/chrome/app/theme/default_200_percent/cros/bluetooth_pairing_tick.png
Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd
index 42888f6..a55115e 100644
--- a/chrome/app/theme/theme_resources.grd
+++ b/chrome/app/theme/theme_resources.grd
@@ -111,7 +111,7 @@
       <structure type="chrome_scaled_image" name="IDR_BLOCKED_LOCATION" file="common/blocked_location.png" />
       <structure type="chrome_scaled_image" name="IDR_BLOCKED_MEDIA" file="common/blocked_media.png" />
       <structure type="chrome_scaled_image" name="IDR_SAVE_PASSWORD" file="common/save_password.png" />
-      <structure type="chrome_scaled_image" name="IDR_SAVE_PASSWORD_BLACKLISTED" file="common/blocked_images.png" />
+      <structure type="chrome_scaled_image" name="IDR_SAVE_PASSWORD_BLACKLISTED" file="common/blocked_save_passwords.png" />
       <structure type="chrome_scaled_image" name="IDR_BLOCKED_MIDI_SYSEX" file="common/blocked_midi.png" />
       <structure type="chrome_scaled_image" name="IDR_BLOCKED_MOUSE_CURSOR" file="common/blocked_mouse_cursor.png" />
       <structure type="chrome_scaled_image" name="IDR_BLOCKED_MIXED_CONTENT" file="common/blocked_mixed_content.png" />
@@ -119,6 +119,11 @@
       <structure type="chrome_scaled_image" name="IDR_BLOCKED_PLUGINS" file="common/blocked_plugins.png" />
       <structure type="chrome_scaled_image" name="IDR_BLOCKED_POPUPS" file="common/blocked_popups.png" />
       <structure type="chrome_scaled_image" name="IDR_BLOCKED_PPAPI_BROKER" file="common/blocked_pepper_broker.png" />
+      <if expr="chromeos">
+        <structure type="chrome_scaled_image" name="IDR_BLUETOOTH_KEYBOARD" file="cros/bluetooth_pairing_keyboard.png" />
+        <structure type="chrome_scaled_image" name="IDR_BLUETOOTH_MOUSE" file="cros/bluetooth_pairing_mouse.png" />
+        <structure type="chrome_scaled_image" name="IDR_BLUETOOTH_PAIRING_TICK" file="cros/bluetooth_pairing_tick.png" />
+      </if>
       <structure type="chrome_scaled_image" name="IDR_BOOKMARKS_FAVICON" file="common/favicon_bookmarks.png" />
       <structure type="chrome_scaled_image" name="IDR_BOOKMARK_BAR_CHEVRONS" file="common/chevron.png" />
       <if expr="is_macosx or is_ios">
@@ -359,6 +364,11 @@
         name="IDR_ICON_PROFILES_EDIT_HOVER" file="common/edit_button_hover.png" />
         <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_EDIT_PRESSED" file="common/edit_button_pressed.png" />
         <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_CARET" file="common/carrot_blue.png" />
+        <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_AVATAR_PHOTO_FRAME" file="common/avatar_photo_frame.png" />
+        <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_EDIT_CAMERA" file="common/edit_camera.png" />
+        <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_QUESTION_STABLE" file="common/profile_menu_question_stable.png" />
+        <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_QUESTION_HOVER" file="common/profile_menu_question_hover.png" />
+        <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_MENU_QUESTION_SELECT" file="common/profile_menu_question_select.png" />
       </if>
       <if expr="not is_android and not is_ios and not chromeos">
         <!-- User Manager tutorial -->
@@ -367,7 +377,6 @@
         <structure type="chrome_scaled_image" name="IDR_ICON_USER_MANAGER_TUTORIAL_GUESTS" file="common/user_manager_tutorial/guests.png" />
         <structure type="chrome_scaled_image" name="IDR_ICON_USER_MANAGER_TUTORIAL_FRIENDS" file="common/user_manager_tutorial/family_and_friends.png" />
         <structure type="chrome_scaled_image" name="IDR_ICON_USER_MANAGER_TUTORIAL_COMPLETE" file="common/user_manager_tutorial/complete.png" />
-
       </if>
       <if expr="chromeos">
         <structure type="chrome_scaled_image" name="IDR_ICON_ADD_USER_WHITE" file="icon_add_user_white.png" />
@@ -1074,11 +1083,6 @@
         <structure type="chrome_scaled_image" name="IDR_ORIGIN_CHIP_MALWARE_HOVER_TOP_RIGHT" file="common/chip_malware_hover_top_right.png" />
       </if>
       <structure type="chrome_scaled_image" name="IDR_SETTINGS_FAVICON" file="common/favicon_settings.png" />
-      <structure type="chrome_scaled_image" name="IDR_SPEECH_INPUT_MIC_EMPTY" file="common/speech_input_mic_empty.png" />
-      <structure type="chrome_scaled_image" name="IDR_SPEECH_INPUT_MIC_FULL" file="common/speech_input_mic_full.png" />
-      <structure type="chrome_scaled_image" name="IDR_SPEECH_INPUT_MIC_MASK" file="common/speech_input_mic_mask.png" />
-      <structure type="chrome_scaled_image" name="IDR_SPEECH_INPUT_MIC_NOISE" file="common/speech_input_mic_noise.png" />
-      <structure type="chrome_scaled_image" name="IDR_SPEECH_INPUT_SPINNER" file="common/speech_input_spinner.png" />
       <structure type="chrome_scaled_image" name="IDR_SHARE" file="share.png" />
       <structure type="chrome_scaled_image" name="IDR_STAR" file="star.png" />
       <structure type="chrome_scaled_image" name="IDR_STAR_LIT" file="star_lit.png" />
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 276e134..dccea18 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -14,12 +14,15 @@
   "+components/autofill/core/common",
   "+components/bookmarks/core/browser",
   "+components/bookmarks/core/common",
+  "+components/bookmarks/core/test",
   "+components/breakpad",
+  "+components/cdm/browser",
   "+components/cloud_devices/common",
   "+components/data_reduction_proxy",
   "+components/dom_distiller",
   "+components/domain_reliability",
   "+components/favicon_base",
+  "+components/feedback",
   "+components/infobars",
   "+components/keyed_service",
   "+components/language_usage_metrics",
diff --git a/chrome/browser/OWNERS b/chrome/browser/OWNERS
index c41f8c3..efcea34 100644
--- a/chrome/browser/OWNERS
+++ b/chrome/browser/OWNERS
@@ -18,3 +18,6 @@
 per-file shell_integration_win*=gab@chromium.org
 per-file shell_integration_win*=grt@chromium.org
 per-file shell_integration_linux*=erg@chromium.org
+
+per-file PRESUBMIT.py=dbeam@chromium.org
+per-file test_presubmit.py=dbeam@chromium.org
diff --git a/chrome/browser/PRESUBMIT.py b/chrome/browser/PRESUBMIT.py
new file mode 100644
index 0000000..a485728
--- /dev/null
+++ b/chrome/browser/PRESUBMIT.py
@@ -0,0 +1,69 @@
+# 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.
+
+"""Presubmit script for Chromium browser code.
+
+This script currently only checks HTML/CSS/JS files in resources/.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into gcl/git cl, and see
+http://www.chromium.org/developers/web-development-style-guide for the rules
+checked for here.
+"""
+
+
+def CheckChangeOnUpload(input_api, output_api):
+  return _CommonChecks(input_api, output_api)
+
+
+def CheckChangeOnCommit(input_api, output_api):
+  return _CommonChecks(input_api, output_api)
+
+
+def _CommonChecks(input_api, output_api):
+  """Checks common to both upload and commit."""
+  results = []
+
+  path = input_api.os_path
+  cwd = input_api.PresubmitLocalPath()
+  resources = path.join(cwd, 'resources')
+  webui = path.join(cwd, 'ui', 'webui')
+
+  affected_files = (f.AbsoluteLocalPath() for f in input_api.AffectedFiles())
+  would_affect_tests = (
+      path.join(cwd, 'PRESUBMIT.py'),
+      path.join(cwd, 'test_presubmit.py'),
+      path.join(cwd, 'web_dev_style', 'css_checker.py'),
+      path.join(cwd, 'web_dev_style', 'js_checker.py'),
+  )
+  if any(f for f in affected_files if f in would_affect_tests):
+    tests = [path.join(cwd, 'test_presubmit.py')]
+    results.extend(
+        input_api.canned_checks.RunUnitTests(input_api, output_api, tests))
+
+  import sys
+  old_path = sys.path
+
+  try:
+    sys.path = [cwd] + old_path
+    from web_dev_style import css_checker, js_checker
+
+    search_dirs = (resources, webui)
+    def _html_css_js_resource(p):
+      return p.endswith(('.html', '.css', '.js')) and p.startswith(search_dirs)
+
+    BLACKLIST = ['chrome/browser/resources/pdf/index.html',
+                 'chrome/browser/resources/pdf/index.js']
+    def is_resource(maybe_resource):
+      return (maybe_resource.LocalPath() not in BLACKLIST and
+          _html_css_js_resource(maybe_resource.AbsoluteLocalPath()))
+
+    results.extend(css_checker.CSSChecker(
+        input_api, output_api, file_filter=is_resource).RunChecks())
+    results.extend(js_checker.JSChecker(
+        input_api, output_api, file_filter=is_resource).RunChecks())
+  finally:
+    sys.path = old_path
+
+  return results
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index c55094f..ff62452 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -203,6 +203,14 @@
   { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, switches::kDisableLCDText, ""}
 };
 
+const Experiment::Choice kDistanceFieldTextChoices[] = {
+  { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" },
+  { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED,
+    switches::kEnableDistanceFieldText, "" },
+  { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED,
+    switches::kDisableDistanceFieldText, "" }
+};
+
 #ifndef USE_AURA
 const Experiment::Choice kDelegatedRendererChoices[] = {
   { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" },
@@ -392,6 +400,19 @@
 };
 #endif
 
+const Experiment::Choice kExtensionContentVerificationChoices[] = {
+  { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" },
+  { IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_BOOTSTRAP,
+    extensions::switches::kExtensionContentVerification,
+    extensions::switches::kExtensionContentVerificationBootstrap },
+  { IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_ENFORCE,
+    extensions::switches::kExtensionContentVerification,
+    extensions::switches::kExtensionContentVerificationEnforce },
+  { IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_ENFORCE_STRICT,
+    extensions::switches::kExtensionContentVerification,
+    extensions::switches::kExtensionContentVerificationEnforceStrict },
+};
+
 // RECORDING USER METRICS FOR FLAGS:
 // -----------------------------------------------------------------------------
 // The first line of the experiment is the internal name. If you'd like to
@@ -1042,14 +1063,6 @@
     kOsAll,
     SINGLE_VALUE_TYPE(ash::switches::kAshDebugShortcuts),
   },
-  { "ash-alternate-caption-button",
-    IDS_FLAGS_ASH_FRAME_CAPTION_BUTTON_STYLE_NAME,
-    IDS_FLAGS_ASH_FRAME_CAPTION_BUTTON_STYLE_DESCRIPTION,
-    kOsCrOS,
-    ENABLE_DISABLE_VALUE_TYPE(
-        ash::switches::kAshEnableAlternateFrameCaptionButtonStyle,
-        ash::switches::kAshDisableAlternateFrameCaptionButtonStyle),
-  },
   { "ash-enable-touch-view-testing",
     IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_NAME,
     IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_DESCRIPTION,
@@ -1243,7 +1256,16 @@
     IDS_FLAGS_ENABLE_OFFLINE_AUTO_RELOAD_NAME,
     IDS_FLAGS_ENABLE_OFFLINE_AUTO_RELOAD_DESCRIPTION,
     kOsAll,
-    SINGLE_VALUE_TYPE(switches::kEnableOfflineAutoReload)
+    ENABLE_DISABLE_VALUE_TYPE(switches::kEnableOfflineAutoReload,
+                              switches::kDisableOfflineAutoReload)
+  },
+  {
+    "enable-offline-load-stale-cache",
+    IDS_FLAGS_ENABLE_OFFLINE_LOAD_STALE_NAME,
+    IDS_FLAGS_ENABLE_OFFLINE_LOAD_STALE_DESCRIPTION,
+    kOsLinux | kOsMac | kOsWin | kOsAndroid,
+    ENABLE_DISABLE_VALUE_TYPE(switches::kEnableOfflineLoadStaleCache,
+                              switches::kDisableOfflineLoadStaleCache)
   },
   {
     "default-tile-width",
@@ -1668,7 +1690,7 @@
     "search-button-in-omnibox",
     IDS_FLAGS_SEARCH_BUTTON_IN_OMNIBOX_NAME,
     IDS_FLAGS_SEARCH_BUTTON_IN_OMNIBOX_DESCRIPTION,
-    kOsCrOS | kOsMac | kOsWin,
+    kOsCrOS | kOsMac | kOsWin | kOsLinux,
     MULTI_VALUE_TYPE(kSearchButtonInOmniboxChoices)
   },
   {
@@ -1732,11 +1754,11 @@
     SINGLE_VALUE_TYPE(app_list::switches::kEnableExperimentalAppList)
   },
   {
-    "enable-experimental-app-list-position",
-    IDS_FLAGS_ENABLE_EXPERIMENTAL_APP_LIST_POSITION_NAME,
-    IDS_FLAGS_ENABLE_EXPERIMENTAL_APP_LIST_POSITION_DESCRIPTION,
+    "enable-centered-app-list",
+    IDS_FLAGS_ENABLE_CENTERED_APP_LIST_NAME,
+    IDS_FLAGS_ENABLE_CENTERED_APP_LIST_DESCRIPTION,
     kOsWin | kOsLinux | kOsCrOS,
-    SINGLE_VALUE_TYPE(app_list::switches::kEnableExperimentalAppListPosition)
+    SINGLE_VALUE_TYPE(app_list::switches::kEnableCenteredAppList)
   },
 #endif
   {
@@ -1835,6 +1857,37 @@
     kOsAndroid,
     SINGLE_VALUE_TYPE(switches::kEnableEmbeddedSearchAPI)
   },
+  {
+    "enable-app-install-alerts",
+    IDS_FLAGS_ENABLE_APP_INSTALL_ALERTS_NAME,
+    IDS_FLAGS_ENABLE_APP_INSTALL_ALERTS_DESCRIPTION,
+    kOsAndroid,
+    SINGLE_VALUE_TYPE(switches::kEnableAppInstallAlerts)
+  },
+#endif
+  {
+    "distance-field-text",
+    IDS_FLAGS_DISTANCE_FIELD_TEXT_NAME,
+    IDS_FLAGS_DISTANCE_FIELD_TEXT_DESCRIPTION,
+    kOsAll,
+    MULTI_VALUE_TYPE(kDistanceFieldTextChoices)
+  },
+  {
+    "extension-content-verification",
+    IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_NAME,
+    IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_DESCRIPTION,
+    kOsDesktop,
+    MULTI_VALUE_TYPE(kExtensionContentVerificationChoices)
+  },
+#if defined(USE_AURA)
+  {
+    "text-input-focus-manager",
+    IDS_FLAGS_TEXT_INPUT_FOCUS_MANAGER_NAME,
+    IDS_FLAGS_TEXT_INPUT_FOCUS_MANAGER_DESCRIPTION,
+    kOsCrOS | kOsLinux | kOsWin,
+    ENABLE_DISABLE_VALUE_TYPE(switches::kEnableTextInputFocusManager,
+                              switches::kDisableTextInputFocusManager)
+  },
 #endif
 };
 
diff --git a/chrome/browser/accessibility/accessibility_extension_api.cc b/chrome/browser/accessibility/accessibility_extension_api.cc
index 26020dc..d77cee0 100644
--- a/chrome/browser/accessibility/accessibility_extension_api.cc
+++ b/chrome/browser/accessibility/accessibility_extension_api.cc
@@ -14,7 +14,7 @@
 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/extensions/api/experimental_accessibility.h"
+#include "chrome/common/extensions/api/accessibility_private.h"
 #include "components/infobars/core/infobar.h"
 #include "content/public/browser/browser_accessibility_state.h"
 #include "extensions/browser/event_router.h"
@@ -25,8 +25,7 @@
 #include "extensions/common/manifest_handlers/background_info.h"
 
 namespace keys = extension_accessibility_api_constants;
-namespace experimental_accessibility =
-    extensions::api::experimental_accessibility;
+namespace accessibility_private = extensions::api::accessibility_private;
 
 // Returns the AccessibilityControlInfo serialized into a JSON string,
 // consisting of an array of a single object of type AccessibilityObject,
@@ -129,7 +128,7 @@
     const AccessibilityWindowInfo* info) {
   scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
   DispatchEvent(info->profile(),
-                experimental_accessibility::OnWindowOpened::kEventName,
+                accessibility_private::OnWindowOpened::kEventName,
                 args.Pass());
 }
 
@@ -139,7 +138,7 @@
   info->SerializeToDict(&last_focused_control_dict_);
   scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
   DispatchEvent(info->profile(),
-                experimental_accessibility::OnControlFocused::kEventName,
+                accessibility_private::OnControlFocused::kEventName,
                 args.Pass());
 }
 
@@ -147,7 +146,7 @@
     const AccessibilityControlInfo* info) {
   scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
   DispatchEvent(info->profile(),
-                experimental_accessibility::OnControlAction::kEventName,
+                accessibility_private::OnControlAction::kEventName,
                 args.Pass());
 }
 
@@ -155,7 +154,7 @@
     const AccessibilityControlInfo* info) {
   scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
   DispatchEvent(info->profile(),
-                experimental_accessibility::OnTextChanged::kEventName,
+                accessibility_private::OnTextChanged::kEventName,
                 args.Pass());
 }
 
@@ -163,7 +162,7 @@
     const AccessibilityMenuInfo* info) {
   scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
   DispatchEvent(info->profile(),
-                experimental_accessibility::OnMenuOpened::kEventName,
+                accessibility_private::OnMenuOpened::kEventName,
                 args.Pass());
 }
 
@@ -171,7 +170,7 @@
     const AccessibilityMenuInfo* info) {
   scoped_ptr<base::ListValue> args(ControlInfoToEventArguments(info));
   DispatchEvent(info->profile(),
-                experimental_accessibility::OnMenuClosed::kEventName,
+                accessibility_private::OnMenuClosed::kEventName,
                 args.Pass());
 }
 
@@ -182,8 +181,9 @@
   scoped_ptr<base::ListValue> event_args(new base::ListValue());
   event_args->Append(base::Value::CreateBooleanValue(loading));
   event_args->Append(base::Value::CreateBooleanValue(make_announcements));
-  ExtensionAccessibilityEventRouter::DispatchEventToChromeVox(profile,
-      experimental_accessibility::OnChromeVoxLoadStateChanged::kEventName,
+  ExtensionAccessibilityEventRouter::DispatchEventToChromeVox(
+      profile,
+      accessibility_private::OnChromeVoxLoadStateChanged::kEventName,
       event_args.Pass());
 }
 
@@ -217,7 +217,7 @@
   event_router->BroadcastEvent(event.Pass());
 }
 
-bool AccessibilitySetAccessibilityEnabledFunction::RunSync() {
+bool AccessibilityPrivateSetAccessibilityEnabledFunction::RunSync() {
   bool enabled;
   EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
   ExtensionAccessibilityEventRouter::GetInstance()
@@ -225,7 +225,7 @@
   return true;
 }
 
-bool AccessibilitySetNativeAccessibilityEnabledFunction::RunSync() {
+bool AccessibilityPrivateSetNativeAccessibilityEnabledFunction::RunSync() {
   bool enabled;
   EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
   if (enabled) {
@@ -238,7 +238,7 @@
   return true;
 }
 
-bool AccessibilityGetFocusedControlFunction::RunSync() {
+bool AccessibilityPrivateGetFocusedControlFunction::RunSync() {
   // Get the serialized dict from the last focused control and return it.
   // However, if the dict is empty, that means we haven't seen any focus
   // events yet, so return null instead.
@@ -254,7 +254,7 @@
   return true;
 }
 
-bool AccessibilityGetAlertsForTabFunction::RunSync() {
+bool AccessibilityPrivateGetAlertsForTabFunction::RunSync() {
   int tab_id;
   EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id));
 
diff --git a/chrome/browser/accessibility/accessibility_extension_api.h b/chrome/browser/accessibility/accessibility_extension_api.h
index 7357187..c56a29b 100644
--- a/chrome/browser/accessibility/accessibility_extension_api.h
+++ b/chrome/browser/accessibility/accessibility_extension_api.h
@@ -98,43 +98,40 @@
 // API function that enables or disables accessibility support.  Event
 // listeners are only installed when accessibility support is enabled, to
 // minimize the impact.
-class AccessibilitySetAccessibilityEnabledFunction
+class AccessibilityPrivateSetAccessibilityEnabledFunction
     : public ChromeSyncExtensionFunction {
-  virtual ~AccessibilitySetAccessibilityEnabledFunction() {}
+  virtual ~AccessibilityPrivateSetAccessibilityEnabledFunction() {}
   virtual bool RunSync() OVERRIDE;
-  DECLARE_EXTENSION_FUNCTION(
-      "experimental.accessibility.setAccessibilityEnabled",
-      EXPERIMENTAL_ACCESSIBILITY_SETACCESSIBILITYENABLED)
+  DECLARE_EXTENSION_FUNCTION("accessibilityPrivate.setAccessibilityEnabled",
+                             EXPERIMENTAL_ACCESSIBILITY_SETACCESSIBILITYENABLED)
 };
 
 // API function that enables or disables web content accessibility support.
-class AccessibilitySetNativeAccessibilityEnabledFunction
+class AccessibilityPrivateSetNativeAccessibilityEnabledFunction
     : public ChromeSyncExtensionFunction {
-  virtual ~AccessibilitySetNativeAccessibilityEnabledFunction() {}
+  virtual ~AccessibilityPrivateSetNativeAccessibilityEnabledFunction() {}
   virtual bool RunSync() OVERRIDE;
   DECLARE_EXTENSION_FUNCTION(
-      "experimental.accessibility.setNativeAccessibilityEnabled",
+      "accessibilityPrivate.setNativeAccessibilityEnabled",
       EXPERIMENTAL_ACCESSIBILITY_SETNATIVEACCESSIBILITYENABLED)
 };
 
 // API function that returns the most recent focused control.
-class AccessibilityGetFocusedControlFunction
+class AccessibilityPrivateGetFocusedControlFunction
     : public ChromeSyncExtensionFunction {
-  virtual ~AccessibilityGetFocusedControlFunction() {}
+  virtual ~AccessibilityPrivateGetFocusedControlFunction() {}
   virtual bool RunSync() OVERRIDE;
-  DECLARE_EXTENSION_FUNCTION(
-      "experimental.accessibility.getFocusedControl",
-      EXPERIMENTAL_ACCESSIBILITY_GETFOCUSEDCONTROL)
+  DECLARE_EXTENSION_FUNCTION("accessibilityPrivate.getFocusedControl",
+                             EXPERIMENTAL_ACCESSIBILITY_GETFOCUSEDCONTROL)
 };
 
 // API function that returns alerts being shown on the give tab.
-class AccessibilityGetAlertsForTabFunction
+class AccessibilityPrivateGetAlertsForTabFunction
     : public ChromeSyncExtensionFunction {
-  virtual ~AccessibilityGetAlertsForTabFunction() {}
+  virtual ~AccessibilityPrivateGetAlertsForTabFunction() {}
   virtual bool RunSync() OVERRIDE;
-  DECLARE_EXTENSION_FUNCTION(
-      "experimental.accessibility.getAlertsForTab",
-      EXPERIMENTAL_ACCESSIBILITY_GETALERTSFORTAB)
+  DECLARE_EXTENSION_FUNCTION("accessibilityPrivate.getAlertsForTab",
+                             EXPERIMENTAL_ACCESSIBILITY_GETALERTSFORTAB)
 };
 
 #endif  // CHROME_BROWSER_ACCESSIBILITY_ACCESSIBILITY_EXTENSION_API_H_
diff --git a/chrome/browser/accessibility/accessibility_extension_apitest.cc b/chrome/browser/accessibility/accessibility_extension_apitest.cc
index 7282a76..55a9aa0 100644
--- a/chrome/browser/accessibility/accessibility_extension_apitest.cc
+++ b/chrome/browser/accessibility/accessibility_extension_apitest.cc
@@ -38,5 +38,6 @@
                                      base::ASCIIToUTF16(kAlertMessage), false);
   CommandLine::ForCurrentProcess()->AppendSwitch(
       extensions::switches::kEnableExperimentalExtensionApis);
-  ASSERT_TRUE(RunExtensionTest("accessibility/get_alerts_for_tab")) << message_;
+  ASSERT_TRUE(RunComponentExtensionTest("accessibility/get_alerts_for_tab"))
+      << message_;
 }
diff --git a/chrome/browser/android/banners/app_banner_manager.cc b/chrome/browser/android/banners/app_banner_manager.cc
index 704c1ac..d8bb86d 100644
--- a/chrome/browser/android/banners/app_banner_manager.cc
+++ b/chrome/browser/android/banners/app_banner_manager.cc
@@ -6,17 +6,20 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
+#include "base/command_line.h"
 #include "base/metrics/histogram.h"
 #include "chrome/browser/android/banners/app_banner_metrics_ids.h"
 #include "chrome/browser/android/banners/app_banner_settings_helper.h"
 #include "chrome/browser/android/banners/app_banner_utilities.h"
 #include "chrome/browser/bitmap_fetcher.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_switches.h"
 #include "content/public/browser/android/content_view_core.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/frame_navigate_params.h"
 #include "jni/AppBannerManager_jni.h"
+#include "net/base/load_flags.h"
 #include "ui/gfx/android/java_bitmap.h"
 
 using base::android::ConvertJavaStringToUTF8;
@@ -132,7 +135,11 @@
   Profile* profile =
       Profile::FromBrowserContext(web_contents()->GetBrowserContext());
   fetcher_.reset(new chrome::BitmapFetcher(GURL(image_url), this));
-  fetcher_.get()->Start(profile->GetRequestContext());
+  fetcher_.get()->Start(
+      profile->GetRequestContext(),
+      std::string(),
+      net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+      net::LOAD_NORMAL);
   return true;
 }
 
@@ -150,7 +157,8 @@
 }
 
 jboolean IsEnabled(JNIEnv* env, jclass clazz) {
-  return false;
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kEnableAppInstallAlerts);
 }
 
 // Register native methods
diff --git a/chrome/browser/android/bookmarks/bookmarks_bridge.cc b/chrome/browser/android/bookmarks/bookmarks_bridge.cc
index a71c615..90dfca3 100644
--- a/chrome/browser/android/bookmarks/bookmarks_bridge.cc
+++ b/chrome/browser/android/bookmarks/bookmarks_bridge.cc
@@ -405,7 +405,8 @@
 void BookmarksBridge::BookmarkNodeRemoved(BookmarkModel* model,
                                           const BookmarkNode* parent,
                                           int old_index,
-                                          const BookmarkNode* node) {
+                                          const BookmarkNode* node,
+                                          const std::set<GURL>& removed_urls) {
   if (!IsLoaded())
     return;
 
diff --git a/chrome/browser/android/bookmarks/bookmarks_bridge.h b/chrome/browser/android/bookmarks/bookmarks_bridge.h
index 9512df7..f4a52aa 100644
--- a/chrome/browser/android/bookmarks/bookmarks_bridge.h
+++ b/chrome/browser/android/bookmarks/bookmarks_bridge.h
@@ -90,7 +90,8 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE;
   virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc b/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc
index 8141bbb..a8caa96 100644
--- a/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc
+++ b/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc
@@ -8,9 +8,9 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/android/chrome_startup_flags.cc b/chrome/browser/android/chrome_startup_flags.cc
index 93ee6cc..88c2e23 100644
--- a/chrome/browser/android/chrome_startup_flags.cc
+++ b/chrome/browser/android/chrome_startup_flags.cc
@@ -52,11 +52,4 @@
       channel == chrome::VersionInfo::CHANNEL_DEV) {
     SetCommandLineSwitch(switches::kEnableDomDistiller);
   }
-
-  // Enable the Fast Text Autosizer on local builds, canary and dev-channel.
-  if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN ||
-      channel == chrome::VersionInfo::CHANNEL_CANARY ||
-      channel == chrome::VersionInfo::CHANNEL_DEV) {
-    SetCommandLineSwitch(switches::kEnableFastTextAutosizing);
-  }
 }
diff --git a/chrome/browser/android/dev_tools_server.cc b/chrome/browser/android/dev_tools_server.cc
index b89a0c1..246218e 100644
--- a/chrome/browser/android/dev_tools_server.cc
+++ b/chrome/browser/android/dev_tools_server.cc
@@ -19,7 +19,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/android/tab_android.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/devtools/device/devtools_android_bridge.h"
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/android/tab_model/tab_model.h"
@@ -50,6 +49,17 @@
 
 namespace {
 
+// TL;DR: Do not change this string.
+//
+// Desktop Chrome relies on this format to identify debuggable apps on Android
+// (see the code under chrome/browser/devtools/device).
+// If this string ever changes it would not be sufficient to change the
+// corresponding string on the client side. Since debugging an older version of
+// Chrome for Android from a newer version of desktop Chrome is a very common
+// scenario, the client code will have to be modified to recognize both the old
+// and the new format.
+const char kDevToolsChannelNameFormat[] = "%s_devtools_remote";
+
 const char kFrontEndURL[] =
     "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html";
 const char kDefaultSocketNamePrefix[] = "chrome";
@@ -58,7 +68,7 @@
 const char kTargetTypePage[] = "page";
 const char kTargetTypeOther[] = "other";
 
-static GURL GetFaviconURL(WebContents* web_contents) {
+static GURL GetFaviconURLForContents(WebContents* web_contents) {
   content::NavigationController& controller = web_contents->GetController();
   content::NavigationEntry* entry = controller.GetActiveEntry();
   if (entry != NULL && entry->GetURL().is_valid())
@@ -73,9 +83,9 @@
 
   virtual std::string GetDescription() const OVERRIDE { return std::string(); }
 
-  virtual GURL GetUrl() const OVERRIDE { return url_; }
+  virtual GURL GetURL() const OVERRIDE { return url_; }
 
-  virtual GURL GetFaviconUrl() const OVERRIDE { return favicon_url_; }
+  virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; }
 
   virtual base::TimeTicks GetLastActivityTime() const OVERRIDE {
     return last_activity_time_;
@@ -85,7 +95,7 @@
   explicit TargetBase(WebContents* web_contents)
       : title_(base::UTF16ToUTF8(web_contents->GetTitle())),
         url_(web_contents->GetURL()),
-        favicon_url_(GetFaviconURL(web_contents)),
+        favicon_url_(GetFaviconURLForContents(web_contents)),
         last_activity_time_(web_contents->GetLastActiveTime()) {
   }
 
diff --git a/chrome/browser/android/favicon_helper.cc b/chrome/browser/android/favicon_helper.cc
index f6ae96c..07840d8 100644
--- a/chrome/browser/android/favicon_helper.cc
+++ b/chrome/browser/android/favicon_helper.cc
@@ -7,6 +7,7 @@
 #include <jni.h>
 
 #include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/bind.h"
@@ -23,6 +24,7 @@
 #include "jni/FaviconHelper_jni.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/android/java_bitmap.h"
+#include "ui/gfx/codec/png_codec.h"
 #include "ui/gfx/color_analysis.h"
 #include "ui/gfx/color_utils.h"
 
@@ -55,6 +57,32 @@
                                                j_icon_url.obj());
 }
 
+void OnFaviconBitmapResultAvailable(
+    ScopedJavaGlobalRef<jobject>* j_favicon_image_callback,
+    const favicon_base::FaviconBitmapResult& favicon_bitmap_result) {
+  JNIEnv* env = AttachCurrentThread();
+
+  // Convert favicon_image_result to java objects.
+  ScopedJavaLocalRef<jstring> j_icon_url =
+      ConvertUTF8ToJavaString(env, favicon_bitmap_result.icon_url.spec());
+
+  SkBitmap favicon_bitmap;
+  if (favicon_bitmap_result.is_valid()) {
+    gfx::PNGCodec::Decode(favicon_bitmap_result.bitmap_data->front(),
+                          favicon_bitmap_result.bitmap_data->size(),
+                          &favicon_bitmap);
+  }
+  ScopedJavaLocalRef<jobject> j_favicon_bitmap;
+  if (!favicon_bitmap.isNull())
+    j_favicon_bitmap = gfx::ConvertToJavaBitmap(&favicon_bitmap);
+
+  // Call java side OnLocalFaviconAvailable method.
+  Java_FaviconImageCallback_onFaviconAvailable(env,
+                                               j_favicon_image_callback->obj(),
+                                               j_favicon_bitmap.obj(),
+                                               j_icon_url.obj());
+}
+
 }  // namespace
 
 static jlong Init(JNIEnv* env, jclass clazz) {
@@ -107,6 +135,43 @@
   return true;
 }
 
+void FaviconHelper::GetLargestRawFaviconForUrl(
+    JNIEnv* env,
+    jobject obj,
+    jobject j_profile,
+    jstring j_page_url,
+    jintArray j_icon_types,
+    jint j_min_size_threshold_px,
+    jobject j_favicon_image_callback) {
+  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
+  DCHECK(profile);
+  if (!profile)
+    return;
+
+  FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
+      profile, Profile::EXPLICIT_ACCESS);
+  DCHECK(favicon_service);
+  if (!favicon_service)
+    return;
+
+  std::vector<int> icon_types;
+  base::android::JavaIntArrayToIntVector(env, j_icon_types, &icon_types);
+
+  ScopedJavaGlobalRef<jobject>* j_scoped_favicon_callback =
+      new ScopedJavaGlobalRef<jobject>();
+  j_scoped_favicon_callback->Reset(env, j_favicon_image_callback);
+
+  FaviconService::FaviconRawCallback callback_runner = base::Bind(
+      &OnFaviconBitmapResultAvailable, base::Owned(j_scoped_favicon_callback));
+  favicon_service->GetLargestRawFaviconForURL(
+      profile,
+      GURL(ConvertJavaStringToUTF16(env, j_page_url)),
+      icon_types,
+      static_cast<int>(j_min_size_threshold_px),
+      callback_runner,
+      cancelable_task_tracker_.get());
+}
+
 ScopedJavaLocalRef<jobject> FaviconHelper::GetSyncedFaviconImageForURL(
     JNIEnv* env,
     jobject obj,
@@ -129,7 +194,7 @@
   if (!open_tabs->GetSyncedFaviconForPageURL(page_url, &favicon_png))
     return ScopedJavaLocalRef<jobject>();
 
-    // Convert favicon_image_result to java objects.
+  // Convert favicon_image_result to java objects.
   gfx::Image favicon_image = gfx::Image::CreateFrom1xPNGBytes(favicon_png);
   SkBitmap favicon_bitmap = favicon_image.AsBitmap();
 
diff --git a/chrome/browser/android/favicon_helper.h b/chrome/browser/android/favicon_helper.h
index 6c22975..377eaa5 100644
--- a/chrome/browser/android/favicon_helper.h
+++ b/chrome/browser/android/favicon_helper.h
@@ -22,6 +22,13 @@
                                       jint j_icon_types,
                                       jint j_desired_size_in_dip,
                                       jobject j_favicon_image_callback);
+  void GetLargestRawFaviconForUrl(JNIEnv* env,
+                                  jobject obj,
+                                  jobject j_profile,
+                                  jstring j_page_url,
+                                  jintArray j_icon_types,
+                                  jint j_min_size_threshold_px,
+                                  jobject j_favicon_image_callback);
   base::android::ScopedJavaLocalRef<jobject> GetSyncedFaviconImageForURL(
       JNIEnv* env,
       jobject obj,
diff --git a/chrome/browser/android/logo_service.cc b/chrome/browser/android/logo_service.cc
index 266d226..3dea449 100644
--- a/chrome/browser/android/logo_service.cc
+++ b/chrome/browser/android/logo_service.cc
@@ -6,6 +6,7 @@
 
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/google/google_url_tracker.h"
+#include "chrome/browser/google/google_util.h"
 #include "chrome/browser/image_decoder.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url_service.h"
@@ -35,7 +36,11 @@
   std::string path = kGoogleDoodleURLPath;
   GURL::Replacements replacements;
   replacements.SetPathStr(path);
-  return GoogleURLTracker::GoogleURL(profile).ReplaceComponents(replacements);
+
+  GURL base_url(google_util::CommandLineGoogleBaseURL());
+  if (!base_url.is_valid())
+    base_url = GoogleURLTracker::GoogleURL(profile);
+  return base_url.ReplaceComponents(replacements);
 }
 
 class LogoDecoderDelegate : public ImageDecoder::Delegate {
diff --git a/chrome/browser/android/most_visited_sites.cc b/chrome/browser/android/most_visited_sites.cc
index cf20d4b..968f5cb 100644
--- a/chrome/browser/android/most_visited_sites.cc
+++ b/chrome/browser/android/most_visited_sites.cc
@@ -17,8 +17,11 @@
 #include "chrome/browser/search/suggestions/proto/suggestions.pb.h"
 #include "chrome/browser/search/suggestions/suggestions_service.h"
 #include "chrome/browser/search/suggestions/suggestions_service_factory.h"
+#include "chrome/browser/search/suggestions/suggestions_source.h"
+#include "chrome/browser/thumbnails/thumbnail_list_source.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_source.h"
+#include "content/public/browser/url_data_source.h"
 #include "jni/MostVisitedSites_jni.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/android/java_bitmap.h"
@@ -124,6 +127,11 @@
 
 MostVisitedSites::MostVisitedSites(Profile* profile)
     : profile_(profile), num_sites_(0), weak_ptr_factory_(this) {
+  // Register the debugging page for the Suggestions Service and the thumbnails
+  // debugging page.
+  content::URLDataSource::Add(profile_,
+                              new suggestions::SuggestionsSource(profile_));
+  content::URLDataSource::Add(profile_, new ThumbnailListSource(profile_));
 }
 
 MostVisitedSites::~MostVisitedSites() {
diff --git a/chrome/browser/android/omnibox/omnibox_prerender.cc b/chrome/browser/android/omnibox/omnibox_prerender.cc
index 05e1636..67bb950 100644
--- a/chrome/browser/android/omnibox/omnibox_prerender.cc
+++ b/chrome/browser/android/omnibox/omnibox_prerender.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_android.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "jni/OmniboxPrerender_jni.h"
 #include "url/gurl.h"
 
@@ -135,8 +134,7 @@
   DCHECK(web_contents);
   if (!web_contents)
     return;
-  gfx::Rect container_bounds;
-  web_contents->GetView()->GetContainerBounds(&container_bounds);
+  gfx::Rect container_bounds = web_contents->GetContainerBounds();
   predictors::AutocompleteActionPredictorFactory::GetForProfile(profile)->
       StartPrerendering(
           match.destination_url,
diff --git a/chrome/browser/android/provider/bookmark_model_observer_task.cc b/chrome/browser/android/provider/bookmark_model_observer_task.cc
index 1341be1..867dcab 100644
--- a/chrome/browser/android/provider/bookmark_model_observer_task.cc
+++ b/chrome/browser/android/provider/bookmark_model_observer_task.cc
@@ -47,16 +47,22 @@
                                                   int index) {
 }
 
-void BookmarkModelObserverTask::BookmarkNodeRemoved(BookmarkModel* model,
-                                                    const BookmarkNode* parent,
-                                                    int old_index,
-                                                    const BookmarkNode* node) {
+void BookmarkModelObserverTask::BookmarkNodeRemoved(
+    BookmarkModel* model,
+    const BookmarkNode* parent,
+    int old_index,
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {
 }
 
-void BookmarkModelObserverTask::BookmarkAllNodesRemoved(BookmarkModel* model) {}
+void BookmarkModelObserverTask::BookmarkAllNodesRemoved(
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
+}
 
 void BookmarkModelObserverTask::BookmarkNodeChanged(BookmarkModel* model,
-                                                    const BookmarkNode* node) {}
+                                                    const BookmarkNode* node) {
+}
 
 void BookmarkModelObserverTask::BookmarkNodeFaviconChanged(
     BookmarkModel* model,
diff --git a/chrome/browser/android/provider/bookmark_model_observer_task.h b/chrome/browser/android/provider/bookmark_model_observer_task.h
index 8c00f46..9155537 100644
--- a/chrome/browser/android/provider/bookmark_model_observer_task.h
+++ b/chrome/browser/android/provider/bookmark_model_observer_task.h
@@ -44,8 +44,11 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE;
   virtual void BookmarkNodeFaviconChanged(BookmarkModel* model,
diff --git a/chrome/browser/android/provider/chrome_browser_provider.cc b/chrome/browser/android/provider/chrome_browser_provider.cc
index db0dd7a..0589117 100644
--- a/chrome/browser/android/provider/chrome_browser_provider.cc
+++ b/chrome/browser/android/provider/chrome_browser_provider.cc
@@ -264,10 +264,12 @@
   }
 
   // Verify that the bookmark was actually removed. Called synchronously.
-  virtual void BookmarkNodeRemoved(BookmarkModel* bookmark_model,
-                                   const BookmarkNode* parent,
-                                   int old_index,
-                                   const BookmarkNode* node) OVERRIDE {
+  virtual void BookmarkNodeRemoved(
+      BookmarkModel* bookmark_model,
+      const BookmarkNode* parent,
+      int old_index,
+      const BookmarkNode* node,
+      const std::set<GURL>& removed_urls) OVERRIDE {
     if (bookmark_model == model() && node->id() == id_to_delete_)
         ++deleted_;
   }
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc
index 4539402..7a010b1 100644
--- a/chrome/browser/android/shortcut_helper.cc
+++ b/chrome/browser/android/shortcut_helper.cc
@@ -114,7 +114,7 @@
   return handled;
 }
 
-void ShortcutBuilder::WebContentsDestroyed(content::WebContents* web_contents) {
+void ShortcutBuilder::WebContentsDestroyed() {
   Destroy();
 }
 
diff --git a/chrome/browser/android/shortcut_helper.h b/chrome/browser/android/shortcut_helper.h
index 4be5c30..9e4e13c 100644
--- a/chrome/browser/android/shortcut_helper.h
+++ b/chrome/browser/android/shortcut_helper.h
@@ -57,8 +57,7 @@
 
   // WebContentsObserver
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-  virtual void WebContentsDestroyed(content::WebContents* web_contents)
-      OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
  private:
   void Destroy();
diff --git a/chrome/browser/android/signin/signin_manager_android.cc b/chrome/browser/android/signin/signin_manager_android.cc
index e754e91..acc4ec7 100644
--- a/chrome/browser/android/signin/signin_manager_android.cc
+++ b/chrome/browser/android/signin/signin_manager_android.cc
@@ -28,8 +28,8 @@
 
 #if defined(ENABLE_CONFIGURATION_POLICY)
 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
-#include "chrome/browser/policy/cloud/user_policy_signin_service_android.h"
 #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
+#include "chrome/browser/policy/cloud/user_policy_signin_service_mobile.h"
 #include "components/policy/core/browser/browser_policy_connector.h"
 #include "components/policy/core/common/cloud/cloud_policy_core.h"
 #include "components/policy/core/common/cloud/cloud_policy_store.h"
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc
index a362bf2..f831f21 100644
--- a/chrome/browser/android/tab_android.cc
+++ b/chrome/browser/android/tab_android.cc
@@ -177,26 +177,6 @@
   NOTIMPLEMENTED();
 }
 
-void TabAndroid::AddShortcutToBookmark(const GURL& url,
-                                       const base::string16& title,
-                                       const SkBitmap& skbitmap,
-                                       int r_value,
-                                       int g_value,
-                                       int b_value) {
-  NOTREACHED();
-}
-
-void TabAndroid::EditBookmark(int64 node_id,
-                              const base::string16& node_title,
-                              bool is_folder,
-                              bool is_partner_bookmark) {
-  NOTREACHED();
-}
-
-void TabAndroid::OnNewTabPageReady() {
-  NOTREACHED();
-}
-
 bool TabAndroid::ShouldWelcomePageLinkToTermsOfService() {
   NOTIMPLEMENTED();
   return false;
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h
index 1727afb..9435eca 100644
--- a/chrome/browser/android/tab_android.h
+++ b/chrome/browser/android/tab_android.h
@@ -98,24 +98,6 @@
                                          const base::string16& host,
                                          const base::string16& realm);
 
-  // Called when context menu option to create the bookmark shortcut on
-  // homescreen is called.
-  virtual void AddShortcutToBookmark(const GURL& url,
-                                     const base::string16& title,
-                                     const SkBitmap& skbitmap,
-                                     int r_value,
-                                     int g_value,
-                                     int b_value);
-
-  // Called when a bookmark node should be edited.
-  virtual void EditBookmark(int64 node_id,
-                            const base::string16& node_title,
-                            bool is_folder,
-                            bool is_partner_bookmark);
-
-  // Called to notify that the new tab page has completely rendered.
-  virtual void OnNewTabPageReady();
-
   // Called to determine if chrome://welcome should contain links to the terms
   // of service and the privacy notice.
   virtual bool ShouldWelcomePageLinkToTermsOfService();
diff --git a/chrome/browser/apps/app_browsertest.cc b/chrome/browser/apps/app_browsertest.cc
index 34591b8..6f1833e 100644
--- a/chrome/browser/apps/app_browsertest.cc
+++ b/chrome/browser/apps/app_browsertest.cc
@@ -38,7 +38,6 @@
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_widget_host_view.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/test_utils.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_system.h"
@@ -142,9 +141,9 @@
   }
 
   // PrintPreviewUI::TestingDelegate implementation.
-  virtual void DidRenderPreviewPage(const content::WebContents& preview_dialog)
+  virtual void DidRenderPreviewPage(content::WebContents* preview_dialog)
       OVERRIDE {
-    dialog_size_ = preview_dialog.GetView()->GetContainerSize();
+    dialog_size_ = preview_dialog->GetContainerBounds().size();
     ++rendered_page_count_;
     CHECK(rendered_page_count_ <= total_page_count_);
     if (waiting_runner_ && rendered_page_count_ == total_page_count_) {
@@ -547,6 +546,16 @@
       << message_;
 }
 
+// Tests that launch data is sent through to a whitelisted extension if the file
+// extension matches.
+IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
+                       LaunchWhiteListedExtensionWithFile) {
+  SetCommandLineArg(kTestFilePath);
+  ASSERT_TRUE(RunPlatformAppTest(
+      "platform_apps/launch_whitelisted_ext_with_file"))
+          << message_;
+}
+
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
 // TODO(erg): linux_aura bringup: http://crbug.com/163931
 #define MAYBE_LaunchWithFileExtensionAndMimeType DISABLED_LaunchWithFileExtensionAndMimeType
@@ -1184,10 +1193,8 @@
 
   // AppWindowRegistry::Observer implementation.
   virtual void OnAppWindowAdded(AppWindow* app_window) OVERRIDE {
-    opener_app_ids_.insert(app_window->extension()->id());
+    opener_app_ids_.insert(app_window->extension_id());
   }
-  virtual void OnAppWindowIconChanged(AppWindow* app_window) OVERRIDE {}
-  virtual void OnAppWindowRemoved(AppWindow* app_window) OVERRIDE {}
 
  protected:
   // A set of ids of apps we've seen open a app window.
diff --git a/chrome/browser/apps/app_window_browsertest.cc b/chrome/browser/apps/app_window_browsertest.cc
index 9e6ff95..0272567 100644
--- a/chrome/browser/apps/app_window_browsertest.cc
+++ b/chrome/browser/apps/app_window_browsertest.cc
@@ -249,8 +249,11 @@
   ASSERT_TRUE(RunAppWindowAPITest("testFrameColors")) << message_;
 }
 
+// TODO(benwells): Remove this test once all the things are merged together. It
+// is currently present as this feature was previously disabled on stable
+// channel, so the test is to ensure it has all been re-enabled properly.
 IN_PROC_BROWSER_TEST_F(AppWindowAPITest, TestFrameColorsInStable) {
   extensions::ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_STABLE);
-  ASSERT_TRUE(RunAppWindowAPITest("testFrameColorsInStable")) << message_;
+  ASSERT_TRUE(RunAppWindowAPITest("testFrameColors")) << message_;
 }
 #endif
diff --git a/chrome/browser/apps/ephemeral_app_launcher.cc b/chrome/browser/apps/ephemeral_app_launcher.cc
index d4cf4ec..d0f4c70 100644
--- a/chrome/browser/apps/ephemeral_app_launcher.cc
+++ b/chrome/browser/apps/ephemeral_app_launcher.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/extensions/extension_enable_flow.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/common/permissions/permissions_data.h"
@@ -38,7 +37,7 @@
   if (!contents)
     return NULL;
 
-  return contents->GetView()->GetTopLevelNativeWindow();
+  return contents->GetTopLevelNativeWindow();
 }
 
 }  // namespace
@@ -132,7 +131,7 @@
 
 void EphemeralAppLauncher::StartObserving() {
   extension_registry_observer_.Add(
-      extensions::ExtensionRegistry::Get(profile()->GetOriginalProfile()));
+      extensions::ExtensionRegistry::Get(profile()));
 }
 
 void EphemeralAppLauncher::LaunchApp(const Extension* extension) const {
@@ -253,15 +252,13 @@
   // WebstoreStandaloneInstaller to support this cleanly.
 }
 
-void EphemeralAppLauncher::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void EphemeralAppLauncher::WebContentsDestroyed() {
   AbortInstall();
 }
 
 void EphemeralAppLauncher::OnExtensionLoaded(
     content::BrowserContext* browser_context,
     const Extension* extension) {
-  DCHECK(extension);
   if (extension->id() == id()) {
     LaunchApp(extension);
     WebstoreStandaloneInstaller::CompleteInstall(std::string());
diff --git a/chrome/browser/apps/ephemeral_app_launcher.h b/chrome/browser/apps/ephemeral_app_launcher.h
index baefed52..a68d611 100644
--- a/chrome/browser/apps/ephemeral_app_launcher.h
+++ b/chrome/browser/apps/ephemeral_app_launcher.h
@@ -90,8 +90,7 @@
   virtual void CompleteInstall(const std::string& error) OVERRIDE;
 
   // content::WebContentsObserver implementation.
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // ExtensionRegistryObserver implementation.
   virtual void OnExtensionLoaded(
diff --git a/chrome/browser/apps/web_view_browsertest.cc b/chrome/browser/apps/web_view_browsertest.cc
index ababfa9..8b96069 100644
--- a/chrome/browser/apps/web_view_browsertest.cc
+++ b/chrome/browser/apps/web_view_browsertest.cc
@@ -122,6 +122,30 @@
   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
 };
 
+class WebContentsHiddenObserver : public content::WebContentsObserver {
+ public:
+  WebContentsHiddenObserver(content::WebContents* web_contents,
+                            const base::Closure& hidden_callback)
+      : WebContentsObserver(web_contents),
+        hidden_callback_(hidden_callback),
+        hidden_observed_(true) {
+  }
+
+  // WebContentsObserver.
+  virtual void WasHidden() OVERRIDE {
+    hidden_observed_ = true;
+    hidden_callback_.Run();
+  }
+
+  bool hidden_observed() { return hidden_observed_; }
+
+ private:
+  base::Closure hidden_callback_;
+  bool hidden_observed_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebContentsHiddenObserver);
+};
+
 class InterstitialObserver : public content::WebContentsObserver {
  public:
   InterstitialObserver(content::WebContents* web_contents,
@@ -147,6 +171,18 @@
   DISALLOW_COPY_AND_ASSIGN(InterstitialObserver);
 };
 
+void ExecuteScriptWaitForTitle(content::WebContents* web_contents,
+                               const char* script,
+                               const char* title) {
+  base::string16 expected_title(base::ASCIIToUTF16(title));
+  base::string16 error_title(base::ASCIIToUTF16("error"));
+
+  content::TitleWatcher title_watcher(web_contents, expected_title);
+  title_watcher.AlsoWaitForTitle(error_title);
+  EXPECT_TRUE(content::ExecuteScript(web_contents, script));
+  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
+}
+
 }  // namespace
 
 // This class intercepts media access request from the embedder. The request
@@ -457,18 +493,6 @@
     }
   }
 
-  void ExecuteScriptWaitForTitle(content::WebContents* web_contents,
-                                 const char* script,
-                                 const char* title) {
-    base::string16 expected_title(base::ASCIIToUTF16(title));
-    base::string16 error_title(base::ASCIIToUTF16("error"));
-
-    content::TitleWatcher title_watcher(web_contents, expected_title);
-    title_watcher.AlsoWaitForTitle(error_title);
-    EXPECT_TRUE(content::ExecuteScript(web_contents, script));
-    EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
-  }
-
   // Handles |request| by serving a redirect response.
   static scoped_ptr<net::test_server::HttpResponse> RedirectResponseHandler(
       const std::string& path,
@@ -628,21 +652,91 @@
       loop_runner->Run();
   }
 
+  void LoadAppWithGuest(const std::string& app_path) {
+    GuestContentBrowserClient new_client;
+    content::ContentBrowserClient* old_client =
+        SetBrowserClientForTesting(&new_client);
+
+    ExtensionTestMessageListener launched_listener("WebViewTest.LAUNCHED",
+                                                   false);
+    launched_listener.set_failure_message("WebViewTest.FAILURE");
+    LoadAndLaunchPlatformApp(app_path.c_str());
+    ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
+
+    guest_web_contents_ = new_client.WaitForGuestCreated();
+    SetBrowserClientForTesting(old_client);
+  }
+
+  void SendMessageToEmbedder(const std::string& message) {
+    EXPECT_TRUE(
+        content::ExecuteScript(
+            GetEmbedderWebContents(),
+            base::StringPrintf("onAppCommand('%s');", message.c_str())));
+  }
+
+  content::WebContents* GetGuestWebContents() {
+    return guest_web_contents_;
+  }
+
+  content::WebContents* GetEmbedderWebContents() {
+    if (!embedder_web_contents_) {
+      embedder_web_contents_ = GetFirstAppWindowWebContents();
+    }
+    return embedder_web_contents_;
+  }
+
+  WebViewTest() : guest_web_contents_(NULL),
+                  embedder_web_contents_(NULL) {
+  }
+
  private:
   bool UsesFakeSpeech() {
     const testing::TestInfo* const test_info =
         testing::UnitTest::GetInstance()->current_test_info();
 
     // SpeechRecognition test specific SetUp.
-    return !strcmp(test_info->name(), "SpeechRecognition") ||
-           !strcmp(test_info->name(),
+    return !strcmp(test_info->name(),
                    "SpeechRecognitionAPI_HasPermissionAllow");
   }
 
   scoped_ptr<content::FakeSpeechRecognitionManager>
       fake_speech_recognition_manager_;
+
+  // Note that these are only set if you launch app using LoadAppWithGuest().
+  content::WebContents* guest_web_contents_;
+  content::WebContents* embedder_web_contents_;
 };
 
+// This test verifies that hiding the guest triggers WebContents::WasHidden().
+IN_PROC_BROWSER_TEST_F(WebViewTest, GuestVisibilityChanged) {
+  LoadAppWithGuest("web_view/visibility_changed");
+
+  scoped_refptr<content::MessageLoopRunner> loop_runner(
+      new content::MessageLoopRunner);
+  WebContentsHiddenObserver observer(GetGuestWebContents(),
+                                     loop_runner->QuitClosure());
+
+  // Handled in platform_apps/web_view/visibility_changed/main.js
+  SendMessageToEmbedder("hide-guest");
+  if (!observer.hidden_observed())
+    loop_runner->Run();
+}
+
+// This test verifies that hiding the embedder also hides the guest.
+IN_PROC_BROWSER_TEST_F(WebViewTest, EmbedderVisibilityChanged) {
+  LoadAppWithGuest("web_view/visibility_changed");
+
+  scoped_refptr<content::MessageLoopRunner> loop_runner(
+      new content::MessageLoopRunner);
+  WebContentsHiddenObserver observer(GetGuestWebContents(),
+                                     loop_runner->QuitClosure());
+
+  // Handled in platform_apps/web_view/visibility_changed/main.js
+  SendMessageToEmbedder("hide-embedder");
+  if (!observer.hidden_observed())
+    loop_runner->Run();
+}
+
 // This test ensures JavaScript errors ("Cannot redefine property") do not
 // happen when a <webview> is removed from DOM and added back.
 IN_PROC_BROWSER_TEST_F(WebViewTest,
@@ -1588,20 +1682,10 @@
 }
 
 IN_PROC_BROWSER_TEST_F(WebViewTest, ContextMenusAPI_Basic) {
-  GuestContentBrowserClient new_client;
-  content::ContentBrowserClient* old_client =
-      SetBrowserClientForTesting(&new_client);
+  LoadAppWithGuest("web_view/context_menus/basic");
 
-  ExtensionTestMessageListener launched_listener("Launched", false);
-  launched_listener.set_failure_message("TEST_FAILED");
-  LoadAndLaunchPlatformApp("web_view/context_menus/basic");
-  ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
-
-  content::WebContents* guest_web_contents = new_client.WaitForGuestCreated();
-  ASSERT_TRUE(guest_web_contents);
-  SetBrowserClientForTesting(old_client);
-
-  content::WebContents* embedder = GetFirstAppWindowWebContents();
+  content::WebContents* guest_web_contents = GetGuestWebContents();
+  content::WebContents* embedder = GetEmbedderWebContents();
   ASSERT_TRUE(embedder);
 
   // 1. Basic property test.
@@ -1674,25 +1758,6 @@
           << message_;
 }
 
-// crbug/360448
-IN_PROC_BROWSER_TEST_F(WebViewTest, DISABLED_SpeechRecognition) {
-  ASSERT_TRUE(StartEmbeddedTestServer());
-  content::WebContents* guest_web_contents = LoadGuest(
-      "/extensions/platform_apps/web_view/speech/guest.html",
-      "web_view/speech");
-  ASSERT_TRUE(guest_web_contents);
-
-  // Click on the guest (center of the WebContents), the guest is rendered in a
-  // way that this will trigger clicking on speech recognition input mic.
-  SimulateMouseClick(guest_web_contents, 0, blink::WebMouseEvent::ButtonLeft);
-
-  base::string16 expected_title(base::ASCIIToUTF16("PASSED"));
-  base::string16 error_title(base::ASCIIToUTF16("FAILED"));
-  content::TitleWatcher title_watcher(guest_web_contents, expected_title);
-  title_watcher.AlsoWaitForTitle(error_title);
-  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
-}
-
 #if defined(OS_CHROMEOS)
 IN_PROC_BROWSER_TEST_F(WebViewTest, ChromeVoxInjection) {
   EXPECT_FALSE(
diff --git a/chrome/browser/apps/web_view_interactive_browsertest.cc b/chrome/browser/apps/web_view_interactive_browsertest.cc
index 3b633fa..cb01b23 100644
--- a/chrome/browser/apps/web_view_interactive_browsertest.cc
+++ b/chrome/browser/apps/web_view_interactive_browsertest.cc
@@ -20,7 +20,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -225,8 +224,7 @@
     guest_web_contents_ = source->GetWebContents();
     embedder_web_contents_ = guest_web_contents_->GetEmbedderWebContents();
 
-    gfx::Rect offset;
-    embedder_web_contents_->GetView()->GetContainerBounds(&offset);
+    gfx::Rect offset = embedder_web_contents_->GetContainerBounds();
     corner_ = gfx::Point(offset.x(), offset.y());
 
     const testing::TestInfo* const test_info =
@@ -689,9 +687,8 @@
 
   ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(GetPlatformAppWindow()));
 
-  gfx::Rect offset;
   embedder_web_contents_ = GetFirstAppWindowWebContents();
-  embedder_web_contents_->GetView()->GetContainerBounds(&offset);
+  gfx::Rect offset = embedder_web_contents_->GetContainerBounds();
   corner_ = gfx::Point(offset.x(), offset.y());
 
   // In the drag drop test we add 20px padding to the page body because on
diff --git a/chrome/browser/apps/window_controls_browsertest.cc b/chrome/browser/apps/window_controls_browsertest.cc
index 7da2e46..172aa32 100644
--- a/chrome/browser/apps/window_controls_browsertest.cc
+++ b/chrome/browser/apps/window_controls_browsertest.cc
@@ -6,7 +6,6 @@
 #include "chrome/browser/extensions/extension_test_message_listener.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_switches.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/browser_test_utils.h"
 #include "extensions/browser/process_manager.h"
 
@@ -69,7 +68,7 @@
 
   // Send mouse click somewhere inside the [x] button
   const int controlOffset = 25;
-  int x = web_contents->GetView()->GetContainerSize().width() - controlOffset;
+  int x = web_contents->GetContainerBounds().size().width() - controlOffset;
   int y = controlOffset;
   content::SimulateMouseClickAt(web_contents,
                                 0,
diff --git a/chrome/browser/autocomplete/autocomplete_controller.cc b/chrome/browser/autocomplete/autocomplete_controller.cc
index 0f83d16..1bb947f 100644
--- a/chrome/browser/autocomplete/autocomplete_controller.cc
+++ b/chrome/browser/autocomplete/autocomplete_controller.cc
@@ -39,14 +39,28 @@
 // specification. For more details, see
 // http://goto.google.com/binary-clients-logging.
 void AutocompleteMatchToAssistedQuery(
-    const AutocompleteMatch::Type& match, size_t* type, size_t* subtype) {
+    const AutocompleteMatch::Type& match,
+    const AutocompleteProvider* provider,
+    size_t* type,
+    size_t* subtype) {
   // This type indicates a native chrome suggestion.
   *type = 69;
   // Default value, indicating no subtype.
   *subtype = base::string16::npos;
 
+  // If provider is TYPE_ZERO_SUGGEST, set the subtype accordingly.
+  // Type will be set in the switch statement below where we'll enter one of
+  // SEARCH_SUGGEST or NAVSUGGEST.
+  if (provider &&
+      (provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST)) {
+    DCHECK((match == AutocompleteMatchType::SEARCH_SUGGEST) ||
+           (match == AutocompleteMatchType::NAVSUGGEST));
+    *subtype = 66;
+  }
+
   switch (match) {
     case AutocompleteMatchType::SEARCH_SUGGEST: {
+      // Do not set subtype here; subtype may have been set above.
       *type = 0;
       return;
     }
@@ -67,6 +81,7 @@
       return;
     }
     case AutocompleteMatchType::NAVSUGGEST: {
+      // Do not set subtype here; subtype may have been set above.
       *type = 5;
       return;
     }
@@ -102,6 +117,10 @@
       *subtype = 65;
       return;
     }
+    case AutocompleteMatchType::NAVSUGGEST_PERSONALIZED: {
+      *subtype = 39;
+      return;
+    }
     default: {
       // This value indicates a native chrome suggestion with no named subtype
       // (yet).
@@ -303,20 +322,24 @@
 }
 
 void AutocompleteController::StartZeroSuggest(const AutocompleteInput& input) {
-  if (zero_suggest_provider_ != NULL) {
-    DCHECK(!in_start_);  // We should not be already running a query.
+  if (zero_suggest_provider_ == NULL)
+    return;
 
-    // Call Start() on all prefix-based providers with an INVALID
-    // AutocompleteInput to clear out cached |matches_|, which ensures that
-    // they aren't used with zero suggest.
-    for (ACProviders::iterator i(providers_.begin()); i != providers_.end();
-        ++i) {
-      if (*i == zero_suggest_provider_)
-        (*i)->Start(input, false);
-      else
-        (*i)->Start(AutocompleteInput(), false);
-    }
+  DCHECK(!in_start_);  // We should not be already running a query.
+
+  // Call Start() on all prefix-based providers with an INVALID
+  // AutocompleteInput to clear out cached |matches_|, which ensures that
+  // they aren't used with zero suggest.
+  for (ACProviders::iterator i(providers_.begin()); i != providers_.end();
+      ++i) {
+    if (*i == zero_suggest_provider_)
+      (*i)->Start(input, false);
+    else
+      (*i)->Start(AutocompleteInput(), false);
   }
+
+  if (!zero_suggest_provider_->matches().empty())
+    UpdateResult(false, false);
 }
 
 void AutocompleteController::DeleteMatch(const AutocompleteMatch& match) {
@@ -551,7 +574,8 @@
        ++match) {
     size_t type = base::string16::npos;
     size_t subtype = base::string16::npos;
-    AutocompleteMatchToAssistedQuery(match->type, &type, &subtype);
+    AutocompleteMatchToAssistedQuery(
+        match->type, match->provider, &type, &subtype);
     if (last_type != base::string16::npos &&
         (type != last_type || subtype != last_subtype)) {
       AppendAvailableAutocompletion(
diff --git a/chrome/browser/autocomplete/autocomplete_input.cc b/chrome/browser/autocomplete/autocomplete_input.cc
index 87867cc..d81e728 100644
--- a/chrome/browser/autocomplete/autocomplete_input.cc
+++ b/chrome/browser/autocomplete/autocomplete_input.cc
@@ -175,8 +175,8 @@
   // (e.g. "ftp" or "view-source") but I'll wait to spend the effort on that
   // until I run into some cases that really need it.
   if (parts->scheme.is_nonempty() &&
-      !LowerCaseEqualsASCII(parsed_scheme, content::kHttpScheme) &&
-      !LowerCaseEqualsASCII(parsed_scheme, content::kHttpsScheme)) {
+      !LowerCaseEqualsASCII(parsed_scheme, url::kHttpScheme) &&
+      !LowerCaseEqualsASCII(parsed_scheme, url::kHttpsScheme)) {
     // See if we know how to handle the URL internally.  There are some schemes
     // that we convert to other things before they reach the renderer or else
     // the renderer handles internally without reaching the net::URLRequest
@@ -213,7 +213,7 @@
         // We don't know about this scheme.  It might be that the user typed a
         // URL of the form "username:password@foo.com".
         const base::string16 http_scheme_prefix =
-            base::ASCIIToUTF16(std::string(content::kHttpScheme) +
+            base::ASCIIToUTF16(std::string(url::kHttpScheme) +
                                content::kStandardSchemeSeparator);
         url::Parsed http_parts;
         base::string16 http_scheme;
@@ -221,7 +221,7 @@
         Type http_type = Parse(http_scheme_prefix + text, desired_tld,
                                &http_parts, &http_scheme,
                                &http_canonicalized_url);
-        DCHECK_EQ(std::string(content::kHttpScheme),
+        DCHECK_EQ(std::string(url::kHttpScheme),
                   base::UTF16ToUTF8(http_scheme));
 
         if ((http_type == URL) && http_parts.username.is_nonempty() &&
@@ -504,7 +504,7 @@
                                 &scheme)) {
     utf8_input.erase(0, scheme.end() + 1);
   }
-  return url::FindAndCompareScheme(utf8_input, content::kHttpScheme, NULL);
+  return url::FindAndCompareScheme(utf8_input, url::kHttpScheme, NULL);
 }
 
 void AutocompleteInput::UpdateText(const base::string16& text,
diff --git a/chrome/browser/autocomplete/autocomplete_match.cc b/chrome/browser/autocomplete/autocomplete_match.cc
index f13669e..46bbd6b 100644
--- a/chrome/browser/autocomplete/autocomplete_match.cc
+++ b/chrome/browser/autocomplete/autocomplete_match.cc
@@ -152,6 +152,7 @@
     IDR_OMNIBOX_EXTENSION_APP,
     IDR_OMNIBOX_SEARCH,
     IDR_OMNIBOX_HTTP,
+    IDR_OMNIBOX_HTTP,
   };
   COMPILE_ASSERT(arraysize(icons) == AutocompleteMatchType::NUM_TYPES,
                  icons_array_must_match_type_enum);
@@ -376,9 +377,9 @@
   }
 
   // Replace https protocol with http protocol.
-  if (stripped_destination_url.SchemeIs(content::kHttpsScheme)) {
-    replacements.SetScheme(content::kHttpScheme,
-                           url::Component(0, strlen(content::kHttpScheme)));
+  if (stripped_destination_url.SchemeIs(url::kHttpsScheme)) {
+    replacements.SetScheme(url::kHttpScheme,
+                           url::Component(0, strlen(url::kHttpScheme)));
     needs_replacement = true;
   }
 
diff --git a/chrome/browser/autocomplete/autocomplete_provider.cc b/chrome/browser/autocomplete/autocomplete_provider.cc
index d2ef91d..963a1db 100644
--- a/chrome/browser/autocomplete/autocomplete_provider.cc
+++ b/chrome/browser/autocomplete/autocomplete_provider.cc
@@ -210,11 +210,11 @@
   if (!AutocompleteInput::HasHTTPScheme(*url))
     return 0;
   size_t scheme_pos =
-      url->find(base::ASCIIToUTF16(content::kHttpScheme) + base::char16(':'));
+      url->find(base::ASCIIToUTF16(url::kHttpScheme) + base::char16(':'));
   DCHECK_NE(base::string16::npos, scheme_pos);
 
   // Erase scheme plus up to two slashes.
-  size_t prefix_end = scheme_pos + strlen(content::kHttpScheme) + 1;
+  size_t prefix_end = scheme_pos + strlen(url::kHttpScheme) + 1;
   const size_t after_slashes = std::min(url->length(), prefix_end + 2);
   while ((prefix_end < after_slashes) && ((*url)[prefix_end] == '/'))
     ++prefix_end;
diff --git a/chrome/browser/autocomplete/autocomplete_provider.h b/chrome/browser/autocomplete/autocomplete_provider.h
index f55e9f6..02e247e 100644
--- a/chrome/browser/autocomplete/autocomplete_provider.h
+++ b/chrome/browser/autocomplete/autocomplete_provider.h
@@ -11,7 +11,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/autocomplete/autocomplete_match.h"
-#include "chrome/common/metrics/proto/omnibox_event.pb.h"
+#include "components/metrics/proto/omnibox_event.pb.h"
 
 class AutocompleteInput;
 class AutocompleteProviderListener;
diff --git a/chrome/browser/autocomplete/autocomplete_provider_unittest.cc b/chrome/browser/autocomplete/autocomplete_provider_unittest.cc
index fb0c318..a2cd035 100644
--- a/chrome/browser/autocomplete/autocomplete_provider_unittest.cc
+++ b/chrome/browser/autocomplete/autocomplete_provider_unittest.cc
@@ -303,10 +303,11 @@
   ASSERT_NE(0, default_provider_id);
 
   // Create another TemplateURL for KeywordProvider.
-  data.short_name = base::ASCIIToUTF16("k");
-  data.SetKeyword(base::ASCIIToUTF16("k"));
-  data.SetURL("http://keyword/{searchTerms}");
-  TemplateURL* keyword_t_url = new TemplateURL(&profile_, data);
+  TemplateURLData data2;
+  data2.short_name = base::ASCIIToUTF16("k");
+  data2.SetKeyword(base::ASCIIToUTF16("k"));
+  data2.SetURL("http://keyword/{searchTerms}");
+  TemplateURL* keyword_t_url = new TemplateURL(&profile_, data2);
   turl_model->Add(keyword_t_url);
   ASSERT_NE(0, keyword_t_url->id());
 
diff --git a/chrome/browser/autocomplete/base_search_provider.cc b/chrome/browser/autocomplete/base_search_provider.cc
index 7db7eb6..69ec6da 100644
--- a/chrome/browser/autocomplete/base_search_provider.cc
+++ b/chrome/browser/autocomplete/base_search_provider.cc
@@ -7,6 +7,7 @@
 #include "base/i18n/case_conversion.h"
 #include "base/i18n/icu_string_conversions.h"
 #include "base/json/json_string_value_serializer.h"
+#include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -21,6 +22,8 @@
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
+#include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/common/net/url_fixer_upper.h"
@@ -31,6 +34,7 @@
 #include "net/base/net_util.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "net/http/http_response_headers.h"
+#include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "url/gurl.h"
 
@@ -45,6 +49,10 @@
     return AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED;
   if (type == "PROFILE")
     return AutocompleteMatchType::SEARCH_SUGGEST_PROFILE;
+  if (type == "NAVIGATION")
+    return AutocompleteMatchType::NAVSUGGEST;
+  if (type == "PERSONALIZED_NAVIGATION")
+    return AutocompleteMatchType::NAVSUGGEST_PERSONALIZED;
   return AutocompleteMatchType::SEARCH_SUGGEST;
 }
 
@@ -149,7 +157,6 @@
 
 void BaseSearchProvider::DeleteMatch(const AutocompleteMatch& match) {
   DCHECK(match.deletable);
-
   if (!match.GetAdditionalInfo(BaseSearchProvider::kDeletionUrlKey).empty()) {
     deletion_handlers_.push_back(new SuggestionDeletionHandler(
         match.GetAdditionalInfo(BaseSearchProvider::kDeletionUrlKey),
@@ -188,6 +195,7 @@
           field_trial_hashes[i]);
     }
   }
+  ModifyProviderInfo(&new_entry);
 }
 
 // static
@@ -205,10 +213,14 @@
 
 BaseSearchProvider::Result::Result(bool from_keyword_provider,
                                    int relevance,
-                                   bool relevance_from_server)
+                                   bool relevance_from_server,
+                                   AutocompleteMatchType::Type type,
+                                   const std::string& deletion_url)
     : from_keyword_provider_(from_keyword_provider),
-      relevance_(relevance),
-      relevance_from_server_(relevance_from_server) {}
+       type_(type),
+       relevance_(relevance),
+       relevance_from_server_(relevance_from_server),
+       deletion_url_(deletion_url) {}
 
 BaseSearchProvider::Result::~Result() {}
 
@@ -227,13 +239,15 @@
     bool relevance_from_server,
     bool should_prefetch,
     const base::string16& input_text)
-    : Result(from_keyword_provider, relevance, relevance_from_server),
+    : Result(from_keyword_provider,
+             relevance,
+             relevance_from_server,
+             type,
+             deletion_url),
       suggestion_(suggestion),
-      type_(type),
       match_contents_prefix_(match_contents_prefix),
       annotation_(annotation),
       suggest_query_params_(suggest_query_params),
-      deletion_url_(deletion_url),
       should_prefetch_(should_prefetch) {
   match_contents_ = match_contents;
   DCHECK(!match_contents_.empty());
@@ -326,13 +340,19 @@
 BaseSearchProvider::NavigationResult::NavigationResult(
     const AutocompleteProvider& provider,
     const GURL& url,
+    AutocompleteMatchType::Type type,
     const base::string16& description,
+    const std::string& deletion_url,
     bool from_keyword_provider,
     int relevance,
     bool relevance_from_server,
     const base::string16& input_text,
     const std::string& languages)
-    : Result(from_keyword_provider, relevance, relevance_from_server),
+    : Result(from_keyword_provider,
+             relevance,
+             relevance_from_server,
+             type,
+             deletion_url),
       url_(url),
       formatted_url_(AutocompleteInput::FormattedStringWithEquivalentMeaning(
           url,
@@ -430,6 +450,24 @@
   return false;
 }
 
+void BaseSearchProvider::SetDeletionURL(const std::string& deletion_url,
+                                        AutocompleteMatch* match) {
+  if (deletion_url.empty())
+    return;
+  TemplateURLService* template_service =
+      TemplateURLServiceFactory::GetForProfile(profile_);
+  if (!template_service)
+    return;
+  GURL url = TemplateURLService::GenerateSearchURL(
+      template_service->GetDefaultSearchProvider());
+  url = url.GetOrigin().Resolve(deletion_url);
+  if (url.is_valid()) {
+    match->RecordAdditionalInfo(BaseSearchProvider::kDeletionUrlKey,
+        url.spec());
+    match->deletable = true;
+  }
+}
+
 // BaseSearchProvider ---------------------------------------------------------
 
 // static
@@ -542,7 +580,7 @@
 
   // Make sure we are sending the suggest request through HTTPS to prevent
   // exposing the current page URL or personalized results without encryption.
-  if (!suggest_url.SchemeIs(content::kHttpsScheme))
+  if (!suggest_url.SchemeIs(url::kHttpsScheme))
     return false;
 
   // Don't show zero suggest on the NTP.
@@ -589,8 +627,8 @@
 
   // Only allow HTTP URLs or HTTPS URLs for the same domain as the search
   // provider.
-  if ((current_page_url.scheme() != content::kHttpScheme) &&
-      ((current_page_url.scheme() != content::kHttpsScheme) ||
+  if ((current_page_url.scheme() != url::kHttpScheme) &&
+      ((current_page_url.scheme() != url::kHttpsScheme) ||
        !net::registry_controlled_domains::SameDomainOrHost(
            current_page_url, suggest_url,
            net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)))
@@ -648,6 +686,9 @@
     }
 
     scoped_ptr<base::Value> data(DeserializeJsonData(json_data));
+    if (data && StoreSuggestionResponse(json_data, *data.get()))
+      return;
+
     results_updated = data.get() && ParseSuggestResults(
         *data.get(), is_keyword, GetResultsToFill(is_keyword));
   }
@@ -681,17 +722,9 @@
                              result.relevance_from_server() ? kTrue : kFalse);
   match.RecordAdditionalInfo(kShouldPrefetchKey,
                              result.should_prefetch() ? kTrue : kFalse);
-
-  if (!result.deletion_url().empty()) {
-    GURL url(match.destination_url.GetOrigin().Resolve(result.deletion_url()));
-    if (url.is_valid()) {
-      match.RecordAdditionalInfo(kDeletionUrlKey, url.spec());
-      match.deletable = true;
-    }
-  } else if (mark_as_deletable) {
+  SetDeletionURL(result.deletion_url(), &match);
+  if (mark_as_deletable)
     match.deletable = true;
-  }
-
   // Metadata is needed only for prefetching queries.
   if (result.should_prefetch())
     match.RecordAdditionalInfo(kSuggestMetadataKey, metadata);
@@ -827,8 +860,19 @@
     // Apply valid suggested relevance scores; discard invalid lists.
     if (relevances != NULL && !relevances->GetInteger(index, &relevance))
       relevances = NULL;
+    AutocompleteMatchType::Type match_type =
+        AutocompleteMatchType::SEARCH_SUGGEST;
+    if (types && types->GetString(index, &type))
+      match_type = GetAutocompleteMatchType(type);
+    const base::DictionaryValue* suggestion_detail = NULL;
+    std::string deletion_url;
 
-    if (types && types->GetString(index, &type) && (type == "NAVIGATION")) {
+    if (suggestion_details &&
+        suggestion_details->GetDictionary(index, &suggestion_detail))
+      suggestion_detail->GetString("du", &deletion_url);
+
+    if ((match_type == AutocompleteMatchType::NAVSUGGEST) ||
+        (match_type == AutocompleteMatchType::NAVSUGGEST_PERSONALIZED)) {
       // Do not blindly trust the URL coming from the server to be valid.
       GURL url(URLFixerUpper::FixupURL(
           base::UTF16ToUTF8(suggestion), std::string()));
@@ -837,23 +881,18 @@
         if (descriptions != NULL)
           descriptions->GetString(index, &title);
         results->navigation_results.push_back(NavigationResult(
-            *this, url, title, is_keyword_result, relevance,
-            relevances != NULL, input.text(), languages));
+            *this, url, match_type, title, deletion_url, is_keyword_result,
+            relevance, relevances != NULL, input.text(), languages));
       }
     } else {
-      AutocompleteMatchType::Type match_type = GetAutocompleteMatchType(type);
-      bool should_prefetch = static_cast<int>(index) == prefetch_index;
-      const base::DictionaryValue* suggestion_detail = NULL;
       base::string16 match_contents = suggestion;
       base::string16 match_contents_prefix;
       base::string16 annotation;
       std::string suggest_query_params;
-      std::string deletion_url;
 
       if (suggestion_details) {
         suggestion_details->GetDictionary(index, &suggestion_detail);
         if (suggestion_detail) {
-          suggestion_detail->GetString("du", &deletion_url);
           suggestion_detail->GetString("t", &match_contents);
           suggestion_detail->GetString("mp", &match_contents_prefix);
           // Error correction for bad data from server.
@@ -864,6 +903,7 @@
         }
       }
 
+      bool should_prefetch = static_cast<int>(index) == prefetch_index;
       // TODO(kochi): Improve calculator suggestion presentation.
       results->suggest_results.push_back(SuggestResult(
           base::CollapseWhitespace(suggestion, false), match_type,
@@ -882,6 +922,16 @@
                                      Results* results) {
 }
 
+bool BaseSearchProvider::StoreSuggestionResponse(
+    const std::string& json_data,
+    const base::Value& parsed_data) {
+  return false;
+}
+
+void BaseSearchProvider::ModifyProviderInfo(
+    metrics::OmniboxEventProto_ProviderInfo* provider_info) const {
+}
+
 void BaseSearchProvider::DeleteMatchFromMatches(
     const AutocompleteMatch& match) {
   for (ACMatches::iterator i(matches_.begin()); i != matches_.end(); ++i) {
diff --git a/chrome/browser/autocomplete/base_search_provider.h b/chrome/browser/autocomplete/base_search_provider.h
index 2e26ab0..d21defb 100644
--- a/chrome/browser/autocomplete/base_search_provider.h
+++ b/chrome/browser/autocomplete/base_search_provider.h
@@ -109,7 +109,9 @@
    public:
     Result(bool from_keyword_provider,
            int relevance,
-           bool relevance_from_server);
+           bool relevance_from_server,
+           AutocompleteMatchType::Type type,
+           const std::string& deletion_url);
     virtual ~Result();
 
     bool from_keyword_provider() const { return from_keyword_provider_; }
@@ -119,6 +121,7 @@
       return match_contents_class_;
     }
 
+    AutocompleteMatchType::Type type() const { return type_; }
     int relevance() const { return relevance_; }
     void set_relevance(int relevance) { relevance_ = relevance; }
 
@@ -127,6 +130,8 @@
       relevance_from_server_ = relevance_from_server;
     }
 
+    const std::string& deletion_url() const { return deletion_url_; }
+
     // Returns if this result is inlineable against the current input |input|.
     // Non-inlineable results are stale.
     virtual bool IsInlineable(const base::string16& input) const = 0;
@@ -146,6 +151,8 @@
     // True if the result came from the keyword provider.
     bool from_keyword_provider_;
 
+    AutocompleteMatchType::Type type_;
+
     // The relevance score.
     int relevance_;
 
@@ -156,6 +163,11 @@
     // SearchProvider::ConvertResultsToAutocompleteMatches(), see comments
     // there.
     bool relevance_from_server_;
+
+    // Optional deletion URL provided with suggestions. Fetching this URL
+    // should result in some reasonable deletion behaviour on the server,
+    // e.g. deleting this term out of a user's server-side search history.
+    std::string deletion_url_;
   };
 
   class SuggestResult : public Result {
@@ -175,7 +187,6 @@
     virtual ~SuggestResult();
 
     const base::string16& suggestion() const { return suggestion_; }
-    AutocompleteMatchType::Type type() const { return type_; }
     const base::string16& match_contents_prefix() const {
       return match_contents_prefix_;
     }
@@ -183,7 +194,6 @@
     const std::string& suggest_query_params() const {
       return suggest_query_params_;
     }
-    const std::string& deletion_url() const { return deletion_url_; }
     bool should_prefetch() const { return should_prefetch_; }
 
     // Fills in |match_contents_class_| to reflect how |match_contents_| should
@@ -203,8 +213,6 @@
     // The search terms to be used for this suggestion.
     base::string16 suggestion_;
 
-    AutocompleteMatchType::Type type_;
-
     // The contents to be displayed as prefix of match contents.
     // Used for postfix suggestions to display a leading ellipsis (or some
     // equivalent character) to indicate omitted text.
@@ -219,11 +227,6 @@
     // Optional additional parameters to be added to the search URL.
     std::string suggest_query_params_;
 
-    // Optional deletion URL provided with suggestions. Fetching this URL
-    // should result in some reasonable deletion behaviour on the server,
-    // e.g. deleting this term out of a user's server-side search history.
-    std::string deletion_url_;
-
     // Should this result be prefetched?
     bool should_prefetch_;
   };
@@ -234,7 +237,9 @@
     // compute |formatted_url_|.
     NavigationResult(const AutocompleteProvider& provider,
                      const GURL& url,
+                     AutocompleteMatchType::Type type,
                      const base::string16& description,
+                     const std::string& deletion_url,
                      bool from_keyword_provider,
                      int relevance,
                      bool relevance_from_server,
@@ -388,6 +393,12 @@
   // net::URLFetcherDelegate:
   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
 
+  // If the |deletion_url| is valid, then set |match.deletable| to true and
+  // save the |deletion_url| into the |match|'s additional info under
+  // the key |kDeletionUrlKey|.
+  void SetDeletionURL(const std::string& deletion_url,
+                      AutocompleteMatch* match);
+
   // Creates an AutocompleteMatch from |result| to search for the query in
   // |result|. Adds the created match to |map|; if such a match
   // already exists, whichever one has lower relevance is eliminated.
@@ -414,6 +425,12 @@
                            const base::ListValue* relevances,
                            Results* results);
 
+  // Optionally, cache the received |json_data| and return true if we want
+  // to stop processing results at this point. The |parsed_data| is the parsed
+  // version of |json_data| used to determine if we received an empty result.
+  virtual bool StoreSuggestionResponse(const std::string& json_data,
+                                       const base::Value& parsed_data);
+
   // Returns the TemplateURL corresponding to the keyword or default
   // provider based on the value of |is_keyword|.
   virtual const TemplateURL* GetTemplateURL(bool is_keyword) const = 0;
@@ -445,6 +462,10 @@
   // Records UMA statistics about a suggest server response.
   virtual void LogFetchComplete(bool succeeded, bool is_keyword) = 0;
 
+  // Modify provider-specific UMA statistics.
+  virtual void ModifyProviderInfo(
+      metrics::OmniboxEventProto_ProviderInfo* provider_info) const;
+
   // Returns whether the |fetcher| is for the keyword provider.
   virtual bool IsKeywordFetcher(const net::URLFetcher* fetcher) const = 0;
 
diff --git a/chrome/browser/autocomplete/bookmark_provider_unittest.cc b/chrome/browser/autocomplete/bookmark_provider_unittest.cc
index c2a2e04..79a87f0 100644
--- a/chrome/browser/autocomplete/bookmark_provider_unittest.cc
+++ b/chrome/browser/autocomplete/bookmark_provider_unittest.cc
@@ -16,10 +16,10 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/autocomplete/autocomplete_provider.h"
 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
-#include "chrome/browser/bookmarks/test_bookmark_client.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_match.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/test_bookmark_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 // The bookmark corpus against which we will simulate searches.
diff --git a/chrome/browser/autocomplete/history_quick_provider_unittest.cc b/chrome/browser/autocomplete/history_quick_provider_unittest.cc
index 7a8955f..524aeac 100644
--- a/chrome/browser/autocomplete/history_quick_provider_unittest.cc
+++ b/chrome/browser/autocomplete/history_quick_provider_unittest.cc
@@ -20,7 +20,7 @@
 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
 #include "chrome/browser/autocomplete/autocomplete_result.h"
 #include "chrome/browser/autocomplete/history_url_provider.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_database.h"
 #include "chrome/browser/history/history_service.h"
@@ -34,6 +34,7 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/test/test_browser_thread.h"
 #include "sql/transaction.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -161,7 +162,8 @@
   profile_.reset(new TestingProfile());
   ASSERT_TRUE(profile_->CreateHistoryService(true, false));
   profile_->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(profile_.get());
+  test::WaitForBookmarkModelToLoad(
+      BookmarkModelFactory::GetForProfile(profile_.get()));
   profile_->BlockUntilHistoryIndexIsRefreshed();
   history_service_ =
       HistoryServiceFactory::GetForProfile(profile_.get(),
diff --git a/chrome/browser/autocomplete/history_url_provider.cc b/chrome/browser/autocomplete/history_url_provider.cc
index 3d9ebdb..67ac762 100644
--- a/chrome/browser/autocomplete/history_url_provider.cc
+++ b/chrome/browser/autocomplete/history_url_provider.cc
@@ -862,7 +862,7 @@
   // input's text and parts between Parse() and here, it seems better to be
   // paranoid and check.
   if ((input.type() != AutocompleteInput::UNKNOWN) ||
-      !LowerCaseEqualsASCII(input.scheme(), content::kHttpScheme) ||
+      !LowerCaseEqualsASCII(input.scheme(), url::kHttpScheme) ||
       !input.parts().host.is_nonempty())
     return false;
   const std::string host(base::UTF16ToUTF8(
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc
index 442d855..a08ea87 100644
--- a/chrome/browser/autocomplete/search_provider.cc
+++ b/chrome/browser/autocomplete/search_provider.cc
@@ -47,7 +47,6 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "url/url_util.h"
 
-
 // Helpers --------------------------------------------------------------------
 
 namespace {
@@ -559,8 +558,8 @@
   // and happens to currently be invalid -- in which case we again want to run
   // our checks below.  Other QUERY cases are less likely to be URLs and thus we
   // assume we're OK.
-  if (!LowerCaseEqualsASCII(input_.scheme(), content::kHttpScheme) &&
-      !LowerCaseEqualsASCII(input_.scheme(), content::kHttpsScheme) &&
+  if (!LowerCaseEqualsASCII(input_.scheme(), url::kHttpScheme) &&
+      !LowerCaseEqualsASCII(input_.scheme(), url::kHttpsScheme) &&
       !LowerCaseEqualsASCII(input_.scheme(), content::kFtpScheme))
     return (input_.type() == AutocompleteInput::QUERY);
 
@@ -582,7 +581,7 @@
   // Don't send anything for https except the hostname.  Hostnames are OK
   // because they are visible when the TCP connection is established, but the
   // specific path may reveal private information.
-  if (LowerCaseEqualsASCII(input_.scheme(), content::kHttpsScheme) &&
+  if (LowerCaseEqualsASCII(input_.scheme(), url::kHttpsScheme) &&
       parts.path.is_nonempty())
     return false;
 
@@ -807,7 +806,8 @@
   return (input_.type() == AutocompleteInput::URL) &&
       (first_match != matches_.end()) &&
       (first_match->relevance > CalculateRelevanceForVerbatim()) &&
-      (first_match->type != AutocompleteMatchType::NAVSUGGEST);
+      (first_match->type != AutocompleteMatchType::NAVSUGGEST) &&
+      (first_match->type != AutocompleteMatchType::NAVSUGGEST_PERSONALIZED);
 }
 
 void SearchProvider::AddNavigationResultsToMatches(
@@ -1063,9 +1063,9 @@
           keyword_input_.text() : input_.text(),
       base::TRIM_TRAILING, &input) != base::TRIM_NONE;
   AutocompleteMatch match(this, navigation.relevance(), false,
-                          AutocompleteMatchType::NAVSUGGEST);
+                          navigation.type());
   match.destination_url = navigation.url();
-
+  BaseSearchProvider::SetDeletionURL(navigation.deletion_url(), &match);
   // First look for the user's input inside the formatted url as it would be
   // without trimming the scheme, so we can find matches at the beginning of the
   // scheme.
@@ -1110,7 +1110,7 @@
   match.allowed_to_be_default_match = navigation.IsInlineable(input) &&
       (providers_.GetKeywordProviderURL() == NULL) &&
       (match.inline_autocompletion.empty() ||
-       (!input_.prevent_inline_autocomplete() && !trimmed_whitespace));
+      (!input_.prevent_inline_autocomplete() && !trimmed_whitespace));
 
   match.contents = navigation.match_contents();
   match.contents_class = navigation.match_contents_class();
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc
index c8a3c11..3cb2496 100644
--- a/chrome/browser/autocomplete/search_provider_unittest.cc
+++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -2325,8 +2325,9 @@
     QueryForInput(ASCIIToUTF16(cases[i].input), false, false);
     AutocompleteMatch match(
         provider_->NavigationToMatch(SearchProvider::NavigationResult(
-            *provider_.get(), GURL(cases[i].url), base::string16(), false, 0,
-            false, ASCIIToUTF16(cases[i].input), std::string())));
+            *provider_.get(), GURL(cases[i].url),
+            AutocompleteMatchType::NAVSUGGEST, base::string16(), std::string(),
+            false, 0, false, ASCIIToUTF16(cases[i].input), std::string())));
     EXPECT_EQ(ASCIIToUTF16(cases[i].inline_autocompletion),
               match.inline_autocompletion);
     EXPECT_EQ(ASCIIToUTF16(cases[i].fill_into_edit), match.fill_into_edit);
@@ -2337,8 +2338,9 @@
     QueryForInput(ASCIIToUTF16(cases[i].input), true, false);
     AutocompleteMatch match_prevent_inline(
         provider_->NavigationToMatch(SearchProvider::NavigationResult(
-            *provider_.get(), GURL(cases[i].url), base::string16(), false, 0,
-            false, ASCIIToUTF16(cases[i].input), std::string())));
+            *provider_.get(), GURL(cases[i].url),
+            AutocompleteMatchType::NAVSUGGEST, base::string16(), std::string(),
+            false, 0, false, ASCIIToUTF16(cases[i].input), std::string())));
     EXPECT_EQ(ASCIIToUTF16(cases[i].inline_autocompletion),
               match_prevent_inline.inline_autocompletion);
     EXPECT_EQ(ASCIIToUTF16(cases[i].fill_into_edit),
@@ -2353,8 +2355,8 @@
   const base::string16 input(ASCIIToUTF16("ht"));
   const base::string16 url(ASCIIToUTF16("http://a.com"));
   const SearchProvider::NavigationResult result(
-      *provider_.get(), GURL(url), base::string16(), false, 0, false,
-      input, std::string());
+      *provider_.get(), GURL(url), AutocompleteMatchType::NAVSUGGEST,
+      base::string16(), std::string(), false, 0, false, input, std::string());
 
   // Check the offset and strings when inline autocompletion is allowed.
   QueryForInput(input, false, false);
@@ -2377,8 +2379,9 @@
   QueryForInput(ASCIIToUTF16("w"), false, false);
   AutocompleteMatch match(
       provider_->NavigationToMatch(SearchProvider::NavigationResult(
-          *provider_.get(), GURL("http://www.wow.com"), base::string16(), false,
-          0, false, ASCIIToUTF16("w"), std::string())));
+          *provider_.get(), GURL("http://www.wow.com"),
+          AutocompleteMatchType::NAVSUGGEST, base::string16(), std::string(),
+          false, 0, false, ASCIIToUTF16("w"), std::string())));
   EXPECT_EQ(ASCIIToUTF16("ow.com"), match.inline_autocompletion);
   EXPECT_TRUE(match.allowed_to_be_default_match);
   EXPECT_EQ(ASCIIToUTF16("www.wow.com"), match.fill_into_edit);
@@ -2747,7 +2750,7 @@
 }
 
 // Test that deletion url gets set on an AutocompleteMatch when available for a
-// personalized query.
+// personalized query or a personalized URL.
 TEST_F(SearchProviderTest, ParseDeletionUrl) {
    struct Match {
      std::string contents;
@@ -2759,38 +2762,66 @@
        kNotApplicable, "", AutocompleteMatchType::NUM_TYPES
    };
 
-   const char url[] = "https://www.google.com/complete/deleteitems"
-       "?delq=ab&client=chrome&deltok=xsrf123";
+   const char* url[] = {
+    "http://defaultturl/complete/deleteitems"
+       "?delq=ab&client=chrome&deltok=xsrf124",
+    "http://defaultturl/complete/deleteitems"
+       "?delq=www.amazon.com&client=chrome&deltok=xsrf123",
+     };
 
    struct {
        const std::string input_text;
        const std::string response_json;
-       const Match matches[4];
+       const Match matches[5];
      } cases[] = {
        // A deletion URL on a personalized query should be reflected in the
        // resulting AutocompleteMatch.
        { "a",
-         "[\"a\",[\"ab\", \"ac\"],[],[],"
-         "{\"google:suggesttype\":[\"PERSONALIZED_QUERY\",\"QUERY\"],"
-         "\"google:suggestrelevance\":[1, 2],"
+         "[\"a\",[\"ab\", \"ac\",\"www.amazon.com\"],[],[],"
+         "{\"google:suggesttype\":[\"PERSONALIZED_QUERY\",\"QUERY\","
+          "\"PERSONALIZED_NAVIGATION\"],"
+         "\"google:suggestrelevance\":[3, 2, 1],"
          "\"google:suggestdetail\":[{\"du\":"
-         "\"https://www.google.com/complete/deleteitems?delq=ab&client=chrome"
-         "&deltok=xsrf123\"}, {}]}]",
+         "\"/complete/deleteitems?delq=ab&client=chrome"
+          "&deltok=xsrf124\"}, {}, {\"du\":"
+         "\"/complete/deleteitems?delq=www.amazon.com&"
+         "client=chrome&deltok=xsrf123\"}]}]",
          { { "a", "", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED },
+           { "ab", url[0], AutocompleteMatchType::SEARCH_SUGGEST },
            { "ac", "", AutocompleteMatchType::SEARCH_SUGGEST },
-           { "ab", url, AutocompleteMatchType::SEARCH_SUGGEST },
+           { "www.amazon.com", url[1],
+              AutocompleteMatchType::NAVSUGGEST_PERSONALIZED },
            kEmptyMatch,
          },
        },
-       // Personalized queries without deletion URLs shouldn't cause errors.
+       // Personalized queries or a personalized URL without deletion URLs
+       // shouldn't cause errors.
        { "a",
          "[\"a\",[\"ab\", \"ac\"],[],[],"
-         "{\"google:suggesttype\":[\"PERSONALIZED_QUERY\",\"QUERY\"],"
+         "{\"google:suggesttype\":[\"PERSONALIZED_QUERY\",\"QUERY\","
+         "\"PERSONALIZED_NAVIGATION\"],"
          "\"google:suggestrelevance\":[1, 2],"
          "\"google:suggestdetail\":[{}, {}]}]",
          { { "a", "", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED },
            { "ac", "", AutocompleteMatchType::SEARCH_SUGGEST },
            { "ab", "", AutocompleteMatchType::SEARCH_SUGGEST },
+           { "www.amazon.com", "",
+              AutocompleteMatchType::NAVSUGGEST_PERSONALIZED },
+           kEmptyMatch,
+         },
+       },
+       // Personalized queries or a personalized URL without
+       // google:suggestdetail shouldn't cause errors.
+       { "a",
+         "[\"a\",[\"ab\", \"ac\"],[],[],"
+         "{\"google:suggesttype\":[\"PERSONALIZED_QUERY\",\"QUERY\","
+         "\"PERSONALIZED_NAVIGATION\"],"
+         "\"google:suggestrelevance\":[1, 2]}]",
+         { { "a", "", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED },
+           { "ac", "", AutocompleteMatchType::SEARCH_SUGGEST },
+           { "ab", "", AutocompleteMatchType::SEARCH_SUGGEST },
+           { "www.amazon.com", "",
+              AutocompleteMatchType::NAVSUGGEST_PERSONALIZED },
            kEmptyMatch,
          },
        },
diff --git a/chrome/browser/autocomplete/shortcuts_backend.cc b/chrome/browser/autocomplete/shortcuts_backend.cc
index 312a765..15e8bba 100644
--- a/chrome/browser/autocomplete/shortcuts_backend.cc
+++ b/chrome/browser/autocomplete/shortcuts_backend.cc
@@ -53,6 +53,7 @@
   switch (type) {
     case AutocompleteMatchType::URL_WHAT_YOU_TYPED:
     case AutocompleteMatchType::NAVSUGGEST:
+    case AutocompleteMatchType::NAVSUGGEST_PERSONALIZED:
       return AutocompleteMatchType::HISTORY_URL;
 
     case AutocompleteMatchType::SEARCH_OTHER_ENGINE:
diff --git a/chrome/browser/autocomplete/zero_suggest_provider.cc b/chrome/browser/autocomplete/zero_suggest_provider.cc
index 0a88882..5f0e1b0 100644
--- a/chrome/browser/autocomplete/zero_suggest_provider.cc
+++ b/chrome/browser/autocomplete/zero_suggest_provider.cc
@@ -32,6 +32,7 @@
 #include "chrome/common/net/url_fixer_upper.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
+#include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/user_metrics.h"
 #include "net/base/escape.h"
 #include "net/base/load_flags.h"
@@ -80,6 +81,15 @@
   return new ZeroSuggestProvider(listener, profile);
 }
 
+// static
+void ZeroSuggestProvider::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  registry->RegisterStringPref(
+      prefs::kZeroSuggestCachedResults,
+      std::string(),
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+}
+
 void ZeroSuggestProvider::Start(const AutocompleteInput& input,
                                 bool minimal_changes) {
   matches_.clear();
@@ -89,6 +99,7 @@
   Stop(true);
   field_trial_triggered_ = false;
   field_trial_triggered_in_session_ = false;
+  results_from_cache_ = false;
   permanent_text_ = input.text();
   current_query_ = input.current_url().spec();
   current_page_classification_ = input.current_page_classification();
@@ -123,9 +134,20 @@
   // TODO(jered): Consider adding locally-sourced zero-suggestions here too.
   // These may be useful on the NTP or more relevant to the user than server
   // suggestions, if based on local browsing history.
+  MaybeUseCachedSuggestions();
   Run(suggest_url);
 }
 
+void ZeroSuggestProvider::DeleteMatch(const AutocompleteMatch& match) {
+  if (OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) {
+    // Remove the deleted match from the cache, so it is not shown to the user
+    // again. Since we cannot remove just one result, blow away the cache.
+    profile_->GetPrefs()->SetString(prefs::kZeroSuggestCachedResults,
+                                    std::string());
+  }
+  BaseSearchProvider::DeleteMatch(match);
+}
+
 void ZeroSuggestProvider::ResetSession() {
   // The user has started editing in the omnibox, so leave
   // |field_trial_triggered_in_session_| unchanged and set
@@ -133,18 +155,49 @@
   field_trial_triggered_ = false;
 }
 
+void ZeroSuggestProvider::ModifyProviderInfo(
+    metrics::OmniboxEventProto_ProviderInfo* provider_info) const {
+  if (!results_.suggest_results.empty() || !results_.navigation_results.empty())
+    provider_info->set_times_returned_results_in_session(1);
+}
+
 ZeroSuggestProvider::ZeroSuggestProvider(
   AutocompleteProviderListener* listener,
   Profile* profile)
     : BaseSearchProvider(listener, profile,
                          AutocompleteProvider::TYPE_ZERO_SUGGEST),
       template_url_service_(TemplateURLServiceFactory::GetForProfile(profile)),
+      results_from_cache_(false),
       weak_ptr_factory_(this) {
 }
 
 ZeroSuggestProvider::~ZeroSuggestProvider() {
 }
 
+bool ZeroSuggestProvider::StoreSuggestionResponse(
+    const std::string& json_data,
+    const base::Value& parsed_data) {
+  if (!OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial() ||
+      json_data.empty())
+    return false;
+  profile_->GetPrefs()->SetString(prefs::kZeroSuggestCachedResults, json_data);
+
+  // If we received an empty result list, we should update the display, as it
+  // may be showing cached results that should not be shown.
+  const base::ListValue* root_list = NULL;
+  const base::ListValue* results_list = NULL;
+  if (parsed_data.GetAsList(&root_list) &&
+      root_list->GetList(1, &results_list) &&
+      results_list->empty())
+    return false;
+
+  // We are finished with the request and want to bail early.
+  if (results_from_cache_)
+    done_ = true;
+
+  return results_from_cache_;
+}
+
 const TemplateURL* ZeroSuggestProvider::GetTemplateURL(bool is_keyword) const {
   // Zero suggest provider should not receive keyword results.
   DCHECK(!is_keyword);
@@ -227,7 +280,7 @@
 AutocompleteMatch ZeroSuggestProvider::NavigationToMatch(
     const NavigationResult& navigation) {
   AutocompleteMatch match(this, navigation.relevance(), false,
-                          AutocompleteMatchType::NAVSUGGEST);
+                          navigation.type());
   match.destination_url = navigation.url();
 
   // Zero suggest results should always omit protocols and never appear bold.
@@ -265,7 +318,6 @@
   chrome_variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders(
       fetcher_->GetOriginalURL(), profile_->IsOffTheRecord(), false, &headers);
   fetcher_->SetExtraRequestHeaders(headers.ToString());
-
   fetcher_->Start();
 
   if (OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) {
@@ -302,7 +354,7 @@
   const int num_nav_results = results_.navigation_results.size();
   const int num_results = num_query_results + num_nav_results;
   UMA_HISTOGRAM_COUNTS("ZeroSuggest.QueryResults", num_query_results);
-  UMA_HISTOGRAM_COUNTS("ZeroSuggest.URLResults",  num_nav_results);
+  UMA_HISTOGRAM_COUNTS("ZeroSuggest.URLResults", num_nav_results);
   UMA_HISTOGRAM_COUNTS("ZeroSuggest.AllResults", num_results);
 
   // Show Most Visited results after ZeroSuggest response is received.
@@ -322,7 +374,8 @@
         profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
     for (size_t i = 0; i < most_visited_urls_.size(); i++) {
       const history::MostVisitedURL& url = most_visited_urls_[i];
-      NavigationResult nav(*this, url.url, url.title, false, relevance, true,
+      NavigationResult nav(*this, url.url, AutocompleteMatchType::NAVSUGGEST,
+          url.title, std::string(), false, relevance, true,
           current_query_string16, languages);
       matches_.push_back(NavigationToMatch(nav));
       --relevance;
@@ -385,9 +438,24 @@
   // with other schemes (e.g. chrome://). That may require improvements to
   // the formatting of the verbatim result returned by MatchForCurrentURL().
   if (!current_page_url.is_valid() ||
-      ((current_page_url.scheme() != content::kHttpScheme) &&
-      (current_page_url.scheme() != content::kHttpsScheme)))
+      ((current_page_url.scheme() != url::kHttpScheme) &&
+      (current_page_url.scheme() != url::kHttpsScheme)))
     return false;
 
   return true;
 }
+
+void ZeroSuggestProvider::MaybeUseCachedSuggestions() {
+  if (!OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial())
+    return;
+
+  std::string json_data = profile_->GetPrefs()->GetString(
+      prefs::kZeroSuggestCachedResults);
+  if (!json_data.empty()) {
+    scoped_ptr<base::Value> data(DeserializeJsonData(json_data));
+    if (data && ParseSuggestResults(*data.get(), false, &results_)) {
+      ConvertResultsToAutocompleteMatches();
+      results_from_cache_ = !matches_.empty();
+    }
+  }
+}
diff --git a/chrome/browser/autocomplete/zero_suggest_provider.h b/chrome/browser/autocomplete/zero_suggest_provider.h
index 68acf23..7c33d7d 100644
--- a/chrome/browser/autocomplete/zero_suggest_provider.h
+++ b/chrome/browser/autocomplete/zero_suggest_provider.h
@@ -31,6 +31,10 @@
 class URLFetcher;
 }
 
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
 // Autocomplete provider for searches based on the current URL.
 //
 // The controller will call StartZeroSuggest when the user focuses in the
@@ -47,13 +51,22 @@
   static ZeroSuggestProvider* Create(AutocompleteProviderListener* listener,
                                      Profile* profile);
 
+  // Registers a preference used to cache zero suggest results.
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
   // AutocompleteProvider:
   virtual void Start(const AutocompleteInput& input,
                      bool minimal_changes) OVERRIDE;
+  virtual void DeleteMatch(const AutocompleteMatch& match) OVERRIDE;
 
   // Sets |field_trial_triggered_| to false.
   virtual void ResetSession() OVERRIDE;
 
+ protected:
+  // BaseSearchProvider:
+  virtual void ModifyProviderInfo(
+      metrics::OmniboxEventProto_ProviderInfo* provider_info) const OVERRIDE;
+
  private:
   ZeroSuggestProvider(AutocompleteProviderListener* listener,
                       Profile* profile);
@@ -61,6 +74,8 @@
   virtual ~ZeroSuggestProvider();
 
   // BaseSearchProvider:
+  virtual bool StoreSuggestionResponse(const std::string& json_data,
+                                       const base::Value& parsed_data) OVERRIDE;
   virtual const TemplateURL* GetTemplateURL(bool is_keyword) const OVERRIDE;
   virtual const AutocompleteInput GetInput(bool is_keyword) const OVERRIDE;
   virtual Results* GetResultsToFill(bool is_keyword) OVERRIDE;
@@ -76,8 +91,7 @@
 
   // Adds AutocompleteMatches for each of the suggestions in |results| to
   // |map|.
-  void AddSuggestResultsToMap(const SuggestResults& results,
-                              MatchMap* map);
+  void AddSuggestResultsToMap(const SuggestResults& results, MatchMap* map);
 
   // Returns an AutocompleteMatch for a navigational suggestion |navigation|.
   AutocompleteMatch NavigationToMatch(const NavigationResult& navigation);
@@ -105,9 +119,12 @@
 
   // Whether we can show zero suggest on |current_page_url| without
   // sending |current_page_url| as a parameter to the server at |suggest_url|.
-  bool CanShowZeroSuggestWithoutSendingURL(
-      const GURL& suggest_url,
-      const GURL& current_page_url) const;
+  bool CanShowZeroSuggestWithoutSendingURL(const GURL& suggest_url,
+                                           const GURL& current_page_url) const;
+
+  // Checks whether we have a set of zero suggest results cached, and if so
+  // populates |matches_| with cached results.
+  void MaybeUseCachedSuggestions();
 
   // Used to build default search engine URLs for suggested queries.
   TemplateURLService* template_url_service_;
@@ -132,6 +149,9 @@
   // the response for the most recent zero suggest input URL.
   Results results_;
 
+  // Whether we are currently showing cached zero suggest results.
+  bool results_from_cache_;
+
   history::MostVisitedURLList most_visited_urls_;
 
   // For callbacks that may be run after destruction.
diff --git a/chrome/browser/autocomplete/zero_suggest_provider_unittest.cc b/chrome/browser/autocomplete/zero_suggest_provider_unittest.cc
new file mode 100644
index 0000000..f43c63c
--- /dev/null
+++ b/chrome/browser/autocomplete/zero_suggest_provider_unittest.cc
@@ -0,0 +1,222 @@
+// 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.
+
+#include "chrome/browser/autocomplete/zero_suggest_provider.h"
+
+#include "base/metrics/field_trial.h"
+#include "base/prefs/pref_service.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
+#include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
+#include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
+#include "chrome/common/metrics/variations/variations_util.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/variations/entropy_provider.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/url_request/test_url_fetcher_factory.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class ZeroSuggestProviderTest : public testing::Test,
+                                public AutocompleteProviderListener {
+ public:
+  ZeroSuggestProviderTest();
+
+  virtual void SetUp() OVERRIDE;
+  virtual void TearDown() OVERRIDE;
+
+ protected:
+  // AutocompleteProviderListener:
+  virtual void OnProviderUpdate(bool updated_matches) OVERRIDE;
+
+  void ResetFieldTrialList();
+
+  // Set up threads for testing; this needs to be instantiated before
+  // |profile_|.
+  content::TestBrowserThreadBundle thread_bundle_;
+
+  // Needed for OmniboxFieldTrial::ActivateStaticTrials().
+  scoped_ptr<base::FieldTrialList> field_trial_list_;
+
+  // URLFetcherFactory implementation registered.
+  net::TestURLFetcherFactory test_factory_;
+
+  // Profile we use.
+  TestingProfile profile_;
+
+  // ZeroSuggestProvider object under test.
+  scoped_refptr<ZeroSuggestProvider> provider_;
+
+  // Default template URL.
+  TemplateURL* default_t_url_;
+};
+
+ZeroSuggestProviderTest::ZeroSuggestProviderTest() {
+  ResetFieldTrialList();
+}
+
+void ZeroSuggestProviderTest::SetUp() {
+  // Make sure that fetchers are automatically ungregistered upon destruction.
+  test_factory_.set_remove_fetcher_on_delete(true);
+  TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+      &profile_, &TemplateURLServiceFactory::BuildInstanceFor);
+  AutocompleteClassifierFactory::GetInstance()->SetTestingFactoryAndUse(
+      &profile_, &AutocompleteClassifierFactory::BuildInstanceFor);
+
+  TemplateURLService* turl_model =
+      TemplateURLServiceFactory::GetForProfile(&profile_);
+  turl_model->Load();
+
+  TemplateURLData data;
+  data.short_name = base::ASCIIToUTF16("t");
+  data.SetURL("https://www.google.com/?q={searchTerms}");
+  data.suggestions_url = "https://www.google.com/complete/?q={searchTerms}";
+  data.instant_url = "https://does/not/exist?strk=1";
+  data.search_terms_replacement_key = "strk";
+  default_t_url_ = new TemplateURL(&profile_, data);
+  turl_model->Add(default_t_url_);
+  turl_model->SetUserSelectedDefaultSearchProvider(default_t_url_);
+
+  provider_ = ZeroSuggestProvider::Create(this, &profile_);
+}
+
+void ZeroSuggestProviderTest::TearDown() {
+  // Shutdown the provider before the profile.
+  provider_ = NULL;
+}
+
+void ZeroSuggestProviderTest::OnProviderUpdate(bool updated_matches) {
+}
+
+void ZeroSuggestProviderTest::ResetFieldTrialList() {
+  // Destroy the existing FieldTrialList before creating a new one to avoid
+  // a DCHECK.
+  field_trial_list_.reset();
+  field_trial_list_.reset(new base::FieldTrialList(
+      new metrics::SHA1EntropyProvider("foo")));
+  chrome_variations::testing::ClearAllVariationParams();
+}
+
+TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestCachingFirstRun) {
+  base::FieldTrialList::CreateFieldTrial(
+      "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment");
+
+  // Ensure the cache is empty.
+  PrefService* prefs = profile_.GetPrefs();
+  prefs->SetString(prefs::kZeroSuggestCachedResults, std::string());
+
+  std::string url("http://www.cnn.com");
+  AutocompleteInput input(
+      base::ASCIIToUTF16(url), base::string16::npos, base::string16(),
+      GURL(url), AutocompleteInput::INVALID_SPEC, true, false, true, true);
+
+  provider_->Start(input, false);
+
+  EXPECT_TRUE(prefs->GetString(prefs::kZeroSuggestCachedResults).empty());
+  EXPECT_TRUE(provider_->matches().empty());
+
+  net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID(1);
+  ASSERT_TRUE(fetcher);
+  fetcher->set_response_code(200);
+  std::string json_response("[\"\",[\"search1\", \"search2\", \"search3\"],"
+      "[],[],{\"google:suggestrelevance\":[602, 601, 600],"
+      "\"google:verbatimrelevance\":1300}]");
+  fetcher->SetResponseString(json_response);
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(4U, provider_->matches().size());  // 3 results + verbatim
+  EXPECT_EQ(json_response, prefs->GetString(prefs::kZeroSuggestCachedResults));
+}
+
+TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestHasCachedResults) {
+  base::FieldTrialList::CreateFieldTrial(
+      "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment");
+
+  std::string url("http://www.cnn.com");
+  AutocompleteInput input(
+      base::ASCIIToUTF16(url), base::string16::npos, base::string16(),
+      GURL(url), AutocompleteInput::INVALID_SPEC, true, false, true, true);
+
+  // Set up the pref to cache the response from the previous run.
+  std::string json_response("[\"\",[\"search1\", \"search2\", \"search3\"],"
+      "[],[],{\"google:suggestrelevance\":[602, 601, 600],"
+      "\"google:verbatimrelevance\":1300}]");
+  PrefService* prefs = profile_.GetPrefs();
+  prefs->SetString(prefs::kZeroSuggestCachedResults, json_response);
+
+  provider_->Start(input, false);
+
+  // Expect that matches get populated synchronously out of the cache.
+  ASSERT_EQ(4U, provider_->matches().size());
+  EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_->matches()[1].contents);
+  EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_->matches()[2].contents);
+  EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_->matches()[3].contents);
+
+  net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID(1);
+  ASSERT_TRUE(fetcher);
+  fetcher->set_response_code(200);
+  std::string json_response2("[\"\",[\"search4\", \"search5\", \"search6\"],"
+      "[],[],{\"google:suggestrelevance\":[602, 601, 600],"
+      "\"google:verbatimrelevance\":1300}]");
+  fetcher->SetResponseString(json_response2);
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+
+  base::RunLoop().RunUntilIdle();
+
+  // Expect the same 4 results after the response has been handled.
+  ASSERT_EQ(4U, provider_->matches().size());
+  EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_->matches()[1].contents);
+  EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_->matches()[2].contents);
+  EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_->matches()[3].contents);
+
+  // Expect the new results have been stored.
+  EXPECT_EQ(json_response2,
+            prefs->GetString(prefs::kZeroSuggestCachedResults));
+}
+
+TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestReceivedEmptyResults) {
+  base::FieldTrialList::CreateFieldTrial(
+      "AutocompleteDynamicTrial_2", "EnableZeroSuggestPersonalizedExperiment");
+
+  std::string url("http://www.cnn.com");
+  AutocompleteInput input(
+      base::ASCIIToUTF16(url), base::string16::npos, base::string16(),
+      GURL(url), AutocompleteInput::INVALID_SPEC, true, false, true, true);
+
+  // Set up the pref to cache the response from the previous run.
+  std::string json_response("[\"\",[\"search1\", \"search2\", \"search3\"],"
+      "[],[],{\"google:suggestrelevance\":[602, 601, 600],"
+      "\"google:verbatimrelevance\":1300}]");
+  PrefService* prefs = profile_.GetPrefs();
+  prefs->SetString(prefs::kZeroSuggestCachedResults, json_response);
+
+  provider_->Start(input, false);
+
+  // Expect that matches get populated synchronously out of the cache.
+  ASSERT_EQ(4U, provider_->matches().size());
+  EXPECT_EQ(base::ASCIIToUTF16("search1"), provider_->matches()[1].contents);
+  EXPECT_EQ(base::ASCIIToUTF16("search2"), provider_->matches()[2].contents);
+  EXPECT_EQ(base::ASCIIToUTF16("search3"), provider_->matches()[3].contents);
+
+  net::TestURLFetcher* fetcher = test_factory_.GetFetcherByID(1);
+  ASSERT_TRUE(fetcher);
+  fetcher->set_response_code(200);
+  std::string empty_response("[\"\",[],[],[],{}]");
+  fetcher->SetResponseString(empty_response);
+  fetcher->delegate()->OnURLFetchComplete(fetcher);
+
+  base::RunLoop().RunUntilIdle();
+
+  // Expect that the matches have been cleared.
+  ASSERT_TRUE(provider_->matches().empty());
+
+  // Expect the new results have been stored.
+  EXPECT_EQ(empty_response,
+            prefs->GetString(prefs::kZeroSuggestCachedResults));
+}
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.cc b/chrome/browser/autofill/android/personal_data_manager_android.cc
index a094a2c..c020e10 100644
--- a/chrome/browser/autofill/android/personal_data_manager_android.cc
+++ b/chrome/browser/autofill/android/personal_data_manager_android.cc
@@ -43,27 +43,31 @@
       ConvertUTF16ToJavaString(env, profile.GetRawInfo(COMPANY_NAME)).obj(),
       ConvertUTF16ToJavaString(
           env,
-          profile.GetRawInfo(ADDRESS_HOME_LINE1)).obj(),
-      ConvertUTF16ToJavaString(
-          env,
-          profile.GetRawInfo(ADDRESS_HOME_LINE2)).obj(),
-      ConvertUTF16ToJavaString(
-          env,
-          profile.GetRawInfo(ADDRESS_HOME_CITY)).obj(),
+          profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS)).obj(),
       ConvertUTF16ToJavaString(
           env,
           profile.GetRawInfo(ADDRESS_HOME_STATE)).obj(),
       ConvertUTF16ToJavaString(
           env,
+          profile.GetRawInfo(ADDRESS_HOME_CITY)).obj(),
+      ConvertUTF16ToJavaString(
+          env,
+          profile.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY)).obj(),
+      ConvertUTF16ToJavaString(
+          env,
           profile.GetRawInfo(ADDRESS_HOME_ZIP)).obj(),
       ConvertUTF16ToJavaString(
           env,
+          profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE)).obj(),
+      ConvertUTF16ToJavaString(
+          env,
           profile.GetInfo(AutofillType(ADDRESS_HOME_COUNTRY),
                           g_browser_process->GetApplicationLocale())).obj(),
       ConvertUTF16ToJavaString(
           env,
           profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)).obj(),
-      ConvertUTF16ToJavaString(env, profile.GetRawInfo(EMAIL_ADDRESS)).obj());
+      ConvertUTF16ToJavaString(env, profile.GetRawInfo(EMAIL_ADDRESS)).obj(),
+      ConvertUTF8ToJavaString(env, profile.language_code()).obj());
 }
 
 void PopulateNativeProfileFromJava(
@@ -82,25 +86,29 @@
       ConvertJavaStringToUTF16(
           Java_AutofillProfile_getCompanyName(env, jprofile)));
   profile->SetRawInfo(
-      ADDRESS_HOME_LINE1,
+      ADDRESS_HOME_STREET_ADDRESS,
       ConvertJavaStringToUTF16(
-          Java_AutofillProfile_getAddressLine1(env, jprofile)));
-  profile->SetRawInfo(
-      ADDRESS_HOME_LINE2,
-      ConvertJavaStringToUTF16(
-          Java_AutofillProfile_getAddressLine2(env, jprofile)));
-  profile->SetRawInfo(
-      ADDRESS_HOME_CITY,
-      ConvertJavaStringToUTF16(
-          Java_AutofillProfile_getCity(env, jprofile)));
+          Java_AutofillProfile_getStreetAddress(env, jprofile)));
   profile->SetRawInfo(
       ADDRESS_HOME_STATE,
       ConvertJavaStringToUTF16(
-          Java_AutofillProfile_getState(env, jprofile)));
+          Java_AutofillProfile_getRegion(env, jprofile)));
+  profile->SetRawInfo(
+      ADDRESS_HOME_CITY,
+      ConvertJavaStringToUTF16(
+          Java_AutofillProfile_getLocality(env, jprofile)));
+  profile->SetRawInfo(
+      ADDRESS_HOME_DEPENDENT_LOCALITY,
+      ConvertJavaStringToUTF16(
+          Java_AutofillProfile_getDependentLocality(env, jprofile)));
   profile->SetRawInfo(
       ADDRESS_HOME_ZIP,
       ConvertJavaStringToUTF16(
-          Java_AutofillProfile_getZip(env, jprofile)));
+          Java_AutofillProfile_getPostalCode(env, jprofile)));
+  profile->SetRawInfo(
+      ADDRESS_HOME_SORTING_CODE,
+      ConvertJavaStringToUTF16(
+          Java_AutofillProfile_getSortingCode(env, jprofile)));
   profile->SetInfo(
       AutofillType(ADDRESS_HOME_COUNTRY),
       ConvertJavaStringToUTF16(
@@ -114,6 +122,9 @@
       EMAIL_ADDRESS,
       ConvertJavaStringToUTF16(
           Java_AutofillProfile_getEmailAddress(env, jprofile)));
+  profile->set_language_code(
+      ConvertJavaStringToUTF8(
+          Java_AutofillProfile_getLanguageCode(env, jprofile)));
 }
 
 ScopedJavaLocalRef<jobject> CreateJavaCreditCardFromNative(
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc
index 04e5fae..98c7fd9 100644
--- a/chrome/browser/autofill/autofill_interactive_uitest.cc
+++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -39,6 +39,7 @@
 #include "components/autofill/core/browser/personal_data_manager_observer.h"
 #include "components/autofill/core/browser/validation.h"
 #include "components/infobars/core/infobar.h"
+#include "components/infobars/core/infobar_manager.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -131,25 +132,24 @@
 
 class WindowedPersonalDataManagerObserver
     : public PersonalDataManagerObserver,
-      public content::NotificationObserver {
+      public infobars::InfoBarManager::Observer {
  public:
   explicit WindowedPersonalDataManagerObserver(Browser* browser)
       : alerted_(false),
         has_run_message_loop_(false),
         browser_(browser),
-        infobar_service_(NULL) {
+        infobar_service_(InfoBarService::FromWebContents(
+            browser_->tab_strip_model()->GetActiveWebContents())) {
     PersonalDataManagerFactory::GetForProfile(browser_->profile())->
         AddObserver(this);
-    registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
-                   content::NotificationService::AllSources());
+    infobar_service_->AddObserver(this);
   }
 
   virtual ~WindowedPersonalDataManagerObserver() {
-    if (infobar_service_) {
-      while (infobar_service_->infobar_count() > 0) {
-        infobar_service_->RemoveInfoBar(infobar_service_->infobar_at(0));
-      }
+    while (infobar_service_->infobar_count() > 0) {
+      infobar_service_->RemoveInfoBar(infobar_service_->infobar_at(0));
     }
+    infobar_service_->RemoveObserver(this);
   }
 
   // PersonalDataManagerObserver:
@@ -165,15 +165,6 @@
     OnPersonalDataChanged();
   }
 
-  // content::NotificationObserver:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) OVERRIDE {
-    infobar_service_ = InfoBarService::FromWebContents(
-        browser_->tab_strip_model()->GetActiveWebContents());
-    infobar_service_->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate()->
-        Accept();
-  }
 
   void Wait() {
     if (!alerted_) {
@@ -185,10 +176,15 @@
   }
 
  private:
+  // infobars::InfoBarManager::Observer:
+  virtual void OnInfoBarAdded(infobars::InfoBar* infobar) OVERRIDE {
+    infobar_service_->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate()->
+        Accept();
+  }
+
   bool alerted_;
   bool has_run_message_loop_;
   Browser* browser_;
-  content::NotificationRegistrar registrar_;
   InfoBarService* infobar_service_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowedPersonalDataManagerObserver);
diff --git a/chrome/browser/autofill/content_autofill_driver_browsertest.cc b/chrome/browser/autofill/content_autofill_driver_browsertest.cc
index d452e1e..1df9234 100644
--- a/chrome/browser/autofill/content_autofill_driver_browsertest.cc
+++ b/chrome/browser/autofill/content_autofill_driver_browsertest.cc
@@ -81,20 +81,19 @@
   virtual ~ContentAutofillDriverBrowserTest() {}
 
   virtual void SetUpOnMainThread() OVERRIDE {
-    web_contents_ = browser()->tab_strip_model()->GetActiveWebContents();
-    ASSERT_TRUE(web_contents_ != NULL);
-    Observe(web_contents_);
+    content::WebContents* web_contents =
+        browser()->tab_strip_model()->GetActiveWebContents();
+    ASSERT_TRUE(web_contents != NULL);
+    Observe(web_contents);
     AutofillManager::RegisterProfilePrefs(manager_delegate_.GetPrefRegistry());
 
     autofill_driver_.reset(
-        new TestContentAutofillDriver(web_contents_, &manager_delegate_));
+        new TestContentAutofillDriver(web_contents, &manager_delegate_));
   }
 
   // Normally the WebContents will automatically delete the driver, but here
   // the driver is owned by this test, so we have to manually destroy.
-  virtual void WebContentsDestroyed(content::WebContents* web_contents)
-      OVERRIDE {
-    DCHECK_EQ(web_contents_, web_contents);
+  virtual void WebContentsDestroyed() OVERRIDE {
     autofill_driver_.reset();
   }
 
diff --git a/chrome/browser/bitmap_fetcher.cc b/chrome/browser/bitmap_fetcher.cc
index c31b62a..023111b 100644
--- a/chrome/browser/bitmap_fetcher.cc
+++ b/chrome/browser/bitmap_fetcher.cc
@@ -19,12 +19,18 @@
 
 BitmapFetcher::~BitmapFetcher() {}
 
-void BitmapFetcher::Start(net::URLRequestContextGetter* request_context) {
+void BitmapFetcher::Start(net::URLRequestContextGetter* request_context,
+                          const std::string& referrer,
+                          net::URLRequest::ReferrerPolicy referrer_policy,
+                          int load_flags) {
   if (url_fetcher_ != NULL)
     return;
 
   url_fetcher_.reset(net::URLFetcher::Create(url_, net::URLFetcher::GET, this));
   url_fetcher_->SetRequestContext(request_context);
+  url_fetcher_->SetReferrer(referrer);
+  url_fetcher_->SetReferrerPolicy(referrer_policy);
+  url_fetcher_->SetLoadFlags(load_flags);
   url_fetcher_->Start();
 }
 
diff --git a/chrome/browser/bitmap_fetcher.h b/chrome/browser/bitmap_fetcher.h
index b468c03..e531084 100644
--- a/chrome/browser/bitmap_fetcher.h
+++ b/chrome/browser/bitmap_fetcher.h
@@ -9,6 +9,7 @@
 #include "chrome/browser/bitmap_fetcher_delegate.h"
 #include "chrome/browser/image_decoder.h"
 #include "net/url_request/url_fetcher_delegate.h"
+#include "net/url_request/url_request.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "url/gurl.h"
 
@@ -32,8 +33,13 @@
   // Start fetching the URL with the fetcher. The delegate is notified
   // asynchronously when done.  Start may be called more than once in some
   // cases.  If so, subsequent starts will be ignored since the operation is
-  // already in progress.
-  void Start(net::URLRequestContextGetter* request_context);
+  // already in progress.  Arguments are used to configure the internal fetcher.
+  // Values for |load_flags| are defined in net/base/load_flags.h.  In general,
+  // |net::LOAD_NORMAL| is appropriate.
+  void Start(net::URLRequestContextGetter* request_context,
+             const std::string& referrer,
+             net::URLRequest::ReferrerPolicy referrer_policy,
+             int load_flags);
 
   // Methods inherited from URLFetcherDelegate
 
diff --git a/chrome/browser/bitmap_fetcher_browsertest.cc b/chrome/browser/bitmap_fetcher_browsertest.cc
index 534fa6e..3706d11 100644
--- a/chrome/browser/bitmap_fetcher_browsertest.cc
+++ b/chrome/browser/bitmap_fetcher_browsertest.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/test/test_utils.h"
+#include "net/base/load_flags.h"
 #include "net/http/http_status_code.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "net/url_request/url_fetcher.h"
@@ -113,7 +114,11 @@
 
   // We expect that the image decoder will get called and return
   // an image in a callback to OnImageDecoded().
-  fetcher.Start(browser()->profile()->GetRequestContext());
+  fetcher.Start(
+      browser()->profile()->GetRequestContext(),
+      std::string(),
+      net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+      net::LOAD_NORMAL);
 
   // Blocks until test delegate is notified via a callback.
   content::RunMessageLoop();
@@ -162,7 +167,11 @@
                                         net::HTTP_INTERNAL_SERVER_ERROR,
                                         net::URLRequestStatus::FAILED);
 
-  fetcher.Start(browser()->profile()->GetRequestContext());
+  fetcher.Start(
+      browser()->profile()->GetRequestContext(),
+      std::string(),
+      net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+      net::LOAD_NORMAL);
 
   // Blocks until test delegate is notified via a callback.
   content::RunMessageLoop();
@@ -186,7 +195,11 @@
                                         net::HTTP_OK,
                                         net::URLRequestStatus::SUCCESS);
 
-  fetcher.Start(browser()->profile()->GetRequestContext());
+  fetcher.Start(
+      browser()->profile()->GetRequestContext(),
+      std::string(),
+      net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+      net::LOAD_NORMAL);
 
   // Blocks until test delegate is notified via a callback.
   content::RunMessageLoop();
diff --git a/chrome/browser/bookmarks/DEPS b/chrome/browser/bookmarks/DEPS
index e7b25b7..2f599a7 100644
--- a/chrome/browser/bookmarks/DEPS
+++ b/chrome/browser/bookmarks/DEPS
@@ -15,7 +15,6 @@
   # and please do not introduce more #includes of these files.
   "!chrome/browser/history/history_service.h",
   "!chrome/browser/history/history_service_factory.h",
-  "!chrome/browser/history/query_parser.h",
   "!chrome/browser/history/url_database.h",
   "!chrome/browser/omnibox/omnibox_field_trial.h",
   "!chrome/browser/profiles/incognito_helpers.h",
diff --git a/chrome/browser/bookmarks/bookmark_codec_unittest.cc b/chrome/browser/bookmarks/bookmark_codec_unittest.cc
deleted file mode 100644
index 7eb76e9..0000000
--- a/chrome/browser/bookmarks/bookmark_codec_unittest.cc
+++ /dev/null
@@ -1,467 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "components/bookmarks/core/browser/bookmark_codec.h"
-
-#include "base/file_util.h"
-#include "base/files/file_path.h"
-#include "base/json/json_file_value_serializer.h"
-#include "base/json/json_string_value_serializer.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/path_service.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/browser/bookmarks/test_bookmark_client.h"
-#include "chrome/common/chrome_paths.h"
-#include "components/bookmarks/core/browser/bookmark_model.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::ASCIIToUTF16;
-
-namespace {
-
-const char kUrl1Title[] = "url1";
-const char kUrl1Url[] = "http://www.url1.com";
-const char kUrl2Title[] = "url2";
-const char kUrl2Url[] = "http://www.url2.com";
-const char kUrl3Title[] = "url3";
-const char kUrl3Url[] = "http://www.url3.com";
-const char kUrl4Title[] = "url4";
-const char kUrl4Url[] = "http://www.url4.com";
-const char kFolder1Title[] = "folder1";
-const char kFolder2Title[] = "folder2";
-
-// Helper to get a mutable bookmark node.
-BookmarkNode* AsMutable(const BookmarkNode* node) {
-  return const_cast<BookmarkNode*>(node);
-}
-
-// Helper to verify the two given bookmark nodes.
-void AssertNodesEqual(const BookmarkNode* expected,
-                      const BookmarkNode* actual) {
-  ASSERT_TRUE(expected);
-  ASSERT_TRUE(actual);
-  EXPECT_EQ(expected->id(), actual->id());
-  EXPECT_EQ(expected->GetTitle(), actual->GetTitle());
-  EXPECT_EQ(expected->type(), actual->type());
-  EXPECT_TRUE(expected->date_added() == actual->date_added());
-  if (expected->is_url()) {
-    EXPECT_EQ(expected->url(), actual->url());
-  } else {
-    EXPECT_TRUE(expected->date_folder_modified() ==
-                actual->date_folder_modified());
-    ASSERT_EQ(expected->child_count(), actual->child_count());
-    for (int i = 0; i < expected->child_count(); ++i)
-      AssertNodesEqual(expected->GetChild(i), actual->GetChild(i));
-  }
-}
-
-// Verifies that the two given bookmark models are the same.
-void AssertModelsEqual(BookmarkModel* expected, BookmarkModel* actual) {
-  ASSERT_NO_FATAL_FAILURE(AssertNodesEqual(expected->bookmark_bar_node(),
-                                           actual->bookmark_bar_node()));
-  ASSERT_NO_FATAL_FAILURE(
-      AssertNodesEqual(expected->other_node(), actual->other_node()));
-  ASSERT_NO_FATAL_FAILURE(
-      AssertNodesEqual(expected->mobile_node(), actual->mobile_node()));
-}
-
-}  // namespace
-
-class BookmarkCodecTest : public testing::Test {
- protected:
-  // Helpers to create bookmark models with different data.
-  BookmarkModel* CreateTestModel1() {
-    scoped_ptr<BookmarkModel> model(client_.CreateModel(false));
-    const BookmarkNode* bookmark_bar = model->bookmark_bar_node();
-    model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url));
-    return model.release();
-  }
-  BookmarkModel* CreateTestModel2() {
-    scoped_ptr<BookmarkModel> model(client_.CreateModel(false));
-    const BookmarkNode* bookmark_bar = model->bookmark_bar_node();
-    model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url));
-    model->AddURL(bookmark_bar, 1, ASCIIToUTF16(kUrl2Title), GURL(kUrl2Url));
-    return model.release();
-  }
-  BookmarkModel* CreateTestModel3() {
-    scoped_ptr<BookmarkModel> model(client_.CreateModel(false));
-    const BookmarkNode* bookmark_bar = model->bookmark_bar_node();
-    model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url));
-    const BookmarkNode* folder1 = model->AddFolder(bookmark_bar, 1,
-                                                   ASCIIToUTF16(kFolder1Title));
-    model->AddURL(folder1, 0, ASCIIToUTF16(kUrl2Title), GURL(kUrl2Url));
-    return model.release();
-  }
-
-  void GetBookmarksBarChildValue(base::Value* value,
-                                 size_t index,
-                                 base::DictionaryValue** result_value) {
-    ASSERT_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
-
-    base::DictionaryValue* d_value = static_cast<base::DictionaryValue*>(value);
-    base::Value* roots;
-    ASSERT_TRUE(d_value->Get(BookmarkCodec::kRootsKey, &roots));
-    ASSERT_EQ(base::Value::TYPE_DICTIONARY, roots->GetType());
-
-    base::DictionaryValue* roots_d_value =
-        static_cast<base::DictionaryValue*>(roots);
-    base::Value* bb_value;
-    ASSERT_TRUE(roots_d_value->Get(BookmarkCodec::kRootFolderNameKey,
-                                   &bb_value));
-    ASSERT_EQ(base::Value::TYPE_DICTIONARY, bb_value->GetType());
-
-    base::DictionaryValue* bb_d_value =
-        static_cast<base::DictionaryValue*>(bb_value);
-    base::Value* bb_children_value;
-    ASSERT_TRUE(bb_d_value->Get(BookmarkCodec::kChildrenKey,
-                                &bb_children_value));
-    ASSERT_EQ(base::Value::TYPE_LIST, bb_children_value->GetType());
-
-    base::ListValue* bb_children_l_value =
-        static_cast<base::ListValue*>(bb_children_value);
-    base::Value* child_value;
-    ASSERT_TRUE(bb_children_l_value->Get(index, &child_value));
-    ASSERT_EQ(base::Value::TYPE_DICTIONARY, child_value->GetType());
-
-    *result_value = static_cast<base::DictionaryValue*>(child_value);
-  }
-
-  base::Value* EncodeHelper(BookmarkModel* model, std::string* checksum) {
-    BookmarkCodec encoder;
-    // Computed and stored checksums should be empty.
-    EXPECT_EQ("", encoder.computed_checksum());
-    EXPECT_EQ("", encoder.stored_checksum());
-
-    scoped_ptr<base::Value> value(encoder.Encode(model));
-    const std::string& computed_checksum = encoder.computed_checksum();
-    const std::string& stored_checksum = encoder.stored_checksum();
-
-    // Computed and stored checksums should not be empty and should be equal.
-    EXPECT_FALSE(computed_checksum.empty());
-    EXPECT_FALSE(stored_checksum.empty());
-    EXPECT_EQ(computed_checksum, stored_checksum);
-
-    *checksum = computed_checksum;
-    return value.release();
-  }
-
-  bool Decode(BookmarkCodec* codec,
-              BookmarkModel* model,
-              const base::Value& value) {
-    int64 max_id;
-    bool result = codec->Decode(AsMutable(model->bookmark_bar_node()),
-                                AsMutable(model->other_node()),
-                                AsMutable(model->mobile_node()),
-                                &max_id, value);
-    model->set_next_node_id(max_id);
-    AsMutable(model->root_node())->
-        SetMetaInfoMap(codec->model_meta_info_map());
-    AsMutable(model->root_node())->
-        set_sync_transaction_version(codec->model_sync_transaction_version());
-
-    return result;
-  }
-
-  BookmarkModel* DecodeHelper(const base::Value& value,
-                              const std::string& expected_stored_checksum,
-                              std::string* computed_checksum,
-                              bool expected_changes) {
-    BookmarkCodec decoder;
-    // Computed and stored checksums should be empty.
-    EXPECT_EQ("", decoder.computed_checksum());
-    EXPECT_EQ("", decoder.stored_checksum());
-
-    scoped_ptr<BookmarkModel> model(client_.CreateModel(false));
-    EXPECT_TRUE(Decode(&decoder, model.get(), value));
-
-    *computed_checksum = decoder.computed_checksum();
-    const std::string& stored_checksum = decoder.stored_checksum();
-
-    // Computed and stored checksums should not be empty.
-    EXPECT_FALSE(computed_checksum->empty());
-    EXPECT_FALSE(stored_checksum.empty());
-
-    // Stored checksum should be as expected.
-    EXPECT_EQ(expected_stored_checksum, stored_checksum);
-
-    // The two checksums should be equal if expected_changes is true; otherwise
-    // they should be different.
-    if (expected_changes)
-      EXPECT_NE(*computed_checksum, stored_checksum);
-    else
-      EXPECT_EQ(*computed_checksum, stored_checksum);
-
-    return model.release();
-  }
-
-  void CheckIDs(const BookmarkNode* node, std::set<int64>* assigned_ids) {
-    DCHECK(node);
-    int64 node_id = node->id();
-    EXPECT_TRUE(assigned_ids->find(node_id) == assigned_ids->end());
-    assigned_ids->insert(node_id);
-    for (int i = 0; i < node->child_count(); ++i)
-      CheckIDs(node->GetChild(i), assigned_ids);
-  }
-
-  void ExpectIDsUnique(BookmarkModel* model) {
-    std::set<int64> assigned_ids;
-    CheckIDs(model->bookmark_bar_node(), &assigned_ids);
-    CheckIDs(model->other_node(), &assigned_ids);
-    CheckIDs(model->mobile_node(), &assigned_ids);
-  }
-
-  test::TestBookmarkClient client_;
-};
-
-TEST_F(BookmarkCodecTest, ChecksumEncodeDecodeTest) {
-  scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel1());
-  std::string enc_checksum;
-  scoped_ptr<base::Value> value(
-      EncodeHelper(model_to_encode.get(), &enc_checksum));
-
-  EXPECT_TRUE(value.get() != NULL);
-
-  std::string dec_checksum;
-  scoped_ptr<BookmarkModel> decoded_model(DecodeHelper(
-      *value.get(), enc_checksum, &dec_checksum, false));
-}
-
-TEST_F(BookmarkCodecTest, ChecksumEncodeIdenticalModelsTest) {
-  // Encode two identical models and make sure the check-sums are same as long
-  // as the data is the same.
-  scoped_ptr<BookmarkModel> model1(CreateTestModel1());
-  std::string enc_checksum1;
-  scoped_ptr<base::Value> value1(EncodeHelper(model1.get(), &enc_checksum1));
-  EXPECT_TRUE(value1.get() != NULL);
-
-  scoped_ptr<BookmarkModel> model2(CreateTestModel1());
-  std::string enc_checksum2;
-  scoped_ptr<base::Value> value2(EncodeHelper(model2.get(), &enc_checksum2));
-  EXPECT_TRUE(value2.get() != NULL);
-
-  ASSERT_EQ(enc_checksum1, enc_checksum2);
-}
-
-TEST_F(BookmarkCodecTest, ChecksumManualEditTest) {
-  scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel1());
-  std::string enc_checksum;
-  scoped_ptr<base::Value> value(
-      EncodeHelper(model_to_encode.get(), &enc_checksum));
-
-  EXPECT_TRUE(value.get() != NULL);
-
-  // Change something in the encoded value before decoding it.
-  base::DictionaryValue* child1_value;
-  GetBookmarksBarChildValue(value.get(), 0, &child1_value);
-  std::string title;
-  ASSERT_TRUE(child1_value->GetString(BookmarkCodec::kNameKey, &title));
-  child1_value->SetString(BookmarkCodec::kNameKey, title + "1");
-
-  std::string dec_checksum;
-  scoped_ptr<BookmarkModel> decoded_model1(DecodeHelper(
-      *value.get(), enc_checksum, &dec_checksum, true));
-
-  // Undo the change and make sure the checksum is same as original.
-  child1_value->SetString(BookmarkCodec::kNameKey, title);
-  scoped_ptr<BookmarkModel> decoded_model2(DecodeHelper(
-      *value.get(), enc_checksum, &dec_checksum, false));
-}
-
-TEST_F(BookmarkCodecTest, ChecksumManualEditIDsTest) {
-  scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel3());
-
-  // The test depends on existence of multiple children under bookmark bar, so
-  // make sure that's the case.
-  int bb_child_count = model_to_encode->bookmark_bar_node()->child_count();
-  ASSERT_GT(bb_child_count, 1);
-
-  std::string enc_checksum;
-  scoped_ptr<base::Value> value(
-      EncodeHelper(model_to_encode.get(), &enc_checksum));
-
-  EXPECT_TRUE(value.get() != NULL);
-
-  // Change IDs for all children of bookmark bar to be 1.
-  base::DictionaryValue* child_value;
-  for (int i = 0; i < bb_child_count; ++i) {
-    GetBookmarksBarChildValue(value.get(), i, &child_value);
-    std::string id;
-    ASSERT_TRUE(child_value->GetString(BookmarkCodec::kIdKey, &id));
-    child_value->SetString(BookmarkCodec::kIdKey, "1");
-  }
-
-  std::string dec_checksum;
-  scoped_ptr<BookmarkModel> decoded_model(DecodeHelper(
-      *value.get(), enc_checksum, &dec_checksum, true));
-
-  ExpectIDsUnique(decoded_model.get());
-
-  // add a few extra nodes to bookmark model and make sure IDs are still uniuqe.
-  const BookmarkNode* bb_node = decoded_model->bookmark_bar_node();
-  decoded_model->AddURL(bb_node, 0, ASCIIToUTF16("new url1"),
-                        GURL("http://newurl1.com"));
-  decoded_model->AddURL(bb_node, 0, ASCIIToUTF16("new url2"),
-                        GURL("http://newurl2.com"));
-
-  ExpectIDsUnique(decoded_model.get());
-}
-
-TEST_F(BookmarkCodecTest, PersistIDsTest) {
-  scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel3());
-  BookmarkCodec encoder;
-  scoped_ptr<base::Value> model_value(encoder.Encode(model_to_encode.get()));
-
-  scoped_ptr<BookmarkModel> decoded_model(client_.CreateModel(false));
-  BookmarkCodec decoder;
-  ASSERT_TRUE(Decode(&decoder, decoded_model.get(), *model_value.get()));
-  ASSERT_NO_FATAL_FAILURE(
-      AssertModelsEqual(model_to_encode.get(), decoded_model.get()));
-
-  // Add a couple of more items to the decoded bookmark model and make sure
-  // ID persistence is working properly.
-  const BookmarkNode* bookmark_bar = decoded_model->bookmark_bar_node();
-  decoded_model->AddURL(bookmark_bar,
-                        bookmark_bar->child_count(),
-                        ASCIIToUTF16(kUrl3Title),
-                        GURL(kUrl3Url));
-  const BookmarkNode* folder2_node = decoded_model->AddFolder(
-      bookmark_bar, bookmark_bar->child_count(), ASCIIToUTF16(kFolder2Title));
-  decoded_model->AddURL(
-      folder2_node, 0, ASCIIToUTF16(kUrl4Title), GURL(kUrl4Url));
-
-  BookmarkCodec encoder2;
-  scoped_ptr<base::Value> model_value2(encoder2.Encode(decoded_model.get()));
-
-  scoped_ptr<BookmarkModel> decoded_model2(client_.CreateModel(false));
-  BookmarkCodec decoder2;
-  ASSERT_TRUE(Decode(&decoder2, decoded_model2.get(), *model_value2.get()));
-  ASSERT_NO_FATAL_FAILURE(
-      AssertModelsEqual(decoded_model.get(), decoded_model2.get()));
-}
-
-TEST_F(BookmarkCodecTest, CanDecodeModelWithoutMobileBookmarks) {
-  base::FilePath test_data_directory;
-  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory));
-  base::FilePath test_file = test_data_directory.AppendASCII(
-      "bookmarks/model_without_sync.json");
-  ASSERT_TRUE(base::PathExists(test_file));
-
-  JSONFileValueSerializer serializer(test_file);
-  scoped_ptr<base::Value> root(serializer.Deserialize(NULL, NULL));
-
-  scoped_ptr<BookmarkModel> decoded_model(client_.CreateModel(false));
-  BookmarkCodec decoder;
-  ASSERT_TRUE(Decode(&decoder, decoded_model.get(), *root.get()));
-  ExpectIDsUnique(decoded_model.get());
-
-  const BookmarkNode* bbn = decoded_model->bookmark_bar_node();
-  ASSERT_EQ(1, bbn->child_count());
-
-  const BookmarkNode* child = bbn->GetChild(0);
-  EXPECT_EQ(BookmarkNode::FOLDER, child->type());
-  EXPECT_EQ(ASCIIToUTF16("Folder A"), child->GetTitle());
-  ASSERT_EQ(1, child->child_count());
-
-  child = child->GetChild(0);
-  EXPECT_EQ(BookmarkNode::URL, child->type());
-  EXPECT_EQ(ASCIIToUTF16("Bookmark Manager"), child->GetTitle());
-
-  const BookmarkNode* other = decoded_model->other_node();
-  ASSERT_EQ(1, other->child_count());
-
-  child = other->GetChild(0);
-  EXPECT_EQ(BookmarkNode::FOLDER, child->type());
-  EXPECT_EQ(ASCIIToUTF16("Folder B"), child->GetTitle());
-  ASSERT_EQ(1, child->child_count());
-
-  child = child->GetChild(0);
-  EXPECT_EQ(BookmarkNode::URL, child->type());
-  EXPECT_EQ(ASCIIToUTF16("Get started with Google Chrome"), child->GetTitle());
-
-  ASSERT_TRUE(decoded_model->mobile_node() != NULL);
-}
-
-TEST_F(BookmarkCodecTest, EncodeAndDecodeMetaInfo) {
-  // Add meta info and encode.
-  scoped_ptr<BookmarkModel> model(CreateTestModel1());
-  model->SetNodeMetaInfo(model->root_node(), "model_info", "value1");
-  model->SetNodeMetaInfo(model->bookmark_bar_node()->GetChild(0),
-                         "node_info", "value2");
-  std::string checksum;
-  scoped_ptr<base::Value> value(EncodeHelper(model.get(), &checksum));
-  ASSERT_TRUE(value.get() != NULL);
-
-  // Decode and check for meta info.
-  model.reset(DecodeHelper(*value, checksum, &checksum, false));
-  std::string meta_value;
-  EXPECT_TRUE(model->root_node()->GetMetaInfo("model_info", &meta_value));
-  EXPECT_EQ("value1", meta_value);
-  EXPECT_FALSE(model->root_node()->GetMetaInfo("other_key", &meta_value));
-  const BookmarkNode* bbn = model->bookmark_bar_node();
-  ASSERT_EQ(1, bbn->child_count());
-  const BookmarkNode* child = bbn->GetChild(0);
-  EXPECT_TRUE(child->GetMetaInfo("node_info", &meta_value));
-  EXPECT_EQ("value2", meta_value);
-  EXPECT_FALSE(child->GetMetaInfo("other_key", &meta_value));
-}
-
-TEST_F(BookmarkCodecTest, EncodeAndDecodeSyncTransactionVersion) {
-  // Add sync transaction version and encode.
-  scoped_ptr<BookmarkModel> model(CreateTestModel2());
-  model->SetNodeSyncTransactionVersion(model->root_node(), 1);
-  const BookmarkNode* bbn = model->bookmark_bar_node();
-  model->SetNodeSyncTransactionVersion(bbn->GetChild(1), 42);
-
-  std::string checksum;
-  scoped_ptr<base::Value> value(EncodeHelper(model.get(), &checksum));
-  ASSERT_TRUE(value.get() != NULL);
-
-  // Decode and verify.
-  model.reset(DecodeHelper(*value, checksum, &checksum, false));
-  EXPECT_EQ(1, model->root_node()->sync_transaction_version());
-  bbn = model->bookmark_bar_node();
-  EXPECT_EQ(42, bbn->GetChild(1)->sync_transaction_version());
-  EXPECT_EQ(BookmarkNode::kInvalidSyncTransactionVersion,
-            bbn->GetChild(0)->sync_transaction_version());
-}
-
-// Verifies that we can still decode the old codec format after changing the
-// way meta info is stored.
-TEST_F(BookmarkCodecTest, CanDecodeMetaInfoAsString) {
-  base::FilePath test_data_directory;
-  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory));
-  base::FilePath test_file = test_data_directory.AppendASCII(
-      "bookmarks/meta_info_as_string.json");
-  ASSERT_TRUE(base::PathExists(test_file));
-
-  JSONFileValueSerializer serializer(test_file);
-  scoped_ptr<base::Value> root(serializer.Deserialize(NULL, NULL));
-
-  scoped_ptr<BookmarkModel> model(client_.CreateModel(false));
-  BookmarkCodec decoder;
-  ASSERT_TRUE(Decode(&decoder, model.get(), *root.get()));
-
-  EXPECT_EQ(1, model->root_node()->sync_transaction_version());
-  const BookmarkNode* bbn = model->bookmark_bar_node();
-  EXPECT_EQ(BookmarkNode::kInvalidSyncTransactionVersion,
-            bbn->GetChild(0)->sync_transaction_version());
-  EXPECT_EQ(42, bbn->GetChild(1)->sync_transaction_version());
-
-  const char kSyncTransactionVersionKey[] = "sync.transaction_version";
-  const char kNormalKey[] = "key";
-  const char kNestedKey[] = "nested.key";
-  std::string meta_value;
-  EXPECT_FALSE(
-      model->root_node()->GetMetaInfo(kSyncTransactionVersionKey, &meta_value));
-  EXPECT_FALSE(bbn->GetChild(1)->GetMetaInfo(kSyncTransactionVersionKey,
-                                             &meta_value));
-  EXPECT_TRUE(bbn->GetChild(0)->GetMetaInfo(kNormalKey, &meta_value));
-  EXPECT_EQ("value", meta_value);
-  EXPECT_TRUE(bbn->GetChild(1)->GetMetaInfo(kNormalKey, &meta_value));
-  EXPECT_EQ("value2", meta_value);
-  EXPECT_TRUE(bbn->GetChild(0)->GetMetaInfo(kNestedKey, &meta_value));
-  EXPECT_EQ("value3", meta_value);
-}
diff --git a/chrome/browser/bookmarks/bookmark_expanded_state_tracker_unittest.cc b/chrome/browser/bookmarks/bookmark_expanded_state_tracker_unittest.cc
index 19798c9..ce53cbb 100644
--- a/chrome/browser/bookmarks/bookmark_expanded_state_tracker_unittest.cc
+++ b/chrome/browser/bookmarks/bookmark_expanded_state_tracker_unittest.cc
@@ -6,9 +6,9 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc
index 8d4796c..82bf59c 100644
--- a/chrome/browser/bookmarks/bookmark_html_writer.cc
+++ b/chrome/browser/bookmarks/bookmark_html_writer.cc
@@ -205,7 +205,7 @@
   // Writes out the text string (as UTF8). The text is escaped based on
   // type.
   bool Write(const std::string& text, TextType type) {
-    DCHECK(IsStringUTF8(text));
+    DCHECK(base::IsStringUTF8(text));
     std::string utf8_string;
 
     switch (type) {
diff --git a/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc b/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc
index a7df2c3..2d44669 100644
--- a/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc
+++ b/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/favicon/favicon_service.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/history/history_service.h"
@@ -23,6 +22,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/utility/importer/bookmark_html_reader.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "grit/component_strings.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/bookmarks/bookmark_index_unittest.cc b/chrome/browser/bookmarks/bookmark_index_unittest.cc
deleted file mode 100644
index 3814013..0000000
--- a/chrome/browser/bookmarks/bookmark_index_unittest.cc
+++ /dev/null
@@ -1,471 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "components/bookmarks/core/browser/bookmark_index.h"
-
-#include <string>
-#include <vector>
-
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
-#include "chrome/browser/bookmarks/test_bookmark_client.h"
-#include "chrome/browser/history/history_service.h"
-#include "chrome/browser/history/history_service_factory.h"
-#include "chrome/browser/history/url_database.h"
-#include "chrome/test/base/testing_profile.h"
-#include "components/bookmarks/core/browser/bookmark_match.h"
-#include "components/bookmarks/core/browser/bookmark_model.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::ASCIIToUTF16;
-
-class BookmarkIndexTest : public testing::Test {
- public:
-  BookmarkIndexTest() : model_(client_.CreateModel(false)) {}
-
-  typedef std::pair<std::string, std::string> TitleAndURL;
-
-  void AddBookmarks(const char** titles, const char** urls, size_t count) {
-    // The pair is (title, url).
-    std::vector<TitleAndURL> bookmarks;
-    for (size_t i = 0; i < count; ++i) {
-      TitleAndURL bookmark(titles[i], urls[i]);
-      bookmarks.push_back(bookmark);
-    }
-    AddBookmarks(bookmarks);
-  }
-
-  void AddBookmarks(const std::vector<TitleAndURL> bookmarks) {
-    for (size_t i = 0; i < bookmarks.size(); ++i) {
-      model_->AddURL(model_->other_node(), static_cast<int>(i),
-                     ASCIIToUTF16(bookmarks[i].first),
-                     GURL(bookmarks[i].second));
-    }
-  }
-
-  void ExpectMatches(const std::string& query,
-                     const char** expected_titles,
-                     size_t expected_count) {
-    std::vector<std::string> title_vector;
-    for (size_t i = 0; i < expected_count; ++i)
-      title_vector.push_back(expected_titles[i]);
-    ExpectMatches(query, title_vector);
-  }
-
-  void ExpectMatches(const std::string& query,
-                     const std::vector<std::string>& expected_titles) {
-    std::vector<BookmarkMatch> matches;
-    model_->GetBookmarksMatching(ASCIIToUTF16(query), 1000, &matches);
-    ASSERT_EQ(expected_titles.size(), matches.size());
-    for (size_t i = 0; i < expected_titles.size(); ++i) {
-      bool found = false;
-      for (size_t j = 0; j < matches.size(); ++j) {
-        if (ASCIIToUTF16(expected_titles[i]) == matches[j].node->GetTitle()) {
-          matches.erase(matches.begin() + j);
-          found = true;
-          break;
-        }
-      }
-      ASSERT_TRUE(found);
-    }
-  }
-
-  void ExtractMatchPositions(const std::string& string,
-                             BookmarkMatch::MatchPositions* matches) {
-    std::vector<std::string> match_strings;
-    base::SplitString(string, ':', &match_strings);
-    for (size_t i = 0; i < match_strings.size(); ++i) {
-      std::vector<std::string> chunks;
-      base::SplitString(match_strings[i], ',', &chunks);
-      ASSERT_EQ(2U, chunks.size());
-      matches->push_back(BookmarkMatch::MatchPosition());
-      int chunks0, chunks1;
-      base::StringToInt(chunks[0], &chunks0);
-      base::StringToInt(chunks[1], &chunks1);
-      matches->back().first = chunks0;
-      matches->back().second = chunks1;
-    }
-  }
-
-  void ExpectMatchPositions(
-      const BookmarkMatch::MatchPositions& actual_positions,
-      const BookmarkMatch::MatchPositions& expected_positions) {
-    ASSERT_EQ(expected_positions.size(), actual_positions.size());
-    for (size_t i = 0; i < expected_positions.size(); ++i) {
-      EXPECT_EQ(expected_positions[i].first, actual_positions[i].first);
-      EXPECT_EQ(expected_positions[i].second, actual_positions[i].second);
-    }
-  }
-
- protected:
-  test::TestBookmarkClient client_;
-  scoped_ptr<BookmarkModel> model_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BookmarkIndexTest);
-};
-
-// Various permutations with differing input, queries and output that exercises
-// all query paths.
-TEST_F(BookmarkIndexTest, GetBookmarksMatching) {
-  struct TestData {
-    const std::string titles;
-    const std::string query;
-    const std::string expected;
-  } data[] = {
-    // Trivial test case of only one term, exact match.
-    { "a;b",                        "A",        "a" },
-
-    // Prefix match, one term.
-    { "abcd;abc;b",                 "abc",      "abcd;abc" },
-
-    // Prefix match, multiple terms.
-    { "abcd cdef;abcd;abcd cdefg",  "abc cde",  "abcd cdef;abcd cdefg"},
-
-    // Exact and prefix match.
-    { "ab cdef;abcd;abcd cdefg",    "ab cdef",  "ab cdef"},
-
-    // Exact and prefix match.
-    { "ab cdef ghij;ab;cde;cdef;ghi;cdef ab;ghij ab",
-      "ab cde ghi",
-      "ab cdef ghij"},
-
-    // Title with term multiple times.
-    { "ab ab",                      "ab",       "ab ab"},
-
-    // Make sure quotes don't do a prefix match.
-    { "think",                      "\"thi\"",  ""},
-
-    // Prefix matches against multiple candidates.
-    { "abc1 abc2 abc3 abc4", "abc", "abc1 abc2 abc3 abc4"},
-  };
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
-    std::vector<std::string> titles;
-    base::SplitString(data[i].titles, ';', &titles);
-    std::vector<TitleAndURL> bookmarks;
-    for (size_t j = 0; j < titles.size(); ++j) {
-      TitleAndURL bookmark(titles[j], "about:blank");
-      bookmarks.push_back(bookmark);
-    }
-    AddBookmarks(bookmarks);
-
-    std::vector<std::string> expected;
-    if (!data[i].expected.empty())
-      base::SplitString(data[i].expected, ';', &expected);
-
-    ExpectMatches(data[i].query, expected);
-
-    model_ = client_.CreateModel(false);
-  }
-}
-
-// Analogous to GetBookmarksMatching, this test tests various permutations
-// of title, URL, and input to see if the title/URL matches the input as
-// expected.
-TEST_F(BookmarkIndexTest, GetBookmarksMatchingWithURLs) {
-  struct TestData {
-    const std::string query;
-    const std::string title;
-    const std::string url;
-    const bool should_be_retrieved;
-  } data[] = {
-    // Test single-word inputs.  Include both exact matches and prefix matches.
-    { "foo", "Foo",    "http://www.bar.com/",    true  },
-    { "foo", "Foodie", "http://www.bar.com/",    true  },
-    { "foo", "Bar",    "http://www.foo.com/",    true  },
-    { "foo", "Bar",    "http://www.foodie.com/", true  },
-    { "foo", "Foo",    "http://www.foo.com/",    true  },
-    { "foo", "Bar",    "http://www.bar.com/",    false },
-    { "foo", "Bar",    "http://www.bar.com/blah/foo/blah-again/ ",    true  },
-    { "foo", "Bar",    "http://www.bar.com/blah/foodie/blah-again/ ", true  },
-    { "foo", "Bar",    "http://www.bar.com/blah-foo/blah-again/ ",    true  },
-    { "foo", "Bar",    "http://www.bar.com/blah-foodie/blah-again/ ", true  },
-    { "foo", "Bar",    "http://www.bar.com/blahafoo/blah-again/ ",    false },
-
-    // Test multi-word inputs.
-    { "foo bar", "Foo Bar",      "http://baz.com/",   true  },
-    { "foo bar", "Foodie Bar",   "http://baz.com/",   true  },
-    { "bar foo", "Foo Bar",      "http://baz.com/",   true  },
-    { "bar foo", "Foodie Barly", "http://baz.com/",   true  },
-    { "foo bar", "Foo Baz",      "http://baz.com/",   false },
-    { "foo bar", "Foo Baz",      "http://bar.com/",   true  },
-    { "foo bar", "Foo Baz",      "http://barly.com/", true  },
-    { "foo bar", "Foodie Baz",   "http://barly.com/", true  },
-    { "bar foo", "Foo Baz",      "http://bar.com/",   true  },
-    { "bar foo", "Foo Baz",      "http://barly.com/", true  },
-    { "foo bar", "Baz Bar",      "http://blah.com/foo",         true  },
-    { "foo bar", "Baz Barly",    "http://blah.com/foodie",      true  },
-    { "foo bar", "Baz Bur",      "http://blah.com/foo/bar",     true  },
-    { "foo bar", "Baz Bur",      "http://blah.com/food/barly",  true  },
-    { "foo bar", "Baz Bur",      "http://bar.com/blah/foo",     true  },
-    { "foo bar", "Baz Bur",      "http://barly.com/blah/food",  true  },
-    { "foo bar", "Baz Bur",      "http://bar.com/blah/flub",    false },
-    { "foo bar", "Baz Bur",      "http://foo.com/blah/flub",    false }
-  };
-
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
-    model_ = client_.CreateModel(true);
-    std::vector<TitleAndURL> bookmarks;
-    bookmarks.push_back(TitleAndURL(data[i].title, data[i].url));
-    AddBookmarks(bookmarks);
-
-    std::vector<std::string> expected;
-    if (data[i].should_be_retrieved)
-      expected.push_back(data[i].title);
-
-    ExpectMatches(data[i].query, expected);
-  }
-}
-
-TEST_F(BookmarkIndexTest, Normalization) {
-  struct TestData {
-    const char* title;
-    const char* query;
-  } data[] = {
-    { "fooa\xcc\x88-test", "foo\xc3\xa4-test" },
-    { "fooa\xcc\x88-test", "fooa\xcc\x88-test" },
-    { "fooa\xcc\x88-test", "foo\xc3\xa4" },
-    { "fooa\xcc\x88-test", "fooa\xcc\x88" },
-    { "fooa\xcc\x88-test", "foo" },
-    { "foo\xc3\xa4-test", "foo\xc3\xa4-test" },
-    { "foo\xc3\xa4-test", "fooa\xcc\x88-test" },
-    { "foo\xc3\xa4-test", "foo\xc3\xa4" },
-    { "foo\xc3\xa4-test", "fooa\xcc\x88" },
-    { "foo\xc3\xa4-test", "foo" },
-    { "foo", "foo" }
-  };
-
-  GURL url("about:blank");
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
-    model_->AddURL(model_->other_node(), 0, base::UTF8ToUTF16(data[i].title),
-                   url);
-    std::vector<BookmarkMatch> matches;
-    model_->GetBookmarksMatching(
-        base::UTF8ToUTF16(data[i].query), 10, &matches);
-    EXPECT_EQ(1u, matches.size());
-    model_ = client_.CreateModel(false);
-  }
-}
-
-// Makes sure match positions are updated appropriately for title matches.
-TEST_F(BookmarkIndexTest, MatchPositionsTitles) {
-  struct TestData {
-    const std::string title;
-    const std::string query;
-    const std::string expected_title_match_positions;
-  } data[] = {
-    // Trivial test case of only one term, exact match.
-    { "a",                        "A",        "0,1" },
-    { "foo bar",                  "bar",      "4,7" },
-    { "fooey bark",               "bar foo",  "0,3:6,9" },
-    // Non-trivial tests.
-    { "foobar foo",               "foobar foo",   "0,6:7,10" },
-    { "foobar foo",               "foo foobar",   "0,6:7,10" },
-    { "foobar foobar",            "foobar foo",   "0,6:7,13" },
-    { "foobar foobar",            "foo foobar",   "0,6:7,13" },
-  };
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
-    std::vector<TitleAndURL> bookmarks;
-    TitleAndURL bookmark(data[i].title, "about:blank");
-    bookmarks.push_back(bookmark);
-    AddBookmarks(bookmarks);
-
-    std::vector<BookmarkMatch> matches;
-    model_->GetBookmarksMatching(ASCIIToUTF16(data[i].query), 1000, &matches);
-    ASSERT_EQ(1U, matches.size());
-
-    BookmarkMatch::MatchPositions expected_title_matches;
-    ExtractMatchPositions(data[i].expected_title_match_positions,
-                          &expected_title_matches);
-    ExpectMatchPositions(matches[0].title_match_positions,
-                         expected_title_matches);
-
-    model_ = client_.CreateModel(false);
-  }
-}
-
-// Makes sure match positions are updated appropriately for URL matches.
-TEST_F(BookmarkIndexTest, MatchPositionsURLs) {
-  // The encoded stuff between /wiki/ and the # is 第二次世界大戦
-  const std::string ja_wiki_url = "http://ja.wikipedia.org/wiki/%E7%AC%AC%E4"
-      "%BA%8C%E6%AC%A1%E4%B8%96%E7%95%8C%E5%A4%A7%E6%88%A6#.E3.83.B4.E3.82.A7"
-      ".E3.83.AB.E3.82.B5.E3.82.A4.E3.83.A6.E4.BD.93.E5.88.B6";
-  struct TestData {
-    const std::string query;
-    const std::string url;
-    const std::string expected_url_match_positions;
-  } data[] = {
-    { "foo",        "http://www.foo.com/",    "11,14" },
-    { "foo",        "http://www.foodie.com/", "11,14" },
-    { "foo",        "http://www.foofoo.com/", "11,14" },
-    { "www",        "http://www.foo.com/",    "7,10"  },
-    { "foo",        "http://www.foodie.com/blah/foo/fi", "11,14:27,30"      },
-    { "foo",        "http://www.blah.com/blah/foo/fi",   "25,28"            },
-    { "foo www",    "http://www.foodie.com/blah/foo/fi", "7,10:11,14:27,30" },
-    { "www foo",    "http://www.foodie.com/blah/foo/fi", "7,10:11,14:27,30" },
-    { "www bla",    "http://www.foodie.com/blah/foo/fi", "7,10:22,25"       },
-    { "http",       "http://www.foo.com/",               "0,4"              },
-    { "http www",   "http://www.foo.com/",               "0,4:7,10"         },
-    { "http foo",   "http://www.foo.com/",               "0,4:11,14"        },
-    { "http foo",   "http://www.bar.com/baz/foodie/hi",  "0,4:23,26"        },
-    { "第二次",      ja_wiki_url,                         "29,56"            },
-    { "ja 第二次",   ja_wiki_url,                         "7,9:29,56"        },
-    { "第二次 E3.8", ja_wiki_url,                         "29,56:94,98:103,107:"
-                                                         "112,116:121,125:"
-                                                         "130,134:139,143"  }
-  };
-
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
-    model_ = client_.CreateModel(true);
-    std::vector<TitleAndURL> bookmarks;
-    TitleAndURL bookmark("123456", data[i].url);
-    bookmarks.push_back(bookmark);
-    AddBookmarks(bookmarks);
-
-    std::vector<BookmarkMatch> matches;
-    model_->GetBookmarksMatching(
-        base::UTF8ToUTF16(data[i].query), 1000, &matches);
-    ASSERT_EQ(1U, matches.size()) << data[i].url << data[i].query;
-
-    BookmarkMatch::MatchPositions expected_url_matches;
-    ExtractMatchPositions(data[i].expected_url_match_positions,
-                          &expected_url_matches);
-    ExpectMatchPositions(matches[0].url_match_positions, expected_url_matches);
-  }
-}
-
-// Makes sure index is updated when a node is removed.
-TEST_F(BookmarkIndexTest, Remove) {
-  const char* titles[] = { "a", "b" };
-  const char* urls[] = { "about:blank", "about:blank" };
-  AddBookmarks(titles, urls, ARRAYSIZE_UNSAFE(titles));
-
-  // Remove the node and make sure we don't get back any results.
-  model_->Remove(model_->other_node(), 0);
-  ExpectMatches("A", NULL, 0U);
-}
-
-// Makes sure index is updated when a node's title is changed.
-TEST_F(BookmarkIndexTest, ChangeTitle) {
-  const char* titles[] = { "a", "b" };
-  const char* urls[] = { "about:blank", "about:blank" };
-  AddBookmarks(titles, urls, ARRAYSIZE_UNSAFE(titles));
-
-  // Remove the node and make sure we don't get back any results.
-  const char* expected[] = { "blah" };
-  model_->SetTitle(model_->other_node()->GetChild(0), ASCIIToUTF16("blah"));
-  ExpectMatches("BlAh", expected, ARRAYSIZE_UNSAFE(expected));
-}
-
-// Makes sure no more than max queries is returned.
-TEST_F(BookmarkIndexTest, HonorMax) {
-  const char* titles[] = { "abcd", "abcde" };
-  const char* urls[] = { "about:blank", "about:blank" };
-  AddBookmarks(titles, urls, ARRAYSIZE_UNSAFE(titles));
-
-  std::vector<BookmarkMatch> matches;
-  model_->GetBookmarksMatching(ASCIIToUTF16("ABc"), 1, &matches);
-  EXPECT_EQ(1U, matches.size());
-}
-
-// Makes sure if the lower case string of a bookmark title is more characters
-// than the upper case string no match positions are returned.
-TEST_F(BookmarkIndexTest, EmptyMatchOnMultiwideLowercaseString) {
-  const BookmarkNode* n1 = model_->AddURL(model_->other_node(), 0,
-                                          base::WideToUTF16(L"\u0130 i"),
-                                          GURL("http://www.google.com"));
-
-  std::vector<BookmarkMatch> matches;
-  model_->GetBookmarksMatching(ASCIIToUTF16("i"), 100, &matches);
-  ASSERT_EQ(1U, matches.size());
-  EXPECT_TRUE(matches[0].node == n1);
-  EXPECT_TRUE(matches[0].title_match_positions.empty());
-}
-
-TEST_F(BookmarkIndexTest, GetResultsSortedByTypedCount) {
-  // This ensures MessageLoop::current() will exist, which is needed by
-  // TestingProfile::BlockUntilHistoryProcessesPendingRequests().
-  content::TestBrowserThreadBundle thread_bundle;
-
-  TestingProfile profile;
-  ASSERT_TRUE(profile.CreateHistoryService(true, false));
-  profile.BlockUntilHistoryProcessesPendingRequests();
-  profile.CreateBookmarkModel(true);
-
-  BookmarkModel* model = BookmarkModelFactory::GetForProfile(&profile);
-  test::WaitForBookmarkModelToLoad(model);
-
-  HistoryService* const history_service =
-      HistoryServiceFactory::GetForProfile(&profile, Profile::EXPLICIT_ACCESS);
-
-  history::URLDatabase* url_db = history_service->InMemoryDatabase();
-
-  struct TestData {
-    const GURL url;
-    const char* title;
-    const int typed_count;
-  } data[] = {
-    { GURL("http://www.google.com/"),      "Google",           100 },
-    { GURL("http://maps.google.com/"),     "Google Maps",       40 },
-    { GURL("http://docs.google.com/"),     "Google Docs",       50 },
-    { GURL("http://reader.google.com/"),   "Google Reader",     80 },
-  };
-
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
-    history::URLRow info(data[i].url);
-    info.set_title(base::UTF8ToUTF16(data[i].title));
-    info.set_typed_count(data[i].typed_count);
-    // Populate the InMemoryDatabase....
-    url_db->AddURL(info);
-    // Populate the BookmarkIndex.
-    model->AddURL(model->other_node(), i, base::UTF8ToUTF16(data[i].title),
-                  data[i].url);
-  }
-
-  // Check that the InMemoryDatabase stored the URLs properly.
-  history::URLRow result1;
-  url_db->GetRowForURL(data[0].url, &result1);
-  EXPECT_EQ(data[0].title, base::UTF16ToUTF8(result1.title()));
-
-  history::URLRow result2;
-  url_db->GetRowForURL(data[1].url, &result2);
-  EXPECT_EQ(data[1].title, base::UTF16ToUTF8(result2.title()));
-
-  history::URLRow result3;
-  url_db->GetRowForURL(data[2].url, &result3);
-  EXPECT_EQ(data[2].title, base::UTF16ToUTF8(result3.title()));
-
-  history::URLRow result4;
-  url_db->GetRowForURL(data[3].url, &result4);
-  EXPECT_EQ(data[3].title, base::UTF16ToUTF8(result4.title()));
-
-  // Populate match nodes.
-  std::vector<BookmarkMatch> matches;
-  model->GetBookmarksMatching(ASCIIToUTF16("google"), 4, &matches);
-
-  // The resulting order should be:
-  // 1. Google (google.com) 100
-  // 2. Google Reader (google.com/reader) 80
-  // 3. Google Docs (docs.google.com) 50
-  // 4. Google Maps (maps.google.com) 40
-  EXPECT_EQ(4, static_cast<int>(matches.size()));
-  EXPECT_EQ(data[0].url, matches[0].node->url());
-  EXPECT_EQ(data[3].url, matches[1].node->url());
-  EXPECT_EQ(data[2].url, matches[2].node->url());
-  EXPECT_EQ(data[1].url, matches[3].node->url());
-
-  matches.clear();
-  // Select top two matches.
-  model->GetBookmarksMatching(ASCIIToUTF16("google"), 2, &matches);
-
-  EXPECT_EQ(2, static_cast<int>(matches.size()));
-  EXPECT_EQ(data[0].url, matches[0].node->url());
-  EXPECT_EQ(data[3].url, matches[1].node->url());
-}
diff --git a/chrome/browser/bookmarks/bookmark_model_factory.cc b/chrome/browser/bookmarks/bookmark_model_factory.cc
index 92e0e35..0b068fe 100644
--- a/chrome/browser/bookmarks/bookmark_model_factory.cc
+++ b/chrome/browser/bookmarks/bookmark_model_factory.cc
@@ -65,8 +65,13 @@
       content::BrowserThread::GetMessageLoopProxyForThread(
           content::BrowserThread::UI));
 #if !defined(OS_ANDROID)
-  if (CommandLine::ForCurrentProcess()->HasSwitch(
-     switches::kEnableBookmarkUndo)) {
+  bool register_bookmark_undo_service_as_observer = true;
+#if !defined(OS_IOS)
+  register_bookmark_undo_service_as_observer =
+      CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableBookmarkUndo);
+#endif  // !defined(OS_IOS)
+  if (register_bookmark_undo_service_as_observer) {
     bookmark_client->model()->AddObserver(
         BookmarkUndoServiceFactory::GetForProfile(profile));
   }
diff --git a/chrome/browser/bookmarks/bookmark_model_unittest.cc b/chrome/browser/bookmarks/bookmark_model_unittest.cc
index 8f68122..8198b21 100644
--- a/chrome/browser/bookmarks/bookmark_model_unittest.cc
+++ b/chrome/browser/bookmarks/bookmark_model_unittest.cc
@@ -20,11 +20,11 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
-#include "chrome/browser/bookmarks/test_bookmark_client.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model_observer.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
+#include "components/bookmarks/core/test/test_bookmark_client.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/models/tree_node_iterator.h"
@@ -175,10 +175,12 @@
     ++before_remove_count_;
   }
 
-  virtual void BookmarkNodeRemoved(BookmarkModel* model,
-                                   const BookmarkNode* parent,
-                                   int old_index,
-                                   const BookmarkNode* node) OVERRIDE {
+  virtual void BookmarkNodeRemoved(
+      BookmarkModel* model,
+      const BookmarkNode* parent,
+      int old_index,
+      const BookmarkNode* node,
+      const std::set<GURL>& removed_urls) OVERRIDE {
     ++removed_count_;
     observer_details_.Set(parent, NULL, old_index, -1);
   }
@@ -220,7 +222,9 @@
     ++extensive_changes_ended_count_;
   }
 
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE {
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE {
     ++all_bookmarks_removed_;
   }
 
diff --git a/chrome/browser/bookmarks/bookmark_node_data_unittest.cc b/chrome/browser/bookmarks/bookmark_node_data_unittest.cc
index e2d8c6d..5c23cd3 100644
--- a/chrome/browser/bookmarks/bookmark_node_data_unittest.cc
+++ b/chrome/browser/bookmarks/bookmark_node_data_unittest.cc
@@ -8,10 +8,10 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
 #include "components/bookmarks/core/browser/bookmark_node_data.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/dragdrop/os_exchange_data.h"
diff --git a/chrome/browser/bookmarks/bookmark_test_helpers.cc b/chrome/browser/bookmarks/bookmark_test_helpers.cc
deleted file mode 100644
index 1638bcf..0000000
--- a/chrome/browser/bookmarks/bookmark_test_helpers.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/run_loop.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "components/bookmarks/core/browser/base_bookmark_model_observer.h"
-#include "components/bookmarks/core/browser/bookmark_model.h"
-#include "url/gurl.h"
-
-namespace {
-
-// BookmarkLoadObserver is used when blocking until the BookmarkModel finishes
-// loading. As soon as the BookmarkModel finishes loading the message loop is
-// quit.
-class BookmarkLoadObserver : public BaseBookmarkModelObserver {
- public:
-  explicit BookmarkLoadObserver(const base::Closure& quit_task);
-  virtual ~BookmarkLoadObserver();
-
- private:
-  // BaseBookmarkModelObserver:
-  virtual void BookmarkModelChanged() OVERRIDE;
-  virtual void BookmarkModelLoaded(BookmarkModel* model,
-                                   bool ids_reassigned) OVERRIDE;
-
-  base::Closure quit_task_;
-
-  DISALLOW_COPY_AND_ASSIGN(BookmarkLoadObserver);
-};
-
-BookmarkLoadObserver::BookmarkLoadObserver(const base::Closure& quit_task)
-    : quit_task_(quit_task) {}
-
-BookmarkLoadObserver::~BookmarkLoadObserver() {}
-
-void BookmarkLoadObserver::BookmarkModelChanged() {}
-
-void BookmarkLoadObserver::BookmarkModelLoaded(BookmarkModel* model,
-                                               bool ids_reassigned) {
-  quit_task_.Run();
-}
-
-// Helper function which does the actual work of creating the nodes for
-// a particular level in the hierarchy.
-std::string::size_type AddNodesFromString(BookmarkModel* model,
-                                          const BookmarkNode* node,
-                                          const std::string& model_string,
-                                          std::string::size_type start_pos) {
-  DCHECK(node);
-  int index = node->child_count();
-  static const std::string folder_tell(":[");
-  std::string::size_type end_pos = model_string.find(' ', start_pos);
-  while (end_pos != std::string::npos) {
-    std::string::size_type part_length = end_pos - start_pos;
-    std::string node_name = model_string.substr(start_pos, part_length);
-    // Are we at the end of a folder group?
-    if (node_name != "]") {
-      // No, is it a folder?
-      std::string tell;
-      if (part_length > 2)
-        tell = node_name.substr(part_length - 2, 2);
-      if (tell == folder_tell) {
-        node_name = node_name.substr(0, part_length - 2);
-        const BookmarkNode* new_node =
-            model->AddFolder(node, index, base::UTF8ToUTF16(node_name));
-        end_pos = AddNodesFromString(model, new_node, model_string,
-                                     end_pos + 1);
-      } else {
-        std::string url_string("http://");
-        url_string += std::string(node_name.begin(), node_name.end());
-        url_string += ".com";
-        model->AddURL(
-            node, index, base::UTF8ToUTF16(node_name), GURL(url_string));
-        ++end_pos;
-      }
-      ++index;
-      start_pos = end_pos;
-      end_pos = model_string.find(' ', start_pos);
-    } else {
-      ++end_pos;
-      break;
-    }
-  }
-  return end_pos;
-}
-
-}  // namespace
-
-namespace test {
-
-void WaitForBookmarkModelToLoad(BookmarkModel* model) {
-  if (model->loaded())
-    return;
-  base::RunLoop run_loop;
-  base::MessageLoop::ScopedNestableTaskAllower allow(
-      base::MessageLoop::current());
-
-  BookmarkLoadObserver observer(run_loop.QuitClosure());
-  model->AddObserver(&observer);
-  run_loop.Run();
-  model->RemoveObserver(&observer);
-  DCHECK(model->loaded());
-}
-
-void WaitForBookmarkModelToLoad(Profile* profile) {
-  WaitForBookmarkModelToLoad(BookmarkModelFactory::GetForProfile(profile));
-}
-
-std::string ModelStringFromNode(const BookmarkNode* node) {
-  // Since the children of the node are not available as a vector,
-  // we'll just have to do it the hard way.
-  int child_count = node->child_count();
-  std::string child_string;
-  for (int i = 0; i < child_count; ++i) {
-    const BookmarkNode* child = node->GetChild(i);
-    if (child->is_folder()) {
-      child_string += base::UTF16ToUTF8(child->GetTitle()) + ":[ " +
-          ModelStringFromNode(child) + "] ";
-    } else {
-      child_string += base::UTF16ToUTF8(child->GetTitle()) + " ";
-    }
-  }
-  return child_string;
-}
-
-void AddNodesFromModelString(BookmarkModel* model,
-                             const BookmarkNode* node,
-                             const std::string& model_string) {
-  DCHECK(node);
-  std::string::size_type start_pos = 0;
-  std::string::size_type end_pos =
-      AddNodesFromString(model, node, model_string, start_pos);
-  DCHECK(end_pos == std::string::npos);
-}
-
-}  // namespace test
diff --git a/chrome/browser/bookmarks/bookmark_test_helpers.h b/chrome/browser/bookmarks/bookmark_test_helpers.h
deleted file mode 100644
index 7b52cab..0000000
--- a/chrome/browser/bookmarks/bookmark_test_helpers.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_BOOKMARKS_BOOKMARK_TEST_HELPERS_H_
-#define CHROME_BROWSER_BOOKMARKS_BOOKMARK_TEST_HELPERS_H_
-
-#include <string>
-
-class BookmarkModel;
-class BookmarkNode;
-class Profile;
-
-namespace test {
-
-// Blocks until |model| finishes loading.
-void WaitForBookmarkModelToLoad(BookmarkModel* model);
-void WaitForBookmarkModelToLoad(Profile* profile);
-
-// Return the descendants of |node| as a string useful for verifying node
-// modifications. The format of the resulting string is:
-//
-//           result = node " " , { node " " }
-//             node = bookmark title | folder
-//           folder = folder title ":[ " { node " " } "]"
-//   bookmark title = (* string with no spaces *)
-//     folder title = (* string with no spaces *)
-//
-// Example: "a f1:[ b d c ] d f2:[ e f g ] h "
-//
-// (Logically, we should use |string16|s, but it's more convenient for test
-// purposes to use (UTF-8) |std::string|s.)
-std::string ModelStringFromNode(const BookmarkNode* node);
-
-// Create and add the node hierarchy specified by |model_string| to the
-// bookmark node given by |node|. The string has the same format as
-// specified for ModelStringFromNode(). The new nodes added to |node|
-// are appended to the end of node's existing subnodes, if any.
-// |model| must be the model of which |node| is a member.
-// NOTE: The string format is very rigid and easily broken if not followed
-//       exactly (since we're using a very simple parser).
-void AddNodesFromModelString(BookmarkModel* model,
-                             const BookmarkNode* node,
-                             const std::string& model_string);
-}  // namespace test
-
-#endif  // CHROME_BROWSER_BOOKMARKS_BOOKMARK_TEST_HELPERS_H_
diff --git a/chrome/browser/bookmarks/bookmark_utils_unittest.cc b/chrome/browser/bookmarks/bookmark_utils_unittest.cc
index 97bfd32..d090f36 100644
--- a/chrome/browser/bookmarks/bookmark_utils_unittest.cc
+++ b/chrome/browser/bookmarks/bookmark_utils_unittest.cc
@@ -8,10 +8,10 @@
 
 #include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/test_bookmark_client.h"
 #include "components/bookmarks/core/browser/base_bookmark_model_observer.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
 #include "components/bookmarks/core/browser/bookmark_node_data.h"
+#include "components/bookmarks/core/test/test_bookmark_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/clipboard/clipboard.h"
 #include "ui/base/clipboard/scoped_clipboard_writer.h"
@@ -30,9 +30,12 @@
         grouped_changes_ended_count_(0) {}
   virtual ~BookmarkUtilsTest() {}
 
+// Copy and paste is not yet supported on iOS. http://crbug.com/228147
+#if !defined(OS_IOS)
   virtual void TearDown() OVERRIDE {
     ui::Clipboard::DestroyClipboardForCurrentThread();
   }
+#endif  // !defined(OS_IOS)
 
   // Certain user actions require multiple changes to the bookmark model,
   // however these modifications need to be atomic for the undo framework. The
@@ -252,6 +255,8 @@
   }
 }
 
+// Copy and paste is not yet supported on iOS. http://crbug.com/228147
+#if !defined(OS_IOS)
 TEST_F(BookmarkUtilsTest, CopyPaste) {
   test::TestBookmarkClient client;
   scoped_ptr<BookmarkModel> model(client.CreateModel(false));
@@ -305,6 +310,7 @@
   // And make sure we can paste from the clipboard.
   EXPECT_TRUE(CanPasteFromClipboard(model->other_node()));
 }
+#endif  // !defined(OS_IOS)
 
 TEST_F(BookmarkUtilsTest, GetParentForNewNodes) {
   test::TestBookmarkClient client;
diff --git a/chrome/browser/bookmarks/chrome_bookmark_client.cc b/chrome/browser/bookmarks/chrome_bookmark_client.cc
index dfbac89..ec50ffa 100644
--- a/chrome/browser/bookmarks/chrome_bookmark_client.cc
+++ b/chrome/browser/bookmarks/chrome_bookmark_client.cc
@@ -17,9 +17,22 @@
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/user_metrics.h"
 
+namespace {
+
+void NotifyHistoryOfRemovedURLs(Profile* profile,
+                                const std::set<GURL>& removed_urls) {
+  HistoryService* history_service =
+      HistoryServiceFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS);
+  if (history_service)
+    history_service->URLsNoLongerBookmarked(removed_urls);
+}
+
+}  // namespace
+
 ChromeBookmarkClient::ChromeBookmarkClient(Profile* profile, bool index_urls)
     : profile_(profile),
       model_(new BookmarkModel(this, index_urls)) {
+  model_->AddObserver(this);
   // Listen for changes to favicons so that we can update the favicon of the
   // node appropriately.
   registrar_.Add(this,
@@ -28,9 +41,19 @@
 }
 
 ChromeBookmarkClient::~ChromeBookmarkClient() {
+  model_->RemoveObserver(this);
+
   registrar_.RemoveAll();
 }
 
+bool ChromeBookmarkClient::PreferTouchIcon() {
+#if !defined(OS_IOS)
+  return false;
+#else
+  return true;
+#endif
+}
+
 base::CancelableTaskTracker::TaskId ChromeBookmarkClient::GetFaviconImageForURL(
     const GURL& page_url,
     int icon_types,
@@ -78,19 +101,6 @@
   content::RecordAction(action);
 }
 
-void ChromeBookmarkClient::NotifyHistoryAboutRemovedBookmarks(
-    const std::set<GURL>& removed_bookmark_urls) {
-  if (removed_bookmark_urls.empty()) {
-    // No point in sending out notification if the starred state didn't change.
-    return;
-  }
-
-  HistoryService* history_service =
-      HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
-  if (history_service)
-    history_service->URLsNoLongerBookmarked(removed_bookmark_urls);
-}
-
 void ChromeBookmarkClient::Observe(
     int type,
     const content::NotificationSource& source,
@@ -111,3 +121,21 @@
 void ChromeBookmarkClient::Shutdown() {
   model_->Shutdown();
 }
+
+void ChromeBookmarkClient::BookmarkModelChanged() {
+}
+
+void ChromeBookmarkClient::BookmarkNodeRemoved(
+    BookmarkModel* model,
+    const BookmarkNode* parent,
+    int old_index,
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {
+  NotifyHistoryOfRemovedURLs(profile_, removed_urls);
+}
+
+void ChromeBookmarkClient::BookmarkAllNodesRemoved(
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
+  NotifyHistoryOfRemovedURLs(profile_, removed_urls);
+}
diff --git a/chrome/browser/bookmarks/chrome_bookmark_client.h b/chrome/browser/bookmarks/chrome_bookmark_client.h
index ac159ac..a136f17 100644
--- a/chrome/browser/bookmarks/chrome_bookmark_client.h
+++ b/chrome/browser/bookmarks/chrome_bookmark_client.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_BOOKMARKS_CHROME_BOOKMARK_CLIENT_H_
 
 #include "base/compiler_specific.h"
+#include "components/bookmarks/core/browser/base_bookmark_model_observer.h"
 #include "components/bookmarks/core/browser/bookmark_client.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "content/public/browser/notification_observer.h"
@@ -16,8 +17,9 @@
 
 class ChromeBookmarkClient : public BookmarkClient,
                              public content::NotificationObserver,
-                             public KeyedService {
- public:
+                             public KeyedService,
+                             public BaseBookmarkModelObserver {
+  public:
   // |index_urls| says whether URLs should be stored in the BookmarkIndex
   // in addition to bookmark titles.
   ChromeBookmarkClient(Profile* profile, bool index_urls);
@@ -27,6 +29,7 @@
   BookmarkModel* model() { return model_.get(); }
 
   // BookmarkClient:
+  virtual bool PreferTouchIcon() OVERRIDE;
   virtual base::CancelableTaskTracker::TaskId GetFaviconImageForURL(
       const GURL& page_url,
       int icon_types,
@@ -38,8 +41,6 @@
       const NodeSet& nodes,
       NodeTypedCountPairs* node_typed_count_pairs) OVERRIDE;
   virtual void RecordAction(const base::UserMetricsAction& action) OVERRIDE;
-  virtual void NotifyHistoryAboutRemovedBookmarks(
-      const std::set<GURL>& removed_bookmarks_urls) OVERRIDE;
 
   // content::NotificationObserver:
   virtual void Observe(int type,
@@ -50,6 +51,17 @@
   virtual void Shutdown() OVERRIDE;
 
  private:
+  // BaseBookmarkModelObserver:
+  virtual void BookmarkModelChanged() OVERRIDE;
+  virtual void BookmarkNodeRemoved(BookmarkModel* model,
+                                   const BookmarkNode* parent,
+                                   int old_index,
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
+
   Profile* profile_;
 
   content::NotificationRegistrar registrar_;
diff --git a/chrome/browser/bookmarks/test_bookmark_client.cc b/chrome/browser/bookmarks/test_bookmark_client.cc
deleted file mode 100644
index 262a200..0000000
--- a/chrome/browser/bookmarks/test_bookmark_client.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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.
-
-#include "chrome/browser/bookmarks/test_bookmark_client.h"
-
-#include "components/bookmarks/core/browser/bookmark_model.h"
-#include "components/bookmarks/core/browser/bookmark_storage.h"
-
-namespace test {
-
-scoped_ptr<BookmarkModel> TestBookmarkClient::CreateModel(bool index_urls) {
-  scoped_ptr<BookmarkModel> bookmark_model(new BookmarkModel(this, index_urls));
-  bookmark_model->DoneLoading(bookmark_model->CreateLoadDetails(std::string()));
-  return bookmark_model.Pass();
-}
-
-base::CancelableTaskTracker::TaskId TestBookmarkClient::GetFaviconImageForURL(
-    const GURL& page_url,
-    int icon_types,
-    int desired_size_in_dip,
-    const FaviconImageCallback& callback,
-    base::CancelableTaskTracker* tracker) {
-  return base::CancelableTaskTracker::kBadTaskId;
-}
-
-bool TestBookmarkClient::SupportsTypedCountForNodes() {
-  return false;
-}
-
-void TestBookmarkClient::GetTypedCountForNodes(
-    const NodeSet& nodes,
-    NodeTypedCountPairs* node_typed_count_pairs) {
-  NOTREACHED();
-}
-
-void TestBookmarkClient::RecordAction(const base::UserMetricsAction& action) {
-}
-
-void TestBookmarkClient::NotifyHistoryAboutRemovedBookmarks(
-    const std::set<GURL>& removed_bookmark_urls) {
-}
-
-}  // namespace test
diff --git a/chrome/browser/bookmarks/test_bookmark_client.h b/chrome/browser/bookmarks/test_bookmark_client.h
deleted file mode 100644
index 9e59230..0000000
--- a/chrome/browser/bookmarks/test_bookmark_client.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_BOOKMARKS_TEST_BOOKMARK_CLIENT_H_
-#define CHROME_BROWSER_BOOKMARKS_TEST_BOOKMARK_CLIENT_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "components/bookmarks/core/browser/bookmark_client.h"
-
-class BookmarkModel;
-
-namespace test {
-
-class TestBookmarkClient : public BookmarkClient {
- public:
-  TestBookmarkClient() {}
-  virtual ~TestBookmarkClient() {}
-
-  // Create a BookmarkModel using this object as its client. The returned
-  // BookmarkModel* is owned by the caller.
-  scoped_ptr<BookmarkModel> CreateModel(bool index_urls);
-
-  // BookmarkClient:
-  virtual base::CancelableTaskTracker::TaskId GetFaviconImageForURL(
-      const GURL& page_url,
-      int icon_types,
-      int desired_size_in_dip,
-      const FaviconImageCallback& callback,
-      base::CancelableTaskTracker* tracker) OVERRIDE;
-  virtual bool SupportsTypedCountForNodes() OVERRIDE;
-  virtual void GetTypedCountForNodes(
-      const NodeSet& nodes,
-      NodeTypedCountPairs* node_typed_count_pairs) OVERRIDE;
-  virtual void RecordAction(const base::UserMetricsAction& action) OVERRIDE;
-  virtual void NotifyHistoryAboutRemovedBookmarks(
-      const std::set<GURL>& removed_bookmark_urls) OVERRIDE;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestBookmarkClient);
-};
-
-}  // namespace test
-
-#endif  // CHROME_BROWSER_BOOKMARKS_TEST_BOOKMARK_CLIENT_H_
diff --git a/chrome/browser/browser_commands_unittest.cc b/chrome/browser/browser_commands_unittest.cc
index f04d302..723f9e9 100644
--- a/chrome/browser/browser_commands_unittest.cc
+++ b/chrome/browser/browser_commands_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/ui/browser_command_controller.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
@@ -13,6 +12,7 @@
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/browser_keyevents_browsertest.cc b/chrome/browser/browser_keyevents_browsertest.cc
index 974c634..e60d75b 100644
--- a/chrome/browser/browser_keyevents_browsertest.cc
+++ b/chrome/browser/browser_keyevents_browsertest.cc
@@ -22,7 +22,6 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "ui/events/keycodes/keyboard_codes.h"
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
index d7591f2..b74276d 100644
--- a/chrome/browser/browser_process.h
+++ b/chrome/browser/browser_process.h
@@ -18,7 +18,6 @@
 #include "chrome/browser/ui/host_desktop.h"
 
 class BackgroundModeManager;
-class BookmarkPromptController;
 class ChromeNetLog;
 class CRLSetFetcher;
 class DownloadRequestLimiter;
@@ -212,8 +211,6 @@
   virtual component_updater::PnaclComponentInstaller*
       pnacl_component_installer() = 0;
 
-  virtual BookmarkPromptController* bookmark_prompt_controller() = 0;
-
   virtual MediaFileSystemRegistry* media_file_system_registry() = 0;
 
   virtual bool created_local_state() const = 0;
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index dfbb509..1189149 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -44,8 +44,8 @@
 #include "chrome/browser/io_thread.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/metrics/metrics_service.h"
+#include "chrome/browser/metrics/metrics_services_manager.h"
 #include "chrome/browser/metrics/thread_watcher.h"
-#include "chrome/browser/metrics/variations/variations_service.h"
 #include "chrome/browser/net/chrome_net_log.h"
 #include "chrome/browser/net/crl_set_fetcher.h"
 #include "chrome/browser/net/sdch_dictionary_fetcher.h"
@@ -63,7 +63,6 @@
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/shell_integration.h"
 #include "chrome/browser/status_icons/status_tray.h"
-#include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/web_resource/promo_resource_service.h"
@@ -76,7 +75,6 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/installer/util/google_update_constants.h"
 #include "components/policy/core/common/policy_service.h"
-#include "components/rappor/rappor_service.h"
 #include "components/signin/core/common/profile_management_switches.h"
 #include "components/translate/core/browser/translate_download_manager.h"
 #include "content/public/browser/browser_thread.h"
@@ -144,8 +142,7 @@
 BrowserProcessImpl::BrowserProcessImpl(
     base::SequencedTaskRunner* local_state_task_runner,
     const CommandLine& command_line)
-    : created_metrics_service_(false),
-      created_watchdog_thread_(false),
+    : created_watchdog_thread_(false),
       created_browser_policy_connector_(false),
       created_profile_manager_(false),
       created_local_state_(false),
@@ -206,15 +203,13 @@
   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                           base::Bind(&SdchDictionaryFetcher::Shutdown));
 
-  // We need to destroy the MetricsService, RapporService, VariationsService,
-  // IntranetRedirectDetector, PromoResourceService, and SafeBrowsing
-  // ClientSideDetectionService (owned by the SafeBrowsingService) before the
-  // io_thread_ gets destroyed, since their destructors can call the URLFetcher
-  // destructor, which does a PostDelayedTask operation on the IO thread. (The
-  // IO thread will handle that URLFetcher operation before going away.)
-  metrics_service_.reset();
-  rappor_service_.reset();
-  variations_service_.reset();
+  // We need to destroy the MetricsServicesManager, IntranetRedirectDetector,
+  // PromoResourceService, and SafeBrowsing ClientSideDetectionService (owned by
+  // the SafeBrowsingService) before the io_thread_ gets destroyed, since their
+  // destructors can call the URLFetcher destructor, which does a
+  // PostDelayedTask operation on the IO thread. (The IO thread will handle that
+  // URLFetcher operation before going away.)
+  metrics_services_manager_.reset();
   intranet_redirect_detector_.reset();
 #if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
   if (safe_browsing_service_.get())
@@ -413,16 +408,12 @@
 
 MetricsService* BrowserProcessImpl::metrics_service() {
   DCHECK(CalledOnValidThread());
-  if (!created_metrics_service_)
-    CreateMetricsService();
-  return metrics_service_.get();
+  return GetMetricsServicesManager()->GetMetricsService();
 }
 
 rappor::RapporService* BrowserProcessImpl::rappor_service() {
   DCHECK(CalledOnValidThread());
-  if (!rappor_service_.get())
-    rappor_service_.reset(new rappor::RapporService());
-  return rappor_service_.get();
+  return GetMetricsServicesManager()->GetRapporService();
 }
 
 IOThread* BrowserProcessImpl::io_thread() {
@@ -460,11 +451,7 @@
 
 chrome_variations::VariationsService* BrowserProcessImpl::variations_service() {
   DCHECK(CalledOnValidThread());
-  if (!variations_service_.get()) {
-    variations_service_.reset(
-        chrome_variations::VariationsService::Create(local_state()));
-  }
-  return variations_service_.get();
+  return GetMetricsServicesManager()->GetVariationsService();
 }
 
 BrowserProcessPlatformPart* BrowserProcessImpl::platform_part() {
@@ -607,14 +594,6 @@
   return download_status_updater_.get();
 }
 
-BookmarkPromptController* BrowserProcessImpl::bookmark_prompt_controller() {
-#if defined(OS_ANDROID)
-  return NULL;
-#else
-  return bookmark_prompt_controller_.get();
-#endif
-}
-
 MediaFileSystemRegistry* BrowserProcessImpl::media_file_system_registry() {
 #if defined(OS_ANDROID) || defined(OS_IOS)
     return NULL;
@@ -793,13 +772,6 @@
   ApplyAllowCrossOriginAuthPromptPolicy();
 }
 
-void BrowserProcessImpl::CreateMetricsService() {
-  DCHECK(!created_metrics_service_ && metrics_service_.get() == NULL);
-  created_metrics_service_ = true;
-
-  metrics_service_.reset(new MetricsService);
-}
-
 void BrowserProcessImpl::CreateWatchdogThread() {
   DCHECK(!created_watchdog_thread_ && watchdog_thread_.get() == NULL);
   created_watchdog_thread_ = true;
@@ -918,13 +890,6 @@
     promo_resource_service_->StartAfterDelay();
   }
 
-#if !defined(OS_ANDROID)
-  if (browser_defaults::bookmarks_enabled &&
-      BookmarkPromptController::IsEnabled()) {
-    bookmark_prompt_controller_.reset(new BookmarkPromptController());
-  }
-#endif
-
 #if !defined(OS_ANDROID) && !defined(OS_IOS)
   storage_monitor::StorageMonitor::Create();
 #endif
@@ -995,6 +960,13 @@
 #endif
 }
 
+MetricsServicesManager* BrowserProcessImpl::GetMetricsServicesManager() {
+  DCHECK(CalledOnValidThread());
+  if (!metrics_services_manager_)
+    metrics_services_manager_.reset(new MetricsServicesManager(local_state()));
+  return metrics_services_manager_.get();
+}
+
 void BrowserProcessImpl::ApplyDefaultBrowserPolicy() {
   if (local_state()->GetBoolean(prefs::kDefaultBrowserSettingEnabled)) {
     scoped_refptr<ShellIntegration::DefaultWebClientWorker>
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
index a083a74..75258d0 100644
--- a/chrome/browser/browser_process_impl.h
+++ b/chrome/browser/browser_process_impl.h
@@ -23,6 +23,7 @@
 
 class ChromeNetLog;
 class ChromeResourceDispatcherHostDelegate;
+class MetricsServicesManager;
 class RemoteDebuggingServer;
 class PrefRegistrySimple;
 class PromoResourceService;
@@ -126,7 +127,6 @@
   virtual CRLSetFetcher* crl_set_fetcher() OVERRIDE;
   virtual component_updater::PnaclComponentInstaller*
       pnacl_component_installer() OVERRIDE;
-  virtual BookmarkPromptController* bookmark_prompt_controller() OVERRIDE;
   virtual MediaFileSystemRegistry* media_file_system_registry() OVERRIDE;
   virtual bool created_local_state() const OVERRIDE;
 #if defined(ENABLE_WEBRTC)
@@ -136,7 +136,6 @@
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
  private:
-  void CreateMetricsService();
   void CreateWatchdogThread();
   void CreateProfileManager();
   void CreateLocalState();
@@ -152,14 +151,13 @@
   void CreateStatusTray();
   void CreateBackgroundModeManager();
 
+  MetricsServicesManager* GetMetricsServicesManager();
+
   void ApplyAllowCrossOriginAuthPromptPolicy();
   void ApplyDefaultBrowserPolicy();
   void ApplyMetricsReportingPolicy();
 
-  bool created_metrics_service_;
-  scoped_ptr<MetricsService> metrics_service_;
-
-  scoped_ptr<rappor::RapporService> rappor_service_;
+  scoped_ptr<MetricsServicesManager> metrics_services_manager_;
 
   scoped_ptr<IOThread> io_thread_;
 
@@ -196,9 +194,6 @@
 
 #if !defined(OS_ANDROID)
   scoped_ptr<RemoteDebuggingServer> remote_debugging_server_;
-
-  // Bookmark prompt controller displays the prompt for frequently visited URL.
-  scoped_ptr<BookmarkPromptController> bookmark_prompt_controller_;
 #endif
 
 #if !defined(OS_ANDROID) && !defined(OS_IOS)
@@ -210,8 +205,6 @@
 
   scoped_ptr<printing::BackgroundPrintingManager> background_printing_manager_;
 
-  scoped_ptr<chrome_variations::VariationsService> variations_service_;
-
   // Manager for desktop notification UI.
   bool created_notification_ui_manager_;
   scoped_ptr<NotificationUIManager> notification_ui_manager_;
diff --git a/chrome/browser/browser_process_platform_part_mac.mm b/chrome/browser/browser_process_platform_part_mac.mm
index 5a78d7b..4a2df71 100644
--- a/chrome/browser/browser_process_platform_part_mac.mm
+++ b/chrome/browser/browser_process_platform_part_mac.mm
@@ -5,7 +5,6 @@
 #include "chrome/browser/browser_process_platform_part_mac.h"
 
 #include "chrome/browser/chrome_browser_application_mac.h"
-#include "chrome/browser/ui/app_list/app_list_service.h"
 
 BrowserProcessPlatformPart::BrowserProcessPlatformPart() {
 }
@@ -29,10 +28,6 @@
   // domain socket will cause the just-created socket to be unlinked.
   DCHECK(!app_shim_host_manager_);
   app_shim_host_manager_ = new AppShimHostManager;
-  // Init needs to be called after assigning to a scoped_refptr (i.e. after
-  // incrementing the refcount).
-  app_shim_host_manager_->Init();
-  AppListService::InitAll(NULL);
 }
 
 AppShimHostManager* BrowserProcessPlatformPart::app_shim_host_manager() {
diff --git a/chrome/browser/browsing_data/browsing_data_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_helper_unittest.cc
index 00d6a9a..5e3dd80 100644
--- a/chrome/browser/browsing_data/browsing_data_helper_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_helper_unittest.cc
@@ -58,8 +58,8 @@
 };
 
 TEST_F(BrowsingDataHelperTest, WebSafeSchemesAreWebSafe) {
-  EXPECT_TRUE(IsWebScheme(content::kHttpScheme));
-  EXPECT_TRUE(IsWebScheme(content::kHttpsScheme));
+  EXPECT_TRUE(IsWebScheme(url::kHttpScheme));
+  EXPECT_TRUE(IsWebScheme(url::kHttpsScheme));
   EXPECT_TRUE(IsWebScheme(content::kFtpScheme));
   EXPECT_TRUE(IsWebScheme(content::kDataScheme));
   EXPECT_TRUE(IsWebScheme("feed"));
@@ -81,8 +81,8 @@
 }
 
 TEST_F(BrowsingDataHelperTest, WebSafeSchemesAreNotExtensions) {
-  EXPECT_FALSE(IsExtensionScheme(content::kHttpScheme));
-  EXPECT_FALSE(IsExtensionScheme(content::kHttpsScheme));
+  EXPECT_FALSE(IsExtensionScheme(url::kHttpScheme));
+  EXPECT_FALSE(IsExtensionScheme(url::kHttpsScheme));
   EXPECT_FALSE(IsExtensionScheme(content::kFtpScheme));
   EXPECT_FALSE(IsExtensionScheme(content::kDataScheme));
   EXPECT_FALSE(IsExtensionScheme("feed"));
diff --git a/chrome/browser/browsing_data/browsing_data_remover.cc b/chrome/browser/browsing_data/browsing_data_remover.cc
index b7b4299..1eb34c1 100644
--- a/chrome/browser/browsing_data/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover.cc
@@ -662,6 +662,10 @@
   }
 #endif
 
+  // Remove omnibox zero-suggest cache results.
+  if ((remove_mask & (REMOVE_CACHE | REMOVE_COOKIES)))
+    prefs->SetString(prefs::kZeroSuggestCachedResults, std::string());
+
   // Always wipe accumulated network related data (TransportSecurityState and
   // HttpServerPropertiesManager data).
   waiting_for_clear_networking_history_ = true;
diff --git a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
index 35a61f0..619588e 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
@@ -1575,6 +1575,20 @@
   EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginSetMask());
 }
 
+TEST_F(BrowsingDataRemoverTest, ZeroSuggestCacheClear) {
+  PrefService* prefs = GetProfile()->GetPrefs();
+  prefs->SetString(prefs::kZeroSuggestCachedResults,
+                   "[\"\", [\"foo\", \"bar\"]]");
+  BlockUntilBrowsingDataRemoved(BrowsingDataRemover::EVERYTHING,
+                                BrowsingDataRemover::REMOVE_COOKIES,
+                                false);
+
+  // Expect the prefs to be cleared when cookies are removed.
+  EXPECT_TRUE(prefs->GetString(prefs::kZeroSuggestCachedResults).empty());
+  EXPECT_EQ(BrowsingDataRemover::REMOVE_COOKIES, GetRemovalMask());
+  EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginSetMask());
+}
+
 #if defined(OS_CHROMEOS)
 TEST_F(BrowsingDataRemoverTest, ContentProtectionPlatformKeysRemoval) {
   chromeos::ScopedTestDeviceSettingsService test_device_settings_service;
diff --git a/chrome/browser/browsing_data/cookies_tree_model.cc b/chrome/browser/browsing_data/cookies_tree_model.cc
index 37a4e63..0fb14e5 100644
--- a/chrome/browser/browsing_data/cookies_tree_model.cc
+++ b/chrome/browser/browsing_data/cookies_tree_model.cc
@@ -1088,7 +1088,7 @@
         domain = domain.substr(1);
 
       // We treat secure cookies just the same as normal ones.
-      source_string = std::string(content::kHttpScheme) +
+      source_string = std::string(url::kHttpScheme) +
           content::kStandardSchemeSeparator + domain + "/";
     }
 
@@ -1235,7 +1235,7 @@
     if (!origin.is_valid()) {
       // Domain Bound Cert.  Make a valid URL to satisfy the
       // CookieTreeRootNode::GetOrCreateHostNode interface.
-      origin = GURL(std::string(content::kHttpsScheme) +
+      origin = GURL(std::string(url::kHttpsScheme) +
           content::kStandardSchemeSeparator +
           cert_info->server_identifier() + "/");
     }
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 19c4cad..66ec527 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -125,7 +125,6 @@
 #include "content/public/common/content_switches.h"
 #include "content/public/common/main_function_params.h"
 #include "extensions/browser/extension_protocols.h"
-#include "extensions/browser/extension_system.h"
 #include "grit/app_locale_settings.h"
 #include "grit/browser_resources.h"
 #include "grit/chromium_strings.h"
@@ -562,14 +561,8 @@
   // Initialize FieldTrialList to support FieldTrials that use one-time
   // randomization.
   MetricsService* metrics = browser_process_->metrics_service();
-  MetricsService::ReportingState reporting_state =
-      IsMetricsReportingEnabled() ? MetricsService::REPORTING_ENABLED :
-                                    MetricsService::REPORTING_DISABLED;
-  if (reporting_state == MetricsService::REPORTING_ENABLED)
-    metrics->ForceClientIdCreation();  // Needed below.
   field_trial_list_.reset(
-      new base::FieldTrialList(
-          metrics->CreateEntropyProvider(reporting_state).release()));
+      new base::FieldTrialList(metrics->CreateEntropyProvider().release()));
 
   const CommandLine* command_line = CommandLine::ForCurrentProcess();
   if (command_line->HasSwitch(switches::kEnableBenchmarking))
@@ -617,7 +610,7 @@
   field_trial_synchronizer_ = new FieldTrialSynchronizer();
 
   // Now that field trials have been created, initializes metrics recording.
-  metrics->InitializeMetricsRecordingState(reporting_state);
+  metrics->InitializeMetricsRecordingState();
 }
 
 // ChromeBrowserMainParts: |SetupMetricsAndFieldTrials()| related --------------
@@ -637,33 +630,14 @@
   }
 
   metrics->CheckForClonedInstall();
-
-  if (IsMetricsReportingEnabled())
-    metrics->Start();
-}
-
-bool ChromeBrowserMainParts::IsMetricsReportingEnabled() {
-  // If the user permits metrics reporting with the checkbox in the
-  // prefs, we turn on recording.  We disable metrics completely for
-  // non-official builds.  This can be forced with a flag.
-  const CommandLine* command_line = CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kEnableMetricsReportingForTesting))
-    return true;
-
-  bool enabled = false;
-  // The debug build doesn't send UMA logs when FieldTrials are forced.
-  if (command_line->HasSwitch(switches::kForceFieldTrials))
-    return false;
-
-#if defined(GOOGLE_CHROME_BUILD)
-#if defined(OS_CHROMEOS)
-  chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref,
-                                            &enabled);
-#else
-  enabled = local_state_->GetBoolean(prefs::kMetricsReportingEnabled);
-#endif  // #if defined(OS_CHROMEOS)
-#endif  // defined(GOOGLE_CHROME_BUILD)
-  return enabled;
+  const bool metrics_enabled = metrics->StartIfMetricsReportingEnabled();
+  if (metrics_enabled) {
+    // TODO(asvitkine): Since this function is not run on Android, RAPPOR is
+    // currently disabled there. http://crbug.com/370041
+    browser_process_->rappor_service()->Start(
+        browser_process_->local_state(),
+        browser_process_->system_request_context());
+  }
 }
 
 void ChromeBrowserMainParts::RecordBrowserStartupTime() {
@@ -1094,12 +1068,6 @@
   StartMetricsRecording();
 #endif
 
-  if (IsMetricsReportingEnabled()) {
-    browser_process_->rappor_service()->Start(
-        browser_process_->local_state(),
-        browser_process_->system_request_context());
-  }
-
   // Create watchdog thread after creating all other threads because it will
   // watch the other threads and they must be running.
   browser_process_->watchdog_thread();
@@ -1287,8 +1255,8 @@
   // NaClBrowserDelegateImpl is accessed inside PostProfileInit().
   // So make sure to create it before that.
 #if !defined(DISABLE_NACL)
-  NaClBrowserDelegateImpl* delegate = new NaClBrowserDelegateImpl(
-    extensions::ExtensionSystem::Get(profile_)->info_map());
+  NaClBrowserDelegateImpl* delegate =
+      new NaClBrowserDelegateImpl(browser_process_->profile_manager());
   nacl::NaClBrowser::SetDelegate(delegate);
 #endif
 
diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h
index 0d1b51c..a856a2b 100644
--- a/chrome/browser/chrome_browser_main.h
+++ b/chrome/browser/chrome_browser_main.h
@@ -107,9 +107,6 @@
   // thread.
   void StartMetricsRecording();
 
-  // Returns true if the user opted in to sending metric reports.
-  bool IsMetricsReportingEnabled();
-
   // Record time from process startup to present time in an UMA histogram.
   void RecordBrowserStartupTime();
 
diff --git a/chrome/browser/chrome_browser_main_mac.h b/chrome/browser/chrome_browser_main_mac.h
index efe1bc7..621c8df 100644
--- a/chrome/browser/chrome_browser_main_mac.h
+++ b/chrome/browser/chrome_browser_main_mac.h
@@ -16,6 +16,7 @@
   // BrowserParts overrides.
   virtual void PreEarlyInitialization() OVERRIDE;
   virtual void PreMainMessageLoopStart() OVERRIDE;
+  virtual void PreProfileInit() OVERRIDE;
   virtual void PostProfileInit() OVERRIDE;
 
   // Perform platform-specific work that needs to be done after the main event
diff --git a/chrome/browser/chrome_browser_main_mac.mm b/chrome/browser/chrome_browser_main_mac.mm
index 1535b15..bda75fb 100644
--- a/chrome/browser/chrome_browser_main_mac.mm
+++ b/chrome/browser/chrome_browser_main_mac.mm
@@ -7,6 +7,7 @@
 #import <Cocoa/Cocoa.h>
 #include <sys/sysctl.h>
 
+#include "apps/app_shim/app_shim_host_manager_mac.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/mac/bundle_locations.h"
@@ -20,6 +21,7 @@
 #include "chrome/browser/mac/install_from_dmg.h"
 #import "chrome/browser/mac/keystone_glue.h"
 #include "chrome/browser/metrics/metrics_service.h"
+#include "chrome/browser/ui/app_list/app_list_service.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/breakpad/app/breakpad_mac.h"
@@ -243,6 +245,14 @@
   }];
 }
 
+void ChromeBrowserMainPartsMac::PreProfileInit() {
+  ChromeBrowserMainPartsPosix::PreProfileInit();
+  // This is called here so that the app shim socket is only created after
+  // taking the singleton lock.
+  g_browser_process->platform_part()->app_shim_host_manager()->Init();
+  AppListService::InitAll(NULL);
+}
+
 void ChromeBrowserMainPartsMac::PostProfileInit() {
   ChromeBrowserMainPartsPosix::PostProfileInit();
   g_browser_process->metrics_service()->RecordBreakpadRegistration(
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 62c5d04..06b97e7 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -44,6 +44,7 @@
 #include "chrome/browser/guest_view/ad_view/ad_view_guest.h"
 #include "chrome/browser/guest_view/guest_view_base.h"
 #include "chrome/browser/guest_view/guest_view_constants.h"
+#include "chrome/browser/guest_view/guest_view_manager.h"
 #include "chrome/browser/guest_view/web_view/web_view_guest.h"
 #include "chrome/browser/media/cast_transport_host_filter.h"
 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
@@ -97,6 +98,7 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/installer/util/google_update_settings.h"
 #include "chromeos/chromeos_constants.h"
+#include "components/cdm/browser/cdm_message_filter_android.h"
 #include "components/cloud_devices/common/cloud_devices_switches.h"
 #include "components/nacl/browser/nacl_browser.h"
 #include "components/nacl/browser/nacl_host_message_filter.h"
@@ -119,7 +121,6 @@
 #include "content/public/browser/resource_context.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/child_process_host.h"
 #include "content/public/common/content_descriptors.h"
 #include "content/public/common/url_utils.h"
@@ -177,7 +178,6 @@
 #include "chrome/browser/android/new_tab_page_url_handler.h"
 #include "chrome/browser/android/webapps/single_tab_mode_tab_helper.h"
 #include "chrome/browser/chrome_browser_main_android.h"
-#include "chrome/browser/media/encrypted_media_message_filter_android.h"
 #include "chrome/common/descriptors_android.h"
 #include "components/breakpad/browser/crash_dump_manager_android.h"
 #elif defined(OS_POSIX)
@@ -215,10 +215,6 @@
 #include "chrome/browser/media/webrtc_logging_handler_host.h"
 #endif
 
-#if defined(ENABLE_INPUT_SPEECH)
-#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h"
-#endif
-
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/file_manager/app_id.h"
 #endif
@@ -853,7 +849,10 @@
 
     // Create a new GuestViewBase of the same type as the opener.
     *guest_delegate = GuestViewBase::Create(
-        guest_web_contents, extension_id, guest->GetViewType());
+        guest_web_contents,
+        extension_id,
+        guest->GetViewType(),
+        guest->AsWeakPtr());
     return;
   }
 
@@ -868,7 +867,10 @@
     return;
 
   *guest_delegate =
-      GuestViewBase::Create(guest_web_contents, extension_id, api_type);
+      GuestViewBase::Create(guest_web_contents,
+                            extension_id,
+                            api_type,
+                            base::WeakPtr<GuestViewBase>());
 }
 
 void ChromeContentBrowserClient::GuestWebContentsAttached(
@@ -928,7 +930,7 @@
       context));
 #endif
 #if defined(OS_ANDROID)
-  host->AddFilter(new EncryptedMediaMessageFilterAndroid());
+  host->AddFilter(new cdm::CdmMessageFilterAndroid());
 #endif
   if (switches::IsNewProfileManagement())
     host->AddFilter(new PrincipalsMessageFilter(id));
@@ -1553,11 +1555,57 @@
     {
       // Enable auto-reload if this session is in the field trial or the user
       // explicitly enabled it.
-      std::string group =
-          base::FieldTrialList::FindFullName("AutoReloadExperiment");
-      if (group == "Enabled" ||
-          browser_command_line.HasSwitch(switches::kEnableOfflineAutoReload)) {
+      bool hard_enabled =
+          browser_command_line.HasSwitch(switches::kEnableOfflineAutoReload);
+      bool hard_disabled =
+          browser_command_line.HasSwitch(switches::kDisableOfflineAutoReload);
+      if (hard_enabled) {
         command_line->AppendSwitch(switches::kEnableOfflineAutoReload);
+      } else if (!hard_disabled) {
+        chrome::VersionInfo::Channel channel =
+          chrome::VersionInfo::GetChannel();
+#if defined(OS_ANDROID) || defined(OS_IOS)
+        chrome::VersionInfo::Channel kForceChannel =
+            chrome::VersionInfo::CHANNEL_DEV;
+#else
+        chrome::VersionInfo::Channel kForceChannel =
+            chrome::VersionInfo::CHANNEL_CANARY;
+#endif
+        std::string group =
+            base::FieldTrialList::FindFullName("AutoReloadExperiment");
+        if (channel <= kForceChannel || group == "Enabled")
+          command_line->AppendSwitch(switches::kEnableOfflineAutoReload);
+      }
+    }
+
+    {
+      // Enable load stale cache if this session is in the field trial, one
+      // of the forced on channels, or the user explicitly enabled it.
+      // Note that as far as the renderer  is concerned, the feature is
+      // enabled if-and-only-if the kEnableOfflineLoadStaleCache flag
+      // is on the command line; the yes/no/default behavior is only
+      // at the browser command line level.
+
+      // Command line switches override
+      if (browser_command_line.HasSwitch(
+              switches::kEnableOfflineLoadStaleCache)) {
+        command_line->AppendSwitch(switches::kEnableOfflineLoadStaleCache);
+      } else if (!browser_command_line.HasSwitch(
+          switches::kDisableOfflineLoadStaleCache)) {
+        std::string group =
+            base::FieldTrialList::FindFullName("LoadStaleCacheExperiment");
+        chrome::VersionInfo::Channel channel =
+            chrome::VersionInfo::GetChannel();
+#if defined(OS_ANDROID) || defined(OS_IOS)
+        chrome::VersionInfo::Channel forceChannel =
+            chrome::VersionInfo::CHANNEL_DEV;
+#else
+        chrome::VersionInfo::Channel forceChannel =
+            chrome::VersionInfo::CHANNEL_CANARY;
+#endif
+
+        if (channel <= forceChannel || group == "Enabled")
+          command_line->AppendSwitch(switches::kEnableOfflineLoadStaleCache);
       }
     }
 
@@ -1592,6 +1640,7 @@
       switches::kEnableNetBenchmarking,
       switches::kEnableStreamlinedHostedApps,
       switches::kEnableWatchdog,
+      switches::kEnableWebBasedSignin,
       switches::kMemoryProfiling,
       switches::kMessageLoopHistogrammer,
       switches::kNoJsRandomness,
@@ -2168,13 +2217,7 @@
 // TODO(tommi): Rename from Get to Create.
 content::SpeechRecognitionManagerDelegate*
     ChromeContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
-#if defined(ENABLE_INPUT_SPEECH)
-  return new speech::ChromeSpeechRecognitionManagerDelegateBubbleUI();
-#else
-  // Platforms who don't implement x-webkit-speech (a.k.a INPUT_SPEECH) just
-  // need the base delegate without the bubble UI.
   return new speech::ChromeSpeechRecognitionManagerDelegate();
-#endif
 }
 
 net::NetLog* ChromeContentBrowserClient::GetNetLog() {
diff --git a/chrome/browser/chrome_plugin_browsertest.cc b/chrome/browser/chrome_plugin_browsertest.cc
index 290b36f..256d6df 100644
--- a/chrome/browser/chrome_plugin_browsertest.cc
+++ b/chrome/browser/chrome_plugin_browsertest.cc
@@ -34,7 +34,6 @@
 #include "net/base/filename_util.h"
 
 #if defined(OS_WIN)
-#include "content/public/browser/web_contents_view.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #endif
@@ -326,8 +325,7 @@
   EXPECT_EQ(expected_title2, title_watcher2.WaitAndGetTitle());
 
   HWND child = NULL;
-  HWND hwnd =
-      tab->GetView()->GetNativeView()->GetHost()->GetAcceleratedWidget();
+  HWND hwnd = tab->GetNativeView()->GetHost()->GetAcceleratedWidget();
   EnumChildWindows(hwnd, EnumerateChildren,reinterpret_cast<LPARAM>(&child));
 
   RECT region;
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
index 58a9d6f..98843a5 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -18,6 +18,8 @@
 #include "base/path_service.h"
 #include "base/prefs/pref_member.h"
 #include "base/prefs/pref_service.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/accessibility/accessibility_extension_api.h"
@@ -35,10 +37,11 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/chrome_paths.h"
-#include "chrome/common/extensions/api/experimental_accessibility.h"
+#include "chrome/common/extensions/api/accessibility_private.h"
 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/audio/chromeos_sounds.h"
+#include "chromeos/ime/input_method_manager.h"
 #include "chromeos/login/login_state.h"
 #include "content/public/browser/browser_accessibility_state.h"
 #include "content/public/browser/browser_thread.h"
@@ -66,6 +69,7 @@
 using content::RenderViewHost;
 using extensions::api::braille_display_private::BrailleController;
 using extensions::api::braille_display_private::DisplayState;
+using extensions::api::braille_display_private::KeyEvent;
 
 namespace chromeos {
 
@@ -310,7 +314,8 @@
       should_speak_chrome_vox_announcements_on_user_screen_(true),
       system_sounds_enabled_(false),
       braille_display_connected_(false),
-      scoped_braille_observer_(this) {
+      scoped_braille_observer_(this),
+      braille_ime_current_(false) {
   notification_registrar_.Add(this,
                               chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
                               content::NotificationService::AllSources());
@@ -511,6 +516,7 @@
   } else {
     UnloadChromeVox();
   }
+  UpdateBrailleImeState();
 }
 
 void AccessibilityManager::LoadChromeVox() {
@@ -738,9 +744,16 @@
 
 #if defined(USE_ASH)
   keyboard::SetAccessibilityKeyboardEnabled(enabled);
-  if (enabled)
+  // Note that there are two versions of the on-screen keyboard. A full layout
+  // is provided for accessibility, which includes sticky modifier keys to
+  // enable typing of hotkeys. A compact version is used in touchview mode
+  // to provide a layout with larger keys to facilitate touch typing. In the
+  // event that the a11y keyboard is being disabled, an on-screen keyboard might
+  // still be enabled and a forced reset is required to pick up the layout
+  // change.
+  if (keyboard::IsKeyboardEnabled())
     ash::Shell::GetInstance()->CreateKeyboard();
-  else if (!keyboard::IsKeyboardEnabled())
+  else
     ash::Shell::GetInstance()->DeactivateKeyboard();
 #endif
 }
@@ -764,7 +777,33 @@
 
 void AccessibilityManager::ReceiveBrailleDisplayState(
     scoped_ptr<extensions::api::braille_display_private::DisplayState> state) {
-  OnDisplayStateChanged(*state);
+  OnBrailleDisplayStateChanged(*state);
+}
+
+void AccessibilityManager::UpdateBrailleImeState() {
+  if (!profile_)
+    return;
+  PrefService* pref_service = profile_->GetPrefs();
+  std::vector<std::string> preload_engines;
+  base::SplitString(pref_service->GetString(prefs::kLanguagePreloadEngines),
+                    ',',
+                    &preload_engines);
+  std::vector<std::string>::iterator it =
+      std::find(preload_engines.begin(),
+                preload_engines.end(),
+                extension_misc::kBrailleImeEngineId);
+  bool is_enabled = (it != preload_engines.end());
+  bool should_be_enabled =
+      (spoken_feedback_enabled_ && braille_display_connected_);
+  if (is_enabled == should_be_enabled)
+    return;
+  if (should_be_enabled)
+    preload_engines.push_back(extension_misc::kBrailleImeEngineId);
+  else
+    preload_engines.erase(it);
+  pref_service->SetString(prefs::kLanguagePreloadEngines,
+                          JoinString(preload_engines, ','));
+  braille_ime_current_ = false;
 }
 
 // Overridden from InputMethodManager::Observer.
@@ -777,6 +816,10 @@
       manager->IsISOLevel5ShiftUsedByCurrentInputMethod(),
       manager->IsAltGrUsedByCurrentInputMethod());
 #endif
+  const chromeos::input_method::InputMethodDescriptor descriptor =
+      manager->GetCurrentInputMethod();
+  braille_ime_current_ =
+      (descriptor.id() == extension_misc::kBrailleImeEngineId);
 }
 
 void AccessibilityManager::SetProfile(Profile* profile) {
@@ -841,7 +884,8 @@
 
   if (!had_profile && profile)
     CheckBrailleState();
-
+  else
+    UpdateBrailleImeState();
   UpdateLargeCursorFromPref();
   UpdateStickyKeysFromPref();
   UpdateSpokenFeedbackFromPref();
@@ -982,11 +1026,13 @@
   }
 }
 
-void AccessibilityManager::OnDisplayStateChanged(
+void AccessibilityManager::OnBrailleDisplayStateChanged(
     const DisplayState& display_state) {
   braille_display_connected_ = display_state.available;
-  if (braille_display_connected_)
+  if (braille_display_connected_) {
     EnableSpokenFeedback(true, ash::A11Y_NOTIFICATION_SHOW);
+  }
+  UpdateBrailleImeState();
 
   AccessibilityStatusEventDetails details(
       ACCESSIBILITY_BRAILLE_DISPLAY_CONNECTION_STATE_CHANGED,
@@ -995,6 +1041,16 @@
   NotifyAccessibilityStatusChanged(details);
 }
 
+void AccessibilityManager::OnBrailleKeyEvent(const KeyEvent& event) {
+  // Ensure the braille IME is active on braille keyboard (dots) input.
+  if ((event.command ==
+       extensions::api::braille_display_private::KEY_COMMAND_DOTS) &&
+      !braille_ime_current_) {
+    input_method::InputMethodManager::Get()->ChangeInputMethod(
+        extension_misc::kBrailleImeEngineId);
+  }
+}
+
 void AccessibilityManager::PostLoadChromeVox(Profile* profile) {
   // Do any setup work needed immediately after ChromeVox actually loads.
   if (system_sounds_enabled_)
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.h b/chrome/browser/chromeos/accessibility/accessibility_manager.h
index a0aec2c..91a4f4c 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager.h
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager.h
@@ -213,6 +213,7 @@
   void CheckBrailleState();
   void ReceiveBrailleDisplayState(
       scoped_ptr<extensions::api::braille_display_private::DisplayState> state);
+  void UpdateBrailleImeState();
 
   void SetProfile(Profile* profile);
 
@@ -225,9 +226,11 @@
 
   // extensions::api::braille_display_private::BrailleObserver implementation.
   // Enables spoken feedback if a braille display becomes available.
-  virtual void OnDisplayStateChanged(
+  virtual void OnBrailleDisplayStateChanged(
       const extensions::api::braille_display_private::DisplayState&
           display_state) OVERRIDE;
+  virtual void OnBrailleKeyEvent(
+      const extensions::api::braille_display_private::KeyEvent& event) OVERRIDE;
 
   // InputMethodManager::Observer
   virtual void InputMethodChanged(input_method::InputMethodManager* manager,
@@ -276,6 +279,8 @@
   ScopedObserver<extensions::api::braille_display_private::BrailleController,
                  AccessibilityManager> scoped_braille_observer_;
 
+  bool braille_ime_current_;
+
   DISALLOW_COPY_AND_ASSIGN(AccessibilityManager);
 };
 
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
index d397f23..4389ed4 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager_browsertest.cc
@@ -15,19 +15,30 @@
 #include "chrome/browser/chromeos/login/login_utils.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/user_manager_impl.h"
+#include "chrome/browser/chromeos/preferences.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/extensions/api/braille_display_private/mock_braille_controller.h"
+#include "chrome/browser/prefs/pref_service_syncable.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/chromeos_switches.h"
+#include "chromeos/ime/component_extension_ime_manager.h"
+#include "chromeos/ime/input_method_manager.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using chromeos::input_method::InputMethodManager;
+using chromeos::input_method::InputMethodUtil;
+using chromeos::input_method::InputMethodDescriptors;
+using content::BrowserThread;
 using extensions::api::braille_display_private::BrailleObserver;
 using extensions::api::braille_display_private::DisplayState;
+using extensions::api::braille_display_private::KeyEvent;
 using extensions::api::braille_display_private::MockBrailleController;
 
 namespace chromeos {
@@ -189,7 +200,25 @@
   return GetPrefs()->GetInteger(prefs::kAutoclickDelayMs);
 }
 
-}  // anonymouse namespace
+bool IsBrailleImeActive() {
+  InputMethodManager* imm = InputMethodManager::Get();
+  scoped_ptr<InputMethodDescriptors> descriptors =
+      imm->GetActiveInputMethods();
+  for (InputMethodDescriptors::const_iterator i = descriptors->begin();
+       i != descriptors->end();
+       ++i) {
+    if (i->id() == extension_misc::kBrailleImeEngineId)
+      return true;
+  }
+  return false;
+}
+
+bool IsBrailleImeCurrent() {
+  InputMethodManager* imm = InputMethodManager::Get();
+  return imm->GetCurrentInputMethod().id() ==
+         extension_misc::kBrailleImeEngineId;
+}
+}  // anonymous namespace
 
 class AccessibilityManagerTest : public InProcessBrowserTest {
  protected:
@@ -217,6 +246,12 @@
     AccessibilityManager::SetBrailleControllerForTest(NULL);
   }
 
+  void SetBrailleDisplayAvailability(bool available) {
+    braille_controller_.SetAvailable(available);
+    braille_controller_.GetObserver()->OnBrailleDisplayStateChanged(
+        *braille_controller_.GetDisplayState());
+  }
+
   int default_autoclick_delay() const { return default_autoclick_delay_; }
 
   int default_autoclick_delay_;
@@ -291,10 +326,7 @@
   EXPECT_FALSE(IsSpokenFeedbackEnabled());
 
   // Signal the accessibility manager that a braille display was connected.
-  braille_controller_.SetAvailable(true);
-  braille_controller_.GetObserver()->OnDisplayStateChanged(
-      *braille_controller_.GetDisplayState());
-
+  SetBrailleDisplayAvailability(true);
   // Confirms that the spoken feedback is enabled.
   EXPECT_TRUE(IsSpokenFeedbackEnabled());
 }
@@ -582,6 +614,56 @@
   EXPECT_EQ(kTestAutoclickDelayMs, GetAutoclickDelayFromPref());
 }
 
+IN_PROC_BROWSER_TEST_P(AccessibilityManagerUserTypeTest, BrailleWhenLoggedIn) {
+  // Logs in.
+  const char* user_name = GetParam();
+  UserManager::Get()->UserLoggedIn(user_name, user_name, true);
+  UserManager::Get()->SessionStarted();
+  // The |ComponentExtensionIMEManager| defers some initialization to the
+  // |FILE| thread.  We need to wait for that to finish before continuing.
+  InputMethodManager* imm = InputMethodManager::Get();
+  while (!imm->GetComponentExtensionIMEManager()->IsInitialized()) {
+    content::RunAllPendingInMessageLoop(BrowserThread::FILE);
+  }
+  // This object watches for IME preference changes and reflects those in
+  // the IME framework state.
+  chromeos::Preferences prefs;
+  prefs.InitUserPrefsForTesting(PrefServiceSyncable::FromProfile(GetProfile()),
+                                UserManager::Get()->GetActiveUser());
+
+  // Make sure we start in the expected state.
+  EXPECT_FALSE(IsBrailleImeActive());
+  EXPECT_FALSE(IsSpokenFeedbackEnabled());
+
+  // Signal the accessibility manager that a braille display was connected.
+  SetBrailleDisplayAvailability(true);
+
+  // Now, both spoken feedback and the Braille IME should be enabled.
+  EXPECT_TRUE(IsSpokenFeedbackEnabled());
+  EXPECT_TRUE(IsBrailleImeActive());
+
+  // Send a braille dots key event and make sure that the braille IME is
+  // enabled.
+  KeyEvent event;
+  event.command = extensions::api::braille_display_private::KEY_COMMAND_DOTS;
+  event.braille_dots.reset(new int(0));
+  braille_controller_.GetObserver()->OnBrailleKeyEvent(event);
+  EXPECT_TRUE(IsBrailleImeCurrent());
+
+  // Unplug the display.  Spolken feedback remains on, but the Braille IME
+  // should get deactivated.
+  SetBrailleDisplayAvailability(false);
+  EXPECT_TRUE(IsSpokenFeedbackEnabled());
+  EXPECT_FALSE(IsBrailleImeActive());
+  EXPECT_FALSE(IsBrailleImeCurrent());
+
+  // Plugging in a display while spoken feedback is enabled should activate
+  // the Braille IME.
+  SetBrailleDisplayAvailability(true);
+  EXPECT_TRUE(IsSpokenFeedbackEnabled());
+  EXPECT_TRUE(IsBrailleImeActive());
+}
+
 IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, AcessibilityMenuVisibility) {
   // Log in.
   UserManager::Get()->UserLoggedIn(kTestUserName, kTestUserName, true);
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
index 20567ea..555bd3d 100644
--- a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
+++ b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -39,7 +40,14 @@
 // Spoken feedback tests in a normal browser window.
 //
 
-class SpokenFeedbackTest : public InProcessBrowserTest {
+enum SpokenFeedbackTestVariant {
+  kTestAsNormalUser,
+  kTestAsGuestUser
+};
+
+class SpokenFeedbackTest
+    : public InProcessBrowserTest,
+      public ::testing::WithParamInterface<SpokenFeedbackTestVariant> {
  protected:
   SpokenFeedbackTest() {}
   virtual ~SpokenFeedbackTest() {}
@@ -52,12 +60,29 @@
     AccessibilityManager::SetBrailleControllerForTest(NULL);
   }
 
+  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+    if (GetParam() == kTestAsGuestUser) {
+      command_line->AppendSwitch(chromeos::switches::kGuestSession);
+      command_line->AppendSwitch(::switches::kIncognito);
+      command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
+                                      "user");
+      command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
+                                      chromeos::UserManager::kGuestUserName);
+    }
+  }
+
  private:
   StubBrailleController braille_controller_;
   DISALLOW_COPY_AND_ASSIGN(SpokenFeedbackTest);
 };
 
-IN_PROC_BROWSER_TEST_F(SpokenFeedbackTest, EnableSpokenFeedback) {
+INSTANTIATE_TEST_CASE_P(
+    TestAsNormalAndGuestUser,
+    SpokenFeedbackTest,
+    ::testing::Values(kTestAsNormalUser,
+                      kTestAsGuestUser));
+
+IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, EnableSpokenFeedback) {
   EXPECT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
 
   SpeechMonitor monitor;
@@ -66,7 +91,7 @@
   EXPECT_TRUE(monitor.SkipChromeVoxEnabledMessage());
 }
 
-IN_PROC_BROWSER_TEST_F(SpokenFeedbackTest, FocusToolbar) {
+IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, FocusToolbar) {
   EXPECT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
 
   SpeechMonitor monitor;
@@ -81,7 +106,7 @@
   EXPECT_EQ("button", monitor.GetNextUtterance());
 }
 
-IN_PROC_BROWSER_TEST_F(SpokenFeedbackTest, TypeInOmnibox) {
+IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, TypeInOmnibox) {
   EXPECT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
 
   SpeechMonitor monitor;
@@ -111,6 +136,42 @@
 }
 
 //
+// Spoken feedback tests that run in guest mode.
+//
+
+class GuestSpokenFeedbackTest : public SpokenFeedbackTest {
+ protected:
+  GuestSpokenFeedbackTest() {}
+  virtual ~GuestSpokenFeedbackTest() {}
+
+  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+    command_line->AppendSwitch(chromeos::switches::kGuestSession);
+    command_line->AppendSwitch(::switches::kIncognito);
+    command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user");
+    command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
+                                    chromeos::UserManager::kGuestUserName);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GuestSpokenFeedbackTest);
+};
+
+IN_PROC_BROWSER_TEST_F(GuestSpokenFeedbackTest, FocusToolbar) {
+  EXPECT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled());
+
+  SpeechMonitor monitor;
+  AccessibilityManager::Get()->EnableSpokenFeedback(
+      true, ash::A11Y_NOTIFICATION_NONE);
+  EXPECT_TRUE(monitor.SkipChromeVoxEnabledMessage());
+
+  chrome::ExecuteCommand(browser(), IDC_FOCUS_TOOLBAR);
+  // Might be "Google Chrome Toolbar" or "Chromium Toolbar".
+  EXPECT_TRUE(MatchPattern(monitor.GetNextUtterance(), "*oolbar*"));
+  EXPECT_EQ("Reload,", monitor.GetNextUtterance());
+  EXPECT_EQ("button", monitor.GetNextUtterance());
+}
+
+//
 // Spoken feedback tests of the out-of-box experience.
 //
 
diff --git a/chrome/browser/chromeos/accessibility/touch_exploration_controller_browsertest.cc b/chrome/browser/chromeos/accessibility/touch_exploration_controller_browsertest.cc
new file mode 100644
index 0000000..dd60c17
--- /dev/null
+++ b/chrome/browser/chromeos/accessibility/touch_exploration_controller_browsertest.cc
@@ -0,0 +1,85 @@
+// 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.
+
+#include "ui/chromeos/touch_exploration_controller.h"
+
+#include "ash/accessibility_delegate.h"
+#include "ash/ash_switches.h"
+#include "ash/shell.h"
+#include "ash/test/ash_test_base.h"
+#include "base/command_line.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "ui/aura/test/event_generator.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/compositor/compositor.h"
+#include "ui/compositor/test/draw_waiter_for_test.h"
+#include "ui/events/test/test_event_handler.h"
+
+namespace ui {
+
+class TouchExplorationTest : public InProcessBrowserTest {
+ public:
+  TouchExplorationTest() {}
+  virtual ~TouchExplorationTest() {}
+
+  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+    command_line->AppendSwitch(ash::switches::kAshEnableTouchExplorationMode);
+  }
+
+ protected:
+  void SwitchTouchExplorationMode(bool on) {
+    ash::AccessibilityDelegate* ad =
+        ash::Shell::GetInstance()->accessibility_delegate();
+    if (on != ad->IsSpokenFeedbackEnabled())
+      ad->ToggleSpokenFeedback(ash::A11Y_NOTIFICATION_NONE);
+  }
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(TouchExplorationTest);
+};
+
+IN_PROC_BROWSER_TEST_F(TouchExplorationTest, PRE_ToggleOnOff) {
+  // TODO (mfomitchev): If the test is run by itself, there is a resize at the
+  //  very beginning. An in-progress resize creates a "resize lock" in
+  // RenderWidgetHostViewAura, which calls
+  // WindowEventDispatcher::HoldPointerMoves(), which prevents mouse events from
+  // coming through. Adding a PRE_ test ensures the resize completes before the
+  // actual test is executed. sadrul@ says the resize shouldn't be even
+  // happening, so this needs to be looked at further.
+}
+
+// This test turns the touch exploration mode on/off and confirms that events
+// get rewritten when the touch exploration mode is on, and aren't affected
+// after the touch exploration mode is turned off.
+IN_PROC_BROWSER_TEST_F(TouchExplorationTest, ToggleOnOff) {
+  aura::Window* root_window = ash::Shell::GetInstance()->GetPrimaryRootWindow();
+  scoped_ptr<ui::test::TestEventHandler>
+      event_handler(new ui::test::TestEventHandler());
+  root_window->AddPreTargetHandler(event_handler.get());
+  SwitchTouchExplorationMode(true);
+  aura::test::EventGenerator generator(root_window);
+
+  generator.PressTouchId(1);
+  // Number of mouse events may be greater than 1 because of ET_MOUSE_ENTERED.
+  EXPECT_GT(event_handler->num_mouse_events(), 0);
+  EXPECT_EQ(0, event_handler->num_touch_events());
+  event_handler->Reset();
+
+  SwitchTouchExplorationMode(false);
+  generator.MoveTouchId(gfx::Point(11, 12), 1);
+  EXPECT_EQ(0, event_handler->num_mouse_events());
+  EXPECT_EQ(1, event_handler->num_touch_events());
+  event_handler->Reset();
+
+  SwitchTouchExplorationMode(true);
+  generator.PressTouchId(2);
+  EXPECT_GT(event_handler->num_mouse_events(), 0);
+  EXPECT_EQ(0, event_handler->num_touch_events());
+
+  SwitchTouchExplorationMode(false);
+  root_window->RemovePreTargetHandler(event_handler.get());
+}
+
+}  // namespace ui
diff --git a/chrome/browser/chromeos/app_mode/app_session_lifetime.cc b/chrome/browser/chromeos/app_mode/app_session_lifetime.cc
index 1f865d6..287473a 100644
--- a/chrome/browser/chromeos/app_mode/app_session_lifetime.cc
+++ b/chrome/browser/chromeos/app_mode/app_session_lifetime.cc
@@ -52,8 +52,6 @@
 
  private:
   // apps::AppWindowRegistry::Observer overrides:
-  virtual void OnAppWindowAdded(apps::AppWindow* app_window) OVERRIDE {}
-  virtual void OnAppWindowIconChanged(apps::AppWindow* app_window) OVERRIDE {}
   virtual void OnAppWindowRemoved(apps::AppWindow* app_window) OVERRIDE {
     if (window_registry_->app_windows().empty()) {
       if (DemoAppLauncher::IsDemoAppSession(
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
index 9fab7ce..8b38fbf 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -8,6 +8,7 @@
 #include <set>
 
 #include "base/bind.h"
+#include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/path_service.h"
 #include "base/prefs/pref_registry_simple.h"
@@ -23,7 +24,10 @@
 #include "chrome/browser/chromeos/policy/device_local_account.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/owner_key_util.h"
+#include "chrome/browser/extensions/external_provider_impl.h"
 #include "chrome/common/chrome_paths.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "chromeos/chromeos_paths.h"
 #include "chromeos/cryptohome/async_method_caller.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "content/public/browser/browser_thread.h"
@@ -54,13 +58,21 @@
   *present = util->IsPublicKeyPresent();
 }
 
+scoped_refptr<base::SequencedTaskRunner> GetBackgroundTaskRunner() {
+  base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
+  CHECK(pool);
+  return pool->GetSequencedTaskRunnerWithShutdownBehavior(
+      pool->GetSequenceToken(), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+}
+
 }  // namespace
 
 // static
 const char KioskAppManager::kKioskDictionaryName[] = "kiosk";
 const char KioskAppManager::kKeyApps[] = "apps";
 const char KioskAppManager::kKeyAutoLoginState[] = "auto_login_state";
-const char KioskAppManager::kIconCacheDir[] = "kiosk";
+const char KioskAppManager::kIconCacheDir[] = "kiosk/icon";
+const char KioskAppManager::kCrxCacheDir[] = "kiosk/crx";
 
 // static
 static base::LazyInstance<KioskAppManager> instance = LAZY_INSTANCE_INITIALIZER;
@@ -81,12 +93,12 @@
   registry->RegisterDictionaryPref(kKioskDictionaryName);
 }
 
-KioskAppManager::App::App(const KioskAppData& data)
+KioskAppManager::App::App(const KioskAppData& data, bool is_extension_pending)
     : app_id(data.app_id()),
       user_id(data.user_id()),
       name(data.name()),
       icon(data.icon()),
-      is_loading(data.IsLoading()) {
+      is_loading(data.IsLoading() || is_extension_pending) {
 }
 
 KioskAppManager::App::App() : is_loading(false) {}
@@ -292,7 +304,8 @@
   for (size_t i = 0; i < apps_.size(); ++i) {
     const KioskAppData& app_data = *apps_[i];
     if (app_data.status() != KioskAppData::STATUS_ERROR)
-      apps->push_back(App(app_data));
+      apps->push_back(App(
+          app_data, external_cache_->IsExtensionPending(app_data.app_id())));
   }
 }
 
@@ -301,7 +314,7 @@
   if (!data)
     return false;
 
-  *app = App(*data);
+  *app = App(*data, external_cache_->IsExtensionPending(app_id));
   return true;
 }
 
@@ -352,6 +365,16 @@
 }
 
 KioskAppManager::KioskAppManager() : ownership_established_(false) {
+  base::FilePath cache_dir;
+  GetKioskAppCrxCacheDir(&cache_dir);
+  external_cache_.reset(
+      new ExternalCache(cache_dir,
+                        g_browser_process->system_request_context(),
+                        GetBackgroundTaskRunner(),
+                        this,
+                        true /* always_check_updates */,
+                        false /* wait_for_cache_initialization */));
+
   UpdateAppData();
   local_accounts_subscription_ =
       CrosSettings::Get()->AddSettingsObserver(
@@ -369,6 +392,7 @@
   local_accounts_subscription_.reset();
   local_account_auto_login_id_subscription_.reset();
   apps_.clear();
+  external_cache_.reset();
 }
 
 const KioskAppData* KioskAppManager::GetAppData(
@@ -426,14 +450,24 @@
   }
 
   // Clears cache and deletes the remaining old data.
+  std::vector<std::string> apps_to_remove;
   for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin();
        it != old_apps.end(); ++it) {
     it->second->ClearCache();
     cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
         it->second->user_id(),
         base::Bind(&OnRemoveAppCryptohomeComplete, it->first));
+    apps_to_remove.push_back(it->second->app_id());
   }
   STLDeleteValues(&old_apps);
+  external_cache_->RemoveExtensions(apps_to_remove);
+
+  // Request external_cache_ to download new apps and update the existing
+  // apps.
+  scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue);
+  for (size_t i = 0; i < apps_.size(); ++i)
+    prefs->Set(apps_[i]->app_id(), new base::DictionaryValue);
+  external_cache_->UpdateExtensionsList(prefs.Pass());
 
   FOR_EACH_OBSERVER(KioskAppManagerObserver, observers_,
                     OnKioskAppsSettingsChanged());
@@ -457,6 +491,26 @@
                     OnKioskAppDataLoadFailure(app_id));
 }
 
+void KioskAppManager::OnExtensionListsUpdated(
+    const base::DictionaryValue* prefs) {
+}
+
+void KioskAppManager::OnExtensionLoadedInCache(const std::string& id) {
+  KioskAppData* app_data = GetAppDataMutable(id);
+  if (!app_data)
+    return;
+  OnKioskAppDataChanged(id);
+}
+
+void KioskAppManager::OnExtensionDownloadFailed(
+    const std::string& id,
+    extensions::ExtensionDownloaderDelegate::Error error) {
+  KioskAppData* app_data = GetAppDataMutable(id);
+  if (!app_data)
+    return;
+  OnKioskAppDataLoadFailure(id);
+}
+
 KioskAppManager::AutoLoginState KioskAppManager::GetAutoLoginState() const {
   PrefService* prefs = g_browser_process->local_state();
   const base::DictionaryValue* dict =
@@ -476,4 +530,10 @@
   prefs->CommitPendingWrite();
 }
 
+void KioskAppManager::GetKioskAppCrxCacheDir(base::FilePath* cache_dir) {
+  base::FilePath user_data_dir;
+  CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
+  *cache_dir = user_data_dir.AppendASCII(kCrxCacheDir);
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
index 7c12315..61df498 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.h
@@ -15,6 +15,7 @@
 #include "base/memory/scoped_vector.h"
 #include "base/observer_list.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_data_delegate.h"
+#include "chrome/browser/chromeos/extensions/external_cache.h"
 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "ui/gfx/image/image_skia.h"
@@ -36,7 +37,8 @@
 class KioskAppManagerObserver;
 
 // KioskAppManager manages cached app data.
-class KioskAppManager : public KioskAppDataDelegate {
+class KioskAppManager : public KioskAppDataDelegate,
+                        public ExternalCache::Delegate {
  public:
   enum ConsumerKioskAutoLaunchStatus {
     // Consumer kiosk mode auto-launch feature can be enabled on this machine.
@@ -54,7 +56,7 @@
 
   // Struct to hold app info returned from GetApps() call.
   struct App {
-    explicit App(const KioskAppData& data);
+    App(const KioskAppData& data, bool is_extension_pending);
     App();
     ~App();
 
@@ -78,6 +80,9 @@
   // Sub directory under DIR_USER_DATA to store cached icon files.
   static const char kIconCacheDir[];
 
+  // Sub directory under DIR_USER_DATA to store cached crx files.
+  static const char kCrxCacheDir[];
+
   // Gets the KioskAppManager instance, which is lazily created on first call..
   static KioskAppManager* Get();
 
@@ -179,6 +184,14 @@
   virtual void OnKioskAppDataChanged(const std::string& app_id) OVERRIDE;
   virtual void OnKioskAppDataLoadFailure(const std::string& app_id) OVERRIDE;
 
+  // ExternalCache::Delegate:
+  virtual void OnExtensionListsUpdated(
+      const base::DictionaryValue* prefs) OVERRIDE;
+  virtual void OnExtensionLoadedInCache(const std::string& id) OVERRIDE;
+  virtual void OnExtensionDownloadFailed(
+      const std::string& id,
+      extensions::ExtensionDownloaderDelegate::Error error) OVERRIDE;
+
   // Callback for EnterpriseInstallAttributes::LockDevice() during
   // EnableConsumerModeKiosk() call.
   void OnLockDevice(
@@ -199,6 +212,8 @@
   AutoLoginState GetAutoLoginState() const;
   void SetAutoLoginState(AutoLoginState state);
 
+  void GetKioskAppCrxCacheDir(base::FilePath* cache_dir);
+
   // True if machine ownership is already established.
   bool ownership_established_;
   ScopedVector<KioskAppData> apps_;
@@ -210,6 +225,8 @@
   scoped_ptr<CrosSettings::ObserverSubscription>
       local_account_auto_login_id_subscription_;
 
+  scoped_ptr<ExternalCache> external_cache_;
+
   DISALLOW_COPY_AND_ASSIGN(KioskAppManager);
 };
 
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_update_service.cc b/chrome/browser/chromeos/app_mode/kiosk_app_update_service.cc
index a488b51..e695674 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_update_service.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_update_service.cc
@@ -10,11 +10,11 @@
 #include "chrome/browser/browser_process_platform_part_chromeos.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/system/automatic_reboot_manager.h"
-#include "chrome/browser/extensions/api/runtime/runtime_api.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "extensions/browser/api/runtime/runtime_api.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/extension_system_provider.h"
 #include "extensions/browser/extensions_browser_client.h"
@@ -82,22 +82,22 @@
   extensions::RuntimeEventRouter::DispatchOnRestartRequiredEvent(
       profile_,
       app_id_,
-      extensions::api::runtime::OnRestartRequired::REASON_APP_UPDATE);
+      extensions::core_api::runtime::OnRestartRequired::REASON_APP_UPDATE);
 
   StartAppUpdateRestartTimer();
 }
 
 void KioskAppUpdateService::OnRebootScheduled(Reason reason) {
-  extensions::api::runtime::OnRestartRequired::Reason restart_reason =
-      extensions::api::runtime::OnRestartRequired::REASON_NONE;
+  extensions::core_api::runtime::OnRestartRequired::Reason restart_reason =
+      extensions::core_api::runtime::OnRestartRequired::REASON_NONE;
   switch (reason) {
     case REBOOT_REASON_OS_UPDATE:
       restart_reason =
-          extensions::api::runtime::OnRestartRequired::REASON_OS_UPDATE;
+          extensions::core_api::runtime::OnRestartRequired::REASON_OS_UPDATE;
       break;
     case REBOOT_REASON_PERIODIC:
       restart_reason =
-          extensions::api::runtime::OnRestartRequired::REASON_PERIODIC;
+          extensions::core_api::runtime::OnRestartRequired::REASON_PERIODIC;
       break;
     default:
       NOTREACHED() << "Unknown reboot reason=" << reason;
diff --git a/chrome/browser/chromeos/app_mode/kiosk_diagnosis_runner.cc b/chrome/browser/chromeos/app_mode/kiosk_diagnosis_runner.cc
index 8e1bc05..af74890 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_diagnosis_runner.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_diagnosis_runner.cc
@@ -17,6 +17,8 @@
 #include "extensions/browser/extension_system_provider.h"
 #include "extensions/browser/extensions_browser_client.h"
 
+using feedback::FeedbackData;
+
 namespace chromeos {
 
 class KioskDiagnosisRunner::Factory : public BrowserContextKeyedServiceFactory {
@@ -95,7 +97,7 @@
     const extensions::SystemInformationList& sys_info) {
   scoped_refptr<FeedbackData> feedback_data(new FeedbackData());
 
-  feedback_data->set_profile(profile_);
+  feedback_data->set_context(profile_);
   feedback_data->set_description(base::StringPrintf(
       "Autogenerated feedback:\nAppId: %s\n(uniquifier:%s)",
       app_id_.c_str(),
diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow.cc b/chrome/browser/chromeos/attestation/platform_verification_flow.cc
index 1c31f91..0adda12 100644
--- a/chrome/browser/chromeos/attestation/platform_verification_flow.cc
+++ b/chrome/browser/chromeos/attestation/platform_verification_flow.cc
@@ -445,9 +445,9 @@
          ->WithPathWildcard();
   if (!url.port().empty())
     builder->WithPort(url.port());
-  else if (url.SchemeIs(content::kHttpsScheme))
+  else if (url.SchemeIs(url::kHttpsScheme))
     builder->WithPort(kDefaultHttpsPort);
-  else if (url.SchemeIs(content::kHttpScheme))
+  else if (url.SchemeIs(url::kHttpScheme))
     builder->WithPortWildcard();
   ContentSettingsPattern pattern = builder->Build();
   if (pattern.IsValid()) {
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index 5a66cb5..f4d2074 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -30,6 +30,7 @@
 #include "chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.h"
 #include "chrome/browser/chromeos/boot_times_loader.h"
 #include "chrome/browser/chromeos/dbus/cros_dbus_service.h"
+#include "chrome/browser/chromeos/events/event_rewriter.h"
 #include "chrome/browser/chromeos/events/event_rewriter_controller.h"
 #include "chrome/browser/chromeos/events/keyboard_driven_event_rewriter.h"
 #include "chrome/browser/chromeos/extensions/default_app_order.h"
@@ -116,7 +117,6 @@
 // Exclude X11 dependents for ozone
 #if defined(USE_X11)
 #include "chrome/browser/chromeos/device_uma.h"
-#include "chrome/browser/chromeos/events/event_rewriter.h"
 #include "chrome/browser/chromeos/events/system_key_event_listener.h"
 #include "chrome/browser/chromeos/events/xinput_hierarchy_changed_event_listener.h"
 #endif
@@ -247,16 +247,6 @@
 class DBusServices {
  public:
   explicit DBusServices(const content::MainFunctionParams& parameters) {
-    if (!base::SysInfo::IsRunningOnChromeOS()) {
-      // Override this path on the desktop, so that the user policy key can be
-      // stored by the stub SessionManagerClient.
-      base::FilePath user_data_dir;
-      if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
-        PathService::Override(chromeos::DIR_USER_POLICY_KEYS,
-                              user_data_dir.AppendASCII("stub_user_policy"));
-      }
-    }
-
     // Initialize DBusThreadManager for the browser. This must be done after
     // the main message loop is started, as it uses the message loop.
     DBusThreadManager::Initialize();
@@ -404,6 +394,15 @@
 }
 
 void ChromeBrowserMainPartsChromeos::PostMainMessageLoopStart() {
+  base::FilePath user_data_dir;
+  if (!base::SysInfo::IsRunningOnChromeOS() &&
+      PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
+    // Override some paths with stub locations so that cloud policy and
+    // enterprise enrollment work on desktop builds, for ease of
+    // development.
+    chromeos::RegisterStubPathOverrides(user_data_dir);
+  }
+
   dbus_services_.reset(new internal::DBusServices(parameters()));
 
   ChromeBrowserMainPartsLinux::PostMainMessageLoopStart();
@@ -720,12 +719,12 @@
 
   // Start the CrOS input device UMA watcher
   DeviceUMA::GetInstance();
-
-  event_rewriter_.reset(new EventRewriter());
 #endif
   keyboard_event_rewriters_.reset(new EventRewriterController());
   keyboard_event_rewriters_->AddEventRewriter(
       scoped_ptr<ui::EventRewriter>(new KeyboardDrivenEventRewriter()));
+  keyboard_event_rewriters_->AddEventRewriter(
+      scoped_ptr<ui::EventRewriter>(new EventRewriter()));
 
   // -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
   // -- immediately after ChildProcess::WaitForDebugger().
@@ -797,8 +796,6 @@
 
   keyboard_event_rewriters_.reset();
 #if defined(USE_X11)
-  event_rewriter_.reset();
-
   // The XInput2 event listener needs to be shut down earlier than when
   // Singletons are finally destroyed in AtExitManager.
   XInputHierarchyChangedEventListener::GetInstance()->Stop();
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
index cc6b06b..9f1b5e4 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
@@ -69,9 +69,6 @@
 
   scoped_ptr<internal::DBusServices> dbus_services_;
 
-#if defined(USE_X11)
-  scoped_ptr<EventRewriter> event_rewriter_;
-#endif
   scoped_ptr<EventRewriterController> keyboard_event_rewriters_;
 
   VersionLoader cros_version_loader_;
diff --git a/chrome/browser/chromeos/drive/file_system_util.cc b/chrome/browser/chromeos/drive/file_system_util.cc
index 9eb52e2..5cba03b 100644
--- a/chrome/browser/chromeos/drive/file_system_util.cc
+++ b/chrome/browser/chromeos/drive/file_system_util.cc
@@ -299,7 +299,7 @@
 }
 
 std::string NormalizeFileName(const std::string& input) {
-  DCHECK(IsStringUTF8(input));
+  DCHECK(base::IsStringUTF8(input));
 
   std::string output;
   if (!base::ConvertToUtf8AndNormalize(input, base::kCodepageUTF8, &output))
diff --git a/chrome/browser/chromeos/drive/local_file_reader.cc b/chrome/browser/chromeos/drive/local_file_reader.cc
index e6bacc1..5041811 100644
--- a/chrome/browser/chromeos/drive/local_file_reader.cc
+++ b/chrome/browser/chromeos/drive/local_file_reader.cc
@@ -28,7 +28,7 @@
                            const net::CompletionCallback& callback) {
   DCHECK(!callback.is_null());
   int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
-              base::PLATFORM_FILE_ASYNC;
+              base::File::FLAG_ASYNC;
 
   int rv = file_stream_.Open(file_path, flags,
                              Bind(&LocalFileReader::DidOpen,
diff --git a/chrome/browser/chromeos/drive/resource_metadata.cc b/chrome/browser/chromeos/drive/resource_metadata.cc
index 0b8fd44..56c0101 100644
--- a/chrome/browser/chromeos/drive/resource_metadata.cc
+++ b/chrome/browser/chromeos/drive/resource_metadata.cc
@@ -84,9 +84,21 @@
   if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
     return FILE_ERROR_NO_LOCAL_SPACE;
 
-  if (!storage_->SetLargestChangestamp(0) ||
-      !RemoveEntryRecursively(util::kDriveGrandRootLocalId) ||
-      !SetUpDefaultEntries())
+  if (!storage_->SetLargestChangestamp(0))
+    return FILE_ERROR_FAILED;
+
+  // Remove all root entries.
+  scoped_ptr<Iterator> it = GetIterator();
+  for (; !it->IsAtEnd(); it->Advance()) {
+    if (it->GetValue().parent_local_id().empty()) {
+      if (!RemoveEntryRecursively(it->GetID()))
+        return FILE_ERROR_FAILED;
+    }
+  }
+  if (it->HasError())
+    return FILE_ERROR_FAILED;
+
+  if (!SetUpDefaultEntries())
     return FILE_ERROR_FAILED;
 
   return FILE_ERROR_OK;
diff --git a/chrome/browser/chromeos/events/event_rewriter.cc b/chrome/browser/chromeos/events/event_rewriter.cc
index 75e8663..c251889 100644
--- a/chrome/browser/chromeos/events/event_rewriter.cc
+++ b/chrome/browser/chromeos/events/event_rewriter.cc
@@ -4,14 +4,6 @@
 
 #include "chrome/browser/chromeos/events/event_rewriter.h"
 
-#include <X11/extensions/XInput2.h>
-#include <X11/keysym.h>
-#include <X11/XF86keysym.h>
-#include <X11/Xlib.h>
-// Get rid of macros from Xlib.h that conflicts with other parts of the code.
-#undef RootWindow
-#undef Status
-
 #include <vector>
 
 #include "ash/wm/window_state.h"
@@ -21,7 +13,6 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_util.h"
 #include "base/sys_info.h"
-#include "chrome/browser/chromeos/events/xinput_hierarchy_changed_event_listener.h"
 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -29,58 +20,62 @@
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/ime/ime_keyboard.h"
 #include "chromeos/ime/input_method_manager.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
-#include "ui/events/keycodes/keyboard_code_conversion_x.h"
+#include "ui/events/keycodes/keyboard_code_conversion.h"
 #include "ui/events/platform/platform_event_source.h"
 #include "ui/wm/core/window_util.h"
 
+#if defined(USE_X11)
+#include <X11/extensions/XInput2.h>
+#include <X11/Xlib.h>
+// Get rid of macros from Xlib.h that conflicts with other parts of the code.
+#undef RootWindow
+#undef Status
+
+#include "chrome/browser/chromeos/events/xinput_hierarchy_changed_event_listener.h"
+#include "ui/base/x/x11_util.h"
+#include "ui/events/keycodes/keyboard_code_conversion_x.h"
+#endif
+
+namespace chromeos {
+
 namespace {
 
 const int kBadDeviceId = -1;
 
-// A key code and a flag we should use when a key is remapped to |remap_to|.
+// Table of key properties of remappable keys and/or remapping targets.
+// This is searched in two distinct ways:
+//  - |remap_to| is an |input_method::ModifierKey|, which is the form
+//    held in user preferences. |GetRemappedKey()| maps this to the
+//    corresponding |key_code| and characterstic event |flag|.
+//  - |flag| is a |ui::EventFlags|. |GetRemappedModifierMasks()| maps this
+//    to the corresponding user preference |pref_name| for that flag's
+//    key, so that it can then be remapped as above.
+// In addition |kModifierRemappingCtrl| is a direct reference to the
+// Control key entry in the table, used in handling Chromebook Diamond
+// and Apple Command keys.
 const struct ModifierRemapping {
   int remap_to;
   int flag;
-  unsigned int native_modifier;
-  ui::KeyboardCode keycode;
-  KeySym native_keysyms[4];  // left, right, shift+left, shift+right.
+  ui::KeyboardCode key_code;
+  const char* pref_name;
 } kModifierRemappings[] = {
-  { chromeos::input_method::kSearchKey, 0, Mod4Mask, ui::VKEY_LWIN,
-    { XK_Super_L, XK_Super_L, XK_Super_L, XK_Super_L }},
-  { chromeos::input_method::kControlKey, ui::EF_CONTROL_DOWN, ControlMask,
-    ui::VKEY_CONTROL,
-    { XK_Control_L, XK_Control_R, XK_Control_L, XK_Control_R }},
-  { chromeos::input_method::kAltKey, ui::EF_ALT_DOWN, Mod1Mask,
-    ui::VKEY_MENU, { XK_Alt_L, XK_Alt_R, XK_Meta_L, XK_Meta_R }},
-  { chromeos::input_method::kVoidKey, 0, 0U, ui::VKEY_UNKNOWN,
-    { XK_VoidSymbol, XK_VoidSymbol, XK_VoidSymbol, XK_VoidSymbol }},
-  { chromeos::input_method::kCapsLockKey, 0, 0U, ui::VKEY_CAPITAL,
-    { XK_Caps_Lock, XK_Caps_Lock, XK_Caps_Lock, XK_Caps_Lock }},
-  { chromeos::input_method::kEscapeKey, 0, 0U, ui::VKEY_ESCAPE,
-    { XK_Escape, XK_Escape, XK_Escape, XK_Escape }},
+      {input_method::kSearchKey, ui::EF_COMMAND_DOWN, ui::VKEY_LWIN,
+       prefs::kLanguageRemapSearchKeyTo},
+      {input_method::kControlKey, ui::EF_CONTROL_DOWN, ui::VKEY_CONTROL,
+       prefs::kLanguageRemapControlKeyTo},
+      {input_method::kAltKey, ui::EF_ALT_DOWN, ui::VKEY_MENU,
+       prefs::kLanguageRemapAltKeyTo},
+      {input_method::kVoidKey, 0, ui::VKEY_UNKNOWN, NULL},
+      {input_method::kCapsLockKey, ui::EF_CAPS_LOCK_DOWN, ui::VKEY_CAPITAL,
+       prefs::kLanguageRemapCapsLockKeyTo},
+      {input_method::kEscapeKey, 0, ui::VKEY_ESCAPE, NULL},
+      {0, 0, ui::VKEY_F15, prefs::kLanguageRemapDiamondKeyTo},
 };
 
 const ModifierRemapping* kModifierRemappingCtrl = &kModifierRemappings[1];
 
-// A structure for converting |native_modifier| to a pair of |flag| and
-// |pref_name|.
-const struct ModifierFlagToPrefName {
-  unsigned int native_modifier;
-  int flag;
-  const char* pref_name;
-} kModifierFlagToPrefName[] = {
-  // TODO(yusukes): When the device has a Chrome keyboard (i.e. the one without
-  // Caps Lock), we should not check kLanguageRemapCapsLockKeyTo.
-  { Mod3Mask, 0, prefs::kLanguageRemapCapsLockKeyTo },
-  { Mod4Mask, 0, prefs::kLanguageRemapSearchKeyTo },
-  { ControlMask, ui::EF_CONTROL_DOWN, prefs::kLanguageRemapControlKeyTo },
-  { Mod1Mask, ui::EF_ALT_DOWN, prefs::kLanguageRemapAltKeyTo },
-  { Mod2Mask, 0, prefs::kLanguageRemapDiamondKeyTo },
-};
-
 // Gets a remapped key for |pref_name| key. For example, to find out which
 // key Search is currently remapped to, call the function with
 // prefs::kLanguageRemapSearchKeyTo.
@@ -96,21 +91,6 @@
   return NULL;
 }
 
-bool IsRight(KeySym native_keysym) {
-  switch (native_keysym) {
-    case XK_Alt_R:
-    case XK_Control_R:
-    case XK_Hyper_R:
-    case XK_Meta_R:
-    case XK_Shift_R:
-    case XK_Super_R:
-      return true;
-    default:
-      break;
-  }
-  return false;
-}
-
 bool HasDiamondKey() {
   return CommandLine::ForCurrentProcess()->HasSwitch(
       chromeos::switches::kHasChromeOSDiamondKey);
@@ -121,42 +101,12 @@
   // it's not possible to make both features work. For now, we don't remap
   // Mod3Mask when Neo2 is in use.
   // TODO(yusukes): Remove the restriction.
-  chromeos::input_method::InputMethodManager* manager =
-      chromeos::input_method::InputMethodManager::Get();
+  input_method::InputMethodManager* manager =
+      input_method::InputMethodManager::Get();
   return manager->IsISOLevel5ShiftUsedByCurrentInputMethod();
 }
 
-}  // namespace
-
-namespace chromeos {
-
-EventRewriter::EventRewriter()
-    : last_device_id_(kBadDeviceId),
-      keyboard_for_testing_(NULL),
-      pref_service_for_testing_(NULL) {
-  ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
-  if (base::SysInfo::IsRunningOnChromeOS()) {
-    XInputHierarchyChangedEventListener::GetInstance()->AddObserver(this);
-  }
-  RefreshKeycodes();
-}
-
-EventRewriter::~EventRewriter() {
-  ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
-  if (base::SysInfo::IsRunningOnChromeOS()) {
-    XInputHierarchyChangedEventListener::GetInstance()->RemoveObserver(this);
-  }
-}
-
-EventRewriter::DeviceType EventRewriter::DeviceAddedForTesting(
-    int device_id,
-    const std::string& device_name) {
-  return DeviceAddedInternal(device_id, device_name);
-}
-
-// static
-EventRewriter::DeviceType EventRewriter::GetDeviceType(
-    const std::string& device_name) {
+EventRewriter::DeviceType GetDeviceType(const std::string& device_name) {
   std::vector<std::string> tokens;
   Tokenize(device_name, " .", &tokens);
 
@@ -170,44 +120,600 @@
     if (!found_keyboard && LowerCaseEqualsASCII(tokens[i], "keyboard"))
       found_keyboard = true;
     if (found_apple && found_keyboard)
-      return kDeviceAppleKeyboard;
+      return EventRewriter::kDeviceAppleKeyboard;
   }
 
-  return kDeviceUnknown;
+  return EventRewriter::kDeviceUnknown;
 }
 
-void EventRewriter::RewriteForTesting(XEvent* event) {
-  Rewrite(event);
+#if defined(USE_X11)
+void UpdateX11EventMask(int ui_flags, unsigned int* x_flags) {
+  static struct {
+    int ui;
+    int x;
+  } flags[] = {
+    {ui::EF_CONTROL_DOWN, ControlMask},
+    {ui::EF_SHIFT_DOWN, ShiftMask},
+    {ui::EF_ALT_DOWN, Mod1Mask},
+    {ui::EF_CAPS_LOCK_DOWN, LockMask},
+    {ui::EF_ALTGR_DOWN, Mod5Mask},
+    {ui::EF_MOD3_DOWN, Mod3Mask},
+    {ui::EF_NUMPAD_KEY, Mod2Mask},
+    {ui::EF_LEFT_MOUSE_BUTTON, Button1Mask},
+    {ui::EF_MIDDLE_MOUSE_BUTTON, Button2Mask},
+    {ui::EF_RIGHT_MOUSE_BUTTON, Button3Mask},
+  };
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(flags); ++i) {
+    if (ui_flags & flags[i].ui)
+      *x_flags |= flags[i].x;
+    else
+      *x_flags &= ~flags[i].x;
+  }
+}
+#endif
+
+}  // namespace
+
+EventRewriter::EventRewriter()
+    : last_device_id_(kBadDeviceId),
+      ime_keyboard_for_testing_(NULL),
+      pref_service_for_testing_(NULL) {
+#if defined(USE_X11)
+  ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
+  if (base::SysInfo::IsRunningOnChromeOS()) {
+    XInputHierarchyChangedEventListener::GetInstance()->AddObserver(this);
+  }
+#endif
 }
 
+EventRewriter::~EventRewriter() {
+#if defined(USE_X11)
+  ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
+  if (base::SysInfo::IsRunningOnChromeOS()) {
+    XInputHierarchyChangedEventListener::GetInstance()->RemoveObserver(this);
+  }
+#endif
+}
+
+EventRewriter::DeviceType EventRewriter::DeviceAddedForTesting(
+    int device_id,
+    const std::string& device_name) {
+  return DeviceAddedInternal(device_id, device_name);
+}
+
+void EventRewriter::RewriteLocatedEventForTesting(const ui::Event& event,
+                                                  int* flags) {
+  MutableKeyState state = {*flags, ui::VKEY_UNKNOWN};
+  RewriteLocatedEvent(event, &state);
+  *flags = state.flags;
+}
+
+ui::EventRewriteStatus EventRewriter::RewriteEvent(
+    const ui::Event& event,
+    scoped_ptr<ui::Event>* rewritten_event) {
+#if defined(USE_X11)
+  // Do not rewrite an event sent by ui_controls::SendKeyPress(). See
+  // crbug.com/136465.
+  XEvent* xev = event.native_event();
+  if (xev && xev->xany.send_event)
+    return ui::EVENT_REWRITE_CONTINUE;
+#endif
+  switch (event.type()) {
+    case ui::ET_KEY_PRESSED:
+    case ui::ET_KEY_RELEASED: {
+      const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event);
+      MutableKeyState state = {key_event.flags(), key_event.key_code()};
+      RewriteModifierKeys(key_event, &state);
+      RewriteNumPadKeys(key_event, &state);
+      RewriteExtendedKeys(key_event, &state);
+      RewriteFunctionKeys(key_event, &state);
+      if ((key_event.flags() != state.flags) ||
+          (key_event.key_code() != state.key_code)) {
+        ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event);
+        rewritten_event->reset(rewritten_key_event);
+        rewritten_key_event->set_flags(state.flags);
+        rewritten_key_event->set_key_code(state.key_code);
+        rewritten_key_event->set_character(
+            ui::GetCharacterFromKeyCode(state.key_code, state.flags));
+        rewritten_key_event->NormalizeFlags();
+#if defined(USE_X11)
+        xev = rewritten_key_event->native_event();
+        if (xev) {
+          XKeyEvent* xkey = &(xev->xkey);
+          UpdateX11EventMask(state.flags, &xkey->state);
+          xkey->keycode = XKeysymToKeycode(
+              gfx::GetXDisplay(),
+              ui::XKeysymForWindowsKeyCode(state.key_code,
+                                           state.flags & ui::EF_SHIFT_DOWN));
+        }
+#endif
+        return ui::EVENT_REWRITE_REWRITTEN;
+      }
+      return ui::EVENT_REWRITE_CONTINUE;
+    }
+    case ui::ET_MOUSE_PRESSED:
+    case ui::ET_MOUSE_RELEASED:
+    case ui::ET_TOUCH_PRESSED:
+    case ui::ET_TOUCH_RELEASED: {
+      MutableKeyState state = {event.flags(), ui::VKEY_UNKNOWN};
+      RewriteLocatedEvent(event, &state);
+      if (event.flags() != state.flags) {
+        if (event.IsMouseEvent()) {
+          rewritten_event->reset(
+              new ui::MouseEvent(static_cast<const ui::MouseEvent&>(event)));
+        } else {
+          rewritten_event->reset(
+              new ui::TouchEvent(static_cast<const ui::TouchEvent&>(event)));
+        }
+        rewritten_event->get()->set_flags(state.flags);
+        return ui::EVENT_REWRITE_REWRITTEN;
+      }
+      return ui::EVENT_REWRITE_CONTINUE;
+    }
+    default:
+      return ui::EVENT_REWRITE_CONTINUE;
+  }
+  NOTREACHED();
+}
+
+ui::EventRewriteStatus EventRewriter::NextDispatchEvent(
+    const ui::Event& last_event,
+    scoped_ptr<ui::Event>* new_event) {
+  NOTREACHED();
+  return ui::EVENT_REWRITE_CONTINUE;
+}
+
+#if defined(USE_X11)
 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) {
-  std::map<int, DeviceType>::const_iterator iter =
-      device_id_to_type_.find(device_id);
-  if (iter == device_id_to_type_.end()) {
+  if (!device_id_to_type_.count(device_id)) {
     // |device_id| is unknown. This means the device was connected before
     // booting the OS. Query the name of the device and add it to the map.
     DeviceAdded(device_id);
   }
-
   last_device_id_ = device_id;
 }
+#endif
 
+const PrefService* EventRewriter::GetPrefService() const {
+  if (pref_service_for_testing_)
+    return pref_service_for_testing_;
+  Profile* profile = ProfileManager::GetActiveUserProfile();
+  return profile ? profile->GetPrefs() : NULL;
+}
+
+bool EventRewriter::IsAppleKeyboard() const {
+  if (last_device_id_ == kBadDeviceId)
+    return false;
+
+  // Check which device generated |event|.
+  std::map<int, DeviceType>::const_iterator iter =
+      device_id_to_type_.find(last_device_id_);
+  if (iter == device_id_to_type_.end()) {
+    LOG(ERROR) << "Device ID " << last_device_id_ << " is unknown.";
+    return false;
+  }
+
+  const DeviceType type = iter->second;
+  return type == kDeviceAppleKeyboard;
+}
+
+bool EventRewriter::TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const {
+  const PrefService* prefs = GetPrefService();
+  if (prefs && prefs->FindPreference(prefs::kLanguageSendFunctionKeys) &&
+      prefs->GetBoolean(prefs::kLanguageSendFunctionKeys))
+    return true;
+
+  ash::wm::WindowState* state = ash::wm::GetActiveWindowState();
+  return state ? state->top_row_keys_are_function_keys() : false;
+}
+
+int EventRewriter::GetRemappedModifierMasks(const PrefService& pref_service,
+                                            const ui::Event& event,
+                                            int original_flags) const {
+  int unmodified_flags = original_flags;
+  int rewritten_flags = 0;
+  for (size_t i = 0; unmodified_flags && (i < arraysize(kModifierRemappings));
+       ++i) {
+    const ModifierRemapping* remapped_key = 0;
+    if (!(unmodified_flags & kModifierRemappings[i].flag))
+      continue;
+    switch (kModifierRemappings[i].flag) {
+      case ui::EF_COMMAND_DOWN:
+        // Rewrite Command key presses on an Apple keyboard to Control.
+        if (IsAppleKeyboard()) {
+          DCHECK_EQ(ui::EF_CONTROL_DOWN, kModifierRemappingCtrl->flag);
+          remapped_key = kModifierRemappingCtrl;
+        }
+        break;
+      case ui::EF_CAPS_LOCK_DOWN:
+        // If CapsLock is used by the current input method, don't allow the
+        // CapsLock pref to remap it, or the keyboard behavior will be broken.
+        if (IsISOLevel5ShiftUsedByCurrentInputMethod())
+          continue;
+        break;
+      default:
+        break;
+    }
+    if (!remapped_key && kModifierRemappings[i].pref_name) {
+      remapped_key =
+          GetRemappedKey(kModifierRemappings[i].pref_name, pref_service);
+    }
+    if (remapped_key) {
+      unmodified_flags &= ~kModifierRemappings[i].flag;
+      rewritten_flags |= remapped_key->flag;
+    }
+  }
+  return rewritten_flags | unmodified_flags;
+}
+
+bool EventRewriter::RewriteWithKeyboardRemappingsByKeyCode(
+    const KeyboardRemapping* remappings,
+    size_t num_remappings,
+    const MutableKeyState& input,
+    MutableKeyState* remapped_state) {
+  for (size_t i = 0; i < num_remappings; ++i) {
+    const KeyboardRemapping& map = remappings[i];
+    if (input.key_code != map.input_key_code)
+      continue;
+    if ((input.flags & map.input_flags) != map.input_flags)
+      continue;
+    remapped_state->key_code = map.output_key_code;
+    remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags;
+    return true;
+  }
+  return false;
+}
+
+void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event,
+                                        MutableKeyState* state) {
+  DCHECK(key_event.type() == ui::ET_KEY_PRESSED ||
+         key_event.type() == ui::ET_KEY_RELEASED);
+
+  // Do nothing if we have just logged in as guest but have not restarted chrome
+  // process yet (so we are still on the login screen). In this situations we
+  // have no user profile so can not do anything useful.
+  // Note that currently, unlike other accounts, when user logs in as guest, we
+  // restart chrome process. In future this is to be changed.
+  // TODO(glotov): remove the following condition when we do not restart chrome
+  // when user logs in as guest.
+  // TODO(kpschoedel): check whether this is still necessary.
+  if (UserManager::Get()->IsLoggedInAsGuest() &&
+      LoginDisplayHostImpl::default_host())
+    return;
+
+  const PrefService* pref_service = GetPrefService();
+  if (!pref_service)
+    return;
+
+  MutableKeyState incoming = *state;
+  state->flags = ui::EF_NONE;
+  int characteristic_flag = ui::EF_NONE;
+
+  // First, remap the key code.
+  const ModifierRemapping* remapped_key = NULL;
+  switch (incoming.key_code) {
+    // On Chrome OS, F15 (XF86XK_Launch6) with NumLock (Mod2Mask) is sent
+    // when Diamond key is pressed.
+    case ui::VKEY_F15:
+      // When diamond key is not available, the configuration UI for Diamond
+      // key is not shown. Therefore, ignore the kLanguageRemapDiamondKeyTo
+      // syncable pref.
+      if (HasDiamondKey())
+        remapped_key =
+            GetRemappedKey(prefs::kLanguageRemapDiamondKeyTo, *pref_service);
+      // Default behavior is Ctrl key.
+      if (!remapped_key) {
+        DCHECK_EQ(ui::VKEY_CONTROL, kModifierRemappingCtrl->key_code);
+        remapped_key = kModifierRemappingCtrl;
+        characteristic_flag = ui::EF_CONTROL_DOWN;
+      }
+      break;
+    // On Chrome OS, XF86XK_Launch7 (F16) with Mod3Mask is sent when Caps Lock
+    // is pressed (with one exception: when
+    // IsISOLevel5ShiftUsedByCurrentInputMethod() is true, the key generates
+    // XK_ISO_Level3_Shift with Mod3Mask, not XF86XK_Launch7).
+    case ui::VKEY_F16:
+      characteristic_flag = ui::EF_CAPS_LOCK_DOWN;
+      remapped_key =
+          GetRemappedKey(prefs::kLanguageRemapCapsLockKeyTo, *pref_service);
+      break;
+    case ui::VKEY_LWIN:
+    case ui::VKEY_RWIN:
+      characteristic_flag = ui::EF_COMMAND_DOWN;
+      // Rewrite Command-L/R key presses on an Apple keyboard to Control.
+      if (IsAppleKeyboard()) {
+        DCHECK_EQ(ui::VKEY_CONTROL, kModifierRemappingCtrl->key_code);
+        remapped_key = kModifierRemappingCtrl;
+      } else {
+        remapped_key =
+            GetRemappedKey(prefs::kLanguageRemapSearchKeyTo, *pref_service);
+      }
+      // Default behavior is Super key, hence don't remap the event if the pref
+      // is unavailable.
+      break;
+    case ui::VKEY_CONTROL:
+      characteristic_flag = ui::EF_CONTROL_DOWN;
+      remapped_key =
+          GetRemappedKey(prefs::kLanguageRemapControlKeyTo, *pref_service);
+      break;
+    case ui::VKEY_MENU:
+      // ALT key
+      characteristic_flag = ui::EF_ALT_DOWN;
+      remapped_key =
+          GetRemappedKey(prefs::kLanguageRemapAltKeyTo, *pref_service);
+      break;
+    default:
+      break;
+  }
+
+  if (remapped_key) {
+    state->key_code = remapped_key->key_code;
+    incoming.flags |= characteristic_flag;
+    characteristic_flag = remapped_key->flag;
+  }
+
+  // Next, remap modifier bits.
+  state->flags |=
+      GetRemappedModifierMasks(*pref_service, key_event, incoming.flags);
+  if (key_event.type() == ui::ET_KEY_PRESSED)
+    state->flags |= characteristic_flag;
+  else
+    state->flags &= ~characteristic_flag;
+
+  // Toggle Caps Lock if the remapped key is ui::VKEY_CAPITAL, but do nothing if
+  // the original key is ui::VKEY_CAPITAL (i.e. a Caps Lock key on an external
+  // keyboard is pressed) since X can handle that case.
+  if (key_event.type() == ui::ET_KEY_PRESSED &&
+      incoming.key_code != ui::VKEY_CAPITAL &&
+      state->key_code == ui::VKEY_CAPITAL) {
+    chromeos::input_method::ImeKeyboard* ime_keyboard =
+        ime_keyboard_for_testing_
+            ? ime_keyboard_for_testing_
+            : chromeos::input_method::InputMethodManager::Get()
+                  ->GetImeKeyboard();
+    ime_keyboard->SetCapsLockEnabled(!ime_keyboard->CapsLockIsEnabled());
+  }
+}
+
+void EventRewriter::RewriteNumPadKeys(const ui::KeyEvent& key_event,
+                                      MutableKeyState* state) {
+  DCHECK(key_event.type() == ui::ET_KEY_PRESSED ||
+         key_event.type() == ui::ET_KEY_RELEASED);
+  if (!(state->flags & ui::EF_NUMPAD_KEY))
+    return;
+  MutableKeyState incoming = *state;
+
+  static const KeyboardRemapping kNumPadRemappings[] = {
+      {ui::VKEY_INSERT, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY},
+      {ui::VKEY_DELETE, ui::EF_NUMPAD_KEY, ui::VKEY_DECIMAL, ui::EF_NUMPAD_KEY},
+      {ui::VKEY_END, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD1, ui::EF_NUMPAD_KEY},
+      {ui::VKEY_DOWN, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD2, ui::EF_NUMPAD_KEY},
+      {ui::VKEY_NEXT, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD3, ui::EF_NUMPAD_KEY},
+      {ui::VKEY_LEFT, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD4, ui::EF_NUMPAD_KEY},
+      {ui::VKEY_CLEAR, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD5, ui::EF_NUMPAD_KEY},
+      {ui::VKEY_RIGHT, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD6, ui::EF_NUMPAD_KEY},
+      {ui::VKEY_HOME, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD7, ui::EF_NUMPAD_KEY},
+      {ui::VKEY_UP, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD8, ui::EF_NUMPAD_KEY},
+      {ui::VKEY_PRIOR, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD9, ui::EF_NUMPAD_KEY},
+  };
+
+  RewriteWithKeyboardRemappingsByKeyCode(
+      kNumPadRemappings, arraysize(kNumPadRemappings), incoming, state);
+}
+
+void EventRewriter::RewriteExtendedKeys(const ui::KeyEvent& key_event,
+                                        MutableKeyState* state) {
+  DCHECK(key_event.type() == ui::ET_KEY_PRESSED ||
+         key_event.type() == ui::ET_KEY_RELEASED);
+
+  MutableKeyState incoming = *state;
+  bool rewritten = false;
+
+  if ((incoming.flags & (ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN)) ==
+      (ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN)) {
+    // Allow Search to avoid rewriting extended keys.
+    static const KeyboardRemapping kAvoidRemappings[] = {
+        {  // Alt+Backspace
+         ui::VKEY_BACK, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, ui::VKEY_BACK,
+         ui::EF_ALT_DOWN,
+        },
+        {  // Control+Alt+Up
+         ui::VKEY_UP,
+         ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_COMMAND_DOWN,
+         ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
+        },
+        {  // Alt+Up
+         ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, ui::VKEY_UP,
+         ui::EF_ALT_DOWN,
+        },
+        {  // Control+Alt+Down
+         ui::VKEY_DOWN,
+         ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_COMMAND_DOWN,
+         ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
+        },
+        {  // Alt+Down
+         ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, ui::VKEY_DOWN,
+         ui::EF_ALT_DOWN,
+        }};
+
+    rewritten = RewriteWithKeyboardRemappingsByKeyCode(
+        kAvoidRemappings, arraysize(kAvoidRemappings), incoming, state);
+  }
+
+  if (!rewritten && (incoming.flags & ui::EF_COMMAND_DOWN)) {
+    static const KeyboardRemapping kSearchRemappings[] = {
+        {  // Search+BackSpace -> Delete
+         ui::VKEY_BACK, ui::EF_COMMAND_DOWN, ui::VKEY_DELETE, 0},
+        {  // Search+Left -> Home
+         ui::VKEY_LEFT, ui::EF_COMMAND_DOWN, ui::VKEY_HOME, 0},
+        {  // Search+Up -> Prior (aka PageUp)
+         ui::VKEY_UP, ui::EF_COMMAND_DOWN, ui::VKEY_PRIOR, 0},
+        {  // Search+Right -> End
+         ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN, ui::VKEY_END, 0},
+        {  // Search+Down -> Next (aka PageDown)
+         ui::VKEY_DOWN, ui::EF_COMMAND_DOWN, ui::VKEY_NEXT, 0},
+        {  // Search+Period -> Insert
+         ui::VKEY_OEM_PERIOD, ui::EF_COMMAND_DOWN, ui::VKEY_INSERT, 0}};
+
+    rewritten = RewriteWithKeyboardRemappingsByKeyCode(
+        kSearchRemappings, arraysize(kSearchRemappings), incoming, state);
+  }
+
+  if (!rewritten && (incoming.flags & ui::EF_ALT_DOWN)) {
+    static const KeyboardRemapping kNonSearchRemappings[] = {
+        {  // Alt+BackSpace -> Delete
+         ui::VKEY_BACK, ui::EF_ALT_DOWN, ui::VKEY_DELETE, 0},
+        {  // Control+Alt+Up -> Home
+         ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, ui::VKEY_HOME, 0},
+        {  // Alt+Up -> Prior (aka PageUp)
+         ui::VKEY_UP, ui::EF_ALT_DOWN, ui::VKEY_PRIOR, 0},
+        {  // Control+Alt+Down -> End
+         ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, ui::VKEY_END, 0},
+        {  // Alt+Down -> Next (aka PageDown)
+         ui::VKEY_DOWN, ui::EF_ALT_DOWN, ui::VKEY_NEXT, 0}};
+
+    rewritten = RewriteWithKeyboardRemappingsByKeyCode(
+        kNonSearchRemappings, arraysize(kNonSearchRemappings), incoming, state);
+  }
+}
+
+void EventRewriter::RewriteFunctionKeys(const ui::KeyEvent& key_event,
+                                        MutableKeyState* state) {
+  CHECK(key_event.type() == ui::ET_KEY_PRESSED ||
+        key_event.type() == ui::ET_KEY_RELEASED);
+  MutableKeyState incoming = *state;
+  bool rewritten = false;
+
+  if ((incoming.key_code >= ui::VKEY_F1) &&
+      (incoming.key_code <= ui::VKEY_F24)) {
+    // By default the top row (F1-F12) keys are system keys for back, forward,
+    // brightness, volume, etc. However, windows for v2 apps can optionally
+    // request raw function keys for these keys.
+    bool top_row_keys_are_function_keys = TopRowKeysAreFunctionKeys(key_event);
+    bool search_is_pressed = (incoming.flags & ui::EF_COMMAND_DOWN) != 0;
+
+    //  Search? Top Row   Result
+    //  ------- --------  ------
+    //  No      Fn        Unchanged
+    //  No      System    Fn -> System
+    //  Yes     Fn        Fn -> System
+    //  Yes     System    Search+Fn -> Fn
+    if (top_row_keys_are_function_keys == search_is_pressed) {
+      // Rewrite the F1-F12 keys on a Chromebook keyboard to system keys.
+      static const KeyboardRemapping kFkeysToSystemKeys[] = {
+          {ui::VKEY_F1, 0, ui::VKEY_BROWSER_BACK, 0},
+          {ui::VKEY_F2, 0, ui::VKEY_BROWSER_FORWARD, 0},
+          {ui::VKEY_F3, 0, ui::VKEY_BROWSER_REFRESH, 0},
+          {ui::VKEY_F4, 0, ui::VKEY_MEDIA_LAUNCH_APP2, 0},
+          {ui::VKEY_F5, 0, ui::VKEY_MEDIA_LAUNCH_APP1, 0},
+          {ui::VKEY_F6, 0, ui::VKEY_BRIGHTNESS_DOWN, 0},
+          {ui::VKEY_F7, 0, ui::VKEY_BRIGHTNESS_UP, 0},
+          {ui::VKEY_F8, 0, ui::VKEY_VOLUME_MUTE, 0},
+          {ui::VKEY_F9, 0, ui::VKEY_VOLUME_DOWN, 0},
+          {ui::VKEY_F10, 0, ui::VKEY_VOLUME_UP, 0},
+      };
+      MutableKeyState incoming_without_command = incoming;
+      incoming_without_command.flags &= ~ui::EF_COMMAND_DOWN;
+      rewritten =
+          RewriteWithKeyboardRemappingsByKeyCode(kFkeysToSystemKeys,
+                                                 arraysize(kFkeysToSystemKeys),
+                                                 incoming_without_command,
+                                                 state);
+    } else if (search_is_pressed) {
+      // Allow Search to avoid rewriting F1-F12.
+      state->flags &= ~ui::EF_COMMAND_DOWN;
+      rewritten = true;
+    }
+  }
+
+  if (!rewritten && (incoming.flags & ui::EF_COMMAND_DOWN)) {
+    // Remap Search+<number> to F<number>.
+    // We check the keycode here instead of the keysym, as these keys have
+    // different keysyms when modifiers are pressed, such as shift.
+
+    // TODO(danakj): On some i18n keyboards, these choices will be bad and we
+    // should make layout-specific choices here. For eg. on a french keyboard
+    // "-" and "6" are the same key, so F11 will not be accessible.
+    static const KeyboardRemapping kNumberKeysToFkeys[] = {
+        {ui::VKEY_1, ui::EF_COMMAND_DOWN, ui::VKEY_F1, 0},
+        {ui::VKEY_2, ui::EF_COMMAND_DOWN, ui::VKEY_F2, 0},
+        {ui::VKEY_3, ui::EF_COMMAND_DOWN, ui::VKEY_F3, 0},
+        {ui::VKEY_4, ui::EF_COMMAND_DOWN, ui::VKEY_F4, 0},
+        {ui::VKEY_5, ui::EF_COMMAND_DOWN, ui::VKEY_F5, 0},
+        {ui::VKEY_6, ui::EF_COMMAND_DOWN, ui::VKEY_F6, 0},
+        {ui::VKEY_7, ui::EF_COMMAND_DOWN, ui::VKEY_F7, 0},
+        {ui::VKEY_8, ui::EF_COMMAND_DOWN, ui::VKEY_F8, 0},
+        {ui::VKEY_9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, 0},
+        {ui::VKEY_0, ui::EF_COMMAND_DOWN, ui::VKEY_F10, 0},
+        {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN, ui::VKEY_F11, 0},
+        {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN, ui::VKEY_F12, 0}};
+    rewritten = RewriteWithKeyboardRemappingsByKeyCode(
+        kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state);
+  }
+}
+
+void EventRewriter::RewriteLocatedEvent(const ui::Event& event,
+                                        MutableKeyState* state) {
+  const PrefService* pref_service = GetPrefService();
+  if (!pref_service)
+    return;
+
+  // First, remap modifier masks.
+  state->flags = GetRemappedModifierMasks(*pref_service, event, state->flags);
+
+#if defined(USE_X11)
+  // TODO(kpschoedel): de-X11 with unified device ids from crbug.com/360377
+  XEvent* xevent = event.native_event();
+  if (!xevent || xevent->type != GenericEvent)
+    return;
+  XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data);
+  if (xievent->evtype != XI_ButtonPress && xievent->evtype != XI_ButtonRelease)
+    return;
+
+  // Then, remap Alt+Button1 to Button3.
+  if ((xievent->evtype == XI_ButtonPress ||
+       pressed_device_ids_.count(xievent->sourceid)) &&
+      (xievent->mods.effective & Mod1Mask) && xievent->detail == Button1) {
+    state->flags &= ~(ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON);
+    state->flags |= ui::EF_RIGHT_MOUSE_BUTTON;
+    xievent->mods.effective &= ~Mod1Mask;
+    xievent->detail = Button3;
+    if (xievent->evtype == XI_ButtonRelease) {
+      // On the release clear the left button from the existing state and the
+      // mods, and set the right button.
+      XISetMask(xievent->buttons.mask, Button3);
+      XIClearMask(xievent->buttons.mask, Button1);
+      xievent->mods.effective &= ~Button1Mask;
+      pressed_device_ids_.erase(xievent->sourceid);
+    } else {
+      pressed_device_ids_.insert(xievent->sourceid);
+    }
+  }
+#endif  // defined(USE_X11)
+}
+
+EventRewriter::DeviceType EventRewriter::DeviceAddedInternal(
+    int device_id,
+    const std::string& device_name) {
+  const DeviceType type = GetDeviceType(device_name);
+  if (type == kDeviceAppleKeyboard) {
+    VLOG(1) << "Apple keyboard '" << device_name << "' connected: "
+            << "id=" << device_id;
+  }
+  // Always overwrite the existing device_id since the X server may reuse a
+  // device id for an unattached device.
+  device_id_to_type_[device_id] = type;
+  return type;
+}
+
+#if defined(USE_X11)
 void EventRewriter::WillProcessEvent(const ui::PlatformEvent& event) {
   XEvent* xevent = event;
-  if (xevent->type == KeyPress || xevent->type == KeyRelease) {
-    Rewrite(xevent);
-  } else if (xevent->type == GenericEvent) {
+  if (xevent->type == GenericEvent) {
     XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data);
     if (xievent->evtype == XI_KeyPress || xievent->evtype == XI_KeyRelease) {
       if (xievent->deviceid == xievent->sourceid)
         DeviceKeyPressedOrReleased(xievent->deviceid);
-    } else {
-      RewriteLocatedEvent(xevent);
-    }
-  } else if (xevent->type == MappingNotify) {
-    if (xevent->xmapping.request == MappingModifier ||
-        xevent->xmapping.request == MappingKeyboard) {
-      RefreshKeycodes();
     }
   }
 }
@@ -215,7 +721,8 @@
 void EventRewriter::DidProcessEvent(const ui::PlatformEvent& event) {
 }
 
-void EventRewriter::DeviceHierarchyChanged() {}
+void EventRewriter::DeviceHierarchyChanged() {
+}
 
 void EventRewriter::DeviceAdded(int device_id) {
   DCHECK_NE(XIAllDevices, device_id);
@@ -226,9 +733,8 @@
   }
 
   int ndevices_return = 0;
-  XIDeviceInfo* device_info = XIQueryDevice(gfx::GetXDisplay(),
-                                            device_id,
-                                            &ndevices_return);
+  XIDeviceInfo* device_info =
+      XIQueryDevice(gfx::GetXDisplay(), device_id, &ndevices_return);
 
   // Since |device_id| is neither XIAllDevices nor XIAllMasterDevices,
   // the number of devices found should be either 0 (not found) or 1.
@@ -250,643 +756,6 @@
 void EventRewriter::DeviceRemoved(int device_id) {
   device_id_to_type_.erase(device_id);
 }
-
-void EventRewriter::RefreshKeycodes() {
-  keysym_to_keycode_map_.clear();
-}
-
-KeyCode EventRewriter::NativeKeySymToNativeKeycode(KeySym keysym) {
-  if (keysym_to_keycode_map_.count(keysym))
-    return keysym_to_keycode_map_[keysym];
-
-  XDisplay* display = gfx::GetXDisplay();
-  KeyCode keycode = XKeysymToKeycode(display, keysym);
-  keysym_to_keycode_map_[keysym] = keycode;
-  return keycode;
-}
-
-bool EventRewriter::TopRowKeysAreFunctionKeys(XEvent* event) const {
-  const PrefService* prefs = GetPrefService();
-  if (prefs &&
-      prefs->FindPreference(prefs::kLanguageSendFunctionKeys) &&
-      prefs->GetBoolean(prefs::kLanguageSendFunctionKeys))
-    return true;
-
-  ash::wm::WindowState* state = ash::wm::GetActiveWindowState();
-  return state ? state->top_row_keys_are_function_keys() : false;
-}
-
-bool EventRewriter::RewriteWithKeyboardRemappingsByKeySym(
-    const KeyboardRemapping* remappings,
-    size_t num_remappings,
-    KeySym keysym,
-    unsigned int native_mods,
-    KeySym* remapped_native_keysym,
-    unsigned int* remapped_native_mods) {
-  for (size_t i = 0; i < num_remappings; ++i) {
-    const KeyboardRemapping& map = remappings[i];
-
-    if (keysym != map.input_keysym)
-      continue;
-    unsigned int matched_mods = native_mods & map.input_native_mods;
-    if (matched_mods != map.input_native_mods)
-      continue;
-
-    *remapped_native_keysym = map.output_keysym;
-    *remapped_native_mods = (native_mods & ~map.input_native_mods) |
-                            map.output_native_mods;
-    return true;
-  }
-
-  return false;
-}
-
-bool EventRewriter::RewriteWithKeyboardRemappingsByKeyCode(
-    const KeyboardRemapping* remappings,
-    size_t num_remappings,
-    KeyCode keycode,
-    unsigned int native_mods,
-    KeySym* remapped_native_keysym,
-    unsigned int* remapped_native_mods) {
-  for (size_t i = 0; i < num_remappings; ++i) {
-    const KeyboardRemapping& map = remappings[i];
-
-    KeyCode input_keycode = NativeKeySymToNativeKeycode(map.input_keysym);
-    if (keycode != input_keycode)
-      continue;
-    unsigned int matched_mods = native_mods & map.input_native_mods;
-    if (matched_mods != map.input_native_mods)
-      continue;
-
-    *remapped_native_keysym = map.output_keysym;
-    *remapped_native_mods = (native_mods & ~map.input_native_mods) |
-                            map.output_native_mods;
-    return true;
-  }
-
-  return false;
-}
-
-const PrefService* EventRewriter::GetPrefService() const {
-  if (pref_service_for_testing_)
-    return pref_service_for_testing_;
-  Profile* profile = ProfileManager::GetActiveUserProfile();
-  return profile ? profile->GetPrefs() : NULL;
-}
-
-void EventRewriter::Rewrite(XEvent* event) {
-  // Do not rewrite an event sent by ui_controls::SendKeyPress(). See
-  // crbug.com/136465.
-  if (event->xkey.send_event)
-    return;
-
-  RewriteModifiers(event);
-  RewriteNumPadKeys(event);
-  RewriteExtendedKeys(event);
-  RewriteFunctionKeys(event);
-}
-
-bool EventRewriter::IsAppleKeyboard() const {
-  if (last_device_id_ == kBadDeviceId)
-    return false;
-
-  // Check which device generated |event|.
-  std::map<int, DeviceType>::const_iterator iter =
-      device_id_to_type_.find(last_device_id_);
-  if (iter == device_id_to_type_.end()) {
-    LOG(ERROR) << "Device ID " << last_device_id_ << " is unknown.";
-    return false;
-  }
-
-  const DeviceType type = iter->second;
-  return type == kDeviceAppleKeyboard;
-}
-
-void EventRewriter::GetRemappedModifierMasks(
-    unsigned int original_native_modifiers,
-    unsigned int* remapped_native_modifiers) const {
-  // TODO(glotov): remove the following condition when we do not restart chrome
-  // when user logs in as guest. See Rewrite() for details.
-  if (UserManager::Get()->IsLoggedInAsGuest() &&
-      LoginDisplayHostImpl::default_host()) {
-    return;
-  }
-
-  const PrefService* pref_service = GetPrefService();
-  if (!pref_service)
-    return;
-
-  // When a diamond key is not available, a Mod2Mask should not treated as a
-  // configurable modifier because Mod2Mask may be worked as NumLock mask.
-  // (cf. http://crbug.com/173956)
-  const bool skip_mod2 = !HasDiamondKey();
-  // If Mod3 is used by the current input method, don't allow the CapsLock
-  // pref to remap it, or the keyboard behavior will be broken.
-  const bool skip_mod3 = IsISOLevel5ShiftUsedByCurrentInputMethod();
-
-  for (size_t i = 0; i < arraysize(kModifierFlagToPrefName); ++i) {
-    if ((skip_mod2 && kModifierFlagToPrefName[i].native_modifier == Mod2Mask) ||
-        (skip_mod3 && kModifierFlagToPrefName[i].native_modifier == Mod3Mask)) {
-      continue;
-    }
-    if (original_native_modifiers &
-        kModifierFlagToPrefName[i].native_modifier) {
-      const ModifierRemapping* remapped_key =
-          GetRemappedKey(kModifierFlagToPrefName[i].pref_name, *pref_service);
-      // Rewrite Command-L/R key presses on an Apple keyboard to Control-L/R.
-      if (IsAppleKeyboard() &&
-          (kModifierFlagToPrefName[i].native_modifier == Mod4Mask)) {
-        remapped_key = kModifierRemappingCtrl;
-      }
-      if (remapped_key) {
-        *remapped_native_modifiers |= remapped_key->native_modifier;
-      } else {
-        *remapped_native_modifiers |=
-            kModifierFlagToPrefName[i].native_modifier;
-      }
-    }
-  }
-
-  unsigned int native_mask = Mod4Mask | ControlMask | Mod1Mask;
-  if (!skip_mod2)
-    native_mask |= Mod2Mask;
-  if (!skip_mod3)
-    native_mask |= Mod3Mask;
-  *remapped_native_modifiers =
-      (original_native_modifiers & ~native_mask) |
-      *remapped_native_modifiers;
-}
-
-bool EventRewriter::RewriteModifiers(XEvent* event) {
-  DCHECK(event->type == KeyPress || event->type == KeyRelease);
-  // Do nothing if we have just logged in as guest but have not restarted chrome
-  // process yet (so we are still on the login screen). In this situations we
-  // have no user profile so can not do anything useful.
-  // Note that currently, unlike other accounts, when user logs in as guest, we
-  // restart chrome process. In future this is to be changed.
-  // TODO(glotov): remove the following condition when we do not restart chrome
-  // when user logs in as guest.
-  if (UserManager::Get()->IsLoggedInAsGuest() &&
-      LoginDisplayHostImpl::default_host())
-    return false;
-
-  const PrefService* pref_service = GetPrefService();
-  if (!pref_service)
-    return false;
-
-  DCHECK_EQ(input_method::kControlKey, kModifierRemappingCtrl->remap_to);
-
-  XKeyEvent* xkey = &event->xkey;
-  KeySym keysym = XLookupKeysym(xkey, 0);
-  ui::KeyboardCode original_keycode = ui::KeyboardCodeFromNative(event);
-  ui::KeyboardCode remapped_keycode = original_keycode;
-  KeyCode remapped_native_keycode = xkey->keycode;
-
-  // First, remap |keysym|.
-  const ModifierRemapping* remapped_key = NULL;
-  switch (keysym) {
-    // On Chrome OS, XF86XK_Launch6 (F15) with Mod2Mask is sent when Diamond
-    // key is pressed.
-    case XF86XK_Launch6:
-      // When diamond key is not available, the configuration UI for Diamond
-      // key is not shown. Therefore, ignore the kLanguageRemapDiamondKeyTo
-      // syncable pref.
-      if (HasDiamondKey())
-        remapped_key =
-            GetRemappedKey(prefs::kLanguageRemapDiamondKeyTo, *pref_service);
-      // Default behavior is Ctrl key.
-      if (!remapped_key)
-        remapped_key = kModifierRemappingCtrl;
-      break;
-    // On Chrome OS, XF86XK_Launch7 (F16) with Mod3Mask is sent when Caps Lock
-    // is pressed (with one exception: when
-    // IsISOLevel5ShiftUsedByCurrentInputMethod() is true, the key generates
-    // XK_ISO_Level3_Shift with Mod3Mask, not XF86XK_Launch7).
-    case XF86XK_Launch7:
-      remapped_key =
-          GetRemappedKey(prefs::kLanguageRemapCapsLockKeyTo, *pref_service);
-      break;
-    case XK_Super_L:
-    case XK_Super_R:
-      // Rewrite Command-L/R key presses on an Apple keyboard to Control-L/R.
-      if (IsAppleKeyboard())
-        remapped_key = kModifierRemappingCtrl;
-      else
-        remapped_key =
-            GetRemappedKey(prefs::kLanguageRemapSearchKeyTo, *pref_service);
-      // Default behavior is Super key, hence don't remap the event if the pref
-      // is unavailable.
-      break;
-    case XK_Control_L:
-    case XK_Control_R:
-      remapped_key =
-          GetRemappedKey(prefs::kLanguageRemapControlKeyTo, *pref_service);
-      break;
-    case XK_Alt_L:
-    case XK_Alt_R:
-    case XK_Meta_L:
-    case XK_Meta_R:
-      remapped_key =
-          GetRemappedKey(prefs::kLanguageRemapAltKeyTo, *pref_service);
-      break;
-    default:
-      break;
-  }
-
-  if (remapped_key) {
-    int flags = ui::EventFlagsFromNative(event);
-    remapped_keycode = remapped_key->keycode;
-    const size_t level = ((flags & ui::EF_SHIFT_DOWN) ? (1 << 1) : 0) +
-        (IsRight(keysym) ? (1 << 0) : 0);
-    const KeySym native_keysym = remapped_key->native_keysyms[level];
-    remapped_native_keycode = NativeKeySymToNativeKeycode(native_keysym);
-  }
-
-  // Next, remap modifier bits.
-  unsigned int remapped_native_modifiers = 0U;
-  GetRemappedModifierMasks(xkey->state, &remapped_native_modifiers);
-
-  // Toggle Caps Lock if the remapped key is ui::VKEY_CAPITAL, but do nothing if
-  // the original key is ui::VKEY_CAPITAL (i.e. a Caps Lock key on an external
-  // keyboard is pressed) since X can handle that case.
-  if (event->type == KeyPress &&
-      original_keycode != ui::VKEY_CAPITAL &&
-      remapped_keycode == ui::VKEY_CAPITAL) {
-    input_method::ImeKeyboard* keyboard = keyboard_for_testing_ ?
-        keyboard_for_testing_ :
-        input_method::InputMethodManager::Get()->GetImeKeyboard();
-    keyboard->SetCapsLockEnabled(!keyboard->CapsLockIsEnabled());
-  }
-
-  OverwriteEvent(event, remapped_native_keycode, remapped_native_modifiers);
-  return true;
-}
-
-bool EventRewriter::RewriteNumPadKeys(XEvent* event) {
-  DCHECK(event->type == KeyPress || event->type == KeyRelease);
-  bool rewritten = false;
-  XKeyEvent* xkey = &event->xkey;
-  const KeySym keysym = XLookupKeysym(xkey, 0);
-  switch (keysym) {
-    case XK_KP_Insert:
-      OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_0),
-                     xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    case XK_KP_Delete:
-      OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_Decimal),
-                     xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    case XK_KP_End:
-      OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_1),
-                     xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    case XK_KP_Down:
-      OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_2),
-                     xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    case XK_KP_Next:
-      OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_3),
-                     xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    case XK_KP_Left:
-      OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_4),
-                     xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    case XK_KP_Begin:
-      OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_5),
-                     xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    case XK_KP_Right:
-      OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_6),
-                     xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    case XK_KP_Home:
-      OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_7),
-                     xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    case XK_KP_Up:
-      OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_8),
-                     xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    case XK_KP_Prior:
-      OverwriteEvent(event, NativeKeySymToNativeKeycode(XK_KP_9),
-                     xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    case XK_KP_Divide:
-    case XK_KP_Multiply:
-    case XK_KP_Subtract:
-    case XK_KP_Add:
-    case XK_KP_Enter:
-      // Add Mod2Mask for consistency.
-      OverwriteEvent(event, xkey->keycode, xkey->state | Mod2Mask);
-      rewritten = true;
-      break;
-    default:
-      break;
-  }
-  return rewritten;
-}
-
-bool EventRewriter::RewriteExtendedKeys(XEvent* event) {
-  DCHECK(event->type == KeyPress || event->type == KeyRelease);
-  XKeyEvent* xkey = &event->xkey;
-  const KeySym keysym = XLookupKeysym(xkey, 0);
-
-  KeySym remapped_native_keysym = 0;
-  unsigned int remapped_native_mods = 0;
-  bool rewritten = false;
-
-  if (xkey->state & Mod4Mask) {
-    // Allow Search to avoid rewriting extended keys.
-    static const KeyboardRemapping kAvoidRemappings[] = {
-      { // Alt+Backspace
-        XK_BackSpace, Mod1Mask | Mod4Mask,
-        XK_BackSpace, Mod1Mask,
-      },
-      { // Control+Alt+Up
-        XK_Up, Mod1Mask | ControlMask | Mod4Mask,
-        XK_Up, Mod1Mask | ControlMask,
-      },
-      { // Alt+Up
-        XK_Up, Mod1Mask | Mod4Mask,
-        XK_Up, Mod1Mask,
-      },
-      { // Control+Alt+Down
-        XK_Down, Mod1Mask | ControlMask | Mod4Mask,
-        XK_Down, Mod1Mask | ControlMask,
-      },
-      { // Alt+Down
-        XK_Down, Mod1Mask | Mod4Mask,
-        XK_Down, Mod1Mask,
-      }
-    };
-
-    rewritten = RewriteWithKeyboardRemappingsByKeySym(
-        kAvoidRemappings,
-        arraysize(kAvoidRemappings),
-        keysym,
-        xkey->state,
-        &remapped_native_keysym,
-        &remapped_native_mods);
-  }
-
-  if (!rewritten) {
-    static const KeyboardRemapping kSearchRemappings[] = {
-      { // Search+BackSpace -> Delete
-        XK_BackSpace, Mod4Mask,
-        XK_Delete, 0
-      },
-      { // Search+Left -> Home
-        XK_Left, Mod4Mask,
-        XK_Home, 0
-      },
-      { // Search+Up -> Prior (aka PageUp)
-        XK_Up, Mod4Mask,
-        XK_Prior, 0
-      },
-      { // Search+Right -> End
-        XK_Right, Mod4Mask,
-        XK_End, 0
-      },
-      { // Search+Down -> Next (aka PageDown)
-        XK_Down, Mod4Mask,
-        XK_Next, 0
-      },
-      { // Search+Period -> Insert
-        XK_period, Mod4Mask,
-        XK_Insert, 0
-      }
-    };
-
-    rewritten = RewriteWithKeyboardRemappingsByKeySym(
-        kSearchRemappings,
-        arraysize(kSearchRemappings),
-        keysym,
-        xkey->state,
-        &remapped_native_keysym,
-        &remapped_native_mods);
-  }
-
-  if (!rewritten) {
-    static const KeyboardRemapping kNonSearchRemappings[] = {
-      { // Alt+BackSpace -> Delete
-        XK_BackSpace, Mod1Mask,
-        XK_Delete, 0
-      },
-      { // Control+Alt+Up -> Home
-        XK_Up, Mod1Mask | ControlMask,
-        XK_Home, 0
-      },
-      { // Alt+Up -> Prior (aka PageUp)
-        XK_Up, Mod1Mask,
-        XK_Prior, 0
-      },
-      { // Control+Alt+Down -> End
-        XK_Down, Mod1Mask | ControlMask,
-        XK_End, 0
-      },
-      { // Alt+Down -> Next (aka PageDown)
-        XK_Down, Mod1Mask,
-        XK_Next, 0
-      }
-    };
-
-    rewritten = RewriteWithKeyboardRemappingsByKeySym(
-        kNonSearchRemappings,
-        arraysize(kNonSearchRemappings),
-        keysym,
-        xkey->state,
-        &remapped_native_keysym,
-        &remapped_native_mods);
-  }
-
-  if (!rewritten)
-    return false;
-
-  OverwriteEvent(event,
-                 NativeKeySymToNativeKeycode(remapped_native_keysym),
-                 remapped_native_mods);
-  return true;
-}
-
-bool EventRewriter::RewriteFunctionKeys(XEvent* event) {
-  DCHECK(event->type == KeyPress || event->type == KeyRelease);
-  XKeyEvent* xkey = &event->xkey;
-  const KeySym keysym = XLookupKeysym(xkey, 0);
-
-  KeySym remapped_native_keysym = 0;
-  unsigned int remapped_native_mods = 0;
-  bool rewritten = false;
-
-  // By default the top row (F1-F12) keys are special keys for back, forward,
-  // brightness, volume, etc. However, windows for v2 apps can optionally
-  // request raw function keys for these keys.
-  bool top_row_keys_are_special_keys = !TopRowKeysAreFunctionKeys(event);
-
-  if ((xkey->state & Mod4Mask) && top_row_keys_are_special_keys) {
-    // Allow Search to avoid rewriting F1-F12.
-    static const KeyboardRemapping kFkeysToFkeys[] = {
-      { XK_F1, Mod4Mask, XK_F1, },
-      { XK_F2, Mod4Mask, XK_F2, },
-      { XK_F3, Mod4Mask, XK_F3, },
-      { XK_F4, Mod4Mask, XK_F4, },
-      { XK_F5, Mod4Mask, XK_F5, },
-      { XK_F6, Mod4Mask, XK_F6, },
-      { XK_F7, Mod4Mask, XK_F7, },
-      { XK_F8, Mod4Mask, XK_F8, },
-      { XK_F9, Mod4Mask, XK_F9, },
-      { XK_F10, Mod4Mask, XK_F10, },
-      { XK_F11, Mod4Mask, XK_F11, },
-      { XK_F12, Mod4Mask, XK_F12, },
-    };
-
-    rewritten = RewriteWithKeyboardRemappingsByKeySym(
-        kFkeysToFkeys,
-        arraysize(kFkeysToFkeys),
-        keysym,
-        xkey->state,
-        &remapped_native_keysym,
-        &remapped_native_mods);
-  }
-
-  if (!rewritten) {
-    static const KeyboardRemapping kFkeysToSpecialKeys[] = {
-      { XK_F1, 0, XF86XK_Back, 0 },
-      { XK_F2, 0, XF86XK_Forward, 0 },
-      { XK_F3, 0, XF86XK_Reload, 0 },
-      { XK_F4, 0, XF86XK_LaunchB, 0 },
-      { XK_F5, 0, XF86XK_LaunchA, 0 },
-      { XK_F6, 0, XF86XK_MonBrightnessDown, 0 },
-      { XK_F7, 0, XF86XK_MonBrightnessUp, 0 },
-      { XK_F8, 0, XF86XK_AudioMute, 0 },
-      { XK_F9, 0, XF86XK_AudioLowerVolume, 0 },
-      { XK_F10, 0, XF86XK_AudioRaiseVolume, 0 },
-    };
-
-    if (top_row_keys_are_special_keys) {
-      // Rewrite the F1-F12 keys on a Chromebook keyboard to special keys.
-      rewritten = RewriteWithKeyboardRemappingsByKeySym(
-          kFkeysToSpecialKeys,
-          arraysize(kFkeysToSpecialKeys),
-          keysym,
-          xkey->state,
-          &remapped_native_keysym,
-          &remapped_native_mods);
-    } else if (xkey->state & Mod4Mask) {
-      // Use Search + F1-F12 for the special keys.
-      rewritten = RewriteWithKeyboardRemappingsByKeySym(
-          kFkeysToSpecialKeys,
-          arraysize(kFkeysToSpecialKeys),
-          keysym,
-          xkey->state & ~Mod4Mask,
-          &remapped_native_keysym,
-          &remapped_native_mods);
-    }
-  }
-
-  if (!rewritten && (xkey->state & Mod4Mask)) {
-    // Remap Search+<number> to F<number>.
-    // We check the keycode here instead of the keysym, as these keys have
-    // different keysyms when modifiers are pressed, such as shift.
-
-    // TODO(danakj): On some i18n keyboards, these choices will be bad and we
-    // should make layout-specific choices here. For eg. on a french keyboard
-    // "-" and "6" are the same key, so F11 will not be accessible.
-    static const KeyboardRemapping kNumberKeysToFkeys[] = {
-      { XK_1, Mod4Mask, XK_F1, 0 },
-      { XK_2, Mod4Mask, XK_F2, 0 },
-      { XK_3, Mod4Mask, XK_F3, 0 },
-      { XK_4, Mod4Mask, XK_F4, 0 },
-      { XK_5, Mod4Mask, XK_F5, 0 },
-      { XK_6, Mod4Mask, XK_F6, 0 },
-      { XK_7, Mod4Mask, XK_F7, 0 },
-      { XK_8, Mod4Mask, XK_F8, 0 },
-      { XK_9, Mod4Mask, XK_F9, 0 },
-      { XK_0, Mod4Mask, XK_F10, 0 },
-      { XK_minus, Mod4Mask, XK_F11, 0 },
-      { XK_equal, Mod4Mask, XK_F12, 0 }
-    };
-
-    rewritten = RewriteWithKeyboardRemappingsByKeyCode(
-        kNumberKeysToFkeys,
-        arraysize(kNumberKeysToFkeys),
-        xkey->keycode,
-        xkey->state,
-        &remapped_native_keysym,
-        &remapped_native_mods);
-  }
-
-  if (!rewritten)
-    return false;
-
-  OverwriteEvent(event,
-                 NativeKeySymToNativeKeycode(remapped_native_keysym),
-                 remapped_native_mods);
-  return true;
-}
-
-void EventRewriter::RewriteLocatedEvent(XEvent* event) {
-  DCHECK_EQ(GenericEvent, event->type);
-  XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(event->xcookie.data);
-  if (xievent->evtype != XI_ButtonPress && xievent->evtype != XI_ButtonRelease)
-    return;
-
-  // First, remap modifier masks.
-  unsigned int remapped_native_modifiers = 0U;
-  GetRemappedModifierMasks(xievent->mods.effective, &remapped_native_modifiers);
-  xievent->mods.effective = remapped_native_modifiers;
-
-  // Then, remap Alt+Button1 to Button3.
-  if ((xievent->evtype == XI_ButtonPress ||
-       pressed_device_ids_.count(xievent->sourceid)) &&
-      (xievent->mods.effective & Mod1Mask) && xievent->detail == Button1) {
-    xievent->mods.effective &= ~Mod1Mask;
-    xievent->detail = Button3;
-    if (xievent->evtype == XI_ButtonRelease) {
-      // On the release clear the left button from the existing state and the
-      // mods, and set the right button.
-      XISetMask(xievent->buttons.mask, Button3);
-      XIClearMask(xievent->buttons.mask, Button1);
-      xievent->mods.effective &= ~Button1Mask;
-      pressed_device_ids_.erase(xievent->sourceid);
-    } else {
-      pressed_device_ids_.insert(xievent->sourceid);
-    }
-  }
-}
-
-void EventRewriter::OverwriteEvent(XEvent* event,
-                                   unsigned int new_native_keycode,
-                                   unsigned int new_native_state) {
-  DCHECK(event->type == KeyPress || event->type == KeyRelease);
-  XKeyEvent* xkey = &event->xkey;
-  xkey->keycode = new_native_keycode;
-  xkey->state = new_native_state;
-}
-
-EventRewriter::DeviceType EventRewriter::DeviceAddedInternal(
-    int device_id,
-    const std::string& device_name) {
-  const DeviceType type = EventRewriter::GetDeviceType(device_name);
-  if (type == kDeviceAppleKeyboard) {
-    VLOG(1) << "Apple keyboard '" << device_name << "' connected: "
-            << "id=" << device_id;
-  }
-  // Always overwrite the existing device_id since the X server may reuse a
-  // device id for an unattached device.
-  device_id_to_type_[device_id] = type;
-  return type;
-}
+#endif
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/events/event_rewriter.h b/chrome/browser/chromeos/events/event_rewriter.h
index c25d7b9..d389d8c 100644
--- a/chrome/browser/chromeos/events/event_rewriter.h
+++ b/chrome/browser/chromeos/events/event_rewriter.h
@@ -9,25 +9,42 @@
 #include <set>
 #include <string>
 
-#include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "base/containers/hash_tables.h"
 #include "base/memory/scoped_ptr.h"
+#include "ui/events/event.h"
+#include "ui/events/event_rewriter.h"
+
+#if defined(USE_X11)
 #include "chrome/browser/chromeos/device_hierarchy_observer.h"
-#include "chromeos/ime/ime_keyboard.h"
-#include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/events/platform/platform_event_observer.h"
+typedef union _XEvent XEvent;
+#endif
 
 class PrefService;
-typedef union _XEvent XEvent;
 
 namespace chromeos {
 namespace input_method {
 class ImeKeyboard;
 }
 
-class EventRewriter : public DeviceHierarchyObserver,
-                      public ui::PlatformEventObserver {
+// EventRewriter makes various changes to keyboard-related events,
+// including KeyEvents and some other events with keyboard modifier flags:
+// - maps modifiers keys (Control, Alt, Search, Caps, Diamond) according
+//   to user preferences;
+// - maps Command to Control on Apple keyboards;
+// - converts numeric pad editing keys to their numeric forms;
+// - converts top-row function keys to special keys where necessary;
+// - handles various key combinations like Search+Backspace -> Delete
+//   and Search+number to Fnumber;
+// - handles key/pointer combinations like Alt+Button1 -> Button3.
+class EventRewriter
+    :
+#if defined(USE_X11)
+      public DeviceHierarchyObserver,
+      public ui::PlatformEventObserver,
+#endif
+      public ui::EventRewriter {
  public:
   enum DeviceType {
     kDeviceUnknown = 0,
@@ -40,31 +57,36 @@
   // Calls DeviceAddedInternal.
   DeviceType DeviceAddedForTesting(int device_id,
                                    const std::string& device_name);
-  // Calls Rewrite.
-  void RewriteForTesting(XEvent* event);
 
+  // Calls RewriteLocatedEvent().
+  void RewriteLocatedEventForTesting(const ui::Event& event, int* flags);
+
+#if defined(USE_X11)
   const std::map<int, DeviceType>& device_id_to_type_for_testing() const {
     return device_id_to_type_;
   }
+#endif
+
   void set_last_device_id_for_testing(int device_id) {
     last_device_id_ = device_id;
   }
   void set_pref_service_for_testing(const PrefService* pref_service) {
     pref_service_for_testing_ = pref_service;
   }
-  void set_keyboard_for_testing(input_method::ImeKeyboard* keyboard) {
-    keyboard_for_testing_ = keyboard;
+  void set_ime_keyboard_for_testing(
+      chromeos::input_method::ImeKeyboard* ime_keyboard) {
+    ime_keyboard_for_testing_ = ime_keyboard;
   }
 
-  // Gets DeviceType from the |device_name|.
-  static DeviceType GetDeviceType(const std::string& device_name);
+  // EventRewriter overrides:
+  virtual ui::EventRewriteStatus RewriteEvent(
+      const ui::Event& event,
+      scoped_ptr<ui::Event>* rewritten_event) OVERRIDE;
+  virtual ui::EventRewriteStatus NextDispatchEvent(
+      const ui::Event& last_event,
+      scoped_ptr<ui::Event>* new_event) OVERRIDE;
 
- private:
-  friend class EventRewriterAshTest;
-  friend class EventRewriterTest;
-
-  void DeviceKeyPressedOrReleased(int device_id);
-
+#if defined(USE_X11)
   // ui::PlatformEventObserver:
   virtual void WillProcessEvent(const ui::PlatformEvent& event) OVERRIDE;
   virtual void DidProcessEvent(const ui::PlatformEvent& event) OVERRIDE;
@@ -73,102 +95,30 @@
   virtual void DeviceHierarchyChanged() OVERRIDE;
   virtual void DeviceAdded(int device_id) OVERRIDE;
   virtual void DeviceRemoved(int device_id) OVERRIDE;
+#endif
 
-  // We don't want to include Xlib.h here since it has polluting macros, so
-  // define these locally.
-  typedef unsigned long KeySym;
-  typedef unsigned char KeyCode;
-
-  // Updates |*_xkeycode_| in response to a keyboard map change.
-  void RefreshKeycodes();
-  // Converts an X key symbol like XK_Control_L to a key code.
-  unsigned char NativeKeySymToNativeKeycode(KeySym keysym);
-
-  struct KeyboardRemapping {
-    KeySym input_keysym;
-    unsigned int input_native_mods;
-    KeySym output_keysym;
-    unsigned int output_native_mods;
+ private:
+  // Things that internal rewriter phases can change about an Event.
+  struct MutableKeyState {
+    int flags;
+    ui::KeyboardCode key_code;
   };
 
-  // Returns true if the target for |event| would prefer to receive raw function
-  // keys instead of having them rewritten into back, forward, brightness,
-  // volume, etc. or if the user has specified that they desire top-row keys to
-  // be treated as function keys globally.
-  bool TopRowKeysAreFunctionKeys(XEvent* event) const;
+  // Tables of direct remappings for |RewriteWithKeyboardRemappingsByKeyCode()|.
+  struct KeyboardRemapping {
+    ui::KeyboardCode input_key_code;
+    int input_flags;
+    ui::KeyboardCode output_key_code;
+    int output_flags;
+  };
 
-  // Given a set of KeyboardRemapping structs, it finds a matching struct
-  // if possible, and updates the remapped event values. Returns true if a
-  // remapping was found and remapped values were updated.
-  bool RewriteWithKeyboardRemappingsByKeySym(
-      const KeyboardRemapping* remappings,
-      size_t num_remappings,
-      KeySym keysym,
-      unsigned int native_mods,
-      KeySym* remapped_native_keysym,
-      unsigned int* remapped_native_mods);
-
-  // Given a set of KeyboardRemapping structs, it finds a matching struct
-  // if possible, and updates the remapped event values. This function converts
-  // the KeySym in the KeyboardRemapping struct into the KeyCode before matching
-  // to allow any KeyCode on the same physical key as the given KeySym to match.
-  // Returns true if a remapping was found and remapped values were updated.
-  bool RewriteWithKeyboardRemappingsByKeyCode(
-      const KeyboardRemapping* remappings,
-      size_t num_remappings,
-      KeyCode keycode,
-      unsigned int native_mods,
-      KeySym* remapped_native_keysym,
-      unsigned int* remapped_native_mods);
+#if defined(USE_X11)
+  void DeviceKeyPressedOrReleased(int device_id);
+#endif
 
   // Returns the PrefService that should be used.
   const PrefService* GetPrefService() const;
 
-  // Rewrites the |event| by applying all RewriteXXX functions as needed.
-  void Rewrite(XEvent* event);
-
-  // Rewrites a modifier key press/release following the current user
-  // preferences.
-  bool RewriteModifiers(XEvent* event);
-
-  // Rewrites Fn key press/release to Control. In some cases, Fn key is not
-  // intercepted by the EC, but generates a key event like "XK_F15 + Mod3Mask"
-  // as shown in crosbug.com/p/14339.
-  bool RewriteFnKey(XEvent* event);
-
-  // Rewrites a NumPad key press/release without Num Lock to a corresponding key
-  // press/release with the lock.  Returns true when |event| is rewritten.
-  bool RewriteNumPadKeys(XEvent* event);
-
-  // Rewrites Backspace and Arrow keys following the Chrome OS keyboard spec.
-  //  * Alt+Backspace -> Delete
-  //  * Alt+Up -> Prior (aka PageUp)
-  //  * Alt+Down -> Next (aka PageDown)
-  //  * Ctrl+Alt+Up -> Home
-  //  * Ctrl+Alt+Down -> End
-  // When the Search key acts as a function key, it instead maps:
-  //  * Search+Backspace -> Delete
-  //  * Search+Up -> Prior (aka PageUp)
-  //  * Search+Down -> Next (aka PageDown)
-  //  * Search+Left -> Home
-  //  * Search+Right -> End
-  //  * Search+. -> Insert
-  // Returns true when the |event| is rewritten.
-  bool RewriteExtendedKeys(XEvent* event);
-
-  // When the Search key acts as a function key, it remaps Search+1
-  // through Search+= to F1 through F12. Returns true when the |event| is
-  // rewritten.
-  bool RewriteFunctionKeys(XEvent* event);
-
-  // Rewrites the located |event|.
-  void RewriteLocatedEvent(XEvent* event);
-
-  // Overwrites |event| with the keycodes and flags.
-  void OverwriteEvent(XEvent* event,
-                      unsigned int new_native_keycode,
-                      unsigned int new_native_state);
-
   // Checks the type of the |device_name|, and inserts a new entry to
   // |device_id_to_type_|.
   DeviceType DeviceAddedInternal(int device_id, const std::string& device_name);
@@ -176,22 +126,42 @@
   // Returns true if |last_device_id_| is Apple's.
   bool IsAppleKeyboard() const;
 
-  // Remaps |original_native_modifiers| to |remapped_native_modifiers| following
-  // the current user prefs.
-  void GetRemappedModifierMasks(unsigned int original_native_modifiers,
-                                unsigned int* remapped_native_modifiers) const;
+  // Returns true if the target for |event| would prefer to receive raw function
+  // keys instead of having them rewritten into back, forward, brightness,
+  // volume, etc. or if the user has specified that they desire top-row keys to
+  // be treated as function keys globally.
+  bool TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const;
 
-  std::map<int, DeviceType> device_id_to_type_;
-  int last_device_id_;
+  // Given modifier flags |original_flags|, returns the remapped modifiers
+  // according to user preferences and/or event properties.
+  int GetRemappedModifierMasks(const PrefService& pref_service,
+                               const ui::Event& event,
+                               int original_flags) const;
 
-  // A mapping from X11 KeySym keys to KeyCode values.
-  base::hash_map<unsigned long, unsigned long> keysym_to_keycode_map_;
+  // Given a set of KeyboardRemapping structs, it finds a matching struct
+  // if possible, and updates the remapped event values. Returns true if a
+  // remapping was found and remapped values were updated.
+  bool RewriteWithKeyboardRemappingsByKeyCode(
+      const KeyboardRemapping* remappings,
+      size_t num_remappings,
+      const MutableKeyState& input,
+      MutableKeyState* remapped_state);
+
+  // Rewriter phases. These can inspect the original |event|, but operate using
+  // the current |state|, which may have been modified by previous phases.
+  void RewriteModifierKeys(const ui::KeyEvent& event, MutableKeyState* state);
+  void RewriteNumPadKeys(const ui::KeyEvent& event, MutableKeyState* state);
+  void RewriteExtendedKeys(const ui::KeyEvent& event, MutableKeyState* state);
+  void RewriteFunctionKeys(const ui::KeyEvent& event, MutableKeyState* state);
+  void RewriteLocatedEvent(const ui::Event& event, MutableKeyState* state);
 
   // A set of device IDs whose press event has been rewritten.
   std::set<int> pressed_device_ids_;
 
-  input_method::ImeKeyboard* keyboard_for_testing_;
+  std::map<int, DeviceType> device_id_to_type_;
+  int last_device_id_;
 
+  chromeos::input_method::ImeKeyboard* ime_keyboard_for_testing_;
   const PrefService* pref_service_for_testing_;
 
   DISALLOW_COPY_AND_ASSIGN(EventRewriter);
diff --git a/chrome/browser/chromeos/events/event_rewriter_unittest.cc b/chrome/browser/chromeos/events/event_rewriter_unittest.cc
index 6692cb1..3c6ce72 100644
--- a/chrome/browser/chromeos/events/event_rewriter_unittest.cc
+++ b/chrome/browser/chromeos/events/event_rewriter_unittest.cc
@@ -11,6 +11,8 @@
 #undef None
 #undef RootWindow
 
+#include <vector>
+
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/window_state.h"
 #include "base/basictypes.h"
@@ -29,40 +31,57 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/aura/window.h"
 #include "ui/events/event.h"
+#include "ui/events/event_rewriter.h"
 #include "ui/events/test/events_test_utils_x11.h"
 #include "ui/events/x/touch_factory_x11.h"
 #include "ui/gfx/x/x11_types.h"
 
 namespace {
 
+std::string GetKeyEventAsString(const ui::KeyEvent& keyevent) {
+  return base::StringPrintf("ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
+                            keyevent.key_code(),
+                            keyevent.flags(),
+                            keyevent.type());
+}
+
 std::string GetRewrittenEventAsString(chromeos::EventRewriter* rewriter,
                                       ui::KeyboardCode ui_keycode,
                                       int ui_flags,
-                                      ui::EventType ui_type,
-                                      KeyCode x_keycode,
-                                      unsigned int x_state) {
-  ui::ScopedXI2Event xev;
-  xev.InitKeyEvent(ui_type, ui_keycode, ui_flags);
-  XEvent* xevent = xev;
-  xevent->xkey.keycode = x_keycode;
-  xevent->xkey.state = x_state;
-  rewriter->RewriteForTesting(xevent);
-  ui::KeyEvent keyevent(xevent, false /* is_char */);
-  return base::StringPrintf(
-      "ui_keycode=%d ui_flags=%d ui_type=%d x_keycode=%u x_state=%u x_type=%d",
-      keyevent.key_code(), keyevent.flags(), keyevent.type(),
-      xevent->xkey.keycode, xevent->xkey.state, xevent->xkey.type);
+                                      ui::EventType ui_type) {
+  const ui::KeyEvent event(ui_type, ui_keycode, ui_flags, false);
+  scoped_ptr<ui::Event> new_event;
+  rewriter->RewriteEvent(event, &new_event);
+  if (new_event)
+    return GetKeyEventAsString(
+        static_cast<const ui::KeyEvent&>(*new_event.get()));
+  return GetKeyEventAsString(event);
 }
 
 std::string GetExpectedResultAsString(ui::KeyboardCode ui_keycode,
                                       int ui_flags,
-                                      ui::EventType ui_type,
-                                      KeyCode x_keycode,
-                                      unsigned int x_state,
-                                      int x_type) {
-  return base::StringPrintf(
-      "ui_keycode=%d ui_flags=%d ui_type=%d x_keycode=%u x_state=%u x_type=%d",
-      ui_keycode, ui_flags, ui_type, x_keycode, x_state, x_type);
+                                      ui::EventType ui_type) {
+  return base::StringPrintf("ui_keycode=0x%X ui_flags=0x%X ui_type=%d",
+                            ui_keycode,
+                            ui_flags,
+                            ui_type);
+}
+
+std::string GetRewrittenEventNumbered(size_t i,
+                                      chromeos::EventRewriter* rewriter,
+                                      ui::KeyboardCode ui_keycode,
+                                      int ui_flags,
+                                      ui::EventType ui_type) {
+  return base::StringPrintf("(%zu) ", i) +
+         GetRewrittenEventAsString(rewriter, ui_keycode, ui_flags, ui_type);
+}
+
+std::string GetExpectedResultNumbered(size_t i,
+                                      ui::KeyboardCode ui_keycode,
+                                      int ui_flags,
+                                      ui::EventType ui_type) {
+  return base::StringPrintf("(%zu) ", i) +
+         GetExpectedResultAsString(ui_keycode, ui_flags, ui_type);
 }
 
 }  // namespace
@@ -73,94 +92,6 @@
  public:
   EventRewriterTest()
       : display_(gfx::GetXDisplay()),
-        keycode_a_(XKeysymToKeycode(display_, XK_a)),
-        keycode_alt_l_(XKeysymToKeycode(display_, XK_Alt_L)),
-        keycode_alt_r_(XKeysymToKeycode(display_, XK_Alt_R)),
-        keycode_b_(XKeysymToKeycode(display_, XK_B)),
-        keycode_caps_lock_(XKeysymToKeycode(display_, XK_Caps_Lock)),
-        keycode_control_l_(XKeysymToKeycode(display_, XK_Control_L)),
-        keycode_control_r_(XKeysymToKeycode(display_, XK_Control_R)),
-        keycode_meta_l_(XKeysymToKeycode(display_, XK_Meta_L)),
-        keycode_meta_r_(XKeysymToKeycode(display_, XK_Meta_R)),
-        keycode_num_pad_0_(XKeysymToKeycode(display_, XK_KP_0)),
-        keycode_num_pad_1_(XKeysymToKeycode(display_, XK_KP_1)),
-        keycode_num_pad_2_(XKeysymToKeycode(display_, XK_KP_2)),
-        keycode_num_pad_3_(XKeysymToKeycode(display_, XK_KP_3)),
-        keycode_num_pad_4_(XKeysymToKeycode(display_, XK_KP_4)),
-        keycode_num_pad_5_(XKeysymToKeycode(display_, XK_KP_5)),
-        keycode_num_pad_6_(XKeysymToKeycode(display_, XK_KP_6)),
-        keycode_num_pad_7_(XKeysymToKeycode(display_, XK_KP_7)),
-        keycode_num_pad_8_(XKeysymToKeycode(display_, XK_KP_8)),
-        keycode_num_pad_9_(XKeysymToKeycode(display_, XK_KP_9)),
-        keycode_num_pad_begin_(XKeysymToKeycode(display_, XK_KP_Begin)),
-        keycode_num_pad_decimal_(XKeysymToKeycode(display_, XK_KP_Decimal)),
-        keycode_num_pad_delete_(XKeysymToKeycode(display_, XK_KP_Delete)),
-        keycode_num_pad_down_(XKeysymToKeycode(display_, XK_KP_Down)),
-        keycode_num_pad_end_(XKeysymToKeycode(display_, XK_KP_End)),
-        keycode_num_pad_home_(XKeysymToKeycode(display_, XK_KP_Home)),
-        keycode_num_pad_insert_(XKeysymToKeycode(display_, XK_KP_Insert)),
-        keycode_num_pad_left_(XKeysymToKeycode(display_, XK_KP_Left)),
-        keycode_num_pad_next_(XKeysymToKeycode(display_, XK_KP_Next)),
-        keycode_num_pad_prior_(XKeysymToKeycode(display_, XK_KP_Prior)),
-        keycode_num_pad_right_(XKeysymToKeycode(display_, XK_KP_Right)),
-        keycode_num_pad_up_(XKeysymToKeycode(display_, XK_KP_Up)),
-        keycode_super_l_(XKeysymToKeycode(display_, XK_Super_L)),
-        keycode_super_r_(XKeysymToKeycode(display_, XK_Super_R)),
-        keycode_void_symbol_(XKeysymToKeycode(display_, XK_VoidSymbol)),
-        keycode_delete_(XKeysymToKeycode(display_, XK_Delete)),
-        keycode_backspace_(XKeysymToKeycode(display_, XK_BackSpace)),
-        keycode_up_(XKeysymToKeycode(display_, XK_Up)),
-        keycode_down_(XKeysymToKeycode(display_, XK_Down)),
-        keycode_left_(XKeysymToKeycode(display_, XK_Left)),
-        keycode_right_(XKeysymToKeycode(display_, XK_Right)),
-        keycode_prior_(XKeysymToKeycode(display_, XK_Prior)),
-        keycode_next_(XKeysymToKeycode(display_, XK_Next)),
-        keycode_home_(XKeysymToKeycode(display_, XK_Home)),
-        keycode_end_(XKeysymToKeycode(display_, XK_End)),
-        keycode_escape_(XKeysymToKeycode(display_, XK_Escape)),
-        keycode_launch6_(XKeysymToKeycode(display_, XF86XK_Launch6)),
-        keycode_launch7_(XKeysymToKeycode(display_, XF86XK_Launch7)),
-        keycode_f1_(XKeysymToKeycode(display_, XK_F1)),
-        keycode_f2_(XKeysymToKeycode(display_, XK_F2)),
-        keycode_f3_(XKeysymToKeycode(display_, XK_F3)),
-        keycode_f4_(XKeysymToKeycode(display_, XK_F4)),
-        keycode_f5_(XKeysymToKeycode(display_, XK_F5)),
-        keycode_f6_(XKeysymToKeycode(display_, XK_F6)),
-        keycode_f7_(XKeysymToKeycode(display_, XK_F7)),
-        keycode_f8_(XKeysymToKeycode(display_, XK_F8)),
-        keycode_f9_(XKeysymToKeycode(display_, XK_F9)),
-        keycode_f10_(XKeysymToKeycode(display_, XK_F10)),
-        keycode_f11_(XKeysymToKeycode(display_, XK_F11)),
-        keycode_f12_(XKeysymToKeycode(display_, XK_F12)),
-        keycode_browser_back_(XKeysymToKeycode(display_, XF86XK_Back)),
-        keycode_browser_forward_(XKeysymToKeycode(display_, XF86XK_Forward)),
-        keycode_browser_refresh_(XKeysymToKeycode(display_, XF86XK_Reload)),
-        keycode_media_launch_app1_(XKeysymToKeycode(display_, XF86XK_LaunchA)),
-        keycode_media_launch_app2_(XKeysymToKeycode(display_, XF86XK_LaunchB)),
-        keycode_brightness_down_(XKeysymToKeycode(
-            display_, XF86XK_MonBrightnessDown)),
-        keycode_brightness_up_(XKeysymToKeycode(
-            display_, XF86XK_MonBrightnessUp)),
-        keycode_volume_mute_(XKeysymToKeycode(display_, XF86XK_AudioMute)),
-        keycode_volume_down_(XKeysymToKeycode(
-            display_, XF86XK_AudioLowerVolume)),
-        keycode_volume_up_(XKeysymToKeycode(
-            display_, XF86XK_AudioRaiseVolume)),
-        keycode_power_(XKeysymToKeycode(display_, XF86XK_PowerOff)),
-        keycode_1_(XKeysymToKeycode(display_, XK_1)),
-        keycode_2_(XKeysymToKeycode(display_, XK_2)),
-        keycode_3_(XKeysymToKeycode(display_, XK_3)),
-        keycode_4_(XKeysymToKeycode(display_, XK_4)),
-        keycode_5_(XKeysymToKeycode(display_, XK_5)),
-        keycode_6_(XKeysymToKeycode(display_, XK_6)),
-        keycode_7_(XKeysymToKeycode(display_, XK_7)),
-        keycode_8_(XKeysymToKeycode(display_, XK_8)),
-        keycode_9_(XKeysymToKeycode(display_, XK_9)),
-        keycode_0_(XKeysymToKeycode(display_, XK_0)),
-        keycode_minus_(XKeysymToKeycode(display_, XK_minus)),
-        keycode_equal_(XKeysymToKeycode(display_, XK_equal)),
-        keycode_period_(XKeysymToKeycode(display_, XK_period)),
-        keycode_insert_(XKeysymToKeycode(display_, XK_Insert)),
         mock_user_manager_(new chromeos::MockUserManager),
         user_manager_enabler_(mock_user_manager_),
         input_method_manager_mock_(NULL) {
@@ -189,156 +120,19 @@
   void TestRewriteNumPadKeys();
   void TestRewriteNumPadKeysOnAppleKeyboard();
 
-  void RewriteMouseEvent(EventRewriter* rewriter,
-                         ui::MouseEvent* event) {
-    XEvent* xevent = event->native_event();
-    rewriter->RewriteLocatedEvent(xevent);
-    *event = ui::MouseEvent(xevent);
+  int RewriteMouseEvent(chromeos::EventRewriter* rewriter,
+                        const ui::MouseEvent& event) {
+    int flags = event.flags();
+    rewriter->RewriteLocatedEventForTesting(event, &flags);
+    return flags;
   }
 
   Display* display_;
-  const KeyCode keycode_a_;
-  const KeyCode keycode_alt_l_;
-  const KeyCode keycode_alt_r_;
-  const KeyCode keycode_b_;
-  const KeyCode keycode_caps_lock_;
-  const KeyCode keycode_control_l_;
-  const KeyCode keycode_control_r_;
-  const KeyCode keycode_meta_l_;
-  const KeyCode keycode_meta_r_;
-  const KeyCode keycode_num_pad_0_;
-  const KeyCode keycode_num_pad_1_;
-  const KeyCode keycode_num_pad_2_;
-  const KeyCode keycode_num_pad_3_;
-  const KeyCode keycode_num_pad_4_;
-  const KeyCode keycode_num_pad_5_;
-  const KeyCode keycode_num_pad_6_;
-  const KeyCode keycode_num_pad_7_;
-  const KeyCode keycode_num_pad_8_;
-  const KeyCode keycode_num_pad_9_;
-  const KeyCode keycode_num_pad_begin_;
-  const KeyCode keycode_num_pad_decimal_;
-  const KeyCode keycode_num_pad_delete_;
-  const KeyCode keycode_num_pad_down_;
-  const KeyCode keycode_num_pad_end_;
-  const KeyCode keycode_num_pad_home_;
-  const KeyCode keycode_num_pad_insert_;
-  const KeyCode keycode_num_pad_left_;
-  const KeyCode keycode_num_pad_next_;
-  const KeyCode keycode_num_pad_prior_;
-  const KeyCode keycode_num_pad_right_;
-  const KeyCode keycode_num_pad_up_;
-  const KeyCode keycode_super_l_;
-  const KeyCode keycode_super_r_;
-  const KeyCode keycode_void_symbol_;
-  const KeyCode keycode_delete_;
-  const KeyCode keycode_backspace_;
-  const KeyCode keycode_up_;
-  const KeyCode keycode_down_;
-  const KeyCode keycode_left_;
-  const KeyCode keycode_right_;
-  const KeyCode keycode_prior_;
-  const KeyCode keycode_next_;
-  const KeyCode keycode_home_;
-  const KeyCode keycode_end_;
-  const KeyCode keycode_escape_;
-  const KeyCode keycode_launch6_;  // F15
-  const KeyCode keycode_launch7_;  // F16
-  const KeyCode keycode_f1_;
-  const KeyCode keycode_f2_;
-  const KeyCode keycode_f3_;
-  const KeyCode keycode_f4_;
-  const KeyCode keycode_f5_;
-  const KeyCode keycode_f6_;
-  const KeyCode keycode_f7_;
-  const KeyCode keycode_f8_;
-  const KeyCode keycode_f9_;
-  const KeyCode keycode_f10_;
-  const KeyCode keycode_f11_;
-  const KeyCode keycode_f12_;
-  const KeyCode keycode_browser_back_;
-  const KeyCode keycode_browser_forward_;
-  const KeyCode keycode_browser_refresh_;
-  const KeyCode keycode_media_launch_app1_;
-  const KeyCode keycode_media_launch_app2_;
-  const KeyCode keycode_brightness_down_;
-  const KeyCode keycode_brightness_up_;
-  const KeyCode keycode_volume_mute_;
-  const KeyCode keycode_volume_down_;
-  const KeyCode keycode_volume_up_;
-  const KeyCode keycode_power_;
-  const KeyCode keycode_1_;
-  const KeyCode keycode_2_;
-  const KeyCode keycode_3_;
-  const KeyCode keycode_4_;
-  const KeyCode keycode_5_;
-  const KeyCode keycode_6_;
-  const KeyCode keycode_7_;
-  const KeyCode keycode_8_;
-  const KeyCode keycode_9_;
-  const KeyCode keycode_0_;
-  const KeyCode keycode_minus_;
-  const KeyCode keycode_equal_;
-  const KeyCode keycode_period_;
-  const KeyCode keycode_insert_;
   chromeos::MockUserManager* mock_user_manager_;  // Not owned.
   chromeos::ScopedUserManagerEnabler user_manager_enabler_;
   chromeos::input_method::MockInputMethodManager* input_method_manager_mock_;
 };
 
-TEST_F(EventRewriterTest, TestGetDeviceType) {
-  // This is the typical string which an Apple keyboard sends.
-  EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
-            EventRewriter::GetDeviceType("Apple Inc. Apple Keyboard"));
-
-  // Other cases we accept.
-  EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
-            EventRewriter::GetDeviceType("Apple Keyboard"));
-  EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
-            EventRewriter::GetDeviceType("apple keyboard"));
-  EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
-            EventRewriter::GetDeviceType("apple keyboard."));
-  EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
-            EventRewriter::GetDeviceType("apple.keyboard."));
-  EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
-            EventRewriter::GetDeviceType(".apple.keyboard."));
-
-  // Dell, Microsoft, Logitech, ... should be recognized as a kDeviceUnknown.
-  EXPECT_EQ(EventRewriter::kDeviceUnknown,
-            EventRewriter::GetDeviceType("Dell Dell USB Entry Keyboard"));
-  EXPECT_EQ(EventRewriter::kDeviceUnknown,
-            EventRewriter::GetDeviceType(
-                "Microsoft Natural Ergonomic Keyboard"));
-  EXPECT_EQ(EventRewriter::kDeviceUnknown,
-            EventRewriter::GetDeviceType("CHESEN USB Keyboard"));
-
-  // Some corner cases.
-  EXPECT_EQ(EventRewriter::kDeviceUnknown, EventRewriter::GetDeviceType(""));
-  EXPECT_EQ(EventRewriter::kDeviceUnknown,
-            EventRewriter::GetDeviceType("."));
-  EXPECT_EQ(EventRewriter::kDeviceUnknown,
-            EventRewriter::GetDeviceType(". "));
-  EXPECT_EQ(EventRewriter::kDeviceUnknown,
-            EventRewriter::GetDeviceType(" ."));
-  EXPECT_EQ(EventRewriter::kDeviceUnknown,
-            EventRewriter::GetDeviceType("not-an-apple keyboard"));
-}
-
-TEST_F(EventRewriterTest, TestDeviceAddedOrRemoved) {
-  EventRewriter rewriter;
-  EXPECT_TRUE(rewriter.device_id_to_type_for_testing().empty());
-  EXPECT_EQ(EventRewriter::kDeviceUnknown,
-            rewriter.DeviceAddedForTesting(0, "PC Keyboard"));
-  EXPECT_EQ(1U, rewriter.device_id_to_type_for_testing().size());
-  EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
-            rewriter.DeviceAddedForTesting(1, "Apple Keyboard"));
-  EXPECT_EQ(2U, rewriter.device_id_to_type_for_testing().size());
-  // Try to reuse the first ID.
-  EXPECT_EQ(EventRewriter::kDeviceAppleKeyboard,
-            rewriter.DeviceAddedForTesting(0, "Apple Keyboard"));
-  EXPECT_EQ(2U, rewriter.device_id_to_type_for_testing().size());
-}
-
 TEST_F(EventRewriterTest, TestRewriteCommandToControl) {
   // First, test with a PC keyboard.
   TestingPrefServiceSyncable prefs;
@@ -347,149 +141,89 @@
   rewriter.set_last_device_id_for_testing(0);
   rewriter.set_pref_service_for_testing(&prefs);
 
-  // XK_a, Alt modifier.
+  // VKEY_A, Alt modifier.
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
+
+  // VKEY_A, Win modifier.
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_A, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_A, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
+
+  // VKEY_A, Alt+Win modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask,
-                                      KeyPress),
+                                      ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_A,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
-  // XK_a, Win modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod4Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_A,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod4Mask));
-
-  // XK_a, Alt+Win modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask | Mod4Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_A,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask | Mod4Mask));
-
-  // XK_Super_L (left Windows key), Alt modifier.
+  // VKEY_LWIN (left Windows key), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      Mod1Mask,
-                                      KeyPress),
+                                      ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_LWIN,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
-  // XK_Super_R (right Windows key), Alt modifier.
+  // VKEY_RWIN (right Windows key), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_RWIN,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_r_,
-                                      Mod1Mask,
-                                      KeyPress),
+                                      ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_RWIN,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_r_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
   // An Apple keyboard reusing the ID, zero.
   rewriter.DeviceAddedForTesting(0, "Apple Keyboard");
   rewriter.set_last_device_id_for_testing(0);
 
-  // XK_a, Alt modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_A,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask));
+  // VKEY_A, Alt modifier.
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
 
-  // XK_a, Win modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      ControlMask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_A,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod4Mask));
+  // VKEY_A, Win modifier.
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_A, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
 
-  // XK_a, Alt+Win modifier.
+  // VKEY_A, Alt+Win modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
                                       ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask | ControlMask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_A,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask | Mod4Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
-  // XK_Super_L (left Windows key), Alt modifier.
+  // VKEY_LWIN (left Windows key), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
                                       ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      Mod1Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_LWIN,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      Mod1Mask));
+                                      ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
-  // XK_Super_R (right Windows key), Alt modifier.
+  // VKEY_RWIN (right Windows key), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
                                       ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_r_,
-                                      Mod1Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_RWIN,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_r_,
-                                      Mod1Mask));
+                                      ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
+                                      ui::ET_KEY_PRESSED));
 }
 
 // For crbug.com/133896.
@@ -506,53 +240,37 @@
   rewriter.DeviceAddedForTesting(0, "PC Keyboard");
   rewriter.set_last_device_id_for_testing(0);
 
-  // XK_Control_L (left Control key) should be remapped to Alt.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_l_,
-                                      0U,
-                                      KeyPress),
+  // Control should be remapped to Alt.
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_CONTROL,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U));
+                                      ui::EF_CONTROL_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
   // An Apple keyboard reusing the ID, zero.
   rewriter.DeviceAddedForTesting(0, "Apple Keyboard");
   rewriter.set_last_device_id_for_testing(0);
 
-  // XK_Super_L (left Command key) with  Alt modifier. The remapped Command key
+  // VKEY_LWIN (left Command key) with  Alt modifier. The remapped Command key
   // should never be re-remapped to Alt.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
                                       ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      Mod1Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_LWIN,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      Mod1Mask));
+                                      ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
-  // XK_Super_R (right Command key) with  Alt modifier. The remapped Command key
+  // VKEY_RWIN (right Command key) with  Alt modifier. The remapped Command key
   // should never be re-remapped to Alt.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
                                       ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_r_,
-                                      Mod1Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_RWIN,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_r_,
-                                      Mod1Mask));
+                                      ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
+                                      ui::ET_KEY_PRESSED));
 }
 
 void EventRewriterTest::TestRewriteNumPadKeys() {
@@ -561,326 +279,187 @@
   rewriter.set_pref_service_for_testing(&prefs);
 
   // XK_KP_Insert (= NumPad 0 without Num Lock), no modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_0_,
-                                      Mod2Mask,  // Num Lock
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_INSERT,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_insert_,
-                                      0));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_INSERT, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 
   // XK_KP_Insert (= NumPad 0 without Num Lock), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0,
                                       ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_0_,
-                                      Mod1Mask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_INSERT,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_insert_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
   // XK_KP_Delete (= NumPad . without Num Lock), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_DECIMAL,
                                       ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_decimal_,
-                                      Mod1Mask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_DELETE,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_delete_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
   // XK_KP_End (= NumPad 1 without Num Lock), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
                                       ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_1_,
-                                      Mod1Mask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_END,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_end_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
   // XK_KP_Down (= NumPad 2 without Num Lock), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD2,
                                       ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_2_,
-                                      Mod1Mask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_DOWN,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_down_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
   // XK_KP_Next (= NumPad 3 without Num Lock), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD3,
                                       ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_3_,
-                                      Mod1Mask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_NEXT,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_next_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
   // XK_KP_Left (= NumPad 4 without Num Lock), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD4,
                                       ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_4_,
-                                      Mod1Mask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_LEFT,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_left_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
   // XK_KP_Begin (= NumPad 5 without Num Lock), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD5,
                                       ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_5_,
-                                      Mod1Mask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_CLEAR,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_begin_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
   // XK_KP_Right (= NumPad 6 without Num Lock), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD6,
                                       ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_6_,
-                                      Mod1Mask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_RIGHT,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_right_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
   // XK_KP_Home (= NumPad 7 without Num Lock), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD7,
                                       ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_7_,
-                                      Mod1Mask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_HOME,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_home_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
   // XK_KP_Up (= NumPad 8 without Num Lock), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD8,
                                       ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_8_,
-                                      Mod1Mask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_UP,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_up_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
   // XK_KP_Prior (= NumPad 9 without Num Lock), Alt modifier.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD9,
                                       ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_9_,
-                                      Mod1Mask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_PRIOR,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_prior_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
   // XK_KP_0 (= NumPad 0 with Num Lock), Num Lock modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD0,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_0_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_NUMPAD0,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_0_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 
   // XK_KP_DECIMAL (= NumPad . with Num Lock), Num Lock modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_DECIMAL,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_decimal_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_DECIMAL,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_decimal_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_DECIMAL, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_DECIMAL, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 
   // XK_KP_1 (= NumPad 1 with Num Lock), Num Lock modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_1_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_NUMPAD1,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_1_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_NUMPAD1, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_NUMPAD1, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 
   // XK_KP_2 (= NumPad 2 with Num Lock), Num Lock modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD2,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_2_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_NUMPAD2,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_2_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_NUMPAD2, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_NUMPAD2, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 
   // XK_KP_3 (= NumPad 3 with Num Lock), Num Lock modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD3,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_3_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_NUMPAD3,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_3_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_NUMPAD3, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_NUMPAD3, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 
   // XK_KP_4 (= NumPad 4 with Num Lock), Num Lock modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD4,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_4_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_NUMPAD4,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_4_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_NUMPAD4, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_NUMPAD4, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 
   // XK_KP_5 (= NumPad 5 with Num Lock), Num Lock modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD5,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_5_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_NUMPAD5,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_5_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_NUMPAD5, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_NUMPAD5, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 
   // XK_KP_6 (= NumPad 6 with Num Lock), Num Lock modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD6,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_6_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_NUMPAD6,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_6_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_NUMPAD6, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_NUMPAD6, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 
   // XK_KP_7 (= NumPad 7 with Num Lock), Num Lock modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD7,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_7_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_NUMPAD7,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_7_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_NUMPAD7, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_NUMPAD7, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 
   // XK_KP_8 (= NumPad 8 with Num Lock), Num Lock modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD8,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_8_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_NUMPAD8,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_8_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_NUMPAD8, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_NUMPAD8, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 
   // XK_KP_9 (= NumPad 9 with Num Lock), Num Lock modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD9,
-                                      ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_9_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_NUMPAD9,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_9_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_NUMPAD9, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_NUMPAD9, ui::EF_NUMPAD_KEY, ui::ET_KEY_PRESSED));
 }
 
 TEST_F(EventRewriterTest, TestRewriteNumPadKeys) {
@@ -909,31 +488,21 @@
   // The result should be "Num Pad 1 with Control + Num Lock modifiers".
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
                                       ui::EF_CONTROL_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_1_,
-                                      ControlMask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_END,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_end_,
-                                      Mod4Mask));
+                                      ui::EF_COMMAND_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 
-  // XK_KP_1 (= NumPad 1 without Num Lock), Win modifier.
+  // XK_KP_1 (= NumPad 1 with Num Lock), Win modifier.
   // The result should also be "Num Pad 1 with Control + Num Lock modifiers".
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_NUMPAD1,
                                       ui::EF_CONTROL_DOWN | ui::EF_NUMPAD_KEY,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_1_,
-                                      ControlMask | Mod2Mask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_NUMPAD1,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_num_pad_end_,
-                                      Mod4Mask));
+                                      ui::EF_COMMAND_DOWN | ui::EF_NUMPAD_KEY,
+                                      ui::ET_KEY_PRESSED));
 }
 
 TEST_F(EventRewriterTest, TestRewriteNumPadKeysOnAppleKeyboard) {
@@ -957,89 +526,45 @@
   rewriter.set_pref_service_for_testing(&prefs);
 
   // Press Search. Confirm the event is not rewritten.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      0U));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_PRESSED));
 
   // Press left Control. Confirm the event is not rewritten.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U,
-                                      KeyPress),
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_CONTROL,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U));
+                                      ui::EF_CONTROL_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
   // Press right Control. Confirm the event is not rewritten.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_r_,
-                                      0U,
-                                      KeyPress),
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_CONTROL,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_r_,
-                                      0U));
+                                      ui::EF_CONTROL_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
   // Press left Alt. Confirm the event is not rewritten.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_l_,
-                                      0,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_MENU,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_l_,
-                                      0U));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
 
   // Press right Alt. Confirm the event is not rewritten.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_r_,
-                                      0,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_MENU,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_r_,
-                                      0U));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
 
   // Test KeyRelease event, just in case.
   // Release Search. Confirm the release event is not rewritten.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
-                                      0,
-                                      ui::ET_KEY_RELEASED,
-                                      keycode_super_l_,
-                                      Mod4Mask,
-                                      KeyRelease),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      0,
-                                      ui::ET_KEY_RELEASED,
-                                      keycode_super_l_,
-                                      Mod4Mask));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED));
 }
 
 TEST_F(EventRewriterTest, TestRewriteModifiersNoRemapMultipleKeys) {
@@ -1047,79 +572,43 @@
   EventRewriter rewriter;
   rewriter.set_pref_service_for_testing(&prefs);
 
-  // Press left Alt with Shift. Confirm the event is not rewritten.
+  // Press Alt with Shift. Confirm the event is not rewritten.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
                                       ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_meta_l_,
-                                      ShiftMask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_MENU,
-                                      ui::EF_SHIFT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_meta_l_,
-                                      ShiftMask));
-
-  // Press right Alt with Shift. Confirm the event is not rewritten.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
                                       ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_meta_r_,
-                                      ShiftMask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_MENU,
-                                      ui::EF_SHIFT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_meta_r_,
-                                      ShiftMask));
+                                      ui::ET_KEY_PRESSED));
 
   // Press Search with Caps Lock mask. Confirm the event is not rewritten.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      LockMask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      LockMask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(ui::VKEY_LWIN,
+                                ui::EF_CAPS_LOCK_DOWN | ui::EF_COMMAND_DOWN,
+                                ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(&rewriter,
+                                ui::VKEY_LWIN,
+                                ui::EF_CAPS_LOCK_DOWN | ui::EF_COMMAND_DOWN,
+                                ui::ET_KEY_PRESSED));
 
   // Release Search with Caps Lock mask. Confirm the event is not rewritten.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_RELEASED,
-                                      keycode_super_l_,
-                                      LockMask | Mod4Mask,
-                                      KeyRelease),
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_RELEASED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_LWIN,
                                       ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_RELEASED,
-                                      keycode_super_l_,
-                                      LockMask | Mod4Mask));
+                                      ui::ET_KEY_RELEASED));
 
   // Press Shift+Ctrl+Alt+Search+A. Confirm the event is not rewritten.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
-                                      ui::EF_SHIFT_DOWN |
-                                      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_b_,
-                                      ShiftMask | ControlMask | Mod1Mask |
-                                      Mod4Mask,
-                                      KeyPress),
+                                      ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
+                                          ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_B,
-                                      ui::EF_SHIFT_DOWN |
-                                      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_b_,
-                                      ShiftMask | ControlMask | Mod1Mask |
-                                      Mod4Mask));
+                                      ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
+                                          ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED));
 }
 
 TEST_F(EventRewriterTest, TestRewriteModifiersDisableSome) {
@@ -1136,128 +625,70 @@
   EventRewriter rewriter;
   rewriter.set_pref_service_for_testing(&prefs);
 
-  // Press left Alt with Shift. This key press shouldn't be affected by the
+  // Press Alt with Shift. This key press shouldn't be affected by the
   // pref. Confirm the event is not rewritten.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
                                       ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_meta_l_,
-                                      ShiftMask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_MENU,
-                                      ui::EF_SHIFT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_meta_l_,
-                                      ShiftMask));
+                                      ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
-  // Press Search. Confirm the event is now VKEY_UNKNOWN + XK_VoidSymbol.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_void_symbol_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      0U));
+  // Press Search. Confirm the event is now VKEY_UNKNOWN.
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_UNKNOWN, ui::EF_NONE, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_PRESSED));
 
-  // Press Control. Confirm the event is now VKEY_UNKNOWN + XK_VoidSymbol.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_void_symbol_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_CONTROL,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U));
+  // Press Control. Confirm the event is now VKEY_UNKNOWN.
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_UNKNOWN, ui::EF_NONE, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_CONTROL, ui::EF_NONE, ui::ET_KEY_PRESSED));
 
-  // Press Control+Search. Confirm the event is now VKEY_UNKNOWN +
-  // XK_VoidSymbol without any modifiers.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_void_symbol_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      ControlMask));
+  // Press Control+Search. Confirm the event is now VKEY_UNKNOWN
+  // without any modifiers.
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_UNKNOWN, ui::EF_NONE, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_LWIN, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED));
 
   // Press Control+Search+a. Confirm the event is now VKEY_A without any
   // modifiers.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_A,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      ControlMask | Mod4Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED));
 
   // Press Control+Search+Alt+a. Confirm the event is now VKEY_A only with
   // the Alt modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask,
-                                      KeyPress),
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_A,
                                       ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      ControlMask | Mod1Mask | Mod4Mask));
+                                      ui::ET_KEY_PRESSED));
 
   // Remap Alt to Control.
   IntegerPrefMember alt;
   alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
   alt.SetValue(chromeos::input_method::kControlKey);
 
-  // Press left Alt. Confirm the event is now VKEY_CONTROL + XK_Control_L
+  // Press left Alt. Confirm the event is now VKEY_CONTROL
   // even though the Control key itself is disabled.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_MENU,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_l_,
-                                      0U));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
 
   // Press Alt+a. Confirm the event is now Control+a even though the Control
   // key itself is disabled.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      ControlMask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_A,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_A, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
 }
 
 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToControl) {
@@ -1271,113 +702,62 @@
   EventRewriter rewriter;
   rewriter.set_pref_service_for_testing(&prefs);
 
-  // Press Search. Confirm the event is now VKEY_CONTROL + XK_Control_L.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      0U));
+  // Press Search. Confirm the event is now VKEY_CONTROL.
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
 
   // Remap Alt to Control too.
   IntegerPrefMember alt;
   alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
   alt.SetValue(chromeos::input_method::kControlKey);
 
-  // Press left Alt. Confirm the event is now VKEY_CONTROL + XK_Control_L.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_MENU,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_l_,
-                                      0U));
+  // Press Alt. Confirm the event is now VKEY_CONTROL.
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
 
-  // Press right Alt. Confirm the event is now VKEY_CONTROL + XK_Control_R.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_r_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_MENU,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_r_,
-                                      0U));
-
-  // Press Alt+Search. Confirm the event is now VKEY_CONTROL + XK_Control_L.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      ControlMask,
-                                      KeyPress),
+  // Press Alt+Search. Confirm the event is now VKEY_CONTROL.
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_LWIN,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      Mod1Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
-  // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL +
-  // XK_Control_L.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      ControlMask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      ControlMask | Mod1Mask));
+  // Press Control+Alt+Search. Confirm the event is now VKEY_CONTROL.
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter,
+                ui::VKEY_LWIN,
+                ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                ui::ET_KEY_PRESSED));
 
   // Press Shift+Control+Alt+Search. Confirm the event is now Control with
   // Shift and Control modifiers.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
                                       ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      ShiftMask | ControlMask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_LWIN,
-                                      ui::EF_SHIFT_DOWN |
-                                      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      ShiftMask | ControlMask | Mod1Mask));
+                                      ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
+                                          ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
   // Press Shift+Control+Alt+Search+B. Confirm the event is now B with Shift
   // and Control modifiers.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
                                       ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_b_,
-                                      ShiftMask | ControlMask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_B,
-                                      ui::EF_SHIFT_DOWN |
-                                      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_b_,
-                                      ShiftMask | ControlMask | Mod1Mask));
+                                      ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
+                                          ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED));
 }
 
 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToEscape) {
@@ -1392,18 +772,11 @@
   rewriter.set_pref_service_for_testing(&prefs);
 
   // Press Search. Confirm the event is now VKEY_ESCAPE.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_ESCAPE,
-                                      ui::EF_NONE,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_escape_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      0U));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_ESCAPE, ui::EF_NONE, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
 }
 
 TEST_F(EventRewriterTest, TestRewriteModifiersRemapMany) {
@@ -1417,38 +790,23 @@
   EventRewriter rewriter;
   rewriter.set_pref_service_for_testing(&prefs);
 
-  // Press Search. Confirm the event is now VKEY_MENU + XK_Alt_L.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_l_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      0U));
+  // Press Search. Confirm the event is now VKEY_MENU.
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
 
   // Remap Alt to Control.
   IntegerPrefMember alt;
   alt.Init(prefs::kLanguageRemapAltKeyTo, &prefs);
   alt.SetValue(chromeos::input_method::kControlKey);
 
-  // Press left Alt. Confirm the event is now VKEY_CONTROL + XK_Control_L.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_MENU,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_l_,
-                                      0U));
+  // Press left Alt. Confirm the event is now VKEY_CONTROL.
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED));
 
   // Remap Control to Search.
   IntegerPrefMember control;
@@ -1456,66 +814,45 @@
   control.SetValue(chromeos::input_method::kSearchKey);
 
   // Press left Control. Confirm the event is now VKEY_LWIN.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_LWIN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      0U,
-                                      KeyPress),
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_CONTROL,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U));
+                                      ui::EF_CONTROL_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
   // Then, press all of the three, Control+Alt+Search.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
-                                      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_l_,
-                                      ControlMask | Mod4Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      ControlMask | Mod1Mask));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_MENU,
+                ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter,
+                ui::VKEY_LWIN,
+                ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                ui::ET_KEY_PRESSED));
 
   // Press Shift+Control+Alt+Search.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
-                                      (ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
-                                       ui::EF_ALT_DOWN),
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_l_,
-                                      ShiftMask | ControlMask | Mod4Mask,
-                                      KeyPress),
+                                      ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
+                                          ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_LWIN,
-                                      ui::EF_SHIFT_DOWN |
-                                      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      ShiftMask | ControlMask | Mod1Mask));
+                                      ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
+                                          ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
   // Press Shift+Control+Alt+Search+B
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_B,
-                                      ui::EF_SHIFT_DOWN |
-                                      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_b_,
-                                      ShiftMask | ControlMask | Mod1Mask |
-                                      Mod4Mask,
-                                      KeyPress),
+                                      ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
+                                          ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_B,
-                                      ui::EF_SHIFT_DOWN |
-                                      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_b_,
-                                      ShiftMask | ControlMask | Mod1Mask |
-                                      Mod4Mask));
+                                      ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
+                                          ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                      ui::ET_KEY_PRESSED));
 }
 
 TEST_F(EventRewriterTest, TestRewriteModifiersRemapToCapsLock) {
@@ -1526,185 +863,111 @@
   search.Init(prefs::kLanguageRemapSearchKeyTo, &prefs);
   search.SetValue(chromeos::input_method::kCapsLockKey);
 
-  chromeos::input_method::FakeImeKeyboard keyboard;
+  chromeos::input_method::FakeImeKeyboard ime_keyboard;
   EventRewriter rewriter;
   rewriter.set_pref_service_for_testing(&prefs);
-  rewriter.set_keyboard_for_testing(&keyboard);
-  EXPECT_FALSE(keyboard.caps_lock_is_enabled_);
+  rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
+  EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
 
   // Press Search.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_caps_lock_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      0U));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_CAPITAL, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_LWIN, ui::EF_COMMAND_DOWN, ui::ET_KEY_PRESSED));
   // Confirm that the Caps Lock status is changed.
-  EXPECT_TRUE(keyboard.caps_lock_is_enabled_);
+  EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
 
   // Release Search.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
-                                      ui::EF_NONE,
-                                      ui::ET_KEY_RELEASED,
-                                      keycode_caps_lock_,
-                                      LockMask,
-                                      KeyRelease),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_RELEASED,
-                                      keycode_super_l_,
-                                      Mod4Mask | LockMask));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED));
   // Confirm that the Caps Lock status is not changed.
-  EXPECT_TRUE(keyboard.caps_lock_is_enabled_);
+  EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
 
   // Press Search.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_caps_lock_,
-                                      LockMask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_super_l_,
-                                      LockMask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_CAPITAL, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(&rewriter,
+                                ui::VKEY_LWIN,
+                                ui::EF_COMMAND_DOWN | ui::EF_CAPS_LOCK_DOWN,
+                                ui::ET_KEY_PRESSED));
   // Confirm that the Caps Lock status is changed.
-  EXPECT_FALSE(keyboard.caps_lock_is_enabled_);
+  EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
 
   // Release Search.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
-                                      ui::EF_NONE,
-                                      ui::ET_KEY_RELEASED,
-                                      keycode_caps_lock_,
-                                      LockMask,
-                                      KeyRelease),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_LWIN,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_RELEASED,
-                                      keycode_super_l_,
-                                      Mod4Mask | LockMask));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_LWIN, ui::EF_NONE, ui::ET_KEY_RELEASED));
   // Confirm that the Caps Lock status is not changed.
-  EXPECT_FALSE(keyboard.caps_lock_is_enabled_);
+  EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
 
   // Press Caps Lock (on an external keyboard).
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_caps_lock_,
-                                      0U,
-                                      KeyPress),
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CAPITAL, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_CAPITAL,
-                                      ui::EF_NONE,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_caps_lock_,
-                                      0U));
+                                      ui::EF_CAPS_LOCK_DOWN,
+                                      ui::ET_KEY_PRESSED));
 
   // Confirm that calling RewriteForTesting() does not change the state of
-  // |keyboard|. In this case, X Window system itself should change the
+  // |ime_keyboard|. In this case, X Window system itself should change the
   // Caps Lock state, not ash::EventRewriter.
-  EXPECT_FALSE(keyboard.caps_lock_is_enabled_);
+  EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
 
   // Release Caps Lock (on an external keyboard).
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
-                                      ui::EF_NONE,
-                                      ui::ET_KEY_RELEASED,
-                                      keycode_caps_lock_,
-                                      LockMask,
-                                      KeyRelease),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_CAPITAL,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_RELEASED,
-                                      keycode_caps_lock_,
-                                      LockMask));
-  EXPECT_FALSE(keyboard.caps_lock_is_enabled_);
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_CAPITAL, ui::EF_NONE, ui::ET_KEY_RELEASED));
+  EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
 }
 
-TEST_F(EventRewriterTest, DISABLED_TestRewriteCapsLock) {
-  // It seems that the X server running on build servers is too old and does not
-  // support F16 (i.e. 'XKeysymToKeycode(display_, XF86XK_Launch7)' call).
-  // TODO(yusukes): Reenable the test once build servers are upgraded.
-
+TEST_F(EventRewriterTest, TestRewriteCapsLock) {
   TestingPrefServiceSyncable prefs;
   chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
 
-  chromeos::input_method::FakeImeKeyboard keyboard;
+  chromeos::input_method::FakeImeKeyboard ime_keyboard;
   EventRewriter rewriter;
   rewriter.set_pref_service_for_testing(&prefs);
-  rewriter.set_keyboard_for_testing(&keyboard);
-  EXPECT_FALSE(keyboard.caps_lock_is_enabled_);
+  rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
+  EXPECT_FALSE(ime_keyboard.caps_lock_is_enabled_);
 
   // On Chrome OS, CapsLock is mapped to F16 with Mod3Mask.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_caps_lock_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_F16,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_launch7_,
-                                      0U));
-  EXPECT_TRUE(keyboard.caps_lock_is_enabled_);
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CAPITAL, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_F16, ui::EF_NONE, ui::ET_KEY_PRESSED));
+  EXPECT_TRUE(ime_keyboard.caps_lock_is_enabled_);
 }
 
-TEST_F(EventRewriterTest, DISABLED_TestRewriteDiamondKey) {
-  // TODO(yusukes): Reenable the test once build servers are upgraded.
-
+TEST_F(EventRewriterTest, TestRewriteDiamondKey) {
   TestingPrefServiceSyncable prefs;
   chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
 
-  chromeos::input_method::FakeImeKeyboard keyboard;
+  chromeos::input_method::FakeImeKeyboard ime_keyboard;
   EventRewriter rewriter;
   rewriter.set_pref_service_for_testing(&prefs);
-  rewriter.set_keyboard_for_testing(&keyboard);
+  rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
 
   // F15 should work as Ctrl when --has-chromeos-diamond-key is not specified.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_F15,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_launch6_,
-                                      0U));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
 
   // However, Mod2Mask should not be rewritten to CtrlMask when
   // --has-chromeos-diamond-key is not specified.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod2Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_A,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod2Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
 }
 
-TEST_F(EventRewriterTest, DISABLED_TestRewriteDiamondKeyWithFlag) {
-  // TODO(yusukes): Reenable the test once build servers are upgraded.
-
+TEST_F(EventRewriterTest, TestRewriteDiamondKeyWithFlag) {
   const CommandLine original_cl(*CommandLine::ForCurrentProcess());
   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
       chromeos::switches::kHasChromeOSDiamondKey, "");
@@ -1712,91 +975,52 @@
   TestingPrefServiceSyncable prefs;
   chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
 
-  chromeos::input_method::FakeImeKeyboard keyboard;
+  chromeos::input_method::FakeImeKeyboard ime_keyboard;
   EventRewriter rewriter;
   rewriter.set_pref_service_for_testing(&prefs);
-  rewriter.set_keyboard_for_testing(&keyboard);
+  rewriter.set_ime_keyboard_for_testing(&ime_keyboard);
 
   // By default, F15 should work as Control.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_F15,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_launch6_,
-                                      0U));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
 
   IntegerPrefMember diamond;
   diamond.Init(prefs::kLanguageRemapDiamondKeyTo, &prefs);
   diamond.SetValue(chromeos::input_method::kVoidKey);
 
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_UNKNOWN,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_void_symbol_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_F15,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_launch6_,
-                                      0U));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_UNKNOWN, ui::EF_NONE, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
 
   diamond.SetValue(chromeos::input_method::kControlKey);
 
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_F15,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_launch6_,
-                                      0U));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CONTROL, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
 
   diamond.SetValue(chromeos::input_method::kAltKey);
 
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_MENU,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_alt_l_,
-                                      0,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_F15,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_launch6_,
-                                      0U));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_MENU, ui::EF_ALT_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
 
   diamond.SetValue(chromeos::input_method::kCapsLockKey);
 
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CAPITAL,
-                                      ui::EF_CAPS_LOCK_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_caps_lock_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_F15,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_launch6_,
-                                      0U));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_CAPITAL, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter, ui::VKEY_F15, ui::EF_NONE, ui::ET_KEY_PRESSED));
 
   *CommandLine::ForCurrentProcess() = original_cl;
 }
 
 TEST_F(EventRewriterTest, TestRewriteCapsLockToControl) {
+  // Remap CapsLock to Control.
   TestingPrefServiceSyncable prefs;
   chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   IntegerPrefMember control;
@@ -1808,46 +1032,27 @@
 
   // Press CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
   // On Chrome OS, CapsLock works as a Mod3 modifier.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      ControlMask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_A,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod3Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_A, ui::EF_CAPS_LOCK_DOWN, ui::ET_KEY_PRESSED));
 
   // Press Control+CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      ControlMask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_A,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod3Mask | ControlMask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(
+          ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_A, ui::EF_CONTROL_DOWN, ui::ET_KEY_PRESSED));
 
   // Press Alt+CapsLock+a. Confirm that Mod3Mask is rewritten to ControlMask.
   EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
                                       ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask | ControlMask,
-                                      KeyPress),
+                                      ui::ET_KEY_PRESSED),
             GetRewrittenEventAsString(&rewriter,
                                       ui::VKEY_A,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod1Mask | Mod3Mask));
+                                      ui::EF_ALT_DOWN | ui::EF_CAPS_LOCK_DOWN,
+                                      ui::ET_KEY_PRESSED));
 }
 
 TEST_F(EventRewriterTest, TestRewriteCapsLockMod3InUse) {
@@ -1864,18 +1069,10 @@
 
   // Press CapsLock+a. Confirm that Mod3Mask is NOT rewritten to ControlMask
   // when Mod3Mask is already in use by the current XKB layout.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_A,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod3Mask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_A,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_a_,
-                                      Mod3Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(
+          &rewriter, ui::VKEY_A, ui::EF_NONE, ui::ET_KEY_PRESSED));
 
   input_method_manager_mock_->set_mod3_used(false);
 }
@@ -1884,142 +1081,90 @@
   TestingPrefServiceSyncable prefs;
   chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
   EventRewriter rewriter;
+  rewriter.DeviceAddedForTesting(0, "PC Keyboard");
+  rewriter.set_last_device_id_for_testing(0);
   rewriter.set_pref_service_for_testing(&prefs);
 
   struct {
     ui::KeyboardCode input;
-    KeyCode input_native;
     unsigned int input_mods;
-    unsigned int input_native_mods;
     ui::KeyboardCode output;
-    KeyCode output_native;
     unsigned int output_mods;
-    unsigned int output_native_mods;
   } chromeos_tests[] = {
-    // Alt+Backspace -> Delete
-    { ui::VKEY_BACK, keycode_backspace_,
-      ui::EF_ALT_DOWN, Mod1Mask,
-      ui::VKEY_DELETE, keycode_delete_,
-      0, 0, },
-    // Control+Alt+Backspace -> Control+Delete
-    { ui::VKEY_BACK, keycode_backspace_,
-      ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask,
-      ui::VKEY_DELETE, keycode_delete_,
-      ui::EF_CONTROL_DOWN, ControlMask, },
-    // Search+Alt+Backspace -> Alt+Backspace
-    { ui::VKEY_BACK, keycode_backspace_,
-      ui::EF_ALT_DOWN, Mod1Mask | Mod4Mask,
-      ui::VKEY_BACK, keycode_backspace_,
-      ui::EF_ALT_DOWN, Mod1Mask, },
-    // Search+Control+Alt+Backspace -> Control+Alt+Backspace
-    { ui::VKEY_BACK, keycode_backspace_,
-      ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask | Mod4Mask,
-      ui::VKEY_BACK, keycode_backspace_,
-      ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask, },
-    // Alt+Up -> Prior
-    { ui::VKEY_UP, keycode_up_,
-      ui::EF_ALT_DOWN, Mod1Mask,
-      ui::VKEY_PRIOR, keycode_prior_,
-      0, 0, },
-    // Alt+Down -> Next
-    { ui::VKEY_DOWN, keycode_down_,
-      ui::EF_ALT_DOWN, Mod1Mask,
-      ui::VKEY_NEXT, keycode_next_,
-      0, 0, },
-    // Ctrl+Alt+Up -> Home
-    { ui::VKEY_UP, keycode_up_,
-      ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask,
-      ui::VKEY_HOME, keycode_home_,
-      0, 0, },
-    // Ctrl+Alt+Down -> End
-    { ui::VKEY_DOWN, keycode_down_,
-      ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask,
-      ui::VKEY_END, keycode_end_,
-      0, 0, },
+        // Alt+Backspace -> Delete
+        {ui::VKEY_BACK, ui::EF_ALT_DOWN, ui::VKEY_DELETE, ui::EF_NONE},
+        // Control+Alt+Backspace -> Control+Delete
+        {ui::VKEY_BACK, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, ui::VKEY_DELETE,
+         ui::EF_CONTROL_DOWN},
+        // Search+Alt+Backspace -> Alt+Backspace
+        {ui::VKEY_BACK, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::VKEY_BACK,
+         ui::EF_ALT_DOWN},
+        // Search+Control+Alt+Backspace -> Control+Alt+Backspace
+        {ui::VKEY_BACK,
+         ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
+         ui::VKEY_BACK, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
+        // Alt+Up -> Prior
+        {ui::VKEY_UP, ui::EF_ALT_DOWN, ui::VKEY_PRIOR, ui::EF_NONE},
+        // Alt+Down -> Next
+        {ui::VKEY_DOWN, ui::EF_ALT_DOWN, ui::VKEY_NEXT, ui::EF_NONE},
+        // Ctrl+Alt+Up -> Home
+        {ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, ui::VKEY_HOME,
+         ui::EF_NONE},
+        // Ctrl+Alt+Down -> End
+        {ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, ui::VKEY_END,
+         ui::EF_NONE},
 
-    // Search+Alt+Up -> Alt+Up
-    { ui::VKEY_UP, keycode_up_,
-      ui::EF_ALT_DOWN, Mod1Mask | Mod4Mask,
-      ui::VKEY_UP, keycode_up_,
-      ui::EF_ALT_DOWN, Mod1Mask },
-    // Search+Alt+Down -> Alt+Down
-    { ui::VKEY_DOWN, keycode_down_,
-      ui::EF_ALT_DOWN, Mod1Mask | Mod4Mask,
-      ui::VKEY_DOWN, keycode_down_,
-      ui::EF_ALT_DOWN, Mod1Mask },
-    // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
-    { ui::VKEY_UP, keycode_up_,
-      ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask | Mod4Mask,
-      ui::VKEY_UP, keycode_up_,
-      ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask },
-    // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
-    { ui::VKEY_DOWN, keycode_down_,
-      ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask | Mod4Mask,
-      ui::VKEY_DOWN, keycode_down_,
-      ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, Mod1Mask | ControlMask },
+        // Search+Alt+Up -> Alt+Up
+        {ui::VKEY_UP, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::VKEY_UP,
+         ui::EF_ALT_DOWN},
+        // Search+Alt+Down -> Alt+Down
+        {ui::VKEY_DOWN, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::VKEY_DOWN,
+         ui::EF_ALT_DOWN},
+        // Search+Ctrl+Alt+Up -> Search+Ctrl+Alt+Up
+        {ui::VKEY_UP,
+         ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
+         ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
+        // Search+Ctrl+Alt+Down -> Ctrl+Alt+Down
+        {ui::VKEY_DOWN,
+         ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
+         ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN},
 
-    // Period -> Period
-    { ui::VKEY_OEM_PERIOD, keycode_period_, 0, 0,
-      ui::VKEY_OEM_PERIOD, keycode_period_, 0, 0 },
+        // Period -> Period
+        {ui::VKEY_OEM_PERIOD, ui::EF_NONE, ui::VKEY_OEM_PERIOD, ui::EF_NONE},
 
-    // Search+Backspace -> Delete
-    { ui::VKEY_BACK, keycode_backspace_,
-      0, Mod4Mask,
-      ui::VKEY_DELETE, keycode_delete_,
-      0, 0, },
-    // Search+Up -> Prior
-    { ui::VKEY_UP, keycode_up_,
-      0, Mod4Mask,
-      ui::VKEY_PRIOR, keycode_prior_,
-      0, 0, },
-    // Search+Down -> Next
-    { ui::VKEY_DOWN, keycode_down_,
-      0, Mod4Mask,
-      ui::VKEY_NEXT, keycode_next_,
-      0, 0, },
-    // Search+Left -> Home
-    { ui::VKEY_LEFT, keycode_left_,
-      0, Mod4Mask,
-      ui::VKEY_HOME, keycode_home_,
-      0, 0, },
-    // Control+Search+Left -> Home
-    { ui::VKEY_LEFT, keycode_left_,
-      ui::EF_CONTROL_DOWN, Mod4Mask | ControlMask,
-      ui::VKEY_HOME, keycode_home_,
-      ui::EF_CONTROL_DOWN, ControlMask },
-    // Search+Right -> End
-    { ui::VKEY_RIGHT, keycode_right_,
-      0, Mod4Mask,
-      ui::VKEY_END, keycode_end_,
-      0, 0, },
-    // Control+Search+Right -> End
-    { ui::VKEY_RIGHT, keycode_right_,
-      ui::EF_CONTROL_DOWN, Mod4Mask | ControlMask,
-      ui::VKEY_END, keycode_end_,
-      ui::EF_CONTROL_DOWN, ControlMask },
-    // Search+Period -> Insert
-    { ui::VKEY_OEM_PERIOD, keycode_period_, 0, Mod4Mask,
-      ui::VKEY_INSERT, keycode_insert_, 0, 0 },
-    // Control+Search+Period -> Control+Insert
-    { ui::VKEY_OEM_PERIOD, keycode_period_,
-      ui::EF_CONTROL_DOWN, Mod4Mask | ControlMask,
-      ui::VKEY_INSERT, keycode_insert_,
-      ui::EF_CONTROL_DOWN, ControlMask }
-  };
+        // Search+Backspace -> Delete
+        {ui::VKEY_BACK, ui::EF_COMMAND_DOWN, ui::VKEY_DELETE, ui::EF_NONE},
+        // Search+Up -> Prior
+        {ui::VKEY_UP, ui::EF_COMMAND_DOWN, ui::VKEY_PRIOR, ui::EF_NONE},
+        // Search+Down -> Next
+        {ui::VKEY_DOWN, ui::EF_COMMAND_DOWN, ui::VKEY_NEXT, ui::EF_NONE},
+        // Search+Left -> Home
+        {ui::VKEY_LEFT, ui::EF_COMMAND_DOWN, ui::VKEY_HOME, ui::EF_NONE},
+        // Control+Search+Left -> Home
+        {ui::VKEY_LEFT, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN,
+         ui::VKEY_HOME, ui::EF_CONTROL_DOWN},
+        // Search+Right -> End
+        {ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN, ui::VKEY_END, ui::EF_NONE},
+        // Control+Search+Right -> End
+        {ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN,
+         ui::VKEY_END, ui::EF_CONTROL_DOWN},
+        // Search+Period -> Insert
+        {ui::VKEY_OEM_PERIOD, ui::EF_COMMAND_DOWN, ui::VKEY_INSERT,
+         ui::EF_NONE},
+        // Control+Search+Period -> Control+Insert
+        {ui::VKEY_OEM_PERIOD, ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN,
+         ui::VKEY_INSERT, ui::EF_CONTROL_DOWN}};
 
   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(chromeos_tests); ++i) {
-    EXPECT_EQ(GetExpectedResultAsString(chromeos_tests[i].output,
+    EXPECT_EQ(GetExpectedResultNumbered(i,
+                                        chromeos_tests[i].output,
                                         chromeos_tests[i].output_mods,
-                                        ui::ET_KEY_PRESSED,
-                                        chromeos_tests[i].output_native,
-                                        chromeos_tests[i].output_native_mods,
-                                        KeyPress),
-              GetRewrittenEventAsString(&rewriter,
+                                        ui::ET_KEY_PRESSED),
+              GetRewrittenEventNumbered(i,
+                                        &rewriter,
                                         chromeos_tests[i].input,
                                         chromeos_tests[i].input_mods,
-                                        ui::ET_KEY_PRESSED,
-                                        chromeos_tests[i].input_native,
-                                        chromeos_tests[i].input_native_mods));
+                                        ui::ET_KEY_PRESSED));
   }
 }
 
@@ -2031,214 +1176,126 @@
 
   struct {
     ui::KeyboardCode input;
-    KeyCode input_native;
-    unsigned int input_native_mods;
     unsigned int input_mods;
     ui::KeyboardCode output;
-    KeyCode output_native;
-    unsigned int output_native_mods;
     unsigned int output_mods;
   } tests[] = {
-    // F1 -> Back
-    { ui::VKEY_F1, keycode_f1_, 0, 0,
-      ui::VKEY_BROWSER_BACK, keycode_browser_back_, 0, 0 },
-    { ui::VKEY_F1, keycode_f1_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_BROWSER_BACK, keycode_browser_back_,
-      ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F1, keycode_f1_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_BROWSER_BACK, keycode_browser_back_,
-      Mod1Mask, ui::EF_ALT_DOWN },
-    // F2 -> Forward
-    { ui::VKEY_F2, keycode_f2_, 0, 0,
-      ui::VKEY_BROWSER_FORWARD, keycode_browser_forward_, 0, 0 },
-    { ui::VKEY_F2, keycode_f2_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_BROWSER_FORWARD, keycode_browser_forward_,
-      ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F2, keycode_f2_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_BROWSER_FORWARD, keycode_browser_forward_,
-      Mod1Mask, ui::EF_ALT_DOWN },
-    // F3 -> Refresh
-    { ui::VKEY_F3, keycode_f3_, 0, 0,
-      ui::VKEY_BROWSER_REFRESH, keycode_browser_refresh_, 0, 0 },
-    { ui::VKEY_F3, keycode_f3_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_BROWSER_REFRESH, keycode_browser_refresh_,
-      ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F3, keycode_f3_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_BROWSER_REFRESH, keycode_browser_refresh_,
-      Mod1Mask, ui::EF_ALT_DOWN },
-    // F4 -> Launch App 2
-    { ui::VKEY_F4, keycode_f4_, 0, 0,
-      ui::VKEY_MEDIA_LAUNCH_APP2, keycode_media_launch_app2_, 0, 0 },
-    { ui::VKEY_F4, keycode_f4_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_MEDIA_LAUNCH_APP2, keycode_media_launch_app2_,
-      ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F4, keycode_f4_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_MEDIA_LAUNCH_APP2, keycode_media_launch_app2_,
-      Mod1Mask, ui::EF_ALT_DOWN },
-    // F5 -> Launch App 1
-    { ui::VKEY_F5, keycode_f5_, 0, 0,
-      ui::VKEY_MEDIA_LAUNCH_APP1, keycode_media_launch_app1_, 0, 0 },
-    { ui::VKEY_F5, keycode_f5_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_MEDIA_LAUNCH_APP1, keycode_media_launch_app1_,
-      ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F5, keycode_f5_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_MEDIA_LAUNCH_APP1, keycode_media_launch_app1_,
-      Mod1Mask, ui::EF_ALT_DOWN },
-    // F6 -> Brightness down
-    { ui::VKEY_F6, keycode_f6_, 0, 0,
-      ui::VKEY_BRIGHTNESS_DOWN, keycode_brightness_down_, 0, 0 },
-    { ui::VKEY_F6, keycode_f6_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_BRIGHTNESS_DOWN, keycode_brightness_down_,
-      ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F6, keycode_f6_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_BRIGHTNESS_DOWN, keycode_brightness_down_,
-      Mod1Mask, ui::EF_ALT_DOWN },
-    // F7 -> Brightness up
-    { ui::VKEY_F7, keycode_f7_, 0, 0,
-      ui::VKEY_BRIGHTNESS_UP, keycode_brightness_up_, 0, 0 },
-    { ui::VKEY_F7, keycode_f7_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_BRIGHTNESS_UP, keycode_brightness_up_,
-      ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F7, keycode_f7_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_BRIGHTNESS_UP, keycode_brightness_up_,
-      Mod1Mask, ui::EF_ALT_DOWN },
-    // F8 -> Volume Mute
-    { ui::VKEY_F8, keycode_f8_, 0, 0,
-      ui::VKEY_VOLUME_MUTE, keycode_volume_mute_, 0, 0 },
-    { ui::VKEY_F8, keycode_f8_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_VOLUME_MUTE, keycode_volume_mute_,
-      ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F8, keycode_f8_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_VOLUME_MUTE, keycode_volume_mute_,
-      Mod1Mask, ui::EF_ALT_DOWN },
-    // F9 -> Volume Down
-    { ui::VKEY_F9, keycode_f9_, 0, 0,
-      ui::VKEY_VOLUME_DOWN, keycode_volume_down_, 0, 0 },
-    { ui::VKEY_F9, keycode_f9_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_VOLUME_DOWN, keycode_volume_down_,
-      ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F9, keycode_f9_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_VOLUME_DOWN, keycode_volume_down_,
-      Mod1Mask, ui::EF_ALT_DOWN },
-    // F10 -> Volume Up
-    { ui::VKEY_F10, keycode_f10_, 0, 0,
-      ui::VKEY_VOLUME_UP, keycode_volume_up_, 0, 0 },
-    { ui::VKEY_F10, keycode_f10_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_VOLUME_UP, keycode_volume_up_,
-      ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F10, keycode_f10_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_VOLUME_UP, keycode_volume_up_,
-      Mod1Mask, ui::EF_ALT_DOWN },
-    // F11 -> F11
-    { ui::VKEY_F11, keycode_f11_, 0, 0,
-      ui::VKEY_F11, keycode_f11_, 0, 0 },
-    { ui::VKEY_F11, keycode_f11_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_F11, keycode_f11_, ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F11, keycode_f11_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_F11, keycode_f11_, Mod1Mask, ui::EF_ALT_DOWN },
-    // F12 -> F12
-    { ui::VKEY_F12, keycode_f12_, 0, 0,
-      ui::VKEY_F12, keycode_f12_, 0, 0 },
-    { ui::VKEY_F12, keycode_f12_, ControlMask, ui::EF_CONTROL_DOWN,
-      ui::VKEY_F12, keycode_f12_, ControlMask, ui::EF_CONTROL_DOWN },
-    { ui::VKEY_F12, keycode_f12_, Mod1Mask, ui::EF_ALT_DOWN,
-      ui::VKEY_F12, keycode_f12_, Mod1Mask, ui::EF_ALT_DOWN },
+        // F1 -> Back
+        {ui::VKEY_F1, ui::EF_NONE, ui::VKEY_BROWSER_BACK, ui::EF_NONE},
+        {ui::VKEY_F1, ui::EF_CONTROL_DOWN, ui::VKEY_BROWSER_BACK,
+         ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F1, ui::EF_ALT_DOWN, ui::VKEY_BROWSER_BACK, ui::EF_ALT_DOWN},
+        // F2 -> Forward
+        {ui::VKEY_F2, ui::EF_NONE, ui::VKEY_BROWSER_FORWARD, ui::EF_NONE},
+        {ui::VKEY_F2, ui::EF_CONTROL_DOWN, ui::VKEY_BROWSER_FORWARD,
+         ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F2, ui::EF_ALT_DOWN, ui::VKEY_BROWSER_FORWARD,
+         ui::EF_ALT_DOWN},
+        // F3 -> Refresh
+        {ui::VKEY_F3, ui::EF_NONE, ui::VKEY_BROWSER_REFRESH, ui::EF_NONE},
+        {ui::VKEY_F3, ui::EF_CONTROL_DOWN, ui::VKEY_BROWSER_REFRESH,
+         ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F3, ui::EF_ALT_DOWN, ui::VKEY_BROWSER_REFRESH,
+         ui::EF_ALT_DOWN},
+        // F4 -> Launch App 2
+        {ui::VKEY_F4, ui::EF_NONE, ui::VKEY_MEDIA_LAUNCH_APP2, ui::EF_NONE},
+        {ui::VKEY_F4, ui::EF_CONTROL_DOWN, ui::VKEY_MEDIA_LAUNCH_APP2,
+         ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F4, ui::EF_ALT_DOWN, ui::VKEY_MEDIA_LAUNCH_APP2,
+         ui::EF_ALT_DOWN},
+        // F5 -> Launch App 1
+        {ui::VKEY_F5, ui::EF_NONE, ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_NONE},
+        {ui::VKEY_F5, ui::EF_CONTROL_DOWN, ui::VKEY_MEDIA_LAUNCH_APP1,
+         ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F5, ui::EF_ALT_DOWN, ui::VKEY_MEDIA_LAUNCH_APP1,
+         ui::EF_ALT_DOWN},
+        // F6 -> Brightness down
+        {ui::VKEY_F6, ui::EF_NONE, ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE},
+        {ui::VKEY_F6, ui::EF_CONTROL_DOWN, ui::VKEY_BRIGHTNESS_DOWN,
+         ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F6, ui::EF_ALT_DOWN, ui::VKEY_BRIGHTNESS_DOWN,
+         ui::EF_ALT_DOWN},
+        // F7 -> Brightness up
+        {ui::VKEY_F7, ui::EF_NONE, ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE},
+        {ui::VKEY_F7, ui::EF_CONTROL_DOWN, ui::VKEY_BRIGHTNESS_UP,
+         ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F7, ui::EF_ALT_DOWN, ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN},
+        // F8 -> Volume Mute
+        {ui::VKEY_F8, ui::EF_NONE, ui::VKEY_VOLUME_MUTE, ui::EF_NONE},
+        {ui::VKEY_F8, ui::EF_CONTROL_DOWN, ui::VKEY_VOLUME_MUTE,
+         ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F8, ui::EF_ALT_DOWN, ui::VKEY_VOLUME_MUTE, ui::EF_ALT_DOWN},
+        // F9 -> Volume Down
+        {ui::VKEY_F9, ui::EF_NONE, ui::VKEY_VOLUME_DOWN, ui::EF_NONE},
+        {ui::VKEY_F9, ui::EF_CONTROL_DOWN, ui::VKEY_VOLUME_DOWN,
+         ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F9, ui::EF_ALT_DOWN, ui::VKEY_VOLUME_DOWN, ui::EF_ALT_DOWN},
+        // F10 -> Volume Up
+        {ui::VKEY_F10, ui::EF_NONE, ui::VKEY_VOLUME_UP, ui::EF_NONE},
+        {ui::VKEY_F10, ui::EF_CONTROL_DOWN, ui::VKEY_VOLUME_UP,
+         ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F10, ui::EF_ALT_DOWN, ui::VKEY_VOLUME_UP, ui::EF_ALT_DOWN},
+        // F11 -> F11
+        {ui::VKEY_F11, ui::EF_NONE, ui::VKEY_F11, ui::EF_NONE},
+        {ui::VKEY_F11, ui::EF_CONTROL_DOWN, ui::VKEY_F11, ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F11, ui::EF_ALT_DOWN, ui::VKEY_F11, ui::EF_ALT_DOWN},
+        // F12 -> F12
+        {ui::VKEY_F12, ui::EF_NONE, ui::VKEY_F12, ui::EF_NONE},
+        {ui::VKEY_F12, ui::EF_CONTROL_DOWN, ui::VKEY_F12, ui::EF_CONTROL_DOWN},
+        {ui::VKEY_F12, ui::EF_ALT_DOWN, ui::VKEY_F12, ui::EF_ALT_DOWN},
 
-    // The number row should not be rewritten without Search key.
-    { ui::VKEY_1, keycode_1_, 0, 0,
-      ui::VKEY_1, keycode_1_, 0, 0 },
-    { ui::VKEY_2, keycode_2_, 0, 0,
-      ui::VKEY_2, keycode_2_, 0, 0 },
-    { ui::VKEY_3, keycode_3_, 0, 0,
-      ui::VKEY_3, keycode_3_, 0, 0 },
-    { ui::VKEY_4, keycode_4_, 0, 0,
-      ui::VKEY_4, keycode_4_, 0, 0 },
-    { ui::VKEY_5, keycode_5_, 0, 0,
-      ui::VKEY_5, keycode_5_, 0, 0 },
-    { ui::VKEY_6, keycode_6_, 0, 0,
-      ui::VKEY_6, keycode_6_, 0, 0 },
-    { ui::VKEY_7, keycode_7_, 0, 0,
-      ui::VKEY_7, keycode_7_, 0, 0 },
-    { ui::VKEY_8, keycode_8_, 0, 0,
-      ui::VKEY_8, keycode_8_, 0, 0 },
-    { ui::VKEY_9, keycode_9_, 0, 0,
-      ui::VKEY_9, keycode_9_, 0, 0 },
-    { ui::VKEY_0, keycode_0_, 0, 0,
-      ui::VKEY_0, keycode_0_, 0, 0 },
-    { ui::VKEY_OEM_MINUS, keycode_minus_, 0, 0,
-      ui::VKEY_OEM_MINUS, keycode_minus_, 0, 0 },
-    { ui::VKEY_OEM_PLUS, keycode_equal_, 0, 0,
-      ui::VKEY_OEM_PLUS, keycode_equal_, 0, 0 },
+        // The number row should not be rewritten without Search key.
+        {ui::VKEY_1, ui::EF_NONE, ui::VKEY_1, ui::EF_NONE},
+        {ui::VKEY_2, ui::EF_NONE, ui::VKEY_2, ui::EF_NONE},
+        {ui::VKEY_3, ui::EF_NONE, ui::VKEY_3, ui::EF_NONE},
+        {ui::VKEY_4, ui::EF_NONE, ui::VKEY_4, ui::EF_NONE},
+        {ui::VKEY_5, ui::EF_NONE, ui::VKEY_5, ui::EF_NONE},
+        {ui::VKEY_6, ui::EF_NONE, ui::VKEY_6, ui::EF_NONE},
+        {ui::VKEY_7, ui::EF_NONE, ui::VKEY_7, ui::EF_NONE},
+        {ui::VKEY_8, ui::EF_NONE, ui::VKEY_8, ui::EF_NONE},
+        {ui::VKEY_9, ui::EF_NONE, ui::VKEY_9, ui::EF_NONE},
+        {ui::VKEY_0, ui::EF_NONE, ui::VKEY_0, ui::EF_NONE},
+        {ui::VKEY_OEM_MINUS, ui::EF_NONE, ui::VKEY_OEM_MINUS, ui::EF_NONE},
+        {ui::VKEY_OEM_PLUS, ui::EF_NONE, ui::VKEY_OEM_PLUS, ui::EF_NONE},
 
-    // The number row should be rewritten as the F<number> row with Search key.
-    { ui::VKEY_1, keycode_1_, Mod4Mask, 0,
-      ui::VKEY_F1, keycode_f1_, 0, 0 },
-    { ui::VKEY_2, keycode_2_, Mod4Mask, 0,
-      ui::VKEY_F2, keycode_f2_, 0, 0 },
-    { ui::VKEY_3, keycode_3_, Mod4Mask, 0,
-      ui::VKEY_F3, keycode_f3_, 0, 0 },
-    { ui::VKEY_4, keycode_4_, Mod4Mask, 0,
-      ui::VKEY_F4, keycode_f4_, 0, 0 },
-    { ui::VKEY_5, keycode_5_, Mod4Mask, 0,
-      ui::VKEY_F5, keycode_f5_, 0, 0 },
-    { ui::VKEY_6, keycode_6_, Mod4Mask, 0,
-      ui::VKEY_F6, keycode_f6_, 0, 0 },
-    { ui::VKEY_7, keycode_7_, Mod4Mask, 0,
-      ui::VKEY_F7, keycode_f7_, 0, 0 },
-    { ui::VKEY_8, keycode_8_, Mod4Mask, 0,
-      ui::VKEY_F8, keycode_f8_, 0, 0 },
-    { ui::VKEY_9, keycode_9_, Mod4Mask, 0,
-      ui::VKEY_F9, keycode_f9_, 0, 0 },
-    { ui::VKEY_0, keycode_0_, Mod4Mask, 0,
-      ui::VKEY_F10, keycode_f10_, 0, 0 },
-    { ui::VKEY_OEM_MINUS, keycode_minus_, Mod4Mask, 0,
-      ui::VKEY_F11, keycode_f11_, 0, 0 },
-    { ui::VKEY_OEM_PLUS, keycode_equal_, Mod4Mask, 0,
-      ui::VKEY_F12, keycode_f12_, 0, 0 },
+        // The number row should be rewritten as the F<number> row with Search
+        // key.
+        {ui::VKEY_1, ui::EF_COMMAND_DOWN, ui::VKEY_F1, ui::EF_NONE},
+        {ui::VKEY_2, ui::EF_COMMAND_DOWN, ui::VKEY_F2, ui::EF_NONE},
+        {ui::VKEY_3, ui::EF_COMMAND_DOWN, ui::VKEY_F3, ui::EF_NONE},
+        {ui::VKEY_4, ui::EF_COMMAND_DOWN, ui::VKEY_F4, ui::EF_NONE},
+        {ui::VKEY_5, ui::EF_COMMAND_DOWN, ui::VKEY_F5, ui::EF_NONE},
+        {ui::VKEY_6, ui::EF_COMMAND_DOWN, ui::VKEY_F6, ui::EF_NONE},
+        {ui::VKEY_7, ui::EF_COMMAND_DOWN, ui::VKEY_F7, ui::EF_NONE},
+        {ui::VKEY_8, ui::EF_COMMAND_DOWN, ui::VKEY_F8, ui::EF_NONE},
+        {ui::VKEY_9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, ui::EF_NONE},
+        {ui::VKEY_0, ui::EF_COMMAND_DOWN, ui::VKEY_F10, ui::EF_NONE},
+        {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN, ui::VKEY_F11, ui::EF_NONE},
+        {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN, ui::VKEY_F12, ui::EF_NONE},
 
-    // The function keys should not be rewritten with Search key pressed.
-    { ui::VKEY_F1, keycode_f1_, Mod4Mask, 0,
-      ui::VKEY_F1, keycode_f1_, 0, 0 },
-    { ui::VKEY_F2, keycode_f2_, Mod4Mask, 0,
-      ui::VKEY_F2, keycode_f2_, 0, 0 },
-    { ui::VKEY_F3, keycode_f3_, Mod4Mask, 0,
-      ui::VKEY_F3, keycode_f3_, 0, 0 },
-    { ui::VKEY_F4, keycode_f4_, Mod4Mask, 0,
-      ui::VKEY_F4, keycode_f4_, 0, 0 },
-    { ui::VKEY_F5, keycode_f5_, Mod4Mask, 0,
-      ui::VKEY_F5, keycode_f5_, 0, 0 },
-    { ui::VKEY_F6, keycode_f6_, Mod4Mask, 0,
-      ui::VKEY_F6, keycode_f6_, 0, 0 },
-    { ui::VKEY_F7, keycode_f7_, Mod4Mask, 0,
-      ui::VKEY_F7, keycode_f7_, 0, 0 },
-    { ui::VKEY_F8, keycode_f8_, Mod4Mask, 0,
-      ui::VKEY_F8, keycode_f8_, 0, 0 },
-    { ui::VKEY_F9, keycode_f9_, Mod4Mask, 0,
-      ui::VKEY_F9, keycode_f9_, 0, 0 },
-    { ui::VKEY_F10, keycode_f10_, Mod4Mask, 0,
-      ui::VKEY_F10, keycode_f10_, 0, 0 },
-    { ui::VKEY_F11, keycode_f11_, Mod4Mask, 0,
-      ui::VKEY_F11, keycode_f11_, 0, 0 },
-    { ui::VKEY_F12, keycode_f12_, Mod4Mask, 0,
-      ui::VKEY_F12, keycode_f12_, 0, 0 },
-  };
+        // The function keys should not be rewritten with Search key pressed.
+        {ui::VKEY_F1, ui::EF_COMMAND_DOWN, ui::VKEY_F1, ui::EF_NONE},
+        {ui::VKEY_F2, ui::EF_COMMAND_DOWN, ui::VKEY_F2, ui::EF_NONE},
+        {ui::VKEY_F3, ui::EF_COMMAND_DOWN, ui::VKEY_F3, ui::EF_NONE},
+        {ui::VKEY_F4, ui::EF_COMMAND_DOWN, ui::VKEY_F4, ui::EF_NONE},
+        {ui::VKEY_F5, ui::EF_COMMAND_DOWN, ui::VKEY_F5, ui::EF_NONE},
+        {ui::VKEY_F6, ui::EF_COMMAND_DOWN, ui::VKEY_F6, ui::EF_NONE},
+        {ui::VKEY_F7, ui::EF_COMMAND_DOWN, ui::VKEY_F7, ui::EF_NONE},
+        {ui::VKEY_F8, ui::EF_COMMAND_DOWN, ui::VKEY_F8, ui::EF_NONE},
+        {ui::VKEY_F9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, ui::EF_NONE},
+        {ui::VKEY_F10, ui::EF_COMMAND_DOWN, ui::VKEY_F10, ui::EF_NONE},
+        {ui::VKEY_F11, ui::EF_COMMAND_DOWN, ui::VKEY_F11, ui::EF_NONE},
+        {ui::VKEY_F12, ui::EF_COMMAND_DOWN, ui::VKEY_F12, ui::EF_NONE},
+    };
 
   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
-    // XKeysymToKeycode returns zero for unknown keys. So ignore those.
-    if (tests[i].output_native == 0)
-      continue;
-    EXPECT_EQ(GetExpectedResultAsString(tests[i].output,
-                                        tests[i].output_mods,
-                                        ui::ET_KEY_PRESSED,
-                                        tests[i].output_native,
-                                        tests[i].output_native_mods,
-                                        KeyPress),
-              GetRewrittenEventAsString(&rewriter,
+    EXPECT_EQ(GetExpectedResultNumbered(
+                  i, tests[i].output, tests[i].output_mods, ui::ET_KEY_PRESSED),
+              GetRewrittenEventNumbered(i,
+                                        &rewriter,
                                         tests[i].input,
                                         tests[i].input_mods,
-                                        ui::ET_KEY_PRESSED,
-                                        tests[i].input_native,
-                                        tests[i].input_native_mods));
+                                        ui::ET_KEY_PRESSED));
   }
 }
 
@@ -2259,32 +1316,21 @@
       chromeos::switches::kHasChromeOSKeyboard, "");
 
   // Alt+Search+Down -> End
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_END,
-                                      0,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_end_,
-                                      0U,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_DOWN,
-                                      ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_down_,
-                                      Mod1Mask | Mod4Mask));
+  EXPECT_EQ(
+      GetExpectedResultAsString(ui::VKEY_END, ui::EF_NONE, ui::ET_KEY_PRESSED),
+      GetRewrittenEventAsString(&rewriter,
+                                ui::VKEY_DOWN,
+                                ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                                ui::ET_KEY_PRESSED));
 
   // Shift+Alt+Search+Down -> Shift+End
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_END,
-                                      ui::EF_SHIFT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_end_,
-                                      ShiftMask,
-                                      KeyPress),
-            GetRewrittenEventAsString(&rewriter,
-                                      ui::VKEY_DOWN,
-                                      ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_down_,
-                                      ShiftMask | Mod1Mask | Mod4Mask));
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_END, ui::EF_SHIFT_DOWN, ui::ET_KEY_PRESSED),
+            GetRewrittenEventAsString(
+                &rewriter,
+                ui::VKEY_DOWN,
+                ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN,
+                ui::ET_KEY_PRESSED));
 
   *CommandLine::ForCurrentProcess() = original_cl;
 }
@@ -2306,37 +1352,54 @@
     ui::ScopedXI2Event xev;
     xev.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, 0);
     XEvent* xevent = xev;
-    xevent->xkey.keycode = keycode_control_l_;
+    xevent->xkey.keycode = XKeysymToKeycode(gfx::GetXDisplay(), XK_Control_L);
     xevent->xkey.send_event = True;  // XSendEvent() always does this.
-    rewriter.RewriteForTesting(xevent);
     ui::KeyEvent keyevent(xev, false /* is_char */);
-    rewritten_event = base::StringPrintf(
-        "ui_keycode=%d ui_flags=%d ui_type=%d "
-        "x_keycode=%u x_state=%u x_type=%d",
-        keyevent.key_code(), keyevent.flags(), keyevent.type(),
-        xevent->xkey.keycode, xevent->xkey.state, xevent->xkey.type);
+    scoped_ptr<ui::Event> new_event;
+    // Control should NOT be remapped to Alt if send_event
+    // flag in the event is True.
+    EXPECT_EQ(ui::EVENT_REWRITE_CONTINUE,
+              rewriter.RewriteEvent(keyevent, &new_event));
+    EXPECT_FALSE(new_event);
   }
+}
 
-  // XK_Control_L (left Control key) should NOT be remapped to Alt if send_event
-  // flag in the event is True.
-  EXPECT_EQ(GetExpectedResultAsString(ui::VKEY_CONTROL,
-                                      ui::EF_CONTROL_DOWN,
-                                      ui::ET_KEY_PRESSED,
-                                      keycode_control_l_,
-                                      0U,
-                                      KeyPress),
-            rewritten_event);
+TEST_F(EventRewriterTest, TestRewriteNonNativeEvent) {
+  // Remap Control to Alt.
+  TestingPrefServiceSyncable prefs;
+  chromeos::Preferences::RegisterProfilePrefs(prefs.registry());
+  IntegerPrefMember control;
+  control.Init(prefs::kLanguageRemapControlKeyTo, &prefs);
+  control.SetValue(chromeos::input_method::kAltKey);
+
+  EventRewriter rewriter;
+  rewriter.set_pref_service_for_testing(&prefs);
+
+  const int kTouchId = 2;
+  gfx::Point location(0, 0);
+  ui::TouchEvent press(
+      ui::ET_TOUCH_PRESSED, location, kTouchId, base::TimeDelta());
+  press.set_flags(ui::EF_CONTROL_DOWN);
+
+  scoped_ptr<ui::Event> new_event;
+  rewriter.RewriteEvent(press, &new_event);
+  EXPECT_TRUE(new_event);
+  // Control should be remapped to Alt.
+  EXPECT_EQ(ui::EF_ALT_DOWN,
+            new_event->flags() & (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN));
 }
 
 // Tests of event rewriting that depend on the Ash window manager.
 class EventRewriterAshTest : public ash::test::AshTestBase {
  public:
-  EventRewriterAshTest() {
-  }
+  EventRewriterAshTest()
+      : mock_user_manager_(new chromeos::MockUserManager),
+        user_manager_enabler_(mock_user_manager_) {}
   virtual ~EventRewriterAshTest() {}
 
-  bool RewriteFunctionKeys(XEvent* event) {
-    return rewriter_->RewriteFunctionKeys(event);
+  bool RewriteFunctionKeys(const ui::Event& event,
+                           scoped_ptr<ui::Event>* rewritten_event) {
+    return rewriter_->RewriteEvent(event, rewritten_event);
   }
 
  protected:
@@ -2357,6 +1420,9 @@
  private:
   scoped_ptr<EventRewriter> rewriter_;
 
+  chromeos::MockUserManager* mock_user_manager_;  // Not owned.
+  chromeos::ScopedUserManagerEnabler user_manager_enabler_;
+
   DISALLOW_COPY_AND_ASSIGN(EventRewriterAshTest);
 };
 
@@ -2366,38 +1432,39 @@
   window_state->Activate();
 
   // Create a simulated keypress of F1 targetted at the window.
-  ui::ScopedXI2Event xev_f1;
-  KeyCode keycode_f1 = XKeysymToKeycode(gfx::GetXDisplay(), XK_F1);
-  xev_f1.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_F1, 0);
-  XEvent* xevent = xev_f1;
-  xevent->xkey.keycode = keycode_f1;
+  ui::KeyEvent press_f1(ui::ET_KEY_PRESSED, ui::VKEY_F1, 0, false);
 
   // Simulate an apps v2 window that has requested top row keys as function
   // keys. The event should not be rewritten.
   window_state->set_top_row_keys_are_function_keys(true);
-  ASSERT_FALSE(RewriteFunctionKeys(xevent));
-  ui::KeyEvent press_f1(xev_f1, false);
-  ASSERT_EQ(ui::VKEY_F1, press_f1.key_code());
+  scoped_ptr<ui::Event> rewritten_event;
+  ASSERT_FALSE(RewriteFunctionKeys(press_f1, &rewritten_event));
+  ASSERT_FALSE(rewritten_event);
+  EXPECT_EQ(
+      GetExpectedResultAsString(ui::VKEY_F1, ui::EF_NONE, ui::ET_KEY_PRESSED),
+      GetKeyEventAsString(press_f1));
 
   // The event should also not be rewritten if the send-function-keys pref is
   // additionally set, for both apps v2 and regular windows.
   BooleanPrefMember send_function_keys_pref;
   send_function_keys_pref.Init(prefs::kLanguageSendFunctionKeys, &prefs_);
   send_function_keys_pref.SetValue(true);
-  ASSERT_FALSE(RewriteFunctionKeys(xevent));
-  press_f1 = ui::KeyEvent(xev_f1, false);
-  ASSERT_EQ(ui::VKEY_F1, press_f1.key_code());
   window_state->set_top_row_keys_are_function_keys(false);
-  ASSERT_FALSE(RewriteFunctionKeys(xevent));
-  press_f1 = ui::KeyEvent(xev_f1, false);
-  ASSERT_EQ(ui::VKEY_F1, press_f1.key_code());
+  ASSERT_FALSE(RewriteFunctionKeys(press_f1, &rewritten_event));
+  ASSERT_FALSE(rewritten_event);
+  EXPECT_EQ(
+      GetExpectedResultAsString(ui::VKEY_F1, ui::EF_NONE, ui::ET_KEY_PRESSED),
+      GetKeyEventAsString(press_f1));
 
   // If the pref isn't set when an event is sent to a regular window, F1 is
   // rewritten to the back key.
   send_function_keys_pref.SetValue(false);
-  ASSERT_TRUE(RewriteFunctionKeys(xevent));
-  press_f1 = ui::KeyEvent(xev_f1, false);
-  ASSERT_EQ(ui::VKEY_BROWSER_BACK, press_f1.key_code());
+  ASSERT_TRUE(RewriteFunctionKeys(press_f1, &rewritten_event));
+  ASSERT_TRUE(rewritten_event);
+  EXPECT_EQ(GetExpectedResultAsString(
+                ui::VKEY_BROWSER_BACK, ui::EF_NONE, ui::ET_KEY_PRESSED),
+            GetKeyEventAsString(
+                *static_cast<const ui::KeyEvent*>(rewritten_event.get())));
 }
 
 TEST_F(EventRewriterTest, DontRewriteIfNotRewritten) {
@@ -2417,18 +1484,16 @@
     // Sanity check.
     EXPECT_EQ(ui::ET_MOUSE_PRESSED, press.type());
     EXPECT_EQ(kLeftAndAltFlag, press.flags());
-
-    RewriteMouseEvent(&rewriter, &press);
-
-    EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & press.flags());
+    int flags = RewriteMouseEvent(&rewriter, press);
+    EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & flags);
   }
   {
     ui::ScopedXI2Event xev;
     xev.InitGenericButtonEvent(
         10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
     ui::MouseEvent release(xev);
-    RewriteMouseEvent(&rewriter, &release);
-    EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & release.flags());
+    int flags = RewriteMouseEvent(&rewriter, release);
+    EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & flags);
   }
 
   // No ALT in frst click.
@@ -2437,17 +1502,16 @@
     xev.InitGenericButtonEvent(
         10, ui::ET_MOUSE_PRESSED, gfx::Point(), ui::EF_LEFT_MOUSE_BUTTON);
     ui::MouseEvent press(xev);
-    RewriteMouseEvent(&rewriter, &press);
-    EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & press.flags());
+    int flags = RewriteMouseEvent(&rewriter, press);
+    EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & flags);
   }
   {
     ui::ScopedXI2Event xev;
     xev.InitGenericButtonEvent(
         10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
     ui::MouseEvent release(xev);
-    RewriteMouseEvent(&rewriter, &release);
-    EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) &
-                release.flags());
+    int flags = RewriteMouseEvent(&rewriter, release);
+    EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & flags);
   }
 
   // ALT on different device.
@@ -2456,25 +1520,24 @@
     xev.InitGenericButtonEvent(
         11, ui::ET_MOUSE_PRESSED, gfx::Point(), kLeftAndAltFlag);
     ui::MouseEvent press(xev);
-    RewriteMouseEvent(&rewriter, &press);
-    EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & press.flags());
+    int flags = RewriteMouseEvent(&rewriter, press);
+    EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & flags);
   }
   {
     ui::ScopedXI2Event xev;
     xev.InitGenericButtonEvent(
         10, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
     ui::MouseEvent release(xev);
-    RewriteMouseEvent(&rewriter, &release);
-    EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) &
-                release.flags());
+    int flags = RewriteMouseEvent(&rewriter, release);
+    EXPECT_TRUE((ui::EF_LEFT_MOUSE_BUTTON | ui::EF_ALT_DOWN) & flags);
   }
   {
     ui::ScopedXI2Event xev;
     xev.InitGenericButtonEvent(
         11, ui::ET_MOUSE_RELEASED, gfx::Point(), kLeftAndAltFlag);
     ui::MouseEvent release(xev);
-    RewriteMouseEvent(&rewriter, &release);
-    EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & release.flags());
+    int flags = RewriteMouseEvent(&rewriter, release);
+    EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & flags);
   }
 }
 
diff --git a/chrome/browser/chromeos/extensions/echo_private_api.cc b/chrome/browser/chromeos/extensions/echo_private_api.cc
index 1ebc5f0..230c636 100644
--- a/chrome/browser/chromeos/extensions/echo_private_api.cc
+++ b/chrome/browser/chromeos/extensions/echo_private_api.cc
@@ -150,7 +150,7 @@
 EchoPrivateGetOobeTimestampFunction::~EchoPrivateGetOobeTimestampFunction() {
 }
 
-bool EchoPrivateGetOobeTimestampFunction::RunImpl() {
+bool EchoPrivateGetOobeTimestampFunction::RunAsync() {
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::FILE, FROM_HERE,
       base::Bind(
@@ -199,7 +199,7 @@
 
 EchoPrivateGetUserConsentFunction::~EchoPrivateGetUserConsentFunction() {}
 
-bool EchoPrivateGetUserConsentFunction::RunImpl() {
+bool EchoPrivateGetUserConsentFunction::RunAsync() {
    CheckRedeemOffersAllowed();
    return true;
 }
diff --git a/chrome/browser/chromeos/extensions/echo_private_api.h b/chrome/browser/chromeos/extensions/echo_private_api.h
index 2ec5bc7..20ea9ca 100644
--- a/chrome/browser/chromeos/extensions/echo_private_api.h
+++ b/chrome/browser/chromeos/extensions/echo_private_api.h
@@ -46,7 +46,7 @@
 
  protected:
   virtual ~EchoPrivateGetOobeTimestampFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   bool GetOobeTimestampOnFileThread();
@@ -102,7 +102,7 @@
  protected:
   virtual ~EchoPrivateGetUserConsentFunction();
 
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // chromeos::EchoDialogListener overrides.
diff --git a/chrome/browser/chromeos/extensions/external_cache.cc b/chrome/browser/chromeos/extensions/external_cache.cc
index 5b547a4..fc7774a 100644
--- a/chrome/browser/chromeos/extensions/external_cache.cc
+++ b/chrome/browser/chromeos/extensions/external_cache.cc
@@ -108,6 +108,18 @@
   LOG(ERROR) << "ExternalCache cannot find external_crx " << path.value();
 }
 
+void ExternalCache::RemoveExtensions(const std::vector<std::string>& ids) {
+  if (ids.empty())
+    return;
+
+  for (size_t i = 0; i < ids.size(); ++i) {
+    cached_extensions_->Remove(ids[i], NULL);
+    extensions_->Remove(ids[i], NULL);
+    local_cache_.RemoveExtension(ids[i]);
+  }
+  UpdateExtensionLoader();
+}
+
 void ExternalCache::Observe(int type,
                             const content::NotificationSource& source,
                             const content::NotificationDetails& details) {
@@ -133,10 +145,14 @@
     if (!cached_extensions_->HasKey(id)) {
       LOG(ERROR) << "ExternalCache extension " << id
                  << " not found on update server";
+      delegate_->OnExtensionDownloadFailed(id, error);
+    } else {
+      delegate_->OnExtensionLoadedInCache(id);
     }
   } else {
     LOG(ERROR) << "ExternalCache failed to download extension " << id
                << ", error " << error;
+    delegate_->OnExtensionDownloadFailed(id, error);
   }
 }
 
@@ -293,6 +309,8 @@
                    file_path.value());
 
   cached_extensions_->Set(id, entry);
+  if (delegate_)
+    delegate_->OnExtensionLoadedInCache(id);
   UpdateExtensionLoader();
 }
 
diff --git a/chrome/browser/chromeos/extensions/external_cache.h b/chrome/browser/chromeos/extensions/external_cache.h
index 7fa81fe..83834a0 100644
--- a/chrome/browser/chromeos/extensions/external_cache.h
+++ b/chrome/browser/chromeos/extensions/external_cache.h
@@ -44,6 +44,12 @@
     // Caller owns |prefs|.
     virtual void OnExtensionListsUpdated(
         const base::DictionaryValue* prefs) = 0;
+    // Called after extension with |id| is loaded in cache.
+    virtual void OnExtensionLoadedInCache(const std::string& id) {}
+    // Called when extension with |id| is failed with downloading for |error|.
+    virtual void OnExtensionDownloadFailed(
+        const std::string& id,
+        extensions::ExtensionDownloaderDelegate::Error error) {}
 
     // Cache needs to provide already installed extensions otherwise they
     // will be removed. Cache calls this function to get version of installed
@@ -110,6 +116,10 @@
   // the cache and retry to download it after a restart.
   void OnDamagedFileDetected(const base::FilePath& path);
 
+  // Removes extensions listed in |ids| from external cache, corresponding crx
+  // files will be removed from disk too.
+  void RemoveExtensions(const std::vector<std::string>& ids);
+
  private:
   // Notifies the that the cache has been updated, providing
   // extensions loader with an updated list of extensions.
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.cc b/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.cc
index f80e275..bdf207e 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.cc
@@ -284,7 +284,7 @@
 FileBrowserHandlerInternalSelectFileFunction::
     ~FileBrowserHandlerInternalSelectFileFunction() {}
 
-bool FileBrowserHandlerInternalSelectFileFunction::RunImpl() {
+bool FileBrowserHandlerInternalSelectFileFunction::RunAsync() {
   scoped_ptr<SelectFile::Params> params(SelectFile::Params::Create(*args_));
 
   base::FilePath suggested_name(params->selection_params.suggested_name);
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.h b/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.h
index 472782f..e130ae7 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.h
+++ b/chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.h
@@ -110,7 +110,7 @@
 
   // AsyncExtensionFunction implementation.
   // Runs the extension function implementation.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Respond to the API with selected entry definition.
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_dialog.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_dialog.cc
index a96a1fc..375a7bd 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_dialog.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_dialog.cc
@@ -25,14 +25,14 @@
 
 }  // namespace
 
-bool FileBrowserPrivateCancelDialogFunction::RunImpl() {
+bool FileBrowserPrivateCancelDialogFunction::RunAsync() {
   SelectFileDialogExtension::OnFileSelectionCanceled(
       GetFileDialogRoutingID(this));
   SendResponse(true);
   return true;
 }
 
-bool FileBrowserPrivateSelectFileFunction::RunImpl() {
+bool FileBrowserPrivateSelectFileFunction::RunAsync() {
   using extensions::api::file_browser_private::SelectFile::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -73,7 +73,7 @@
   SendResponse(true);
 }
 
-bool FileBrowserPrivateSelectFilesFunction::RunImpl() {
+bool FileBrowserPrivateSelectFilesFunction::RunAsync() {
   using extensions::api::file_browser_private::SelectFiles::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_dialog.h b/chrome/browser/chromeos/extensions/file_manager/private_api_dialog.h
index 899f047..c333a15 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_dialog.h
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_dialog.h
@@ -29,7 +29,7 @@
   virtual ~FileBrowserPrivateCancelDialogFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class FileBrowserPrivateSelectFileFunction
@@ -42,7 +42,7 @@
   virtual ~FileBrowserPrivateSelectFileFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // A callback method to handle the result of GetSelectedFileInfo.
@@ -62,7 +62,7 @@
   virtual ~FileBrowserPrivateSelectFilesFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // A callback method to handle the result of GetSelectedFileInfo.
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
index f5f1528..52dd4eb 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -349,7 +349,7 @@
 FileBrowserPrivateGetDriveEntryPropertiesFunction::
     ~FileBrowserPrivateGetDriveEntryPropertiesFunction() {}
 
-bool FileBrowserPrivateGetDriveEntryPropertiesFunction::RunImpl() {
+bool FileBrowserPrivateGetDriveEntryPropertiesFunction::RunAsync() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   using api::file_browser_private::GetDriveEntryProperties::Params;
@@ -390,7 +390,7 @@
   SendResponse(true);
 }
 
-bool FileBrowserPrivatePinDriveFileFunction::RunImpl() {
+bool FileBrowserPrivatePinDriveFileFunction::RunAsync() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   using extensions::api::file_browser_private::PinDriveFile::Params;
@@ -437,7 +437,7 @@
     ~FileBrowserPrivateGetDriveFilesFunction() {
 }
 
-bool FileBrowserPrivateGetDriveFilesFunction::RunImpl() {
+bool FileBrowserPrivateGetDriveFilesFunction::RunAsync() {
   using extensions::api::file_browser_private::GetDriveFiles::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -503,7 +503,7 @@
   GetFileOrSendResponse();
 }
 
-bool FileBrowserPrivateCancelFileTransfersFunction::RunImpl() {
+bool FileBrowserPrivateCancelFileTransfersFunction::RunAsync() {
   using extensions::api::file_browser_private::CancelFileTransfers::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -557,7 +557,7 @@
   return true;
 }
 
-bool FileBrowserPrivateSearchDriveFunction::RunImpl() {
+bool FileBrowserPrivateSearchDriveFunction::RunAsync() {
   using extensions::api::file_browser_private::SearchDrive::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -626,7 +626,7 @@
   SendResponse(true);
 }
 
-bool FileBrowserPrivateSearchDriveMetadataFunction::RunImpl() {
+bool FileBrowserPrivateSearchDriveMetadataFunction::RunAsync() {
   using api::file_browser_private::SearchDriveMetadata::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -770,7 +770,7 @@
   return true;
 }
 
-bool FileBrowserPrivateRequestAccessTokenFunction::RunImpl() {
+bool FileBrowserPrivateRequestAccessTokenFunction::RunAsync() {
   using extensions::api::file_browser_private::RequestAccessToken::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -804,7 +804,7 @@
   SendResponse(true);
 }
 
-bool FileBrowserPrivateGetShareUrlFunction::RunImpl() {
+bool FileBrowserPrivateGetShareUrlFunction::RunAsync() {
   using extensions::api::file_browser_private::GetShareUrl::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -842,7 +842,7 @@
   SendResponse(true);
 }
 
-bool FileBrowserPrivateRequestDriveShareFunction::RunImpl() {
+bool FileBrowserPrivateRequestDriveShareFunction::RunAsync() {
   using extensions::api::file_browser_private::RequestDriveShare::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.h b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.h
index f666c90..b3eec92 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.h
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.h
@@ -41,7 +41,7 @@
   virtual ~FileBrowserPrivateGetDriveEntryPropertiesFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void CompleteGetFileProperties(drive::FileError error);
@@ -62,10 +62,10 @@
   virtual ~FileBrowserPrivatePinDriveFileFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
-  // Callback for RunImpl().
+  // Callback for RunAsync().
   void OnPinStateSet(drive::FileError error);
 };
 
@@ -89,7 +89,7 @@
   virtual ~FileBrowserPrivateGetDriveFilesFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Gets the file on the top of the |remaining_drive_paths_| or sends the
@@ -117,7 +117,7 @@
   virtual ~FileBrowserPrivateCancelFileTransfersFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class FileBrowserPrivateSearchDriveFunction
@@ -131,7 +131,7 @@
  protected:
   virtual ~FileBrowserPrivateSearchDriveFunction() {}
 
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Callback for Search().
@@ -159,7 +159,7 @@
  protected:
   virtual ~FileBrowserPrivateSearchDriveMetadataFunction() {}
 
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Callback for SearchMetadata();
@@ -199,7 +199,7 @@
   virtual ~FileBrowserPrivateRequestAccessTokenFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Callback with a cached auth token (if available) or a fetched one.
   void OnAccessTokenFetched(google_apis::GDataErrorCode code,
@@ -217,7 +217,7 @@
   virtual ~FileBrowserPrivateGetShareUrlFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Callback with an url to the sharing dialog as |share_url|, called by
   // FileSystem::GetShareUrl.
@@ -233,7 +233,7 @@
 
  protected:
   virtual ~FileBrowserPrivateRequestDriveShareFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Called back after the drive file system operation is finished.
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
index 0edaaaf..d150dcb 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -258,7 +258,7 @@
   return true;
 }
 
-bool FileBrowserPrivateRequestFileSystemFunction::RunImpl() {
+bool FileBrowserPrivateRequestFileSystemFunction::RunAsync() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   using extensions::api::file_browser_private::RequestFileSystem::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
@@ -340,7 +340,7 @@
   SendResponse(success);
 }
 
-bool FileWatchFunctionBase::RunImpl() {
+bool FileWatchFunctionBase::RunAsync() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   if (!render_view_host() || !render_view_host()->GetProcess())
@@ -394,7 +394,7 @@
   Respond(true);
 }
 
-bool FileBrowserPrivateGetSizeStatsFunction::RunImpl() {
+bool FileBrowserPrivateGetSizeStatsFunction::RunAsync() {
   using extensions::api::file_browser_private::GetSizeStats::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -469,7 +469,7 @@
   SendResponse(true);
 }
 
-bool FileBrowserPrivateValidatePathNameLengthFunction::RunImpl() {
+bool FileBrowserPrivateValidatePathNameLengthFunction::RunAsync() {
   using extensions::api::file_browser_private::ValidatePathNameLength::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -508,7 +508,7 @@
   SendResponse(true);
 }
 
-bool FileBrowserPrivateFormatVolumeFunction::RunImpl() {
+bool FileBrowserPrivateFormatVolumeFunction::RunAsync() {
   using extensions::api::file_browser_private::FormatVolume::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -529,7 +529,7 @@
   return true;
 }
 
-bool FileBrowserPrivateStartCopyFunction::RunImpl() {
+bool FileBrowserPrivateStartCopyFunction::RunAsync() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   using  extensions::api::file_browser_private::StartCopy::Params;
@@ -578,7 +578,7 @@
   SendResponse(true);
 }
 
-bool FileBrowserPrivateCancelCopyFunction::RunImpl() {
+bool FileBrowserPrivateCancelCopyFunction::RunAsync() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   using  extensions::api::file_browser_private::CancelCopy::Params;
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h
index b3d4280..6209105 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h
@@ -42,7 +42,7 @@
   virtual ~FileBrowserPrivateRequestFileSystemFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void RespondSuccessOnUIThread(const std::string& name,
@@ -81,7 +81,7 @@
       const std::string& extension_id) = 0;
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Calls SendResponse() with |success| converted to base::Value.
   void Respond(bool success);
@@ -133,7 +133,7 @@
   virtual ~FileBrowserPrivateGetSizeStatsFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void GetDriveAvailableSpaceCallback(drive::FileError error,
@@ -157,7 +157,7 @@
   void OnFilePathLimitRetrieved(size_t current_length, size_t max_length);
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 // Implements the chrome.fileBrowserPrivate.formatVolume method.
@@ -172,7 +172,7 @@
   virtual ~FileBrowserPrivateFormatVolumeFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 // Implements the chrome.fileBrowserPrivate.startCopy method.
@@ -186,10 +186,10 @@
   virtual ~FileBrowserPrivateStartCopyFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
-  // Part of RunImpl(). Called after Copy() is started on IO thread.
+  // Part of RunAsync(). Called after Copy() is started on IO thread.
   void RunAfterStartCopy(int operation_id);
 };
 
@@ -204,7 +204,7 @@
   virtual ~FileBrowserPrivateCancelCopyFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
index da77c42..ce1e3af 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h"
 #include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
 #include "chrome/browser/chromeos/file_manager/app_installer.h"
+#include "chrome/browser/chromeos/file_manager/zip_file_creator.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/drive/event_logger.h"
@@ -167,7 +168,7 @@
 FileBrowserPrivateZipSelectionFunction::
     ~FileBrowserPrivateZipSelectionFunction() {}
 
-bool FileBrowserPrivateZipSelectionFunction::RunImpl() {
+bool FileBrowserPrivateZipSelectionFunction::RunAsync() {
   using extensions::api::file_browser_private::ZipSelection::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -215,22 +216,17 @@
     src_relative_paths.push_back(relative_path);
   }
 
-  zip_file_creator_ = new file_manager::ZipFileCreator(this,
-                                                       src_dir,
-                                                       src_relative_paths,
-                                                       dest_file);
-
-  // Keep the refcount until the zipping is complete on utility process.
-  AddRef();
-
-  zip_file_creator_->Start();
+  (new file_manager::ZipFileCreator(
+       base::Bind(&FileBrowserPrivateZipSelectionFunction::OnZipDone, this),
+       src_dir,
+       src_relative_paths,
+       dest_file))->Start();
   return true;
 }
 
 void FileBrowserPrivateZipSelectionFunction::OnZipDone(bool success) {
   SetResult(new base::FundamentalValue(success));
   SendResponse(true);
-  Release();
 }
 
 bool FileBrowserPrivateZoomFunction::RunSync() {
@@ -257,7 +253,7 @@
   return true;
 }
 
-bool FileBrowserPrivateInstallWebstoreItemFunction::RunImpl() {
+bool FileBrowserPrivateInstallWebstoreItemFunction::RunAsync() {
   using extensions::api::file_browser_private::InstallWebstoreItem::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -312,7 +308,7 @@
     ~FileBrowserPrivateRequestWebStoreAccessTokenFunction() {
 }
 
-bool FileBrowserPrivateRequestWebStoreAccessTokenFunction::RunImpl() {
+bool FileBrowserPrivateRequestWebStoreAccessTokenFunction::RunAsync() {
   std::vector<std::string> scopes;
   scopes.push_back(kCWSScope);
 
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h
index 85b55d7..d6f4a59 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.h
@@ -9,7 +9,6 @@
 #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_MISC_H_
 
 #include "chrome/browser/chromeos/extensions/file_manager/private_api_base.h"
-#include "chrome/browser/chromeos/file_manager/zip_file_creator.h"
 #include "google_apis/drive/gdata_errorcode.h"
 
 namespace google_apis {
@@ -64,8 +63,7 @@
 // Implements the chrome.fileBrowserPrivate.zipSelection method.
 // Creates a zip file for the selected files.
 class FileBrowserPrivateZipSelectionFunction
-    : public LoggedAsyncExtensionFunction,
-      public file_manager::ZipFileCreator::Observer {
+    : public LoggedAsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.zipSelection",
                              FILEBROWSERPRIVATE_ZIPSELECTION)
@@ -76,13 +74,10 @@
   virtual ~FileBrowserPrivateZipSelectionFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
-  // extensions::ZipFileCreator::Delegate overrides.
-  virtual void OnZipDone(bool success) OVERRIDE;
-
- private:
-  scoped_refptr<file_manager::ZipFileCreator> zip_file_creator_;
+  // Receives the result from ZipFileCreator.
+  void OnZipDone(bool success);
 };
 
 // Implements the chrome.fileBrowserPrivate.zoom method.
@@ -112,7 +107,7 @@
   virtual ~FileBrowserPrivateInstallWebstoreItemFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void OnInstallComplete(bool success, const std::string& error);
 
  private:
@@ -129,7 +124,7 @@
 
  protected:
   virtual ~FileBrowserPrivateRequestWebStoreAccessTokenFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   scoped_ptr<google_apis::AuthServiceInterface> auth_service_;
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc
index 16fa5ac..e30dd19 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc
@@ -25,7 +25,7 @@
 
 namespace extensions {
 
-bool FileBrowserPrivateAddMountFunction::RunImpl() {
+bool FileBrowserPrivateAddMountFunction::RunAsync() {
   using file_browser_private::AddMount::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -89,7 +89,7 @@
       chromeos::MOUNT_TYPE_ARCHIVE);
 }
 
-bool FileBrowserPrivateRemoveMountFunction::RunImpl() {
+bool FileBrowserPrivateRemoveMountFunction::RunAsync() {
   using file_browser_private::RemoveMount::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -143,7 +143,7 @@
   return true;
 }
 
-bool FileBrowserPrivateGetVolumeMetadataListFunction::RunImpl() {
+bool FileBrowserPrivateGetVolumeMetadataListFunction::RunAsync() {
   if (args_->GetSize())
     return false;
 
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_mount.h b/chrome/browser/chromeos/extensions/file_manager/private_api_mount.h
index b66f8e0..69c2d9d 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_mount.h
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_mount.h
@@ -30,11 +30,11 @@
   virtual ~FileBrowserPrivateAddMountFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Part of Run(). Called after MarkCacheFielAsMounted for Drive File System.
-  // (or directly called from RunImpl() for other file system).
+  // (or directly called from RunAsync() for other file system).
   void RunAfterMarkCacheFileAsMounted(const base::FilePath& display_name,
                                       drive::FileError error,
                                       const base::FilePath& file_path);
@@ -52,7 +52,7 @@
   virtual ~FileBrowserPrivateRemoveMountFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 // Implements chrome.fileBrowserPrivate.getVolumeMetadataList method.
@@ -66,7 +66,7 @@
   virtual ~FileBrowserPrivateGetVolumeMetadataListFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
index 3b84c16..95ccaf0 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
@@ -226,6 +226,8 @@
   SET_STRING("RENAME_BUTTON_LABEL", IDS_FILE_BROWSER_RENAME_BUTTON_LABEL);
   SET_STRING("DELETE_BUTTON_LABEL", IDS_FILE_BROWSER_DELETE_BUTTON_LABEL);
   SET_STRING("PASTE_BUTTON_LABEL", IDS_FILE_BROWSER_PASTE_BUTTON_LABEL);
+  SET_STRING("PASTE_INTO_FOLDER_BUTTON_LABEL",
+             IDS_FILE_BROWSER_PASTE_INTO_FOLDER_BUTTON_LABEL);
 
   SET_STRING("COPY_BUTTON_LABEL", IDS_FILE_BROWSER_COPY_BUTTON_LABEL);
   SET_STRING("CUT_BUTTON_LABEL", IDS_FILE_BROWSER_CUT_BUTTON_LABEL);
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc
index 0e703c5..e2cb9fe 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.cc
@@ -87,7 +87,7 @@
 
 }  // namespace
 
-bool FileBrowserPrivateExecuteTaskFunction::RunImpl() {
+bool FileBrowserPrivateExecuteTaskFunction::RunAsync() {
   using extensions::api::file_browser_private::ExecuteTask::Params;
   using extensions::api::file_browser_private::ExecuteTask::Results::Create;
   const scoped_ptr<Params> params(Params::Create(*args_));
@@ -146,7 +146,7 @@
                extensions::api::file_browser_private::TASK_RESULT_FAILED);
 }
 
-bool FileBrowserPrivateGetFileTasksFunction::RunImpl() {
+bool FileBrowserPrivateGetFileTasksFunction::RunAsync() {
   using extensions::api::file_browser_private::GetFileTasks::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.h b/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.h
index 0c9f027..6f0a75e 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.h
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_tasks.h
@@ -26,7 +26,7 @@
   virtual ~FileBrowserPrivateExecuteTaskFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnTaskExecuted(
@@ -44,7 +44,7 @@
   virtual ~FileBrowserPrivateGetFileTasksFunction() {}
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnSniffingMimeTypeCompleted(
diff --git a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.cc b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.cc
index 1bbd5c5..d080d52 100644
--- a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.cc
+++ b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/memory/scoped_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
 #include "chrome/browser/chromeos/file_system_provider/request_manager.h"
@@ -15,80 +16,10 @@
 #include "chrome/common/extensions/api/file_system_provider_internal.h"
 
 using chromeos::file_system_provider::ProvidedFileSystemInterface;
-using chromeos::file_system_provider::RequestManager;
 using chromeos::file_system_provider::RequestValue;
 using chromeos::file_system_provider::Service;
 
 namespace extensions {
-namespace {
-
-// Error names from
-// http://www.w3.org/TR/file-system-api/#errors-and-exceptions
-const char kNotFoundErrorName[] = "NotFoundError";
-const char kSecurityErrorName[] = "SecurityError";
-
-// Error messages.
-const char kEmptyNameErrorMessage[] = "Empty display name is not allowed.";
-const char kMountFailedErrorMessage[] = "Mounting the file system failed.";
-const char kUnmountFailedErrorMessage[] = "Unmounting the file system failed.";
-const char kResponseFailedErrorMessage[] =
-    "Sending a response for the request failed.";
-
-// Creates a dictionary, which looks like a DOMError. The returned dictionary
-// will be converted to a real DOMError object in
-// file_system_provier_custom_bindings.js.
-base::DictionaryValue* CreateError(const std::string& name,
-                                   const std::string& message) {
-  base::DictionaryValue* error = new base::DictionaryValue();
-  error->SetString("name", name);
-  error->SetString("message", message);
-  return error;
-}
-
-// Converts ProviderError to base::File::Error. This could be redundant, if it
-// was possible to create DOMError instances in Javascript easily.
-base::File::Error ProviderErrorToFileError(
-    api::file_system_provider::ProviderError error) {
-  switch (error) {
-    case api::file_system_provider::PROVIDER_ERROR_OK:
-      return base::File::FILE_OK;
-    case api::file_system_provider::PROVIDER_ERROR_IN_USE:
-      return base::File::FILE_ERROR_IN_USE;
-    case api::file_system_provider::PROVIDER_ERROR_EXISTS:
-      return base::File::FILE_ERROR_EXISTS;
-    case api::file_system_provider::PROVIDER_ERROR_NOT_FOUND:
-      return base::File::FILE_ERROR_NOT_FOUND;
-    case api::file_system_provider::PROVIDER_ERROR_ACCESS_DENIED:
-      return base::File::FILE_ERROR_ACCESS_DENIED;
-    case api::file_system_provider::PROVIDER_ERROR_TOO_MANY_OPENED:
-      return base::File::FILE_ERROR_TOO_MANY_OPENED;
-    case api::file_system_provider::PROVIDER_ERROR_NO_MEMORY:
-      return base::File::FILE_ERROR_NO_MEMORY;
-    case api::file_system_provider::PROVIDER_ERROR_NO_SPACE:
-      return base::File::FILE_ERROR_NO_SPACE;
-    case api::file_system_provider::PROVIDER_ERROR_NOT_A_DIRECTORY:
-      return base::File::FILE_ERROR_NOT_A_DIRECTORY;
-    case api::file_system_provider::PROVIDER_ERROR_INVALID_OPERATION:
-      return base::File::FILE_ERROR_INVALID_OPERATION;
-    case api::file_system_provider::PROVIDER_ERROR_SECURITY:
-      return base::File::FILE_ERROR_SECURITY;
-    case api::file_system_provider::PROVIDER_ERROR_ABORT:
-      return base::File::FILE_ERROR_ABORT;
-    case api::file_system_provider::PROVIDER_ERROR_NOT_A_FILE:
-      return base::File::FILE_ERROR_NOT_A_FILE;
-    case api::file_system_provider::PROVIDER_ERROR_NOT_EMPTY:
-      return base::File::FILE_ERROR_NOT_EMPTY;
-    case api::file_system_provider::PROVIDER_ERROR_INVALID_URL:
-      return base::File::FILE_ERROR_INVALID_URL;
-    case api::file_system_provider::PROVIDER_ERROR_IO:
-      return base::File::FILE_ERROR_IO;
-    default:
-      NOTREACHED();
-  }
-  return base::File::FILE_ERROR_FAILED;
-}
-
-}  // namespace
 
 bool FileSystemProviderMountFunction::RunSync() {
   using api::file_system_provider::Mount::Params;
@@ -107,6 +38,8 @@
 
   Service* service = Service::Get(GetProfile());
   DCHECK(service);
+  if (!service)
+    return false;
 
   int file_system_id =
       service->MountFileSystem(extension_id(), params->display_name);
@@ -132,11 +65,13 @@
 
 bool FileSystemProviderUnmountFunction::RunSync() {
   using api::file_system_provider::Unmount::Params;
-  const scoped_ptr<Params> params(Params::Create(*args_));
+  scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
 
   Service* service = Service::Get(GetProfile());
   DCHECK(service);
+  if (!service)
+    return false;
 
   if (!service->UnmountFileSystem(extension_id(), params->file_system_id)) {
     // TODO(mtomasz): Pass more detailed errors, rather than just a bool.
@@ -151,78 +86,66 @@
   return true;
 }
 
-bool FileSystemProviderInternalUnmountRequestedSuccessFunction::RunSync() {
+bool FileSystemProviderInternalUnmountRequestedSuccessFunction::RunWhenValid() {
   using api::file_system_provider_internal::UnmountRequestedSuccess::Params;
   scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
 
-  Service* service = Service::Get(GetProfile());
-  DCHECK(service);
-
-  ProvidedFileSystemInterface* file_system =
-      service->GetProvidedFileSystem(extension_id(), params->file_system_id);
-  if (!file_system) {
-    base::ListValue* result = new base::ListValue();
-    result->Append(
-        CreateError(kNotFoundErrorName, kResponseFailedErrorMessage));
-    SetResult(result);
-    return true;
-  }
-
-  RequestManager* request_manager = file_system->GetRequestManager();
-  DCHECK(request_manager);
-
-  const int request_id = params->request_id;
-  if (!request_manager->FulfillRequest(
-          request_id,
-          RequestValue::CreateForUnmountSuccess(params.Pass()),
-          false /* has_more */)) {
-    // TODO(mtomasz): Pass more detailed errors, rather than just a bool.
-    base::ListValue* result = new base::ListValue();
-    result->Append(
-        CreateError(kSecurityErrorName, kResponseFailedErrorMessage));
-    SetResult(result);
-    return true;
-  }
-
-  base::ListValue* result = new base::ListValue();
-  SetResult(result);
+  FulfillRequest(RequestValue::CreateForUnmountSuccess(params.Pass()),
+                 false /* has_more */);
   return true;
 }
 
-bool FileSystemProviderInternalUnmountRequestedErrorFunction::RunSync() {
+bool FileSystemProviderInternalUnmountRequestedErrorFunction::RunWhenValid() {
   using api::file_system_provider_internal::UnmountRequestedError::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
 
-  Service* service = Service::Get(GetProfile());
-  DCHECK(service);
+  RejectRequest(ProviderErrorToFileError(params->error));
+  return true;
+}
 
-  ProvidedFileSystemInterface* file_system =
-      service->GetProvidedFileSystem(extension_id(), params->file_system_id);
-  if (!file_system) {
-    base::ListValue* result = new base::ListValue();
-    result->Append(
-        CreateError(kNotFoundErrorName, kResponseFailedErrorMessage));
-    SetResult(result);
-    return true;
-  }
+bool
+FileSystemProviderInternalGetMetadataRequestedSuccessFunction::RunWhenValid() {
+  using api::file_system_provider_internal::GetMetadataRequestedSuccess::Params;
+  scoped_ptr<Params> params(Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params);
 
-  RequestManager* request_manager = file_system->GetRequestManager();
-  DCHECK(request_manager);
+  FulfillRequest(RequestValue::CreateForGetMetadataSuccess(params.Pass()),
+                 false /* has_more */);
+  return true;
+}
 
-  if (!request_manager->RejectRequest(
-          params->request_id, ProviderErrorToFileError(params->error))) {
-    // TODO(mtomasz): Pass more detailed errors, rather than just a bool.
-    base::ListValue* result = new base::ListValue();
-    result->Append(
-        CreateError(kSecurityErrorName, kResponseFailedErrorMessage));
-    SetResult(result);
-    return true;
-  }
+bool
+FileSystemProviderInternalGetMetadataRequestedErrorFunction::RunWhenValid() {
+  using api::file_system_provider_internal::GetMetadataRequestedError::Params;
+  const scoped_ptr<Params> params(Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params);
 
-  base::ListValue* result = new base::ListValue();
-  SetResult(result);
+  RejectRequest(ProviderErrorToFileError(params->error));
+  return true;
+}
+
+bool FileSystemProviderInternalReadDirectoryRequestedSuccessFunction::
+    RunWhenValid() {
+  using api::file_system_provider_internal::ReadDirectoryRequestedSuccess::
+      Params;
+  scoped_ptr<Params> params(Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params);
+
+  const bool has_next = params->has_next;
+  FulfillRequest(RequestValue::CreateForReadDirectorySuccess(params.Pass()),
+                 has_next);
+  return true;
+}
+
+bool
+FileSystemProviderInternalReadDirectoryRequestedErrorFunction::RunWhenValid() {
+  using api::file_system_provider_internal::ReadDirectoryRequestedError::Params;
+  const scoped_ptr<Params> params(Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params);
+
+  RejectRequest(ProviderErrorToFileError(params->error));
   return true;
 }
 
diff --git a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h
index d5c945d..21102a6 100644
--- a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h
+++ b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h
@@ -5,8 +5,8 @@
 #ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_SYSTEM_PROVIDER_FILE_SYSTEM_PROVIDER_API_H_
 #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_SYSTEM_PROVIDER_FILE_SYSTEM_PROVIDER_API_H_
 
+#include "chrome/browser/chromeos/extensions/file_system_provider/provider_function.h"
 #include "chrome/browser/extensions/chrome_extension_function.h"
-#include "chrome/common/extensions/api/file_system_provider.h"
 
 namespace extensions {
 
@@ -31,26 +31,75 @@
 };
 
 class FileSystemProviderInternalUnmountRequestedSuccessFunction
-    : public ChromeSyncExtensionFunction {
+    : public FileSystemProviderInternalFunction {
  public:
   DECLARE_EXTENSION_FUNCTION(
       "fileSystemProviderInternal.unmountRequestedSuccess",
-      FILESYSTEMPROVIDERINTERNAL_UNMOUNTREQUESTEDSUCCESS)
+      FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDSUCCESS)
 
  protected:
   virtual ~FileSystemProviderInternalUnmountRequestedSuccessFunction() {}
-  virtual bool RunSync() OVERRIDE;
+  virtual bool RunWhenValid() OVERRIDE;
 };
 
 class FileSystemProviderInternalUnmountRequestedErrorFunction
-    : public ChromeSyncExtensionFunction {
+    : public FileSystemProviderInternalFunction {
  public:
-  DECLARE_EXTENSION_FUNCTION("fileSystemProviderInternal.unmountRequestedError",
-                             FILESYSTEMPROVIDERINTERNAL_UNMOUNTREQUESTEDERROR)
+  DECLARE_EXTENSION_FUNCTION(
+      "fileSystemProviderInternal.unmountRequestedError",
+      FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDERROR)
 
  protected:
   virtual ~FileSystemProviderInternalUnmountRequestedErrorFunction() {}
-  virtual bool RunSync() OVERRIDE;
+  virtual bool RunWhenValid() OVERRIDE;
+};
+
+class FileSystemProviderInternalGetMetadataRequestedSuccessFunction
+    : public FileSystemProviderInternalFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION(
+      "fileSystemProviderInternal.getMetadataRequestedSuccess",
+      FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDSUCCESS)
+
+ protected:
+  virtual ~FileSystemProviderInternalGetMetadataRequestedSuccessFunction() {}
+  virtual bool RunWhenValid() OVERRIDE;
+};
+
+class FileSystemProviderInternalGetMetadataRequestedErrorFunction
+    : public FileSystemProviderInternalFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION(
+      "fileSystemProviderInternal.getMetadataRequestedError",
+      FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDERROR)
+
+ protected:
+  virtual ~FileSystemProviderInternalGetMetadataRequestedErrorFunction() {}
+  virtual bool RunWhenValid() OVERRIDE;
+};
+
+class FileSystemProviderInternalReadDirectoryRequestedSuccessFunction
+    : public FileSystemProviderInternalFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION(
+      "fileSystemProviderInternal.readDirectoryRequestedSuccess",
+      FILESYSTEMPROVIDERINTERNAL_READDIRECTORYREQUESTEDSUCCESS)
+
+ protected:
+  virtual ~FileSystemProviderInternalReadDirectoryRequestedSuccessFunction() {}
+  virtual bool RunWhenValid() OVERRIDE;
+};
+
+class FileSystemProviderInternalReadDirectoryRequestedErrorFunction
+    : public FileSystemProviderInternalFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION(
+      "fileSystemProviderInternal.readDirectoryRequestedError",
+      FILESYSTEMPROVIDERINTERNAL_READDIRECTORYREQUESTEDERROR)
+
+ protected:
+  virtual ~FileSystemProviderInternalReadDirectoryRequestedErrorFunction() {}
+  virtual bool RunWhenValid() OVERRIDE;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc
index c1317e0..db78129 100644
--- a/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc
+++ b/chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc
@@ -29,4 +29,16 @@
       << message_;
 }
 
+IN_PROC_BROWSER_TEST_F(FileSystemProviderApiTest, GetMetadata) {
+  ASSERT_TRUE(RunPlatformAppTestWithFlags("file_system_provider/get_metadata",
+                                          kFlagLoadAsComponent))
+      << message_;
+}
+
+IN_PROC_BROWSER_TEST_F(FileSystemProviderApiTest, ReadDirectory) {
+  ASSERT_TRUE(RunPlatformAppTestWithFlags("file_system_provider/read_directory",
+                                          kFlagLoadAsComponent))
+      << message_;
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/file_system_provider/provider_function.cc b/chrome/browser/chromeos/extensions/file_system_provider/provider_function.cc
new file mode 100644
index 0000000..53a3206
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/file_system_provider/provider_function.cc
@@ -0,0 +1,142 @@
+// 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.
+
+#include "chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h"
+
+#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
+#include "chrome/browser/chromeos/file_system_provider/request_manager.h"
+#include "chrome/browser/chromeos/file_system_provider/request_value.h"
+#include "chrome/browser/chromeos/file_system_provider/service.h"
+#include "chrome/common/extensions/api/file_system_provider_internal.h"
+
+using chromeos::file_system_provider::ProvidedFileSystemInterface;
+using chromeos::file_system_provider::RequestManager;
+using chromeos::file_system_provider::RequestValue;
+using chromeos::file_system_provider::Service;
+
+namespace extensions {
+
+const char kNotFoundErrorName[] = "NotFoundError";
+const char kSecurityErrorName[] = "SecurityError";
+
+const char kEmptyNameErrorMessage[] = "Empty display name is not allowed.";
+const char kMountFailedErrorMessage[] = "Mounting the file system failed.";
+const char kUnmountFailedErrorMessage[] = "Unmounting the file system failed.";
+const char kResponseFailedErrorMessage[] =
+    "Sending a response for the request failed.";
+
+base::DictionaryValue* CreateError(const std::string& name,
+                                   const std::string& message) {
+  base::DictionaryValue* error = new base::DictionaryValue();
+  error->SetString("name", name);
+  error->SetString("message", message);
+  return error;
+}
+
+base::File::Error ProviderErrorToFileError(
+    api::file_system_provider::ProviderError error) {
+  switch (error) {
+    case api::file_system_provider::PROVIDER_ERROR_OK:
+      return base::File::FILE_OK;
+    case api::file_system_provider::PROVIDER_ERROR_FAILED:
+      return base::File::FILE_ERROR_FAILED;
+    case api::file_system_provider::PROVIDER_ERROR_IN_USE:
+      return base::File::FILE_ERROR_IN_USE;
+    case api::file_system_provider::PROVIDER_ERROR_EXISTS:
+      return base::File::FILE_ERROR_EXISTS;
+    case api::file_system_provider::PROVIDER_ERROR_NOT_FOUND:
+      return base::File::FILE_ERROR_NOT_FOUND;
+    case api::file_system_provider::PROVIDER_ERROR_ACCESS_DENIED:
+      return base::File::FILE_ERROR_ACCESS_DENIED;
+    case api::file_system_provider::PROVIDER_ERROR_TOO_MANY_OPENED:
+      return base::File::FILE_ERROR_TOO_MANY_OPENED;
+    case api::file_system_provider::PROVIDER_ERROR_NO_MEMORY:
+      return base::File::FILE_ERROR_NO_MEMORY;
+    case api::file_system_provider::PROVIDER_ERROR_NO_SPACE:
+      return base::File::FILE_ERROR_NO_SPACE;
+    case api::file_system_provider::PROVIDER_ERROR_NOT_A_DIRECTORY:
+      return base::File::FILE_ERROR_NOT_A_DIRECTORY;
+    case api::file_system_provider::PROVIDER_ERROR_INVALID_OPERATION:
+      return base::File::FILE_ERROR_INVALID_OPERATION;
+    case api::file_system_provider::PROVIDER_ERROR_SECURITY:
+      return base::File::FILE_ERROR_SECURITY;
+    case api::file_system_provider::PROVIDER_ERROR_ABORT:
+      return base::File::FILE_ERROR_ABORT;
+    case api::file_system_provider::PROVIDER_ERROR_NOT_A_FILE:
+      return base::File::FILE_ERROR_NOT_A_FILE;
+    case api::file_system_provider::PROVIDER_ERROR_NOT_EMPTY:
+      return base::File::FILE_ERROR_NOT_EMPTY;
+    case api::file_system_provider::PROVIDER_ERROR_INVALID_URL:
+      return base::File::FILE_ERROR_INVALID_URL;
+    case api::file_system_provider::PROVIDER_ERROR_IO:
+      return base::File::FILE_ERROR_IO;
+    case api::file_system_provider::PROVIDER_ERROR_NONE:
+      NOTREACHED();
+  }
+  return base::File::FILE_ERROR_FAILED;
+}
+
+FileSystemProviderInternalFunction::FileSystemProviderInternalFunction()
+    : request_id_(0), request_manager_(NULL) {
+}
+
+void FileSystemProviderInternalFunction::RejectRequest(
+    base::File::Error error) {
+  if (!request_manager_->RejectRequest(request_id_, error))
+    SetErrorResponse(kSecurityErrorName, kResponseFailedErrorMessage);
+}
+
+void FileSystemProviderInternalFunction::FulfillRequest(
+    scoped_ptr<RequestValue> value,
+    bool has_next) {
+  if (!request_manager_->FulfillRequest(request_id_, value.Pass(), has_next))
+    SetErrorResponse(kSecurityErrorName, kResponseFailedErrorMessage);
+}
+
+bool FileSystemProviderInternalFunction::RunSync() {
+  DCHECK(args_);
+  if (!Parse())
+    return true;
+
+  SendResponse(RunWhenValid());
+  return true;
+}
+
+bool FileSystemProviderInternalFunction::Parse() {
+  int file_system_id = 0;
+
+  if (!args_->GetInteger(0, &file_system_id) ||
+      !args_->GetInteger(1, &request_id_)) {
+    bad_message_ = true;
+    SendResponse(false);
+    return false;
+  }
+
+  Service* service = Service::Get(GetProfile());
+  if (!service) {
+    SendResponse(false);
+    return false;
+  }
+
+  ProvidedFileSystemInterface* file_system =
+      service->GetProvidedFileSystem(extension_id(), file_system_id);
+  if (!file_system) {
+    SetErrorResponse(kNotFoundErrorName, kResponseFailedErrorMessage);
+    SendResponse(true);
+    return false;
+  }
+
+  request_manager_ = file_system->GetRequestManager();
+  return true;
+}
+
+void FileSystemProviderInternalFunction::SetErrorResponse(
+    const std::string& name,
+    const std::string& message) {
+  base::ListValue* result = new base::ListValue();
+  result->Append(CreateError(name, message));
+  SetResult(result);
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/file_system_provider/provider_function.h b/chrome/browser/chromeos/extensions/file_system_provider/provider_function.h
new file mode 100644
index 0000000..a035f8c
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/file_system_provider/provider_function.h
@@ -0,0 +1,93 @@
+// 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_SYSTEM_PROVIDER_PROVIDER_FUNCTION_H_
+#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_SYSTEM_PROVIDER_PROVIDER_FUNCTION_H_
+#include <string>
+
+#include "base/files/file.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/extensions/chrome_extension_function.h"
+#include "chrome/common/extensions/api/file_system_provider.h"
+
+namespace base {
+class DictionaryValue;
+}  // namespace base
+
+namespace chromeos {
+namespace file_system_provider {
+
+class RequestManager;
+class RequestValue;
+
+}  // namespace file_system_provider
+}  // namespace chromeos
+
+namespace extensions {
+
+// Error names from
+// http://www.w3.org/TR/file-system-api/#errors-and-exceptions
+extern const char kNotFoundErrorName[];
+extern const char kSecurityErrorName[];
+
+// Error messages.
+extern const char kEmptyNameErrorMessage[];
+extern const char kMountFailedErrorMessage[];
+extern const char kUnmountFailedErrorMessage[];
+extern const char kResponseFailedErrorMessage[];
+
+// Creates a dictionary, which looks like a DOMError. The returned dictionary
+// will be converted to a real DOMError object in
+// file_system_provier_custom_bindings.js.
+base::DictionaryValue* CreateError(const std::string& name,
+                                   const std::string& message);
+
+// Converts ProviderError to base::File::Error. This could be redundant, if it
+// was possible to create DOMError instances in Javascript easily.
+base::File::Error ProviderErrorToFileError(
+    api::file_system_provider::ProviderError error);
+
+// Base class for internal API functions handling request results, either
+// a success or a failure.
+class FileSystemProviderInternalFunction : public ChromeSyncExtensionFunction {
+ public:
+  FileSystemProviderInternalFunction();
+
+ protected:
+  virtual ~FileSystemProviderInternalFunction() {}
+
+  // Rejects the request and sets a response for this API function.
+  void RejectRequest(base::File::Error error);
+
+  // Fulfills the request with parsed arguments of this API function
+  // encapsulated as a RequestValue instance. Also, sets a response.
+  // If |has_next| is set to true, then the function will be called again for
+  // this request.
+  void FulfillRequest(
+      scoped_ptr<chromeos::file_system_provider::RequestValue> value,
+      bool has_next);
+
+  // Subclasses implement this for their functionality.
+  // Called after Parse() is successful, such that |request_id_| and
+  // |request_manager_| have been fully initialized.
+  virtual bool RunWhenValid() = 0;
+
+  // ChromeSyncExtensionFunction overrides.
+  virtual bool RunSync() OVERRIDE;
+
+ private:
+  // Parses the request in order to extract the request manager. If fails, then
+  // sets a response and returns false.
+  bool Parse();
+
+  // Sets an error message in case of a failure.
+  void SetErrorResponse(const std::string& name, const std::string& message);
+
+  int request_id_;
+  chromeos::file_system_provider::RequestManager* request_manager_;
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_SYSTEM_PROVIDER_PROVIDER_FUNCTION_H_
diff --git a/chrome/browser/chromeos/extensions/info_private_api.cc b/chrome/browser/chromeos/extensions/info_private_api.cc
index f7c9514..4d13dcf 100644
--- a/chrome/browser/chromeos/extensions/info_private_api.cc
+++ b/chrome/browser/chromeos/extensions/info_private_api.cc
@@ -112,7 +112,7 @@
 ChromeosInfoPrivateGetFunction::~ChromeosInfoPrivateGetFunction() {
 }
 
-bool ChromeosInfoPrivateGetFunction::RunImpl() {
+bool ChromeosInfoPrivateGetFunction::RunAsync() {
   base::ListValue* list = NULL;
   EXTENSION_FUNCTION_VALIDATE(args_->GetList(0, &list));
   scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
diff --git a/chrome/browser/chromeos/extensions/info_private_api.h b/chrome/browser/chromeos/extensions/info_private_api.h
index 14f2e68..afa531c 100644
--- a/chrome/browser/chromeos/extensions/info_private_api.h
+++ b/chrome/browser/chromeos/extensions/info_private_api.h
@@ -23,7 +23,7 @@
  protected:
   virtual ~ChromeosInfoPrivateGetFunction();
 
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Returns a newly allocate value, or null.
diff --git a/chrome/browser/chromeos/extensions/input_view_browsertest.cc b/chrome/browser/chromeos/extensions/input_view_browsertest.cc
new file mode 100644
index 0000000..ba4b5bf
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/input_view_browsertest.cc
@@ -0,0 +1,82 @@
+// 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.
+
+#include "ash/shell.h"
+#include "base/files/file_path.h"
+#include "chrome/browser/chromeos/extensions/virtual_keyboard_browsertest.h"
+#include "chrome/browser/extensions/crx_installer.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_test_notification_observer.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "chromeos/ime/extension_ime_util.h"
+#include "chromeos/ime/input_method_manager.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/site_instance.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test_utils.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/file_util.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/base/ime/input_method.h"
+
+namespace {
+
+const base::FilePath::CharType kExtensionName[] = "GoogleKeyboardInput-xkb.crx";
+
+const base::FilePath::CharType kInputViewTestDir[] =
+    "chromeos/virtual_keyboard/inputview/";
+const base::FilePath::CharType kBaseKeyboardTestFramework[] = "test_base.js";
+
+struct InputViewConfig : public VirtualKeyboardBrowserTestConfig {
+  explicit InputViewConfig(std::string id) {
+    base_framework_ = kBaseKeyboardTestFramework;
+    extension_id_ = id;
+    test_dir_ = kInputViewTestDir;
+    url_ = "chrome-extension://" + id + "/inputview.html?id=us-altgr-intl";
+  }
+};
+
+}  // namespace
+
+class InputViewBrowserTest : public VirtualKeyboardBrowserTest {
+ public:
+  // Installs the IME Extension keyboard |kExtensionName|.
+  std::string InstallIMEExtension() {
+    // Loads extension.
+    base::FilePath path = ui_test_utils::GetTestFilePath(
+        base::FilePath(kInputViewTestDir), base::FilePath(kExtensionName));
+    ExtensionService* service = browser()->profile()->GetExtensionService();
+    scoped_refptr<extensions::CrxInstaller> installer =
+        extensions::CrxInstaller::CreateSilent(service);
+
+    ExtensionTestNotificationObserver observer(browser());
+    observer.Watch(chrome::NOTIFICATION_CRX_INSTALLER_DONE,
+                   content::Source<extensions::CrxInstaller>(installer.get()));
+    installer->set_allow_silent_install(true);
+    installer->set_creation_flags(extensions::Extension::FROM_WEBSTORE);
+    installer->InstallCrx(path);
+    // Wait for CRX to be installed.
+    observer.Wait();
+    std::string extensionId = installer->extension()->id();
+    if (!service->GetExtensionById(extensionId, false))
+      return "";
+
+    // Register extension with IME.
+    chromeos::input_method::InputMethodManager* ime =
+        chromeos::input_method::InputMethodManager::Get();
+    std::string id = chromeos::extension_ime_util::GetComponentInputMethodID(
+        extensionId, "xkb:us::eng");
+    ime->ChangeInputMethod(id);
+    return extensionId;
+  }
+};
+
+IN_PROC_BROWSER_TEST_F(InputViewBrowserTest, TypingTest) {
+  std::string id = InstallIMEExtension();
+  ASSERT_FALSE(id.empty());
+  RunTest(base::FilePath("typing_test.js"), InputViewConfig(id));
+}
diff --git a/chrome/browser/chromeos/extensions/screenlock_private_api.cc b/chrome/browser/chromeos/extensions/screenlock_private_api.cc
deleted file mode 100644
index c22fb4d..0000000
--- a/chrome/browser/chromeos/extensions/screenlock_private_api.cc
+++ /dev/null
@@ -1,312 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/chromeos/extensions/screenlock_private_api.h"
-
-#include "base/lazy_instance.h"
-#include "base/values.h"
-#include "chrome/browser/chromeos/login/screen_locker.h"
-#include "chrome/browser/extensions/image_loader.h"
-#include "chrome/common/extensions/api/screenlock_private.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "extensions/browser/event_router.h"
-#include "extensions/browser/extension_system.h"
-#include "ui/gfx/image/image.h"
-
-namespace screenlock = extensions::api::screenlock_private;
-
-namespace extensions {
-
-namespace {
-
-const char kNotLockedError[] = "Screen is not currently locked.";
-
-chromeos::LoginDisplay::AuthType ToLoginDisplayAuthType(
-    screenlock::AuthType auth_type) {
-  switch (auth_type) {
-    case screenlock::AUTH_TYPE_OFFLINEPASSWORD:
-      return chromeos::LoginDisplay::OFFLINE_PASSWORD;
-    case screenlock::AUTH_TYPE_NUMERICPIN:
-      return chromeos::LoginDisplay::NUMERIC_PIN;
-    case screenlock::AUTH_TYPE_USERCLICK:
-      return chromeos::LoginDisplay::USER_CLICK;
-    default:
-      NOTREACHED();
-      return chromeos::LoginDisplay::OFFLINE_PASSWORD;
-  }
-}
-
-screenlock::AuthType ToScreenlockPrivateAuthType(
-    chromeos::LoginDisplay::AuthType auth_type) {
-  switch (auth_type) {
-    case chromeos::LoginDisplay::OFFLINE_PASSWORD:
-      return screenlock::AUTH_TYPE_OFFLINEPASSWORD;
-    case chromeos::LoginDisplay::NUMERIC_PIN:
-      return screenlock::AUTH_TYPE_NUMERICPIN;
-    case chromeos::LoginDisplay::USER_CLICK:
-      return screenlock::AUTH_TYPE_USERCLICK;
-    case chromeos::LoginDisplay::ONLINE_SIGN_IN:
-      // Apps should treat forced online sign in same as system password.
-      return screenlock::AUTH_TYPE_OFFLINEPASSWORD;
-    default:
-      NOTREACHED();
-      return screenlock::AUTH_TYPE_OFFLINEPASSWORD;
-  }
-}
-
-}  // namespace
-
-ScreenlockPrivateGetLockedFunction::ScreenlockPrivateGetLockedFunction() {}
-
-ScreenlockPrivateGetLockedFunction::~ScreenlockPrivateGetLockedFunction() {}
-
-bool ScreenlockPrivateGetLockedFunction::RunImpl() {
-  bool locked = false;
-  chromeos::ScreenLocker* locker =
-      chromeos::ScreenLocker::default_screen_locker();
-  if (locker)
-    locked = locker->locked();
-  SetResult(new base::FundamentalValue(locked));
-  SendResponse(error_.empty());
-  return true;
-}
-
-ScreenlockPrivateSetLockedFunction::ScreenlockPrivateSetLockedFunction() {}
-
-ScreenlockPrivateSetLockedFunction::~ScreenlockPrivateSetLockedFunction() {}
-
-bool ScreenlockPrivateSetLockedFunction::RunImpl() {
-  scoped_ptr<screenlock::SetLocked::Params> params(
-      screenlock::SetLocked::Params::Create(*args_));
-  EXTENSION_FUNCTION_VALIDATE(params.get());
-  if (params->locked) {
-    chromeos::SessionManagerClient* session_manager =
-        chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
-    session_manager->RequestLockScreen();
-  } else {
-    chromeos::ScreenLocker* locker =
-        chromeos::ScreenLocker::default_screen_locker();
-    if (locker)
-      chromeos::ScreenLocker::Hide();
-  }
-  SendResponse(error_.empty());
-  return true;
-}
-
-ScreenlockPrivateShowMessageFunction::ScreenlockPrivateShowMessageFunction() {}
-
-ScreenlockPrivateShowMessageFunction::~ScreenlockPrivateShowMessageFunction() {}
-
-bool ScreenlockPrivateShowMessageFunction::RunImpl() {
-  scoped_ptr<screenlock::ShowMessage::Params> params(
-      screenlock::ShowMessage::Params::Create(*args_));
-  EXTENSION_FUNCTION_VALIDATE(params.get());
-  chromeos::ScreenLocker* locker =
-      chromeos::ScreenLocker::default_screen_locker();
-  if (locker)
-    locker->ShowBannerMessage(params->message);
-  SendResponse(error_.empty());
-  return true;
-}
-
-static const int kMaxButtonIconSize = 40;
-
-ScreenlockPrivateShowButtonFunction::
-  ScreenlockPrivateShowButtonFunction() {}
-
-ScreenlockPrivateShowButtonFunction::
-  ~ScreenlockPrivateShowButtonFunction() {}
-
-bool ScreenlockPrivateShowButtonFunction::RunImpl() {
-  scoped_ptr<screenlock::ShowButton::Params> params(
-      screenlock::ShowButton::Params::Create(*args_));
-  EXTENSION_FUNCTION_VALIDATE(params.get());
-  chromeos::ScreenLocker* locker =
-      chromeos::ScreenLocker::default_screen_locker();
-  if (!locker) {
-    SetError(kNotLockedError);
-    SendResponse(false);
-    return true;
-  }
-  extensions::ImageLoader* loader = extensions::ImageLoader::Get(GetProfile());
-  loader->LoadImageAsync(
-      GetExtension(), GetExtension()->GetResource(params->icon),
-      gfx::Size(kMaxButtonIconSize, kMaxButtonIconSize),
-      base::Bind(&ScreenlockPrivateShowButtonFunction::OnImageLoaded, this));
-  return true;
-}
-
-void ScreenlockPrivateShowButtonFunction::OnImageLoaded(
-    const gfx::Image& image) {
-  chromeos::ScreenLocker* locker =
-      chromeos::ScreenLocker::default_screen_locker();
-  ScreenlockPrivateEventRouter* router =
-      ScreenlockPrivateEventRouter::GetFactoryInstance()->Get(GetProfile());
-  const chromeos::User* user =
-      chromeos::UserManager::Get()->GetUserByProfile(GetProfile());
-  locker->ShowUserPodButton(
-      user->email(),
-      image,
-      base::Bind(&ScreenlockPrivateEventRouter::OnButtonClicked,
-                 base::Unretained(router)));
-  SendResponse(error_.empty());
-}
-
-ScreenlockPrivateHideButtonFunction::ScreenlockPrivateHideButtonFunction() {}
-
-ScreenlockPrivateHideButtonFunction::~ScreenlockPrivateHideButtonFunction() {}
-
-bool ScreenlockPrivateHideButtonFunction::RunImpl() {
-  chromeos::ScreenLocker* locker =
-      chromeos::ScreenLocker::default_screen_locker();
-  if (locker) {
-    const chromeos::User* user =
-        chromeos::UserManager::Get()->GetUserByProfile(GetProfile());
-    locker->HideUserPodButton(user->email());
-  } else {
-    SetError(kNotLockedError);
-  }
-  SendResponse(error_.empty());
-  return true;
-}
-
-ScreenlockPrivateSetAuthTypeFunction::ScreenlockPrivateSetAuthTypeFunction() {}
-
-ScreenlockPrivateSetAuthTypeFunction::~ScreenlockPrivateSetAuthTypeFunction() {}
-
-bool ScreenlockPrivateSetAuthTypeFunction::RunImpl() {
-  scoped_ptr<screenlock::SetAuthType::Params> params(
-      screenlock::SetAuthType::Params::Create(*args_));
-  EXTENSION_FUNCTION_VALIDATE(params.get());
-
-  chromeos::ScreenLocker* locker =
-      chromeos::ScreenLocker::default_screen_locker();
-  if (locker) {
-    std::string initial_value =
-        params->initial_value.get() ? *(params->initial_value.get()) : "";
-    const chromeos::User* user =
-        chromeos::UserManager::Get()->GetUserByProfile(GetProfile());
-    locker->SetAuthType(user->email(),
-                        ToLoginDisplayAuthType(params->auth_type),
-                        initial_value);
-  } else {
-    SetError(kNotLockedError);
-  }
-  SendResponse(error_.empty());
-  return true;
-}
-
-ScreenlockPrivateGetAuthTypeFunction::ScreenlockPrivateGetAuthTypeFunction() {}
-
-ScreenlockPrivateGetAuthTypeFunction::~ScreenlockPrivateGetAuthTypeFunction() {}
-
-bool ScreenlockPrivateGetAuthTypeFunction::RunImpl() {
-  chromeos::ScreenLocker* locker =
-      chromeos::ScreenLocker::default_screen_locker();
-  if (locker) {
-    const chromeos::User* user =
-        chromeos::UserManager::Get()->GetUserByProfile(GetProfile());
-    chromeos::LoginDisplay::AuthType auth_type =
-        locker->GetAuthType(user->email());
-    std::string auth_type_name =
-        screenlock::ToString(ToScreenlockPrivateAuthType(auth_type));
-    SetResult(new base::StringValue(auth_type_name));
-  } else {
-    SetError(kNotLockedError);
-  }
-  SendResponse(error_.empty());
-  return true;
-}
-
-ScreenlockPrivateAcceptAuthAttemptFunction::
-    ScreenlockPrivateAcceptAuthAttemptFunction() {}
-
-ScreenlockPrivateAcceptAuthAttemptFunction::
-    ~ScreenlockPrivateAcceptAuthAttemptFunction() {}
-
-bool ScreenlockPrivateAcceptAuthAttemptFunction::RunImpl() {
-  scoped_ptr<screenlock::AcceptAuthAttempt::Params> params(
-      screenlock::AcceptAuthAttempt::Params::Create(*args_));
-  EXTENSION_FUNCTION_VALIDATE(params.get());
-
-  chromeos::ScreenLocker* locker =
-      chromeos::ScreenLocker::default_screen_locker();
-  if (locker) {
-    if (params->accept)
-      chromeos::ScreenLocker::Hide();
-    else
-      locker->EnableInput();
-  } else {
-    SetError(kNotLockedError);
-  }
-  SendResponse(error_.empty());
-  return true;
-}
-
-ScreenlockPrivateEventRouter::ScreenlockPrivateEventRouter(
-    content::BrowserContext* context)
-    : browser_context_(context) {
-  chromeos::SessionManagerClient* session_manager =
-      chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
-  if (!session_manager->HasObserver(this))
-    session_manager->AddObserver(this);
-}
-
-ScreenlockPrivateEventRouter::~ScreenlockPrivateEventRouter() {}
-
-void ScreenlockPrivateEventRouter::ScreenIsLocked() {
-  DispatchEvent(screenlock::OnChanged::kEventName,
-      new base::FundamentalValue(true));
-}
-
-void ScreenlockPrivateEventRouter::ScreenIsUnlocked() {
-  DispatchEvent(screenlock::OnChanged::kEventName,
-      new base::FundamentalValue(false));
-}
-
-void ScreenlockPrivateEventRouter::DispatchEvent(
-    const std::string& event_name,
-    base::Value* arg) {
-  scoped_ptr<base::ListValue> args(new base::ListValue());
-  if (arg)
-    args->Append(arg);
-  scoped_ptr<extensions::Event> event(new extensions::Event(
-      event_name, args.Pass()));
-  extensions::EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
-}
-
-static base::LazyInstance<extensions::BrowserContextKeyedAPIFactory<
-    ScreenlockPrivateEventRouter> > g_factory = LAZY_INSTANCE_INITIALIZER;
-
-// static
-extensions::BrowserContextKeyedAPIFactory<ScreenlockPrivateEventRouter>*
-ScreenlockPrivateEventRouter::GetFactoryInstance() {
-  return g_factory.Pointer();
-}
-
-void ScreenlockPrivateEventRouter::Shutdown() {
-  chromeos::SessionManagerClient* session_manager =
-      chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
-  if (session_manager->HasObserver(this))
-    session_manager->RemoveObserver(this);
-}
-
-void ScreenlockPrivateEventRouter::OnButtonClicked() {
-  DispatchEvent(screenlock::OnButtonClicked::kEventName, NULL);
-}
-
-void ScreenlockPrivateEventRouter::OnAuthAttempted(
-    chromeos::LoginDisplay::AuthType auth_type,
-    const std::string& value) {
-  scoped_ptr<base::ListValue> args(new base::ListValue());
-  args->AppendString(
-      screenlock::ToString(ToScreenlockPrivateAuthType(auth_type)));
-  args->AppendString(value);
-
-  scoped_ptr<extensions::Event> event(new extensions::Event(
-      screenlock::OnAuthAttempted::kEventName, args.Pass()));
-  extensions::EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/screenlock_private_api.h b/chrome/browser/chromeos/extensions/screenlock_private_api.h
deleted file mode 100644
index 7e597d2..0000000
--- a/chrome/browser/chromeos/extensions/screenlock_private_api.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_SCREENLOCK_PRIVATE_API_H_
-#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_SCREENLOCK_PRIVATE_API_H_
-
-#include "chrome/browser/chromeos/login/login_display.h"
-#include "chrome/browser/extensions/chrome_extension_function.h"
-#include "chromeos/dbus/session_manager_client.h"
-#include "extensions/browser/browser_context_keyed_api_factory.h"
-
-namespace gfx {
-class Image;
-}
-
-namespace extensions {
-
-class ScreenlockPrivateGetLockedFunction : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.getLocked",
-                             SCREENLOCKPRIVATE_GETLOCKED)
-  ScreenlockPrivateGetLockedFunction();
-  virtual bool RunImpl() OVERRIDE;
- private:
-  virtual ~ScreenlockPrivateGetLockedFunction();
-  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateGetLockedFunction);
-};
-
-class ScreenlockPrivateSetLockedFunction : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.setLocked",
-                             SCREENLOCKPRIVATE_SETLOCKED)
-  ScreenlockPrivateSetLockedFunction();
-  virtual bool RunImpl() OVERRIDE;
- private:
-  virtual ~ScreenlockPrivateSetLockedFunction();
-  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateSetLockedFunction);
-};
-
-class ScreenlockPrivateShowMessageFunction
-    : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.showMessage",
-                             SCREENLOCKPRIVATE_SHOWMESSAGE)
-  ScreenlockPrivateShowMessageFunction();
-  virtual bool RunImpl() OVERRIDE;
- private:
-  virtual ~ScreenlockPrivateShowMessageFunction();
-  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateShowMessageFunction );
-};
-
-class ScreenlockPrivateShowButtonFunction
-    : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.showButton",
-                             SCREENLOCKPRIVATE_SHOWBUTTON)
-  ScreenlockPrivateShowButtonFunction();
-  virtual bool RunImpl() OVERRIDE;
- private:
-  virtual ~ScreenlockPrivateShowButtonFunction();
-  void OnImageLoaded(const gfx::Image& image);
-  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateShowButtonFunction);
-};
-
-class ScreenlockPrivateHideButtonFunction
-    : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.hideButton",
-                             SCREENLOCKPRIVATE_HIDEBUTTON)
-  ScreenlockPrivateHideButtonFunction();
-  virtual bool RunImpl() OVERRIDE;
-
- private:
-  virtual ~ScreenlockPrivateHideButtonFunction();
-  void OnImageLoaded(const gfx::Image& image);
-  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateHideButtonFunction);
-};
-
-class ScreenlockPrivateSetAuthTypeFunction
-    : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.setAuthType",
-                             SCREENLOCKPRIVATE_SETAUTHTYPE)
-  ScreenlockPrivateSetAuthTypeFunction();
-  virtual bool RunImpl() OVERRIDE;
-
- private:
-  virtual ~ScreenlockPrivateSetAuthTypeFunction();
-  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateSetAuthTypeFunction);
-};
-
-class ScreenlockPrivateGetAuthTypeFunction
-    : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.getAuthType",
-                             SCREENLOCKPRIVATE_GETAUTHTYPE)
-  ScreenlockPrivateGetAuthTypeFunction();
-  virtual bool RunImpl() OVERRIDE;
-
- private:
-  virtual ~ScreenlockPrivateGetAuthTypeFunction();
-  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateGetAuthTypeFunction);
-};
-
-class ScreenlockPrivateAcceptAuthAttemptFunction
-    : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.acceptAuthAttempt",
-                             SCREENLOCKPRIVATE_ACCEPTAUTHATTEMPT)
-  ScreenlockPrivateAcceptAuthAttemptFunction();
-  virtual bool RunImpl() OVERRIDE;
-
- private:
-  virtual ~ScreenlockPrivateAcceptAuthAttemptFunction();
-  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateAcceptAuthAttemptFunction);
-};
-
-class ScreenlockPrivateEventRouter
-    : public extensions::BrowserContextKeyedAPI,
-      public chromeos::SessionManagerClient::Observer {
- public:
-  explicit ScreenlockPrivateEventRouter(content::BrowserContext* context);
-  virtual ~ScreenlockPrivateEventRouter();
-
-  void OnButtonClicked();
-
-  void OnAuthAttempted(chromeos::LoginDisplay::AuthType auth_type,
-                       const std::string& value);
-
-  // BrowserContextKeyedAPI
-  static extensions::BrowserContextKeyedAPIFactory<
-      ScreenlockPrivateEventRouter>*
-      GetFactoryInstance();
-  virtual void Shutdown() OVERRIDE;
-
-  // chromeos::SessionManagerClient::Observer
-  virtual void ScreenIsLocked() OVERRIDE;
-  virtual void ScreenIsUnlocked() OVERRIDE;
-
- private:
-  friend class extensions::BrowserContextKeyedAPIFactory<
-      ScreenlockPrivateEventRouter>;
-
-  // BrowserContextKeyedAPI
-  static const char* service_name() {
-    return "ScreenlockPrivateEventRouter";
-  }
-  static const bool kServiceIsNULLWhileTesting = true;
-  static const bool kServiceRedirectedInIncognito = true;
-
-  void DispatchEvent(const std::string& event_name, base::Value* arg);
-
-  content::BrowserContext* browser_context_;
-  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateEventRouter);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_SCREENLOCK_PRIVATE_API_H_
diff --git a/chrome/browser/chromeos/extensions/screenlock_private_apitest.cc b/chrome/browser/chromeos/extensions/screenlock_private_apitest.cc
index 9092b95..1a9a6f1 100644
--- a/chrome/browser/chromeos/extensions/screenlock_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/screenlock_private_apitest.cc
@@ -6,6 +6,8 @@
 #include "chrome/browser/chromeos/login/screen_locker.h"
 #include "chrome/browser/chromeos/login/user.h"
 #include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "components/signin/core/browser/signin_manager.h"
 #include "content/public/browser/notification_service.h"
 #include "extensions/browser/api/test/test_api.h"
 
@@ -24,6 +26,13 @@
 
   virtual ~ScreenlockPrivateApiTest() {}
 
+  // ExtensionApiTest
+  virtual void SetUpOnMainThread() OVERRIDE {
+    SigninManagerFactory::GetForProfile(profile())
+        ->SetAuthenticatedUsername("TestUser@gmail.com");
+    ExtensionApiTest::SetUpOnMainThread();
+  }
+
  protected:
   chromeos::ScreenLocker* GetScreenLocker() {
     chromeos::ScreenLocker* locker =
diff --git a/chrome/browser/chromeos/extensions/virtual_keyboard_browsertest.cc b/chrome/browser/chromeos/extensions/virtual_keyboard_browsertest.cc
index 813dcc1..530bfd1 100644
--- a/chrome/browser/chromeos/extensions/virtual_keyboard_browsertest.cc
+++ b/chrome/browser/chromeos/extensions/virtual_keyboard_browsertest.cc
@@ -3,6 +3,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+#include "chrome/browser/chromeos/extensions/virtual_keyboard_browsertest.h"
 
 #include <vector>
 
@@ -17,131 +18,143 @@
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
+#include "extensions/common/extension.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/base/ime/input_method.h"
 #include "ui/keyboard/keyboard_controller.h"
 #include "ui/keyboard/keyboard_switches.h"
 
 namespace {
+const base::FilePath::CharType kWebuiTestDir[] = FILE_PATH_LITERAL("webui");
 
-const base::FilePath kWebuiTestDir =
-    base::FilePath(FILE_PATH_LITERAL("webui"));
+const base::FilePath::CharType kMockController[] =
+    FILE_PATH_LITERAL("mock_controller.js");
 
-const base::FilePath kVirtualKeyboardTestDir =
-    base::FilePath(FILE_PATH_LITERAL("chromeos/virtual_keyboard"));
+const base::FilePath::CharType kMockTimer[] =
+    FILE_PATH_LITERAL("mock_timer.js");
 
-const base::FilePath kMockController =
-    base::FilePath(FILE_PATH_LITERAL("mock_controller.js"));
+const char kVirtualKeyboardTestDir[] = "chromeos/virtual_keyboard";
 
-const base::FilePath kMockTimer =
-    base::FilePath(FILE_PATH_LITERAL("mock_timer.js"));
+const char kBaseKeyboardTestFramework[] = "virtual_keyboard_test_base.js";
 
-const base::FilePath kBaseKeyboardTestFramework =
-    base::FilePath(FILE_PATH_LITERAL("virtual_keyboard_test_base.js"));
+const char kExtensionId[] = "mppnpdlheglhdfmldimlhpnegondlapf";
+
+const char kVirtualKeyboardURL[] = "chrome://keyboard";
 
 }  // namespace
 
-class VirtualKeyboardBrowserTest : public InProcessBrowserTest {
- public:
+VirtualKeyboardBrowserTestConfig::VirtualKeyboardBrowserTestConfig()
+    : base_framework_(kBaseKeyboardTestFramework),
+      extension_id_(kExtensionId),
+      test_dir_(kVirtualKeyboardTestDir),
+      url_(kVirtualKeyboardURL) {
+}
 
-  // Ensure that the virtual keyboard is enabled.
-  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
-    command_line->AppendSwitch(
-        keyboard::switches::kEnableVirtualKeyboard);
-  }
+VirtualKeyboardBrowserTestConfig::~VirtualKeyboardBrowserTestConfig() {};
 
-  // Injects javascript in |file| into the keyboard page and runs test methods.
-  void RunTest(const base::FilePath& file) {
-    ui_test_utils::NavigateToURL(browser(), GURL("chrome://keyboard"));
+void VirtualKeyboardBrowserTest::SetUpCommandLine(CommandLine* command_line) {
+  command_line->AppendSwitch(keyboard::switches::kEnableVirtualKeyboard);
+}
 
-    content::WebContents* web_contents =
-        browser()->tab_strip_model()->GetActiveWebContents();
-    ASSERT_TRUE(web_contents);
+void VirtualKeyboardBrowserTest::RunTest(
+    const base::FilePath& file,
+    const VirtualKeyboardBrowserTestConfig& config) {
+  ui_test_utils::NavigateToURL(browser(), GURL(config.url_));
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  content::WaitForLoadStop(web_contents);
+  ASSERT_TRUE(web_contents);
 
-    // Inject testing scripts.
-    InjectJavascript(kWebuiTestDir, kMockController);
-    InjectJavascript(kWebuiTestDir, kMockTimer);
-    InjectJavascript(kVirtualKeyboardTestDir, kBaseKeyboardTestFramework);
-    InjectJavascript(kVirtualKeyboardTestDir, file);
+  // Inject testing scripts.
+  InjectJavascript(base::FilePath(kWebuiTestDir),
+                   base::FilePath(kMockController));
+  InjectJavascript(base::FilePath(kWebuiTestDir), base::FilePath(kMockTimer));
+  InjectJavascript(base::FilePath(FILE_PATH_LITERAL(config.test_dir_)),
+                   base::FilePath(FILE_PATH_LITERAL(config.base_framework_)));
+  InjectJavascript(base::FilePath(FILE_PATH_LITERAL(config.test_dir_)), file);
 
-    ASSERT_TRUE(content::ExecuteScript(web_contents, utf8_content_));
+  ASSERT_TRUE(content::ExecuteScript(web_contents, utf8_content_));
 
-    // Inject DOM-automation test harness and run tests.
-    std::vector<int> resource_ids;
-    EXPECT_TRUE(ExecuteWebUIResourceTest(web_contents, resource_ids));
-  }
+  // Inject DOM-automation test harness and run tests.
+  std::vector<int> resource_ids;
+  EXPECT_TRUE(ExecuteWebUIResourceTest(web_contents, resource_ids));
+}
 
-  void showVirtualKeyboard() {
-    aura::Window *window = ash::Shell::GetPrimaryRootWindow();
-    ui::InputMethod* input_method = window->GetProperty(
-        aura::client::kRootWindowInputMethodKey);
-    ASSERT_TRUE(input_method);
-    input_method->ShowImeIfNeeded();
-  }
+void VirtualKeyboardBrowserTest::ShowVirtualKeyboard() {
+  aura::Window* window = ash::Shell::GetPrimaryRootWindow();
+  ui::InputMethod* input_method =
+      window->GetProperty(aura::client::kRootWindowInputMethodKey);
+  ASSERT_TRUE(input_method);
+  input_method->ShowImeIfNeeded();
+}
 
-  content::RenderViewHost* GetKeyboardRenderViewHost() {
-    showVirtualKeyboard();
-    std::string kVirtualKeyboardURL =
-        "chrome-extension://mppnpdlheglhdfmldimlhpnegondlapf/";
-    scoped_ptr<content::RenderWidgetHostIterator> widgets(
-        content::RenderWidgetHost::GetRenderWidgetHosts());
-    while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
-      if (widget->IsRenderView()) {
-        content::RenderViewHost* view = content::RenderViewHost::From(widget);
-        std::string url = view->GetSiteInstance()->GetSiteURL().spec();
-        if (url == kVirtualKeyboardURL) {
-          content::WebContents* wc =
-              content::WebContents::FromRenderViewHost(view);
-          // Waits for Polymer to load.
-          content::WaitForLoadStop(wc);
-          return view;
-        }
+content::RenderViewHost* VirtualKeyboardBrowserTest::GetKeyboardRenderViewHost(
+    const std::string& id) {
+  ShowVirtualKeyboard();
+  GURL url = extensions::Extension::GetBaseURLFromExtensionId(id);
+  scoped_ptr<content::RenderWidgetHostIterator> widgets(
+      content::RenderWidgetHost::GetRenderWidgetHosts());
+  while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
+    if (widget->IsRenderView()) {
+      content::RenderViewHost* view = content::RenderViewHost::From(widget);
+      if (url == view->GetSiteInstance()->GetSiteURL()) {
+        content::WebContents* wc =
+            content::WebContents::FromRenderViewHost(view);
+        // Waits for Polymer to load.
+        content::WaitForLoadStop(wc);
+        return view;
       }
     }
-    return NULL;
   }
+  LOG(ERROR) << "Extension not found:" << url;
+  return NULL;
+}
 
- private:
-
-  // Injects javascript into the keyboard page.  The test |file| is in
-  // directory |dir| relative to the root testing directory.
-  void InjectJavascript(const base::FilePath& dir,
-                        const base::FilePath& file) {
-    base::FilePath path = ui_test_utils::GetTestFilePath(dir, file);
-    std::string library_content;
-    ASSERT_TRUE(base::ReadFileToString(path, &library_content))
-        << path.value();
-    utf8_content_.append(library_content);
-    utf8_content_.append(";\n");
-  }
-
-  std::string utf8_content_;
-};
+void VirtualKeyboardBrowserTest::InjectJavascript(const base::FilePath& dir,
+                                                  const base::FilePath& file) {
+  base::FilePath path = ui_test_utils::GetTestFilePath(dir, file);
+  std::string library_content;
+  ASSERT_TRUE(base::ReadFileToString(path, &library_content)) << path.value();
+  utf8_content_.append(library_content);
+  utf8_content_.append(";\n");
+}
 
 // crbug.com/367817. Either this feature or just the test are depending
 // on the presense of Object.observe which is presently disabled by default.
 IN_PROC_BROWSER_TEST_F(VirtualKeyboardBrowserTest, DISABLED_AttributesTest) {
-  RunTest(base::FilePath(FILE_PATH_LITERAL("attributes_test.js")));
+  RunTest(base::FilePath(FILE_PATH_LITERAL("attributes_test.js")),
+          VirtualKeyboardBrowserTestConfig());
 }
 
 IN_PROC_BROWSER_TEST_F(VirtualKeyboardBrowserTest, TypingTest) {
-  RunTest(base::FilePath(FILE_PATH_LITERAL("typing_test.js")));
+  RunTest(base::FilePath(FILE_PATH_LITERAL("typing_test.js")),
+          VirtualKeyboardBrowserTestConfig());
 }
 
 IN_PROC_BROWSER_TEST_F(VirtualKeyboardBrowserTest, ControlKeysTest) {
-  RunTest(base::FilePath(FILE_PATH_LITERAL("control_keys_test.js")));
+  RunTest(base::FilePath(FILE_PATH_LITERAL("control_keys_test.js")),
+          VirtualKeyboardBrowserTestConfig());
 }
 
 IN_PROC_BROWSER_TEST_F(VirtualKeyboardBrowserTest, HideKeyboardKeyTest) {
-  RunTest(base::FilePath(FILE_PATH_LITERAL("hide_keyboard_key_test.js")));
+  RunTest(base::FilePath(FILE_PATH_LITERAL("hide_keyboard_key_test.js")),
+          VirtualKeyboardBrowserTestConfig());
 }
 
 IN_PROC_BROWSER_TEST_F(VirtualKeyboardBrowserTest, KeysetTransitionTest) {
-  RunTest(base::FilePath(FILE_PATH_LITERAL("keyset_transition_test.js")));
+  RunTest(base::FilePath(FILE_PATH_LITERAL("keyset_transition_test.js")),
+          VirtualKeyboardBrowserTestConfig());
 }
 
-IN_PROC_BROWSER_TEST_F(VirtualKeyboardBrowserTest, IsKeyboardLoaded) {
-  content::RenderViewHost* keyboard_rvh = GetKeyboardRenderViewHost();
+// Fails when enabling Object.observe. See http://crbug.com/370004
+#if defined(OS_CHROMEOS)
+#define MAYBE_IsKeyboardLoaded DISABLED_IsKeyboardLoaded
+#else
+#define MAYBE_IsKeyboardLoaded IsKeyboardLoaded
+#endif
+IN_PROC_BROWSER_TEST_F(VirtualKeyboardBrowserTest, MAYBE_IsKeyboardLoaded) {
+  content::RenderViewHost* keyboard_rvh =
+      GetKeyboardRenderViewHost(kExtensionId);
   ASSERT_TRUE(keyboard_rvh);
   bool loaded = false;
   std::string script = "!!chrome.virtualKeyboardPrivate";
@@ -153,9 +166,10 @@
   ASSERT_TRUE(loaded);
 }
 
-IN_PROC_BROWSER_TEST_F(VirtualKeyboardBrowserTest, EndToEndTest) {
+IN_PROC_BROWSER_TEST_F(VirtualKeyboardBrowserTest, DISABLED_EndToEndTest) {
   // Get the virtual keyboard's render view host.
-  content::RenderViewHost* keyboard_rvh = GetKeyboardRenderViewHost();
+  content::RenderViewHost* keyboard_rvh =
+      GetKeyboardRenderViewHost(kExtensionId);
   ASSERT_TRUE(keyboard_rvh);
 
   // Get the test page's render view host.
@@ -172,7 +186,7 @@
 
   // Press 'a' on keyboard.
   base::FilePath path = ui_test_utils::GetTestFilePath(
-      kVirtualKeyboardTestDir,
+      base::FilePath(FILE_PATH_LITERAL(kVirtualKeyboardTestDir)),
       base::FilePath(FILE_PATH_LITERAL("end_to_end_test.js")));
   std::string script;
   ASSERT_TRUE(base::ReadFileToString(path, &script));
diff --git a/chrome/browser/chromeos/extensions/virtual_keyboard_browsertest.h b/chrome/browser/chromeos/extensions/virtual_keyboard_browsertest.h
new file mode 100644
index 0000000..930edf2
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/virtual_keyboard_browsertest.h
@@ -0,0 +1,66 @@
+// 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_VIRTUAL_KEYBOARD_BROWSERTEST_H_
+#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_VIRTUAL_KEYBOARD_BROWSERTEST_H_
+
+#include "base/files/file_path.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "url/gurl.h"
+
+namespace base {
+class CommandLine;
+class FilePath;
+}
+
+namespace content {
+class RenderViewHost;
+class WebContents;
+}
+
+// See the .cc for default values.
+struct VirtualKeyboardBrowserTestConfig {
+  VirtualKeyboardBrowserTestConfig();
+
+  ~VirtualKeyboardBrowserTestConfig();
+
+  // The filename of the base framework. This file should be in |test_dir_|.
+  std::string base_framework_;
+
+  // The virtual keyboard's extension id.
+  std::string extension_id_;
+
+  // Path to the test directory.
+  std::string test_dir_;
+
+  // URL of the keyboard extension.
+  std::string url_;
+};
+
+class VirtualKeyboardBrowserTest : public InProcessBrowserTest {
+ public:
+  // Injects javascript in |file| into the keyboard page and runs the methods in
+  // |file| whose names match the expression "test*".
+  void RunTest(const base::FilePath& file,
+               const VirtualKeyboardBrowserTestConfig& config);
+
+  void ShowVirtualKeyboard();
+
+  // Returns the render view host that the keyboard with extension |id| is in.
+  content::RenderViewHost* GetKeyboardRenderViewHost(const std::string& id);
+
+  // InProcessBrowserTest.
+  // Ensure that the virtual keyboard is enabled.
+  virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE;
+
+ protected:
+  // Accumulates the javascript and injects it when the test starts. The test
+  // |file| is in directory |dir| relative to the root testing directory.
+  void InjectJavascript(const base::FilePath& dir, const base::FilePath& file);
+
+ private:
+  std::string utf8_content_;
+};
+
+#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_VIRTUAL_KEYBOARD_BROWSERTEST_H_
diff --git a/chrome/browser/chromeos/extensions/wallpaper_api.cc b/chrome/browser/chromeos/extensions/wallpaper_api.cc
index 383c7c7..7ce929d 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_api.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_api.cc
@@ -93,7 +93,7 @@
 WallpaperSetWallpaperFunction::~WallpaperSetWallpaperFunction() {
 }
 
-bool WallpaperSetWallpaperFunction::RunImpl() {
+bool WallpaperSetWallpaperFunction::RunAsync() {
   params_ = set_wallpaper::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params_);
 
diff --git a/chrome/browser/chromeos/extensions/wallpaper_api.h b/chrome/browser/chromeos/extensions/wallpaper_api.h
index 7fe549d..493ff55 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_api.h
+++ b/chrome/browser/chromeos/extensions/wallpaper_api.h
@@ -29,7 +29,7 @@
   virtual ~WallpaperSetWallpaperFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   virtual void OnWallpaperDecoded(const gfx::ImageSkia& image) OVERRIDE;
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
index f74db97..9643385 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -285,7 +285,7 @@
 WallpaperPrivateSetWallpaperIfExistsFunction::
     ~WallpaperPrivateSetWallpaperIfExistsFunction() {}
 
-bool WallpaperPrivateSetWallpaperIfExistsFunction::RunImpl() {
+bool WallpaperPrivateSetWallpaperIfExistsFunction::RunAsync() {
   params = set_wallpaper_if_exists::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
 
@@ -388,7 +388,7 @@
 WallpaperPrivateSetWallpaperFunction::~WallpaperPrivateSetWallpaperFunction() {
 }
 
-bool WallpaperPrivateSetWallpaperFunction::RunImpl() {
+bool WallpaperPrivateSetWallpaperFunction::RunAsync() {
   params = set_wallpaper::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
 
@@ -489,7 +489,7 @@
 WallpaperPrivateResetWallpaperFunction::
     ~WallpaperPrivateResetWallpaperFunction() {}
 
-bool WallpaperPrivateResetWallpaperFunction::RunImpl() {
+bool WallpaperPrivateResetWallpaperFunction::RunAsync() {
   chromeos::WallpaperManager* wallpaper_manager =
       chromeos::WallpaperManager::Get();
   chromeos::UserManager* user_manager = chromeos::UserManager::Get();
@@ -517,7 +517,7 @@
 WallpaperPrivateSetCustomWallpaperFunction::
     ~WallpaperPrivateSetCustomWallpaperFunction() {}
 
-bool WallpaperPrivateSetCustomWallpaperFunction::RunImpl() {
+bool WallpaperPrivateSetCustomWallpaperFunction::RunAsync() {
   params = set_custom_wallpaper::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
 
@@ -609,7 +609,7 @@
 WallpaperPrivateSetCustomWallpaperLayoutFunction::
     ~WallpaperPrivateSetCustomWallpaperLayoutFunction() {}
 
-bool WallpaperPrivateSetCustomWallpaperLayoutFunction::RunImpl() {
+bool WallpaperPrivateSetCustomWallpaperLayoutFunction::RunAsync() {
   scoped_ptr<set_custom_wallpaper_layout::Params> params(
       set_custom_wallpaper_layout::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -645,7 +645,7 @@
     ~WallpaperPrivateMinimizeInactiveWindowsFunction() {
 }
 
-bool WallpaperPrivateMinimizeInactiveWindowsFunction::RunImpl() {
+bool WallpaperPrivateMinimizeInactiveWindowsFunction::RunAsync() {
   WindowStateManager::MinimizeInactiveWindows(
       chromeos::UserManager::Get()->GetActiveUser()->username_hash());
   return true;
@@ -659,7 +659,7 @@
     ~WallpaperPrivateRestoreMinimizedWindowsFunction() {
 }
 
-bool WallpaperPrivateRestoreMinimizedWindowsFunction::RunImpl() {
+bool WallpaperPrivateRestoreMinimizedWindowsFunction::RunAsync() {
   WindowStateManager::RestoreWindows(
       chromeos::UserManager::Get()->GetActiveUser()->username_hash());
   return true;
@@ -671,7 +671,7 @@
 WallpaperPrivateGetThumbnailFunction::~WallpaperPrivateGetThumbnailFunction() {
 }
 
-bool WallpaperPrivateGetThumbnailFunction::RunImpl() {
+bool WallpaperPrivateGetThumbnailFunction::RunAsync() {
   scoped_ptr<get_thumbnail::Params> params(
       get_thumbnail::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -758,7 +758,7 @@
 WallpaperPrivateSaveThumbnailFunction::
     ~WallpaperPrivateSaveThumbnailFunction() {}
 
-bool WallpaperPrivateSaveThumbnailFunction::RunImpl() {
+bool WallpaperPrivateSaveThumbnailFunction::RunAsync() {
   scoped_ptr<save_thumbnail::Params> params(
       save_thumbnail::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -811,7 +811,7 @@
     ~WallpaperPrivateGetOfflineWallpaperListFunction() {
 }
 
-bool WallpaperPrivateGetOfflineWallpaperListFunction::RunImpl() {
+bool WallpaperPrivateGetOfflineWallpaperListFunction::RunAsync() {
   sequence_token_ = BrowserThread::GetBlockingPool()->
       GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName);
   scoped_refptr<base::SequencedTaskRunner> task_runner =
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.h b/chrome/browser/chromeos/extensions/wallpaper_private_api.h
index 5586c8b..a9be422 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.h
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.h
@@ -39,7 +39,7 @@
   virtual ~WallpaperPrivateSetWallpaperIfExistsFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   virtual void OnWallpaperDecoded(const gfx::ImageSkia& image) OVERRIDE;
@@ -74,7 +74,7 @@
   virtual ~WallpaperPrivateSetWallpaperFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   virtual void OnWallpaperDecoded(const gfx::ImageSkia& image) OVERRIDE;
@@ -111,7 +111,7 @@
   virtual ~WallpaperPrivateResetWallpaperFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class WallpaperPrivateSetCustomWallpaperFunction
@@ -126,7 +126,7 @@
   virtual ~WallpaperPrivateSetCustomWallpaperFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   virtual void OnWallpaperDecoded(const gfx::ImageSkia& wallpaper) OVERRIDE;
@@ -165,7 +165,7 @@
   virtual ~WallpaperPrivateSetCustomWallpaperLayoutFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class WallpaperPrivateMinimizeInactiveWindowsFunction
@@ -180,7 +180,7 @@
   virtual ~WallpaperPrivateMinimizeInactiveWindowsFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class WallpaperPrivateRestoreMinimizedWindowsFunction
@@ -195,7 +195,7 @@
   virtual ~WallpaperPrivateRestoreMinimizedWindowsFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class WallpaperPrivateGetThumbnailFunction : public AsyncExtensionFunction {
@@ -209,7 +209,7 @@
   virtual ~WallpaperPrivateGetThumbnailFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Failed to get thumbnail for |file_name|.
@@ -242,7 +242,7 @@
   virtual ~WallpaperPrivateSaveThumbnailFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Failed to save thumbnail for |file_name|.
@@ -270,7 +270,7 @@
   virtual ~WallpaperPrivateGetOfflineWallpaperListFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Enumerates the list of files in online wallpaper directory.
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
index ea63359..515f586 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
@@ -51,8 +51,8 @@
  public:
   TestMinimizeFunction() {}
 
-  virtual bool RunImpl() OVERRIDE {
-    return WallpaperPrivateMinimizeInactiveWindowsFunction::RunImpl();
+  virtual bool RunAsync() OVERRIDE {
+    return WallpaperPrivateMinimizeInactiveWindowsFunction::RunAsync();
   }
 
  protected:
@@ -64,8 +64,8 @@
  public:
   TestRestoreFunction() {}
 
-  virtual bool RunImpl() OVERRIDE {
-    return WallpaperPrivateRestoreMinimizedWindowsFunction::RunImpl();
+  virtual bool RunAsync() OVERRIDE {
+    return WallpaperPrivateRestoreMinimizedWindowsFunction::RunAsync();
   }
  protected:
   virtual ~TestRestoreFunction() {}
@@ -100,7 +100,7 @@
   EXPECT_TRUE(window0_state->IsActive());
   scoped_refptr<TestMinimizeFunction> minimize_function(
       new TestMinimizeFunction());
-  EXPECT_TRUE(minimize_function->RunImpl());
+  EXPECT_TRUE(minimize_function->RunAsync());
 
   // All windows except window 0 should be minimized.
   EXPECT_FALSE(window0_state->IsMinimized());
@@ -112,7 +112,7 @@
   window0.reset();
   scoped_refptr<TestRestoreFunction> restore_function(
       new TestRestoreFunction());
-  EXPECT_TRUE(restore_function->RunImpl());
+  EXPECT_TRUE(restore_function->RunAsync());
 
   // Windows 1 and 2 should no longer be minimized. Window 1 should again
   // be maximized. Window 3 should still be minimized.
@@ -140,7 +140,7 @@
   EXPECT_TRUE(window0_state->IsActive());
   scoped_refptr<TestMinimizeFunction> minimize_function_0(
       new TestMinimizeFunction());
-  EXPECT_TRUE(minimize_function_0->RunImpl());
+  EXPECT_TRUE(minimize_function_0->RunAsync());
 
   // All windows except window 0 should be minimized.
   EXPECT_FALSE(window0_state->IsMinimized());
@@ -150,7 +150,7 @@
   // change.
   scoped_refptr<TestMinimizeFunction> minimize_function_1(
       new TestMinimizeFunction());
-  EXPECT_TRUE(minimize_function_1->RunImpl());
+  EXPECT_TRUE(minimize_function_1->RunAsync());
 
   // All windows except window 0 should be minimized.
   EXPECT_FALSE(window0_state->IsMinimized());
@@ -163,7 +163,7 @@
 
   scoped_refptr<TestMinimizeFunction> minimize_function_2(
       new TestMinimizeFunction());
-  EXPECT_TRUE(minimize_function_2->RunImpl());
+  EXPECT_TRUE(minimize_function_2->RunAsync());
 
   // Window 1 should be minimized again.
   EXPECT_FALSE(window0_state->IsMinimized());
@@ -173,7 +173,7 @@
   window0.reset();
   scoped_refptr<TestRestoreFunction> restore_function(
       new TestRestoreFunction());
-  EXPECT_TRUE(restore_function->RunImpl());
+  EXPECT_TRUE(restore_function->RunAsync());
 
   // Windows 1 should no longer be minimized.
   EXPECT_FALSE(window1_state->IsMinimized());
@@ -280,7 +280,7 @@
   EXPECT_TRUE(window0_state->IsActive());
   scoped_refptr<TestMinimizeFunction> minimize_function_0(
       new TestMinimizeFunction());
-  EXPECT_TRUE(minimize_function_0->RunImpl());
+  EXPECT_TRUE(minimize_function_0->RunAsync());
 
   // All windows except window 0 should be minimized.
   EXPECT_FALSE(window0_state->IsMinimized());
@@ -298,7 +298,7 @@
   EXPECT_TRUE(window2_state->IsActive());
   scoped_refptr<TestMinimizeFunction> minimize_function_1(
       new TestMinimizeFunction());
-  EXPECT_TRUE(minimize_function_1->RunImpl());
+  EXPECT_TRUE(minimize_function_1->RunAsync());
 
   // All windows except window 2 should be minimized.
   EXPECT_FALSE(window2_state->IsMinimized());
@@ -322,7 +322,7 @@
   window2.reset();
   scoped_refptr<TestRestoreFunction> restore_function_0(
       new TestRestoreFunction());
-  EXPECT_TRUE(restore_function_0->RunImpl());
+  EXPECT_TRUE(restore_function_0->RunAsync());
 
   EXPECT_FALSE(window3_state->IsMinimized());
 
@@ -336,7 +336,7 @@
   window0.reset();
   scoped_refptr<TestRestoreFunction> restore_function_1(
       new TestRestoreFunction());
-  EXPECT_TRUE(restore_function_1->RunImpl());
+  EXPECT_TRUE(restore_function_1->RunAsync());
 
   EXPECT_FALSE(window1_state->IsMinimized());
   EXPECT_FALSE(window3_state->IsMinimized());
@@ -380,7 +380,7 @@
   EXPECT_TRUE(window0_state->IsActive());
   scoped_refptr<TestMinimizeFunction> minimize_function_0(
       new TestMinimizeFunction());
-  EXPECT_TRUE(minimize_function_0->RunImpl());
+  EXPECT_TRUE(minimize_function_0->RunAsync());
 
   // All windows except window 0 should be minimized.
   EXPECT_FALSE(window0_state->IsMinimized());
@@ -395,7 +395,7 @@
   window0.reset();
   scoped_refptr<TestRestoreFunction> restore_function_1(
       new TestRestoreFunction());
-  EXPECT_TRUE(restore_function_1->RunImpl());
+  EXPECT_TRUE(restore_function_1->RunAsync());
 
   EXPECT_FALSE(window1_state->IsMinimized());
   EXPECT_FALSE(window2_state->IsMinimized());
diff --git a/chrome/browser/chromeos/external_protocol_dialog.cc b/chrome/browser/chromeos/external_protocol_dialog.cc
index 7bed86d..06c44d5 100644
--- a/chrome/browser/chromeos/external_protocol_dialog.cc
+++ b/chrome/browser/chromeos/external_protocol_dialog.cc
@@ -10,7 +10,6 @@
 #include "chrome/browser/external_protocol/external_protocol_handler.h"
 #include "chrome/browser/tab_contents/tab_util.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -108,7 +107,7 @@
 
   gfx::NativeWindow parent_window;
   if (web_contents) {
-    parent_window = web_contents->GetView()->GetTopLevelNativeWindow();
+    parent_window = web_contents->GetTopLevelNativeWindow();
   } else {
     // Dialog is top level if we don't have a web_contents associated with us.
     parent_window = NULL;
diff --git a/chrome/browser/chromeos/file_manager/app_installer.cc b/chrome/browser/chromeos/file_manager/app_installer.cc
index 40c90cd..637bc2f 100644
--- a/chrome/browser/chromeos/file_manager/app_installer.cc
+++ b/chrome/browser/chromeos/file_manager/app_installer.cc
@@ -27,9 +27,8 @@
 
  protected:
   // content::WebContentsObserver implementation.
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE {
-    parent_->OnWebContentsDestroyed(web_contents);
+  virtual void WebContentsDestroyed() OVERRIDE {
+    parent_->OnWebContentsDestroyed(web_contents());
   }
 
  private:
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index 04e60ce..a98b2f0 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -775,8 +775,9 @@
                       TestParameter(NOT_IN_GUEST_MODE,
                                     "renameFileDrive")));
 
+// Disabled due to frequent timeouts; http://crbug.com/370980.
 INSTANTIATE_TEST_CASE_P(
-    DriveSpecific,
+    DISABLED_DriveSpecific,
     FileManagerBrowserTest,
     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "openSidebarRecent"),
                       TestParameter(NOT_IN_GUEST_MODE, "openSidebarOffline"),
diff --git a/chrome/browser/chromeos/file_manager/zip_file_creator.cc b/chrome/browser/chromeos/file_manager/zip_file_creator.cc
index 61d813a..f6e0788 100644
--- a/chrome/browser/chromeos/file_manager/zip_file_creator.cc
+++ b/chrome/browser/chromeos/file_manager/zip_file_creator.cc
@@ -5,42 +5,47 @@
 #include "chrome/browser/chromeos/file_manager/zip_file_creator.h"
 
 #include "base/bind.h"
-#include "base/command_line.h"
-#include "base/files/file_util_proxy.h"
-#include "base/memory/scoped_handle.h"
+#include "base/callback_helpers.h"
 #include "base/message_loop/message_loop.h"
-#include "base/path_service.h"
 #include "base/threading/sequenced_worker_pool.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_utility_messages.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/utility_process_host.h"
-#include "grit/generated_resources.h"
 
 using content::BrowserThread;
 using content::UtilityProcessHost;
 
+namespace {
+
+// Creates the destination zip file only if it does not already exist.
+base::File OpenFileHandleOnBlockingThreadPool(const base::FilePath& zip_path) {
+  return base::File(zip_path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
+}
+
+}  // namespace
+
 namespace file_manager {
 
 ZipFileCreator::ZipFileCreator(
-    Observer* observer,
+    const ResultCallback& callback,
     const base::FilePath& src_dir,
     const std::vector<base::FilePath>& src_relative_paths,
     const base::FilePath& dest_file)
-    : thread_identifier_(BrowserThread::ID_COUNT),
-      observer_(observer),
+    : callback_(callback),
       src_dir_(src_dir),
       src_relative_paths_(src_relative_paths),
-      dest_file_(dest_file),
-      got_response_(false) {
+      dest_file_(dest_file) {
+  DCHECK(!callback_.is_null());
 }
 
 void ZipFileCreator::Start() {
-  CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_identifier_));
-  BrowserThread::GetBlockingPool()->PostTask(
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  base::PostTaskAndReplyWithResult(
+      BrowserThread::GetBlockingPool(),
       FROM_HERE,
-      base::Bind(&ZipFileCreator::OpenFileHandleOnBlockingThreadPool, this));
+      base::Bind(&OpenFileHandleOnBlockingThreadPool, dest_file_),
+      base::Bind(&ZipFileCreator::OnOpenFileHandle, this));
 }
 
 ZipFileCreator::~ZipFileCreator() {
@@ -59,40 +64,33 @@
 }
 
 void ZipFileCreator::OnProcessCrashed(int exit_code) {
-  // Don't report crashes if they happen after we got a response.
-  if (got_response_)
-    return;
-
-  // Utility process crashed while trying to create the zip file.
   ReportDone(false);
 }
 
-void ZipFileCreator::OpenFileHandleOnBlockingThreadPool() {
-  // Create the destination zip file only if it does not already exist.
-  base::File dest_file(dest_file_,
-                       base::File::FLAG_CREATE | base::File::FLAG_WRITE);
+void ZipFileCreator::OnOpenFileHandle(base::File file) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  if (!dest_file.IsValid()) {
+  if (!file.IsValid()) {
     LOG(ERROR) << "Failed to create dest zip file " << dest_file_.value();
-
-    BrowserThread::GetMessageLoopProxyForThread(thread_identifier_)->PostTask(
-        FROM_HERE,
-        base::Bind(&ZipFileCreator::ReportDone, this, false));
+    ReportDone(false);
     return;
   }
 
   BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::Bind(&ZipFileCreator::StartProcessOnIOThread, this,
-                 Passed(&dest_file)));
+      BrowserThread::IO,
+      FROM_HERE,
+      base::Bind(
+          &ZipFileCreator::StartProcessOnIOThread, this, base::Passed(&file)));
 }
 
 void ZipFileCreator::StartProcessOnIOThread(base::File dest_file) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
   base::FileDescriptor dest_fd(dest_file.Pass());
 
   UtilityProcessHost* host = UtilityProcessHost::Create(
       this,
-      BrowserThread::GetMessageLoopProxyForThread(thread_identifier_).get());
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get());
   host->SetExposedDir(src_dir_);
   host->Send(new ChromeUtilityMsg_CreateZipFile(src_dir_, src_relative_paths_,
                                                 dest_fd));
@@ -107,16 +105,11 @@
 }
 
 void ZipFileCreator::ReportDone(bool success) {
-  // Skip check for unittests.
-  if (thread_identifier_ != BrowserThread::ID_COUNT)
-    DCHECK(BrowserThread::CurrentlyOn(thread_identifier_));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // Guard against calling observer multiple times.
-  if (got_response_)
-    return;
-
-  got_response_ = true;
-  observer_->OnZipDone(success);
+  if (!callback_.is_null())
+    base::ResetAndReturn(&callback_).Run(success);
 }
 
 }  // namespace file_manager
diff --git a/chrome/browser/chromeos/file_manager/zip_file_creator.h b/chrome/browser/chromeos/file_manager/zip_file_creator.h
index 510f19e..f94e931 100644
--- a/chrome/browser/chromeos/file_manager/zip_file_creator.h
+++ b/chrome/browser/chromeos/file_manager/zip_file_creator.h
@@ -5,13 +5,10 @@
 #ifndef CHROME_BROWSER_CHROMEOS_FILE_MANAGER_ZIP_FILE_CREATOR_H_
 #define CHROME_BROWSER_CHROMEOS_FILE_MANAGER_ZIP_FILE_CREATOR_H_
 
-#include <string>
-
+#include "base/callback.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
-#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/utility_process_host_client.h"
-#include "extensions/common/extension.h"
 
 namespace file_manager {
 
@@ -20,30 +17,22 @@
 // subprocess to protect the browser process from handling arbitrary input data
 // from untrusted sources.
 //
-// Lifetime management:
-//
-// This class is ref-counted by each call it makes to itself on another thread,
-// and by UtilityProcessHost.
-//
-// Additionally, we hold a reference to our own client so that it lives at least
-// long enough to receive the result of zip file creation.
+// The class is ref-counted and its ownership is passed around internal callback
+// objects and finally to UtilityProcessHost. After the job finishes, the host
+// releases the ref-pointer and then ZipFileCreator is automatically deleted.
 class ZipFileCreator : public content::UtilityProcessHostClient {
  public:
-  class Observer {
-   public:
-    virtual void OnZipDone(bool success) = 0;
-
-   protected:
-    virtual ~Observer() {}
-  };
+  typedef base::Callback<void(bool)> ResultCallback;
 
   // Creates a zip file from the specified list of files and directories.
-  ZipFileCreator(Observer* observer,
+  ZipFileCreator(const ResultCallback& callback,
                  const base::FilePath& src_dir,
                  const std::vector<base::FilePath>& src_relative_paths,
                  const base::FilePath& dest_file);
 
-  // Start creating the zip file. The client is called with the results.
+  // Starts creating the zip file. Must be called from the UI thread.
+  // The result will be passed to |callback|. After the task is finished and
+  // |callback| is run, ZipFileCreator instance is deleted.
   void Start();
 
  private:
@@ -51,8 +40,8 @@
 
   virtual ~ZipFileCreator();
 
-  // Opens a handle for the zip file, and proceeds to StartProcessOnIOThread.
-  void OpenFileHandleOnBlockingThreadPool();
+  // Called after the file handle is opened on blocking pool.
+  void OnOpenFileHandle(base::File file);
 
   // Starts the utility process that creates the zip file.
   void StartProcessOnIOThread(base::File dest_file);
@@ -67,11 +56,8 @@
 
   void ReportDone(bool success);
 
-  // The observer's thread. This is the thread we respond on.
-  content::BrowserThread::ID thread_identifier_;
-
-  // The observer.
-  Observer* observer_;
+  // The callback.
+  ResultCallback callback_;
 
   // The source directory for input files.
   base::FilePath src_dir_;
@@ -82,9 +68,6 @@
 
   // The output zip file.
   base::FilePath dest_file_;
-
-  // Whether we've received a response from the utility process yet.
-  bool got_response_;
 };
 
 }  // namespace file_manager
diff --git a/chrome/browser/chromeos/file_manager/zip_file_creator_browsertest.cc b/chrome/browser/chromeos/file_manager/zip_file_creator_browsertest.cc
index e8788f5..e81ef66 100644
--- a/chrome/browser/chromeos/file_manager/zip_file_creator_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/zip_file_creator_browsertest.cc
@@ -6,7 +6,7 @@
 
 #include <vector>
 
-#include "base/callback.h"
+#include "base/bind.h"
 #include "base/file_util.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
@@ -21,22 +21,10 @@
 
 namespace {
 
-class TestObserver : public ZipFileCreator::Observer {
- public:
-  explicit TestObserver(const base::Closure& quit)
-      : success_(false), quit_(quit) {}
-
-  virtual void OnZipDone(bool success) OVERRIDE {
-    success_ = success;
-    quit_.Run();
-  }
-
-  const bool success() const { return success_; }
-
- private:
-  bool success_;
-  const base::Closure quit_;
-};
+void TestCallback(bool* out_success, const base::Closure& quit, bool success) {
+  *out_success = success;
+  quit.Run();
+}
 
 class ZipFileCreatorTest : public InProcessBrowserTest {
  protected:
@@ -61,16 +49,19 @@
 
 IN_PROC_BROWSER_TEST_F(ZipFileCreatorTest, FailZipForAbsentFile) {
   base::RunLoop run_loop;
-  TestObserver observer(content::GetQuitTaskForRunLoop(&run_loop));
+  bool success = true;
 
   std::vector<base::FilePath> paths;
   paths.push_back(base::FilePath(FILE_PATH_LITERAL("not.exist")));
-  scoped_refptr<ZipFileCreator> zipper(new ZipFileCreator(
-      &observer, zip_base_dir(), paths, zip_archive_path()));
-  zipper->Start();
+  (new ZipFileCreator(
+       base::Bind(
+           &TestCallback, &success, content::GetQuitTaskForRunLoop(&run_loop)),
+       zip_base_dir(),
+       paths,
+       zip_archive_path()))->Start();
 
   content::RunThisRunLoop(&run_loop);
-  EXPECT_FALSE(observer.success());
+  EXPECT_FALSE(success);
 }
 
 IN_PROC_BROWSER_TEST_F(ZipFileCreatorTest, SomeFilesZip) {
@@ -85,19 +76,22 @@
   base::WriteFile(zip_base_dir().Append(kFile2),
                   kRandomData.c_str(), kRandomData.size());
 
+  bool success = false;
   base::RunLoop run_loop;
-  TestObserver observer(content::GetQuitTaskForRunLoop(&run_loop));
 
   std::vector<base::FilePath> paths;
   paths.push_back(kDir1);
   paths.push_back(kFile1);
   paths.push_back(kFile2);
-  scoped_refptr<ZipFileCreator> zipper(new ZipFileCreator(
-      &observer, zip_base_dir(), paths, zip_archive_path()));
-  zipper->Start();
+  (new ZipFileCreator(
+       base::Bind(
+           &TestCallback, &success, content::GetQuitTaskForRunLoop(&run_loop)),
+       zip_base_dir(),
+       paths,
+       zip_archive_path()))->Start();
 
   content::RunThisRunLoop(&run_loop);
-  EXPECT_TRUE(observer.success());
+  EXPECT_TRUE(success);
 
   // Check the archive content.
   zip::ZipReader reader;
diff --git a/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc
index 68a424d..f27aeb0 100644
--- a/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc
+++ b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.cc
@@ -4,12 +4,31 @@
 
 #include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
 
+#include <string>
+
 #include "base/files/file.h"
 #include "base/message_loop/message_loop_proxy.h"
 #include "extensions/browser/event_router.h"
 
 namespace chromeos {
 namespace file_system_provider {
+namespace {
+
+// Adds a fake entry to the entry list.
+void AddDirectoryEntry(fileapi::AsyncFileUtil::EntryList* entry_list,
+                       const std::string& name,
+                       fileapi::DirectoryEntry::DirectoryEntryType type,
+                       int64 size,
+                       std::string last_modified_time_string) {
+  base::Time last_modified_time;
+  const bool result = base::Time::FromString(last_modified_time_string.c_str(),
+                                             &last_modified_time);
+  DCHECK(result);
+  entry_list->push_back(
+      fileapi::DirectoryEntry(name, type, size, last_modified_time));
+}
+
+}  // namespace
 
 FakeProvidedFileSystem::FakeProvidedFileSystem(
     const ProvidedFileSystemInfo& file_system_info)
@@ -24,6 +43,81 @@
       FROM_HERE, base::Bind(callback, base::File::FILE_OK));
 }
 
+void FakeProvidedFileSystem::GetMetadata(
+    const base::FilePath& entry_path,
+    const fileapi::AsyncFileUtil::GetFileInfoCallback& callback) {
+  // Return fake metadata for the root directory only.
+  if (entry_path.AsUTF8Unsafe() != "/") {
+    base::MessageLoopProxy::current()->PostTask(
+        FROM_HERE,
+        base::Bind(
+            callback, base::File::FILE_ERROR_NOT_FOUND, base::File::Info()));
+    return;
+  }
+
+  base::File::Info file_info;
+  file_info.size = 0;
+  file_info.is_directory = true;
+  file_info.is_symbolic_link = false;
+  base::Time last_modified_time;
+  const bool result = base::Time::FromString("Thu Apr 24 00:46:52 UTC 2014",
+                                             &last_modified_time);
+  DCHECK(result);
+  file_info.last_modified = last_modified_time;
+
+  base::MessageLoopProxy::current()->PostTask(
+      FROM_HERE, base::Bind(callback, base::File::FILE_OK, file_info));
+}
+
+void FakeProvidedFileSystem::ReadDirectory(
+    const base::FilePath& directory_path,
+    const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) {
+  // Return fake contents for the root directory only.
+  if (directory_path.AsUTF8Unsafe() != "/") {
+    base::MessageLoopProxy::current()->PostTask(
+        FROM_HERE,
+        base::Bind(callback,
+                   base::File::FILE_ERROR_NOT_FOUND,
+                   fileapi::AsyncFileUtil::EntryList(),
+                   false /* has_more */));
+    return;
+  }
+
+  {
+    fileapi::AsyncFileUtil::EntryList entry_list;
+    AddDirectoryEntry(&entry_list,
+                      "hello.txt",
+                      fileapi::DirectoryEntry::FILE,
+                      1024 /* size */,
+                      "Thu Apr 24 00:46:52 UTC 2014");
+
+    AddDirectoryEntry(&entry_list,
+                      "world.txt",
+                      fileapi::DirectoryEntry::FILE,
+                      1024 /* size */,
+                      "Wed Apr 23 00:20:30 UTC 2014");
+
+    base::MessageLoopProxy::current()->PostTask(
+        FROM_HERE,
+        base::Bind(
+            callback, base::File::FILE_OK, entry_list, true /* has_more */));
+  }
+
+  {
+    fileapi::AsyncFileUtil::EntryList entry_list;
+    AddDirectoryEntry(&entry_list,
+                      "pictures",
+                      fileapi::DirectoryEntry::DIRECTORY,
+                      0 /* size */,
+                      "Tue May 22 00:40:50 UTC 2014");
+
+    base::MessageLoopProxy::current()->PostTask(
+        FROM_HERE,
+        base::Bind(
+            callback, base::File::FILE_OK, entry_list, false /* has_more */));
+  }
+}
+
 const ProvidedFileSystemInfo& FakeProvidedFileSystem::GetFileSystemInfo()
     const {
   return file_system_info_;
diff --git a/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h
index 60a9f63..47dcdcf 100644
--- a/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h
+++ b/chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h
@@ -5,8 +5,6 @@
 #ifndef CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_FAKE_PROVIDED_FILE_SYSTEM_H_
 #define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_FAKE_PROVIDED_FILE_SYSTEM_H_
 
-#include <string>
-
 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
 
@@ -30,6 +28,12 @@
   // ProvidedFileSystemInterface overrides.
   virtual void RequestUnmount(
       const fileapi::AsyncFileUtil::StatusCallback& callback) OVERRIDE;
+  virtual void GetMetadata(
+      const base::FilePath& entry_path,
+      const fileapi::AsyncFileUtil::GetFileInfoCallback& callback) OVERRIDE;
+  virtual void ReadDirectory(
+      const base::FilePath& directory_path,
+      const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) OVERRIDE;
   virtual const ProvidedFileSystemInfo& GetFileSystemInfo() const OVERRIDE;
   virtual RequestManager* GetRequestManager() OVERRIDE;
 
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/backend_delegate.cc b/chrome/browser/chromeos/file_system_provider/fileapi/backend_delegate.cc
index bf3f8b4..2b41fe3 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/backend_delegate.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/backend_delegate.cc
@@ -23,7 +23,7 @@
 
 fileapi::AsyncFileUtil* BackendDelegate::GetAsyncFileUtil(
     fileapi::FileSystemType type) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK_EQ(fileapi::kFileSystemTypeProvided, type);
   return async_file_util_.get();
 }
@@ -34,7 +34,7 @@
     int64 offset,
     const base::Time& expected_modification_time,
     fileapi::FileSystemContext* context) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK_EQ(fileapi::kFileSystemTypeProvided, url.type());
   NOTIMPLEMENTED();
   return scoped_ptr<webkit_blob::FileStreamReader>();
@@ -44,7 +44,7 @@
     const fileapi::FileSystemURL& url,
     int64 offset,
     fileapi::FileSystemContext* context) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK_EQ(fileapi::kFileSystemTypeProvided, url.type());
   NOTIMPLEMENTED();
   return scoped_ptr<fileapi::FileStreamWriter>();
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc b/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc
index b4a5cce..cf41cbc 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.cc
@@ -5,9 +5,12 @@
 #include "chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.h"
 
 #include "base/callback.h"
+#include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/platform_file.h"
+#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
+#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
 #include "content/public/browser/browser_thread.h"
 #include "webkit/browser/fileapi/file_system_operation_context.h"
 #include "webkit/browser/fileapi/file_system_url.h"
@@ -18,6 +21,58 @@
 namespace chromeos {
 namespace file_system_provider {
 namespace internal {
+namespace {
+
+// Executes GetFileInfo on the UI thread.
+void GetFileInfoOnUIThread(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    const fileapi::AsyncFileUtil::GetFileInfoCallback& callback) {
+  util::FileSystemURLParser parser(url);
+  if (!parser.Parse()) {
+    callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info());
+    return;
+  }
+
+  parser.file_system()->GetMetadata(parser.file_path(), callback);
+}
+
+// Routes the response of GetFileInfo back to the IO thread.
+void OnGetFileInfo(const fileapi::AsyncFileUtil::GetFileInfoCallback& callback,
+                   base::File::Error result,
+                   const base::File::Info& file_info) {
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE, base::Bind(callback, result, file_info));
+}
+
+// Executes ReadDirectory on the UI thread.
+void ReadDirectoryOnUIThread(
+    scoped_ptr<fileapi::FileSystemOperationContext> context,
+    const fileapi::FileSystemURL& url,
+    const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) {
+  util::FileSystemURLParser parser(url);
+  if (!parser.Parse()) {
+    callback.Run(base::File::FILE_ERROR_NOT_FOUND,
+                 fileapi::AsyncFileUtil::EntryList(),
+                 false /* has_more */);
+    return;
+  }
+
+  parser.file_system()->ReadDirectory(parser.file_path(), callback);
+}
+
+// Routes the response of ReadDirectory back to the IO thread.
+void OnReadDirectory(
+    const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback,
+    base::File::Error result,
+    const fileapi::AsyncFileUtil::EntryList& entry_list,
+    bool has_more) {
+  BrowserThread::PostTask(BrowserThread::IO,
+                          FROM_HERE,
+                          base::Bind(callback, result, entry_list, has_more));
+}
+
+}  // namespace
 
 ProviderAsyncFileUtil::ProviderAsyncFileUtil() {}
 
@@ -28,7 +83,7 @@
     const fileapi::FileSystemURL& url,
     int file_flags,
     const CreateOrOpenCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   base::PlatformFile platform_file = base::kInvalidPlatformFileValue;
   if ((file_flags & base::PLATFORM_FILE_CREATE) ||
       (file_flags & base::PLATFORM_FILE_OPEN_ALWAYS) ||
@@ -50,7 +105,7 @@
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const EnsureFileExistsCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   callback.Run(base::File::FILE_ERROR_SECURITY, false /* created */);
 }
 
@@ -60,7 +115,7 @@
     bool exclusive,
     bool recursive,
     const StatusCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   callback.Run(base::File::FILE_ERROR_SECURITY);
 }
 
@@ -68,18 +123,26 @@
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const GetFileInfoCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  NOTIMPLEMENTED();
-  callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info());
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  BrowserThread::PostTask(BrowserThread::UI,
+                          FROM_HERE,
+                          base::Bind(&GetFileInfoOnUIThread,
+                                     base::Passed(&context),
+                                     url,
+                                     base::Bind(&OnGetFileInfo, callback)));
 }
 
 void ProviderAsyncFileUtil::ReadDirectory(
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const ReadDirectoryCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  NOTIMPLEMENTED();
-  callback.Run(base::File::FILE_ERROR_NOT_FOUND, EntryList(), false);
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  BrowserThread::PostTask(BrowserThread::UI,
+                          FROM_HERE,
+                          base::Bind(&ReadDirectoryOnUIThread,
+                                     base::Passed(&context),
+                                     url,
+                                     base::Bind(&OnReadDirectory, callback)));
 }
 
 void ProviderAsyncFileUtil::Touch(
@@ -88,7 +151,7 @@
     const base::Time& last_access_time,
     const base::Time& last_modified_time,
     const StatusCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   callback.Run(base::File::FILE_ERROR_SECURITY);
 }
 
@@ -97,7 +160,7 @@
     const fileapi::FileSystemURL& url,
     int64 length,
     const StatusCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   callback.Run(base::File::FILE_ERROR_SECURITY);
 }
 
@@ -108,7 +171,7 @@
     CopyOrMoveOption option,
     const CopyFileProgressCallback& progress_callback,
     const StatusCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   callback.Run(base::File::FILE_ERROR_SECURITY);
 }
 
@@ -118,7 +181,7 @@
     const fileapi::FileSystemURL& dest_url,
     CopyOrMoveOption option,
     const StatusCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   callback.Run(base::File::FILE_ERROR_SECURITY);
 }
 
@@ -127,7 +190,7 @@
     const base::FilePath& src_file_path,
     const fileapi::FileSystemURL& dest_url,
     const StatusCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   callback.Run(base::File::FILE_ERROR_SECURITY);
 }
 
@@ -135,7 +198,7 @@
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const StatusCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   callback.Run(base::File::FILE_ERROR_SECURITY);
 }
 
@@ -143,7 +206,7 @@
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const StatusCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   callback.Run(base::File::FILE_ERROR_SECURITY);
 }
 
@@ -151,7 +214,7 @@
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const StatusCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   callback.Run(base::File::FILE_ERROR_SECURITY);
 }
 
@@ -159,7 +222,7 @@
     scoped_ptr<fileapi::FileSystemOperationContext> context,
     const fileapi::FileSystemURL& url,
     const CreateSnapshotFileCallback& callback) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
   NOTIMPLEMENTED();
   callback.Run(base::File::FILE_ERROR_NOT_FOUND,
                base::File::Info(),
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util_unittest.cc b/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util_unittest.cc
index 8b18bb8..a02ce1c 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util_unittest.cc
@@ -11,11 +11,17 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/platform_file.h"
+#include "base/run_loop.h"
+#include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
 #include "chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.h"
-#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
+#include "chrome/browser/chromeos/file_system_provider/service.h"
+#include "chrome/browser/chromeos/file_system_provider/service_factory.h"
+#include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_file_system_context.h"
+#include "extensions/browser/extension_registry.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "webkit/browser/fileapi/async_file_util.h"
 #include "webkit/browser/fileapi/external_mount_points.h"
@@ -28,7 +34,6 @@
 namespace {
 
 const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
-const int kFileSystemId = 1;
 
 // Logs callbacks invocations on the tested operations.
 // TODO(mtomasz): Store and verify more arguments, once the operations return
@@ -86,42 +91,6 @@
   DISALLOW_COPY_AND_ASSIGN(EventLogger);
 };
 
-// Registers an external mount point, and removes it once the object gets out
-// of scope. To ensure that creating the mount point succeeded, call is_valid().
-class ScopedExternalMountPoint {
- public:
-  ScopedExternalMountPoint(const std::string& mount_point_name,
-                           const base::FilePath& mount_path,
-                           fileapi::FileSystemType type)
-      : mount_point_name_(mount_point_name) {
-    fileapi::ExternalMountPoints* const mount_points =
-        fileapi::ExternalMountPoints::GetSystemInstance();
-    DCHECK(mount_points);
-    is_valid_ =
-        mount_points->RegisterFileSystem(mount_point_name,
-                                         fileapi::kFileSystemTypeProvided,
-                                         fileapi::FileSystemMountOption(),
-                                         mount_path);
-  }
-
-  virtual ~ScopedExternalMountPoint() {
-    if (!is_valid_)
-      return;
-
-    // If successfully registered in the constructor, then unregister.
-    fileapi::ExternalMountPoints* const mount_points =
-        fileapi::ExternalMountPoints::GetSystemInstance();
-    DCHECK(mount_points);
-    mount_points->RevokeFileSystem(mount_point_name_);
-  }
-
-  bool is_valid() { return is_valid_; }
-
- private:
-  const std::string mount_point_name_;
-  bool is_valid_;
-};
-
 // Creates a cracked FileSystemURL for tests.
 fileapi::FileSystemURL CreateFileSystemURL(const std::string& mount_point_name,
                                            const base::FilePath& file_path) {
@@ -134,6 +103,13 @@
       base::FilePath::FromUTF8Unsafe(mount_point_name).Append(file_path));
 }
 
+// Creates a Service instance. Used to be able to destroy the service in
+// TearDown().
+KeyedService* CreateService(content::BrowserContext* context) {
+  return new Service(Profile::FromBrowserContext(context),
+                     extensions::ExtensionRegistry::Get(context));
+}
+
 }  // namespace
 
 // Tests in this file are very lightweight and just test integration between
@@ -148,17 +124,28 @@
 
   virtual void SetUp() OVERRIDE {
     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
-    profile_.reset(new TestingProfile);
+    profile_manager_.reset(
+        new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
+    ASSERT_TRUE(profile_manager_->SetUp());
+    profile_ = profile_manager_->CreateTestingProfile("testing-profile");
     async_file_util_.reset(new internal::ProviderAsyncFileUtil);
-    const base::FilePath mount_path =
-        util::GetMountPath(profile_.get(), kExtensionId, kFileSystemId);
+
     file_system_context_ =
         content::CreateFileSystemContextForTesting(NULL, data_dir_.path());
 
-    const std::string mount_point_name = mount_path.BaseName().AsUTF8Unsafe();
-    mount_point_.reset(new ScopedExternalMountPoint(
-        mount_point_name, mount_path, fileapi::kFileSystemTypeProvided));
-    ASSERT_TRUE(mount_point_->is_valid());
+    ServiceFactory::GetInstance()->SetTestingFactory(profile_, &CreateService);
+    Service* service = Service::Get(profile_);  // Owned by its factory.
+    service->SetFileSystemFactoryForTests(
+        base::Bind(&FakeProvidedFileSystem::Create));
+
+    const int file_system_id =
+        service->MountFileSystem(kExtensionId, "testing-file-system");
+    ASSERT_LT(0, file_system_id);
+    const ProvidedFileSystemInfo& file_system_info =
+        service->GetProvidedFileSystem(kExtensionId, file_system_id)
+            ->GetFileSystemInfo();
+    const std::string mount_point_name =
+        file_system_info.mount_path().BaseName().AsUTF8Unsafe();
 
     file_url_ = CreateFileSystemURL(
         mount_point_name, base::FilePath::FromUTF8Unsafe("hello/world.txt"));
@@ -170,6 +157,12 @@
     ASSERT_TRUE(root_url_.is_valid());
   }
 
+  virtual void TearDown() OVERRIDE {
+    // Setting the testing factory to NULL will destroy the created service
+    // associated with the testing profile.
+    ServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL);
+  }
+
   scoped_ptr<fileapi::FileSystemOperationContext> CreateOperationContext() {
     return make_scoped_ptr(
         new fileapi::FileSystemOperationContext(file_system_context_.get()));
@@ -177,10 +170,10 @@
 
   content::TestBrowserThreadBundle thread_bundle_;
   base::ScopedTempDir data_dir_;
-  scoped_ptr<TestingProfile> profile_;
+  scoped_ptr<TestingProfileManager> profile_manager_;
+  TestingProfile* profile_;  // Owned by TestingProfileManager.
   scoped_ptr<fileapi::AsyncFileUtil> async_file_util_;
   scoped_refptr<fileapi::FileSystemContext> file_system_context_;
-  scoped_ptr<ScopedExternalMountPoint> mount_point_;
   fileapi::FileSystemURL file_url_;
   fileapi::FileSystemURL directory_url_;
   fileapi::FileSystemURL root_url_;
@@ -283,11 +276,12 @@
 
   async_file_util_->GetFileInfo(
       CreateOperationContext(),
-      file_url_,
+      root_url_,
       base::Bind(&EventLogger::OnGetFileInfo, logger.GetWeakPtr()));
+  base::RunLoop().RunUntilIdle();
 
   ASSERT_TRUE(logger.error());
-  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, *logger.error());
+  EXPECT_EQ(base::File::FILE_OK, *logger.error());
 }
 
 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, ReadDirectory) {
@@ -297,9 +291,10 @@
       CreateOperationContext(),
       root_url_,
       base::Bind(&EventLogger::OnReadDirectory, logger.GetWeakPtr()));
+  base::RunLoop().RunUntilIdle();
 
   ASSERT_TRUE(logger.error());
-  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, *logger.error());
+  EXPECT_EQ(base::File::FILE_OK, *logger.error());
 }
 
 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, Touch) {
diff --git a/chrome/browser/chromeos/file_system_provider/mount_path_util.cc b/chrome/browser/chromeos/file_system_provider/mount_path_util.cc
index ed7016d..a7a351d 100644
--- a/chrome/browser/chromeos/file_system_provider/mount_path_util.cc
+++ b/chrome/browser/chromeos/file_system_provider/mount_path_util.cc
@@ -16,6 +16,9 @@
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
 
 namespace chromeos {
 namespace file_system_provider {
@@ -50,6 +53,8 @@
 }
 
 bool FileSystemURLParser::Parse() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
   if (url_.type() != fileapi::kFileSystemTypeProvided)
     return false;
 
@@ -80,7 +85,7 @@
     std::vector<base::FilePath::StringType> components;
     url_.virtual_path().GetComponents(&components);
     DCHECK_LT(0u, components.size());
-    file_path_ = base::FilePath();
+    file_path_ = base::FilePath::FromUTF8Unsafe("/");
     for (size_t i = 1; i < components.size(); ++i) {
       // TODO(mtomasz): This could be optimized, to avoid unnecessary copies.
       file_path_ = file_path_.Append(components[i]);
diff --git a/chrome/browser/chromeos/file_system_provider/mount_path_util.h b/chrome/browser/chromeos/file_system_provider/mount_path_util.h
index 25f6129..91f91e9 100644
--- a/chrome/browser/chromeos/file_system_provider/mount_path_util.h
+++ b/chrome/browser/chromeos/file_system_provider/mount_path_util.h
@@ -25,16 +25,15 @@
                             int file_system_id);
 
 // Finds file system, which is responsible for handling the specified |url| by
-// analysing the mount path.
-// Also, extract the file path from the virtual path to be used by the file
-// system operations.
+// analysing the mount path. Also, extract the file path from the virtual path
+// to be used by the file system operations.
 class FileSystemURLParser {
  public:
   explicit FileSystemURLParser(const fileapi::FileSystemURL& url);
   virtual ~FileSystemURLParser();
 
   // Parses the |url| passed to the constructor. If parsing succeeds, then
-  // returns true. Otherwise, false.
+  // returns true. Otherwise, false. Must be called on UI thread.
   bool Parse();
 
   ProvidedFileSystemInterface* file_system() const { return file_system_; }
diff --git a/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc b/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc
index f4f843b..80fb16a 100644
--- a/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/mount_path_util_unittest.cc
@@ -43,10 +43,12 @@
   const fileapi::ExternalMountPoints* const mount_points =
       fileapi::ExternalMountPoints::GetSystemInstance();
   DCHECK(mount_points);
+  DCHECK(file_path.IsAbsolute());
+  base::FilePath relative_path(file_path.value().substr(1));
   return mount_points->CreateCrackedFileSystemURL(
       GURL(origin),
       fileapi::kFileSystemTypeExternal,
-      base::FilePath(mount_path.BaseName().Append(file_path)));
+      base::FilePath(mount_path.BaseName().Append(relative_path)));
 }
 
 // Creates a Service instance. Used to be able to destroy the service in
@@ -105,7 +107,8 @@
       kExtensionId, kFileSystemName);
   EXPECT_LT(0, file_system_id);
 
-  const base::FilePath kFilePath = base::FilePath("hello/world.txt");
+  const base::FilePath kFilePath =
+      base::FilePath::FromUTF8Unsafe("/hello/world.txt");
   const fileapi::FileSystemURL url =
       CreateFileSystemURL(profile_, kExtensionId, file_system_id, kFilePath);
   EXPECT_TRUE(url.is_valid());
@@ -124,7 +127,7 @@
       kExtensionId, kFileSystemName);
   EXPECT_LT(0, file_system_id);
 
-  const base::FilePath kFilePath = base::FilePath();
+  const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/");
   const fileapi::FileSystemURL url =
       CreateFileSystemURL(profile_, kExtensionId, file_system_id, kFilePath);
   EXPECT_TRUE(url.is_valid());
@@ -143,7 +146,7 @@
       kExtensionId, kFileSystemName);
   EXPECT_LT(0, file_system_id);
 
-  const base::FilePath kFilePath = base::FilePath("hello");
+  const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/hello");
   const fileapi::FileSystemURL url = CreateFileSystemURL(
       profile_, kExtensionId, file_system_id + 1, kFilePath);
   // It is impossible to create a cracked URL for a mount point which doesn't
diff --git a/chrome/browser/chromeos/file_system_provider/operations/get_metadata.cc b/chrome/browser/chromeos/file_system_provider/operations/get_metadata.cc
new file mode 100644
index 0000000..809351a
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/operations/get_metadata.cc
@@ -0,0 +1,85 @@
+// 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.
+
+#include "chrome/browser/chromeos/file_system_provider/operations/get_metadata.h"
+
+#include <string>
+
+#include "chrome/common/extensions/api/file_system_provider.h"
+#include "chrome/common/extensions/api/file_system_provider_internal.h"
+
+namespace chromeos {
+namespace file_system_provider {
+namespace operations {
+namespace {
+
+// Convert |value| into |output|. If parsing fails, then returns false.
+bool ConvertRequestValueToFileInfo(scoped_ptr<RequestValue> value,
+                                   base::File::Info* output) {
+  using extensions::api::file_system_provider::EntryMetadata;
+  using extensions::api::file_system_provider_internal::
+      GetMetadataRequestedSuccess::Params;
+
+  const Params* params = value->get_metadata_success_params();
+  if (!params)
+    return false;
+
+  output->is_directory = params->metadata.is_directory;
+  output->size = static_cast<int64>(params->metadata.size);
+  output->is_symbolic_link = false;  // Not supported.
+
+  std::string input_modification_time;
+  if (!params->metadata.modification_time.additional_properties.GetString(
+          "value", &input_modification_time)) {
+    return false;
+  }
+  if (!base::Time::FromString(input_modification_time.c_str(),
+                              &output->last_modified)) {
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace
+
+GetMetadata::GetMetadata(
+    extensions::EventRouter* event_router,
+    const ProvidedFileSystemInfo& file_system_info,
+    const base::FilePath& directory_path,
+    const fileapi::AsyncFileUtil::GetFileInfoCallback& callback)
+    : Operation(event_router, file_system_info),
+      directory_path_(directory_path),
+      callback_(callback) {
+}
+
+GetMetadata::~GetMetadata() {
+}
+
+bool GetMetadata::Execute(int request_id) {
+  scoped_ptr<base::ListValue> values(new base::ListValue);
+  values->AppendString(directory_path_.AsUTF8Unsafe());
+  return SendEvent(
+      request_id,
+      extensions::api::file_system_provider::OnGetMetadataRequested::kEventName,
+      values.Pass());
+}
+
+void GetMetadata::OnSuccess(int /* request_id */,
+                            scoped_ptr<RequestValue> result,
+                            bool has_next) {
+  base::File::Info file_info;
+  const bool convert_result =
+      ConvertRequestValueToFileInfo(result.Pass(), &file_info);
+  DCHECK(convert_result);
+  callback_.Run(base::File::FILE_OK, file_info);
+}
+
+void GetMetadata::OnError(int /* request_id */, base::File::Error error) {
+  callback_.Run(error, base::File::Info());
+}
+
+}  // namespace operations
+}  // namespace file_system_provider
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/file_system_provider/operations/get_metadata.h b/chrome/browser/chromeos/file_system_provider/operations/get_metadata.h
new file mode 100644
index 0000000..804bc3e
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/operations/get_metadata.h
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_OPERATIONS_GET_METADATA_H_
+#define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_OPERATIONS_GET_METADATA_H_
+
+#include "base/files/file.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/file_system_provider/operations/operation.h"
+#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
+#include "chrome/browser/chromeos/file_system_provider/request_value.h"
+#include "webkit/browser/fileapi/async_file_util.h"
+
+namespace base {
+class FilePath;
+}  // namespace base
+
+namespace extensions {
+class EventRouter;
+}  // namespace extensions
+
+namespace chromeos {
+namespace file_system_provider {
+namespace operations {
+
+// Bridge between fileapi read directory operation and providing extension's
+// read directory request. Created per request.
+class GetMetadata : public Operation {
+ public:
+  GetMetadata(extensions::EventRouter* event_router,
+              const ProvidedFileSystemInfo& file_system_info,
+              const base::FilePath& directory_path,
+              const fileapi::AsyncFileUtil::GetFileInfoCallback& callback);
+  virtual ~GetMetadata();
+
+  // Operation overrides.
+  virtual bool Execute(int request_id) OVERRIDE;
+  virtual void OnSuccess(int request_id,
+                         scoped_ptr<RequestValue> result,
+                         bool has_next) OVERRIDE;
+  virtual void OnError(int request_id, base::File::Error error) OVERRIDE;
+
+ private:
+  base::FilePath directory_path_;
+  const fileapi::AsyncFileUtil::GetFileInfoCallback callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(GetMetadata);
+};
+
+}  // namespace operations
+}  // namespace file_system_provider
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_OPERATIONS_GET_METADATA_H_
diff --git a/chrome/browser/chromeos/file_system_provider/operations/get_metadata_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/get_metadata_unittest.cc
new file mode 100644
index 0000000..4b091ac
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/operations/get_metadata_unittest.cc
@@ -0,0 +1,256 @@
+// 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.
+
+#include <string>
+
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/json/json_reader.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "chrome/browser/chromeos/file_system_provider/operations/get_metadata.h"
+#include "chrome/common/extensions/api/file_system_provider.h"
+#include "chrome/common/extensions/api/file_system_provider_internal.h"
+#include "extensions/browser/event_router.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/browser/fileapi/async_file_util.h"
+
+namespace chromeos {
+namespace file_system_provider {
+namespace operations {
+namespace {
+
+const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
+const int kFileSystemId = 1;
+const int kRequestId = 2;
+const base::FilePath::CharType kDirectoryPath[] = "/directory";
+
+// Fake event dispatcher implementation with extra logging capability. Acts as
+// a providing extension end-point.
+class LoggingDispatchEventImpl {
+ public:
+  explicit LoggingDispatchEventImpl(bool dispatch_reply)
+      : dispatch_reply_(dispatch_reply) {}
+  virtual ~LoggingDispatchEventImpl() {}
+
+  bool OnDispatchEventImpl(scoped_ptr<extensions::Event> event) {
+    events_.push_back(event->DeepCopy());
+    return dispatch_reply_;
+  }
+
+  ScopedVector<extensions::Event>& events() { return events_; }
+
+ private:
+  ScopedVector<extensions::Event> events_;
+  bool dispatch_reply_;
+
+  DISALLOW_COPY_AND_ASSIGN(LoggingDispatchEventImpl);
+};
+
+// Callback invocation logger. Acts as a fileapi end-point.
+class CallbackLogger {
+ public:
+  class Event {
+   public:
+    Event(base::File::Error result, const base::File::Info& file_info)
+        : result_(result), file_info_(file_info) {}
+    virtual ~Event() {}
+
+    base::File::Error result() { return result_; }
+    const base::File::Info& file_info() { return file_info_; }
+
+   private:
+    base::File::Error result_;
+    base::File::Info file_info_;
+
+    DISALLOW_COPY_AND_ASSIGN(Event);
+  };
+
+  CallbackLogger() : weak_ptr_factory_(this) {}
+  virtual ~CallbackLogger() {}
+
+  void OnGetMetadata(base::File::Error result,
+                     const base::File::Info& file_info) {
+    events_.push_back(new Event(result, file_info));
+  }
+
+  ScopedVector<Event>& events() { return events_; }
+
+  base::WeakPtr<CallbackLogger> GetWeakPtr() {
+    return weak_ptr_factory_.GetWeakPtr();
+  }
+
+ private:
+  ScopedVector<Event> events_;
+  bool dispatch_reply_;
+  base::WeakPtrFactory<CallbackLogger> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(CallbackLogger);
+};
+
+}  // namespace
+
+class FileSystemProviderOperationsGetMetadataTest : public testing::Test {
+ protected:
+  FileSystemProviderOperationsGetMetadataTest() {}
+  virtual ~FileSystemProviderOperationsGetMetadataTest() {}
+
+  virtual void SetUp() OVERRIDE {
+    file_system_info_ =
+        ProvidedFileSystemInfo(kExtensionId,
+                               kFileSystemId,
+                               "" /* file_system_name */,
+                               base::FilePath() /* mount_path */);
+  }
+
+  ProvidedFileSystemInfo file_system_info_;
+};
+
+TEST_F(FileSystemProviderOperationsGetMetadataTest, Execute) {
+  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
+  CallbackLogger callback_logger;
+
+  GetMetadata get_metadata(
+      NULL,
+      file_system_info_,
+      base::FilePath::FromUTF8Unsafe(kDirectoryPath),
+      base::Bind(&CallbackLogger::OnGetMetadata, callback_logger.GetWeakPtr()));
+  get_metadata.SetDispatchEventImplForTesting(
+      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
+                 base::Unretained(&dispatcher)));
+
+  EXPECT_TRUE(get_metadata.Execute(kRequestId));
+
+  ASSERT_EQ(1u, dispatcher.events().size());
+  extensions::Event* event = dispatcher.events()[0];
+  EXPECT_EQ(
+      extensions::api::file_system_provider::OnGetMetadataRequested::kEventName,
+      event->event_name);
+  base::ListValue* event_args = event->event_args.get();
+  ASSERT_EQ(3u, event_args->GetSize());
+
+  int event_file_system_id = -1;
+  EXPECT_TRUE(event_args->GetInteger(0, &event_file_system_id));
+  EXPECT_EQ(kFileSystemId, event_file_system_id);
+
+  int event_request_id = -1;
+  EXPECT_TRUE(event_args->GetInteger(1, &event_request_id));
+  EXPECT_EQ(kRequestId, event_request_id);
+
+  std::string event_directory_path;
+  EXPECT_TRUE(event_args->GetString(2, &event_directory_path));
+  EXPECT_EQ(kDirectoryPath, event_directory_path);
+}
+
+TEST_F(FileSystemProviderOperationsGetMetadataTest, Execute_NoListener) {
+  LoggingDispatchEventImpl dispatcher(false /* dispatch_reply */);
+  CallbackLogger callback_logger;
+
+  GetMetadata get_metadata(
+      NULL,
+      file_system_info_,
+      base::FilePath::FromUTF8Unsafe(kDirectoryPath),
+      base::Bind(&CallbackLogger::OnGetMetadata, callback_logger.GetWeakPtr()));
+  get_metadata.SetDispatchEventImplForTesting(
+      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
+                 base::Unretained(&dispatcher)));
+
+  EXPECT_FALSE(get_metadata.Execute(kRequestId));
+}
+
+TEST_F(FileSystemProviderOperationsGetMetadataTest, OnSuccess) {
+  using extensions::api::file_system_provider::EntryMetadata;
+  using extensions::api::file_system_provider_internal::
+      GetMetadataRequestedSuccess::Params;
+
+  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
+  CallbackLogger callback_logger;
+
+  GetMetadata get_metadata(
+      NULL,
+      file_system_info_,
+      base::FilePath::FromUTF8Unsafe(kDirectoryPath),
+      base::Bind(&CallbackLogger::OnGetMetadata, callback_logger.GetWeakPtr()));
+  get_metadata.SetDispatchEventImplForTesting(
+      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
+                 base::Unretained(&dispatcher)));
+
+  EXPECT_TRUE(get_metadata.Execute(kRequestId));
+
+  // Sample input as JSON. Keep in sync with file_system_provider_api.idl.
+  // As for now, it is impossible to create *::Params class directly, not from
+  // base::Value.
+  const std::string input =
+      "[\n"
+      "  1,\n"  // kFileSystemId
+      "  2,\n"  // kRequestId
+      "  {\n"
+      "    \"isDirectory\": false,\n"
+      "    \"name\": \"blueberries.txt\",\n"
+      "    \"size\": 4096,\n"
+      "    \"modificationTime\": {\n"
+      "      \"value\": \"Thu Apr 24 00:46:52 UTC 2014\"\n"
+      "    }\n"
+      "  }\n"
+      "]\n";
+
+  int json_error_code;
+  std::string json_error_msg;
+  scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
+      input, base::JSON_PARSE_RFC, &json_error_code, &json_error_msg));
+  ASSERT_TRUE(value.get()) << json_error_msg;
+
+  base::ListValue* value_as_list;
+  ASSERT_TRUE(value->GetAsList(&value_as_list));
+  scoped_ptr<Params> params(Params::Create(*value_as_list));
+  ASSERT_TRUE(params.get());
+  scoped_ptr<RequestValue> request_value(
+      RequestValue::CreateForGetMetadataSuccess(params.Pass()));
+  ASSERT_TRUE(request_value.get());
+
+  const bool has_next = false;
+  get_metadata.OnSuccess(kRequestId, request_value.Pass(), has_next);
+
+  ASSERT_EQ(1u, callback_logger.events().size());
+  CallbackLogger::Event* event = callback_logger.events()[0];
+  EXPECT_EQ(base::File::FILE_OK, event->result());
+
+  const base::File::Info& file_info = event->file_info();
+  EXPECT_FALSE(file_info.is_directory);
+  EXPECT_EQ(4096, file_info.size);
+  base::Time expected_time;
+  EXPECT_TRUE(
+      base::Time::FromString("Thu Apr 24 00:46:52 UTC 2014", &expected_time));
+  EXPECT_EQ(expected_time, file_info.last_modified);
+}
+
+TEST_F(FileSystemProviderOperationsGetMetadataTest, OnError) {
+  using extensions::api::file_system_provider::EntryMetadata;
+  using extensions::api::file_system_provider_internal::
+      GetMetadataRequestedError::Params;
+
+  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
+  CallbackLogger callback_logger;
+
+  GetMetadata get_metadata(
+      NULL,
+      file_system_info_,
+      base::FilePath::FromUTF8Unsafe(kDirectoryPath),
+      base::Bind(&CallbackLogger::OnGetMetadata, callback_logger.GetWeakPtr()));
+  get_metadata.SetDispatchEventImplForTesting(
+      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
+                 base::Unretained(&dispatcher)));
+
+  EXPECT_TRUE(get_metadata.Execute(kRequestId));
+
+  get_metadata.OnError(kRequestId, base::File::FILE_ERROR_TOO_MANY_OPENED);
+
+  ASSERT_EQ(1u, callback_logger.events().size());
+  CallbackLogger::Event* event = callback_logger.events()[0];
+  EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, event->result());
+}
+
+}  // namespace operations
+}  // namespace file_system_provider
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/file_system_provider/operations/read_directory.cc b/chrome/browser/chromeos/file_system_provider/operations/read_directory.cc
new file mode 100644
index 0000000..48437f5
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/operations/read_directory.cc
@@ -0,0 +1,94 @@
+// 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.
+
+#include "chrome/browser/chromeos/file_system_provider/operations/read_directory.h"
+
+#include <string>
+
+#include "base/memory/linked_ptr.h"
+#include "chrome/common/extensions/api/file_system_provider.h"
+#include "chrome/common/extensions/api/file_system_provider_internal.h"
+
+namespace chromeos {
+namespace file_system_provider {
+namespace operations {
+namespace {
+
+// Convert |input| into |output|. If parsing fails, then returns false.
+bool ConvertRequestValueToEntryList(scoped_ptr<RequestValue> value,
+                                    fileapi::AsyncFileUtil::EntryList* output) {
+  using extensions::api::file_system_provider::EntryMetadata;
+  using extensions::api::file_system_provider_internal::
+      ReadDirectoryRequestedSuccess::Params;
+
+  const Params* params = value->read_directory_success_params();
+  if (!params)
+    return false;
+
+  for (size_t i = 0; i < params->entries.size(); ++i) {
+    const linked_ptr<EntryMetadata> entry_metadata = params->entries[i];
+
+    fileapi::DirectoryEntry output_entry;
+    output_entry.is_directory = entry_metadata->is_directory;
+    output_entry.name = entry_metadata->name;
+    output_entry.size = static_cast<int64>(entry_metadata->size);
+
+    std::string input_modification_time;
+    if (!entry_metadata->modification_time.additional_properties.GetString(
+            "value", &input_modification_time)) {
+      return false;
+    }
+    if (!base::Time::FromString(input_modification_time.c_str(),
+                                &output_entry.last_modified_time)) {
+      return false;
+    }
+
+    output->push_back(output_entry);
+  }
+
+  return true;
+}
+
+}  // namespace
+
+ReadDirectory::ReadDirectory(
+    extensions::EventRouter* event_router,
+    const ProvidedFileSystemInfo& file_system_info,
+    const base::FilePath& directory_path,
+    const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback)
+    : Operation(event_router, file_system_info),
+      directory_path_(directory_path),
+      callback_(callback) {
+}
+
+ReadDirectory::~ReadDirectory() {
+}
+
+bool ReadDirectory::Execute(int request_id) {
+  scoped_ptr<base::ListValue> values(new base::ListValue);
+  values->AppendString(directory_path_.AsUTF8Unsafe());
+  return SendEvent(request_id,
+                   extensions::api::file_system_provider::
+                       OnReadDirectoryRequested::kEventName,
+                   values.Pass());
+}
+
+void ReadDirectory::OnSuccess(int /* request_id */,
+                              scoped_ptr<RequestValue> result,
+                              bool has_next) {
+  fileapi::AsyncFileUtil::EntryList entry_list;
+  const bool convert_result =
+      ConvertRequestValueToEntryList(result.Pass(), &entry_list);
+  DCHECK(convert_result);
+  callback_.Run(base::File::FILE_OK, entry_list, has_next);
+}
+
+void ReadDirectory::OnError(int /* request_id */, base::File::Error error) {
+  callback_.Run(
+      error, fileapi::AsyncFileUtil::EntryList(), false /* has_next */);
+}
+
+}  // namespace operations
+}  // namespace file_system_provider
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/file_system_provider/operations/read_directory.h b/chrome/browser/chromeos/file_system_provider/operations/read_directory.h
new file mode 100644
index 0000000..68176d9
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/operations/read_directory.h
@@ -0,0 +1,55 @@
+// 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_OPERATIONS_READ_DIRECTORY_H_
+#define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_OPERATIONS_READ_DIRECTORY_H_
+
+#include "base/files/file.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/file_system_provider/operations/operation.h"
+#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
+#include "chrome/browser/chromeos/file_system_provider/request_value.h"
+#include "webkit/browser/fileapi/async_file_util.h"
+
+namespace base {
+class FilePath;
+}  // namespace base
+
+namespace extensions {
+class EventRouter;
+}  // namespace extensions
+
+namespace chromeos {
+namespace file_system_provider {
+namespace operations {
+
+// Bridge between fileapi read directory operation and providing extension's
+// read directory request. Created per request.
+class ReadDirectory : public Operation {
+ public:
+  ReadDirectory(extensions::EventRouter* event_router,
+                const ProvidedFileSystemInfo& file_system_info,
+                const base::FilePath& directory_path,
+                const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback);
+  virtual ~ReadDirectory();
+
+  // Operation overrides.
+  virtual bool Execute(int request_id) OVERRIDE;
+  virtual void OnSuccess(int request_id,
+                         scoped_ptr<RequestValue> result,
+                         bool has_next) OVERRIDE;
+  virtual void OnError(int request_id, base::File::Error error) OVERRIDE;
+
+ private:
+  base::FilePath directory_path_;
+  const fileapi::AsyncFileUtil::ReadDirectoryCallback callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(ReadDirectory);
+};
+
+}  // namespace operations
+}  // namespace file_system_provider
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_OPERATIONS_READ_DIRECTORY_H_
diff --git a/chrome/browser/chromeos/file_system_provider/operations/read_directory_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/read_directory_unittest.cc
new file mode 100644
index 0000000..1158ddf
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/operations/read_directory_unittest.cc
@@ -0,0 +1,269 @@
+// 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.
+
+#include <string>
+
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/json/json_reader.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "chrome/browser/chromeos/file_system_provider/operations/read_directory.h"
+#include "chrome/common/extensions/api/file_system_provider.h"
+#include "chrome/common/extensions/api/file_system_provider_internal.h"
+#include "extensions/browser/event_router.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/browser/fileapi/async_file_util.h"
+
+namespace chromeos {
+namespace file_system_provider {
+namespace operations {
+namespace {
+
+const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
+const int kFileSystemId = 1;
+const int kRequestId = 2;
+const base::FilePath::CharType kDirectoryPath[] = "/directory";
+
+// Fake event dispatcher implementation with extra logging capability. Acts as
+// a providing extension end-point.
+class LoggingDispatchEventImpl {
+ public:
+  explicit LoggingDispatchEventImpl(bool dispatch_reply)
+      : dispatch_reply_(dispatch_reply) {}
+  virtual ~LoggingDispatchEventImpl() {}
+
+  bool OnDispatchEventImpl(scoped_ptr<extensions::Event> event) {
+    events_.push_back(event->DeepCopy());
+    return dispatch_reply_;
+  }
+
+  ScopedVector<extensions::Event>& events() { return events_; }
+
+ private:
+  ScopedVector<extensions::Event> events_;
+  bool dispatch_reply_;
+
+  DISALLOW_COPY_AND_ASSIGN(LoggingDispatchEventImpl);
+};
+
+// Callback invocation logger. Acts as a fileapi end-point.
+class CallbackLogger {
+ public:
+  class Event {
+   public:
+    Event(base::File::Error result,
+          const fileapi::AsyncFileUtil::EntryList& entry_list,
+          bool has_more)
+        : result_(result), entry_list_(entry_list), has_more_(has_more) {}
+    virtual ~Event() {}
+
+    base::File::Error result() { return result_; }
+    const fileapi::AsyncFileUtil::EntryList& entry_list() {
+      return entry_list_;
+    }
+    bool has_more() { return has_more_; }
+
+   private:
+    base::File::Error result_;
+    fileapi::AsyncFileUtil::EntryList entry_list_;
+    bool has_more_;
+
+    DISALLOW_COPY_AND_ASSIGN(Event);
+  };
+
+  CallbackLogger() : weak_ptr_factory_(this) {}
+  virtual ~CallbackLogger() {}
+
+  void OnReadDirectory(base::File::Error result,
+                       const fileapi::AsyncFileUtil::EntryList& entry_list,
+                       bool has_more) {
+    events_.push_back(new Event(result, entry_list, has_more));
+  }
+
+  ScopedVector<Event>& events() { return events_; }
+
+  base::WeakPtr<CallbackLogger> GetWeakPtr() {
+    return weak_ptr_factory_.GetWeakPtr();
+  }
+
+ private:
+  ScopedVector<Event> events_;
+  bool dispatch_reply_;
+  base::WeakPtrFactory<CallbackLogger> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(CallbackLogger);
+};
+
+}  // namespace
+
+class FileSystemProviderOperationsReadDirectoryTest : public testing::Test {
+ protected:
+  FileSystemProviderOperationsReadDirectoryTest() {}
+  virtual ~FileSystemProviderOperationsReadDirectoryTest() {}
+
+  virtual void SetUp() OVERRIDE {
+    file_system_info_ =
+        ProvidedFileSystemInfo(kExtensionId,
+                               kFileSystemId,
+                               "" /* file_system_name */,
+                               base::FilePath() /* mount_path */);
+  }
+
+  ProvidedFileSystemInfo file_system_info_;
+};
+
+TEST_F(FileSystemProviderOperationsReadDirectoryTest, Execute) {
+  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
+  CallbackLogger callback_logger;
+
+  ReadDirectory read_directory(NULL,
+                               file_system_info_,
+                               base::FilePath::FromUTF8Unsafe(kDirectoryPath),
+                               base::Bind(&CallbackLogger::OnReadDirectory,
+                                          callback_logger.GetWeakPtr()));
+  read_directory.SetDispatchEventImplForTesting(
+      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
+                 base::Unretained(&dispatcher)));
+
+  EXPECT_TRUE(read_directory.Execute(kRequestId));
+
+  ASSERT_EQ(1u, dispatcher.events().size());
+  extensions::Event* event = dispatcher.events()[0];
+  EXPECT_EQ(extensions::api::file_system_provider::OnReadDirectoryRequested::
+                kEventName,
+            event->event_name);
+  base::ListValue* event_args = event->event_args.get();
+  ASSERT_EQ(3u, event_args->GetSize());
+
+  int event_file_system_id = -1;
+  EXPECT_TRUE(event_args->GetInteger(0, &event_file_system_id));
+  EXPECT_EQ(kFileSystemId, event_file_system_id);
+
+  int event_request_id = -1;
+  EXPECT_TRUE(event_args->GetInteger(1, &event_request_id));
+  EXPECT_EQ(kRequestId, event_request_id);
+
+  std::string event_directory_path;
+  EXPECT_TRUE(event_args->GetString(2, &event_directory_path));
+  EXPECT_EQ(kDirectoryPath, event_directory_path);
+}
+
+TEST_F(FileSystemProviderOperationsReadDirectoryTest, Execute_NoListener) {
+  LoggingDispatchEventImpl dispatcher(false /* dispatch_reply */);
+  CallbackLogger callback_logger;
+
+  ReadDirectory read_directory(NULL,
+                               file_system_info_,
+                               base::FilePath::FromUTF8Unsafe(kDirectoryPath),
+                               base::Bind(&CallbackLogger::OnReadDirectory,
+                                          callback_logger.GetWeakPtr()));
+  read_directory.SetDispatchEventImplForTesting(
+      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
+                 base::Unretained(&dispatcher)));
+
+  EXPECT_FALSE(read_directory.Execute(kRequestId));
+}
+
+TEST_F(FileSystemProviderOperationsReadDirectoryTest, OnSuccess) {
+  using extensions::api::file_system_provider::EntryMetadata;
+  using extensions::api::file_system_provider_internal::
+      ReadDirectoryRequestedSuccess::Params;
+
+  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
+  CallbackLogger callback_logger;
+
+  ReadDirectory read_directory(NULL,
+                               file_system_info_,
+                               base::FilePath::FromUTF8Unsafe(kDirectoryPath),
+                               base::Bind(&CallbackLogger::OnReadDirectory,
+                                          callback_logger.GetWeakPtr()));
+  read_directory.SetDispatchEventImplForTesting(
+      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
+                 base::Unretained(&dispatcher)));
+
+  EXPECT_TRUE(read_directory.Execute(kRequestId));
+
+  // Sample input as JSON. Keep in sync with file_system_provider_api.idl.
+  // As for now, it is impossible to create *::Params class directly, not from
+  // base::Value.
+  const std::string input =
+      "[\n"
+      "  1,\n"  // kFileSystemId
+      "  2,\n"  // kRequestId
+      "  [\n"
+      "    {\n"
+      "      \"isDirectory\": false,\n"
+      "      \"name\": \"blueberries.txt\",\n"
+      "      \"size\": 4096,\n"
+      "      \"modificationTime\": {\n"
+      "        \"value\": \"Thu Apr 24 00:46:52 UTC 2014\"\n"
+      "      }\n"
+      "    }\n"
+      "  ],\n"
+      "  false\n"  // has_next
+      "]\n";
+
+  int json_error_code;
+  std::string json_error_msg;
+  scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
+      input, base::JSON_PARSE_RFC, &json_error_code, &json_error_msg));
+  ASSERT_TRUE(value.get()) << json_error_msg;
+
+  base::ListValue* value_as_list;
+  ASSERT_TRUE(value->GetAsList(&value_as_list));
+  scoped_ptr<Params> params(Params::Create(*value_as_list));
+  ASSERT_TRUE(params.get());
+  scoped_ptr<RequestValue> request_value(
+      RequestValue::CreateForReadDirectorySuccess(params.Pass()));
+  ASSERT_TRUE(request_value.get());
+
+  const bool has_next = false;
+  read_directory.OnSuccess(kRequestId, request_value.Pass(), has_next);
+
+  ASSERT_EQ(1u, callback_logger.events().size());
+  CallbackLogger::Event* event = callback_logger.events()[0];
+  EXPECT_EQ(base::File::FILE_OK, event->result());
+
+  ASSERT_EQ(1u, event->entry_list().size());
+  const fileapi::DirectoryEntry entry = event->entry_list()[0];
+  EXPECT_FALSE(entry.is_directory);
+  EXPECT_EQ("blueberries.txt", entry.name);
+  EXPECT_EQ(4096, entry.size);
+  base::Time expected_time;
+  EXPECT_TRUE(
+      base::Time::FromString("Thu Apr 24 00:46:52 UTC 2014", &expected_time));
+  EXPECT_EQ(expected_time, entry.last_modified_time);
+}
+
+TEST_F(FileSystemProviderOperationsReadDirectoryTest, OnError) {
+  using extensions::api::file_system_provider::EntryMetadata;
+  using extensions::api::file_system_provider_internal::
+      ReadDirectoryRequestedSuccess::Params;
+
+  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
+  CallbackLogger callback_logger;
+
+  ReadDirectory read_directory(NULL,
+                               file_system_info_,
+                               base::FilePath::FromUTF8Unsafe(kDirectoryPath),
+                               base::Bind(&CallbackLogger::OnReadDirectory,
+                                          callback_logger.GetWeakPtr()));
+  read_directory.SetDispatchEventImplForTesting(
+      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
+                 base::Unretained(&dispatcher)));
+
+  EXPECT_TRUE(read_directory.Execute(kRequestId));
+
+  read_directory.OnError(kRequestId, base::File::FILE_ERROR_TOO_MANY_OPENED);
+
+  ASSERT_EQ(1u, callback_logger.events().size());
+  CallbackLogger::Event* event = callback_logger.events()[0];
+  EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, event->result());
+  ASSERT_EQ(0u, event->entry_list().size());
+}
+
+}  // namespace operations
+}  // namespace file_system_provider
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system.cc b/chrome/browser/chromeos/file_system_provider/provided_file_system.cc
index 5b39f33..7b372f4 100644
--- a/chrome/browser/chromeos/file_system_provider/provided_file_system.cc
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system.cc
@@ -5,6 +5,8 @@
 #include "chrome/browser/chromeos/file_system_provider/provided_file_system.h"
 
 #include "base/files/file.h"
+#include "chrome/browser/chromeos/file_system_provider/operations/get_metadata.h"
+#include "chrome/browser/chromeos/file_system_provider/operations/read_directory.h"
 #include "chrome/browser/chromeos/file_system_provider/operations/unmount.h"
 #include "chrome/browser/chromeos/file_system_provider/request_manager.h"
 #include "chrome/common/extensions/api/file_system_provider.h"
@@ -34,6 +36,29 @@
   }
 }
 
+void ProvidedFileSystem::GetMetadata(
+    const base::FilePath& entry_path,
+    const fileapi::AsyncFileUtil::GetFileInfoCallback& callback) {
+  if (!request_manager_.CreateRequest(
+          make_scoped_ptr<RequestManager::HandlerInterface>(
+              new operations::GetMetadata(
+                  event_router_, file_system_info_, entry_path, callback)))) {
+    callback.Run(base::File::FILE_ERROR_SECURITY, base::File::Info());
+  }
+}
+
+void ProvidedFileSystem::ReadDirectory(
+    const base::FilePath& directory_path,
+    const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) {
+  if (!request_manager_.CreateRequest(make_scoped_ptr<
+          RequestManager::HandlerInterface>(new operations::ReadDirectory(
+          event_router_, file_system_info_, directory_path, callback)))) {
+    callback.Run(base::File::FILE_ERROR_SECURITY,
+                 fileapi::AsyncFileUtil::EntryList(),
+                 false /* has_more */);
+  }
+}
+
 const ProvidedFileSystemInfo& ProvidedFileSystem::GetFileSystemInfo() const {
   return file_system_info_;
 }
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system.h b/chrome/browser/chromeos/file_system_provider/provided_file_system.h
index 90bfcea..6fffe4b 100644
--- a/chrome/browser/chromeos/file_system_provider/provided_file_system.h
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system.h
@@ -32,6 +32,12 @@
   // ProvidedFileSystemInterface overrides.
   virtual void RequestUnmount(
       const fileapi::AsyncFileUtil::StatusCallback& callback) OVERRIDE;
+  virtual void GetMetadata(
+      const base::FilePath& entry_path,
+      const fileapi::AsyncFileUtil::GetFileInfoCallback& callback) OVERRIDE;
+  virtual void ReadDirectory(
+      const base::FilePath& directory_path,
+      const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) OVERRIDE;
   virtual const ProvidedFileSystemInfo& GetFileSystemInfo() const OVERRIDE;
   virtual RequestManager* GetRequestManager() OVERRIDE;
 
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h b/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h
index 2af2430..76be11d 100644
--- a/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h
@@ -31,6 +31,18 @@
   virtual void RequestUnmount(
       const fileapi::AsyncFileUtil::StatusCallback& callback) = 0;
 
+  // Requests metadata of the passed |entry_path|. It can be either a file
+  // or a directory.
+  virtual void GetMetadata(
+      const base::FilePath& entry_path,
+      const fileapi::AsyncFileUtil::GetFileInfoCallback& callback) = 0;
+  // Requests enumerating entries from the passed |directory_path|. The callback
+  // can be called multiple times until either an error is returned or the
+  // has_more field is set to false.
+  virtual void ReadDirectory(
+      const base::FilePath& directory_path,
+      const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) = 0;
+
   // Returns a provided file system info for this file system.
   virtual const ProvidedFileSystemInfo& GetFileSystemInfo() const = 0;
 
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc b/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc
index 7adf76c..ba72300 100644
--- a/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(mtomasz): Move these test cases to operations/unmount_unittest.cc.
+
 #include <string>
 #include <vector>
 
diff --git a/chrome/browser/chromeos/file_system_provider/request_value.cc b/chrome/browser/chromeos/file_system_provider/request_value.cc
index 105e6b0..ac85e66 100644
--- a/chrome/browser/chromeos/file_system_provider/request_value.cc
+++ b/chrome/browser/chromeos/file_system_provider/request_value.cc
@@ -21,6 +21,22 @@
   return result.Pass();
 }
 
+scoped_ptr<RequestValue> RequestValue::CreateForGetMetadataSuccess(
+    scoped_ptr<extensions::api::file_system_provider_internal::
+                   GetMetadataRequestedSuccess::Params> params) {
+  scoped_ptr<RequestValue> result(new RequestValue);
+  result->get_metadata_success_params_ = params.Pass();
+  return result.Pass();
+}
+
+scoped_ptr<RequestValue> RequestValue::CreateForReadDirectorySuccess(
+    scoped_ptr<extensions::api::file_system_provider_internal::
+                   ReadDirectoryRequestedSuccess::Params> params) {
+  scoped_ptr<RequestValue> result(new RequestValue);
+  result->read_directory_success_params_ = params.Pass();
+  return result.Pass();
+}
+
 scoped_ptr<RequestValue> RequestValue::CreateForTesting(
     const std::string& params) {
   scoped_ptr<RequestValue> result(new RequestValue);
diff --git a/chrome/browser/chromeos/file_system_provider/request_value.h b/chrome/browser/chromeos/file_system_provider/request_value.h
index 33872b0..2519473 100644
--- a/chrome/browser/chromeos/file_system_provider/request_value.h
+++ b/chrome/browser/chromeos/file_system_provider/request_value.h
@@ -28,9 +28,14 @@
       scoped_ptr<extensions::api::file_system_provider_internal::
                      UnmountRequestedSuccess::Params> params);
 
-  static scoped_ptr<RequestValue> CreateForTesting(const std::string& params);
+  static scoped_ptr<RequestValue> CreateForGetMetadataSuccess(
+      scoped_ptr<extensions::api::file_system_provider_internal::
+                     GetMetadataRequestedSuccess::Params> params);
+  static scoped_ptr<RequestValue> CreateForReadDirectorySuccess(
+      scoped_ptr<extensions::api::file_system_provider_internal::
+                     ReadDirectoryRequestedSuccess::Params> params);
 
-  const std::string* testing_params() const { return testing_params_.get(); }
+  static scoped_ptr<RequestValue> CreateForTesting(const std::string& params);
 
   const extensions::api::file_system_provider_internal::
       UnmountRequestedSuccess::Params*
@@ -38,9 +43,29 @@
     return unmount_success_params_.get();
   }
 
+  const extensions::api::file_system_provider_internal::
+      GetMetadataRequestedSuccess::Params*
+      get_metadata_success_params() const {
+    return get_metadata_success_params_.get();
+  }
+
+  const extensions::api::file_system_provider_internal::
+      ReadDirectoryRequestedSuccess::Params*
+      read_directory_success_params() const {
+    return read_directory_success_params_.get();
+  }
+
+  const std::string* testing_params() const { return testing_params_.get(); }
+
  private:
   scoped_ptr<extensions::api::file_system_provider_internal::
                  UnmountRequestedSuccess::Params> unmount_success_params_;
+  scoped_ptr<extensions::api::file_system_provider_internal::
+                 GetMetadataRequestedSuccess::Params>
+      get_metadata_success_params_;
+  scoped_ptr<extensions::api::file_system_provider_internal::
+                 ReadDirectoryRequestedSuccess::Params>
+      read_directory_success_params_;
   scoped_ptr<std::string> testing_params_;
 
   DISALLOW_COPY_AND_ASSIGN(RequestValue);
diff --git a/chrome/browser/chromeos/file_system_provider/service.cc b/chrome/browser/chromeos/file_system_provider/service.cc
index 35d5bcb..9694296 100644
--- a/chrome/browser/chromeos/file_system_provider/service.cc
+++ b/chrome/browser/chromeos/file_system_provider/service.cc
@@ -18,6 +18,8 @@
 #include "extensions/browser/extension_system.h"
 #include "webkit/browser/fileapi/external_mount_points.h"
 
+using content::BrowserThread;
+
 namespace chromeos {
 namespace file_system_provider {
 namespace {
@@ -85,7 +87,7 @@
 
 int Service::MountFileSystem(const std::string& extension_id,
                              const std::string& file_system_name) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // Restrict number of file systems to prevent system abusing.
   if (file_system_map_.size() + 1 > kMaxFileSystems) {
@@ -151,7 +153,7 @@
 
 bool Service::UnmountFileSystem(const std::string& extension_id,
                                 int file_system_id) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   const ProvidedFileSystemMap::iterator file_system_it =
       file_system_map_.find(file_system_id);
@@ -199,7 +201,7 @@
 }
 
 bool Service::RequestUnmount(int file_system_id) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   ProvidedFileSystemMap::iterator file_system_it =
       file_system_map_.find(file_system_id);
@@ -214,7 +216,7 @@
 }
 
 std::vector<ProvidedFileSystemInfo> Service::GetProvidedFileSystemInfoList() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   std::vector<ProvidedFileSystemInfo> result;
   for (ProvidedFileSystemMap::const_iterator it = file_system_map_.begin();
@@ -228,7 +230,7 @@
 ProvidedFileSystemInterface* Service::GetProvidedFileSystem(
     const std::string& extension_id,
     int file_system_id) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   const ProvidedFileSystemMap::const_iterator file_system_it =
       file_system_map_.find(file_system_id);
@@ -263,7 +265,7 @@
 
 ProvidedFileSystemInterface* Service::GetProvidedFileSystem(
     const std::string& mount_point_name) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   const MountPointNameToIdMap::const_iterator mapping_it =
       mount_point_name_to_id_map_.find(mount_point_name);
diff --git a/chrome/browser/chromeos/fileapi/file_system_backend.cc b/chrome/browser/chromeos/fileapi/file_system_backend.cc
index 5b793c4..a040fc7 100644
--- a/chrome/browser/chromeos/fileapi/file_system_backend.cc
+++ b/chrome/browser/chromeos/fileapi/file_system_backend.cc
@@ -81,6 +81,7 @@
     case fileapi::kFileSystemTypeNativeLocal:
     case fileapi::kFileSystemTypeNativeForPlatformApp:
     case fileapi::kFileSystemTypeDeviceMediaAsFileStorage:
+    case fileapi::kFileSystemTypeProvided:
       return true;
     default:
       return false;
@@ -267,7 +268,8 @@
 
   DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal ||
          url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal ||
-         url.type() == fileapi::kFileSystemTypeDrive);
+         url.type() == fileapi::kFileSystemTypeDrive ||
+         url.type() == fileapi::kFileSystemTypeProvided);
   return fileapi::FileSystemOperation::Create(
       url, context,
       make_scoped_ptr(new fileapi::FileSystemOperationContext(context)));
diff --git a/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc b/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc
index 8afa4b9..6ce6bae 100644
--- a/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc
+++ b/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc
@@ -6,10 +6,13 @@
 
 #include "base/file_util.h"
 #include "base/logging.h"
+#include "base/path_service.h"
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/extensions/extension_file_util.h"
 #include "content/public/browser/browser_thread.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/common/extension.h"
@@ -84,6 +87,11 @@
     "/usr/share/chromeos-assets/input_methods/nacl_mozc",
   },
 #endif
+  {
+    // Braille hardware keyboard IME that works together with ChromeVox.
+    extension_misc::kBrailleImeExtensionId,
+    extension_misc::kBrailleImeExtensionPath,
+  },
 };
 
 extensions::ComponentLoader* GetComponentLoader() {
@@ -284,6 +292,12 @@
     component_ime.path = base::FilePath(
         whitelisted_component_extension[i].path);
 
+    if (!component_ime.path.IsAbsolute()) {
+      base::FilePath resources_path;
+      if (!PathService::Get(chrome::DIR_RESOURCES, &resources_path))
+        NOTREACHED();
+      component_ime.path = resources_path.Append(component_ime.path);
+    }
     const base::FilePath manifest_path =
         component_ime.path.Append("manifest.json");
 
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc
index aaa9539..215e9bd 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine.cc
@@ -19,8 +19,10 @@
 #include "ash/shell.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chromeos/ime/component_extension_ime_manager.h"
 #include "chromeos/ime/composition_text.h"
@@ -55,6 +57,19 @@
         composition_text, cursor_pos, is_visible);
 }
 
+// Returns the length of characters of a UTF-8 string with unknown string
+// length. Cannot apply faster algorithm to count characters in an utf-8
+// string without knowing the string length,  so just does a full scan.
+size_t GetUtf8StringLength(const char* s) {
+  size_t ret = 0;
+  while (*s) {
+    if ((*s & 0xC0) != 0x80)
+      ret++;
+    ++s;
+  }
+  return ret;
+}
+
 }  // namespace
 
 InputMethodEngine::InputMethodEngine()
@@ -69,6 +84,8 @@
       sent_key_event_(NULL) {}
 
 InputMethodEngine::~InputMethodEngine() {
+  if (start_time_.ToInternalValue())
+    RecordHistogram("WorkingTime", (end_time_ - start_time_).InSeconds());
   input_method::InputMethodManager::Get()->RemoveInputMethodExtension(imm_id_);
 }
 
@@ -122,6 +139,15 @@
   return descriptor_;
 }
 
+void InputMethodEngine::RecordHistogram(const char* name, int count) {
+  std::string histo_name =
+      base::StringPrintf("InputMethod.%s.%s", name, engine_id_.c_str());
+  base::HistogramBase* counter = base::Histogram::FactoryGet(
+      histo_name, 0, 1000000, 50, base::HistogramBase::kNoFlags);
+  if (counter)
+    counter->Add(count);
+}
+
 void InputMethodEngine::NotifyImeReady() {
   input_method::InputMethodManager* manager =
       input_method::InputMethodManager::Get();
@@ -209,6 +235,14 @@
   }
 
   IMEBridge::Get()->GetInputContextHandler()->CommitText(text);
+
+  // Records times for using input method.
+  if (!start_time_.ToInternalValue())
+    start_time_ = base::Time::Now();
+  end_time_ = base::Time::Now();
+  // Records histograms for counts of commits and committed characters.
+  RecordHistogram("Commit", 1);
+  RecordHistogram("CommitCharacter", GetUtf8StringLength(text));
   return true;
 }
 
@@ -525,11 +559,18 @@
   FocusIn(IMEEngineHandlerInterface::InputContext(
       current_input_type_, ui::TEXT_INPUT_MODE_DEFAULT));
   EnableInputView(true);
+
+  start_time_ = base::Time();
+  end_time_ = base::Time();
+  RecordHistogram("Enable", 1);
 }
 
 void InputMethodEngine::Disable() {
   active_ = false;
   observer_->OnDeactivated(engine_id_);
+
+  if (start_time_.ToInternalValue())
+    RecordHistogram("WorkingTime", (end_time_ - start_time_).InSeconds());
 }
 
 void InputMethodEngine::PropertyActivate(const std::string& property_name) {
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.h b/chrome/browser/chromeos/input_method/input_method_engine.h
index 328653d..716d136 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.h
+++ b/chrome/browser/chromeos/input_method/input_method_engine.h
@@ -8,6 +8,7 @@
 #include <map>
 #include <string>
 #include <vector>
+#include "base/time/time.h"
 #include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
 #include "chromeos/ime/input_method_descriptor.h"
 #include "url/gurl.h"
@@ -99,6 +100,8 @@
   virtual void HideInputView() OVERRIDE;
 
  private:
+  void RecordHistogram(const char* name, int count);
+
   // Converts MenuItem to InputMethodMenuItem.
   void MenuItemToProperty(const MenuItem& item,
                           ash::ime::InputMethodMenuItem* property);
@@ -157,6 +160,10 @@
   // Used with SendKeyEvents and ProcessKeyEvent to check if the key event
   // sent to ProcessKeyEvent is sent by SendKeyEvents.
   const ui::KeyEvent* sent_key_event_;
+
+  // The start & end time of using this input method. This is for UMA.
+  base::Time start_time_;
+  base::Time end_time_;
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
index 7a8434b..50e3be4 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -3,6 +3,9 @@
 // found in the LICENSE file.
 
 #include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_samples.h"
+#include "base/metrics/statistics_recorder.h"
 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
 #include "chrome/browser/chromeos/input_method/input_method_engine.h"
 #include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
@@ -10,6 +13,7 @@
 #include "chromeos/ime/extension_ime_util.h"
 #include "chromeos/ime/mock_component_extension_ime_manager_delegate.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
 
 namespace chromeos {
 
@@ -20,6 +24,19 @@
 const char kTestExtensionId2[] = "dmpipdbjkoajgdeppkffbjhngfckdloi";
 const char kTestImeEngineId[] = "test_engine_id";
 
+const char* kHistogramNames[] = {
+    "InputMethod.Enable.test_engine_id", "InputMethod.Commit.test_engine_id",
+    "InputMethod.CommitCharacter.test_engine_id",
+};
+
+scoped_ptr<base::HistogramSamples> GetHistogramSamples(
+    const char* histogram_name) {
+  base::HistogramBase* histogram =
+      base::StatisticsRecorder::FindHistogram(histogram_name);
+  EXPECT_NE(static_cast<base::HistogramBase*>(NULL), histogram);
+  return histogram->SnapshotSamples().Pass();
+}
+
 enum CallsBitmap {
   NONE = 0U,
   ACTIVATE = 1U,
@@ -112,13 +129,48 @@
     layouts_.push_back("us");
     InitInputMethod();
     IMEBridge::Initialize();
+    mock_ime_input_context_handler_.reset(new MockIMEInputContextHandler());
+    IMEBridge::Get()->SetInputContextHandler(
+        mock_ime_input_context_handler_.get());
+
+    base::StatisticsRecorder::Initialize();
+
+    for (size_t i = 0; i < arraysize(kHistogramNames); i++) {
+      base::Histogram::FactoryGet(
+          kHistogramNames[i], 0, 1000000, 50, base::HistogramBase::kNoFlags)
+          ->Add(0);
+      initial_histogram_samples_[i] =
+          GetHistogramSamples(kHistogramNames[i]).Pass();
+      initial_histogram_samples_map_[kHistogramNames[i]] =
+          initial_histogram_samples_[i].get();
+    }
   }
   virtual ~InputMethodEngineTest() {
+    IMEBridge::Get()->SetInputContextHandler(NULL);
     engine_.reset();
     Shutdown();
   }
 
  protected:
+  scoped_ptr<base::HistogramSamples> GetHistogramSamplesDelta(
+      const char* histogram_name) {
+    scoped_ptr<base::HistogramSamples> delta_samples(
+        GetHistogramSamples(histogram_name));
+    delta_samples->Subtract(*initial_histogram_samples_map_[histogram_name]);
+
+    return delta_samples.Pass();
+  }
+
+  void ExpectNewSample(const char* histogram_name,
+                       base::HistogramBase::Sample sample,
+                       int total_count,
+                       int sample_count) {
+    scoped_ptr<base::HistogramSamples> delta_samples(
+        GetHistogramSamplesDelta(histogram_name));
+    EXPECT_EQ(total_count, delta_samples->TotalCount());
+    EXPECT_EQ(sample_count, delta_samples->GetCount(sample));
+  }
+
   void CreateEngine(bool whitelisted) {
     engine_.reset(new InputMethodEngine());
     observer_ = new TestObserver();
@@ -141,12 +193,19 @@
   }
 
   scoped_ptr<InputMethodEngine> engine_;
+
   TestObserver* observer_;
   std::vector<std::string> languages_;
   std::vector<std::string> layouts_;
   GURL options_page_;
   GURL input_view_;
 
+  scoped_ptr<base::HistogramSamples>
+      initial_histogram_samples_[arraysize(kHistogramNames)];
+  std::map<std::string, base::HistogramSamples*> initial_histogram_samples_map_;
+
+  scoped_ptr<MockIMEInputContextHandler> mock_ime_input_context_handler_;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(InputMethodEngineTest);
 };
@@ -223,5 +282,20 @@
   EXPECT_EQ(DEACTIVATED, observer_->GetCallsBitmapAndReset());
 }
 
+TEST_F(InputMethodEngineTest, TestHistograms) {
+  CreateEngine(true);
+  FocusIn(ui::TEXT_INPUT_TYPE_TEXT);
+  engine_->Enable();
+  std::string error;
+  ExpectNewSample("InputMethod.Enable.test_engine_id", 1, 1, 1);
+  engine_->CommitText(1, "input", &error);
+  engine_->CommitText(1, "入力", &error);
+  engine_->CommitText(1, "input入力", &error);
+  ExpectNewSample("InputMethod.Commit.test_engine_id", 1, 3, 3);
+  ExpectNewSample("InputMethod.CommitCharacter.test_engine_id", 5, 3, 1);
+  ExpectNewSample("InputMethod.CommitCharacter.test_engine_id", 2, 3, 1);
+  ExpectNewSample("InputMethod.CommitCharacter.test_engine_id", 7, 3, 1);
+}
+
 }  // namespace input_method
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/input_method/input_method_util.cc b/chrome/browser/chromeos/input_method/input_method_util.cc
index 21b9d64..d4355db 100644
--- a/chrome/browser/chromeos/input_method/input_method_util.cc
+++ b/chrome/browser/chromeos/input_method/input_method_util.cc
@@ -15,6 +15,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/common/extensions/extension_constants.h"
 #include "chromeos/ime/component_extension_ime_manager.h"
 #include "chromeos/ime/extension_ime_util.h"
 // For SetHardwareKeyboardLayoutForTesting.
@@ -70,6 +71,10 @@
   { "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_3setnoshift",
     "\xed\x95\x9c" },
   { "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_romaja", "\xed\x95\x9c" },
+  { extension_misc::kBrailleImeEngineId,
+    // U+2803 U+2817 U+2807 (Unicode braille patterns for the letters 'brl' in
+    // English (and many other) braille codes.
+    "\xe2\xa0\x83\xe2\xa0\x97\xe2\xa0\x87" },
 };
 
 const size_t kMappingFromIdToIndicatorTextLen =
@@ -104,6 +109,8 @@
     IDS_LANGUAGES_MEDIUM_LEN_NAME_CHINESE_TRADITIONAL },
   { "_comp_ime_gjaehgfemfahhmlgpdfknkhdnemmolopzh-hant-t-i0-cangjie-1987",
     IDS_LANGUAGES_MEDIUM_LEN_NAME_CHINESE_TRADITIONAL },
+  { extension_misc::kBrailleImeEngineId,
+    IDS_LANGUAGES_MEDIUM_LEN_NAME_BRAILLE },
 };
 const size_t kMappingImeIdToMediumLenNameResourceIdLen =
     ARRAYSIZE_UNSAFE(kMappingImeIdToMediumLenNameResourceId);
diff --git a/chrome/browser/chromeos/login/app_launch_controller.cc b/chrome/browser/chromeos/login/app_launch_controller.cc
index ad021b3..a277a58 100644
--- a/chrome/browser/chromeos/login/app_launch_controller.cc
+++ b/chrome/browser/chromeos/login/app_launch_controller.cc
@@ -86,8 +86,6 @@
       NotifyAppWindowCreated();
     }
   }
-  virtual void OnAppWindowIconChanged(apps::AppWindow* app_window) OVERRIDE {}
-  virtual void OnAppWindowRemoved(apps::AppWindow* app_window) OVERRIDE {}
 
   void NotifyAppWindowCreated() {
     controller_->OnAppWindowCreated();
diff --git a/chrome/browser/chromeos/login/captive_portal_window_browsertest.cc b/chrome/browser/chromeos/login/captive_portal_window_browsertest.cc
index cccf9ae..23b2d1f 100644
--- a/chrome/browser/chromeos/login/captive_portal_window_browsertest.cc
+++ b/chrome/browser/chromeos/login/captive_portal_window_browsertest.cc
@@ -199,6 +199,10 @@
     return network_portal_detector_;
   }
 
+  PortalDetectorStrategy::StrategyId strategy_id() {
+    return network_portal_detector_->strategy_id();
+  }
+
  private:
   NetworkPortalDetectorTestImpl* network_portal_detector_;
 
@@ -210,16 +214,22 @@
 }
 
 IN_PROC_BROWSER_TEST_F(CaptivePortalWindowCtorDtorTest, OpenPortalDialog) {
-  network_portal_detector()->NotifyObserversForTesting();
-  OobeScreenWaiter(OobeDisplay::SCREEN_ERROR_MESSAGE).Wait();
   LoginDisplayHostImpl* host =
       static_cast<LoginDisplayHostImpl*>(LoginDisplayHostImpl::default_host());
-
   ASSERT_TRUE(host);
   OobeUI* oobe = host->GetOobeUI();
   ASSERT_TRUE(oobe);
   ErrorScreenActor* actor = oobe->GetErrorScreenActor();
   ASSERT_TRUE(actor);
+
+  // Error screen asks portal detector to change detection strategy.
+  ErrorScreen error_screen(NULL, actor);
+
+  ASSERT_EQ(PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN, strategy_id());
+  network_portal_detector()->NotifyObserversForTesting();
+  OobeScreenWaiter(OobeDisplay::SCREEN_ERROR_MESSAGE).Wait();
+  ASSERT_EQ(PortalDetectorStrategy::STRATEGY_ID_ERROR_SCREEN, strategy_id());
+
   actor->ShowCaptivePortal();
 }
 
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index fef8a52..56520c4 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -73,6 +73,7 @@
     ::switches::kDisableAcceleratedOverflowScroll,
     ::switches::kDisableAcceleratedVideoDecode,
     ::switches::kDisableDelegatedRenderer,
+    ::switches::kDisableDistanceFieldText,
     ::switches::kDisableFastTextAutosizing,
     ::switches::kDisableFiltersOverIPC,
     ::switches::kDisableGpuShaderDiskCache,
@@ -103,8 +104,9 @@
     ::switches::kEnableGestureTapHighlight,
     ::switches::kDisableGestureTapHighlight,
     ::switches::kDisableGpuSandbox,
-    ::switches::kEnableDeferredFilters,
+    ::switches::kDisableDeferredFilters,
     ::switches::kEnableContainerCulling,
+    ::switches::kEnableDistanceFieldText,
     ::switches::kEnableGpuRasterization,
     ::switches::kEnableImplSidePainting,
     ::switches::kEnableLogging,
@@ -203,6 +205,7 @@
     chromeos::switches::kDbusStub,
     chromeos::switches::kDisableLoginAnimations,
     chromeos::switches::kEnableConsumerManagement,
+    chromeos::switches::kEnterpriseEnableForcedReEnrollment,
     chromeos::switches::kHasChromeOSDiamondKey,
     chromeos::switches::kHasChromeOSKeyboard,
     chromeos::switches::kLoginProfile,
diff --git a/chrome/browser/chromeos/login/crash_restore_browsertest.cc b/chrome/browser/chromeos/login/crash_restore_browsertest.cc
index e7470c9..8bcaaf5 100644
--- a/chrome/browser/chromeos/login/crash_restore_browsertest.cc
+++ b/chrome/browser/chromeos/login/crash_restore_browsertest.cc
@@ -33,7 +33,7 @@
 
 class CrashRestoreSimpleTest : public InProcessBrowserTest {
  protected:
-  CrashRestoreSimpleTest() : session_started_count_(0) {}
+  CrashRestoreSimpleTest() {}
 
   virtual ~CrashRestoreSimpleTest() {}
 
@@ -53,27 +53,10 @@
     dbus_thread_manager->SetSessionManagerClient(
         scoped_ptr<SessionManagerClient>(session_manager_client_));
     DBusThreadManager::SetInstanceForTesting(dbus_thread_manager);
-    // We need to create MessageLoop here to process callback from
-    // session_manager
-    base::MessageLoop msg_loop;
-    session_manager_client_->StartSession(
-        kUserId1,
-        base::Bind(&CrashRestoreSimpleTest::OnSessionStarted,
-                   base::Unretained(this),
-                   kUserId1));
-    base::RunLoop().RunUntilIdle();
-    ASSERT_EQ(1, session_started_count_);
+    session_manager_client_->StartSession(kUserId1);
   }
 
- public:
-  void OnSessionStarted(const std::string& user_email, bool success) {
-    ASSERT_TRUE(success);
-    ++session_started_count_;
-  }
-
- protected:
   FakeSessionManagerClient* session_manager_client_;
-  int session_started_count_;
 };
 
 IN_PROC_BROWSER_TEST_F(CrashRestoreSimpleTest, RestoreSessionForOneUser) {
@@ -135,21 +118,8 @@
 
   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
     CrashRestoreSimpleTest::SetUpInProcessBrowserTestFixture();
-    // We need to create MessageLoop here to process callback from
-    // session_manager
-    base::MessageLoop msg_loop;
-    session_manager_client_->StartSession(
-        kUserId2,
-        base::Bind(&CrashRestoreSimpleTest::OnSessionStarted,
-                   base::Unretained(this),
-                   kUserId2));
-    session_manager_client_->StartSession(
-        kUserId3,
-        base::Bind(&CrashRestoreSimpleTest::OnSessionStarted,
-                   base::Unretained(this),
-                   kUserId3));
-    base::RunLoop().RunUntilIdle();
-    ASSERT_EQ(3, CrashRestoreSimpleTest::session_started_count_);
+    session_manager_client_->StartSession(kUserId2);
+    session_manager_client_->StartSession(kUserId3);
   }
 };
 
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
index ff6cc9c..c348cd6 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
@@ -10,9 +10,10 @@
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
+#include "chrome/browser/chromeos/policy/server_backed_state_keys_broker.h"
 #include "chromeos/chromeos_switches.h"
-#include "components/policy/core/browser/browser_policy_connector.h"
 #include "components/policy/core/common/cloud/device_management_service.h"
 #include "net/url_request/url_request_context_getter.h"
 
@@ -81,7 +82,7 @@
 
 AutoEnrollmentController::AutoEnrollmentController()
     : state_(policy::AUTO_ENROLLMENT_STATE_IDLE),
-      weak_factory_(this) {}
+      client_start_weak_factory_(this) {}
 
 AutoEnrollmentController::~AutoEnrollmentController() {}
 
@@ -107,16 +108,15 @@
     return;
   }
 
-  // If there already is a client, bail out.
-  if (client_)
+  // If a client is being created or already existing, bail out.
+  if (client_start_weak_factory_.HasWeakPtrs() || client_)
     return;
 
   // Start by checking if the device has already been owned.
   UpdateState(policy::AUTO_ENROLLMENT_STATE_PENDING);
-  weak_factory_.InvalidateWeakPtrs();
   DeviceSettingsService::Get()->GetOwnershipStatusAsync(
       base::Bind(&AutoEnrollmentController::OnOwnershipStatusCheckDone,
-                 weak_factory_.GetWeakPtr()));
+                 client_start_weak_factory_.GetWeakPtr()));
 }
 
 void AutoEnrollmentController::Cancel() {
@@ -125,6 +125,9 @@
     // its protocol finished before login was complete.
     client_.release()->CancelAndDeleteSoon();
   }
+
+  // Make sure to nuke pending |client_| start sequences.
+  client_start_weak_factory_.InvalidateWeakPtrs();
 }
 
 void AutoEnrollmentController::Retry() {
@@ -152,8 +155,18 @@
     return;
   }
 
-  policy::BrowserPolicyConnector* connector =
-      g_browser_process->browser_policy_connector();
+  // Make sure state keys are available.
+  g_browser_process->platform_part()
+      ->browser_policy_connector_chromeos()
+      ->GetStateKeysBroker()
+      ->RequestStateKeys(base::Bind(&AutoEnrollmentController::StartClient,
+                                    client_start_weak_factory_.GetWeakPtr()));
+}
+
+void AutoEnrollmentController::StartClient(
+    const std::vector<std::string>& state_keys) {
+  policy::BrowserPolicyConnectorChromeOS* connector =
+      g_browser_process->platform_part()->browser_policy_connector_chromeos();
   policy::DeviceManagementService* service =
       connector->device_management_service();
   service->ScheduleInitialization(0);
@@ -172,8 +185,7 @@
   std::string device_id;
   if (GetMode() == MODE_FORCED_RE_ENROLLMENT) {
     retrieve_device_state = true;
-    device_id =
-        policy::DeviceCloudPolicyManagerChromeOS::GetCurrentDeviceStateKey();
+    device_id = state_keys.empty() ? std::string() : state_keys.front();
   } else {
     device_id = policy::DeviceCloudPolicyManagerChromeOS::GetMachineID();
   }
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h
index 8a9361f..67f31d5 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h
@@ -5,6 +5,9 @@
 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_ENROLLMENT_AUTO_ENROLLMENT_CONTROLLER_H_
 #define CHROME_BROWSER_CHROMEOS_LOGIN_ENROLLMENT_AUTO_ENROLLMENT_CONTROLLER_H_
 
+#include <string>
+#include <vector>
+
 #include "base/callback_list.h"
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
@@ -12,6 +15,10 @@
 #include "chrome/browser/chromeos/policy/auto_enrollment_client.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 
+namespace policy {
+class ServerBackedStateKeysBroker;
+}
+
 namespace chromeos {
 
 // Drives the auto-enrollment check, running an AutoEnrollmentClient if
@@ -67,13 +74,16 @@
   void OnOwnershipStatusCheckDone(
       DeviceSettingsService::OwnershipStatus status);
 
+  // Starts the auto-enrollment client.
+  void StartClient(const std::vector<std::string>& state_keys);
+
   // Sets |state_| and notifies |progress_callbacks_|.
   void UpdateState(policy::AutoEnrollmentState state);
 
   policy::AutoEnrollmentState state_;
   ProgressCallbackList progress_callbacks_;
 
-  base::WeakPtrFactory<AutoEnrollmentController> weak_factory_;
+  base::WeakPtrFactory<AutoEnrollmentController> client_start_weak_factory_;
 
   scoped_ptr<policy::AutoEnrollmentClient> client_;
 
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc b/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc
index a4f3f9e..e9712b0 100644
--- a/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc
+++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc
@@ -269,6 +269,7 @@
     case policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER:
       UMAFailure(policy::kMetricEnrollmentWrongUserError);
       return;
+    case policy::EnrollmentStatus::STATUS_NO_STATE_KEYS:
     case policy::EnrollmentStatus::STATUS_VALIDATION_FAILED:
     case policy::EnrollmentStatus::STATUS_STORE_ERROR:
     case policy::EnrollmentStatus::STATUS_LOCK_ERROR:
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index 0474696..e6da1ca 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -1096,6 +1096,15 @@
       break;
   }
 
+  if (error_id == IDS_LOGIN_ERROR_AUTHENTICATING) {
+    if (num_login_attempts_ > 1) {
+      const User* user =
+          UserManager::Get()->FindUser(last_login_attempt_username_);
+      if (user && (user->GetType() == User::USER_TYPE_LOCALLY_MANAGED))
+        error_id = IDS_LOGIN_ERROR_AUTHENTICATING_2ND_TIME_SUPERVISED;
+    }
+  }
+
   login_display_->ShowError(error_id, num_login_attempts_, help_topic_id);
 }
 
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc
index 7289203..328e643 100644
--- a/chrome/browser/chromeos/login/kiosk_browsertest.cc
+++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -32,6 +32,7 @@
 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_test_message_listener.h"
+#include "chrome/browser/profiles/profile_impl.h"
 #include "chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths.h"
@@ -366,6 +367,10 @@
     Profile* app_profile = ProfileManager::GetPrimaryUserProfile();
     ASSERT_TRUE(app_profile);
 
+    // Check ChromeOS preference is initialized.
+    EXPECT_TRUE(
+        static_cast<ProfileImpl*>(app_profile)->chromeos_preferences_);
+
     // Check installer status.
     EXPECT_EQ(chromeos::KioskAppLaunchError::NONE,
               chromeos::KioskAppLaunchError::Get());
@@ -849,15 +854,6 @@
 }
 
 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableAfter2ndSigninScreen) {
-  // Fake an auto enrollment is not going to be enforced.
-  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
-      switches::kEnterpriseEnrollmentInitialModulus, "1");
-  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
-      switches::kEnterpriseEnrollmentModulusLimit, "2");
-  g_browser_process->local_state()->SetBoolean(prefs::kShouldAutoEnroll, false);
-  g_browser_process->local_state()->SetInteger(
-      prefs::kAutoEnrollmentPowerLimit, -1);
-
   chromeos::WizardController::SkipPostLoginScreensForTesting();
   chromeos::WizardController* wizard_controller =
       chromeos::WizardController::default_controller();
@@ -1123,9 +1119,13 @@
         device_policy_test_helper_.device_policy()->policy_data();
     policy_data.set_service_account_identity(kTestEnterpriseServiceAccountId);
     device_policy_test_helper_.device_policy()->Build();
+
+    base::RunLoop run_loop;
     DBusThreadManager::Get()->GetSessionManagerClient()->StoreDevicePolicy(
         device_policy_test_helper_.device_policy()->GetBlob(),
-        base::Bind(&KioskEnterpriseTest::StorePolicyCallback));
+        base::Bind(&KioskEnterpriseTest::StorePolicyCallback,
+                   run_loop.QuitClosure()));
+    run_loop.Run();
 
     DeviceSettingsService::Get()->Load();
 
@@ -1164,8 +1164,9 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  static void StorePolicyCallback(bool result) {
+  static void StorePolicyCallback(const base::Closure& callback, bool result) {
     ASSERT_TRUE(result);
+    callback.Run();
   }
 
   policy::DevicePolicyCrosTestHelper device_policy_test_helper_;
diff --git a/chrome/browser/chromeos/login/login_display_host_impl.cc b/chrome/browser/chromeos/login/login_display_host_impl.cc
index 4692b4e..772188d 100644
--- a/chrome/browser/chromeos/login/login_display_host_impl.cc
+++ b/chrome/browser/chromeos/login/login_display_host_impl.cc
@@ -71,7 +71,6 @@
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "grit/browser_resources.h"
 #include "media/audio/sounds/sounds_manager.h"
@@ -960,7 +959,7 @@
   }
   LOG(WARNING) << "Login WebUI >> Show already initialized UI";
   login_window_->Show();
-  login_view_->GetWebContents()->GetView()->Focus();
+  login_view_->GetWebContents()->Focus();
   login_view_->SetStatusAreaVisible(status_area_saved_visibility_);
   login_view_->OnPostponedShow();
 
diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc
index 7801be1..792b107 100644
--- a/chrome/browser/chromeos/login/login_utils.cc
+++ b/chrome/browser/chromeos/login/login_utils.cc
@@ -200,19 +200,6 @@
   // the authentication profile.
   void CompleteProfileCreate(Profile* user_profile);
 
-  // Callback to resume profile preparing after start session.
-  void OnSessionStarted(const UserContext& user_context,
-                        const std::string& display_email,
-                        bool has_cookies,
-                        LoginUtils::Delegate* delegate,
-                        bool success);
-
-  // Complete profile preparation with having active session.
-  void CompletePrepareProfileWithActiveSession(const UserContext& user_context,
-                                               const std::string& display_email,
-                                               bool has_cookies,
-                                               LoginUtils::Delegate* delegate);
-
   // Finalized profile preparation.
   void FinalizePrepareProfile(Profile* user_profile);
 
@@ -413,42 +400,10 @@
   if (!has_active_session) {
     btl->AddLoginTimeMarker("StartSession-Start", false);
     DBusThreadManager::Get()->GetSessionManagerClient()->StartSession(
-        user_context.username,
-        base::Bind(&LoginUtilsImpl::OnSessionStarted,
-                   AsWeakPtr(),
-                   user_context,
-                   display_email,
-                   has_cookies,
-                   delegate));
-    return;
+        user_context.username);
+    btl->AddLoginTimeMarker("StartSession-End", false);
   }
-  CompletePrepareProfileWithActiveSession(
-      user_context, display_email, has_cookies, delegate);
-}
 
-void LoginUtilsImpl::OnSessionStarted(const UserContext& user_context,
-                                      const std::string& display_email,
-                                      bool has_cookies,
-                                      LoginUtils::Delegate* delegate,
-                                      bool success) {
-  BootTimesLoader* btl = BootTimesLoader::Get();
-  btl->AddLoginTimeMarker("StartSession-End", false);
-
-  if (!success) {
-    LOG(ERROR) << "StartSession failed";
-    chrome::AttemptUserExit();
-    return;
-  }
-  CompletePrepareProfileWithActiveSession(
-      user_context, display_email, has_cookies, delegate);
-}
-
-void LoginUtilsImpl::CompletePrepareProfileWithActiveSession(
-    const UserContext& user_context,
-    const std::string& display_email,
-    bool has_cookies,
-    LoginUtils::Delegate* delegate) {
-  BootTimesLoader* btl = BootTimesLoader::Get();
   btl->AddLoginTimeMarker("UserLoggedIn-Start", false);
   UserManager* user_manager = UserManager::Get();
   user_manager->UserLoggedIn(user_context.username,
diff --git a/chrome/browser/chromeos/login/managed/managed_user_creation_browsertest.cc b/chrome/browser/chromeos/login/managed/managed_user_creation_browsertest.cc
index 9dc3bb0..9a40054 100644
--- a/chrome/browser/chromeos/login/managed/managed_user_creation_browsertest.cc
+++ b/chrome/browser/chromeos/login/managed/managed_user_creation_browsertest.cc
@@ -37,9 +37,9 @@
 #include "sync/protocol/sync.pb.h"
 
 using testing::_;
-using chromeos::testing::ManagedUserTestBase;
-using chromeos::testing::kTestSupervisedUserDisplayName;
-using chromeos::testing::kTestManager;
+using chromeos::ManagedUserTestBase;
+using chromeos::kTestSupervisedUserDisplayName;
+using chromeos::kTestManager;
 
 namespace chromeos {
 
@@ -150,7 +150,7 @@
 
   JSEval("$('managed-user-creation-next-button').click()");
 
-  ::testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
+  testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
 
   EXPECT_TRUE(registration_utility_stub_->register_was_called());
   EXPECT_EQ(registration_utility_stub_->display_name(),
@@ -169,7 +169,7 @@
     SupervisedUserTransactionCleanupTest,
     CreateAndCancelSupervisedUser,
     SupervisedUserTransactionCleanupTest2,
-    ::testing::internal::GetTypeId<SupervisedUserTransactionCleanupTest>()) {
+    testing::internal::GetTypeId<SupervisedUserTransactionCleanupTest>()) {
   // Make sure there is no supervised user in list.
   ASSERT_EQ(2UL, UserManager::Get()->GetUsers().size());
 }
diff --git a/chrome/browser/chromeos/login/managed/managed_user_password_browsertest.cc b/chrome/browser/chromeos/login/managed/managed_user_password_browsertest.cc
index f037ae8..a6a3937 100644
--- a/chrome/browser/chromeos/login/managed/managed_user_password_browsertest.cc
+++ b/chrome/browser/chromeos/login/managed/managed_user_password_browsertest.cc
@@ -37,9 +37,9 @@
 #include "sync/protocol/sync.pb.h"
 
 using testing::_;
-using chromeos::testing::ManagedUserTestBase;
-using chromeos::testing::kTestSupervisedUserDisplayName;
-using chromeos::testing::kTestManager;
+using chromeos::ManagedUserTestBase;
+using chromeos::kTestSupervisedUserDisplayName;
+using chromeos::kTestManager;
 
 namespace chromeos {
 
@@ -102,7 +102,7 @@
   EXPECT_CALL(*mock_homedir_methods_, MountEx(_, _, _, _)).Times(1);
   EXPECT_CALL(*mock_homedir_methods_, UpdateKeyEx(_, _, _, _, _)).Times(1);
   SigninAsSupervisedUser(false, 0, kTestSupervisedUserDisplayName);
-  ::testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
+  testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
 }
 
 IN_PROC_BROWSER_TEST_F(SupervisedUserPasswordTest,
@@ -156,7 +156,7 @@
       sync_id, managed_users::kChromeOSPasswordData, password, true, false);
   content::RunAllPendingInMessageLoop();
 
-  ::testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
+  testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
 }
 
 // After that supervised user signs in, and no password change happens.
@@ -165,7 +165,7 @@
   EXPECT_CALL(*mock_homedir_methods_, MountEx(_, _, _, _)).Times(1);
   EXPECT_CALL(*mock_homedir_methods_, UpdateKeyEx(_, _, _, _, _)).Times(0);
   SigninAsSupervisedUser(false, 1, kTestSupervisedUserDisplayName);
-  ::testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
+  testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
 }
 
 IN_PROC_BROWSER_TEST_F(SupervisedUserPasswordTest,
@@ -243,7 +243,7 @@
       sync_id, managed_users::kChromeOSPasswordData, password, true, false);
   content::RunAllPendingInMessageLoop();
 
-  ::testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
+  testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
 }
 
 // When supervised user signs in, password is already migrated, so no migration
@@ -253,7 +253,7 @@
   EXPECT_CALL(*mock_homedir_methods_, MountEx(_, _, _, _)).Times(1);
   EXPECT_CALL(*mock_homedir_methods_, UpdateKeyEx(_, _, _, _, _)).Times(0);
   SigninAsSupervisedUser(false, 1, kTestSupervisedUserDisplayName);
-  ::testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
+  testing::Mock::VerifyAndClearExpectations(mock_homedir_methods_);
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/managed/managed_user_test_base.cc b/chrome/browser/chromeos/login/managed/managed_user_test_base.cc
index 05cdc7a..f036623 100644
--- a/chrome/browser/chromeos/login/managed/managed_user_test_base.cc
+++ b/chrome/browser/chromeos/login/managed/managed_user_test_base.cc
@@ -28,6 +28,7 @@
 #include "chrome/browser/managed_mode/managed_user_shared_settings_service_factory.h"
 #include "chrome/browser/managed_mode/managed_user_sync_service.h"
 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
+#include "chrome/browser/profiles/profile_impl.h"
 #include "chromeos/cryptohome/mock_async_method_caller.h"
 #include "chromeos/cryptohome/mock_homedir_methods.h"
 #include "content/public/browser/notification_service.h"
@@ -44,8 +45,6 @@
 
 namespace chromeos {
 
-namespace testing {
-
 namespace {
 
 const char kCurrentPage[] = "$('managed-user-creation').currentPage_";
@@ -366,6 +365,10 @@
   Profile* profile = UserManager::Get()->GetProfileByUser(user);
   shared_settings_adapter_.reset(
       new ManagedUsersSharedSettingsSyncTestAdapter(profile));
+
+  // Check ChromeOS preference is initialized.
+  EXPECT_TRUE(
+      static_cast<ProfileImpl*>(profile)->chromeos_preferences_);
 }
 
 void ManagedUserTestBase::SigninAsManager(int user_index) {
@@ -423,6 +426,4 @@
   ASSERT_EQ(original_user_count - 1, UserManager::Get()->GetUsers().size());
 }
 
-}  // namespace testing
-
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/managed/managed_user_test_base.h b/chrome/browser/chromeos/login/managed/managed_user_test_base.h
index e25cd5d..de4242f 100644
--- a/chrome/browser/chromeos/login/managed/managed_user_test_base.h
+++ b/chrome/browser/chromeos/login/managed/managed_user_test_base.h
@@ -20,8 +20,6 @@
 
 namespace chromeos {
 
-namespace testing {
-
 const char kStubEthernetServicePath[] = "eth0";
 
 const char kTestManager[] = "test-manager@gmail.com";
@@ -114,8 +112,6 @@
   DISALLOW_COPY_AND_ASSIGN(ManagedUserTestBase);
 };
 
-}  // namespace testing
-
 }  // namespace chromeos
 
 #endif  // CHROME_BROWSER_CHROMEOS_LOGIN_MANAGED_MANAGED_USER_TEST_BASE_H_
diff --git a/chrome/browser/chromeos/login/oobe_display.h b/chrome/browser/chromeos/login/oobe_display.h
index 4084f29..1ea116a 100644
--- a/chrome/browser/chromeos/login/oobe_display.h
+++ b/chrome/browser/chromeos/login/oobe_display.h
@@ -35,12 +35,12 @@
 class OobeDisplay {
  public:
   enum Screen {
-    SCREEN_OOBE_NETWORK = 0,
+    SCREEN_OOBE_HID_DETECTION = 0,
+    SCREEN_OOBE_NETWORK,
     SCREEN_OOBE_EULA,
     SCREEN_OOBE_UPDATE,
     SCREEN_OOBE_ENROLLMENT,
     SCREEN_OOBE_RESET,
-    SCREEN_OOBE_HID_DETECTION,
     SCREEN_GAIA_SIGNIN,
     SCREEN_ACCOUNT_PICKER,
     SCREEN_KIOSK_AUTOLAUNCH,
diff --git a/chrome/browser/chromeos/login/reset_browsertest.cc b/chrome/browser/chromeos/login/reset_browsertest.cc
index 045671c..759e8c7 100644
--- a/chrome/browser/chromeos/login/reset_browsertest.cc
+++ b/chrome/browser/chromeos/login/reset_browsertest.cc
@@ -206,22 +206,51 @@
   EXPECT_EQ(0, update_engine_client_->rollback_call_count());
 }
 
-IN_PROC_BROWSER_TEST_F(ResetFirstAfterBootTest, PRE_RollbackRequested) {
+IN_PROC_BROWSER_TEST_F(ResetFirstAfterBootTest, PRE_ErrorOnRollbackRequested) {
   PrefService* prefs = g_browser_process->local_state();
   prefs->SetBoolean(prefs::kRollbackRequested, true);
   prefs->SetBoolean(prefs::kFactoryResetRequested, true);
   RegisterSomeUser();
 }
 
-IN_PROC_BROWSER_TEST_F(ResetFirstAfterBootTest, RollbackRequested) {
+IN_PROC_BROWSER_TEST_F(ResetFirstAfterBootTest, ErrorOnRollbackRequested) {
   OobeScreenWaiter(OobeDisplay::SCREEN_OOBE_RESET).Wait();
   EXPECT_EQ(0, power_manager_client_->num_request_restart_calls());
   EXPECT_EQ(0, session_manager_client_->start_device_wipe_call_count());
   EXPECT_EQ(0, update_engine_client_->rollback_call_count());
+  JSExpect("!$('reset').classList.contains('revert-promise')");
   ClickResetButton();
   EXPECT_EQ(0, power_manager_client_->num_request_restart_calls());
   EXPECT_EQ(0, session_manager_client_->start_device_wipe_call_count());
   EXPECT_EQ(1, update_engine_client_->rollback_call_count());
+  JSExpect("$('reset').classList.contains('revert-promise')");
+  UpdateEngineClient::Status error_update_status;
+  error_update_status.status = UpdateEngineClient::UPDATE_STATUS_ERROR;
+  update_engine_client_->NotifyObserversThatStatusChanged(error_update_status);
+  OobeScreenWaiter(OobeDisplay::SCREEN_ERROR_MESSAGE).Wait();
 }
 
+IN_PROC_BROWSER_TEST_F(ResetFirstAfterBootTest,
+                       PRE_SuccessOnRollbackRequested) {
+  PrefService* prefs = g_browser_process->local_state();
+  prefs->SetBoolean(prefs::kRollbackRequested, true);
+  prefs->SetBoolean(prefs::kFactoryResetRequested, true);
+  RegisterSomeUser();
+}
+
+IN_PROC_BROWSER_TEST_F(ResetFirstAfterBootTest, SuccessOnRollbackRequested) {
+  OobeScreenWaiter(OobeDisplay::SCREEN_OOBE_RESET).Wait();
+  ClickResetButton();
+  EXPECT_EQ(0, power_manager_client_->num_request_restart_calls());
+  EXPECT_EQ(0, session_manager_client_->start_device_wipe_call_count());
+  EXPECT_EQ(1, update_engine_client_->rollback_call_count());
+  UpdateEngineClient::Status ready_for_reboot_status;
+  ready_for_reboot_status.status =
+      UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT;
+  update_engine_client_->NotifyObserversThatStatusChanged(
+      ready_for_reboot_status);
+  EXPECT_EQ(1, power_manager_client_->num_request_restart_calls());
+}
+
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
index 9657f70..2004263 100644
--- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -9,6 +9,7 @@
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/chrome_notification_types.h"
@@ -417,9 +418,26 @@
   JsExpect("!$('gaia-signin').classList.contains('saml')");
 }
 
-// Tests the sign-in flow when the credentials passing API is used.
-IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPI) {
-  fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html");
+// Tests the sign-in flow when version 1 of the credentials passing API is used.
+IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPIV1) {
+  fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login_v1.html");
+  fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
+  StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
+
+  // Fill-in the SAML IdP form and submit.
+  SetSignFormField("Email", "fake_user");
+  SetSignFormField("Password", "fake_password");
+  ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
+
+  // Login should finish login and a session should start.
+  content::WindowedNotificationObserver(
+      chrome::NOTIFICATION_SESSION_STARTED,
+      content::NotificationService::AllSources()).Wait();
+}
+
+// Tests the sign-in flow when version 2 of the credentials passing API is used.
+IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPIV2) {
+  fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login_v2.html");
   fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
   StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
 
@@ -566,6 +584,9 @@
   GetLoginDisplay()->ShowSigninScreenForCreds(kHTTPSAMLUserEmail, "");
 
   OobeScreenWaiter(OobeDisplay::SCREEN_FATAL_ERROR).Wait();
+  JsExpect(base::StringPrintf(
+      "$('fatal-error-message').textContent.indexOf('%s') != -1",
+      embedded_test_server()->base_url().Resolve("/SAML").spec().c_str()));
 }
 
 // Verifies that when GAIA attempts to redirect to a page served over http, not
diff --git a/chrome/browser/chromeos/login/screen_locker.cc b/chrome/browser/chromeos/login/screen_locker.cc
index 8b397a6..0e7d0e3 100644
--- a/chrome/browser/chromeos/login/screen_locker.cc
+++ b/chrome/browser/chromeos/login/screen_locker.cc
@@ -25,7 +25,6 @@
 #include "base/strings/string_util.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/extensions/screenlock_private_api.h"
 #include "chrome/browser/chromeos/login/authenticator.h"
 #include "chrome/browser/chromeos/login/extended_authenticator.h"
 #include "chrome/browser/chromeos/login/login_performer.h"
@@ -35,6 +34,7 @@
 #include "chrome/browser/chromeos/login/user_adding_screen.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
 #include "chrome/browser/chromeos/login/webui_screen_locker.h"
+#include "chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -123,6 +123,39 @@
 
 ScreenLockObserver* g_screen_lock_observer = NULL;
 
+// TODO(xiyuan): Get rid of LoginDisplay::AuthType and the mappers below.
+ScreenlockBridge::LockHandler::AuthType ToLockHandlerAuthType(
+    LoginDisplay::AuthType auth_type) {
+  switch (auth_type) {
+    case LoginDisplay::OFFLINE_PASSWORD:
+      return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
+    case LoginDisplay::ONLINE_SIGN_IN:
+      return ScreenlockBridge::LockHandler::ONLINE_SIGN_IN;
+    case LoginDisplay::NUMERIC_PIN:
+      return ScreenlockBridge::LockHandler::NUMERIC_PIN;
+    case LoginDisplay::USER_CLICK:
+      return ScreenlockBridge::LockHandler::USER_CLICK;
+  }
+  NOTREACHED();
+  return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
+}
+
+LoginDisplay::AuthType FromLockHandlerAuthType(
+    ScreenlockBridge::LockHandler::AuthType auth_type) {
+  switch (auth_type) {
+    case ScreenlockBridge::LockHandler::OFFLINE_PASSWORD:
+      return LoginDisplay::OFFLINE_PASSWORD;
+    case ScreenlockBridge::LockHandler::ONLINE_SIGN_IN:
+      return LoginDisplay::ONLINE_SIGN_IN;
+    case ScreenlockBridge::LockHandler::NUMERIC_PIN:
+      return LoginDisplay::NUMERIC_PIN;
+    case ScreenlockBridge::LockHandler::USER_CLICK:
+      return LoginDisplay::USER_CLICK;
+  }
+  NOTREACHED();
+  return LoginDisplay::OFFLINE_PASSWORD;
+}
+
 }  // namespace
 
 // static
@@ -258,7 +291,8 @@
 
   // Send authentication request to chrome.screenlockPrivate API event router
   // if the authentication type is not the system password.
-  LoginDisplay::AuthType auth_type = GetAuthType(user_context.username);
+  LoginDisplay::AuthType auth_type =
+      FromLockHandlerAuthType(GetAuthType(user_context.username));
   if (auth_type != LoginDisplay::OFFLINE_PASSWORD) {
     const User* unlock_user = FindUnlockUser(user_context.username);
     LOG_ASSERT(unlock_user);
@@ -267,7 +301,8 @@
     extensions::ScreenlockPrivateEventRouter* router =
         extensions::ScreenlockPrivateEventRouter::GetFactoryInstance()->Get(
             profile);
-    router->OnAuthAttempted(auth_type, user_context.password);
+    router->OnAuthAttempted(ToLockHandlerAuthType(auth_type),
+                            user_context.password);
     return;
   }
 
@@ -316,10 +351,6 @@
   delegate_->ClearErrors();
 }
 
-void ScreenLocker::EnableInput() {
-  delegate_->SetInputEnabled(true);
-}
-
 void ScreenLocker::Signout() {
   delegate_->ClearErrors();
   content::RecordAction(UserMetricsAction("ScreenLocker_Signout"));
@@ -359,20 +390,30 @@
   delegate_->HideUserPodButton(username);
 }
 
-void ScreenLocker::SetAuthType(const std::string& username,
-                               LoginDisplay::AuthType auth_type,
-                               const std::string& initial_value) {
-  if (!locked_)
-    return;
-  delegate_->SetAuthType(username, auth_type, initial_value);
+void ScreenLocker::EnableInput() {
+  delegate_->SetInputEnabled(true);
 }
 
-LoginDisplay::AuthType ScreenLocker::GetAuthType(const std::string& username)
-    const {
+void ScreenLocker::SetAuthType(
+    const std::string& username,
+    ScreenlockBridge::LockHandler::AuthType auth_type,
+    const std::string& initial_value) {
+  if (!locked_)
+    return;
+  delegate_->SetAuthType(
+      username, FromLockHandlerAuthType(auth_type), initial_value);
+}
+
+ScreenlockBridge::LockHandler::AuthType ScreenLocker::GetAuthType(
+    const std::string& username) const {
   // Return default authentication type when not locked.
   if (!locked_)
-    return LoginDisplay::OFFLINE_PASSWORD;
-  return delegate_->GetAuthType(username);
+    return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
+  return ToLockHandlerAuthType(delegate_->GetAuthType(username));
+}
+
+void ScreenLocker::Unlock(const std::string& user_email) {
+  chromeos::ScreenLocker::Hide();
 }
 
 void ScreenLocker::ShowErrorMessage(int error_msg_id,
@@ -515,10 +556,12 @@
       chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
       content::Source<ScreenLocker>(this),
       content::Details<bool>(&state));
-  VLOG(1) << "Calling session manager's HandleLockScreenDismissed D-Bus method";
 
+  VLOG(1) << "Calling session manager's HandleLockScreenDismissed D-Bus method";
   DBusThreadManager::Get()->GetSessionManagerClient()->
       NotifyLockScreenDismissed();
+
+  ScreenlockBridge::Get()->SetLockHandler(NULL);
 }
 
 void ScreenLocker::SetAuthenticator(Authenticator* authenticator) {
@@ -544,6 +587,8 @@
       content::Details<bool>(&state));
   VLOG(1) << "Calling session manager's HandleLockScreenShown D-Bus method";
   DBusThreadManager::Get()->GetSessionManagerClient()->NotifyLockScreenShown();
+
+  ScreenlockBridge::Get()->SetLockHandler(this);
 }
 
 content::WebUI* ScreenLocker::GetAssociatedWebUI() {
diff --git a/chrome/browser/chromeos/login/screen_locker.h b/chrome/browser/chromeos/login/screen_locker.h
index 1e0265c..5d26f5c 100644
--- a/chrome/browser/chromeos/login/screen_locker.h
+++ b/chrome/browser/chromeos/login/screen_locker.h
@@ -18,6 +18,7 @@
 #include "chrome/browser/chromeos/login/login_status_consumer.h"
 #include "chrome/browser/chromeos/login/screen_locker_delegate.h"
 #include "chrome/browser/chromeos/login/user.h"
+#include "chrome/browser/signin/screenlock_bridge.h"
 #include "ui/base/accelerators/accelerator.h"
 
 namespace content {
@@ -44,7 +45,8 @@
 // ScreenLocker creates a ScreenLockerDelegate which will display the lock UI.
 // As well, it takes care of authenticating the user and managing a global
 // instance of itself which will be deleted when the system is unlocked.
-class ScreenLocker : public LoginStatusConsumer {
+class ScreenLocker : public LoginStatusConsumer,
+                     public ScreenlockBridge::LockHandler {
  public:
   explicit ScreenLocker(const UserList& users);
 
@@ -58,7 +60,7 @@
   // Initialize and show the screen locker.
   void Init();
 
-  // LoginStatusConsumer implements:
+  // LoginStatusConsumer:
   virtual void OnLoginFailure(const chromeos::LoginFailure& error) OVERRIDE;
   virtual void OnLoginSuccess(const UserContext& user_context) OVERRIDE;
 
@@ -72,30 +74,22 @@
   // Close message bubble to clear error messages.
   void ClearErrors();
 
-  // (Re)enable input field.
-  void EnableInput();
-
   // Exit the chrome, which will sign out the current session.
   void Signout();
 
-  // Displays |message| in a banner on the lock screen.
-  void ShowBannerMessage(const std::string& message);
-
-  // Shows a button inside the user pod on the lock screen with an icon.
-  void ShowUserPodButton(const std::string& username,
-                         const gfx::Image& icon,
-                         const base::Closure& click_callback);
-
-  // Hides the user pod button for a user.
-  void HideUserPodButton(const std::string& username);
-
-  // Set the authentication type to be used on the lock screen.
-  void SetAuthType(const std::string& username,
-                   LoginDisplay::AuthType auth_type,
-                   const std::string& initial_value);
-
-  // Returns the authentication type used for |username|.
-  LoginDisplay::AuthType GetAuthType(const std::string& username) const;
+  // ScreenlockBridge::LockHandler:
+  virtual void ShowBannerMessage(const std::string& message) OVERRIDE;
+  virtual void ShowUserPodButton(const std::string& username,
+                                 const gfx::Image& icon,
+                                 const base::Closure& click_callback) OVERRIDE;
+  virtual void HideUserPodButton(const std::string& username) OVERRIDE;
+  virtual void EnableInput() OVERRIDE;
+  virtual void SetAuthType(const std::string& username,
+                           ScreenlockBridge::LockHandler::AuthType auth_type,
+                           const std::string& initial_value) OVERRIDE;
+  virtual ScreenlockBridge::LockHandler::AuthType GetAuthType(
+      const std::string& username) const OVERRIDE;
+  virtual void Unlock(const std::string& user_email) OVERRIDE;
 
   // Disables all UI needed and shows error bubble with |message|.
   // If |sign_out_only| is true then all other input except "Sign Out"
diff --git a/chrome/browser/chromeos/login/screens/error_screen.cc b/chrome/browser/chromeos/login/screens/error_screen.cc
index a7a7bab..2aedaca 100644
--- a/chrome/browser/chromeos/login/screens/error_screen.cc
+++ b/chrome/browser/chromeos/login/screens/error_screen.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/net/network_portal_detector.h"
+#include "chrome/browser/chromeos/net/network_portal_detector_strategy.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 
 namespace chromeos {
@@ -22,22 +23,10 @@
       weak_factory_(this) {
   DCHECK(actor_);
   actor_->SetDelegate(this);
-  AddObserver(NetworkPortalDetector::Get());
 }
 
 ErrorScreen::~ErrorScreen() {
   actor_->SetDelegate(NULL);
-  RemoveObserver(NetworkPortalDetector::Get());
-}
-
-void ErrorScreen::AddObserver(Observer* observer) {
-  if (observer)
-    observers_.AddObserver(observer);
-}
-
-void ErrorScreen::RemoveObserver(Observer* observer) {
-  if (observer)
-    observers_.RemoveObserver(observer);
 }
 
 void ErrorScreen::PrepareToShow() {
@@ -58,11 +47,13 @@
 }
 
 void ErrorScreen::OnErrorShow() {
-  FOR_EACH_OBSERVER(Observer, observers_, OnErrorScreenShow());
+  NetworkPortalDetector::Get()->SetStrategy(
+      PortalDetectorStrategy::STRATEGY_ID_ERROR_SCREEN);
 }
 
 void ErrorScreen::OnErrorHide() {
-  FOR_EACH_OBSERVER(Observer, observers_, OnErrorScreenHide());
+  NetworkPortalDetector::Get()->SetStrategy(
+      PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN);
 }
 
 void ErrorScreen::OnLaunchOobeGuestSession() {
diff --git a/chrome/browser/chromeos/login/screens/error_screen.h b/chrome/browser/chromeos/login/screens/error_screen.h
index bd20d81..5a06b09 100644
--- a/chrome/browser/chromeos/login/screens/error_screen.h
+++ b/chrome/browser/chromeos/login/screens/error_screen.h
@@ -9,7 +9,6 @@
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "base/observer_list.h"
 #include "chrome/browser/chromeos/login/login_performer.h"
 #include "chrome/browser/chromeos/login/oobe_display.h"
 #include "chrome/browser/chromeos/login/screens/error_screen_actor_delegate.h"
@@ -25,13 +24,6 @@
                     public ErrorScreenActorDelegate,
                     public LoginPerformer::Delegate {
  public:
-  class Observer {
-   public:
-    virtual ~Observer() {}
-    virtual void OnErrorScreenShow() = 0;
-    virtual void OnErrorScreenHide() = 0;
-  };
-
   enum UIState {
     UI_STATE_UNKNOWN = 0,
     UI_STATE_UPDATE,
@@ -40,6 +32,7 @@
     UI_STATE_KIOSK_MODE,
     UI_STATE_LOCAL_STATE_ERROR,
     UI_STATE_AUTO_ENROLLMENT_ERROR,
+    UI_STATE_ROLLBACK_ERROR,
   };
 
   enum ErrorState {
@@ -54,9 +47,6 @@
   ErrorScreen(ScreenObserver* screen_observer, ErrorScreenActor* actor);
   virtual ~ErrorScreen();
 
-  void AddObserver(Observer* observer);
-  void RemoveObserver(Observer* observer);
-
   // WizardScreen implementation.
   virtual void PrepareToShow() OVERRIDE;
   virtual void Show() OVERRIDE;
@@ -117,12 +107,10 @@
 
   OobeDisplay::Screen parent_screen_;
 
-  base::WeakPtrFactory<ErrorScreen> weak_factory_;
-
-  ObserverList<Observer> observers_;
-
   scoped_ptr<LoginPerformer> guest_login_performer_;
 
+  base::WeakPtrFactory<ErrorScreen> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(ErrorScreen);
 };
 
diff --git a/chrome/browser/chromeos/login/screens/hid_detection_screen.cc b/chrome/browser/chromeos/login/screens/hid_detection_screen.cc
index 24ec97f..b9d7280 100644
--- a/chrome/browser/chromeos/login/screens/hid_detection_screen.cc
+++ b/chrome/browser/chromeos/login/screens/hid_detection_screen.cc
@@ -23,8 +23,6 @@
 }
 
 void HIDDetectionScreen::PrepareToShow() {
-  if (actor_)
-    actor_->PrepareToShow();
 }
 
 void HIDDetectionScreen::Show() {
diff --git a/chrome/browser/chromeos/login/screens/hid_detection_screen_actor.h b/chrome/browser/chromeos/login/screens/hid_detection_screen_actor.h
index 53411a7..575dfc4 100644
--- a/chrome/browser/chromeos/login/screens/hid_detection_screen_actor.h
+++ b/chrome/browser/chromeos/login/screens/hid_detection_screen_actor.h
@@ -28,7 +28,6 @@
 
   virtual ~HIDDetectionScreenActor() {}
 
-  virtual void PrepareToShow() = 0;
   virtual void Show() = 0;
   virtual void Hide() = 0;
   virtual void SetDelegate(Delegate* delegate) = 0;
diff --git a/chrome/browser/chromeos/login/test/app_window_waiter.cc b/chrome/browser/chromeos/login/test/app_window_waiter.cc
index 5c69bb0..f9be212 100644
--- a/chrome/browser/chromeos/login/test/app_window_waiter.cc
+++ b/chrome/browser/chromeos/login/test/app_window_waiter.cc
@@ -38,8 +38,4 @@
   }
 }
 
-void AppWindowWaiter::OnAppWindowIconChanged(apps::AppWindow* app_window) {}
-
-void AppWindowWaiter::OnAppWindowRemoved(apps::AppWindow* app_window) {}
-
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/test/app_window_waiter.h b/chrome/browser/chromeos/login/test/app_window_waiter.h
index 3fcb9ec..3e796de 100644
--- a/chrome/browser/chromeos/login/test/app_window_waiter.h
+++ b/chrome/browser/chromeos/login/test/app_window_waiter.h
@@ -30,8 +30,6 @@
 
   // AppWindowRegistry::Observer:
   virtual void OnAppWindowAdded(apps::AppWindow* app_window) OVERRIDE;
-  virtual void OnAppWindowIconChanged(apps::AppWindow* app_window) OVERRIDE;
-  virtual void OnAppWindowRemoved(apps::AppWindow* app_window) OVERRIDE;
 
  private:
   apps::AppWindowRegistry* registry_;
diff --git a/chrome/browser/chromeos/login/user_adding_screen_browsertest.cc b/chrome/browser/chromeos/login/user_adding_screen_browsertest.cc
index 5c90708..0bdb21a 100644
--- a/chrome/browser/chromeos/login/user_adding_screen_browsertest.cc
+++ b/chrome/browser/chromeos/login/user_adding_screen_browsertest.cc
@@ -114,8 +114,7 @@
   StartupUtils::MarkOobeCompleted();
 }
 
-// Very flaky, see http://crbug.com/368621
-IN_PROC_BROWSER_TEST_F(UserAddingScreenTest, DISABLED_AddingSeveralUsers) {
+IN_PROC_BROWSER_TEST_F(UserAddingScreenTest, AddingSeveralUsers) {
   EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_LOGIN_PRIMARY,
             ash::Shell::GetInstance()->session_state_delegate()->
                 GetSessionState());
diff --git a/chrome/browser/chromeos/login/user_manager_impl.cc b/chrome/browser/chromeos/login/user_manager_impl.cc
index 7f27162..f9c557b 100644
--- a/chrome/browser/chromeos/login/user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/user_manager_impl.cc
@@ -40,6 +40,8 @@
 #include "chrome/browser/chromeos/login/supervised_user_manager_impl.h"
 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
+#include "chrome/browser/chromeos/net/network_portal_detector.h"
+#include "chrome/browser/chromeos/net/network_portal_detector_strategy.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_local_account.h"
 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
@@ -1570,6 +1572,11 @@
     // Indicate to DeviceSettingsService that the owner key may have become
     // available.
     DeviceSettingsService::Get()->SetUsername(active_user_->email());
+
+    if (NetworkPortalDetector::IsInitialized()) {
+      NetworkPortalDetector::Get()->SetStrategy(
+          PortalDetectorStrategy::STRATEGY_ID_SESSION);
+    }
   }
 }
 
diff --git a/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc b/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
index 13b8f23..0a74926 100644
--- a/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
+++ b/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/chromeos/login/wallpaper_manager.h"
 
-#include "ash/ash_resources/grit/ash_resources.h"
 #include "ash/ash_switches.h"
 #include "ash/desktop_background/desktop_background_controller.h"
 #include "ash/desktop_background/desktop_background_controller_observer.h"
@@ -34,6 +33,7 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/chromeos_switches.h"
 #include "content/public/test/test_utils.h"
+#include "grit/ash_resources.h"
 #include "ui/aura/env.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/codec/jpeg_codec.h"
diff --git a/chrome/browser/chromeos/login/wallpaper_manager_unittest.cc b/chrome/browser/chromeos/login/wallpaper_manager_unittest.cc
index e07a95d..4656c25 100644
--- a/chrome/browser/chromeos/login/wallpaper_manager_unittest.cc
+++ b/chrome/browser/chromeos/login/wallpaper_manager_unittest.cc
@@ -5,7 +5,6 @@
 #include <cstdlib>
 #include <cstring>
 
-#include "ash/ash_resources/grit/ash_resources.h"
 #include "ash/desktop_background/desktop_background_controller.h"
 #include "ash/desktop_background/desktop_background_controller_observer.h"
 #include "ash/shell.h"
@@ -31,6 +30,7 @@
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "chromeos/settings/cros_settings_provider.h"
+#include "grit/ash_resources.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/image/image.h"
diff --git a/chrome/browser/chromeos/login/webui_login_view.cc b/chrome/browser/chromeos/login/webui_login_view.cc
index 79d62f2..1a731cb 100644
--- a/chrome/browser/chromeos/login/webui_login_view.cc
+++ b/chrome/browser/chromeos/login/webui_login_view.cc
@@ -36,7 +36,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #include "ui/gfx/rect.h"
@@ -337,7 +336,7 @@
   // Return the focus to the web contents.
   webui_login_->web_contents()->FocusThroughTabTraversal(reverse);
   GetWidget()->Activate();
-  webui_login_->web_contents()->GetView()->Focus();
+  webui_login_->web_contents()->Focus();
 }
 
 void WebUILoginView::Observe(int type,
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index e3113bc..f2486d7 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -61,6 +61,7 @@
 #include "chrome/common/pref_names.h"
 #include "chromeos/audio/cras_audio_handler.h"
 #include "chromeos/chromeos_constants.h"
+#include "chromeos/chromeos_switches.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager_client.h"
 #include "chromeos/network/network_state.h"
@@ -84,6 +85,13 @@
 
 // Total timezone resolving process timeout.
 const unsigned int kResolveTimeZoneTimeoutSeconds = 60;
+
+// Checks flag for HID-detection screen show.
+bool CanShowHIDDetectionScreen() {
+  return CommandLine::ForCurrentProcess()->HasSwitch(
+      chromeos::switches::kEnableHIDDetectionOnOOBE);
+}
+
 }  // namespace
 
 namespace chromeos {
@@ -385,6 +393,8 @@
 }
 
 void WizardController::ShowEnrollmentScreen() {
+  VLOG(1) << "Showing enrollment screen.";
+
   SetStatusAreaVisible(true);
 
   bool is_auto_enrollment = false;
@@ -456,16 +466,21 @@
 
 void WizardController::ShowHIDDetectionScreen() {
   VLOG(1) << "Showing HID discovery screen.";
-  SetStatusAreaVisible(false);
+  SetStatusAreaVisible(true);
   SetCurrentScreen(GetHIDDetectionScreen());
 }
 
 void WizardController::SkipToLoginForTesting(
     const LoginScreenContext& context) {
+  VLOG(1) << "SkipToLoginForTesting.";
   StartupUtils::MarkEulaAccepted();
   PerformPostEulaActions();
   PerformOOBECompletedActions();
-  ShowLoginScreen(context);
+  if (ShouldAutoStartEnrollment()) {
+    ShowEnrollmentScreen();
+  } else {
+    ShowLoginScreen(context);
+  }
 }
 
 void WizardController::AddObserver(Observer* observer) {
@@ -776,7 +791,10 @@
     ShowHIDDetectionScreen();
   } else if (screen_name != kTestNoScreenName) {
     if (is_out_of_box_) {
-      ShowNetworkScreen();
+      if (CanShowHIDDetectionScreen())
+        ShowHIDDetectionScreen();
+      else
+        ShowNetworkScreen();
     } else {
       ShowLoginScreen(LoginScreenContext());
     }
diff --git a/chrome/browser/chromeos/net/network_portal_detector.cc b/chrome/browser/chromeos/net/network_portal_detector.cc
index 3a4c465..53ae3f8 100644
--- a/chrome/browser/chromeos/net/network_portal_detector.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector.cc
@@ -47,6 +47,8 @@
   virtual bool IsEnabled() OVERRIDE { return false; }
   virtual void Enable(bool /* start_detection */) OVERRIDE {}
   virtual bool StartDetectionIfIdle() OVERRIDE { return false; }
+  virtual void SetStrategy(
+      PortalDetectorStrategy::StrategyId /* id */) OVERRIDE {}
 };
 
 }  // namespace
diff --git a/chrome/browser/chromeos/net/network_portal_detector.h b/chrome/browser/chromeos/net/network_portal_detector.h
index 1add8ee..4a5872f 100644
--- a/chrome/browser/chromeos/net/network_portal_detector.h
+++ b/chrome/browser/chromeos/net/network_portal_detector.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_NET_NETWORK_PORTAL_DETECTOR_H_
 
 #include "base/basictypes.h"
-#include "chrome/browser/chromeos/login/screens/error_screen.h"
+#include "chrome/browser/chromeos/net/network_portal_detector_strategy.h"
 #include "net/url_request/url_fetcher.h"
 
 namespace chromeos {
@@ -16,7 +16,7 @@
 // This class handles all notifications about network changes from
 // NetworkStateHandler and delegates portal detection for the active
 // network to CaptivePortalService.
-class NetworkPortalDetector : public ErrorScreen::Observer {
+class NetworkPortalDetector {
  public:
   enum CaptivePortalStatus {
     CAPTIVE_PORTAL_STATUS_UNKNOWN  = 0,
@@ -96,8 +96,9 @@
   // started.
   virtual bool StartDetectionIfIdle() = 0;
 
-  virtual void OnErrorScreenShow() OVERRIDE {}
-  virtual void OnErrorScreenHide() OVERRIDE {}
+  // Sets current strategy according to |id|. If current detection id
+  // doesn't equal to |id|, detection is restarted.
+  virtual void SetStrategy(PortalDetectorStrategy::StrategyId id) = 0;
 
   // Initializes network portal detector for testing. The
   // |network_portal_detector| will be owned by the internal pointer
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl.cc b/chrome/browser/chromeos/net/network_portal_detector_impl.cc
index b05c749..ea8372b 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl.cc
@@ -156,8 +156,7 @@
       weak_factory_(this),
       attempt_count_(0),
       strategy_(PortalDetectorStrategy::CreateById(
-          PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN)),
-      error_screen_displayed_(false) {
+          PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN)) {
   captive_portal_detector_.reset(new CaptivePortalDetector(request_context));
   strategy_->set_delegate(this);
 
@@ -170,12 +169,9 @@
   registrar_.Add(this,
                  chrome::NOTIFICATION_AUTH_CANCELLED,
                  content::NotificationService::AllSources());
-  registrar_.Add(this,
-                 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
-                 content::NotificationService::AllSources());
 
   NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
-  UpdateCurrentStrategy();
+  StartDetectionIfIdle();
 }
 
 NetworkPortalDetectorImpl::~NetworkPortalDetectorImpl() {
@@ -252,6 +248,16 @@
   return true;
 }
 
+void NetworkPortalDetectorImpl::SetStrategy(
+    PortalDetectorStrategy::StrategyId id) {
+  if (id == strategy_->Id())
+    return;
+  strategy_.reset(PortalDetectorStrategy::CreateById(id).release());
+  strategy_->set_delegate(this);
+  StopDetection();
+  StartDetectionIfIdle();
+}
+
 void NetworkPortalDetectorImpl::DefaultNetworkChanged(
     const NetworkState* default_network) {
   DCHECK(CalledOnValidThread());
@@ -307,15 +313,6 @@
   return time_ticks_for_testing_;
 }
 
-void NetworkPortalDetectorImpl::OnErrorScreenShow() {
-  error_screen_displayed_ = true;
-  UpdateCurrentStrategy();
-}
-
-void NetworkPortalDetectorImpl::OnErrorScreenHide() {
-  error_screen_displayed_ = false;
-  UpdateCurrentStrategy();
-}
 
 ////////////////////////////////////////////////////////////////////////////////
 // NetworkPortalDetectorImpl, private:
@@ -401,8 +398,7 @@
           << "name=" << default_network_name_ << ", "
           << "id=" << default_network_id_ << ", "
           << "result="
-          << captive_portal::CaptivePortalResultToString(results.result)
-          << ", "
+          << captive_portal::CaptivePortalResultToString(results.result) << ", "
           << "response_code=" << results.response_code;
 
   state_ = STATE_IDLE;
@@ -425,11 +421,12 @@
   state.time = GetCurrentTimeTicks();
   switch (result) {
     case captive_portal::RESULT_NO_RESPONSE:
-      if (state.response_code == net::HTTP_PROXY_AUTHENTICATION_REQUIRED) {
-        state.status = CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED;
-      } else if (CanPerformAttempt()) {
+      if (CanPerformAttempt()) {
         ScheduleAttempt(results.retry_after_delta);
         return;
+      } else if (state.response_code ==
+                 net::HTTP_PROXY_AUTHENTICATION_REQUIRED) {
+        state.status = CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED;
       } else if (network &&
                  (network->connection_state() == shill::kStatePortal)) {
         // Take into account shill's detection results.
@@ -472,8 +469,6 @@
       return;
     StopDetection();
     ScheduleAttempt(base::TimeDelta::FromSeconds(kProxyChangeDelaySec));
-  } else if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) {
-    UpdateCurrentStrategy();
   }
 }
 
@@ -561,26 +556,4 @@
   }
 }
 
-void NetworkPortalDetectorImpl::UpdateCurrentStrategy() {
-  if (InSession()) {
-    SetStrategy(PortalDetectorStrategy::STRATEGY_ID_SESSION);
-    return;
-  }
-  if (error_screen_displayed_) {
-    SetStrategy(PortalDetectorStrategy::STRATEGY_ID_ERROR_SCREEN);
-    return;
-  }
-  SetStrategy(PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN);
-}
-
-void NetworkPortalDetectorImpl::SetStrategy(
-    PortalDetectorStrategy::StrategyId id) {
-  if (id == strategy_->Id())
-    return;
-  strategy_.reset(PortalDetectorStrategy::CreateById(id).release());
-  strategy_->set_delegate(this);
-  StopDetection();
-  StartDetectionIfIdle();
-}
-
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl.h b/chrome/browser/chromeos/net/network_portal_detector_impl.h
index 3f9aade..5a46362 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl.h
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl.h
@@ -73,6 +73,7 @@
   virtual bool IsEnabled() OVERRIDE;
   virtual void Enable(bool start_detection) OVERRIDE;
   virtual bool StartDetectionIfIdle() OVERRIDE;
+  virtual void SetStrategy(PortalDetectorStrategy::StrategyId id) OVERRIDE;
 
   // NetworkStateHandlerObserver implementation:
   virtual void DefaultNetworkChanged(const NetworkState* network) OVERRIDE;
@@ -82,10 +83,6 @@
   virtual base::TimeTicks AttemptStartTime() OVERRIDE;
   virtual base::TimeTicks GetCurrentTimeTicks() OVERRIDE;
 
-  // ErrorScreen::Observer implementation:
-  virtual void OnErrorScreenShow() OVERRIDE;
-  virtual void OnErrorScreenHide() OVERRIDE;
-
  private:
   friend class NetworkPortalDetectorImplTest;
   friend class NetworkPortalDetectorImplBrowserTest;
@@ -140,14 +137,6 @@
   void NotifyDetectionCompleted(const NetworkState* network,
                                 const CaptivePortalState& state);
 
-  // Updates current detection strategy according to the curren state:
-  // error screen, login screen or user session.
-  void UpdateCurrentStrategy();
-
-  // Sets current strategy according to |id|. If current detection id
-  // doesn't equal to |id|, detection is restarted.
-  void SetStrategy(PortalDetectorStrategy::StrategyId id);
-
   State state() const { return state_; }
 
   bool is_idle() const {
@@ -237,9 +226,6 @@
   // Current detection strategy.
   scoped_ptr<PortalDetectorStrategy> strategy_;
 
-  // True when error screen is displayed.
-  bool error_screen_displayed_;
-
   // UI notification controller about captive portal state.
   NetworkPortalNotificationController notification_controller_;
 
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc
index 70a0135..5060aeb 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc
@@ -69,7 +69,9 @@
     run_loop_.reset(new base::RunLoop());
   }
 
-  virtual void OnNotificationDisplayed(const std::string& notification_id)
+  virtual void OnNotificationDisplayed(
+      const std::string& notification_id,
+      const message_center::DisplaySource source)
       OVERRIDE {
     if (notification_id == kNotificationId)
       MessageLoop::current()->PostTask(FROM_HERE, run_loop_->QuitClosure());
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
index 20fb4b9..f2fbd67 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/metrics/statistics_recorder.h"
 #include "base/run_loop.h"
 #include "chrome/browser/chromeos/net/network_portal_detector_impl.h"
+#include "chrome/browser/chromeos/net/network_portal_detector_strategy.h"
 #include "chrome/browser/chromeos/net/network_portal_detector_test_utils.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/chromeos_switches.h"
@@ -134,11 +135,13 @@
   }
 
   void enable_error_screen_strategy() {
-    network_portal_detector()->OnErrorScreenShow();
+    network_portal_detector()->SetStrategy(
+        PortalDetectorStrategy::STRATEGY_ID_ERROR_SCREEN);
   }
 
   void disable_error_screen_strategy() {
-    network_portal_detector()->OnErrorScreenHide();
+    network_portal_detector()->SetStrategy(
+        PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN);
   }
 
   void stop_detection() { network_portal_detector()->StopDetection(); }
@@ -647,7 +650,18 @@
   SetConnected(kStubWireless1);
   CompleteURLFetch(net::OK, 407, NULL);
   ASSERT_EQ(1, attempt_count());
+  ASSERT_TRUE(is_state_portal_detection_pending());
+
+  base::RunLoop().RunUntilIdle();
+  CompleteURLFetch(net::OK, 407, NULL);
+  ASSERT_EQ(2, attempt_count());
+  ASSERT_TRUE(is_state_portal_detection_pending());
+
+  base::RunLoop().RunUntilIdle();
+  CompleteURLFetch(net::OK, 407, NULL);
+  ASSERT_EQ(3, attempt_count());
   ASSERT_TRUE(is_state_idle());
+
   CheckPortalState(
       NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED,
       407,
diff --git a/chrome/browser/chromeos/net/network_portal_detector_strategy.h b/chrome/browser/chromeos/net/network_portal_detector_strategy.h
index 36706da..3b02761 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_strategy.h
+++ b/chrome/browser/chromeos/net/network_portal_detector_strategy.h
@@ -17,7 +17,7 @@
   enum StrategyId {
     STRATEGY_ID_LOGIN_SCREEN,
     STRATEGY_ID_ERROR_SCREEN,
-    STRATEGY_ID_SESSION,
+    STRATEGY_ID_SESSION
   };
 
   class Delegate {
diff --git a/chrome/browser/chromeos/net/network_portal_detector_test_impl.cc b/chrome/browser/chromeos/net/network_portal_detector_test_impl.cc
index 0943b4a..ca2980a 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_test_impl.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_test_impl.cc
@@ -8,7 +8,9 @@
 
 namespace chromeos {
 
-NetworkPortalDetectorTestImpl::NetworkPortalDetectorTestImpl() {}
+NetworkPortalDetectorTestImpl::NetworkPortalDetectorTestImpl()
+    : strategy_id_(PortalDetectorStrategy::STRATEGY_ID_LOGIN_SCREEN) {
+}
 
 NetworkPortalDetectorTestImpl::~NetworkPortalDetectorTestImpl() {
 }
@@ -83,4 +85,9 @@
   return false;
 }
 
+void NetworkPortalDetectorTestImpl::SetStrategy(
+    PortalDetectorStrategy::StrategyId id) {
+  strategy_id_ = id;
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/net/network_portal_detector_test_impl.h b/chrome/browser/chromeos/net/network_portal_detector_test_impl.h
index 7ca0592..a176ba2 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_test_impl.h
+++ b/chrome/browser/chromeos/net/network_portal_detector_test_impl.h
@@ -36,14 +36,20 @@
   virtual void Enable(bool start_detection) OVERRIDE;
   virtual bool StartDetectionIfIdle() OVERRIDE;
 
+  virtual void SetStrategy(PortalDetectorStrategy::StrategyId id) OVERRIDE;
+
+  PortalDetectorStrategy::StrategyId strategy_id() const {
+    return strategy_id_;
+  }
+
  private:
   typedef std::string NetworkId;
   typedef base::hash_map<NetworkId, CaptivePortalState> CaptivePortalStateMap;
 
-
   ObserverList<Observer> observers_;
   scoped_ptr<NetworkState> default_network_;
   CaptivePortalStateMap portal_state_map_;
+  PortalDetectorStrategy::StrategyId strategy_id_;
 
   DISALLOW_COPY_AND_ASSIGN(NetworkPortalDetectorTestImpl);
 };
diff --git a/chrome/browser/chromeos/net/onc_utils.cc b/chrome/browser/chromeos/net/onc_utils.cc
index 83c89a4..e4dbceb 100644
--- a/chrome/browser/chromeos/net/onc_utils.cc
+++ b/chrome/browser/chromeos/net/onc_utils.cc
@@ -27,7 +27,6 @@
 #include "chromeos/network/onc/onc_signature.h"
 #include "chromeos/network/onc/onc_translator.h"
 #include "chromeos/network/onc/onc_utils.h"
-#include "chromeos/network/shill_property_util.h"
 #include "net/base/host_port_pair.h"
 #include "net/proxy/proxy_bypass_rules.h"
 #include "net/proxy/proxy_server.h"
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
index efb4c27..af19adc 100644
--- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
+++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/chromeos/policy/device_network_configuration_updater.h"
 #include "chrome/browser/chromeos/policy/device_status_collector.h"
 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
+#include "chrome/browser/chromeos/policy/server_backed_state_keys_broker.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chrome/browser/policy/device_management_service_configuration.h"
@@ -95,6 +96,10 @@
   // (removing it now breaks tests). crbug.com/141016.
   if (chromeos::SystemSaltGetter::IsInitialized() &&
       chromeos::DBusThreadManager::IsInitialized()) {
+    state_keys_broker_.reset(new ServerBackedStateKeysBroker(
+        chromeos::DBusThreadManager::Get()->GetSessionManagerClient(),
+        base::MessageLoopProxy::current()));
+
     chromeos::CryptohomeClient* cryptohome_client =
         chromeos::DBusThreadManager::Get()->GetCryptohomeClient();
     if (!install_attributes_) {
@@ -115,7 +120,8 @@
         new DeviceCloudPolicyManagerChromeOS(device_cloud_policy_store.Pass(),
                                              base::MessageLoopProxy::current(),
                                              GetBackgroundTaskRunner(),
-                                             install_attributes_.get());
+                                             install_attributes_.get(),
+                                             state_keys_broker_.get());
     AddPolicyProvider(
         scoped_ptr<ConfigurationPolicyProvider>(device_cloud_policy_manager_));
   }
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
index 86b34aa..19f0497 100644
--- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
+++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
@@ -30,6 +30,7 @@
 class EnterpriseInstallAttributes;
 class NetworkConfigurationUpdater;
 class ProxyPolicyProvider;
+class ServerBackedStateKeysBroker;
 
 // Extends ChromeBrowserPolicyConnector with the setup specific to ChromeOS.
 class BrowserPolicyConnectorChromeOS : public ChromeBrowserPolicyConnector {
@@ -75,6 +76,10 @@
     return install_attributes_.get();
   }
 
+  ServerBackedStateKeysBroker* GetStateKeysBroker() {
+    return state_keys_broker_.get();
+  }
+
   // The browser-global PolicyService is created before Profiles are ready, to
   // provide managed values for the local state PrefService. It includes a
   // policy provider that forwards policies from a delegate policy provider.
@@ -106,6 +111,7 @@
   void SetTimezoneIfPolicyAvailable();
 
   // Components of the device cloud policy implementation.
+  scoped_ptr<ServerBackedStateKeysBroker> state_keys_broker_;
   scoped_ptr<EnterpriseInstallAttributes> install_attributes_;
   DeviceCloudPolicyManagerChromeOS* device_cloud_policy_manager_;
   scoped_ptr<DeviceLocalAccountPolicyService>
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.cc b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.cc
index 82f04de..efc50b8 100644
--- a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.cc
+++ b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/chromeos/policy/enrollment_handler_chromeos.h"
 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
 #include "chrome/browser/chromeos/policy/server_backed_device_state.h"
+#include "chrome/browser/chromeos/policy/server_backed_state_keys_broker.h"
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_constants.h"
@@ -95,19 +96,20 @@
   return value;
 }
 
+// Checks whether forced re-enrollment is enabled.
+bool ForcedReEnrollmentEnabled() {
+  return chromeos::AutoEnrollmentController::GetMode() ==
+         chromeos::AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT;
+}
+
 }  // namespace
 
-const int
-DeviceCloudPolicyManagerChromeOS::kDeviceStateKeyTimeQuantumPower;
-
-const int
-DeviceCloudPolicyManagerChromeOS::kDeviceStateKeyFutureQuanta;
-
 DeviceCloudPolicyManagerChromeOS::DeviceCloudPolicyManagerChromeOS(
     scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,
     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
     const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
-    EnterpriseInstallAttributes* install_attributes)
+    EnterpriseInstallAttributes* install_attributes,
+    ServerBackedStateKeysBroker* state_keys_broker)
     : CloudPolicyManager(
           PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType,
                              std::string()),
@@ -118,8 +120,10 @@
       device_store_(store.Pass()),
       background_task_runner_(background_task_runner),
       install_attributes_(install_attributes),
+      state_keys_broker_(state_keys_broker),
       device_management_service_(NULL),
-      local_state_(NULL) {}
+      local_state_(NULL) {
+}
 
 DeviceCloudPolicyManagerChromeOS::~DeviceCloudPolicyManagerChromeOS() {}
 
@@ -135,7 +139,11 @@
   device_management_service_ = device_management_service;
   device_status_provider_ = device_status_provider.Pass();
 
-  InitalizeRequisition();
+  state_keys_update_subscription_ = state_keys_broker_->RegisterUpdateCallback(
+      base::Bind(&DeviceCloudPolicyManagerChromeOS::OnStateKeysUpdated,
+                 base::Unretained(this)));
+
+  InitializeRequisition();
   StartIfManaged();
 }
 
@@ -145,22 +153,28 @@
     const AllowedDeviceModes& allowed_device_modes,
     const EnrollmentCallback& callback) {
   CHECK(device_management_service_);
+  CHECK(!enrollment_handler_);
   core()->Disconnect();
 
-  enrollment_handler_.reset(
-      new EnrollmentHandlerChromeOS(
-          device_store_.get(), install_attributes_, CreateClient(),
-          background_task_runner_, auth_token,
-          install_attributes_->GetDeviceId(), is_auto_enrollment,
-          GetDeviceRequisition(), GetCurrentDeviceStateKey(),
-          allowed_device_modes,
-          base::Bind(&DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted,
-                     base::Unretained(this), callback)));
+  enrollment_handler_.reset(new EnrollmentHandlerChromeOS(
+      device_store_.get(),
+      install_attributes_,
+      state_keys_broker_,
+      CreateClient(),
+      background_task_runner_,
+      auth_token,
+      install_attributes_->GetDeviceId(),
+      is_auto_enrollment,
+      GetDeviceRequisition(),
+      allowed_device_modes,
+      base::Bind(&DeviceCloudPolicyManagerChromeOS::EnrollmentCompleted,
+                 base::Unretained(this),
+                 callback)));
   enrollment_handler_->StartEnrollment();
 }
 
 void DeviceCloudPolicyManagerChromeOS::CancelEnrollment() {
-  if (enrollment_handler_.get()) {
+  if (enrollment_handler_) {
     enrollment_handler_.reset();
     StartIfManaged();
   }
@@ -234,15 +248,14 @@
 }
 
 void DeviceCloudPolicyManagerChromeOS::Shutdown() {
+  state_keys_update_subscription_.reset();
   CloudPolicyManager::Shutdown();
   device_status_provider_.reset();
 }
 
 void DeviceCloudPolicyManagerChromeOS::OnStoreLoaded(CloudPolicyStore* store) {
   CloudPolicyManager::OnStoreLoaded(store);
-
-  if (!enrollment_handler_.get())
-    StartIfManaged();
+  StartIfManaged();
 }
 
 // static
@@ -279,18 +292,6 @@
   return GetMachineStatistic(chromeos::system::kHardwareClassKey);
 }
 
-// static
-std::string DeviceCloudPolicyManagerChromeOS::GetCurrentDeviceStateKey() {
-  std::vector<std::string> state_keys;
-  if (GetDeviceStateKeys(base::Time::Now(), &state_keys) &&
-      !state_keys.empty()) {
-    // The key for the current time is always the first one.
-    return state_keys[0];
-  }
-
-  return std::string();
-}
-
 scoped_ptr<CloudPolicyClient> DeviceCloudPolicyManagerChromeOS::CreateClient() {
   scoped_refptr<net::URLRequestContextGetter> request_context =
       new SystemPolicyRequestContext(
@@ -304,15 +305,6 @@
                             device_management_service_,
                             request_context));
 
-  // Set state keys to upload immediately after creation so the first policy
-  // fetch submits them to the server.
-  if (chromeos::AutoEnrollmentController::GetMode() ==
-      chromeos::AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT) {
-    std::vector<std::string> state_keys;
-    if (GetDeviceStateKeys(base::Time::Now(), &state_keys))
-      client->SetStateKeysToUpload(state_keys);
-  }
-
   return client.Pass();
 }
 
@@ -334,6 +326,8 @@
       local_state_ &&
       store()->is_initialized() &&
       store()->has_policy() &&
+      !state_keys_broker_->pending() &&
+      !enrollment_handler_ &&
       !service()) {
     StartConnection(CreateClient());
   }
@@ -341,6 +335,10 @@
 
 void DeviceCloudPolicyManagerChromeOS::StartConnection(
     scoped_ptr<CloudPolicyClient> client_to_connect) {
+  // Set state keys here so the first policy fetch submits them to the server.
+  if (ForcedReEnrollmentEnabled())
+    client_to_connect->SetStateKeysToUpload(state_keys_broker_->state_keys());
+
   core()->Connect(client_to_connect.Pass());
   core()->StartRefreshScheduler();
   core()->TrackRefreshDelayPref(local_state_,
@@ -349,7 +347,16 @@
       new chromeos::attestation::AttestationPolicyObserver(client()));
 }
 
-void DeviceCloudPolicyManagerChromeOS::InitalizeRequisition() {
+void DeviceCloudPolicyManagerChromeOS::OnStateKeysUpdated() {
+  if (client()) {
+    if (ForcedReEnrollmentEnabled())
+      client()->SetStateKeysToUpload(state_keys_broker_->state_keys());
+  } else {
+    StartIfManaged();
+  }
+}
+
+void DeviceCloudPolicyManagerChromeOS::InitializeRequisition() {
   // OEM statistics are only loaded when OOBE is not completed.
   if (chromeos::StartupUtils::IsOobeCompleted())
     return;
@@ -388,41 +395,4 @@
   return restore_mode;
 }
 
-// static
-bool DeviceCloudPolicyManagerChromeOS::GetDeviceStateKeys(
-    const base::Time& timestamp,
-    std::vector<std::string>* state_keys) {
-  state_keys->clear();
-
-  std::string disk_serial_number =
-      GetMachineStatistic(chromeos::system::kDiskSerialNumber);
-  if (disk_serial_number.empty()) {
-    LOG(ERROR) << "Missing disk serial number";
-    return false;
-  }
-
-  std::string machine_id = GetMachineID();
-  if (machine_id.empty())
-    return false;
-
-  // Tolerate missing group code keys, some old devices may not have it.
-  std::string group_code_key =
-      GetMachineStatistic(chromeos::system::kOffersGroupCodeKey);
-
-  // Get the current time in quantized form.
-  int64 quantum_size = GG_INT64_C(1) << kDeviceStateKeyTimeQuantumPower;
-  int64 quantized_time =
-      (timestamp - base::Time::UnixEpoch()).InSeconds() & ~(quantum_size - 1);
-  for (int i = 0; i < kDeviceStateKeyFutureQuanta; ++i) {
-    state_keys->push_back(crypto::SHA256HashString(
-        crypto::SHA256HashString(group_code_key) +
-        crypto::SHA256HashString(disk_serial_number) +
-        crypto::SHA256HashString(machine_id) +
-        crypto::SHA256HashString(base::Int64ToString(quantized_time))));
-    quantized_time += quantum_size;
-  }
-
-  return true;
-}
-
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h
index 735a747..0520567 100644
--- a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h
+++ b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h
@@ -15,6 +15,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/chromeos/policy/enrollment_status_chromeos.h"
+#include "chrome/browser/chromeos/policy/server_backed_state_keys_broker.h"
 #include "components/policy/core/common/cloud/cloud_policy_client.h"
 #include "components/policy/core/common/cloud/cloud_policy_manager.h"
 #include "components/policy/core/common/cloud/cloud_policy_store.h"
@@ -46,22 +47,6 @@
   typedef std::bitset<32> AllowedDeviceModes;
   typedef base::Callback<void(EnrollmentStatus)> EnrollmentCallback;
 
-  // The power of two determining the size of the time quanta for device state
-  // keys, i.e. the quanta will be of size 2^kDeviceStateKeyTimeQuantumPower
-  // seconds. 2^23 seconds corresponds to 97.09 days.
-  static const int kDeviceStateKeyTimeQuantumPower = 23;
-
-  // The number of future time quanta to generate device state identifiers for.
-  // This determines the interval after which a device will no longer receive
-  // server-backed state information and thus corresponds to the delay until a
-  // device becomes anonymous to the server again.
-  //
-  // The goal here is to guarantee state key validity for 1 year into the
-  // future. 4 quanta are needed to cover a year, but the current quantum is
-  // clipped short in the general case. Hence, one buffer quantum is needed to
-  // make up for the clipping, yielding a total of 5 quanta.
-  static const int kDeviceStateKeyFutureQuanta = 5;
-
   // |task_runner| is the runner for policy refresh tasks.
   // |background_task_runner| is used to execute long-running background tasks
   // that may involve file I/O.
@@ -69,7 +54,8 @@
       scoped_ptr<DeviceCloudPolicyStoreChromeOS> store,
       const scoped_refptr<base::SequencedTaskRunner>& task_runner,
       const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
-      EnterpriseInstallAttributes* install_attributes);
+      EnterpriseInstallAttributes* install_attributes,
+      ServerBackedStateKeysBroker* state_keys_broker);
   virtual ~DeviceCloudPolicyManagerChromeOS();
 
   // Establishes the connection to the cloud, updating policy as necessary.
@@ -118,15 +104,6 @@
   // Returns the machine model, or an empty string if not available.
   static std::string GetMachineModel();
 
-  // Gets the device state keys for |timestamp|. These will cover a time frame
-  // including |timestamp| and extending into the future as configured by the
-  // constants declared above.
-  static bool GetDeviceStateKeys(const base::Time& timestamp,
-                                 std::vector<std::string>* state_keys);
-
-  // Returns the currently valid device state key.
-  static std::string GetCurrentDeviceStateKey();
-
   // Returns the robot 'email address' associated with the device robot
   // account (sometimes called a service account) associated with this device
   // during enterprise enrollment.
@@ -147,8 +124,11 @@
   // Starts the connection via |client_to_connect|.
   void StartConnection(scoped_ptr<CloudPolicyClient> client_to_connect);
 
+  // Saves the state keys received from |session_manager_client_|.
+  void OnStateKeysUpdated();
+
   // Initializes requisition settings at OOBE with values from VPD.
-  void InitalizeRequisition();
+  void InitializeRequisition();
 
   // Gets the device restore mode as stored in |local_state_|.
   std::string GetRestoreMode() const;
@@ -158,6 +138,9 @@
   scoped_ptr<DeviceCloudPolicyStoreChromeOS> device_store_;
   scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
   EnterpriseInstallAttributes* install_attributes_;
+  ServerBackedStateKeysBroker* state_keys_broker_;
+
+  ServerBackedStateKeysBroker::Subscription state_keys_update_subscription_;
 
   DeviceManagementService* device_management_service_;
   scoped_ptr<CloudPolicyClient::StatusProvider> device_status_provider_;
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
index 5abfe5a..1ad3778 100644
--- a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
@@ -28,6 +28,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/fake_cryptohome_client.h"
 #include "chromeos/dbus/fake_dbus_thread_manager.h"
+#include "chromeos/dbus/fake_session_manager_client.h"
 #include "chromeos/system/mock_statistics_provider.h"
 #include "chromeos/system/statistics_provider.h"
 #include "components/policy/core/common/cloud/cloud_policy_client.h"
@@ -66,7 +67,10 @@
 class DeviceCloudPolicyManagerChromeOSTest
     : public chromeos::DeviceSettingsTestBase {
  protected:
-  DeviceCloudPolicyManagerChromeOSTest() : store_(NULL) {
+  DeviceCloudPolicyManagerChromeOSTest()
+      : state_keys_broker_(&fake_session_manager_client_,
+                           loop_.message_loop_proxy()),
+        store_(NULL) {
     EXPECT_CALL(mock_statistics_provider_,
                 GetMachineStatistic(_, _))
         .WillRepeatedly(Return(false));
@@ -76,6 +80,11 @@
                               Return(true)));
     chromeos::system::StatisticsProvider::SetTestProvider(
         &mock_statistics_provider_);
+    std::vector<std::string> state_keys;
+    state_keys.push_back("1");
+    state_keys.push_back("2");
+    state_keys.push_back("3");
+    fake_session_manager_client_.set_server_backed_state_keys(state_keys);
   }
 
   virtual ~DeviceCloudPolicyManagerChromeOSTest() {
@@ -95,7 +104,8 @@
         make_scoped_ptr(store_),
         loop_.message_loop_proxy(),
         loop_.message_loop_proxy(),
-        install_attributes_.get()));
+        install_attributes_.get(),
+        &state_keys_broker_));
 
     chrome::RegisterLocalState(local_state_.registry());
     manager_->Init(&schema_registry_);
@@ -160,6 +170,8 @@
   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
   chromeos::ScopedTestCrosSettings test_cros_settings_;
   chromeos::system::MockStatisticsProvider mock_statistics_provider_;
+  chromeos::FakeSessionManagerClient fake_session_manager_client_;
+  ServerBackedStateKeysBroker state_keys_broker_;
 
   DeviceCloudPolicyStoreChromeOS* store_;
   SchemaRegistry schema_registry_;
@@ -215,10 +227,6 @@
   PolicyBundle bundle;
   EXPECT_TRUE(manager_->policies().Equals(bundle));
 
-  manager_->Connect(&local_state_,
-                    &device_management_service_,
-                    scoped_ptr<CloudPolicyClient::StatusProvider>());
-
   // Trigger a policy refresh.
   MockDeviceManagementJob* policy_fetch_job = NULL;
   EXPECT_CALL(device_management_service_,
@@ -227,7 +235,10 @@
       .WillOnce(device_management_service_.CreateAsyncJob(&policy_fetch_job));
   EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _))
       .Times(AtMost(1));
-  manager_->RefreshPolicies();
+  manager_->Connect(&local_state_,
+                    &device_management_service_,
+                    scoped_ptr<CloudPolicyClient::StatusProvider>());
+  base::RunLoop().RunUntilIdle();
   Mock::VerifyAndClearExpectations(&device_management_service_);
   ASSERT_TRUE(policy_fetch_job);
 
@@ -263,70 +274,6 @@
   EXPECT_TRUE(manager_->policies().Equals(bundle));
 }
 
-class DeviceCloudPolicyManagerChromeOSStateKeyTest : public testing::Test {
- protected:
-  DeviceCloudPolicyManagerChromeOSStateKeyTest() {}
-
-  virtual void SetUp() OVERRIDE {
-    chromeos::system::StatisticsProvider::SetTestProvider(
-        &statistics_provider_);
-    EXPECT_CALL(statistics_provider_, GetMachineStatistic(_, _))
-        .WillRepeatedly(Invoke(this,
-                               &DeviceCloudPolicyManagerChromeOSStateKeyTest::
-                                   GetMachineStatistic));
-  }
-
-  virtual void TearDown() OVERRIDE {
-    chromeos::system::StatisticsProvider::SetTestProvider(NULL);
-  }
-
-  bool GetMachineStatistic(const std::string& name, std::string* result) {
-    *result = "fake-" + name;
-    return true;
-  }
-
- private:
-  chromeos::system::MockStatisticsProvider statistics_provider_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyManagerChromeOSStateKeyTest);
-};
-
-TEST_F(DeviceCloudPolicyManagerChromeOSStateKeyTest, GetDeviceStateKeys) {
-  base::Time current = base::Time::UnixEpoch() + base::TimeDelta::FromDays(100);
-
-  // The correct number of state keys gets returned.
-  std::vector<std::string> state_keys;
-  EXPECT_TRUE(DeviceCloudPolicyManagerChromeOS::GetDeviceStateKeys(
-      current, &state_keys));
-  EXPECT_EQ(DeviceCloudPolicyManagerChromeOS::kDeviceStateKeyFutureQuanta,
-            static_cast<int>(state_keys.size()));
-
-  // All state keys are different.
-  std::set<std::string> state_key_set(state_keys.begin(), state_keys.end());
-  EXPECT_EQ(DeviceCloudPolicyManagerChromeOS::kDeviceStateKeyFutureQuanta,
-            static_cast<int>(state_key_set.size()));
-
-  // Moving forward just a little yields the same keys.
-  std::vector<std::string> new_state_keys;
-  current += base::TimeDelta::FromDays(1);
-  EXPECT_TRUE(DeviceCloudPolicyManagerChromeOS::GetDeviceStateKeys(
-      current, &new_state_keys));
-  EXPECT_EQ(state_keys, new_state_keys);
-
-  // Jumping to a future quantum results in the state keys rolling forward.
-  int64 step =
-      GG_INT64_C(1)
-      << DeviceCloudPolicyManagerChromeOS::kDeviceStateKeyTimeQuantumPower;
-  current += 2 * base::TimeDelta::FromSeconds(step);
-
-  EXPECT_TRUE(DeviceCloudPolicyManagerChromeOS::GetDeviceStateKeys(
-      current, &new_state_keys));
-  ASSERT_EQ(DeviceCloudPolicyManagerChromeOS::kDeviceStateKeyFutureQuanta,
-            static_cast<int>(new_state_keys.size()));
-  EXPECT_TRUE(std::equal(state_keys.begin() + 2, state_keys.end(),
-                         new_state_keys.begin()));
-}
-
 class DeviceCloudPolicyManagerChromeOSEnrollmentTest
     : public DeviceCloudPolicyManagerChromeOSTest {
  public:
@@ -411,6 +358,7 @@
         "auth token", is_auto_enrollment_, modes,
         base::Bind(&DeviceCloudPolicyManagerChromeOSEnrollmentTest::Done,
                    base::Unretained(this)));
+    base::RunLoop().RunUntilIdle();
     Mock::VerifyAndClearExpectations(&device_management_service_);
 
     if (done_)
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
index e439529..5edfd05 100644
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -375,8 +375,6 @@
       run_loop_->Quit();
   }
 
-  virtual void OnAppWindowIconChanged(apps::AppWindow* app_window) OVERRIDE {}
-
   virtual void OnAppWindowRemoved(apps::AppWindow* app_window) OVERRIDE {
     if (run_loop_)
       run_loop_->Quit();
diff --git a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc
index 4797ee4..782cf3d 100644
--- a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc
+++ b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
 #include "chrome/browser/chromeos/policy/proto/install_attributes.pb.h"
+#include "chrome/common/chrome_paths.h"
 #include "chromeos/chromeos_paths.h"
 #include "chromeos/dbus/fake_dbus_thread_manager.h"
 #include "chromeos/dbus/fake_session_manager_client.h"
@@ -27,13 +28,13 @@
 
 namespace policy {
 
-DevicePolicyCrosTestHelper::DevicePolicyCrosTestHelper() {
-  CHECK(temp_dir_.CreateUniqueTempDir());
-}
+DevicePolicyCrosTestHelper::DevicePolicyCrosTestHelper() {}
 
 DevicePolicyCrosTestHelper::~DevicePolicyCrosTestHelper() {}
 
 void DevicePolicyCrosTestHelper::MarkAsEnterpriseOwned() {
+  OverridePaths();
+
   cryptohome::SerializedInstallAttributes install_attrs_proto;
   cryptohome::SerializedInstallAttributes::Attribute* attribute = NULL;
 
@@ -45,20 +46,22 @@
   attribute->set_name(EnterpriseInstallAttributes::kAttrEnterpriseUser);
   attribute->set_value(device_policy_.policy_data().username());
 
-  base::FilePath install_attrs_file =
-      temp_dir_.path().AppendASCII("install_attributes.pb");
+  base::FilePath install_attrs_file;
+  ASSERT_TRUE(
+      PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, &install_attrs_file));
   const std::string install_attrs_blob(
       install_attrs_proto.SerializeAsString());
   ASSERT_EQ(static_cast<int>(install_attrs_blob.size()),
             base::WriteFile(install_attrs_file,
                             install_attrs_blob.c_str(),
                             install_attrs_blob.size()));
-  ASSERT_TRUE(PathService::Override(chromeos::FILE_INSTALL_ATTRIBUTES,
-                                    install_attrs_file));
 }
 
 void DevicePolicyCrosTestHelper::InstallOwnerKey() {
-  base::FilePath owner_key_file = temp_dir_.path().AppendASCII("owner.key");
+  OverridePaths();
+
+  base::FilePath owner_key_file;
+  ASSERT_TRUE(PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_file));
   std::vector<uint8> owner_key_bits;
   ASSERT_TRUE(
       device_policy()->GetSigningKey()->ExportPublicKey(&owner_key_bits));
@@ -67,7 +70,15 @@
           reinterpret_cast<const char*>(vector_as_array(&owner_key_bits)),
           owner_key_bits.size()),
       static_cast<int>(owner_key_bits.size()));
-  ASSERT_TRUE(PathService::Override(chromeos::FILE_OWNER_KEY, owner_key_file));
+}
+
+void DevicePolicyCrosTestHelper::OverridePaths() {
+  // This is usually done by ChromeBrowserMainChromeOS, but some tests
+  // use the overridden paths before ChromeBrowserMain starts. Make sure that
+  // the paths are overridden before using them.
+  base::FilePath user_data_dir;
+  ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
+  chromeos::RegisterStubPathOverrides(user_data_dir);
 }
 
 DevicePolicyCrosBrowserTest::DevicePolicyCrosBrowserTest()
diff --git a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h
index c7b5036..1547504 100644
--- a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h
+++ b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h
@@ -7,7 +7,6 @@
 
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
-#include "base/files/scoped_temp_dir.h"
 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chromeos/dbus/fake_dbus_thread_manager.h"
@@ -34,8 +33,7 @@
   DevicePolicyBuilder* device_policy() { return &device_policy_; }
 
  private:
-  // Stores the device owner key and the install attributes.
-  base::ScopedTempDir temp_dir_;
+  void OverridePaths();
 
   // Carries Chrome OS device policies for tests.
   DevicePolicyBuilder device_policy_;
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
index 48c6d34..d9b2793 100644
--- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
+++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
@@ -9,6 +9,7 @@
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h"
 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
@@ -40,24 +41,24 @@
 EnrollmentHandlerChromeOS::EnrollmentHandlerChromeOS(
     DeviceCloudPolicyStoreChromeOS* store,
     EnterpriseInstallAttributes* install_attributes,
+    ServerBackedStateKeysBroker* state_keys_broker,
     scoped_ptr<CloudPolicyClient> client,
     scoped_refptr<base::SequencedTaskRunner> background_task_runner,
     const std::string& auth_token,
     const std::string& client_id,
     bool is_auto_enrollment,
     const std::string& requisition,
-    const std::string& current_state_key,
     const AllowedDeviceModes& allowed_device_modes,
     const EnrollmentCallback& completion_callback)
     : store_(store),
       install_attributes_(install_attributes),
+      state_keys_broker_(state_keys_broker),
       client_(client.Pass()),
       background_task_runner_(background_task_runner),
       auth_token_(auth_token),
       client_id_(client_id),
       is_auto_enrollment_(is_auto_enrollment),
       requisition_(requisition),
-      current_state_key_(current_state_key),
       allowed_device_modes_(allowed_device_modes),
       completion_callback_(completion_callback),
       device_mode_(DEVICE_MODE_NOT_SET),
@@ -79,8 +80,10 @@
 
 void EnrollmentHandlerChromeOS::StartEnrollment() {
   CHECK_EQ(STEP_PENDING, enrollment_step_);
-  enrollment_step_ = STEP_LOADING_STORE;
-  AttemptRegistration();
+  enrollment_step_ = STEP_STATE_KEYS;
+  state_keys_broker_->RequestStateKeys(
+      base::Bind(&EnrollmentHandlerChromeOS::CheckStateKeys,
+                 weak_ptr_factory_.GetWeakPtr()));
 }
 
 scoped_ptr<CloudPolicyClient> EnrollmentHandlerChromeOS::ReleaseClient() {
@@ -189,6 +192,26 @@
                                                store_->validation_status()));
 }
 
+void EnrollmentHandlerChromeOS::CheckStateKeys(
+    const std::vector<std::string>& state_keys) {
+  CHECK_EQ(STEP_STATE_KEYS, enrollment_step_);
+
+  // Make sure state keys are available if forced re-enrollment is on.
+  if (chromeos::AutoEnrollmentController::GetMode() ==
+      chromeos::AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT) {
+    if (state_keys.empty()) {
+      ReportResult(
+          EnrollmentStatus::ForStatus(EnrollmentStatus::STATUS_NO_STATE_KEYS));
+      return;
+    }
+    client_->SetStateKeysToUpload(state_keys);
+    current_state_key_ = state_keys_broker_->current_state_key();
+  }
+
+  enrollment_step_ = STEP_LOADING_STORE;
+  AttemptRegistration();
+}
+
 void EnrollmentHandlerChromeOS::AttemptRegistration() {
   CHECK_EQ(STEP_LOADING_STORE, enrollment_step_);
   if (store_->is_initialized()) {
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h
index e92accf..c54eb51 100644
--- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h
+++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h
@@ -29,6 +29,8 @@
 
 namespace policy {
 
+class ServerBackedStateKeysBroker;
+
 // Implements the logic that establishes enterprise enrollment for Chromium OS
 // devices. The process is as follows:
 //   1. Given an auth token, register with the policy service.
@@ -57,13 +59,13 @@
   EnrollmentHandlerChromeOS(
       DeviceCloudPolicyStoreChromeOS* store,
       EnterpriseInstallAttributes* install_attributes,
+      ServerBackedStateKeysBroker* state_keys_broker,
       scoped_ptr<CloudPolicyClient> client,
       scoped_refptr<base::SequencedTaskRunner> background_task_runner,
       const std::string& auth_token,
       const std::string& client_id,
       bool is_auto_enrollment,
       const std::string& requisition,
-      const std::string& current_state_key,
       const AllowedDeviceModes& allowed_device_modes,
       const EnrollmentCallback& completion_callback);
   virtual ~EnrollmentHandlerChromeOS();
@@ -99,6 +101,7 @@
   // to be listed in the order they are traversed in.
   enum EnrollmentStep {
     STEP_PENDING,             // Not started yet.
+    STEP_STATE_KEYS,          // Waiting for state keys to become available.
     STEP_LOADING_STORE,       // Waiting for |store_| to initialize.
     STEP_REGISTRATION,        // Currently registering the client.
     STEP_POLICY_FETCH,        // Fetching policy.
@@ -111,6 +114,9 @@
     STEP_FINISHED,            // Enrollment process finished, no further action.
   };
 
+  // Handles the response to a request for server-backed state keys.
+  void CheckStateKeys(const std::vector<std::string>& state_keys);
+
   // Starts registration if the store is initialized.
   void AttemptRegistration();
 
@@ -144,6 +150,7 @@
 
   DeviceCloudPolicyStoreChromeOS* store_;
   EnterpriseInstallAttributes* install_attributes_;
+  ServerBackedStateKeysBroker* state_keys_broker_;
   scoped_ptr<CloudPolicyClient> client_;
   scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
   scoped_ptr<gaia::GaiaOAuthClient> gaia_oauth_client_;
@@ -172,7 +179,6 @@
   // initialization.
   int lockbox_init_duration_;
 
-  // Used for locking the device.
   base::WeakPtrFactory<EnrollmentHandlerChromeOS> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(EnrollmentHandlerChromeOS);
diff --git a/chrome/browser/chromeos/policy/enrollment_status_chromeos.h b/chrome/browser/chromeos/policy/enrollment_status_chromeos.h
index f2c4281..3bf97f6 100644
--- a/chrome/browser/chromeos/policy/enrollment_status_chromeos.h
+++ b/chrome/browser/chromeos/policy/enrollment_status_chromeos.h
@@ -18,6 +18,7 @@
   // Enrollment status codes.
   enum Status {
     STATUS_SUCCESS,                     // Enrollment succeeded.
+    STATUS_NO_STATE_KEYS,               // Server-backed state keys unavailable.
     STATUS_REGISTRATION_FAILED,         // DM registration failed.
     STATUS_REGISTRATION_BAD_MODE,       // Bad device mode.
     STATUS_ROBOT_AUTH_FETCH_FAILED,     // API OAuth2 auth code failure.
diff --git a/chrome/browser/chromeos/policy/enterprise_install_attributes_unittest.cc b/chrome/browser/chromeos/policy/enterprise_install_attributes_unittest.cc
index 338735a..565f22a 100644
--- a/chrome/browser/chromeos/policy/enterprise_install_attributes_unittest.cc
+++ b/chrome/browser/chromeos/policy/enterprise_install_attributes_unittest.cc
@@ -5,14 +5,18 @@
 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
 
 #include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/path_service.h"
 #include "base/run_loop.h"
+#include "base/threading/worker_pool.h"
 #include "chrome/browser/chromeos/policy/proto/install_attributes.pb.h"
+#include "chromeos/chromeos_paths.h"
 #include "chromeos/cryptohome/cryptohome_util.h"
+#include "chromeos/dbus/cryptohome_client.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/fake_cryptohome_client.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -38,15 +42,15 @@
 
 class EnterpriseInstallAttributesTest : public testing::Test {
  protected:
-  EnterpriseInstallAttributesTest()
-      : fake_cryptohome_client_(new chromeos::FakeCryptohomeClient()),
-        install_attributes_(fake_cryptohome_client_.get()) {
-    fake_cryptohome_client_->Init(NULL /* no dbus::Bus */);
-  }
+  EnterpriseInstallAttributesTest() {}
 
   virtual void SetUp() OVERRIDE {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+    ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(
+        chromeos::FILE_INSTALL_ATTRIBUTES, GetTempPath(), true, false));
     chromeos::DBusThreadManager::InitializeWithStub();
+    install_attributes_.reset(new EnterpriseInstallAttributes(
+        chromeos::DBusThreadManager::Get()->GetCryptohomeClient()));
   }
 
   virtual void TearDown() OVERRIDE {
@@ -54,7 +58,8 @@
   }
 
   base::FilePath GetTempPath() const {
-    return temp_dir_.path().Append("install_attrs_test");
+    base::FilePath temp_path = base::MakeAbsoluteFilePath(temp_dir_.path());
+    return temp_path.Append("install_attrs_test");
   }
 
   void SetAttribute(
@@ -69,8 +74,7 @@
 
   base::MessageLoopForUI message_loop_;
   base::ScopedTempDir temp_dir_;
-  scoped_ptr<chromeos::FakeCryptohomeClient> fake_cryptohome_client_;
-  EnterpriseInstallAttributes install_attributes_;
+  scoped_ptr<EnterpriseInstallAttributes> install_attributes_;
 
   EnterpriseInstallAttributes::LockResult LockDeviceAndWaitForResult(
       const std::string& user,
@@ -78,8 +82,11 @@
       const std::string& device_id) {
     base::RunLoop loop;
     EnterpriseInstallAttributes::LockResult result;
-    install_attributes_.LockDevice(user, device_mode, device_id,
-                                   base::Bind(&CopyLockResult, &loop, &result));
+    install_attributes_->LockDevice(
+        user,
+        device_mode,
+        device_id,
+        base::Bind(&CopyLockResult, &loop, &result));
     loop.Run();
     return result;
   }
@@ -118,81 +125,81 @@
                 DEVICE_MODE_ENTERPRISE,
                 kTestDeviceId));
   EXPECT_EQ(gaia::CanonicalizeEmail(kTestUserCanonicalize),
-            install_attributes_.GetRegistrationUser());
+            install_attributes_->GetRegistrationUser());
 }
 
 TEST_F(EnterpriseInstallAttributesTest, IsEnterpriseDevice) {
-  install_attributes_.ReadCacheFile(GetTempPath());
-  EXPECT_FALSE(install_attributes_.IsEnterpriseDevice());
+  install_attributes_->ReadCacheFile(GetTempPath());
+  EXPECT_FALSE(install_attributes_->IsEnterpriseDevice());
   ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS,
             LockDeviceAndWaitForResult(
                 kTestUser,
                 DEVICE_MODE_ENTERPRISE,
                 kTestDeviceId));
-  EXPECT_TRUE(install_attributes_.IsEnterpriseDevice());
+  EXPECT_TRUE(install_attributes_->IsEnterpriseDevice());
 }
 
 TEST_F(EnterpriseInstallAttributesTest, GetDomain) {
-  install_attributes_.ReadCacheFile(GetTempPath());
-  EXPECT_EQ(std::string(), install_attributes_.GetDomain());
+  install_attributes_->ReadCacheFile(GetTempPath());
+  EXPECT_EQ(std::string(), install_attributes_->GetDomain());
   ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS,
             LockDeviceAndWaitForResult(
                 kTestUser,
                 DEVICE_MODE_ENTERPRISE,
                 kTestDeviceId));
-  EXPECT_EQ(kTestDomain, install_attributes_.GetDomain());
+  EXPECT_EQ(kTestDomain, install_attributes_->GetDomain());
 }
 
 TEST_F(EnterpriseInstallAttributesTest, GetRegistrationUser) {
-  install_attributes_.ReadCacheFile(GetTempPath());
-  EXPECT_EQ(std::string(), install_attributes_.GetRegistrationUser());
+  install_attributes_->ReadCacheFile(GetTempPath());
+  EXPECT_EQ(std::string(), install_attributes_->GetRegistrationUser());
   ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS,
             LockDeviceAndWaitForResult(
                 kTestUser,
                 DEVICE_MODE_ENTERPRISE,
                 kTestDeviceId));
-  EXPECT_EQ(kTestUser, install_attributes_.GetRegistrationUser());
+  EXPECT_EQ(kTestUser, install_attributes_->GetRegistrationUser());
 }
 
 TEST_F(EnterpriseInstallAttributesTest, GetDeviceId) {
-  install_attributes_.ReadCacheFile(GetTempPath());
-  EXPECT_EQ(std::string(), install_attributes_.GetDeviceId());
+  install_attributes_->ReadCacheFile(GetTempPath());
+  EXPECT_EQ(std::string(), install_attributes_->GetDeviceId());
   ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS,
             LockDeviceAndWaitForResult(
                 kTestUser,
                 DEVICE_MODE_ENTERPRISE,
                 kTestDeviceId));
-  EXPECT_EQ(kTestDeviceId, install_attributes_.GetDeviceId());
+  EXPECT_EQ(kTestDeviceId, install_attributes_->GetDeviceId());
 }
 
 TEST_F(EnterpriseInstallAttributesTest, GetMode) {
-  install_attributes_.ReadCacheFile(GetTempPath());
-  EXPECT_EQ(DEVICE_MODE_PENDING, install_attributes_.GetMode());
+  install_attributes_->ReadCacheFile(GetTempPath());
+  EXPECT_EQ(DEVICE_MODE_PENDING, install_attributes_->GetMode());
   ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS,
             LockDeviceAndWaitForResult(
                 kTestUser,
                 DEVICE_MODE_RETAIL_KIOSK,
                 kTestDeviceId));
   EXPECT_EQ(DEVICE_MODE_RETAIL_KIOSK,
-            install_attributes_.GetMode());
+            install_attributes_->GetMode());
 }
 
 TEST_F(EnterpriseInstallAttributesTest, ConsumerDevice) {
-  install_attributes_.ReadCacheFile(GetTempPath());
-  EXPECT_EQ(DEVICE_MODE_PENDING, install_attributes_.GetMode());
+  install_attributes_->ReadCacheFile(GetTempPath());
+  EXPECT_EQ(DEVICE_MODE_PENDING, install_attributes_->GetMode());
   // Lock the attributes empty.
   ASSERT_TRUE(cryptohome_util::InstallAttributesFinalize());
   base::RunLoop loop;
-  install_attributes_.ReadImmutableAttributes(base::Bind(loop.QuitClosure()));
+  install_attributes_->ReadImmutableAttributes(loop.QuitClosure());
   loop.Run();
 
   ASSERT_FALSE(cryptohome_util::InstallAttributesIsFirstInstall());
-  EXPECT_EQ(DEVICE_MODE_CONSUMER, install_attributes_.GetMode());
+  EXPECT_EQ(DEVICE_MODE_CONSUMER, install_attributes_->GetMode());
 }
 
 TEST_F(EnterpriseInstallAttributesTest, ConsumerKioskDevice) {
-  install_attributes_.ReadCacheFile(GetTempPath());
-  EXPECT_EQ(DEVICE_MODE_PENDING, install_attributes_.GetMode());
+  install_attributes_->ReadCacheFile(GetTempPath());
+  EXPECT_EQ(DEVICE_MODE_PENDING, install_attributes_->GetMode());
   // Lock the attributes for consumer kiosk.
   ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS,
             LockDeviceAndWaitForResult(
@@ -202,13 +209,13 @@
 
   ASSERT_FALSE(cryptohome_util::InstallAttributesIsFirstInstall());
   EXPECT_EQ(DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH,
-            install_attributes_.GetMode());
-  ASSERT_TRUE(install_attributes_.IsConsumerKioskDeviceWithAutoLaunch());
+            install_attributes_->GetMode());
+  ASSERT_TRUE(install_attributes_->IsConsumerKioskDeviceWithAutoLaunch());
 }
 
 TEST_F(EnterpriseInstallAttributesTest, DeviceLockedFromOlderVersion) {
-  install_attributes_.ReadCacheFile(GetTempPath());
-  EXPECT_EQ(DEVICE_MODE_PENDING, install_attributes_.GetMode());
+  install_attributes_->ReadCacheFile(GetTempPath());
+  EXPECT_EQ(DEVICE_MODE_PENDING, install_attributes_->GetMode());
   // Lock the attributes as if it was done from older Chrome version.
   ASSERT_TRUE(cryptohome_util::InstallAttributesSet(
       EnterpriseInstallAttributes::kAttrEnterpriseOwned, "true"));
@@ -216,14 +223,14 @@
       EnterpriseInstallAttributes::kAttrEnterpriseUser, kTestUser));
   ASSERT_TRUE(cryptohome_util::InstallAttributesFinalize());
   base::RunLoop loop;
-  install_attributes_.ReadImmutableAttributes(base::Bind(loop.QuitClosure()));
+  install_attributes_->ReadImmutableAttributes(loop.QuitClosure());
   loop.Run();
 
   ASSERT_FALSE(cryptohome_util::InstallAttributesIsFirstInstall());
-  EXPECT_EQ(DEVICE_MODE_ENTERPRISE, install_attributes_.GetMode());
-  EXPECT_EQ(kTestDomain, install_attributes_.GetDomain());
-  EXPECT_EQ(kTestUser, install_attributes_.GetRegistrationUser());
-  EXPECT_EQ("", install_attributes_.GetDeviceId());
+  EXPECT_EQ(DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode());
+  EXPECT_EQ(kTestDomain, install_attributes_->GetDomain());
+  EXPECT_EQ(kTestUser, install_attributes_->GetRegistrationUser());
+  EXPECT_EQ("", install_attributes_->GetDeviceId());
 }
 
 TEST_F(EnterpriseInstallAttributesTest, ReadCacheFile) {
@@ -235,11 +242,11 @@
   const std::string blob(install_attrs_proto.SerializeAsString());
   ASSERT_EQ(static_cast<int>(blob.size()),
             base::WriteFile(GetTempPath(), blob.c_str(), blob.size()));
-  install_attributes_.ReadCacheFile(GetTempPath());
-  EXPECT_EQ(DEVICE_MODE_ENTERPRISE, install_attributes_.GetMode());
-  EXPECT_EQ(kTestDomain, install_attributes_.GetDomain());
-  EXPECT_EQ(kTestUser, install_attributes_.GetRegistrationUser());
-  EXPECT_EQ("", install_attributes_.GetDeviceId());
+  install_attributes_->ReadCacheFile(GetTempPath());
+  EXPECT_EQ(DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode());
+  EXPECT_EQ(kTestDomain, install_attributes_->GetDomain());
+  EXPECT_EQ(kTestUser, install_attributes_->GetRegistrationUser());
+  EXPECT_EQ("", install_attributes_->GetDeviceId());
 }
 
 TEST_F(EnterpriseInstallAttributesTest, ReadCacheFileForConsumerKiosk) {
@@ -249,12 +256,38 @@
   const std::string blob(install_attrs_proto.SerializeAsString());
   ASSERT_EQ(static_cast<int>(blob.size()),
             base::WriteFile(GetTempPath(), blob.c_str(), blob.size()));
-  install_attributes_.ReadCacheFile(GetTempPath());
+  install_attributes_->ReadCacheFile(GetTempPath());
   EXPECT_EQ(DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH,
-            install_attributes_.GetMode());
-  EXPECT_EQ("", install_attributes_.GetDomain());
-  EXPECT_EQ("", install_attributes_.GetRegistrationUser());
-  EXPECT_EQ("", install_attributes_.GetDeviceId());
+            install_attributes_->GetMode());
+  EXPECT_EQ("", install_attributes_->GetDomain());
+  EXPECT_EQ("", install_attributes_->GetRegistrationUser());
+  EXPECT_EQ("", install_attributes_->GetDeviceId());
+}
+
+TEST_F(EnterpriseInstallAttributesTest, VerifyFakeInstallAttributesCache) {
+  // This test verifies that FakeCryptohomeClient::InstallAttributesFinalize
+  // writes a cache that EnterpriseInstallAttributes::ReadCacheFile accepts.
+
+  // Verify that no attributes are initially set.
+  install_attributes_->ReadCacheFile(GetTempPath());
+  EXPECT_EQ("", install_attributes_->GetRegistrationUser());
+
+  // Write test values.
+  ASSERT_TRUE(cryptohome_util::InstallAttributesSet(
+      EnterpriseInstallAttributes::kAttrEnterpriseOwned, "true"));
+  ASSERT_TRUE(cryptohome_util::InstallAttributesSet(
+      EnterpriseInstallAttributes::kAttrEnterpriseUser, kTestUser));
+  ASSERT_TRUE(cryptohome_util::InstallAttributesFinalize());
+  // Wait for the async write.
+  base::RunLoop loop;
+  base::WorkerPool::PostTaskAndReply(
+      FROM_HERE, base::Bind(&base::DoNothing), loop.QuitClosure(), false);
+  loop.Run();
+
+  // Verify that EnterpriseInstallAttributes correctly decodes the stub
+  // cache file.
+  install_attributes_->ReadCacheFile(GetTempPath());
+  EXPECT_EQ(kTestUser, install_attributes_->GetRegistrationUser());
 }
 
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc
new file mode 100644
index 0000000..df174e2
--- /dev/null
+++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc
@@ -0,0 +1,105 @@
+// 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.
+
+#include "chrome/browser/chromeos/policy/server_backed_state_keys_broker.h"
+
+#include <algorithm>
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/task_runner.h"
+#include "chromeos/dbus/session_manager_client.h"
+
+namespace policy {
+
+namespace {
+
+// Refresh interval for state keys. There's a quantized time component in
+// state key generation, so they rotate over time. The quantum size is pretty
+// coarse though (currently 2^23 seconds), so simply polling for a new state
+// keys once a day is good enough.
+const int kPollIntervalSeconds = 60 * 60 * 24;
+
+}  // namespace
+
+ServerBackedStateKeysBroker::ServerBackedStateKeysBroker(
+    chromeos::SessionManagerClient* session_manager_client,
+    scoped_refptr<base::TaskRunner> delayed_task_runner)
+    : session_manager_client_(session_manager_client),
+      delayed_task_runner_(delayed_task_runner),
+      requested_(false),
+      initial_retrieval_completed_(false),
+      weak_factory_(this) {
+}
+
+ServerBackedStateKeysBroker::~ServerBackedStateKeysBroker() {
+}
+
+ServerBackedStateKeysBroker::Subscription
+ServerBackedStateKeysBroker::RegisterUpdateCallback(
+    const base::Closure& callback) {
+  if (!available())
+    FetchStateKeys();
+  return update_callbacks_.Add(callback);
+}
+
+void ServerBackedStateKeysBroker::RequestStateKeys(
+    const StateKeysCallback& callback) {
+  if (pending()) {
+    request_callbacks_.push_back(callback);
+    FetchStateKeys();
+    return;
+  }
+
+  if (!callback.is_null())
+    callback.Run(state_keys_);
+  return;
+}
+
+void ServerBackedStateKeysBroker::FetchStateKeys() {
+  if (!requested_) {
+    requested_ = true;
+    session_manager_client_->GetServerBackedStateKeys(
+        base::Bind(&ServerBackedStateKeysBroker::StoreStateKeys,
+                   weak_factory_.GetWeakPtr()));
+  }
+}
+
+void ServerBackedStateKeysBroker::StoreStateKeys(
+    const std::vector<std::string>& state_keys) {
+  bool send_notification = !initial_retrieval_completed_;
+
+  requested_ = false;
+  initial_retrieval_completed_ = true;
+  if (state_keys.empty()) {
+    LOG(WARNING) << "Failed to obtain server-backed state keys.";
+  } else if (state_keys.end() !=
+             std::find(state_keys.begin(), state_keys.end(), std::string())) {
+    LOG(WARNING) << "Bad state keys.";
+  } else {
+    send_notification |= state_keys_ != state_keys;
+    state_keys_ = state_keys;
+  }
+
+  if (send_notification)
+    update_callbacks_.Notify();
+
+  std::vector<StateKeysCallback> callbacks;
+  request_callbacks_.swap(callbacks);
+  for (std::vector<StateKeysCallback>::const_iterator callback(
+           callbacks.begin());
+       callback != callbacks.end();
+       ++callback) {
+    if (!callback->is_null())
+      callback->Run(state_keys_);
+  }
+
+  delayed_task_runner_->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&ServerBackedStateKeysBroker::FetchStateKeys,
+                 weak_factory_.GetWeakPtr()),
+      base::TimeDelta::FromSeconds(kPollIntervalSeconds));
+}
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h
new file mode 100644
index 0000000..3711cad
--- /dev/null
+++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h
@@ -0,0 +1,102 @@
+// 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_POLICY_SERVER_BACKED_STATE_KEYS_BROKER_H_
+#define CHROME_BROWSER_CHROMEOS_POLICY_SERVER_BACKED_STATE_KEYS_BROKER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/callback_list.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+
+namespace base {
+class TaskRunner;
+}
+
+namespace chromeos {
+class SessionManagerClient;
+}
+
+namespace policy {
+
+// Brokers server-backed state keys for the device. Retrieves them from session
+// manager via DBus and refreshes them periodically. Consumers can register
+// callbacks to invoke when the state keys change.
+class ServerBackedStateKeysBroker {
+ public:
+  typedef scoped_ptr<base::CallbackList<void()>::Subscription> Subscription;
+  typedef base::Callback<void(const std::vector<std::string>&)>
+      StateKeysCallback;
+
+  ServerBackedStateKeysBroker(
+      chromeos::SessionManagerClient* session_manager_client,
+      scoped_refptr<base::TaskRunner> delayed_task_runner);
+  ~ServerBackedStateKeysBroker();
+
+  // Registers a callback to be invoked whenever the state keys get updated.
+  // Note that consuming code needs to hold on to the returned Subscription as
+  // long as it wants to receive the callback. If the state keys haven't been
+  // requested yet, calling this will also trigger their initial fetch.
+  Subscription RegisterUpdateCallback(const base::Closure& callback);
+
+  // Requests state keys asynchronously. Invokes the passed callback exactly
+  // once (unless |this| gets destroyed before the callback happens), with the
+  // current state keys passed as a parameter to the callback. If there's a
+  // problem determining the state keys, the passed vector will be empty.
+  void RequestStateKeys(const StateKeysCallback& callback);
+
+  // Get the set of current state keys. Empty if state keys are unavailable
+  // or pending retrieval.
+  const std::vector<std::string>& state_keys() const { return state_keys_; }
+
+  // Returns the state key for the current point in time. Returns an empty
+  // string if state keys are unavailable or pending retrieval.
+  std::string current_state_key() const {
+    return state_keys_.empty() ? std::string() : state_keys_.front();
+  }
+
+  // Whether state key retrieval is pending.
+  bool pending() const { return !initial_retrieval_completed_; }
+
+  // Whether state keys are available.
+  bool available() const { return !state_keys_.empty(); }
+
+ private:
+  // Asks |session_manager_client_| to provide current state keys..
+  void FetchStateKeys();
+
+  // Stores newly-received state keys and notifies consumers.
+  void StoreStateKeys(const std::vector<std::string>& state_keys);
+
+  chromeos::SessionManagerClient* session_manager_client_;
+
+  scoped_refptr<base::TaskRunner> delayed_task_runner_;
+
+  // The current set of state keys.
+  std::vector<std::string> state_keys_;
+
+  // Whether a request for state keys is pending.
+  bool requested_;
+
+  // Whether the initial retrieval operation completed.
+  bool initial_retrieval_completed_;
+
+  // List of callbacks to receive update notifications.
+  base::CallbackList<void()> update_callbacks_;
+
+  // List of pending one-shot state key request callbacks.
+  std::vector<StateKeysCallback> request_callbacks_;
+
+  base::WeakPtrFactory<ServerBackedStateKeysBroker> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ServerBackedStateKeysBroker);
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_CHROMEOS_POLICY_SERVER_BACKED_STATE_KEYS_BROKER_H_
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc b/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc
new file mode 100644
index 0000000..2dad66b
--- /dev/null
+++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc
@@ -0,0 +1,151 @@
+// 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.
+
+#include "chrome/browser/chromeos/policy/server_backed_state_keys_broker.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/test/test_simple_task_runner.h"
+#include "chromeos/dbus/fake_session_manager_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+class ServerBackedStateKeysBrokerTest : public testing::Test {
+ public:
+  ServerBackedStateKeysBrokerTest()
+      : task_runner_(new base::TestSimpleTaskRunner()),
+        broker_(&fake_session_manager_client_, task_runner_),
+        updated_(false),
+        callback_invoked_(false) {
+    state_keys_.push_back("1");
+    state_keys_.push_back("2");
+    state_keys_.push_back("3");
+    fake_session_manager_client_.set_server_backed_state_keys(state_keys_);
+  }
+  virtual ~ServerBackedStateKeysBrokerTest() {}
+
+  void StateKeysUpdated() {
+    updated_ = true;
+  }
+
+  void ExpectGood() {
+    EXPECT_FALSE(broker_.pending());
+    EXPECT_TRUE(broker_.available());
+    EXPECT_EQ(state_keys_, broker_.state_keys());
+    EXPECT_EQ(state_keys_.front(), broker_.current_state_key());
+  }
+
+  void HandleStateKeysCallback(const std::vector<std::string>& state_keys) {
+    callback_invoked_ = true;
+    callback_state_keys_ = state_keys;
+  }
+
+ protected:
+  base::MessageLoop loop_;
+  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  chromeos::FakeSessionManagerClient fake_session_manager_client_;
+  ServerBackedStateKeysBroker broker_;
+  std::vector<std::string> state_keys_;
+  bool updated_;
+  std::vector<std::string> callback_state_keys_;
+  bool callback_invoked_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ServerBackedStateKeysBrokerTest);
+};
+
+TEST_F(ServerBackedStateKeysBrokerTest, Load) {
+  EXPECT_TRUE(broker_.pending());
+  EXPECT_FALSE(broker_.available());
+  EXPECT_TRUE(broker_.state_keys().empty());
+  EXPECT_TRUE(broker_.current_state_key().empty());
+
+  ServerBackedStateKeysBroker::Subscription subscription =
+      broker_.RegisterUpdateCallback(
+          base::Bind(&ServerBackedStateKeysBrokerTest::StateKeysUpdated,
+                     base::Unretained(this)));
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(updated_);
+  ExpectGood();
+}
+
+TEST_F(ServerBackedStateKeysBrokerTest, Retry) {
+  fake_session_manager_client_.set_server_backed_state_keys(
+      std::vector<std::string>());
+
+  ServerBackedStateKeysBroker::Subscription subscription =
+      broker_.RegisterUpdateCallback(
+          base::Bind(&ServerBackedStateKeysBrokerTest::StateKeysUpdated,
+                     base::Unretained(this)));
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(updated_);
+
+  EXPECT_FALSE(broker_.pending());
+  EXPECT_FALSE(broker_.available());
+  EXPECT_TRUE(broker_.state_keys().empty());
+  EXPECT_TRUE(broker_.current_state_key().empty());
+
+  fake_session_manager_client_.set_server_backed_state_keys(state_keys_);
+  updated_ = false;
+  ServerBackedStateKeysBroker::Subscription subscription2 =
+      broker_.RegisterUpdateCallback(base::Bind(&base::DoNothing));
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(updated_);
+  ExpectGood();
+}
+
+TEST_F(ServerBackedStateKeysBrokerTest, Refresh) {
+  ServerBackedStateKeysBroker::Subscription subscription =
+      broker_.RegisterUpdateCallback(
+          base::Bind(&ServerBackedStateKeysBrokerTest::StateKeysUpdated,
+                     base::Unretained(this)));
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(updated_);
+  ExpectGood();
+
+  // Update callbacks get fired if the keys change.
+  state_keys_.erase(state_keys_.begin());
+  state_keys_.push_back("4");
+  fake_session_manager_client_.set_server_backed_state_keys(state_keys_);
+  updated_ = false;
+  task_runner_->RunPendingTasks();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(updated_);
+  ExpectGood();
+
+  // No update callback if the keys are unchanged.
+  updated_ = false;
+  task_runner_->RunPendingTasks();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(updated_);
+  ExpectGood();
+}
+
+TEST_F(ServerBackedStateKeysBrokerTest, Request) {
+  broker_.RequestStateKeys(
+      base::Bind(&ServerBackedStateKeysBrokerTest::HandleStateKeysCallback,
+                 base::Unretained(this)));
+  base::RunLoop().RunUntilIdle();
+  ExpectGood();
+  EXPECT_TRUE(callback_invoked_);
+  EXPECT_EQ(state_keys_, callback_state_keys_);
+}
+
+TEST_F(ServerBackedStateKeysBrokerTest, RequestFailure) {
+  fake_session_manager_client_.set_server_backed_state_keys(
+      std::vector<std::string>());
+
+  broker_.RequestStateKeys(
+      base::Bind(&ServerBackedStateKeysBrokerTest::HandleStateKeysCallback,
+                 base::Unretained(this)));
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(callback_invoked_);
+  EXPECT_TRUE(callback_state_keys_.empty());
+}
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc
index 419557e..3a1d445 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc
@@ -319,7 +319,6 @@
   session_manager_client_->StorePolicyForUser(
       username_,
       policy_blob,
-      validator->policy()->new_public_key(),
       base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyStored,
                  weak_factory_.GetWeakPtr()));
 }
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc
index 7595a4e..5d1adce 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc
@@ -145,8 +145,8 @@
     chromeos::SessionManagerClient::StorePolicyCallback store_callback;
     EXPECT_CALL(session_manager_client_,
                 StorePolicyForUser(PolicyBuilder::kFakeUsername,
-                                   policy_.GetBlob(), _, _))
-        .WillOnce(SaveArg<3>(&store_callback));
+                                   policy_.GetBlob(), _))
+        .WillOnce(SaveArg<2>(&store_callback));
     store_->Store(policy_.policy());
     RunUntilIdle();
     Mock::VerifyAndClearExpectations(&session_manager_client_);
@@ -265,8 +265,8 @@
   chromeos::SessionManagerClient::StorePolicyCallback store_callback;
   EXPECT_CALL(session_manager_client_,
               StorePolicyForUser(PolicyBuilder::kFakeUsername,
-                                 policy_.GetBlob(), _, _))
-      .WillOnce(SaveArg<3>(&store_callback));
+                                 policy_.GetBlob(), _))
+      .WillOnce(SaveArg<2>(&store_callback));
   store_->Store(policy_.policy());
   RunUntilIdle();
   Mock::VerifyAndClearExpectations(&session_manager_client_);
@@ -290,7 +290,7 @@
   ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
   EXPECT_CALL(session_manager_client_,
               StorePolicyForUser(PolicyBuilder::kFakeUsername,
-                                 policy_.GetBlob(), _, _))
+                                 policy_.GetBlob(), _))
       .Times(0);
   store_->Store(policy_.policy());
   RunUntilIdle();
@@ -311,7 +311,7 @@
   ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
   EXPECT_CALL(session_manager_client_,
               StorePolicyForUser(PolicyBuilder::kFakeUsername,
-                                 policy_.GetBlob(), _, _))
+                                 policy_.GetBlob(), _))
       .Times(0);
   store_->Store(policy_.policy());
   RunUntilIdle();
@@ -327,7 +327,7 @@
   ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
   EXPECT_CALL(session_manager_client_,
               StorePolicyForUser(PolicyBuilder::kFakeUsername,
-                                 policy_.GetBlob(), _, _))
+                                 policy_.GetBlob(), _))
       .Times(0);
   store_->Store(policy_.policy());
   RunUntilIdle();
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index 63c6d09..dbf1014 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -28,7 +28,6 @@
 #include "chrome/browser/chromeos/login/user.h"
 #include "chrome/browser/chromeos/system/input_device_settings.h"
 #include "chrome/browser/download/download_prefs.h"
-#include "chrome/browser/feedback/tracing_manager.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -37,6 +36,7 @@
 #include "chromeos/ime/ime_keyboard.h"
 #include "chromeos/ime/input_method_manager.h"
 #include "chromeos/system/statistics_provider.h"
+#include "components/feedback/tracing_manager.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "third_party/icu/source/i18n/unicode/timezone.h"
 #include "ui/events/event_constants.h"
diff --git a/chrome/browser/chromeos/preferences_browsertest.cc b/chrome/browser/chromeos/preferences_browsertest.cc
index b8a5267..0e51868 100644
--- a/chrome/browser/chromeos/preferences_browsertest.cc
+++ b/chrome/browser/chromeos/preferences_browsertest.cc
@@ -17,12 +17,12 @@
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
 #include "chrome/browser/chromeos/system/fake_input_device_settings.h"
-#include "chrome/browser/feedback/tracing_manager.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/ime/fake_ime_keyboard.h"
+#include "components/feedback/tracing_manager.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/event_utils.h"
@@ -60,7 +60,7 @@
   }
 
   // Sets set of preferences in given |prefs|. Value of prefernece depends of
-  // |variant| value. For opposite |variant| values all preferences recieve
+  // |variant| value. For opposite |variant| values all preferences receive
   // different values.
   void SetPrefs(PrefService* prefs, bool variant) {
     prefs->SetBoolean(prefs::kTapToClickEnabled, variant);
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.cc b/chrome/browser/chromeos/settings/device_settings_test_helper.cc
index b3ca649..bb1e5b6 100644
--- a/chrome/browser/chromeos/settings/device_settings_test_helper.cc
+++ b/chrome/browser/chromeos/settings/device_settings_test_helper.cc
@@ -116,10 +116,7 @@
 void DeviceSettingsTestHelper::RestartJob(int pid,
                                           const std::string& command_line) {}
 
-void DeviceSettingsTestHelper::StartSession(
-    const std::string& user_email,
-    const StartSessionCallback& callback) {
-}
+void DeviceSettingsTestHelper::StartSession(const std::string& user_email) {}
 
 void DeviceSettingsTestHelper::StopSession() {}
 
@@ -166,7 +163,6 @@
 void DeviceSettingsTestHelper::StorePolicyForUser(
     const std::string& username,
     const std::string& policy_blob,
-    const std::string& policy_key,
     const StorePolicyCallback& callback) {
 }
 
@@ -182,6 +178,9 @@
     const std::string& account_id,
     const std::vector<std::string>& flags) {}
 
+void DeviceSettingsTestHelper::GetServerBackedStateKeys(
+    const StateKeysCallback& callback) {}
+
 DeviceSettingsTestHelper::PolicyState::PolicyState()
     : store_result_(true) {}
 
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.h b/chrome/browser/chromeos/settings/device_settings_test_helper.h
index 3727264..71ae633 100644
--- a/chrome/browser/chromeos/settings/device_settings_test_helper.h
+++ b/chrome/browser/chromeos/settings/device_settings_test_helper.h
@@ -88,8 +88,7 @@
   virtual bool HasObserver(Observer* observer) OVERRIDE;
   virtual void EmitLoginPromptVisible() OVERRIDE;
   virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE;
-  virtual void StartSession(const std::string& user_email,
-                            const StartSessionCallback& callback) OVERRIDE;
+  virtual void StartSession(const std::string& user_email) OVERRIDE;
   virtual void StopSession() OVERRIDE;
   virtual void StartDeviceWipe() OVERRIDE;
   virtual void RequestLockScreen() OVERRIDE;
@@ -111,7 +110,6 @@
                                  const StorePolicyCallback& callback) OVERRIDE;
   virtual void StorePolicyForUser(const std::string& username,
                                   const std::string& policy_blob,
-                                  const std::string& policy_key,
                                   const StorePolicyCallback& callback) OVERRIDE;
   virtual void StoreDeviceLocalAccountPolicy(
       const std::string& account_id,
@@ -120,6 +118,8 @@
   virtual void SetFlagsForUser(
       const std::string& account_id,
       const std::vector<std::string>& flags) OVERRIDE;
+  virtual void GetServerBackedStateKeys(
+      const StateKeysCallback& callback) OVERRIDE;
 
  private:
   struct PolicyState {
diff --git a/chrome/browser/chromeos/system/syslogs_provider.cc b/chrome/browser/chromeos/system/syslogs_provider.cc
index b30212b..33e34d1 100644
--- a/chrome/browser/chromeos/system/syslogs_provider.cc
+++ b/chrome/browser/chromeos/system/syslogs_provider.cc
@@ -18,10 +18,10 @@
 #include "base/strings/string_util.h"
 #include "base/task_runner.h"
 #include "base/threading/sequenced_worker_pool.h"
-#include "chrome/browser/feedback/feedback_util.h"
 #include "chrome/browser/memory_details.h"
 #include "chrome/common/chrome_switches.h"
 #include "chromeos/network/network_event_log.h"
+#include "components/feedback/feedback_util.h"
 #include "content/public/browser/browser_thread.h"
 #include "dbus/dbus_statistics.h"
 
@@ -158,7 +158,7 @@
     base::TrimWhitespaceASCII(key, base::TRIM_ALL, &key);
     if (!key.empty()) {
       std::string value = ReadValue(&data);
-      if (IsStringUTF8(value)) {
+      if (base::IsStringUTF8(value)) {
         base::TrimWhitespaceASCII(value, base::TRIM_ALL, &value);
         if (value.empty())
           (*logs)[key] = kEmptyLogEntry;
diff --git a/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc b/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
index b6fc802..3e5d178 100644
--- a/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
+++ b/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
@@ -251,7 +251,7 @@
 
   void SetBrailleConnected(bool connected) {
     braille_controller_.SetAvailable(connected);
-    braille_controller_.GetObserver()->OnDisplayStateChanged(
+    braille_controller_.GetObserver()->OnBrailleDisplayStateChanged(
         *braille_controller_.GetDisplayState());
   }
 
diff --git a/chrome/browser/chromeos/system_logs/touch_log_source.cc b/chrome/browser/chromeos/system_logs/touch_log_source.cc
index 57ef5f5..f7a077e 100644
--- a/chrome/browser/chromeos/system_logs/touch_log_source.cc
+++ b/chrome/browser/chromeos/system_logs/touch_log_source.cc
@@ -9,7 +9,7 @@
 #include "base/command_line.h"
 #include "base/json/json_string_value_serializer.h"
 #include "base/process/launch.h"
-#include "chrome/browser/feedback/feedback_util.h"
+#include "components/feedback/feedback_util.h"
 #include "content/public/browser/browser_thread.h"
 
 using content::BrowserThread;
diff --git a/chrome/browser/component_updater/background_downloader_win.cc b/chrome/browser/component_updater/background_downloader_win.cc
index af8d0dd..9cfa01f 100644
--- a/chrome/browser/component_updater/background_downloader_win.cc
+++ b/chrome/browser/component_updater/background_downloader_win.cc
@@ -99,7 +99,7 @@
 const base::char16 kJobDescription[] = L"Chrome Component Updater";
 
 // How often the code looks for changes in the BITS job state.
-const int kJobPollingIntervalSec = 10;
+const int kJobPollingIntervalSec = 4;
 
 // How long BITS waits before retrying a job after the job encountered
 // a transient error. If this value is not set, the BITS default is 10 minutes.
@@ -128,8 +128,8 @@
   // BITS errors are defined in bitsmsg.h. Although not documented, it is
   // clear that all errors corresponding to http status code have the high
   // word equal to 0x8019 and the low word equal to the http status code.
-  const int kHttpStatusFirst = 100;    // Continue.
-  const int kHttpStatusLast  = 505;    // Version not supported.
+  const int kHttpStatusFirst = 100;  // Continue.
+  const int kHttpStatusLast = 505;   // Version not supported.
   bool is_valid = HIWORD(error) == 0x8019 &&
                   LOWORD(error) >= kHttpStatusFirst &&
                   LOWORD(error) <= kHttpStatusLast;
@@ -151,7 +151,7 @@
 
   for (ULONG i = 0; i != num_files; ++i) {
     ScopedComPtr<IBackgroundCopyFile> file;
-    if (enum_files->Next(1, file.Receive(), NULL) == S_OK)
+    if (enum_files->Next(1, file.Receive(), NULL) == S_OK && file)
       files->push_back(file);
   }
 
@@ -164,6 +164,9 @@
                              base::string16* local_name,
                              base::string16* remote_name,
                              BG_FILE_PROGRESS* progress) {
+  if (!file)
+    return E_FAIL;
+
   HRESULT hr = S_OK;
 
   if (local_name) {
@@ -197,10 +200,10 @@
 // in the job. If the values are not known or if an error has occurred,
 // a value of -1 is reported.
 HRESULT GetJobByteCount(IBackgroundCopyJob* job,
-                        int64* bytes_downloaded,
-                        int64* bytes_total) {
-  *bytes_downloaded = -1;
-  *bytes_total = -1;
+                        int64* downloaded_bytes,
+                        int64* total_bytes) {
+  *downloaded_bytes = -1;
+  *total_bytes = -1;
 
   if (!job)
     return E_FAIL;
@@ -211,11 +214,11 @@
     return hr;
 
   if (job_progress.BytesTransferred <= kint64max)
-    *bytes_downloaded = job_progress.BytesTransferred;
+    *downloaded_bytes = job_progress.BytesTransferred;
 
   if (job_progress.BytesTotal <= kint64max &&
       job_progress.BytesTotal != BG_SIZE_UNKNOWN)
-    *bytes_total = job_progress.BytesTotal;
+    *total_bytes = job_progress.BytesTotal;
 
   return S_OK;
 }
@@ -248,7 +251,7 @@
 // Finds the component updater jobs matching the given predicate.
 // Returns S_OK if the function has found at least one job, returns S_FALSE if
 // no job was found, and it returns an error otherwise.
-template<class Predicate>
+template <class Predicate>
 HRESULT FindBitsJobIf(Predicate pred,
                       IBackgroundCopyManager* bits_manager,
                       std::vector<ScopedComPtr<IBackgroundCopyJob> >* jobs) {
@@ -300,9 +303,9 @@
 
 // Compares the url of a file in a job and returns true if the remote name
 // of any file in a job matches the argument.
-struct JobFileUrlEqual
-    : public std::binary_function<IBackgroundCopyJob*, const base::string16&,
-                                  bool> {
+struct JobFileUrlEqual : public std::binary_function<IBackgroundCopyJob*,
+                                                     const base::string16&,
+                                                     bool> {
   bool operator()(IBackgroundCopyJob* job,
                   const base::string16& remote_name) const;
 };
@@ -329,8 +332,6 @@
   ScopedComPtr<IBackgroundCopyManager> object;
   HRESULT hr = object.CreateInstance(__uuidof(BackgroundCopyManager));
   if (FAILED(hr)) {
-    VLOG(1) << "Failed to instantiate BITS." << std::hex << hr;
-    // TODO: add UMA pings.
     return hr;
   }
   *bits_manager = object.Detach();
@@ -357,8 +358,8 @@
 
   static base::Time last_sweep;
 
-  const base::TimeDelta time_delta(base::TimeDelta::FromDays(
-      kPurgeStaleJobsIntervalBetweenChecksDays));
+  const base::TimeDelta time_delta(
+      base::TimeDelta::FromDays(kPurgeStaleJobsIntervalBetweenChecksDays));
   const base::Time current_time(base::Time::Now());
   if (last_sweep + time_delta > current_time)
     return S_OK;
@@ -414,11 +415,10 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   BrowserThread::PostTask(
-        BrowserThread::FILE,
-        FROM_HERE,
-        base::Bind(&BackgroundDownloader::BeginDownload,
-                   base::Unretained(this),
-                   url));
+      BrowserThread::FILE,
+      FROM_HERE,
+      base::Bind(
+          &BackgroundDownloader::BeginDownload, base::Unretained(this), url));
 }
 
 // Called once when this class is asked to do a download. Creates or opens
@@ -482,9 +482,9 @@
       return;
 
     case BG_JOB_STATE_QUEUED:
-      // Fall through.
+    // Fall through.
     case BG_JOB_STATE_CONNECTING:
-      // Fall through.
+    // Fall through.
     case BG_JOB_STATE_SUSPENDED:
       OnStateQueued();
       break;
@@ -514,34 +514,13 @@
 
   const base::Time download_end_time(base::Time::Now());
   const base::TimeDelta download_time =
-    download_end_time >= download_start_time_ ?
-    download_end_time - download_start_time_ : base::TimeDelta();
+      download_end_time >= download_start_time_
+          ? download_end_time - download_start_time_
+          : base::TimeDelta();
 
-  int64 bytes_downloaded = -1;
-  int64 bytes_total = -1;
-  GetJobByteCount(job_, &bytes_downloaded, &bytes_total);
-
-  base::FilePath response;
-  if (SUCCEEDED(error)) {
-    DCHECK(job_);
-    std::vector<ScopedComPtr<IBackgroundCopyFile> > files;
-    GetFilesInJob(job_, &files);
-    DCHECK(files.size() == 1);
-    base::string16 local_name;
-    BG_FILE_PROGRESS progress = {0};
-    HRESULT hr = GetJobFileProperties(files[0], &local_name, NULL, &progress);
-    if (SUCCEEDED(hr)) {
-      // Sanity check the post-conditions of a successful download, including
-      // the file and job invariants. The byte counts for a job and its file
-      // must match as a job only contains one file.
-      DCHECK(progress.Completed);
-      DCHECK(bytes_downloaded == static_cast<int64>(progress.BytesTransferred));
-      DCHECK(bytes_total == static_cast<int64>(progress.BytesTotal));
-      response = base::FilePath(local_name);
-    } else {
-      error = hr;
-    }
-  }
+  int64 downloaded_bytes = -1;
+  int64 total_bytes = -1;
+  GetJobByteCount(job_, &downloaded_bytes, &total_bytes);
 
   if (FAILED(error) && job_) {
     job_->Cancel();
@@ -550,10 +529,13 @@
 
   job_ = NULL;
 
+  CleanupStaleJobs(bits_manager_);
+  bits_manager_ = NULL;
+
   // Consider the url handled if it has been successfully downloaded or a
   // 5xx has been received.
-  const bool is_handled = SUCCEEDED(error) ||
-                          IsHttpServerError(GetHttpStatusFromBitsError(error));
+  const bool is_handled =
+      SUCCEEDED(error) || IsHttpServerError(GetHttpStatusFromBitsError(error));
 
   const int error_to_report = SUCCEEDED(error) ? 0 : error;
 
@@ -561,26 +543,22 @@
   download_metrics.url = url();
   download_metrics.downloader = DownloadMetrics::kBits;
   download_metrics.error = error_to_report;
-  download_metrics.bytes_downloaded = bytes_downloaded;
-  download_metrics.bytes_total = bytes_total;
+  download_metrics.downloaded_bytes = downloaded_bytes;
+  download_metrics.total_bytes = total_bytes;
   download_metrics.download_time_ms = download_time.InMilliseconds();
 
-  // Clean up stale jobs before invoking the callback.
-  CleanupStaleJobs(bits_manager_);
-
-  bits_manager_ = NULL;
-
   Result result;
   result.error = error_to_report;
-  result.response = response;
-  BrowserThread::PostTask(
-        BrowserThread::UI,
-        FROM_HERE,
-        base::Bind(&BackgroundDownloader::OnDownloadComplete,
-                   base::Unretained(this),
-                   is_handled,
-                   result,
-                   download_metrics));
+  result.response = response_;
+  result.downloaded_bytes = downloaded_bytes;
+  result.total_bytes = total_bytes;
+  BrowserThread::PostTask(BrowserThread::UI,
+                          FROM_HERE,
+                          base::Bind(&BackgroundDownloader::OnDownloadComplete,
+                                     base::Unretained(this),
+                                     is_handled,
+                                     result,
+                                     download_metrics));
 
   // Once the task is posted to the the UI thread, this object may be deleted
   // by its owner. It is not safe to access members of this object on the
@@ -592,10 +570,7 @@
 // BITS job by removing it from the BITS queue and making the download
 // available to the caller.
 void BackgroundDownloader::OnStateTransferred() {
-  HRESULT hr = job_->Complete();
-  if (SUCCEEDED(hr) || hr == BG_S_UNABLE_TO_DELETE_FILES)
-    hr = S_OK;
-  EndDownload(hr);
+  EndDownload(CompleteJob());
 }
 
 // Called when the job has encountered an error and no further progress can
@@ -632,13 +607,29 @@
 
 void BackgroundDownloader::OnStateQueued() {
   if (IsStuck())
-    EndDownload(E_ABORT);      // Return a generic error for now.
+    EndDownload(E_ABORT);  // Return a generic error for now.
 }
 
 void BackgroundDownloader::OnStateTransferring() {
   // Resets the baseline for detecting a stuck job since the job is transferring
   // data and it is making progress.
   job_stuck_begin_time_ = base::Time::Now();
+
+  int64 downloaded_bytes = -1;
+  int64 total_bytes = -1;
+  HRESULT hr = GetJobByteCount(job_, &downloaded_bytes, &total_bytes);
+  if (FAILED(hr))
+    return;
+
+  Result result;
+  result.downloaded_bytes = downloaded_bytes;
+  result.total_bytes = total_bytes;
+
+  BrowserThread::PostTask(BrowserThread::UI,
+                          FROM_HERE,
+                          base::Bind(&BackgroundDownloader::OnDownloadProgress,
+                                     base::Unretained(this),
+                                     result));
 }
 
 // Called when the download was cancelled. Since the observer should have
@@ -692,10 +683,8 @@
   // display name is initialized later on.
   GUID guid = {0};
   ScopedComPtr<IBackgroundCopyJob> job;
-  hr = bits_manager_->CreateJob(kJobDescription,
-                                BG_JOB_TYPE_DOWNLOAD,
-                                &guid,
-                                job.Receive());
+  hr = bits_manager_->CreateJob(
+      kJobDescription, BG_JOB_TYPE_DOWNLOAD, &guid, job.Receive());
   if (FAILED(hr))
     return hr;
 
@@ -707,14 +696,12 @@
   const base::string16 filename(base::SysUTF8ToWide(url.ExtractFileName()));
 
   base::FilePath tempdir;
-  if (!base::CreateNewTempDirectory(
-      FILE_PATH_LITERAL("chrome_BITS_"),
-      &tempdir))
+  if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_BITS_"),
+                                    &tempdir))
     return E_FAIL;
 
-  HRESULT hr = job_->AddFile(
-      base::SysUTF8ToWide(url.spec()).c_str(),
-      tempdir.Append(filename).AsUTF16Unsafe().c_str());
+  HRESULT hr = job_->AddFile(base::SysUTF8ToWide(url.spec()).c_str(),
+                             tempdir.Append(filename).AsUTF16Unsafe().c_str());
   if (FAILED(hr))
     return hr;
 
@@ -748,5 +735,34 @@
   return job_stuck_begin_time_ + job_stuck_timeout < base::Time::Now();
 }
 
-}  // namespace component_updater
+HRESULT BackgroundDownloader::CompleteJob() {
+  HRESULT hr = job_->Complete();
+  if (FAILED(hr) && hr != BG_S_UNABLE_TO_DELETE_FILES)
+    return hr;
 
+  std::vector<ScopedComPtr<IBackgroundCopyFile> > files;
+  hr = GetFilesInJob(job_, &files);
+  if (FAILED(hr))
+    return hr;
+
+  if (files.empty())
+    return E_UNEXPECTED;
+
+  base::string16 local_name;
+  BG_FILE_PROGRESS progress = {0};
+  hr = GetJobFileProperties(files.front(), &local_name, NULL, &progress);
+  if (FAILED(hr))
+    return hr;
+
+  // Sanity check the post-conditions of a successful download, including
+  // the file and job invariants. The byte counts for a job and its file
+  // must match as a job only contains one file.
+  DCHECK(progress.Completed);
+  DCHECK_EQ(progress.BytesTotal, progress.BytesTransferred);
+
+  response_ = base::FilePath(local_name);
+
+  return S_OK;
+}
+
+}  // namespace component_updater
diff --git a/chrome/browser/component_updater/background_downloader_win.h b/chrome/browser/component_updater/background_downloader_win.h
index c3ca4c4..9bec30f 100644
--- a/chrome/browser/component_updater/background_downloader_win.h
+++ b/chrome/browser/component_updater/background_downloader_win.h
@@ -5,8 +5,6 @@
 #ifndef CHROME_BROWSER_COMPONENT_UPDATER_BACKGROUND_DOWNLOADER_WIN_H_
 #define CHROME_BROWSER_COMPONENT_UPDATER_BACKGROUND_DOWNLOADER_WIN_H_
 
-#include "chrome/browser/component_updater/crx_downloader.h"
-
 #include <windows.h>
 #include <bits.h>
 
@@ -14,6 +12,11 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "base/win/scoped_comptr.h"
+#include "chrome/browser/component_updater/crx_downloader.h"
+
+namespace base {
+class FilePath;
+}
 
 namespace component_updater {
 
@@ -68,6 +71,10 @@
   // has not been making progress toward completion.
   bool IsStuck();
 
+  // Makes the downloaded file available to the caller by renaming the
+  // temporary file to its destination and removing it from the BITS queue.
+  HRESULT CompleteJob();
+
   net::URLRequestContextGetter* context_getter_;
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
@@ -85,12 +92,15 @@
   // Contains the time when the BITS job is last seen making progress.
   base::Time job_stuck_begin_time_;
 
+  // True if EndDownload was called.
   bool is_completed_;
 
+  // Contains the path of the downloaded file if the download was successful.
+  base::FilePath response_;
+
   DISALLOW_COPY_AND_ASSIGN(BackgroundDownloader);
 };
 
 }  // namespace component_updater
 
 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_BACKGROUND_DOWNLOADER_WIN_H_
-
diff --git a/chrome/browser/component_updater/cld_component_installer.cc b/chrome/browser/component_updater/cld_component_installer.cc
index 6e493ac..190925a 100644
--- a/chrome/browser/component_updater/cld_component_installer.cc
+++ b/chrome/browser/component_updater/cld_component_installer.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/component_updater/cld_component_installer.h"
 
+#include <string>
+#include <vector>
+
 #include "base/bind.h"
 #include "base/file_util.h"
 #include "base/files/file_path.h"
@@ -37,10 +40,10 @@
 // The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
 // The extension id is: dpedmmgabcgnikllifiidmijgoiihfgf
 const uint8 kPublicKeySHA256[32] = {
-  0x3f, 0x43, 0xcc, 0x60, 0x12, 0x6d, 0x8a, 0xbb,
-  0x85, 0x88, 0x3c, 0x89, 0x6e, 0x88, 0x75, 0x65,
-  0xb9, 0x46, 0x09, 0xe8, 0xca, 0x92, 0xdd, 0x82,
-  0x4e, 0x6d, 0x0e, 0xe6, 0x79, 0x8a, 0x87, 0xf5
+    0x3f, 0x43, 0xcc, 0x60, 0x12, 0x6d, 0x8a, 0xbb,
+    0x85, 0x88, 0x3c, 0x89, 0x6e, 0x88, 0x75, 0x65,
+    0xb9, 0x46, 0x09, 0xe8, 0xca, 0x92, 0xdd, 0x82,
+    0x4e, 0x6d, 0x0e, 0xe6, 0x79, 0x8a, 0x87, 0xf5
 };
 
 const char kCldManifestName[] = "CLD2 Data";
@@ -80,7 +83,7 @@
 bool CldComponentInstallerTraits::OnCustomInstall(
     const base::DictionaryValue& manifest,
     const base::FilePath& install_dir) {
-  return true; // Nothing custom here.
+  return true;  // Nothing custom here.
 }
 
 base::FilePath CldComponentInstallerTraits::GetInstalledPath(
@@ -97,8 +100,8 @@
     const base::Version& version,
     const base::FilePath& path,
     scoped_ptr<base::DictionaryValue> manifest) {
-  VLOG(1) << "Component ready, version " << version.GetString()
-          << " in " << path.value();
+  VLOG(1) << "Component ready, version " << version.GetString() << " in "
+          << path.value();
   SetLatestCldDataFile(GetInstalledPath(path));
 }
 
@@ -133,8 +136,8 @@
   scoped_ptr<ComponentInstallerTraits> traits(
       new CldComponentInstallerTraits());
   // |cus| will take ownership of |installer| during installer->Register(cus).
-  DefaultComponentInstaller* installer
-      = new DefaultComponentInstaller(traits.Pass());
+  DefaultComponentInstaller* installer =
+      new DefaultComponentInstaller(traits.Pass());
   installer->Register(cus);
 }
 
@@ -149,7 +152,8 @@
 bool GetLatestCldDataFile(base::FilePath* path) {
   base::AutoLock lock(cld_file_lock.Get());
   const base::FilePath cached = cld_file.Get();
-  if (cached.empty()) return false;
+  if (cached.empty())
+    return false;
   *path = cached;
   return true;
 }
diff --git a/chrome/browser/component_updater/component_patcher.cc b/chrome/browser/component_updater/component_patcher.cc
index 7806430..dbf04a1 100644
--- a/chrome/browser/component_updater/component_patcher.cc
+++ b/chrome/browser/component_updater/component_patcher.cc
@@ -32,8 +32,9 @@
   JSONFileValueSerializer serializer(commands);
   scoped_ptr<base::Value> root(serializer.Deserialize(NULL, NULL));
 
-  return (root.get() && root->IsType(base::Value::TYPE_LIST)) ?
-      static_cast<base::ListValue*>(root.release()) : NULL;
+  return (root.get() && root->IsType(base::Value::TYPE_LIST))
+             ? static_cast<base::ListValue*>(root.release())
+             : NULL;
 }
 
 }  // namespace
@@ -87,15 +88,14 @@
     DonePatching(ComponentUnpacker::kDeltaUnsupportedCommand, 0);
     return;
   }
-  current_operation_->Run(
-      command_args,
-      input_dir_,
-      unpack_dir_,
-      installer_,
-      in_process_,
-      base::Bind(&ComponentPatcher::DonePatchingFile,
-                 scoped_refptr<ComponentPatcher>(this)),
-      task_runner_);
+  current_operation_->Run(command_args,
+                          input_dir_,
+                          unpack_dir_,
+                          installer_,
+                          in_process_,
+                          base::Bind(&ComponentPatcher::DonePatchingFile,
+                                     scoped_refptr<ComponentPatcher>(this)),
+                          task_runner_);
 }
 
 void ComponentPatcher::DonePatchingFile(ComponentUnpacker::Error error,
@@ -111,9 +111,8 @@
 void ComponentPatcher::DonePatching(ComponentUnpacker::Error error,
                                     int extended_error) {
   current_operation_ = NULL;
-  task_runner_->PostTask(FROM_HERE, base::Bind(callback_,
-                                               error,
-                                               extended_error));
+  task_runner_->PostTask(FROM_HERE,
+                         base::Bind(callback_, error, extended_error));
   callback_.Reset();
 }
 
diff --git a/chrome/browser/component_updater/component_patcher.h b/chrome/browser/component_updater/component_patcher.h
index 9269967..f96e156 100644
--- a/chrome/browser/component_updater/component_patcher.h
+++ b/chrome/browser/component_updater/component_patcher.h
@@ -24,7 +24,6 @@
 // fingerprint of the installed files, to later identify the existing files to
 // the server so that a proper differential update can be provided next cycle.
 
-
 #ifndef CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_PATCHER_H_
 #define CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_PATCHER_H_
 
diff --git a/chrome/browser/component_updater/component_patcher_operation.cc b/chrome/browser/component_updater/component_patcher_operation.cc
index 34d06bd..62f7d7b 100644
--- a/chrome/browser/component_updater/component_patcher_operation.cc
+++ b/chrome/browser/component_updater/component_patcher_operation.cc
@@ -149,18 +149,19 @@
   return CreateDeltaUpdateOp(operation);
 }
 
-DeltaUpdateOp::DeltaUpdateOp() : in_process_(false) {}
+DeltaUpdateOp::DeltaUpdateOp() : in_process_(false) {
+}
 
-DeltaUpdateOp::~DeltaUpdateOp() {}
+DeltaUpdateOp::~DeltaUpdateOp() {
+}
 
-void DeltaUpdateOp::Run(
-    const base::DictionaryValue* command_args,
-    const base::FilePath& input_dir,
-    const base::FilePath& unpack_dir,
-    ComponentInstaller* installer,
-    bool in_process,
-    const ComponentUnpacker::Callback& callback,
-    scoped_refptr<base::SequencedTaskRunner> task_runner) {
+void DeltaUpdateOp::Run(const base::DictionaryValue* command_args,
+                        const base::FilePath& input_dir,
+                        const base::FilePath& unpack_dir,
+                        ComponentInstaller* installer,
+                        bool in_process,
+                        const ComponentUnpacker::Callback& callback,
+                        scoped_refptr<base::SequencedTaskRunner> task_runner) {
   callback_ = callback;
   in_process_ = in_process;
   task_runner_ = task_runner;
@@ -171,10 +172,10 @@
     return;
   }
 
-  output_abs_path_ = unpack_dir.Append(
-      base::FilePath::FromUTF8Unsafe(output_rel_path));
-  ComponentUnpacker::Error parse_result = DoParseArguments(
-      command_args, input_dir, installer);
+  output_abs_path_ =
+      unpack_dir.Append(base::FilePath::FromUTF8Unsafe(output_rel_path));
+  ComponentUnpacker::Error parse_result =
+      DoParseArguments(command_args, input_dir, installer);
   if (parse_result != ComponentUnpacker::kNone) {
     DoneRunning(parse_result, 0);
     return;
@@ -231,9 +232,11 @@
   return task_runner_;
 }
 
-DeltaUpdateOpCopy::DeltaUpdateOpCopy() {}
+DeltaUpdateOpCopy::DeltaUpdateOpCopy() {
+}
 
-DeltaUpdateOpCopy::~DeltaUpdateOpCopy() {}
+DeltaUpdateOpCopy::~DeltaUpdateOpCopy() {
+}
 
 ComponentUnpacker::Error DeltaUpdateOpCopy::DoParseArguments(
     const base::DictionaryValue* command_args,
@@ -256,9 +259,11 @@
     callback.Run(ComponentUnpacker::kNone, 0);
 }
 
-DeltaUpdateOpCreate::DeltaUpdateOpCreate() {}
+DeltaUpdateOpCreate::DeltaUpdateOpCreate() {
+}
 
-DeltaUpdateOpCreate::~DeltaUpdateOpCreate() {}
+DeltaUpdateOpCreate::~DeltaUpdateOpCreate() {
+}
 
 ComponentUnpacker::Error DeltaUpdateOpCreate::DoParseArguments(
     const base::DictionaryValue* command_args,
@@ -268,8 +273,8 @@
   if (!command_args->GetString(kPatch, &patch_rel_path))
     return ComponentUnpacker::kDeltaBadCommands;
 
-  patch_abs_path_ = input_dir.Append(
-      base::FilePath::FromUTF8Unsafe(patch_rel_path));
+  patch_abs_path_ =
+      input_dir.Append(base::FilePath::FromUTF8Unsafe(patch_rel_path));
 
   return ComponentUnpacker::kNone;
 }
@@ -363,8 +368,8 @@
   if (!installer->GetInstalledFile(input_rel_path, &input_abs_path_))
     return ComponentUnpacker::kDeltaMissingExistingFile;
 
-  patch_abs_path_ = input_dir.Append(
-      base::FilePath::FromUTF8Unsafe(patch_rel_path));
+  patch_abs_path_ =
+      input_dir.Append(base::FilePath::FromUTF8Unsafe(patch_rel_path));
 
   return ComponentUnpacker::kNone;
 }
diff --git a/chrome/browser/component_updater/component_patcher_operation.h b/chrome/browser/component_updater/component_patcher_operation.h
index 6475c33..3a1b6cf 100644
--- a/chrome/browser/component_updater/component_patcher_operation.h
+++ b/chrome/browser/component_updater/component_patcher_operation.h
@@ -51,7 +51,6 @@
  private:
   friend class base::RefCountedThreadSafe<DeltaUpdateOp>;
 
-
   ComponentUnpacker::Error CheckHash();
 
   // Subclasses must override DoParseArguments to parse operation-specific
diff --git a/chrome/browser/component_updater/component_unpacker.cc b/chrome/browser/component_updater/component_unpacker.cc
index 48c584c..ed7bf1f 100644
--- a/chrome/browser/component_updater/component_unpacker.cc
+++ b/chrome/browser/component_updater/component_unpacker.cc
@@ -61,8 +61,10 @@
     crypto::SignatureVerifier verifier;
     if (!verifier.VerifyInit(extension_misc::kSignatureAlgorithm,
                              sizeof(extension_misc::kSignatureAlgorithm),
-                             &signature[0], signature.size(),
-                             &key[0], key.size())) {
+                             &signature[0],
+                             signature.size(),
+                             &key[0],
+                             key.size())) {
       // Signature verification initialization failed. This is most likely
       // caused by a public key in the wrong format (should encode algorithm).
       return;
@@ -129,7 +131,7 @@
   if (!root->IsType(base::Value::TYPE_DICTIONARY))
     return scoped_ptr<base::DictionaryValue>();
   return scoped_ptr<base::DictionaryValue>(
-      static_cast<base::DictionaryValue*>(root.release())).Pass();
+             static_cast<base::DictionaryValue*>(root.release())).Pass();
 }
 
 bool ComponentUnpacker::UnpackInternal() {
@@ -198,7 +200,6 @@
   return true;
 }
 
-
 bool ComponentUnpacker::BeginPatching() {
   if (is_delta_) {  // Package is a diff package.
     // Use a different temp directory for the patch output files.
diff --git a/chrome/browser/component_updater/component_updater_configurator.cc b/chrome/browser/component_updater/component_updater_configurator.cc
index 4770b7a..269dea1 100644
--- a/chrome/browser/component_updater/component_updater_configurator.cc
+++ b/chrome/browser/component_updater/component_updater_configurator.cc
@@ -40,7 +40,7 @@
 const char kSwitchUrlSource[] = "url-source";
 
 #define COMPONENT_UPDATER_SERVICE_ENDPOINT \
-    "//clients2.google.com/service/update2"
+  "//clients2.google.com/service/update2"
 
 // The default url for the v3 protocol service endpoint. Can be
 // overridden with --component-updater=url-source=someurl.
@@ -73,8 +73,8 @@
   if (vec.empty())
     return std::string();
   for (std::vector<std::string>::const_iterator it = vec.begin();
-      it != vec.end();
-      ++it) {
+       it != vec.end();
+       ++it) {
     const std::size_t found = it->find("=");
     if (found != std::string::npos) {
       if (it->substr(0, found) == test) {
@@ -119,17 +119,19 @@
   bool background_downloads_enabled_;
 };
 
-ChromeConfigurator::ChromeConfigurator(const CommandLine* cmdline,
+ChromeConfigurator::ChromeConfigurator(
+    const CommandLine* cmdline,
     net::URLRequestContextGetter* url_request_getter)
-      : url_request_getter_(url_request_getter),
-        fast_update_(false),
-        pings_enabled_(false),
-        deltas_enabled_(false),
-        background_downloads_enabled_(false) {
+    : url_request_getter_(url_request_getter),
+      fast_update_(false),
+      pings_enabled_(false),
+      deltas_enabled_(false),
+      background_downloads_enabled_(false) {
   // Parse comma-delimited debug flags.
   std::vector<std::string> switch_values;
   Tokenize(cmdline->GetSwitchValueASCII(switches::kComponentUpdater),
-      ",", &switch_values);
+           ",",
+           &switch_values);
   fast_update_ = HasSwitchValue(switch_values, kSwitchFastUpdate);
   pings_enabled_ = !HasSwitchValue(switch_values, kSwitchDisablePings);
   deltas_enabled_ = !HasSwitchValue(switch_values, kSwitchDisableDeltaUpdates);
@@ -207,7 +209,8 @@
 }
 
 ComponentUpdateService::Configurator* MakeChromeComponentUpdaterConfigurator(
-    const CommandLine* cmdline, net::URLRequestContextGetter* context_getter) {
+    const CommandLine* cmdline,
+    net::URLRequestContextGetter* context_getter) {
   return new ChromeConfigurator(cmdline, context_getter);
 }
 
diff --git a/chrome/browser/component_updater/component_updater_configurator.h b/chrome/browser/component_updater/component_updater_configurator.h
index da8a046..c9c7b14 100644
--- a/chrome/browser/component_updater/component_updater_configurator.h
+++ b/chrome/browser/component_updater/component_updater_configurator.h
@@ -24,4 +24,3 @@
 }  // namespace component_updater
 
 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_UPDATER_CONFIGURATOR_H_
-
diff --git a/chrome/browser/component_updater/component_updater_ping_manager.cc b/chrome/browser/component_updater/component_updater_ping_manager.cc
index fb5cf30..cf284ac 100644
--- a/chrome/browser/component_updater/component_updater_ping_manager.cc
+++ b/chrome/browser/component_updater/component_updater_ping_manager.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/component_updater/component_updater_ping_manager.h"
 
+#include <string>
+
 #include "base/compiler_specific.h"
 #include "base/guid.h"
 #include "base/logging.h"
@@ -39,6 +41,7 @@
   void SendPing(const GURL& ping_url,
                 net::URLRequestContextGetter* url_request_context_getter,
                 const CrxUpdateItem* item);
+
  private:
   virtual ~PingSender();
 
@@ -55,9 +58,11 @@
   DISALLOW_COPY_AND_ASSIGN(PingSender);
 };
 
-PingSender::PingSender() {}
+PingSender::PingSender() {
+}
 
-PingSender::~PingSender() {}
+PingSender::~PingSender() {
+}
 
 void PingSender::OnURLFetchComplete(const net::URLFetcher* source) {
   delete this;
@@ -72,10 +77,8 @@
   if (!ping_url.is_valid())
     return;
 
-  url_fetcher_.reset(SendProtocolRequest(ping_url,
-                                         BuildPing(item),
-                                         this,
-                                         url_request_context_getter));
+  url_fetcher_.reset(SendProtocolRequest(
+      ping_url, BuildPing(item), this, url_request_context_getter));
 }
 
 // Builds a ping message for the specified update item.
@@ -87,11 +90,11 @@
       "</app>";
   const std::string app_element(base::StringPrintf(
       app_element_format,
-      item->id.c_str(),                                     // "appid"
-      item->previous_version.GetString().c_str(),           // "version"
-      item->next_version.GetString().c_str(),               // "nextversion"
-      BuildUpdateCompleteEventElement(item).c_str(),        // update event
-      BuildDownloadCompleteEventElements(item).c_str()));   // download events
+      item->id.c_str(),                                    // "appid"
+      item->previous_version.GetString().c_str(),          // "version"
+      item->next_version.GetString().c_str(),              // "nextversion"
+      BuildUpdateCompleteEventElement(item).c_str(),       // update event
+      BuildDownloadCompleteEventElements(item).c_str()));  // download events
 
   return BuildProtocolRequest(app_element, "");
 }
@@ -107,23 +110,28 @@
     std::string event("<event eventtype=\"14\"");
     StringAppendF(&event, " eventresult=\"%d\"", metrics.error == 0);
     StringAppendF(&event,
-                  " downloader=\"%s\"", DownloaderToString(metrics.downloader));
-    if (metrics.error)
+                  " downloader=\"%s\"",
+                  DownloaderToString(metrics.downloader));
+    if (metrics.error) {
       StringAppendF(&event, " errorcode=\"%d\"", metrics.error);
+    }
     StringAppendF(&event, " url=\"%s\"", metrics.url.spec().c_str());
 
     // -1 means that the  byte counts are not known.
-    if (metrics.bytes_downloaded != -1) {
-      StringAppendF(&event, " downloaded=\"%s\"",
-                    base::Int64ToString(metrics.bytes_downloaded).c_str());
+    if (metrics.downloaded_bytes != -1) {
+      StringAppendF(&event,
+                    " downloaded=\"%s\"",
+                    base::Int64ToString(metrics.downloaded_bytes).c_str());
     }
-    if (metrics.bytes_total != -1) {
-      StringAppendF(&event, " total=\"%s\"",
-                    base::Int64ToString(metrics.bytes_total).c_str());
+    if (metrics.total_bytes != -1) {
+      StringAppendF(&event,
+                    " total=\"%s\"",
+                    base::Int64ToString(metrics.total_bytes).c_str());
     }
 
     if (metrics.download_time_ms) {
-      StringAppendF(&event, " download_time_ms=\"%s\"",
+      StringAppendF(&event,
+                    " download_time_ms=\"%s\"",
                     base::Uint64ToString(metrics.download_time_ms).c_str());
     }
     StringAppendF(&event, "/>");
@@ -152,16 +160,15 @@
     StringAppendF(&ping_event, " extracode1=\"%d\"", item->extra_code1);
   if (HasDiffUpdate(item))
     StringAppendF(&ping_event, " diffresult=\"%d\"", !item->diff_update_failed);
-  if (item->diff_error_category)
-    StringAppendF(&ping_event,
-                  " differrorcat=\"%d\"",
-                  item->diff_error_category);
+  if (item->diff_error_category) {
+    StringAppendF(
+        &ping_event, " differrorcat=\"%d\"", item->diff_error_category);
+  }
   if (item->diff_error_code)
     StringAppendF(&ping_event, " differrorcode=\"%d\"", item->diff_error_code);
   if (item->diff_extra_code1) {
-    StringAppendF(&ping_event,
-                  " diffextracode1=\"%d\"",
-                  item->diff_extra_code1);
+    StringAppendF(
+        &ping_event, " diffextracode1=\"%d\"", item->diff_extra_code1);
   }
   if (!item->previous_fp.empty())
     StringAppendF(&ping_event, " previousfp=\"%s\"", item->previous_fp.c_str());
@@ -189,4 +196,3 @@
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/component_updater_ping_manager.h b/chrome/browser/component_updater/component_updater_ping_manager.h
index f998b7b..1bb0a8b 100644
--- a/chrome/browser/component_updater/component_updater_ping_manager.h
+++ b/chrome/browser/component_updater/component_updater_ping_manager.h
@@ -25,6 +25,7 @@
   ~PingManager();
 
   void OnUpdateComplete(const CrxUpdateItem* item);
+
  private:
   const GURL ping_url_;
 
@@ -37,4 +38,3 @@
 }  // namespace component_updater
 
 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_UPDATER_PING_MANAGER_H_
-
diff --git a/chrome/browser/component_updater/component_updater_service.cc b/chrome/browser/component_updater/component_updater_service.cc
index 5d6e71d..60740e6 100644
--- a/chrome/browser/component_updater/component_updater_service.cc
+++ b/chrome/browser/component_updater/component_updater_service.cc
@@ -54,8 +54,7 @@
 // and the configuration allows it.
 bool CanTryDiffUpdate(const CrxUpdateItem* update_item,
                       const ComponentUpdateService::Configurator& config) {
-  return HasDiffUpdate(update_item) &&
-         !update_item->diff_update_failed &&
+  return HasDiffUpdate(update_item) && !update_item->diff_update_failed &&
          config.DeltasEnabled();
 }
 
@@ -83,8 +82,7 @@
 }
 
 CrxComponent::CrxComponent()
-    : installer(NULL),
-      allow_background_download(true) {
+    : installer(NULL), allow_background_download(true) {
 }
 
 CrxComponent::~CrxComponent() {
@@ -103,9 +101,8 @@
 // unless the CrxUpdateService calls Unblock().
 // The lifetime is controlled by Chrome's resource loader so the component
 // updater cannot touch objects from this class except via weak pointers.
-class CUResourceThrottle
-    : public content::ResourceThrottle,
-      public base::SupportsWeakPtr<CUResourceThrottle> {
+class CUResourceThrottle : public content::ResourceThrottle,
+                           public base::SupportsWeakPtr<CUResourceThrottle> {
  public:
   explicit CUResourceThrottle(const net::URLRequest* request);
   virtual ~CUResourceThrottle();
@@ -121,20 +118,15 @@
   typedef std::vector<base::WeakPtr<CUResourceThrottle> > WeakPtrVector;
 
  private:
-  enum State {
-    NEW,
-    BLOCKED,
-    UNBLOCKED
-  };
+  enum State { NEW, BLOCKED, UNBLOCKED };
 
   State state_;
 };
 
 void UnblockResourceThrottle(base::WeakPtr<CUResourceThrottle> rt) {
-  BrowserThread::PostTask(
-      BrowserThread::IO,
-      FROM_HERE,
-      base::Bind(&CUResourceThrottle::Unblock, rt));
+  BrowserThread::PostTask(BrowserThread::IO,
+                          FROM_HERE,
+                          base::Bind(&CUResourceThrottle::Unblock, rt));
 }
 
 void UnblockandReapAllThrottles(CUResourceThrottle::WeakPtrVector* throttles) {
@@ -172,16 +164,17 @@
   virtual void GetComponents(
       std::vector<CrxComponentInfo>* components) OVERRIDE;
   virtual content::ResourceThrottle* GetOnDemandResourceThrottle(
-      net::URLRequest* request, const std::string& crx_id) OVERRIDE;
+      net::URLRequest* request,
+      const std::string& crx_id) OVERRIDE;
 
-   // Context for a crx download url request.
-   struct CRXContext {
-     ComponentInstaller* installer;
-     std::vector<uint8> pk_hash;
-     std::string id;
-     std::string fingerprint;
-     CRXContext() : installer(NULL) {}
-   };
+  // Context for a crx download url request.
+  struct CRXContext {
+    ComponentInstaller* installer;
+    std::vector<uint8> pk_hash;
+    std::string id;
+    std::string fingerprint;
+    CRXContext() : installer(NULL) {}
+  };
 
  private:
   enum ErrorCategory {
@@ -203,9 +196,11 @@
   void OnUpdateCheckSucceeded(const UpdateResponse::Results& results);
   void OnUpdateCheckFailed(int error, const std::string& error_message);
 
-  void DownloadComplete(
-      scoped_ptr<CRXContext> crx_context,
-      const CrxDownloader::Result& download_result);
+  void DownloadProgress(const std::string& component_id,
+                        const CrxDownloader::Result& download_result);
+
+  void DownloadComplete(scoped_ptr<CRXContext> crx_context,
+                        const CrxDownloader::Result& download_result);
 
   Status OnDemandUpdateInternal(CrxUpdateItem* item);
 
@@ -238,8 +233,7 @@
 
   void ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::Status to);
 
-  size_t ChangeItemStatus(CrxUpdateItem::Status from,
-                          CrxUpdateItem::Status to);
+  size_t ChangeItemStatus(CrxUpdateItem::Status from, CrxUpdateItem::Status to);
 
   CrxUpdateItem* FindUpdateItemById(const std::string& id);
 
@@ -281,12 +275,13 @@
 
 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config)
     : config_(config),
-      ping_manager_(new PingManager(config->PingUrl(),
-                                    config->RequestContext())),
-      blocking_task_runner_(BrowserThread::GetBlockingPool()->
-          GetSequencedTaskRunnerWithShutdownBehavior(
-              BrowserThread::GetBlockingPool()->GetSequenceToken(),
-              base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
+      ping_manager_(
+          new PingManager(config->PingUrl(), config->RequestContext())),
+      blocking_task_runner_(
+          BrowserThread::GetBlockingPool()->
+              GetSequencedTaskRunnerWithShutdownBehavior(
+                  BrowserThread::GetBlockingPool()->GetSequenceToken(),
+                  base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
       chrome_version_(chrome::VersionInfo().Version()),
       running_(false) {
 }
@@ -322,8 +317,10 @@
 
   VLOG(1) << "First update attempt will take place in "
           << config_->InitialDelay() << " seconds";
-  timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->InitialDelay()),
-               this, &CrxUpdateService::ProcessPendingItems);
+  timer_.Start(FROM_HERE,
+               base::TimeDelta::FromSeconds(config_->InitialDelay()),
+               this,
+               &CrxUpdateService::ProcessPendingItems);
   return kOk;
 }
 
@@ -339,9 +336,7 @@
 bool CrxUpdateService::HasOnDemandItems() const {
   class Helper {
    public:
-    static bool IsOnDemand(CrxUpdateItem* item) {
-      return item->on_demand;
-    }
+    static bool IsOnDemand(CrxUpdateItem* item) { return item->on_demand; }
   };
   return std::find_if(work_items_.begin(),
                       work_items_.end(),
@@ -394,17 +389,18 @@
   }
 
   VLOG(1) << "Scheduling next run to occur in " << delay_seconds << " seconds";
-  timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay_seconds),
-               this, &CrxUpdateService::ProcessPendingItems);
+  timer_.Start(FROM_HERE,
+               base::TimeDelta::FromSeconds(delay_seconds),
+               this,
+               &CrxUpdateService::ProcessPendingItems);
 }
 
 // Given a extension-like component id, find the associated component.
 CrxUpdateItem* CrxUpdateService::FindUpdateItemById(const std::string& id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   CrxUpdateItem::FindById finder(id);
-  UpdateItems::iterator it = std::find_if(work_items_.begin(),
-                                          work_items_.end(),
-                                          finder);
+  UpdateItems::iterator it =
+      std::find_if(work_items_.begin(), work_items_.end(), finder);
   return it != work_items_.end() ? *it : NULL;
 }
 
@@ -415,8 +411,7 @@
 void CrxUpdateService::ChangeItemState(CrxUpdateItem* item,
                                        CrxUpdateItem::Status to) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  if (to == CrxUpdateItem::kNoUpdate ||
-      to == CrxUpdateItem::kUpdated ||
+  if (to == CrxUpdateItem::kNoUpdate || to == CrxUpdateItem::kUpdated ||
       to == CrxUpdateItem::kUpToDate) {
     item->on_demand = false;
   }
@@ -448,8 +443,7 @@
   }
 
   // Free possible pending network requests.
-  if ((to == CrxUpdateItem::kUpdated) ||
-      (to == CrxUpdateItem::kUpToDate) ||
+  if ((to == CrxUpdateItem::kUpdated) || (to == CrxUpdateItem::kUpToDate) ||
       (to == CrxUpdateItem::kNoUpdate)) {
     UnblockandReapAllThrottles(&item->throttles);
   }
@@ -462,7 +456,8 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   size_t count = 0;
   for (UpdateItems::iterator it = work_items_.begin();
-       it != work_items_.end(); ++it) {
+       it != work_items_.end();
+       ++it) {
     CrxUpdateItem* item = *it;
     if (item->status == from) {
       ChangeItemState(item, to);
@@ -477,8 +472,7 @@
 ComponentUpdateService::Status CrxUpdateService::RegisterComponent(
     const CrxComponent& component) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  if (component.pk_hash.empty() ||
-      !component.version.IsValid() ||
+  if (component.pk_hash.empty() || !component.version.IsValid() ||
       !component.installer)
     return kError;
 
@@ -547,8 +541,10 @@
   // to get the ball rolling.
   if (timer_.IsRunning()) {
     timer_.Stop();
-    timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->StepDelay()),
-                 this, &CrxUpdateService::ProcessPendingItems);
+    timer_.Start(FROM_HERE,
+                 base::TimeDelta::FromSeconds(config_->StepDelay()),
+                 this,
+                 &CrxUpdateService::ProcessPendingItems);
   }
 
   return kOk;
@@ -558,7 +554,8 @@
     std::vector<CrxComponentInfo>* components) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   for (UpdateItems::const_iterator it = work_items_.begin();
-       it != work_items_.end(); ++it) {
+       it != work_items_.end();
+       ++it) {
     const CrxUpdateItem* item = *it;
     CrxComponentInfo info;
     info.id = GetCrxComponentID(item->component);
@@ -634,8 +631,7 @@
 
     VLOG(1) << "Scheduling update check for component id=" << item->id
             << ", time_since_last_checked="
-            << time_since_last_checked.InSeconds()
-            << " seconds";
+            << time_since_last_checked.InSeconds() << " seconds";
 
     ChangeItemState(item, CrxUpdateItem::kChecking);
 
@@ -661,11 +657,11 @@
   if (items_to_check.empty())
     return false;
 
-  update_checker_ = UpdateChecker::Create(
-      config_->UpdateUrl(),
-      config_->RequestContext(),
-      base::Bind(&CrxUpdateService::UpdateCheckComplete,
-                 base::Unretained(this))).Pass();
+  update_checker_ =
+      UpdateChecker::Create(config_->UpdateUrl(),
+                            config_->RequestContext(),
+                            base::Bind(&CrxUpdateService::UpdateCheckComplete,
+                                       base::Unretained(this))).Pass();
   return update_checker_->CheckForUpdates(items_to_check,
                                           config_->ExtraRequestParams());
 }
@@ -690,13 +686,17 @@
   }
 
   // On demand component updates are always downloaded in foreground.
-  const bool is_background_download =
-      !workitem->on_demand && allow_background_download &&
-      config_->UseBackgroundDownloader();
+  const bool is_background_download = !workitem->on_demand &&
+                                      allow_background_download &&
+                                      config_->UseBackgroundDownloader();
 
   crx_downloader_.reset(CrxDownloader::Create(is_background_download,
                                               config_->RequestContext(),
                                               blocking_task_runner_));
+  crx_downloader_->set_progress_callback(
+      base::Bind(&CrxUpdateService::DownloadProgress,
+                 base::Unretained(this),
+                 crx_context->id));
   crx_downloader_->StartDownload(*urls,
                                  base::Bind(&CrxUpdateService::DownloadComplete,
                                             base::Unretained(this),
@@ -779,12 +779,12 @@
     for (size_t i = 0; i != it->crx_urls.size(); ++i) {
       const GURL url(it->crx_urls[i].Resolve(package.name));
       if (url.is_valid())
-         crx->crx_urls.push_back(url);
+        crx->crx_urls.push_back(url);
     }
     for (size_t i = 0; i != it->crx_diffurls.size(); ++i) {
       const GURL url(it->crx_diffurls[i].Resolve(package.namediff));
       if (url.is_valid())
-         crx->crx_diffurls.push_back(url);
+        crx->crx_diffurls.push_back(url);
     }
 
     ChangeItemState(crx, CrxUpdateItem::kCanUpdate);
@@ -800,18 +800,27 @@
   ScheduleNextRun(num_updates_pending > 0 ? kStepDelayShort : kStepDelayLong);
 }
 
-// TODO: record UMA stats.
 void CrxUpdateService::OnUpdateCheckFailed(int error,
                                            const std::string& error_message) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(error);
-  size_t count = ChangeItemStatus(CrxUpdateItem::kChecking,
-                                  CrxUpdateItem::kNoUpdate);
+  size_t count =
+      ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kNoUpdate);
   DCHECK_GT(count, 0ul);
   VLOG(1) << "Update check failed.";
   ScheduleNextRun(kStepDelayLong);
 }
 
+// Called when progress is being made downloading a CRX. The progress may
+// not monotonically increase due to how the CRX downloader switches between
+// different downloaders and fallback urls.
+void CrxUpdateService::DownloadProgress(
+    const std::string& component_id,
+    const CrxDownloader::Result& download_result) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  NotifyObservers(Observer::COMPONENT_UPDATE_DOWNLOADING, component_id);
+}
+
 // Called when the CRX package has been downloaded to a temporary location.
 // Here we fire the notifications and schedule the component-specific installer
 // to be called in the file thread.
@@ -827,6 +836,8 @@
   AppendDownloadMetrics(crx_downloader_->download_metrics(),
                         &crx->download_metrics);
 
+  crx_downloader_.reset();
+
   if (download_result.error) {
     if (crx->status == CrxUpdateItem::kDownloadingDiff) {
       crx->diff_error_category = kNetworkError;
@@ -835,17 +846,15 @@
       size_t count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff,
                                       CrxUpdateItem::kCanUpdate);
       DCHECK_EQ(count, 1ul);
-      crx_downloader_.reset();
 
       ScheduleNextRun(kStepDelayShort);
       return;
     }
     crx->error_category = kNetworkError;
     crx->error_code = download_result.error;
-    size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading,
-                                    CrxUpdateItem::kNoUpdate);
+    size_t count =
+        ChangeItemStatus(CrxUpdateItem::kDownloading, CrxUpdateItem::kNoUpdate);
     DCHECK_EQ(count, 1ul);
-    crx_downloader_.reset();
 
     // At this point, since both the differential and the full downloads failed,
     // the update for this component has finished with an error.
@@ -863,7 +872,6 @@
                                CrxUpdateItem::kUpdating);
     }
     DCHECK_EQ(count, 1ul);
-    crx_downloader_.reset();
 
     // Why unretained? See comment at top of file.
     blocking_task_runner_->PostDelayedTask(
@@ -904,8 +912,11 @@
   BrowserThread::PostDelayedTask(
       BrowserThread::UI,
       FROM_HERE,
-      base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this),
-                 component_id, error, extended_error),
+      base::Bind(&CrxUpdateService::DoneInstalling,
+                 base::Unretained(this),
+                 component_id,
+                 error,
+                 extended_error),
       base::TimeDelta::FromMilliseconds(config_->StepDelay()));
   // Reset the unpacker last, otherwise we free our own arguments.
   unpacker_ = NULL;
@@ -944,7 +955,7 @@
     DCHECK_EQ(count, 1ul);
     ScheduleNextRun(kStepDelayShort);
     return;
-    }
+  }
 
   if (is_success) {
     ChangeItemState(item, CrxUpdateItem::kUpdated);
@@ -970,23 +981,24 @@
 }
 
 content::ResourceThrottle* CrxUpdateService::GetOnDemandResourceThrottle(
-     net::URLRequest* request, const std::string& crx_id) {
+    net::URLRequest* request,
+    const std::string& crx_id) {
   // We give the raw pointer to the caller, who will delete it at will
   // and we keep for ourselves a weak pointer to it so we can post tasks
   // from the UI thread without having to track lifetime directly.
   CUResourceThrottle* rt = new CUResourceThrottle(request);
-  BrowserThread::PostTask(
-      BrowserThread::UI,
-      FROM_HERE,
-      base::Bind(&CrxUpdateService::OnNewResourceThrottle,
-                 base::Unretained(this),
-                 rt->AsWeakPtr(),
-                 crx_id));
+  BrowserThread::PostTask(BrowserThread::UI,
+                          FROM_HERE,
+                          base::Bind(&CrxUpdateService::OnNewResourceThrottle,
+                                     base::Unretained(this),
+                                     rt->AsWeakPtr(),
+                                     crx_id));
   return rt;
 }
 
 void CrxUpdateService::OnNewResourceThrottle(
-    base::WeakPtr<CUResourceThrottle> rt, const std::string& crx_id) {
+    base::WeakPtr<CUResourceThrottle> rt,
+    const std::string& crx_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   // Check if we can on-demand update, else unblock the request anyway.
   CrxUpdateItem* item = FindUpdateItemById(crx_id);
@@ -1042,4 +1054,3 @@
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/component_updater_service.h b/chrome/browser/component_updater/component_updater_service.h
index 217e472..99164c3 100644
--- a/chrome/browser/component_updater/component_updater_service.h
+++ b/chrome/browser/component_updater/component_updater_service.h
@@ -35,7 +35,7 @@
 // OnUpdateError() and Install(). A valid instance of this class must be
 // given to ComponentUpdateService::RegisterComponent().
 class ComponentInstaller {
- public :
+ public:
   // Called by the component updater on the UI thread when there was a
   // problem unpacking or verifying the component. |error| is a non-zero
   // value which is only meaningful to the component updater.
@@ -106,12 +106,7 @@
 // All methods are safe to call ONLY from chrome's UI thread.
 class ComponentUpdateService {
  public:
-  enum Status {
-    kOk,
-    kReplaced,
-    kInProgress,
-    kError
-  };
+  enum Status { kOk, kReplaced, kInProgress, kError };
   // Controls the component updater behavior.
   class Configurator {
    public:
@@ -176,6 +171,9 @@
       // Sent when a component has not been updated following an update check:
       // either there was no update available, or an update failed.
       COMPONENT_NOT_UPDATED,
+
+      // Sent when component bytes are being downloaded.
+      COMPONENT_UPDATE_DOWNLOADING,
     };
 
     virtual ~Observer() {}
@@ -214,7 +212,8 @@
   // downloaded and installed before the resource is unthrottled. This is the
   // only function callable from the IO thread.
   virtual content::ResourceThrottle* GetOnDemandResourceThrottle(
-      net::URLRequest* request, const std::string& crx_id) = 0;
+      net::URLRequest* request,
+      const std::string& crx_id) = 0;
 
   virtual ~ComponentUpdateService() {}
 
diff --git a/chrome/browser/component_updater/component_updater_utils.cc b/chrome/browser/component_updater/component_updater_utils.cc
index 7f4c075..d6cb1e0 100644
--- a/chrome/browser/component_updater/component_updater_utils.cc
+++ b/chrome/browser/component_updater/component_updater_utils.cc
@@ -37,7 +37,7 @@
       "<request protocol=\"3.0\" ");
 
   if (!additional_attributes.empty())
-     base::StringAppendF(&request, "%s ", additional_attributes.c_str());
+    base::StringAppendF(&request, "%s ", additional_attributes.c_str());
 
   // Chrome version and platform information.
   base::StringAppendF(
@@ -56,13 +56,12 @@
       chrome::OmahaQueryParams::GetArch(),           // "arch"
       chrome::OmahaQueryParams::GetNaclArch());      // "nacl_arch"
 #if defined(OS_WIN)
-    const bool is_wow64(
-        base::win::OSInfo::GetInstance()->wow64_status() ==
-        base::win::OSInfo::WOW64_ENABLED);
-    if (is_wow64)
-      base::StringAppendF(&request, " wow64=\"1\"");
+  const bool is_wow64(base::win::OSInfo::GetInstance()->wow64_status() ==
+                      base::win::OSInfo::WOW64_ENABLED);
+  if (is_wow64)
+    base::StringAppendF(&request, " wow64=\"1\"");
 #endif
-    base::StringAppendF(&request, ">");
+  base::StringAppendF(&request, ">");
 
   // OS version and platform information.
   base::StringAppendF(
@@ -83,11 +82,8 @@
     const std::string& protocol_request,
     net::URLFetcherDelegate* url_fetcher_delegate,
     net::URLRequestContextGetter* url_request_context_getter) {
-  net::URLFetcher* url_fetcher(
-      net::URLFetcher::Create(0,
-                              url,
-                              net::URLFetcher::POST,
-                              url_fetcher_delegate));
+  net::URLFetcher* url_fetcher(net::URLFetcher::Create(
+      0, url, net::URLFetcher::POST, url_fetcher_delegate));
 
   url_fetcher->SetUploadData("application/xml", protocol_request);
   url_fetcher->SetRequestContext(url_request_context_getter);
@@ -156,9 +152,9 @@
   std::string id;
   for (size_t i = 0; i < hexstr.size(); ++i) {
     int val = 0;
-    if (base::HexStringToInt(base::StringPiece(hexstr.begin() + i,
-                                               hexstr.begin() + i + 1),
-                             &val)) {
+    if (base::HexStringToInt(
+            base::StringPiece(hexstr.begin() + i, hexstr.begin() + i + 1),
+            &val)) {
       id.append(1, val + 'a');
     } else {
       id.append(1, 'a');
@@ -169,9 +165,8 @@
 }
 
 std::string GetCrxComponentID(const CrxComponent& component) {
-  return HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0],
-                       component.pk_hash.size()/2)));
+  return HexStringToID(StringToLowerASCII(
+      base::HexEncode(&component.pk_hash[0], component.pk_hash.size() / 2)));
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/component_updater_utils.h b/chrome/browser/component_updater/component_updater_utils.h
index d5431b6..17acb59 100644
--- a/chrome/browser/component_updater/component_updater_utils.h
+++ b/chrome/browser/component_updater/component_updater_utils.h
@@ -82,4 +82,3 @@
 }  // namespace component_updater
 
 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_UPDATER_UTILS_H_
-
diff --git a/chrome/browser/component_updater/crx_downloader.cc b/chrome/browser/component_updater/crx_downloader.cc
index 9591b9c..a70211a 100644
--- a/chrome/browser/component_updater/crx_downloader.cc
+++ b/chrome/browser/component_updater/crx_downloader.cc
@@ -14,14 +14,17 @@
 
 namespace component_updater {
 
-CrxDownloader::Result::Result() : error(0) {}
+CrxDownloader::Result::Result()
+    : error(0), downloaded_bytes(-1), total_bytes(-1) {
+}
 
 CrxDownloader::DownloadMetrics::DownloadMetrics()
     : downloader(kNone),
       error(0),
-      bytes_downloaded(-1),
-      bytes_total(-1),
-      download_time_ms(0) {}
+      downloaded_bytes(-1),
+      total_bytes(-1),
+      download_time_ms(0) {
+}
 
 // On Windows, the first downloader in the chain is a background downloader,
 // which uses the BITS service.
@@ -33,7 +36,7 @@
       new UrlFetcherDownloader(scoped_ptr<CrxDownloader>().Pass(),
                                context_getter,
                                task_runner));
-#if defined (OS_WIN)
+#if defined(OS_WIN)
   if (is_background_download) {
     return new BackgroundDownloader(url_fetcher_downloader.Pass(),
                                     context_getter,
@@ -52,6 +55,11 @@
 CrxDownloader::~CrxDownloader() {
 }
 
+void CrxDownloader::set_progress_callback(
+    const ProgressCallback& progress_callback) {
+  progress_callback_ = progress_callback;
+}
+
 GURL CrxDownloader::url() const {
   return current_url_ != urls_.end() ? *current_url_ : GURL();
 }
@@ -62,9 +70,8 @@
     return download_metrics_;
 
   std::vector<DownloadMetrics> retval(successor_->download_metrics());
-  retval.insert(retval.begin(),
-                download_metrics_.begin(),
-                download_metrics_.end());
+  retval.insert(
+      retval.begin(), download_metrics_.begin(), download_metrics_.end());
   return retval;
 }
 
@@ -139,5 +146,13 @@
   download_callback_.Run(result);
 }
 
-}  // namespace component_updater
+void CrxDownloader::OnDownloadProgress(const Result& result) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
+  if (progress_callback_.is_null())
+    return;
+
+  progress_callback_.Run(result);
+}
+
+}  // namespace component_updater
diff --git a/chrome/browser/component_updater/crx_downloader.h b/chrome/browser/component_updater/crx_downloader.h
index 1648d27..fbe2259 100644
--- a/chrome/browser/component_updater/crx_downloader.h
+++ b/chrome/browser/component_updater/crx_downloader.h
@@ -34,11 +34,7 @@
 class CrxDownloader {
  public:
   struct DownloadMetrics {
-    enum Downloader {
-      kNone = 0,
-      kUrlFetcher,
-      kBits
-    };
+    enum Downloader { kNone = 0, kUrlFetcher, kBits };
 
     DownloadMetrics();
 
@@ -48,13 +44,13 @@
 
     int error;
 
-    int64 bytes_downloaded;   // -1 means that the byte count is unknown.
-    int64 bytes_total;
+    int64 downloaded_bytes;  // -1 means that the byte count is unknown.
+    int64 total_bytes;
 
     uint64 download_time_ms;
   };
 
-  // Contains the outcome of the download.
+  // Contains the progress or the outcome of the download.
   struct Result {
     Result();
 
@@ -63,6 +59,13 @@
 
     // Path of the downloaded file if the download was successful.
     base::FilePath response;
+
+    // Number of bytes actually downloaded, not including the bytes downloaded
+    // as a result of falling back on urls.
+    int64 downloaded_bytes;
+
+    // Number of bytes expected to be downloaded.
+    int64 total_bytes;
   };
 
   // The callback fires only once, regardless of how many urls are tried, and
@@ -70,7 +73,13 @@
   // download. The callback interface can be extended if needed to provide
   // more visibility into how the download has been handled, including
   // specific error codes and download metrics.
-  typedef base::Callback<void (const Result& result)> DownloadCallback;
+  typedef base::Callback<void(const Result& result)> DownloadCallback;
+
+  // The callback may fire 0 or many times during a download. Since this
+  // class implements a chain of responsibility, the callback can fire for
+  // different urls and different downloaders. The number of actual downloaded
+  // bytes is not guaranteed to monotonically increment over time.
+  typedef base::Callback<void(const Result& result)> ProgressCallback;
 
   // Factory method to create an instance of this class and build the
   // chain of responsibility. |is_background_download| specifies that a
@@ -81,6 +90,8 @@
       scoped_refptr<base::SequencedTaskRunner> task_runner);
   virtual ~CrxDownloader();
 
+  void set_progress_callback(const ProgressCallback& progress_callback);
+
   // Starts the download. One instance of the class handles one download only.
   // One instance of CrxDownloader can only be started once, otherwise the
   // behavior is undefined. The callback gets invoked if the download can't
@@ -107,7 +118,10 @@
                           const Result& result,
                           const DownloadMetrics& download_metrics);
 
-  // Returns the url which is currently downloaded from.
+  // Calls the callback when progress is made.
+  void OnDownloadProgress(const Result& result);
+
+  // Returns the url which is currently being downloaded from.
   GURL url() const;
 
  private:
@@ -116,6 +130,7 @@
   std::vector<GURL> urls_;
   scoped_ptr<CrxDownloader> successor_;
   DownloadCallback download_callback_;
+  ProgressCallback progress_callback_;
 
   std::vector<GURL>::iterator current_url_;
 
@@ -127,4 +142,3 @@
 }  // namespace component_updater
 
 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_CRX_DOWNLOADER_H_
-
diff --git a/chrome/browser/component_updater/crx_update_item.h b/chrome/browser/component_updater/crx_update_item.h
index ff94d98..cb7ac62 100644
--- a/chrome/browser/component_updater/crx_update_item.h
+++ b/chrome/browser/component_updater/crx_update_item.h
@@ -120,9 +120,8 @@
    public:
     explicit FindById(const std::string& id) : id_(id) {}
 
-    bool operator() (CrxUpdateItem* item) const {
-      return (item->id == id_);
-    }
+    bool operator()(CrxUpdateItem* item) const { return item->id == id_; }
+
    private:
     const std::string& id_;
   };
diff --git a/chrome/browser/component_updater/default_component_installer.cc b/chrome/browser/component_updater/default_component_installer.cc
index 1447ca3..a2983c1 100644
--- a/chrome/browser/component_updater/default_component_installer.cc
+++ b/chrome/browser/component_updater/default_component_installer.cc
@@ -89,7 +89,8 @@
   scoped_ptr<base::DictionaryValue> manifest_copy(
       current_manifest_->DeepCopy());
   content::BrowserThread::PostTask(
-      content::BrowserThread::UI, FROM_HERE,
+      content::BrowserThread::UI,
+      FROM_HERE,
       base::Bind(&ComponentInstallerTraits::ComponentReady,
                  base::Unretained(installer_traits_.get()),
                  current_version_,
@@ -104,17 +105,15 @@
   if (current_version_.Equals(base::Version(kNullVersion)))
     return false;  // No component has been installed yet.
 
-  *installed_file =
-      installer_traits_->GetBaseDirectory()
-          .AppendASCII(current_version_.GetString()).AppendASCII(file);
+  *installed_file = installer_traits_->GetBaseDirectory()
+                        .AppendASCII(current_version_.GetString())
+                        .AppendASCII(file);
   return true;
 }
 
-void DefaultComponentInstaller::StartRegistration(
-    ComponentUpdateService* cus) {
+void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) {
   base::FilePath base_dir = installer_traits_->GetBaseDirectory();
-  if (!base::PathExists(base_dir) &&
-      !base::CreateDirectory(base_dir)) {
+  if (!base::PathExists(base_dir) && !base::CreateDirectory(base_dir)) {
     NOTREACHED() << "Could not create the base directory for "
                  << installer_traits_->GetName() << " ("
                  << base_dir.MaybeAsASCII() << ").";
@@ -160,7 +159,7 @@
     // FinishRegistration().
     base::ReadFileToString(latest_dir.AppendASCII("manifest.fingerprint"),
                            &current_fingerprint_);
-    current_manifest_= ReadManifest(latest_dir);
+    current_manifest_ = ReadManifest(latest_dir);
     if (!current_manifest_) {
       DLOG(ERROR) << "Failed to read manifest for "
                   << installer_traits_->GetName() << " ("
@@ -172,12 +171,14 @@
   // Remove older versions of the component. None should be in use during
   // browser startup.
   for (std::vector<base::FilePath>::iterator iter = older_dirs.begin();
-       iter != older_dirs.end(); ++iter) {
-   base::DeleteFile(*iter, true);
+       iter != older_dirs.end();
+       ++iter) {
+    base::DeleteFile(*iter, true);
   }
 
   content::BrowserThread::PostTask(
-      content::BrowserThread::UI, FROM_HERE,
+      content::BrowserThread::UI,
+      FROM_HERE,
       base::Bind(&DefaultComponentInstaller::FinishRegistration,
                  base::Unretained(this),
                  cus));
@@ -211,11 +212,8 @@
     scoped_ptr<base::DictionaryValue> manifest_copy(
         current_manifest_->DeepCopy());
     installer_traits_->ComponentReady(
-        current_version_,
-        GetInstallDirectory(),
-        manifest_copy.Pass());
+        current_version_, GetInstallDirectory(), manifest_copy.Pass());
   }
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/default_component_installer.h b/chrome/browser/component_updater/default_component_installer.h
index 3c9f52d..12394fe 100644
--- a/chrome/browser/component_updater/default_component_installer.h
+++ b/chrome/browser/component_updater/default_component_installer.h
@@ -56,10 +56,9 @@
   // |version| is the version of the component.
   // |install_dir| is the path to the install directory for this version.
   // |manifest| is the manifest for this version of the component.
-  virtual void ComponentReady(
-      const base::Version& version,
-      const base::FilePath& install_dir,
-      scoped_ptr<base::DictionaryValue> manifest) = 0;
+  virtual void ComponentReady(const base::Version& version,
+                              const base::FilePath& install_dir,
+                              scoped_ptr<base::DictionaryValue> manifest) = 0;
 
   // Returns the directory that the installer will place versioned installs of
   // the component into.
diff --git a/chrome/browser/component_updater/pepper_flash_component_installer.cc b/chrome/browser/component_updater/pepper_flash_component_installer.cc
index c0c5846..5a493d8 100644
--- a/chrome/browser/component_updater/pepper_flash_component_installer.cc
+++ b/chrome/browser/component_updater/pepper_flash_component_installer.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/component_updater/flash_component_installer.h"
-
 #include <string.h>
 
 #include <vector>
@@ -25,6 +23,7 @@
 #include "base/version.h"
 #include "build/build_config.h"
 #include "chrome/browser/component_updater/component_updater_service.h"
+#include "chrome/browser/component_updater/flash_component_installer.h"
 #include "chrome/browser/component_updater/ppapi_utils.h"
 #include "chrome/browser/plugins/plugin_prefs.h"
 #include "chrome/common/chrome_constants.h"
@@ -35,11 +34,10 @@
 #include "content/public/browser/plugin_service.h"
 #include "content/public/common/content_constants.h"
 #include "content/public/common/pepper_plugin_info.h"
+#include "flapper_version.h"  // In SHARED_INTERMEDIATE_DIR.  NOLINT
 #include "ppapi/c/private/ppb_pdf.h"
 #include "ppapi/shared_impl/ppapi_permissions.h"
 
-#include "flapper_version.h"  // In SHARED_INTERMEDIATE_DIR.
-
 using content::BrowserThread;
 using content::PluginService;
 
@@ -112,8 +110,8 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
   base::FilePath base_dir = GetPepperFlashBaseDirectory();
   bool found = false;
-  base::FileEnumerator
-      file_enumerator(base_dir, false, base::FileEnumerator::DIRECTORIES);
+  base::FileEnumerator file_enumerator(
+      base_dir, false, base::FileEnumerator::DIRECTORIES);
   for (base::FilePath path = file_enumerator.Next(); !path.value().empty();
        path = file_enumerator.Next()) {
     Version version(path.BaseName().MaybeAsASCII());
@@ -229,9 +227,12 @@
 
   // The description is like "Shockwave Flash 10.2 r154".
   plugin_info->description = base::StringPrintf("%s %d.%d r%d",
-      content::kFlashPluginName, ver_nums[0], ver_nums[1], ver_nums[2]);
+                                                content::kFlashPluginName,
+                                                ver_nums[0],
+                                                ver_nums[1],
+                                                ver_nums[2]);
   if (is_debugger) {
-    plugin_info->description += " Debug";
+    plugin_info->description += "Debug";
   }
 
   plugin_info->version = flash_version.GetString();
@@ -351,7 +352,8 @@
 };
 
 PepperFlashComponentInstaller::PepperFlashComponentInstaller(
-    const Version& version) : current_version_(version) {
+    const Version& version)
+    : current_version_(version) {
   DCHECK(version.IsValid());
 }
 
@@ -367,8 +369,7 @@
     return false;
   if (current_version_.CompareTo(version) > 0)
     return false;
-  if (!base::PathExists(unpack_path.Append(
-          chrome::kPepperFlashPluginFilename)))
+  if (!base::PathExists(unpack_path.Append(chrome::kPepperFlashPluginFilename)))
     return false;
   // Passed the basic tests. Time to install it.
   base::FilePath path =
@@ -390,7 +391,8 @@
 }
 
 bool PepperFlashComponentInstaller::GetInstalledFile(
-    const std::string& file, base::FilePath* installed_file) {
+    const std::string& file,
+    base::FilePath* installed_file) {
   return false;
 }
 
@@ -474,12 +476,14 @@
   }
 
   BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
+      BrowserThread::UI,
+      FROM_HERE,
       base::Bind(&FinishPepperFlashUpdateRegistration, cus, version));
 
   // Remove older versions of Pepper Flash.
   for (std::vector<base::FilePath>::iterator iter = older_dirs.begin();
-       iter != older_dirs.end(); ++iter) {
+       iter != older_dirs.end();
+       ++iter) {
     base::DeleteFile(*iter, true);
   }
 
@@ -500,16 +504,16 @@
 }  // namespace
 
 void RegisterPepperFlashComponent(ComponentUpdateService* cus) {
-  #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX)
+#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_LINUX)
   // Component updated flash supersedes bundled flash therefore if that one
   // is disabled then this one should never install.
   CommandLine* cmd_line = CommandLine::ForCurrentProcess();
   if (cmd_line->HasSwitch(switches::kDisableBundledPpapiFlash))
     return;
-  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+  BrowserThread::PostTask(BrowserThread::FILE,
+                          FROM_HERE,
                           base::Bind(&StartPepperFlashUpdateRegistration, cus));
-  #endif
+#endif
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc b/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc
index dc1157c..aea484b 100644
--- a/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc
+++ b/chrome/browser/component_updater/pnacl/pnacl_component_installer.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h"
 
+#include <string>
+#include <vector>
+
 #include "base/atomicops.h"
 #include "base/base_paths.h"
 #include "base/bind.h"
@@ -51,19 +54,20 @@
 
 // Set the component's hash to the multi-CRX PNaCl package.
 void SetPnaclHash(CrxComponent* component) {
- static const uint8 sha256_hash[32] =
-     { // This corresponds to AppID: hnimpnehoodheedghdeeijklkeaacbdc
-       0x7d, 0x8c, 0xfd, 0x47, 0xee, 0x37, 0x44, 0x36, 0x73, 0x44,
-       0x89, 0xab, 0xa4, 0x00, 0x21, 0x32, 0x4a, 0x06, 0x06, 0xf1, 0x51,
-       0x3c, 0x51, 0xba, 0x31, 0x2f, 0xbc, 0xb3, 0x99, 0x07, 0xdc, 0x9c};
+  static const uint8 sha256_hash[32] = {
+      // This corresponds to AppID: hnimpnehoodheedghdeeijklkeaacbdc
+      0x7d, 0x8c, 0xfd, 0x47, 0xee, 0x37, 0x44, 0x36,
+      0x73, 0x44, 0x89, 0xab, 0xa4, 0x00, 0x21, 0x32,
+      0x4a, 0x06, 0x06, 0xf1, 0x51, 0x3c, 0x51, 0xba,
+      0x31, 0x2f, 0xbc, 0xb3, 0x99, 0x07, 0xdc, 0x9c
+  };
 
-  component->pk_hash.assign(sha256_hash,
-                            &sha256_hash[arraysize(sha256_hash)]);
+  component->pk_hash.assign(sha256_hash, &sha256_hash[arraysize(sha256_hash)]);
 }
 
 // If we don't have Pnacl installed, this is the version we claim.
 const char kNullVersion[] = "0.0.0.0";
-const char kMinPnaclVersion[] = "0.1.0.12773";
+const char kMinPnaclVersion[] = "0.1.0.13154";
 
 // Initially say that we do not need OnDemand updates. This should be
 // updated by CheckVersionCompatiblity(), before doing any URLRequests
@@ -86,8 +90,7 @@
 
 // Tell the rest of the world where to find the platform-specific PNaCl files.
 void OverrideDirPnaclComponent(const base::FilePath& base_path) {
-  PathService::Override(chrome::DIR_PNACL_COMPONENT,
-                        GetPlatformDir(base_path));
+  PathService::Override(chrome::DIR_PNACL_COMPONENT, GetPlatformDir(base_path));
 }
 
 bool GetLatestPnaclDirectory(PnaclComponentInstaller* pci,
@@ -97,8 +100,8 @@
   // Enumerate all versions starting from the base directory.
   base::FilePath base_dir = pci->GetPnaclBaseDirectory();
   bool found = false;
-  base::FileEnumerator
-      file_enumerator(base_dir, false, base::FileEnumerator::DIRECTORIES);
+  base::FileEnumerator file_enumerator(
+      base_dir, false, base::FileEnumerator::DIRECTORIES);
   for (base::FilePath path = file_enumerator.Next(); !path.value().empty();
        path = file_enumerator.Next()) {
     Version version(path.BaseName().MaybeAsASCII());
@@ -122,8 +125,7 @@
 }
 
 // Read a manifest file in.
-base::DictionaryValue* ReadJSONManifest(
-    const base::FilePath& manifest_path) {
+base::DictionaryValue* ReadJSONManifest(const base::FilePath& manifest_path) {
   JSONFileValueSerializer serializer(manifest_path);
   std::string error;
   scoped_ptr<base::Value> root(serializer.Deserialize(NULL, &error));
@@ -136,8 +138,8 @@
 
 // Read the PNaCl specific manifest.
 base::DictionaryValue* ReadPnaclManifest(const base::FilePath& unpack_path) {
-  base::FilePath manifest_path = GetPlatformDir(unpack_path).AppendASCII(
-      "pnacl_public_pnacl_json");
+  base::FilePath manifest_path =
+      GetPlatformDir(unpack_path).AppendASCII("pnacl_public_pnacl_json");
   if (!base::PathExists(manifest_path))
     return NULL;
   return ReadJSONManifest(manifest_path);
@@ -146,8 +148,8 @@
 // Read the component's manifest.json.
 base::DictionaryValue* ReadComponentManifest(
     const base::FilePath& unpack_path) {
-  base::FilePath manifest_path = unpack_path.Append(
-      FILE_PATH_LITERAL("manifest.json"));
+  base::FilePath manifest_path =
+      unpack_path.Append(FILE_PATH_LITERAL("manifest.json"));
   if (!base::PathExists(manifest_path))
     return NULL;
   return ReadJSONManifest(manifest_path);
@@ -168,9 +170,8 @@
   // architecture specific packages (and test/QA vs not test/QA)
   // so only part of it is the same.
   if (name.find(kPnaclManifestName) == std::string::npos) {
-    LOG(WARNING) << "'name' field in manifest is invalid ("
-                 << name << ") -- missing ("
-                 << kPnaclManifestName << ")";
+    LOG(WARNING) << "'name' field in manifest is invalid (" << name
+                 << ") -- missing (" << kPnaclManifestName << ")";
     return false;
   }
 
@@ -205,9 +206,7 @@
 }  // namespace
 
 PnaclComponentInstaller::PnaclComponentInstaller()
-    : per_user_(false),
-      updates_disabled_(false),
-      cus_(NULL) {
+    : per_user_(false), updates_disabled_(false), cus_(NULL) {
 #if defined(OS_CHROMEOS)
   per_user_ = true;
 #endif
@@ -233,8 +232,8 @@
   //   so we need to watch for user-login-events (see pnacl_profile_observer.h).
   if (per_user_) {
     DCHECK(!current_profile_path_.empty());
-    base::FilePath path = current_profile_path_.Append(
-        FILE_PATH_LITERAL("pnacl"));
+    base::FilePath path =
+        current_profile_path_.Append(FILE_PATH_LITERAL("pnacl"));
     return path;
   } else {
     base::FilePath result;
@@ -248,8 +247,8 @@
   // Even though the path does vary between users, the content
   // changes when logging out and logging in.
   ProfileManager* pm = g_browser_process->profile_manager();
-  current_profile_path_ = pm->user_data_dir().Append(
-      pm->GetInitialProfileDir());
+  current_profile_path_ =
+      pm->user_data_dir().Append(pm->GetInitialProfileDir());
 }
 
 bool PnaclComponentInstaller::Install(const base::DictionaryValue& manifest,
@@ -273,8 +272,8 @@
   }
 
   // Passed the basic tests. Time to install it.
-  base::FilePath path = GetPnaclBaseDirectory().AppendASCII(
-      version.GetString());
+  base::FilePath path =
+      GetPnaclBaseDirectory().AppendASCII(version.GetString());
   if (base::PathExists(path)) {
     if (!base::DeleteFile(path, true))
       return false;
@@ -297,13 +296,14 @@
 // returns the assumed install path. The path separator in |file| is '/'
 // for all platforms. Caller is responsible for checking that the
 // |installed_file| actually exists.
-bool PnaclComponentInstaller::GetInstalledFile(
-    const std::string& file, base::FilePath* installed_file) {
+bool PnaclComponentInstaller::GetInstalledFile(const std::string& file,
+                                               base::FilePath* installed_file) {
   if (current_version().Equals(Version(kNullVersion)))
     return false;
 
-  *installed_file = GetPnaclBaseDirectory().AppendASCII(
-      current_version().GetString()).AppendASCII(file);
+  *installed_file = GetPnaclBaseDirectory()
+                        .AppendASCII(current_version().GetString())
+                        .AppendASCII(file);
   return true;
 }
 
@@ -331,8 +331,8 @@
 
   ComponentUpdateService::Status status =
       pci->cus()->RegisterComponent(pnacl_component);
-  if (status != ComponentUpdateService::kOk
-      && status != ComponentUpdateService::kReplaced) {
+  if (status != ComponentUpdateService::kOk &&
+      status != ComponentUpdateService::kReplaced) {
     NOTREACHED() << "Pnacl component registration failed.";
   }
 }
@@ -353,19 +353,17 @@
   std::string current_fingerprint;
   std::vector<base::FilePath> older_dirs;
   if (GetLatestPnaclDirectory(pci, &path, &current_version, &older_dirs)) {
-    scoped_ptr<base::DictionaryValue> manifest(
-        ReadComponentManifest(path));
-    scoped_ptr<base::DictionaryValue> pnacl_manifest(
-        ReadPnaclManifest(path));
+    scoped_ptr<base::DictionaryValue> manifest(ReadComponentManifest(path));
+    scoped_ptr<base::DictionaryValue> pnacl_manifest(ReadPnaclManifest(path));
     Version manifest_version;
     // Check that the component manifest and PNaCl manifest files
     // are legit, and that the indicated version matches the one
     // encoded within the path name.
-    if (manifest == NULL || pnacl_manifest == NULL
-        || !CheckPnaclComponentManifest(*manifest,
-                                        *pnacl_manifest,
-                                        &manifest_version)
-        || !current_version.Equals(manifest_version)) {
+    if (manifest == NULL || pnacl_manifest == NULL ||
+        !CheckPnaclComponentManifest(*manifest,
+                                     *pnacl_manifest,
+                                     &manifest_version) ||
+        !current_version.Equals(manifest_version)) {
       current_version = Version(kNullVersion);
     } else {
       OverrideDirPnaclComponent(path);
@@ -381,16 +379,17 @@
   if (pci->updates_disabled())
     return;
 
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&FinishPnaclUpdateRegistration,
-                 current_version,
-                 current_fingerprint,
-                 pci));
+  BrowserThread::PostTask(BrowserThread::UI,
+                          FROM_HERE,
+                          base::Bind(&FinishPnaclUpdateRegistration,
+                                     current_version,
+                                     current_fingerprint,
+                                     pci));
 
   // Remove older versions of PNaCl.
   for (std::vector<base::FilePath>::iterator iter = older_dirs.begin();
-       iter != older_dirs.end(); ++iter) {
+       iter != older_dirs.end();
+       ++iter) {
     base::DeleteFile(*iter, true);
   }
 }
@@ -405,12 +404,11 @@
     return;
 
   // Do a basic sanity check first.
-  if (pci->per_user()
-      && path.BaseName().value().compare(FILE_PATH_LITERAL("pnacl")) == 0)
+  if (pci->per_user() &&
+      path.BaseName().value().compare(FILE_PATH_LITERAL("pnacl")) == 0)
     base::DeleteFile(path, true);
 }
 
-
 void GetProfileInformation(PnaclComponentInstaller* pci) {
   // Bail if not logged in yet.
   if (!g_browser_process->profile_manager()->IsLoggedIn()) {
@@ -422,15 +420,16 @@
   // Do not actually register PNaCl for component updates, for CHROMEOS.
   // Just get the profile information and delete the per-profile files
   // if they exist.
- BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
-                         base::Bind(&ReapOldChromeOSPnaclFiles, pci));
+  BrowserThread::PostTask(BrowserThread::FILE,
+                          FROM_HERE,
+                          base::Bind(&ReapOldChromeOSPnaclFiles, pci));
 }
 
 }  // namespace
 
 void PnaclComponentInstaller::RegisterPnaclComponent(
-                            ComponentUpdateService* cus,
-                            const CommandLine& command_line) {
+    ComponentUpdateService* cus,
+    const CommandLine& command_line) {
   // Register PNaCl by default (can be disabled).
   updates_disabled_ = command_line.HasSwitch(switches::kDisablePnaclInstall);
   cus_ = cus;
@@ -441,10 +440,11 @@
   }
   if (per_user_) {
     // Figure out profile information, before proceeding to look for files.
-    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-                            base::Bind(&GetProfileInformation, this));
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE, base::Bind(&GetProfileInformation, this));
   } else {
-    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+    BrowserThread::PostTask(BrowserThread::FILE,
+                            FROM_HERE,
                             base::Bind(&StartPnaclUpdateRegistration, this));
   }
 }
@@ -453,8 +453,7 @@
   DCHECK(per_user_);
   // Figure out profile information, before proceeding to look for files.
   BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&GetProfileInformation, this));
+      BrowserThread::UI, FROM_HERE, base::Bind(&GetProfileInformation, this));
 }
 
 }  // namespace component_updater
@@ -463,7 +462,7 @@
 
 bool NeedsOnDemandUpdate() {
   return base::subtle::NoBarrier_Load(
-      &component_updater::needs_on_demand_update) != 0;
+             &component_updater::needs_on_demand_update) != 0;
 }
 
 }  // namespace pnacl
diff --git a/chrome/browser/component_updater/pnacl/pnacl_component_installer.h b/chrome/browser/component_updater/pnacl/pnacl_component_installer.h
index ba5fd24..b54fe40 100644
--- a/chrome/browser/component_updater/pnacl/pnacl_component_installer.h
+++ b/chrome/browser/component_updater/pnacl/pnacl_component_installer.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_COMPONENT_UPDATER_PNACL_PNACL_COMPONENT_INSTALLER_H_
 
 #include <list>
+#include <string>
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
diff --git a/chrome/browser/component_updater/pnacl/pnacl_profile_observer.cc b/chrome/browser/component_updater/pnacl/pnacl_profile_observer.cc
index 12211e8..da5d055 100644
--- a/chrome/browser/component_updater/pnacl/pnacl_profile_observer.cc
+++ b/chrome/browser/component_updater/pnacl/pnacl_profile_observer.cc
@@ -11,10 +11,10 @@
 
 namespace component_updater {
 
-PnaclProfileObserver::PnaclProfileObserver(
-    PnaclComponentInstaller* installer) : pnacl_installer_(installer) {
-  // We only need to observe NOTIFICATION_LOGIN_USER_CHANGED for ChromeOS
-  // (and it's only defined for ChromeOS).
+PnaclProfileObserver::PnaclProfileObserver(PnaclComponentInstaller* installer)
+    : pnacl_installer_(installer) {
+// We only need to observe NOTIFICATION_LOGIN_USER_CHANGED for ChromeOS
+// (and it's only defined for ChromeOS).
 #if defined(OS_CHROMEOS)
   registrar_.Add(this,
                  chrome::NOTIFICATION_LOGIN_USER_CHANGED,
@@ -22,7 +22,8 @@
 #endif
 }
 
-PnaclProfileObserver::~PnaclProfileObserver() { }
+PnaclProfileObserver::~PnaclProfileObserver() {
+}
 
 void PnaclProfileObserver::Observe(
     int type,
diff --git a/chrome/browser/component_updater/pnacl/pnacl_profile_observer.h b/chrome/browser/component_updater/pnacl/pnacl_profile_observer.h
index 2b377b6..c314b6b 100644
--- a/chrome/browser/component_updater/pnacl/pnacl_profile_observer.h
+++ b/chrome/browser/component_updater/pnacl/pnacl_profile_observer.h
@@ -20,10 +20,9 @@
   explicit PnaclProfileObserver(PnaclComponentInstaller* installer);
   virtual ~PnaclProfileObserver();
 
-  virtual void Observe(
-      int type,
-      const content::NotificationSource& source,
-      const content::NotificationDetails& details) OVERRIDE;
+  virtual void Observe(int type,
+                       const content::NotificationSource& source,
+                       const content::NotificationDetails& details) OVERRIDE;
 
  private:
   content::NotificationRegistrar registrar_;
diff --git a/chrome/browser/component_updater/ppapi_utils.cc b/chrome/browser/component_updater/ppapi_utils.cc
index 0e2ff64..cdd8363 100644
--- a/chrome/browser/component_updater/ppapi_utils.cc
+++ b/chrome/browser/component_updater/ppapi_utils.cc
@@ -112,26 +112,26 @@
 #endif
 
 bool IsSupportedPepperInterface(const char* name) {
-  // TODO(brettw) put these in a hash map for better performance.
-  #define PROXIED_IFACE(iface_str, iface_struct) \
-      if (strcmp(name, iface_str) == 0) \
-        return true;
+// TODO(brettw) put these in a hash map for better performance.
+#define PROXIED_IFACE(iface_str, iface_struct) \
+  if (strcmp(name, iface_str) == 0)            \
+    return true;
 
-  #include "ppapi/thunk/interfaces_ppb_private.h"
-  #include "ppapi/thunk/interfaces_ppb_private_flash.h"
-  #include "ppapi/thunk/interfaces_ppb_private_no_permissions.h"
-  #include "ppapi/thunk/interfaces_ppb_public_dev.h"
-  #include "ppapi/thunk/interfaces_ppb_public_dev_channel.h"
-  #include "ppapi/thunk/interfaces_ppb_public_stable.h"
+#include "ppapi/thunk/interfaces_ppb_private.h"
+#include "ppapi/thunk/interfaces_ppb_private_flash.h"
+#include "ppapi/thunk/interfaces_ppb_private_no_permissions.h"
+#include "ppapi/thunk/interfaces_ppb_public_dev.h"
+#include "ppapi/thunk/interfaces_ppb_public_dev_channel.h"
+#include "ppapi/thunk/interfaces_ppb_public_stable.h"
 
-  #undef PROXIED_IFACE
+#undef PROXIED_IFACE
 
-  #define LEGACY_IFACE(iface_str, dummy) \
-      if (strcmp(name, iface_str) == 0) \
-        return true;
+#define LEGACY_IFACE(iface_str, dummy) \
+  if (strcmp(name, iface_str) == 0)    \
+    return true;
 
-  #include "ppapi/thunk/interfaces_legacy.h"
+#include "ppapi/thunk/interfaces_legacy.h"
 
-  #undef LEGACY_IFACE
+#undef LEGACY_IFACE
   return false;
 }
diff --git a/chrome/browser/component_updater/ppapi_utils.h b/chrome/browser/component_updater/ppapi_utils.h
index 41100eb..893d727 100644
--- a/chrome/browser/component_updater/ppapi_utils.h
+++ b/chrome/browser/component_updater/ppapi_utils.h
@@ -10,5 +10,3 @@
 bool IsSupportedPepperInterface(const char* name);
 
 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_PPAPI_UTILS_H_
-
-
diff --git a/chrome/browser/component_updater/recovery_component_installer.cc b/chrome/browser/component_updater/recovery_component_installer.cc
index bcf9aea..642f94c 100644
--- a/chrome/browser/component_updater/recovery_component_installer.cc
+++ b/chrome/browser/component_updater/recovery_component_installer.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/component_updater/recovery_component_installer.h"
 
+#include <string>
+
 #include "base/base_paths.h"
 #include "base/bind.h"
 #include "base/command_line.h"
@@ -66,8 +68,7 @@
   PrefService* prefs_;
 };
 
-void RecoveryRegisterHelper(ComponentUpdateService* cus,
-                            PrefService* prefs) {
+void RecoveryRegisterHelper(ComponentUpdateService* cus, PrefService* prefs) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   Version version(prefs->GetString(prefs::kRecoveryComponentVersion));
   if (!version.IsValid()) {
@@ -90,9 +91,9 @@
   prefs->SetString(prefs::kRecoveryComponentVersion, version.GetString());
 }
 
-RecoveryComponentInstaller::RecoveryComponentInstaller(
-      const Version& version, PrefService* prefs)
-    : current_version_(version), prefs_(prefs){
+RecoveryComponentInstaller::RecoveryComponentInstaller(const Version& version,
+                                                       PrefService* prefs)
+    : current_version_(version), prefs_(prefs) {
   DCHECK(version.IsValid());
 }
 
@@ -129,14 +130,17 @@
   }
   current_version_ = version;
   if (prefs_) {
-    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+    BrowserThread::PostTask(
+        BrowserThread::UI,
+        FROM_HERE,
         base::Bind(&RecoveryUpdateVersionHelper, version, prefs_));
   }
   return base::LaunchProcess(cmdline, base::LaunchOptions(), NULL);
 }
 
 bool RecoveryComponentInstaller::GetInstalledFile(
-    const std::string& file, base::FilePath* installed_file) {
+    const std::string& file,
+    base::FilePath* installed_file) {
   return false;
 }
 
@@ -158,4 +162,3 @@
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/recovery_component_installer.h b/chrome/browser/component_updater/recovery_component_installer.h
index 81d46c9..260083d 100644
--- a/chrome/browser/component_updater/recovery_component_installer.h
+++ b/chrome/browser/component_updater/recovery_component_installer.h
@@ -15,9 +15,7 @@
 // Component update registration for the recovery component. The job of the
 // recovery component is to repair the chrome installation or repair the Google
 // update installation. This is a last resort safety mechanism.
-void RegisterRecoveryComponent(ComponentUpdateService* cus,
-                               PrefService* prefs);
-
+void RegisterRecoveryComponent(ComponentUpdateService* cus, PrefService* prefs);
 
 // Register user preferences related to the recovery component.
 void RegisterPrefsForRecoveryComponent(PrefRegistrySimple* registry);
@@ -25,4 +23,3 @@
 }  // namespace component_updater
 
 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_RECOVERY_COMPONENT_INSTALLER_H_
-
diff --git a/chrome/browser/component_updater/swiftshader_component_installer.cc b/chrome/browser/component_updater/swiftshader_component_installer.cc
index 5991bdf..e4c410a 100644
--- a/chrome/browser/component_updater/swiftshader_component_installer.cc
+++ b/chrome/browser/component_updater/swiftshader_component_installer.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/component_updater/swiftshader_component_installer.h"
 
+#include <string>
+#include <vector>
+
 #include "base/base_paths.h"
 #include "base/bind.h"
 #include "base/compiler_specific.h"
@@ -66,8 +69,8 @@
                                    std::vector<base::FilePath>* older_dirs) {
   base::FilePath base_dir = GetSwiftShaderBaseDirectory();
   bool found = false;
-  base::FileEnumerator
-      file_enumerator(base_dir, false, base::FileEnumerator::DIRECTORIES);
+  base::FileEnumerator file_enumerator(
+      base_dir, false, base::FileEnumerator::DIRECTORIES);
   for (base::FilePath path = file_enumerator.Next(); !path.value().empty();
        path = file_enumerator.Next()) {
     Version version(path.BaseName().MaybeAsASCII());
@@ -77,7 +80,7 @@
         base::PathExists(path.Append(kSwiftShaderEglName)) &&
         base::PathExists(path.Append(kSwiftShaderGlesName))) {
       if (found && older_dirs)
-          older_dirs->push_back(*result);
+        older_dirs->push_back(*result);
       *latest = version;
       *result = path;
       found = true;
@@ -113,7 +116,8 @@
 };
 
 SwiftShaderComponentInstaller::SwiftShaderComponentInstaller(
-    const Version& version) : current_version_(version) {
+    const Version& version)
+    : current_version_(version) {
   DCHECK(version.IsValid());
 }
 
@@ -147,13 +151,15 @@
     return false;
   // Installation is done. Now tell the rest of chrome.
   current_version_ = version;
-  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-      base::Bind(&RegisterSwiftShaderWithChrome, path));
+  BrowserThread::PostTask(BrowserThread::UI,
+                          FROM_HERE,
+                          base::Bind(&RegisterSwiftShaderWithChrome, path));
   return true;
 }
 
 bool SwiftShaderComponentInstaller::GetInstalledFile(
-    const std::string& file, base::FilePath* installed_file) {
+    const std::string& file,
+    base::FilePath* installed_file) {
   return false;
 }
 
@@ -181,12 +187,11 @@
   ComponentUpdateService* cus_;
 };
 
-UpdateChecker::UpdateChecker(ComponentUpdateService* cus)
-  : cus_(cus) {
+UpdateChecker::UpdateChecker(ComponentUpdateService* cus) : cus_(cus) {
 }
 
 void UpdateChecker::OnGpuInfoUpdate() {
-  GpuDataManager *gpu_data_manager = GpuDataManager::GetInstance();
+  GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance();
 
   if (!gpu_data_manager->GpuAccessAllowed(NULL) ||
       gpu_data_manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL) ||
@@ -198,7 +203,9 @@
     Version version(kNullVersion);
     GetLatestSwiftShaderDirectory(&path, &version, NULL);
 
-    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+    BrowserThread::PostTask(
+        BrowserThread::UI,
+        FROM_HERE,
         base::Bind(&FinishSwiftShaderUpdateRegistration, cus_, version));
   }
 }
@@ -220,10 +227,11 @@
   Version version(kNullVersion);
   std::vector<base::FilePath> older_dirs;
   if (GetLatestSwiftShaderDirectory(&path, &version, &older_dirs))
-    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-        base::Bind(&RegisterSwiftShaderWithChrome, path));
+    BrowserThread::PostTask(BrowserThread::UI,
+                            FROM_HERE,
+                            base::Bind(&RegisterSwiftShaderWithChrome, path));
 
-  UpdateChecker *update_checker = new UpdateChecker(cus);
+  UpdateChecker* update_checker = new UpdateChecker(cus);
   GpuDataManager::GetInstance()->AddObserver(update_checker);
   update_checker->OnGpuInfoUpdate();
   // We leak update_checker here, because it has to stick around for the life
@@ -231,7 +239,8 @@
 
   // Remove older versions of SwiftShader.
   for (std::vector<base::FilePath>::iterator iter = older_dirs.begin();
-       iter != older_dirs.end(); ++iter) {
+       iter != older_dirs.end();
+       ++iter) {
     base::DeleteFile(*iter, true);
   }
 }
@@ -246,10 +255,10 @@
 
   if (!cpu.has_sse2())
     return;
-  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
-      base::Bind(&RegisterSwiftShaderPath, cus));
+  BrowserThread::PostTask(BrowserThread::FILE,
+                          FROM_HERE,
+                          base::Bind(&RegisterSwiftShaderPath, cus));
 #endif
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/test/component_installers_unittest.cc b/chrome/browser/component_updater/test/component_installers_unittest.cc
index 2e7e794..bb481b2 100644
--- a/chrome/browser/component_updater/test/component_installers_unittest.cc
+++ b/chrome/browser/component_updater/test/component_installers_unittest.cc
@@ -38,7 +38,7 @@
     FILE_PATH_LITERAL("components/flapper/NONEXISTENT");
 #endif
 #endif
-}
+}  // namespace
 
 // TODO(jschuh): Get Pepper Flash supported on Win64 build.
 // http://crbug.com/179716
@@ -86,4 +86,3 @@
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/test/component_patcher_unittest.cc b/chrome/browser/component_updater/test/component_patcher_unittest.cc
index 8769545..d220d9d 100644
--- a/chrome/browser/component_updater/test/component_patcher_unittest.cc
+++ b/chrome/browser/component_updater/test/component_patcher_unittest.cc
@@ -38,8 +38,7 @@
   DISALLOW_COPY_AND_ASSIGN(TestCallback);
 };
 
-TestCallback::TestCallback()
-    : error_(-1), extra_code_(-1), called_(false) {
+TestCallback::TestCallback() : error_(-1), extra_code_(-1), called_(false) {
 }
 
 void TestCallback::Set(component_updater::ComponentUnpacker::Error error,
@@ -142,10 +141,9 @@
   EXPECT_TRUE(base::CopyFile(
       test_file("binary_input.bin"),
       installed_dir_.path().Append(FILE_PATH_LITERAL("binary_input.bin"))));
-  EXPECT_TRUE(base::CopyFile(
-      test_file("binary_courgette_patch.bin"),
-      input_dir_.path().Append(
-          FILE_PATH_LITERAL("binary_courgette_patch.bin"))));
+  EXPECT_TRUE(base::CopyFile(test_file("binary_courgette_patch.bin"),
+                             input_dir_.path().Append(FILE_PATH_LITERAL(
+                                 "binary_courgette_patch.bin"))));
 
   scoped_ptr<base::DictionaryValue> command_args(new base::DictionaryValue());
   command_args->SetString("output", "output.bin");
diff --git a/chrome/browser/component_updater/test/component_updater_ping_manager_unittest.cc b/chrome/browser/component_updater/test/component_updater_ping_manager_unittest.cc
index da693dd..a7b9aed 100644
--- a/chrome/browser/component_updater/test/component_updater_ping_manager_unittest.cc
+++ b/chrome/browser/component_updater/test/component_updater_ping_manager_unittest.cc
@@ -25,9 +25,9 @@
 
   void RunThreadsUntilIdle();
 
- // Overrides from testing::Test.
- virtual void SetUp() OVERRIDE;
- virtual void TearDown() OVERRIDE;
+  // Overrides from testing::Test.
+  virtual void SetUp() OVERRIDE;
+  virtual void TearDown() OVERRIDE;
 
  protected:
   scoped_ptr<PingManager> ping_manager_;
@@ -37,7 +37,6 @@
   content::TestBrowserThreadBundle thread_bundle_;
 };
 
-
 ComponentUpdaterPingManagerTest::ComponentUpdaterPingManagerTest()
     : context_(new net::TestURLRequestContextGetter(
           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))),
@@ -49,8 +48,8 @@
 }
 
 void ComponentUpdaterPingManagerTest::SetUp() {
-  ping_manager_.reset(new PingManager(
-      GURL("http://localhost2/update2"), context_));
+  ping_manager_.reset(
+      new PingManager(GURL("http://localhost2/update2"), context_));
 }
 
 void ComponentUpdaterPingManagerTest::TearDown() {
@@ -79,9 +78,10 @@
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
-  EXPECT_NE(string::npos, interceptor->GetRequests()[0].find(
-      "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
-      "<event eventtype=\"3\" eventresult=\"1\"/></app>"))
+  EXPECT_NE(string::npos,
+            interceptor->GetRequests()[0].find(
+                "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
+                "<event eventtype=\"3\" eventresult=\"1\"/></app>"))
       << interceptor->GetRequestsAsString();
   interceptor->Reset();
 
@@ -96,9 +96,10 @@
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
-  EXPECT_NE(string::npos, interceptor->GetRequests()[0].find(
-      "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
-      "<event eventtype=\"3\" eventresult=\"0\"/></app>"))
+  EXPECT_NE(string::npos,
+            interceptor->GetRequests()[0].find(
+                "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
+                "<event eventtype=\"3\" eventresult=\"0\"/></app>"))
       << interceptor->GetRequestsAsString();
   interceptor->Reset();
 
@@ -123,12 +124,14 @@
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
-  EXPECT_NE(string::npos, interceptor->GetRequests()[0].find(
-      "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
-      "<event eventtype=\"3\" eventresult=\"0\" errorcat=\"1\" "
-      "errorcode=\"2\" extracode1=\"-1\" diffresult=\"0\" differrorcat=\"10\" "
-      "differrorcode=\"20\" diffextracode1=\"-10\" "
-      "previousfp=\"prev fp\" nextfp=\"next fp\"/></app>"))
+  EXPECT_NE(string::npos,
+            interceptor->GetRequests()[0].find(
+                "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
+                "<event eventtype=\"3\" eventresult=\"0\" errorcat=\"1\" "
+                "errorcode=\"2\" extracode1=\"-1\" diffresult=\"0\" "
+                "differrorcat=\"10\" "
+                "differrorcode=\"20\" diffextracode1=\"-10\" "
+                "previousfp=\"prev fp\" nextfp=\"next fp\"/></app>"))
       << interceptor->GetRequestsAsString();
   interceptor->Reset();
 
@@ -143,8 +146,8 @@
   download_metrics.url = GURL("http://host1/path1");
   download_metrics.downloader = CrxDownloader::DownloadMetrics::kUrlFetcher;
   download_metrics.error = -1;
-  download_metrics.bytes_downloaded = 123;
-  download_metrics.bytes_total = 456;
+  download_metrics.downloaded_bytes = 123;
+  download_metrics.total_bytes = 456;
   download_metrics.download_time_ms = 987;
   item.download_metrics.push_back(download_metrics);
 
@@ -152,8 +155,8 @@
   download_metrics.url = GURL("http://host2/path2");
   download_metrics.downloader = CrxDownloader::DownloadMetrics::kBits;
   download_metrics.error = 0;
-  download_metrics.bytes_downloaded = 1230;
-  download_metrics.bytes_total = 4560;
+  download_metrics.downloaded_bytes = 1230;
+  download_metrics.total_bytes = 4560;
   download_metrics.download_time_ms = 9870;
   item.download_metrics.push_back(download_metrics);
 
@@ -161,18 +164,19 @@
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(1, interceptor->GetCount()) << interceptor->GetRequestsAsString();
-  EXPECT_NE(string::npos, interceptor->GetRequests()[0].find(
-      "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
-      "<event eventtype=\"3\" eventresult=\"1\"/>"
-      "<event eventtype=\"14\" eventresult=\"0\" downloader=\"direct\" "
-      "errorcode=\"-1\" url=\"http://host1/path1\" downloaded=\"123\" "
-      "total=\"456\" download_time_ms=\"987\"/>"
-      "<event eventtype=\"14\" eventresult=\"1\" downloader=\"bits\" "
-      "url=\"http://host2/path2\" downloaded=\"1230\" total=\"4560\" "
-      "download_time_ms=\"9870\"/></app>"))
+  EXPECT_NE(
+      string::npos,
+      interceptor->GetRequests()[0].find(
+          "<app appid=\"abc\" version=\"1.0\" nextversion=\"2.0\">"
+          "<event eventtype=\"3\" eventresult=\"1\"/>"
+          "<event eventtype=\"14\" eventresult=\"0\" downloader=\"direct\" "
+          "errorcode=\"-1\" url=\"http://host1/path1\" downloaded=\"123\" "
+          "total=\"456\" download_time_ms=\"987\"/>"
+          "<event eventtype=\"14\" eventresult=\"1\" downloader=\"bits\" "
+          "url=\"http://host2/path2\" downloaded=\"1230\" total=\"4560\" "
+          "download_time_ms=\"9870\"/></app>"))
       << interceptor->GetRequestsAsString();
   interceptor->Reset();
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/test/component_updater_service_unittest.cc b/chrome/browser/component_updater/test/component_updater_service_unittest.cc
index 86fc313..b58905b 100644
--- a/chrome/browser/component_updater/test/component_updater_service_unittest.cc
+++ b/chrome/browser/component_updater/test/component_updater_service_unittest.cc
@@ -26,14 +26,15 @@
 using content::BrowserThread;
 
 using ::testing::_;
+using ::testing::AnyNumber;
 using ::testing::InSequence;
 using ::testing::Mock;
 
 namespace component_updater {
 
-#define POST_INTERCEPT_SCHEME    "https"
-#define POST_INTERCEPT_HOSTNAME  "localhost2"
-#define POST_INTERCEPT_PATH      "/update2"
+#define POST_INTERCEPT_SCHEME "https"
+#define POST_INTERCEPT_HOSTNAME "localhost2"
+#define POST_INTERCEPT_PATH "/update2"
 
 MockServiceObserver::MockServiceObserver() {
 }
@@ -58,7 +59,9 @@
 TestConfigurator::~TestConfigurator() {
 }
 
-int TestConfigurator::InitialDelay() { return initial_time_; }
+int TestConfigurator::InitialDelay() {
+  return initial_time_;
+}
 
 int TestConfigurator::NextCheckDelay() {
   // This is called when a new full cycle of checking for updates is going
@@ -89,24 +92,30 @@
 }
 
 GURL TestConfigurator::UpdateUrl() {
-  return GURL(POST_INTERCEPT_SCHEME "://"
-              POST_INTERCEPT_HOSTNAME POST_INTERCEPT_PATH);
+  return GURL(POST_INTERCEPT_SCHEME
+              "://" POST_INTERCEPT_HOSTNAME POST_INTERCEPT_PATH);
 }
 
 GURL TestConfigurator::PingUrl() {
   return UpdateUrl();
 }
 
-std::string TestConfigurator::ExtraRequestParams() { return "extra=\"foo\""; }
+std::string TestConfigurator::ExtraRequestParams() {
+  return "extra=\"foo\"";
+}
 
-size_t TestConfigurator::UrlSizeLimit() { return 256; }
+size_t TestConfigurator::UrlSizeLimit() {
+  return 256;
+}
 
 net::URLRequestContextGetter* TestConfigurator::RequestContext() {
   return context_.get();
 }
 
 // Don't use the utility process to run code out-of-process.
-bool TestConfigurator::InProcess() { return true; }
+bool TestConfigurator::InProcess() {
+  return true;
+}
 
 bool TestConfigurator::DeltasEnabled() const {
   return true;
@@ -117,7 +126,9 @@
 }
 
 // Set how many update checks are called, the default value is just once.
-void TestConfigurator::SetLoopCount(int times) { times_ = times; }
+void TestConfigurator::SetLoopCount(int times) {
+  times_ = times;
+}
 
 void TestConfigurator::SetRecheckTime(int seconds) {
   recheck_time_ = seconds;
@@ -141,13 +152,15 @@
 
 InterceptorFactory::InterceptorFactory()
     : URLRequestPostInterceptorFactory(POST_INTERCEPT_SCHEME,
-                                       POST_INTERCEPT_HOSTNAME) {}
+                                       POST_INTERCEPT_HOSTNAME) {
+}
 
-InterceptorFactory::~InterceptorFactory() {}
+InterceptorFactory::~InterceptorFactory() {
+}
 
 URLRequestPostInterceptor* InterceptorFactory::CreateInterceptor() {
   return URLRequestPostInterceptorFactory::CreateInterceptor(
-    base::FilePath::FromUTF8Unsafe(POST_INTERCEPT_PATH));
+      base::FilePath::FromUTF8Unsafe(POST_INTERCEPT_PATH));
 }
 
 ComponentUpdaterTest::ComponentUpdaterTest()
@@ -186,7 +199,7 @@
   return component_updater_.get();
 }
 
-  // Makes the full path to a component updater test file.
+// Makes the full path to a component updater test file.
 const base::FilePath ComponentUpdaterTest::test_file(const char* file) {
   return test_data_dir_.AppendASCII(file);
 }
@@ -232,7 +245,8 @@
 }
 
 ComponentUpdateService::Status OnDemandTester::OnDemand(
-    ComponentUpdateService* cus, const std::string& component_id) {
+    ComponentUpdateService* cus,
+    const std::string& component_id) {
   return cus->OnDemandUpdate(component_id);
 }
 
@@ -258,28 +272,26 @@
 
   EXPECT_CALL(observer,
               OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-              .Times(1);
+      .Times(1);
   EXPECT_CALL(observer,
               OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-              .Times(2);
+      .Times(2);
   EXPECT_CALL(observer,
               OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                       "abagagagagagagagagagagagagagagag"))
-              .Times(2);
+      .Times(2);
 
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
 
   TestInstaller installer;
   CrxComponent com;
   component_updater()->AddObserver(&observer);
-  EXPECT_EQ(ComponentUpdateService::kOk,
-            RegisterComponent(&com,
-                              kTestComponent_abag,
-                              Version("1.1"),
-                              &installer));
+  EXPECT_EQ(
+      ComponentUpdateService::kOk,
+      RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
 
   // We loop twice, but there are no updates so we expect two sleep messages.
   test_configurator()->SetLoopCount(2);
@@ -295,35 +307,38 @@
       << post_interceptor_->GetRequestsAsString();
   EXPECT_EQ(2, post_interceptor_->GetCount())
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find(
-      "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[1].find(
+          "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
 
   component_updater()->Stop();
 
   // Loop twice again but this case we simulate a server error by returning
   // an empty file. Expect the behavior of the service to be the same as before.
-  EXPECT_CALL(observer,
-              OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-              .Times(1);
+  EXPECT_CALL(observer, OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
+      .Times(1);
   EXPECT_CALL(observer,
               OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-              .Times(2);
+      .Times(2);
   EXPECT_CALL(observer,
               OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                       "abagagagagagagagagagagagagagagag"))
-              .Times(2);
+      .Times(2);
 
   post_interceptor_->Reset();
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_empty")));
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_empty")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
 
   test_configurator()->SetLoopCount(2);
   component_updater()->Start();
@@ -336,13 +351,17 @@
       << post_interceptor_->GetRequestsAsString();
   EXPECT_EQ(2, post_interceptor_->GetCount())
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find(
-      "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[1].find(
+          "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"1.1\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
 
   component_updater()->Stop();
@@ -363,44 +382,48 @@
     InSequence seq;
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
+    EXPECT_CALL(observer,
+                OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
+                        "jebgalgnebhfojomionfpkfelancnnkf"))
+                .Times(AnyNumber());
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATED,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
   }
 
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
   EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
 
   get_interceptor_->SetResponse(
       GURL(expected_crx_url),
@@ -433,33 +456,45 @@
   // Expect one component download.
   EXPECT_EQ(1, get_interceptor_->GetHitCount());
 
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
 
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
-      "version=\"0.9\" nextversion=\"1.0\">"
-      "<event eventtype=\"3\" eventresult=\"1\"/>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[1].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+          "version=\"0.9\" nextversion=\"1.0\">"
+          "<event eventtype=\"3\" eventresult=\"1\"/>"))
       << post_interceptor_->GetRequestsAsString();
 
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[2].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">"
-      "<updatecheck /></app>"));
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[2].find(
-      "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[2].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">"
+          "<updatecheck /></app>"));
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[2].find(
+          "<app appid=\"abagagagagagagagagagagagagagagag\" version=\"2.2\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
 
   // Test the protocol version is correct and the extra request attributes
   // are included in the request.
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "request protocol=\"3.0\" extra=\"foo\""))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "request protocol=\"3.0\" extra=\"foo\""))
       << post_interceptor_->GetRequestsAsString();
 
   // Tokenize the request string to look for specific attributes, which
@@ -494,8 +529,8 @@
 // particular there should not be an install because the minimum product
 // version is much higher than of chrome.
 TEST_F(ComponentUpdaterTest, ProdVersionCheck) {
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_2.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_2.xml")));
 
   get_interceptor_->SetResponse(
       GURL(expected_crx_url),
@@ -536,44 +571,48 @@
     InSequence seq;
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
+    EXPECT_CALL(observer,
+                OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
+                        "jebgalgnebhfojomionfpkfelancnnkf"))
+                .Times(AnyNumber());
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATED,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
   }
 
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_empty")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
 
   get_interceptor_->SetResponse(
       GURL(expected_crx_url),
@@ -603,13 +642,13 @@
 
   // Update after an on-demand check is issued.
   post_interceptor_->Reset();
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
   EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
 
-  EXPECT_EQ(ComponentUpdateService::kOk,
-            OnDemandTester::OnDemand(component_updater(),
-                                     GetCrxComponentID(com2)));
+  EXPECT_EQ(
+      ComponentUpdateService::kOk,
+      OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
   test_configurator()->SetLoopCount(1);
   component_updater()->Start();
   RunThreads();
@@ -628,25 +667,31 @@
 
   // Expect the update check to contain an "ondemand" request for the
   // second component (com2) and a normal request for the other component.
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"abagagagagagagagagagagagagagagag\" "
-      "version=\"2.2\"><updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"abagagagagagagagagagagagagagagag\" "
+          "version=\"2.2\"><updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
-      "version=\"0.9\" installsource=\"ondemand\"><updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+          "version=\"0.9\" installsource=\"ondemand\"><updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
-      "version=\"0.9\" nextversion=\"1.0\">"
-      "<event eventtype=\"3\" eventresult=\"1\"/>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[1].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+          "version=\"0.9\" nextversion=\"1.0\">"
+          "<event eventtype=\"3\" eventresult=\"1\"/>"))
       << post_interceptor_->GetRequestsAsString();
 
   // Also check what happens if previous check too soon.
   test_configurator()->SetOnDemandTime(60 * 60);
-  EXPECT_EQ(ComponentUpdateService::kError,
-            OnDemandTester::OnDemand(component_updater(),
-                                     GetCrxComponentID(com2)));
+  EXPECT_EQ(
+      ComponentUpdateService::kError,
+      OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
   // Okay, now reset to 0 for the other tests.
   test_configurator()->SetOnDemandTime(0);
   component_updater()->Stop();
@@ -658,30 +703,30 @@
     InSequence seq;
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
   }
 
   // No update: error from no server response
   post_interceptor_->Reset();
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_empty")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_empty")));
 
   test_configurator()->SetLoopCount(1);
   component_updater()->Start();
-  EXPECT_EQ(ComponentUpdateService::kOk,
-            OnDemandTester::OnDemand(component_updater(),
-                                     GetCrxComponentID(com2)));
+  EXPECT_EQ(
+      ComponentUpdateService::kOk,
+      OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
   RunThreads();
   component_updater()->Stop();
 
@@ -696,29 +741,29 @@
     InSequence seq;
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
   }
 
   post_interceptor_->Reset();
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
 
   test_configurator()->SetLoopCount(1);
   component_updater()->Start();
-  EXPECT_EQ(ComponentUpdateService::kOk,
-            OnDemandTester::OnDemand(component_updater(),
-                                     GetCrxComponentID(com2)));
+  EXPECT_EQ(
+      ComponentUpdateService::kOk,
+      OnDemandTester::OnDemand(component_updater(), GetCrxComponentID(com2)));
   RunThreads();
 
   EXPECT_EQ(1, post_interceptor_->GetHitCount())
@@ -737,44 +782,48 @@
     InSequence seq;
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATE_FOUND,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
+    EXPECT_CALL(observer,
+                OnEvent(ServiceObserver::COMPONENT_UPDATE_DOWNLOADING,
+                        "jebgalgnebhfojomionfpkfelancnnkf"))
+                .Times(AnyNumber());
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATE_READY,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATED,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
   }
 
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
   EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
 
   get_interceptor_->SetResponse(
       GURL(expected_crx_url),
@@ -801,21 +850,27 @@
   EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count());
 
   EXPECT_EQ(3, post_interceptor_->GetHitCount())
-        << post_interceptor_->GetRequestsAsString();
+      << post_interceptor_->GetRequestsAsString();
   EXPECT_EQ(1, get_interceptor_->GetHitCount());
 
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
-      "version=\"0.9\" nextversion=\"1.0\">"
-      "<event eventtype=\"3\" eventresult=\"1\"/>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[1].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+          "version=\"0.9\" nextversion=\"1.0\">"
+          "<event eventtype=\"3\" eventresult=\"1\"/>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[2].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[2].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"1.0\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
 
   component_updater()->Stop();
@@ -826,30 +881,28 @@
     InSequence seq;
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "jebgalgnebhfojomionfpkfelancnnkf"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
   }
 
   post_interceptor_->Reset();
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
 
   TestInstaller installer3;
   EXPECT_EQ(ComponentUpdateService::kReplaced,
-            RegisterComponent(&com1,
-                              kTestComponent_jebg,
-                              Version("2.2"),
-                              &installer3));
+            RegisterComponent(
+                &com1, kTestComponent_jebg, Version("2.2"), &installer3));
 
   // Loop once just to notice the check happening with the re-register version.
   test_configurator()->SetLoopCount(1);
@@ -864,13 +917,15 @@
 
   // One update check and no additional pings are expected.
   EXPECT_EQ(1, post_interceptor_->GetHitCount())
-        << post_interceptor_->GetRequestsAsString();
+      << post_interceptor_->GetRequestsAsString();
   EXPECT_EQ(1, post_interceptor_->GetCount())
-        << post_interceptor_->GetRequestsAsString();
+      << post_interceptor_->GetRequestsAsString();
 
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"2.2\">"
-      "<updatecheck /></app>"));
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"2.2\">"
+          "<updatecheck /></app>"));
 
   component_updater()->Stop();
 }
@@ -887,14 +942,17 @@
 // There should be two pings, one for each update. The second will bear a
 // diffresult=1, while the first will not.
 TEST_F(ComponentUpdaterTest, DifferentialUpdate) {
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_diff_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"),
+      test_file("updatecheck_diff_reply_1.xml")));
   EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_diff_reply_2.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"),
+      test_file("updatecheck_diff_reply_2.xml")));
   EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_diff_reply_3.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"),
+      test_file("updatecheck_diff_reply_3.xml")));
 
   get_interceptor_->SetResponse(
       GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"),
@@ -921,28 +979,38 @@
       << post_interceptor_->GetRequestsAsString();
   EXPECT_EQ(2, get_interceptor_->GetHitCount());
 
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
-      "version=\"0.0\" nextversion=\"1.0\">"
-      "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[1].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
+          "version=\"0.0\" nextversion=\"1.0\">"
+          "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[2].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
-      "<updatecheck /><packages><package fp=\"1\"/></packages></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[2].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
+          "<updatecheck /><packages><package fp=\"1\"/></packages></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[3].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
-      "version=\"1.0\" nextversion=\"2.0\">"
-      "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"1\" "
-      "previousfp=\"1\" nextfp=\"22\"/>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[3].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
+          "version=\"1.0\" nextversion=\"2.0\">"
+          "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"1\" "
+          "previousfp=\"1\" nextfp=\"22\"/>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[4].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
-      "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[4].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
+          "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
       << post_interceptor_->GetRequestsAsString();
   component_updater()->Stop();
 }
@@ -964,18 +1032,20 @@
 #define MAYBE_DifferentialUpdateFails DifferentialUpdateFails
 #endif
 TEST_F(ComponentUpdaterTest, MAYBE_DifferentialUpdateFails) {
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_diff_reply_2.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"),
+      test_file("updatecheck_diff_reply_2.xml")));
   EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_diff_reply_3.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"),
+      test_file("updatecheck_diff_reply_3.xml")));
 
   get_interceptor_->SetResponse(
       GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"),
       test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"));
   get_interceptor_->SetResponse(
       GURL("http://localhost/download/"
-           "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"),
+          "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"),
       test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"));
   get_interceptor_->SetResponse(
       GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"),
@@ -999,19 +1069,25 @@
       << post_interceptor_->GetRequestsAsString();
   EXPECT_EQ(2, get_interceptor_->GetHitCount());
 
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
-      "version=\"1.0\" nextversion=\"2.0\">"
-      "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"0\" "
-      "differrorcat=\"2\" differrorcode=\"16\" nextfp=\"22\"/>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[1].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
+          "version=\"1.0\" nextversion=\"2.0\">"
+          "<event eventtype=\"3\" eventresult=\"1\" diffresult=\"0\" "
+          "differrorcat=\"2\" differrorcode=\"16\" nextfp=\"22\"/>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[2].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
-      "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[2].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
+          "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
       << post_interceptor_->GetRequestsAsString();
 
   component_updater()->Stop();
@@ -1024,7 +1100,7 @@
 #define MAYBE_CheckFailedInstallPing CheckFailedInstallPing
 #endif
 // Verify that a failed installation causes an install failure ping.
-  TEST_F(ComponentUpdaterTest, MAYBE_CheckFailedInstallPing) {
+TEST_F(ComponentUpdaterTest, MAYBE_CheckFailedInstallPing) {
   // This test installer reports installation failure.
   class : public TestInstaller {
     virtual bool Install(const base::DictionaryValue& manifest,
@@ -1035,11 +1111,11 @@
     }
   } installer;
 
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
   EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
   EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
   get_interceptor_->SetResponse(
       GURL(expected_crx_url),
@@ -1059,33 +1135,42 @@
       << post_interceptor_->GetRequestsAsString();
   EXPECT_EQ(2, get_interceptor_->GetHitCount());
 
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
-      "version=\"0.9\" nextversion=\"1.0\">"
-      "<event eventtype=\"3\" eventresult=\"0\" "
-      "errorcat=\"3\" errorcode=\"9\"/>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[1].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+          "version=\"0.9\" nextversion=\"1.0\">"
+          "<event eventtype=\"3\" eventresult=\"0\" "
+          "errorcat=\"3\" errorcode=\"9\"/>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[2].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[2].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[3].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
-      "version=\"0.9\" nextversion=\"1.0\">"
-      "<event eventtype=\"3\" eventresult=\"0\" "
-      "errorcat=\"3\" errorcode=\"9\"/>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[3].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" "
+          "version=\"0.9\" nextversion=\"1.0\">"
+          "<event eventtype=\"3\" eventresult=\"0\" "
+          "errorcat=\"3\" errorcode=\"9\"/>"))
       << post_interceptor_->GetRequestsAsString();
 
   // Loop once more, but expect no ping because a noupdate response is issued.
   // This is necessary to clear out the fire-and-forget ping from the previous
   // iteration.
   post_interceptor_->Reset();
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_noupdate.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"),
+      test_file("updatecheck_reply_noupdate.xml")));
 
   test_configurator()->SetLoopCount(1);
   component_updater()->Start();
@@ -1099,9 +1184,11 @@
   EXPECT_EQ(1, post_interceptor_->GetCount())
       << post_interceptor_->GetRequestsAsString();
 
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
 
   component_updater()->Stop();
@@ -1111,14 +1198,17 @@
 // ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx contains an incorrect
 // patching instruction that should fail.
 TEST_F(ComponentUpdaterTest, DifferentialUpdateFailErrorcode) {
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_diff_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"),
+      test_file("updatecheck_diff_reply_1.xml")));
   EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_diff_reply_2.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"),
+      test_file("updatecheck_diff_reply_2.xml")));
   EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch("event")));
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_diff_reply_3.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"),
+      test_file("updatecheck_diff_reply_3.xml")));
 
   get_interceptor_->SetResponse(
       GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"),
@@ -1153,30 +1243,40 @@
       << post_interceptor_->GetRequestsAsString();
   EXPECT_EQ(3, get_interceptor_->GetHitCount());
 
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">"
-      "<updatecheck /></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"0.0\">"
+          "<updatecheck /></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[1].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
-      "version=\"0.0\" nextversion=\"1.0\">"
-      "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[1].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
+          "version=\"0.0\" nextversion=\"1.0\">"
+          "<event eventtype=\"3\" eventresult=\"1\" nextfp=\"1\"/>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[2].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
-      "<updatecheck /><packages><package fp=\"1\"/></packages></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[2].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"1.0\">"
+          "<updatecheck /><packages><package fp=\"1\"/></packages></app>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[3].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
-      "version=\"1.0\" nextversion=\"2.0\">"
-      "<event eventtype=\"3\" eventresult=\"1\" "
-      "diffresult=\"0\" differrorcat=\"2\" "
-      "differrorcode=\"14\" diffextracode1=\"305\" "
-      "previousfp=\"1\" nextfp=\"22\"/>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[3].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" "
+          "version=\"1.0\" nextversion=\"2.0\">"
+          "<event eventtype=\"3\" eventresult=\"1\" "
+          "diffresult=\"0\" differrorcat=\"2\" "
+          "differrorcode=\"14\" diffextracode1=\"305\" "
+          "previousfp=\"1\" nextfp=\"22\"/>"))
       << post_interceptor_->GetRequestsAsString();
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[4].find(
-      "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
-      "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[4].find(
+          "<app appid=\"ihfokbkgjpifnbbojhneepfflplebdkc\" version=\"2.0\">"
+          "<updatecheck /><packages><package fp=\"22\"/></packages></app>"))
       << post_interceptor_->GetRequestsAsString();
 }
 
@@ -1189,13 +1289,11 @@
     ComponentUpdateService* cus,
     TestResourceController* controller,
     const char* crx_id) {
-
   net::TestURLRequestContext context;
-  net::TestURLRequest url_request(
-      GURL("http://foo.example.com/thing.bin"),
-      net::DEFAULT_PRIORITY,
-      NULL,
-      &context);
+  net::TestURLRequest url_request(GURL("http://foo.example.com/thing.bin"),
+                                  net::DEFAULT_PRIORITY,
+                                  NULL,
+                                  &context);
 
   content::ResourceThrottle* rt =
       cus->GetOnDemandResourceThrottle(&url_request, crx_id);
@@ -1204,12 +1302,12 @@
   return rt;
 }
 
-void RequestAndDeleteResourceThrottle(
-    ComponentUpdateService* cus, const char* crx_id) {
+void RequestAndDeleteResourceThrottle(ComponentUpdateService* cus,
+                                      const char* crx_id) {
   // By requesting a throttle and deleting it immediately we ensure that we
   // hit the case where the component updater tries to use the weak
   // pointer to a dead Resource throttle.
-  class  NoCallResourceController : public TestResourceController {
+  class NoCallResourceController : public TestResourceController {
    public:
     virtual ~NoCallResourceController() {}
     virtual void Cancel() OVERRIDE { CHECK(false); }
@@ -1227,27 +1325,25 @@
     InSequence seq;
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
   }
 
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
 
   TestInstaller installer;
   CrxComponent com;
   component_updater()->AddObserver(&observer);
-  EXPECT_EQ(ComponentUpdateService::kOk,
-            RegisterComponent(&com,
-                              kTestComponent_abag,
-                              Version("1.1"),
-                              &installer));
+  EXPECT_EQ(
+      ComponentUpdateService::kOk,
+      RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
   // The following two calls ensure that we don't do an update check via the
   // timer, so the only update check should be the on-demand one.
   test_configurator()->SetInitialDelay(1000000);
@@ -1259,12 +1355,11 @@
 
   EXPECT_EQ(0, post_interceptor_->GetHitCount());
 
-  BrowserThread::PostTask(
-      BrowserThread::IO,
-      FROM_HERE,
-      base::Bind(&RequestAndDeleteResourceThrottle,
-                 component_updater(),
-                 "abagagagagagagagagagagagagagagag"));
+  BrowserThread::PostTask(BrowserThread::IO,
+                          FROM_HERE,
+                          base::Bind(&RequestAndDeleteResourceThrottle,
+                                     component_updater(),
+                                     "abagagagagagagagagagagagagagagag"));
 
   RunThreads();
 
@@ -1275,24 +1370,23 @@
   component_updater()->Stop();
 }
 
-class  CancelResourceController: public TestResourceController {
-  public:
+class CancelResourceController : public TestResourceController {
+ public:
   CancelResourceController() : throttle_(NULL), resume_called_(0) {}
   virtual ~CancelResourceController() {
     // Check that the throttle has been resumed by the time we
     // exit the test.
-    CHECK(resume_called_ == 1);
+    CHECK_EQ(1, resume_called_);
     delete throttle_;
   }
   virtual void Cancel() OVERRIDE { CHECK(false); }
   virtual void CancelAndIgnore() OVERRIDE { CHECK(false); }
   virtual void CancelWithError(int error_code) OVERRIDE { CHECK(false); }
   virtual void Resume() OVERRIDE {
-    BrowserThread::PostTask(
-        BrowserThread::IO,
-        FROM_HERE,
-        base::Bind(&CancelResourceController::ResumeCalled,
-                    base::Unretained(this)));
+    BrowserThread::PostTask(BrowserThread::IO,
+                            FROM_HERE,
+                            base::Bind(&CancelResourceController::ResumeCalled,
+                                       base::Unretained(this)));
   }
   virtual void SetThrottle(content::ResourceThrottle* throttle) OVERRIDE {
     throttle_ = throttle;
@@ -1303,7 +1397,7 @@
     CHECK(defer);
   }
 
-  private:
+ private:
   void ResumeCalled() { ++resume_called_; }
 
   content::ResourceThrottle* throttle_;
@@ -1316,27 +1410,25 @@
     InSequence seq;
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
   }
 
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
 
   TestInstaller installer;
   CrxComponent com;
   component_updater()->AddObserver(&observer);
-  EXPECT_EQ(ComponentUpdateService::kOk,
-            RegisterComponent(&com,
-                              kTestComponent_abag,
-                              Version("1.1"),
-                              &installer));
+  EXPECT_EQ(
+      ComponentUpdateService::kOk,
+      RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
   // The following two calls ensure that we don't do an update check via the
   // timer, so the only update check should be the on-demand one.
   test_configurator()->SetInitialDelay(1000000);
@@ -1376,39 +1468,37 @@
     InSequence seq;
     EXPECT_CALL(observer1,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer2,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer1,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer2,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer1,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer2,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
   }
 
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
 
   component_updater()->AddObserver(&observer1);
   component_updater()->AddObserver(&observer2);
 
   TestInstaller installer;
   CrxComponent com;
-  EXPECT_EQ(ComponentUpdateService::kOk,
-            RegisterComponent(&com,
-                              kTestComponent_abag,
-                              Version("1.1"),
-                              &installer));
+  EXPECT_EQ(
+      ComponentUpdateService::kOk,
+      RegisterComponent(&com, kTestComponent_abag, Version("1.1"), &installer));
   test_configurator()->SetLoopCount(1);
   component_updater()->Start();
   RunThreads();
@@ -1421,14 +1511,14 @@
     InSequence seq;
     EXPECT_CALL(observer2,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_STARTED, ""))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer2,
                 OnEvent(ServiceObserver::COMPONENT_NOT_UPDATED,
                         "abagagagagagagagagagagagagagagag"))
-                .Times(1);
+        .Times(1);
     EXPECT_CALL(observer2,
                 OnEvent(ServiceObserver::COMPONENT_UPDATER_SLEEPING, ""))
-                .Times(1);
+        .Times(1);
   }
 
   component_updater()->RemoveObserver(&observer1);
diff --git a/chrome/browser/component_updater/test/component_updater_service_unittest.h b/chrome/browser/component_updater/test/component_updater_service_unittest.h
index 56c1fc6..90e1e45 100644
--- a/chrome/browser/component_updater/test/component_updater_service_unittest.h
+++ b/chrome/browser/component_updater/test/component_updater_service_unittest.h
@@ -47,6 +47,7 @@
  public:
   explicit PartialMatch(const std::string& expected) : expected_(expected) {}
   virtual bool Match(const std::string& actual) const OVERRIDE;
+
  private:
   const std::string expected_;
 
@@ -145,9 +146,10 @@
   void RunThreadsUntilIdle();
 
   scoped_ptr<InterceptorFactory> interceptor_factory_;
-  URLRequestPostInterceptor* post_interceptor_;   // Owned by the factory.
+  URLRequestPostInterceptor* post_interceptor_;  // Owned by the factory.
 
   scoped_ptr<GetInterceptor> get_interceptor_;
+
  private:
   TestConfigurator* test_config_;
   base::FilePath test_data_dir_;
@@ -168,7 +170,8 @@
 class OnDemandTester {
  public:
   static ComponentUpdateService::Status OnDemand(
-      ComponentUpdateService* cus, const std::string& component_id);
+      ComponentUpdateService* cus,
+      const std::string& component_id);
 };
 
 }  // namespace component_updater
diff --git a/chrome/browser/component_updater/test/crx_downloader_unittest.cc b/chrome/browser/component_updater/test/crx_downloader_unittest.cc
index eb5bf3f..1612861 100644
--- a/chrome/browser/component_updater/test/crx_downloader_unittest.cc
+++ b/chrome/browser/component_updater/test/crx_downloader_unittest.cc
@@ -54,16 +54,23 @@
 
   void DownloadComplete(int crx_context, const CrxDownloader::Result& result);
 
+  void DownloadProgress(int crx_context, const CrxDownloader::Result& result);
+
  protected:
   scoped_ptr<CrxDownloader> crx_downloader_;
 
   CrxDownloader::DownloadCallback callback_;
+  CrxDownloader::ProgressCallback progress_callback_;
 
   int crx_context_;
 
   int num_download_complete_calls_;
   CrxDownloader::Result download_complete_result_;
 
+  // These members are updated by DownloadProgress.
+  int num_progress_calls_;
+  CrxDownloader::Result download_progress_result_;
+
   // A magic value for the context to be used in the tests.
   static const int kExpectedContext = 0xaabb;
 
@@ -80,8 +87,12 @@
     : callback_(base::Bind(&CrxDownloaderTest::DownloadComplete,
                            base::Unretained(this),
                            kExpectedContext)),
+      progress_callback_(base::Bind(&CrxDownloaderTest::DownloadProgress,
+                                    base::Unretained(this),
+                                    kExpectedContext)),
       crx_context_(0),
       num_download_complete_calls_(0),
+      num_progress_calls_(0),
       blocking_task_runner_(BrowserThread::GetBlockingPool()->
           GetSequencedTaskRunnerWithShutdownBehavior(
               BrowserThread::GetBlockingPool()->GetSequenceToken(),
@@ -98,13 +109,17 @@
 void CrxDownloaderTest::SetUp() {
   num_download_complete_calls_ = 0;
   download_complete_result_ = CrxDownloader::Result();
+  num_progress_calls_ = 0;
+  download_progress_result_ = CrxDownloader::Result();
   crx_downloader_.reset(CrxDownloader::Create(
-      false,    // Do not use the background downloader in these tests.
+      false,  // Do not use the background downloader in these tests.
       context_.get(),
       blocking_task_runner_));
+  crx_downloader_->set_progress_callback(progress_callback_);
 }
 
 void CrxDownloaderTest::TearDown() {
+  crx_downloader_.reset();
 }
 
 void CrxDownloaderTest::Quit() {
@@ -120,6 +135,12 @@
   Quit();
 }
 
+void CrxDownloaderTest::DownloadProgress(int crx_context,
+                                         const CrxDownloader::Result& result) {
+  ++num_progress_calls_;
+  download_progress_result_ = result;
+}
+
 void CrxDownloaderTest::RunThreads() {
   base::RunLoop runloop;
   quit_closure_ = runloop.QuitClosure();
@@ -146,12 +167,15 @@
   EXPECT_EQ(kExpectedContext, crx_context_);
   EXPECT_EQ(-1, download_complete_result_.error);
   EXPECT_TRUE(download_complete_result_.response.empty());
+  EXPECT_EQ(-1, download_complete_result_.downloaded_bytes);
+  EXPECT_EQ(-1, download_complete_result_.total_bytes);
+  EXPECT_EQ(0, num_progress_calls_);
 }
 
 // Tests that downloading from one url is successful.
 TEST_F(CrxDownloaderTest, OneUrl) {
   const GURL expected_crx_url =
-    GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
+      GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
   GetInterceptor interceptor;
@@ -165,9 +189,15 @@
   EXPECT_EQ(1, num_download_complete_calls_);
   EXPECT_EQ(kExpectedContext, crx_context_);
   EXPECT_EQ(0, download_complete_result_.error);
+  EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
+  EXPECT_EQ(1843, download_complete_result_.total_bytes);
   EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
 
   EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
+
+  EXPECT_LE(1, num_progress_calls_);
+  EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
+  EXPECT_EQ(1843, download_progress_result_.total_bytes);
 }
 
 // Tests that specifying from two urls has no side effects. Expect a successful
@@ -180,7 +210,7 @@
 #endif
 TEST_F(CrxDownloaderTest, MAYBE_TwoUrls) {
   const GURL expected_crx_url =
-    GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
+      GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
   GetInterceptor interceptor;
@@ -198,15 +228,21 @@
   EXPECT_EQ(1, num_download_complete_calls_);
   EXPECT_EQ(kExpectedContext, crx_context_);
   EXPECT_EQ(0, download_complete_result_.error);
+  EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
+  EXPECT_EQ(1843, download_complete_result_.total_bytes);
   EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
 
   EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
+
+  EXPECT_LE(1, num_progress_calls_);
+  EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
+  EXPECT_EQ(1843, download_progress_result_.total_bytes);
 }
 
 // Tests that an invalid host results in a download error.
 TEST_F(CrxDownloaderTest, OneUrl_InvalidHost) {
   const GURL expected_crx_url =
-    GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
+      GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
   GetInterceptor interceptor;
@@ -229,15 +265,14 @@
 // Tests that an invalid path results in a download error.
 TEST_F(CrxDownloaderTest, OneUrl_InvalidPath) {
   const GURL expected_crx_url =
-    GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
+      GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
   GetInterceptor interceptor;
   interceptor.SetResponse(expected_crx_url, test_file);
 
-  crx_downloader_->StartDownloadFromUrl(
-      GURL("http://localhost/no/such/file"),
-      callback_);
+  crx_downloader_->StartDownloadFromUrl(GURL("http://localhost/no/such/file"),
+                                        callback_);
   RunThreads();
 
   EXPECT_EQ(0, interceptor.GetHitCount());
@@ -257,7 +292,7 @@
 #endif
 TEST_F(CrxDownloaderTest, MAYBE_TwoUrls_FirstInvalid) {
   const GURL expected_crx_url =
-    GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
+      GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
   GetInterceptor interceptor;
@@ -275,16 +310,22 @@
   EXPECT_EQ(1, num_download_complete_calls_);
   EXPECT_EQ(kExpectedContext, crx_context_);
   EXPECT_EQ(0, download_complete_result_.error);
+  EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
+  EXPECT_EQ(1843, download_complete_result_.total_bytes);
   EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
 
   EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
+
+  EXPECT_LE(1, num_progress_calls_);
+  EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
+  EXPECT_EQ(1843, download_progress_result_.total_bytes);
 }
 
 // Tests that the download succeeds if the first url is correct and the
 // second bad url does not have a side-effect.
 TEST_F(CrxDownloaderTest, TwoUrls_SecondInvalid) {
   const GURL expected_crx_url =
-    GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
+      GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
   GetInterceptor interceptor;
@@ -302,15 +343,21 @@
   EXPECT_EQ(1, num_download_complete_calls_);
   EXPECT_EQ(kExpectedContext, crx_context_);
   EXPECT_EQ(0, download_complete_result_.error);
+  EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
+  EXPECT_EQ(1843, download_complete_result_.total_bytes);
   EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
 
   EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
+
+  EXPECT_LE(1, num_progress_calls_);
+  EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
+  EXPECT_EQ(1843, download_progress_result_.total_bytes);
 }
 
 // Tests that the download fails if both urls are bad.
 TEST_F(CrxDownloaderTest, TwoUrls_BothInvalid) {
   const GURL expected_crx_url =
-    GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
+      GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
 
   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
   GetInterceptor interceptor;
diff --git a/chrome/browser/component_updater/test/test_installer.cc b/chrome/browser/component_updater/test/test_installer.cc
index 400edca..2f1a7bc 100644
--- a/chrome/browser/component_updater/test/test_installer.cc
+++ b/chrome/browser/component_updater/test/test_installer.cc
@@ -4,14 +4,15 @@
 
 #include "chrome/browser/component_updater/test/test_installer.h"
 
+#include <string>
+
 #include "base/file_util.h"
 #include "base/files/file_path.h"
 #include "base/values.h"
 
 namespace component_updater {
 
-TestInstaller::TestInstaller()
-    : error_(0), install_count_(0) {
+TestInstaller::TestInstaller() : error_(0), install_count_(0) {
 }
 
 void TestInstaller::OnUpdateError(int error) {
@@ -29,10 +30,13 @@
   return false;
 }
 
-int TestInstaller::error() const { return error_; }
+int TestInstaller::error() const {
+  return error_;
+}
 
-int TestInstaller::install_count() const { return install_count_; }
-
+int TestInstaller::install_count() const {
+  return install_count_;
+}
 
 ReadOnlyTestInstaller::ReadOnlyTestInstaller(const base::FilePath& install_dir)
     : install_directory_(install_dir) {
@@ -47,7 +51,6 @@
   return true;
 }
 
-
 VersionedTestInstaller::VersionedTestInstaller() {
   base::CreateNewTempDirectory(FILE_PATH_LITERAL("TEST_"), &install_directory_);
 }
@@ -56,7 +59,6 @@
   base::DeleteFile(install_directory_, true);
 }
 
-
 bool VersionedTestInstaller::Install(const base::DictionaryValue& manifest,
                                      const base::FilePath& unpack_path) {
   std::string version_string;
@@ -82,4 +84,3 @@
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/test/test_installer.h b/chrome/browser/component_updater/test/test_installer.h
index e93eeba..9613953 100644
--- a/chrome/browser/component_updater/test/test_installer.h
+++ b/chrome/browser/component_updater/test/test_installer.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_COMPONENT_UPDATER_TEST_TEST_INSTALLER_H_
 #define CHROME_BROWSER_COMPONENT_UPDATER_TEST_TEST_INSTALLER_H_
 
+#include <string>
+
 #include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "chrome/browser/component_updater/component_updater_service.h"
@@ -56,7 +58,7 @@
 // A VersionedTestInstaller is an installer that installs files into versioned
 // directories (e.g. somedir/25.23.89.141/<files>).
 class VersionedTestInstaller : public TestInstaller {
- public :
+ public:
   explicit VersionedTestInstaller();
 
   virtual ~VersionedTestInstaller();
diff --git a/chrome/browser/component_updater/test/update_checker_unittest.cc b/chrome/browser/component_updater/test/update_checker_unittest.cc
index 09c2b3f..223be81 100644
--- a/chrome/browser/component_updater/test/update_checker_unittest.cc
+++ b/chrome/browser/component_updater/test/update_checker_unittest.cc
@@ -48,9 +48,7 @@
                            const std::string& error_message,
                            const UpdateResponse::Results& results);
 
-  net::URLRequestContextGetter* context() {
-    return context_.get();
-  }
+  net::URLRequestContextGetter* context() { return context_.get(); }
 
  protected:
   void Quit();
@@ -62,7 +60,7 @@
   scoped_ptr<UpdateChecker> update_checker_;
 
   scoped_ptr<InterceptorFactory> interceptor_factory_;
-  URLRequestPostInterceptor* post_interceptor_;   // Owned by the factory.
+  URLRequestPostInterceptor* post_interceptor_;  // Owned by the factory.
 
   int error_;
   std::string error_message_;
@@ -161,14 +159,14 @@
 }
 
 TEST_F(UpdateCheckerTest, UpdateCheckSuccess) {
-  EXPECT_TRUE(post_interceptor_->ExpectRequest(new PartialMatch(
-      "updatecheck"), test_file("updatecheck_reply_1.xml")));
+  EXPECT_TRUE(post_interceptor_->ExpectRequest(
+      new PartialMatch("updatecheck"), test_file("updatecheck_reply_1.xml")));
 
-  update_checker_ = UpdateChecker::Create(
-      GURL("https://localhost2/update2"),
-      context(),
-      base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
-                 base::Unretained(this))).Pass();
+  update_checker_ =
+      UpdateChecker::Create(GURL("https://localhost2/update2"),
+                            context(),
+                            base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
+                                       base::Unretained(this))).Pass();
 
   CrxUpdateItem item(BuildCrxUpdateItem());
   std::vector<CrxUpdateItem*> items_to_check;
@@ -184,11 +182,15 @@
       << post_interceptor_->GetRequestsAsString();
 
   // Sanity check the request.
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "request protocol=\"3.0\" extra=\"params\""));
-  EXPECT_NE(string::npos, post_interceptor_->GetRequests()[0].find(
-      "app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
-      "<updatecheck /><packages><package fp=\"fp1\"/></packages></app>"));
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "request protocol=\"3.0\" extra=\"params\""));
+  EXPECT_NE(
+      string::npos,
+      post_interceptor_->GetRequests()[0].find(
+          "app appid=\"jebgalgnebhfojomionfpkfelancnnkf\" version=\"0.9\">"
+          "<updatecheck /><packages><package fp=\"fp1\"/></packages></app>"));
 
   // Sanity check the arguments of the callback after parsing.
   EXPECT_EQ(0, error_);
@@ -203,15 +205,15 @@
   // Setting this expectation simulates a network error since the
   // file is not found. Since setting the expectation fails, this function
   // owns |request_matcher|.
-  scoped_ptr<PartialMatch> request_matcher( new PartialMatch("updatecheck"));
+  scoped_ptr<PartialMatch> request_matcher(new PartialMatch("updatecheck"));
   EXPECT_FALSE(post_interceptor_->ExpectRequest(request_matcher.get(),
                                                 test_file("no such file")));
 
-  update_checker_ = UpdateChecker::Create(
-      GURL("https://localhost2/update2"),
-      context(),
-      base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
-                 base::Unretained(this))).Pass();
+  update_checker_ =
+      UpdateChecker::Create(GURL("https://localhost2/update2"),
+                            context(),
+                            base::Bind(&UpdateCheckerTest::UpdateCheckComplete,
+                                       base::Unretained(this))).Pass();
 
   CrxUpdateItem item(BuildCrxUpdateItem());
   std::vector<CrxUpdateItem*> items_to_check;
@@ -232,4 +234,3 @@
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/test/update_response_unittest.cc b/chrome/browser/component_updater/test/update_response_unittest.cc
index a881d73..84ad655 100644
--- a/chrome/browser/component_updater/test/update_response_unittest.cc
+++ b/chrome/browser/component_updater/test/update_response_unittest.cc
@@ -10,203 +10,203 @@
 namespace component_updater {
 
 const char* kValidXml =
-"<?xml version='1.0' encoding='UTF-8'?>"
-"<response protocol='3.0'>"
-" <app appid='12345'>"
-"   <updatecheck status='ok'>"
-"     <urls>"
-"       <url codebase='http://example.com/'/>"
-"       <url codebasediff='http://diff.example.com/'/>"
-"     </urls>"
-"     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
-"       <packages>"
-"         <package name='extension_1_2_3_4.crx'/>"
-"       </packages>"
-"     </manifest>"
-"   </updatecheck>"
-" </app>"
-"</response>";
+    "<?xml version='1.0' encoding='UTF-8'?>"
+    "<response protocol='3.0'>"
+    " <app appid='12345'>"
+    "   <updatecheck status='ok'>"
+    "     <urls>"
+    "       <url codebase='http://example.com/'/>"
+    "       <url codebasediff='http://diff.example.com/'/>"
+    "     </urls>"
+    "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
+    "       <packages>"
+    "         <package name='extension_1_2_3_4.crx'/>"
+    "       </packages>"
+    "     </manifest>"
+    "   </updatecheck>"
+    " </app>"
+    "</response>";
 
 const char* valid_xml_with_hash =
-"<?xml version='1.0' encoding='UTF-8'?>"
-"<response protocol='3.0'>"
-" <app appid='12345'>"
-"   <updatecheck status='ok'>"
-"     <urls>"
-"       <url codebase='http://example.com/'/>"
-"     </urls>"
-"     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
-"       <packages>"
-"         <package name='extension_1_2_3_4.crx' hash_sha256='1234'/>"
-"       </packages>"
-"     </manifest>"
-"   </updatecheck>"
-" </app>"
-"</response>";
+    "<?xml version='1.0' encoding='UTF-8'?>"
+    "<response protocol='3.0'>"
+    " <app appid='12345'>"
+    "   <updatecheck status='ok'>"
+    "     <urls>"
+    "       <url codebase='http://example.com/'/>"
+    "     </urls>"
+    "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
+    "       <packages>"
+    "         <package name='extension_1_2_3_4.crx' hash_sha256='1234'/>"
+    "       </packages>"
+    "     </manifest>"
+    "   </updatecheck>"
+    " </app>"
+    "</response>";
 
 const char* valid_xml_with_invalid_sizes =
-"<?xml version='1.0' encoding='UTF-8'?>"
-"<response protocol='3.0'>"
-" <app appid='12345'>"
-"   <updatecheck status='ok'>"
-"     <urls>"
-"       <url codebase='http://example.com/'/>"
-"     </urls>"
-"     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
-"       <packages>"
-"         <package name='1' size='1234'/>"
-"         <package name='2' size='-1234'/>"
-"         <package name='3' />"
-"         <package name='4' size='-a'/>"
-"         <package name='5' size='-123467890123456789'/>"
-"         <package name='6' size='123467890123456789'/>"
-"       </packages>"
-"     </manifest>"
-"   </updatecheck>"
-" </app>"
-"</response>";
+    "<?xml version='1.0' encoding='UTF-8'?>"
+    "<response protocol='3.0'>"
+    " <app appid='12345'>"
+    "   <updatecheck status='ok'>"
+    "     <urls>"
+    "       <url codebase='http://example.com/'/>"
+    "     </urls>"
+    "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
+    "       <packages>"
+    "         <package name='1' size='1234'/>"
+    "         <package name='2' size='-1234'/>"
+    "         <package name='3' />"
+    "         <package name='4' size='-a'/>"
+    "         <package name='5' size='-123467890123456789'/>"
+    "         <package name='6' size='123467890123456789'/>"
+    "       </packages>"
+    "     </manifest>"
+    "   </updatecheck>"
+    " </app>"
+    "</response>";
 
 const char* kInvalidValidXmlMissingCodebase =
-"<?xml version='1.0' encoding='UTF-8'?>"
-"<response protocol='3.0'>"
-" <app appid='12345'>"
-"   <updatecheck status='ok'>"
-"     <urls>"
-"       <url codebasediff='http://diff.example.com/'/>"
-"     </urls>"
-"     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
-"       <packages>"
-"         <package namediff='extension_1_2_3_4.crx'/>"
-"       </packages>"
-"     </manifest>"
-"   </updatecheck>"
-" </app>"
-"</response>";
+    "<?xml version='1.0' encoding='UTF-8'?>"
+    "<response protocol='3.0'>"
+    " <app appid='12345'>"
+    "   <updatecheck status='ok'>"
+    "     <urls>"
+    "       <url codebasediff='http://diff.example.com/'/>"
+    "     </urls>"
+    "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
+    "       <packages>"
+    "         <package namediff='extension_1_2_3_4.crx'/>"
+    "       </packages>"
+    "     </manifest>"
+    "   </updatecheck>"
+    " </app>"
+    "</response>";
 
 const char* kMissingAppId =
-"<?xml version='1.0'?>"
-"<response protocol='3.0'>"
-" <app>"
-"  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
-"               version='1.2.3.4' />"
-" </app>"
-"</response>";
+    "<?xml version='1.0'?>"
+    "<response protocol='3.0'>"
+    " <app>"
+    "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
+    "               version='1.2.3.4' />"
+    " </app>"
+    "</response>";
 
 const char* kInvalidCodebase =
-"<?xml version='1.0'?>"
-"<response protocol='3.0'>"
-" <app appid='12345' status='ok'>"
-"  <updatecheck codebase='example.com/extension_1.2.3.4.crx'"
-"               version='1.2.3.4' />"
-" </app>"
-"</response>";
+    "<?xml version='1.0'?>"
+    "<response protocol='3.0'>"
+    " <app appid='12345' status='ok'>"
+    "  <updatecheck codebase='example.com/extension_1.2.3.4.crx'"
+    "               version='1.2.3.4' />"
+    " </app>"
+    "</response>";
 
 const char* kMissingVersion =
-"<?xml version='1.0'?>"
-"<response protocol='3.0'>"
-" <app appid='12345' status='ok'>"
-"  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' />"
-" </app>"
-"</response>";
+    "<?xml version='1.0'?>"
+    "<response protocol='3.0'>"
+    " <app appid='12345' status='ok'>"
+    "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' />"
+    " </app>"
+    "</response>";
 
 const char* kInvalidVersion =
-"<?xml version='1.0'?>"
-"<response protocol='3.0'>"
-" <app appid='12345' status='ok'>"
-"  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' "
-"               version='1.2.3.a'/>"
-" </app>"
-"</response>";
+    "<?xml version='1.0'?>"
+    "<response protocol='3.0'>"
+    " <app appid='12345' status='ok'>"
+    "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' "
+    "               version='1.2.3.a'/>"
+    " </app>"
+    "</response>";
 
 // The v3 version of the protocol is not using namespaces. However, the parser
 // must be able to parse responses that include namespaces.
 const char* kUsesNamespacePrefix =
-"<?xml version='1.0' encoding='UTF-8'?>"
-"<g:response xmlns='http://www.google.com/update2/response' protocol='3.0'>"
-" <g:app appid='12345'>"
-"   <g:updatecheck status='ok'>"
-"     <g:urls>"
-"       <g:url codebase='http://example.com/'/>"
-"     </g:urls>"
-"     <g:manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
-"       <g:packages>"
-"         <g:package name='extension_1_2_3_4.crx'/>"
-"       </g:packages>"
-"     </g:manifest>"
-"   </g:updatecheck>"
-" </g:app>"
-"</g:response>";
+    "<?xml version='1.0' encoding='UTF-8'?>"
+    "<g:response xmlns='http://www.google.com/update2/response' protocol='3.0'>"
+    " <g:app appid='12345'>"
+    "   <g:updatecheck status='ok'>"
+    "     <g:urls>"
+    "       <g:url codebase='http://example.com/'/>"
+    "     </g:urls>"
+    "     <g:manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
+    "       <g:packages>"
+    "         <g:package name='extension_1_2_3_4.crx'/>"
+    "       </g:packages>"
+    "     </g:manifest>"
+    "   </g:updatecheck>"
+    " </g:app>"
+    "</g:response>";
 
 // Includes unrelated <app> tags from other xml namespaces - this should
 // not cause problems.
 const char* kSimilarTagnames =
-"<?xml version='1.0' encoding='UTF-8'?>"
-"<response xmlns:a='http://a' protocol='3.0'>"
-" <a:app appid='12345'>"
-"   <updatecheck status='ok'>"
-"     <urls>"
-"       <url codebase='http://example.com/'/>"
-"     </urls>"
-"     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
-"       <packages>"
-"         <package name='extension_1_2_3_4.crx'/>"
-"       </packages>"
-"     </manifest>"
-"   </updatecheck>"
-" </a:app>"
-" <b:app appid='xyz' xmlns:b='http://b'>"
-"   <updatecheck status='noupdate'/>"
-" </b:app>"
-"</response>";
+    "<?xml version='1.0' encoding='UTF-8'?>"
+    "<response xmlns:a='http://a' protocol='3.0'>"
+    " <a:app appid='12345'>"
+    "   <updatecheck status='ok'>"
+    "     <urls>"
+    "       <url codebase='http://example.com/'/>"
+    "     </urls>"
+    "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
+    "       <packages>"
+    "         <package name='extension_1_2_3_4.crx'/>"
+    "       </packages>"
+    "     </manifest>"
+    "   </updatecheck>"
+    " </a:app>"
+    " <b:app appid='xyz' xmlns:b='http://b'>"
+    "   <updatecheck status='noupdate'/>"
+    " </b:app>"
+    "</response>";
 
 // Includes a <daystart> tag.
 const char* kWithDaystart =
-"<?xml version='1.0' encoding='UTF-8'?>"
-"<response protocol='3.0'>"
-" <daystart elapsed_seconds='456' />"
-" <app appid='12345'>"
-"   <updatecheck status='ok'>"
-"     <urls>"
-"       <url codebase='http://example.com/'/>"
-"     </urls>"
-"     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
-"       <packages>"
-"         <package name='extension_1_2_3_4.crx'/>"
-"       </packages>"
-"     </manifest>"
-"   </updatecheck>"
-" </app>"
-"</response>";
+    "<?xml version='1.0' encoding='UTF-8'?>"
+    "<response protocol='3.0'>"
+    " <daystart elapsed_seconds='456' />"
+    " <app appid='12345'>"
+    "   <updatecheck status='ok'>"
+    "     <urls>"
+    "       <url codebase='http://example.com/'/>"
+    "     </urls>"
+    "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
+    "       <packages>"
+    "         <package name='extension_1_2_3_4.crx'/>"
+    "       </packages>"
+    "     </manifest>"
+    "   </updatecheck>"
+    " </app>"
+    "</response>";
 
 // Indicates no updates available - this should not be a parse error.
 const char* kNoUpdate =
-"<?xml version='1.0' encoding='UTF-8'?>"
-"<response protocol='3.0'>"
-" <app appid='12345'>"
-"  <updatecheck status='noupdate' />"
-" </app>"
-"</response>";
+    "<?xml version='1.0' encoding='UTF-8'?>"
+    "<response protocol='3.0'>"
+    " <app appid='12345'>"
+    "  <updatecheck status='noupdate' />"
+    " </app>"
+    "</response>";
 
 // Includes two <app> tags, one with an error.
 const char* kTwoAppsOneError =
-"<?xml version='1.0' encoding='UTF-8'?>"
-"<response protocol='3.0'>"
-" <app appid='aaaaaaaa' status='error-unknownApplication'>"
-"  <updatecheck status='error-unknownapplication'/>"
-" </app>"
-" <app appid='bbbbbbbb'>"
-"   <updatecheck status='ok'>"
-"     <urls>"
-"       <url codebase='http://example.com/'/>"
-"     </urls>"
-"     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
-"       <packages>"
-"         <package name='extension_1_2_3_4.crx'/>"
-"       </packages>"
-"     </manifest>"
-"   </updatecheck>"
-" </app>"
-"</response>";
+    "<?xml version='1.0' encoding='UTF-8'?>"
+    "<response protocol='3.0'>"
+    " <app appid='aaaaaaaa' status='error-unknownApplication'>"
+    "  <updatecheck status='error-unknownapplication'/>"
+    " </app>"
+    " <app appid='bbbbbbbb'>"
+    "   <updatecheck status='ok'>"
+    "     <urls>"
+    "       <url codebase='http://example.com/'/>"
+    "     </urls>"
+    "     <manifest version='1.2.3.4' prodversionmin='2.0.143.0'>"
+    "       <packages>"
+    "         <package name='extension_1_2_3_4.crx'/>"
+    "       </packages>"
+    "     </manifest>"
+    "   </updatecheck>"
+    " </app>"
+    "</response>";
 
 TEST(ComponentUpdaterUpdateResponseTest, TestParser) {
   UpdateResponse parser;
@@ -299,4 +299,3 @@
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/test/url_request_post_interceptor.cc b/chrome/browser/component_updater/test/url_request_post_interceptor.cc
index 2f0f992..a9fd511 100644
--- a/chrome/browser/component_updater/test/url_request_post_interceptor.cc
+++ b/chrome/browser/component_updater/test/url_request_post_interceptor.cc
@@ -28,9 +28,7 @@
         response_(response) {}
 
  protected:
-  virtual int GetResponseCode() const OVERRIDE {
-    return 200;
-  }
+  virtual int GetResponseCode() const OVERRIDE { return 200; }
 
   virtual int GetData(std::string* mime_type,
                       std::string* charset,
@@ -50,7 +48,8 @@
 };
 
 URLRequestPostInterceptor::URLRequestPostInterceptor(const GURL& url)
-    : url_(url), hit_count_(0) {}
+    : url_(url), hit_count_(0) {
+}
 
 URLRequestPostInterceptor::~URLRequestPostInterceptor() {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -95,10 +94,9 @@
   return static_cast<int>(requests_.size());
 }
 
-std::vector<std::string>
-URLRequestPostInterceptor::GetRequests() const {
- base::AutoLock auto_lock(interceptor_lock_);
- return requests_;
+std::vector<std::string> URLRequestPostInterceptor::GetRequests() const {
+  base::AutoLock auto_lock(interceptor_lock_);
+  return requests_;
 }
 
 std::string URLRequestPostInterceptor::GetRequestsAsString() const {
@@ -108,7 +106,8 @@
 
   int i = 0;
   for (std::vector<std::string>::const_iterator it = requests.begin();
-      it != requests.end(); ++it) {
+       it != requests.end();
+       ++it) {
     s.append(base::StringPrintf("\n  (%d): %s", ++i, it->c_str()));
   }
 
@@ -122,7 +121,6 @@
   ClearExpectations();
 }
 
-
 class URLRequestPostInterceptor::Delegate
     : public net::URLRequestJobFactory::ProtocolHandler {
  public:
@@ -132,17 +130,19 @@
   void Register() {
     CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     net::URLRequestFilter::GetInstance()->AddHostnameProtocolHandler(
-        scheme_, hostname_,
+        scheme_,
+        hostname_,
         scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(this));
   }
 
   void Unregister() {
     CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     for (InterceptorMap::iterator it = interceptors_.begin();
-        it != interceptors_.end(); ++it)
+         it != interceptors_.end();
+         ++it)
       delete (*it).second;
-    net::URLRequestFilter::GetInstance()->
-      RemoveHostnameHandler(scheme_, hostname_);
+    net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(scheme_,
+                                                                hostname_);
   }
 
   void OnCreateInterceptor(URLRequestPostInterceptor* interceptor) {
@@ -224,28 +224,30 @@
       hostname_(hostname),
       delegate_(new URLRequestPostInterceptor::Delegate(scheme, hostname)) {
   BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
+      BrowserThread::IO,
+      FROM_HERE,
       base::Bind(&URLRequestPostInterceptor::Delegate::Register,
                  base::Unretained(delegate_)));
 }
 
 URLRequestPostInterceptorFactory::~URLRequestPostInterceptorFactory() {
   BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
+      BrowserThread::IO,
+      FROM_HERE,
       base::Bind(&URLRequestPostInterceptor::Delegate::Unregister,
                  base::Unretained(delegate_)));
 }
 
 URLRequestPostInterceptor* URLRequestPostInterceptorFactory::CreateInterceptor(
     const base::FilePath& filepath) {
-  const GURL base_url(base::StringPrintf("%s://%s",
-                                         scheme_.c_str(),
-                                         hostname_.c_str()));
+  const GURL base_url(
+      base::StringPrintf("%s://%s", scheme_.c_str(), hostname_.c_str()));
   GURL absolute_url(base_url.Resolve(filepath.MaybeAsASCII()));
   URLRequestPostInterceptor* interceptor(
       new URLRequestPostInterceptor(absolute_url));
   bool res = BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
+      BrowserThread::IO,
+      FROM_HERE,
       base::Bind(&URLRequestPostInterceptor::Delegate::OnCreateInterceptor,
                  base::Unretained(delegate_),
                  base::Unretained(interceptor)));
@@ -258,4 +260,3 @@
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/update_checker.cc b/chrome/browser/component_updater/update_checker.cc
index bd2fc0a..061671a 100644
--- a/chrome/browser/component_updater/update_checker.cc
+++ b/chrome/browser/component_updater/update_checker.cc
@@ -61,9 +61,7 @@
   return BuildProtocolRequest(app_elements, additional_attributes);
 }
 
-class UpdateCheckerImpl
-    : public UpdateChecker,
-      public net::URLFetcherDelegate {
+class UpdateCheckerImpl : public UpdateChecker, public net::URLFetcherDelegate {
  public:
   UpdateCheckerImpl(const GURL& url,
                     net::URLRequestContextGetter* url_request_context_getter,
@@ -117,13 +115,13 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   if (url_fetcher_)
-    return false;     // Another fetch is in progress.
+    return false;  // Another fetch is in progress.
 
   url_fetcher_.reset(SendProtocolRequest(
-    url_,
-    BuildUpdateCheckRequest(items_to_check, additional_attributes),
-    this,
-    url_request_context_getter_));
+      url_,
+      BuildUpdateCheckRequest(items_to_check, additional_attributes),
+      this,
+      url_request_context_getter_));
 
   return true;
 }
@@ -155,4 +153,3 @@
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/update_checker.h b/chrome/browser/component_updater/update_checker.h
index 7120b69..b43e2fc 100644
--- a/chrome/browser/component_updater/update_checker.h
+++ b/chrome/browser/component_updater/update_checker.h
@@ -25,8 +25,10 @@
 
 class UpdateChecker {
  public:
-  typedef base::Callback<void (int error, const std::string& error_message,
-      const UpdateResponse::Results& results)> UpdateCheckCallback;
+  typedef base::Callback<void(int error,
+                              const std::string& error_message,
+                              const UpdateResponse::Results& results)>
+      UpdateCheckCallback;
 
   virtual ~UpdateChecker() {}
 
@@ -52,4 +54,3 @@
 }  // namespace component_updater
 
 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_UPDATE_CHECKER_H_
-
diff --git a/chrome/browser/component_updater/update_response.cc b/chrome/browser/component_updater/update_response.cc
index cf93658..2b5a98e 100644
--- a/chrome/browser/component_updater/update_response.cc
+++ b/chrome/browser/component_updater/update_response.cc
@@ -68,8 +68,8 @@
   for (xmlAttr* attr = node->properties; attr != NULL; attr = attr->next) {
     if (!xmlStrcmp(attr->name, name) && attr->children &&
         attr->children->content) {
-      return std::string(reinterpret_cast<const char*>(
-          attr->children->content));
+      return std::string(
+          reinterpret_cast<const char*>(attr->children->content));
     }
   }
   return std::string();
@@ -77,7 +77,7 @@
 
 // This is used for the xml parser to report errors. This assumes the context
 // is a pointer to a std::string where the error message should be appended.
-static void XmlErrorFunc(void *context, const char *message, ...) {
+static void XmlErrorFunc(void* context, const char* message, ...) {
   va_list args;
   va_start(args, message);
   std::string* error = static_cast<std::string*>(context);
@@ -94,9 +94,7 @@
       xmlFreeDoc(document_);
   }
 
-  xmlDocPtr get() {
-    return document_;
-  }
+  xmlDocPtr get() { return document_; }
 
  private:
   xmlDocPtr document_;
@@ -283,8 +281,8 @@
   ScopedXmlErrorFunc error_func(&xml_errors, &XmlErrorFunc);
 
   // Start up the xml parser with the manifest_xml contents.
-  ScopedXmlDocument document(xmlParseDoc(
-      reinterpret_cast<const xmlChar*>(response_xml.c_str())));
+  ScopedXmlDocument document(
+      xmlParseDoc(reinterpret_cast<const xmlChar*>(response_xml.c_str())));
   if (!document.get()) {
     ParseError("%s", xml_errors.c_str());
     return false;
@@ -303,8 +301,10 @@
 
   // Check for the response "protocol" attribute.
   if (GetAttribute(root, "protocol") != kExpectedResponseProtocol) {
-    ParseError("Missing/incorrect protocol on response tag "
-        "(expected '%s')", kExpectedResponseProtocol);
+    ParseError(
+        "Missing/incorrect protocol on response tag "
+        "(expected '%s')",
+        kExpectedResponseProtocol);
     return false;
   }
 
@@ -335,4 +335,3 @@
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/update_response.h b/chrome/browser/component_updater/update_response.h
index 6e174ec..08ab77f 100644
--- a/chrome/browser/component_updater/update_response.h
+++ b/chrome/browser/component_updater/update_response.h
@@ -132,4 +132,3 @@
 }  // namespace component_updater
 
 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_UPDATE_RESPONSE_H_
-
diff --git a/chrome/browser/component_updater/url_fetcher_downloader.cc b/chrome/browser/component_updater/url_fetcher_downloader.cc
index 39579cd..ed00523 100644
--- a/chrome/browser/component_updater/url_fetcher_downloader.cc
+++ b/chrome/browser/component_updater/url_fetcher_downloader.cc
@@ -27,15 +27,14 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
 
-UrlFetcherDownloader::~UrlFetcherDownloader() {}
+UrlFetcherDownloader::~UrlFetcherDownloader() {
+}
 
 void UrlFetcherDownloader::DoStartDownload(const GURL& url) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  url_fetcher_.reset(net::URLFetcher::Create(0,
-                                             url,
-                                             net::URLFetcher::GET,
-                                             this));
+  url_fetcher_.reset(
+      net::URLFetcher::Create(0, url, net::URLFetcher::GET, this));
   url_fetcher_->SetRequestContext(context_getter_);
   url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
                              net::LOAD_DO_NOT_SAVE_COOKIES |
@@ -57,8 +56,9 @@
 
   const base::Time download_end_time(base::Time::Now());
   const base::TimeDelta download_time =
-    download_end_time >= download_start_time_ ?
-    download_end_time - download_start_time_ : base::TimeDelta();
+      download_end_time >= download_start_time_
+          ? download_end_time - download_start_time_
+          : base::TimeDelta();
 
   // Consider a 5xx response from the server as an indication to terminate
   // the request and avoid overloading the server in this case.
@@ -71,21 +71,22 @@
   if (!fetch_error) {
     source->GetResponseAsFilePath(true, &result.response);
   }
+  result.downloaded_bytes = downloaded_bytes_;
+  result.total_bytes = total_bytes_;
 
   DownloadMetrics download_metrics;
   download_metrics.url = url();
   download_metrics.downloader = DownloadMetrics::kUrlFetcher;
   download_metrics.error = fetch_error;
-  download_metrics.bytes_downloaded = downloaded_bytes_;
-  download_metrics.bytes_total = total_bytes_;
+  download_metrics.downloaded_bytes = downloaded_bytes_;
+  download_metrics.total_bytes = total_bytes_;
   download_metrics.download_time_ms = download_time.InMilliseconds();
 
   base::FilePath local_path_;
   source->GetResponseAsFilePath(false, &local_path_);
   VLOG(1) << "Downloaded " << downloaded_bytes_ << " bytes in "
           << download_time.InMilliseconds() << "ms from "
-          << source->GetURL().spec()
-          << " to " << local_path_.value();
+          << source->GetURL().spec() << " to " << local_path_.value();
   CrxDownloader::OnDownloadComplete(is_handled, result, download_metrics);
 }
 
@@ -94,9 +95,15 @@
     int64 current,
     int64 total) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
   downloaded_bytes_ = current;
   total_bytes_ = total;
+
+  Result result;
+  result.downloaded_bytes = downloaded_bytes_;
+  result.total_bytes = total_bytes_;
+
+  OnDownloadProgress(result);
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/component_updater/url_fetcher_downloader.h b/chrome/browser/component_updater/url_fetcher_downloader.h
index ddd9ae8..2132aa3 100644
--- a/chrome/browser/component_updater/url_fetcher_downloader.h
+++ b/chrome/browser/component_updater/url_fetcher_downloader.h
@@ -53,4 +53,3 @@
 }  // namespace component_updater
 
 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_URL_FETCHER_DOWNLOADER_H_
-
diff --git a/chrome/browser/component_updater/widevine_cdm_component_installer.cc b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
index f8c494a..1445247 100644
--- a/chrome/browser/component_updater/widevine_cdm_component_installer.cc
+++ b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
@@ -6,6 +6,7 @@
 
 #include <string.h>
 
+#include <string>
 #include <vector>
 
 #include "base/base_paths.h"
@@ -34,7 +35,7 @@
 #include "media/cdm/ppapi/supported_cdm_versions.h"
 #include "third_party/widevine/cdm/widevine_cdm_common.h"
 
-#include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR.
+#include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR. NOLINT
 
 using content::BrowserThread;
 using content::PluginService;
@@ -46,10 +47,10 @@
 namespace {
 
 // CRX hash. The extension id is: oimompecagnajdejgnnjijobebaeigek.
-const uint8 kSha2Hash[] = { 0xe8, 0xce, 0xcf, 0x42, 0x06, 0xd0, 0x93, 0x49,
-                            0x6d, 0xd9, 0x89, 0xe1, 0x41, 0x04, 0x86, 0x4a,
-                            0x8f, 0xbd, 0x86, 0x12, 0xb9, 0x58, 0x9b, 0xfb,
-                            0x4f, 0xbb, 0x1b, 0xa9, 0xd3, 0x85, 0x37, 0xef };
+const uint8 kSha2Hash[] = {0xe8, 0xce, 0xcf, 0x42, 0x06, 0xd0, 0x93, 0x49,
+                           0x6d, 0xd9, 0x89, 0xe1, 0x41, 0x04, 0x86, 0x4a,
+                           0x8f, 0xbd, 0x86, 0x12, 0xb9, 0x58, 0x9b, 0xfb,
+                           0x4f, 0xbb, 0x1b, 0xa9, 0xd3, 0x85, 0x37, 0xef};
 
 // File name of the Widevine CDM component manifest on different platforms.
 const char kWidevineCdmManifestName[] = "WidevineCdm";
@@ -155,9 +156,7 @@
       << "Widevine CDM component manifest has empty " << version_name;
 
   std::vector<std::string> versions;
-  base::SplitString(versions_string,
-                    kCdmValueDelimiter,
-                    &versions);
+  base::SplitString(versions_string, kCdmValueDelimiter, &versions);
 
   for (size_t i = 0; i < versions.size(); ++i) {
     int version = 0;
@@ -177,16 +176,15 @@
 // This should never fail except in rare cases where the component has not been
 // updated recently or the user downgrades Chrome.
 bool IsCompatibleWithChrome(const base::DictionaryValue& manifest) {
-  return
-      CheckForCompatibleVersion(manifest,
-                                kCdmModuleVersionsName,
-                                media::IsSupportedCdmModuleVersion) &&
-      CheckForCompatibleVersion(manifest,
-                                kCdmInterfaceVersionsName,
-                                media::IsSupportedCdmInterfaceVersion) &&
-      CheckForCompatibleVersion(manifest,
-                                kCdmHostVersionsName,
-                                media::IsSupportedCdmHostVersion);
+  return CheckForCompatibleVersion(manifest,
+                                   kCdmModuleVersionsName,
+                                   media::IsSupportedCdmModuleVersion) &&
+         CheckForCompatibleVersion(manifest,
+                                   kCdmInterfaceVersionsName,
+                                   media::IsSupportedCdmInterfaceVersion) &&
+         CheckForCompatibleVersion(manifest,
+                                   kCdmHostVersionsName,
+                                   media::IsSupportedCdmHostVersion);
 }
 
 void GetAdditionalParams(const base::DictionaryValue& manifest,
@@ -288,7 +286,9 @@
       FROM_HERE,
       base::Bind(&WidevineCdmComponentInstallerTraits::UpdateCdmAdapter,
                  base::Unretained(this),
-                 version, path, base::Passed(&manifest)));
+                 version,
+                 path,
+                 base::Passed(&manifest)));
 }
 
 bool WidevineCdmComponentInstallerTraits::VerifyInstallation(
@@ -365,8 +365,8 @@
   scoped_ptr<ComponentInstallerTraits> traits(
       new WidevineCdmComponentInstallerTraits);
   // |cus| will take ownership of |installer| during installer->Register(cus).
-  DefaultComponentInstaller* installer
-      = new DefaultComponentInstaller(traits.Pass());
+  DefaultComponentInstaller* installer =
+      new DefaultComponentInstaller(traits.Pass());
   installer->Register(cus);
 #else
   return;
@@ -374,4 +374,3 @@
 }
 
 }  // namespace component_updater
-
diff --git a/chrome/browser/content_settings/content_settings_internal_extension_provider.cc b/chrome/browser/content_settings/content_settings_internal_extension_provider.cc
index 46644f5..ef010c5 100644
--- a/chrome/browser/content_settings/content_settings_internal_extension_provider.cc
+++ b/chrome/browser/content_settings/content_settings_internal_extension_provider.cc
@@ -108,7 +108,7 @@
           "8B344D9E8A4C505EF82A0DBBC25B8BD1F984E777",
           "E06AFCB1EB0EFD237824CC4AC8FDD3D43E8BC868"
         };
-        if (extensions::SimpleFeature::IsIdInWhitelist(
+        if (extensions::SimpleFeature::IsIdInList(
                 host->extension()->id(),
                 std::set<std::string>(
                     kAppWhitelist, kAppWhitelist + arraysize(kAppWhitelist)))) {
diff --git a/chrome/browser/content_settings/local_shared_objects_container.cc b/chrome/browser/content_settings/local_shared_objects_container.cc
index 4cc1fa1..fa48f6f 100644
--- a/chrome/browser/content_settings/local_shared_objects_container.cc
+++ b/chrome/browser/content_settings/local_shared_objects_container.cc
@@ -99,7 +99,7 @@
       // The |domain_url| is only created in order to use the
       // SameDomainOrHost method below. It does not matter which scheme is
       // used as the scheme is ignored by the SameDomainOrHost method.
-      GURL domain_url(std::string(content::kHttpScheme) +
+      GURL domain_url(std::string(url::kHttpScheme) +
                       content::kStandardSchemeSeparator + cookie_domain);
       if (SameDomainOrHost(origin, domain_url))
         ++count;
diff --git a/chrome/browser/devtools/device/adb/adb_client_socket.cc b/chrome/browser/devtools/device/adb/adb_client_socket.cc
index 70b19bd..0845f92 100644
--- a/chrome/browser/devtools/device/adb/adb_client_socket.cc
+++ b/chrome/browser/devtools/device/adb/adb_client_socket.cc
@@ -9,8 +9,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
-#include "net/base/address_list.h"
-#include "net/base/completion_callback.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_util.h"
 #include "net/socket/tcp_client_socket.h"
@@ -92,130 +90,6 @@
   SocketCallback callback_;
 };
 
-class HttpOverAdbSocket {
- public:
-  HttpOverAdbSocket(net::StreamSocket* socket,
-                    const std::string& request,
-                    const CommandCallback& callback)
-    : socket_(socket),
-      command_callback_(callback),
-      body_pos_(0) {
-    SendRequest(request);
-  }
-
-  HttpOverAdbSocket(net::StreamSocket* socket,
-                    const std::string& request,
-                    const SocketCallback& callback)
-    : socket_(socket),
-      socket_callback_(callback),
-      body_pos_(0) {
-    SendRequest(request);
-  }
-
- private:
-  ~HttpOverAdbSocket() {
-  }
-
-  void SendRequest(const std::string& request) {
-    scoped_refptr<net::StringIOBuffer> request_buffer =
-        new net::StringIOBuffer(request);
-
-    int result = socket_->Write(
-        request_buffer.get(),
-        request_buffer->size(),
-        base::Bind(&HttpOverAdbSocket::ReadResponse, base::Unretained(this)));
-    if (result != net::ERR_IO_PENDING)
-      ReadResponse(result);
-  }
-
-  void ReadResponse(int result) {
-    if (!CheckNetResultOrDie(result))
-      return;
-    scoped_refptr<net::IOBuffer> response_buffer =
-        new net::IOBuffer(kBufferSize);
-
-    result = socket_->Read(response_buffer.get(),
-                           kBufferSize,
-                           base::Bind(&HttpOverAdbSocket::OnResponseData,
-                                      base::Unretained(this),
-                                      response_buffer,
-                                      -1));
-    if (result != net::ERR_IO_PENDING)
-      OnResponseData(response_buffer, -1, result);
-  }
-
-  void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer,
-                      int bytes_total,
-                      int result) {
-    if (!CheckNetResultOrDie(result))
-      return;
-    if (result == 0) {
-      CheckNetResultOrDie(net::ERR_CONNECTION_CLOSED);
-      return;
-    }
-
-    response_ += std::string(response_buffer->data(), result);
-    int expected_length = 0;
-    if (bytes_total < 0) {
-      // TODO(kaznacheev): Use net::HttpResponseHeader to parse the header.
-      size_t content_pos = response_.find("Content-Length:");
-      if (content_pos != std::string::npos) {
-        size_t endline_pos = response_.find("\n", content_pos);
-        if (endline_pos != std::string::npos) {
-          std::string len = response_.substr(content_pos + 15,
-                                             endline_pos - content_pos - 15);
-          base::TrimWhitespace(len, base::TRIM_ALL, &len);
-          if (!base::StringToInt(len, &expected_length)) {
-            CheckNetResultOrDie(net::ERR_FAILED);
-            return;
-          }
-        }
-      }
-
-      body_pos_ = response_.find("\r\n\r\n");
-      if (body_pos_ != std::string::npos) {
-        body_pos_ += 4;
-        bytes_total = body_pos_ + expected_length;
-      }
-    }
-
-    if (bytes_total == static_cast<int>(response_.length())) {
-      if (!command_callback_.is_null())
-        command_callback_.Run(net::OK, response_.substr(body_pos_));
-      else
-        socket_callback_.Run(net::OK, socket_.release());
-      delete this;
-      return;
-    }
-
-    result = socket_->Read(response_buffer.get(),
-                           kBufferSize,
-                           base::Bind(&HttpOverAdbSocket::OnResponseData,
-                                      base::Unretained(this),
-                                      response_buffer,
-                                      bytes_total));
-    if (result != net::ERR_IO_PENDING)
-      OnResponseData(response_buffer, bytes_total, result);
-  }
-
-  bool CheckNetResultOrDie(int result) {
-    if (result >= 0)
-      return true;
-    if (!command_callback_.is_null())
-      command_callback_.Run(result, std::string());
-    else
-      socket_callback_.Run(result, NULL);
-    delete this;
-    return false;
-  }
-
-  scoped_ptr<net::StreamSocket> socket_;
-  std::string response_;
-  CommandCallback command_callback_;
-  SocketCallback socket_callback_;
-  size_t body_pos_;
-};
-
 class AdbQuerySocket : AdbClientSocket {
  public:
   AdbQuerySocket(int port,
@@ -288,20 +162,6 @@
   new AdbTransportSocket(port, serial, socket_name, callback);
 }
 
-// static
-void AdbClientSocket::HttpQuery(net::StreamSocket* socket,
-                                const std::string& request_path,
-                                const CommandCallback& callback) {
-  new HttpOverAdbSocket(socket, request_path, callback);
-}
-
-// static
-void AdbClientSocket::HttpQuery(net::StreamSocket* socket,
-                                const std::string& request_path,
-                                const SocketCallback& callback) {
-  new HttpOverAdbSocket(socket, request_path, callback);
-}
-
 AdbClientSocket::AdbClientSocket(int port)
     : host_(kLocalhost), port_(port) {
 }
diff --git a/chrome/browser/devtools/device/adb/adb_client_socket.h b/chrome/browser/devtools/device/adb/adb_client_socket.h
index d8207e5..f0d26ad 100644
--- a/chrome/browser/devtools/device/adb/adb_client_socket.h
+++ b/chrome/browser/devtools/device/adb/adb_client_socket.h
@@ -20,23 +20,15 @@
                        const CommandCallback& callback);
 
 
-  static void HttpQuery(net::StreamSocket* socket,
-                        const std::string& request,
-                        const CommandCallback& callback);
-
-  static void HttpQuery(net::StreamSocket* socket,
-                        const std::string& request,
-                        const SocketCallback& callback);
-
   static void TransportQuery(int port,
                              const std::string& serial,
                              const std::string& socket_name,
                              const SocketCallback& callback);
 
+ protected:
   explicit AdbClientSocket(int port);
   ~AdbClientSocket();
 
- protected:
   void Connect(const net::CompletionCallback& callback);
 
   void SendCommand(const std::string& command,
diff --git a/chrome/browser/devtools/device/adb/adb_client_socket_browsertest.cc b/chrome/browser/devtools/device/adb/adb_client_socket_browsertest.cc
index 5a4fa93..1a3fdef 100644
--- a/chrome/browser/devtools/device/adb/adb_client_socket_browsertest.cc
+++ b/chrome/browser/devtools/device/adb/adb_client_socket_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/devtools/device/adb/adb_device_provider.h"
 #include "chrome/browser/devtools/device/adb/mock_adb_server.h"
 #include "chrome/browser/devtools/device/devtools_android_bridge.h"
 #include "chrome/browser/devtools/devtools_target_impl.h"
@@ -30,7 +31,7 @@
     Profile* profile = browser()->profile();
     android_bridge_ = DevToolsAndroidBridge::Factory::GetForProfile(profile);
     AndroidDeviceManager::DeviceProviders device_providers;
-    device_providers.push_back(AndroidDeviceManager::GetAdbDeviceProvider());
+    device_providers.push_back(new AdbDeviceProvider());
     android_bridge_->set_device_providers_for_test(device_providers);
     android_bridge_->AddDeviceListListener(this);
   }
@@ -91,24 +92,26 @@
     ASSERT_EQ("31.0.1599.0", chrome_beta->version());
     ASSERT_EQ("4.0", webview->version());
 
-    std::vector<DevToolsTargetImpl*> chrome_pages =
-        chrome->CreatePageTargets();
-    std::vector<DevToolsTargetImpl*> chrome_beta_pages =
-        chrome_beta->CreatePageTargets();
-    std::vector<DevToolsTargetImpl*> webview_pages =
-        webview->CreatePageTargets();
+    std::vector<DevToolsAndroidBridge::RemotePage*> chrome_pages =
+        chrome->CreatePages();
+    std::vector<DevToolsAndroidBridge::RemotePage*> chrome_beta_pages =
+        chrome_beta->CreatePages();
+    std::vector<DevToolsAndroidBridge::RemotePage*> webview_pages =
+        webview->CreatePages();
 
     ASSERT_EQ(1U, chrome_pages.size());
     ASSERT_EQ(0U, chrome_beta_pages.size());
     ASSERT_EQ(2U, webview_pages.size());
 
     // Check that we have non-empty description for webview pages.
-    ASSERT_EQ(0U, chrome_pages[0]->GetDescription().size());
-    ASSERT_NE(0U, webview_pages[0]->GetDescription().size());
-    ASSERT_NE(0U, webview_pages[1]->GetDescription().size());
+    ASSERT_EQ(0U, chrome_pages[0]->GetTarget()->GetDescription().size());
+    ASSERT_NE(0U, webview_pages[0]->GetTarget()->GetDescription().size());
+    ASSERT_NE(0U, webview_pages[1]->GetTarget()->GetDescription().size());
 
-    ASSERT_EQ(GURL("http://www.chromium.org/"), chrome_pages[0]->GetUrl());
-    ASSERT_EQ("The Chromium Projects", chrome_pages[0]->GetTitle());
+    ASSERT_EQ(GURL("http://www.chromium.org/"),
+                   chrome_pages[0]->GetTarget()->GetURL());
+    ASSERT_EQ("The Chromium Projects",
+              chrome_pages[0]->GetTarget()->GetTitle());
 
     STLDeleteElements(&chrome_pages);
     STLDeleteElements(&webview_pages);
diff --git a/chrome/browser/devtools/device/adb/adb_device_provider.cc b/chrome/browser/devtools/device/adb/adb_device_provider.cc
new file mode 100644
index 0000000..904bea6
--- /dev/null
+++ b/chrome/browser/devtools/device/adb/adb_device_provider.cc
@@ -0,0 +1,77 @@
+// 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.
+
+#include "chrome/browser/devtools/device/adb/adb_device_provider.h"
+
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "chrome/browser/devtools/device/adb/adb_client_socket.h"
+
+namespace {
+
+const char kHostDevicesCommand[] = "host:devices";
+const char kHostTransportCommand[] = "host:transport:%s|%s";
+const char kLocalAbstractCommand[] = "localabstract:%s";
+
+const int kAdbPort = 5037;
+
+class AdbDeviceImpl : public AndroidDeviceManager::Device {
+ public:
+  AdbDeviceImpl(const std::string& serial, bool is_connected);
+
+  virtual void RunCommand(const std::string& command,
+                          const CommandCallback& callback) OVERRIDE;
+
+  virtual void OpenSocket(const std::string& name,
+                          const SocketCallback& callback) OVERRIDE;
+ private:
+  virtual ~AdbDeviceImpl() {}
+};
+
+AdbDeviceImpl::AdbDeviceImpl(const std::string& serial, bool is_connected)
+    : Device(serial, is_connected) {
+}
+
+void AdbDeviceImpl::RunCommand(const std::string& command,
+                               const CommandCallback& callback) {
+  DCHECK(CalledOnValidThread());
+  std::string query = base::StringPrintf(kHostTransportCommand,
+                                         serial().c_str(), command.c_str());
+  AdbClientSocket::AdbQuery(kAdbPort, query, callback);
+}
+
+void AdbDeviceImpl::OpenSocket(const std::string& name,
+                               const SocketCallback& callback) {
+  DCHECK(CalledOnValidThread());
+  std::string socket_name =
+      base::StringPrintf(kLocalAbstractCommand, name.c_str());
+  AdbClientSocket::TransportQuery(kAdbPort, serial(), socket_name, callback);
+}
+
+// static
+void ReceivedAdbDevices(
+    const AdbDeviceProvider::QueryDevicesCallback& callback,
+    int result_code,
+    const std::string& response) {
+  AndroidDeviceManager::Devices result;
+  std::vector<std::string> serials;
+  Tokenize(response, "\n", &serials);
+  for (size_t i = 0; i < serials.size(); ++i) {
+    std::vector<std::string> tokens;
+    Tokenize(serials[i], "\t ", &tokens);
+    bool offline = tokens.size() > 1 && tokens[1] == "offline";
+    result.push_back(new AdbDeviceImpl(tokens[0], !offline));
+  }
+  callback.Run(result);
+}
+
+} // namespace
+
+AdbDeviceProvider::~AdbDeviceProvider() {
+}
+
+void AdbDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) {
+  AdbClientSocket::AdbQuery(
+      kAdbPort, kHostDevicesCommand, base::Bind(&ReceivedAdbDevices, callback));
+}
diff --git a/chrome/browser/devtools/device/adb/adb_device_provider.h b/chrome/browser/devtools/device/adb/adb_device_provider.h
new file mode 100644
index 0000000..2918673
--- /dev/null
+++ b/chrome/browser/devtools/device/adb/adb_device_provider.h
@@ -0,0 +1,20 @@
+// 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.
+
+#ifndef CHROME_BROWSER_DEVTOOLS_DEVICE_ADB_ADB_DEVICE_PROVIDER_H_
+#define CHROME_BROWSER_DEVTOOLS_DEVICE_ADB_ADB_DEVICE_PROVIDER_H_
+
+#include "chrome/browser/devtools/device/android_device_manager.h"
+
+class AdbDeviceProvider : public AndroidDeviceManager::DeviceProvider {
+ public:
+  typedef DeviceProvider::QueryDevicesCallback QueryDevicesCallback;
+
+  virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE;
+
+ private:
+  virtual ~AdbDeviceProvider();
+};
+
+#endif  // CHROME_BROWSER_DEVTOOLS_DEVICE_ADB_ADB_DEVICE_PROVIDER_H_
diff --git a/chrome/browser/devtools/device/android_device_manager.cc b/chrome/browser/devtools/device/android_device_manager.cc
index 32a4f5b..d4b31c9 100644
--- a/chrome/browser/devtools/device/android_device_manager.cc
+++ b/chrome/browser/devtools/device/android_device_manager.cc
@@ -7,242 +7,173 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
-#include "base/threading/thread.h"
-#include "chrome/browser/devtools/device/adb/adb_client_socket.h"
-#include "chrome/browser/devtools/device/usb/android_rsa.h"
-#include "chrome/browser/devtools/device/usb/android_usb_device.h"
+#include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
-#include "net/base/net_util.h"
-#include "net/socket/tcp_client_socket.h"
+#include "net/socket/stream_socket.h"
 
 using content::BrowserThread;
 
 namespace {
 
-const char kHostTransportCommand[] = "host:transport:%s|%s";
-const char kHostDevicesCommand[] = "host:devices";
-const char kLocalAbstractCommand[] = "localabstract:%s";
-
-const int kAdbPort = 5037;
 const int kBufferSize = 16 * 1024;
 
-const char kDeviceModelCommand[] = "shell:getprop ro.product.model";
-const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix";
-const char kOpenedUnixSocketsResponse[] =
-    "Num       RefCount Protocol Flags    Type St Inode Path\n"
-    "00000000: 00000002 00000000 00010000 0001 01 20894 @%s\n";
-const char kRemoteDebuggingSocket[] = "chrome_devtools_remote";
-const char kLocalChrome[] = "Local Chrome";
-const char kLocalhost[] = "127.0.0.1";
+static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n"
+    "Upgrade: WebSocket\r\n"
+    "Connection: Upgrade\r\n"
+    "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
+    "Sec-WebSocket-Version: 13\r\n"
+    "\r\n";
 
-// AdbDeviceImpl --------------------------------------------------------------
-
-class AdbDeviceImpl : public AndroidDeviceManager::Device {
+class HttpRequest {
  public:
-  AdbDeviceImpl(const std::string& serial, bool is_connected);
-  virtual void RunCommand(const std::string& command,
-                          const CommandCallback& callback) OVERRIDE;
-  virtual void OpenSocket(const std::string& name,
-                          const SocketCallback& callback) OVERRIDE;
- private:
-  virtual ~AdbDeviceImpl() {}
-};
+  typedef AndroidDeviceManager::CommandCallback CommandCallback;
+  typedef AndroidDeviceManager::SocketCallback SocketCallback;
 
-AdbDeviceImpl::AdbDeviceImpl(const std::string& serial, bool is_connected)
-    : Device(serial, is_connected) {
-}
-
-void AdbDeviceImpl::RunCommand(const std::string& command,
-                               const CommandCallback& callback) {
-  DCHECK(CalledOnValidThread());
-  std::string query = base::StringPrintf(kHostTransportCommand,
-                                         serial().c_str(), command.c_str());
-  AdbClientSocket::AdbQuery(kAdbPort, query, callback);
-}
-
-void AdbDeviceImpl::OpenSocket(const std::string& name,
-                               const SocketCallback& callback) {
-  DCHECK(CalledOnValidThread());
-  std::string socket_name =
-      base::StringPrintf(kLocalAbstractCommand, name.c_str());
-  AdbClientSocket::TransportQuery(kAdbPort, serial(), socket_name, callback);
-}
-
-// UsbDeviceImpl --------------------------------------------------------------
-
-class UsbDeviceImpl : public AndroidDeviceManager::Device {
- public:
-  explicit UsbDeviceImpl(AndroidUsbDevice* device);
-  virtual void RunCommand(const std::string& command,
-                          const CommandCallback& callback) OVERRIDE;
-  virtual void OpenSocket(const std::string& name,
-                          const SocketCallback& callback) OVERRIDE;
- private:
-  void OnOpenSocket(const SocketCallback& callback,
-                    net::StreamSocket* socket,
-                    int result);
-  void OpenedForCommand(const CommandCallback& callback,
-                        net::StreamSocket* socket,
-                        int result);
-  void OnRead(net::StreamSocket* socket,
-              scoped_refptr<net::IOBuffer> buffer,
-              const std::string& data,
-              const CommandCallback& callback,
-              int result);
-
-  virtual ~UsbDeviceImpl() {}
-  scoped_refptr<AndroidUsbDevice> device_;
-};
-
-
-UsbDeviceImpl::UsbDeviceImpl(AndroidUsbDevice* device)
-    : Device(device->serial(), device->is_connected()),
-      device_(device) {
-  device_->InitOnCallerThread();
-}
-
-void UsbDeviceImpl::RunCommand(const std::string& command,
-                               const CommandCallback& callback) {
-  DCHECK(CalledOnValidThread());
-  net::StreamSocket* socket = device_->CreateSocket(command);
-  if (!socket) {
-    callback.Run(net::ERR_CONNECTION_FAILED, std::string());
-    return;
-  }
-  int result = socket->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand,
-                                          this, callback, socket));
-  if (result != net::ERR_IO_PENDING)
-    callback.Run(result, std::string());
-}
-
-void UsbDeviceImpl::OpenSocket(const std::string& name,
-                               const SocketCallback& callback) {
-  DCHECK(CalledOnValidThread());
-  std::string socket_name =
-      base::StringPrintf(kLocalAbstractCommand, name.c_str());
-  net::StreamSocket* socket = device_->CreateSocket(socket_name);
-  if (!socket) {
-    callback.Run(net::ERR_CONNECTION_FAILED, NULL);
-    return;
-  }
-  int result = socket->Connect(base::Bind(&UsbDeviceImpl::OnOpenSocket, this,
-                                          callback, socket));
-  if (result != net::ERR_IO_PENDING)
-    callback.Run(result, NULL);
-}
-
-void UsbDeviceImpl::OnOpenSocket(const SocketCallback& callback,
-                  net::StreamSocket* socket,
-                  int result) {
-  callback.Run(result, result == net::OK ? socket : NULL);
-}
-
-void UsbDeviceImpl::OpenedForCommand(const CommandCallback& callback,
-                                     net::StreamSocket* socket,
-                                     int result) {
-  if (result != net::OK) {
-    callback.Run(result, std::string());
-    return;
-  }
-  scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize);
-  result = socket->Read(buffer, kBufferSize,
-                        base::Bind(&UsbDeviceImpl::OnRead, this,
-                                   socket, buffer, std::string(), callback));
-  if (result != net::ERR_IO_PENDING)
-    OnRead(socket, buffer, std::string(), callback, result);
-}
-
-void UsbDeviceImpl::OnRead(net::StreamSocket* socket,
-                           scoped_refptr<net::IOBuffer> buffer,
-                           const std::string& data,
+  static void CommandRequest(const std::string& request,
                            const CommandCallback& callback,
-                           int result) {
-  if (result <= 0) {
-    callback.Run(result, result == 0 ? data : std::string());
-    delete socket;
-    return;
+                           int result,
+                           net::StreamSocket* socket) {
+    if (result != net::OK) {
+      callback.Run(result, std::string());
+      return;
+    }
+    new HttpRequest(socket, request, callback);
   }
 
-  std::string new_data = data + std::string(buffer->data(), result);
-  result = socket->Read(buffer, kBufferSize,
-                        base::Bind(&UsbDeviceImpl::OnRead, this,
-                                   socket, buffer, new_data, callback));
-  if (result != net::ERR_IO_PENDING)
-    OnRead(socket, buffer, new_data, callback, result);
-}
-
-// AdbDeviceProvider -------------------------------------------
-
-class AdbDeviceProvider : public AndroidDeviceManager::DeviceProvider {
- public:
-  virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE;
- private:
-  void ReceivedAdbDevices(const QueryDevicesCallback& callback, int result,
-                          const std::string& response);
-
-  virtual ~AdbDeviceProvider();
-};
-
-AdbDeviceProvider::~AdbDeviceProvider() {
-}
-
-void AdbDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) {
-  AdbClientSocket::AdbQuery(
-      kAdbPort, kHostDevicesCommand,
-      base::Bind(&AdbDeviceProvider::ReceivedAdbDevices, this, callback));
-}
-
-void AdbDeviceProvider::ReceivedAdbDevices(const QueryDevicesCallback& callback,
-                                           int result_code,
-                                           const std::string& response) {
-  AndroidDeviceManager::Devices result;
-  std::vector<std::string> serials;
-  Tokenize(response, "\n", &serials);
-  for (size_t i = 0; i < serials.size(); ++i) {
-    std::vector<std::string> tokens;
-    Tokenize(serials[i], "\t ", &tokens);
-    bool offline = tokens.size() > 1 && tokens[1] == "offline";
-    result.push_back(new AdbDeviceImpl(tokens[0], !offline));
+  static void SocketRequest(const std::string& request,
+                          const SocketCallback& callback,
+                          int result,
+                          net::StreamSocket* socket) {
+    if (result != net::OK) {
+      callback.Run(result, NULL);
+      return;
+    }
+    new HttpRequest(socket, request, callback);
   }
-  callback.Run(result);
-}
 
-// UsbDeviceProvider -------------------------------------------
-
-class UsbDeviceProvider : public AndroidDeviceManager::DeviceProvider {
- public:
-  explicit UsbDeviceProvider(Profile* profile);
-
-  virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE;
  private:
-  virtual ~UsbDeviceProvider();
-  void EnumeratedDevices(const QueryDevicesCallback& callback,
-                         const AndroidUsbDevices& devices);
+  HttpRequest(net::StreamSocket* socket,
+                      const std::string& request,
+                      const CommandCallback& callback)
+    : socket_(socket),
+      command_callback_(callback),
+      body_pos_(0) {
+    SendRequest(request);
+  }
 
-  scoped_ptr<crypto::RSAPrivateKey>  rsa_key_;
+  HttpRequest(net::StreamSocket* socket,
+                      const std::string& request,
+                      const SocketCallback& callback)
+    : socket_(socket),
+      socket_callback_(callback),
+      body_pos_(0) {
+    SendRequest(request);
+  }
+
+  ~HttpRequest() {
+  }
+
+  void SendRequest(const std::string& request) {
+    scoped_refptr<net::StringIOBuffer> request_buffer =
+        new net::StringIOBuffer(request);
+
+    int result = socket_->Write(
+        request_buffer.get(),
+        request_buffer->size(),
+        base::Bind(&HttpRequest::ReadResponse, base::Unretained(this)));
+    if (result != net::ERR_IO_PENDING)
+      ReadResponse(result);
+  }
+
+  void ReadResponse(int result) {
+    if (!CheckNetResultOrDie(result))
+      return;
+    scoped_refptr<net::IOBuffer> response_buffer =
+        new net::IOBuffer(kBufferSize);
+
+    result = socket_->Read(
+        response_buffer.get(),
+        kBufferSize,
+        base::Bind(&HttpRequest::OnResponseData, base::Unretained(this),
+                  response_buffer,
+                  -1));
+    if (result != net::ERR_IO_PENDING)
+      OnResponseData(response_buffer, -1, result);
+  }
+
+  void OnResponseData(scoped_refptr<net::IOBuffer> response_buffer,
+                      int bytes_total,
+                      int result) {
+    if (!CheckNetResultOrDie(result))
+      return;
+    if (result == 0) {
+      CheckNetResultOrDie(net::ERR_CONNECTION_CLOSED);
+      return;
+    }
+
+    response_ += std::string(response_buffer->data(), result);
+    int expected_length = 0;
+    if (bytes_total < 0) {
+      // TODO(kaznacheev): Use net::HttpResponseHeader to parse the header.
+      size_t content_pos = response_.find("Content-Length:");
+      if (content_pos != std::string::npos) {
+        size_t endline_pos = response_.find("\n", content_pos);
+        if (endline_pos != std::string::npos) {
+          std::string len = response_.substr(content_pos + 15,
+                                             endline_pos - content_pos - 15);
+          base::TrimWhitespace(len, base::TRIM_ALL, &len);
+          if (!base::StringToInt(len, &expected_length)) {
+            CheckNetResultOrDie(net::ERR_FAILED);
+            return;
+          }
+        }
+      }
+
+      body_pos_ = response_.find("\r\n\r\n");
+      if (body_pos_ != std::string::npos) {
+        body_pos_ += 4;
+        bytes_total = body_pos_ + expected_length;
+      }
+    }
+
+    if (bytes_total == static_cast<int>(response_.length())) {
+      if (!command_callback_.is_null())
+        command_callback_.Run(net::OK, response_.substr(body_pos_));
+      else
+        socket_callback_.Run(net::OK, socket_.release());
+      delete this;
+      return;
+    }
+
+    result = socket_->Read(
+        response_buffer.get(),
+        kBufferSize,
+        base::Bind(&HttpRequest::OnResponseData,
+                   base::Unretained(this),
+                   response_buffer,
+                   bytes_total));
+    if (result != net::ERR_IO_PENDING)
+      OnResponseData(response_buffer, bytes_total, result);
+  }
+
+  bool CheckNetResultOrDie(int result) {
+    if (result >= 0)
+      return true;
+    if (!command_callback_.is_null())
+      command_callback_.Run(result, std::string());
+    else
+      socket_callback_.Run(result, NULL);
+    delete this;
+    return false;
+  }
+
+  scoped_ptr<net::StreamSocket> socket_;
+  std::string response_;
+  AndroidDeviceManager::CommandCallback command_callback_;
+  AndroidDeviceManager::SocketCallback socket_callback_;
+  size_t body_pos_;
 };
 
-UsbDeviceProvider::UsbDeviceProvider(Profile* profile){
-  rsa_key_.reset(AndroidRSAPrivateKey(profile));
-}
-
-UsbDeviceProvider::~UsbDeviceProvider() {
-}
-
-void UsbDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) {
-  AndroidUsbDevice::Enumerate(rsa_key_.get(),
-      base::Bind(&UsbDeviceProvider::EnumeratedDevices, this, callback));
-}
-
-void UsbDeviceProvider::EnumeratedDevices(const QueryDevicesCallback& callback,
-                                          const AndroidUsbDevices& devices) {
-  AndroidDeviceManager::Devices result;
-  for (AndroidUsbDevices::const_iterator it = devices.begin();
-      it != devices.end(); ++it)
-    result.push_back(new UsbDeviceImpl(*it));
-  callback.Run(result);
-}
-
 } // namespace
 
 AndroidDeviceManager::Device::Device(const std::string& serial,
@@ -251,51 +182,9 @@
       is_connected_(is_connected) {
 }
 
-void AndroidDeviceManager::Device::HttpQuery(
-    const std::string& la_name,
-    const std::string& request,
-    const CommandCallback& callback) {
-  DCHECK(CalledOnValidThread());
-  OpenSocket(la_name, base::Bind(
-      &Device::OnHttpSocketOpened, this, request, callback));
-}
-
-void AndroidDeviceManager::Device::HttpUpgrade(
-    const std::string& la_name,
-    const std::string& request,
-    const SocketCallback& callback) {
-  DCHECK(CalledOnValidThread());
-  OpenSocket(la_name, base::Bind(
-      &Device::OnHttpSocketOpened2, this, request, callback));
-}
-
 AndroidDeviceManager::Device::~Device() {
 }
 
-void AndroidDeviceManager::Device::OnHttpSocketOpened(
-    const std::string& request,
-    const CommandCallback& callback,
-    int result,
-    net::StreamSocket* socket) {
-  if (result != net::OK) {
-    callback.Run(result, std::string());
-    return;
-  }
-  AdbClientSocket::HttpQuery(socket, request, callback);
-}
-
-void AndroidDeviceManager::Device::OnHttpSocketOpened2(
-    const std::string& request,
-    const SocketCallback& callback,
-    int result,
-    net::StreamSocket* socket) {
-  if (result != net::OK) {
-    callback.Run(result, NULL);
-    return;
-  }
-  AdbClientSocket::HttpQuery(socket, request, callback);
-}
-
 AndroidDeviceManager::DeviceProvider::DeviceProvider() {
 }
 
@@ -303,122 +192,6 @@
 }
 
 // static
-scoped_refptr<AndroidDeviceManager::DeviceProvider>
-    AndroidDeviceManager::GetUsbDeviceProvider(Profile* profile) {
-  return new UsbDeviceProvider(profile);
-}
-
-// static
-scoped_refptr<AndroidDeviceManager::DeviceProvider>
-    AndroidDeviceManager::GetAdbDeviceProvider() {
-  return new AdbDeviceProvider();
-}
-
-
-class SelfAsDevice : public AndroidDeviceManager::Device {
- public:
-  explicit SelfAsDevice(int port);
-
-  virtual void RunCommand(const std::string& command,
-                          const CommandCallback& callback) OVERRIDE;
-  virtual void OpenSocket(const std::string& socket_name,
-                          const SocketCallback& callback) OVERRIDE;
- private:
-  void RunCommandCallback(const CommandCallback& callback,
-                          const std::string& response,
-                          int result);
-
-  void RunSocketCallback(const SocketCallback& callback,
-                         net::StreamSocket* socket,
-                         int result);
-  virtual ~SelfAsDevice() {}
-
-  int port_;
-};
-
-SelfAsDevice::SelfAsDevice(int port)
-    : Device("local", true),
-      port_(port)
-{}
-
-void SelfAsDevice::RunCommandCallback(const CommandCallback& callback,
-                                      const std::string& response,
-                                      int result) {
-  callback.Run(result, response);
-}
-
-void SelfAsDevice::RunSocketCallback(const SocketCallback& callback,
-                                     net::StreamSocket* socket,
-                                     int result) {
-  callback.Run(result, socket);
-}
-
-void SelfAsDevice::RunCommand(const std::string& command,
-                              const CommandCallback& callback) {
-  DCHECK(CalledOnValidThread());
-  std::string response;
-  if (command == kDeviceModelCommand) {
-    response = kLocalChrome;
-  } else if (command == kOpenedUnixSocketsCommand) {
-    response = base::StringPrintf(kOpenedUnixSocketsResponse,
-                                  kRemoteDebuggingSocket);
-  }
-
-  base::MessageLoop::current()->PostTask(FROM_HERE,
-                base::Bind(&SelfAsDevice::RunCommandCallback, this, callback,
-                           response, 0));
-}
-
-void SelfAsDevice::OpenSocket(const std::string& socket_name,
-                              const SocketCallback& callback) {
-  DCHECK(CalledOnValidThread());
-  // Use plain socket for remote debugging and port forwarding on Desktop
-  // (debugging purposes).
-  net::IPAddressNumber ip_number;
-  net::ParseIPLiteralToNumber(kLocalhost, &ip_number);
-
-  int port = 0;
-  if (socket_name == kRemoteDebuggingSocket)
-    port = port_;
-  else
-    base::StringToInt(socket_name, &port);
-
-  net::AddressList address_list =
-      net::AddressList::CreateFromIPAddress(ip_number, port);
-  net::TCPClientSocket* socket = new net::TCPClientSocket(
-      address_list, NULL, net::NetLog::Source());
-  socket->Connect(base::Bind(&SelfAsDevice::RunSocketCallback, this, callback,
-                             socket));
-}
-
-class SelfAsDeviceProvider : public AndroidDeviceManager::DeviceProvider {
- public:
-  explicit SelfAsDeviceProvider(int port);
-
-  virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE;
- private:
-  virtual ~SelfAsDeviceProvider(){}
-
-  int port_;
-};
-
-SelfAsDeviceProvider::SelfAsDeviceProvider(int port)
-    : port_(port) {
-}
-
-void SelfAsDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) {
-  AndroidDeviceManager::Devices result;
-  result.push_back(new SelfAsDevice(port_));
-  callback.Run(result);
-}
-
-// static
-scoped_refptr<AndroidDeviceManager::DeviceProvider>
-AndroidDeviceManager::GetSelfAsDeviceProvider(int port) {
-  return new SelfAsDeviceProvider(port);
-}
-
-// static
 scoped_refptr<AndroidDeviceManager> AndroidDeviceManager::Create() {
   return new AndroidDeviceManager();
 }
@@ -470,28 +243,34 @@
 
 void AndroidDeviceManager::HttpQuery(
     const std::string& serial,
-    const std::string& la_name,
+    const std::string& socket_name,
     const std::string& request,
     const CommandCallback& callback) {
   DCHECK(CalledOnValidThread());
   Device* device = FindDevice(serial);
   if (device)
-    device->HttpQuery(la_name, request, callback);
+    device->OpenSocket(socket_name,
+        base::Bind(&HttpRequest::CommandRequest, request, callback));
   else
     callback.Run(net::ERR_CONNECTION_FAILED, std::string());
 }
 
 void AndroidDeviceManager::HttpUpgrade(
     const std::string& serial,
-    const std::string& la_name,
-    const std::string& request,
+    const std::string& socket_name,
+    const std::string& url,
     const SocketCallback& callback) {
   DCHECK(CalledOnValidThread());
   Device* device = FindDevice(serial);
-  if (device)
-    device->HttpUpgrade(la_name, request, callback);
-  else
+  if (device) {
+    device->OpenSocket(
+        socket_name,
+        base::Bind(&HttpRequest::SocketRequest,
+                   base::StringPrintf(kWebSocketUpgradeRequest, url.c_str()),
+                   callback));
+  } else {
     callback.Run(net::ERR_CONNECTION_FAILED, NULL);
+  }
 }
 
 AndroidDeviceManager::AndroidDeviceManager()
diff --git a/chrome/browser/devtools/device/android_device_manager.h b/chrome/browser/devtools/device/android_device_manager.h
index 4c147c7..0e473c9 100644
--- a/chrome/browser/devtools/device/android_device_manager.h
+++ b/chrome/browser/devtools/device/android_device_manager.h
@@ -11,8 +11,10 @@
 #include "base/threading/non_thread_safe.h"
 #include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/browser_thread.h"
-#include "crypto/rsa_private_key.h"
-#include "net/socket/stream_socket.h"
+
+namespace net {
+class StreamSocket;
+}
 
 class AndroidDeviceManager
     : public base::RefCountedThreadSafe<AndroidDeviceManager>,
@@ -35,12 +37,6 @@
                             const CommandCallback& callback) = 0;
     virtual void OpenSocket(const std::string& socket_name,
                             const SocketCallback& callback) = 0;
-    void HttpQuery(const std::string& la_name,
-                   const std::string& request,
-                   const CommandCallback& callback);
-    void HttpUpgrade(const std::string& la_name,
-                     const std::string& request,
-                     const SocketCallback& callback);
 
     std::string serial() { return serial_; }
     bool is_connected() { return is_connected_; }
@@ -49,15 +45,6 @@
     virtual ~Device();
 
    private:
-    void OnHttpSocketOpened(const std::string& request,
-                            const CommandCallback& callback,
-                            int result,
-                            net::StreamSocket* socket);
-    void OnHttpSocketOpened2(const std::string& request,
-                             const SocketCallback& callback,
-                             int result,
-                             net::StreamSocket* socket);
-
     const std::string serial_;
     const bool is_connected_;
 
@@ -87,11 +74,6 @@
   };
 
  public:
-  static scoped_refptr<DeviceProvider> GetAdbDeviceProvider();
-  static scoped_refptr<DeviceProvider> GetUsbDeviceProvider(Profile* profile);
-  // Use only in a test and/or when DEBUG_DEVTOOLS is defined.
-  static scoped_refptr<DeviceProvider> GetSelfAsDeviceProvider(int port);
-
   static scoped_refptr<AndroidDeviceManager> Create();
 
   typedef std::vector<scoped_refptr<DeviceProvider> > DeviceProviders;
@@ -114,13 +96,13 @@
                   const SocketCallback& callback);
 
   void HttpQuery(const std::string& serial,
-                 const std::string& la_name,
+                 const std::string& socket_name,
                  const std::string& request,
                  const CommandCallback& callback);
 
   void HttpUpgrade(const std::string& serial,
-                   const std::string& la_name,
-                   const std::string& request,
+                   const std::string& socket_name,
+                   const std::string& url,
                    const SocketCallback& callback);
 
  private:
diff --git a/chrome/browser/devtools/device/android_web_socket.cc b/chrome/browser/devtools/device/android_web_socket.cc
index 6c7bf01..d08cd2c 100644
--- a/chrome/browser/devtools/device/android_web_socket.cc
+++ b/chrome/browser/devtools/device/android_web_socket.cc
@@ -4,12 +4,12 @@
 
 #include "base/message_loop/message_loop.h"
 #include "base/rand_util.h"
-#include "base/strings/stringprintf.h"
 #include "chrome/browser/devtools/device/devtools_android_bridge.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 #include "net/server/web_socket.h"
+#include "net/socket/stream_socket.h"
 
 using content::BrowserThread;
 using net::WebSocket;
@@ -18,13 +18,6 @@
 
 const int kBufferSize = 16 * 1024;
 
-static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n"
-    "Upgrade: WebSocket\r\n"
-    "Connection: Upgrade\r\n"
-    "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
-    "Sec-WebSocket-Version: 13\r\n"
-    "\r\n";
-
 class WebSocketImpl : public DevToolsAndroidBridge::AndroidWebSocket {
  public:
   WebSocketImpl(scoped_refptr<DevToolsAndroidBridge> android_bridge,
@@ -35,6 +28,7 @@
                    const std::string& url,
                    Delegate* delegate);
 
+  virtual void Connect() OVERRIDE;
   virtual void Disconnect() OVERRIDE;
 
   virtual void SendFrame(const std::string& message) OVERRIDE;
@@ -83,6 +77,9 @@
       socket_name_(socket_name),
       url_(url),
       delegate_(delegate) {
+}
+
+void WebSocketImpl::Connect() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   device_message_loop_->PostTask(
       FROM_HERE, base::Bind(&WebSocketImpl::ConnectOnHandlerThread, this));
@@ -115,7 +112,7 @@
   device_manager_->HttpUpgrade(
       serial_,
       socket_name_,
-      base::StringPrintf(kWebSocketUpgradeRequest, url_.c_str()),
+      url_,
       base::Bind(&WebSocketImpl::ConnectedOnHandlerThread, this));
 }
 
diff --git a/chrome/browser/devtools/device/devtools_android_bridge.cc b/chrome/browser/devtools/device/devtools_android_bridge.cc
index 01eae77..5fefecc 100644
--- a/chrome/browser/devtools/device/devtools_android_bridge.cc
+++ b/chrome/browser/devtools/device/devtools_android_bridge.cc
@@ -21,7 +21,9 @@
 #include "base/threading/thread.h"
 #include "base/values.h"
 #include "chrome/browser/devtools/browser_list_tabcontents_provider.h"
-#include "chrome/browser/devtools/device/usb/android_usb_device.h"
+#include "chrome/browser/devtools/device/adb/adb_device_provider.h"
+#include "chrome/browser/devtools/device/self_device_provider.h"
+#include "chrome/browser/devtools/device/usb/usb_device_provider.h"
 #include "chrome/browser/devtools/devtools_protocol.h"
 #include "chrome/browser/devtools/devtools_target_impl.h"
 #include "chrome/browser/devtools/devtools_window.h"
@@ -60,6 +62,9 @@
 const char kPageReloadCommand[] = "Page.reload";
 const char kPageNavigateCommand[] = "Page.navigate";
 
+// The format used for constructing DevTools server socket names.
+const char kDevToolsChannelNameFormat[] = "%s_devtools_remote";
+
 const char kChromeDefaultName[] = "Chrome";
 const char kChromeDefaultSocket[] = "chrome_devtools_remote";
 const int kMinVersionNewWithURL = 32;
@@ -636,6 +641,7 @@
     : command_(command),
       callback_(callback){
   web_socket_ = browser->CreateWebSocket(debug_url, this);
+  web_socket_->Connect();
 }
 
 void ProtocolCommand::OnSocketOpened() {
@@ -655,8 +661,6 @@
 
 }  // namespace
 
-const char kDevToolsChannelNameFormat[] = "%s_devtools_remote";
-
 class AgentHostDelegate;
 
 typedef std::map<std::string, AgentHostDelegate*> AgentHostDelegates;
@@ -730,10 +734,10 @@
   const std::string id_;
   bool socket_opened_;
   bool detached_;
+  bool is_web_view_;
   std::vector<std::string> pending_messages_;
-
-  scoped_ptr<content::DevToolsExternalAgentProxy> proxy_;
   scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
+  scoped_ptr<content::DevToolsExternalAgentProxy> proxy_;
   DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate);
 };
 
@@ -757,18 +761,11 @@
     const std::string& debug_url)
     : id_(id),
       socket_opened_(false),
-      detached_(false) {
-  web_socket_ = browser->CreateWebSocket(debug_url, this);
+      detached_(false),
+      is_web_view_(browser->socket().find(kWebViewSocketPrefix) == 0),
+      web_socket_(browser->CreateWebSocket(debug_url, this)),
+      proxy_(content::DevToolsExternalAgentProxy::Create(this)) {
   g_host_delegates.Get()[id] = this;
-
-  if (browser->socket().find(kWebViewSocketPrefix) == 0) {
-    content::RecordAction(
-        base::UserMetricsAction("DevTools_InspectAndroidWebView"));
-  } else {
-    content::RecordAction(
-        base::UserMetricsAction("DevTools_InspectAndroidPage"));
-  }
-  proxy_.reset(content::DevToolsExternalAgentProxy::Create(this));
 }
 
 AgentHostDelegate::~AgentHostDelegate() {
@@ -776,6 +773,9 @@
 }
 
 void AgentHostDelegate::Attach() {
+  content::RecordAction(base::UserMetricsAction(is_web_view_ ?
+      "DevTools_InspectAndroidWebView" : "DevTools_InspectAndroidPage"));
+  web_socket_->Connect();
 }
 
 void AgentHostDelegate::Detach() {
@@ -817,18 +817,21 @@
 
 //// RemotePageTarget ----------------------------------------------
 
-class RemotePageTarget : public DevToolsTargetImpl {
+class RemotePageTarget : public DevToolsTargetImpl,
+                         public DevToolsAndroidBridge::RemotePage {
  public:
   RemotePageTarget(scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser,
                    const base::DictionaryValue& value);
   virtual ~RemotePageTarget();
 
-  // content::DevToolsTarget overrides:
+  // DevToolsAndroidBridge::RemotePage implementation.
+  virtual DevToolsTargetImpl* GetTarget() OVERRIDE;
+  virtual std::string GetFrontendURL() OVERRIDE;
+
+  // DevToolsTargetImpl overrides.
   virtual bool IsAttached() const OVERRIDE;
   virtual bool Activate() const OVERRIDE;
   virtual bool Close() const OVERRIDE;
-
-  // DevToolsTargetImpl overrides:
   virtual void Inspect(Profile* profile) const OVERRIDE;
   virtual void Reload() const OVERRIDE;
 
@@ -842,52 +845,66 @@
   DISALLOW_COPY_AND_ASSIGN(RemotePageTarget);
 };
 
+static std::string GetStringProperty(const base::DictionaryValue& value,
+                                     const std::string& name) {
+  std::string result;
+  value.GetString(name, &result);
+  return result;
+}
+
+static std::string BuildUniqueTargetId(
+    DevToolsAndroidBridge::RemoteBrowser* browser,
+    const base::DictionaryValue& value) {
+  return base::StringPrintf("%s:%s:%s", browser->serial().c_str(),
+      browser->socket().c_str(), GetStringProperty(value, "id").c_str());
+}
+
+static std::string GetDebugURL(const base::DictionaryValue& value) {
+  std::string debug_url = GetStringProperty(value, "webSocketDebuggerUrl");
+
+  if (debug_url.find("ws://") == 0)
+    debug_url = debug_url.substr(5);
+  else
+    debug_url = "";
+  return debug_url;
+}
+
 RemotePageTarget::RemotePageTarget(
     scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser,
     const base::DictionaryValue& value)
-    : browser_(browser) {
-  type_ = "adb_page";
-  value.GetString("id", &remote_id_);
-  std::string url;
-  value.GetString("url", &url);
-  url_ = GURL(url);
-  value.GetString("title", &title_);
-  title_ = base::UTF16ToUTF8(net::UnescapeForHTML(base::UTF8ToUTF16(title_)));
-  value.GetString("description", &description_);
-  std::string favicon_url;
-  value.GetString("faviconUrl", &favicon_url);
-  favicon_url_ = GURL(favicon_url);
-  value.GetString("webSocketDebuggerUrl", &debug_url_);
-  value.GetString("devtoolsFrontendUrl", &frontend_url_);
-
-  if (remote_id_.empty() && !debug_url_.empty())  {
-    // Target id is not available until Chrome 26. Use page id at the end of
-    // debug_url_ instead. For attached targets the id will remain empty.
-    std::vector<std::string> parts;
-    Tokenize(debug_url_, "/", &parts);
-    remote_id_ = parts[parts.size()-1];
-  }
-
-  if (debug_url_.find("ws://") == 0)
-    debug_url_ = debug_url_.substr(5);
-  else
-    debug_url_ = "";
+    : DevToolsTargetImpl(AgentHostDelegate::GetOrCreateAgentHost(
+                             BuildUniqueTargetId(browser.get(), value),
+                             browser, GetDebugURL(value))),
+      browser_(browser),
+      debug_url_(GetDebugURL(value)),
+      remote_id_(GetStringProperty(value, "id")) {
+  set_type("adb_page");
+  set_url(GURL(GetStringProperty(value, "url")));
+  set_title(base::UTF16ToUTF8(net::UnescapeForHTML(base::UTF8ToUTF16(
+      GetStringProperty(value, "title")))));
+  set_description(GetStringProperty(value, "description"));
+  set_favicon_url(GURL(GetStringProperty(value, "faviconUrl")));
+  debug_url_ = GetDebugURL(value);
+  frontend_url_ = GetStringProperty(value, "devtoolsFrontendUrl");
 
   size_t ws_param = frontend_url_.find("?ws");
   if (ws_param != std::string::npos)
     frontend_url_ = frontend_url_.substr(0, ws_param);
   if (frontend_url_.find("http:") == 0)
     frontend_url_ = "https:" + frontend_url_.substr(5);
-
-  id_ = base::StringPrintf("%s:%s:%s",
-      browser_->serial().c_str(),
-      browser_->socket().c_str(),
-      remote_id_.c_str());
 }
 
 RemotePageTarget::~RemotePageTarget() {
 }
 
+DevToolsTargetImpl* RemotePageTarget::GetTarget() {
+  return this;
+}
+
+std::string RemotePageTarget::GetFrontendURL() {
+  return frontend_url_;
+}
+
 bool RemotePageTarget::IsAttached() const {
   return debug_url_.empty();
 }
@@ -896,12 +913,8 @@
 
 void RemotePageTarget::Inspect(Profile* profile) const {
   Activate();
-  scoped_refptr<content::DevToolsAgentHost> agent_host =
-      AgentHostDelegate::GetOrCreateAgentHost(id_, browser_, debug_url_);
-  if (agent_host) {
-    DevToolsWindow::OpenExternalFrontend(profile, frontend_url_,
-                                         agent_host.get());
-  }
+  DevToolsWindow::OpenExternalFrontend(profile, frontend_url_,
+                                       GetAgentHost());
 }
 
 bool RemotePageTarget::Activate() const {
@@ -962,9 +975,9 @@
   return result;
 }
 
-std::vector<DevToolsTargetImpl*>
-DevToolsAndroidBridge::RemoteBrowser::CreatePageTargets() {
-  std::vector<DevToolsTargetImpl*> result;
+std::vector<DevToolsAndroidBridge::RemotePage*>
+DevToolsAndroidBridge::RemoteBrowser::CreatePages() {
+  std::vector<DevToolsAndroidBridge::RemotePage*> result;
   for (size_t i = 0; i < page_descriptors_->GetSize(); ++i) {
     base::Value* item;
     page_descriptors_->Get(i, &item);
@@ -1017,14 +1030,14 @@
 
 void DevToolsAndroidBridge::RemoteBrowser::Open(
     const std::string& url,
-    const DevToolsAndroidBridge::TargetCallback& callback) {
+    const DevToolsAndroidBridge::RemotePageCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   InnerOpen(url, base::Bind(&RemoteBrowser::RespondToOpenOnUIThread,
                             this, callback));
 }
 
 void DevToolsAndroidBridge::RemoteBrowser::RespondToOpenOnUIThread(
-    const DevToolsAndroidBridge::TargetCallback& callback,
+    const DevToolsAndroidBridge::RemotePageCallback& callback,
     int result,
     const std::string& response) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -1035,8 +1048,8 @@
   scoped_ptr<base::Value> value(base::JSONReader::Read(response));
   base::DictionaryValue* dict;
   if (value && value->GetAsDictionary(&dict)) {
-    RemotePageTarget new_page(this, *dict);
-    callback.Run(&new_page);
+    RemotePageTarget* new_page = new RemotePageTarget(this, *dict);
+    callback.Run(new_page);
   }
 }
 
@@ -1302,7 +1315,7 @@
   if (device_count_listeners_.empty())
     return;
 
-  AndroidUsbDevice::CountDevices(
+  UsbDeviceProvider::CountDevices(
       base::Bind(&DevToolsAndroidBridge::ReceivedDeviceCount, this));
 }
 
@@ -1330,10 +1343,9 @@
   // We cannot rely on command line switch here as we might want to connect
   // to another instance of Chrome. Using hard-coded port number instead.
   const int kDefaultDebuggingPort = 9222;
-  device_providers_.push_back(
-      AndroidDeviceManager::GetSelfAsDeviceProvider(kDefaultDebuggingPort));
+  device_providers_.push_back(new SelfAsDeviceProvider(kDefaultDebuggingPort));
 #endif
-  device_providers_.push_back(AndroidDeviceManager::GetAdbDeviceProvider());
+  device_providers_.push_back(new AdbDeviceProvider());
 
   PrefService* service = profile_->GetPrefs();
   const PrefService::Preference* pref =
@@ -1342,7 +1354,6 @@
 
   bool enabled;
   if (pref_value->GetAsBoolean(&enabled) && enabled) {
-    device_providers_.push_back(
-        AndroidDeviceManager::GetUsbDeviceProvider(profile_));
+    device_providers_.push_back(new UsbDeviceProvider(profile_));
   }
 }
diff --git a/chrome/browser/devtools/device/devtools_android_bridge.h b/chrome/browser/devtools/device/devtools_android_bridge.h
index 8873816..d35f8e1 100644
--- a/chrome/browser/devtools/device/devtools_android_bridge.h
+++ b/chrome/browser/devtools/device/devtools_android_bridge.h
@@ -30,16 +30,9 @@
 class BrowserContext;
 }
 
-namespace crypto {
-class RSAPrivateKey;
-}
-
 class DevToolsTargetImpl;
 class Profile;
 
-// The format used for constructing DevTools server socket names.
-extern const char kDevToolsChannelNameFormat[];
-
 class DevToolsAndroidBridge
     : public base::RefCountedThreadSafe<
           DevToolsAndroidBridge,
@@ -47,7 +40,6 @@
  public:
   typedef base::Callback<void(int result,
                               const std::string& response)> Callback;
-  typedef base::Callback<void(DevToolsTargetImpl*)> TargetCallback;
 
   class Wrapper : public KeyedService {
    public:
@@ -93,8 +85,8 @@
 
     AndroidWebSocket() {}
 
+    virtual void Connect() = 0;
     virtual void Disconnect() = 0;
-
     virtual void SendFrame(const std::string& message) = 0;
 
    protected:
@@ -106,6 +98,15 @@
     DISALLOW_COPY_AND_ASSIGN(AndroidWebSocket);
   };
 
+  class RemotePage {
+   public:
+    virtual ~RemotePage() {}
+    virtual DevToolsTargetImpl* GetTarget() = 0;
+    virtual std::string GetFrontendURL() = 0;
+  };
+
+  typedef base::Callback<void(RemotePage*)> RemotePageCallback;
+
   class RemoteBrowser : public base::RefCounted<RemoteBrowser> {
    public:
     RemoteBrowser(
@@ -127,7 +128,7 @@
     typedef std::vector<int> ParsedVersion;
     ParsedVersion GetParsedVersion() const;
 
-    std::vector<DevToolsTargetImpl*> CreatePageTargets();
+    std::vector<RemotePage*> CreatePages();
     void SetPageDescriptors(const base::ListValue&);
 
     typedef base::Callback<void(int, const std::string&)> JsonRequestCallback;
@@ -139,7 +140,7 @@
                              const base::Closure callback);
 
     void Open(const std::string& url,
-              const TargetCallback& callback);
+              const RemotePageCallback& callback);
 
     scoped_refptr<AndroidWebSocket> CreateWebSocket(
         const std::string& url,
@@ -162,7 +163,7 @@
         const std::string& url);
 
     void RespondToOpenOnUIThread(
-        const DevToolsAndroidBridge::TargetCallback& callback,
+        const DevToolsAndroidBridge::RemotePageCallback& callback,
         int result,
         const std::string& response);
 
diff --git a/chrome/browser/devtools/device/port_forwarding_browsertest.cc b/chrome/browser/devtools/device/port_forwarding_browsertest.cc
index f4f03b8..970d46f 100644
--- a/chrome/browser/devtools/device/port_forwarding_browsertest.cc
+++ b/chrome/browser/devtools/device/port_forwarding_browsertest.cc
@@ -8,6 +8,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/devtools/browser_list_tabcontents_provider.h"
 #include "chrome/browser/devtools/device/port_forwarding_controller.h"
+#include "chrome/browser/devtools/device/self_device_provider.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -64,8 +65,7 @@
   Profile* profile = browser()->profile();
 
   AndroidDeviceManager::DeviceProviders device_providers;
-  device_providers.push_back(
-      AndroidDeviceManager::GetSelfAsDeviceProvider(kDefaultDebuggingPort));
+  device_providers.push_back(new SelfAsDeviceProvider(kDefaultDebuggingPort));
   DevToolsAndroidBridge::Factory::GetForProfile(profile)->
       set_device_providers_for_test(device_providers);
 
diff --git a/chrome/browser/devtools/device/port_forwarding_controller.cc b/chrome/browser/devtools/device/port_forwarding_controller.cc
index 937aa34..c22789b 100644
--- a/chrome/browser/devtools/device/port_forwarding_controller.cc
+++ b/chrome/browser/devtools/device/port_forwarding_controller.cc
@@ -322,6 +322,7 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   (*registry_)[device_->serial()] = this;
   web_socket_ = browser->CreateWebSocket(kDevToolsRemoteBrowserTarget, this);
+  web_socket_->Connect();
   AddRef();  // Balanced in OnSocketClosed();
 }
 
diff --git a/chrome/browser/devtools/device/self_device_provider.cc b/chrome/browser/devtools/device/self_device_provider.cc
new file mode 100644
index 0000000..fb782fc
--- /dev/null
+++ b/chrome/browser/devtools/device/self_device_provider.cc
@@ -0,0 +1,109 @@
+// 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.
+
+#include "chrome/browser/devtools/device/self_device_provider.h"
+
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "net/socket/tcp_client_socket.h"
+
+namespace {
+
+const char kDeviceModelCommand[] = "shell:getprop ro.product.model";
+const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix";
+const char kOpenedUnixSocketsResponse[] =
+    "Num       RefCount Protocol Flags    Type St Inode Path\n"
+    "00000000: 00000002 00000000 00010000 0001 01 20894 @%s\n";
+const char kRemoteDebuggingSocket[] = "chrome_devtools_remote";
+
+const char kDeviceModel[] = "Local Chrome";
+const char kLocalhost[] = "127.0.0.1";
+
+class SelfAsDevice : public AndroidDeviceManager::Device {
+ public:
+  explicit SelfAsDevice(int port);
+
+  virtual void RunCommand(const std::string& command,
+                          const CommandCallback& callback) OVERRIDE;
+  virtual void OpenSocket(const std::string& socket_name,
+                          const SocketCallback& callback) OVERRIDE;
+ private:
+  void RunCommandCallback(const CommandCallback& callback,
+                          const std::string& response,
+                          int result);
+
+  void RunSocketCallback(const SocketCallback& callback,
+                         net::StreamSocket* socket,
+                         int result);
+  virtual ~SelfAsDevice() {}
+
+  int port_;
+};
+
+SelfAsDevice::SelfAsDevice(int port)
+    : Device("local", true),
+      port_(port)
+{}
+
+void SelfAsDevice::RunCommandCallback(const CommandCallback& callback,
+                                      const std::string& response,
+                                      int result) {
+  callback.Run(result, response);
+}
+
+void SelfAsDevice::RunSocketCallback(const SocketCallback& callback,
+                                     net::StreamSocket* socket,
+                                     int result) {
+  callback.Run(result, socket);
+}
+
+void SelfAsDevice::RunCommand(const std::string& command,
+                              const CommandCallback& callback) {
+  DCHECK(CalledOnValidThread());
+  std::string response;
+  if (command == kDeviceModelCommand) {
+    response = kDeviceModel;
+  } else if (command == kOpenedUnixSocketsCommand) {
+    response = base::StringPrintf(kOpenedUnixSocketsResponse,
+                                  kRemoteDebuggingSocket);
+  }
+
+  base::MessageLoop::current()->PostTask(FROM_HERE,
+                base::Bind(&SelfAsDevice::RunCommandCallback, this, callback,
+                           response, 0));
+}
+
+void SelfAsDevice::OpenSocket(const std::string& socket_name,
+                              const SocketCallback& callback) {
+  DCHECK(CalledOnValidThread());
+  // Use plain socket for remote debugging and port forwarding on Desktop
+  // (debugging purposes).
+  net::IPAddressNumber ip_number;
+  net::ParseIPLiteralToNumber(kLocalhost, &ip_number);
+
+  int port = 0;
+  if (socket_name == kRemoteDebuggingSocket)
+    port = port_;
+  else
+    base::StringToInt(socket_name, &port);
+
+  net::AddressList address_list =
+      net::AddressList::CreateFromIPAddress(ip_number, port);
+  net::TCPClientSocket* socket = new net::TCPClientSocket(
+      address_list, NULL, net::NetLog::Source());
+  socket->Connect(base::Bind(&SelfAsDevice::RunSocketCallback, this, callback,
+                             socket));
+}
+
+} // namespace
+
+SelfAsDeviceProvider::SelfAsDeviceProvider(int port)
+    : port_(port) {
+}
+
+void SelfAsDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) {
+  AndroidDeviceManager::Devices result;
+  result.push_back(new SelfAsDevice(port_));
+  callback.Run(result);
+}
diff --git a/chrome/browser/devtools/device/self_device_provider.h b/chrome/browser/devtools/device/self_device_provider.h
new file mode 100644
index 0000000..8d18145
--- /dev/null
+++ b/chrome/browser/devtools/device/self_device_provider.h
@@ -0,0 +1,23 @@
+// 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.
+
+#ifndef CHROME_BROWSER_DEVTOOLS_DEVICE_SELF_DEVICE_PROVIDER_H_
+#define CHROME_BROWSER_DEVTOOLS_DEVICE_SELF_DEVICE_PROVIDER_H_
+
+#include "chrome/browser/devtools/device/android_device_manager.h"
+
+// Instantiate this class only in a test and/or when DEBUG_DEVTOOLS is defined.
+class SelfAsDeviceProvider : public AndroidDeviceManager::DeviceProvider {
+ public:
+  explicit SelfAsDeviceProvider(int port);
+
+  virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE;
+
+ private:
+  virtual ~SelfAsDeviceProvider(){}
+
+  int port_;
+};
+
+#endif  // CHROME_BROWSER_DEVTOOLS_DEVICE_SELF_DEVICE_PROVIDER_H_
diff --git a/chrome/browser/devtools/device/usb/usb_device_provider.cc b/chrome/browser/devtools/device/usb/usb_device_provider.cc
new file mode 100644
index 0000000..a4a51e9
--- /dev/null
+++ b/chrome/browser/devtools/device/usb/usb_device_provider.cc
@@ -0,0 +1,151 @@
+// 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.
+
+#include "chrome/browser/devtools/device/usb/usb_device_provider.h"
+
+#include "base/strings/stringprintf.h"
+#include "chrome/browser/devtools/device/usb/android_rsa.h"
+#include "chrome/browser/devtools/device/usb/android_usb_device.h"
+#include "crypto/rsa_private_key.h"
+#include "net/base/net_errors.h"
+#include "net/socket/stream_socket.h"
+
+namespace {
+
+const char kLocalAbstractCommand[] = "localabstract:%s";
+
+const int kBufferSize = 16 * 1024;
+
+class UsbDeviceImpl : public AndroidDeviceManager::Device {
+ public:
+  explicit UsbDeviceImpl(AndroidUsbDevice* device);
+
+  virtual void RunCommand(const std::string& command,
+                          const CommandCallback& callback) OVERRIDE;
+
+  virtual void OpenSocket(const std::string& name,
+                          const SocketCallback& callback) OVERRIDE;
+ private:
+  void OnOpenSocket(const SocketCallback& callback,
+                    net::StreamSocket* socket,
+                    int result);
+  void OpenedForCommand(const CommandCallback& callback,
+                        net::StreamSocket* socket,
+                        int result);
+  void OnRead(net::StreamSocket* socket,
+              scoped_refptr<net::IOBuffer> buffer,
+              const std::string& data,
+              const CommandCallback& callback,
+              int result);
+
+  virtual ~UsbDeviceImpl() {}
+  scoped_refptr<AndroidUsbDevice> device_;
+};
+
+
+UsbDeviceImpl::UsbDeviceImpl(AndroidUsbDevice* device)
+    : Device(device->serial(), device->is_connected()),
+      device_(device) {
+  device_->InitOnCallerThread();
+}
+
+void UsbDeviceImpl::RunCommand(const std::string& command,
+                               const CommandCallback& callback) {
+  DCHECK(CalledOnValidThread());
+  net::StreamSocket* socket = device_->CreateSocket(command);
+  if (!socket) {
+    callback.Run(net::ERR_CONNECTION_FAILED, std::string());
+    return;
+  }
+  int result = socket->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand,
+                                          this, callback, socket));
+  if (result != net::ERR_IO_PENDING)
+    callback.Run(result, std::string());
+}
+
+void UsbDeviceImpl::OpenSocket(const std::string& name,
+                               const SocketCallback& callback) {
+  DCHECK(CalledOnValidThread());
+  std::string socket_name =
+      base::StringPrintf(kLocalAbstractCommand, name.c_str());
+  net::StreamSocket* socket = device_->CreateSocket(socket_name);
+  if (!socket) {
+    callback.Run(net::ERR_CONNECTION_FAILED, NULL);
+    return;
+  }
+  int result = socket->Connect(base::Bind(&UsbDeviceImpl::OnOpenSocket, this,
+                                          callback, socket));
+  if (result != net::ERR_IO_PENDING)
+    callback.Run(result, NULL);
+}
+
+void UsbDeviceImpl::OnOpenSocket(const SocketCallback& callback,
+                  net::StreamSocket* socket,
+                  int result) {
+  callback.Run(result, result == net::OK ? socket : NULL);
+}
+
+void UsbDeviceImpl::OpenedForCommand(const CommandCallback& callback,
+                                     net::StreamSocket* socket,
+                                     int result) {
+  if (result != net::OK) {
+    callback.Run(result, std::string());
+    return;
+  }
+  scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize);
+  result = socket->Read(buffer, kBufferSize,
+                        base::Bind(&UsbDeviceImpl::OnRead, this,
+                                   socket, buffer, std::string(), callback));
+  if (result != net::ERR_IO_PENDING)
+    OnRead(socket, buffer, std::string(), callback, result);
+}
+
+void UsbDeviceImpl::OnRead(net::StreamSocket* socket,
+                           scoped_refptr<net::IOBuffer> buffer,
+                           const std::string& data,
+                           const CommandCallback& callback,
+                           int result) {
+  if (result <= 0) {
+    callback.Run(result, result == 0 ? data : std::string());
+    delete socket;
+    return;
+  }
+
+  std::string new_data = data + std::string(buffer->data(), result);
+  result = socket->Read(buffer, kBufferSize,
+                        base::Bind(&UsbDeviceImpl::OnRead, this,
+                                   socket, buffer, new_data, callback));
+  if (result != net::ERR_IO_PENDING)
+    OnRead(socket, buffer, new_data, callback, result);
+}
+
+static void EnumeratedDevices(
+    const UsbDeviceProvider::QueryDevicesCallback& callback,
+    const AndroidUsbDevices& devices) {
+  AndroidDeviceManager::Devices result;
+  for (AndroidUsbDevices::const_iterator it = devices.begin();
+      it != devices.end(); ++it)
+    result.push_back(new UsbDeviceImpl(*it));
+  callback.Run(result);
+}
+
+} // namespace
+
+// static
+void UsbDeviceProvider::CountDevices(
+    const base::Callback<void(int)>& callback) {
+  AndroidUsbDevice::CountDevices(callback);
+}
+
+UsbDeviceProvider::UsbDeviceProvider(Profile* profile){
+  rsa_key_.reset(AndroidRSAPrivateKey(profile));
+}
+
+UsbDeviceProvider::~UsbDeviceProvider() {
+}
+
+void UsbDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) {
+  AndroidUsbDevice::Enumerate(
+      rsa_key_.get(), base::Bind(&EnumeratedDevices, callback));
+}
diff --git a/chrome/browser/devtools/device/usb/usb_device_provider.h b/chrome/browser/devtools/device/usb/usb_device_provider.h
new file mode 100644
index 0000000..197d0f9
--- /dev/null
+++ b/chrome/browser/devtools/device/usb/usb_device_provider.h
@@ -0,0 +1,30 @@
+// 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.
+
+#ifndef CHROME_BROWSER_DEVTOOLS_DEVICE_USB_USB_DEVICE_PROVIDER_H_
+#define CHROME_BROWSER_DEVTOOLS_DEVICE_USB_USB_DEVICE_PROVIDER_H_
+
+#include "chrome/browser/devtools/device/android_device_manager.h"
+
+namespace crypto {
+class RSAPrivateKey;
+}
+
+class UsbDeviceProvider : public AndroidDeviceManager::DeviceProvider {
+ public:
+  typedef DeviceProvider::QueryDevicesCallback QueryDevicesCallback;
+
+  static void CountDevices(const base::Callback<void(int)>& callback);
+
+  explicit UsbDeviceProvider(Profile* profile);
+
+  virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE;
+
+ private:
+  virtual ~UsbDeviceProvider();
+
+  scoped_ptr<crypto::RSAPrivateKey>  rsa_key_;
+};
+
+#endif  // CHROME_BROWSER_DEVTOOLS_DEVICE_USB_USB_DEVICE_PROVIDER_H_
diff --git a/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc b/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc
index 2fae4a9..a33044e 100644
--- a/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc
+++ b/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc
@@ -245,6 +245,8 @@
                      &Delegate::SetContentsResizingStrategy, delegate);
   d->RegisterHandler("inspectElementCompleted",
                      &Delegate::InspectElementCompleted, delegate);
+  d->RegisterHandler("inspectedURLChanged",
+                     &Delegate::InspectedURLChanged, delegate);
   d->RegisterHandler("moveWindowBy", &Delegate::MoveWindow, delegate);
   d->RegisterHandler("setIsDocked", &Delegate::SetIsDocked, delegate);
   d->RegisterHandler("openInNewTab", &Delegate::OpenInNewTab, delegate);
diff --git a/chrome/browser/devtools/devtools_embedder_message_dispatcher.h b/chrome/browser/devtools/devtools_embedder_message_dispatcher.h
index 397eb6b..b210698 100644
--- a/chrome/browser/devtools/devtools_embedder_message_dispatcher.h
+++ b/chrome/browser/devtools/devtools_embedder_message_dispatcher.h
@@ -35,6 +35,7 @@
     virtual void SetContentsResizingStrategy(
         const gfx::Insets& insets, const gfx::Size& min_size) = 0;
     virtual void InspectElementCompleted() = 0;
+    virtual void InspectedURLChanged(const std::string& url) = 0;
     virtual void MoveWindow(int x, int y) = 0;
     virtual void SetIsDocked(bool is_docked) = 0;
     virtual void OpenInNewTab(const std::string& url) = 0;
diff --git a/chrome/browser/devtools/devtools_file_helper.cc b/chrome/browser/devtools/devtools_file_helper.cc
index 107d4df..03ab906 100644
--- a/chrome/browser/devtools/devtools_file_helper.cc
+++ b/chrome/browser/devtools/devtools_file_helper.cc
@@ -29,7 +29,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/url_constants.h"
 #include "grit/generated_resources.h"
@@ -83,7 +82,7 @@
       NULL,
       0,
       base::FilePath::StringType(),
-      platform_util::GetTopLevel(web_contents_->GetView()->GetNativeView()),
+      platform_util::GetTopLevel(web_contents_->GetNativeView()),
       NULL);
   }
 
diff --git a/chrome/browser/devtools/devtools_target_impl.cc b/chrome/browser/devtools/devtools_target_impl.cc
index 8434969..dad516d 100644
--- a/chrome/browser/devtools/devtools_target_impl.cc
+++ b/chrome/browser/devtools/devtools_target_impl.cc
@@ -36,15 +36,15 @@
 const char kTargetTypeWorker[] = "worker";
 const char kTargetTypeOther[] = "other";
 
+// RenderViewHostTarget --------------------------------------------------------
+
 class RenderViewHostTarget : public DevToolsTargetImpl {
  public:
   explicit RenderViewHostTarget(RenderViewHost* rvh, bool is_tab);
 
-  // content::DevToolsTarget overrides:
+  // DevToolsTargetImpl overrides:
   virtual bool Activate() const OVERRIDE;
   virtual bool Close() const OVERRIDE;
-
-  // DevToolsTargetImpl overrides:
   virtual RenderViewHost* GetRenderViewHost() const OVERRIDE;
   virtual int GetTabId() const OVERRIDE;
   virtual std::string GetExtensionId() const OVERRIDE;
@@ -55,35 +55,33 @@
   std::string extension_id_;
 };
 
-RenderViewHostTarget::RenderViewHostTarget(RenderViewHost* rvh, bool is_tab) {
-  agent_host_ = DevToolsAgentHost::GetOrCreateFor(rvh);
-  id_ = agent_host_->GetId();
-  type_ = kTargetTypeOther;
-  tab_id_ = -1;
-
+RenderViewHostTarget::RenderViewHostTarget(RenderViewHost* rvh, bool is_tab)
+    : DevToolsTargetImpl(DevToolsAgentHost::GetOrCreateFor(rvh)),
+      tab_id_(-1) {
+  set_type(kTargetTypeOther);
   WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
   if (!web_contents)
     return;  // Orphan RVH will show up with no title/url/icon in clients.
 
   content::RenderFrameHost* rfh = rvh->GetMainFrame();
   if (rfh->IsCrossProcessSubframe()) {
-    url_ = rfh->GetLastCommittedURL();
-    type_ = kTargetTypeOther;
+    set_url(rfh->GetLastCommittedURL());
+    set_type(kTargetTypeOther);
     // TODO(kaznacheev) Try setting the title when the frame navigation
     // refactoring is done.
     return;
   }
 
-  title_ = base::UTF16ToUTF8(web_contents->GetTitle());
-  url_ = web_contents->GetURL();
+  set_title(base::UTF16ToUTF8(web_contents->GetTitle()));
+  set_url(web_contents->GetURL());
   content::NavigationController& controller = web_contents->GetController();
   content::NavigationEntry* entry = controller.GetActiveEntry();
   if (entry != NULL && entry->GetURL().is_valid())
-    favicon_url_ = entry->GetFavicon().url;
-  last_activity_time_ = web_contents->GetLastActiveTime();
+    set_favicon_url(entry->GetFavicon().url);
+  set_last_activity_time(web_contents->GetLastActiveTime());
 
   if (is_tab) {
-    type_ = kTargetTypePage;
+    set_type(kTargetTypePage);
     tab_id_ = extensions::ExtensionTabUtil::GetTabId(web_contents);
   } else {
     Profile* profile =
@@ -91,24 +89,24 @@
     if (profile) {
       ExtensionService* extension_service = profile->GetExtensionService();
       const extensions::Extension* extension = extension_service->
-          extensions()->GetByID(url_.host());
+          extensions()->GetByID(GetURL().host());
       if (extension) {
-        title_ = extension->name();
+        set_title(extension->name());
         extensions::ExtensionHost* extension_host =
             extensions::ExtensionSystem::Get(profile)->process_manager()->
                 GetBackgroundHostForExtension(extension->id());
         if (extension_host &&
             extension_host->host_contents() == web_contents) {
-          type_ = kTargetTypeBackgroundPage;
+          set_type(kTargetTypeBackgroundPage);
           extension_id_ = extension->id();
         } else if (extension->is_hosted_app()
             || extension->is_legacy_packaged_app()
             || extension->is_platform_app()) {
-          type_ = kTargetTypeApp;
+          set_type(kTargetTypeApp);
         }
-        favicon_url_ = extensions::ExtensionIconSource::GetIconURL(
+        set_favicon_url(extensions::ExtensionIconSource::GetIconURL(
             extension, extension_misc::EXTENSION_ICON_SMALLISH,
-            ExtensionIconSet::MATCH_BIGGER, false, NULL);
+            ExtensionIconSet::MATCH_BIGGER, false, NULL));
       }
     }
   }
@@ -134,7 +132,7 @@
 }
 
 RenderViewHost* RenderViewHostTarget::GetRenderViewHost() const {
-  return agent_host_->GetRenderViewHost();
+  return GetAgentHost()->GetRenderViewHost();
 }
 
 int RenderViewHostTarget::GetTabId() const {
@@ -152,7 +150,7 @@
   DevToolsWindow::OpenDevToolsWindow(rvh);
 }
 
-///////////////////////////////////////////////////////////////////////////////
+// WorkerTarget ----------------------------------------------------------------
 
 class WorkerTarget : public DevToolsTargetImpl {
  public:
@@ -169,15 +167,14 @@
   int route_id_;
 };
 
-WorkerTarget::WorkerTarget(const WorkerService::WorkerInfo& worker) {
-  agent_host_ =
-      DevToolsAgentHost::GetForWorker(worker.process_id, worker.route_id);
-  id_ = agent_host_->GetId();
-  type_ = kTargetTypeWorker;
-  title_ = base::UTF16ToUTF8(worker.name);
-  description_ =
-      base::StringPrintf("Worker pid:%d", base::GetProcId(worker.handle));
-  url_ = worker.url;
+WorkerTarget::WorkerTarget(const WorkerService::WorkerInfo& worker)
+    : DevToolsTargetImpl(DevToolsAgentHost::GetForWorker(worker.process_id,
+                                                         worker.route_id)) {
+  set_type(kTargetTypeWorker);
+  set_title(base::UTF16ToUTF8(worker.name));
+  set_description(base::StringPrintf("Worker pid:%d",
+                      base::GetProcId(worker.handle)));
+  set_url(worker.url);
 
   process_id_ = worker.process_id;
   route_id_ = worker.route_id;
@@ -194,19 +191,22 @@
 }
 
 void WorkerTarget::Inspect(Profile* profile) const {
-  DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host_.get());
+  DevToolsWindow::OpenDevToolsWindowForWorker(profile, GetAgentHost());
 }
 
 }  // namespace
 
+// DevToolsTargetImpl ----------------------------------------------------------
+
 DevToolsTargetImpl::~DevToolsTargetImpl() {
 }
 
-DevToolsTargetImpl::DevToolsTargetImpl() {
+DevToolsTargetImpl::DevToolsTargetImpl(DevToolsAgentHost* agent_host)
+    : agent_host_(agent_host) {
 }
 
 std::string DevToolsTargetImpl::GetId() const {
-  return id_;
+  return agent_host_->GetId();
 }
 
 std::string DevToolsTargetImpl::GetType() const {
@@ -221,11 +221,11 @@
   return description_;
 }
 
-GURL DevToolsTargetImpl::GetUrl() const {
+GURL DevToolsTargetImpl::GetURL() const {
   return url_;
 }
 
-GURL DevToolsTargetImpl::GetFaviconUrl() const {
+GURL DevToolsTargetImpl::GetFaviconURL() const {
   return favicon_url_;
 }
 
diff --git a/chrome/browser/devtools/devtools_target_impl.h b/chrome/browser/devtools/devtools_target_impl.h
index b17f300..4842788 100644
--- a/chrome/browser/devtools/devtools_target_impl.h
+++ b/chrome/browser/devtools/devtools_target_impl.h
@@ -20,8 +20,7 @@
 
 class DevToolsTargetImpl : public content::DevToolsTarget {
  public:
-
-  DevToolsTargetImpl();
+  explicit DevToolsTargetImpl(content::DevToolsAgentHost* agent_host);
   virtual ~DevToolsTargetImpl();
 
   // content::DevToolsTarget overrides:
@@ -29,12 +28,12 @@
   virtual std::string GetType() const OVERRIDE;
   virtual std::string GetTitle() const OVERRIDE;
   virtual std::string GetDescription() const OVERRIDE;
-  virtual GURL GetUrl() const OVERRIDE;
-  virtual GURL GetFaviconUrl() const OVERRIDE;
+  virtual GURL GetURL() const OVERRIDE;
+  virtual GURL GetFaviconURL() const OVERRIDE;
   virtual base::TimeTicks GetLastActivityTime() const OVERRIDE;
+  virtual scoped_refptr<content::DevToolsAgentHost>
+      GetAgentHost() const OVERRIDE;
   virtual bool IsAttached() const OVERRIDE;
-  virtual scoped_refptr<content::DevToolsAgentHost> GetAgentHost() const
-    OVERRIDE;
   virtual bool Activate() const OVERRIDE;
   virtual bool Close() const OVERRIDE;
 
@@ -59,6 +58,15 @@
   static scoped_ptr<DevToolsTargetImpl> CreateForRenderViewHost(
       content::RenderViewHost*, bool is_tab);
 
+  void set_type(const std::string& type) { type_ = type; }
+  void set_title(const std::string& title) { title_ = title; }
+  void set_description(const std::string& desc) { description_ = desc; }
+  void set_url(const GURL& url) { url_ = url; }
+  void set_favicon_url(const GURL& url) { favicon_url_ = url; }
+  void set_last_activity_time(const base::TimeTicks& time) {
+     last_activity_time_ = time;
+  }
+
   typedef std::vector<DevToolsTargetImpl*> List;
   typedef base::Callback<void(const List&)> Callback;
 
@@ -66,7 +74,7 @@
   static void EnumerateWorkerTargets(Callback callback);
   static void EnumerateAllTargets(Callback callback);
 
- protected:
+ private:
   scoped_refptr<content::DevToolsAgentHost> agent_host_;
   std::string id_;
   std::string type_;
diff --git a/chrome/browser/devtools/devtools_targets_ui.cc b/chrome/browser/devtools/devtools_targets_ui.cc
index 069dba3..5f60275 100644
--- a/chrome/browser/devtools/devtools_targets_ui.cc
+++ b/chrome/browser/devtools/devtools_targets_ui.cc
@@ -372,13 +372,20 @@
     android_bridge->RemoveDeviceListListener(this);
 }
 
+static void CallOnTarget(
+    const DevToolsTargetsUIHandler::TargetCallback& callback,
+    DevToolsAndroidBridge::RemotePage* page) {
+  scoped_ptr<DevToolsAndroidBridge::RemotePage> my_page(page);
+  callback.Run(my_page ? my_page->GetTarget() : NULL);
+}
+
 void AdbTargetsUIHandler::Open(
     const std::string& browser_id,
     const std::string& url,
     const DevToolsTargetsUIHandler::TargetCallback& callback) {
   RemoteBrowsers::iterator it = remote_browsers_.find(browser_id);
   if (it !=  remote_browsers_.end())
-    it->second->Open(url, callback);
+    it->second->Open(url, base::Bind(&CallOnTarget, callback));
 }
 
 void AdbTargetsUIHandler::DeviceListChanged(
@@ -443,10 +450,12 @@
       base::ListValue* page_list = new base::ListValue();
       remote_browsers_[browser_id] = browser;
             browser_data->Set(kAdbPagesList, page_list);
-      DevToolsTargetImpl::List pages = browser->CreatePageTargets();
-      for (DevToolsTargetImpl::List::iterator it =
+      std::vector<DevToolsAndroidBridge::RemotePage*> pages =
+          browser->CreatePages();
+      for (std::vector<DevToolsAndroidBridge::RemotePage*>::iterator it =
           pages.begin(); it != pages.end(); ++it) {
-        DevToolsTargetImpl* target =  *it;
+        DevToolsAndroidBridge::RemotePage* page =  *it;
+        DevToolsTargetImpl* target = page->GetTarget();
         base::DictionaryValue* target_data = Serialize(*target);
         target_data->SetBoolean(
             kAdbAttachedForeignField,
@@ -529,9 +538,9 @@
   target_data->SetString(kTargetIdField, target.GetId());
   target_data->SetString(kTargetTypeField, target.GetType());
   target_data->SetBoolean(kAttachedField, target.IsAttached());
-  target_data->SetString(kUrlField, target.GetUrl().spec());
+  target_data->SetString(kUrlField, target.GetURL().spec());
   target_data->SetString(kNameField, net::EscapeForHTML(target.GetTitle()));
-  target_data->SetString(kFaviconUrlField, target.GetFaviconUrl().spec());
+  target_data->SetString(kFaviconUrlField, target.GetFaviconURL().spec());
   target_data->SetString(kDescriptionField, target.GetDescription());
   return target_data;
 }
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc
index 975b53a..7a01b2e 100644
--- a/chrome/browser/devtools/devtools_ui_bindings.cc
+++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -9,6 +9,7 @@
 #include "base/json/json_writer.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/chrome_notification_types.h"
@@ -34,6 +35,7 @@
 #include "content/public/browser/devtools_client_host.h"
 #include "content/public/browser/devtools_manager.h"
 #include "content/public/browser/favicon_status.h"
+#include "content/public/browser/invalidate_type.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_source.h"
@@ -42,7 +44,6 @@
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/page_transition_types.h"
 #include "content/public/common/renderer_preferences.h"
 #include "content/public/common/url_constants.h"
@@ -63,6 +64,7 @@
 static const char kFrontendHostId[] = "id";
 static const char kFrontendHostMethod[] = "method";
 static const char kFrontendHostParams[] = "params";
+static const char kTitleFormat[] = "Developer Tools - %s";
 
 std::string SkColorToRGBAString(SkColor color) {
   // We avoid StringPrintf because it will use locale specific formatters for
@@ -195,6 +197,8 @@
 
   virtual void InspectedContentsClosing() OVERRIDE;
   virtual void OnLoadCompleted() OVERRIDE {}
+  virtual InfoBarService* GetInfoBarService() OVERRIDE;
+  virtual void RenderProcessGone() OVERRIDE {}
 
   content::WebContents* web_contents_;
   DISALLOW_COPY_AND_ASSIGN(DefaultBindingsDelegate);
@@ -202,7 +206,7 @@
 
 void DefaultBindingsDelegate::ActivateWindow() {
   web_contents_->GetDelegate()->ActivateContents(web_contents_);
-  web_contents_->GetView()->Focus();
+  web_contents_->Focus();
 }
 
 void DefaultBindingsDelegate::OpenInNewTab(const std::string& url) {
@@ -217,6 +221,10 @@
   web_contents_->GetRenderViewHost()->ClosePage();
 }
 
+InfoBarService* DefaultBindingsDelegate::GetInfoBarService() {
+  return InfoBarService::FromWebContents(web_contents_);
+}
+
 }  // namespace
 
 // DevToolsUIBindings::FrontendWebContentsObserver ----------------------------
@@ -229,9 +237,10 @@
 
  private:
   // contents::WebContentsObserver:
+  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
   virtual void AboutToNavigateRenderView(
       content::RenderViewHost* render_view_host) OVERRIDE;
-  virtual void DocumentOnLoadCompletedInMainFrame(int32 page_id) OVERRIDE;
+  virtual void DocumentOnLoadCompletedInMainFrame() OVERRIDE;
 
   DevToolsUIBindings* devtools_bindings_;
   DISALLOW_COPY_AND_ASSIGN(FrontendWebContentsObserver);
@@ -247,13 +256,18 @@
     ~FrontendWebContentsObserver() {
 }
 
+void DevToolsUIBindings::FrontendWebContentsObserver::RenderProcessGone(
+    base::TerminationStatus status) {
+  devtools_bindings_->delegate_->RenderProcessGone();
+}
+
 void DevToolsUIBindings::FrontendWebContentsObserver::AboutToNavigateRenderView(
     content::RenderViewHost* render_view_host) {
   content::DevToolsClientHost::SetupDevToolsFrontendClient(render_view_host);
 }
 
 void DevToolsUIBindings::FrontendWebContentsObserver::
-    DocumentOnLoadCompletedInMainFrame(int32 page_id) {
+    DocumentOnLoadCompletedInMainFrame() {
   devtools_bindings_->DocumentOnLoadCompletedInMainFrame();
 }
 
@@ -389,7 +403,7 @@
 }
 
 void DevToolsUIBindings::CloseWindow() {
-  delegate_->ActivateWindow();
+  delegate_->CloseWindow();
 }
 
 void DevToolsUIBindings::SetContentsInsets(
@@ -414,6 +428,15 @@
   delegate_->InspectElementCompleted();
 }
 
+void DevToolsUIBindings::InspectedURLChanged(const std::string& url) {
+  content::NavigationController& controller = web_contents()->GetController();
+  content::NavigationEntry* entry = controller.GetActiveEntry();
+  // DevTools UI is not localized.
+  entry->SetTitle(
+      base::UTF8ToUTF16(base::StringPrintf(kTitleFormat, url.c_str())));
+  web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TITLE);
+}
+
 void DevToolsUIBindings::OpenInNewTab(const std::string& url) {
   delegate_->OpenInNewTab(url);
 }
@@ -680,8 +703,7 @@
 void DevToolsUIBindings::ShowDevToolsConfirmInfoBar(
     const base::string16& message,
     const InfoBarCallback& callback) {
-  DevToolsConfirmInfoBarDelegate::Create(
-      InfoBarService::FromWebContents(web_contents_),
+  DevToolsConfirmInfoBarDelegate::Create(delegate_->GetInfoBarService(),
       callback, message);
 }
 
diff --git a/chrome/browser/devtools/devtools_ui_bindings.h b/chrome/browser/devtools/devtools_ui_bindings.h
index ae86b4b..7a98cae 100644
--- a/chrome/browser/devtools/devtools_ui_bindings.h
+++ b/chrome/browser/devtools/devtools_ui_bindings.h
@@ -23,6 +23,7 @@
 #include "content/public/browser/notification_registrar.h"
 #include "ui/gfx/size.h"
 
+class InfoBarService;
 class Profile;
 
 namespace content {
@@ -58,6 +59,8 @@
 
     virtual void InspectedContentsClosing() = 0;
     virtual void OnLoadCompleted() = 0;
+    virtual InfoBarService* GetInfoBarService() = 0;
+    virtual void RenderProcessGone() = 0;
   };
 
   explicit DevToolsUIBindings(content::WebContents* web_contents);
@@ -91,6 +94,7 @@
   virtual void SetContentsResizingStrategy(
       const gfx::Insets& insets, const gfx::Size& min_size) OVERRIDE;
   virtual void InspectElementCompleted() OVERRIDE;
+  virtual void InspectedURLChanged(const std::string& url) OVERRIDE;
   virtual void MoveWindow(int x, int y) OVERRIDE;
   virtual void SetIsDocked(bool is_docked) OVERRIDE;
   virtual void OpenInNewTab(const std::string& url) OVERRIDE;
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc
index 5de3123..da8615c 100644
--- a/chrome/browser/devtools/devtools_window.cc
+++ b/chrome/browser/devtools/devtools_window.cc
@@ -13,6 +13,7 @@
 #include "base/values.h"
 #include "chrome/browser/chrome_page_zoom.h"
 #include "chrome/browser/file_select_helper.h"
+#include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_tab_helper.h"
@@ -44,7 +45,6 @@
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/page_transition_types.h"
 #include "content/public/common/url_constants.h"
@@ -480,12 +480,12 @@
     tab_strip_model->ActivateTabAt(inspected_tab_index, true);
 
     inspected_window->UpdateDevTools();
-    web_contents_->GetView()->SetInitialFocus();
+    web_contents_->SetInitialFocus();
     inspected_window->Show();
     // On Aura, focusing once is not enough. Do it again.
     // Note that focusing only here but not before isn't enough either. We just
     // need to focus twice.
-    web_contents_->GetView()->SetInitialFocus();
+    web_contents_->SetInitialFocus();
 
     PrefsTabHelper::CreateForWebContents(web_contents_);
     web_contents_->GetRenderViewHost()->SyncRendererPrefs();
@@ -504,7 +504,7 @@
 
   if (should_show_window) {
     browser_->window()->Show();
-    web_contents_->GetView()->SetInitialFocus();
+    web_contents_->SetInitialFocus();
   }
 
   DoAction(action);
@@ -863,7 +863,7 @@
 
 void DevToolsWindow::ActivateWindow() {
   if (is_docked_ && GetInspectedBrowserWindow())
-    web_contents_->GetView()->Focus();
+    web_contents_->Focus();
   else if (!is_docked_ && !browser_->window()->IsActive())
     browser_->window()->Activate();
 }
@@ -1013,6 +1013,19 @@
   web_contents_->GetRenderViewHost()->ClosePage();
 }
 
+InfoBarService* DevToolsWindow::GetInfoBarService() {
+  return is_docked_ ?
+      InfoBarService::FromWebContents(GetInspectedWebContents()) :
+      InfoBarService::FromWebContents(web_contents_);
+}
+
+void DevToolsWindow::RenderProcessGone() {
+  // Docked DevToolsWindow owns its web_contents_ and must delete it.
+  // Undocked web_contents_ are owned and handled by browser.
+  if (is_docked_)
+    CloseContents(web_contents_);
+}
+
 void DevToolsWindow::OnLoadCompleted() {
   // First seed inspected tab id for extension APIs.
   WebContents* inspected_web_contents = GetInspectedWebContents();
@@ -1054,7 +1067,7 @@
   browser_ = new Browser(Browser::CreateParams::CreateForDevTools(
       profile_,
       chrome::GetHostDesktopTypeForNativeView(
-          web_contents_->GetView()->GetNativeView())));
+          web_contents_->GetNativeView())));
   browser_->tab_strip_model()->AddWebContents(
       web_contents_, -1, content::PAGE_TRANSITION_AUTO_TOPLEVEL,
       TabStripModel::ADD_ACTIVE);
diff --git a/chrome/browser/devtools/devtools_window.h b/chrome/browser/devtools/devtools_window.h
index 379b0bd..82fa483 100644
--- a/chrome/browser/devtools/devtools_window.h
+++ b/chrome/browser/devtools/devtools_window.h
@@ -281,6 +281,8 @@
   virtual void SetWhitelistedShortcuts(const std::string& message) OVERRIDE;
   virtual void InspectedContentsClosing() OVERRIDE;
   virtual void OnLoadCompleted() OVERRIDE;
+  virtual InfoBarService* GetInfoBarService() OVERRIDE;
+  virtual void RenderProcessGone() OVERRIDE;
 
   void CreateDevToolsBrowser();
   BrowserWindow* GetInspectedBrowserWindow();
diff --git a/chrome/browser/download/download_dir_policy_handler.cc b/chrome/browser/download/download_dir_policy_handler.cc
index f7fed2c..1bd511b 100644
--- a/chrome/browser/download/download_dir_policy_handler.cc
+++ b/chrome/browser/download/download_dir_policy_handler.cc
@@ -69,6 +69,7 @@
 
   base::FilePath::StringType expanded_value;
 #if defined(OS_CHROMEOS)
+  bool download_to_drive = false;
   // TODO(kaliamoorthi): Clean up policy::path_parser and fold this code
   // into it. http://crbug.com/352627
   size_t position = string_value.find(kDriveNamePolicyVariableName);
@@ -79,6 +80,7 @@
                               parameters.user_id_hash)
                               .Append(kRootRelativeToDriveMount)
                               .value();
+      download_to_drive = true;
     }
     expanded_value = string_value.replace(
         position,
@@ -103,6 +105,12 @@
   // Otherwise, it would enable a user to bypass the mandatory policy.
   if (policies.Get(policy_name())->level == policy::POLICY_LEVEL_MANDATORY) {
     prefs->SetValue(prefs::kPromptForDownload,
-                    base::Value::CreateBooleanValue(false));
+                    new base::FundamentalValue(false));
+#if defined(OS_CHROMEOS)
+    if (download_to_drive) {
+      prefs->SetValue(prefs::kDisableDrive,
+                      new base::FundamentalValue(false));
+    }
+#endif
   }
 }
diff --git a/chrome/browser/download/download_dir_policy_handler_unittest.cc b/chrome/browser/download/download_dir_policy_handler_unittest.cc
index 2729242..fb8dc5f 100644
--- a/chrome/browser/download/download_dir_policy_handler_unittest.cc
+++ b/chrome/browser/download/download_dir_policy_handler_unittest.cc
@@ -105,6 +105,12 @@
   EXPECT_TRUE(value->GetAsBoolean(&prompt_for_download));
   EXPECT_FALSE(prompt_for_download);
 
+  bool disable_drive;
+  EXPECT_TRUE(store_->GetValue(prefs::kDisableDrive, &value));
+  EXPECT_TRUE(value);
+  EXPECT_TRUE(value->GetAsBoolean(&disable_drive));
+  EXPECT_FALSE(disable_drive);
+
   std::string download_directory;
   EXPECT_TRUE(store_->GetValue(prefs::kDownloadDefaultDirectory, &value));
   EXPECT_TRUE(value);
@@ -112,6 +118,14 @@
   EXPECT_EQ(GetExpectedDownloadDirectory(), download_directory);
 
   policy.Set(policy::key::kDownloadDirectory,
+             policy::POLICY_LEVEL_MANDATORY,
+             policy::POLICY_SCOPE_USER,
+             new base::StringValue(kUserIDHash),
+             NULL);
+  UpdateProviderPolicy(policy);
+  EXPECT_FALSE(recommended_store_->GetValue(prefs::kDisableDrive, NULL));
+
+  policy.Set(policy::key::kDownloadDirectory,
              policy::POLICY_LEVEL_RECOMMENDED,
              policy::POLICY_SCOPE_USER,
              new base::StringValue(std::string(kDriveNamePolicyVariableName) +
@@ -120,6 +134,7 @@
   UpdateProviderPolicy(policy);
 
   EXPECT_FALSE(recommended_store_->GetValue(prefs::kPromptForDownload, NULL));
+  EXPECT_FALSE(recommended_store_->GetValue(prefs::kDisableDrive, NULL));
 
   EXPECT_TRUE(
       recommended_store_->GetValue(prefs::kDownloadDefaultDirectory, &value));
@@ -136,6 +151,7 @@
   UpdateProviderPolicy(policy);
 
   EXPECT_FALSE(recommended_store_->GetValue(prefs::kPromptForDownload, NULL));
+  EXPECT_FALSE(recommended_store_->GetValue(prefs::kDisableDrive, NULL));
 
   EXPECT_TRUE(
       recommended_store_->GetValue(prefs::kDownloadDefaultDirectory, &value));
diff --git a/chrome/browser/download/download_extensions.cc b/chrome/browser/download/download_extensions.cc
index 4d36aa0..75ebb01 100644
--- a/chrome/browser/download/download_extensions.cc
+++ b/chrome/browser/download/download_extensions.cc
@@ -209,7 +209,7 @@
   base::FilePath::StringType extension(path.FinalExtension());
   if (extension.empty())
     return NOT_DANGEROUS;
-  if (!IsStringASCII(extension))
+  if (!base::IsStringASCII(extension))
     return NOT_DANGEROUS;
 #if defined(OS_WIN)
   std::string ascii_extension = base::UTF16ToASCII(extension);
diff --git a/chrome/browser/download/download_file_picker.cc b/chrome/browser/download/download_file_picker.cc
index a2d2d3e..b1af519 100644
--- a/chrome/browser/download/download_file_picker.cc
+++ b/chrome/browser/download/download_file_picker.cc
@@ -12,7 +12,6 @@
 #include "content/public/browser/download_item.h"
 #include "content/public/browser/download_manager.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -80,8 +79,7 @@
   file_type_info.include_all_files = true;
   file_type_info.support_drive = true;
   gfx::NativeWindow owning_window = web_contents ?
-      platform_util::GetTopLevel(web_contents->GetView()->GetNativeView()) :
-      NULL;
+      platform_util::GetTopLevel(web_contents->GetNativeView()) : NULL;
 
   select_file_dialog_->SelectFile(ui::SelectFileDialog::SELECT_SAVEAS_FILE,
                                   base::string16(),
diff --git a/chrome/browser/download/download_request_limiter.cc b/chrome/browser/download/download_request_limiter.cc
index 9431b79..504af77 100644
--- a/chrome/browser/download/download_request_limiter.cc
+++ b/chrome/browser/download/download_request_limiter.cc
@@ -110,14 +110,12 @@
   }
 }
 
-void DownloadRequestLimiter::TabDownloadState::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void DownloadRequestLimiter::TabDownloadState::WebContentsDestroyed() {
   // Tab closed, no need to handle closing the dialog as it's owned by the
   // WebContents.
 
   NotifyCallbacks(false);
-  // Note that web_contents() is NULL at this point.
-  host_->Remove(this, web_contents);
+  host_->Remove(this, web_contents());
   // WARNING: We've been deleted.
 }
 
diff --git a/chrome/browser/download/download_request_limiter.h b/chrome/browser/download/download_request_limiter.h
index 4ecf370..83552ed 100644
--- a/chrome/browser/download/download_request_limiter.h
+++ b/chrome/browser/download/download_request_limiter.h
@@ -112,8 +112,7 @@
     // Invoked when a user gesture occurs (mouse click, enter or space). This
     // may result in invoking Remove on DownloadRequestLimiter.
     virtual void DidGetUserGesture() OVERRIDE;
-    virtual void WebContentsDestroyed(
-        content::WebContents* web_contents) OVERRIDE;
+    virtual void WebContentsDestroyed() OVERRIDE;
 
     // Asks the user if they really want to allow the download.
     // See description above CanDownloadOnIOThread for details on lifetime of
diff --git a/chrome/browser/download/download_shelf.cc b/chrome/browser/download/download_shelf.cc
index d54141c..ddd4a85 100644
--- a/chrome/browser/download/download_shelf.cc
+++ b/chrome/browser/download/download_shelf.cc
@@ -24,7 +24,6 @@
 #include "content/public/browser/download_item.h"
 #include "content/public/browser/download_manager.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/locale_settings.h"
 #include "grit/theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -360,7 +359,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   if (DownloadItemModel(download).ShouldShowDownloadStartedAnimation() &&
       shelf_tab &&
-      platform_util::IsVisible(shelf_tab->GetView()->GetNativeView()) &&
+      platform_util::IsVisible(shelf_tab->GetNativeView()) &&
       gfx::Animation::ShouldRenderRichAnimation()) {
     DownloadStartedAnimation::Show(shelf_tab);
   }
diff --git a/chrome/browser/download/download_target_determiner.cc b/chrome/browser/download/download_target_determiner.cc
index bc86f14..e7bb16d 100644
--- a/chrome/browser/download/download_target_determiner.cc
+++ b/chrome/browser/download/download_target_determiner.cc
@@ -241,6 +241,9 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DVLOG(20) << "Extension suggested path: " << suggested_path.AsUTF8Unsafe();
 
+  // Extensions should not call back here more than once.
+  DCHECK_EQ(STATE_RESERVE_VIRTUAL_PATH, next_state_);
+
   if (!suggested_path.empty()) {
     // If an extension overrides the filename, then the target directory will be
     // forced to download_prefs_->DownloadPath() since extensions cannot place
@@ -284,6 +287,8 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DVLOG(20) << "Reserved path: " << path.AsUTF8Unsafe()
             << " Verified:" << verified;
+  DCHECK_EQ(STATE_PROMPT_USER_FOR_DOWNLOAD_PATH, next_state_);
+
   should_prompt_ = (should_prompt_ || !verified);
   virtual_path_ = path;
   DoLoop();
@@ -315,6 +320,8 @@
     CancelOnFailureAndDeleteSelf();
     return;
   }
+  DCHECK_EQ(STATE_DETERMINE_LOCAL_PATH, next_state_);
+
   virtual_path_ = virtual_path;
   download_prefs_->SetSaveFilePath(virtual_path_.DirName());
   DoLoop();
@@ -345,6 +352,8 @@
     CancelOnFailureAndDeleteSelf();
     return;
   }
+  DCHECK_EQ(STATE_DETERMINE_MIME_TYPE, next_state_);
+
   local_path_ = local_path;
   DoLoop();
 }
@@ -372,6 +381,8 @@
     const std::string& mime_type) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DVLOG(20) << "MIME type: " << mime_type;
+  DCHECK_EQ(STATE_DETERMINE_IF_HANDLED_SAFELY_BY_BROWSER, next_state_);
+
   mime_type_ = mime_type;
   DoLoop();
 }
@@ -477,8 +488,9 @@
 void DownloadTargetDeterminer::DetermineIfHandledSafelyDone(
     bool is_handled_safely) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  is_filetype_handled_safely_ = is_handled_safely;
   DVLOG(20) << "Is file type handled safely: " << is_filetype_handled_safely_;
+  DCHECK_EQ(STATE_CHECK_DOWNLOAD_URL, next_state_);
+  is_filetype_handled_safely_ = is_handled_safely;
   DoLoop();
 }
 
@@ -499,6 +511,7 @@
     content::DownloadDangerType danger_type) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DVLOG(20) << "URL Check Result:" << danger_type;
+  DCHECK_EQ(STATE_CHECK_VISITED_REFERRER_BEFORE, next_state_);
   danger_type_ = danger_type;
   DoLoop();
 }
@@ -549,6 +562,7 @@
 void DownloadTargetDeterminer::CheckVisitedReferrerBeforeDone(
     bool visited_referrer_before) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_EQ(STATE_DETERMINE_INTERMEDIATE_PATH, next_state_);
   if (IsDangerousFile(
           visited_referrer_before ? VISITED_REFERRER : NO_VISITS_TO_REFERRER))
     danger_type_ = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
diff --git a/chrome/browser/download/save_package_file_picker.cc b/chrome/browser/download/save_package_file_picker.cc
index da18db3..3a320f7 100644
--- a/chrome/browser/download/save_package_file_picker.cc
+++ b/chrome/browser/download/save_package_file_picker.cc
@@ -22,7 +22,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/save_page_type.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -211,7 +210,7 @@
         &file_type_info,
         file_type_index,
         default_extension_copy,
-        platform_util::GetTopLevel(web_contents->GetView()->GetNativeView()),
+        platform_util::GetTopLevel(web_contents->GetNativeView()),
         NULL);
   } else {
     // Just use 'suggested_path_copy' instead of opening the dialog prompt.
diff --git a/chrome/browser/errorpage_browsertest.cc b/chrome/browser/errorpage_browsertest.cc
index b34c1a5..f6c41e9 100644
--- a/chrome/browser/errorpage_browsertest.cc
+++ b/chrome/browser/errorpage_browsertest.cc
@@ -7,10 +7,12 @@
 #include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/path_service.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/lock.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_remover.h"
 #include "chrome/browser/google/google_util.h"
@@ -26,6 +28,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
@@ -142,34 +145,28 @@
   return l10n_util::GetStringUTF8(IDS_ERRORPAGES_BUTTON_LOAD_STALE);
 }
 
+void AddProtocolHandlerForURL(
+    const GURL& url,
+    scoped_ptr<URLRequestJobFactory::ProtocolHandler> handler) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler(
+      url, handler.Pass());
+}
+
 // A protocol handler that fails a configurable number of requests, then
 // succeeds all requests after that, keeping count of failures and successes.
 class FailFirstNRequestsProtocolHandler
     : public URLRequestJobFactory::ProtocolHandler {
  public:
-  FailFirstNRequestsProtocolHandler(const GURL& url, int requests_to_fail)
-      : url_(url), requests_(0), failures_(0),
-        requests_to_fail_(requests_to_fail) {}
+  explicit FailFirstNRequestsProtocolHandler(int requests_to_fail)
+      : requests_(0), failures_(0), requests_to_fail_(requests_to_fail) {}
   virtual ~FailFirstNRequestsProtocolHandler() {}
 
-  // This method deliberately violates pointer ownership rules:
-  // AddUrlProtocolHandler() takes a scoped_ptr, taking ownership of the
-  // supplied ProtocolHandler (i.e., |this|), but also having the caller retain
-  // a pointer to |this| so the caller can use the requests() and failures()
-  // accessors.
-  void AddUrlHandler() {
-    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-    scoped_ptr<URLRequestJobFactory::ProtocolHandler> scoped_handler(this);
-    net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler(
-        url_,
-        scoped_handler.Pass());
-  }
-
   // net::URLRequestJobFactory::ProtocolHandler implementation
   virtual net::URLRequestJob* MaybeCreateJob(
       net::URLRequest* request,
       net::NetworkDelegate* network_delegate) const OVERRIDE {
-    DCHECK_EQ(url_, request->url());
+    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     requests_++;
     if (failures_ < requests_to_fail_) {
       failures_++;
@@ -190,7 +187,6 @@
   int failures() const { return failures_; }
 
  private:
-  const GURL url_;
   // These are mutable because MaybeCreateJob is const but we want this state
   // for testing.
   mutable int requests_;
@@ -198,6 +194,96 @@
   int requests_to_fail_;
 };
 
+// A protocol handler that serves LinkDoctor responses.  It also allows waiting
+// until a certain number of requests have been sent.
+// TODO(mmenke):  Wait until responses have been received instead.
+class LinkDoctorProtocolHandler
+    : public URLRequestJobFactory::ProtocolHandler {
+ public:
+  LinkDoctorProtocolHandler()
+      : num_requests_(0),
+        requests_to_wait_for_(-1),
+        weak_factory_(this) {
+  }
+
+  virtual ~LinkDoctorProtocolHandler() {}
+
+  // net::URLRequestJobFactory::ProtocolHandler implementation
+  virtual net::URLRequestJob* MaybeCreateJob(
+      net::URLRequest* request,
+      net::NetworkDelegate* network_delegate) const OVERRIDE {
+    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::Bind(&LinkDoctorProtocolHandler::RequestCreated,
+                   weak_factory_.GetWeakPtr()));
+
+    base::FilePath root_http;
+    PathService::Get(chrome::DIR_TEST_DATA, &root_http);
+    return new content::URLRequestMockHTTPJob(
+        request, network_delegate,
+        root_http.AppendASCII("mock-link-doctor.json"));
+  }
+
+  void WaitForRequests(int requests_to_wait_for) {
+    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+    DCHECK_EQ(-1, requests_to_wait_for_);
+    DCHECK(!run_loop_);
+
+    if (requests_to_wait_for >= num_requests_)
+      return;
+
+    requests_to_wait_for_ = requests_to_wait_for;
+    run_loop_.reset(new base::RunLoop());
+    run_loop_->Run();
+    run_loop_.reset();
+    requests_to_wait_for_ = -1;
+    EXPECT_EQ(num_requests_, requests_to_wait_for);
+  }
+
+  // It is up to the caller to wait until all relevant requests has been
+  // created, either through calling WaitForRequests or some other manner,
+  // before calling this method.
+  int num_requests() const {
+    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+    return num_requests_;
+  }
+
+ private:
+  void RequestCreated() {
+    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+    num_requests_++;
+    if (num_requests_ == requests_to_wait_for_)
+      run_loop_->Quit();
+  }
+
+  // These are only used on the UI thread.
+  int num_requests_;
+  int requests_to_wait_for_;
+  scoped_ptr<base::RunLoop> run_loop_;
+
+  // This prevents any risk of flake if any test doesn't wait for a request
+  // it sent.  Mutable so it can be accessed from a const function.
+  mutable base::WeakPtrFactory<LinkDoctorProtocolHandler> weak_factory_;
+};
+
+void InstallMockProtocolHandlers(
+    const GURL& search_url,
+    scoped_ptr<URLRequestJobFactory::ProtocolHandler> link_doctor_handler) {
+  chrome_browser_net::SetUrlRequestMocksEnabled(true);
+
+  AddProtocolHandlerForURL(google_util::LinkDoctorBaseURL(),
+                            link_doctor_handler.Pass());
+
+  // Add a mock for the search engine the error page will use.
+  base::FilePath root_http;
+  PathService::Get(chrome::DIR_TEST_DATA, &root_http);
+  content::URLRequestMockHTTPJob::AddHostnameToFileHandler(
+      search_url.host(), root_http.AppendASCII("title3.html"));
+}
+
 class ErrorPageTest : public InProcessBrowserTest {
  public:
   enum HistoryNavigationDirection {
@@ -205,6 +291,15 @@
     HISTORY_NAVIGATE_FORWARD,
   };
 
+  ErrorPageTest() : link_doctor_handler_(NULL) {}
+  virtual ~ErrorPageTest() {}
+
+  // Navigates the active tab to a mock url created for the file at |file_path|.
+  // Needed for StaleCacheStatus and StaleCacheStatusFailedCorrections tests.
+  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+    command_line->AppendSwitch(switches::kEnableOfflineLoadStaleCache);
+  }
+
   // Navigates the active tab to a mock url created for the file at |file_path|.
   void NavigateToFileURL(const base::FilePath::StringType& file_path) {
     ui_test_utils::NavigateToURL(
@@ -304,22 +399,24 @@
             (testing::AssertionFailure() << "Exception message is " << result));
   }
 
- protected:
-  static void EnableMocks(const GURL& search_url) {
-    chrome_browser_net::SetUrlRequestMocksEnabled(true);
-
-    // Add a mock for the search engine the error page will use.
-    base::FilePath root_http;
-    PathService::Get(chrome::DIR_TEST_DATA, &root_http);
-    content::URLRequestMockHTTPJob::AddHostnameToFileHandler(
-        search_url.host(), root_http.AppendASCII("title3.html"));
+  LinkDoctorProtocolHandler* link_doctor_handler() {
+    return link_doctor_handler_;
   }
 
+ protected:
   virtual void SetUpOnMainThread() OVERRIDE {
+    link_doctor_handler_ = new LinkDoctorProtocolHandler();
+    scoped_ptr<URLRequestJobFactory::ProtocolHandler> owned_handler(
+        link_doctor_handler_);
+    // Ownership of the |protocol_handler_| is passed to an object the IO
+    // thread, but a pointer is kept in the test fixture.  As soon as anything
+    // calls URLRequestFilter::ClearHandlers(), |protocol_handler_| can become
+    // invalid.
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
-        base::Bind(&ErrorPageTest::EnableMocks,
-                   google_util::GetGoogleSearchURL(browser()->profile())));
+        base::Bind(&InstallMockProtocolHandlers,
+                   google_util::GetGoogleSearchURL(browser()->profile()),
+                   base::Passed(&owned_handler)));
   }
 
   // Returns a GURL that results in a DNS error.
@@ -357,6 +454,8 @@
     }
     test_navigation_observer.Wait();
   }
+
+  LinkDoctorProtocolHandler* link_doctor_handler_;
 };
 
 class TestFailProvisionalLoadObserver : public content::WebContentsObserver {
@@ -411,6 +510,7 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(1, link_doctor_handler()->num_requests());
 }
 
 // See crbug.com/109669
@@ -428,6 +528,7 @@
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
   GoBackAndWaitForTitle("Title Of Awesomeness", 1);
+  EXPECT_EQ(1, link_doctor_handler()->num_requests());
 }
 
 // See crbug.com/109669
@@ -444,13 +545,16 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(1, link_doctor_handler()->num_requests());
 
   NavigateToFileURL(FILE_PATH_LITERAL("title3.html"));
 
   GoBackAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(2, link_doctor_handler()->num_requests());
 
   GoBackAndWaitForTitle("Title Of Awesomeness", 1);
+  EXPECT_EQ(2, link_doctor_handler()->num_requests());
 }
 
 // See crbug.com/109669
@@ -467,16 +571,19 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(1, link_doctor_handler()->num_requests());
 
   NavigateToFileURL(FILE_PATH_LITERAL("title3.html"));
 
   GoBackAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(2, link_doctor_handler()->num_requests());
 
   GoBackAndWaitForTitle("Title Of Awesomeness", 1);
 
   GoForwardAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(3, link_doctor_handler()->num_requests());
 }
 
 // See crbug.com/109669
@@ -493,18 +600,22 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(1, link_doctor_handler()->num_requests());
 
   NavigateToFileURL(FILE_PATH_LITERAL("title2.html"));
 
   GoBackAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(2, link_doctor_handler()->num_requests());
 
   GoBackAndWaitForTitle("Title Of More Awesomeness", 1);
 
   GoForwardAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(3, link_doctor_handler()->num_requests());
 
   GoForwardAndWaitForTitle("Title Of Awesomeness", 1);
+  EXPECT_EQ(3, link_doctor_handler()->num_requests());
 }
 
 // See crbug.com/109669
@@ -520,21 +631,31 @@
   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), GetDnsErrorURL(), 2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(1, link_doctor_handler()->num_requests());
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
 
   // Do a search and make sure the browser ends up at the right page.
-  content::TestNavigationObserver nav_observer(
-      browser()->tab_strip_model()->GetActiveWebContents(),
-      1);
+  content::TestNavigationObserver nav_observer(web_contents, 1);
   content::TitleWatcher title_watcher(
-      browser()->tab_strip_model()->GetActiveWebContents(),
+      web_contents,
       base::ASCIIToUTF16("Title Of More Awesomeness"));
-  ASSERT_TRUE(content::ExecuteScript(
-                  browser()->tab_strip_model()->GetActiveWebContents(),
-                  "document.getElementById('search-button').click();"));
+  // Can't use content::ExecuteScript because it waits for scripts to send
+  // notification that they've run, and scripts that trigger a navigation may
+  // not send that notification.
+  web_contents->GetMainFrame()->ExecuteJavaScript(
+      base::ASCIIToUTF16("document.getElementById('search-button').click();"));
   nav_observer.Wait();
   EXPECT_EQ(base::ASCIIToUTF16("Title Of More Awesomeness"),
             title_watcher.WaitAndGetTitle());
 
+  // There should have been another Link Doctor request, for tracking purposes.
+  // Have to wait for it, since the search page does not depend on having
+  // sent the tracking request.
+  link_doctor_handler()->WaitForRequests(2);
+  EXPECT_EQ(2, link_doctor_handler()->num_requests());
+
   // Check the path and query string.
   std::string url;
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
@@ -547,6 +668,75 @@
   // Go back to the error page, to make sure the history is correct.
   GoBackAndWaitForNavigations(2);
   ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(3, link_doctor_handler()->num_requests());
+}
+
+// Test that the reload button on a DNS error page works.
+IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_DoReload) {
+  // The first navigation should fail, and the second one should be the error
+  // page.
+  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
+       browser(), GetDnsErrorURL(), 2);
+  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(1, link_doctor_handler()->num_requests());
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  // Clicking the reload button should load the error page again, and there
+  // should be two commits, as before.
+  content::TestNavigationObserver nav_observer(web_contents, 2);
+  // Can't use content::ExecuteScript because it waits for scripts to send
+  // notification that they've run, and scripts that trigger a navigation may
+  // not send that notification.
+  web_contents->GetMainFrame()->ExecuteJavaScript(
+      base::ASCIIToUTF16("document.getElementById('reload-button').click();"));
+  nav_observer.Wait();
+  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+
+  // There should have two more requests to the correction service:  One for the
+  // new error page, and one for tracking purposes.  Have to make sure to wait
+  // for the tracking request, since the new error page does not depend on it.
+  link_doctor_handler()->WaitForRequests(3);
+  EXPECT_EQ(3, link_doctor_handler()->num_requests());
+}
+
+// Test that clicking links on a DNS error page works.
+IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_DoClickLink) {
+  // The first navigation should fail, and the second one should be the error
+  // page.
+  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
+       browser(), GetDnsErrorURL(), 2);
+  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
+  EXPECT_EQ(1, link_doctor_handler()->num_requests());
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  // Simulate a click on a link.
+
+  content::TitleWatcher title_watcher(
+      web_contents,
+      base::ASCIIToUTF16("Title Of Awesomeness"));
+  std::string link_selector =
+      "document.querySelector('a[href=\"http://mock.http/title2.html\"]')";
+  // The tracking request is triggered by onmousedown, so it catches middle
+  // mouse button clicks, as well as left clicks.
+  web_contents->GetMainFrame()->ExecuteJavaScript(
+      base::ASCIIToUTF16(link_selector + ".onmousedown();"));
+  // Can't use content::ExecuteScript because it waits for scripts to send
+  // notification that they've run, and scripts that trigger a navigation may
+  // not send that notification.
+  web_contents->GetMainFrame()->ExecuteJavaScript(
+      base::ASCIIToUTF16(link_selector + ".click();"));
+  EXPECT_EQ(base::ASCIIToUTF16("Title Of Awesomeness"),
+            title_watcher.WaitAndGetTitle());
+
+  // There should have been a tracking request to the correction service.  Have
+  // to make sure to wait the tracking request, since the new page does not
+  // depend on it.
+  link_doctor_handler()->WaitForRequests(2);
+  EXPECT_EQ(2, link_doctor_handler()->num_requests());
 }
 
 // Test that a DNS error occuring in an iframe does not result in showing
@@ -562,6 +752,7 @@
   EXPECT_EQ(2,
       browser()->tab_strip_model()->GetActiveWebContents()->
           GetController().GetEntryCount());
+  EXPECT_EQ(0, link_doctor_handler()->num_requests());
 }
 
 // This test fails regularly on win_rel trybots. See crbug.com/121540
@@ -576,6 +767,7 @@
   NavigateToFileURL(FILE_PATH_LITERAL("title2.html"));
   NavigateToFileURL(FILE_PATH_LITERAL("iframe_dns_error.html"));
   GoBackAndWaitForTitle("Title Of Awesomeness", 1);
+  EXPECT_EQ(0, link_doctor_handler()->num_requests());
 }
 
 // This test fails regularly on win_rel trybots. See crbug.com/121540
@@ -593,6 +785,7 @@
   NavigateToFileURL(FILE_PATH_LITERAL("iframe_dns_error.html"));
   GoBackAndWaitForTitle("Title Of Awesomeness", 1);
   GoForwardAndWaitForTitle("Blah", 1);
+  EXPECT_EQ(0, link_doctor_handler()->num_requests());
 }
 
 // Test that a DNS error occuring in an iframe, once the main document is
@@ -657,6 +850,7 @@
     EXPECT_EQ(fail_url, fail_observer.fail_url());
     EXPECT_EQ(2, wc->GetController().GetEntryCount());
   }
+  EXPECT_EQ(0, link_doctor_handler()->num_requests());
 }
 
 // Checks that navigation corrections are not loaded when we receive an actual
@@ -667,6 +861,7 @@
           base::FilePath(FILE_PATH_LITERAL("page404.html"))),
       "SUCCESS",
       1);
+  EXPECT_EQ(0, link_doctor_handler()->num_requests());
 }
 
 // Checks that when an error occurs, the stale cache status of the page
@@ -714,6 +909,7 @@
       browser(), test_url, 1);
   EXPECT_TRUE(ProbeStaleCopyValue(false));
   EXPECT_FALSE(IsDisplayingText(browser(), GetLoadStaleButtonLabel()));
+  EXPECT_EQ(0, link_doctor_handler()->num_requests());
 }
 
 class ErrorPageAutoReloadTest : public InProcessBrowserTest {
@@ -723,16 +919,22 @@
   }
 
   void InstallProtocolHandler(const GURL& url, int requests_to_fail) {
-    protocol_handler_ = new FailFirstNRequestsProtocolHandler(
-        url,
-        requests_to_fail);
+    protocol_handler_ = new FailFirstNRequestsProtocolHandler(requests_to_fail);
+    scoped_ptr<URLRequestJobFactory::ProtocolHandler> owned_handler(
+        protocol_handler_);
+
     // Tests don't need to wait for this task to complete before using the
     // filter; any requests that might be affected by it will end up in the IO
     // thread's message loop after this posted task anyway.
+    //
+    // Ownership of the |protocol_handler_| is passed to an object the IO
+    // thread, but a pointer is kept in the test fixture.  As soon as anything
+    // calls URLRequestFilter::ClearHandlers(), |protocol_handler_| can become
+    // invalid.
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
-        base::Bind(&ErrorPageAutoReloadTest::AddFilters,
-                   base::Unretained(this)));
+        base::Bind(&AddProtocolHandlerForURL, url,
+                   base::Passed(&owned_handler)));
   }
 
   void NavigateToURLAndWaitForTitle(const GURL& url,
@@ -754,15 +956,6 @@
   }
 
  private:
-  void AddFilters() {
-    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-    // Note: in theory, AddUrlHandler gives ownership of |protocol_handler_| to
-    // URLRequestFilter. As soon as anything calls
-    // URLRequestFilter::ClearHandlers(), |protocol_handler_| can become
-    // invalid.
-    protocol_handler_->AddUrlHandler();
-  }
-
   FailFirstNRequestsProtocolHandler* protocol_handler_;
 };
 
diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc
index ef87525..1a67167 100644
--- a/chrome/browser/extensions/active_tab_permission_granter.cc
+++ b/chrome/browser/extensions/active_tab_permission_granter.cc
@@ -83,8 +83,7 @@
   ClearActiveExtensionsAndNotify();
 }
 
-void ActiveTabPermissionGranter::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void ActiveTabPermissionGranter::WebContentsDestroyed() {
   ClearActiveExtensionsAndNotify();
 }
 
diff --git a/chrome/browser/extensions/active_tab_permission_granter.h b/chrome/browser/extensions/active_tab_permission_granter.h
index bf51ed0..4945915 100644
--- a/chrome/browser/extensions/active_tab_permission_granter.h
+++ b/chrome/browser/extensions/active_tab_permission_granter.h
@@ -45,8 +45,7 @@
   virtual void DidNavigateMainFrame(
       const content::LoadCommittedDetails& details,
       const content::FrameNavigateParams& params) OVERRIDE;
-  virtual void WebContentsDestroyed(content::WebContents* web_contents)
-      OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // extensions::ExtensionRegistryObserver implementation.
   virtual void OnExtensionUnloaded(content::BrowserContext* browser_context,
diff --git a/chrome/browser/extensions/activity_log/activity_log.cc b/chrome/browser/extensions/activity_log/activity_log.cc
index 09c209b..16fc3dd 100644
--- a/chrome/browser/extensions/activity_log/activity_log.cc
+++ b/chrome/browser/extensions/activity_log/activity_log.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/extensions/activity_log/counting_policy.h"
 #include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
 #include "chrome/browser/extensions/api/activity_log_private/activity_log_private_api.h"
-#include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
 #include "chrome/browser/extensions/install_tracker.h"
 #include "chrome/browser/extensions/install_tracker_factory.h"
@@ -32,10 +31,12 @@
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
+#include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/extension_system_provider.h"
 #include "extensions/browser/extensions_browser_client.h"
 #include "extensions/common/extension.h"
+#include "extensions/common/one_shot_event.h"
 #include "third_party/re2/re2/re2.h"
 #include "url/gurl.h"
 
@@ -498,7 +499,7 @@
   if (watchdog_apps_active_ == 0 &&
       !CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableExtensionActivityLogging)) {
-   db_enabled_ = false;
+    db_enabled_ = false;
   }
 }
 
@@ -574,16 +575,11 @@
     const GURL& on_url) {
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
-  const ExtensionService* extension_service =
-      ExtensionSystem::Get(profile)->extension_service();
-  const ExtensionSet* extensions = extension_service->extensions();
-  const prerender::PrerenderManager* prerender_manager =
-      prerender::PrerenderManagerFactory::GetForProfile(
-          Profile::FromBrowserContext(web_contents->GetBrowserContext()));
-
+  ExtensionRegistry* registry = ExtensionRegistry::Get(profile);
   for (ExecutingScriptsMap::const_iterator it = extension_ids.begin();
        it != extension_ids.end(); ++it) {
-    const Extension* extension = extensions->GetByID(it->first);
+    const Extension* extension =
+        registry->GetExtensionById(it->first, ExtensionRegistry::ENABLED);
     if (!extension || ActivityLogAPI::IsExtensionWhitelisted(extension->id()))
       continue;
 
@@ -600,6 +596,9 @@
       action->set_page_title(base::UTF16ToUTF8(web_contents->GetTitle()));
       action->set_page_incognito(
           web_contents->GetBrowserContext()->IsOffTheRecord());
+
+      const prerender::PrerenderManager* prerender_manager =
+          prerender::PrerenderManagerFactory::GetForProfile(profile);
       if (prerender_manager &&
           prerender_manager->IsWebContentsPrerendering(web_contents, NULL))
         action->mutable_other()->SetBoolean(constants::kActionPrerender, true);
diff --git a/chrome/browser/extensions/activity_log/ad_network_database.cc b/chrome/browser/extensions/activity_log/ad_network_database.cc
index 3ca6700..ead3e31 100644
--- a/chrome/browser/extensions/activity_log/ad_network_database.cc
+++ b/chrome/browser/extensions/activity_log/ad_network_database.cc
@@ -4,105 +4,15 @@
 
 #include "chrome/browser/extensions/activity_log/ad_network_database.h"
 
-#include "base/basictypes.h"
 #include "base/lazy_instance.h"
-#include "base/memory/ref_counted_memory.h"
-#include "crypto/secure_hash.h"
-#include "crypto/sha2.h"
+#include "chrome/browser/extensions/activity_log/hashed_ad_network_database.h"
 #include "grit/browser_resources.h"
 #include "ui/base/resource/resource_bundle.h"
-#include "url/gurl.h"
 
 namespace extensions {
 
 namespace {
 
-// We use a hash size of 8 for these for three reasons.
-// 1. It saves us a bit on space, and, since we have to store these in memory
-//    (reading from disk would be far too slow because these checks are
-//    performed synchronously), that space is important.
-// 2. Since we don't store full hashes, reconstructing the list is more
-//    difficult. This may mean we get a few incorrect hits, but the security is
-//    worth the (very small) amount of noise.
-// 3. It fits nicely into a int64.
-const size_t kUrlHashSize = 8u;
-COMPILE_ASSERT(kUrlHashSize <= sizeof(int64), url_hashes_must_fit_into_a_int64);
-
-const size_t kChecksumHashSize = 32u;
-
-class AdNetworkDatabaseImpl : public AdNetworkDatabase {
- public:
-  AdNetworkDatabaseImpl();
-  virtual ~AdNetworkDatabaseImpl();
-
- private:
-  virtual bool IsAdNetwork(const GURL& url) const OVERRIDE;
-
-  // Initialize the AdNetworkDatabase. This means initializing the set of
-  // hashes from the shared memory.
-  void Init();
-
-  // The set of partial hashes for known ad networks.
-  base::hash_set<int64> entries_;
-};
-
-AdNetworkDatabaseImpl::AdNetworkDatabaseImpl() {
-  Init();
-}
-
-AdNetworkDatabaseImpl::~AdNetworkDatabaseImpl() {}
-
-void AdNetworkDatabaseImpl::Init() {
-  base::RefCountedStaticMemory* entries_memory =
-      ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
-          IDR_AD_NETWORK_HASHES);
-
-  // This can legitimately happen in unit tests.
-  if (!entries_memory)
-    return;
-
-  const size_t size = entries_memory->size();
-  const unsigned char* const front = entries_memory->front();
-  if (size < kChecksumHashSize ||
-      (size - kChecksumHashSize) % kUrlHashSize != 0) {
-    NOTREACHED();
-    return;
-  }
-
-  // The format of the data resource is fairly straight-forward:
-  // <32-bit checksum><list of 64-bit hashes of hosts>, with no linebreaks or
-  // other separations.
-  scoped_ptr<crypto::SecureHash> hash(
-      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
-
-  hash->Update(front + kChecksumHashSize, size - kChecksumHashSize);
-  char hash_value[kChecksumHashSize];
-  hash->Finish(hash_value, kChecksumHashSize);
-  // If the checksum doesn't match, abort.
-  if (memcmp(hash_value, front, kChecksumHashSize) != 0) {
-    NOTREACHED();
-    return;
-  }
-
-  // Construct and insert all hashes.
-  for (const unsigned char* index = front + kChecksumHashSize;
-       index < front + size;
-       index += kUrlHashSize) {
-    int64 value = 0;
-    memcpy(&value, index, kUrlHashSize);
-    entries_.insert(value);
-  }
-}
-
-bool AdNetworkDatabaseImpl::IsAdNetwork(const GURL& url) const {
-  int64 hash = 0;
-  crypto::SHA256HashString(url.host(), &hash, sizeof(hash));
-  // If initialization failed (most likely because this is a unittest), then
-  // |entries_| is never populated and we are guaranteed to return false - which
-  // is desired default behavior.
-  return entries_.count(hash) != 0;
-}
-
 class AdNetworkDatabaseFactory {
  public:
   AdNetworkDatabaseFactory();
@@ -120,8 +30,11 @@
 
 const AdNetworkDatabase* AdNetworkDatabaseFactory::GetDatabase() {
   // Construct a new database, if we don't have one.
-  if (!database_.get())
-    database_.reset(new AdNetworkDatabaseImpl());
+  if (!database_.get()) {
+    database_.reset(new HashedAdNetworkDatabase(
+        ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
+            IDR_AD_NETWORK_HASHES)));
+  }
 
   return database_.get();
 }
diff --git a/chrome/browser/extensions/activity_log/ad_network_database_unittest.cc b/chrome/browser/extensions/activity_log/ad_network_database_unittest.cc
deleted file mode 100644
index 47264e8..0000000
--- a/chrome/browser/extensions/activity_log/ad_network_database_unittest.cc
+++ /dev/null
@@ -1,219 +0,0 @@
-// 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.
-
-#include "base/basictypes.h"
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/extensions/activity_log/ad_network_database.h"
-#include "crypto/secure_hash.h"
-#include "crypto/sha2.h"
-#include "grit/browser_resources.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "url/gurl.h"
-
-namespace extensions {
-
-namespace {
-
-// A list of fake ad networks.
-const char* kAdNetworkHosts[] = {
-  "alpha.adnetwork",
-  "bravo.adnetwork",
-  "charlie.delta.adnetwork"
-};
-
-// The number of ad networks for these tests.
-const size_t kNumAdNetworkHosts = arraysize(kAdNetworkHosts);
-
-// Each hash of an ad network is stored in an int64.
-const size_t kAdNetworkHostHashSize = sizeof(int64);
-
-// The total size for storing all ad network host hashes.
-const size_t kAdNetworkHostHashesTotalSize =
-    kAdNetworkHostHashSize * kNumAdNetworkHosts;
-
-// The size of the checksum we use in the data resource.
-const size_t kChecksumSize = 32u;
-
-// The total size of the data resource, including the checksum and all host
-// hashes.
-const size_t kDataResourceSize = kChecksumSize + kAdNetworkHostHashesTotalSize;
-
-// The MockResourceDelegate handles the call to get the data for the ad networks
-// file, which is constructed to contain hashes for the hosts in
-// |kAdNetworkHosts|.
-class MockResourceDelegate : public ui::ResourceBundle::Delegate {
- public:
-  MockResourceDelegate();
-  virtual ~MockResourceDelegate();
-
- private:
-  // Populate |data_resource_| with fake data for ad network url hashes.
-  void MakeMockResourceData();
-
-  // ResourceBundle::Delegate implementation. We actually only care about
-  // LoadDataResourceBytes(), but they're all pure virtual, so no choice but
-  // to have them all.
-  virtual base::FilePath GetPathForResourcePack(
-        const base::FilePath& pack_path, ui::ScaleFactor scale_factor) OVERRIDE;
-  virtual base::FilePath GetPathForLocalePack(
-        const base::FilePath& pack_path,
-        const std::string& locale) OVERRIDE;
-  virtual gfx::Image GetImageNamed(int resource_id) OVERRIDE;
-  virtual gfx::Image GetNativeImageNamed(
-      int resource_id, ui::ResourceBundle::ImageRTL rtl) OVERRIDE;
-  virtual base::RefCountedStaticMemory* LoadDataResourceBytes(
-        int resource_id, ui::ScaleFactor scale_factor) OVERRIDE;
-  virtual bool GetRawDataResource(int resource_id,
-                                  ui::ScaleFactor scale_factor,
-                                  base::StringPiece* value) OVERRIDE;
-  virtual bool GetLocalizedString(int message_id, base::string16* value)
-      OVERRIDE;
-  virtual scoped_ptr<gfx::Font> GetFont(ResourceBundle::FontStyle style)
-      OVERRIDE;
-
-  // The raw bits of the mocked-up data resource.
-  char raw_data_[kDataResourceSize];
-
-  // The RefCountedStaticMemory wrapper around |raw_data_|.
-  scoped_refptr<base::RefCountedStaticMemory> data_resource_;
-};
-
-MockResourceDelegate::MockResourceDelegate() {
-  MakeMockResourceData();
-}
-
-MockResourceDelegate::~MockResourceDelegate() {}
-
-void MockResourceDelegate::MakeMockResourceData() {
-  int64 host_hashes[kNumAdNetworkHosts];
-
-  for (size_t i = 0; i < kNumAdNetworkHosts; ++i) {
-    int64 hash = 0;
-    crypto::SHA256HashString(kAdNetworkHosts[i], &hash, sizeof(hash));
-    host_hashes[i] = hash;
-  }
-
-  // Create the Checksum.
-  scoped_ptr<crypto::SecureHash> hash(
-      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
-  hash->Update(host_hashes, kNumAdNetworkHosts * kAdNetworkHostHashSize);
-
-  char checksum[kChecksumSize];
-  hash->Finish(checksum, kChecksumSize);
-
-  // Copy the checksum to our data.
-  memcpy(raw_data_, &checksum, kChecksumSize);
-
-  // Copy the hashes.
-  memcpy(raw_data_ + kChecksumSize, host_hashes, kAdNetworkHostHashesTotalSize);
-
-  data_resource_ =
-      new base::RefCountedStaticMemory(raw_data_, kDataResourceSize);
-};
-
-base::FilePath MockResourceDelegate::GetPathForResourcePack(
-        const base::FilePath& pack_path, ui::ScaleFactor scale_factor) {
-  return base::FilePath();
-}
-
-base::FilePath MockResourceDelegate::GetPathForLocalePack(
-        const base::FilePath& pack_path,
-        const std::string& locale) {
-  return base::FilePath();
-}
-
-gfx::Image MockResourceDelegate::GetImageNamed(int resource_id) {
-  return gfx::Image();
-}
-
-gfx::Image MockResourceDelegate::GetNativeImageNamed(
-    int resource_id, ui::ResourceBundle::ImageRTL rtl) {
-  return gfx::Image();
-}
-
-base::RefCountedStaticMemory* MockResourceDelegate::LoadDataResourceBytes(
-        int resource_id, ui::ScaleFactor scale_factor) {
-  if (resource_id != IDR_AD_NETWORK_HASHES)
-    return NULL;
-  return data_resource_;
-}
-
-bool MockResourceDelegate::GetRawDataResource(int resource_id,
-                                              ui::ScaleFactor scale_factor,
-                                              base::StringPiece* value) {
-  return false;
-}
-
-bool MockResourceDelegate::GetLocalizedString(int message_id,
-                                              base::string16* value) {
-  return false;
-}
-
-scoped_ptr<gfx::Font> MockResourceDelegate::GetFont(
-    ResourceBundle::FontStyle style) {
-  return scoped_ptr<gfx::Font>();
-}
-
-}  // namespace
-
-class AdNetworkDatabaseUnitTest : public testing::Test {
- protected:
-  virtual void SetUp() OVERRIDE;
-
- private:
-  scoped_ptr<MockResourceDelegate> mock_resource_delegate_;
-};
-
-void AdNetworkDatabaseUnitTest::SetUp() {
-  // Clear the current resource bundle, and replace it with one with our own
-  // Delegate.
-  mock_resource_delegate_.reset(new MockResourceDelegate);
-  ui::ResourceBundle::CleanupSharedInstance();
-  ui::ResourceBundle::InitSharedInstanceWithLocale(
-      "en-US", mock_resource_delegate_.get());
-}
-
-TEST_F(AdNetworkDatabaseUnitTest, AdNetworkDatabaseTest) {
-  const AdNetworkDatabase* database = AdNetworkDatabase::Get();
-  ASSERT_TRUE(database);
-
-  // First, just check the basic urls in the list of ad networks.
-  EXPECT_TRUE(database->IsAdNetwork(GURL("http://alpha.adnetwork")));
-  EXPECT_TRUE(database->IsAdNetwork(GURL("http://bravo.adnetwork")));
-  EXPECT_TRUE(database->IsAdNetwork(GURL("http://charlie.delta.adnetwork")));
-
-  // Next, try adding some paths. These should still register.
-  EXPECT_TRUE(database->IsAdNetwork(GURL("http://alpha.adnetwork/foo")));
-  EXPECT_TRUE(database->IsAdNetwork(GURL("http://bravo.adnetwork/foo/bar")));
-  EXPECT_TRUE(
-      database->IsAdNetwork(GURL("http://charlie.delta.adnetwork/foo.html")));
-
-  // Then, try subdomains. These should not register, as they are treated as
-  // different hosts.
-  EXPECT_FALSE(database->IsAdNetwork(GURL("http://foo.alpha.adnetwork")));
-  EXPECT_FALSE(database->IsAdNetwork(GURL("http://foo.bar.bravo.adnetwork")));
-  EXPECT_FALSE(
-      database->IsAdNetwork(GURL("http://foo.charlie.delta.adnetwork")));
-
-  // Check to make sure that removing a subdomain (from charlie.delta.adnetwork)
-  // is considered different, and doesn't register.
-  EXPECT_FALSE(database->IsAdNetwork(GURL("http://delta.adnetwork")));
-
-  // And, of course, try some random sites and make sure we don't miscategorize.
-  EXPECT_FALSE(database->IsAdNetwork(GURL("http://www.google.com")));
-  EXPECT_FALSE(database->IsAdNetwork(GURL("http://drive.google.com")));
-  EXPECT_FALSE(database->IsAdNetwork(GURL("https://www.google.com")));
-  EXPECT_FALSE(
-      database->IsAdNetwork(GURL("file:///usr/someone/files/file.html")));
-  EXPECT_FALSE(database->IsAdNetwork(
-      GURL("chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")));
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/activity_log/hashed_ad_network_database.cc b/chrome/browser/extensions/activity_log/hashed_ad_network_database.cc
new file mode 100644
index 0000000..3e6f7ce
--- /dev/null
+++ b/chrome/browser/extensions/activity_log/hashed_ad_network_database.cc
@@ -0,0 +1,83 @@
+// 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.
+
+#include "chrome/browser/extensions/activity_log/hashed_ad_network_database.h"
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted_memory.h"
+#include "crypto/secure_hash.h"
+#include "crypto/sha2.h"
+#include "url/gurl.h"
+
+namespace extensions {
+
+namespace {
+
+// We use a hash size of 8 for these for three reasons.
+// 1. It saves us a bit on space, and, since we have to store these in memory
+//    (reading from disk would be far too slow because these checks are
+//    performed synchronously), that space is important.
+// 2. Since we don't store full hashes, reconstructing the list is more
+//    difficult. This may mean we get a few incorrect hits, but the security is
+//    worth the (very small) amount of noise.
+// 3. It fits nicely into a int64.
+const size_t kUrlHashSize = 8u;
+COMPILE_ASSERT(kUrlHashSize <= sizeof(int64), url_hashes_must_fit_into_a_int64);
+
+const size_t kChecksumHashSize = 32u;
+
+}  // namespace
+
+HashedAdNetworkDatabase::HashedAdNetworkDatabase(
+    scoped_refptr<base::RefCountedStaticMemory> entries_memory) {
+  // This can legitimately happen in unit tests.
+  if (!entries_memory)
+    return;
+
+  const size_t size = entries_memory->size();
+  const unsigned char* const front = entries_memory->front();
+  if (size < kChecksumHashSize ||
+      (size - kChecksumHashSize) % kUrlHashSize != 0) {
+    NOTREACHED();
+    return;
+  }
+
+  // The format of the data resource is fairly straight-forward:
+  // <32-bit checksum><list of 64-bit hashes of hosts>, with no linebreaks or
+  // other separations.
+  scoped_ptr<crypto::SecureHash> hash(
+      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
+
+  hash->Update(front + kChecksumHashSize, size - kChecksumHashSize);
+  char hash_value[kChecksumHashSize];
+  hash->Finish(hash_value, kChecksumHashSize);
+  // If the checksum doesn't match, abort.
+  if (memcmp(hash_value, front, kChecksumHashSize) != 0) {
+    NOTREACHED();
+    return;
+  }
+
+  // Construct and insert all hashes.
+  for (const unsigned char* index = front + kChecksumHashSize;
+       index < front + size;
+       index += kUrlHashSize) {
+    int64 value = 0;
+    memcpy(&value, index, kUrlHashSize);
+    entries_.insert(value);
+  }
+}
+
+HashedAdNetworkDatabase::~HashedAdNetworkDatabase() {}
+
+bool HashedAdNetworkDatabase::IsAdNetwork(const GURL& url) const {
+  int64 hash = 0;
+  crypto::SHA256HashString(url.host(), &hash, sizeof(hash));
+  // If initialization failed (most likely because this is a unittest), then
+  // |entries_| is never populated and we are guaranteed to return false - which
+  // is desired default behavior.
+  return entries_.count(hash) != 0;
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/activity_log/hashed_ad_network_database.h b/chrome/browser/extensions/activity_log/hashed_ad_network_database.h
new file mode 100644
index 0000000..74deb7b
--- /dev/null
+++ b/chrome/browser/extensions/activity_log/hashed_ad_network_database.h
@@ -0,0 +1,36 @@
+// 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_HASHED_AD_NETWORK_DATABASE_H_
+#define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_HASHED_AD_NETWORK_DATABASE_H_
+
+#include "base/containers/hash_tables.h"
+#include "base/memory/ref_counted.h"
+#include "chrome/browser/extensions/activity_log/ad_network_database.h"
+
+namespace base {
+class RefCountedStaticMemory;
+}
+
+namespace extensions {
+
+// The standard ("real") implementation of the AdNetworkDatabase, which stores
+// a list of hashes of ad networks.
+class HashedAdNetworkDatabase : public AdNetworkDatabase {
+ public:
+  explicit HashedAdNetworkDatabase(
+      scoped_refptr<base::RefCountedStaticMemory> memory);
+  virtual ~HashedAdNetworkDatabase();
+
+ private:
+  // AdNetworkDatabase implementation.
+  virtual bool IsAdNetwork(const GURL& url) const OVERRIDE;
+
+  // The set of partial hashes for known ad networks.
+  base::hash_set<int64> entries_;
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_HASHED_AD_NETWORK_DATABASE_H_
diff --git a/chrome/browser/extensions/activity_log/hashed_ad_network_database_unittest.cc b/chrome/browser/extensions/activity_log/hashed_ad_network_database_unittest.cc
new file mode 100644
index 0000000..f1e2d77
--- /dev/null
+++ b/chrome/browser/extensions/activity_log/hashed_ad_network_database_unittest.cc
@@ -0,0 +1,133 @@
+// 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.
+
+#include "base/basictypes.h"
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/extensions/activity_log/ad_network_database.h"
+#include "chrome/browser/extensions/activity_log/hashed_ad_network_database.h"
+#include "crypto/secure_hash.h"
+#include "crypto/sha2.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace extensions {
+
+namespace {
+
+// A list of fake ad networks.
+const char* kAdNetworkHosts[] = {
+  "alpha.adnetwork",
+  "bravo.adnetwork",
+  "charlie.delta.adnetwork"
+};
+
+// The number of ad networks for these tests.
+const size_t kNumAdNetworkHosts = arraysize(kAdNetworkHosts);
+
+// Each hash of an ad network is stored in an int64.
+const size_t kAdNetworkHostHashSize = sizeof(int64);
+
+// The total size for storing all ad network host hashes.
+const size_t kAdNetworkHostHashesTotalSize =
+    kAdNetworkHostHashSize * kNumAdNetworkHosts;
+
+// The size of the checksum we use in the data resource.
+const size_t kChecksumSize = 32u;
+
+// The total size of the data resource, including the checksum and all host
+// hashes.
+const size_t kDataResourceSize = kChecksumSize + kAdNetworkHostHashesTotalSize;
+
+}  // namespace
+
+class HashedAdNetworkDatabaseUnitTest : public testing::Test {
+ protected:
+  virtual void SetUp() OVERRIDE;
+
+ private:
+  // Generate a piece of memory with a hash structure identical to the real one,
+  // but with only mock data.
+  void GenerateMockMemory();
+
+  // The raw bits of the mocked-up data resource.
+  char raw_data_[kDataResourceSize];
+
+  // The RefCountedStaticMemory wrapper around |raw_data_|.
+  scoped_refptr<base::RefCountedStaticMemory> memory_;
+};
+
+void HashedAdNetworkDatabaseUnitTest::SetUp() {
+  GenerateMockMemory();
+  AdNetworkDatabase::SetForTesting(
+      scoped_ptr<AdNetworkDatabase>(new HashedAdNetworkDatabase(memory_)));
+}
+
+void HashedAdNetworkDatabaseUnitTest::GenerateMockMemory() {
+  int64 host_hashes[kNumAdNetworkHosts];
+
+  for (size_t i = 0; i < kNumAdNetworkHosts; ++i) {
+    int64 hash = 0;
+    crypto::SHA256HashString(kAdNetworkHosts[i], &hash, sizeof(hash));
+    host_hashes[i] = hash;
+  }
+
+  // Create the Checksum.
+  scoped_ptr<crypto::SecureHash> hash(
+      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
+  hash->Update(host_hashes, kNumAdNetworkHosts * kAdNetworkHostHashSize);
+
+  char checksum[kChecksumSize];
+  hash->Finish(checksum, kChecksumSize);
+
+  // Copy the checksum to our data.
+  memcpy(raw_data_, &checksum, kChecksumSize);
+
+  // Copy the hashes.
+  memcpy(raw_data_ + kChecksumSize, host_hashes, kAdNetworkHostHashesTotalSize);
+
+  memory_ = new base::RefCountedStaticMemory(raw_data_, kDataResourceSize);
+};
+
+TEST_F(HashedAdNetworkDatabaseUnitTest, HashedAdNetworkDatabaseTest) {
+  const AdNetworkDatabase* database = AdNetworkDatabase::Get();
+  ASSERT_TRUE(database);
+
+  // First, just check the basic urls in the list of ad networks.
+  EXPECT_TRUE(database->IsAdNetwork(GURL("http://alpha.adnetwork")));
+  EXPECT_TRUE(database->IsAdNetwork(GURL("http://bravo.adnetwork")));
+  EXPECT_TRUE(database->IsAdNetwork(GURL("http://charlie.delta.adnetwork")));
+
+  // Next, try adding some paths. These should still register.
+  EXPECT_TRUE(database->IsAdNetwork(GURL("http://alpha.adnetwork/foo")));
+  EXPECT_TRUE(database->IsAdNetwork(GURL("http://bravo.adnetwork/foo/bar")));
+  EXPECT_TRUE(
+      database->IsAdNetwork(GURL("http://charlie.delta.adnetwork/foo.html")));
+
+  // Then, try subdomains. These should not register, as they are treated as
+  // different hosts.
+  EXPECT_FALSE(database->IsAdNetwork(GURL("http://foo.alpha.adnetwork")));
+  EXPECT_FALSE(database->IsAdNetwork(GURL("http://foo.bar.bravo.adnetwork")));
+  EXPECT_FALSE(
+      database->IsAdNetwork(GURL("http://foo.charlie.delta.adnetwork")));
+
+  // Check to make sure that removing a subdomain (from charlie.delta.adnetwork)
+  // is considered different, and doesn't register.
+  EXPECT_FALSE(database->IsAdNetwork(GURL("http://delta.adnetwork")));
+
+  // And, of course, try some random sites and make sure we don't miscategorize.
+  EXPECT_FALSE(database->IsAdNetwork(GURL("http://www.google.com")));
+  EXPECT_FALSE(database->IsAdNetwork(GURL("http://drive.google.com")));
+  EXPECT_FALSE(database->IsAdNetwork(GURL("https://www.google.com")));
+  EXPECT_FALSE(
+      database->IsAdNetwork(GURL("file:///usr/someone/files/file.html")));
+  EXPECT_FALSE(database->IsAdNetwork(
+      GURL("chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")));
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.cc b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.cc
index bb99213..ba4f4a9 100644
--- a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.cc
+++ b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.cc
@@ -95,7 +95,7 @@
   EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
 }
 
-bool ActivityLogPrivateGetExtensionActivitiesFunction::RunImpl() {
+bool ActivityLogPrivateGetExtensionActivitiesFunction::RunAsync() {
   scoped_ptr<activity_log_private::GetExtensionActivities::Params> params(
       activity_log_private::GetExtensionActivities::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -176,7 +176,7 @@
   SendResponse(true);
 }
 
-bool ActivityLogPrivateDeleteActivitiesFunction::RunImpl() {
+bool ActivityLogPrivateDeleteActivitiesFunction::RunAsync() {
   scoped_ptr<activity_log_private::DeleteActivities::Params> params(
       activity_log_private::DeleteActivities::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -195,14 +195,14 @@
   return true;
 }
 
-bool ActivityLogPrivateDeleteDatabaseFunction::RunImpl() {
+bool ActivityLogPrivateDeleteDatabaseFunction::RunAsync() {
   ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile());
   DCHECK(activity_log);
   activity_log->DeleteDatabase();
   return true;
 }
 
-bool ActivityLogPrivateDeleteUrlsFunction::RunImpl() {
+bool ActivityLogPrivateDeleteUrlsFunction::RunAsync() {
   scoped_ptr<activity_log_private::DeleteUrls::Params> params(
       activity_log_private::DeleteUrls::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
diff --git a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.h b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.h
index 513d015..3df12f4 100644
--- a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.h
+++ b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api.h
@@ -71,7 +71,7 @@
   virtual ~ActivityLogPrivateGetExtensionActivitiesFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnLookupCompleted(
@@ -89,7 +89,7 @@
   virtual ~ActivityLogPrivateDeleteActivitiesFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 // The implementation of activityLogPrivate.deleteDatabase
@@ -103,7 +103,7 @@
   virtual ~ActivityLogPrivateDeleteDatabaseFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 // The implementation of activityLogPrivate.deleteUrls
@@ -117,7 +117,7 @@
   virtual ~ActivityLogPrivateDeleteUrlsFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/alarms/alarms_api.cc b/chrome/browser/extensions/api/alarms/alarms_api.cc
index 6c717cb..4de1670 100644
--- a/chrome/browser/extensions/api/alarms/alarms_api.cc
+++ b/chrome/browser/extensions/api/alarms/alarms_api.cc
@@ -98,7 +98,7 @@
     delete clock_;
 }
 
-bool AlarmsCreateFunction::RunImpl() {
+bool AlarmsCreateFunction::RunAsync() {
   scoped_ptr<alarms::Create::Params> params(
       alarms::Create::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -129,7 +129,7 @@
   SendResponse(true);
 }
 
-bool AlarmsGetFunction::RunImpl() {
+bool AlarmsGetFunction::RunAsync() {
   scoped_ptr<alarms::Get::Params> params(alarms::Get::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -150,7 +150,7 @@
   SendResponse(true);
 }
 
-bool AlarmsGetAllFunction::RunImpl() {
+bool AlarmsGetAllFunction::RunAsync() {
   AlarmManager::Get(GetProfile())->GetAllAlarms(
       extension_id(), base::Bind(&AlarmsGetAllFunction::Callback, this));
   return true;
@@ -170,7 +170,7 @@
   SendResponse(true);
 }
 
-bool AlarmsClearFunction::RunImpl() {
+bool AlarmsClearFunction::RunAsync() {
   scoped_ptr<alarms::Clear::Params> params(
       alarms::Clear::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -189,7 +189,7 @@
   SendResponse(true);
 }
 
-bool AlarmsClearAllFunction::RunImpl() {
+bool AlarmsClearAllFunction::RunAsync() {
   AlarmManager::Get(GetProfile())->RemoveAllAlarms(
       extension_id(), base::Bind(&AlarmsClearAllFunction::Callback, this));
   return true;
diff --git a/chrome/browser/extensions/api/alarms/alarms_api.h b/chrome/browser/extensions/api/alarms/alarms_api.h
index 3d971af..4bbe339 100644
--- a/chrome/browser/extensions/api/alarms/alarms_api.h
+++ b/chrome/browser/extensions/api/alarms/alarms_api.h
@@ -27,7 +27,7 @@
   virtual ~AlarmsCreateFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   DECLARE_EXTENSION_FUNCTION("alarms.create", ALARMS_CREATE)
  private:
   void Callback();
@@ -44,7 +44,7 @@
   virtual ~AlarmsGetFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void Callback(const std::string& name, Alarm* alarm);
@@ -56,7 +56,8 @@
   virtual ~AlarmsGetAllFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
+
  private:
   void Callback(const AlarmList* alarms);
   DECLARE_EXTENSION_FUNCTION("alarms.getAll", ALARMS_GETALL)
@@ -67,7 +68,8 @@
   virtual ~AlarmsClearFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
+
  private:
   void Callback(const std::string& name, bool success);
   DECLARE_EXTENSION_FUNCTION("alarms.clear", ALARMS_CLEAR)
@@ -78,7 +80,8 @@
   virtual ~AlarmsClearAllFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
+
  private:
   void Callback();
   DECLARE_EXTENSION_FUNCTION("alarms.clearAll", ALARMS_CLEARALL)
diff --git a/chrome/browser/extensions/api/app_current_window_internal/app_current_window_internal_api.cc b/chrome/browser/extensions/api/app_current_window_internal/app_current_window_internal_api.cc
index 52fe000..403bddb 100644
--- a/chrome/browser/extensions/api/app_current_window_internal/app_current_window_internal_api.cc
+++ b/chrome/browser/extensions/api/app_current_window_internal/app_current_window_internal_api.cc
@@ -385,7 +385,7 @@
     "E06AFCB1EB0EFD237824CC4AC8FDD3D43E8BC868"
   };
   if (GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV &&
-      !SimpleFeature::IsIdInWhitelist(
+      !SimpleFeature::IsIdInList(
           GetExtension()->id(),
           std::set<std::string>(whitelist,
                                 whitelist + arraysize(whitelist)))) {
diff --git a/chrome/browser/extensions/api/app_window/app_window_api.cc b/chrome/browser/extensions/api/app_window/app_window_api.cc
index 14af30a..63c40c0 100644
--- a/chrome/browser/extensions/api/app_window/app_window_api.cc
+++ b/chrome/browser/extensions/api/app_window/app_window_api.cc
@@ -43,8 +43,6 @@
     "The window id can not be more than 256 characters long.";
 const char kInvalidColorSpecification[] =
     "The color specification could not be parsed.";
-const char kInvalidChannelForFrameOptions[] =
-    "Frame options are only available in dev channel.";
 const char kColorWithFrameNone[] = "Windows with no frame cannot have a color.";
 const char kInactiveColorWithoutColor[] =
     "frame.inactiveColor must be used with frame.color.";
@@ -139,7 +137,7 @@
   SendResponse(true);
 }
 
-bool AppWindowCreateFunction::RunImpl() {
+bool AppWindowCreateFunction::RunAsync() {
   // Don't create app window if the system is shutting down.
   if (extensions::ExtensionsBrowserClient::Get()->IsShuttingDown())
     return false;
@@ -261,8 +259,6 @@
     }
   }
 
-  UpdateFrameOptionsForChannel(&create_params);
-
   create_params.creator_process_id =
       render_view_host_->GetProcess()->GetID();
 
@@ -438,11 +434,6 @@
     return true;
   }
 
-  if (GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV) {
-    error_ = app_window_constants::kInvalidChannelForFrameOptions;
-    return false;
-  }
-
   if (options.frame->as_frame_options->type)
     create_params->frame =
         GetFrameFromString(*options.frame->as_frame_options->type);
@@ -483,19 +474,4 @@
   return true;
 }
 
-void AppWindowCreateFunction::UpdateFrameOptionsForChannel(
-    apps::AppWindow::CreateParams* create_params) {
-#if defined(OS_WIN)
-  if (create_params->frame == AppWindow::FRAME_CHROME &&
-      GetCurrentChannel() > chrome::VersionInfo::CHANNEL_DEV) {
-    // If not on trunk or dev channel, always use the standard white frame.
-    // TODO(benwells): Remove this code once we get agreement to use the new
-    // native style frame.
-    create_params->has_frame_color = true;
-    create_params->active_frame_color = SK_ColorWHITE;
-    create_params->inactive_frame_color = SK_ColorWHITE;
-  }
-#endif
-}
-
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/app_window/app_window_api.h b/chrome/browser/extensions/api/app_window/app_window_api.h
index de73bac..8f976bf 100644
--- a/chrome/browser/extensions/api/app_window/app_window_api.h
+++ b/chrome/browser/extensions/api/app_window/app_window_api.h
@@ -16,7 +16,7 @@
 }
 }
 
-class AppWindowCreateFunction : public UIThreadExtensionFunction {
+class AppWindowCreateFunction : public AsyncExtensionFunction {
  public:
   AppWindowCreateFunction();
   DECLARE_EXTENSION_FUNCTION("app.window.create", APP_WINDOW_CREATE)
@@ -25,7 +25,7 @@
 
  protected:
   virtual ~AppWindowCreateFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   bool GetBoundsSpec(
diff --git a/chrome/browser/extensions/api/app_window/app_window_apitest.cc b/chrome/browser/extensions/api/app_window/app_window_apitest.cc
index 9f0f546..8b58157 100644
--- a/chrome/browser/extensions/api/app_window/app_window_apitest.cc
+++ b/chrome/browser/extensions/api/app_window/app_window_apitest.cc
@@ -30,11 +30,9 @@
   }
 
   // Overridden from AppWindowRegistry::Observer:
-  virtual void OnAppWindowAdded(AppWindow* app_window) OVERRIDE {}
   virtual void OnAppWindowIconChanged(AppWindow* app_window) OVERRIDE {
     ++icon_updates_;
   }
-  virtual void OnAppWindowRemoved(AppWindow* app_window) OVERRIDE {}
 
   int icon_updates() { return icon_updates_; }
 
diff --git a/chrome/browser/extensions/api/audio/audio_api.cc b/chrome/browser/extensions/api/audio/audio_api.cc
index 06285f0..f711c95 100644
--- a/chrome/browser/extensions/api/audio/audio_api.cc
+++ b/chrome/browser/extensions/api/audio/audio_api.cc
@@ -46,7 +46,7 @@
   }
 }
 
-bool AudioGetInfoFunction::RunImpl() {
+bool AudioGetInfoFunction::RunAsync() {
   AudioService* service =
       AudioAPI::GetFactoryInstance()->Get(GetProfile())->GetService();
   DCHECK(service);
diff --git a/chrome/browser/extensions/api/audio/audio_api.h b/chrome/browser/extensions/api/audio/audio_api.h
index f99547a..8a33e85 100644
--- a/chrome/browser/extensions/api/audio/audio_api.h
+++ b/chrome/browser/extensions/api/audio/audio_api.h
@@ -45,7 +45,7 @@
 
  protected:
   virtual ~AudioGetInfoFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnGetInfoCompleted(const OutputInfo& output_info,
diff --git a/chrome/browser/extensions/api/automation/automation_apitest.cc b/chrome/browser/extensions/api/automation/automation_apitest.cc
index 5e38d0b..470cb4d9 100644
--- a/chrome/browser/extensions/api/automation/automation_apitest.cc
+++ b/chrome/browser/extensions/api/automation/automation_apitest.cc
@@ -99,26 +99,33 @@
 #endif  // defined(OS_MACOSX)
 IN_PROC_BROWSER_TEST_F(AutomationApiTest, MAYBE_SanityCheck) {
   StartEmbeddedTestServer();
-  ASSERT_TRUE(RunExtensionSubtest("automation/tests", "sanity_check.html"))
+  ASSERT_TRUE(RunExtensionSubtest("automation/tests/tabs", "sanity_check.html"))
       << message_;
 }
 
 IN_PROC_BROWSER_TEST_F(AutomationApiTest, Events) {
   LoadPage();
-  ASSERT_TRUE(RunExtensionSubtest("automation/tests", "events.html"))
+  ASSERT_TRUE(RunExtensionSubtest("automation/tests/tabs", "events.html"))
       << message_;
 }
 
 IN_PROC_BROWSER_TEST_F(AutomationApiTest, Actions) {
   LoadPage();
-  ASSERT_TRUE(RunExtensionSubtest("automation/tests", "actions.html"))
+  ASSERT_TRUE(RunExtensionSubtest("automation/tests/tabs", "actions.html"))
       << message_;
 }
 
 IN_PROC_BROWSER_TEST_F(AutomationApiTest, Location) {
   LoadPage();
-  ASSERT_TRUE(RunExtensionSubtest("automation/tests", "location.html"))
+  ASSERT_TRUE(RunExtensionSubtest("automation/tests/tabs", "location.html"))
       << message_;
 }
 
+#if defined(OS_CHROMEOS)
+IN_PROC_BROWSER_TEST_F(AutomationApiTest, Desktop) {
+  ASSERT_TRUE(RunExtensionSubtest("automation/tests/desktop", "desktop.html"))
+      << message_;
+}
+#endif
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc b/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc
index 9c77eda..8d2769c 100644
--- a/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc
+++ b/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc
@@ -19,6 +19,10 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/ui/ash/accessibility/automation_manager_views.h"
+#endif
+
 namespace extensions {
 class AutomationWebContentsObserver;
 }  // namespace extensions
@@ -59,7 +63,7 @@
 // if this doesn't turn accessibility on for the first time (e.g. if a
 // RendererAccessibility object existed already because a screenreader has been
 // run at some point).
-bool AutomationInternalEnableCurrentTabFunction::RunImpl() {
+bool AutomationInternalEnableCurrentTabFunction::RunAsync() {
   if (!CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableAutomationAPI)) {
     return false;
@@ -88,7 +92,7 @@
   return true;
 }
 
-bool AutomationInternalPerformActionFunction::RunImpl() {
+bool AutomationInternalPerformActionFunction::RunAsync() {
   using api::automation_internal::PerformAction::Params;
   scoped_ptr<Params> params(Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -124,4 +128,19 @@
   return true;
 }
 
+bool AutomationInternalEnableDesktopFunction::RunAsync() {
+  if (!CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableAutomationAPI)) {
+    return false;
+  }
+
+#if defined(OS_CHROMEOS)
+  AutomationManagerViews::GetInstance()->Enable(browser_context());
+#else
+  error_ = "getDesktop is unsupported by this platform";
+#endif
+
+  return true;
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/automation_internal/automation_internal_api.h b/chrome/browser/extensions/api/automation_internal/automation_internal_api.h
index f82867b..007cb27 100644
--- a/chrome/browser/extensions/api/automation_internal/automation_internal_api.h
+++ b/chrome/browser/extensions/api/automation_internal/automation_internal_api.h
@@ -27,7 +27,7 @@
  protected:
   virtual ~AutomationInternalEnableCurrentTabFunction() {}
 
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class AutomationInternalPerformActionFunction
@@ -37,7 +37,17 @@
  protected:
   virtual ~AutomationInternalPerformActionFunction() {}
 
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
+};
+
+class AutomationInternalEnableDesktopFunction
+    : public ChromeAsyncExtensionFunction {
+  DECLARE_EXTENSION_FUNCTION("automationInternal.enableDesktop",
+                             AUTOMATIONINTERNAL_ENABLEDESKTOP)
+ protected:
+  virtual ~AutomationInternalEnableDesktopFunction() {}
+
+  virtual bool RunAsync() OVERRIDE;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc b/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc
index 77128f8..14bff9d 100644
--- a/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc
+++ b/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc
@@ -315,7 +315,7 @@
 
 BluetoothAddProfileFunction::~BluetoothAddProfileFunction() {}
 
-bool BluetoothAddProfileFunction::RunImpl() {
+bool BluetoothAddProfileFunction::RunAsync() {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   scoped_ptr<AddProfile::Params> params(AddProfile::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
@@ -474,37 +474,37 @@
   SendResponse(false);
 }
 
-bool BluetoothDisconnectFunction::RunImpl() {
+bool BluetoothDisconnectFunction::RunAsync() {
   // TODO(keybuk): Remove.
   SetError("Removed. Use chrome.bluetoothSocket.disconnect() instead.");
   return false;
 }
 
-bool BluetoothSendFunction::RunImpl() {
+bool BluetoothSendFunction::RunAsync() {
   // TODO(keybuk): Remove.
   SetError("Removed. Use chrome.bluetoothSocket.send() instead.");
   return false;
 }
 
-bool BluetoothUpdateSocketFunction::RunImpl() {
+bool BluetoothUpdateSocketFunction::RunAsync() {
   // TODO(keybuk): Remove.
   SetError("Removed. Use chrome.bluetoothSocket.update() instead.");
   return false;
 }
 
-bool BluetoothSetSocketPausedFunction::RunImpl() {
+bool BluetoothSetSocketPausedFunction::RunAsync() {
   // TODO(keybuk): Remove.
   SetError("Removed. Use chrome.bluetoothSocket.setPaused() instead.");
   return false;
 }
 
-bool BluetoothGetSocketFunction::RunImpl() {
+bool BluetoothGetSocketFunction::RunAsync() {
   // TODO(keybuk): Remove.
   SetError("Removed. Use chrome.bluetoothSocket.getInfo() instead.");
   return false;
 }
 
-bool BluetoothGetSocketsFunction::RunImpl() {
+bool BluetoothGetSocketsFunction::RunAsync() {
   // TODO(keybuk): Remove.
   SetError("Removed. Use chrome.bluetoothSocket.getSockets() instead.");
   return false;
diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_api.h b/chrome/browser/extensions/api/bluetooth/bluetooth_api.h
index 9ce771e..22afeaf 100644
--- a/chrome/browser/extensions/api/bluetooth/bluetooth_api.h
+++ b/chrome/browser/extensions/api/bluetooth/bluetooth_api.h
@@ -142,7 +142,7 @@
   virtual ~BluetoothGetDeviceFunction();
 };
 
-class BluetoothAddProfileFunction : public UIThreadExtensionFunction {
+class BluetoothAddProfileFunction : public AsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetooth.addProfile", BLUETOOTH_ADDPROFILE)
 
@@ -150,7 +150,7 @@
 
  protected:
   virtual ~BluetoothAddProfileFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   virtual void RegisterProfile(
       const device::BluetoothProfile::Options& options,
@@ -187,40 +187,40 @@
   void OnErrorCallback(const std::string& error);
 };
 
-class BluetoothDisconnectFunction : public UIThreadExtensionFunction {
+class BluetoothDisconnectFunction : public AsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetooth.disconnect", BLUETOOTH_DISCONNECT)
 
  protected:
   virtual ~BluetoothDisconnectFunction() {}
 
-  // UIThreadExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  // AsyncExtensionFunction:
+  virtual bool RunAsync() OVERRIDE;
 };
 
-class BluetoothSendFunction : public UIThreadExtensionFunction {
+class BluetoothSendFunction : public AsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetooth.send", BLUETOOTH_WRITE)
 
  protected:
   virtual ~BluetoothSendFunction() {}
 
-  // UIThreadExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  // AsyncExtensionFunction:
+  virtual bool RunAsync() OVERRIDE;
 };
 
-class BluetoothUpdateSocketFunction : public UIThreadExtensionFunction {
+class BluetoothUpdateSocketFunction : public AsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetooth.updateSocket", BLUETOOTH_UPDATE_SOCKET)
 
  protected:
   virtual ~BluetoothUpdateSocketFunction() {}
 
-  // UIThreadExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  // AsyncExtensionFunction:
+  virtual bool RunAsync() OVERRIDE;
 };
 
-class BluetoothSetSocketPausedFunction : public UIThreadExtensionFunction {
+class BluetoothSetSocketPausedFunction : public AsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetooth.setSocketPaused",
                              BLUETOOTH_SET_SOCKET_PAUSED)
@@ -228,30 +228,30 @@
  protected:
   virtual ~BluetoothSetSocketPausedFunction() {}
 
-  // UIThreadExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  // AsyncExtensionFunction:
+  virtual bool RunAsync() OVERRIDE;
 };
 
-class BluetoothGetSocketFunction : public UIThreadExtensionFunction {
+class BluetoothGetSocketFunction : public AsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetooth.getSocket", BLUETOOTH_GET_SOCKET)
 
  protected:
   virtual ~BluetoothGetSocketFunction() {}
 
-  // UIThreadExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  // AsyncExtensionFunction:
+  virtual bool RunAsync() OVERRIDE;
 };
 
-class BluetoothGetSocketsFunction : public UIThreadExtensionFunction {
+class BluetoothGetSocketsFunction : public AsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetooth.getSockets", BLUETOOTH_GET_SOCKETS)
 
  protected:
   virtual ~BluetoothGetSocketsFunction() {}
 
-  // UIThreadExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  // AsyncExtensionFunction:
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class BluetoothGetLocalOutOfBandPairingDataFunction
diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_api_socket.cc b/chrome/browser/extensions/api/bluetooth/bluetooth_api_socket.cc
index 2be7f3e..b33c635 100644
--- a/chrome/browser/extensions/api/bluetooth/bluetooth_api_socket.cc
+++ b/chrome/browser/extensions/api/bluetooth/bluetooth_api_socket.cc
@@ -58,6 +58,21 @@
     socket_->Close();
 }
 
+void BluetoothApiSocket::AdoptConnectedSocket(
+    scoped_refptr<device::BluetoothSocket> socket,
+    const std::string& device_address,
+    const device::BluetoothUUID& uuid) {
+  DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
+
+  if (socket_.get())
+    socket_->Close();
+
+  socket_ = socket;
+  device_address_ = device_address;
+  uuid_ = uuid;
+  connected_ = true;
+}
+
 void BluetoothApiSocket::Disconnect(const base::Closure& success_callback) {
   DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
 
diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_api_socket.h b/chrome/browser/extensions/api/bluetooth/bluetooth_api_socket.h
index 965cc51..e4b5edd 100644
--- a/chrome/browser/extensions/api/bluetooth/bluetooth_api_socket.h
+++ b/chrome/browser/extensions/api/bluetooth/bluetooth_api_socket.h
@@ -38,6 +38,13 @@
                      const device::BluetoothUUID& uuid);
   virtual ~BluetoothApiSocket();
 
+  // Adopts a socket |socket| connected to a device with address
+  // |device_address| using the service with UUID |uuid|.
+  virtual void AdoptConnectedSocket(
+      scoped_refptr<device::BluetoothSocket> socket,
+      const std::string& device_address,
+      const device::BluetoothUUID& uuid);
+
   // Closes the underlying connection. This is a best effort, and never fails.
   virtual void Disconnect(const base::Closure& success_callback);
 
diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_extension_function.cc b/chrome/browser/extensions/api/bluetooth/bluetooth_extension_function.cc
index 2732bea..bbc4fbd 100644
--- a/chrome/browser/extensions/api/bluetooth/bluetooth_extension_function.cc
+++ b/chrome/browser/extensions/api/bluetooth/bluetooth_extension_function.cc
@@ -46,7 +46,7 @@
 BluetoothExtensionFunction::~BluetoothExtensionFunction() {
 }
 
-bool BluetoothExtensionFunction::RunImpl() {
+bool BluetoothExtensionFunction::RunAsync() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   if (!IsBluetoothSupported(browser_context())) {
diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_extension_function.h b/chrome/browser/extensions/api/bluetooth/bluetooth_extension_function.h
index 0e77d7a..dfe9ea5 100644
--- a/chrome/browser/extensions/api/bluetooth/bluetooth_extension_function.h
+++ b/chrome/browser/extensions/api/bluetooth/bluetooth_extension_function.h
@@ -21,7 +21,7 @@
 // Base class for bluetooth extension functions. This class initializes
 // bluetooth adapter and calls (on the UI thread) DoWork() implemented by
 // individual bluetooth extension functions.
-class BluetoothExtensionFunction : public UIThreadExtensionFunction {
+class BluetoothExtensionFunction : public AsyncExtensionFunction {
  public:
   BluetoothExtensionFunction();
 
@@ -29,7 +29,7 @@
   virtual ~BluetoothExtensionFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void RunOnAdapterReady(scoped_refptr<device::BluetoothAdapter> adapter);
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.cc
index 972d395..79caa34 100644
--- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.cc
+++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.cc
@@ -8,6 +8,7 @@
 #include "base/lazy_instance.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h"
+#include "chrome/browser/extensions/api/bluetooth_low_energy/utils.h"
 #include "chrome/common/extensions/api/bluetooth_low_energy.h"
 #include "content/public/browser/browser_thread.h"
 #include "extensions/browser/event_router.h"
@@ -21,8 +22,12 @@
 
 const char kErrorAdapterNotInitialized[] =
     "Could not initialize Bluetooth adapter.";
+const char kErrorCharacteristicNotFoundFormat[] =
+    "Characteristic with ID \"%s\" not found.";
 const char kErrorDeviceNotFoundFormat[] =
     "Device with address \"%s\" not found.";
+const char kErrorReadCharacteristicValueFailedFormat[] =
+    "Failed to read value of characteristic with ID \"%s\".";
 const char kErrorServiceNotFoundFormat[] = "Service with ID \"%s\" not found.";
 const char kErrorPlatformNotSupported[] =
     "This operation is not supported on the current platform";
@@ -78,7 +83,7 @@
 BluetoothLowEnergyExtensionFunction::~BluetoothLowEnergyExtensionFunction() {
 }
 
-bool BluetoothLowEnergyExtensionFunction::RunImpl() {
+bool BluetoothLowEnergyExtensionFunction::RunAsync() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   BluetoothLowEnergyEventRouter* event_router =
@@ -168,17 +173,85 @@
 }
 
 bool BluetoothLowEnergyGetCharacteristicFunction::DoWork() {
-  // TODO(armansito): Implement.
-  SetError("Call not supported.");
-  SendResponse(false);
-  return false;
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  BluetoothLowEnergyEventRouter* event_router =
+      GetEventRouter(browser_context());
+
+  // The adapter must be initialized at this point, but return an error instead
+  // of asserting.
+  if (!event_router->HasAdapter()) {
+    SetError(kErrorAdapterNotInitialized);
+    SendResponse(false);
+    return false;
+  }
+
+  scoped_ptr<apibtle::GetCharacteristic::Params> params(
+      apibtle::GetCharacteristic::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
+
+  std::string characteristic_id = params->characteristic_id;
+
+  apibtle::Characteristic characteristic;
+  if (!event_router->GetCharacteristic(characteristic_id, &characteristic)) {
+    SetError(base::StringPrintf(kErrorCharacteristicNotFoundFormat,
+                                characteristic_id.c_str()));
+    SendResponse(false);
+    return false;
+  }
+
+  // Manually construct the result instead of using
+  // apibtle::GetCharacteristic::Result::Create as it doesn't convert lists of
+  // enums correctly.
+  SetResult(apibtle::CharacteristicToValue(&characteristic).release());
+  SendResponse(true);
+
+  return true;
 }
 
 bool BluetoothLowEnergyGetCharacteristicsFunction::DoWork() {
-  // TODO(armansito): Implement.
-  SetError("Call not supported.");
-  SendResponse(false);
-  return false;
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  BluetoothLowEnergyEventRouter* event_router =
+      GetEventRouter(browser_context());
+
+  // The adapter must be initialized at this point, but return an error instead
+  // of asserting.
+  if (!event_router->HasAdapter()) {
+    SetError(kErrorAdapterNotInitialized);
+    SendResponse(false);
+    return false;
+  }
+
+  scoped_ptr<apibtle::GetCharacteristics::Params> params(
+      apibtle::GetCharacteristics::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
+
+  std::string service_id = params->service_id;
+
+  BluetoothLowEnergyEventRouter::CharacteristicList characteristic_list;
+  if (!event_router->GetCharacteristics(service_id, &characteristic_list)) {
+    SetError(
+        base::StringPrintf(kErrorServiceNotFoundFormat, service_id.c_str()));
+
+    SendResponse(false);
+    return false;
+  }
+
+  // Manually construct the result instead of using
+  // apibtle::GetCharacteristics::Result::Create as it doesn't convert lists of
+  // enums correctly.
+  scoped_ptr<base::ListValue> result(new base::ListValue());
+  for (BluetoothLowEnergyEventRouter::CharacteristicList::iterator iter =
+           characteristic_list.begin();
+       iter != characteristic_list.end();
+       ++iter)
+    result->Append(apibtle::CharacteristicToValue(iter->get()).release());
+
+  SetResult(result.release());
+  SendResponse(true);
+
+  return true;
 }
 
 bool BluetoothLowEnergyGetIncludedServicesFunction::DoWork() {
@@ -230,10 +303,65 @@
 }
 
 bool BluetoothLowEnergyReadCharacteristicValueFunction::DoWork() {
-  // TODO(armansito): Implement.
-  SetError("Call not supported.");
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  BluetoothLowEnergyEventRouter* event_router =
+      GetEventRouter(browser_context());
+
+  // The adapter must be initialized at this point, but return an error instead
+  // of asserting.
+  if (!event_router->HasAdapter()) {
+    SetError(kErrorAdapterNotInitialized);
+    SendResponse(false);
+    return false;
+  }
+
+  scoped_ptr<apibtle::ReadCharacteristicValue::Params> params(
+      apibtle::ReadCharacteristicValue::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
+
+  instance_id_ = params->characteristic_id;
+
+  if (!event_router->ReadCharacteristicValue(
+          instance_id_,
+          base::Bind(&BluetoothLowEnergyReadCharacteristicValueFunction::
+                         SuccessCallback,
+                     this),
+          base::Bind(
+              &BluetoothLowEnergyReadCharacteristicValueFunction::ErrorCallback,
+              this))) {
+    SetError(base::StringPrintf(kErrorCharacteristicNotFoundFormat,
+                                instance_id_.c_str()));
+    SendResponse(false);
+    return false;
+  }
+
+  return true;
+}
+
+void BluetoothLowEnergyReadCharacteristicValueFunction::SuccessCallback() {
+  // Obtain info on the characteristic and see whether or not the characteristic
+  // is still around.
+  apibtle::Characteristic characteristic;
+  if (!GetEventRouter(browser_context())
+           ->GetCharacteristic(instance_id_, &characteristic)) {
+    SetError(base::StringPrintf(kErrorCharacteristicNotFoundFormat,
+                                instance_id_.c_str()));
+    SendResponse(false);
+    return;
+  }
+
+  // Manually construct the result instead of using
+  // apibtle::GetCharacteristic::Result::Create as it doesn't convert lists of
+  // enums correctly.
+  SetResult(apibtle::CharacteristicToValue(&characteristic).release());
+  SendResponse(true);
+}
+
+void BluetoothLowEnergyReadCharacteristicValueFunction::ErrorCallback() {
+  SetError(base::StringPrintf(kErrorReadCharacteristicValueFailedFormat,
+                              instance_id_.c_str()));
   SendResponse(false);
-  return false;
 }
 
 bool BluetoothLowEnergyWriteCharacteristicValueFunction::DoWork() {
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h
index ad55f61..a1a3d6b 100644
--- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h
+++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h
@@ -53,7 +53,7 @@
 // Base class for bluetoothLowEnergy API functions. This class handles some of
 // the common logic involved in all API functions, such as checking for
 // platform support and returning the correct error.
-class BluetoothLowEnergyExtensionFunction : public UIThreadExtensionFunction {
+class BluetoothLowEnergyExtensionFunction : public AsyncExtensionFunction {
  public:
   BluetoothLowEnergyExtensionFunction();
 
@@ -61,10 +61,10 @@
   virtual ~BluetoothLowEnergyExtensionFunction();
 
   // ExtensionFunction override.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Implemented by individual bluetoothLowEnergy extension functions to perform
-  // the body of the function. This invoked asynchonously after RunImpl after
+  // the body of the function. This invoked asynchonously after RunAsync after
   // the BluetoothLowEnergyEventRouter has obtained a handle on the
   // BluetoothAdapter.
   virtual bool DoWork() = 0;
@@ -175,6 +175,15 @@
 
   // BluetoothLowEnergyExtensionFunction override.
   virtual bool DoWork() OVERRIDE;
+
+ private:
+  // Success and error callbacks, called by
+  // BluetoothLowEnergyEventRouter::ReadCharacteristicValue.
+  void SuccessCallback();
+  void ErrorCallback();
+
+  // The instance ID of the requested characteristic.
+  std::string instance_id_;
 };
 
 class BluetoothLowEnergyWriteCharacteristicValueFunction
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc
index fb1da70..7cd3320 100644
--- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc
+++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc
@@ -10,17 +10,23 @@
 #include "chrome/browser/extensions/extension_test_message_listener.h"
 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
 #include "device/bluetooth/test/mock_bluetooth_device.h"
+#include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h"
 #include "device/bluetooth/test/mock_bluetooth_gatt_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 using device::BluetoothUUID;
 using device::BluetoothAdapter;
 using device::BluetoothDevice;
+using device::BluetoothGattCharacteristic;
 using device::BluetoothGattService;
 using device::MockBluetoothAdapter;
 using device::MockBluetoothDevice;
+using device::MockBluetoothGattCharacteristic;
 using device::MockBluetoothGattService;
+using extensions::BluetoothLowEnergyEventRouter;
+using testing::Invoke;
 using testing::Return;
+using testing::ReturnRefOfCopy;
 using testing::_;
 
 namespace utils = extension_function_test_utils;
@@ -32,9 +38,32 @@
 
 const char kTestServiceId0[] = "service_id0";
 const char kTestServiceUuid0[] = "1234";
+
 const char kTestServiceId1[] = "service_id1";
 const char kTestServiceUuid1[] = "5678";
 
+const char kTestCharacteristicId0[] = "char_id0";
+const char kTestCharacteristicUuid0[] = "1211";
+const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties0 =
+    BluetoothGattCharacteristic::kPropertyBroadcast |
+    BluetoothGattCharacteristic::kPropertyRead |
+    BluetoothGattCharacteristic::kPropertyWriteWithoutResponse |
+    BluetoothGattCharacteristic::kPropertyIndicate;
+const uint8 kTestCharacteristicDefaultValue0[] = {0x01, 0x02, 0x03, 0x04, 0x05};
+
+const char kTestCharacteristicId1[] = "char_id1";
+const char kTestCharacteristicUuid1[] = "1212";
+const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties1 =
+    BluetoothGattCharacteristic::kPropertyRead |
+    BluetoothGattCharacteristic::kPropertyWrite |
+    BluetoothGattCharacteristic::kPropertyNotify;
+const uint8 kTestCharacteristicDefaultValue1[] = {0x06, 0x07, 0x08};
+
+const char kTestCharacteristicId2[] = "char_id2";
+const char kTestCharacteristicUuid2[] = "1213";
+const BluetoothGattCharacteristic::Properties kTestCharacteristicProperties2 =
+    BluetoothGattCharacteristic::kPropertyNone;
+
 class BluetoothLowEnergyApiTest : public ExtensionApiTest {
  public:
   BluetoothLowEnergyApiTest() {}
@@ -79,10 +108,47 @@
         BluetoothUUID(kTestServiceUuid1),
         false /* is_primary */,
         false /* is_local */));
+
+    // Assign characteristics some random properties and permissions. They don't
+    // need to reflect what the characteristic is actually capable of, since
+    // the JS API just passes values through from
+    // device::BluetoothGattCharacteristic.
+    std::vector<uint8> default_value;
+    chrc0_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>(
+        service0_.get(),
+        kTestCharacteristicId0,
+        BluetoothUUID(kTestCharacteristicUuid0),
+        false /* is_local */,
+        kTestCharacteristicProperties0,
+        BluetoothGattCharacteristic::kPermissionNone));
+    default_value.assign(kTestCharacteristicDefaultValue0,
+                         (kTestCharacteristicDefaultValue0 +
+                          sizeof(kTestCharacteristicDefaultValue0)));
+    ON_CALL(*chrc0_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value));
+
+    chrc1_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>(
+        service0_.get(),
+        kTestCharacteristicId1,
+        BluetoothUUID(kTestCharacteristicUuid1),
+        false /* is_local */,
+        kTestCharacteristicProperties1,
+        BluetoothGattCharacteristic::kPermissionNone));
+    default_value.assign(kTestCharacteristicDefaultValue1,
+                         (kTestCharacteristicDefaultValue1 +
+                          sizeof(kTestCharacteristicDefaultValue1)));
+    ON_CALL(*chrc1_, GetValue()).WillByDefault(ReturnRefOfCopy(default_value));
+
+    chrc2_.reset(new testing::NiceMock<MockBluetoothGattCharacteristic>(
+        service1_.get(),
+        kTestCharacteristicId2,
+        BluetoothUUID(kTestCharacteristicUuid2),
+        false /* is_local */,
+        kTestCharacteristicProperties2,
+        BluetoothGattCharacteristic::kPermissionNone));
   }
 
  protected:
-  extensions::BluetoothLowEnergyEventRouter* event_router() {
+  BluetoothLowEnergyEventRouter* event_router() {
     return extensions::BluetoothLowEnergyAPI::Get(browser()->profile())
         ->event_router();
   }
@@ -91,11 +157,27 @@
   scoped_ptr<testing::NiceMock<MockBluetoothDevice> > device_;
   scoped_ptr<testing::NiceMock<MockBluetoothGattService> > service0_;
   scoped_ptr<testing::NiceMock<MockBluetoothGattService> > service1_;
+  scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc0_;
+  scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc1_;
+  scoped_ptr<testing::NiceMock<MockBluetoothGattCharacteristic> > chrc2_;
 
  private:
   scoped_refptr<extensions::Extension> empty_extension_;
 };
 
+void ReadValueSuccessCallback(
+    const base::Callback<void(const std::vector<uint8>&)>& callback,
+    const base::Closure& error_callback) {
+  std::vector<uint8> value;
+  callback.Run(value);
+}
+
+void ReadValueErrorCallback(
+    const base::Callback<void(const std::vector<uint8>&)>& callback,
+    const base::Closure& error_callback) {
+  error_callback.Run();
+}
+
 IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetServices) {
   ResultCatcher catcher;
   catcher.RestrictToProfile(browser()->profile());
@@ -256,6 +338,7 @@
 
   listener.Reply("go");
   listener.Reset();
+
   EXPECT_TRUE(listener.WaitUntilSatisfied());
 
   listener.Reply("go");
@@ -265,4 +348,208 @@
   event_router()->DeviceRemoved(mock_adapter_, device_.get());
 }
 
+IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetCharacteristics) {
+  ResultCatcher catcher;
+  catcher.RestrictToProfile(browser()->profile());
+
+  std::vector<BluetoothGattCharacteristic*> characteristics;
+  characteristics.push_back(chrc0_.get());
+  characteristics.push_back(chrc1_.get());
+
+  event_router()->DeviceAdded(mock_adapter_, device_.get());
+  event_router()->GattServiceAdded(device_.get(), service0_.get());
+
+  EXPECT_CALL(*mock_adapter_, GetDevice(_)).Times(3).WillRepeatedly(
+      Return(device_.get()));
+  EXPECT_CALL(*device_, GetGattService(kTestServiceId0))
+      .Times(3)
+      .WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
+      .WillRepeatedly(Return(service0_.get()));
+  EXPECT_CALL(*service0_, GetCharacteristics())
+      .Times(2)
+      .WillOnce(Return(std::vector<BluetoothGattCharacteristic*>()))
+      .WillOnce(Return(characteristics));
+
+  ExtensionTestMessageListener listener("ready", true);
+  ASSERT_TRUE(LoadExtension(
+      test_data_dir_.AppendASCII("bluetooth_low_energy/get_characteristics")));
+  EXPECT_TRUE(listener.WaitUntilSatisfied());
+
+  listener.Reply("go");
+
+  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
+  event_router()->GattServiceRemoved(device_.get(), service0_.get());
+  event_router()->DeviceRemoved(mock_adapter_, device_.get());
+}
+
+IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetCharacteristic) {
+  ResultCatcher catcher;
+  catcher.RestrictToProfile(browser()->profile());
+
+  event_router()->DeviceAdded(mock_adapter_, device_.get());
+  event_router()->GattServiceAdded(device_.get(), service0_.get());
+  event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
+
+  EXPECT_CALL(*mock_adapter_, GetDevice(_))
+      .Times(4)
+      .WillOnce(Return(static_cast<BluetoothDevice*>(NULL)))
+      .WillRepeatedly(Return(device_.get()));
+
+  EXPECT_CALL(*device_, GetGattService(kTestServiceId0))
+      .Times(3)
+      .WillOnce(Return(static_cast<BluetoothGattService*>(NULL)))
+      .WillRepeatedly(Return(service0_.get()));
+
+  EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
+      .Times(2)
+      .WillOnce(Return(static_cast<BluetoothGattCharacteristic*>(NULL)))
+      .WillOnce(Return(chrc0_.get()));
+
+  // Load the extension and wait for first test.
+  ExtensionTestMessageListener listener("ready", true);
+  ASSERT_TRUE(LoadExtension(
+      test_data_dir_.AppendASCII("bluetooth_low_energy/get_characteristic")));
+  EXPECT_TRUE(listener.WaitUntilSatisfied());
+
+  listener.Reply("go");
+
+  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
+
+  event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
+  event_router()->GattServiceRemoved(device_.get(), service0_.get());
+  event_router()->DeviceRemoved(mock_adapter_, device_.get());
+}
+
+IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicProperties) {
+  ResultCatcher catcher;
+  catcher.RestrictToProfile(browser()->profile());
+
+  event_router()->DeviceAdded(mock_adapter_, device_.get());
+  event_router()->GattServiceAdded(device_.get(), service0_.get());
+  event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
+
+  EXPECT_CALL(*mock_adapter_, GetDevice(_))
+      .Times(12)
+      .WillRepeatedly(Return(device_.get()));
+  EXPECT_CALL(*device_, GetGattService(kTestServiceId0))
+      .Times(12)
+      .WillRepeatedly(Return(service0_.get()));
+  EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
+      .Times(12)
+      .WillRepeatedly(Return(chrc0_.get()));
+  EXPECT_CALL(*chrc0_, GetProperties())
+      .Times(12)
+      .WillOnce(Return(BluetoothGattCharacteristic::kPropertyNone))
+      .WillOnce(Return(BluetoothGattCharacteristic::kPropertyBroadcast))
+      .WillOnce(Return(BluetoothGattCharacteristic::kPropertyRead))
+      .WillOnce(
+           Return(BluetoothGattCharacteristic::kPropertyWriteWithoutResponse))
+      .WillOnce(Return(BluetoothGattCharacteristic::kPropertyWrite))
+      .WillOnce(Return(BluetoothGattCharacteristic::kPropertyNotify))
+      .WillOnce(Return(BluetoothGattCharacteristic::kPropertyIndicate))
+      .WillOnce(Return(
+          BluetoothGattCharacteristic::kPropertyAuthenticatedSignedWrites))
+      .WillOnce(
+           Return(BluetoothGattCharacteristic::kPropertyExtendedProperties))
+      .WillOnce(Return(BluetoothGattCharacteristic::kPropertyReliableWrite))
+      .WillOnce(
+           Return(BluetoothGattCharacteristic::kPropertyWriteableAuxiliaries))
+      .WillOnce(Return(
+          BluetoothGattCharacteristic::kPropertyBroadcast |
+          BluetoothGattCharacteristic::kPropertyRead |
+          BluetoothGattCharacteristic::kPropertyWriteWithoutResponse |
+          BluetoothGattCharacteristic::kPropertyWrite |
+          BluetoothGattCharacteristic::kPropertyNotify |
+          BluetoothGattCharacteristic::kPropertyIndicate |
+          BluetoothGattCharacteristic::kPropertyAuthenticatedSignedWrites |
+          BluetoothGattCharacteristic::kPropertyExtendedProperties |
+          BluetoothGattCharacteristic::kPropertyReliableWrite |
+          BluetoothGattCharacteristic::kPropertyWriteableAuxiliaries));
+
+  ExtensionTestMessageListener listener("ready", true);
+  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
+      "bluetooth_low_energy/characteristic_properties")));
+  EXPECT_TRUE(listener.WaitUntilSatisfied());
+
+  listener.Reply("go");
+
+  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
+
+  event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
+  event_router()->GattServiceRemoved(device_.get(), service0_.get());
+  event_router()->DeviceRemoved(mock_adapter_, device_.get());
+}
+
+IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicValueChanged) {
+  ResultCatcher catcher;
+  catcher.RestrictToProfile(browser()->profile());
+
+  // Load the extension and let it set up.
+  ExtensionTestMessageListener listener("ready", true);
+  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
+      "bluetooth_low_energy/characteristic_value_changed")));
+
+  // Cause events to be sent to the extension.
+  event_router()->DeviceAdded(mock_adapter_, device_.get());
+  event_router()->GattServiceAdded(device_.get(), service0_.get());
+  event_router()->GattServiceAdded(device_.get(), service1_.get());
+  event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
+  event_router()->GattCharacteristicAdded(service1_.get(), chrc2_.get());
+
+  std::vector<uint8> value;
+  event_router()->GattCharacteristicValueChanged(
+      service0_.get(), chrc0_.get(), value);
+  event_router()->GattCharacteristicValueChanged(
+      service1_.get(), chrc2_.get(), value);
+
+  EXPECT_TRUE(listener.WaitUntilSatisfied());
+  listener.Reply("go");
+
+  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
+  event_router()->GattCharacteristicRemoved(service1_.get(), chrc2_.get());
+  event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
+  event_router()->GattServiceRemoved(device_.get(), service1_.get());
+  event_router()->GattServiceRemoved(device_.get(), service0_.get());
+  event_router()->DeviceRemoved(mock_adapter_, device_.get());
+}
+
+IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadCharacteristicValue) {
+  ResultCatcher catcher;
+  catcher.RestrictToProfile(browser()->profile());
+
+  event_router()->DeviceAdded(mock_adapter_, device_.get());
+  event_router()->GattServiceAdded(device_.get(), service0_.get());
+  event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get());
+
+  EXPECT_CALL(*mock_adapter_, GetDevice(_))
+      .Times(3)
+      .WillRepeatedly(Return(device_.get()));
+
+  EXPECT_CALL(*device_, GetGattService(kTestServiceId0))
+      .Times(3)
+      .WillRepeatedly(Return(service0_.get()));
+
+  EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0))
+      .Times(3)
+      .WillRepeatedly(Return(chrc0_.get()));
+
+  EXPECT_CALL(*chrc0_, ReadRemoteCharacteristic(_, _))
+      .Times(2)
+      .WillOnce(Invoke(&ReadValueErrorCallback))
+      .WillOnce(Invoke(&ReadValueSuccessCallback));
+
+  ExtensionTestMessageListener listener("ready", true);
+  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
+      "bluetooth_low_energy/read_characteristic_value")));
+  EXPECT_TRUE(listener.WaitUntilSatisfied());
+
+  listener.Reply("go");
+
+  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
+
+  event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get());
+  event_router()->GattServiceRemoved(device_.get(), service0_.get());
+  event_router()->DeviceRemoved(mock_adapter_, device_.get());
+}
+
 }  // namespace
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
index d9d96c4..eeccc82 100644
--- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
+++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc
@@ -7,8 +7,10 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/values.h"
+#include "chrome/browser/extensions/api/bluetooth_low_energy/utils.h"
 #include "content/public/browser/browser_thread.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/bluetooth/bluetooth_gatt_characteristic.h"
 #include "extensions/browser/event_router.h"
 
 using content::BrowserThread;
@@ -39,15 +41,68 @@
       new std::string(service->GetDevice()->GetAddress()));
 }
 
+void PopulateCharacteristicProperties(
+    BluetoothGattCharacteristic::Properties properties,
+    std::vector<apibtle::CharacteristicProperty>* api_properties) {
+  DCHECK(api_properties && api_properties->empty());
+
+  if (properties == BluetoothGattCharacteristic::kPropertyNone)
+    return;
+
+  if (properties & BluetoothGattCharacteristic::kPropertyBroadcast)
+    api_properties->push_back(apibtle::CHARACTERISTIC_PROPERTY_BROADCAST);
+  if (properties & BluetoothGattCharacteristic::kPropertyRead)
+    api_properties->push_back(apibtle::CHARACTERISTIC_PROPERTY_READ);
+  if (properties & BluetoothGattCharacteristic::kPropertyWriteWithoutResponse) {
+    api_properties->push_back(
+        apibtle::CHARACTERISTIC_PROPERTY_WRITEWITHOUTRESPONSE);
+  }
+  if (properties & BluetoothGattCharacteristic::kPropertyWrite)
+    api_properties->push_back(apibtle::CHARACTERISTIC_PROPERTY_WRITE);
+  if (properties & BluetoothGattCharacteristic::kPropertyNotify)
+    api_properties->push_back(apibtle::CHARACTERISTIC_PROPERTY_NOTIFY);
+  if (properties & BluetoothGattCharacteristic::kPropertyIndicate)
+    api_properties->push_back(apibtle::CHARACTERISTIC_PROPERTY_INDICATE);
+  if (properties &
+      BluetoothGattCharacteristic::kPropertyAuthenticatedSignedWrites) {
+    api_properties->push_back(
+        apibtle::CHARACTERISTIC_PROPERTY_AUTHENTICATEDSIGNEDWRITES);
+  }
+  if (properties & BluetoothGattCharacteristic::kPropertyExtendedProperties) {
+    api_properties->push_back(
+        apibtle::CHARACTERISTIC_PROPERTY_EXTENDEDPROPERTIES);
+  }
+  if (properties & BluetoothGattCharacteristic::kPropertyReliableWrite)
+    api_properties->push_back(apibtle::CHARACTERISTIC_PROPERTY_RELIABLEWRITE);
+  if (properties & BluetoothGattCharacteristic::kPropertyWriteableAuxiliaries) {
+    api_properties->push_back(
+        apibtle::CHARACTERISTIC_PROPERTY_WRITEABLEAUXILIARIES);
+  }
+}
+
+void PopulateCharacteristic(const BluetoothGattCharacteristic* characteristic,
+                            apibtle::Characteristic* out) {
+  DCHECK(out);
+
+  out->uuid = characteristic->GetUUID().canonical_value();
+  out->is_local = characteristic->IsLocal();
+  out->instance_id.reset(new std::string(characteristic->GetIdentifier()));
+
+  PopulateService(characteristic->GetService(), &out->service);
+  PopulateCharacteristicProperties(characteristic->GetProperties(),
+                                   &out->properties);
+
+  const std::vector<uint8>& value = characteristic->GetValue();
+  if (value.empty())
+    return;
+
+  out->value.reset(new std::string(value.begin(), value.end()));
+}
+
 }  // namespace
 
 namespace extensions {
 
-BluetoothLowEnergyEventRouter::GattObjectData::GattObjectData() {
-}
-BluetoothLowEnergyEventRouter::GattObjectData::~GattObjectData() {
-}
-
 BluetoothLowEnergyEventRouter::BluetoothLowEnergyEventRouter(
     content::BrowserContext* context)
     : adapter_(NULL), browser_context_(context), weak_ptr_factory_(this) {
@@ -81,20 +136,9 @@
            observed_gatt_services_.begin();
        iter != observed_gatt_services_.end();
        ++iter) {
-    InstanceIdToObjectDataMap::const_iterator id_iter =
-        service_ids_to_objects_.find(*iter);
-    if (id_iter == service_ids_to_objects_.end())
-      continue;
-
-    GattObjectData data = id_iter->second;
-    BluetoothDevice* device = adapter_->GetDevice(data.device_address);
-    if (!device)
-      continue;
-
-    BluetoothGattService* service = device->GetGattService(data.service_id);
+    BluetoothGattService* service = FindServiceById(*iter);
     if (!service)
       continue;
-
     service->RemoveObserver(this);
   }
 
@@ -217,6 +261,88 @@
   return true;
 }
 
+bool BluetoothLowEnergyEventRouter::GetCharacteristics(
+    const std::string& instance_id,
+    CharacteristicList* out_characteristics) const {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(out_characteristics);
+  if (!adapter_) {
+    VLOG(1) << "BlutoothAdapter not ready.";
+    return false;
+  }
+
+  BluetoothGattService* service = FindServiceById(instance_id);
+  if (!service) {
+    VLOG(1) << "Service not found: " << instance_id;
+    return false;
+  }
+
+  out_characteristics->clear();
+
+  const std::vector<BluetoothGattCharacteristic*>& characteristics =
+      service->GetCharacteristics();
+  for (std::vector<BluetoothGattCharacteristic*>::const_iterator iter =
+           characteristics.begin();
+       iter != characteristics.end();
+       ++iter) {
+    // Populate an API characteristic and add it to the return value.
+    const BluetoothGattCharacteristic* characteristic = *iter;
+    linked_ptr<apibtle::Characteristic> api_characteristic(
+        new apibtle::Characteristic());
+    PopulateCharacteristic(characteristic, api_characteristic.get());
+
+    out_characteristics->push_back(api_characteristic);
+  }
+
+  return true;
+}
+
+bool BluetoothLowEnergyEventRouter::GetCharacteristic(
+    const std::string& instance_id,
+    apibtle::Characteristic* out_characteristic) const {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  if (!adapter_) {
+    VLOG(1) << "BluetoothAdapter not ready.";
+    return false;
+  }
+
+  BluetoothGattCharacteristic* characteristic =
+      FindCharacteristicById(instance_id);
+  if (!characteristic) {
+    VLOG(1) << "Characteristic not found: " << instance_id;
+    return false;
+  }
+
+  PopulateCharacteristic(characteristic, out_characteristic);
+  return true;
+}
+
+bool BluetoothLowEnergyEventRouter::ReadCharacteristicValue(
+    const std::string& instance_id,
+    const base::Closure& callback,
+    const base::Closure& error_callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  if (!adapter_) {
+    VLOG(1) << "BluetoothAdapter not ready.";
+    return false;
+  }
+
+  BluetoothGattCharacteristic* characteristic =
+      FindCharacteristicById(instance_id);
+  if (!characteristic) {
+    VLOG(1) << "Characteristic not found: " << instance_id;
+    return false;
+  }
+
+  characteristic->ReadRemoteCharacteristic(
+      base::Bind(&BluetoothLowEnergyEventRouter::ValueCallback,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 callback),
+      error_callback);
+
+  return true;
+}
+
 void BluetoothLowEnergyEventRouter::SetAdapterForTesting(
     device::BluetoothAdapter* adapter) {
   adapter_ = adapter;
@@ -249,16 +375,14 @@
 
   DCHECK(observed_gatt_services_.find(service->GetIdentifier()) ==
          observed_gatt_services_.end());
-  DCHECK(service_ids_to_objects_.find(service->GetIdentifier()) ==
-         service_ids_to_objects_.end());
+  DCHECK(service_id_to_device_address_.find(service->GetIdentifier()) ==
+         service_id_to_device_address_.end());
 
   service->AddObserver(this);
-  observed_gatt_services_.insert(service->GetIdentifier());
 
-  GattObjectData data;
-  data.device_address = device->GetAddress();
-  data.service_id = service->GetIdentifier();
-  service_ids_to_objects_[data.service_id] = data;
+  const std::string& service_id = service->GetIdentifier();
+  observed_gatt_services_.insert(service_id);
+  service_id_to_device_address_[service_id] = device->GetAddress();
 
   // Signal API event.
   apibtle::Service api_service;
@@ -279,15 +403,15 @@
 
   DCHECK(observed_gatt_services_.find(service->GetIdentifier()) !=
          observed_gatt_services_.end());
-  DCHECK(service_ids_to_objects_.find(service->GetIdentifier()) !=
-         service_ids_to_objects_.end());
+  DCHECK(service_id_to_device_address_.find(service->GetIdentifier()) !=
+         service_id_to_device_address_.end());
 
   service->RemoveObserver(this);
   observed_gatt_services_.erase(service->GetIdentifier());
 
   DCHECK(device->GetAddress() ==
-         service_ids_to_objects_[service->GetIdentifier()].device_address);
-  service_ids_to_objects_.erase(service->GetIdentifier());
+         service_id_to_device_address_[service->GetIdentifier()]);
+  service_id_to_device_address_.erase(service->GetIdentifier());
 
   // Signal API event.
   apibtle::Service api_service;
@@ -307,8 +431,8 @@
 
   DCHECK(observed_gatt_services_.find(service->GetIdentifier()) !=
          observed_gatt_services_.end());
-  DCHECK(service_ids_to_objects_.find(service->GetIdentifier()) !=
-         service_ids_to_objects_.end());
+  DCHECK(service_id_to_device_address_.find(service->GetIdentifier()) !=
+         service_id_to_device_address_.end());
 
   // Signal API event.
   apibtle::Service api_service;
@@ -324,30 +448,63 @@
 void BluetoothLowEnergyEventRouter::GattCharacteristicAdded(
     BluetoothGattService* service,
     BluetoothGattCharacteristic* characteristic) {
-  // TODO(armansito): Implement.
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  VLOG(2) << "GATT characteristic added: " << characteristic->GetIdentifier();
+
+  DCHECK(chrc_id_to_service_id_.find(characteristic->GetIdentifier()) ==
+         chrc_id_to_service_id_.end());
+
+  chrc_id_to_service_id_[characteristic->GetIdentifier()] =
+      service->GetIdentifier();
 }
 
 void BluetoothLowEnergyEventRouter::GattCharacteristicRemoved(
     BluetoothGattService* service,
     BluetoothGattCharacteristic* characteristic) {
-  // TODO(armansito): Implement.
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  VLOG(2) << "GATT characteristic removed: " << characteristic->GetIdentifier();
+
+  DCHECK(chrc_id_to_service_id_.find(characteristic->GetIdentifier()) !=
+         chrc_id_to_service_id_.end());
+  DCHECK(service->GetIdentifier() ==
+         chrc_id_to_service_id_[characteristic->GetIdentifier()]);
+
+  chrc_id_to_service_id_.erase(characteristic->GetIdentifier());
 }
 
 void BluetoothLowEnergyEventRouter::GattCharacteristicValueChanged(
     BluetoothGattService* service,
     BluetoothGattCharacteristic* characteristic,
     const std::vector<uint8>& value) {
-  // TODO(armansito): Implement.
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  VLOG(2) << "GATT characteristic value changed: " << service->GetIdentifier();
+
+  DCHECK(observed_gatt_services_.find(service->GetIdentifier()) !=
+         observed_gatt_services_.end());
+  DCHECK(service_id_to_device_address_.find(service->GetIdentifier()) !=
+         service_id_to_device_address_.end());
+  DCHECK(chrc_id_to_service_id_.find(characteristic->GetIdentifier()) !=
+         chrc_id_to_service_id_.end());
+  DCHECK(chrc_id_to_service_id_[characteristic->GetIdentifier()] ==
+         service->GetIdentifier());
+
+  // Signal API event.
+  apibtle::Characteristic api_characteristic;
+  PopulateCharacteristic(characteristic, &api_characteristic);
+
+  // Manually construct the arguments, instead of using
+  // apibtle::OnCharacteristicValueChanged::Create, as it doesn't convert lists
+  // of enums correctly.
+  scoped_ptr<base::ListValue> args(new base::ListValue());
+  args->Append(apibtle::CharacteristicToValue(&api_characteristic).release());
+  scoped_ptr<Event> event(new Event(
+      apibtle::OnCharacteristicValueChanged::kEventName, args.Pass()));
+  EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
 }
 
 void BluetoothLowEnergyEventRouter::OnGetAdapter(
     const base::Closure& callback,
     scoped_refptr<device::BluetoothAdapter> adapter) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(service_ids_to_objects_.empty());
-  DCHECK(observed_devices_.empty());
-  DCHECK(observed_gatt_services_.empty());
-
   adapter_ = adapter;
 
   // Initialize instance ID mappings for all discovered GATT objects and add
@@ -359,6 +516,13 @@
 }
 
 void BluetoothLowEnergyEventRouter::InitializeIdentifierMappings() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(service_id_to_device_address_.empty());
+  DCHECK(chrc_id_to_service_id_.empty());
+  DCHECK(observed_devices_.empty());
+  DCHECK(observed_gatt_services_.empty());
+
+  // Devices
   BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
   for (BluetoothAdapter::DeviceList::iterator iter = devices.begin();
        iter != devices.end();
@@ -367,53 +531,96 @@
     device->AddObserver(this);
     observed_devices_.insert(device->GetAddress());
 
+    // Services
     std::vector<BluetoothGattService*> services = device->GetGattServices();
     for (std::vector<BluetoothGattService*>::iterator siter = services.begin();
          siter != services.end();
          ++siter) {
       BluetoothGattService* service = *siter;
       service->AddObserver(this);
-      observed_gatt_services_.insert(service->GetIdentifier());
 
-      GattObjectData service_data;
-      service_data.device_address = device->GetAddress();
-      service_data.service_id = service->GetIdentifier();
-      service_ids_to_objects_[service_data.service_id] = service_data;
+      const std::string& service_id = service->GetIdentifier();
+      observed_gatt_services_.insert(service_id);
+      service_id_to_device_address_[service_id] = device->GetAddress();
 
-      // TODO(armansito): Initialize mapping for characteristics & descriptors.
+      // Characteristics
+      std::vector<BluetoothGattCharacteristic*> characteristics =
+          service->GetCharacteristics();
+      for (std::vector<BluetoothGattCharacteristic*>::iterator citer =
+               characteristics.begin();
+           citer != characteristics.end();
+           ++citer) {
+        BluetoothGattCharacteristic* characteristic = *citer;
+
+        const std::string& chrc_id = characteristic->GetIdentifier();
+        chrc_id_to_service_id_[chrc_id] = service_id;
+
+        // TODO(armansito): Initialize mapping for descriptors.
+      }
     }
   }
 }
 
 BluetoothGattService* BluetoothLowEnergyEventRouter::FindServiceById(
     const std::string& instance_id) const {
-  InstanceIdToObjectDataMap::const_iterator iter =
-      service_ids_to_objects_.find(instance_id);
-  if (iter == service_ids_to_objects_.end()) {
+  InstanceIdMap::const_iterator iter =
+      service_id_to_device_address_.find(instance_id);
+  if (iter == service_id_to_device_address_.end()) {
     VLOG(1) << "GATT service identifier unknown: " << instance_id;
     return NULL;
   }
 
-  GattObjectData data = iter->second;
-  DCHECK(!data.device_address.empty());
-  DCHECK(!data.service_id.empty());
-  DCHECK(data.characteristic_id.empty());
-  DCHECK(data.descriptor_id.empty());
+  const std::string& address = iter->second;
 
-  BluetoothDevice* device = adapter_->GetDevice(data.device_address);
+  BluetoothDevice* device = adapter_->GetDevice(address);
   if (!device) {
-    VLOG(1) << "Bluetooth device not found: " << data.device_address;
+    VLOG(1) << "Bluetooth device not found: " << address;
     return NULL;
   }
 
-  BluetoothGattService* service = device->GetGattService(data.service_id);
+  BluetoothGattService* service = device->GetGattService(instance_id);
   if (!service) {
-    VLOG(1) << "GATT service with ID \"" << data.service_id
-            << "\" not found on device \"" << data.device_address << "\"";
+    VLOG(1) << "GATT service with ID \"" << instance_id
+            << "\" not found on device \"" << address << "\"";
     return NULL;
   }
 
   return service;
 }
 
+BluetoothGattCharacteristic*
+BluetoothLowEnergyEventRouter::FindCharacteristicById(
+    const std::string& instance_id) const {
+  InstanceIdMap::const_iterator iter = chrc_id_to_service_id_.find(instance_id);
+  if (iter == chrc_id_to_service_id_.end()) {
+    VLOG(1) << "GATT characteristic identifier unknown: " << instance_id;
+    return NULL;
+  }
+
+  const std::string& service_id = iter->second;
+
+  BluetoothGattService* service = FindServiceById(service_id);
+  if (!service) {
+    VLOG(1) << "Failed to obtain service for characteristic: " << instance_id;
+    return NULL;
+  }
+
+  BluetoothGattCharacteristic* characteristic =
+      service->GetCharacteristic(instance_id);
+  if (!characteristic) {
+    VLOG(1) << "GATT characteristic with ID \"" << instance_id
+            << "\" not found on service \"" << service_id << "\"";
+    return NULL;
+  }
+
+  return characteristic;
+}
+
+void BluetoothLowEnergyEventRouter::ValueCallback(
+    const base::Closure& callback,
+    const std::vector<uint8>& value) {
+  VLOG(2) << "Remote characteristic value read successful.";
+  callback.Run();
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h
index 82e20ad..8ea114b 100644
--- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h
+++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h
@@ -61,7 +61,7 @@
   // with the Bluetooth device with address |device_address| in |out_services|.
   // Returns false, if no device with the given address is known. If the device
   // is found but it has no GATT services, then returns true and leaves
-  // |out_services| as empty. Returns true, on success. |out_services| must not
+  // |out_services| empty. Returns true, on success. |out_services| must not
   // be NULL. If it is non-empty, then its contents will be cleared.
   typedef std::vector<linked_ptr<api::bluetooth_low_energy::Service> >
       ServiceList;
@@ -70,7 +70,7 @@
 
   // Populates |out_service| based on GATT service with instance ID
   // |instance_id|. Returns true on success. Returns false, if no GATT service
-  // with the given ID is known. |service| must not be NULL.
+  // with the given ID is known. |out_service| must not be NULL.
   bool GetService(const std::string& instance_id,
                   api::bluetooth_low_energy::Service* out_service) const;
 
@@ -83,6 +83,34 @@
   bool GetIncludedServices(const std::string& instance_id,
                            ServiceList* out_services) const;
 
+  // Returns the list of api::bluetooth_low_energy::Characteristic objects
+  // associated with the GATT service with instance ID |instance_id| in
+  // |out_characteristics|. Returns false, if no service with the given instance
+  // ID is known. If the service is found but it has no characteristics, then
+  // returns true and leaves |out_characteristics| empty. Returns true on
+  // success. |out_characteristics| must not be NULL and if it is non-empty,
+  // then its contents will be cleared.
+  typedef std::vector<linked_ptr<api::bluetooth_low_energy::Characteristic> >
+      CharacteristicList;
+  bool GetCharacteristics(const std::string& instance_id,
+                          CharacteristicList* out_characteristics) const;
+
+  // Populates |out_characteristic| based on GATT characteristic with instance
+  // ID |instance_id|. Returns true, on success. Returns false, if no GATT
+  // characteristic with the given ID is known. |out_characteristic| must not be
+  // NULL.
+  bool GetCharacteristic(
+      const std::string& instance_id,
+      api::bluetooth_low_energy::Characteristic* out_characteristic) const;
+
+  // Sends a request to read the value of the characteristic with intance ID
+  // |instance_id|. Returns false, if no such characteristic is known.
+  // Otherwise, returns true and invokes |callback| on success and
+  // |error_callback| on failure.
+  bool ReadCharacteristicValue(const std::string& instance_id,
+                               const base::Closure& callback,
+                               const base::Closure& error_callback);
+
   // Initializes the adapter for testing. Used by unit tests only.
   void SetAdapterForTesting(device::BluetoothAdapter* adapter);
 
@@ -127,32 +155,31 @@
   device::BluetoothGattService* FindServiceById(
       const std::string& instance_id) const;
 
-  // Meta-data that identifies GATT services, characteristics, and descriptors,
-  // for obtaining instances from the BluetoothAdapter.
-  struct GattObjectData {
-    GattObjectData();
-    ~GattObjectData();
+  // Returns a BluetoothGattCharacteristic by its instance ID |instance_id|.
+  // Returns NULL, if the characteristic cannot be found.
+  device::BluetoothGattCharacteristic* FindCharacteristicById(
+      const std::string& instance_id) const;
 
-    std::string device_address;
-    std::string service_id;
-    std::string characteristic_id;
-    std::string descriptor_id;
-  };
+  // Called by BluetoothGattCharacteristic in response to
+  // ReadRemoteCharacteristic.
+  void ValueCallback(const base::Closure& callback,
+                     const std::vector<uint8>& value);
 
-  // Mapping from instance ids to GattObjectData. The keys are used to identify
-  // individual instances of GATT objects and is used by bluetoothLowEnergy API
-  // functions to obtain the correct GATT object to operate on. Instance IDs are
-  // string identifiers that are returned by the device/bluetooth API, by
-  // calling GetIdentifier() on the corresponding device::BluetoothGatt*
-  // instance.
+  // Mapping from instance ids to identifiers of owning instances. The keys are
+  // used to identify individual instances of GATT objects and are used by
+  // bluetoothLowEnergy API functions to obtain the correct GATT object to
+  // operate on. Instance IDs are string identifiers that are returned by the
+  // device/bluetooth API, by calling GetIdentifier() on the corresponding
+  // device::BluetoothGatt* instance.
   //
   // This mapping is necessary, as GATT object instances can only be obtained
   // from the object that owns it, where raw pointers should not be cached. E.g.
   // to obtain a device::BluetoothGattCharacteristic, it is necessary to obtain
   // a pointer to the associated device::BluetoothDevice, and then to the
   // device::BluetoothGattService that owns the characteristic.
-  typedef std::map<std::string, GattObjectData> InstanceIdToObjectDataMap;
-  InstanceIdToObjectDataMap service_ids_to_objects_;
+  typedef std::map<std::string, std::string> InstanceIdMap;
+  InstanceIdMap service_id_to_device_address_;
+  InstanceIdMap chrc_id_to_service_id_;
 
   // Sets of BluetoothDevice and BluetoothGattService objects that are being
   // observed, used to remove the BluetoothLowEnergyEventRouter as an observer
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/utils.cc b/chrome/browser/extensions/api/bluetooth_low_energy/utils.cc
new file mode 100644
index 0000000..09e5819
--- /dev/null
+++ b/chrome/browser/extensions/api/bluetooth_low_energy/utils.cc
@@ -0,0 +1,33 @@
+// 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.
+
+#include "chrome/browser/extensions/api/bluetooth_low_energy/utils.h"
+
+namespace extensions {
+namespace api {
+namespace bluetooth_low_energy {
+
+scoped_ptr<base::DictionaryValue> CharacteristicToValue(Characteristic* from) {
+  // Copy the properties. Use Characteristic::ToValue to generate the result
+  // dictionary without the properties, to prevent json_schema_compiler from
+  // failing.
+  std::vector<CharacteristicProperty> properties = from->properties;
+  from->properties.clear();
+  scoped_ptr<base::DictionaryValue> to = from->ToValue();
+
+  // Manually set each property.
+  scoped_ptr<base::ListValue> property_list(new base::ListValue());
+  for (std::vector<CharacteristicProperty>::iterator iter = properties.begin();
+       iter != properties.end();
+       ++iter)
+    property_list->Append(new base::StringValue(ToString(*iter)));
+
+  to->Set("properties", property_list.release());
+
+  return to.Pass();
+}
+
+}  // namespace bluetooth_low_energy
+}  // namespace api
+}  // namespace extensions
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/utils.h b/chrome/browser/extensions/api/bluetooth_low_energy/utils.h
new file mode 100644
index 0000000..7d3da07
--- /dev/null
+++ b/chrome/browser/extensions/api/bluetooth_low_energy/utils.h
@@ -0,0 +1,29 @@
+// 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_LOW_ENERGY_UTILS_H_
+#define CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_LOW_ENERGY_UTILS_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "chrome/common/extensions/api/bluetooth_low_energy.h"
+
+namespace extensions {
+namespace api {
+namespace bluetooth_low_energy {
+
+// TODO(armansito): Remove this function once the described bug is fixed.
+// (See crbug.com/368368)
+//
+// Converts a Characteristic to a base::Value. This function is necessary as
+// json_schema_compiler::util::AddItemToList has no template specialization for
+// user defined enums, which get treated as integers. This is because
+// Characteristic contains a list of enum CharacteristicProperty.
+scoped_ptr<base::DictionaryValue> CharacteristicToValue(Characteristic* from);
+
+}  // namespace bluetooth_low_energy
+}  // namespace api
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_LOW_ENERGY_UTILS_H_
diff --git a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.cc b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.cc
index 0fd43f5..1221359 100644
--- a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.cc
+++ b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.cc
@@ -6,8 +6,14 @@
 
 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_socket.h"
 #include "chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_event_dispatcher.h"
+#include "chrome/common/extensions/api/bluetooth/bluetooth_manifest_data.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
+#include "device/bluetooth/bluetooth_adapter.h"
+#include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/bluetooth_socket.h"
+#include "extensions/common/permissions/permissions_data.h"
 #include "net/base/io_buffer.h"
 
 using content::BrowserThread;
@@ -17,6 +23,9 @@
 
 namespace {
 
+const char kDeviceNotFoundError[] = "Device not found";
+const char kInvalidUuidError[] = "Invalid UUID";
+const char kPermissionDeniedError[] = "Permission denied";
 const char kSocketNotFoundError[] = "Socket not found";
 
 linked_ptr<SocketInfo> CreateSocketInfo(int socket_id,
@@ -59,6 +68,18 @@
   }
 }
 
+extensions::api::BluetoothSocketEventDispatcher* GetSocketEventDispatcher(
+    content::BrowserContext* browser_context) {
+  extensions::api::BluetoothSocketEventDispatcher* socket_event_dispatcher =
+      extensions::api::BluetoothSocketEventDispatcher::Get(browser_context);
+  DCHECK(socket_event_dispatcher)
+      << "There is no socket event dispatcher. "
+         "If this assertion is failing during a test, then it is likely that "
+         "TestExtensionSystem is failing to provide an instance of "
+         "BluetoothSocketEventDispatcher.";
+  return socket_event_dispatcher;
+}
+
 }  // namespace
 
 namespace extensions {
@@ -68,7 +89,7 @@
 
 BluetoothSocketAsyncApiFunction::~BluetoothSocketAsyncApiFunction() {}
 
-bool BluetoothSocketAsyncApiFunction::RunImpl() {
+bool BluetoothSocketAsyncApiFunction::RunAsync() {
   if (!PrePrepare() || !Prepare()) {
     return false;
   }
@@ -180,13 +201,7 @@
   params_ = bluetooth_socket::SetPaused::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params_.get());
 
-  socket_event_dispatcher_ =
-      BluetoothSocketEventDispatcher::Get(browser_context());
-  DCHECK(socket_event_dispatcher_)
-      << "There is no socket event dispatcher. "
-         "If this assertion is failing during a test, then it is likely that "
-         "TestExtensionSystem is failing to provide an instance of "
-         "BluetoothSocketEventDispatcher.";
+  socket_event_dispatcher_ = GetSocketEventDispatcher(browser_context());
   return socket_event_dispatcher_ != NULL;
 }
 
@@ -208,28 +223,109 @@
   results_ = bluetooth_socket::SetPaused::Results::Create();
 }
 
-bool BluetoothSocketListenUsingRfcommFunction::RunImpl() {
+bool BluetoothSocketListenUsingRfcommFunction::RunAsync() {
   // TODO(keybuk): Implement.
   SetError("Not yet implemented.");
   return false;
 }
 
-bool BluetoothSocketListenUsingInsecureRfcommFunction::RunImpl() {
+bool BluetoothSocketListenUsingInsecureRfcommFunction::RunAsync() {
   // TODO(keybuk): Implement.
   SetError("Not yet implemented.");
   return false;
 }
 
-bool BluetoothSocketListenUsingL2capFunction::RunImpl() {
+bool BluetoothSocketListenUsingL2capFunction::RunAsync() {
   // TODO(keybuk): Implement.
   SetError("Not yet implemented.");
   return false;
 }
 
-bool BluetoothSocketConnectFunction::RunImpl() {
-  // TODO(keybuk): Implement.
-  SetError("Not yet implemented.");
-  return false;
+BluetoothSocketConnectFunction::BluetoothSocketConnectFunction() {}
+
+BluetoothSocketConnectFunction::~BluetoothSocketConnectFunction() {}
+
+bool BluetoothSocketConnectFunction::Prepare() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  params_ = bluetooth_socket::Connect::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(params_.get());
+
+  socket_event_dispatcher_ = GetSocketEventDispatcher(browser_context());
+  return socket_event_dispatcher_ != NULL;
+}
+
+void BluetoothSocketConnectFunction::AsyncWorkStart() {
+  DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
+  device::BluetoothAdapterFactory::GetAdapter(
+      base::Bind(&BluetoothSocketConnectFunction::OnGetAdapter, this));
+}
+
+void BluetoothSocketConnectFunction::OnGetAdapter(
+    scoped_refptr<device::BluetoothAdapter> adapter) {
+  DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
+  BluetoothApiSocket* socket = GetSocket(params_->socket_id);
+  if (!socket) {
+    error_ = kSocketNotFoundError;
+    AsyncWorkCompleted();
+    return;
+  }
+
+  device::BluetoothDevice* device = adapter->GetDevice(params_->address);
+  if (!device) {
+    error_ = kDeviceNotFoundError;
+    AsyncWorkCompleted();
+    return;
+  }
+
+  device::BluetoothUUID uuid(params_->uuid);
+  if (!uuid.IsValid()) {
+    error_ = kInvalidUuidError;
+    AsyncWorkCompleted();
+    return;
+  }
+
+  BluetoothPermissionRequest param(params_->uuid);
+  if (!BluetoothManifestData::CheckRequest(GetExtension(), param)) {
+    error_ = kPermissionDeniedError;
+    AsyncWorkCompleted();
+    return;
+  }
+
+  device->ConnectToService(
+      uuid,
+      base::Bind(&BluetoothSocketConnectFunction::OnConnect, this),
+      base::Bind(&BluetoothSocketConnectFunction::OnConnectError, this));
+}
+
+void BluetoothSocketConnectFunction::OnConnect(
+    scoped_refptr<device::BluetoothSocket> socket) {
+  DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
+
+  // Fetch the socket again since this is not a reference-counted object, and
+  // it may have gone away in the meantime (we check earlier to avoid making
+  // a connection in the case of an obvious programming error).
+  BluetoothApiSocket* api_socket = GetSocket(params_->socket_id);
+  if (!api_socket) {
+    error_ = kSocketNotFoundError;
+    AsyncWorkCompleted();
+    return;
+  }
+
+  api_socket->AdoptConnectedSocket(socket,
+                                   params_->address,
+                                   device::BluetoothUUID(params_->uuid));
+  socket_event_dispatcher_->OnSocketConnect(extension_id(),
+                                            params_->socket_id);
+
+  results_ = bluetooth_socket::Connect::Results::Create();
+  AsyncWorkCompleted();
+}
+
+void BluetoothSocketConnectFunction::OnConnectError(
+    const std::string& message) {
+  DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
+  error_ = message;
+  AsyncWorkCompleted();
 }
 
 BluetoothSocketDisconnectFunction::BluetoothSocketDisconnectFunction() {}
@@ -248,6 +344,7 @@
   BluetoothApiSocket* socket = GetSocket(params_->socket_id);
   if (!socket) {
     error_ = kSocketNotFoundError;
+    AsyncWorkCompleted();
     return;
   }
 
diff --git a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h
index c7cd376..4eff552 100644
--- a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h
+++ b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h
@@ -12,11 +12,16 @@
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_socket.h"
 #include "chrome/common/extensions/api/bluetooth_socket.h"
+#include "device/bluetooth/bluetooth_adapter.h"
 #include "extensions/browser/api/api_resource_manager.h"
 #include "extensions/browser/api/async_api_function.h"
 #include "extensions/browser/extension_function.h"
 #include "extensions/browser/extension_function_histogram_value.h"
 
+namespace device {
+class BluetoothSocket;
+}
+
 namespace net {
 class IOBuffer;
 }
@@ -31,15 +36,15 @@
 // thread while providing methods to manage resources of that class. This
 // follows the pattern of AsyncApiFunction, but does not derive from it,
 // because BluetoothApiSocket methods must be called on the UI Thread.
-class BluetoothSocketAsyncApiFunction : public UIThreadExtensionFunction {
+class BluetoothSocketAsyncApiFunction : public AsyncExtensionFunction {
  public:
   BluetoothSocketAsyncApiFunction();
 
  protected:
   virtual ~BluetoothSocketAsyncApiFunction();
 
-  // UIThreadExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  // AsyncExtensionFunction:
+  virtual bool RunAsync() OVERRIDE;
 
   bool PrePrepare();
   bool Respond();
@@ -114,8 +119,7 @@
   BluetoothSocketEventDispatcher* socket_event_dispatcher_;
 };
 
-class BluetoothSocketListenUsingRfcommFunction
-    : public UIThreadExtensionFunction {
+class BluetoothSocketListenUsingRfcommFunction : public AsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetoothSocket.listenUsingRfcomm",
                              BLUETOOTHSOCKET_LISTENUSINGRFCOMM);
@@ -123,12 +127,12 @@
  protected:
   virtual ~BluetoothSocketListenUsingRfcommFunction() {}
 
-  // UIThreadExtensionFunction override:
-  virtual bool RunImpl() OVERRIDE;
+  // AsyncExtensionFunction override:
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class BluetoothSocketListenUsingInsecureRfcommFunction
-    : public UIThreadExtensionFunction {
+    : public AsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetoothSocket.listenUsingInsecureRfcomm",
                              BLUETOOTHSOCKET_LISTENUSINGINSECURERFCOMM);
@@ -136,12 +140,11 @@
  protected:
   virtual ~BluetoothSocketListenUsingInsecureRfcommFunction() {}
 
-  // UIThreadExtensionFunction override:
-  virtual bool RunImpl() OVERRIDE;
+  // AsyncExtensionFunction override:
+  virtual bool RunAsync() OVERRIDE;
 };
 
-class BluetoothSocketListenUsingL2capFunction
-    : public UIThreadExtensionFunction {
+class BluetoothSocketListenUsingL2capFunction : public AsyncExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetoothSocket.listenUsingL2cap",
                              BLUETOOTHSOCKET_LISTENUSINGL2CAP);
@@ -149,20 +152,31 @@
  protected:
   virtual ~BluetoothSocketListenUsingL2capFunction() {}
 
-  // UIThreadExtensionFunction override:
-  virtual bool RunImpl() OVERRIDE;
+  // AsyncExtensionFunction override:
+  virtual bool RunAsync() OVERRIDE;
 };
 
-class BluetoothSocketConnectFunction : public UIThreadExtensionFunction {
+class BluetoothSocketConnectFunction : public BluetoothSocketAsyncApiFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetoothSocket.connect",
                              BLUETOOTHSOCKET_CONNECT);
 
- protected:
-  virtual ~BluetoothSocketConnectFunction() {}
+  BluetoothSocketConnectFunction();
 
-  // UIThreadExtensionFunction override:
-  virtual bool RunImpl() OVERRIDE;
+ protected:
+  virtual ~BluetoothSocketConnectFunction();
+
+  // BluetoothSocketAsyncApiFunction:
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+  virtual void OnGetAdapter(scoped_refptr<device::BluetoothAdapter> adapter);
+  virtual void OnConnect(scoped_refptr<device::BluetoothSocket> socket);
+  virtual void OnConnectError(const std::string& message);
+
+  scoped_ptr<bluetooth_socket::Connect::Params> params_;
+  BluetoothSocketEventDispatcher* socket_event_dispatcher_;
 };
 
 class BluetoothSocketDisconnectFunction
diff --git a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_apitest.cc b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_apitest.cc
new file mode 100644
index 0000000..b7bb236
--- /dev/null
+++ b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_apitest.cc
@@ -0,0 +1,134 @@
+// 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.
+
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/extensions/extension_function_test_utils.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_test_message_listener.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/test/mock_bluetooth_adapter.h"
+#include "device/bluetooth/test/mock_bluetooth_device.h"
+#include "device/bluetooth/test/mock_bluetooth_socket.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using device::BluetoothAdapter;
+using device::BluetoothAdapterFactory;
+using device::BluetoothDevice;
+using device::BluetoothSocket;
+using device::BluetoothUUID;
+using device::MockBluetoothAdapter;
+using device::MockBluetoothDevice;
+using device::MockBluetoothSocket;
+using extensions::Extension;
+
+namespace utils = extension_function_test_utils;
+namespace api = extensions::api;
+
+namespace {
+
+class BluetoothSocketApiTest : public ExtensionApiTest {
+ public:
+  BluetoothSocketApiTest() {}
+
+  virtual void SetUpOnMainThread() OVERRIDE {
+    ExtensionApiTest::SetUpOnMainThread();
+    empty_extension_ = utils::CreateEmptyExtension();
+    SetUpMockAdapter();
+  }
+
+  virtual void CleanUpOnMainThread() OVERRIDE {
+    ExtensionApiTest::CleanUpOnMainThread();
+  }
+
+  void SetUpMockAdapter() {
+    // The browser will clean this up when it is torn down.
+    mock_adapter_ = new testing::StrictMock<MockBluetoothAdapter>();
+    BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter_);
+
+    mock_device1_.reset(new testing::NiceMock<MockBluetoothDevice>(
+        mock_adapter_, 0, "d1", "11:12:13:14:15:16",
+        true /* paired */, false /* connected */));
+    mock_device2_.reset(new testing::NiceMock<MockBluetoothDevice>(
+        mock_adapter_, 0, "d2", "21:22:23:24:25:26",
+        true /* paired */, false /* connected */));
+  }
+
+ protected:
+  scoped_refptr<testing::StrictMock<MockBluetoothAdapter> > mock_adapter_;
+  scoped_ptr<testing::NiceMock<MockBluetoothDevice> > mock_device1_;
+  scoped_ptr<testing::NiceMock<MockBluetoothDevice> > mock_device2_;
+
+ private:
+  scoped_refptr<Extension> empty_extension_;
+};
+
+// testing::InvokeArgument<N> does not work with base::Callback, fortunately
+// gmock makes it simple to create action templates that do for the various
+// possible numbers of arguments.
+ACTION_TEMPLATE(InvokeCallbackArgument,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_0_VALUE_PARAMS()) {
+  ::std::tr1::get<k>(args).Run();
+}
+
+ACTION_TEMPLATE(InvokeCallbackArgument,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_1_VALUE_PARAMS(p0)) {
+  ::std::tr1::get<k>(args).Run(p0);
+}
+
+ACTION_TEMPLATE(InvokeCallbackArgument,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_2_VALUE_PARAMS(p0, p1)) {
+  ::std::tr1::get<k>(args).Run(p0, p1);
+}
+
+}  // namespace
+
+IN_PROC_BROWSER_TEST_F(BluetoothSocketApiTest, Connect) {
+  ResultCatcher catcher;
+  catcher.RestrictToProfile(browser()->profile());
+
+  // Return the right mock device object for the address used by the test,
+  // return NULL for the "Device not found" test.
+  EXPECT_CALL(*mock_adapter_, GetDevice(mock_device1_->GetAddress()))
+      .WillRepeatedly(testing::Return(mock_device1_.get()));
+  EXPECT_CALL(*mock_adapter_, GetDevice(std::string("aa:aa:aa:aa:aa:aa")))
+      .WillOnce(testing::Return(static_cast<BluetoothDevice*>(NULL)));
+
+  // Return a mock socket object as a successful result to the connect() call.
+  BluetoothUUID service_uuid("8e3ad063-db38-4289-aa8f-b30e4223cf40");
+  scoped_refptr<testing::StrictMock<MockBluetoothSocket> > mock_socket
+      = new testing::StrictMock<MockBluetoothSocket>();
+  EXPECT_CALL(*mock_device1_,
+              ConnectToService(service_uuid, testing::_, testing::_))
+      .WillOnce(InvokeCallbackArgument<1>(mock_socket));
+
+  // Since the socket is unpaused, expect a call to Receive() from the socket
+  // dispatcher. Since there is no data, this will not call its callback.
+  EXPECT_CALL(*mock_socket, Receive(testing::_, testing::_, testing::_));
+
+  // The test also cleans up by calling Disconnect and Close.
+  EXPECT_CALL(*mock_socket, Disconnect(testing::_))
+      .WillOnce(InvokeCallbackArgument<0>());
+  EXPECT_CALL(*mock_socket, Close());
+
+  // Run the test.
+  ExtensionTestMessageListener listener("ready", true);
+  scoped_refptr<const Extension> extension(
+      LoadExtension(test_data_dir_.AppendASCII("bluetooth_socket/connect")));
+  ASSERT_TRUE(extension.get());
+  EXPECT_TRUE(listener.WaitUntilSatisfied());
+
+  listener.Reply("go");
+  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
+}
diff --git a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_event_dispatcher.cc b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_event_dispatcher.cc
index 2d7f539..ae312fc 100644
--- a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_event_dispatcher.cc
+++ b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_event_dispatcher.cc
@@ -82,11 +82,27 @@
 
 BluetoothSocketEventDispatcher::ReceiveParams::~ReceiveParams() {}
 
+void BluetoothSocketEventDispatcher::OnSocketConnect(
+    const std::string& extension_id,
+    int socket_id) {
+  DCHECK(BrowserThread::CurrentlyOn(thread_id_));
+
+  StartSocketReceive(extension_id, socket_id);
+}
+
 void BluetoothSocketEventDispatcher::OnSocketResume(
     const std::string& extension_id,
     int socket_id) {
   DCHECK(BrowserThread::CurrentlyOn(thread_id_));
 
+  StartSocketReceive(extension_id, socket_id);
+}
+
+void BluetoothSocketEventDispatcher::StartSocketReceive(
+    const std::string& extension_id,
+    int socket_id) {
+  DCHECK(BrowserThread::CurrentlyOn(thread_id_));
+
   ReceiveParams params;
   params.thread_id = thread_id_;
   params.browser_context_id = browser_context_;
diff --git a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_event_dispatcher.h b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_event_dispatcher.h
index 81fdfca..fa13597 100644
--- a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_event_dispatcher.h
+++ b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_event_dispatcher.h
@@ -30,6 +30,9 @@
   explicit BluetoothSocketEventDispatcher(content::BrowserContext* context);
   virtual ~BluetoothSocketEventDispatcher();
 
+  // Socket is active, start receiving data from it.
+  void OnSocketConnect(const std::string& extension_id, int socket_id);
+
   // Socket is active again, start receiving data from it.
   void OnSocketResume(const std::string& extension_id, int socket_id);
 
@@ -62,6 +65,7 @@
   };
 
   // Start a receive and register a callback.
+  void StartSocketReceive(const std::string& extension_id, int socket_id);
   static void StartReceive(const ReceiveParams& params);
 
   // Called when socket receive data.
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
index 91f2fa6..fab0377 100644
--- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
+++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
@@ -30,7 +30,6 @@
 #include "components/user_prefs/user_prefs.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "extensions/browser/extension_function_dispatcher.h"
 #include "extensions/browser/view_type_utils.h"
@@ -224,13 +223,15 @@
   }
 
   // Identify added fields:
-  for (BookmarkNode::MetaInfoMap::const_iterator it = new_meta_info->begin();
-       it != new_meta_info->end();
-       ++it) {
-    BookmarkNode::MetaInfoMap::const_iterator prev_meta_field =
-        prev_meta_info_.find(it->first);
-    if (prev_meta_field == prev_meta_info_.end())
-      changes.additional_properties[it->first] = it->second;
+  if (new_meta_info) {
+    for (BookmarkNode::MetaInfoMap::const_iterator it = new_meta_info->begin();
+         it != new_meta_info->end();
+         ++it) {
+      BookmarkNode::MetaInfoMap::const_iterator prev_meta_field =
+          prev_meta_info_.find(it->first);
+      if (prev_meta_field == prev_meta_info_.end())
+        changes.additional_properties[it->first] = it->second;
+    }
   }
 
   prev_meta_info_.clear();
@@ -440,7 +441,7 @@
   return true;
 }
 
-bool BookmarkManagerPrivateGetStringsFunction::RunImpl() {
+bool BookmarkManagerPrivateGetStringsFunction::RunAsync() {
   base::DictionaryValue* localized_strings = new base::DictionaryValue();
 
   localized_strings->SetString("title",
@@ -544,7 +545,7 @@
       source = ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH;
 
     chrome::DragBookmarks(
-        GetProfile(), nodes, web_contents->GetView()->GetNativeView(), source);
+        GetProfile(), nodes, web_contents->GetNativeView(), source);
 
     return true;
   } else {
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h
index e5f1007..1aed39c 100644
--- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h
+++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h
@@ -197,7 +197,7 @@
   virtual ~BookmarkManagerPrivateGetStringsFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class BookmarkManagerPrivateStartDragFunction
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc
index 726bfe1..ba2527d 100644
--- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc
+++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc
@@ -8,12 +8,12 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/pref_names.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "components/user_prefs/user_prefs.h"
 
 // Times out on win syzyasan, http://crbug.com/166026
diff --git a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc
index 966a132..df7c73e 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc
+++ b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc
@@ -7,10 +7,10 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
-#include "chrome/browser/bookmarks/test_bookmark_client.h"
 #include "chrome/browser/extensions/api/bookmarks/bookmark_api_constants.h"
 #include "chrome/common/extensions/api/bookmarks.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/test_bookmark_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace extensions {
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
index c780c18..2a736b0 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
+++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
@@ -41,7 +41,6 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_function_dispatcher.h"
 #include "extensions/browser/quota_service.h"
@@ -98,7 +97,7 @@
 
 }  // namespace
 
-bool BookmarksFunction::RunImpl() {
+bool BookmarksFunction::RunAsync() {
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(GetProfile());
   if (!model->loaded()) {
     // Bookmarks are not ready yet.  We'll wait.
@@ -282,10 +281,12 @@
                                              *tree_node));
 }
 
-void BookmarkEventRouter::BookmarkNodeRemoved(BookmarkModel* model,
-                                              const BookmarkNode* parent,
-                                              int index,
-                                              const BookmarkNode* node) {
+void BookmarkEventRouter::BookmarkNodeRemoved(
+    BookmarkModel* model,
+    const BookmarkNode* parent,
+    int index,
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {
   bookmarks::OnRemoved::RemoveInfo remove_info;
   remove_info.parent_id = base::Int64ToString(parent->id());
   remove_info.index = index;
@@ -295,7 +296,9 @@
                                              remove_info));
 }
 
-void BookmarkEventRouter::BookmarkAllNodesRemoved(BookmarkModel* model) {
+void BookmarkEventRouter::BookmarkAllNodesRemoved(
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
   NOTREACHED();
   // TODO(shashishekhar) Currently this notification is only used on Android,
   // which does not support extensions. If Desktop needs to support this, add
@@ -951,7 +954,7 @@
   file_type_info.extensions.resize(1);
   file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html"));
   gfx::NativeWindow owning_window = web_contents ?
-      platform_util::GetTopLevel(web_contents->GetView()->GetNativeView())
+      platform_util::GetTopLevel(web_contents->GetNativeView())
           : NULL;
 #if defined(OS_WIN)
   if (!owning_window &&
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.h b/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
index 60010fb..112f63e 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
+++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
@@ -57,8 +57,11 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE;
   virtual void BookmarkNodeFaviconChanged(BookmarkModel* model,
@@ -114,12 +117,12 @@
                           public BaseBookmarkModelObserver {
  public:
   // AsyncExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  protected:
   virtual ~BookmarksFunction() {}
 
-  // RunImpl semantic equivalent called when the bookmarks are ready.
+  // RunAsync semantic equivalent called when the bookmarks are ready.
   virtual bool RunOnReady() = 0;
 
   // Helper to get the bookmark id as int64 from the given string id.
diff --git a/chrome/browser/extensions/api/braille_display_private/braille_controller.h b/chrome/browser/extensions/api/braille_display_private/braille_controller.h
index ed7954d..f975fc3 100644
--- a/chrome/browser/extensions/api/braille_display_private/braille_controller.h
+++ b/chrome/browser/extensions/api/braille_display_private/braille_controller.h
@@ -39,8 +39,9 @@
 // Observer for events from the BrailleController
 class BrailleObserver {
  public:
-  virtual void OnDisplayStateChanged(const DisplayState& display_state) {}
-  virtual void OnKeyEvent(const KeyEvent& event) {}
+  virtual void OnBrailleDisplayStateChanged(
+      const DisplayState& display_state) {}
+  virtual void OnBrailleKeyEvent(const KeyEvent& event) {}
 };
 
 }  // namespace braille_display_private
diff --git a/chrome/browser/extensions/api/braille_display_private/braille_controller_brlapi.cc b/chrome/browser/extensions/api/braille_display_private/braille_controller_brlapi.cc
index 38431ad..60eaa5e 100644
--- a/chrome/browser/extensions/api/braille_display_private/braille_controller_brlapi.cc
+++ b/chrome/browser/extensions/api/braille_display_private/braille_controller_brlapi.cc
@@ -347,7 +347,7 @@
     return;
   }
   VLOG(1) << "Dispatching key event: " << *event->ToValue();
-  FOR_EACH_OBSERVER(BrailleObserver, observers_, OnKeyEvent(*event));
+  FOR_EACH_OBSERVER(BrailleObserver, observers_, OnBrailleKeyEvent(*event));
 }
 
 void BrailleControllerImpl::DispatchOnDisplayStateChanged(
@@ -363,7 +363,7 @@
     return;
   }
   FOR_EACH_OBSERVER(BrailleObserver, observers_,
-                    OnDisplayStateChanged(*new_state));
+                    OnBrailleDisplayStateChanged(*new_state));
 }
 
 }  // namespace braille_display_private
diff --git a/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.cc b/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.cc
index 5cbcb34..8c0fa61 100644
--- a/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.cc
+++ b/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.cc
@@ -60,7 +60,7 @@
   return g_factory.Pointer();
 }
 
-void BrailleDisplayPrivateAPI::OnDisplayStateChanged(
+void BrailleDisplayPrivateAPI::OnBrailleDisplayStateChanged(
     const DisplayState& display_state) {
   scoped_ptr<Event> event(new Event(
       OnDisplayStateChanged::kEventName,
@@ -68,8 +68,7 @@
   event_delegate_->BroadcastEvent(event.Pass());
 }
 
-void BrailleDisplayPrivateAPI::OnKeyEvent(
-    const KeyEvent& key_event) {
+void BrailleDisplayPrivateAPI::OnBrailleKeyEvent(const KeyEvent& key_event) {
   // Key events only go to extensions of the active profile.
   if (!IsProfileActive())
     return;
diff --git a/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.h b/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.h
index 3fe1ba2..6c049d6 100644
--- a/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.h
+++ b/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.h
@@ -37,9 +37,9 @@
       GetFactoryInstance();
 
   // BrailleObserver implementation.
-  virtual void OnDisplayStateChanged(
+  virtual void OnBrailleDisplayStateChanged(
       const api::braille_display_private::DisplayState& display_state) OVERRIDE;
-  virtual void OnKeyEvent(
+  virtual void OnBrailleKeyEvent(
       const api::braille_display_private::KeyEvent& keyEvent) OVERRIDE;
 
   // EventRouter::Observer implementation.
diff --git a/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc b/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc
index c28feb6..d212b77 100644
--- a/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc
+++ b/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc
@@ -304,23 +304,23 @@
   // Send key event to both profiles.
   KeyEvent key_event;
   key_event.command = KEY_COMMAND_LINE_UP;
-  signin_api.OnKeyEvent(key_event);
-  user_api.OnKeyEvent(key_event);
+  signin_api.OnBrailleKeyEvent(key_event);
+  user_api.OnBrailleKeyEvent(key_event);
   EXPECT_EQ(0, signin_delegate->GetEventCount());
   EXPECT_EQ(1, user_delegate->GetEventCount());
 
   // Lock screen, and make sure that the key event goes to the
   // signin profile.
   LockScreen(tester.get());
-  signin_api.OnKeyEvent(key_event);
-  user_api.OnKeyEvent(key_event);
+  signin_api.OnBrailleKeyEvent(key_event);
+  user_api.OnBrailleKeyEvent(key_event);
   EXPECT_EQ(1, signin_delegate->GetEventCount());
   EXPECT_EQ(1, user_delegate->GetEventCount());
 
   // Unlock screen, making sur ekey events go to the user profile again.
   DismissLockScreen(tester.get());
-  signin_api.OnKeyEvent(key_event);
-  user_api.OnKeyEvent(key_event);
+  signin_api.OnBrailleKeyEvent(key_event);
+  user_api.OnBrailleKeyEvent(key_event);
   EXPECT_EQ(1, signin_delegate->GetEventCount());
   EXPECT_EQ(2, user_delegate->GetEventCount());
 }
diff --git a/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc b/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc
index 987f4b5..59b29b8 100644
--- a/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc
+++ b/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc
@@ -121,7 +121,10 @@
   }
 
   const brlapi_keyCode_t extraKeys[] = {
-    BRLAPI_KEY_TYPE_CMD | BRLAPI_KEY_CMD_OFFLINE,
+      BRLAPI_KEY_TYPE_CMD | BRLAPI_KEY_CMD_OFFLINE,
+      // brltty 5.1 converts dot input to Unicode characters unless we
+      // explicitly accept this command.
+      BRLAPI_KEY_TYPE_CMD | BRLAPI_KEY_CMD_PASSDOTS,
   };
   if (libbrlapi_loader_->brlapi__acceptKeys(
           handle_.get(), brlapi_rangeType_command, extraKeys,
diff --git a/chrome/browser/extensions/api/browser/browser_api.cc b/chrome/browser/extensions/api/browser/browser_api.cc
new file mode 100644
index 0000000..7e1a64b
--- /dev/null
+++ b/chrome/browser/extensions/api/browser/browser_api.cc
@@ -0,0 +1,36 @@
+// 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.
+
+#include "chrome/browser/extensions/api/browser/browser_api.h"
+
+#include "chrome/browser/extensions/extension_tab_util.h"
+
+namespace extensions {
+namespace api {
+
+BrowserOpenTabFunction::~BrowserOpenTabFunction() {
+}
+
+bool BrowserOpenTabFunction::RunSync() {
+  scoped_ptr<browser::OpenTab::Params> params(
+      browser::OpenTab::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+
+  ExtensionTabUtil::OpenTabParams options;
+  options.create_browser_if_needed = true;
+  options.url.reset(new std::string(params->options.url));
+
+  std::string error;
+  scoped_ptr<base::DictionaryValue> result(
+      ExtensionTabUtil::OpenTab(this, options, &error));
+  if (!result) {
+    SetError(error);
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace api
+}  // namespace extensions
diff --git a/chrome/browser/extensions/api/browser/browser_api.h b/chrome/browser/extensions/api/browser/browser_api.h
new file mode 100644
index 0000000..5707857
--- /dev/null
+++ b/chrome/browser/extensions/api/browser/browser_api.h
@@ -0,0 +1,27 @@
+// 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_BROWSER_BROWSER_API_H_
+#define CHROME_BROWSER_EXTENSIONS_API_BROWSER_BROWSER_API_H_
+
+#include "chrome/browser/extensions/chrome_extension_function.h"
+#include "chrome/common/extensions/api/browser.h"
+
+namespace extensions {
+namespace api {
+
+class BrowserOpenTabFunction : public ChromeSyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("browser.openTab", BROWSER_OPENTAB)
+
+ protected:
+  virtual ~BrowserOpenTabFunction();
+
+  virtual bool RunSync() OVERRIDE;
+};
+
+}  // namespace api
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_API_BROWSER_BROWSER_API_H_
diff --git a/chrome/browser/extensions/api/browser/browser_apitest.cc b/chrome/browser/extensions/api/browser/browser_apitest.cc
new file mode 100644
index 0000000..88754b8
--- /dev/null
+++ b/chrome/browser/extensions/api/browser/browser_apitest.cc
@@ -0,0 +1,41 @@
+// 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.
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/stringprintf.h"
+#include "base/values.h"
+#include "chrome/browser/extensions/api/browser/browser_api.h"
+#include "chrome/browser/extensions/extension_function_test_utils.h"
+#include "chrome/test/base/in_process_browser_test.h"
+
+namespace extensions {
+
+namespace utils = extension_function_test_utils;
+
+namespace {
+
+class BrowserApiTest : public InProcessBrowserTest {
+};
+
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserApiTest, OpenTab) {
+  std::string url = "about:blank";
+
+  scoped_refptr<api::BrowserOpenTabFunction> function =
+      new api::BrowserOpenTabFunction();
+  scoped_refptr<Extension> extension(utils::CreateEmptyExtension());
+  function->set_extension(extension.get());
+  base::Value* result = utils::RunFunctionAndReturnSingleResult(
+      function.get(),
+      base::StringPrintf("[{\"url\":\"%s\"}]", url.c_str()),
+      browser());
+
+  // result is currently NULL on success.
+  EXPECT_FALSE(result);
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc
index 3c881d3..b6987ae 100644
--- a/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc
+++ b/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc
@@ -220,10 +220,10 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   this->SendResponse(true);
 
-  Release();  // Balanced in RunImpl.
+  Release();  // Balanced in RunAsync.
 }
 
-bool BrowsingDataRemoverFunction::RunImpl() {
+bool BrowsingDataRemoverFunction::RunAsync() {
   // If we don't have a profile, something's pretty wrong.
   DCHECK(GetProfile());
 
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_api.h b/chrome/browser/extensions/api/browsing_data/browsing_data_api.h
index 9a5c814..42d1cad 100644
--- a/chrome/browser/extensions/api/browsing_data/browsing_data_api.h
+++ b/chrome/browser/extensions/api/browsing_data/browsing_data_api.h
@@ -86,7 +86,7 @@
   virtual void OnBrowsingDataRemoverDone() OVERRIDE;
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  protected:
   virtual ~BrowsingDataRemoverFunction() {}
diff --git a/chrome/browser/extensions/api/capture_web_contents_function.cc b/chrome/browser/extensions/api/capture_web_contents_function.cc
index 6590856..ae2bdbb 100644
--- a/chrome/browser/extensions/api/capture_web_contents_function.cc
+++ b/chrome/browser/extensions/api/capture_web_contents_function.cc
@@ -32,7 +32,7 @@
   return true;
 }
 
-bool CaptureWebContentsFunction::RunImpl() {
+bool CaptureWebContentsFunction::RunAsync() {
   EXTENSION_FUNCTION_VALIDATE(args_);
 
   context_id_ = extension_misc::kCurrentWindowId;
diff --git a/chrome/browser/extensions/api/capture_web_contents_function.h b/chrome/browser/extensions/api/capture_web_contents_function.h
index 1e3a85f..0a1c741 100644
--- a/chrome/browser/extensions/api/capture_web_contents_function.h
+++ b/chrome/browser/extensions/api/capture_web_contents_function.h
@@ -27,7 +27,7 @@
 
   // ExtensionFunction implementation.
   virtual bool HasPermission() OVERRIDE;
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   virtual bool IsScreenshotEnabled() = 0;
   virtual content::WebContents* GetWebContentsForID(int context_id) = 0;
@@ -51,10 +51,10 @@
   // the guest.
   int context_id_;
 
-  // The format (JPEG vs PNG) of the resulting image.  Set in RunImpl().
+  // The format (JPEG vs PNG) of the resulting image.  Set in RunAsync().
   ImageDetails::Format image_format_;
 
-  // Quality setting to use when encoding jpegs.  Set in RunImpl().
+  // Quality setting to use when encoding jpegs.  Set in RunAsync().
   int image_quality_;
 
   DISALLOW_COPY_AND_ASSIGN(CaptureWebContentsFunction);
diff --git a/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.cc b/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.cc
index 4c5f73e..e094f7a 100644
--- a/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.cc
+++ b/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.cc
@@ -37,8 +37,7 @@
     ~CloudPrintPrivateSetupConnectorFunction() {
 }
 
-
-bool CloudPrintPrivateSetupConnectorFunction::RunImpl() {
+bool CloudPrintPrivateSetupConnectorFunction::RunAsync() {
 #if defined(ENABLE_FULL_PRINTING)
   using api::cloud_print_private::SetupConnector::Params;
   scoped_ptr<Params> params(Params::Create(*args_));
@@ -73,7 +72,7 @@
 CloudPrintPrivateGetHostNameFunction::~CloudPrintPrivateGetHostNameFunction() {
 }
 
-bool CloudPrintPrivateGetHostNameFunction::RunImpl() {
+bool CloudPrintPrivateGetHostNameFunction::RunAsync() {
   SetResult(new base::StringValue(
       CloudPrintTestsDelegate::instance() ?
       CloudPrintTestsDelegate::instance()->GetHostName() :
@@ -94,7 +93,7 @@
   SendResponse(true);
 }
 
-bool CloudPrintPrivateGetPrintersFunction::RunImpl() {
+bool CloudPrintPrivateGetPrintersFunction::RunAsync() {
 #if defined(ENABLE_FULL_PRINTING)
   std::vector<std::string> result;
   if (CloudPrintTestsDelegate::instance()) {
@@ -120,7 +119,7 @@
 CloudPrintPrivateGetClientIdFunction::~CloudPrintPrivateGetClientIdFunction() {
 }
 
-bool CloudPrintPrivateGetClientIdFunction::RunImpl() {
+bool CloudPrintPrivateGetClientIdFunction::RunAsync() {
   SetResult(new base::StringValue(
       CloudPrintTestsDelegate::instance() ?
       CloudPrintTestsDelegate::instance()->GetClientId() :
diff --git a/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.h b/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.h
index 8f1cc32..4585014 100644
--- a/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.h
+++ b/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.h
@@ -58,7 +58,7 @@
   virtual ~CloudPrintPrivateSetupConnectorFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class CloudPrintPrivateGetHostNameFunction
@@ -73,7 +73,7 @@
   virtual ~CloudPrintPrivateGetHostNameFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class CloudPrintPrivateGetPrintersFunction
@@ -91,7 +91,7 @@
   void SendResults(const std::vector<std::string>& printers);
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class CloudPrintPrivateGetClientIdFunction
@@ -106,7 +106,7 @@
   virtual ~CloudPrintPrivateGetClientIdFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_api.cc b/chrome/browser/extensions/api/content_settings/content_settings_api.cc
index 976b632..99f7fc0 100644
--- a/chrome/browser/extensions/api/content_settings/content_settings_api.cc
+++ b/chrome/browser/extensions/api/content_settings/content_settings_api.cc
@@ -246,7 +246,7 @@
   return true;
 }
 
-bool ContentSettingsContentSettingGetResourceIdentifiersFunction::RunImpl() {
+bool ContentSettingsContentSettingGetResourceIdentifiersFunction::RunAsync() {
   ContentSettingsType content_type;
   EXTENSION_FUNCTION_VALIDATE(RemoveContentType(args_.get(), &content_type));
 
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_api.h b/chrome/browser/extensions/api/content_settings/content_settings_api.h
index cd18443..a138cf3 100644
--- a/chrome/browser/extensions/api/content_settings/content_settings_api.h
+++ b/chrome/browser/extensions/api/content_settings/content_settings_api.h
@@ -61,7 +61,7 @@
   virtual ~ContentSettingsContentSettingGetResourceIdentifiersFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(ExtensionApiTest,
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_helpers.cc b/chrome/browser/extensions/api/content_settings/content_settings_helpers.cc
index 29af76e..6601abd 100644
--- a/chrome/browser/extensions/api/content_settings/content_settings_helpers.cc
+++ b/chrome/browser/extensions/api/content_settings/content_settings_helpers.cc
@@ -43,9 +43,9 @@
 
 // TODO(bauerb): Move this someplace where it can be reused.
 std::string GetDefaultPort(const std::string& scheme) {
-  if (scheme == content::kHttpScheme)
+  if (scheme == url::kHttpScheme)
     return "80";
-  if (scheme == content::kHttpsScheme)
+  if (scheme == url::kHttpsScheme)
     return "443";
   NOTREACHED();
   return std::string();
diff --git a/chrome/browser/extensions/api/cookies/cookies_api.cc b/chrome/browser/extensions/api/cookies/cookies_api.cc
index 2de26a1..ed95507 100644
--- a/chrome/browser/extensions/api/cookies/cookies_api.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_api.cc
@@ -205,7 +205,7 @@
 CookiesGetFunction::~CookiesGetFunction() {
 }
 
-bool CookiesGetFunction::RunImpl() {
+bool CookiesGetFunction::RunAsync() {
   parsed_args_ = Get::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
 
@@ -278,7 +278,7 @@
 CookiesGetAllFunction::~CookiesGetAllFunction() {
 }
 
-bool CookiesGetAllFunction::RunImpl() {
+bool CookiesGetAllFunction::RunAsync() {
   parsed_args_ = GetAll::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
 
@@ -343,7 +343,7 @@
 CookiesSetFunction::~CookiesSetFunction() {
 }
 
-bool CookiesSetFunction::RunImpl() {
+bool CookiesSetFunction::RunAsync() {
   parsed_args_ = Set::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
 
@@ -458,7 +458,7 @@
 CookiesRemoveFunction::~CookiesRemoveFunction() {
 }
 
-bool CookiesRemoveFunction::RunImpl() {
+bool CookiesRemoveFunction::RunAsync() {
   parsed_args_ = Remove::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
 
diff --git a/chrome/browser/extensions/api/cookies/cookies_api.h b/chrome/browser/extensions/api/cookies/cookies_api.h
index 1389ffc..a7a0876 100644
--- a/chrome/browser/extensions/api/cookies/cookies_api.h
+++ b/chrome/browser/extensions/api/cookies/cookies_api.h
@@ -71,7 +71,7 @@
   virtual ~CookiesGetFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void GetCookieOnIOThread();
@@ -94,7 +94,7 @@
   virtual ~CookiesGetAllFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void GetAllCookiesOnIOThread();
@@ -115,7 +115,7 @@
 
  protected:
   virtual ~CookiesSetFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void SetCookieOnIOThread();
@@ -140,7 +140,7 @@
   virtual ~CookiesRemoveFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void RemoveCookieOnIOThread();
diff --git a/chrome/browser/extensions/api/cookies/cookies_helpers.cc b/chrome/browser/extensions/api/cookies/cookies_helpers.cc
index 750bd1e..7044bfe 100644
--- a/chrome/browser/extensions/api/cookies/cookies_helpers.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_helpers.cc
@@ -76,8 +76,8 @@
   cookie->host_only = net::cookie_util::DomainIsHostOnly(
       canonical_cookie.Domain());
   // A non-UTF8 path is invalid, so we just replace it with an empty string.
-  cookie->path = IsStringUTF8(canonical_cookie.Path()) ? canonical_cookie.Path()
-                                                       : std::string();
+  cookie->path = base::IsStringUTF8(canonical_cookie.Path()) ?
+      canonical_cookie.Path() : std::string();
   cookie->secure = canonical_cookie.IsSecure();
   cookie->http_only = canonical_cookie.IsHttpOnly();
   cookie->session = !canonical_cookie.IsPersistent();
@@ -120,7 +120,7 @@
 GURL GetURLFromCanonicalCookie(const net::CanonicalCookie& cookie) {
   const std::string& domain_key = cookie.Domain();
   const std::string scheme =
-      cookie.IsSecure() ? content::kHttpsScheme : content::kHttpScheme;
+      cookie.IsSecure() ? url::kHttpsScheme : url::kHttpScheme;
   const std::string host =
       domain_key.find('.') != 0 ? domain_key : domain_key.substr(1);
   return GURL(scheme + content::kStandardSchemeSeparator + host + "/");
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc
index 35c0215..31db514 100644
--- a/chrome/browser/extensions/api/debugger/debugger_api.cc
+++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -14,6 +14,7 @@
 #include "base/json/json_writer.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/singleton.h"
+#include "base/scoped_observer.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -43,6 +44,8 @@
 #include "content/public/common/url_utils.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_host.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_registry_observer.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/common/error_utils.h"
 #include "extensions/common/extension.h"
@@ -57,7 +60,6 @@
 using content::RenderViewHost;
 using content::RenderWidgetHost;
 using content::WebContents;
-using extensions::ErrorUtils;
 
 namespace keys = debugger_api_constants;
 namespace Attach = extensions::api::debugger::Attach;
@@ -66,11 +68,14 @@
 namespace OnEvent = extensions::api::debugger::OnEvent;
 namespace SendCommand = extensions::api::debugger::SendCommand;
 
+namespace extensions {
+class ExtensionRegistry;
 
 // ExtensionDevToolsClientHost ------------------------------------------------
 
 class ExtensionDevToolsClientHost : public DevToolsClientHost,
-                                    public content::NotificationObserver {
+                                    public content::NotificationObserver,
+                                    public ExtensionRegistryObserver {
  public:
   ExtensionDevToolsClientHost(Profile* profile,
                               DevToolsAgentHost* agent_host,
@@ -103,6 +108,12 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
+  // ExtensionRegistryObserver implementation.
+  virtual void OnExtensionUnloaded(
+      content::BrowserContext* browser_context,
+      const Extension* extension,
+      UnloadedExtensionInfo::Reason reason) OVERRIDE;
+
   Profile* profile_;
   scoped_refptr<DevToolsAgentHost> agent_host_;
   std::string extension_id_;
@@ -115,6 +126,10 @@
   infobars::InfoBar* infobar_;
   OnDetach::Reason detach_reason_;
 
+  // Listen to extension unloaded notification.
+  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
+      extension_registry_observer_;
+
   DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsClientHost);
 };
 
@@ -302,14 +317,15 @@
       extension_id_(extension_id),
       last_request_id_(0),
       infobar_(infobar),
-      detach_reason_(OnDetach::REASON_TARGET_CLOSED) {
+      detach_reason_(OnDetach::REASON_TARGET_CLOSED),
+      extension_registry_observer_(this) {
   CopyDebuggee(&debuggee_, debuggee);
 
   AttachedClientHosts::GetInstance()->Add(this);
 
-  // Detach from debugger when extension unloads.
-  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
-                 content::Source<Profile>(profile_));
+  // ExtensionRegistryObserver listen extension unloaded and detach debugger
+  // from there.
+  extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
 
   // RVH-based agents disconnect from their clients when the app is terminating
   // but shared worker-based agents do not.
@@ -386,42 +402,49 @@
 }
 
 void ExtensionDevToolsClientHost::SendDetachedEvent() {
-  if (!extensions::EventRouter::Get(profile_))
+  if (!EventRouter::Get(profile_))
     return;
 
   scoped_ptr<base::ListValue> args(OnDetach::Create(debuggee_,
                                                     detach_reason_));
-  scoped_ptr<extensions::Event> event(new extensions::Event(
-      OnDetach::kEventName, args.Pass()));
+  scoped_ptr<Event> event(new Event(OnDetach::kEventName, args.Pass()));
   event->restrict_to_browser_context = profile_;
-  extensions::EventRouter::Get(profile_)
+  EventRouter::Get(profile_)
       ->DispatchEventToExtension(extension_id_, event.Pass());
 }
 
+void ExtensionDevToolsClientHost::OnExtensionUnloaded(
+    content::BrowserContext* browser_context,
+    const Extension* extension,
+    UnloadedExtensionInfo::Reason reason) {
+  if (extension->id() == extension_id_)
+    Close();
+}
+
 void ExtensionDevToolsClientHost::Observe(
     int type,
     const content::NotificationSource& source,
     const content::NotificationDetails& details) {
-  if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED) {
-    if (content::Details<extensions::UnloadedExtensionInfo>(details)->
-        extension->id() == extension_id_)
+  switch (type) {
+    case chrome::NOTIFICATION_APP_TERMINATING:
       Close();
-  } else if (type == chrome::NOTIFICATION_APP_TERMINATING) {
-    Close();
-  } else {
-    DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
-    if (content::Details<infobars::InfoBar::RemovedDetails>(details)->first ==
-        infobar_) {
-      infobar_ = NULL;
-      SendDetachedEvent();
-      Close();
-    }
+      break;
+    case chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED:
+      if (content::Details<infobars::InfoBar::RemovedDetails>(details)->first ==
+          infobar_) {
+        infobar_ = NULL;
+        SendDetachedEvent();
+        Close();
+      }
+      break;
+    default:
+      NOTREACHED();
   }
 }
 
 void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend(
     const std::string& message) {
-  if (!extensions::EventRouter::Get(profile_))
+  if (!EventRouter::Get(profile_))
     return;
 
   scoped_ptr<base::Value> result(base::JSONReader::Read(message));
@@ -443,10 +466,9 @@
 
     scoped_ptr<base::ListValue> args(
         OnEvent::Create(debuggee_, method_name, params));
-    scoped_ptr<extensions::Event> event(new extensions::Event(
-        OnEvent::kEventName, args.Pass()));
+    scoped_ptr<Event> event(new Event(OnEvent::kEventName, args.Pass()));
     event->restrict_to_browser_context = profile_;
-    extensions::EventRouter::Get(profile_)
+    EventRouter::Get(profile_)
         ->DispatchEventToExtension(extension_id_, event.Pass());
   } else {
     DebuggerSendCommandFunction* function = pending_requests_[id].get();
@@ -483,13 +505,13 @@
 bool DebuggerFunction::InitAgentHost() {
   if (debuggee_.tab_id) {
     WebContents* web_contents = NULL;
-    bool result = extensions::ExtensionTabUtil::GetTabById(*debuggee_.tab_id,
-                                                           GetProfile(),
-                                                           include_incognito(),
-                                                           NULL,
-                                                           NULL,
-                                                           &web_contents,
-                                                           NULL);
+    bool result = ExtensionTabUtil::GetTabById(*debuggee_.tab_id,
+                                               GetProfile(),
+                                               include_incognito(),
+                                               NULL,
+                                               NULL,
+                                               &web_contents,
+                                               NULL);
     if (result && web_contents) {
       if (content::HasWebUIScheme(web_contents->GetURL())) {
         error_ = ErrorUtils::FormatErrorMessage(
@@ -500,8 +522,8 @@
       agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents);
     }
   } else if (debuggee_.extension_id) {
-    extensions::ExtensionHost* extension_host =
-        extensions::ExtensionSystem::Get(GetProfile())
+    ExtensionHost* extension_host =
+        ExtensionSystem::Get(GetProfile())
             ->process_manager()
             ->GetBackgroundHostForExtension(*debuggee_.extension_id);
     if (extension_host) {
@@ -545,7 +567,7 @@
 DebuggerAttachFunction::~DebuggerAttachFunction() {
 }
 
-bool DebuggerAttachFunction::RunImpl() {
+bool DebuggerAttachFunction::RunAsync() {
   scoped_ptr<Attach::Params> params(Attach::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -600,7 +622,7 @@
 DebuggerDetachFunction::~DebuggerDetachFunction() {
 }
 
-bool DebuggerDetachFunction::RunImpl() {
+bool DebuggerDetachFunction::RunAsync() {
   scoped_ptr<Detach::Params> params(Detach::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -622,7 +644,7 @@
 DebuggerSendCommandFunction::~DebuggerSendCommandFunction() {
 }
 
-bool DebuggerSendCommandFunction::RunImpl() {
+bool DebuggerSendCommandFunction::RunAsync() {
   scoped_ptr<SendCommand::Params> params(SendCommand::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -677,7 +699,7 @@
   dictionary->SetString(kTargetIdField, target.GetId());
   dictionary->SetString(kTargetTitleField, target.GetTitle());
   dictionary->SetBoolean(kTargetAttachedField, target.IsAttached());
-  dictionary->SetString(kTargetUrlField, target.GetUrl().spec());
+  dictionary->SetString(kTargetUrlField, target.GetURL().spec());
 
   std::string type = target.GetType();
   if (type == kTargetTypePage) {
@@ -690,14 +712,14 @@
   }
   dictionary->SetString(kTargetTypeField, type);
 
-  GURL favicon_url = target.GetFaviconUrl();
+  GURL favicon_url = target.GetFaviconURL();
   if (favicon_url.is_valid())
     dictionary->SetString(kTargetFaviconUrlField, favicon_url.spec());
 
   return dictionary;
 }
 
-} // namespace
+}  // namespace
 
 DebuggerGetTargetsFunction::DebuggerGetTargetsFunction() {
 }
@@ -705,7 +727,7 @@
 DebuggerGetTargetsFunction::~DebuggerGetTargetsFunction() {
 }
 
-bool DebuggerGetTargetsFunction::RunImpl() {
+bool DebuggerGetTargetsFunction::RunAsync() {
   DevToolsTargetImpl::EnumerateAllTargets(
       base::Bind(&DebuggerGetTargetsFunction::SendTargetList, this));
   return true;
@@ -720,3 +742,5 @@
   SetResult(result.release());
   SendResponse(true);
 }
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.h b/chrome/browser/extensions/api/debugger/debugger_api.h
index e8a1048..52120c8 100644
--- a/chrome/browser/extensions/api/debugger/debugger_api.h
+++ b/chrome/browser/extensions/api/debugger/debugger_api.h
@@ -18,7 +18,6 @@
 
 // Base debugger function.
 
-class ExtensionDevToolsClientHost;
 class DevToolsTargetImpl;
 
 namespace base {
@@ -30,6 +29,9 @@
 class WebContents;
 }
 
+namespace extensions {
+class ExtensionDevToolsClientHost;
+
 class DebuggerFunction : public ChromeAsyncExtensionFunction {
  protected:
   DebuggerFunction();
@@ -56,7 +58,7 @@
   virtual ~DebuggerAttachFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 // Implements the debugger.detach() extension function.
@@ -70,7 +72,7 @@
   virtual ~DebuggerDetachFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 // Implements the debugger.sendCommand() extension function.
@@ -85,7 +87,7 @@
   virtual ~DebuggerSendCommandFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 // Implements the debugger.getTargets() extension function.
@@ -99,10 +101,12 @@
   virtual ~DebuggerGetTargetsFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void SendTargetList(const std::vector<DevToolsTargetImpl*>& target_list);
 };
 
+}  // namespace extensions
+
 #endif  // CHROME_BROWSER_EXTENSIONS_API_DEBUGGER_DEBUGGER_API_H_
diff --git a/chrome/browser/extensions/api/declarative/declarative_api.cc b/chrome/browser/extensions/api/declarative/declarative_api.cc
index 7a644c2..dbb22a6 100644
--- a/chrome/browser/extensions/api/declarative/declarative_api.cc
+++ b/chrome/browser/extensions/api/declarative/declarative_api.cc
@@ -68,7 +68,7 @@
   return availability.is_available();
 }
 
-bool RulesFunction::RunImpl() {
+bool RulesFunction::RunAsync() {
   std::string event_name;
   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name));
 
@@ -93,7 +93,7 @@
   EXTENSION_FUNCTION_VALIDATE(rules_registry_.get());
 
   if (content::BrowserThread::CurrentlyOn(rules_registry_->owner_thread())) {
-    bool success = RunImplOnCorrectThread();
+    bool success = RunAsyncOnCorrectThread();
     SendResponse(success);
   } else {
     scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
@@ -102,14 +102,14 @@
     base::PostTaskAndReplyWithResult(
         message_loop_proxy.get(),
         FROM_HERE,
-        base::Bind(&RulesFunction::RunImplOnCorrectThread, this),
+        base::Bind(&RulesFunction::RunAsyncOnCorrectThread, this),
         base::Bind(&RulesFunction::SendResponse, this));
   }
 
   return true;
 }
 
-bool EventsEventAddRulesFunction::RunImplOnCorrectThread() {
+bool EventsEventAddRulesFunction::RunAsyncOnCorrectThread() {
   scoped_ptr<AddRules::Params> params(AddRules::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -121,7 +121,7 @@
   return error_.empty();
 }
 
-bool EventsEventRemoveRulesFunction::RunImplOnCorrectThread() {
+bool EventsEventRemoveRulesFunction::RunAsyncOnCorrectThread() {
   scoped_ptr<RemoveRules::Params> params(RemoveRules::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -135,7 +135,7 @@
   return error_.empty();
 }
 
-bool EventsEventGetRulesFunction::RunImplOnCorrectThread() {
+bool EventsEventGetRulesFunction::RunAsyncOnCorrectThread() {
   scoped_ptr<GetRules::Params> params(GetRules::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
diff --git a/chrome/browser/extensions/api/declarative/declarative_api.h b/chrome/browser/extensions/api/declarative/declarative_api.h
index f740a3e..502e2fa 100644
--- a/chrome/browser/extensions/api/declarative/declarative_api.h
+++ b/chrome/browser/extensions/api/declarative/declarative_api.h
@@ -21,12 +21,12 @@
 
   // ExtensionFunction:
   virtual bool HasPermission() OVERRIDE;
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Concrete implementation of the RulesFunction that is being called
   // on the thread on which the respective RulesRegistry lives.
   // Returns false in case of errors.
-  virtual bool RunImplOnCorrectThread() = 0;
+  virtual bool RunAsyncOnCorrectThread() = 0;
 
   scoped_refptr<RulesRegistry> rules_registry_;
 };
@@ -39,7 +39,7 @@
   virtual ~EventsEventAddRulesFunction() {}
 
   // RulesFunction:
-  virtual bool RunImplOnCorrectThread() OVERRIDE;
+  virtual bool RunAsyncOnCorrectThread() OVERRIDE;
 };
 
 class EventsEventRemoveRulesFunction : public RulesFunction {
@@ -50,7 +50,7 @@
   virtual ~EventsEventRemoveRulesFunction() {}
 
   // RulesFunction:
-  virtual bool RunImplOnCorrectThread() OVERRIDE;
+  virtual bool RunAsyncOnCorrectThread() OVERRIDE;
 };
 
 class EventsEventGetRulesFunction : public RulesFunction {
@@ -61,7 +61,7 @@
   virtual ~EventsEventGetRulesFunction() {}
 
   // RulesFunction:
-  virtual bool RunImplOnCorrectThread() OVERRIDE;
+  virtual bool RunAsyncOnCorrectThread() OVERRIDE;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc
index 42cff1f..57d1133 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.cc
@@ -18,7 +18,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "net/base/net_util.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
@@ -76,7 +75,7 @@
   }
 }
 
-bool DesktopCaptureChooseDesktopMediaFunction::RunImpl() {
+bool DesktopCaptureChooseDesktopMediaFunction::RunAsync() {
   EXTENSION_FUNCTION_VALIDATE(args_->GetSize() > 0);
 
   EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &request_id_));
@@ -131,13 +130,13 @@
     Observe(web_contents);
 
     render_view = web_contents->GetRenderViewHost();
-    parent_window = web_contents->GetView()->GetTopLevelNativeWindow();
+    parent_window = web_contents->GetTopLevelNativeWindow();
   } else {
     origin_ = GetExtension()->url();
     target_name = base::UTF8ToUTF16(GetExtension()->name());
     render_view = render_view_host();
     parent_window =
-        GetAssociatedWebContents()->GetView()->GetTopLevelNativeWindow();
+        GetAssociatedWebContents()->GetTopLevelNativeWindow();
   }
   render_process_id_ = render_view->GetProcess()->GetID();
   render_view_id_ = render_view->GetRoutingID();
@@ -216,8 +215,7 @@
   return true;
 }
 
-void DesktopCaptureChooseDesktopMediaFunction::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void DesktopCaptureChooseDesktopMediaFunction::WebContentsDestroyed() {
   Cancel();
 }
 
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h
index dd62c98..7c3af4b 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_api.h
@@ -49,11 +49,10 @@
   virtual ~DesktopCaptureChooseDesktopMediaFunction();
 
   // ExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // content::WebContentsObserver overrides.
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   void OnPickerDialogResults(content::DesktopMediaID source);
 
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
index 5f9ce42..4ff758d 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -95,7 +95,7 @@
     return profile->GetExtensionService()->updater();
 }
 
-GURL GetImageURLFromData(std::string contents) {
+GURL GetImageURLFromData(const std::string& contents) {
   std::string contents_base64;
   base::Base64Encode(contents, &contents_base64);
 
@@ -595,7 +595,7 @@
   return result;
 }
 
-bool DeveloperPrivateGetItemsInfoFunction::RunImpl() {
+bool DeveloperPrivateGetItemsInfoFunction::RunAsync() {
   scoped_ptr<developer::GetItemsInfo::Params> params(
       developer::GetItemsInfo::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
@@ -834,7 +834,7 @@
 }
 
 void DeveloperPrivateEnableFunction::OnRequirementsChecked(
-    std::string extension_id,
+    const std::string& extension_id,
     std::vector<std::string> requirements_errors) {
   if (requirements_errors.empty()) {
     ExtensionService* service = GetProfile()->GetExtensionService();
@@ -889,7 +889,7 @@
 
 DeveloperPrivateInspectFunction::~DeveloperPrivateInspectFunction() {}
 
-bool DeveloperPrivateLoadUnpackedFunction::RunImpl() {
+bool DeveloperPrivateLoadUnpackedFunction::RunAsync() {
   base::string16 select_title =
       l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY);
 
@@ -946,7 +946,9 @@
   return true;
 }
 
-bool DeveloperPrivateChooseEntryFunction::RunImpl() { return false; }
+bool DeveloperPrivateChooseEntryFunction::RunAsync() {
+  return false;
+}
 
 DeveloperPrivateChooseEntryFunction::~DeveloperPrivateChooseEntryFunction() {}
 
@@ -980,7 +982,7 @@
   Release();
 }
 
-bool DeveloperPrivatePackDirectoryFunction::RunImpl() {
+bool DeveloperPrivatePackDirectoryFunction::RunAsync() {
   scoped_ptr<PackDirectory::Params> params(
       PackDirectory::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -1034,7 +1036,7 @@
 
 DeveloperPrivateLoadUnpackedFunction::~DeveloperPrivateLoadUnpackedFunction() {}
 
-bool DeveloperPrivateLoadDirectoryFunction::RunImpl() {
+bool DeveloperPrivateLoadDirectoryFunction::RunAsync() {
   // TODO(grv) : add unittests.
   std::string directory_url_str;
   std::string filesystem_name;
@@ -1241,7 +1243,7 @@
 DeveloperPrivateLoadDirectoryFunction::~DeveloperPrivateLoadDirectoryFunction()
     {}
 
-bool DeveloperPrivateChoosePathFunction::RunImpl() {
+bool DeveloperPrivateChoosePathFunction::RunAsync() {
   scoped_ptr<developer::ChoosePath::Params> params(
       developer::ChoosePath::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
@@ -1310,7 +1312,7 @@
 DeveloperPrivateRequestFileSourceFunction::
     ~DeveloperPrivateRequestFileSourceFunction() {}
 
-bool DeveloperPrivateRequestFileSourceFunction::RunImpl() {
+bool DeveloperPrivateRequestFileSourceFunction::RunAsync() {
   scoped_ptr<developer::RequestFileSource::Params> params(
       developer::RequestFileSource::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
@@ -1334,13 +1336,13 @@
     const base::DictionaryValue& results) {
   SetResult(results.DeepCopy());
   SendResponse(true);
-  Release();  // Balanced in RunImpl().
+  Release();  // Balanced in RunAsync().
 }
 
 DeveloperPrivateOpenDevToolsFunction::DeveloperPrivateOpenDevToolsFunction() {}
 DeveloperPrivateOpenDevToolsFunction::~DeveloperPrivateOpenDevToolsFunction() {}
 
-bool DeveloperPrivateOpenDevToolsFunction::RunImpl() {
+bool DeveloperPrivateOpenDevToolsFunction::RunAsync() {
   scoped_ptr<developer::OpenDevTools::Params> params(
       developer::OpenDevTools::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.h b/chrome/browser/extensions/api/developer_private/developer_private_api.h
index 41ce8e4..20792a4 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.h
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.h
@@ -162,7 +162,7 @@
   virtual ~DeveloperPrivateGetItemsInfoFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   scoped_ptr<developer::ItemInfo> CreateItemInfo(const Extension& item,
@@ -278,7 +278,7 @@
   virtual ~DeveloperPrivateEnableFunction();
 
   // Callback for requirements checker.
-  void OnRequirementsChecked(std::string extension_id,
+  void OnRequirementsChecked(const std::string& extension_id,
                              std::vector<std::string> requirements_errors);
   // ExtensionFunction:
   virtual bool RunSync() OVERRIDE;
@@ -291,7 +291,7 @@
                                             public EntryPickerClient {
  protected:
   virtual ~DeveloperPrivateChooseEntryFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   bool ShowPicker(ui::SelectFileDialog::Type picker_type,
                   const base::FilePath& last_directory,
                   const base::string16& select_title,
@@ -312,7 +312,7 @@
 
  protected:
   virtual ~DeveloperPrivateLoadUnpackedFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // EntryPickerCLient implementation.
   virtual void FileSelected(const base::FilePath& path) OVERRIDE;
@@ -327,7 +327,7 @@
 
  protected:
   virtual ~DeveloperPrivateChoosePathFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // EntryPickerClient functions.
   virtual void FileSelected(const base::FilePath& path) OVERRIDE;
@@ -352,7 +352,7 @@
 
  protected:
   virtual ~DeveloperPrivatePackDirectoryFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   scoped_refptr<PackExtensionJob> pack_job_;
@@ -385,7 +385,7 @@
   virtual ~DeveloperPrivateLoadDirectoryFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   void ClearExistingDirectoryContent(const base::FilePath& project_path);
 
@@ -442,7 +442,7 @@
   virtual ~DeveloperPrivateRequestFileSourceFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void LaunchCallback(const base::DictionaryValue& results);
@@ -460,7 +460,7 @@
   virtual ~DeveloperPrivateOpenDevToolsFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 }  // namespace api
diff --git a/chrome/browser/extensions/api/developer_private/entry_picker.cc b/chrome/browser/extensions/api/developer_private/entry_picker.cc
index f21371c..9e3b6af 100644
--- a/chrome/browser/extensions/api/developer_private/entry_picker.cc
+++ b/chrome/browser/extensions/api/developer_private/entry_picker.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/ui/chrome_select_file_policy.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
 
 namespace {
@@ -37,7 +36,7 @@
       this, new ChromeSelectFilePolicy(web_contents));
 
   gfx::NativeWindow owning_window = web_contents ?
-      platform_util::GetTopLevel(web_contents->GetView()->GetNativeView()) :
+      platform_util::GetTopLevel(web_contents->GetNativeView()) :
       NULL;
 
   if (g_skip_picker_for_test) {
diff --git a/chrome/browser/extensions/api/dial/dial_service_unittest.cc b/chrome/browser/extensions/api/dial/dial_service_unittest.cc
index adaecc0..699e631 100644
--- a/chrome/browser/extensions/api/dial/dial_service_unittest.cc
+++ b/chrome/browser/extensions/api/dial/dial_service_unittest.cc
@@ -84,19 +84,23 @@
   net::NetworkInterfaceList interface_list;
   interface_list.push_back(
       net::NetworkInterface("network1", "network1", 0,
-                            net::NETWORK_INTERFACE_UNKNOWN, mock_ip_, 0));
+                            net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
+                            mock_ip_, 0));
   interface_list.push_back(
       net::NetworkInterface("network2", "network2", 1,
-                            net::NETWORK_INTERFACE_UNKNOWN, mock_ip_, 0));
+                            net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
+                            mock_ip_, 0));
   interface_list.push_back(
       net::NetworkInterface("network3", "network3", 2,
-                            net::NETWORK_INTERFACE_UNKNOWN, mock_ip_, 0));
+                            net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
+                            mock_ip_, 0));
 
   // "network4" is equivalent to "network2" because both the address family
   // and interface index are the same.
   interface_list.push_back(
       net::NetworkInterface("network4", "network4", 1,
-                            net::NETWORK_INTERFACE_UNKNOWN, mock_ip_, 0));
+                            net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
+                            mock_ip_, 0));
 
   // 3 sockets * 4 requests per socket = 12 requests
   EXPECT_CALL(mock_observer_, OnDiscoveryRequest(A<DialService*>())).Times(12);
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc
index a89ed7a..46f1d4e 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api.cc
@@ -61,7 +61,6 @@
 #include "content/public/browser/resource_context.h"
 #include "content/public/browser/resource_dispatcher_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_function_dispatcher.h"
 #include "extensions/browser/extension_registry.h"
@@ -614,16 +613,34 @@
   void OnItemUpdated() { ++updated_; }
   void OnChangedFired() { ++changed_fired_; }
 
-  void set_filename_change_callbacks(
+  static void SetDetermineFilenameTimeoutSecondsForTesting(int s) {
+    determine_filename_timeout_s_ = s;
+  }
+
+  void BeginFilenameDetermination(
       const base::Closure& no_change,
       const ExtensionDownloadsEventRouter::FilenameChangedCallback& change) {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    ClearPendingDeterminers();
     filename_no_change_ = no_change;
     filename_change_ = change;
     determined_filename_ = creator_suggested_filename_;
     determined_conflict_action_ = creator_conflict_action_;
     // determiner_.install_time should default to 0 so that creator suggestions
     // should be lower priority than any actual onDeterminingFilename listeners.
+
+    // Ensure that the callback is called within a time limit.
+    weak_ptr_factory_.reset(
+        new base::WeakPtrFactory<ExtensionDownloadsEventRouterData>(this));
+    base::MessageLoopForUI::current()->PostDelayedTask(
+        FROM_HERE,
+        base::Bind(&ExtensionDownloadsEventRouterData::DetermineFilenameTimeout,
+                   weak_ptr_factory_->GetWeakPtr()),
+        base::TimeDelta::FromSeconds(determine_filename_timeout_s_));
+  }
+
+  void DetermineFilenameTimeout() {
+    CallFilenameCallback();
   }
 
   void ClearPendingDeterminers() {
@@ -749,6 +766,8 @@
   }
 
  private:
+  static int determine_filename_timeout_s_;
+
   struct DeterminerInfo {
     DeterminerInfo();
     DeterminerInfo(const std::string& e_id,
@@ -771,17 +790,8 @@
       if (!iter->reported)
         return;
     }
-    if (determined_filename_.empty() &&
-        (determined_conflict_action_ ==
-         downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY)) {
-      if (!filename_no_change_.is_null())
-        filename_no_change_.Run();
-    } else {
-      if (!filename_change_.is_null()) {
-        filename_change_.Run(determined_filename_, ConvertConflictAction(
-            determined_conflict_action_));
-      }
-    }
+    CallFilenameCallback();
+
     // Don't clear determiners_ immediately in case there's a second listener
     // for one of the extensions, so that DetermineFilename can return
     // kTooManyListeners. After a few seconds, DetermineFilename will return
@@ -793,9 +803,27 @@
         FROM_HERE,
         base::Bind(&ExtensionDownloadsEventRouterData::ClearPendingDeterminers,
                    weak_ptr_factory_->GetWeakPtr()),
-        base::TimeDelta::FromSeconds(30));
+        base::TimeDelta::FromSeconds(15));
   }
 
+  void CallFilenameCallback() {
+    if (determined_filename_.empty() &&
+        (determined_conflict_action_ ==
+         downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY)) {
+      if (!filename_no_change_.is_null())
+        filename_no_change_.Run();
+    } else {
+      if (!filename_change_.is_null()) {
+        filename_change_.Run(determined_filename_, ConvertConflictAction(
+            determined_conflict_action_));
+      }
+    }
+    // Clear the callbacks immediately in case they aren't idempotent.
+    filename_no_change_ = base::Closure();
+    filename_change_ = ExtensionDownloadsEventRouter::FilenameChangedCallback();
+  }
+
+
   int updated_;
   int changed_fired_;
   scoped_ptr<base::DictionaryValue> json_;
@@ -819,6 +847,8 @@
   DISALLOW_COPY_AND_ASSIGN(ExtensionDownloadsEventRouterData);
 };
 
+int ExtensionDownloadsEventRouterData::determine_filename_timeout_s_ = 15;
+
 ExtensionDownloadsEventRouterData::DeterminerInfo::DeterminerInfo(
     const std::string& e_id,
     const base::Time& installed)
@@ -958,7 +988,7 @@
 
 DownloadsDownloadFunction::~DownloadsDownloadFunction() {}
 
-bool DownloadsDownloadFunction::RunImpl() {
+bool DownloadsDownloadFunction::RunAsync() {
   scoped_ptr<downloads::Download::Params> params(
       downloads::Download::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -1207,7 +1237,7 @@
 DownloadsRemoveFileFunction::~DownloadsRemoveFileFunction() {
 }
 
-bool DownloadsRemoveFileFunction::RunImpl() {
+bool DownloadsRemoveFileFunction::RunAsync() {
   scoped_ptr<downloads::RemoveFile::Params> params(
       downloads::RemoveFile::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -1240,7 +1270,7 @@
 DownloadsAcceptDangerFunction::OnPromptCreatedCallback*
     DownloadsAcceptDangerFunction::on_prompt_created_ = NULL;
 
-bool DownloadsAcceptDangerFunction::RunImpl() {
+bool DownloadsAcceptDangerFunction::RunAsync() {
   scoped_ptr<downloads::AcceptDanger::Params> params(
       downloads::AcceptDanger::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -1261,8 +1291,7 @@
     SendResponse(error_.empty());
     return;
   }
-  bool visible = platform_util::IsVisible(
-      web_contents->GetView()->GetNativeView());
+  bool visible = platform_util::IsVisible(web_contents->GetNativeView());
   if (!visible) {
     if (retries > 0) {
       base::MessageLoopForUI::current()->PostDelayedTask(
@@ -1317,7 +1346,7 @@
 
 DownloadsShowFunction::~DownloadsShowFunction() {}
 
-bool DownloadsShowFunction::RunImpl() {
+bool DownloadsShowFunction::RunAsync() {
   scoped_ptr<downloads::Show::Params> params(
       downloads::Show::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -1334,7 +1363,7 @@
 
 DownloadsShowDefaultFolderFunction::~DownloadsShowDefaultFolderFunction() {}
 
-bool DownloadsShowDefaultFolderFunction::RunImpl() {
+bool DownloadsShowDefaultFolderFunction::RunAsync() {
   DownloadManager* manager = NULL;
   DownloadManager* incognito_manager = NULL;
   GetManagers(GetProfile(), include_incognito(), &manager, &incognito_manager);
@@ -1372,7 +1401,7 @@
 
 DownloadsDragFunction::~DownloadsDragFunction() {}
 
-bool DownloadsDragFunction::RunImpl() {
+bool DownloadsDragFunction::RunAsync() {
   scoped_ptr<downloads::Drag::Params> params(
       downloads::Drag::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -1386,7 +1415,7 @@
   RecordApiFunctions(DOWNLOADS_FUNCTION_DRAG);
   gfx::Image* icon = g_browser_process->icon_manager()->LookupIconFromFilepath(
       download_item->GetTargetFilePath(), IconLoader::NORMAL);
-  gfx::NativeView view = web_contents->GetView()->GetNativeView();
+  gfx::NativeView view = web_contents->GetNativeView();
   {
     // Enable nested tasks during DnD, while |DragDownload()| blocks.
     base::MessageLoop::ScopedNestableTaskAllower allow(
@@ -1466,7 +1495,7 @@
   icon_extractor_.reset(extractor);
 }
 
-bool DownloadsGetFileIconFunction::RunImpl() {
+bool DownloadsGetFileIconFunction::RunAsync() {
   scoped_ptr<downloads::GetFileIcon::Params> params(
       downloads::GetFileIcon::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -1535,6 +1564,12 @@
     router->UnregisterObserver(this);
 }
 
+void ExtensionDownloadsEventRouter::
+    SetDetermineFilenameTimeoutSecondsForTesting(int s) {
+  ExtensionDownloadsEventRouterData::
+      SetDetermineFilenameTimeoutSecondsForTesting(s);
+}
+
 void ExtensionDownloadsEventRouter::SetShelfEnabled(
     const extensions::Extension* extension, bool enabled) {
   std::set<const extensions::Extension*>::iterator iter =
@@ -1558,23 +1593,22 @@
 // chrome.downloads.onDeterminingFilename.addListener, which adds an
 // EventListener object to ExtensionEventRouter::listeners().
 //
-// When a download's filename is being determined,
-// ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone (CVRBD) passes
-// 2 callbacks to ExtensionDownloadsEventRouter::OnDeterminingFilename (ODF),
-// which stores the callbacks in the item's ExtensionDownloadsEventRouterData
-// (EDERD) along with all of the extension IDs that are listening for
-// onDeterminingFilename events.  ODF dispatches
-// chrome.downloads.onDeterminingFilename.
+// When a download's filename is being determined, DownloadTargetDeterminer (via
+// ChromeDownloadManagerDelegate (CDMD) ::NotifyExtensions()) passes 2 callbacks
+// to ExtensionDownloadsEventRouter::OnDeterminingFilename (ODF), which stores
+// the callbacks in the item's ExtensionDownloadsEventRouterData (EDERD) along
+// with all of the extension IDs that are listening for onDeterminingFilename
+// events. ODF dispatches chrome.downloads.onDeterminingFilename.
 //
 // When the extension's event handler calls |suggestCallback|,
 // downloads_custom_bindings.js calls
-// DownloadsInternalDetermineFilenameFunction::RunImpl, which calls
+// DownloadsInternalDetermineFilenameFunction::RunAsync, which calls
 // EDER::DetermineFilename, which notifies the item's EDERD.
 //
 // When the last extension's event handler returns, EDERD calls one of the two
-// callbacks that CVRBD passed to ODF, allowing CDMD to complete the filename
-// determination process. If multiple extensions wish to override the filename,
-// then the extension that was last installed wins.
+// callbacks that CDMD passed to ODF, allowing DownloadTargetDeterminer to
+// continue the filename determination process. If multiple extensions wish to
+// override the filename, then the extension that was last installed wins.
 
 void ExtensionDownloadsEventRouter::OnDeterminingFilename(
     DownloadItem* item,
@@ -1588,8 +1622,7 @@
     no_change.Run();
     return;
   }
-  data->ClearPendingDeterminers();
-  data->set_filename_change_callbacks(no_change, change);
+  data->BeginFilenameDetermination(no_change, change);
   bool any_determiners = false;
   base::DictionaryValue* json = DownloadItemToJSON(
       item, profile_).release();
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.h b/chrome/browser/extensions/api/downloads/downloads_api.h
index b4c2358..b24a938 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api.h
+++ b/chrome/browser/extensions/api/downloads/downloads_api.h
@@ -92,7 +92,7 @@
  public:
   DECLARE_EXTENSION_FUNCTION("downloads.download", DOWNLOADS_DOWNLOAD)
   DownloadsDownloadFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  protected:
   virtual ~DownloadsDownloadFunction();
@@ -176,7 +176,7 @@
  public:
   DECLARE_EXTENSION_FUNCTION("downloads.removeFile", DOWNLOADS_REMOVEFILE)
   DownloadsRemoveFileFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  protected:
   virtual ~DownloadsRemoveFileFunction();
@@ -197,7 +197,7 @@
 
   DECLARE_EXTENSION_FUNCTION("downloads.acceptDanger", DOWNLOADS_ACCEPTDANGER)
   DownloadsAcceptDangerFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  protected:
   virtual ~DownloadsAcceptDangerFunction();
@@ -215,7 +215,7 @@
  public:
   DECLARE_EXTENSION_FUNCTION("downloads.show", DOWNLOADS_SHOW)
   DownloadsShowFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  protected:
   virtual ~DownloadsShowFunction();
@@ -229,7 +229,7 @@
   DECLARE_EXTENSION_FUNCTION(
       "downloads.showDefaultFolder", DOWNLOADS_SHOWDEFAULTFOLDER)
   DownloadsShowDefaultFolderFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  protected:
   virtual ~DownloadsShowDefaultFolderFunction();
@@ -269,7 +269,7 @@
  public:
   DECLARE_EXTENSION_FUNCTION("downloads.drag", DOWNLOADS_DRAG)
   DownloadsDragFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  protected:
   virtual ~DownloadsDragFunction();
@@ -282,7 +282,7 @@
  public:
   DECLARE_EXTENSION_FUNCTION("downloads.getFileIcon", DOWNLOADS_GETFILEICON)
   DownloadsGetFileIconFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void SetIconExtractorForTesting(DownloadFileIconExtractor* extractor);
 
  protected:
@@ -307,6 +307,8 @@
       DownloadPathReservationTracker::FilenameConflictAction)>
     FilenameChangedCallback;
 
+  static void SetDetermineFilenameTimeoutSecondsForTesting(int s);
+
   // The logic for how to handle conflicting filename suggestions from multiple
   // extensions is split out here for testing.
   static void DetermineFilenameInternal(
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
index af2fcb0..bf3e7e4 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -291,6 +291,8 @@
   }
 
   content::RenderProcessHost* AddFilenameDeterminer() {
+    ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
+        2);
     content::WebContents* tab = chrome::AddSelectedTabWithURL(
         current_browser(),
         extension_->GetResourceURL("empty.html"),
@@ -2354,9 +2356,8 @@
   EXPECT_STREQ(kPayloadData, disk_data.c_str());
 }
 
-// Test is flaky: http://crbug.com/302071
 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
-                       DISABLED_DownloadExtensionTest_OnDeterminingFilename_NoChange) {
+                       DownloadExtensionTest_OnDeterminingFilename_NoChange) {
   GoOnTheRecord();
   LoadExtension("downloads_split");
   AddFilenameDeterminer();
@@ -2425,6 +2426,147 @@
                           result_id)));
 }
 
+// Disabled due to cross-platform flakes; http://crbug.com/370531.
+IN_PROC_BROWSER_TEST_F(
+    DownloadExtensionTest,
+    DISABLED_DownloadExtensionTest_OnDeterminingFilename_Timeout) {
+  GoOnTheRecord();
+  LoadExtension("downloads_split");
+  AddFilenameDeterminer();
+  ASSERT_TRUE(StartEmbeddedTestServer());
+  ASSERT_TRUE(test_server()->Start());
+  std::string download_url = test_server()->GetURL("slow?0").spec();
+
+  ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
+      0);
+
+  // Start downloading a file.
+  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
+      new DownloadsDownloadFunction(), base::StringPrintf(
+          "[{\"url\": \"%s\"}]", download_url.c_str())));
+  ASSERT_TRUE(result.get());
+  int result_id = -1;
+  ASSERT_TRUE(result->GetAsInteger(&result_id));
+  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
+  ASSERT_TRUE(item);
+  ScopedCancellingItem canceller(item);
+  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
+
+  // Wait for the onCreated and onDeterminingFilename events.
+  ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
+      base::StringPrintf("[{\"danger\": \"safe\","
+                          "  \"incognito\": false,"
+                          "  \"id\": %d,"
+                          "  \"mime\": \"text/plain\","
+                          "  \"paused\": false,"
+                          "  \"url\": \"%s\"}]",
+                          result_id,
+                          download_url.c_str())));
+  ASSERT_TRUE(WaitFor(
+      downloads::OnDeterminingFilename::kEventName,
+      base::StringPrintf("[{\"id\": %d,"
+                         "  \"filename\":\"slow.txt\"}]",
+                         result_id)));
+  ASSERT_TRUE(item->GetTargetFilePath().empty());
+  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
+
+  // Do not respond to the onDeterminingFilename.
+
+  // The download should complete successfully.
+  ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
+      base::StringPrintf("[{\"id\": %d,"
+                         "  \"filename\": {"
+                         "    \"previous\": \"\","
+                         "    \"current\": \"%s\"}}]",
+                         result_id,
+                         GetFilename("slow.txt").c_str())));
+  ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
+      base::StringPrintf("[{\"id\": %d,"
+                         "  \"state\": {"
+                         "    \"previous\": \"in_progress\","
+                         "    \"current\": \"complete\"}}]",
+                         result_id)));
+}
+
+IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
+                       DownloadExtensionTest_OnDeterminingFilename_Twice) {
+  GoOnTheRecord();
+  LoadExtension("downloads_split");
+  AddFilenameDeterminer();
+  ASSERT_TRUE(StartEmbeddedTestServer());
+  ASSERT_TRUE(test_server()->Start());
+  std::string download_url = test_server()->GetURL("slow?0").spec();
+
+  // Start downloading a file.
+  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
+      new DownloadsDownloadFunction(), base::StringPrintf(
+          "[{\"url\": \"%s\"}]", download_url.c_str())));
+  ASSERT_TRUE(result.get());
+  int result_id = -1;
+  ASSERT_TRUE(result->GetAsInteger(&result_id));
+  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
+  ASSERT_TRUE(item);
+  ScopedCancellingItem canceller(item);
+  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
+
+  // Wait for the onCreated and onDeterminingFilename events.
+  ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
+      base::StringPrintf("[{\"danger\": \"safe\","
+                          "  \"incognito\": false,"
+                          "  \"id\": %d,"
+                          "  \"mime\": \"text/plain\","
+                          "  \"paused\": false,"
+                          "  \"url\": \"%s\"}]",
+                          result_id,
+                          download_url.c_str())));
+  ASSERT_TRUE(WaitFor(
+      downloads::OnDeterminingFilename::kEventName,
+      base::StringPrintf("[{\"id\": %d,"
+                         "  \"filename\":\"slow.txt\"}]",
+                         result_id)));
+  ASSERT_TRUE(item->GetTargetFilePath().empty());
+  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
+
+  // Respond to the onDeterminingFilename.
+  std::string error;
+  ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
+      browser()->profile(),
+      false,
+      GetExtensionId(),
+      result_id,
+      base::FilePath(),
+      downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
+      &error));
+  EXPECT_EQ("", error);
+
+  // Calling DetermineFilename again should return an error instead of calling
+  // DownloadTargetDeterminer.
+  ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
+      browser()->profile(),
+      false,
+      GetExtensionId(),
+      result_id,
+      base::FilePath(FILE_PATH_LITERAL("different")),
+      downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
+      &error));
+  EXPECT_EQ(errors::kTooManyListeners, error);
+
+  // The download should complete successfully.
+  ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
+      base::StringPrintf("[{\"id\": %d,"
+                         "  \"filename\": {"
+                         "    \"previous\": \"\","
+                         "    \"current\": \"%s\"}}]",
+                         result_id,
+                         GetFilename("slow.txt").c_str())));
+  ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
+      base::StringPrintf("[{\"id\": %d,"
+                         "  \"state\": {"
+                         "    \"previous\": \"in_progress\","
+                         "    \"current\": \"complete\"}}]",
+                         result_id)));
+}
+
 IN_PROC_BROWSER_TEST_F(
     DownloadExtensionTest,
     DownloadExtensionTest_OnDeterminingFilename_DangerousOverride) {
diff --git a/chrome/browser/extensions/api/downloads_internal/downloads_internal_api.cc b/chrome/browser/extensions/api/downloads_internal/downloads_internal_api.cc
index cb12918..299e0d3 100644
--- a/chrome/browser/extensions/api/downloads_internal/downloads_internal_api.cc
+++ b/chrome/browser/extensions/api/downloads_internal/downloads_internal_api.cc
@@ -19,7 +19,7 @@
 typedef extensions::api::downloads_internal::DetermineFilename::Params
     DetermineFilenameParams;
 
-bool DownloadsInternalDetermineFilenameFunction::RunImpl() {
+bool DownloadsInternalDetermineFilenameFunction::RunAsync() {
   scoped_ptr<DetermineFilenameParams> params(
       DetermineFilenameParams::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
diff --git a/chrome/browser/extensions/api/downloads_internal/downloads_internal_api.h b/chrome/browser/extensions/api/downloads_internal/downloads_internal_api.h
index a88364e..94fef49 100644
--- a/chrome/browser/extensions/api/downloads_internal/downloads_internal_api.h
+++ b/chrome/browser/extensions/api/downloads_internal/downloads_internal_api.h
@@ -15,7 +15,7 @@
   DECLARE_EXTENSION_FUNCTION("downloadsInternal.determineFilename",
                              DOWNLOADSINTERNAL_DETERMINEFILENAME);
   DownloadsInternalDetermineFilenameFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  protected:
   virtual ~DownloadsInternalDetermineFilenameFunction();
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
index 1413446..804c8c1 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
+++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
@@ -289,7 +289,7 @@
 EPKPChallengeMachineKey::~EPKPChallengeMachineKey() {
 }
 
-bool EPKPChallengeMachineKey::RunImpl() {
+bool EPKPChallengeMachineKey::RunAsync() {
   scoped_ptr<api_epkp::ChallengeMachineKey::Params>
       params(api_epkp::ChallengeMachineKey::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -416,7 +416,7 @@
                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 }
 
-bool EPKPChallengeUserKey::RunImpl() {
+bool EPKPChallengeUserKey::RunAsync() {
   scoped_ptr<api_epkp::ChallengeUserKey::Params> params(
       api_epkp::ChallengeUserKey::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h
index 49122ea..8c91d1f 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h
+++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h
@@ -158,7 +158,7 @@
       policy::EnterpriseInstallAttributes* install_attributes);
 
  protected:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   static const char kKeyName[];
@@ -195,7 +195,7 @@
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
  protected:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   static const char kKeyName[];
diff --git a/chrome/browser/extensions/api/execute_code_function.cc b/chrome/browser/extensions/api/execute_code_function.cc
index fd19219..f06c91c 100644
--- a/chrome/browser/extensions/api/execute_code_function.cc
+++ b/chrome/browser/extensions/api/execute_code_function.cc
@@ -162,7 +162,7 @@
   return true;
 }
 
-bool ExecuteCodeFunction::RunImpl() {
+bool ExecuteCodeFunction::RunAsync() {
   EXTENSION_FUNCTION_VALIDATE(Init());
 
   if (!details_->code.get() && !details_->file.get()) {
diff --git a/chrome/browser/extensions/api/execute_code_function.h b/chrome/browser/extensions/api/execute_code_function.h
index 213998f..da7e73d 100644
--- a/chrome/browser/extensions/api/execute_code_function.h
+++ b/chrome/browser/extensions/api/execute_code_function.h
@@ -23,7 +23,7 @@
 
   // ExtensionFunction implementation.
   virtual bool HasPermission() OVERRIDE;
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Initialize |details_| if it hasn't already been.
   virtual bool Init() = 0;
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
index a74d44f..3b552b3 100644
--- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc
+++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
@@ -27,6 +27,7 @@
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_function_registry.h"
 #include "extensions/browser/extension_host.h"
+#include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/image_util.h"
 #include "extensions/common/error_utils.h"
@@ -415,10 +416,8 @@
 //
 
 ExtensionActionStorageManager::ExtensionActionStorageManager(Profile* profile)
-    : profile_(profile) {
-  registrar_.Add(this,
-                 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
-                 content::Source<Profile>(profile_));
+    : profile_(profile), extension_registry_observer_(this) {
+  extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
                  content::NotificationService::AllBrowserContextsAndSources());
 
@@ -430,41 +429,36 @@
 ExtensionActionStorageManager::~ExtensionActionStorageManager() {
 }
 
+void ExtensionActionStorageManager::OnExtensionLoaded(
+    content::BrowserContext* browser_context,
+    const Extension* extension) {
+  if (!ExtensionActionManager::Get(profile_)->GetBrowserAction(*extension)) {
+    return;
+  }
+
+  StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
+  if (storage) {
+    storage->GetExtensionValue(
+        extension->id(),
+        kBrowserActionStorageKey,
+        base::Bind(&ExtensionActionStorageManager::ReadFromStorage,
+                   AsWeakPtr(),
+                   extension->id()));
+  }
+};
+
 void ExtensionActionStorageManager::Observe(
     int type,
     const content::NotificationSource& source,
     const content::NotificationDetails& details) {
-  switch (type) {
-    case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
-      const Extension* extension =
-          content::Details<const Extension>(details).ptr();
-      if (!ExtensionActionManager::Get(profile_)->
-          GetBrowserAction(*extension)) {
-        break;
-      }
+  DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED);
+  ExtensionAction* extension_action =
+      content::Source<ExtensionAction>(source).ptr();
+  Profile* profile = content::Details<Profile>(details).ptr();
+  if (profile != profile_)
+    return;
 
-      StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
-      if (storage) {
-        storage->GetExtensionValue(extension->id(), kBrowserActionStorageKey,
-            base::Bind(&ExtensionActionStorageManager::ReadFromStorage,
-                       AsWeakPtr(), extension->id()));
-      }
-      break;
-    }
-    case chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED: {
-      ExtensionAction* extension_action =
-          content::Source<ExtensionAction>(source).ptr();
-      Profile* profile = content::Details<Profile>(details).ptr();
-      if (profile != profile_)
-        break;
-
-      WriteToStorage(extension_action);
-      break;
-    }
-    default:
-      NOTREACHED();
-      break;
-  }
+  WriteToStorage(extension_action);
 }
 
 void ExtensionActionStorageManager::WriteToStorage(
@@ -800,7 +794,7 @@
     : response_sent_(false) {
 }
 
-bool BrowserActionOpenPopupFunction::RunImpl() {
+bool BrowserActionOpenPopupFunction::RunAsync() {
   ExtensionToolbarModel* model = ExtensionToolbarModel::Get(GetProfile());
   if (!model) {
     error_ = kInternalError;
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.h b/chrome/browser/extensions/api/extension_action/extension_action_api.h
index 5e013de..dfd0e6e 100644
--- a/chrome/browser/extensions/api/extension_action/extension_action_api.h
+++ b/chrome/browser/extensions/api/extension_action/extension_action_api.h
@@ -8,11 +8,13 @@
 #include <string>
 
 #include "base/memory/weak_ptr.h"
+#include "base/scoped_observer.h"
 #include "chrome/browser/extensions/chrome_extension_function.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
+#include "extensions/browser/extension_registry_observer.h"
 
 namespace base {
 class DictionaryValue;
@@ -25,6 +27,7 @@
 
 namespace extensions {
 class ExtensionPrefs;
+class ExtensionRegistry;
 class TabHelper;
 
 class ExtensionActionAPI : public BrowserContextKeyedAPI {
@@ -91,6 +94,7 @@
 // This class manages reading and writing browser action values from storage.
 class ExtensionActionStorageManager
     : public content::NotificationObserver,
+      public ExtensionRegistryObserver,
       public base::SupportsWeakPtr<ExtensionActionStorageManager> {
  public:
   explicit ExtensionActionStorageManager(Profile* profile);
@@ -102,6 +106,10 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
+  // ExtensionRegistryObserver:
+  virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
+                                 const Extension* extension) OVERRIDE;
+
   // Reads/Writes the ExtensionAction's default values to/from storage.
   void WriteToStorage(ExtensionAction* extension_action);
   void ReadFromStorage(
@@ -109,6 +117,10 @@
 
   Profile* profile_;
   content::NotificationRegistrar registrar_;
+
+  // Listen to extension loaded notification.
+  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
+      extension_registry_observer_;
 };
 
 // Implementation of the browserAction and pageAction APIs.
@@ -351,7 +363,7 @@
   virtual ~BrowserActionOpenPopupFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   virtual void Observe(int type,
                        const content::NotificationSource& source,
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc
index c6d2874..05429d8 100644
--- a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc
+++ b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc
@@ -65,7 +65,7 @@
     AppWindow* window =
         PlatformAppBrowserTest::GetFirstAppWindowForBrowser(browser());
     ASSERT_TRUE(window);
-    const Extension* feedback_app = window->extension();
+    const Extension* feedback_app = window->GetExtension();
     ASSERT_TRUE(feedback_app);
     EXPECT_EQ(feedback_app->id(), std::string(kFeedbackExtensionId));
   }
@@ -81,7 +81,15 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(FeedbackTest, ShowFeedback) {
+// Disabled test; it is crashing on ChromeOS build bots intermittently.
+// See http://crbug.com/369886.
+#if defined(OS_CHROMEOS)
+#define MAYBE_ShowFeedback DISABLED_ShowFeedback
+#else
+#define MAYBE_ShowFeedback ShowFeedback
+#endif
+
+IN_PROC_BROWSER_TEST_F(FeedbackTest, MAYBE_ShowFeedback) {
   WaitForExtensionViewsToLoad();
 
   ASSERT_TRUE(IsFeedbackAppAvailable());
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc b/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc
index 4a7eaae..aff4998 100644
--- a/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc
+++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc
@@ -11,14 +11,16 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/extensions/api/feedback_private/feedback_service.h"
-#include "chrome/browser/feedback/tracing_manager.h"
 #include "chrome/browser/profiles/profile.h"
+#include "components/feedback/tracing_manager.h"
 #include "extensions/browser/event_router.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/webui/web_ui_util.h"
 #include "url/url_util.h"
 
+using feedback::FeedbackData;
+
 namespace {
 
 // Getting the filename of a blob prepends a "C:\fakepath" to the filename.
@@ -142,7 +144,7 @@
   return true;
 }
 
-bool FeedbackPrivateGetSystemInformationFunction::RunImpl() {
+bool FeedbackPrivateGetSystemInformationFunction::RunAsync() {
   // TODO(rkc): Remove logging once crbug.com/284662 is closed.
   LOG(WARNING) << "FEEDBACK_DEBUG: System information requested.";
   FeedbackService* service =
@@ -161,7 +163,7 @@
   SendResponse(true);
 }
 
-bool FeedbackPrivateSendFeedbackFunction::RunImpl() {
+bool FeedbackPrivateSendFeedbackFunction::RunAsync() {
   scoped_ptr<feedback_private::SendFeedback::Params> params(
       feedback_private::SendFeedback::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -180,7 +182,7 @@
 
   // Populate feedback data.
   scoped_refptr<FeedbackData> feedback_data(new FeedbackData());
-  feedback_data->set_profile(GetProfile());
+  feedback_data->set_context(GetProfile());
   feedback_data->set_description(feedback_info.description);
 
   if (feedback_info.category_tag.get())
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api.h b/chrome/browser/extensions/api/feedback_private/feedback_private_api.h
index 02fabe3..43f4de2 100644
--- a/chrome/browser/extensions/api/feedback_private/feedback_private_api.h
+++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api.h
@@ -85,7 +85,7 @@
 
  protected:
   virtual ~FeedbackPrivateGetSystemInformationFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnCompleted(
@@ -100,7 +100,7 @@
 
  protected:
   virtual ~FeedbackPrivateSendFeedbackFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnCompleted(bool success);
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_service.cc b/chrome/browser/extensions/api/feedback_private/feedback_service.cc
index f32840c..31a1c6c 100644
--- a/chrome/browser/extensions/api/feedback_private/feedback_service.cc
+++ b/chrome/browser/extensions/api/feedback_private/feedback_service.cc
@@ -7,10 +7,13 @@
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_content_client.h"
 #include "content/public/browser/browser_thread.h"
 
 using content::BrowserThread;
+using feedback::FeedbackData;
 
 namespace {
 
@@ -44,6 +47,8 @@
     const SendFeedbackCallback& callback) {
   send_feedback_callback_ = callback;
   feedback_data_ = feedback_data;
+  feedback_data_->set_locale(g_browser_process->GetApplicationLocale());
+  feedback_data_->set_user_agent(GetUserAgent());
 
   if (!feedback_data_->attached_file_uuid().empty()) {
     // Self-deleting object.
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_service.h b/chrome/browser/extensions/api/feedback_private/feedback_service.h
index 3daff71..76c210f 100644
--- a/chrome/browser/extensions/api/feedback_private/feedback_service.h
+++ b/chrome/browser/extensions/api/feedback_private/feedback_service.h
@@ -11,9 +11,9 @@
 #include "base/memory/linked_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/extensions/blob_reader.h"
-#include "chrome/browser/feedback/feedback_data.h"
 #include "chrome/browser/feedback/system_logs/scrubbed_system_logs_fetcher.h"
 #include "chrome/common/extensions/api/feedback_private.h"
+#include "components/feedback/feedback_data.h"
 
 class Profile;
 
@@ -36,7 +36,7 @@
 
   // Sends a feedback report.
   void SendFeedback(Profile* profile,
-                    scoped_refptr<FeedbackData> feedback_data,
+                    scoped_refptr<feedback::FeedbackData> feedback_data,
                     const SendFeedbackCallback& callback);
 
   // Start to gather system information.
@@ -73,7 +73,7 @@
   GetSystemInformationCallback system_information_callback_;
   SendFeedbackCallback send_feedback_callback_;
 
-  scoped_refptr<FeedbackData> feedback_data_;
+  scoped_refptr<feedback::FeedbackData> feedback_data_;
 
   DISALLOW_COPY_AND_ASSIGN(FeedbackService);
 };
diff --git a/chrome/browser/extensions/api/file_system/file_system_api.cc b/chrome/browser/extensions/api/file_system/file_system_api.cc
index cafcb0e..fee90cb 100644
--- a/chrome/browser/extensions/api/file_system/file_system_api.cc
+++ b/chrome/browser/extensions/api/file_system/file_system_api.cc
@@ -32,7 +32,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/common/permissions/api_permission.h"
 #include "grit/generated_resources.h"
@@ -353,7 +352,7 @@
   SendResponse(false);
 }
 
-bool FileSystemGetWritableEntryFunction::RunImpl() {
+bool FileSystemGetWritableEntryFunction::RunAsync() {
   std::string filesystem_name;
   std::string filesystem_path;
   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &filesystem_name));
@@ -438,7 +437,7 @@
     select_file_dialog_ = ui::SelectFileDialog::Create(
         this, new ChromeSelectFilePolicy(web_contents));
     gfx::NativeWindow owning_window = web_contents ?
-        platform_util::GetTopLevel(web_contents->GetView()->GetNativeView()) :
+        platform_util::GetTopLevel(web_contents->GetNativeView()) :
         NULL;
 
     if (g_skip_picker_for_test) {
@@ -833,7 +832,7 @@
   }
 }
 
-bool FileSystemChooseEntryFunction::RunImpl() {
+bool FileSystemChooseEntryFunction::RunAsync() {
   scoped_ptr<ChooseEntry::Params> params(ChooseEntry::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -902,7 +901,7 @@
   return true;
 }
 
-bool FileSystemRetainEntryFunction::RunImpl() {
+bool FileSystemRetainEntryFunction::RunAsync() {
   std::string entry_id;
   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &entry_id));
   SavedFilesService* saved_files_service = SavedFilesService::Get(GetProfile());
@@ -957,7 +956,7 @@
   return true;
 }
 
-bool FileSystemRestoreEntryFunction::RunImpl() {
+bool FileSystemRestoreEntryFunction::RunAsync() {
   std::string entry_id;
   bool needs_new_entry;
   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &entry_id));
diff --git a/chrome/browser/extensions/api/file_system/file_system_api.h b/chrome/browser/extensions/api/file_system/file_system_api.h
index a2a8c70..7aee4e5 100644
--- a/chrome/browser/extensions/api/file_system/file_system_api.h
+++ b/chrome/browser/extensions/api/file_system/file_system_api.h
@@ -88,7 +88,7 @@
 
  protected:
   virtual ~FileSystemGetWritableEntryFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void CheckPermissionAndSendResponse();
@@ -145,7 +145,7 @@
   class FilePicker;
 
   virtual ~FileSystemChooseEntryFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void ShowPicker(const ui::SelectFileDialog::FileTypeInfo& file_type_info,
                   ui::SelectFileDialog::Type picker_type);
 
@@ -176,7 +176,7 @@
 
  protected:
   virtual ~FileSystemRetainEntryFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Retains the file entry referenced by |entry_id| in apps::SavedFilesService.
@@ -207,7 +207,7 @@
 
  protected:
   virtual ~FileSystemRestoreEntryFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/file_system/file_system_api_unittest.cc b/chrome/browser/extensions/api/file_system/file_system_api_unittest.cc
index ba2fd95..179c2c3 100644
--- a/chrome/browser/extensions/api/file_system/file_system_api_unittest.cc
+++ b/chrome/browser/extensions/api/file_system/file_system_api_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "base/files/file_path.h"
 #include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -25,9 +26,9 @@
   }
 }
 
-AcceptOption* BuildAcceptOption(std::string description,
-    std::string mime_types,
-    std::string extensions) {
+AcceptOption* BuildAcceptOption(const std::string& description,
+                                const std::string& mime_types,
+                                const std::string& extensions) {
   AcceptOption* option = new AcceptOption();
 
   if (!description.empty())
@@ -70,7 +71,7 @@
   file_type_info = ui::SelectFileDialog::FileTypeInfo();
   std::vector<linked_ptr<AcceptOption> > options;
   options.push_back(linked_ptr<AcceptOption>(BuildAcceptOption(
-      std::string(), "application/x-chrome-extension", "jso")));
+      base::EmptyString(), "application/x-chrome-extension", "jso")));
   acceptsAllTypes = false;
   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
       base::FilePath::StringType(), &options, &acceptsAllTypes);
@@ -88,8 +89,8 @@
   // Test that not satisfying the extension will force all types.
   file_type_info = ui::SelectFileDialog::FileTypeInfo();
   options.clear();
-  options.push_back(linked_ptr<AcceptOption>(
-      BuildAcceptOption(std::string(), std::string(), "unrelated")));
+  options.push_back(linked_ptr<AcceptOption>(BuildAcceptOption(
+      base::EmptyString(), base::EmptyString(), "unrelated")));
   acceptsAllTypes = false;
   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
       ToStringType(".jso"), &options, &acceptsAllTypes);
@@ -99,9 +100,9 @@
   file_type_info = ui::SelectFileDialog::FileTypeInfo();
   options.clear();
   options.push_back(linked_ptr<AcceptOption>(
-      BuildAcceptOption(std::string(), std::string(), "jso,js")));
+      BuildAcceptOption(base::EmptyString(), base::EmptyString(), "jso,js")));
   options.push_back(linked_ptr<AcceptOption>(
-      BuildAcceptOption(std::string(), std::string(), "cpp,cc")));
+      BuildAcceptOption(base::EmptyString(), base::EmptyString(), "cpp,cc")));
   acceptsAllTypes = false;
   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
       base::FilePath::StringType(), &options, &acceptsAllTypes);
@@ -121,7 +122,7 @@
   file_type_info = ui::SelectFileDialog::FileTypeInfo();
   options.clear();
   options.push_back(linked_ptr<AcceptOption>(
-      BuildAcceptOption(std::string(), "image/*", "html")));
+      BuildAcceptOption(base::EmptyString(), "image/*", "html")));
   acceptsAllTypes = false;
   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
       base::FilePath::StringType(), &options, &acceptsAllTypes);
@@ -134,7 +135,7 @@
   file_type_info = ui::SelectFileDialog::FileTypeInfo();
   options.clear();
   options.push_back(linked_ptr<AcceptOption>(BuildAcceptOption(
-      std::string(), "image/*,audio/*,video/*", std::string())));
+      base::EmptyString(), "image/*,audio/*,video/*", base::EmptyString())));
   acceptsAllTypes = false;
   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
       base::FilePath::StringType(), &options, &acceptsAllTypes);
@@ -145,7 +146,7 @@
   file_type_info = ui::SelectFileDialog::FileTypeInfo();
   options.clear();
   options.push_back(linked_ptr<AcceptOption>(
-      BuildAcceptOption("File Types 101", "image/jpeg", std::string())));
+      BuildAcceptOption("File Types 101", "image/jpeg", base::EmptyString())));
   acceptsAllTypes = false;
   FileSystemChooseEntryFunction::BuildFileTypeInfo(&file_type_info,
       base::FilePath::StringType(), &options, &acceptsAllTypes);
diff --git a/chrome/browser/extensions/api/file_system/file_system_apitest.cc b/chrome/browser/extensions/api/file_system/file_system_apitest.cc
index fee48ef..ac32e37 100644
--- a/chrome/browser/extensions/api/file_system/file_system_apitest.cc
+++ b/chrome/browser/extensions/api/file_system/file_system_apitest.cc
@@ -152,7 +152,7 @@
 #if defined(OS_WIN) || defined(OS_POSIX)
 IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPathPrettify) {
   ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(base::DIR_HOME,
-      test_root_folder_, false));
+      test_root_folder_, false, false));
 
   base::FilePath test_file = test_root_folder_.AppendASCII("gold.txt");
   FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
@@ -212,7 +212,7 @@
   base::FilePath test_file = TempFilePath("open_existing.txt", true);
   ASSERT_FALSE(test_file.empty());
   ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(
-      chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false));
+      chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false, false));
   FileSystemChooseEntryFunction::
       SkipPickerAndSelectSuggestedPathForTest();
   {
@@ -232,7 +232,7 @@
   base::FilePath test_file = TempFilePath("open_existing.txt", true);
   ASSERT_FALSE(test_file.empty());
   ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(
-      chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false));
+      chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false, false));
   FileSystemChooseEntryFunction::
       SkipPickerAndSelectSuggestedPathForTest();
   ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_existing"))
@@ -244,7 +244,7 @@
   base::FilePath test_file = TempFilePath("open_existing.txt", true);
   ASSERT_FALSE(test_file.empty());
   ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(
-      chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false));
+      chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false, false));
   FileSystemChooseEntryFunction::SkipPickerAndSelectSuggestedPathForTest();
   ASSERT_TRUE(RunPlatformAppTest(
       "api_test/file_system/open_multiple_with_suggested_name"))
@@ -323,7 +323,7 @@
   ASSERT_FALSE(test_file.empty());
   base::FilePath test_directory = test_file.DirName();
   ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(
-      kGraylistedPath, test_directory, false));
+      kGraylistedPath, test_directory, false, false));
   FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
       &test_directory);
   ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_directory"))
@@ -338,7 +338,7 @@
   ASSERT_FALSE(test_file.empty());
   base::FilePath test_directory = test_file.DirName();
   ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(
-      kGraylistedPath, test_directory, false));
+      kGraylistedPath, test_directory, false, false));
   FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
       &test_directory);
   ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_directory_cancel"))
@@ -354,7 +354,7 @@
   base::FilePath test_directory = test_file.DirName();
   base::FilePath parent_directory = test_directory.DirName();
   ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(
-      kGraylistedPath, test_directory, false));
+      kGraylistedPath, test_directory, false, false));
   FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
       &parent_directory);
   ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_directory_cancel"))
@@ -373,7 +373,7 @@
   base::FilePath test_directory = test_file.DirName();
   base::FilePath parent_directory = test_directory.DirName();
   ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(
-      kGraylistedPath, parent_directory, false));
+      kGraylistedPath, parent_directory, false, false));
   FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest(
       &test_directory);
   ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_directory"))
diff --git a/chrome/browser/extensions/api/font_settings/font_settings_api.cc b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
index 2031cf7..cf01a95 100644
--- a/chrome/browser/extensions/api/font_settings/font_settings_api.cc
+++ b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
@@ -298,7 +298,7 @@
   return true;
 }
 
-bool FontSettingsGetFontListFunction::RunImpl() {
+bool FontSettingsGetFontListFunction::RunAsync() {
   content::GetFontListAsync(
       Bind(&FontSettingsGetFontListFunction::FontListHasLoaded, this));
   return true;
diff --git a/chrome/browser/extensions/api/font_settings/font_settings_api.h b/chrome/browser/extensions/api/font_settings/font_settings_api.h
index 8aa6963..f5c8416 100644
--- a/chrome/browser/extensions/api/font_settings/font_settings_api.h
+++ b/chrome/browser/extensions/api/font_settings/font_settings_api.h
@@ -142,7 +142,7 @@
   virtual ~FontSettingsGetFontListFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void FontListHasLoaded(scoped_ptr<base::ListValue> list);
diff --git a/chrome/browser/extensions/api/gcm/gcm_api.cc b/chrome/browser/extensions/api/gcm/gcm_api.cc
index 7fe632a..343299c 100644
--- a/chrome/browser/extensions/api/gcm/gcm_api.cc
+++ b/chrome/browser/extensions/api/gcm/gcm_api.cc
@@ -78,7 +78,7 @@
 
 namespace extensions {
 
-bool GcmApiFunction::RunImpl() {
+bool GcmApiFunction::RunAsync() {
   if (!IsGcmApiEnabled())
     return false;
 
diff --git a/chrome/browser/extensions/api/gcm/gcm_api.h b/chrome/browser/extensions/api/gcm/gcm_api.h
index 07009a1..e5447c0 100644
--- a/chrome/browser/extensions/api/gcm/gcm_api.h
+++ b/chrome/browser/extensions/api/gcm/gcm_api.h
@@ -26,7 +26,7 @@
   virtual ~GcmApiFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE FINAL;
+  virtual bool RunAsync() OVERRIDE FINAL;
 
   // Actual implementation of specific functions.
   virtual bool DoWork() = 0;
diff --git a/chrome/browser/extensions/api/history/history_api.cc b/chrome/browser/extensions/api/history/history_api.cc
index 51670d2..bf06088 100644
--- a/chrome/browser/extensions/api/history/history_api.cc
+++ b/chrome/browser/extensions/api/history/history_api.cc
@@ -270,7 +270,7 @@
 HistoryFunctionWithCallback::~HistoryFunctionWithCallback() {
 }
 
-bool HistoryFunctionWithCallback::RunImpl() {
+bool HistoryFunctionWithCallback::RunAsync() {
   AddRef();  // Balanced in SendAysncRepose() and below.
   bool retval = RunAsyncImpl();
   if (false == retval)
@@ -286,7 +286,7 @@
 
 void HistoryFunctionWithCallback::SendResponseToCallback() {
   SendResponse(true);
-  Release();  // Balanced in RunImpl().
+  Release();  // Balanced in RunAsync().
 }
 
 bool HistoryGetVisitsFunction::RunAsyncImpl() {
@@ -370,7 +370,7 @@
   SendAsyncResponse();
 }
 
-bool HistoryAddUrlFunction::RunImpl() {
+bool HistoryAddUrlFunction::RunAsync() {
   scoped_ptr<AddUrl::Params> params(AddUrl::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -386,7 +386,7 @@
   return true;
 }
 
-bool HistoryDeleteUrlFunction::RunImpl() {
+bool HistoryDeleteUrlFunction::RunAsync() {
   scoped_ptr<DeleteUrl::Params> params(DeleteUrl::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
diff --git a/chrome/browser/extensions/api/history/history_api.h b/chrome/browser/extensions/api/history/history_api.h
index 3b13b28..32040b5 100644
--- a/chrome/browser/extensions/api/history/history_api.h
+++ b/chrome/browser/extensions/api/history/history_api.h
@@ -105,7 +105,7 @@
   virtual ~HistoryFunctionWithCallback();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Return true if the async call was completed, false otherwise.
   virtual bool RunAsyncImpl() = 0;
@@ -164,7 +164,7 @@
   virtual ~HistoryAddUrlFunction() {}
 
   // HistoryFunctionWithCallback:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class HistoryDeleteAllFunction : public HistoryFunctionWithCallback {
@@ -190,7 +190,7 @@
   virtual ~HistoryDeleteUrlFunction() {}
 
   // HistoryFunctionWithCallback:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class HistoryDeleteRangeFunction : public HistoryFunctionWithCallback {
diff --git a/chrome/browser/extensions/api/hotword_private/hotword_private_api.cc b/chrome/browser/extensions/api/hotword_private/hotword_private_api.cc
index 4dc9218..42bbe18 100644
--- a/chrome/browser/extensions/api/hotword_private/hotword_private_api.cc
+++ b/chrome/browser/extensions/api/hotword_private/hotword_private_api.cc
@@ -7,6 +7,7 @@
 #include "base/lazy_instance.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search/hotword_client.h"
 #include "chrome/browser/search/hotword_service.h"
 #include "chrome/browser/search/hotword_service_factory.h"
 #include "chrome/common/pref_names.h"
@@ -51,17 +52,23 @@
 void HotwordPrivateEventService::OnEnabledChanged(
     const std::string& pref_name) {
   DCHECK_EQ(pref_name, std::string(prefs::kHotwordSearchEnabled));
-  SignalEvent();
+  SignalEvent(OnEnabledChanged::kEventName);
 }
 
-void HotwordPrivateEventService::SignalEvent() {
-  using OnEnabledChanged::kEventName;
+void HotwordPrivateEventService::OnHotwordSessionRequested() {
+  SignalEvent(api::hotword_private::OnHotwordSessionRequested::kEventName);
+}
 
+void HotwordPrivateEventService::OnHotwordSessionStopped() {
+  SignalEvent(api::hotword_private::OnHotwordSessionStopped::kEventName);
+}
+
+void HotwordPrivateEventService::SignalEvent(const std::string& event_name) {
   EventRouter* router = EventRouter::Get(profile_);
-  if (!router || !router->HasEventListener(kEventName))
+  if (!router || !router->HasEventListener(event_name))
     return;
   scoped_ptr<base::ListValue> args(new base::ListValue());
-  scoped_ptr<Event> event(new Event(kEventName, args.Pass()));
+  scoped_ptr<Event> event(new Event(event_name, args.Pass()));
   router->BroadcastEvent(event.Pass());
 }
 
@@ -106,4 +113,24 @@
   return true;
 }
 
+bool HotwordPrivateSetHotwordSessionStateFunction::RunSync() {
+  scoped_ptr<api::hotword_private::SetHotwordSessionState::Params> params(
+      api::hotword_private::SetHotwordSessionState::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+
+  HotwordService* hotword_service =
+      HotwordServiceFactory::GetForProfile(GetProfile());
+  if (hotword_service && hotword_service->client())
+    hotword_service->client()->OnHotwordStateChanged(params->started);
+  return true;
+}
+
+bool HotwordPrivateNotifyHotwordRecognitionFunction::RunSync() {
+  HotwordService* hotword_service =
+      HotwordServiceFactory::GetForProfile(GetProfile());
+  if (hotword_service && hotword_service->client())
+    hotword_service->client()->OnHotwordRecognized();
+  return true;
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/hotword_private/hotword_private_api.h b/chrome/browser/extensions/api/hotword_private/hotword_private_api.h
index bd07501..0a409f4 100644
--- a/chrome/browser/extensions/api/hotword_private/hotword_private_api.h
+++ b/chrome/browser/extensions/api/hotword_private/hotword_private_api.h
@@ -30,10 +30,14 @@
 
   void OnEnabledChanged(const std::string& pref_name);
 
+  void OnHotwordSessionRequested();
+
+  void OnHotwordSessionStopped();
+
  private:
   friend class BrowserContextKeyedAPIFactory<HotwordPrivateEventService>;
 
-  void SignalEvent();
+  void SignalEvent(const std::string& event_name);
 
   Profile* profile_;
   PrefChangeRegistrar pref_change_registrar_;
@@ -77,6 +81,32 @@
   virtual bool RunSync() OVERRIDE;
 };
 
+class HotwordPrivateSetHotwordSessionStateFunction
+    : public ChromeSyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("hotwordPrivate.setHotwordSessionState",
+                             HOTWORDPRIVATE_SETHOTWORDSESSIONSTATE);
+
+ protected:
+  virtual ~HotwordPrivateSetHotwordSessionStateFunction() {}
+
+  // ExtensionFunction:
+  virtual bool RunSync() OVERRIDE;
+};
+
+class HotwordPrivateNotifyHotwordRecognitionFunction
+    : public ChromeSyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("hotwordPrivate.notifyHotwordRecognition",
+                             HOTWORDPRIVATE_NOTIFYHOTWORDRECOGNITION);
+
+ protected:
+  virtual ~HotwordPrivateNotifyHotwordRecognitionFunction() {}
+
+  // ExtensionFunction:
+  virtual bool RunSync() OVERRIDE;
+};
+
 }  // namespace extensions
 
 #endif  // CHROME_BROWSER_EXTENSIONS_API_HOTWORD_PRIVATE_HOTWORD_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/hotword_private/hotword_private_apitest.cc b/chrome/browser/extensions/api/hotword_private/hotword_private_apitest.cc
index bd7c08f..8773ee5 100644
--- a/chrome/browser/extensions/api/hotword_private/hotword_private_apitest.cc
+++ b/chrome/browser/extensions/api/hotword_private/hotword_private_apitest.cc
@@ -8,6 +8,7 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_test_message_listener.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search/hotword_client.h"
 #include "chrome/browser/search/hotword_service.h"
 #include "chrome/browser/search/hotword_service_factory.h"
 #include "chrome/common/pref_names.h"
@@ -38,6 +39,37 @@
   DISALLOW_COPY_AND_ASSIGN(MockHotwordService);
 };
 
+class MockHotwordClient : public HotwordClient {
+ public:
+  MockHotwordClient()
+      : last_enabled_(false),
+        state_changed_count_(0),
+        recognized_count_(0) {
+  }
+
+  virtual ~MockHotwordClient() {}
+
+  virtual void OnHotwordStateChanged(bool enabled) OVERRIDE {
+    last_enabled_ = enabled;
+    state_changed_count_++;
+  }
+
+  virtual void OnHotwordRecognized() OVERRIDE {
+    recognized_count_++;
+  }
+
+  bool last_enabled() const { return last_enabled_; }
+  int state_changed_count() const { return state_changed_count_; }
+  int recognized_count() const { return recognized_count_; }
+
+ private:
+  bool last_enabled_;
+  int state_changed_count_;
+  int recognized_count_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockHotwordClient);
+};
+
 class HotwordPrivateApiTest : public ExtensionApiTest {
  public:
   HotwordPrivateApiTest() {}
@@ -69,12 +101,12 @@
   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled));
 
   ExtensionTestMessageListener listenerTrue("ready", false);
-  EXPECT_TRUE(RunComponentExtensionTest("setEnabledTrue")) << message_;
+  ASSERT_TRUE(RunComponentExtensionTest("setEnabledTrue")) << message_;
   EXPECT_TRUE(listenerTrue.WaitUntilSatisfied());
   EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled));
 
   ExtensionTestMessageListener listenerFalse("ready", false);
-  EXPECT_TRUE(RunComponentExtensionTest("setEnabledFalse")) << message_;
+  ASSERT_TRUE(RunComponentExtensionTest("setEnabledFalse")) << message_;
   EXPECT_TRUE(listenerFalse.WaitUntilSatisfied());
   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled));
 }
@@ -85,16 +117,16 @@
       prefs::kHotwordAudioLoggingEnabled));
 
   ExtensionTestMessageListener listenerTrue("ready", false);
-  EXPECT_TRUE(
-      RunComponentExtensionTest("setAudioLoggingEnableTrue")) << message_;
+  ASSERT_TRUE(RunComponentExtensionTest("setAudioLoggingEnableTrue"))
+      << message_;
   EXPECT_TRUE(listenerTrue.WaitUntilSatisfied());
   EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
       prefs::kHotwordAudioLoggingEnabled));
   EXPECT_TRUE(service()->IsOptedIntoAudioLogging());
 
   ExtensionTestMessageListener listenerFalse("ready", false);
-  EXPECT_TRUE(
-      RunComponentExtensionTest("setAudioLoggingEnableFalse")) << message_;
+  ASSERT_TRUE(RunComponentExtensionTest("setAudioLoggingEnableFalse"))
+      << message_;
   EXPECT_TRUE(listenerFalse.WaitUntilSatisfied());
   EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(
       prefs::kHotwordAudioLoggingEnabled));
@@ -102,20 +134,20 @@
 }
 
 IN_PROC_BROWSER_TEST_F(HotwordPrivateApiTest, GetStatus) {
-  EXPECT_TRUE(RunComponentExtensionTest("getEnabled")) << message_;
+  ASSERT_TRUE(RunComponentExtensionTest("getEnabled")) << message_;
 }
 
 IN_PROC_BROWSER_TEST_F(HotwordPrivateApiTest, IsAvailableTrue) {
   service()->setServiceAvailable(true);
   ExtensionTestMessageListener listener("available: true", false);
-  EXPECT_TRUE(RunComponentExtensionTest("isAvailable")) << message_;
+  ASSERT_TRUE(RunComponentExtensionTest("isAvailable")) << message_;
   EXPECT_TRUE(listener.WaitUntilSatisfied());
 }
 
 IN_PROC_BROWSER_TEST_F(HotwordPrivateApiTest, IsAvailableFalse) {
   service()->setServiceAvailable(false);
   ExtensionTestMessageListener listener("available: false", false);
-  EXPECT_TRUE(RunComponentExtensionTest("isAvailable")) << message_;
+  ASSERT_TRUE(RunComponentExtensionTest("isAvailable")) << message_;
   EXPECT_TRUE(listener.WaitUntilSatisfied());
 }
 
@@ -123,11 +155,31 @@
   // Trigger the pref registrar.
   extensions::HotwordPrivateEventService::GetFactoryInstance();
   ExtensionTestMessageListener listener("ready", false);
-  LoadExtensionAsComponent(
-      test_data_dir_.AppendASCII("onEnabledChanged"));
+  ASSERT_TRUE(
+      LoadExtensionAsComponent(test_data_dir_.AppendASCII("onEnabledChanged")));
   EXPECT_TRUE(listener.WaitUntilSatisfied());
 
   ExtensionTestMessageListener listenerNotification("notification", false);
   profile()->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, true);
   EXPECT_TRUE(listenerNotification.WaitUntilSatisfied());
 }
+
+IN_PROC_BROWSER_TEST_F(HotwordPrivateApiTest, HotwordSession) {
+  extensions::HotwordPrivateEventService::GetFactoryInstance();
+  ExtensionTestMessageListener listener("ready", false);
+  LoadExtensionAsComponent(
+      test_data_dir_.AppendASCII("hotwordSession"));
+  EXPECT_TRUE(listener.WaitUntilSatisfied());
+
+  ExtensionTestMessageListener listenerStopReady("stopReady", false);
+  ExtensionTestMessageListener listenerStopped("stopped", false);
+  MockHotwordClient client;
+  service()->RequestHotwordSession(&client);
+  EXPECT_TRUE(listenerStopReady.WaitUntilSatisfied());
+  service()->StopHotwordSession(&client);
+  EXPECT_TRUE(listenerStopped.WaitUntilSatisfied());
+
+  EXPECT_TRUE(client.last_enabled());
+  EXPECT_EQ(1, client.state_changed_count());
+  EXPECT_EQ(1, client.recognized_count());
+}
diff --git a/chrome/browser/extensions/api/identity/identity_api.cc b/chrome/browser/extensions/api/identity/identity_api.cc
index 65dc4a7..df6fdbd 100644
--- a/chrome/browser/extensions/api/identity/identity_api.cc
+++ b/chrome/browser/extensions/api/identity/identity_api.cc
@@ -230,7 +230,7 @@
 
 IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() {}
 
-bool IdentityGetAuthTokenFunction::RunImpl() {
+bool IdentityGetAuthTokenFunction::RunAsync() {
   if (GetProfile()->IsOffTheRecord()) {
     error_ = identity_constants::kOffTheRecord;
     return false;
@@ -710,7 +710,7 @@
     auth_flow_.release()->DetachDelegateAndDelete();
 }
 
-bool IdentityLaunchWebAuthFlowFunction::RunImpl() {
+bool IdentityLaunchWebAuthFlowFunction::RunAsync() {
   if (GetProfile()->IsOffTheRecord()) {
     error_ = identity_constants::kOffTheRecord;
     return false;
@@ -767,7 +767,7 @@
       break;
   }
   SendResponse(false);
-  Release();  // Balanced in RunImpl.
+  Release();  // Balanced in RunAsync.
 }
 
 void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange(
@@ -775,7 +775,7 @@
   if (redirect_url.GetWithEmptyPath() == final_url_prefix_) {
     SetResult(new base::StringValue(redirect_url.spec()));
     SendResponse(true);
-    Release();  // Balanced in RunImpl.
+    Release();  // Balanced in RunAsync.
   }
 }
 
diff --git a/chrome/browser/extensions/api/identity/identity_api.h b/chrome/browser/extensions/api/identity/identity_api.h
index 79b5ee0..a434620 100644
--- a/chrome/browser/extensions/api/identity/identity_api.h
+++ b/chrome/browser/extensions/api/identity/identity_api.h
@@ -184,7 +184,7 @@
   friend class MockGetAuthTokenFunction;
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Helpers to report async function results to the caller.
   void StartAsyncRun();
@@ -300,7 +300,7 @@
 
  private:
   virtual ~IdentityLaunchWebAuthFlowFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // WebAuthFlow::Delegate implementation.
   virtual void OnAuthFlowFailure(WebAuthFlow::Failure failure) OVERRIDE;
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc
index 3b18d52..48a392a 100644
--- a/chrome/browser/extensions/api/identity/identity_apitest.cc
+++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -48,7 +48,7 @@
 static const char kAccessToken[] = "auth_token";
 static const char kExtensionId[] = "ext_id";
 
-// This helps us be able to wait until an AsyncExtensionFunction calls
+// This helps us be able to wait until an UIThreadExtensionFunction calls
 // SendResponse.
 class SendResponseDelegate
     : public UIThreadExtensionFunction::DelegateForTests {
@@ -109,7 +109,7 @@
 
     function->set_browser_context(browser()->profile());
     function->set_has_callback(true);
-    function->Run();
+    function->Run()->Execute();
   }
 
   std::string WaitForError(UIThreadExtensionFunction* function) {
@@ -132,7 +132,7 @@
 
  private:
   void RunMessageLoopUntilResponse() {
-    // If the RunImpl of |function| didn't already call SendResponse, run the
+    // If the RunAsync of |function| didn't already call SendResponse, run the
     // message loop until they do.
     if (!response_delegate_->HasResponse()) {
       response_delegate_->set_should_post_quit(true);
diff --git a/chrome/browser/extensions/api/identity/web_auth_flow.cc b/chrome/browser/extensions/api/identity/web_auth_flow.cc
index 8235a03..2a88e48 100644
--- a/chrome/browser/extensions/api/identity/web_auth_flow.cc
+++ b/chrome/browser/extensions/api/identity/web_auth_flow.cc
@@ -110,7 +110,7 @@
 
 void WebAuthFlow::OnAppWindowAdded(AppWindow* app_window) {
   if (app_window->window_key() == app_window_key_ &&
-      app_window->extension()->id() == extension_misc::kIdentityApiUiAppId) {
+      app_window->extension_id() == extension_misc::kIdentityApiUiAppId) {
     app_window_ = app_window;
     WebContentsObserver::Observe(app_window->web_contents());
 
@@ -121,11 +121,9 @@
   }
 }
 
-void WebAuthFlow::OnAppWindowIconChanged(AppWindow* app_window) {}
-
 void WebAuthFlow::OnAppWindowRemoved(AppWindow* app_window) {
   if (app_window->window_key() == app_window_key_ &&
-      app_window->extension()->id() == extension_misc::kIdentityApiUiAppId) {
+      app_window->extension_id() == extension_misc::kIdentityApiUiAppId) {
     app_window_ = NULL;
     registrar_.RemoveAll();
 
diff --git a/chrome/browser/extensions/api/identity/web_auth_flow.h b/chrome/browser/extensions/api/identity/web_auth_flow.h
index 169cc32..ba7e8ab 100644
--- a/chrome/browser/extensions/api/identity/web_auth_flow.h
+++ b/chrome/browser/extensions/api/identity/web_auth_flow.h
@@ -93,7 +93,6 @@
 
   // ::AppWindowRegistry::Observer implementation.
   virtual void OnAppWindowAdded(apps::AppWindow* app_window) OVERRIDE;
-  virtual void OnAppWindowIconChanged(apps::AppWindow* app_window) OVERRIDE;
   virtual void OnAppWindowRemoved(apps::AppWindow* app_window) OVERRIDE;
 
   // NotificationObserver implementation.
diff --git a/chrome/browser/extensions/api/idle/idle_api.cc b/chrome/browser/extensions/api/idle/idle_api.cc
index a04d739..a80d0cf 100644
--- a/chrome/browser/extensions/api/idle/idle_api.cc
+++ b/chrome/browser/extensions/api/idle/idle_api.cc
@@ -30,7 +30,7 @@
 
 namespace extensions {
 
-bool IdleQueryStateFunction::RunImpl() {
+bool IdleQueryStateFunction::RunAsync() {
   int threshold;
   EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &threshold));
   threshold = ClampThreshold(threshold);
diff --git a/chrome/browser/extensions/api/idle/idle_api.h b/chrome/browser/extensions/api/idle/idle_api.h
index 79070e4..6e18f47 100644
--- a/chrome/browser/extensions/api/idle/idle_api.h
+++ b/chrome/browser/extensions/api/idle/idle_api.h
@@ -19,7 +19,7 @@
   virtual ~IdleQueryStateFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void IdleStateCallback(IdleState state);
diff --git a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc
index e89d460..54453c5 100644
--- a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc
+++ b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc
@@ -21,7 +21,7 @@
     ~ImageWriterPrivateWriteFromUrlFunction() {
 }
 
-bool ImageWriterPrivateWriteFromUrlFunction::RunImpl() {
+bool ImageWriterPrivateWriteFromUrlFunction::RunAsync() {
   scoped_ptr<image_writer_api::WriteFromUrl::Params> params(
       image_writer_api::WriteFromUrl::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -65,7 +65,7 @@
     ~ImageWriterPrivateWriteFromFileFunction() {
 }
 
-bool ImageWriterPrivateWriteFromFileFunction::RunImpl() {
+bool ImageWriterPrivateWriteFromFileFunction::RunAsync() {
   std::string filesystem_name;
   std::string filesystem_path;
   std::string storage_unit_id;
@@ -109,7 +109,7 @@
     ~ImageWriterPrivateCancelWriteFunction() {
 }
 
-bool ImageWriterPrivateCancelWriteFunction::RunImpl() {
+bool ImageWriterPrivateCancelWriteFunction::RunAsync() {
   image_writer::OperationManager::Get(GetProfile())->CancelWrite(
       extension_id(),
       base::Bind(&ImageWriterPrivateCancelWriteFunction::OnWriteCancelled,
@@ -134,7 +134,7 @@
     ~ImageWriterPrivateDestroyPartitionsFunction() {
 }
 
-bool ImageWriterPrivateDestroyPartitionsFunction::RunImpl() {
+bool ImageWriterPrivateDestroyPartitionsFunction::RunAsync() {
   scoped_ptr<image_writer_api::DestroyPartitions::Params> params(
       image_writer_api::DestroyPartitions::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -166,7 +166,7 @@
   ~ImageWriterPrivateListRemovableStorageDevicesFunction() {
 }
 
-bool ImageWriterPrivateListRemovableStorageDevicesFunction::RunImpl() {
+bool ImageWriterPrivateListRemovableStorageDevicesFunction::RunAsync() {
   RemovableStorageProvider::GetAllDevices(
     base::Bind(
       &ImageWriterPrivateListRemovableStorageDevicesFunction::OnDeviceListReady,
diff --git a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h
index 9cccd0f..56ee446 100644
--- a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h
+++ b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h
@@ -19,7 +19,7 @@
 
  private:
   virtual ~ImageWriterPrivateWriteFromUrlFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void OnWriteStarted(bool success, const std::string& error);
 };
 
@@ -32,7 +32,7 @@
 
  private:
   virtual ~ImageWriterPrivateWriteFromFileFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void OnWriteStarted(bool success, const std::string& error);
 };
 
@@ -45,7 +45,7 @@
 
  private:
   virtual ~ImageWriterPrivateCancelWriteFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void OnWriteCancelled(bool success, const std::string& error);
 };
 
@@ -58,7 +58,7 @@
 
  private:
   virtual ~ImageWriterPrivateDestroyPartitionsFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void OnDestroyComplete(bool success, const std::string& error);
 };
 
@@ -71,7 +71,7 @@
 
  private:
   virtual ~ImageWriterPrivateListRemovableStorageDevicesFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void OnDeviceListReady(scoped_refptr<StorageDeviceList> device_list,
                          bool success);
 };
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc
index 9f6385d..1c907a5 100644
--- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc
+++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc
@@ -22,7 +22,7 @@
   return result;
 }
 
-static int get_device_blk_size(std::string path) {
+static int get_device_blk_size(const std::string& path) {
   base::FilePath file_path(path);
   std::string device = file_path.BaseName().value();
 
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.cc b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
index 8f05189..f37bac0 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api.cc
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
@@ -161,19 +161,24 @@
     if (profile_ == NULL || extension_id_.empty())
       return;
 
+    // If there is no listener for the event, no need to dispatch the event to
+    // extension. Instead, releases the key event for default system behavior.
+    if (!HasKeyEventListener()) {
+      // Continue processing the key event so that the physical keyboard can
+      // still work.
+      base::Callback<void(bool consumed)>* callback =
+          reinterpret_cast<base::Callback<void(bool consumed)>*>(key_data);
+      callback->Run(false);
+      delete callback;
+      return;
+    }
+
     extensions::InputImeEventRouter* ime_event_router =
         extensions::InputImeEventRouter::GetInstance();
 
     const std::string request_id =
         ime_event_router->AddRequest(engine_id, key_data);
 
-    // If there is no listener for the event, no need to dispatch the event to
-    // extension. Instead, releases the key event for default system behavior.
-    if (!HasKeyEventListener()) {
-      ime_event_router->OnKeyEventHandled(extension_id_, request_id, false);
-      return;
-    }
-
     input_ime::KeyboardEvent key_data_value;
     key_data_value.type = input_ime::KeyboardEvent::ParseType(event.type);
     key_data_value.request_id = request_id;
@@ -516,7 +521,7 @@
   return true;
 }
 
-bool InputImeHideInputViewFunction::RunImpl() {
+bool InputImeHideInputViewFunction::RunAsync() {
   InputMethodEngineInterface* engine =
       InputImeEventRouter::GetInstance()->GetActiveEngine(extension_id());
   if (!engine) {
@@ -526,7 +531,7 @@
   return true;
 }
 
-bool InputImeSendKeyEventsFunction::RunImpl() {
+bool InputImeSendKeyEventsFunction::RunAsync() {
   scoped_ptr<SendKeyEvents::Params> parent_params(
       SendKeyEvents::Params::Create(*args_));
   const SendKeyEvents::Params::Parameters& params =
@@ -765,7 +770,7 @@
   return true;
 }
 
-bool InputImeKeyEventHandledFunction::RunImpl() {
+bool InputImeKeyEventHandledFunction::RunAsync() {
   scoped_ptr<KeyEventHandled::Params> params(
       KeyEventHandled::Params::Create(*args_));
   InputImeEventRouter::GetInstance()->OnKeyEventHandled(
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.h b/chrome/browser/extensions/api/input_ime/input_ime_api.h
index 2f0d833..773d13b 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api.h
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api.h
@@ -192,7 +192,7 @@
   virtual ~InputImeKeyEventHandledFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class InputImeSendKeyEventsFunction : public AsyncExtensionFunction {
@@ -204,7 +204,7 @@
   virtual ~InputImeSendKeyEventsFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class InputImeHideInputViewFunction : public AsyncExtensionFunction {
@@ -216,7 +216,7 @@
   virtual ~InputImeHideInputViewFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class InputImeAPI : public BrowserContextKeyedAPI,
diff --git a/chrome/browser/extensions/api/log_private/log_private_api.h b/chrome/browser/extensions/api/log_private/log_private_api.h
index 24c8fcd..2b6648b 100644
--- a/chrome/browser/extensions/api/log_private/log_private_api.h
+++ b/chrome/browser/extensions/api/log_private/log_private_api.h
@@ -85,7 +85,7 @@
 
  protected:
   virtual ~LogPrivateGetHistoricalFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnSystemLogsLoaded(scoped_ptr<system_logs::SystemLogsResponse> sys_info);
diff --git a/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc b/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc
index e0ffc17..8cce97f 100644
--- a/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc
+++ b/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc
@@ -174,7 +174,7 @@
 LogPrivateGetHistoricalFunction::~LogPrivateGetHistoricalFunction() {
 }
 
-bool LogPrivateGetHistoricalFunction::RunImpl() {
+bool LogPrivateGetHistoricalFunction::RunAsync() {
   // Get parameters
   scoped_ptr<api::log_private::GetHistorical::Params> params(
       api::log_private::GetHistorical::Params::Create(*args_));
diff --git a/chrome/browser/extensions/api/management/management_api.cc b/chrome/browser/extensions/api/management/management_api.cc
index 2384461..86f67ef 100644
--- a/chrome/browser/extensions/api/management/management_api.cc
+++ b/chrome/browser/extensions/api/management/management_api.cc
@@ -25,6 +25,9 @@
 #include "chrome/browser/extensions/extension_uninstall_dialog.h"
 #include "chrome/browser/extensions/launch_util.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser_dialogs.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
 #include "chrome/common/chrome_utility_messages.h"
@@ -373,7 +376,7 @@
 
 }  // namespace
 
-bool ManagementGetPermissionWarningsByManifestFunction::RunImpl() {
+bool ManagementGetPermissionWarningsByManifestFunction::RunAsync() {
   scoped_ptr<management::GetPermissionWarningsByManifest::Params> params(
       management::GetPermissionWarningsByManifest::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -406,7 +409,7 @@
       management::GetPermissionWarningsByManifest::Results::Create(warnings);
   SendResponse(true);
 
-  // Matched with AddRef() in RunImpl().
+  // Matched with AddRef() in RunAsync().
   Release();
 }
 
@@ -415,7 +418,7 @@
   error_ = error;
   SendResponse(false);
 
-  // Matched with AddRef() in RunImpl().
+  // Matched with AddRef() in RunAsync().
   Release();
 }
 
@@ -457,7 +460,7 @@
 ManagementSetEnabledFunction::~ManagementSetEnabledFunction() {
 }
 
-bool ManagementSetEnabledFunction::RunImpl() {
+bool ManagementSetEnabledFunction::RunAsync() {
   scoped_ptr<management::SetEnabled::Params> params(
       management::SetEnabled::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -608,7 +611,7 @@
 ManagementUninstallFunction::~ManagementUninstallFunction() {
 }
 
-bool ManagementUninstallFunction::RunImpl() {
+bool ManagementUninstallFunction::RunAsync() {
   scoped_ptr<management::Uninstall::Params> params(
       management::Uninstall::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(extension_);
@@ -635,7 +638,7 @@
 ManagementUninstallSelfFunction::~ManagementUninstallSelfFunction() {
 }
 
-bool ManagementUninstallSelfFunction::RunImpl() {
+bool ManagementUninstallSelfFunction::RunAsync() {
   scoped_ptr<management::UninstallSelf::Params> params(
       management::UninstallSelf::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -646,6 +649,77 @@
   return Uninstall(extension_->id(), show_confirm_dialog);
 }
 
+ManagementCreateAppShortcutFunction::ManagementCreateAppShortcutFunction() {
+}
+
+ManagementCreateAppShortcutFunction::~ManagementCreateAppShortcutFunction() {
+}
+
+// static
+void ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(
+    bool should_proceed) {
+  auto_confirm_for_test = should_proceed ? PROCEED : ABORT;
+}
+
+void ManagementCreateAppShortcutFunction::OnCloseShortcutPrompt(bool created) {
+  if (!created)
+    error_ = keys::kCreateShortcutCanceledError;
+  SendResponse(created);
+  Release();
+}
+
+bool ManagementCreateAppShortcutFunction::RunAsync() {
+  if (!user_gesture()) {
+    error_ = keys::kGestureNeededForCreateAppShortcutError;
+    return false;
+  }
+
+  scoped_ptr<management::CreateAppShortcut::Params> params(
+      management::CreateAppShortcut::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+  const Extension* extension = service()->GetExtensionById(params->id, true);
+  if (!extension) {
+    error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
+                                            params->id);
+    return false;
+  }
+
+  if (!extension->is_app()) {
+    error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id);
+    return false;
+  }
+
+#if defined(OS_MACOSX)
+  if (!extension->is_platform_app()) {
+    error_ = keys::kCreateOnlyPackagedAppShortcutMac;
+    return false;
+  }
+#endif
+
+  Browser* browser = chrome::FindBrowserWithProfile(
+      GetProfile(), chrome::HOST_DESKTOP_TYPE_NATIVE);
+  if (!browser) {
+    // Shouldn't happen if we have user gesture.
+    error_ = keys::kNoBrowserToCreateShortcut;
+    return false;
+  }
+
+  // Matched with a Release() in OnCloseShortcutPrompt().
+  AddRef();
+
+  if (auto_confirm_for_test == DO_NOT_SKIP) {
+    chrome::ShowCreateChromeAppShortcutsDialog(
+        browser->window()->GetNativeWindow(), browser->profile(), extension,
+        base::Bind(&ManagementCreateAppShortcutFunction::OnCloseShortcutPrompt,
+           this));
+  } else {
+    OnCloseShortcutPrompt(auto_confirm_for_test == PROCEED);
+  }
+
+  // Response is sent async in OnCloseShortcutPrompt().
+  return true;
+}
+
 ManagementEventRouter::ManagementEventRouter(Profile* profile)
     : profile_(profile) {
   int types[] = {chrome::NOTIFICATION_EXTENSION_INSTALLED,
diff --git a/chrome/browser/extensions/api/management/management_api.h b/chrome/browser/extensions/api/management/management_api.h
index c2f26d9..3c348c9 100644
--- a/chrome/browser/extensions/api/management/management_api.h
+++ b/chrome/browser/extensions/api/management/management_api.h
@@ -83,7 +83,7 @@
   virtual ~ManagementGetPermissionWarningsByManifestFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class ManagementLaunchAppFunction : public ManagementFunction {
@@ -108,7 +108,7 @@
   virtual ~ManagementSetEnabledFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // ExtensionInstallPrompt::Delegate.
   virtual void InstallUIProceed() OVERRIDE;
@@ -140,7 +140,7 @@
 
   // If should_uninstall is true, this method does the actual uninstall.
   // If |show_uninstall_dialog|, then this function will be called by one of the
-  // Accepted/Canceled callbacks. Otherwise, it's called directly from RunImpl.
+  // Accepted/Canceled callbacks. Otherwise, it's called directly from RunAsync.
   void Finish(bool should_uninstall);
 
   std::string extension_id_;
@@ -156,7 +156,7 @@
  private:
   virtual ~ManagementUninstallFunction();
 
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class ManagementUninstallSelfFunction : public ManagementUninstallFunctionBase {
@@ -169,7 +169,24 @@
  private:
   virtual ~ManagementUninstallSelfFunction();
 
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
+};
+
+class ManagementCreateAppShortcutFunction : public AsyncManagementFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("management.createAppShortcut",
+      MANAGEMENT_CREATEAPPSHORTCUT);
+
+  ManagementCreateAppShortcutFunction();
+
+  void OnCloseShortcutPrompt(bool created);
+
+  static void SetAutoConfirmForTest(bool should_proceed);
+
+ protected:
+  virtual ~ManagementCreateAppShortcutFunction();
+
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class ManagementEventRouter : public content::NotificationObserver {
diff --git a/chrome/browser/extensions/api/management/management_api_browsertest.cc b/chrome/browser/extensions/api/management/management_api_browsertest.cc
index 2227a3c..fc13267 100644
--- a/chrome/browser/extensions/api/management/management_api_browsertest.cc
+++ b/chrome/browser/extensions/api/management/management_api_browsertest.cc
@@ -146,6 +146,34 @@
 }
 
 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
+                       CreateAppShortcutConfirmDialog) {
+  const Extension* app = InstallExtension(
+      test_data_dir_.AppendASCII("api_test/management/packaged_app"), 1);
+  ASSERT_TRUE(app);
+
+  const std::string app_id = app->id();
+
+  scoped_refptr<ManagementCreateAppShortcutFunction> create_shortcut_function(
+      new ManagementCreateAppShortcutFunction());
+  create_shortcut_function->set_user_gesture(true);
+  ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(true);
+  util::RunFunctionAndReturnSingleResult(
+      create_shortcut_function.get(),
+      base::StringPrintf("[\"%s\"]", app_id.c_str()),
+      browser());
+
+  create_shortcut_function = new ManagementCreateAppShortcutFunction();
+  create_shortcut_function->set_user_gesture(true);
+  ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(false);
+  EXPECT_TRUE(MatchPattern(
+      util::RunFunctionAndReturnError(
+          create_shortcut_function.get(),
+          base::StringPrintf("[\"%s\"]", app_id.c_str()),
+          browser()),
+      keys::kCreateShortcutCanceledError));
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
                        GetAllIncludesTerminated) {
   // Load an extension with a background page, so that we know it has a process
   // running.
diff --git a/chrome/browser/extensions/api/management/management_api_constants.cc b/chrome/browser/extensions/api/management/management_api_constants.cc
index 8be22c7..71eeda1 100644
--- a/chrome/browser/extensions/api/management/management_api_constants.cc
+++ b/chrome/browser/extensions/api/management/management_api_constants.cc
@@ -25,5 +25,13 @@
     "Extension * uninstall canceled by user.";
 const char kUserDidNotReEnableError[] =
     "The user did not accept the re-enable dialog.";
+const char kGestureNeededForCreateAppShortcutError[] =
+    "chrome.management.createAppShortcut requires a user gesture.";
+const char kNoBrowserToCreateShortcut[] =
+    "There is no browser window to create shortcut.";
+const char kCreateOnlyPackagedAppShortcutMac[] =
+    "Shortcuts can only be created for new-style packaged apps on Mac.";
+const char kCreateShortcutCanceledError[] =
+    "App shortcuts creation canceled by user.";
 
 }  // namespace extension_management_api_constants
diff --git a/chrome/browser/extensions/api/management/management_api_constants.h b/chrome/browser/extensions/api/management/management_api_constants.h
index 3111810..a63448a 100644
--- a/chrome/browser/extensions/api/management/management_api_constants.h
+++ b/chrome/browser/extensions/api/management/management_api_constants.h
@@ -23,6 +23,10 @@
 extern const char kUserCantModifyError[];
 extern const char kUninstallCanceledError[];
 extern const char kUserDidNotReEnableError[];
+extern const char kGestureNeededForCreateAppShortcutError[];
+extern const char kNoBrowserToCreateShortcut[];
+extern const char kCreateOnlyPackagedAppShortcutMac[];
+extern const char kCreateShortcutCanceledError[];
 
 
 }  // namespace extension_management_api_constants
diff --git a/chrome/browser/extensions/api/management/management_apitest.cc b/chrome/browser/extensions/api/management/management_apitest.cc
index 3a99f51..72d211e 100644
--- a/chrome/browser/extensions/api/management/management_apitest.cc
+++ b/chrome/browser/extensions/api/management/management_apitest.cc
@@ -131,6 +131,24 @@
   ASSERT_TRUE(RunExtensionSubtest("management/test", "uninstall.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, CreateAppShortcut) {
+  LoadExtensions();
+  base::FilePath basedir = test_data_dir_.AppendASCII("management");
+  LoadNamedExtension(basedir, "packaged_app");
+
+  extensions::ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(true);
+  ASSERT_TRUE(RunExtensionSubtest("management/test",
+                                  "createAppShortcut.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,
+                       CreateAppShortcutNotInStable) {
+  extensions::ScopedCurrentChannel channel(
+      chrome::VersionInfo::CHANNEL_STABLE);
+  ASSERT_TRUE(RunExtensionSubtest("management/test",
+                                  "createAppShortcutNotInStable.html"));
+}
+
 // Fails often on Windows dbg bots. http://crbug.com/177163
 #if defined(OS_WIN)
 #define MAYBE_ManagementPolicyAllowed DISABLED_ManagementPolicyAllowed
diff --git a/chrome/browser/extensions/api/mdns/mdns_api.cc b/chrome/browser/extensions/api/mdns/mdns_api.cc
index 2e61ec9..9bc7fb3 100644
--- a/chrome/browser/extensions/api/mdns/mdns_api.cc
+++ b/chrome/browser/extensions/api/mdns/mdns_api.cc
@@ -88,7 +88,7 @@
           .GetEventListenersByName(details.event_name);
   for (EventListenerMap::ListenerList::const_iterator it = listeners.begin();
        it != listeners.end(); ++it) {
-    base::DictionaryValue* filter = ((*it)->filter.get());
+    base::DictionaryValue* filter = ((*it)->filter());
 
     std::string filter_value;
     filter->GetStringASCII(kEventFilterServiceTypeKey, &filter_value);
diff --git a/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc b/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
index 171111b..024efde 100644
--- a/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
+++ b/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
@@ -42,7 +42,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_system.h"
@@ -228,7 +227,7 @@
       NULL,
       0,
       base::FilePath::StringType(),
-      platform_util::GetTopLevel(web_contents_->GetView()->GetNativeView()),
+      platform_util::GetTopLevel(web_contents_->GetNativeView()),
       NULL);
   }
 
@@ -368,7 +367,7 @@
 MediaGalleriesGetMediaFileSystemsFunction::
     ~MediaGalleriesGetMediaFileSystemsFunction() {}
 
-bool MediaGalleriesGetMediaFileSystemsFunction::RunImpl() {
+bool MediaGalleriesGetMediaFileSystemsFunction::RunAsync() {
   media_galleries::UsageCount(media_galleries::GET_MEDIA_FILE_SYSTEMS);
   scoped_ptr<GetMediaFileSystems::Params> params(
       GetMediaFileSystems::Params::Create(*args_));
@@ -476,7 +475,7 @@
 MediaGalleriesGetAllMediaFileSystemMetadataFunction::
     ~MediaGalleriesGetAllMediaFileSystemMetadataFunction() {}
 
-bool MediaGalleriesGetAllMediaFileSystemMetadataFunction::RunImpl() {
+bool MediaGalleriesGetAllMediaFileSystemMetadataFunction::RunAsync() {
   media_galleries::UsageCount(
       media_galleries::GET_ALL_MEDIA_FILE_SYSTEM_METADATA);
   return Setup(GetProfile(), &error_, base::Bind(
@@ -538,7 +537,7 @@
 MediaGalleriesAddUserSelectedFolderFunction::
     ~MediaGalleriesAddUserSelectedFolderFunction() {}
 
-bool MediaGalleriesAddUserSelectedFolderFunction::RunImpl() {
+bool MediaGalleriesAddUserSelectedFolderFunction::RunAsync() {
   media_galleries::UsageCount(media_galleries::ADD_USER_SELECTED_FOLDER);
   return Setup(GetProfile(), &error_, base::Bind(
       &MediaGalleriesAddUserSelectedFolderFunction::OnPreferencesInit, this));
@@ -647,7 +646,7 @@
 MediaGalleriesDropPermissionForMediaFileSystemFunction::
     ~MediaGalleriesDropPermissionForMediaFileSystemFunction() {}
 
-bool MediaGalleriesDropPermissionForMediaFileSystemFunction::RunImpl() {
+bool MediaGalleriesDropPermissionForMediaFileSystemFunction::RunAsync() {
   media_galleries::UsageCount(
       media_galleries::DROP_PERMISSION_FOR_MEDIA_FILE_SYSTEM);
 
@@ -689,7 +688,7 @@
 
 MediaGalleriesStartMediaScanFunction::~MediaGalleriesStartMediaScanFunction() {}
 
-bool MediaGalleriesStartMediaScanFunction::RunImpl() {
+bool MediaGalleriesStartMediaScanFunction::RunAsync() {
   media_galleries::UsageCount(media_galleries::START_MEDIA_SCAN);
   if (!CheckScanPermission(GetExtension(), &error_)) {
     MediaGalleriesEventRouter::Get(GetProfile())->OnScanError(
@@ -717,7 +716,7 @@
     ~MediaGalleriesCancelMediaScanFunction() {
 }
 
-bool MediaGalleriesCancelMediaScanFunction::RunImpl() {
+bool MediaGalleriesCancelMediaScanFunction::RunAsync() {
   media_galleries::UsageCount(media_galleries::CANCEL_MEDIA_SCAN);
   if (!CheckScanPermission(GetExtension(), &error_)) {
     MediaGalleriesEventRouter::Get(GetProfile())->OnScanError(
@@ -736,7 +735,7 @@
 
 MediaGalleriesAddScanResultsFunction::~MediaGalleriesAddScanResultsFunction() {}
 
-bool MediaGalleriesAddScanResultsFunction::RunImpl() {
+bool MediaGalleriesAddScanResultsFunction::RunAsync() {
   media_galleries::UsageCount(media_galleries::ADD_SCAN_RESULTS);
   if (!CheckScanPermission(GetExtension(), &error_)) {
     // We don't fire a scan progress error here, as it would be unintuitive.
@@ -811,7 +810,7 @@
 
 MediaGalleriesGetMetadataFunction::~MediaGalleriesGetMetadataFunction() {}
 
-bool MediaGalleriesGetMetadataFunction::RunImpl() {
+bool MediaGalleriesGetMetadataFunction::RunAsync() {
   std::string blob_uuid;
   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &blob_uuid));
 
diff --git a/chrome/browser/extensions/api/media_galleries/media_galleries_api.h b/chrome/browser/extensions/api/media_galleries/media_galleries_api.h
index 4a85487..94762c4 100644
--- a/chrome/browser/extensions/api/media_galleries/media_galleries_api.h
+++ b/chrome/browser/extensions/api/media_galleries/media_galleries_api.h
@@ -95,10 +95,10 @@
 
  protected:
   virtual ~MediaGalleriesGetMediaFileSystemsFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
-  // Bottom half for RunImpl, invoked after the preferences is initialized.
+  // Bottom half for RunAsync, invoked after the preferences is initialized.
   void OnPreferencesInit(
       MediaGalleries::GetMediaFileSystemsInteractivity interactive);
 
@@ -132,10 +132,10 @@
 
  protected:
   virtual ~MediaGalleriesGetAllMediaFileSystemMetadataFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
-  // Bottom half for RunImpl, invoked after the preferences is initialized.
+  // Bottom half for RunAsync, invoked after the preferences is initialized.
   // Gets the list of permitted galleries and checks if they are available.
   void OnPreferencesInit();
 
@@ -154,10 +154,10 @@
 
  protected:
   virtual ~MediaGalleriesAddUserSelectedFolderFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
-  // Bottom half for RunImpl, invoked after the preferences is initialized.
+  // Bottom half for RunAsync, invoked after the preferences is initialized.
   void OnPreferencesInit();
 
   // Callback for the directory prompt request, with the input from the user.
@@ -187,10 +187,10 @@
 
  protected:
   virtual ~MediaGalleriesDropPermissionForMediaFileSystemFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
-  // Bottom half for RunImpl, invoked after the preferences is initialized.
+  // Bottom half for RunAsync, invoked after the preferences is initialized.
   void OnPreferencesInit(MediaGalleryPrefId pref_id);
 };
 
@@ -202,10 +202,10 @@
 
  protected:
   virtual ~MediaGalleriesStartMediaScanFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
-  // Bottom half for RunImpl, invoked after the preferences is initialized.
+  // Bottom half for RunAsync, invoked after the preferences is initialized.
   void OnPreferencesInit();
 };
 
@@ -217,10 +217,10 @@
 
  protected:
   virtual ~MediaGalleriesCancelMediaScanFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
-  // Bottom half for RunImpl, invoked after the preferences is initialized.
+  // Bottom half for RunAsync, invoked after the preferences is initialized.
   void OnPreferencesInit();
 };
 
@@ -232,7 +232,7 @@
 
  protected:
   virtual ~MediaGalleriesAddScanResultsFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Pulled out for testing.
   virtual MediaGalleriesScanResultDialogController* MakeDialog(
@@ -241,7 +241,7 @@
       const base::Closure& on_finish);
 
  private:
-  // Bottom half for RunImpl, invoked after the preferences is initialized.
+  // Bottom half for RunAsync, invoked after the preferences is initialized.
   void OnPreferencesInit();
 
   // Grabs galleries from the media file system registry and passes them to
@@ -259,10 +259,10 @@
 
  protected:
   virtual ~MediaGalleriesGetMetadataFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
-  // Bottom half for RunImpl, invoked after the preferences is initialized.
+  // Bottom half for RunAsync, invoked after the preferences is initialized.
   void OnPreferencesInit(bool mime_type_only, const std::string& blob_uuid);
 
   void SniffMimeType(bool mime_type_only,
diff --git a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc
index 3bd212a..d54ee6e 100644
--- a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc
+++ b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc
@@ -159,7 +159,7 @@
 ~MediaGalleriesPrivateAddGalleryWatchFunction() {
 }
 
-bool MediaGalleriesPrivateAddGalleryWatchFunction::RunImpl() {
+bool MediaGalleriesPrivateAddGalleryWatchFunction::RunAsync() {
   DCHECK(GetProfile());
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!render_view_host() || !render_view_host()->GetProcess())
@@ -245,7 +245,7 @@
 ~MediaGalleriesPrivateRemoveGalleryWatchFunction() {
 }
 
-bool MediaGalleriesPrivateRemoveGalleryWatchFunction::RunImpl() {
+bool MediaGalleriesPrivateRemoveGalleryWatchFunction::RunAsync() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!render_view_host() || !render_view_host()->GetProcess())
     return false;
@@ -304,7 +304,7 @@
 ~MediaGalleriesPrivateGetAllGalleryWatchFunction() {
 }
 
-bool MediaGalleriesPrivateGetAllGalleryWatchFunction::RunImpl() {
+bool MediaGalleriesPrivateGetAllGalleryWatchFunction::RunAsync() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!render_view_host() || !render_view_host()->GetProcess())
     return false;
@@ -342,7 +342,7 @@
 ~MediaGalleriesPrivateRemoveAllGalleryWatchFunction() {
 }
 
-bool MediaGalleriesPrivateRemoveAllGalleryWatchFunction::RunImpl() {
+bool MediaGalleriesPrivateRemoveAllGalleryWatchFunction::RunAsync() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!render_view_host() || !render_view_host()->GetProcess())
     return false;
@@ -377,7 +377,7 @@
 ~MediaGalleriesPrivateGetHandlersFunction() {
 }
 
-bool MediaGalleriesPrivateGetHandlersFunction::RunImpl() {
+bool MediaGalleriesPrivateGetHandlersFunction::RunAsync() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   ExtensionService* service =
diff --git a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.h b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.h
index bb897de..2f8e3e1 100644
--- a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.h
+++ b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.h
@@ -88,7 +88,7 @@
   virtual ~MediaGalleriesPrivateAddGalleryWatchFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnPreferencesInit(const std::string& pref_id);
@@ -108,7 +108,7 @@
   virtual ~MediaGalleriesPrivateRemoveGalleryWatchFunction();
 
   // SyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnPreferencesInit(const std::string& pref_id);
@@ -124,7 +124,7 @@
   virtual ~MediaGalleriesPrivateGetAllGalleryWatchFunction();
 
   // SyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnPreferencesInit();
@@ -140,7 +140,7 @@
   virtual ~MediaGalleriesPrivateRemoveAllGalleryWatchFunction();
 
   // SyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnPreferencesInit();
@@ -157,7 +157,7 @@
   virtual ~MediaGalleriesPrivateGetHandlersFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/messaging/incognito_connectability.cc b/chrome/browser/extensions/api/messaging/incognito_connectability.cc
index c8d59ee..ae1baa4 100644
--- a/chrome/browser/extensions/api/messaging/incognito_connectability.cc
+++ b/chrome/browser/extensions/api/messaging/incognito_connectability.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/simple_message_box.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/common/extension.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -79,8 +78,7 @@
           IDS_EXTENSION_PROMPT_APP_CONNECT_FROM_INCOGNITO :
           IDS_EXTENSION_PROMPT_EXTENSION_CONNECT_FROM_INCOGNITO;
       result = chrome::ShowMessageBox(
-          web_contents ? web_contents->GetView()->GetTopLevelNativeWindow()
-                       : NULL,
+          web_contents ? web_contents->GetTopLevelNativeWindow() : NULL,
           base::string16(),  // no title
           l10n_util::GetStringFUTF16(template_id,
                                      base::UTF8ToUTF16(origin.spec()),
diff --git a/chrome/browser/extensions/api/messaging/message_property_provider.cc b/chrome/browser/extensions/api/messaging/message_property_provider.cc
index c15c3ad..4871bc3 100644
--- a/chrome/browser/extensions/api/messaging/message_property_provider.cc
+++ b/chrome/browser/extensions/api/messaging/message_property_provider.cc
@@ -10,8 +10,8 @@
 #include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/common/extensions/api/runtime.h"
 #include "content/public/browser/browser_thread.h"
+#include "extensions/common/api/runtime.h"
 #include "net/base/completion_callback.h"
 #include "net/cert/asn1_util.h"
 #include "net/cert/jwk_serializer.h"
diff --git a/chrome/browser/extensions/api/messaging/message_service.cc b/chrome/browser/extensions/api/messaging/message_service.cc
index dbe469c..67abb74 100644
--- a/chrome/browser/extensions/api/messaging/message_service.cc
+++ b/chrome/browser/extensions/api/messaging/message_service.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/common/extensions/manifest_handlers/externally_connectable.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
@@ -39,6 +38,7 @@
 #include "extensions/common/extension_messages.h"
 #include "extensions/common/manifest_constants.h"
 #include "extensions/common/manifest_handlers/background_info.h"
+#include "extensions/common/manifest_handlers/externally_connectable.h"
 #include "extensions/common/manifest_handlers/incognito_info.h"
 #include "net/base/completion_callback.h"
 #include "url/gurl.h"
diff --git a/chrome/browser/extensions/api/messaging/native_message_process_host.cc b/chrome/browser/extensions/api/messaging/native_message_process_host.cc
index 73af519..b4993dc 100644
--- a/chrome/browser/extensions/api/messaging/native_message_process_host.cc
+++ b/chrome/browser/extensions/api/messaging/native_message_process_host.cc
@@ -198,14 +198,8 @@
           GetTaskRunnerWithShutdownBehavior(
               base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
 
-  read_stream_.reset(new net::FileStream(
-      read_file.TakePlatformFile(),
-      base::PLATFORM_FILE_READ | base::PLATFORM_FILE_ASYNC,
-      task_runner));
-  write_stream_.reset(new net::FileStream(
-      write_file.TakePlatformFile(),
-      base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC,
-      task_runner));
+  read_stream_.reset(new net::FileStream(read_file.Pass(), task_runner));
+  write_stream_.reset(new net::FileStream(write_file.Pass(), task_runner));
 
   WaitRead();
   DoWrite();
diff --git a/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.cc b/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.cc
index 0495981..b51ec55 100644
--- a/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.cc
+++ b/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.cc
@@ -26,7 +26,7 @@
     ~MusicManagerPrivateGetDeviceIdFunction() {
 }
 
-bool MusicManagerPrivateGetDeviceIdFunction::RunImpl() {
+bool MusicManagerPrivateGetDeviceIdFunction::RunAsync() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DeviceId::GetDeviceId(
       this->extension_id(),
diff --git a/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.h b/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.h
index 93eec43..9c43be2 100644
--- a/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.h
+++ b/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.h
@@ -21,7 +21,7 @@
   virtual ~MusicManagerPrivateGetDeviceIdFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   void DeviceIdCallback(const std::string& device_id);
 };
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_api.h b/chrome/browser/extensions/api/networking_private/networking_private_api.h
index 43057ee..e244e84 100644
--- a/chrome/browser/extensions/api/networking_private/networking_private_api.h
+++ b/chrome/browser/extensions/api/networking_private/networking_private_api.h
@@ -28,7 +28,7 @@
   virtual ~NetworkingPrivateGetPropertiesFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void GetPropertiesSuccess(const std::string& service_path,
@@ -50,7 +50,7 @@
   virtual ~NetworkingPrivateGetManagedPropertiesFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Callbacks for ManagedNetworkConfigurationHandler::GetManagedProperties.
@@ -73,7 +73,7 @@
   virtual ~NetworkingPrivateGetStateFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void Success(const std::string& service_path,
@@ -96,7 +96,7 @@
   virtual ~NetworkingPrivateSetPropertiesFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void ErrorCallback(const std::string& error_name,
@@ -117,7 +117,7 @@
   virtual ~NetworkingPrivateCreateNetworkFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void ErrorCallback(const std::string& error_name,
@@ -138,7 +138,7 @@
   virtual ~NetworkingPrivateGetVisibleNetworksFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void ResultCallback(const base::ListValue& network_list);
@@ -231,7 +231,7 @@
   virtual ~NetworkingPrivateStartConnectFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Called when the request to connect succeeds. Doesn't mean that the connect
@@ -257,7 +257,7 @@
   virtual ~NetworkingPrivateStartDisconnectFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   // Called when the request to disconnect succeeds. Doesn't mean that the
@@ -283,7 +283,7 @@
   virtual ~NetworkingPrivateVerifyDestinationFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   void ResultCallback(bool result);
   void ErrorCallback(const std::string& error_name, const std::string& error);
@@ -304,7 +304,7 @@
   virtual ~NetworkingPrivateVerifyAndEncryptCredentialsFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   void ResultCallback(const std::string& result);
   void ErrorCallback(const std::string& error_name, const std::string& error);
@@ -326,7 +326,7 @@
   virtual ~NetworkingPrivateVerifyAndEncryptDataFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   void ResultCallback(const std::string& result);
   void ErrorCallback(const std::string& error_name, const std::string& error);
@@ -347,7 +347,7 @@
   virtual ~NetworkingPrivateSetWifiTDLSEnabledStateFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   void Success(const std::string& result);
   void Failure(const std::string& error_name,
@@ -369,7 +369,7 @@
   virtual ~NetworkingPrivateGetWifiTDLSStatusFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   void Success(const std::string& result);
   void Failure(const std::string& error_name,
@@ -387,7 +387,7 @@
                              NETWORKINGPRIVATE_GETCAPTIVEPORTALSTATUS);
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  protected:
   virtual ~NetworkingPrivateGetCaptivePortalStatusFunction();
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_api_chromeos.cc b/chrome/browser/extensions/api/networking_private/networking_private_api_chromeos.cc
index 4a015e6..685290e 100644
--- a/chrome/browser/extensions/api/networking_private/networking_private_api_chromeos.cc
+++ b/chrome/browser/extensions/api/networking_private/networking_private_api_chromeos.cc
@@ -23,6 +23,7 @@
 #include "chromeos/network/network_state_handler.h"
 #include "chromeos/network/onc/onc_signature.h"
 #include "chromeos/network/onc/onc_translator.h"
+#include "chromeos/network/onc/onc_utils.h"
 #include "chromeos/network/shill_property_util.h"
 #include "components/onc/onc_constants.h"
 #include "extensions/browser/extension_function_registry.h"
@@ -79,7 +80,7 @@
   ~NetworkingPrivateGetPropertiesFunction() {
 }
 
-bool NetworkingPrivateGetPropertiesFunction::RunImpl() {
+bool NetworkingPrivateGetPropertiesFunction::RunAsync() {
   scoped_ptr<api::GetProperties::Params> params =
       api::GetProperties::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -117,7 +118,7 @@
   ~NetworkingPrivateGetManagedPropertiesFunction() {
 }
 
-bool NetworkingPrivateGetManagedPropertiesFunction::RunImpl() {
+bool NetworkingPrivateGetManagedPropertiesFunction::RunAsync() {
   scoped_ptr<api::GetManagedProperties::Params> params =
       api::GetManagedProperties::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -159,7 +160,7 @@
   ~NetworkingPrivateGetStateFunction() {
 }
 
-bool NetworkingPrivateGetStateFunction::RunImpl() {
+bool NetworkingPrivateGetStateFunction::RunAsync() {
   scoped_ptr<api::GetState::Params> params =
       api::GetState::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -174,7 +175,7 @@
   }
 
   scoped_ptr<base::DictionaryValue> result_dict(new base::DictionaryValue);
-  state->GetProperties(result_dict.get());
+  state->GetStateProperties(result_dict.get());
   scoped_ptr<base::DictionaryValue> onc_network_part =
       chromeos::onc::TranslateShillServiceToONCPart(*result_dict,
           &chromeos::onc::kNetworkWithStateSignature);
@@ -191,7 +192,7 @@
 ~NetworkingPrivateSetPropertiesFunction() {
 }
 
-bool NetworkingPrivateSetPropertiesFunction::RunImpl() {
+bool NetworkingPrivateSetPropertiesFunction::RunAsync() {
   scoped_ptr<api::SetProperties::Params> params =
       api::SetProperties::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -227,7 +228,7 @@
 ~NetworkingPrivateCreateNetworkFunction() {
 }
 
-bool NetworkingPrivateCreateNetworkFunction::RunImpl() {
+bool NetworkingPrivateCreateNetworkFunction::RunAsync() {
   scoped_ptr<api::CreateNetwork::Params> params =
       api::CreateNetwork::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -270,39 +271,31 @@
 ~NetworkingPrivateGetVisibleNetworksFunction() {
 }
 
-bool NetworkingPrivateGetVisibleNetworksFunction::RunImpl() {
+bool NetworkingPrivateGetVisibleNetworksFunction::RunAsync() {
   scoped_ptr<api::GetVisibleNetworks::Params> params =
       api::GetVisibleNetworks::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
-  std::string type_filter =
-      api::GetVisibleNetworks::Params::ToString(params->type);
+  NetworkTypePattern type = chromeos::onc::NetworkTypePatternFromOncType(
+      api::GetVisibleNetworks::Params::ToString(params->type));
 
   NetworkStateHandler::NetworkStateList network_states;
-  NetworkHandler::Get()->network_state_handler()->GetNetworkList(
-      &network_states);
+  NetworkHandler::Get()->network_state_handler()->GetNetworkListByType(
+      type, &network_states);
 
   base::ListValue* network_properties_list = new base::ListValue;
   for (NetworkStateHandler::NetworkStateList::iterator it =
            network_states.begin();
        it != network_states.end(); ++it) {
-    const std::string& service_path = (*it)->path();
     base::DictionaryValue shill_dictionary;
-    (*it)->GetProperties(&shill_dictionary);
+    (*it)->GetStateProperties(&shill_dictionary);
 
     scoped_ptr<base::DictionaryValue> onc_network_part =
-        chromeos::onc::TranslateShillServiceToONCPart(shill_dictionary,
-            &chromeos::onc::kNetworkWithStateSignature);
-
-    std::string onc_type;
-    onc_network_part->GetStringWithoutPathExpansion(onc::network_config::kType,
-                                                    &onc_type);
-    if (type_filter == onc::network_type::kAllTypes ||
-        onc_type == type_filter) {
-      onc_network_part->SetStringWithoutPathExpansion(
-          onc::network_config::kGUID,
-          service_path);
-      network_properties_list->Append(onc_network_part.release());
-    }
+        chromeos::onc::TranslateShillServiceToONCPart(
+            shill_dictionary, &chromeos::onc::kNetworkWithStateSignature);
+    // TODO(stevenjb): Fix this to always use GUID: crbug.com/284827
+    onc_network_part->SetStringWithoutPathExpansion(
+        onc::network_config::kGUID, (*it)->path());
+    network_properties_list->Append(onc_network_part.release());
   }
 
   SetResult(network_properties_list);
@@ -442,7 +435,7 @@
   SendResponse(false);
 }
 
-bool NetworkingPrivateStartConnectFunction::RunImpl() {
+bool NetworkingPrivateStartConnectFunction::RunAsync() {
   scoped_ptr<api::StartConnect::Params> params =
       api::StartConnect::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -478,7 +471,7 @@
   SendResponse(false);
 }
 
-bool NetworkingPrivateStartDisconnectFunction::RunImpl() {
+bool NetworkingPrivateStartDisconnectFunction::RunAsync() {
   scoped_ptr<api::StartDisconnect::Params> params =
       api::StartDisconnect::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -501,7 +494,7 @@
   ~NetworkingPrivateVerifyDestinationFunction() {
 }
 
-bool NetworkingPrivateVerifyDestinationFunction::RunImpl() {
+bool NetworkingPrivateVerifyDestinationFunction::RunAsync() {
   scoped_ptr<api::VerifyDestination::Params> params =
       api::VerifyDestination::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -539,7 +532,7 @@
   ~NetworkingPrivateVerifyAndEncryptCredentialsFunction() {
 }
 
-bool NetworkingPrivateVerifyAndEncryptCredentialsFunction::RunImpl() {
+bool NetworkingPrivateVerifyAndEncryptCredentialsFunction::RunAsync() {
   scoped_ptr<api::VerifyAndEncryptCredentials::Params> params =
       api::VerifyAndEncryptCredentials::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -580,7 +573,7 @@
   ~NetworkingPrivateVerifyAndEncryptDataFunction() {
 }
 
-bool NetworkingPrivateVerifyAndEncryptDataFunction::RunImpl() {
+bool NetworkingPrivateVerifyAndEncryptDataFunction::RunAsync() {
   scoped_ptr<api::VerifyAndEncryptData::Params> params =
       api::VerifyAndEncryptData::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -620,7 +613,7 @@
   ~NetworkingPrivateSetWifiTDLSEnabledStateFunction() {
 }
 
-bool NetworkingPrivateSetWifiTDLSEnabledStateFunction::RunImpl() {
+bool NetworkingPrivateSetWifiTDLSEnabledStateFunction::RunAsync() {
   scoped_ptr<api::SetWifiTDLSEnabledState::Params> params =
       api::SetWifiTDLSEnabledState::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -660,7 +653,7 @@
   ~NetworkingPrivateGetWifiTDLSStatusFunction() {
 }
 
-bool NetworkingPrivateGetWifiTDLSStatusFunction::RunImpl() {
+bool NetworkingPrivateGetWifiTDLSStatusFunction::RunAsync() {
   scoped_ptr<api::GetWifiTDLSStatus::Params> params =
       api::GetWifiTDLSStatus::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -697,7 +690,7 @@
 NetworkingPrivateGetCaptivePortalStatusFunction::
     ~NetworkingPrivateGetCaptivePortalStatusFunction() {}
 
-bool NetworkingPrivateGetCaptivePortalStatusFunction::RunImpl() {
+bool NetworkingPrivateGetCaptivePortalStatusFunction::RunAsync() {
   scoped_ptr<api::GetCaptivePortalStatus::Params> params =
       api::GetCaptivePortalStatus::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc b/chrome/browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc
index ad5edbe..64d5dbf 100644
--- a/chrome/browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc
+++ b/chrome/browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc
@@ -30,7 +30,7 @@
   ~NetworkingPrivateGetPropertiesFunction() {
 }
 
-bool NetworkingPrivateGetPropertiesFunction::RunImpl() {
+bool NetworkingPrivateGetPropertiesFunction::RunAsync() {
   scoped_ptr<api::GetProperties::Params> params =
       api::GetProperties::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -68,7 +68,7 @@
   ~NetworkingPrivateGetManagedPropertiesFunction() {
 }
 
-bool NetworkingPrivateGetManagedPropertiesFunction::RunImpl() {
+bool NetworkingPrivateGetManagedPropertiesFunction::RunAsync() {
   scoped_ptr<api::GetManagedProperties::Params> params =
       api::GetManagedProperties::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -108,7 +108,7 @@
   ~NetworkingPrivateGetStateFunction() {
 }
 
-bool NetworkingPrivateGetStateFunction::RunImpl() {
+bool NetworkingPrivateGetStateFunction::RunAsync() {
   scoped_ptr<api::GetState::Params> params =
       api::GetState::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -145,7 +145,7 @@
   ~NetworkingPrivateSetPropertiesFunction() {
 }
 
-bool NetworkingPrivateSetPropertiesFunction::RunImpl() {
+bool NetworkingPrivateSetPropertiesFunction::RunAsync() {
   scoped_ptr<api::SetProperties::Params> params =
       api::SetProperties::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -181,7 +181,7 @@
 ~NetworkingPrivateCreateNetworkFunction() {
 }
 
-bool NetworkingPrivateCreateNetworkFunction::RunImpl() {
+bool NetworkingPrivateCreateNetworkFunction::RunAsync() {
   scoped_ptr<api::CreateNetwork::Params> params =
       api::CreateNetwork::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -219,7 +219,7 @@
   ~NetworkingPrivateGetVisibleNetworksFunction() {
 }
 
-bool NetworkingPrivateGetVisibleNetworksFunction::RunImpl() {
+bool NetworkingPrivateGetVisibleNetworksFunction::RunAsync() {
   scoped_ptr<api::GetVisibleNetworks::Params> params =
       api::GetVisibleNetworks::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -304,7 +304,7 @@
   ~NetworkingPrivateStartConnectFunction() {
 }
 
-bool NetworkingPrivateStartConnectFunction::RunImpl() {
+bool NetworkingPrivateStartConnectFunction::RunAsync() {
   scoped_ptr<api::StartConnect::Params> params =
       api::StartConnect::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -337,7 +337,7 @@
   ~NetworkingPrivateStartDisconnectFunction() {
 }
 
-bool NetworkingPrivateStartDisconnectFunction::RunImpl() {
+bool NetworkingPrivateStartDisconnectFunction::RunAsync() {
   scoped_ptr<api::StartDisconnect::Params> params =
       api::StartDisconnect::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -371,7 +371,7 @@
 NetworkingPrivateVerifyDestinationFunction::
     ~NetworkingPrivateVerifyDestinationFunction() {}
 
-bool NetworkingPrivateVerifyDestinationFunction::RunImpl() {
+bool NetworkingPrivateVerifyDestinationFunction::RunAsync() {
   scoped_ptr<api::VerifyDestination::Params> params =
       api::VerifyDestination::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -406,7 +406,7 @@
   ~NetworkingPrivateVerifyAndEncryptCredentialsFunction() {
 }
 
-bool NetworkingPrivateVerifyAndEncryptCredentialsFunction::RunImpl() {
+bool NetworkingPrivateVerifyAndEncryptCredentialsFunction::RunAsync() {
   scoped_ptr<api::VerifyAndEncryptCredentials::Params> params =
       api::VerifyAndEncryptCredentials::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -443,7 +443,7 @@
   ~NetworkingPrivateVerifyAndEncryptDataFunction() {
 }
 
-bool NetworkingPrivateVerifyAndEncryptDataFunction::RunImpl() {
+bool NetworkingPrivateVerifyAndEncryptDataFunction::RunAsync() {
   scoped_ptr<api::VerifyAndEncryptData::Params> params =
       api::VerifyAndEncryptData::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -479,7 +479,7 @@
   ~NetworkingPrivateSetWifiTDLSEnabledStateFunction() {
 }
 
-bool NetworkingPrivateSetWifiTDLSEnabledStateFunction::RunImpl() {
+bool NetworkingPrivateSetWifiTDLSEnabledStateFunction::RunAsync() {
   scoped_ptr<api::SetWifiTDLSEnabledState::Params> params =
       api::SetWifiTDLSEnabledState::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -494,7 +494,7 @@
   ~NetworkingPrivateGetWifiTDLSStatusFunction() {
 }
 
-bool NetworkingPrivateGetWifiTDLSStatusFunction::RunImpl() {
+bool NetworkingPrivateGetWifiTDLSStatusFunction::RunAsync() {
   scoped_ptr<api::GetWifiTDLSStatus::Params> params =
       api::GetWifiTDLSStatus::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -508,7 +508,7 @@
 NetworkingPrivateGetCaptivePortalStatusFunction::
     ~NetworkingPrivateGetCaptivePortalStatusFunction() {}
 
-bool NetworkingPrivateGetCaptivePortalStatusFunction::RunImpl() {
+bool NetworkingPrivateGetCaptivePortalStatusFunction::RunAsync() {
   scoped_ptr<api::GetCaptivePortalStatus::Params> params =
       api::GetCaptivePortalStatus::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc b/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc
index 5f04dfd..45eeadf 100644
--- a/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc
+++ b/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc
@@ -23,6 +23,7 @@
 #include "chromeos/dbus/cryptohome_client.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/shill_device_client.h"
+#include "chromeos/dbus/shill_ipconfig_client.h"
 #include "chromeos/dbus/shill_manager_client.h"
 #include "chromeos/dbus/shill_profile_client.h"
 #include "chromeos/dbus/shill_service_client.h"
@@ -43,9 +44,11 @@
 #include "chrome/browser/extensions/api/networking_private/networking_private_credentials_getter.h"
 #include "chrome/browser/extensions/api/networking_private/networking_private_service_client.h"
 #include "chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.h"
-#include "components/wifi/wifi_service.h"
+#include "components/wifi/fake_wifi_service.h"
 #endif  // defined(OS_CHROMEOS)
 
+// TODO(stevenjb/mef): Clean these tests up. crbug.com/371442
+
 using testing::Return;
 using testing::_;
 
@@ -57,6 +60,7 @@
 using chromeos::NetworkPortalDetector;
 using chromeos::NetworkPortalDetectorTestImpl;
 using chromeos::ShillDeviceClient;
+using chromeos::ShillIPConfigClient;
 using chromeos::ShillManagerClient;
 using chromeos::ShillProfileClient;
 using chromeos::ShillServiceClient;
@@ -68,6 +72,9 @@
 
 #if defined(OS_CHROMEOS)
 const char kUser1ProfilePath[] = "/profile/user1/shill";
+const char kWifiDevicePath[] = "/device/stub_wifi_device1";
+const char kCellularDevicePath[] = "/device/stub_cellular_device1";
+const char kIPConfigPath[] = "/ipconfig/ipconfig1";
 
 class TestListener : public content::NotificationObserver {
  public:
@@ -112,7 +119,7 @@
   virtual void VerifyAndEncryptCredentials(
       scoped_ptr<base::ListValue> args,
       const extensions::NetworkingPrivateServiceClient::CryptoVerify::
-          VerifyAndEncryptCredentialsCallback& callback) OVERRIDE {
+      VerifyAndEncryptCredentialsCallback& callback) OVERRIDE {
     callback.Run("encrypted_credentials", "");
   }
 
@@ -130,7 +137,8 @@
  public:
   ExtensionNetworkingPrivateApiTest()
 #if defined(OS_CHROMEOS)
-      : detector_(NULL)
+      : detector_(NULL),
+        service_test_(NULL)
 #endif
   {
   }
@@ -153,8 +161,8 @@
 
 #if defined(OS_CHROMEOS)
   static void AssignString(std::string* out,
-                    DBusMethodCallStatus call_status,
-                    const std::string& result) {
+                           DBusMethodCallStatus call_status,
+                           const std::string& result) {
     CHECK_EQ(call_status, DBUS_METHOD_CALL_SUCCESS);
     *out = result;
   }
@@ -199,107 +207,118 @@
 
     InitializeSanitizedUsername();
 
+    DBusThreadManager* dbus_manager = DBusThreadManager::Get();
     ShillManagerClient::TestInterface* manager_test =
-        DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
+        dbus_manager->GetShillManagerClient()->GetTestInterface();
+    ShillIPConfigClient::TestInterface* ip_config_test =
+        dbus_manager->GetShillIPConfigClient()->GetTestInterface();
     ShillDeviceClient::TestInterface* device_test =
-        DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
+        dbus_manager->GetShillDeviceClient()->GetTestInterface();
     ShillProfileClient::TestInterface* profile_test =
-        DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
-    ShillServiceClient::TestInterface* service_test =
-        DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
+        dbus_manager->GetShillProfileClient()->GetTestInterface();
+
+    service_test_ = dbus_manager->GetShillServiceClient()->GetTestInterface();
 
     device_test->ClearDevices();
-    service_test->ClearServices();
+    service_test_->ClearServices();
 
     // Sends a notification about the added profile.
     profile_test->AddProfile(kUser1ProfilePath, userhash_);
 
-    device_test->AddDevice("/device/stub_wifi_device1",
-                           shill::kTypeWifi, "stub_wifi_device1");
-    device_test->AddDevice("/device/stub_cellular_device1",
-                           shill::kTypeCellular, "stub_cellular_device1");
+    // Add IPConfigs
+    base::DictionaryValue ipconfig;
+    ipconfig.SetStringWithoutPathExpansion(shill::kAddressProperty, "0.0.0.0");
+    ipconfig.SetStringWithoutPathExpansion(shill::kGatewayProperty, "0.0.0.1");
+    ipconfig.SetIntegerWithoutPathExpansion(shill::kPrefixlenProperty, 0);
+    ipconfig.SetStringWithoutPathExpansion(
+        shill::kMethodProperty, shill::kTypeIPv4);
+    ip_config_test->AddIPConfig(kIPConfigPath, ipconfig);
 
+    // Add Devices
+    device_test->AddDevice(
+        kWifiDevicePath, shill::kTypeWifi, "stub_wifi_device1");
+    base::ListValue wifi_ip_configs;
+    wifi_ip_configs.AppendString(kIPConfigPath);
+    device_test->SetDeviceProperty(
+        kWifiDevicePath, shill::kIPConfigsProperty, wifi_ip_configs);
+    device_test->AddDevice(
+        kCellularDevicePath, shill::kTypeCellular, "stub_cellular_device1");
+
+    // Add Services
     const bool add_to_watchlist = true;
     const bool add_to_visible = true;
-    service_test->AddService("stub_ethernet", "eth0",
-                             shill::kTypeEthernet, shill::kStateOnline,
-                             add_to_visible, add_to_watchlist);
-    service_test->SetServiceProperty(
+    service_test_->AddService("stub_ethernet", "eth0",
+                              shill::kTypeEthernet, shill::kStateOnline,
+                              add_to_visible, add_to_watchlist);
+    service_test_->SetServiceProperty(
         "stub_ethernet",
         shill::kProfileProperty,
         base::StringValue(ShillProfileClient::GetSharedProfilePath()));
     profile_test->AddService(ShillProfileClient::GetSharedProfilePath(),
                              "stub_ethernet");
 
-    service_test->AddService("stub_wifi1", "wifi1",
-                             shill::kTypeWifi, shill::kStateOnline,
-                             add_to_visible, add_to_watchlist);
-    service_test->SetServiceProperty("stub_wifi1",
-                                     shill::kSecurityProperty,
-                                     base::StringValue(shill::kSecurityWep));
-    service_test->SetServiceProperty("stub_wifi1",
-                                     shill::kProfileProperty,
-                                     base::StringValue(kUser1ProfilePath));
+    service_test_->AddService("stub_wifi1", "wifi1",
+                              shill::kTypeWifi, shill::kStateOnline,
+                              add_to_visible, add_to_watchlist);
+    service_test_->SetServiceProperty("stub_wifi1",
+                                      shill::kSecurityProperty,
+                                      base::StringValue(shill::kSecurityWep));
+    service_test_->SetServiceProperty("stub_wifi1",
+                                      shill::kSignalStrengthProperty,
+                                      base::FundamentalValue(40));
+    service_test_->SetServiceProperty("stub_wifi1",
+                                      shill::kProfileProperty,
+                                      base::StringValue(kUser1ProfilePath));
+    service_test_->SetServiceProperty("stub_wifi1",
+                                      shill::kConnectableProperty,
+                                      base::FundamentalValue(true));
+    service_test_->SetServiceProperty("stub_wifi1",
+                                      shill::kDeviceProperty,
+                                      base::StringValue(kWifiDevicePath));
     profile_test->AddService(kUser1ProfilePath, "stub_wifi1");
     base::ListValue frequencies1;
     frequencies1.AppendInteger(2400);
-    service_test->SetServiceProperty("stub_wifi1",
-                                     shill::kWifiFrequencyListProperty,
-                                     frequencies1);
-    service_test->SetServiceProperty("stub_wifi1",
-                                     shill::kWifiFrequency,
-                                     base::FundamentalValue(2400));
+    service_test_->SetServiceProperty("stub_wifi1",
+                                      shill::kWifiFrequencyListProperty,
+                                      frequencies1);
+    service_test_->SetServiceProperty("stub_wifi1",
+                                      shill::kWifiFrequency,
+                                      base::FundamentalValue(2400));
 
-    service_test->AddService("stub_wifi2", "wifi2_PSK",
-                             shill::kTypeWifi, shill::kStateIdle,
-                             add_to_visible, add_to_watchlist);
-    service_test->SetServiceProperty("stub_wifi2",
-                                     shill::kGuidProperty,
-                                     base::StringValue("stub_wifi2"));
-    service_test->SetServiceProperty("stub_wifi2",
-                                     shill::kSecurityProperty,
-                                     base::StringValue(shill::kSecurityPsk));
-    service_test->SetServiceProperty("stub_wifi2",
-                                     shill::kSignalStrengthProperty,
-                                     base::FundamentalValue(80));
-    service_test->SetServiceProperty("stub_wifi2",
-                                     shill::kConnectableProperty,
-                                     base::FundamentalValue(true));
+    service_test_->AddService("stub_wifi2", "wifi2_PSK",
+                              shill::kTypeWifi, shill::kStateIdle,
+                              add_to_visible, add_to_watchlist);
+    service_test_->SetServiceProperty("stub_wifi2",
+                                      shill::kGuidProperty,
+                                      base::StringValue("stub_wifi2"));
+    service_test_->SetServiceProperty("stub_wifi2",
+                                      shill::kSecurityProperty,
+                                      base::StringValue(shill::kSecurityPsk));
+    service_test_->SetServiceProperty("stub_wifi2",
+                                      shill::kSignalStrengthProperty,
+                                      base::FundamentalValue(80));
+    service_test_->SetServiceProperty("stub_wifi2",
+                                      shill::kConnectableProperty,
+                                      base::FundamentalValue(true));
 
     base::ListValue frequencies2;
     frequencies2.AppendInteger(2400);
     frequencies2.AppendInteger(5000);
-    service_test->SetServiceProperty("stub_wifi2",
-                                     shill::kWifiFrequencyListProperty,
-                                     frequencies2);
-    service_test->SetServiceProperty("stub_wifi2",
-                                     shill::kWifiFrequency,
-                                     base::FundamentalValue(5000));
-    service_test->SetServiceProperty("stub_wifi2",
-                                     shill::kProfileProperty,
-                                     base::StringValue(kUser1ProfilePath));
+    service_test_->SetServiceProperty("stub_wifi2",
+                                      shill::kWifiFrequencyListProperty,
+                                      frequencies2);
+    service_test_->SetServiceProperty("stub_wifi2",
+                                      shill::kWifiFrequency,
+                                      base::FundamentalValue(5000));
+    service_test_->SetServiceProperty("stub_wifi2",
+                                      shill::kProfileProperty,
+                                      base::StringValue(kUser1ProfilePath));
     profile_test->AddService(kUser1ProfilePath, "stub_wifi2");
 
-    service_test->AddService("stub_cellular1", "cellular1",
-                             shill::kTypeCellular, shill::kStateIdle,
-                             add_to_visible, add_to_watchlist);
-    service_test->SetServiceProperty(
-        "stub_cellular1",
-        shill::kNetworkTechnologyProperty,
-        base::StringValue(shill::kNetworkTechnologyGsm));
-    service_test->SetServiceProperty(
-        "stub_cellular1",
-        shill::kActivationStateProperty,
-        base::StringValue(shill::kActivationStateNotActivated));
-    service_test->SetServiceProperty(
-        "stub_cellular1",
-        shill::kRoamingStateProperty,
-        base::StringValue(shill::kRoamingStateHome));
-
-    service_test->AddService("stub_vpn1", "vpn1",
-                             shill::kTypeVPN,
-                             shill::kStateOnline,
-                             add_to_visible, add_to_watchlist);
+    service_test_->AddService("stub_vpn1", "vpn1",
+                              shill::kTypeVPN,
+                              shill::kStateOnline,
+                              add_to_visible, add_to_watchlist);
 
     manager_test->SortManagerServices();
 
@@ -317,8 +336,7 @@
   static KeyedService* CreateNetworkingPrivateServiceClient(
       content::BrowserContext* profile) {
     return new extensions::NetworkingPrivateServiceClient(
-        wifi::WiFiService::CreateForTest(),
-        new CryptoVerifyStub());
+        new wifi::FakeWiFiService(), new CryptoVerifyStub());
   }
 
   virtual void SetUpOnMainThread() OVERRIDE {
@@ -336,6 +354,7 @@
   NetworkPortalDetectorTestImpl* detector() { return detector_; }
 
   NetworkPortalDetectorTestImpl* detector_;
+  ShillServiceClient::TestInterface* service_test_;
   policy::MockConfigurationPolicyProvider provider_;
   std::string userhash_;
 #endif
@@ -369,18 +388,24 @@
       << message_;
 }
 
+#if defined(OS_CHROMEOS)
+// Non-Chrome OS only supports wifi currently.
 IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, GetVisibleNetworks) {
   EXPECT_TRUE(RunNetworkingSubtest("getVisibleNetworks")) << message_;
 }
+#endif
 
 IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
                        GetVisibleNetworksWifi) {
   EXPECT_TRUE(RunNetworkingSubtest("getVisibleNetworksWifi")) << message_;
 }
 
+#if defined(OS_CHROMEOS)
+// TODO(stevenjb/mef): Fix this on non-Chrome OS, crbug.com/371442.
 IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, RequestNetworkScan) {
   EXPECT_TRUE(RunNetworkingSubtest("requestNetworkScan")) << message_;
 }
+#endif
 
 // Properties are filtered and translated through
 // ShillToONCTranslator::TranslateWiFiWithState
@@ -404,24 +429,23 @@
   EXPECT_TRUE(RunNetworkingSubtest("createNetwork")) << message_;
 }
 
+#if defined(OS_CHROMEOS)
+// TODO(stevenjb/mef): Find a maintainable way to support this on win/mac and
+// a better way to set this up on Chrome OS.
 IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
                        GetManagedProperties) {
-#if defined(OS_CHROMEOS)
-  // TODO(mef): Move this to ChromeOS-specific helper or SetUpOnMainThread.
-  ShillServiceClient::TestInterface* service_test =
-      DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
   const std::string uidata_blob =
       "{ \"user_settings\": {"
       "      \"WiFi\": {"
       "        \"Passphrase\": \"FAKE_CREDENTIAL_VPaJDV9x\" }"
       "    }"
       "}";
-  service_test->SetServiceProperty("stub_wifi2",
-                                   shill::kUIDataProperty,
-                                   base::StringValue(uidata_blob));
-  service_test->SetServiceProperty("stub_wifi2",
-                                   shill::kAutoConnectProperty,
-                                   base::FundamentalValue(false));
+  service_test_->SetServiceProperty("stub_wifi2",
+                                    shill::kUIDataProperty,
+                                    base::StringValue(uidata_blob));
+  service_test_->SetServiceProperty("stub_wifi2",
+                                    shill::kAutoConnectProperty,
+                                    base::FundamentalValue(false));
 
   ShillProfileClient::TestInterface* profile_test =
       DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
@@ -455,10 +479,10 @@
   provider_.UpdateChromePolicy(policy);
 
   content::RunAllPendingInMessageLoop();
-#endif  // OS_CHROMEOS
 
   EXPECT_TRUE(RunNetworkingSubtest("getManagedProperties")) << message_;
 }
+#endif  // OS_CHROMEOS
 
 IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
                        OnNetworksChangedEventConnect) {
@@ -472,10 +496,13 @@
       << message_;
 }
 
+#if defined(OS_CHROMEOS)
+// TODO(stevenjb/mef): Fix this on non-Chrome OS, crbug.com/371442.
 IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
                        OnNetworkListChangedEvent) {
   EXPECT_TRUE(RunNetworkingSubtest("onNetworkListChangedEvent")) << message_;
 }
+#endif  // OS_CHROMEOS
 
 IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
                        VerifyDestination) {
@@ -509,6 +536,26 @@
 #if defined(OS_CHROMEOS)
 IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest,
                        GetCaptivePortalStatus) {
+  service_test_->AddService("stub_cellular1", "cellular1",
+                            shill::kTypeCellular, shill::kStateIdle,
+                            true /* add_to_visible */,
+                            true /* add_to_watchlist */);
+  service_test_->SetServiceProperty(
+      "stub_cellular1",
+      shill::kNetworkTechnologyProperty,
+      base::StringValue(shill::kNetworkTechnologyGsm));
+  service_test_->SetServiceProperty(
+      "stub_cellular1",
+      shill::kActivationStateProperty,
+      base::StringValue(shill::kActivationStateNotActivated));
+  service_test_->SetServiceProperty(
+      "stub_cellular1",
+      shill::kRoamingStateProperty,
+      base::StringValue(shill::kRoamingStateHome));
+  DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
+      SortManagerServices();
+  content::RunAllPendingInMessageLoop();
+
   NetworkPortalDetector::CaptivePortalState state;
   state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE;
   detector()->SetDetectionResultsForTesting("stub_ethernet", state);
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc
index 0e1e987..869cb1a 100644
--- a/chrome/browser/extensions/api/notifications/notifications_api.cc
+++ b/chrome/browser/extensions/api/notifications/notifications_api.cc
@@ -177,7 +177,7 @@
   virtual content::WebContents* GetWebContents() const OVERRIDE {
     // We're holding a reference to api_function_, so we know it'll be valid
     // until ReleaseRVH is called, and api_function_ (as a
-    // UIThreadExtensionFunction) will zero out its copy of render_view_host
+    // AsyncExtensionFunction) will zero out its copy of render_view_host
     // when the RVH goes away.
     if (!api_function_.get())
       return NULL;
@@ -451,7 +451,7 @@
   return false;
 }
 
-bool NotificationsApiFunction::RunImpl() {
+bool NotificationsApiFunction::RunAsync() {
   if (IsNotificationsApiAvailable() && IsNotificationsApiEnabled()) {
     return RunNotificationsApi();
   } else {
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.h b/chrome/browser/extensions/api/notifications/notifications_api.h
index 02fee4b..bd1b511 100644
--- a/chrome/browser/extensions/api/notifications/notifications_api.h
+++ b/chrome/browser/extensions/api/notifications/notifications_api.h
@@ -41,11 +41,11 @@
   // notifications for a notifier have been disabled.
   virtual bool CanRunWhileDisabled() const;
 
-  // Called inside of RunImpl.
+  // Called inside of RunAsync.
   virtual bool RunNotificationsApi() = 0;
 
   // UITHreadExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   message_center::NotificationType MapApiTemplateTypeToType(
       api::notifications::TemplateType type);
diff --git a/chrome/browser/extensions/api/page_capture/page_capture_api.cc b/chrome/browser/extensions/api/page_capture/page_capture_api.cc
index d82487c..046c5be 100644
--- a/chrome/browser/extensions/api/page_capture/page_capture_api.cc
+++ b/chrome/browser/extensions/api/page_capture/page_capture_api.cc
@@ -54,7 +54,7 @@
   test_delegate_ = delegate;
 }
 
-bool PageCaptureSaveAsMHTMLFunction::RunImpl() {
+bool PageCaptureSaveAsMHTMLFunction::RunAsync() {
   params_ = SaveAsMHTML::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params_.get());
 
diff --git a/chrome/browser/extensions/api/page_capture/page_capture_api.h b/chrome/browser/extensions/api/page_capture/page_capture_api.h
index 1bc5611..c58a781 100644
--- a/chrome/browser/extensions/api/page_capture/page_capture_api.h
+++ b/chrome/browser/extensions/api/page_capture/page_capture_api.h
@@ -37,7 +37,7 @@
 
  private:
   virtual ~PageCaptureSaveAsMHTMLFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
 
   // Called on the file thread.
diff --git a/chrome/browser/extensions/api/permissions/permissions_api.cc b/chrome/browser/extensions/api/permissions/permissions_api.cc
index 162135e..76f875d 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api.cc
+++ b/chrome/browser/extensions/api/permissions/permissions_api.cc
@@ -131,18 +131,18 @@
   results_ = Request::Results::Create(true);
   SendResponse(true);
 
-  Release();  // Balanced in RunImpl().
+  Release();  // Balanced in RunAsync().
 }
 
 void PermissionsRequestFunction::InstallUIAbort(bool user_initiated) {
   SendResponse(true);
 
-  Release();  // Balanced in RunImpl().
+  Release();  // Balanced in RunAsync().
 }
 
 PermissionsRequestFunction::~PermissionsRequestFunction() {}
 
-bool PermissionsRequestFunction::RunImpl() {
+bool PermissionsRequestFunction::RunAsync() {
   results_ = Request::Results::Create(false);
 
   if (!user_gesture() &&
diff --git a/chrome/browser/extensions/api/permissions/permissions_api.h b/chrome/browser/extensions/api/permissions/permissions_api.h
index 43de8af..65597bb 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api.h
+++ b/chrome/browser/extensions/api/permissions/permissions_api.h
@@ -72,7 +72,7 @@
   virtual ~PermissionsRequestFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   scoped_ptr<ExtensionInstallPrompt> install_ui_;
diff --git a/chrome/browser/extensions/api/preferences_private/preferences_private_api.cc b/chrome/browser/extensions/api/preferences_private/preferences_private_api.cc
index c85fc04..98a89f0 100644
--- a/chrome/browser/extensions/api/preferences_private/preferences_private_api.cc
+++ b/chrome/browser/extensions/api/preferences_private/preferences_private_api.cc
@@ -27,12 +27,12 @@
       ProfileSyncServiceFactory::GetForProfile(GetProfile());
   if (sync_service->sync_initialized()) {
     sync_service->RemoveObserver(this);
-    RunImpl();
-    Release();  // Balanced in RunImpl().
+    RunAsync();
+    Release();  // Balanced in RunAsync().
   }
 }
 
-bool PreferencesPrivateGetSyncCategoriesWithoutPassphraseFunction::RunImpl() {
+bool PreferencesPrivateGetSyncCategoriesWithoutPassphraseFunction::RunAsync() {
   ProfileSyncService* sync_service =
       ProfileSyncServiceFactory::GetForProfile(GetProfile());
   if (!sync_service)
diff --git a/chrome/browser/extensions/api/preferences_private/preferences_private_api.h b/chrome/browser/extensions/api/preferences_private/preferences_private_api.h
index 205342b..e88d022 100644
--- a/chrome/browser/extensions/api/preferences_private/preferences_private_api.h
+++ b/chrome/browser/extensions/api/preferences_private/preferences_private_api.h
@@ -29,7 +29,7 @@
   virtual void OnStateChanged() OVERRIDE;
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(
       PreferencesPrivateGetSyncCategoriesWithoutPassphraseFunction);
diff --git a/chrome/browser/extensions/api/processes/processes_api.cc b/chrome/browser/extensions/api/processes/processes_api.cc
index 70bc204..d09cc5e 100644
--- a/chrome/browser/extensions/api/processes/processes_api.cc
+++ b/chrome/browser/extensions/api/processes/processes_api.cc
@@ -538,7 +538,7 @@
 GetProcessIdForTabFunction::GetProcessIdForTabFunction() : tab_id_(-1) {
 }
 
-bool GetProcessIdForTabFunction::RunImpl() {
+bool GetProcessIdForTabFunction::RunAsync() {
 #if defined(ENABLE_TASK_MANAGER)
   EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id_));
 
@@ -592,14 +592,14 @@
     SendResponse(true);
   }
 
-  // Balance the AddRef in the RunImpl.
+  // Balance the AddRef in the RunAsync.
   Release();
 }
 
 TerminateFunction::TerminateFunction() : process_id_(-1) {
 }
 
-bool TerminateFunction::RunImpl() {
+bool TerminateFunction::RunAsync() {
 #if defined(ENABLE_TASK_MANAGER)
   EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &process_id_));
 
@@ -662,7 +662,7 @@
     SendResponse(true);
   }
 
-  // Balance the AddRef in the RunImpl.
+  // Balance the AddRef in the RunAsync.
   Release();
 #else
   error_ = errors::kExtensionNotSupported;
@@ -680,7 +680,7 @@
 GetProcessInfoFunction::~GetProcessInfoFunction() {
 }
 
-bool GetProcessInfoFunction::RunImpl() {
+bool GetProcessInfoFunction::RunAsync() {
 #if defined(ENABLE_TASK_MANAGER)
   base::Value* processes = NULL;
 
@@ -763,7 +763,7 @@
   SetResult(processes);
   SendResponse(true);
 
-  // Balance the AddRef in the RunImpl.
+  // Balance the AddRef in the RunAsync.
   Release();
 #endif  // defined(ENABLE_TASK_MANAGER)
 }
diff --git a/chrome/browser/extensions/api/processes/processes_api.h b/chrome/browser/extensions/api/processes/processes_api.h
index 035a705..dd89ca2 100644
--- a/chrome/browser/extensions/api/processes/processes_api.h
+++ b/chrome/browser/extensions/api/processes/processes_api.h
@@ -139,7 +139,7 @@
 
  private:
   virtual ~GetProcessIdForTabFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   void GetProcessIdForTab();
 
@@ -161,8 +161,7 @@
 
  private:
   virtual ~TerminateFunction() {}
-  virtual bool RunImpl() OVERRIDE;
-
+  virtual bool RunAsync() OVERRIDE;
 
   void TerminateProcess();
 
@@ -181,7 +180,7 @@
 
  private:
   virtual ~GetProcessInfoFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   void GatherProcessInfo();
 
diff --git a/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc b/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc
index e7c1174..64a4282 100644
--- a/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc
+++ b/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc
@@ -112,7 +112,7 @@
     *bad_message = true;
     return false;
   }
-  if (!IsStringASCII(pac_url16)) {
+  if (!base::IsStringASCII(pac_url16)) {
     *error = "'pacScript.url' supports only ASCII URLs "
              "(encode URLs in Punycode format).";
     return false;
@@ -137,7 +137,7 @@
     *bad_message = true;
     return false;
   }
-  if (!IsStringASCII(pac_data16)) {
+  if (!base::IsStringASCII(pac_data16)) {
     *error = "'pacScript.data' supports only ASCII code"
              "(encode URLs in Punycode format).";
     return false;
@@ -169,7 +169,7 @@
     *bad_message = true;
     return false;
   }
-  if (!IsStringASCII(host16)) {
+  if (!base::IsStringASCII(host16)) {
     *error = ErrorUtils::FormatErrorMessage(
         "Invalid 'rules.???.host' entry '*'. 'host' field supports only ASCII "
         "URLs (encode URLs in Punycode format).",
@@ -272,7 +272,7 @@
       *bad_message = true;
       return false;
     }
-    if (!IsStringASCII(entry)) {
+    if (!base::IsStringASCII(entry)) {
       *error = "'rules.bypassList' supports only ASCII URLs "
                "(encode URLs in Punycode format).";
       return false;
diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc b/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc
index 5ed1365..5180d85 100644
--- a/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc
+++ b/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc
@@ -90,7 +90,7 @@
 
 PushMessagingGetChannelIdFunction::~PushMessagingGetChannelIdFunction() {}
 
-bool PushMessagingGetChannelIdFunction::RunImpl() {
+bool PushMessagingGetChannelIdFunction::RunAsync() {
   // Fetch the function arguments.
   scoped_ptr<glue::GetChannelId::Params> params(
       glue::GetChannelId::Params::Create(*args_));
@@ -222,7 +222,7 @@
                             timeout);
   }
 
-  // Balanced in RunImpl.
+  // Balanced in RunAsync.
   Release();
 }
 
diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_api.h b/chrome/browser/extensions/api/push_messaging/push_messaging_api.h
index 264a766..0b5884b 100644
--- a/chrome/browser/extensions/api/push_messaging/push_messaging_api.h
+++ b/chrome/browser/extensions/api/push_messaging/push_messaging_api.h
@@ -66,7 +66,7 @@
   virtual ~PushMessagingGetChannelIdFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   DECLARE_EXTENSION_FUNCTION("pushMessaging.getChannelId",
                              PUSHMESSAGING_GETCHANNELID)
 
diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler.cc b/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler.cc
index a060864..8168d30 100644
--- a/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler.cc
+++ b/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler.cc
@@ -158,7 +158,7 @@
 
       // We always forward unknown version invalidation when we receive one.
       if (invalidation_list.StartsWithUnknownVersion()) {
-        DVLOG(2) << "Sending push message to reciever, extension is "
+        DVLOG(2) << "Sending push message to receiver, extension is "
             << extension_id << ", subchannel is " << subchannel
             << "and payload was lost";
         delegate_->OnMessage(extension_id, subchannel, std::string());
@@ -169,7 +169,7 @@
       if (!max_invalidation.is_unknown_version() &&
           max_invalidation.version() > max_object_version_map_[*it]) {
         max_object_version_map_[*it] = max_invalidation.version();
-        DVLOG(2) << "Sending push message to reciever, extension is "
+        DVLOG(2) << "Sending push message to receiver, extension is "
             << extension_id << ", subchannel is " << subchannel
             << ", and payload is " << max_invalidation.payload();
         delegate_->OnMessage(extension_id,
diff --git a/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.cc b/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.cc
index 605a648..7676c05 100644
--- a/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.cc
+++ b/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.cc
@@ -25,7 +25,7 @@
 using dom_distiller::DomDistillerService;
 using dom_distiller::DomDistillerServiceFactory;
 
-bool ReadingListPrivateAddEntryFunction::RunImpl() {
+bool ReadingListPrivateAddEntryFunction::RunAsync() {
   scoped_ptr<AddEntry::Params> params(AddEntry::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
   GURL url_to_add(params->entry.url);
diff --git a/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.h b/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.h
index c88cb01..bedc0fb 100644
--- a/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.h
+++ b/chrome/browser/extensions/api/reading_list_private/reading_list_private_api.h
@@ -24,7 +24,7 @@
   virtual ~ReadingListPrivateAddEntryFunction() {}
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class ReadingListPrivateRemoveEntryFunction
diff --git a/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc b/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc
new file mode 100644
index 0000000..59e611c
--- /dev/null
+++ b/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc
@@ -0,0 +1,284 @@
+// 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.
+
+#include "chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/metrics/histogram.h"
+#include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_warning_service.h"
+#include "chrome/browser/extensions/extension_warning_set.h"
+#include "chrome/browser/extensions/updater/extension_updater.h"
+#include "chrome/browser/omaha_query_params/omaha_query_params.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "content/public/browser/notification_service.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/common/api/runtime.h"
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/power_manager_client.h"
+#endif
+
+using extensions::Extension;
+using extensions::ExtensionSystem;
+using extensions::ExtensionUpdater;
+
+using extensions::core_api::runtime::PlatformInfo;
+
+namespace {
+
+const char kUpdateThrottled[] = "throttled";
+const char kUpdateNotFound[] = "no_update";
+const char kUpdateFound[] = "update_available";
+
+// If an extension reloads itself within this many miliseconds of reloading
+// itself, the reload is considered suspiciously fast.
+const int kFastReloadTime = 10000;
+
+// After this many suspiciously fast consecutive reloads, an extension will get
+// disabled.
+const int kFastReloadCount = 5;
+
+}  // namespace
+
+ChromeRuntimeAPIDelegate::ChromeRuntimeAPIDelegate(
+    content::BrowserContext* context)
+    : browser_context_(context), registered_for_updates_(false) {
+  registrar_.Add(this,
+                 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
+                 content::NotificationService::AllSources());
+}
+
+ChromeRuntimeAPIDelegate::~ChromeRuntimeAPIDelegate() {
+}
+
+void ChromeRuntimeAPIDelegate::AddUpdateObserver(
+    extensions::UpdateObserver* observer) {
+  registered_for_updates_ = true;
+  ExtensionSystem::Get(browser_context_)
+      ->extension_service()
+      ->AddUpdateObserver(observer);
+}
+
+void ChromeRuntimeAPIDelegate::RemoveUpdateObserver(
+    extensions::UpdateObserver* observer) {
+  if (registered_for_updates_) {
+    ExtensionSystem::Get(browser_context_)
+        ->extension_service()
+        ->RemoveUpdateObserver(observer);
+  }
+}
+
+base::Version ChromeRuntimeAPIDelegate::GetPreviousExtensionVersion(
+    const Extension* extension) {
+  // Get the previous version to check if this is an upgrade.
+  ExtensionService* service =
+      ExtensionSystem::Get(browser_context_)->extension_service();
+  const Extension* old = service->GetExtensionById(extension->id(), true);
+  if (old)
+    return *old->version();
+  return base::Version();
+}
+
+void ChromeRuntimeAPIDelegate::ReloadExtension(
+    const std::string& extension_id) {
+  std::pair<base::TimeTicks, int>& reload_info =
+      last_reload_time_[extension_id];
+  base::TimeTicks now = base::TimeTicks::Now();
+  if (reload_info.first.is_null() ||
+      (now - reload_info.first).InMilliseconds() > kFastReloadTime) {
+    reload_info.second = 0;
+  } else {
+    reload_info.second++;
+  }
+  if (!reload_info.first.is_null()) {
+    UMA_HISTOGRAM_LONG_TIMES("Extensions.RuntimeReloadTime",
+                             now - reload_info.first);
+  }
+  UMA_HISTOGRAM_COUNTS_100("Extensions.RuntimeReloadFastCount",
+                           reload_info.second);
+  reload_info.first = now;
+
+  ExtensionService* service =
+      ExtensionSystem::Get(browser_context_)->extension_service();
+  if (reload_info.second >= kFastReloadCount) {
+    // Unloading an extension clears all warnings, so first terminate the
+    // extension, and then add the warning. Since this is called from an
+    // extension function unloading the extension has to be done
+    // asynchronously. Fortunately PostTask guarentees FIFO order so just
+    // post both tasks.
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(&ExtensionService::TerminateExtension,
+                   service->AsWeakPtr(),
+                   extension_id));
+    extensions::ExtensionWarningSet warnings;
+    warnings.insert(
+        extensions::ExtensionWarning::CreateReloadTooFrequentWarning(
+            extension_id));
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(&extensions::ExtensionWarningService::NotifyWarningsOnUI,
+                   browser_context_,
+                   warnings));
+  } else {
+    // We can't call ReloadExtension directly, since when this method finishes
+    // it tries to decrease the reference count for the extension, which fails
+    // if the extension has already been reloaded; so instead we post a task.
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(&ExtensionService::ReloadExtension,
+                   service->AsWeakPtr(),
+                   extension_id));
+  }
+}
+
+bool ChromeRuntimeAPIDelegate::CheckForUpdates(
+    const std::string& extension_id,
+    const UpdateCheckCallback& callback) {
+  ExtensionSystem* system = ExtensionSystem::Get(browser_context_);
+  ExtensionService* service = system->extension_service();
+  ExtensionUpdater* updater = service->updater();
+  if (!updater) {
+    return false;
+  }
+  if (!updater->CheckExtensionSoon(
+          extension_id,
+          base::Bind(&ChromeRuntimeAPIDelegate::UpdateCheckComplete,
+                     base::Unretained(this),
+                     extension_id))) {
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(callback, UpdateCheckResult(true, kUpdateThrottled, "")));
+  } else {
+    UpdateCallbackList& callbacks = pending_update_checks_[extension_id];
+    callbacks.push_back(callback);
+  }
+  return true;
+}
+
+void ChromeRuntimeAPIDelegate::OpenURL(const GURL& uninstall_url) {
+#if defined(ENABLE_EXTENSIONS)
+  Profile* profile = Profile::FromBrowserContext(browser_context_);
+  Browser* browser =
+      chrome::FindLastActiveWithProfile(profile, chrome::GetActiveDesktop());
+  if (!browser)
+    browser =
+        new Browser(Browser::CreateParams(profile, chrome::GetActiveDesktop()));
+
+  chrome::NavigateParams params(
+      browser, uninstall_url, content::PAGE_TRANSITION_CLIENT_REDIRECT);
+  params.disposition = NEW_FOREGROUND_TAB;
+  params.user_gesture = false;
+  chrome::Navigate(&params);
+#endif
+}
+
+bool ChromeRuntimeAPIDelegate::GetPlatformInfo(PlatformInfo* info) {
+  const char* os = chrome::OmahaQueryParams::GetOS();
+  if (strcmp(os, "mac") == 0) {
+    info->os = PlatformInfo::OS_MAC_;
+  } else if (strcmp(os, "win") == 0) {
+    info->os = PlatformInfo::OS_WIN_;
+  } else if (strcmp(os, "android") == 0) {
+    info->os = PlatformInfo::OS_ANDROID_;
+  } else if (strcmp(os, "cros") == 0) {
+    info->os = PlatformInfo::OS_CROS_;
+  } else if (strcmp(os, "linux") == 0) {
+    info->os = PlatformInfo::OS_LINUX_;
+  } else if (strcmp(os, "openbsd") == 0) {
+    info->os = PlatformInfo::OS_OPENBSD_;
+  } else {
+    NOTREACHED();
+    return false;
+  }
+
+  const char* arch = chrome::OmahaQueryParams::GetArch();
+  if (strcmp(arch, "arm") == 0) {
+    info->arch = PlatformInfo::ARCH_ARM;
+  } else if (strcmp(arch, "x86") == 0) {
+    info->arch = PlatformInfo::ARCH_X86_32;
+  } else if (strcmp(arch, "x64") == 0) {
+    info->arch = PlatformInfo::ARCH_X86_64;
+  } else {
+    NOTREACHED();
+    return false;
+  }
+
+  const char* nacl_arch = chrome::OmahaQueryParams::GetNaclArch();
+  if (strcmp(nacl_arch, "arm") == 0) {
+    info->nacl_arch = PlatformInfo::NACL_ARCH_ARM;
+  } else if (strcmp(nacl_arch, "x86-32") == 0) {
+    info->nacl_arch = PlatformInfo::NACL_ARCH_X86_32;
+  } else if (strcmp(nacl_arch, "x86-64") == 0) {
+    info->nacl_arch = PlatformInfo::NACL_ARCH_X86_64;
+  } else {
+    NOTREACHED();
+    return false;
+  }
+
+  return true;
+}
+
+bool ChromeRuntimeAPIDelegate::RestartDevice(std::string* error_message) {
+#if defined(OS_CHROMEOS)
+  if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp()) {
+    chromeos::DBusThreadManager::Get()
+        ->GetPowerManagerClient()
+        ->RequestRestart();
+    return true;
+  }
+#endif
+  *error_message = "Function available only for ChromeOS kiosk mode.";
+  return false;
+}
+
+void ChromeRuntimeAPIDelegate::Observe(
+    int type,
+    const content::NotificationSource& source,
+    const content::NotificationDetails& details) {
+  DCHECK(type == chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND);
+  typedef const std::pair<std::string, Version> UpdateDetails;
+  const std::string& id = content::Details<UpdateDetails>(details)->first;
+  const Version& version = content::Details<UpdateDetails>(details)->second;
+  if (version.IsValid()) {
+    CallUpdateCallbacks(
+        id, UpdateCheckResult(true, kUpdateFound, version.GetString()));
+  }
+}
+
+void ChromeRuntimeAPIDelegate::UpdateCheckComplete(
+    const std::string& extension_id) {
+  ExtensionSystem* system = ExtensionSystem::Get(browser_context_);
+  ExtensionService* service = system->extension_service();
+  const Extension* update = service->GetPendingExtensionUpdate(extension_id);
+  if (update) {
+    CallUpdateCallbacks(
+        extension_id,
+        UpdateCheckResult(true, kUpdateFound, update->VersionString()));
+  } else {
+    CallUpdateCallbacks(extension_id,
+                        UpdateCheckResult(true, kUpdateNotFound, ""));
+  }
+}
+
+void ChromeRuntimeAPIDelegate::CallUpdateCallbacks(
+    const std::string& extension_id,
+    const UpdateCheckResult& result) {
+  UpdateCallbackList callbacks = pending_update_checks_[extension_id];
+  pending_update_checks_.erase(extension_id);
+  for (UpdateCallbackList::const_iterator iter = callbacks.begin();
+       iter != callbacks.end();
+       ++iter) {
+    const UpdateCheckCallback& callback = *iter;
+    callback.Run(result);
+  }
+}
diff --git a/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h b/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h
new file mode 100644
index 0000000..cdb6e7a
--- /dev/null
+++ b/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h
@@ -0,0 +1,86 @@
+// 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_RUNTIME_CHROME_RUNTIME_API_DELEGATE_H_
+#define CHROME_BROWSER_EXTENSIONS_API_RUNTIME_CHROME_RUNTIME_API_DELEGATE_H_
+
+#include <map>
+#include <vector>
+
+#include "base/macros.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "extensions/browser/api/runtime/runtime_api.h"
+#include "extensions/browser/api/runtime/runtime_api_delegate.h"
+
+namespace base {
+class TimeTicks;
+}
+
+namespace content {
+class BrowserContext;
+class NotificationDetails;
+class NotificationSource;
+}
+
+namespace extensions {
+class RuntimeAPI;
+class UpdateObserver;
+}
+
+class ChromeRuntimeAPIDelegate : public extensions::RuntimeAPIDelegate,
+                                 public content::NotificationObserver {
+ public:
+  explicit ChromeRuntimeAPIDelegate(content::BrowserContext* context);
+  virtual ~ChromeRuntimeAPIDelegate();
+
+ private:
+  friend class extensions::RuntimeAPI;
+
+  // extensions::RuntimeAPIDelegate implementation.
+  virtual void AddUpdateObserver(extensions::UpdateObserver* observer) OVERRIDE;
+  virtual void RemoveUpdateObserver(
+      extensions::UpdateObserver* observer) OVERRIDE;
+  virtual base::Version GetPreviousExtensionVersion(
+      const extensions::Extension* extension) OVERRIDE;
+  virtual void ReloadExtension(const std::string& extension_id) OVERRIDE;
+  virtual bool CheckForUpdates(const std::string& extension_id,
+                               const UpdateCheckCallback& callback) OVERRIDE;
+  virtual void OpenURL(const GURL& uninstall_url) OVERRIDE;
+  virtual bool GetPlatformInfo(
+      extensions::core_api::runtime::PlatformInfo* info) OVERRIDE;
+  virtual bool RestartDevice(std::string* error_message) OVERRIDE;
+
+  // content::NotificationObserver implementation.
+  virtual void Observe(int type,
+                       const content::NotificationSource& source,
+                       const content::NotificationDetails& details) OVERRIDE;
+
+  void UpdateCheckComplete(const std::string& extension_id);
+  void CallUpdateCallbacks(const std::string& extension_id,
+                           const UpdateCheckResult& result);
+
+  content::BrowserContext* browser_context_;
+
+  content::NotificationRegistrar registrar_;
+
+  // Whether the API registered with the ExtensionService to receive
+  // update notifications.
+  bool registered_for_updates_;
+
+  // Map to prevent extensions from getting stuck in reload loops. Maps
+  // extension id to the last time it was reloaded and the number of times
+  // it was reloaded with not enough time in between reloads.
+  std::map<std::string, std::pair<base::TimeTicks, int> > last_reload_time_;
+
+  // Pending update checks.
+  typedef std::vector<UpdateCheckCallback> UpdateCallbackList;
+  typedef std::map<std::string, UpdateCallbackList> UpdateCallbackMap;
+  UpdateCallbackMap pending_update_checks_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ChromeRuntimeAPIDelegate);
+};
+
+#endif  // CHROME_BROWSER_EXTENSIONS_API_RUNTIME_CHROME_RUNTIME_API_DELEGATE_H_
diff --git a/chrome/browser/extensions/api/runtime/runtime_api.cc b/chrome/browser/extensions/api/runtime/runtime_api.cc
deleted file mode 100644
index 59ff72e..0000000
--- a/chrome/browser/extensions/api/runtime/runtime_api.cc
+++ /dev/null
@@ -1,678 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/extensions/api/runtime/runtime_api.h"
-
-#include <utility>
-
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/metrics/histogram.h"
-#include "base/values.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_warning_service.h"
-#include "chrome/browser/extensions/updater/extension_updater.h"
-#include "chrome/browser/omaha_query_params/omaha_query_params.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_navigator.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/extensions/api/runtime.h"
-#include "content/public/browser/child_process_security_policy.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
-#include "extensions/browser/event_router.h"
-#include "extensions/browser/extension_host.h"
-#include "extensions/browser/extension_registry.h"
-#include "extensions/browser/extension_system.h"
-#include "extensions/browser/extensions_browser_client.h"
-#include "extensions/browser/lazy_background_task_queue.h"
-#include "extensions/browser/process_manager.h"
-#include "extensions/common/error_utils.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/manifest_handlers/background_info.h"
-#include "url/gurl.h"
-#include "webkit/browser/fileapi/isolated_context.h"
-
-#if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/login/user_manager.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/power_manager_client.h"
-#endif
-
-using content::BrowserContext;
-
-namespace GetPlatformInfo = extensions::api::runtime::GetPlatformInfo;
-
-namespace extensions {
-
-namespace runtime = api::runtime;
-
-namespace {
-
-const char kNoBackgroundPageError[] = "You do not have a background page.";
-const char kPageLoadError[] = "Background page failed to load.";
-const char kInstallReason[] = "reason";
-const char kInstallReasonChromeUpdate[] = "chrome_update";
-const char kInstallReasonUpdate[] = "update";
-const char kInstallReasonInstall[] = "install";
-const char kInstallPreviousVersion[] = "previousVersion";
-const char kInvalidUrlError[] = "Invalid URL.";
-const char kUpdatesDisabledError[] = "Autoupdate is not enabled.";
-const char kUpdateFound[] = "update_available";
-const char kUpdateNotFound[] = "no_update";
-const char kUpdateThrottled[] = "throttled";
-
-// A preference key storing the url loaded when an extension is uninstalled.
-const char kUninstallUrl[] = "uninstall_url";
-
-// The name of the directory to be returned by getPackageDirectoryEntry. This
-// particular value does not matter to user code, but is chosen for consistency
-// with the equivalent Pepper API.
-const char kPackageDirectoryPath[] = "crxfs";
-
-// If an extension reloads itself within this many miliseconds of reloading
-// itself, the reload is considered suspiciously fast.
-const int kFastReloadTime = 10000;
-
-// After this many suspiciously fast consecutive reloads, an extension will get
-// disabled.
-const int kFastReloadCount = 5;
-
-void DispatchOnStartupEventImpl(BrowserContext* browser_context,
-                                const std::string& extension_id,
-                                bool first_call,
-                                ExtensionHost* host) {
-  // A NULL host from the LazyBackgroundTaskQueue means the page failed to
-  // load. Give up.
-  if (!host && !first_call)
-    return;
-
-  // Don't send onStartup events to incognito browser contexts.
-  if (browser_context->IsOffTheRecord())
-    return;
-
-  if (ExtensionsBrowserClient::Get()->IsShuttingDown() ||
-      !ExtensionsBrowserClient::Get()->IsValidContext(browser_context))
-    return;
-  ExtensionSystem* system = ExtensionSystem::Get(browser_context);
-  if (!system)
-    return;
-
-  // If this is a persistent background page, we want to wait for it to load
-  // (it might not be ready, since this is startup). But only enqueue once.
-  // If it fails to load the first time, don't bother trying again.
-  const Extension* extension =
-      ExtensionRegistry::Get(browser_context)->enabled_extensions().GetByID(
-          extension_id);
-  if (extension && BackgroundInfo::HasPersistentBackgroundPage(extension) &&
-      first_call &&
-      system->lazy_background_task_queue()->
-          ShouldEnqueueTask(browser_context, extension)) {
-    system->lazy_background_task_queue()->AddPendingTask(
-        browser_context, extension_id,
-        base::Bind(&DispatchOnStartupEventImpl,
-                   browser_context, extension_id, false));
-    return;
-  }
-
-  scoped_ptr<base::ListValue> event_args(new base::ListValue());
-  scoped_ptr<Event> event(new Event(runtime::OnStartup::kEventName,
-                                    event_args.Pass()));
-  system->event_router()->DispatchEventToExtension(extension_id, event.Pass());
-}
-
-void SetUninstallURL(ExtensionPrefs* prefs,
-                     const std::string& extension_id,
-                     const std::string& url_string) {
-  prefs->UpdateExtensionPref(extension_id,
-                             kUninstallUrl,
-                             new base::StringValue(url_string));
-}
-
-#if defined(ENABLE_EXTENSIONS)
-std::string GetUninstallURL(ExtensionPrefs* prefs,
-                            const std::string& extension_id) {
-  std::string url_string;
-  prefs->ReadPrefAsString(extension_id, kUninstallUrl, &url_string);
-  return url_string;
-}
-#endif  // defined(ENABLE_EXTENSIONS)
-
-}  // namespace
-
-///////////////////////////////////////////////////////////////////////////////
-
-static base::LazyInstance<BrowserContextKeyedAPIFactory<RuntimeAPI> >
-    g_factory = LAZY_INSTANCE_INITIALIZER;
-
-// static
-BrowserContextKeyedAPIFactory<RuntimeAPI>* RuntimeAPI::GetFactoryInstance() {
-  return g_factory.Pointer();
-}
-
-RuntimeAPI::RuntimeAPI(content::BrowserContext* context)
-    : browser_context_(context),
-      dispatch_chrome_updated_event_(false),
-      registered_for_updates_(false) {
-  registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
-                 content::Source<BrowserContext>(context));
-  registrar_.Add(this,
-                 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
-                 content::Source<BrowserContext>(context));
-  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
-                 content::Source<BrowserContext>(context));
-  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
-                 content::Source<BrowserContext>(context));
-
-  // Check if registered events are up-to-date. We can only do this once
-  // per browser context, since it updates internal state when called.
-  dispatch_chrome_updated_event_ =
-      ExtensionsBrowserClient::Get()->DidVersionUpdate(browser_context_);
-}
-
-RuntimeAPI::~RuntimeAPI() {
-  if (registered_for_updates_) {
-    ExtensionSystem::Get(browser_context_)->
-        extension_service()->RemoveUpdateObserver(this);
-  }
-}
-
-void RuntimeAPI::Observe(int type,
-                         const content::NotificationSource& source,
-                         const content::NotificationDetails& details) {
-  switch (type) {
-    case chrome::NOTIFICATION_EXTENSIONS_READY: {
-      OnExtensionsReady();
-      break;
-    }
-    case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
-      const Extension* extension =
-          content::Details<const Extension>(details).ptr();
-      OnExtensionLoaded(extension);
-      break;
-    }
-    case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
-      const Extension* extension =
-          content::Details<const InstalledExtensionInfo>(details)->extension;
-      OnExtensionInstalled(extension);
-      break;
-    }
-    case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
-      const Extension* extension =
-          content::Details<const Extension>(details).ptr();
-      OnExtensionUninstalled(extension);
-      break;
-    }
-    default:
-      NOTREACHED();
-      break;
-  }
-}
-
-void RuntimeAPI::OnExtensionsReady() {
-  // We're done restarting Chrome after an update.
-  dispatch_chrome_updated_event_ = false;
-
-  registered_for_updates_ = true;
-
-  ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_);
-  extension_system->extension_service()->AddUpdateObserver(this);
-
-  // RuntimeAPI is redirected in incognito, so |browser_context_| is never
-  // incognito. We don't observe incognito ProcessManagers but that is OK
-  // because we don't send onStartup events to incognito browser contexts.
-  DCHECK(!browser_context_->IsOffTheRecord());
-  // Some tests use partially constructed Profiles without a process manager.
-  if (extension_system->process_manager())
-    extension_system->process_manager()->AddObserver(this);
-}
-
-void RuntimeAPI::OnExtensionLoaded(const Extension* extension) {
-  if (!dispatch_chrome_updated_event_)
-    return;
-
-  // Dispatch the onInstalled event with reason "chrome_update".
-  base::MessageLoop::current()->PostTask(
-      FROM_HERE,
-      base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent,
-                 browser_context_,
-                 extension->id(),
-                 Version(),
-                 true));
-}
-
-void RuntimeAPI::OnExtensionInstalled(const Extension* extension) {
-  // Ephemeral apps are not considered to be installed and do not receive
-  // the onInstalled() event.
-  if (extension->is_ephemeral())
-    return;
-
-  // Get the previous version to check if this is an upgrade.
-  ExtensionService* service = ExtensionSystem::Get(
-      browser_context_)->extension_service();
-  const Extension* old = service->GetExtensionById(extension->id(), true);
-  Version old_version;
-  if (old)
-    old_version = *old->version();
-
-  // Dispatch the onInstalled event.
-  base::MessageLoop::current()->PostTask(
-      FROM_HERE,
-      base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent,
-                 browser_context_,
-                 extension->id(),
-                 old_version,
-                 false));
-
-}
-
-void RuntimeAPI::OnExtensionUninstalled(const Extension* extension) {
-  // Ephemeral apps are not considered to be installed, so the uninstall URL
-  // is not invoked when they are removed.
-  if (extension->is_ephemeral())
-    return;
-
-  Profile* profile = Profile::FromBrowserContext(browser_context_);
-  RuntimeEventRouter::OnExtensionUninstalled(profile, extension->id());
-}
-
-void RuntimeAPI::Shutdown() {
-  // ExtensionSystem deletes its ProcessManager during the Shutdown() phase, so
-  // the observer must be removed here and not in the RuntimeAPI destructor.
-  ProcessManager* process_manager =
-      ExtensionSystem::Get(browser_context_)->process_manager();
-  // Some tests use partially constructed Profiles without a process manager.
-  if (process_manager)
-    process_manager->RemoveObserver(this);
-}
-
-void RuntimeAPI::OnAppUpdateAvailable(const Extension* extension) {
-  Profile* profile = Profile::FromBrowserContext(browser_context_);
-  RuntimeEventRouter::DispatchOnUpdateAvailableEvent(
-      profile, extension->id(), extension->manifest()->value());
-}
-
-void RuntimeAPI::OnChromeUpdateAvailable() {
-  Profile* profile = Profile::FromBrowserContext(browser_context_);
-  RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(profile);
-}
-
-void RuntimeAPI::OnBackgroundHostStartup(const Extension* extension) {
-  RuntimeEventRouter::DispatchOnStartupEvent(browser_context_, extension->id());
-}
-
-void RuntimeAPI::MaybeReloadExtension(const std::string& extension_id) {
-  std::pair<base::TimeTicks, int>& reload_info =
-      last_reload_time_[extension_id];
-  base::TimeTicks now = base::TimeTicks::Now();
-  if (reload_info.first.is_null() ||
-      (now - reload_info.first).InMilliseconds() > kFastReloadTime) {
-    reload_info.second = 0;
-  } else {
-    reload_info.second++;
-  }
-  if (!reload_info.first.is_null()) {
-    UMA_HISTOGRAM_LONG_TIMES("Extensions.RuntimeReloadTime",
-                             now - reload_info.first);
-  }
-  UMA_HISTOGRAM_COUNTS_100("Extensions.RuntimeReloadFastCount",
-                           reload_info.second);
-  reload_info.first = now;
-
-  ExtensionService* service =
-      ExtensionSystem::Get(browser_context_)->extension_service();
-  if (reload_info.second >= kFastReloadCount) {
-    // Unloading an extension clears all warnings, so first terminate the
-    // extension, and then add the warning. Since this is called from an
-    // extension function unloading the extension has to be done
-    // asynchronously. Fortunately PostTask guarentees FIFO order so just
-    // post both tasks.
-    base::MessageLoop::current()->PostTask(
-        FROM_HERE,
-        base::Bind(&ExtensionService::TerminateExtension,
-                   service->AsWeakPtr(),
-                   extension_id));
-    ExtensionWarningSet warnings;
-    warnings.insert(
-        ExtensionWarning::CreateReloadTooFrequentWarning(extension_id));
-    base::MessageLoop::current()->PostTask(
-        FROM_HERE,
-        base::Bind(&ExtensionWarningService::NotifyWarningsOnUI,
-                   browser_context_,
-                   warnings));
-  } else {
-    // We can't call ReloadExtension directly, since when this method finishes
-    // it tries to decrease the reference count for the extension, which fails
-    // if the extension has already been reloaded; so instead we post a task.
-    base::MessageLoop::current()->PostTask(
-        FROM_HERE,
-        base::Bind(&ExtensionService::ReloadExtension,
-                   service->AsWeakPtr(),
-                   extension_id));
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-// static
-void RuntimeEventRouter::DispatchOnStartupEvent(
-    content::BrowserContext* context, const std::string& extension_id) {
-  DispatchOnStartupEventImpl(context, extension_id, true, NULL);
-}
-
-// static
-void RuntimeEventRouter::DispatchOnInstalledEvent(
-    content::BrowserContext* context,
-    const std::string& extension_id,
-    const Version& old_version,
-    bool chrome_updated) {
-  if (!ExtensionsBrowserClient::Get()->IsValidContext(context))
-    return;
-  ExtensionSystem* system = ExtensionSystem::Get(context);
-  if (!system)
-    return;
-
-  scoped_ptr<base::ListValue> event_args(new base::ListValue());
-  base::DictionaryValue* info = new base::DictionaryValue();
-  event_args->Append(info);
-  if (old_version.IsValid()) {
-    info->SetString(kInstallReason, kInstallReasonUpdate);
-    info->SetString(kInstallPreviousVersion, old_version.GetString());
-  } else if (chrome_updated) {
-    info->SetString(kInstallReason, kInstallReasonChromeUpdate);
-  } else {
-    info->SetString(kInstallReason, kInstallReasonInstall);
-  }
-  DCHECK(system->event_router());
-  scoped_ptr<Event> event(new Event(runtime::OnInstalled::kEventName,
-                                    event_args.Pass()));
-  system->event_router()->DispatchEventWithLazyListener(extension_id,
-                                                        event.Pass());
-}
-
-// static
-void RuntimeEventRouter::DispatchOnUpdateAvailableEvent(
-    Profile* profile,
-    const std::string& extension_id,
-    const base::DictionaryValue* manifest) {
-  ExtensionSystem* system = ExtensionSystem::Get(profile);
-  if (!system)
-    return;
-
-  scoped_ptr<base::ListValue> args(new base::ListValue);
-  args->Append(manifest->DeepCopy());
-  DCHECK(system->event_router());
-  scoped_ptr<Event> event(new Event(runtime::OnUpdateAvailable::kEventName,
-                                    args.Pass()));
-  system->event_router()->DispatchEventToExtension(extension_id, event.Pass());
-}
-
-// static
-void RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(
-    Profile* profile) {
-  ExtensionSystem* system = ExtensionSystem::Get(profile);
-  if (!system)
-    return;
-
-  scoped_ptr<base::ListValue> args(new base::ListValue);
-  DCHECK(system->event_router());
-  scoped_ptr<Event> event(new Event(
-      runtime::OnBrowserUpdateAvailable::kEventName, args.Pass()));
-  system->event_router()->BroadcastEvent(event.Pass());
-}
-
-// static
-void RuntimeEventRouter::DispatchOnRestartRequiredEvent(
-    Profile* profile,
-    const std::string& app_id,
-    api::runtime::OnRestartRequired::Reason reason) {
-  ExtensionSystem* system = ExtensionSystem::Get(profile);
-  if (!system)
-    return;
-
-  scoped_ptr<Event> event(
-      new Event(runtime::OnRestartRequired::kEventName,
-                api::runtime::OnRestartRequired::Create(reason)));
-
-  DCHECK(system->event_router());
-  system->event_router()->DispatchEventToExtension(app_id, event.Pass());
-}
-
-// static
-void RuntimeEventRouter::OnExtensionUninstalled(
-    Profile* profile,
-    const std::string& extension_id) {
-#if defined(ENABLE_EXTENSIONS)
-  GURL uninstall_url(GetUninstallURL(ExtensionPrefs::Get(profile),
-                                     extension_id));
-
-  if (uninstall_url.is_empty())
-    return;
-
-  Browser* browser = chrome::FindLastActiveWithProfile(profile,
-      chrome::GetActiveDesktop());
-  if (!browser)
-    browser = new Browser(Browser::CreateParams(profile,
-                                                chrome::GetActiveDesktop()));
-
-  chrome::NavigateParams params(browser, uninstall_url,
-                                content::PAGE_TRANSITION_CLIENT_REDIRECT);
-  params.disposition = NEW_FOREGROUND_TAB;
-  params.user_gesture = false;
-  chrome::Navigate(&params);
-#endif  // defined(ENABLE_EXTENSIONS)
-}
-
-bool RuntimeGetBackgroundPageFunction::RunImpl() {
-  ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
-  ExtensionHost* host = system->process_manager()->
-      GetBackgroundHostForExtension(extension_id());
-  if (system->lazy_background_task_queue()->ShouldEnqueueTask(GetProfile(),
-                                                              GetExtension())) {
-    system->lazy_background_task_queue()->AddPendingTask(
-        GetProfile(),
-        extension_id(),
-        base::Bind(&RuntimeGetBackgroundPageFunction::OnPageLoaded, this));
-  } else if (host) {
-    OnPageLoaded(host);
-  } else {
-    error_ = kNoBackgroundPageError;
-    return false;
-  }
-
-  return true;
-}
-
-void RuntimeGetBackgroundPageFunction::OnPageLoaded(ExtensionHost* host) {
-  if (host) {
-    SendResponse(true);
-  } else {
-    error_ = kPageLoadError;
-    SendResponse(false);
-  }
-}
-
-bool RuntimeSetUninstallURLFunction::RunSync() {
-  std::string url_string;
-  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url_string));
-
-  GURL url(url_string);
-  if (!url.is_valid()) {
-    error_ = ErrorUtils::FormatErrorMessage(kInvalidUrlError, url_string);
-    return false;
-  }
-
-  SetUninstallURL(
-      ExtensionPrefs::Get(GetProfile()), extension_id(), url_string);
-  return true;
-}
-
-bool RuntimeReloadFunction::RunSync() {
-  RuntimeAPI::GetFactoryInstance()->Get(GetProfile())->MaybeReloadExtension(
-      extension_id());
-  return true;
-}
-
-RuntimeRequestUpdateCheckFunction::RuntimeRequestUpdateCheckFunction() {
-  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
-                 content::NotificationService::AllSources());
-}
-
-bool RuntimeRequestUpdateCheckFunction::RunImpl() {
-  ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
-  ExtensionService* service = system->extension_service();
-  ExtensionUpdater* updater = service->updater();
-  if (!updater) {
-    error_ = kUpdatesDisabledError;
-    return false;
-  }
-
-  did_reply_ = false;
-  if (!updater->CheckExtensionSoon(extension_id(), base::Bind(
-      &RuntimeRequestUpdateCheckFunction::CheckComplete, this))) {
-    did_reply_ = true;
-    SetResult(new base::StringValue(kUpdateThrottled));
-    SendResponse(true);
-  }
-  return true;
-}
-
-void RuntimeRequestUpdateCheckFunction::CheckComplete() {
-  if (did_reply_)
-    return;
-
-  did_reply_ = true;
-
-  // Since no UPDATE_FOUND notification was seen, this generally would mean
-  // that no update is found, but a previous update check might have already
-  // queued up an update, so check for that here to make sure we return the
-  // right value.
-  ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
-  ExtensionService* service = system->extension_service();
-  const Extension* update = service->GetPendingExtensionUpdate(extension_id());
-  if (update) {
-    ReplyUpdateFound(update->VersionString());
-  } else {
-    SetResult(new base::StringValue(kUpdateNotFound));
-  }
-  SendResponse(true);
-}
-
-void RuntimeRequestUpdateCheckFunction::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  if (did_reply_)
-    return;
-
-  DCHECK(type == chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND);
-  typedef const std::pair<std::string, Version> UpdateDetails;
-  const std::string& id = content::Details<UpdateDetails>(details)->first;
-  const Version& version = content::Details<UpdateDetails>(details)->second;
-  if (id == extension_id()) {
-    ReplyUpdateFound(version.GetString());
-  }
-}
-
-void RuntimeRequestUpdateCheckFunction::ReplyUpdateFound(
-    const std::string& version) {
-  did_reply_ = true;
-  results_.reset(new base::ListValue);
-  results_->AppendString(kUpdateFound);
-  base::DictionaryValue* details = new base::DictionaryValue;
-  results_->Append(details);
-  details->SetString("version", version);
-  SendResponse(true);
-}
-
-bool RuntimeRestartFunction::RunSync() {
-#if defined(OS_CHROMEOS)
-  if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp()) {
-    chromeos::DBusThreadManager::Get()
-        ->GetPowerManagerClient()
-        ->RequestRestart();
-    return true;
-  }
-#endif
-  SetError("Function available only for ChromeOS kiosk mode.");
-  return false;
-}
-
-bool RuntimeGetPlatformInfoFunction::RunSync() {
-  GetPlatformInfo::Results::PlatformInfo info;
-
-  const char* os = chrome::OmahaQueryParams::GetOS();
-  if (strcmp(os, "mac") == 0) {
-    info.os = GetPlatformInfo::Results::PlatformInfo::OS_MAC_;
-  } else if (strcmp(os, "win") == 0) {
-    info.os = GetPlatformInfo::Results::PlatformInfo::OS_WIN_;
-  } else if (strcmp(os, "android") == 0) {
-    info.os = GetPlatformInfo::Results::PlatformInfo::OS_ANDROID_;
-  } else if (strcmp(os, "cros") == 0) {
-    info.os = GetPlatformInfo::Results::PlatformInfo::OS_CROS_;
-  } else if (strcmp(os, "linux") == 0) {
-    info.os = GetPlatformInfo::Results::PlatformInfo::OS_LINUX_;
-  } else if (strcmp(os, "openbsd") == 0) {
-    info.os = GetPlatformInfo::Results::PlatformInfo::OS_OPENBSD_;
-  } else {
-    NOTREACHED();
-    return false;
-  }
-
-  const char* arch = chrome::OmahaQueryParams::GetArch();
-  if (strcmp(arch, "arm") == 0) {
-    info.arch = GetPlatformInfo::Results::PlatformInfo::ARCH_ARM;
-  } else if (strcmp(arch, "x86") == 0) {
-    info.arch = GetPlatformInfo::Results::PlatformInfo::ARCH_X86_32;
-  } else if (strcmp(arch, "x64") == 0) {
-    info.arch = GetPlatformInfo::Results::PlatformInfo::ARCH_X86_64;
-  } else {
-    NOTREACHED();
-    return false;
-  }
-
-  const char* nacl_arch = chrome::OmahaQueryParams::GetNaclArch();
-  if (strcmp(nacl_arch, "arm") == 0) {
-    info.nacl_arch = GetPlatformInfo::Results::PlatformInfo::NACL_ARCH_ARM;
-  } else if (strcmp(nacl_arch, "x86-32") == 0) {
-    info.nacl_arch = GetPlatformInfo::Results::PlatformInfo::NACL_ARCH_X86_32;
-  } else if (strcmp(nacl_arch, "x86-64") == 0) {
-    info.nacl_arch = GetPlatformInfo::Results::PlatformInfo::NACL_ARCH_X86_64;
-  } else {
-    NOTREACHED();
-    return false;
-  }
-
-  results_ = GetPlatformInfo::Results::Create(info);
-  return true;
-}
-
-bool RuntimeGetPackageDirectoryEntryFunction::RunSync() {
-  fileapi::IsolatedContext* isolated_context =
-      fileapi::IsolatedContext::GetInstance();
-  DCHECK(isolated_context);
-
-  std::string relative_path = kPackageDirectoryPath;
-  base::FilePath path = extension_->path();
-  std::string filesystem_id = isolated_context->RegisterFileSystemForPath(
-      fileapi::kFileSystemTypeNativeLocal, path, &relative_path);
-
-  int renderer_id = render_view_host_->GetProcess()->GetID();
-  content::ChildProcessSecurityPolicy* policy =
-      content::ChildProcessSecurityPolicy::GetInstance();
-  policy->GrantReadFileSystem(renderer_id, filesystem_id);
-  base::DictionaryValue* dict = new base::DictionaryValue();
-  SetResult(dict);
-  dict->SetString("fileSystemId", filesystem_id);
-  dict->SetString("baseName", relative_path);
-  return true;
-}
-
-}   // namespace extensions
diff --git a/chrome/browser/extensions/api/runtime/runtime_api.h b/chrome/browser/extensions/api/runtime/runtime_api.h
deleted file mode 100644
index 4bc411c..0000000
--- a/chrome/browser/extensions/api/runtime/runtime_api.h
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_RUNTIME_RUNTIME_API_H_
-#define CHROME_BROWSER_EXTENSIONS_API_RUNTIME_RUNTIME_API_H_
-
-#include <string>
-
-#include "chrome/browser/extensions/chrome_extension_function.h"
-#include "chrome/common/extensions/api/runtime.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "extensions/browser/browser_context_keyed_api_factory.h"
-#include "extensions/browser/process_manager_observer.h"
-#include "extensions/browser/update_observer.h"
-
-class Profile;
-
-namespace base {
-class Version;
-}
-
-namespace content {
-class BrowserContext;
-}
-
-namespace extensions {
-class Extension;
-class ExtensionHost;
-
-// Runtime API dispatches onStartup, onInstalled, and similar events to
-// extensions. There is one instance shared between a browser context and
-// its related incognito instance.
-class RuntimeAPI : public BrowserContextKeyedAPI,
-                   public content::NotificationObserver,
-                   public UpdateObserver,
-                   public ProcessManagerObserver {
- public:
-  static BrowserContextKeyedAPIFactory<RuntimeAPI>* GetFactoryInstance();
-
-  explicit RuntimeAPI(content::BrowserContext* context);
-  virtual ~RuntimeAPI();
-
-  // content::NotificationObserver overrides:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) OVERRIDE;
-
-  void MaybeReloadExtension(const std::string& extension_id);
-
- private:
-  friend class BrowserContextKeyedAPIFactory<RuntimeAPI>;
-
-  void OnExtensionsReady();
-  void OnExtensionLoaded(const Extension* extension);
-  void OnExtensionInstalled(const Extension* extension);
-  void OnExtensionUninstalled(const Extension* extension);
-
-  // BrowserContextKeyedAPI implementation:
-  static const char* service_name() { return "RuntimeAPI"; }
-  static const bool kServiceRedirectedInIncognito = true;
-  static const bool kServiceIsNULLWhileTesting = true;
-  virtual void Shutdown() OVERRIDE;
-
-  // extensions::UpdateObserver overrides:
-  virtual void OnAppUpdateAvailable(const Extension* extension) OVERRIDE;
-  virtual void OnChromeUpdateAvailable() OVERRIDE;
-
-  // ProcessManagerObserver implementation:
-  virtual void OnBackgroundHostStartup(const Extension* extension) OVERRIDE;
-
-  content::BrowserContext* browser_context_;
-
-  // True if we should dispatch the chrome.runtime.onInstalled event with
-  // reason "chrome_update" upon loading each extension.
-  bool dispatch_chrome_updated_event_;
-
-  // Whether the API registered with the ExtensionService to receive
-  // update notifications.
-  bool registered_for_updates_;
-
-  content::NotificationRegistrar registrar_;
-
-  // Map to prevent extensions from getting stuck in reload loops. Maps
-  // extension id to the last time it was reloaded and the number of times
-  // it was reloaded with not enough time in between reloads.
-  std::map<std::string, std::pair<base::TimeTicks, int> > last_reload_time_;
-
-  DISALLOW_COPY_AND_ASSIGN(RuntimeAPI);
-};
-
-class RuntimeEventRouter {
- public:
-  // Dispatches the onStartup event to all currently-loaded extensions.
-  static void DispatchOnStartupEvent(content::BrowserContext* context,
-                                     const std::string& extension_id);
-
-  // Dispatches the onInstalled event to the given extension.
-  static void DispatchOnInstalledEvent(content::BrowserContext* context,
-                                       const std::string& extension_id,
-                                       const base::Version& old_version,
-                                       bool chrome_updated);
-
-  // Dispatches the onUpdateAvailable event to the given extension.
-  static void DispatchOnUpdateAvailableEvent(
-      Profile* profile,
-      const std::string& extension_id,
-      const base::DictionaryValue* manifest);
-
-  // Dispatches the onBrowserUpdateAvailable event to all extensions.
-  static void DispatchOnBrowserUpdateAvailableEvent(Profile* profile);
-
-  // Dispatches the onRestartRequired event to the given app.
-  static void DispatchOnRestartRequiredEvent(
-      Profile* profile,
-      const std::string& app_id,
-      api::runtime::OnRestartRequired::Reason reason);
-
-  // Does any work needed at extension uninstall (e.g. load uninstall url).
-  static void OnExtensionUninstalled(Profile* profile,
-                                     const std::string& extension_id);
-};
-
-class RuntimeGetBackgroundPageFunction : public ChromeAsyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("runtime.getBackgroundPage",
-                             RUNTIME_GETBACKGROUNDPAGE)
-
- protected:
-  virtual ~RuntimeGetBackgroundPageFunction() {}
-  virtual bool RunImpl() OVERRIDE;
-
- private:
-  void OnPageLoaded(ExtensionHost*);
-};
-
-class RuntimeSetUninstallURLFunction : public ChromeSyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("runtime.setUninstallURL",
-                             RUNTIME_SETUNINSTALLURL)
-
- protected:
-  virtual ~RuntimeSetUninstallURLFunction() {}
-  virtual bool RunSync() OVERRIDE;
-};
-
-class RuntimeReloadFunction : public ChromeSyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("runtime.reload", RUNTIME_RELOAD)
-
- protected:
-  virtual ~RuntimeReloadFunction() {}
-  virtual bool RunSync() OVERRIDE;
-};
-
-class RuntimeRequestUpdateCheckFunction : public ChromeAsyncExtensionFunction,
-                                          public content::NotificationObserver {
- public:
-  DECLARE_EXTENSION_FUNCTION("runtime.requestUpdateCheck",
-                             RUNTIME_REQUESTUPDATECHECK)
-
-  RuntimeRequestUpdateCheckFunction();
- protected:
-  virtual ~RuntimeRequestUpdateCheckFunction() {}
-  virtual bool RunImpl() OVERRIDE;
-
-  // Implements content::NotificationObserver interface.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) OVERRIDE;
- private:
-  void CheckComplete();
-  void ReplyUpdateFound(const std::string& version);
-
-  content::NotificationRegistrar registrar_;
-  bool did_reply_;
-};
-
-class RuntimeRestartFunction : public ChromeSyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("runtime.restart", RUNTIME_RESTART)
-
- protected:
-  virtual ~RuntimeRestartFunction() {}
-  virtual bool RunSync() OVERRIDE;
-};
-
-class RuntimeGetPlatformInfoFunction : public ChromeSyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("runtime.getPlatformInfo",
-                             RUNTIME_GETPLATFORMINFO);
- protected:
-  virtual ~RuntimeGetPlatformInfoFunction() {}
-  virtual bool RunSync() OVERRIDE;
-};
-
-class RuntimeGetPackageDirectoryEntryFunction
-    : public ChromeSyncExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("runtime.getPackageDirectoryEntry",
-                             RUNTIME_GETPACKAGEDIRECTORYENTRY)
-
- protected:
-  virtual ~RuntimeGetPackageDirectoryEntryFunction() {}
-  virtual bool RunSync() OVERRIDE;
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_API_RUNTIME_RUNTIME_API_H_
diff --git a/chrome/browser/extensions/api/runtime/runtime_apitest.cc b/chrome/browser/extensions/api/runtime/runtime_apitest.cc
deleted file mode 100644
index ccb45ce..0000000
--- a/chrome/browser/extensions/api/runtime/runtime_apitest.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/apps/app_browsertest_util.h"
-#include "chrome/browser/extensions/api/management/management_api.h"
-#include "chrome/browser/extensions/api/runtime/runtime_api.h"
-#include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/extensions/extension_function_test_utils.h"
-#include "chrome/browser/extensions/test_extension_dir.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "content/public/browser/notification_service.h"
-#include "extensions/browser/extension_registry.h"
-#include "net/test/embedded_test_server/embedded_test_server.h"
-
-// Tests the privileged components of chrome.runtime.
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimePrivileged) {
-  ASSERT_TRUE(RunExtensionTest("runtime/privileged")) << message_;
-}
-
-// Tests the unprivileged components of chrome.runtime.
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeUnprivileged) {
-  ASSERT_TRUE(StartEmbeddedTestServer());
-  ASSERT_TRUE(
-      LoadExtension(test_data_dir_.AppendASCII("runtime/content_script")));
-
-  // The content script runs on webpage.html.
-  ResultCatcher catcher;
-  ui_test_utils::NavigateToURL(browser(),
-                               embedded_test_server()->GetURL("/webpage.html"));
-  EXPECT_TRUE(catcher.GetNextResult()) << message_;
-}
-
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeUninstallURL) {
-  // Auto-confirm the uninstall dialog.
-  extensions::ManagementUninstallFunction::SetAutoConfirmForTest(true);
-  ASSERT_TRUE(LoadExtension(
-      test_data_dir_.AppendASCII("runtime").AppendASCII("uninstall_url").
-          AppendASCII("sets_uninstall_url")));
-  ASSERT_TRUE(RunExtensionTest("runtime/uninstall_url")) << message_;
-}
-
-namespace extensions {
-
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeGetPlatformInfo) {
-  scoped_ptr<base::Value> result(
-      extension_function_test_utils::RunFunctionAndReturnSingleResult(
-          new RuntimeGetPlatformInfoFunction(),
-          "[]",
-          browser()));
-  ASSERT_TRUE(result.get() != NULL);
-  base::DictionaryValue* dict =
-      extension_function_test_utils::ToDictionary(result.get());
-  ASSERT_TRUE(dict != NULL);
-  EXPECT_TRUE(dict->HasKey("os"));
-  EXPECT_TRUE(dict->HasKey("arch"));
-  EXPECT_TRUE(dict->HasKey("nacl_arch"));
-}
-
-// Tests chrome.runtime.getPackageDirectory with an app.
-IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
-                       ChromeRuntimeGetPackageDirectoryEntryApp) {
-  ClearCommandLineArgs();
-  ASSERT_TRUE(RunPlatformAppTest("api_test/runtime/get_package_directory/app"))
-      << message_;
-}
-
-// Tests chrome.runtime.getPackageDirectory with an extension.
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest,
-                       ChromeRuntimeGetPackageDirectoryEntryExtension) {
-  ASSERT_TRUE(RunExtensionTest("runtime/get_package_directory/extension"))
-      << message_;
-}
-
-// Tests chrome.runtime.reload
-// This test is flaky on Linux: crbug.com/366181
-#if defined(OS_LINUX) || defined(OS_CHROMEOS)
-#define MAYBE_ChromeRuntimeReload DISABLED_ChromeRuntimeReload
-#else
-#define MAYBE_ChromeRuntimeReload ChromeRuntimeReload
-#endif
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_ChromeRuntimeReload) {
-  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
-  const char kManifest[] =
-      "{"
-      "  \"name\": \"reload\","
-      "  \"version\": \"1.0\","
-      "  \"background\": {"
-      "    \"scripts\": [\"background.js\"]"
-      "  },"
-      "  \"manifest_version\": 2"
-      "}";
-
-  TestExtensionDir dir;
-  dir.WriteManifest(kManifest);
-  dir.WriteFile(FILE_PATH_LITERAL("background.js"), "console.log('loaded');");
-
-  const Extension* extension = LoadExtension(dir.unpacked_path());
-  ASSERT_TRUE(extension);
-  const std::string extension_id = extension->id();
-
-  // Somewhat arbitrary upper limit of 30 iterations. If the extension manages
-  // to reload itself that often without being terminated, the test fails
-  // anyway.
-  for (int i = 0; i < 30; i++) {
-    content::WindowedNotificationObserver unload_observer(
-        chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
-        content::NotificationService::AllSources());
-    content::WindowedNotificationObserver load_observer(
-        chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
-        content::NotificationService::AllSources());
-
-    ASSERT_TRUE(ExecuteScriptInBackgroundPageNoWait(
-        extension_id, "chrome.runtime.reload();"));
-    unload_observer.Wait();
-
-    if (registry->GetExtensionById(extension_id,
-                                   ExtensionRegistry::TERMINATED)) {
-      break;
-    } else {
-      load_observer.Wait();
-      WaitForExtensionViewsToLoad();
-    }
-  }
-  ASSERT_TRUE(
-      registry->GetExtensionById(extension_id, ExtensionRegistry::TERMINATED));
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/api/screenlock_private/screenlock_private_api.cc b/chrome/browser/extensions/api/screenlock_private/screenlock_private_api.cc
new file mode 100644
index 0000000..32b0b80
--- /dev/null
+++ b/chrome/browser/extensions/api/screenlock_private/screenlock_private_api.cc
@@ -0,0 +1,287 @@
+// Copyright 2013 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.
+
+#include "chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h"
+
+#include "base/lazy_instance.h"
+#include "base/values.h"
+#include "chrome/browser/extensions/image_loader.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/extensions/api/screenlock_private.h"
+#include "extensions/browser/event_router.h"
+#include "ui/gfx/image/image.h"
+
+namespace screenlock = extensions::api::screenlock_private;
+
+namespace extensions {
+
+namespace {
+
+const char kNotLockedError[] = "Screen is not currently locked.";
+
+ScreenlockBridge::LockHandler::AuthType ToLockHandlerAuthType(
+    screenlock::AuthType auth_type) {
+  switch (auth_type) {
+    case screenlock::AUTH_TYPE_OFFLINEPASSWORD:
+      return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
+    case screenlock::AUTH_TYPE_NUMERICPIN:
+      return ScreenlockBridge::LockHandler::NUMERIC_PIN;
+    case screenlock::AUTH_TYPE_USERCLICK:
+      return ScreenlockBridge::LockHandler::USER_CLICK;
+    case screenlock::AUTH_TYPE_NONE:
+      break;
+  }
+  NOTREACHED();
+  return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
+}
+
+screenlock::AuthType FromLockHandlerAuthType(
+    ScreenlockBridge::LockHandler::AuthType auth_type) {
+  switch (auth_type) {
+    case ScreenlockBridge::LockHandler::OFFLINE_PASSWORD:
+      return screenlock::AUTH_TYPE_OFFLINEPASSWORD;
+    case ScreenlockBridge::LockHandler::NUMERIC_PIN:
+      return screenlock::AUTH_TYPE_NUMERICPIN;
+    case ScreenlockBridge::LockHandler::USER_CLICK:
+      return screenlock::AUTH_TYPE_USERCLICK;
+    case ScreenlockBridge::LockHandler::ONLINE_SIGN_IN:
+      // Apps should treat forced online sign in same as system password.
+      return screenlock::AUTH_TYPE_OFFLINEPASSWORD;
+  }
+  NOTREACHED();
+  return screenlock::AUTH_TYPE_OFFLINEPASSWORD;
+}
+
+}  // namespace
+
+ScreenlockPrivateGetLockedFunction::ScreenlockPrivateGetLockedFunction() {}
+
+ScreenlockPrivateGetLockedFunction::~ScreenlockPrivateGetLockedFunction() {}
+
+bool ScreenlockPrivateGetLockedFunction::RunAsync() {
+  SetResult(new base::FundamentalValue(ScreenlockBridge::Get()->IsLocked()));
+  SendResponse(error_.empty());
+  return true;
+}
+
+ScreenlockPrivateSetLockedFunction::ScreenlockPrivateSetLockedFunction() {}
+
+ScreenlockPrivateSetLockedFunction::~ScreenlockPrivateSetLockedFunction() {}
+
+bool ScreenlockPrivateSetLockedFunction::RunAsync() {
+  scoped_ptr<screenlock::SetLocked::Params> params(
+      screenlock::SetLocked::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+  if (params->locked)
+    ScreenlockBridge::Get()->Lock(GetProfile());
+  else
+    ScreenlockBridge::Get()->Unlock(GetProfile());
+  SendResponse(error_.empty());
+  return true;
+}
+
+ScreenlockPrivateShowMessageFunction::ScreenlockPrivateShowMessageFunction() {}
+
+ScreenlockPrivateShowMessageFunction::~ScreenlockPrivateShowMessageFunction() {}
+
+bool ScreenlockPrivateShowMessageFunction::RunAsync() {
+  scoped_ptr<screenlock::ShowMessage::Params> params(
+      screenlock::ShowMessage::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+  ScreenlockBridge::LockHandler* locker =
+      ScreenlockBridge::Get()->lock_handler();
+  if (locker)
+    locker->ShowBannerMessage(params->message);
+  SendResponse(error_.empty());
+  return true;
+}
+
+static const int kMaxButtonIconSize = 40;
+
+ScreenlockPrivateShowButtonFunction::
+  ScreenlockPrivateShowButtonFunction() {}
+
+ScreenlockPrivateShowButtonFunction::
+  ~ScreenlockPrivateShowButtonFunction() {}
+
+bool ScreenlockPrivateShowButtonFunction::RunAsync() {
+  scoped_ptr<screenlock::ShowButton::Params> params(
+      screenlock::ShowButton::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+  ScreenlockBridge::LockHandler* locker =
+      ScreenlockBridge::Get()->lock_handler();
+  if (!locker) {
+    SetError(kNotLockedError);
+    SendResponse(false);
+    return true;
+  }
+  extensions::ImageLoader* loader = extensions::ImageLoader::Get(GetProfile());
+  loader->LoadImageAsync(
+      GetExtension(), GetExtension()->GetResource(params->icon),
+      gfx::Size(kMaxButtonIconSize, kMaxButtonIconSize),
+      base::Bind(&ScreenlockPrivateShowButtonFunction::OnImageLoaded, this));
+  return true;
+}
+
+void ScreenlockPrivateShowButtonFunction::OnImageLoaded(
+    const gfx::Image& image) {
+  ScreenlockBridge::LockHandler* locker =
+      ScreenlockBridge::Get()->lock_handler();
+  ScreenlockPrivateEventRouter* router =
+      ScreenlockPrivateEventRouter::GetFactoryInstance()->Get(GetProfile());
+  locker->ShowUserPodButton(
+      ScreenlockBridge::GetAuthenticatedUserEmail(GetProfile()),
+      image,
+      base::Bind(&ScreenlockPrivateEventRouter::OnButtonClicked,
+                 base::Unretained(router)));
+  SendResponse(error_.empty());
+}
+
+ScreenlockPrivateHideButtonFunction::ScreenlockPrivateHideButtonFunction() {}
+
+ScreenlockPrivateHideButtonFunction::~ScreenlockPrivateHideButtonFunction() {}
+
+bool ScreenlockPrivateHideButtonFunction::RunAsync() {
+  ScreenlockBridge::LockHandler* locker =
+      ScreenlockBridge::Get()->lock_handler();
+  if (locker) {
+    locker->HideUserPodButton(
+        ScreenlockBridge::GetAuthenticatedUserEmail(GetProfile()));
+  } else {
+    SetError(kNotLockedError);
+  }
+  SendResponse(error_.empty());
+  return true;
+}
+
+ScreenlockPrivateSetAuthTypeFunction::ScreenlockPrivateSetAuthTypeFunction() {}
+
+ScreenlockPrivateSetAuthTypeFunction::~ScreenlockPrivateSetAuthTypeFunction() {}
+
+bool ScreenlockPrivateSetAuthTypeFunction::RunAsync() {
+  scoped_ptr<screenlock::SetAuthType::Params> params(
+      screenlock::SetAuthType::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+
+  ScreenlockBridge::LockHandler* locker =
+      ScreenlockBridge::Get()->lock_handler();
+  if (locker) {
+    std::string initial_value =
+        params->initial_value.get() ? *(params->initial_value.get()) : "";
+    locker->SetAuthType(
+        ScreenlockBridge::GetAuthenticatedUserEmail(GetProfile()),
+        ToLockHandlerAuthType(params->auth_type),
+        initial_value);
+  } else {
+    SetError(kNotLockedError);
+  }
+  SendResponse(error_.empty());
+  return true;
+}
+
+ScreenlockPrivateGetAuthTypeFunction::ScreenlockPrivateGetAuthTypeFunction() {}
+
+ScreenlockPrivateGetAuthTypeFunction::~ScreenlockPrivateGetAuthTypeFunction() {}
+
+bool ScreenlockPrivateGetAuthTypeFunction::RunAsync() {
+  ScreenlockBridge::LockHandler* locker =
+      ScreenlockBridge::Get()->lock_handler();
+  if (locker) {
+    ScreenlockBridge::LockHandler::AuthType auth_type = locker->GetAuthType(
+        ScreenlockBridge::GetAuthenticatedUserEmail(GetProfile()));
+    std::string auth_type_name =
+        screenlock::ToString(FromLockHandlerAuthType(auth_type));
+    SetResult(new base::StringValue(auth_type_name));
+  } else {
+    SetError(kNotLockedError);
+  }
+  SendResponse(error_.empty());
+  return true;
+}
+
+ScreenlockPrivateAcceptAuthAttemptFunction::
+    ScreenlockPrivateAcceptAuthAttemptFunction() {}
+
+ScreenlockPrivateAcceptAuthAttemptFunction::
+    ~ScreenlockPrivateAcceptAuthAttemptFunction() {}
+
+bool ScreenlockPrivateAcceptAuthAttemptFunction::RunAsync() {
+  scoped_ptr<screenlock::AcceptAuthAttempt::Params> params(
+      screenlock::AcceptAuthAttempt::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+
+  ScreenlockBridge::LockHandler* locker =
+      ScreenlockBridge::Get()->lock_handler();
+  if (locker) {
+    if (params->accept) {
+      locker->Unlock(ScreenlockBridge::GetAuthenticatedUserEmail(GetProfile()));
+    } else {
+      locker->EnableInput();
+    }
+  } else {
+    SetError(kNotLockedError);
+  }
+  SendResponse(error_.empty());
+  return true;
+}
+
+ScreenlockPrivateEventRouter::ScreenlockPrivateEventRouter(
+    content::BrowserContext* context)
+    : browser_context_(context) {
+  ScreenlockBridge::Get()->AddObserver(this);
+}
+
+ScreenlockPrivateEventRouter::~ScreenlockPrivateEventRouter() {}
+
+void ScreenlockPrivateEventRouter::OnScreenDidLock() {
+  DispatchEvent(screenlock::OnChanged::kEventName,
+      new base::FundamentalValue(true));
+}
+
+void ScreenlockPrivateEventRouter::OnScreenDidUnlock() {
+  DispatchEvent(screenlock::OnChanged::kEventName,
+      new base::FundamentalValue(false));
+}
+
+void ScreenlockPrivateEventRouter::DispatchEvent(
+    const std::string& event_name,
+    base::Value* arg) {
+  scoped_ptr<base::ListValue> args(new base::ListValue());
+  if (arg)
+    args->Append(arg);
+  scoped_ptr<extensions::Event> event(new extensions::Event(
+      event_name, args.Pass()));
+  extensions::EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
+}
+
+static base::LazyInstance<extensions::BrowserContextKeyedAPIFactory<
+    ScreenlockPrivateEventRouter> > g_factory = LAZY_INSTANCE_INITIALIZER;
+
+// static
+extensions::BrowserContextKeyedAPIFactory<ScreenlockPrivateEventRouter>*
+ScreenlockPrivateEventRouter::GetFactoryInstance() {
+  return g_factory.Pointer();
+}
+
+void ScreenlockPrivateEventRouter::Shutdown() {
+  ScreenlockBridge::Get()->RemoveObserver(this);
+}
+
+void ScreenlockPrivateEventRouter::OnButtonClicked() {
+  DispatchEvent(screenlock::OnButtonClicked::kEventName, NULL);
+}
+
+void ScreenlockPrivateEventRouter::OnAuthAttempted(
+    ScreenlockBridge::LockHandler::AuthType auth_type,
+    const std::string& value) {
+  scoped_ptr<base::ListValue> args(new base::ListValue());
+  args->AppendString(screenlock::ToString(FromLockHandlerAuthType(auth_type)));
+  args->AppendString(value);
+
+  scoped_ptr<extensions::Event> event(new extensions::Event(
+      screenlock::OnAuthAttempted::kEventName, args.Pass()));
+  extensions::EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h b/chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h
new file mode 100644
index 0000000..317274f
--- /dev/null
+++ b/chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h
@@ -0,0 +1,162 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_SCREENLOCK_PRIVATE_SCREENLOCK_PRIVATE_API_H_
+#define CHROME_BROWSER_EXTENSIONS_API_SCREENLOCK_PRIVATE_SCREENLOCK_PRIVATE_API_H_
+
+#include "chrome/browser/extensions/chrome_extension_function.h"
+#include "chrome/browser/signin/screenlock_bridge.h"
+#include "extensions/browser/browser_context_keyed_api_factory.h"
+
+namespace gfx {
+class Image;
+}
+
+namespace extensions {
+
+class ScreenlockPrivateGetLockedFunction : public ChromeAsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.getLocked",
+                             SCREENLOCKPRIVATE_GETLOCKED)
+  ScreenlockPrivateGetLockedFunction();
+  virtual bool RunAsync() OVERRIDE;
+
+ private:
+  virtual ~ScreenlockPrivateGetLockedFunction();
+  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateGetLockedFunction);
+};
+
+class ScreenlockPrivateSetLockedFunction : public ChromeAsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.setLocked",
+                             SCREENLOCKPRIVATE_SETLOCKED)
+  ScreenlockPrivateSetLockedFunction();
+  virtual bool RunAsync() OVERRIDE;
+
+ private:
+  virtual ~ScreenlockPrivateSetLockedFunction();
+  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateSetLockedFunction);
+};
+
+class ScreenlockPrivateShowMessageFunction
+    : public ChromeAsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.showMessage",
+                             SCREENLOCKPRIVATE_SHOWMESSAGE)
+  ScreenlockPrivateShowMessageFunction();
+  virtual bool RunAsync() OVERRIDE;
+
+ private:
+  virtual ~ScreenlockPrivateShowMessageFunction();
+  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateShowMessageFunction );
+};
+
+class ScreenlockPrivateShowButtonFunction
+    : public ChromeAsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.showButton",
+                             SCREENLOCKPRIVATE_SHOWBUTTON)
+  ScreenlockPrivateShowButtonFunction();
+  virtual bool RunAsync() OVERRIDE;
+
+ private:
+  virtual ~ScreenlockPrivateShowButtonFunction();
+  void OnImageLoaded(const gfx::Image& image);
+  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateShowButtonFunction);
+};
+
+class ScreenlockPrivateHideButtonFunction
+    : public ChromeAsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.hideButton",
+                             SCREENLOCKPRIVATE_HIDEBUTTON)
+  ScreenlockPrivateHideButtonFunction();
+  virtual bool RunAsync() OVERRIDE;
+
+ private:
+  virtual ~ScreenlockPrivateHideButtonFunction();
+  void OnImageLoaded(const gfx::Image& image);
+  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateHideButtonFunction);
+};
+
+class ScreenlockPrivateSetAuthTypeFunction
+    : public ChromeAsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.setAuthType",
+                             SCREENLOCKPRIVATE_SETAUTHTYPE)
+  ScreenlockPrivateSetAuthTypeFunction();
+  virtual bool RunAsync() OVERRIDE;
+
+ private:
+  virtual ~ScreenlockPrivateSetAuthTypeFunction();
+  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateSetAuthTypeFunction);
+};
+
+class ScreenlockPrivateGetAuthTypeFunction
+    : public ChromeAsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.getAuthType",
+                             SCREENLOCKPRIVATE_GETAUTHTYPE)
+  ScreenlockPrivateGetAuthTypeFunction();
+  virtual bool RunAsync() OVERRIDE;
+
+ private:
+  virtual ~ScreenlockPrivateGetAuthTypeFunction();
+  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateGetAuthTypeFunction);
+};
+
+class ScreenlockPrivateAcceptAuthAttemptFunction
+    : public ChromeAsyncExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("screenlockPrivate.acceptAuthAttempt",
+                             SCREENLOCKPRIVATE_ACCEPTAUTHATTEMPT)
+  ScreenlockPrivateAcceptAuthAttemptFunction();
+  virtual bool RunAsync() OVERRIDE;
+
+ private:
+  virtual ~ScreenlockPrivateAcceptAuthAttemptFunction();
+  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateAcceptAuthAttemptFunction);
+};
+
+class ScreenlockPrivateEventRouter : public extensions::BrowserContextKeyedAPI,
+                                     public ScreenlockBridge::Observer {
+ public:
+  explicit ScreenlockPrivateEventRouter(content::BrowserContext* context);
+  virtual ~ScreenlockPrivateEventRouter();
+
+  void OnButtonClicked();
+
+  void OnAuthAttempted(ScreenlockBridge::LockHandler::AuthType auth_type,
+                       const std::string& value);
+
+  // BrowserContextKeyedAPI
+  static extensions::BrowserContextKeyedAPIFactory<
+      ScreenlockPrivateEventRouter>*
+      GetFactoryInstance();
+  virtual void Shutdown() OVERRIDE;
+
+  // ScreenlockBridge::Observer
+  virtual void OnScreenDidLock() OVERRIDE;
+  virtual void OnScreenDidUnlock() OVERRIDE;
+
+ private:
+  friend class extensions::BrowserContextKeyedAPIFactory<
+      ScreenlockPrivateEventRouter>;
+
+  // BrowserContextKeyedAPI
+  static const char* service_name() {
+    return "ScreenlockPrivateEventRouter";
+  }
+  static const bool kServiceIsNULLWhileTesting = true;
+  static const bool kServiceRedirectedInIncognito = true;
+
+  void DispatchEvent(const std::string& event_name, base::Value* arg);
+
+  content::BrowserContext* browser_context_;
+  DISALLOW_COPY_AND_ASSIGN(ScreenlockPrivateEventRouter);
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_API_SCREENLOCK_PRIVATE_SCREENLOCK_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/serial/serial_apitest.cc b/chrome/browser/extensions/api/serial/serial_apitest.cc
index a53bb80..6bdad96 100644
--- a/chrome/browser/extensions/api/serial/serial_apitest.cc
+++ b/chrome/browser/extensions/api/serial/serial_apitest.cc
@@ -36,7 +36,7 @@
 
 class FakeSerialGetDevicesFunction : public AsyncExtensionFunction {
  public:
-  virtual bool RunImpl() OVERRIDE {
+  virtual bool RunAsync() OVERRIDE {
     base::ListValue* devices = new base::ListValue();
     base::DictionaryValue* device0 = new base::DictionaryValue();
     device0->SetString("path", "/dev/fakeserial");
diff --git a/chrome/browser/extensions/api/serial/serial_connection.cc b/chrome/browser/extensions/api/serial/serial_connection.cc
index 8ff045e..3671901 100644
--- a/chrome/browser/extensions/api/serial/serial_connection.cc
+++ b/chrome/browser/extensions/api/serial/serial_connection.cc
@@ -164,7 +164,7 @@
   // It's the responsibility of the API wrapper around SerialConnection to
   // validate the supplied path against the set of valid port names, and
   // it is a reasonable assumption that serial port names are ASCII.
-  DCHECK(IsStringASCII(port_));
+  DCHECK(base::IsStringASCII(port_));
   base::FilePath path(
       base::FilePath::FromUTF8Unsafe(MaybeFixUpPortName(port_)));
   int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
diff --git a/chrome/browser/extensions/api/sessions/sessions_api.cc b/chrome/browser/extensions/api/sessions/sessions_api.cc
index 1b7fc2d..a484be4 100644
--- a/chrome/browser/extensions/api/sessions/sessions_api.cc
+++ b/chrome/browser/extensions/api/sessions/sessions_api.cc
@@ -342,7 +342,7 @@
 scoped_ptr<api::sessions::Device> SessionsGetDevicesFunction::CreateDeviceModel(
     const browser_sync::SyncedSession* session) {
   int max_results = api::sessions::MAX_SESSION_RESULTS;
-  // Already validated in RunImpl().
+  // Already validated in RunAsync().
   scoped_ptr<GetDevices::Params> params(GetDevices::Params::Create(*args_));
   if (params->filter && params->filter->max_results)
     max_results = *params->filter->max_results;
@@ -405,7 +405,7 @@
 
 
 void SessionsRestoreFunction::SetResultRestoredTab(
-    const content::WebContents* contents) {
+    content::WebContents* contents) {
   scoped_ptr<base::DictionaryValue> tab_value(
       ExtensionTabUtil::CreateTabValue(contents, GetExtension()));
   scoped_ptr<tabs::Tab> tab(tabs::Tab::FromValue(*tab_value));
diff --git a/chrome/browser/extensions/api/sessions/sessions_api.h b/chrome/browser/extensions/api/sessions/sessions_api.h
index f30d371..da0305c 100644
--- a/chrome/browser/extensions/api/sessions/sessions_api.h
+++ b/chrome/browser/extensions/api/sessions/sessions_api.h
@@ -73,7 +73,7 @@
 
  private:
   void SetInvalidIdError(const std::string& invalid_id);
-  void SetResultRestoredTab(const content::WebContents* contents);
+  void SetResultRestoredTab(content::WebContents* contents);
   bool SetResultRestoredWindow(int window_id);
   bool RestoreMostRecentlyClosed(Browser* browser);
   bool RestoreLocalSession(const SessionId& session_id, Browser* browser);
diff --git a/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc b/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc
index 3f88362..56e4d65 100644
--- a/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc
+++ b/chrome/browser/extensions/api/spellcheck/spellcheck_api.cc
@@ -25,7 +25,8 @@
   return spellcheck_info;
 }
 
-SpellcheckService::DictionaryFormat GetDictionaryFormat(std::string format) {
+SpellcheckService::DictionaryFormat GetDictionaryFormat(
+    const std::string& format) {
   if (format == "hunspell") {
     return SpellcheckService::DICT_HUNSPELL;
   } else if (format == "text") {
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_api.cc b/chrome/browser/extensions/api/streams_private/streams_private_api.cc
index 66bf858..1a1445a 100644
--- a/chrome/browser/extensions/api/streams_private/streams_private_api.cc
+++ b/chrome/browser/extensions/api/streams_private/streams_private_api.cc
@@ -59,7 +59,7 @@
 
 void StreamsPrivateAPI::ExecuteMimeTypeHandler(
     const std::string& extension_id,
-    const content::WebContents* web_contents,
+    content::WebContents* web_contents,
     scoped_ptr<content::StreamHandle> stream,
     int64 expected_content_size) {
   // Create the event's arguments value.
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_api.h b/chrome/browser/extensions/api/streams_private/streams_private_api.h
index fcf7245..0ac149f 100644
--- a/chrome/browser/extensions/api/streams_private/streams_private_api.h
+++ b/chrome/browser/extensions/api/streams_private/streams_private_api.h
@@ -31,7 +31,7 @@
   virtual ~StreamsPrivateAPI();
 
   void ExecuteMimeTypeHandler(const std::string& extension_id,
-                              const content::WebContents* web_contents,
+                              content::WebContents* web_contents,
                               scoped_ptr<content::StreamHandle> stream,
                               int64 expected_content_size);
 
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
index ddcbc0f..c7907c9 100644
--- a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
+++ b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/extensions/api/streams_private.h"
-#include "chrome/common/extensions/mime_types_handler.h"
+#include "chrome/common/extensions/manifest_handlers/mime_types_handler.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/test_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_manifest_unittest.cc b/chrome/browser/extensions/api/streams_private/streams_private_manifest_unittest.cc
index dfdf7d8..317c95f 100644
--- a/chrome/browser/extensions/api/streams_private/streams_private_manifest_unittest.cc
+++ b/chrome/browser/extensions/api/streams_private/streams_private_manifest_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "base/strings/string_number_conversions.h"
 #include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/extensions/manifest_handlers/mime_types_handler.h"
 #include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
 #include "chrome/common/extensions/manifest_url_handler.h"
-#include "chrome/common/extensions/mime_types_handler.h"
 #include "extensions/common/error_utils.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/manifest_constants.h"
diff --git a/chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer.cc b/chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer.cc
index 5cfb808..25dda79 100644
--- a/chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer.cc
+++ b/chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer.cc
@@ -92,8 +92,12 @@
   scoped_ptr<base::ListValue> params(new base::ListValue());
 
   // For now we always assume events come only for files (not directories).
-  params->Append(CreateDictionaryValueForFileSystemEntry(
-      url, sync_file_system::SYNC_FILE_TYPE_FILE));
+  scoped_ptr<base::DictionaryValue> entry(
+      CreateDictionaryValueForFileSystemEntry(
+          url, sync_file_system::SYNC_FILE_TYPE_FILE));
+  if (!entry)
+    return;
+  params->Append(entry.release());
 
   // Status, SyncAction and any optional notes to go here.
   api::sync_file_system::FileStatus status_enum =
diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
index f6bd637..dac14c1 100644
--- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
+++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
@@ -65,7 +65,7 @@
 
 }  // namespace
 
-bool SyncFileSystemDeleteFileSystemFunction::RunImpl() {
+bool SyncFileSystemDeleteFileSystemFunction::RunAsync() {
   std::string url;
   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url));
 
@@ -113,7 +113,7 @@
   SendResponse(true);
 }
 
-bool SyncFileSystemRequestFileSystemFunction::RunImpl() {
+bool SyncFileSystemRequestFileSystemFunction::RunAsync() {
   // SyncFileSystem initialization is done in OpenFileSystem below, but we call
   // GetSyncFileSystemService here too to initialize sync event observer for
   // extensions API.
@@ -168,7 +168,7 @@
   SendResponse(true);
 }
 
-bool SyncFileSystemGetFileStatusFunction::RunImpl() {
+bool SyncFileSystemGetFileStatusFunction::RunAsync() {
   std::string url;
   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url));
 
@@ -207,7 +207,7 @@
 SyncFileSystemGetFileStatusesFunction::~SyncFileSystemGetFileStatusesFunction(
     ) {}
 
-bool SyncFileSystemGetFileStatusesFunction::RunImpl() {
+bool SyncFileSystemGetFileStatusesFunction::RunAsync() {
   // All FileEntries converted into array of URL Strings in JS custom bindings.
   base::ListValue* file_entry_urls = NULL;
   EXTENSION_FUNCTION_VALIDATE(args_->GetList(0, &file_entry_urls));
@@ -284,7 +284,7 @@
   SendResponse(true);
 }
 
-bool SyncFileSystemGetUsageAndQuotaFunction::RunImpl() {
+bool SyncFileSystemGetUsageAndQuotaFunction::RunAsync() {
   std::string url;
   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url));
 
diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.h b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.h
index e0e9621..afc06dd 100644
--- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.h
+++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.h
@@ -32,7 +32,7 @@
 
  protected:
   virtual ~SyncFileSystemDeleteFileSystemFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void DidDeleteFileSystem(base::File::Error error);
@@ -46,7 +46,7 @@
 
  protected:
   virtual ~SyncFileSystemGetFileStatusFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void DidGetFileStatus(
@@ -63,7 +63,7 @@
 
  protected:
   virtual ~SyncFileSystemGetFileStatusesFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   typedef std::pair<sync_file_system::SyncStatusCode,
@@ -89,7 +89,7 @@
 
  protected:
   virtual ~SyncFileSystemGetUsageAndQuotaFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void DidGetUsageAndQuota(quota::QuotaStatusCode status,
@@ -105,7 +105,7 @@
 
  protected:
   virtual ~SyncFileSystemRequestFileSystemFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   typedef SyncFileSystemRequestFileSystemFunction self;
diff --git a/chrome/browser/extensions/api/system_cpu/system_cpu_api.cc b/chrome/browser/extensions/api/system_cpu/system_cpu_api.cc
index 74040c5..4ace528 100644
--- a/chrome/browser/extensions/api/system_cpu/system_cpu_api.cc
+++ b/chrome/browser/extensions/api/system_cpu/system_cpu_api.cc
@@ -18,7 +18,7 @@
 SystemCpuGetInfoFunction::~SystemCpuGetInfoFunction() {
 }
 
-bool SystemCpuGetInfoFunction::RunImpl() {
+bool SystemCpuGetInfoFunction::RunAsync() {
   CpuInfoProvider::Get()->StartQueryInfo(
       base::Bind(&SystemCpuGetInfoFunction::OnGetCpuInfoCompleted, this));
   return true;
diff --git a/chrome/browser/extensions/api/system_cpu/system_cpu_api.h b/chrome/browser/extensions/api/system_cpu/system_cpu_api.h
index d2b7ab8..3101390 100644
--- a/chrome/browser/extensions/api/system_cpu/system_cpu_api.h
+++ b/chrome/browser/extensions/api/system_cpu/system_cpu_api.h
@@ -16,7 +16,7 @@
 
  private:
   virtual ~SystemCpuGetInfoFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void OnGetCpuInfoCompleted(bool success);
 };
 
diff --git a/chrome/browser/extensions/api/system_memory/system_memory_api.cc b/chrome/browser/extensions/api/system_memory/system_memory_api.cc
index 7556410..f0c4a24 100644
--- a/chrome/browser/extensions/api/system_memory/system_memory_api.cc
+++ b/chrome/browser/extensions/api/system_memory/system_memory_api.cc
@@ -14,7 +14,7 @@
 
 SystemMemoryGetInfoFunction::~SystemMemoryGetInfoFunction() {}
 
-bool SystemMemoryGetInfoFunction::RunImpl() {
+bool SystemMemoryGetInfoFunction::RunAsync() {
   MemoryInfoProvider::Get()->StartQueryInfo(
       base::Bind(&SystemMemoryGetInfoFunction::OnGetMemoryInfoCompleted, this));
   return true;
diff --git a/chrome/browser/extensions/api/system_memory/system_memory_api.h b/chrome/browser/extensions/api/system_memory/system_memory_api.h
index 740cac2..af5436d 100644
--- a/chrome/browser/extensions/api/system_memory/system_memory_api.h
+++ b/chrome/browser/extensions/api/system_memory/system_memory_api.h
@@ -17,7 +17,7 @@
 
  private:
   virtual ~SystemMemoryGetInfoFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void OnGetMemoryInfoCompleted(bool success);
 };
 
diff --git a/chrome/browser/extensions/api/system_network/system_network_api.cc b/chrome/browser/extensions/api/system_network/system_network_api.cc
index 6710052..946bde5 100644
--- a/chrome/browser/extensions/api/system_network/system_network_api.cc
+++ b/chrome/browser/extensions/api/system_network/system_network_api.cc
@@ -17,7 +17,7 @@
 SystemNetworkGetNetworkInterfacesFunction::
     ~SystemNetworkGetNetworkInterfacesFunction() {}
 
-bool SystemNetworkGetNetworkInterfacesFunction::RunImpl() {
+bool SystemNetworkGetNetworkInterfacesFunction::RunAsync() {
   content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
       base::Bind(&SystemNetworkGetNetworkInterfacesFunction::
           GetListOnFileThread,
diff --git a/chrome/browser/extensions/api/system_network/system_network_api.h b/chrome/browser/extensions/api/system_network/system_network_api.h
index ed14631..edd5707 100644
--- a/chrome/browser/extensions/api/system_network/system_network_api.h
+++ b/chrome/browser/extensions/api/system_network/system_network_api.h
@@ -24,7 +24,7 @@
   virtual ~SystemNetworkGetNetworkInterfacesFunction();
 
   // AsyncApiFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void GetListOnFileThread();
diff --git a/chrome/browser/extensions/api/system_storage/system_storage_api.cc b/chrome/browser/extensions/api/system_storage/system_storage_api.cc
index 6d8da0d..3b8407d 100644
--- a/chrome/browser/extensions/api/system_storage/system_storage_api.cc
+++ b/chrome/browser/extensions/api/system_storage/system_storage_api.cc
@@ -18,7 +18,7 @@
 SystemStorageGetInfoFunction::~SystemStorageGetInfoFunction() {
 }
 
-bool SystemStorageGetInfoFunction::RunImpl() {
+bool SystemStorageGetInfoFunction::RunAsync() {
   StorageInfoProvider::Get()->StartQueryInfo(
       base::Bind(&SystemStorageGetInfoFunction::OnGetStorageInfoCompleted,
                  this));
@@ -39,7 +39,7 @@
 SystemStorageEjectDeviceFunction::~SystemStorageEjectDeviceFunction() {
 }
 
-bool SystemStorageEjectDeviceFunction::RunImpl() {
+bool SystemStorageEjectDeviceFunction::RunAsync() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   scoped_ptr<EjectDevice::Params> params(EjectDevice::Params::Create(*args_));
@@ -103,7 +103,7 @@
     ~SystemStorageGetAvailableCapacityFunction() {
 }
 
-bool SystemStorageGetAvailableCapacityFunction::RunImpl() {
+bool SystemStorageGetAvailableCapacityFunction::RunAsync() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   scoped_ptr<GetAvailableCapacity::Params> params(
diff --git a/chrome/browser/extensions/api/system_storage/system_storage_api.h b/chrome/browser/extensions/api/system_storage/system_storage_api.h
index b619809..e8118af 100644
--- a/chrome/browser/extensions/api/system_storage/system_storage_api.h
+++ b/chrome/browser/extensions/api/system_storage/system_storage_api.h
@@ -20,7 +20,7 @@
 
  private:
   virtual ~SystemStorageGetInfoFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   void OnGetStorageInfoCompleted(bool success);
 };
@@ -35,7 +35,7 @@
   virtual ~SystemStorageEjectDeviceFunction();
 
   // AsyncExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnStorageMonitorInit(const std::string& transient_device_id);
@@ -56,7 +56,7 @@
   void OnQueryCompleted(const std::string& transient_id,
                         double available_capacity);
   virtual ~SystemStorageGetAvailableCapacityFunction();
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc
index b5c9ffe..1fa909a 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc
@@ -93,7 +93,7 @@
           extension, tab_id, APIPermission::kTabCaptureForTab) &&
       CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
           switches::kWhitelistedExtensionID) != extension_id &&
-      !SimpleFeature::IsIdInWhitelist(
+      !SimpleFeature::IsIdInList(
           extension_id,
           std::set<std::string>(
               whitelisted_extensions,
diff --git a/chrome/browser/extensions/api/tabs/ash_panel_contents.cc b/chrome/browser/extensions/api/tabs/ash_panel_contents.cc
index 02f59af..a1ca630 100644
--- a/chrome/browser/extensions/api/tabs/ash_panel_contents.cc
+++ b/chrome/browser/extensions/api/tabs/ash_panel_contents.cc
@@ -140,8 +140,7 @@
 
 bool AshPanelWindowController::IsVisibleToExtension(
     const extensions::Extension* extension) const {
-  return app_window_->extension() &&
-         extension->id() == app_window_->extension()->id();
+  return extension->id() == app_window_->extension_id();
 }
 
 void AshPanelWindowController::NativeWindowChanged() {
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index e30904d..d0ca7fe 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -62,19 +62,16 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/url_constants.h"
 #include "extensions/browser/extension_function_dispatcher.h"
 #include "extensions/browser/extension_function_util.h"
 #include "extensions/browser/extension_host.h"
 #include "extensions/browser/file_reader.h"
-#include "extensions/common/constants.h"
 #include "extensions/common/error_utils.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_l10n_util.h"
 #include "extensions/common/extension_messages.h"
 #include "extensions/common/manifest_constants.h"
-#include "extensions/common/manifest_handlers/incognito_info.h"
 #include "extensions/common/message_bundle.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "extensions/common/user_script.h"
@@ -108,52 +105,19 @@
 
 namespace {
 
-// |error_message| can optionally be passed in a will be set with an appropriate
-// message if the window cannot be found by id.
-Browser* GetBrowserInProfileWithId(Profile* profile,
-                                   const int window_id,
-                                   bool include_incognito,
-                                   std::string* error_message) {
-  Profile* incognito_profile =
-      include_incognito && profile->HasOffTheRecordProfile() ?
-          profile->GetOffTheRecordProfile() : NULL;
-  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
-    Browser* browser = *it;
-    if ((browser->profile() == profile ||
-         browser->profile() == incognito_profile) &&
-        ExtensionTabUtil::GetWindowId(browser) == window_id &&
-        browser->window()) {
-      return browser;
-    }
-  }
-
-  if (error_message)
-    *error_message = ErrorUtils::FormatErrorMessage(
-        keys::kWindowNotFoundError, base::IntToString(window_id));
-
-  return NULL;
-}
-
-bool GetBrowserFromWindowID(ChromeAsyncExtensionFunction* function,
+bool GetBrowserFromWindowID(ChromeUIThreadExtensionFunction* function,
                             int window_id,
                             Browser** browser) {
-  if (window_id == extension_misc::kCurrentWindowId) {
-    *browser = function->GetCurrentBrowser();
-    if (!(*browser) || !(*browser)->window()) {
-      function->SetError(keys::kNoCurrentWindowError);
-      return false;
-    }
-  } else {
-    std::string error;
-    *browser = GetBrowserInProfileWithId(function->GetProfile(),
-                                         window_id,
-                                         function->include_incognito(),
-                                         &error);
-    if (!*browser) {
-      function->SetError(error);
-      return false;
-    }
+  std::string error;
+  Browser* result;
+  result =
+      ExtensionTabUtil::GetBrowserFromWindowID(function, window_id, &error);
+  if (!result) {
+    function->SetError(error);
+    return false;
   }
+
+  *browser = result;
   return true;
 }
 
@@ -185,6 +149,14 @@
   return !boolean || *boolean == value;
 }
 
+template <typename T>
+void AssignOptionalValue(const scoped_ptr<T>& source,
+                         scoped_ptr<T>& destination) {
+  if (source.get()) {
+    destination.reset(new T(*source.get()));
+  }
+}
+
 }  // namespace
 
 // Windows ---------------------------------------------------------------------
@@ -861,7 +833,7 @@
 
     TabStripModel* tab_strip = browser->tab_strip_model();
     for (int i = 0; i < tab_strip->count(); ++i) {
-      const WebContents* web_contents = tab_strip->GetWebContentsAt(i);
+      WebContents* web_contents = tab_strip->GetWebContentsAt(i);
 
       if (index > -1 && i != index)
         continue;
@@ -904,137 +876,29 @@
   scoped_ptr<tabs::Create::Params> params(tabs::Create::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
-  // windowId defaults to "current" window.
-  int window_id = extension_misc::kCurrentWindowId;
-  if (params->create_properties.window_id.get())
-    window_id = *params->create_properties.window_id;
-
-  Browser* browser = NULL;
-  if (!GetBrowserFromWindowID(this, window_id, &browser))
-    return false;
-
-  // Ensure the selected browser is tabbed.
-  if (!browser->is_type_tabbed() && browser->IsAttemptingToCloseBrowser())
-    browser = chrome::FindTabbedBrowser(
-        GetProfile(), include_incognito(), browser->host_desktop_type());
-
-  if (!browser || !browser->window())
-    return false;
-
-  // TODO(jstritar): Add a constant, chrome.tabs.TAB_ID_ACTIVE, that
-  // represents the active tab.
-  WebContents* opener = NULL;
-  if (params->create_properties.opener_tab_id.get()) {
-    int opener_id = *params->create_properties.opener_tab_id;
-
-    if (!ExtensionTabUtil::GetTabById(opener_id,
-                                      GetProfile(),
-                                      include_incognito(),
-                                      NULL,
-                                      NULL,
-                                      &opener,
-                                      NULL)) {
-      return false;
-    }
-  }
-
-  // TODO(rafaelw): handle setting remaining tab properties:
-  // -title
-  // -favIconUrl
-
-  std::string url_string;
-  GURL url;
-  if (params->create_properties.url.get()) {
-    url_string = *params->create_properties.url;
-    url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string,
-                                                       GetExtension());
-    if (!url.is_valid()) {
-      error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError,
-                                                       url_string);
-      return false;
-    }
-  }
-
-  // Don't let extensions crash the browser or renderers.
-  if (ExtensionTabUtil::IsCrashURL(url)) {
-    error_ = keys::kNoCrashBrowserError;
-    return false;
-  }
-
-  // Default to foreground for the new tab. The presence of 'selected' property
-  // will override this default. This property is deprecated ('active' should
-  // be used instead).
-  bool active = true;
-  if (params->create_properties.selected.get())
-    active = *params->create_properties.selected;
-
+  ExtensionTabUtil::OpenTabParams options;
+  AssignOptionalValue(params->create_properties.window_id, options.window_id);
+  AssignOptionalValue(params->create_properties.opener_tab_id,
+                      options.opener_tab_id);
+  AssignOptionalValue(params->create_properties.selected, options.active);
   // The 'active' property has replaced the 'selected' property.
-  if (params->create_properties.active.get())
-    active = *params->create_properties.active;
+  AssignOptionalValue(params->create_properties.active, options.active);
+  AssignOptionalValue(params->create_properties.pinned, options.pinned);
+  AssignOptionalValue(params->create_properties.index, options.index);
+  AssignOptionalValue(params->create_properties.url, options.url);
 
-  // Default to not pinning the tab. Setting the 'pinned' property to true
-  // will override this default.
-  bool pinned = false;
-  if (params->create_properties.pinned.get())
-    pinned = *params->create_properties.pinned;
-
-  // We can't load extension URLs into incognito windows unless the extension
-  // uses split mode. Special case to fall back to a tabbed window.
-  if (url.SchemeIs(kExtensionScheme) &&
-      !IncognitoInfo::IsSplitMode(GetExtension()) &&
-      browser->profile()->IsOffTheRecord()) {
-    Profile* profile = browser->profile()->GetOriginalProfile();
-    chrome::HostDesktopType desktop_type = browser->host_desktop_type();
-
-    browser = chrome::FindTabbedBrowser(profile, false, desktop_type);
-    if (!browser) {
-      browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED,
-                                                  profile, desktop_type));
-      browser->window()->Show();
-    }
+  std::string error;
+  scoped_ptr<base::DictionaryValue> result(
+      ExtensionTabUtil::OpenTab(this, options, &error));
+  if (!result) {
+    SetError(error);
+    return false;
   }
 
-  // If index is specified, honor the value, but keep it bound to
-  // -1 <= index <= tab_strip->count() where -1 invokes the default behavior.
-  int index = -1;
-  if (params->create_properties.index.get())
-    index = *params->create_properties.index;
-
-  TabStripModel* tab_strip = browser->tab_strip_model();
-
-  index = std::min(std::max(index, -1), tab_strip->count());
-
-  int add_types = active ? TabStripModel::ADD_ACTIVE :
-                             TabStripModel::ADD_NONE;
-  add_types |= TabStripModel::ADD_FORCE_INDEX;
-  if (pinned)
-    add_types |= TabStripModel::ADD_PINNED;
-  chrome::NavigateParams navigate_params(
-      browser, url, content::PAGE_TRANSITION_LINK);
-  navigate_params.disposition =
-      active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
-  navigate_params.tabstrip_index = index;
-  navigate_params.tabstrip_add_types = add_types;
-  chrome::Navigate(&navigate_params);
-
-  // The tab may have been created in a different window, so make sure we look
-  // at the right tab strip.
-  tab_strip = navigate_params.browser->tab_strip_model();
-  int new_index = tab_strip->GetIndexOfWebContents(
-      navigate_params.target_contents);
-  if (opener)
-    tab_strip->SetOpenerOfWebContentsAt(new_index, opener);
-
-  if (active)
-    navigate_params.target_contents->GetView()->SetInitialFocus();
-
   // Return data about the newly created tab.
   if (has_callback()) {
-    SetResult(ExtensionTabUtil::CreateTabValue(
-        navigate_params.target_contents,
-        tab_strip, new_index, GetExtension()));
+    SetResult(result.release());
   }
-
   return true;
 }
 
@@ -1187,7 +1051,7 @@
 TabsUpdateFunction::TabsUpdateFunction() : web_contents_(NULL) {
 }
 
-bool TabsUpdateFunction::RunImpl() {
+bool TabsUpdateFunction::RunAsync() {
   scoped_ptr<tabs::Update::Params> params(tabs::Update::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -1657,7 +1521,7 @@
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 }
 
-bool TabsDetectLanguageFunction::RunImpl() {
+bool TabsDetectLanguageFunction::RunAsync() {
   scoped_ptr<tabs::DetectLanguage::Params> params(
       tabs::DetectLanguage::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.h b/chrome/browser/extensions/api/tabs/tabs_api.h
index 605fcb9..720b93c 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.h
+++ b/chrome/browser/extensions/api/tabs/tabs_api.h
@@ -148,7 +148,7 @@
   content::WebContents* web_contents_;
 
  private:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void OnExecuteCodeFinished(const std::string& error,
                              int32 on_page_id,
                              const GURL& on_url,
@@ -181,7 +181,7 @@
                                    public content::NotificationObserver {
  private:
   virtual ~TabsDetectLanguageFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   virtual void Observe(int type,
                        const content::NotificationSource& source,
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
index 4957647..4e93b40 100644
--- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
@@ -203,8 +203,8 @@
 }
 
 void TabsEventRouter::TabInsertedAt(WebContents* contents,
-                                       int index,
-                                       bool active) {
+                                    int index,
+                                    bool active) {
   // If tab is new, send created event.
   int tab_id = ExtensionTabUtil::GetTabId(contents);
   if (!GetTabEntry(contents)) {
@@ -472,8 +472,7 @@
   EventRouter::Get(profile)->BroadcastEvent(event.Pass());
 }
 
-TabsEventRouter::TabEntry* TabsEventRouter::GetTabEntry(
-    const WebContents* contents) {
+TabsEventRouter::TabEntry* TabsEventRouter::GetTabEntry(WebContents* contents) {
   int tab_id = ExtensionTabUtil::GetTabId(contents);
   std::map<int, TabEntry>::iterator i = tab_entries_.find(tab_id);
   if (tab_entries_.end() == i)
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.h b/chrome/browser/extensions/api/tabs/tabs_event_router.h
index 461786a..12ecfb7 100644
--- a/chrome/browser/extensions/api/tabs/tabs_event_router.h
+++ b/chrome/browser/extensions/api/tabs/tabs_event_router.h
@@ -156,7 +156,7 @@
 
   // Gets the TabEntry for the given |contents|. Returns TabEntry* if
   // found, NULL if not.
-  TabEntry* GetTabEntry(const content::WebContents* contents);
+  TabEntry* GetTabEntry(content::WebContents* contents);
 
   std::map<int, TabEntry> tab_entries_;
 
diff --git a/chrome/browser/extensions/api/tabs/windows_util.cc b/chrome/browser/extensions/api/tabs/windows_util.cc
index 88363d1..a2b640d 100644
--- a/chrome/browser/extensions/api/tabs/windows_util.cc
+++ b/chrome/browser/extensions/api/tabs/windows_util.cc
@@ -15,7 +15,7 @@
 
 namespace windows_util {
 
-bool GetWindowFromWindowID(ChromeAsyncExtensionFunction* function,
+bool GetWindowFromWindowID(ChromeUIThreadExtensionFunction* function,
                            int window_id,
                            extensions::WindowController** controller) {
   if (window_id == extension_misc::kCurrentWindowId) {
diff --git a/chrome/browser/extensions/api/tabs/windows_util.h b/chrome/browser/extensions/api/tabs/windows_util.h
index f3d6c5f..61f8c4b 100644
--- a/chrome/browser/extensions/api/tabs/windows_util.h
+++ b/chrome/browser/extensions/api/tabs/windows_util.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_API_TABS_WINDOWS_UTIL_H__
 #define CHROME_BROWSER_EXTENSIONS_API_TABS_WINDOWS_UTIL_H__
 
-class ChromeAsyncExtensionFunction;
+class ChromeUIThreadExtensionFunction;
 
 namespace extensions {
 class WindowController;
@@ -15,7 +15,7 @@
 
 // Populates |controller| for given |window_id|. If the window is not found,
 // returns false and sets UIThreadExtensionFunction error_.
-bool GetWindowFromWindowID(ChromeAsyncExtensionFunction* function,
+bool GetWindowFromWindowID(ChromeUIThreadExtensionFunction* function,
                            int window_id,
                            extensions::WindowController** controller);
 
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.cc b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
index 8cfbfdd..76eb375 100644
--- a/chrome/browser/extensions/api/terminal/terminal_private_api.cc
+++ b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
@@ -77,7 +77,7 @@
 
 TerminalPrivateFunction::~TerminalPrivateFunction() {}
 
-bool TerminalPrivateFunction::RunImpl() {
+bool TerminalPrivateFunction::RunAsync() {
   return RunTerminalFunction();
 }
 
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.h b/chrome/browser/extensions/api/terminal/terminal_private_api.h
index ca79049..1764ab8 100644
--- a/chrome/browser/extensions/api/terminal/terminal_private_api.h
+++ b/chrome/browser/extensions/api/terminal/terminal_private_api.h
@@ -20,7 +20,7 @@
   virtual ~TerminalPrivateFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Override with actual extension function implementation.
   virtual bool RunTerminalFunction() = 0;
diff --git a/chrome/browser/extensions/api/top_sites/top_sites_api.cc b/chrome/browser/extensions/api/top_sites/top_sites_api.cc
index cead49a..940667a 100644
--- a/chrome/browser/extensions/api/top_sites/top_sites_api.cc
+++ b/chrome/browser/extensions/api/top_sites/top_sites_api.cc
@@ -17,7 +17,7 @@
 
 TopSitesGetFunction::~TopSitesGetFunction() {}
 
-bool TopSitesGetFunction::RunImpl() {
+bool TopSitesGetFunction::RunAsync() {
   history::TopSites* ts = GetProfile()->GetTopSites();
   if (!ts)
     return false;
diff --git a/chrome/browser/extensions/api/top_sites/top_sites_api.h b/chrome/browser/extensions/api/top_sites/top_sites_api.h
index 9cd2b78..21440a1 100644
--- a/chrome/browser/extensions/api/top_sites/top_sites_api.h
+++ b/chrome/browser/extensions/api/top_sites/top_sites_api.h
@@ -21,7 +21,7 @@
   virtual ~TopSitesGetFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void OnMostVisitedURLsAvailable(const history::MostVisitedURLList& data);
diff --git a/chrome/browser/extensions/api/usb/usb_api.cc b/chrome/browser/extensions/api/usb/usb_api.cc
deleted file mode 100644
index 2df4c20..0000000
--- a/chrome/browser/extensions/api/usb/usb_api.cc
+++ /dev/null
@@ -1,1191 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/extensions/api/usb/usb_api.h"
-
-#include <string>
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "chrome/browser/extensions/api/usb/usb_device_resource.h"
-#include "chrome/common/extensions/api/usb.h"
-#include "components/usb_service/usb_device_handle.h"
-#include "components/usb_service/usb_service.h"
-#include "extensions/browser/extension_system.h"
-#include "extensions/common/permissions/permissions_data.h"
-#include "extensions/common/permissions/usb_device_permission.h"
-
-namespace usb = extensions::api::usb;
-namespace BulkTransfer = usb::BulkTransfer;
-namespace ClaimInterface = usb::ClaimInterface;
-namespace CloseDevice = usb::CloseDevice;
-namespace ControlTransfer = usb::ControlTransfer;
-namespace FindDevices = usb::FindDevices;
-namespace GetDevices = usb::GetDevices;
-namespace InterruptTransfer = usb::InterruptTransfer;
-namespace IsochronousTransfer = usb::IsochronousTransfer;
-namespace ListInterfaces = usb::ListInterfaces;
-namespace OpenDevice = usb::OpenDevice;
-namespace ReleaseInterface = usb::ReleaseInterface;
-namespace RequestAccess = usb::RequestAccess;
-namespace ResetDevice = usb::ResetDevice;
-namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting;
-
-using content::BrowserThread;
-using std::string;
-using std::vector;
-using usb::ControlTransferInfo;
-using usb::ConnectionHandle;
-using usb::Device;
-using usb::Direction;
-using usb::EndpointDescriptor;
-using usb::GenericTransferInfo;
-using usb::InterfaceDescriptor;
-using usb::IsochronousTransferInfo;
-using usb::Recipient;
-using usb::RequestType;
-using usb::SynchronizationType;
-using usb::TransferType;
-using usb::UsageType;
-using usb_service::UsbConfigDescriptor;
-using usb_service::UsbDevice;
-using usb_service::UsbDeviceHandle;
-using usb_service::UsbEndpointDescriptor;
-using usb_service::UsbEndpointDirection;
-using usb_service::UsbInterfaceAltSettingDescriptor;
-using usb_service::UsbInterfaceDescriptor;
-using usb_service::UsbService;
-using usb_service::UsbSynchronizationType;
-using usb_service::UsbTransferStatus;
-using usb_service::UsbTransferType;
-using usb_service::UsbUsageType;
-
-typedef std::vector<scoped_refptr<UsbDevice> > DeviceVector;
-typedef scoped_ptr<DeviceVector> ScopedDeviceVector;
-
-namespace {
-
-const char kDataKey[] = "data";
-const char kResultCodeKey[] = "resultCode";
-
-const char kErrorInitService[] = "Failed to initialize USB service.";
-
-const char kErrorOpen[] = "Failed to open device.";
-const char kErrorCancelled[] = "Transfer was cancelled.";
-const char kErrorDisconnect[] = "Device disconnected.";
-const char kErrorGeneric[] = "Transfer failed.";
-#if !defined(OS_CHROMEOS)
-const char kErrorNotSupported[] = "Not supported on this platform.";
-#endif
-const char kErrorOverflow[] = "Inbound transfer overflow.";
-const char kErrorStalled[] = "Transfer stalled.";
-const char kErrorTimeout[] = "Transfer timed out.";
-const char kErrorTransferLength[] = "Transfer length is insufficient.";
-
-const char kErrorCannotListInterfaces[] = "Error listing interfaces.";
-const char kErrorCannotClaimInterface[] = "Error claiming interface.";
-const char kErrorCannotReleaseInterface[] = "Error releasing interface.";
-const char kErrorCannotSetInterfaceAlternateSetting[] =
-    "Error setting alternate interface setting.";
-const char kErrorConvertDirection[] = "Invalid transfer direction.";
-const char kErrorConvertRecipient[] = "Invalid transfer recipient.";
-const char kErrorConvertRequestType[] = "Invalid request type.";
-const char kErrorConvertSynchronizationType[] = "Invalid synchronization type";
-const char kErrorConvertTransferType[] = "Invalid endpoint type.";
-const char kErrorConvertUsageType[] = "Invalid usage type.";
-const char kErrorMalformedParameters[] = "Error parsing parameters.";
-const char kErrorNoDevice[] = "No such device.";
-const char kErrorPermissionDenied[] =
-    "Permission to access device was denied";
-const char kErrorInvalidTransferLength[] =
-    "Transfer length must be a positive number less than 104,857,600.";
-const char kErrorInvalidNumberOfPackets[] =
-    "Number of packets must be a positive number less than 4,194,304.";
-const char kErrorInvalidPacketLength[] = "Packet length must be a "
-    "positive number less than 65,536.";
-const char kErrorResetDevice[] =
-    "Error resetting the device. The device has been closed.";
-
-const size_t kMaxTransferLength = 100 * 1024 * 1024;
-const int kMaxPackets = 4 * 1024 * 1024;
-const int kMaxPacketLength = 64 * 1024;
-
-UsbDevice* g_device_for_test = NULL;
-
-bool ConvertDirectionToApi(const UsbEndpointDirection& input,
-                           Direction* output) {
-  switch (input) {
-    case usb_service::USB_DIRECTION_INBOUND:
-      *output = usb::DIRECTION_IN;
-      return true;
-    case usb_service::USB_DIRECTION_OUTBOUND:
-      *output = usb::DIRECTION_OUT;
-      return true;
-    default:
-      NOTREACHED();
-      return false;
-  }
-}
-
-bool ConvertSynchronizationTypeToApi(const UsbSynchronizationType& input,
-                                     usb::SynchronizationType* output) {
-  switch (input) {
-    case usb_service::USB_SYNCHRONIZATION_NONE:
-      *output = usb::SYNCHRONIZATION_TYPE_NONE;
-      return true;
-    case usb_service::USB_SYNCHRONIZATION_ASYNCHRONOUS:
-      *output = usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS;
-      return true;
-    case usb_service::USB_SYNCHRONIZATION_ADAPTIVE:
-      *output = usb::SYNCHRONIZATION_TYPE_ADAPTIVE;
-      return true;
-    case usb_service::USB_SYNCHRONIZATION_SYNCHRONOUS:
-      *output = usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS;
-      return true;
-    default:
-      NOTREACHED();
-      return false;
-  }
-}
-
-bool ConvertTransferTypeToApi(
-    const UsbTransferType& input,
-    usb::TransferType* output) {
-  switch (input) {
-    case usb_service::USB_TRANSFER_CONTROL:
-      *output = usb::TRANSFER_TYPE_CONTROL;
-      return true;
-    case usb_service::USB_TRANSFER_INTERRUPT:
-      *output = usb::TRANSFER_TYPE_INTERRUPT;
-      return true;
-    case usb_service::USB_TRANSFER_ISOCHRONOUS:
-      *output = usb::TRANSFER_TYPE_ISOCHRONOUS;
-      return true;
-    case usb_service::USB_TRANSFER_BULK:
-      *output = usb::TRANSFER_TYPE_BULK;
-      return true;
-    default:
-      NOTREACHED();
-      return false;
-  }
-}
-
-bool ConvertUsageTypeToApi(const UsbUsageType& input, usb::UsageType* output) {
-  switch (input) {
-    case usb_service::USB_USAGE_DATA:
-      *output = usb::USAGE_TYPE_DATA;
-      return true;
-    case usb_service::USB_USAGE_FEEDBACK:
-      *output = usb::USAGE_TYPE_FEEDBACK;
-      return true;
-    case usb_service::USB_USAGE_EXPLICIT_FEEDBACK:
-      *output = usb::USAGE_TYPE_EXPLICITFEEDBACK;
-      return true;
-    default:
-      NOTREACHED();
-      return false;
-  }
-}
-
-bool ConvertDirection(const Direction& input,
-                      UsbEndpointDirection* output) {
-  switch (input) {
-    case usb::DIRECTION_IN:
-      *output = usb_service::USB_DIRECTION_INBOUND;
-      return true;
-    case usb::DIRECTION_OUT:
-      *output = usb_service::USB_DIRECTION_OUTBOUND;
-      return true;
-    default:
-      NOTREACHED();
-      return false;
-  }
-}
-
-bool ConvertRequestType(const RequestType& input,
-                        UsbDeviceHandle::TransferRequestType* output) {
-  switch (input) {
-    case usb::REQUEST_TYPE_STANDARD:
-      *output = UsbDeviceHandle::STANDARD;
-      return true;
-    case usb::REQUEST_TYPE_CLASS:
-      *output = UsbDeviceHandle::CLASS;
-      return true;
-    case usb::REQUEST_TYPE_VENDOR:
-      *output = UsbDeviceHandle::VENDOR;
-      return true;
-    case usb::REQUEST_TYPE_RESERVED:
-      *output = UsbDeviceHandle::RESERVED;
-      return true;
-    default:
-      NOTREACHED();
-      return false;
-  }
-}
-
-bool ConvertRecipient(const Recipient& input,
-                      UsbDeviceHandle::TransferRecipient* output) {
-  switch (input) {
-    case usb::RECIPIENT_DEVICE:
-      *output = UsbDeviceHandle::DEVICE;
-      return true;
-    case usb::RECIPIENT_INTERFACE:
-      *output = UsbDeviceHandle::INTERFACE;
-      return true;
-    case usb::RECIPIENT_ENDPOINT:
-      *output = UsbDeviceHandle::ENDPOINT;
-      return true;
-    case usb::RECIPIENT_OTHER:
-      *output = UsbDeviceHandle::OTHER;
-      return true;
-    default:
-      NOTREACHED();
-      return false;
-  }
-}
-
-template<class T>
-bool GetTransferSize(const T& input, size_t* output) {
-  if (input.direction == usb::DIRECTION_IN) {
-    const int* length = input.length.get();
-    if (length && *length >= 0 &&
-        static_cast<size_t>(*length) < kMaxTransferLength) {
-      *output = *length;
-      return true;
-    }
-  } else if (input.direction == usb::DIRECTION_OUT) {
-    if (input.data.get()) {
-      *output = input.data->size();
-      return true;
-    }
-  }
-  return false;
-}
-
-template<class T>
-scoped_refptr<net::IOBuffer> CreateBufferForTransfer(
-    const T& input, UsbEndpointDirection direction, size_t size) {
-
-  if (size >= kMaxTransferLength)
-    return NULL;
-
-  // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This
-  // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer
-  // cannot represent a zero-length buffer, while an URB can.
-  scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(std::max(
-      static_cast<size_t>(1), size));
-
-  if (direction == usb_service::USB_DIRECTION_INBOUND) {
-    return buffer;
-  } else if (direction == usb_service::USB_DIRECTION_OUTBOUND) {
-    if (input.data.get() && size <= input.data->size()) {
-      memcpy(buffer->data(), input.data->data(), size);
-      return buffer;
-    }
-  }
-  NOTREACHED();
-  return NULL;
-}
-
-const char* ConvertTransferStatusToErrorString(const UsbTransferStatus status) {
-  switch (status) {
-    case usb_service::USB_TRANSFER_COMPLETED:
-      return "";
-    case usb_service::USB_TRANSFER_ERROR:
-      return kErrorGeneric;
-    case usb_service::USB_TRANSFER_TIMEOUT:
-      return kErrorTimeout;
-    case usb_service::USB_TRANSFER_CANCELLED:
-      return kErrorCancelled;
-    case usb_service::USB_TRANSFER_STALLED:
-      return kErrorStalled;
-    case usb_service::USB_TRANSFER_DISCONNECT:
-      return kErrorDisconnect;
-    case usb_service::USB_TRANSFER_OVERFLOW:
-      return kErrorOverflow;
-    case usb_service::USB_TRANSFER_LENGTH_SHORT:
-      return kErrorTransferLength;
-    default:
-      NOTREACHED();
-      return "";
-  }
-}
-
-#if defined(OS_CHROMEOS)
-void RequestUsbDevicesAccessHelper(
-    ScopedDeviceVector devices,
-    std::vector<scoped_refptr<UsbDevice> >::iterator i,
-    int interface_id,
-    const base::Callback<void(ScopedDeviceVector result)>& callback,
-    bool success) {
-  if (success) {
-    ++i;
-  } else {
-    i = devices->erase(i);
-  }
-  if (i == devices->end()) {
-    callback.Run(devices.Pass());
-    return;
-  }
-  (*i)->RequestUsbAcess(interface_id, base::Bind(RequestUsbDevicesAccessHelper,
-                                                 base::Passed(devices.Pass()),
-                                                 i, interface_id, callback));
-}
-
-void RequestUsbDevicesAccess(
-    ScopedDeviceVector devices,
-    int interface_id,
-    const base::Callback<void(ScopedDeviceVector result)>& callback) {
-  if (devices->empty()) {
-    callback.Run(devices.Pass());
-    return;
-  }
-  std::vector<scoped_refptr<UsbDevice> >::iterator i = devices->begin();
-  (*i)->RequestUsbAcess(
-      interface_id,
-      base::Bind(RequestUsbDevicesAccessHelper, base::Passed(devices.Pass()),
-                 i, interface_id, callback));
-}
-#endif  // OS_CHROMEOS
-
-base::DictionaryValue* CreateTransferInfo(
-    UsbTransferStatus status,
-    scoped_refptr<net::IOBuffer> data,
-    size_t length) {
-  base::DictionaryValue* result = new base::DictionaryValue();
-  result->SetInteger(kResultCodeKey, status);
-  result->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer(data->data(),
-                                                                  length));
-  return result;
-}
-
-base::Value* PopulateConnectionHandle(int handle, int vendor_id,
-                                      int product_id) {
-  ConnectionHandle result;
-  result.handle = handle;
-  result.vendor_id = vendor_id;
-  result.product_id = product_id;
-  return result.ToValue().release();
-}
-
-base::Value* PopulateDevice(UsbDevice* device) {
-  Device result;
-  result.device = device->unique_id();
-  result.vendor_id = device->vendor_id();
-  result.product_id = device->product_id();
-  return result.ToValue().release();
-}
-
-base::Value* PopulateInterfaceDescriptor(
-    int interface_number,
-    int alternate_setting,
-    int interface_class,
-    int interface_subclass,
-    int interface_protocol,
-    std::vector<linked_ptr<EndpointDescriptor> >* endpoints) {
-  InterfaceDescriptor descriptor;
-  descriptor.interface_number = interface_number;
-  descriptor.alternate_setting = alternate_setting;
-  descriptor.interface_class = interface_class;
-  descriptor.interface_subclass = interface_subclass;
-  descriptor.interface_protocol = interface_protocol;
-  descriptor.endpoints = *endpoints;
-  return descriptor.ToValue().release();
-}
-
-}  // namespace
-
-namespace extensions {
-
-UsbAsyncApiFunction::UsbAsyncApiFunction()
-    : manager_(NULL) {
-}
-
-UsbAsyncApiFunction::~UsbAsyncApiFunction() {
-}
-
-bool UsbAsyncApiFunction::PrePrepare() {
-  manager_ = ApiResourceManager<UsbDeviceResource>::Get(browser_context());
-  set_work_thread_id(BrowserThread::FILE);
-  return manager_ != NULL;
-}
-
-bool UsbAsyncApiFunction::Respond() {
-  return error_.empty();
-}
-
-scoped_refptr<UsbDevice>
-UsbAsyncApiFunction::GetDeviceOrOrCompleteWithError(
-    const Device& input_device) {
-  if (g_device_for_test)
-    return g_device_for_test;
-
-  const uint16_t vendor_id = input_device.vendor_id;
-  const uint16_t product_id = input_device.product_id;
-  UsbDevicePermission::CheckParam param(
-      vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
-  if (!PermissionsData::CheckAPIPermissionWithParam(
-          GetExtension(), APIPermission::kUsbDevice, &param)) {
-    LOG(WARNING) << "Insufficient permissions to access device.";
-    CompleteWithError(kErrorPermissionDenied);
-    return NULL;
-  }
-
-  UsbService* service = UsbService::GetInstance();
-  if (!service) {
-    CompleteWithError(kErrorInitService);
-    return NULL;
-  }
-  scoped_refptr<UsbDevice> device;
-
-  device = service->GetDeviceById(input_device.device);
-
-  if (!device) {
-    CompleteWithError(kErrorNoDevice);
-    return NULL;
-  }
-
-  if (device->vendor_id() != input_device.vendor_id ||
-      device->product_id() != input_device.product_id) {
-    // Must act as if there is no such a device.
-    // Otherwise can be used to finger print unauthorized devices.
-    CompleteWithError(kErrorNoDevice);
-    return NULL;
-  }
-
-  return device;
-}
-
-scoped_refptr<UsbDeviceHandle>
-UsbAsyncApiFunction::GetDeviceHandleOrCompleteWithError(
-    const ConnectionHandle& input_device_handle) {
-  UsbDeviceResource* resource =
-      manager_->Get(extension_->id(), input_device_handle.handle);
-  if (!resource) {
-    CompleteWithError(kErrorNoDevice);
-    return NULL;
-  }
-
-  if (!resource->device() || !resource->device()->device()) {
-    CompleteWithError(kErrorDisconnect);
-    manager_->Remove(extension_->id(), input_device_handle.handle);
-    return NULL;
-  }
-
-  if (resource->device()->device()->vendor_id() !=
-          input_device_handle.vendor_id ||
-      resource->device()->device()->product_id() !=
-          input_device_handle.product_id) {
-    CompleteWithError(kErrorNoDevice);
-    return NULL;
-  }
-
-  return resource->device();
-}
-
-void UsbAsyncApiFunction::RemoveUsbDeviceResource(int api_resource_id) {
-  manager_->Remove(extension_->id(), api_resource_id);
-}
-
-void UsbAsyncApiFunction::CompleteWithError(const std::string& error) {
-  SetError(error);
-  AsyncWorkCompleted();
-}
-
-UsbAsyncApiTransferFunction::UsbAsyncApiTransferFunction() {}
-
-UsbAsyncApiTransferFunction::~UsbAsyncApiTransferFunction() {}
-
-void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status,
-                                              scoped_refptr<net::IOBuffer> data,
-                                              size_t length) {
-  if (status != usb_service::USB_TRANSFER_COMPLETED)
-    SetError(ConvertTransferStatusToErrorString(status));
-
-  SetResult(CreateTransferInfo(status, data, length));
-  AsyncWorkCompleted();
-}
-
-bool UsbAsyncApiTransferFunction::ConvertDirectionSafely(
-    const Direction& input, UsbEndpointDirection* output) {
-  const bool converted = ConvertDirection(input, output);
-  if (!converted)
-    SetError(kErrorConvertDirection);
-  return converted;
-}
-
-bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely(
-    const RequestType& input, UsbDeviceHandle::TransferRequestType* output) {
-  const bool converted = ConvertRequestType(input, output);
-  if (!converted)
-    SetError(kErrorConvertRequestType);
-  return converted;
-}
-
-bool UsbAsyncApiTransferFunction::ConvertRecipientSafely(
-    const Recipient& input, UsbDeviceHandle::TransferRecipient* output) {
-  const bool converted = ConvertRecipient(input, output);
-  if (!converted)
-    SetError(kErrorConvertRecipient);
-  return converted;
-}
-
-UsbFindDevicesFunction::UsbFindDevicesFunction() {}
-
-UsbFindDevicesFunction::~UsbFindDevicesFunction() {}
-
-bool UsbFindDevicesFunction::Prepare() {
-  parameters_ = FindDevices::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbFindDevicesFunction::AsyncWorkStart() {
-  scoped_ptr<base::ListValue> result(new base::ListValue());
-
-  if (g_device_for_test) {
-    UsbDeviceResource* const resource = new UsbDeviceResource(
-        extension_->id(),
-        g_device_for_test->Open());
-
-    result->Append(PopulateConnectionHandle(manager_->Add(resource), 0, 0));
-    SetResult(result.release());
-    AsyncWorkCompleted();
-    return;
-  }
-
-  const uint16_t vendor_id = parameters_->options.vendor_id;
-  const uint16_t product_id = parameters_->options.product_id;
-  int interface_id = parameters_->options.interface_id.get() ?
-      *parameters_->options.interface_id.get() :
-      UsbDevicePermissionData::ANY_INTERFACE;
-  UsbDevicePermission::CheckParam param(vendor_id, product_id, interface_id);
-  if (!PermissionsData::CheckAPIPermissionWithParam(
-          GetExtension(), APIPermission::kUsbDevice, &param)) {
-    LOG(WARNING) << "Insufficient permissions to access device.";
-    CompleteWithError(kErrorPermissionDenied);
-    return;
-  }
-
-  UsbService *service = UsbService::GetInstance();
-  if (!service) {
-    CompleteWithError(kErrorInitService);
-    return;
-  }
-
-  ScopedDeviceVector devices(new DeviceVector());
-  service->GetDevices(devices.get());
-
-  for (DeviceVector::iterator it = devices->begin();
-      it != devices->end();) {
-    if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) {
-      it = devices->erase(it);
-    } else {
-      ++it;
-    }
-  }
-
-#if defined(OS_CHROMEOS)
-  RequestUsbDevicesAccess(
-      devices.Pass(), interface_id,
-      base::Bind(&UsbFindDevicesFunction::OpenDevices, this));
-#else
-  OpenDevices(devices.Pass());
-#endif  // OS_CHROMEOS
-}
-
-void UsbFindDevicesFunction::OpenDevices(ScopedDeviceVector devices) {
-  base::ListValue* result = new base::ListValue();
-
-  for (size_t i = 0; i < devices->size(); ++i) {
-    scoped_refptr<UsbDeviceHandle> device_handle =
-      devices->at(i)->Open();
-    if (device_handle)
-      device_handles_.push_back(device_handle);
-  }
-
-  for (size_t i = 0; i < device_handles_.size(); ++i) {
-    UsbDeviceHandle* const device_handle = device_handles_[i].get();
-    UsbDeviceResource* const resource =
-        new UsbDeviceResource(extension_->id(), device_handle);
-
-    result->Append(PopulateConnectionHandle(manager_->Add(resource),
-                                             parameters_->options.vendor_id,
-                                             parameters_->options.product_id));
-  }
-
-  SetResult(result);
-  AsyncWorkCompleted();
-}
-
-UsbGetDevicesFunction::UsbGetDevicesFunction() {
-}
-
-UsbGetDevicesFunction::~UsbGetDevicesFunction() {
-}
-
-void UsbGetDevicesFunction::SetDeviceForTest(UsbDevice* device) {
-  g_device_for_test = device;
-}
-
-bool UsbGetDevicesFunction::Prepare() {
-  parameters_ = GetDevices::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbGetDevicesFunction::AsyncWorkStart() {
-  scoped_ptr<base::ListValue> result(new base::ListValue());
-
-  if (g_device_for_test) {
-    result->Append(PopulateDevice(g_device_for_test));
-    SetResult(result.release());
-    AsyncWorkCompleted();
-    return;
-  }
-
-  const uint16_t vendor_id = parameters_->options.vendor_id;
-  const uint16_t product_id = parameters_->options.product_id;
-  UsbDevicePermission::CheckParam param(
-      vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
-  if (!PermissionsData::CheckAPIPermissionWithParam(
-          GetExtension(), APIPermission::kUsbDevice, &param)) {
-    LOG(WARNING) << "Insufficient permissions to access device.";
-    CompleteWithError(kErrorPermissionDenied);
-    return;
-  }
-
-  UsbService* service = UsbService::GetInstance();
-  if (!service) {
-    CompleteWithError(kErrorInitService);
-    return;
-  }
-
-  DeviceVector devices;
-  service->GetDevices(&devices);
-
-  for (DeviceVector::iterator it = devices.begin(); it != devices.end();) {
-    if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) {
-      it = devices.erase(it);
-    } else {
-      ++it;
-    }
-  }
-
-  for (size_t i = 0; i < devices.size(); ++i) {
-    result->Append(PopulateDevice(devices[i].get()));
-  }
-
-  SetResult(result.release());
-  AsyncWorkCompleted();
-}
-
-UsbRequestAccessFunction::UsbRequestAccessFunction() {}
-
-UsbRequestAccessFunction::~UsbRequestAccessFunction() {}
-
-bool UsbRequestAccessFunction::Prepare() {
-  parameters_ = RequestAccess::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbRequestAccessFunction::AsyncWorkStart() {
-#if defined(OS_CHROMEOS)
-  scoped_refptr<UsbDevice> device =
-      GetDeviceOrOrCompleteWithError(parameters_->device);
-  if (!device) return;
-
-  device->RequestUsbAcess(parameters_->interface_id,
-                          base::Bind(&UsbRequestAccessFunction::OnCompleted,
-                                     this));
-#else
-  SetResult(new base::FundamentalValue(false));
-  CompleteWithError(kErrorNotSupported);
-#endif  // OS_CHROMEOS
-}
-
-void UsbRequestAccessFunction::OnCompleted(bool success) {
-  SetResult(new base::FundamentalValue(success));
-  AsyncWorkCompleted();
-}
-
-UsbOpenDeviceFunction::UsbOpenDeviceFunction() {}
-
-UsbOpenDeviceFunction::~UsbOpenDeviceFunction() {}
-
-bool UsbOpenDeviceFunction::Prepare() {
-  parameters_ = OpenDevice::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbOpenDeviceFunction::AsyncWorkStart() {
-  scoped_refptr<UsbDevice> device =
-      GetDeviceOrOrCompleteWithError(parameters_->device);
-  if (!device) return;
-
-  handle_ = device->Open();
-  if (!handle_) {
-    SetError(kErrorOpen);
-    AsyncWorkCompleted();
-    return;
-  }
-
-  SetResult(PopulateConnectionHandle(
-      manager_->Add(new UsbDeviceResource(extension_->id(), handle_)),
-      handle_->device()->vendor_id(),
-      handle_->device()->product_id()));
-  AsyncWorkCompleted();
-}
-
-UsbListInterfacesFunction::UsbListInterfacesFunction() {}
-
-UsbListInterfacesFunction::~UsbListInterfacesFunction() {}
-
-bool UsbListInterfacesFunction::Prepare() {
-  parameters_ = ListInterfaces::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbListInterfacesFunction::AsyncWorkStart() {
-  scoped_refptr<UsbDeviceHandle> device_handle =
-      GetDeviceHandleOrCompleteWithError(parameters_->handle);
-  if (!device_handle) return;
-
-  scoped_refptr<UsbConfigDescriptor> config =
-      device_handle->device()->ListInterfaces();
-
-  if (!config) {
-    SetError(kErrorCannotListInterfaces);
-    AsyncWorkCompleted();
-    return;
-  }
-
-  result_.reset(new base::ListValue());
-
-  for (size_t i = 0, num_interfaces = config->GetNumInterfaces();
-      i < num_interfaces; ++i) {
-    scoped_refptr<const UsbInterfaceDescriptor>
-        usb_interface(config->GetInterface(i));
-    for (size_t j = 0, num_descriptors = usb_interface->GetNumAltSettings();
-            j < num_descriptors; ++j) {
-      scoped_refptr<const UsbInterfaceAltSettingDescriptor> descriptor
-          = usb_interface->GetAltSetting(j);
-      std::vector<linked_ptr<EndpointDescriptor> > endpoints;
-      for (size_t k = 0, num_endpoints = descriptor->GetNumEndpoints();
-          k < num_endpoints; k++) {
-        scoped_refptr<const UsbEndpointDescriptor> endpoint
-            = descriptor->GetEndpoint(k);
-        linked_ptr<EndpointDescriptor> endpoint_desc(new EndpointDescriptor());
-
-        TransferType type;
-        Direction direction;
-        SynchronizationType synchronization;
-        UsageType usage;
-
-        if (!ConvertTransferTypeSafely(endpoint->GetTransferType(), &type) ||
-            !ConvertDirectionSafely(endpoint->GetDirection(), &direction) ||
-            !ConvertSynchronizationTypeSafely(
-                endpoint->GetSynchronizationType(), &synchronization) ||
-            !ConvertUsageTypeSafely(endpoint->GetUsageType(), &usage)) {
-          SetError(kErrorCannotListInterfaces);
-          AsyncWorkCompleted();
-          return;
-        }
-
-        endpoint_desc->address = endpoint->GetAddress();
-        endpoint_desc->type = type;
-        endpoint_desc->direction = direction;
-        endpoint_desc->maximum_packet_size = endpoint->GetMaximumPacketSize();
-        endpoint_desc->synchronization = synchronization;
-        endpoint_desc->usage = usage;
-
-        int* polling_interval = new int;
-        endpoint_desc->polling_interval.reset(polling_interval);
-        *polling_interval = endpoint->GetPollingInterval();
-
-        endpoints.push_back(endpoint_desc);
-      }
-
-      result_->Append(PopulateInterfaceDescriptor(
-          descriptor->GetInterfaceNumber(),
-          descriptor->GetAlternateSetting(),
-          descriptor->GetInterfaceClass(),
-          descriptor->GetInterfaceSubclass(),
-          descriptor->GetInterfaceProtocol(),
-          &endpoints));
-    }
-  }
-
-  SetResult(result_.release());
-  AsyncWorkCompleted();
-}
-
-bool UsbListInterfacesFunction::ConvertDirectionSafely(
-    const UsbEndpointDirection& input,
-    usb::Direction* output) {
-  const bool converted = ConvertDirectionToApi(input, output);
-  if (!converted)
-    SetError(kErrorConvertDirection);
-  return converted;
-}
-
-bool UsbListInterfacesFunction::ConvertSynchronizationTypeSafely(
-    const UsbSynchronizationType& input,
-    usb::SynchronizationType* output) {
-  const bool converted = ConvertSynchronizationTypeToApi(input, output);
-  if (!converted)
-    SetError(kErrorConvertSynchronizationType);
-  return converted;
-}
-
-bool UsbListInterfacesFunction::ConvertTransferTypeSafely(
-    const UsbTransferType& input,
-    usb::TransferType* output) {
-  const bool converted = ConvertTransferTypeToApi(input, output);
-  if (!converted)
-    SetError(kErrorConvertTransferType);
-  return converted;
-}
-
-bool UsbListInterfacesFunction::ConvertUsageTypeSafely(
-    const UsbUsageType& input,
-    usb::UsageType* output) {
-  const bool converted = ConvertUsageTypeToApi(input, output);
-  if (!converted)
-    SetError(kErrorConvertUsageType);
-  return converted;
-}
-
-UsbCloseDeviceFunction::UsbCloseDeviceFunction() {}
-
-UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {}
-
-bool UsbCloseDeviceFunction::Prepare() {
-  parameters_ = CloseDevice::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbCloseDeviceFunction::AsyncWorkStart() {
-  scoped_refptr<UsbDeviceHandle> device_handle =
-      GetDeviceHandleOrCompleteWithError(parameters_->handle);
-  if (!device_handle) return;
-
-  device_handle->Close();
-  RemoveUsbDeviceResource(parameters_->handle.handle);
-  AsyncWorkCompleted();
-}
-
-UsbClaimInterfaceFunction::UsbClaimInterfaceFunction() {}
-
-UsbClaimInterfaceFunction::~UsbClaimInterfaceFunction() {}
-
-bool UsbClaimInterfaceFunction::Prepare() {
-  parameters_ = ClaimInterface::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbClaimInterfaceFunction::AsyncWorkStart() {
-  scoped_refptr<UsbDeviceHandle> device_handle =
-      GetDeviceHandleOrCompleteWithError(parameters_->handle);
-  if (!device_handle) return;
-
-  bool success = device_handle->ClaimInterface(parameters_->interface_number);
-
-  if (!success)
-    SetError(kErrorCannotClaimInterface);
-  AsyncWorkCompleted();
-}
-
-UsbReleaseInterfaceFunction::UsbReleaseInterfaceFunction() {}
-
-UsbReleaseInterfaceFunction::~UsbReleaseInterfaceFunction() {}
-
-bool UsbReleaseInterfaceFunction::Prepare() {
-  parameters_ = ReleaseInterface::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbReleaseInterfaceFunction::AsyncWorkStart() {
-  scoped_refptr<UsbDeviceHandle> device_handle =
-      GetDeviceHandleOrCompleteWithError(parameters_->handle);
-  if (!device_handle) return;
-
-  bool success = device_handle->ReleaseInterface(parameters_->interface_number);
-  if (!success)
-    SetError(kErrorCannotReleaseInterface);
-  AsyncWorkCompleted();
-}
-
-UsbSetInterfaceAlternateSettingFunction::
-    UsbSetInterfaceAlternateSettingFunction() {}
-
-UsbSetInterfaceAlternateSettingFunction::
-    ~UsbSetInterfaceAlternateSettingFunction() {}
-
-bool UsbSetInterfaceAlternateSettingFunction::Prepare() {
-  parameters_ = SetInterfaceAlternateSetting::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbSetInterfaceAlternateSettingFunction::AsyncWorkStart() {
-  scoped_refptr<UsbDeviceHandle> device_handle =
-      GetDeviceHandleOrCompleteWithError(parameters_->handle);
-  if (!device_handle) return;
-
-  bool success = device_handle->SetInterfaceAlternateSetting(
-      parameters_->interface_number,
-      parameters_->alternate_setting);
-  if (!success)
-    SetError(kErrorCannotSetInterfaceAlternateSetting);
-
-  AsyncWorkCompleted();
-}
-
-UsbControlTransferFunction::UsbControlTransferFunction() {}
-
-UsbControlTransferFunction::~UsbControlTransferFunction() {}
-
-bool UsbControlTransferFunction::Prepare() {
-  parameters_ = ControlTransfer::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbControlTransferFunction::AsyncWorkStart() {
-  scoped_refptr<UsbDeviceHandle> device_handle =
-      GetDeviceHandleOrCompleteWithError(parameters_->handle);
-  if (!device_handle) return;
-
-  const ControlTransferInfo& transfer = parameters_->transfer_info;
-
-  UsbEndpointDirection direction;
-  UsbDeviceHandle::TransferRequestType request_type;
-  UsbDeviceHandle::TransferRecipient recipient;
-  size_t size = 0;
-
-  if (!ConvertDirectionSafely(transfer.direction, &direction) ||
-      !ConvertRequestTypeSafely(transfer.request_type, &request_type) ||
-      !ConvertRecipientSafely(transfer.recipient, &recipient)) {
-    AsyncWorkCompleted();
-    return;
-  }
-
-  if (!GetTransferSize(transfer, &size)) {
-    CompleteWithError(kErrorInvalidTransferLength);
-    return;
-  }
-
-  scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
-      transfer, direction, size);
-  if (!buffer.get()) {
-    CompleteWithError(kErrorMalformedParameters);
-    return;
-  }
-
-  device_handle->ControlTransfer(
-      direction,
-      request_type,
-      recipient,
-      transfer.request,
-      transfer.value,
-      transfer.index,
-      buffer.get(),
-      size,
-      0,
-      base::Bind(&UsbControlTransferFunction::OnCompleted, this));
-}
-
-UsbBulkTransferFunction::UsbBulkTransferFunction() {}
-
-UsbBulkTransferFunction::~UsbBulkTransferFunction() {}
-
-bool UsbBulkTransferFunction::Prepare() {
-  parameters_ = BulkTransfer::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbBulkTransferFunction::AsyncWorkStart() {
-  scoped_refptr<UsbDeviceHandle> device_handle =
-      GetDeviceHandleOrCompleteWithError(parameters_->handle);
-  if (!device_handle) return;
-
-  const GenericTransferInfo& transfer = parameters_->transfer_info;
-
-  UsbEndpointDirection direction;
-  size_t size = 0;
-
-  if (!ConvertDirectionSafely(transfer.direction, &direction)) {
-    AsyncWorkCompleted();
-    return;
-  }
-
-  if (!GetTransferSize(transfer, &size)) {
-    CompleteWithError(kErrorInvalidTransferLength);
-    return;
-  }
-
-  scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
-      transfer, direction, size);
-  if (!buffer.get()) {
-    CompleteWithError(kErrorMalformedParameters);
-    return;
-  }
-
-  device_handle->BulkTransfer(
-      direction,
-      transfer.endpoint,
-      buffer.get(),
-      size,
-      0,
-      base::Bind(&UsbBulkTransferFunction::OnCompleted, this));
-}
-
-UsbInterruptTransferFunction::UsbInterruptTransferFunction() {}
-
-UsbInterruptTransferFunction::~UsbInterruptTransferFunction() {}
-
-bool UsbInterruptTransferFunction::Prepare() {
-  parameters_ = InterruptTransfer::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbInterruptTransferFunction::AsyncWorkStart() {
-  scoped_refptr<UsbDeviceHandle> device_handle =
-      GetDeviceHandleOrCompleteWithError(parameters_->handle);
-  if (!device_handle) return;
-
-  const GenericTransferInfo& transfer = parameters_->transfer_info;
-
-  UsbEndpointDirection direction;
-  size_t size = 0;
-
-  if (!ConvertDirectionSafely(transfer.direction, &direction)) {
-    AsyncWorkCompleted();
-    return;
-  }
-
-  if (!GetTransferSize(transfer, &size)) {
-    CompleteWithError(kErrorInvalidTransferLength);
-    return;
-  }
-
-  scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
-      transfer, direction, size);
-  if (!buffer.get()) {
-    CompleteWithError(kErrorMalformedParameters);
-    return;
-  }
-
-  device_handle->InterruptTransfer(
-      direction,
-      transfer.endpoint,
-      buffer.get(),
-      size,
-      0,
-      base::Bind(&UsbInterruptTransferFunction::OnCompleted, this));
-}
-
-UsbIsochronousTransferFunction::UsbIsochronousTransferFunction() {}
-
-UsbIsochronousTransferFunction::~UsbIsochronousTransferFunction() {}
-
-bool UsbIsochronousTransferFunction::Prepare() {
-  parameters_ = IsochronousTransfer::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbIsochronousTransferFunction::AsyncWorkStart() {
-  scoped_refptr<UsbDeviceHandle> device_handle =
-      GetDeviceHandleOrCompleteWithError(parameters_->handle);
-  if (!device_handle) return;
-
-  const IsochronousTransferInfo& transfer = parameters_->transfer_info;
-  const GenericTransferInfo& generic_transfer = transfer.transfer_info;
-
-  size_t size = 0;
-  UsbEndpointDirection direction;
-
-  if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) {
-    AsyncWorkCompleted();
-    return;
-  }
-  if (!GetTransferSize(generic_transfer, &size)) {
-    CompleteWithError(kErrorInvalidTransferLength);
-    return;
-  }
-  if (transfer.packets < 0 || transfer.packets >= kMaxPackets) {
-    CompleteWithError(kErrorInvalidNumberOfPackets);
-    return;
-  }
-  unsigned int packets = transfer.packets;
-  if (transfer.packet_length < 0 ||
-      transfer.packet_length >= kMaxPacketLength) {
-    CompleteWithError(kErrorInvalidPacketLength);
-    return;
-  }
-  unsigned int packet_length = transfer.packet_length;
-  const uint64 total_length = packets * packet_length;
-  if (packets > size || total_length > size) {
-    CompleteWithError(kErrorTransferLength);
-    return;
-  }
-
-  scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
-      generic_transfer, direction, size);
-  if (!buffer.get()) {
-    CompleteWithError(kErrorMalformedParameters);
-    return;
-  }
-
-  device_handle->IsochronousTransfer(
-      direction,
-      generic_transfer.endpoint,
-      buffer.get(),
-      size,
-      packets,
-      packet_length,
-      0,
-      base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this));
-}
-
-UsbResetDeviceFunction::UsbResetDeviceFunction() {}
-
-UsbResetDeviceFunction::~UsbResetDeviceFunction() {}
-
-bool UsbResetDeviceFunction::Prepare() {
-  parameters_ = ResetDevice::Params::Create(*args_);
-  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
-  return true;
-}
-
-void UsbResetDeviceFunction::AsyncWorkStart() {
-  scoped_refptr<UsbDeviceHandle> device_handle =
-      GetDeviceHandleOrCompleteWithError(parameters_->handle);
-  if (!device_handle) return;
-
-  bool success = device_handle->ResetDevice();
-  if (!success) {
-    device_handle->Close();
-    RemoveUsbDeviceResource(parameters_->handle.handle);
-    SetResult(new base::FundamentalValue(false));
-    CompleteWithError(kErrorResetDevice);
-    return;
-  }
-
-  SetResult(new base::FundamentalValue(true));
-  AsyncWorkCompleted();
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/api/usb/usb_api.h b/chrome/browser/extensions/api/usb/usb_api.h
deleted file mode 100644
index 12e572c..0000000
--- a/chrome/browser/extensions/api/usb/usb_api.h
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_USB_USB_API_H_
-#define CHROME_BROWSER_EXTENSIONS_API_USB_USB_API_H_
-
-#include <string>
-#include <vector>
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/common/extensions/api/usb.h"
-#include "components/usb_service/usb_device.h"
-#include "components/usb_service/usb_device_handle.h"
-#include "extensions/browser/api/api_resource_manager.h"
-#include "extensions/browser/api/async_api_function.h"
-#include "net/base/io_buffer.h"
-
-namespace extensions {
-
-class UsbDeviceResource;
-
-class UsbAsyncApiFunction : public AsyncApiFunction {
- public:
-  UsbAsyncApiFunction();
-
- protected:
-  virtual ~UsbAsyncApiFunction();
-
-  virtual bool PrePrepare() OVERRIDE;
-  virtual bool Respond() OVERRIDE;
-
-  scoped_refptr<usb_service::UsbDevice> GetDeviceOrOrCompleteWithError(
-      const extensions::api::usb::Device& input_device);
-
-  scoped_refptr<usb_service::UsbDeviceHandle>
-      GetDeviceHandleOrCompleteWithError(
-          const extensions::api::usb::ConnectionHandle& input_device_handle);
-
-  void RemoveUsbDeviceResource(int api_resource_id);
-
-  void CompleteWithError(const std::string& error);
-
-  ApiResourceManager<UsbDeviceResource>* manager_;
-};
-
-class UsbAsyncApiTransferFunction : public UsbAsyncApiFunction {
- protected:
-  UsbAsyncApiTransferFunction();
-  virtual ~UsbAsyncApiTransferFunction();
-
-  bool ConvertDirectionSafely(const extensions::api::usb::Direction& input,
-                              usb_service::UsbEndpointDirection* output);
-  bool ConvertRequestTypeSafely(
-      const extensions::api::usb::RequestType& input,
-      usb_service::UsbDeviceHandle::TransferRequestType* output);
-  bool ConvertRecipientSafely(
-      const extensions::api::usb::Recipient& input,
-      usb_service::UsbDeviceHandle::TransferRecipient* output);
-
-  void OnCompleted(usb_service::UsbTransferStatus status,
-                   scoped_refptr<net::IOBuffer> data,
-                   size_t length);
-};
-
-class UsbFindDevicesFunction : public UsbAsyncApiFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.findDevices", USB_FINDDEVICES)
-
-  UsbFindDevicesFunction();
-
- protected:
-  virtual ~UsbFindDevicesFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- private:
-  void OpenDevices(
-      scoped_ptr<std::vector<scoped_refptr<usb_service::UsbDevice> > > devices);
-
-  std::vector<scoped_refptr<usb_service::UsbDeviceHandle> > device_handles_;
-  scoped_ptr<extensions::api::usb::FindDevices::Params> parameters_;
-};
-
-class UsbGetDevicesFunction : public UsbAsyncApiFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.getDevices", USB_GETDEVICES)
-
-  UsbGetDevicesFunction();
-
-  static void SetDeviceForTest(usb_service::UsbDevice* device);
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- protected:
-  virtual ~UsbGetDevicesFunction();
-
- private:
-  void EnumerationCompletedFileThread(
-      scoped_ptr<std::vector<scoped_refptr<usb_service::UsbDevice> > > devices);
-
-  scoped_ptr<extensions::api::usb::GetDevices::Params> parameters_;
-};
-
-class UsbRequestAccessFunction : public UsbAsyncApiFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.requestAccess", USB_REQUESTACCESS)
-
-  UsbRequestAccessFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- protected:
-  virtual ~UsbRequestAccessFunction();
-
-  void OnCompleted(bool success);
-
- private:
-  scoped_ptr<extensions::api::usb::RequestAccess::Params> parameters_;
-};
-
-class UsbOpenDeviceFunction : public UsbAsyncApiFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.openDevice", USB_OPENDEVICE)
-
-  UsbOpenDeviceFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- protected:
-  virtual ~UsbOpenDeviceFunction();
-
- private:
-  scoped_refptr<usb_service::UsbDeviceHandle> handle_;
-  scoped_ptr<extensions::api::usb::OpenDevice::Params> parameters_;
-};
-
-class UsbListInterfacesFunction : public UsbAsyncApiFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.listInterfaces", USB_LISTINTERFACES)
-
-  UsbListInterfacesFunction();
-
- protected:
-  virtual ~UsbListInterfacesFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- private:
-  bool ConvertDirectionSafely(const usb_service::UsbEndpointDirection& input,
-                              extensions::api::usb::Direction* output);
-  bool ConvertSynchronizationTypeSafely(
-      const usb_service::UsbSynchronizationType& input,
-      extensions::api::usb::SynchronizationType* output);
-  bool ConvertTransferTypeSafely(const usb_service::UsbTransferType& input,
-                                 extensions::api::usb::TransferType* output);
-  bool ConvertUsageTypeSafely(const usb_service::UsbUsageType& input,
-                              extensions::api::usb::UsageType* output);
-
-  scoped_ptr<base::ListValue> result_;
-  scoped_ptr<extensions::api::usb::ListInterfaces::Params> parameters_;
-};
-
-class UsbCloseDeviceFunction : public UsbAsyncApiFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.closeDevice", USB_CLOSEDEVICE)
-
-  UsbCloseDeviceFunction();
-
- protected:
-  virtual ~UsbCloseDeviceFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- private:
-  scoped_ptr<extensions::api::usb::CloseDevice::Params> parameters_;
-};
-
-class UsbClaimInterfaceFunction : public UsbAsyncApiFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.claimInterface", USB_CLAIMINTERFACE)
-
-  UsbClaimInterfaceFunction();
-
- protected:
-  virtual ~UsbClaimInterfaceFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- private:
-  scoped_ptr<extensions::api::usb::ClaimInterface::Params> parameters_;
-};
-
-class UsbReleaseInterfaceFunction : public UsbAsyncApiFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.releaseInterface", USB_RELEASEINTERFACE)
-
-  UsbReleaseInterfaceFunction();
-
- protected:
-  virtual ~UsbReleaseInterfaceFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- private:
-  scoped_ptr<extensions::api::usb::ReleaseInterface::Params> parameters_;
-};
-
-class UsbSetInterfaceAlternateSettingFunction : public UsbAsyncApiFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.setInterfaceAlternateSetting",
-                             USB_SETINTERFACEALTERNATESETTING)
-
-  UsbSetInterfaceAlternateSettingFunction();
-
- private:
-  virtual ~UsbSetInterfaceAlternateSettingFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
-  scoped_ptr<extensions::api::usb::SetInterfaceAlternateSetting::Params>
-      parameters_;
-};
-
-class UsbControlTransferFunction : public UsbAsyncApiTransferFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.controlTransfer", USB_CONTROLTRANSFER)
-
-  UsbControlTransferFunction();
-
- protected:
-  virtual ~UsbControlTransferFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- private:
-  scoped_ptr<extensions::api::usb::ControlTransfer::Params> parameters_;
-};
-
-class UsbBulkTransferFunction : public UsbAsyncApiTransferFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.bulkTransfer", USB_BULKTRANSFER)
-
-  UsbBulkTransferFunction();
-
- protected:
-  virtual ~UsbBulkTransferFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- private:
-  scoped_ptr<extensions::api::usb::BulkTransfer::Params> parameters_;
-};
-
-class UsbInterruptTransferFunction : public UsbAsyncApiTransferFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.interruptTransfer", USB_INTERRUPTTRANSFER)
-
-  UsbInterruptTransferFunction();
-
- protected:
-  virtual ~UsbInterruptTransferFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- private:
-  scoped_ptr<extensions::api::usb::InterruptTransfer::Params> parameters_;
-};
-
-class UsbIsochronousTransferFunction : public UsbAsyncApiTransferFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.isochronousTransfer", USB_ISOCHRONOUSTRANSFER)
-
-  UsbIsochronousTransferFunction();
-
- protected:
-  virtual ~UsbIsochronousTransferFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- private:
-  scoped_ptr<extensions::api::usb::IsochronousTransfer::Params> parameters_;
-};
-
-class UsbResetDeviceFunction : public UsbAsyncApiFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("usb.resetDevice", USB_RESETDEVICE)
-
-  UsbResetDeviceFunction();
-
- protected:
-  virtual ~UsbResetDeviceFunction();
-
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- private:
-  scoped_ptr<extensions::api::usb::ResetDevice::Params> parameters_;
-};
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_API_USB_USB_API_H_
diff --git a/chrome/browser/extensions/api/usb/usb_apitest.cc b/chrome/browser/extensions/api/usb/usb_apitest.cc
deleted file mode 100644
index 4f2d72f..0000000
--- a/chrome/browser/extensions/api/usb/usb_apitest.cc
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/extensions/api/usb/usb_api.h"
-#include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/ui/browser.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/base/io_buffer.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-using testing::AnyNumber;
-using testing::_;
-using testing::Return;
-using content::BrowserThread;
-using usb_service::UsbConfigDescriptor;
-using usb_service::UsbDevice;
-using usb_service::UsbDeviceHandle;
-using usb_service::UsbEndpointDirection;
-using usb_service::UsbTransferCallback;
-
-namespace {
-
-ACTION_TEMPLATE(InvokeUsbTransferCallback,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_1_VALUE_PARAMS(p1)) {
-  ::std::tr1::get<k>(args).Run(p1, new net::IOBuffer(1), 1);
-}
-
-// MSVC erroneously thinks that at least one of the arguments for the transfer
-// methods differ by const or volatility and emits a warning about the old
-// standards-noncompliant behaviour of their compiler.
-#if defined(OS_WIN)
-#pragma warning(push)
-#pragma warning(disable:4373)
-#endif
-
-class MockUsbDeviceHandle : public UsbDeviceHandle {
- public:
-  MockUsbDeviceHandle() : UsbDeviceHandle() {}
-
-  MOCK_METHOD0(Close, void());
-
-  MOCK_METHOD10(ControlTransfer, void(const UsbEndpointDirection direction,
-      const TransferRequestType request_type, const TransferRecipient recipient,
-      const uint8 request, const uint16 value, const uint16 index,
-      net::IOBuffer* buffer, const size_t length, const unsigned int timeout,
-      const UsbTransferCallback& callback));
-
-  MOCK_METHOD6(BulkTransfer, void(const UsbEndpointDirection direction,
-      const uint8 endpoint, net::IOBuffer* buffer, const size_t length,
-      const unsigned int timeout, const UsbTransferCallback& callback));
-
-  MOCK_METHOD6(InterruptTransfer, void(const UsbEndpointDirection direction,
-      const uint8 endpoint, net::IOBuffer* buffer, const size_t length,
-      const unsigned int timeout, const UsbTransferCallback& callback));
-
-  MOCK_METHOD8(IsochronousTransfer, void(const UsbEndpointDirection direction,
-      const uint8 endpoint, net::IOBuffer* buffer, const size_t length,
-      const unsigned int packets, const unsigned int packet_length,
-      const unsigned int timeout, const UsbTransferCallback& callback));
-
-  MOCK_METHOD0(ResetDevice, bool());
-
-  void set_device(UsbDevice* device) { device_ = device; }
-
- protected:
-  virtual ~MockUsbDeviceHandle() {}
-};
-
-class MockUsbDevice : public UsbDevice {
- public:
-  explicit MockUsbDevice(MockUsbDeviceHandle* mock_handle)
-     : UsbDevice(),
-       mock_handle_(mock_handle) {
-    mock_handle->set_device(this);
-  }
-
-  virtual scoped_refptr<UsbDeviceHandle> Open() OVERRIDE {
-    return mock_handle_;
-  }
-
-  virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE {
-    EXPECT_TRUE(false) << "Should not be reached";
-    return false;
-  }
-
-  MOCK_METHOD0(ListInterfaces, scoped_refptr<UsbConfigDescriptor>());
-
- private:
-  MockUsbDeviceHandle* mock_handle_;
-  virtual ~MockUsbDevice() {}
-};
-
-#if defined(OS_WIN)
-#pragma warning(pop)
-#endif
-
-class UsbApiTest : public ExtensionApiTest {
- public:
-  virtual void SetUpOnMainThread() OVERRIDE {
-    mock_device_handle_ = new MockUsbDeviceHandle();
-    mock_device_ = new MockUsbDevice(mock_device_handle_.get());
-    extensions::UsbGetDevicesFunction::SetDeviceForTest(mock_device_.get());
-  }
-
- protected:
-  scoped_refptr<MockUsbDeviceHandle> mock_device_handle_;
-  scoped_refptr<MockUsbDevice> mock_device_;
-};
-
-}  // namespace
-
-IN_PROC_BROWSER_TEST_F(UsbApiTest, DeviceHandling) {
-  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(4);
-  ASSERT_TRUE(RunExtensionTest("usb/device_handling"));
-}
-
-IN_PROC_BROWSER_TEST_F(UsbApiTest, ResetDevice) {
-  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(2);
-  EXPECT_CALL(*mock_device_handle_.get(), ResetDevice())
-      .WillOnce(Return(true))
-      .WillOnce(Return(false));
-  EXPECT_CALL(
-      *mock_device_handle_.get(),
-      InterruptTransfer(usb_service::USB_DIRECTION_OUTBOUND, 2, _, 1, _, _))
-      .WillOnce(
-          InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_COMPLETED));
-  ASSERT_TRUE(RunExtensionTest("usb/reset_device"));
-}
-
-IN_PROC_BROWSER_TEST_F(UsbApiTest, ListInterfaces) {
-  EXPECT_CALL(*mock_device_.get(), ListInterfaces())
-      .WillOnce(Return(scoped_refptr<UsbConfigDescriptor>()));
-  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
-  ASSERT_TRUE(RunExtensionTest("usb/list_interfaces"));
-}
-
-IN_PROC_BROWSER_TEST_F(UsbApiTest, TransferEvent) {
-  EXPECT_CALL(*mock_device_handle_.get(),
-              ControlTransfer(usb_service::USB_DIRECTION_OUTBOUND,
-                              UsbDeviceHandle::STANDARD,
-                              UsbDeviceHandle::DEVICE,
-                              1, 2, 3, _, 1, _, _))
-      .WillOnce(
-          InvokeUsbTransferCallback<9>(usb_service::USB_TRANSFER_COMPLETED));
-  EXPECT_CALL(*mock_device_handle_.get(),
-              BulkTransfer(usb_service::USB_DIRECTION_OUTBOUND, 1, _, 1, _, _))
-      .WillOnce(
-          InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_COMPLETED));
-  EXPECT_CALL(
-      *mock_device_handle_.get(),
-      InterruptTransfer(usb_service::USB_DIRECTION_OUTBOUND, 2, _, 1, _, _))
-      .WillOnce(
-          InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_COMPLETED));
-  EXPECT_CALL(*mock_device_handle_.get(),
-              IsochronousTransfer(
-                  usb_service::USB_DIRECTION_OUTBOUND, 3, _, 1, 1, 1, _, _))
-      .WillOnce(
-          InvokeUsbTransferCallback<7>(usb_service::USB_TRANSFER_COMPLETED));
-  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
-  ASSERT_TRUE(RunExtensionTest("usb/transfer_event"));
-}
-
-IN_PROC_BROWSER_TEST_F(UsbApiTest, ZeroLengthTransfer) {
-  EXPECT_CALL(*mock_device_handle_.get(), BulkTransfer(_, _, _, 0, _, _))
-      .WillOnce(
-          InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_COMPLETED));
-  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
-  ASSERT_TRUE(RunExtensionTest("usb/zero_length_transfer"));
-}
-
-IN_PROC_BROWSER_TEST_F(UsbApiTest, TransferFailure) {
-  EXPECT_CALL(*mock_device_handle_.get(), BulkTransfer(_, _, _, _, _, _))
-      .WillOnce(
-           InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_COMPLETED))
-      .WillOnce(InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_ERROR))
-      .WillOnce(
-          InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_TIMEOUT));
-  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
-  ASSERT_TRUE(RunExtensionTest("usb/transfer_failure"));
-}
-
-IN_PROC_BROWSER_TEST_F(UsbApiTest, InvalidLengthTransfer) {
-  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
-  ASSERT_TRUE(RunExtensionTest("usb/invalid_length_transfer"));
-}
diff --git a/chrome/browser/extensions/api/usb/usb_device_resource.cc b/chrome/browser/extensions/api/usb/usb_device_resource.cc
deleted file mode 100644
index 633635d..0000000
--- a/chrome/browser/extensions/api/usb/usb_device_resource.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/extensions/api/usb/usb_device_resource.h"
-
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/synchronization/lock.h"
-#include "chrome/common/extensions/api/usb.h"
-#include "components/usb_service/usb_device_handle.h"
-#include "content/public/browser/browser_thread.h"
-#include "extensions/browser/api/api_resource.h"
-
-using content::BrowserThread;
-using usb_service::UsbDeviceHandle;
-
-namespace extensions {
-
-static base::LazyInstance<
-    BrowserContextKeyedAPIFactory<ApiResourceManager<UsbDeviceResource> > >
-    g_factory = LAZY_INSTANCE_INITIALIZER;
-
-// static
-template <>
-BrowserContextKeyedAPIFactory<ApiResourceManager<UsbDeviceResource> >*
-ApiResourceManager<UsbDeviceResource>::GetFactoryInstance() {
-  return g_factory.Pointer();
-}
-
-UsbDeviceResource::UsbDeviceResource(const std::string& owner_extension_id,
-                                     scoped_refptr<UsbDeviceHandle> device)
-    : ApiResource(owner_extension_id), device_(device) {}
-
-UsbDeviceResource::~UsbDeviceResource() {
-  BrowserThread::PostTask(BrowserThread::FILE,
-                          FROM_HERE,
-                          base::Bind(&UsbDeviceHandle::Close, device_));
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/api/usb/usb_device_resource.h b/chrome/browser/extensions/api/usb/usb_device_resource.h
deleted file mode 100644
index f07f2dc..0000000
--- a/chrome/browser/extensions/api/usb/usb_device_resource.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_USB_USB_DEVICE_RESOURCE_H_
-#define CHROME_BROWSER_EXTENSIONS_API_USB_USB_DEVICE_RESOURCE_H_
-
-#include <set>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/memory/linked_ptr.h"
-#include "base/memory/ref_counted.h"
-#include "base/synchronization/lock.h"
-#include "chrome/common/extensions/api/usb.h"
-#include "components/usb_service/usb_device_handle.h"
-#include "content/public/browser/browser_thread.h"
-#include "extensions/browser/api/api_resource.h"
-#include "extensions/browser/api/api_resource_manager.h"
-
-namespace net {
-class IOBuffer;
-}  // namespace net
-
-namespace extensions {
-
-// A UsbDeviceResource is an ApiResource wrapper for a UsbDevice.
-class UsbDeviceResource : public ApiResource {
- public:
-  UsbDeviceResource(const std::string& owner_extension_id,
-                    scoped_refptr<usb_service::UsbDeviceHandle> device);
-  virtual ~UsbDeviceResource();
-
-  scoped_refptr<usb_service::UsbDeviceHandle> device() { return device_; }
-
-  static const content::BrowserThread::ID kThreadId =
-      content::BrowserThread::FILE;
-
- private:
-  friend class ApiResourceManager<UsbDeviceResource>;
-  static const char* service_name() { return "UsbDeviceResourceManager"; }
-
-  scoped_refptr<usb_service::UsbDeviceHandle> device_;
-
-  DISALLOW_COPY_AND_ASSIGN(UsbDeviceResource);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_API_USB_USB_DEVICE_RESOURCE_H_
diff --git a/chrome/browser/extensions/api/usb/usb_manual_apitest.cc b/chrome/browser/extensions/api/usb/usb_manual_apitest.cc
deleted file mode 100644
index be08a8a..0000000
--- a/chrome/browser/extensions/api/usb/usb_manual_apitest.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2013 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.
-
-#include "chrome/browser/extensions/api/permissions/permissions_api.h"
-#include "chrome/browser/extensions/extension_apitest.h"
-
-namespace {
-
-class UsbManualApiTest : public ExtensionApiTest {
-};
-
-}  // namespace
-
-IN_PROC_BROWSER_TEST_F(UsbManualApiTest, MANUAL_ListInterfaces) {
-  extensions::PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
-  extensions::PermissionsRequestFunction::SetAutoConfirmForTests(true);
-  ASSERT_TRUE(RunExtensionTest("usb_manual/list_interfaces"));
-}
diff --git a/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc b/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc
index 8356221..9cd4349 100644
--- a/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc
+++ b/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc
@@ -14,14 +14,14 @@
 
 // URL schemes for which we'll send events.
 const char* kValidSchemes[] = {
-  content::kChromeUIScheme,
-  content::kHttpScheme,
-  content::kHttpsScheme,
-  content::kFileScheme,
-  content::kFtpScheme,
-  content::kJavaScriptScheme,
-  content::kDataScheme,
-  content::kFileSystemScheme,
+    content::kChromeUIScheme,
+    url::kHttpScheme,
+    url::kHttpsScheme,
+    content::kFileScheme,
+    content::kFtpScheme,
+    content::kJavaScriptScheme,
+    content::kDataScheme,
+    content::kFileSystemScheme,
 };
 
 }  // namespace
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
index 26e86ad..392d749 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
@@ -646,10 +646,10 @@
   navigation_state_.FrameDetached(frame_id);
 }
 
-void WebNavigationTabObserver::WebContentsDestroyed(content::WebContents* tab) {
-  g_tab_observer.Get().erase(tab);
+void WebNavigationTabObserver::WebContentsDestroyed() {
+  g_tab_observer.Get().erase(web_contents());
   registrar_.RemoveAll();
-  SendErrorEvents(tab, NULL, FrameNavigationState::FrameID());
+  SendErrorEvents(web_contents(), NULL, FrameNavigationState::FrameID());
 }
 
 void WebNavigationTabObserver::SendErrorEvents(
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
index d3aaf76..f0e144d 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
@@ -105,7 +105,7 @@
                                    int64 source_frame_num) OVERRIDE;
   virtual void FrameDetached(content::RenderViewHost* render_view_host,
                              int64 frame_num) OVERRIDE;
-  virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
  private:
   explicit WebNavigationTabObserver(content::WebContents* web_contents);
diff --git a/chrome/browser/extensions/api/web_request/web_request_api.cc b/chrome/browser/extensions/api/web_request/web_request_api.cc
index 1b4fe41..eef2a80 100644
--- a/chrome/browser/extensions/api/web_request/web_request_api.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_api.cc
@@ -302,7 +302,7 @@
                                           const std::string& value) {
   base::DictionaryValue* header = new base::DictionaryValue();
   header->SetString(keys::kHeaderNameKey, name);
-  if (IsStringUTF8(value)) {
+  if (base::IsStringUTF8(value)) {
     header->SetString(keys::kHeaderValueKey, value);
   } else {
     header->Set(keys::kHeaderBinaryValueKey,
@@ -2417,7 +2417,7 @@
                  profile_id(), warnings));
 
   // Continue gracefully.
-  Run();
+  RunSync();
 }
 
 bool WebRequestHandlerBehaviorChangedFunction::RunSync() {
diff --git a/chrome/browser/extensions/api/web_request/web_request_permissions.cc b/chrome/browser/extensions/api/web_request/web_request_permissions.cc
index 636db60..3bda598 100644
--- a/chrome/browser/extensions/api/web_request/web_request_permissions.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_permissions.cc
@@ -72,8 +72,8 @@
           url.SchemeIs(content::kFileScheme) ||
           url.SchemeIs(content::kFileSystemScheme) ||
           url.SchemeIs(content::kFtpScheme) ||
-          url.SchemeIs(content::kHttpScheme) ||
-          url.SchemeIs(content::kHttpsScheme) ||
+          url.SchemeIs(url::kHttpScheme) ||
+          url.SchemeIs(url::kHttpsScheme) ||
           url.SchemeIs(extensions::kExtensionScheme));
 }
 
diff --git a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc
index 6d4c178..0edc00b 100644
--- a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc
+++ b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc
@@ -204,7 +204,7 @@
   return resource_context_;
 }
 
-bool WebrtcAudioPrivateGetSinksFunction::RunImpl() {
+bool WebrtcAudioPrivateGetSinksFunction::RunAsync() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   InitResourceContext();
@@ -233,7 +233,7 @@
   // normally runs) because there is one instance of this object per
   // function call, no actor outside of this object is modifying the
   // results_ member, and the different method invocations on this
-  // object run strictly in sequence; first RunImpl on the UI thread,
+  // object run strictly in sequence; first RunAsync on the UI thread,
   // then DoQuery on the audio IO thread, then DoneOnUIThread on the
   // UI thread.
   results_.reset(wap::GetSinks::Results::Create(results).release());
@@ -248,7 +248,7 @@
   SendResponse(true);
 }
 
-bool WebrtcAudioPrivateGetActiveSinkFunction::RunImpl() {
+bool WebrtcAudioPrivateGetActiveSinkFunction::RunAsync() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   InitResourceContext();
 
@@ -306,7 +306,7 @@
 ~WebrtcAudioPrivateSetActiveSinkFunction() {
 }
 
-bool WebrtcAudioPrivateSetActiveSinkFunction::RunImpl() {
+bool WebrtcAudioPrivateSetActiveSinkFunction::RunAsync() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   scoped_ptr<wap::SetActiveSink::Params> params(
       wap::SetActiveSink::Params::Create(*args_));
@@ -391,7 +391,7 @@
 ~WebrtcAudioPrivateGetAssociatedSinkFunction() {
 }
 
-bool WebrtcAudioPrivateGetAssociatedSinkFunction::RunImpl() {
+bool WebrtcAudioPrivateGetAssociatedSinkFunction::RunAsync() {
   params_ = wap::GetAssociatedSink::Params::Create(*args_);
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   EXTENSION_FUNCTION_VALIDATE(params_.get());
diff --git a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.h b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.h
index be4a9e8..be98154 100644
--- a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.h
+++ b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.h
@@ -117,7 +117,7 @@
   // Sequence of events is that we query the list of sinks on the
   // AudioManager's thread, then calculate HMACs on the IO thread,
   // then finish on the UI thread.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   void DoQuery();
   virtual void OnOutputDeviceNames(
       scoped_ptr<media::AudioDeviceNames> raw_ids) OVERRIDE;
@@ -133,7 +133,7 @@
   DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getActiveSink",
                              WEBRTC_AUDIO_PRIVATE_GET_ACTIVE_SINK);
 
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   virtual void OnControllerList(
       const content::RenderViewHost::AudioOutputControllerList&
       controllers) OVERRIDE;
@@ -152,7 +152,7 @@
   DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.setActiveSink",
                              WEBRTC_AUDIO_PRIVATE_SET_ACTIVE_SINK);
 
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   virtual void OnControllerList(
       const content::RenderViewHost::AudioOutputControllerList&
       controllers) OVERRIDE;
@@ -184,7 +184,7 @@
   DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getAssociatedSink",
                              WEBRTC_AUDIO_PRIVATE_GET_ASSOCIATED_SINK);
 
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // This implementation is slightly complicated because of different
   // thread requirements for the various functions we need to invoke.
diff --git a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc
index 6ea1163..9d02674 100644
--- a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc
+++ b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc
@@ -29,6 +29,8 @@
 namespace Stop = api::webrtc_logging_private::Stop;
 namespace Upload = api::webrtc_logging_private::Upload;
 namespace Discard = api::webrtc_logging_private::Discard;
+namespace StartRtpDump = api::webrtc_logging_private::StartRtpDump;
+namespace StopRtpDump = api::webrtc_logging_private::StopRtpDump;
 
 using api::webrtc_logging_private::MetaDataEntry;
 
@@ -64,7 +66,7 @@
 WebrtcLoggingPrivateSetMetaDataFunction::
 ~WebrtcLoggingPrivateSetMetaDataFunction() {}
 
-bool WebrtcLoggingPrivateSetMetaDataFunction::RunImpl() {
+bool WebrtcLoggingPrivateSetMetaDataFunction::RunAsync() {
   scoped_ptr<SetMetaData::Params> params(SetMetaData::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -104,7 +106,7 @@
 
 WebrtcLoggingPrivateStartFunction::~WebrtcLoggingPrivateStartFunction() {}
 
-bool WebrtcLoggingPrivateStartFunction::RunImpl() {
+bool WebrtcLoggingPrivateStartFunction::RunAsync() {
   scoped_ptr<Start::Params> params(Start::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -140,7 +142,7 @@
 WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::
 ~WebrtcLoggingPrivateSetUploadOnRenderCloseFunction() {}
 
-bool WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::RunImpl() {
+bool WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::RunAsync() {
   scoped_ptr<SetUploadOnRenderClose::Params> params(
       SetUploadOnRenderClose::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -163,7 +165,7 @@
 
 WebrtcLoggingPrivateStopFunction::~WebrtcLoggingPrivateStopFunction() {}
 
-bool WebrtcLoggingPrivateStopFunction::RunImpl() {
+bool WebrtcLoggingPrivateStopFunction::RunAsync() {
   scoped_ptr<Stop::Params> params(Stop::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -197,7 +199,7 @@
 
 WebrtcLoggingPrivateUploadFunction::~WebrtcLoggingPrivateUploadFunction() {}
 
-bool WebrtcLoggingPrivateUploadFunction::RunImpl() {
+bool WebrtcLoggingPrivateUploadFunction::RunAsync() {
   scoped_ptr<Upload::Params> params(Upload::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -237,7 +239,7 @@
 
 WebrtcLoggingPrivateDiscardFunction::~WebrtcLoggingPrivateDiscardFunction() {}
 
-bool WebrtcLoggingPrivateDiscardFunction::RunImpl() {
+bool WebrtcLoggingPrivateDiscardFunction::RunAsync() {
   scoped_ptr<Discard::Params> params(Discard::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -267,4 +269,86 @@
   SendResponse(success);
 }
 
+WebrtcLoggingPrivateStartRtpDumpFunction::
+    WebrtcLoggingPrivateStartRtpDumpFunction() {}
+
+WebrtcLoggingPrivateStartRtpDumpFunction::
+    ~WebrtcLoggingPrivateStartRtpDumpFunction() {}
+
+bool WebrtcLoggingPrivateStartRtpDumpFunction::RunAsync() {
+  scoped_ptr<StartRtpDump::Params> params(StartRtpDump::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+
+  content::RenderProcessHost* host =
+      RphFromTabIdAndSecurityOrigin(params->tab_id, params->security_origin);
+  if (!host)
+    return false;
+
+  scoped_refptr<WebRtcLoggingHandlerHost> webrtc_logging_handler_host(
+      base::UserDataAdapter<WebRtcLoggingHandlerHost>::Get(host, host));
+
+  WebRtcLoggingHandlerHost::GenericDoneCallback callback = base::Bind(
+      &WebrtcLoggingPrivateStartRtpDumpFunction::StartRtpDumpCallback, this);
+
+  BrowserThread::PostTask(BrowserThread::IO,
+                          FROM_HERE,
+                          base::Bind(&WebRtcLoggingHandlerHost::StartRtpDump,
+                                     webrtc_logging_handler_host,
+                                     params->incoming,
+                                     params->outgoing,
+                                     callback));
+
+  return true;
+}
+
+void WebrtcLoggingPrivateStartRtpDumpFunction::StartRtpDumpCallback(
+    bool success,
+    const std::string& error_message) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  if (!success)
+    SetError(error_message);
+  SendResponse(success);
+}
+
+WebrtcLoggingPrivateStopRtpDumpFunction::
+    WebrtcLoggingPrivateStopRtpDumpFunction() {}
+
+WebrtcLoggingPrivateStopRtpDumpFunction::
+    ~WebrtcLoggingPrivateStopRtpDumpFunction() {}
+
+bool WebrtcLoggingPrivateStopRtpDumpFunction::RunAsync() {
+  scoped_ptr<StopRtpDump::Params> params(StopRtpDump::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+
+  content::RenderProcessHost* host =
+      RphFromTabIdAndSecurityOrigin(params->tab_id, params->security_origin);
+  if (!host)
+    return false;
+
+  scoped_refptr<WebRtcLoggingHandlerHost> webrtc_logging_handler_host(
+      base::UserDataAdapter<WebRtcLoggingHandlerHost>::Get(host, host));
+
+  WebRtcLoggingHandlerHost::GenericDoneCallback callback = base::Bind(
+      &WebrtcLoggingPrivateStopRtpDumpFunction::StopRtpDumpCallback, this);
+
+  BrowserThread::PostTask(BrowserThread::IO,
+                          FROM_HERE,
+                          base::Bind(&WebRtcLoggingHandlerHost::StopRtpDump,
+                                     webrtc_logging_handler_host,
+                                     params->incoming,
+                                     params->outgoing,
+                                     callback));
+
+  return true;
+}
+
+void WebrtcLoggingPrivateStopRtpDumpFunction::StopRtpDumpCallback(
+    bool success,
+    const std::string& error_message) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  if (!success)
+    SetError(error_message);
+  SendResponse(success);
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h
index 9bf1326..3f80538 100644
--- a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h
+++ b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h
@@ -36,7 +36,7 @@
   virtual ~WebrtcLoggingPrivateSetMetaDataFunction();
 
   // ExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Must be called on UI thread.
   void SetMetaDataCallback(bool success, const std::string& error_message);
@@ -53,7 +53,7 @@
   virtual ~WebrtcLoggingPrivateStartFunction();
 
   // ExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Must be called on UI thread.
   void StartCallback(bool success, const std::string& error_message);
@@ -70,7 +70,7 @@
   virtual ~WebrtcLoggingPrivateSetUploadOnRenderCloseFunction();
 
   // ExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class WebrtcLoggingPrivateStopFunction
@@ -84,7 +84,7 @@
   virtual ~WebrtcLoggingPrivateStopFunction();
 
   // ExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Must be called on UI thread.
   void StopCallback(bool success, const std::string& error_message);
@@ -101,7 +101,7 @@
   virtual ~WebrtcLoggingPrivateUploadFunction();
 
   // ExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Must be called on UI thread.
   void UploadCallback(bool success, const std::string& report_id,
@@ -119,12 +119,46 @@
   virtual ~WebrtcLoggingPrivateDiscardFunction();
 
   // ExtensionFunction overrides.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Must be called on UI thread.
   void DiscardCallback(bool success, const std::string& error_message);
 };
 
+class WebrtcLoggingPrivateStartRtpDumpFunction
+    : public WebrtcLoggingPrivateTabIdFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("webrtcLoggingPrivate.startRtpDump",
+                             WEBRTCLOGGINGPRIVATE_STARTRTPDUMP)
+  WebrtcLoggingPrivateStartRtpDumpFunction();
+
+ private:
+  virtual ~WebrtcLoggingPrivateStartRtpDumpFunction();
+
+  // ExtensionFunction overrides.
+  virtual bool RunAsync() OVERRIDE;
+
+  // Must be called on UI thread.
+  void StartRtpDumpCallback(bool success, const std::string& error_message);
+};
+
+class WebrtcLoggingPrivateStopRtpDumpFunction
+    : public WebrtcLoggingPrivateTabIdFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("webrtcLoggingPrivate.stopRtpDump",
+                             WEBRTCLOGGINGPRIVATE_STOPRTPDUMP)
+  WebrtcLoggingPrivateStopRtpDumpFunction();
+
+ private:
+  virtual ~WebrtcLoggingPrivateStopRtpDumpFunction();
+
+  // ExtensionFunction overrides.
+  virtual bool RunAsync() OVERRIDE;
+
+  // Must be called on UI thread.
+  void StopRtpDumpCallback(bool success, const std::string& error_message);
+};
+
 }  // namespace extensions
 
 #endif  // CHROME_BROWSER_EXTENSIONS_API_WEBRTC_LOGGING_PRIVATE_WEBRTC_LOGGING_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api_stub.cc b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api_stub.cc
index 9d082da..6a55645 100644
--- a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api_stub.cc
+++ b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api_stub.cc
@@ -20,7 +20,7 @@
 WebrtcLoggingPrivateSetMetaDataFunction::
 ~WebrtcLoggingPrivateSetMetaDataFunction() {}
 
-bool WebrtcLoggingPrivateSetMetaDataFunction::RunImpl() {
+bool WebrtcLoggingPrivateSetMetaDataFunction::RunAsync() {
   SetError(kErrorNotSupported);
   SendResponse(false);
   return false;
@@ -33,7 +33,7 @@
 
 WebrtcLoggingPrivateStartFunction::~WebrtcLoggingPrivateStartFunction() {}
 
-bool WebrtcLoggingPrivateStartFunction::RunImpl() {
+bool WebrtcLoggingPrivateStartFunction::RunAsync() {
   SetError(kErrorNotSupported);
   SendResponse(false);
   return false;
@@ -48,7 +48,7 @@
 WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::
 ~WebrtcLoggingPrivateSetUploadOnRenderCloseFunction() {}
 
-bool WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::RunImpl() {
+bool WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::RunAsync() {
   SetError(kErrorNotSupported);
   SendResponse(false);
   return false;
@@ -58,7 +58,7 @@
 
 WebrtcLoggingPrivateStopFunction::~WebrtcLoggingPrivateStopFunction() {}
 
-bool WebrtcLoggingPrivateStopFunction::RunImpl() {
+bool WebrtcLoggingPrivateStopFunction::RunAsync() {
   SetError(kErrorNotSupported);
   SendResponse(false);
   return false;
@@ -71,7 +71,7 @@
 
 WebrtcLoggingPrivateUploadFunction::~WebrtcLoggingPrivateUploadFunction() {}
 
-bool WebrtcLoggingPrivateUploadFunction::RunImpl() {
+bool WebrtcLoggingPrivateUploadFunction::RunAsync() {
   SetError(kErrorNotSupported);
   SendResponse(false);
   return false;
@@ -86,7 +86,7 @@
 
 WebrtcLoggingPrivateDiscardFunction::~WebrtcLoggingPrivateDiscardFunction() {}
 
-bool WebrtcLoggingPrivateDiscardFunction::RunImpl() {
+bool WebrtcLoggingPrivateDiscardFunction::RunAsync() {
   SetError(kErrorNotSupported);
   SendResponse(false);
   return false;
@@ -95,4 +95,42 @@
 void WebrtcLoggingPrivateDiscardFunction::DiscardCallback(
     bool success, const std::string& error_message) {}
 
+WebrtcLoggingPrivateStartRtpDumpFunction::
+    WebrtcLoggingPrivateStartRtpDumpFunction() {
+}
+
+WebrtcLoggingPrivateStartRtpDumpFunction::
+    ~WebrtcLoggingPrivateStartRtpDumpFunction() {
+}
+
+bool WebrtcLoggingPrivateStartRtpDumpFunction::RunAsync() {
+  SetError(kErrorNotSupported);
+  SendResponse(false);
+  return false;
+}
+
+void WebrtcLoggingPrivateStartRtpDumpFunction::StartRtpDumpCallback(
+    bool success,
+    const std::string& error_message) {
+}
+
+WebrtcLoggingPrivateStopRtpDumpFunction::
+    WebrtcLoggingPrivateStopRtpDumpFunction() {
+}
+
+WebrtcLoggingPrivateStopRtpDumpFunction::
+    ~WebrtcLoggingPrivateStopRtpDumpFunction() {
+}
+
+bool WebrtcLoggingPrivateStopRtpDumpFunction::RunAsync() {
+  SetError(kErrorNotSupported);
+  SendResponse(false);
+  return false;
+}
+
+void WebrtcLoggingPrivateStopRtpDumpFunction::StopRtpDumpCallback(
+    bool success,
+    const std::string& error_message) {
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
index 85e051c..8652336 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -215,7 +215,7 @@
 WebstorePrivateInstallBundleFunction::WebstorePrivateInstallBundleFunction() {}
 WebstorePrivateInstallBundleFunction::~WebstorePrivateInstallBundleFunction() {}
 
-bool WebstorePrivateInstallBundleFunction::RunImpl() {
+bool WebstorePrivateInstallBundleFunction::RunAsync() {
   scoped_ptr<InstallBundle::Params> params(
       InstallBundle::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -261,13 +261,13 @@
 
   SendResponse(false);
 
-  Release();  // Balanced in RunImpl().
+  Release();  // Balanced in RunAsync().
 }
 
 void WebstorePrivateInstallBundleFunction::OnBundleInstallCompleted() {
   SendResponse(true);
 
-  Release();  // Balanced in RunImpl().
+  Release();  // Balanced in RunAsync().
 }
 
 WebstorePrivateBeginInstallWithManifest3Function::
@@ -276,7 +276,7 @@
 WebstorePrivateBeginInstallWithManifest3Function::
     ~WebstorePrivateBeginInstallWithManifest3Function() {}
 
-bool WebstorePrivateBeginInstallWithManifest3Function::RunImpl() {
+bool WebstorePrivateBeginInstallWithManifest3Function::RunAsync() {
   params_ = BeginInstallWithManifest3::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params_);
 
@@ -434,7 +434,7 @@
   g_pending_installs.Get().EraseInstall(GetProfile(), id);
   SendResponse(false);
 
-  // Matches the AddRef in RunImpl().
+  // Matches the AddRef in RunAsync().
   Release();
 }
 
@@ -447,7 +447,7 @@
   g_pending_installs.Get().EraseInstall(GetProfile(), params_->details.id);
   SendResponse(false);
 
-  // Matches the AddRef in RunImpl().
+  // Matches the AddRef in RunAsync().
   Release();
 }
 
@@ -503,7 +503,7 @@
   ExtensionService::RecordPermissionMessagesHistogram(
       dummy_extension_.get(), "Extensions.Permissions_WebStoreInstall");
 
-  // Matches the AddRef in RunImpl().
+  // Matches the AddRef in RunAsync().
   Release();
 }
 
@@ -529,7 +529,7 @@
   ExtensionService::RecordPermissionMessagesHistogram(dummy_extension_.get(),
                                                       histogram_name.c_str());
 
-  // Matches the AddRef in RunImpl().
+  // Matches the AddRef in RunAsync().
   Release();
 }
 
@@ -539,7 +539,7 @@
 WebstorePrivateCompleteInstallFunction::
     ~WebstorePrivateCompleteInstallFunction() {}
 
-bool WebstorePrivateCompleteInstallFunction::RunImpl() {
+bool WebstorePrivateCompleteInstallFunction::RunAsync() {
   scoped_ptr<CompleteInstall::Params> params(
       CompleteInstall::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -601,7 +601,7 @@
 
   RecordWebstoreExtensionInstallResult(true);
 
-  // Matches the AddRef in RunImpl().
+  // Matches the AddRef in RunAsync().
   Release();
 }
 
@@ -621,7 +621,7 @@
 
   RecordWebstoreExtensionInstallResult(false);
 
-  // Matches the AddRef in RunImpl().
+  // Matches the AddRef in RunAsync().
   Release();
 }
 
@@ -673,7 +673,7 @@
       ParseWebgl_status(webgl_allowed ? "webgl_allowed" : "webgl_blocked"));
 }
 
-bool WebstorePrivateGetWebGLStatusFunction::RunImpl() {
+bool WebstorePrivateGetWebGLStatusFunction::RunAsync() {
   feature_checker_->CheckGPUFeatureAvailability();
   return true;
 }
@@ -699,7 +699,7 @@
     : signin_manager_(NULL) {}
 WebstorePrivateSignInFunction::~WebstorePrivateSignInFunction() {}
 
-bool WebstorePrivateSignInFunction::RunImpl() {
+bool WebstorePrivateSignInFunction::RunAsync() {
   scoped_ptr<SignIn::Params> params = SignIn::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
 
@@ -772,7 +772,7 @@
   SendResponse(false);
 
   SigninManagerFactory::GetInstance()->RemoveObserver(this);
-  Release();  // Balanced in RunImpl().
+  Release();  // Balanced in RunAsync().
 }
 
 void WebstorePrivateSignInFunction::SigninSuccess() {
@@ -789,7 +789,7 @@
   }
 
   SigninManagerFactory::GetInstance()->RemoveObserver(this);
-  Release();  // Balanced in RunImpl().
+  Release();  // Balanced in RunAsync().
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.h b/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
index 6c6cd45..d733319 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.h
@@ -63,7 +63,7 @@
   virtual ~WebstorePrivateInstallBundleFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Reads the extension |details| into |items|.
   bool ReadBundleInfo(
@@ -137,7 +137,7 @@
   virtual ~WebstorePrivateBeginInstallWithManifest3Function();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // Sets the result_ as a string based on |code|.
   void SetResultCode(ResultCode code);
@@ -191,7 +191,7 @@
   virtual ~WebstorePrivateCompleteInstallFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   scoped_ptr<WebstoreInstaller::Approval> approval_;
@@ -265,7 +265,7 @@
   void OnFeatureCheck(bool feature_allowed);
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void CreateResult(bool webgl_allowed);
@@ -319,7 +319,7 @@
   virtual ~WebstorePrivateSignInFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   // SigninManagerFactory::Observer:
   virtual void SigninManagerShutdown(SigninManagerBase* manager) OVERRIDE;
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc
index 092fb8e..74ac417 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc
@@ -526,7 +526,7 @@
   ResultCatcher catcher;
   StartSignInTest("sign_in_auth_in_progress_merge_session_fails.html");
   signin_manager_->CompletePendingSignin();
-  token_service_->IssueRefreshToken("token");
+  token_service_->IssueRefreshTokenForUser("user@example.com", "token");
   signin_manager_->NotifyMergeSessionObservers(
       GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
   ASSERT_TRUE(catcher.GetNextResult());
@@ -543,7 +543,7 @@
   ResultCatcher catcher;
   StartSignInTest("sign_in_auth_in_progress_succeeds.html");
   signin_manager_->CompletePendingSignin();
-  token_service_->IssueRefreshToken("token");
+  token_service_->IssueRefreshTokenForUser("user@example.com", "token");
   signin_manager_->NotifyMergeSessionObservers(
       GoogleServiceAuthError::AuthErrorNone());
   ASSERT_TRUE(catcher.GetNextResult());
diff --git a/chrome/browser/extensions/api/webview/webview_api.cc b/chrome/browser/extensions/api/webview/webview_api.cc
index a4be01a..93898f0 100644
--- a/chrome/browser/extensions/api/webview/webview_api.cc
+++ b/chrome/browser/extensions/api/webview/webview_api.cc
@@ -46,7 +46,7 @@
 
 }  // namespace
 
-bool WebviewExtensionFunction::RunImpl() {
+bool WebviewExtensionFunction::RunAsync() {
   int instance_id = 0;
   EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id));
   WebViewGuest* guest = WebViewGuest::From(
@@ -54,12 +54,12 @@
   if (!guest)
     return false;
 
-  return RunImplSafe(guest);
+  return RunAsyncSafe(guest);
 }
 
 // TODO(lazyboy): Add checks similar to
-// WebviewExtensionFunction::RunImplSafe(WebViewGuest*).
-bool WebviewContextMenusCreateFunction::RunImpl() {
+// WebviewExtensionFunction::RunAsyncSafe(WebViewGuest*).
+bool WebviewContextMenusCreateFunction::RunAsync() {
   scoped_ptr<webview::ContextMenusCreate::Params> params(
       webview::ContextMenusCreate::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -89,7 +89,7 @@
   return success;
 }
 
-bool WebviewContextMenusUpdateFunction::RunImpl() {
+bool WebviewContextMenusUpdateFunction::RunAsync() {
   scoped_ptr<webview::ContextMenusUpdate::Params> params(
       webview::ContextMenusUpdate::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -112,7 +112,7 @@
   return success;
 }
 
-bool WebviewContextMenusRemoveFunction::RunImpl() {
+bool WebviewContextMenusRemoveFunction::RunAsync() {
   scoped_ptr<webview::ContextMenusRemove::Params> params(
       webview::ContextMenusRemove::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -148,7 +148,7 @@
   return success;
 }
 
-bool WebviewContextMenusRemoveAllFunction::RunImpl() {
+bool WebviewContextMenusRemoveAllFunction::RunAsync() {
   scoped_ptr<webview::ContextMenusRemoveAll::Params> params(
       webview::ContextMenusRemoveAll::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -196,7 +196,7 @@
 
 // TODO(lazyboy): Parameters in this extension function are similar (or a
 // sub-set) to BrowsingDataRemoverFunction. How can we share this code?
-bool WebviewClearDataFunction::RunImplSafe(WebViewGuest* guest) {
+bool WebviewClearDataFunction::RunAsyncSafe(WebViewGuest* guest) {
   // Grab the initial |options| parameter, and parse out the arguments.
   base::DictionaryValue* options;
   EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &options));
@@ -242,7 +242,7 @@
 }
 
 void WebviewClearDataFunction::ClearDataDone() {
-  Release();  // Balanced in RunImpl().
+  Release();  // Balanced in RunAsync().
   SendResponse(true);
 }
 
@@ -355,7 +355,7 @@
 WebviewSetZoomFunction::~WebviewSetZoomFunction() {
 }
 
-bool WebviewSetZoomFunction::RunImplSafe(WebViewGuest* guest) {
+bool WebviewSetZoomFunction::RunAsyncSafe(WebViewGuest* guest) {
   scoped_ptr<webview::SetZoom::Params> params(
       webview::SetZoom::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -371,7 +371,7 @@
 WebviewGetZoomFunction::~WebviewGetZoomFunction() {
 }
 
-bool WebviewGetZoomFunction::RunImplSafe(WebViewGuest* guest) {
+bool WebviewGetZoomFunction::RunAsyncSafe(WebViewGuest* guest) {
   scoped_ptr<webview::GetZoom::Params> params(
       webview::GetZoom::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -388,7 +388,7 @@
 WebviewFindFunction::~WebviewFindFunction() {
 }
 
-bool WebviewFindFunction::RunImplSafe(WebViewGuest* guest) {
+bool WebviewFindFunction::RunAsyncSafe(WebViewGuest* guest) {
   scoped_ptr<webview::Find::Params> params(
       webview::Find::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -418,7 +418,7 @@
 WebviewStopFindingFunction::~WebviewStopFindingFunction() {
 }
 
-bool WebviewStopFindingFunction::RunImplSafe(WebViewGuest* guest) {
+bool WebviewStopFindingFunction::RunAsyncSafe(WebViewGuest* guest) {
   scoped_ptr<webview::StopFinding::Params> params(
       webview::StopFinding::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -449,7 +449,7 @@
 WebviewGoFunction::~WebviewGoFunction() {
 }
 
-bool WebviewGoFunction::RunImplSafe(WebViewGuest* guest) {
+bool WebviewGoFunction::RunAsyncSafe(WebViewGuest* guest) {
   scoped_ptr<webview::Go::Params> params(webview::Go::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
@@ -463,7 +463,7 @@
 WebviewReloadFunction::~WebviewReloadFunction() {
 }
 
-bool WebviewReloadFunction::RunImplSafe(WebViewGuest* guest) {
+bool WebviewReloadFunction::RunAsyncSafe(WebViewGuest* guest) {
   guest->Reload();
   return true;
 }
@@ -474,7 +474,7 @@
 WebviewSetPermissionFunction::~WebviewSetPermissionFunction() {
 }
 
-bool WebviewSetPermissionFunction::RunImplSafe(WebViewGuest* guest) {
+bool WebviewSetPermissionFunction::RunAsyncSafe(WebViewGuest* guest) {
   scoped_ptr<webview::SetPermission::Params> params(
       webview::SetPermission::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -508,13 +508,32 @@
   return true;
 }
 
+WebviewShowContextMenuFunction::WebviewShowContextMenuFunction() {
+}
+
+WebviewShowContextMenuFunction::~WebviewShowContextMenuFunction() {
+}
+
+bool WebviewShowContextMenuFunction::RunAsyncSafe(WebViewGuest* guest) {
+  scoped_ptr<webview::ShowContextMenu::Params> params(
+      webview::ShowContextMenu::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params.get());
+
+  // TODO(lazyboy): Actually implement filtering menu items, we pass NULL for
+  // now.
+  guest->ShowContextMenu(params->request_id, NULL);
+
+  SendResponse(true);
+  return true;
+}
+
 WebviewOverrideUserAgentFunction::WebviewOverrideUserAgentFunction() {
 }
 
 WebviewOverrideUserAgentFunction::~WebviewOverrideUserAgentFunction() {
 }
 
-bool WebviewOverrideUserAgentFunction::RunImplSafe(WebViewGuest* guest) {
+bool WebviewOverrideUserAgentFunction::RunAsyncSafe(WebViewGuest* guest) {
   scoped_ptr<extensions::api::webview::OverrideUserAgent::Params> params(
       extensions::api::webview::OverrideUserAgent::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
@@ -529,7 +548,7 @@
 WebviewStopFunction::~WebviewStopFunction() {
 }
 
-bool WebviewStopFunction::RunImplSafe(WebViewGuest* guest) {
+bool WebviewStopFunction::RunAsyncSafe(WebViewGuest* guest) {
   guest->Stop();
   return true;
 }
@@ -540,7 +559,7 @@
 WebviewTerminateFunction::~WebviewTerminateFunction() {
 }
 
-bool WebviewTerminateFunction::RunImplSafe(WebViewGuest* guest) {
+bool WebviewTerminateFunction::RunAsyncSafe(WebViewGuest* guest) {
   guest->Terminate();
   return true;
 }
diff --git a/chrome/browser/extensions/api/webview/webview_api.h b/chrome/browser/extensions/api/webview/webview_api.h
index b90eef7..2e23bfd 100644
--- a/chrome/browser/extensions/api/webview/webview_api.h
+++ b/chrome/browser/extensions/api/webview/webview_api.h
@@ -18,7 +18,7 @@
 namespace extensions {
 
 // An abstract base class for async webview APIs. It does a process ID check
-// in RunImpl, and then calls RunImplSafe which must be overriden by all
+// in RunAsync, and then calls RunAsyncSafe which must be overriden by all
 // subclasses.
 class WebviewExtensionFunction : public AsyncExtensionFunction {
  public:
@@ -28,10 +28,10 @@
   virtual ~WebviewExtensionFunction() {}
 
   // ExtensionFunction implementation.
-  virtual bool RunImpl() OVERRIDE FINAL;
+  virtual bool RunAsync() OVERRIDE FINAL;
 
  private:
-  virtual bool RunImplSafe(WebViewGuest* guest) = 0;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) = 0;
 };
 
 class WebviewContextMenusCreateFunction : public AsyncExtensionFunction {
@@ -44,7 +44,7 @@
   virtual ~WebviewContextMenusCreateFunction() {}
 
   // ExtensionFunction implementation.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(WebviewContextMenusCreateFunction);
@@ -60,7 +60,7 @@
   virtual ~WebviewContextMenusUpdateFunction() {}
 
   // ExtensionFunction implementation.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(WebviewContextMenusUpdateFunction);
@@ -76,7 +76,7 @@
   virtual ~WebviewContextMenusRemoveFunction() {}
 
   // ExtensionFunction implementation.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(WebviewContextMenusRemoveFunction);
@@ -92,7 +92,7 @@
   virtual ~WebviewContextMenusRemoveAllFunction() {}
 
   // ExtensionFunction implementation.
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(WebviewContextMenusRemoveAllFunction);
@@ -109,7 +109,7 @@
 
  private:
   // WebviewExtensionFunction implementation.
-  virtual bool RunImplSafe(WebViewGuest* guest) OVERRIDE;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
 
   uint32 GetRemovalMask();
   void ClearDataDone();
@@ -214,7 +214,7 @@
   virtual ~WebviewSetZoomFunction();
 
  private:
-  virtual bool RunImplSafe(WebViewGuest* guest) OVERRIDE;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewSetZoomFunction);
 };
@@ -229,7 +229,7 @@
   virtual ~WebviewGetZoomFunction();
 
  private:
-  virtual bool RunImplSafe(WebViewGuest* guest) OVERRIDE;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewGetZoomFunction);
 };
@@ -248,7 +248,7 @@
 
  private:
   // WebviewExtensionFunction implementation.
-  virtual bool RunImplSafe(WebViewGuest* guest) OVERRIDE;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewFindFunction);
 };
@@ -264,7 +264,7 @@
 
  private:
   // WebviewExtensionFunction implementation.
-  virtual bool RunImplSafe(WebViewGuest* guest) OVERRIDE;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewStopFindingFunction);
 };
@@ -280,7 +280,7 @@
 
  private:
   // WebviewExtensionFunction implementation.
-  virtual bool RunImplSafe(WebViewGuest* guest) OVERRIDE;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewGoFunction);
 };
@@ -296,7 +296,7 @@
 
  private:
   // WebviewExtensionFunction implementation.
-  virtual bool RunImplSafe(WebViewGuest* guest) OVERRIDE;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewReloadFunction);
 };
@@ -312,11 +312,28 @@
 
  private:
   // WebviewExtensionFunction implementation.
-  virtual bool RunImplSafe(WebViewGuest* guest) OVERRIDE;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewSetPermissionFunction);
 };
 
+class WebviewShowContextMenuFunction : public WebviewExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("webview.showContextMenu",
+                             WEBVIEW_SHOWCONTEXTMENU);
+
+  WebviewShowContextMenuFunction();
+
+ protected:
+  virtual ~WebviewShowContextMenuFunction();
+
+ private:
+  // WebviewExtensionFunction implementation.
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
+
+  DISALLOW_COPY_AND_ASSIGN(WebviewShowContextMenuFunction);
+};
+
 class WebviewOverrideUserAgentFunction: public WebviewExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("webview.overrideUserAgent",
@@ -329,7 +346,7 @@
 
  private:
   // WebviewExtensionFunction implementation.
-  virtual bool RunImplSafe(WebViewGuest* guest) OVERRIDE;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewOverrideUserAgentFunction);
 };
@@ -345,7 +362,7 @@
 
  private:
   // WebviewExtensionFunction implementation.
-  virtual bool RunImplSafe(WebViewGuest* guest) OVERRIDE;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewStopFunction);
 };
@@ -361,7 +378,7 @@
 
  private:
   // WebviewExtensionFunction implementation.
-  virtual bool RunImplSafe(WebViewGuest* guest) OVERRIDE;
+  virtual bool RunAsyncSafe(WebViewGuest* guest) OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(WebviewTerminateFunction);
 };
diff --git a/chrome/browser/extensions/app_sync_data_unittest.cc b/chrome/browser/extensions/app_sync_data_unittest.cc
index f81f07c..f75f58e 100644
--- a/chrome/browser/extensions/app_sync_data_unittest.cc
+++ b/chrome/browser/extensions/app_sync_data_unittest.cc
@@ -28,6 +28,7 @@
     extension_specifics->set_version(kValidVersion);
     extension_specifics->set_enabled(false);
     extension_specifics->set_incognito_enabled(true);
+    extension_specifics->set_remote_install(false);
     extension_specifics->set_name(kName);
   }
 };
diff --git a/chrome/browser/extensions/browser_context_keyed_service_factories.cc b/chrome/browser/extensions/browser_context_keyed_service_factories.cc
index c9f3c43..7077f2d 100644
--- a/chrome/browser/extensions/browser_context_keyed_service_factories.cc
+++ b/chrome/browser/extensions/browser_context_keyed_service_factories.cc
@@ -38,7 +38,7 @@
 #include "chrome/browser/extensions/api/preference/preference_api.h"
 #include "chrome/browser/extensions/api/processes/processes_api.h"
 #include "chrome/browser/extensions/api/push_messaging/push_messaging_api.h"
-#include "chrome/browser/extensions/api/runtime/runtime_api.h"
+#include "chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h"
 #include "chrome/browser/extensions/api/serial/serial_connection.h"
 #include "chrome/browser/extensions/api/sessions/sessions_api.h"
 #include "chrome/browser/extensions/api/settings_overrides/settings_overrides_api.h"
@@ -47,7 +47,6 @@
 #include "chrome/browser/extensions/api/system_info/system_info_api.h"
 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h"
 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h"
-#include "chrome/browser/extensions/api/usb/usb_device_resource.h"
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
 #include "chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.h"
@@ -64,12 +63,12 @@
 #include "chrome/browser/extensions/token_cache/token_cache_service_factory.h"
 #include "chrome/browser/speech/extension_api/tts_extension_api.h"
 #include "extensions/browser/api/api_resource_manager.h"
+#include "extensions/browser/api/usb/usb_device_resource.h"
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/extensions/file_manager/file_browser_private_api_factory.h"
 #include "chrome/browser/chromeos/extensions/input_method_api.h"
 #include "chrome/browser/chromeos/extensions/media_player_api.h"
-#include "chrome/browser/chromeos/extensions/screenlock_private_api.h"
 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h"
 #include "chrome/browser/extensions/api/log_private/log_private_api.h"
 #endif
@@ -124,7 +123,6 @@
   extensions::LocationManager::GetFactoryInstance();
 #if defined(OS_CHROMEOS)
   extensions::LogPrivateAPI::GetFactoryInstance();
-  extensions::ScreenlockPrivateEventRouter::GetFactoryInstance();
 #endif
   extensions::ManagementAPI::GetFactoryInstance();
   extensions::MDnsAPI::GetFactoryInstance();
@@ -143,7 +141,7 @@
   extensions::PreferenceAPI::GetFactoryInstance();
   extensions::ProcessesAPI::GetFactoryInstance();
   extensions::PushMessagingAPI::GetFactoryInstance();
-  extensions::RuntimeAPI::GetFactoryInstance();
+  extensions::ScreenlockPrivateEventRouter::GetFactoryInstance();
   extensions::SessionsAPI::GetFactoryInstance();
   extensions::SettingsOverridesAPI::GetFactoryInstance();
   extensions::SignedInDevicesManager::GetFactoryInstance();
diff --git a/chrome/browser/extensions/chrome_extension_function.cc b/chrome/browser/extensions/chrome_extension_function.cc
index 24ccfc4..0f5a503 100644
--- a/chrome/browser/extensions/chrome_extension_function.cc
+++ b/chrome/browser/extensions/chrome_extension_function.cc
@@ -17,13 +17,14 @@
 using content::RenderViewHost;
 using content::WebContents;
 
-ChromeAsyncExtensionFunction::ChromeAsyncExtensionFunction() {}
+ChromeUIThreadExtensionFunction::ChromeUIThreadExtensionFunction() {
+}
 
-Profile* ChromeAsyncExtensionFunction::GetProfile() const {
+Profile* ChromeUIThreadExtensionFunction::GetProfile() const {
   return Profile::FromBrowserContext(context_);
 }
 
-bool ChromeAsyncExtensionFunction::CanOperateOnWindow(
+bool ChromeUIThreadExtensionFunction::CanOperateOnWindow(
     const extensions::WindowController* window_controller) const {
   const extensions::Extension* extension = GetExtension();
   // |extension| is NULL for unit tests only.
@@ -41,7 +42,7 @@
 }
 
 // TODO(stevenjb): Replace this with GetExtensionWindowController().
-Browser* ChromeAsyncExtensionFunction::GetCurrentBrowser() {
+Browser* ChromeUIThreadExtensionFunction::GetCurrentBrowser() {
   // If the delegate has an associated browser, return it.
   if (dispatcher()) {
     extensions::WindowController* window_controller =
@@ -80,7 +81,7 @@
 }
 
 extensions::WindowController*
-ChromeAsyncExtensionFunction::GetExtensionWindowController() {
+ChromeUIThreadExtensionFunction::GetExtensionWindowController() {
   // If the delegate has an associated window controller, return it.
   if (dispatcher()) {
     extensions::WindowController* window_controller =
@@ -93,7 +94,8 @@
       ->CurrentWindowForFunction(this);
 }
 
-content::WebContents* ChromeAsyncExtensionFunction::GetAssociatedWebContents() {
+content::WebContents*
+ChromeUIThreadExtensionFunction::GetAssociatedWebContents() {
   content::WebContents* web_contents =
       UIThreadExtensionFunction::GetAssociatedWebContents();
   if (web_contents)
@@ -105,13 +107,36 @@
   return browser->tab_strip_model()->GetActiveWebContents();
 }
 
+ChromeUIThreadExtensionFunction::~ChromeUIThreadExtensionFunction() {
+}
+
+ChromeAsyncExtensionFunction::ChromeAsyncExtensionFunction() {
+}
+
 ChromeAsyncExtensionFunction::~ChromeAsyncExtensionFunction() {}
 
-ChromeSyncExtensionFunction::ChromeSyncExtensionFunction() {}
+ExtensionFunction::ResponseAction ChromeAsyncExtensionFunction::Run() {
+  return RunAsync() ? RespondLater() : RespondNow(Error(error_));
+}
 
-bool ChromeSyncExtensionFunction::RunImpl() {
-  SendResponse(RunSync());
-  return true;
+// static
+bool ChromeAsyncExtensionFunction::ValidationFailure(
+    ChromeAsyncExtensionFunction* function) {
+  return false;
+}
+
+ChromeSyncExtensionFunction::ChromeSyncExtensionFunction() {
 }
 
 ChromeSyncExtensionFunction::~ChromeSyncExtensionFunction() {}
+
+ExtensionFunction::ResponseAction ChromeSyncExtensionFunction::Run() {
+  return RespondNow(RunSync() ? MultipleArguments(results_.get())
+                              : Error(error_));
+}
+
+// static
+bool ChromeSyncExtensionFunction::ValidationFailure(
+    ChromeSyncExtensionFunction* function) {
+  return false;
+}
diff --git a/chrome/browser/extensions/chrome_extension_function.h b/chrome/browser/extensions/chrome_extension_function.h
index 40fc539..dc35815 100644
--- a/chrome/browser/extensions/chrome_extension_function.h
+++ b/chrome/browser/extensions/chrome_extension_function.h
@@ -18,11 +18,11 @@
 class WindowController;
 }
 
-// A chrome specific analog to AsyncExtensionFunction. This has access
-// the a chrome Profile.
-class ChromeAsyncExtensionFunction : public UIThreadExtensionFunction {
+// A chrome specific analog to AsyncExtensionFunction. This has access to a
+// chrome Profile.
+class ChromeUIThreadExtensionFunction : public UIThreadExtensionFunction {
  public:
-  ChromeAsyncExtensionFunction();
+  ChromeUIThreadExtensionFunction();
 
   Profile* GetProfile() const;
 
@@ -59,21 +59,45 @@
   virtual content::WebContents* GetAssociatedWebContents() OVERRIDE;
 
  protected:
-  virtual ~ChromeAsyncExtensionFunction();
+  virtual ~ChromeUIThreadExtensionFunction();
 };
 
-// A chrome specific analog to SyncExtensionFunction. This has access
-// the a chrome Profile.
-class ChromeSyncExtensionFunction : public ChromeAsyncExtensionFunction {
+// A chrome specific analog to AsyncExtensionFunction. This has access to a
+// chrome Profile.
+class ChromeAsyncExtensionFunction : public ChromeUIThreadExtensionFunction {
+ public:
+  ChromeAsyncExtensionFunction();
+
+ protected:
+  virtual ~ChromeAsyncExtensionFunction();
+
+  // Deprecated, see AsyncExtensionFunction::RunAsync.
+  virtual bool RunAsync() = 0;
+
+  // ValidationFailure override to match RunAsync().
+  static bool ValidationFailure(ChromeAsyncExtensionFunction* function);
+
+ private:
+  virtual ResponseAction Run() OVERRIDE;
+};
+
+// A chrome specific analog to SyncExtensionFunction. This has access to a
+// chrome Profile.
+class ChromeSyncExtensionFunction : public ChromeUIThreadExtensionFunction {
  public:
   ChromeSyncExtensionFunction();
 
-  virtual bool RunImpl() OVERRIDE;
-
-  virtual bool RunSync() = 0;
-
  protected:
   virtual ~ChromeSyncExtensionFunction();
+
+  // Deprecated, see SyncExtensionFunction::RunSync.
+  virtual bool RunSync() = 0;
+
+  // ValidationFailure override to match RunSync().
+  static bool ValidationFailure(ChromeSyncExtensionFunction* function);
+
+ private:
+  virtual ResponseAction Run() OVERRIDE;
 };
 
 #endif  // CHROME_BROWSER_EXTENSIONS_CHROME_EXTENSION_FUNCTION_H_
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc
index cb0868a..fe53a07 100644
--- a/chrome/browser/extensions/chrome_extensions_browser_client.cc
+++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/extensions/activity_log/activity_log.h"
 #include "chrome/browser/extensions/api/preference/chrome_direct_setting.h"
 #include "chrome/browser/extensions/api/preference/preference_api.h"
+#include "chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h"
 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
 #include "chrome/browser/extensions/chrome_app_sorting.h"
 #include "chrome/browser/extensions/chrome_extension_host_delegate.h"
@@ -269,4 +270,11 @@
 #endif
 }
 
+scoped_ptr<extensions::RuntimeAPIDelegate>
+ChromeExtensionsBrowserClient::CreateRuntimeAPIDelegate(
+    content::BrowserContext* context) const {
+  return scoped_ptr<extensions::RuntimeAPIDelegate>(
+      new ChromeRuntimeAPIDelegate(context));
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.h b/chrome/browser/extensions/chrome_extensions_browser_client.h
index c47e851..0c5d160 100644
--- a/chrome/browser/extensions/chrome_extensions_browser_client.h
+++ b/chrome/browser/extensions/chrome_extensions_browser_client.h
@@ -87,6 +87,8 @@
   virtual ExtensionSystemProvider* GetExtensionSystemFactory() OVERRIDE;
   virtual void RegisterExtensionFunctions(
       ExtensionFunctionRegistry* registry) const OVERRIDE;
+  virtual scoped_ptr<extensions::RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
+      content::BrowserContext* context) const OVERRIDE;
 
  private:
   friend struct base::DefaultLazyInstanceTraits<ChromeExtensionsBrowserClient>;
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc
index 3b7647e..65bfaa5 100644
--- a/chrome/browser/extensions/component_loader.cc
+++ b/chrome/browser/extensions/component_loader.cc
@@ -296,11 +296,7 @@
 }
 
 void ComponentLoader::AddGalleryExtension() {
-#if defined(OS_CHROMEOS)
-  const CommandLine* const command_line = CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(chromeos::switches::kFileManagerEnableNewGallery))
-    Add(IDR_GALLERY_MANIFEST, base::FilePath(FILE_PATH_LITERAL("gallery")));
-#endif
+  // TODO(hirono): Disable the new experimental gallery in M36 temporarily.
 }
 
 void ComponentLoader::AddHangoutServicesExtension() {
diff --git a/chrome/browser/extensions/content_verifier_browsertest.cc b/chrome/browser/extensions/content_verifier_browsertest.cc
new file mode 100644
index 0000000..f657c34
--- /dev/null
+++ b/chrome/browser/extensions/content_verifier_browsertest.cc
@@ -0,0 +1,152 @@
+// 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.
+
+#include "base/scoped_observer.h"
+#include "chrome/browser/extensions/extension_browsertest.h"
+#include "content/public/test/test_utils.h"
+#include "extensions/browser/content_verify_job.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_registry_observer.h"
+#include "extensions/common/switches.h"
+
+namespace extensions {
+
+namespace {
+
+// Helper for observing extension unloads.
+class UnloadObserver : public ExtensionRegistryObserver {
+ public:
+  explicit UnloadObserver(ExtensionRegistry* registry) : observer_(this) {
+    observer_.Add(registry);
+  }
+  virtual ~UnloadObserver() {}
+
+  void WaitForUnload(const ExtensionId& id) {
+    if (ContainsKey(observed_, id))
+      return;
+
+    ASSERT_TRUE(loop_runner_.get() == NULL);
+    awaited_id_ = id;
+    loop_runner_ = new content::MessageLoopRunner();
+    loop_runner_->Run();
+  }
+
+  virtual void OnExtensionUnloaded(
+      content::BrowserContext* browser_context,
+      const Extension* extension,
+      UnloadedExtensionInfo::Reason reason) OVERRIDE {
+    observed_.insert(extension->id());
+    if (awaited_id_ == extension->id())
+      loop_runner_->Quit();
+  }
+
+ private:
+  ExtensionId awaited_id_;
+  std::set<ExtensionId> observed_;
+  scoped_refptr<content::MessageLoopRunner> loop_runner_;
+  ScopedObserver<ExtensionRegistry, UnloadObserver> observer_;
+};
+
+// Helper for forcing ContentVerifyJob's to return an error.
+class JobDelegate : public ContentVerifyJob::TestDelegate {
+ public:
+  JobDelegate() : fail_next_read_(false), fail_next_done_(false) {}
+
+  virtual ~JobDelegate() {}
+
+  void set_id(const ExtensionId& id) { id_ = id; }
+  void fail_next_read() { fail_next_read_ = true; }
+  void fail_next_done() { fail_next_done_ = true; }
+
+  virtual ContentVerifyJob::FailureReason BytesRead(const ExtensionId& id,
+                                                    int count,
+                                                    const char* data) OVERRIDE {
+    if (id == id_ && fail_next_read_) {
+      fail_next_read_ = false;
+      return ContentVerifyJob::HASH_MISMATCH;
+    }
+    return ContentVerifyJob::NONE;
+  }
+
+  virtual ContentVerifyJob::FailureReason DoneReading(
+      const ExtensionId& id) OVERRIDE {
+    if (id == id_ && fail_next_done_) {
+      fail_next_done_ = false;
+      return ContentVerifyJob::HASH_MISMATCH;
+    }
+    return ContentVerifyJob::NONE;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(JobDelegate);
+
+  ExtensionId id_;
+  bool fail_next_read_;
+  bool fail_next_done_;
+};
+
+}  // namespace
+
+class ContentVerifierTest : public ExtensionBrowserTest {
+ public:
+  ContentVerifierTest() {}
+  virtual ~ContentVerifierTest() {}
+
+  virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE {
+    ExtensionBrowserTest::SetUpCommandLine(command_line);
+    command_line->AppendSwitchASCII(
+        switches::kExtensionContentVerification,
+        switches::kExtensionContentVerificationEnforce);
+  }
+
+  // Setup our unload observer and JobDelegate, and install a test extension.
+  virtual void SetUpOnMainThread() OVERRIDE {
+    ExtensionBrowserTest::SetUpOnMainThread();
+    unload_observer_.reset(
+        new UnloadObserver(ExtensionRegistry::Get(profile())));
+    const Extension* extension = InstallExtensionFromWebstore(
+        test_data_dir_.AppendASCII("content_verifier/v1.crx"), 1);
+    ASSERT_TRUE(extension);
+    id_ = extension->id();
+    page_url_ = extension->GetResourceURL("page.html");
+    delegate_.set_id(id_);
+    ContentVerifyJob::SetDelegateForTests(&delegate_);
+  }
+
+  virtual void TearDownOnMainThread() OVERRIDE {
+    ContentVerifyJob::SetDelegateForTests(NULL);
+    ExtensionBrowserTest::TearDownOnMainThread();
+  }
+
+  virtual void OpenPageAndWaitForUnload() {
+    AddTabAtIndex(1, page_url_, content::PAGE_TRANSITION_LINK);
+    unload_observer_->WaitForUnload(id_);
+    ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
+    int reasons = prefs->GetDisableReasons(id_);
+    EXPECT_TRUE(reasons & Extension::DISABLE_CORRUPTED);
+
+    // This needs to happen before the ExtensionRegistry gets deleted, which
+    // happens before TearDownOnMainThread is called.
+    unload_observer_.reset();
+  }
+
+ protected:
+  JobDelegate delegate_;
+  scoped_ptr<UnloadObserver> unload_observer_;
+  ExtensionId id_;
+  GURL page_url_;
+};
+
+IN_PROC_BROWSER_TEST_F(ContentVerifierTest, FailOnRead) {
+  delegate_.fail_next_read();
+  OpenPageAndWaitForUnload();
+}
+
+IN_PROC_BROWSER_TEST_F(ContentVerifierTest, FailOnDone) {
+  delegate_.fail_next_done();
+  OpenPageAndWaitForUnload();
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/convert_user_script.cc b/chrome/browser/extensions/convert_user_script.cc
index b67892c..1a7d48f 100644
--- a/chrome/browser/extensions/convert_user_script.cc
+++ b/chrome/browser/extensions/convert_user_script.cc
@@ -39,7 +39,7 @@
     return NULL;
   }
 
-  if (!IsStringUTF8(content)) {
+  if (!base::IsStringUTF8(content)) {
     *error = base::ASCIIToUTF16("User script must be UTF8 encoded.");
     return NULL;
   }
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index f419eab..9a5e4ef 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -491,7 +491,6 @@
         SharedModuleInfo::GetImports(extension());
     std::vector<SharedModuleInfo::ImportInfo>::const_iterator i;
     for (i = imports.begin(); i != imports.end(); ++i) {
-      Version version_required(i->minimum_version);
       const Extension* imported_module =
           service->GetExtensionById(i->extension_id, true);
       if (imported_module &&
@@ -501,6 +500,14 @@
                 IDS_EXTENSION_INSTALL_DEPENDENCY_NOT_SHARED_MODULE,
                 base::ASCIIToUTF16(i->extension_id))));
         return;
+      } else if (imported_module &&
+          !SharedModuleInfo::IsExportAllowedByWhitelist(imported_module,
+                                                        extension()->id())) {
+        ReportFailureFromUIThread(
+            CrxInstallerError(l10n_util::GetStringFUTF16(
+                IDS_EXTENSION_INSTALL_DEPENDENCY_NOT_WHITELISTED,
+                base::ASCIIToUTF16(i->extension_id))));
+        return;
       }
     }
   }
diff --git a/chrome/browser/extensions/dev_mode_bubble_controller.cc b/chrome/browser/extensions/dev_mode_bubble_controller.cc
index cc4448b..db7e36c 100644
--- a/chrome/browser/extensions/dev_mode_bubble_controller.cc
+++ b/chrome/browser/extensions/dev_mode_bubble_controller.cc
@@ -79,7 +79,7 @@
 base::string16 DevModeBubbleDelegate::GetOverflowText(
     const base::string16& overflow_count) const {
   return l10n_util::GetStringFUTF16(
-            IDS_EXTENSIONS_SUSPICIOUS_DISABLED_AND_N_MORE,
+            IDS_EXTENSIONS_DISABLED_AND_N_MORE,
             overflow_count);
 }
 
diff --git a/chrome/browser/extensions/extension_error_reporter.cc b/chrome/browser/extensions/extension_error_reporter.cc
index fbcc5b1..837402b 100644
--- a/chrome/browser/extensions/extension_error_reporter.cc
+++ b/chrome/browser/extensions/extension_error_reporter.cc
@@ -8,10 +8,14 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/simple_message_box.h"
+#include "content/public/browser/notification_service.h"
 
 ExtensionErrorReporter* ExtensionErrorReporter::instance_ = NULL;
 
@@ -35,6 +39,24 @@
 
 ExtensionErrorReporter::~ExtensionErrorReporter() {}
 
+void ExtensionErrorReporter::ReportLoadError(
+    const base::FilePath& extension_path,
+    const std::string& error,
+    Profile* profile,
+    bool be_noisy) {
+  content::NotificationService::current()->Notify(
+      chrome::NOTIFICATION_EXTENSION_LOAD_ERROR,
+      content::Source<Profile>(profile),
+      content::Details<const std::string>(&error));
+
+  std::string path_str = base::UTF16ToUTF8(extension_path.LossyDisplayName());
+  base::string16 message = base::UTF8ToUTF16(
+      base::StringPrintf("Could not load extension from '%s'. %s",
+                         path_str.c_str(),
+                         error.c_str()));
+  ReportError(message, be_noisy);
+}
+
 void ExtensionErrorReporter::ReportError(const base::string16& message,
                                          bool be_noisy) {
   // NOTE: There won't be a ui_loop_ in the unit test environment.
diff --git a/chrome/browser/extensions/extension_error_reporter.h b/chrome/browser/extensions/extension_error_reporter.h
index f5e2d10..ccc1887 100644
--- a/chrome/browser/extensions/extension_error_reporter.h
+++ b/chrome/browser/extensions/extension_error_reporter.h
@@ -12,8 +12,11 @@
 
 namespace base {
 class MessageLoop;
+class FilePath;
 }
 
+class Profile;
+
 // Exposes an easy way for the various components of the extension system to
 // report errors. This is a singleton that lives on the UI thread, with the
 // exception of ReportError() which may be called from any thread.
@@ -31,6 +34,16 @@
   // Get the singleton instance.
   static ExtensionErrorReporter* GetInstance();
 
+  // Report an extension load error. This forwards to ReportError() after
+  // sending an EXTENSION_LOAD_ERROR notification.
+  // TODO(rdevlin.cronin): There's a lot wrong with this. But some of our
+  // systems rely on the notification. Investigate what it will take to remove
+  // the notification and this method.
+  void ReportLoadError(const base::FilePath& extension_path,
+                       const std::string& error,
+                       Profile* profile,
+                       bool be_noisy);
+
   // Report an error. Errors always go to VLOG(1). Optionally, they can also
   // cause a noisy alert box.
   void ReportError(const base::string16& message, bool be_noisy);
diff --git a/chrome/browser/extensions/extension_function_test_utils.cc b/chrome/browser/extensions/extension_function_test_utils.cc
index e7de247..94951ca 100644
--- a/chrome/browser/extensions/extension_function_test_utils.cc
+++ b/chrome/browser/extensions/extension_function_test_utils.cc
@@ -257,9 +257,9 @@
 
   function->set_browser_context(browser->profile());
   function->set_include_incognito(flags & INCLUDE_INCOGNITO);
-  function->Run();
+  function->Run()->Execute();
 
-  // If the RunImpl of |function| didn't already call SendResponse, run the
+  // If the RunAsync of |function| didn't already call SendResponse, run the
   // message loop until they do.
   if (!response_delegate.HasResponse()) {
     response_delegate.set_should_post_quit(true);
diff --git a/chrome/browser/extensions/extension_function_test_utils.h b/chrome/browser/extensions/extension_function_test_utils.h
index 7bd111c..37c7592 100644
--- a/chrome/browser/extensions/extension_function_test_utils.h
+++ b/chrome/browser/extensions/extension_function_test_utils.h
@@ -10,7 +10,6 @@
 #include "base/memory/ref_counted.h"
 #include "extensions/common/manifest.h"
 
-class AsyncExtensionFunction;
 class Browser;
 class UIThreadExtensionFunction;
 
diff --git a/chrome/browser/extensions/extension_garbage_collector.cc b/chrome/browser/extensions/extension_garbage_collector.cc
index df33b09..5419873 100644
--- a/chrome/browser/extensions/extension_garbage_collector.cc
+++ b/chrome/browser/extensions/extension_garbage_collector.cc
@@ -54,7 +54,7 @@
 
   // Parse directory name as a potential extension ID.
   std::string extension_id;
-  if (IsStringASCII(basename.value())) {
+  if (base::IsStringASCII(basename.value())) {
     extension_id = base::UTF16ToASCII(basename.LossyDisplayName());
     if (!Extension::IdIsValid(extension_id))
       extension_id.clear();
diff --git a/chrome/browser/extensions/extension_install_prompt.cc b/chrome/browser/extensions/extension_install_prompt.cc
index 569124f..76f5a37 100644
--- a/chrome/browser/extensions/extension_install_prompt.cc
+++ b/chrome/browser/extensions/extension_install_prompt.cc
@@ -26,7 +26,6 @@
 #include "chrome/common/pref_names.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_icon_set.h"
@@ -187,7 +186,7 @@
   if (!contents)
     return NULL;
 
-  return contents->GetView()->GetTopLevelNativeWindow();
+  return contents->GetTopLevelNativeWindow();
 }
 
 }  // namespace
diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/extension_messages_apitest.cc
index 81257d6..5d219d8 100644
--- a/chrome/browser/extensions/extension_messages_apitest.cc
+++ b/chrome/browser/extensions/extension_messages_apitest.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
-#include "chrome/common/extensions/api/runtime.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
@@ -29,6 +28,7 @@
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_system.h"
+#include "extensions/common/api/runtime.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/value_builder.h"
 #include "net/cert/asn1_util.h"
@@ -1011,38 +1011,6 @@
           "    window.domAutomationController.send('' + response.result);\n"
           "  });\n"
           "});", receiver->id().c_str())));
-
-  // Messges sent from a setTimeout handler should not forward the user gesture
-  // again.
-  EXPECT_EQ(
-      "false",
-      ExecuteScriptInBackgroundPage(
-          sender->id(),
-          base::StringPrintf(
-              "chrome.test.runWithUserGesture(function() {\n"
-              "  window.setTimeout(function() {\n"
-              "    chrome.runtime.sendMessage('%s', {}, function(response)  {\n"
-              "      window.domAutomationController.send('' + "
-              "          response.result);\n"
-              "    });\n"
-              "  }, 0);\n"
-              "});",
-              receiver->id().c_str())));
-
-  // The user gesture should not be send back with the reply message, gestures
-  // are only forwarded once.
-  EXPECT_EQ(
-      "false",
-      ExecuteScriptInBackgroundPage(
-          sender->id(),
-          base::StringPrintf(
-              "chrome.test.runWithUserGesture(function() {\n"
-              "  chrome.runtime.sendMessage('%s', {}, function(response)  {\n"
-              "    window.domAutomationController.send('' + "
-              "        chrome.test.isProcessingUserGesture());\n"
-              "  });\n"
-              "});",
-              receiver->id().c_str())));
 }
 
 // Tests that a hosted app on a connectable site doesn't interfere with the
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 704fade..fd12b35 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -24,7 +24,6 @@
 #include "chrome/browser/extensions/data_deleter.h"
 #include "chrome/browser/extensions/extension_disabled_ui.h"
 #include "chrome/browser/extensions/extension_error_controller.h"
-#include "chrome/browser/extensions/extension_error_reporter.h"
 #include "chrome/browser/extensions/extension_install_ui.h"
 #include "chrome/browser/extensions/extension_special_storage_policy.h"
 #include "chrome/browser/extensions/extension_sync_service.h"
@@ -2063,22 +2062,6 @@
   return true;
 }
 
-void ExtensionService::ReportExtensionLoadError(
-    const base::FilePath& extension_path,
-    const std::string &error) {
-  content::NotificationService::current()->Notify(
-      chrome::NOTIFICATION_EXTENSION_LOAD_ERROR,
-      content::Source<Profile>(profile_),
-      content::Details<const std::string>(&error));
-
-  std::string path_str = base::UTF16ToUTF8(extension_path.LossyDisplayName());
-  base::string16 message = base::UTF8ToUTF16(
-      base::StringPrintf("Could not load extension from '%s'. %s",
-                         path_str.c_str(),
-                         error.c_str()));
-  ExtensionErrorReporter::GetInstance()->ReportError(message, false);
-}
-
 void ExtensionService::DidCreateRenderViewForBackgroundPage(
     extensions::ExtensionHost* host) {
   OrphanedDevTools::iterator iter =
@@ -2412,6 +2395,10 @@
   }
 }
 
+void ExtensionService::ContentVerifyFailed(const std::string& extension_id) {
+  DisableExtension(extension_id, Extension::DISABLE_CORRUPTED);
+}
+
 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) {
   update_observers_.AddObserver(observer);
 }
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 03f18a1..ca80400 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -24,6 +24,7 @@
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
+#include "extensions/browser/content_verifier.h"
 #include "extensions/browser/extension_function_histogram_value.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/external_provider_interface.h"
@@ -126,7 +127,8 @@
     : public ExtensionServiceInterface,
       public extensions::ExternalProviderInterface::VisitorInterface,
       public content::NotificationObserver,
-      public extensions::Blacklist::Observer {
+      public extensions::Blacklist::Observer,
+      public extensions::ContentVerifierObserver {
  public:
   // Attempts to uninstall an extension from a given ExtensionService. Returns
   // true iff the target extension exists.
@@ -471,6 +473,9 @@
     external_updates_finished_callback_ = callback;
   }
 
+  // ContentVerifierObserver implementation.
+  virtual void ContentVerifyFailed(const std::string& extension_id) OVERRIDE;
+
   // Adds/Removes update observers.
   void AddUpdateObserver(extensions::UpdateObserver* observer);
   void RemoveUpdateObserver(extensions::UpdateObserver* observer);
diff --git a/chrome/browser/extensions/extension_sync_data.cc b/chrome/browser/extensions/extension_sync_data.cc
index 016f46e..0ebe72e 100644
--- a/chrome/browser/extensions/extension_sync_data.cc
+++ b/chrome/browser/extensions/extension_sync_data.cc
@@ -18,13 +18,15 @@
 ExtensionSyncData::ExtensionSyncData()
     : uninstalled_(false),
       enabled_(false),
-      incognito_enabled_(false) {
+      incognito_enabled_(false),
+      remote_install_(false) {
 }
 
 ExtensionSyncData::ExtensionSyncData(const syncer::SyncData& sync_data)
     : uninstalled_(false),
       enabled_(false),
-      incognito_enabled_(false) {
+      incognito_enabled_(false),
+      remote_install_(false) {
   PopulateFromSyncData(sync_data);
 }
 
@@ -32,7 +34,8 @@
     : uninstalled_(
         sync_change.change_type() == syncer::SyncChange::ACTION_DELETE),
       enabled_(false),
-      incognito_enabled_(false) {
+      incognito_enabled_(false),
+      remote_install_(false) {
   PopulateFromSyncData(sync_change.sync_data());
 }
 
@@ -43,6 +46,7 @@
       uninstalled_(false),
       enabled_(enabled),
       incognito_enabled_(incognito_enabled),
+      remote_install_(false),
       version_(extension.from_bookmark() ? base::Version("0")
                                          : *extension.version()),
       update_url_(ManifestURL::GetUpdateURL(&extension)),
@@ -71,6 +75,7 @@
   specifics->set_version(version_.GetString());
   specifics->set_enabled(enabled_);
   specifics->set_incognito_enabled(incognito_enabled_);
+  specifics->set_remote_install(remote_install_);
   specifics->set_name(name_);
 }
 
@@ -95,6 +100,7 @@
   version_ = specifics_version;
   enabled_ = specifics.enabled();
   incognito_enabled_ = specifics.incognito_enabled();
+  remote_install_ = specifics.remote_install();
   name_ = specifics.name();
 }
 
diff --git a/chrome/browser/extensions/extension_sync_data.h b/chrome/browser/extensions/extension_sync_data.h
index 8fbe73a..04c4b18 100644
--- a/chrome/browser/extensions/extension_sync_data.h
+++ b/chrome/browser/extensions/extension_sync_data.h
@@ -72,6 +72,7 @@
   bool uninstalled_;
   bool enabled_;
   bool incognito_enabled_;
+  bool remote_install_;
   Version version_;
   GURL update_url_;
   std::string name_;
diff --git a/chrome/browser/extensions/extension_system_impl.cc b/chrome/browser/extensions/extension_system_impl.cc
index 2e4d293..924890a 100644
--- a/chrome/browser/extensions/extension_system_impl.cc
+++ b/chrome/browser/extensions/extension_system_impl.cc
@@ -32,8 +32,10 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/extensions/features/feature_channel.h"
+#include "chrome/common/extensions/manifest_url_handler.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/url_data_source.h"
+#include "extensions/browser/content_verifier.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_pref_store.h"
 #include "extensions/browser/extension_pref_value_map.h"
@@ -137,6 +139,12 @@
 #endif  // defined(ENABLE_EXTENSIONS)
 }
 
+static bool ShouldVerifyExtensionContent(const Extension* extension) {
+  return ((extension->is_extension() || extension->is_legacy_packaged_app()) &&
+          ManifestURL::UpdatesFromGallery(extension) &&
+          Manifest::IsAutoUpdateableLocation(extension->location()));
+}
+
 void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) {
   const CommandLine* command_line = CommandLine::ForCurrentProcess();
 
@@ -171,6 +179,11 @@
     install_verifier_.reset(
         new InstallVerifier(ExtensionPrefs::Get(profile_), profile_));
     install_verifier_->Init();
+    ContentVerifierFilter filter = base::Bind(&ShouldVerifyExtensionContent);
+    content_verifier_ = new ContentVerifier(profile_, filter);
+    content_verifier_->AddObserver(extension_service_.get());
+    content_verifier_->Start();
+    info_map()->SetContentVerifier(content_verifier_.get());
 
     management_policy_.reset(new ManagementPolicy);
     RegisterManagementPolicyProviders();
@@ -243,6 +256,12 @@
     extension_warning_service_->RemoveObserver(
         extension_warning_badge_service_.get());
   }
+  if (content_verifier_) {
+    if (extension_service_)
+      content_verifier_->RemoveObserver(extension_service_.get());
+    content_verifier_->Shutdown();
+  }
+
   if (extension_service_)
     extension_service_->Shutdown();
 }
@@ -306,6 +325,10 @@
   return quota_service_.get();
 }
 
+ContentVerifier* ExtensionSystemImpl::Shared::content_verifier() {
+  return content_verifier_.get();
+}
+
 //
 // ExtensionSystemImpl
 //
@@ -403,6 +426,10 @@
   return shared_->quota_service();
 }
 
+ContentVerifier* ExtensionSystemImpl::content_verifier() {
+  return shared_->content_verifier();
+}
+
 void ExtensionSystemImpl::RegisterExtensionWithRequestContexts(
     const Extension* extension) {
   base::Time install_time;
diff --git a/chrome/browser/extensions/extension_system_impl.h b/chrome/browser/extensions/extension_system_impl.h
index 90c8c82..8d5b1d6 100644
--- a/chrome/browser/extensions/extension_system_impl.h
+++ b/chrome/browser/extensions/extension_system_impl.h
@@ -12,6 +12,7 @@
 
 namespace extensions {
 
+class ContentVerifier;
 class ExtensionSystemSharedFactory;
 class ExtensionWarningBadgeService;
 class NavigationObserver;
@@ -57,6 +58,7 @@
       const UnloadedExtensionInfo::Reason reason) OVERRIDE;
 
   virtual const OneShotEvent& ready() const OVERRIDE;
+  virtual ContentVerifier* content_verifier() OVERRIDE;  // shared
 
  private:
   friend class ExtensionSystemSharedFactory;
@@ -92,6 +94,7 @@
     InstallVerifier* install_verifier();
     QuotaService* quota_service();
     const OneShotEvent& ready() const { return ready_; }
+    ContentVerifier* content_verifier();
 
    private:
     Profile* profile_;
@@ -122,6 +125,9 @@
     scoped_ptr<InstallVerifier> install_verifier_;
     scoped_ptr<QuotaService> quota_service_;
 
+    // For verifying the contents of extensions read from disk.
+    scoped_refptr<ContentVerifier> content_verifier_;
+
 #if defined(OS_CHROMEOS)
     scoped_ptr<chromeos::DeviceLocalAccountManagementPolicyProvider>
         device_local_account_management_policy_provider_;
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc
index be7f4c9..1cde659 100644
--- a/chrome/browser/extensions/extension_tab_util.cc
+++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -6,7 +6,9 @@
 
 #include "apps/app_window.h"
 #include "apps/app_window_registry.h"
+#include "base/strings/string_number_conversions.h"
 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
+#include "chrome/browser/extensions/chrome_extension_function.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/extensions/window_controller.h"
 #include "chrome/browser/extensions/window_controller_list.h"
@@ -25,9 +27,11 @@
 #include "content/public/browser/favicon_status.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/error_utils.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/manifest_constants.h"
+#include "extensions/common/manifest_handlers/incognito_info.h"
 #include "extensions/common/permissions/api_permission.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "url/gurl.h"
@@ -55,8 +59,220 @@
       app_window->session_id().id());
 }
 
+// |error_message| can optionally be passed in and will be set with an
+// appropriate message if the window cannot be found by id.
+Browser* GetBrowserInProfileWithId(Profile* profile,
+                                   const int window_id,
+                                   bool include_incognito,
+                                   std::string* error_message) {
+  Profile* incognito_profile =
+      include_incognito && profile->HasOffTheRecordProfile()
+          ? profile->GetOffTheRecordProfile()
+          : NULL;
+  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
+    Browser* browser = *it;
+    if ((browser->profile() == profile ||
+         browser->profile() == incognito_profile) &&
+        ExtensionTabUtil::GetWindowId(browser) == window_id &&
+        browser->window()) {
+      return browser;
+    }
+  }
+
+  if (error_message)
+    *error_message = ErrorUtils::FormatErrorMessage(
+        keys::kWindowNotFoundError, base::IntToString(window_id));
+
+  return NULL;
+}
+
+Browser* CreateBrowser(ChromeUIThreadExtensionFunction* function,
+                       int window_id,
+                       std::string* error) {
+  content::WebContents* web_contents = function->GetAssociatedWebContents();
+  DCHECK(web_contents);
+  DCHECK(web_contents->GetNativeView());
+  DCHECK(!chrome::FindBrowserWithWebContents(web_contents));
+
+  chrome::HostDesktopType desktop_type =
+      chrome::GetHostDesktopTypeForNativeView(web_contents->GetNativeView());
+  Browser::CreateParams params(
+      Browser::TYPE_TABBED, function->GetProfile(), desktop_type);
+  Browser* browser = new Browser(params);
+  browser->window()->Show();
+  return browser;
+}
+
 }  // namespace
 
+ExtensionTabUtil::OpenTabParams::OpenTabParams()
+    : create_browser_if_needed(false) {
+}
+
+ExtensionTabUtil::OpenTabParams::~OpenTabParams() {
+}
+
+// Opens a new tab for a given extension. Returns NULL and sets |error| if an
+// error occurs.
+base::DictionaryValue* ExtensionTabUtil::OpenTab(
+    ChromeUIThreadExtensionFunction* function,
+    const OpenTabParams& params,
+    std::string* error) {
+  // windowId defaults to "current" window.
+  int window_id = extension_misc::kCurrentWindowId;
+  if (params.window_id.get())
+    window_id = *params.window_id;
+
+  Browser* browser = GetBrowserFromWindowID(function, window_id, error);
+  if (!browser) {
+    if (!params.create_browser_if_needed) {
+      return NULL;
+    }
+    browser = CreateBrowser(function, window_id, error);
+    if (!browser)
+      return NULL;
+  }
+
+  // Ensure the selected browser is tabbed.
+  if (!browser->is_type_tabbed() && browser->IsAttemptingToCloseBrowser())
+    browser = chrome::FindTabbedBrowser(function->GetProfile(),
+                                        function->include_incognito(),
+                                        browser->host_desktop_type());
+
+  if (!browser || !browser->window()) {
+    // TODO(rpaquay): Error message?
+    return NULL;
+  }
+
+  // TODO(jstritar): Add a constant, chrome.tabs.TAB_ID_ACTIVE, that
+  // represents the active tab.
+  WebContents* opener = NULL;
+  if (params.opener_tab_id.get()) {
+    int opener_id = *params.opener_tab_id;
+
+    if (!ExtensionTabUtil::GetTabById(opener_id,
+                                      function->GetProfile(),
+                                      function->include_incognito(),
+                                      NULL,
+                                      NULL,
+                                      &opener,
+                                      NULL)) {
+      // TODO(rpaquay): Error message?
+      return NULL;
+    }
+  }
+
+  // TODO(rafaelw): handle setting remaining tab properties:
+  // -title
+  // -favIconUrl
+
+  std::string url_string;
+  GURL url;
+  if (params.url.get()) {
+    url_string = *params.url;
+    url = ExtensionTabUtil::ResolvePossiblyRelativeURL(
+        url_string, function->GetExtension());
+    if (!url.is_valid()) {
+      *error =
+          ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, url_string);
+      return NULL;
+    }
+  }
+
+  // Don't let extensions crash the browser or renderers.
+  if (ExtensionTabUtil::IsCrashURL(url)) {
+    *error = keys::kNoCrashBrowserError;
+    return NULL;
+  }
+
+  // Default to foreground for the new tab. The presence of 'active' property
+  // will override this default.
+  bool active = true;
+  if (params.active.get())
+    active = *params.active;
+
+  // Default to not pinning the tab. Setting the 'pinned' property to true
+  // will override this default.
+  bool pinned = false;
+  if (params.pinned.get())
+    pinned = *params.pinned;
+
+  // We can't load extension URLs into incognito windows unless the extension
+  // uses split mode. Special case to fall back to a tabbed window.
+  if (url.SchemeIs(kExtensionScheme) &&
+      !IncognitoInfo::IsSplitMode(function->GetExtension()) &&
+      browser->profile()->IsOffTheRecord()) {
+    Profile* profile = browser->profile()->GetOriginalProfile();
+    chrome::HostDesktopType desktop_type = browser->host_desktop_type();
+
+    browser = chrome::FindTabbedBrowser(profile, false, desktop_type);
+    if (!browser) {
+      browser = new Browser(
+          Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type));
+      browser->window()->Show();
+    }
+  }
+
+  // If index is specified, honor the value, but keep it bound to
+  // -1 <= index <= tab_strip->count() where -1 invokes the default behavior.
+  int index = -1;
+  if (params.index.get())
+    index = *params.index;
+
+  TabStripModel* tab_strip = browser->tab_strip_model();
+
+  index = std::min(std::max(index, -1), tab_strip->count());
+
+  int add_types = active ? TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE;
+  add_types |= TabStripModel::ADD_FORCE_INDEX;
+  if (pinned)
+    add_types |= TabStripModel::ADD_PINNED;
+  chrome::NavigateParams navigate_params(
+      browser, url, content::PAGE_TRANSITION_LINK);
+  navigate_params.disposition =
+      active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
+  navigate_params.tabstrip_index = index;
+  navigate_params.tabstrip_add_types = add_types;
+  chrome::Navigate(&navigate_params);
+
+  // The tab may have been created in a different window, so make sure we look
+  // at the right tab strip.
+  tab_strip = navigate_params.browser->tab_strip_model();
+  int new_index =
+      tab_strip->GetIndexOfWebContents(navigate_params.target_contents);
+  if (opener)
+    tab_strip->SetOpenerOfWebContentsAt(new_index, opener);
+
+  if (active)
+    navigate_params.target_contents->SetInitialFocus();
+
+  // Return data about the newly created tab.
+  return ExtensionTabUtil::CreateTabValue(navigate_params.target_contents,
+                                          tab_strip,
+                                          new_index,
+                                          function->GetExtension());
+}
+
+Browser* ExtensionTabUtil::GetBrowserFromWindowID(
+    ChromeUIThreadExtensionFunction* function,
+    int window_id,
+    std::string* error) {
+  if (window_id == extension_misc::kCurrentWindowId) {
+    Browser* result = function->GetCurrentBrowser();
+    if (!result || !result->window()) {
+      if (error)
+        *error = keys::kNoCurrentWindowError;
+      return NULL;
+    }
+    return result;
+  } else {
+    return GetBrowserInProfileWithId(function->GetProfile(),
+                                     window_id,
+                                     function->include_incognito(),
+                                     error);
+  }
+}
+
 int ExtensionTabUtil::GetWindowId(const Browser* browser) {
   return browser->session_id().id();
 }
@@ -70,7 +286,7 @@
   return -1;
 }
 
-int ExtensionTabUtil::GetTabId(const WebContents* web_contents) {
+int ExtensionTabUtil::GetTabId(WebContents* web_contents) {
   return SessionID::IdForTab(web_contents);
 }
 
@@ -83,7 +299,7 @@
 }
 
 base::DictionaryValue* ExtensionTabUtil::CreateTabValue(
-    const WebContents* contents,
+    WebContents* contents,
     TabStripModel* tab_strip,
     int tab_index,
     const Extension* extension) {
@@ -116,7 +332,7 @@
 }
 
 base::DictionaryValue* ExtensionTabUtil::CreateTabValue(
-    const WebContents* contents,
+    WebContents* contents,
     TabStripModel* tab_strip,
     int tab_index) {
   // If we have a matching AppWindow with a controller, get the tab value
@@ -145,9 +361,9 @@
   result->SetBoolean(keys::kIncognitoKey,
                      contents->GetBrowserContext()->IsOffTheRecord());
   result->SetInteger(keys::kWidthKey,
-                     contents->GetView()->GetContainerSize().width());
+                     contents->GetContainerBounds().size().width());
   result->SetInteger(keys::kHeightKey,
-                     contents->GetView()->GetContainerSize().height());
+                     contents->GetContainerBounds().size().height());
 
   // Privacy-sensitive fields: these should be stripped off by
   // ScrubTabValueForExtension if the extension should not see them.
@@ -169,7 +385,7 @@
 }
 
 void ExtensionTabUtil::ScrubTabValueForExtension(
-    const WebContents* contents,
+    WebContents* contents,
     const Extension* extension,
     base::DictionaryValue* tab_info) {
   bool has_permission =
diff --git a/chrome/browser/extensions/extension_tab_util.h b/chrome/browser/extensions/extension_tab_util.h
index 0b3092a..c7e201f 100644
--- a/chrome/browser/extensions/extension_tab_util.h
+++ b/chrome/browser/extensions/extension_tab_util.h
@@ -12,6 +12,7 @@
 #include "ui/base/window_open_disposition.h"
 
 class Browser;
+class ChromeUIThreadExtensionFunction;
 class GURL;
 class Profile;
 class TabStripModel;
@@ -36,25 +37,50 @@
 // Provides various utility functions that help manipulate tabs.
 class ExtensionTabUtil {
  public:
+  struct OpenTabParams {
+    OpenTabParams();
+    ~OpenTabParams();
+
+    bool create_browser_if_needed;
+    scoped_ptr<int> window_id;
+    scoped_ptr<int> opener_tab_id;
+    scoped_ptr<std::string> url;
+    scoped_ptr<bool> active;
+    scoped_ptr<bool> pinned;
+    scoped_ptr<int> index;
+  };
+
+  // Opens a new tab given an extension function |function| and creation
+  // parameters |params|. Returns a Tab object if successful, or NULL and
+  // optionally sets |error| if an error occurs.
+  static base::DictionaryValue* OpenTab(
+      ChromeUIThreadExtensionFunction* function,
+      const OpenTabParams& params,
+      std::string* error);
+
   static int GetWindowId(const Browser* browser);
   static int GetWindowIdOfTabStripModel(const TabStripModel* tab_strip_model);
-  static int GetTabId(const content::WebContents* web_contents);
+  static int GetTabId(content::WebContents* web_contents);
   static std::string GetTabStatusText(bool is_loading);
   static int GetWindowIdOfTab(const content::WebContents* web_contents);
   static base::ListValue* CreateTabList(const Browser* browser,
                                         const Extension* extension);
+  static Browser* GetBrowserFromWindowID(
+      ChromeUIThreadExtensionFunction* function,
+      int window_id,
+      std::string* error_message);
 
   // Creates a Tab object (see chrome/common/extensions/api/tabs.json) with
   // information about the state of a browser tab.  Depending on the
   // permissions of the extension, the object may or may not include sensitive
   // data such as the tab's URL.
   static base::DictionaryValue* CreateTabValue(
-      const content::WebContents* web_contents,
+      content::WebContents* web_contents,
       const Extension* extension) {
     return CreateTabValue(web_contents, NULL, -1, extension);
   }
   static base::DictionaryValue* CreateTabValue(
-      const content::WebContents* web_contents,
+      content::WebContents* web_contents,
       TabStripModel* tab_strip,
       int tab_index,
       const Extension* extension);
@@ -62,18 +88,18 @@
   // Creates a Tab object but performs no extension permissions checks; the
   // returned object will contain privacy-sensitive data.
   static base::DictionaryValue* CreateTabValue(
-      const content::WebContents* web_contents) {
+      content::WebContents* web_contents) {
     return CreateTabValue(web_contents, NULL, -1);
   }
   static base::DictionaryValue* CreateTabValue(
-      const content::WebContents* web_contents,
+      content::WebContents* web_contents,
       TabStripModel* tab_strip,
       int tab_index);
 
   // Removes any privacy-sensitive fields from a Tab object if appropriate,
   // given the permissions of the extension and the tab in question.  The
   // tab_info object is modified in place.
-  static void ScrubTabValueForExtension(const content::WebContents* contents,
+  static void ScrubTabValueForExtension(content::WebContents* contents,
                                         const Extension* extension,
                                         base::DictionaryValue* tab_info);
 
diff --git a/chrome/browser/extensions/extension_tab_util_android.cc b/chrome/browser/extensions/extension_tab_util_android.cc
index da7be3f..9d0abe8 100644
--- a/chrome/browser/extensions/extension_tab_util_android.cc
+++ b/chrome/browser/extensions/extension_tab_util_android.cc
@@ -26,7 +26,7 @@
 }
 
 // static
-int ExtensionTabUtil::GetTabId(const WebContents* web_contents) {
+int ExtensionTabUtil::GetTabId(WebContents* web_contents) {
   return SessionID::IdForTab(web_contents);
 }
 
@@ -38,7 +38,7 @@
 
 // static
 base::DictionaryValue* ExtensionTabUtil::CreateTabValue(
-    const WebContents* contents,
+    WebContents* contents,
     TabStripModel* tab_strip,
     int tab_index,
     const Extension* extension) {
@@ -55,7 +55,7 @@
 
 // static
 base::DictionaryValue* ExtensionTabUtil::CreateTabValue(
-    const WebContents* contents,
+    WebContents* contents,
     TabStripModel* tab_strip,
     int tab_index) {
   NOTIMPLEMENTED();
diff --git a/chrome/browser/extensions/extension_toolbar_model.cc b/chrome/browser/extensions/extension_toolbar_model.cc
index 90c065a..7c9d5bf 100644
--- a/chrome/browser/extensions/extension_toolbar_model.cc
+++ b/chrome/browser/extensions/extension_toolbar_model.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
-#include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
 #include "chrome/browser/extensions/extension_toolbar_model_factory.h"
 #include "chrome/browser/extensions/extension_util.h"
@@ -32,17 +31,17 @@
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_set.h"
 #include "extensions/common/feature_switch.h"
+#include "extensions/common/one_shot_event.h"
 
 namespace extensions {
 
 bool ExtensionToolbarModel::Observer::BrowserActionShowPopup(
-    const extensions::Extension* extension) {
+    const Extension* extension) {
   return false;
 }
 
-ExtensionToolbarModel::ExtensionToolbarModel(
-    Profile* profile,
-    extensions::ExtensionPrefs* extension_prefs)
+ExtensionToolbarModel::ExtensionToolbarModel(Profile* profile,
+                                             ExtensionPrefs* extension_prefs)
     : profile_(profile),
       extension_prefs_(extension_prefs),
       prefs_(profile_->GetPrefs()),
@@ -50,24 +49,16 @@
       is_highlighting_(false),
       extension_registry_observer_(this),
       weak_ptr_factory_(this) {
-  extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
-
-  registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
-                 content::Source<Profile>(profile_));
-  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
-                 content::Source<Profile>(profile_));
-  registrar_.Add(
-      this, chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
-      content::Source<extensions::ExtensionPrefs>(extension_prefs_));
-
-  visible_icon_count_ = prefs_->GetInteger(
-      extensions::pref_names::kToolbarSize);
+  ExtensionSystem::Get(profile_)->ready().Post(
+      FROM_HERE,
+      base::Bind(&ExtensionToolbarModel::OnReady,
+                 weak_ptr_factory_.GetWeakPtr()));
+  visible_icon_count_ = prefs_->GetInteger(pref_names::kToolbarSize);
   pref_change_registrar_.Init(prefs_);
   pref_change_callback_ =
       base::Bind(&ExtensionToolbarModel::OnExtensionToolbarPrefChange,
                  base::Unretained(this));
-  pref_change_registrar_.Add(extensions::pref_names::kToolbar,
-                             pref_change_callback_);
+  pref_change_registrar_.Add(pref_names::kToolbar, pref_change_callback_);
 }
 
 ExtensionToolbarModel::~ExtensionToolbarModel() {
@@ -138,22 +129,21 @@
     bool should_grant) {
   content::WebContents* web_contents = NULL;
   int tab_id = 0;
-  if (!extensions::ExtensionTabUtil::GetDefaultTab(
-          browser, &web_contents, &tab_id)) {
+  if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, &tab_id)) {
     return ACTION_NONE;
   }
 
   ExtensionAction* browser_action =
-      extensions::ExtensionActionManager::Get(profile_)->
-      GetBrowserAction(*extension);
+      ExtensionActionManager::Get(profile_)->GetBrowserAction(*extension);
 
   // For browser actions, visibility == enabledness.
   if (!browser_action->GetIsVisible(tab_id))
     return ACTION_NONE;
 
   if (should_grant) {
-    extensions::TabHelper::FromWebContents(web_contents)->
-        active_tab_permission_granter()->GrantIfRequested(extension);
+    TabHelper::FromWebContents(web_contents)
+        ->active_tab_permission_granter()
+        ->GrantIfRequested(extension);
   }
 
   if (browser_action->HasPopup(tab_id)) {
@@ -162,7 +152,7 @@
     return ACTION_SHOW_POPUP;
   }
 
-  extensions::ExtensionActionAPI::BrowserActionExecuted(
+  ExtensionActionAPI::BrowserActionExecuted(
       browser->profile(), *browser_action, web_contents);
   return ACTION_NONE;
 }
@@ -174,8 +164,7 @@
   // designed to be a transitory state, and should not persist across browser
   // restarts (though it may be re-entered).
   if (!is_highlighting_) {
-    prefs_->SetInteger(extensions::pref_names::kToolbarSize,
-                       visible_icon_count_);
+    prefs_->SetInteger(pref_names::kToolbarSize, visible_icon_count_);
   }
 }
 
@@ -206,16 +195,7 @@
     int type,
     const content::NotificationSource& source,
     const content::NotificationDetails& details) {
-  ExtensionService* extension_service =
-      ExtensionSystem::Get(profile_)->extension_service();
-  DCHECK(extension_service);
-  if (!extension_service->is_ready())
-    return;
-
   switch (type) {
-    case chrome::NOTIFICATION_EXTENSIONS_READY:
-      InitializeExtensionList(extension_service);
-      break;
     case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
       const Extension* extension =
           content::Details<const Extension>(details).ptr();
@@ -223,8 +203,10 @@
       break;
     }
     case chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED: {
-      const Extension* extension = extension_service->GetExtensionById(
-          *content::Details<const std::string>(details).ptr(), true);
+      const Extension* extension =
+          ExtensionRegistry::Get(profile_)->GetExtensionById(
+              *content::Details<const std::string>(details).ptr(),
+              ExtensionRegistry::EVERYTHING);
       if (ExtensionActionAPI::GetBrowserActionVisibility(extension_prefs_,
                                                          extension->id())) {
         AddExtension(extension);
@@ -238,6 +220,22 @@
   }
 }
 
+void ExtensionToolbarModel::OnReady() {
+  ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
+  InitializeExtensionList(registry->enabled_extensions());
+  // Wait until the extension system is ready before observing any further
+  // changes so that the toolbar buttons can be shown in their stable ordering
+  // taken from prefs.
+  extension_registry_observer_.Add(registry);
+  registrar_.Add(this,
+                 chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
+                 content::Source<Profile>(profile_));
+  registrar_.Add(
+      this,
+      chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
+      content::Source<ExtensionPrefs>(extension_prefs_));
+}
+
 size_t ExtensionToolbarModel::FindNewPositionFromLastKnownGood(
     const Extension* extension) {
   // See if we have last known good position for this extension.
@@ -341,25 +339,23 @@
 }
 
 // Combine the currently enabled extensions that have browser actions (which
-// we get from the ExtensionService) with the ordering we get from the
+// we get from the ExtensionRegistry) with the ordering we get from the
 // pref service. For robustness we use a somewhat inefficient process:
 // 1. Create a vector of extensions sorted by their pref values. This vector may
 // have holes.
 // 2. Create a vector of extensions that did not have a pref value.
 // 3. Remove holes from the sorted vector and append the unsorted vector.
-void ExtensionToolbarModel::InitializeExtensionList(ExtensionService* service) {
-  DCHECK(service->is_ready());
-
+void ExtensionToolbarModel::InitializeExtensionList(
+    const ExtensionSet& extensions) {
   last_known_positions_ = extension_prefs_->GetToolbarOrder();
-  Populate(last_known_positions_, service);
+  Populate(last_known_positions_, extensions);
 
   extensions_initialized_ = true;
   FOR_EACH_OBSERVER(Observer, observers_, VisibleCountChanged());
 }
 
-void ExtensionToolbarModel::Populate(
-    const ExtensionIdList& positions,
-    ExtensionService* service) {
+void ExtensionToolbarModel::Populate(const ExtensionIdList& positions,
+                                     const ExtensionSet& extensions) {
   // Items that have explicit positions.
   ExtensionList sorted;
   sorted.resize(positions.size(), NULL);
@@ -371,9 +367,9 @@
 
   // Create the lists.
   int hidden = 0;
-  for (extensions::ExtensionSet::const_iterator it =
-           service->extensions()->begin();
-       it != service->extensions()->end(); ++it) {
+  for (ExtensionSet::const_iterator it = extensions.begin();
+       it != extensions.end();
+       ++it) {
     const Extension* extension = it->get();
     if (!extension_action_manager->GetBrowserAction(*extension))
       continue;
@@ -492,7 +488,7 @@
 
   // Re-populate.
   Populate(last_known_positions_,
-           ExtensionSystem::Get(profile_)->extension_service());
+           ExtensionRegistry::Get(profile_)->enabled_extensions());
 
   if (last_known_positions_.size() > pref_position_size) {
     // Need to update pref because we have extra icons. But can't call
diff --git a/chrome/browser/extensions/extension_toolbar_model.h b/chrome/browser/extensions/extension_toolbar_model.h
index ba78a37..df57107 100644
--- a/chrome/browser/extensions/extension_toolbar_model.h
+++ b/chrome/browser/extensions/extension_toolbar_model.h
@@ -17,12 +17,12 @@
 #include "extensions/common/extension.h"
 
 class Browser;
-class ExtensionService;
 class PrefService;
 class Profile;
 
 namespace extensions {
 class ExtensionRegistry;
+class ExtensionSet;
 
 // Model for the browser actions toolbar.
 class ExtensionToolbarModel : public content::NotificationObserver,
@@ -141,6 +141,9 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
+  // Callback when extensions are ready.
+  void OnReady();
+
   // ExtensionRegistryObserver implementation.
   virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
                                  const Extension* extension) OVERRIDE;
@@ -152,12 +155,9 @@
   // To be called after the extension service is ready; gets loaded extensions
   // from the extension service and their saved order from the pref service
   // and constructs |toolbar_items_| from these data.
-  void InitializeExtensionList(ExtensionService* service);
-  void Populate(const ExtensionIdList& positions, ExtensionService* service);
-
-  // Fills |list| with extensions based on provided |order|.
-  void FillExtensionList(const ExtensionIdList& order,
-                         ExtensionService* service);
+  void InitializeExtensionList(const ExtensionSet& extensions);
+  void Populate(const ExtensionIdList& positions,
+                const ExtensionSet& extensions);
 
   // Save the model to prefs.
   void UpdatePrefs();
diff --git a/chrome/browser/extensions/extension_view_host.cc b/chrome/browser/extensions/extension_view_host.cc
index 3bdad60..12afacc 100644
--- a/chrome/browser/extensions/extension_view_host.cc
+++ b/chrome/browser/extensions/extension_view_host.cc
@@ -15,7 +15,6 @@
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/runtime_data.h"
 #include "extensions/common/extension_messages.h"
@@ -43,7 +42,7 @@
   virtual ~AssociatedWebContentsObserver() {}
 
   // content::WebContentsObserver:
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     // Deleting |this| from here is safe.
     host_->SetAssociatedWebContents(NULL);
   }
@@ -276,7 +275,7 @@
 }
 
 bool ExtensionViewHost::IsWebContentsVisible(WebContents* web_contents) {
-  return platform_util::IsVisible(web_contents->GetView()->GetNativeView());
+  return platform_util::IsVisible(web_contents->GetNativeView());
 }
 
 gfx::NativeView ExtensionViewHost::GetHostView() const {
@@ -286,7 +285,7 @@
 gfx::Point ExtensionViewHost::GetDialogPosition(const gfx::Size& size) {
   if (!GetVisibleWebContents())
     return gfx::Point();
-  gfx::Rect bounds = GetVisibleWebContents()->GetView()->GetViewBounds();
+  gfx::Rect bounds = GetVisibleWebContents()->GetViewBounds();
   return gfx::Point(
       std::max(0, (bounds.width() - size.width()) / 2),
       std::max(0, (bounds.height() - size.height()) / 2));
@@ -295,7 +294,7 @@
 gfx::Size ExtensionViewHost::GetMaximumDialogSize() {
   if (!GetVisibleWebContents())
     return gfx::Size();
-  return GetVisibleWebContents()->GetView()->GetViewBounds().size();
+  return GetVisibleWebContents()->GetViewBounds().size();
 }
 
 void ExtensionViewHost::AddObserver(
diff --git a/chrome/browser/extensions/external_install_ui.cc b/chrome/browser/extensions/external_install_ui.cc
index 1832184..dc0abc4 100644
--- a/chrome/browser/extensions/external_install_ui.cc
+++ b/chrome/browser/extensions/external_install_ui.cc
@@ -340,7 +340,13 @@
 
 void ExternalInstallDialogDelegate::InstallUIAbort(bool user_initiated) {
   const Extension* extension = NULL;
-  if (service_weak_.get() &&
+
+  // Uninstall the extension if the abort was user initiated (and not, e.g., the
+  // result of the window closing).
+  // Otherwise, the extension will remain installed, but unacknowledged, so it
+  // will be prompted again.
+  if (user_initiated &&
+      service_weak_.get() &&
       (extension = service_weak_->GetInstalledExtension(extension_id_))) {
     service_weak_->UninstallExtension(extension_id_, false, NULL);
   }
diff --git a/chrome/browser/extensions/favicon_downloader.cc b/chrome/browser/extensions/favicon_downloader.cc
index b518a32..4237eb7 100644
--- a/chrome/browser/extensions/favicon_downloader.cc
+++ b/chrome/browser/extensions/favicon_downloader.cc
@@ -112,7 +112,6 @@
 }
 
 void FaviconDownloader::DidUpdateFaviconURL(
-    int32 page_id,
     const std::vector<content::FaviconURL>& candidates) {
   // Only consider the first candidates we are given. This prevents pages that
   // change their favicon from spamming us.
diff --git a/chrome/browser/extensions/favicon_downloader.h b/chrome/browser/extensions/favicon_downloader.h
index e42ee9b..36bf23f 100644
--- a/chrome/browser/extensions/favicon_downloader.h
+++ b/chrome/browser/extensions/favicon_downloader.h
@@ -69,7 +69,6 @@
       const content::LoadCommittedDetails& details,
       const content::FrameNavigateParams& params) OVERRIDE;
   virtual void DidUpdateFaviconURL(
-      int32 page_id,
       const std::vector<content::FaviconURL>& candidates) OVERRIDE;
 
   // Whether we have received favicons from the renderer.
diff --git a/chrome/browser/extensions/favicon_downloader_unittest.cc b/chrome/browser/extensions/favicon_downloader_unittest.cc
index b75208a..f177ce3 100644
--- a/chrome/browser/extensions/favicon_downloader_unittest.cc
+++ b/chrome/browser/extensions/favicon_downloader_unittest.cc
@@ -87,7 +87,7 @@
   }
 
   void UpdateFaviconURLs(const std::vector<content::FaviconURL>& candidates) {
-    FaviconDownloader::DidUpdateFaviconURL(0, candidates);
+    FaviconDownloader::DidUpdateFaviconURL(candidates);
   }
 
   void set_initial_favicon_urls(const std::vector<content::FaviconURL>& urls) {
diff --git a/chrome/browser/extensions/installed_loader.cc b/chrome/browser/extensions/installed_loader.cc
index ba3cdfd..2406160 100644
--- a/chrome/browser/extensions/installed_loader.cc
+++ b/chrome/browser/extensions/installed_loader.cc
@@ -11,8 +11,8 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/extensions/api/runtime/runtime_api.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
+#include "chrome/browser/extensions/extension_error_reporter.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/chrome_switches.h"
@@ -21,6 +21,7 @@
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/user_metrics.h"
+#include "extensions/browser/api/runtime/runtime_api.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
@@ -171,7 +172,11 @@
   }
 
   if (!extension.get()) {
-    extension_service_->ReportExtensionLoadError(info.extension_path, error);
+    ExtensionErrorReporter::GetInstance()->ReportLoadError(
+        info.extension_path,
+        error,
+        extension_service_->profile(),
+        false);  // Be quiet.
     return;
   }
 
@@ -222,8 +227,11 @@
                                    &error));
 
       if (!extension.get()) {
-        extension_service_->ReportExtensionLoadError(
-            info->extension_path, error);
+        ExtensionErrorReporter::GetInstance()->ReportLoadError(
+            info->extension_path,
+            error,
+            extension_service_->profile(),
+            false);  // Be quiet.
         continue;
       }
 
diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc
index 0265b31..d57b770 100644
--- a/chrome/browser/extensions/lazy_background_page_apitest.cc
+++ b/chrome/browser/extensions/lazy_background_page_apitest.cc
@@ -6,7 +6,6 @@
 #include "base/files/file_path.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/browser_action_test_util.h"
 #include "chrome/browser/extensions/extension_apitest.h"
@@ -23,6 +22,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
diff --git a/chrome/browser/extensions/ntp_overridden_bubble_controller.cc b/chrome/browser/extensions/ntp_overridden_bubble_controller.cc
index 183f0dc..632e88d 100644
--- a/chrome/browser/extensions/ntp_overridden_bubble_controller.cc
+++ b/chrome/browser/extensions/ntp_overridden_bubble_controller.cc
@@ -132,22 +132,15 @@
 }
 
 GURL NtpOverriddenBubbleDelegate::GetLearnMoreUrl() const {
-  // TODO(finnur): Rename the const when things settle down (since it is used in
-  // more places than for the Settings API bubble now).
-  return GURL(chrome::kSettingsApiLearnMoreURL);
+  return GURL(chrome::kExtensionControlledSettingLearnMoreURL);
 }
 
 base::string16 NtpOverriddenBubbleDelegate::GetActionButtonLabel() const {
-  // TODO(finnur): Rename the const when things settle down (since it is used in
-  // more places than for the Settings API bubble now).
-  return l10n_util::GetStringUTF16(
-      IDS_EXTENSIONS_SETTINGS_API_RESTORE_SETTINGS);
+  return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_RESTORE_SETTINGS);
 }
 
 base::string16 NtpOverriddenBubbleDelegate::GetDismissButtonLabel() const {
-  // TODO(finnur): Rename the const when things settle down (since it is used in
-  // more places than for the Settings API bubble now).
-  return l10n_util::GetStringUTF16(IDS_EXTENSIONS_SETTINGS_API_KEEP_CHANGES);
+  return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_KEEP_CHANGES);
 }
 
 bool NtpOverriddenBubbleDelegate::ShouldShowExtensionList() const {
diff --git a/chrome/browser/extensions/page_action_controller.cc b/chrome/browser/extensions/page_action_controller.cc
index 4e3a548..6d9bfad 100644
--- a/chrome/browser/extensions/page_action_controller.cc
+++ b/chrome/browser/extensions/page_action_controller.cc
@@ -4,23 +4,22 @@
 
 #include "chrome/browser/extensions/page_action_controller.h"
 
+#include <set>
+
 #include "base/lazy_instance.h"
 #include "base/metrics/histogram.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/extensions/extension_action_manager.h"
-#include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_id.h"
 #include "content/public/browser/invalidate_type.h"
 #include "content/public/browser/navigation_details.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
-#include "extensions/browser/extension_system.h"
+#include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension_set.h"
 
 namespace extensions {
@@ -35,28 +34,30 @@
 PageActionController::~PageActionController() {}
 
 std::vector<ExtensionAction*> PageActionController::GetCurrentActions() const {
-  ExtensionService* service = GetExtensionService();
-  if (!service)
+  ExtensionRegistry* registry = GetExtensionRegistry();
+  if (!registry)
     return std::vector<ExtensionAction*>();
 
   // Accumulate the list of all page actions to display.
   std::vector<ExtensionAction*> current_actions;
 
   ExtensionActionManager* extension_action_manager =
-      ExtensionActionManager::Get(profile());
+      ExtensionActionManager::Get(GetProfile());
 
-  for (ExtensionSet::const_iterator i = service->extensions()->begin();
-       i != service->extensions()->end(); ++i) {
+  const ExtensionSet& enabled_set = registry->enabled_extensions();
+  for (ExtensionSet::const_iterator i = enabled_set.begin();
+       i != enabled_set.end();
+       ++i) {
     ExtensionAction* action =
         extension_action_manager->GetPageAction(*i->get());
     if (action)
       current_actions.push_back(action);
   }
 
-  if (!g_reported_for_profiles.Get().count(profile())) {
+  if (!g_reported_for_profiles.Get().count(GetProfile())) {
     UMA_HISTOGRAM_COUNTS_100("PageActionController.ExtensionsWithPageActions",
                              current_actions.size());
-    g_reported_for_profiles.Get().insert(profile());
+    g_reported_for_profiles.Get().insert(GetProfile());
   }
 
   return current_actions;
@@ -64,14 +65,15 @@
 
 LocationBarController::Action PageActionController::OnClicked(
     const std::string& extension_id, int mouse_button) {
-  ExtensionService* service = GetExtensionService();
-  if (!service)
+  ExtensionRegistry* registry = GetExtensionRegistry();
+  if (!registry)
     return ACTION_NONE;
 
-  const Extension* extension = service->extensions()->GetByID(extension_id);
+  const Extension* extension =
+      registry->enabled_extensions().GetByID(extension_id);
   CHECK(extension);
   ExtensionAction* page_action =
-      ExtensionActionManager::Get(profile())->GetPageAction(*extension);
+      ExtensionActionManager::Get(GetProfile())->GetPageAction(*extension);
   CHECK(page_action);
   int tab_id = ExtensionTabUtil::GetTabId(web_contents());
 
@@ -85,7 +87,7 @@
         return ACTION_SHOW_POPUP;
 
       ExtensionActionAPI::PageActionExecuted(
-          profile(), *page_action, tab_id,
+          GetProfile(), *page_action, tab_id,
           web_contents()->GetURL().spec(), mouse_button);
       return ACTION_NONE;
 
@@ -121,7 +123,7 @@
   NotifyChange();
 }
 
-Profile* PageActionController::profile() const {
+Profile* PageActionController::GetProfile() const {
   content::WebContents* web_contents = this->web_contents();
   if (web_contents)
     return Profile::FromBrowserContext(web_contents->GetBrowserContext());
@@ -129,12 +131,9 @@
   return NULL;
 }
 
-ExtensionService* PageActionController::GetExtensionService() const {
-  Profile* profile = this->profile();
-  if (profile)
-    return ExtensionSystem::Get(profile)->extension_service();
-
-  return NULL;
+ExtensionRegistry* PageActionController::GetExtensionRegistry() const {
+  Profile* profile = this->GetProfile();
+  return profile ? ExtensionRegistry::Get(profile) : NULL;
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/page_action_controller.h b/chrome/browser/extensions/page_action_controller.h
index b1a32d3..88320d3 100644
--- a/chrome/browser/extensions/page_action_controller.h
+++ b/chrome/browser/extensions/page_action_controller.h
@@ -5,17 +5,16 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_PAGE_ACTION_CONTROLLER_H_
 #define CHROME_BROWSER_EXTENSIONS_PAGE_ACTION_CONTROLLER_H_
 
-#include <set>
 #include <string>
 
 #include "base/observer_list.h"
 #include "chrome/browser/extensions/location_bar_controller.h"
 #include "content/public/browser/web_contents_observer.h"
 
-class ExtensionService;
 class Profile;
 
 namespace extensions {
+class ExtensionRegistry;
 
 // A LocationBarController which populates the location bar with icons based
 // on the page_action extension API.
@@ -38,10 +37,10 @@
 
  private:
   // Gets the Profile for the web contents.
-  Profile* profile() const;
+  Profile* GetProfile() const;
 
-  // Gets the ExtensionService for the web contents.
-  ExtensionService* GetExtensionService() const;
+  // Gets the ExtensionRegistry for the web contents.
+  ExtensionRegistry* GetExtensionRegistry() const;
 
   DISALLOW_COPY_AND_ASSIGN(PageActionController);
 };
diff --git a/chrome/browser/extensions/script_executor.cc b/chrome/browser/extensions/script_executor.cc
index 45f6fc5..6ff22d8 100644
--- a/chrome/browser/extensions/script_executor.cc
+++ b/chrome/browser/extensions/script_executor.cc
@@ -64,7 +64,7 @@
     return true;
   }
 
-  virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     base::ListValue val;
     callback_.Run(kRendererDestroyed, -1, GURL(std::string()), val);
     delete this;
diff --git a/chrome/browser/extensions/settings_api_bubble_controller.cc b/chrome/browser/extensions/settings_api_bubble_controller.cc
index f10ccc9..93fd83b 100644
--- a/chrome/browser/extensions/settings_api_bubble_controller.cc
+++ b/chrome/browser/extensions/settings_api_bubble_controller.cc
@@ -227,16 +227,15 @@
 }
 
 GURL SettingsApiBubbleDelegate::GetLearnMoreUrl() const {
-  return GURL(chrome::kSettingsApiLearnMoreURL);
+  return GURL(chrome::kExtensionControlledSettingLearnMoreURL);
 }
 
 base::string16 SettingsApiBubbleDelegate::GetActionButtonLabel() const {
-  return l10n_util::GetStringUTF16(
-      IDS_EXTENSIONS_SETTINGS_API_RESTORE_SETTINGS);
+  return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_RESTORE_SETTINGS);
 }
 
 base::string16 SettingsApiBubbleDelegate::GetDismissButtonLabel() const {
-  return l10n_util::GetStringUTF16(IDS_EXTENSIONS_SETTINGS_API_KEEP_CHANGES);
+  return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_KEEP_CHANGES);
 }
 
 bool SettingsApiBubbleDelegate::ShouldShowExtensionList() const {
diff --git a/chrome/browser/extensions/shared_module_apitest.cc b/chrome/browser/extensions/shared_module_apitest.cc
index e10a467..3b31496 100644
--- a/chrome/browser/extensions/shared_module_apitest.cc
+++ b/chrome/browser/extensions/shared_module_apitest.cc
@@ -6,12 +6,13 @@
 
 using extensions::Extension;
 
+// NB: We use LoadExtension instead of InstallExtension for shared modules so
+// the public-keys in their manifests are used to generate the extension ID, so
+// it can be imported correctly.  We use InstallExtension otherwise so the loads
+// happen through the CRX installer which validates imports.
+
 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, SharedModule) {
   // import_pass depends on this shared module.
-  // NB: We use LoadExtension instead of InstallExtension here so the public-key
-  // in 'shared' is used to generate the extension ID so it can be imported
-  // correctly.  We use InstallExtension otherwise so the loads happen through
-  // the CRX installer which validates imports.
   ASSERT_TRUE(LoadExtension(
       test_data_dir_.AppendASCII("shared_module").AppendASCII("shared")));
 
@@ -24,3 +25,13 @@
       test_data_dir_.AppendASCII("shared_module")
           .AppendASCII("import_non_existent"), 0));
 }
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, SharedModuleWhitelist) {
+  ASSERT_TRUE(LoadExtension(
+      test_data_dir_.AppendASCII("shared_module")
+          .AppendASCII("shared_whitelist")));
+
+  EXPECT_FALSE(InstallExtension(
+      test_data_dir_.AppendASCII("shared_module")
+          .AppendASCII("import_not_in_whitelist"), 0));
+}
diff --git a/chrome/browser/extensions/shared_module_service.cc b/chrome/browser/extensions/shared_module_service.cc
index 6deb9bf..78e9ab7 100644
--- a/chrome/browser/extensions/shared_module_service.cc
+++ b/chrome/browser/extensions/shared_module_service.cc
@@ -62,6 +62,9 @@
       }
     } else if (!SharedModuleInfo::IsSharedModule(imported_module)) {
       return IMPORT_STATUS_UNRECOVERABLE;
+    } else if (!SharedModuleInfo::IsExportAllowedByWhitelist(imported_module,
+                                                             extension->id())) {
+      return IMPORT_STATUS_UNRECOVERABLE;
     } else if (version_required.IsValid() &&
                imported_module->version()->CompareTo(version_required) < 0) {
       if (imported_module->from_webstore()) {
diff --git a/chrome/browser/extensions/shared_module_service_unittest.cc b/chrome/browser/extensions/shared_module_service_unittest.cc
index 2905a93..6ce20d7 100644
--- a/chrome/browser/extensions/shared_module_service_unittest.cc
+++ b/chrome/browser/extensions/shared_module_service_unittest.cc
@@ -20,9 +20,10 @@
 
 namespace {
 
-// Return an extension which imports a module with the given |id|.
+// Return an extension with |id| which imports a module with the given
+// |import_id|.
 scoped_refptr<Extension> CreateExtensionImportingModule(
-    const std::string& import_id) {
+    const std::string& import_id, const std::string& id) {
   scoped_ptr<base::DictionaryValue> manifest =
       DictionaryBuilder()
           .Set("name", "Has Dependent Modules")
@@ -34,6 +35,7 @@
 
   return ExtensionBuilder().SetManifest(manifest.Pass())
                            .AddFlags(Extension::FROM_WEBSTORE)
+                           .SetID(id)
                            .Build();
 }
 
@@ -81,8 +83,9 @@
 TEST_F(SharedModuleServiceUnitTest, AddDependentSharedModules) {
   // Create an extension that has a dependency.
   std::string import_id = id_util::GenerateId("id");
+  std::string extension_id = id_util::GenerateId("extension_id");
   scoped_refptr<Extension> extension =
-      CreateExtensionImportingModule(import_id);
+      CreateExtensionImportingModule(import_id, extension_id);
 
   PendingExtensionManager* pending_extension_manager =
       service_->pending_extension_manager();
@@ -114,9 +117,10 @@
 
   EXPECT_TRUE(InstallExtension(shared_module));
 
+  std::string extension_id = id_util::GenerateId("extension_id");
   // Create and install an extension that imports our new module.
   scoped_refptr<Extension> importing_extension =
-      CreateExtensionImportingModule(shared_module->id());
+      CreateExtensionImportingModule(shared_module->id(), extension_id);
   EXPECT_TRUE(InstallExtension(importing_extension));
 
   // Uninstall the extension that imports our module.
@@ -133,4 +137,44 @@
                                            ExtensionRegistry::EVERYTHING));
 }
 
+#if defined(OS_WIN)
+// TODO(elijahtaylor) Temporary disable until crbug.com/369914 is fixed.
+#define MAYBE_WhitelistedImports DISABLED_WhitelistedImports
+#else
+#define MAYBE_WhitelistedImports WhitelistedImports
+#endif
+TEST_F(SharedModuleServiceUnitTest, MAYBE_WhitelistedImports) {
+  std::string whitelisted_id = id_util::GenerateId("whitelisted");
+  std::string nonwhitelisted_id = id_util::GenerateId("nonwhitelisted");
+  // Create a module which exports to a restricted whitelist.
+  scoped_ptr<base::DictionaryValue> manifest =
+      DictionaryBuilder()
+          .Set("name", "Shared Module")
+          .Set("version", "1.0")
+          .Set("manifest_version", 2)
+          .Set("export",
+               DictionaryBuilder().Set("whitelist",
+                                       ListBuilder()
+                                           .Append(whitelisted_id))
+                                  .Set("resources",
+                                       ListBuilder().Append("*"))).Build();
+  scoped_refptr<Extension> shared_module =
+      ExtensionBuilder().SetManifest(manifest.Pass())
+                        .AddFlags(Extension::FROM_WEBSTORE)
+                        .SetID(id_util::GenerateId("shared_module"))
+                        .Build();
+
+  EXPECT_TRUE(InstallExtension(shared_module));
+
+  // Create and install an extension with the whitelisted ID.
+  scoped_refptr<Extension> whitelisted_extension =
+      CreateExtensionImportingModule(shared_module->id(), whitelisted_id);
+  EXPECT_TRUE(InstallExtension(whitelisted_extension));
+
+  // Try to install an extension with an ID that is not whitelisted.
+  scoped_refptr<Extension> nonwhitelisted_extension =
+      CreateExtensionImportingModule(shared_module->id(), nonwhitelisted_id);
+  EXPECT_FALSE(InstallExtension(nonwhitelisted_extension));
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/suspicious_extension_bubble_controller.cc b/chrome/browser/extensions/suspicious_extension_bubble_controller.cc
index 873a3cc..83e5354 100644
--- a/chrome/browser/extensions/suspicious_extension_bubble_controller.cc
+++ b/chrome/browser/extensions/suspicious_extension_bubble_controller.cc
@@ -63,33 +63,19 @@
 }
 
 base::string16 SuspiciousExtensionBubbleDelegate::GetTitle() const {
-  return l10n_util::GetStringUTF16(IDS_EXTENSIONS_SUSPICIOUS_DISABLED_TITLE);
+  return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_TITLE);
 }
 
 base::string16 SuspiciousExtensionBubbleDelegate::GetMessageBody() const {
-  return l10n_util::GetStringFUTF16(IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BODY,
+  return l10n_util::GetStringFUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BODY,
       l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE));
 }
 
 base::string16 SuspiciousExtensionBubbleDelegate::GetOverflowText(
     const base::string16& overflow_count) const {
-  base::string16 overflow_string = l10n_util::GetStringUTF16(
-      IDS_EXTENSIONS_SUSPICIOUS_DISABLED_AND_N_MORE);
-  base::string16 new_string;
-
-  // Just before string freeze, we checked in # as a substitution value for
-  // this string, whereas we should have used $1. It was discovered too late,
-  // so we do the substitution by hand in that case.
-  if (overflow_string.find(base::ASCIIToUTF16("#")) != base::string16::npos) {
-    base::ReplaceChars(overflow_string, base::ASCIIToUTF16("#").c_str(),
-                       overflow_count, &new_string);
-  } else {
-    new_string = l10n_util::GetStringFUTF16(
-            IDS_EXTENSIONS_SUSPICIOUS_DISABLED_AND_N_MORE,
+  return l10n_util::GetStringFUTF16(
+            IDS_EXTENSIONS_DISABLED_AND_N_MORE,
             overflow_count);
-  }
-
-  return new_string;
 }
 
 base::string16
@@ -108,7 +94,7 @@
 
 base::string16
 SuspiciousExtensionBubbleDelegate::GetDismissButtonLabel() const {
-  return l10n_util::GetStringUTF16(IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BUTTON);
+  return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BUTTON);
 }
 
 bool
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc
index 76bed7b..fda6175 100644
--- a/chrome/browser/extensions/tab_helper.cc
+++ b/chrome/browser/extensions/tab_helper.cc
@@ -51,7 +51,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/frame_navigate_params.h"
 #include "extensions/browser/extension_error.h"
 #include "extensions/browser/extension_registry.h"
@@ -342,7 +341,7 @@
   switch (pending_web_app_action_) {
     case CREATE_SHORTCUT: {
       chrome::ShowCreateWebAppShortcutsDialog(
-          web_contents()->GetView()->GetTopLevelNativeWindow(),
+          web_contents()->GetTopLevelNativeWindow(),
           web_contents());
       break;
     }
diff --git a/chrome/browser/extensions/test_extension_environment.cc b/chrome/browser/extensions/test_extension_environment.cc
index a9aa78d..e8d9850 100644
--- a/chrome/browser/extensions/test_extension_environment.cc
+++ b/chrome/browser/extensions/test_extension_environment.cc
@@ -32,7 +32,7 @@
       extension_service_(NULL),
       extension_prefs_(NULL) {
 #if defined(USE_AURA)
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
 #endif
 }
 
diff --git a/chrome/browser/extensions/test_extension_system.cc b/chrome/browser/extensions/test_extension_system.cc
index 50948d5..1a062ac 100644
--- a/chrome/browser/extensions/test_extension_system.cc
+++ b/chrome/browser/extensions/test_extension_system.cc
@@ -183,6 +183,10 @@
   return ready_;
 }
 
+ContentVerifier* TestExtensionSystem::content_verifier() {
+  return NULL;
+}
+
 // static
 KeyedService* TestExtensionSystem::Build(content::BrowserContext* profile) {
   return new TestExtensionSystem(static_cast<Profile*>(profile));
diff --git a/chrome/browser/extensions/test_extension_system.h b/chrome/browser/extensions/test_extension_system.h
index ad5375a..82d7cb3 100644
--- a/chrome/browser/extensions/test_extension_system.h
+++ b/chrome/browser/extensions/test_extension_system.h
@@ -77,6 +77,7 @@
   virtual InstallVerifier* install_verifier() OVERRIDE;
   virtual QuotaService* quota_service() OVERRIDE;
   virtual const OneShotEvent& ready() const OVERRIDE;
+  virtual ContentVerifier* content_verifier() OVERRIDE;
 
   void SetReady() {
     LOG(INFO) << "SetReady()";
diff --git a/chrome/browser/extensions/unpacked_installer.cc b/chrome/browser/extensions/unpacked_installer.cc
index 867c183..56d5197 100644
--- a/chrome/browser/extensions/unpacked_installer.cc
+++ b/chrome/browser/extensions/unpacked_installer.cc
@@ -11,6 +11,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
+#include "chrome/browser/extensions/extension_error_reporter.h"
 #include "chrome/browser/extensions/extension_install_prompt.h"
 #include "chrome/browser/extensions/extension_install_ui.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -112,6 +113,7 @@
     : service_weak_(extension_service->AsWeakPtr()),
       prompt_for_plugins_(true),
       require_modern_manifest_version_(true),
+      be_noisy_on_failure_(true),
       installer_(extension_service->profile()) {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
@@ -296,8 +298,13 @@
   if (!on_failure_callback_.is_null())
     on_failure_callback_.Run(extension_path_, error);
 
-  if (service_weak_.get())
-    service_weak_->ReportExtensionLoadError(extension_path_, error);
+  if (service_weak_.get()) {
+    ExtensionErrorReporter::GetInstance()->ReportLoadError(
+        extension_path_,
+        error,
+        service_weak_->profile(),
+        be_noisy_on_failure_);
+  }
 }
 
 void UnpackedInstaller::ConfirmInstall() {
diff --git a/chrome/browser/extensions/unpacked_installer.h b/chrome/browser/extensions/unpacked_installer.h
index 5d24149..fc22e3c 100644
--- a/chrome/browser/extensions/unpacked_installer.h
+++ b/chrome/browser/extensions/unpacked_installer.h
@@ -69,6 +69,10 @@
     on_failure_callback_ = callback;
   }
 
+  void set_be_noisy_on_failure(bool be_noisy_on_failure) {
+    be_noisy_on_failure_ = be_noisy_on_failure;
+  }
+
  private:
   friend class base::RefCountedThreadSafe<UnpackedInstaller>;
 
@@ -128,6 +132,9 @@
   // An optional callback to set in order to be notified of failure.
   OnFailureCallback on_failure_callback_;
 
+  // Whether or not to be noisy (show a dialog) on failure. Defaults to true.
+  bool be_noisy_on_failure_;
+
   // Gives access to common methods and data of an extension installer.
   ExtensionInstaller installer_;
 
diff --git a/chrome/browser/extensions/url_request_util.cc b/chrome/browser/extensions/url_request_util.cc
index 82dd7f7..4670462 100644
--- a/chrome/browser/extensions/url_request_util.cc
+++ b/chrome/browser/extensions/url_request_util.cc
@@ -107,7 +107,7 @@
     if (StartsWithASCII(*read_mime_type, "text/", false)) {
       // All of our HTML files should be UTF-8 and for other resource types
       // (like images), charset doesn't matter.
-      DCHECK(IsStringUTF8(*data));
+      DCHECK(base::IsStringUTF8(*data));
       *charset = "utf-8";
     }
     int result = read_result ? net::OK : net::ERR_INVALID_URL;
@@ -242,6 +242,9 @@
 bool IsWebViewRequest(net::URLRequest* request) {
   const content::ResourceRequestInfo* info =
       content::ResourceRequestInfo::ForRequest(request);
+  // |info| can be NULL sometimes: http://crbug.com/370070.
+  if (!info)
+    return false;
   ExtensionRendererState* renderer_state =
       ExtensionRendererState::GetInstance();
   ExtensionRendererState::WebViewInfo webview_info;
diff --git a/chrome/browser/extensions/user_script_master.cc b/chrome/browser/extensions/user_script_master.cc
index 8a56f45..ccf7f19 100644
--- a/chrome/browser/extensions/user_script_master.cc
+++ b/chrome/browser/extensions/user_script_master.cc
@@ -19,7 +19,9 @@
 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
+#include "extensions/browser/content_verifier.h"
 #include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_system.h"
 #include "extensions/common/file_util.h"
 #include "extensions/common/message_bundle.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -148,12 +150,13 @@
 
 void UserScriptMaster::ScriptReloader::StartLoad(
     const UserScriptList& user_scripts,
-    const ExtensionsInfo& extensions_info_) {
+    const ExtensionsInfo& extensions_info) {
   // Add a reference to ourselves to keep ourselves alive while we're running.
   // Balanced by NotifyMaster().
   AddRef();
 
-  this->extensions_info_ = extensions_info_;
+  verifier_ = master_->content_verifier();
+  this->extensions_info_ = extensions_info;
   BrowserThread::PostTask(
       BrowserThread::FILE, FROM_HERE,
       base::Bind(
@@ -175,8 +178,24 @@
   Release();
 }
 
-static bool LoadScriptContent(UserScript::File* script_file,
-                              const SubstitutionMap* localization_messages) {
+static void VerifyContent(ContentVerifier* verifier,
+                          const std::string& extension_id,
+                          const base::FilePath& extension_root,
+                          const base::FilePath& relative_path,
+                          const std::string& content) {
+  scoped_refptr<ContentVerifyJob> job(
+      verifier->CreateJobFor(extension_id, extension_root, relative_path));
+  if (job.get()) {
+    job->Start();
+    job->BytesRead(content.size(), content.data());
+    job->DoneReading();
+  }
+}
+
+static bool LoadScriptContent(const std::string& extension_id,
+                              UserScript::File* script_file,
+                              const SubstitutionMap* localization_messages,
+                              ContentVerifier* verifier) {
   std::string content;
   const base::FilePath& path = ExtensionResource::GetFilePath(
       script_file->extension_root(), script_file->relative_path(),
@@ -199,6 +218,13 @@
       LOG(WARNING) << "Failed to load user script file: " << path.value();
       return false;
     }
+    if (verifier) {
+      VerifyContent(verifier,
+                    extension_id,
+                    script_file->extension_root(),
+                    script_file->relative_path(),
+                    content);
+    }
   }
 
   // Localize the content.
@@ -231,12 +257,16 @@
     for (size_t k = 0; k < script.js_scripts().size(); ++k) {
       UserScript::File& script_file = script.js_scripts()[k];
       if (script_file.GetContent().empty())
-        LoadScriptContent(&script_file, NULL);
+        LoadScriptContent(
+            script.extension_id(), &script_file, NULL, verifier_.get());
     }
     for (size_t k = 0; k < script.css_scripts().size(); ++k) {
       UserScript::File& script_file = script.css_scripts()[k];
       if (script_file.GetContent().empty())
-        LoadScriptContent(&script_file, localization_messages.get());
+        LoadScriptContent(script.extension_id(),
+                          &script_file,
+                          localization_messages.get(),
+                          verifier_.get());
     }
   }
 }
@@ -370,6 +400,11 @@
   }
 }
 
+ContentVerifier* UserScriptMaster::content_verifier() {
+  ExtensionSystem* system = ExtensionSystem::Get(profile_);
+  return system->content_verifier();
+}
+
 void UserScriptMaster::OnExtensionLoaded(
     content::BrowserContext* browser_context,
     const Extension* extension) {
diff --git a/chrome/browser/extensions/user_script_master.h b/chrome/browser/extensions/user_script_master.h
index 91fd3ed..909bf8b 100644
--- a/chrome/browser/extensions/user_script_master.h
+++ b/chrome/browser/extensions/user_script_master.h
@@ -27,6 +27,7 @@
 
 namespace extensions {
 
+class ContentVerifier;
 class ExtensionRegistry;
 
 typedef std::map<std::string, ExtensionSet::ExtensionPathAndDefaultLocale>
@@ -55,6 +56,9 @@
   // Return true if we have any scripts ready.
   bool ScriptsReady() const { return shared_memory_.get() != NULL; }
 
+  // Returns the content verifier for our browser context.
+  ContentVerifier* content_verifier();
+
  protected:
   friend class base::RefCountedThreadSafe<UserScriptMaster>;
 
@@ -79,7 +83,7 @@
     // Start loading of scripts.
     // Will always send a message to the master upon completion.
     void StartLoad(const UserScriptList& external_scripts,
-                   const ExtensionsInfo& extension_info_);
+                   const ExtensionsInfo& extensions_info);
 
     // The master is going away; don't call it back.
     void DisownMaster() {
@@ -126,6 +130,8 @@
     // Expected to always outlive us.
     content::BrowserThread::ID master_thread_id_;
 
+    scoped_refptr<ContentVerifier> verifier_;
+
     DISALLOW_COPY_AND_ASSIGN(ScriptReloader);
   };
 
diff --git a/chrome/browser/extensions/webstore_inline_installer.cc b/chrome/browser/extensions/webstore_inline_installer.cc
index 0d0b897..f857f94 100644
--- a/chrome/browser/extensions/webstore_inline_installer.cc
+++ b/chrome/browser/extensions/webstore_inline_installer.cc
@@ -158,8 +158,7 @@
 // Private implementation.
 //
 
-void WebstoreInlineInstaller::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void WebstoreInlineInstaller::WebContentsDestroyed() {
   AbortInstall();
 }
 
diff --git a/chrome/browser/extensions/webstore_inline_installer.h b/chrome/browser/extensions/webstore_inline_installer.h
index 59fcb40..33b278d 100644
--- a/chrome/browser/extensions/webstore_inline_installer.h
+++ b/chrome/browser/extensions/webstore_inline_installer.h
@@ -58,8 +58,7 @@
 
  private:
   // content::WebContentsObserver interface implementation.
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // Checks whether the install is initiated by a page in a verified site
   // (which is at least a domain, but can also have a port or a path).
diff --git a/chrome/browser/extensions/window_controller_list.cc b/chrome/browser/extensions/window_controller_list.cc
index 608d3e5..230ec51 100644
--- a/chrome/browser/extensions/window_controller_list.cc
+++ b/chrome/browser/extensions/window_controller_list.cc
@@ -62,7 +62,7 @@
 }
 
 WindowController* WindowControllerList::FindWindowForFunctionById(
-    const ChromeAsyncExtensionFunction* function,
+    const ChromeUIThreadExtensionFunction* function,
     int id) const {
   WindowController* controller = FindWindowById(id);
   if (controller && function->CanOperateOnWindow(controller))
@@ -71,7 +71,7 @@
 }
 
 WindowController* WindowControllerList::CurrentWindowForFunction(
-    const ChromeAsyncExtensionFunction* function) const {
+    const ChromeUIThreadExtensionFunction* function) const {
   WindowController* result = NULL;
   // Returns either the focused window (if any), or the last window in the list.
   for (ControllerList::const_iterator iter = windows().begin();
diff --git a/chrome/browser/extensions/window_controller_list.h b/chrome/browser/extensions/window_controller_list.h
index 103069f..a68c59f 100644
--- a/chrome/browser/extensions/window_controller_list.h
+++ b/chrome/browser/extensions/window_controller_list.h
@@ -13,7 +13,7 @@
 #include "chrome/browser/extensions/window_controller.h"
 
 class Profile;
-class ChromeAsyncExtensionFunction;
+class ChromeUIThreadExtensionFunction;
 
 namespace extensions {
 
@@ -38,13 +38,13 @@
 
   // Returns a window matching the context the function was invoked in.
   WindowController* FindWindowForFunctionById(
-      const ChromeAsyncExtensionFunction* function,
+      const ChromeUIThreadExtensionFunction* function,
       int id) const;
 
   // Returns the focused or last added window matching the context the function
   // was invoked in.
   WindowController* CurrentWindowForFunction(
-      const ChromeAsyncExtensionFunction* function) const;
+      const ChromeUIThreadExtensionFunction* function) const;
 
   const ControllerList& windows() const { return windows_; }
 
diff --git a/chrome/browser/favicon/favicon_handler.cc b/chrome/browser/favicon/favicon_handler.cc
index bc4a565..addf93b 100644
--- a/chrome/browser/favicon/favicon_handler.cc
+++ b/chrome/browser/favicon/favicon_handler.cc
@@ -370,7 +370,6 @@
 }
 
 void FaviconHandler::OnUpdateFaviconURL(
-    int32 page_id,
     const std::vector<FaviconURL>& candidates) {
   image_urls_.clear();
   best_favicon_candidate_ = FaviconCandidate();
diff --git a/chrome/browser/favicon/favicon_handler.h b/chrome/browser/favicon/favicon_handler.h
index 7dc6a7f..6cb9d59 100644
--- a/chrome/browser/favicon/favicon_handler.h
+++ b/chrome/browser/favicon/favicon_handler.h
@@ -97,8 +97,7 @@
 
   // Message Handler.  Must be public, because also called from
   // PrerenderContents. Collects the |image_urls| list.
-  void OnUpdateFaviconURL(int32 page_id,
-                          const std::vector<content::FaviconURL>& candidates);
+  void OnUpdateFaviconURL(const std::vector<content::FaviconURL>& candidates);
 
   // Processes the current image_irls_ entry, requesting the image from the
   // history / download service.
diff --git a/chrome/browser/favicon/favicon_handler_unittest.cc b/chrome/browser/favicon/favicon_handler_unittest.cc
index 3fadf19..8f4fcf6 100644
--- a/chrome/browser/favicon/favicon_handler_unittest.cc
+++ b/chrome/browser/favicon/favicon_handler_unittest.cc
@@ -437,7 +437,7 @@
     favicon_handler->FetchFavicon(page_url);
     favicon_handler->history_handler()->InvokeCallback();
 
-    favicon_handler->OnUpdateFaviconURL(0, candidate_icons);
+    favicon_handler->OnUpdateFaviconURL(candidate_icons);
   }
 
   virtual void SetUp() {
@@ -498,7 +498,7 @@
   std::vector<FaviconURL> urls;
   urls.push_back(
       FaviconURL(icon_url, FaviconURL::FAVICON, std::vector<gfx::Size>()));
-  helper.OnUpdateFaviconURL(0, urls);
+  helper.OnUpdateFaviconURL(urls);
 
   // Verify FaviconHandler status
   EXPECT_EQ(1U, helper.urls().size());
@@ -542,7 +542,7 @@
   std::vector<FaviconURL> urls;
   urls.push_back(
       FaviconURL(icon_url, FaviconURL::FAVICON, std::vector<gfx::Size>()));
-  helper.OnUpdateFaviconURL(0, urls);
+  helper.OnUpdateFaviconURL(urls);
 
   // Verify FaviconHandler status
   EXPECT_EQ(1U, helper.urls().size());
@@ -614,7 +614,7 @@
   std::vector<FaviconURL> urls;
   urls.push_back(
       FaviconURL(new_icon_url, FaviconURL::FAVICON, std::vector<gfx::Size>()));
-  helper.OnUpdateFaviconURL(0, urls);
+  helper.OnUpdateFaviconURL(urls);
 
   // Verify FaviconHandler status.
   EXPECT_EQ(1U, helper.urls().size());
@@ -704,7 +704,7 @@
   std::vector<FaviconURL> urls;
   urls.push_back(
       FaviconURL(icon_url, FaviconURL::FAVICON, std::vector<gfx::Size>()));
-  helper.OnUpdateFaviconURL(0, urls);
+  helper.OnUpdateFaviconURL(urls);
 
   // A download for the favicon should be requested, and we should not do
   // another history request.
@@ -768,7 +768,7 @@
   std::vector<FaviconURL> urls;
   urls.push_back(
       FaviconURL(new_icon_url, FaviconURL::FAVICON, std::vector<gfx::Size>()));
-  helper.OnUpdateFaviconURL(0, urls);
+  helper.OnUpdateFaviconURL(urls);
 
   // Verify FaviconHandler status.
   EXPECT_EQ(1U, helper.urls().size());
@@ -835,7 +835,7 @@
       new_icon_url, FaviconURL::TOUCH_ICON, std::vector<gfx::Size>()));
   urls.push_back(
       FaviconURL(new_icon_url, FaviconURL::FAVICON, std::vector<gfx::Size>()));
-  helper.OnUpdateFaviconURL(0, urls);
+  helper.OnUpdateFaviconURL(urls);
 
   // Verify FaviconHandler status.
   EXPECT_EQ(2U, helper.urls().size());
@@ -949,7 +949,7 @@
       new_icon_url, FaviconURL::TOUCH_ICON, std::vector<gfx::Size>()));
   urls.push_back(
       FaviconURL(new_icon_url, FaviconURL::FAVICON, std::vector<gfx::Size>()));
-  helper.OnUpdateFaviconURL(0, urls);
+  helper.OnUpdateFaviconURL(urls);
 
   // Verify FaviconHandler status.
   EXPECT_EQ(2U, helper.urls().size());
@@ -983,7 +983,7 @@
   std::vector<FaviconURL> latest_urls;
   latest_urls.push_back(FaviconURL(
       latest_icon_url, FaviconURL::TOUCH_ICON, std::vector<gfx::Size>()));
-  helper.OnUpdateFaviconURL(0, latest_urls);
+  helper.OnUpdateFaviconURL(latest_urls);
 
   EXPECT_EQ(1U, helper.urls().size());
   EXPECT_EQ(latest_icon_url, helper.current_candidate()->icon_url);
diff --git a/chrome/browser/favicon/favicon_tab_helper.cc b/chrome/browser/favicon/favicon_tab_helper.cc
index 542c634..a6a7bb8 100644
--- a/chrome/browser/favicon/favicon_tab_helper.cc
+++ b/chrome/browser/favicon/favicon_tab_helper.cc
@@ -191,14 +191,13 @@
 }
 
 void FaviconTabHelper::DidUpdateFaviconURL(
-    int32 page_id,
     const std::vector<content::FaviconURL>& candidates) {
   DCHECK(!candidates.empty());
   favicon_urls_ = candidates;
 
-  favicon_handler_->OnUpdateFaviconURL(page_id, candidates);
+  favicon_handler_->OnUpdateFaviconURL(candidates);
   if (touch_icon_handler_.get())
-    touch_icon_handler_->OnUpdateFaviconURL(page_id, candidates);
+    touch_icon_handler_->OnUpdateFaviconURL(candidates);
 }
 
 FaviconService* FaviconTabHelper::GetFaviconService() {
diff --git a/chrome/browser/favicon/favicon_tab_helper.h b/chrome/browser/favicon/favicon_tab_helper.h
index 442df7a..9450b0c 100644
--- a/chrome/browser/favicon/favicon_tab_helper.h
+++ b/chrome/browser/favicon/favicon_tab_helper.h
@@ -62,7 +62,6 @@
   // content::WebContentsObserver override. Must be public, because also
   // called from PrerenderContents.
   virtual void DidUpdateFaviconURL(
-      int32 page_id,
       const std::vector<content::FaviconURL>& candidates) OVERRIDE;
 
   // Saves the favicon for the current page.
diff --git a/chrome/browser/feedback/feedback_data.cc b/chrome/browser/feedback/feedback_data.cc
deleted file mode 100644
index e5dde6a..0000000
--- a/chrome/browser/feedback/feedback_data.cc
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/feedback/feedback_data.h"
-
-#include "base/file_util.h"
-#include "base/json/json_string_value_serializer.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/feedback/feedback_util.h"
-#include "chrome/browser/feedback/tracing_manager.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "content/public/browser/browser_thread.h"
-
-#if defined(USE_ASH)
-#include "ash/shell.h"
-#include "ash/shell_delegate.h"
-#endif
-
-using content::BrowserThread;
-
-namespace {
-
-const char kMultilineIndicatorString[] = "<multiline>\n";
-const char kMultilineStartString[] = "---------- START ----------\n";
-const char kMultilineEndString[] = "---------- END ----------\n\n";
-
-const size_t kFeedbackMaxLength = 4 * 1024;
-const size_t kFeedbackMaxLineCount = 40;
-
-const char kTraceFilename[] = "tracing.zip\n";
-const char kPerformanceCategoryTag[] = "Performance";
-
-const char kZipExt[] = ".zip";
-
-const base::FilePath::CharType kLogsFilename[] =
-    FILE_PATH_LITERAL("system_logs.txt");
-const base::FilePath::CharType kHistogramsFilename[] =
-    FILE_PATH_LITERAL("histograms.txt");
-
-// Converts the system logs into a string that we can compress and send
-// with the report. This method only converts those logs that we want in
-// the compressed zip file sent with the report, hence it ignores any logs
-// below the size threshold of what we want compressed.
-std::string LogsToString(const FeedbackData::SystemLogsMap& sys_info) {
-  std::string syslogs_string;
-  for (FeedbackData::SystemLogsMap::const_iterator it = sys_info.begin();
-      it != sys_info.end(); ++it) {
-    std::string key = it->first;
-    std::string value = it->second;
-
-    if (FeedbackData::BelowCompressionThreshold(value))
-      continue;
-
-    base::TrimString(key, "\n ", &key);
-    base::TrimString(value, "\n ", &value);
-
-    if (value.find("\n") != std::string::npos) {
-      syslogs_string.append(
-          key + "=" + kMultilineIndicatorString +
-          kMultilineStartString +
-          value + "\n" +
-          kMultilineEndString);
-    } else {
-      syslogs_string.append(key + "=" + value + "\n");
-    }
-  }
-  return syslogs_string;
-}
-
-void ZipFile(const base::FilePath& filename,
-             const std::string& data, std::string* compressed_data) {
-  if (!feedback_util::ZipString(filename, data, compressed_data))
-    compressed_data->clear();
-}
-
-void ZipLogs(const FeedbackData::SystemLogsMap& sys_info,
-             std::string* compressed_logs) {
-  DCHECK(compressed_logs);
-  std::string logs_string = LogsToString(sys_info);
-  if (logs_string.empty() ||
-      !feedback_util::ZipString(
-          base::FilePath(kLogsFilename), logs_string, compressed_logs)) {
-    compressed_logs->clear();
-  }
-}
-
-void ZipHistograms(const std::string& histograms,
-                   std::string* compressed_histograms) {
-  DCHECK(compressed_histograms);
-  if (histograms.empty() ||
-      !feedback_util::ZipString(
-          base::FilePath(kHistogramsFilename),
-          histograms,
-          compressed_histograms)) {
-    compressed_histograms->clear();
-  }
-}
-
-}  // namespace
-
-// static
-bool FeedbackData::BelowCompressionThreshold(const std::string& content) {
-  if (content.length() > kFeedbackMaxLength)
-    return false;
-  const size_t line_count = std::count(content.begin(), content.end(), '\n');
-  if (line_count > kFeedbackMaxLineCount)
-    return false;
-  return true;
-}
-
-FeedbackData::FeedbackData() : profile_(NULL),
-                               trace_id_(0),
-                               feedback_page_data_complete_(false),
-                               syslogs_compression_complete_(false),
-                               histograms_compression_complete_(false),
-                               attached_file_compression_complete_(false),
-                               report_sent_(false) {
-}
-
-FeedbackData::~FeedbackData() {
-}
-
-void FeedbackData::OnFeedbackPageDataComplete() {
-  feedback_page_data_complete_ = true;
-  SendReport();
-}
-
-void FeedbackData::SetAndCompressSystemInfo(
-    scoped_ptr<FeedbackData::SystemLogsMap> sys_info) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  if (trace_id_ != 0) {
-    TracingManager* manager = TracingManager::Get();
-    if (!manager ||
-        !manager->GetTraceData(
-            trace_id_,
-            base::Bind(&FeedbackData::OnGetTraceData, this, trace_id_))) {
-      trace_id_ = 0;
-    }
-  }
-
-  sys_info_ = sys_info.Pass();
-  if (sys_info_.get()) {
-    std::string* compressed_logs_ptr = new std::string;
-    scoped_ptr<std::string> compressed_logs(compressed_logs_ptr);
-    BrowserThread::PostBlockingPoolTaskAndReply(
-        FROM_HERE,
-        base::Bind(&ZipLogs,
-                   *sys_info_,
-                   compressed_logs_ptr),
-        base::Bind(&FeedbackData::OnCompressLogsComplete,
-                   this,
-                   base::Passed(&compressed_logs)));
-  }
-}
-
-void FeedbackData::SetAndCompressHistograms(
-    scoped_ptr<std::string> histograms) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  histograms_ = histograms.Pass();
-  if (histograms_.get()) {
-    std::string* compressed_histograms_ptr = new std::string;
-    scoped_ptr<std::string> compressed_histograms(compressed_histograms_ptr);
-    BrowserThread::PostBlockingPoolTaskAndReply(
-        FROM_HERE,
-        base::Bind(&ZipHistograms,
-                   *histograms_,
-                   compressed_histograms_ptr),
-        base::Bind(&FeedbackData::OnCompressHistogramsComplete,
-                   this,
-                   base::Passed(&compressed_histograms)));
-  }
-}
-
-void FeedbackData::AttachAndCompressFileData(
-    scoped_ptr<std::string> attached_filedata) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  attached_filedata_ = attached_filedata.Pass();
-
-  if (!attached_filename_.empty() && attached_filedata_.get()) {
-    std::string* compressed_file_ptr = new std::string;
-    scoped_ptr<std::string> compressed_file(compressed_file_ptr);
-#if defined(OS_WIN)
-    base::FilePath attached_file(base::UTF8ToWide(attached_filename_));
-#else
-    base::FilePath attached_file(attached_filename_);
-#endif
-    BrowserThread::PostBlockingPoolTaskAndReply(
-        FROM_HERE,
-        base::Bind(&ZipFile,
-                   attached_file,
-                   *(attached_filedata_.get()),
-                   compressed_file_ptr),
-        base::Bind(&FeedbackData::OnCompressFileComplete,
-                   this,
-                   base::Passed(&compressed_file)));
-  }
-}
-
-void FeedbackData::OnGetTraceData(
-    int trace_id,
-    scoped_refptr<base::RefCountedString> trace_data) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TracingManager* manager = TracingManager::Get();
-  if (manager)
-    manager->DiscardTraceData(trace_id);
-
-  scoped_ptr<std::string> data(new std::string);
-  data->swap(trace_data->data());
-
-  attached_filename_ = kTraceFilename;
-  attached_filedata_ = data.Pass();
-  attached_file_compression_complete_ = true;
-  trace_id_ = 0;
-
-  set_category_tag(kPerformanceCategoryTag);
-
-  SendReport();
-}
-
-void FeedbackData::OnCompressLogsComplete(
-    scoped_ptr<std::string> compressed_logs) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  compressed_logs_ = compressed_logs.Pass();
-  syslogs_compression_complete_ = true;
-
-  SendReport();
-}
-
-void FeedbackData::OnCompressHistogramsComplete(
-    scoped_ptr<std::string> compressed_histograms) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  compressed_histograms_ = compressed_histograms.Pass();
-  histograms_compression_complete_ = true;
-
-  SendReport();
-}
-
-void FeedbackData::OnCompressFileComplete(
-    scoped_ptr<std::string> compressed_file) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  if (compressed_file.get()) {
-    attached_filedata_ = compressed_file.Pass();
-    attached_filename_.append(kZipExt);
-    attached_file_compression_complete_ = true;
-  } else {
-    attached_filename_.clear();
-    attached_filedata_.reset(NULL);
-  }
-
-  SendReport();
-}
-
-bool FeedbackData::IsDataComplete() {
-  return (!sys_info_.get() || syslogs_compression_complete_) &&
-      (!histograms_.get() || histograms_compression_complete_) &&
-      (!attached_filedata_.get() || attached_file_compression_complete_) &&
-      !trace_id_ &&
-      feedback_page_data_complete_;
-}
-
-void FeedbackData::SendReport() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  if (IsDataComplete() && !report_sent_) {
-    report_sent_ = true;
-    feedback_util::SendReport(this);
-  }
-}
diff --git a/chrome/browser/feedback/feedback_data.h b/chrome/browser/feedback/feedback_data.h
deleted file mode 100644
index bc566f5..0000000
--- a/chrome/browser/feedback/feedback_data.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_FEEDBACK_FEEDBACK_DATA_H_
-#define CHROME_BROWSER_FEEDBACK_FEEDBACK_DATA_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "url/gurl.h"
-
-namespace base {
-class FilePath;
-class RefCountedString;
-}
-class Profile;
-
-class FeedbackData : public base::RefCountedThreadSafe<FeedbackData> {
- public:
-  typedef std::map<std::string, std::string> SystemLogsMap;
-
-  // Determine if the given feedback value is small enough to not need to
-  // be compressed.
-  static bool BelowCompressionThreshold(const std::string& content);
-
-  FeedbackData();
-
-  // Called once we've updated all the data from the feedback page.
-  void OnFeedbackPageDataComplete();
-
-  // Sets the system information for this instance and kicks off its
-  // compression.
-  void SetAndCompressSystemInfo(scoped_ptr<SystemLogsMap> sys_info);
-
-  // Sets the histograms for this instance and kicks off its
-  // compression.
-  void SetAndCompressHistograms(scoped_ptr<std::string> histograms);
-
-  // Sets the attached file data and kicks off its compression.
-  void AttachAndCompressFileData(scoped_ptr<std::string> attached_filedata);
-
-  // Called once we have compressed our system logs.
-  void OnCompressLogsComplete(scoped_ptr<std::string> compressed_logs);
-
-  // Called once we have compressed our histograms.
-  void OnCompressHistogramsComplete(
-      scoped_ptr<std::string> compressed_histograms);
-
-  // Called once we have compressed our attached file.
-  void OnCompressFileComplete(scoped_ptr<std::string> compressed_file);
-
-  // Returns true if we've completed all the tasks needed before we can send
-  // feedback - at this time this is includes getting the feedback page data
-  // and compressing the system logs.
-  bool IsDataComplete();
-
-  // Sends the feedback report if we have all our data complete.
-  void SendReport();
-
-  // Getters
-  Profile* profile() const { return profile_; }
-  const std::string& category_tag() const { return category_tag_; }
-  const std::string& page_url() const { return page_url_; }
-  const std::string& description() const { return description_; }
-  const std::string& user_email() const { return user_email_; }
-  std::string* image() const { return image_.get(); }
-  const std::string attached_filename() const { return attached_filename_; }
-  const std::string attached_file_uuid() const { return attached_file_uuid_; }
-  std::string* attached_filedata() const { return attached_filedata_.get(); }
-  const std::string screenshot_uuid() const { return screenshot_uuid_; }
-  int trace_id() const { return trace_id_; }
-  SystemLogsMap* sys_info() const { return sys_info_.get(); }
-  std::string* compressed_logs() const { return compressed_logs_.get(); }
-  std::string* histograms() const { return histograms_.get(); }
-  std::string* compressed_histograms() const {
-    return compressed_histograms_.get();
-  }
-
-  // Setters
-  void set_profile(Profile* profile) { profile_ = profile; }
-  void set_category_tag(const std::string& category_tag) {
-    category_tag_ = category_tag;
-  }
-  void set_page_url(const std::string& page_url) { page_url_ = page_url; }
-  void set_description(const std::string& description) {
-    description_ = description;
-  }
-  void set_user_email(const std::string& user_email) {
-    user_email_ = user_email;
-  }
-  void set_image(scoped_ptr<std::string> image) { image_ = image.Pass(); }
-  void set_attached_filename(const std::string& attached_filename) {
-    attached_filename_ = attached_filename;
-  }
-  void set_attached_file_uuid(const std::string& uuid) {
-    attached_file_uuid_ = uuid;
-  }
-  void set_screenshot_uuid(const std::string& uuid) {
-    screenshot_uuid_ = uuid;
-  }
-  void set_trace_id(int trace_id) { trace_id_ = trace_id; }
-
- private:
-  friend class base::RefCountedThreadSafe<FeedbackData>;
-
-  virtual ~FeedbackData();
-
-  void OnGetTraceData(int trace_id,
-                      scoped_refptr<base::RefCountedString> trace_data);
-
-  Profile* profile_;
-
-  std::string category_tag_;
-  std::string page_url_;
-  std::string description_;
-  std::string user_email_;
-  scoped_ptr<std::string> image_;
-  std::string attached_filename_;
-  scoped_ptr<std::string> attached_filedata_;
-
-  std::string attached_file_uuid_;
-  std::string screenshot_uuid_;
-
-  int trace_id_;
-
-  scoped_ptr<SystemLogsMap> sys_info_;
-  scoped_ptr<std::string> compressed_logs_;
-
-  scoped_ptr<std::string> histograms_;
-  scoped_ptr<std::string> compressed_histograms_;
-
-  // TODO(rkc): Refactor compressing logic into a simpler common implementation.
-  bool feedback_page_data_complete_;
-  bool syslogs_compression_complete_;
-  bool histograms_compression_complete_;
-  bool attached_file_compression_complete_;
-  bool report_sent_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedbackData);
-};
-
-#endif  // CHROME_BROWSER_FEEDBACK_FEEDBACK_DATA_H_
diff --git a/chrome/browser/feedback/feedback_profile_observer.cc b/chrome/browser/feedback/feedback_profile_observer.cc
index a08b653..63d5ac7 100644
--- a/chrome/browser/feedback/feedback_profile_observer.cc
+++ b/chrome/browser/feedback/feedback_profile_observer.cc
@@ -6,10 +6,10 @@
 
 #include "base/callback.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/feedback/feedback_report.h"
-#include "chrome/browser/feedback/feedback_uploader.h"
-#include "chrome/browser/feedback/feedback_uploader_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "components/feedback/feedback_report.h"
+#include "components/feedback/feedback_uploader.h"
+#include "components/feedback/feedback_uploader_factory.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/feedback/feedback_report.cc b/chrome/browser/feedback/feedback_report.cc
deleted file mode 100644
index 8518d2b..0000000
--- a/chrome/browser/feedback/feedback_report.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// 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.
-
-#include "chrome/browser/feedback/feedback_report.h"
-
-#include "base/file_util.h"
-#include "base/files/file_enumerator.h"
-#include "base/files/important_file_writer.h"
-#include "base/guid.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "net/base/directory_lister.h"
-
-namespace {
-
-const base::FilePath::CharType kFeedbackReportFilenameWildcard[] =
-    FILE_PATH_LITERAL("Feedback Report.*");
-
-const char kFeedbackReportFilenamePrefix[] = "Feedback Report.";
-
-void WriteReportOnBlockingPool(const base::FilePath reports_path,
-                               const base::FilePath& file,
-                               const std::string& data) {
-  DCHECK(reports_path.IsParent(file));
-  if (!base::DirectoryExists(reports_path)) {
-    base::File::Error error;
-    if (!base::CreateDirectoryAndGetError(reports_path, &error))
-      return;
-  }
-  base::ImportantFileWriter::WriteFileAtomically(file, data);
-}
-
-}  // namespace
-
-namespace feedback {
-
-FeedbackReport::FeedbackReport(
-    const base::FilePath& path,
-    const base::Time& upload_at,
-    const std::string& data,
-    scoped_refptr<base::SequencedTaskRunner> task_runner)
-    : reports_path_(path),
-      upload_at_(upload_at),
-      data_(data),
-      reports_task_runner_(task_runner) {
-  if (reports_path_.empty())
-    return;
-  file_ = reports_path_.AppendASCII(
-      kFeedbackReportFilenamePrefix + base::GenerateGUID());
-
-  reports_task_runner_->PostTask(FROM_HERE, base::Bind(
-      &WriteReportOnBlockingPool, reports_path_, file_, data_));
-}
-
-FeedbackReport::~FeedbackReport() {}
-
-void FeedbackReport::DeleteReportOnDisk() {
-  reports_task_runner_->PostTask(FROM_HERE, base::Bind(
-      base::IgnoreResult(&base::DeleteFile), file_, false));
-}
-
-// static
-void FeedbackReport::LoadReportsAndQueue(
-    const base::FilePath& user_dir, QueueCallback callback) {
-  if (user_dir.empty())
-    return;
-
-  base::FileEnumerator enumerator(user_dir,
-                                  false,
-                                  base::FileEnumerator::FILES,
-                                  kFeedbackReportFilenameWildcard);
-  for (base::FilePath name = enumerator.Next();
-       !name.empty();
-       name = enumerator.Next()) {
-    std::string data;
-    if (ReadFileToString(name, &data))
-      callback.Run(data);
-    base::DeleteFile(name, false);
-  }
-}
-
-}  // namespace feedback
diff --git a/chrome/browser/feedback/feedback_report.h b/chrome/browser/feedback/feedback_report.h
deleted file mode 100644
index 92914d1..0000000
--- a/chrome/browser/feedback/feedback_report.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_FEEDBACK_FEEDBACK_REPORT_H_
-#define CHROME_BROWSER_FEEDBACK_FEEDBACK_REPORT_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/callback_forward.h"
-#include "base/files/file_path.h"
-#include "base/memory/ref_counted.h"
-#include "base/time/time.h"
-
-namespace base {
-class SequencedTaskRunner;
-}
-
-namespace feedback {
-
-typedef base::Callback<void(const std::string&)> QueueCallback;
-
-// This class holds a feedback report. Once a report is created, a disk backup
-// for it is created automatically. This backup needs to explicitly be
-// deleted by calling DeleteReportOnDisk.
-class FeedbackReport : public base::RefCounted<FeedbackReport> {
- public:
-  FeedbackReport(const base::FilePath& path,
-                 const base::Time& upload_at,
-                 const std::string& data,
-                 scoped_refptr<base::SequencedTaskRunner> task_runner);
-
-  // Stops the disk write of the report and deletes the report file if already
-  // written.
-  void DeleteReportOnDisk();
-
-  const base::Time& upload_at() const { return upload_at_; }
-  const std::string& data() const { return data_; }
-
-  // Loads the reports still on disk and queues then using the given callback.
-  // This call blocks on the file reads.
-  static void LoadReportsAndQueue(const base::FilePath& user_dir,
-                                  QueueCallback callback);
-
- private:
-  friend class base::RefCounted<FeedbackReport>;
-  virtual ~FeedbackReport();
-
-  // Name of the file corresponding to this report.
-  base::FilePath file_;
-
-  base::FilePath reports_path_;
-  base::Time upload_at_;  // Upload this report at or after this time.
-  std::string data_;
-
-  scoped_refptr<base::SequencedTaskRunner> reports_task_runner_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedbackReport);
-};
-
-}  // namespace feedback
-
-#endif  // CHROME_BROWSER_FEEDBACK_FEEDBACK_REPORT_H_
diff --git a/chrome/browser/feedback/feedback_uploader.cc b/chrome/browser/feedback/feedback_uploader.cc
deleted file mode 100644
index 1798e3b..0000000
--- a/chrome/browser/feedback/feedback_uploader.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/feedback/feedback_uploader.h"
-
-#include "base/callback.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/sequenced_task_runner.h"
-#include "base/task_runner_util.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "chrome/browser/feedback/feedback_report.h"
-
-namespace feedback {
-namespace {
-
-const char kFeedbackPostUrl[] =
-    "https://www.google.com/tools/feedback/chrome/__submit";
-
-const int64 kRetryDelayMinutes = 60;
-
-const base::FilePath::CharType kFeedbackReportPath[] =
-    FILE_PATH_LITERAL("Feedback Reports");
-
-}  // namespace
-
-bool FeedbackUploader::ReportsUploadTimeComparator::operator()(
-    FeedbackReport* a, FeedbackReport* b) const {
-  return a->upload_at() > b->upload_at();
-}
-
-FeedbackUploader::FeedbackUploader(const base::FilePath& path,
-                                   base::SequencedWorkerPool* pool)
-    : report_path_(path.Append(kFeedbackReportPath)),
-      retry_delay_(base::TimeDelta::FromMinutes(kRetryDelayMinutes)),
-      url_(kFeedbackPostUrl),
-      pool_(pool) {
-  dispatch_callback_ = base::Bind(&FeedbackUploader::DispatchReport,
-                                  AsWeakPtr());
-}
-
-FeedbackUploader::~FeedbackUploader() {}
-
-void FeedbackUploader::QueueReport(const std::string& data) {
-  QueueReportWithDelay(data, base::TimeDelta());
-}
-
-void FeedbackUploader::UpdateUploadTimer() {
-  if (reports_queue_.empty())
-    return;
-
-  scoped_refptr<FeedbackReport> report = reports_queue_.top();
-  base::Time now = base::Time::Now();
-  if (report->upload_at() <= now) {
-    reports_queue_.pop();
-    dispatch_callback_.Run(report->data());
-    report->DeleteReportOnDisk();
-  } else {
-    // Stop the old timer and start an updated one.
-    if (upload_timer_.IsRunning())
-      upload_timer_.Stop();
-    upload_timer_.Start(
-        FROM_HERE, report->upload_at() - now, this,
-        &FeedbackUploader::UpdateUploadTimer);
-  }
-}
-
-void FeedbackUploader::RetryReport(const std::string& data) {
-  QueueReportWithDelay(data, retry_delay_);
-}
-
-void FeedbackUploader::QueueReportWithDelay(const std::string& data,
-                                            base::TimeDelta delay) {
-  // Uses a BLOCK_SHUTDOWN file task runner because we really don't want to
-  // lose reports.
-  scoped_refptr<base::SequencedTaskRunner> task_runner =
-      pool_->GetSequencedTaskRunnerWithShutdownBehavior(
-          pool_->GetSequenceToken(),
-          base::SequencedWorkerPool::BLOCK_SHUTDOWN);
-
-  reports_queue_.push(new FeedbackReport(report_path_,
-                                         base::Time::Now() + delay,
-                                         data,
-                                         task_runner));
-  UpdateUploadTimer();
-}
-
-void FeedbackUploader::setup_for_test(
-    const ReportDataCallback& dispatch_callback,
-    const base::TimeDelta& retry_delay) {
-  dispatch_callback_ = dispatch_callback;
-  retry_delay_ = retry_delay;
-}
-
-}  // namespace feedback
diff --git a/chrome/browser/feedback/feedback_uploader.h b/chrome/browser/feedback/feedback_uploader.h
deleted file mode 100644
index 2bef774..0000000
--- a/chrome/browser/feedback/feedback_uploader.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_H_
-#define CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_H_
-
-#include <queue>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/file_util.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
-#include "base/timer/timer.h"
-
-namespace feedback {
-
-typedef base::Callback<void(const std::string&)> ReportDataCallback;
-
-class FeedbackReport;
-
-// FeedbackUploader is used to add a feedback report to the queue of reports
-// being uploaded. In case uploading a report fails, it is written to disk and
-// tried again when it's turn comes up next in the queue.
-class FeedbackUploader : public base::SupportsWeakPtr<FeedbackUploader> {
- public:
-  explicit FeedbackUploader(const base::FilePath& path,
-                            base::SequencedWorkerPool* pool);
-  virtual ~FeedbackUploader();
-
-  // Queues a report for uploading.
-  void QueueReport(const std::string& data);
-
-  base::FilePath GetFeedbackReportsPath() { return report_path_; }
-
- protected:
-  friend class FeedbackUploaderTest;
-  struct ReportsUploadTimeComparator {
-    bool operator()(FeedbackReport* a, FeedbackReport* b) const;
-  };
-
-  // Dispatches the report to be uploaded.
-  virtual void DispatchReport(const std::string& data) = 0;
-
-  // Update our timer for uploading the next report.
-  void UpdateUploadTimer();
-
-  // Requeue this report with a delay.
-  void RetryReport(const std::string& data);
-
-  void QueueReportWithDelay(const std::string& data, base::TimeDelta delay);
-
-  void setup_for_test(const ReportDataCallback& dispatch_callback,
-                      const base::TimeDelta& retry_delay);
-
-  base::FilePath report_path_;
-  // Timer to upload the next report at.
-  base::OneShotTimer<FeedbackUploader> upload_timer_;
-  // Priority queue of reports prioritized by the time the report is supposed
-  // to be uploaded at.
-  std::priority_queue<scoped_refptr<FeedbackReport>,
-                      std::vector<scoped_refptr<FeedbackReport> >,
-                      ReportsUploadTimeComparator> reports_queue_;
-
-  ReportDataCallback dispatch_callback_;
-  base::TimeDelta retry_delay_;
-  std::string url_;
-  base::SequencedWorkerPool* pool_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedbackUploader);
-};
-
-}  // namespace feedback
-
-#endif  // CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_H_
diff --git a/chrome/browser/feedback/feedback_uploader_chrome.cc b/chrome/browser/feedback/feedback_uploader_chrome.cc
deleted file mode 100644
index 7a0be8f..0000000
--- a/chrome/browser/feedback/feedback_uploader_chrome.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.
-
-#include "chrome/browser/feedback/feedback_uploader_chrome.h"
-
-#include "base/callback.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/task_runner_util.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "chrome/browser/feedback/feedback_report.h"
-#include "chrome/browser/feedback/feedback_uploader_delegate.h"
-#include "chrome/common/chrome_switches.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/base/load_flags.h"
-#include "net/url_request/url_fetcher.h"
-#include "url/gurl.h"
-
-using content::BrowserThread;
-
-namespace feedback {
-namespace {
-
-const char kProtoBufMimeType[] = "application/x-protobuf";
-
-}  // namespace
-
-FeedbackUploaderChrome::FeedbackUploaderChrome(
-    content::BrowserContext* context)
-    : FeedbackUploader(context ? context->GetPath() : base::FilePath(),
-                       BrowserThread::GetBlockingPool()),
-      context_(context) {
-  CHECK(context_);
-  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kFeedbackServer))
-    url_ = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-        switches::kFeedbackServer);
-}
-
-void FeedbackUploaderChrome::DispatchReport(const std::string& data) {
-  GURL post_url(url_);
-
-  net::URLFetcher* fetcher = net::URLFetcher::Create(
-      post_url, net::URLFetcher::POST,
-      new FeedbackUploaderDelegate(
-          data,
-          base::Bind(&FeedbackUploaderChrome::UpdateUploadTimer, AsWeakPtr()),
-          base::Bind(&FeedbackUploaderChrome::RetryReport, AsWeakPtr())));
-
-  fetcher->SetUploadData(std::string(kProtoBufMimeType), data);
-  fetcher->SetRequestContext(context_->GetRequestContext());
-  fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
-                        net::LOAD_DO_NOT_SEND_COOKIES);
-  fetcher->Start();
-}
-
-}  // namespace feedback
diff --git a/chrome/browser/feedback/feedback_uploader_chrome.h b/chrome/browser/feedback/feedback_uploader_chrome.h
deleted file mode 100644
index dc4ac59..0000000
--- a/chrome/browser/feedback/feedback_uploader_chrome.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_CHROME_H_
-#define CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_CHROME_H_
-
-#include "chrome/browser/feedback/feedback_uploader.h"
-
-#include "components/keyed_service/core/keyed_service.h"
-
-namespace content {
-class BrowserContext;
-}
-
-namespace feedback {
-
-class FeedbackUploaderChrome : public FeedbackUploader,
-                               public KeyedService {
- public:
-  explicit FeedbackUploaderChrome(content::BrowserContext* context);
-
-  virtual void DispatchReport(const std::string& data) OVERRIDE;
-
- private:
-  // Browser context this uploader was created for.
-  content::BrowserContext* context_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedbackUploaderChrome);
-};
-
-}  // namespace feedback
-
-#endif  // CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_CHROME_H_
diff --git a/chrome/browser/feedback/feedback_uploader_delegate.cc b/chrome/browser/feedback/feedback_uploader_delegate.cc
deleted file mode 100644
index 28256dd..0000000
--- a/chrome/browser/feedback/feedback_uploader_delegate.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/feedback/feedback_uploader_delegate.h"
-
-#include <sstream>
-
-#include "base/logging.h"
-#include "net/url_request/url_fetcher.h"
-#include "url/gurl.h"
-
-namespace feedback {
-namespace {
-
-const int kHttpPostSuccessNoContent = 204;
-const int kHttpPostFailNoConnection = -1;
-const int kHttpPostFailClientError = 400;
-const int kHttpPostFailServerError = 500;
-
-}  // namespace
-
-FeedbackUploaderDelegate::FeedbackUploaderDelegate(
-    const std::string& post_body,
-    const base::Closure& success_callback,
-    const ReportDataCallback& error_callback)
-        : post_body_(post_body),
-          success_callback_(success_callback),
-          error_callback_(error_callback) {
-}
-
-FeedbackUploaderDelegate::~FeedbackUploaderDelegate() {}
-
-void FeedbackUploaderDelegate::OnURLFetchComplete(
-    const net::URLFetcher* source) {
-  scoped_ptr<const net::URLFetcher> source_scoper(source);
-
-  std::stringstream error_stream;
-  int response_code = source->GetResponseCode();
-  if (response_code == kHttpPostSuccessNoContent) {
-    error_stream << "Success";
-    success_callback_.Run();
-  } else {
-    // Process the error for debug output
-    if (response_code == kHttpPostFailNoConnection) {
-      error_stream << "No connection to server.";
-    } else if ((response_code > kHttpPostFailClientError) &&
-               (response_code < kHttpPostFailServerError)) {
-      error_stream << "Client error: HTTP response code " << response_code;
-    } else if (response_code > kHttpPostFailServerError) {
-      error_stream << "Server error: HTTP response code " << response_code;
-    } else {
-      error_stream << "Unknown error: HTTP response code " << response_code;
-    }
-    error_callback_.Run(post_body_);
-  }
-
-  LOG(WARNING) << "FEEDBACK: Submission to feedback server ("
-               << source->GetURL() << ") status: " << error_stream.str();
-
-  // This instance won't be used for anything else, delete us.
-  delete this;
-}
-
-}  // namespace feedback
diff --git a/chrome/browser/feedback/feedback_uploader_delegate.h b/chrome/browser/feedback/feedback_uploader_delegate.h
deleted file mode 100644
index 67d23a7..0000000
--- a/chrome/browser/feedback/feedback_uploader_delegate.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_DELEGATE_H_
-#define CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_DELEGATE_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "chrome/browser/feedback/feedback_uploader.h"
-#include "net/url_request/url_fetcher_delegate.h"
-
-namespace feedback {
-
-// FeedbackUploaderDelegate is a simple http uploader for a feedback report. On
-// succes or failure, it deletes itself, but on failure it also notifies the
-// error callback specified when constructing the class instance.
-class FeedbackUploaderDelegate : public net::URLFetcherDelegate {
- public:
-  FeedbackUploaderDelegate(const std::string& post_body,
-                           const base::Closure& success_callback,
-                           const ReportDataCallback& error_callback);
-  virtual ~FeedbackUploaderDelegate();
-
- private:
-  // Overridden from net::URLFetcherDelegate.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
-
-  std::string post_body_;
-  base::Closure success_callback_;
-  ReportDataCallback error_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedbackUploaderDelegate);
-};
-
-}  // namespace feedback
-
-#endif  // CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_DELEGATE_H_
diff --git a/chrome/browser/feedback/feedback_uploader_factory.cc b/chrome/browser/feedback/feedback_uploader_factory.cc
deleted file mode 100644
index bc20ecc..0000000
--- a/chrome/browser/feedback/feedback_uploader_factory.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/feedback/feedback_uploader_factory.h"
-
-#include "base/memory/singleton.h"
-#include "chrome/browser/feedback/feedback_uploader.h"
-#include "chrome/browser/feedback/feedback_uploader_chrome.h"
-#include "chrome/browser/profiles/incognito_helpers.h"
-#include "components/keyed_service/content/browser_context_dependency_manager.h"
-
-namespace feedback {
-
-// static
-FeedbackUploaderFactory* FeedbackUploaderFactory::GetInstance() {
-  return Singleton<FeedbackUploaderFactory>::get();
-}
-
-// static
-FeedbackUploader* FeedbackUploaderFactory::GetForBrowserContext(
-    content::BrowserContext* context) {
-  return static_cast<FeedbackUploaderChrome*>(
-      GetInstance()->GetServiceForBrowserContext(context, true));
-}
-
-FeedbackUploaderFactory::FeedbackUploaderFactory()
-    : BrowserContextKeyedServiceFactory(
-          "feedback::FeedbackUploader",
-          BrowserContextDependencyManager::GetInstance()) {}
-
-FeedbackUploaderFactory::~FeedbackUploaderFactory() {}
-
-KeyedService* FeedbackUploaderFactory::BuildServiceInstanceFor(
-    content::BrowserContext* context) const {
-  return new FeedbackUploaderChrome(context);
-}
-
-content::BrowserContext* FeedbackUploaderFactory::GetBrowserContextToUse(
-    content::BrowserContext* context) const {
-  return chrome::GetBrowserContextOwnInstanceInIncognito(context);
-}
-
-}  // namespace feedback
diff --git a/chrome/browser/feedback/feedback_uploader_factory.h b/chrome/browser/feedback/feedback_uploader_factory.h
deleted file mode 100644
index 2823c09..0000000
--- a/chrome/browser/feedback/feedback_uploader_factory.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_FACTORY_H_
-#define CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_FACTORY_H_
-
-#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
-
-template<typename T> struct DefaultSingletonTraits;
-
-namespace content {
-class BrowserContext;
-}
-
-namespace feedback {
-
-class FeedbackUploader;
-
-// Singleton that owns the FeedbackUploaders and associates them with profiles;
-class FeedbackUploaderFactory : public BrowserContextKeyedServiceFactory {
- public:
-  // Returns singleton instance of FeedbackUploaderFactory.
-  static FeedbackUploaderFactory* GetInstance();
-
-  // Returns the Feedback Uploader associated with |context|.
-  static FeedbackUploader* GetForBrowserContext(
-      content::BrowserContext* context);
-
- private:
-  friend struct DefaultSingletonTraits<FeedbackUploaderFactory>;
-
-  FeedbackUploaderFactory();
-  virtual ~FeedbackUploaderFactory();
-
-  // BrowserContextKeyedServiceFactory overrides:
-  virtual KeyedService* BuildServiceInstanceFor(
-      content::BrowserContext* context) const OVERRIDE;
-  virtual content::BrowserContext* GetBrowserContextToUse(
-      content::BrowserContext* context) const OVERRIDE;
-
-  DISALLOW_COPY_AND_ASSIGN(FeedbackUploaderFactory);
-};
-
-}  // namespace feedback
-
-#endif  // CHROME_BROWSER_FEEDBACK_FEEDBACK_UPLOADER_FACTORY_H_
diff --git a/chrome/browser/feedback/feedback_uploader_unittest.cc b/chrome/browser/feedback/feedback_uploader_unittest.cc
deleted file mode 100644
index b504be0..0000000
--- a/chrome/browser/feedback/feedback_uploader_unittest.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/feedback/feedback_uploader.h"
-
-#include <set>
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "chrome/browser/feedback/feedback_uploader_chrome.h"
-#include "chrome/browser/feedback/feedback_uploader_factory.h"
-#include "chrome/test/base/testing_profile.h"
-#include "content/public/test/test_browser_thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-const char kReportOne[] = "one";
-const char kReportTwo[] = "two";
-const char kReportThree[] = "three";
-const char kReportFour[] = "four";
-const char kReportFive[] = "five";
-
-const base::TimeDelta kRetryDelayForTest =
-    base::TimeDelta::FromMilliseconds(100);
-
-KeyedService* CreateFeedbackUploaderService(content::BrowserContext* context) {
-  return new feedback::FeedbackUploaderChrome(
-      Profile::FromBrowserContext(context));
-}
-
-}  // namespace
-
-namespace feedback {
-
-class FeedbackUploaderTest : public testing::Test {
- protected:
-  FeedbackUploaderTest()
-     : ui_thread_(content::BrowserThread::UI, &message_loop_),
-       profile_(new TestingProfile()),
-       dispatched_reports_count_(0),
-       expected_reports_(0) {
-    FeedbackUploaderFactory::GetInstance()->SetTestingFactory(
-        profile_.get(), &CreateFeedbackUploaderService);
-
-    uploader_ = FeedbackUploaderFactory::GetForBrowserContext(profile_.get());
-    uploader_->setup_for_test(
-        base::Bind(&FeedbackUploaderTest::MockDispatchReport,
-                   base::Unretained(this)),
-        kRetryDelayForTest);
-  }
-
-  virtual ~FeedbackUploaderTest() {
-    FeedbackUploaderFactory::GetInstance()->SetTestingFactory(
-        profile_.get(), NULL);
-  }
-
-  void QueueReport(const std::string& data) {
-    uploader_->QueueReport(data);
-  }
-
-  void ReportFailure(const std::string& data) {
-    uploader_->RetryReport(data);
-  }
-
-  void MockDispatchReport(const std::string& report_data) {
-    if (ContainsKey(dispatched_reports_, report_data)) {
-      dispatched_reports_[report_data]++;
-    } else {
-      dispatched_reports_[report_data] = 1;
-    }
-    dispatched_reports_count_++;
-
-    // Dispatch will always update the timer, whether successful or not,
-    // simulate the same behavior.
-    uploader_->UpdateUploadTimer();
-
-    if (ProcessingComplete()) {
-      if (run_loop_.get())
-        run_loop_->Quit();
-    }
-  }
-
-  bool ProcessingComplete() {
-    return (dispatched_reports_count_ >= expected_reports_);
-  }
-
-  void RunMessageLoop() {
-    if (ProcessingComplete())
-      return;
-    run_loop_.reset(new base::RunLoop());
-    run_loop_->Run();
-  }
-
-  base::MessageLoop message_loop_;
-  scoped_ptr<base::RunLoop> run_loop_;
-  content::TestBrowserThread ui_thread_;
-  scoped_ptr<TestingProfile> profile_;
-
-  FeedbackUploader* uploader_;
-
-  std::map<std::string, unsigned int> dispatched_reports_;
-  size_t dispatched_reports_count_;
-  size_t expected_reports_;
-};
-
-#if defined(OS_LINUX) || defined(OS_MACOSX)
-#define MAYBE_QueueMultiple QueueMultiple
-#else
-// crbug.com/330547
-#define MAYBE_QueueMultiple DISABLED_QueueMultiple
-#endif
-TEST_F(FeedbackUploaderTest, MAYBE_QueueMultiple) {
-  dispatched_reports_.clear();
-  QueueReport(kReportOne);
-  QueueReport(kReportTwo);
-  QueueReport(kReportThree);
-  QueueReport(kReportFour);
-
-  EXPECT_EQ(dispatched_reports_.size(), 4u);
-  EXPECT_EQ(dispatched_reports_[kReportOne], 1u);
-  EXPECT_EQ(dispatched_reports_[kReportTwo], 1u);
-  EXPECT_EQ(dispatched_reports_[kReportThree], 1u);
-  EXPECT_EQ(dispatched_reports_[kReportFour], 1u);
-}
-
-#if defined(OS_WIN) || defined(OS_ANDROID)
-// crbug.com/330547
-#define MAYBE_QueueMultipleWithFailures DISABLED_QueueMultipleWithFailures
-#else
-#define MAYBE_QueueMultipleWithFailures QueueMultipleWithFailures
-#endif
-TEST_F(FeedbackUploaderTest, MAYBE_QueueMultipleWithFailures) {
-  dispatched_reports_.clear();
-
-  QueueReport(kReportOne);
-  QueueReport(kReportTwo);
-  QueueReport(kReportThree);
-  QueueReport(kReportFour);
-
-  ReportFailure(kReportThree);
-  ReportFailure(kReportTwo);
-  QueueReport(kReportFive);
-
-  expected_reports_ = 7;
-  RunMessageLoop();
-
-  EXPECT_EQ(dispatched_reports_.size(), 5u);
-  EXPECT_EQ(dispatched_reports_[kReportOne], 1u);
-  EXPECT_EQ(dispatched_reports_[kReportTwo], 2u);
-  EXPECT_EQ(dispatched_reports_[kReportThree], 2u);
-  EXPECT_EQ(dispatched_reports_[kReportFour], 1u);
-  EXPECT_EQ(dispatched_reports_[kReportFive], 1u);
-}
-
-}  // namespace feedback
diff --git a/chrome/browser/feedback/feedback_util.cc b/chrome/browser/feedback/feedback_util.cc
deleted file mode 100644
index 688891a..0000000
--- a/chrome/browser/feedback/feedback_util.cc
+++ /dev/null
@@ -1,275 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/feedback/feedback_util.h"
-
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/file_util.h"
-#include "base/file_version_info.h"
-#include "base/memory/singleton.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/win/windows_version.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h"
-#include "chrome/browser/feedback/feedback_data.h"
-#include "chrome/browser/feedback/feedback_uploader.h"
-#include "chrome/browser/feedback/feedback_uploader_factory.h"
-#include "chrome/browser/metrics/variations/variations_http_header_provider.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/safe_browsing/safe_browsing_util.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_content_client.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/chrome_version_info.h"
-#include "chrome/common/metrics/metrics_log_manager.h"
-#include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/web_contents.h"
-#include "grit/generated_resources.h"
-#include "grit/locale_settings.h"
-#include "grit/theme_resources.h"
-#include "net/base/load_flags.h"
-#include "net/http/http_request_headers.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_fetcher_delegate.h"
-#include "net/url_request/url_request_status.h"
-#include "third_party/icu/source/common/unicode/locid.h"
-#include "third_party/zlib/google/zip.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "url/gurl.h"
-
-namespace {
-
-GURL GetTargetTabUrl(int session_id, int index) {
-  Browser* browser = chrome::FindBrowserWithID(session_id);
-  // Sanity checks.
-  if (!browser || index >= browser->tab_strip_model()->count())
-    return GURL();
-
-  if (index >= 0) {
-    content::WebContents* target_tab =
-        browser->tab_strip_model()->GetWebContentsAt(index);
-    if (target_tab)
-      return target_tab->GetURL();
-  }
-
-  return GURL();
-}
-
-const char kPngMimeType[] = "image/png";
-const char kArbitraryMimeType[] = "application/octet-stream";
-const char kHistogramsAttachmentName[] = "histograms.zip";
-const char kLogsAttachmentName[] = "system_logs.zip";
-
-#if defined(OS_CHROMEOS)
-const int kChromeOSProductId = 208;
-#else
-const int kChromeBrowserProductId = 237;
-#endif
-
-void AddFeedbackData(userfeedback::ExtensionSubmit* feedback_data,
-                     const std::string& key, const std::string& value) {
-  // Don't bother with empty keys or values
-  if (key == "" || value == "") return;
-  // Create log_value object and add it to the web_data object
-  userfeedback::ProductSpecificData log_value;
-  log_value.set_key(key);
-  log_value.set_value(value);
-  userfeedback::WebData* web_data = feedback_data->mutable_web_data();
-  *(web_data->add_product_specific_data()) = log_value;
-}
-
-// Adds data as an attachment to feedback_data if the data is non-empty.
-void AddAttachment(userfeedback::ExtensionSubmit* feedback_data,
-                   const char* name,
-                   std::string* data) {
-  if (data == NULL || data->empty())
-    return;
-
-  userfeedback::ProductSpecificBinaryData* attachment =
-      feedback_data->add_product_specific_binary_data();
-  attachment->set_mime_type(kArbitraryMimeType);
-  attachment->set_name(name);
-  attachment->set_data(*data);
-}
-
-}  // namespace
-
-namespace chrome {
-
-const char kAppLauncherCategoryTag[] = "AppLauncher";
-
-void ShowFeedbackPage(Browser* browser,
-                      const std::string& description_template,
-                      const std::string& category_tag) {
-  GURL page_url;
-  if (browser) {
-    page_url = GetTargetTabUrl(browser->session_id().id(),
-                               browser->tab_strip_model()->active_index());
-  }
-
-  Profile* profile = NULL;
-  if (browser) {
-    profile = browser->profile();
-  } else {
-    profile = ProfileManager::GetLastUsedProfileAllowedByPolicy();
-  }
-  if (!profile) {
-    LOG(ERROR) << "Cannot invoke feedback: No profile found!";
-    return;
-  }
-
-  // We do not want to launch on an OTR profile.
-  profile = profile->GetOriginalProfile();
-  DCHECK(profile);
-
-  extensions::FeedbackPrivateAPI* api =
-      extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get(profile);
-
-  api->RequestFeedback(description_template,
-                       category_tag,
-                       page_url);
-}
-
-}  // namespace chrome
-
-namespace feedback_util {
-
-void SendReport(scoped_refptr<FeedbackData> data) {
-  if (!data.get()) {
-    LOG(ERROR) << "SendReport called with NULL data!";
-    NOTREACHED();
-    return;
-  }
-
-  userfeedback::ExtensionSubmit feedback_data;
-  // Unused field, needs to be 0 though.
-  feedback_data.set_type_id(0);
-
-  userfeedback::CommonData* common_data = feedback_data.mutable_common_data();
-  // We're not using gaia ids, we're using the e-mail field instead.
-  common_data->set_gaia_id(0);
-  common_data->set_user_email(data->user_email());
-  common_data->set_description(data->description());
-
-  std::string chrome_locale = g_browser_process->GetApplicationLocale();
-  common_data->set_source_description_language(chrome_locale);
-
-  userfeedback::WebData* web_data = feedback_data.mutable_web_data();
-  web_data->set_url(data->page_url());
-  web_data->mutable_navigator()->set_user_agent(GetUserAgent());
-
-  gfx::Rect screen_size;
-  if (data->sys_info()) {
-    for (FeedbackData::SystemLogsMap::const_iterator i =
-        data->sys_info()->begin(); i != data->sys_info()->end(); ++i) {
-      if (FeedbackData::BelowCompressionThreshold(i->second))
-        AddFeedbackData(&feedback_data, i->first, i->second);
-    }
-
-    AddAttachment(&feedback_data, kLogsAttachmentName, data->compressed_logs());
-  }
-
-  if (data->histograms()) {
-    AddAttachment(&feedback_data,
-                  kHistogramsAttachmentName,
-                  data->compressed_histograms());
-  }
-
-  if (!data->attached_filename().empty()) {
-    // We need to use the UTF8Unsafe methods here to accomodate Windows, which
-    // uses wide strings to store filepaths.
-    std::string name = base::FilePath::FromUTF8Unsafe(
-        data->attached_filename()).BaseName().AsUTF8Unsafe();
-    AddAttachment(&feedback_data, name.c_str(), data->attached_filedata());
-  }
-
-  // NOTE: Screenshot needs to be processed after system info since we'll get
-  // the screenshot dimensions from system info.
-  if (data->image() && data->image()->size()) {
-    userfeedback::PostedScreenshot screenshot;
-    screenshot.set_mime_type(kPngMimeType);
-
-    // Set that we 'have' dimensions of the screenshot. These dimensions are
-    // ignored by the server but are a 'required' field in the protobuf.
-    userfeedback::Dimensions dimensions;
-    dimensions.set_width(0.0);
-    dimensions.set_height(0.0);
-
-    *(screenshot.mutable_dimensions()) = dimensions;
-    screenshot.set_binary_content(*data->image());
-
-    *(feedback_data.mutable_screenshot()) = screenshot;
-  }
-
-  if (data->category_tag().size())
-    feedback_data.set_bucket(data->category_tag());
-
-  // Set whether we're reporting from ChromeOS or Chrome on another platform.
-  userfeedback::ChromeData chrome_data;
-#if defined(OS_CHROMEOS)
-  chrome_data.set_chrome_platform(
-      userfeedback::ChromeData_ChromePlatform_CHROME_OS);
-  userfeedback::ChromeOsData chrome_os_data;
-  chrome_os_data.set_category(
-      userfeedback::ChromeOsData_ChromeOsCategory_OTHER);
-  *(chrome_data.mutable_chrome_os_data()) = chrome_os_data;
-  feedback_data.set_product_id(kChromeOSProductId);
-#else
-  chrome_data.set_chrome_platform(
-      userfeedback::ChromeData_ChromePlatform_CHROME_BROWSER);
-  userfeedback::ChromeBrowserData chrome_browser_data;
-  chrome_browser_data.set_category(
-      userfeedback::ChromeBrowserData_ChromeBrowserCategory_OTHER);
-  *(chrome_data.mutable_chrome_browser_data()) = chrome_browser_data;
-  feedback_data.set_product_id(kChromeBrowserProductId);
-#endif
-
-  *(feedback_data.mutable_chrome_data()) = chrome_data;
-
-  // This pointer will eventually get deleted by the PostCleanup class, after
-  // we've either managed to successfully upload the report or died trying.
-  std::string post_body;
-  feedback_data.SerializeToString(&post_body);
-
-  feedback::FeedbackUploader *uploader =
-      feedback::FeedbackUploaderFactory::GetForBrowserContext(data->profile());
-  uploader->QueueReport(post_body);
-}
-
-bool ZipString(const base::FilePath& filename,
-               const std::string& data, std::string* compressed_logs) {
-  base::FilePath temp_path;
-  base::FilePath zip_file;
-
-  // Create a temporary directory, put the logs into a file in it. Create
-  // another temporary file to receive the zip file in.
-  if (!base::CreateNewTempDirectory(base::FilePath::StringType(), &temp_path))
-    return false;
-  if (base::WriteFile(temp_path.Append(filename), data.c_str(), data.size()) ==
-      -1)
-    return false;
-
-  bool succeed = base::CreateTemporaryFile(&zip_file) &&
-      zip::Zip(temp_path, zip_file, false) &&
-      base::ReadFileToString(zip_file, compressed_logs);
-
-  base::DeleteFile(temp_path, true);
-  base::DeleteFile(zip_file, false);
-
-  return succeed;
-}
-
-}  // namespace feedback_util
diff --git a/chrome/browser/feedback/feedback_util.h b/chrome/browser/feedback/feedback_util.h
deleted file mode 100644
index 1fc9e64..0000000
--- a/chrome/browser/feedback/feedback_util.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_FEEDBACK_FEEDBACK_UTIL_H_
-#define CHROME_BROWSER_FEEDBACK_FEEDBACK_UTIL_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/files/file_path.h"
-#include "base/memory/ref_counted.h"
-#include "chrome/browser/feedback/proto/common.pb.h"
-#include "chrome/browser/feedback/proto/dom.pb.h"
-#include "chrome/browser/feedback/proto/extension.pb.h"
-#include "chrome/browser/feedback/proto/math.pb.h"
-#include "ui/gfx/rect.h"
-
-#if defined(OS_MACOSX)
-#include "base/sys_info.h"
-#elif defined(OS_WIN)
-#include "base/win/windows_version.h"
-#endif
-
-class FeedbackData;
-class Profile;
-
-namespace content {
-class WebContents;
-}
-
-namespace chrome {
-extern const char kAppLauncherCategoryTag[];
-}  // namespace chrome
-
-namespace feedback_util {
-
-  void SendReport(scoped_refptr<FeedbackData> data);
-  bool ZipString(const base::FilePath& filename,
-                 const std::string& data, std::string* compressed_data);
-
-}  // namespace feedback_util
-
-#endif  // CHROME_BROWSER_FEEDBACK_FEEDBACK_UTIL_H_
diff --git a/chrome/browser/feedback/proto/annotations.proto b/chrome/browser/feedback/proto/annotations.proto
deleted file mode 100644
index d14751a..0000000
--- a/chrome/browser/feedback/proto/annotations.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Messages containing data about the annotations drawn on the screenshot of a 
-// web page.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package userfeedback;
-
-import "math.proto";
-import "dom.proto";
-
-// An annotation drawn by the user on the screenshot of a web page.
-message Annotation {
-  // A rectangular area covered by this annotation on annotated image.
-  // The (0, 0) coordinate is placed in the top-left corner of the image.
-  // One unit corresponds to one pixel.
-  required Rectangle rectangle = 1;
-
-  // A snippet of text displayed inside annotated portion of a web page.
-  optional string snippet = 2;
-
-  // A path from root element of the document to the annotated element.
-  optional HtmlPath annotatedElementPath = 3;
-};
diff --git a/chrome/browser/feedback/proto/chrome.proto b/chrome/browser/feedback/proto/chrome.proto
deleted file mode 100644
index c721b06..0000000
--- a/chrome/browser/feedback/proto/chrome.proto
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2012 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.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package userfeedback;
-
-// Chrome Browser and Chrome OS specific data.
-message ChromeData {
-  // Encapsulates the priorities of Buganizer issues.
-  enum ChromePlatform {
-    CHROME_OS = 1;
-    CHROME_BROWSER = 2;
-  }
-
-  // What platform has a report been sent from.
-  optional ChromePlatform chrome_platform = 1 [default = CHROME_OS];
-
-  optional ChromeOsData chrome_os_data = 2;
-
-  optional ChromeBrowserData chrome_browser_data = 3;
-}
-
-message ChromeOsData {
-  enum ChromeOsCategory {
-    CONNECTIVITY = 1;
-    SYNC = 2;
-    CRASH = 3;
-    PAGE_FORMATTING_OR_LAYOUT = 4;
-    EXTENSIONS_OR_APPS = 5;
-    STANDBY_OR_RESUME = 6;
-    PHISHING_PAGE = 7;
-    OTHER = 8;
-    AUTOFILL = 9;
-  }
-
-  optional ChromeOsCategory category = 1 [default = OTHER];
-}
-
-message ChromeBrowserData{
-
-  enum ChromeBrowserCategory {
-    PAGE_FORMATTING_OR_LAYOUT = 1;
-    PAGES_NOT_LOADING = 2;
-    PLUGINS = 3;
-    TABS_OR_WINDOWS = 4;
-    SYNCED_PREFERENCES = 5;
-    CRASH = 6;
-    EXTENSIONS_OR_APPS = 7;
-    PHISHING_PAGE = 8;
-    OTHER = 9;
-    AUTOFILL = 10;
-  }
-
-  optional ChromeBrowserCategory category = 1 [default = OTHER];
-}
-
diff --git a/chrome/browser/feedback/proto/common.proto b/chrome/browser/feedback/proto/common.proto
deleted file mode 100644
index 5e028eb..0000000
--- a/chrome/browser/feedback/proto/common.proto
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Basic messages used by all systems (extension, feedbackserver,
-// silver-bullet clustering, android etc).
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package userfeedback;
-
-// Data present in all kinds of feedbacks, regardless of source (Web, Android,
-// other).
-message CommonData {
-  optional fixed64 gaia_id = 1;
-
-  // Description of the problem entered by user.
-  optional string description = 2;
-  optional string description_translated = 4;
-  optional string source_description_language = 5 [ default = "en" ];
-  optional string ui_language = 6 [ default = "en_US" ];
-
-  optional string user_email = 3;
-  
-  // Unique identifier of feedback report. If set than only one report
-  // with the same identifier is stored in the system.
-  // If you are not sure how to use it leave it not set.
-  optional string unique_report_identifier = 7;
-};
diff --git a/chrome/browser/feedback/proto/config.proto b/chrome/browser/feedback/proto/config.proto
deleted file mode 100644
index f178912..0000000
--- a/chrome/browser/feedback/proto/config.proto
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Messages containing configuration of Feedback Service
-// that control classification and processing of submitted feedbacks.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package userfeedback;
-
-// Product for which feedback can be sent: GMail, Writely etc.
-message Product {
-  required int32 id = 1;
-
-  required string name = 2;
-
-  repeated string owner = 3;
-};
-
-// Contains information needed to check whether particular
-// feedback type applies to the page user is browsing and forward
-// it's execution to a specific handler. It also carries information
-// about the creator.
-// TODO(morgwai): design new structure of Type with fields relevant
-// for android, web, selenium grouped into submessages.
-message FeedbackTypeData {
-  // index of feedback type as found in database
-  required int32 id = 1;
-
-  // Specifies whether this feedback type is currently enabled and
-  // feedback of this type can be submitted.
-  required bool enabled = 2;
-
-  // Problem name of this feedback type on Google Feedback pages.
-  required string problem_name = 3;
-
-  // Name of the product to which this feedback type belongs.
-  optional string product_name = 4;
-
-  // Tag 5 is used by some legacy data that is already in production db.
-
-  // matcher to execute against page
-  required MatcherData matcher = 6;
-
-  // Comma separated list of email addresses to which email notification
-  // is sent upon each new feedback of this type.
-  // No email is sent if this field is set to an empty string.
-  required string notification_email = 7;
-
-  // Do not use tag 8, 9, 10. They were used by a legacy field.
-
-  // Encapsulates different kind of feedback type.
-  enum Kind {
-    // Product feedback type.
-    PRODUCT = 1;
-    // Special feedback type (e.g. fixit).
-    SPECIAL = 2;
-  }
-
-  // Kind of feedback type.
-  optional Kind kind = 11 [default=PRODUCT];
-
-  // Prefix to be added to summary of notification email sent for feedback of this
-  // type.
-  optional string summary_prefix = 12;
-
-  // String template with which "Additional Info" field in extension
-  // should be initially filled.
-  optional string template = 13;
-
-  // ID of the product this feedback type belongs to.
-  optional int32 product_id = 14;
-
-  // Tag that is used for marking feedback types that require non-ordinary handling.
-  // E.g: This field is equal:
-  // "unclassified" for Unclassified feedback,
-  // "android" for android feedback
-  // "selenium" for selenium feedback
-  optional string tag = 15;
-
-  // Problem description visible in feedback extension.
-  optional string problem_description = 16;
-
-  // Visibilities of feedback type.
-  enum Visibility {
-    // feedback type visible in external extension only
-    EXTERNAL = 1;
-    // feedback type visible in internal extension only
-    INTERNAL = 2;
-  }
-
-  // Specifies the visibility of this feedback type.
-  optional Visibility visibility = 17 [default=INTERNAL];
-
-  // tag 18 was used by removed field
-
-  // Specifies Buganizer fields
-  // TODO(kaczmarek): enable once we migrated to new protos.
-  // optional BuganizerSettings buganizer_settings = 19;
-
-  // Channel via which notification about feedback should be send
-  enum NotifyChannel {
-    // Send email notification.
-    EMAIL = 1;
-    // File a bug in buganizer.
-    BUGANIZER = 2;
-    // File a bug in issue tracker.
-    ISSUE_TRACKER = 3;
-  }
-
-  // Specifies channel via which notification about feedback of this type should be sent.
-  optional NotifyChannel notify_channel = 20 [default=EMAIL];
-
-  // Granularity of notifications.
-  enum NotificationGranularity {
-    // Send notification per each feedback.
-    FEEDBACK = 1;
-    // Send notification per clustered group of similar feedbacks.
-    CLUSTER = 2;
-  }
-
-  // Specifies granularity of notifications send for feedbacks of this type.
-  optional NotificationGranularity notification_granularity = 21 [default=FEEDBACK];
-
-  // Threshold for number of feedbacks in a cluster at which notification is sent.
-  optional int32 clustering_threshold = 22 [default=5];
-};
-
-// Used to detect content relevant to particular type of feedback.
-message MatcherData {
-  // XPATH expression to match against page.
-  required string content_matcher = 1;
-
-  // Regexp matching page URL.
-  required string url_matcher = 2;
-
-  // Approval by feedback admins
-  optional bool url_matcher_approved = 3 [default=true];
-};
diff --git a/chrome/browser/feedback/proto/dom.proto b/chrome/browser/feedback/proto/dom.proto
deleted file mode 100644
index f5d1bc3..0000000
--- a/chrome/browser/feedback/proto/dom.proto
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Messages containing DOM data captured from the browser.
-// It includes the structure of the HTML document and Navigator data.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package userfeedback;
-
-// Data captured from HTMLDocument DOM object.
-message HtmlDocument {
-
-  // The value of document.URL property.
-  required string url = 1;
-
-  // The value of document.title property.
-  optional string title = 2;
-
-  // The value of document.documentElement property.
-  optional HtmlElement document_element = 3;
-};
-
-// Data captured from HTMLElement DOM object.
-message HtmlElement {
-
-  // The value of element.tagName property.
-  required string tag_name = 1;
-
-  // The value of element.id property.
-  optional string id = 2;
-
-  // The value of element.className property.
-  optional string class_name = 3;
-
-  // A list of child elements.
-  repeated HtmlElement child_element = 4;
-
-  // The value of frame.contentDocument property for FRAME and IFRAME elements.
-  optional HtmlDocument frame_content_document = 5;
-};
-
-// Data captured from DOM Navigator object.
-message Navigator {
-
-  // The value of 'navigator.appCodeName' property.
-  optional string app_code_name = 1;
-
-  // The value of 'navigator.appName' property.
-  optional string app_name = 2;
-
-  // The value of 'navigator.appVersion' property.
-  optional string app_version = 3;
-
-  // The value of 'navigator.appMinorVersion' property.
-  optional string app_minor_version = 4;
-
-  // The value of 'navigator.cookieEnabled' property.
-  optional bool cookie_enabled = 5;
-
-  // The value of 'navigator.cpuClass' property.
-  optional string cpu_class = 6;
-
-  // The value of 'navigator.onLine' property.
-  optional bool on_line = 7;
-
-  // The value of 'navigator.platform' property.
-  optional string platform = 8;
-
-  // The value of 'navigator.browserLanguage' property.
-  optional string browser_language = 9;
-
-  // The value of 'navigator.systemLanguage' property.
-  optional string system_language = 10;
-
-  // The value of 'navigator.userAgent' property.
-  optional string user_agent = 11;
-
-  // The return value of 'navigator.javaEnabled()' method.
-  optional bool java_enabled = 12;
-
-  // The return value of 'navigator.taintEnabled()' method.
-  optional bool taint_enabled = 13;
-
-  // Plugin names specified by 'navigator.plugins' property.
-  repeated string plugin_name = 14;
-};
-
-// A path in the HTML document between two elements, which are in the
-// ancestor-descendant relationship.
-message HtmlPath {
-
-  // Ordered list of zero-based indices.
-  // Empty path selects root element.
-  // Non-negative index N selects (N+1)-th child.
-  // Index -1 selects root element from frame content document.
-  repeated int32 index = 1;
-};
diff --git a/chrome/browser/feedback/proto/extension.proto b/chrome/browser/feedback/proto/extension.proto
deleted file mode 100644
index ff1fe48..0000000
--- a/chrome/browser/feedback/proto/extension.proto
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Messages sent from extension to feedback server as JSON.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package userfeedback;
-
-import "common.proto";
-import "chrome.proto";
-import "dom.proto";
-import "math.proto";
-import "web.proto";
-
-// Sent along with request for extension page when user attempts to open
-// feedback tab.
-message ExtensionPageRequestParams {
-
-  required ExtensionDetails extension_details = 1;
-
-  // Url of the page (without request params) that user wants to open
-  // feedback tool for.
-  required string url = 2;
-};
-
-message PostedScreenshot {
-
-  required string mime_type = 1;
-
-  required Dimensions dimensions = 2;
-
-  optional string base64_content = 3;
-
-  optional bytes binary_content = 4;
-};
-
-// Contains data about possible errors on the client side.
-// Describes number of attempts to send feedback and possible error codes/
-// exceptions which occured.
-message ExtensionErrors {
-
-  required int32 number_of_attempts = 1;
-
-  required string errors = 2;
-};
-
-// Sent when user hits final submit button.
-message ExtensionSubmit {
-
-  required CommonData common_data = 1;
-
-  required WebData web_data = 2;
-
-  required int32 type_id = 3;
-
-  optional PostedScreenshot screenshot = 4;
-
-  optional ChromeData chrome_data = 14;
-
-  repeated ProductSpecificBinaryData product_specific_binary_data = 15;
-
-  optional string category_tag = 16;
-
-  optional int32 product_id = 17;
-
-  optional string bucket = 18;
-};
-
-// A query for suggestions, sent when the user hits the preview button.
-message SuggestQuery {
-
-  required CommonData common_data = 1;
-
-  required WebData web_data = 2;
-
-  required int32 type_id = 3;
-
-  optional HtmlDocument html_document_structure = 4;
-
-  optional ChromeData chrome_data = 5;
-};
diff --git a/chrome/browser/feedback/proto/math.proto b/chrome/browser/feedback/proto/math.proto
deleted file mode 100644
index 6d8d5cb..0000000
--- a/chrome/browser/feedback/proto/math.proto
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Messages containing common math data structures.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package userfeedback;
-
-// 2D Dimensions.
-message Dimensions {
-  required float width = 1;
-  required float height = 2;
-};
-
-// Axis-aligned rectangle in 2D space.
-message Rectangle {
-  required float left = 1;
-  required float top = 2;
-  required float width = 3;
-  required float height = 4;
-};
diff --git a/chrome/browser/feedback/proto/web.proto b/chrome/browser/feedback/proto/web.proto
deleted file mode 100644
index 024ef29..0000000
--- a/chrome/browser/feedback/proto/web.proto
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2012 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.
-
-syntax = "proto2";
-
-package userfeedback;
-
-option optimize_for = LITE_RUNTIME;
-
-// Data present in Web related feedbacks
-
-import "annotations.proto";
-import "dom.proto";
-import "math.proto";
-
-// Data present in feedbacks sent from web extension.
-message WebData {
-  // Data captured from DOM Navigator object.
-  optional Navigator navigator = 1;
-
-  // Details of the extension from which this data was sent.
-  optional ExtensionDetails extension_details = 2;
-
-  // The URL of the document.
-  // Useful when user opts out from sending html structure.
-  optional string url = 3;
-
-  // A list of annotations.
-  repeated Annotation annotation = 4;
-
-  // The ID of the suggestion selected by the user.
-  // Possible values:
-  // - Not set if no suggestions were shown, either because the version of
-  //   the client did not support suggestions, suggestions were disabled or
-  //   no matching suggestions were found.
-  // - NONE_OF_THE_ABOVE if the user has chosen "None of the above".
-  // - Empty string if suggestions were shown but the user hasn't chosen
-  //   any of them (and also she hasn't chosen "None of the above").
-  // - Actual suggestion identifier as returned from the server.
-  optional string suggestion_id = 5;
-
-  repeated ProductSpecificData product_specific_data = 6;
-
-  // Name of the binary data stored. Replicated from
-  // ProductSpecificBinaryData.name which is stored as a separate
-  // column in Feedbacks3 megastore table.
-  repeated string product_specific_binary_data_name = 7;
-};
-
-message ExtensionDetails {
-  // Indicates browser and mpm release.
-  required string extension_version = 1;
-
-  required string protocol_version = 2;
-};
-
-// Additional data sent by the internal version.
-message InternalWebData {
-  // List of user names in google.com domain to which feedback should be sent
-  // directly apart from submitting it to server.
-  repeated string email_receiver = 1;
-
-  // Subject of the problem entered by user.
-  optional string subject = 2;
-
-  // If this flag is set then product support team should be notified
-  // immediately.
-  optional bool DEPRECATED_urgent = 3 [default = false];
-};
-
-// Product specific data. Contains one key/value pair that is specific to the
-// product for which feedback is submitted.
-message ProductSpecificData {
-  required string key = 1;
-  optional string value = 2;
-};
-
-message ProductSpecificBinaryData {
-  required string name = 1;
-
-  // mime_type of data
-  optional string mime_type = 2;
-
-  // raw data
-  optional bytes data = 3;
-};
diff --git a/chrome/browser/feedback/show_feedback_page.cc b/chrome/browser/feedback/show_feedback_page.cc
new file mode 100644
index 0000000..828dee0
--- /dev/null
+++ b/chrome/browser/feedback/show_feedback_page.cc
@@ -0,0 +1,72 @@
+// 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.
+
+#include <string>
+
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "content/public/browser/web_contents.h"
+#include "url/gurl.h"
+
+namespace {
+
+GURL GetTargetTabUrl(int session_id, int index) {
+  Browser* browser = chrome::FindBrowserWithID(session_id);
+  // Sanity checks.
+  if (!browser || index >= browser->tab_strip_model()->count())
+    return GURL();
+
+  if (index >= 0) {
+    content::WebContents* target_tab =
+        browser->tab_strip_model()->GetWebContentsAt(index);
+    if (target_tab)
+      return target_tab->GetURL();
+  }
+
+  return GURL();
+}
+
+}  // namespace
+
+namespace chrome {
+
+extern const char kAppLauncherCategoryTag[] = "AppLauncher";
+
+void ShowFeedbackPage(Browser* browser,
+                      const std::string& description_template,
+                      const std::string& category_tag) {
+  GURL page_url;
+  if (browser) {
+    page_url = GetTargetTabUrl(browser->session_id().id(),
+                               browser->tab_strip_model()->active_index());
+  }
+
+  Profile* profile = NULL;
+  if (browser) {
+    profile = browser->profile();
+  } else {
+    profile = ProfileManager::GetLastUsedProfileAllowedByPolicy();
+  }
+  if (!profile) {
+    LOG(ERROR) << "Cannot invoke feedback: No profile found!";
+    return;
+  }
+
+  // We do not want to launch on an OTR profile.
+  profile = profile->GetOriginalProfile();
+  DCHECK(profile);
+
+  extensions::FeedbackPrivateAPI* api =
+      extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get(profile);
+
+  api->RequestFeedback(description_template,
+                       category_tag,
+                       page_url);
+}
+
+}  // namespace chrome
diff --git a/chrome/browser/feedback/system_logs/system_logs_fetcher_base.h b/chrome/browser/feedback/system_logs/system_logs_fetcher_base.h
index 92e98ac..e49ea20 100644
--- a/chrome/browser/feedback/system_logs/system_logs_fetcher_base.h
+++ b/chrome/browser/feedback/system_logs/system_logs_fetcher_base.h
@@ -57,7 +57,7 @@
   void Fetch(const SysLogsFetcherCallback& callback);
 
  protected:
-  // Callback passed to all the data sources. It merges the |data| it recieves
+  // Callback passed to all the data sources. It merges the |data| it receives
   // into response_. When all the data sources have responded, it deletes their
   // objects and returns the response to the callback_. After this it
   // deletes this instance of the object.
diff --git a/chrome/browser/feedback/tracing_manager.cc b/chrome/browser/feedback/tracing_manager.cc
deleted file mode 100644
index 577a7c1..0000000
--- a/chrome/browser/feedback/tracing_manager.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/feedback/tracing_manager.h"
-
-#include "base/bind.h"
-#include "base/file_util.h"
-#include "base/location.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "base/prefs/pref_service.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/feedback/feedback_util.h"
-#include "chrome/common/pref_names.h"
-#include "content/public/browser/tracing_controller.h"
-
-namespace {
-// Only once trace manager can exist at a time.
-TracingManager* g_tracing_manager = NULL;
-// Trace IDs start at 1 and increase.
-int g_next_trace_id = 1;
-// Name of the file to store the tracing data as.
-const base::FilePath::CharType kTracingFilename[] =
-    FILE_PATH_LITERAL("tracing.json");
-}
-
-TracingManager::TracingManager()
-    : current_trace_id_(0),
-      weak_ptr_factory_(this) {
-  DCHECK(!g_tracing_manager);
-  g_tracing_manager = this;
-  StartTracing();
-}
-
-TracingManager::~TracingManager() {
-  DCHECK(g_tracing_manager == this);
-  g_tracing_manager = NULL;
-}
-
-int TracingManager::RequestTrace() {
-  // Return the current trace if one is being collected.
-  if (current_trace_id_)
-    return current_trace_id_;
-
-  current_trace_id_ = g_next_trace_id;
-  ++g_next_trace_id;
-  content::TracingController::GetInstance()->DisableRecording(
-      base::FilePath(),
-      base::Bind(&TracingManager::OnTraceDataCollected,
-                 weak_ptr_factory_.GetWeakPtr()));
-  return current_trace_id_;
-}
-
-bool TracingManager::GetTraceData(int id, const TraceDataCallback& callback) {
-  // If a trace is being collected currently, send it via callback when
-  // complete.
-  if (current_trace_id_) {
-    // Only allow one trace data request at a time.
-    if (trace_callback_.is_null()) {
-      trace_callback_ = callback;
-      return true;
-    } else {
-      return false;
-    }
-  } else {
-    std::map<int, scoped_refptr<base::RefCountedString> >::iterator data =
-        trace_data_.find(id);
-    if (data == trace_data_.end())
-      return false;
-
-    // Always return the data asychronously, so the behavior is consistant.
-    base::MessageLoopProxy::current()->PostTask(
-        FROM_HERE,
-        base::Bind(callback, data->second));
-    return true;
-  }
-}
-
-void TracingManager::DiscardTraceData(int id) {
-  trace_data_.erase(id);
-
-  // If the trace is discarded before it is complete, clean up the accumulators.
-  if (id == current_trace_id_) {
-    current_trace_id_ = 0;
-
-    // If the trace has already been requested, provide an empty string.
-    if (!trace_callback_.is_null()) {
-      trace_callback_.Run(scoped_refptr<base::RefCountedString>());
-      trace_callback_.Reset();
-    }
-  }
-}
-
-void TracingManager::StartTracing() {
-  content::TracingController::GetInstance()->EnableRecording(
-      "", content::TracingController::DEFAULT_OPTIONS,
-      content::TracingController::EnableRecordingDoneCallback());
-}
-
-void TracingManager::OnTraceDataCollected(const base::FilePath& path) {
-  if (!current_trace_id_)
-    return;
-
-  std::string data;
-  if (!base::ReadFileToString(path, &data)) {
-    LOG(ERROR) << "Failed to read trace data from: " << path.value();
-    return;
-  }
-  base::DeleteFile(path, false);
-
-  std::string output_val;
-  feedback_util::ZipString(
-      base::FilePath(kTracingFilename), data, &output_val);
-
-  scoped_refptr<base::RefCountedString> output(
-      base::RefCountedString::TakeString(&output_val));
-
-  trace_data_[current_trace_id_] = output;
-
-  if (!trace_callback_.is_null()) {
-    trace_callback_.Run(output);
-    trace_callback_.Reset();
-  }
-
-  current_trace_id_ = 0;
-
-  // Tracing has to be restarted asynchronous, so the TracingController can
-  // clean up.
-  base::MessageLoopProxy::current()->PostTask(
-      FROM_HERE,
-      base::Bind(&TracingManager::StartTracing,
-                 weak_ptr_factory_.GetWeakPtr()));
-}
-
-// static
-scoped_ptr<TracingManager> TracingManager::Create() {
-  if (g_tracing_manager)
-    return scoped_ptr<TracingManager>();
-  return scoped_ptr<TracingManager>(new TracingManager());
-}
-
-TracingManager* TracingManager::Get() {
-  return g_tracing_manager;
-}
diff --git a/chrome/browser/feedback/tracing_manager.h b/chrome/browser/feedback/tracing_manager.h
deleted file mode 100644
index 5fd5588..0000000
--- a/chrome/browser/feedback/tracing_manager.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_FEEDBACK_TRACING_MANAGER_H_
-#define CHROME_BROWSER_FEEDBACK_TRACING_MANAGER_H_
-
-#include <map>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-
-namespace base {
-
-class RefCountedString;
-class FilePath;
-
-}
-// Callback used for getting the output of a trace.
-typedef base::Callback<void(scoped_refptr<base::RefCountedString> trace_data)>
-    TraceDataCallback;
-
-// This class is used to manage performance metrics that can be attached to
-// feedback reports.  This class is a Singleton that is owned by the preference
-// system.  It should only be created when it is enabled, and should only be
-// accessed elsewhere via Get().
-//
-// When a performance trace is desired, TracingManager::Get()->RequestTrace()
-// should be invoked.  The TracingManager will then start preparing a zipped
-// version of the performance data.  That data can then be requested via
-// GetTraceData().  When the data is no longer needed, it should be discarded
-// via DiscardTraceData().
-class TracingManager {
- public:
-  virtual ~TracingManager();
-
-  // Create a TracingManager.  Can only be called when none exists.
-  static scoped_ptr<TracingManager> Create();
-
-  // Get the current TracingManager.  Returns NULL if one doesn't exist.
-  static TracingManager* Get();
-
-  // Request a trace ending at the current time.  If a trace is already being
-  // collected, the id for that trace is returned.
-  int RequestTrace();
-
-  // Get the trace data for |id|.  On success, true is returned, and the data is
-  // returned via |callback|.  Returns false on failure.
-  bool GetTraceData(int id, const TraceDataCallback& callback);
-
-  // Discard the data for trace |id|.
-  void DiscardTraceData(int id);
-
- private:
-  TracingManager();
-
-  void StartTracing();
-  void OnTraceDataCollected(const base::FilePath& path);
-
-  // ID of the trace that is being collected.
-  int current_trace_id_;
-
-  // Mapping of trace ID to trace data.
-  std::map<int, scoped_refptr<base::RefCountedString> > trace_data_;
-
-  // Callback for the current trace request.
-  TraceDataCallback trace_callback_;
-
-  base::WeakPtrFactory<TracingManager> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(TracingManager);
-};
-
-#endif  // CHROME_BROWSER_FEEDBACK_TRACING_MANAGER_H_
-
diff --git a/chrome/browser/first_run/first_run_browsertest.cc b/chrome/browser/first_run/first_run_browsertest.cc
index 5c7298f..5104498 100644
--- a/chrome/browser/first_run/first_run_browsertest.cc
+++ b/chrome/browser/first_run/first_run_browsertest.cc
@@ -292,6 +292,8 @@
         chrome_prefs::internals::kSettingsEnforcementGroupEnforceOnload,
         chrome_prefs::internals::kSettingsEnforcementGroupEnforceAlways,
         chrome_prefs::internals::
-            kSettingsEnforcementGroupEnforceAlwaysWithExtensions));
+            kSettingsEnforcementGroupEnforceAlwaysWithExtensions,
+        chrome_prefs::internals::
+            kSettingsEnforcementGroupEnforceAlwaysWithExtensionsAndDSE));
 
 #endif  // !defined(OS_CHROMEOS)
diff --git a/chrome/browser/guest_view/ad_view/ad_view_guest.cc b/chrome/browser/guest_view/ad_view/ad_view_guest.cc
index b09b8df..165c9f4 100644
--- a/chrome/browser/guest_view/ad_view/ad_view_guest.cc
+++ b/chrome/browser/guest_view/ad_view/ad_view_guest.cc
@@ -14,7 +14,9 @@
 
 AdViewGuest::AdViewGuest(WebContents* guest_web_contents,
                          const std::string& extension_id)
-    : GuestView<AdViewGuest>(guest_web_contents, extension_id),
+    : GuestView<AdViewGuest>(guest_web_contents,
+                             extension_id,
+                             base::WeakPtr<GuestViewBase>()),
       WebContentsObserver(guest_web_contents) {
 }
 
diff --git a/chrome/browser/guest_view/guest_view.h b/chrome/browser/guest_view/guest_view.h
index 84b9b08..3633b03 100644
--- a/chrome/browser/guest_view/guest_view.h
+++ b/chrome/browser/guest_view/guest_view.h
@@ -30,8 +30,9 @@
 
  protected:
   GuestView(content::WebContents* guest_web_contents,
-            const std::string& embedder_extension_id)
-      : GuestViewBase(guest_web_contents, embedder_extension_id) {}
+            const std::string& embedder_extension_id,
+            const base::WeakPtr<GuestViewBase>& opener)
+      : GuestViewBase(guest_web_contents, embedder_extension_id, opener) {}
 
  private:
   DISALLOW_COPY_AND_ASSIGN(GuestView);
diff --git a/chrome/browser/guest_view/guest_view_base.cc b/chrome/browser/guest_view/guest_view_base.cc
index a6ea195..a9bcbbf 100644
--- a/chrome/browser/guest_view/guest_view_base.cc
+++ b/chrome/browser/guest_view/guest_view_base.cc
@@ -7,6 +7,7 @@
 #include "base/lazy_instance.h"
 #include "chrome/browser/guest_view/ad_view/ad_view_guest.h"
 #include "chrome/browser/guest_view/guest_view_constants.h"
+#include "chrome/browser/guest_view/guest_view_manager.h"
 #include "chrome/browser/guest_view/web_view/web_view_guest.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/content_settings.h"
@@ -20,11 +21,6 @@
 
 namespace {
 
-// <embedder_process_id, guest_instance_id> => GuestViewBase*
-typedef std::map<std::pair<int, int>, GuestViewBase*> EmbedderGuestViewMap;
-static base::LazyInstance<EmbedderGuestViewMap> embedder_guestview_map =
-    LAZY_INSTANCE_INITIALIZER;
-
 typedef std::map<WebContents*, GuestViewBase*> WebContentsGuestViewMap;
 static base::LazyInstance<WebContentsGuestViewMap> webcontents_guestview_map =
     LAZY_INSTANCE_INITIALIZER;
@@ -44,7 +40,8 @@
 }
 
 GuestViewBase::GuestViewBase(WebContents* guest_web_contents,
-                             const std::string& embedder_extension_id)
+                             const std::string& embedder_extension_id,
+                             const base::WeakPtr<GuestViewBase>& opener)
     : guest_web_contents_(guest_web_contents),
       embedder_web_contents_(NULL),
       embedder_extension_id_(embedder_extension_id),
@@ -52,17 +49,20 @@
       browser_context_(guest_web_contents->GetBrowserContext()),
       guest_instance_id_(guest_web_contents->GetEmbeddedInstanceID()),
       view_instance_id_(guestview::kInstanceIDNone),
+      opener_(opener),
       weak_ptr_factory_(this) {
   webcontents_guestview_map.Get().insert(
       std::make_pair(guest_web_contents, this));
 }
 
 // static
-GuestViewBase* GuestViewBase::Create(WebContents* guest_web_contents,
-                                     const std::string& embedder_extension_id,
-                                     const std::string& view_type) {
+GuestViewBase* GuestViewBase::Create(
+    WebContents* guest_web_contents,
+    const std::string& embedder_extension_id,
+    const std::string& view_type,
+    const base::WeakPtr<GuestViewBase>& opener) {
   if (view_type == "webview") {
-    return new WebViewGuest(guest_web_contents, embedder_extension_id);
+    return new WebViewGuest(guest_web_contents, embedder_extension_id, opener);
   } else if (view_type == "adview") {
     return new AdViewGuest(guest_web_contents, embedder_extension_id);
   }
@@ -80,10 +80,18 @@
 // static
 GuestViewBase* GuestViewBase::From(int embedder_process_id,
                                    int guest_instance_id) {
-  EmbedderGuestViewMap* guest_map = embedder_guestview_map.Pointer();
-  EmbedderGuestViewMap::iterator it =
-      guest_map->find(std::make_pair(embedder_process_id, guest_instance_id));
-  return it == guest_map->end() ? NULL : it->second;
+  content::RenderProcessHost* host =
+      content::RenderProcessHost::FromID(embedder_process_id);
+  if (!host)
+    return NULL;
+
+  content::WebContents* guest_web_contents =
+      GuestViewManager::FromBrowserContext(host->GetBrowserContext())->
+          GetGuestByInstanceIDSafely(guest_instance_id, embedder_process_id);
+  if (!guest_web_contents)
+    return NULL;
+
+  return GuestViewBase::FromWebContents(guest_web_contents);
 }
 
 // static
@@ -128,6 +136,10 @@
                                   incognito));
 }
 
+base::WeakPtr<GuestViewBase> GuestViewBase::AsWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 void GuestViewBase::Attach(content::WebContents* embedder_web_contents,
                            const base::DictionaryValue& args) {
   embedder_web_contents_ = embedder_web_contents;
@@ -136,7 +148,6 @@
   args.GetInteger(guestview::kParameterInstanceId, &view_instance_id_);
 
   std::pair<int, int> key(embedder_render_process_id_, guest_instance_id_);
-  embedder_guestview_map.Get().insert(std::make_pair(key, this));
 
   // GuestViewBase::Attach is called prior to initialization (and initial
   // navigation) of the guest in the content layer in order to permit mapping
@@ -154,9 +165,23 @@
                  weak_ptr_factory_.GetWeakPtr()));
 }
 
+WebContents* GuestViewBase::GetOpener() const {
+  if (!opener_)
+    return NULL;
+  return opener_->guest_web_contents();
+}
+
+void GuestViewBase::SetOpener(WebContents* web_contents) {
+  GuestViewBase* guest = FromWebContents(web_contents);
+  if (guest && guest->IsViewType(GetViewType())) {
+    opener_ = guest->AsWeakPtr();
+    return;
+  }
+  opener_ = base::WeakPtr<GuestViewBase>();
+}
+
 GuestViewBase::~GuestViewBase() {
   std::pair<int, int> key(embedder_render_process_id_, guest_instance_id_);
-  embedder_guestview_map.Get().erase(key);
 
   webcontents_guestview_map.Get().erase(guest_web_contents());
 
diff --git a/chrome/browser/guest_view/guest_view_base.h b/chrome/browser/guest_view/guest_view_base.h
index 76ea724..3fe02f4 100644
--- a/chrome/browser/guest_view/guest_view_base.h
+++ b/chrome/browser/guest_view/guest_view_base.h
@@ -39,15 +39,16 @@
   // Returns a *ViewGuest if this GuestView is of the given view type.
   template <typename T>
   T* As() {
-    if (!strcmp(GetViewType(), T::Type)) {
+    if (IsViewType(T::Type))
       return static_cast<T*>(this);
-    }
+
     return NULL;
   }
 
   static GuestViewBase* Create(content::WebContents* guest_web_contents,
                                const std::string& embedder_extension_id,
-                               const std::string& view_type);
+                               const std::string& view_type,
+                               const base::WeakPtr<GuestViewBase>& opener);
 
   static GuestViewBase* FromWebContents(content::WebContents* web_contents);
 
@@ -71,6 +72,12 @@
 
   virtual const char* GetViewType() const = 0;
 
+  bool IsViewType(const char* const view_type) const {
+    return !strcmp(GetViewType(), view_type);
+  }
+
+  base::WeakPtr<GuestViewBase> AsWeakPtr();
+
   virtual void Attach(content::WebContents* embedder_web_contents,
                       const base::DictionaryValue& args);
 
@@ -106,9 +113,14 @@
   // Returns the embedder's process ID.
   int embedder_render_process_id() const { return embedder_render_process_id_; }
 
+  // BrowserPluginGuestDelegate implementation.
+  virtual content::WebContents* GetOpener() const OVERRIDE;
+  virtual void SetOpener(content::WebContents* opener) OVERRIDE;
+
  protected:
   GuestViewBase(content::WebContents* guest_web_contents,
-                const std::string& embedder_extension_id);
+                const std::string& embedder_extension_id,
+                const base::WeakPtr<GuestViewBase>& opener);
   virtual ~GuestViewBase();
 
   // Dispatches an event |event_name| to the embedder with the |event| fields.
@@ -133,6 +145,9 @@
   // the guest is attached to a particular embedder.
   std::deque<linked_ptr<Event> > pending_events_;
 
+  // The opener guest view.
+  base::WeakPtr<GuestViewBase> opener_;
+
   // This is used to ensure pending tasks will not fire after this object is
   // destroyed.
   base::WeakPtrFactory<GuestViewBase> weak_ptr_factory_;
diff --git a/chrome/browser/guest_view/guest_view_constants.cc b/chrome/browser/guest_view/guest_view_constants.cc
index 844c3e1..b12c41c 100644
--- a/chrome/browser/guest_view/guest_view_constants.cc
+++ b/chrome/browser/guest_view/guest_view_constants.cc
@@ -17,6 +17,7 @@
 const char kParameterInstanceId[] = "instanceId";
 
 // Other.
+const char kGuestViewManagerKeyName[] = "guest_view_manager";
 const int kInstanceIDNone = 0;
 
 }  // namespace guestview
diff --git a/chrome/browser/guest_view/guest_view_constants.h b/chrome/browser/guest_view/guest_view_constants.h
index dbdfb62..a32d039 100644
--- a/chrome/browser/guest_view/guest_view_constants.h
+++ b/chrome/browser/guest_view/guest_view_constants.h
@@ -20,6 +20,7 @@
 extern const char kParameterInstanceId[];
 
 // Other.
+extern const char kGuestViewManagerKeyName[];
 extern const int kInstanceIDNone;
 
 }  // namespace guestview
diff --git a/chrome/browser/guest_view/guest_view_manager.cc b/chrome/browser/guest_view/guest_view_manager.cc
new file mode 100644
index 0000000..2db79a2
--- /dev/null
+++ b/chrome/browser/guest_view/guest_view_manager.cc
@@ -0,0 +1,223 @@
+// 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.
+
+#include "chrome/browser/guest_view/guest_view_manager.h"
+
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/guest_view/guest_view_base.h"
+#include "chrome/browser/guest_view/guest_view_constants.h"
+#include "chrome/browser/profiles/profile.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/user_metrics.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/common/result_codes.h"
+#include "extensions/browser/extension_system.h"
+#include "url/gurl.h"
+
+using content::BrowserContext;
+using content::SiteInstance;
+using content::WebContents;
+
+// A WebContents does not immediately have a RenderProcessHost. It acquires one
+// on initial navigation. This observer exists until that initial navigation in
+// order to grab the ID if tis RenderProcessHost so that it can register it as
+// a guest.
+class GuestWebContentsObserver
+    : public content::WebContentsObserver {
+ public:
+  explicit GuestWebContentsObserver(WebContents* guest_web_contents)
+      : WebContentsObserver(guest_web_contents) {
+  }
+
+  virtual ~GuestWebContentsObserver() {
+  }
+
+  // WebContentsObserver:
+  virtual void DidStartProvisionalLoadForFrame(
+      int64 frame_id,
+      int64 parent_frame_id,
+      bool is_main_frame,
+      const GURL& validated_url,
+      bool is_error_page,
+      bool is_iframe_srcdoc,
+      content::RenderViewHost* render_view_host) OVERRIDE {
+    GuestViewManager::FromBrowserContext(web_contents()->GetBrowserContext())->
+        AddRenderProcessHostID(web_contents()->GetRenderProcessHost()->GetID());
+    delete this;
+  }
+
+  virtual void WebContentsDestroyed() OVERRIDE {
+    delete this;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GuestWebContentsObserver);
+};
+
+GuestViewManager::GuestViewManager(content::BrowserContext* context)
+    : current_instance_id_(0),
+      context_(context) {}
+
+GuestViewManager::~GuestViewManager() {}
+
+// static.
+GuestViewManager* GuestViewManager::FromBrowserContext(
+    BrowserContext* context) {
+  GuestViewManager* guest_manager =
+      static_cast<GuestViewManager*>(context->GetUserData(
+          guestview::kGuestViewManagerKeyName));
+  if (!guest_manager) {
+    guest_manager = new GuestViewManager(context);
+    context->SetUserData(guestview::kGuestViewManagerKeyName, guest_manager);
+  }
+  return guest_manager;
+}
+
+content::WebContents* GuestViewManager::GetGuestByInstanceIDSafely(
+    int guest_instance_id,
+    int embedder_render_process_id) {
+  if (!CanEmbedderAccessInstanceIDMaybeKill(embedder_render_process_id,
+                                            guest_instance_id)) {
+    return NULL;
+  }
+  return GetGuestByInstanceID(guest_instance_id, embedder_render_process_id);
+}
+
+int GuestViewManager::GetNextInstanceID() {
+  return ++current_instance_id_;
+}
+
+void GuestViewManager::AddGuest(int guest_instance_id,
+                                WebContents* guest_web_contents) {
+  DCHECK(guest_web_contents_by_instance_id_.find(guest_instance_id) ==
+         guest_web_contents_by_instance_id_.end());
+  guest_web_contents_by_instance_id_[guest_instance_id] = guest_web_contents;
+  // This will add the RenderProcessHost ID when we get one.
+  new GuestWebContentsObserver(guest_web_contents);
+}
+
+void GuestViewManager::RemoveGuest(int guest_instance_id) {
+  GuestInstanceMap::iterator it =
+      guest_web_contents_by_instance_id_.find(guest_instance_id);
+  DCHECK(it != guest_web_contents_by_instance_id_.end());
+  render_process_host_id_multiset_.erase(
+      it->second->GetRenderProcessHost()->GetID());
+  guest_web_contents_by_instance_id_.erase(it);
+}
+
+void GuestViewManager::MaybeGetGuestByInstanceIDOrKill(
+    int guest_instance_id,
+    int embedder_render_process_id,
+    const GuestByInstanceIDCallback& callback) {
+  if (!CanEmbedderAccessInstanceIDMaybeKill(embedder_render_process_id,
+                                            guest_instance_id)) {
+    // If we kill the embedder, then don't bother calling back.
+    return;
+  }
+  content::WebContents* guest_web_contents =
+      GetGuestByInstanceID(guest_instance_id, embedder_render_process_id);
+  callback.Run(guest_web_contents);
+}
+
+SiteInstance* GuestViewManager::GetGuestSiteInstance(
+    const GURL& guest_site) {
+  for (GuestInstanceMap::const_iterator it =
+       guest_web_contents_by_instance_id_.begin();
+       it != guest_web_contents_by_instance_id_.end(); ++it) {
+    if (it->second->GetSiteInstance()->GetSiteURL() == guest_site)
+      return it->second->GetSiteInstance();
+  }
+  return NULL;
+}
+
+bool GuestViewManager::ForEachGuest(WebContents* embedder_web_contents,
+                                    const GuestCallback& callback) {
+  for (GuestInstanceMap::iterator it =
+           guest_web_contents_by_instance_id_.begin();
+       it != guest_web_contents_by_instance_id_.end(); ++it) {
+    WebContents* guest = it->second;
+    if (embedder_web_contents != guest->GetEmbedderWebContents())
+      continue;
+
+    if (callback.Run(guest))
+      return true;
+  }
+  return false;
+}
+
+void GuestViewManager::AddRenderProcessHostID(int render_process_host_id) {
+  render_process_host_id_multiset_.insert(render_process_host_id);
+}
+
+content::WebContents* GuestViewManager::GetGuestByInstanceID(
+    int guest_instance_id,
+    int embedder_render_process_id) {
+  GuestInstanceMap::const_iterator it =
+      guest_web_contents_by_instance_id_.find(guest_instance_id);
+  if (it == guest_web_contents_by_instance_id_.end())
+    return NULL;
+  return it->second;
+}
+
+bool GuestViewManager::CanEmbedderAccessInstanceIDMaybeKill(
+    int embedder_render_process_id,
+    int guest_instance_id) {
+  if (!CanEmbedderAccessInstanceID(embedder_render_process_id,
+                                  guest_instance_id)) {
+    // The embedder process is trying to access a guest it does not own.
+    content::RecordAction(
+        base::UserMetricsAction("BadMessageTerminate_BPGM"));
+    base::KillProcess(
+        content::RenderProcessHost::FromID(embedder_render_process_id)->
+            GetHandle(),
+        content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
+    return false;
+  }
+  return true;
+}
+
+bool GuestViewManager::CanEmbedderAccessInstanceID(
+    int embedder_render_process_id,
+    int guest_instance_id) {
+  // The embedder is trying to access a guest with a negative or zero
+  // instance ID.
+  if (guest_instance_id <= guestview::kInstanceIDNone)
+    return false;
+
+  // The embedder is trying to access an instance ID that has not yet been
+  // allocated by GuestViewManager. This could cause instance ID
+  // collisions in the future, and potentially give one embedder access to a
+  // guest it does not own.
+  if (guest_instance_id > current_instance_id_)
+    return false;
+
+  GuestInstanceMap::const_iterator it =
+      guest_web_contents_by_instance_id_.find(guest_instance_id);
+  if (it == guest_web_contents_by_instance_id_.end())
+    return true;
+
+  GuestViewBase* guest_view = GuestViewBase::FromWebContents(it->second);
+  if (!guest_view)
+    return false;
+
+  return CanEmbedderAccessGuest(embedder_render_process_id, guest_view);
+}
+
+bool GuestViewManager::CanEmbedderAccessGuest(int embedder_render_process_id,
+                                              GuestViewBase* guest) {
+  // The embedder can access the guest if it has not been attached and its
+  // opener's embedder lives in the same process as the given embedder.
+  if (!guest->attached()) {
+    if (!guest->GetOpener())
+      return false;
+
+    return embedder_render_process_id ==
+        guest->GetOpener()->GetEmbedderWebContents()->GetRenderProcessHost()->
+            GetID();
+  }
+
+  return embedder_render_process_id ==
+      guest->embedder_web_contents()->GetRenderProcessHost()->GetID();
+}
diff --git a/chrome/browser/guest_view/guest_view_manager.h b/chrome/browser/guest_view/guest_view_manager.h
new file mode 100644
index 0000000..b26ae9c
--- /dev/null
+++ b/chrome/browser/guest_view/guest_view_manager.h
@@ -0,0 +1,87 @@
+// 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.
+
+#ifndef CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_MANAGER_H_
+#define CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_MANAGER_H_
+
+#include <map>
+
+#include "base/lazy_instance.h"
+#include "base/macros.h"
+#include "content/public/browser/browser_plugin_guest_manager_delegate.h"
+#include "content/public/browser/site_instance.h"
+#include "content/public/browser/web_contents.h"
+
+class GuestViewBase;
+class GuestWebContentsObserver;
+class GURL;
+
+namespace content {
+class BrowserContext;
+}  // namespace content
+
+class GuestViewManager : public content::BrowserPluginGuestManagerDelegate,
+                         public base::SupportsUserData::Data {
+ public:
+  explicit GuestViewManager(content::BrowserContext* context);
+  virtual ~GuestViewManager();
+
+  static GuestViewManager* FromBrowserContext(content::BrowserContext* context);
+
+  // Returns the guest WebContents associated with the given |guest_instance_id|
+  // if the provided |embedder_render_process_id| is allowed to access it.
+  // If the embedder is not allowed access, the embedder will be killed, and
+  // this method will return NULL. If no WebContents exists with the given
+  // instance ID, then NULL will also be returned.
+  content::WebContents* GetGuestByInstanceIDSafely(
+      int guest_instance_id,
+      int embedder_render_process_id);
+
+  // BrowserPluginGuestManagerDelegate implementation.
+  virtual int GetNextInstanceID() OVERRIDE;
+  virtual void AddGuest(int guest_instance_id,
+                        content::WebContents* guest_web_contents) OVERRIDE;
+  virtual void RemoveGuest(int guest_instance_id) OVERRIDE;
+  virtual void MaybeGetGuestByInstanceIDOrKill(
+      int guest_instance_id,
+      int embedder_render_process_id,
+      const GuestByInstanceIDCallback& callback) OVERRIDE;
+  virtual content::SiteInstance* GetGuestSiteInstance(
+      const GURL& guest_site) OVERRIDE;
+  virtual bool ForEachGuest(content::WebContents* embedder_web_contents,
+                            const GuestCallback& callback) OVERRIDE;
+
+ private:
+  friend class GuestWebContentsObserver;
+
+  void AddRenderProcessHostID(int render_process_host_id);
+
+  content::WebContents* GetGuestByInstanceID(
+      int guest_instance_id,
+      int embedder_render_process_id);
+
+  bool CanEmbedderAccessInstanceIDMaybeKill(
+      int embedder_render_process_id,
+      int guest_instance_id);
+
+  bool CanEmbedderAccessInstanceID(int embedder_render_process_id,
+                                   int guest_instance_id);
+
+  static bool CanEmbedderAccessGuest(int embedder_render_process_id,
+                                     GuestViewBase* guest);
+
+  // Counts RenderProcessHost IDs of GuestViewBases.
+  std::multiset<int> render_process_host_id_multiset_;
+
+  // Contains guests' WebContents, mapping from their instance ids.
+  typedef std::map<int, content::WebContents*> GuestInstanceMap;
+  GuestInstanceMap guest_web_contents_by_instance_id_;
+
+  int current_instance_id_;
+  content::BrowserContext* context_;
+
+  DISALLOW_COPY_AND_ASSIGN(GuestViewManager);
+};
+
+#endif  // CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_MANAGER_H_
diff --git a/chrome/browser/guest_view/web_view/web_view_constants.cc b/chrome/browser/guest_view/web_view/web_view_constants.cc
index 408d1ee..493576a 100644
--- a/chrome/browser/guest_view/web_view/web_view_constants.cc
+++ b/chrome/browser/guest_view/web_view/web_view_constants.cc
@@ -10,6 +10,7 @@
 const char kEventClose[] = "webview.onClose";
 const char kEventConsoleMessage[] = "webview.onConsoleMessage";
 const char kEventContentLoad[] = "webview.onContentLoad";
+const char kEventContextMenu[] = "webview.contextmenu";
 const char kEventDialog[] = "webview.onDialog";
 const char kEventExit[] = "webview.onExit";
 const char kEventFindReply[] = "webview.onFindReply";
@@ -27,6 +28,7 @@
 const char kEventZoomChange[] = "webview.onZoomChange";
 
 // Parameters/properties on events.
+const char kContextMenuItems[] = "items";
 const char kDefaultPromptText[] = "defaultPromptText";
 const char kFindSearchText[] = "searchText";
 const char kFindFinalUpdate[] = "finalUpdate";
@@ -77,6 +79,8 @@
 const char kParameterUserAgentOverride[] = "userAgentOverride";
 
 // Miscellaneous.
+const char kMenuItemCommandId[] = "commandId";
+const char kMenuItemLabel[] = "label";
 const unsigned int kMaxOutstandingPermissionRequests = 1024;
 const int kInvalidPermissionRequestID = 0;
 
diff --git a/chrome/browser/guest_view/web_view/web_view_constants.h b/chrome/browser/guest_view/web_view/web_view_constants.h
index ff50895..96c9e97 100644
--- a/chrome/browser/guest_view/web_view/web_view_constants.h
+++ b/chrome/browser/guest_view/web_view/web_view_constants.h
@@ -13,6 +13,7 @@
 extern const char kEventClose[];
 extern const char kEventConsoleMessage[];
 extern const char kEventContentLoad[];
+extern const char kEventContextMenu[];
 extern const char kEventDialog[];
 extern const char kEventExit[];
 extern const char kEventFindReply[];
@@ -30,6 +31,7 @@
 extern const char kEventZoomChange[];
 
 // Parameters/properties on events.
+extern const char kContextMenuItems[];
 extern const char kDefaultPromptText[];
 extern const char kFindSearchText[];
 extern const char kFindFinalUpdate[];
@@ -81,6 +83,8 @@
 extern const char kParameterUserAgentOverride[];
 
 // Miscellaneous.
+extern const char kMenuItemCommandId[];
+extern const char kMenuItemLabel[];
 extern const unsigned int kMaxOutstandingPermissionRequests;
 extern const int kInvalidPermissionRequestID;
 
diff --git a/chrome/browser/guest_view/web_view/web_view_guest.cc b/chrome/browser/guest_view/web_view/web_view_guest.cc
index 4575e66..b29d103 100644
--- a/chrome/browser/guest_view/web_view/web_view_guest.cc
+++ b/chrome/browser/guest_view/web_view/web_view_guest.cc
@@ -17,6 +17,8 @@
 #include "chrome/browser/guest_view/guest_view_constants.h"
 #include "chrome/browser/guest_view/web_view/web_view_constants.h"
 #include "chrome/browser/guest_view/web_view/web_view_permission_types.h"
+#include "chrome/browser/renderer_context_menu/context_menu_delegate.h"
+#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
 #include "chrome/common/chrome_version_info.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/geolocation_permission_context.h"
@@ -40,6 +42,7 @@
 #include "extensions/common/constants.h"
 #include "net/base/net_errors.h"
 #include "third_party/WebKit/public/web/WebFindOptions.h"
+#include "ui/base/models/simple_menu_model.h"
 
 #if defined(ENABLE_PLUGINS)
 #include "chrome/browser/guest_view/web_view/plugin_permission_helper.h"
@@ -129,11 +132,15 @@
 }  // namespace
 
 WebViewGuest::WebViewGuest(WebContents* guest_web_contents,
-                           const std::string& extension_id)
-    : GuestView<WebViewGuest>(guest_web_contents, extension_id),
+                           const std::string& embedder_extension_id,
+                           const base::WeakPtr<GuestViewBase>& opener)
+   :  GuestView<WebViewGuest>(guest_web_contents,
+                              embedder_extension_id,
+                              opener),
       WebContentsObserver(guest_web_contents),
       script_executor_(new extensions::ScriptExecutor(guest_web_contents,
                                                       &script_observers_)),
+      pending_context_menu_request_id_(0),
       next_permission_request_id_(0),
       is_overriding_user_agent_(false),
       pending_reload_on_attachment_(false),
@@ -263,6 +270,22 @@
   }
 }
 
+// static
+scoped_ptr<base::ListValue> WebViewGuest::MenuModelToValue(
+    const ui::SimpleMenuModel& menu_model) {
+  scoped_ptr<base::ListValue> items(new base::ListValue());
+  for (int i = 0; i < menu_model.GetItemCount(); ++i) {
+    base::DictionaryValue* item_value = new base::DictionaryValue();
+    // TODO(lazyboy): We need to expose some kind of enum equivalent of
+    // |command_id| instead of plain integers.
+    item_value->SetInteger(webview::kMenuItemCommandId,
+                           menu_model.GetCommandIdAt(i));
+    item_value->SetString(webview::kMenuItemLabel, menu_model.GetLabelAt(i));
+    items->Append(item_value);
+  }
+  return items.Pass();
+}
+
 void WebViewGuest::Attach(WebContents* embedder_web_contents,
                           const base::DictionaryValue& args) {
   std::string user_agent_override;
@@ -278,6 +301,26 @@
   AddWebViewToExtensionRendererState();
 }
 
+bool WebViewGuest::HandleContextMenu(
+    const content::ContextMenuParams& params) {
+  ContextMenuDelegate* menu_delegate =
+      ContextMenuDelegate::FromWebContents(guest_web_contents());
+  DCHECK(menu_delegate);
+
+  pending_menu_ = menu_delegate->BuildMenu(guest_web_contents(), params);
+
+  // Pass it to embedder.
+  int request_id = ++pending_context_menu_request_id_;
+  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
+  scoped_ptr<base::ListValue> items =
+      MenuModelToValue(pending_menu_->menu_model());
+  args->Set(webview::kContextMenuItems, items.release());
+  args->SetInteger(webview::kRequestId, request_id);
+  DispatchEvent(new GuestViewBase::Event(webview::kEventContextMenu,
+                                         args.Pass()));
+  return true;
+}
+
 void WebViewGuest::AddMessageToConsole(int32 level,
                                        const base::string16& message,
                                        int32 line_no,
@@ -748,14 +791,14 @@
   DispatchEvent(new GuestViewBase::Event(webview::kEventLoadStop, args.Pass()));
 }
 
-void WebViewGuest::WebContentsDestroyed(WebContents* web_contents) {
+void WebViewGuest::WebContentsDestroyed() {
   // Clean up custom context menu items for this guest.
   extensions::MenuManager* menu_manager = extensions::MenuManager::Get(
       Profile::FromBrowserContext(browser_context()));
   menu_manager->RemoveAllContextItems(extensions::MenuItem::ExtensionKey(
       embedder_extension_id(), view_instance_id()));
 
-  RemoveWebViewFromExtensionRendererState(web_contents);
+  RemoveWebViewFromExtensionRendererState(web_contents());
 }
 
 void WebViewGuest::UserAgentOverrideSet(const std::string& user_agent) {
@@ -1021,3 +1064,20 @@
 
 WebViewGuest::PermissionResponseInfo::~PermissionResponseInfo() {
 }
+
+void WebViewGuest::ShowContextMenu(int request_id,
+                                   const MenuItemVector* items) {
+  if (!pending_menu_.get())
+    return;
+
+  // Make sure this was the correct request.
+  if (request_id != pending_context_menu_request_id_)
+    return;
+
+  // TODO(lazyboy): Implement.
+  DCHECK(!items);
+
+  ContextMenuDelegate* menu_delegate =
+      ContextMenuDelegate::FromWebContents(guest_web_contents());
+  menu_delegate->ShowMenu(pending_menu_.Pass());
+}
diff --git a/chrome/browser/guest_view/web_view/web_view_guest.h b/chrome/browser/guest_view/web_view/web_view_guest.h
index d0a50b7..37557bf 100644
--- a/chrome/browser/guest_view/web_view/web_view_guest.h
+++ b/chrome/browser/guest_view/web_view/web_view_guest.h
@@ -5,11 +5,14 @@
 #ifndef CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_
 #define CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_
 
+#include <vector>
+
 #include "base/observer_list.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/guest_view/guest_view.h"
 #include "chrome/browser/guest_view/web_view/javascript_dialog_helper.h"
 #include "chrome/browser/guest_view/web_view/web_view_find_helper.h"
+#include "chrome/common/extensions/api/webview.h"
 #include "content/public/browser/javascript_dialog_manager.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_contents_observer.h"
@@ -19,11 +22,19 @@
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #endif
 
+namespace webview_api = extensions::api::webview;
+
+class RenderViewContextMenu;
+
 namespace extensions {
 class ScriptExecutor;
 class WebviewFindFunction;
 }  // namespace extensions
 
+namespace ui {
+class SimpleMenuModel;
+}  // namespace ui
+
 // A WebViewGuest is a WebContentsObserver on the guest WebContents of a
 // <webview> tag. It provides the browser-side implementation of the <webview>
 // API and manages the lifetime of <webview> extension events. WebViewGuest is
@@ -36,17 +47,29 @@
                      public content::WebContentsObserver {
  public:
   WebViewGuest(content::WebContents* guest_web_contents,
-               const std::string& embedder_extension_id);
+               const std::string& embedder_extension_id,
+               const base::WeakPtr<GuestViewBase>& opener);
 
   // Returns guestview::kInstanceIDNone if |contents| does not correspond to a
   // WebViewGuest.
   static int GetViewInstanceId(content::WebContents* contents);
   static const char Type[];
 
+  typedef std::vector<linked_ptr<webview_api::ContextMenuItem> > MenuItemVector;
+  // Shows the context menu for the guest.
+  // |items| acts as a filter. This restricts the current context's default
+  // menu items to contain only the items from |items|.
+  // |items| == NULL means no filtering will be applied.
+  void ShowContextMenu(int request_id, const MenuItemVector* items);
+
   // GuestViewBase implementation.
   virtual void Attach(content::WebContents* embedder_web_contents,
                       const base::DictionaryValue& args) OVERRIDE;
 
+  // BrowserPluginGuestDelegate public implementation.
+  virtual bool HandleContextMenu(
+      const content::ContextMenuParams& params) OVERRIDE;
+
   // GuestDelegate implementation.
   virtual void AddMessageToConsole(int32 level,
                                    const base::string16& message,
@@ -207,6 +230,11 @@
 
   static void RecordUserInitiatedUMA(const PermissionResponseInfo& info,
                                      bool allow);
+
+  // Returns the top level items (ignoring submenus) as Value.
+  static scoped_ptr<base::ListValue> MenuModelToValue(
+      const ui::SimpleMenuModel& menu_model);
+
   // WebContentsObserver implementation.
   virtual void DidCommitProvisionalLoadForFrame(
       int64 frame_id,
@@ -236,8 +264,7 @@
       content::RenderViewHost* render_view_host) OVERRIDE;
   virtual void DidStopLoading(
       content::RenderViewHost* render_view_host) OVERRIDE;
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
   virtual void UserAgentOverrideSet(const std::string& user_agent) OVERRIDE;
 
   // Called after the load handler is called in the guest's main frame.
@@ -277,6 +304,10 @@
 
   content::NotificationRegistrar notification_registrar_;
 
+  // A counter to generate a unique request id for a context menu request.
+  // We only need the ids to be unique for a given WebViewGuest.
+  int pending_context_menu_request_id_;
+
   // A counter to generate a unique request id for a permission request.
   // We only need the ids to be unique for a given WebViewGuest.
   int next_permission_request_id_;
@@ -309,6 +340,10 @@
   friend void WebviewFindHelper::DispatchFindUpdateEvent(bool canceled,
                                                          bool final_update);
 
+  // Holds the RenderViewContextMenu that has been built but yet to be
+  // shown. This is .Reset() after ShowContextMenu().
+  scoped_ptr<RenderViewContextMenu> pending_menu_;
+
 #if defined(OS_CHROMEOS)
   // Subscription to receive notifications on changes to a11y settings.
   scoped_ptr<chromeos::AccessibilityStatusSubscription>
diff --git a/chrome/browser/history/android/android_history_provider_service_unittest.cc b/chrome/browser/history/android/android_history_provider_service_unittest.cc
index b03b0bb..a2647a2 100644
--- a/chrome/browser/history/android/android_history_provider_service_unittest.cc
+++ b/chrome/browser/history/android/android_history_provider_service_unittest.cc
@@ -6,12 +6,13 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/history/android/android_history_types.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -52,7 +53,8 @@
         chrome::kInitialProfile);
 
     testing_profile_->CreateBookmarkModel(true);
-    test::WaitForBookmarkModelToLoad(testing_profile_);
+    test::WaitForBookmarkModelToLoad(
+        BookmarkModelFactory::GetForProfile(testing_profile_));
     ASSERT_TRUE(testing_profile_->CreateHistoryService(true, false));
     service_.reset(new AndroidHistoryProviderService(testing_profile_));
   }
diff --git a/chrome/browser/history/android/android_provider_backend_unittest.cc b/chrome/browser/history/android/android_provider_backend_unittest.cc
index c657709..3fcdf37 100644
--- a/chrome/browser/history/android/android_provider_backend_unittest.cc
+++ b/chrome/browser/history/android/android_provider_backend_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/favicon/favicon_changed_details.h"
 #include "chrome/browser/history/android/android_time.h"
@@ -24,6 +23,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread.h"
 #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc b/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc
index ce3fb63..d1c443a 100644
--- a/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc
+++ b/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc
@@ -7,7 +7,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/waitable_event.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/history/history_database.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/chrome_constants.h"
@@ -15,6 +14,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread.h"
 #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/history/android/sqlite_cursor_unittest.cc b/chrome/browser/history/android/sqlite_cursor_unittest.cc
index 56e47a8..a0a2521 100644
--- a/chrome/browser/history/android/sqlite_cursor_unittest.cc
+++ b/chrome/browser/history/android/sqlite_cursor_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/android/jni_string.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/history/android/android_history_provider_service.h"
 #include "chrome/browser/history/android/android_history_types.h"
 #include "chrome/browser/history/android/android_time.h"
@@ -21,6 +21,7 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread.h"
 #include "content/public/test/test_utils.h"
@@ -60,7 +61,8 @@
         chrome::kInitialProfile);
 
     testing_profile_->CreateBookmarkModel(true);
-    test::WaitForBookmarkModelToLoad(testing_profile_);
+    test::WaitForBookmarkModelToLoad(
+        BookmarkModelFactory::GetForProfile(testing_profile_));
 
     testing_profile_->CreateFaviconService();
     ASSERT_TRUE(testing_profile_->CreateHistoryService(true, false));
diff --git a/chrome/browser/history/expire_history_backend_unittest.cc b/chrome/browser/history/expire_history_backend_unittest.cc
index b1f3c87..405066e 100644
--- a/chrome/browser/history/expire_history_backend_unittest.cc
+++ b/chrome/browser/history/expire_history_backend_unittest.cc
@@ -16,7 +16,6 @@
 #include "base/stl_util.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/test_bookmark_client.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/archived_database.h"
 #include "chrome/browser/history/expire_history_backend.h"
@@ -29,6 +28,7 @@
 #include "chrome/tools/profiles/thumbnail-inl.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/test_bookmark_client.h"
 #include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index fca0c7a..935c2a4 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -405,8 +405,8 @@
       !is_keyword_generated) {
     const GURL& origin_url(has_redirects ?
         request.redirects[0] : request.url);
-    if (origin_url.SchemeIs(content::kHttpScheme) ||
-        origin_url.SchemeIs(content::kHttpsScheme) ||
+    if (origin_url.SchemeIs(url::kHttpScheme) ||
+        origin_url.SchemeIs(url::kHttpsScheme) ||
         origin_url.SchemeIs(content::kFtpScheme)) {
       std::string host(origin_url.host());
       size_t registry_length =
diff --git a/chrome/browser/history/history_backend_unittest.cc b/chrome/browser/history/history_backend_unittest.cc
index 50c7157..b6230b3 100644
--- a/chrome/browser/history/history_backend_unittest.cc
+++ b/chrome/browser/history/history_backend_unittest.cc
@@ -21,8 +21,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
-#include "chrome/browser/bookmarks/test_bookmark_client.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/history_service.h"
@@ -36,6 +34,8 @@
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
+#include "components/bookmarks/core/test/test_bookmark_client.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/test/test_browser_thread.h"
diff --git a/chrome/browser/history/history_tab_helper.cc b/chrome/browser/history/history_tab_helper.cc
index 03ccc81..948811b 100644
--- a/chrome/browser/history/history_tab_helper.cc
+++ b/chrome/browser/history/history_tab_helper.cc
@@ -153,10 +153,9 @@
                                               Profile::IMPLICIT_ACCESS);
 }
 
-void HistoryTabHelper::WebContentsDestroyed(WebContents* tab) {
+void HistoryTabHelper::WebContentsDestroyed() {
   // We update the history for this URL.
-  // The content returned from web_contents() has been destroyed by now.
-  // We need to use tab value directly.
+  WebContents* tab = web_contents();
   Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
   if (profile->IsOffTheRecord())
     return;
diff --git a/chrome/browser/history/history_tab_helper.h b/chrome/browser/history/history_tab_helper.h
index 65c21ad..c6372b4 100644
--- a/chrome/browser/history/history_tab_helper.h
+++ b/chrome/browser/history/history_tab_helper.h
@@ -51,7 +51,7 @@
       const content::FrameNavigateParams& params) OVERRIDE;
   virtual void TitleWasSet(content::NavigationEntry* entry,
                            bool explicit_set) OVERRIDE;
-  virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // Helper function to return the history service.  May return NULL.
   HistoryService* GetHistoryService();
diff --git a/chrome/browser/history/in_memory_url_index.cc b/chrome/browser/history/in_memory_url_index.cc
index e25a092..71a58c8 100644
--- a/chrome/browser/history/in_memory_url_index.cc
+++ b/chrome/browser/history/in_memory_url_index.cc
@@ -42,8 +42,8 @@
   whitelist->insert(std::string(content::kChromeUIScheme));
   whitelist->insert(std::string(content::kFileScheme));
   whitelist->insert(std::string(content::kFtpScheme));
-  whitelist->insert(std::string(content::kHttpScheme));
-  whitelist->insert(std::string(content::kHttpsScheme));
+  whitelist->insert(std::string(url::kHttpScheme));
+  whitelist->insert(std::string(url::kHttpsScheme));
   whitelist->insert(std::string(content::kMailToScheme));
 }
 
diff --git a/chrome/browser/history/in_memory_url_index.h b/chrome/browser/history/in_memory_url_index.h
index 1279c32..c6bf307 100644
--- a/chrome/browser/history/in_memory_url_index.h
+++ b/chrome/browser/history/in_memory_url_index.h
@@ -17,8 +17,6 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string16.h"
-#include "chrome/browser/autocomplete/autocomplete_match.h"
-#include "chrome/browser/autocomplete/history_provider_util.h"
 #include "chrome/browser/common/cancelable_request.h"
 #include "chrome/browser/history/history_db_task.h"
 #include "chrome/browser/history/history_types.h"
diff --git a/chrome/browser/history/in_memory_url_index_types.h b/chrome/browser/history/in_memory_url_index_types.h
index 17813d5..7c1993c 100644
--- a/chrome/browser/history/in_memory_url_index_types.h
+++ b/chrome/browser/history/in_memory_url_index_types.h
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/strings/string16.h"
-#include "chrome/browser/autocomplete/history_provider_util.h"
 #include "chrome/browser/history/history_types.h"
 #include "url/gurl.h"
 
diff --git a/chrome/browser/history/in_memory_url_index_unittest.cc b/chrome/browser/history/in_memory_url_index_unittest.cc
index 29fed9b..ba06b21 100644
--- a/chrome/browser/history/in_memory_url_index_unittest.cc
+++ b/chrome/browser/history/in_memory_url_index_unittest.cc
@@ -15,7 +15,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/autocomplete/autocomplete_provider.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_database.h"
@@ -28,6 +28,7 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/history_index_restore_observer.h"
 #include "chrome/test/base/testing_profile.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/test/test_browser_thread.h"
@@ -189,7 +190,8 @@
   // We cannot access the database until the backend has been loaded.
   ASSERT_TRUE(profile_.CreateHistoryService(true, false));
   profile_.CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(&profile_);
+  test::WaitForBookmarkModelToLoad(
+      BookmarkModelFactory::GetForProfile(&profile_));
   profile_.BlockUntilHistoryProcessesPendingRequests();
   profile_.BlockUntilHistoryIndexIsRefreshed();
   history_service_ = HistoryServiceFactory::GetForProfile(
diff --git a/chrome/browser/history/scored_history_match.cc b/chrome/browser/history/scored_history_match.cc
index c50b1f4..e44ea87 100644
--- a/chrome/browser/history/scored_history_match.cc
+++ b/chrome/browser/history/scored_history_match.cc
@@ -19,7 +19,6 @@
 #include "chrome/browser/autocomplete/history_url_provider.h"
 #include "chrome/browser/autocomplete/url_prefix.h"
 #include "chrome/browser/omnibox/omnibox_field_trial.h"
-#include "chrome/common/chrome_switches.h"
 #include "components/bookmarks/core/browser/bookmark_service.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/history/top_sites_database.cc b/chrome/browser/history/top_sites_database.cc
index 51ddad8..c5ad09f 100644
--- a/chrome/browser/history/top_sites_database.cc
+++ b/chrome/browser/history/top_sites_database.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/history/top_sites_database.h"
+
 #include "base/file_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/metrics/histogram.h"
@@ -9,7 +11,6 @@
 #include "base/strings/string_util.h"
 #include "chrome/browser/history/history_types.h"
 #include "chrome/browser/history/top_sites.h"
-#include "chrome/browser/history/top_sites_database.h"
 #include "chrome/common/thumbnail_score.h"
 #include "sql/connection.h"
 #include "sql/recovery.h"
diff --git a/chrome/browser/history/top_sites_impl.cc b/chrome/browser/history/top_sites_impl.cc
index 3d45f35..f27229a 100644
--- a/chrome/browser/history/top_sites_impl.cc
+++ b/chrome/browser/history/top_sites_impl.cc
@@ -29,8 +29,6 @@
 #include "chrome/browser/history/top_sites_cache.h"
 #include "chrome/browser/history/url_utils.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/ntp/most_visited_handler.h"
-#include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/thumbnail_score.h"
 #include "content/public/browser/browser_thread.h"
@@ -39,7 +37,6 @@
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
-#include "grit/locale_settings.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/layout.h"
 #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/history/typed_url_syncable_service.h b/chrome/browser/history/typed_url_syncable_service.h
index 8e7aea6..d3dd015 100644
--- a/chrome/browser/history/typed_url_syncable_service.h
+++ b/chrome/browser/history/typed_url_syncable_service.h
@@ -10,7 +10,7 @@
 
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/history_types.h"
-#include "content/public/browser/notification_types.h"
+#include "content/public/common/page_transition_types.h"
 #include "sync/api/sync_change.h"
 #include "sync/api/sync_data.h"
 #include "sync/api/sync_error.h"
diff --git a/chrome/browser/history/url_database.cc b/chrome/browser/history/url_database.cc
index 605213b..9de3e1a 100644
--- a/chrome/browser/history/url_database.cc
+++ b/chrome/browser/history/url_database.cc
@@ -313,8 +313,8 @@
 
 bool URLDatabase::IsTypedHost(const std::string& host) {
   const char* schemes[] = {
-    content::kHttpScheme,
-    content::kHttpsScheme,
+    url::kHttpScheme,
+    url::kHttpsScheme,
     content::kFtpScheme
   };
   URLRows dummy;
diff --git a/chrome/browser/history/url_index_private_data.cc b/chrome/browser/history/url_index_private_data.cc
index b76b051..2c69fd0 100644
--- a/chrome/browser/history/url_index_private_data.cc
+++ b/chrome/browser/history/url_index_private_data.cc
@@ -28,9 +28,6 @@
 #include "chrome/browser/history/in_memory_url_index.h"
 #include "components/bookmarks/core/browser/bookmark_service.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_source.h"
 #include "net/base/net_util.h"
 
 #if defined(USE_SYSTEM_PROTOBUF)
diff --git a/chrome/browser/history/url_index_private_data.h b/chrome/browser/history/url_index_private_data.h
index ff4eb7f..0d98584 100644
--- a/chrome/browser/history/url_index_private_data.h
+++ b/chrome/browser/history/url_index_private_data.h
@@ -16,7 +16,6 @@
 #include "chrome/browser/history/in_memory_url_index_cache.pb.h"
 #include "chrome/browser/history/in_memory_url_index_types.h"
 #include "chrome/browser/history/scored_history_match.h"
-#include "content/public/browser/notification_details.h"
 
 class BookmarkService;
 class HistoryQuickProviderTest;
diff --git a/chrome/browser/history/url_utils.cc b/chrome/browser/history/url_utils.cc
index c5d2eb6..0c7369a 100644
--- a/chrome/browser/history/url_utils.cc
+++ b/chrome/browser/history/url_utils.cc
@@ -6,6 +6,8 @@
 
 #include <algorithm>
 
+#include "url/gurl.h"
+
 namespace history {
 
 namespace {
diff --git a/chrome/browser/history/url_utils.h b/chrome/browser/history/url_utils.h
index c5b74fe..9e1ed2c 100644
--- a/chrome/browser/history/url_utils.h
+++ b/chrome/browser/history/url_utils.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "chrome/browser/history/history_types.h"
+class GURL;
 
 namespace history {
 
diff --git a/chrome/browser/history/url_utils_unittest.cc b/chrome/browser/history/url_utils_unittest.cc
index b1ffb6a..8df0d86 100644
--- a/chrome/browser/history/url_utils_unittest.cc
+++ b/chrome/browser/history/url_utils_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/history/url_utils.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace history {
 
diff --git a/chrome/browser/history/visit_database.cc b/chrome/browser/history/visit_database.cc
index 20e98b1..962c76a 100644
--- a/chrome/browser/history/visit_database.cc
+++ b/chrome/browser/history/visit_database.cc
@@ -490,8 +490,8 @@
 bool VisitDatabase::GetVisibleVisitCountToHost(const GURL& url,
                                                int* count,
                                                base::Time* first_visit) {
-  if (!url.SchemeIs(content::kHttpScheme) &&
-      !url.SchemeIs(content::kHttpsScheme))
+  if (!url.SchemeIs(url::kHttpScheme) &&
+      !url.SchemeIs(url::kHttpsScheme))
     return false;
 
   // We need to search for URLs with a matching host/port. One way to query for
diff --git a/chrome/browser/image_holder.cc b/chrome/browser/image_holder.cc
new file mode 100644
index 0000000..960b057
--- /dev/null
+++ b/chrome/browser/image_holder.cc
@@ -0,0 +1,100 @@
+// 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.
+
+// This class holds the URL to an image and the bitmap for the fetched image,
+// and has code to fetch the bitmap from the URL.
+
+#include "chrome/browser/image_holder.h"
+
+#include "chrome/browser/profiles/profile.h"
+#include "net/base/load_flags.h"
+
+namespace chrome {
+
+ImageHolder::ImageHolder(const GURL& low_dpi_url,
+                         const GURL& high_dpi_url,
+                         Profile* profile,
+                         ImageHolderDelegate* delegate)
+    : low_dpi_url_(low_dpi_url),
+      high_dpi_url_(high_dpi_url),
+      low_dpi_fetched_(false),
+      high_dpi_fetched_(false),
+      delegate_(delegate),
+      profile_(profile) {
+
+  // If a URL is invalid, clear it so we don't try to fetch it.
+  if (!low_dpi_url_.is_valid()) {
+    low_dpi_url_ = GURL();
+  }
+  if (!high_dpi_url_.is_valid()) {
+    high_dpi_url_ = GURL();
+  }
+
+  // Create a featcher for each URL that is set.
+  if (!low_dpi_url_.is_empty()) {
+    CreateBitmapFetcher(low_dpi_url_);
+  }
+  if (!high_dpi_url_.is_empty()) {
+    CreateBitmapFetcher(high_dpi_url_);
+  }
+}
+
+ImageHolder::~ImageHolder() {}
+
+// This will let us know if we have tried to fetch once and the try completed.
+// Currently there is no logic for retries.
+bool ImageHolder::IsFetchingDone() const {
+  return ((low_dpi_url_.is_empty() || low_dpi_fetched_) &&
+           (high_dpi_url_.is_empty() || high_dpi_fetched_));
+}
+
+// If this bitmap has a valid GURL, create a fetcher for it.
+void ImageHolder::CreateBitmapFetcher(const GURL& url) {
+  // Check for dups, ignore any request for a dup.
+  ScopedVector<chrome::BitmapFetcher>::iterator iter;
+  for (iter = fetchers_.begin(); iter != fetchers_.end(); ++iter) {
+    if ((*iter)->url() == url)
+      return;
+  }
+
+  if (url.is_valid()) {
+    fetchers_.push_back(new chrome::BitmapFetcher(url, this));
+    DVLOG(2) << __FUNCTION__ << "Pushing bitmap " << url;
+  }
+}
+
+void ImageHolder::StartFetch() {
+  // Now that we have queued them all, start the fetching.
+  ScopedVector<chrome::BitmapFetcher>::iterator iter;
+  for (iter = fetchers_.begin(); iter != fetchers_.end(); ++iter) {
+    (*iter)->Start(
+        profile_->GetRequestContext(),
+        std::string(),
+        net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+        net::LOAD_NORMAL);
+  }
+}
+
+// Method inherited from BitmapFetcher delegate.
+void ImageHolder::OnFetchComplete(const GURL url, const SkBitmap* bitmap) {
+  // TODO(petewil): Should I retry if a fetch fails?
+  // Match the bitmap to the URL to put it into the image with the correct scale
+  // factor.
+  if (url == low_dpi_url_) {
+    low_dpi_fetched_ = true;
+    if (bitmap != NULL)
+      image_.AddRepresentation(gfx::ImageSkiaRep(*bitmap, 1.0));
+  } else if (url == high_dpi_url_) {
+    high_dpi_fetched_ = true;
+    if (bitmap != NULL)
+      image_.AddRepresentation(gfx::ImageSkiaRep(*bitmap, 2.0));
+  } else {
+    DVLOG(2) << __FUNCTION__ << "Unmatched bitmap arrived " << url;
+  }
+
+  // Notify callback of bitmap arrival.
+  delegate_->OnFetchComplete();
+}
+
+}  // namespace chrome.
diff --git a/chrome/browser/image_holder.h b/chrome/browser/image_holder.h
new file mode 100644
index 0000000..db74296
--- /dev/null
+++ b/chrome/browser/image_holder.h
@@ -0,0 +1,72 @@
+// 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.
+
+#ifndef CHROME_BROWSER_IMAGE_HOLDER_H_
+#define CHROME_BROWSER_IMAGE_HOLDER_H_
+
+#include "base/memory/scoped_vector.h"
+#include "chrome/browser/bitmap_fetcher.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+#include "url/gurl.h"
+
+class Profile;
+
+namespace chrome {
+
+// This provides a callback so the ImageHolder can inform its parent when a
+// bitmap arrives.
+class ImageHolderDelegate {
+ public:
+  virtual void OnFetchComplete() = 0;
+};
+
+// This class encapsulates the action of fetching a bitmap, reporting when it is
+// fetched, and holding onto the bitmap until no longer needed.
+class ImageHolder : public chrome::BitmapFetcherDelegate {
+ public:
+  ImageHolder(const GURL& low_dpi_url,
+              const GURL& high_dpi_url,
+              Profile* profile,
+              ImageHolderDelegate* delegate);
+  virtual ~ImageHolder();
+
+  // Begin fetching of the URLs we have.
+  void StartFetch();
+
+  // Check whether we have a response from the server for these resources,
+  // even if the response is a failed fetch.
+  bool IsFetchingDone() const;
+
+  // Inherited from BitmapFetcherDelegate
+  virtual void OnFetchComplete(const GURL url, const SkBitmap* bitmap) OVERRIDE;
+
+  // Accessors:
+  GURL low_dpi_url() const { return low_dpi_url_; }
+  GURL high_dpi_url() const { return high_dpi_url_; }
+  gfx::Image low_dpi_image() { return gfx::Image(image_); }
+
+ private:
+  // Helper function to create a bitmap fetcher (but not start the fetch).
+  void CreateBitmapFetcher(const GURL& url);
+
+  GURL low_dpi_url_;
+  GURL high_dpi_url_;
+  bool low_dpi_fetched_;
+  bool high_dpi_fetched_;
+  gfx::ImageSkia image_;
+  ImageHolderDelegate* delegate_;
+  ScopedVector<chrome::BitmapFetcher> fetchers_;
+  Profile* profile_;
+
+  FRIEND_TEST_ALL_PREFIXES(ImageHolderTest, CreateBitmapFetcherTest);
+  FRIEND_TEST_ALL_PREFIXES(ImageHolderTest, OnFetchCompleteTest);
+  FRIEND_TEST_ALL_PREFIXES(ImageHolderTest, IsFetchingDoneTest);
+
+  DISALLOW_COPY_AND_ASSIGN(ImageHolder);
+};
+
+}  // namespace chrome.
+
+#endif  // CHROME_BROWSER_IMAGE_HOLDER_H_
diff --git a/chrome/browser/image_holder_unittest.cc b/chrome/browser/image_holder_unittest.cc
new file mode 100644
index 0000000..e8b725c
--- /dev/null
+++ b/chrome/browser/image_holder_unittest.cc
@@ -0,0 +1,104 @@
+// 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.
+
+#include <string>
+
+#include "chrome/browser/image_holder.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char kIconUrl1[] = "http://www.google.com/icon1.jpg";
+const char kIconUrl2[] = "http://www.google.com/icon2.jpg";
+
+class TestDelegate : public chrome::ImageHolderDelegate {
+ public:
+  TestDelegate() : on_fetch_complete_called_(false) {}
+  virtual void OnFetchComplete() OVERRIDE {
+    on_fetch_complete_called_ = true;
+  }
+  bool on_fetch_complete_called_;
+};
+
+}  // namespace.
+
+namespace chrome {
+
+typedef testing::Test ImageHolderTest;
+
+TEST_F(ImageHolderTest, CreateBitmapFetcherTest) {
+  TestDelegate delegate;
+  ImageHolder image_holder(GURL(kIconUrl1), GURL(kIconUrl2), NULL, &delegate);
+
+  EXPECT_EQ(GURL(kIconUrl1), image_holder.fetchers_[0]->url());
+  EXPECT_EQ(GURL(kIconUrl2), image_holder.fetchers_[1]->url());
+  EXPECT_EQ(static_cast<unsigned int>(2), image_holder.fetchers_.size());
+
+  // Adding a dup of an existing URL shouldn't change anything.
+  image_holder.CreateBitmapFetcher(GURL(kIconUrl2));
+  EXPECT_EQ(GURL(kIconUrl1), image_holder.fetchers_[0]->url());
+  EXPECT_EQ(GURL(kIconUrl2), image_holder.fetchers_[1]->url());
+  EXPECT_EQ(static_cast<unsigned int>(2), image_holder.fetchers_.size());
+}
+
+TEST_F(ImageHolderTest, OnFetchCompleteTest) {
+  TestDelegate delegate;
+  ImageHolder image_holder(GURL(kIconUrl1), GURL(), NULL, &delegate);
+
+  // Put a real bitmap into "bitmap".  2x2 bitmap of green 32 bit pixels.
+  SkBitmap bitmap;
+  bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
+  bitmap.allocPixels();
+  bitmap.eraseColor(SK_ColorGREEN);
+
+  image_holder.OnFetchComplete(GURL(kIconUrl1), &bitmap);
+
+  // Expect that the app icon has some data in it.
+  EXPECT_FALSE(image_holder.low_dpi_image().IsEmpty());
+
+  // Expect that we reported the fetch done to the delegate.
+  EXPECT_TRUE(delegate.on_fetch_complete_called_);
+}
+
+TEST_F(ImageHolderTest, IsFetchingDoneTest) {
+  TestDelegate delegate;
+  ImageHolder image_holder1(GURL(kIconUrl1), GURL(kIconUrl2), NULL, &delegate);
+  ImageHolder image_holder2(GURL(kIconUrl1), GURL(), NULL, &delegate);
+  ImageHolder image_holder3(GURL(), GURL(kIconUrl2), NULL, &delegate);
+  ImageHolder image_holder4(GURL(), GURL(), NULL, &delegate);
+
+  // Initially, image holder 4 with no URLs should report done, but no others.
+  EXPECT_FALSE(image_holder1.IsFetchingDone());
+  EXPECT_FALSE(image_holder2.IsFetchingDone());
+  EXPECT_FALSE(image_holder3.IsFetchingDone());
+  EXPECT_TRUE(image_holder4.IsFetchingDone());
+
+  // Put a real bitmap into "bitmap".  2x2 bitmap of green 32 bit pixels.
+  SkBitmap bitmap;
+  bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
+  bitmap.allocPixels();
+  bitmap.eraseColor(SK_ColorGREEN);
+
+  // Add the first icon, and image holder 2 should now also report done.
+  image_holder1.OnFetchComplete(GURL(kIconUrl1), &bitmap);
+  image_holder2.OnFetchComplete(GURL(kIconUrl1), &bitmap);
+  image_holder3.OnFetchComplete(GURL(kIconUrl1), &bitmap);
+  image_holder4.OnFetchComplete(GURL(kIconUrl1), &bitmap);
+  EXPECT_FALSE(image_holder1.IsFetchingDone());
+  EXPECT_TRUE(image_holder2.IsFetchingDone());
+  EXPECT_FALSE(image_holder3.IsFetchingDone());
+  EXPECT_TRUE(image_holder4.IsFetchingDone());
+
+  // Add the second image, and now all 4 should report done.
+  image_holder1.OnFetchComplete(GURL(kIconUrl2), &bitmap);
+  image_holder2.OnFetchComplete(GURL(kIconUrl2), &bitmap);
+  image_holder3.OnFetchComplete(GURL(kIconUrl2), &bitmap);
+  image_holder4.OnFetchComplete(GURL(kIconUrl2), &bitmap);
+  EXPECT_TRUE(image_holder1.IsFetchingDone());
+  EXPECT_TRUE(image_holder2.IsFetchingDone());
+  EXPECT_TRUE(image_holder3.IsFetchingDone());
+  EXPECT_TRUE(image_holder4.IsFetchingDone());
+}
+
+}  // namespace chrome.
diff --git a/chrome/browser/importer/firefox_importer_browsertest.cc b/chrome/browser/importer/firefox_importer_browsertest.cc
index d841c9b..c56af96 100644
--- a/chrome/browser/importer/firefox_importer_browsertest.cc
+++ b/chrome/browser/importer/firefox_importer_browsertest.cc
@@ -38,10 +38,10 @@
   const char* origin;
   const char* action;
   const char* realm;
-  const wchar_t* username_element;
-  const wchar_t* username;
-  const wchar_t* password_element;
-  const wchar_t* password;
+  const char* username_element;
+  const char* username;
+  const char* password_element;
+  const char* password;
   bool blacklisted;
 };
 
@@ -51,7 +51,7 @@
 };
 
 const BookmarkInfo kFirefoxBookmarks[] = {
-  {true, 1, {L"Bookmarks Toolbar"},
+  {true, 1, {"Bookmarks Toolbar"},
     L"Toolbar",
     "http://site/"},
   {false, 0, {},
@@ -61,9 +61,9 @@
 
 const PasswordInfo kFirefoxPasswords[] = {
   {"http://localhost:8080/", "http://localhost:8080/", "http://localhost:8080/",
-    L"loginuser", L"abc", L"loginpass", L"123", false},
+    "loginuser", "abc", "loginpass", "123", false},
   {"http://localhost:8080/", "", "http://localhost:8080/localhost",
-    L"", L"http", L"", L"Http1+1abcdefg", false},
+    "", "http", "", "Http1+1abcdefg", false},
 };
 
 const KeywordInfo kFirefoxKeywords[] = {
@@ -135,10 +135,10 @@
     EXPECT_EQ(p.origin, form.origin.spec());
     EXPECT_EQ(p.realm, form.signon_realm);
     EXPECT_EQ(p.action, form.action.spec());
-    EXPECT_EQ(base::WideToUTF16(p.username_element), form.username_element);
-    EXPECT_EQ(base::WideToUTF16(p.username), form.username_value);
-    EXPECT_EQ(base::WideToUTF16(p.password_element), form.password_element);
-    EXPECT_EQ(base::WideToUTF16(p.password), form.password_value);
+    EXPECT_EQ(base::ASCIIToUTF16(p.username_element), form.username_element);
+    EXPECT_EQ(base::ASCIIToUTF16(p.username), form.username_value);
+    EXPECT_EQ(base::ASCIIToUTF16(p.password_element), form.password_element);
+    EXPECT_EQ(base::ASCIIToUTF16(p.password), form.password_value);
     EXPECT_EQ(p.blacklisted, form.blacklisted_by_user);
     ++password_count_;
   }
@@ -177,10 +177,9 @@
       // The order might not be deterministic, look in the expected list for
       // that template URL.
       bool found = false;
-      base::string16 keyword = template_urls[i]->keyword();
+      const base::string16& keyword = template_urls[i]->keyword();
       for (size_t j = 0; j < arraysize(kFirefoxKeywords); ++j) {
-        if (template_urls[i]->keyword() ==
-                base::WideToUTF16Hack(kFirefoxKeywords[j].keyword)) {
+        if (keyword == base::WideToUTF16(kFirefoxKeywords[j].keyword)) {
           EXPECT_EQ(kFirefoxKeywords[j].url, template_urls[i]->url());
           found = true;
           break;
@@ -247,7 +246,7 @@
       data_path = data_path.AppendASCII("firefox3_searchplugins");
       if (!base::PathExists(data_path)) {
         // TODO(maruel):  Create search test data that we can open source!
-        LOG(ERROR) << L"Missing internal test data";
+        LOG(ERROR) << "Missing internal test data";
         return;
       }
       ASSERT_TRUE(base::CopyDirectory(data_path, search_engine_path, false));
diff --git a/chrome/browser/importer/ie_importer_browsertest_win.cc b/chrome/browser/importer/ie_importer_browsertest_win.cc
index c616744..e0e62d8 100644
--- a/chrome/browser/importer/ie_importer_browsertest_win.cc
+++ b/chrome/browser/importer/ie_importer_browsertest_win.cc
@@ -49,36 +49,36 @@
 namespace {
 
 const BookmarkInfo kIEBookmarks[] = {
-  {true, 2, {L"Links", L"SubFolderOfLinks"},
-   L"SubLink",
-   "http://www.links-sublink.com/"},
-  {true, 1, {L"Links"},
-   L"TheLink",
-   "http://www.links-thelink.com/"},
+  {true, 2, {"Links", "SubFolderOfLinks"},
+    L"SubLink",
+    "http://www.links-sublink.com/"},
+  {true, 1, {"Links"},
+    L"TheLink",
+    "http://www.links-thelink.com/"},
   {false, 0, {},
-   L"Google Home Page",
-   "http://www.google.com/"},
+    L"Google Home Page",
+    "http://www.google.com/"},
   {false, 0, {},
-   L"TheLink",
-   "http://www.links-thelink.com/"},
-  {false, 1, {L"SubFolder"},
-   L"Title",
-   "http://www.link.com/"},
+    L"TheLink",
+    "http://www.links-thelink.com/"},
+  {false, 1, {"SubFolder"},
+    L"Title",
+    "http://www.link.com/"},
   {false, 0, {},
-   L"WithPortAndQuery",
-   "http://host:8080/cgi?q=query"},
-  {false, 1, {L"a"},
-   L"\x4E2D\x6587",
-   "http://chinese-title-favorite/"},
+    L"WithPortAndQuery",
+    "http://host:8080/cgi?q=query"},
+  {false, 1, {"a"},
+    L"\x4E2D\x6587",
+    "http://chinese-title-favorite/"},
   {false, 0, {},
-   L"SubFolder",
-   "http://www.subfolder.com/"},
+    L"SubFolder",
+    "http://www.subfolder.com/"},
 };
 
 const BookmarkInfo kIESortedBookmarks[] = {
   {false, 0, {}, L"a", "http://www.google.com/0"},
-  {false, 1, {L"b"}, L"a", "http://www.google.com/1"},
-  {false, 1, {L"b"}, L"b", "http://www.google.com/2"},
+  {false, 1, {"b"}, L"a", "http://www.google.com/1"},
+  {false, 1, {"b"}, L"b", "http://www.google.com/2"},
   {false, 0, {}, L"c", "http://www.google.com/3"},
 };
 
@@ -106,11 +106,11 @@
 
 const FaviconGroup kIEFaviconGroup[2] = {
   {L"http://www.google.com/favicon.ico",
-   {L"http://www.google.com/",
-    L"http://www.subfolder.com/"}},
+    {L"http://www.google.com/",
+      L"http://www.subfolder.com/"}},
   {L"http://example.com/favicon.ico",
-   {L"http://host:8080/cgi?q=query",
-    L"http://chinese-title-favorite/"}},
+    {L"http://host:8080/cgi?q=query",
+      L"http://chinese-title-favorite/"}},
 };
 
 bool CreateOrderBlob(const base::FilePath& favorites_folder,
diff --git a/chrome/browser/importer/importer_unittest_utils.cc b/chrome/browser/importer/importer_unittest_utils.cc
index 284a6f9..e29bed7 100644
--- a/chrome/browser/importer/importer_unittest_utils.cc
+++ b/chrome/browser/importer/importer_unittest_utils.cc
@@ -10,12 +10,12 @@
 
 void TestEqualBookmarkEntry(const ImportedBookmarkEntry& entry,
                             const BookmarkInfo& expected) {
-  ASSERT_EQ(base::WideToUTF16Hack(expected.title), entry.title);
+  ASSERT_EQ(base::WideToUTF16(expected.title), entry.title);
   ASSERT_EQ(expected.in_toolbar, entry.in_toolbar) << entry.title;
   ASSERT_EQ(expected.path_size, entry.path.size()) << entry.title;
   ASSERT_EQ(expected.url, entry.url.spec()) << entry.title;
   for (size_t i = 0; i < expected.path_size; ++i) {
-    ASSERT_EQ(base::WideToUTF16Hack(expected.path[i]),
+    ASSERT_EQ(base::ASCIIToUTF16(expected.path[i]),
               entry.path[i]) << entry.title;
   }
 }
diff --git a/chrome/browser/importer/importer_unittest_utils.h b/chrome/browser/importer/importer_unittest_utils.h
index 9f6f143..7696565 100644
--- a/chrome/browser/importer/importer_unittest_utils.h
+++ b/chrome/browser/importer/importer_unittest_utils.h
@@ -14,7 +14,7 @@
 struct BookmarkInfo {
   const bool in_toolbar;
   const size_t path_size;
-  const wchar_t* path[kMaxPathSize];
+  const char* path[kMaxPathSize];
   const wchar_t* title;
   const char* url;
 };
diff --git a/chrome/browser/importer/profile_writer_unittest.cc b/chrome/browser/importer/profile_writer_unittest.cc
index c72874a..3ae714a 100644
--- a/chrome/browser/importer/profile_writer_unittest.cc
+++ b/chrome/browser/importer/profile_writer_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/history/history_types.h"
@@ -19,6 +18,7 @@
 #include "components/bookmarks/core/browser/bookmark_match.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/infobars/infobar_service.cc b/chrome/browser/infobars/infobar_service.cc
index 3d03544..030035b 100644
--- a/chrome/browser/infobars/infobar_service.cc
+++ b/chrome/browser/infobars/infobar_service.cc
@@ -107,11 +107,11 @@
   OnNavigation(NavigationDetailsFromLoadCommittedDetails(load_details));
 }
 
-void InfoBarService::WebContentsDestroyed(content::WebContents* web_contents) {
+void InfoBarService::WebContentsDestroyed() {
   // The WebContents is going away; be aggressively paranoid and delete
   // ourselves lest other parts of the system attempt to add infobars or use
   // us otherwise during the destruction.
-  web_contents->RemoveUserData(UserDataKey());
+  web_contents()->RemoveUserData(UserDataKey());
   // That was the equivalent of "delete this". This object is now destroyed;
   // returning from this function is the only safe thing to do.
 }
diff --git a/chrome/browser/infobars/infobar_service.h b/chrome/browser/infobars/infobar_service.h
index 39cca9a..a90305b 100644
--- a/chrome/browser/infobars/infobar_service.h
+++ b/chrome/browser/infobars/infobar_service.h
@@ -62,8 +62,7 @@
   virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
   virtual void NavigationEntryCommitted(
       const content::LoadCommittedDetails& load_details) OVERRIDE;
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
 
   // Message handlers.
diff --git a/chrome/browser/internal_auth.cc b/chrome/browser/internal_auth.cc
index 984c954..acdd442 100644
--- a/chrome/browser/internal_auth.cc
+++ b/chrome/browser/internal_auth.cc
@@ -89,7 +89,7 @@
 bool IsDomainSane(const std::string& domain) {
   return !domain.empty() &&
       domain.size() <= kStringLengthLimit &&
-      IsStringUTF8(domain) &&
+      base::IsStringUTF8(domain) &&
       domain.find_first_of(kItemSeparator) == std::string::npos;
 }
 
@@ -109,14 +109,14 @@
       kVarValueSeparator) == kAllowedChars + arraysize(kAllowedChars));
   return !var.empty() &&
       var.size() <= kStringLengthLimit &&
-      IsStringASCII(var) &&
+      base::IsStringASCII(var) &&
       var.find_first_not_of(kAllowedChars) == std::string::npos &&
       !IsAsciiDigit(var[0]);
 }
 
 bool IsValueSane(const std::string& value) {
   return value.size() <= kStringLengthLimit &&
-      IsStringUTF8(value) &&
+      base::IsStringUTF8(value) &&
       value.find_first_of(kItemSeparator) == std::string::npos;
 }
 
@@ -265,7 +265,7 @@
     const std::string& domain,
     int64 current_tick) {
     if (passport.size() != kPassportSize ||
-        !IsStringASCII(passport) ||
+        !base::IsStringASCII(passport) ||
         !IsDomainSane(domain) ||
         current_tick <= dark_tick_ ||
         current_tick > key_change_tick_  + kKeyRegenerationHardTicks ||
diff --git a/chrome/browser/invalidation/invalidation_logger.h b/chrome/browser/invalidation/invalidation_logger.h
index 3ae1553..befaa4c 100644
--- a/chrome/browser/invalidation/invalidation_logger.h
+++ b/chrome/browser/invalidation/invalidation_logger.h
@@ -36,7 +36,7 @@
 //
 // Observers can be registered and will be called to be notified of any
 // status change immediatly. They can log there the history of what messages
-// they recieve.
+// they receive.
 
 class InvalidationLogger {
 
diff --git a/chrome/browser/invalidation/invalidator_storage_unittest.cc b/chrome/browser/invalidation/invalidator_storage_unittest.cc
index b587997..841bead 100644
--- a/chrome/browser/invalidation/invalidator_storage_unittest.cc
+++ b/chrome/browser/invalidation/invalidator_storage_unittest.cc
@@ -55,7 +55,7 @@
 TEST_F(InvalidatorStorageTest, SetGetBootstrapData) {
   InvalidatorStorage storage(&pref_service_);
   const std::string mess("n\0tK\0\0l\344", 8);
-  ASSERT_FALSE(IsStringUTF8(mess));
+  ASSERT_FALSE(base::IsStringUTF8(mess));
 
   storage.SetBootstrapData(mess);
   EXPECT_EQ(mess, storage.GetBootstrapData());
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 55b3f62..29a65ea 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -44,6 +44,7 @@
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_prefs.h"
 #include "components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.h"
 #include "components/policy/core/common/policy_service.h"
 #include "content/public/browser/browser_thread.h"
@@ -600,7 +601,7 @@
 #endif
   globals_->ssl_config_service = GetSSLConfigService();
 #if defined(OS_ANDROID) || defined(OS_IOS)
-  if (DataReductionProxySettings::IsDataReductionProxyAllowed()) {
+  if (DataReductionProxySettings::IsIncludedInFieldTrialOrFlags()) {
     spdyproxy_auth_origins_ =
         DataReductionProxySettings::GetDataReductionProxies();
   }
@@ -876,44 +877,7 @@
   registry->RegisterStringPref(
       data_reduction_proxy::prefs::kDataReductionProxy, std::string());
   registry->RegisterBooleanPref(prefs::kEnableReferrers, true);
-  registry->RegisterInt64Pref(
-      data_reduction_proxy::prefs::kHttpReceivedContentLength, 0);
-  registry->RegisterInt64Pref(
-      data_reduction_proxy::prefs::kHttpOriginalContentLength, 0);
-#if defined(OS_ANDROID) || defined(OS_IOS)
-  registry->RegisterListPref(
-      data_reduction_proxy::prefs::kDailyHttpOriginalContentLength);
-  registry->RegisterListPref(
-      data_reduction_proxy::prefs::kDailyHttpReceivedContentLength);
-  registry->RegisterListPref(
-      data_reduction_proxy::prefs::
-          kDailyOriginalContentLengthWithDataReductionProxyEnabled);
-  registry->RegisterListPref(
-      data_reduction_proxy::prefs::
-          kDailyContentLengthWithDataReductionProxyEnabled);
-  registry->RegisterListPref(
-      data_reduction_proxy::prefs::
-          kDailyContentLengthHttpsWithDataReductionProxyEnabled);
-  registry->RegisterListPref(
-      data_reduction_proxy::prefs::
-          kDailyContentLengthShortBypassWithDataReductionProxyEnabled
-      );
-  registry->RegisterListPref(
-      data_reduction_proxy::prefs::
-          kDailyContentLengthLongBypassWithDataReductionProxyEnabled);
-  registry->RegisterListPref(
-      data_reduction_proxy::prefs::
-          kDailyContentLengthUnknownWithDataReductionProxyEnabled);
-  registry->RegisterListPref(
-      data_reduction_proxy::prefs::
-          kDailyOriginalContentLengthViaDataReductionProxy);
-  registry->RegisterListPref(
-      data_reduction_proxy::
-          prefs::kDailyContentLengthViaDataReductionProxy);
-  registry->RegisterInt64Pref(
-      data_reduction_proxy::prefs::
-          kDailyHttpContentLengthLastUpdateDate, 0L);
-#endif
+  data_reduction_proxy::RegisterPrefs(registry);
   registry->RegisterBooleanPref(prefs::kBuiltInDnsClientEnabled, true);
   registry->RegisterBooleanPref(prefs::kQuickCheckEnabled, true);
 }
diff --git a/chrome/browser/local_discovery/privet_traffic_detector.cc b/chrome/browser/local_discovery/privet_traffic_detector.cc
index c6a56c6..7c0d666 100644
--- a/chrome/browser/local_discovery/privet_traffic_detector.cc
+++ b/chrome/browser/local_discovery/privet_traffic_detector.cc
@@ -40,7 +40,8 @@
   net::IPAddressNumber localhost_prefix(4, 0);
   localhost_prefix[0] = 127;
   ip4_networks.push_back(
-      net::NetworkInterface("lo", "lo", 0, net::NETWORK_INTERFACE_UNKNOWN,
+      net::NetworkInterface("lo", "lo", 0,
+                            net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
                             localhost_prefix, 8));
   content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
                                    base::Bind(callback, ip4_networks));
diff --git a/chrome/browser/local_discovery/service_discovery_shared_client.cc b/chrome/browser/local_discovery/service_discovery_shared_client.cc
index dcfb64b..01c3c00 100644
--- a/chrome/browser/local_discovery/service_discovery_shared_client.cc
+++ b/chrome/browser/local_discovery/service_discovery_shared_client.cc
@@ -11,7 +11,6 @@
 #include "base/metrics/histogram.h"
 #include "base/path_service.h"
 #include "base/timer/elapsed_timer.h"
-#include "chrome/browser/local_discovery/service_discovery_client_utility.h"
 #include "chrome/installer/util/browser_distribution.h"
 #include "chrome/installer/util/firewall_manager_win.h"
 #endif  // OS_WIN
@@ -21,26 +20,25 @@
 #endif
 
 #if defined(ENABLE_MDNS)
-#include "chrome/browser/local_discovery/service_discovery_client_mdns.h"
+#include "chrome/browser/local_discovery/service_discovery_client_utility.h"
 #endif  // ENABLE_MDNS
 
 namespace {
 
 #if defined(OS_WIN)
-bool IsFirewallReady() {
+void ReportFirewallStats() {
   base::FilePath exe_path;
   if (!PathService::Get(base::FILE_EXE, &exe_path))
-    return false;
+    return;
   base::ElapsedTimer timer;
   scoped_ptr<installer::FirewallManager> manager =
       installer::FirewallManager::Create(BrowserDistribution::GetDistribution(),
                                          exe_path);
   if (!manager)
-    return false;
+    return;
   bool is_ready = manager->CanUseLocalPorts();
   UMA_HISTOGRAM_TIMES("LocalDiscovery.FirewallAccessTime", timer.Elapsed());
   UMA_HISTOGRAM_BOOLEAN("LocalDiscovery.IsFirewallReady", is_ready);
-  return is_ready;
 }
 #endif  // OS_WIN
 
@@ -76,18 +74,18 @@
 
 #if defined(OS_MACOSX)
   return ServiceDiscoveryClientMacFactory::CreateInstance();
-#else
+#else  // OS_MACOSX
 
 #if defined(OS_WIN)
-  static bool is_firewall_ready = IsFirewallReady();
-  if (!is_firewall_ready) {
-    // TODO(vitalybuka): Remove after we find what to do with firewall for
-    // user-level installs. crbug.com/366408
-    return new ServiceDiscoveryClientUtility();
-  }
+  static bool reported =
+      BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+                              base::Bind(&ReportFirewallStats));
 #endif  // OS_WIN
-  return new ServiceDiscoveryClientMdns();
-#endif
+
+  // TODO(vitalybuka): Switch to |ServiceDiscoveryClientMdns| after we find what
+  // to do with firewall for user-level installs. crbug.com/366408
+  return new ServiceDiscoveryClientUtility();
+#endif // OS_MACOSX
 }
 
 #else
diff --git a/chrome/browser/managed_mode/managed_mode_navigation_observer.cc b/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
index 12cb5b2..0e27dc8 100644
--- a/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
+++ b/chrome/browser/managed_mode/managed_mode_navigation_observer.cc
@@ -26,7 +26,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/user_metrics.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -63,8 +62,7 @@
   // If we can't go back (because we opened a new tab), try to close the tab.
   // If this is the last tab on this desktop, open a new window.
   chrome::HostDesktopType host_desktop_type =
-      chrome::GetHostDesktopTypeForNativeView(
-          web_contents->GetView()->GetNativeView());
+      chrome::GetHostDesktopTypeForNativeView(web_contents->GetNativeView());
   const BrowserList* browser_list = BrowserList::GetInstance(host_desktop_type);
   if (browser_list->size() == 1) {
     Browser* browser = browser_list->get(0);
diff --git a/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc b/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
index e083340..49cc42c 100644
--- a/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
+++ b/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/infobars/infobar_service.h"
+#include "chrome/browser/media/media_stream_devices_controller.h"
 #include "chrome/browser/media/webrtc_browsertest_base.h"
 #include "chrome/browser/media/webrtc_browsertest_common.h"
 #include "chrome/browser/profiles/profile.h"
@@ -22,6 +23,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/infobars/core/infobar.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/common/media_stream_request.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
 
@@ -50,21 +52,56 @@
     return LoadTestPageInBrowser(CreateIncognitoBrowser());
   }
 
+  // Returns the URL of the main test page.
+  GURL test_page_url() const {
+    const char kMainWebrtcTestHtmlPage[] =
+        "files/webrtc/webrtc_jsep01_test.html";
+    return test_server()->GetURL(kMainWebrtcTestHtmlPage);
+  }
+
+  // Denies getUserMedia requests (audio, video) for the test page.
+  // The deny setting is sticky.
+  void DenyRequest(content::WebContents* tab_contents,
+                   content::MediaStreamRequestResult result) const {
+    const std::string no_id;
+    content::MediaStreamRequest request(
+        0, 0, 0, test_page_url().GetOrigin(), false,
+        content::MEDIA_DEVICE_ACCESS, no_id, no_id,
+        content::MEDIA_DEVICE_AUDIO_CAPTURE,
+        content::MEDIA_DEVICE_VIDEO_CAPTURE);
+
+    scoped_ptr<MediaStreamDevicesController> controller(
+        new MediaStreamDevicesController(tab_contents, request,
+            base::Bind(&OnMediaStreamResponse)));
+    controller->Deny(true, result);
+  }
+
+  // Executes stopLocalStream() in the test page, which frees up an already
+  // acquired mediastream.
+  bool StopLocalStream(content::WebContents* tab_contents) {
+    std::string result;
+    bool ok = content::ExecuteScriptAndExtractString(
+        tab_contents, "stopLocalStream()", &result);
+    DCHECK(ok);
+    return result.compare("ok-stopped") == 0;
+  }
+
  private:
   content::WebContents* LoadTestPageInBrowser(Browser* browser) {
     EXPECT_TRUE(test_server()->Start());
 
-    const char kMainWebrtcTestHtmlPage[] =
-        "files/webrtc/webrtc_jsep01_test.html";
-    ui_test_utils::NavigateToURL(
-        browser, test_server()->GetURL(kMainWebrtcTestHtmlPage));
+    ui_test_utils::NavigateToURL(browser, test_page_url());
     return browser->tab_strip_model()->GetActiveWebContents();
   }
 
+  // Dummy callback for when we deny the current request directly.
+  static void OnMediaStreamResponse(const content::MediaStreamDevices& devices,
+                                    content::MediaStreamRequestResult result,
+                                    scoped_ptr<content::MediaStreamUI> ui) {}
+
   DISALLOW_COPY_AND_ASSIGN(MediaStreamInfoBarTest);
 };
 
-
 // Actual tests ---------------------------------------------------------------
 
 // Failing on ChromiumOS Debug and Win Aura, so disabling on both.
@@ -114,7 +151,7 @@
   content::WebContents* tab_contents = LoadTestPageInTab();
 
   GetUserMediaAndAccept(tab_contents);
-  GetUserMediaAndDeny(tab_contents);
+  DenyRequest(tab_contents, content::MEDIA_DEVICE_PERMISSION_DENIED);
 
   // Should fail with permission denied right away with no infobar popping up.
   GetUserMedia(tab_contents, kAudioVideoCallConstraints);
@@ -139,9 +176,58 @@
   // If accept were sticky the second call would hang because it hangs if an
   // infobar does not pop up.
   GetUserMediaAndAccept(tab_contents);
+
+  // Because http request permissions are sticky per navigation, we need to
+  // navigate away from the current page in order to verify that the granted
+  // permissions are not permanently sticky.
+  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(),
+      GURL("about:blank"), 1);
+
+  // Now navigate back to our test page.
+  ui_test_utils::NavigateToURL(browser(), test_page_url());
+  tab_contents = browser()->tab_strip_model()->GetActiveWebContents();
+
   GetUserMediaAndAccept(tab_contents);
 }
 
+// Test that accepting one getUserMedia request will not require a second
+// prompt when issuing a second getUserMedia request.
+IN_PROC_BROWSER_TEST_F(MediaStreamInfoBarTest,
+                       TestAcceptIsStickyPerNavigation) {
+  content::WebContents* tab_contents = LoadTestPageInTab();
+
+  GetUserMediaAndAccept(tab_contents);
+
+  // Before issuing the second gUM request, make sure we first stop the tracks
+  // we started with the first request. If they're still running the permissions
+  // will be active for other reasons and we won't be testing the temporary
+  // stickiness properly.
+  EXPECT_TRUE(StopLocalStream(tab_contents));
+
+  // Now no media tracks are running, so let's issue the second request.
+  GetUserMedia(tab_contents, kAudioVideoCallConstraints);
+}
+
+IN_PROC_BROWSER_TEST_F(MediaStreamInfoBarTest,
+                       TestTwoAcceptsPlusStickyPerNavigation) {
+  content::WebContents* tab_contents = LoadTestPageInTab();
+
+  // First ask for audio only and approve.
+  GetUserMediaWithSpecificConstraintsAndAccept(tab_contents,
+                                               kAudioOnlyCallConstraints);
+  EXPECT_TRUE(StopLocalStream(tab_contents));
+
+  // Next ask for video permissions.
+  // This will hang if the previous gUM call somehow gave video permissions.
+  GetUserMediaWithSpecificConstraintsAndAccept(tab_contents,
+                                               kVideoOnlyCallConstraints);
+  EXPECT_TRUE(StopLocalStream(tab_contents));
+
+  // Now ask for both audio and video and expect the call to go through without
+  // showing any UI.
+  GetUserMedia(tab_contents, kAudioVideoCallConstraints);
+}
+
 IN_PROC_BROWSER_TEST_F(MediaStreamInfoBarTest, TestDismissIsNotSticky) {
   content::WebContents* tab_contents = LoadTestPageInTab();
 
diff --git a/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc b/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc
index e9a38ab..40a8c6f 100644
--- a/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
+#include "base/files/file_enumerator.h"
 #include "base/path_service.h"
 #include "base/process/launch.h"
 #include "base/rand_util.h"
@@ -37,7 +38,7 @@
 // on the running system. This test is not meant to run in the main browser
 // test suite since normal tester machines do not have webcams. Chrome will use
 // its fake camera for both tests, but Firefox will use the real webcam in the
-// Firefox interop test.
+// Firefox interop test. Thus, this test must on a machine with a real webcam.
 //
 // This test will bring up a AppRTC instance on localhost and verify that the
 // call gets up when connecting to the same room from two tabs in a browser.
@@ -184,6 +185,22 @@
                                &firefox_);
   }
 
+  bool HasWebcamOnSystem() {
+#if defined(OS_LINUX)
+    // Implementation note: normally we would be able to figure this out with
+    // MediaStreamTrack.getSources, but we can't ask Chrome since it runs in
+    // fake device mode where it will not enumerate webcams on the system.
+    // Therefore, look for /dev/video* entries directly since this test only
+    // runs on Linux for now anyway.
+    base::FileEnumerator dev_video(base::FilePath(FILE_PATH_LITERAL("/dev")),
+                                   false, base::FileEnumerator::FILES,
+                                   FILE_PATH_LITERAL("video*"));
+    return !dev_video.Next().empty();
+#endif
+    NOTREACHED();
+    return false;
+  }
+
  private:
   base::ProcessHandle dev_appserver_;
   base::ProcessHandle firefox_;
@@ -217,7 +234,7 @@
 }
 
 #if defined(OS_LINUX)
-#define MAYBE_MANUAL_FirefoxApprtcInteropTest DISABLED_MANUAL_FirefoxApprtcInteropTest
+#define MAYBE_MANUAL_FirefoxApprtcInteropTest MANUAL_FirefoxApprtcInteropTest
 #else
 // Not implemented yet on Windows and Mac.
 #define MAYBE_MANUAL_FirefoxApprtcInteropTest DISABLED_MANUAL_FirefoxApprtcInteropTest
@@ -230,6 +247,12 @@
   if (base::win::GetVersion() < base::win::VERSION_VISTA)
     return;
 #endif
+  if (!HasWebcamOnSystem()) {
+    LOG(INFO)
+        << "Didn't find a webcam on the system; skipping test since Firefox "
+        << "needs to be able to acquire a webcam.";
+    return;
+  }
 
   DetectErrorsInJavaScript();
   ASSERT_TRUE(LaunchApprtcInstanceOnLocalhost());
diff --git a/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc b/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc
index a1e492e..5e59a10 100644
--- a/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc
@@ -87,7 +87,6 @@
  public:
   WebRtcAudioQualityBrowserTest() {}
   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
-    test::PeerConnectionServerRunner::KillAllPeerConnectionServers();
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
@@ -114,18 +113,6 @@
     EXPECT_EQ("ok-playing", ExecuteJavascript("playAudioFile()", tab_contents));
   }
 
-  void EstablishCall(content::WebContents* from_tab,
-                     content::WebContents* to_tab) {
-    EXPECT_EQ("ok-negotiating",
-              ExecuteJavascript("negotiateCall()", from_tab));
-
-    // Ensure the call gets up on both sides.
-    EXPECT_TRUE(test::PollingWaitUntil("getPeerConnectionReadyState()",
-                                       "active", from_tab));
-    EXPECT_TRUE(test::PollingWaitUntil("getPeerConnectionReadyState()",
-                                       "active", to_tab));
-  }
-
   base::FilePath CreateTemporaryWaveFile() {
     base::FilePath filename;
     EXPECT_TRUE(base::CreateTemporaryFile(&filename));
@@ -134,8 +121,6 @@
     EXPECT_TRUE(base::Move(filename, wav_filename));
     return wav_filename;
   }
-
-  test::PeerConnectionServerRunner peerconnection_server_;
 };
 
 class AudioRecorder {
@@ -373,7 +358,6 @@
 #endif
   ASSERT_TRUE(test::HasReferenceFilesInCheckout());
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-  ASSERT_TRUE(peerconnection_server_.Start());
 
   ASSERT_TRUE(ForceMicrophoneVolumeTo100Percent());
 
@@ -388,15 +372,16 @@
   ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage));
 
-  ConnectToPeerConnectionServer("peer 1", left_tab);
-  ConnectToPeerConnectionServer("peer 2", right_tab);
-
+  // Prepare the peer connections manually in this test since we don't add
+  // getUserMedia-derived media streams in this test like the other tests.
   EXPECT_EQ("ok-peerconnection-created",
             ExecuteJavascript("preparePeerConnection()", left_tab));
+  EXPECT_EQ("ok-peerconnection-created",
+            ExecuteJavascript("preparePeerConnection()", right_tab));
 
   AddAudioFile(kReferenceFileRelativeUrl, left_tab);
 
-  EstablishCall(left_tab, right_tab);
+  NegotiateCall(left_tab, right_tab);
 
   // Note: the media flow isn't necessarily established on the connection just
   // because the ready state is ok on both sides. We sleep a bit between call
@@ -418,8 +403,6 @@
   VLOG(0) << "Done recording to " << recording.value() << std::endl;
 
   HangUp(left_tab);
-  WaitUntilHangupVerified(left_tab);
-  WaitUntilHangupVerified(right_tab);
 
   base::FilePath trimmed_recording = CreateTemporaryWaveFile();
 
@@ -438,6 +421,4 @@
 
   EXPECT_TRUE(base::DeleteFile(recording, false));
   EXPECT_TRUE(base::DeleteFile(trimmed_recording, false));
-
-  ASSERT_TRUE(peerconnection_server_.Stop());
 }
diff --git a/chrome/browser/media/chrome_webrtc_browsertest.cc b/chrome/browser/media/chrome_webrtc_browsertest.cc
index 6fd8643..7127c09 100644
--- a/chrome/browser/media/chrome_webrtc_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_browsertest.cc
@@ -48,7 +48,6 @@
  public:
   WebRtcBrowserTest() {}
   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
-    test::PeerConnectionServerRunner::KillAllPeerConnectionServers();
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
@@ -129,8 +128,6 @@
     return false;
 #endif
   }
-
-  test::PeerConnectionServerRunner peerconnection_server_;
 };
 
 static const bool kRunTestsWithFlag[] = { false, true };
@@ -144,14 +141,16 @@
 
   ASSERT_TRUE(test::HasReferenceFilesInCheckout());
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-  ASSERT_TRUE(peerconnection_server_.Start());
 
   content::WebContents* left_tab =
       OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
   content::WebContents* right_tab =
       OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
 
-  EstablishCall(left_tab, right_tab);
+  SetupPeerconnectionWithLocalStream(left_tab);
+  SetupPeerconnectionWithLocalStream(right_tab);
+
+  NegotiateCall(left_tab, right_tab);
 
   StartDetectingVideo(left_tab, "remote-view");
   StartDetectingVideo(right_tab, "remote-view");
@@ -160,10 +159,6 @@
   WaitForVideoToPlay(right_tab);
 
   HangUp(left_tab);
-  WaitUntilHangupVerified(left_tab);
-  WaitUntilHangupVerified(right_tab);
-
-  ASSERT_TRUE(peerconnection_server_.Stop());
 }
 
 IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MANUAL_CpuUsage15Seconds) {
@@ -171,7 +166,6 @@
 
   ASSERT_TRUE(test::HasReferenceFilesInCheckout());
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-  ASSERT_TRUE(peerconnection_server_.Start());
 
   base::FilePath results_file;
   ASSERT_TRUE(base::CreateTemporaryFile(&results_file));
@@ -203,20 +197,19 @@
   content::WebContents* right_tab =
       OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
 
-  EstablishCall(left_tab, right_tab);
+  SetupPeerconnectionWithLocalStream(left_tab);
+  SetupPeerconnectionWithLocalStream(right_tab);
+
+  NegotiateCall(left_tab, right_tab);
 
   test::SleepInJavascript(left_tab, 15000);
 
   HangUp(left_tab);
-  WaitUntilHangupVerified(left_tab);
-  WaitUntilHangupVerified(right_tab);
 
 #if !defined(OS_MACOSX)
   PrintProcessMetrics(renderer_process_metrics.get(), "_r");
 #endif
   PrintProcessMetrics(browser_process_metrics.get(), "_b");
-
-  ASSERT_TRUE(peerconnection_server_.Stop());
 }
 
 // This is manual for its long execution time.
@@ -226,7 +219,6 @@
 
   ASSERT_TRUE(test::HasReferenceFilesInCheckout());
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-  ASSERT_TRUE(peerconnection_server_.Start());
 
   ASSERT_GE(TestTimeouts::action_max_timeout().InSeconds(), 100) <<
       "This is a long-running test; you must specify "
@@ -237,7 +229,10 @@
   content::WebContents* right_tab =
       OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
 
-  EstablishCall(left_tab, right_tab);
+  SetupPeerconnectionWithLocalStream(left_tab);
+  SetupPeerconnectionWithLocalStream(right_tab);
+
+  NegotiateCall(left_tab, right_tab);
 
   StartDetectingVideo(left_tab, "remote-view");
   StartDetectingVideo(right_tab, "remote-view");
@@ -267,10 +262,6 @@
   test::PrintMetricsForAllStreams(*first_pc_dict);
 
   HangUp(left_tab);
-  WaitUntilHangupVerified(left_tab);
-  WaitUntilHangupVerified(right_tab);
-
-  ASSERT_TRUE(peerconnection_server_.Stop());
 }
 
 IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MANUAL_TestWebAudioMediaStream) {
diff --git a/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc b/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc
index 14e461f..49e59a3 100644
--- a/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc
@@ -32,7 +32,6 @@
   virtual ~WebRtcDisableEncryptionFlagBrowserTest() {}
 
   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
-    test::PeerConnectionServerRunner::KillAllPeerConnectionServers();
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
@@ -44,9 +43,6 @@
     command_line->AppendSwitch(switches::kDisableWebRtcEncryption);
   }
 
- protected:
-  test::PeerConnectionServerRunner peerconnection_server_;
-
  private:
   DISALLOW_COPY_AND_ASSIGN(WebRtcDisableEncryptionFlagBrowserTest);
 };
@@ -64,14 +60,16 @@
 #endif
 
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
-  ASSERT_TRUE(peerconnection_server_.Start());
 
   content::WebContents* left_tab =
       OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
   content::WebContents* right_tab =
       OpenTestPageAndGetUserMediaInNewTab(kMainWebrtcTestHtmlPage);
 
-  EstablishCall(left_tab, right_tab);
+  SetupPeerconnectionWithLocalStream(left_tab);
+  SetupPeerconnectionWithLocalStream(right_tab);
+
+  NegotiateCall(left_tab, right_tab);
 
   StartDetectingVideo(left_tab, "remote-view");
   StartDetectingVideo(right_tab, "remote-view");
@@ -98,8 +96,4 @@
             ExecuteJavascript("hasSeenCryptoInSdp()", left_tab));
 
   HangUp(left_tab);
-  WaitUntilHangupVerified(left_tab);
-  WaitUntilHangupVerified(right_tab);
-
-  ASSERT_TRUE(peerconnection_server_.Stop());
 }
diff --git a/chrome/browser/media/chrome_webrtc_typing_detection_browsertest.cc b/chrome/browser/media/chrome_webrtc_typing_detection_browsertest.cc
index 26d4c87..2777436 100644
--- a/chrome/browser/media/chrome_webrtc_typing_detection_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_typing_detection_browsertest.cc
@@ -50,10 +50,6 @@
  public:
   // TODO(phoglund): clean up duplication from audio quality browser test when
   // this test is complete and is proven to work.
-  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
-    test::PeerConnectionServerRunner::KillAllPeerConnectionServers();
-  }
-
   bool HasAllRequiredResources() {
     base::FilePath reference_file =
         GetTestDataDir().Append(kReferenceFile);
@@ -92,8 +88,6 @@
     EXPECT_TRUE(test::PollingWaitUntil("getPeerConnectionReadyState()",
                                        "active", to_tab));
   }
-
-  test::PeerConnectionServerRunner peerconnection_server_;
 };
 
 // TODO(phoglund): enable when fully implemented.
@@ -102,7 +96,6 @@
   // TODO(phoglund): make this use embedded_test_server when that test server
   // can handle files > ~400Kb.
   ASSERT_TRUE(test_server()->Start());
-  ASSERT_TRUE(peerconnection_server_.Start());
 
   ui_test_utils::NavigateToURL(
       browser(), test_server()->GetURL(kMainWebrtcTestHtmlPage));
@@ -115,9 +108,6 @@
   ui_test_utils::NavigateToURL(
       browser(), test_server()->GetURL(kMainWebrtcTestHtmlPage));
 
-  ConnectToPeerConnectionServer("peer 1", left_tab);
-  ConnectToPeerConnectionServer("peer 2", right_tab);
-
   GetUserMediaWithSpecificConstraintsAndAccept(left_tab,
                                                kAudioOnlyCallConstraints);
   EXPECT_EQ("ok-peerconnection-created",
@@ -126,7 +116,10 @@
   AddAudioFile(kReferenceFileRelativeUrl, left_tab);
   MixLocalStreamWithPreviouslyLoadedAudioFile(left_tab);
 
-  EstablishCall(left_tab, right_tab);
+  SetupPeerconnectionWithLocalStream(left_tab);
+  SetupPeerconnectionWithLocalStream(right_tab);
+
+  NegotiateCall(left_tab, right_tab);
 
   // Note: the media flow isn't necessarily established on the connection just
   // because the ready state is ok on both sides. We sleep a bit between call
@@ -141,8 +134,4 @@
   test::SleepInJavascript(left_tab, 10000);
 
   HangUp(left_tab);
-  WaitUntilHangupVerified(left_tab);
-  WaitUntilHangupVerified(right_tab);
-
-  ASSERT_TRUE(peerconnection_server_.Stop());
 }
diff --git a/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc b/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
index 280a8c0..edb42b0 100644
--- a/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
@@ -106,10 +106,7 @@
 // * zxing (see the CPP version at https://code.google.com/p/zxing)
 // * ffmpeg 0.11.1 or compatible version (see http://www.ffmpeg.org)
 //
-// The test case will launch a custom binary (peerconnection_server) which will
-// allow two WebRTC clients to find each other.
-//
-// The test also runs several other custom binaries - rgba_to_i420 converter and
+// The test runs several custom binaries - rgba_to_i420 converter and
 // frame_analyzer. Both tools can be found under third_party/webrtc/tools. The
 // test also runs a stand alone Python implementation of a WebSocket server
 // (pywebsocket) and a barcode_decoder script.
@@ -123,7 +120,6 @@
   }
 
   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
-    test::PeerConnectionServerRunner::KillAllPeerConnectionServers();
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
@@ -298,7 +294,6 @@
   }
 
  protected:
-  test::PeerConnectionServerRunner peerconnection_server_;
   VideoQualityTestConfig test_config_;
 
  private:
@@ -339,7 +334,6 @@
   ASSERT_TRUE(HasAllRequiredResources());
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
   ASSERT_TRUE(StartPyWebSocketServer());
-  ASSERT_TRUE(peerconnection_server_.Start());
 
   content::WebContents* left_tab =
       OpenPageAndGetUserMediaInNewTabWithConstraints(
@@ -350,7 +344,10 @@
           embedded_test_server()->GetURL(test_config_.capture_page),
           test_config_.constraints);
 
-  EstablishCall(left_tab, right_tab);
+  SetupPeerconnectionWithLocalStream(left_tab);
+  SetupPeerconnectionWithLocalStream(right_tab);
+
+  NegotiateCall(left_tab, right_tab);
 
   // Poll slower here to avoid flooding the log with messages: capturing and
   // sending frames take quite a bit of time.
@@ -361,8 +358,6 @@
       polling_interval_msec));
 
   HangUp(left_tab);
-  WaitUntilHangupVerified(left_tab);
-  WaitUntilHangupVerified(right_tab);
 
   EXPECT_TRUE(test::PollingWaitUntil(
       "haveMoreFramesToSend()", "no-more-frames", right_tab,
@@ -371,7 +366,6 @@
   // Shut everything down to avoid having the javascript race with the analysis
   // tools. For instance, dont have console log printouts interleave with the
   // RESULT lines from the analysis tools (crbug.com/323200).
-  ASSERT_TRUE(peerconnection_server_.Stop());
   ASSERT_TRUE(ShutdownPyWebSocketServer());
 
   chrome::CloseWebContents(browser(), left_tab, false);
diff --git a/chrome/browser/media/chrome_webrtc_webcam_browsertest.cc b/chrome/browser/media/chrome_webrtc_webcam_browsertest.cc
index 92457f5..0ca1726 100644
--- a/chrome/browser/media/chrome_webrtc_webcam_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_webcam_browsertest.cc
@@ -12,40 +12,74 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/test/browser_test_utils.h"
+#include "media/base/media_switches.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "testing/gtest/include/gtest/gtest-param-test.h"
 
 static const char kMainWebrtcTestHtmlPage[] =
     "/webrtc/webrtc_jsep01_test.html";
 
+static const char* kTestConfigFlags[] = {
+#if defined(OS_WIN)
+  switches::kForceDirectShowVideoCapture,
+  // Media Foundation is only available in Windows versions >= 7, below that the
+  // following flag has no effect; the test would run twice using DirectShow.
+  switches::kForceMediaFoundationVideoCapture
+#elif defined(OS_MACOSX)
+  switches::kForceQTKit,
+  switches::kEnableAVFoundation
+#else
+  NULL
+#endif
+};
+
 // These tests runs on real webcams and ensure WebRTC can acquire webcams
 // correctly. They will do nothing if there are no webcams on the system.
 // The webcam on the system must support up to 1080p, or the test will fail.
-class WebRtcWebcamBrowserTest : public WebRtcTestBase {
+class WebRtcWebcamBrowserTest : public WebRtcTestBase,
+    public testing::WithParamInterface<const char*> {
  public:
+  WebRtcWebcamBrowserTest() : get_user_media_call_count_(0) {}
+
   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     EXPECT_FALSE(command_line->HasSwitch(
         switches::kUseFakeDeviceForMediaStream));
     EXPECT_FALSE(command_line->HasSwitch(
         switches::kUseFakeUIForMediaStream));
+    if (GetParam())
+      command_line->AppendSwitch(GetParam());
   }
 
+ protected:
   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
- protected:
   std::string GetUserMediaAndGetStreamSize(content::WebContents* tab,
                                            const std::string& constraints) {
-    GetUserMediaWithSpecificConstraintsAndAccept(tab, constraints);
+    // We will get a permission prompt for the first getUserMedia call.
+    // Subsequent calls won't trigger a prompt.
+    if (get_user_media_call_count_ == 0) {
+      GetUserMediaWithSpecificConstraintsAndAccept(tab, constraints);
+    } else {
+      GetUserMedia(tab, constraints);
+      EXPECT_TRUE(test::PollingWaitUntil(
+          "obtainGetUserMediaResult()", "ok-got-stream", tab));
+    }
+
+    ++get_user_media_call_count_;
+
     StartDetectingVideo(tab, "local-view");
     WaitForVideoToPlay(tab);
     std::string actual_stream_size = GetStreamSize(tab, "local-view");
     CloseLastLocalStream(tab);
     return actual_stream_size;
   }
+
+  int get_user_media_call_count_;
 };
 
-IN_PROC_BROWSER_TEST_F(WebRtcWebcamBrowserTest,
+IN_PROC_BROWSER_TEST_P(WebRtcWebcamBrowserTest,
                        TestAcquiringAndReacquiringWebcam) {
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
   GURL url(embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage));
@@ -69,3 +103,7 @@
   EXPECT_EQ("1920x1080",
             GetUserMediaAndGetStreamSize(tab, kAudioVideoCallConstraints1080p));
 }
+
+INSTANTIATE_TEST_CASE_P(WebRtcWebcamBrowserTests,
+                        WebRtcWebcamBrowserTest,
+                        testing::ValuesIn(kTestConfigFlags));
diff --git a/chrome/browser/media/encrypted_media_message_filter_android.cc b/chrome/browser/media/encrypted_media_message_filter_android.cc
deleted file mode 100644
index e16b0e9..0000000
--- a/chrome/browser/media/encrypted_media_message_filter_android.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/media/encrypted_media_message_filter_android.h"
-
-#include <string>
-
-#include "chrome/common/encrypted_media_messages_android.h"
-#include "ipc/ipc_message_macros.h"
-#include "media/base/android/media_codec_bridge.h"
-#include "media/base/android/media_drm_bridge.h"
-
-using content::BrowserThread;
-using content::SupportedCodecs;
-using media::MediaCodecBridge;
-using media::MediaDrmBridge;
-
-namespace chrome {
-
-const size_t kMaxKeySystemLength = 256;
-
-enum CodecType {
-  CODEC_AUDIO,
-  CODEC_VIDEO
-};
-
-struct CodecInfo {
-  SupportedCodecs codec;
-  CodecType codec_type;
-  const char* codec_name;
-  const char* container_mime_type;
-};
-
-const CodecInfo kCodecsToQuery[] = {
-  {content::EME_CODEC_WEBM_VORBIS, CODEC_AUDIO, "vorbis", "video/webm"},
-  {content::EME_CODEC_WEBM_VP8, CODEC_VIDEO, "vp8", "video/webm"},
-  {content::EME_CODEC_WEBM_VP9, CODEC_VIDEO, "vp9", "video/webm"},
-#if defined(USE_PROPRIETARY_CODECS)
-  {content::EME_CODEC_MP4_AAC, CODEC_AUDIO, "mp4a", "video/mp4"},
-  {content::EME_CODEC_MP4_AVC1, CODEC_VIDEO, "avc1", "video/mp4"}
-#endif  // defined(USE_PROPRIETARY_CODECS)
-};
-
-static SupportedCodecs GetSupportedCodecs(
-    const SupportedKeySystemRequest& request,
-    bool video_must_be_compositable) {
-  const std::string& key_system = request.key_system;
-  SupportedCodecs supported_codecs = content::EME_CODEC_NONE;
-
-  for (size_t i = 0; i < arraysize(kCodecsToQuery); ++i) {
-    const CodecInfo& info = kCodecsToQuery[i];
-    // TODO(qinmin): Remove the composition logic when secure contents can be
-    // composited.
-    bool is_secure = (info.codec_type == CODEC_VIDEO)
-                         ? (!video_must_be_compositable) : false;
-    if ((request.codecs & info.codec) &&
-        MediaDrmBridge::IsKeySystemSupportedWithType(
-            key_system, info.container_mime_type) &&
-        MediaCodecBridge::CanDecode(info.codec_name, is_secure)) {
-      supported_codecs |= info.codec;
-    }
-  }
-
-  return supported_codecs;
-}
-
-EncryptedMediaMessageFilterAndroid::EncryptedMediaMessageFilterAndroid()
-    : BrowserMessageFilter(EncryptedMediaMsgStart) {}
-
-EncryptedMediaMessageFilterAndroid::~EncryptedMediaMessageFilterAndroid() {}
-
-bool EncryptedMediaMessageFilterAndroid::OnMessageReceived(
-    const IPC::Message& message, bool* message_was_ok) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP_EX(
-      EncryptedMediaMessageFilterAndroid, message, *message_was_ok)
-    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_GetSupportedKeySystems,
-                        OnGetSupportedKeySystems)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP_EX()
-  return handled;
-}
-
-void EncryptedMediaMessageFilterAndroid::OverrideThreadForMessage(
-    const IPC::Message& message, BrowserThread::ID* thread) {
-  // Move the IPC handling to FILE thread as it is not very cheap.
-  if (message.type() == ChromeViewHostMsg_GetSupportedKeySystems::ID)
-    *thread = BrowserThread::FILE;
-}
-
-void EncryptedMediaMessageFilterAndroid::OnGetSupportedKeySystems(
-    const SupportedKeySystemRequest& request,
-    SupportedKeySystemResponse* response) {
-  if (!response) {
-    NOTREACHED() << "NULL response pointer provided.";
-    return;
-  }
-
-  if (request.key_system.size() > kMaxKeySystemLength) {
-    NOTREACHED() << "Invalid key system: " << request.key_system;
-    return;
-  }
-
-  if (!MediaDrmBridge::IsKeySystemSupported(request.key_system))
-    return;
-
-  DCHECK(request.codecs & content::EME_CODEC_ALL) << "unrecognized codec";
-  response->key_system = request.key_system;
-  // TODO(qinmin): check composition is supported or not.
-  response->compositing_codecs = GetSupportedCodecs(request, true);
-  response->non_compositing_codecs = GetSupportedCodecs(request, false);
-}
-
-}  // namespace chrome
diff --git a/chrome/browser/media/encrypted_media_message_filter_android.h b/chrome/browser/media/encrypted_media_message_filter_android.h
deleted file mode 100644
index 9d426ae..0000000
--- a/chrome/browser/media/encrypted_media_message_filter_android.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_MEDIA_ENCRYPTED_MEDIA_MESSAGE_FILTER_ANDROID_H_
-#define CHROME_BROWSER_MEDIA_ENCRYPTED_MEDIA_MESSAGE_FILTER_ANDROID_H_
-
-#include "base/basictypes.h"
-#include "content/public/browser/browser_message_filter.h"
-
-struct SupportedKeySystemRequest;
-struct SupportedKeySystemResponse;
-
-namespace chrome {
-
-// Message filter for EME on android. It is responsible for getting the
-// SupportedKeySystems information and passing it back to renderer.
-class EncryptedMediaMessageFilterAndroid
-    : public content::BrowserMessageFilter {
- public:
-  EncryptedMediaMessageFilterAndroid();
-
- private:
-  virtual ~EncryptedMediaMessageFilterAndroid();
-
-  // BrowserMessageFilter implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message,
-                                 bool* message_was_ok) OVERRIDE;
-  virtual void OverrideThreadForMessage(
-      const IPC::Message& message,
-      content::BrowserThread::ID* thread) OVERRIDE;
-
-  // Retrieve the supported key systems.
-  void OnGetSupportedKeySystems(
-      const SupportedKeySystemRequest& request,
-      SupportedKeySystemResponse* response);
-
-  DISALLOW_COPY_AND_ASSIGN(EncryptedMediaMessageFilterAndroid);
-};
-
-}  // namespace chrome
-
-#endif  // CHROME_BROWSER_MEDIA_ENCRYPTED_MEDIA_MESSAGE_FILTER_ANDROID_H_
diff --git a/chrome/browser/media/media_stream_capture_indicator.cc b/chrome/browser/media/media_stream_capture_indicator.cc
index 24d9292..244a645 100644
--- a/chrome/browser/media/media_stream_capture_indicator.cc
+++ b/chrome/browser/media/media_stream_capture_indicator.cc
@@ -161,8 +161,8 @@
 
  private:
   // content::WebContentsObserver overrides.
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
-    indicator_->UnregisterWebContents(web_contents);
+  virtual void WebContentsDestroyed() OVERRIDE {
+    indicator_->UnregisterWebContents(web_contents());
     delete this;
   }
 
diff --git a/chrome/browser/media/media_stream_devices_controller.cc b/chrome/browser/media/media_stream_devices_controller.cc
index 36bc392..93d6145 100644
--- a/chrome/browser/media/media_stream_devices_controller.cc
+++ b/chrome/browser/media/media_stream_devices_controller.cc
@@ -23,6 +23,7 @@
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_entry.h"
 #include "content/public/common/media_stream_request.h"
 #include "extensions/common/constants.h"
 #include "grit/generated_resources.h"
@@ -37,19 +38,127 @@
 
 namespace {
 
-bool HasAvailableDevicesForRequest(const content::MediaStreamRequest& request) {
-  bool has_audio_device =
-      request.audio_type == content::MEDIA_NO_SERVICE ||
-      !MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices()
-          .empty();
-  bool has_video_device =
-      request.video_type == content::MEDIA_NO_SERVICE ||
-      !MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices()
-          .empty();
+// This prefix is combined with request security origins to store media access
+// permissions that the user has granted a specific page navigation instance.
+// The string value stored with the navigation instance will contain one or more
+// kMediaPermissionXxx constants that indicates the permission(s) that the user
+// has granted the page.
+const char kMediaPermissionKeyPrefix[] = "media_permissions#";
+const base::char16 kMediaPermissionAudio = static_cast<base::char16>('a');
+const base::char16 kMediaPermissionVideo = static_cast<base::char16>('v');
 
-  return has_audio_device && has_video_device;
+bool HasAvailableDevicesForRequest(const content::MediaStreamRequest& request) {
+  const content::MediaStreamDevices* audio_devices =
+      request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ?
+          &MediaCaptureDevicesDispatcher::GetInstance()
+              ->GetAudioCaptureDevices() :
+          NULL;
+
+  const content::MediaStreamDevices* video_devices =
+      request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ?
+          &MediaCaptureDevicesDispatcher::GetInstance()
+              ->GetVideoCaptureDevices() :
+          NULL;
+
+  // Check if we're being asked for audio and/or video and that either of those
+  // lists is empty.  If they are, we do not have devices available for the
+  // request.
+  // TODO(tommi): It's kind of strange to have this here since if we fail this
+  // test, there'll be a UI shown that indicates to the user that access to
+  // non-existing audio/video devices has been denied.  The user won't have
+  // any way to change that but there will be a UI shown which indicates that
+  // access is blocked.
+  if ((audio_devices != NULL && audio_devices->empty()) ||
+      (video_devices != NULL && video_devices->empty())) {
+    return false;
+  }
+
+  // Note: we check requested_[audio|video]_device_id before dereferencing
+  // [audio|video]_devices.  If the requested device id is non-empty, then
+  // the corresponding device list must not be NULL.
+
+  if (!request.requested_audio_device_id.empty() &&
+      !audio_devices->FindById(request.requested_audio_device_id)) {
+    return false;
+  }
+
+  if (!request.requested_video_device_id.empty() &&
+      !video_devices->FindById(request.requested_video_device_id)) {
+    return false;
+  }
+
+  return true;
 }
 
+base::string16 GetMediaPermissionsFromNavigationEntry(
+    content::NavigationEntry* navigation_entry,
+    const content::MediaStreamRequest& request) {
+  const std::string key(kMediaPermissionKeyPrefix +
+                        request.security_origin.spec());
+
+  base::string16 permissions;
+  if (!navigation_entry->GetExtraData(key, &permissions)) {
+    DCHECK(permissions.empty());
+  }
+
+  return permissions;
+}
+
+void SetMediaPermissionsForNavigationEntry(
+    content::NavigationEntry* navigation_entry,
+    const content::MediaStreamRequest& request,
+    const base::string16& permissions) {
+  const std::string key(kMediaPermissionKeyPrefix +
+                        request.security_origin.spec());
+  permissions.empty() ?
+      navigation_entry->ClearExtraData(key) :
+      navigation_entry->SetExtraData(key, permissions);
+}
+
+void SetMediaPermissionsForNavigationEntry(
+    content::NavigationEntry* navigation_entry,
+    const content::MediaStreamRequest& request,
+    bool allow_audio,
+    bool allow_video) {
+  base::string16 permissions;
+  if (allow_audio)
+    permissions += kMediaPermissionAudio;
+  if (allow_video)
+    permissions += kMediaPermissionVideo;
+  SetMediaPermissionsForNavigationEntry(navigation_entry, request, permissions);
+}
+
+bool IsRequestAllowedByNavigationEntry(
+    content::NavigationEntry* navigation_entry,
+    const content::MediaStreamRequest& request) {
+  using content::MEDIA_NO_SERVICE;
+  using content::MEDIA_DEVICE_AUDIO_CAPTURE;
+  using content::MEDIA_DEVICE_VIDEO_CAPTURE;
+
+  // If we aren't being asked for at least one of these two, fail right away.
+  if (!navigation_entry ||
+      (request.audio_type != MEDIA_DEVICE_AUDIO_CAPTURE &&
+       request.video_type != MEDIA_DEVICE_VIDEO_CAPTURE)) {
+    return false;
+  }
+
+  base::string16 permissions =
+      GetMediaPermissionsFromNavigationEntry(navigation_entry, request);
+
+  bool audio_requested_and_granted =
+      request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE &&
+      permissions.find(kMediaPermissionAudio) != base::string16::npos;
+
+  bool video_requested_and_granted =
+      request.video_type == MEDIA_DEVICE_VIDEO_CAPTURE &&
+      permissions.find(kMediaPermissionVideo) != base::string16::npos;
+
+  return
+      (audio_requested_and_granted || request.audio_type == MEDIA_NO_SERVICE) &&
+      (video_requested_and_granted || request.video_type == MEDIA_NO_SERVICE);
+}
+
+
 bool IsInKioskMode() {
   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
     return true;
@@ -200,21 +309,16 @@
     return true;
   }
 
-  if (request_.request_type == content::MEDIA_OPEN_DEVICE) {
-    bool no_matched_audio_device =
-        (request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE &&
-         !request_.requested_audio_device_id.empty() &&
-         MediaCaptureDevicesDispatcher::GetInstance()->GetRequestedAudioDevice(
-             request_.requested_audio_device_id) == NULL);
-    bool no_matched_video_device =
-        (request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE &&
-         !request_.requested_video_device_id.empty() &&
-         MediaCaptureDevicesDispatcher::GetInstance()->GetRequestedVideoDevice(
-             request_.requested_video_device_id) == NULL);
-    if (no_matched_audio_device || no_matched_video_device) {
-      Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED);
-      return true;
-    }
+  // Check if the navigation entry has previously been granted access.
+  // We do this after the IsDefaultMediaAccessBlocked check to handle the use
+  // case where the user modifies the content settings to 'deny' after having
+  // previously granted the page access and the permissions in the
+  // NavigationEntry are out of date.
+  content::NavigationEntry* navigation_entry =
+      web_contents_->GetController().GetVisibleEntry();
+  if (IsRequestAllowedByNavigationEntry(navigation_entry, request_)) {
+    Accept(false);
+    return true;
   }
 
   // Show the infobar.
@@ -305,6 +409,15 @@
                                           get_default_video_device,
                                           &devices);
         }
+
+        // Tag this navigation entry with the granted permissions.
+        // This avoids repeated prompts for requests accessed via http.
+        content::NavigationEntry* navigation_entry =
+            web_contents_->GetController().GetVisibleEntry();
+        if (navigation_entry) {
+          SetMediaPermissionsForNavigationEntry(
+              navigation_entry, request_, audio_allowed, video_allowed);
+        }
         break;
       }
       case content::MEDIA_DEVICE_ACCESS: {
@@ -354,8 +467,18 @@
   DLOG(WARNING) << "MediaStreamDevicesController::Deny: " << result;
   NotifyUIRequestDenied();
 
-  if (update_content_setting)
+  // Clear previously allowed permissions from the navigation entry if any.
+  content::NavigationEntry* navigation_entry =
+      web_contents_->GetController().GetVisibleEntry();
+  if (navigation_entry) {
+    SetMediaPermissionsForNavigationEntry(
+        navigation_entry, request_, false, false);
+  }
+
+  if (update_content_setting) {
+    CHECK_EQ(content::MEDIA_DEVICE_PERMISSION_DENIED, result);
     SetPermission(false);
+  }
 
   content::MediaResponseCallback cb = callback_;
   callback_.Reset();
@@ -419,7 +542,7 @@
 void MediaStreamDevicesController::Cancelled() {
   UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
                             kCancel, kPermissionActionsMax);
-  Deny(true, content::MEDIA_DEVICE_PERMISSION_DISMISSED);
+  Deny(false, content::MEDIA_DEVICE_PERMISSION_DISMISSED);
 }
 
 void MediaStreamDevicesController::RequestFinished() {
@@ -589,7 +712,7 @@
       CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
   if (request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE) !=
       request_permissions_.end()) {
-      profile_->GetHostContentSettingsMap()->SetContentSetting(
+    profile_->GetHostContentSettingsMap()->SetContentSetting(
         primary_pattern,
         ContentSettingsPattern::Wildcard(),
         CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
diff --git a/chrome/browser/media/webrtc_browsertest_base.cc b/chrome/browser/media/webrtc_browsertest_base.cc
index a85e0c9..f469ff9 100644
--- a/chrome/browser/media/webrtc_browsertest_base.cc
+++ b/chrome/browser/media/webrtc_browsertest_base.cc
@@ -248,44 +248,71 @@
   return result;
 }
 
-// The peer connection server lets our two tabs find each other and talk to
-// each other (e.g. it is the application-specific "signaling solution").
-void WebRtcTestBase::ConnectToPeerConnectionServer(
-    const std::string& peer_name,
-    content::WebContents* tab_contents) const {
-  std::string javascript = base::StringPrintf(
-      "connect('http://localhost:%s', '%s');",
-      test::PeerConnectionServerRunner::kDefaultPort, peer_name.c_str());
-  EXPECT_EQ("ok-connected", ExecuteJavascript(javascript, tab_contents));
+void WebRtcTestBase::SetupPeerconnectionWithLocalStream(
+    content::WebContents* tab) const {
+  EXPECT_EQ("ok-peerconnection-created",
+            ExecuteJavascript("preparePeerConnection()", tab));
+  EXPECT_EQ("ok-added", ExecuteJavascript("addLocalStream()", tab));
 }
 
-void WebRtcTestBase::EstablishCall(content::WebContents* from_tab,
+std::string WebRtcTestBase::CreateLocalOffer(
+      content::WebContents* from_tab) const {
+  std::string response = ExecuteJavascript("createLocalOffer({})", from_tab);
+  EXPECT_EQ("ok-", response.substr(0, 3)) << "Failed to create local offer: "
+      << response;
+
+  std::string local_offer = response.substr(3);
+  return local_offer;
+}
+
+std::string WebRtcTestBase::CreateAnswer(std::string local_offer,
+                                         content::WebContents* to_tab) const {
+  std::string javascript =
+      base::StringPrintf("receiveOfferFromPeer('%s', {})", local_offer.c_str());
+  std::string response = ExecuteJavascript(javascript, to_tab);
+  EXPECT_EQ("ok-", response.substr(0, 3))
+      << "Receiving peer failed to receive offer and create answer: "
+      << response;
+
+  std::string answer = response.substr(3);
+  return answer;
+}
+
+void WebRtcTestBase::ReceiveAnswer(std::string answer,
+                                   content::WebContents* from_tab) const {
+  ASSERT_EQ(
+      "ok-accepted-answer",
+      ExecuteJavascript(
+          base::StringPrintf("receiveAnswerFromPeer('%s')", answer.c_str()),
+          from_tab));
+}
+
+void WebRtcTestBase::GatherAndSendIceCandidates(
+    content::WebContents* from_tab,
+    content::WebContents* to_tab) const {
+  std::string ice_candidates =
+      ExecuteJavascript("getAllIceCandidates()", from_tab);
+
+  EXPECT_EQ("ok-received-candidates", ExecuteJavascript(
+      base::StringPrintf("receiveIceCandidates('%s')", ice_candidates.c_str()),
+      to_tab));
+}
+
+void WebRtcTestBase::NegotiateCall(content::WebContents* from_tab,
                                    content::WebContents* to_tab) const {
-  ConnectToPeerConnectionServer("peer 1", from_tab);
-  ConnectToPeerConnectionServer("peer 2", to_tab);
+  std::string local_offer = CreateLocalOffer(from_tab);
+  std::string answer = CreateAnswer(local_offer, to_tab);
+  ReceiveAnswer(answer, from_tab);
 
-  EXPECT_EQ("ok-peerconnection-created",
-            ExecuteJavascript("preparePeerConnection()", from_tab));
-  EXPECT_EQ("ok-added", ExecuteJavascript("addLocalStream()", from_tab));
-  EXPECT_EQ("ok-negotiating", ExecuteJavascript("negotiateCall()", from_tab));
-
-  // Ensure the call gets up on both sides.
-  EXPECT_TRUE(test::PollingWaitUntil("getPeerConnectionReadyState()",
-                                     "active", from_tab));
-  EXPECT_TRUE(test::PollingWaitUntil("getPeerConnectionReadyState()",
-                                     "active", to_tab));
+  // Send all ICE candidates (wait for gathering to finish if necessary).
+  GatherAndSendIceCandidates(to_tab, from_tab);
+  GatherAndSendIceCandidates(from_tab, to_tab);
 }
 
 void WebRtcTestBase::HangUp(content::WebContents* from_tab) const {
   EXPECT_EQ("ok-call-hung-up", ExecuteJavascript("hangUp()", from_tab));
 }
 
-void WebRtcTestBase::WaitUntilHangupVerified(
-    content::WebContents* tab_contents) const {
-  EXPECT_TRUE(test::PollingWaitUntil("getPeerConnectionReadyState()",
-                                     "no-peer-connection", tab_contents));
-}
-
 void WebRtcTestBase::DetectErrorsInJavaScript() {
   detect_errors_in_javascript_ = true;
 }
diff --git a/chrome/browser/media/webrtc_browsertest_base.h b/chrome/browser/media/webrtc_browsertest_base.h
index 217e5e3..acfdb23 100644
--- a/chrome/browser/media/webrtc_browsertest_base.h
+++ b/chrome/browser/media/webrtc_browsertest_base.h
@@ -74,18 +74,23 @@
   // Closes the last local stream acquired by the GetUserMedia* methods.
   void CloseLastLocalStream(content::WebContents* tab_contents) const;
 
-  void ConnectToPeerConnectionServer(const std::string& peer_name,
-                                     content::WebContents* tab_contents) const;
   std::string ExecuteJavascript(const std::string& javascript,
                                 content::WebContents* tab_contents) const;
 
-  void EstablishCall(content::WebContents* from_tab,
+  // Sets up a peer connection in the tab and adds the current local stream
+  // (which you can prepare by calling one of the GetUserMedia* methods above).
+  void SetupPeerconnectionWithLocalStream(content::WebContents* tab) const;
+
+  // Exchanges offers and answers between the peer connections in the
+  // respective tabs. Before calling this, you must have prepared peer
+  // connections in both tabs and configured them as you like (for instance by
+  // calling SetupPeerconnectionWithLocalStream).
+  void NegotiateCall(content::WebContents* from_tab,
                      content::WebContents* to_tab) const;
 
+  // Hangs up a negotiated call.
   void HangUp(content::WebContents* from_tab) const;
 
-  void WaitUntilHangupVerified(content::WebContents* tab_contents) const;
-
   // Call this to enable monitoring of javascript errors for this test method.
   // This will only work if the tests are run sequentially by the test runner
   // (i.e. with --test-launcher-developer-mode or --test-launcher-jobs=1).
@@ -108,6 +113,14 @@
  private:
   void CloseInfoBarInTab(content::WebContents* tab_contents,
                          infobars::InfoBar* infobar) const;
+
+  std::string CreateLocalOffer(content::WebContents* from_tab) const;
+  std::string CreateAnswer(std::string local_offer,
+                           content::WebContents* to_tab) const;
+  void ReceiveAnswer(std::string answer, content::WebContents* from_tab) const;
+  void GatherAndSendIceCandidates(content::WebContents* from_tab,
+                                  content::WebContents* to_tab) const;
+
   infobars::InfoBar* GetUserMediaAndWaitForInfoBar(
       content::WebContents* tab_contents,
       const std::string& constraints) const;
diff --git a/chrome/browser/media/webrtc_browsertest_common.cc b/chrome/browser/media/webrtc_browsertest_common.cc
index eb2e0ce..f66c810 100644
--- a/chrome/browser/media/webrtc_browsertest_common.cc
+++ b/chrome/browser/media/webrtc_browsertest_common.cc
@@ -4,10 +4,8 @@
 
 #include "chrome/browser/media/webrtc_browsertest_common.h"
 
-#include "base/command_line.h"
 #include "base/file_util.h"
 #include "base/path_service.h"
-#include "base/process/launch.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/test_timeouts.h"
 #include "base/time/time.h"
@@ -134,49 +132,4 @@
   return false;
 }
 
-static base::FilePath::CharType kServerExecutable[] =
-#if defined(OS_WIN)
-    FILE_PATH_LITERAL("peerconnection_server.exe");
-#else
-    FILE_PATH_LITERAL("peerconnection_server");
-#endif
-
-const char PeerConnectionServerRunner::kDefaultPort[] = "7778";
-
-bool PeerConnectionServerRunner::Start() {
-  base::FilePath peerconnection_server;
-  if (!PathService::Get(base::DIR_MODULE, &peerconnection_server)) {
-    LOG(ERROR) << "Failed retrieving base::DIR_MODULE!";
-    return false;
-  }
-  peerconnection_server = peerconnection_server.Append(kServerExecutable);
-
-  if (!base::PathExists(peerconnection_server)) {
-    LOG(ERROR)
-        << "Missing " << kServerExecutable << ". You must build "
-        << "it so it ends up next to the browser test binary.";
-    return false;
-  }
-
-  CommandLine command_line(peerconnection_server);
-  command_line.AppendSwitchASCII("port", kDefaultPort);
-  VLOG(0) << "Running " << command_line.GetCommandLineString();
-  return base::LaunchProcess(command_line,
-                             base::LaunchOptions(),
-                             &server_pid_);
-}
-
-bool PeerConnectionServerRunner::Stop() {
-  return base::KillProcess(server_pid_, 0, false);
-}
-
-void PeerConnectionServerRunner::KillAllPeerConnectionServers() {
-  if (!base::KillProcesses(kServerExecutable, -1, NULL)) {
-    LOG(ERROR) << "Failed to kill instances of " << kServerExecutable << ".";
-    return;
-  }
-  base::WaitForProcessesToExit(kServerExecutable,
-                               base::TimeDelta::FromSeconds(5), NULL);
-}
-
 }  // namespace test
diff --git a/chrome/browser/media/webrtc_browsertest_common.h b/chrome/browser/media/webrtc_browsertest_common.h
index 0de994d..27ab604 100644
--- a/chrome/browser/media/webrtc_browsertest_common.h
+++ b/chrome/browser/media/webrtc_browsertest_common.h
@@ -54,25 +54,6 @@
                       content::WebContents* tab_contents,
                       int poll_interval_msec);
 
-class PeerConnectionServerRunner {
- public:
-  static const char kDefaultPort[];
-
-  PeerConnectionServerRunner(): server_pid_(0) {}
-  ~PeerConnectionServerRunner() {}
-
-  // Starts the peerconnection server on localhost on |kDefaultPort|.
-  bool Start();
-
-  // Stops the peerconnection server.
-  bool Stop();
-
-  static void KillAllPeerConnectionServers();
-
- private:
-  base::ProcessHandle server_pid_;
-};
-
 }  // namespace test
 
 #endif  // CHROME_BROWSER_MEDIA_WEBRTC_BROWSERTEST_COMMON_H_
diff --git a/chrome/browser/media/webrtc_logging_handler_host.cc b/chrome/browser/media/webrtc_logging_handler_host.cc
index d9ea675..816be38 100644
--- a/chrome/browser/media/webrtc_logging_handler_host.cc
+++ b/chrome/browser/media/webrtc_logging_handler_host.cc
@@ -184,6 +184,7 @@
     return;
   }
   upload_callback_ = callback;
+  logging_state_ = UPLOADING;
   content::BrowserThread::PostTaskAndReplyWithResult(
       content::BrowserThread::FILE,
       FROM_HERE,
@@ -224,11 +225,25 @@
           WebRtcLoggingMessageData(base::Time::Now(), message)));
 }
 
+void WebRtcLoggingHandlerHost::StartRtpDump(
+    bool incoming,
+    bool outgoing,
+    const GenericDoneCallback& callback) {
+  NOTIMPLEMENTED();
+}
+
+void WebRtcLoggingHandlerHost::StopRtpDump(
+    bool incoming,
+    bool outgoing,
+    const GenericDoneCallback& callback) {
+  NOTIMPLEMENTED();
+}
+
 void WebRtcLoggingHandlerHost::OnChannelClosing() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (logging_state_ == STARTED || logging_state_ == STOPPED) {
     if (upload_log_on_render_close_) {
-      logging_state_ = STOPPED;
+      logging_state_ = UPLOADING;
       logging_started_time_ = base::Time();
       content::BrowserThread::PostTaskAndReplyWithResult(
           content::BrowserThread::FILE,
@@ -386,12 +401,16 @@
   // GPU
   gpu::GPUInfo gpu_info = content::GpuDataManager::GetInstance()->GetGPUInfo();
   LogToCircularBuffer(
-      "Gpu: machine-model-name='" + gpu_info.machine_model_name +
-      "', machine-model-version=" + gpu_info.machine_model_version +
-      "', vendor-id=" + IntToString(gpu_info.gpu.vendor_id) +
+      "Gpu: machine-model-name=" + gpu_info.machine_model_name +
+      ", machine-model-version=" + gpu_info.machine_model_version +
+      ", vendor-id=" + IntToString(gpu_info.gpu.vendor_id) +
       ", device-id=" + IntToString(gpu_info.gpu.device_id) +
-      ", driver-vendor='" + gpu_info.driver_vendor +
-      "', driver-version=" + gpu_info.driver_version);
+      ", driver-vendor=" + gpu_info.driver_vendor +
+      ", driver-version=" + gpu_info.driver_version);
+  LogToCircularBuffer(
+      "OpenGL: gl-vendor=" + gpu_info.gl_vendor +
+      ", gl-renderer=" + gpu_info.gl_renderer +
+      ", gl-version=" + gpu_info.gl_version);
 
   // Network interfaces
   LogToCircularBuffer("Discovered " + IntToString(network_list.size()) +
@@ -436,11 +455,9 @@
 void WebRtcLoggingHandlerHost::TriggerUploadLog(
     const base::FilePath& log_directory) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  DCHECK(logging_state_ == STOPPED);
+  DCHECK_EQ(logging_state_, UPLOADING);
 
-  logging_state_ = UPLOADING;
   WebRtcLogUploadDoneData upload_done_data;
-
   upload_done_data.log_path = log_directory;
   upload_done_data.callback = upload_callback_;
   upload_done_data.host = this;
diff --git a/chrome/browser/media/webrtc_logging_handler_host.h b/chrome/browser/media/webrtc_logging_handler_host.h
index d4605ba..835fbda 100644
--- a/chrome/browser/media/webrtc_logging_handler_host.h
+++ b/chrome/browser/media/webrtc_logging_handler_host.h
@@ -73,6 +73,22 @@
     upload_log_on_render_close_ = should_upload;
   }
 
+  // Starts dumping the RTP headers for the specified direction. Must be called
+  // on the IO thread. |incoming| and |outgoing| specifies which direction(s) of
+  // RTP packets should be dumped. |callback| will be called when starting the
+  // dump is done.
+  void StartRtpDump(bool incoming,
+                    bool outgoing,
+                    const GenericDoneCallback& callback);
+
+  // Stops dumping the RTP headers for the specified direction. Must be called
+  // on the IO thread. |incoming| and |outgoing| specifies which direction(s) of
+  // RTP packet dumping should be stopped. |callback| will be called when
+  // stopping the dump is done.
+  void StopRtpDump(bool incoming,
+                   bool outgoing,
+                   const GenericDoneCallback& callback);
+
  private:
   // States used for protecting from function calls made at non-allowed points
   // in time. For example, StartLogging() is only allowed in CLOSED state.
diff --git a/chrome/browser/media_galleries/fileapi/iphoto_data_provider.cc b/chrome/browser/media_galleries/fileapi/iphoto_data_provider.cc
index f954b87..bdb1fa4 100644
--- a/chrome/browser/media_galleries/fileapi/iphoto_data_provider.cc
+++ b/chrome/browser/media_galleries/fileapi/iphoto_data_provider.cc
@@ -48,7 +48,6 @@
 
 void IPhotoDataProvider::BuildIndices(const parser::Library& library) {
   typedef base::hash_map<uint64, const base::FilePath*> IdIndex;
-  typedef base::hash_map<uint64, std::string> IdFileNameIndex;
 
   IdIndex photo_id_index;
   IdIndex originals_id_index;
diff --git a/chrome/browser/media_galleries/media_file_system_registry.cc b/chrome/browser/media_galleries/media_file_system_registry.cc
index 08cecd1..a53ed2b 100644
--- a/chrome/browser/media_galleries/media_file_system_registry.cc
+++ b/chrome/browser/media_galleries/media_file_system_registry.cc
@@ -85,7 +85,7 @@
 
    private:
     // content::WebContentsObserver
-    virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+    virtual void WebContentsDestroyed() OVERRIDE;
     virtual void NavigationEntryCommitted(
         const content::LoadCommittedDetails& load_details) OVERRIDE;
 
@@ -155,9 +155,8 @@
       manager_(manager) {
 }
 
-void RPHReferenceManager::RPHWebContentsObserver::WebContentsDestroyed(
-    WebContents* web_contents) {
-  manager_->OnWebContentsDestroyedOrNavigated(web_contents);
+void RPHReferenceManager::RPHWebContentsObserver::WebContentsDestroyed() {
+  manager_->OnWebContentsDestroyedOrNavigated(web_contents());
 }
 
 void RPHReferenceManager::RPHWebContentsObserver::NavigationEntryCommitted(
diff --git a/chrome/browser/media_galleries/media_galleries_dialog_controller.cc b/chrome/browser/media_galleries/media_galleries_dialog_controller.cc
index d815e1d..8ad59e8 100644
--- a/chrome/browser/media_galleries/media_galleries_dialog_controller.cc
+++ b/chrome/browser/media_galleries/media_galleries_dialog_controller.cc
@@ -18,7 +18,6 @@
 #include "components/storage_monitor/storage_info.h"
 #include "components/storage_monitor/storage_monitor.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/permissions/media_galleries_permission.h"
@@ -207,7 +206,7 @@
       NULL,
       0,
       base::FilePath::StringType(),
-      web_contents_->GetView()->GetTopLevelNativeWindow(),
+      web_contents_->GetTopLevelNativeWindow(),
       NULL);
 }
 
diff --git a/chrome/browser/metrics/OWNERS b/chrome/browser/metrics/OWNERS
index a4b8a7a..5423b03 100644
--- a/chrome/browser/metrics/OWNERS
+++ b/chrome/browser/metrics/OWNERS
@@ -2,3 +2,6 @@
 rtenneti@chromium.org
 isherman@chromium.org
 asvitkine@chromium.org
+
+# Primarily for omnibox-related changes.
+mpearson@chromium.org
diff --git a/chrome/browser/metrics/cloned_install_detector_unittest.cc b/chrome/browser/metrics/cloned_install_detector_unittest.cc
index dcc8bf6..6114632 100644
--- a/chrome/browser/metrics/cloned_install_detector_unittest.cc
+++ b/chrome/browser/metrics/cloned_install_detector_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "base/prefs/testing_pref_service.h"
 #include "chrome/browser/metrics/machine_id_provider.h"
-#include "chrome/browser/metrics/metrics_service.h"
+#include "chrome/browser/metrics/metrics_state_manager.h"
 #include "chrome/common/pref_names.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -37,8 +37,7 @@
 
 TEST(ClonedInstallDetectorTest, DetectClone) {
   TestingPrefServiceSimple prefs;
-  ClonedInstallDetector::RegisterPrefs(prefs.registry());
-  MetricsService::RegisterPrefs(prefs.registry());
+  MetricsStateManager::RegisterPrefs(prefs.registry());
 
   // Save a machine id that will cause a clone to be detected.
   prefs.SetInteger(prefs::kMetricsMachineId, kTestHashedId + 1);
diff --git a/chrome/browser/metrics/extension_metrics.cc b/chrome/browser/metrics/extension_metrics.cc
index b57a6f0..46d3084 100644
--- a/chrome/browser/metrics/extension_metrics.cc
+++ b/chrome/browser/metrics/extension_metrics.cc
@@ -11,7 +11,7 @@
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/metrics/proto/system_profile.pb.h"
+#include "components/metrics/proto/system_profile.pb.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension_set.h"
 #include "third_party/smhasher/src/City.h"
diff --git a/chrome/browser/metrics/extension_metrics_unittest.cc b/chrome/browser/metrics/extension_metrics_unittest.cc
index a75cc1e..0f5af0a 100644
--- a/chrome/browser/metrics/extension_metrics_unittest.cc
+++ b/chrome/browser/metrics/extension_metrics_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <string>
 
-#include "chrome/common/metrics/proto/system_profile.pb.h"
+#include "components/metrics/proto/system_profile.pb.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/extension_set.h"
diff --git a/chrome/browser/metrics/metrics_log.cc b/chrome/browser/metrics/metrics_log.cc
index 239657f..532909b 100644
--- a/chrome/browser/metrics/metrics_log.cc
+++ b/chrome/browser/metrics/metrics_log.cc
@@ -37,12 +37,12 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/logging_chrome.h"
-#include "chrome/common/metrics/proto/omnibox_event.pb.h"
-#include "chrome/common/metrics/proto/profiler_event.pb.h"
-#include "chrome/common/metrics/proto/system_profile.pb.h"
 #include "chrome/common/metrics/variations/variations_util.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/installer/util/google_update_settings.h"
+#include "components/metrics/proto/omnibox_event.pb.h"
+#include "components/metrics/proto/profiler_event.pb.h"
+#include "components/metrics/proto/system_profile.pb.h"
 #include "components/nacl/common/nacl_process_type.h"
 #include "content/public/browser/gpu_data_manager.h"
 #include "content/public/common/content_client.h"
@@ -67,6 +67,7 @@
 #endif  // OS_CHROMEOS
 
 using content::GpuDataManager;
+using metrics::MetricsLogBase;
 using metrics::OmniboxEventProto;
 using metrics::ProfilerEventProto;
 using metrics::SystemProfileProto;
@@ -141,6 +142,8 @@
       return OmniboxEventProto::Suggestion::EXTENSION_APP;
     case AutocompleteMatchType::BOOKMARK_TITLE:
       return OmniboxEventProto::Suggestion::BOOKMARK_TITLE;
+    case AutocompleteMatchType::NAVSUGGEST_PERSONALIZED:
+      return OmniboxEventProto::Suggestion::NAVSUGGEST_PERSONALIZED;
     default:
       NOTREACHED();
       return OmniboxEventProto::Suggestion::UNKNOWN_RESULT_TYPE;
@@ -207,6 +210,25 @@
   }
 }
 
+SystemProfileProto::Channel AsProtobufChannel(
+    chrome::VersionInfo::Channel channel) {
+  switch (channel) {
+    case chrome::VersionInfo::CHANNEL_UNKNOWN:
+      return SystemProfileProto::CHANNEL_UNKNOWN;
+    case chrome::VersionInfo::CHANNEL_CANARY:
+      return SystemProfileProto::CHANNEL_CANARY;
+    case chrome::VersionInfo::CHANNEL_DEV:
+      return SystemProfileProto::CHANNEL_DEV;
+    case chrome::VersionInfo::CHANNEL_BETA:
+      return SystemProfileProto::CHANNEL_BETA;
+    case chrome::VersionInfo::CHANNEL_STABLE:
+      return SystemProfileProto::CHANNEL_STABLE;
+    default:
+      NOTREACHED();
+      return SystemProfileProto::CHANNEL_UNKNOWN;
+  }
+}
+
 // Computes a SHA-1 hash of |data| and returns it as a hex string.
 std::string ComputeSHA1(const std::string& data) {
   const std::string sha1 = base::SHA1HashString(data);
@@ -386,6 +408,9 @@
                      MetricsLog::GetVersionString()),
       creation_time_(base::TimeTicks::Now()),
       extension_metrics_(uma_proto()->client_id()) {
+  uma_proto()->mutable_system_profile()->set_channel(
+      AsProtobufChannel(chrome::VersionInfo::GetChannel()));
+
 #if defined(OS_CHROMEOS)
   metrics_log_chromeos_.reset(new MetricsLogChromeOS(uma_proto()));
 #endif  // OS_CHROMEOS
@@ -846,19 +871,33 @@
   omnibox_event->set_selected_index(log.selected_index);
   if (log.completed_length != base::string16::npos)
     omnibox_event->set_completed_length(log.completed_length);
+  const base::TimeDelta default_time_delta =
+      base::TimeDelta::FromMilliseconds(-1);
   if (log.elapsed_time_since_user_first_modified_omnibox !=
-      base::TimeDelta::FromMilliseconds(-1)) {
+      default_time_delta) {
     // Only upload the typing duration if it is set/valid.
     omnibox_event->set_typing_duration_ms(
         log.elapsed_time_since_user_first_modified_omnibox.InMilliseconds());
   }
-  omnibox_event->set_duration_since_last_default_match_update_ms(
-      log.elapsed_time_since_last_change_to_default_match.InMilliseconds());
+  if (log.elapsed_time_since_last_change_to_default_match !=
+      default_time_delta) {
+    omnibox_event->set_duration_since_last_default_match_update_ms(
+        log.elapsed_time_since_last_change_to_default_match.InMilliseconds());
+  }
   omnibox_event->set_current_page_classification(
       AsOmniboxEventPageClassification(log.current_page_classification));
   omnibox_event->set_input_type(AsOmniboxEventInputType(log.input_type));
-  omnibox_event->set_is_top_result_hidden_in_dropdown(
-      log.result.ShouldHideTopMatch());
+  // We consider a paste-and-search/paste-and-go action to have a closed popup
+  // (as explained in omnibox_event.proto) even if it was not, because such
+  // actions ignore the contents of the popup so it doesn't matter that it was
+  // open.
+  const bool consider_popup_open = log.is_popup_open && !log.is_paste_and_go;
+  omnibox_event->set_is_popup_open(consider_popup_open);
+  omnibox_event->set_is_paste_and_go(log.is_paste_and_go);
+  if (consider_popup_open) {
+    omnibox_event->set_is_top_result_hidden_in_dropdown(
+        log.result.ShouldHideTopMatch());
+  }
 
   for (AutocompleteResult::const_iterator i(log.result.begin());
        i != log.result.end(); ++i) {
diff --git a/chrome/browser/metrics/metrics_log.h b/chrome/browser/metrics/metrics_log.h
index 0af6f35..c074823 100644
--- a/chrome/browser/metrics/metrics_log.h
+++ b/chrome/browser/metrics/metrics_log.h
@@ -14,9 +14,9 @@
 #include "base/basictypes.h"
 #include "chrome/browser/metrics/extension_metrics.h"
 #include "chrome/browser/metrics/metrics_network_observer.h"
-#include "chrome/common/metrics/metrics_log_base.h"
 #include "chrome/common/metrics/variations/variations_util.h"
 #include "chrome/installer/util/google_update_settings.h"
+#include "components/metrics/metrics_log_base.h"
 #include "ui/gfx/size.h"
 
 class HashedExtensionMetrics;
@@ -55,7 +55,7 @@
     bool is_system_install;
     // The time at which Google Update last started an automatic update check.
     base::Time last_started_au;
-    // The time at which Google Update last successfully recieved update
+    // The time at which Google Update last successfully received update
     // information from Google servers.
     base::Time last_checked;
     // Details about Google Update's attempts to update itself.
@@ -64,7 +64,7 @@
     GoogleUpdateSettings::ProductData product_data;
 };
 
-class MetricsLog : public MetricsLogBase {
+class MetricsLog : public metrics::MetricsLogBase {
  public:
   // Creates a new metrics log of the specified type.
   // client_id is the identifier for this profile on this installation
diff --git a/chrome/browser/metrics/metrics_log_chromeos.cc b/chrome/browser/metrics/metrics_log_chromeos.cc
index 55dcc62..517447f 100644
--- a/chrome/browser/metrics/metrics_log_chromeos.cc
+++ b/chrome/browser/metrics/metrics_log_chromeos.cc
@@ -9,8 +9,8 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/login/user_manager.h"
-#include "chrome/common/metrics/proto/chrome_user_metrics_extension.pb.h"
 #include "chrome/common/pref_names.h"
+#include "components/metrics/proto/chrome_user_metrics_extension.pb.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_device.h"
diff --git a/chrome/browser/metrics/metrics_log_serializer.cc b/chrome/browser/metrics/metrics_log_serializer.cc
index b086f84..0d545ec 100644
--- a/chrome/browser/metrics/metrics_log_serializer.cc
+++ b/chrome/browser/metrics/metrics_log_serializer.cc
@@ -14,6 +14,9 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/common/pref_names.h"
 
+using metrics::MetricsLogBase;
+using metrics::MetricsLogManager;
+
 namespace {
 
 // The number of "initial" logs to save, and hope to send during a future Chrome
diff --git a/chrome/browser/metrics/metrics_log_serializer.h b/chrome/browser/metrics/metrics_log_serializer.h
index ae85b13..74d39e5 100644
--- a/chrome/browser/metrics/metrics_log_serializer.h
+++ b/chrome/browser/metrics/metrics_log_serializer.h
@@ -9,14 +9,14 @@
 
 #include "base/basictypes.h"
 #include "base/gtest_prod_util.h"
-#include "chrome/common/metrics/metrics_log_manager.h"
+#include "components/metrics/metrics_log_manager.h"
 
 namespace base {
 class ListValue;
 }
 
 // Serializer for persisting metrics logs to prefs.
-class MetricsLogSerializer : public MetricsLogManager::LogSerializer {
+class MetricsLogSerializer : public metrics::MetricsLogManager::LogSerializer {
  public:
   // Used to produce a histogram that keeps track of the status of recalling
   // persisted per logs.
@@ -39,13 +39,13 @@
   MetricsLogSerializer();
   virtual ~MetricsLogSerializer();
 
-  // Implementation of MetricsLogManager::LogSerializer
+  // Implementation of metrics::MetricsLogManager::LogSerializer
   virtual void SerializeLogs(
-      const std::vector<MetricsLogManager::SerializedLog>& logs,
-      MetricsLogManager::LogType log_type) OVERRIDE;
+      const std::vector<metrics::MetricsLogManager::SerializedLog>& logs,
+      metrics::MetricsLogManager::LogType log_type) OVERRIDE;
   virtual void DeserializeLogs(
-      MetricsLogManager::LogType log_type,
-      std::vector<MetricsLogManager::SerializedLog>* logs) OVERRIDE;
+      metrics::MetricsLogManager::LogType log_type,
+      std::vector<metrics::MetricsLogManager::SerializedLog>* logs) OVERRIDE;
 
  private:
   // Encodes the textual log data from |local_list| and writes it to the given
@@ -54,7 +54,7 @@
   // |list_length_limit| logs and |byte_limit| bytes of logs have been
   // stored. At least one of those two arguments must be non-zero.
   static void WriteLogsToPrefList(
-      const std::vector<MetricsLogManager::SerializedLog>& local_list,
+      const std::vector<metrics::MetricsLogManager::SerializedLog>& local_list,
       size_t list_length_limit,
       size_t byte_limit,
       base::ListValue* list);
@@ -63,7 +63,7 @@
   // |local_list| and returning a status code.
   static LogReadStatus ReadLogsFromPrefList(
       const base::ListValue& list,
-      std::vector<MetricsLogManager::SerializedLog>* local_list);
+      std::vector<metrics::MetricsLogManager::SerializedLog>* local_list);
 
   FRIEND_TEST_ALL_PREFIXES(MetricsLogSerializerTest, EmptyLogList);
   FRIEND_TEST_ALL_PREFIXES(MetricsLogSerializerTest, SingleElementLogList);
diff --git a/chrome/browser/metrics/metrics_log_serializer_unittest.cc b/chrome/browser/metrics/metrics_log_serializer_unittest.cc
index 5833940..386a3cb 100644
--- a/chrome/browser/metrics/metrics_log_serializer_unittest.cc
+++ b/chrome/browser/metrics/metrics_log_serializer_unittest.cc
@@ -8,6 +8,8 @@
 #include "chrome/browser/metrics/metrics_log_serializer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using metrics::MetricsLogManager;
+
 namespace {
 
 const size_t kListLengthLimit = 3;
diff --git a/chrome/browser/metrics/metrics_log_unittest.cc b/chrome/browser/metrics/metrics_log_unittest.cc
index 2f112a9..9ff887f 100644
--- a/chrome/browser/metrics/metrics_log_unittest.cc
+++ b/chrome/browser/metrics/metrics_log_unittest.cc
@@ -23,12 +23,13 @@
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/common/chrome_switches.h"
-#include "chrome/common/metrics/proto/profiler_event.pb.h"
-#include "chrome/common/metrics/proto/system_profile.pb.h"
+#include "chrome/common/chrome_version_info.h"
 #include "chrome/common/metrics/variations/variations_util.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/installer/util/google_update_settings.h"
 #include "components/metrics/metrics_hashes.h"
+#include "components/metrics/proto/profiler_event.pb.h"
+#include "components/metrics/proto/system_profile.pb.h"
 #include "components/variations/metrics_util.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/process_type.h"
@@ -650,6 +651,11 @@
   }
 }
 
+TEST_F(MetricsLogTest, ChromeChannelWrittenToProtobuf) {
+  TestMetricsLog log("user@test.com", kSessionId, MetricsLog::ONGOING_LOG);
+  EXPECT_TRUE(log.uma_proto().system_profile().has_channel());
+}
+
 #if defined(OS_CHROMEOS)
 TEST_F(MetricsLogTest, MultiProfileUserCount) {
   std::string user1("user1@example.com");
diff --git a/chrome/browser/metrics/metrics_network_observer.h b/chrome/browser/metrics/metrics_network_observer.h
index bcec85e..e64800b 100644
--- a/chrome/browser/metrics/metrics_network_observer.h
+++ b/chrome/browser/metrics/metrics_network_observer.h
@@ -8,7 +8,7 @@
 #include "base/basictypes.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/common/metrics/proto/system_profile.pb.h"
+#include "components/metrics/proto/system_profile.pb.h"
 #include "net/base/net_util.h"
 #include "net/base/network_change_notifier.h"
 
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc
index c082ccf..d27ca1b 100644
--- a/chrome/browser/metrics/metrics_service.cc
+++ b/chrome/browser/metrics/metrics_service.cc
@@ -168,14 +168,12 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/command_line.h"
-#include "base/guid.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/sparse_histogram.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
 #include "base/prefs/scoped_user_pref_update.h"
-#include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/platform_thread.h"
@@ -187,12 +185,11 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/io_thread.h"
 #include "chrome/browser/memory_details.h"
-#include "chrome/browser/metrics/cloned_install_detector.h"
 #include "chrome/browser/metrics/compression_utils.h"
-#include "chrome/browser/metrics/machine_id_provider.h"
 #include "chrome/browser/metrics/metrics_log.h"
 #include "chrome/browser/metrics/metrics_log_serializer.h"
 #include "chrome/browser/metrics/metrics_reporting_scheduler.h"
+#include "chrome/browser/metrics/metrics_state_manager.h"
 #include "chrome/browser/metrics/time_ticks_experiment_win.h"
 #include "chrome/browser/metrics/tracking_synchronizer.h"
 #include "chrome/common/metrics/variations/variations_util.h"
@@ -206,11 +203,10 @@
 #include "chrome/common/chrome_result_codes.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/crash_keys.h"
-#include "chrome/common/metrics/caching_permuted_entropy_provider.h"
-#include "chrome/common/metrics/metrics_log_manager.h"
 #include "chrome/common/net/test_server_locations.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/render_messages.h"
+#include "components/metrics/metrics_log_manager.h"
 #include "components/variations/entropy_provider.h"
 #include "components/variations/metrics_util.h"
 #include "content/public/browser/child_process_data.h"
@@ -252,6 +248,7 @@
 using content::ChildProcessData;
 using content::LoadNotificationDetails;
 using content::PluginService;
+using metrics::MetricsLogManager;
 
 namespace {
 
@@ -312,21 +309,6 @@
   }
 }
 
-// The argument used to generate a non-identifying entropy source. We want no
-// more than 13 bits of entropy, so use this max to return a number in the range
-// [0, 7999] as the entropy source (12.97 bits of entropy).
-const int kMaxLowEntropySize = 8000;
-
-// Default prefs value for prefs::kMetricsLowEntropySource to indicate that the
-// value has not yet been set.
-const int kLowEntropySourceNotSet = -1;
-
-// Generates a new non-identifying entropy source used to seed persistent
-// activities.
-int GenerateLowEntropySource() {
-  return base::RandInt(0, kMaxLowEntropySize - 1);
-}
-
 // Converts an exit code into something that can be inserted into our
 // histograms (which expect non-negative numbers less than MAX_INT).
 int MapCrashExitCodeForHistogram(int exit_code) {
@@ -429,11 +411,8 @@
 // static
 void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) {
   DCHECK(IsSingleThreaded());
-  registry->RegisterBooleanPref(prefs::kMetricsResetIds, false);
-  registry->RegisterStringPref(prefs::kMetricsClientID, std::string());
-  registry->RegisterInt64Pref(prefs::kMetricsReportingEnabledTimestamp, 0);
-  registry->RegisterIntegerPref(prefs::kMetricsLowEntropySource,
-                                kLowEntropySourceNotSet);
+  metrics::MetricsStateManager::RegisterPrefs(registry);
+
   registry->RegisterInt64Pref(prefs::kStabilityLaunchTimeSec, 0);
   registry->RegisterInt64Pref(prefs::kStabilityLastTimestampSec, 0);
   registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string());
@@ -478,33 +457,27 @@
   registry->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec, 0);
   registry->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec, 0);
 
-  // TODO(asvitkine): Remove these once a couple of releases have passed.
-  // http://crbug.com/357704
-  registry->RegisterStringPref(prefs::kMetricsOldClientID, std::string());
-  registry->RegisterIntegerPref(prefs::kMetricsOldLowEntropySource, 0);
-
 #if defined(OS_ANDROID)
   RegisterPrefsAndroid(registry);
 #endif  // defined(OS_ANDROID)
 }
 
-MetricsService::MetricsService()
-    : metrics_ids_reset_check_performed_(false),
+MetricsService::MetricsService(metrics::MetricsStateManager* state_manager)
+    : state_manager_(state_manager),
       recording_active_(false),
       reporting_active_(false),
       test_mode_active_(false),
       state_(INITIALIZED),
       has_initial_stability_log_(false),
-      low_entropy_source_(kLowEntropySourceNotSet),
       idle_since_last_transmission_(false),
       session_id_(-1),
       next_window_id_(0),
       self_ptr_factory_(this),
       state_saver_factory_(this),
       waiting_for_asynchronous_reporting_step_(false),
-      num_async_histogram_fetches_in_progress_(0),
-      entropy_source_returned_(LAST_ENTROPY_NONE) {
+      num_async_histogram_fetches_in_progress_(0) {
   DCHECK(IsSingleThreaded());
+  DCHECK(state_manager_);
 
   log_manager_.set_log_serializer(new MetricsLogSerializer);
   log_manager_.set_max_ongoing_log_store_size(kUploadLogAvoidRetransmitSize);
@@ -518,9 +491,8 @@
   BrowserChildProcessObserver::Remove(this);
 }
 
-void MetricsService::InitializeMetricsRecordingState(
-    ReportingState reporting_state) {
-  InitializeMetricsState(reporting_state);
+void MetricsService::InitializeMetricsRecordingState() {
+  InitializeMetricsState();
 
   base::Closure callback = base::Bind(&MetricsService::StartScheduledUpload,
                                       self_ptr_factory_.GetWeakPtr());
@@ -533,6 +505,13 @@
   EnableReporting();
 }
 
+bool MetricsService::StartIfMetricsReportingEnabled() {
+  const bool enabled = state_manager_->IsMetricsReportingEnabled();
+  if (enabled)
+    Start();
+  return enabled;
+}
+
 void MetricsService::StartRecordingForTests() {
   test_mode_active_ = true;
   EnableRecording();
@@ -557,70 +536,14 @@
 }
 
 std::string MetricsService::GetClientId() {
-  return client_id_;
+  return state_manager_->client_id();
 }
 
 scoped_ptr<const base::FieldTrial::EntropyProvider>
-MetricsService::CreateEntropyProvider(ReportingState reporting_state) {
-  // For metrics reporting-enabled users, we combine the client ID and low
-  // entropy source to get the final entropy source. Otherwise, only use the low
-  // entropy source.
-  // This has two useful properties:
-  //  1) It makes the entropy source less identifiable for parties that do not
-  //     know the low entropy source.
-  //  2) It makes the final entropy source resettable.
-  const int low_entropy_source_value = GetLowEntropySource();
-  UMA_HISTOGRAM_SPARSE_SLOWLY("UMA.LowEntropySourceValue",
-                              low_entropy_source_value);
-  if (reporting_state == REPORTING_ENABLED) {
-    if (entropy_source_returned_ == LAST_ENTROPY_NONE)
-      entropy_source_returned_ = LAST_ENTROPY_HIGH;
-    DCHECK_EQ(LAST_ENTROPY_HIGH, entropy_source_returned_);
-    const std::string high_entropy_source =
-        client_id_ + base::IntToString(low_entropy_source_value);
-    return scoped_ptr<const base::FieldTrial::EntropyProvider>(
-        new metrics::SHA1EntropyProvider(high_entropy_source));
-  }
-
-  if (entropy_source_returned_ == LAST_ENTROPY_NONE)
-    entropy_source_returned_ = LAST_ENTROPY_LOW;
-  DCHECK_EQ(LAST_ENTROPY_LOW, entropy_source_returned_);
-
-#if defined(OS_ANDROID) || defined(OS_IOS)
-  return scoped_ptr<const base::FieldTrial::EntropyProvider>(
-      new metrics::CachingPermutedEntropyProvider(
-          g_browser_process->local_state(),
-          low_entropy_source_value,
-          kMaxLowEntropySize));
-#else
-  return scoped_ptr<const base::FieldTrial::EntropyProvider>(
-      new metrics::PermutedEntropyProvider(low_entropy_source_value,
-                                           kMaxLowEntropySize));
-#endif
-}
-
-void MetricsService::ForceClientIdCreation() {
-  if (!client_id_.empty())
-    return;
-
-  ResetMetricsIDsIfNecessary();
-
-  PrefService* pref = g_browser_process->local_state();
-  client_id_ = pref->GetString(prefs::kMetricsClientID);
-  if (!client_id_.empty())
-    return;
-
-  client_id_ = GenerateClientID();
-  pref->SetString(prefs::kMetricsClientID, client_id_);
-
-  if (pref->GetString(prefs::kMetricsOldClientID).empty()) {
-    // Record the timestamp of when the user opted in to UMA.
-    pref->SetInt64(prefs::kMetricsReportingEnabledTimestamp,
-                   Time::Now().ToTimeT());
-  } else {
-    UMA_HISTOGRAM_BOOLEAN("UMA.ClientIdMigrated", true);
-  }
-  pref->ClearPref(prefs::kMetricsOldClientID);
+MetricsService::CreateEntropyProvider() {
+  // TODO(asvitkine): Refactor the code so that MetricsService does not expose
+  // this method.
+  return state_manager_->CreateEntropyProvider();
 }
 
 void MetricsService::EnableRecording() {
@@ -630,8 +553,8 @@
     return;
   recording_active_ = true;
 
-  ForceClientIdCreation();
-  crash_keys::SetClientID(client_id_);
+  state_manager_->ForceClientIdCreation();
+  crash_keys::SetClientID(state_manager_->client_id());
   if (!log_manager_.current_log())
     OpenNewLog();
 
@@ -917,7 +840,7 @@
 //------------------------------------------------------------------------------
 // Initialization methods
 
-void MetricsService::InitializeMetricsState(ReportingState reporting_state) {
+void MetricsService::InitializeMetricsState() {
 #if defined(OS_POSIX)
   network_stats_server_ = chrome_common_net::kEchoTestServerLocation;
   http_pipelining_test_server_ = chrome_common_net::kPipelineTestServerBaseUrl;
@@ -954,7 +877,7 @@
 
     // If the previous session didn't exit cleanly, then prepare an initial
     // stability log if UMA is enabled.
-    if (reporting_state == REPORTING_ENABLED)
+    if (state_manager_->IsMetricsReportingEnabled())
       PrepareInitialStabilityLog();
   }
 
@@ -1118,7 +1041,8 @@
   // save the profiler data.
   if (!initial_metrics_log_.get()) {
     initial_metrics_log_.reset(
-        new MetricsLog(client_id_, session_id_, MetricsLog::ONGOING_LOG));
+        new MetricsLog(state_manager_->client_id(), session_id_,
+                       MetricsLog::ONGOING_LOG));
   }
 
   initial_metrics_log_->RecordProfilerData(process_data, process_type);
@@ -1152,64 +1076,6 @@
   }
 }
 
-void MetricsService::ResetMetricsIDsIfNecessary() {
-  if (metrics_ids_reset_check_performed_)
-    return;
-
-  metrics_ids_reset_check_performed_ = true;
-
-  PrefService* local_state = g_browser_process->local_state();
-  if (!local_state->GetBoolean(prefs::kMetricsResetIds))
-    return;
-
-  UMA_HISTOGRAM_BOOLEAN("UMA.MetricsIDsReset", true);
-
-  DCHECK(client_id_.empty());
-  DCHECK_EQ(kLowEntropySourceNotSet, low_entropy_source_);
-
-  local_state->ClearPref(prefs::kMetricsClientID);
-  local_state->ClearPref(prefs::kMetricsLowEntropySource);
-  local_state->ClearPref(prefs::kMetricsResetIds);
-}
-
-int MetricsService::GetLowEntropySource() {
-  // Note that the default value for the low entropy source and the default pref
-  // value are both kLowEntropySourceNotSet, which is used to identify if the
-  // value has been set or not.
-  if (low_entropy_source_ != kLowEntropySourceNotSet)
-    return low_entropy_source_;
-
-  ResetMetricsIDsIfNecessary();
-
-  PrefService* local_state = g_browser_process->local_state();
-  const CommandLine* command_line(CommandLine::ForCurrentProcess());
-  // Only try to load the value from prefs if the user did not request a reset.
-  // Otherwise, skip to generating a new value.
-  if (!command_line->HasSwitch(switches::kResetVariationState)) {
-    int value = local_state->GetInteger(prefs::kMetricsLowEntropySource);
-    // If the value is outside the [0, kMaxLowEntropySize) range, re-generate
-    // it below.
-    if (value >= 0 && value < kMaxLowEntropySize) {
-      low_entropy_source_ = value;
-      UMA_HISTOGRAM_BOOLEAN("UMA.GeneratedLowEntropySource", false);
-      return low_entropy_source_;
-    }
-  }
-
-  UMA_HISTOGRAM_BOOLEAN("UMA.GeneratedLowEntropySource", true);
-  low_entropy_source_ = GenerateLowEntropySource();
-  local_state->SetInteger(prefs::kMetricsLowEntropySource, low_entropy_source_);
-  local_state->ClearPref(prefs::kMetricsOldLowEntropySource);
-  metrics::CachingPermutedEntropyProvider::ClearCache(local_state);
-
-  return low_entropy_source_;
-}
-
-// static
-std::string MetricsService::GenerateClientID() {
-  return base::GenerateGUID();
-}
-
 //------------------------------------------------------------------------------
 // State save methods
 
@@ -1243,7 +1109,8 @@
   DCHECK(!log_manager_.current_log());
 
   log_manager_.BeginLoggingWithLog(
-      new MetricsLog(client_id_, session_id_, MetricsLog::ONGOING_LOG));
+      new MetricsLog(state_manager_->client_id(), session_id_,
+                     MetricsLog::ONGOING_LOG));
   if (state_ == INITIALIZED) {
     // We only need to schedule that run once.
     state_ = INIT_TASK_SCHEDULED;
@@ -1539,7 +1406,7 @@
   DCHECK_NE(0, pref->GetInteger(prefs::kStabilityCrashCount));
 
   scoped_ptr<MetricsLog> initial_stability_log(
-      new MetricsLog(client_id_, session_id_,
+      new MetricsLog(state_manager_->client_id(), session_id_,
                      MetricsLog::INITIAL_STABILITY_LOG));
   if (!initial_stability_log->LoadSavedEnvironmentFromPrefs())
     return;
@@ -1838,18 +1705,7 @@
 }
 
 void MetricsService::CheckForClonedInstall() {
-  DCHECK(!cloned_install_detector_);
-
-  metrics::MachineIdProvider* provider =
-      metrics::MachineIdProvider::CreateInstance();
-  if (!provider)
-    return;
-
-  cloned_install_detector_.reset(
-      new metrics::ClonedInstallDetector(provider));
-
-  PrefService* local_state = g_browser_process->local_state();
-  cloned_install_detector_->CheckForClonedInstall(local_state);
+  state_manager_->CheckForClonedInstall();
 }
 
 void MetricsService::GetCurrentSyntheticFieldTrials(
diff --git a/chrome/browser/metrics/metrics_service.h b/chrome/browser/metrics/metrics_service.h
index 82c3c30..731706b 100644
--- a/chrome/browser/metrics/metrics_service.h
+++ b/chrome/browser/metrics/metrics_service.h
@@ -69,7 +69,7 @@
 }
 
 namespace metrics {
-class ClonedInstallDetector;
+class MetricsStateManager;
 }
 
 namespace net {
@@ -127,26 +127,27 @@
     SHUTDOWN_COMPLETE = 700,
   };
 
-  enum ReportingState {
-    REPORTING_ENABLED,
-    REPORTING_DISABLED,
-  };
-
-  MetricsService();
+  // Creates the MetricsService with the given |state_manager|. Does not take
+  // ownership of |state_manager|, instead stores a weak pointer to it. Caller
+  // should ensure that |state_manager| is valid for the lifetime of this class.
+  explicit MetricsService(metrics::MetricsStateManager* state_manager);
   virtual ~MetricsService();
 
   // Initializes metrics recording state. Updates various bookkeeping values in
   // prefs and sets up the scheduler. This is a separate function rather than
   // being done by the constructor so that field trials could be created before
-  // this is run. Takes |reporting_state| parameter which specifies whether UMA
-  // is enabled.
-  void InitializeMetricsRecordingState(ReportingState reporting_state);
+  // this is run.
+  void InitializeMetricsRecordingState();
 
   // Starts the metrics system, turning on recording and uploading of metrics.
   // Should be called when starting up with metrics enabled, or when metrics
   // are turned on.
   void Start();
 
+  // If metrics reporting is enabled, starts the metrics service. Returns
+  // whether the metrics service was started.
+  bool StartIfMetricsReportingEnabled();
+
   // Starts the metrics system in a special test-only mode. Metrics won't ever
   // be uploaded or persisted in this mode, but metrics will be recorded in
   // memory.
@@ -169,23 +170,12 @@
 
   // Returns the preferred entropy provider used to seed persistent activities
   // based on whether or not metrics reporting will be permitted on this client.
-  // The caller must determine if metrics reporting will be enabled for this
-  // client and pass that state in as |reporting_will_be_enabled|.
   //
-  // If |reporting_will_be_enabled| is true, this method returns an entropy
-  // provider that has a high source of entropy, partially based on the client
-  // ID. Otherwise, an entropy provider that is based on a low entropy source
-  // is returned.
-  //
-  // Note that this reporting state can not be checked by reporting_active()
-  // because this method may need to be called before the MetricsService needs
-  // to be started.
-  scoped_ptr<const base::FieldTrial::EntropyProvider> CreateEntropyProvider(
-      ReportingState reporting_state);
-
-  // Force the client ID to be generated. This is useful in case it's needed
-  // before recording.
-  void ForceClientIdCreation();
+  // If metrics reporting is enabled, this method returns an entropy provider
+  // that has a high source of entropy, partially based on the client ID.
+  // Otherwise, it returns an entropy provider that is based on a low entropy
+  // source.
+  scoped_ptr<const base::FieldTrial::EntropyProvider> CreateEntropyProvider();
 
   // At startup, prefs needs to be called with a list of all the pref names and
   // types we'll be using.
@@ -312,15 +302,6 @@
     NEED_TO_SHUTDOWN = ~CLEANLY_SHUTDOWN
   };
 
-  // Designates which entropy source was returned from this MetricsService.
-  // This is used for testing to validate that we return the correct source
-  // depending on the state of the service.
-  enum EntropySourceReturned {
-    LAST_ENTROPY_NONE,
-    LAST_ENTROPY_LOW,
-    LAST_ENTROPY_HIGH,
-  };
-
   struct ChildProcessStats;
 
   typedef std::vector<SyntheticTrialGroup> SyntheticTrialGroups;
@@ -368,22 +349,6 @@
                   base::TimeDelta* incremental_uptime,
                   base::TimeDelta* uptime);
 
-  // Reset the client id and low entropy source if the kMetricsResetMetricIDs
-  // pref is true.
-  void ResetMetricsIDsIfNecessary();
-
-  // Returns the low entropy source for this client. This is a random value
-  // that is non-identifying amongst browser clients. This method will
-  // generate the entropy source value if it has not been called before.
-  int GetLowEntropySource();
-
-  // Returns the first entropy source that was returned by this service since
-  // start up, or NONE if neither was returned yet. This is exposed for testing
-  // only.
-  EntropySourceReturned entropy_source_returned() const {
-    return entropy_source_returned_;
-  }
-
   // Turns recording on or off.
   // DisableRecording() also forces a persistent save of logging state (if
   // anything has been recorded, or transmitted).
@@ -397,10 +362,7 @@
   void HandleIdleSinceLastTransmission(bool in_idle);
 
   // Set up client ID, session ID, etc.
-  void InitializeMetricsState(ReportingState reporting_state);
-
-  // Generates a new client ID to use to identify self to metrics server.
-  static std::string GenerateClientID();
+  void InitializeMetricsState();
 
   // Schedule the next save of LocalState information.  This is called
   // automatically by the task that performs each save to schedule the next one.
@@ -512,6 +474,10 @@
   void GetCurrentSyntheticFieldTrials(
       std::vector<chrome_variations::ActiveGroupId>* synthetic_trials);
 
+  // Used to manage various metrics reporting state prefs, such as client id,
+  // low entropy source and whether metrics reporting is enabled. Weak pointer.
+  metrics::MetricsStateManager* state_manager_;
+
   base::ActionCallback action_callback_;
 
   content::NotificationRegistrar registrar_;
@@ -563,12 +529,6 @@
   // The HTTP pipelining test server.
   std::string http_pipelining_test_server_;
 
-  // The identifier that's sent to the server with the log reports.
-  std::string client_id_;
-
-  // The non-identifying low entropy source value.
-  int low_entropy_source_;
-
   // Whether the MetricsService object has received any notifications since
   // the last time a transmission was sent.
   bool idle_since_last_transmission_;
@@ -609,9 +569,6 @@
   scoped_refptr<chromeos::ExternalMetrics> external_metrics_;
 #endif
 
-  // The last entropy source returned by this service, used for testing.
-  EntropySourceReturned entropy_source_returned_;
-
   // Stores the time of the first call to |GetUptimes()|.
   base::TimeTicks first_updated_time_;
 
@@ -628,19 +585,10 @@
   // Field trial groups that map to Chrome configuration states.
   SyntheticTrialGroups synthetic_trial_groups_;
 
-  scoped_ptr<metrics::ClonedInstallDetector> cloned_install_detector_;
-
-  FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, ClientIdCorrectlyFormatted);
   FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, IsPluginProcess);
-  FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, LowEntropySource0NotReset);
   FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest,
                            PermutedEntropyCacheClearedWhenLowEntropyReset);
   FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, RegisterSyntheticTrial);
-  FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, ResetMetricsIDs);
-  FRIEND_TEST_ALL_PREFIXES(MetricsServiceBrowserTest,
-                           CheckLowEntropySourceUsed);
-  FRIEND_TEST_ALL_PREFIXES(MetricsServiceReportingTest,
-                           CheckHighEntropySourceUsed);
 
   DISALLOW_COPY_AND_ASSIGN(MetricsService);
 };
@@ -662,6 +610,9 @@
   FRIEND_TEST_ALL_PREFIXES(MetricsServiceTest, CrashReportingEnabled);
 
   // Returns true if prefs::kMetricsReportingEnabled is set.
+  // TODO(asvitkine): Consolidate the method in MetricsStateManager.
+  // TODO(asvitkine): This function does not report the correct value on
+  // Android and ChromeOS, see http://crbug.com/362192.
   static bool IsMetricsReportingEnabled();
 
   // Returns true if crash reporting is enabled.  This is set at the platform
diff --git a/chrome/browser/metrics/metrics_service_browsertest.cc b/chrome/browser/metrics/metrics_service_browsertest.cc
index 666afae..d87f5b7 100644
--- a/chrome/browser/metrics/metrics_service_browsertest.cc
+++ b/chrome/browser/metrics/metrics_service_browsertest.cc
@@ -5,6 +5,8 @@
 // Tests the MetricsService stat recording to make sure that the numbers are
 // what we expect.
 
+#include "chrome/browser/metrics/metrics_service.h"
+
 #include <string>
 
 #include "base/command_line.h"
@@ -12,7 +14,6 @@
 #include "base/path_service.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/metrics/metrics_service.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_paths.h"
@@ -58,14 +59,6 @@
   }
 };
 
-class MetricsServiceReportingTest : public InProcessBrowserTest {
- public:
-  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
-    // Enable the metrics service for testing (in the full mode).
-    command_line->AppendSwitch(switches::kEnableMetricsReportingForTesting);
-  }
-};
-
 IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, CloseRenderersNormally) {
   OpenTabs();
 
@@ -115,20 +108,3 @@
   // exits... it's not clear to me how to test that.
 }
 
-IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, CheckLowEntropySourceUsed) {
-  // Since MetricsService is only in recording mode, and is not reporting,
-  // check that the low entropy source is returned at some point.
-  ASSERT_TRUE(g_browser_process->metrics_service());
-  EXPECT_EQ(MetricsService::LAST_ENTROPY_LOW,
-            g_browser_process->metrics_service()->entropy_source_returned());
-}
-
-IN_PROC_BROWSER_TEST_F(MetricsServiceReportingTest,
-                       CheckHighEntropySourceUsed) {
-  // Since the full metrics service runs in this test, we expect that
-  // MetricsService returns the full entropy source at some point during
-  // BrowserMain startup.
-  ASSERT_TRUE(g_browser_process->metrics_service());
-  EXPECT_EQ(MetricsService::LAST_ENTROPY_HIGH,
-            g_browser_process->metrics_service()->entropy_source_returned());
-}
diff --git a/chrome/browser/metrics/metrics_service_unittest.cc b/chrome/browser/metrics/metrics_service_unittest.cc
index 262cce4..801659e 100644
--- a/chrome/browser/metrics/metrics_service_unittest.cc
+++ b/chrome/browser/metrics/metrics_service_unittest.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/metrics/metrics_service.h"
 
-#include <ctype.h>
 #include <string>
 
 #include "base/command_line.h"
 #include "base/threading/platform_thread.h"
+#include "chrome/browser/metrics/metrics_state_manager.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
@@ -26,9 +26,13 @@
 
 namespace {
 
+using metrics::MetricsLogManager;
+
 class TestMetricsService : public MetricsService {
  public:
-  TestMetricsService() {}
+  explicit TestMetricsService(metrics::MetricsStateManager* state_manager)
+      : MetricsService(state_manager) {
+  }
   virtual ~TestMetricsService() {}
 
   MetricsLogManager* log_manager() {
@@ -84,17 +88,30 @@
 class MetricsServiceTest : public testing::Test {
  public:
   MetricsServiceTest()
-      : testing_local_state_(TestingBrowserProcess::GetGlobal()) {
+      : testing_local_state_(TestingBrowserProcess::GetGlobal()),
+        metrics_state_manager_(metrics::MetricsStateManager::Create(
+            GetLocalState())) {
   }
 
   virtual ~MetricsServiceTest() {
     MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE);
   }
 
+  metrics::MetricsStateManager* GetMetricsStateManager() {
+    return metrics_state_manager_.get();
+  }
+
   PrefService* GetLocalState() {
     return testing_local_state_.Get();
   }
 
+  // Sets metrics reporting as enabled for testing.
+  void EnableMetricsReporting() {
+    // TODO(asvitkine): Refactor the code to not need this flag and delete it.
+    CommandLine::ForCurrentProcess()->AppendSwitch(
+        switches::kEnableMetricsReportingForTesting);
+  }
+
   // Waits until base::TimeTicks::Now() no longer equals |value|. This should
   // take between 1-15ms per the documented resolution of base::TimeTicks.
   void WaitUntilTimeChanges(const base::TimeTicks& value) {
@@ -123,26 +140,13 @@
  private:
   content::TestBrowserThreadBundle thread_bundle_;
   ScopedTestingLocalState testing_local_state_;
+  scoped_ptr<metrics::MetricsStateManager> metrics_state_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(MetricsServiceTest);
 };
 
 }  // namespace
 
-// Ensure the ClientId is formatted as expected.
-TEST_F(MetricsServiceTest, ClientIdCorrectlyFormatted) {
-  std::string clientid = MetricsService::GenerateClientID();
-  EXPECT_EQ(36U, clientid.length());
-
-  for (size_t i = 0; i < clientid.length(); ++i) {
-    char current = clientid[i];
-    if (i == 8 || i == 13 || i == 18 || i == 23)
-      EXPECT_EQ('-', current);
-    else
-      EXPECT_TRUE(isxdigit(current));
-  }
-}
-
 TEST_F(MetricsServiceTest, IsPluginProcess) {
   EXPECT_TRUE(
       MetricsService::IsPluginProcess(content::PROCESS_TYPE_PLUGIN));
@@ -152,82 +156,19 @@
       MetricsService::IsPluginProcess(content::PROCESS_TYPE_GPU));
 }
 
-TEST_F(MetricsServiceTest, LowEntropySource0NotReset) {
-  MetricsService service;
-
-  // Get the low entropy source once, to initialize it.
-  service.GetLowEntropySource();
-
-  // Now, set it to 0 and ensure it doesn't get reset.
-  service.low_entropy_source_ = 0;
-  EXPECT_EQ(0, service.GetLowEntropySource());
-  // Call it another time, just to make sure.
-  EXPECT_EQ(0, service.GetLowEntropySource());
-}
-
-TEST_F(MetricsServiceTest, PermutedEntropyCacheClearedWhenLowEntropyReset) {
-  const PrefService::Preference* low_entropy_pref =
-      GetLocalState()->FindPreference(prefs::kMetricsLowEntropySource);
-  const char* kCachePrefName = prefs::kMetricsPermutedEntropyCache;
-  int low_entropy_value = -1;
-
-  // First, generate an initial low entropy source value.
-  {
-    EXPECT_TRUE(low_entropy_pref->IsDefaultValue());
-
-    MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE);
-    MetricsService service;
-    service.GetLowEntropySource();
-
-    EXPECT_FALSE(low_entropy_pref->IsDefaultValue());
-    EXPECT_TRUE(low_entropy_pref->GetValue()->GetAsInteger(&low_entropy_value));
-  }
-
-  // Now, set a dummy value in the permuted entropy cache pref and verify that
-  // another call to GetLowEntropySource() doesn't clobber it when
-  // --reset-variation-state wasn't specified.
-  {
-    GetLocalState()->SetString(kCachePrefName, "test");
-
-    MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE);
-    MetricsService service;
-    service.GetLowEntropySource();
-
-    EXPECT_EQ("test", GetLocalState()->GetString(kCachePrefName));
-    EXPECT_EQ(low_entropy_value,
-              GetLocalState()->GetInteger(prefs::kMetricsLowEntropySource));
-  }
-
-  // Verify that the cache does get reset if --reset-variations-state is passed.
-  {
-    CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kResetVariationState);
-
-    MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE);
-    MetricsService service;
-    service.GetLowEntropySource();
-
-    EXPECT_TRUE(GetLocalState()->GetString(kCachePrefName).empty());
-  }
-}
-
 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCleanShutDown) {
-  base::FieldTrialList field_trial_list(NULL);
-  base::FieldTrialList::CreateFieldTrial("UMAStability", "SeparateLog");
-
+  EnableMetricsReporting();
   GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true);
 
-  TestMetricsService service;
-  service.InitializeMetricsRecordingState(MetricsService::REPORTING_ENABLED);
+  TestMetricsService service(GetMetricsStateManager());
+  service.InitializeMetricsRecordingState();
   // No initial stability log should be generated.
   EXPECT_FALSE(service.log_manager()->has_unsent_logs());
   EXPECT_FALSE(service.log_manager()->has_staged_log());
 }
 
 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCrash) {
-  base::FieldTrialList field_trial_list(NULL);
-  base::FieldTrialList::CreateFieldTrial("UMAStability", "SeparateLog");
-
+  EnableMetricsReporting();
   GetLocalState()->ClearPref(prefs::kStabilityExitedCleanly);
 
   // Set up prefs to simulate restarting after a crash.
@@ -248,8 +189,8 @@
 
   GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, false);
 
-  TestMetricsService service;
-  service.InitializeMetricsRecordingState(MetricsService::REPORTING_ENABLED);
+  TestMetricsService service(GetMetricsStateManager());
+  service.InitializeMetricsRecordingState();
 
   // The initial stability log should be generated and persisted in unsent logs.
   MetricsLogManager* log_manager = service.log_manager();
@@ -276,7 +217,7 @@
 }
 
 TEST_F(MetricsServiceTest, RegisterSyntheticTrial) {
-  MetricsService service;
+  MetricsService service(GetMetricsStateManager());
 
   // Add two synthetic trials and confirm that they show up in the list.
   SyntheticTrialGroup trial1(metrics::HashName("TestTrial1"),
@@ -306,7 +247,6 @@
   WaitUntilTimeChanges(begin_log_time);
 
   // Change the group for the first trial after the log started.
-  // TODO(asvitkine): Assumption that this is > than BeginLoggingWithLog() time.
   SyntheticTrialGroup trial3(metrics::HashName("TestTrial1"),
                              metrics::HashName("Group2"));
   service.RegisterSyntheticFieldTrial(trial3);
@@ -373,42 +313,3 @@
   EXPECT_FALSE(MetricsServiceHelper::IsCrashReportingEnabled());
 #endif  // defined(GOOGLE_CHROME_BUILD)
 }
-
-// Check that setting the kMetricsResetIds pref to true causes the client id to
-// be reset. We do not check that the low entropy source is reset because we
-// cannot ensure that metrics service won't generate the same id again.
-TEST_F(MetricsServiceTest, ResetMetricsIDs) {
-  // Set an initial client id in prefs. It should not be possible for the
-  // metrics service to generate this id randomly.
-  const std::string kInitialClientId = "initial client id";
-  GetLocalState()->SetString(prefs::kMetricsClientID, kInitialClientId);
-
-  // Make sure the initial client id isn't reset by the metrics service.
-  {
-    MetricsService service;
-    service.ForceClientIdCreation();
-    EXPECT_TRUE(service.metrics_ids_reset_check_performed_);
-    EXPECT_EQ(kInitialClientId, service.client_id_);
-  }
-
-
-  // Set the reset pref to cause the IDs to be reset.
-  GetLocalState()->SetBoolean(prefs::kMetricsResetIds, true);
-
-  // Cause the actual reset to happen.
-  {
-    MetricsService service;
-    service.ForceClientIdCreation();
-    EXPECT_TRUE(service.metrics_ids_reset_check_performed_);
-    EXPECT_NE(kInitialClientId, service.client_id_);
-
-    service.GetLowEntropySource();
-
-    EXPECT_FALSE(GetLocalState()->GetBoolean(prefs::kMetricsResetIds));
-  }
-
-  std::string new_client_id =
-      GetLocalState()->GetString(prefs::kMetricsClientID);
-
-  EXPECT_NE(kInitialClientId, new_client_id);
-}
diff --git a/chrome/browser/metrics/metrics_services_manager.cc b/chrome/browser/metrics/metrics_services_manager.cc
new file mode 100644
index 0000000..95d0ac9
--- /dev/null
+++ b/chrome/browser/metrics/metrics_services_manager.cc
@@ -0,0 +1,49 @@
+// 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.
+
+#include "chrome/browser/metrics/metrics_services_manager.h"
+
+#include "chrome/browser/metrics/metrics_service.h"
+#include "chrome/browser/metrics/metrics_state_manager.h"
+#include "chrome/browser/metrics/variations/variations_service.h"
+#include "components/rappor/rappor_service.h"
+
+MetricsServicesManager::MetricsServicesManager(PrefService* local_state)
+    : local_state_(local_state) {
+  DCHECK(local_state);
+}
+
+MetricsServicesManager::~MetricsServicesManager() {
+}
+
+MetricsService* MetricsServicesManager::GetMetricsService() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!metrics_service_)
+    metrics_service_.reset(new MetricsService(GetMetricsStateManager()));
+  return metrics_service_.get();
+}
+
+rappor::RapporService* MetricsServicesManager::GetRapporService() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!rappor_service_)
+    rappor_service_.reset(new rappor::RapporService);
+  return rappor_service_.get();
+}
+
+chrome_variations::VariationsService*
+MetricsServicesManager::GetVariationsService() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!variations_service_) {
+    variations_service_.reset(
+        chrome_variations::VariationsService::Create(local_state_));
+  }
+  return variations_service_.get();
+}
+
+metrics::MetricsStateManager* MetricsServicesManager::GetMetricsStateManager() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (!metrics_state_manager_)
+    metrics_state_manager_ = metrics::MetricsStateManager::Create(local_state_);
+  return metrics_state_manager_.get();
+}
diff --git a/chrome/browser/metrics/metrics_services_manager.h b/chrome/browser/metrics/metrics_services_manager.h
new file mode 100644
index 0000000..66d0c2a
--- /dev/null
+++ b/chrome/browser/metrics/metrics_services_manager.h
@@ -0,0 +1,69 @@
+// 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.
+
+#ifndef CHROME_BROWSER_METRICS_METRICS_SERVICES_MANAGER_H_
+#define CHROME_BROWSER_METRICS_METRICS_SERVICES_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread_checker.h"
+
+class MetricsService;
+class PrefService;
+
+namespace metrics {
+class MetricsStateManager;
+}
+
+namespace rappor {
+class RapporService;
+}
+
+namespace chrome_variations {
+class VariationsService;
+}
+
+// MetricsServicesManager is a helper class that has ownership over the various
+// metrics-related services in Chrome: MetricsService, RapporService and
+// VariationsService.
+class MetricsServicesManager {
+ public:
+  // Creates the MetricsServicesManager with the |local_state| prefs service.
+  explicit MetricsServicesManager(PrefService* local_state);
+  virtual ~MetricsServicesManager();
+
+  // Returns the MetricsService, creating it if it hasn't been created yet.
+  MetricsService* GetMetricsService();
+
+  // Returns the GetRapporService, creating it if it hasn't been created yet.
+  rappor::RapporService* GetRapporService();
+
+  // Returns the VariationsService, creating it if it hasn't been created yet.
+  chrome_variations::VariationsService* GetVariationsService();
+
+ private:
+  metrics::MetricsStateManager* GetMetricsStateManager();
+
+  // Ensures that all functions are called from the same thread.
+  base::ThreadChecker thread_checker_;
+
+  // Weak pointer to the local state prefs store.
+  PrefService* local_state_;
+
+  // MetricsStateManager which is passed as a parameter to service constructors.
+  scoped_ptr<metrics::MetricsStateManager> metrics_state_manager_;
+
+  // The MetricsService, used for UMA report uploads.
+  scoped_ptr<MetricsService> metrics_service_;
+
+  // The RapporService, for RAPPOR metric uploads.
+  scoped_ptr<rappor::RapporService> rappor_service_;
+
+  // The VariationsService, for server-side experiments infrastructure.
+  scoped_ptr<chrome_variations::VariationsService> variations_service_;
+
+  DISALLOW_COPY_AND_ASSIGN(MetricsServicesManager);
+};
+
+#endif  // CHROME_BROWSER_METRICS_METRICS_SERVICES_MANAGER_H_
diff --git a/chrome/browser/metrics/metrics_state_manager.cc b/chrome/browser/metrics/metrics_state_manager.cc
new file mode 100644
index 0000000..5242a23
--- /dev/null
+++ b/chrome/browser/metrics/metrics_state_manager.cc
@@ -0,0 +1,233 @@
+// 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.
+
+#include "chrome/browser/metrics/metrics_state_manager.h"
+
+#include "base/command_line.h"
+#include "base/guid.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/sparse_histogram.h"
+#include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/pref_service.h"
+#include "base/rand_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
+#include "chrome/browser/metrics/cloned_install_detector.h"
+#include "chrome/browser/metrics/machine_id_provider.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/metrics/caching_permuted_entropy_provider.h"
+#include "chrome/common/pref_names.h"
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+#endif
+
+namespace metrics {
+
+namespace {
+
+// The argument used to generate a non-identifying entropy source. We want no
+// more than 13 bits of entropy, so use this max to return a number in the range
+// [0, 7999] as the entropy source (12.97 bits of entropy).
+const int kMaxLowEntropySize = 8000;
+
+// Default prefs value for prefs::kMetricsLowEntropySource to indicate that the
+// value has not yet been set.
+const int kLowEntropySourceNotSet = -1;
+
+// Generates a new non-identifying entropy source used to seed persistent
+// activities.
+int GenerateLowEntropySource() {
+  return base::RandInt(0, kMaxLowEntropySize - 1);
+}
+
+}  // namespace
+
+// static
+bool MetricsStateManager::instance_exists_ = false;
+
+MetricsStateManager::MetricsStateManager(PrefService* local_state)
+    : local_state_(local_state),
+      low_entropy_source_(kLowEntropySourceNotSet),
+      entropy_source_returned_(ENTROPY_SOURCE_NONE) {
+  ResetMetricsIDsIfNecessary();
+  if (IsMetricsReportingEnabled())
+    ForceClientIdCreation();
+
+  DCHECK(!instance_exists_);
+  instance_exists_ = true;
+}
+
+MetricsStateManager::~MetricsStateManager() {
+  DCHECK(instance_exists_);
+  instance_exists_ = false;
+}
+
+bool MetricsStateManager::IsMetricsReportingEnabled() {
+  // If the user permits metrics reporting with the checkbox in the
+  // prefs, we turn on recording.  We disable metrics completely for
+  // non-official builds.  This can be forced with a flag.
+  const CommandLine* command_line = CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kEnableMetricsReportingForTesting))
+    return true;
+
+  // Disable metrics reporting when field trials are forced.
+  if (command_line->HasSwitch(switches::kForceFieldTrials))
+    return false;
+
+  bool enabled = false;
+#if defined(GOOGLE_CHROME_BUILD)
+#if defined(OS_CHROMEOS)
+  chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref,
+                                            &enabled);
+#else
+  enabled = local_state_->GetBoolean(prefs::kMetricsReportingEnabled);
+#endif  // #if defined(OS_CHROMEOS)
+#endif  // defined(GOOGLE_CHROME_BUILD)
+  return enabled;
+}
+
+void MetricsStateManager::ForceClientIdCreation() {
+  if (!client_id_.empty())
+    return;
+
+  client_id_ = local_state_->GetString(prefs::kMetricsClientID);
+  if (!client_id_.empty())
+    return;
+
+  client_id_ = base::GenerateGUID();
+  local_state_->SetString(prefs::kMetricsClientID, client_id_);
+
+  if (local_state_->GetString(prefs::kMetricsOldClientID).empty()) {
+    // Record the timestamp of when the user opted in to UMA.
+    local_state_->SetInt64(prefs::kMetricsReportingEnabledTimestamp,
+                           base::Time::Now().ToTimeT());
+  } else {
+    UMA_HISTOGRAM_BOOLEAN("UMA.ClientIdMigrated", true);
+  }
+  local_state_->ClearPref(prefs::kMetricsOldClientID);
+}
+
+void MetricsStateManager::CheckForClonedInstall() {
+  DCHECK(!cloned_install_detector_);
+
+  MachineIdProvider* provider = MachineIdProvider::CreateInstance();
+  if (!provider)
+    return;
+
+  cloned_install_detector_.reset(new ClonedInstallDetector(provider));
+  cloned_install_detector_->CheckForClonedInstall(local_state_);
+}
+
+scoped_ptr<const base::FieldTrial::EntropyProvider>
+MetricsStateManager::CreateEntropyProvider() {
+  // For metrics reporting-enabled users, we combine the client ID and low
+  // entropy source to get the final entropy source. Otherwise, only use the low
+  // entropy source.
+  // This has two useful properties:
+  //  1) It makes the entropy source less identifiable for parties that do not
+  //     know the low entropy source.
+  //  2) It makes the final entropy source resettable.
+  const int low_entropy_source_value = GetLowEntropySource();
+  UMA_HISTOGRAM_SPARSE_SLOWLY("UMA.LowEntropySourceValue",
+                              low_entropy_source_value);
+  if (IsMetricsReportingEnabled()) {
+    if (entropy_source_returned_ == ENTROPY_SOURCE_NONE)
+      entropy_source_returned_ = ENTROPY_SOURCE_HIGH;
+    DCHECK_EQ(ENTROPY_SOURCE_HIGH, entropy_source_returned_);
+    const std::string high_entropy_source =
+        client_id_ + base::IntToString(low_entropy_source_value);
+    return scoped_ptr<const base::FieldTrial::EntropyProvider>(
+        new SHA1EntropyProvider(high_entropy_source));
+  }
+
+  if (entropy_source_returned_ == ENTROPY_SOURCE_NONE)
+    entropy_source_returned_ = ENTROPY_SOURCE_LOW;
+  DCHECK_EQ(ENTROPY_SOURCE_LOW, entropy_source_returned_);
+
+#if defined(OS_ANDROID) || defined(OS_IOS)
+  return scoped_ptr<const base::FieldTrial::EntropyProvider>(
+      new CachingPermutedEntropyProvider(local_state_,
+                                         low_entropy_source_value,
+                                         kMaxLowEntropySize));
+#else
+  return scoped_ptr<const base::FieldTrial::EntropyProvider>(
+      new PermutedEntropyProvider(low_entropy_source_value,
+                                  kMaxLowEntropySize));
+#endif
+}
+
+// static
+scoped_ptr<MetricsStateManager> MetricsStateManager::Create(
+    PrefService* local_state) {
+  scoped_ptr<MetricsStateManager> result;
+  // Note: |instance_exists_| is updated in the constructor and destructor.
+  if (!instance_exists_)
+    result.reset(new MetricsStateManager(local_state));
+  return result.Pass();
+}
+
+// static
+void MetricsStateManager::RegisterPrefs(PrefRegistrySimple* registry) {
+  registry->RegisterBooleanPref(prefs::kMetricsResetIds, false);
+  registry->RegisterStringPref(prefs::kMetricsClientID, std::string());
+  registry->RegisterInt64Pref(prefs::kMetricsReportingEnabledTimestamp, 0);
+  registry->RegisterIntegerPref(prefs::kMetricsLowEntropySource,
+                                kLowEntropySourceNotSet);
+
+  ClonedInstallDetector::RegisterPrefs(registry);
+  CachingPermutedEntropyProvider::RegisterPrefs(registry);
+
+  // TODO(asvitkine): Remove these once a couple of releases have passed.
+  // http://crbug.com/357704
+  registry->RegisterStringPref(prefs::kMetricsOldClientID, std::string());
+  registry->RegisterIntegerPref(prefs::kMetricsOldLowEntropySource, 0);
+}
+
+int MetricsStateManager::GetLowEntropySource() {
+  // Note that the default value for the low entropy source and the default pref
+  // value are both kLowEntropySourceNotSet, which is used to identify if the
+  // value has been set or not.
+  if (low_entropy_source_ != kLowEntropySourceNotSet)
+    return low_entropy_source_;
+
+  const CommandLine* command_line(CommandLine::ForCurrentProcess());
+  // Only try to load the value from prefs if the user did not request a reset.
+  // Otherwise, skip to generating a new value.
+  if (!command_line->HasSwitch(switches::kResetVariationState)) {
+    int value = local_state_->GetInteger(prefs::kMetricsLowEntropySource);
+    // If the value is outside the [0, kMaxLowEntropySize) range, re-generate
+    // it below.
+    if (value >= 0 && value < kMaxLowEntropySize) {
+      low_entropy_source_ = value;
+      UMA_HISTOGRAM_BOOLEAN("UMA.GeneratedLowEntropySource", false);
+      return low_entropy_source_;
+    }
+  }
+
+  UMA_HISTOGRAM_BOOLEAN("UMA.GeneratedLowEntropySource", true);
+  low_entropy_source_ = GenerateLowEntropySource();
+  local_state_->SetInteger(prefs::kMetricsLowEntropySource,
+                           low_entropy_source_);
+  local_state_->ClearPref(prefs::kMetricsOldLowEntropySource);
+  metrics::CachingPermutedEntropyProvider::ClearCache(local_state_);
+
+  return low_entropy_source_;
+}
+
+void MetricsStateManager::ResetMetricsIDsIfNecessary() {
+  if (!local_state_->GetBoolean(prefs::kMetricsResetIds))
+    return;
+
+  UMA_HISTOGRAM_BOOLEAN("UMA.MetricsIDsReset", true);
+
+  DCHECK(client_id_.empty());
+  DCHECK_EQ(kLowEntropySourceNotSet, low_entropy_source_);
+
+  local_state_->ClearPref(prefs::kMetricsClientID);
+  local_state_->ClearPref(prefs::kMetricsLowEntropySource);
+  local_state_->ClearPref(prefs::kMetricsResetIds);
+}
+
+}  // namespace metrics
diff --git a/chrome/browser/metrics/metrics_state_manager.h b/chrome/browser/metrics/metrics_state_manager.h
new file mode 100644
index 0000000..5b2f954
--- /dev/null
+++ b/chrome/browser/metrics/metrics_state_manager.h
@@ -0,0 +1,124 @@
+// 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.
+
+#ifndef CHROME_BROWSER_METRICS_METRICS_STATE_MANAGER_H_
+#define CHROME_BROWSER_METRICS_METRICS_STATE_MANAGER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/field_trial.h"
+
+class PrefService;
+class PrefRegistrySimple;
+
+namespace metrics {
+
+class ClonedInstallDetector;
+
+// Responsible for managing MetricsService state prefs, specifically the UMA
+// client id and low entropy source. Code outside the metrics directory should
+// not be instantiating or using this class directly.
+class MetricsStateManager {
+ public:
+  virtual ~MetricsStateManager();
+
+  // Returns true if the user opted in to sending metric reports.
+  // TODO(asvitkine): This function does not report the correct value on
+  // Android, see http://crbug.com/362192.
+  bool IsMetricsReportingEnabled();
+
+  // Returns the client ID for this client, or the empty string if the user is
+  // not opted in to metrics reporting.
+  const std::string& client_id() const { return client_id_; }
+
+  // Forces the client ID to be generated. This is useful in case it's needed
+  // before recording.
+  void ForceClientIdCreation();
+
+  // Checks if this install was cloned or imaged from another machine. If a
+  // clone is detected, resets the client id and low entropy source. This
+  // should not be called more than once.
+  void CheckForClonedInstall();
+
+  // Returns the preferred entropy provider used to seed persistent activities
+  // based on whether or not metrics reporting is permitted on this client.
+  //
+  // If metrics reporting is enabled, this method returns an entropy provider
+  // that has a high source of entropy, partially based on the client ID.
+  // Otherwise, it returns an entropy provider that is based on a low entropy
+  // source.
+  scoped_ptr<const base::FieldTrial::EntropyProvider> CreateEntropyProvider();
+
+  // Creates the MetricsStateManager, enforcing that only a single instance
+  // of the class exists at a time. Returns NULL if an instance exists already.
+  static scoped_ptr<MetricsStateManager> Create(PrefService* local_state);
+
+  // Registers local state prefs used by this class.
+  static void RegisterPrefs(PrefRegistrySimple* registry);
+
+ private:
+  FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, EntropySourceUsed_Low);
+  FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, EntropySourceUsed_High);
+  FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, LowEntropySource0NotReset);
+  FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest,
+                           PermutedEntropyCacheClearedWhenLowEntropyReset);
+  FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, ResetMetricsIDs);
+
+  // Designates which entropy source was returned from this class.
+  // This is used for testing to validate that we return the correct source
+  // depending on the state of the service.
+  enum EntropySourceType {
+    ENTROPY_SOURCE_NONE,
+    ENTROPY_SOURCE_LOW,
+    ENTROPY_SOURCE_HIGH,
+  };
+
+  // Creates the MetricsStateManager with the given |local_state|. Clients
+  // should instead use Create(), which enforces a single instance of this class
+  // is alive at any given time.
+  explicit MetricsStateManager(PrefService* local_state);
+
+  // Returns the low entropy source for this client. This is a random value
+  // that is non-identifying amongst browser clients. This method will
+  // generate the entropy source value if it has not been called before.
+  int GetLowEntropySource();
+
+  // Returns the first entropy source that was returned by this service since
+  // start up, or NONE if neither was returned yet. This is exposed for testing
+  // only.
+  EntropySourceType entropy_source_returned() const {
+    return entropy_source_returned_;
+  }
+
+  // Reset the client id and low entropy source if the kMetricsResetMetricIDs
+  // pref is true.
+  void ResetMetricsIDsIfNecessary();
+
+  // Whether an instance of this class exists. Used to enforce that there aren't
+  // multiple instances of this class at a given time.
+  static bool instance_exists_;
+
+  // Weak pointer to the local state prefs store.
+  PrefService* local_state_;
+
+  // The identifier that's sent to the server with the log reports.
+  std::string client_id_;
+
+  // The non-identifying low entropy source value.
+  int low_entropy_source_;
+
+  // The last entropy source returned by this service, used for testing.
+  EntropySourceType entropy_source_returned_;
+
+  scoped_ptr<ClonedInstallDetector> cloned_install_detector_;
+
+  DISALLOW_COPY_AND_ASSIGN(MetricsStateManager);
+};
+
+}  // namespace metrics
+
+#endif  // CHROME_BROWSER_METRICS_METRICS_STATE_MANAGER_H_
diff --git a/chrome/browser/metrics/metrics_state_manager_unittest.cc b/chrome/browser/metrics/metrics_state_manager_unittest.cc
new file mode 100644
index 0000000..bad4b77
--- /dev/null
+++ b/chrome/browser/metrics/metrics_state_manager_unittest.cc
@@ -0,0 +1,160 @@
+// 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.
+
+#include "chrome/browser/metrics/metrics_state_manager.h"
+
+#include <ctype.h>
+#include <string>
+
+#include "base/command_line.h"
+#include "base/prefs/testing_pref_service.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/metrics/caching_permuted_entropy_provider.h"
+#include "chrome/common/pref_names.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace metrics {
+
+class MetricsStateManagerTest : public testing::Test {
+ public:
+  MetricsStateManagerTest() {
+    MetricsStateManager::RegisterPrefs(prefs_.registry());
+  }
+
+  scoped_ptr<MetricsStateManager> CreateStateManager() {
+    return MetricsStateManager::Create(&prefs_).Pass();
+  }
+
+ protected:
+  TestingPrefServiceSimple prefs_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MetricsStateManagerTest);
+};
+
+// Ensure the ClientId is formatted as expected.
+TEST_F(MetricsStateManagerTest, ClientIdCorrectlyFormatted) {
+  scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
+  state_manager->ForceClientIdCreation();
+
+  const std::string client_id = state_manager->client_id();
+  EXPECT_EQ(36U, client_id.length());
+
+  for (size_t i = 0; i < client_id.length(); ++i) {
+    char current = client_id[i];
+    if (i == 8 || i == 13 || i == 18 || i == 23)
+      EXPECT_EQ('-', current);
+    else
+      EXPECT_TRUE(isxdigit(current));
+  }
+}
+
+TEST_F(MetricsStateManagerTest, EntropySourceUsed_Low) {
+  scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
+  state_manager->CreateEntropyProvider();
+  EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_LOW,
+            state_manager->entropy_source_returned());
+}
+
+TEST_F(MetricsStateManagerTest, EntropySourceUsed_High) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableMetricsReportingForTesting);
+
+  scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
+  state_manager->CreateEntropyProvider();
+  EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_HIGH,
+            state_manager->entropy_source_returned());
+}
+
+TEST_F(MetricsStateManagerTest, LowEntropySource0NotReset) {
+  scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
+
+  // Get the low entropy source once, to initialize it.
+  state_manager->GetLowEntropySource();
+
+  // Now, set it to 0 and ensure it doesn't get reset.
+  state_manager->low_entropy_source_ = 0;
+  EXPECT_EQ(0, state_manager->GetLowEntropySource());
+  // Call it another time, just to make sure.
+  EXPECT_EQ(0, state_manager->GetLowEntropySource());
+}
+
+TEST_F(MetricsStateManagerTest,
+       PermutedEntropyCacheClearedWhenLowEntropyReset) {
+  const PrefService::Preference* low_entropy_pref =
+      prefs_.FindPreference(prefs::kMetricsLowEntropySource);
+  const char* kCachePrefName = prefs::kMetricsPermutedEntropyCache;
+  int low_entropy_value = -1;
+
+  // First, generate an initial low entropy source value.
+  {
+    EXPECT_TRUE(low_entropy_pref->IsDefaultValue());
+
+    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
+    state_manager->GetLowEntropySource();
+
+    EXPECT_FALSE(low_entropy_pref->IsDefaultValue());
+    EXPECT_TRUE(low_entropy_pref->GetValue()->GetAsInteger(&low_entropy_value));
+  }
+
+  // Now, set a dummy value in the permuted entropy cache pref and verify that
+  // another call to GetLowEntropySource() doesn't clobber it when
+  // --reset-variation-state wasn't specified.
+  {
+    prefs_.SetString(kCachePrefName, "test");
+
+    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
+    state_manager->GetLowEntropySource();
+
+    EXPECT_EQ("test", prefs_.GetString(kCachePrefName));
+    EXPECT_EQ(low_entropy_value,
+              prefs_.GetInteger(prefs::kMetricsLowEntropySource));
+  }
+
+  // Verify that the cache does get reset if --reset-variations-state is passed.
+  {
+    CommandLine::ForCurrentProcess()->AppendSwitch(
+        switches::kResetVariationState);
+
+    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
+    state_manager->GetLowEntropySource();
+
+    EXPECT_TRUE(prefs_.GetString(kCachePrefName).empty());
+  }
+}
+
+// Check that setting the kMetricsResetIds pref to true causes the client id to
+// be reset. We do not check that the low entropy source is reset because we
+// cannot ensure that metrics state manager won't generate the same id again.
+TEST_F(MetricsStateManagerTest, ResetMetricsIDs) {
+  // Set an initial client id in prefs. It should not be possible for the
+  // metrics state manager to generate this id randomly.
+  const std::string kInitialClientId = "initial client id";
+  prefs_.SetString(prefs::kMetricsClientID, kInitialClientId);
+
+  // Make sure the initial client id isn't reset by the metrics state manager.
+  {
+    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
+    state_manager->ForceClientIdCreation();
+    EXPECT_EQ(kInitialClientId, state_manager->client_id());
+  }
+
+  // Set the reset pref to cause the IDs to be reset.
+  prefs_.SetBoolean(prefs::kMetricsResetIds, true);
+
+  // Cause the actual reset to happen.
+  {
+    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
+    state_manager->ForceClientIdCreation();
+    EXPECT_NE(kInitialClientId, state_manager->client_id());
+
+    state_manager->GetLowEntropySource();
+
+    EXPECT_FALSE(prefs_.GetBoolean(prefs::kMetricsResetIds));
+  }
+
+  EXPECT_NE(kInitialClientId, prefs_.GetString(prefs::kMetricsClientID));
+}
+
+}  // namespace metrics
diff --git a/chrome/browser/metrics/perf_provider_chromeos.h b/chrome/browser/metrics/perf_provider_chromeos.h
index b08c845..2822710 100644
--- a/chrome/browser/metrics/perf_provider_chromeos.h
+++ b/chrome/browser/metrics/perf_provider_chromeos.h
@@ -12,7 +12,7 @@
 #include "base/threading/non_thread_safe.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
-#include "chrome/common/metrics/proto/perf_data.pb.h"
+#include "components/metrics/proto/perf_data.pb.h"
 
 namespace metrics {
 
diff --git a/chrome/browser/metrics/thread_watcher.cc b/chrome/browser/metrics/thread_watcher.cc
index ab80a86..23e33b9 100644
--- a/chrome/browser/metrics/thread_watcher.cc
+++ b/chrome/browser/metrics/thread_watcher.cc
@@ -53,6 +53,13 @@
 #endif
 }
 
+#if !defined(OS_ANDROID) || !defined(NDEBUG)
+// TODO(rtenneti): Enabled crashing, after getting data.
+NOINLINE void StartupCrash() {
+  NullPointerCrash(__LINE__);
+}
+#endif  // OS_ANDROID
+
 NOINLINE void ShutdownCrash() {
   NullPointerCrash(__LINE__);
 }
@@ -882,20 +889,48 @@
   // alarming.
   explicit StartupWatchDogThread(const base::TimeDelta& duration)
       : base::Watchdog(duration, "Startup watchdog thread", true) {
+#if defined(OS_ANDROID)
+    // TODO(rtenneti): Delete this code, after getting data.
+    start_time_clock_= base::Time::Now();
+    start_time_monotonic_ = base::TimeTicks::Now();
+    start_time_thread_now_ = base::TimeTicks::IsThreadNowSupported()
+        ? base::TimeTicks::ThreadNow() : base::TimeTicks::Now();
+#endif  // OS_ANDROID
   }
 
   // Alarm is called if the time expires after an Arm() without someone calling
   // Disarm(). When Alarm goes off, in release mode we get the crash dump
   // without crashing and in debug mode we break into the debugger.
   virtual void Alarm() OVERRIDE {
-#ifndef NDEBUG
-    DCHECK(false);
-#else
-    WatchDogThread::PostTask(FROM_HERE,
-                             base::Bind(&base::debug::DumpWithoutCrashing));
-#endif
+#if !defined(NDEBUG)
+    StartupCrash();
+    return;
+#elif !defined(OS_ANDROID)
+    WatchDogThread::PostTask(FROM_HERE, base::Bind(&StartupCrash));
+    return;
+#else  // Android release: gather stats to figure out when to crash.
+    // TODO(rtenneti): Delete this code, after getting data.
+    UMA_HISTOGRAM_TIMES("StartupTimebomm.Alarm.TimeDuration",
+                        base::Time::Now() - start_time_clock_);
+    UMA_HISTOGRAM_TIMES("StartupTimebomm.Alarm.TimeTicksDuration",
+                        base::TimeTicks::Now() - start_time_monotonic_);
+    if (base::TimeTicks::IsThreadNowSupported()) {
+      UMA_HISTOGRAM_TIMES(
+          "StartupTimebomm.Alarm.ThreadNowDuration",
+          base::TimeTicks::ThreadNow() - start_time_thread_now_);
+    }
+    return;
+#endif  // OS_ANDROID
   }
 
+ private:
+#if defined(OS_ANDROID)
+  // TODO(rtenneti): Delete this code, after getting data.
+  base::Time start_time_clock_;
+  base::TimeTicks start_time_monotonic_;
+  base::TimeTicks start_time_thread_now_;
+#endif  // OS_ANDROID
+
   DISALLOW_COPY_AND_ASSIGN(StartupWatchDogThread);
 };
 
@@ -916,6 +951,7 @@
     ShutdownCrash();
   }
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(ShutdownWatchDogThread);
 };
 }  // namespace
diff --git a/chrome/browser/metrics/variations/variations_http_header_provider.cc b/chrome/browser/metrics/variations/variations_http_header_provider.cc
index 4881bf6..90fde20 100644
--- a/chrome/browser/metrics/variations/variations_http_header_provider.cc
+++ b/chrome/browser/metrics/variations/variations_http_header_provider.cc
@@ -105,11 +105,17 @@
     const std::string& group_name) {
   VariationID new_id =
       GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial_name, group_name);
-  if (new_id == EMPTY_ID)
+  VariationID new_trigger_id = GetGoogleVariationID(
+      GOOGLE_WEB_PROPERTIES_TRIGGER, trial_name, group_name);
+  if (new_id == EMPTY_ID && new_trigger_id == EMPTY_ID)
     return;
 
   base::AutoLock scoped_lock(lock_);
-  variation_ids_set_.insert(new_id);
+  if (new_id != EMPTY_ID)
+    variation_ids_set_.insert(new_id);
+  if (new_trigger_id != EMPTY_ID)
+    variation_trigger_ids_set_.insert(new_trigger_id);
+
   UpdateVariationIDsHeaderValue();
 }
 
@@ -135,6 +141,12 @@
                              it->group_name);
     if (id != EMPTY_ID)
       variation_ids_set_.insert(id);
+
+    const VariationID trigger_id =
+        GetGoogleVariationID(GOOGLE_WEB_PROPERTIES_TRIGGER, it->trial_name,
+                             it->group_name);
+    if (trigger_id != EMPTY_ID)
+      variation_trigger_ids_set_.insert(trigger_id);
   }
   UpdateVariationIDsHeaderValue();
 
@@ -156,15 +168,17 @@
   variation_ids_header_.clear();
 
   if (variation_ids_set_.empty() && default_variation_ids_set_.empty() &&
-      default_trigger_id_set_.empty()) {
+      variation_trigger_ids_set_.empty() && default_trigger_id_set_.empty()) {
     return;
   }
 
   // This is the bottleneck for the creation of the header, so validate the size
   // here. Force a hard maximum on the ID count in case the Variations server
   // returns too many IDs and DOSs receiving servers with large requests.
-  DCHECK_LE(variation_ids_set_.size(), 10U);
-  if (variation_ids_set_.size() > 20)
+  const size_t total_id_count =
+      variation_ids_set_.size() + variation_trigger_ids_set_.size();
+  DCHECK_LE(total_id_count, 10U);
+  if (total_id_count > 20)
     return;
 
   // Merge the two sets of experiment ids.
@@ -179,9 +193,14 @@
     proto.add_variation_id(*it);
   }
 
+  std::set<VariationID> all_trigger_ids_set = default_trigger_id_set_;
   for (std::set<VariationID>::const_iterator it =
-           default_trigger_id_set_.begin();
-       it != default_trigger_id_set_.end(); ++it) {
+           variation_trigger_ids_set_.begin();
+       it != variation_trigger_ids_set_.end(); ++it) {
+    all_trigger_ids_set.insert(*it);
+  }
+  for (std::set<VariationID>::const_iterator it = all_trigger_ids_set.begin();
+       it != all_trigger_ids_set.end(); ++it) {
     proto.add_trigger_variation_id(*it);
   }
 
diff --git a/chrome/browser/metrics/variations/variations_http_header_provider.h b/chrome/browser/metrics/variations/variations_http_header_provider.h
index 930e3df..4b7d9a8 100644
--- a/chrome/browser/metrics/variations/variations_http_header_provider.h
+++ b/chrome/browser/metrics/variations/variations_http_header_provider.h
@@ -62,6 +62,8 @@
                            SetDefaultVariationIds_Valid);
   FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest,
                            SetDefaultVariationIds_Invalid);
+  FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest,
+                           OnFieldTrialGroupFinalized);
 
   VariationsHttpHeaderProvider();
   virtual ~VariationsHttpHeaderProvider();
@@ -97,6 +99,7 @@
   // Keep a cache of variation IDs that are transmitted in headers to Google.
   // This consists of a list of valid IDs, and the actual transmitted header.
   std::set<chrome_variations::VariationID> variation_ids_set_;
+  std::set<chrome_variations::VariationID> variation_trigger_ids_set_;
 
   // Provides the google experiment ids forced from command line.
   std::set<chrome_variations::VariationID> default_variation_ids_set_;
diff --git a/chrome/browser/metrics/variations/variations_http_header_provider_unittest.cc b/chrome/browser/metrics/variations/variations_http_header_provider_unittest.cc
index f66a438..2aeed12 100644
--- a/chrome/browser/metrics/variations/variations_http_header_provider_unittest.cc
+++ b/chrome/browser/metrics/variations/variations_http_header_provider_unittest.cc
@@ -8,7 +8,11 @@
 
 #include "base/base64.h"
 #include "base/message_loop/message_loop.h"
+#include "base/metrics/field_trial.h"
+#include "base/run_loop.h"
 #include "chrome/common/metrics/proto/chrome_experiments.pb.h"
+#include "components/variations/entropy_provider.h"
+#include "components/variations/variations_associated_data.h"
 #include "net/http/http_request_headers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -34,9 +38,34 @@
   return true;
 }
 
+scoped_refptr<base::FieldTrial> CreateTrialAndAssociateId(
+    const std::string& trial_name,
+    const std::string& default_group_name,
+    IDCollectionKey key,
+    VariationID id) {
+  scoped_refptr<base::FieldTrial> trial(
+      base::FieldTrialList::CreateFieldTrial(trial_name, default_group_name));
+
+  chrome_variations::AssociateGoogleVariationID(key, trial->trial_name(),
+                                                trial->group_name(), id);
+
+  return trial;
+}
+
 }  // namespace
 
-TEST(VariationsHttpHeaderProviderTest, ShouldAppendHeaders) {
+class VariationsHttpHeaderProviderTest : public ::testing::Test {
+ public:
+  VariationsHttpHeaderProviderTest() {}
+
+  virtual ~VariationsHttpHeaderProviderTest() {}
+
+  virtual void TearDown() OVERRIDE {
+    testing::ClearAllVariationIDs();
+  }
+};
+
+TEST_F(VariationsHttpHeaderProviderTest, ShouldAppendHeaders) {
   struct {
     const char* url;
     bool should_append_headers;
@@ -90,7 +119,7 @@
   }
 }
 
-TEST(VariationsHttpHeaderProviderTest, SetDefaultVariationIds_Valid) {
+TEST_F(VariationsHttpHeaderProviderTest, SetDefaultVariationIds_Valid) {
   base::MessageLoop loop;
   VariationsHttpHeaderProvider provider;
   GURL url("http://www.google.com");
@@ -112,7 +141,7 @@
   EXPECT_FALSE(variation_ids.find(789) != variation_ids.end());
 }
 
-TEST(VariationsHttpHeaderProviderTest, SetDefaultVariationIds_Invalid) {
+TEST_F(VariationsHttpHeaderProviderTest, SetDefaultVariationIds_Invalid) {
   base::MessageLoop loop;
   VariationsHttpHeaderProvider provider;
   GURL url("http://www.google.com");
@@ -131,4 +160,39 @@
   EXPECT_FALSE(headers.HasHeader("X-Client-Data"));
 }
 
+TEST_F(VariationsHttpHeaderProviderTest, OnFieldTrialGroupFinalized) {
+  base::MessageLoop loop;
+  base::FieldTrialList field_trial_list(
+      new metrics::SHA1EntropyProvider("test"));
+  VariationsHttpHeaderProvider provider;
+  provider.InitVariationIDsCacheIfNeeded();
+
+  const std::string default_name = "default";
+  scoped_refptr<base::FieldTrial> trial_1(CreateTrialAndAssociateId(
+      "t1", default_name, GOOGLE_WEB_PROPERTIES, 123));
+
+  ASSERT_EQ(default_name, trial_1->group_name());
+
+  scoped_refptr<base::FieldTrial> trial_2(CreateTrialAndAssociateId(
+      "t2", default_name, GOOGLE_WEB_PROPERTIES_TRIGGER, 456));
+
+  ASSERT_EQ(default_name, trial_2->group_name());
+
+  // Run the message loop to make sure OnFieldTrialGroupFinalized is called for
+  // the two field trials.
+  base::RunLoop().RunUntilIdle();
+
+  GURL url("http://www.google.com");
+  net::HttpRequestHeaders headers;
+  provider.AppendHeaders(url, false, false, &headers);
+  std::string variations;
+  headers.GetHeader("X-Client-Data", &variations);
+
+  std::set<VariationID> variation_ids;
+  std::set<VariationID> trigger_ids;
+  ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids));
+  EXPECT_TRUE(variation_ids.find(123) != variation_ids.end());
+  EXPECT_TRUE(trigger_ids.find(456) != trigger_ids.end());
+}
+
 }  // namespace chrome_variations
diff --git a/chrome/browser/metrics/variations/variations_service.cc b/chrome/browser/metrics/variations/variations_service.cc
index 4d3aec7..e8fe57d 100644
--- a/chrome/browser/metrics/variations/variations_service.cc
+++ b/chrome/browser/metrics/variations/variations_service.cc
@@ -12,6 +12,7 @@
 #include "base/metrics/sparse_histogram.h"
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
+#include "base/sys_info.h"
 #include "base/version.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/network_time/network_time_tracker.h"
@@ -156,7 +157,7 @@
 }
 
 
-// Get current form factor and convert it from enum DeviceFormFactor to enum
+// Gets current form factor and converts it from enum DeviceFormFactor to enum
 // Study_FormFactor.
 Study_FormFactor GetCurrentFormFactor() {
   switch (ui::GetDeviceFormFactor()) {
@@ -171,6 +172,15 @@
   return Study_FormFactor_DESKTOP;
 }
 
+// Gets the hardware class and returns it as a string. This returns an empty
+// string if the client is not ChromeOS.
+std::string GetHardwareClass() {
+#if defined(OS_CHROMEOS)
+  return base::SysInfo::GetLsbReleaseBoard();
+#endif  // OS_CHROMEOS
+  return std::string();
+}
+
 // Returns the date that should be used by the VariationsSeedProcessor to do
 // expiry and start date checks.
 base::Time GetReferenceDateForExpiryChecks(PrefService* local_state) {
@@ -230,7 +240,7 @@
   VariationsSeedProcessor().CreateTrialsFromSeed(
       seed, g_browser_process->GetApplicationLocale(),
       GetReferenceDateForExpiryChecks(local_state_), current_version,
-      GetChannelForVariations(), GetCurrentFormFactor());
+      GetChannelForVariations(), GetCurrentFormFactor(), GetHardwareClass());
 
   // Log the "freshness" of the seed that was just used. The freshness is the
   // time between the last successful seed download and now.
diff --git a/chrome/browser/mouseleave_browsertest.cc b/chrome/browser/mouseleave_browsertest.cc
index d909f1a..664f6b6 100644
--- a/chrome/browser/mouseleave_browsertest.cc
+++ b/chrome/browser/mouseleave_browsertest.cc
@@ -10,7 +10,6 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/browser_test_utils.h"
 #include "ui/base/test/ui_controls.h"
 
@@ -26,8 +25,7 @@
 
     content::WebContents* tab =
         browser()->tab_strip_model()->GetActiveWebContents();
-    gfx::Rect tab_view_bounds;
-    tab->GetView()->GetContainerBounds(&tab_view_bounds);
+    gfx::Rect tab_view_bounds = tab->GetContainerBounds();
 
     gfx::Point in_content_point(
         tab_view_bounds.x() + tab_view_bounds.width() / 2,
diff --git a/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc b/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc
index b30a3ae..c4ffd39 100644
--- a/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc
+++ b/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/nacl_host/nacl_infobar_delegate.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_paths_internal.h"
@@ -104,8 +105,10 @@
 }  // namespace
 
 NaClBrowserDelegateImpl::NaClBrowserDelegateImpl(
-    extensions::InfoMap* extension_info_map)
-    : extension_info_map_(extension_info_map), inverse_debug_patterns_(false) {}
+    ProfileManager* profile_manager)
+    : profile_manager_(profile_manager), inverse_debug_patterns_(false) {
+  DCHECK(profile_manager_);
+}
 
 NaClBrowserDelegateImpl::~NaClBrowserDelegateImpl() {
 }
@@ -203,11 +206,22 @@
 // This function is security sensitive.  Be sure to check with a security
 // person before you modify it.
 bool NaClBrowserDelegateImpl::MapUrlToLocalFilePath(
-    const GURL& file_url, bool use_blocking_api, base::FilePath* file_path) {
-  DCHECK(extension_info_map_);
+    const GURL& file_url,
+    bool use_blocking_api,
+    const base::FilePath& profile_directory,
+    base::FilePath* file_path) {
+  // Get the profile associated with the renderer.
+  Profile* profile = profile_manager_->GetProfileByPath(profile_directory);
+  if (!profile)
+    return false;
+
+  scoped_refptr<extensions::InfoMap> extension_info_map =
+      extensions::ExtensionSystem::Get(profile)->info_map();
+  DCHECK(extension_info_map);
+
   // Check that the URL is recognized by the extension system.
   const extensions::Extension* extension =
-      extension_info_map_->extensions().GetExtensionOrAppByURL(file_url);
+      extension_info_map->extensions().GetExtensionOrAppByURL(file_url);
   if (!extension)
     return false;
 
@@ -234,7 +248,7 @@
     SharedModuleInfo::ParseImportedPath(path, &new_extension_id,
                                         &new_relative_path);
     const extensions::Extension* new_extension =
-        extension_info_map_->extensions().GetByID(new_extension_id);
+        extension_info_map->extensions().GetByID(new_extension_id);
     if (!new_extension)
       return false;
 
diff --git a/chrome/browser/nacl_host/nacl_browser_delegate_impl.h b/chrome/browser/nacl_host/nacl_browser_delegate_impl.h
index 44b0754..086e1d8 100644
--- a/chrome/browser/nacl_host/nacl_browser_delegate_impl.h
+++ b/chrome/browser/nacl_host/nacl_browser_delegate_impl.h
@@ -7,11 +7,13 @@
 
 #include "base/compiler_specific.h"
 #include "components/nacl/browser/nacl_browser_delegate.h"
-#include "extensions/browser/info_map.h"
+#include "extensions/common/url_pattern.h"
+
+class ProfileManager;
 
 class NaClBrowserDelegateImpl : public NaClBrowserDelegate {
  public:
-  explicit NaClBrowserDelegateImpl(extensions::InfoMap* extension_info_map);
+  explicit NaClBrowserDelegateImpl(ProfileManager* profile_manager);
   virtual ~NaClBrowserDelegateImpl();
 
   virtual void ShowMissingArchInfobar(int render_process_id,
@@ -26,6 +28,7 @@
       content::BrowserPpapiHost* ppapi_host) OVERRIDE;
   virtual bool MapUrlToLocalFilePath(const GURL& url,
                                      bool is_blocking,
+                                     const base::FilePath& profile_directory,
                                      base::FilePath* file_path) OVERRIDE;
   virtual void SetDebugPatterns(std::string debug_patterns) OVERRIDE;
   virtual bool URLMatchesDebugPatterns(const GURL& manifest_url) OVERRIDE;
@@ -33,7 +36,7 @@
       GetOnKeepaliveCallback() OVERRIDE;
 
  private:
-  scoped_refptr<extensions::InfoMap> extension_info_map_;
+  ProfileManager* profile_manager_;
   std::vector<URLPattern> debug_patterns_;
   bool inverse_debug_patterns_;
   DISALLOW_COPY_AND_ASSIGN(NaClBrowserDelegateImpl);
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index 8e5cf65..b580265 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -768,6 +768,7 @@
   static const char* const kLocalAccessWhiteList[] = {
       "/home/chronos/user/Downloads",
       "/home/chronos/user/log",
+      "/home/chronos/user/WebRTC Logs",
       "/media",
       "/opt/oem",
       "/usr/share/chromeos-assets",
diff --git a/chrome/browser/net/firefox_proxy_settings.cc b/chrome/browser/net/firefox_proxy_settings.cc
index bc3b04f..ba7fe94 100644
--- a/chrome/browser/net/firefox_proxy_settings.cc
+++ b/chrome/browser/net/firefox_proxy_settings.cc
@@ -118,7 +118,7 @@
       value = value.substr(1, value.size() - 2);
       // ValueString only accept valid UTF-8.  Simply ignore that entry if it is
       // not UTF-8.
-      if (IsStringUTF8(value))
+      if (base::IsStringUTF8(value))
         prefs->SetString(key, value);
       else
         VLOG(1) << "Non UTF8 value for key " << key << ", ignored.";
diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc
index 8a26189..4c8a435 100644
--- a/chrome/browser/net/predictor.cc
+++ b/chrome/browser/net/predictor.cc
@@ -1320,14 +1320,9 @@
     return url;
   if (!url.SchemeIs("http"))
     return url;
-  net::TransportSecurityState::DomainState domain_state;
-  if (!transport_security_state_->GetDomainState(
-          url.host(),
-          net::SSLConfigService::IsSNIAvailable(ssl_config_service_),
-          &domain_state)) {
-    return url;
-  }
-  if (!domain_state.ShouldUpgradeToSSL())
+  bool sni_available =
+      net::SSLConfigService::IsSNIAvailable(ssl_config_service_);
+  if (!transport_security_state_->ShouldUpgradeToSSL(url.host(), sni_available))
     return url;
 
   url::Replacements<char> replacements;
diff --git a/chrome/browser/net/predictor_tab_helper.cc b/chrome/browser/net/predictor_tab_helper.cc
index 4379281..3f2bcc4 100644
--- a/chrome/browser/net/predictor_tab_helper.cc
+++ b/chrome/browser/net/predictor_tab_helper.cc
@@ -49,7 +49,7 @@
   chrome_browser_net::Predictor* predictor = profile->GetNetworkPredictor();
   if (!predictor)
     return;
-  if (url.SchemeIs(content::kHttpScheme) || url.SchemeIs(content::kHttpsScheme))
+  if (url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kHttpsScheme))
     predictor->PreconnectUrlAndSubresources(url, GURL());
 }
 
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.cc
index bd4d571..25cc7e4 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.cc
@@ -18,28 +18,38 @@
 DataReductionProxyChromeConfigurator::~DataReductionProxyChromeConfigurator() {
 }
 
-void DataReductionProxyChromeConfigurator::Enable(bool restricted,
+void DataReductionProxyChromeConfigurator::Enable(bool primary_restricted,
+                                                  bool fallback_restricted,
                                       const std::string& primary_origin,
                                       const std::string& fallback_origin) {
   DCHECK(prefs_);
   DictionaryPrefUpdate update(prefs_, prefs::kProxy);
   base::DictionaryValue* dict = update.Get();
-  std::string proxy_list;
-  std::string trimmed_fallback_origin;
-  base::TrimString(fallback_origin, "/", &trimmed_fallback_origin);
 
-  if (restricted) {
-    DCHECK(!fallback_origin.empty());
-    proxy_list = trimmed_fallback_origin;
-  } else {
-    std::string trimmed_primary_origin;
-    base::TrimString(primary_origin, "/", &trimmed_primary_origin);
-    proxy_list = trimmed_primary_origin +
-        (fallback_origin.empty() ? "" : "," + trimmed_fallback_origin);
+  std::vector<std::string> proxies;
+  if (!primary_restricted) {
+    std::string trimmed_primary;
+    base::TrimString(primary_origin, "/", &trimmed_primary);
+    if (!trimmed_primary.empty())
+      proxies.push_back(trimmed_primary);
+  }
+  if (!fallback_restricted) {
+    std::string trimmed_fallback;
+    base::TrimString(fallback_origin, "/", &trimmed_fallback);
+    if (!trimmed_fallback.empty())
+      proxies.push_back(trimmed_fallback);
+  }
+  if (proxies.empty()) {
+    std::string mode;
+    // If already in a disabled mode, do nothing.
+    if (dict->GetString("mode", &mode))
+      if (ProxyModeToString(ProxyPrefs::MODE_SYSTEM) == mode)
+        return;
+    Disable();
+    return;
   }
 
-  std::string proxy_server_config = "http=" + proxy_list + ",direct://;";
-  dict->SetString("server", proxy_server_config);
+  dict->SetString("server", "http=" + JoinString(proxies, ",") + ",direct://;");
   dict->SetString("mode", ProxyModeToString(ProxyPrefs::MODE_FIXED_SERVERS));
   dict->SetString("bypass_list", JoinString(bypass_rules_, ", "));
 }
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.h
index 91123ae..e23efbe 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.h
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.h
@@ -19,7 +19,8 @@
   explicit DataReductionProxyChromeConfigurator(PrefService* prefs);
   virtual ~DataReductionProxyChromeConfigurator();
 
-  virtual void Enable(bool restricted,
+  virtual void Enable(bool primary_restricted,
+                      bool fallback_restricted,
                       const std::string& primary_origin,
                       const std::string& fallback_origin) OVERRIDE;
   virtual void Disable() OVERRIDE;
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator_unittest.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator_unittest.cc
index 9e41dc4..a8ef6dc 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator_unittest.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator_unittest.cc
@@ -46,6 +46,7 @@
 
 TEST_F(DataReductionProxyConfigTest, TestUnrestricted) {
   config_->Enable(false,
+                  false,
                   "https://www.foo.com:443/",
                  "http://www.bar.com:80/");
   CheckProxyConfig(
@@ -57,6 +58,7 @@
   config_->AddHostPatternToBypass("<local>");
   config_->AddHostPatternToBypass("*.goo.com");
   config_->Enable(false,
+                  false,
                   "https://www.foo.com:443/",
                  "http://www.bar.com:80/");
   CheckProxyConfig(
@@ -67,6 +69,7 @@
 
 TEST_F(DataReductionProxyConfigTest, TestUnrestrictedWithoutFallback) {
   config_->Enable(false,
+                  false,
                   "https://www.foo.com:443/",
                   "");
   CheckProxyConfig("fixed_servers",
@@ -76,6 +79,7 @@
 
 TEST_F(DataReductionProxyConfigTest, TestRestricted) {
   config_->Enable(true,
+                  false,
                   "https://www.foo.com:443/",
                  "http://www.bar.com:80/");
   CheckProxyConfig("fixed_servers",
@@ -83,6 +87,24 @@
                    "");
 }
 
+TEST_F(DataReductionProxyConfigTest, TestFallbackRestricted) {
+  config_->Enable(false,
+                  true,
+                  "https://www.foo.com:443/",
+                 "http://www.bar.com:80/");
+  CheckProxyConfig("fixed_servers",
+                   "http=https://www.foo.com:443,direct://;",
+                   "");
+}
+
+TEST_F(DataReductionProxyConfigTest, TestBothRestricted) {
+  config_->Enable(true,
+                  true,
+                  "https://www.foo.com:443/",
+                 "http://www.bar.com:80/");
+  CheckProxyConfig("system", "", "");
+}
+
 TEST_F(DataReductionProxyConfigTest, TestDisable) {
   config_->Disable();
   CheckProxyConfig("system", "", "");
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc
index aa87a12..f6d957c 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/metrics/field_trial.h"
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_member.h"
 #include "base/prefs/pref_service.h"
@@ -54,28 +55,41 @@
   NUM_SPDY_PROXY_AUTH_STATE
 };
 
+const char kEnabled[] = "Enabled";
+
 }  // namespace
 
 DataReductionProxySettingsAndroid::DataReductionProxySettingsAndroid(
-    JNIEnv* env, jobject obj): DataReductionProxySettings() {
+    JNIEnv* env, jobject obj) : DataReductionProxySettings() {
+#if defined(SPDY_PROXY_AUTH_VALUE)
+  SetKey(SPDY_PROXY_AUTH_VALUE);
+#endif
+  SetAllowed(IsIncludedInFieldTrialOrFlags());
+  SetPromoAllowed(base::FieldTrialList::FindFullName(
+      "DataCompressionProxyPromoVisibility") == kEnabled);
 }
 
-DataReductionProxySettingsAndroid::DataReductionProxySettingsAndroid() {}
+DataReductionProxySettingsAndroid::DataReductionProxySettingsAndroid() {
+#if defined(SPDY_PROXY_AUTH_VALUE)
+  SetKey(SPDY_PROXY_AUTH_VALUE);
+#endif
+}
 
-DataReductionProxySettingsAndroid::~DataReductionProxySettingsAndroid() {}
+DataReductionProxySettingsAndroid::~DataReductionProxySettingsAndroid() {
+}
 
 void DataReductionProxySettingsAndroid::InitDataReductionProxySettings(
     JNIEnv* env,
     jobject obj) {
+  PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();
+
   scoped_ptr<data_reduction_proxy::DataReductionProxyConfigurator>
-      configurator(
-          new DataReductionProxyChromeConfigurator(
-              ProfileManager::GetActiveUserProfile()->GetPrefs()));
+      configurator(new DataReductionProxyChromeConfigurator(prefs));
+  SetProxyConfigurator(configurator.Pass());
   DataReductionProxySettings::InitDataReductionProxySettings(
-      ProfileManager::GetActiveUserProfile()->GetPrefs(),
+      prefs,
       g_browser_process->local_state(),
-      ProfileManager::GetActiveUserProfile()->GetRequestContext(),
-      configurator.Pass());
+      ProfileManager::GetActiveUserProfile()->GetRequestContext());
 }
 
 void DataReductionProxySettingsAndroid::BypassHostPattern(
@@ -211,6 +225,7 @@
 
   if (enabled) {
     config()->Enable(restricted,
+                     !fallback_allowed(),
                      DataReductionProxySettings::GetDataReductionProxyOrigin(),
                      GetDataReductionProxyFallback());
   } else {
diff --git a/chrome/browser/net/ssl_config_service_manager_pref.cc b/chrome/browser/net/ssl_config_service_manager_pref.cc
index 9c61f95..8af3c74 100644
--- a/chrome/browser/net/ssl_config_service_manager_pref.cc
+++ b/chrome/browser/net/ssl_config_service_manager_pref.cc
@@ -265,7 +265,12 @@
 
 void SSLConfigServiceManagerPref::GetSSLConfigFromPrefs(
     net::SSLConfig* config) {
-  config->rev_checking_enabled = rev_checking_enabled_.GetValue();
+  // rev_checking_enabled was formerly a user-settable preference, but now
+  // it is managed-only.
+  if (rev_checking_enabled_.IsManaged())
+    config->rev_checking_enabled = rev_checking_enabled_.GetValue();
+  else
+    config->rev_checking_enabled = false;
   config->rev_checking_required_local_anchors =
       rev_checking_required_local_anchors_.GetValue();
   std::string version_min_str = ssl_version_min_.GetValue();
diff --git a/chrome/browser/net/url_request_mock_util.cc b/chrome/browser/net/url_request_mock_util.cc
index 1d1b704..6255c60 100644
--- a/chrome/browser/net/url_request_mock_util.cc
+++ b/chrome/browser/net/url_request_mock_util.cc
@@ -8,7 +8,6 @@
 
 #include "base/path_service.h"
 #include "base/threading/thread_restrictions.h"
-#include "chrome/browser/google/google_util.h"
 #include "chrome/common/chrome_paths.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/test/net/url_request_failed_job.h"
@@ -39,9 +38,6 @@
     base::FilePath root_http;
     PathService::Get(chrome::DIR_TEST_DATA, &root_http);
     content::URLRequestMockHTTPJob::AddUrlHandler(root_http);
-    content::URLRequestMockHTTPJob::AddHostnameToFileHandler(
-        google_util::LinkDoctorBaseURL().host(),
-        root_http.AppendASCII("mock-link-doctor.json"));
   } else {
     // Revert to the default handlers.
     net::URLRequestFilter::GetInstance()->ClearHandlers();
diff --git a/chrome/browser/notifications/google_now_notification_stats_collector.cc b/chrome/browser/notifications/google_now_notification_stats_collector.cc
new file mode 100644
index 0000000..5ab6e61
--- /dev/null
+++ b/chrome/browser/notifications/google_now_notification_stats_collector.cc
@@ -0,0 +1,77 @@
+// 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.
+
+#include "chrome/browser/notifications/google_now_notification_stats_collector.h"
+
+#include <string>
+
+#include "base/metrics/sparse_histogram.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/notifications/notification.h"
+#include "chrome/browser/notifications/notification_ui_manager.h"
+#include "content/public/browser/user_metrics.h"
+#include "ui/message_center/notification.h"
+
+namespace {
+const char kChromeNowExtensionID[] = "pafkbggdmjlpgkdkcbjmhmfcdpncadgh";
+const int kNotificationsMaxCount = 20;
+}
+
+GoogleNowNotificationStatsCollector::GoogleNowNotificationStatsCollector(
+    message_center::MessageCenter* message_center)
+    : message_center_(message_center) {
+  message_center_->AddObserver(this);
+}
+
+GoogleNowNotificationStatsCollector::~GoogleNowNotificationStatsCollector() {
+  message_center_->RemoveObserver(this);
+}
+
+void GoogleNowNotificationStatsCollector::OnNotificationDisplayed(
+    const std::string& notification_id,
+    const message_center::DisplaySource source) {
+  if ((source == message_center::DISPLAY_SOURCE_POPUP) &&
+      IsNotificationIdForGoogleNow(notification_id)) {
+    content::RecordAction(
+        base::UserMetricsAction(
+            "GoogleNow.MessageCenter.NotificationPoppedUp"));
+  }
+}
+
+void GoogleNowNotificationStatsCollector::OnCenterVisibilityChanged(
+    message_center::Visibility visibility) {
+  if (visibility == message_center::VISIBILITY_MESSAGE_CENTER) {
+    UMA_HISTOGRAM_SPARSE_SLOWLY(
+        "GoogleNow.MessageCenter.Displayed.NotificationsVisible",
+        std::min(CountVisibleGoogleNowNotifications(), kNotificationsMaxCount));
+  }
+}
+
+bool GoogleNowNotificationStatsCollector::IsNotificationIdForGoogleNow(
+  const std::string& notification_id) {
+  bool isGoogleNowNotification = false;
+  const Notification* const notification =
+      g_browser_process->notification_ui_manager()->FindById(notification_id);
+  if (notification) {
+    isGoogleNowNotification =
+        ((notification->notifier_id().type ==
+              message_center::NotifierId::APPLICATION) &&
+        (notification->notifier_id().id == kChromeNowExtensionID));
+  }
+  return isGoogleNowNotification;
+}
+
+int GoogleNowNotificationStatsCollector::CountVisibleGoogleNowNotifications() {
+  typedef message_center::NotificationList::Notifications Notifications;
+  const Notifications visible_notifications =
+      message_center_->GetVisibleNotifications();
+  int google_now_notification_count = 0;
+  for (Notifications::iterator iter = visible_notifications.begin();
+      iter != visible_notifications.end();
+      ++iter) {
+    if ((*iter)->notifier_id().id == kChromeNowExtensionID)
+      google_now_notification_count++;
+  }
+  return google_now_notification_count;
+}
diff --git a/chrome/browser/notifications/google_now_notification_stats_collector.h b/chrome/browser/notifications/google_now_notification_stats_collector.h
new file mode 100644
index 0000000..1fd1387
--- /dev/null
+++ b/chrome/browser/notifications/google_now_notification_stats_collector.h
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef CHROME_BROWSER_NOTIFICATIONS_GOOGLE_NOW_NOTIFICATION_STATS_COLLECTOR_H_
+#define CHROME_BROWSER_NOTIFICATIONS_GOOGLE_NOW_NOTIFICATION_STATS_COLLECTOR_H_
+
+#include <string>
+
+#include "ui/message_center/message_center.h"
+#include "ui/message_center/message_center_observer.h"
+#include "ui/message_center/message_center_types.h"
+
+// The Google Now Notification Stats Collector listens for message center
+// events and records stats about Google Now specific notifications.
+class GoogleNowNotificationStatsCollector
+    : public message_center::MessageCenterObserver {
+ public:
+  explicit GoogleNowNotificationStatsCollector(
+      message_center::MessageCenter* message_center);
+  virtual ~GoogleNowNotificationStatsCollector();
+
+ private:
+  // MessageCenterObserver
+  virtual void OnNotificationDisplayed(
+      const std::string& notification_id,
+      const message_center::DisplaySource source) OVERRIDE;
+  virtual void OnCenterVisibilityChanged(
+      message_center::Visibility visibility) OVERRIDE;
+
+  // Counts the number of Google Now Notifications in the message center.
+  int CountVisibleGoogleNowNotifications();
+
+  // Returns true if the notification ID is for Google Now.
+  bool IsNotificationIdForGoogleNow(const std::string& notification_id);
+
+  // Weak, global.
+  message_center::MessageCenter* message_center_;
+
+  DISALLOW_COPY_AND_ASSIGN(GoogleNowNotificationStatsCollector);
+};
+
+#endif  // CHROME_BROWSER_NOTIFICATIONS_GOOGLE_NOW_NOTIFICATION_STATS_COLLECTOR_H_
diff --git a/chrome/browser/notifications/message_center_notification_manager.cc b/chrome/browser/notifications/message_center_notification_manager.cc
index 85a4dfe..c06040a 100644
--- a/chrome/browser/notifications/message_center_notification_manager.cc
+++ b/chrome/browser/notifications/message_center_notification_manager.cc
@@ -60,7 +60,8 @@
 #endif
       settings_provider_(settings_provider.Pass()),
       system_observer_(this),
-      stats_collector_(message_center) {
+      stats_collector_(message_center),
+      google_now_stats_collector_(message_center) {
 #if defined(OS_WIN)
   first_run_pref_.Init(prefs::kMessageCenterShowedFirstRunBalloon, local_state);
 #endif
diff --git a/chrome/browser/notifications/message_center_notification_manager.h b/chrome/browser/notifications/message_center_notification_manager.h
index 52f3c16..e8400f9 100644
--- a/chrome/browser/notifications/message_center_notification_manager.h
+++ b/chrome/browser/notifications/message_center_notification_manager.h
@@ -14,6 +14,7 @@
 #include "base/prefs/pref_member.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
+#include "chrome/browser/notifications/google_now_notification_stats_collector.h"
 #include "chrome/browser/notifications/message_center_stats_collector.h"
 #include "chrome/browser/notifications/notification.h"
 #include "chrome/browser/notifications/notification_system_observer.h"
@@ -240,6 +241,9 @@
   // Keeps track of all notification statistics for UMA purposes.
   MessageCenterStatsCollector stats_collector_;
 
+  // Keeps track of notifications specific to Google Now for UMA purposes.
+  GoogleNowNotificationStatsCollector google_now_stats_collector_;
+
   DISALLOW_COPY_AND_ASSIGN(MessageCenterNotificationManager);
 };
 
diff --git a/chrome/browser/notifications/message_center_notifications_unittest_win.cc b/chrome/browser/notifications/message_center_notifications_unittest_win.cc
index 86b19ed..acb0a44 100644
--- a/chrome/browser/notifications/message_center_notifications_unittest_win.cc
+++ b/chrome/browser/notifications/message_center_notifications_unittest_win.cc
@@ -105,7 +105,8 @@
 TEST_F(MessageCenterNotificationManagerTest, FirstRunShown) {
   TestingProfile profile;
   notification_manager()->Add(GetANotification("test"), &profile);
-  message_center()->DisplayedNotification("test");
+  message_center()->DisplayedNotification(
+      "test", message_center::DISPLAY_SOURCE_MESSAGE_CENTER);
   message_center()->MarkSinglePopupAsShown("test", false);
 
   run_loop()->Run();
@@ -119,7 +120,8 @@
        FirstRunNotShownWithPopupsVisible) {
   TestingProfile profile;
   notification_manager()->Add(GetANotification("test"), &profile);
-  message_center()->DisplayedNotification("test");
+  message_center()->DisplayedNotification(
+      "test", message_center::DISPLAY_SOURCE_MESSAGE_CENTER);
   run_loop()->RunUntilIdle();
   EXPECT_FALSE(delegate()->displayed_first_run_balloon());
   EXPECT_FALSE(notification_manager()->FirstRunTimerIsActive());
diff --git a/chrome/browser/notifications/message_center_stats_collector.cc b/chrome/browser/notifications/message_center_stats_collector.cc
index 3ab6203..82e3e96 100644
--- a/chrome/browser/notifications/message_center_stats_collector.cc
+++ b/chrome/browser/notifications/message_center_stats_collector.cc
@@ -108,7 +108,8 @@
 }
 
 void MessageCenterStatsCollector::OnNotificationDisplayed(
-    const std::string& notification_id) {
+    const std::string& notification_id,
+    const message_center::DisplaySource source) {
   StatsCollection::iterator iter = stats_.find(notification_id);
   if (iter == stats_.end())
     return;
diff --git a/chrome/browser/notifications/message_center_stats_collector.h b/chrome/browser/notifications/message_center_stats_collector.h
index 463b7ed..b14cfb0 100644
--- a/chrome/browser/notifications/message_center_stats_collector.h
+++ b/chrome/browser/notifications/message_center_stats_collector.h
@@ -73,7 +73,8 @@
   virtual void OnNotificationButtonClicked(const std::string& notification_id,
                                            int button_index) OVERRIDE;
   virtual void OnNotificationDisplayed(
-      const std::string& notification_id) OVERRIDE;
+      const std::string& notification_id,
+      const message_center::DisplaySource source) OVERRIDE;
   virtual void OnCenterVisibilityChanged(
       message_center::Visibility visibility) OVERRIDE;
   virtual void OnQuietModeChanged(bool in_quiet_mode) OVERRIDE;
diff --git a/chrome/browser/notifications/sync_notifier/image_holder.cc b/chrome/browser/notifications/sync_notifier/image_holder.cc
deleted file mode 100644
index c5dcbc1..0000000
--- a/chrome/browser/notifications/sync_notifier/image_holder.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// 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.
-
-// This class holds the URL to an image and the bitmap for the fetched image,
-// and has code to fetch the bitmap from the URL.
-
-#include "chrome/browser/notifications/sync_notifier/image_holder.h"
-
-#include "chrome/browser/profiles/profile.h"
-
-namespace notifier {
-
-ImageHolder::ImageHolder(const GURL& low_dpi_url,
-                         const GURL& high_dpi_url,
-                         Profile* profile,
-                         ImageHolderDelegate* delegate)
-    : low_dpi_url_(low_dpi_url),
-      high_dpi_url_(high_dpi_url),
-      low_dpi_fetched_(false),
-      high_dpi_fetched_(false),
-      delegate_(delegate),
-      profile_(profile) {
-
-  // If a URL is invalid, clear it so we don't try to fetch it.
-  if (!low_dpi_url_.is_valid()) {
-    low_dpi_url_ = GURL();
-  }
-  if (!high_dpi_url_.is_valid()) {
-    high_dpi_url_ = GURL();
-  }
-
-  // Create a featcher for each URL that is set.
-  if (!low_dpi_url_.is_empty()) {
-    CreateBitmapFetcher(low_dpi_url_);
-  }
-  if (!high_dpi_url_.is_empty()) {
-    CreateBitmapFetcher(high_dpi_url_);
-  }
-}
-
-ImageHolder::~ImageHolder() {}
-
-// This will let us know if we have tried to fetch once and the try completed.
-// Currently there is no logic for retries.
-bool ImageHolder::IsFetchingDone() const {
-  return ((low_dpi_url_.is_empty() || low_dpi_fetched_) &&
-           (high_dpi_url_.is_empty() || high_dpi_fetched_));
-}
-
-// If this bitmap has a valid GURL, create a fetcher for it.
-void ImageHolder::CreateBitmapFetcher(const GURL& url) {
-  // Check for dups, ignore any request for a dup.
-  ScopedVector<chrome::BitmapFetcher>::iterator iter;
-  for (iter = fetchers_.begin(); iter != fetchers_.end(); ++iter) {
-    if ((*iter)->url() == url)
-      return;
-  }
-
-  if (url.is_valid()) {
-    fetchers_.push_back(new chrome::BitmapFetcher(url, this));
-    DVLOG(2) << __FUNCTION__ << "Pushing bitmap " << url;
-  }
-}
-
-void ImageHolder::StartFetch() {
-  // Now that we have queued them all, start the fetching.
-  ScopedVector<chrome::BitmapFetcher>::iterator iter;
-  for (iter = fetchers_.begin(); iter != fetchers_.end(); ++iter) {
-    (*iter)->Start(profile_->GetRequestContext());
-  }
-}
-
-// Method inherited from BitmapFetcher delegate.
-void ImageHolder::OnFetchComplete(const GURL url, const SkBitmap* bitmap) {
-  // TODO(petewil): Should I retry if a fetch fails?
-  // Match the bitmap to the URL to put it into the image with the correct scale
-  // factor.
-  if (url == low_dpi_url_) {
-    low_dpi_fetched_ = true;
-    if (bitmap != NULL)
-      image_.AddRepresentation(gfx::ImageSkiaRep(*bitmap, 1.0));
-  } else if (url == high_dpi_url_) {
-    high_dpi_fetched_ = true;
-    if (bitmap != NULL)
-      image_.AddRepresentation(gfx::ImageSkiaRep(*bitmap, 2.0));
-  } else {
-    DVLOG(2) << __FUNCTION__ << "Unmatched bitmap arrived " << url;
-  }
-
-  // Notify callback of bitmap arrival.
-  delegate_->OnFetchComplete();
-}
-
-}  // namespace notifier.
diff --git a/chrome/browser/notifications/sync_notifier/image_holder.h b/chrome/browser/notifications/sync_notifier/image_holder.h
deleted file mode 100644
index 3d0c089..0000000
--- a/chrome/browser/notifications/sync_notifier/image_holder.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_NOTIFICATIONS_SYNC_NOTIFIER_IMAGE_HOLDER_H_
-#define CHROME_BROWSER_NOTIFICATIONS_SYNC_NOTIFIER_IMAGE_HOLDER_H_
-
-#include "base/memory/scoped_vector.h"
-#include "chrome/browser/bitmap_fetcher.h"
-#include "ui/gfx/image/image.h"
-#include "ui/gfx/image/image_skia.h"
-#include "url/gurl.h"
-
-class Profile;
-
-namespace notifier {
-
-// This provides a callback so the ImageHolder can inform its parent when a
-// bitmap arrives.
-class ImageHolderDelegate {
- public:
-  virtual void OnFetchComplete() = 0;
-};
-
-// This class encapsulates the action of fetching a bitmap, reporting when it is
-// fetched, and holding onto the bitmap until no longer needed.
-class ImageHolder : public chrome::BitmapFetcherDelegate {
- public:
-  ImageHolder(const GURL& low_dpi_url,
-              const GURL& high_dpi_url,
-              Profile* profile,
-              ImageHolderDelegate* delegate);
-  virtual ~ImageHolder();
-
-  // Begin fetching of the URLs we have.
-  void StartFetch();
-
-  // Check whether we have a response from the server for these resources,
-  // even if the response is a failed fetch.
-  bool IsFetchingDone() const;
-
-  // Inherited from BitmapFetcherDelegate
-  virtual void OnFetchComplete(const GURL url, const SkBitmap* bitmap) OVERRIDE;
-
-  // Accessors:
-  GURL low_dpi_url() const { return low_dpi_url_; }
-  GURL high_dpi_url() const { return high_dpi_url_; }
-  gfx::Image low_dpi_image() { return gfx::Image(image_); }
-
- private:
-  // Helper function to create a bitmap fetcher (but not start the fetch).
-  void CreateBitmapFetcher(const GURL& url);
-
-  GURL low_dpi_url_;
-  GURL high_dpi_url_;
-  bool low_dpi_fetched_;
-  bool high_dpi_fetched_;
-  gfx::ImageSkia image_;
-  ImageHolderDelegate* delegate_;
-  ScopedVector<chrome::BitmapFetcher> fetchers_;
-  Profile* profile_;
-
-  FRIEND_TEST_ALL_PREFIXES(ImageHolderTest, CreateBitmapFetcherTest);
-  FRIEND_TEST_ALL_PREFIXES(ImageHolderTest, OnFetchCompleteTest);
-  FRIEND_TEST_ALL_PREFIXES(ImageHolderTest, IsFetchingDoneTest);
-
-  DISALLOW_COPY_AND_ASSIGN(ImageHolder);
-};
-
-}  // namespace notifier.
-
-#endif  // CHROME_BROWSER_NOTIFICATIONS_SYNC_NOTIFIER_IMAGE_HOLDER_H_
diff --git a/chrome/browser/notifications/sync_notifier/image_holder_unittest.cc b/chrome/browser/notifications/sync_notifier/image_holder_unittest.cc
deleted file mode 100644
index 534228e..0000000
--- a/chrome/browser/notifications/sync_notifier/image_holder_unittest.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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.
-
-#include <string>
-
-#include "chrome/browser/notifications/sync_notifier/image_holder.h"
-#include "chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-class TestDelegate : public notifier::ImageHolderDelegate {
- public:
-  TestDelegate() : on_fetch_complete_called_(false) {}
-  virtual void OnFetchComplete() OVERRIDE {
-    on_fetch_complete_called_ = true;
-  }
-  bool on_fetch_complete_called_;
-};
-
-}  // namespace.
-
-namespace notifier {
-
-typedef testing::Test ImageHolderTest;
-
-TEST_F(ImageHolderTest, CreateBitmapFetcherTest) {
-  TestDelegate delegate;
-  ImageHolder image_holder(GURL(kIconUrl1), GURL(kIconUrl2), NULL, &delegate);
-
-  EXPECT_EQ(GURL(kIconUrl1), image_holder.fetchers_[0]->url());
-  EXPECT_EQ(GURL(kIconUrl2), image_holder.fetchers_[1]->url());
-  EXPECT_EQ(static_cast<unsigned int>(2), image_holder.fetchers_.size());
-
-  // Adding a dup of an existing URL shouldn't change anything.
-  image_holder.CreateBitmapFetcher(GURL(kIconUrl2));
-  EXPECT_EQ(GURL(kIconUrl1), image_holder.fetchers_[0]->url());
-  EXPECT_EQ(GURL(kIconUrl2), image_holder.fetchers_[1]->url());
-  EXPECT_EQ(static_cast<unsigned int>(2), image_holder.fetchers_.size());
-}
-
-TEST_F(ImageHolderTest, OnFetchCompleteTest) {
-  TestDelegate delegate;
-  ImageHolder image_holder(GURL(kIconUrl1), GURL(), NULL, &delegate);
-
-  // Put a real bitmap into "bitmap".  2x2 bitmap of green 32 bit pixels.
-  SkBitmap bitmap;
-  bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
-  bitmap.allocPixels();
-  bitmap.eraseColor(SK_ColorGREEN);
-
-  image_holder.OnFetchComplete(GURL(kIconUrl1), &bitmap);
-
-  // Expect that the app icon has some data in it.
-  EXPECT_FALSE(image_holder.low_dpi_image().IsEmpty());
-
-  // Expect that we reported the fetch done to the delegate.
-  EXPECT_TRUE(delegate.on_fetch_complete_called_);
-}
-
-TEST_F(ImageHolderTest, IsFetchingDoneTest) {
-  TestDelegate delegate;
-  ImageHolder image_holder1(GURL(kIconUrl1), GURL(kIconUrl2), NULL, &delegate);
-  ImageHolder image_holder2(GURL(kIconUrl1), GURL(), NULL, &delegate);
-  ImageHolder image_holder3(GURL(), GURL(kIconUrl2), NULL, &delegate);
-  ImageHolder image_holder4(GURL(), GURL(), NULL, &delegate);
-
-  // Initially, image holder 4 with no URLs should report done, but no others.
-  EXPECT_FALSE(image_holder1.IsFetchingDone());
-  EXPECT_FALSE(image_holder2.IsFetchingDone());
-  EXPECT_FALSE(image_holder3.IsFetchingDone());
-  EXPECT_TRUE(image_holder4.IsFetchingDone());
-
-  // Put a real bitmap into "bitmap".  2x2 bitmap of green 32 bit pixels.
-  SkBitmap bitmap;
-  bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
-  bitmap.allocPixels();
-  bitmap.eraseColor(SK_ColorGREEN);
-
-  // Add the first icon, and image holder 2 should now also report done.
-  image_holder1.OnFetchComplete(GURL(kIconUrl1), &bitmap);
-  image_holder2.OnFetchComplete(GURL(kIconUrl1), &bitmap);
-  image_holder3.OnFetchComplete(GURL(kIconUrl1), &bitmap);
-  image_holder4.OnFetchComplete(GURL(kIconUrl1), &bitmap);
-  EXPECT_FALSE(image_holder1.IsFetchingDone());
-  EXPECT_TRUE(image_holder2.IsFetchingDone());
-  EXPECT_FALSE(image_holder3.IsFetchingDone());
-  EXPECT_TRUE(image_holder4.IsFetchingDone());
-
-  // Add the second image, and now all 4 should report done.
-  image_holder1.OnFetchComplete(GURL(kIconUrl2), &bitmap);
-  image_holder2.OnFetchComplete(GURL(kIconUrl2), &bitmap);
-  image_holder3.OnFetchComplete(GURL(kIconUrl2), &bitmap);
-  image_holder4.OnFetchComplete(GURL(kIconUrl2), &bitmap);
-  EXPECT_TRUE(image_holder1.IsFetchingDone());
-  EXPECT_TRUE(image_holder2.IsFetchingDone());
-  EXPECT_TRUE(image_holder3.IsFetchingDone());
-  EXPECT_TRUE(image_holder4.IsFetchingDone());
-}
-
-}  // namespace notifier.
diff --git a/chrome/browser/notifications/sync_notifier/synced_notification.cc b/chrome/browser/notifications/sync_notifier/synced_notification.cc
index 105b4c5..ad795a0 100644
--- a/chrome/browser/notifications/sync_notifier/synced_notification.cc
+++ b/chrome/browser/notifications/sync_notifier/synced_notification.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/browser_thread.h"
+#include "net/base/load_flags.h"
 #include "skia/ext/image_operations.h"
 #include "sync/protocol/sync.pb.h"
 #include "sync/protocol/synced_notification_specifics.pb.h"
@@ -283,7 +284,11 @@
   // Now that we have queued and counted them all, start the fetching.
   ScopedVector<chrome::BitmapFetcher>::iterator iter;
   for (iter = fetchers_.begin(); iter != fetchers_.end(); ++iter) {
-    (*iter)->Start(profile_->GetRequestContext());
+    (*iter)->Start(
+        profile_->GetRequestContext(),
+        std::string(),
+        net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+        net::LOAD_NORMAL);
   }
 }
 
diff --git a/chrome/browser/notifications/sync_notifier/synced_notification_app_info.cc b/chrome/browser/notifications/sync_notifier/synced_notification_app_info.cc
index 9c82fb74..6511f81 100644
--- a/chrome/browser/notifications/sync_notifier/synced_notification_app_info.cc
+++ b/chrome/browser/notifications/sync_notifier/synced_notification_app_info.cc
@@ -4,12 +4,14 @@
 
 #include "chrome/browser/notifications/sync_notifier/synced_notification_app_info.h"
 
-#include "chrome/browser/notifications/sync_notifier/image_holder.h"
 #include "chrome/browser/notifications/sync_notifier/synced_notification_app_info_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "sync/api/sync_data.h"
 #include "sync/protocol/synced_notification_app_info_specifics.pb.h"
 
+using chrome::ImageHolder;
+using chrome::ImageHolderDelegate;
+
 namespace notifier {
 
 SyncedNotificationAppInfo::SyncedNotificationAppInfo(
diff --git a/chrome/browser/notifications/sync_notifier/synced_notification_app_info.h b/chrome/browser/notifications/sync_notifier/synced_notification_app_info.h
index 3862528..d68b26a 100644
--- a/chrome/browser/notifications/sync_notifier/synced_notification_app_info.h
+++ b/chrome/browser/notifications/sync_notifier/synced_notification_app_info.h
@@ -12,7 +12,7 @@
 #include <vector>
 
 #include "base/memory/scoped_vector.h"
-#include "chrome/browser/notifications/sync_notifier/image_holder.h"
+#include "chrome/browser/image_holder.h"
 #include "ui/gfx/image/image.h"
 #include "ui/message_center/notifier_settings.h"
 #include "url/gurl.h"
@@ -23,7 +23,7 @@
 
 class SyncedNotificationAppInfoService;
 
-class SyncedNotificationAppInfo : public notifier::ImageHolderDelegate {
+class SyncedNotificationAppInfo : public chrome::ImageHolderDelegate {
  public:
   SyncedNotificationAppInfo(
       Profile* const profile,
@@ -72,7 +72,7 @@
   std::vector<std::string> added_app_ids() { return added_app_ids_; }
 
   // If an app info is updated removing app ids, keep track of the removed app
-  // ids so we can later remove any affected notfications.
+  // ids so we can later remove any affected notifications.
   void set_removed_app_ids(std::vector<std::string> removed_app_ids) {
     removed_app_ids_ = removed_app_ids;
   }
@@ -111,11 +111,11 @@
   GURL welcome_link_url_;
 
   // The 1x and 2x versions of the icon for settings, small.
-  scoped_ptr<ImageHolder> settings_holder_;
+  scoped_ptr<chrome::ImageHolder> settings_holder_;
   // Monochrome icons for app badging (1x and 2x), small.
-  scoped_ptr<ImageHolder> monochrome_holder_;
+  scoped_ptr<chrome::ImageHolder> monochrome_holder_;
   // Welcome dialog icon (1x and 2x), large.
-  scoped_ptr<ImageHolder> welcome_holder_;
+  scoped_ptr<chrome::ImageHolder> welcome_holder_;
   // A landing page link for settings/welcome toast.
   GURL welcome_landing_page_url_;
   std::vector<std::string> added_app_ids_;
diff --git a/chrome/browser/omnibox/omnibox_log.cc b/chrome/browser/omnibox/omnibox_log.cc
index 2ad76a0..48f6241 100644
--- a/chrome/browser/omnibox/omnibox_log.cc
+++ b/chrome/browser/omnibox/omnibox_log.cc
@@ -8,7 +8,9 @@
     const base::string16& text,
     bool just_deleted_text,
     AutocompleteInput::Type input_type,
+    bool is_popup_open,
     size_t selected_index,
+    bool is_paste_and_go,
     SessionID::id_type tab_id,
     AutocompleteInput::PageClassification current_page_classification,
     base::TimeDelta elapsed_time_since_user_first_modified_omnibox,
@@ -18,7 +20,9 @@
     : text(text),
       just_deleted_text(just_deleted_text),
       input_type(input_type),
+      is_popup_open(is_popup_open),
       selected_index(selected_index),
+      is_paste_and_go(is_paste_and_go),
       tab_id(tab_id),
       current_page_classification(current_page_classification),
       elapsed_time_since_user_first_modified_omnibox(
diff --git a/chrome/browser/omnibox/omnibox_log.h b/chrome/browser/omnibox/omnibox_log.h
index f3b4809..3b5d2eb 100644
--- a/chrome/browser/omnibox/omnibox_log.h
+++ b/chrome/browser/omnibox/omnibox_log.h
@@ -22,7 +22,9 @@
       const base::string16& text,
       bool just_deleted_text,
       AutocompleteInput::Type input_type,
+      bool is_popup_open,
       size_t selected_index,
+      bool is_paste_and_go,
       SessionID::id_type tab_id,
       AutocompleteInput::PageClassification current_page_classification,
       base::TimeDelta elapsed_time_since_user_first_modified_omnibox,
@@ -41,9 +43,17 @@
   // The detected type of the user's input.
   AutocompleteInput::Type input_type;
 
-  // Selected index (if selected) or -1 (OmniboxPopupModel::kNoMatch).
+  // True if the popup is open.
+  bool is_popup_open;
+
+  // The index of the item selected in the dropdown list.  Set to 0 if the
+  // dropdown is closed (and therefore there is only one implicit suggestion).
   size_t selected_index;
 
+  // True if this is a paste-and-search or paste-and-go omnibox interaction.
+  // (The codebase refers to both these types as paste-and-go.)
+  bool is_paste_and_go;
+
   // ID of the tab the selected autocomplete suggestion was opened in.
   // Set to -1 if we haven't yet determined the destination tab.
   SessionID::id_type tab_id;
@@ -69,7 +79,9 @@
 
   // The amount of time since the last time the default (i.e., inline)
   // match changed.  This will certainly be less than
-  // elapsed_time_since_user_first_modified_omnibox.
+  // elapsed_time_since_user_first_modified_omnibox.  Measuring this
+  // may be inappropriate in some cases (e.g., if editing is not in
+  // progress).  In such cases, it's set to -1 milliseconds.
   base::TimeDelta elapsed_time_since_last_change_to_default_match;
 
   // Result set.
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index 06bd024..31329aa 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -15,7 +15,7 @@
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/autofill/password_generation_popup_controller_impl.h"
-#include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h"
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "components/autofill/content/common/autofill_messages.h"
@@ -28,8 +28,6 @@
 #include "components/password_manager/core/common/password_manager_switches.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "ipc/ipc_message_macros.h"
 
 #if defined(OS_ANDROID)
 #include "chrome/browser/android/password_authentication_manager.h"
@@ -88,10 +86,10 @@
 void ChromePasswordManagerClient::PromptUserToSavePassword(
     password_manager::PasswordFormManager* form_to_save) {
   if (IsTheHotNewBubbleUIEnabled()) {
-    ManagePasswordsBubbleUIController* manage_passwords_bubble_ui_controller =
-        ManagePasswordsBubbleUIController::FromWebContents(web_contents());
-    if (manage_passwords_bubble_ui_controller) {
-      manage_passwords_bubble_ui_controller->OnPasswordSubmitted(form_to_save);
+    ManagePasswordsUIController* manage_passwords_ui_controller =
+        ManagePasswordsUIController::FromWebContents(web_contents());
+    if (manage_passwords_ui_controller) {
+      manage_passwords_ui_controller->OnPasswordSubmitted(form_to_save);
     } else {
       delete form_to_save;
     }
@@ -107,17 +105,18 @@
 
 void ChromePasswordManagerClient::PasswordWasAutofilled(
     const autofill::PasswordFormMap& best_matches) const {
-  ManagePasswordsBubbleUIController* manage_passwords_bubble_ui_controller =
-      ManagePasswordsBubbleUIController::FromWebContents(web_contents());
-  if (manage_passwords_bubble_ui_controller && IsTheHotNewBubbleUIEnabled())
-    manage_passwords_bubble_ui_controller->OnPasswordAutofilled(best_matches);
+  ManagePasswordsUIController* manage_passwords_ui_controller =
+      ManagePasswordsUIController::FromWebContents(web_contents());
+  if (manage_passwords_ui_controller && IsTheHotNewBubbleUIEnabled())
+    manage_passwords_ui_controller->OnPasswordAutofilled(best_matches);
 }
 
-void ChromePasswordManagerClient::PasswordAutofillWasBlocked() const {
-  ManagePasswordsBubbleUIController* manage_passwords_bubble_ui_controller =
-      ManagePasswordsBubbleUIController::FromWebContents(web_contents());
-  if (manage_passwords_bubble_ui_controller && IsTheHotNewBubbleUIEnabled())
-    manage_passwords_bubble_ui_controller->OnBlacklistBlockedAutofill();
+void ChromePasswordManagerClient::PasswordAutofillWasBlocked(
+    const autofill::PasswordFormMap& best_matches) const {
+  ManagePasswordsUIController* controller =
+      ManagePasswordsUIController::FromWebContents(web_contents());
+  if (controller && IsTheHotNewBubbleUIEnabled())
+    controller->OnBlacklistBlockedAutofill(best_matches);
 }
 
 void ChromePasswordManagerClient::AuthenticateAutofillAndFillForm(
@@ -263,8 +262,7 @@
 
 gfx::RectF ChromePasswordManagerClient::GetBoundsInScreenSpace(
     const gfx::RectF& bounds) {
-  gfx::Rect client_area;
-  web_contents()->GetView()->GetContainerBounds(&client_area);
+  gfx::Rect client_area = web_contents()->GetContainerBounds();
   return bounds + client_area.OffsetFromOrigin();
 }
 
@@ -287,7 +285,7 @@
           driver_.GetPasswordManager(),
           observer_,
           web_contents(),
-          web_contents()->GetView()->GetNativeView());
+          web_contents()->GetNativeView());
   popup_controller_->Show(true /* display_password */);
 #endif  // #if defined(USE_AURA)
 }
@@ -308,7 +306,7 @@
           driver_.GetPasswordManager(),
           observer_,
           web_contents(),
-          web_contents()->GetView()->GetNativeView());
+          web_contents()->GetNativeView());
   popup_controller_->Show(false /* display_password */);
 #endif  // #if defined(USE_AURA)
 }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index 17584aa..f57fc3b 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -43,7 +43,8 @@
       password_manager::PasswordFormManager* form_to_save) OVERRIDE;
   virtual void PasswordWasAutofilled(
       const autofill::PasswordFormMap& best_matches) const OVERRIDE;
-  virtual void PasswordAutofillWasBlocked() const OVERRIDE;
+  virtual void PasswordAutofillWasBlocked(
+      const autofill::PasswordFormMap& best_matches) const OVERRIDE;
   virtual void AuthenticateAutofillAndFillForm(
       scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE;
   virtual PrefService* GetPrefs() OVERRIDE;
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index 3728403..1c3de2f 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -674,16 +674,18 @@
           PasswordStoreFactory::GetForProfile(browser()->profile(),
                                               Profile::IMPLICIT_ACCESS).get());
 
-  EXPECT_EQ(0U, password_store->stored_passwords().size());
+  EXPECT_TRUE(password_store->IsEmpty());
 
   NavigateToFile("/password/password_form.html");
 
-  // Enable the enable-automatic-password-saving switch
+  // Add the enable-automatic-password-saving switch.
   CommandLine::ForCurrentProcess()->AppendSwitch(
       password_manager::switches::kEnableAutomaticPasswordSaving);
 
   // Fill a form and submit through a <input type="submit"> button.
   NavigationObserver observer(WebContents());
+  // Make sure that the only passwords saved are the auto-saved ones.
+  observer.disable_should_automatically_accept_infobar();
   std::string fill_and_submit =
       "document.getElementById('username_field').value = 'temp';"
       "document.getElementById('password_field').value = 'random';"
@@ -693,9 +695,27 @@
   if (chrome::VersionInfo::GetChannel() ==
       chrome::VersionInfo::CHANNEL_UNKNOWN) {
     EXPECT_FALSE(observer.infobar_shown());
-    EXPECT_EQ(1U, password_store->stored_passwords().size());
+    EXPECT_FALSE(password_store->IsEmpty());
   } else {
     EXPECT_TRUE(observer.infobar_shown());
-    EXPECT_EQ(0U, password_store->stored_passwords().size());
+    EXPECT_TRUE(password_store->IsEmpty());
   }
 }
+
+// Test fix for crbug.com/368690.
+IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, NoPromptWhenReloading) {
+  NavigateToFile("/password/password_form.html");
+
+  std::string fill =
+      "document.getElementById('username_redirect').value = 'temp';"
+      "document.getElementById('password_redirect').value = 'random';";
+  ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill));
+
+  NavigationObserver observer(WebContents());
+  GURL url = embedded_test_server()->GetURL("/password/password_form.html");
+  chrome::NavigateParams params(browser(), url,
+                                content::PAGE_TRANSITION_RELOAD);
+  ui_test_utils::NavigateToURL(&params);
+  observer.Wait();
+  EXPECT_FALSE(observer.infobar_shown());
+}
diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc
index 99aeff0..9cf6bd6 100644
--- a/chrome/browser/password_manager/password_store_mac.cc
+++ b/chrome/browser/password_manager/password_store_mac.cc
@@ -874,6 +874,7 @@
 
 PasswordStoreChangeList PasswordStoreMac::AddLoginImpl(
     const PasswordForm& form) {
+  DCHECK(thread_->message_loop() == base::MessageLoop::current());
   PasswordStoreChangeList changes;
   if (AddToKeychainIfNecessary(form)) {
     if (login_metadata_db_->AddLogin(form)) {
@@ -885,6 +886,7 @@
 
 PasswordStoreChangeList PasswordStoreMac::UpdateLoginImpl(
     const PasswordForm& form) {
+  DCHECK(thread_->message_loop() == base::MessageLoop::current());
   PasswordStoreChangeList changes;
   int update_count = 0;
   if (!login_metadata_db_->UpdateLogin(form, &update_count))
@@ -916,6 +918,7 @@
 
 PasswordStoreChangeList PasswordStoreMac::RemoveLoginImpl(
     const PasswordForm& form) {
+  DCHECK(thread_->message_loop() == base::MessageLoop::current());
   PasswordStoreChangeList changes;
   if (login_metadata_db_->RemoveLogin(form)) {
     // See if we own a Keychain item associated with this item. We can do an
diff --git a/chrome/browser/performance_monitor/performance_monitor_browsertest.cc b/chrome/browser/performance_monitor/performance_monitor_browsertest.cc
index 61096ee..2dc6001 100644
--- a/chrome/browser/performance_monitor/performance_monitor_browsertest.cc
+++ b/chrome/browser/performance_monitor/performance_monitor_browsertest.cc
@@ -43,6 +43,8 @@
 #include "extensions/common/extension.h"
 
 #if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chromeos/chromeos_switches.h"
 #endif
 
@@ -58,6 +60,13 @@
 
 const base::TimeDelta kMaxStartupTime = base::TimeDelta::FromMinutes(3);
 
+#if defined(OS_CHROMEOS)
+// User account email and directory hash for secondary account for multi-profile
+// sensitive test cases.
+const char kSecondProfileAccount[] = "profile2@test.com";
+const char kSecondProfileHash[] = "profile2";
+#endif
+
 // Helper struct to store the information of an extension; this is needed if the
 // pointer to the extension ever becomes invalid (e.g., if we uninstall the
 // extension).
@@ -276,8 +285,15 @@
 };
 
 class PerformanceMonitorUncleanExitBrowserTest
-    : public PerformanceMonitorBrowserTest {
+    : public PerformanceMonitorBrowserTest,
+      public testing::WithParamInterface<bool> {
  public:
+  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+    PerformanceMonitorBrowserTest::SetUpCommandLine(command_line);
+    if (GetParam())
+      command_line->AppendSwitch(::switches::kMultiProfiles);
+  }
+
   virtual bool SetUpUserDataDirectory() OVERRIDE {
     base::FilePath user_data_directory;
     PathService::Get(chrome::DIR_USER_DATA, &user_data_directory);
@@ -316,6 +332,12 @@
     second_profile_name_ =
         std::string(chrome::kMultiProfileDirPrefix)
         .append(base::IntToString(1));
+#if defined(OS_CHROMEOS)
+    if (GetParam()) {
+      second_profile_name_ = chromeos::ProfileHelper::GetUserProfileDir(
+          kSecondProfileHash).BaseName().value();
+    }
+#endif
 
     base::FilePath second_profile =
         user_data_directory.AppendASCII(second_profile_name_);
@@ -329,6 +351,17 @@
     return true;
   }
 
+#if defined(OS_CHROMEOS)
+  virtual void AddSecondUserAccount() {
+    // Add second user account for multi-profile test.
+    if (GetParam()) {
+      chromeos::UserManager::Get()->UserLoggedIn(kSecondProfileAccount,
+                                                 kSecondProfileHash,
+                                                 false);
+    }
+  }
+#endif
+
  protected:
   std::string first_profile_name_;
   std::string second_profile_name_;
@@ -643,7 +676,7 @@
 }
 #endif
 
-IN_PROC_BROWSER_TEST_F(PerformanceMonitorUncleanExitBrowserTest,
+IN_PROC_BROWSER_TEST_P(PerformanceMonitorUncleanExitBrowserTest,
                        OneProfileUncleanExit) {
   // Initialize the database value (if there's no value in the database, it
   // can't determine the last active time of the profile, and doesn't insert
@@ -666,8 +699,12 @@
   ASSERT_EQ(first_profile_name_, event_profile);
 }
 
-IN_PROC_BROWSER_TEST_F(PerformanceMonitorUncleanExitBrowserTest,
+IN_PROC_BROWSER_TEST_P(PerformanceMonitorUncleanExitBrowserTest,
                        TwoProfileUncleanExit) {
+#if defined(OS_CHROMEOS)
+  AddSecondUserAccount();
+#endif
+
   base::FilePath second_profile_path;
   PathService::Get(chrome::DIR_USER_DATA, &second_profile_path);
   second_profile_path = second_profile_path.AppendASCII(second_profile_name_);
@@ -794,4 +831,8 @@
   EXPECT_GE(metrics[1].value, page1_size + page2_size);
 }
 
+INSTANTIATE_TEST_CASE_P(PerformanceMonitorUncleanExitBrowserTestInstantiation,
+                        PerformanceMonitorUncleanExitBrowserTest,
+                        testing::Bool());
+
 }  // namespace performance_monitor
diff --git a/chrome/browser/plugins/plugin_observer.cc b/chrome/browser/plugins/plugin_observer.cc
index c838046..4312062 100644
--- a/chrome/browser/plugins/plugin_observer.cc
+++ b/chrome/browser/plugins/plugin_observer.cc
@@ -29,7 +29,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/webplugininfo.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
@@ -272,7 +271,7 @@
   // where we have instances on both Ash and Native desktop.
 
   // We will do both tests. Both have some factor of unreliability.
-  aura::Window* window = web_contents()->GetView()->GetNativeView();
+  aura::Window* window = web_contents()->GetNativeView();
   if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH ||
       chrome::GetHostDesktopTypeForNativeView(window) ==
       chrome::HOST_DESKTOP_TYPE_ASH) {
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.cc b/chrome/browser/policy/chrome_browser_policy_connector.cc
index 087adee..ff06118 100644
--- a/chrome/browser/policy/chrome_browser_policy_connector.cc
+++ b/chrome/browser/policy/chrome_browser_policy_connector.cc
@@ -19,7 +19,11 @@
 #include "components/policy/core/common/async_policy_provider.h"
 #include "components/policy/core/common/cloud/device_management_service.h"
 #include "components/policy/core/common/configuration_policy_provider.h"
+#include "components/policy/core/common/policy_map.h"
+#include "components/policy/core/common/policy_namespace.h"
+#include "components/policy/core/common/policy_service.h"
 #include "components/policy/core/common/policy_types.h"
+#include "components/signin/core/common/signin_switches.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "policy/policy_constants.h"
@@ -93,6 +97,8 @@
 
   BrowserPolicyConnector::Init(
       local_state, request_context, device_management_service.Pass());
+
+  AppendExtraFlagPerPolicy();
 }
 
 ConfigurationPolicyProvider*
@@ -126,4 +132,18 @@
 #endif
 }
 
+void ChromeBrowserPolicyConnector::AppendExtraFlagPerPolicy() {
+  PolicyService* policy_service = GetPolicyService();
+  PolicyNamespace chrome_ns = PolicyNamespace(POLICY_DOMAIN_CHROME, "");
+  const PolicyMap& chrome_policy = policy_service->GetPolicies(chrome_ns);
+  const base::Value* policy_value =
+      chrome_policy.GetValue(key::kEnableWebBasedSignin);
+  bool enabled = false;
+  CommandLine* command_line = CommandLine::ForCurrentProcess();
+  if (policy_value && policy_value->GetAsBoolean(&enabled) && enabled &&
+      !command_line->HasSwitch(switches::kEnableWebBasedSignin)) {
+    command_line->AppendSwitch(switches::kEnableWebBasedSignin);
+  }
+}
+
 }  // namespace policy
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.h b/chrome/browser/policy/chrome_browser_policy_connector.h
index 69c21a6..1e772e1 100644
--- a/chrome/browser/policy/chrome_browser_policy_connector.h
+++ b/chrome/browser/policy/chrome_browser_policy_connector.h
@@ -40,6 +40,12 @@
  private:
   ConfigurationPolicyProvider* CreatePlatformProvider();
 
+  // Appends the --enable-web-based-signin flag if the
+  // enable-web-based-signin policy is enabled.
+  // TODO(guohui): Needs to move this to a more proper place and also to handle
+  // dynamic refresh.
+ void AppendExtraFlagPerPolicy();
+
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserPolicyConnector);
 };
 
diff --git a/chrome/browser/policy/cloud/DEPS b/chrome/browser/policy/cloud/DEPS
index 3e754ec..931d987 100644
--- a/chrome/browser/policy/cloud/DEPS
+++ b/chrome/browser/policy/cloud/DEPS
@@ -24,11 +24,10 @@
   r"user_cloud_policy_invalidator|"
   r"user_cloud_policy_invalidator_factory|"
   r"user_cloud_policy_manager_factory|"
-  r"user_policy_signin_service_android|"
   r"user_policy_signin_service_base|"
   r"user_policy_signin_service|"
   r"user_policy_signin_service_factory|"
-  r"user_policy_signin_service_ios|"
+  r"user_policy_signin_service_mobile|"
   r"user_policy_signin_service_unittest)"
   r"\.(cc|h|mm)": [
     "+chrome",
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_android.cc b/chrome/browser/policy/cloud/user_policy_signin_service_android.cc
deleted file mode 100644
index 91e5702..0000000
--- a/chrome/browser/policy/cloud/user_policy_signin_service_android.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/policy/cloud/user_policy_signin_service_android.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/prefs/pref_service.h"
-#include "base/time/time.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
-#include "chrome/common/pref_names.h"
-#include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h"
-#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
-#include "components/policy/core/common/policy_switches.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
-#include "components/signin/core/browser/signin_manager.h"
-#include "net/base/network_change_notifier.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "policy/proto/device_management_backend.pb.h"
-
-namespace policy {
-
-namespace {
-
-enterprise_management::DeviceRegisterRequest::Type GetRegistrationType() {
-  CommandLine* command_line = CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kFakeCloudPolicyType))
-    return enterprise_management::DeviceRegisterRequest::BROWSER;
-  return enterprise_management::DeviceRegisterRequest::ANDROID_BROWSER;
-}
-
-}  // namespace
-
-UserPolicySigninService::UserPolicySigninService(
-    Profile* profile,
-    PrefService* local_state,
-    DeviceManagementService* device_management_service,
-    UserCloudPolicyManager* policy_manager,
-    SigninManager* signin_manager,
-    scoped_refptr<net::URLRequestContextGetter> system_request_context,
-    ProfileOAuth2TokenService* token_service)
-    : UserPolicySigninServiceBase(profile,
-                                  local_state,
-                                  device_management_service,
-                                  policy_manager,
-                                  signin_manager,
-                                  system_request_context),
-      weak_factory_(this),
-      oauth2_token_service_(token_service),
-      profile_prefs_(profile->GetPrefs()) {}
-
-UserPolicySigninService::~UserPolicySigninService() {}
-
-void UserPolicySigninService::RegisterForPolicy(
-    const std::string& username,
-    const PolicyRegistrationCallback& callback) {
-  // Create a new CloudPolicyClient for fetching the DMToken.
-  scoped_ptr<CloudPolicyClient> policy_client = CreateClientForRegistrationOnly(
-      username);
-  if (!policy_client) {
-    callback.Run(std::string(), std::string());
-    return;
-  }
-
-  CancelPendingRegistration();
-
-  // Fire off the registration process. Callback keeps the CloudPolicyClient
-  // alive for the length of the registration process.
-  registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
-      policy_client.get(),
-      GetRegistrationType()));
-  registration_helper_->StartRegistration(
-      oauth2_token_service_,
-      username,
-      base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback,
-                 base::Unretained(this),
-                 base::Passed(&policy_client),
-                 callback));
-}
-
-void UserPolicySigninService::CallPolicyRegistrationCallback(
-    scoped_ptr<CloudPolicyClient> client,
-    PolicyRegistrationCallback callback) {
-  registration_helper_.reset();
-  callback.Run(client->dm_token(), client->client_id());
-}
-
-void UserPolicySigninService::Shutdown() {
-  CancelPendingRegistration();
-  registration_helper_.reset();
-  UserPolicySigninServiceBase::Shutdown();
-}
-
-void UserPolicySigninService::OnInitializationCompleted(
-    CloudPolicyService* service) {
-  UserCloudPolicyManager* manager = policy_manager();
-  DCHECK_EQ(service, manager->core()->service());
-  DCHECK(service->IsInitializationComplete());
-  // The service is now initialized - if the client is not yet registered, then
-  // it means that there is no cached policy and so we need to initiate a new
-  // client registration.
-  if (manager->IsClientRegistered()) {
-    DVLOG(1) << "Client already registered - not fetching DMToken";
-    return;
-  }
-
-  net::NetworkChangeNotifier::ConnectionType connection_type =
-      net::NetworkChangeNotifier::GetConnectionType();
-  base::TimeDelta retry_delay = base::TimeDelta::FromDays(3);
-  if (connection_type == net::NetworkChangeNotifier::CONNECTION_ETHERNET ||
-      connection_type == net::NetworkChangeNotifier::CONNECTION_WIFI) {
-    retry_delay = base::TimeDelta::FromDays(1);
-  }
-
-  base::Time last_check_time = base::Time::FromInternalValue(
-      profile_prefs_->GetInt64(prefs::kLastPolicyCheckTime));
-  base::Time now = base::Time::Now();
-  base::Time next_check_time = last_check_time + retry_delay;
-
-  // Check immediately if no check was ever done before (last_check_time == 0),
-  // or if the last check was in the future (?), or if we're already past the
-  // next check time. Otherwise, delay checking until the next check time.
-  base::TimeDelta try_registration_delay = base::TimeDelta::FromSeconds(5);
-  if (now > last_check_time && now < next_check_time)
-    try_registration_delay = next_check_time - now;
-
-  base::MessageLoop::current()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&UserPolicySigninService::RegisterCloudPolicyService,
-                 weak_factory_.GetWeakPtr()),
-      try_registration_delay);
-}
-
-void UserPolicySigninService::RegisterCloudPolicyService() {
-  // If the user signed-out while this task was waiting then Shutdown() would
-  // have been called, which would have invalidated this task. Since we're here
-  // then the user must still be signed-in.
-  const std::string& username = signin_manager()->GetAuthenticatedUsername();
-  DCHECK(!username.empty());
-  DCHECK(!policy_manager()->IsClientRegistered());
-  DCHECK(policy_manager()->core()->client());
-
-  // Persist the current time as the last policy registration attempt time.
-  profile_prefs_->SetInt64(prefs::kLastPolicyCheckTime,
-                           base::Time::Now().ToInternalValue());
-
-  registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
-      policy_manager()->core()->client(),
-      GetRegistrationType()));
-  registration_helper_->StartRegistration(
-      oauth2_token_service_,
-      username,
-      base::Bind(&UserPolicySigninService::OnRegistrationDone,
-                 base::Unretained(this)));
-}
-
-void UserPolicySigninService::CancelPendingRegistration() {
-  weak_factory_.InvalidateWeakPtrs();
-}
-
-void UserPolicySigninService::OnRegistrationDone() {
-  registration_helper_.reset();
-}
-
-}  // namespace policy
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_android.h b/chrome/browser/policy/cloud/user_policy_signin_service_android.h
deleted file mode 100644
index 7242f1b..0000000
--- a/chrome/browser/policy/cloud/user_policy_signin_service_android.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_ANDROID_H_
-#define CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_ANDROID_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/policy/cloud/user_policy_signin_service_base.h"
-
-class ProfileOAuth2TokenService;
-class Profile;
-
-namespace net {
-class URLRequestContextGetter;
-}
-
-namespace policy {
-
-class CloudPolicyClientRegistrationHelper;
-
-// A specialization of the UserPolicySigninServiceBase for Android.
-class UserPolicySigninService : public UserPolicySigninServiceBase {
- public:
-  // Creates a UserPolicySigninService associated with the passed |profile|.
-  UserPolicySigninService(
-      Profile* profile,
-      PrefService* local_state,
-      DeviceManagementService* device_management_service,
-      UserCloudPolicyManager* policy_manager,
-      SigninManager* signin_manager,
-      scoped_refptr<net::URLRequestContextGetter> system_request_context,
-      ProfileOAuth2TokenService* token_service);
-  virtual ~UserPolicySigninService();
-
-  // Registers a CloudPolicyClient for fetching policy for |username|.
-  // This requests an OAuth2 token for the services involved, and contacts
-  // the policy service if the account has management enabled.
-  // |callback| is invoked once we have registered this device to fetch policy,
-  // or once it is determined that |username| is not a managed account.
-  void RegisterForPolicy(const std::string& username,
-                         const PolicyRegistrationCallback& callback);
-
- private:
-  void CallPolicyRegistrationCallback(scoped_ptr<CloudPolicyClient> client,
-                                      PolicyRegistrationCallback callback);
-
-  // KeyedService implementation:
-  virtual void Shutdown() OVERRIDE;
-
-  // CloudPolicyService::Observer implementation:
-  virtual void OnInitializationCompleted(CloudPolicyService* service) OVERRIDE;
-
-  // Registers for cloud policy for an already signed-in user.
-  void RegisterCloudPolicyService();
-
-  // Cancels a pending cloud policy registration attempt.
-  void CancelPendingRegistration();
-
-  void OnRegistrationDone();
-
-  scoped_ptr<CloudPolicyClientRegistrationHelper> registration_helper_;
-  base::WeakPtrFactory<UserPolicySigninService> weak_factory_;
-
-  // Weak pointer to the token service used to authenticate the
-  // CloudPolicyClient during registration.
-  ProfileOAuth2TokenService* oauth2_token_service_;
-
-  // The PrefService associated with the profile.
-  PrefService* profile_prefs_;
-
-  DISALLOW_COPY_AND_ASSIGN(UserPolicySigninService);
-};
-
-}  // namespace policy
-
-#endif  // CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_ANDROID_H_
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc b/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc
index 337ada1..f4af06f 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc
@@ -17,10 +17,8 @@
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "net/url_request/url_request_context_getter.h"
 
-#if defined(OS_ANDROID)
-#include "chrome/browser/policy/cloud/user_policy_signin_service_android.h"
-#elif defined(OS_IOS)
-#include "chrome/browser/policy/cloud/user_policy_signin_service_ios.h"
+#if defined(OS_ANDROID) || defined(OS_IOS)
+#include "chrome/browser/policy/cloud/user_policy_signin_service_mobile.h"
 #else
 #include "chrome/browser/policy/cloud/user_policy_signin_service.h"
 #endif
@@ -99,7 +97,7 @@
 
 void UserPolicySigninServiceFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* user_prefs) {
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_IOS)
   user_prefs->RegisterInt64Pref(
       prefs::kLastPolicyCheckTime,
       0,
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_ios.h b/chrome/browser/policy/cloud/user_policy_signin_service_ios.h
deleted file mode 100644
index 41305e5..0000000
--- a/chrome/browser/policy/cloud/user_policy_signin_service_ios.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_IOS_H_
-#define CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_IOS_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/policy/cloud/user_policy_signin_service_base.h"
-
-class ProfileOAuth2TokenService;
-class Profile;
-
-namespace net {
-class URLRequestContextGetter;
-}
-
-namespace policy {
-
-class CloudPolicyClientRegistrationHelper;
-
-typedef void (^PolicyRegistrationBlockCallback)(const std::string& dm_token,
-                                                const std::string& client_id);
-
-typedef void (^PolicyFetchBlockCallback)(bool succeeded);
-
-// A specialization of the UserPolicySigninServiceBase for iOS.
-// TODO(joaodasilva): share more code with UserPolicySigninServiceBase and
-// the Android implementation. http://crbug.com/273055
-class UserPolicySigninService : public UserPolicySigninServiceBase {
- public:
-  // Creates a UserPolicySigninService associated with the passed |profile|.
-  UserPolicySigninService(
-      Profile* profile,
-      PrefService* local_state,
-      DeviceManagementService* device_management_service,
-      UserCloudPolicyManager* policy_manager,
-      SigninManager* signin_manager,
-      scoped_refptr<net::URLRequestContextGetter> system_request_context,
-      ProfileOAuth2TokenService* token_service);
-  virtual ~UserPolicySigninService();
-
-  // Registers a CloudPolicyClient for fetching policy for |username|.
-  // This requires a valid OAuth access token for the scopes returned by the
-  // |GetScopes| static function. |callback| is invoked once we have
-  // registered this device to fetch policy, or once it is determined that
-  // |username| is not a managed account.
-  void RegisterForPolicy(const std::string& username,
-                         const std::string& access_token,
-                         PolicyRegistrationBlockCallback callback);
-
-  static std::vector<std::string> GetScopes();
-
-  // Wrapper for FetchPolicyForSignedInUser that uses a block instead of
-  // a base::Callback.
-  void FetchPolicy(
-      const std::string& username,
-      const std::string& dm_token,
-      const std::string& client_id,
-      scoped_refptr<net::URLRequestContextGetter> profile_request_context,
-      PolicyFetchBlockCallback callback);
-
- private:
-  void CallPolicyRegistrationCallback(scoped_ptr<CloudPolicyClient> client,
-                                      PolicyRegistrationBlockCallback callback);
-
-  void CallPolicyFetchCallback(PolicyFetchBlockCallback callback,
-                               bool succeeded);
-
-  // KeyedService implementation:
-  virtual void Shutdown() OVERRIDE;
-
-  // CloudPolicyService::Observer implementation:
-  virtual void OnInitializationCompleted(CloudPolicyService* service) OVERRIDE;
-
-  // Cancels a pending cloud policy registration attempt.
-  void CancelPendingRegistration();
-
-  scoped_ptr<CloudPolicyClientRegistrationHelper> registration_helper_;
-  base::WeakPtrFactory<UserPolicySigninService> weak_factory_;
-
-  // The PrefService associated with the profile.
-  PrefService* profile_prefs_;
-
-  DISALLOW_COPY_AND_ASSIGN(UserPolicySigninService);
-};
-
-}  // namespace policy
-
-#endif  // CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_IOS_H_
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_ios.mm b/chrome/browser/policy/cloud/user_policy_signin_service_ios.mm
deleted file mode 100644
index 98c0f36..0000000
--- a/chrome/browser/policy/cloud/user_policy_signin_service_ios.mm
+++ /dev/null
@@ -1,140 +0,0 @@
-// 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.
-
-#include "chrome/browser/policy/cloud/user_policy_signin_service_ios.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/prefs/pref_service.h"
-#include "base/time/time.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/common/pref_names.h"
-#include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h"
-#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
-#include "components/policy/core/common/policy_switches.h"
-#include "components/signin/core/browser/signin_manager.h"
-#include "net/base/network_change_notifier.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "policy/proto/device_management_backend.pb.h"
-
-namespace policy {
-
-namespace {
-
-enterprise_management::DeviceRegisterRequest::Type GetRegistrationType() {
-  CommandLine* command_line = CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kFakeCloudPolicyType))
-    return enterprise_management::DeviceRegisterRequest::BROWSER;
-  return enterprise_management::DeviceRegisterRequest::IOS_BROWSER;
-}
-
-}  // namespace
-
-UserPolicySigninService::UserPolicySigninService(
-    Profile* profile,
-    PrefService* local_state,
-    DeviceManagementService* device_management_service,
-    UserCloudPolicyManager* policy_manager,
-    SigninManager* signin_manager,
-    scoped_refptr<net::URLRequestContextGetter> system_request_context,
-    ProfileOAuth2TokenService* token_service)
-    : UserPolicySigninServiceBase(profile,
-                                  local_state,
-                                  device_management_service,
-                                  policy_manager,
-                                  signin_manager,
-                                  system_request_context),
-      weak_factory_(this),
-      profile_prefs_(profile->GetPrefs()) {}
-
-UserPolicySigninService::~UserPolicySigninService() {}
-
-void UserPolicySigninService::RegisterForPolicy(
-    const std::string& username,
-    const std::string& access_token,
-    PolicyRegistrationBlockCallback callback) {
-  // Create a new CloudPolicyClient for fetching the DMToken.
-  scoped_ptr<CloudPolicyClient> policy_client = CreateClientForRegistrationOnly(
-      username);
-  if (!policy_client) {
-    callback(std::string(), std::string());
-    return;
-  }
-
-  CancelPendingRegistration();
-
-  // Fire off the registration process. Callback keeps the CloudPolicyClient
-  // alive for the length of the registration process.
-  registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
-      policy_client.get(),
-      GetRegistrationType()));
-      registration_helper_->StartRegistrationWithAccessToken(
-          access_token,
-          base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback,
-                     base::Unretained(this),
-                     base::Passed(&policy_client),
-                     [callback copy]));
-}
-
-// static
-std::vector<std::string> UserPolicySigninService::GetScopes() {
-  return CloudPolicyClientRegistrationHelper::GetScopes();
-}
-
-void UserPolicySigninService::FetchPolicy(
-    const std::string& username,
-    const std::string& dm_token,
-    const std::string& client_id,
-    scoped_refptr<net::URLRequestContextGetter> profile_request_context,
-    PolicyFetchBlockCallback callback) {
-  FetchPolicyForSignedInUser(
-      username,
-      dm_token,
-      client_id,
-      profile_request_context,
-      base::Bind(&UserPolicySigninService::CallPolicyFetchCallback,
-                 base::Unretained(this),
-                 [callback copy]));
-}
-
-void UserPolicySigninService::CallPolicyRegistrationCallback(
-    scoped_ptr<CloudPolicyClient> client,
-    PolicyRegistrationBlockCallback callback) {
-  registration_helper_.reset();
-  callback(client->dm_token(), client->client_id());
-  [callback release];
-}
-
-void UserPolicySigninService::CallPolicyFetchCallback(
-    PolicyFetchBlockCallback callback,
-    bool succeeded) {
-  callback(succeeded);
-  [callback release];
-}
-
-void UserPolicySigninService::Shutdown() {
-  CancelPendingRegistration();
-  registration_helper_.reset();
-  UserPolicySigninServiceBase::Shutdown();
-}
-
-void UserPolicySigninService::OnInitializationCompleted(
-    CloudPolicyService* service) {
-  UserCloudPolicyManager* manager = policy_manager();
-  DCHECK_EQ(service, manager->core()->service());
-  DCHECK(service->IsInitializationComplete());
-  // Note: we don't register the cloud policy client on iOS if it's not
-  // registered at this stage. If there was no policy at sign-in time then
-  // there won't be policy later either.
-}
-
-void UserPolicySigninService::CancelPendingRegistration() {
-  weak_factory_.InvalidateWeakPtrs();
-}
-
-}  // namespace policy
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_mobile.cc b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.cc
new file mode 100644
index 0000000..7f17fc1
--- /dev/null
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.cc
@@ -0,0 +1,223 @@
+// 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.
+
+#include "chrome/browser/policy/cloud/user_policy_signin_service_mobile.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "base/prefs/pref_service.h"
+#include "base/time/time.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/common/pref_names.h"
+#include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h"
+#include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
+#include "components/policy/core/common/policy_switches.h"
+#include "components/signin/core/browser/profile_oauth2_token_service.h"
+#include "components/signin/core/browser/signin_manager.h"
+#include "net/base/network_change_notifier.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "policy/proto/device_management_backend.pb.h"
+
+namespace policy {
+
+namespace {
+
+enterprise_management::DeviceRegisterRequest::Type GetRegistrationType() {
+  CommandLine* command_line = CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kFakeCloudPolicyType))
+    return enterprise_management::DeviceRegisterRequest::BROWSER;
+#if defined(OS_IOS)
+  return enterprise_management::DeviceRegisterRequest::IOS_BROWSER;
+#elif defined(OS_ANDROID)
+  return enterprise_management::DeviceRegisterRequest::ANDROID_BROWSER;
+#else
+#error "This file can be built only on OS_IOS or OS_ANDROID."
+#endif
+}
+
+}  // namespace
+
+UserPolicySigninService::UserPolicySigninService(
+    Profile* profile,
+    PrefService* local_state,
+    DeviceManagementService* device_management_service,
+    UserCloudPolicyManager* policy_manager,
+    SigninManager* signin_manager,
+    scoped_refptr<net::URLRequestContextGetter> system_request_context,
+    ProfileOAuth2TokenService* token_service)
+    : UserPolicySigninServiceBase(profile,
+                                  local_state,
+                                  device_management_service,
+                                  policy_manager,
+                                  signin_manager,
+                                  system_request_context),
+      weak_factory_(this),
+      oauth2_token_service_(token_service),
+      profile_prefs_(profile->GetPrefs()) {
+#if defined(OS_IOS)
+  // iOS doesn't create this service with the Profile; instead it's created
+  // a little bit later. See UserPolicySigninServiceFactory.
+  InitializeOnProfileReady(profile);
+#endif
+}
+
+UserPolicySigninService::~UserPolicySigninService() {}
+
+void UserPolicySigninService::RegisterForPolicy(
+    const std::string& username,
+    const PolicyRegistrationCallback& callback) {
+  RegisterForPolicyInternal(username, "", callback);
+}
+
+#if !defined(OS_ANDROID)
+void UserPolicySigninService::RegisterForPolicyWithAccessToken(
+    const std::string& username,
+    const std::string& access_token,
+    const PolicyRegistrationCallback& callback) {
+  RegisterForPolicyInternal(username, access_token, callback);
+}
+
+// static
+std::vector<std::string> UserPolicySigninService::GetScopes() {
+  return CloudPolicyClientRegistrationHelper::GetScopes();
+}
+#endif
+
+void UserPolicySigninService::RegisterForPolicyInternal(
+    const std::string& username,
+    const std::string& access_token,
+    const PolicyRegistrationCallback& callback) {
+  // Create a new CloudPolicyClient for fetching the DMToken.
+  scoped_ptr<CloudPolicyClient> policy_client = CreateClientForRegistrationOnly(
+      username);
+  if (!policy_client) {
+    callback.Run(std::string(), std::string());
+    return;
+  }
+
+  CancelPendingRegistration();
+
+  // Fire off the registration process. Callback keeps the CloudPolicyClient
+  // alive for the length of the registration process.
+  registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
+      policy_client.get(),
+      GetRegistrationType()));
+
+  if (access_token.empty()) {
+    registration_helper_->StartRegistration(
+        oauth2_token_service_,
+        username,
+        base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback,
+                   base::Unretained(this),
+                   base::Passed(&policy_client),
+                   callback));
+  } else {
+#if defined(OS_ANDROID)
+    NOTREACHED();
+#else
+    registration_helper_->StartRegistrationWithAccessToken(
+        access_token,
+        base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback,
+                   base::Unretained(this),
+                   base::Passed(&policy_client),
+                   callback));
+#endif
+  }
+}
+
+void UserPolicySigninService::CallPolicyRegistrationCallback(
+    scoped_ptr<CloudPolicyClient> client,
+    PolicyRegistrationCallback callback) {
+  registration_helper_.reset();
+  callback.Run(client->dm_token(), client->client_id());
+}
+
+void UserPolicySigninService::Shutdown() {
+  CancelPendingRegistration();
+  registration_helper_.reset();
+  UserPolicySigninServiceBase::Shutdown();
+}
+
+void UserPolicySigninService::OnInitializationCompleted(
+    CloudPolicyService* service) {
+  UserCloudPolicyManager* manager = policy_manager();
+  DCHECK_EQ(service, manager->core()->service());
+  DCHECK(service->IsInitializationComplete());
+  // The service is now initialized - if the client is not yet registered, then
+  // it means that there is no cached policy and so we need to initiate a new
+  // client registration.
+  if (manager->IsClientRegistered()) {
+    DVLOG(1) << "Client already registered - not fetching DMToken";
+    return;
+  }
+
+  net::NetworkChangeNotifier::ConnectionType connection_type =
+      net::NetworkChangeNotifier::GetConnectionType();
+  base::TimeDelta retry_delay = base::TimeDelta::FromDays(3);
+  if (connection_type == net::NetworkChangeNotifier::CONNECTION_ETHERNET ||
+      connection_type == net::NetworkChangeNotifier::CONNECTION_WIFI) {
+    retry_delay = base::TimeDelta::FromDays(1);
+  }
+
+  base::Time last_check_time = base::Time::FromInternalValue(
+      profile_prefs_->GetInt64(prefs::kLastPolicyCheckTime));
+  base::Time now = base::Time::Now();
+  base::Time next_check_time = last_check_time + retry_delay;
+
+  // Check immediately if no check was ever done before (last_check_time == 0),
+  // or if the last check was in the future (?), or if we're already past the
+  // next check time. Otherwise, delay checking until the next check time.
+  base::TimeDelta try_registration_delay = base::TimeDelta::FromSeconds(5);
+  if (now > last_check_time && now < next_check_time)
+    try_registration_delay = next_check_time - now;
+
+  base::MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&UserPolicySigninService::RegisterCloudPolicyService,
+                 weak_factory_.GetWeakPtr()),
+      try_registration_delay);
+}
+
+void UserPolicySigninService::ShutdownUserCloudPolicyManager() {
+  CancelPendingRegistration();
+  UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager();
+}
+
+void UserPolicySigninService::RegisterCloudPolicyService() {
+  // If the user signed-out while this task was waiting then Shutdown() would
+  // have been called, which would have invalidated this task. Since we're here
+  // then the user must still be signed-in.
+  const std::string& username = signin_manager()->GetAuthenticatedUsername();
+  DCHECK(!username.empty());
+  DCHECK(!policy_manager()->IsClientRegistered());
+  DCHECK(policy_manager()->core()->client());
+
+  // Persist the current time as the last policy registration attempt time.
+  profile_prefs_->SetInt64(prefs::kLastPolicyCheckTime,
+                           base::Time::Now().ToInternalValue());
+
+  registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
+      policy_manager()->core()->client(),
+      GetRegistrationType()));
+  registration_helper_->StartRegistration(
+      oauth2_token_service_,
+      username,
+      base::Bind(&UserPolicySigninService::OnRegistrationDone,
+                 base::Unretained(this)));
+}
+
+void UserPolicySigninService::CancelPendingRegistration() {
+  weak_factory_.InvalidateWeakPtrs();
+}
+
+void UserPolicySigninService::OnRegistrationDone() {
+  registration_helper_.reset();
+}
+
+}  // namespace policy
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_mobile.h b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.h
new file mode 100644
index 0000000..7fc5ba6
--- /dev/null
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.h
@@ -0,0 +1,109 @@
+// 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.
+
+#ifndef CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_MOBILE_H_
+#define CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_MOBILE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/policy/cloud/user_policy_signin_service_base.h"
+
+class ProfileOAuth2TokenService;
+class Profile;
+
+namespace net {
+class URLRequestContextGetter;
+}
+
+namespace policy {
+
+class CloudPolicyClientRegistrationHelper;
+
+// A specialization of the UserPolicySigninServiceBase for the mobile platforms
+// (currently Android and iOS).
+class UserPolicySigninService : public UserPolicySigninServiceBase {
+ public:
+  // Creates a UserPolicySigninService associated with the passed |profile|.
+  UserPolicySigninService(
+      Profile* profile,
+      PrefService* local_state,
+      DeviceManagementService* device_management_service,
+      UserCloudPolicyManager* policy_manager,
+      SigninManager* signin_manager,
+      scoped_refptr<net::URLRequestContextGetter> system_request_context,
+      ProfileOAuth2TokenService* token_service);
+  virtual ~UserPolicySigninService();
+
+  // Registers a CloudPolicyClient for fetching policy for |username|.
+  // This requests an OAuth2 token for the services involved, and contacts
+  // the policy service if the account has management enabled.
+  // |callback| is invoked once we have registered this device to fetch policy,
+  // or once it is determined that |username| is not a managed account.
+  void RegisterForPolicy(const std::string& username,
+                         const PolicyRegistrationCallback& callback);
+
+#if !defined(OS_ANDROID)
+  // Registers a CloudPolicyClient for fetching policy for |username|.
+  // This requires a valid OAuth access token for the scopes returned by the
+  // |GetScopes| static function. |callback| is invoked once we have
+  // registered this device to fetch policy, or once it is determined that
+  // |username| is not a managed account.
+  void RegisterForPolicyWithAccessToken(
+      const std::string& username,
+      const std::string& access_token,
+      const PolicyRegistrationCallback& callback);
+
+  // Returns the list of OAuth access scopes required for policy fetching.
+  static std::vector<std::string> GetScopes();
+#endif
+
+ private:
+  void RegisterForPolicyInternal(
+      const std::string& username,
+      const std::string& access_token,
+      const PolicyRegistrationCallback& callback);
+
+  void CallPolicyRegistrationCallback(scoped_ptr<CloudPolicyClient> client,
+                                      PolicyRegistrationCallback callback);
+
+  // KeyedService implementation:
+  virtual void Shutdown() OVERRIDE;
+
+  // CloudPolicyService::Observer implementation:
+  virtual void OnInitializationCompleted(CloudPolicyService* service) OVERRIDE;
+
+  // Overridden from UserPolicySigninServiceBase to cancel the pending delayed
+  // registration.
+  virtual void ShutdownUserCloudPolicyManager() OVERRIDE;
+
+  // Registers for cloud policy for an already signed-in user.
+  void RegisterCloudPolicyService();
+
+  // Cancels a pending cloud policy registration attempt.
+  void CancelPendingRegistration();
+
+  void OnRegistrationDone();
+
+  scoped_ptr<CloudPolicyClientRegistrationHelper> registration_helper_;
+  base::WeakPtrFactory<UserPolicySigninService> weak_factory_;
+
+  // Weak pointer to the token service used to authenticate the
+  // CloudPolicyClient during registration.
+  ProfileOAuth2TokenService* oauth2_token_service_;
+
+  // The PrefService associated with the profile.
+  PrefService* profile_prefs_;
+
+  DISALLOW_COPY_AND_ASSIGN(UserPolicySigninService);
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_MOBILE_H_
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
index c80c62e..5a9d019 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
@@ -47,7 +47,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if defined(OS_ANDROID)
-#include "chrome/browser/policy/cloud/user_policy_signin_service_android.h"
+#include "chrome/browser/policy/cloud/user_policy_signin_service_mobile.h"
 #else
 #include "chrome/browser/policy/cloud/user_policy_signin_service.h"
 #endif
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 53bbac9..fca167e 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -497,8 +497,7 @@
   void Wait();
 
   // Overridden WebContentsObserver methods.
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
   virtual void DidStopLoading(
       content::RenderViewHost* render_view_host) OVERRIDE;
 
@@ -520,8 +519,7 @@
   message_loop_runner_->Run();
 }
 
-void WebContentsLoadedOrDestroyedWatcher::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void WebContentsLoadedOrDestroyedWatcher::WebContentsDestroyed() {
   message_loop_runner_->Quit();
 }
 
@@ -540,8 +538,6 @@
 
   // apps::AppWindowRegistry::Observer:
   virtual void OnAppWindowAdded(apps::AppWindow* app_window) OVERRIDE;
-  virtual void OnAppWindowIconChanged(apps::AppWindow* app_window) OVERRIDE;
-  virtual void OnAppWindowRemoved(apps::AppWindow* app_window) OVERRIDE;
 
   apps::AppWindow* WaitForAppWindow();
 
@@ -568,12 +564,6 @@
   run_loop_.Quit();
 }
 
-void TestAddAppWindowObserver::OnAppWindowIconChanged(
-    apps::AppWindow* app_window) {}
-
-void TestAddAppWindowObserver::OnAppWindowRemoved(apps::AppWindow* app_window) {
-}
-
 apps::AppWindow* TestAddAppWindowObserver::WaitForAppWindow() {
   run_loop_.Run();
   return window_;
diff --git a/chrome/browser/policy/policy_prefs_browsertest.cc b/chrome/browser/policy/policy_prefs_browsertest.cc
index 2d86b96..4becba9 100644
--- a/chrome/browser/policy/policy_prefs_browsertest.cc
+++ b/chrome/browser/policy/policy_prefs_browsertest.cc
@@ -55,6 +55,13 @@
 
 const char kCrosSettingsPrefix[] = "cros.";
 
+std::string GetPolicyName(const std::string& policy_name_decorated) {
+  const size_t offset = policy_name_decorated.find('.');
+  if (offset != std::string::npos)
+    return policy_name_decorated.substr(0, offset);
+  return policy_name_decorated;
+}
+
 // Contains the details of a single test case verifying that the controlled
 // setting indicators for a pref affected by a policy work correctly. This is
 // part of the data loaded from chrome/test/data/policy/policy_test_cases.json.
@@ -208,7 +215,8 @@
 // Parses all policy test cases and makes then available in a map.
 class PolicyTestCases {
  public:
-  typedef std::map<std::string, PolicyTestCase*> PolicyTestCaseMap;
+  typedef std::vector<PolicyTestCase*> PolicyTestCaseVector;
+  typedef std::map<std::string, PolicyTestCaseVector> PolicyTestCaseMap;
   typedef PolicyTestCaseMap::const_iterator iterator;
 
   PolicyTestCases() {
@@ -234,21 +242,33 @@
       ADD_FAILURE();
       return;
     }
-    for (Schema::Iterator it = chrome_schema.GetPropertiesIterator();
-         !it.IsAtEnd(); it.Advance()) {
+    for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
+         it.Advance()) {
+      const std::string policy_name = GetPolicyName(it.key());
+      if (!chrome_schema.GetKnownProperty(policy_name).valid())
+        continue;
       PolicyTestCase* policy_test_case = GetPolicyTestCase(dict, it.key());
       if (policy_test_case)
-        policy_test_cases_[it.key()] = policy_test_case;
+        policy_test_cases_[policy_name].push_back(policy_test_case);
     }
   }
 
   ~PolicyTestCases() {
-    STLDeleteValues(&policy_test_cases_);
+    for (iterator policy = policy_test_cases_.begin();
+         policy != policy_test_cases_.end();
+         ++policy) {
+      for (PolicyTestCaseVector::const_iterator test_case =
+               policy->second.begin();
+           test_case != policy->second.end();
+           ++test_case) {
+        delete *test_case;
+      }
+    }
   }
 
-  const PolicyTestCase* Get(const std::string& name) const {
+  const PolicyTestCaseVector* Get(const std::string& name) const {
     const iterator it = policy_test_cases_.find(name);
-    return it == end() ? NULL : it->second;
+    return it == end() ? NULL : &it->second;
   }
 
   const PolicyTestCaseMap& map() const { return policy_test_cases_; }
@@ -259,7 +279,7 @@
   PolicyTestCase* GetPolicyTestCase(const base::DictionaryValue* tests,
                                     const std::string& name) {
     const base::DictionaryValue* policy_test_dict = NULL;
-    if (!tests->GetDictionary(name, &policy_test_dict))
+    if (!tests->GetDictionaryWithoutPathExpansion(name, &policy_test_dict))
       return NULL;
     bool is_official_only = false;
     policy_test_dict->GetBoolean("official_only", &is_official_only);
@@ -521,49 +541,55 @@
   PrefService* user_prefs = browser()->profile()->GetPrefs();
 
   const PolicyTestCases test_cases;
-  for (PolicyTestCases::iterator it = test_cases.begin();
-       it != test_cases.end(); ++it) {
-    const ScopedVector<PrefMapping>& pref_mappings =
-        it->second->pref_mappings();
-    if (!it->second->IsSupported() || pref_mappings.empty())
-      continue;
-
-    LOG(INFO) << "Testing policy: " << it->first;
-
-    for (ScopedVector<PrefMapping>::const_iterator
-             pref_mapping = pref_mappings.begin();
-         pref_mapping != pref_mappings.end();
-         ++pref_mapping) {
-      // Skip Chrome OS preferences that use a different backend and cannot be
-      // retrieved through the prefs mechanism.
-      if (StartsWithASCII((*pref_mapping)->pref(), kCrosSettingsPrefix, true))
+  for (PolicyTestCases::iterator policy = test_cases.begin();
+       policy != test_cases.end();
+       ++policy) {
+    for (PolicyTestCases::PolicyTestCaseVector::const_iterator test_case =
+             policy->second.begin();
+         test_case != policy->second.end();
+         ++test_case) {
+      const ScopedVector<PrefMapping>& pref_mappings =
+          (*test_case)->pref_mappings();
+      if (!(*test_case)->IsSupported() || pref_mappings.empty())
         continue;
 
-      // Skip preferences that should not be checked when the policy is set to
-      // a mandatory value.
-      if (!(*pref_mapping)->check_for_mandatory())
-        continue;
+      LOG(INFO) << "Testing policy: " << policy->first;
 
-      PrefService* prefs = (*pref_mapping)->is_local_state() ?
-          local_state : user_prefs;
-      // The preference must have been registered.
-      const PrefService::Preference* pref =
-          prefs->FindPreference((*pref_mapping)->pref().c_str());
-      ASSERT_TRUE(pref);
+      for (ScopedVector<PrefMapping>::const_iterator pref_mapping =
+               pref_mappings.begin();
+           pref_mapping != pref_mappings.end();
+           ++pref_mapping) {
+        // Skip Chrome OS preferences that use a different backend and cannot be
+        // retrieved through the prefs mechanism.
+        if (StartsWithASCII((*pref_mapping)->pref(), kCrosSettingsPrefix, true))
+          continue;
 
-      // Verify that setting the policy overrides the pref.
-      ClearProviderPolicy();
-      prefs->ClearPref((*pref_mapping)->pref().c_str());
-      EXPECT_TRUE(pref->IsDefaultValue());
-      EXPECT_TRUE(pref->IsUserModifiable());
-      EXPECT_FALSE(pref->IsUserControlled());
-      EXPECT_FALSE(pref->IsManaged());
+        // Skip preferences that should not be checked when the policy is set to
+        // a mandatory value.
+        if (!(*pref_mapping)->check_for_mandatory())
+          continue;
 
-      SetProviderPolicy(it->second->test_policy(), POLICY_LEVEL_MANDATORY);
-      EXPECT_FALSE(pref->IsDefaultValue());
-      EXPECT_FALSE(pref->IsUserModifiable());
-      EXPECT_FALSE(pref->IsUserControlled());
-      EXPECT_TRUE(pref->IsManaged());
+        PrefService* prefs =
+            (*pref_mapping)->is_local_state() ? local_state : user_prefs;
+        // The preference must have been registered.
+        const PrefService::Preference* pref =
+            prefs->FindPreference((*pref_mapping)->pref().c_str());
+        ASSERT_TRUE(pref);
+
+        // Verify that setting the policy overrides the pref.
+        ClearProviderPolicy();
+        prefs->ClearPref((*pref_mapping)->pref().c_str());
+        EXPECT_TRUE(pref->IsDefaultValue());
+        EXPECT_TRUE(pref->IsUserModifiable());
+        EXPECT_FALSE(pref->IsUserControlled());
+        EXPECT_FALSE(pref->IsManaged());
+
+        SetProviderPolicy((*test_case)->test_policy(), POLICY_LEVEL_MANDATORY);
+        EXPECT_FALSE(pref->IsDefaultValue());
+        EXPECT_FALSE(pref->IsUserModifiable());
+        EXPECT_FALSE(pref->IsUserControlled());
+        EXPECT_TRUE(pref->IsManaged());
+      }
     }
   }
 }
@@ -582,122 +608,139 @@
 
   ui_test_utils::NavigateToURL(browser(), GURL(kMainSettingsPage));
 
-  for (std::vector<std::string>::const_iterator it = GetParam().begin();
-       it != GetParam().end(); ++it) {
-    const PolicyTestCase* policy_test_case = test_cases.Get(*it);
-    ASSERT_TRUE(policy_test_case) << "PolicyTestCase not found for " << *it;
-    if (!policy_test_case->IsSupported())
-      continue;
-    const ScopedVector<PrefMapping>& pref_mappings =
-        policy_test_case->pref_mappings();
-    if (policy_test_case->indicator_selector().empty()) {
-      bool has_pref_indicator_tests = false;
-      for (ScopedVector<PrefMapping>::const_iterator
-               pref_mapping = pref_mappings.begin();
-           pref_mapping != pref_mappings.end();
-           ++pref_mapping) {
-        if (!(*pref_mapping)->indicator_test_cases().empty()) {
-          has_pref_indicator_tests = true;
-          break;
+  for (std::vector<std::string>::const_iterator policy = GetParam().begin();
+       policy != GetParam().end();
+       ++policy) {
+    const std::vector<PolicyTestCase*>* policy_test_cases =
+        test_cases.Get(*policy);
+    ASSERT_TRUE(policy_test_cases) << "PolicyTestCase not found for "
+                                   << *policy;
+    for (std::vector<PolicyTestCase*>::const_iterator test_case =
+             policy_test_cases->begin();
+         test_case != policy_test_cases->end();
+         ++test_case) {
+      PolicyTestCase* policy_test_case = *test_case;
+      if (!policy_test_case->IsSupported())
+        continue;
+      const ScopedVector<PrefMapping>& pref_mappings =
+          policy_test_case->pref_mappings();
+      if (policy_test_case->indicator_selector().empty()) {
+        bool has_pref_indicator_tests = false;
+        for (ScopedVector<PrefMapping>::const_iterator pref_mapping =
+                 pref_mappings.begin();
+             pref_mapping != pref_mappings.end();
+             ++pref_mapping) {
+          if (!(*pref_mapping)->indicator_test_cases().empty()) {
+            has_pref_indicator_tests = true;
+            break;
+          }
         }
-      }
-      if (!has_pref_indicator_tests)
-        continue;
-    }
-
-    LOG(INFO) << "Testing policy: " << *it;
-
-    if (!policy_test_case->indicator_selector().empty()) {
-      // Check that no controlled setting indicator is visible when no value is
-      // set by policy.
-      ClearProviderPolicy();
-      VerifyControlledSettingIndicators(browser(),
-                                        policy_test_case->indicator_selector(),
-                                        std::string(),
-                                        std::string(),
-                                        false);
-      // Check that the appropriate controlled setting indicator is shown when a
-      // value is enforced by policy.
-      SetProviderPolicy(policy_test_case->test_policy(),
-                        POLICY_LEVEL_MANDATORY);
-      VerifyControlledSettingIndicators(browser(),
-                                        policy_test_case->indicator_selector(),
-                                        std::string(),
-                                        "policy",
-                                        false);
-    }
-
-    for (ScopedVector<PrefMapping>::const_iterator
-             pref_mapping = pref_mappings.begin();
-         pref_mapping != pref_mappings.end();
-         ++pref_mapping) {
-      const ScopedVector<IndicatorTestCase>&
-          indicator_test_cases = (*pref_mapping)->indicator_test_cases();
-      if (indicator_test_cases.empty())
-        continue;
-
-      if (!(*pref_mapping)->indicator_test_setup_js().empty()) {
-        ASSERT_TRUE(content::ExecuteScript(
-            browser()->tab_strip_model()->GetActiveWebContents(),
-            (*pref_mapping)->indicator_test_setup_js()));
+        if (!has_pref_indicator_tests)
+          continue;
       }
 
-      std::string indicator_selector = (*pref_mapping)->indicator_selector();
-      if (indicator_selector.empty())
-        indicator_selector = "[pref=\"" + (*pref_mapping)->pref() + "\"]";
-      for (ScopedVector<IndicatorTestCase>::const_iterator
-               indicator_test_case = indicator_test_cases.begin();
-           indicator_test_case != indicator_test_cases.end();
-           ++indicator_test_case) {
+      LOG(INFO) << "Testing policy: " << *policy;
+
+      if (!policy_test_case->indicator_selector().empty()) {
         // Check that no controlled setting indicator is visible when no value
         // is set by policy.
         ClearProviderPolicy();
         VerifyControlledSettingIndicators(
-            browser(), indicator_selector, std::string(), std::string(), false);
+            browser(),
+            policy_test_case->indicator_selector(),
+            std::string(),
+            std::string(),
+            false);
+        // Check that the appropriate controlled setting indicator is shown when
+        // a value is enforced by policy.
+        SetProviderPolicy(policy_test_case->test_policy(),
+                          POLICY_LEVEL_MANDATORY);
+        VerifyControlledSettingIndicators(
+            browser(),
+            policy_test_case->indicator_selector(),
+            std::string(),
+            "policy",
+            false);
+      }
 
-        if ((*pref_mapping)->check_for_mandatory()) {
+      for (ScopedVector<PrefMapping>::const_iterator
+               pref_mapping = pref_mappings.begin();
+           pref_mapping != pref_mappings.end();
+           ++pref_mapping) {
+        const ScopedVector<IndicatorTestCase>& indicator_test_cases =
+            (*pref_mapping)->indicator_test_cases();
+        if (indicator_test_cases.empty())
+          continue;
+
+        if (!(*pref_mapping)->indicator_test_setup_js().empty()) {
+          ASSERT_TRUE(content::ExecuteScript(
+              browser()->tab_strip_model()->GetActiveWebContents(),
+              (*pref_mapping)->indicator_test_setup_js()));
+        }
+
+        std::string indicator_selector = (*pref_mapping)->indicator_selector();
+        if (indicator_selector.empty())
+          indicator_selector = "[pref=\"" + (*pref_mapping)->pref() + "\"]";
+        for (ScopedVector<IndicatorTestCase>::const_iterator
+                 indicator_test_case = indicator_test_cases.begin();
+             indicator_test_case != indicator_test_cases.end();
+             ++indicator_test_case) {
+          // Check that no controlled setting indicator is visible when no value
+          // is set by policy.
+          ClearProviderPolicy();
+          VerifyControlledSettingIndicators(browser(),
+                                            indicator_selector,
+                                            std::string(),
+                                            std::string(),
+                                            false);
+
+          if ((*pref_mapping)->check_for_mandatory()) {
+            // Check that the appropriate controlled setting indicator is shown
+            // when a value is enforced by policy.
+            SetProviderPolicy((*indicator_test_case)->policy(),
+                              POLICY_LEVEL_MANDATORY);
+
+            VerifyControlledSettingIndicators(
+                browser(),
+                indicator_selector,
+                (*indicator_test_case)->value(),
+                "policy",
+                (*indicator_test_case)->readonly());
+          }
+
+          if (!policy_test_case->can_be_recommended() ||
+              !(*pref_mapping)->check_for_recommended()) {
+            continue;
+          }
+
+          PrefService* prefs =
+              (*pref_mapping)->is_local_state() ? local_state : user_prefs;
+          // The preference must have been registered.
+          const PrefService::Preference* pref =
+              prefs->FindPreference((*pref_mapping)->pref().c_str());
+          ASSERT_TRUE(pref);
+
           // Check that the appropriate controlled setting indicator is shown
-          // when a value is enforced by policy.
+          // when a value is recommended by policy and the user has not
+          // overridden the recommendation.
           SetProviderPolicy((*indicator_test_case)->policy(),
-                            POLICY_LEVEL_MANDATORY);
-
+                            POLICY_LEVEL_RECOMMENDED);
           VerifyControlledSettingIndicators(browser(),
                                             indicator_selector,
                                             (*indicator_test_case)->value(),
-                                            "policy",
+                                            "recommended",
                                             (*indicator_test_case)->readonly());
+          // Check that the appropriate controlled setting indicator is shown
+          // when a value is recommended by policy and the user has overridden
+          // the recommendation.
+          prefs->Set((*pref_mapping)->pref().c_str(), *pref->GetValue());
+          VerifyControlledSettingIndicators(browser(),
+                                            indicator_selector,
+                                            (*indicator_test_case)->value(),
+                                            "hasRecommendation",
+                                            (*indicator_test_case)->readonly());
+          prefs->ClearPref((*pref_mapping)->pref().c_str());
         }
-
-        if (!policy_test_case->can_be_recommended() ||
-            !(*pref_mapping)->check_for_recommended()) {
-          continue;
-        }
-
-        PrefService* prefs = (*pref_mapping)->is_local_state() ?
-            local_state : user_prefs;
-        // The preference must have been registered.
-        const PrefService::Preference* pref =
-            prefs->FindPreference((*pref_mapping)->pref().c_str());
-        ASSERT_TRUE(pref);
-
-        // Check that the appropriate controlled setting indicator is shown when
-        // a value is recommended by policy and the user has not overridden the
-        // recommendation.
-        SetProviderPolicy((*indicator_test_case)->policy(),
-                          POLICY_LEVEL_RECOMMENDED);
-        VerifyControlledSettingIndicators(browser(), indicator_selector,
-                                          (*indicator_test_case)->value(),
-                                          "recommended",
-                                          (*indicator_test_case)->readonly());
-        // Check that the appropriate controlled setting indicator is shown when
-        // a value is recommended by policy and the user has overridden the
-        // recommendation.
-        prefs->Set((*pref_mapping)->pref().c_str(), *pref->GetValue());
-        VerifyControlledSettingIndicators(browser(), indicator_selector,
-                                          (*indicator_test_case)->value(),
-                                          "hasRecommendation",
-                                          (*indicator_test_case)->readonly());
-        prefs->ClearPref((*pref_mapping)->pref().c_str());
       }
     }
   }
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.cc b/chrome/browser/predictors/autocomplete_action_predictor.cc
index 99a2244..923b25b 100644
--- a/chrome/browser/predictors/autocomplete_action_predictor.cc
+++ b/chrome/browser/predictors/autocomplete_action_predictor.cc
@@ -31,6 +31,7 @@
 #include "chrome/browser/prerender/prerender_manager.h"
 #include "chrome/browser/prerender/prerender_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
@@ -247,9 +248,6 @@
       break;
     }
 
-    // This notification does not catch all instances of the user navigating
-    // from the Omnibox, but it does catch the cases where the dropdown is open
-    // and those are the events we're most interested in.
     case chrome::NOTIFICATION_OMNIBOX_OPENED_URL: {
       DCHECK(initialized_);
 
@@ -338,6 +336,16 @@
   if (log.text.length() < kMinimumUserTextLength)
     return;
 
+  // Do not attempt to learn from omnibox interactions where the omnibox
+  // dropdown is closed.  In these cases the user text (|log.text|) that we
+  // learn from is either empty or effectively identical to the destination
+  // string.  In either case, it can't teach us much.  Also do not attempt
+  // to learn from paste-and-go actions even if the popup is open because
+  // the paste-and-go destination has no relation to whatever text the user
+  // may have typed.
+  if (!log.is_popup_open || log.is_paste_and_go)
+    return;
+
   // Abandon the current prerender. If it is to be used, it will be used very
   // soon, so use the lower timeout.
   if (prerender_handle_) {
@@ -346,13 +354,12 @@
     // next StartPrerendering call.
   }
 
-  const AutocompleteMatch& match = log.result.match_at(log.selected_index);
-
   UMA_HISTOGRAM_BOOLEAN(
       base::StringPrintf("Prerender.OmniboxNavigationsCouldPrerender%s",
                          prerender::PrerenderManager::GetModeString()).c_str(),
       prerender::IsOmniboxEnabled(profile_));
 
+  const AutocompleteMatch& match = log.result.match_at(log.selected_index);
   const GURL& opened_url = match.destination_url;
   const base::string16 lower_user_text(base::i18n::ToLower(log.text));
 
diff --git a/chrome/browser/prefetch/prefetch.cc b/chrome/browser/prefetch/prefetch.cc
index ad88568..ccf13e2 100644
--- a/chrome/browser/prefetch/prefetch.cc
+++ b/chrome/browser/prefetch/prefetch.cc
@@ -10,12 +10,19 @@
 #include "base/strings/string_util.h"
 #include "chrome/browser/prefetch/prefetch_field_trial.h"
 #include "chrome/browser/profiles/profile_io_data.h"
+#include "net/base/network_change_notifier.h"
 
 namespace prefetch {
 
 bool IsPrefetchEnabled(content::ResourceContext* resource_context) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
 
+  // TODO(jkarlin): Eventually tie this to a new Chrome preference to predict
+  // network actions when on cellular connections.  See crbug.com/370454.
+  if (net::NetworkChangeNotifier::IsConnectionCellular(
+          net::NetworkChangeNotifier::GetConnectionType()))
+    return false;
+
   ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
   if (io_data != NULL && io_data->network_prediction_enabled()->GetValue())
     return IsPrefetchFieldTrialEnabled();
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 001c77e..f55c4b1 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/about_flags.h"
 #include "chrome/browser/accessibility/invert_bubble_prefs.h"
 #include "chrome/browser/apps/shortcut_manager.h"
+#include "chrome/browser/autocomplete/zero_suggest_provider.h"
 #include "chrome/browser/background/background_mode_manager.h"
 #include "chrome/browser/browser_process_impl.h"
 #include "chrome/browser/browser_shutdown.h"
@@ -37,7 +38,6 @@
 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
 #include "chrome/browser/media/media_device_id_salt.h"
 #include "chrome/browser/media/media_stream_devices_controller.h"
-#include "chrome/browser/metrics/cloned_install_detector.h"
 #include "chrome/browser/metrics/metrics_log.h"
 #include "chrome/browser/metrics/metrics_service.h"
 #include "chrome/browser/metrics/variations/variations_service.h"
@@ -87,10 +87,8 @@
 #include "chrome/browser/ui/webui/print_preview/sticky_settings.h"
 #include "chrome/browser/upgrade_detector.h"
 #include "chrome/browser/web_resource/promo_resource_service.h"
-#include "chrome/common/metrics/caching_permuted_entropy_provider.h"
 #include "chrome/common/pref_names.h"
 #include "components/autofill/core/browser/autofill_manager.h"
-#include "components/bookmarks/core/browser/bookmark_prompt_prefs.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
 #include "components/password_manager/core/browser/password_manager.h"
 #include "components/rappor/rappor_service.h"
@@ -236,8 +234,6 @@
   KeywordEditorController::RegisterPrefs(registry);
   MetricsLog::RegisterPrefs(registry);
   MetricsService::RegisterPrefs(registry);
-  metrics::CachingPermutedEntropyProvider::RegisterPrefs(registry);
-  metrics::ClonedInstallDetector::RegisterPrefs(registry);
   PrefProxyConfigTrackerImpl::RegisterPrefs(registry);
   ProfileInfoCache::RegisterPrefs(registry);
   profiles::RegisterPrefs(registry);
@@ -336,7 +332,6 @@
   // User prefs. Please keep this list alphabetized.
   apps::RegisterProfilePrefs(registry);
   autofill::AutofillManager::RegisterProfilePrefs(registry);
-  BookmarkPromptPrefs::RegisterProfilePrefs(registry);
   bookmark_utils::RegisterProfilePrefs(registry);
   sync_driver::SyncPrefs::RegisterProfilePrefs(registry);
   ChromeContentBrowserClient::RegisterProfilePrefs(registry);
@@ -371,6 +366,7 @@
   SessionStartupPref::RegisterProfilePrefs(registry);
   TemplateURLPrepopulateData::RegisterProfilePrefs(registry);
   TranslatePrefs::RegisterProfilePrefs(registry);
+  ZeroSuggestProvider::RegisterProfilePrefs(registry);
   gcm::GCMProfileService::RegisterProfilePrefs(registry);
 
 #if defined(ENABLE_AUTOFILL_DIALOG)
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.cc b/chrome/browser/prefs/chrome_pref_service_factory.cc
index b057bbc..0f1d01b 100644
--- a/chrome/browser/prefs/chrome_pref_service_factory.cc
+++ b/chrome/browser/prefs/chrome_pref_service_factory.cc
@@ -34,6 +34,8 @@
 #include "chrome/browser/profiles/file_path_verifier_win.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/search_engines/default_search_manager.h"
+#include "chrome/browser/search_engines/default_search_pref_migration.h"
 #include "chrome/browser/ui/profile_error_dialog.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/pref_names.h"
@@ -151,10 +153,15 @@
     PrefHashFilter::ENFORCE_ON_LOAD,
     PrefHashFilter::TRACKING_STRATEGY_ATOMIC
   },
+  {
+    14, DefaultSearchManager::kDefaultSearchProviderDataPrefName,
+    PrefHashFilter::NO_ENFORCEMENT,
+    PrefHashFilter::TRACKING_STRATEGY_ATOMIC
+  },
 };
 
 // The count of tracked preferences IDs across all platforms.
-const size_t kTrackedPrefsReportingIDsCount = 14;
+const size_t kTrackedPrefsReportingIDsCount = 15;
 COMPILE_ASSERT(kTrackedPrefsReportingIDsCount >= arraysize(kTrackedPrefs),
                need_to_increment_ids_count);
 
@@ -169,6 +176,8 @@
   GROUP_ENFORCE_ALWAYS,
   // Also enforce extension settings.
   GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS,
+  // Also enforce extension settings and default search.
+  GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS_AND_DSE,
   // The default enforcement group contains all protection features.
   GROUP_ENFORCE_DEFAULT
 };
@@ -201,6 +210,9 @@
     { chrome_prefs::internals::
           kSettingsEnforcementGroupEnforceAlwaysWithExtensions,
       GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS },
+    { chrome_prefs::internals::
+          kSettingsEnforcementGroupEnforceAlwaysWithExtensionsAndDSE,
+      GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS_AND_DSE },
   };
 
   // Use the strongest enforcement setting in the absence of a field trial
@@ -247,20 +259,21 @@
   for (size_t i = 0; i < arraysize(kTrackedPrefs); ++i) {
     PrefHashFilter::TrackedPreferenceMetadata data = kTrackedPrefs[i];
 
-    switch (enforcement_group) {
-      case GROUP_NO_ENFORCEMENT:
-        // Remove enforcement for all tracked preferences.
-        data.enforcement_level = PrefHashFilter::NO_ENFORCEMENT;
-        break;
-      case GROUP_ENFORCE_ON_LOAD:  // Falls through.
-      case GROUP_ENFORCE_ALWAYS:
-        // Keep the default enforcement level for this tracked preference.
-        break;
-      case GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS:  // Falls through.
-      case GROUP_ENFORCE_DEFAULT:
-        // Specifically enable extension settings enforcement.
-        if (data.name == extensions::pref_names::kExtensions)
-          data.enforcement_level = PrefHashFilter::ENFORCE_ON_LOAD;
+    if (GROUP_NO_ENFORCEMENT == enforcement_group) {
+      // Remove enforcement for all tracked preferences.
+      data.enforcement_level = PrefHashFilter::NO_ENFORCEMENT;
+    }
+
+    if (enforcement_group >= GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS &&
+        data.name == extensions::pref_names::kExtensions) {
+      // Specifically enable extension settings enforcement.
+      data.enforcement_level = PrefHashFilter::ENFORCE_ON_LOAD;
+    }
+
+    if (enforcement_group >= GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS_AND_DSE &&
+        data.name == DefaultSearchManager::kDefaultSearchProviderDataPrefName) {
+      // Specifically enable default search settings enforcement.
+      data.enforcement_level = PrefHashFilter::ENFORCE_ON_LOAD;
     }
 
     result.push_back(data);
@@ -392,6 +405,8 @@
 const char kSettingsEnforcementGroupEnforceAlways[] = "enforce_always";
 const char kSettingsEnforcementGroupEnforceAlwaysWithExtensions[] =
     "enforce_always_with_extensions";
+const char kSettingsEnforcementGroupEnforceAlwaysWithExtensionsAndDSE[] =
+    "enforce_always_with_extensions_and_dse";
 
 }  // namespace internals
 
@@ -431,7 +446,12 @@
                          ->CreateProfilePrefStore(pref_io_task_runner)),
                  extension_prefs,
                  async);
-  return factory.CreateSyncable(pref_registry.get());
+  scoped_ptr<PrefServiceSyncable> pref_service =
+      factory.CreateSyncable(pref_registry.get());
+
+  ConfigureDefaultSearchPrefMigrationToDictionaryValue(pref_service.get());
+
+  return pref_service.Pass();
 }
 
 void SchedulePrefsFilePathVerification(const base::FilePath& profile_path) {
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.h b/chrome/browser/prefs/chrome_pref_service_factory.h
index e4b369a..54f84bc 100644
--- a/chrome/browser/prefs/chrome_pref_service_factory.h
+++ b/chrome/browser/prefs/chrome_pref_service_factory.h
@@ -41,6 +41,7 @@
 extern const char kSettingsEnforcementGroupEnforceOnload[];
 extern const char kSettingsEnforcementGroupEnforceAlways[];
 extern const char kSettingsEnforcementGroupEnforceAlwaysWithExtensions[];
+extern const char kSettingsEnforcementGroupEnforceAlwaysWithExtensionsAndDSE[];
 
 }  // namespace internals
 
diff --git a/chrome/browser/prefs/pref_hash_browsertest.cc b/chrome/browser/prefs/pref_hash_browsertest.cc
index 104c88a..4cfd45b 100644
--- a/chrome/browser/prefs/pref_hash_browsertest.cc
+++ b/chrome/browser/prefs/pref_hash_browsertest.cc
@@ -144,11 +144,10 @@
     return true;
 #endif  // defined(OS_WIN)
 #endif  // defined(OFFICIAL_BUILD)
-    return GetParam() != chrome_prefs::internals::
-                             kSettingsEnforcementGroupEnforceAlways &&
-           GetParam() !=
-               chrome_prefs::internals::
-                   kSettingsEnforcementGroupEnforceAlwaysWithExtensions;
+    return GetParam() == chrome_prefs::internals::
+                             kSettingsEnforcementGroupNoEnforcement ||
+           GetParam() == chrome_prefs::internals::
+                             kSettingsEnforcementGroupEnforceOnload;
   }
 };
 
@@ -325,4 +324,6 @@
         chrome_prefs::internals::kSettingsEnforcementGroupEnforceOnload,
         chrome_prefs::internals::kSettingsEnforcementGroupEnforceAlways,
         chrome_prefs::internals::
-            kSettingsEnforcementGroupEnforceAlwaysWithExtensions));
+            kSettingsEnforcementGroupEnforceAlwaysWithExtensions,
+        chrome_prefs::internals::
+            kSettingsEnforcementGroupEnforceAlwaysWithExtensionsAndDSE));
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 133c81d..bbfba0d 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -59,7 +59,7 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/mime_types_handler.h"
+#include "chrome/common/extensions/manifest_handlers/mime_types_handler.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/test_switches.h"
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index 38a16a1..25b6c0e 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -37,7 +37,6 @@
 #include "content/public/browser/session_storage_namespace.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/frame_navigate_params.h"
 #include "content/public/common/page_transition_types.h"
 #include "ui/gfx/rect.h"
@@ -187,7 +186,7 @@
   }
 
   virtual gfx::Size GetSizeForNewRenderView(
-      const WebContents* web_contents) const OVERRIDE {
+      WebContents* web_contents) const OVERRIDE {
     // Have to set the size of the RenderView on initialization to be sure it is
     // set before the RenderView is hidden on all platforms (esp. Android).
     return prerender_contents_->size_;
diff --git a/chrome/browser/prerender/prerender_local_predictor.cc b/chrome/browser/prerender/prerender_local_predictor.cc
index 706f375..cc3b1f5 100644
--- a/chrome/browser/prerender/prerender_local_predictor.cc
+++ b/chrome/browser/prerender/prerender_local_predictor.cc
@@ -36,7 +36,6 @@
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/page_transition_types.h"
 #include "crypto/secure_hash.h"
 #include "grit/browser_resources.h"
@@ -600,8 +599,7 @@
   info->session_storage_namespace_ =
       source_web_contents->GetController().GetDefaultSessionStorageNamespace();
 
-  gfx::Rect container_bounds;
-  source_web_contents->GetView()->GetContainerBounds(&container_bounds);
+  gfx::Rect container_bounds = source_web_contents->GetContainerBounds();
   info->size_.reset(new gfx::Size(container_bounds.size()));
 
   RecordEvent(EVENT_PRERENDER_URL_LOOKUP_SUCCESS);
@@ -1163,7 +1161,7 @@
       continue;
     }
 #if defined(FULL_SAFE_BROWSING)
-    if (!SkipLocalPredictorWhitelist() &&
+    if (!SkipLocalPredictorWhitelist() && sb_db_manager &&
         sb_db_manager->CheckSideEffectFreeWhitelistUrl(url_info->url)) {
       // If a page is on the side-effect free whitelist, we will just prerender
       // it without any additional checks.
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index d98a175..d36a502 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -60,7 +60,6 @@
 #include "content/public/browser/session_storage_namespace.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/url_constants.h"
 #include "extensions/common/constants.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
@@ -1119,8 +1118,7 @@
   prerender_data_->ClearPendingSwap();
 }
 
-void PrerenderManager::PendingSwap::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void PrerenderManager::PendingSwap::WebContentsDestroyed() {
   prerender_data_->ClearPendingSwap();
 }
 
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h
index 87d8b11..6861b7b 100644
--- a/chrome/browser/prerender/prerender_manager.h
+++ b/chrome/browser/prerender/prerender_manager.h
@@ -477,8 +477,7 @@
         int error_code,
         const base::string16& error_description,
         content::RenderViewHost* render_view_host) OVERRIDE;
-    virtual void WebContentsDestroyed(content::WebContents* web_contents)
-        OVERRIDE;
+    virtual void WebContentsDestroyed() OVERRIDE;
 
    private:
     void RecordEvent(PrerenderEvent event) const;
diff --git a/chrome/browser/printing/background_printing_manager.cc b/chrome/browser/printing/background_printing_manager.cc
index 4a29c65..1e5c58d 100644
--- a/chrome/browser/printing/background_printing_manager.cc
+++ b/chrome/browser/printing/background_printing_manager.cc
@@ -28,7 +28,7 @@
 
  private:
   virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   BackgroundPrintingManager* manager_;
 };
@@ -43,9 +43,8 @@
     base::TerminationStatus status) {
   manager_->DeletePreviewContents(web_contents());
 }
-void BackgroundPrintingManager::Observer::WebContentsDestroyed(
-    WebContents* web_contents) {
-  manager_->DeletePreviewContents(web_contents);
+void BackgroundPrintingManager::Observer::WebContentsDestroyed() {
+  manager_->DeletePreviewContents(web_contents());
 }
 
 BackgroundPrintingManager::BackgroundPrintingManager() {
diff --git a/chrome/browser/printing/print_dialog_cloud.cc b/chrome/browser/printing/print_dialog_cloud.cc
index 740664c..5dbc2b55 100644
--- a/chrome/browser/printing/print_dialog_cloud.cc
+++ b/chrome/browser/printing/print_dialog_cloud.cc
@@ -36,7 +36,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/common/frame_navigate_params.h"
 #include "webkit/common/webpreferences.h"
@@ -151,7 +150,7 @@
     }
   }
 
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     delete this;
   }
 
@@ -465,9 +464,8 @@
 }
 
 void CloudPrintFlowHandler::StoreDialogClientSize() const {
-  if (web_ui() && web_ui()->GetWebContents() &&
-      web_ui()->GetWebContents()->GetView()) {
-    gfx::Size size = web_ui()->GetWebContents()->GetView()->GetContainerSize();
+  if (web_ui() && web_ui()->GetWebContents()) {
+    gfx::Size size = web_ui()->GetWebContents()->GetContainerBounds().size();
     Profile* profile = Profile::FromWebUI(web_ui());
     profile->GetPrefs()->SetInteger(prefs::kCloudPrintDialogWidth,
                                     size.width());
diff --git a/chrome/browser/printing/print_preview_dialog_controller.cc b/chrome/browser/printing/print_preview_dialog_controller.cc
index 27d365f..3c8c24f 100644
--- a/chrome/browser/printing/print_preview_dialog_controller.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller.cc
@@ -40,7 +40,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/webplugininfo.h"
 #include "ui/web_dialogs/web_dialog_delegate.h"
 #include "ui/web_dialogs/web_dialog_web_contents_delegate.h"
@@ -138,7 +137,7 @@
     size->SetToMax(host->GetMaximumDialogSize());
     size->Enlarge(-2 * kBorder, -kBorder);
   } else {
-    size->SetToMax(initiator_->GetView()->GetContainerSize());
+    size->SetToMax(initiator_->GetContainerBounds().size());
     size->Enlarge(-2 * kBorder, -2 * kBorder);
   }
 
diff --git a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
index 1c769f4..c18b999 100644
--- a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
@@ -91,7 +91,7 @@
 
  private:
   // content::WebContentsObserver implementation.
-  virtual void WebContentsDestroyed(WebContents* contents) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     dialog_destroyed_ = true;
   }
 
diff --git a/chrome/browser/printing/print_preview_test.cc b/chrome/browser/printing/print_preview_test.cc
index ad93a33..4ce8fa4 100644
--- a/chrome/browser/printing/print_preview_test.cc
+++ b/chrome/browser/printing/print_preview_test.cc
@@ -13,7 +13,6 @@
 #include "components/web_modal/web_contents_modal_dialog_host.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 using web_modal::WebContentsModalDialogHost;
 using web_modal::ModalDialogHostObserver;
@@ -38,7 +37,7 @@
   // The web contents modal dialog must be parented to *something*; use the
   // WebContents window since there is no true browser window for unit tests.
   virtual gfx::NativeView GetHostView() const OVERRIDE {
-    return FindBrowser()->tab_strip_model()->GetActiveWebContents()->GetView()->
+    return FindBrowser()->tab_strip_model()->GetActiveWebContents()->
         GetNativeView();
   }
 
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index cfadc09..53598aa 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -26,7 +26,6 @@
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "printing/metafile_impl.h"
 #include "printing/printed_document.h"
diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc
index fb6e58b..421cf49 100644
--- a/chrome/browser/printing/printing_message_filter.cc
+++ b/chrome/browser/printing/printing_message_filter.cc
@@ -30,7 +30,6 @@
 #include "base/file_util.h"
 #include "base/lazy_instance.h"
 #include "chrome/browser/printing/print_dialog_cloud.h"
-#include "content/public/browser/web_contents_view.h"
 #endif
 
 #if defined(OS_ANDROID)
@@ -242,7 +241,7 @@
     return;
   print_dialog_cloud::CreatePrintDialogForFile(
       wc->GetBrowserContext(),
-      wc->GetView()->GetTopLevelNativeWindow(),
+      wc->GetTopLevelNativeWindow(),
       path,
       wc->GetTitle(),
       base::string16(),
diff --git a/chrome/browser/printing/printing_ui_web_contents_observer.cc b/chrome/browser/printing/printing_ui_web_contents_observer.cc
index 03a09f7..311d621 100644
--- a/chrome/browser/printing/printing_ui_web_contents_observer.cc
+++ b/chrome/browser/printing/printing_ui_web_contents_observer.cc
@@ -6,7 +6,6 @@
 
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 PrintingUIWebContentsObserver::PrintingUIWebContentsObserver(
     content::WebContents* web_contents)
@@ -16,5 +15,5 @@
 
 gfx::NativeView PrintingUIWebContentsObserver::GetParentView() {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-  return web_contents() ? web_contents()->GetView()->GetNativeView() : NULL;
+  return web_contents() ? web_contents()->GetNativeView() : NULL;
 }
diff --git a/chrome/browser/process_singleton_posix.cc b/chrome/browser/process_singleton_posix.cc
index 2753279..ad678ca 100644
--- a/chrome/browser/process_singleton_posix.cc
+++ b/chrome/browser/process_singleton_posix.cc
@@ -374,7 +374,7 @@
     // Now we know the directory was (at that point) created by the profile
     // owner. Try to connect.
     sockaddr_un addr;
-    SetupSockAddr(socket_path.value(), &addr);
+    SetupSockAddr(socket_target.value(), &addr);
     int ret = HANDLE_EINTR(connect(socket->fd(),
                                    reinterpret_cast<sockaddr*>(&addr),
                                    sizeof(addr)));
diff --git a/chrome/browser/process_singleton_posix_unittest.cc b/chrome/browser/process_singleton_posix_unittest.cc
index 4f9d318..f717a37 100644
--- a/chrome/browser/process_singleton_posix_unittest.cc
+++ b/chrome/browser/process_singleton_posix_unittest.cc
@@ -7,6 +7,7 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/un.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
@@ -77,9 +78,15 @@
     // Put the lock in a temporary directory.  Doesn't need to be a
     // full profile to test this code.
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-    lock_path_ = temp_dir_.path().Append(chrome::kSingletonLockFilename);
-    socket_path_ = temp_dir_.path().Append(chrome::kSingletonSocketFilename);
-    cookie_path_ = temp_dir_.path().Append(chrome::kSingletonCookieFilename);
+    // Use a long directory name to ensure that the socket isn't opened through
+    // the symlink.
+    user_data_path_ = temp_dir_.path().Append(
+        std::string(sizeof(sockaddr_un::sun_path), 'a'));
+    ASSERT_TRUE(CreateDirectory(user_data_path_));
+
+    lock_path_ = user_data_path_.Append(chrome::kSingletonLockFilename);
+    socket_path_ = user_data_path_.Append(chrome::kSingletonSocketFilename);
+    cookie_path_ = user_data_path_.Append(chrome::kSingletonCookieFilename);
   }
 
   virtual void TearDown() {
@@ -121,7 +128,7 @@
   }
 
   TestableProcessSingleton* CreateProcessSingleton() {
-    return new TestableProcessSingleton(temp_dir_.path());
+    return new TestableProcessSingleton(user_data_path_);
   }
 
   void VerifyFiles() {
@@ -218,6 +225,7 @@
     signal_event_.Signal();
   }
 
+  base::FilePath user_data_path_;
   base::FilePath lock_path_;
   base::FilePath socket_path_;
   base::FilePath cookie_path_;
diff --git a/chrome/browser/profile_resetter/jtl_interpreter.cc b/chrome/browser/profile_resetter/jtl_interpreter.cc
index a4cbd16..e258078 100644
--- a/chrome/browser/profile_resetter/jtl_interpreter.cc
+++ b/chrome/browser/profile_resetter/jtl_interpreter.cc
@@ -195,7 +195,7 @@
   StoreValue(const std::string& hashed_name, scoped_ptr<base::Value> value)
       : hashed_name_(hashed_name),
         value_(value.Pass()) {
-    DCHECK(IsStringUTF8(hashed_name));
+    DCHECK(base::IsStringUTF8(hashed_name));
     DCHECK(value_);
   }
   virtual ~StoreValue() {}
@@ -218,7 +218,7 @@
       : hashed_name_(hashed_name),
         value_(value.Pass()),
         default_value_(default_value.Pass()) {
-    DCHECK(IsStringUTF8(hashed_name));
+    DCHECK(base::IsStringUTF8(hashed_name));
     DCHECK(value_);
     DCHECK(default_value_);
   }
@@ -244,7 +244,7 @@
  public:
   explicit StoreNodeValue(const std::string& hashed_name)
       : hashed_name_(hashed_name) {
-    DCHECK(IsStringUTF8(hashed_name));
+    DCHECK(base::IsStringUTF8(hashed_name));
   }
   virtual ~StoreNodeValue() {}
   virtual bool Execute(ExecutionContext* context) OVERRIDE {
@@ -275,7 +275,7 @@
  public:
   explicit StoreNodeRegisterableDomain(const std::string& hashed_name)
       : hashed_name_(hashed_name) {
-    DCHECK(IsStringUTF8(hashed_name));
+    DCHECK(base::IsStringUTF8(hashed_name));
   }
   virtual ~StoreNodeRegisterableDomain() {}
   virtual bool Execute(ExecutionContext* context) OVERRIDE {
@@ -488,7 +488,7 @@
           break;
         case jtl_foundation::STORE_BOOL: {
           std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !IsStringUTF8(hashed_name))
+          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
             return false;
           bool value = false;
           if (!ReadBool(&value))
@@ -500,7 +500,7 @@
         }
         case jtl_foundation::COMPARE_STORED_BOOL: {
           std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !IsStringUTF8(hashed_name))
+          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
             return false;
           bool value = false;
           if (!ReadBool(&value))
@@ -517,7 +517,7 @@
         }
         case jtl_foundation::STORE_HASH: {
           std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !IsStringUTF8(hashed_name))
+          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
             return false;
           std::string hashed_value;
           if (!ReadHash(&hashed_value))
@@ -529,7 +529,7 @@
         }
         case jtl_foundation::COMPARE_STORED_HASH: {
           std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !IsStringUTF8(hashed_name))
+          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
             return false;
           std::string hashed_value;
           if (!ReadHash(&hashed_value))
@@ -546,21 +546,21 @@
         }
         case jtl_foundation::STORE_NODE_BOOL: {
           std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !IsStringUTF8(hashed_name))
+          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
             return false;
           operators.push_back(new StoreNodeValue<true>(hashed_name));
           break;
         }
         case jtl_foundation::STORE_NODE_HASH: {
           std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !IsStringUTF8(hashed_name))
+          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
             return false;
           operators.push_back(new StoreNodeValue<false>(hashed_name));
           break;
         }
         case jtl_foundation::STORE_NODE_REGISTERABLE_DOMAIN_HASH: {
           std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !IsStringUTF8(hashed_name))
+          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
             return false;
           operators.push_back(new StoreNodeRegisterableDomain(hashed_name));
           break;
@@ -588,14 +588,14 @@
         }
         case jtl_foundation::COMPARE_NODE_TO_STORED_BOOL: {
           std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !IsStringUTF8(hashed_name))
+          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
             return false;
           operators.push_back(new CompareNodeToStored<true>(hashed_name));
           break;
         }
         case jtl_foundation::COMPARE_NODE_TO_STORED_HASH: {
           std::string hashed_name;
-          if (!ReadHash(&hashed_name) || !IsStringUTF8(hashed_name))
+          if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name))
             return false;
           operators.push_back(new CompareNodeToStored<false>(hashed_name));
           break;
diff --git a/chrome/browser/profile_resetter/profile_resetter.cc b/chrome/browser/profile_resetter/profile_resetter.cc
index 9bc7dc9..3cfc57c 100644
--- a/chrome/browser/profile_resetter/profile_resetter.cc
+++ b/chrome/browser/profile_resetter/profile_resetter.cc
@@ -170,7 +170,7 @@
     const TemplateURL* default_search_provider =
         template_url_service_->GetDefaultSearchProvider();
     if (default_search_provider &&
-        default_search_provider->url_ref().HasGoogleBaseURLs())
+        default_search_provider->HasGoogleBaseURLs())
       GoogleURLTracker::RequestServerCheck(profile_, true);
 
     MarkAsDone(DEFAULT_SEARCH_ENGINE);
diff --git a/chrome/browser/profile_resetter/resettable_settings_snapshot.cc b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc
index 2ef05d5..7ba8be2 100644
--- a/chrome/browser/profile_resetter/resettable_settings_snapshot.cc
+++ b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc
@@ -11,19 +11,21 @@
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/feedback/feedback_data.h"
-#include "chrome/browser/feedback/feedback_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/pref_names.h"
+#include "components/feedback/feedback_data.h"
+#include "components/feedback/feedback_util.h"
 #include "content/public/browser/browser_thread.h"
 #include "grit/generated_resources.h"
 #include "grit/google_chrome_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 
+using feedback::FeedbackData;
+
 namespace {
 
 // Feedback bucket labels.
@@ -230,7 +232,7 @@
   feedback_data->set_description(report);
 
   feedback_data->set_image(make_scoped_ptr(new std::string));
-  feedback_data->set_profile(profile);
+  feedback_data->set_context(profile);
 
   feedback_data->set_page_url("");
   feedback_data->set_user_email("");
diff --git a/chrome/browser/profiles/host_zoom_map_browsertest.cc b/chrome/browser/profiles/host_zoom_map_browsertest.cc
new file mode 100644
index 0000000..f485636
--- /dev/null
+++ b/chrome/browser/profiles/host_zoom_map_browsertest.cc
@@ -0,0 +1,216 @@
+// 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.
+
+#include "content/public/browser/host_zoom_map.h"
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/path_service.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/stringprintf.h"
+#include "base/values.h"
+#include "chrome/browser/chrome_page_zoom.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "url/gurl.h"
+
+namespace {
+
+class ZoomLevelChangeObserver {
+ public:
+  explicit ZoomLevelChangeObserver(Profile* profile)
+      : message_loop_runner_(new content::MessageLoopRunner) {
+    content::HostZoomMap* host_zoom_map = static_cast<content::HostZoomMap*>(
+        content::HostZoomMap::GetForBrowserContext(profile));
+    subscription_ = host_zoom_map->AddZoomLevelChangedCallback(base::Bind(
+        &ZoomLevelChangeObserver::OnZoomLevelChanged, base::Unretained(this)));
+  }
+
+  void BlockUntilZoomLevelForHostHasChanged(const std::string& host) {
+    while (!std::count(changed_hosts_.begin(), changed_hosts_.end(), host)) {
+      message_loop_runner_->Run();
+      message_loop_runner_ = new content::MessageLoopRunner;
+    }
+    changed_hosts_.clear();
+  }
+
+ private:
+  void OnZoomLevelChanged(const content::HostZoomMap::ZoomLevelChange& change) {
+    changed_hosts_.push_back(change.host);
+    message_loop_runner_->Quit();
+  }
+
+  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
+  std::vector<std::string> changed_hosts_;
+  scoped_ptr<content::HostZoomMap::Subscription> subscription_;
+
+  DISALLOW_COPY_AND_ASSIGN(ZoomLevelChangeObserver);
+};
+
+}  // namespace
+
+class HostZoomMapBrowserTest : public InProcessBrowserTest {
+ public:
+  HostZoomMapBrowserTest() {}
+
+ protected:
+  void SetDefaultZoomLevel(double level) {
+    browser()->profile()->GetPrefs()->SetDouble(
+        prefs::kDefaultZoomLevel, level);
+  }
+
+  double GetZoomLevel(const GURL& url) {
+    content::HostZoomMap* host_zoom_map = static_cast<content::HostZoomMap*>(
+        content::HostZoomMap::GetForBrowserContext(browser()->profile()));
+    return host_zoom_map->GetZoomLevelForHostAndScheme(url.scheme(),
+                                                       url.host());
+  }
+
+  std::vector<std::string> GetHostsWithZoomLevels() {
+    typedef content::HostZoomMap::ZoomLevelVector ZoomLevelVector;
+    content::HostZoomMap* host_zoom_map = static_cast<content::HostZoomMap*>(
+        content::HostZoomMap::GetForBrowserContext(browser()->profile()));
+    content::HostZoomMap::ZoomLevelVector zoom_levels =
+        host_zoom_map->GetAllZoomLevels();
+    std::vector<std::string> results;
+    for (ZoomLevelVector::const_iterator it = zoom_levels.begin();
+         it != zoom_levels.end(); ++it)
+      results.push_back(it->host);
+    return results;
+  }
+
+  std::vector<std::string> GetHostsWithZoomLevelsFromPrefs() {
+    PrefService* prefs = browser()->profile()->GetPrefs();
+    const base::DictionaryValue* values =
+        prefs->GetDictionary(prefs::kPerHostZoomLevels);
+    std::vector<std::string> results;
+    if (values) {
+      for (base::DictionaryValue::Iterator it(*values);
+           !it.IsAtEnd(); it.Advance())
+        results.push_back(it.key());
+    }
+    return results;
+  }
+
+  GURL ConstructTestServerURL(const char* url_template) {
+    return GURL(base::StringPrintf(
+        url_template, embedded_test_server()->port()));
+  }
+
+ private:
+  scoped_ptr<net::test_server::HttpResponse> HandleRequest(
+      const net::test_server::HttpRequest& request) {
+    return scoped_ptr<net::test_server::HttpResponse>(
+        new net::test_server::BasicHttpResponse);
+  }
+
+  // BrowserTestBase:
+  virtual void SetUpOnMainThread() OVERRIDE {
+    ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+    embedded_test_server()->RegisterRequestHandler(base::Bind(
+        &HostZoomMapBrowserTest::HandleRequest, base::Unretained(this)));
+    host_resolver()->AddRule("*", "127.0.0.1");
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(HostZoomMapBrowserTest);
+};
+
+class HostZoomMapSanitizationBrowserTest : public HostZoomMapBrowserTest {
+ public:
+  HostZoomMapSanitizationBrowserTest() {}
+
+ private:
+  // InProcessBrowserTest:
+  virtual bool SetUpUserDataDirectory() OVERRIDE {
+    // Zoom-related preferences demonstrating the two problems that could be
+    // caused by the bug. They incorrectly contain a per-host zoom level for the
+    // empty host; and a value for 'host1' that only differs from the default by
+    // epsilon. Neither should have been persisted.
+    const char kBrokenPrefs[] =
+        "{'profile': {"
+        "   'default_zoom_level': 1.2,"
+        "   'per_host_zoom_levels': {'': 1.1, 'host1': 1.20001, 'host2': 1.3}"
+        "}}";
+    std::string broken_prefs(kBrokenPrefs);
+    std::replace(broken_prefs.begin(), broken_prefs.end(), '\'', '\"');
+
+    base::FilePath user_data_directory, path_to_prefs;
+    PathService::Get(chrome::DIR_USER_DATA, &user_data_directory);
+    path_to_prefs = user_data_directory
+        .AppendASCII(TestingProfile::kTestUserProfileDir)
+        .Append(chrome::kPreferencesFilename);
+    base::CreateDirectory(path_to_prefs.DirName());
+    base::WriteFile(path_to_prefs, broken_prefs.c_str(), broken_prefs.size());
+    return true;
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(HostZoomMapSanitizationBrowserTest);
+};
+
+// Regression test for crbug.com/364399.
+IN_PROC_BROWSER_TEST_F(HostZoomMapBrowserTest, ToggleDefaultZoomLevel) {
+  const double default_zoom_level = content::ZoomFactorToZoomLevel(1.5);
+
+  const char kTestURLTemplate1[] = "http://host1:%d/";
+  const char kTestURLTemplate2[] = "http://host2:%d/";
+
+  ZoomLevelChangeObserver observer(browser()->profile());
+
+  GURL test_url1 = ConstructTestServerURL(kTestURLTemplate1);
+  ui_test_utils::NavigateToURL(browser(), test_url1);
+
+  SetDefaultZoomLevel(default_zoom_level);
+  observer.BlockUntilZoomLevelForHostHasChanged(test_url1.host());
+  EXPECT_TRUE(
+      content::ZoomValuesEqual(default_zoom_level, GetZoomLevel(test_url1)));
+
+  GURL test_url2 = ConstructTestServerURL(kTestURLTemplate2);
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(), test_url2, NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+  EXPECT_TRUE(
+      content::ZoomValuesEqual(default_zoom_level, GetZoomLevel(test_url2)));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  chrome_page_zoom::Zoom(web_contents, content::PAGE_ZOOM_OUT);
+  observer.BlockUntilZoomLevelForHostHasChanged(test_url2.host());
+  EXPECT_FALSE(
+      content::ZoomValuesEqual(default_zoom_level, GetZoomLevel(test_url2)));
+
+  chrome_page_zoom::Zoom(web_contents, content::PAGE_ZOOM_IN);
+  observer.BlockUntilZoomLevelForHostHasChanged(test_url2.host());
+  EXPECT_TRUE(
+      content::ZoomValuesEqual(default_zoom_level, GetZoomLevel(test_url2)));
+
+  // Now both tabs should be at the default zoom level, so there should not be
+  // any per-host values saved either to Pref, or internally in HostZoomMap.
+  EXPECT_TRUE(GetHostsWithZoomLevels().empty());
+  EXPECT_TRUE(GetHostsWithZoomLevelsFromPrefs().empty());
+}
+
+// Test that garbage data from crbug.com/364399 is cleared up on startup.
+IN_PROC_BROWSER_TEST_F(HostZoomMapSanitizationBrowserTest, ClearOnStartup) {
+  EXPECT_THAT(GetHostsWithZoomLevels(), testing::ElementsAre("host2"));
+  EXPECT_THAT(GetHostsWithZoomLevelsFromPrefs(), testing::ElementsAre("host2"));
+}
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index 13c48be..0e13179 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -25,6 +25,7 @@
 #include "chrome/browser/extensions/extension_special_storage_policy.h"
 #include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
 #include "chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h"
+#include "chrome/browser/guest_view/guest_view_manager.h"
 #include "chrome/browser/io_thread.h"
 #include "chrome/browser/media/chrome_midi_permission_context.h"
 #include "chrome/browser/media/chrome_midi_permission_context_factory.h"
@@ -423,6 +424,11 @@
   return ChromeGeolocationPermissionContextFactory::GetForProfile(this);
 }
 
+content::BrowserPluginGuestManagerDelegate*
+    OffTheRecordProfileImpl::GetGuestManagerDelegate() {
+  return GuestViewManager::FromBrowserContext(this);
+}
+
 quota::SpecialStoragePolicy*
     OffTheRecordProfileImpl::GetSpecialStoragePolicy() {
   return GetExtensionSpecialStoragePolicy();
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h
index 8a66045..0e1b2e5 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.h
+++ b/chrome/browser/profiles/off_the_record_profile_impl.h
@@ -124,6 +124,8 @@
   virtual content::ResourceContext* GetResourceContext() OVERRIDE;
   virtual content::GeolocationPermissionContext*
       GetGeolocationPermissionContext() OVERRIDE;
+  virtual content::BrowserPluginGuestManagerDelegate*
+      GetGuestManagerDelegate() OVERRIDE;
   virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
 
  private:
diff --git a/chrome/browser/profiles/off_the_record_profile_impl_unittest.cc b/chrome/browser/profiles/off_the_record_profile_impl_unittest.cc
index 236daf8..a2afac9 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl_unittest.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl_unittest.cc
@@ -19,6 +19,7 @@
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "content/public/browser/host_zoom_map.h"
+#include "content/public/common/page_zoom.h"
 #include "net/dns/mock_host_resolver.h"
 
 using content::HostZoomMap;
@@ -57,7 +58,7 @@
     double level = change.zoom_level;
     DictionaryPrefUpdate update(prefs_.get(), prefs::kPerHostZoomLevels);
     base::DictionaryValue* host_zoom_dictionary = update.Get();
-    if (level == host_zoom_map->GetDefaultZoomLevel()) {
+    if (content::ZoomValuesEqual(level, host_zoom_map->GetDefaultZoomLevel())) {
       host_zoom_dictionary->RemoveWithoutPathExpansion(change.host, NULL);
     } else {
       host_zoom_dictionary->SetWithoutPathExpansion(
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index be393e2..7e7ee56 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/common/pref_names.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_prefs.h"
 #include "components/sync_driver/sync_prefs.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/browser/notification_service.h"
@@ -158,14 +159,7 @@
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 #endif
 #if defined(OS_ANDROID) || defined(OS_IOS)
-  registry->RegisterBooleanPref(
-      data_reduction_proxy::prefs::kDataReductionProxyEnabled,
-      false,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-  registry->RegisterBooleanPref(
-      data_reduction_proxy::prefs::kDataReductionProxyWasEnabledBefore,
-      false,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+  data_reduction_proxy::RegisterSyncableProfilePrefs(registry);
 #endif  // defined(OS_ANDROID) || defined(OS_IOS)
 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) && !defined(OS_IOS)
   // Preferences related to the avatar bubble and user manager tutorials.
diff --git a/chrome/browser/profiles/profile_avatar_downloader.cc b/chrome/browser/profiles/profile_avatar_downloader.cc
new file mode 100644
index 0000000..cda9116
--- /dev/null
+++ b/chrome/browser/profiles/profile_avatar_downloader.cc
@@ -0,0 +1,55 @@
+// 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.
+
+#include "chrome/browser/profiles/profile_avatar_downloader.h"
+
+#include "base/files/file_path.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_avatar_icon_util.h"
+#include "chrome/browser/profiles/profile_info_cache.h"
+#include "net/base/load_flags.h"
+
+namespace {
+const char kHighResAvatarDownloadUrlPrefix[] =
+    "http://www.gstatic.com/chrome/profile_avatars/";
+}
+
+ProfileAvatarDownloader::ProfileAvatarDownloader(
+    size_t icon_index,
+    ProfileInfoCache* cache)
+    : icon_index_(icon_index),
+      cache_(cache) {
+  GURL url(std::string(kHighResAvatarDownloadUrlPrefix) +
+           profiles::GetDefaultAvatarIconFileNameAtIndex(icon_index));
+  fetcher_.reset(new chrome::BitmapFetcher(url, this));
+}
+
+ProfileAvatarDownloader::~ProfileAvatarDownloader() {
+}
+
+void ProfileAvatarDownloader::Start() {
+  // In unit tests, the browser process can return a NULL request context.
+  net::URLRequestContextGetter* request_context =
+      g_browser_process->system_request_context();
+  if (request_context)
+    fetcher_->Start(
+        request_context,
+        std::string(),
+        net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
+        net::LOAD_NORMAL);
+}
+
+// BitmapFetcherDelegate overrides.
+void ProfileAvatarDownloader::OnFetchComplete(const GURL url,
+                                              const SkBitmap* bitmap) {
+  if (!bitmap || !cache_)
+    return;
+
+  // Decode the downloaded bitmap. Ownership of the image is taken by |cache_|.
+  gfx::Image image = gfx::Image::CreateFrom1xBitmap(*bitmap);
+  cache_->SaveAvatarImageAtPath(&image,
+      profiles::GetDefaultAvatarIconFileNameAtIndex(icon_index_),
+      profiles::GetPathOfHighResAvatarAtIndex(icon_index_));
+}
diff --git a/chrome/browser/profiles/profile_avatar_downloader.h b/chrome/browser/profiles/profile_avatar_downloader.h
new file mode 100644
index 0000000..67450ec
--- /dev/null
+++ b/chrome/browser/profiles/profile_avatar_downloader.h
@@ -0,0 +1,31 @@
+// 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.
+#ifndef CHROME_BROWSER_PROFILES_PROFILE_AVATAR_DOWNLOADER_H_
+#define CHROME_BROWSER_PROFILES_PROFILE_AVATAR_DOWNLOADER_H_
+
+#include "chrome/browser/bitmap_fetcher.h"
+
+class ProfileInfoCache;
+
+class ProfileAvatarDownloader : public chrome::BitmapFetcherDelegate {
+ public:
+  ProfileAvatarDownloader(size_t icon_index, ProfileInfoCache* cache);
+  virtual ~ProfileAvatarDownloader();
+
+  void Start();
+
+  // BitmapFetcherDelegate:
+  virtual void OnFetchComplete(const GURL url, const SkBitmap* bitmap) OVERRIDE;
+
+ private:
+  // Downloads the avatar image from a url.
+  scoped_ptr<chrome::BitmapFetcher> fetcher_;
+
+  // Index of the avatar being downloaded.
+  size_t icon_index_;
+
+  ProfileInfoCache* cache_;  // Weak.
+};
+
+#endif  // CHROME_BROWSER_PROFILES_PROFILE_AVATAR_DOWNLOADER_H_
diff --git a/chrome/browser/profiles/profile_avatar_icon_util.cc b/chrome/browser/profiles/profile_avatar_icon_util.cc
index 0ae3f29..6a3e613 100644
--- a/chrome/browser/profiles/profile_avatar_icon_util.cc
+++ b/chrome/browser/profiles/profile_avatar_icon_util.cc
@@ -4,10 +4,13 @@
 
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 
+#include "base/file_util.h"
 #include "base/format_macros.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/common/chrome_paths.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "third_party/skia/include/core/SkPaint.h"
@@ -17,6 +20,7 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/image/canvas_image_source.h"
+#include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia_operations.h"
 
 // Helper methods for transforming and drawing avatar icons.
@@ -25,7 +29,6 @@
 // Determine what the scaled height of the avatar icon should be for a
 // specified width, to preserve the aspect ratio.
 int GetScaledAvatarHeightForWidth(int width, const gfx::ImageSkia& avatar) {
-
   // Multiply the width by the inverted aspect ratio (height over
   // width), and then add 0.5 to ensure the int truncation rounds nicely.
   int scaled_height = width *
@@ -76,9 +79,8 @@
                                      AvatarBorder border)
     : gfx::CanvasImageSource(canvas_size, false),
       canvas_size_(canvas_size),
-      width_(width - profiles::kAvatarIconPadding),
-      height_(GetScaledAvatarHeightForWidth(width, avatar) -
-          profiles::kAvatarIconPadding),
+      width_(width),
+      height_(GetScaledAvatarHeightForWidth(width, avatar)),
       position_(position),
       border_(border) {
   avatar_ = gfx::ImageSkiaOperations::CreateResizedImage(
@@ -183,7 +185,6 @@
 
 const int kAvatarIconWidth = 38;
 const int kAvatarIconHeight = 38;
-const int kAvatarIconPadding = 2;
 const SkColor kAvatarTutorialBackgroundColor = SkColorSetRGB(0x42, 0x85, 0xf4);
 const SkColor kAvatarTutorialContentTextColor = SkColorSetRGB(0xc6, 0xda, 0xfc);
 const SkColor kAvatarBubbleAccountsBackgroundColor =
@@ -327,6 +328,14 @@
   return kNoHighResAvatar;
 }
 
+base::FilePath GetPathOfHighResAvatarAtIndex(size_t index) {
+  std::string file_name = GetDefaultAvatarIconResourceInfo(index)->filename;
+  base::FilePath user_data_dir;
+  PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
+  return user_data_dir.AppendASCII(
+      kHighResAvatarFolderName).AppendASCII(file_name);
+}
+
 std::string GetDefaultAvatarIconUrl(size_t index) {
   DCHECK(IsDefaultAvatarIconIndex(index));
   return base::StringPrintf("%s%" PRIuS, kDefaultUrlPrefix, index);
@@ -336,8 +345,7 @@
   return index < kDefaultAvatarIconsCount;
 }
 
-bool IsDefaultAvatarIconUrl(const std::string& url,
-                                              size_t* icon_index) {
+bool IsDefaultAvatarIconUrl(const std::string& url, size_t* icon_index) {
   DCHECK(icon_index);
   if (url.find(kDefaultUrlPrefix) != 0)
     return false;
diff --git a/chrome/browser/profiles/profile_avatar_icon_util.h b/chrome/browser/profiles/profile_avatar_icon_util.h
index 1ed7803..ecc3642 100644
--- a/chrome/browser/profiles/profile_avatar_icon_util.h
+++ b/chrome/browser/profiles/profile_avatar_icon_util.h
@@ -5,8 +5,17 @@
 #ifndef CHROME_BROWSER_PROFILES_PROFILE_AVATAR_ICON_UTIL_H_
 #define CHROME_BROWSER_PROFILES_PROFILE_AVATAR_ICON_UTIL_H_
 
+#include <string>
+
 #include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/image/image.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace gfx {
+class Image;
+}
 
 namespace profiles {
 
@@ -17,7 +26,6 @@
 // Avatar formatting.
 extern const int kAvatarIconWidth;
 extern const int kAvatarIconHeight;
-extern const int kAvatarIconPadding;
 extern const SkColor kAvatarTutorialBackgroundColor;
 extern const SkColor kAvatarTutorialContentTextColor;
 extern const SkColor kAvatarBubbleAccountsBackgroundColor;
@@ -43,6 +51,9 @@
 // Gets the file name of an avatar that has no high res version.
 const char* GetNoHighResAvatarFileName();
 
+// Gets the full path of the high res avatar icon at |index|.
+base::FilePath GetPathOfHighResAvatarAtIndex(size_t index);
+
 // Returns a URL for the default avatar icon with specified index.
 std::string GetDefaultAvatarIconUrl(size_t index);
 
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 3162f4c..055ab26 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/profiles/profile_impl.h"
 
+#include <vector>
+
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/command_line.h"
@@ -41,6 +43,7 @@
 #include "chrome/browser/extensions/extension_special_storage_policy.h"
 #include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
 #include "chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h"
+#include "chrome/browser/guest_view/guest_view_manager.h"
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/media/chrome_midi_permission_context.h"
 #include "chrome/browser/media/chrome_midi_permission_context_factory.h"
@@ -93,6 +96,7 @@
 #include "content/public/browser/url_data_source.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/common/content_constants.h"
+#include "content/public/common/page_zoom.h"
 #include "extensions/browser/extension_pref_store.h"
 #include "extensions/browser/extension_pref_value_map.h"
 #include "extensions/browser/extension_pref_value_map_factory.h"
@@ -657,6 +661,7 @@
       prefs_->GetDictionary(prefs::kPerHostZoomLevels);
   // Careful: The returned value could be NULL if the pref has never been set.
   if (host_zoom_dictionary != NULL) {
+    std::vector<std::string> keys_to_remove;
     for (base::DictionaryValue::Iterator i(*host_zoom_dictionary); !i.IsAtEnd();
          i.Advance()) {
       const std::string& host(i.key());
@@ -664,8 +669,30 @@
 
       bool success = i.value().GetAsDouble(&zoom_level);
       DCHECK(success);
+
+      // Filter out A) the empty host, B) zoom levels equal to the default; and
+      // remember them, so that we can later erase them from Prefs.
+      // Values of type A and B could have been stored due to crbug.com/364399.
+      // Values of type B could further have been stored before the default zoom
+      // level was set to its current value. In either case, SetZoomLevelForHost
+      // will ignore type B values, thus, to have consistency with HostZoomMap's
+      // internal state, these values must also be removed from Prefs.
+      if (host.empty() ||
+          content::ZoomValuesEqual(zoom_level,
+                                   host_zoom_map->GetDefaultZoomLevel())) {
+        keys_to_remove.push_back(host);
+        continue;
+      }
+
       host_zoom_map->SetZoomLevelForHost(host, zoom_level);
     }
+
+    DictionaryPrefUpdate update(prefs_.get(), prefs::kPerHostZoomLevels);
+    base::DictionaryValue* host_zoom_dictionary = update.Get();
+    for (std::vector<std::string>::const_iterator it = keys_to_remove.begin();
+         it != keys_to_remove.end(); ++it) {
+      host_zoom_dictionary->RemoveWithoutPathExpansion(*it, NULL);
+    }
   }
 
   zoom_subscription_ = host_zoom_map->AddZoomLevelChangedCallback(
@@ -1044,6 +1071,11 @@
   return ChromeGeolocationPermissionContextFactory::GetForProfile(this);
 }
 
+content::BrowserPluginGuestManagerDelegate*
+    ProfileImpl::GetGuestManagerDelegate() {
+  return GuestViewManager::FromBrowserContext(this);
+}
+
 DownloadManagerDelegate* ProfileImpl::GetDownloadManagerDelegate() {
   return DownloadServiceFactory::GetForBrowserContext(this)->
       GetDownloadManagerDelegate();
@@ -1090,7 +1122,7 @@
   double level = change.zoom_level;
   DictionaryPrefUpdate update(prefs_.get(), prefs::kPerHostZoomLevels);
   base::DictionaryValue* host_zoom_dictionary = update.Get();
-  if (level == host_zoom_map->GetDefaultZoomLevel()) {
+  if (content::ZoomValuesEqual(level, host_zoom_map->GetDefaultZoomLevel())) {
     host_zoom_dictionary->RemoveWithoutPathExpansion(change.host, NULL);
   } else {
     host_zoom_dictionary->SetWithoutPathExpansion(
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h
index e972fa5..9296d58 100644
--- a/chrome/browser/profiles/profile_impl.h
+++ b/chrome/browser/profiles/profile_impl.h
@@ -28,7 +28,9 @@
 
 #if defined(OS_CHROMEOS)
 namespace chromeos {
+class KioskTest;
 class LocaleChangeGuard;
+class ManagedUserTestBase;
 class Preferences;
 }
 #endif
@@ -99,6 +101,8 @@
   virtual content::ResourceContext* GetResourceContext() OVERRIDE;
   virtual content::GeolocationPermissionContext*
       GetGeolocationPermissionContext() OVERRIDE;
+  virtual content::BrowserPluginGuestManagerDelegate*
+      GetGuestManagerDelegate() OVERRIDE;
   virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
 
   // Profile implementation:
@@ -155,6 +159,10 @@
   virtual PrefProxyConfigTracker* GetProxyConfigTracker() OVERRIDE;
 
  private:
+#if defined(OS_CHROMEOS)
+  friend class chromeos::KioskTest;
+  friend class chromeos::ManagedUserTestBase;
+#endif
   friend class Profile;
   friend class BetterSessionRestoreCrashTest;
   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc
index 8220ede..e616e42 100644
--- a/chrome/browser/profiles/profile_info_cache.cc
+++ b/chrome/browser/profiles/profile_info_cache.cc
@@ -9,7 +9,6 @@
 #include "base/i18n/case_conversion.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/path_service.h"
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
 #include "base/prefs/scoped_user_pref_update.h"
@@ -21,15 +20,15 @@
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/profiles/profile_avatar_downloader.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
-#include "chrome/common/chrome_paths.h"
+#include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/common/pref_names.h"
 #include "components/signin/core/common/profile_management_switches.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
-#include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/image/image.h"
@@ -82,14 +81,12 @@
 
 typedef std::vector<unsigned char> ImageData;
 
-// Writes |data| to disk and takes ownership of the pointer. On completion
-// |success| is set to true on success and false on failure.
-void SaveBitmap(ImageData* data,
+// Writes |data| to disk and takes ownership of the pointer. On successful
+// completion, it runs |callback|.
+void SaveBitmap(scoped_ptr<ImageData> data,
                 const base::FilePath& image_path,
-                bool* success) {
+                const base::Closure& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-  scoped_ptr<ImageData> data_owner(data);
-  *success = false;
 
   // Make sure the destination directory exists.
   base::FilePath dir = image_path.DirName();
@@ -104,7 +101,7 @@
     return;
   }
 
-  *success = true;
+  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
 }
 
 // Reads a PNG from disk and decodes it. If the bitmap was successfully read
@@ -188,11 +185,20 @@
     }
     info->SetBoolean(kIsUsingDefaultName, IsDefaultName(name));
   }
+
+  // If needed, start downloading the high-res avatars.
+  if (switches::IsNewAvatarMenu()) {
+    for (size_t i = 0; i < GetNumberOfProfiles(); i++)
+      DownloadHighResAvatar(GetAvatarIconIndexOfProfileAtIndex(i));
+  }
 }
 
 ProfileInfoCache::~ProfileInfoCache() {
   STLDeleteContainerPairSecondPointers(
       cached_avatar_images_.begin(), cached_avatar_images_.end());
+  STLDeleteContainerPairSecondPointers(
+      avatar_images_downloads_in_progress_.begin(),
+      avatar_images_downloads_in_progress_.end());
 }
 
 void ProfileInfoCache::AddProfileToCache(const base::FilePath& profile_path,
@@ -332,7 +338,7 @@
   }
 
   // Use the high resolution version of the avatar if it exists.
-  if (switches::IsNewProfileManagement()) {
+  if (switches::IsNewAvatarMenu()) {
     const gfx::Image* image = GetHighResAvatarOfProfileAtIndex(index);
     if (image)
       return *image;
@@ -391,42 +397,10 @@
   return LoadAvatarPictureFromPath(key, image_path);
 }
 
-const gfx::Image* ProfileInfoCache::GetHighResAvatarOfProfileAtIndex(
-    size_t index) const {
-  int avatar_index = GetAvatarIconIndexOfProfileAtIndex(index);
-  std::string key = profiles::GetDefaultAvatarIconFileNameAtIndex(avatar_index);
-
-  if (!strcmp(key.c_str(), profiles::GetNoHighResAvatarFileName()))
-    return NULL;
-
-  base::FilePath user_data_dir;
-  PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
-  base::FilePath image_path = user_data_dir.
-      AppendASCII(profiles::kHighResAvatarFolderName).AppendASCII(key);
-  return LoadAvatarPictureFromPath(key, image_path);
-}
-
-const gfx::Image* ProfileInfoCache::LoadAvatarPictureFromPath(
-    const std::string& key,
-    const base::FilePath& image_path) const {
-  // If the picture is already loaded then use it.
-  if (cached_avatar_images_.count(key)) {
-    if (cached_avatar_images_[key]->IsEmpty())
-      return NULL;
-    return cached_avatar_images_[key];
-  }
-
-  // If the picture is already being loaded then don't try loading it again.
-  if (cached_avatar_images_loading_[key])
-    return NULL;
-  cached_avatar_images_loading_[key] = true;
-
-  gfx::Image** image = new gfx::Image*;
-  BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
-      base::Bind(&ReadBitmap, image_path, image),
-      base::Bind(&ProfileInfoCache::OnAvatarPictureLoaded,
-          const_cast<ProfileInfoCache*>(this)->AsWeakPtr(), key, image));
-  return NULL;
+bool ProfileInfoCache::IsUsingGAIAPictureOfProfileAtIndex(size_t index) const {
+  bool value = false;
+  GetInfoForProfileAtIndex(index)->GetBoolean(kUseGAIAPictureKey, &value);
+  return value;
 }
 
 bool ProfileInfoCache::ProfileIsManagedAtIndex(size_t index) const {
@@ -465,47 +439,6 @@
   return value;
 }
 
-void ProfileInfoCache::OnAvatarPictureLoaded(const std::string& key,
-                                             gfx::Image** image) const {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  cached_avatar_images_loading_[key] = false;
-
-  delete cached_avatar_images_[key];
-  if (*image) {
-    cached_avatar_images_[key] = *image;
-  } else {
-    // Place an empty image in the cache to avoid reloading it again.
-    cached_avatar_images_[key] = new gfx::Image();
-  }
-  delete image;
-
-  content::NotificationService::current()->Notify(
-      chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
-      content::NotificationService::AllSources(),
-      content::NotificationService::NoDetails());
-}
-
-void ProfileInfoCache::OnGAIAPictureSaved(const base::FilePath& path,
-                                          bool* success) const  {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  if (*success) {
-    content::NotificationService::current()->Notify(
-        chrome::NOTIFICATION_PROFILE_CACHE_PICTURE_SAVED,
-        content::NotificationService::AllSources(),
-        content::NotificationService::NoDetails());
-  }
-  delete success;
-}
-
-bool ProfileInfoCache::IsUsingGAIAPictureOfProfileAtIndex(
-    size_t index) const {
-  bool value = false;
-  GetInfoForProfileAtIndex(index)->GetBoolean(kUseGAIAPictureKey, &value);
-  return value;
-}
-
 size_t ProfileInfoCache::GetAvatarIconIndexOfProfileAtIndex(size_t index)
     const {
   std::string icon_url;
@@ -585,6 +518,10 @@
   // This takes ownership of |info|.
   SetInfoForProfileAtIndex(index, info.release());
 
+  // If needed, start downloading the high-res avatar.
+  if (switches::IsNewAvatarMenu())
+    DownloadHighResAvatar(icon_index);
+
   base::FilePath profile_path = GetPathOfProfileAtIndex(index);
   FOR_EACH_OBSERVER(ProfileInfoCacheObserver,
                     observer_list_,
@@ -604,6 +541,8 @@
 
 void ProfileInfoCache::SetManagedUserIdOfProfileAtIndex(size_t index,
                                                         const std::string& id) {
+  if (GetManagedUserIdOfProfileAtIndex(index) == id)
+    return;
   scoped_ptr<base::DictionaryValue> info(
       GetInfoForProfileAtIndex(index)->DeepCopy());
   info->SetString(kManagedUserId, id);
@@ -695,22 +634,10 @@
     }
   } else {
     // Save the new bitmap to disk.
-    cached_avatar_images_[key] = new gfx::Image(*image);
-    scoped_ptr<ImageData> data(new ImageData);
-    scoped_refptr<base::RefCountedMemory> png_data = image->As1xPNGBytes();
-    data->assign(png_data->front(), png_data->front() + png_data->size());
-    if (!data->size()) {
-      LOG(ERROR) << "Failed to PNG encode the image.";
-    } else {
-      new_file_name = old_file_name.empty() ?
-          profiles::kGAIAPictureFileName : old_file_name;
-      base::FilePath image_path = path.AppendASCII(new_file_name);
-      bool* success = new bool;
-      BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
-          base::Bind(&SaveBitmap, data.release(), image_path, success),
-          base::Bind(&ProfileInfoCache::OnGAIAPictureSaved, AsWeakPtr(),
-                     path, success));
-    }
+    new_file_name =
+        old_file_name.empty() ? profiles::kGAIAPictureFileName : old_file_name;
+    base::FilePath image_path = path.AppendASCII(new_file_name);
+    SaveAvatarImageAtPath(image, key, image_path);
   }
 
   scoped_ptr<base::DictionaryValue> info(
@@ -809,38 +736,6 @@
   }
 }
 
-bool ProfileInfoCache::IconIndexIsUnique(size_t icon_index) const {
-  for (size_t i = 0; i < GetNumberOfProfiles(); ++i) {
-    if (GetAvatarIconIndexOfProfileAtIndex(i) == icon_index)
-      return false;
-  }
-  return true;
-}
-
-bool ProfileInfoCache::ChooseAvatarIconIndexForNewProfile(
-    bool allow_generic_icon,
-    bool must_be_unique,
-    size_t* out_icon_index) const {
-  // Always allow all icons for new profiles if using the
-  // --new-profile-management flag.
-  if (switches::IsNewProfileManagement())
-    allow_generic_icon = true;
-  size_t start = allow_generic_icon ? 0 : profiles::GetGenericAvatarIconCount();
-  size_t end = profiles::GetDefaultAvatarIconCount();
-  size_t count = end - start;
-
-  int rand = base::RandInt(0, count);
-  for (size_t i = 0; i < count; ++i) {
-    size_t icon_index = start + (rand + i) %  count;
-    if (!must_be_unique || IconIndexIsUnique(icon_index)) {
-      *out_icon_index = icon_index;
-      return true;
-    }
-  }
-
-  return false;
-}
-
 size_t ProfileInfoCache::ChooseAvatarIconIndexForNewProfile() const {
   size_t icon_index = 0;
   // Try to find a unique, non-generic icon.
@@ -861,6 +756,70 @@
   return user_data_dir_;
 }
 
+// static
+std::vector<base::string16> ProfileInfoCache::GetProfileNames() {
+  std::vector<base::string16> names;
+  PrefService* local_state = g_browser_process->local_state();
+  const base::DictionaryValue* cache = local_state->GetDictionary(
+      prefs::kProfileInfoCache);
+  base::string16 name;
+  for (base::DictionaryValue::Iterator it(*cache); !it.IsAtEnd();
+       it.Advance()) {
+    const base::DictionaryValue* info = NULL;
+    it.value().GetAsDictionary(&info);
+    info->GetString(kNameKey, &name);
+    names.push_back(name);
+  }
+  return names;
+}
+
+// static
+void ProfileInfoCache::RegisterPrefs(PrefRegistrySimple* registry) {
+  registry->RegisterDictionaryPref(prefs::kProfileInfoCache);
+}
+
+void ProfileInfoCache::DownloadHighResAvatar(size_t icon_index) {
+  // TODO(noms): We should check whether the file already exists on disk
+  // before trying to re-download it. For now, since this is behind a flag and
+  // the resources are still changing, re-download it every time the profile
+  // avatar changes, to make sure we have the latest copy.
+  std::string file_name = profiles::GetDefaultAvatarIconFileNameAtIndex(
+      icon_index);
+  // If the file is already being downloaded, don't start another download.
+  if (avatar_images_downloads_in_progress_[file_name])
+    return;
+
+  // Start the download for this file. The cache takes ownership of the
+  // |avatar_downloader|, which will be deleted when the download completes, or
+  // if that never happens, when the ProfileInfoCache is destroyed.
+  ProfileAvatarDownloader* avatar_downloader = new ProfileAvatarDownloader(
+      icon_index,
+      this);
+  avatar_images_downloads_in_progress_[file_name] = avatar_downloader;
+  avatar_downloader->Start();
+}
+
+void ProfileInfoCache::SaveAvatarImageAtPath(
+    const gfx::Image* image,
+    const std::string& key,
+    const base::FilePath& image_path) {
+  cached_avatar_images_[key] = new gfx::Image(*image);
+
+  scoped_ptr<ImageData> data(new ImageData);
+  scoped_refptr<base::RefCountedMemory> png_data = image->As1xPNGBytes();
+  data->assign(png_data->front(), png_data->front() + png_data->size());
+
+  if (!data->size()) {
+    LOG(ERROR) << "Failed to PNG encode the image.";
+  } else {
+    base::Closure callback = base::Bind(
+        &ProfileInfoCache::OnAvatarPictureSaved, AsWeakPtr(), key);
+
+    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+        base::Bind(&SaveBitmap, base::Passed(&data), image_path, callback));
+  }
+}
+
 const base::DictionaryValue* ProfileInfoCache::GetInfoForProfileAtIndex(
     size_t index) const {
   DCHECK_LT(index, GetNumberOfProfiles());
@@ -914,6 +873,38 @@
   return sorted_keys_.end();
 }
 
+bool ProfileInfoCache::IconIndexIsUnique(size_t icon_index) const {
+  for (size_t i = 0; i < GetNumberOfProfiles(); ++i) {
+    if (GetAvatarIconIndexOfProfileAtIndex(i) == icon_index)
+      return false;
+  }
+  return true;
+}
+
+bool ProfileInfoCache::ChooseAvatarIconIndexForNewProfile(
+    bool allow_generic_icon,
+    bool must_be_unique,
+    size_t* out_icon_index) const {
+  // Always allow all icons for new profiles if using the
+  // --new-profile-management flag.
+  if (switches::IsNewProfileManagement())
+    allow_generic_icon = true;
+  size_t start = allow_generic_icon ? 0 : profiles::GetGenericAvatarIconCount();
+  size_t end = profiles::GetDefaultAvatarIconCount();
+  size_t count = end - start;
+
+  int rand = base::RandInt(0, count);
+  for (size_t i = 0; i < count; ++i) {
+    size_t icon_index = start + (rand + i) %  count;
+    if (!must_be_unique || IconIndexIsUnique(icon_index)) {
+      *out_icon_index = icon_index;
+      return true;
+    }
+  }
+
+  return false;
+}
+
 void ProfileInfoCache::UpdateSortForProfileIndex(size_t index) {
   base::string16 name = GetNameOfProfileAtIndex(index);
 
@@ -931,24 +922,76 @@
       content::NotificationService::NoDetails());
 }
 
-// static
-std::vector<base::string16> ProfileInfoCache::GetProfileNames() {
-  std::vector<base::string16> names;
-  PrefService* local_state = g_browser_process->local_state();
-  const base::DictionaryValue* cache = local_state->GetDictionary(
-      prefs::kProfileInfoCache);
-  base::string16 name;
-  for (base::DictionaryValue::Iterator it(*cache); !it.IsAtEnd();
-       it.Advance()) {
-    const base::DictionaryValue* info = NULL;
-    it.value().GetAsDictionary(&info);
-    info->GetString(kNameKey, &name);
-    names.push_back(name);
-  }
-  return names;
+const gfx::Image* ProfileInfoCache::GetHighResAvatarOfProfileAtIndex(
+    size_t index) const {
+  int avatar_index = GetAvatarIconIndexOfProfileAtIndex(index);
+  std::string key = profiles::GetDefaultAvatarIconFileNameAtIndex(avatar_index);
+
+  if (!strcmp(key.c_str(), profiles::GetNoHighResAvatarFileName()))
+      return NULL;
+
+  base::FilePath image_path =
+      profiles::GetPathOfHighResAvatarAtIndex(avatar_index);
+  return LoadAvatarPictureFromPath(key, image_path);
 }
 
-// static
-void ProfileInfoCache::RegisterPrefs(PrefRegistrySimple* registry) {
-  registry->RegisterDictionaryPref(prefs::kProfileInfoCache);
+const gfx::Image* ProfileInfoCache::LoadAvatarPictureFromPath(
+    const std::string& key,
+    const base::FilePath& image_path) const {
+  // If the picture is already loaded then use it.
+  if (cached_avatar_images_.count(key)) {
+    if (cached_avatar_images_[key]->IsEmpty())
+      return NULL;
+    return cached_avatar_images_[key];
+  }
+
+  // If the picture is already being loaded then don't try loading it again.
+  if (cached_avatar_images_loading_[key])
+    return NULL;
+  cached_avatar_images_loading_[key] = true;
+
+  gfx::Image** image = new gfx::Image*;
+  BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
+      base::Bind(&ReadBitmap, image_path, image),
+      base::Bind(&ProfileInfoCache::OnAvatarPictureLoaded,
+          const_cast<ProfileInfoCache*>(this)->AsWeakPtr(), key, image));
+  return NULL;
+}
+
+void ProfileInfoCache::OnAvatarPictureLoaded(const std::string& key,
+                                             gfx::Image** image) const {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  cached_avatar_images_loading_[key] = false;
+  delete cached_avatar_images_[key];
+
+  if (*image) {
+    cached_avatar_images_[key] = *image;
+  } else {
+    // Place an empty image in the cache to avoid reloading it again.
+    cached_avatar_images_[key] = new gfx::Image();
+  }
+  delete image;
+
+  content::NotificationService::current()->Notify(
+      chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
+      content::NotificationService::AllSources(),
+      content::NotificationService::NoDetails());
+}
+
+void ProfileInfoCache::OnAvatarPictureSaved(const std::string& file_name) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  content::NotificationService::current()->Notify(
+      chrome::NOTIFICATION_PROFILE_CACHE_PICTURE_SAVED,
+      content::NotificationService::AllSources(),
+      content::NotificationService::NoDetails());
+
+  // Remove the file from the list of downloads in progress. Note that this list
+  // only contains the high resolution avatars, and not the Gaia profile images.
+  if (!avatar_images_downloads_in_progress_[file_name])
+    return;
+
+  delete avatar_images_downloads_in_progress_[file_name];
+  avatar_images_downloads_in_progress_[file_name] = NULL;
 }
diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h
index 4b88fcb..cf6dec1 100644
--- a/chrome/browser/profiles/profile_info_cache.h
+++ b/chrome/browser/profiles/profile_info_cache.h
@@ -28,6 +28,7 @@
 
 class PrefService;
 class PrefRegistrySimple;
+class ProfileAvatarDownloader;
 
 // This class saves various information about profiles to local preferences.
 // This cache can be used to display a list of profiles without having to
@@ -135,10 +136,22 @@
   // Register cache related preferences in Local State.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
+  // Starts downloading the high res avatar at index |icon_index|.
+  void DownloadHighResAvatar(size_t icon_index);
+
+  // Saves the avatar |image| at |image_path|. This is used both for the
+  // GAIA profile pictures and the ProfileAvatarDownloader that is used to
+  // download the high res avatars.
+  void SaveAvatarImageAtPath(const gfx::Image* image,
+                             const std::string& key,
+                             const base::FilePath& image_path);
+
   void AddObserver(ProfileInfoCacheObserver* obs);
   void RemoveObserver(ProfileInfoCacheObserver* obs);
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(ProfileInfoCacheTest, DownloadHighResAvatarTest);
+
   const base::DictionaryValue* GetInfoForProfileAtIndex(size_t index) const;
   // Saves the profile info to a cache and takes ownership of |info|.
   // Currently the only information that is cached is the profile's name,
@@ -168,12 +181,19 @@
   // generic profile avatar.
   const gfx::Image* GetHighResAvatarOfProfileAtIndex(size_t index) const;
 
+  // Returns the decoded image at |image_path|. Used both by the GAIA profile
+  // image and the high res avatars.
   const gfx::Image* LoadAvatarPictureFromPath(
       const std::string& key,
       const base::FilePath& image_path) const;
+
+  // Called when the picture given by |key| has been loaded from disk and
+  // decoded into |image|.
   void OnAvatarPictureLoaded(const std::string& key,
                              gfx::Image** image) const;
-  void OnGAIAPictureSaved(const base::FilePath& path, bool* success) const;
+  // Called when the picture given by |file_name| has been saved to disk.
+  // Used both for the GAIA profile picture and the high res avatar files.
+  void OnAvatarPictureSaved(const std::string& file_name);
 
   PrefService* prefs_;
   std::vector<std::string> sorted_keys_;
@@ -184,10 +204,18 @@
   // A cache of gaia/high res avatar profile pictures. This cache is updated
   // lazily so it needs to be mutable.
   mutable std::map<std::string, gfx::Image*> cached_avatar_images_;
-  // Marks a profile picture as loading. This prevents a picture from
+  // Marks a profile picture as loading from disk. This prevents a picture from
   // loading multiple times.
   mutable std::map<std::string, bool> cached_avatar_images_loading_;
 
+  // Map of profile pictures currently being downloaded from the remote
+  // location and the ProfileAvatarDownloader instances downloading them.
+  // This prevents a picture from being downloaded multiple times. The
+  // ProfileAvatarDownloader instances are deleted when the download completes
+  // or when the ProfileInfoCache is destroyed.
+  mutable std::map<std::string, ProfileAvatarDownloader*>
+      avatar_images_downloads_in_progress_;
+
   DISALLOW_COPY_AND_ASSIGN(ProfileInfoCache);
 };
 
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc
index 0405b1f..d1a39f9 100644
--- a/chrome/browser/profiles/profile_info_cache_unittest.cc
+++ b/chrome/browser/profiles/profile_info_cache_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <vector>
 
+#include "base/file_util.h"
 #include "base/prefs/testing_pref_service.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -13,6 +14,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
+#include "chrome/browser/profiles/profile_avatar_downloader.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -117,8 +119,6 @@
   testing_profile_manager_.DeleteProfileInfoCache();
 }
 
-namespace {
-
 TEST_F(ProfileInfoCacheTest, AddProfiles) {
   EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
 
@@ -502,4 +502,49 @@
     ASSERT_FALSE(names[i].empty());
 }
 
-}  // namespace
+TEST_F(ProfileInfoCacheTest, DownloadHighResAvatarTest) {
+  EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles());
+  base::FilePath path_1 = GetProfilePath("path_1");
+  GetCache()->AddProfileToCache(path_1, ASCIIToUTF16("name_1"),
+                                base::string16(), 0, std::string());
+  EXPECT_EQ(1U, GetCache()->GetNumberOfProfiles());
+
+  // We haven't downloaded any high-res avatars yet.
+  EXPECT_EQ(0U, GetCache()->cached_avatar_images_.size());
+  EXPECT_EQ(0U, GetCache()->avatar_images_downloads_in_progress_.size());
+  EXPECT_FALSE(GetCache()->GetHighResAvatarOfProfileAtIndex(0));
+
+  // Simulate downloading a high-res avatar.
+  const size_t kIconIndex = 0;
+  ProfileAvatarDownloader avatar_downloader(kIconIndex, GetCache());
+
+  // Put a real bitmap into "bitmap".  2x2 bitmap of green 32 bit pixels.
+  SkBitmap bitmap;
+  bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
+  bitmap.allocPixels();
+  bitmap.eraseColor(SK_ColorGREEN);
+
+  avatar_downloader.OnFetchComplete(
+      GURL("http://www.google.com/avatar.png"), &bitmap);
+
+  std::string file_name =
+      profiles::GetDefaultAvatarIconFileNameAtIndex(kIconIndex);
+
+  // The file should have been cached and saved.
+  EXPECT_EQ(0U, GetCache()->avatar_images_downloads_in_progress_.size());
+  EXPECT_EQ(1U, GetCache()->cached_avatar_images_.size());
+  EXPECT_TRUE(GetCache()->GetHighResAvatarOfProfileAtIndex(0));
+  EXPECT_EQ(GetCache()->cached_avatar_images_[file_name],
+      GetCache()->GetHighResAvatarOfProfileAtIndex(0));
+
+  // Make sure everything has completed, and the file has been written to disk.
+  base::RunLoop().RunUntilIdle();
+
+  // Clean up.
+  base::FilePath icon_path =
+      profiles::GetPathOfHighResAvatarAtIndex(kIconIndex);
+  EXPECT_NE(std::string::npos, icon_path.MaybeAsASCII().find(file_name));
+  EXPECT_TRUE(base::PathExists(icon_path));
+  EXPECT_TRUE(base::DeleteFile(icon_path, true));
+  EXPECT_FALSE(base::PathExists(icon_path));
+}
diff --git a/chrome/browser/profiles/profile_metrics.cc b/chrome/browser/profiles/profile_metrics.cc
index feb1922..a829be2 100644
--- a/chrome/browser/profiles/profile_metrics.cc
+++ b/chrome/browser/profiles/profile_metrics.cc
@@ -289,6 +289,12 @@
                             NUM_PROFILE_AUTH_METRICS);
 }
 
+void ProfileMetrics::LogProfileUpgradeEnrollment(
+    ProfileUpgradeEnrollment metric) {
+  UMA_HISTOGRAM_ENUMERATION("Profile.UpgradeEnrollment", metric,
+                            NUM_PROFILE_ENROLLMENT_METRICS);
+}
+
 void ProfileMetrics::LogProfileLaunch(Profile* profile) {
   base::FilePath profile_path = profile->GetPath();
   UMA_HISTOGRAM_ENUMERATION("Profile.LaunchBrowser",
diff --git a/chrome/browser/profiles/profile_metrics.h b/chrome/browser/profiles/profile_metrics.h
index f31eb10..174c203 100644
--- a/chrome/browser/profiles/profile_metrics.h
+++ b/chrome/browser/profiles/profile_metrics.h
@@ -61,8 +61,8 @@
   };
 
   enum ProfileType {
-    ORIGINAL = 0,         // Refers to the original/default profile
-    SECONDARY,            // Refers to a user-created profile
+    ORIGINAL = 0,             // Refers to the original/default profile
+    SECONDARY,                // Refers to a user-created profile
     NUM_PROFILE_TYPE_METRICS
   };
 
@@ -80,6 +80,22 @@
     NUM_PROFILE_AUTH_METRICS
   };
 
+  // Enum for tracking if new profile management is enabled and Promo views.
+  // This is used in a histogram; the items should not be removed or re-ordered.
+  enum ProfileUpgradeEnrollment {
+    // User viewed the Upgrade promo card in the user menu.
+    PROFILE_ENROLLMENT_SHOW_PREVIEW_PROMO,
+    // User selected to view the intro tutorial.
+    PROFILE_ENROLLMENT_LAUNCH_LEARN_MORE,
+    // User opted into New Profile Management via Promo card.
+    PROFILE_ENROLLMENT_ACCEPT_NEW_PROFILE_MGMT,
+    // User closed the Upgrade card.
+    PROFILE_ENROLLMENT_CLOSE_WELCOME_CARD,
+    // Used disabled New Profile Management.
+    PROFILE_ENROLLMENT_DISABLE_NEW_PROFILE_MGMT,
+    NUM_PROFILE_ENROLLMENT_METRICS,
+  };
+
   static void UpdateReportedProfilesStatistics(ProfileManager* manager);
 
   static void LogNumberOfProfiles(ProfileManager* manager);
@@ -91,6 +107,7 @@
   static void LogProfileSwitchUser(ProfileOpen metric);
   static void LogProfileSyncInfo(ProfileSync metric);
   static void LogProfileAuthResult(ProfileAuth metric);
+  static void LogProfileUpgradeEnrollment(ProfileUpgradeEnrollment metric);
 
   // These functions should only be called on the UI thread because they hook
   // into g_browser_process through a helper function.
diff --git a/chrome/browser/renderer_context_menu/context_menu_content_type.cc b/chrome/browser/renderer_context_menu/context_menu_content_type.cc
index 256f30b..4441030 100644
--- a/chrome/browser/renderer_context_menu/context_menu_content_type.cc
+++ b/chrome/browser/renderer_context_menu/context_menu_content_type.cc
@@ -127,6 +127,9 @@
     case ITEM_GROUP_MEDIA_AUDIO:
       return params_.media_type == WebContextMenuData::MediaTypeAudio;
 
+    case ITEM_GROUP_MEDIA_CANVAS:
+      return params_.media_type == WebContextMenuData::MediaTypeCanvas;
+
     case ITEM_GROUP_MEDIA_PLUGIN:
       return params_.media_type == WebContextMenuData::MediaTypePlugin;
 
diff --git a/chrome/browser/renderer_context_menu/context_menu_content_type.h b/chrome/browser/renderer_context_menu/context_menu_content_type.h
index a2fd20f..858f99a 100644
--- a/chrome/browser/renderer_context_menu/context_menu_content_type.h
+++ b/chrome/browser/renderer_context_menu/context_menu_content_type.h
@@ -38,6 +38,7 @@
     ITEM_GROUP_SEARCHWEBFORIMAGE,
     ITEM_GROUP_MEDIA_VIDEO,
     ITEM_GROUP_MEDIA_AUDIO,
+    ITEM_GROUP_MEDIA_CANVAS,
     ITEM_GROUP_MEDIA_PLUGIN,
     ITEM_GROUP_MEDIA_FILE,
     ITEM_GROUP_EDITABLE,
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
index a7e58d8..2669074 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -199,9 +199,6 @@
   { 46, IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS },
   { 47, IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_SETTINGS },
   { 48, IDC_CONTENT_CONTEXT_ADDSEARCHENGINE },
-  { 49, IDC_CONTENT_CONTEXT_SPEECH_INPUT_FILTER_PROFANITIES },
-  { 50, IDC_CONTENT_CONTEXT_SPEECH_INPUT_ABOUT },
-  { 51, IDC_SPEECH_INPUT_MENU },
   { 52, IDC_CONTENT_CONTEXT_OPENLINKWITH },
   { 53, IDC_CHECK_SPELLING_WHILE_TYPING },
   { 54, IDC_SPELLCHECK_MENU },
@@ -412,7 +409,6 @@
                        this,
                        &menu_model_,
                        base::Bind(MenuItemMatchesParams, params_)),
-      speech_input_submenu_model_(this),
       protocol_handler_submenu_model_(this),
       protocol_handler_registry_(
           ProtocolHandlerRegistryFactory::GetForProfile(profile_)),
@@ -630,6 +626,11 @@
   }
 
   if (content_type_->SupportsGroup(
+          ContextMenuContentType::ITEM_GROUP_MEDIA_CANVAS)) {
+    AppendCanvasItems();
+  }
+
+  if (content_type_->SupportsGroup(
           ContextMenuContentType::ITEM_GROUP_MEDIA_PLUGIN)) {
     AppendPluginItems();
   }
@@ -843,6 +844,14 @@
                                   IDS_CONTENT_CONTEXT_OPENAUDIONEWTAB);
 }
 
+void RenderViewContextMenu::AppendCanvasItems() {
+  menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_SAVEIMAGEAS,
+                                  IDS_CONTENT_CONTEXT_SAVEIMAGEAS);
+
+  // TODO(zino): We should support 'copy image' for canvas.
+  // http://crbug.com/369092
+}
+
 void RenderViewContextMenu::AppendVideoItems() {
   AppendMediaItems();
   menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
@@ -1022,7 +1031,6 @@
 
   if (use_spellcheck_and_search)
     AppendSpellcheckOptionsSubMenu();
-  AppendSpeechInputOptionsSubMenu();
   AppendPlatformEditableItems();
 
   menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
@@ -1046,24 +1054,6 @@
   observers_.AddObserver(spellchecker_submenu_observer_.get());
 }
 
-void RenderViewContextMenu::AppendSpeechInputOptionsSubMenu() {
-  if (params_.speech_input_enabled) {
-    speech_input_submenu_model_.AddCheckItem(
-        IDC_CONTENT_CONTEXT_SPEECH_INPUT_FILTER_PROFANITIES,
-        l10n_util::GetStringUTF16(
-            IDS_CONTENT_CONTEXT_SPEECH_INPUT_FILTER_PROFANITIES));
-
-    speech_input_submenu_model_.AddItemWithStringId(
-        IDC_CONTENT_CONTEXT_SPEECH_INPUT_ABOUT,
-        IDS_CONTENT_CONTEXT_SPEECH_INPUT_ABOUT);
-
-    menu_model_.AddSubMenu(
-        IDC_SPEECH_INPUT_MENU,
-        l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPEECH_INPUT_MENU),
-        &speech_input_submenu_model_);
-  }
-}
-
 void RenderViewContextMenu::AppendProtocolHandlerSubMenu() {
   const ProtocolHandlerRegistry::ProtocolHandlerList handlers =
       GetHandlersForLinkUrl();
@@ -1225,6 +1215,9 @@
       if (!local_state->GetBoolean(prefs::kAllowFileSelectionDialogs))
         return false;
 
+      if (params_.media_type == WebContextMenuData::MediaTypeCanvas)
+        return true;
+
       return params_.src_url.is_valid() &&
           ProfileIOData::IsHandledProtocol(params_.src_url.scheme());
     }
@@ -1377,11 +1370,6 @@
     case IDC_SPELLCHECK_MENU:
       return true;
 
-    case IDC_CONTENT_CONTEXT_SPEECH_INPUT_FILTER_PROFANITIES:
-    case IDC_CONTENT_CONTEXT_SPEECH_INPUT_ABOUT:
-    case IDC_SPEECH_INPUT_MENU:
-      return true;
-
     case IDC_CONTENT_CONTEXT_OPENLINKWITH:
       return true;
 
@@ -1427,14 +1415,6 @@
     return extension_items_.IsCommandIdChecked(id);
   }
 
-#if defined(ENABLE_INPUT_SPEECH)
-  // Check box for menu item 'Block offensive words'.
-  if (id == IDC_CONTENT_CONTEXT_SPEECH_INPUT_FILTER_PROFANITIES) {
-    return profile_->GetPrefs()->GetBoolean(
-        prefs::kSpeechRecognitionFilterProfanities);
-  }
-#endif
-
   return false;
 }
 
@@ -1537,12 +1517,18 @@
 
     case IDC_CONTENT_CONTEXT_SAVEAVAS:
     case IDC_CONTENT_CONTEXT_SAVEIMAGEAS: {
-      RecordDownloadSource(DOWNLOAD_INITIATED_BY_CONTEXT_MENU);
-      const GURL& referrer =
-          params_.frame_url.is_empty() ? params_.page_url : params_.frame_url;
-      const GURL& url = params_.src_url;
-      source_web_contents_->SaveFrame(url, content::Referrer(
-          referrer, params_.referrer_policy));
+      if (params_.media_type == WebContextMenuData::MediaTypeCanvas) {
+        source_web_contents_->GetRenderViewHost()->SaveImageAt(
+          params_.x, params_.y);
+      } else {
+        // TODO(zino): We can use SaveImageAt() like a case of canvas.
+        RecordDownloadSource(DOWNLOAD_INITIATED_BY_CONTEXT_MENU);
+        const GURL& referrer =
+            params_.frame_url.is_empty() ? params_.page_url : params_.frame_url;
+        const GURL& url = params_.src_url;
+        source_web_contents_->SaveFrame(url, content::Referrer(
+            referrer, params_.referrer_policy));
+      }
       break;
     }
 
@@ -1861,24 +1847,6 @@
       break;
     }
 
-#if defined(ENABLE_INPUT_SPEECH)
-    case IDC_CONTENT_CONTEXT_SPEECH_INPUT_FILTER_PROFANITIES: {
-      profile_->GetPrefs()->SetBoolean(
-          prefs::kSpeechRecognitionFilterProfanities,
-          !profile_->GetPrefs()->GetBoolean(
-              prefs::kSpeechRecognitionFilterProfanities));
-      break;
-    }
-#endif
-    case IDC_CONTENT_CONTEXT_SPEECH_INPUT_ABOUT: {
-      GURL url(chrome::kSpeechInputAboutURL);
-      GURL localized_url = google_util::AppendGoogleLocaleParam(url);
-      // Open URL with no referrer field (because user clicked on menu item).
-      OpenURL(localized_url, GURL(), NEW_FOREGROUND_TAB,
-              content::PAGE_TRANSITION_LINK);
-      break;
-    }
-
     default:
       NOTREACHED();
       break;
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.h b/chrome/browser/renderer_context_menu/render_view_context_menu.h
index 257bf15..0d1c174 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.h
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -141,7 +141,7 @@
   // Programmatically closes the context menu.
   void Cancel();
 
-  const ui::MenuModel& menu_model() const { return menu_model_; }
+  const ui::SimpleMenuModel& menu_model() const { return menu_model_; }
   const content::ContextMenuParams& params() const { return params_; }
 
   // SimpleMenuModel::Delegate implementation.
@@ -211,6 +211,7 @@
   void AppendLinkItems();
   void AppendImageItems();
   void AppendAudioItems();
+  void AppendCanvasItems();
   void AppendVideoItems();
   void AppendMediaItems();
   void AppendPluginItems();
@@ -226,7 +227,6 @@
   void AppendSearchWebForImageItems();
   void AppendSpellingSuggestionsSubMenu();
   void AppendSpellcheckOptionsSubMenu();
-  void AppendSpeechInputOptionsSubMenu();
   void AppendProtocolHandlerSubMenu();
 
   // Opens the specified URL string in a new tab.
@@ -265,7 +265,6 @@
   // a text selection.
   GURL selection_navigation_url_;
 
-  ui::SimpleMenuModel speech_input_submenu_model_;
   ui::SimpleMenuModel protocol_handler_submenu_model_;
   ProtocolHandlerRegistry* protocol_handler_registry_;
 
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
index 99c25fe..b797ebc 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -21,7 +21,6 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/browser_test_utils.h"
 #include "third_party/WebKit/public/web/WebContextMenuData.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
@@ -77,6 +76,19 @@
   ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION));
 }
 
+IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest,
+                       SaveAsImageForCanvas) {
+  content::ContextMenuParams params;
+  params.media_type = blink::WebContextMenuData::MediaTypeCanvas;
+
+  TestRenderViewContextMenu menu(
+      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
+      params);
+  menu.Init();
+
+  ASSERT_TRUE(menu.IsItemPresent(IDC_CONTENT_CONTEXT_SAVEIMAGEAS));
+}
+
 // GTK requires a X11-level mouse event to open a context menu correctly.
 #if defined(TOOLKIT_GTK)
 #define MAYBE_RealMenu DISABLED_RealMenu
@@ -101,10 +113,9 @@
   mouse_event.button = blink::WebMouseEvent::ButtonRight;
   mouse_event.x = 15;
   mouse_event.y = 15;
-  gfx::Rect offset;
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
-  tab->GetView()->GetContainerBounds(&offset);
+  gfx::Rect offset = tab->GetContainerBounds();
   mouse_event.globalX = 15 + offset.x();
   mouse_event.globalY = 15 + offset.y();
   mouse_event.clickCount = 1;
diff --git a/chrome/browser/renderer_context_menu/spelling_menu_observer.cc b/chrome/browser/renderer_context_menu/spelling_menu_observer.cc
index dff5965..bbce83d 100644
--- a/chrome/browser/renderer_context_menu/spelling_menu_observer.cc
+++ b/chrome/browser/renderer_context_menu/spelling_menu_observer.cc
@@ -25,7 +25,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/context_menu_params.h"
 #include "extensions/browser/view_type_utils.h"
 #include "grit/generated_resources.h"
@@ -300,7 +299,7 @@
       gfx::Rect rect = rvh->GetView()->GetViewBounds();
       chrome::ShowConfirmBubble(
 #if defined(TOOLKIT_VIEWS)
-          proxy_->GetWebContents()->GetView()->GetTopLevelNativeWindow(),
+          proxy_->GetWebContents()->GetTopLevelNativeWindow(),
 #else
           rvh->GetView()->GetNativeView(),
 #endif
diff --git a/chrome/browser/renderer_context_menu/spelling_menu_observer_browsertest.cc b/chrome/browser/renderer_context_menu/spelling_menu_observer_browsertest.cc
index 1cde7c6..59d1372 100644
--- a/chrome/browser/renderer_context_menu/spelling_menu_observer_browsertest.cc
+++ b/chrome/browser/renderer_context_menu/spelling_menu_observer_browsertest.cc
@@ -232,6 +232,16 @@
     observer_->InitMenu(params);
   }
 
+  void ForceSuggestMode() {
+    menu()->GetPrefs()->SetBoolean(prefs::kSpellCheckUseSpellingService, true);
+    // Force a non-empty and non-"en" locale so SUGGEST is available.
+    menu()->GetPrefs()->SetString(prefs::kSpellCheckDictionary, "fr");
+    ASSERT_TRUE(SpellingServiceClient::IsAvailable(
+        menu()->GetProfile(), SpellingServiceClient::SUGGEST));
+    ASSERT_FALSE(SpellingServiceClient::IsAvailable(
+        menu()->GetProfile(), SpellingServiceClient::SPELLCHECK));
+  }
+
   virtual ~SpellingMenuObserverTest();
   MockRenderViewContextMenu* menu() { return menu_.get(); }
   SpellingMenuObserver* observer() { return observer_.get(); }
@@ -323,15 +333,7 @@
 // Test that there will be a separator after "no suggestions" if
 // SpellingServiceClient::SUGGEST is on.
 IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, SeparatorAfterSuggestions) {
-  menu()->GetPrefs()->SetBoolean(prefs::kSpellCheckUseSpellingService, true);
-  CommandLine* command_line = CommandLine::ForCurrentProcess();
-  command_line->AppendSwitch(switches::kUseSpellingSuggestions);
-
-  // Force a non-empty locale so SUGGEST is available.
-  menu()->GetPrefs()->SetString(prefs::kSpellCheckDictionary, "en");
-  EXPECT_TRUE(SpellingServiceClient::IsAvailable(menu()->GetProfile(),
-    SpellingServiceClient::SUGGEST));
-
+  ForceSuggestMode();
   InitMenu("jhhj", NULL);
 
   // The test should see a top separator, "No spelling suggestions",
@@ -467,9 +469,7 @@
 
   // Case #3. Misspelled word, suggestion service is on.
   Reset(false);
-  menu()->GetPrefs()->SetBoolean(prefs::kSpellCheckUseSpellingService, true);
-  CommandLine* command_line = CommandLine::ForCurrentProcess();
-  command_line->AppendSwitch(switches::kUseSpellingSuggestions);
+  ForceSuggestMode();
   InitMenu("asdfkj", NULL);
 
   // Should have at least 2 entries. Separator, suggestion.
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
index 819a381..2a3e134 100644
--- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
@@ -36,7 +36,7 @@
 #include "chrome/browser/ui/login/login_prompt.h"
 #include "chrome/browser/ui/sync/one_click_signin_helper.h"
 #include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/mime_types_handler.h"
+#include "chrome/common/extensions/manifest_handlers/mime_types_handler.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/renderer_host/offline_resource_throttle.cc b/chrome/browser/renderer_host/offline_resource_throttle.cc
index 598debd..f37b998 100644
--- a/chrome/browser/renderer_host/offline_resource_throttle.cc
+++ b/chrome/browser/renderer_host/offline_resource_throttle.cc
@@ -119,8 +119,8 @@
 
 bool OfflineResourceThrottle::IsRemote(const GURL& url) const {
   return !net::IsLocalhost(url.host()) && (url.SchemeIs(content::kFtpScheme) ||
-                                           url.SchemeIs(content::kHttpScheme) ||
-                                           url.SchemeIs(content::kHttpsScheme));
+                                           url.SchemeIs(url::kHttpScheme) ||
+                                           url.SchemeIs(url::kHttpsScheme));
 }
 
 bool OfflineResourceThrottle::ShouldShowOfflinePage(const GURL& url) const {
diff --git a/chrome/browser/resources/PRESUBMIT.py b/chrome/browser/resources/PRESUBMIT.py
deleted file mode 100644
index 831864c..0000000
--- a/chrome/browser/resources/PRESUBMIT.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (c) 2012 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.
-
-"""Presubmit script for Chromium WebUI resources.
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
-for more details about the presubmit API built into gcl/git cl, and see
-http://www.chromium.org/developers/web-development-style-guide for the rules
-we're checking against here.
-"""
-
-
-def CheckChangeOnUpload(input_api, output_api):
-  return _CommonChecks(input_api, output_api)
-
-
-def CheckChangeOnCommit(input_api, output_api):
-  return _CommonChecks(input_api, output_api)
-
-
-def _CommonChecks(input_api, output_api):
-  """Checks common to both upload and commit."""
-  results = []
-  resources = input_api.PresubmitLocalPath()
-
-  path = input_api.os_path
-  affected_files = (f.AbsoluteLocalPath() for f in input_api.AffectedFiles())
-  would_affect_tests = (
-      path.join(resources, 'PRESUBMIT.py'),
-      path.join(resources, 'test_presubmit.py'),
-      path.join(resources, 'web_dev_style', 'css_checker.py'),
-      path.join(resources, 'web_dev_style', 'js_checker.py'),
-  )
-  if any(f for f in affected_files if f in would_affect_tests):
-    tests = [path.join(resources, 'test_presubmit.py')]
-    results.extend(
-        input_api.canned_checks.RunUnitTests(input_api, output_api, tests))
-
-  import sys
-  old_path = sys.path
-
-  try:
-    sys.path = [resources] + old_path
-    from web_dev_style import css_checker, js_checker
-
-    def _html_css_js_resource(p):
-      return p.endswith(('.html', '.css', '.js')) and p.startswith(resources)
-
-    BLACKLIST = ['chrome/browser/resources/pdf/index.html',
-                 'chrome/browser/resources/pdf/index.js']
-    def is_resource(maybe_resource):
-      return (maybe_resource.LocalPath() not in BLACKLIST and
-          _html_css_js_resource(maybe_resource.AbsoluteLocalPath()))
-
-    results.extend(css_checker.CSSChecker(
-        input_api, output_api, file_filter=is_resource).RunChecks())
-    results.extend(js_checker.JSChecker(
-        input_api, output_api, file_filter=is_resource).RunChecks())
-  finally:
-    sys.path = old_path
-
-  return results
diff --git a/chrome/browser/resources/about_sys/about_sys.js b/chrome/browser/resources/about_sys/about_sys.js
index d7edc31..46627db 100644
--- a/chrome/browser/resources/about_sys/about_sys.js
+++ b/chrome/browser/resources/about_sys/about_sys.js
@@ -149,7 +149,7 @@
       value = lines[i].substring(delimiter + 1);
 
     // Delimiters are based on kMultilineIndicatorString, kMultilineStartString,
-    // and kMultilineEndString in chrome/browser/feedback/feedback_data.cc.
+    // and kMultilineEndString in components/feedback/feedback_data.cc.
     // If these change, we should check for both the old and new versions.
     if (value == '<multiline>') {
       // Skip start delimiter.
diff --git a/chrome/browser/resources/chromeos/braille_ime/OWNERS b/chrome/browser/resources/chromeos/braille_ime/OWNERS
new file mode 100644
index 0000000..dfab84a
--- /dev/null
+++ b/chrome/browser/resources/chromeos/braille_ime/OWNERS
@@ -0,0 +1,4 @@
+aboxhall@chromium.org
+dmazzoni@chromium.org
+dtseng@chromium.org
+plundblad@chromium.org
diff --git a/chrome/browser/resources/chromeos/braille_ime/PRESUBMIT.py b/chrome/browser/resources/chromeos/braille_ime/PRESUBMIT.py
new file mode 100644
index 0000000..2a6d3ab
--- /dev/null
+++ b/chrome/browser/resources/chromeos/braille_ime/PRESUBMIT.py
@@ -0,0 +1,25 @@
+# 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.
+
+"""Presubmit script for the Braille IME."""
+
+def CheckChangeOnUpload(input_api, output_api):
+  def FileFilter(path):
+    return path.endswith('.js') or path.endswith('check_braille_ime.py')
+  if not any((FileFilter(p) for p in input_api.LocalPaths())):
+    return []
+  import sys
+  if not sys.platform.startswith('linux'):
+    return []
+  sys.path.insert(0, input_api.PresubmitLocalPath())
+  try:
+    from check_braille_ime import check_braille_ime
+  finally:
+    sys.path.pop(0)
+  success, output = check_braille_ime()
+  if not success:
+    return [output_api.PresubmitError(
+        'Braille IME closure compilation failed',
+        long_text=output)]
+  return []
diff --git a/chrome/browser/resources/chromeos/braille_ime/braille_ime.js b/chrome/browser/resources/chromeos/braille_ime/braille_ime.js
new file mode 100644
index 0000000..885f6df
--- /dev/null
+++ b/chrome/browser/resources/chromeos/braille_ime/braille_ime.js
@@ -0,0 +1,413 @@
+// 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.
+
+'use strict';
+
+/**
+ * @fileoverview Braille hardware keyboard input method.
+ *
+ * This method is automatically enabled when a braille display is connected
+ * and ChromeVox is turned on.  Most of the braille input and editing logic
+ * is located in ChromeVox where the braille translation library is available.
+ * This IME connects to ChromeVox and communicates using messages as follows:
+ *
+ * Sent from this IME to ChromeVox:
+ * {type: 'activeState', active: boolean}
+ * {type: 'inputContext', context: InputContext}
+ *   Sent on focus/blur to inform ChromeVox of the type of the current field.
+ *   In the latter case (blur), context is null.
+ * {type: 'reset'}
+ *   Sent when the {code onReset} IME event fires.
+ * {type: 'brailleDots', dots: number}
+ *   Sent when the user typed a braille cell using the standard keyboard.
+ *   ChromeVox treats this similarly to entering braille input using the
+ *   braille display.
+ *
+ * Sent from ChromeVox to this IME:
+ * {type: 'replaceText', contextID: number, deleteBefore: number,
+ *  newText: string}
+ *   Deletes {@code deleteBefore} characters before the cursor (or selection)
+ *   and inserts {@code newText}.  {@code contextID} identifies the text field
+ *   to apply the update to (no change will happen if focus has moved to a
+ *   different field).
+ */
+
+/**
+ * @constructor
+ */
+var BrailleIme = function() {};
+
+BrailleIme.prototype = {
+  /**
+   * Whether to enable extra debug logging for the IME.
+   * @const {boolean}
+   * @private
+   */
+  DEBUG: false,
+
+  /**
+   * ChromeVox extension ID.
+   * @const {string}
+   * @private
+   */
+  CHROMEVOX_EXTENSION_ID_: 'mndnfokpggljbaajbnioimlmbfngpief',
+
+  /**
+   * Name of the port used for communication with ChromeVox.
+   * @const {string}
+   * @private
+   */
+  PORT_NAME: 'cvox.BrailleIme.Port',
+
+  /**
+   * Identifier for the use standard keyboard option used in the menu and
+   * {@code localStorage}.  This can be switched on to type braille using the
+   * standard keyboard, or off (default) for the usual keyboard behaviour.
+   * @const {string}
+   */
+  USE_STANDARD_KEYBOARD_ID: 'useStandardKeyboard',
+
+  // State related to the support for typing braille using a standrad
+  // (querty) keyboard.
+
+  /** @private {boolean} */
+  useStandardKeyboard_: false,
+
+  /**
+   * Braille dots for keys that are currently pressed.
+   * @private {number}
+   */
+  pressed_: 0,
+
+  /**
+   * Dots that have been pressed at some point since {@code pressed_} was last
+   * {@code 0}.
+   * @private {number}
+   */
+  accumulated_: 0,
+
+  /**
+   * Maps key codes on a standard keyboard to the correspodning dots.
+   * Keys on the 'home row' correspond to the keys on a Perkins-style keyboard.
+   * Note that the mapping below is arranged like the dots in a braille cell.
+   * Only 6 dot input is supported.
+   * @private
+   * @const {Object.<string, string>}
+   */
+  CODE_TO_DOT_: {'KeyF': 0x01, 'KeyJ': 0x08,
+                 'KeyD': 0x02, 'KeyK': 0x10,
+                 'KeyS': 0x04, 'KeyL': 0x20 },
+
+  /**
+   * The current engine ID as set by {@code onActivate}, or the empty string if
+   * the IME is not active.
+   * @type {string}
+   * @private
+   */
+  engineID_: '',
+
+  /**
+   * The port used to communicate with ChromeVox.
+   * @type {Port} port_
+   * @private
+   */
+  port_: null,
+
+  /**
+   * Registers event listeners in the chrome IME API.
+   */
+  init: function() {
+    chrome.input.ime.onActivate.addListener(this.onActivate_.bind(this));
+    chrome.input.ime.onDeactivated.addListener(this.onDeactivated_.bind(this));
+    chrome.input.ime.onFocus.addListener(this.onFocus_.bind(this));
+    chrome.input.ime.onBlur.addListener(this.onBlur_.bind(this));
+    chrome.input.ime.onInputContextUpdate.addListener(
+        this.onInputContextUpdate_.bind(this));
+    chrome.input.ime.onKeyEvent.addListener(this.onKeyEvent_.bind(this));
+    chrome.input.ime.onReset.addListener(this.onReset_.bind(this));
+    chrome.input.ime.onMenuItemActivated.addListener(
+        this.onMenuItemActivated_.bind(this));
+    this.connectChromeVox_();
+  },
+
+  /**
+   * Called by the IME framework when this IME is activated.
+   * @param {string} engineID Engine ID, should be 'braille'.
+   * @private
+   */
+  onActivate_: function(engineID) {
+    this.log_('onActivate', engineID);
+    this.engineID_ = engineID;
+    if (!this.port_) {
+      this.connectChromeVox_();
+    }
+    this.useStandardKeyboard_ =
+        localStorage[this.USE_STANDARD_KEYBOARD_ID] === String(true);
+    this.accumulated_ = 0;
+    this.pressed_ = 0;
+    this.updateMenuItems_();
+    this.sendActiveState_();
+  },
+
+  /**
+   * Called by the IME framework when this IME is deactivated.
+   * @param {string} engineID Engine ID, should be 'braille'.
+   * @private
+   */
+  onDeactivated_: function(engineID) {
+    this.log_('onDectivated', engineID);
+    this.engineID_ = '';
+    this.sendActiveState_();
+  },
+
+  /**
+   * Called by the IME framework when a text field receives focus.
+   * @param {InputContext} context Input field context.
+   * @private
+   */
+  onFocus_: function(context) {
+    this.log_('onFocus', JSON.stringify(context));
+    this.sendInputContext_(context);
+  },
+
+  /**
+   * Called by the IME framework when a text field looses focus.
+   * @param {number} contextID Input field context ID.
+   * @private
+   */
+  onBlur_: function(contextID) {
+    this.log_('onBlur', contextID + '');
+    this.sendInputContext_(null);
+  },
+
+  /**
+   * Called by the IME framework when the current input context is updated.
+   * @param {InputContext} context Input field context.
+   * @private
+   */
+  onInputContextUpdate_: function(context) {
+    this.log_('onInputContextUpdate', JSON.stringify(context));
+    this.sendInputContext_(context);
+  },
+
+  /**
+   * Called by the system when this IME is active and a key event is generated.
+   * @param {string} engineID Engine ID, should be 'braille'.
+   * @param {!ChromeKeyboardEvent} event The keyboard event.
+   * @return {boolean} Whether the event was handled by this IME (true) or
+   *     should be allowed to propagate.
+   * @private
+   */
+  onKeyEvent_: function(engineID, event) {
+    this.log_('onKeyEvent', engineID + ', ' + JSON.stringify(event));
+    return this.processKey_(event.code, event.type);
+  },
+
+  /**
+   * Called when chrome ends the current text input session.
+   * @param {string} engineID Engine ID, should be 'braille'.
+   * @private
+   */
+  onReset_: function(engineID) {
+    this.log_('onReset', engineID);
+    this.engineID_ = engineID;
+    this.sendToChromeVox_({type: 'reset'});
+  },
+
+  /**
+   * Called by the IME framework when a menu item is activated.
+   * @param {string} engineID Engine ID, should be 'braille'.
+   * @param {string} itemID Identifies the menu item.
+   * @private
+   */
+  onMenuItemActivated_: function(engineID, itemID) {
+    if (engineID === this.engineID_ &&
+        itemID === this.USE_STANDARD_KEYBOARD_ID) {
+      this.useStandardKeyboard_ = !this.useStandardKeyboard_;
+      localStorage[this.USE_STANDARD_KEYBOARD_ID] =
+          String(this.useStandardKeyboard_);
+      if (!this.useStandardKeyboard_) {
+        this.accumulated_ = 0;
+        this.pressed_ = 0;
+      }
+      this.updateMenuItems_();
+    }
+  },
+
+  /**
+   * Outputs a log message to the console, only if {@link BrailleIme.DEBUG}
+   * is set to true.
+   * @param {string} func Name of the caller.
+   * @param {string} message Message to output.
+   * @private
+   */
+  log_: function(func, message) {
+    if (func === 'onKeyEvent') {
+      return;
+    }
+    if (this.DEBUG) {
+      console.log('BrailleIme.' + func + ': ' + message);
+    }
+  },
+
+  /**
+   * Handles a querty key on the home row as a braille key.
+   * @param {string} code Key code.
+   * @param {string} type Type of key event.
+   * @return {boolean} Whether the key event was handled or not.
+   * @private
+   */
+  processKey_: function(code, type) {
+    if (!this.useStandardKeyboard_) {
+      return false;
+    }
+    var dot = this.CODE_TO_DOT_[code];
+    if (!dot) {
+      this.pressed_ = 0;
+      this.accumulated_ = 0;
+      return false;
+    }
+    if (type === 'keydown') {
+      this.pressed_ |= dot;
+      this.accumulated_ |= this.pressed_;
+      return true;
+    } else if (type == 'keyup') {
+      this.pressed_ &= ~dot;
+      if (this.pressed_ == 0 && this.accumulated_ != 0) {
+        this.sendToChromeVox_({type: 'brailleDots', dots: this.accumulated_});
+        this.accumulated_ = 0;
+      }
+      return true;
+    }
+    return false;
+  },
+
+  /**
+   * Connects to the ChromeVox extension for message passing.
+   * @private
+   */
+  connectChromeVox_: function() {
+    if (this.port_) {
+      this.port_.disconnect();
+      this.port_ = null;
+    }
+    this.port_ = chrome.runtime.connect(
+        this.CHROMEVOX_EXTENSION_ID_, {name: this.PORT_NAME});
+    this.port_.onMessage.addListener(
+        this.onChromeVoxMessage_.bind(this));
+    this.port_.onDisconnect.addListener(
+        this.onChromeVoxDisconnect_.bind(this));
+  },
+
+  /**
+   * Handles a message from the ChromeVox extension.
+   * @param {*} message The message from the extension.
+   * @private
+   */
+  onChromeVoxMessage_: function(message) {
+    this.log_('onChromeVoxMessage', JSON.stringify(message));
+    message = /** @type {{type: string}} */ (message);
+    switch (message.type) {
+      case 'replaceText':
+        message =
+            /**
+             * @type {{contextID: number, deleteBefore: number,
+             *         newText: string}}
+             */
+            (message);
+        this.replaceText_(message.contextID, message.deleteBefore,
+                          message.newText);
+        break;
+    }
+  },
+
+  /**
+   * Handles a disconnect event from the ChromeVox side.
+   * @private
+   */
+  onChromeVoxDisconnect_: function() {
+    this.port_ = null;
+    this.log_('onChromeVoxDisconnect',
+              JSON.stringify(chrome.runtime.lastError));
+  },
+
+  /**
+   * Sends a message to the ChromeVox extension.
+   * @param {Object} message The message to send.
+   * @private
+   */
+  sendToChromeVox_: function(message) {
+    if (this.port_) {
+      this.port_.postMessage(message);
+    }
+  },
+
+  /**
+   * Sends the given input context to ChromeVox.
+   * @param {InputContext} context Input context, or null when there's no input
+   *    context.
+   * @private
+   */
+  sendInputContext_: function(context) {
+    this.sendToChromeVox_({type: 'inputContext', context: context});
+  },
+
+  /**
+   * Sends the active state to ChromeVox.
+   * @private
+   */
+  sendActiveState_: function() {
+    this.sendToChromeVox_({type: 'activeState',
+                           active: this.engineID_.length > 0});
+  },
+
+  /**
+   * Replaces text in the current text field.
+   * @param {number} contextID Context for the input field to replace the
+   *     text in.
+   * @param {number} deleteBefore How many characters to delete before the
+   *     cursor.
+   * @param {string} toInsert Text to insert at the cursor.
+   */
+  replaceText_: function(contextID, deleteBefore, toInsert) {
+    var addText = function() {
+      chrome.input.ime.commitText(
+          {contextID: contextID, text: toInsert});
+    }.bind(this);
+    if (deleteBefore > 0) {
+      var deleteText = function() {
+        chrome.input.ime.deleteSurroundingText(
+            {engineID: this.engineID_, contextID: contextID,
+             offset: -deleteBefore, length: deleteBefore}, addText);
+      }.bind(this);
+      // Make sure there's no non-zero length selection so that
+      // deleteSurroundingText works correctly.
+      chrome.input.ime.deleteSurroundingText(
+          {engineID: this.engineID_, contextID: contextID,
+           offset: 0, length: 0}, deleteText);
+    } else {
+      addText();
+    }
+  },
+
+  /**
+   * Updates the menu items for this IME.
+   */
+  updateMenuItems_: function() {
+    // TODO(plundblad): Localize when translations available.
+    chrome.input.ime.setMenuItems(
+        {engineID: this.engineID_,
+         items: [
+           {
+             id: this.USE_STANDARD_KEYBOARD_ID,
+             label: 'Use standard keyboard for braille',
+             style: 'check',
+             visible: true,
+             checked: this.useStandardKeyboard_,
+             enabled: true
+             }
+         ]
+        });
+  }
+};
diff --git a/chrome/browser/resources/chromeos/braille_ime/braille_ime_unittest.gtestjs b/chrome/browser/resources/chromeos/braille_ime/braille_ime_unittest.gtestjs
new file mode 100644
index 0000000..d011ee1
--- /dev/null
+++ b/chrome/browser/resources/chromeos/braille_ime/braille_ime_unittest.gtestjs
@@ -0,0 +1,216 @@
+// 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.
+
+/**
+ * @fileoverview Unit test for the Braille IME.
+ */
+
+/**
+ * Mock Chrome event supporting one listener.
+ * @constructor
+ */
+function MockEvent() {}
+
+MockEvent.prototype = {
+  /** @type {Function?} */
+  listener: null,
+
+  /**
+   * @param {Function} listener
+   */
+  addListener: function(listener) {
+    assertTrue(this.listener === null);
+    this.listener = listener;
+  },
+
+  /**
+   * Dispatches an event to the listener if any.
+   * @param {...*} var_args Arguments to pass to the event listener.
+   * @return {*} Return value from listener or {@code undefined} if no
+   *     listener.
+   */
+  dispatch: function() {
+    if (this.listener) {
+      return this.listener.apply(null, arguments);
+    }
+  }
+};
+
+/**
+ * Mock port that supports the {@code onMessage} and {@code onDisconnect}
+ * events as well as {@code postMessage}.
+ * @constructor.
+ */
+function MockPort() {
+  this.onMessage = new MockEvent();
+  this.onDisconnect = new MockEvent();
+  /** @type {Array.<Object>} */
+  this.messages = [];
+}
+
+MockPort.prototype = {
+  /**
+   * Stores {@code message} in this object.
+   * @param {Object} message Message to store.
+   */
+  postMessage: function(message) {
+    this.messages.push(message);
+  }
+};
+
+/**
+ * Engine ID as specified in manifest.
+ * @const {string}
+ */
+ENGINE_ID = 'braille';
+
+var localStorage;
+
+/**
+ * Test fixture for the braille IME unit test.
+ * @constructor
+ * @extends {testing.Test}
+ */
+function BrailleImeUnitTest() {
+  testing.Test.call(this);
+}
+
+BrailleImeUnitTest.prototype = {
+  __proto__: testing.Test.prototype,
+
+  /** @Override */
+  extraLibraries: [
+    'braille_ime.js'
+  ],
+
+  /** @Override */
+  setUp: function() {
+    chrome = chrome || {};
+    chrome.input = chrome.input || {};
+    chrome.input.ime = chrome.input.ime || {};
+    chrome.runtime = chrome.runtime || {};
+    localStorage = {};
+    this.createIme();
+  },
+
+  createIme: function() {
+    var IME_EVENTS = [ 'onActivate', 'onDeactivated', 'onFocus', 'onBlur',
+                       'onInputContextUpdate', 'onKeyEvent', 'onReset',
+                       'onMenuItemActivated' ];
+    for (var i = 0, name; name = IME_EVENTS[i]; ++i) {
+      this[name] = chrome.input.ime[name] = new MockEvent();
+
+    }
+    chrome.input.ime.setMenuItems = function(parameters) {
+      this.menuItems = parameters.items;
+    }.bind(this);
+    chrome.runtime.connect = function() {
+      this.port = new MockPort();
+      return this.port;
+    }.bind(this);
+    this.menuItems = null;
+    this.port = null;
+    this.ime = new BrailleIme();
+    this.ime.init();
+  },
+
+  activateIme: function() {
+    this.onActivate.dispatch(ENGINE_ID);
+    assertThat(this.port.messages,
+               eqJSON([{type: 'activeState', active: true}]));
+    this.port.messages.length = 0;
+  },
+
+  sendKeyDown: function(code) {
+    return this.onKeyEvent.dispatch(ENGINE_ID, {code: code, type: 'keydown'});
+  },
+
+  sendKeyUp: function(code) {
+    return this.onKeyEvent.dispatch(ENGINE_ID, {code: code, type: 'keyup'});
+  },
+};
+
+TEST_F('BrailleImeUnitTest', 'KeysWhenStandardKeyboardDisabled', function() {
+  this.activateIme();
+  expectFalse(this.sendKeyDown('KeyF'));
+  expectFalse(this.sendKeyDown('KeyD'));
+  expectFalse(this.sendKeyUp('KeyD'));
+  expectFalse(this.sendKeyUp('KeyF'));
+  expectEquals(0, this.port.messages.length);
+});
+
+TEST_F('BrailleImeUnitTest', 'KeysWhenStandardKeysEnabled', function() {
+  this.activateIme();
+  assertFalse(this.menuItems[0].checked);
+  this.onMenuItemActivated.dispatch(ENGINE_ID, this.menuItems[0].id);
+  assertTrue(this.menuItems[0].checked);
+  // Type the letters 'b' and 'c' and verify the right dots get sent.
+  expectTrue(this.sendKeyDown('KeyF'));
+  expectTrue(this.sendKeyDown('KeyD'));
+  expectTrue(this.sendKeyUp('KeyD'));
+  expectTrue(this.sendKeyUp('KeyF'));
+  expectTrue(this.sendKeyDown('KeyJ'));
+  expectTrue(this.sendKeyDown('KeyF'));
+  expectTrue(this.sendKeyUp('KeyJ'));
+  expectTrue(this.sendKeyUp('KeyF'));
+  // Make sure that other keys are not handled, either by themselves or while
+  // one of the 'braille keys' is pressed.
+  expectFalse(this.sendKeyDown('KeyX'));
+  expectFalse(this.sendKeyUp('KeyX'));
+
+  expectTrue(this.sendKeyDown('KeyS'));  // Dot 3
+  expectFalse(this.sendKeyDown('KeyG'));  // To the right of dot 1.
+  expectTrue(this.sendKeyUp('KeyS'));
+  expectFalse(this.sendKeyUp('KeyG'));
+
+  assertThat(this.port.messages,
+             eqJSON([{type: 'brailleDots', dots: 0x03},
+                     {type: 'brailleDots', dots: 0x09}]));
+});
+
+TEST_F('BrailleImeUnitTest', 'UseStandardKeyboardSettingPreserved', function() {
+  this.activateIme();
+  assertFalse(this.menuItems[0].checked);
+  this.onMenuItemActivated.dispatch(ENGINE_ID, this.menuItems[0].id);
+  assertTrue(this.menuItems[0].checked);
+  // Create a new instance and make sure the setting is still turned on.
+  console.log('localStorage: ' + JSON.stringify(localStorage));
+  this.createIme();
+  this.activateIme();
+  assertTrue(this.menuItems[0].checked);
+});
+
+TEST_F('BrailleImeUnitTest', 'ReplaceText', function() {
+  var CONTEXT_ID = 1;
+  var hasSelection = false;
+  var text = 'Hi, ';
+  chrome.input.ime.commitText = function(params) {
+    assertEquals(CONTEXT_ID, params.contextID);
+    text += params.text;
+  };
+  chrome.input.ime.deleteSurroundingText = function(params, callback) {
+    assertEquals(ENGINE_ID, params.engineID);
+    assertEquals(CONTEXT_ID, params.contextID);
+    assertEquals(0, params.offset + params.length);
+    if (hasSelection) {
+      assertEquals(0, params.length);
+      hasSelection = false;
+    } else {
+      text = text.slice(0, params.offset);
+    }
+    callback();
+  };
+  var sendReplaceText = function(deleteBefore, newText) {
+    this.port.onMessage.dispatch(
+        {type: 'replaceText', contextID: CONTEXT_ID,
+       deleteBefore: deleteBefore, newText: newText});
+  }.bind(this);
+  this.activateIme();
+  sendReplaceText(0, 'hello!');
+  assertEquals('Hi, hello!', text);
+  hasSelection = true;
+  sendReplaceText('hello!'.length, 'good bye!');
+  assertFalse(hasSelection);
+  assertEquals('Hi, good bye!', text);
+});
diff --git a/chrome/browser/resources/chromeos/braille_ime/check_braille_ime.py b/chrome/browser/resources/chromeos/braille_ime/check_braille_ime.py
new file mode 100755
index 0000000..9e72cb9
--- /dev/null
+++ b/chrome/browser/resources/chromeos/braille_ime/check_braille_ime.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+# 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.
+
+'''Uses the closure compiler to check the braille ime.'''
+
+import os
+import re
+import subprocess
+import sys
+import tempfile
+
+
+# Compiler path, relative to Chromium repository root.
+_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+_CLOSURE_COMPILER_JAR = os.path.normpath(
+    os.path.join(
+        _SCRIPT_DIR, '../../../../..',
+        'third_party/WebKit/Source/devtools/scripts/closure/compiler.jar'))
+# List of compilation errors to enable with the --jscomp_errors flag.
+_JSCOMP_ERRORS = [ 'accessControls', 'checkTypes', 'checkVars', 'invalidCasts',
+                   'missingProperties', 'undefinedNames', 'undefinedVars',
+                   'visibility' ]
+
+_java_executable = 'java'
+
+
+def _error(msg):
+  print >>sys.stderr, msg
+  sys.exit(1)
+
+
+def _execute_command(args, ignore_exit_status=False):
+  try:
+    return subprocess.check_output(args, stderr=subprocess.STDOUT)
+  except subprocess.CalledProcessError as e:
+    if ignore_exit_status and e.returncode > 0:
+      return e.output
+    _error('%s\nCommand \'%s\' returned non-zero exit status %d' %
+           (e.output, ' '.join(e.cmd), e.returncode))
+  except (OSError, IOError) as e:
+    _error('Error executing %s: %s' % (_java_executable, str(e)))
+
+
+def _check_java():
+  global _java_executable
+  java_home = os.environ.get('JAVAHOME')
+  if java_home is not None:
+    _java_executable = os.path.join(java_home, 'bin/java')
+  output = _execute_command([_java_executable, '-version'])
+  match = re.search(r'version "(?:\d+)\.(\d+)', output)
+  if match is None or int(match.group(1)) < 7:
+    _error('Java 7 or later is required: \n%s' % output)
+
+
+def _run_closure_compiler():
+  print 'Compiling Braille IME.'
+  args = [_java_executable, '-jar', _CLOSURE_COMPILER_JAR]
+  args.extend(['--compilation_level', 'SIMPLE_OPTIMIZATIONS'])
+  args.extend(['--jscomp_error=%s' % error for error in _JSCOMP_ERRORS])
+  args.extend(['--externs', 'externs.js'])
+  args.extend(['--js', 'braille_ime.js'])
+  args.extend(['--js', 'main.js'])
+  args.extend(['--js_output_file', '/dev/null'])
+  output = _execute_command(args, ignore_exit_status=True)
+  success = len(output) == 0
+  return success, output
+
+
+def check_braille_ime():
+  _check_java()
+  return _run_closure_compiler()
+
+
+def main(argv):
+  success, output = check_braille_ime()
+  print output
+  return int(not success)
+
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/chrome/browser/resources/chromeos/braille_ime/externs.js b/chrome/browser/resources/chromeos/braille_ime/externs.js
new file mode 100644
index 0000000..b67dd28
--- /dev/null
+++ b/chrome/browser/resources/chromeos/braille_ime/externs.js
@@ -0,0 +1,170 @@
+// 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.
+
+/**
+ * @fileoverview Externs for the braille IME.
+ * @externs
+ */
+
+/**
+ * @const
+ */
+chrome.input = {};
+
+/** @const */
+chrome.input.ime = {};
+
+/**
+ * @constructor
+ */
+function ChromeInputImeOnKeyEventEvent() {}
+
+/**
+ * @param {function(string, !ChromeKeyboardEvent): (boolean|undefined)} callback
+ * @param {Array.<string>=} opt_extraInfoSpec
+ */
+ChromeInputImeOnKeyEventEvent.prototype.addListener =
+    function(callback, opt_extraInfoSpec) {};
+
+/**
+ * @param {!Object.<string,(string|number)>} parameters An object with
+ *     'contextID' (number) and 'text' (string) keys.
+ * @param {function(boolean): void=} opt_callback Callback function.
+ */
+chrome.input.ime.commitText = function(parameters, opt_callback) {};
+
+/**
+ * @param {!Object.<string,(string|number)>} parameters An object with
+ *     'contextID' (number) and 'text' (string) keys.
+ * @param {function(boolean): void=} opt_callback Callback function.
+ */
+chrome.input.ime.deleteSurroundingText = function(parameters, opt_callback) {};
+
+/**
+ * @param {{engineID: string, items: Array.<chrome.input.ime.MenuItem>}}
+ *     parameters
+ * @param {function()=} opt_callback
+ */
+chrome.input.ime.setMenuItems = function(parameters, opt_callback) {};
+
+/** @type {!ChromeEvent} */
+chrome.input.ime.onActivate;
+
+/** @type {!ChromeEvent} */
+chrome.input.ime.onBlur;
+
+/** @type {!ChromeEvent} */
+chrome.input.ime.onDeactivated;
+
+/** @type {!ChromeEvent} */
+chrome.input.ime.onFocus;
+
+/** @type {!ChromeEvent} */
+chrome.input.ime.onInputContextUpdate;
+
+/** @type {!ChromeInputImeOnKeyEventEvent} */
+chrome.input.ime.onKeyEvent;
+
+/** @type {!ChromeEvent} */
+chrome.input.ime.onMenuItemActivated;
+
+/** @type {!ChromeEvent} */
+chrome.input.ime.onReset;
+
+/**
+ * @const
+ */
+chrome.runtime = {};
+
+/** @type {!Object|undefined} */
+chrome.runtime.lastError = {};
+
+/**
+ * @param {string|!Object.<string>=} opt_extensionIdOrConnectInfo Either the
+ *     extensionId to connect to, in which case connectInfo params can be
+ *     passed in the next optional argument, or the connectInfo params.
+ * @param {!Object.<string>=} opt_connectInfo The connectInfo object,
+ *     if arg1 was the extensionId to connect to.
+ * @return {!Port} New port.
+ */
+chrome.runtime.connect = function(
+    opt_extensionIdOrConnectInfo, opt_connectInfo) {};
+
+/**
+ * @constructor
+ */
+function Port() {}
+
+/** @type {ChromeEvent} */
+Port.prototype.onDisconnect;
+
+/** @type {ChromeEvent} */
+Port.prototype.onMessage;
+
+/**
+ * @param {Object.<string>} obj Message object.
+ */
+Port.prototype.postMessage = function(obj) {};
+
+/**
+ * Note: as of 2012-04-12, this function is no longer documented on
+ * the public web pages, but there are still existing usages.
+ */
+Port.prototype.disconnect = function() {};
+
+/**
+ * @constructor
+ */
+function ChromeEvent() {}
+
+/** @param {Function} callback */
+ChromeEvent.prototype.addListener = function(callback) {};
+
+/**
+ * @constructor
+ */
+function ChromeKeyboardEvent() {}
+
+/** @type {string} */
+ChromeKeyboardEvent.prototype.type;
+
+/** @type {string} */
+ChromeKeyboardEvent.prototype.code;
+
+/** @type {boolean} */
+ChromeKeyboardEvent.prototype.altKey;
+
+/** @type {boolean} */
+ChromeKeyboardEvent.prototype.ctrlKey;
+
+/** @type {boolean} */
+ChromeKeyboardEvent.prototype.shiftKey;
+
+/**
+ * @constructor
+ */
+function InputContext() {}
+
+/** @type {number} */
+InputContext.prototype.contextID;
+
+/** @type {string} */
+InputContext.prototype.type;
+
+/**
+ * @typedef {{
+ *     id: string,
+ *     label: (string|undefined),
+ *     style: string,
+ *     visible: (boolean|undefined),
+ *     checked: (boolean|undefined),
+ *     enabled: (boolean|undefined)
+ * }}
+ */
+chrome.input.ime.MenuItem;
+
+/**
+ * @type {Object}
+ */
+var localStorage;
diff --git a/chrome/browser/resources/chromeos/braille_ime/main.js b/chrome/browser/resources/chromeos/braille_ime/main.js
new file mode 100644
index 0000000..603ee28
--- /dev/null
+++ b/chrome/browser/resources/chromeos/braille_ime/main.js
@@ -0,0 +1,11 @@
+// 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.
+
+/**
+ * The Braille IME object.  Attached to the window object for ease of
+ * debugging.
+ * @type {BrailleIme}
+ */
+window.ime = new BrailleIme();
+window.ime.init();
diff --git a/chrome/browser/resources/chromeos/braille_ime/manifest.json b/chrome/browser/resources/chromeos/braille_ime/manifest.json
new file mode 100644
index 0000000..3a95dce
--- /dev/null
+++ b/chrome/browser/resources/chromeos/braille_ime/manifest.json
@@ -0,0 +1,24 @@
+{
+  "name": "Braille IME",
+  "description": "Braille Input Method Extension.",
+  "version": "1.0",
+  "background": {
+    "scripts": [ "braille_ime.js", "main.js" ],
+    "persistent": true
+  },
+  // chrome-extension://jddehjeebkoimngcbdkaahpobgicbffp
+  "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvDjqqYESDQe3OcI65JctUYLSlQ7RAd902VUw+RO/70fJ7SSkg8+2y+5paD6+g8f6wgFsgVsbTX2UM+tsmGKWR23bgSQxYhfZUZgP7qFdk72hGRUnKnXA+JOJ5maI4v+w18WPTWYOFJt2NOvat+GKKF0CAFQG+z2Ucn/sRZVfnrQIDAQAB",
+  "manifest_version": 2,
+  "permissions": [
+    "input"
+  ],
+  "input_components": [
+    {
+      "name": "Braille Keyboard",
+      "type": "ime",
+      "id": "braille",
+      "language": ["None"],
+      "description": "Braille hardware keyboard"
+    }
+  ]
+}
diff --git a/chrome/browser/resources/chromeos/chromevox/manifest_guest.json b/chrome/browser/resources/chromeos/chromevox/manifest_guest.json
index ba8245c..d20b464 100644
--- a/chrome/browser/resources/chromeos/chromevox/manifest_guest.json
+++ b/chrome/browser/resources/chromeos/chromevox/manifest_guest.json
@@ -11,6 +11,8 @@
     "page": "chromevox/background/background.html"
   },
   "permissions": [
+    "accessibilityPrivate",
+    "automation",
     "bookmarks",
     "tabs",
     "experimental",
diff --git a/chrome/browser/resources/chromeos/echo/OWNERS b/chrome/browser/resources/chromeos/echo/OWNERS
index d3a0e8f..c197453 100644
--- a/chrome/browser/resources/chromeos/echo/OWNERS
+++ b/chrome/browser/resources/chromeos/echo/OWNERS
@@ -1,2 +1,5 @@
 gauravsh@chromium.org
 jorgelo@chromium.org
+stephenlin@chromium.org
+andycai@chromium.org
+oscarpan@chromium.org
diff --git a/chrome/browser/resources/chromeos/echo/manifest.json b/chrome/browser/resources/chromeos/echo/manifest.json
index af95398..a9f1a38 100644
--- a/chrome/browser/resources/chromeos/echo/manifest.json
+++ b/chrome/browser/resources/chromeos/echo/manifest.json
@@ -5,12 +5,13 @@
   "version": "1.0.0",
   "description": "Chrome Goodies",
   "manifest_version": 2,
-  "content_security_policy": "default-src 'self'; connect-src 'self' https://chromeos-registration.googleapis.com",
+  "content_security_policy": "default-src 'self'; connect-src 'self' https://chromeos-registration.googleapis.com; script-src 'self' https://ssl.google-analytics.com",
   "permissions": [
       "alarms",
       "cookies",
       "chromeosInfoPrivate",
       "echoPrivate",
+      "metricsPrivate",
       "notifications",
       "https://*/*"
    ],
diff --git a/chrome/browser/resources/chromeos/guest_session_tab.html b/chrome/browser/resources/chromeos/guest_session_tab.html
index c9bdec9..b7e92b0 100644
--- a/chrome/browser/resources/chromeos/guest_session_tab.html
+++ b/chrome/browser/resources/chromeos/guest_session_tab.html
@@ -18,7 +18,7 @@
   <img src="chrome://theme/IDR_CONTROLLED_SETTING_MANDATORY"/>
   <span id="enterprise-info-message" i18n-content="enterpriseInfoMessage">
   </span>
-  <a id="enterprise-info-hint-link" i18n-content="learnMore"
+  <a id="enterprise-info-hint-link" i18n-content="enterpriseLearnMore"
       i18n-values=".href:enterpriseInfoHintLink"></a>
 </div>
 <div class="content">
diff --git a/chrome/browser/resources/chromeos/login/enterprise_info.css b/chrome/browser/resources/chromeos/login/enterprise_info.css
index 2b67520..c323c0c 100644
--- a/chrome/browser/resources/chromeos/login/enterprise_info.css
+++ b/chrome/browser/resources/chromeos/login/enterprise_info.css
@@ -15,8 +15,9 @@
 }
 
 #enterprise-info[location='guest-tab'] {
-  margin-bottom: -49px;
-  max-width: 600px;
+  box-sizing: border-box;
+  margin-bottom: -43px;
+  max-width: 640px;
 }
 
 #enterprise-info[visible='false'] {
@@ -29,3 +30,14 @@
   top: 3px;
 }
 
+@media (max-height:480px) and (max-width:400px) {
+  #enterprise-info[location='guest-tab'] {
+    margin-bottom: 1em;
+  }
+}
+
+@media (max-width:400px) {
+  #enterprise-info[location='guest-tab'] {
+    margin-top: -2em;
+  }
+}
diff --git a/chrome/browser/resources/chromeos/login/login_common.js b/chrome/browser/resources/chromeos/login/login_common.js
index 13dd071..46eeb7f 100644
--- a/chrome/browser/resources/chromeos/login/login_common.js
+++ b/chrome/browser/resources/chromeos/login/login_common.js
@@ -255,6 +255,14 @@
   };
 
   /**
+   * Skip to login screen for telemetry.
+   */
+  Oobe.skipToLoginForTesting = function() {
+    Oobe.disableSigninUI();
+    chrome.send('skipToLoginForTesting');
+  };
+
+  /**
    * Login for telemetry.
    * @param {string} username Login username.
    * @param {string} password Login password.
@@ -269,8 +277,7 @@
    * Guest login for telemetry.
    */
   Oobe.guestLoginForTesting = function() {
-    Oobe.disableSigninUI();
-    chrome.send('skipToLoginForTesting');
+    Oobe.skipToLoginForTesting();
     chrome.send('launchIncognito');
   };
 
@@ -288,17 +295,23 @@
    * Gaia login screen for telemetry.
    */
   Oobe.addUserForTesting = function() {
-    chrome.send('skipToLoginForTesting');
+    Oobe.skipToLoginForTesting();
     chrome.send('addUser');
   };
 
   /**
-   * Chromebox requisition for telemetry.
+   * Hotrod requisition for telemetry.
    */
-  Oobe.chromeboxRequisitionForTesting = function() {
+  Oobe.remoraRequisitionForTesting = function() {
     chrome.send('setDeviceRequisition', ['remora']);
   };
 
+  /**
+   * Finish enterprise enrollment for telemetry.
+   */
+  Oobe.enterpriseEnrollmentDone = function() {
+    chrome.send('oauthEnrollClose', ['done']);
+  };
 
   /**
    * Shows/hides login UI control bar with buttons like [Shut down].
diff --git a/chrome/browser/resources/chromeos/login/login_resources.html b/chrome/browser/resources/chromeos/login/login_resources.html
index e748874..3fc1002 100644
--- a/chrome/browser/resources/chromeos/login/login_resources.html
+++ b/chrome/browser/resources/chromeos/login/login_resources.html
@@ -33,6 +33,7 @@
 <link rel="stylesheet" href="screen_confirm_password.css">
 <link rel="stylesheet" href="screen_fatal_error.css">
 <link rel="stylesheet" href="../../login/user_pod_row.css">
+<link rel="stylesheet" href="../../options/chromeos/bluetooth.css">
 <script src="chrome://resources/js/cr.js"></script>
 <script src="chrome://resources/js/event_tracker.js"></script>
 <script src="chrome://resources/js/cr/event_target.js"></script>
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css b/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css
index 4b499d2..fdab110 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css
@@ -6,4 +6,84 @@
 #hid-detection {
   min-height: 395px;
   padding: 70px 17px 21px;
+  width: 622px;
+}
+
+#hid-detection .step-contents {
+  margin: 33px auto 82px;
+  width: 475px;
+}
+
+#hid-detection #hid-invitation-text {
+  font-size: 16px;
+}
+
+#hid-detection #hid-prerequisite-msg {
+  padding: 10px 0 30px;
+}
+
+#hid-keyboard-block,
+#hid-mouse-block {
+  padding: 20px 0;
+}
+
+#hid-keyboard-icon,
+#hid-mouse-icon {
+  bottom: -15px;
+  height: 40px;
+  position: relative;
+  width: 40px;
+}
+
+#hid-mouse-icon-block,
+#hid-keyboard-icon-block {
+  display: inline;
+}
+
+#hid-mouse-label,
+#hid-keyboard-label {
+  display: inline;
+}
+
+#hid-detection .label,
+#hid-keyboard-pincode {
+  display: none;
+}
+
+#hid-keyboard-tick,
+#hid-mouse-tick {
+  left: -20px;
+  position: relative;
+  visibility: hidden;
+}
+
+.searching {
+  opacity: 0.6
+}
+
+.searching #hid-keyboard-label-searching,
+.searching #hid-mouse-label-searching,
+.connected #hid-keyboard-label-connected,
+.connected #hid-mouse-label-connected,
+.paired #hid-keyboard-label-paired,
+.paired #hid-mouse-label-paired,
+.pairing #hid-keyboard-label-pairing,
+.connected #hid-keyboard-tick,
+.connected #hid-mouse-tick,
+.paired #hid-keyboard-tick,
+.paired #hid-mouse-tick {
+  display: inline;
+}
+
+.connected #hid-keyboard-tick,
+.connected #hid-mouse-tick,
+.paired #hid-keyboard-tick,
+.paired #hid-mouse-tick {
+  visibility: visible;
+}
+
+.pairing #hid-keyboard-pincode {
+  display: block;
+  margin-left: 40px;
+  padding: 15px 0;
 }
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.html b/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.html
index 4dcf73b..b54ac5d 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.html
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.html
@@ -1,12 +1,63 @@
-<div class="step hidden" id="hid-detection">
+<div class="step hidden" id="hid-detection" hidden>
   <div class="step-contents">
-    <div id="logo"></div>
-    <div id="hid-invitation-text"></div>
+    <div id="hid-invitation-text" i18n-content="hidDetectionInvitation"></div>
+    <div id="hid-prerequisite-msg" i18n-content="hidDetectionPrerequisites">
+    </div>
     <div id="hid-mouse-block">
-      <img id="hid-mouse-icon">
+      <div id="hid-mouse-icon-block">
+        <img id="hid-mouse-icon" src="chrome://theme/IDR_BLUETOOTH_MOUSE"
+            alt="">
+        <img id="hid-mouse-tick" src="chrome://theme/IDR_BLUETOOTH_PAIRING_TICK"
+            alt="">
+      </div>
+      <div id="hid-mouse-label">
+        <span id="hid-mouse-label-searching"
+            i18n-content="hidDetectionMouseSearching" class="label">
+        </span>
+        <span id="hid-mouse-label-connected"
+            i18n-content="hidDetectionUSBMouseConnected" class="label">
+        </span>
+        <span id="hid-mouse-label-paired"
+            i18n-content="hidDetectionBTMousePaired" class="label">
+        </span>
+      </div>
     </div>
     <div id="hid-keyboard-block">
-      <img id="hid-keyboard-icon">
+      <div id="hid-keyboard-icon-block">
+        <img id="hid-keyboard-icon" src="chrome://theme/IDR_BLUETOOTH_KEYBOARD"
+            alt="">
+        <img id="hid-keyboard-tick"
+            src="chrome://theme/IDR_BLUETOOTH_PAIRING_TICK" alt="">
+      </div>
+      <div id="hid-keyboard-label">
+        <span id="hid-keyboard-label-searching"
+            i18n-content="hidDetectionKeyboardSearching" class="label">
+        </span>
+        <span id="hid-keyboard-label-connected"
+            i18n-content="hidDetectionUSBKeyboardConnected" class="label">
+        </span>
+        <span id="hid-keyboard-label-paired" class="label">
+        </span>
+        <span id="hid-keyboard-label-pairing" class="label"></span>
+      </div>
+      <div id="hid-keyboard-pincode">
+        <div id="hid-keyboard-pincode-sym-1" class="bluetooth-keyboard-button">
+        </div>
+        <div id="hid-keyboard-pincode-sym-2" class="bluetooth-keyboard-button">
+        </div>
+        <div id="hid-keyboard-pincode-sym-3" class="bluetooth-keyboard-button">
+        </div>
+        <div id="hid-keyboard-pincode-sym-4" class="bluetooth-keyboard-button">
+        </div>
+        <div id="hid-keyboard-pincode-sym-5" class="bluetooth-keyboard-button">
+        </div>
+        <div id="hid-keyboard-pincode-sym-6" class="bluetooth-keyboard-button">
+        </div>
+        <div id="hid-keyboard-pincode-sym-7"
+            i18n-content="hidDetectionBTEnterKey"
+            class="bluetooth-keyboard-button">
+        </div>
+      </div>
     </div>
   </div>
   <div id="hid-detection-controls" class="step-controls"></div>
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.js b/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.js
index 165dae7..f038c96 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.js
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.js
@@ -8,6 +8,27 @@
 
 login.createScreen('HIDDetectionScreen', 'hid-detection', function() {
   return {
+    EXTERNAL_API: [
+      'setPointingDeviceState',
+      'setKeyboardDeviceState',
+    ],
+
+  /**
+   * Enumeration of possible states during pairing.  The value associated with
+   * each state maps to a localized string in the global variable
+   * |loadTimeData|.
+   * @enum {string}
+   */
+   PAIRING: {
+     STARTUP: 'bluetoothStartConnecting',
+     REMOTE_PIN_CODE: 'bluetoothRemotePinCode',
+     REMOTE_PASSKEY: 'bluetoothRemotePasskey',
+     CONNECT_FAILED: 'bluetoothConnectFailed',
+     CANCELED: 'bluetoothPairingCanceled',
+     // Pairing dismissed (succeeded or canceled).
+     DISMISSED: 'bluetoothPairingDismissed'
+   },
+
     /**
      * Button to move to usual OOBE flow after detection.
      * @private
@@ -42,11 +63,107 @@
     },
 
     /**
+     * Sets a device-block css class to reflect device state of searching,
+     * connected, pairing or paired (for BT devices).
+     * @param {blockId} id one of 'hid-mouse-block' or 'hid-keyboard-block'.
+     * @param {state} one of 'searching', 'connected', 'pairing', 'paired',
+     * @private
+     */
+    setDeviceBlockState_: function(blockId, state) {
+      if (state == 'update')
+        return;
+      var deviceBlock = $(blockId);
+      var states = ['searching', 'connected', 'pairing', 'paired'];
+      for (var i = 0; i < states.length; ++i) {
+        if (states[i] != state)
+          deviceBlock.classList.remove(states[i]);
+      }
+      deviceBlock.classList.add(state);
+    },
+
+    /**
+     * Sets state for mouse-block.
+     * @param {state} one of 'searching', 'connected', 'paired'.
+     */
+    setPointingDeviceState: function(state) {
+      if (state === undefined)
+        return;
+      this.setDeviceBlockState_('hid-mouse-block', state);
+    },
+
+    /**
+     * Sets state for pincode key elements.
+     * @param {entered} int, number of typed keys of pincode, -1 if keys press
+     * detection is not supported by device.
+     */
+    setPincodeKeysState_: function(entered) {
+      var pincodeLength = 7; // including enter-key
+      for (var i = 0; i < pincodeLength; i++) {
+        var pincodeSymbol = $('hid-keyboard-pincode-sym-' + (i + 1));
+        pincodeSymbol.classList.remove('key-typed');
+        pincodeSymbol.classList.remove('key-untyped');
+        pincodeSymbol.classList.remove('key-next');
+        if (i < entered)
+          pincodeSymbol.classList.add('key-typed');
+        else if (i == entered)
+          pincodeSymbol.classList.add('key-next');
+        else if (entered != -1)
+          pincodeSymbol.classList.add('key-untyped');
+      }
+    },
+
+    /**
+     * Sets state for keyboard-block.
+     * @param {data} dict with parameters.
+     */
+    setKeyboardDeviceState: function(data) {
+      if (data === undefined || !('state' in data))
+        return;
+      var state = data['state'];
+      this.setDeviceBlockState_('hid-keyboard-block', state);
+      if (state == 'paired')
+        $('hid-keyboard-label-paired').textContent = data['keyboard-label'];
+      else if (state == 'pairing') {
+        $('hid-keyboard-label-pairing').textContent = data['keyboard-label'];
+        if (data['pairing-state'] == this.PAIRING.REMOTE_PIN_CODE ||
+            data['pairing-state'] == this.PAIRING.REMOTE_PASSKEY) {
+          this.setPincodeKeysState_(-1);
+          for (var i = 0, len = data['pincode'].length; i < len; i++) {
+            var pincodeSymbol = $('hid-keyboard-pincode-sym-' + (i + 1));
+            pincodeSymbol.textContent = data['pincode'][i];
+          }
+        }
+      } else if (state == 'update') {
+        if ('keysEntered' in data) {
+          this.setPincodeKeysState_(data['keysEntered']);
+        }
+      }
+    },
+
+    /**
      * Event handler that is invoked just before the screen in shown.
      * @param {Object} data Screen init payload.
      */
     onBeforeShow: function(data) {
       $('hid-continue-button').disabled = true;
+      this.setDeviceBlockState_('hid-mouse-block', 'searching');
+      this.setDeviceBlockState_('hid-keyboard-block', 'searching');
+    },
+
+    addBluetoothDevice: function(device) {
+      // One device can be in the process of pairing.  If found, display
+      // the Bluetooth pairing overlay.
+      if (device.pairing)
+        this.showPairingLayout(device);
+    },
+
+    /**
+     * Displays the pairing overlay.
+     * @param {Object} device Description of the Bluetooth device.
+     */
+    showPairingLayout: function(device) {
+      BluetoothPairing.getInstance().update(device);
+      OptionsPage.showPageByName('bluetoothPairing', false);
     },
   };
 });
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html
index 3d070fa..1bf1c5b 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.html
@@ -10,9 +10,9 @@
         <div id="oauth-enroll-re-enrollment-text"></div>
         <div i18n-content="oauthEnrollDescription"></div>
         <div><a id="oauth-enroll-learn-more-link" class="oauth-enroll-link"
-              i18n-content="oauthEnrollExplainLink"></a></div>
+              href="#" i18n-content="oauthEnrollExplainLink"></a></div>
         <div><a class="oauth-enroll-explain-link oauth-enroll-link"
-              i18n-content="oauthEnrollExplainLink"></a></div>
+              href="#" i18n-content="oauthEnrollExplainLink"></a></div>
       </div>
     </div>
     <div id="oauth-enroll-step-working">
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
index 197a1ab..297e4e6 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
@@ -306,8 +306,11 @@
         this.classList.toggle('saml', msg.isSAML);
       }
 
-      if (msg.method == 'insecureContentBlocked')
-        this.showError(loadTimeData.getString('fatalEnrollmentError'), false);
+      if (msg.method == 'insecureContentBlocked') {
+        this.showError(
+            loadTimeData.getStringF('insecureURLEnrollmentError', msg.url),
+            false);
+      }
     }
   };
 });
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_reset.css b/chrome/browser/resources/chromeos/login/oobe_screen_reset.css
index f2ecc92..996e20a 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_reset.css
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_reset.css
@@ -5,11 +5,16 @@
 
 .norollback #rollback,
 .norestart #reset-warning-restart,
-#powerwash-help-link {
+.revert-promise #reset-info,
+.revert-promise #rollback,
+.revert-promise #reset-controls,
+#powerwash-help-link,
+#revert-promise {
   display: none;
 }
 
-.norollback #powerwash-help-link {
+.norollback #powerwash-help-link,
+.revert-promise #revert-promise {
   display: block;
 }
 
@@ -33,6 +38,10 @@
   margin: 0 10px;
 }
 
+#reset #reset-warning-icon {
+  height: 112px;
+}
+
 #reset #reset-warning-msg {
   color: #606060;
   font-size: 22px;
@@ -43,7 +52,8 @@
   color: #606060;
 }
 
-#reset #reset-warning-details {
+#reset #reset-warning-details,
+#reset #reset-revert-promise-msg {
   padding: 20px 40px 0;
 }
 
@@ -54,3 +64,8 @@
 #reset #rollback {
   padding: 30px 40px 10px;
 }
+
+#reset #reset-revert-spinner-message {
+  display: inline-block;
+  padding: 25px 0;
+}
\ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_reset.html b/chrome/browser/resources/chromeos/login/oobe_screen_reset.html
index bd71cc2..6e311d2 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_reset.html
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_reset.html
@@ -2,13 +2,15 @@
   <div class="step-contents">
     <div id="reset-warning-msg"></div>
     <img id="reset-warning-icon" src="chrome://theme/IDR_RESET_WARNING" alt="">
-    <div id="reset-warning-details" class="reset-text"></div>
-    <div id="reset-warning-data-details" class="reset-text"
-        i18n-content="resetWarningDataDetails">
-    </div>
-    <a id="powerwash-help-link" href="#" i18n-content="learnMore"></a>
-    <div id="reset-warning-restart" i18n-content="resetRestartMessage"
-         class="reset-text">
+    <div id="reset-info">
+      <div id="reset-warning-details" class="reset-text"></div>
+      <div id="reset-warning-data-details" class="reset-text"
+          i18n-content="resetWarningDataDetails">
+      </div>
+      <a id="powerwash-help-link" href="#" i18n-content="learnMore"></a>
+      <div id="reset-warning-restart" i18n-content="resetRestartMessage"
+           class="reset-text">
+      </div>
     </div>
     <div id="rollback" class="reset-text">
       <div>
@@ -20,6 +22,15 @@
         </a>
       </div>
     </div>
+    <div id="revert-promise">
+      <div id="reset-revert-promise-msg" i18n-content="resetRevertPromise">
+      </div>
+      <div id="reset-revert-spinner" class="throbber">
+      </div>
+      <div id="reset-revert-spinner-message" class="reset-text"
+           i18n-content="resetRevertSpinnerMessage">
+      </div>
+    </div>
   </div>
   <div id="reset-controls" class="step-controls"></div>
 </div>
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_reset.js b/chrome/browser/resources/chromeos/login/oobe_screen_reset.js
index f9cf8dd..b8c9aca 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_reset.js
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_reset.js
@@ -8,6 +8,11 @@
 
 login.createScreen('ResetScreen', 'reset', function() {
   return {
+
+    EXTERNAL_API: [
+      'updateViewOnRollbackCall'
+    ],
+
     /** @override */
     decorate: function() {
       $('reset-powerwash-help-link-on-rollback').addEventListener(
@@ -80,6 +85,7 @@
     onBeforeShow: function(data) {
       if (data === undefined)
         return;
+      this.classList.remove('revert-promise');
       if ('showRestartMsg' in data)
         this.setRestartMsg_(data['showRestartMsg']);
       if ('showRollbackOption' in data)
@@ -114,12 +120,13 @@
             'resetWarningTextInitial');
         $('reset-warning-details').textContent = loadTimeData.getString(
             'resetWarningDetailsInitial');
-        if (this.needRestart)
+        if (this.needRestart) {
           $('reset-button').textContent = loadTimeData.getString(
               'resetButtonRelaunch');
-        else
+        } else {
           $('reset-button').textContent = loadTimeData.getString(
               'resetButtonPowerwash');
+        }
       }
     },
 
@@ -142,5 +149,9 @@
       this.classList.toggle('norollback', !show_rollback);
       this.showRollback = show_rollback;
     },
+
+    updateViewOnRollbackCall: function() {
+      this.classList.add('revert-promise');
+    }
   };
 });
diff --git a/chrome/browser/resources/chromeos/login/screen_error_message.css b/chrome/browser/resources/chromeos/login/screen_error_message.css
index 3e88cd0..09fe55a 100644
--- a/chrome/browser/resources/chromeos/login/screen_error_message.css
+++ b/chrome/browser/resources/chromeos/login/screen_error_message.css
@@ -13,6 +13,7 @@
 .show-with-ui-state-kiosk-mode,
 .show-with-ui-state-local-state-error,
 .show-with-ui-state-auto-enrollment-error,
+.show-with-ui-state-rollback-error,
 .show-with-error-state-portal,
 .show-with-error-state-offline,
 .show-with-error-state-proxy,
@@ -30,6 +31,7 @@
 .ui-state-kiosk-mode .show-with-ui-state-kiosk-mode,
 .ui-state-local-state-error .show-with-ui-state-local-state-error,
 .ui-state-auto-enrollment-error .show-with-ui-state-auto-enrollment-error,
+.ui-state-rollback-error .show-with-ui-state-rollback-error,
 .error-state-portal .show-with-error-state-portal,
 .error-state-offline .show-with-error-state-offline,
 .error-state-proxy .show-with-error-state-proxy,
@@ -57,6 +59,7 @@
 
 .error-icon {
   -webkit-margin-after: 40px;
+  height: 64px;
 }
 
 .error-title {
diff --git a/chrome/browser/resources/chromeos/login/screen_error_message.html b/chrome/browser/resources/chromeos/login/screen_error_message.html
index 1034eda..43236e0 100644
--- a/chrome/browser/resources/chromeos/login/screen_error_message.html
+++ b/chrome/browser/resources/chromeos/login/screen_error_message.html
@@ -14,7 +14,12 @@
       </div>
       <div id="kiosk-online-title" i18n-content="kioskOnlineTitle"
           class="error-title
-                 show-with-error-state-kiosk-online"></div>
+                 show-with-error-state-kiosk-online">
+      </div>
+      <div id="rollback-error-title" i18n-content="rollbackErrorTitle"
+           class="error-title
+                 show-with-ui-state-rollback-error">
+      </div>
     </div>
     <div class="error-body">
       <div id="kiosk-online-message-body"
@@ -105,6 +110,12 @@
             class="error-message-paragraph">
         </div>
       </div>
+      <div id="rollback-error-message-body"
+          class="error-message-paragraph
+                 show-with-ui-state-rollback-error">
+        <span i18n-content="rollbackErrorMessageBody"
+            class="show-with-ui-state-rollback-error"></span>
+      </div>
       <div class="show-with-ui-state-update
                   show-with-ui-state-signin
                   show-with-ui-state-locally-managed
diff --git a/chrome/browser/resources/chromeos/login/screen_error_message.js b/chrome/browser/resources/chromeos/login/screen_error_message.js
index 52fa33b..6114925 100644
--- a/chrome/browser/resources/chromeos/login/screen_error_message.js
+++ b/chrome/browser/resources/chromeos/login/screen_error_message.js
@@ -28,7 +28,8 @@
     ERROR_SCREEN_UI_STATE.MANAGED_USER_CREATION_FLOW,
     ERROR_SCREEN_UI_STATE.KIOSK_MODE,
     ERROR_SCREEN_UI_STATE.LOCAL_STATE_ERROR,
-    ERROR_SCREEN_UI_STATE.AUTO_ENROLLMENT_ERROR
+    ERROR_SCREEN_UI_STATE.AUTO_ENROLLMENT_ERROR,
+    ERROR_SCREEN_UI_STATE.ROLLBACK_ERROR,
   ];
 
   // The help topic linked from the auto enrollment error message.
@@ -238,6 +239,16 @@
       });
       buttons.push(continueButton);
 
+      var okButton = this.ownerDocument.createElement('button');
+      okButton.id = 'ok-error-screen-btn';
+      okButton.textContent = loadTimeData.getString('okButton');
+      okButton.classList.add('show-with-ui-state-rollback-error');
+      okButton.addEventListener('click', function(e) {
+        chrome.send('cancelOnReset');
+        e.stopPropagation();
+      });
+      buttons.push(okButton);
+
       var spacer = this.ownerDocument.createElement('div');
       spacer.classList.add('button-spacer');
       spacer.classList.add('show-with-ui-state-kiosk-mode');
diff --git a/chrome/browser/resources/chromeos/login/screen_fatal_error.html b/chrome/browser/resources/chromeos/login/screen_fatal_error.html
index 8a3a173..e03a479 100644
--- a/chrome/browser/resources/chromeos/login/screen_fatal_error.html
+++ b/chrome/browser/resources/chromeos/login/screen_fatal_error.html
@@ -2,7 +2,9 @@
   <div class="step-contents">
     <div id="fatal-error-message-container">
       <img src="chrome://theme/IDR_FATAL_ERROR"><br>
-      <p id="fatal-error-message" i18n-values=".innerHTML:fatalErrorMessage">
+      <p>
+        <span id="fatal-error-message"></span><br>
+        <span i18n-content="fatalErrorInstructions"></span>
       </p>
     </div>
     <div id="fatal-error-button-strip">
diff --git a/chrome/browser/resources/chromeos/login/screen_fatal_error.js b/chrome/browser/resources/chromeos/login/screen_fatal_error.js
index bfcbf48..df4cbf3 100644
--- a/chrome/browser/resources/chromeos/login/screen_fatal_error.js
+++ b/chrome/browser/resources/chromeos/login/screen_fatal_error.js
@@ -57,11 +57,13 @@
     },
 
     /**
-     * Shows the no password warning screen.
+     * Shows the fatal error string screen.
+     * @param {string} message The error message to show.
      * @param {function()} callback The callback to be invoked when the
      *     screen is dismissed.
      */
-    show: function(callback) {
+    show: function(message, callback) {
+      $('fatal-error-message').textContent = message;
       this.callback_ = callback;
       Oobe.showScreen({id: SCREEN_FATAL_ERROR});
     }
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
index ce15048..ea24a66 100644
--- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
+++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -457,16 +457,22 @@
      * served over an unencrypted connection was detected. Shows a fatal error.
      * This method is only called on Chrome OS, where the entire authentication
      * flow is required to be encrypted.
+     * @param {string} url The URL that was blocked.
      */
-    onInsecureContentBlocked_: function() {
-      this.showFatalAuthError();
+    onInsecureContentBlocked_: function(url) {
+      this.showFatalAuthError(loadTimeData.getStringF(
+          'fatalErrorMessageInsecureURL',
+          url));
     },
 
     /**
      * Shows the fatal auth error.
+     * @param {string} message The error message to show.
      */
-    showFatalAuthError: function() {
-      login.FatalErrorScreen.show(Oobe.showSigninUI);
+    showFatalAuthError: function(message) {
+      if (!message)
+        message = loadTimeData.getString('fatalErrorMessageGeneric');
+      login.FatalErrorScreen.show(message, Oobe.showSigninUI);
     },
 
     /**
diff --git a/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.css b/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.css
index 8c5d062..3fcb3f0 100644
--- a/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.css
+++ b/chrome/browser/resources/chromeos/login/screen_locally_managed_user_creation.css
@@ -349,6 +349,11 @@
   overflow-y: auto;
 }
 
+#managed-user-creation-import .page-title-explanation {
+  padding-bottom: 10px;
+  padding-top: 6px;
+}
+
 .manager-pod .password-error,
 #managed-user-creation .password-error,
 #managed-user-creation .duplicate-name {
diff --git a/chrome/browser/resources/chromeos/network.html b/chrome/browser/resources/chromeos/network.html
index bc87812..829a8a6 100644
--- a/chrome/browser/resources/chromeos/network.html
+++ b/chrome/browser/resources/chromeos/network.html
@@ -42,7 +42,6 @@
       <td>Profile</td>
       <td>Connect</td>
       <td>Error</td>
-      <td>IP Addr</td>
       <td>Security</td>
       <td>Technology</td>
       <td>Activation</td>
diff --git a/chrome/browser/resources/chromeos/network.js b/chrome/browser/resources/chromeos/network.js
index 4cfec58..4f952bc 100644
--- a/chrome/browser/resources/chromeos/network.js
+++ b/chrome/browser/resources/chromeos/network.js
@@ -8,7 +8,7 @@
   // specified then the first non empty value is used.
   var NETWORK_STATE_FIELDS = [
     'Name', 'Type', 'State', 'Profile', 'Connectable',
-    'Error', 'Address', 'Security',
+    'Error', 'Security',
     ['Cellular.NetworkTechnology', 'EAP.EAP'],
     'Cellular.ActivationState', 'Cellular.RoamingState',
     'Cellular.OutOfCredits', 'Strength'
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
index 66d341a..1c18ab2 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
@@ -22,9 +22,12 @@
  */
 .dialog-topbar #navstrip,
 .dialog-topbar #window-close-button,
-.image-picker,
 .overlay-container .page,
 #author-website,
+/* TODO(bshe): Once http://crbug.com/369651 fixed, use .image-picker instead of
+ * #category-container.
+ */
+#category-container,
 #surprise-me {
   -webkit-app-region: no-drag;
 }
diff --git a/chrome/browser/resources/component_extension_resources.grd b/chrome/browser/resources/component_extension_resources.grd
index b289b9b..d3d4d4e 100644
--- a/chrome/browser/resources/component_extension_resources.grd
+++ b/chrome/browser/resources/component_extension_resources.grd
@@ -26,6 +26,11 @@
     <includes>
       <include name="IDR_NETWORK_SPEECH_SYNTHESIS_JS" file="network_speech_synthesis/tts_extension.js" type="BINDATA" />
 
+      <if expr="chromeos">
+        <include name="IDR_BRAILLE_IME_JS" file="chromeos/braille_ime/braille_ime.js" type="BINDATA" />
+        <include name="IDR_BRAILLE_IME_MAIN_JS" file="chromeos/braille_ime/main.js" type="BINDATA" />
+      </if>
+
       <include name="IDR_BOOKMARK_MANAGER_BOOKMARK_MANAGER_SEARCH" file="bookmark_manager/images/bookmark_manager_search.png" type="BINDATA" />
       <include name="IDR_BOOKMARK_MANAGER_BOOKMARK_MANAGER_SEARCH_RTL" file="bookmark_manager/images/bookmark_manager_search_rtl.png" type="BINDATA" />
       <include name="IDR_BOOKMARK_MANAGER_BOOKMARK_MAIN_JS" file="bookmark_manager/js/main.js" type="BINDATA" />
diff --git a/chrome/browser/resources/cryptotoken/b64.js b/chrome/browser/resources/cryptotoken/b64.js
index 21140be..d3c1e80 100644
--- a/chrome/browser/resources/cryptotoken/b64.js
+++ b/chrome/browser/resources/cryptotoken/b64.js
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 // WebSafeBase64Escape and Unescape.
-// mschilder@google.com
 function B64_encode(bytes, opt_length) {
   if (!opt_length) opt_length = bytes.length;
   var b64out =
@@ -11,10 +10,10 @@
   var result = '';
   var shift = 0;
   var accu = 0;
-  var input_index = 0;
+  var inputIndex = 0;
   while (opt_length--) {
     accu <<= 8;
-    accu |= bytes[input_index++];
+    accu |= bytes[inputIndex++];
     shift += 8;
     while (shift >= 6) {
       var i = (accu >> (shift - 6)) & 63;
@@ -39,10 +38,10 @@
   var result = '';
   var shift = 0;
   var accu = 0;
-  var input_index = 0;
+  var inputIndex = 0;
   while (opt_length--) {
     accu <<= 8;
-    accu |= bytes[input_index++];
+    accu |= bytes[inputIndex++];
     shift += 8;
     while (shift >= 6) {
       var i = (accu >> (shift - 6)) & 63;
diff --git a/chrome/browser/resources/cryptotoken/background.js b/chrome/browser/resources/cryptotoken/background.js
index 98496e0..d197abe 100644
--- a/chrome/browser/resources/cryptotoken/background.js
+++ b/chrome/browser/resources/cryptotoken/background.js
@@ -23,10 +23,11 @@
 /**
  * @param {boolean} toleratesMultipleResponses Whether the web page can handle
  *     multiple responses given to its sendResponse callback.
- * @param {Object} request
- * @param {MessageSender} sender
- * @param {Function} sendResponse
- * @return {Closeable}
+ * @param {Object} request Request object
+ * @param {MessageSender} sender Sender frame
+ * @param {Function} sendResponse Response callback
+ * @return {?Closeable} Optional handler object that should be closed when port
+ *     closes
  */
 function handleWebPageRequest(toleratesMultipleResponses, request, sender,
     sendResponse) {
diff --git a/chrome/browser/resources/cryptotoken/closeable.js b/chrome/browser/resources/cryptotoken/closeable.js
index dda2d6d..eecf49c 100644
--- a/chrome/browser/resources/cryptotoken/closeable.js
+++ b/chrome/browser/resources/cryptotoken/closeable.js
@@ -4,7 +4,6 @@
 
 /**
  * @fileoverview Defines a Closeable interface.
- * @author juanlang@google.com (Juan Lang)
  */
 'use strict';
 
diff --git a/chrome/browser/resources/cryptotoken/countdown.js b/chrome/browser/resources/cryptotoken/countdown.js
index b9e14eb..12977d9 100644
--- a/chrome/browser/resources/cryptotoken/countdown.js
+++ b/chrome/browser/resources/cryptotoken/countdown.js
@@ -4,7 +4,6 @@
 
 /**
  * @fileoverview Provides a countdown-based timer.
- * @author juanlang@google.com (Juan Lang)
  */
 'use strict';
 
@@ -55,6 +54,7 @@
   this.setTimeout(timeoutMillis || 0, cb);
 }
 
+/** Timer interval */
 CountdownTimer.TIMER_INTERVAL_MILLIS = 200;
 
 /**
diff --git a/chrome/browser/resources/cryptotoken/enroller.js b/chrome/browser/resources/cryptotoken/enroller.js
index 71a8ff0..d7b4609 100644
--- a/chrome/browser/resources/cryptotoken/enroller.js
+++ b/chrome/browser/resources/cryptotoken/enroller.js
@@ -4,7 +4,6 @@
 
 /**
  * @fileoverview Handles web page requests for gnubby enrollment.
- * @author juanlang@google.com (Juan Lang)
  */
 
 'use strict';
@@ -19,7 +18,8 @@
  * @param {Function} sendResponse Called back with the result of the enroll.
  * @param {boolean} toleratesMultipleResponses Whether the sendResponse
  *     callback can be called more than once, e.g. for progress updates.
- * @return {Closeable}
+ * @return {Closeable} A handler object to be closed when the browser channel
+ *     closes.
  */
 function handleEnrollRequest(factory, sender, request, enforceAppIdValid,
     sendResponse, toleratesMultipleResponses) {
@@ -229,9 +229,10 @@
 
 /**
  * Performs an enroll request with the given enroll and sign challenges.
- * @param {Array.<Object>} enrollChallenges
- * @param {Array.<Object>} signChallenges
- * @param {boolean} enforceAppIdValid
+ * @param {Array.<Object>} enrollChallenges A set of enroll challenges
+ * @param {Array.<Object>} signChallenges A set of sign challenges for existing
+ *     enrollments for this user and appId
+ * @param {boolean} enforceAppIdValid Whether to enforce that appId is valid
  */
 Enroller.prototype.doEnroll =
     function(enrollChallenges, signChallenges, enforceAppIdValid) {
@@ -266,7 +267,7 @@
 
 /**
  * Encodes the enroll challenges for use by an enroll helper.
- * @param {Array.<Object>} enrollChallenges
+ * @param {Array.<Object>} enrollChallenges A set of enroll challenges
  * @return {Array.<EnrollHelperChallenge>} the encoded challenges.
  * @private
  */
@@ -451,7 +452,7 @@
 
 /**
  * Notifies the caller with the error code.
- * @param {number} code
+ * @param {number} code Error code
  * @private
  */
 Enroller.prototype.notifyError_ = function(code) {
@@ -464,9 +465,9 @@
 
 /**
  * Notifies the caller of success with the provided response data.
- * @param {string} u2fVersion
- * @param {string} info
- * @param {string|undefined} opt_browserData
+ * @param {string} u2fVersion Protocol version
+ * @param {string} info Response data
+ * @param {string|undefined} opt_browserData Browser data used
  * @private
  */
 Enroller.prototype.notifySuccess_ =
@@ -480,7 +481,7 @@
 
 /**
  * Notifies the caller of progress with the error code.
- * @param {number} code
+ * @param {number} code Status code
  * @private
  */
 Enroller.prototype.notifyProgress_ = function(code) {
@@ -526,8 +527,8 @@
 
 /**
  * Called by the helper upon error.
- * @param {number} code
- * @param {boolean} anyGnubbies
+ * @param {number} code Error code
+ * @param {boolean} anyGnubbies If any gnubbies were found
  * @private
  */
 Enroller.prototype.helperError_ = function(code, anyGnubbies) {
@@ -558,8 +559,8 @@
 
 /**
  * Called by helper to notify progress.
- * @param {number} code
- * @param {boolean} anyGnubbies
+ * @param {number} code Status code
+ * @param {boolean} anyGnubbies If any gnubbies were found
  * @private
  */
 Enroller.prototype.helperProgress_ = function(code, anyGnubbies) {
diff --git a/chrome/browser/resources/cryptotoken/enrollhelper.js b/chrome/browser/resources/cryptotoken/enrollhelper.js
index 1c82c39..e8a983c 100644
--- a/chrome/browser/resources/cryptotoken/enrollhelper.js
+++ b/chrome/browser/resources/cryptotoken/enrollhelper.js
@@ -5,7 +5,6 @@
 /**
  * @fileoverview Provides a "bottom half" helper to assist with raw enroll
  * requests.
- * @author juanlang@google.com (Juan Lang)
  */
 'use strict';
 
diff --git a/chrome/browser/resources/cryptotoken/gnubbies.js b/chrome/browser/resources/cryptotoken/gnubbies.js
index e541253..7726455 100644
--- a/chrome/browser/resources/cryptotoken/gnubbies.js
+++ b/chrome/browser/resources/cryptotoken/gnubbies.js
@@ -162,7 +162,7 @@
 Gnubbies.INACTIVITY_TIMEOUT_MARGIN_MILLIS = 30000;
 
 /**
- * @param {number|undefined} opt_timeoutMillis
+ * @param {number|undefined} opt_timeoutMillis Timeout in milliseconds
  */
 Gnubbies.prototype.resetInactivityTimer = function(opt_timeoutMillis) {
   var millis = opt_timeoutMillis ?
diff --git a/chrome/browser/resources/cryptotoken/gnubby-u2f.js b/chrome/browser/resources/cryptotoken/gnubby-u2f.js
index a8418d9..653b957 100644
--- a/chrome/browser/resources/cryptotoken/gnubby-u2f.js
+++ b/chrome/browser/resources/cryptotoken/gnubby-u2f.js
@@ -8,19 +8,31 @@
 'use strict';
 
 // Commands and flags of the Gnubby applet at
-// //depot/google3/security/tools/gnubby/applet/gnubby/src/pkgGnubby/Gnubby.java
-usbGnubby.U2F_ENROLL        = 0x01;
-usbGnubby.U2F_SIGN          = 0x02;
-usbGnubby.U2F_VERSION       = 0x03;
+/** Enroll */
+usbGnubby.U2F_ENROLL = 0x01;
+/** Request signature */
+usbGnubby.U2F_SIGN = 0x02;
+/** Request protocol version */
+usbGnubby.U2F_VERSION = 0x03;
 
-usbGnubby.APPLET_VERSION    = 0x11;  // First 3 bytes are applet version.
+/** Request applet version */
+usbGnubby.APPLET_VERSION = 0x11;  // First 3 bytes are applet version.
 
 // APDU.P1 flags
-usbGnubby.P1_TUP_REQUIRED   = 0x01;
-usbGnubby.P1_TUP_CONSUME    = 0x02;
-usbGnubby.P1_TUP_TESTONLY   = 0x04;
+/** Test of User Presence required */
+usbGnubby.P1_TUP_REQUIRED = 0x01;
+/** Consume a Test of User Presence */
+usbGnubby.P1_TUP_CONSUME = 0x02;
+/** Test signature only, no TUP. E.g. to check for existing enrollments. */
+usbGnubby.P1_TUP_TESTONLY = 0x04;
+/** Attest with device key */
 usbGnubby.P1_INDIVIDUAL_KEY = 0x80;
 
+/** Perform enrollment
+ * @param {ArrayBuffer|Uint8Array} challenge Enrollment challenge
+ * @param {ArrayBuffer|Uint8Array} appIdHash Hashed application id
+ * @param {function(...)} cb Result callback
+ */
 usbGnubby.prototype.enroll = function(challenge, appIdHash, cb) {
   var apdu = new Uint8Array(
       [0x00,
@@ -29,7 +41,7 @@
          usbGnubby.P1_INDIVIDUAL_KEY,
        0x00, 0x00, 0x00,
        challenge.length + appIdHash.length]);
-  // TODO(mschilder): only use P1_INDIVIDUAL_KEY for corp appIdHashes.
+  // TODO: only use P1_INDIVIDUAL_KEY for corp appIdHashes.
   var u8 = new Uint8Array(apdu.length + challenge.length +
       appIdHash.length + 2);
   for (var i = 0; i < apdu.length; ++i) u8[i] = apdu[i];
@@ -41,6 +53,14 @@
   this.apduReply_(u8.buffer, cb);
 };
 
+/** Request signature
+ * @param {ArrayBuffer|Uint8Array} challengeHash Hashed signature challenge
+ * @param {ArrayBuffer|Uint8Array} appIdHash Hashed application id
+ * @param {ArrayBuffer|Uint8Array} keyHandle Key handle to use
+ * @param {function(...)} cb Result callback
+ * @param {boolean=} opt_nowink Request signature without winking
+ *     (e.g. during enroll)
+ */
 usbGnubby.prototype.sign = function(challengeHash, appIdHash, keyHandle, cb,
                                     opt_nowink) {
   var apdu = new Uint8Array(
@@ -72,6 +92,9 @@
   this.apduReply_(u8.buffer, cb, opt_nowink);
 };
 
+/** Request version information
+ * @param {function(...)} cb Callback
+ */
 usbGnubby.prototype.version = function(cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   var apdu = new Uint8Array([0x00, usbGnubby.U2F_VERSION, 0x00, 0x00, 0x00,
diff --git a/chrome/browser/resources/cryptotoken/gnubby.js b/chrome/browser/resources/cryptotoken/gnubby.js
index f3363f0..27f8c86 100644
--- a/chrome/browser/resources/cryptotoken/gnubby.js
+++ b/chrome/browser/resources/cryptotoken/gnubby.js
@@ -4,13 +4,12 @@
 
 /**
  * @fileoverview Low level usb cruft to talk gnubby.
- * @author mschilder@google.com
  */
 
 'use strict';
 
 // Global Gnubby instance counter.
-var gnubby_id = 0;
+var gnubbyId = 0;
 
 /**
  * Creates a worker Gnubby instance.
@@ -19,7 +18,7 @@
  */
 function usbGnubby(opt_busySeconds) {
   this.dev = null;
-  this.cid = (++gnubby_id) & 0x00ffffff;  // Pick unique channel.
+  this.cid = (++gnubbyId) & 0x00ffffff;  // Pick unique channel.
   this.rxframes = [];
   this.synccnt = 0;
   this.rxcb = null;
@@ -31,7 +30,7 @@
 
 /**
  * Sets usbGnubby's Gnubbies singleton.
- * @param {Gnubbies} gnubbies
+ * @param {Gnubbies} gnubbies Gnubbies singleton instance
  */
 usbGnubby.setGnubbies = function(gnubbies) {
   /** @private {Gnubbies} */
@@ -163,6 +162,7 @@
 
 /**
  * Notify callback for every frame received.
+ * @param {function()} cb Callback
  * @private
  */
 usbGnubby.prototype.notifyFrame_ = function(cb) {
@@ -176,7 +176,7 @@
 
 /**
  * Called by low level driver with a frame.
- * @param {ArrayBuffer} frame
+ * @param {ArrayBuffer|Uint8Array} frame Data frame
  * @return {boolean} Whether this client is still interested in receiving
  *     frames from its device.
  */
@@ -199,7 +199,7 @@
 };
 
 /**
- * @return {ArrayBuffer} oldest received frame. Throw if none.
+ * @return {ArrayBuffer|Uint8Array} oldest received frame. Throw if none.
  * @private
  */
 usbGnubby.prototype.readFrame_ = function() {
@@ -209,8 +209,12 @@
   return frame;
 };
 
-// Poll from rxframes[].
-// timeout in seconds.
+/** Poll from rxframes[].
+ * @param {number} cmd Command
+ * @param {number} timeout timeout in seconds.
+ * @param {?function(...)} cb Callback
+ * @private
+ */
 usbGnubby.prototype.read_ = function(cmd, timeout, cb) {
   if (this.closed) { cb(-llGnubby.GONE); return; }
   if (!this.dev) { cb(-llGnubby.NODEVICE); return; }
@@ -263,9 +267,9 @@
 
     var f = new Uint8Array(self.readFrame_());
     var rcmd = f[4];
-    var total_len = (f[5] << 8) + f[6];
+    var totalLen = (f[5] << 8) + f[6];
 
-    if (rcmd == llGnubby.CMD_ERROR && total_len == 1) {
+    if (rcmd == llGnubby.CMD_ERROR && totalLen == 1) {
       // Error from device; forward.
       console.log(UTIL_fmt(
           '[' + self.cid.toString(16) + '] error frame ' +
@@ -315,9 +319,9 @@
     var f = new Uint8Array(self.readFrame_());
 
     var rcmd = f[4];
-    var total_len = (f[5] << 8) + f[6];
+    var totalLen = (f[5] << 8) + f[6];
 
-    if (rcmd == llGnubby.CMD_ERROR && total_len == 1) {
+    if (rcmd == llGnubby.CMD_ERROR && totalLen == 1) {
       // Error from device; forward.
       // Don't log busy frames, they're "normal".
       if (f[7] != llGnubby.BUSY) {
@@ -351,7 +355,7 @@
     }
 
     // Copy payload.
-    msg = new Uint8Array(total_len);
+    msg = new Uint8Array(totalLen);
     for (var i = 7; i < f.length && count < msg.length; ++i) {
       msg[count++] = f[i];
     }
@@ -373,7 +377,7 @@
 };
 
 /**
- * @param {ArrayBuffer} frame
+ * @param {ArrayBuffer|Uint8Array} frame Data frame
  * @return {boolean} Whether frame is for my channel.
  * @private
  */
@@ -390,7 +394,7 @@
 /**
  * Queue command for sending.
  * @param {number} cmd The command to send.
- * @param {ArrayBuffer} data
+ * @param {ArrayBuffer|Uint8Array} data Command data
  * @private
  */
 usbGnubby.prototype.write_ = function(cmd, data) {
@@ -405,9 +409,9 @@
 /**
  * Writes the command, and calls back when the command's reply is received.
  * @param {number} cmd The command to send.
- * @param {ArrayBuffer} data
+ * @param {ArrayBuffer|Uint8Array} data Command data
  * @param {number} timeout Timeout in seconds.
- * @param {function(number, ArrayBuffer=)} cb
+ * @param {function(number, ArrayBuffer=)} cb Callback
  * @private
  */
 usbGnubby.prototype.exchange_ = function(cmd, data, timeout, cb) {
@@ -430,7 +434,10 @@
   retryBusy(-llGnubby.BUSY, undefined);  // Start work.
 };
 
-// For console interaction.
+/** Default callback for commands. Simply logs to console.
+ * @param {number} rc Result status code
+ * @param {*} data Result data
+ */
 usbGnubby.defaultCallback = function(rc, data) {
   var msg = 'defaultCallback(' + rc;
   if (data) {
@@ -441,7 +448,9 @@
   console.log(UTIL_fmt(msg));
 };
 
-// Send nonce to device, flush read queue until match.
+/** Send nonce to device, flush read queue until match.
+ * @param {?function(...)} cb Callback
+ */
 usbGnubby.prototype.sync = function(cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   if (this.closed) {
@@ -515,13 +524,20 @@
   timeoutLoop();
 };
 
-// Communication timeout values in seconds.
+/** Short timeout value in seconds */
 usbGnubby.SHORT_TIMEOUT = 1;
+/** Normal timeout value in seconds */
 usbGnubby.NORMAL_TIMEOUT = 3;
 // Max timeout usb firmware has for smartcard response is 30 seconds.
 // Make our application level tolerance a little longer.
+/** Maximum timeout in seconds */
 usbGnubby.MAX_TIMEOUT = 31;
 
+/** Blink led
+ * @param {number|ArrayBuffer|Uint8Array} data Command data or number
+ *     of seconds to blink
+ * @param {?function(...)} cb Callback
+ */
 usbGnubby.prototype.blink = function(data, cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   if (typeof data == 'number') {
@@ -531,6 +547,10 @@
   this.exchange_(llGnubby.CMD_PROMPT, data, usbGnubby.NORMAL_TIMEOUT, cb);
 };
 
+/** Lock the gnubby
+ * @param {number|ArrayBuffer|Uint8Array} data Command data
+ * @param {?function(...)} cb Callback
+ */
 usbGnubby.prototype.lock = function(data, cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   if (typeof data == 'number') {
@@ -540,6 +560,9 @@
   this.exchange_(llGnubby.CMD_LOCK, data, usbGnubby.NORMAL_TIMEOUT, cb);
 };
 
+/** Unlock the gnubby
+ * @param {?function(...)} cb Callback
+ */
 usbGnubby.prototype.unlock = function(cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   var data = new Uint8Array([0]);
@@ -547,23 +570,37 @@
       usbGnubby.NORMAL_TIMEOUT, cb);
 };
 
+/** Request system information data.
+ * @param {?function(...)} cb Callback
+ */
 usbGnubby.prototype.sysinfo = function(cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   this.exchange_(llGnubby.CMD_SYSINFO, new ArrayBuffer(0),
       usbGnubby.NORMAL_TIMEOUT, cb);
 };
 
+/** Send wink command
+ * @param {?function(...)} cb Callback
+ */
 usbGnubby.prototype.wink = function(cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   this.exchange_(llGnubby.CMD_WINK, new ArrayBuffer(0),
       usbGnubby.NORMAL_TIMEOUT, cb);
 };
 
+/** Send DFU (Device firmware upgrade) command
+ * @param {ArrayBuffer|Uint8Array} data Command data
+ * @param {?function(...)} cb Callback
+ */
 usbGnubby.prototype.dfu = function(data, cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   this.exchange_(llGnubby.CMD_DFU, data, usbGnubby.NORMAL_TIMEOUT, cb);
 };
 
+/** Ping the gnubby
+ * @param {number|ArrayBuffer|Uint8Array} data Command data
+ * @param {?function(...)} cb Callback
+ */
 usbGnubby.prototype.ping = function(data, cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   if (typeof data == 'number') {
@@ -574,11 +611,18 @@
   this.exchange_(llGnubby.CMD_PING, data, usbGnubby.NORMAL_TIMEOUT, cb);
 };
 
+/** Send a raw APDU command
+ * @param {ArrayBuffer|Uint8Array} data Command data
+ * @param {?function(...)} cb Callback
+ */
 usbGnubby.prototype.apdu = function(data, cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   this.exchange_(llGnubby.CMD_APDU, data, usbGnubby.MAX_TIMEOUT, cb);
 };
 
+/** Reset gnubby
+ * @param {?function(...)} cb Callback
+ */
 usbGnubby.prototype.reset = function(cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   this.exchange_(llGnubby.CMD_ATR, new ArrayBuffer(0),
@@ -588,6 +632,10 @@
 // byte args[3] = [delay-in-ms before disabling interrupts,
 //                 delay-in-ms before disabling usb (aka remove),
 //                 delay-in-ms before reboot (aka insert)]
+/** Send usb test command
+ * @param {ArrayBuffer|Uint8Array} args Command data
+ * @param {?function(...)} cb Callback
+ */
 usbGnubby.prototype.usb_test = function(args, cb) {
   if (!cb) cb = usbGnubby.defaultCallback;
   var u8 = new Uint8Array(args);
@@ -595,6 +643,12 @@
       usbGnubby.NORMAL_TIMEOUT, cb);
 };
 
+/** APDU command with reply
+ * @param {ArrayBuffer|Uint8Array} request The request
+ * @param {?function(...)} cb Callback
+ * @param {boolean=} opt_nowink Do not wink
+ * @private
+ */
 usbGnubby.prototype.apduReply_ = function(request, cb, opt_nowink) {
   if (!cb) cb = usbGnubby.defaultCallback;
   var self = this;
diff --git a/chrome/browser/resources/cryptotoken/gnubbycodetypes.js b/chrome/browser/resources/cryptotoken/gnubbycodetypes.js
index d6c8436..c177cd3 100644
--- a/chrome/browser/resources/cryptotoken/gnubbycodetypes.js
+++ b/chrome/browser/resources/cryptotoken/gnubbycodetypes.js
@@ -51,7 +51,7 @@
  */
 GnubbyCodeTypes.NO_EXTENSION = 8;
 
-// TODO(jayini): change to none_enrolled_for_account and none_enrolled_present
+// TODO: change to none_enrolled_for_account and none_enrolled_present
 /**
  * No devices enrolled for this user.
  * @const
diff --git a/chrome/browser/resources/cryptotoken/gnubbyfactory.js b/chrome/browser/resources/cryptotoken/gnubbyfactory.js
index ecf8f35..3ee9886 100644
--- a/chrome/browser/resources/cryptotoken/gnubbyfactory.js
+++ b/chrome/browser/resources/cryptotoken/gnubbyfactory.js
@@ -4,7 +4,6 @@
 
 /**
  * @fileoverview Contains a factory interface for creating and opening gnubbies.
- * @author juanlang@google.com (Juan Lang)
  */
 'use strict';
 
@@ -16,7 +15,7 @@
 
 /**
  * Enumerates gnubbies.
- * @param {function(number, Array.<llGnubbyDeviceId>)} cb
+ * @param {function(number, Array.<llGnubbyDeviceId>)} cb Enumerate callback
  */
 GnubbyFactory.prototype.enumerate = function(cb) {
 };
diff --git a/chrome/browser/resources/cryptotoken/llgnubby.js b/chrome/browser/resources/cryptotoken/llgnubby.js
index 70551e9..2cf709d 100644
--- a/chrome/browser/resources/cryptotoken/llgnubby.js
+++ b/chrome/browser/resources/cryptotoken/llgnubby.js
@@ -14,43 +14,68 @@
 function llGnubby() {}
 
 // Commands of the USB interface.
-// //depot/google3/security/tools/gnubby/gnubbyd/gnubby_if.h
-llGnubby.CMD_PING =      0x81;
-llGnubby.CMD_ATR =       0x82;
-llGnubby.CMD_APDU =      0x83;
-llGnubby.CMD_LOCK =      0x84;
-llGnubby.CMD_SYSINFO =   0x85;
-llGnubby.CMD_PROMPT =    0x87;
-llGnubby.CMD_WINK =      0x88;
-llGnubby.CMD_USB_TEST =  0xb9;
-llGnubby.CMD_DFU =       0xba;
-llGnubby.CMD_SYNC =      0xbc;
-llGnubby.CMD_ERROR =     0xbf;
+/** Echo data through local processor only */
+llGnubby.CMD_PING = 0x81;
+/** Perform reset action and read ATR string */
+llGnubby.CMD_ATR = 0x82;
+/** Send raw APDU */
+llGnubby.CMD_APDU = 0x83;
+/** Send lock channel command */
+llGnubby.CMD_LOCK = 0x84;
+/** Obtain system information record */
+llGnubby.CMD_SYSINFO = 0x85;
+/** Control prompt flashing */
+llGnubby.CMD_PROMPT = 0x87;
+/** Send device identification wink */
+llGnubby.CMD_WINK = 0x88;
+/** USB test */
+llGnubby.CMD_USB_TEST = 0xb9;
+/** Device Firmware Upgrade */
+llGnubby.CMD_DFU = 0xba;
+/** Protocol resync command */
+llGnubby.CMD_SYNC = 0xbc;
+/** Error response */
+llGnubby.CMD_ERROR = 0xbf;
 
 // Low-level error codes.
-// //depot/google3/security/tools/gnubby/gnubbyd/gnubby_if.h
-// //depot/google3/security/tools/gnubby/client/gnubby_error_codes.h
-llGnubby.OK =            0;
-llGnubby.INVALID_CMD =   1;
-llGnubby.INVALID_PAR =   2;
-llGnubby.INVALID_LEN =   3;
-llGnubby.INVALID_SEQ =   4;
-llGnubby.TIMEOUT =       5;
-llGnubby.BUSY =          6;
+/** No error */
+llGnubby.OK = 0;
+/** Invalid command */
+llGnubby.INVALID_CMD = 1;
+/** Invalid parameter */
+llGnubby.INVALID_PAR = 2;
+/** Invalid message length */
+llGnubby.INVALID_LEN = 3;
+/** Invalid message sequencing */
+llGnubby.INVALID_SEQ = 4;
+/** Message has timed out */
+llGnubby.TIMEOUT = 5;
+/** CHannel is busy */
+llGnubby.BUSY = 6;
+/** Access denied */
 llGnubby.ACCESS_DENIED = 7;
-llGnubby.GONE =          8;
-llGnubby.VERIFY_ERROR =  9;
+/** Device is gone */
+llGnubby.GONE = 8;
+/** Verification error */
+llGnubby.VERIFY_ERROR = 9;
+/** Command requires channel lock */
 llGnubby.LOCK_REQUIRED = 10;
-llGnubby.SYNC_FAIL =     11;
-llGnubby.OTHER =         127;
+/** Sync error */
+llGnubby.SYNC_FAIL = 11;
+/** Other unspecified error */
+llGnubby.OTHER = 127;
 
 // Remote helper errors.
-llGnubby.NOTREMOTE =     263;
-llGnubby.COULDNOTDIAL =  264;
+/** Not a remote helper */
+llGnubby.NOTREMOTE = 263;
+/** Could not reach remote endpoint */
+llGnubby.COULDNOTDIAL = 264;
 
 // chrome.usb-related errors.
-llGnubby.NODEVICE =      512;
-llGnubby.NOPERMISSION =  666;
+/** No device */
+llGnubby.NODEVICE = 512;
+/** Permission denied */
+llGnubby.NOPERMISSION = 666;
 
 /** Destroys this low-level device instance. */
 llGnubby.prototype.destroy = function() {};
@@ -80,6 +105,6 @@
  * If queue was empty, initiate the write.
  * @param {number} cid The client's channel ID.
  * @param {number} cmd The command to send.
- * @param {ArrayBuffer} data
+ * @param {ArrayBuffer} data Command data
  */
 llGnubby.prototype.queueCommand = function(cid, cmd, data) {};
diff --git a/chrome/browser/resources/cryptotoken/llhidgnubby.js b/chrome/browser/resources/cryptotoken/llhidgnubby.js
index b79c11d..0f643bb 100644
--- a/chrome/browser/resources/cryptotoken/llhidgnubby.js
+++ b/chrome/browser/resources/cryptotoken/llhidgnubby.js
@@ -81,7 +81,7 @@
 
 /**
  * Push frame to all clients.
- * @param {ArrayBuffer} f
+ * @param {ArrayBuffer} f Data to push
  * @private
  */
 llHidGnubby.prototype.publishFrame_ = function(f) {
@@ -188,7 +188,7 @@
   // Instead we will see the device drop and re-appear on the bus.
   // Current libusb on some platforms gets unhappy when transfer are pending
   // when that happens.
-  // TODO(mschilder): revisit once Chrome stabilizes its behavior.
+  // TODO: revisit once Chrome stabilizes its behavior.
   if (this.updating) {
     console.log(UTIL_fmt('device updating. Ending readLoop()'));
     return;
@@ -218,8 +218,8 @@
 
 /**
  * Check whether channel is locked for this request or not.
- * @param {number} cid
- * @param {number} cmd
+ * @param {number} cid Channel id
+ * @param {number} cmd Request command
  * @return {boolean} true if not locked for this request.
  * @private
  */
@@ -254,9 +254,9 @@
 
 /**
  * Update or grab lock.
- * @param {number} cid
- * @param {number} cmd
- * @param {number} arg
+ * @param {number} cid Channel ID
+ * @param {number} cmd Command
+ * @param {number} arg Command argument
  * @private
  */
 llHidGnubby.prototype.updateLock_ = function(cid, cmd, arg) {
@@ -299,7 +299,7 @@
  * If queue was empty, initiate the write.
  * @param {number} cid The client's channel ID.
  * @param {number} cmd The command to send.
- * @param {ArrayBuffer} data
+ * @param {ArrayBuffer} data Command arguments
  */
 llHidGnubby.prototype.queueCommand = function(cid, cmd, data) {
   if (!this.dev) return;
@@ -336,7 +336,7 @@
 
 /**
  * Sets the channel id in the frame.
- * @param {Uint8Array} frame
+ * @param {Uint8Array} frame Data frame
  * @param {number} cid The client's channel ID.
  * @private
  */
@@ -350,10 +350,10 @@
 /**
  * Updates the lock, and queues the frame for sending. Also begins sending if
  * no other writes are outstanding.
- * @param {ArrayBuffer} frame
+ * @param {ArrayBuffer} frame Data frame
  * @param {number} cid The client's channel ID.
  * @param {number} cmd The command to send.
- * @param {number} arg
+ * @param {number} arg Command argument
  * @private
  */
 llHidGnubby.prototype.queueFrame_ = function(frame, cid, cmd, arg) {
@@ -404,7 +404,7 @@
   );
 };
 /**
- * @param {function(Array)} cb
+ * @param {function(Array)} cb Enumeration callback
  */
 llHidGnubby.enumerate = function(cb) {
   chrome.hid.getDevices({'vendorId': 4176, 'productId': 512}, cb);
@@ -435,7 +435,7 @@
 };
 
 /**
- * @param {*} dev
+ * @param {*} dev A browser API device object
  * @return {llGnubbyDeviceId} A device identifier for the device.
  */
 llHidGnubby.deviceToDeviceId = function(dev) {
@@ -446,7 +446,7 @@
 
 /**
  * Registers this implementation with gnubbies.
- * @param {Gnubbies} gnubbies
+ * @param {Gnubbies} gnubbies Gnubbies registry
  */
 llHidGnubby.register = function(gnubbies) {
   var HID_GNUBBY_IMPL = {
diff --git a/chrome/browser/resources/cryptotoken/llusbgnubby.js b/chrome/browser/resources/cryptotoken/llusbgnubby.js
index 6dbaf7f..624af64 100644
--- a/chrome/browser/resources/cryptotoken/llusbgnubby.js
+++ b/chrome/browser/resources/cryptotoken/llusbgnubby.js
@@ -91,7 +91,7 @@
 
 /**
  * Push frame to all clients.
- * @param {ArrayBuffer} f
+ * @param {ArrayBuffer} f Data frame
  * @private
  */
 llUsbGnubby.prototype.publishFrame_ = function(f) {
@@ -262,8 +262,8 @@
 
 /**
  * Check whether channel is locked for this request or not.
- * @param {number} cid
- * @param {number} cmd
+ * @param {number} cid Channel id
+ * @param {number} cmd Command to be sent
  * @return {boolean} true if not locked for this request.
  * @private
  */
@@ -298,9 +298,9 @@
 
 /**
  * Update or grab lock.
- * @param {number} cid
- * @param {number} cmd
- * @param {number} arg
+ * @param {number} cid Channel id
+ * @param {number} cmd Command
+ * @param {number} arg Command argument
  * @private
  */
 llUsbGnubby.prototype.updateLock_ = function(cid, cmd, arg) {
@@ -343,7 +343,7 @@
  * If queue was empty, initiate the write.
  * @param {number} cid The client's channel ID.
  * @param {number} cmd The command to send.
- * @param {ArrayBuffer} data
+ * @param {ArrayBuffer} data Command argument data
  */
 llUsbGnubby.prototype.queueCommand = function(cid, cmd, data) {
   if (!this.dev) return;
@@ -371,7 +371,7 @@
 };
 
 /**
- * @param {function(Array)} cb
+ * @param {function(Array)} cb Enumerate callback
  */
 llUsbGnubby.enumerate = function(cb) {
   chrome.usb.getDevices({'vendorId': 4176, 'productId': 529}, cb);
@@ -386,7 +386,7 @@
  *     result of opening the device.
  */
 llUsbGnubby.open = function(gnubbies, which, dev, cb) {
-  /** @param {chrome.usb.ConnectionHandle=} handle */
+  /** @param {chrome.usb.ConnectionHandle=} handle Connection handle */
   function deviceOpened(handle) {
     if (!handle) {
       console.warn(UTIL_fmt('failed to open device. permissions issue?'));
@@ -457,7 +457,7 @@
 };
 
 /**
- * @param {*} dev
+ * @param {*} dev Chrome usb device
  * @return {llGnubbyDeviceId} A device identifier for the device.
  */
 llUsbGnubby.deviceToDeviceId = function(dev) {
@@ -468,7 +468,7 @@
 
 /**
  * Registers this implementation with gnubbies.
- * @param {Gnubbies} gnubbies
+ * @param {Gnubbies} gnubbies Gnubbies singleton instance
  */
 llUsbGnubby.register = function(gnubbies) {
   var USB_GNUBBY_IMPL = {
diff --git a/chrome/browser/resources/cryptotoken/manifest.json b/chrome/browser/resources/cryptotoken/manifest.json
index 0ae3b0b..57e455e 100644
--- a/chrome/browser/resources/cryptotoken/manifest.json
+++ b/chrome/browser/resources/cryptotoken/manifest.json
@@ -17,6 +17,7 @@
   ],
   "externally_connectable": {
     "matches": [
+      "https://login.corp.google.com/*",
       "https://accounts.google.com/*",
       "https://security.google.com/*"
     ],
diff --git a/chrome/browser/resources/cryptotoken/multiplesigner.js b/chrome/browser/resources/cryptotoken/multiplesigner.js
index e132a2a..1f22c71 100644
--- a/chrome/browser/resources/cryptotoken/multiplesigner.js
+++ b/chrome/browser/resources/cryptotoken/multiplesigner.js
@@ -6,8 +6,6 @@
  * @fileoverview A multiple gnubby signer wraps the process of opening a number
  * of gnubbies, signing each challenge in an array of challenges until a
  * success condition is satisfied, and yielding each succeeding gnubby.
- *
- * @author juanlang@google.com (Juan Lang)
  */
 'use strict';
 
@@ -91,10 +89,9 @@
  * object's values are base64-encoded.
  * If the signer is currently idle, begins signing the new challenges.
  *
- * @param {Array} challenges
- * @param {boolean} finalChallenges
+ * @param {Array} challenges Encoded challenges
+ * @param {boolean} finalChallenges True iff there are no more challenges to add
  * @return {boolean} whether the challenges were successfully added.
- * @public
  */
 MultipleGnubbySigner.prototype.addEncodedChallenges =
     function(challenges, finalChallenges) {
@@ -120,10 +117,9 @@
  * Adds challenges to the set of challenges being tried by this signer.
  * If the signer is currently idle, begins signing the new challenges.
  *
- * @param {Array.<SignHelperChallenge>} challenges
- * @param {boolean} finalChallenges
+ * @param {Array.<SignHelperChallenge>} challenges Challenges to add
+ * @param {boolean} finalChallenges True iff there are no more challnges to add
  * @return {boolean} whether the challenges were successfully added.
- * @public
  */
 MultipleGnubbySigner.prototype.addChallenges =
     function(challenges, finalChallenges) {
@@ -154,7 +150,6 @@
  * challenges to sign, begins signing on the new gnubby with them.
  * @param {llGnubbyDeviceId} gnubbyIndex The index of the gnubby to add.
  * @return {boolean} Whether the gnubby was added successfully.
- * @public
  */
 MultipleGnubbySigner.prototype.addGnubby = function(gnubbyIndex) {
   if (this.numComplete_ && this.numComplete_ == this.signers_.length)
@@ -208,7 +203,7 @@
  * @param {number} index the index of the gnubby whose result this is
  * @param {usbGnubby} gnubby the underlying gnubby that succeded.
  * @param {number} code the result code of the sign operation
- * @param {SingleSignerResult=} signResult
+ * @param {SingleSignerResult=} signResult Result object
  * @private
  */
 MultipleGnubbySigner.prototype.signSucceededCallback_ =
@@ -255,10 +250,10 @@
 };
 
 /**
- * @param {number} code
- * @param {usbGnubby} gnubby
- * @param {number} gnubbyIndex
- * @param {SingleSignerResult=} singleSignerResult
+ * @param {number} code Success status code
+ * @param {usbGnubby} gnubby The gnubby that succeeded
+ * @param {number} gnubbyIndex The gnubby's index
+ * @param {SingleSignerResult=} singleSignerResult Result object
  * @private
  */
 MultipleGnubbySigner.prototype.notifySuccess_ =
diff --git a/chrome/browser/resources/cryptotoken/requestqueue.js b/chrome/browser/resources/cryptotoken/requestqueue.js
index 4628554..1516f2f 100644
--- a/chrome/browser/resources/cryptotoken/requestqueue.js
+++ b/chrome/browser/resources/cryptotoken/requestqueue.js
@@ -4,8 +4,6 @@
 
 /**
  * @fileoverview Queue of pending requests from an origin.
- *
- * @author juanlang@google.com (Juan Lang)
  */
 'use strict';
 
@@ -69,7 +67,7 @@
 
 /**
  * Inserts this token into the queue.
- * @param {RequestToken} token
+ * @param {RequestToken} token Queue token
  * @private
  */
 RequestQueue.prototype.insertToken_ = function(token) {
@@ -86,7 +84,7 @@
 
 /**
  * Removes this token from the queue.
- * @param {RequestToken} token
+ * @param {RequestToken} token Queue token
  * @private
  */
 RequestQueue.prototype.removeToken_ = function(token) {
@@ -114,7 +112,7 @@
 /**
  * Completes this token's request, and begins the next queued request, if one
  * exists.
- * @param {RequestToken} token
+ * @param {RequestToken} token Queue token
  */
 RequestQueue.prototype.complete = function(token) {
   var next = token.next;
@@ -133,7 +131,7 @@
  * Queues this request, and, if it's the first request, begins work on it.
  * @param {function(QueuedRequestToken)} beginCb Called when work begins on this
  *     request.
- * @param {Countdown} timer
+ * @param {Countdown} timer Countdown timer
  * @return {QueuedRequestToken} A token for the request.
  */
 RequestQueue.prototype.queueRequest = function(beginCb, timer) {
@@ -163,11 +161,11 @@
 
 /**
  * Queues this request, and, if it's the first request, begins work on it.
- * @param {string} appId
- * @param {string} origin
+ * @param {string} appId Application Id
+ * @param {string} origin Request origin
  * @param {function(QueuedRequestToken)} beginCb Called when work begins on this
  *     request.
- * @param {Countdown} timer
+ * @param {Countdown} timer Countdown timer
  * @return {QueuedRequestToken} A token for the request.
  */
 OriginKeyedRequestQueue.prototype.queueRequest =
diff --git a/chrome/browser/resources/cryptotoken/sha256.js b/chrome/browser/resources/cryptotoken/sha256.js
index b41cb92..fd5834a 100644
--- a/chrome/browser/resources/cryptotoken/sha256.js
+++ b/chrome/browser/resources/cryptotoken/sha256.js
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// SHA256 in javascript by mschilder.
-//
+/** @fileoverview SHA256 in javascript */
 // SHA256 {
 //  SHA256();
 //  void reset();
@@ -17,14 +16,22 @@
   this._W = new Array(64);
   this._pad = new Array(64);
   this._k = [
-   0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
-   0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
-   0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-   0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
-   0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
-   0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-   0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
-   0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
+   0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+   0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+   0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+   0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+   0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+   0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+   0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+   0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+   0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+   0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+   0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+   0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+   0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+   0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+   0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+   0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
 
   this._pad[0] = 0x80;
   for (var i = 1; i < 64; ++i) this._pad[i] = 0;
@@ -32,14 +39,19 @@
   this.reset();
 }
 
+/** Reset the hasher */
 SHA256.prototype.reset = function() {
   this._chain = [
-    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
+    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
 
   this._inbuf = 0;
   this._total = 0;
 };
 
+/** Hash the next block of 64 bytes
+ * @param {Array.<number>} buf A 64 byte buffer
+ */
 SHA256.prototype._compress = function(buf) {
   var W = this._W;
   var k = this._k;
@@ -48,7 +60,10 @@
 
   // get 16 big endian words
   for (var i = 0; i < 64; i += 4) {
-    var w = (buf[i] << 24) | (buf[i + 1] << 16) | (buf[i + 2] << 8) | (buf[i + 3]);
+    var w = (buf[i] << 24) |
+            (buf[i + 1] << 16) |
+            (buf[i + 2] << 8) |
+            (buf[i + 3]);
     W[i / 4] = w;
   }
 
@@ -96,6 +111,9 @@
   this._chain[7] += H;
 };
 
+/** Update the hash with additional data
+ * @param {Array.<number>|Uint8Array} bytes The data
+ * @param {number=} opt_length How many bytes to hash, if not all */
 SHA256.prototype.update = function(bytes, opt_length) {
   if (!opt_length) opt_length = bytes.length;
 
@@ -109,6 +127,11 @@
   }
 };
 
+/** Update the hash with a specified range from a data buffer
+ * @param {Array.<number>} bytes The data buffer
+ * @param {number} start Starting index of the range in bytes
+ * @param {number} end End index, will not be included in range
+ */
 SHA256.prototype.updateRange = function(bytes, start, end) {
   this._total += (end - start);
   for (var n = start; n < end; ++n) {
@@ -123,8 +146,8 @@
 /**
  * Optionally update the hash with additional arguments, and return the
  * resulting hash value.
- * @param {...*} var_args
- * @return the SHA256 hash value.
+ * @param {...*} var_args Data buffers to hash
+ * @return {Array.<number>} the SHA256 hash value.
  */
 SHA256.prototype.digest = function(var_args) {
   for (var i = 0; i < arguments.length; ++i)
diff --git a/chrome/browser/resources/cryptotoken/signer.js b/chrome/browser/resources/cryptotoken/signer.js
index e17142e..1e6e231 100644
--- a/chrome/browser/resources/cryptotoken/signer.js
+++ b/chrome/browser/resources/cryptotoken/signer.js
@@ -4,8 +4,6 @@
 
 /**
  * @fileoverview Handles web page requests for gnubby sign requests.
- *
- * @author juanlang@google.com (Juan Lang)
  */
 
 'use strict';
@@ -22,7 +20,8 @@
  * @param {Function} sendResponse Called back with the result of the sign.
  * @param {boolean} toleratesMultipleResponses Whether the sendResponse
  *     callback can be called more than once, e.g. for progress updates.
- * @return {Closeable}
+ * @return {Closeable} Request handler that should be closed when the browser
+ *     message channel is closed.
  */
 function handleSignRequest(factory, sender, request, enforceAppIdValid,
     sendResponse, toleratesMultipleResponses) {
@@ -130,16 +129,16 @@
 
 /**
  * Adapter class representing a queued sign request.
- * @param {!SignData} signData
- * @param {!SignHelperFactory} factory
- * @param {Countdown} timer
- * @param {string} origin
- * @param {boolean} enforceAppIdValid
- * @param {function(number)} errorCb
- * @param {function(SignChallenge, string, string)} successCb
- * @param {(function(number)|undefined)} opt_progressCb
- * @param {string|undefined} opt_tlsChannelId
- * @param {string|undefined} opt_logMsgUrl
+ * @param {!SignData} signData Signature data
+ * @param {!SignHelperFactory} factory Factory for SignHelper instances
+ * @param {Countdown} timer Timeout timer
+ * @param {string} origin Signature origin
+ * @param {boolean} enforceAppIdValid If to enforce appId validity
+ * @param {function(number)} errorCb Error callback
+ * @param {function(SignChallenge, string, string)} successCb Success callback
+ * @param {(function(number)|undefined)} opt_progressCb Progress callback
+ * @param {string|undefined} opt_tlsChannelId TLS Channel Id
+ * @param {string|undefined} opt_logMsgUrl Url to post log messages to
  * @constructor
  * @implements {Closeable}
  */
@@ -222,7 +221,7 @@
  * Called when this request's signer succeeds.
  * @param {SignChallenge} challenge The challenge that was signed.
  * @param {string} info The sign result.
- * @param {string} browserData
+ * @param {string} browserData Browser data JSON
  * @private
  */
 QueuedSignRequest.prototype.signerSucceeded_ =
@@ -294,7 +293,7 @@
 /**
  * Creates a timer with an expiry greater than the expiration time of the given
  * timer.
- * @param {Countdown} timer
+ * @param {Countdown} timer Timeout timer
  * @private
  */
 Signer.prototype.createWatchdog_ = function(timer) {
@@ -353,7 +352,7 @@
 /**
  * Creates challenges for helper from challenges.
  * @param {Array.<SignChallenge>} challenges Challenges to add.
- * @return {Array.<SignHelperChallenge>}
+ * @return {Array.<SignHelperChallenge>} Encoded challenges
  * @private
  */
 Signer.prototype.encodeSignChallenges_ = function(challenges) {
@@ -491,7 +490,7 @@
 
 /**
  * Notifies the caller of error with the given error code.
- * @param {number} code
+ * @param {number} code Error code
  * @private
  */
 Signer.prototype.notifyError_ = function(code) {
@@ -506,7 +505,7 @@
  * Notifies the caller of success.
  * @param {SignChallenge} challenge The challenge that was signed.
  * @param {string} info The sign result.
- * @param {string} browserData
+ * @param {string} browserData Browser data JSON
  * @private
  */
 Signer.prototype.notifySuccess_ = function(challenge, info, browserData) {
@@ -519,7 +518,7 @@
 
 /**
  * Notifies the caller of progress with the error code.
- * @param {number} code
+ * @param {number} code Status code
  * @private
  */
 Signer.prototype.notifyProgress_ = function(code) {
@@ -571,8 +570,8 @@
 
 /**
  * Called by the helper upon error.
- * @param {number} code
- * @param {boolean} anyGnubbies
+ * @param {number} code Error code
+ * @param {boolean} anyGnubbies If any gnubbies were found
  * @private
  */
 Signer.prototype.helperError_ = function(code, anyGnubbies) {
@@ -603,8 +602,8 @@
 
 /**
  * Called by helper to notify progress.
- * @param {number} code
- * @param {boolean} anyGnubbies
+ * @param {number} code Status code
+ * @param {boolean} anyGnubbies If any gnubbies were found
  * @private
  */
 Signer.prototype.helperProgress_ = function(code, anyGnubbies) {
diff --git a/chrome/browser/resources/cryptotoken/signhelper.js b/chrome/browser/resources/cryptotoken/signhelper.js
index 17db212..1b61567 100644
--- a/chrome/browser/resources/cryptotoken/signhelper.js
+++ b/chrome/browser/resources/cryptotoken/signhelper.js
@@ -5,7 +5,6 @@
 /**
  * @fileoverview Provides a "bottom half" helper to assist with raw sign
  * requests.
- * @author juanlang@google.com (Juan Lang)
  */
 'use strict';
 
diff --git a/chrome/browser/resources/cryptotoken/singlesigner.js b/chrome/browser/resources/cryptotoken/singlesigner.js
index a30d68b..f72a3b5 100644
--- a/chrome/browser/resources/cryptotoken/singlesigner.js
+++ b/chrome/browser/resources/cryptotoken/singlesigner.js
@@ -6,8 +6,6 @@
  * @fileoverview A single gnubby signer wraps the process of opening a gnubby,
  * signing each challenge in an array of challenges until a success condition
  * is satisfied, and finally yielding the gnubby upon success.
- *
- * @author juanlang@google.com (Juan Lang)
  */
 
 'use strict';
@@ -136,8 +134,8 @@
  * Adds challenges to the set of challenges being tried by this signer.
  * If the signer is currently idle, begins signing the new challenges.
  *
- * @param {Array.<SignHelperChallenge>} challenges
- * @param {boolean} finalChallenges
+ * @param {Array.<SignHelperChallenge>} challenges Sign challenges
+ * @param {boolean} finalChallenges True if there are no more challenges to add
  * @return {boolean} Whether the challenges were accepted.
  */
 SingleGnubbySigner.prototype.addChallenges =
@@ -240,7 +238,7 @@
       }
       break;
     default:
-      // TODO(juanlang): This won't be confused with success, but should it be
+      // TODO: This won't be confused with success, but should it be
       // part of the same namespace as the other error codes, which are
       // always in DeviceStatusCodes.*?
       this.goToError_(rc);
@@ -264,7 +262,7 @@
 };
 
 /**
- * @param {number} challengeIndex
+ * @param {number} challengeIndex Index of challenge to sign
  * @private
  */
 SingleGnubbySigner.prototype.doSign_ = function(challengeIndex) {
@@ -297,10 +295,10 @@
     // Sign challenge for a different version of gnubby: return wrong data.
     this.signCallback_(challengeIndex, DeviceStatusCodes.WRONG_DATA_STATUS);
   } else {
-    var opt_nowink = this.forEnroll_;
+    var nowink = this.forEnroll_;
     this.gnubby_.sign(challengeHash, appIdHash, keyHandle,
         this.signCallback_.bind(this, challengeIndex),
-        opt_nowink);
+        nowink);
   }
 };
 
@@ -308,7 +306,7 @@
  * Called with the result of a single sign operation.
  * @param {number} challengeIndex the index of the challenge just attempted
  * @param {number} code the result of the sign operation
- * @param {ArrayBuffer=} opt_info
+ * @param {ArrayBuffer=} opt_info Optional result data
  * @private
  */
 SingleGnubbySigner.prototype.signCallback_ =
@@ -338,7 +336,7 @@
       break;
 
     case DeviceStatusCodes.TIMEOUT_STATUS:
-      // TODO(juanlang): On a TIMEOUT_STATUS, sync first, then retry.
+      // TODO: On a TIMEOUT_STATUS, sync first, then retry.
     case DeviceStatusCodes.BUSY_STATUS:
       this.doSign_(this.challengeIndex_);
       break;
@@ -396,7 +394,7 @@
 
 /**
  * Switches to the error state, and notifies caller.
- * @param {number} code
+ * @param {number} code Error code
  * @private
  */
 SingleGnubbySigner.prototype.goToError_ = function(code) {
@@ -410,9 +408,9 @@
 
 /**
  * Switches to the success state, and notifies caller.
- * @param {number} code
- * @param {SignHelperChallenge=} opt_challenge
- * @param {ArrayBuffer=} opt_info
+ * @param {number} code Status code
+ * @param {SignHelperChallenge=} opt_challenge The challenge signed
+ * @param {ArrayBuffer=} opt_info Optional result data
  * @private
  */
 SingleGnubbySigner.prototype.goToSuccess_ =
diff --git a/chrome/browser/resources/cryptotoken/usbenrollhelper.js b/chrome/browser/resources/cryptotoken/usbenrollhelper.js
index 65838a1..0552a9d 100644
--- a/chrome/browser/resources/cryptotoken/usbenrollhelper.js
+++ b/chrome/browser/resources/cryptotoken/usbenrollhelper.js
@@ -4,13 +4,12 @@
 
 /**
  * @fileoverview Implements an enroll helper using USB gnubbies.
- * @author juanlang@google.com (Juan Lang)
  */
 'use strict';
 
 /**
- * @param {!GnubbyFactory} factory
- * @param {!Countdown} timer
+ * @param {!GnubbyFactory} factory A factory for Gnubby instances
+ * @param {!Countdown} timer A timer for enroll timeout
  * @param {function(number, boolean)} errorCb Called when an enroll request
  *     fails with an error code and whether any gnubbies were found.
  * @param {function(string, string)} successCb Called with the result of a
@@ -100,7 +99,7 @@
 /**
  * Called with the result of enumerating gnubbies.
  * @param {number} rc the result of the enumerate.
- * @param {Array.<llGnubbyDeviceId>} indexes
+ * @param {Array.<llGnubbyDeviceId>} indexes Device ids of enumerated gnubbies
  * @private
  */
 UsbEnrollHelper.prototype.enumerateCallback_ = function(rc, indexes) {
@@ -148,7 +147,7 @@
 
 /**
  * Called with the result of enumerating gnubby indexes.
- * @param {Array.<llGnubbyDeviceId>} indexes
+ * @param {Array.<llGnubbyDeviceId>} indexes Device ids of enumerated gnubbies
  * @private
  */
 UsbEnrollHelper.prototype.gotSomeGnubbies_ = function(indexes) {
@@ -201,8 +200,8 @@
 
 /**
  * Called when a MultipleGnubbySigner finds a gnubby that can enroll.
- * @param {number} code
- * @param {MultipleSignerResult} signResult
+ * @param {number} code Status code
+ * @param {MultipleSignerResult} signResult Signature results
  * @private
  */
 UsbEnrollHelper.prototype.signerFoundGnubby_ = function(code, signResult) {
@@ -224,7 +223,7 @@
 /**
  * Attempts to match the gnubby's U2F version with an appropriate enroll
  * challenge.
- * @param {usbGnubby} gnubby
+ * @param {usbGnubby} gnubby Gnubby instance
  * @private
  */
 UsbEnrollHelper.prototype.matchEnrollVersionToGnubby_ = function(gnubby) {
@@ -236,7 +235,7 @@
 
 /**
  * Called with the result of a version command.
- * @param {usbGnubby} gnubby
+ * @param {usbGnubby} gnubby Gnubby instance
  * @param {number} rc result of version command.
  * @param {ArrayBuffer=} data version.
  * @private
@@ -252,7 +251,7 @@
 
 /**
  * Drops the gnubby from the list of eligible gnubbies.
- * @param {usbGnubby} gnubby
+ * @param {usbGnubby} gnubby Gnubby instance
  * @private
  */
 UsbEnrollHelper.prototype.removeWaitingGnubby_ = function(gnubby) {
@@ -266,7 +265,7 @@
 /**
  * Drops the gnubby from the list of eligible gnubbies, as it has the wrong
  * version.
- * @param {usbGnubby} gnubby
+ * @param {usbGnubby} gnubby Gnubby instance
  * @private
  */
 UsbEnrollHelper.prototype.removeWrongVersionGnubby_ = function(gnubby) {
@@ -280,8 +279,8 @@
 /**
  * Attempts enrolling a particular gnubby with a challenge of the appropriate
  * version.
- * @param {usbGnubby} gnubby
- * @param {string} version
+ * @param {usbGnubby} gnubby Gnubby instance
+ * @param {string} version Protocol version
  * @private
  */
 UsbEnrollHelper.prototype.tryEnroll_ = function(gnubby, version) {
@@ -298,7 +297,7 @@
 
 /**
  * Finds the (first) challenge of the given version in this helper's challenges.
- * @param {string} version
+ * @param {string} version Protocol version
  * @return {Object} challenge, if found, or null if not.
  * @private
  */
@@ -313,10 +312,10 @@
 
 /**
  * Called with the result of an enroll request to a gnubby.
- * @param {usbGnubby} gnubby
- * @param {string} version
- * @param {number} code
- * @param {ArrayBuffer=} infoArray
+ * @param {usbGnubby} gnubby Gnubby instance
+ * @param {string} version Protocol version
+ * @param {number} code Status code
+ * @param {ArrayBuffer=} infoArray Returned data
  * @private
  */
 UsbEnrollHelper.prototype.enrollCallback_ =
@@ -374,8 +373,8 @@
 };
 
 /**
- * @param {number} code
- * @param {boolean} anyGnubbies
+ * @param {number} code Status code
+ * @param {boolean} anyGnubbies If any gnubbies were found
  * @private
  */
 UsbEnrollHelper.prototype.notifyError_ = function(code, anyGnubbies) {
@@ -387,8 +386,8 @@
 };
 
 /**
- * @param {string} version
- * @param {string} info
+ * @param {string} version Protocol version
+ * @param {string} info B64 encoded success data
  * @private
  */
 UsbEnrollHelper.prototype.notifySuccess_ = function(version, info) {
@@ -400,8 +399,8 @@
 };
 
 /**
- * @param {number} code
- * @param {boolean} anyGnubbies
+ * @param {number} code Status code
+ * @param {boolean} anyGnubbies If any gnubbies were found
  * @private
  */
 UsbEnrollHelper.prototype.notifyProgress_ = function(code, anyGnubbies) {
@@ -422,7 +421,7 @@
 }
 
 /**
- * @param {!Countdown} timer
+ * @param {!Countdown} timer Timeout timer
  * @param {function(number, boolean)} errorCb Called when an enroll request
  *     fails with an error code and whether any gnubbies were found.
  * @param {function(string, string)} successCb Called with the result of a
diff --git a/chrome/browser/resources/cryptotoken/usbgnubbyfactory.js b/chrome/browser/resources/cryptotoken/usbgnubbyfactory.js
index d9c54c9..6363d36 100644
--- a/chrome/browser/resources/cryptotoken/usbgnubbyfactory.js
+++ b/chrome/browser/resources/cryptotoken/usbgnubbyfactory.js
@@ -5,12 +5,11 @@
 /**
  * @fileoverview Contains a simple factory for creating and opening usbGnubby
  * instances.
- * @author juanlang@google.com (Juan Lang)
  */
 'use strict';
 
 /**
- * @param {Gnubbies} gnubbies
+ * @param {Gnubbies} gnubbies Gnubbies singleton instance
  * @constructor
  * @implements {GnubbyFactory}
  */
@@ -39,7 +38,7 @@
 
 /**
  * Enumerates gnubbies.
- * @param {function(number, Array.<llGnubbyDeviceId>)} cb
+ * @param {function(number, Array.<llGnubbyDeviceId>)} cb Enumerate callback
  */
 UsbGnubbyFactory.prototype.enumerate = function(cb) {
   this.gnubbies_.enumerate(cb);
diff --git a/chrome/browser/resources/cryptotoken/usbsignhelper.js b/chrome/browser/resources/cryptotoken/usbsignhelper.js
index 2c5b643..224ead2 100644
--- a/chrome/browser/resources/cryptotoken/usbsignhelper.js
+++ b/chrome/browser/resources/cryptotoken/usbsignhelper.js
@@ -4,14 +4,13 @@
 
 /**
  * @fileoverview Implements a sign helper using USB gnubbies.
- * @author juanlang@google.com (Juan Lang)
  */
 'use strict';
 
 var CORRUPT_sign = false;
 
 /**
- * @param {!GnubbyFactory} factory
+ * @param {!GnubbyFactory} factory Factory for gnubby instances
  * @param {Countdown} timer Timer after whose expiration the caller is no longer
  *     interested in the result of a sign request.
  * @param {function(number, boolean)} errorCb Called when a sign request fails
@@ -50,7 +49,7 @@
 
 /**
  * Attempts to sign the provided challenges.
- * @param {Array.<SignHelperChallenge>} challenges
+ * @param {Array.<SignHelperChallenge>} challenges Challenges to sign
  * @return {boolean} whether this set of challenges was accepted.
  */
 UsbSignHelper.prototype.doSign = function(challenges) {
@@ -78,7 +77,7 @@
 /**
  * Called with the result of enumerating gnubbies.
  * @param {number} rc the result of the enumerate.
- * @param {Array.<llGnubbyDeviceId>} indexes
+ * @param {Array.<llGnubbyDeviceId>} indexes Indexes of found gnubbies
  */
 UsbSignHelper.prototype.enumerateCallback = function(rc, indexes) {
   if (rc) {
@@ -98,7 +97,7 @@
 
 /**
  * Called with the result of enumerating gnubby indexes.
- * @param {Array.<llGnubbyDeviceId>} indexes
+ * @param {Array.<llGnubbyDeviceId>} indexes Indexes of found gnubbies
  * @private
  */
 UsbSignHelper.prototype.gotSomeGnubbies_ = function(indexes) {
@@ -150,8 +149,8 @@
 /**
  * Called when a MultipleGnubbySigner finds a gnubby that has successfully
  * signed, or can successfully sign, one of the challenges.
- * @param {number} code
- * @param {MultipleSignerResult} signResult
+ * @param {number} code Status code
+ * @param {MultipleSignerResult} signResult Signer result object
  * @private
  */
 UsbSignHelper.prototype.signerFoundGnubby_ = function(code, signResult) {
@@ -168,9 +167,9 @@
 
 /**
  * Reports the result of a successful sign operation.
- * @param {usbGnubby} gnubby
- * @param {SignHelperChallenge} challenge
- * @param {Uint8Array} info
+ * @param {usbGnubby} gnubby Gnubby instance
+ * @param {SignHelperChallenge} challenge Challenge signed
+ * @param {Uint8Array} info Result data
  * @private
  */
 UsbSignHelper.prototype.notifySuccess_ = function(gnubby, challenge, info) {
@@ -196,7 +195,7 @@
 /**
  * Reports error to the caller.
  * @param {number} code error to report
- * @param {boolean} anyGnubbies
+ * @param {boolean} anyGnubbies If any gnubbies were found
  * @private
  */
 UsbSignHelper.prototype.notifyError_ = function(code, anyGnubbies) {
@@ -209,8 +208,8 @@
 
 /**
  * Retries signing a particular challenge on a gnubby.
- * @param {usbGnubby} gnubby
- * @param {SignHelperChallenge} challenge
+ * @param {usbGnubby} gnubby Gnubby instance
+ * @param {SignHelperChallenge} challenge Challenge to retry
  * @private
  */
 UsbSignHelper.prototype.retrySign_ = function(gnubby, challenge) {
@@ -223,9 +222,9 @@
 
 /**
  * Called when a gnubby completes a sign request.
- * @param {usbGnubby} gnubby
- * @param {SignHelperChallenge} challenge
- * @param {number} code
+ * @param {usbGnubby} gnubby Gnubby instance
+ * @param {SignHelperChallenge} challenge Challenge to retry
+ * @param {number} code Previous status code
  * @private
  */
 UsbSignHelper.prototype.retrySignIfNotTimedOut_ =
@@ -246,8 +245,8 @@
 /**
  * Removes a gnubby that was waiting for touch from the list, with the given
  * error code. If this is the last gnubby, notifies the caller of the error.
- * @param {usbGnubby} gnubby
- * @param {number} code
+ * @param {usbGnubby} gnubby Gnubby instance
+ * @param {number} code Previous status code
  * @private
  */
 UsbSignHelper.prototype.removePreviouslyEligibleGnubby_ =
@@ -274,10 +273,10 @@
 
 /**
  * Called when a gnubby completes a sign request.
- * @param {usbGnubby} gnubby
- * @param {SignHelperChallenge} challenge
- * @param {number} code
- * @param {ArrayBuffer=} infoArray
+ * @param {usbGnubby} gnubby Gnubby instance
+ * @param {SignHelperChallenge} challenge Challenge signed
+ * @param {number} code Status code
+ * @param {ArrayBuffer=} infoArray Result data
  * @private
  */
 UsbSignHelper.prototype.signCallback_ =
diff --git a/chrome/browser/resources/cryptotoken/util.js b/chrome/browser/resources/cryptotoken/util.js
index 0ce15a9..187b443 100644
--- a/chrome/browser/resources/cryptotoken/util.js
+++ b/chrome/browser/resources/cryptotoken/util.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Various string utility functions by mschilder@google.com
+/** @fileoverview Various string utility functions */
 'use strict';
 
 /**
diff --git a/chrome/browser/resources/cryptotoken/webrequest.js b/chrome/browser/resources/cryptotoken/webrequest.js
index 3d7a6d5..3dd5a0a 100644
--- a/chrome/browser/resources/cryptotoken/webrequest.js
+++ b/chrome/browser/resources/cryptotoken/webrequest.js
@@ -9,8 +9,8 @@
 
 /**
  * Gets the scheme + origin from a web url.
- * @param {string} url
- * @return {?string}
+ * @param {string} url Input url
+ * @return {?string} Scheme and origin part if url parses
  */
 function getOriginFromUrl(url) {
   var re = new RegExp('^(https?://)[^/]*/?');
@@ -27,8 +27,8 @@
 
 /**
  * Parses the text as JSON and returns it as an array of strings.
- * @param {string} text
- * @return {Array.<string>}
+ * @param {string} text Input JSON
+ * @return {Array.<string>} Array of origins
  */
 function getOriginsFromJson(text) {
   try {
@@ -72,7 +72,7 @@
 
 /**
  * Retrieves a set of distinct app ids from the SignData.
- * @param {SignData=} signData
+ * @param {SignData=} signData Input signature data
  * @return {Array.<string>} array of distinct app ids.
  */
 function getDistinctAppIds(signData) {
@@ -92,7 +92,7 @@
 /**
  * Reorganizes the requests from the SignData to an array of
  * (appId, [Request]) tuples.
- * @param {SignData} signData
+ * @param {SignData} signData Input signature data
  * @return {Array.<[string, Array.<Request>]>} array of
  *     (appId, [Request]) tuples.
  */
@@ -126,7 +126,7 @@
 
 /**
  * Fetches the allowed origins for an appId.
- * @param {string} appId
+ * @param {string} appId Application id
  * @param {boolean} allowHttp Whether http is a valid scheme for an appId.
  *     (This should be false except on test domains.)
  * @param {function(number, !Array.<string>)} cb Called back with an HTTP
@@ -143,7 +143,7 @@
     cb(200, allowedOrigins);
     return;
   }
-  // TODO(juanlang): hack for old enrolled gnubbies, don't treat
+  // TODO: hack for old enrolled gnubbies, don't treat
   // accounts.google.com/login.corp.google.com specially when cryptauth server
   // stops reporting them as appId.
   if (appId == 'https://accounts.google.com') {
@@ -158,7 +158,7 @@
   }
   // Termination of this function relies in fetchAppId completing.
   // (Not completing would be a bug in XMLHttpRequest.)
-  // TODO(juanlang): provide a termination guarantee, e.g. with a timer?
+  // TODO: provide a termination guarantee, e.g. with a timer?
   fetchAppId(appId, function(rc, fetchedAppId, origins) {
     if (rc != 200) {
       console.log(UTIL_fmt('fetching ' + fetchedAppId + ' failed: ' + rc));
@@ -172,8 +172,8 @@
 
 /**
  * Checks whether an appId is valid for a given origin.
- * @param {!string} appId
- * @param {!string} origin
+ * @param {!string} appId Application id
+ * @param {!string} origin Origin
  * @param {!Array.<string>} allowedOrigins the list of allowed origins for each
  *    appId.
  * @return {boolean} whether the appId is allowed for the origin.
@@ -233,10 +233,10 @@
 
 /**
  * Logs the result of fetching an appId.
- * @param {!string} appId
+ * @param {!string} appId Application Id
  * @param {number} millis elapsed time while fetching the appId.
  * @param {Array.<string>} allowedOrigins the allowed origins retrieved.
- * @param {string=} opt_logMsgUrl
+ * @param {string=} opt_logMsgUrl the url to post log messages to.
  */
 function logFetchAppIdResult(appId, millis, allowedOrigins, opt_logMsgUrl) {
   var logMsg = 'log=fetchappid&appid=' + appId + '&millis=' + millis +
@@ -246,9 +246,9 @@
 
 /**
  * Logs a mismatch between an origin and an appId.
- * @param {string} origin
- * @param {!string} appId
- * @param {string=} opt_logMsgUrl
+ * @param {string} origin Origin
+ * @param {!string} appId Application id
+ * @param {string=} opt_logMsgUrl the url to post log messages to
  */
 function logInvalidOriginForAppId(origin, appId, opt_logMsgUrl) {
   var logMsg = 'log=originrejected&origin=' + origin + '&appid=' + appId;
@@ -272,7 +272,7 @@
 }
 
 /**
- * @param {!string} string
+ * @param {!string} string Input string
  * @return {Array.<number>} SHA256 hash value of string.
  */
 function sha256HashOfString(string) {
@@ -287,7 +287,7 @@
  *     string.
  * 2. Converts valid JSON strings to a JS object.
  * 3. Otherwise, returns the input value unmodified.
- * @param {Object|string|undefined} opt_tlsChannelId
+ * @param {Object|string|undefined} opt_tlsChannelId TLS Channel id
  * @return {Object|string} The normalized TLS channel ID value.
  */
 function tlsChannelIdValue(opt_tlsChannelId) {
@@ -322,7 +322,7 @@
  * @param {!string} serverChallenge The server's challenge, as a base64-
  *     encoded string.
  * @param {!string} origin The server's origin, as seen by the browser.
- * @param {Object|string|undefined} opt_tlsChannelId
+ * @param {Object|string|undefined} opt_tlsChannelId TLS Channel Id
  * @return {string} A string representation of the browser data object.
  */
 function makeBrowserData(type, serverChallenge, origin, opt_tlsChannelId) {
@@ -340,7 +340,7 @@
  * @param {!string} serverChallenge The server's challenge, as a base64-
  *     encoded string.
  * @param {!string} origin The server's origin, as seen by the browser.
- * @param {Object|string|undefined} opt_tlsChannelId
+ * @param {Object|string|undefined} opt_tlsChannelId TLS Channel Id
  * @return {string} A string representation of the browser data object.
  */
 function makeEnrollBrowserData(serverChallenge, origin, opt_tlsChannelId) {
@@ -354,7 +354,7 @@
  * @param {!string} serverChallenge The server's challenge, as a base64-
  *     encoded string.
  * @param {!string} origin The server's origin, as seen by the browser.
- * @param {Object|string|undefined} opt_tlsChannelId
+ * @param {Object|string|undefined} opt_tlsChannelId TLS Channel Id
  * @return {string} A string representation of the browser data object.
  */
 function makeSignBrowserData(serverChallenge, origin, opt_tlsChannelId) {
@@ -363,11 +363,11 @@
 }
 
 /**
- * @param {string} browserData
- * @param {string} appId
- * @param {string} encodedKeyHandle
- * @param {string=} version
- * @return {SignHelperChallenge}
+ * @param {string} browserData Browser data as JSON
+ * @param {string} appId Application Id
+ * @param {string} encodedKeyHandle B64 encoded key handle
+ * @param {string=} version Protocol version
+ * @return {SignHelperChallenge} Challenge object
  */
 function makeChallenge(browserData, appId, encodedKeyHandle, version) {
   var appIdHash = B64_encode(sha256HashOfString(appId));
diff --git a/chrome/browser/resources/extensions/extension_list.js b/chrome/browser/resources/extensions/extension_list.js
index a3b02a5..713ac66 100644
--- a/chrome/browser/resources/extensions/extension_list.js
+++ b/chrome/browser/resources/extensions/extension_list.js
@@ -88,7 +88,7 @@
       if (extension.managedInstall) {
         node.classList.add('may-not-modify');
         node.classList.add('may-not-remove');
-      } else if (extension.suspiciousInstall) {
+      } else if (extension.suspiciousInstall || extension.corruptInstall) {
         node.classList.add('may-not-modify');
       }
 
@@ -223,10 +223,12 @@
         // The 'Enabled' checkbox.
         var enable = node.querySelector('.enable-checkbox');
         enable.hidden = false;
-        enable.querySelector('input').disabled = extension.managedInstall ||
-                                                 extension.suspiciousInstall;
+        var managedOrHosedExtension = extension.managedInstall ||
+                                      extension.suspiciousInstall ||
+                                      extension.corruptInstall;
+        enable.querySelector('input').disabled = managedOrHosedExtension;
 
-        if (!extension.managedInstall && !extension.suspiciousInstall) {
+        if (!managedOrHosedExtension) {
           enable.addEventListener('click', function(e) {
             // When e.target is the label instead of the checkbox, it doesn't
             // have the checked property and the state of the checkbox is
@@ -282,9 +284,15 @@
       // Then the 'managed, cannot uninstall/disable' message.
       if (extension.managedInstall) {
         node.querySelector('.managed-message').hidden = false;
-      } else if (extension.suspiciousInstall) {
-        // Then the 'This isn't from the webstore, looks suspicious' message.
-        node.querySelector('.suspicious-install-message').hidden = false;
+      } else {
+        if (extension.suspiciousInstall) {
+          // Then the 'This isn't from the webstore, looks suspicious' message.
+          node.querySelector('.suspicious-install-message').hidden = false;
+        }
+        if (extension.corruptInstall) {
+          // Then the 'This is a corrupt extension' message.
+          node.querySelector('.corrupt-install-message').hidden = false;
+        }
       }
 
       // Then active views.
diff --git a/chrome/browser/resources/extensions/extensions.css b/chrome/browser/resources/extensions/extensions.css
index 47c73fc..ebd09e3 100644
--- a/chrome/browser/resources/extensions/extensions.css
+++ b/chrome/browser/resources/extensions/extensions.css
@@ -44,6 +44,7 @@
 #apps-developer-tools-promo {
   -webkit-margin-before: 15px;
   -webkit-padding-before: 5px;
+  -webkit-padding-end: 3px;
   align-items: center;
   border-top: 1px solid #eee;
   display: flex;
@@ -54,8 +55,7 @@
   content: url(apps_developer_tools_promo_48.png);
 }
 
-#apps-developer-tools-promo-text,
-#apps-developer-tools-promo-link {
+#apps-developer-tools-promo-text {
   -webkit-margin-start: 5px;
 }
 
@@ -67,6 +67,7 @@
 
 #apps-developer-tools-promo .close-button {
   background: url(chrome://theme/IDR_CLOSE_DIALOG) no-repeat center center;
+  border: 0;
   height: 14px;
   width: 14px;
   z-index: 1;
diff --git a/chrome/browser/resources/extensions/extensions.html b/chrome/browser/resources/extensions/extensions.html
index b0af6cd..6ba6379 100644
--- a/chrome/browser/resources/extensions/extensions.html
+++ b/chrome/browser/resources/extensions/extensions.html
@@ -92,12 +92,11 @@
     <div id="apps-developer-tools-promo">
       <img></img>
       <span id="apps-developer-tools-promo-text"
-          i18n-content="extensionSettingsAppsDevToolsPromoText"></span>
-      <a id="apps-developer-tools-promo-link" target="_blank"
-         i18n-content="extensionSettingsAppsDevToolsLinkText"
-         i18n-values="href:extensionSettingsAppsDevToolsUrl"></a>
+          i18n-values=".innerHTML:extensionSettingsAppsDevToolsPromoHTML">
+      </span>
       <div id="apps-developer-tools-promo-close-wrapper">
-        <div class="close-button"></div>
+        <button i18n-values="title:extensionSettingsAppDevToolsPromoClose"
+            class="custom-appearance close-button"></button>
       </div>
     </div>
   </div>
@@ -149,7 +148,15 @@
             <span i18n-content="extensionSettingsSuspiciousInstall"></span>
             <a target="_blank" class="learn-more-link"
                 i18n-values="href:extensionSettingsSuspiciousInstallHelpUrl"
-                i18n-content="extensionSettingsSuspiciousInstallLearnMore"
+                i18n-content="extensionSettingsLearnMore"
+                href="#">
+            </a>
+          </div>
+          <div class="corrupt-install-message" hidden>
+            <span i18n-content="extensionSettingsCorruptInstall"></span>
+            <a target="_blank" class="learn-more-link"
+                i18n-values="href:extensionSettingsCorruptInstallHelpUrl"
+                i18n-content="extensionSettingsLearnMore"
                 href="#">
             </a>
           </div>
diff --git a/chrome/browser/resources/extensions/extensions.js b/chrome/browser/resources/extensions/extensions.js
index 54a726f..ec2d60c 100644
--- a/chrome/browser/resources/extensions/extensions.js
+++ b/chrome/browser/resources/extensions/extensions.js
@@ -88,6 +88,13 @@
     __proto__: HTMLDivElement.prototype,
 
     /**
+     * Whether or not to try to display the Apps Developer Tools promotion.
+     * @type {boolean}
+     * @private
+     */
+    displayPromo_: false,
+
+    /**
      * Perform initial setup.
      */
     initialize: function() {
@@ -122,7 +129,8 @@
       // Set up the close dialog for the apps developer tools promo.
       $('apps-developer-tools-promo').querySelector('.close-button').
           addEventListener('click', function(e) {
-        $('extension-settings').classList.remove('adt-promo');
+        this.displayPromo_ = false;
+        this.updatePromoVisibility_();
         chrome.send('extensionSettingsDismissADTPromo');
       }.bind(this));
 
@@ -174,6 +182,26 @@
     },
 
     /**
+     * Updates the Chrome Apps and Extensions Developer Tools promotion's
+     * visibility.
+     * @private
+     */
+    updatePromoVisibility_: function() {
+      var extensionSettings = $('extension-settings');
+      var visible = extensionSettings.classList.contains('dev-mode') &&
+                    this.displayPromo_;
+
+      var adtPromo = $('apps-developer-tools-promo');
+      var controls = adtPromo.querySelectorAll('a, button');
+      Array.prototype.forEach.call(controls, function(control) {
+        control[visible ? 'removeAttribute' : 'setAttribute']('tabindex', '-1');
+      });
+
+      adtPromo.setAttribute('aria-hidden', !visible);
+      extensionSettings.classList.toggle('adt-promo', visible);
+    },
+
+    /**
      * Handles the Pack Extension button.
      * @param {Event} e Change event.
      * @private
@@ -226,6 +254,7 @@
       } else {
         $('extension-settings').classList.remove('dev-mode');
       }
+      window.setTimeout(this.updatePromoVisibility_.bind(this));
 
       chrome.send('extensionSettingsToggleDeveloperMode');
     },
@@ -300,7 +329,9 @@
       $('toggle-dev-on').checked = false;
     }
 
-    pageDiv.classList.toggle('adt-promo', extensionsData.promoteAppsDevTools);
+    ExtensionSettings.getInstance().displayPromo_ =
+        extensionsData.promoteAppsDevTools;
+    ExtensionSettings.getInstance().updatePromoVisibility_();
 
     $('load-unpacked').disabled = extensionsData.loadUnpackedDisabled;
 
diff --git a/chrome/browser/resources/feedback/js/event_handler.js b/chrome/browser/resources/feedback/js/event_handler.js
index 4f5d17d..51606a8 100644
--- a/chrome/browser/resources/feedback/js/event_handler.js
+++ b/chrome/browser/resources/feedback/js/event_handler.js
@@ -31,6 +31,13 @@
   'ljoammodoonkhnehlncldjelhidljdpi', // GetHelp app.
   'ljacajndfccfgnfohlgkdphmbnpkjflk', // Chrome Remote Desktop Dev
   'gbchcmhmhahfdphkhkmpfmihenigjmpp', // Chrome Remote Desktop Stable
+  'odkaodonbgfohohmklejpjiejmcipmib', // Chrome Remote Desktop QA
+  'dokpleeekgeeiehdhmdkeimnkmoifgdd', // Chrome Remote Desktop QA backup
+  'ajoainacpilcemgiakehflpbkbfipojk', // Chrome Remote Desktop Apps V2
+  'llohocloplkbhgcfnplnoficdkiechcn', // Play Movies Dev
+  'icljpnebmoleodmchaaajbkpoipfoahp', // Play Movies Nightly
+  'mjekoljodoiapgkggnlmbecndfpbbcch', // Play Movies Beta
+  'gdijeikdkaembjbdobgfkoidjkpbmlkd', // Play Movies Stable
 ];
 
 /**
diff --git a/chrome/browser/resources/flags.css b/chrome/browser/resources/flags.css
index 96fc9ab..30f749b 100644
--- a/chrome/browser/resources/flags.css
+++ b/chrome/browser/resources/flags.css
@@ -4,7 +4,7 @@
 
 body {
   margin: 10px 10px 0;
-<if expr="not is_android">
+<if expr="not is_android and not is_ios">
   min-width: 47em;
 </if>
   /* Should match needs-restart.height + 5 */
diff --git a/chrome/browser/resources/gaia_auth/background.js b/chrome/browser/resources/gaia_auth/background.js
index 4de43a1..3baafc2 100644
--- a/chrome/browser/resources/gaia_auth/background.js
+++ b/chrome/browser/resources/gaia_auth/background.js
@@ -16,7 +16,7 @@
  *    a) A |pageLoaded| message is sent when the page has been loaded. This is
  *       forwarded to the main script as |onAuthPageLoaded|.
  *    b) If the SAML provider supports the credential passing API, the API calls
- *       are sent to this backgroudn script as |apiCall| messages. These
+ *       are sent to this background script as |apiCall| messages. These
  *       messages are forwarded unmodified to the main script.
  *    c) The injected script scrapes passwords. They are sent to this background
  *       script in |updatePassword| messages. The main script can request a list
@@ -40,7 +40,7 @@
     chrome.webRequest.onBeforeRequest.addListener(
         function(details) {
           if (this.bridges_[details.tabId])
-            return this.bridges_[details.tabId].onInsecureRequest();
+            return this.bridges_[details.tabId].onInsecureRequest(details.url);
         }.bind(this),
         {urls: ['http://*/*', 'file://*/*', 'ftp://*/*']},
         ['blocking']);
@@ -163,6 +163,8 @@
     this.channelMain_.registerMessage(
         'getScrapedPasswords',
         this.onGetScrapedPasswords_.bind(this));
+    this.channelMain_.registerMessage(
+        'apiResponse', this.onAPIResponse_.bind(this));
 
     this.channelMain_.send({
       'name': 'channelConnected'
@@ -245,12 +247,13 @@
    * Handler for webRequest.onBeforeRequest, invoked when content served over an
    * unencrypted connection is detected. Determines whether the request should
    * be blocked and if so, signals that an error message needs to be shown.
+   * @param {string} url The URL that was blocked.
    * @return {!Object} Decision whether to block the request.
    */
-  onInsecureRequest: function() {
+  onInsecureRequest: function(url) {
     if (!this.blockInsecureContent_)
       return {};
-    this.channelMain_.send({name: 'onInsecureContentBlocked'});
+    this.channelMain_.send({name: 'onInsecureContentBlocked', url: url});
     return {cancel: true};
   },
 
@@ -341,6 +344,14 @@
     return Object.keys(passwords);
   },
 
+  /**
+   * Handler for 'apiResponse' signal sent from the main script. Passes on the
+   * |msg| to the injected script.
+   */
+  onAPIResponse_: function(msg) {
+    this.channelInjected_.send(msg);
+  },
+
   onAPICall_: function(msg) {
     this.channelMain_.send(msg);
   },
diff --git a/chrome/browser/resources/gaia_auth/main.js b/chrome/browser/resources/gaia_auth/main.js
index e1daff6..9c8698c 100644
--- a/chrome/browser/resources/gaia_auth/main.js
+++ b/chrome/browser/resources/gaia_auth/main.js
@@ -16,6 +16,26 @@
     'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik';
 
 /**
+ * The lowest version of the credentials passing API supported.
+ * @type {number}
+ */
+Authenticator.MIN_API_VERSION_VERSION = 1;
+
+/**
+ * The highest version of the credentials passing API supported.
+ * @type {number}
+ */
+Authenticator.MAX_API_VERSION_VERSION = 2;
+
+/**
+ * The key types supported for credentials passing API 2 and higher.
+ * @type {Array} Array of strings.
+ */
+Authenticator.API_KEY_TYPES = [
+  'KEY_TYPE_PASSWORD_PLAIN',
+];
+
+/**
  * Singleton getter of Authenticator.
  * @return {Object} The singleton instance of Authenticator.
  */
@@ -28,7 +48,14 @@
 
 Authenticator.prototype = {
   email_: null,
-  password_: null,
+
+  // Depending on the key type chosen, this will contain the plain text password
+  // or a credential derived from it along with the information required to
+  // repeat the derivation, such as a salt. The information will be encoded so
+  // that it contains printable ASCII characters only. The exact encoding is TBD
+  // when support for key types other than plain text password is added.
+  passwordBytes_: null,
+
   attemptToken_: null,
 
   // Input params from extension initialization URL.
@@ -175,7 +202,8 @@
     var msg = {
       'method': 'completeLogin',
       'email': (opt_extraMsg && opt_extraMsg.email) || this.email_,
-      'password': (opt_extraMsg && opt_extraMsg.password) || this.password_,
+      'password': (opt_extraMsg && opt_extraMsg.password) ||
+                  this.passwordBytes_,
       'usingSAML': this.isSAMLFlow_,
       'chooseWhatToSync': this.chooseWhatToSync_ || false,
       'skipForNow': opt_extraMsg && opt_extraMsg.skipForNow,
@@ -231,10 +259,10 @@
     if (isSAMLPage && !this.isSAMLFlow_) {
       // GAIA redirected to a SAML login page. The credentials provided to this
       // page will determine what user gets logged in. The credentials obtained
-      // from the GAIA login from are no longer relevant and can be discarded.
+      // from the GAIA login form are no longer relevant and can be discarded.
       this.isSAMLFlow_ = true;
       this.email_ = null;
-      this.password_ = null;
+      this.passwordBytes_ = null;
     }
 
     window.parent.postMessage({
@@ -247,10 +275,13 @@
   /**
    * Invoked when the background page sends an 'onInsecureContentBlocked'
    * message.
+   * @param {!Object} msg Details sent with the message.
    */
-  onInsecureContentBlocked_: function() {
-    window.parent.postMessage({'method': 'insecureContentBlocked'},
-                              this.parentPage_);
+  onInsecureContentBlocked_: function(msg) {
+    window.parent.postMessage({
+      'method': 'insecureContentBlocked',
+      'url': msg.url
+    }, this.parentPage_);
   },
 
   /**
@@ -260,10 +291,46 @@
    */
   onAPICall_: function(msg) {
     var call = msg.call;
+    if (call.method == 'initialize') {
+      // TODO(bartfab): There was no |requestedVersion| parameter in version 1
+      // of the API. Remove this code once all consumers have switched to
+      // version 2 or higher.
+      if (!call.hasOwnProperty('requestedVersion')) {
+        if (Authenticator.MIN_API_VERSION_VERSION == 1) {
+          this.apiVersion_ = 1;
+          this.initialized_ = true;
+          this.sendInitializationSuccess_();
+        }
+        // The glue code for API version 1 interprets all responses as success.
+        // Instead of reporting failure, do not send any response at all.
+        return;
+      }
+
+      if (!Number.isInteger(call.requestedVersion) ||
+          call.requestedVersion < Authenticator.MIN_API_VERSION_VERSION) {
+        this.sendInitializationFailure_();
+        return;
+      }
+
+      this.apiVersion_ = Math.min(call.requestedVersion,
+                                  Authenticator.MAX_API_VERSION_VERSION);
+      this.initialized_ = true;
+      this.sendInitializationSuccess_();
+      return;
+    }
+
     if (call.method == 'add') {
+      if (this.apiVersion_ > 1 &&
+          Authenticator.API_KEY_TYPES.indexOf(call.keyType) == -1) {
+        console.error('Authenticator.onAPICall_: unsupported key type');
+        return;
+      }
       this.apiToken_ = call.token;
       this.email_ = call.user;
-      this.password_ = call.password;
+      if (this.apiVersion_ == 1)
+        this.passwordBytes_ = call.password;
+      else
+        this.passwordBytes_ = call.passwordBytes;
     } else if (call.method == 'confirm') {
       if (call.token != this.apiToken_)
         console.error('Authenticator.onAPICall_: token mismatch');
@@ -272,13 +339,31 @@
     }
   },
 
+  sendInitializationSuccess_: function() {
+    var response = {
+      result: 'initialized',
+      version: this.apiVersion_
+    };
+    if (this.apiVersion_ >= 2)
+      response['keyTypes'] = Authenticator.API_KEY_TYPES;
+
+    this.supportChannel_.send({name: 'apiResponse', response: response});
+  },
+
+  sendInitializationFailure_: function() {
+    this.supportChannel_.send({
+      name: 'apiResponse',
+      response: {result: 'initialization_failed'}
+    });
+  },
+
   onConfirmLogin_: function() {
     if (!this.isSAMLFlow_) {
       this.completeLogin_();
       return;
     }
 
-    var apiUsed = !!this.password_;
+    var apiUsed = !!this.passwordBytes_;
 
     // Retrieve the e-mail address of the user who just authenticated from GAIA.
     window.parent.postMessage({method: 'retrieveAuthenticatedUserEmail',
@@ -307,7 +392,7 @@
   maybeCompleteSAMLLogin_: function() {
     // SAML login is complete when the user's e-mail address has been retrieved
     // from GAIA and the user has successfully confirmed the password.
-    if (this.email_ !== null && this.password_ !== null)
+    if (this.email_ !== null && this.passwordBytes_ !== null)
       this.completeLogin_();
   },
 
@@ -317,7 +402,7 @@
         function(passwords) {
           for (var i = 0; i < passwords.length; ++i) {
             if (passwords[i] == password) {
-              this.password_ = passwords[i];
+              this.passwordBytes_ = passwords[i];
               this.maybeCompleteSAMLLogin_();
               return;
             }
@@ -332,7 +417,7 @@
     var msg = e.data;
     if (msg.method == 'attemptLogin' && this.isGaiaMessage_(e)) {
       this.email_ = msg.email;
-      this.password_ = msg.password;
+      this.passwordBytes_ = msg.password;
       this.attemptToken_ = msg.attemptToken;
       this.chooseWhatToSync_ = msg.chooseWhatToSync;
       this.isSAMLFlow_ = false;
@@ -340,7 +425,7 @@
         this.supportChannel_.send({name: 'startAuth'});
     } else if (msg.method == 'clearOldAttempts' && this.isGaiaMessage_(e)) {
       this.email_ = null;
-      this.password_ = null;
+      this.passwordBytes_ = null;
       this.attemptToken_ = null;
       this.isSAMLFlow_ = false;
       this.onLoginUILoaded_();
diff --git a/chrome/browser/resources/gaia_auth/saml_injected.js b/chrome/browser/resources/gaia_auth/saml_injected.js
index 62857b4..e41dfeb 100644
--- a/chrome/browser/resources/gaia_auth/saml_injected.js
+++ b/chrome/browser/resources/gaia_auth/saml_injected.js
@@ -20,8 +20,9 @@
 
   /**
    * The credential passing API is used by sending messages to the SAML page's
-   * |window| object. This class forwards the calls to a background script via a
-   * |Channel|.
+   * |window| object. This class forwards API calls from the SAML page to a
+   * background script and API responses from the background script to the SAML
+   * page. Communication with the background script occurs via a |Channel|.
    */
   APICallForwarder.prototype = {
     // Channel to which API calls are forwarded.
@@ -33,6 +34,9 @@
      */
     init: function(channel) {
       this.channel_ = channel;
+      this.channel_.registerMessage('apiResponse',
+                                    this.onAPIResponse_.bind(this));
+
       window.addEventListener('message', this.onMessage_.bind(this));
     },
 
@@ -43,15 +47,14 @@
           event.data.type != 'gaia_saml_api') {
         return;
       }
-      if (event.data.call.method == 'initialize') {
-        // Respond to the |initialize| call directly.
-        event.source.postMessage({
-            type: 'gaia_saml_api_reply',
-            response: {result: 'initialized', version: 1}}, '/');
-      } else {
-        // Forward all other calls.
-        this.channel_.send({name: 'apiCall', call: event.data.call});
-      }
+      // Forward API calls to the background script.
+      this.channel_.send({name: 'apiCall', call: event.data.call});
+    },
+
+    onAPIResponse_: function(msg) {
+      // Forward API responses to the SAML page.
+      window.postMessage({type: 'gaia_saml_api_reply', response: msg.response},
+                         '/');
     }
   };
 
diff --git a/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js b/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js
index d1b9790..e835e20 100644
--- a/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js
+++ b/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js
@@ -211,7 +211,7 @@
 
     /**
      * Sets insecureContentBlockedCallback_.
-     * @type {function()}
+     * @type {function(string)}
      */
     set insecureContentBlockedCallback(callback) {
       this.insecureContentBlockedCallback_ = callback;
@@ -389,7 +389,7 @@
 
       if (msg.method == 'insecureContentBlocked') {
         if (this.insecureContentBlockedCallback_) {
-          this.insecureContentBlockedCallback_();
+          this.insecureContentBlockedCallback_(msg.url);
         } else {
           console.error(
               'GaiaAuthHost: Invalid insecureContentBlockedCallback_.');
diff --git a/chrome/browser/resources/gcm_internals.html b/chrome/browser/resources/gcm_internals.html
index 50a508f..c85b2cf 100644
--- a/chrome/browser/resources/gcm_internals.html
+++ b/chrome/browser/resources/gcm_internals.html
@@ -109,6 +109,63 @@
   </tbody>
 </table>
 
+<h2>Check-in Log</h2>
+<table class="log-table">
+  <thead>
+    <tr>
+      <th>Time</th>
+      <th>Event</th>
+      <th>Details</th>
+    </tr>
+  </thead>
+  <tbody id="checkin-info">
+  </tbody>
+</table>
+
+<h2>Connection Log</h2>
+<table class="log-table">
+  <thead>
+    <tr>
+      <th>Time</th>
+      <th>Event</th>
+      <th>Details</th>
+    </tr>
+  </thead>
+  <tbody id="connection-info">
+  </tbody>
+</table>
+
+<h2>Registration Log</h2>
+<table class="log-table">
+  <thead>
+    <tr>
+      <th>Time</th>
+      <th>App Id</th>
+      <th>Sender Ids</th>
+      <th>Event</th>
+      <th>Details</th>
+    </tr>
+  </thead>
+  <tbody id="registration-info">
+  </tbody>
+</table>
+
+<h2>Receive Message Log</h2>
+<table class="log-table">
+  <thead>
+    <tr>
+      <th>Time</th>
+      <th>App Id</th>
+      <th>From</th>
+      <th>Size (bytes)</th>
+      <th>Event</th>
+      <th>Details</th>
+    </tr>
+  </thead>
+  <tbody id="receive-info">
+  </tbody>
+</table>
+
 <h2>Send Message Log</h2>
 <table class="log-table">
   <thead>
diff --git a/chrome/browser/resources/gcm_internals.js b/chrome/browser/resources/gcm_internals.js
index 35100b3..1bc8dae 100644
--- a/chrome/browser/resources/gcm_internals.js
+++ b/chrome/browser/resources/gcm_internals.js
@@ -106,6 +106,19 @@
   }
 
   /**
+   * Refresh the log html table by clearing it first. If data is not empty, then
+   * it will be used to populate the table.
+   * @param {string} id ID of the log html table.
+   * @param {!Object} data A list of list of data items.
+   */
+  function refreshLogTable(id, data) {
+    removeAllChildNodes($(id));
+    if (data !== undefined) {
+      addRows($(id), data);
+    }
+  }
+
+  /**
    * Callback function accepting a dictionary of info items to be displayed.
    * @param {!Object} infos A dictionary of info items to be displayed.
    */
@@ -120,10 +133,11 @@
       displayDeviceInfo(infos.deviceInfo);
     }
 
-    removeAllChildNodes($('send-info'));
-    if (infos.sendInfo !== undefined) {
-      addRows($('send-info'), infos.sendInfo);
-    }
+    refreshLogTable('checkin-info', infos.checkinInfo);
+    refreshLogTable('connection-info', infos.connectionInfo);
+    refreshLogTable('registration-info', infos.registrationInfo);
+    refreshLogTable('receive-info', infos.receiveInfo);
+    refreshLogTable('send-info', infos.sendInfo);
   }
 
   // Return an object with all of the exports.
diff --git a/chrome/browser/resources/google_now/background.js b/chrome/browser/resources/google_now/background.js
index d2d3f3b..72255cd 100644
--- a/chrome/browser/resources/google_now/background.js
+++ b/chrome/browser/resources/google_now/background.js
@@ -54,14 +54,14 @@
  * Initial period for polling for Google Now optin notification after push
  * messaging indicates Google Now is enabled.
  */
-var INITIAL_OPTIN_POLLING_PERIOD_SECONDS = 60;  // 1 minute
+var INITIAL_OPTIN_RECHECK_PERIOD_SECONDS = 60;  // 1 minute
 
 /**
  * Maximum period for polling for Google Now optin notification after push
  * messaging indicates Google Now is enabled. It is expected that the alarm
  * will be stopped after this.
  */
-var MAXIMUM_OPTIN_POLLING_PERIOD_SECONDS = 16 * 60;  // 16 minutes
+var MAXIMUM_OPTIN_RECHECK_PERIOD_SECONDS = 16 * 60;  // 16 minutes
 
 /**
  * Initial period for retrying the server request for dismissing cards.
@@ -205,6 +205,7 @@
     'notifications.onShowSettings.addListener', 0);
 wrapper.instrumentChromeApiFunction('permissions.contains', 1);
 wrapper.instrumentChromeApiFunction('pushMessaging.onMessage.addListener', 0);
+wrapper.instrumentChromeApiFunction('storage.onChanged.addListener', 0);
 wrapper.instrumentChromeApiFunction('runtime.onInstalled.addListener', 0);
 wrapper.instrumentChromeApiFunction('runtime.onStartup.addListener', 0);
 wrapper.instrumentChromeApiFunction('tabs.create', 1);
@@ -214,11 +215,16 @@
     requestCards,
     INITIAL_POLLING_PERIOD_SECONDS,
     MAXIMUM_POLLING_PERIOD_SECONDS);
-var optInCheckAttempts = buildAttemptManager(
+var optInPollAttempts = buildAttemptManager(
     'optin',
-    pollOptedIn,
-    INITIAL_OPTIN_POLLING_PERIOD_SECONDS,
-    MAXIMUM_OPTIN_POLLING_PERIOD_SECONDS);
+    pollOptedInNoImmediateRecheck,
+    INITIAL_POLLING_PERIOD_SECONDS,
+    MAXIMUM_POLLING_PERIOD_SECONDS);
+var optInRecheckAttempts = buildAttemptManager(
+    'optin-recheck',
+    pollOptedInWithRecheck,
+    INITIAL_OPTIN_RECHECK_PERIOD_SECONDS,
+    MAXIMUM_OPTIN_RECHECK_PERIOD_SECONDS);
 var dismissalAttempts = buildAttemptManager(
     'dismiss',
     retryPendingDismissals,
@@ -425,39 +431,52 @@
 }
 
 /**
+ * Calculates the soonest poll time from a map of groups as an absolute time.
+ * @param {Object.<string, StoredNotificationGroup>} groups Map from group name
+ *     to group information.
+ * @return {number} The next poll time based off of the groups.
+ */
+function calculateNextPollTimeMilliseconds(groups) {
+  var nextPollTime = null;
+
+  for (var groupName in groups) {
+    var group = groups[groupName];
+    if (group.nextPollTime !== undefined) {
+      nextPollTime = nextPollTime == null ?
+          group.nextPollTime : Math.min(group.nextPollTime, nextPollTime);
+    }
+  }
+
+  // At least one of the groups must have nextPollTime.
+  verify(nextPollTime != null, 'calculateNextPollTime: nextPollTime is null');
+  return nextPollTime;
+}
+
+/**
  * Schedules next cards poll.
  * @param {Object.<string, StoredNotificationGroup>} groups Map from group name
  *     to group information.
- * @param {boolean} isOptedIn True if the user is opted in to Google Now.
  */
-function scheduleNextPoll(groups, isOptedIn) {
-  if (isOptedIn) {
-    var nextPollTime = null;
+function scheduleNextCardsPoll(groups) {
+  var nextPollTimeMs = calculateNextPollTimeMilliseconds(groups);
 
-    for (var groupName in groups) {
-      var group = groups[groupName];
-      if (group.nextPollTime !== undefined) {
-        nextPollTime = nextPollTime == null ?
-            group.nextPollTime : Math.min(group.nextPollTime, nextPollTime);
-      }
-    }
+  var nextPollDelaySeconds = Math.max(
+      (nextPollTimeMs - Date.now()) / MS_IN_SECOND,
+      MINIMUM_POLLING_PERIOD_SECONDS);
+  updateCardsAttempts.start(nextPollDelaySeconds);
+}
 
-    // At least one of the groups must have nextPollTime.
-    verify(nextPollTime != null, 'scheduleNextPoll: nextPollTime is null');
-
-    var nextPollDelaySeconds = Math.max(
-        (nextPollTime - Date.now()) / MS_IN_SECOND,
-        MINIMUM_POLLING_PERIOD_SECONDS);
-    updateCardsAttempts.start(nextPollDelaySeconds);
-  } else {
-    instrumented.metricsPrivate.getVariationParams(
-        'GoogleNow', function(params) {
-      var optinPollPeriodSeconds =
-          parseInt(params && params.optinPollPeriodSeconds, 10) ||
-          DEFAULT_OPTIN_CHECK_PERIOD_SECONDS;
-      updateCardsAttempts.start(optinPollPeriodSeconds);
-    });
-  }
+/**
+ * Schedules the next opt-in check poll.
+ */
+function scheduleOptInCheckPoll() {
+  instrumented.metricsPrivate.getVariationParams(
+      'GoogleNow', function(params) {
+    var optinPollPeriodSeconds =
+        parseInt(params && params.optinPollPeriodSeconds, 10) ||
+        DEFAULT_OPTIN_CHECK_PERIOD_SECONDS;
+    optInPollAttempts.start(optinPollPeriodSeconds);
+  });
 }
 
 /**
@@ -488,13 +507,6 @@
 
   if (response.googleNowDisabled) {
     chrome.storage.local.set({googleNowEnabled: false});
-    // TODO(robliao): Remove the line below once the server stops sending groups
-    // with 'googleNowDisabled' responses.
-    response.groups = {};
-    // Google Now was enabled; now it's disabled. This is a state change.
-    onStateChange();
-    // Start the Google Now Disabled polling period.
-    scheduleNextPoll({}, false);
     // Stop processing now. The state change will clear the cards.
     return Promise.reject();
   }
@@ -573,7 +585,7 @@
       updatedGroups[groupName] = storedGroup;
     }
 
-    scheduleNextPoll(updatedGroups, !response.googleNowDisabled);
+    scheduleNextCardsPoll(updatedGroups);
     return {
       updatedGroups: updatedGroups,
       recentDismissals: updatedRecentDismissals
@@ -638,10 +650,27 @@
 }
 
 /**
+ * Performs an opt-in poll without an immediate recheck.
+ * If the response is not opted-in, schedule an opt-in check poll.
+ */
+function pollOptedInNoImmediateRecheck() {
+  requestAndUpdateOptedIn()
+      .then(function(optedIn) {
+        if (!optedIn) {
+          // Request a repoll if we're not opted in.
+          return Promise.reject();
+        }
+      })
+      .catch(function() {
+        scheduleOptInCheckPoll();
+      });
+}
+
+/**
  * Requests the account opted-in state from the server and updates any
  * state as necessary.
  * @return {Promise} A promise to request and update the opted-in state.
- *     The promise resolves if the opt-in state is true.
+ *     The promise resolves with the opt-in state.
  */
 function requestAndUpdateOptedIn() {
   console.log('requestOptedIn from ' + NOTIFICATION_CARDS_URL);
@@ -654,15 +683,8 @@
       return parsedResponse.value;
     }
   }).then(function(optedIn) {
-    if (optedIn) {
-      chrome.storage.local.set({googleNowEnabled: true});
-      // Google Now was disabled, now it's enabled. This is a state change.
-      onStateChange();
-      return Promise.resolve();
-    } else {
-      scheduleNextPoll({}, false);
-      return Promise.reject();
-    }
+    chrome.storage.local.set({googleNowEnabled: optedIn});
+    return optedIn;
   });
 }
 
@@ -695,12 +717,7 @@
  */
 function requestNotificationCards() {
   console.log('requestNotificationCards');
-
-  return isGoogleNowEnabled()
-      .then(function(googleNowEnabled) {
-        return googleNowEnabled ? Promise.resolve() : requestAndUpdateOptedIn();
-      })
-      .then(getGroupsToRequest)
+  return getGroupsToRequest()
       .then(requestNotificationGroupsFromServer)
       .then(processServerResponse)
       .then(function(processedResponse) {
@@ -731,10 +748,10 @@
     console.log('requestCards-task-begin');
     updateCardsAttempts.isRunning(function(running) {
       if (running) {
-        updateCardsAttempts.planForNext(function() {
-          // The cards are requested only if there are no unsent dismissals.
-          processPendingDismissals().then(requestNotificationCards);
-        });
+        // The cards are requested only if there are no unsent dismissals.
+        processPendingDismissals()
+            .then(requestNotificationCards)
+            .catch(updateCardsAttempts.scheduleRetry);
       }
     });
   });
@@ -851,9 +868,7 @@
  */
 function retryPendingDismissals() {
   tasks.add(RETRY_DISMISS_TASK_NAME, function() {
-    dismissalAttempts.planForNext(function() {
-      processPendingDismissals();
-     });
+    processPendingDismissals().catch(dismissalAttempts.scheduleRetry);
   });
 }
 
@@ -1006,6 +1021,28 @@
 }
 
 /**
+ * Starts or stops the optin check.
+ * @param {boolean} shouldPollOptInStatus true to start and false to stop
+ *     polling the optin status.
+ */
+function setShouldPollOptInStatus(shouldPollOptInStatus) {
+  optInPollAttempts.isRunning(function(currentValue) {
+    if (shouldPollOptInStatus != currentValue) {
+      console.log(
+          'Action Taken setShouldPollOptInStatus=' + shouldPollOptInStatus);
+      if (shouldPollOptInStatus) {
+        pollOptedInNoImmediateRecheck();
+      } else {
+        optInPollAttempts.stop();
+      }
+    } else {
+      console.log(
+          'Action Ignored setShouldPollOptInStatus=' + shouldPollOptInStatus);
+    }
+  });
+}
+
+/**
  * Enables or disables the Google Now background permission.
  * @param {boolean} backgroundEnable true to run in the background.
  *     false to not run in the background.
@@ -1066,13 +1103,13 @@
       'googleNowEnabled=' + googleNowEnabled);
 
   var shouldPollCards = false;
+  var shouldPollOptInStatus = false;
   var shouldSetBackground = false;
-  var shouldClearCards = true;
 
   if (signedIn && notificationEnabled) {
-    shouldClearCards = !googleNowEnabled;
+    shouldPollCards = googleNowEnabled;
+    shouldPollOptInStatus = !googleNowEnabled;
     shouldSetBackground = canEnableBackground && googleNowEnabled;
-    shouldPollCards = true;
   } else {
     recordEvent(GoogleNowEvent.STOPPED);
   }
@@ -1082,11 +1119,12 @@
   console.log(
       'Requested Actions shouldSetBackground=' + shouldSetBackground + ' ' +
       'setShouldPollCards=' + shouldPollCards + ' ' +
-      'shouldClearCards=' + shouldClearCards);
+      'shouldPollOptInStatus=' + shouldPollOptInStatus);
 
   setBackgroundEnable(shouldSetBackground);
   setShouldPollCards(shouldPollCards);
-  if (shouldClearCards) {
+  setShouldPollOptInStatus(shouldPollOptInStatus);
+  if (!shouldPollCards) {
     removeAllCards();
   }
 }
@@ -1152,30 +1190,35 @@
  * Sometimes we get the response to the opted in result too soon during
  * push messaging. We'll recheck the optin state a few times before giving up.
  */
-function pollOptedIn() {
+function pollOptedInWithRecheck() {
   /**
    * Cleans up any state used to recheck the opt-in poll.
    */
   function clearPollingState() {
     localStorage.removeItem('optedInCheckCount');
-    optInCheckAttempts.stop();
+    optInRecheckAttempts.stop();
   }
 
   if (localStorage.optedInCheckCount === undefined) {
     localStorage.optedInCheckCount = 0;
-    optInCheckAttempts.start();
+    optInRecheckAttempts.start();
   }
 
   console.log(new Date() +
       ' checkOptedIn Attempt ' + localStorage.optedInCheckCount);
 
-  requestAndUpdateOptedIn().then(function() {
-    clearPollingState();
-    requestCards();
+  requestAndUpdateOptedIn().then(function(optedIn) {
+    if (optedIn) {
+      clearPollingState();
+      return Promise.resolve();
+    } else {
+      // If we're not opted in, reject to retry.
+      return Promise.reject();
+    }
   }).catch(function() {
     if (localStorage.optedInCheckCount < 5) {
       localStorage.optedInCheckCount++;
-      optInCheckAttempts.planForNext(function() {});
+      optInRecheckAttempts.scheduleRetry();
     } else {
       clearPollingState();
     }
@@ -1259,6 +1302,15 @@
   openUrl(SETTINGS_URL);
 });
 
+// Handles state change notifications for the Google Now enabled bit.
+instrumented.storage.onChanged.addListener(function(changes, areaName) {
+  if (areaName === 'local') {
+    if ('googleNowEnabled' in changes) {
+      onStateChange();
+    }
+  }
+});
+
 instrumented.pushMessaging.onMessage.addListener(function(message) {
   // message.payload will be '' when the extension first starts.
   // Each time after signing in, we'll get latest payload for all channels.
@@ -1288,7 +1340,7 @@
             notificationGroups: items.notificationGroups
           });
 
-          pollOptedIn();
+          pollOptedInWithRecheck();
         }
       });
     });
diff --git a/chrome/browser/resources/google_now/background_test_util.js b/chrome/browser/resources/google_now/background_test_util.js
index b011122..52d77da 100644
--- a/chrome/browser/resources/google_now/background_test_util.js
+++ b/chrome/browser/resources/google_now/background_test_util.js
@@ -26,6 +26,7 @@
 mockChromeEvent(instrumented, 'pushMessaging.onMessage');
 mockChromeEvent(instrumented, 'runtime.onInstalled');
 mockChromeEvent(instrumented, 'runtime.onStartup');
+mockChromeEvent(instrumented, 'storage.onChanged');
 
 NOTIFICATION_CARDS_URL = 'https://test/';
 navigator = {language: 'en-US'};
diff --git a/chrome/browser/resources/google_now/background_unittest.gtestjs b/chrome/browser/resources/google_now/background_unittest.gtestjs
index 20d9455..22ac615 100644
--- a/chrome/browser/resources/google_now/background_unittest.gtestjs
+++ b/chrome/browser/resources/google_now/background_unittest.gtestjs
@@ -336,9 +336,7 @@
 TEST_F(TEST_NAME, 'RequestAndUpdateOptInOptedIn', function() {
   this.makeAndRegisterMockApis([
     'chrome.storage.local.set',
-    'onStateChange',
-    'requestFromServer',
-    'scheduleNextPoll'
+    'requestFromServer'
   ]);
 
   this.mockApis.expects(once()).requestFromServer('GET', 'settings/optin')
@@ -349,14 +347,11 @@
   this.mockApis.expects(once())
       .chrome_storage_local_set(eqJSON({googleNowEnabled: true}));
 
-  this.mockApis.expects(once()).onStateChange();
-
-  this.mockApis.expects(never()).scheduleNextPoll();
-
   var thenCalled = false;
   var catchCalled = false;
-  requestAndUpdateOptedIn().then(function() {
+  requestAndUpdateOptedIn().then(function(optedIn) {
     thenCalled = true;
+    assertTrue(optedIn);
   }).catch(function() {
     catchCalled = true;
   });
@@ -367,9 +362,7 @@
 TEST_F(TEST_NAME, 'RequestAndUpdateOptInOptedOut', function() {
   this.makeAndRegisterMockApis([
     'chrome.storage.local.set',
-    'onStateChange',
-    'requestFromServer',
-    'scheduleNextPoll'
+    'requestFromServer'
   ]);
 
   this.mockApis.expects(once()).requestFromServer('GET', 'settings/optin')
@@ -377,12 +370,32 @@
         status: 200,
         responseText: '{"value": false}'})));
 
+  this.mockApis.expects(once())
+      .chrome_storage_local_set(eqJSON({googleNowEnabled: false}));
+
+  var thenCalled = false;
+  var catchCalled = false;
+  requestAndUpdateOptedIn().then(function(optedIn) {
+    thenCalled = true;
+    assertFalse(optedIn);
+  }).catch(function() {
+    catchCalled = true;
+  });
+  assertTrue(thenCalled);
+  assertFalse(catchCalled);
+});
+
+TEST_F(TEST_NAME, 'RequestAndUpdateOptInFailure', function() {
+  this.makeAndRegisterMockApis([
+    'chrome.storage.local.set',
+    'requestFromServer'
+  ]);
+
+  this.mockApis.expects(once()).requestFromServer('GET', 'settings/optin')
+      .will(returnValue(Promise.reject({status: 404})));
+
   this.mockApis.expects(never()).chrome_storage_local_set();
 
-  this.mockApis.expects(never()).onStateChange();
-
-  this.mockApis.expects(once()).scheduleNextPoll(eqJSON({}), false);
-
   var thenCalled = false;
   var catchCalled = false;
   requestAndUpdateOptedIn().then(function() {
@@ -394,32 +407,71 @@
   assertTrue(catchCalled);
 });
 
-TEST_F(TEST_NAME, 'RequestAndUpdateOptInFailure', function() {
+/**
+ * pollOptedInNoImmediateRecheck Tests
+ */
+TEST_F(TEST_NAME, 'pollOptedInNoImmediateRecheckOptedIn', function() {
   this.makeAndRegisterMockApis([
-    'chrome.storage.local.set',
-    'onStateChange',
-    'requestFromServer',
-    'scheduleNextPoll'
+    'requestAndUpdateOptedIn',
+    'instrumented.metricsPrivate.getVariationParams',
+    'optInPollAttempts.start'
   ]);
 
-  this.mockApis.expects(once()).requestFromServer('GET', 'settings/optin')
-      .will(returnValue(Promise.reject({status: 404})));
+  this.mockApis.expects(once()).requestAndUpdateOptedIn()
+      .will(returnValue(Promise.resolve(true)));
 
-  this.mockApis.expects(never()).chrome_storage_local_set();
+  this.mockApis.expects(never())
+      .instrumented_metricsPrivate_getVariationParams();
 
-  this.mockApis.expects(never()).onStateChange();
+  this.mockApis.expects(never()).optInPollAttempts_start();
 
-  this.mockApis.expects(never()).scheduleNextPoll();
+  pollOptedInNoImmediateRecheck();
+});
 
-  var thenCalled = false;
-  var catchCalled = false;
-  requestAndUpdateOptedIn().then(function() {
-    thenCalled = true;
-  }).catch(function() {
-    catchCalled = true;
-  });
-  assertFalse(thenCalled);
-  assertTrue(catchCalled);
+TEST_F(TEST_NAME, 'pollOptedInNoImmediateRecheckOptedOut', function() {
+  this.makeAndRegisterMockApis([
+    'requestAndUpdateOptedIn',
+    'instrumented.metricsPrivate.getVariationParams',
+    'optInPollAttempts.start'
+  ]);
+
+  this.mockApis.expects(once()).requestAndUpdateOptedIn()
+      .will(returnValue(Promise.resolve(false)));
+
+  var getVariationParamsSavedArgs = new SaveMockArguments();
+  this.mockApis.expects(once())
+      .instrumented_metricsPrivate_getVariationParams(
+          getVariationParamsSavedArgs.match(eq('GoogleNow')),
+          getVariationParamsSavedArgs.match(ANYTHING))
+      .will(invokeCallback(getVariationParamsSavedArgs, 1, {}));
+
+  this.mockApis.expects(once())
+      .optInPollAttempts_start(DEFAULT_OPTIN_CHECK_PERIOD_SECONDS);
+
+  pollOptedInNoImmediateRecheck();
+});
+
+TEST_F(TEST_NAME, 'pollOptedInNoImmediateRecheckFailure', function() {
+  this.makeAndRegisterMockApis([
+    'requestAndUpdateOptedIn',
+    'instrumented.metricsPrivate.getVariationParams',
+    'optInPollAttempts.start'
+  ]);
+
+  this.mockApis.expects(once()).requestAndUpdateOptedIn()
+      .will(returnValue(Promise.reject()));
+
+  var getVariationParamsSavedArgs = new SaveMockArguments();
+  this.mockApis.expects(once())
+      .instrumented_metricsPrivate_getVariationParams(
+          getVariationParamsSavedArgs.match(eq('GoogleNow')),
+          getVariationParamsSavedArgs.match(ANYTHING))
+      .will(invokeCallback(getVariationParamsSavedArgs, 1, {}));
+
+  this.mockApis.expects(once())
+      .optInPollAttempts_start(DEFAULT_OPTIN_CHECK_PERIOD_SECONDS);
+
+  pollOptedInNoImmediateRecheck();
 });
 
 /**
@@ -531,6 +583,7 @@
  */
 function mockInitializeDependencies(fixture) {
   fixture.makeAndRegisterMockGlobals([
+    'pollOptedInNoImmediateRecheck',
     'recordEvent',
     'removeAllCards',
     'setBackgroundEnable',
@@ -545,6 +598,8 @@
     'instrumented.notifications.getAll',
     'instrumented.notifications.getPermissionLevel',
     'instrumented.webstorePrivate.getBrowserLogin',
+    'optInPollAttempts.isRunning',
+    'optInPollAttempts.stop',
     'tasks.add',
     'updateCardsAttempts.isRunning',
     'updateCardsAttempts.stop'
@@ -607,6 +662,14 @@
       will(
           invokeCallback(
               updateCardsAttemptsIsRunningSavedArgs, 0, undefined));
+
+  var optInPollAttemptsIsRunningSavedArgs = new SaveMockArguments();
+  fixture.mockApis.expects(once()).
+      optInPollAttempts_isRunning(
+          optInPollAttemptsIsRunningSavedArgs.match(ANYTHING)).
+      will(
+          invokeCallback(
+              optInPollAttemptsIsRunningSavedArgs, 0, undefined));
 }
 
 /**
@@ -659,6 +722,8 @@
   this.mockGlobals.expects(never()).startPollingCards();
   this.mockGlobals.expects(once()).stopPollingCards();
   this.mockGlobals.expects(once()).removeAllCards();
+  this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck();
+  this.mockApis.expects(once()).optInPollAttempts_stop();
 
   // Invoking the tested function.
   initialize();
@@ -688,6 +753,8 @@
   this.mockGlobals.expects(never()).startPollingCards();
   this.mockGlobals.expects(once()).stopPollingCards();
   this.mockGlobals.expects(once()).removeAllCards();
+  this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck();
+  this.mockApis.expects(once()).optInPollAttempts_stop();
 
   // Invoking the tested function.
   initialize();
@@ -717,6 +784,8 @@
   this.mockGlobals.expects(once()).startPollingCards();
   this.mockGlobals.expects(never()).stopPollingCards();
   this.mockGlobals.expects(never()).removeAllCards();
+  this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck();
+  this.mockApis.expects(once()).optInPollAttempts_stop();
 
   // Invoking the tested function.
   initialize();
@@ -743,9 +812,11 @@
       testGoogleNowEnabled);
 
   this.mockGlobals.expects(once()).setBackgroundEnable(false);
-  this.mockGlobals.expects(once()).startPollingCards();
-  this.mockGlobals.expects(never()).stopPollingCards();
+  this.mockGlobals.expects(never()).startPollingCards();
+  this.mockGlobals.expects(once()).stopPollingCards();
   this.mockGlobals.expects(once()).removeAllCards();
+  this.mockGlobals.expects(once()).pollOptedInNoImmediateRecheck();
+  this.mockApis.expects(never()).optInPollAttempts_stop();
 
   // Invoking the tested function.
   initialize();
@@ -776,6 +847,8 @@
   this.mockGlobals.expects(once()).startPollingCards();
   this.mockGlobals.expects(never()).stopPollingCards();
   this.mockGlobals.expects(never()).removeAllCards();
+  this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck();
+  this.mockApis.expects(once()).optInPollAttempts_stop();
 
   // Invoking the tested function.
   initialize();
@@ -792,11 +865,13 @@
       'recordEvent',
       'removeAllCards',
       'setBackgroundEnable',
-      'setShouldPollCards']);
+      'setShouldPollCards',
+      'setShouldPollOptInStatus']);
 
   this.mockGlobals.stubs().removeAllCards();
   this.mockGlobals.stubs().setBackgroundEnable(ANYTHING);
   this.mockGlobals.stubs().setShouldPollCards(ANYTHING);
+  this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING);
 
   this.mockGlobals.expects(once()).recordEvent(
       GoogleNowEvent.STOPPED);
@@ -817,11 +892,13 @@
       'recordEvent',
       'removeAllCards',
       'setBackgroundEnable',
-      'setShouldPollCards']);
+      'setShouldPollCards',
+      'setShouldPollOptInStatus']);
 
   this.mockGlobals.stubs().removeAllCards();
   this.mockGlobals.stubs().setBackgroundEnable(ANYTHING);
   this.mockGlobals.stubs().setShouldPollCards(ANYTHING);
+  this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING);
 
   this.mockGlobals.expects(once()).recordEvent(
       GoogleNowEvent.STOPPED);
@@ -842,11 +919,13 @@
       'recordEvent',
       'removeAllCards',
       'setBackgroundEnable',
-      'setShouldPollCards']);
+      'setShouldPollCards',
+      'setShouldPollOptInStatus']);
 
   this.mockGlobals.stubs().removeAllCards();
   this.mockGlobals.stubs().setBackgroundEnable(ANYTHING);
   this.mockGlobals.stubs().setShouldPollCards(ANYTHING);
+  this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING);
 
   this.mockGlobals.expects(never()).recordEvent(
       GoogleNowEvent.STOPPED);
@@ -867,11 +946,13 @@
       'recordEvent',
       'removeAllCards',
       'setBackgroundEnable',
-      'setShouldPollCards']);
+      'setShouldPollCards',
+      'setShouldPollOptInStatus']);
 
   this.mockGlobals.stubs().removeAllCards();
   this.mockGlobals.stubs().setBackgroundEnable(ANYTHING);
   this.mockGlobals.stubs().setShouldPollCards(ANYTHING);
+  this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING);
 
   this.mockGlobals.expects(never()).recordEvent(
       GoogleNowEvent.STOPPED);
@@ -1195,7 +1276,7 @@
   };
 
   this.makeAndRegisterMockGlobals([
-    'scheduleNextPoll'
+    'scheduleNextCardsPoll'
   ]);
 
   this.makeAndRegisterMockApis([
@@ -1213,8 +1294,8 @@
         recentDismissals: recentDismissals
       });
 
-  this.mockGlobals.expects(once()).
-      scheduleNextPoll(eqJSON(expectedUpdatedGroups), true);
+  this.mockGlobals.expects(once())
+      .scheduleNextCardsPoll(eqJSON(expectedUpdatedGroups));
 
   // Invoking the tested function.
   processServerResponse(serverResponse);
@@ -1231,8 +1312,7 @@
   };
 
   this.makeAndRegisterMockGlobals([
-    'onStateChange',
-    'scheduleNextPoll',
+    'scheduleNextCardsPoll'
   ]);
 
   this.makeAndRegisterMockApis([
@@ -1243,9 +1323,7 @@
   this.mockApis.expects(once()).
       chrome_storage_local_set(eqJSON({googleNowEnabled: false}));
 
-  this.mockGlobals.expects(once()).onStateChange();
-
-  this.mockGlobals.expects(once()).scheduleNextPoll(eqJSON({}), false);
+  this.mockGlobals.expects(never()).scheduleNextCardsPoll();
 
   // Invoking the tested function.
   processServerResponse(serverResponse);
diff --git a/chrome/browser/resources/google_now/utility.js b/chrome/browser/resources/google_now/utility.js
index 1dfc7da..591b2f7 100644
--- a/chrome/browser/resources/google_now/utility.js
+++ b/chrome/browser/resources/google_now/utility.js
@@ -879,21 +879,19 @@
   }
 
   /**
-   * Schedules next attempt.
-   * @param {number=} opt_previousDelaySeconds Previous delay in a sequence of
-   *     retry attempts, if specified. Not specified for scheduling first retry
-   *     in the exponential sequence.
+   * Schedules the alarm with a random factor to reduce the chance that all
+   * clients will fire their timers at the same time.
+   * @param {number} durationSeconds Number of seconds before firing the alarm.
    */
-  function scheduleNextAttempt(opt_previousDelaySeconds) {
-    var base = opt_previousDelaySeconds ? opt_previousDelaySeconds * 2 :
-                                          initialDelaySeconds;
-    var newRetryDelaySeconds =
-        Math.min(base * (1 + 0.2 * Math.random()), maximumDelaySeconds);
+  function scheduleAlarm(durationSeconds) {
+    var randomizedRetryDuration =
+        Math.min(durationSeconds * (1 + 0.2 * Math.random()),
+                 maximumDelaySeconds);
 
-    createAlarm(newRetryDelaySeconds);
+    createAlarm(randomizedRetryDuration);
 
     var items = {};
-    items[currentDelayStorageKey] = newRetryDelaySeconds;
+    items[currentDelayStorageKey] = randomizedRetryDuration;
     chrome.storage.local.set(items);
   }
 
@@ -908,7 +906,7 @@
       createAlarm(opt_firstDelaySeconds);
       chrome.storage.local.remove(currentDelayStorageKey);
     } else {
-      scheduleNextAttempt();
+      scheduleAlarm(initialDelaySeconds);
     }
   }
 
@@ -921,21 +919,24 @@
   }
 
   /**
-   * Plans for the next attempt.
-   * @param {function()} callback Completion callback. It will be invoked after
-   *     the planning is done.
+   * Schedules an exponential backoff retry.
+   * @return {Promise} A promise to schedule the retry.
    */
-  function planForNext(callback) {
+  function scheduleRetry() {
     var request = {};
     request[currentDelayStorageKey] = undefined;
-    fillFromChromeLocalStorage(request, PromiseRejection.ALLOW)
+    return fillFromChromeLocalStorage(request, PromiseRejection.ALLOW)
         .catch(function() {
           request[currentDelayStorageKey] = maximumDelaySeconds;
           return Promise.resolve(request);
-        }).then(function(items) {
-          console.log('planForNext-get-storage ' + JSON.stringify(items));
-          scheduleNextAttempt(items[currentDelayStorageKey]);
-          callback();
+        })
+        .then(function(items) {
+          console.log('scheduleRetry-get-storage ' + JSON.stringify(items));
+          var retrySeconds = initialDelaySeconds;
+          if (items[currentDelayStorageKey]) {
+            retrySeconds = items[currentDelayStorageKey] * 2;
+          }
+          scheduleAlarm(retrySeconds);
         });
   }
 
@@ -949,7 +950,7 @@
 
   return {
     start: start,
-    planForNext: planForNext,
+    scheduleRetry: scheduleRetry,
     stop: stop,
     isRunning: isRunning
   };
diff --git a/chrome/browser/resources/google_now/utility_unittest.gtestjs b/chrome/browser/resources/google_now/utility_unittest.gtestjs
index f3552c4..834e6a1 100644
--- a/chrome/browser/resources/google_now/utility_unittest.gtestjs
+++ b/chrome/browser/resources/google_now/utility_unittest.gtestjs
@@ -792,7 +792,6 @@
 
   fixture.makeMockLocalFunctions([
     'attempt',
-    'planForNextCallback',
     'isRunningCallback'
   ]);
   fixture.makeAndRegisterMockApis([
@@ -908,8 +907,8 @@
   var test = setupAttemptManagerTest(this);
   var testStoredRetryDelay = 433;
 
-  // Call planForNext, which prepares next attempt. Current retry time
-  // is less than 1/2 of the maximum delay.
+  // Call scheduleRetry, which schedules a retry.
+  // Current retry time is less than 1/2 of the maximum delay.
   // Expectations.
   var expectedRetryDelaySeconds =
       testStoredRetryDelay * 2 * (1 + testRandomValue * 0.2);
@@ -925,10 +924,16 @@
         periodInMinutes: testMaximumDelaySeconds / 60}));
   this.mockApis.expects(once()).chrome_storage_local_set(
       eqJSON(createTestAttemptStorageEntry(expectedRetryDelaySeconds)));
-  this.mockLocalFunctions.expects(once()).planForNextCallback();
   // Invocation.
-  test.attempts.planForNext(
-      this.mockLocalFunctions.functions().planForNextCallback);
+  var thenCalled = false;
+  var catchCalled = false;
+  test.attempts.scheduleRetry().then(function(request) {
+    thenCalled = true;
+  }).catch(function(request) {
+    catchCalled = true;
+  });
+  assertTrue(thenCalled);
+  assertFalse(catchCalled);
 });
 
 TEST_F('GoogleNowUtilityUnitTest', 'AttemptManagerGrowthLimit', function() {
@@ -938,8 +943,8 @@
   var test = setupAttemptManagerTest(this);
   var testStoredRetryDelay = 1500;
 
-  // Call planForNext, which prepares next attempt. Current retry time
-  // is greater than 1/2 of the maximum delay.
+  // Call scheduleRetry, which schedules a retry.
+  // Current retry time is greater than 1/2 of the maximum delay.
   // Expectations.
   var expectedRetryDelaySeconds = testMaximumDelaySeconds;
   expectChromeLocalStorageGet(
@@ -955,10 +960,16 @@
       }));
   this.mockApis.expects(once()).chrome_storage_local_set(
       eqJSON(createTestAttemptStorageEntry(expectedRetryDelaySeconds)));
-  this.mockLocalFunctions.expects(once()).planForNextCallback();
   // Invocation.
-  test.attempts.planForNext(
-      this.mockLocalFunctions.functions().planForNextCallback);
+  var thenCalled = false;
+  var catchCalled = false;
+  test.attempts.scheduleRetry().then(function(request) {
+    thenCalled = true;
+  }).catch(function(request) {
+    catchCalled = true;
+  });
+  assertTrue(thenCalled);
+  assertFalse(catchCalled);
 });
 
 TEST_F('GoogleNowUtilityUnitTest', 'AttemptManagerAlarm', function() {
diff --git a/chrome/browser/resources/hangout_services/manifest.json b/chrome/browser/resources/hangout_services/manifest.json
index 25d861c..e9ef7aa 100644
--- a/chrome/browser/resources/hangout_services/manifest.json
+++ b/chrome/browser/resources/hangout_services/manifest.json
@@ -20,6 +20,7 @@
   "permissions": [
     "alarms",
     "desktopCapture",
+    "processes",
     "system.cpu",
     "webrtcAudioPrivate",
     "webrtcLoggingPrivate"
diff --git a/chrome/browser/resources/hangout_services/thunk.js b/chrome/browser/resources/hangout_services/thunk.js
index fc97a93..80457d4 100644
--- a/chrome/browser/resources/hangout_services/thunk.js
+++ b/chrome/browser/resources/hangout_services/thunk.js
@@ -160,20 +160,61 @@
         // desktop media source, so it does not need to be conditional.
         chrome.desktopCapture.cancelChooseDesktopMedia(cancelId);
       });
-    } else if (method == 'getNaclArchitecture') {
-      chrome.runtime.getPlatformInfo(function(obj) {
-        doSendResponse(obj.nacl_arch);
-      });
-      return true;
     }
   });
 }
 
+// A port for continuously reporting relevant CPU usage information to the page.
+function onProcessCpu(port) {
+  var tabPid;
+  function processListener(processes) {
+    if (tabPid == undefined) {
+      // getProcessIdForTab sometimes fails, and does not call the callback.
+      // (Tracked at https://crbug.com/368855.)
+      // This call retries it on each process update until it succeeds.
+      chrome.processes.getProcessIdForTab(port.sender.tab.id, function(x) {
+        tabPid = x;
+      });
+      return;
+    }
+    var tabProcess = processes[tabPid];
+    if (!tabProcess) {
+      return;
+    }
+    var pluginProcessCpu = 0, browserProcessCpu = 0, gpuProcessCpu = 0;
+    for (var pid in processes) {
+      var process = processes[pid];
+      if (process.type == 'browser') {
+        browserProcessCpu = process.cpu;
+      } else if (process.type == 'gpu') {
+        gpuProcessCpu = process.cpu;
+      } else if ((process.type == 'plugin' || process.type == 'nacl') &&
+                 process.title.toLowerCase().indexOf('hangouts') > 0) {
+        pluginProcessCpu = process.cpu;
+      }
+    }
+
+    port.postMessage({
+      'tabCpuUsage': tabProcess.cpu,
+      'browserCpuUsage': browserProcessCpu,
+      'gpuCpuUsage': gpuProcessCpu,
+      'pluginCpuUsage': pluginProcessCpu
+    });
+  }
+
+  chrome.processes.onUpdated.addListener(processListener);
+  port.onDisconnect.addListener(function() {
+    chrome.processes.onUpdated.removeListener(processListener);
+  });
+}
+
 chrome.runtime.onConnectExternal.addListener(function(port) {
   if (port.name == 'onSinksChangedListener') {
     onSinksChangedPort(port);
   } else if (port.name == 'chooseDesktopMedia') {
     onChooseDesktopMediaPort(port);
+  } else if (port.name == 'processCpu') {
+    onProcessCpu(port);
   } else {
     // Unknown port type.
     port.disconnect();
diff --git a/chrome/browser/resources/hotword_helper/manager.js b/chrome/browser/resources/hotword_helper/manager.js
index 3fcdb05..815eefd 100644
--- a/chrome/browser/resources/hotword_helper/manager.js
+++ b/chrome/browser/resources/hotword_helper/manager.js
@@ -58,6 +58,11 @@
  */
 OptInManager.prototype.injectTab_ = function(
     tab, sendResponse, hotwordStatus) {
+  if (tab.incognito) {
+    sendResponse({'doNotShowOptinMessage': true});
+    return;
+  }
+
   if (!hotwordStatus.available)
     return;
   if (hotwordStatus.enabled)
diff --git a/chrome/browser/resources/local_ntp/most_visited_thumbnail.js b/chrome/browser/resources/local_ntp/most_visited_thumbnail.js
index ff038a0..789f754 100644
--- a/chrome/browser/resources/local_ntp/most_visited_thumbnail.js
+++ b/chrome/browser/resources/local_ntp/most_visited_thumbnail.js
@@ -38,10 +38,10 @@
     }
     // Creates and adds an image.
     function createThumbnail(src) {
-      var image = new Image();
+      var image = document.createElement('img');
       image.onload = function() {
         var shadow = document.createElement('span');
-        shadow.classList.add('shadow');
+        shadow.className = 'shadow';
         var link = createMostVisitedLink(
             params, data.url, data.title, undefined, data.provider);
         link.appendChild(shadow);
@@ -49,33 +49,33 @@
         displayLink(link);
       };
       image.onerror = function() {
-        logEvent(NTP_LOGGING_EVENT_TYPE.NTP_THUMBNAIL_ERROR);
         if (data.domain) {
-          logEvent(NTP_LOGGING_EVENT_TYPE.NTP_GRAY_TILE_FALLBACK);
           showDomainElement();
+          logEvent(NTP_LOGGING_EVENT_TYPE.NTP_GRAY_TILE_FALLBACK);
         } else {
-          logEvent(NTP_LOGGING_EVENT_TYPE.NTP_EXTERNAL_TILE_FALLBACK);
           showEmptyTile();
+          logEvent(NTP_LOGGING_EVENT_TYPE.NTP_EXTERNAL_TILE_FALLBACK);
         }
+        logEvent(NTP_LOGGING_EVENT_TYPE.NTP_THUMBNAIL_ERROR);
       };
       image.src = src;
     }
 
+    if (data.thumbnailUrl) {
+      createThumbnail(data.thumbnailUrl);
+      logEvent(NTP_LOGGING_EVENT_TYPE.NTP_THUMBNAIL_TILE);
+    } else if (data.domain) {
+      showDomainElement();
+      logEvent(NTP_LOGGING_EVENT_TYPE.NTP_GRAY_TILE);
+    } else {
+      showEmptyTile();
+      logEvent(NTP_LOGGING_EVENT_TYPE.NTP_EXTERNAL_TILE);
+    }
+    logEvent(NTP_LOGGING_EVENT_TYPE.NTP_TILE);
+
     // Log an impression if we know the position of the tile.
     if (isFinite(params.pos) && data.provider) {
       logMostVisitedImpression(parseInt(params.pos, 10), data.provider);
     }
-
-    logEvent(NTP_LOGGING_EVENT_TYPE.NTP_TILE);
-    if (data.thumbnailUrl) {
-      logEvent(NTP_LOGGING_EVENT_TYPE.NTP_THUMBNAIL_TILE);
-      createThumbnail(data.thumbnailUrl);
-    } else if (data.domain) {
-      logEvent(NTP_LOGGING_EVENT_TYPE.NTP_GRAY_TILE);
-      showDomainElement();
-    } else {
-      logEvent(NTP_LOGGING_EVENT_TYPE.NTP_EXTERNAL_TILE);
-      showEmptyTile();
-    }
   });
 });
diff --git a/chrome/browser/resources/login/display_manager.js b/chrome/browser/resources/login/display_manager.js
index 4fbbd03..3644beb 100644
--- a/chrome/browser/resources/login/display_manager.js
+++ b/chrome/browser/resources/login/display_manager.js
@@ -62,7 +62,8 @@
   MANAGED_USER_CREATION_FLOW: 'ui-state-locally-managed',
   KIOSK_MODE: 'ui-state-kiosk-mode',
   LOCAL_STATE_ERROR: 'ui-state-local-state-error',
-  AUTO_ENROLLMENT_ERROR: 'ui-state-auto-enrollment-error'
+  AUTO_ENROLLMENT_ERROR: 'ui-state-auto-enrollment-error',
+  ROLLBACK_ERROR: 'ui-state-rollback-error'
 };
 
 /* Possible types of UI. */
diff --git a/chrome/browser/resources/login/user_pod_row.js b/chrome/browser/resources/login/user_pod_row.js
index a3b21f3..d5e30dc 100644
--- a/chrome/browser/resources/login/user_pod_row.js
+++ b/chrome/browser/resources/login/user_pod_row.js
@@ -1144,6 +1144,11 @@
       this.passwordElement.hidden = !isLockedUser;
       this.nameElement.hidden = isLockedUser;
 
+      if (this.isAuthTypeUserClick) {
+        this.passwordLabelElement.textContent = this.authValue;
+        this.customButtonElement.tabIndex = -1;
+      }
+
       UserPod.prototype.updateActionBoxArea.call(this);
     },
 
@@ -1198,6 +1203,9 @@
       // just activate the pod and show the password field.
       if (!this.user.needsSignin && !this.isActionBoxMenuActive)
         this.activate(e);
+
+      if (this.isAuthTypeUserClick)
+        chrome.send('attemptUnlock', [this.user.emailAddress]);
     },
 
     /** @override */
diff --git a/chrome/browser/resources/net_internals/hsts_view.js b/chrome/browser/resources/net_internals/hsts_view.js
index 5ed1360..4d9c9c7 100644
--- a/chrome/browser/resources/net_internals/hsts_view.js
+++ b/chrome/browser/resources/net_internals/hsts_view.js
@@ -116,54 +116,51 @@
       this.queryOutputDiv_.innerHTML = '';
 
       var s = addNode(this.queryOutputDiv_, 'span');
-      s.innerHTML = '<b>Found</b>: mode: ';
+      s.innerHTML = '<b>Found:</b><br/>';
+      var t;
+      var b;
 
-      // TODO(palmer): Combine these 2-line pairs into 1:
-      // addNodeWithText(this.queryOutputDiv_, 'tt', results.sts_observed);
-      var t = addNode(this.queryOutputDiv_, 'tt');
-      t.textContent = modeToString(result.mode);
+      addTextNode(this.queryOutputDiv_, ' domain: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt', result.domain);
+      b = addNode(this.queryOutputDiv_, 'br');
 
-      addTextNode(this.queryOutputDiv_, ' sts_include_subdomains:');
+      addTextNode(this.queryOutputDiv_, ' static_upgrade_mode: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt',
+                          modeToString(result.static_upgrade_mode));
+      b = addNode(this.queryOutputDiv_, 'br');
 
-      t = addNode(this.queryOutputDiv_, 'tt');
-      t.textContent = result.sts_subdomains;
+      addTextNode(this.queryOutputDiv_, ' static_sts_include_subdomains: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt',
+                          result.static_sts_include_subdomains);
+      b = addNode(this.queryOutputDiv_, 'br');
 
-      addTextNode(this.queryOutputDiv_, ' pkp_include_subdomains:');
+      addTextNode(this.queryOutputDiv_, ' static_pkp_include_subdomains: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt',
+                          result.static_pkp_include_subdomains);
+      b = addNode(this.queryOutputDiv_, 'br');
 
-      t = addNode(this.queryOutputDiv_, 'tt');
-      t.textContent = result.pkp_subdomains;
+      addTextNode(this.queryOutputDiv_, ' static_sts_observed: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt',
+                          result.static_sts_observed);
+      b = addNode(this.queryOutputDiv_, 'br');
 
-      addTextNode(this.queryOutputDiv_, ' sts_observed:');
+      addTextNode(this.queryOutputDiv_, ' static_pkp_observed: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt',
+                          result.static_pkp_observed);
+      b = addNode(this.queryOutputDiv_, 'br');
 
-      t = addNode(this.queryOutputDiv_, 'tt');
-      t.textContent = result.sts_observed;
-
-      addTextNode(this.queryOutputDiv_, ' pkp_observed:');
-
-      t = addNode(this.queryOutputDiv_, 'tt');
-      t.textContent = result.pkp_observed;
-
-      addTextNode(this.queryOutputDiv_, ' domain:');
-
-      t = addNode(this.queryOutputDiv_, 'tt');
-      t.textContent = result.domain;
-
-      addTextNode(this.queryOutputDiv_, ' pubkey_hashes:');
-
+      addTextNode(this.queryOutputDiv_, ' static_spki_hashes: ');
       t = addNode(this.queryOutputDiv_, 'tt');
 
       // |public_key_hashes| is an old synonym for what is now
       // |preloaded_spki_hashes|, which in turn is a legacy synonym for
-      // |static_spki_hashes|. Look for all three, and also for
-      // |dynamic_spki_hashes|.
+      // |static_spki_hashes|.
       if (typeof result.public_key_hashes === 'undefined')
         result.public_key_hashes = '';
       if (typeof result.preloaded_spki_hashes === 'undefined')
         result.preloaded_spki_hashes = '';
       if (typeof result.static_spki_hashes === 'undefined')
         result.static_spki_hashes = '';
-      if (typeof result.dynamic_spki_hashes === 'undefined')
-        result.dynamic_spki_hashes = '';
 
       var hashes = [];
       if (result.public_key_hashes)
@@ -172,10 +169,39 @@
         hashes.push(result.preloaded_spki_hashes);
       if (result.static_spki_hashes)
         hashes.push(result.static_spki_hashes);
-      if (result.dynamic_spki_hashes)
-        hashes.push(result.dynamic_spki_hashes);
 
       t.textContent = hashes.join(',');
+      b = addNode(this.queryOutputDiv_, 'br');
+
+      addTextNode(this.queryOutputDiv_, ' dynamic_upgrade_mode: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt',
+                          modeToString(result.dynamic_upgrade_mode));
+      b = addNode(this.queryOutputDiv_, 'br');
+
+      addTextNode(this.queryOutputDiv_, ' dynamic_sts_include_subdomains: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt',
+                          result.dynamic_sts_include_subdomains || '');
+      b = addNode(this.queryOutputDiv_, 'br');
+
+      addTextNode(this.queryOutputDiv_, ' dynamic_pkp_include_subdomains: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt',
+                          result.dynamic_pkp_include_subdomains || '');
+      b = addNode(this.queryOutputDiv_, 'br');
+
+      addTextNode(this.queryOutputDiv_, ' dynamic_sts_observed: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt',
+                          result.dynamic_sts_observed || '');
+      b = addNode(this.queryOutputDiv_, 'br');
+
+      addTextNode(this.queryOutputDiv_, ' dynamic_pkp_observed: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt',
+                          result.dynamic_pkp_observed || '');
+      b = addNode(this.queryOutputDiv_, 'br');
+
+      addTextNode(this.queryOutputDiv_, ' dynamic_spki_hashes: ');
+      t = addNodeWithText(this.queryOutputDiv_, 'tt',
+                          result.dynamic_spki_hashes || '');
+
       yellowFade(this.queryOutputDiv_);
     }
   };
diff --git a/chrome/browser/resources/ntp4/incognito_and_guest_tab.css b/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
index f187498..5ba3713 100644
--- a/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
+++ b/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
@@ -52,7 +52,7 @@
 
 @media (max-width:700px) {
   body {
-    margin: 3em 2em 2em;
+    margin: 1em 2em 2em;
   }
 }
 
diff --git a/chrome/browser/resources/options/autofill_edit_address_overlay.html b/chrome/browser/resources/options/autofill_edit_address_overlay.html
index a54bc85..3b7ef00 100644
--- a/chrome/browser/resources/options/autofill_edit_address_overlay.html
+++ b/chrome/browser/resources/options/autofill_edit_address_overlay.html
@@ -2,66 +2,26 @@
   <div class="close-button"></div>
   <h1 id="autofill-address-title"></h1>
   <div class="content-area">
-    <div>
-      <div id="autofill-name-labels">
-        <span i18n-content="autofillFirstNameLabel"></span>
-        <span i18n-content="autofillMiddleNameLabel"></span>
-        <span i18n-content="autofillLastNameLabel"></span>
-      </div>
-    </div>
-    <div>
-      <list id="full-name-list"></list>
-    </div>
-
-    <label class="settings-row">
-      <div i18n-content="autofillCompanyNameLabel"></div>
-      <input id="company-name" type="text">
-    </label>
-
-    <label class="settings-row">
-      <div i18n-content="autofillAddrLine1Label"></div>
-      <input id="addr-line-1" type="text">
-    </label>
-
-    <label class="settings-row">
-      <div i18n-content="autofillAddrLine2Label"></div>
-      <input id="addr-line-2" type="text">
-    </label>
-
-    <div class="input-group settings-row">
-      <label>
-        <div i18n-content="autofillCityLabel"></div>
-        <input id="city" type="text">
-      </label>
-
-      <label>
-        <div id="state-label"></div>
-        <input id="state" type="text">
-      </label>
-
-      <label>
-        <div id="postal-code-label"></div>
-        <input id="postal-code" type="text">
-      </label>
+    <div id="autofill-edit-address-fields">
     </div>
 
     <div class="settings-row">
       <label>
         <div i18n-content="autofillCountryLabel"></div>
-        <select id="country"></select>
+        <select class="country" field="country"></select>
       </label>
     </div>
 
     <div class="input-group settings-row">
       <div>
         <div i18n-content="autofillPhoneLabel"></div>
-        <list id="phone-list"
+        <list class="short" field="phone"
             i18n-values="placeholder:autofillAddPhonePlaceholder"></list>
       </div>
 
       <div>
         <div i18n-content="autofillEmailLabel"></div>
-        <list id="email-list"
+        <list class="short" field="email"
             i18n-values="placeholder:autofillAddEmailPlaceholder"></list>
       </div>
     </div>
diff --git a/chrome/browser/resources/options/autofill_edit_address_overlay.js b/chrome/browser/resources/options/autofill_edit_address_overlay.js
index 1f1bf5b..c5e9f25 100644
--- a/chrome/browser/resources/options/autofill_edit_address_overlay.js
+++ b/chrome/browser/resources/options/autofill_edit_address_overlay.js
@@ -9,6 +9,9 @@
   // The GUID of the loaded address.
   var guid;
 
+  // The BCP 47 language code for the layout of input fields.
+  var languageCode;
+
   /**
    * AutofillEditAddressOverlay class
    * Encapsulated handling of the 'Add Page' overlay page.
@@ -46,10 +49,11 @@
         // Blurring is delayed for list elements.  Queue save and close to
         // ensure that pending changes have been applied.
         setTimeout(function() {
-          $('phone-list').doneValidating().then(function() {
-            self.saveAddress_();
-            self.dismissOverlay_();
-          });
+          self.pageDiv.querySelector('[field=phone]').doneValidating().then(
+              function() {
+                self.saveAddress_();
+                self.dismissOverlay_();
+              });
         }, 0);
       };
 
@@ -64,10 +68,17 @@
         event.preventDefault();
       };
 
-      self.guid = '';
-      self.populateCountryList_();
-      self.clearInputFields_();
-      self.connectInputEvents_();
+      this.guid = '';
+      this.populateCountryList_();
+      this.rebuildInputFields_(
+          loadTimeData.getValue('autofillDefaultCountryComponents'));
+      this.languageCode =
+          loadTimeData.getString('autofillDefaultCountryLanguageCode');
+      this.connectInputEvents_();
+      this.setInputFields_({});
+      this.getCountrySelector_().onchange = function(event) {
+        self.countryChanged_();
+      };
     },
 
     /**
@@ -81,34 +92,27 @@
     },
 
     /**
-     * Creates, decorates and initializes the multi-value lists for full name,
-     * phone, and email.
+     * Creates, decorates and initializes the multi-value lists for phone and
+     * email.
      * @private
      */
     createMultiValueLists_: function() {
-      var list = $('full-name-list');
-      options.autofillOptions.AutofillNameValuesList.decorate(list);
-      list.autoExpands = true;
-
-      list = $('phone-list');
+      var list = this.pageDiv.querySelector('[field=phone]');
       options.autofillOptions.AutofillPhoneValuesList.decorate(list);
       list.autoExpands = true;
 
-      list = $('email-list');
+      list = this.pageDiv.querySelector('[field=email]');
       options.autofillOptions.AutofillValuesList.decorate(list);
       list.autoExpands = true;
     },
 
     /**
-     * Updates the data model for the list named |listName| with the values from
-     * |entries|.
-     * @param {string} listName The id of the list.
+     * Updates the data model for the |list| with the values from |entries|.
+     * @param {element} list The list to update.
      * @param {Array} entries The list of items to be added to the list.
+     * @private
      */
-    setMultiValueList_: function(listName, entries) {
-      // Add data entries.
-      var list = $(listName);
-
+    setMultiValueList_: function(list, entries) {
       // Add special entry for adding new values.
       var augmentedList = entries.slice();
       augmentedList.push(null);
@@ -129,32 +133,106 @@
      * @private
      */
     dismissOverlay_: function() {
-      this.clearInputFields_();
+      this.setInputFields_({});
+      this.inputFieldChanged_();
       this.guid = '';
+      this.languageCode = '';
       OptionsPage.closeOverlay();
     },
 
     /**
+     * Returns the country selector element.
+     * @return {element} The country selector.
+     * @private
+     */
+    getCountrySelector_: function() {
+      return this.pageDiv.querySelector('[field=country]');
+    },
+
+    /**
+     * Returns all list elements.
+     * @return {NodeList} The list elements.
+     * @private
+     */
+    getLists_: function() {
+      return this.pageDiv.querySelectorAll('list[field]');
+    },
+
+    /**
+     * Returns all text input elements.
+     * @return {NodeList} The text input elements.
+     * @private
+     */
+    getTextFields_: function() {
+      return this.pageDiv.querySelectorAll(
+          ':-webkit-any(textarea, input)[field]');
+    },
+
+    /**
+     * Aggregates the values in the input fields into an object.
+     * @return {object} The mapping from field names to values.
+     * @private
+     */
+    getInputFields_: function() {
+      var address = {};
+      address['country'] = this.getCountrySelector_().value;
+
+      var lists = this.getLists_();
+      for (var i = 0; i < lists.length; i++) {
+        address[lists[i].getAttribute('field')] =
+            lists[i].dataModel.slice(0, lists[i].dataModel.length - 1);
+      }
+
+      var fields = this.getTextFields_();
+      for (var i = 0; i < fields.length; i++) {
+        address[fields[i].getAttribute('field')] = fields[i].value;
+      }
+
+      return address;
+    },
+
+    /**
+     * Sets the value of each input field according to |address|.
+     * @param {object} address The object with values to use.
+     * @private
+     */
+    setInputFields_: function(address) {
+      this.getCountrySelector_().value = address['country'] || '';
+
+      var lists = this.getLists_();
+      for (var i = 0; i < lists.length; i++) {
+        this.setMultiValueList_(
+            lists[i], address[lists[i].getAttribute('field')] || []);
+      }
+
+      var fields = this.getTextFields_();
+      for (var i = 0; i < fields.length; i++) {
+        fields[i].value = address[fields[i].getAttribute('field')] || '';
+      }
+    },
+
+    /**
      * Aggregates the values in the input fields into an array and sends the
      * array to the Autofill handler.
      * @private
      */
     saveAddress_: function() {
+      var inputFields = this.getInputFields_();
       var address = new Array();
-      address[0] = this.guid;
-      var list = $('full-name-list');
-      address[1] = list.dataModel.slice(0, list.dataModel.length - 1);
-      address[2] = $('company-name').value;
-      address[3] = $('addr-line-1').value;
-      address[4] = $('addr-line-2').value;
-      address[5] = $('city').value;
-      address[6] = $('state').value;
-      address[7] = $('postal-code').value;
-      address[8] = $('country').value;
-      list = $('phone-list');
-      address[9] = list.dataModel.slice(0, list.dataModel.length - 1);
-      list = $('email-list');
-      address[10] = list.dataModel.slice(0, list.dataModel.length - 1);
+      var argCounter = 0;
+      address[argCounter++] = this.guid;
+      address[argCounter++] = inputFields['fullName'] || [];
+      address[argCounter++] = inputFields['companyName'] || '';
+      address[argCounter++] = inputFields['addrLines'] || '';
+      address[argCounter++] = inputFields['dependentLocality'] || '';
+      address[argCounter++] = inputFields['city'] || '';
+      address[argCounter++] = inputFields['state'] || '';
+      address[argCounter++] = inputFields['postalCode'] || '';
+      address[argCounter++] = inputFields['sortingCode'] || '';
+      address[argCounter++] = inputFields['country'] || '';
+      address[argCounter++] = inputFields['phone'] || [];
+      address[argCounter++] = inputFields['email'] || [];
+      address[argCounter++] = this.languageCode;
 
       chrome.send('setAddress', address);
     },
@@ -167,51 +245,56 @@
      */
     connectInputEvents_: function() {
       var self = this;
-      $('company-name').oninput = $('addr-line-1').oninput =
-          $('addr-line-2').oninput = $('city').oninput = $('state').oninput =
-          $('postal-code').oninput = function(event) {
-        self.inputFieldChanged_();
-      };
-
-      $('country').onchange = function(event) {
-        self.countryChanged_();
-      };
+      var fields = this.getTextFields_();
+      for (var i = 0; i < fields.length; i++) {
+        fields[i].oninput = function(event) { self.inputFieldChanged_(); };
+      }
     },
 
     /**
-     * Checks the values of each of the input fields and disables the 'Ok'
-     * button if all of the fields are empty.
+     * Disables the 'Ok' button if all of the fields are empty.
      * @private
      */
     inputFieldChanged_: function() {
-      // Length of lists are tested for <= 1 due to the "add" placeholder item
-      // in the list.
-      var disabled =
-          $('full-name-list').items.length <= 1 &&
-          !$('company-name').value &&
-          !$('addr-line-1').value && !$('addr-line-2').value &&
-          !$('city').value && !$('state').value && !$('postal-code').value &&
-          !$('country').value && $('phone-list').items.length <= 1 &&
-          $('email-list').items.length <= 1;
+      var disabled = true;
+      if (this.getCountrySelector_().value)
+        disabled = false;
+
+      if (disabled) {
+        // Length of lists are tested for > 1 due to the "add" placeholder item
+        // in the list.
+        var lists = this.getLists_();
+        for (var i = 0; i < lists.length; i++) {
+          if (lists[i].items.length > 1) {
+            disabled = false;
+            break;
+          }
+        }
+      }
+
+      if (disabled) {
+        var fields = this.getTextFields_();
+        for (var i = 0; i < fields.length; i++) {
+          if (fields[i].value) {
+            disabled = false;
+            break;
+          }
+        }
+      }
+
       $('autofill-edit-address-apply-button').disabled = disabled;
     },
 
     /**
-     * Updates the postal code and state field labels appropriately for the
-     * selected country.
+     * Updates the address fields appropriately for the selected country.
      * @private
      */
     countryChanged_: function() {
-      var countryCode = $('country').value ||
-          loadTimeData.getString('defaultCountryCode');
-
-      var details = loadTimeData.getValue('autofillCountryData')[countryCode];
-      var postal = $('postal-code-label');
-      postal.textContent = details.postalCodeLabel;
-      $('state-label').textContent = details.stateLabel;
-
-      // Also update the 'Ok' button as needed.
-      this.inputFieldChanged_();
+      var countryCode = this.getCountrySelector_().value;
+      if (countryCode)
+        chrome.send('loadAddressEditorComponents', [countryCode]);
+      else
+        this.inputFieldChanged_();
     },
 
     /**
@@ -222,7 +305,7 @@
       var countryList = loadTimeData.getValue('autofillCountrySelectList');
 
       // Add the countries to the country <select> list.
-      var countrySelect = $('country');
+      var countrySelect = this.getCountrySelector_();
       // Add an empty option.
       countrySelect.appendChild(new Option('', ''));
       for (var i = 0; i < countryList.length; i++) {
@@ -234,52 +317,78 @@
     },
 
     /**
-     * Clears the value of each input field.
-     * @private
-     */
-    clearInputFields_: function() {
-      this.setMultiValueList_('full-name-list', []);
-      $('company-name').value = '';
-      $('addr-line-1').value = '';
-      $('addr-line-2').value = '';
-      $('city').value = '';
-      $('state').value = '';
-      $('postal-code').value = '';
-      $('country').value = '';
-      this.setMultiValueList_('phone-list', []);
-      this.setMultiValueList_('email-list', []);
-
-      this.countryChanged_();
-    },
-
-    /**
      * Loads the address data from |address|, sets the input fields based on
-     * this data and stores the GUID of the address.
+     * this data, and stores the GUID and language code of the address.
      * @private
      */
     loadAddress_: function(address) {
+      this.rebuildInputFields_(address.components);
       this.setInputFields_(address);
       this.inputFieldChanged_();
+      this.connectInputEvents_();
       this.guid = address.guid;
+      this.languageCode = address.languageCode;
     },
 
     /**
-     * Sets the value of each input field according to |address|
+     * Takes a snapshot of the input values, clears the input values, loads the
+     * address input layout from |input.components|, restores the input values
+     * from snapshot, and stores the |input.languageCode| for the address.
      * @private
      */
-    setInputFields_: function(address) {
-      this.setMultiValueList_('full-name-list', address.fullName);
-      $('company-name').value = address.companyName;
-      $('addr-line-1').value = address.addrLine1;
-      $('addr-line-2').value = address.addrLine2;
-      $('city').value = address.city;
-      $('state').value = address.state;
-      $('postal-code').value = address.postalCode;
-      $('country').value = address.country;
-      this.setMultiValueList_('phone-list', address.phone);
-      this.setMultiValueList_('email-list', address.email);
+    loadAddressComponents_: function(input) {
+      var address = this.getInputFields_();
+      this.rebuildInputFields_(input.components);
+      this.setInputFields_(address);
+      this.inputFieldChanged_();
+      this.connectInputEvents_();
+      this.languageCode = input.languageCode;
+    },
 
-      this.countryChanged_();
+    /**
+     * Clears address inputs and rebuilds the input fields according to
+     * |components|.
+     * @private
+     */
+    rebuildInputFields_: function(components) {
+      var content = $('autofill-edit-address-fields');
+      while (content.firstChild) {
+        content.removeChild(content.firstChild);
+      }
+
+      var customContainerElements = {'fullName': 'div'};
+      var customInputElements = {'fullName': 'list', 'addrLines': 'textarea'};
+
+      for (var i in components) {
+        var row = document.createElement('div');
+        row.classList.add('input-group', 'settings-row');
+        content.appendChild(row);
+
+        for (var j in components[i]) {
+          if (components[i][j].field == 'country')
+            continue;
+
+          var fieldContainer = document.createElement(
+              customContainerElements[components[i][j].field] || 'label');
+          row.appendChild(fieldContainer);
+
+          var fieldName = document.createElement('div');
+          fieldName.textContent = components[i][j].name;
+          fieldContainer.appendChild(fieldName);
+
+          var input = document.createElement(
+              customInputElements[components[i][j].field] || 'input');
+          input.setAttribute('field', components[i][j].field);
+          input.classList.add(components[i][j].length);
+          input.setAttribute('placeholder', components[i][j].placeholder || '');
+          fieldContainer.appendChild(input);
+
+          if (input.tagName == 'LIST') {
+            options.autofillOptions.AutofillValuesList.decorate(input);
+            input.autoExpands = true;
+          }
+        }
+      }
     },
   };
 
@@ -287,14 +396,19 @@
     AutofillEditAddressOverlay.getInstance().loadAddress_(address);
   };
 
+  AutofillEditAddressOverlay.loadAddressComponents = function(input) {
+    AutofillEditAddressOverlay.getInstance().loadAddressComponents_(input);
+  };
+
   AutofillEditAddressOverlay.setTitle = function(title) {
     $('autofill-address-title').textContent = title;
   };
 
   AutofillEditAddressOverlay.setValidatedPhoneNumbers = function(numbers) {
-    AutofillEditAddressOverlay.getInstance().setMultiValueList_('phone-list',
-                                                                numbers);
-    $('phone-list').didReceiveValidationResult();
+    var instance = AutofillEditAddressOverlay.getInstance();
+    var phoneList = instance.pageDiv.querySelector('[field=phone]');
+    instance.setMultiValueList_(phoneList, numbers);
+    phoneList.didReceiveValidationResult();
   };
 
   // Export
diff --git a/chrome/browser/resources/options/autofill_edit_overlay.css b/chrome/browser/resources/options/autofill_edit_overlay.css
index 166f0cd..5a302fc 100644
--- a/chrome/browser/resources/options/autofill_edit_overlay.css
+++ b/chrome/browser/resources/options/autofill_edit_overlay.css
@@ -10,14 +10,21 @@
   min-width: 500px;
 }
 
-#full-name-list input,
-#company-name,
-#addr-line-1,
-#addr-line-2 {
+#autofill-edit-address-overlay .long div[role='listitem'] > div > div,
+#autofill-edit-address-overlay .long input,
+#autofill-edit-address-overlay textarea.long,
+#autofill-edit-address-overlay input.long {
   width: 16em;
 }
 
-#country {
+#autofill-edit-address-overlay .short div[role='listitem'] > div > div,
+#autofill-edit-address-overlay .short input,
+#autofill-edit-address-overlay textarea.short,
+#autofill-edit-address-overlay input.short {
+  width: 14em;
+}
+
+#autofill-edit-address-overlay .country {
   max-width: 450px;
 }
 
@@ -40,38 +47,10 @@
 }
 
 :-webkit-any(#autofill-edit-credit-card-overlay, #autofill-edit-address-overlay)
-    .settings-row div + :-webkit-any(input, select) {
+    .settings-row div + :-webkit-any(input, select, textarea) {
   margin-top: 4px;
 }
 
-#autofill-name-labels {
-  display: -webkit-inline-box;
-}
-
-#autofill-name-labels span {
-  -webkit-box-flex: 1;
-  display: block;
-}
-
-#full-name-list {
-  display: inline-block;
-}
-
-#full-name-list div[role='listitem'] > div {
-  display: -webkit-box;
-}
-
-#full-name-list div[role='listitem'] > div > div,
-#autofill-name-labels span {
-  -webkit-margin-end: 5px;
-  width: 16em;
-}
-
-:-webkit-any(#phone-list, #email-list) div[role='listitem'] > div > div,
-:-webkit-any(#phone-list, #email-list) input {
-  width: 14em;
-}
-
 .input-group > * {
   -webkit-box-orient: vertical;
   -webkit-margin-end: 2px;
diff --git a/chrome/browser/resources/options/autofill_options_list.js b/chrome/browser/resources/options/autofill_options_list.js
index 540bf56..8fd7fdb 100644
--- a/chrome/browser/resources/options/autofill_options_list.js
+++ b/chrome/browser/resources/options/autofill_options_list.js
@@ -489,7 +489,8 @@
       var info = new Array();
       info[0] = index;
       info[1] = numbers;
-      info[2] = $('country').value;
+      info[2] = document.querySelector(
+          '#autofill-edit-address-overlay [field=country]').value;
       this.validationRequests_++;
       chrome.send('validatePhoneNumbers', info);
     },
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html
index 3423293..f225218 100644
--- a/chrome/browser/resources/options/browser_options.html
+++ b/chrome/browser/resources/options/browser_options.html
@@ -139,7 +139,7 @@
         <div class="settings-row">
           <select id="default-search-engine" class="weakrtl"></select>
           <span class="controlled-setting-indicator"
-              pref="default_search_provider.enabled">
+              pref="default_search_provider_data.template_url_data">
           </span>
           <button id="manage-default-search-engines"
               i18n-content="defaultSearchManageEngines">
@@ -328,6 +328,7 @@
       <div class="checkbox">
         <span class="controlled-setting-with-label">
           <input id="spelling-enabled-control" type="checkbox"
+              metric="Options_SpellingServiceCheckbox"
               pref="spellcheck.use_spelling_service" dialog-pref>
           <span>
             <label for="spelling-enabled-control" i18n-content="spellingPref">
@@ -658,13 +659,6 @@
               i18n-content="certificatesManageButton"></button>
         </div>
 </if>
-        <div class="checkbox">
-          <label>
-            <input id="sslCheckRevocation" pref="ssl.rev_checking.enabled"
-                   type="checkbox">
-            <span i18n-content="sslCheckRevocation"></span>
-          </label>
-        </div>
       </div>
   </section>
 <if expr="enable_service_discovery">
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js
index 29fd428..4f96c7d 100644
--- a/chrome/browser/resources/options/browser_options.js
+++ b/chrome/browser/resources/options/browser_options.js
@@ -553,11 +553,17 @@
 
       // Extension controlled UI.
       this.addExtensionControlledBox_('search-section-content',
-                                      'search-engine-controlled');
+                                      'search-engine-controlled',
+                                      true);
       this.addExtensionControlledBox_('extension-controlled-container',
-                                      'homepage-controlled');
+                                      'homepage-controlled',
+                                      true);
       this.addExtensionControlledBox_('startup-section-content',
-                                      'startpage-controlled');
+                                      'startpage-controlled',
+                                      false);
+      this.addExtensionControlledBox_('newtab-section-content',
+                                      'newtab-controlled',
+                                      false);
 
       document.body.addEventListener('click', function(e) {
         var button = findAncestor(e.target, function(el) {
@@ -1288,6 +1294,15 @@
              'There should always be a current profile, but none found.');
     },
 
+    /**
+     * Propmpts user to confirm deletion of the profile for this browser
+     * window.
+     * @private
+     */
+    deleteCurrentProfile_: function() {
+      ManageProfileOverlay.showDeleteDialog(this.getCurrentProfile_());
+    },
+
     setNativeThemeButtonEnabled_: function(enabled) {
       var button = $('themes-native-button');
       if (button)
@@ -1528,13 +1543,17 @@
      * extensions.
      * @param {string} parentDiv The div name to append the bubble to.
      * @param {string} bubbleId The ID to use for the bubble.
+     * @param {boolean} first Add as first node if true, otherwise last.
      * @private
      */
-    addExtensionControlledBox_: function(parentDiv, bubbleId) {
+    addExtensionControlledBox_: function(parentDiv, bubbleId, first) {
       var bubble = $('extension-controlled-warning-template').cloneNode(true);
       bubble.id = bubbleId;
       var parent = $(parentDiv);
-      parent.insertBefore(bubble, parent.firstChild);
+      if (first)
+        parent.insertBefore(bubble, parent.firstChild);
+      else
+        parent.appendChild(bubble);
     },
 
     /**
@@ -1570,50 +1589,32 @@
     },
 
     /**
-     * Toggles the bubble that shows which extension is controlling the search
-     * engine.
-     * @param {string} extensionId The ID of the extension controlling the
-     *     default search engine setting.
-     * @param {string} extensionName The name of the extension.
+     * Toggles the warning boxes that show which extension is controlling
+     * various settings of Chrome.
+     * @param {object} details A dictionary of ID+name pairs for each of the
+     *     settings controlled by an extension.
      * @private
      */
-    toggleSearchEngineControlled_: function(extensionId, extensionName) {
+    toggleExtensionIndicators_: function(details) {
       this.toggleExtensionControlledBox_('search-section-content',
                                          'search-engine-controlled',
-                                         extensionId,
-                                         extensionName);
-    },
-
-    /**
-     * Toggles the bubble that shows which extension is controlling the home
-     * page.
-     * @param {string} extensionId The ID of the extension controlling the
-     *     home page setting.
-     * @param {string} extensionName The name of the extension.
-     * @private
-     */
-    toggleHomepageControlled_: function(extensionId, extensionName) {
+                                         details.searchEngine.id,
+                                         details.searchEngine.name);
       this.toggleExtensionControlledBox_('extension-controlled-container',
                                          'homepage-controlled',
-                                         extensionId,
-                                         extensionName);
-    },
-
-    /**
-     * Toggles the bubble that shows which extension is controlling the startup
-     * pages.
-     * @param {string} extensionId The ID of the extension controlling the
-     *     startup pages setting.
-     * @param {string} extensionName The name of the extension.
-     * @private
-     */
-    toggleStartupPagesControlled_: function(extensionId, extensionName) {
+                                         details.homePage.id,
+                                         details.homePage.name);
       this.toggleExtensionControlledBox_('startup-section-content',
                                          'startpage-controlled',
-                                         extensionId,
-                                         extensionName);
+                                         details.startUpPage.id,
+                                         details.startUpPage.name);
+      this.toggleExtensionControlledBox_('newtab-section-content',
+                                         'newtab-controlled',
+                                         details.newTabPage.id,
+                                         details.newTabPage.name);
     },
 
+
     /**
      * Show/hide touchpad-related settings.
      * @private
@@ -1755,6 +1756,7 @@
   //Forward public APIs to private implementations.
   [
     'addBluetoothDevice',
+    'deleteCurrentProfile',
     'enableCertificateButton',
     'enableFactoryResetSection',
     'getCurrentProfile',
@@ -1788,9 +1790,7 @@
     'showManagedUserImportSuccess',
     'showMouseControls',
     'showTouchpadControls',
-    'toggleHomepageControlled',
-    'toggleSearchEngineControlled',
-    'toggleStartupPagesControlled',
+    'toggleExtensionIndicators',
     'updateAccountPicture',
     'updateAutoLaunchState',
     'updateDefaultBrowserState',
diff --git a/chrome/browser/resources/options/content_settings.js b/chrome/browser/resources/options/content_settings.js
index 12b85af..357b9eb 100644
--- a/chrome/browser/resources/options/content_settings.js
+++ b/chrome/browser/resources/options/content_settings.js
@@ -115,8 +115,9 @@
         value: dict[group].value,
         controlledBy: controlledBy,
       };
-      for (var i = 0; i < indicators.length; i++)
+      for (var i = 0; i < indicators.length; i++) {
         indicators[i].handlePrefChange(event);
+      }
     }
   };
 
@@ -164,31 +165,36 @@
   /**
    * Initializes an exceptions list.
    * @param {string} type The content type that we are setting exceptions for.
-   * @param {Array} list An array of pairs, where the first element of each pair
-   *     is the filter string, and the second is the setting (allow/block).
+   * @param {Array} exceptions An array of pairs, where the first element of
+   *     each pair is the filter string, and the second is the setting
+   *     (allow/block).
    */
-  ContentSettings.setExceptions = function(type, list) {
-    var exceptionsList =
-        document.querySelector('div[contentType=' + type + ']' +
-                               ' list[mode=normal]');
-    exceptionsList.setExceptions(list);
+  ContentSettings.setExceptions = function(type, exceptions) {
+    this.getExceptionsList(type, 'normal').setExceptions(exceptions);
   };
 
-  ContentSettings.setHandlers = function(list) {
-    $('handlers-list').setHandlers(list);
+  ContentSettings.setHandlers = function(handlers) {
+    $('handlers-list').setHandlers(handlers);
   };
 
-  ContentSettings.setIgnoredHandlers = function(list) {
-    $('ignored-handlers-list').setHandlers(list);
+  ContentSettings.setIgnoredHandlers = function(ignoredHandlers) {
+    $('ignored-handlers-list').setHandlers(ignoredHandlers);
   };
 
-  ContentSettings.setOTRExceptions = function(type, list) {
-    var exceptionsList =
-        document.querySelector('div[contentType=' + type + ']' +
-                               ' list[mode=otr]');
-
+  ContentSettings.setOTRExceptions = function(type, otrExceptions) {
+    var exceptionsList = this.getExceptionsList(type, 'otr');
     exceptionsList.parentNode.hidden = false;
-    exceptionsList.setExceptions(list);
+    exceptionsList.setExceptions(otrExceptions);
+  };
+
+  /**
+   * @param {string} type The type of exceptions (e.g. "location") to get.
+   * @param {string} mode The mode of the desired exceptions list (e.g. otr).
+   * @return {?ExceptionsList} The corresponding exceptions list or null.
+   */
+  ContentSettings.getExceptionsList = function(type, mode) {
+    return document.querySelector(
+        'div[contentType=' + type + '] list[mode=' + mode + ']');
   };
 
   /**
@@ -202,10 +208,8 @@
    */
   ContentSettings.patternValidityCheckComplete =
       function(type, mode, pattern, valid) {
-    var exceptionsList =
-        document.querySelector('div[contentType=' + type + '] ' +
-                               'list[mode=' + mode + ']');
-    exceptionsList.patternValidityCheckComplete(pattern, valid);
+    this.getExceptionsList(type, mode).patternValidityCheckComplete(pattern,
+                                                                    valid);
   };
 
   /**
@@ -216,7 +220,7 @@
    */
   ContentSettings.showMediaPepperFlashDefaultLink = function(show) {
     $('media-pepper-flash-default').hidden = !show;
-  }
+  };
 
   /**
    * Shows/hides the link to the Pepper Flash camera and microphone
@@ -226,7 +230,7 @@
    */
   ContentSettings.showMediaPepperFlashExceptionsLink = function(show) {
     $('media-pepper-flash-exceptions').hidden = !show;
-  }
+  };
 
   /**
    * Shows/hides the whole Web MIDI settings.
@@ -234,7 +238,7 @@
    */
   ContentSettings.showExperimentalWebMIDISettings = function(show) {
     $('experimental-web-midi-settings').hidden = !show;
-  }
+  };
 
   /**
    * Updates the microphone/camera devices menu with the given entries.
@@ -275,10 +279,9 @@
    */
   ContentSettings.enableProtectedContentExceptions = function(enable) {
     var exceptionsButton = $('protected-content-exceptions');
-    if (exceptionsButton) {
+    if (exceptionsButton)
       exceptionsButton.disabled = !enable;
-    }
-  }
+  };
 
   /**
    * Set the default microphone device based on the popup selection.
diff --git a/chrome/browser/resources/options/controlled_setting.js b/chrome/browser/resources/options/controlled_setting.js
index cdc2205..5ac42d9 100644
--- a/chrome/browser/resources/options/controlled_setting.js
+++ b/chrome/browser/resources/options/controlled_setting.js
@@ -171,7 +171,8 @@
                                          path: '?id=' + extensionId});
           };
 
-          var disableButton = extensionContainer.querySelector('button');
+          var disableButton = extensionContainer.querySelector(
+              '.controlled-setting-bubble-extension-disable-button');
           disableButton.onclick = function() {
             chrome.send('disableExtension', [extensionId]);
           };
diff --git a/chrome/browser/resources/options/handler_options.js b/chrome/browser/resources/options/handler_options.js
index 894e13f..0918e0f 100644
--- a/chrome/browser/resources/options/handler_options.js
+++ b/chrome/browser/resources/options/handler_options.js
@@ -27,7 +27,7 @@
 
     /**
      * The handlers list.
-     * @type {DeletableItemList}
+     * @type {options.HandlersList}
      * @private
      */
     handlersList_: null,
diff --git a/chrome/browser/resources/options/handler_options_list.js b/chrome/browser/resources/options/handler_options_list.js
index 5572a55..fef1740 100644
--- a/chrome/browser/resources/options/handler_options_list.js
+++ b/chrome/browser/resources/options/handler_options_list.js
@@ -6,7 +6,6 @@
   /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
   /** @const */ var List = cr.ui.List;
   /** @const */ var ListItem = cr.ui.ListItem;
-  /** @const */ var HandlerOptions = options.HandlerOptions;
   /** @const */ var DeletableItem = options.DeletableItem;
   /** @const */ var DeletableItemList = options.DeletableItemList;
 
@@ -168,7 +167,6 @@
     decorate: function() {
       ListItem.prototype.decorate.call(this);
 
-      var self = this;
       var delegate = {
         removeHandler: function(index, handler) {
           chrome.send('removeHandler', [handler]);
diff --git a/chrome/browser/resources/options/import_data_overlay.html b/chrome/browser/resources/options/import_data_overlay.html
index 5721508..4aca7cf 100644
--- a/chrome/browser/resources/options/import_data_overlay.html
+++ b/chrome/browser/resources/options/import_data_overlay.html
@@ -116,7 +116,9 @@
       </div>
     </div>
   </div>
+<if expr="is_macosx">
   <div id="mac-password-keychain" class="gray-bottom-bar">
     <span i18n-content="macPasswordKeychain"></span>
   </div>
+</if>
 </div>
diff --git a/chrome/browser/resources/options/import_data_overlay.js b/chrome/browser/resources/options/import_data_overlay.js
index 3cda00d..f6fb061 100644
--- a/chrome/browser/resources/options/import_data_overlay.js
+++ b/chrome/browser/resources/options/import_data_overlay.js
@@ -93,7 +93,9 @@
         this.setUpCheckboxState_(checkboxes[i], enabled);
       $('import-data-commit').disabled = !enabled;
       $('import-choose-file').hidden = !enabled;
+<if expr="is_macosx">
       $('mac-password-keychain').hidden = !enabled;
+</if>
     },
 
     /**
@@ -140,7 +142,9 @@
       if (this.browserProfiles.length > index)
         browserProfile = this.browserProfiles[index];
       var enable = browserProfile && browserProfile['show_bottom_bar'];
+<if expr="is_macosx">
       $('mac-password-keychain').hidden = !enable;
+</if>
     },
 
     /**
diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html
index 1115884..f99f773 100644
--- a/chrome/browser/resources/options/options.html
+++ b/chrome/browser/resources/options/options.html
@@ -166,8 +166,8 @@
     <div class="controlled-setting-bubble-extension-name"></div>
   </div>
   <div class="controlled-setting-bubble-content-row">
-    <div class="controlled-setting-bubble-extension-manage-link link-button"
-        i18n-content="controlledSettingManageExtension"></div>
+    <button class="controlled-setting-bubble-extension-manage-link link-button"
+        i18n-content="controlledSettingManageExtension"></button>
     <button class='controlled-setting-bubble-extension-disable-button'
         i18n-content="controlledSettingDisableExtension"></button>
   </div>
diff --git a/chrome/browser/resources/options/startup_section.html b/chrome/browser/resources/options/startup_section.html
index ce1b7a9..41a34ec 100644
--- a/chrome/browser/resources/options/startup_section.html
+++ b/chrome/browser/resources/options/startup_section.html
@@ -1,7 +1,7 @@
 <section id="startup-section" guest-visibility="hidden">
   <h3 i18n-content="sectionTitleStartup"></h3>
   <div id="startup-section-content">
-    <div class="radio">
+    <div class="radio" id="newtab-section-content">
       <span class="controlled-setting-with-label">
         <input id="startup-newtab" type="radio" name="startup" value="5"
             pref="session.restore_on_startup"
diff --git a/chrome/browser/resources/pdf/manifest.json b/chrome/browser/resources/pdf/manifest.json
index 8e1f348..f97e970 100644
--- a/chrome/browser/resources/pdf/manifest.json
+++ b/chrome/browser/resources/pdf/manifest.json
@@ -6,6 +6,7 @@
   "version": "1",
   "description": "Chrome PDF Viewer",
   "offline_enabled": true,
+  "incognito": "split",
   "permissions": [
     "file://*/",
     "ftp://*/",
diff --git a/chrome/browser/resources/pdf/pdf.js b/chrome/browser/resources/pdf/pdf.js
index 60d3fb9..7a85281 100644
--- a/chrome/browser/resources/pdf/pdf.js
+++ b/chrome/browser/resources/pdf/pdf.js
@@ -9,6 +9,22 @@
 <include src="pdf_scripting_api.js">
 
 /**
+ * @return {number} Width of a scrollbar in pixels
+ */
+function getScrollbarWidth() {
+  var div = document.createElement('div');
+  div.style.visibility = 'hidden';
+  div.style.overflow = 'scroll';
+  div.style.width = '50px';
+  div.style.height = '50px';
+  div.style.position = 'absolute';
+  document.body.appendChild(div);
+  var result = div.offsetWidth - div.clientWidth;
+  div.parentNode.removeChild(div);
+  return result;
+}
+
+/**
  * Creates a new PDFViewer. There should only be one of these objects per
  * document.
  */
@@ -28,13 +44,16 @@
   // Create the viewport.
   this.viewport_ = new Viewport(window,
                                 this.sizer_,
-                                this.viewportChangedCallback_.bind(this));
+                                this.viewportChangedCallback_.bind(this),
+                                getScrollbarWidth());
 
   // Create the plugin object dynamically so we can set its src. The plugin
   // element is sized to fill the entire window and is set to be fixed
   // positioning, acting as a viewport. The plugin renders into this viewport
   // according to the scroll position of the window.
   this.plugin_ = document.createElement('object');
+  // NOTE: The plugin's 'id' field must be set to 'plugin' since
+  // chrome/renderer/printing/print_web_view_helper.cc actually references it.
   this.plugin_.id = 'plugin';
   this.plugin_.type = 'application/x-google-chrome-pdf';
   this.plugin_.addEventListener('message', this.handleMessage_.bind(this),
@@ -62,6 +81,8 @@
   }
 
   this.plugin_.setAttribute('src', streamDetails.streamUrl);
+  if (window.top == window)
+    this.plugin_.setAttribute('full-frame', '');
   document.body.appendChild(this.plugin_);
 
   this.messagingHost_ = new PDFMessagingHost(window, this);
@@ -102,7 +123,7 @@
           return;
         case 33:  // Page up key.
           // Go to the previous page if we are fit-to-page.
-          if (isFitToPageEnabled()) {
+          if (this.viewport_.fittingType == Viewport.FittingType.FIT_TO_PAGE) {
             this.viewport_.goToPage(this.viewport_.getMostVisiblePage() - 1);
             // Since we do the movement of the page.
             e.preventDefault();
@@ -118,7 +139,7 @@
           return;
         case 34:  // Page down key.
           // Go to the next page if we are fit-to-page.
-          if (isFitToPageEnabled()) {
+          if (this.viewport_.fittingType == Viewport.FittingType.FIT_TO_PAGE) {
             this.viewport_.goToPage(this.viewport_.getMostVisiblePage() + 1);
             // Since we do the movement of the page.
             e.preventDefault();
diff --git a/chrome/browser/resources/pdf/viewport.js b/chrome/browser/resources/pdf/viewport.js
index 525b823..f382b2c 100644
--- a/chrome/browser/resources/pdf/viewport.js
+++ b/chrome/browser/resources/pdf/viewport.js
@@ -19,40 +19,24 @@
 }
 
 /**
- * @return {number} width of a scrollbar in pixels
- */
-function getScrollbarWidth() {
-  var parentDiv = document.createElement('div');
-  parentDiv.style.visibility = 'hidden';
-  var parentDivWidth = 500;
-  parentDiv.style.width = parentDivWidth + 'px';
-  document.body.appendChild(parentDiv);
-  parentDiv.style.overflow = 'scroll';
-  var childDiv = document.createElement('div');
-  childDiv.style.width = '100%';
-  parentDiv.appendChild(childDiv);
-  var childDivWidth = childDiv.offsetWidth;
-  parentDiv.parentNode.removeChild(parentDiv);
-  return parentDivWidth - childDivWidth;
-}
-
-/**
  * Create a new viewport.
  * @param {Window} window the window
  * @param {Object} sizer is the element which represents the size of the
  *     document in the viewport
  * @param {Function} viewportChangedCallback is run when the viewport changes
+ * @param {number} scrollbarWidth the width of scrollbars on the page
  */
 function Viewport(window,
                   sizer,
-                  viewportChangedCallback) {
+                  viewportChangedCallback,
+                  scrollbarWidth) {
   this.window_ = window;
   this.sizer_ = sizer;
   this.viewportChangedCallback_ = viewportChangedCallback;
   this.zoom_ = 1;
   this.documentDimensions_ = null;
   this.pageDimensions_ = [];
-  this.scrollbarWidth_ = getScrollbarWidth();
+  this.scrollbarWidth_ = scrollbarWidth;
   this.fittingType_ = Viewport.FittingType.NONE;
 
   window.addEventListener('scroll', this.updateViewport_.bind(this));
@@ -114,10 +98,12 @@
    * Helper function called when the zoomed document size changes.
    */
   contentSizeChanged_: function() {
-    this.sizer_.style.width =
-        this.documentDimensions_.width * this.zoom_ + 'px';
-    this.sizer_.style.height =
-        this.documentDimensions_.height * this.zoom_ + 'px';
+    if (this.documentDimensions_) {
+      this.sizer_.style.width =
+          this.documentDimensions_.width * this.zoom_ + 'px';
+      this.sizer_.style.height =
+          this.documentDimensions_.height * this.zoom_ + 'px';
+    }
   },
 
   /**
@@ -189,8 +175,8 @@
     this.zoom_ = newZoom;
     // Record the scroll position (relative to the middle of the window).
     var currentScrollPos = [
-      (this.window_.scrollX + this.window_.innerWidth / 2) / oldZoom,
-      (this.window_.scrollY + this.window_.innerHeight / 2) / oldZoom
+      (this.window_.pageXOffset + this.window_.innerWidth / 2) / oldZoom,
+      (this.window_.pageYOffset + this.window_.innerHeight / 2) / oldZoom
     ];
     this.contentSizeChanged_();
     // Scroll to the scaled scroll position.
@@ -250,14 +236,14 @@
   getMostVisiblePage: function() {
     var firstVisiblePage = this.getPageAtY_(this.position.y / this.zoom_);
     var mostVisiblePage = {number: 0, area: 0};
+    var viewportRect = {
+      x: this.position.x / this.zoom_,
+      y: this.position.y / this.zoom_,
+      width: this.size.width / this.zoom_,
+      height: this.size.height / this.zoom_
+    };
     for (var i = firstVisiblePage; i < this.pageDimensions_.length; i++) {
-      var viewportRect = {
-        x: 0,
-        y: 0,
-        width: this.size.width,
-        height: this.size.height
-      };
-      var area = getIntersectionArea(this.getPageScreenRect(i),
+      var area = getIntersectionArea(this.pageDimensions_[i],
                                      viewportRect);
       // If we hit a page with 0 area overlap, we must have gone past the
       // pages visible in the viewport so we can break.
@@ -343,13 +329,12 @@
     if (!this.documentDimensions_)
       return;
     // Track the last y-position so we stay at the same position after zooming.
-    var oldY = this.window_.scrollY / this.zoom_;
+    var oldY = this.window_.pageYOffset / this.zoom_;
     // When computing fit-to-width, the maximum width of a page in the document
     // is used, which is equal to the size of the document width.
     this.setZoom_(this.computeFittingZoom_(this.documentDimensions_, true));
     var page = this.getMostVisiblePage();
-    this.window_.scrollTo(this.pageDimensions_[page].x * this.zoom_,
-                          oldY * this.zoom_);
+    this.window_.scrollTo(0, oldY * this.zoom_);
     this.updateViewport_();
   },
 
@@ -403,7 +388,7 @@
 
   /**
    * Go to the given page index.
-   * @param {number} page the index of the page to go to
+   * @param {number} page the index of the page to go to.
    */
   goToPage: function(page) {
     if (this.pageDimensions_.length == 0)
@@ -456,13 +441,20 @@
           Viewport.PAGE_SHADOW.bottom
     };
 
-    // Compute the amount of empty space of the left of the page.
-    var spaceOnLeft = Math.max(
-        (this.size.width - pageDimensions.width * this.zoom_) / 2.0, 0);
+    // Compute the x-coordinate of the page within the document.
+    // TODO(raymes): This should really be set when the PDF plugin passes the
+    // page coordinates, but it isn't yet.
+    var x = (this.documentDimensions_.width - pageDimensions.width) / 2 +
+        Viewport.PAGE_SHADOW.left;
+    // Compute the space on the left of the document if the document fits
+    // completely in the screen.
+    var spaceOnLeft = (this.size.width -
+        this.documentDimensions_.width * this.zoom_) / 2;
+    spaceOnLeft = Math.max(spaceOnLeft, 0);
 
     return {
-      x: Viewport.PAGE_SHADOW.left + spaceOnLeft - this.window_.pageXOffset,
-      y: (insetDimensions.y * this.zoom_) - this.window_.pageYOffset,
+      x: x * this.zoom_ + spaceOnLeft - this.window_.pageXOffset,
+      y: insetDimensions.y * this.zoom_ - this.window_.pageYOffset,
       width: insetDimensions.width * this.zoom_,
       height: insetDimensions.height * this.zoom_
     };
diff --git a/chrome/browser/resources/quota_internals/message_dispatcher.js b/chrome/browser/resources/quota_internals/message_dispatcher.js
index 88646ba..7088a68 100644
--- a/chrome/browser/resources/quota_internals/message_dispatcher.js
+++ b/chrome/browser/resources/quota_internals/message_dispatcher.js
@@ -9,7 +9,7 @@
 /**
  * Bridge between the browser and the page.
  * In this file:
- *   * define EventTargets to recieve message from the browser,
+ *   * define EventTargets to receive message from the browser,
  *   * dispatch browser messages to EventTarget,
  *   * define interface to request data to the browser.
  */
diff --git a/chrome/browser/resources/ssl/blocking.html b/chrome/browser/resources/ssl/blocking.html
index c6d62dd..95ea6f8 100644
--- a/chrome/browser/resources/ssl/blocking.html
+++ b/chrome/browser/resources/ssl/blocking.html
@@ -24,8 +24,10 @@
         </h1>
         <p i18n-values=".innerHTML:message" class="explanation-par"></p>
         <div id="buttons">
-          <button id="reload-button" i18n-content="reloadMsg"></button>
-          <button id="more-less-button" i18n-content="more"></button>
+          <button id="reload-button" i18n-content="reloadMsg"
+              class="blue-button text-button"></button>
+          <button id="more-less-button" i18n-content="more"
+              class="text-button"></button>
         </div>
       </div>
       <div id="help-box-outer" class="hidden">
diff --git a/chrome/browser/resources/sync_setup_overlay.css b/chrome/browser/resources/sync_setup_overlay.css
index ecb8539..173066e 100644
--- a/chrome/browser/resources/sync_setup_overlay.css
+++ b/chrome/browser/resources/sync_setup_overlay.css
@@ -98,6 +98,10 @@
   min-width: 87px;
 }
 
+#sync-setup-delete-profile {
+  margin: 10px 0 0 0;
+}
+
 #email-readonly {
   font-size: 15px;
   height: 29px;
diff --git a/chrome/browser/resources/sync_setup_overlay.html b/chrome/browser/resources/sync_setup_overlay.html
index ebc13c0..a92d431 100644
--- a/chrome/browser/resources/sync_setup_overlay.html
+++ b/chrome/browser/resources/sync_setup_overlay.html
@@ -220,6 +220,14 @@
     <h1 i18n-content="stopSyncingTitle"></h1>
     <div class="content-area">
       <span i18n-values=".innerHTML:stopSyncingExplanation"></span>
+<if expr="(not chromeos and is_posix) or is_win or is_macosx">
+      <div id="sync-setup-delete-profile" class="checkbox">
+        <label>
+          <input id="delete-profile" type="checkbox">
+          <span i18n-content="deleteProfileLabel"></span>
+        </label>
+      </div>
+</if>
     </div>
     <div class="action-area button-strip">
       <input id="stop-syncing-cancel" type="button"
diff --git a/chrome/browser/resources/sync_setup_overlay.js b/chrome/browser/resources/sync_setup_overlay.js
index 909aa0a..a44e2bb 100644
--- a/chrome/browser/resources/sync_setup_overlay.js
+++ b/chrome/browser/resources/sync_setup_overlay.js
@@ -83,7 +83,9 @@
         self.closeOverlay_();
       };
       $('stop-syncing-ok').onclick = function() {
-        chrome.send('SyncSetupStopSyncing');
+        var deleteProfile = $('delete-profile') != undefined &&
+            $('delete-profile').checked;
+        chrome.send('SyncSetupStopSyncing', [deleteProfile]);
         self.closeOverlay_();
       };
     },
diff --git a/chrome/browser/resources/test_presubmit.py b/chrome/browser/resources/test_presubmit.py
deleted file mode 100755
index 00fc207..0000000
--- a/chrome/browser/resources/test_presubmit.py
+++ /dev/null
@@ -1,666 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 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.
-
-"""Unit tests for Web Development Style Guide checker."""
-
-import os
-import re
-import sys
-import unittest
-
-test_dir = os.path.dirname(os.path.abspath(__file__))
-sys.path.extend([
-    os.path.normpath(os.path.join(test_dir, '..', '..', '..', 'tools')),
-    os.path.join(test_dir),
-])
-
-import find_depot_tools # pylint: disable=W0611
-from testing_support.super_mox import SuperMoxTestBase
-from web_dev_style import css_checker, js_checker # pylint: disable=F0401
-
-
-class JsStyleGuideTest(SuperMoxTestBase):
-  def setUp(self):
-    SuperMoxTestBase.setUp(self)
-
-    input_api = self.mox.CreateMockAnything()
-    input_api.re = re
-    output_api = self.mox.CreateMockAnything()
-    self.checker = js_checker.JSChecker(input_api, output_api)
-
-  def GetHighlight(self, line, error):
-    """Returns the substring of |line| that is highlighted in |error|."""
-    error_lines = error.split('\n')
-    highlight = error_lines[error_lines.index(line) + 1]
-    return ''.join(ch1 for (ch1, ch2) in zip(line, highlight) if ch2 == '^')
-
-  def ShouldFailConstCheck(self, line):
-    """Checks that the 'const' checker flags |line| as a style error."""
-    error = self.checker.ConstCheck(1, line)
-    self.assertNotEqual('', error,
-        'Should be flagged as style error: ' + line)
-    self.assertEqual(self.GetHighlight(line, error), 'const')
-
-  def ShouldPassConstCheck(self, line):
-    """Checks that the 'const' checker doesn't flag |line| as a style error."""
-    self.assertEqual('', self.checker.ConstCheck(1, line),
-        'Should not be flagged as style error: ' + line)
-
-  def testConstFails(self):
-    lines = [
-        "const foo = 'bar';",
-        "    const bar = 'foo';",
-
-        # Trying to use |const| as a variable name
-        "var const = 0;",
-
-        "var x = 5; const y = 6;",
-        "for (var i=0, const e=10; i<e; i++) {",
-        "for (const x=0; x<foo; i++) {",
-        "while (const x = 7) {",
-    ]
-    for line in lines:
-      self.ShouldFailConstCheck(line)
-
-  def testConstPasses(self):
-    lines = [
-        # sanity check
-        "var foo = 'bar'",
-
-        # @const JsDoc tag
-        "/** @const */ var SEVEN = 7;",
-
-        # @const tag in multi-line comment
-        " * @const",
-        "   * @const",
-
-        # @constructor tag in multi-line comment
-        " * @constructor",
-        "   * @constructor",
-
-        # words containing 'const'
-        "if (foo.constructor) {",
-        "var deconstruction = 'something';",
-        "var madeUpWordconst = 10;",
-
-        # Strings containing the word |const|
-        "var str = 'const at the beginning';",
-        "var str = 'At the end: const';",
-
-        # doing this one with regex is probably not practical
-        #"var str = 'a const in the middle';",
-    ]
-    for line in lines:
-      self.ShouldPassConstCheck(line)
-
-  def ShouldFailChromeSendCheck(self, line):
-    """Checks that the 'chrome.send' checker flags |line| as a style error."""
-    error = self.checker.ChromeSendCheck(1, line)
-    self.assertNotEqual('', error,
-        'Should be flagged as style error: ' + line)
-    self.assertEqual(self.GetHighlight(line, error), ', []')
-
-  def ShouldPassChromeSendCheck(self, line):
-    """Checks that the 'chrome.send' checker doesn't flag |line| as a style
-       error.
-    """
-    self.assertEqual('', self.checker.ChromeSendCheck(1, line),
-        'Should not be flagged as style error: ' + line)
-
-  def testChromeSendFails(self):
-    lines = [
-        "chrome.send('message', []);",
-        "  chrome.send('message', []);",
-    ]
-    for line in lines:
-      self.ShouldFailChromeSendCheck(line)
-
-  def testChromeSendPasses(self):
-    lines = [
-        "chrome.send('message', constructArgs('foo', []));",
-        "  chrome.send('message', constructArgs('foo', []));",
-        "chrome.send('message', constructArgs([]));",
-        "  chrome.send('message', constructArgs([]));",
-    ]
-    for line in lines:
-      self.ShouldPassChromeSendCheck(line)
-
-  def ShouldFailEndJsDocCommentCheck(self, line):
-    """Checks that the **/ checker flags |line| as a style error."""
-    error = self.checker.EndJsDocCommentCheck(1, line)
-    self.assertNotEqual('', error,
-        'Should be flagged as style error: ' + line)
-    self.assertEqual(self.GetHighlight(line, error), '**/')
-
-  def ShouldPassEndJsDocCommentCheck(self, line):
-    """Checks that the **/ checker doesn't flag |line| as a style error."""
-    self.assertEqual('', self.checker.EndJsDocCommentCheck(1, line),
-        'Should not be flagged as style error: ' + line)
-
-  def testEndJsDocCommentFails(self):
-    lines = [
-        "/** @override **/",
-        "/** @type {number} @const **/",
-        "  **/",
-        "**/  ",
-    ]
-    for line in lines:
-      self.ShouldFailEndJsDocCommentCheck(line)
-
-  def testEndJsDocCommentPasses(self):
-    lines = [
-        "/***************/",  # visual separators
-        "  */",  # valid JSDoc comment ends
-        "*/  ",
-        "/**/",  # funky multi-line comment enders
-        "/** @override */",  # legit JSDoc one-liners
-    ]
-    for line in lines:
-      self.ShouldPassEndJsDocCommentCheck(line)
-
-  def ShouldFailGetElementByIdCheck(self, line):
-    """Checks that the 'getElementById' checker flags |line| as a style
-       error.
-    """
-    error = self.checker.GetElementByIdCheck(1, line)
-    self.assertNotEqual('', error,
-        'Should be flagged as style error: ' + line)
-    self.assertEqual(self.GetHighlight(line, error), 'document.getElementById')
-
-  def ShouldPassGetElementByIdCheck(self, line):
-    """Checks that the 'getElementById' checker doesn't flag |line| as a style
-       error.
-    """
-    self.assertEqual('', self.checker.GetElementByIdCheck(1, line),
-        'Should not be flagged as style error: ' + line)
-
-  def testGetElementByIdFails(self):
-    lines = [
-        "document.getElementById('foo');",
-        "  document.getElementById('foo');",
-        "var x = document.getElementById('foo');",
-        "if (document.getElementById('foo').hidden) {",
-    ]
-    for line in lines:
-      self.ShouldFailGetElementByIdCheck(line)
-
-  def testGetElementByIdPasses(self):
-    lines = [
-        "elem.ownerDocument.getElementById('foo');",
-        "  elem.ownerDocument.getElementById('foo');",
-        "var x = elem.ownerDocument.getElementById('foo');",
-        "if (elem.ownerDocument.getElementById('foo').hidden) {",
-        "doc.getElementById('foo');",
-        "  doc.getElementById('foo');",
-        "cr.doc.getElementById('foo');",
-        "  cr.doc.getElementById('foo');",
-        "var x = doc.getElementById('foo');",
-        "if (doc.getElementById('foo').hidden) {",
-    ]
-    for line in lines:
-      self.ShouldPassGetElementByIdCheck(line)
-
-  def ShouldFailInheritDocCheck(self, line):
-    """Checks that the '@inheritDoc' checker flags |line| as a style error."""
-    error = self.checker.InheritDocCheck(1, line)
-    self.assertNotEqual('', error,
-        msg='Should be flagged as style error: ' + line)
-    self.assertEqual(self.GetHighlight(line, error), '@inheritDoc')
-
-  def ShouldPassInheritDocCheck(self, line):
-    """Checks that the '@inheritDoc' checker doesn't flag |line| as a style
-       error.
-    """
-    self.assertEqual('', self.checker.InheritDocCheck(1, line),
-        msg='Should not be flagged as style error: ' + line)
-
-  def testInheritDocFails(self):
-    lines = [
-        " /** @inheritDoc */",
-        "   * @inheritDoc",
-    ]
-    for line in lines:
-      self.ShouldFailInheritDocCheck(line)
-
-  def testInheritDocPasses(self):
-    lines = [
-        "And then I said, but I won't @inheritDoc! Hahaha!",
-        " If your dad's a doctor, do you inheritDoc?",
-        "  What's up, inherit doc?",
-        "   this.inheritDoc(someDoc)",
-    ]
-    for line in lines:
-      self.ShouldPassInheritDocCheck(line)
-
-  def ShouldFailWrapperTypeCheck(self, line):
-    """Checks that the use of wrapper types (i.e. new Number(), @type {Number})
-       is a style error.
-    """
-    error = self.checker.WrapperTypeCheck(1, line)
-    self.assertNotEqual('', error,
-        msg='Should be flagged as style error: ' + line)
-    highlight = self.GetHighlight(line, error)
-    self.assertTrue(highlight in ('Boolean', 'Number', 'String'))
-
-  def ShouldPassWrapperTypeCheck(self, line):
-    """Checks that the wrapper type checker doesn't flag |line| as a style
-       error.
-    """
-    self.assertEqual('', self.checker.WrapperTypeCheck(1, line),
-        msg='Should not be flagged as style error: ' + line)
-
-  def testWrapperTypePasses(self):
-    lines = [
-        "/** @param {!ComplexType} */",
-        "  * @type {Object}",
-        "   * @param {Function=} opt_callback",
-        "    * @param {} num Number of things to add to {blah}.",
-        "   *  @return {!print_preview.PageNumberSet}",
-        " /* @returns {Number} */",  # Should be /** @return {Number} */
-        "* @param {!LocalStrings}"
-        " Your type of Boolean is false!",
-        "  Then I parameterized her Number from her friend!",
-        "   A String of Pearls",
-        "    types.params.aBoolean.typeString(someNumber)",
-    ]
-    for line in lines:
-      self.ShouldPassWrapperTypeCheck(line)
-
-  def testWrapperTypeFails(self):
-    lines = [
-        "  /**@type {String}*/(string)",
-        "   * @param{Number=} opt_blah A number",
-        "/** @private @return {!Boolean} */",
-        " * @param {number|String}",
-    ]
-    for line in lines:
-      self.ShouldFailWrapperTypeCheck(line)
-
-  def ShouldFailVarNameCheck(self, line):
-    """Checks that var unix_hacker, $dollar are style errors."""
-    error = self.checker.VarNameCheck(1, line)
-    self.assertNotEqual('', error,
-        msg='Should be flagged as style error: ' + line)
-    highlight = self.GetHighlight(line, error)
-    self.assertFalse('var ' in highlight);
-
-  def ShouldPassVarNameCheck(self, line):
-    """Checks that variableNamesLikeThis aren't style errors."""
-    self.assertEqual('', self.checker.VarNameCheck(1, line),
-        msg='Should not be flagged as style error: ' + line)
-
-  def testVarNameFails(self):
-    lines = [
-        "var private_;",
-        " var _super_private",
-        "  var unix_hacker = someFunc();",
-    ]
-    for line in lines:
-      self.ShouldFailVarNameCheck(line)
-
-  def testVarNamePasses(self):
-    lines = [
-        "  var namesLikeThis = [];",
-        " for (var i = 0; i < 10; ++i) { ",
-        "for (var i in obj) {",
-        " var one, two, three;",
-        "  var magnumPI = {};",
-        " var g_browser = 'da browzer';",
-        "/** @const */ var Bla = options.Bla;",  # goog.scope() replacement.
-        " var $ = function() {",                 # For legacy reasons.
-        "  var StudlyCaps = cr.define('bla')",   # Classes.
-        " var SCARE_SMALL_CHILDREN = [",         # TODO(dbeam): add @const in
-                                                 # front of all these vars like
-        "/** @const */ CONST_VAR = 1;",          # this line has (<--).
-    ]
-    for line in lines:
-      self.ShouldPassVarNameCheck(line)
-
-
-class CssStyleGuideTest(SuperMoxTestBase):
-  def setUp(self):
-    SuperMoxTestBase.setUp(self)
-
-    self.fake_file_name = 'fake.css'
-
-    self.fake_file = self.mox.CreateMockAnything()
-    self.mox.StubOutWithMock(self.fake_file, 'LocalPath')
-    self.fake_file.LocalPath().AndReturn(self.fake_file_name)
-    # Actual calls to NewContents() are defined in each test.
-    self.mox.StubOutWithMock(self.fake_file, 'NewContents')
-
-    self.input_api = self.mox.CreateMockAnything()
-    self.input_api.re = re
-    self.mox.StubOutWithMock(self.input_api, 'AffectedSourceFiles')
-    self.input_api.AffectedFiles(
-        include_deletes=False, file_filter=None).AndReturn([self.fake_file])
-
-    # Actual creations of PresubmitPromptWarning are defined in each test.
-    self.output_api = self.mox.CreateMockAnything()
-    self.mox.StubOutWithMock(self.output_api, 'PresubmitPromptWarning',
-                             use_mock_anything=True)
-
-    author_msg = ('Was the CSS checker useful? '
-                  'Send feedback or hate mail to dbeam@chromium.org.')
-    self.output_api = self.mox.CreateMockAnything()
-    self.mox.StubOutWithMock(self.output_api, 'PresubmitNotifyResult',
-                             use_mock_anything=True)
-    self.output_api.PresubmitNotifyResult(author_msg).AndReturn(None)
-
-  def VerifyContentsProducesOutput(self, contents, output):
-    self.fake_file.NewContents().AndReturn(contents.splitlines())
-    self.output_api.PresubmitPromptWarning(
-        self.fake_file_name + ':\n' + output.strip()).AndReturn(None)
-    self.mox.ReplayAll()
-    css_checker.CSSChecker(self.input_api, self.output_api).RunChecks()
-
-  def testCssAlphaWithAtBlock(self):
-    self.VerifyContentsProducesOutput("""
-<include src="../shared/css/cr/ui/overlay.css">
-<include src="chrome://resources/totally-cool.css" />
-
-/* A hopefully safely ignored comment and @media statement. /**/
-@media print {
-  div {
-    display: block;
-    color: red;
-  }
-}
-
-.rule {
-  z-index: 5;
-<if expr="not is macosx">
-  background-image: url(chrome://resources/BLAH); /* TODO(dbeam): Fix this. */
-  background-color: rgb(235, 239, 249);
-</if>
-<if expr="is_macosx">
-  background-color: white;
-  background-image: url(chrome://resources/BLAH2);
-</if>
-  color: black;
-}
-
-<if expr="is_macosx">
-.language-options-right {
-  visibility: hidden;
-  opacity: 1; /* TODO(dbeam): Fix this. */
-}
-</if>""", """
-- Alphabetize properties and list vendor specific (i.e. -webkit) above standard.
-    display: block;
-    color: red;
-
-    z-index: 5;
-    color: black;""")
-
-  def testCssAlphaWithNonStandard(self):
-    self.VerifyContentsProducesOutput("""
-div {
-  /* A hopefully safely ignored comment and @media statement. /**/
-  color: red;
-  -webkit-margin-start: 5px;
-}""", """
-- Alphabetize properties and list vendor specific (i.e. -webkit) above standard.
-    color: red;
-    -webkit-margin-start: 5px;""")
-
-  def testCssAlphaWithLongerDashedProps(self):
-    self.VerifyContentsProducesOutput("""
-div {
-  border-left: 5px;  /* A hopefully removed comment. */
-  border: 5px solid red;
-}""", """
-- Alphabetize properties and list vendor specific (i.e. -webkit) above standard.
-    border-left: 5px;
-    border: 5px solid red;""")
-
-  def testCssBracesHaveSpaceBeforeAndNothingAfter(self):
-    self.VerifyContentsProducesOutput("""
-/* Hello! */div/* Comment here*/{
-  display: block;
-}
-
-blah /* hey! */
-{
-  rule: value;
-}
-
-.this.is { /* allowed */
-  rule: value;
-}""", """
-- Start braces ({) end a selector, have a space before them and no rules after.
-    div{
-    {""")
-
-  def testCssClassesUseDashes(self):
-    self.VerifyContentsProducesOutput("""
-.className,
-.ClassName,
-.class-name /* We should not catch this. */,
-.class_name {
-  display: block;
-}""", """
- - Classes use .dash-form.
-    .className,
-    .ClassName,
-    .class_name {""")
-
-  def testCssCloseBraceOnNewLine(self):
-    self.VerifyContentsProducesOutput("""
-@media { /* TODO(dbeam) Fix this case. */
-  .rule {
-    display: block;
-  }}
-
-@-webkit-keyframe blah {
-  100% { height: -500px 0; }
-}
-
-#rule {
-  rule: value; }""", """
-- Always put a rule closing brace (}) on a new line.
-    rule: value; }""")
-
-  def testCssColonsHaveSpaceAfter(self):
-    self.VerifyContentsProducesOutput("""
-div:not(.class):not([attr=5]), /* We should not catch this. */
-div:not(.class):not([attr]) /* Nor this. */ {
-  background: url(data:image/jpeg,asdfasdfsadf); /* Ignore this. */
-  background: -webkit-linear-gradient(left, red,
-                                      80% blah blee blar);
-  color: red;
-  display:block;
-}""", """
-- Colons (:) should have a space after them.
-    display:block;
-
-- Don't use data URIs in source files. Use grit instead.
-    background: url(data:image/jpeg,asdfasdfsadf);""")
-
-  def testCssFavorSingleQuotes(self):
-    self.VerifyContentsProducesOutput("""
-html[dir="rtl"] body,
-html[dir=ltr] body /* TODO(dbeam): Require '' around rtl in future? */ {
-  background: url("chrome://resources/BLAH");
-  font-family: "Open Sans";
-<if expr="is_macosx">
-  blah: blee;
-</if>
-}""", """
-- Use single quotes (') instead of double quotes (") in strings.
-    html[dir="rtl"] body,
-    background: url("chrome://resources/BLAH");
-    font-family: "Open Sans";""")
-
-  def testCssHexCouldBeShorter(self):
-    self.VerifyContentsProducesOutput("""
-#abc,
-#abc-,
-#abc-ghij,
-#abcdef-,
-#abcdef-ghij,
-#aaaaaa,
-#bbaacc {
-  background-color: #336699; /* Ignore short hex rule if not gray. */
-  color: #999999;
-  color: #666;
-}""", """
-- Use abbreviated hex (#rgb) when in form #rrggbb.
-    color: #999999; (replace with #999)
-
-- Use rgb() over #hex when not a shade of gray (like #333).
-    background-color: #336699; (replace with rgb(51, 102, 153))""")
-
-  def testCssUseMillisecondsForSmallTimes(self):
-    self.VerifyContentsProducesOutput("""
-.transition-0s /* This is gross but may happen. */ {
-  transform: one 0.2s;
-  transform: two .1s;
-  transform: tree 1s;
-  transform: four 300ms;
-}""", """
-- Use milliseconds for time measurements under 1 second.
-    transform: one 0.2s; (replace with 200ms)
-    transform: two .1s; (replace with 100ms)""")
-
-  def testCssNoDataUrisInSourceFiles(self):
-    self.VerifyContentsProducesOutput("""
-img {
-  background: url( data:image/jpeg,4\/\/350|\/|3|2 );
-  background: url('data:image/jpeg,4\/\/350|\/|3|2');
-}""", """
-- Don't use data URIs in source files. Use grit instead.
-    background: url( data:image/jpeg,4\/\/350|\/|3|2 );
-    background: url('data:image/jpeg,4\/\/350|\/|3|2');""")
-
-  def testCssOneRulePerLine(self):
-    self.VerifyContentsProducesOutput("""
-a:not([hidden]):not(.custom-appearance):not([version=1]):first-of-type,
-a:not([hidden]):not(.custom-appearance):not([version=1]):first-of-type ~
-    input[type='checkbox']:not([hidden]),
-div {
-  background: url(chrome://resources/BLAH);
-  rule: value; /* rule: value; */
-  rule: value; rule: value;
-}""", """
-- One rule per line (what not to do: color: red; margin: 0;).
-    rule: value; rule: value;""")
-
-  def testCssOneSelectorPerLine(self):
-    self.VerifyContentsProducesOutput("""
-a,
-div,a,
-div,/* Hello! */ span,
-#id.class([dir=rtl):not(.class):any(a, b, d) {
-  rule: value;
-}
-
-a,
-div,a {
-  some-other: rule here;
-}""", """
-- One selector per line (what not to do: a, b {}).
-    div,a,
-    div, span,
-    div,a {""")
-
-  def testCssPseudoElementDoubleColon(self):
-    self.VerifyContentsProducesOutput("""
-a:href,
-br::after,
-::-webkit-scrollbar-thumb,
-a:not([empty]):hover:focus:active, /* shouldn't catch here and above */
-abbr:after,
-.tree-label:empty:after,
-b:before,
-:-WebKit-ScrollBar {
-  rule: value;
-}""", """
-- Pseudo-elements should use double colon (i.e. ::after).
-    :after (should be ::after)
-    :after (should be ::after)
-    :before (should be ::before)
-    :-WebKit-ScrollBar (should be ::-WebKit-ScrollBar)
-    """)
-
-  def testCssRgbIfNotGray(self):
-    self.VerifyContentsProducesOutput("""
-#abc,
-#aaa,
-#aabbcc {
-  background: -webkit-linear-gradient(left, from(#abc), to(#def));
-  color: #bad;
-  color: #bada55;
-}""", """
-- Use rgb() over #hex when not a shade of gray (like #333).
-    background: -webkit-linear-gradient(left, from(#abc), to(#def)); """
-"""(replace with rgb(170, 187, 204), rgb(221, 238, 255))
-    color: #bad; (replace with rgb(187, 170, 221))
-    color: #bada55; (replace with rgb(186, 218, 85))""")
-
-  def testCssZeroLengthTerms(self):
-    self.VerifyContentsProducesOutput("""
-@-webkit-keyframe anim {
-  0% { /* Ignore key frames */
-    width: 0px;
-  }
-  10% {
-    width: 10px;
-  }
-  100% {
-    width: 100px;
-  }
-}
-
-/* http://crbug.com/359682 */
-#spinner-container #spinner {
-  -webkit-animation-duration: 1.0s;
-}
-
-.media-button.play > .state0.active,
-.media-button[state='0'] > .state0.normal /* blah */, /* blee */
-.media-button[state='0']:not(.disabled):hover > .state0.hover {
-  -webkit-animation: anim 0s;
-  -webkit-animation-duration: anim 0ms;
-  -webkit-transform: scale(0%),
-                     translateX(0deg),
-                     translateY(0rad),
-                     translateZ(0grad);
-  background-position-x: 0em;
-  background-position-y: 0ex;
-  border-width: 0em;
-  color: hsl(0, 0%, 85%); /* Shouldn't trigger error. */
-  opacity: .0;
-  opacity: 0.0;
-  opacity: 0.;
-}
-
-@page {
-  border-width: 0mm;
-  height: 0cm;
-  width: 0in;
-}""", """
-- Make all zero length terms (i.e. 0px) 0 unless inside of hsl() or part of"""
-""" @keyframe.
-    width: 0px;
-    -webkit-animation: anim 0s;
-    -webkit-animation-duration: anim 0ms;
-    -webkit-transform: scale(0%),
-    translateX(0deg),
-    translateY(0rad),
-    translateZ(0grad);
-    background-position-x: 0em;
-    background-position-y: 0ex;
-    border-width: 0em;
-    opacity: .0;
-    opacity: 0.0;
-    opacity: 0.;
-    border-width: 0mm;
-    height: 0cm;
-    width: 0in;
-""")
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/chrome/browser/resources/web_dev_style/js_checker.py b/chrome/browser/resources/web_dev_style/js_checker.py
deleted file mode 100644
index 6e2e10e..0000000
--- a/chrome/browser/resources/web_dev_style/js_checker.py
+++ /dev/null
@@ -1,255 +0,0 @@
-# Copyright (c) 2012 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.
-
-"""Presubmit script for Chromium JS resources.
-
-See chrome/browser/resources/PRESUBMIT.py
-"""
-
-class JSChecker(object):
-  def __init__(self, input_api, output_api, file_filter=None):
-    self.input_api = input_api
-    self.output_api = output_api
-    self.file_filter = file_filter
-
-  def RegexCheck(self, line_number, line, regex, message):
-    """Searches for |regex| in |line| to check for a particular style
-       violation, returning a message like the one below if the regex matches.
-       The |regex| must have exactly one capturing group so that the relevant
-       part of |line| can be highlighted. If more groups are needed, use
-       "(?:...)" to make a non-capturing group. Sample message:
-
-       line 6: Use var instead of const.
-           const foo = bar();
-           ^^^^^
-    """
-    match = self.input_api.re.search(regex, line)
-    if match:
-      assert len(match.groups()) == 1
-      start = match.start(1)
-      length = match.end(1) - start
-      return '  line %d: %s\n%s\n%s' % (
-          line_number,
-          message,
-          line,
-          self.error_highlight(start, length))
-    return ''
-
-  def ChromeSendCheck(self, i, line):
-    """Checks for a particular misuse of 'chrome.send'."""
-    return self.RegexCheck(i, line, r"chrome\.send\('[^']+'\s*(, \[\])\)",
-        'Passing an empty array to chrome.send is unnecessary')
-
-  def ConstCheck(self, i, line):
-    """Check for use of the 'const' keyword."""
-    if self.input_api.re.search(r'\*\s+@const', line):
-      # Probably a JsDoc line
-      return ''
-
-    return self.RegexCheck(i, line, r'(?:^|\s|\()(const)\s',
-        'Use /** @const */ var varName; instead of const varName;')
-
-  def EndJsDocCommentCheck(self, i, line):
-    msg = 'End JSDoc comments with */ instead of **/'
-    def _check(regex):
-      return self.RegexCheck(i, line, regex, msg)
-    return _check(r'^\s*(\*\*/)\s*$') or _check(r'/\*\* @[a-zA-Z]+.* (\*\*/)')
-
-  def GetElementByIdCheck(self, i, line):
-    """Checks for use of 'document.getElementById' instead of '$'."""
-    return self.RegexCheck(i, line, r"(document\.getElementById)\('",
-        "Use $('id'), from chrome://resources/js/util.js, instead of "
-        "document.getElementById('id')")
-
-  def InheritDocCheck(self, i, line):
-    """Checks for use of '@inheritDoc' instead of '@override'."""
-    return self.RegexCheck(i, line, r"\* (@inheritDoc)",
-        "@inheritDoc is deprecated, use @override instead")
-
-  def WrapperTypeCheck(self, i, line):
-    """Check for wrappers (new String()) instead of builtins (string)."""
-    return self.RegexCheck(i, line,
-        r"(?:/\*)?\*.*?@(?:param|return|type) ?"     # /** @param/@return/@type
-        r"{[^}]*\b(String|Boolean|Number)\b[^}]*}",  # {(Boolean|Number|String)}
-        "Don't use wrapper types (i.e. new String() or @type {String})")
-
-  def VarNameCheck(self, i, line):
-    """See the style guide. http://goo.gl/uKir6"""
-    return self.RegexCheck(i, line,
-        r"var (?!g_\w+)([a-z]*[_$][\w_$]*)(?<! \$)",
-        "Please use var namesLikeThis <http://goo.gl/uKir6>")
-
-  def error_highlight(self, start, length):
-    """Takes a start position and a length, and produces a row of '^'s to
-       highlight the corresponding part of a string.
-    """
-    return start * ' ' + length * '^'
-
-  def _makeErrorOrWarning(self, error_text, filename):
-    """Takes a few lines of text indicating a style violation and turns it into
-       a PresubmitError (if |filename| is in a directory where we've already
-       taken out all the style guide violations) or a PresubmitPromptWarning
-       (if it's in a directory where we haven't done that yet).
-    """
-    # TODO(tbreisacher): Once we've cleaned up the style nits in all of
-    # resources/ we can get rid of this function.
-    path = self.input_api.os_path
-    resources = self.input_api.PresubmitLocalPath()
-    dirs = (
-        path.join(resources, 'bookmark_manager'),
-        path.join(resources, 'extensions'),
-        path.join(resources, 'file_manager'),
-        path.join(resources, 'help'),
-        path.join(resources, 'history'),
-        path.join(resources, 'memory_internals'),
-        path.join(resources, 'net_export'),
-        path.join(resources, 'net_internals'),
-        path.join(resources, 'network_action_predictor'),
-        path.join(resources, 'ntp4'),
-        path.join(resources, 'options'),
-        path.join(resources, 'password_manager_internals'),
-        path.join(resources, 'print_preview'),
-        path.join(resources, 'profiler'),
-        path.join(resources, 'sync_promo'),
-        path.join(resources, 'tracing'),
-        path.join(resources, 'uber'),
-    )
-    if filename.startswith(dirs):
-      return self.output_api.PresubmitError(error_text)
-    else:
-      return self.output_api.PresubmitPromptWarning(error_text)
-
-  def RunChecks(self):
-    """Check for violations of the Chromium JavaScript style guide. See
-       http://chromium.org/developers/web-development-style-guide#TOC-JavaScript
-    """
-
-    import sys
-    import warnings
-    old_path = sys.path
-    old_filters = warnings.filters
-
-    try:
-      closure_linter_path = self.input_api.os_path.join(
-          self.input_api.change.RepositoryRoot(),
-          "third_party",
-          "closure_linter")
-      gflags_path = self.input_api.os_path.join(
-          self.input_api.change.RepositoryRoot(),
-          "third_party",
-          "python_gflags")
-
-      sys.path.insert(0, closure_linter_path)
-      sys.path.insert(0, gflags_path)
-
-      warnings.filterwarnings('ignore', category=DeprecationWarning)
-
-      from closure_linter import checker, errors
-      from closure_linter.common import errorhandler
-
-    finally:
-      sys.path = old_path
-      warnings.filters = old_filters
-
-    class ErrorHandlerImpl(errorhandler.ErrorHandler):
-      """Filters out errors that don't apply to Chromium JavaScript code."""
-
-      def __init__(self, re):
-        self._errors = []
-        self.re = re
-
-      def HandleFile(self, filename, first_token):
-        self._filename = filename
-
-      def HandleError(self, error):
-        if (self._valid(error)):
-          error.filename = self._filename
-          self._errors.append(error)
-
-      def GetErrors(self):
-        return self._errors
-
-      def HasErrors(self):
-        return bool(self._errors)
-
-      def _valid(self, error):
-        """Check whether an error is valid. Most errors are valid, with a few
-           exceptions which are listed here.
-        """
-
-        is_grit_statement = bool(
-            self.re.search("</?(include|if)", error.token.line))
-
-        # Ignore missing spaces before "(" until Promise#catch issue is solved.
-        # http://crbug.com/338301
-        if (error.code == errors.MISSING_SPACE and error.token.string == '(' and
-           'catch(' in error.token.line):
-          return False
-
-        return not is_grit_statement and error.code not in [
-            errors.COMMA_AT_END_OF_LITERAL,
-            errors.JSDOC_ILLEGAL_QUESTION_WITH_PIPE,
-            errors.JSDOC_TAG_DESCRIPTION_ENDS_WITH_INVALID_CHARACTER,
-            errors.LINE_TOO_LONG,
-            errors.MISSING_JSDOC_TAG_THIS,
-        ]
-
-    results = []
-
-    affected_files = self.input_api.change.AffectedFiles(
-        file_filter=self.file_filter,
-        include_deletes=False)
-    affected_js_files = filter(lambda f: f.LocalPath().endswith('.js'),
-                               affected_files)
-    for f in affected_js_files:
-      error_lines = []
-
-      # Check for the following:
-      # * document.getElementById()
-      # * the 'const' keyword
-      # * Passing an empty array to 'chrome.send()'
-      for i, line in enumerate(f.NewContents(), start=1):
-        error_lines += filter(None, [
-            self.ChromeSendCheck(i, line),
-            self.ConstCheck(i, line),
-            self.GetElementByIdCheck(i, line),
-            self.InheritDocCheck(i, line),
-            self.WrapperTypeCheck(i, line),
-            self.VarNameCheck(i, line),
-        ])
-
-      # Use closure_linter to check for several different errors
-      error_handler = ErrorHandlerImpl(self.input_api.re)
-      js_checker = checker.JavaScriptStyleChecker(error_handler)
-      js_checker.Check(self.input_api.os_path.join(
-          self.input_api.change.RepositoryRoot(),
-          f.LocalPath()))
-
-      for error in error_handler.GetErrors():
-        highlight = self.error_highlight(
-            error.token.start_index, error.token.length)
-        error_msg = '  line %d: E%04d: %s\n%s\n%s' % (
-            error.token.line_number,
-            error.code,
-            error.message,
-            error.token.line.rstrip(),
-            highlight)
-        error_lines.append(error_msg)
-
-      if error_lines:
-        error_lines = [
-            'Found JavaScript style violations in %s:' %
-            f.LocalPath()] + error_lines
-        results.append(self._makeErrorOrWarning(
-            '\n'.join(error_lines), f.AbsoluteLocalPath()))
-
-    if results:
-      results.append(self.output_api.PresubmitNotifyResult(
-          'See the JavaScript style guide at '
-          'http://www.chromium.org/developers/web-development-style-guide'
-          '#TOC-JavaScript and if you have any feedback about the JavaScript '
-          'PRESUBMIT check, contact tbreisacher@chromium.org or '
-          'dbeam@chromium.org'))
-
-    return results
diff --git a/chrome/browser/rlz/rlz.cc b/chrome/browser/rlz/rlz.cc
index a355450..4f0d182 100644
--- a/chrome/browser/rlz/rlz.cc
+++ b/chrome/browser/rlz/rlz.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_util.h"
+#include "chrome/browser/omnibox/omnibox_log.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_service.h"
@@ -443,6 +444,12 @@
                          const content::NotificationDetails& details) {
   switch (type) {
     case chrome::NOTIFICATION_OMNIBOX_OPENED_URL:
+      // In M-36, we made NOTIFICATION_OMNIBOX_OPENED_URL fire more often than
+      // it did previously.  The RLZ folks want RLZ's "first search" detection
+      // to remain as unaffected as possible by this change.  This test is
+      // there to keep the old behavior.
+      if (!content::Details<OmniboxLog>(details).ptr()->is_popup_open)
+        break;
       RecordFirstSearch(CHROME_OMNIBOX);
       registrar_.Remove(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
                         content::NotificationService::AllSources());
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.cc b/chrome/browser/safe_browsing/client_side_detection_host.cc
index a7d96cf..ad77670 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_host.cc
@@ -109,7 +109,7 @@
     }
 
     // For phishing we only classify HTTP pages.
-    if (!params_.url.SchemeIs(content::kHttpScheme)) {
+    if (!params_.url.SchemeIs(url::kHttpScheme)) {
       VLOG(1) << "Skipping phishing classification for URL: " << params_.url
               << " because it is not HTTP: "
               << params_.socket_address.host();
@@ -479,8 +479,7 @@
   return entry->GetExtraData(kSafeBrowsingMatchKey, &value);
 }
 
-void ClientSideDetectionHost::WebContentsDestroyed(WebContents* tab) {
-  DCHECK(tab);
+void ClientSideDetectionHost::WebContentsDestroyed() {
   // Tell any pending classification request that it is being canceled.
   if (classification_request_.get()) {
     classification_request_->Cancel();
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.h b/chrome/browser/safe_browsing/client_side_detection_host.h
index 1db9f29..24ca81c 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host.h
+++ b/chrome/browser/safe_browsing/client_side_detection_host.h
@@ -67,7 +67,7 @@
   explicit ClientSideDetectionHost(content::WebContents* tab);
 
   // From content::WebContentsObserver.
-  virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // Used for testing.
   void set_safe_browsing_managers(
diff --git a/chrome/browser/safe_browsing/database_manager.cc b/chrome/browser/safe_browsing/database_manager.cc
index 6af4054..7fe23c2 100644
--- a/chrome/browser/safe_browsing/database_manager.cc
+++ b/chrome/browser/safe_browsing/database_manager.cc
@@ -222,8 +222,8 @@
 
 bool SafeBrowsingDatabaseManager::CanCheckUrl(const GURL& url) const {
   return url.SchemeIs(content::kFtpScheme) ||
-         url.SchemeIs(content::kHttpScheme) ||
-         url.SchemeIs(content::kHttpsScheme);
+         url.SchemeIs(url::kHttpScheme) ||
+         url.SchemeIs(url::kHttpsScheme);
 }
 
 bool SafeBrowsingDatabaseManager::CheckDownloadUrl(
diff --git a/chrome/browser/safe_browsing/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection_service.cc
index abdcb0f..a6cfef7 100644
--- a/chrome/browser/safe_browsing/download_protection_service.cc
+++ b/chrome/browser/safe_browsing/download_protection_service.cc
@@ -93,6 +93,8 @@
   EXTENSION_OTHER,  // Groups all other extensions into one bucket.
   EXTENSION_CRX,
   EXTENSION_APK,
+  EXTENSION_DMG,
+  EXTENSION_PKG,
   EXTENSION_MAX,
 };
 
@@ -117,6 +119,8 @@
   if (f.MatchesExtension(FILE_PATH_LITERAL(".grp"))) return EXTENSION_GRP;
   if (f.MatchesExtension(FILE_PATH_LITERAL(".crx"))) return EXTENSION_CRX;
   if (f.MatchesExtension(FILE_PATH_LITERAL(".apk"))) return EXTENSION_APK;
+  if (f.MatchesExtension(FILE_PATH_LITERAL(".dmg"))) return EXTENSION_DMG;
+  if (f.MatchesExtension(FILE_PATH_LITERAL(".pkg"))) return EXTENSION_PKG;
   return EXTENSION_OTHER;
 }
 
diff --git a/chrome/browser/safe_browsing/prefix_set.cc b/chrome/browser/safe_browsing/prefix_set.cc
index 007f8b8..21335e1 100644
--- a/chrome/browser/safe_browsing/prefix_set.cc
+++ b/chrome/browser/safe_browsing/prefix_set.cc
@@ -24,16 +24,26 @@
 // Version history:
 // Version 1: b6cb7cfe/r74487 by shess@chromium.org on 2011-02-10
 // Version 2: 2b59b0a6/r253924 by shess@chromium.org on 2014-02-27
+// Version 3: ????????/r?????? by shess@chromium.org on 2014-04-??
 
 // Version 2 layout is identical to version 1.  The sort order of |index_|
 // changed from |int32| to |uint32| to match the change of |SBPrefix|.
-static uint32 kVersion = 0x2;
+// Version 3 adds storage for full hashes.
+static uint32 kVersion = 0x3;
 
 typedef struct {
   uint32 magic;
   uint32 version;
   uint32 index_size;
   uint32 deltas_size;
+} FileHeader_v2;
+
+typedef struct {
+  uint32 magic;
+  uint32 version;
+  uint32 index_size;
+  uint32 deltas_size;
+  uint32 full_hashes_size;
 } FileHeader;
 
 // Common std::vector<> implementations add capacity by multiplying from the
@@ -84,10 +94,13 @@
 PrefixSet::PrefixSet() {
 }
 
-PrefixSet::PrefixSet(IndexVector* index, std::vector<uint16>* deltas) {
-  DCHECK(index && deltas);
+PrefixSet::PrefixSet(IndexVector* index,
+                     std::vector<uint16>* deltas,
+                     std::vector<SBFullHash>* full_hashes) {
+  DCHECK(index && deltas && full_hashes);
   index_.swap(*index);
   deltas_.swap(*deltas);
+  full_hashes_.swap(*full_hashes);
 }
 
 PrefixSet::~PrefixSet() {}
@@ -156,7 +169,9 @@
   if (!base::GetFileSize(filter_name, &size_64))
     return scoped_ptr<PrefixSet>();
   using base::MD5Digest;
-  if (size_64 < static_cast<int64>(sizeof(FileHeader) + sizeof(MD5Digest)))
+  // TODO(shess): Revert to sizeof(FileHeader) for sanity check once v2 is
+  // deprecated.
+  if (size_64 < static_cast<int64>(sizeof(FileHeader_v2) + sizeof(MD5Digest)))
     return scoped_ptr<PrefixSet>();
 
   base::ScopedFILE file(base::OpenFile(filter_name, "rb"));
@@ -168,6 +183,12 @@
   if (read != 1)
     return scoped_ptr<PrefixSet>();
 
+  // The file looks valid, start building the digest.
+  base::MD5Context context;
+  base::MD5Init(&context);
+  base::MD5Update(&context, base::StringPiece(reinterpret_cast<char*>(&header),
+                                              sizeof(header)));
+
   if (header.magic != kMagic)
     return scoped_ptr<PrefixSet>();
 
@@ -176,9 +197,36 @@
 
   // TODO(shess): Version 1 and 2 use the same file structure, with version 1
   // data using a signed sort.  For M-35, the data is re-sorted before return.
-  // After M-35, just drop v1 support. <http://crbug.com/346405>
-  if (header.version != kVersion && header.version != 1)
+  // After M-36, just drop v1 support. <http://crbug.com/346405>
+  // TODO(shess): <http://crbug.com/368044> for removing v2 support.
+  size_t header_size = sizeof(header);
+  if (header.version == 2 || header.version == 1) {
+    // Rewind the file and restart building the digest with the old header
+    // structure.
+    FileHeader_v2 v2_header;
+    if (0 != fseek(file.get(), 0, SEEK_SET))
+      return scoped_ptr<PrefixSet>();
+
+    size_t read = fread(&v2_header, sizeof(v2_header), 1, file.get());
+    if (read != 1)
+      return scoped_ptr<PrefixSet>();
+
+    base::MD5Init(&context);
+    base::MD5Update(&context,
+                    base::StringPiece(reinterpret_cast<char*>(&v2_header),
+                                      sizeof(v2_header)));
+
+    // The current header is a superset of the old header, fill it in with the
+    // information read.
+    header.magic = v2_header.magic;
+    header.version = v2_header.version;
+    header.index_size = v2_header.index_size;
+    header.deltas_size = v2_header.deltas_size;
+    header.full_hashes_size = 0;
+    header_size = sizeof(v2_header);
+  } else if (header.version != kVersion) {
     return scoped_ptr<PrefixSet>();
+  }
 
   IndexVector index;
   const size_t index_bytes = sizeof(index[0]) * header.index_size;
@@ -186,18 +234,16 @@
   std::vector<uint16> deltas;
   const size_t deltas_bytes = sizeof(deltas[0]) * header.deltas_size;
 
+  std::vector<SBFullHash> full_hashes;
+  const size_t full_hashes_bytes =
+      sizeof(full_hashes[0]) * header.full_hashes_size;
+
   // Check for bogus sizes before allocating any space.
-  const size_t expected_bytes =
-      sizeof(header) + index_bytes + deltas_bytes + sizeof(MD5Digest);
+  const size_t expected_bytes = header_size +
+      index_bytes + deltas_bytes + full_hashes_bytes + sizeof(MD5Digest);
   if (static_cast<int64>(expected_bytes) != size_64)
     return scoped_ptr<PrefixSet>();
 
-  // The file looks valid, start building the digest.
-  base::MD5Context context;
-  base::MD5Init(&context);
-  base::MD5Update(&context, base::StringPiece(reinterpret_cast<char*>(&header),
-                                              sizeof(header)));
-
   // Read the index vector.  Herb Sutter indicates that vectors are
   // guaranteed to be contiuguous, so reading to where element 0 lives
   // is valid.
@@ -222,6 +268,19 @@
                                       deltas_bytes));
   }
 
+  // Read vector of full hashes.
+  if (header.full_hashes_size) {
+    full_hashes.resize(header.full_hashes_size);
+    read = fread(&(full_hashes[0]), sizeof(full_hashes[0]), full_hashes.size(),
+                 file.get());
+    if (read != full_hashes.size())
+      return scoped_ptr<PrefixSet>();
+    base::MD5Update(&context,
+                    base::StringPiece(
+                        reinterpret_cast<char*>(&(full_hashes[0])),
+                        full_hashes_bytes));
+  }
+
   base::MD5Digest calculated_digest;
   base::MD5Final(&calculated_digest, &context);
 
@@ -236,13 +295,15 @@
   // For version 1, fetch the prefixes and re-sort.
   if (header.version == 1) {
     std::vector<SBPrefix> prefixes;
-    PrefixSet(&index, &deltas).GetPrefixes(&prefixes);
+    PrefixSet(&index, &deltas, &full_hashes).GetPrefixes(&prefixes);
     std::sort(prefixes.begin(), prefixes.end());
+
+    // v1 cannot have full hashes, so no need to propagate a copy here.
     return PrefixSetBuilder(prefixes).GetPrefixSetNoHashes().Pass();
   }
 
-  // Steals contents of |index| and |deltas| via swap().
-  return scoped_ptr<PrefixSet>(new PrefixSet(&index, &deltas));
+  // Steals vector contents using swap().
+  return scoped_ptr<PrefixSet>(new PrefixSet(&index, &deltas, &full_hashes));
 }
 
 bool PrefixSet::WriteFile(const base::FilePath& filter_name) const {
@@ -251,10 +312,12 @@
   header.version = kVersion;
   header.index_size = static_cast<uint32>(index_.size());
   header.deltas_size = static_cast<uint32>(deltas_.size());
+  header.full_hashes_size = static_cast<uint32>(full_hashes_.size());
 
   // Sanity check that the 32-bit values never mess things up.
   if (static_cast<size_t>(header.index_size) != index_.size() ||
-      static_cast<size_t>(header.deltas_size) != deltas_.size()) {
+      static_cast<size_t>(header.deltas_size) != deltas_.size() ||
+      static_cast<size_t>(header.full_hashes_size) != full_hashes_.size()) {
     NOTREACHED();
     return false;
   }
@@ -300,6 +363,19 @@
                         deltas_bytes));
   }
 
+  if (full_hashes_.size()) {
+    const size_t elt_size = sizeof(full_hashes_[0]);
+    const size_t elts = full_hashes_.size();
+    const size_t full_hashes_bytes = elt_size * elts;
+    written = fwrite(&(full_hashes_[0]), elt_size, elts, file.get());
+    if (written != elts)
+      return false;
+    base::MD5Update(&context,
+                    base::StringPiece(
+                        reinterpret_cast<const char*>(&(full_hashes_[0])),
+                        full_hashes_bytes));
+  }
+
   base::MD5Digest digest;
   base::MD5Final(&digest, &context);
   written = fwrite(&digest, sizeof(digest), 1, file.get());
diff --git a/chrome/browser/safe_browsing/prefix_set.h b/chrome/browser/safe_browsing/prefix_set.h
index 9a4bbb0..a71ce3b 100644
--- a/chrome/browser/safe_browsing/prefix_set.h
+++ b/chrome/browser/safe_browsing/prefix_set.h
@@ -83,12 +83,15 @@
   FRIEND_TEST_ALL_PREFIXES(PrefixSetTest, FullHashBuild);
   FRIEND_TEST_ALL_PREFIXES(PrefixSetTest, IntMinMax);
   FRIEND_TEST_ALL_PREFIXES(PrefixSetTest, OneElement);
+  FRIEND_TEST_ALL_PREFIXES(PrefixSetTest, ReadWrite);
   FRIEND_TEST_ALL_PREFIXES(PrefixSetTest, ReadWriteSigned);
+  FRIEND_TEST_ALL_PREFIXES(PrefixSetTest, Version3);
 
   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingStoreFileTest, BasicStore);
   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingStoreFileTest, DeleteChunks);
   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingStoreFileTest, DetectsCorruption);
   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingStoreFileTest, Empty);
+  FRIEND_TEST_ALL_PREFIXES(SafeBrowsingStoreFileTest, KnockoutPrefixVolunteers);
   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingStoreFileTest, PrefixMinMax);
   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingStoreFileTest, SubKnockout);
   FRIEND_TEST_ALL_PREFIXES(SafeBrowsingStoreFileTest, Version7);
@@ -120,9 +123,10 @@
   // Used by |PrefixSetBuilder|.
   PrefixSet();
 
-  // Helper for |LoadFile()|.  Steals the contents of |index| and
-  // |deltas| using |swap()|.
-  PrefixSet(IndexVector* index, std::vector<uint16>* deltas);
+  // Helper for |LoadFile()|.  Steals vector contents using |swap()|.
+  PrefixSet(IndexVector* index,
+            std::vector<uint16>* deltas,
+            std::vector<SBFullHash>* full_hashes);
 
   // Top-level index of prefix to offset in |deltas_|.  Each pair
   // indicates a base prefix and where the deltas from that prefix
diff --git a/chrome/browser/safe_browsing/prefix_set_unittest.cc b/chrome/browser/safe_browsing/prefix_set_unittest.cc
index 2520282..e537ad9 100644
--- a/chrome/browser/safe_browsing/prefix_set_unittest.cc
+++ b/chrome/browser/safe_browsing/prefix_set_unittest.cc
@@ -37,7 +37,8 @@
   static const size_t kVersionOffset = 1 * sizeof(uint32);
   static const size_t kIndexSizeOffset = 2 * sizeof(uint32);
   static const size_t kDeltasSizeOffset = 3 * sizeof(uint32);
-  static const size_t kPayloadOffset = 4 * sizeof(uint32);
+  static const size_t kFullHashesSizeOffset = 4 * sizeof(uint32);
+  static const size_t kPayloadOffset = 5 * sizeof(uint32);
 
   // Generate a set of random prefixes to share between tests.  For
   // most tests this generation was a large fraction of the test time.
@@ -398,6 +399,38 @@
     ASSERT_TRUE(prefix_set.get());
     CheckPrefixes(*prefix_set, prefixes);
   }
+
+  // Test that full hashes are persisted.
+  {
+    std::vector<SBFullHash> hashes;
+    hashes.push_back(SBFullHashForString("one"));
+    hashes.push_back(SBFullHashForString("two"));
+    hashes.push_back(SBFullHashForString("three"));
+
+    std::vector<SBPrefix> prefixes(shared_prefixes_);
+
+    // Remove any collisions from the prefixes.
+    for (size_t i = 0; i < hashes.size(); ++i) {
+      std::vector<SBPrefix>::iterator iter =
+          std::lower_bound(prefixes.begin(), prefixes.end(), hashes[i].prefix);
+      if (iter != prefixes.end() && *iter == hashes[i].prefix)
+        prefixes.erase(iter);
+    }
+
+    PrefixSetBuilder builder(prefixes);
+    ASSERT_TRUE(builder.GetPrefixSet(hashes)->WriteFile(filename));
+
+    scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename);
+    ASSERT_TRUE(prefix_set.get());
+    CheckPrefixes(*prefix_set, prefixes);
+
+    EXPECT_TRUE(prefix_set->Exists(hashes[0]));
+    EXPECT_TRUE(prefix_set->Exists(hashes[1]));
+    EXPECT_TRUE(prefix_set->Exists(hashes[2]));
+    EXPECT_FALSE(prefix_set->PrefixExists(hashes[0].prefix));
+    EXPECT_FALSE(prefix_set->PrefixExists(hashes[1].prefix));
+    EXPECT_FALSE(prefix_set->PrefixExists(hashes[2].prefix));
+  }
 }
 
 // Check that |CleanChecksum()| makes an acceptable checksum.
@@ -465,6 +498,17 @@
   ASSERT_FALSE(prefix_set.get());
 }
 
+// Bad |full_hashes_| size is caught by the sanity check.
+TEST_F(PrefixSetTest, CorruptionFullHashesSize) {
+  base::FilePath filename;
+  ASSERT_TRUE(GetPrefixSetFile(&filename));
+
+  ASSERT_NO_FATAL_FAILURE(
+      ModifyAndCleanChecksum(filename, kFullHashesSizeOffset, 1));
+  scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(filename);
+  ASSERT_FALSE(prefix_set.get());
+}
+
 // Test that the digest catches corruption in the middle of the file
 // (in the payload between the header and the digest).
 TEST_F(PrefixSetTest, CorruptionPayload) {
@@ -667,4 +711,32 @@
 }
 #endif
 
+// Test that a golden v3 file can be read by the current code.  All platforms
+// generating v3 files are little-endian, so there is no point to testing this
+// transition if/when a big-endian port is added.
+#if defined(ARCH_CPU_LITTLE_ENDIAN)
+TEST_F(PrefixSetTest, Version3) {
+  std::vector<SBPrefix> ref_prefixes;
+  ASSERT_TRUE(ReadReferencePrefixes(&ref_prefixes));
+
+  const char kBasename[] = "PrefixSetVersion3";
+  base::FilePath golden_path;
+  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &golden_path));
+  golden_path = golden_path.AppendASCII("SafeBrowsing");
+  golden_path = golden_path.AppendASCII(kBasename);
+
+  scoped_ptr<PrefixSet> prefix_set = PrefixSet::LoadFile(golden_path);
+  ASSERT_TRUE(prefix_set.get());
+  CheckPrefixes(*prefix_set, ref_prefixes);
+
+  const SBFullHash kHash1 = SBFullHashForString("www.evil.com/malware.html");
+  const SBFullHash kHash2 = SBFullHashForString("www.evil.com/phishing.html");
+
+  EXPECT_TRUE(prefix_set->Exists(kHash1));
+  EXPECT_TRUE(prefix_set->Exists(kHash2));
+  EXPECT_FALSE(prefix_set->PrefixExists(kHash1.prefix));
+  EXPECT_FALSE(prefix_set->PrefixExists(kHash2.prefix));
+}
+#endif
+
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
index ffcf0a7..c5b4c44 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -265,7 +265,7 @@
 
 bool SafeBrowsingBlockingPage::CanShowMalwareDetailsOption() {
   return (!web_contents_->GetBrowserContext()->IsOffTheRecord() &&
-          web_contents_->GetURL().SchemeIs(content::kHttpScheme));
+          web_contents_->GetURL().SchemeIs(url::kHttpScheme));
 }
 
 SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() {
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
index a9f1f38..d0e3a34 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -34,7 +34,6 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/test_browser_thread.h"
 #include "content/public/test/test_utils.h"
 
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
index 228873b..da5a3ca 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
@@ -17,14 +17,12 @@
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/web_contents_tester.h"
 
 using content::InterstitialPage;
 using content::NavigationEntry;
 using content::WebContents;
 using content::WebContentsTester;
-using content::WebContentsView;
 
 static const char* kGoogleURL = "http://www.google.com/";
 static const char* kGoodURL = "http://www.goodguys.com/";
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.cc b/chrome/browser/safe_browsing/safe_browsing_database.cc
index e1df581..d77433c 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_database.cc
@@ -855,17 +855,12 @@
       store->WriteAddPrefix(encoded_chunk_id, prefix);
     }
   } else {
-    // Prefixes and hashes.
-    const base::Time receive_time = base::Time::Now();
+    // Full hashes only.
     for (int i = 0; i < count; ++i) {
       const SBFullHash full_hash = entry->FullHashAt(i);
-      const SBPrefix prefix = full_hash.prefix;
-
-      STATS_COUNTER("SB.PrefixAdd", 1);
-      store->WriteAddPrefix(encoded_chunk_id, prefix);
 
       STATS_COUNTER("SB.PrefixAddFull", 1);
-      store->WriteAddHash(encoded_chunk_id, receive_time, full_hash);
+      store->WriteAddHash(encoded_chunk_id, full_hash);
     }
   }
 }
@@ -930,15 +925,12 @@
       store->WriteSubPrefix(encoded_chunk_id, add_chunk_id, prefix);
     }
   } else {
-    // Prefixes and hashes.
+    // Full hashes only.
     for (int i = 0; i < count; ++i) {
       const SBFullHash full_hash = entry->FullHashAt(i);
       const int add_chunk_id =
           EncodeChunkId(entry->ChunkIdAtPrefix(i), list_id);
 
-      STATS_COUNTER("SB.PrefixSub", 1);
-      store->WriteSubPrefix(encoded_chunk_id, add_chunk_id, full_hash.prefix);
-
       STATS_COUNTER("SB.PrefixSubFull", 1);
       store->WriteSubHash(encoded_chunk_id, add_chunk_id, full_hash);
     }
diff --git a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
index 0f433eb..559987c 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
@@ -41,6 +41,19 @@
   return hash;
 }
 
+// Add a host-level entry.
+void InsertAddChunkHostPrefix(SBChunk* chunk,
+                              int chunk_number,
+                              const std::string& host_name) {
+  chunk->chunk_number = chunk_number;
+  chunk->is_add = true;
+  SBChunkHost host;
+  host.host = SBPrefixForString(host_name);
+  host.entry = SBEntry::Create(SBEntry::ADD_PREFIX, 0);
+  host.entry->set_chunk_id(chunk->chunk_number);
+  chunk->hosts.push_back(host);
+}
+
 // Same as InsertAddChunkHostPrefixUrl, but with pre-computed
 // prefix values.
 void InsertAddChunkHostPrefixValue(SBChunk* chunk,
@@ -1860,3 +1873,85 @@
   EXPECT_TRUE(database_->ContainsMalwareIP("192.1.255.255"));
   EXPECT_FALSE(database_->ContainsMalwareIP("192.2.0.0"));
 }
+
+TEST_F(SafeBrowsingDatabaseTest, ContainsBrowseURL) {
+  std::vector<SBListChunkRanges> lists;
+  EXPECT_TRUE(database_->UpdateStarted(&lists));
+
+  // Add a host-level hit.
+  {
+    SBChunkList chunks;
+    SBChunk chunk;
+    InsertAddChunkHostPrefix(&chunk, 1, "www.evil.com/");
+    chunks.push_back(chunk);
+    database_->InsertChunks(safe_browsing_util::kMalwareList, chunks);
+  }
+
+  // Add a specific fullhash.
+  static const char kWhateverMalware[] = "www.whatever.com/malware.html";
+  {
+    SBChunkList chunks;
+    SBChunk chunk;
+    InsertAddChunkHostFullHashes(&chunk, 2, "www.whatever.com/",
+                                 kWhateverMalware);
+    chunks.push_back(chunk);
+    database_->InsertChunks(safe_browsing_util::kMalwareList, chunks);
+  }
+
+  // Add a fullhash which has a prefix collision for a known url.
+  static const char kExampleFine[] = "www.example.com/fine.html";
+  static const char kExampleCollision[] =
+      "www.example.com/3123364814/malware.htm";
+  ASSERT_EQ(SBPrefixForString(kExampleFine),
+            SBPrefixForString(kExampleCollision));
+  {
+    SBChunkList chunks;
+    SBChunk chunk;
+    InsertAddChunkHostFullHashes(&chunk, 3, "www.example.com/",
+                                 kExampleCollision);
+    chunks.push_back(chunk);
+    database_->InsertChunks(safe_browsing_util::kMalwareList, chunks);
+  }
+
+  database_->UpdateFinished(true);
+
+  const Time now = Time::Now();
+  std::vector<SBFullHashResult> cached_hashes;
+  std::vector<SBPrefix> prefix_hits;
+
+  // Anything will hit the host prefix.
+  EXPECT_TRUE(database_->ContainsBrowseUrl(
+      GURL("http://www.evil.com/malware.html"),
+      &prefix_hits, &cached_hashes, now));
+  ASSERT_EQ(1U, prefix_hits.size());
+  EXPECT_EQ(SBPrefixForString("www.evil.com/"), prefix_hits[0]);
+  EXPECT_TRUE(cached_hashes.empty());
+
+  // Hit the specific URL prefix.
+  EXPECT_TRUE(database_->ContainsBrowseUrl(
+      GURL(std::string("http://") + kWhateverMalware),
+      &prefix_hits, &cached_hashes, now));
+  ASSERT_EQ(1U, prefix_hits.size());
+  EXPECT_EQ(SBPrefixForString(kWhateverMalware), prefix_hits[0]);
+  EXPECT_TRUE(cached_hashes.empty());
+
+  // Other URLs at that host are fine.
+  EXPECT_FALSE(database_->ContainsBrowseUrl(
+      GURL("http://www.whatever.com/fine.html"),
+      &prefix_hits, &cached_hashes, now));
+  EXPECT_TRUE(prefix_hits.empty());
+  EXPECT_TRUE(cached_hashes.empty());
+
+  // Hit the specific URL full hash.
+  EXPECT_TRUE(database_->ContainsBrowseUrl(
+      GURL(std::string("http://") + kExampleCollision),
+      &prefix_hits, &cached_hashes, now));
+  ASSERT_EQ(1U, prefix_hits.size());
+  EXPECT_EQ(SBPrefixForString(kExampleCollision), prefix_hits[0]);
+  EXPECT_TRUE(cached_hashes.empty());
+
+  // This prefix collides, but no full hash match.
+  EXPECT_FALSE(database_->ContainsBrowseUrl(
+      GURL(std::string("http://") + kExampleFine),
+      &prefix_hits, &cached_hashes, now));
+}
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
index 3bbea4d..ab6d68d 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -39,7 +39,6 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "net/cookies/cookie_store.h"
 #include "sql/connection.h"
 #include "sql/statement.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_store.cc b/chrome/browser/safe_browsing/safe_browsing_store.cc
index e4c15e7..b0f6a2a 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 
 #include "base/logging.h"
+#include "base/metrics/histogram.h"
 
 namespace {
 
@@ -88,6 +89,48 @@
   items->erase(end_iter, items->end());
 }
 
+// Remove prefixes which are in the same chunk as their fullhash.  This was a
+// mistake in earlier implementations.
+template <typename HashesT, typename PrefixesT>
+size_t KnockoutPrefixVolunteers(const HashesT& full_hashes,
+                                PrefixesT* prefixes) {
+  typename PrefixesT::iterator prefixes_process = prefixes->begin();
+  typename PrefixesT::iterator prefixes_out = prefixes->begin();
+  typename HashesT::const_iterator hashes_process = full_hashes.begin();
+
+  size_t skipped_count = 0;
+
+  while (hashes_process != full_hashes.end()) {
+    // Scan prefixes forward until an item is not less than the current hash.
+    while (prefixes_process != prefixes->end() &&
+           SBAddPrefixLess(*prefixes_process, *hashes_process)) {
+      if (prefixes_process != prefixes_out) {
+        *prefixes_out = *prefixes_process;
+      }
+      prefixes_out++;
+      prefixes_process++;
+    }
+
+    // If the current hash is also not less than the prefix, that implies they
+    // are equal.  Skip the prefix.
+    if (prefixes_process != prefixes->end() &&
+        !SBAddPrefixLess(*hashes_process, *prefixes_process)) {
+      skipped_count++;
+      prefixes_process++;
+    }
+
+    hashes_process++;
+  }
+
+  // If any prefixes were skipped, copy over the tail and erase the excess.
+  if (prefixes_process != prefixes_out) {
+    prefixes_out = std::copy(prefixes_process, prefixes->end(), prefixes_out);
+    prefixes->erase(prefixes_out, prefixes->end());
+  }
+
+  return skipped_count;
+}
+
 }  // namespace
 
 void SBProcessSubs(SBAddPrefixes* add_prefixes,
@@ -111,6 +154,17 @@
   DCHECK(sorted(sub_full_hashes->begin(), sub_full_hashes->end(),
                 SBAddPrefixHashLess<SBSubFullHash,SBSubFullHash>));
 
+  // Earlier database code added prefixes when it saw fullhashes.  The protocol
+  // should never send a chunk of mixed prefixes and fullhashes, the following
+  // removes any such cases which are seen.
+  // TODO(shess): Remove this code once most databases have been processed.
+  // Chunk churn should clean up anyone left over.  This only takes a few ms to
+  // run through my current database, so it doesn't seem worthwhile to do much
+  // more than that.
+  size_t skipped = KnockoutPrefixVolunteers(*add_full_hashes, add_prefixes);
+  skipped += KnockoutPrefixVolunteers(*sub_full_hashes, sub_prefixes);
+  UMA_HISTOGRAM_COUNTS("SB2.VolunteerPrefixesRemoved", skipped);
+
   // Factor out the prefix subs.
   KnockoutSubs(sub_prefixes, add_prefixes,
                SBAddPrefixLess<SBAddPrefix,SBSubPrefix>,
diff --git a/chrome/browser/safe_browsing/safe_browsing_store.h b/chrome/browser/safe_browsing/safe_browsing_store.h
index 0abe90b..2cbd30e 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store.h
+++ b/chrome/browser/safe_browsing/safe_browsing_store.h
@@ -74,21 +74,15 @@
 
 struct SBAddFullHash {
   int32 chunk_id;
-  int32 received;  // TODO(shess): Deprecate and remove.
+  // Received field is not used anymore, but is kept for DB compatability.
+  // TODO(shess): Deprecate and remove.
+  int32 deprecated_received;
   SBFullHash full_hash;
 
-  SBAddFullHash(int32 id, base::Time r, const SBFullHash& h)
-      : chunk_id(id),
-        received(static_cast<int32>(r.ToTimeT())),
-        full_hash(h) {
-  }
+  SBAddFullHash(int32 id, const SBFullHash& h)
+      : chunk_id(id), deprecated_received(), full_hash(h) {}
 
-  // Provided for ReadAddHashes() implementations, which already have
-  // an int32 for the time.
-  SBAddFullHash(int32 id, int32 r, const SBFullHash& h)
-      : chunk_id(id), received(r), full_hash(h) {}
-
-  SBAddFullHash() : chunk_id(), received(), full_hash() {}
+  SBAddFullHash() : chunk_id(), deprecated_received(), full_hash() {}
 
   int32 GetAddChunkId() const { return chunk_id; }
   SBPrefix GetAddPrefix() const { return full_hash.prefix; }
@@ -184,7 +178,6 @@
 
   virtual bool WriteAddPrefix(int32 chunk_id, SBPrefix prefix) = 0;
   virtual bool WriteAddHash(int32 chunk_id,
-                            base::Time receive_time,
                             const SBFullHash& full_hash) = 0;
   virtual bool WriteSubPrefix(int32 chunk_id,
                               int32 add_chunk_id, SBPrefix prefix) = 0;
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file.cc b/chrome/browser/safe_browsing/safe_browsing_store_file.cc
index 0c8b2cd..01a5dc7 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_file.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store_file.cc
@@ -765,9 +765,8 @@
 }
 
 bool SafeBrowsingStoreFile::WriteAddHash(int32 chunk_id,
-                                         base::Time receive_time,
                                          const SBFullHash& full_hash) {
-  add_hashes_.push_back(SBAddFullHash(chunk_id, receive_time, full_hash));
+  add_hashes_.push_back(SBAddFullHash(chunk_id, full_hash));
   return true;
 }
 
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file.h b/chrome/browser/safe_browsing/safe_browsing_store_file.h
index f54e39b..a890559 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_file.h
+++ b/chrome/browser/safe_browsing/safe_browsing_store_file.h
@@ -143,7 +143,6 @@
 
   virtual bool WriteAddPrefix(int32 chunk_id, SBPrefix prefix) OVERRIDE;
   virtual bool WriteAddHash(int32 chunk_id,
-                            base::Time receive_time,
                             const SBFullHash& full_hash) OVERRIDE;
   virtual bool WriteSubPrefix(int32 chunk_id,
                               int32 add_chunk_id, SBPrefix prefix) OVERRIDE;
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
index 55437ee..b028446 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
@@ -67,7 +67,7 @@
   }
 
   // Populate the store with some testing data.
-  void PopulateStore(const base::Time& now) {
+  void PopulateStore() {
     ASSERT_TRUE(store_->BeginUpdate());
 
     EXPECT_TRUE(store_->BeginChunk());
@@ -87,7 +87,7 @@
     EXPECT_TRUE(store_->BeginChunk());
     store_->SetAddChunk(kAddChunk2);
     EXPECT_TRUE(store_->CheckAddChunk(kAddChunk2));
-    EXPECT_TRUE(store_->WriteAddHash(kAddChunk2, now, kHash4));
+    EXPECT_TRUE(store_->WriteAddHash(kAddChunk2, kHash4));
     EXPECT_TRUE(store_->FinishChunk());
 
     // Chunk numbers shouldn't leak over.
@@ -151,8 +151,7 @@
 // Write some prefix and hash data to the store, add more data in another
 // transaction, then verify that the union of all the data is present.
 TEST_F(SafeBrowsingStoreFileTest, BasicStore) {
-  const base::Time now = base::Time::Now();
-  PopulateStore(now);
+  PopulateStore();
 
   ASSERT_TRUE(store_->BeginUpdate());
 
@@ -189,16 +188,13 @@
 
     ASSERT_EQ(1U, add_full_hashes_result.size());
     EXPECT_EQ(kAddChunk2, add_full_hashes_result[0].chunk_id);
-    // EXPECT_TRUE(add_full_hashes_result[0].received == now)?
-    EXPECT_EQ(now.ToTimeT(), add_full_hashes_result[0].received);
     EXPECT_TRUE(SBFullHashEqual(kHash4, add_full_hashes_result[0].full_hash));
   }
 }
 
 // Verify that the min and max prefixes are stored and operated on.
 TEST_F(SafeBrowsingStoreFileTest, PrefixMinMax) {
-  const base::Time now = base::Time::Now();
-  PopulateStore(now);
+  PopulateStore();
 
   ASSERT_TRUE(store_->BeginUpdate());
 
@@ -247,8 +243,6 @@
 TEST_F(SafeBrowsingStoreFileTest, SubKnockout) {
   ASSERT_TRUE(store_->BeginUpdate());
 
-  const base::Time now = base::Time::Now();
-
   EXPECT_TRUE(store_->BeginChunk());
   store_->SetAddChunk(kAddChunk1);
   EXPECT_TRUE(store_->WriteAddPrefix(kAddChunk1, kHash1.prefix));
@@ -257,7 +251,7 @@
 
   EXPECT_TRUE(store_->BeginChunk());
   store_->SetAddChunk(kAddChunk2);
-  EXPECT_TRUE(store_->WriteAddHash(kAddChunk2, now, kHash4));
+  EXPECT_TRUE(store_->WriteAddHash(kAddChunk2, kHash4));
   EXPECT_TRUE(store_->FinishChunk());
 
   EXPECT_TRUE(store_->BeginChunk());
@@ -279,7 +273,6 @@
 
     ASSERT_EQ(1U, add_full_hashes_result.size());
     EXPECT_EQ(kAddChunk2, add_full_hashes_result[0].chunk_id);
-    EXPECT_EQ(now.ToTimeT(), add_full_hashes_result[0].received);
     EXPECT_TRUE(SBFullHashEqual(kHash4, add_full_hashes_result[0].full_hash));
   }
 
@@ -303,7 +296,6 @@
 
     ASSERT_EQ(1U, add_full_hashes_result.size());
     EXPECT_EQ(kAddChunk2, add_full_hashes_result[0].chunk_id);
-    EXPECT_EQ(now.ToTimeT(), add_full_hashes_result[0].received);
     EXPECT_TRUE(SBFullHashEqual(kHash4, add_full_hashes_result[0].full_hash));
   }
 
@@ -328,7 +320,6 @@
 
     ASSERT_EQ(1U, add_full_hashes_result.size());
     EXPECT_EQ(kAddChunk2, add_full_hashes_result[0].chunk_id);
-    EXPECT_EQ(now.ToTimeT(), add_full_hashes_result[0].received);
     EXPECT_TRUE(SBFullHashEqual(kHash4, add_full_hashes_result[0].full_hash));
   }
 }
@@ -337,8 +328,6 @@
 TEST_F(SafeBrowsingStoreFileTest, DeleteChunks) {
   ASSERT_TRUE(store_->BeginUpdate());
 
-  const base::Time now = base::Time::Now();
-
   // A prefix chunk which will be deleted.
   EXPECT_FALSE(store_->CheckAddChunk(kAddChunk1));
   store_->SetAddChunk(kAddChunk1);
@@ -358,7 +347,7 @@
   EXPECT_FALSE(store_->CheckAddChunk(kAddChunk3));
   store_->SetAddChunk(kAddChunk3);
   EXPECT_TRUE(store_->BeginChunk());
-  EXPECT_TRUE(store_->WriteAddHash(kAddChunk3, now, kHash6));
+  EXPECT_TRUE(store_->WriteAddHash(kAddChunk3, kHash6));
   EXPECT_TRUE(store_->FinishChunk());
 
   // A sub chunk to delete.
@@ -397,7 +386,6 @@
 
     ASSERT_EQ(1U, add_full_hashes_result.size());
     EXPECT_EQ(kAddChunk3, add_full_hashes_result[0].chunk_id);
-    EXPECT_EQ(now.ToTimeT(), add_full_hashes_result[0].received);
     EXPECT_TRUE(SBFullHashEqual(kHash6, add_full_hashes_result[0].full_hash));
   }
 
@@ -452,7 +440,7 @@
   EXPECT_TRUE(store_->Delete());
 
   // Create a store file.
-  PopulateStore(base::Time::Now());
+  PopulateStore();
 
   EXPECT_TRUE(base::PathExists(filename_));
   EXPECT_TRUE(store_->Delete());
@@ -487,7 +475,7 @@
 // Test basic corruption-handling.
 TEST_F(SafeBrowsingStoreFileTest, DetectsCorruption) {
   // Load a store with some data.
-  PopulateStore(base::Time::Now());
+  PopulateStore();
 
   // Can successfully open and read the store.
   {
@@ -549,7 +537,7 @@
 
   // A store with some data is valid.
   EXPECT_FALSE(base::PathExists(filename_));
-  PopulateStore(base::Time::Now());
+  PopulateStore();
   EXPECT_TRUE(base::PathExists(filename_));
   ASSERT_TRUE(store_->BeginUpdate());
   EXPECT_FALSE(corruption_detected_);
@@ -560,7 +548,7 @@
 
 // Corrupt the header.
 TEST_F(SafeBrowsingStoreFileTest, CheckValidityHeader) {
-  PopulateStore(base::Time::Now());
+  PopulateStore();
   EXPECT_TRUE(base::PathExists(filename_));
 
   // 37 is the most random prime number.  It's also past the initial header
@@ -578,7 +566,7 @@
 
 // Corrupt the prefix payload.
 TEST_F(SafeBrowsingStoreFileTest, CheckValidityPayload) {
-  PopulateStore(base::Time::Now());
+  PopulateStore();
   EXPECT_TRUE(base::PathExists(filename_));
 
   // 137 is the second most random prime number.  It's also past the header and
@@ -600,7 +588,7 @@
 
 // Corrupt the checksum.
 TEST_F(SafeBrowsingStoreFileTest, CheckValidityChecksum) {
-  PopulateStore(base::Time::Now());
+  PopulateStore();
   EXPECT_TRUE(base::PathExists(filename_));
 
   // An offset from the end of the file which is in the checksum.
@@ -621,8 +609,6 @@
 TEST_F(SafeBrowsingStoreFileTest, GetAddPrefixesAndHashes) {
   ASSERT_TRUE(store_->BeginUpdate());
 
-  const base::Time now = base::Time::Now();
-
   EXPECT_TRUE(store_->BeginChunk());
   store_->SetAddChunk(kAddChunk1);
   EXPECT_TRUE(store_->CheckAddChunk(kAddChunk1));
@@ -633,7 +619,7 @@
   EXPECT_TRUE(store_->BeginChunk());
   store_->SetAddChunk(kAddChunk2);
   EXPECT_TRUE(store_->CheckAddChunk(kAddChunk2));
-  EXPECT_TRUE(store_->WriteAddHash(kAddChunk2, now, kHash4));
+  EXPECT_TRUE(store_->WriteAddHash(kAddChunk2, kHash4));
   EXPECT_TRUE(store_->FinishChunk());
 
   store_->SetSubChunk(kSubChunk1);
@@ -896,4 +882,77 @@
 }
 #endif
 
+// Test that when the v8 golden file is updated, the add prefix injected from
+// the full hash is removed.  All platforms generating v8 files are
+// little-endian, so there is no point to testing this transition if/when a
+// big-endian port is added.
+#if defined(ARCH_CPU_LITTLE_ENDIAN)
+TEST_F(SafeBrowsingStoreFileTest, KnockoutPrefixVolunteers) {
+  store_.reset();
+
+  // Copy the golden file into temporary storage.  The golden file contains:
+  // - Add chunk kAddChunk1 containing kHash1.prefix and kHash2.
+  // - Sub chunk kSubChunk1 containing kHash3.
+  const char kBasename[] = "FileStoreVersion8";
+  base::FilePath golden_path;
+  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &golden_path));
+  golden_path = golden_path.AppendASCII("SafeBrowsing");
+  golden_path = golden_path.AppendASCII(kBasename);
+  ASSERT_TRUE(base::CopyFile(golden_path, filename_));
+
+  // Reset the store to make sure it re-reads the file.
+  store_.reset(new SafeBrowsingStoreFile());
+  store_->Init(filename_,
+               base::Bind(&SafeBrowsingStoreFileTest::OnCorruptionDetected,
+                          base::Unretained(this)));
+
+  // Check that the expected prefixes and hashes are in place.
+  {
+    SBAddPrefixes add_prefixes;
+    EXPECT_TRUE(store_->GetAddPrefixes(&add_prefixes));
+    ASSERT_EQ(2U, add_prefixes.size());
+    EXPECT_EQ(kAddChunk1, add_prefixes[0].chunk_id);
+    EXPECT_EQ(kHash1.prefix, add_prefixes[0].prefix);
+    EXPECT_EQ(kAddChunk1, add_prefixes[1].chunk_id);
+    EXPECT_EQ(kHash2.prefix, add_prefixes[1].prefix);
+
+    std::vector<SBAddFullHash> add_hashes;
+    EXPECT_TRUE(store_->GetAddFullHashes(&add_hashes));
+    ASSERT_EQ(1U, add_hashes.size());
+    EXPECT_EQ(kAddChunk1, add_hashes[0].chunk_id);
+    EXPECT_TRUE(SBFullHashEqual(kHash2, add_hashes[0].full_hash));
+  }
+
+  // Update the store.
+  {
+    EXPECT_TRUE(store_->BeginUpdate());
+
+    safe_browsing::PrefixSetBuilder builder;
+    std::vector<SBAddFullHash> add_full_hashes_result;
+    ASSERT_TRUE(store_->FinishUpdate(&builder, &add_full_hashes_result));
+  }
+
+  // Reset the store to make sure it re-reads the file.
+  store_.reset(new SafeBrowsingStoreFile());
+  store_->Init(filename_,
+               base::Bind(&SafeBrowsingStoreFileTest::OnCorruptionDetected,
+                          base::Unretained(this)));
+
+  // |kHash2.prefix| should have dropped.
+  {
+    SBAddPrefixes add_prefixes;
+    EXPECT_TRUE(store_->GetAddPrefixes(&add_prefixes));
+    ASSERT_EQ(1U, add_prefixes.size());
+    EXPECT_EQ(kAddChunk1, add_prefixes[0].chunk_id);
+    EXPECT_EQ(kHash1.prefix, add_prefixes[0].prefix);
+
+    std::vector<SBAddFullHash> add_hashes;
+    EXPECT_TRUE(store_->GetAddFullHashes(&add_hashes));
+    ASSERT_EQ(1U, add_hashes.size());
+    EXPECT_EQ(kAddChunk1, add_hashes[0].chunk_id);
+    EXPECT_TRUE(SBFullHashEqual(kHash2, add_hashes[0].full_hash));
+  }
+}
+#endif
+
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_store_unittest.cc
index c1214e7..2c336ab 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store_unittest.cc
@@ -81,29 +81,27 @@
   onetwo.full_hash[sizeof(SBPrefix)] = 2;
   two.prefix = 2;
 
-  const base::Time now = base::Time::Now();
-
   // prefix dominates.
-  EXPECT_TRUE(SBAddPrefixHashLess(SBAddFullHash(11, now, one),
-                                  SBAddFullHash(10, now, two)));
-  EXPECT_FALSE(SBAddPrefixHashLess(SBAddFullHash(11, now, two),
-                                   SBAddFullHash(10, now, one)));
+  EXPECT_TRUE(SBAddPrefixHashLess(SBAddFullHash(11, one),
+                                  SBAddFullHash(10, two)));
+  EXPECT_FALSE(SBAddPrefixHashLess(SBAddFullHash(11, two),
+                                   SBAddFullHash(10, one)));
 
   // After prefix, add_id.
-  EXPECT_TRUE(SBAddPrefixHashLess(SBAddFullHash(10, now, one),
-                                  SBAddFullHash(11, now, onetwo)));
-  EXPECT_FALSE(SBAddPrefixHashLess(SBAddFullHash(11, now, one),
-                                   SBAddFullHash(10, now, onetwo)));
+  EXPECT_TRUE(SBAddPrefixHashLess(SBAddFullHash(10, one),
+                                  SBAddFullHash(11, onetwo)));
+  EXPECT_FALSE(SBAddPrefixHashLess(SBAddFullHash(11, one),
+                                   SBAddFullHash(10, onetwo)));
 
   // After add_id, full hash.
-  EXPECT_TRUE(SBAddPrefixHashLess(SBAddFullHash(10, now, one),
-                                  SBAddFullHash(10, now, onetwo)));
-  EXPECT_FALSE(SBAddPrefixHashLess(SBAddFullHash(10, now, onetwo),
-                                   SBAddFullHash(10, now, one)));
+  EXPECT_TRUE(SBAddPrefixHashLess(SBAddFullHash(10, one),
+                                  SBAddFullHash(10, onetwo)));
+  EXPECT_FALSE(SBAddPrefixHashLess(SBAddFullHash(10, onetwo),
+                                   SBAddFullHash(10, one)));
 
   // Equal is not less-than.
-  EXPECT_FALSE(SBAddPrefixHashLess(SBAddFullHash(10, now, one),
-                                   SBAddFullHash(10, now, one)));
+  EXPECT_FALSE(SBAddPrefixHashLess(SBAddFullHash(10, one),
+                                   SBAddFullHash(10, one)));
 }
 
 TEST(SafeBrowsingStoreTest, SBSubPrefixLess) {
@@ -174,8 +172,6 @@
 
 // Test that subs knock out adds.
 TEST(SafeBrowsingStoreTest, SBProcessSubsKnockout) {
-  const base::Time kNow = base::Time::Now();
-
   // A full hash which shares prefix with another.
   const SBFullHash kHash1mod = ModifyHashAfterPrefix(kHash1, 1);
 
@@ -192,13 +188,13 @@
   sub_prefixes.push_back(SBSubPrefix(kSubChunk1, kAddChunk1, kHash5.prefix));
 
   // Add hashes with same prefix, plus subs to knock them out.
-  add_hashes.push_back(SBAddFullHash(kAddChunk2, kNow, kHash1));
-  add_hashes.push_back(SBAddFullHash(kAddChunk2, kNow, kHash1mod));
+  add_hashes.push_back(SBAddFullHash(kAddChunk2, kHash1));
+  add_hashes.push_back(SBAddFullHash(kAddChunk2, kHash1mod));
   sub_hashes.push_back(SBSubFullHash(kSubChunk2, kAddChunk2, kHash1));
   sub_hashes.push_back(SBSubFullHash(kSubChunk2, kAddChunk2, kHash1mod));
 
   // Adds with no corresponding sub.  Both items should be retained.
-  add_hashes.push_back(SBAddFullHash(kAddChunk6, kNow, kHash6));
+  add_hashes.push_back(SBAddFullHash(kAddChunk6, kHash6));
   add_prefixes.push_back(SBAddPrefix(kAddChunk7, kHash2.prefix));
 
   // Subs with no corresponding add.  Both items should be retained.
@@ -207,8 +203,8 @@
 
   // Add hashes with the same prefix, with a sub that will knock one of them
   // out.
-  add_hashes.push_back(SBAddFullHash(kAddChunk5, kNow, kHash4));
-  add_hashes.push_back(SBAddFullHash(kAddChunk5, kNow, kHash4mod));
+  add_hashes.push_back(SBAddFullHash(kAddChunk5, kHash4));
+  add_hashes.push_back(SBAddFullHash(kAddChunk5, kHash4mod));
   sub_hashes.push_back(SBSubFullHash(kSubChunk5, kAddChunk5, kHash4mod));
 
   const base::hash_set<int32> no_deletions;
@@ -239,8 +235,6 @@
 // Test chunk deletions, and ordering of deletions WRT subs knocking
 // out adds.
 TEST(SafeBrowsingStoreTest, SBProcessSubsDeleteChunk) {
-  const base::Time kNow = base::Time::Now();
-
   // A full hash which shares prefix with another.
   const SBFullHash kHash1mod = ModifyHashAfterPrefix(kHash1, 1);
 
@@ -249,19 +243,18 @@
   SBSubPrefixes sub_prefixes;
   std::vector<SBSubFullHash> sub_hashes;
 
-
   // An add prefix plus a sub to knock it out.
   add_prefixes.push_back(SBAddPrefix(kAddChunk1, kHash5.prefix));
   sub_prefixes.push_back(SBSubPrefix(kSubChunk1, kAddChunk1, kHash5.prefix));
 
   // Add hashes with same prefix, plus subs to knock them out.
-  add_hashes.push_back(SBAddFullHash(kAddChunk1, kNow, kHash1));
-  add_hashes.push_back(SBAddFullHash(kAddChunk1, kNow, kHash1mod));
+  add_hashes.push_back(SBAddFullHash(kAddChunk1, kHash1));
+  add_hashes.push_back(SBAddFullHash(kAddChunk1, kHash1mod));
   sub_hashes.push_back(SBSubFullHash(kSubChunk1, kAddChunk1, kHash1));
   sub_hashes.push_back(SBSubFullHash(kSubChunk1, kAddChunk1, kHash1mod));
 
   // Adds with no corresponding sub.  Both items should be retained.
-  add_hashes.push_back(SBAddFullHash(kAddChunk1, kNow, kHash6));
+  add_hashes.push_back(SBAddFullHash(kAddChunk1, kHash6));
   add_prefixes.push_back(SBAddPrefix(kAddChunk1, kHash2.prefix));
 
   // Subs with no corresponding add.  Both items should be retained.
@@ -307,4 +300,67 @@
     << " (int32)time_t is running out.";
 }
 
+// Test that prefixes which were injected from full hashes are being removed.
+// This was a mistake in earlier versions of the code.
+TEST(SafeBrowsingStoreTest, KnockoutPrefixVolunteers) {
+  // Construct some full hashes which share prefix with another.
+  const SBFullHash kHash1mod1 = ModifyHashAfterPrefix(kHash1, 1);
+  const SBFullHash kHash2mod1 = ModifyHashAfterPrefix(kHash2, 1);
+
+  SBAddPrefixes add_prefixes;
+  std::vector<SBAddFullHash> add_hashes;
+  SBSubPrefixes sub_prefixes;
+  std::vector<SBSubFullHash> sub_hashes;
+
+  // Full hashes for an add chunk will have had the prefix injected.
+  add_hashes.push_back(SBAddFullHash(kAddChunk1, kHash1));
+  add_hashes.push_back(SBAddFullHash(kAddChunk1, kHash1mod1));
+  add_prefixes.push_back(SBAddPrefix(kAddChunk1, kHash1.prefix));
+
+  // Other full hashes or prefixes are not affected.
+  add_hashes.push_back(SBAddFullHash(kAddChunk1, kHash3));
+  add_prefixes.push_back(SBAddPrefix(kAddChunk2, kHash4.prefix));
+
+  // Full hashes for a sub chunk will have had the prefix injected.
+  sub_hashes.push_back(SBSubFullHash(kSubChunk1, kAddChunk1, kHash2));
+  sub_hashes.push_back(SBSubFullHash(kSubChunk1, kAddChunk1, kHash2mod1));
+  sub_prefixes.push_back(SBSubPrefix(kSubChunk1, kAddChunk1, kHash2.prefix));
+
+  // Other full hashes or prefixes are not affected.
+  sub_hashes.push_back(SBSubFullHash(kSubChunk1, kAddChunk1, kHash5));
+  sub_prefixes.push_back(SBSubPrefix(kSubChunk2, kAddChunk2, kHash6.prefix));
+
+  const base::hash_set<int32> no_deletions;
+  ProcessHelper(&add_prefixes, &sub_prefixes, &add_hashes, &sub_hashes,
+                no_deletions, no_deletions);
+
+  ASSERT_EQ(1U, add_prefixes.size());
+  EXPECT_EQ(kAddChunk2, add_prefixes[0].chunk_id);
+  EXPECT_EQ(kHash4.prefix, add_prefixes[0].prefix);
+
+  ASSERT_EQ(3U, add_hashes.size());
+  EXPECT_EQ(kAddChunk1, add_hashes[0].chunk_id);
+  EXPECT_TRUE(SBFullHashEqual(kHash1mod1, add_hashes[0].full_hash));
+  EXPECT_EQ(kAddChunk1, add_hashes[1].chunk_id);
+  EXPECT_TRUE(SBFullHashEqual(kHash1, add_hashes[1].full_hash));
+  EXPECT_EQ(kAddChunk1, add_hashes[2].chunk_id);
+  EXPECT_TRUE(SBFullHashEqual(kHash3, add_hashes[2].full_hash));
+
+  ASSERT_EQ(1U, sub_prefixes.size());
+  EXPECT_EQ(kSubChunk2, sub_prefixes[0].chunk_id);
+  EXPECT_EQ(kAddChunk2, sub_prefixes[0].add_chunk_id);
+  EXPECT_EQ(kHash6.prefix, sub_prefixes[0].add_prefix);
+
+  ASSERT_EQ(3U, sub_hashes.size());
+  EXPECT_EQ(kSubChunk1, sub_hashes[0].chunk_id);
+  EXPECT_EQ(kAddChunk1, sub_hashes[0].add_chunk_id);
+  EXPECT_TRUE(SBFullHashEqual(kHash5, sub_hashes[0].full_hash));
+  EXPECT_EQ(kSubChunk1, sub_hashes[1].chunk_id);
+  EXPECT_EQ(kAddChunk1, sub_hashes[1].add_chunk_id);
+  EXPECT_TRUE(SBFullHashEqual(kHash2mod1, sub_hashes[1].full_hash));
+  EXPECT_EQ(kSubChunk1, sub_hashes[2].chunk_id);
+  EXPECT_EQ(kAddChunk1, sub_hashes[2].add_chunk_id);
+  EXPECT_TRUE(SBFullHashEqual(kHash2, sub_hashes[2].full_hash));
+}
+
 }  // namespace
diff --git a/chrome/browser/safe_browsing/safe_browsing_test.cc b/chrome/browser/safe_browsing/safe_browsing_test.cc
index 0f3b95e..dd91d09 100644
--- a/chrome/browser/safe_browsing/safe_browsing_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_test.cc
@@ -91,8 +91,7 @@
                  << urls[i];
       return false;
     }
-    phishing_url.url = std::string(content::kHttpScheme) +
-        "://" + record_parts[0];
+    phishing_url.url = std::string(url::kHttpScheme) + "://" + record_parts[0];
     phishing_url.list_name = record_parts[1];
     if (record_parts[2] == "yes") {
       phishing_url.is_phishing = true;
diff --git a/chrome/browser/search/hotword_client.h b/chrome/browser/search/hotword_client.h
new file mode 100644
index 0000000..8862b90
--- /dev/null
+++ b/chrome/browser/search/hotword_client.h
@@ -0,0 +1,19 @@
+// 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.
+
+#ifndef CHROME_BROWSER_SEARCH_HOTWORD_CLIENT_H_
+#define CHROME_BROWSER_SEARCH_HOTWORD_CLIENT_H_
+
+class HotwordClient {
+ public:
+  virtual ~HotwordClient() {}
+
+  // Called when the hotword recognition session state has been changed.
+  virtual void OnHotwordStateChanged(bool started) {}
+
+  // Called when the hotword is recognized.
+  virtual void OnHotwordRecognized() = 0;
+};
+
+#endif  // CHROME_BROWSER_SEARCH_HOTWORD_CLIENT_H_
diff --git a/chrome/browser/search/hotword_service.cc b/chrome/browser/search/hotword_service.cc
index ac25512..6936671 100644
--- a/chrome/browser/search/hotword_service.cc
+++ b/chrome/browser/search/hotword_service.cc
@@ -20,13 +20,28 @@
 #include "extensions/common/extension.h"
 #include "ui/base/l10n/l10n_util.h"
 
+// The whole file relies on the extension systems but this file is built on
+// some non-extension supported platforms and including an API header will cause
+// a compile error since it depends on header files generated by .idl.
+// TODO(mukai): clean up file dependencies and remove this clause.
+#if defined(ENABLE_EXTENSIONS)
+#include "chrome/browser/extensions/api/hotword_private/hotword_private_api.h"
+#endif
+
+#if defined(ENABLE_EXTENSIONS)
+using extensions::BrowserContextKeyedAPIFactory;
+using extensions::HotwordPrivateEventService;
+#endif
+
 namespace {
 const int kMaxTimesToShowOptInPopup = 10;
 
 // Allowed languages for hotwording.
 static const char* kSupportedLocales[] = {
   "en",
-  "en_us"
+  "de",
+  "fr",
+  "ru"
 };
 
 // Enum describing the state of the hotword preference.
@@ -113,14 +128,15 @@
   StringToLowerASCII(&normalized_locale);
 
   for (size_t i = 0; i < arraysize(kSupportedLocales); i++) {
-    if (kSupportedLocales[i] == normalized_locale)
+    if (normalized_locale.compare(0, 2, kSupportedLocales[i]) == 0)
       return true;
   }
   return false;
 }
 
 HotwordService::HotwordService(Profile* profile)
-    : profile_(profile) {
+    : profile_(profile),
+      client_(NULL) {
   // This will be called during profile initialization which is a good time
   // to check the user's hotword state.
   HotwordEnabled enabled_state = UNSET;
@@ -273,3 +289,32 @@
   else
     DisableHotwordExtension(extension_service);
 }
+
+void HotwordService::RequestHotwordSession(HotwordClient* client) {
+#if defined(ENABLE_EXTENSIONS)
+  if (!IsServiceAvailable() || client_)
+    return;
+
+  client_ = client;
+
+  HotwordPrivateEventService* event_service =
+      BrowserContextKeyedAPIFactory<HotwordPrivateEventService>::Get(profile_);
+  if (event_service)
+    event_service->OnHotwordSessionRequested();
+#endif
+}
+
+void HotwordService::StopHotwordSession(HotwordClient* client) {
+#if defined(ENABLE_EXTENSIONS)
+  if (!IsServiceAvailable())
+    return;
+
+  DCHECK(client_ == client);
+
+  client_ = NULL;
+  HotwordPrivateEventService* event_service =
+      BrowserContextKeyedAPIFactory<HotwordPrivateEventService>::Get(profile_);
+  if (event_service)
+    event_service->OnHotwordSessionStopped();
+#endif
+}
diff --git a/chrome/browser/search/hotword_service.h b/chrome/browser/search/hotword_service.h
index def0df0..61478db 100644
--- a/chrome/browser/search/hotword_service.h
+++ b/chrome/browser/search/hotword_service.h
@@ -12,6 +12,7 @@
 #include "content/public/browser/notification_registrar.h"
 
 class ExtensionService;
+class HotwordClient;
 class Profile;
 
 namespace hotword_internal {
@@ -72,6 +73,11 @@
   // turns it off via the settings menu.
   void OnHotwordSearchEnabledChanged(const std::string& pref_name);
 
+  // Called to handle the hotword session from |client|.
+  void RequestHotwordSession(HotwordClient* client);
+  void StopHotwordSession(HotwordClient* client);
+  HotwordClient* client() { return client_; }
+
  private:
   Profile* profile_;
 
@@ -79,6 +85,8 @@
 
   content::NotificationRegistrar registrar_;
 
+  HotwordClient* client_;
+
   DISALLOW_COPY_AND_ASSIGN(HotwordService);
 };
 
diff --git a/chrome/browser/search/hotword_service_unittest.cc b/chrome/browser/search/hotword_service_unittest.cc
index 03b2a5a..5da13fe 100644
--- a/chrome/browser/search/hotword_service_unittest.cc
+++ b/chrome/browser/search/hotword_service_unittest.cc
@@ -145,6 +145,10 @@
   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en_us");
   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
+  SetApplicationLocale(static_cast<Profile*>(profile.get()), "de_DE");
+  EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
+  SetApplicationLocale(static_cast<Profile*>(profile.get()), "fr_fr");
+  EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
 
   // Test that incognito even with a valid locale and valid field trial
   // still returns false.
diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc
index db35dd1..4deb2cb 100644
--- a/chrome/browser/search/instant_service.cc
+++ b/chrome/browser/search/instant_service.cc
@@ -4,52 +4,39 @@
 
 #include "chrome/browser/search/instant_service.h"
 
-#include <vector>
-
-#include "base/logging.h"
-#include "base/prefs/pref_service.h"
-#include "base/strings/string_number_conversions.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/most_visited_tiles_experiment.h"
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/instant_io_context.h"
-#include "chrome/browser/search/instant_service_factory.h"
 #include "chrome/browser/search/instant_service_observer.h"
 #include "chrome/browser/search/local_ntp_source.h"
 #include "chrome/browser/search/most_visited_iframe_source.h"
 #include "chrome/browser/search/search.h"
-#include "chrome/browser/search/suggestions/suggestions_service.h"
 #include "chrome/browser/search/suggestions/suggestions_source.h"
-#include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/search_engines/search_terms_data.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
+#include "chrome/browser/thumbnails/thumbnail_list_source.h"
+#include "chrome/browser/ui/search/instant_search_prerenderer.h"
 #include "chrome/browser/ui/webui/favicon_source.h"
-#include "chrome/browser/ui/webui/ntp/thumbnail_list_source.h"
 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h"
 #include "chrome/browser/ui/webui/theme_source.h"
-#include "chrome/common/pref_names.h"
 #include "chrome/common/render_messages.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_source.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/url_data_source.h"
 #include "grit/theme_resources.h"
-#include "net/base/net_util.h"
-#include "net/url_request/url_request.h"
+#include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/sys_color_change_listener.h"
-#include "url/gurl.h"
 
-using content::BrowserThread;
 
 namespace {
 
@@ -69,12 +56,32 @@
 
 InstantService::InstantService(Profile* profile)
     : profile_(profile),
+      template_url_service_(TemplateURLServiceFactory::GetForProfile(profile_)),
       omnibox_start_margin_(chrome::kDisableStartMargin),
       weak_ptr_factory_(this) {
-  // Stub for unit tests.
-  if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
+  // The initialization below depends on a typical set of browser threads. Skip
+  // it if we are running in a unit test without the full suite.
+  if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI))
     return;
 
+  // This depends on the existence of the typical browser threads. Therefore it
+  // is only instantiated here (after the check for a UI thread above).
+  instant_io_context_ = new InstantIOContext();
+
+  previous_google_base_url_ =
+      GURL(UIThreadSearchTermsData(profile).GoogleBaseURLValue());
+
+  // TemplateURLService is NULL by default in tests.
+  if (template_url_service_) {
+    template_url_service_->AddObserver(this);
+    const TemplateURL* default_search_provider =
+        template_url_service_->GetDefaultSearchProvider();
+    if (default_search_provider) {
+      previous_default_search_provider_.reset(
+          new TemplateURLData(default_search_provider->data()));
+    }
+  }
+
   ResetInstantSearchPrerenderer();
 
   registrar_.Add(this,
@@ -90,11 +97,10 @@
                    chrome::NOTIFICATION_TOP_SITES_CHANGED,
                    content::Source<history::TopSites>(top_sites));
   }
-  instant_io_context_ = new InstantIOContext();
 
   if (profile_ && profile_->GetResourceContext()) {
-    BrowserThread::PostTask(
-        BrowserThread::IO, FROM_HERE,
+    content::BrowserThread::PostTask(
+        content::BrowserThread::IO, FROM_HERE,
         base::Bind(&InstantIOContext::SetUserDataOnIO,
                    profile->GetResourceContext(), instant_io_context_));
   }
@@ -121,33 +127,23 @@
       profile_, new FaviconSource(profile_, FaviconSource::FAVICON));
   content::URLDataSource::Add(profile_, new LocalNtpSource(profile_));
   content::URLDataSource::Add(profile_, new MostVisitedIframeSource());
-  if (suggestions::SuggestionsService::IsEnabled()) {
-    content::URLDataSource::Add(
-        profile_, new suggestions::SuggestionsSource(profile_));
-  }
-
-  profile_pref_registrar_.Init(profile_->GetPrefs());
-  profile_pref_registrar_.Add(
-      prefs::kDefaultSearchProviderID,
-      base::Bind(&InstantService::OnDefaultSearchProviderChanged,
-                 base::Unretained(this)));
-
-  registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED,
-                 content::Source<Profile>(profile_->GetOriginalProfile()));
+  content::URLDataSource::Add(
+      profile_, new suggestions::SuggestionsSource(profile_));
 }
 
 InstantService::~InstantService() {
+  if (template_url_service_)
+    template_url_service_->RemoveObserver(this);
 }
 
 void InstantService::AddInstantProcess(int process_id) {
   process_ids_.insert(process_id);
 
   if (instant_io_context_.get()) {
-    BrowserThread::PostTask(BrowserThread::IO,
-                            FROM_HERE,
-                            base::Bind(&InstantIOContext::AddInstantProcessOnIO,
-                                       instant_io_context_,
-                                       process_id));
+    content::BrowserThread::PostTask(
+        content::BrowserThread::IO, FROM_HERE,
+        base::Bind(&InstantIOContext::AddInstantProcessOnIO,
+                   instant_io_context_, process_id));
   }
 }
 
@@ -204,9 +200,8 @@
   process_ids_.clear();
 
   if (instant_io_context_.get()) {
-    BrowserThread::PostTask(
-        BrowserThread::IO,
-        FROM_HERE,
+    content::BrowserThread::PostTask(
+        content::BrowserThread::IO, FROM_HERE,
         base::Bind(&InstantIOContext::ClearInstantProcessesOnIO,
                    instant_io_context_));
   }
@@ -240,12 +235,6 @@
       break;
     }
 #endif  // defined(ENABLE_THEMES)
-    case chrome::NOTIFICATION_GOOGLE_URL_UPDATED: {
-      OnGoogleURLUpdated(
-          content::Source<Profile>(source).ptr(),
-          content::Details<GoogleURLTracker::UpdatedDetails>(details).ptr());
-      break;
-    }
     default:
       NOTREACHED() << "Unexpected notification type in InstantService.";
   }
@@ -266,12 +255,10 @@
   process_ids_.erase(process_id);
 
   if (instant_io_context_.get()) {
-    BrowserThread::PostTask(
-        BrowserThread::IO,
-        FROM_HERE,
+    content::BrowserThread::PostTask(
+        content::BrowserThread::IO, FROM_HERE,
         base::Bind(&InstantIOContext::RemoveInstantProcessOnIO,
-                   instant_io_context_,
-                   process_id));
+                   instant_io_context_, process_id));
   }
 }
 
@@ -406,47 +393,33 @@
                     ThemeInfoChanged(*theme_info_));
 }
 
-void InstantService::OnGoogleURLUpdated(
-    Profile* profile,
-    GoogleURLTracker::UpdatedDetails* details) {
-  GURL last_prompted_url(
-      profile->GetPrefs()->GetString(prefs::kLastPromptedGoogleURL));
-
-  // See GoogleURLTracker::OnURLFetchComplete().
-  // last_prompted_url.is_empty() indicates very first run of Chrome. So there
-  // is no need to notify, as there won't be any old state.
-  if (last_prompted_url.is_empty())
-    return;
-
-  ResetInstantSearchPrerenderer();
-
-  // Only the scheme changed. Ignore it since we do not prompt the user in this
-  // case.
-  if (net::StripWWWFromHost(details->first) ==
-      net::StripWWWFromHost(details->second))
-    return;
-
-  FOR_EACH_OBSERVER(InstantServiceObserver, observers_, GoogleURLUpdated());
-}
-
-void InstantService::OnDefaultSearchProviderChanged(
-    const std::string& pref_name) {
-  DCHECK_EQ(pref_name, std::string(prefs::kDefaultSearchProviderID));
-  const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile(
-      profile_)->GetDefaultSearchProvider();
-  if (!template_url) {
-    // A NULL |template_url| could mean either this notification is sent during
-    // the browser start up operation or the user now has no default search
-    // provider. There is no way for the user to reach this state using the
-    // Chrome settings. Only explicitly poking at the DB or bugs in the Sync
-    // could cause that, neither of which we support.
-    return;
+void InstantService::OnTemplateURLServiceChanged() {
+  // Check whether the default search provider was changed.
+  const TemplateURL* template_url =
+      template_url_service_->GetDefaultSearchProvider();
+  bool default_search_provider_changed = !TemplateURL::MatchesData(
+      template_url, previous_default_search_provider_.get());
+  if (default_search_provider_changed) {
+    previous_default_search_provider_.reset(
+        template_url ? new TemplateURLData(template_url->data()) : NULL);
   }
 
-  ResetInstantSearchPrerenderer();
+  // Note that, even if the TemplateURL for the Default Search Provider has not
+  // changed, the effective URLs might change if they reference the Google base
+  // URL. The TemplateURLService will notify us when the effective URL changes
+  // in this way but it's up to us to do the work to check both.
+  GURL google_base_url(UIThreadSearchTermsData(profile_).GoogleBaseURLValue());
+  if (google_base_url != previous_google_base_url_) {
+    previous_google_base_url_ = google_base_url;
+    if (template_url && template_url->HasGoogleBaseURLs())
+      default_search_provider_changed = true;
+  }
 
-  FOR_EACH_OBSERVER(
-      InstantServiceObserver, observers_, DefaultSearchProviderChanged());
+  if (default_search_provider_changed) {
+    ResetInstantSearchPrerenderer();
+    FOR_EACH_OBSERVER(InstantServiceObserver, observers_,
+                      DefaultSearchProviderChanged());
+  }
 }
 
 void InstantService::ResetInstantSearchPrerenderer() {
@@ -454,8 +427,6 @@
     return;
 
   GURL url(chrome::GetSearchResultPrefetchBaseURL(profile_));
-  if (url.is_valid())
-    instant_prerenderer_.reset(new InstantSearchPrerenderer(profile_, url));
-  else
-    instant_prerenderer_.reset();
+  instant_prerenderer_.reset(
+      url.is_valid() ? new InstantSearchPrerenderer(profile_, url) : NULL);
 }
diff --git a/chrome/browser/search/instant_service.h b/chrome/browser/search/instant_service.h
index 393d072..02dc7c7 100644
--- a/chrome/browser/search/instant_service.h
+++ b/chrome/browser/search/instant_service.h
@@ -5,44 +5,37 @@
 #ifndef CHROME_BROWSER_SEARCH_INSTANT_SERVICE_H_
 #define CHROME_BROWSER_SEARCH_INSTANT_SERVICE_H_
 
-#include <map>
 #include <set>
-#include <string>
 #include <vector>
 
-#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/gtest_prod_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
-#include "base/prefs/pref_change_registrar.h"
-#include "chrome/browser/google/google_url_tracker.h"
 #include "chrome/browser/history/history_types.h"
-#include "chrome/browser/ui/search/instant_search_prerenderer.h"
-#include "chrome/common/instant_types.h"
+#include "chrome/browser/search_engines/template_url_service_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
+#include "url/gurl.h"
 
-class GURL;
 class InstantIOContext;
+struct InstantMostVisitedItem;
+class InstantSearchPrerenderer;
 class InstantServiceObserver;
-class InstantTestBase;
-class InstantServiceTest;
 class Profile;
+struct TemplateURLData;
+class TemplateURLService;
+struct ThemeBackgroundInfo;
 class ThemeService;
 
 namespace content {
 class RenderProcessHost;
 }
 
-namespace net {
-class URLRequest;
-}
-
 // Tracks render process host IDs that are associated with Instant.
 class InstantService : public KeyedService,
-                       public content::NotificationObserver {
+                       public content::NotificationObserver,
+                       public TemplateURLServiceObserver {
  public:
   explicit InstantService(Profile* profile);
   virtual ~InstantService();
@@ -108,16 +101,23 @@
   FRIEND_TEST_ALL_PREFIXES(InstantExtendedManualTest,
                            MANUAL_SearchesFromFakebox);
   FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, ProcessIsolation);
-  FRIEND_TEST_ALL_PREFIXES(InstantServiceTest, SendsSearchURLsToRenderer);
+  FRIEND_TEST_ALL_PREFIXES(InstantServiceEnabledTest,
+                           SendsSearchURLsToRenderer);
 
-  // Overridden from KeyedService:
+  // KeyedService:
   virtual void Shutdown() OVERRIDE;
 
-  // Overridden from content::NotificationObserver:
+  // content::NotificationObserver:
   virtual void Observe(int type,
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
+  // TemplateURLServiceObserver:
+  // Caches the previous value of the Default Search Provider and the Google
+  // base URL to filter out changes other than those affecting the Default
+  // Search Provider.
+  virtual void OnTemplateURLServiceChanged() OVERRIDE;
+
   // Called when a renderer process is terminated.
   void OnRendererProcessTerminated(int process_id);
 
@@ -132,15 +132,14 @@
   // Theme changed notification handler.
   void OnThemeChanged(ThemeService* theme_service);
 
-  void OnGoogleURLUpdated(Profile* profile,
-                          GoogleURLTracker::UpdatedDetails* details);
-
-  void OnDefaultSearchProviderChanged(const std::string& pref_name);
-
   void ResetInstantSearchPrerenderer();
 
   Profile* const profile_;
 
+  // The TemplateURLService that we are observing. It will outlive this
+  // InstantService due to the dependency declared in InstantServiceFactory.
+  TemplateURLService* template_url_service_;
+
   // The process ids associated with Instant processes.
   std::set<int> process_ids_;
 
@@ -158,8 +157,6 @@
 
   content::NotificationRegistrar registrar_;
 
-  PrefChangeRegistrar profile_pref_registrar_;
-
   scoped_refptr<InstantIOContext> instant_io_context_;
 
   // Set to NULL if the default search provider does not support Instant.
@@ -168,6 +165,11 @@
   // Used for Top Sites async retrieval.
   base::WeakPtrFactory<InstantService> weak_ptr_factory_;
 
+  // Used to check whether notifications from TemplateURLService indicate a
+  // change that affects the default search provider.
+  scoped_ptr<TemplateURLData> previous_default_search_provider_;
+  GURL previous_google_base_url_;
+
   DISALLOW_COPY_AND_ASSIGN(InstantService);
 };
 
diff --git a/chrome/browser/search/instant_service_observer.cc b/chrome/browser/search/instant_service_observer.cc
index efbd8f5..bda8ff0 100644
--- a/chrome/browser/search/instant_service_observer.cc
+++ b/chrome/browser/search/instant_service_observer.cc
@@ -14,9 +14,6 @@
 void InstantServiceObserver::DefaultSearchProviderChanged() {
 }
 
-void InstantServiceObserver::GoogleURLUpdated() {
-}
-
 void InstantServiceObserver::OmniboxStartMarginChanged(
     int omnibox_start_margin) {
 }
diff --git a/chrome/browser/search/instant_service_observer.h b/chrome/browser/search/instant_service_observer.h
index 248b689..68b4c97 100644
--- a/chrome/browser/search/instant_service_observer.h
+++ b/chrome/browser/search/instant_service_observer.h
@@ -23,11 +23,6 @@
   // Indicates that the default search provider changed.
   virtual void DefaultSearchProviderChanged();
 
-  // Indicates that the Google URL has changed as a result of searchdomaincheck.
-  // Note that the search domain change triggers a yellow infobar at the top of
-  // the page, and the actual change is triggered after the user accepts.
-  virtual void GoogleURLUpdated();
-
   // Indicates that the omnibox start margin has changed.
   virtual void OmniboxStartMarginChanged(int omnibox_start_margin);
 
diff --git a/chrome/browser/search/instant_service_unittest.cc b/chrome/browser/search/instant_service_unittest.cc
index 0e9135c..760bb58 100644
--- a/chrome/browser/search/instant_service_unittest.cc
+++ b/chrome/browser/search/instant_service_unittest.cc
@@ -29,7 +29,6 @@
 class MockInstantServiceObserver : public InstantServiceObserver {
  public:
   MOCK_METHOD0(DefaultSearchProviderChanged, void());
-  MOCK_METHOD0(GoogleURLUpdated, void());
   MOCK_METHOD1(OmniboxStartMarginChanged, void(int));
 };
 
@@ -58,24 +57,45 @@
   scoped_ptr<MockInstantServiceObserver> instant_service_observer_;
 };
 
-TEST_F(InstantServiceTest, DispatchDefaultSearchProviderChanged) {
+class InstantServiceEnabledTest : public InstantServiceTest {
+ protected:
+  virtual void SetUp() OVERRIDE {
+    ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
+        "EmbeddedSearch", "Group1 use_cacheable_ntp:1 prefetch_results:1"));
+    InstantServiceTest::SetUp();
+  }
+};
+
+TEST_F(InstantServiceEnabledTest, DispatchDefaultSearchProviderChanged) {
   EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged())
       .Times(1);
 
-  const std::string& new_base_url = "https://bar.com/";
+  const std::string new_base_url = "https://bar.com/";
   SetUserSelectedDefaultSearchProvider(new_base_url);
 }
 
-TEST_F(InstantServiceTest, DispatchGoogleURLUpdated) {
-  EXPECT_CALL(*instant_service_observer_.get(), GoogleURLUpdated()).Times(1);
+TEST_F(InstantServiceTest, DontDispatchGoogleURLUpdatedForNonGoogleURLs) {
+  EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged())
+      .Times(1);
+  const std::string new_dsp_url = "https://bar.com/";
+  SetUserSelectedDefaultSearchProvider(new_dsp_url);
+  testing::Mock::VerifyAndClearExpectations(instant_service_observer_.get());
 
-  const std::string& new_base_url = "https://www.google.es/";
+  EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged())
+      .Times(0);
+  const std::string new_base_url = "https://www.google.es/";
   NotifyGoogleBaseURLUpdate(new_base_url);
 }
 
-TEST_F(InstantServiceTest, SendsSearchURLsToRenderer) {
-  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
-      "Group1 use_cacheable_ntp:1"));
+TEST_F(InstantServiceTest, DispatchGoogleURLUpdated) {
+  EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged())
+      .Times(1);
+
+  const std::string new_base_url = "https://www.google.es/";
+  NotifyGoogleBaseURLUpdate(new_base_url);
+}
+
+TEST_F(InstantServiceEnabledTest, SendsSearchURLsToRenderer) {
   scoped_ptr<content::MockRenderProcessHost> rph(
       new content::MockRenderProcessHost(profile()));
   rph->sink().ClearMessages();
@@ -102,10 +122,8 @@
             GetInstantSearchPrerenderer());
 }
 
-TEST_F(InstantServiceTest,
+TEST_F(InstantServiceEnabledTest,
        ResetInstantSearchPrerenderer_DefaultProviderChanged) {
-  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
-      "EmbeddedSearch", "Group1 use_cacheable_ntp:1 prefetch_results:1"));
   EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged())
       .Times(2);
 
@@ -127,18 +145,15 @@
             GetInstantSearchPrerenderer());
 }
 
-TEST_F(InstantServiceTest, ResetInstantSearchPrerenderer_GoogleBaseURLUpdated) {
-  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
-      "EmbeddedSearch", "Group1 use_cacheable_ntp:1 prefetch_results:1"));
+TEST_F(InstantServiceEnabledTest,
+       ResetInstantSearchPrerenderer_GoogleBaseURLUpdated) {
   EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged())
       .Times(1);
-  EXPECT_CALL(*instant_service_observer_.get(), GoogleURLUpdated()).Times(1);
 
-  SetUserSelectedDefaultSearchProvider("https://google.com/");
   InstantSearchPrerenderer* old_prerenderer = GetInstantSearchPrerenderer();
-  EXPECT_NE(static_cast<InstantSearchPrerenderer*>(NULL), old_prerenderer);
+  EXPECT_TRUE(old_prerenderer != NULL);
 
-  const std::string& new_base_url = "https://www.google.es/";
+  const std::string new_base_url = "https://www.google.es/";
   NotifyGoogleBaseURLUpdate(new_base_url);
   EXPECT_NE(old_prerenderer, GetInstantSearchPrerenderer());
 }
diff --git a/chrome/browser/search/instant_unittest_base.cc b/chrome/browser/search/instant_unittest_base.cc
index 6291009..d164e4b 100644
--- a/chrome/browser/search/instant_unittest_base.cc
+++ b/chrome/browser/search/instant_unittest_base.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/search/instant_unittest_base.h"
 #include <string>
 
-#include "base/basictypes.h"
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/google/google_url_tracker.h"
 #include "chrome/browser/profiles/profile.h"
@@ -52,6 +52,7 @@
 void InstantUnitTestBase::SetUserSelectedDefaultSearchProvider(
     const std::string& base_url) {
   TemplateURLData data;
+  data.SetKeyword(base::UTF8ToUTF16(base_url));
   data.SetURL(base_url + "url?bar={searchTerms}");
   data.instant_url = base_url +
       "instant?{google:omniboxStartMarginParameter}{google:forceInstantResults}"
@@ -87,11 +88,16 @@
   return instant_service_->observers_.HasObserver(observer);
 }
 
+TestingProfile* InstantUnitTestBase::CreateProfile() {
+  TestingProfile* profile = BrowserWithTestWindowTest::CreateProfile();
+  TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+      profile, &TemplateURLServiceFactory::BuildInstanceFor);
+  return profile;
+}
+
 void InstantUnitTestBase::SetUpHelper() {
   BrowserWithTestWindowTest::SetUp();
 
-  TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
-      profile(), &TemplateURLServiceFactory::BuildInstanceFor);
   template_url_service_ = TemplateURLServiceFactory::GetForProfile(profile());
   ui_test_utils::WaitForTemplateURLServiceToLoad(template_url_service_);
 
diff --git a/chrome/browser/search/instant_unittest_base.h b/chrome/browser/search/instant_unittest_base.h
index ec786e5..87b8e33 100644
--- a/chrome/browser/search/instant_unittest_base.h
+++ b/chrome/browser/search/instant_unittest_base.h
@@ -49,6 +49,9 @@
   scoped_ptr<base::FieldTrialList> field_trial_list_;
 
  private:
+  // BrowserWithTestWindowTest override:
+  virtual TestingProfile* CreateProfile() OVERRIDE;
+
   void SetUpHelper();
 };
 
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc
index b1934df..7967311 100644
--- a/chrome/browser/search/search.cc
+++ b/chrome/browser/search/search.cc
@@ -408,7 +408,9 @@
     // page.
     InstantSearchPrerenderer* prerenderer =
         InstantSearchPrerenderer::GetForProfile(profile);
-    DCHECK(prerenderer);
+    // TODO(kmadhusu): Remove this CHECK after the investigation of
+    // crbug.com/367204.
+    CHECK(prerenderer);
     return prerenderer->get_last_query();
   }
 
@@ -530,7 +532,7 @@
   if (!instant_url.SchemeIsSecure() &&
       !google_util::StartsWithCommandLineGoogleBaseURL(instant_url)) {
     GURL::Replacements replacements;
-    const std::string secure_scheme(content::kHttpsScheme);
+    const std::string secure_scheme(url::kHttpsScheme);
     replacements.SetSchemeStr(secure_scheme);
     instant_url = instant_url.ReplaceComponents(replacements);
   }
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc
index 5034bb6..8f18fc4 100644
--- a/chrome/browser/search/search_unittest.cc
+++ b/chrome/browser/search/search_unittest.cc
@@ -878,6 +878,7 @@
 };
 
 TEST_F(SearchURLTest, QueryExtractionEnabled) {
+  UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/");
   EnableQueryExtractionForTesting();
   EXPECT_TRUE(IsQueryExtractionEnabled());
   TemplateURLRef::SearchTermsArgs search_terms_args(base::ASCIIToUTF16("foo"));
@@ -889,6 +890,7 @@
 }
 
 TEST_F(SearchURLTest, QueryExtractionDisabled) {
+  UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/");
   EXPECT_FALSE(IsQueryExtractionEnabled());
   TemplateURLRef::SearchTermsArgs search_terms_args(base::ASCIIToUTF16("foo"));
   GURL result(template_url_->url_ref().ReplaceSearchTerms(search_terms_args));
diff --git a/chrome/browser/search/suggestions/suggestions_source.cc b/chrome/browser/search/suggestions/suggestions_source.cc
index 45d9657..188a046 100644
--- a/chrome/browser/search/suggestions/suggestions_source.cc
+++ b/chrome/browser/search/suggestions/suggestions_source.cc
@@ -57,9 +57,10 @@
   SuggestionsService* suggestions_service(
       suggestions_service_factory->GetForProfile(profile_));
 
-  // If SuggestionsService is unavailable, then SuggestionsSource should not
-  // have been instantiated in the first place.
-  DCHECK(suggestions_service != NULL);
+  if (!suggestions_service) {
+    callback.Run(NULL);
+    return;
+  }
 
   suggestions_service->FetchSuggestionsData(
       base::Bind(&SuggestionsSource::OnSuggestionsAvailable,
diff --git a/chrome/browser/search_engines/default_search_manager.cc b/chrome/browser/search_engines/default_search_manager.cc
index cd763d7..9d344ee 100644
--- a/chrome/browser/search_engines/default_search_manager.cc
+++ b/chrome/browser/search_engines/default_search_manager.cc
@@ -7,8 +7,11 @@
 #include <algorithm>
 #include <utility>
 
+#include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/compiler_specific.h"
 #include "base/i18n/case_conversion.h"
+#include "base/logging.h"
 #include "base/prefs/pref_service.h"
 #include "base/prefs/pref_value_map.h"
 #include "base/stl_util.h"
@@ -19,21 +22,18 @@
 #include "base/time/time.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/util.h"
 #include "chrome/common/pref_names.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 
-namespace {
-
 // A dictionary to hold all data related to the Default Search Engine.
 // Eventually, this should replace all the data stored in the
 // default_search_provider.* prefs.
-const char kDefaultSearchProviderData[] =
+const char DefaultSearchManager::kDefaultSearchProviderDataPrefName[] =
     "default_search_provider_data.template_url_data";
 
-}  // namespace
-
 const char DefaultSearchManager::kID[] = "id";
 const char DefaultSearchManager::kShortName[] = "short_name";
 const char DefaultSearchManager::kKeyword[] = "keyword";
@@ -70,9 +70,25 @@
 const char DefaultSearchManager::kCreatedByPolicy[] = "created_by_policy";
 const char DefaultSearchManager::kDisabledByPolicy[] = "disabled_by_policy";
 
-DefaultSearchManager::DefaultSearchManager(PrefService* pref_service)
-    : pref_service_(pref_service) {
-  DCHECK(pref_service_);
+DefaultSearchManager::DefaultSearchManager(
+    PrefService* pref_service,
+    const ObserverCallback& change_observer)
+    : pref_service_(pref_service),
+      change_observer_(change_observer),
+      default_search_controlled_by_policy_(false) {
+  if (pref_service_) {
+    pref_change_registrar_.Init(pref_service_);
+    pref_change_registrar_.Add(
+        kDefaultSearchProviderDataPrefName,
+        base::Bind(&DefaultSearchManager::OnDefaultSearchPrefChanged,
+                   base::Unretained(this)));
+    pref_change_registrar_.Add(
+        prefs::kSearchProviderOverrides,
+        base::Bind(&DefaultSearchManager::OnOverridesPrefChanged,
+                   base::Unretained(this)));
+  }
+  LoadPrepopulatedDefaultSearch();
+  LoadDefaultSearchEngineFromPrefs();
 }
 
 DefaultSearchManager::~DefaultSearchManager() {
@@ -82,102 +98,55 @@
 void DefaultSearchManager::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterDictionaryPref(
-      kDefaultSearchProviderData,
+      kDefaultSearchProviderDataPrefName,
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
 }
 
 // static
 void DefaultSearchManager::AddPrefValueToMap(base::DictionaryValue* value,
                                              PrefValueMap* pref_value_map) {
-  pref_value_map->SetValue(kDefaultSearchProviderData, value);
+  pref_value_map->SetValue(kDefaultSearchProviderDataPrefName, value);
 }
 
-bool DefaultSearchManager::GetDefaultSearchEngine(TemplateURLData* data) {
-  const base::DictionaryValue* url_dict =
-      pref_service_->GetDictionary(kDefaultSearchProviderData);
-
-  if (url_dict->empty())
-    return false;
-
-  std::string search_url;
-  base::string16 keyword;
-  url_dict->GetString(kURL, &search_url);
-  url_dict->GetString(kKeyword, &keyword);
-  if (search_url.empty())
-    return false;
-  if (keyword.empty())
-    keyword = TemplateURLService::GenerateKeyword(GURL(search_url));
-  data->SetKeyword(keyword);
-  data->SetURL(search_url);
-
-  std::string id;
-  url_dict->GetString(kID, &id);
-  base::StringToInt64(id, &data->id);
-  url_dict->GetString(kShortName, &data->short_name);
-  url_dict->GetInteger(kPrepopulateID, &data->prepopulate_id);
-  url_dict->GetString(kSyncGUID, &data->sync_guid);
-
-  url_dict->GetString(kSuggestionsURL, &data->suggestions_url);
-  url_dict->GetString(kInstantURL, &data->instant_url);
-  url_dict->GetString(kImageURL, &data->image_url);
-  url_dict->GetString(kNewTabURL, &data->new_tab_url);
-
-  std::string favicon_url;
-  std::string originating_url;
-  url_dict->GetString(kFaviconURL, &favicon_url);
-  url_dict->GetString(kOriginatingURL, &originating_url);
-  data->favicon_url = GURL(favicon_url);
-  data->originating_url = GURL(originating_url);
-
-  url_dict->GetString(kSearchURLPostParams, &data->search_url_post_params);
-  url_dict->GetString(kSuggestionsURLPostParams,
-                      &data->suggestions_url_post_params);
-  url_dict->GetString(kInstantURLPostParams, &data->instant_url_post_params);
-  url_dict->GetString(kImageURLPostParams, &data->image_url_post_params);
-
-  url_dict->GetBoolean(kSafeForAutoReplace, &data->safe_for_autoreplace);
-
-  double date_created = 0.0;
-  double last_modified = 0.0;
-  url_dict->GetDouble(kDateCreated, &date_created);
-  url_dict->GetDouble(kLastModified, &last_modified);
-  data->date_created = base::Time::FromInternalValue(date_created);
-  data->last_modified = base::Time::FromInternalValue(last_modified);
-
-  url_dict->GetInteger(kUsageCount, &data->usage_count);
-
-  const base::ListValue* alternate_urls;
-  url_dict->GetList(kAlternateURLs, &alternate_urls);
-  data->alternate_urls.clear();
-  for (base::ListValue::const_iterator it = alternate_urls->begin();
-       it != alternate_urls->end(); ++it) {
-    std::string alternate_url;
-    if ((*it)->GetAsString(&alternate_url))
-      data->alternate_urls.push_back(alternate_url);
+TemplateURLData* DefaultSearchManager::GetDefaultSearchEngine(
+    Source* source) const {
+  if (default_search_controlled_by_policy_) {
+    if (source)
+      *source = FROM_POLICY;
+    return prefs_default_search_.get();
+  }
+  if (extension_default_search_) {
+    if (source)
+      *source = FROM_EXTENSION;
+    return extension_default_search_.get();
+  }
+  if (prefs_default_search_) {
+    if (source)
+      *source = FROM_USER;
+    return prefs_default_search_.get();
   }
 
-  const base::ListValue* encodings;
-  url_dict->GetList(kInputEncodings, &encodings);
-  data->input_encodings.clear();
-  for (base::ListValue::const_iterator it = encodings->begin();
-       it != encodings->end(); ++it) {
-    std::string encoding;
-    if ((*it)->GetAsString(&encoding))
-      data->input_encodings.push_back(encoding);
-  }
+  if (source)
+    *source = FROM_FALLBACK;
+  return fallback_default_search_.get();
+}
 
-  url_dict->GetString(kSearchTermsReplacementKey,
-                      &data->search_terms_replacement_key);
-
-  url_dict->GetBoolean(kCreatedByPolicy, &data->created_by_policy);
-
-  data->show_in_default_list = true;
-
-  return true;
+DefaultSearchManager::Source
+DefaultSearchManager::GetDefaultSearchEngineSource() const {
+  Source source;
+  GetDefaultSearchEngine(&source);
+  return source;
 }
 
 void DefaultSearchManager::SetUserSelectedDefaultSearchEngine(
     const TemplateURLData& data) {
+  if (!pref_service_) {
+    prefs_default_search_.reset(new TemplateURLData(data));
+    MergePrefsDataWithPrepopulated();
+    NotifyObserver();
+    return;
+  }
+
   base::DictionaryValue url_dict;
   url_dict.SetString(kID, base::Int64ToString(data.id));
   url_dict.SetString(kShortName, data.short_name);
@@ -201,8 +170,10 @@
 
   url_dict.SetBoolean(kSafeForAutoReplace, data.safe_for_autoreplace);
 
-  url_dict.SetDouble(kDateCreated, data.date_created.ToInternalValue());
-  url_dict.SetDouble(kLastModified, data.last_modified.ToInternalValue());
+  url_dict.SetString(kDateCreated,
+                     base::Int64ToString(data.date_created.ToInternalValue()));
+  url_dict.SetString(kLastModified,
+                     base::Int64ToString(data.last_modified.ToInternalValue()));
   url_dict.SetInteger(kUsageCount, data.usage_count);
 
   scoped_ptr<base::ListValue> alternate_urls(new base::ListValue);
@@ -226,9 +197,209 @@
 
   url_dict.SetBoolean(kCreatedByPolicy, data.created_by_policy);
 
-  pref_service_->Set(kDefaultSearchProviderData, url_dict);
+  pref_service_->Set(kDefaultSearchProviderDataPrefName, url_dict);
+}
+
+void DefaultSearchManager::SetExtensionControlledDefaultSearchEngine(
+    const TemplateURLData& data) {
+  extension_default_search_.reset(new TemplateURLData(data));
+  if (GetDefaultSearchEngineSource() == FROM_EXTENSION)
+    NotifyObserver();
+}
+
+void DefaultSearchManager::ClearExtensionControlledDefaultSearchEngine() {
+  Source old_source = GetDefaultSearchEngineSource();
+  extension_default_search_.reset();
+  if (old_source == FROM_EXTENSION)
+    NotifyObserver();
 }
 
 void DefaultSearchManager::ClearUserSelectedDefaultSearchEngine() {
-  pref_service_->ClearPref(kDefaultSearchProviderData);
+  if (pref_service_) {
+    pref_service_->ClearPref(kDefaultSearchProviderDataPrefName);
+  } else {
+    prefs_default_search_.reset();
+    NotifyObserver();
+  }
+}
+
+void DefaultSearchManager::OnDefaultSearchPrefChanged() {
+  Source source = GetDefaultSearchEngineSource();
+  LoadDefaultSearchEngineFromPrefs();
+
+  // If we were/are FROM_USER or FROM_POLICY the effective DSE may have changed.
+  if (source != FROM_USER && source != FROM_POLICY)
+    source = GetDefaultSearchEngineSource();
+  if (source == FROM_USER || source == FROM_POLICY)
+    NotifyObserver();
+}
+
+void DefaultSearchManager::OnOverridesPrefChanged() {
+  LoadPrepopulatedDefaultSearch();
+
+  TemplateURLData* effective_data = GetDefaultSearchEngine(NULL);
+  if (effective_data && effective_data->prepopulate_id) {
+    // A user-selected, policy-selected or fallback pre-populated engine is
+    // active and may have changed with this event.
+    NotifyObserver();
+  }
+}
+
+void DefaultSearchManager::MergePrefsDataWithPrepopulated() {
+  if (!prefs_default_search_ || !prefs_default_search_->prepopulate_id)
+    return;
+
+  size_t default_search_index;
+  ScopedVector<TemplateURLData> prepopulated_urls =
+      TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service_,
+                                                         &default_search_index);
+
+  for (size_t i = 0; i < prepopulated_urls.size(); ++i) {
+    if (prepopulated_urls[i]->prepopulate_id ==
+        prefs_default_search_->prepopulate_id) {
+      if (!prefs_default_search_->safe_for_autoreplace) {
+        prepopulated_urls[i]->safe_for_autoreplace = false;
+        prepopulated_urls[i]->SetKeyword(prefs_default_search_->keyword());
+        prepopulated_urls[i]->short_name = prefs_default_search_->short_name;
+      }
+      prepopulated_urls[i]->id = prefs_default_search_->id;
+      prepopulated_urls[i]->sync_guid = prefs_default_search_->sync_guid;
+      prepopulated_urls[i]->date_created = prefs_default_search_->date_created;
+      prepopulated_urls[i]->last_modified =
+          prefs_default_search_->last_modified;
+      prefs_default_search_.reset(prepopulated_urls[i]);
+      prepopulated_urls.weak_erase(prepopulated_urls.begin() + i);
+      return;
+    }
+  }
+}
+
+void DefaultSearchManager::LoadDefaultSearchEngineFromPrefs() {
+  if (!pref_service_)
+    return;
+
+  prefs_default_search_.reset();
+  const PrefService::Preference* pref =
+      pref_service_->FindPreference(kDefaultSearchProviderDataPrefName);
+  DCHECK(pref);
+  default_search_controlled_by_policy_ = pref->IsManaged();
+
+  const base::DictionaryValue* url_dict =
+      pref_service_->GetDictionary(kDefaultSearchProviderDataPrefName);
+  if (url_dict->empty())
+    return;
+
+  if (default_search_controlled_by_policy_) {
+    bool disabled_by_policy = false;
+    if (url_dict->GetBoolean(kDisabledByPolicy, &disabled_by_policy) &&
+        disabled_by_policy)
+      return;
+  }
+
+  std::string search_url;
+  base::string16 keyword;
+  url_dict->GetString(kURL, &search_url);
+  url_dict->GetString(kKeyword, &keyword);
+  if (search_url.empty() || keyword.empty())
+    return;
+
+  prefs_default_search_.reset(new TemplateURLData);
+  prefs_default_search_->SetKeyword(keyword);
+  prefs_default_search_->SetURL(search_url);
+
+  std::string id;
+  url_dict->GetString(kID, &id);
+  base::StringToInt64(id, &prefs_default_search_->id);
+  url_dict->GetString(kShortName, &prefs_default_search_->short_name);
+  url_dict->GetInteger(kPrepopulateID, &prefs_default_search_->prepopulate_id);
+  url_dict->GetString(kSyncGUID, &prefs_default_search_->sync_guid);
+
+  url_dict->GetString(kSuggestionsURL, &prefs_default_search_->suggestions_url);
+  url_dict->GetString(kInstantURL, &prefs_default_search_->instant_url);
+  url_dict->GetString(kImageURL, &prefs_default_search_->image_url);
+  url_dict->GetString(kNewTabURL, &prefs_default_search_->new_tab_url);
+
+  std::string favicon_url;
+  std::string originating_url;
+  url_dict->GetString(kFaviconURL, &favicon_url);
+  url_dict->GetString(kOriginatingURL, &originating_url);
+  prefs_default_search_->favicon_url = GURL(favicon_url);
+  prefs_default_search_->originating_url = GURL(originating_url);
+
+  url_dict->GetString(kSearchURLPostParams,
+                      &prefs_default_search_->search_url_post_params);
+  url_dict->GetString(kSuggestionsURLPostParams,
+                      &prefs_default_search_->suggestions_url_post_params);
+  url_dict->GetString(kInstantURLPostParams,
+                      &prefs_default_search_->instant_url_post_params);
+  url_dict->GetString(kImageURLPostParams,
+                      &prefs_default_search_->image_url_post_params);
+
+  url_dict->GetBoolean(kSafeForAutoReplace,
+                       &prefs_default_search_->safe_for_autoreplace);
+
+  std::string date_created_str;
+  std::string last_modified_str;
+  url_dict->GetString(kDateCreated, &date_created_str);
+  url_dict->GetString(kLastModified, &last_modified_str);
+
+  int64 date_created = 0;
+  if (base::StringToInt64(date_created_str, &date_created)) {
+    prefs_default_search_->date_created =
+        base::Time::FromInternalValue(date_created);
+  }
+
+  int64 last_modified = 0;
+  if (base::StringToInt64(date_created_str, &last_modified)) {
+    prefs_default_search_->last_modified =
+        base::Time::FromInternalValue(last_modified);
+  }
+
+  url_dict->GetInteger(kUsageCount, &prefs_default_search_->usage_count);
+
+  const base::ListValue* alternate_urls = NULL;
+  if (url_dict->GetList(kAlternateURLs, &alternate_urls)) {
+    for (base::ListValue::const_iterator it = alternate_urls->begin();
+         it != alternate_urls->end();
+         ++it) {
+      std::string alternate_url;
+      if ((*it)->GetAsString(&alternate_url))
+        prefs_default_search_->alternate_urls.push_back(alternate_url);
+    }
+  }
+
+  const base::ListValue* encodings = NULL;
+  if (url_dict->GetList(kInputEncodings, &encodings)) {
+    for (base::ListValue::const_iterator it = encodings->begin();
+         it != encodings->end();
+         ++it) {
+      std::string encoding;
+      if ((*it)->GetAsString(&encoding))
+        prefs_default_search_->input_encodings.push_back(encoding);
+    }
+  }
+
+  url_dict->GetString(kSearchTermsReplacementKey,
+                      &prefs_default_search_->search_terms_replacement_key);
+
+  url_dict->GetBoolean(kCreatedByPolicy,
+                       &prefs_default_search_->created_by_policy);
+
+  prefs_default_search_->show_in_default_list = true;
+  MergePrefsDataWithPrepopulated();
+}
+
+void DefaultSearchManager::LoadPrepopulatedDefaultSearch() {
+  scoped_ptr<TemplateURLData> data =
+      TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(pref_service_);
+  fallback_default_search_ = data.Pass();
+  MergePrefsDataWithPrepopulated();
+}
+
+void DefaultSearchManager::NotifyObserver() {
+  if (!change_observer_.is_null()) {
+    Source source = FROM_FALLBACK;
+    TemplateURLData* data = GetDefaultSearchEngine(&source);
+    change_observer_.Run(data, source);
+  }
 }
diff --git a/chrome/browser/search_engines/default_search_manager.h b/chrome/browser/search_engines/default_search_manager.h
index 9035564..95a5bfb 100644
--- a/chrome/browser/search_engines/default_search_manager.h
+++ b/chrome/browser/search_engines/default_search_manager.h
@@ -5,7 +5,10 @@
 #ifndef CHROME_BROWSER_SEARCH_ENGINES_DEFAULT_SEARCH_MANAGER_H_
 #define CHROME_BROWSER_SEARCH_ENGINES_DEFAULT_SEARCH_MANAGER_H_
 
+#include "base/callback.h"
 #include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/prefs/pref_change_registrar.h"
 
 namespace base {
 class DictionaryValue;
@@ -21,9 +24,10 @@
 
 // DefaultSearchManager handles the loading and writing of the user's default
 // search engine selection to and from prefs.
-
 class DefaultSearchManager {
  public:
+  static const char kDefaultSearchProviderDataPrefName[];
+
   static const char kID[];
   static const char kShortName[];
   static const char kKeyword[];
@@ -55,7 +59,18 @@
   static const char kCreatedByPolicy[];
   static const char kDisabledByPolicy[];
 
-  explicit DefaultSearchManager(PrefService* pref_service);
+  enum Source {
+    FROM_FALLBACK = 0,
+    FROM_USER,
+    FROM_EXTENSION,
+    FROM_POLICY,
+  };
+
+  typedef base::Callback<void(const TemplateURLData*, Source)> ObserverCallback;
+
+  DefaultSearchManager(PrefService* pref_service,
+                       const ObserverCallback& change_observer);
+
   ~DefaultSearchManager();
 
   // Register prefs needed for tracking the default search provider.
@@ -65,17 +80,78 @@
   static void AddPrefValueToMap(base::DictionaryValue* value,
                                 PrefValueMap* pref_value_map);
 
-  // Read default search provider data from |pref_service_|.
-  bool GetDefaultSearchEngine(TemplateURLData* url);
+  // Gets a pointer to the current Default Search Engine. If NULL, indicates
+  // that Default Search is explicitly disabled. |source|, if not NULL, will be
+  // filled in with the source of the result.
+  TemplateURLData* GetDefaultSearchEngine(Source* source) const;
+
+  // Gets the source of the current Default Search Engine value.
+  Source GetDefaultSearchEngineSource() const;
 
   // Write default search provider data to |pref_service_|.
   void SetUserSelectedDefaultSearchEngine(const TemplateURLData& data);
 
-  // Clear the user's default search provider choice from |pref_service_|.
+  // Override the default search provider with an extension.
+  void SetExtensionControlledDefaultSearchEngine(const TemplateURLData& data);
+
+  // Clear the extension-provided default search engine. Does not explicitly
+  // disable Default Search. The new current default search engine will be
+  // defined by policy, extensions, or pre-populated data.
+  void ClearExtensionControlledDefaultSearchEngine();
+
+  // Clear the user's default search provider choice from |pref_service_|. Does
+  // not explicitly disable Default Search. The new default search
+  // engine will be defined by policy, extensions, or pre-populated data.
   void ClearUserSelectedDefaultSearchEngine();
 
  private:
+  // Handles changes to kDefaultSearchProviderData pref. This includes sync and
+  // policy changes. Calls LoadDefaultSearchEngineFromPrefs() and
+  // NotifyObserver() if the effective DSE might have changed.
+  void OnDefaultSearchPrefChanged();
+
+  // Handles changes to kSearchProviderOverrides pref. Calls
+  // LoadPrepopulatedDefaultSearch() and NotifyObserver() if the effective DSE
+  // might have changed.
+  void OnOverridesPrefChanged();
+
+  // Updates |prefs_default_search_| with values from its corresponding
+  // pre-populated search provider record, if any.
+  void MergePrefsDataWithPrepopulated();
+
+  // Reads default search provider data from |pref_service_|, updating
+  // |prefs_default_search_| and |default_search_controlled_by_policy_|.
+  // Invokes MergePrefsDataWithPrepopulated().
+  void LoadDefaultSearchEngineFromPrefs();
+
+  // Reads pre-populated search providers, which will be built-in or overridden
+  // by kSearchProviderOverrides. Updates |fallback_default_search_|. Invoke
+  // MergePrefsDataWithPrepopulated().
+  void LoadPrepopulatedDefaultSearch();
+
+  // Invokes |change_observer_| if it is not NULL.
+  void NotifyObserver();
+
   PrefService* pref_service_;
+  const ObserverCallback change_observer_;
+  PrefChangeRegistrar pref_change_registrar_;
+
+  // Default search engine provided by pre-populated data or by the
+  // |kSearchProviderOverrides| pref. This will be used when no other default
+  // search engine has been selected.
+  scoped_ptr<TemplateURLData> fallback_default_search_;
+
+  // Default search engine provided by prefs (either user prefs or policy
+  // prefs). This will be null if no value was set in the pref store.
+  scoped_ptr<TemplateURLData> extension_default_search_;
+
+  // Default search engine provided by extension (usings Settings Override API).
+  // This will be null if there are no extensions installed which provide
+  // default search engines.
+  scoped_ptr<TemplateURLData> prefs_default_search_;
+
+  // True if the default search is currently enforced by policy.
+  bool default_search_controlled_by_policy_;
 
   DISALLOW_COPY_AND_ASSIGN(DefaultSearchManager);
 };
diff --git a/chrome/browser/search_engines/default_search_manager_unittest.cc b/chrome/browser/search_engines/default_search_manager_unittest.cc
index 9dd2cb5..fd6f99f 100644
--- a/chrome/browser/search_engines/default_search_manager_unittest.cc
+++ b/chrome/browser/search_engines/default_search_manager_unittest.cc
@@ -3,19 +3,27 @@
 // found in the LICENSE file.
 
 #include "base/files/scoped_temp_dir.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/search_engines/default_search_manager.h"
 #include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_pref_service_syncable.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
+// A dictionary to hold all data related to the Default Search Engine.
+// Eventually, this should replace all the data stored in the
+// default_search_provider.* prefs.
+const char kDefaultSearchProviderData[] =
+    "default_search_provider_data.template_url_data";
 
-// Checks that the two TemplateURLs are similar. It does not check the id, the
+// Checks that the two TemplateURLs are similar. Does not check the id, the
 // date_created or the last_modified time.  Neither pointer should be NULL.
 void ExpectSimilar(const TemplateURLData* expected,
                    const TemplateURLData* actual) {
@@ -35,6 +43,98 @@
             actual->search_terms_replacement_key);
 }
 
+// TODO(caitkp): TemplateURLData-ify this.
+void SetOverrides(TestingPrefServiceSyncable* prefs, bool update) {
+  prefs->SetUserPref(prefs::kSearchProviderOverridesVersion,
+                     base::Value::CreateIntegerValue(1));
+  base::ListValue* overrides = new base::ListValue;
+  scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
+
+  entry->SetString("name", update ? "new_foo" : "foo");
+  entry->SetString("keyword", update ? "new_fook" : "fook");
+  entry->SetString("search_url", "http://foo.com/s?q={searchTerms}");
+  entry->SetString("favicon_url", "http://foi.com/favicon.ico");
+  entry->SetString("encoding", "UTF-8");
+  entry->SetInteger("id", 1001);
+  entry->SetString("suggest_url", "http://foo.com/suggest?q={searchTerms}");
+  entry->SetString("instant_url", "http://foo.com/instant?q={searchTerms}");
+  base::ListValue* alternate_urls = new base::ListValue;
+  alternate_urls->AppendString("http://foo.com/alternate?q={searchTerms}");
+  entry->Set("alternate_urls", alternate_urls);
+  entry->SetString("search_terms_replacement_key", "espv");
+  overrides->Append(entry->DeepCopy());
+
+  entry.reset(new base::DictionaryValue);
+  entry->SetInteger("id", 1002);
+  entry->SetString("name", update ? "new_bar" : "bar");
+  entry->SetString("keyword", update ? "new_bark" : "bark");
+  entry->SetString("encoding", std::string());
+  overrides->Append(entry->DeepCopy());
+  entry->SetInteger("id", 1003);
+  entry->SetString("name", "baz");
+  entry->SetString("keyword", "bazk");
+  entry->SetString("encoding", "UTF-8");
+  overrides->Append(entry->DeepCopy());
+  prefs->SetUserPref(prefs::kSearchProviderOverrides, overrides);
+}
+
+void SetPolicy(TestingPrefServiceSyncable* prefs,
+               bool enabled,
+               TemplateURLData* data) {
+  if (enabled) {
+    EXPECT_FALSE(data->keyword().empty());
+    EXPECT_FALSE(data->url().empty());
+  }
+  scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
+  entry->SetString(DefaultSearchManager::kShortName, data->short_name);
+  entry->SetString(DefaultSearchManager::kKeyword, data->keyword());
+  entry->SetString(DefaultSearchManager::kURL, data->url());
+  entry->SetString(DefaultSearchManager::kFaviconURL, data->favicon_url.spec());
+  entry->SetString(DefaultSearchManager::kSuggestionsURL,
+                   data->suggestions_url);
+  entry->SetBoolean(DefaultSearchManager::kSafeForAutoReplace,
+                    data->safe_for_autoreplace);
+  scoped_ptr<base::ListValue> alternate_urls(new base::ListValue);
+  for (std::vector<std::string>::const_iterator it =
+           data->alternate_urls.begin();
+       it != data->alternate_urls.end();
+       ++it) {
+    alternate_urls->AppendString(*it);
+  }
+  entry->Set(DefaultSearchManager::kAlternateURLs, alternate_urls.release());
+
+  scoped_ptr<base::ListValue> encodings(new base::ListValue);
+  for (std::vector<std::string>::const_iterator it =
+           data->input_encodings.begin();
+       it != data->input_encodings.end();
+       ++it) {
+    encodings->AppendString(*it);
+  }
+  entry->Set(DefaultSearchManager::kInputEncodings, encodings.release());
+
+  entry->SetString(DefaultSearchManager::kSearchTermsReplacementKey,
+                   data->search_terms_replacement_key);
+  entry->SetBoolean(DefaultSearchManager::kDisabledByPolicy, !enabled);
+  prefs->SetManagedPref(kDefaultSearchProviderData, entry.release());
+}
+
+scoped_ptr<TemplateURLData> GenerateDummyTemplateURLData(std::string type) {
+  scoped_ptr<TemplateURLData> data(new TemplateURLData());
+  data->short_name = base::UTF8ToUTF16(std::string(type).append("name"));
+  data->SetKeyword(base::UTF8ToUTF16(std::string(type).append("key")));
+  data->SetURL(std::string("http://").append(type).append("foo/{searchTerms}"));
+  data->suggestions_url = std::string("http://").append(type).append("sugg");
+  data->alternate_urls.push_back(
+      std::string("http://").append(type).append("foo/alt"));
+  data->favicon_url = GURL("http://icon1");
+  data->safe_for_autoreplace = true;
+  data->show_in_default_list = true;
+  base::SplitString("UTF-8;UTF-16", ';', &data->input_encodings);
+  data->date_created = base::Time();
+  data->last_modified = base::Time();
+  return data.Pass();
+}
+
 }  // namespace
 
 class DefaultSearchManagerTest : public testing::Test {
@@ -44,9 +144,10 @@
   virtual void SetUp() OVERRIDE {
     pref_service_.reset(new TestingPrefServiceSyncable);
     DefaultSearchManager::RegisterProfilePrefs(pref_service_->registry());
+    TemplateURLPrepopulateData::RegisterProfilePrefs(pref_service_->registry());
   }
 
-  PrefService* pref_service() { return pref_service_.get(); }
+  TestingPrefServiceSyncable* pref_service() { return pref_service_.get(); }
 
  private:
   scoped_ptr<TestingPrefServiceSyncable> pref_service_;
@@ -56,7 +157,8 @@
 
 // Test that a TemplateURLData object is properly written and read from Prefs.
 TEST_F(DefaultSearchManagerTest, ReadAndWritePref) {
-  DefaultSearchManager manager(pref_service());
+  DefaultSearchManager manager(pref_service(),
+                               DefaultSearchManager::ObserverCallback());
   TemplateURLData data;
   data.short_name = base::UTF8ToUTF16("name1");
   data.SetKeyword(base::UTF8ToUTF16("key1"));
@@ -71,14 +173,150 @@
   data.last_modified = base::Time();
 
   manager.SetUserSelectedDefaultSearchEngine(data);
-  TemplateURLData read_data;
-  manager.GetDefaultSearchEngine(&read_data);
-  ExpectSimilar(&data, &read_data);
+  TemplateURLData* read_data = manager.GetDefaultSearchEngine(NULL);
+  ExpectSimilar(&data, read_data);
 }
 
-// Test that there is no default value set in the pref.
-TEST_F(DefaultSearchManagerTest, ReadDefaultPref) {
-  DefaultSearchManager manager(pref_service());
-  TemplateURLData read_data;
-  EXPECT_FALSE(manager.GetDefaultSearchEngine(&read_data));
+// Test DefaultSearchmanager handles user-selected DSEs correctly.
+TEST_F(DefaultSearchManagerTest, DefaultSearchSetByUserPref) {
+  size_t default_search_index = 0;
+  DefaultSearchManager manager(pref_service(),
+                               DefaultSearchManager::ObserverCallback());
+  ScopedVector<TemplateURLData> prepopulated_urls =
+      TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service(),
+                                                         &default_search_index);
+  DefaultSearchManager::Source source = DefaultSearchManager::FROM_POLICY;
+  // If no user pref is set, we should use the pre-populated values.
+  ExpectSimilar(prepopulated_urls[default_search_index],
+                manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK, source);
+
+  // Setting a user pref overrides the pre-populated values.
+  scoped_ptr<TemplateURLData> data = GenerateDummyTemplateURLData("user");
+  manager.SetUserSelectedDefaultSearchEngine(*data.get());
+
+  ExpectSimilar(data.get(), manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
+
+  // Updating the user pref (externally to this instance of
+  // DefaultSearchManager) triggers an update.
+  scoped_ptr<TemplateURLData> new_data = GenerateDummyTemplateURLData("user2");
+  DefaultSearchManager other_manager(pref_service(),
+                                     DefaultSearchManager::ObserverCallback());
+  other_manager.SetUserSelectedDefaultSearchEngine(*new_data.get());
+
+  ExpectSimilar(new_data.get(), manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
+
+  // Clearing the user pref should cause the default search to revert to the
+  // prepopulated vlaues.
+  manager.ClearUserSelectedDefaultSearchEngine();
+  ExpectSimilar(prepopulated_urls[default_search_index],
+                manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK, source);
+}
+
+// Test that DefaultSearch manager detects changes to kSearchProviderOverrides.
+TEST_F(DefaultSearchManagerTest, DefaultSearchSetByOverrides) {
+  SetOverrides(pref_service(), false);
+  size_t default_search_index = 0;
+  DefaultSearchManager manager(pref_service(),
+                               DefaultSearchManager::ObserverCallback());
+  ScopedVector<TemplateURLData> prepopulated_urls =
+      TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service(),
+                                                         &default_search_index);
+
+  DefaultSearchManager::Source source = DefaultSearchManager::FROM_POLICY;
+  TemplateURLData first_default(*manager.GetDefaultSearchEngine(&source));
+  ExpectSimilar(prepopulated_urls[default_search_index], &first_default);
+  EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK, source);
+
+  // Update the overrides:
+  SetOverrides(pref_service(), true);
+  prepopulated_urls = TemplateURLPrepopulateData::GetPrepopulatedEngines(
+      pref_service(), &default_search_index);
+
+  // Make sure DefaultSearchManager updated:
+  ExpectSimilar(prepopulated_urls[default_search_index],
+                manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK, source);
+  EXPECT_NE(manager.GetDefaultSearchEngine(NULL)->short_name,
+            first_default.short_name);
+  EXPECT_NE(manager.GetDefaultSearchEngine(NULL)->keyword(),
+            first_default.keyword());
+}
+
+// Test DefaultSearchManager handles policy-enforced DSEs correctly.
+TEST_F(DefaultSearchManagerTest, DefaultSearchSetByPolicy) {
+  DefaultSearchManager manager(pref_service(),
+                               DefaultSearchManager::ObserverCallback());
+  scoped_ptr<TemplateURLData> data = GenerateDummyTemplateURLData("user");
+  manager.SetUserSelectedDefaultSearchEngine(*data.get());
+
+  DefaultSearchManager::Source source = DefaultSearchManager::FROM_FALLBACK;
+  ExpectSimilar(data.get(), manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
+
+  scoped_ptr<TemplateURLData> policy_data =
+      GenerateDummyTemplateURLData("policy");
+  SetPolicy(pref_service(), true, policy_data.get());
+
+  ExpectSimilar(policy_data.get(), manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_POLICY, source);
+
+  TemplateURLData null_policy_data;
+  SetPolicy(pref_service(), false, &null_policy_data);
+  EXPECT_EQ(NULL, manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_POLICY, source);
+
+  pref_service()->RemoveManagedPref(kDefaultSearchProviderData);
+  ExpectSimilar(data.get(), manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
+}
+
+// Test DefaultSearchManager handles extension-controlled DSEs correctly.
+TEST_F(DefaultSearchManagerTest, DefaultSearchSetByExtension) {
+  DefaultSearchManager manager(pref_service(),
+                               DefaultSearchManager::ObserverCallback());
+  scoped_ptr<TemplateURLData> data = GenerateDummyTemplateURLData("user");
+  manager.SetUserSelectedDefaultSearchEngine(*data);
+
+  DefaultSearchManager::Source source = DefaultSearchManager::FROM_FALLBACK;
+  ExpectSimilar(data.get(), manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
+
+  // Extension trumps prefs:
+  scoped_ptr<TemplateURLData> extension_data_1 =
+      GenerateDummyTemplateURLData("ext1");
+  manager.SetExtensionControlledDefaultSearchEngine(*extension_data_1);
+
+  ExpectSimilar(extension_data_1.get(),
+                manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_EXTENSION, source);
+
+  // Policy trumps extension:
+  scoped_ptr<TemplateURLData> policy_data =
+      GenerateDummyTemplateURLData("policy");
+  SetPolicy(pref_service(), true, policy_data.get());
+
+  ExpectSimilar(policy_data.get(), manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_POLICY, source);
+  pref_service()->RemoveManagedPref(kDefaultSearchProviderData);
+
+  // Extensions trump each other:
+  scoped_ptr<TemplateURLData> extension_data_2 =
+      GenerateDummyTemplateURLData("ext2");
+  scoped_ptr<TemplateURLData> extension_data_3 =
+      GenerateDummyTemplateURLData("ext3");
+  manager.SetExtensionControlledDefaultSearchEngine(*extension_data_2);
+  manager.SetExtensionControlledDefaultSearchEngine(*extension_data_3);
+
+  ExpectSimilar(extension_data_3.get(),
+                manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_EXTENSION, source);
+
+  manager.ClearExtensionControlledDefaultSearchEngine();
+
+  ExpectSimilar(data.get(), manager.GetDefaultSearchEngine(&source));
+  EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
 }
diff --git a/chrome/browser/search_engines/default_search_pref_migration.cc b/chrome/browser/search_engines/default_search_pref_migration.cc
new file mode 100644
index 0000000..835254a
--- /dev/null
+++ b/chrome/browser/search_engines/default_search_pref_migration.cc
@@ -0,0 +1,78 @@
+// 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.
+
+#include "chrome/browser/search_engines/default_search_pref_migration.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
+#include "base/prefs/pref_service.h"
+#include "chrome/browser/search_engines/default_search_manager.h"
+#include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/search_engines/template_url_service.h"
+
+namespace {
+
+// Loads the user-selected DSE (if there is one, and it's not masked by policy
+// or an extension) from legacy preferences.
+scoped_ptr<TemplateURLData> LoadDefaultSearchProviderFromPrefs(
+    PrefService* pref_service) {
+  scoped_ptr<TemplateURLData> legacy_dse_from_prefs;
+  bool legacy_is_managed = false;
+  TemplateURLService::LoadDefaultSearchProviderFromPrefs(
+      pref_service, &legacy_dse_from_prefs, &legacy_is_managed);
+  return legacy_is_managed ?
+      scoped_ptr<TemplateURLData>() : legacy_dse_from_prefs.Pass();
+}
+
+void MigrateDefaultSearchPref(PrefService* pref_service) {
+  DCHECK(pref_service);
+
+  scoped_ptr<TemplateURLData> legacy_dse_from_prefs =
+      LoadDefaultSearchProviderFromPrefs(pref_service);
+  if (!legacy_dse_from_prefs)
+    return;
+
+  DefaultSearchManager default_search_manager(
+      pref_service, DefaultSearchManager::ObserverCallback());
+  DefaultSearchManager::Source modern_source;
+  TemplateURLData* modern_value =
+      default_search_manager.GetDefaultSearchEngine(&modern_source);
+  if (modern_source == DefaultSearchManager::FROM_FALLBACK) {
+    // |modern_value| is the prepopulated default. If it matches the legacy DSE
+    // we assume it is not a user-selected value.
+    if (!modern_value ||
+        legacy_dse_from_prefs->prepopulate_id != modern_value->prepopulate_id) {
+      // This looks like a user-selected value, so let's migrate it.
+      // TODO(erikwright): Remove this migration logic when this stat approaches
+      // zero.
+      UMA_HISTOGRAM_BOOLEAN("Search.MigratedPrefToDictionaryValue", true);
+      default_search_manager.SetUserSelectedDefaultSearchEngine(
+          *legacy_dse_from_prefs);
+    }
+  }
+
+  // TODO(erikwright): Clear the legacy value when the modern value is the
+  // authority.
+}
+
+void OnPrefsInitialized(PrefService* pref_service,
+                        bool pref_service_initialization_success) {
+  MigrateDefaultSearchPref(pref_service);
+}
+
+}  // namespace
+
+void ConfigureDefaultSearchPrefMigrationToDictionaryValue(
+    PrefService* pref_service) {
+  if (pref_service->GetInitializationStatus() ==
+      PrefService::INITIALIZATION_STATUS_WAITING) {
+    pref_service->AddPrefInitObserver(
+        base::Bind(&OnPrefsInitialized, base::Unretained(pref_service)));
+  } else {
+    MigrateDefaultSearchPref(pref_service);
+  }
+}
diff --git a/chrome/browser/search_engines/default_search_pref_migration.h b/chrome/browser/search_engines/default_search_pref_migration.h
new file mode 100644
index 0000000..a749006
--- /dev/null
+++ b/chrome/browser/search_engines/default_search_pref_migration.h
@@ -0,0 +1,17 @@
+// 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.
+
+#ifndef CHROME_BROWSER_SEARCH_ENGINES_DEFAULT_SEARCH_PREF_MIGRATION_H_
+#define CHROME_BROWSER_SEARCH_ENGINES_DEFAULT_SEARCH_PREF_MIGRATION_H_
+
+class PrefService;
+
+// Migrates a DSE value stored in separate String/List/..Value preferences by
+// M35 or earlier to the new single DictionaryValue used in M36.
+// Operates immediately if |pref_service| is fully initialized. Otherwise, waits
+// for the PrefService to load using an observer.
+void ConfigureDefaultSearchPrefMigrationToDictionaryValue(
+    PrefService* pref_service);
+
+#endif  // CHROME_BROWSER_SEARCH_ENGINES_DEFAULT_SEARCH_PREF_MIGRATION_H_
diff --git a/chrome/browser/search_engines/default_search_pref_migration_unittest.cc b/chrome/browser/search_engines/default_search_pref_migration_unittest.cc
new file mode 100644
index 0000000..1813670
--- /dev/null
+++ b/chrome/browser/search_engines/default_search_pref_migration_unittest.cc
@@ -0,0 +1,180 @@
+// 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.
+
+#include "chrome/browser/search_engines/default_search_pref_migration.h"
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/browser/search_engines/template_url_service_test_util.h"
+#include "chrome/test/base/testing_pref_service_syncable.h"
+#include "chrome/test/base/testing_profile.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class DefaultSearchPrefMigrationTest : public testing::Test {
+ public:
+  DefaultSearchPrefMigrationTest();
+
+  // testing::Test:
+  virtual void SetUp() OVERRIDE;
+  virtual void TearDown() OVERRIDE;
+
+  scoped_ptr<TemplateURL> CreateKeyword(const std::string& short_name,
+                                        const std::string& keyword,
+                                        const std::string& url);
+
+  TemplateURLServiceTestUtil* test_util() { return &test_util_; }
+
+ private:
+  TemplateURLServiceTestUtil test_util_;
+
+  DISALLOW_COPY_AND_ASSIGN(DefaultSearchPrefMigrationTest);
+};
+
+DefaultSearchPrefMigrationTest::DefaultSearchPrefMigrationTest() {
+}
+
+void DefaultSearchPrefMigrationTest::SetUp() {
+  test_util_.SetUp();
+}
+
+void DefaultSearchPrefMigrationTest::TearDown() {
+  test_util_.TearDown();
+}
+
+scoped_ptr<TemplateURL> DefaultSearchPrefMigrationTest::CreateKeyword(
+    const std::string& short_name,
+    const std::string& keyword,
+    const std::string& url) {
+  TemplateURLData data;
+  data.short_name = base::ASCIIToUTF16(short_name);
+  data.SetKeyword(base::ASCIIToUTF16(keyword));
+  data.SetURL(url);
+  scoped_ptr<TemplateURL> t_url(new TemplateURL(test_util_.profile(), data));
+  return t_url.Pass();
+}
+
+TEST_F(DefaultSearchPrefMigrationTest, MigrateUserSelectedValue) {
+  scoped_ptr<TemplateURL> t_url(
+      CreateKeyword("name1", "key1", "http://foo1/{searchTerms}"));
+  // Store a value in the legacy location.
+  test_util()->model()->SaveDefaultSearchProviderToPrefs(
+      t_url.get(), test_util()->profile()->GetPrefs());
+
+  // Run the migration.
+  ConfigureDefaultSearchPrefMigrationToDictionaryValue(
+      test_util()->profile()->GetPrefs());
+
+  // Test that it was migrated.
+  DefaultSearchManager manager(test_util()->profile()->GetPrefs(),
+                               DefaultSearchManager::ObserverCallback());
+  TemplateURLData* modern_default = manager.GetDefaultSearchEngine(NULL);
+  ASSERT_TRUE(modern_default);
+  EXPECT_EQ(t_url->short_name(), modern_default->short_name);
+  EXPECT_EQ(t_url->keyword(), modern_default->keyword());
+  EXPECT_EQ(t_url->url(), modern_default->url());
+}
+
+TEST_F(DefaultSearchPrefMigrationTest, ModernValuePresent) {
+  scoped_ptr<TemplateURL> t_url(
+      CreateKeyword("name1", "key1", "http://foo1/{searchTerms}"));
+  scoped_ptr<TemplateURL> t_url2(
+      CreateKeyword("name2", "key2", "http://foo2/{searchTerms}"));
+  // Store a value in the legacy location.
+  test_util()->model()->SaveDefaultSearchProviderToPrefs(
+      t_url.get(), test_util()->profile()->GetPrefs());
+
+  // Store another value in the modern location.
+  DefaultSearchManager(test_util()->profile()->GetPrefs(),
+                       DefaultSearchManager::ObserverCallback())
+      .SetUserSelectedDefaultSearchEngine(t_url2->data());
+
+  // Run the migration.
+  ConfigureDefaultSearchPrefMigrationToDictionaryValue(
+      test_util()->profile()->GetPrefs());
+
+  // Test that no migration occurred. The modern value is left intact.
+  DefaultSearchManager manager(test_util()->profile()->GetPrefs(),
+                               DefaultSearchManager::ObserverCallback());
+  TemplateURLData* modern_default = manager.GetDefaultSearchEngine(NULL);
+  ASSERT_TRUE(modern_default);
+  EXPECT_EQ(t_url2->short_name(), modern_default->short_name);
+  EXPECT_EQ(t_url2->keyword(), modern_default->keyword());
+  EXPECT_EQ(t_url2->url(), modern_default->url());
+}
+
+TEST_F(DefaultSearchPrefMigrationTest,
+       AutomaticallySelectedValueIsNotMigrated) {
+  test_util()->VerifyLoad();
+  scoped_ptr<TemplateURLData> legacy_default;
+  bool legacy_is_managed = false;
+  // The initialization of the TemplateURLService will have stored the
+  // pre-populated DSE in the legacy location in prefs.
+  ASSERT_TRUE(TemplateURLService::LoadDefaultSearchProviderFromPrefs(
+      test_util()->profile()->GetPrefs(), &legacy_default, &legacy_is_managed));
+  EXPECT_FALSE(legacy_is_managed);
+  EXPECT_TRUE(legacy_default);
+  EXPECT_GT(legacy_default->prepopulate_id, 0);
+
+  // Run the migration.
+  ConfigureDefaultSearchPrefMigrationToDictionaryValue(
+      test_util()->profile()->GetPrefs());
+
+  // Test that the legacy value is not migrated, as it is not user-selected.
+  ASSERT_EQ(DefaultSearchManager::FROM_FALLBACK,
+            DefaultSearchManager(test_util()->profile()->GetPrefs(),
+                                 DefaultSearchManager::ObserverCallback())
+                .GetDefaultSearchEngineSource());
+}
+
+TEST_F(DefaultSearchPrefMigrationTest, ManagedValueIsNotMigrated) {
+  // Set a managed preference that establishes a default search provider.
+  const char kName[] = "test1";
+  const char kKeyword[] = "test.com";
+  const char kSearchURL[] = "http://test.com/search?t={searchTerms}";
+  const char kIconURL[] = "http://test.com/icon.jpg";
+  const char kEncodings[] = "UTF-16;UTF-32";
+  const char kAlternateURL[] = "http://test.com/search#t={searchTerms}";
+  const char kSearchTermsReplacementKey[] = "espv";
+
+  // This method only updates the legacy location for managed DSEs. So it will
+  // not cause DefaultSearchManager to report a value.
+  test_util()->SetManagedDefaultSearchPreferences(true,
+                                                  kName,
+                                                  kKeyword,
+                                                  kSearchURL,
+                                                  std::string(),
+                                                  kIconURL,
+                                                  kEncodings,
+                                                  kAlternateURL,
+                                                  kSearchTermsReplacementKey);
+  test_util()->VerifyLoad();
+
+  // Verify that the policy value is correctly installed.
+  scoped_ptr<TemplateURLData> legacy_default;
+  bool legacy_is_managed = false;
+  ASSERT_TRUE(TemplateURLService::LoadDefaultSearchProviderFromPrefs(
+      test_util()->profile()->GetPrefs(), &legacy_default, &legacy_is_managed));
+  EXPECT_TRUE(legacy_is_managed);
+  EXPECT_TRUE(legacy_default);
+
+  // Run the migration.
+  ConfigureDefaultSearchPrefMigrationToDictionaryValue(
+      test_util()->profile()->GetPrefs());
+
+  // TODO(caitkp/erikwright): Look into loading policy values in tests. In
+  // practice, the DefaultSearchEngineSource() would be FROM_POLICY in this
+  // case, but since we are not loading the policy here, it will be
+  // FROM_FALLBACK instead.
+  // Test that the policy-defined value is not migrated.
+  ASSERT_EQ(DefaultSearchManager::FROM_FALLBACK,
+            DefaultSearchManager(test_util()->profile()->GetPrefs(),
+                                 DefaultSearchManager::ObserverCallback())
+                .GetDefaultSearchEngineSource());
+}
diff --git a/chrome/browser/search_engines/prepopulated_engines.json b/chrome/browser/search_engines/prepopulated_engines.json
index 4459da3..709b157 100644
--- a/chrome/browser/search_engines/prepopulated_engines.json
+++ b/chrome/browser/search_engines/prepopulated_engines.json
@@ -9,8 +9,9 @@
 // definitions.
 
 // The following unique IDs are available:
-//    11, 12, 14, 18, 19, 20, 22, 24, 26, 28, 29, 30, 32, 33, 34, 39, 37, 38,
-//    40, 41, 42, 46, 47, 48, 49, 51, 52, 59, 71, 72, 82, 84, 86, 88, 89, 91+
+//    11, 12, 13, 14, 18, 19, 20, 22, 24, 26, 28, 29, 30, 32, 33, 34, 39, 37,
+//    38, 40, 41, 42, 46, 47, 48, 49, 51, 52, 58, 59, 69, 71, 72, 82, 84, 86,
+//    88, 89, 91+
 //
 // IDs > 1000 are reserved for distribution custom engines.
 //
@@ -26,7 +27,7 @@
 
     // Increment this if you change the data in ways that mean users with
     // existing data should get a new version.
-    "kCurrentDataVersion": 70
+    "kCurrentDataVersion": 73
   },
 
   // The following engines are included in country lists and are added to the
@@ -36,7 +37,7 @@
       "name": "AOL",
       "keyword": "aol.com",
       "favicon_url": "http://search.aol.com/favicon.ico",
-      "search_url": "http://search.aol.com/aol/search?query={searchTerms}",
+      "search_url": "http://search.aol.com/aol/search?q={searchTerms}",
       "suggest_url": "http://autocomplete.search.aol.com/autocomplete/get?output=json&it=&q={searchTerms}",
       "type": "SEARCH_ENGINE_AOL",
       "id": 35
@@ -57,7 +58,6 @@
       "keyword": "br.ask.com",
       "favicon_url": "http://sp.br.ask.com/sh/i/a14/favicon/favicon.ico",
       "search_url": "http://br.ask.com/web?q={searchTerms}",
-      "suggest_url": "http://ss.ask.com/query?q={searchTerms}&li=ff",
       "type": "SEARCH_ENGINE_ASK",
       "id": 4
     },
@@ -76,7 +76,7 @@
       "name": "\u767e\u5ea6",
       "keyword": "baidu.com",
       "favicon_url": "http://www.baidu.com/favicon.ico",
-      "search_url": "http://www.baidu.com/s?ie={inputEncoding}&wd={searchTerms}",
+      "search_url": "http://www.baidu.com/#ie={inputEncoding}&wd={searchTerms}",
       "type": "SEARCH_ENGINE_BAIDU",
       "id": 21
     },
@@ -84,9 +84,10 @@
     "bing": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -94,9 +95,10 @@
     "bing_ar_XA": {
       "name": "Bing (\u0627\u0644\u0639\u0631\u0628\u064a\u0629)",
       "keyword": "bing.com_",  // bing.com is taken by bing_en_XA.
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=ar-XA&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=ar-XA&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=ar-XA",
       "type": "SEARCH_ENGINE_BING",
       "id": 7  // Can't be 3 as this has to appear in the Arabian countries'
                // lists alongside bing_en_XA.
@@ -105,9 +107,10 @@
     "bing_da_DK": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=da-DK&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=da-DK&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=da-DK",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -115,9 +118,10 @@
     "bing_de_AT": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=de-AT&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=de-AT&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=de-AT",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -125,9 +129,10 @@
     "bing_de_CH": {
       "name": "Bing (Deutsch)",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=de-CH&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=de-CH&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=de-CH",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -135,9 +140,10 @@
     "bing_de_DE": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=de-DE&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=de-DE&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=de-DE",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -145,9 +151,10 @@
     "bing_en_AU": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=en-AU&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=en-AU&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-AU",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -155,9 +162,10 @@
     "bing_en_CA": {
       "name": "Bing (English)",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=en-CA&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=en-CA&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-CA",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -165,9 +173,10 @@
     "bing_en_GB": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=en-GB&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=en-GB&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-GB",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -175,9 +184,10 @@
     "bing_en_IE": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=en-IE&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=en-IE&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-IE",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -185,9 +195,10 @@
     "bing_en_IN": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=en-IN&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=en-IN&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-IN",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -195,9 +206,10 @@
     "bing_en_NZ": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=en-NZ&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=en-NZ&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-NZ",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -205,9 +217,10 @@
     "bing_en_PH": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=en-PH&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=en-PH&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-PH",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -215,9 +228,10 @@
     "bing_en_SG": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=en-SG&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=en-SG&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-SG",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -225,9 +239,10 @@
     "bing_en_US": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=en-US&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=en-US&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-US",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -235,9 +250,10 @@
     "bing_en_XA": {
       "name": "Bing (English)",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=en-XA&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=en-XA&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=en-XA",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -245,9 +261,10 @@
     "bing_es_AR": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=es-AR&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=es-AR&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=es-AR",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -255,9 +272,10 @@
     "bing_es_CL": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=es-CL&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=es-CL&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=es-CL",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -265,9 +283,10 @@
     "bing_es_ES": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=es-ES&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=es-ES&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=es-ES",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -275,9 +294,10 @@
     "bing_es_MX": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=es-MX&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=es-MX&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=es-MX",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -285,9 +305,10 @@
     "bing_es_XL": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=es-XL&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=es-XL&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=es-XL",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -295,9 +316,10 @@
     "bing_fi_FI": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=fi-FI&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=fi-FI&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=fi-FI",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -305,9 +327,10 @@
     "bing_fr_BE": {
       "name": "Bing (Fran\u00e7ais)",
       "keyword": "bing.com_",  // bing.com is taken by bing_nl_BE.
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=fr-BE&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=fr-BE&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=fr-BE",
       "type": "SEARCH_ENGINE_BING",
       "id": 7
     },
@@ -315,9 +338,10 @@
     "bing_fr_CA": {
       "name": "Bing (Fran\u00e7ais)",
       "keyword": "bing.com_",  // bing.com is taken by bing_en_CA.
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=fr-CA&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=fr-CA&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=fr-CA",
       "type": "SEARCH_ENGINE_BING",
       "id": 7
     },
@@ -325,9 +349,10 @@
     "bing_fr_CH": {
       "name": "Bing (Fran\u00e7ais)",
       "keyword": "bing.com_",  // bing.com is taken by bing_de_CH.
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=fr-CH&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=fr-CH&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=fr-CH",
       "type": "SEARCH_ENGINE_BING",
       "id": 7
     },
@@ -335,9 +360,10 @@
     "bing_fr_FR": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=fr-FR&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=fr-FR&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=fr-FR",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -345,9 +371,10 @@
     "bing_it_IT": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=it-IT&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=it-IT&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=it-IT",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -355,9 +382,10 @@
     "bing_ja_JP": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=ja-JP&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=ja-JP&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=ja-JP",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -365,9 +393,10 @@
     "bing_lv_LV": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=lv-LV&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=lv-LV&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=lv-LV",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -375,9 +404,10 @@
     "bing_nb_NO": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=nb-NO&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=nb-NO&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=nb-NO",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -385,9 +415,10 @@
     "bing_nl_BE": {
       "name": "Bing (Nederlandstalige)",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=nl-BE&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=nl-BE&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=nl-BE",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -395,9 +426,10 @@
     "bing_pl_PL": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=pl-PL&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=pl-PL&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=pl-PL",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -405,9 +437,10 @@
     "bing_pt_BR": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=pt-BR&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=pt-BR&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=pt-BR",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -415,9 +448,10 @@
     "bing_pt_PT": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=pt-PT&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=pt-PT&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=pt-PT",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -425,9 +459,10 @@
     "bing_ru_RU": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=ru-RU&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=ru-RU&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=ru-RU",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -435,9 +470,10 @@
     "bing_sv_SE": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=sv-SE&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=sv-SE&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=sv-SE",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -445,9 +481,10 @@
     "bing_tr_TR": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=tr-TR&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=tr-TR&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=tr-TR",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -455,9 +492,10 @@
     "bing_zh_HK": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=zh-HK&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=zh-HK&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=zh-HK",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -465,9 +503,10 @@
     "bing_zh_TW": {
       "name": "Bing",
       "keyword": "bing.com",
-      "favicon_url": "http://www.bing.com/s/wlflag.ico",
-      "search_url": "http://www.bing.com/search?setmkt=zh-TW&q={searchTerms}",
+      "favicon_url": "https://www.bing.com/s/a/bing_p.ico",
+      "search_url": "https://www.bing.com/search?setmkt=zh-TW&q={searchTerms}",
       "suggest_url": "http://api.bing.com/osjson.aspx?query={searchTerms}&language={language}",
+      "new_tab_url": "https://www.bing.com/chrome/newtab?setmkt=zh-TW",
       "type": "SEARCH_ENGINE_BING",
       "id": 3
     },
@@ -505,8 +544,8 @@
     "kvasir": {
       "name": "Kvasir",
       "keyword": "kvasir.no",
-      "favicon_url": "http://www.kvasir.no/grafikk/favicon.ico",
-      "search_url": "http://www.kvasir.no/alle?q={searchTerms}",
+      "favicon_url": "http://kvasir.no/grafikk/favicon.ico",
+      "search_url": "http://kvasir.no/alle?q={searchTerms}",
       "type": "SEARCH_ENGINE_KVASIR",
       "id": 73
     },
@@ -514,7 +553,7 @@
     "mail_ru": {
       "name": "@MAIL.RU",
       "keyword": "mail.ru",
-      "favicon_url": "http://img.go.mail.ru/favicon.ico",
+      "favicon_url": "http://go.imgsmail.ru/favicon.ico",
       "search_url": "http://go.mail.ru/search?q={searchTerms}",
       "encoding": "windows-1251",
       "suggest_url": "http://suggests.go.mail.ru/chrome?q={searchTerms}",
@@ -525,28 +564,18 @@
     "najdi": {
       "name": "Najdi.si",
       "keyword": "najdi.si",
-      "favicon_url": "http://nsi2.sdn.si/master/v2/favicon.ico",
+      "favicon_url": "http://www.najdi.si/assets/PROD-1.4.10/ctx/images/favicon.ico",
       "search_url": "http://www.najdi.si/search.jsp?q={searchTerms}",
       "type": "SEARCH_ENGINE_NAJDI",
       "id": 87
     },
 
-    "nate": {
-      "name": "\ub124\uc774\ud2b8",
-      "keyword": "nate.com",
-      "favicon_url": "http://search.nate.com/favicon.ico",
-      "search_url": "http://search.nate.com/search/all.html?q={searchTerms}",
-      "encoding": "EUC-KR",
-      "type": "SEARCH_ENGINE_NATE",
-      "id": 69
-    },
-
     "naver": {
       "name": "\ub124\uc774\ubc84",
       "keyword": "naver.com",
-      "favicon_url": "http://static.naver.net/www/favicon.ico",
+      "favicon_url": "http://sstatic.naver.net/search/favicon/favicon_140327.ico",
       "search_url": "http://search.naver.com/search.naver?ie={inputEncoding}&query={searchTerms}",
-      "suggest_url": "http://ac.search.naver.com/autocompl?m=s&ie={inputEncoding}&oe={outputEncoding}&q={searchTerms}",
+      "suggest_url": "http://ac.search.naver.com/nx/ac?of=os&ie={inputEncoding}&q={searchTerms}&oe={outputEncoding}",
       "type": "SEARCH_ENGINE_NAVER",
       "id": 67
     },
@@ -563,9 +592,9 @@
     "seznam": {
       "name": "Seznam",
       "keyword": "seznam.cz",
-      "favicon_url": "http://1.im.cz/szn/img/favicon.ico",
+      "favicon_url": "http://search.seznam.cz/r/img/favicon.ico",
       "search_url": "http://search.seznam.cz/?q={searchTerms}",
-      "suggest_url": "http:///suggest.fulltext.seznam.cz/?dict=fulltext_ff&phrase={searchTerms}&encoding={inputEncoding}&response_encoding=utf-8",
+      "suggest_url": "http://suggest.fulltext.seznam.cz/fulltext_ff?phrase={searchTerms}",
       "type": "SEARCH_ENGINE_SEZNAM",
       "id": 25
     },
@@ -573,21 +602,12 @@
     "sogou": {
       "name": "\u641c\u72d7",
       "keyword": "sogou.com",
-      "favicon_url": "http://www.sogou.com/favicon.ico",
+      "favicon_url": "http://www.sogou.com/images/logo/old/favicon.ico",
       "search_url": "http://www.sogou.com/web?ie={inputEncoding}&query={searchTerms}",
       "type": "SEARCH_ENGINE_SOGOU",
       "id": 56
     },
 
-    "soso": {
-      "name": "\u641c\u641c",
-      "keyword": "soso.com",
-      "favicon_url": "http://www.soso.com/favicon.ico",
-      "search_url": "http://www.soso.com/q?ie={inputEncoding}&w={searchTerms}",
-      "type": "SEARCH_ENGINE_SOSO",
-      "id": 58
-    },
-
     "vinden": {
       "name": "Vinden.nl",
       "keyword": "vinden.nl",
@@ -610,8 +630,8 @@
     "yahoo": {
       "name": "Yahoo!",
       "keyword": "yahoo.com",
-      "favicon_url": "http://search.yahoo.com/favicon.ico",
-      "search_url": "http://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://search.yahoo.com/favicon.ico",
+      "search_url": "https://search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -620,8 +640,8 @@
     "yahoo_ar": {
       "name": "Yahoo! Argentina",
       "keyword": "ar.yahoo.com",
-      "favicon_url": "http://ar.search.yahoo.com/favicon.ico",
-      "search_url": "http://ar.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://ar.search.yahoo.com/favicon.ico",
+      "search_url": "https://ar.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://ar-sayt.ff.search.yahoo.com/gossip-ar-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -630,8 +650,8 @@
     "yahoo_at": {
       "name": "Yahoo! \u00d6sterreich",
       "keyword": "at.yahoo.com",
-      "favicon_url": "http://at.search.yahoo.com/favicon.ico",
-      "search_url": "http://at.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://at.search.yahoo.com/favicon.ico",
+      "search_url": "https://at.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://de-sayt.ff.search.yahoo.com/gossip-de-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -640,30 +660,18 @@
     "yahoo_au": {
       "name": "Yahoo!7",
       "keyword": "au.yahoo.com",
-      "favicon_url": "http://au.search.yahoo.com/favicon.ico",
-      "search_url": "http://au.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://au.search.yahoo.com/favicon.ico",
+      "search_url": "https://au.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://aue-sayt.ff.search.yahoo.com/gossip-au-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
     },
 
-    // For regional Yahoo variants without a region-specific suggestion service,
-    // suggestion is disabled. For some of them, we might consider using one of
-    // the other language/country URLs as a fallback.
-    "yahoo_be": {
-      "name": "Yahoo! Belgi\u00eb",
-      "keyword": "be.yahoo.com",
-      "favicon_url": "http://be.search.yahoo.com/favicon.ico",
-      "search_url": "http://be.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
-      "type": "SEARCH_ENGINE_YAHOO",
-      "id": 2
-    },
-
     "yahoo_br": {
       "name": "Yahoo! Brasil",
       "keyword": "br.yahoo.com",
-      "favicon_url": "http://br.search.yahoo.com/favicon.ico",
-      "search_url": "http://br.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://br.search.yahoo.com/favicon.ico",
+      "search_url": "https://br.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://br-sayt.ff.search.yahoo.com/gossip-br-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -672,8 +680,8 @@
     "yahoo_ca": {
       "name": "Yahoo! Canada",
       "keyword": "ca.yahoo.com",
-      "favicon_url": "http://ca.search.yahoo.com/favicon.ico",
-      "search_url": "http://ca.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://ca.search.yahoo.com/favicon.ico",
+      "search_url": "https://ca.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://gossip.ca.yahoo.com/gossip-ca-sayt?output=fxjsonp&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -682,8 +690,8 @@
     "yahoo_ch": {
       "name": "Yahoo! Schweiz",
       "keyword": "ch.yahoo.com",
-      "favicon_url": "http://ch.search.yahoo.com/favicon.ico",
-      "search_url": "http://ch.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://ch.search.yahoo.com/favicon.ico",
+      "search_url": "https://ch.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://de-sayt.ff.search.yahoo.com/gossip-de-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -692,8 +700,8 @@
     "yahoo_cl": {
       "name": "Yahoo! Chile",
       "keyword": "cl.yahoo.com",
-      "favicon_url": "http://cl.search.yahoo.com/favicon.ico",
-      "search_url": "http://cl.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://cl.search.yahoo.com/favicon.ico",
+      "search_url": "https://cl.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://gossip.telemundo.yahoo.com/gossip-e1-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -702,8 +710,8 @@
     "yahoo_co": {
       "name": "Yahoo! Colombia",
       "keyword": "co.yahoo.com",
-      "favicon_url": "http://co.search.yahoo.com/favicon.ico",
-      "search_url": "http://co.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://co.search.yahoo.com/favicon.ico",
+      "search_url": "https://co.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://gossip.telemundo.yahoo.com/gossip-e1-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -719,6 +727,9 @@
       "id": 2
     },
 
+    // For regional Yahoo variants without a region-specific suggestion service,
+    // suggestion is disabled. For some of them, we might consider using one of
+    // the other language/country URLs as a fallback.
     "yahoo_dk": {
       "name": "Yahoo! Danmark",
       "keyword": "dk.yahoo.com",
@@ -731,8 +742,8 @@
     "yahoo_es": {
       "name": "Yahoo! Espa\u00f1a",
       "keyword": "es.yahoo.com",
-      "favicon_url": "http://es.search.yahoo.com/favicon.ico",
-      "search_url": "http://es.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://es.search.yahoo.com/favicon.ico",
+      "search_url": "https://es.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://es-sayt.ff.search.yahoo.com/gossip-es-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -741,8 +752,8 @@
     "yahoo_fi": {
       "name": "Yahoo! Suomi",
       "keyword": "fi.yahoo.com",
-      "favicon_url": "http://fi.search.yahoo.com/favicon.ico",
-      "search_url": "http://fi.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://fi.search.yahoo.com/favicon.ico",
+      "search_url": "https://fi.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
     },
@@ -750,29 +761,19 @@
     "yahoo_fr": {
       "name": "Yahoo! France",
       "keyword": "fr.yahoo.com",
-      "favicon_url": "http://fr.search.yahoo.com/favicon.ico",
-      "search_url": "http://fr.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
-      "suggest_url": "http://fr-sayt.ff.search.yahoo.com/gossip-fr-sayt?output=fxjson&command={searchTerms}",
-      "type": "SEARCH_ENGINE_YAHOO",
-      "id": 2
-    },
-
-    "yahoo_fr_be": {
-      "name": "Yahoo! Belgique",
-      "keyword": "fr-be.yahoo.com",
-      "favicon_url": "http://fr.search.yahoo.com/favicon.ico",
-      "search_url": "http://fr.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://fr.search.yahoo.com/favicon.ico",
+      "search_url": "https://fr.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://fr-sayt.ff.search.yahoo.com/gossip-fr-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 5  // Can't be 2 as this has to appear in the Belgium list alongside
-               // yahoo_be.
+               // yahoo.
     },
 
     "yahoo_gr": {
       "name": "Yahoo! \u0395\u03bb\u03bb\u03ac\u03b4\u03b1\u03c2",
       "keyword": "gr.yahoo.com",
-      "favicon_url": "http://gr.search.yahoo.com/favicon.ico",
-      "search_url": "http://gr.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://gr.search.yahoo.com/favicon.ico",
+      "search_url": "https://gr.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
     },
@@ -780,8 +781,8 @@
     "yahoo_hk": {
       "name": "Yahoo! Hong Kong",
       "keyword": "hk.yahoo.com",
-      "favicon_url": "http://hk.search.yahoo.com/favicon.ico",
-      "search_url": "http://hk.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://hk.search.yahoo.com/favicon.ico",
+      "search_url": "https://hk.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://hk-sayt.ff.search.yahoo.com/gossip-hk-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -790,8 +791,8 @@
     "yahoo_id": {
       "name": "Yahoo! Indonesia",
       "keyword": "id.yahoo.com",
-      "favicon_url": "http://id.search.yahoo.com/favicon.ico",
-      "search_url": "http://id.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://id.search.yahoo.com/favicon.ico",
+      "search_url": "https://id.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://id-sayt.ff.search.yahoo.com/gossip-id-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -800,8 +801,8 @@
     "yahoo_in": {
       "name": "Yahoo! India",
       "keyword": "in.yahoo.com",
-      "favicon_url": "http://in.search.yahoo.com/favicon.ico",
-      "search_url": "http://in.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://in.search.yahoo.com/favicon.ico",
+      "search_url": "https://in.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://in-sayt.ff.search.yahoo.com/gossip-in-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -820,17 +821,17 @@
     "yahoo_maktoob": {
       "name": "Yahoo!\u200e \u0645\u0643\u062a\u0648\u0628",
       "keyword": "maktoob.yahoo.com",
-      "favicon_url": "http://maktoob.yahoo.com/favicon.ico",
-      "search_url": "http://maktoob.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://maktoob.search.yahoo.com/favicon.ico",
+      "search_url": "https://maktoob.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
-      "id": 13  // Should be 2, but is 13 due to historical reasons.
+      "id": 2
     },
 
     "yahoo_mx": {
       "name": "Yahoo! M\u00e9xico",
       "keyword": "mx.yahoo.com",
-      "favicon_url": "http://mx.search.yahoo.com/favicon.ico",
-      "search_url": "http://mx.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://mx.search.yahoo.com/favicon.ico",
+      "search_url": "https://mx.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://gossip.mx.yahoo.com/gossip-mx-sayt?output=fxjsonp&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -839,8 +840,8 @@
     "yahoo_my": {
       "name": "Yahoo! Malaysia",
       "keyword": "malaysia.yahoo.com",
-      "favicon_url": "http://malaysia.search.yahoo.com/favicon.ico",
-      "search_url": "http://malaysia.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://malaysia.search.yahoo.com/favicon.ico",
+      "search_url": "https://malaysia.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://my-sayt.ff.search.yahoo.com/gossip-my-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -849,8 +850,8 @@
     "yahoo_nl": {
       "name": "Yahoo! Nederland",
       "keyword": "nl.yahoo.com",
-      "favicon_url": "http://nl.search.yahoo.com/favicon.ico",
-      "search_url": "http://nl.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://nl.search.yahoo.com/favicon.ico",
+      "search_url": "https://nl.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -859,8 +860,8 @@
     "yahoo_nz": {
       "name": "Yahoo! New Zealand",
       "keyword": "nz.yahoo.com",
-      "favicon_url": "http://nz.search.yahoo.com/favicon.ico",
-      "search_url": "http://nz.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://nz.search.yahoo.com/favicon.ico",
+      "search_url": "https://nz.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://aue-sayt.ff.search.yahoo.com/gossip-nz-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -869,8 +870,8 @@
     "yahoo_pe": {
       "name": "Yahoo! Per\u00fa",
       "keyword": "pe.yahoo.com",
-      "favicon_url": "http://pe.search.yahoo.com/favicon.ico",
-      "search_url": "http://pe.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://pe.search.yahoo.com/favicon.ico",
+      "search_url": "https://pe.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://gossip.telemundo.yahoo.com/gossip-e1-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -879,8 +880,8 @@
     "yahoo_ph": {
       "name": "Yahoo! Philippines",
       "keyword": "ph.yahoo.com",
-      "favicon_url": "http://ph.search.yahoo.com/favicon.ico",
-      "search_url": "http://ph.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://ph.search.yahoo.com/favicon.ico",
+      "search_url": "https://ph.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://ph-sayt.ff.search.yahoo.com/gossip-ph-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -889,8 +890,8 @@
     "yahoo_qc": {
       "name": "Yahoo! Qu\u00e9bec",
       "keyword": "qc.yahoo.com",
-      "favicon_url": "http://qc.search.yahoo.com/favicon.ico",
-      "search_url": "http://qc.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://qc.search.yahoo.com/favicon.ico",
+      "search_url": "https://qc.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://gossip.ca.yahoo.com/gossip-ca-sayt?output=fxjsonp&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 5  // Can't be 2 as this has to appear in the Canada list alongside
@@ -900,8 +901,8 @@
     "yahoo_ro": {
       "name": "Yahoo! Rom\u00e2nia",
       "keyword": "ro.yahoo.com",
-      "favicon_url": "http://ro.search.yahoo.com/favicon.ico",
-      "search_url": "http://ro.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://ro.search.yahoo.com/favicon.ico",
+      "search_url": "https://ro.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
     },
@@ -909,8 +910,8 @@
     "yahoo_ru": {
       "name": "Yahoo! \u043f\u043e-\u0440\u0443\u0441\u0441\u043a\u0438",
       "keyword": "ru.yahoo.com",
-      "favicon_url": "http://ru.search.yahoo.com/favicon.ico",
-      "search_url": "http://ru.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://ru.search.yahoo.com/favicon.ico",
+      "search_url": "https://ru.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
     },
@@ -918,8 +919,8 @@
     "yahoo_se": {
       "name": "Yahoo! Sverige",
       "keyword": "se.yahoo.com",
-      "favicon_url": "http://se.search.yahoo.com/favicon.ico",
-      "search_url": "http://se.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://se.search.yahoo.com/favicon.ico",
+      "search_url": "https://se.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
     },
@@ -927,8 +928,8 @@
     "yahoo_sg": {
       "name": "Yahoo! Singapore",
       "keyword": "sg.yahoo.com",
-      "favicon_url": "http://sg.search.yahoo.com/favicon.ico",
-      "search_url": "http://sg.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://sg.search.yahoo.com/favicon.ico",
+      "search_url": "https://sg.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://sg-sayt.ff.search.yahoo.com/gossip-sg-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -937,8 +938,8 @@
     "yahoo_th": {
       "name": "Yahoo! \u0e1b\u0e23\u0e30\u0e40\u0e17\u0e28\u0e44\u0e17\u0e22",
       "keyword": "th.yahoo.com",
-      "favicon_url": "http://th.search.yahoo.com/favicon.ico",
-      "search_url": "http://th.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://th.search.yahoo.com/favicon.ico",
+      "search_url": "https://th.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://th-sayt.ff.search.yahoo.com/gossip-th-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -947,8 +948,8 @@
     "yahoo_tr": {
       "name": "Yahoo! T\u00fcrkiye",
       "keyword": "tr.yahoo.com",
-      "favicon_url": "http://tr.search.yahoo.com/favicon.ico",
-      "search_url": "http://tr.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://tr.search.yahoo.com/favicon.ico",
+      "search_url": "https://tr.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
     },
@@ -956,8 +957,8 @@
     "yahoo_tw": {
       "name": "Yahoo!\u5947\u6469",
       "keyword": "tw.yahoo.com",
-      "favicon_url": "http://tw.search.yahoo.com/favicon.ico",
-      "search_url": "http://tw.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://tw.search.yahoo.com/favicon.ico",
+      "search_url": "https://tw.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://hk-sayt.ff.search.yahoo.com/gossip-hk-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -966,8 +967,8 @@
     "yahoo_uk": {
       "name": "Yahoo! UK & Ireland",
       "keyword": "uk.yahoo.com",
-      "favicon_url": "http://uk.search.yahoo.com/favicon.ico",
-      "search_url": "http://uk.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://uk.search.yahoo.com/favicon.ico",
+      "search_url": "https://uk.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://uk-sayt.ff.search.yahoo.com/gossip-uk-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -976,8 +977,8 @@
     "yahoo_ve": {
       "name": "Yahoo! Venezuela",
       "keyword": "ve.yahoo.com",
-      "favicon_url": "http://ve.search.yahoo.com/favicon.ico",
-      "search_url": "http://ve.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
+      "favicon_url": "https://ve.search.yahoo.com/favicon.ico",
+      "search_url": "https://ve.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
       "suggest_url": "http://gossip.telemundo.yahoo.com/gossip-e1-sayt?output=fxjson&command={searchTerms}",
       "type": "SEARCH_ENGINE_YAHOO",
       "id": 2
@@ -993,19 +994,10 @@
       "id": 2
     },
 
-    "yahoo_za": {
-      "name": "Yahoo! South Africa",
-      "keyword": "za.yahoo.com",
-      "favicon_url": "http://za.search.yahoo.com/favicon.ico",
-      "search_url": "http://za.search.yahoo.com/search?ei={inputEncoding}&fr=crmas&p={searchTerms}",
-      "type": "SEARCH_ENGINE_YAHOO",
-      "id": 2
-    },
-
     "yandex_ru": {
       "name": "\u042f\u043d\u0434\u0435\u043a\u0441",
       "keyword": "yandex.ru",
-      "favicon_url": "http://yandex.ru/favicon.ico",
+      "favicon_url": "http://yandex.st/lego/_/pDu9OWAQKB0s2J9IojKpiS_Eho.ico",
       "search_url": "http://yandex.ru/yandsearch?text={searchTerms}",
       "suggest_url": "http://suggest.yandex.net/suggest-ff.cgi?part={searchTerms}",
       "type": "SEARCH_ENGINE_YANDEX",
@@ -1015,7 +1007,7 @@
     "yandex_tr": {
       "name": "Yandex",
       "keyword": "yandex.com.tr",
-      "favicon_url": "http://yandex.st/islands-icons/_/6jyHGXR8-HAc8oJ1bU8qMUQQz_g.ico",
+      "favicon_url": "http://yastatic.net/islands-icons/_/6jyHGXR8-HAc8oJ1bU8qMUQQz_g.ico",
       "search_url": "http://www.yandex.com.tr/yandsearch?text={searchTerms}",
       "suggest_url": "http://suggest.yandex.com.tr/suggest-ff.cgi?part={searchTerms}",
       "type": "SEARCH_ENGINE_YANDEX",
@@ -1025,9 +1017,9 @@
     "yandex_ua": {
       "name": "\u042f\u043d\u0434\u0435\u043a\u0441",
       "keyword": "yandex.ua",
-      "favicon_url": "http://yandex.ua/favicon.ico",
+      "favicon_url": "http://yastatic.net/islands-icons/_/aKnllxm-gQhidpzbZqub7qe641g.ico",
       "search_url": "http://yandex.ua/yandsearch?text={searchTerms}",
-      "suggest_url": "http://suggest.yandex.net/suggest-ff.cgi?part={searchTerms}",
+      "suggest_url": "http://suggest.yandex.ua/suggest-ff.cgi?part={searchTerms}",
       "type": "SEARCH_ENGINE_YANDEX",
       "id": 15
     },
diff --git a/chrome/browser/search_engines/search_provider_install_data.cc b/chrome/browser/search_engines/search_provider_install_data.cc
index 64b14fd..95d5a77 100644
--- a/chrome/browser/search_engines/search_provider_install_data.cc
+++ b/chrome/browser/search_engines/search_provider_install_data.cc
@@ -10,6 +10,7 @@
 
 #include "base/basictypes.h"
 #include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequenced_task_runner_helpers.h"
@@ -20,6 +21,7 @@
 #include "chrome/browser/search_engines/search_terms_data.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/search_engines/util.h"
 #include "chrome/browser/webdata/web_data_service.h"
 #include "content/public/browser/browser_thread.h"
@@ -36,6 +38,30 @@
 
 namespace {
 
+void LoadDataOnUIThread(TemplateURLService* template_url_service,
+                        const base::Callback<void(ScopedVector<TemplateURL>,
+                                                  TemplateURL*)>& callback) {
+  ScopedVector<TemplateURL> template_url_copies;
+  TemplateURL* default_provider_copy = NULL;
+  TemplateURLService::TemplateURLVector original_template_urls =
+      template_url_service->GetTemplateURLs();
+  TemplateURL* original_default_provider =
+      template_url_service->GetDefaultSearchProvider();
+  for (TemplateURLService::TemplateURLVector::const_iterator it =
+           original_template_urls.begin();
+       it != original_template_urls.end();
+       ++it) {
+    template_url_copies.push_back(new TemplateURL(NULL, (*it)->data()));
+    if (*it == original_default_provider)
+      default_provider_copy = template_url_copies.back();
+  }
+  BrowserThread::PostTask(BrowserThread::IO,
+                          FROM_HERE,
+                          base::Bind(callback,
+                                     base::Passed(template_url_copies.Pass()),
+                                     base::Unretained(default_provider_copy)));
+}
+
 // Implementation of SearchTermsData that may be used on the I/O thread.
 class IOThreadSearchTermsData : public SearchTermsData {
  public:
@@ -165,9 +191,9 @@
 }  // namespace
 
 SearchProviderInstallData::SearchProviderInstallData(
-    Profile* profile, content::RenderProcessHost* host)
-    : web_service_(WebDataService::FromBrowserContext(profile)),
-      load_handle_(0),
+    Profile* profile,
+    content::RenderProcessHost* host)
+    : template_url_service_(TemplateURLServiceFactory::GetForProfile(profile)),
       google_base_url_(UIThreadSearchTermsData(profile).GoogleBaseURLValue()),
       weak_factory_(this) {
   // GoogleURLObserver is responsible for killing itself when
@@ -179,11 +205,6 @@
 
 SearchProviderInstallData::~SearchProviderInstallData() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
-  if (load_handle_) {
-    DCHECK(web_service_.get());
-    web_service_->CancelRequest(load_handle_);
-  }
 }
 
 void SearchProviderInstallData::CallWhenLoaded(const base::Closure& closure) {
@@ -194,14 +215,24 @@
     return;
   }
 
+  bool do_load = closure_queue_.empty();
   closure_queue_.push_back(closure);
-  if (load_handle_)
+
+  // If the queue wasn't empty, there was already a load in progress.
+  if (!do_load)
     return;
 
-  if (web_service_.get())
-    load_handle_ = web_service_->GetKeywords(this);
-  else
+  if (template_url_service_) {
+    BrowserThread::PostTask(
+        BrowserThread::UI,
+        FROM_HERE,
+        base::Bind(&LoadDataOnUIThread,
+                   template_url_service_,
+                   base::Bind(&SearchProviderInstallData::OnTemplateURLsLoaded,
+                              weak_factory_.GetWeakPtr())));
+  } else {
     OnLoadFailed();
+  }
 }
 
 SearchProviderInstallData::State SearchProviderInstallData::GetInstallState(
@@ -233,35 +264,17 @@
   google_base_url_ = google_base_url;
 }
 
-void SearchProviderInstallData::OnWebDataServiceRequestDone(
-    WebDataService::Handle h,
-    const WDTypedResult* result) {
+void SearchProviderInstallData::OnTemplateURLsLoaded(
+    ScopedVector<TemplateURL> template_urls,
+    TemplateURL* default_provider) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
-  // Reset the load_handle so that we don't try and cancel the load in
-  // the destructor.
-  load_handle_ = 0;
+  template_urls_ = template_urls.Pass();
 
-  if (!result) {
-    // Results are null if the database went away or (most likely) wasn't
-    // loaded.
-    OnLoadFailed();
-    return;
-  }
-
-  TemplateURL* default_search_provider = NULL;
-  int new_resource_keyword_version = 0;
-  std::vector<TemplateURL*> extracted_template_urls;
-  GetSearchProvidersUsingKeywordResult(*result, NULL, NULL,
-      &extracted_template_urls, &default_search_provider,
-      &new_resource_keyword_version, NULL);
-  template_urls_.get().insert(template_urls_.get().begin(),
-                              extracted_template_urls.begin(),
-                              extracted_template_urls.end());
   IOThreadSearchTermsData search_terms_data(google_base_url_);
   provider_map_.reset(new SearchHostToURLsMap());
   provider_map_->Init(template_urls_.get(), search_terms_data);
-  SetDefault(default_search_provider);
+  SetDefault(default_provider);
   NotifyLoaded();
 }
 
diff --git a/chrome/browser/search_engines/search_provider_install_data.h b/chrome/browser/search_engines/search_provider_install_data.h
index dc196ea..853e449 100644
--- a/chrome/browser/search_engines/search_provider_install_data.h
+++ b/chrome/browser/search_engines/search_provider_install_data.h
@@ -13,11 +13,12 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/webdata/web_data_service.h"
 
 class GURL;
+class Profile;
 class SearchHostToURLsMap;
 class TemplateURL;
+class TemplateURLService;
 
 namespace content {
 class RenderProcessHost;
@@ -27,7 +28,7 @@
 // loading the data on demand (when CallWhenLoaded is called) and then throwing
 // away the results after the callbacks are done, so the results are always up
 // to date with what is in the database.
-class SearchProviderInstallData : public WebDataServiceConsumer {
+class SearchProviderInstallData {
  public:
   enum State {
     // The search provider is not installed.
@@ -61,13 +62,9 @@
   void OnGoogleURLChange(const std::string& google_base_url);
 
  private:
-  // WebDataServiceConsumer
-  // Notification that the keywords have been loaded.
-  // This is invoked from WebDataService, and should not be directly
-  // invoked.
-  virtual void OnWebDataServiceRequestDone(
-      WebDataService::Handle h,
-      const WDTypedResult* result) OVERRIDE;
+  // Receives a copy of the TemplateURLService's keywords on the IO thread.
+  void OnTemplateURLsLoaded(ScopedVector<TemplateURL> template_urls,
+                            TemplateURL* default_provider);
 
   // Stores information about the default search provider.
   void SetDefault(const TemplateURL* template_url);
@@ -80,15 +77,13 @@
   // install state has been loaded.
   void NotifyLoaded();
 
-  // The list of closures to call after the load has finished.
+  // The original data source. Only accessed on the UI thread.
+  TemplateURLService* template_url_service_;
+
+  // The list of closures to call after the load has finished. If empty, there
+  // is no pending load.
   std::vector<base::Closure> closure_queue_;
 
-  // Service used to store entries.
-  scoped_refptr<WebDataService> web_service_;
-
-  // If non-zero, we're waiting on a load.
-  WebDataService::Handle load_handle_;
-
   // Holds results of a load that was done using this class.
   scoped_ptr<SearchHostToURLsMap> provider_map_;
 
diff --git a/chrome/browser/search_engines/search_provider_install_data_unittest.cc b/chrome/browser/search_engines/search_provider_install_data_unittest.cc
index ebc6616..a554255 100644
--- a/chrome/browser/search_engines/search_provider_install_data_unittest.cc
+++ b/chrome/browser/search_engines/search_provider_install_data_unittest.cc
@@ -125,8 +125,6 @@
   virtual void SetUp() OVERRIDE;
   virtual void TearDown() OVERRIDE;
 
-  void SimulateDefaultSearchIsManaged(const std::string& url);
-
  protected:
   TemplateURL* AddNewTemplateURL(const std::string& url,
                                  const base::string16& keyword);
@@ -172,29 +170,6 @@
   testing::Test::TearDown();
 }
 
-void SearchProviderInstallDataTest::SimulateDefaultSearchIsManaged(
-    const std::string& url) {
-  ASSERT_FALSE(url.empty());
-  TestingPrefServiceSyncable* service =
-      util_.profile()->GetTestingPrefService();
-  service->SetManagedPref(prefs::kDefaultSearchProviderEnabled,
-                          base::Value::CreateBooleanValue(true));
-  service->SetManagedPref(prefs::kDefaultSearchProviderSearchURL,
-                          base::Value::CreateStringValue(url));
-  service->SetManagedPref(prefs::kDefaultSearchProviderName,
-                          base::Value::CreateStringValue("managed"));
-  service->SetManagedPref(prefs::kDefaultSearchProviderKeyword,
-                          new base::StringValue("managed"));
-  // Clear the IDs that are not specified via policy.
-  service->SetManagedPref(prefs::kDefaultSearchProviderID,
-                          new base::StringValue(std::string()));
-  service->SetManagedPref(prefs::kDefaultSearchProviderPrepopulateID,
-                          new base::StringValue(std::string()));
-  util_.model()->Observe(chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED,
-                         content::NotificationService::AllSources(),
-                         content::NotificationService::NoDetails());
-}
-
 TemplateURL* SearchProviderInstallDataTest::AddNewTemplateURL(
     const std::string& url,
     const base::string16& keyword) {
@@ -239,8 +214,17 @@
 
   // Set a managed preference that establishes a default search provider.
   std::string host2 = "www.managedtest.com";
-  std::string url2 = "http://" + host2 + "/p{searchTerms}";
-  SimulateDefaultSearchIsManaged(url2);
+  util_.SetManagedDefaultSearchPreferences(
+      true,
+      "managed",
+      "managed",
+      "http://" + host2 + "/p{searchTerms}",
+      std::string(),
+      std::string(),
+      std::string(),
+      std::string(),
+      std::string());
+
   EXPECT_TRUE(util_.model()->is_default_search_managed());
 
   // Wait for the changes to be saved.
diff --git a/chrome/browser/search_engines/search_terms_data.cc b/chrome/browser/search_engines/search_terms_data.cc
index 7c6e0d7..abb201a 100644
--- a/chrome/browser/search_engines/search_terms_data.cc
+++ b/chrome/browser/search_engines/search_terms_data.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/search_engines/search_terms_data.h"
 
+#include "base/command_line.h"
 #include "base/logging.h"
 #include "base/metrics/field_trial.h"
 #include "base/prefs/pref_service.h"
@@ -15,6 +16,7 @@
 #include "chrome/browser/sync/glue/device_info.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
+#include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/browser_thread.h"
 #include "sync/protocol/sync.pb.h"
@@ -163,8 +165,15 @@
 #if defined(OS_ANDROID)
   sync_pb::SyncEnums::DeviceType device_type =
       browser_sync::DeviceInfo::GetLocalDeviceType();
-  return device_type == sync_pb::SyncEnums_DeviceType_TYPE_PHONE ?
-    "chrome-mobile-ext" : "chrome-ext";
+  if (device_type == sync_pb::SyncEnums_DeviceType_TYPE_PHONE) {
+    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+            switches::kEnableAnswersInSuggest)) {
+      return "chrome-mobile-ext-ansg";
+    } else {
+      return "chrome-mobile-ext";
+    }
+  }
+  return "chrome-ext";
 #else
   return "chrome-ext";
 #endif
diff --git a/chrome/browser/search_engines/template_url.cc b/chrome/browser/search_engines/template_url.cc
index 501b798..f19bf61 100644
--- a/chrome/browser/search_engines/template_url.cc
+++ b/chrome/browser/search_engines/template_url.cc
@@ -835,7 +835,7 @@
           search_terms_args_without_aqs.assisted_query_stats.clear();
           GURL base_url(ReplaceSearchTermsUsingTermsData(
               search_terms_args_without_aqs, search_terms_data, NULL));
-          if (base_url.SchemeIs(content::kHttpsScheme)) {
+          if (base_url.SchemeIs(url::kHttpsScheme)) {
             HandleReplacement(
                 "aqs", search_terms_args.assisted_query_stats, *i, &url);
           }
@@ -1112,6 +1112,33 @@
   return url.ReplaceComponents(rep);
 }
 
+// static
+bool TemplateURL::MatchesData(const TemplateURL* t_url,
+                              const TemplateURLData* data) {
+  if (!t_url || !data)
+    return !t_url && !data;
+
+  return (t_url->short_name() == data->short_name) &&
+      t_url->HasSameKeywordAs(*data) &&
+      (t_url->url() == data->url()) &&
+      (t_url->suggestions_url() == data->suggestions_url) &&
+      (t_url->instant_url() == data->instant_url) &&
+      (t_url->image_url() == data->image_url) &&
+      (t_url->new_tab_url() == data->new_tab_url) &&
+      (t_url->search_url_post_params() == data->search_url_post_params) &&
+      (t_url->suggestions_url_post_params() ==
+          data->suggestions_url_post_params) &&
+      (t_url->instant_url_post_params() == data->instant_url_post_params) &&
+      (t_url->image_url_post_params() == data->image_url_post_params) &&
+      (t_url->favicon_url() == data->favicon_url) &&
+      (t_url->safe_for_autoreplace() == data->safe_for_autoreplace) &&
+      (t_url->show_in_default_list() == data->show_in_default_list) &&
+      (t_url->input_encodings() == data->input_encodings) &&
+      (t_url->alternate_urls() == data->alternate_urls) &&
+      (t_url->search_terms_replacement_key() ==
+          data->search_terms_replacement_key);
+}
+
 base::string16 TemplateURL::AdjustedShortNameForLocaleDirection() const {
   base::string16 bidi_safe_short_name = data_.short_name;
   base::i18n::AdjustStringForLocaleDirection(&bidi_safe_short_name);
@@ -1132,6 +1159,14 @@
   return url_ref_.SupportsReplacementUsingTermsData(search_terms_data);
 }
 
+bool TemplateURL::HasGoogleBaseURLs() const {
+  return url_ref_.HasGoogleBaseURLs() ||
+      suggestions_url_ref_.HasGoogleBaseURLs() ||
+      instant_url_ref_.HasGoogleBaseURLs() ||
+      image_url_ref_.HasGoogleBaseURLs() ||
+      new_tab_url_ref_.HasGoogleBaseURLs();
+}
+
 bool TemplateURL::IsGoogleSearchURLWithReplaceableKeyword() const {
   return (GetType() == NORMAL) && url_ref_.HasGoogleBaseURLs() &&
       google_util::IsGoogleHostname(base::UTF16ToUTF8(data_.keyword()),
diff --git a/chrome/browser/search_engines/template_url.h b/chrome/browser/search_engines/template_url.h
index 5d1542b..9d04355 100644
--- a/chrome/browser/search_engines/template_url.h
+++ b/chrome/browser/search_engines/template_url.h
@@ -567,6 +567,11 @@
   // Generates a favicon URL from the specified url.
   static GURL GenerateFaviconURL(const GURL& url);
 
+  // Returns true if |t_url| and |data| are equal in all meaningful respects.
+  // Static to allow either or both params to be NULL.
+  static bool MatchesData(const TemplateURL* t_url,
+                          const TemplateURLData* data);
+
   Profile* profile() { return profile_; }
   const TemplateURLData& data() const { return data_; }
 
@@ -645,6 +650,9 @@
   bool SupportsReplacementUsingTermsData(
       const SearchTermsData& search_terms_data) const;
 
+  // Returns true if any URLRefs use Googe base URLs.
+  bool HasGoogleBaseURLs() const;
+
   // Returns true if this TemplateURL uses Google base URLs and has a keyword
   // of "google.TLD".  We use this to decide whether we can automatically
   // update the keyword to reflect the current Google base URL TLD.
diff --git a/chrome/browser/search_engines/template_url_parser.cc b/chrome/browser/search_engines/template_url_parser.cc
index 083aeec..5669a2c 100644
--- a/chrome/browser/search_engines/template_url_parser.cc
+++ b/chrome/browser/search_engines/template_url_parser.cc
@@ -94,8 +94,8 @@
   if (url.empty())
     return true;
   GURL gurl(url);
-  return gurl.is_valid() && (gurl.SchemeIs(content::kHttpScheme) ||
-                             gurl.SchemeIs(content::kHttpsScheme));
+  return gurl.is_valid() && (gurl.SchemeIs(url::kHttpScheme) ||
+                             gurl.SchemeIs(url::kHttpsScheme));
 }
 
 }  // namespace
@@ -252,8 +252,8 @@
         // favicon from the URL.
         context->derive_image_from_url_ = true;
       } else if (context->image_is_valid_for_favicon_ && image_url.is_valid() &&
-                 (image_url.SchemeIs(content::kHttpScheme) ||
-                  image_url.SchemeIs(content::kHttpsScheme))) {
+                 (image_url.SchemeIs(url::kHttpScheme) ||
+                  image_url.SchemeIs(url::kHttpsScheme))) {
         context->data_.favicon_url = image_url;
       }
       context->image_is_valid_for_favicon_ = false;
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data.cc b/chrome/browser/search_engines/template_url_prepopulate_data.cc
index d13dd47..81aa35b 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data.cc
+++ b/chrome/browser/search_engines/template_url_prepopulate_data.cc
@@ -80,7 +80,7 @@
 
 // Belgium
 const PrepopulatedEngine* engines_BE[] =
-    { &google, &bing_nl_BE, &bing_fr_BE, &yahoo_be, &yahoo_fr_be, };
+    { &google, &bing_nl_BE, &bing_fr_BE, &yahoo, &yahoo_fr, };
 
 // Bulgaria
 const PrepopulatedEngine* engines_BG[] =
@@ -128,7 +128,7 @@
 
 // China
 const PrepopulatedEngine* engines_CN[] =
-    { &google, &baidu, &sogou, &soso, };
+    { &google, &baidu, &sogou, };
 
 // Colombia
 const PrepopulatedEngine* engines_CO[] =
@@ -268,7 +268,7 @@
 
 // South Korea
 const PrepopulatedEngine* engines_KR[] =
-    { &google, &naver, &daum, &nate, };
+    { &google, &naver, &daum, };
 
 // Kazakhstan
 const PrepopulatedEngine* engines_KZ[] =
@@ -476,7 +476,7 @@
 
 // South Africa
 const PrepopulatedEngine* engines_ZA[] =
-    { &google, &bing, &yahoo_za, };
+    { &google, &bing, &yahoo, };
 
 // Zimbabwe
 const PrepopulatedEngine* engines_ZW[] =
@@ -494,17 +494,16 @@
   &bing_fr_FR,   &bing_it_IT,   &bing_ja_JP,   &bing_lv_LV,   &bing_nb_NO,
   &bing_nl_BE,   &bing_pl_PL,   &bing_pt_BR,   &bing_pt_PT,   &bing_ru_RU,
   &bing_sv_SE,   &bing_tr_TR,   &bing_zh_HK,   &bing_zh_TW,   &daum,
-  &google,       &kvasir,       &mail_ru,      &najdi,        &nate,
-  &naver,        &onet,         &seznam,       &sogou,        &soso,
-  &vinden,       &virgilio,     &yahoo,        &yahoo_ar,     &yahoo_at,
-  &yahoo_au,     &yahoo_be,     &yahoo_br,     &yahoo_ca,     &yahoo_ch,
-  &yahoo_cl,     &yahoo_co,     &yahoo_de,     &yahoo_dk,     &yahoo_es,
-  &yahoo_fi,     &yahoo_fr,     &yahoo_fr_be,  &yahoo_gr,     &yahoo_hk,
-  &yahoo_id,     &yahoo_in,     &yahoo_jp,     &yahoo_maktoob, &yahoo_mx,
-  &yahoo_my,     &yahoo_nl,     &yahoo_nz,     &yahoo_pe,     &yahoo_ph,
-  &yahoo_qc,     &yahoo_ro,     &yahoo_ru,     &yahoo_se,     &yahoo_sg,
-  &yahoo_th,     &yahoo_tr,     &yahoo_tw,     &yahoo_uk,     &yahoo_ve,
-  &yahoo_vn,     &yahoo_za,     &yandex_ru,    &yandex_tr,    &yandex_ua,
+  &google,       &kvasir,       &mail_ru,      &najdi,        &naver,
+  &onet,         &seznam,       &sogou,        &vinden,       &virgilio,
+  &yahoo,        &yahoo_ar,     &yahoo_at,     &yahoo_au,     &yahoo_br,
+  &yahoo_ca,     &yahoo_ch,     &yahoo_cl,     &yahoo_co,     &yahoo_de,
+  &yahoo_dk,     &yahoo_es,     &yahoo_fi,     &yahoo_fr,     &yahoo_gr,
+  &yahoo_hk,     &yahoo_id,     &yahoo_in,     &yahoo_jp,     &yahoo_maktoob,
+  &yahoo_mx,     &yahoo_my,     &yahoo_nl,     &yahoo_nz,     &yahoo_pe,
+  &yahoo_ph,     &yahoo_qc,     &yahoo_ro,     &yahoo_ru,     &yahoo_se,
+  &yahoo_sg,     &yahoo_th,     &yahoo_tr,     &yahoo_tw,     &yahoo_uk,
+  &yahoo_ve,     &yahoo_vn,     &yandex_ru,    &yandex_tr,    &yandex_ua,
 
   // UMA-only engines:
   &atlas_cz,     &atlas_sk,     &avg,          &babylon,      &conduit,
diff --git a/chrome/browser/search_engines/template_url_service.cc b/chrome/browser/search_engines/template_url_service.cc
index 3457868..c6c9a42 100644
--- a/chrome/browser/search_engines/template_url_service.cc
+++ b/chrome/browser/search_engines/template_url_service.cc
@@ -51,38 +51,13 @@
 #include "sync/protocol/search_engine_specifics.pb.h"
 #include "sync/protocol/sync.pb.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
 
 typedef SearchHostToURLsMap::TemplateURLSet TemplateURLSet;
 typedef TemplateURLService::SyncDataMap SyncDataMap;
 
 namespace {
 
-bool TemplateURLMatchesData(const TemplateURL* url1,
-                            const TemplateURLData* url2) {
-  if (!url1 || !url2)
-    return !url1 && !url2;
-
-  return (url1->short_name() == url2->short_name) &&
-         url1->HasSameKeywordAs(*url2) &&
-         (url1->url() == url2->url()) &&
-         (url1->suggestions_url() == url2->suggestions_url) &&
-         (url1->instant_url() == url2->instant_url) &&
-         (url1->image_url() == url2->image_url) &&
-         (url1->new_tab_url() == url2->new_tab_url) &&
-         (url1->search_url_post_params() == url2->search_url_post_params) &&
-         (url1->suggestions_url_post_params() ==
-          url2->suggestions_url_post_params) &&
-         (url1->instant_url_post_params() == url2->instant_url_post_params) &&
-         (url1->image_url_post_params() == url2->image_url_post_params) &&
-         (url1->favicon_url() == url2->favicon_url) &&
-         (url1->safe_for_autoreplace() == url2->safe_for_autoreplace) &&
-         (url1->show_in_default_list() == url2->show_in_default_list) &&
-         (url1->input_encodings() == url2->input_encodings) &&
-         (url1->alternate_urls() == url2->alternate_urls) &&
-         (url1->search_terms_replacement_key() ==
-          url2->search_terms_replacement_key);
-}
-
 const char kFirstPotentialEngineHistogramName[] =
     "Search.FirstPotentialEngineCalled";
 
@@ -290,7 +265,8 @@
       processing_syncer_changes_(false),
       pending_synced_default_search_(false),
       dsp_change_origin_(DSP_CHANGE_OTHER),
-      default_search_manager_(new DefaultSearchManager(GetPrefs())) {
+      default_search_manager_(
+          GetPrefs(), DefaultSearchManager::ObserverCallback()) {
   DCHECK(profile_);
   Init(NULL, 0);
 }
@@ -310,7 +286,9 @@
       models_associated_(false),
       processing_syncer_changes_(false),
       pending_synced_default_search_(false),
-      dsp_change_origin_(DSP_CHANGE_OTHER) {
+      dsp_change_origin_(DSP_CHANGE_OTHER),
+      default_search_manager_(
+          GetPrefs(), DefaultSearchManager::ObserverCallback()) {
   Init(initializers, count);
 }
 
@@ -321,6 +299,103 @@
 }
 
 // static
+bool TemplateURLService::LoadDefaultSearchProviderFromPrefs(
+    PrefService* prefs,
+    scoped_ptr<TemplateURLData>* default_provider_data,
+    bool* is_managed) {
+  if (!prefs || !prefs->HasPrefPath(prefs::kDefaultSearchProviderSearchURL) ||
+      !prefs->HasPrefPath(prefs::kDefaultSearchProviderKeyword))
+    return false;
+
+  const PrefService::Preference* pref =
+      prefs->FindPreference(prefs::kDefaultSearchProviderSearchURL);
+  *is_managed = pref && pref->IsManaged();
+
+  if (!prefs->GetBoolean(prefs::kDefaultSearchProviderEnabled)) {
+    // The user doesn't want a default search provider.
+    default_provider_data->reset(NULL);
+    return true;
+  }
+
+  base::string16 name =
+      base::UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderName));
+  base::string16 keyword =
+      base::UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderKeyword));
+  if (keyword.empty())
+    return false;
+  std::string search_url =
+      prefs->GetString(prefs::kDefaultSearchProviderSearchURL);
+  // Force URL to be non-empty.  We've never supported this case, but past bugs
+  // might have resulted in it slipping through; eventually this code can be
+  // replaced with a DCHECK(!search_url.empty());.
+  if (search_url.empty())
+    return false;
+  std::string suggest_url =
+      prefs->GetString(prefs::kDefaultSearchProviderSuggestURL);
+  std::string instant_url =
+      prefs->GetString(prefs::kDefaultSearchProviderInstantURL);
+  std::string image_url =
+      prefs->GetString(prefs::kDefaultSearchProviderImageURL);
+  std::string new_tab_url =
+      prefs->GetString(prefs::kDefaultSearchProviderNewTabURL);
+  std::string search_url_post_params =
+      prefs->GetString(prefs::kDefaultSearchProviderSearchURLPostParams);
+  std::string suggest_url_post_params =
+      prefs->GetString(prefs::kDefaultSearchProviderSuggestURLPostParams);
+  std::string instant_url_post_params =
+      prefs->GetString(prefs::kDefaultSearchProviderInstantURLPostParams);
+  std::string image_url_post_params =
+      prefs->GetString(prefs::kDefaultSearchProviderImageURLPostParams);
+  std::string icon_url =
+      prefs->GetString(prefs::kDefaultSearchProviderIconURL);
+  std::string encodings =
+      prefs->GetString(prefs::kDefaultSearchProviderEncodings);
+  std::string id_string = prefs->GetString(prefs::kDefaultSearchProviderID);
+  std::string prepopulate_id =
+      prefs->GetString(prefs::kDefaultSearchProviderPrepopulateID);
+  const base::ListValue* alternate_urls =
+      prefs->GetList(prefs::kDefaultSearchProviderAlternateURLs);
+  std::string search_terms_replacement_key = prefs->GetString(
+      prefs::kDefaultSearchProviderSearchTermsReplacementKey);
+
+  default_provider_data->reset(new TemplateURLData);
+  (*default_provider_data)->short_name = name;
+  (*default_provider_data)->SetKeyword(keyword);
+  (*default_provider_data)->SetURL(search_url);
+  (*default_provider_data)->suggestions_url = suggest_url;
+  (*default_provider_data)->instant_url = instant_url;
+  (*default_provider_data)->image_url = image_url;
+  (*default_provider_data)->new_tab_url = new_tab_url;
+  (*default_provider_data)->search_url_post_params = search_url_post_params;
+  (*default_provider_data)->suggestions_url_post_params =
+      suggest_url_post_params;
+  (*default_provider_data)->instant_url_post_params = instant_url_post_params;
+  (*default_provider_data)->image_url_post_params = image_url_post_params;
+  (*default_provider_data)->favicon_url = GURL(icon_url);
+  (*default_provider_data)->show_in_default_list = true;
+  (*default_provider_data)->alternate_urls.clear();
+  for (size_t i = 0; i < alternate_urls->GetSize(); ++i) {
+    std::string alternate_url;
+    if (alternate_urls->GetString(i, &alternate_url))
+      (*default_provider_data)->alternate_urls.push_back(alternate_url);
+  }
+  (*default_provider_data)->search_terms_replacement_key =
+      search_terms_replacement_key;
+  base::SplitString(encodings, ';', &(*default_provider_data)->input_encodings);
+  if (!id_string.empty() && !*is_managed) {
+    int64 value;
+    base::StringToInt64(id_string, &value);
+    (*default_provider_data)->id = value;
+  }
+  if (!prepopulate_id.empty() && !*is_managed) {
+    int value;
+    base::StringToInt(prepopulate_id, &value);
+    (*default_provider_data)->prepopulate_id = value;
+  }
+  return true;
+}
+
+// static
 base::string16 TemplateURLService::GenerateKeyword(const GURL& url) {
   DCHECK(url.is_valid());
   // Strip "www." off the front of the keyword; otherwise the keyword won't work
@@ -346,9 +421,9 @@
     // type a web address, but rather an FTP, file:, or other scheme URL, or a
     // search query with some sort of initial operator (e.g. "site:").
     if (result.compare(0, scheme_component.end(),
-                       base::ASCIIToUTF16(content::kHttpScheme)) &&
+                       base::ASCIIToUTF16(url::kHttpScheme)) &&
         result.compare(0, scheme_component.end(),
-                       base::ASCIIToUTF16(content::kHttpsScheme)))
+                       base::ASCIIToUTF16(url::kHttpsScheme)))
       return base::string16();
 
     // Include trailing ':'.
@@ -398,6 +473,79 @@
       search_terms_data, NULL));
 }
 
+void TemplateURLService::SaveDefaultSearchProviderToPrefs(
+    const TemplateURL* t_url,
+    PrefService* prefs) const {
+  if (!prefs || load_failed_)
+    return;
+
+  bool enabled = false;
+  std::string search_url;
+  std::string suggest_url;
+  std::string instant_url;
+  std::string image_url;
+  std::string new_tab_url;
+  std::string search_url_post_params;
+  std::string suggest_url_post_params;
+  std::string instant_url_post_params;
+  std::string image_url_post_params;
+  std::string icon_url;
+  std::string encodings;
+  std::string short_name;
+  std::string keyword;
+  std::string id_string;
+  std::string prepopulate_id;
+  base::ListValue alternate_urls;
+  std::string search_terms_replacement_key;
+  if (t_url) {
+    DCHECK_EQ(TemplateURL::NORMAL, t_url->GetType());
+    enabled = true;
+    search_url = t_url->url();
+    suggest_url = t_url->suggestions_url();
+    instant_url = t_url->instant_url();
+    image_url = t_url->image_url();
+    new_tab_url = t_url->new_tab_url();
+    search_url_post_params = t_url->search_url_post_params();
+    suggest_url_post_params = t_url->suggestions_url_post_params();
+    instant_url_post_params = t_url->instant_url_post_params();
+    image_url_post_params = t_url->image_url_post_params();
+    GURL icon_gurl = t_url->favicon_url();
+    if (!icon_gurl.is_empty())
+      icon_url = icon_gurl.spec();
+    encodings = JoinString(t_url->input_encodings(), ';');
+    short_name = base::UTF16ToUTF8(t_url->short_name());
+    keyword = base::UTF16ToUTF8(t_url->keyword());
+    id_string = base::Int64ToString(t_url->id());
+    prepopulate_id = base::Int64ToString(t_url->prepopulate_id());
+    for (size_t i = 0; i < t_url->alternate_urls().size(); ++i)
+      alternate_urls.AppendString(t_url->alternate_urls()[i]);
+    search_terms_replacement_key = t_url->search_terms_replacement_key();
+  }
+  prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, enabled);
+  prefs->SetString(prefs::kDefaultSearchProviderSearchURL, search_url);
+  prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, suggest_url);
+  prefs->SetString(prefs::kDefaultSearchProviderInstantURL, instant_url);
+  prefs->SetString(prefs::kDefaultSearchProviderImageURL, image_url);
+  prefs->SetString(prefs::kDefaultSearchProviderNewTabURL, new_tab_url);
+  prefs->SetString(prefs::kDefaultSearchProviderSearchURLPostParams,
+                   search_url_post_params);
+  prefs->SetString(prefs::kDefaultSearchProviderSuggestURLPostParams,
+                   suggest_url_post_params);
+  prefs->SetString(prefs::kDefaultSearchProviderInstantURLPostParams,
+                   instant_url_post_params);
+  prefs->SetString(prefs::kDefaultSearchProviderImageURLPostParams,
+                   image_url_post_params);
+  prefs->SetString(prefs::kDefaultSearchProviderIconURL, icon_url);
+  prefs->SetString(prefs::kDefaultSearchProviderEncodings, encodings);
+  prefs->SetString(prefs::kDefaultSearchProviderName, short_name);
+  prefs->SetString(prefs::kDefaultSearchProviderKeyword, keyword);
+  prefs->SetString(prefs::kDefaultSearchProviderID, id_string);
+  prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID, prepopulate_id);
+  prefs->Set(prefs::kDefaultSearchProviderAlternateURLs, alternate_urls);
+  prefs->SetString(prefs::kDefaultSearchProviderSearchTermsReplacementKey,
+      search_terms_replacement_key);
+}
+
 bool TemplateURLService::CanReplaceKeyword(
     const base::string16& keyword,
     const GURL& url,
@@ -426,7 +574,7 @@
 void TemplateURLService::FindMatchingKeywords(
     const base::string16& prefix,
     bool support_replacement_only,
-    TemplateURLVector* matches) const {
+    TemplateURLVector* matches) {
   // Sanity check args.
   if (prefix.empty())
     return;
@@ -640,31 +788,15 @@
     return;
   ++url->data_.usage_count;
 
-  if (service_.get())
-    service_.get()->UpdateKeyword(url->data());
+  if (service_)
+    service_->UpdateKeyword(url->data());
 }
 
 void TemplateURLService::ResetTemplateURL(TemplateURL* url,
                                           const base::string16& title,
                                           const base::string16& keyword,
                                           const std::string& search_url) {
-  if (!loaded_)
-    return;
-  DCHECK(!keyword.empty());
-  DCHECK(!search_url.empty());
-  TemplateURLData data(url->data());
-  data.short_name = title;
-  data.SetKeyword(keyword);
-  if (search_url != data.url()) {
-    data.SetURL(search_url);
-    // The urls have changed, reset the favicon url.
-    data.favicon_url = GURL();
-  }
-  data.safe_for_autoreplace = false;
-  data.last_modified = time_provider_();
-  TemplateURL new_url(url->profile(), data);
-  UIThreadSearchTermsData search_terms_data(url->profile());
-  if (UpdateNoNotify(url, new_url, search_terms_data))
+  if (ResetTemplateURLNoNotify(url, title, keyword, search_url))
     NotifyObservers();
 }
 
@@ -679,19 +811,15 @@
 void TemplateURLService::SetUserSelectedDefaultSearchProvider(
     TemplateURL* url) {
   SetDefaultSearchProvider(url);
-  if (default_search_manager_) {
-    if (url)
-      default_search_manager_->SetUserSelectedDefaultSearchEngine(url->data());
-    else
-      default_search_manager_->ClearUserSelectedDefaultSearchEngine();
-  }
+  if (url)
+    default_search_manager_.SetUserSelectedDefaultSearchEngine(url->data());
+  else
+    default_search_manager_.ClearUserSelectedDefaultSearchEngine();
 }
 
 TemplateURL* TemplateURLService::GetDefaultSearchProvider() {
-  if (loaded_ && !load_failed_)
-    return default_search_provider_;
-  // We're not loaded, rely on the default search provider stored in prefs.
-  return initial_default_search_provider_.get();
+  return (loaded_ && !load_failed_) ?
+      default_search_provider_ : initial_default_search_provider_.get();
 }
 
 bool TemplateURLService::IsSearchResultsPageFromDefaultSearchProvider(
@@ -802,11 +930,10 @@
   if (loaded_ || load_handle_)
     return;
 
-  if (!service_.get()) {
+  if (!service_)
     service_ = WebDataService::FromBrowserContext(profile_);
-  }
 
-  if (service_.get()) {
+  if (service_) {
     load_handle_ = service_->GetKeywords(this);
   } else {
     ChangeToLoadedState();
@@ -833,6 +960,7 @@
     // Results are null if the database went away or (most likely) wasn't
     // loaded.
     load_failed_ = true;
+    service_ = NULL;
     ChangeToLoadedState();
     on_loaded_callbacks_.Notify();
     return;
@@ -1039,7 +1167,7 @@
         new_changes.push_back(syncer::SyncChange(FROM_HERE,
                                                  syncer::SyncChange::ACTION_ADD,
                                                  sync_data));
-        // Ignore the delete attempt. This means we never end up reseting the
+        // Ignore the delete attempt. This means we never end up resetting the
         // default search provider due to an ACTION_DELETE from sync.
         continue;
       }
@@ -1110,6 +1238,15 @@
   DCHECK(sync_processor.get());
   DCHECK(sync_error_factory.get());
   syncer::SyncMergeResult merge_result(type);
+
+  // Disable sync if we failed to load.
+  if (load_failed_) {
+    merge_result.set_error(syncer::SyncError(
+        FROM_HERE, syncer::SyncError::DATATYPE_ERROR,
+        "Local database load failed.", syncer::SEARCH_ENGINES));
+    return merge_result;
+  }
+
   sync_processor_ = sync_processor.Pass();
   sync_error_factory_ = sync_error_factory.Pass();
 
@@ -1499,8 +1636,8 @@
 
   // Request a server check for the correct Google URL if Google is the
   // default search engine and not in headless mode.
-  if (profile_ && initial_default_search_provider_.get() &&
-      initial_default_search_provider_->url_ref().HasGoogleBaseURLs()) {
+  if (profile_ && initial_default_search_provider_ &&
+      initial_default_search_provider_->HasGoogleBaseURLs()) {
     scoped_ptr<base::Environment> env(base::Environment::Create());
     if (!env->HasVar(env_vars::kHeadless))
       GoogleURLTracker::RequestServerCheck(profile_, false);
@@ -1615,179 +1752,10 @@
   loaded_ = true;
 }
 
-void TemplateURLService::SaveDefaultSearchProviderToPrefs(
-    const TemplateURL* t_url) {
-  PrefService* prefs = GetPrefs();
-  if (!prefs)
-    return;
-
-  bool enabled = false;
-  std::string search_url;
-  std::string suggest_url;
-  std::string instant_url;
-  std::string image_url;
-  std::string new_tab_url;
-  std::string search_url_post_params;
-  std::string suggest_url_post_params;
-  std::string instant_url_post_params;
-  std::string image_url_post_params;
-  std::string icon_url;
-  std::string encodings;
-  std::string short_name;
-  std::string keyword;
-  std::string id_string;
-  std::string prepopulate_id;
-  base::ListValue alternate_urls;
-  std::string search_terms_replacement_key;
-  if (t_url) {
-    DCHECK_EQ(TemplateURL::NORMAL, t_url->GetType());
-    enabled = true;
-    search_url = t_url->url();
-    suggest_url = t_url->suggestions_url();
-    instant_url = t_url->instant_url();
-    image_url = t_url->image_url();
-    new_tab_url = t_url->new_tab_url();
-    search_url_post_params = t_url->search_url_post_params();
-    suggest_url_post_params = t_url->suggestions_url_post_params();
-    instant_url_post_params = t_url->instant_url_post_params();
-    image_url_post_params = t_url->image_url_post_params();
-    GURL icon_gurl = t_url->favicon_url();
-    if (!icon_gurl.is_empty())
-      icon_url = icon_gurl.spec();
-    encodings = JoinString(t_url->input_encodings(), ';');
-    short_name = base::UTF16ToUTF8(t_url->short_name());
-    keyword = base::UTF16ToUTF8(t_url->keyword());
-    id_string = base::Int64ToString(t_url->id());
-    prepopulate_id = base::Int64ToString(t_url->prepopulate_id());
-    for (size_t i = 0; i < t_url->alternate_urls().size(); ++i)
-      alternate_urls.AppendString(t_url->alternate_urls()[i]);
-    search_terms_replacement_key = t_url->search_terms_replacement_key();
-  }
-  prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, enabled);
-  prefs->SetString(prefs::kDefaultSearchProviderSearchURL, search_url);
-  prefs->SetString(prefs::kDefaultSearchProviderSuggestURL, suggest_url);
-  prefs->SetString(prefs::kDefaultSearchProviderInstantURL, instant_url);
-  prefs->SetString(prefs::kDefaultSearchProviderImageURL, image_url);
-  prefs->SetString(prefs::kDefaultSearchProviderNewTabURL, new_tab_url);
-  prefs->SetString(prefs::kDefaultSearchProviderSearchURLPostParams,
-                   search_url_post_params);
-  prefs->SetString(prefs::kDefaultSearchProviderSuggestURLPostParams,
-                   suggest_url_post_params);
-  prefs->SetString(prefs::kDefaultSearchProviderInstantURLPostParams,
-                   instant_url_post_params);
-  prefs->SetString(prefs::kDefaultSearchProviderImageURLPostParams,
-                   image_url_post_params);
-  prefs->SetString(prefs::kDefaultSearchProviderIconURL, icon_url);
-  prefs->SetString(prefs::kDefaultSearchProviderEncodings, encodings);
-  prefs->SetString(prefs::kDefaultSearchProviderName, short_name);
-  prefs->SetString(prefs::kDefaultSearchProviderKeyword, keyword);
-  prefs->SetString(prefs::kDefaultSearchProviderID, id_string);
-  prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID, prepopulate_id);
-  prefs->Set(prefs::kDefaultSearchProviderAlternateURLs, alternate_urls);
-  prefs->SetString(prefs::kDefaultSearchProviderSearchTermsReplacementKey,
-      search_terms_replacement_key);
-}
-
-bool TemplateURLService::LoadDefaultSearchProviderFromPrefs(
-    scoped_ptr<TemplateURLData>* default_provider_data,
-    bool* is_managed) {
-  PrefService* prefs = GetPrefs();
-  if (!prefs || !prefs->HasPrefPath(prefs::kDefaultSearchProviderSearchURL) ||
-      !prefs->HasPrefPath(prefs::kDefaultSearchProviderKeyword))
-    return false;
-
-  const PrefService::Preference* pref =
-      prefs->FindPreference(prefs::kDefaultSearchProviderSearchURL);
-  *is_managed = pref && pref->IsManaged();
-
-  if (!prefs->GetBoolean(prefs::kDefaultSearchProviderEnabled)) {
-    // The user doesn't want a default search provider.
-    default_provider_data->reset(NULL);
-    return true;
-  }
-
-  base::string16 name =
-      base::UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderName));
-  base::string16 keyword =
-      base::UTF8ToUTF16(prefs->GetString(prefs::kDefaultSearchProviderKeyword));
-  if (keyword.empty())
-    return false;
-  std::string search_url =
-      prefs->GetString(prefs::kDefaultSearchProviderSearchURL);
-  // Force URL to be non-empty.  We've never supported this case, but past bugs
-  // might have resulted in it slipping through; eventually this code can be
-  // replaced with a DCHECK(!search_url.empty());.
-  if (search_url.empty())
-    return false;
-  std::string suggest_url =
-      prefs->GetString(prefs::kDefaultSearchProviderSuggestURL);
-  std::string instant_url =
-      prefs->GetString(prefs::kDefaultSearchProviderInstantURL);
-  std::string image_url =
-      prefs->GetString(prefs::kDefaultSearchProviderImageURL);
-  std::string new_tab_url =
-      prefs->GetString(prefs::kDefaultSearchProviderNewTabURL);
-  std::string search_url_post_params =
-      prefs->GetString(prefs::kDefaultSearchProviderSearchURLPostParams);
-  std::string suggest_url_post_params =
-      prefs->GetString(prefs::kDefaultSearchProviderSuggestURLPostParams);
-  std::string instant_url_post_params =
-      prefs->GetString(prefs::kDefaultSearchProviderInstantURLPostParams);
-  std::string image_url_post_params =
-      prefs->GetString(prefs::kDefaultSearchProviderImageURLPostParams);
-  std::string icon_url =
-      prefs->GetString(prefs::kDefaultSearchProviderIconURL);
-  std::string encodings =
-      prefs->GetString(prefs::kDefaultSearchProviderEncodings);
-  std::string id_string = prefs->GetString(prefs::kDefaultSearchProviderID);
-  std::string prepopulate_id =
-      prefs->GetString(prefs::kDefaultSearchProviderPrepopulateID);
-  const base::ListValue* alternate_urls =
-      prefs->GetList(prefs::kDefaultSearchProviderAlternateURLs);
-  std::string search_terms_replacement_key = prefs->GetString(
-      prefs::kDefaultSearchProviderSearchTermsReplacementKey);
-
-  default_provider_data->reset(new TemplateURLData);
-  (*default_provider_data)->short_name = name;
-  (*default_provider_data)->SetKeyword(keyword);
-  (*default_provider_data)->SetURL(search_url);
-  (*default_provider_data)->suggestions_url = suggest_url;
-  (*default_provider_data)->instant_url = instant_url;
-  (*default_provider_data)->image_url = image_url;
-  (*default_provider_data)->new_tab_url = new_tab_url;
-  (*default_provider_data)->search_url_post_params = search_url_post_params;
-  (*default_provider_data)->suggestions_url_post_params =
-      suggest_url_post_params;
-  (*default_provider_data)->instant_url_post_params = instant_url_post_params;
-  (*default_provider_data)->image_url_post_params = image_url_post_params;
-  (*default_provider_data)->favicon_url = GURL(icon_url);
-  (*default_provider_data)->show_in_default_list = true;
-  (*default_provider_data)->alternate_urls.clear();
-  for (size_t i = 0; i < alternate_urls->GetSize(); ++i) {
-    std::string alternate_url;
-    if (alternate_urls->GetString(i, &alternate_url))
-      (*default_provider_data)->alternate_urls.push_back(alternate_url);
-  }
-  (*default_provider_data)->search_terms_replacement_key =
-      search_terms_replacement_key;
-  base::SplitString(encodings, ';', &(*default_provider_data)->input_encodings);
-  if (!id_string.empty() && !*is_managed) {
-    int64 value;
-    base::StringToInt64(id_string, &value);
-    (*default_provider_data)->id = value;
-  }
-  if (!prepopulate_id.empty() && !*is_managed) {
-    int value;
-    base::StringToInt(prepopulate_id, &value);
-    (*default_provider_data)->prepopulate_id = value;
-  }
-  return true;
-}
-
 void TemplateURLService::ClearDefaultProviderFromPrefs() {
   // We overwrite user preferences. If the default search engine is managed,
   // there is no effect.
-  SaveDefaultSearchProviderToPrefs(NULL);
+  SaveDefaultSearchProviderToPrefs(NULL, GetPrefs());
   // Default value for kDefaultSearchProviderEnabled is true.
   PrefService* prefs = GetPrefs();
   if (prefs)
@@ -1884,7 +1852,7 @@
   if (!existing_turl->sync_guid().empty())
     guid_to_template_map_[existing_turl->sync_guid()] = existing_turl;
 
-  if (service_.get())
+  if (service_)
     service_->UpdateKeyword(existing_turl->data());
 
   // Inform sync of the update.
@@ -1987,8 +1955,7 @@
   for (TemplateURLVector::iterator i(template_urls_.begin());
        i != template_urls_.end(); ++i) {
     TemplateURL* t_url = *i;
-    if (t_url->url_ref().HasGoogleBaseURLs() ||
-        t_url->suggestions_url_ref().HasGoogleBaseURLs()) {
+    if (t_url->HasGoogleBaseURLs()) {
       TemplateURL updated_turl(t_url->profile(), t_url->data());
       updated_turl.ResetKeywordIfNecessary(false);
       KeywordToTemplateMap::const_iterator existing_entry =
@@ -2023,8 +1990,8 @@
     // Set |initial_default_search_provider_| from the preferences.  We use this
     // value for default search provider until the database has been loaded.
     scoped_ptr<TemplateURLData> data;
-    if (!LoadDefaultSearchProviderFromPrefs(&data,
-                                            &is_default_search_managed_)) {
+    if (!LoadDefaultSearchProviderFromPrefs(
+            GetPrefs(), &data, &is_default_search_managed_)) {
       // Prefs does not specify, so rely on the prepopulated engines.  This
       // should happen only the first time Chrome is started.
       data =
@@ -2045,8 +2012,8 @@
   // and all the preference items have not been saved.  In that case, we
   // don't have yet a default.  It would be much better if we could save
   // preferences in batches and trigger notifications at the end.
-  LoadDefaultSearchProviderFromPrefs(&new_default_from_prefs,
-                                     &new_is_default_managed);
+  LoadDefaultSearchProviderFromPrefs(
+      GetPrefs(), &new_default_from_prefs, &new_is_default_managed);
   if (!is_default_search_managed_ && !new_is_default_managed) {
     // We're not interested in cases where the default was and remains
     // unmanaged.  In that case, preferences have no impact on the default.
@@ -2057,13 +2024,12 @@
     // The default was managed and remains managed.  Update the default only
     // if it has changed; we don't want to respond to changes triggered by
     // SaveDefaultSearchProviderToPrefs.
-    if (TemplateURLMatchesData(default_search_provider_,
-                               new_default_from_prefs.get()))
+    if (TemplateURL::MatchesData(default_search_provider_,
+                                 new_default_from_prefs.get()))
       return;
     if (!new_default_from_prefs) {
-      // default_search_provider_ can't be NULL otherwise
-      // TemplateURLMatchesData would have returned true.  Remove this now
-      // invalid value.
+      // |default_search_provider_| can't be NULL or MatchesData() would have
+      // returned true.  Remove this now invalid value.
       TemplateURL* old_default = default_search_provider_;
       bool success = SetDefaultSearchProviderNoNotify(NULL);
       DCHECK(success);
@@ -2173,10 +2139,10 @@
     // Don't mark the url as edited, otherwise we won't be able to rev the
     // template urls we ship with.
     url->data_.show_in_default_list = true;
-    if (service_.get() && (url->GetType() == TemplateURL::NORMAL))
+    if (service_ && (url->GetType() == TemplateURL::NORMAL))
       service_->UpdateKeyword(url->data());
 
-    if (url->url_ref().HasGoogleBaseURLs()) {
+    if (url->HasGoogleBaseURLs()) {
       GoogleURLTracker::RequestServerCheck(profile_, false);
 #if defined(ENABLE_RLZ)
       RLZTracker::RecordProductEvent(rlz_lib::CHROME,
@@ -2191,7 +2157,7 @@
     return true;
 
   if (!is_default_search_managed_) {
-    SaveDefaultSearchProviderToPrefs(url);
+    SaveDefaultSearchProviderToPrefs(url, GetPrefs());
 
     // If we are syncing, we want to set the synced pref that will notify other
     // instances to change their default to this new search provider.
@@ -2208,7 +2174,7 @@
     }
   }
 
-  if (service_.get())
+  if (service_)
     service_->SetDefaultSearchProviderID(url ? url->id() : 0);
 
   // Inform sync the change to the show_in_default_list flag.
@@ -2249,9 +2215,9 @@
     } else {
       base::string16 new_keyword =
           UniquifyKeyword(*existing_keyword_turl, false);
-      ResetTemplateURL(existing_keyword_turl,
-                       existing_keyword_turl->short_name(), new_keyword,
-                       existing_keyword_turl->url());
+      ResetTemplateURLNoNotify(existing_keyword_turl,
+                               existing_keyword_turl->short_name(), new_keyword,
+                               existing_keyword_turl->url());
     }
   }
   template_urls_.push_back(template_url);
@@ -2260,7 +2226,7 @@
   if (newly_adding &&
       (template_url->GetType() !=
           TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) {
-    if (service_.get())
+    if (service_)
       service_->AddKeyword(template_url->data());
 
     // Inform sync of the addition. Note that this will assign a GUID to
@@ -2287,7 +2253,7 @@
   template_urls_.erase(i);
 
   if (template_url->GetType() != TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION) {
-    if (service_.get())
+    if (service_)
       service_->RemoveKeyword(template_url->id());
 
     // Inform sync of the deletion.
@@ -2312,6 +2278,30 @@
   delete template_url;
 }
 
+bool TemplateURLService::ResetTemplateURLNoNotify(
+    TemplateURL* url,
+    const base::string16& title,
+    const base::string16& keyword,
+    const std::string& search_url) {
+  if (!loaded_)
+    return false;
+  DCHECK(!keyword.empty());
+  DCHECK(!search_url.empty());
+  TemplateURLData data(url->data());
+  data.short_name = title;
+  data.SetKeyword(keyword);
+  if (search_url != data.url()) {
+    data.SetURL(search_url);
+    // The urls have changed, reset the favicon url.
+    data.favicon_url = GURL();
+  }
+  data.safe_for_autoreplace = false;
+  data.last_modified = time_provider_();
+  TemplateURL new_url(url->profile(), data);
+  UIThreadSearchTermsData search_terms_data(url->profile());
+  return UpdateNoNotify(url, new_url, search_terms_data);
+}
+
 void TemplateURLService::NotifyObservers() {
   if (!loaded_)
     return;
@@ -2340,7 +2330,7 @@
     if (template_url->created_by_policy()) {
       if (template_url == *default_search_provider &&
           is_default_search_managed_ &&
-          TemplateURLMatchesData(template_url, default_from_prefs)) {
+          TemplateURL::MatchesData(template_url, default_from_prefs)) {
         // If the database specified a default search provider that was set
         // by policy, and the default search provider from the preferences
         // is also set by policy and they are the same, keep the entry in the
@@ -2357,7 +2347,7 @@
         *default_search_provider = NULL;
 
       i = template_urls->erase(i);
-      if (service_.get())
+      if (service_)
         service_->RemoveKeyword(template_url->id());
       delete template_url;
     } else {
@@ -2581,7 +2571,7 @@
         (template_url->GetType() !=
             TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) {
       template_url->data_.sync_guid = base::GenerateGUID();
-      if (service_.get())
+      if (service_)
         service_->UpdateKeyword(template_url->data());
     }
   }
@@ -2596,8 +2586,8 @@
 
   // Check if default search provider is now managed.
   scoped_ptr<TemplateURLData> default_from_prefs;
-  LoadDefaultSearchProviderFromPrefs(&default_from_prefs,
-                                     &is_default_search_managed_);
+  LoadDefaultSearchProviderFromPrefs(
+      GetPrefs(), &default_from_prefs, &is_default_search_managed_);
 
   // Remove entries that were created because of policy as they may have
   // changed since the database was saved.
@@ -2610,8 +2600,8 @@
   if (is_default_search_managed_) {
     SetTemplateURLs(template_urls);
 
-    if (TemplateURLMatchesData(default_search_provider,
-                               default_from_prefs.get())) {
+    if (TemplateURL::MatchesData(default_search_provider,
+                                 default_from_prefs.get())) {
       // The value from the preferences was previously stored in the database.
       // Reuse it.
     } else {
@@ -2669,7 +2659,7 @@
       // Always save the default search provider to prefs. That way we don't
       // have to worry about it being out of sync.
       if (default_search_provider_)
-        SaveDefaultSearchProviderToPrefs(default_search_provider_);
+        SaveDefaultSearchProviderToPrefs(default_search_provider_, GetPrefs());
     }
   }
 }
@@ -2696,7 +2686,7 @@
 }
 
 TemplateURL* TemplateURLService::CreateTemplateURLForExtension(
-    const ExtensionKeyword& extension_keyword) const {
+    const ExtensionKeyword& extension_keyword) {
   TemplateURLData data;
   data.short_name = base::UTF8ToUTF16(extension_keyword.extension_name);
   data.SetKeyword(base::UTF8ToUTF16(extension_keyword.extension_keyword));
@@ -2709,7 +2699,7 @@
 
 TemplateURL* TemplateURLService::FindTemplateURLForExtension(
     const std::string& extension_id,
-    TemplateURL::Type type) const {
+    TemplateURL::Type type) {
   DCHECK_NE(TemplateURL::NORMAL, type);
   for (TemplateURLVector::const_iterator i = template_urls_.begin();
        i != template_urls_.end(); ++i) {
@@ -2744,7 +2734,8 @@
   if (!new_dse) {
     scoped_ptr<TemplateURLData> default_provider;
     bool is_managed;
-    if (LoadDefaultSearchProviderFromPrefs(&default_provider, &is_managed) &&
+    if (LoadDefaultSearchProviderFromPrefs(
+            GetPrefs(), &default_provider, &is_managed) &&
         default_provider) {
       for (TemplateURLVector::const_iterator i = template_urls_.begin();
            i != template_urls_.end(); ++i) {
diff --git a/chrome/browser/search_engines/template_url_service.h b/chrome/browser/search_engines/template_url_service.h
index f8896d5..654b25c 100644
--- a/chrome/browser/search_engines/template_url_service.h
+++ b/chrome/browser/search_engines/template_url_service.h
@@ -101,6 +101,17 @@
   TemplateURLService(const Initializer* initializers, const int count);
   virtual ~TemplateURLService();
 
+  // Creates a TemplateURLData that was previously saved to |prefs| via
+  // SaveDefaultSearchProviderToPrefs or set via policy.
+  // Returns true if successful, false otherwise.
+  // If the user or the policy has opted for no default search, this
+  // returns true but default_provider is set to NULL.
+  // |*is_managed| specifies whether the default is managed via policy.
+  static bool LoadDefaultSearchProviderFromPrefs(
+      PrefService* prefs,
+      scoped_ptr<TemplateURLData>* default_provider_data,
+      bool* is_managed);
+
   // Generates a suitable keyword for the specified url, which must be valid.
   // This is guaranteed not to return an empty string, since TemplateURLs should
   // never have an empty keyword.
@@ -124,6 +135,11 @@
       const TemplateURL* t_url,
       const SearchTermsData& search_terms_data);
 
+  // Saves enough of url to |prefs| so that it can be loaded from preferences on
+  // start up.
+  void SaveDefaultSearchProviderToPrefs(const TemplateURL* url,
+                                        PrefService* prefs) const;
+
   // Returns true if there is no TemplateURL that conflicts with the
   // keyword/url pair, or there is one but it can be replaced. If there is an
   // existing keyword that can be replaced and template_url_to_replace is
@@ -140,7 +156,7 @@
   // TemplateURLs that support replacement are returned.
   void FindMatchingKeywords(const base::string16& prefix,
                             bool support_replacement_only,
-                            TemplateURLVector* matches) const;
+                            TemplateURLVector* matches);
 
   // Looks up |keyword| and returns the element it maps to.  Returns NULL if
   // the keyword was not found.
@@ -260,7 +276,7 @@
   // revved: all existing prepopulated entries are checked against the current
   // prepopulate data, any now-extraneous safe_for_autoreplace() entries are
   // removed, any existing engines are reset to the provided data (except for
-  // user-edited names or keywords), and any new prepopulated anegines are
+  // user-edited names or keywords), and any new prepopulated engines are
   // added.
   //
   // After this, the default search engine is reset to the default entry in the
@@ -393,16 +409,12 @@
                            DontUpdateKeywordSearchForNonReplaceable);
   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ChangeGoogleBaseValue);
   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, MergeDeletesUnusedProviders);
-  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest,
-                           CreateSyncDataFromTemplateURL);
-  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest,
-                           CreateTemplateURLFromSyncData);
   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, UniquifyKeyword);
   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest,
+                           IsLocalTemplateURLBetter);
+  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest,
                            ResolveSyncKeywordConflict);
   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, PreSyncDeletes);
-  FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest,
-                           IsLocalTemplateURLBetter);
   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, MergeInSyncTemplateURL);
 
   friend class TemplateURLServiceTestUtilBase;
@@ -460,20 +472,6 @@
   // Transitions to the loaded state.
   void ChangeToLoadedState();
 
-  // Saves enough of url to preferences so that it can be loaded from
-  // preferences on start up.
-  void SaveDefaultSearchProviderToPrefs(const TemplateURL* url);
-
-  // Creates a TemplateURLData that was previously saved to prefs via
-  // SaveDefaultSearchProviderToPrefs or set via policy.
-  // Returns true if successful, false otherwise.
-  // If the user or the policy has opted for no default search, this
-  // returns true but default_provider is set to NULL.
-  // |*is_managed| specifies whether the default is managed via policy.
-  bool LoadDefaultSearchProviderFromPrefs(
-      scoped_ptr<TemplateURLData>* default_provider,
-      bool* is_managed);
-
   // Clears user preferences describing the default search engine.
   void ClearDefaultProviderFromPrefs();
 
@@ -566,6 +564,13 @@
   // Caller is responsible for notifying observers.
   void RemoveNoNotify(TemplateURL* template_url);
 
+  // Like ResetTemplateURL(), but instead of notifying observers, returns
+  // whether anything has changed.
+  bool ResetTemplateURLNoNotify(TemplateURL* url,
+                                const base::string16& title,
+                                const base::string16& keyword,
+                                const std::string& search_url);
+
   // Notify the observers that the model has changed.  This is done only if the
   // model is loaded.
   void NotifyObservers();
@@ -668,11 +673,11 @@
 
   // Returns a new TemplateURL for the given extension.
   TemplateURL* CreateTemplateURLForExtension(
-      const ExtensionKeyword& extension_keyword) const;
+      const ExtensionKeyword& extension_keyword);
 
   // Returns the TemplateURL associated with |extension_id|, if any.
   TemplateURL* FindTemplateURLForExtension(const std::string& extension_id,
-                                           TemplateURL::Type type) const;
+                                           TemplateURL::Type type);
 
   // Finds the most recently-installed NORMAL_CONTROLLED_BY_EXTENSION engine
   // that supports replacement and wants to be default, if any.
@@ -711,7 +716,9 @@
   // Whether the keywords have been loaded.
   bool loaded_;
 
-  // Did loading fail? This is only valid if loaded_ is true.
+  // Set when the web data service fails to load properly.  This prevents
+  // further communication with sync or writing to prefs, so we don't persist
+  // inconsistent state data anywhere.
   bool load_failed_;
 
   // If non-zero, we're waiting on a load.
@@ -725,7 +732,7 @@
   std::vector<history::URLVisitedDetails> visits_to_add_;
 
   // Once loaded, the default search provider.  This is a pointer to a
-  // TemplateURL owned by template_urls_.
+  // TemplateURL owned by |template_urls_|.
   TemplateURL* default_search_provider_;
 
   // The initial search provider extracted from preferences. This is only valid
@@ -779,9 +786,8 @@
   // Stores a list of callbacks to be run after TemplateURLService has loaded.
   base::CallbackList<void(void)> on_loaded_callbacks_;
 
-  // Helper class to manage the default search engine. This will be NULL when
-  // using the testing-specific constructor.
-  scoped_ptr<DefaultSearchManager> default_search_manager_;
+  // Helper class to manage the default search engine.
+  DefaultSearchManager default_search_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(TemplateURLService);
 };
diff --git a/chrome/browser/search_engines/template_url_service_sync_unittest.cc b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
index 1b0332a..d0ec2d9 100644
--- a/chrome/browser/search_engines/template_url_service_sync_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
@@ -1881,9 +1881,9 @@
   // updated time.
   TemplateURL* added_turl = model()->GetTemplateURLForKeyword(
       ASCIIToUTF16(kNewKeyword));
+  ASSERT_TRUE(added_turl);
   base::Time new_timestamp = added_turl->last_modified();
   EXPECT_GE(new_timestamp, pre_merge_time);
-  ASSERT_TRUE(added_turl);
   std::string sync_guid = added_turl->sync_guid();
 
   // Bring down a copy of the prepopulate engine from Sync with the old values,
diff --git a/chrome/browser/search_engines/template_url_service_unittest.cc b/chrome/browser/search_engines/template_url_service_unittest.cc
index d6ca738..5237b7e 100644
--- a/chrome/browser/search_engines/template_url_service_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_unittest.cc
@@ -500,7 +500,7 @@
   data.safe_for_autoreplace = false;
   TemplateURL* t_url2 = new TemplateURL(test_util_.profile(), data);
   model()->Add(t_url2);
-  VerifyObserverCount(2);
+  VerifyObserverCount(1);
   EXPECT_EQ(t_url2, model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")));
   EXPECT_EQ(ASCIIToUTF16("fourth"), t_url2->short_name());
   EXPECT_EQ(ASCIIToUTF16("keyword"), t_url2->keyword());
diff --git a/chrome/browser/search_engines/template_url_unittest.cc b/chrome/browser/search_engines/template_url_unittest.cc
index c8a4085..89c0334 100644
--- a/chrome/browser/search_engines/template_url_unittest.cc
+++ b/chrome/browser/search_engines/template_url_unittest.cc
@@ -565,6 +565,7 @@
       "{google:baseURL}?{searchTerms}&{google:cursorPosition}",
       "http://www.google.com/?foo&cp=15&" },
   };
+  UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/");
   TemplateURLData data;
   data.input_encodings.push_back("UTF-8");
   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
@@ -601,6 +602,7 @@
       "{google:baseURL}?{searchTerms}&{google:currentPageUrl}",
       "http://www.google.com/?foo&url=http%3A%2F%2Fg.com%2F%2B-%2F*%26%3D&" },
   };
+  UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/");
   TemplateURLData data;
   data.input_encodings.push_back("UTF-8");
   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
@@ -1297,6 +1299,7 @@
 }
 
 TEST_F(TemplateURLTest, ReflectsBookmarkBarPinned) {
+  UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/");
   TemplateURLData data;
   data.input_encodings.push_back("UTF-8");
   data.SetURL("{google:baseURL}?{google:bookmarkBarPinned}q={searchTerms}");
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc
index cf069bb..fcd601a 100644
--- a/chrome/browser/sessions/session_restore.cc
+++ b/chrome/browser/sessions/session_restore.cc
@@ -49,7 +49,6 @@
 #include "content/public/browser/session_storage_namespace.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension_set.h"
 #include "net/base/network_change_notifier.h"
@@ -1074,8 +1073,7 @@
 
     // TODO(jcampan): http://crbug.com/8123 we should not need to set the
     //                initial focus explicitly.
-    browser->tab_strip_model()->GetActiveWebContents()->
-        GetView()->SetInitialFocus();
+    browser->tab_strip_model()->GetActiveWebContents()->SetInitialFocus();
 
     if (!browser_shown_) {
       browser_shown_ = true;
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc
index 67f3961..029200b 100644
--- a/chrome/browser/sessions/session_restore_browsertest.cc
+++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -42,7 +42,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/bindings_policy.h"
 #include "content/public/common/page_transition_types.h"
 #include "content/public/test/browser_test_utils.h"
@@ -215,7 +214,7 @@
   // Check the restored tabs have a root window.
   for (int i = 0; i < tabs; ++i) {
     content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
-    gfx::NativeView window = contents->GetView()->GetNativeView();
+    gfx::NativeView window = contents->GetNativeView();
     bool tab_has_root_window = !!window->GetRootWindow();
     EXPECT_TRUE(tab_has_root_window);
   }
@@ -223,7 +222,7 @@
 #endif  // USE_AURA
 
 // Verify that restored tabs have correct disposition. Only one tab should
-// have disposition->visibility state.
+// have "visible" visibility state, the rest should not.
 // (http://crbug.com/155365 http://crbug.com/118269)
 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
     RestoredTabsHaveCorrectVisibilityState) {
diff --git a/chrome/browser/signin/screenlock_bridge.cc b/chrome/browser/signin/screenlock_bridge.cc
new file mode 100644
index 0000000..995b1d9
--- /dev/null
+++ b/chrome/browser/signin/screenlock_bridge.cc
@@ -0,0 +1,78 @@
+// 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.
+
+#include "chrome/browser/signin/screenlock_bridge.h"
+
+#include "base/logging.h"
+#include "chrome/browser/profiles/profile_window.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "components/signin/core/browser/signin_manager.h"
+
+#if defined(OS_CHROMEOS)
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/session_manager_client.h"
+#endif
+
+namespace {
+
+base::LazyInstance<ScreenlockBridge> g_screenlock_bridge_bridge_instance =
+    LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
+// static
+ScreenlockBridge* ScreenlockBridge::Get() {
+  return g_screenlock_bridge_bridge_instance.Pointer();
+}
+
+// static
+std::string ScreenlockBridge::GetAuthenticatedUserEmail(Profile* profile) {
+  // |profile| has to be a signed-in profile with SigninManager already
+  // created. Otherwise, just crash to collect stack.
+  SigninManagerBase* signin_manager =
+      SigninManagerFactory::GetForProfileIfExists(profile);
+  return signin_manager->GetAuthenticatedUsername();
+}
+
+ScreenlockBridge::ScreenlockBridge() : lock_handler_(NULL) {
+}
+
+ScreenlockBridge::~ScreenlockBridge() {
+}
+
+void ScreenlockBridge::SetLockHandler(LockHandler* lock_handler) {
+  DCHECK(lock_handler_ == NULL || lock_handler == NULL);
+  lock_handler_ = lock_handler;
+  if (lock_handler_)
+    FOR_EACH_OBSERVER(Observer, observers_, OnScreenDidLock());
+  else
+    FOR_EACH_OBSERVER(Observer, observers_, OnScreenDidUnlock());
+}
+
+bool ScreenlockBridge::IsLocked() const {
+  return lock_handler_ != NULL;
+}
+
+void ScreenlockBridge::Lock(Profile* profile) {
+#if defined(OS_CHROMEOS)
+  chromeos::SessionManagerClient* session_manager =
+      chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
+  session_manager->RequestLockScreen();
+#else
+  profiles::LockProfile(profile);
+#endif
+}
+
+void ScreenlockBridge::Unlock(Profile* profile) {
+  if (lock_handler_)
+    lock_handler_->Unlock(GetAuthenticatedUserEmail(profile));
+}
+
+void ScreenlockBridge::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void ScreenlockBridge::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
diff --git a/chrome/browser/signin/screenlock_bridge.h b/chrome/browser/signin/screenlock_bridge.h
new file mode 100644
index 0000000..cce1b7c
--- /dev/null
+++ b/chrome/browser/signin/screenlock_bridge.h
@@ -0,0 +1,102 @@
+// 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.
+
+#ifndef CHROME_BROWSER_SIGNIN_SCREENLOCK_BRIDGE_H_
+#define CHROME_BROWSER_SIGNIN_SCREENLOCK_BRIDGE_H_
+
+#include "base/callback_forward.h"
+#include "base/lazy_instance.h"
+#include "base/macros.h"
+#include "base/observer_list.h"
+
+namespace gfx {
+class Image;
+}
+
+class Profile;
+
+// ScreenlockBridge brings together the screenLockPrivate API and underlying
+// support. On ChromeOS, it delegates calls to the ScreenLocker. On other
+// platforms, it delegates calls to UserManagerUI (and friends).
+class ScreenlockBridge {
+ public:
+  class Observer {
+   public:
+    // Invoked after the screen is locked.
+    virtual void OnScreenDidLock() = 0;
+    // Invoked after the screen lock is dismissed.
+    virtual void OnScreenDidUnlock() = 0;
+   protected:
+    virtual ~Observer() {}
+  };
+
+  class LockHandler {
+   public:
+    // Supported authentication types. Keep in sync with the enum in
+    // user_pod_row.js.
+    enum AuthType {
+      OFFLINE_PASSWORD = 0,
+      ONLINE_SIGN_IN = 1,
+      NUMERIC_PIN = 2,
+      USER_CLICK = 3,
+    };
+
+    // Displays |message| in a banner on the lock screen.
+    virtual void ShowBannerMessage(const std::string& message) = 0;
+
+    // Shows a button inside the user pod on the lock screen with an icon.
+    // |callback| is invoked when the icon is clicked. This is deprecated now.
+    virtual void ShowUserPodButton(const std::string& user_email,
+                                   const gfx::Image& icon,
+                                   const base::Closure& callback) = 0;
+
+    // Hides the user pod button for a user.
+    virtual void HideUserPodButton(const std::string& user_email) = 0;
+
+    // (Re)enable lock screen UI.
+    virtual void EnableInput() = 0;
+
+    // Set the authentication type to be used on the lock screen.
+    virtual void SetAuthType(const std::string& user_email,
+                             AuthType auth_type,
+                             const std::string& auth_value) = 0;
+
+    // Returns the authentication type used for a user.
+    virtual AuthType GetAuthType(const std::string& user_email) const = 0;
+
+    // Unlock from easy unlock app for a user.
+    virtual void Unlock(const std::string& user_email) = 0;
+
+   protected:
+    virtual ~LockHandler() {}
+  };
+
+  static ScreenlockBridge* Get();
+  static std::string GetAuthenticatedUserEmail(Profile* profile);
+
+  void SetLockHandler(LockHandler* lock_handler);
+
+  bool IsLocked() const;
+  void Lock(Profile* profile);
+  void Unlock(Profile* profile);
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+  LockHandler* lock_handler() { return lock_handler_; }
+
+ private:
+  friend struct base::DefaultLazyInstanceTraits<ScreenlockBridge>;
+  friend struct base::DefaultDeleter<ScreenlockBridge>;
+
+  ScreenlockBridge();
+  ~ScreenlockBridge();
+
+  LockHandler* lock_handler_;  // Not owned
+  ObserverList<Observer, true> observers_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScreenlockBridge);
+};
+
+#endif  // CHROME_BROWSER_SIGNIN_SCREENLOCK_BRIDGE_H_
diff --git a/chrome/browser/signin/signin_tracker_unittest.cc b/chrome/browser/signin/signin_tracker_unittest.cc
index 645fd89..63b34e0 100644
--- a/chrome/browser/signin/signin_tracker_unittest.cc
+++ b/chrome/browser/signin/signin_tracker_unittest.cc
@@ -100,5 +100,6 @@
   EXPECT_CALL(observer_, SigninFailed(_)).Times(0);
 
   mock_signin_manager_->SetAuthenticatedUsername("user@gmail.com");
-  fake_oauth2_token_service_->IssueRefreshToken("refresh_token");
+  fake_oauth2_token_service_->IssueRefreshTokenForUser(
+      "user@gmail.com", "refresh_token");
 }
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc
index 668aae0..8761c8f 100644
--- a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc
+++ b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc
@@ -373,8 +373,7 @@
                           base::Bind(&CheckRenderViewType,
                                      callback,
                                      render_process_id,
-                                     render_view_id,
-                                     !context.requested_by_page_element));
+                                     render_view_id));
 }
 
 content::SpeechRecognitionEventListener*
@@ -397,8 +396,7 @@
 void ChromeSpeechRecognitionManagerDelegate::CheckRenderViewType(
     base::Callback<void(bool ask_user, bool is_allowed)> callback,
     int render_process_id,
-    int render_view_id,
-    bool js_api) {
+    int render_view_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   const content::RenderViewHost* render_view_host =
       content::RenderViewHost::FromID(render_process_id, render_view_id);
@@ -407,16 +405,9 @@
   bool check_permission = false;
 
   if (!render_view_host) {
-    if (!js_api) {
-      // If there is no render view, we cannot show the speech bubble, so this
-      // is not allowed.
-      allowed = false;
-      check_permission = false;
-    } else {
-      // This happens for extensions. Manifest should be checked for permission.
-      allowed = true;
-      check_permission = false;
-    }
+    // This happens for extensions. Manifest should be checked for permission.
+    allowed = true;
+    check_permission = false;
     BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                             base::Bind(callback, check_permission, allowed));
     return;
@@ -434,28 +425,14 @@
 
   extensions::ViewType view_type = extensions::GetViewType(web_contents);
 
-  // TODO(kalman): Also enable speech bubble for extension popups
-  // (VIEW_TYPE_EXTENSION_POPUP) once popup-like control UI works properly in
-  // extensions: http://crbug.com/163851.
-  // Right now the extension popup closes and dismisses immediately on user
-  // click.
   if (view_type == extensions::VIEW_TYPE_TAB_CONTENTS ||
       view_type == extensions::VIEW_TYPE_APP_WINDOW ||
       view_type == extensions::VIEW_TYPE_VIRTUAL_KEYBOARD ||
-      // Only allow requests through JavaScript API (|js_api| = true).
-      // Requests originating from html element (|js_api| = false) would want
-      // to show bubble which isn't quite intuitive from a background page. Also
-      // see todo above about issues with rendering such bubbles from extension
-      // popups.
-      (view_type == extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE &&
-       js_api)) {
-    // If it is a tab, we can show the speech input bubble or check for
-    // permission. For apps, this means manifest would be checked for
-    // permission.
-
+      view_type == extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
+    // If it is a tab, we can check for permission. For apps, this means
+    // manifest would be checked for permission.
     allowed = true;
-    if (js_api)
-      check_permission = true;
+    check_permission = true;
   }
 
   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h
index 1d33a71..cc57804 100644
--- a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h
+++ b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h
@@ -59,8 +59,7 @@
   static void CheckRenderViewType(
       base::Callback<void(bool ask_user, bool is_allowed)> callback,
       int render_process_id,
-      int render_view_id,
-      bool js_api);
+      int render_view_id);
 
   scoped_refptr<OptionalRequestInfo> optional_request_info_;
   scoped_refptr<TabWatcher> tab_watcher_;
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.cc b/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.cc
deleted file mode 100644
index da18bd4..0000000
--- a/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.cc
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h"
-
-#include "base/strings/utf_string_conversions.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/speech_recognition_manager.h"
-#include "content/public/browser/speech_recognition_session_context.h"
-#include "content/public/common/speech_recognition_error.h"
-#include "grit/generated_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-
-using content::BrowserThread;
-using content::SpeechRecognitionManager;
-
-namespace {
-
-bool RequiresBubble(int session_id) {
-  return SpeechRecognitionManager::GetInstance()->
-      GetSessionContext(session_id).requested_by_page_element;
-}
-
-}  // namespace
-
-namespace speech {
-
-ChromeSpeechRecognitionManagerDelegateBubbleUI
-::ChromeSpeechRecognitionManagerDelegateBubbleUI() {
-}
-
-ChromeSpeechRecognitionManagerDelegateBubbleUI
-::~ChromeSpeechRecognitionManagerDelegateBubbleUI() {
-  if (bubble_controller_.get())
-    bubble_controller_->CloseBubble();
-}
-
-void ChromeSpeechRecognitionManagerDelegateBubbleUI::InfoBubbleButtonClicked(
-    int session_id, SpeechRecognitionBubble::Button button) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
-  // Note, the session might have been destroyed, therefore avoid calls to the
-  // manager which imply its existance (e.g., GetSessionContext()).
-
-  if (button == SpeechRecognitionBubble::BUTTON_CANCEL) {
-    GetBubbleController()->CloseBubble();
-    last_session_config_.reset();
-
-    // We can safely call AbortSession even if the session has already ended,
-    // the manager's public methods are reliable and will handle it properly.
-    SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
-  } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) {
-    GetBubbleController()->CloseBubble();
-    RestartLastSession();
-  } else {
-    NOTREACHED();
-  }
-}
-
-void ChromeSpeechRecognitionManagerDelegateBubbleUI::InfoBubbleFocusChanged(
-    int session_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
-  // This check is needed since on some systems (MacOS), in rare cases, if the
-  // user clicks repeatedly and fast on the input element, the FocusChanged
-  // event (corresponding to the old session that should be aborted) can be
-  // received after a new session (corresponding to the 2nd click) is started.
-  if (GetBubbleController()->GetActiveSessionID() != session_id)
-    return;
-
-  // Note, the session might have been destroyed, therefore avoid calls to the
-  // manager which imply its existance (e.g., GetSessionContext()).
-  GetBubbleController()->CloseBubble();
-  last_session_config_.reset();
-
-  // Clicking outside the bubble means we should abort.
-  SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
-}
-
-void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnRecognitionStart(
-    int session_id) {
-  ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart(session_id);
-
-  const content::SpeechRecognitionSessionContext& context =
-      SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
-
-  if (RequiresBubble(session_id)) {
-    // Copy the configuration of the session (for the "try again" button).
-    last_session_config_.reset(new content::SpeechRecognitionSessionConfig(
-        SpeechRecognitionManager::GetInstance()->GetSessionConfig(session_id)));
-
-    // Create and show the bubble. It will be closed upon the OnEnd event.
-    GetBubbleController()->CreateBubble(session_id,
-                                        context.render_process_id,
-                                        context.render_view_id,
-                                        context.element_rect);
-  }
-}
-
-void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnAudioStart(
-    int session_id) {
-  ChromeSpeechRecognitionManagerDelegate::OnAudioStart(session_id);
-
-  if (RequiresBubble(session_id)) {
-    DCHECK_EQ(session_id, GetBubbleController()->GetActiveSessionID());
-    GetBubbleController()->SetBubbleRecordingMode();
-  }
-}
-
-void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnAudioEnd(
-    int session_id) {
-  ChromeSpeechRecognitionManagerDelegate::OnAudioEnd(session_id);
-
-  // OnAudioEnd can be also raised after an abort, when the bubble has already
-  // been closed.
-  if (GetBubbleController()->GetActiveSessionID() == session_id) {
-    DCHECK(RequiresBubble(session_id));
-    GetBubbleController()->SetBubbleRecognizingMode();
-  }
-}
-
-void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnRecognitionError(
-    int session_id, const content::SpeechRecognitionError& error) {
-  ChromeSpeechRecognitionManagerDelegate::OnRecognitionError(session_id, error);
-
-  // An error can be dispatched when the bubble is not visible anymore.
-  if (GetBubbleController()->GetActiveSessionID() != session_id)
-    return;
-  DCHECK(RequiresBubble(session_id));
-
-  int error_message_id = 0;
-  switch (error.code) {
-    case content::SPEECH_RECOGNITION_ERROR_AUDIO:
-      switch (error.details) {
-        case content::SPEECH_AUDIO_ERROR_DETAILS_NO_MIC:
-          error_message_id = IDS_SPEECH_INPUT_NO_MIC;
-          break;
-        default:
-          error_message_id = IDS_SPEECH_INPUT_MIC_ERROR;
-          break;
-      }
-      break;
-    case content::SPEECH_RECOGNITION_ERROR_ABORTED:
-      error_message_id = IDS_SPEECH_INPUT_ABORTED;
-      break;
-    case content::SPEECH_RECOGNITION_ERROR_NO_SPEECH:
-      error_message_id = IDS_SPEECH_INPUT_NO_SPEECH;
-      break;
-    case content::SPEECH_RECOGNITION_ERROR_NO_MATCH:
-      error_message_id = IDS_SPEECH_INPUT_NO_RESULTS;
-      break;
-    case content::SPEECH_RECOGNITION_ERROR_NETWORK:
-      error_message_id = IDS_SPEECH_INPUT_NET_ERROR;
-      break;
-    default:
-      NOTREACHED() << "unknown error " << error.code;
-      return;
-  }
-  GetBubbleController()->SetBubbleMessage(
-      l10n_util::GetStringUTF16(error_message_id));
-
-}
-
-void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnAudioLevelsChange(
-    int session_id, float volume, float noise_volume) {
-  ChromeSpeechRecognitionManagerDelegate::OnAudioLevelsChange(
-      session_id, volume, noise_volume);
-
-  if (GetBubbleController()->GetActiveSessionID() == session_id) {
-    DCHECK(RequiresBubble(session_id));
-    GetBubbleController()->SetBubbleInputVolume(volume, noise_volume);
-  }
-}
-
-void ChromeSpeechRecognitionManagerDelegateBubbleUI::OnRecognitionEnd(
-    int session_id) {
-  ChromeSpeechRecognitionManagerDelegate::OnRecognitionEnd(session_id);
-
-  // The only case in which the OnRecognitionEnd should not close the bubble is
-  // when we are showing an error. In this case the bubble will be closed by
-  // the |InfoBubbleFocusChanged| method, when the users clicks either the
-  // "Cancel" button or outside of the bubble.
-  if (GetBubbleController()->GetActiveSessionID() == session_id &&
-      !GetBubbleController()->IsShowingMessage()) {
-    DCHECK(RequiresBubble(session_id));
-    GetBubbleController()->CloseBubble();
-  }
-}
-
-void ChromeSpeechRecognitionManagerDelegateBubbleUI::TabClosedCallback(
-    int render_process_id, int render_view_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  ChromeSpeechRecognitionManagerDelegate::TabClosedCallback(
-      render_process_id, render_view_id);
-
-  // Avoid instantiating a bubble_controller_ if not needed. Thus, prefer a
-  // checked access to bubble_controller_ to GetBubbleController().
-  if (bubble_controller_.get())
-    bubble_controller_->CloseBubbleForRenderViewOnUIThread(render_process_id,
-                                                           render_view_id);
-}
-
-SpeechRecognitionBubbleController*
-ChromeSpeechRecognitionManagerDelegateBubbleUI::GetBubbleController() {
-  if (!bubble_controller_.get())
-    bubble_controller_ = new SpeechRecognitionBubbleController(this);
-  return bubble_controller_.get();
-}
-
-void ChromeSpeechRecognitionManagerDelegateBubbleUI::RestartLastSession() {
-  DCHECK(last_session_config_.get());
-  SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance();
-  const int new_session_id = manager->CreateSession(*last_session_config_);
-  DCHECK_NE(SpeechRecognitionManager::kSessionIDInvalid, new_session_id);
-  last_session_config_.reset();
-  manager->StartSession(new_session_id);
-}
-
-}  // namespace speech
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h b/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h
deleted file mode 100644
index e9e25e1..0000000
--- a/chrome/browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_SPEECH_CHROME_SPEECH_RECOGNITION_MANAGER_DELEGATE_BUBBLE_UI_H_
-#define CHROME_BROWSER_SPEECH_CHROME_SPEECH_RECOGNITION_MANAGER_DELEGATE_BUBBLE_UI_H_
-
-#include "base/compiler_specific.h"
-#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h"
-#include "chrome/browser/speech/speech_recognition_bubble_controller.h"
-
-namespace speech {
-
-// This class extends ChromeSpeechRecognitionManagerDelegate to add the behavior
-// required to handle the (bubble) UI for speech recognition sessions initiated
-// by input elements with a x-webkit-speech attribute. This extended behavior is
-// achieved by means of overriding some SpeechRecognitionEventListener methods
-// and intercepting the calls required to show, animate and hide the bubble UI.
-class ChromeSpeechRecognitionManagerDelegateBubbleUI
-    : public ChromeSpeechRecognitionManagerDelegate,
-      public SpeechRecognitionBubbleControllerDelegate {
- public:
-  ChromeSpeechRecognitionManagerDelegateBubbleUI();
-  virtual ~ChromeSpeechRecognitionManagerDelegateBubbleUI();
-
- protected:
-  // SpeechRecognitionBubbleControllerDelegate methods.
-  virtual void InfoBubbleButtonClicked(
-      int session_id, SpeechRecognitionBubble::Button button) OVERRIDE;
-  virtual void InfoBubbleFocusChanged(int session_id) OVERRIDE;
-
-  // Overridden base class SpeechRecognitionEventListener methods.
-  virtual void OnRecognitionStart(int session_id) OVERRIDE;
-  virtual void OnAudioStart(int session_id) OVERRIDE;
-  virtual void OnAudioEnd(int session_id) OVERRIDE;
-  virtual void OnRecognitionEnd(int session_id) OVERRIDE;
-  virtual void OnRecognitionError(
-      int session_id, const content::SpeechRecognitionError& error) OVERRIDE;
-  virtual void OnAudioLevelsChange(
-      int session_id, float volume, float noise_volume) OVERRIDE;
-
-  // Starts a new recognition session, using the config of the last one
-  // (which is copied into |last_session_config_|). Used for "try again".
-  void RestartLastSession();
-
-  // Called on the UI thread by the base class when tab closure was detected.
-  virtual void TabClosedCallback(
-      int render_process_id, int render_view_id) OVERRIDE;
-
- private:
-  // Lazy initializer for bubble controller.
-  SpeechRecognitionBubbleController* GetBubbleController();
-
-  scoped_refptr<SpeechRecognitionBubbleController> bubble_controller_;
-  scoped_ptr<content::SpeechRecognitionSessionConfig> last_session_config_;
-
-  DISALLOW_COPY_AND_ASSIGN(ChromeSpeechRecognitionManagerDelegateBubbleUI);
-};
-
-}  // namespace speech
-
-#endif  // CHROME_BROWSER_SPEECH_CHROME_SPEECH_RECOGNITION_MANAGER_DELEGATE_BUBBLE_UI_H_
diff --git a/chrome/browser/speech/extension_api/tts_extension_api.cc b/chrome/browser/speech/extension_api/tts_extension_api.cc
index 36549ce..89db1c5 100644
--- a/chrome/browser/speech/extension_api/tts_extension_api.cc
+++ b/chrome/browser/speech/extension_api/tts_extension_api.cc
@@ -135,7 +135,7 @@
     delete this;
 }
 
-bool TtsSpeakFunction::RunImpl() {
+bool TtsSpeakFunction::RunAsync() {
   std::string text;
   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &text));
   if (text.size() > 32768) {
diff --git a/chrome/browser/speech/extension_api/tts_extension_api.h b/chrome/browser/speech/extension_api/tts_extension_api.h
index b4dfcd6..bb96474 100644
--- a/chrome/browser/speech/extension_api/tts_extension_api.h
+++ b/chrome/browser/speech/extension_api/tts_extension_api.h
@@ -23,7 +23,7 @@
 class TtsSpeakFunction : public ChromeAsyncExtensionFunction {
  private:
   virtual ~TtsSpeakFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
   DECLARE_EXTENSION_FUNCTION("tts.speak", TTS_SPEAK)
 };
 
diff --git a/chrome/browser/speech/speech_recognition_bubble.cc b/chrome/browser/speech/speech_recognition_bubble.cc
deleted file mode 100644
index 611eb7f..0000000
--- a/chrome/browser/speech/speech_recognition_bubble.cc
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/speech/speech_recognition_bubble.h"
-
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "base/message_loop/message_loop.h"
-#include "chrome/browser/tab_contents/tab_util.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/image/image_skia_operations.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/screen.h"
-
-using content::WebContents;
-
-namespace {
-
-const color_utils::HSL kGrayscaleShift = { -1, 0, 0.6 };
-const int kWarmingUpAnimationStartMs = 500;
-const int kWarmingUpAnimationStepMs = 100;
-const int kRecognizingAnimationStepMs = 100;
-
-// A lazily initialized singleton to hold all the image used by the speech
-// recognition bubbles and safely destroy them on exit.
-class SpeechRecognitionBubbleImages {
- public:
-  const std::vector<gfx::ImageSkia>& spinner() const { return spinner_; }
-  const std::vector<gfx::ImageSkia>& warm_up() const { return warm_up_; }
-  gfx::ImageSkia* mic_full() const { return mic_full_; }
-  gfx::ImageSkia* mic_empty() const { return mic_empty_; }
-  gfx::ImageSkia* mic_noise() const { return mic_noise_; }
-  gfx::ImageSkia* mic_mask() const { return mic_mask_; }
-
- private:
-  // Private constructor to enforce singleton.
-  friend struct base::DefaultLazyInstanceTraits<SpeechRecognitionBubbleImages>;
-  SpeechRecognitionBubbleImages();
-
-  std::vector<gfx::ImageSkia> spinner_;  // Frames for the progress spinner.
-  std::vector<gfx::ImageSkia> warm_up_;  // Frames for the warm up animation.
-
-  // These images are owned by ResourceBundle and need not be destroyed.
-  gfx::ImageSkia* mic_full_;  // Mic image with full volume.
-  gfx::ImageSkia* mic_noise_;  // Mic image with full noise volume.
-  gfx::ImageSkia* mic_empty_;  // Mic image with zero volume.
-  gfx::ImageSkia* mic_mask_;  // Gradient mask used by the volume indicator.
-};
-
-SpeechRecognitionBubbleImages::SpeechRecognitionBubbleImages() {
-  mic_empty_ = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-      IDR_SPEECH_INPUT_MIC_EMPTY);
-  mic_noise_ = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-      IDR_SPEECH_INPUT_MIC_NOISE);
-  mic_full_ = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-      IDR_SPEECH_INPUT_MIC_FULL);
-  mic_mask_ = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-      IDR_SPEECH_INPUT_MIC_MASK);
-
-  // The sprite image consists of all the animation frames put together in one
-  // horizontal/wide image. Each animation frame is square in shape within the
-  // sprite.
-  const gfx::ImageSkia* spinner_image = ui::ResourceBundle::GetSharedInstance().
-      GetImageSkiaNamed(IDR_SPEECH_INPUT_SPINNER);
-  int frame_size = spinner_image->height();
-
-  // When recording starts up, it may take a short while (few ms or even a
-  // couple of seconds) before the audio device starts really capturing data.
-  // This is more apparent on first use. To cover such cases we show a warming
-  // up state in the bubble starting with a blank spinner image. If audio data
-  // starts coming in within a couple hundred ms, we switch to the recording
-  // UI and if it takes longer, we show the real warm up animation frames.
-  // This reduces visual jank for the most part.
-  SkBitmap empty_spinner;
-  empty_spinner.setConfig(SkBitmap::kARGB_8888_Config, frame_size, frame_size);
-  empty_spinner.allocPixels();
-  empty_spinner.eraseRGB(255, 255, 255);
-  // |empty_spinner| has solid color. Pixel doubling a solid color is ok.
-  warm_up_.push_back(gfx::ImageSkia::CreateFrom1xBitmap(empty_spinner));
-
-  for (gfx::Rect src_rect(frame_size, frame_size);
-       src_rect.x() < spinner_image->width();
-       src_rect.Offset(frame_size, 0)) {
-    gfx::ImageSkia frame = gfx::ImageSkiaOperations::ExtractSubset(
-        *spinner_image, src_rect);
-
-    // The image created by ExtractSubset just points to the same pixels as
-    // the original and adjusts rowBytes accordingly. However that doesn't
-    // render properly and gets vertically squished in Linux due to a bug in
-    // Skia. Until that gets fixed we work around by taking a real copy of it
-    // below as the copied image has the correct rowBytes and renders fine.
-    frame.EnsureRepsForSupportedScales();
-    std::vector<gfx::ImageSkiaRep> image_reps = frame.image_reps();
-    gfx::ImageSkia frame_copy;
-    for (size_t i = 0; i < image_reps.size(); ++i) {
-      const SkBitmap& copy_src = image_reps[i].sk_bitmap();
-      SkBitmap copy_dst;
-      copy_src.copyTo(&copy_dst, kPMColor_SkColorType);
-      frame_copy.AddRepresentation(gfx::ImageSkiaRep(
-          copy_dst, image_reps[i].scale()));
-    }
-    spinner_.push_back(frame_copy);
-
-    // The warm up spinner animation is a gray scale version of the real one.
-    warm_up_.push_back(gfx::ImageSkiaOperations::CreateHSLShiftedImage(
-        frame_copy, kGrayscaleShift));
-  }
-}
-
-base::LazyInstance<SpeechRecognitionBubbleImages> g_images =
-    LAZY_INSTANCE_INITIALIZER;
-
-}  // namespace
-
-SpeechRecognitionBubble::FactoryMethod SpeechRecognitionBubble::factory_ = NULL;
-const int SpeechRecognitionBubble::kBubbleTargetOffsetX = 10;
-
-SpeechRecognitionBubble* SpeechRecognitionBubble::Create(
-    int render_process_id, int render_view_id, Delegate* delegate,
-    const gfx::Rect& element_rect) {
-  WebContents* web_contents =
-      tab_util::GetWebContentsByID(render_process_id, render_view_id);
-
-  if (factory_)
-    return (*factory_)(web_contents, delegate, element_rect);
-
-  // Has the tab already closed before bubble create request was processed?
-  if (!web_contents)
-    return NULL;
-
-  return CreateNativeBubble(render_process_id, render_view_id,
-      delegate, element_rect);
-}
-
-SpeechRecognitionBubbleBase::SpeechRecognitionBubbleBase(
-    int render_process_id, int render_view_id)
-    : weak_factory_(this),
-      animation_step_(0),
-      display_mode_(DISPLAY_MODE_RECORDING),
-      render_process_id_(render_process_id),
-      render_view_id_(render_view_id),
-      scale_(1.0f) {
-  WebContents* web_contents = GetWebContents();
-  gfx::NativeView view =
-      web_contents ? web_contents->GetView()->GetNativeView() : NULL;
-  gfx::Screen* screen = gfx::Screen::GetScreenFor(view);
-  gfx::Display display = screen->GetDisplayNearestWindow(view);
-  scale_ = display.device_scale_factor();
-
-  const gfx::ImageSkiaRep& rep =
-      g_images.Get().mic_empty()->GetRepresentation(scale_);
-  mic_image_.reset(new SkBitmap());
-  mic_image_->setConfig(SkBitmap::kARGB_8888_Config,
-      rep.pixel_width(), rep.pixel_height());
-  mic_image_->allocPixels();
-
-  buffer_image_.reset(new SkBitmap());
-  buffer_image_->setConfig(SkBitmap::kARGB_8888_Config,
-      rep.pixel_width(), rep.pixel_height());
-  buffer_image_->allocPixels();
-}
-
-SpeechRecognitionBubbleBase::~SpeechRecognitionBubbleBase() {
-  // This destructor is added to make sure members such as the scoped_ptr
-  // get destroyed here and the derived classes don't have to care about such
-  // member variables which they don't use.
-}
-
-void SpeechRecognitionBubbleBase::SetWarmUpMode() {
-  weak_factory_.InvalidateWeakPtrs();
-  display_mode_ = DISPLAY_MODE_WARM_UP;
-  animation_step_ = 0;
-  DoWarmingUpAnimationStep();
-  UpdateLayout();
-}
-
-void SpeechRecognitionBubbleBase::DoWarmingUpAnimationStep() {
-  SetImage(g_images.Get().warm_up()[animation_step_]);
-  base::MessageLoop::current()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&SpeechRecognitionBubbleBase::DoWarmingUpAnimationStep,
-          weak_factory_.GetWeakPtr()),
-      base::TimeDelta::FromMilliseconds(
-          animation_step_ == 0 ? kWarmingUpAnimationStartMs
-                               : kWarmingUpAnimationStepMs));
-  if (++animation_step_ >= static_cast<int>(g_images.Get().warm_up().size()))
-    animation_step_ = 1;  // Frame 0 is skipped during the animation.
-}
-
-void SpeechRecognitionBubbleBase::SetRecordingMode() {
-  weak_factory_.InvalidateWeakPtrs();
-  display_mode_ = DISPLAY_MODE_RECORDING;
-  SetInputVolume(0, 0);
-  UpdateLayout();
-}
-
-void SpeechRecognitionBubbleBase::SetRecognizingMode() {
-  display_mode_ = DISPLAY_MODE_RECOGNIZING;
-  animation_step_ = 0;
-  DoRecognizingAnimationStep();
-  UpdateLayout();
-}
-
-void SpeechRecognitionBubbleBase::DoRecognizingAnimationStep() {
-  SetImage(g_images.Get().spinner()[animation_step_]);
-  if (++animation_step_ >= static_cast<int>(g_images.Get().spinner().size()))
-    animation_step_ = 0;
-  base::MessageLoop::current()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&SpeechRecognitionBubbleBase::DoRecognizingAnimationStep,
-          weak_factory_.GetWeakPtr()),
-      base::TimeDelta::FromMilliseconds(kRecognizingAnimationStepMs));
-}
-
-void SpeechRecognitionBubbleBase::SetMessage(const base::string16& text) {
-  weak_factory_.InvalidateWeakPtrs();
-  message_text_ = text;
-  display_mode_ = DISPLAY_MODE_MESSAGE;
-  UpdateLayout();
-}
-
-void SpeechRecognitionBubbleBase::DrawVolumeOverlay(SkCanvas* canvas,
-                                                    const gfx::ImageSkia& image,
-                                                    float volume) {
-  buffer_image_->eraseARGB(0, 0, 0, 0);
-
-  int width = mic_image_->width();
-  int height = mic_image_->height();
-  SkCanvas buffer_canvas(*buffer_image_);
-
-  buffer_canvas.save();
-  const int kVolumeSteps = 12;
-  SkScalar clip_right =
-      (((1.0f - volume) * (width * (kVolumeSteps + 1))) - width) / kVolumeSteps;
-  buffer_canvas.clipRect(SkRect::MakeLTRB(0, 0,
-      SkIntToScalar(width) - clip_right, SkIntToScalar(height)));
-  buffer_canvas.drawBitmap(image.GetRepresentation(scale_).sk_bitmap(), 0, 0);
-  buffer_canvas.restore();
-  SkPaint multiply_paint;
-  multiply_paint.setXfermodeMode(SkXfermode::kModulate_Mode);
-  buffer_canvas.drawBitmap(
-      g_images.Get().mic_mask()->GetRepresentation(scale_).sk_bitmap(),
-      -clip_right, 0, &multiply_paint);
-
-  canvas->drawBitmap(*buffer_image_.get(), 0, 0);
-}
-
-void SpeechRecognitionBubbleBase::SetInputVolume(float volume,
-                                                 float noise_volume) {
-  mic_image_->eraseARGB(0, 0, 0, 0);
-  SkCanvas canvas(*mic_image_);
-
-  // Draw the empty volume image first and the current volume image on top,
-  // and then the noise volume image on top of both.
-  canvas.drawBitmap(
-      g_images.Get().mic_empty()->GetRepresentation(scale_).sk_bitmap(),
-      0, 0);
-  DrawVolumeOverlay(&canvas, *g_images.Get().mic_full(), volume);
-  DrawVolumeOverlay(&canvas, *g_images.Get().mic_noise(), noise_volume);
-
-  gfx::ImageSkia image(gfx::ImageSkiaRep(*mic_image_.get(), scale_));
-  SetImage(image);
-}
-
-WebContents* SpeechRecognitionBubbleBase::GetWebContents() {
-  return tab_util::GetWebContentsByID(render_process_id_, render_view_id_);
-}
-
-void SpeechRecognitionBubbleBase::SetImage(const gfx::ImageSkia& image) {
-  icon_image_ = image;
-  UpdateImage();
-}
-
-gfx::ImageSkia SpeechRecognitionBubbleBase::icon_image() {
-  return icon_image_;
-}
diff --git a/chrome/browser/speech/speech_recognition_bubble.h b/chrome/browser/speech/speech_recognition_bubble.h
deleted file mode 100644
index 96a805e..0000000
--- a/chrome/browser/speech/speech_recognition_bubble.h
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_BUBBLE_H_
-#define CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_BUBBLE_H_
-
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/strings/string16.h"
-#include "ui/base/layout.h"
-#include "ui/gfx/image/image_skia.h"
-
-class SkBitmap;
-class SkCanvas;
-
-namespace content {
-class WebContents;
-}
-
-namespace gfx {
-class Canvas;
-class Rect;
-}
-
-// SpeechRecognitionBubble displays a popup info bubble during speech
-// recognition, points to the html element which requested speech recognition
-// and shows progress events. The popup is closed by the user clicking anywhere
-// outside the popup window, or by the caller destroying this object.
-class SpeechRecognitionBubble {
- public:
-  // The various buttons which may be part of the bubble.
-  enum Button {
-    BUTTON_TRY_AGAIN,
-    BUTTON_CANCEL
-  };
-
-  // Informs listeners of user actions in the bubble.
-  class Delegate {
-   public:
-    // Invoked when the user selects a button in the info bubble. The InfoBubble
-    // is still active and the caller should close it if necessary.
-    virtual void InfoBubbleButtonClicked(Button button) = 0;
-
-    // Invoked when the user clicks outside the InfoBubble causing it to close.
-    // The InfoBubble window is no longer visible on screen and the caller can
-    // free the InfoBubble instance. This callback is not issued if the bubble
-    // got closed because the object was destroyed by the caller.
-    virtual void InfoBubbleFocusChanged() = 0;
-
-   protected:
-    virtual ~Delegate() {
-    }
-  };
-
-  // Factory method to create new instances.
-  // Creates the bubble, call |Show| to display it on screen.
-  // |render_process_id| and |render_view_id| is used to extract the
-  // correct WebContents.
-  // |element_rect| is the display bounds of the html element requesting speech
-  // recognition (in page coordinates).
-  static SpeechRecognitionBubble* Create(
-      int render_process_id,
-      int render_view_id,
-      Delegate* delegate,
-      const gfx::Rect& element_rect);
-
-  // This is implemented by platform specific code to create the underlying
-  // bubble window. Not to be called directly by users of this class.
-  static SpeechRecognitionBubble* CreateNativeBubble(
-      int render_process_id,
-      int render_view_id,
-      Delegate* delegate,
-      const gfx::Rect& element_rect);
-
-  // |Create| uses the currently registered FactoryMethod to create the
-  // SpeechRecognitionBubble instances. FactoryMethod is intended for testing.
-  typedef SpeechRecognitionBubble* (*FactoryMethod)(content::WebContents*,
-                                                    Delegate*,
-                                                    const gfx::Rect&);
-  // Sets the factory used by the static method Create. SpeechRecognitionBubble
-  // does not take ownership of |factory|. A value of NULL results in a
-  // SpeechRecognitionBubble being created directly.
-#if defined(UNIT_TEST)
-  static void set_factory(FactoryMethod factory) { factory_ = factory; }
-#endif
-
-  virtual ~SpeechRecognitionBubble() {}
-
-  // Indicates to the user that audio hardware is initializing. If the bubble is
-  // hidden, |Show| must be called to make it appear on screen.
-  virtual void SetWarmUpMode() = 0;
-
-  // Indicates to the user that audio recording is in progress. If the bubble is
-  // hidden, |Show| must be called to make it appear on screen.
-  virtual void SetRecordingMode() = 0;
-
-  // Indicates to the user that recognition is in progress. If the bubble is
-  // hidden, |Show| must be called to make it appear on screen.
-  virtual void SetRecognizingMode() = 0;
-
-  // Displays the given string with the 'Try again' and 'Cancel' buttons. If the
-  // bubble is hidden, |Show| must be called to make it appear on screen.
-  virtual void SetMessage(const base::string16& text) = 0;
-
-  // Brings up the bubble on screen.
-  virtual void Show() = 0;
-
-  // Hides the info bubble, resulting in a call to
-  // |Delegate::InfoBubbleFocusChanged| as well.
-  virtual void Hide() = 0;
-
-  // Updates and draws the current captured audio volume displayed on screen.
-  virtual void SetInputVolume(float volume, float noise_volume) = 0;
-
-  // Returns the WebContents for which this bubble gets displayed.
-  virtual content::WebContents* GetWebContents() = 0;
-
-  // The horizontal distance between the start of the html widget and the speech
-  // bubble's arrow.
-  static const int kBubbleTargetOffsetX;
-
- private:
-  static FactoryMethod factory_;
-};
-
-// Base class for the platform specific bubble implementations, this contains
-// the platform independent code for SpeechRecognitionBubble.
-class SpeechRecognitionBubbleBase : public SpeechRecognitionBubble {
- public:
-  // The current display mode of the bubble, useful only for the platform
-  // specific implementation.
-  enum DisplayMode {
-    DISPLAY_MODE_WARM_UP,
-    DISPLAY_MODE_RECORDING,
-    DISPLAY_MODE_RECOGNIZING,
-    DISPLAY_MODE_MESSAGE
-  };
-
-  SpeechRecognitionBubbleBase(int render_process_id, int render_view_id);
-  virtual ~SpeechRecognitionBubbleBase();
-
-  // SpeechRecognitionBubble methods
-  virtual void SetWarmUpMode() OVERRIDE;
-  virtual void SetRecordingMode() OVERRIDE;
-  virtual void SetRecognizingMode() OVERRIDE;
-  virtual void SetMessage(const base::string16& text) OVERRIDE;
-  virtual void SetInputVolume(float volume, float noise_volume) OVERRIDE;
-  virtual content::WebContents* GetWebContents() OVERRIDE;
-
- protected:
-  // Updates the platform specific UI layout for the current display mode.
-  virtual void UpdateLayout() = 0;
-
-  // Overridden by subclasses to copy |icon_image()| to the screen.
-  virtual void UpdateImage() = 0;
-
-  DisplayMode display_mode() const { return display_mode_; }
-
-  const base::string16& message_text() const { return message_text_; }
-
-  gfx::ImageSkia icon_image();
-
- private:
-  void DoRecognizingAnimationStep();
-  void DoWarmingUpAnimationStep();
-  void SetImage(const gfx::ImageSkia& image);
-
-  void DrawVolumeOverlay(SkCanvas* canvas,
-                         const gfx::ImageSkia& image_skia,
-                         float volume);
-
-  // Task factory used for animation timer.
-  base::WeakPtrFactory<SpeechRecognitionBubbleBase> weak_factory_;
-  int animation_step_;  // Current index/step of the animation.
-
-  DisplayMode display_mode_;
-  base::string16 message_text_;  // Text displayed in DISPLAY_MODE_MESSAGE
-
-  // The current microphone image with volume level indication.
-  scoped_ptr<SkBitmap> mic_image_;
-  // A temporary buffer image used in creating the above mic image.
-  scoped_ptr<SkBitmap> buffer_image_;
-
-  // Content in which this bubble gets displayed.
-  int render_process_id_;
-  int render_view_id_;
-
-  // The current image displayed in the bubble's icon widget.
-  gfx::ImageSkia icon_image_;
-  // The scale factor used for the web-contents.
-  float scale_;
-
-  DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionBubbleBase);
-};
-
-// This typedef is to workaround the issue with certain versions of
-// Visual Studio where it gets confused between multiple Delegate
-// classes and gives a C2500 error. (I saw this error on the try bots -
-// the workaround was not needed for my machine).
-typedef SpeechRecognitionBubble::Delegate SpeechRecognitionBubbleDelegate;
-
-#endif  // CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_BUBBLE_H_
diff --git a/chrome/browser/speech/speech_recognition_bubble_browsertest.cc b/chrome/browser/speech/speech_recognition_bubble_browsertest.cc
deleted file mode 100644
index dcb35f4..0000000
--- a/chrome/browser/speech/speech_recognition_bubble_browsertest.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/speech/speech_recognition_bubble.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/web_contents.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/rect.h"
-
-class SpeechRecognitionBubbleTest : public SpeechRecognitionBubbleDelegate,
-                              public InProcessBrowserTest {
- public:
-  // SpeechRecognitionBubble::Delegate methods.
-  virtual void InfoBubbleButtonClicked(
-      SpeechRecognitionBubble::Button button) OVERRIDE {
-  }
-  virtual void InfoBubbleFocusChanged() OVERRIDE {}
-
- protected:
-};
-
-IN_PROC_BROWSER_TEST_F(SpeechRecognitionBubbleTest, CreateAndDestroy) {
-  gfx::Rect element_rect(100, 100, 100, 100);
-  content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  scoped_ptr<SpeechRecognitionBubble> bubble(SpeechRecognitionBubble::Create(
-       web_contents->GetRenderProcessHost()->GetID(),
-       web_contents->GetRenderViewHost()->GetRoutingID(),
-       this, element_rect));
-  EXPECT_TRUE(bubble.get());
-}
-
-IN_PROC_BROWSER_TEST_F(SpeechRecognitionBubbleTest, ShowAndDestroy) {
-  gfx::Rect element_rect(100, 100, 100, 100);
-  content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  scoped_ptr<SpeechRecognitionBubble> bubble(SpeechRecognitionBubble::Create(
-       web_contents->GetRenderProcessHost()->GetID(),
-       web_contents->GetRenderViewHost()->GetRoutingID(),
-       this, element_rect));
-  EXPECT_TRUE(bubble.get());
-  bubble->Show();
-}
-
-IN_PROC_BROWSER_TEST_F(SpeechRecognitionBubbleTest, ShowAndHide) {
-  gfx::Rect element_rect(100, 100, 100, 100);
-  content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  scoped_ptr<SpeechRecognitionBubble> bubble(SpeechRecognitionBubble::Create(
-       web_contents->GetRenderProcessHost()->GetID(),
-       web_contents->GetRenderViewHost()->GetRoutingID(),
-       this, element_rect));
-  EXPECT_TRUE(bubble.get());
-  bubble->Show();
-  bubble->Hide();
-}
-
-IN_PROC_BROWSER_TEST_F(SpeechRecognitionBubbleTest, ShowAndHideTwice) {
-  gfx::Rect element_rect(100, 100, 100, 100);
-  content::WebContents* web_contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  scoped_ptr<SpeechRecognitionBubble> bubble(SpeechRecognitionBubble::Create(
-       web_contents->GetRenderProcessHost()->GetID(),
-       web_contents->GetRenderViewHost()->GetRoutingID(),
-       this, element_rect));
-  EXPECT_TRUE(bubble.get());
-  bubble->Show();
-  bubble->Hide();
-  bubble->Show();
-  bubble->Hide();
-}
diff --git a/chrome/browser/speech/speech_recognition_bubble_controller.cc b/chrome/browser/speech/speech_recognition_bubble_controller.cc
deleted file mode 100644
index ede3858..0000000
--- a/chrome/browser/speech/speech_recognition_bubble_controller.cc
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/speech/speech_recognition_bubble_controller.h"
-
-#include "base/bind.h"
-#include "chrome/browser/tab_contents/tab_util.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/notification_source.h"
-#include "content/public/browser/notification_types.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/web_contents.h"
-
-using content::BrowserThread;
-using content::WebContents;
-
-namespace {
-const int kInvalidSessionId = 0;
-}
-
-namespace speech {
-
-SpeechRecognitionBubbleController::SpeechRecognitionBubbleController(
-    Delegate* delegate)
-    : delegate_(delegate),
-      last_request_issued_(REQUEST_CLOSE),
-      current_bubble_session_id_(kInvalidSessionId),
-      current_bubble_render_process_id_(0),
-      current_bubble_render_view_id_(0) {
-}
-
-SpeechRecognitionBubbleController::~SpeechRecognitionBubbleController() {
-  DCHECK_EQ(kInvalidSessionId, current_bubble_session_id_);
-}
-
-void SpeechRecognitionBubbleController::CreateBubble(
-    int session_id,
-    int render_process_id,
-    int render_view_id,
-    const gfx::Rect& element_rect) {
-  {
-    base::AutoLock auto_lock(lock_);
-    current_bubble_session_id_ = session_id;
-    current_bubble_render_process_id_ = render_process_id;
-    current_bubble_render_view_id_ = render_view_id;
-  }
-
-  UIRequest request(REQUEST_CREATE);
-  request.render_process_id = render_process_id;
-  request.render_view_id = render_view_id;
-  request.element_rect = element_rect;
-  ProcessRequestInUiThread(request);
-}
-
-void SpeechRecognitionBubbleController::SetBubbleRecordingMode() {
-  ProcessRequestInUiThread(UIRequest(REQUEST_SET_RECORDING_MODE));
-}
-
-void SpeechRecognitionBubbleController::SetBubbleRecognizingMode() {
-  ProcessRequestInUiThread(UIRequest(REQUEST_SET_RECOGNIZING_MODE));
-}
-
-void SpeechRecognitionBubbleController::SetBubbleMessage(
-    const base::string16& text) {
-  UIRequest request(REQUEST_SET_MESSAGE);
-  request.message = text;
-  ProcessRequestInUiThread(request);
-}
-
-bool SpeechRecognitionBubbleController::IsShowingMessage() const {
-  return last_request_issued_ == REQUEST_SET_MESSAGE;
-}
-
-void SpeechRecognitionBubbleController::SetBubbleInputVolume(
-    float volume,
-    float noise_volume) {
-  UIRequest request(REQUEST_SET_INPUT_VOLUME);
-  request.volume = volume;
-  request.noise_volume = noise_volume;
-  ProcessRequestInUiThread(request);
-}
-
-void SpeechRecognitionBubbleController::CloseBubble() {
-  {
-    base::AutoLock auto_lock(lock_);
-    current_bubble_session_id_ = kInvalidSessionId;
-  }
-  ProcessRequestInUiThread(UIRequest(REQUEST_CLOSE));
-}
-
-void SpeechRecognitionBubbleController::CloseBubbleForRenderViewOnUIThread(
-    int render_process_id, int render_view_id) {
-  {
-    base::AutoLock auto_lock(lock_);
-    if (current_bubble_session_id_ == kInvalidSessionId ||
-        current_bubble_render_process_id_ != render_process_id ||
-        current_bubble_render_view_id_ != render_view_id) {
-      return;
-    }
-    current_bubble_session_id_ = kInvalidSessionId;
-  }
-  ProcessRequestInUiThread(UIRequest(REQUEST_CLOSE));
-}
-
-int SpeechRecognitionBubbleController::GetActiveSessionID() {
-  base::AutoLock auto_lock(lock_);
-  return current_bubble_session_id_;
-}
-
-void SpeechRecognitionBubbleController::InfoBubbleButtonClicked(
-    SpeechRecognitionBubble::Button button) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
-      base::Bind(
-          &SpeechRecognitionBubbleController::InvokeDelegateButtonClicked, this,
-          button));
-}
-
-void SpeechRecognitionBubbleController::InfoBubbleFocusChanged() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
-      base::Bind(&SpeechRecognitionBubbleController::InvokeDelegateFocusChanged,
-                 this));
-}
-
-void SpeechRecognitionBubbleController::InvokeDelegateButtonClicked(
-    SpeechRecognitionBubble::Button button) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  {
-    base::AutoLock auto_lock(lock_);
-    if (kInvalidSessionId == current_bubble_session_id_)
-      return;
-  }
-  delegate_->InfoBubbleButtonClicked(current_bubble_session_id_, button);
-}
-
-void SpeechRecognitionBubbleController::InvokeDelegateFocusChanged() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  {
-    base::AutoLock auto_lock(lock_);
-    if (kInvalidSessionId == current_bubble_session_id_)
-      return;
-  }
-  delegate_->InfoBubbleFocusChanged(current_bubble_session_id_);
-}
-
-void SpeechRecognitionBubbleController::ProcessRequestInUiThread(
-    const UIRequest& request) {
-  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    last_request_issued_ = request.type;
-    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-        base::Bind(&SpeechRecognitionBubbleController::ProcessRequestInUiThread,
-                   this, request));
-    return;
-  }
-
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  // In the case of a tab closed or crashed, the bubble can have been destroyed
-  // earlier on the UI thread, while other tasks were being enqueued from the IO
-  // to the UI thread. Simply return in such cases.
-  if (request.type != REQUEST_CREATE && !bubble_.get())
-    return;
-
-  switch (request.type) {
-    case REQUEST_CREATE:
-      bubble_.reset(SpeechRecognitionBubble::Create(
-          request.render_process_id, request.render_view_id,
-          this, request.element_rect));
-
-      if (!bubble_.get()) {
-        // Could be null if tab or display rect were invalid.
-        // Simulate the cancel button being clicked to inform the delegate.
-        BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
-            base::Bind(
-                &SpeechRecognitionBubbleController::InvokeDelegateButtonClicked,
-                this, SpeechRecognitionBubble::BUTTON_CANCEL));
-        return;
-      }
-      bubble_->Show();
-      bubble_->SetWarmUpMode();
-      break;
-    case REQUEST_SET_RECORDING_MODE:
-      bubble_->SetRecordingMode();
-      break;
-    case REQUEST_SET_RECOGNIZING_MODE:
-      bubble_->SetRecognizingMode();
-      break;
-    case REQUEST_SET_MESSAGE:
-      bubble_->SetMessage(request.message);
-      break;
-    case REQUEST_SET_INPUT_VOLUME:
-      bubble_->SetInputVolume(request.volume, request.noise_volume);
-      break;
-    case REQUEST_CLOSE:
-      bubble_.reset();
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-}
-
-SpeechRecognitionBubbleController::UIRequest::UIRequest(RequestType type_value)
-    : type(type_value),
-      volume(0.0F),
-      noise_volume(0.0F),
-      render_process_id(0),
-      render_view_id(0) {
-}
-
-SpeechRecognitionBubbleController::UIRequest::~UIRequest() {
-}
-
-}  // namespace speech
diff --git a/chrome/browser/speech/speech_recognition_bubble_controller.h b/chrome/browser/speech/speech_recognition_bubble_controller.h
deleted file mode 100644
index 67e0e71..0000000
--- a/chrome/browser/speech/speech_recognition_bubble_controller.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_BUBBLE_CONTROLLER_H_
-#define CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_BUBBLE_CONTROLLER_H_
-
-#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
-#include "base/synchronization/lock.h"
-#include "chrome/browser/speech/speech_recognition_bubble.h"
-#include "ui/gfx/rect.h"
-
-namespace speech {
-
-// This class handles the speech recognition popup UI on behalf of
-// SpeechRecognitionManager, which invokes methods on the IO thread, processing
-// those requests on the UI thread. At most one bubble can be active.
-class SpeechRecognitionBubbleController
-    : public base::RefCountedThreadSafe<SpeechRecognitionBubbleController>,
-      public SpeechRecognitionBubbleDelegate {
- public:
-  // All methods of this delegate are called on the IO thread.
-  class Delegate {
-   public:
-    // Invoked when the user clicks on a button in the speech recognition UI.
-    virtual void InfoBubbleButtonClicked(
-        int session_id, SpeechRecognitionBubble::Button button) = 0;
-
-    // Invoked when the user clicks outside the speech recognition info bubble
-    // causing it to close and input focus to change.
-    virtual void InfoBubbleFocusChanged(int session_id) = 0;
-
-   protected:
-    virtual ~Delegate() {}
-  };
-
-  explicit SpeechRecognitionBubbleController(Delegate* delegate);
-
-  // Creates and shows a new speech recognition UI bubble in warmup mode.
-  void CreateBubble(int session_id,
-                    int render_process_id,
-                    int render_view_id,
-                    const gfx::Rect& element_rect);
-
-  // Indicates to the user that audio recording is in progress.
-  void SetBubbleRecordingMode();
-
-  // Indicates to the user that recognition is in progress.
-  void SetBubbleRecognizingMode();
-
-  // Displays the given string with the 'Try again' and 'Cancel' buttons.
-  void SetBubbleMessage(const base::string16& text);
-
-  // Checks whether the bubble is active and is showing a message.
-  bool IsShowingMessage() const;
-
-  // Updates the current captured audio volume displayed on screen.
-  void SetBubbleInputVolume(float volume, float noise_volume);
-
-  // Closes the bubble.
-  void CloseBubble();
-
-  // This is the only method that can be called from the UI thread.
-  void CloseBubbleForRenderViewOnUIThread(int render_process_id,
-                                          int render_view_id);
-
-  // Retrieves the session ID associated to the active bubble (if any).
-  // Returns 0 if no bubble is currently shown.
-  int GetActiveSessionID();
-
-  // SpeechRecognitionBubble::Delegate methods.
-  virtual void InfoBubbleButtonClicked(
-      SpeechRecognitionBubble::Button button) OVERRIDE;
-  virtual void InfoBubbleFocusChanged() OVERRIDE;
-
- private:
-  friend class base::RefCountedThreadSafe<SpeechRecognitionBubbleController>;
-
-  // The various calls received by this object and handled on the UI thread.
-  enum RequestType {
-    REQUEST_CREATE,
-    REQUEST_SET_RECORDING_MODE,
-    REQUEST_SET_RECOGNIZING_MODE,
-    REQUEST_SET_MESSAGE,
-    REQUEST_SET_INPUT_VOLUME,
-    REQUEST_CLOSE,
-  };
-
-  struct UIRequest {
-    RequestType type;
-    base::string16 message;
-    gfx::Rect element_rect;
-    float volume;
-    float noise_volume;
-    int render_process_id;
-    int render_view_id;
-
-    explicit UIRequest(RequestType type_value);
-    ~UIRequest();
-  };
-
-  virtual ~SpeechRecognitionBubbleController();
-
-  void InvokeDelegateButtonClicked(SpeechRecognitionBubble::Button button);
-  void InvokeDelegateFocusChanged();
-  void ProcessRequestInUiThread(const UIRequest& request);
-
-  // The following are accessed only on the IO thread.
-  Delegate* delegate_;
-  RequestType last_request_issued_;
-
-  // The following are accessed only on the UI thread.
-  scoped_ptr<SpeechRecognitionBubble> bubble_;
-
-  // The following are accessed on both IO and  UI threads.
-  base::Lock lock_;
-
-  // The session id for currently visible bubble.
-  int current_bubble_session_id_;
-
-  // The render process and view ids for the currently visible bubble.
-  int current_bubble_render_process_id_;
-  int current_bubble_render_view_id_;
-};
-
-// This typedef is to workaround the issue with certain versions of
-// Visual Studio where it gets confused between multiple Delegate
-// classes and gives a C2500 error. (I saw this error on the try bots -
-// the workaround was not needed for my machine).
-typedef SpeechRecognitionBubbleController::Delegate
-    SpeechRecognitionBubbleControllerDelegate;
-
-}  // namespace speech
-
-#endif  // CHROME_BROWSER_SPEECH_SPEECH_RECOGNITION_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/speech/speech_recognition_bubble_controller_unittest.cc b/chrome/browser/speech/speech_recognition_bubble_controller_unittest.cc
deleted file mode 100644
index 80f2de7..0000000
--- a/chrome/browser/speech/speech_recognition_bubble_controller_unittest.cc
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/bind.h"
-#include "base/run_loop.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/speech/speech_recognition_bubble_controller.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_tabstrip.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/test/base/browser_with_test_window_test.h"
-#include "chrome/test/base/testing_profile.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/test/test_browser_thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/rect.h"
-
-
-using content::BrowserThread;
-using content::WebContents;
-
-namespace speech {
-
-// A mock bubble class which fakes a focus change or recognition cancel by the
-// user and closing of the info bubble.
-class MockSpeechRecognitionBubble : public SpeechRecognitionBubbleBase {
- public:
-  enum BubbleType {
-    BUBBLE_TEST_FOCUS_CHANGED,
-    BUBBLE_TEST_CLICK_CANCEL,
-    BUBBLE_TEST_CLICK_TRY_AGAIN,
-  };
-
-  MockSpeechRecognitionBubble(int render_process_id, int render_view_id,
-      Delegate* delegate, const gfx::Rect&)
-      : SpeechRecognitionBubbleBase(render_process_id, render_view_id) {
-    VLOG(1) << "MockSpeechRecognitionBubble created";
-    base::MessageLoop::current()->PostTask(
-        FROM_HERE, base::Bind(&InvokeDelegate, delegate));
-  }
-
-  static void InvokeDelegate(Delegate* delegate) {
-    VLOG(1) << "MockSpeechRecognitionBubble invoking delegate for type "
-            << type_;
-    switch (type_) {
-      case BUBBLE_TEST_FOCUS_CHANGED:
-        delegate->InfoBubbleFocusChanged();
-        break;
-      case BUBBLE_TEST_CLICK_CANCEL:
-        delegate->InfoBubbleButtonClicked(
-            SpeechRecognitionBubble::BUTTON_CANCEL);
-        break;
-      case BUBBLE_TEST_CLICK_TRY_AGAIN:
-        delegate->InfoBubbleButtonClicked(
-            SpeechRecognitionBubble::BUTTON_TRY_AGAIN);
-        break;
-    }
-  }
-
-  static void set_type(BubbleType type) {
-    type_ = type;
-  }
-  static BubbleType type() {
-    return type_;
-  }
-
-  virtual void Show() OVERRIDE {}
-  virtual void Hide() OVERRIDE {}
-  virtual void UpdateLayout() OVERRIDE {}
-  virtual void UpdateImage() OVERRIDE {}
-
- private:
-  static BubbleType type_;
-};
-
-// The test fixture.
-class SpeechRecognitionBubbleControllerTest
-    : public SpeechRecognitionBubbleControllerDelegate,
-      public BrowserWithTestWindowTest {
- public:
-  SpeechRecognitionBubbleControllerTest()
-      : BrowserWithTestWindowTest(),
-        cancel_clicked_(false),
-        try_again_clicked_(false),
-        focus_changed_(false),
-        controller_(new SpeechRecognitionBubbleController(this)) {
-    EXPECT_EQ(NULL, test_fixture_);
-    test_fixture_ = this;
-  }
-
-  virtual ~SpeechRecognitionBubbleControllerTest() {
-    test_fixture_ = NULL;
-  }
-
-  // SpeechRecognitionBubbleControllerDelegate methods.
-  virtual void InfoBubbleButtonClicked(
-      int session_id,
-      SpeechRecognitionBubble::Button button) OVERRIDE {
-    VLOG(1) << "Received InfoBubbleButtonClicked for button " << button;
-    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
-    if (button == SpeechRecognitionBubble::BUTTON_CANCEL) {
-      cancel_clicked_ = true;
-    } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) {
-      try_again_clicked_ = true;
-    }
-  }
-
-  virtual void InfoBubbleFocusChanged(int session_id) OVERRIDE {
-    VLOG(1) << "Received InfoBubbleFocusChanged";
-    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
-    focus_changed_ = true;
-  }
-
-  // testing::Test methods.
-  virtual void SetUp() {
-    BrowserWithTestWindowTest::SetUp();
-    SpeechRecognitionBubble::set_factory(
-        &SpeechRecognitionBubbleControllerTest::CreateBubble);
-  }
-
-  virtual void TearDown() {
-    SpeechRecognitionBubble::set_factory(NULL);
-    BrowserWithTestWindowTest::TearDown();
-  }
-
-  static void ActivateBubble() {
-    if (MockSpeechRecognitionBubble::type() !=
-        MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED) {
-      test_fixture_->controller_->SetBubbleMessage(base::ASCIIToUTF16("Test"));
-    }
-  }
-
-  static SpeechRecognitionBubble* CreateBubble(
-      WebContents* web_contents,
-      SpeechRecognitionBubble::Delegate* delegate,
-      const gfx::Rect& element_rect) {
-    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
-    // Set up to activate the bubble soon after it gets created, since we test
-    // events sent by the bubble and those are handled only when the bubble is
-    // active.
-    base::MessageLoop::current()->PostTask(FROM_HERE,
-                                           base::Bind(&ActivateBubble));
-
-    return new MockSpeechRecognitionBubble(0, 0, delegate, element_rect);
-  }
-
- protected:
-  bool cancel_clicked_;
-  bool try_again_clicked_;
-  bool focus_changed_;
-  scoped_refptr<SpeechRecognitionBubbleController> controller_;
-
-  static const int kBubbleSessionId;
-  static SpeechRecognitionBubbleControllerTest* test_fixture_;
-};
-
-SpeechRecognitionBubbleControllerTest*
-SpeechRecognitionBubbleControllerTest::test_fixture_ = NULL;
-
-const int SpeechRecognitionBubbleControllerTest::kBubbleSessionId = 1;
-
-MockSpeechRecognitionBubble::BubbleType MockSpeechRecognitionBubble::type_ =
-    MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED;
-
-// Test that the speech bubble UI gets created in the UI thread and that the
-// focus changed callback comes back in the IO thread.
-TEST_F(SpeechRecognitionBubbleControllerTest, TestFocusChanged) {
-  MockSpeechRecognitionBubble::set_type(
-      MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED);
-
-  controller_->CreateBubble(kBubbleSessionId, 1, 1, gfx::Rect(1, 1));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(focus_changed_);
-  EXPECT_FALSE(cancel_clicked_);
-  EXPECT_FALSE(try_again_clicked_);
-  controller_->CloseBubble();
-}
-
-// Test that the speech bubble UI gets created in the UI thread and that the
-// recognition cancelled callback comes back in the IO thread.
-TEST_F(SpeechRecognitionBubbleControllerTest, TestRecognitionCancelled) {
-  MockSpeechRecognitionBubble::set_type(
-      MockSpeechRecognitionBubble::BUBBLE_TEST_CLICK_CANCEL);
-
-  controller_->CreateBubble(kBubbleSessionId, 1, 1, gfx::Rect(1, 1));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(cancel_clicked_);
-  EXPECT_FALSE(try_again_clicked_);
-  EXPECT_FALSE(focus_changed_);
-  controller_->CloseBubble();
-}
-
-// Test that the speech bubble UI gets created in the UI thread and that the
-// try-again button click event comes back in the IO thread.
-TEST_F(SpeechRecognitionBubbleControllerTest, TestTryAgainClicked) {
-  MockSpeechRecognitionBubble::set_type(
-      MockSpeechRecognitionBubble::BUBBLE_TEST_CLICK_TRY_AGAIN);
-
-  controller_->CreateBubble(kBubbleSessionId, 1, 1, gfx::Rect(1, 1));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(cancel_clicked_);
-  EXPECT_TRUE(try_again_clicked_);
-  EXPECT_FALSE(focus_changed_);
-  controller_->CloseBubble();
-}
-
-}  // namespace speech
diff --git a/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc b/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc
index a34c7b6..e7b9140 100644
--- a/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc
+++ b/chrome/browser/spellchecker/spellcheck_custom_dictionary.cc
@@ -76,7 +76,7 @@
 // Returns true for invalid words and false for valid words.
 bool IsInvalidWord(const std::string& word) {
   std::string tmp;
-  return !IsStringUTF8(word) ||
+  return !base::IsStringUTF8(word) ||
       word.length() >
           chrome::spellcheck_common::MAX_CUSTOM_DICTIONARY_WORD_BYTES ||
       word.empty() ||
diff --git a/chrome/browser/spellchecker/spelling_service_client.cc b/chrome/browser/spellchecker/spelling_service_client.cc
index a0506ba..a74b356 100644
--- a/chrome/browser/spellchecker/spelling_service_client.cc
+++ b/chrome/browser/spellchecker/spelling_service_client.cc
@@ -120,12 +120,6 @@
   if (locale.empty())
     return false;
 
-  // If we do not have the spelling service enabled, then we are only available
-  // for SUGGEST.
-  const CommandLine* command_line = CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kUseSpellingSuggestions))
-    return type == SUGGEST;
-
   // Finally, if all options are available, we only enable only SUGGEST
   // if SPELLCHECK is not available for our language because SPELLCHECK results
   // are a superset of SUGGEST results.
diff --git a/chrome/browser/ssl/ssl_tab_helper.cc b/chrome/browser/ssl/ssl_tab_helper.cc
index a5be317..a1d5a0b 100644
--- a/chrome/browser/ssl/ssl_tab_helper.cc
+++ b/chrome/browser/ssl/ssl_tab_helper.cc
@@ -28,7 +28,6 @@
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "net/base/net_errors.h"
@@ -123,7 +122,7 @@
   content::WebContents* web_contents =
       InfoBarService::WebContentsFromInfoBar(infobar());
   ShowCertificateViewer(web_contents,
-                        web_contents->GetView()->GetTopLevelNativeWindow(),
+                        web_contents->GetTopLevelNativeWindow(),
                         cert_.get());
   return false;  // Hiding the infobar just as the dialog opens looks weird.
 }
diff --git a/chrome/browser/sync/glue/bookmark_change_processor.cc b/chrome/browser/sync/glue/bookmark_change_processor.cc
index b57994f..1ecef95 100644
--- a/chrome/browser/sync/glue/bookmark_change_processor.cc
+++ b/chrome/browser/sync/glue/bookmark_change_processor.cc
@@ -268,14 +268,18 @@
   return sync_child.GetId();
 }
 
-void BookmarkChangeProcessor::BookmarkNodeRemoved(BookmarkModel* model,
-                                                  const BookmarkNode* parent,
-                                                  int index,
-                                                  const BookmarkNode* node) {
+void BookmarkChangeProcessor::BookmarkNodeRemoved(
+    BookmarkModel* model,
+    const BookmarkNode* parent,
+    int index,
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {
   RemoveSyncNodeHierarchy(node);
 }
 
-void BookmarkChangeProcessor::BookmarkAllNodesRemoved(BookmarkModel* model) {
+void BookmarkChangeProcessor::BookmarkAllNodesRemoved(
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
   RemoveAllSyncNodes();
 }
 
diff --git a/chrome/browser/sync/glue/bookmark_change_processor.h b/chrome/browser/sync/glue/bookmark_change_processor.h
index 360d26d..cd86131 100644
--- a/chrome/browser/sync/glue/bookmark_change_processor.h
+++ b/chrome/browser/sync/glue/bookmark_change_processor.h
@@ -56,8 +56,11 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int index,
-                                   const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE;
   virtual void BookmarkMetaInfoChanged(BookmarkModel* model,
diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
index 81b1cb1..e0dcc88 100644
--- a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/prefs/pref_service.h"
 #include "base/run_loop.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/bookmarks/chrome_bookmark_client.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_service.h"
@@ -23,6 +22,7 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/profile_mock.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "components/keyed_service/content/refcounted_browser_context_keyed_service.h"
 #include "components/sync_driver/change_processor_mock.h"
 #include "components/sync_driver/data_type_controller_mock.h"
@@ -141,7 +141,6 @@
         WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true)));
     EXPECT_CALL(*model_associator_, AssociateModels(_, _)).
         WillRepeatedly(Return(syncer::SyncError()));
-    EXPECT_CALL(service_, ActivateDataType(_, _, _));
   }
 
   void SetStopExpectations() {
diff --git a/chrome/browser/sync/glue/data_type_manager_impl.cc b/chrome/browser/sync/glue/data_type_manager_impl.cc
index 3c14d48..d578465 100644
--- a/chrome/browser/sync/glue/data_type_manager_impl.cc
+++ b/chrome/browser/sync/glue/data_type_manager_impl.cc
@@ -387,6 +387,14 @@
     syncer::ModelType type,
     const syncer::DataTypeAssociationStats& association_stats) {
   DCHECK(!association_types_queue_.empty());
+  DataTypeController::TypeMap::const_iterator c_it = controllers_->find(type);
+  DCHECK(c_it != controllers_->end());
+  if (c_it->second->state() == DataTypeController::RUNNING) {
+    // Tell the backend about the change processor for this type so it can
+    // begin routing changes to it.
+    configurer_->ActivateDataType(type, c_it->second->model_safe_group(),
+                                  c_it->second->GetChangeProcessor());
+  }
 
   if (!debug_info_listener_.IsInitialized())
     return;
diff --git a/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc b/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
index 8046a01..acb8670 100644
--- a/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
+++ b/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
@@ -74,6 +74,11 @@
     }
   }
 
+  virtual void ActivateDataType(
+      syncer::ModelType type, syncer::ModelSafeGroup group,
+      ChangeProcessor* change_processor) OVERRIDE {}
+  virtual void DeactivateDataType(syncer::ModelType type) OVERRIDE {}
+
   base::Callback<void(ModelTypeSet, ModelTypeSet)> last_ready_task() const {
     return last_ready_task_;
   }
diff --git a/chrome/browser/sync/glue/frontend_data_type_controller.cc b/chrome/browser/sync/glue/frontend_data_type_controller.cc
index 7872aa0..b7f31ac 100644
--- a/chrome/browser/sync/glue/frontend_data_type_controller.cc
+++ b/chrome/browser/sync/glue/frontend_data_type_controller.cc
@@ -200,8 +200,6 @@
     return false;
   }
 
-  sync_service_->ActivateDataType(type(), model_safe_group(),
-                                  change_processor());
   state_ = RUNNING;
   // FinishStart() invokes the DataTypeManager callback, which can lead to a
   // call to Stop() if one of the other data types being started generates an
@@ -295,7 +293,7 @@
   model_associator_.reset(model_associator);
 }
 
-ChangeProcessor* FrontendDataTypeController::change_processor() const {
+ChangeProcessor* FrontendDataTypeController::GetChangeProcessor() const {
   return change_processor_.get();
 }
 
diff --git a/chrome/browser/sync/glue/frontend_data_type_controller.h b/chrome/browser/sync/glue/frontend_data_type_controller.h
index ae7cd55..b7fb351 100644
--- a/chrome/browser/sync/glue/frontend_data_type_controller.h
+++ b/chrome/browser/sync/glue/frontend_data_type_controller.h
@@ -102,7 +102,7 @@
 
   virtual AssociatorInterface* model_associator() const;
   virtual void set_model_associator(AssociatorInterface* associator);
-  virtual ChangeProcessor* change_processor() const;
+  virtual ChangeProcessor* GetChangeProcessor() const OVERRIDE;
   virtual void set_change_processor(ChangeProcessor* processor);
 
   ProfileSyncComponentsFactory* const profile_sync_factory_;
diff --git a/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc b/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc
index 96fb47e..88f13d3 100644
--- a/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc
@@ -122,7 +122,6 @@
   }
 
   void SetActivateExpectations(DataTypeController::StartResult result) {
-    EXPECT_CALL(service_, ActivateDataType(_, _, _));
     EXPECT_CALL(start_callback_, Run(result, _, _));
   }
 
diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
index 309cd5a..c4f011a 100644
--- a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
+++ b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc
@@ -429,7 +429,7 @@
   return model_associator_;
 }
 
-ChangeProcessor* NonFrontendDataTypeController::change_processor() const {
+ChangeProcessor* NonFrontendDataTypeController::GetChangeProcessor() const {
   return change_processor_;
 }
 
@@ -464,8 +464,6 @@
   change_processor_ = result.change_processor;
   model_associator_ = result.model_associator;
 
-  profile_sync_service_->ActivateDataType(type(), model_safe_group(),
-                                          change_processor());
   StartDone(!result.sync_has_nodes ? OK_FIRST_RUN : OK,
             result.local_merge_result,
             result.syncer_merge_result);
diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller.h b/chrome/browser/sync/glue/non_frontend_data_type_controller.h
index 5a379bd..ac8ddcb 100644
--- a/chrome/browser/sync/glue/non_frontend_data_type_controller.h
+++ b/chrome/browser/sync/glue/non_frontend_data_type_controller.h
@@ -161,7 +161,7 @@
   void set_state(State state);
 
   virtual AssociatorInterface* associator() const;
-  virtual ChangeProcessor* change_processor() const;
+  virtual ChangeProcessor* GetChangeProcessor() const OVERRIDE;
 
   State state_;
   StartCallback start_callback_;
diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc b/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc
index 9f8febb..df5cc95 100644
--- a/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc
@@ -162,7 +162,6 @@
   }
 
   void SetActivateExpectations(DataTypeController::StartResult result) {
-    EXPECT_CALL(service_, ActivateDataType(_, _, _));
     EXPECT_CALL(start_callback_, Run(result, _, _));
   }
 
diff --git a/chrome/browser/sync/glue/non_ui_data_type_controller.cc b/chrome/browser/sync/glue/non_ui_data_type_controller.cc
index e14a8fd..d8e364c 100644
--- a/chrome/browser/sync/glue/non_ui_data_type_controller.cc
+++ b/chrome/browser/sync/glue/non_ui_data_type_controller.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/sync/glue/shared_change_processor_ref.h"
 #include "chrome/browser/sync/profile_sync_components_factory.h"
 #include "chrome/browser/sync/profile_sync_service.h"
+#include "components/sync_driver/generic_change_processor_factory.h"
 #include "content/public/browser/browser_thread.h"
 #include "sync/api/sync_error.h"
 #include "sync/api/syncable_service.h"
@@ -35,7 +36,8 @@
       profile_sync_factory_(profile_sync_factory),
       profile_(profile),
       sync_service_(sync_service),
-      state_(NOT_RUNNING) {
+      state_(NOT_RUNNING),
+      user_share_(NULL) {
 }
 
 void NonUIDataTypeController::LoadModels(
@@ -57,7 +59,7 @@
   DCHECK(!shared_change_processor_.get());
   shared_change_processor_ = CreateSharedChangeProcessor();
   DCHECK(shared_change_processor_.get());
-
+  user_share_ = sync_service_->GetUserShare();
   model_load_callback_ = model_load_callback;
   if (!StartModels()) {
     // If we are waiting for some external service to load before associating
@@ -311,6 +313,11 @@
           shared_change_processor_));
 }
 
+ChangeProcessor* NonUIDataTypeController::GetChangeProcessor() const {
+  DCHECK_EQ(state_, RUNNING);
+  return shared_change_processor_->generic_change_processor();
+}
+
 // This method can execute after we've already stopped (and possibly even
 // destroyed) both the Syncer and the SyncableService. As a result, all actions
 // must either have no side effects outside of the DTC or must be protected
@@ -331,9 +338,11 @@
   // Note that it's possible the shared_change_processor has already been
   // disconnected at this point, so all our accesses to the syncer from this
   // point on are through it.
+  GenericChangeProcessorFactory factory;
   local_service_ = shared_change_processor->Connect(
       profile_sync_factory_,
-      sync_service_,
+      &factory,
+      user_share_,
       this,
       type(),
       weak_ptr_factory.GetWeakPtr());
@@ -410,13 +419,6 @@
   syncer_merge_result.set_num_items_after_association(
       shared_change_processor->GetSyncCount());
 
-  // If we've been disconnected, sync_service_ may return an invalid
-  // pointer, but |shared_change_processor| protects us from attempting to
-  // access it.
-  // Note: This must be done on the datatype's thread to ensure local_service_
-  // doesn't start trying to push changes from its thread before we activate
-  // the datatype.
-  shared_change_processor->ActivateDataType(model_safe_group());
   StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK,
             local_merge_result,
             syncer_merge_result);
diff --git a/chrome/browser/sync/glue/non_ui_data_type_controller.h b/chrome/browser/sync/glue/non_ui_data_type_controller.h
index f7c8d68..29dbc98 100644
--- a/chrome/browser/sync/glue/non_ui_data_type_controller.h
+++ b/chrome/browser/sync/glue/non_ui_data_type_controller.h
@@ -40,6 +40,7 @@
   virtual void Stop() OVERRIDE;
   virtual syncer::ModelType type() const = 0;
   virtual syncer::ModelSafeGroup model_safe_group() const = 0;
+  virtual ChangeProcessor* GetChangeProcessor() const OVERRIDE;
   virtual std::string name() const OVERRIDE;
   virtual State state() const OVERRIDE;
   virtual void OnSingleDatatypeUnrecoverableError(
@@ -158,6 +159,10 @@
   // reference).
   scoped_refptr<SharedChangeProcessor> shared_change_processor_;
 
+  // The UserShare to connect the SharedChangeProcessor to. NULL until set in
+  // LoadModels.
+  syncer::UserShare* user_share_;
+
   // A weak pointer to the actual local syncable service, which performs all the
   // real work. We do not own the object, and it is only safe to access on the
   // DataType's thread.
diff --git a/chrome/browser/sync/glue/non_ui_data_type_controller_unittest.cc b/chrome/browser/sync/glue/non_ui_data_type_controller_unittest.cc
index 78c467b..e27684a 100644
--- a/chrome/browser/sync/glue/non_ui_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/non_ui_data_type_controller_unittest.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
 #include "chrome/browser/sync/profile_sync_service_mock.h"
 #include "components/sync_driver/data_type_controller_mock.h"
+#include "components/sync_driver/generic_change_processor_factory.h"
 #include "content/public/test/test_browser_thread.h"
 #include "sync/api/fake_syncable_service.h"
 #include "sync/internal_api/public/engine/model_safe_worker.h"
@@ -60,9 +61,10 @@
  public:
   SharedChangeProcessorMock() {}
 
-  MOCK_METHOD5(Connect, base::WeakPtr<syncer::SyncableService>(
-      ProfileSyncComponentsFactory*,
-      ProfileSyncService*,
+  MOCK_METHOD6(Connect, base::WeakPtr<syncer::SyncableService>(
+      browser_sync::SyncApiComponentFactory*,
+      GenericChangeProcessorFactory*,
+      syncer::UserShare*,
       DataTypeErrorHandler*,
       syncer::ModelType,
       const base::WeakPtr<syncer::SyncMergeResult>&));
@@ -78,8 +80,6 @@
                bool(bool*));
   MOCK_METHOD0(CryptoReadyIfNecessary, bool());
   MOCK_CONST_METHOD1(GetDataTypeContext, bool(std::string*));
-  MOCK_METHOD1(ActivateDataType,
-               void(syncer::ModelSafeGroup));
 
  protected:
   virtual ~SharedChangeProcessorMock() {}
@@ -236,11 +236,10 @@
   }
 
   void SetAssociateExpectations() {
-    EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _))
+    EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
         .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
     EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
         .WillOnce(Return(true));
-    EXPECT_CALL(*change_processor_.get(), ActivateDataType(_));
     EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_))
         .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true)));
     EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_,_))
@@ -308,7 +307,7 @@
 
 TEST_F(SyncNonUIDataTypeControllerTest, StartFirstRun) {
   SetStartExpectations();
-  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _))
+  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
       .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
   EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
       .WillOnce(Return(true));
@@ -345,7 +344,7 @@
 // cleanly.
 TEST_F(SyncNonUIDataTypeControllerTest, StartAssociationFailed) {
   SetStartExpectations();
-  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _))
+  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
       .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
   EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
       .WillOnce(Return(true));
@@ -374,7 +373,7 @@
   SetStartExpectations();
   SetStartFailExpectations(DataTypeController::UNRECOVERABLE_ERROR);
   // Set up association to fail with an unrecoverable error.
-  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _))
+  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
       .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
   EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
       .WillRepeatedly(Return(true));
@@ -391,7 +390,7 @@
   SetStartExpectations();
   SetStartFailExpectations(DataTypeController::NEEDS_CRYPTO);
   // Set up association to fail with a NEEDS_CRYPTO error.
-  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _))
+  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
       .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
   EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
       .WillRepeatedly(Return(false));
@@ -409,7 +408,7 @@
 
   SetStartExpectations();
   SetStartFailExpectations(DataTypeController::ABORTED);
-  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _))
+  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
       .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
   EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
       .WillOnce(Return(true));
@@ -459,7 +458,7 @@
   Mock::VerifyAndClearExpectations(change_processor_.get());
   Mock::VerifyAndClearExpectations(dtc_mock_.get());
 
-  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _))
+  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
       .WillOnce(Return(base::WeakPtr<syncer::SyncableService>()));
   non_ui_dtc_->UnblockBackendTasks();
   WaitForDTC();
diff --git a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
index ec18609..463d70b 100644
--- a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc
@@ -28,15 +28,9 @@
 namespace browser_sync {
 namespace {
 
-ACTION_P(ReturnAndRelease, change_processor) {
-  return change_processor->release();
-}
-
 class SyncSearchEngineDataTypeControllerTest : public testing::Test {
  public:
-  SyncSearchEngineDataTypeControllerTest()
-      : change_processor_(new FakeGenericChangeProcessor()) {
-  }
+  SyncSearchEngineDataTypeControllerTest() { }
 
   virtual void SetUp() {
     test_util_.SetUp();
@@ -65,19 +59,14 @@
   }
 
   void SetStartExpectations() {
-    // Ownership gets passed to caller of CreateGenericChangeProcessor.
+    search_engine_dtc_->SetGenericChangeProcessorFactoryForTest(
+        make_scoped_ptr<GenericChangeProcessorFactory>(
+            new FakeGenericChangeProcessorFactory(
+                make_scoped_ptr(new FakeGenericChangeProcessor()))));
     EXPECT_CALL(model_load_callback_, Run(_, _));
     EXPECT_CALL(*profile_sync_factory_,
                 GetSyncableServiceForType(syncer::SEARCH_ENGINES)).
         WillOnce(Return(syncable_service_.AsWeakPtr()));
-    EXPECT_CALL(*profile_sync_factory_,
-                CreateGenericChangeProcessor(_, _, _, _)).
-        WillOnce(ReturnAndRelease(&change_processor_));
-  }
-
-  void SetActivateExpectations() {
-    EXPECT_CALL(*service_.get(),
-                ActivateDataType(syncer::SEARCH_ENGINES, _, _));
   }
 
   void SetStopExpectations() {
@@ -101,7 +90,6 @@
   scoped_refptr<SearchEngineDataTypeController> search_engine_dtc_;
   scoped_ptr<ProfileSyncComponentsFactoryMock> profile_sync_factory_;
   scoped_ptr<ProfileSyncServiceMock> service_;
-  scoped_ptr<FakeGenericChangeProcessor> change_processor_;
   syncer::FakeSyncableService syncable_service_;
   StartCallbackMock start_callback_;
   ModelLoadCallbackMock model_load_callback_;
@@ -111,7 +99,6 @@
   SetStartExpectations();
   // We want to start ready.
   PreloadTemplateURLService();
-  SetActivateExpectations();
   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
 
   EXPECT_EQ(DataTypeController::NOT_RUNNING, search_engine_dtc_->state());
@@ -138,17 +125,6 @@
   base::RunLoop().RunUntilIdle();
 }
 
-TEST_F(SyncSearchEngineDataTypeControllerTest, StartFirstRun) {
-  SetStartExpectations();
-  PreloadTemplateURLService();
-  SetActivateExpectations();
-  change_processor_->set_sync_model_has_user_created_nodes(false);
-  EXPECT_CALL(start_callback_, Run(DataTypeController::OK_FIRST_RUN, _, _));
-
-  Start();
-  EXPECT_TRUE(syncable_service_.syncing());
-}
-
 TEST_F(SyncSearchEngineDataTypeControllerTest, StartAssociationFailed) {
   SetStartExpectations();
   PreloadTemplateURLService();
@@ -169,24 +145,9 @@
   EXPECT_FALSE(syncable_service_.syncing());
 }
 
-TEST_F(SyncSearchEngineDataTypeControllerTest,
-       StartAssociationTriggersUnrecoverableError) {
-  SetStartExpectations();
-  PreloadTemplateURLService();
-  EXPECT_CALL(start_callback_,
-              Run(DataTypeController::UNRECOVERABLE_ERROR, _, _));
-  // Set up association to fail with an unrecoverable error.
-  change_processor_->set_sync_model_has_user_created_nodes_success(false);
-
-  Start();
-  EXPECT_EQ(DataTypeController::NOT_RUNNING, search_engine_dtc_->state());
-  EXPECT_FALSE(syncable_service_.syncing());
-}
-
 TEST_F(SyncSearchEngineDataTypeControllerTest, Stop) {
   SetStartExpectations();
   PreloadTemplateURLService();
-  SetActivateExpectations();
   SetStopExpectations();
   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
 
@@ -204,7 +165,6 @@
        OnSingleDatatypeUnrecoverableError) {
   SetStartExpectations();
   PreloadTemplateURLService();
-  SetActivateExpectations();
   EXPECT_CALL(*service_.get(), DisableBrokenDatatype(_, _, _)).
       WillOnce(InvokeWithoutArgs(search_engine_dtc_.get(),
                                  &SearchEngineDataTypeController::Stop));
diff --git a/chrome/browser/sync/glue/shared_change_processor.cc b/chrome/browser/sync/glue/shared_change_processor.cc
index 22fc64c..eb29911 100644
--- a/chrome/browser/sync/glue/shared_change_processor.cc
+++ b/chrome/browser/sync/glue/shared_change_processor.cc
@@ -4,25 +4,25 @@
 
 #include "chrome/browser/sync/glue/shared_change_processor.h"
 
-#include "chrome/browser/sync/profile_sync_components_factory.h"
-#include "chrome/browser/sync/profile_sync_service.h"
+#include "base/message_loop/message_loop_proxy.h"
 #include "components/sync_driver/generic_change_processor.h"
-#include "content/public/browser/browser_thread.h"
+#include "components/sync_driver/generic_change_processor_factory.h"
+#include "components/sync_driver/sync_api_component_factory.h"
+#include "sync/api/attachments/attachment_service.h"
+#include "sync/api/attachments/fake_attachment_service.h"
+#include "sync/api/attachments/fake_attachment_uploader.h"
 #include "sync/api/sync_change.h"
 
 using base::AutoLock;
-using content::BrowserThread;
 
 namespace browser_sync {
 
 SharedChangeProcessor::SharedChangeProcessor()
     : disconnected_(false),
       type_(syncer::UNSPECIFIED),
-      sync_service_(NULL),
+      frontend_loop_(base::MessageLoopProxy::current()),
       generic_change_processor_(NULL),
       error_handler_(NULL) {
-  // We're always created on the UI thread.
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
 
 SharedChangeProcessor::~SharedChangeProcessor() {
@@ -30,7 +30,7 @@
   // thread), or when the syncer::SyncableService stop's syncing (datatype
   // thread).  |generic_change_processor_|, if non-NULL, must be
   // deleted on |backend_loop_|.
-  if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+  if (frontend_loop_->BelongsToCurrentThread()) {
     if (backend_loop_.get()) {
       if (!backend_loop_->DeleteSoon(FROM_HERE, generic_change_processor_)) {
         NOTREACHED();
@@ -46,13 +46,13 @@
 }
 
 base::WeakPtr<syncer::SyncableService> SharedChangeProcessor::Connect(
-    ProfileSyncComponentsFactory* sync_factory,
-    ProfileSyncService* sync_service,
+    browser_sync::SyncApiComponentFactory* sync_factory,
+    GenericChangeProcessorFactory* processor_factory,
+    syncer::UserShare* user_share,
     DataTypeErrorHandler* error_handler,
     syncer::ModelType type,
     const base::WeakPtr<syncer::SyncMergeResult>& merge_result) {
   DCHECK(sync_factory);
-  DCHECK(sync_service);
   DCHECK(error_handler);
   DCHECK_NE(type, syncer::UNSPECIFIED);
   backend_loop_ = base::MessageLoopProxy::current();
@@ -60,7 +60,6 @@
   if (disconnected_)
     return base::WeakPtr<syncer::SyncableService>();
   type_ = type;
-  sync_service_ = sync_service;
   error_handler_ = error_handler;
   base::WeakPtr<syncer::SyncableService> local_service =
       sync_factory->GetSyncableServiceForType(type);
@@ -70,12 +69,25 @@
     return base::WeakPtr<syncer::SyncableService>();
   }
 
-  // TODO(zea): Pass |merge_result| to the generic change processor.
-  generic_change_processor_ =
-      sync_factory->CreateGenericChangeProcessor(sync_service_,
-                                                 error_handler,
-                                                 local_service,
-                                                 merge_result);
+  // TODO(maniscalco): Use a shared (one per profile) thread-safe instance of
+  // AttachmentUpload instead of creating a new one per AttachmentService (bug
+  // 369536).
+  scoped_ptr<syncer::AttachmentUploader> attachment_uploader(
+      new syncer::FakeAttachmentUploader);
+
+  // TODO(maniscalco): Replace FakeAttachmentService with a real
+  // AttachmentService implementation once implemented (bug 356359).
+  scoped_ptr<syncer::AttachmentService> attachment_service(
+      new syncer::FakeAttachmentService(
+          sync_factory->CreateCustomAttachmentStoreForType(type),
+          attachment_uploader.Pass()));
+
+  generic_change_processor_ = processor_factory->CreateGenericChangeProcessor(
+      user_share,
+      error_handler,
+      local_service,
+      merge_result,
+      attachment_service.Pass()).release();
   return local_service;
 }
 
@@ -89,6 +101,10 @@
   return was_connected;
 }
 
+ChangeProcessor* SharedChangeProcessor::generic_change_processor() {
+  return generic_change_processor_;
+}
+
 int SharedChangeProcessor::GetSyncCount() {
   DCHECK(backend_loop_.get());
   DCHECK(backend_loop_->BelongsToCurrentThread());
@@ -194,20 +210,6 @@
   return generic_change_processor_->GetDataTypeContext(type_, context);
 }
 
-void SharedChangeProcessor::ActivateDataType(
-    syncer::ModelSafeGroup model_safe_group) {
-  DCHECK(backend_loop_.get());
-  DCHECK(backend_loop_->BelongsToCurrentThread());
-  AutoLock lock(monitor_lock_);
-  if (disconnected_) {
-    LOG(ERROR) << "Change processor disconnected.";
-    return;
-  }
-  sync_service_->ActivateDataType(type_,
-                                  model_safe_group,
-                                  generic_change_processor_);
-}
-
 syncer::SyncError SharedChangeProcessor::CreateAndUploadError(
     const tracked_objects::Location& location,
     const std::string& message) {
diff --git a/chrome/browser/sync/glue/shared_change_processor.h b/chrome/browser/sync/glue/shared_change_processor.h
index 1012676..7000bd9 100644
--- a/chrome/browser/sync/glue/shared_change_processor.h
+++ b/chrome/browser/sync/glue/shared_change_processor.h
@@ -12,25 +12,26 @@
 #include "base/synchronization/lock.h"
 #include "components/sync_driver/data_type_error_handler.h"
 #include "sync/api/sync_change_processor.h"
+#include "sync/api/sync_data.h"
 #include "sync/api/sync_error.h"
 #include "sync/api/sync_error_factory.h"
 #include "sync/api/sync_merge_result.h"
 #include "sync/internal_api/public/engine/model_safe_worker.h"
 
-class ProfileSyncComponentsFactory;
 class ProfileSyncService;
 
 namespace syncer {
-class SyncData;
 class SyncableService;
-
-typedef std::vector<syncer::SyncData> SyncDataList;
+struct UserShare;
 }  // namespace syncer
 
 namespace browser_sync {
 
+class ChangeProcessor;
 class GenericChangeProcessor;
+class GenericChangeProcessorFactory;
 class DataTypeErrorHandler;
+class SyncApiComponentFactory;
 
 // A ref-counted wrapper around a GenericChangeProcessor for use with datatypes
 // that don't live on the UI thread.
@@ -52,7 +53,7 @@
 class SharedChangeProcessor
     : public base::RefCountedThreadSafe<SharedChangeProcessor> {
  public:
-  // Create an uninitialized SharedChangeProcessor (to be later connected).
+  // Create an uninitialized SharedChangeProcessor.
   SharedChangeProcessor();
 
   // Connect to the Syncer and prepare to handle changes for |type|. Will
@@ -61,10 +62,11 @@
   // Note: If this SharedChangeProcessor has been disconnected, or the
   // syncer::SyncableService was not alive, will return a null weak pointer.
   virtual base::WeakPtr<syncer::SyncableService> Connect(
-    ProfileSyncComponentsFactory* sync_factory,
-    ProfileSyncService* sync_service,
-    DataTypeErrorHandler* error_handler,
-    syncer::ModelType type,
+      browser_sync::SyncApiComponentFactory* sync_factory,
+      GenericChangeProcessorFactory* processor_factory,
+      syncer::UserShare* user_share,
+      DataTypeErrorHandler* error_handler,
+      syncer::ModelType type,
     const base::WeakPtr<syncer::SyncMergeResult>& merge_result);
 
   // Disconnects from the generic change processor. May be called from any
@@ -99,15 +101,12 @@
   // set, returns false.
   virtual bool GetDataTypeContext(std::string* context) const;
 
-  // Register |generic_change_processor_| as the change processor for the
-  // current type on |model_safe_group|.
-  // Does nothing if |disconnected_| is true.
-  virtual void ActivateDataType(syncer::ModelSafeGroup model_safe_group);
-
   virtual syncer::SyncError CreateAndUploadError(
       const tracked_objects::Location& location,
       const std::string& message);
 
+  ChangeProcessor* generic_change_processor();
+
  protected:
   friend class base::RefCountedThreadSafe<SharedChangeProcessor>;
   virtual ~SharedChangeProcessor();
@@ -124,8 +123,9 @@
   // The sync datatype we were last connected to.
   syncer::ModelType type_;
 
-  // The ProfileSyncService we're currently connected to.
-  ProfileSyncService* sync_service_;
+  // The frontend / UI MessageLoop this object is constructed on. May also be
+  // destructed and/or disconnected on this loop, see ~SharedChangeProcessor.
+  const scoped_refptr<const base::MessageLoopProxy> frontend_loop_;
 
   // The loop that all methods except the constructor, destructor, and
   // Disconnect() should be called on.  Set in Connect().
diff --git a/chrome/browser/sync/glue/shared_change_processor_unittest.cc b/chrome/browser/sync/glue/shared_change_processor_unittest.cc
index 6f9afc5..46190b1 100644
--- a/chrome/browser/sync/glue/shared_change_processor_unittest.cc
+++ b/chrome/browser/sync/glue/shared_change_processor_unittest.cc
@@ -14,6 +14,8 @@
 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
 #include "chrome/browser/sync/profile_sync_service_mock.h"
 #include "components/sync_driver/data_type_error_handler_mock.h"
+#include "components/sync_driver/generic_change_processor.h"
+#include "components/sync_driver/generic_change_processor_factory.h"
 #include "content/public/test/test_browser_thread.h"
 #include "sync/api/fake_syncable_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -104,9 +106,13 @@
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
     EXPECT_CALL(sync_factory_, GetSyncableServiceForType(syncer::AUTOFILL)).
         WillOnce(GetWeakPtrToSyncableService(db_syncable_service_.get()));
+    syncer::UserShare share;
+    EXPECT_CALL(sync_service_, GetUserShare()).WillOnce(
+        ::testing::Return(&share));
     EXPECT_TRUE(shared_change_processor->Connect(
         &sync_factory_,
-        &sync_service_,
+        &processor_factory_,
+        sync_service_.GetUserShare(),
         &error_handler_,
         syncer::AUTOFILL,
         base::WeakPtr<syncer::SyncMergeResult>()));
@@ -122,6 +128,8 @@
   NiceMock<ProfileSyncServiceMock> sync_service_;
   StrictMock<DataTypeErrorHandlerMock> error_handler_;
 
+  GenericChangeProcessorFactory processor_factory_;
+
   // Used only on DB thread.
   scoped_ptr<syncer::FakeSyncableService> db_syncable_service_;
 };
diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h
index e9fb105..d92fe04 100644
--- a/chrome/browser/sync/glue/sync_backend_host.h
+++ b/chrome/browser/sync/glue/sync_backend_host.h
@@ -143,17 +143,6 @@
   // Turns on encryption of all present and future sync data.
   virtual void EnableEncryptEverything() = 0;
 
-  // Activates change processing for the given data type.  This must
-  // be called synchronously with the data type's model association so
-  // no changes are dropped between model association and change
-  // processor activation.
-  virtual void ActivateDataType(
-      syncer::ModelType type, syncer::ModelSafeGroup group,
-      ChangeProcessor* change_processor) = 0;
-
-  // Deactivates change processing for the given data type.
-  virtual void DeactivateDataType(syncer::ModelType type) = 0;
-
   // Called on |frontend_loop_| to obtain a handle to the UserShare needed for
   // creating transactions.  Should not be called before we signal
   // initialization is complete with OnBackendInitialized().
@@ -215,6 +204,14 @@
       base::Callback<void(const std::vector<syncer::ModelType>&,
                           ScopedVector<base::ListValue>)> type) = 0;
 
+  // Enables the sending of directory type debug counters.  Also, for every
+  // time it is called, it makes an explicit request that updates to an update
+  // for all counters be emitted.
+  virtual void EnableDirectoryTypeDebugInfoForwarding() = 0;
+
+  // Disables the sending of directory type debug counters.
+  virtual void DisableDirectoryTypeDebugInfoForwarding() = 0;
+
   virtual base::MessageLoop* GetSyncLoopForTesting() = 0;
 
   DISALLOW_COPY_AND_ASSIGN(SyncBackendHost);
diff --git a/chrome/browser/sync/glue/sync_backend_host_core.cc b/chrome/browser/sync/glue/sync_backend_host_core.cc
index b5e2eb3..32b7da2 100644
--- a/chrome/browser/sync/glue/sync_backend_host_core.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_core.cc
@@ -15,7 +15,10 @@
 #include "sync/internal_api/public/events/protocol_event.h"
 #include "sync/internal_api/public/http_post_provider_factory.h"
 #include "sync/internal_api/public/internal_components_factory.h"
+#include "sync/internal_api/public/sessions/commit_counters.h"
+#include "sync/internal_api/public/sessions/status_counters.h"
 #include "sync/internal_api/public/sessions/sync_session_snapshot.h"
+#include "sync/internal_api/public/sessions/update_counters.h"
 #include "sync/internal_api/public/sync_core_proxy.h"
 #include "sync/internal_api/public/sync_manager.h"
 #include "sync/internal_api/public/sync_manager_factory.h"
@@ -300,6 +303,33 @@
       type, passphrase_time);
 }
 
+void SyncBackendHostCore::OnCommitCountersUpdated(
+    syncer::ModelType type,
+    const syncer::CommitCounters& counters) {
+  host_.Call(
+      FROM_HERE,
+      &SyncBackendHostImpl::HandleDirectoryCommitCountersUpdatedOnFrontendLoop,
+      type, counters);
+}
+
+void SyncBackendHostCore::OnUpdateCountersUpdated(
+    syncer::ModelType type,
+    const syncer::UpdateCounters& counters) {
+  host_.Call(
+      FROM_HERE,
+      &SyncBackendHostImpl::HandleDirectoryUpdateCountersUpdatedOnFrontendLoop,
+      type, counters);
+}
+
+void SyncBackendHostCore::OnStatusCountersUpdated(
+    syncer::ModelType type,
+    const syncer::StatusCounters& counters) {
+  host_.Call(
+      FROM_HERE,
+      &SyncBackendHostImpl::HandleDirectoryStatusCountersUpdatedOnFrontendLoop,
+      type, counters);
+}
+
 void SyncBackendHostCore::OnActionableError(
     const syncer::SyncProtocolError& sync_error) {
   if (!sync_loop_)
@@ -548,6 +578,7 @@
   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   if (sync_manager_) {
     save_changes_timer_.reset();
+    DisableDirectoryTypeDebugInfoForwarding();
     sync_manager_->RemoveObserver(this);
     sync_manager_->ShutdownOnSyncThread();
     sync_manager_.reset();
@@ -636,6 +667,19 @@
   forward_protocol_events_ = false;
 }
 
+void SyncBackendHostCore::EnableDirectoryTypeDebugInfoForwarding() {
+  DCHECK(sync_manager_);
+  if (!sync_manager_->HasDirectoryTypeDebugInfoObserver(this))
+    sync_manager_->RegisterDirectoryTypeDebugInfoObserver(this);
+  sync_manager_->RequestEmitDebugInfo();
+}
+
+void SyncBackendHostCore::DisableDirectoryTypeDebugInfoForwarding() {
+  DCHECK(sync_manager_);
+  if (sync_manager_->HasDirectoryTypeDebugInfoObserver(this))
+    sync_manager_->UnregisterDirectoryTypeDebugInfoObserver(this);
+}
+
 void SyncBackendHostCore::DeleteSyncDataFolder() {
   DCHECK_EQ(base::MessageLoop::current(), sync_loop_);
   if (base::DirectoryExists(sync_data_folder_path_)) {
diff --git a/chrome/browser/sync/glue/sync_backend_host_core.h b/chrome/browser/sync/glue/sync_backend_host_core.h
index eb267a6..4ae89c7 100644
--- a/chrome/browser/sync/glue/sync_backend_host_core.h
+++ b/chrome/browser/sync/glue/sync_backend_host_core.h
@@ -11,6 +11,7 @@
 #include "chrome/browser/sync/glue/sync_backend_host_impl.h"
 #include "components/sync_driver/system_encryptor.h"
 #include "sync/internal_api/public/base/cancelation_signal.h"
+#include "sync/internal_api/public/sessions/type_debug_info_observer.h"
 #include "sync/internal_api/public/sync_encryption_handler.h"
 #include "url/gurl.h"
 
@@ -79,7 +80,8 @@
 class SyncBackendHostCore
     : public base::RefCountedThreadSafe<SyncBackendHostCore>,
       public syncer::SyncEncryptionHandler::Observer,
-      public syncer::SyncManager::Observer {
+      public syncer::SyncManager::Observer,
+      public syncer::TypeDebugInfoObserver {
  public:
   SyncBackendHostCore(const std::string& name,
        const base::FilePath& sync_data_folder_path,
@@ -121,6 +123,17 @@
   virtual void OnPassphraseTypeChanged(syncer::PassphraseType type,
                                        base::Time passphrase_time) OVERRIDE;
 
+  // TypeDebugInfoObserver implementation
+  virtual void OnCommitCountersUpdated(
+      syncer::ModelType type,
+      const syncer::CommitCounters& counters) OVERRIDE;
+  virtual void OnUpdateCountersUpdated(
+      syncer::ModelType type,
+      const syncer::UpdateCounters& counters) OVERRIDE;
+  virtual void OnStatusCountersUpdated(
+      syncer::ModelType type,
+      const syncer::StatusCounters& counters) OVERRIDE;
+
   // Forwards an invalidation state change to the sync manager.
   void DoOnInvalidatorStateChange(syncer::InvalidatorState state);
 
@@ -212,6 +225,14 @@
   void SendBufferedProtocolEventsAndEnableForwarding();
   void DisableProtocolEventForwarding();
 
+  // Enables the forwarding of directory type debug counters to the
+  // SyncBackendHost.  Also requests that updates to all counters be
+  // emitted right away to initialize any new listeners' states.
+  void EnableDirectoryTypeDebugInfoForwarding();
+
+  // Disables forwarding of directory type debug counters.
+  void DisableDirectoryTypeDebugInfoForwarding();
+
   // Delete the sync data folder to cleanup backend data.  Happens the first
   // time sync is enabled for a user (to prevent accidentally reusing old
   // sync databases), as well as shutdown when you're no longer syncing.
diff --git a/chrome/browser/sync/glue/sync_backend_host_impl.cc b/chrome/browser/sync/glue/sync_backend_host_impl.cc
index ac4eacd..cee5863 100644
--- a/chrome/browser/sync/glue/sync_backend_host_impl.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_impl.cc
@@ -500,6 +500,24 @@
           core_));
 }
 
+void SyncBackendHostImpl::EnableDirectoryTypeDebugInfoForwarding() {
+  DCHECK(initialized());
+  registrar_->sync_thread()->message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &SyncBackendHostCore::EnableDirectoryTypeDebugInfoForwarding,
+          core_));
+}
+
+void SyncBackendHostImpl::DisableDirectoryTypeDebugInfoForwarding() {
+  DCHECK(initialized());
+  registrar_->sync_thread()->message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &SyncBackendHostCore::DisableDirectoryTypeDebugInfoForwarding,
+          core_));
+}
+
 void SyncBackendHostImpl::GetAllNodesForTypes(
     syncer::ModelTypeSet types,
     base::Callback<void(const std::vector<syncer::ModelType>&,
@@ -796,6 +814,30 @@
   frontend_->OnProtocolEvent(*scoped_event);
 }
 
+void SyncBackendHostImpl::HandleDirectoryCommitCountersUpdatedOnFrontendLoop(
+    syncer::ModelType type,
+    const syncer::CommitCounters& counters) {
+  if (!frontend_)
+    return;
+  frontend_->OnDirectoryTypeCommitCounterUpdated(type, counters);
+}
+
+void SyncBackendHostImpl::HandleDirectoryUpdateCountersUpdatedOnFrontendLoop(
+    syncer::ModelType type,
+    const syncer::UpdateCounters& counters) {
+  if (!frontend_)
+    return;
+  frontend_->OnDirectoryTypeUpdateCounterUpdated(type, counters);
+}
+
+void SyncBackendHostImpl::HandleDirectoryStatusCountersUpdatedOnFrontendLoop(
+    syncer::ModelType type,
+    const syncer::StatusCounters& counters) {
+  if (!frontend_)
+    return;
+  frontend_->OnDirectoryTypeStatusCounterUpdated(type, counters);
+}
+
 base::MessageLoop* SyncBackendHostImpl::GetSyncLoopForTesting() {
   return registrar_->sync_thread()->message_loop();
 }
diff --git a/chrome/browser/sync/glue/sync_backend_host_impl.h b/chrome/browser/sync/glue/sync_backend_host_impl.h
index 9ba56b3..6d90bcf 100644
--- a/chrome/browser/sync/glue/sync_backend_host_impl.h
+++ b/chrome/browser/sync/glue/sync_backend_host_impl.h
@@ -21,6 +21,7 @@
 #include "sync/internal_api/public/base/model_type.h"
 #include "sync/internal_api/public/configure_reason.h"
 #include "sync/internal_api/public/sessions/sync_session_snapshot.h"
+#include "sync/internal_api/public/sessions/type_debug_info_observer.h"
 #include "sync/internal_api/public/sync_manager.h"
 #include "sync/internal_api/public/util/report_unrecoverable_error_function.h"
 #include "sync/internal_api/public/util/unrecoverable_error_handler.h"
@@ -106,11 +107,11 @@
       const base::Callback<void(syncer::ModelTypeSet,
                                 syncer::ModelTypeSet)>& ready_task,
       const base::Callback<void()>& retry_callback) OVERRIDE;
-  virtual void EnableEncryptEverything() OVERRIDE;
   virtual void ActivateDataType(
-      syncer::ModelType type, syncer::ModelSafeGroup group,
-      ChangeProcessor* change_processor) OVERRIDE;
+     syncer::ModelType type, syncer::ModelSafeGroup group,
+     ChangeProcessor* change_processor) OVERRIDE;
   virtual void DeactivateDataType(syncer::ModelType type) OVERRIDE;
+  virtual void EnableEncryptEverything() OVERRIDE;
   virtual syncer::UserShare* GetUserShare() const OVERRIDE;
   virtual scoped_ptr<syncer::SyncCoreProxy> GetSyncCoreProxy() OVERRIDE;
   virtual Status GetDetailedStatus() OVERRIDE;
@@ -127,6 +128,8 @@
   virtual SyncedDeviceTracker* GetSyncedDeviceTracker() const OVERRIDE;
   virtual void RequestBufferedProtocolEventsAndEnableForwarding() OVERRIDE;
   virtual void DisableProtocolEventForwarding() OVERRIDE;
+  virtual void EnableDirectoryTypeDebugInfoForwarding() OVERRIDE;
+  virtual void DisableDirectoryTypeDebugInfoForwarding() OVERRIDE;
   virtual void GetAllNodesForTypes(
       syncer::ModelTypeSet types,
       base::Callback<void(const std::vector<syncer::ModelType>&,
@@ -183,6 +186,27 @@
   // forwarding these events.
   void HandleProtocolEventOnFrontendLoop(syncer::ProtocolEvent* event);
 
+  // Forwards a directory commit counter update to the frontend loop.  Will not
+  // be called unless a call to EnableDirectoryTypeDebugInfoForwarding()
+  // explicitly requested that we start forwarding these events.
+  void HandleDirectoryCommitCountersUpdatedOnFrontendLoop(
+      syncer::ModelType type,
+      const syncer::CommitCounters& counters);
+
+  // Forwards a directory update counter update to the frontend loop.  Will not
+  // be called unless a call to EnableDirectoryTypeDebugInfoForwarding()
+  // explicitly requested that we start forwarding these events.
+  void HandleDirectoryUpdateCountersUpdatedOnFrontendLoop(
+      syncer::ModelType type,
+      const syncer::UpdateCounters& counters);
+
+  // Forwards a directory status counter update to the frontend loop.  Will not
+  // be called unless a call to EnableDirectoryTypeDebugInfoForwarding()
+  // explicitly requested that we start forwarding these events.
+  void HandleDirectoryStatusCountersUpdatedOnFrontendLoop(
+      syncer::ModelType type,
+      const syncer::StatusCounters& counters);
+
   SyncFrontend* frontend() { return frontend_; }
 
  private:
diff --git a/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc b/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc
index 239c38b..1d2ce7d 100644
--- a/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc
@@ -32,6 +32,9 @@
 #include "sync/internal_api/public/engine/model_safe_worker.h"
 #include "sync/internal_api/public/http_bridge_network_resources.h"
 #include "sync/internal_api/public/network_resources.h"
+#include "sync/internal_api/public/sessions/commit_counters.h"
+#include "sync/internal_api/public/sessions/status_counters.h"
+#include "sync/internal_api/public/sessions/update_counters.h"
 #include "sync/internal_api/public/sync_manager_factory.h"
 #include "sync/internal_api/public/test/fake_sync_manager.h"
 #include "sync/internal_api/public/util/experiments.h"
@@ -87,6 +90,12 @@
   MOCK_METHOD0(OnEncryptionComplete, void());
   MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet));
   MOCK_METHOD1(OnProtocolEvent, void(const syncer::ProtocolEvent&));
+  MOCK_METHOD2(OnDirectoryTypeCommitCounterUpdated,
+               void(syncer::ModelType, const syncer::CommitCounters&));
+  MOCK_METHOD2(OnDirectoryTypeUpdateCounterUpdated,
+               void(syncer::ModelType, const syncer::UpdateCounters&));
+  MOCK_METHOD2(OnDirectoryTypeStatusCounterUpdated,
+               void(syncer::ModelType, const syncer::StatusCounters&));
   MOCK_METHOD1(OnExperimentsChanged,
       void(const syncer::Experiments&));
   MOCK_METHOD1(OnActionableError,
diff --git a/chrome/browser/sync/glue/sync_backend_host_mock.cc b/chrome/browser/sync/glue/sync_backend_host_mock.cc
index aee76c6..b1257a0 100644
--- a/chrome/browser/sync/glue/sync_backend_host_mock.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_mock.cc
@@ -118,6 +118,10 @@
 
 void SyncBackendHostMock::DisableProtocolEventForwarding() {}
 
+void SyncBackendHostMock::EnableDirectoryTypeDebugInfoForwarding() {}
+
+void SyncBackendHostMock::DisableDirectoryTypeDebugInfoForwarding() {}
+
 void SyncBackendHostMock::GetAllNodesForTypes(
     syncer::ModelTypeSet types,
     base::Callback<void(const std::vector<syncer::ModelType>& type,
diff --git a/chrome/browser/sync/glue/sync_backend_host_mock.h b/chrome/browser/sync/glue/sync_backend_host_mock.h
index 0b0782d..42cfeae 100644
--- a/chrome/browser/sync/glue/sync_backend_host_mock.h
+++ b/chrome/browser/sync/glue/sync_backend_host_mock.h
@@ -98,6 +98,9 @@
   virtual void RequestBufferedProtocolEventsAndEnableForwarding() OVERRIDE;
   virtual void DisableProtocolEventForwarding() OVERRIDE;
 
+  virtual void EnableDirectoryTypeDebugInfoForwarding() OVERRIDE;
+  virtual void DisableDirectoryTypeDebugInfoForwarding() OVERRIDE;
+
   virtual void GetAllNodesForTypes(
       syncer::ModelTypeSet types,
       base::Callback<void(const std::vector<syncer::ModelType>& type,
diff --git a/chrome/browser/sync/glue/sync_backend_registrar.cc b/chrome/browser/sync/glue/sync_backend_registrar.cc
index ded6f42..fb046be 100644
--- a/chrome/browser/sync/glue/sync_backend_registrar.cc
+++ b/chrome/browser/sync/glue/sync_backend_registrar.cc
@@ -204,14 +204,12 @@
     syncer::UserShare* user_share) {
   DVLOG(1) << "Activate: " << syncer::ModelTypeToString(type);
 
-  CHECK(IsOnThreadForGroup(type, group));
   base::AutoLock lock(lock_);
   // Ensure that the given data type is in the PASSIVE group.
   syncer::ModelSafeRoutingInfo::iterator i = routing_info_.find(type);
   DCHECK(i != routing_info_.end());
   DCHECK_EQ(i->second, syncer::GROUP_PASSIVE);
   routing_info_[type] = group;
-  CHECK(IsCurrentThreadSafeForModel(type));
 
   // Add the data type's change processor to the list of change
   // processors so it can receive updates.
diff --git a/chrome/browser/sync/glue/ui_data_type_controller.cc b/chrome/browser/sync/glue/ui_data_type_controller.cc
index b127442..2863f44 100644
--- a/chrome/browser/sync/glue/ui_data_type_controller.cc
+++ b/chrome/browser/sync/glue/ui_data_type_controller.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/sync/glue/shared_change_processor_ref.h"
 #include "chrome/browser/sync/profile_sync_components_factory.h"
 #include "chrome/browser/sync/profile_sync_service.h"
+#include "components/sync_driver/generic_change_processor_factory.h"
 #include "content/public/browser/browser_thread.h"
 #include "sync/api/sync_error.h"
 #include "sync/api/syncable_service.h"
@@ -41,7 +42,8 @@
       profile_(profile),
       sync_service_(sync_service),
       state_(NOT_RUNNING),
-      type_(type) {
+      type_(type),
+      processor_factory_(new GenericChangeProcessorFactory()) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(profile_sync_factory);
   DCHECK(profile);
@@ -49,6 +51,12 @@
   DCHECK(syncer::IsRealDataType(type_));
 }
 
+void UIDataTypeController::SetGenericChangeProcessorFactoryForTest(
+      scoped_ptr<GenericChangeProcessorFactory> factory) {
+  DCHECK_EQ(state_, NOT_RUNNING);
+  processor_factory_ = factory.Pass();
+}
+
 UIDataTypeController::~UIDataTypeController() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
@@ -129,7 +137,8 @@
   // syncer::SyncableService associated with type().
   local_service_ = shared_change_processor_->Connect(
       profile_sync_factory_,
-      sync_service_,
+      processor_factory_.get(),
+      sync_service_->GetUserShare(),
       this,
       type(),
       weak_ptr_factory.GetWeakPtr());
@@ -206,13 +215,17 @@
   syncer_merge_result.set_num_items_after_association(
       shared_change_processor_->GetSyncCount());
 
-  shared_change_processor_->ActivateDataType(model_safe_group());
   state_ = RUNNING;
   StartDone(sync_has_nodes ? OK : OK_FIRST_RUN,
             local_merge_result,
             syncer_merge_result);
 }
 
+ChangeProcessor* UIDataTypeController::GetChangeProcessor() const {
+  DCHECK_EQ(state_, RUNNING);
+  return shared_change_processor_->generic_change_processor();
+}
+
 void UIDataTypeController::AbortModelLoad() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   state_ = NOT_RUNNING;
diff --git a/chrome/browser/sync/glue/ui_data_type_controller.h b/chrome/browser/sync/glue/ui_data_type_controller.h
index c30c1d4..1552f3f 100644
--- a/chrome/browser/sync/glue/ui_data_type_controller.h
+++ b/chrome/browser/sync/glue/ui_data_type_controller.h
@@ -50,6 +50,7 @@
   virtual void Stop() OVERRIDE;
   virtual syncer::ModelType type() const OVERRIDE;
   virtual syncer::ModelSafeGroup model_safe_group() const OVERRIDE;
+  virtual ChangeProcessor* GetChangeProcessor() const OVERRIDE;
   virtual std::string name() const OVERRIDE;
   virtual State state() const OVERRIDE;
 
@@ -58,6 +59,11 @@
       const tracked_objects::Location& from_here,
       const std::string& message) OVERRIDE;
 
+  // Used by tests to override the factory used to create
+  // GenericChangeProcessors.
+  void SetGenericChangeProcessorFactoryForTest(
+      scoped_ptr<GenericChangeProcessorFactory> factory);
+
  protected:
   // For testing only.
   UIDataTypeController();
@@ -118,6 +124,8 @@
   // datatypes).
   scoped_refptr<SharedChangeProcessor> shared_change_processor_;
 
+  scoped_ptr<GenericChangeProcessorFactory> processor_factory_;
+
   // A weak pointer to the actual local syncable service, which performs all the
   // real work. We do not own the object.
   base::WeakPtr<syncer::SyncableService> local_service_;
diff --git a/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc b/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc
index 14d2abb..0b45441 100644
--- a/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc
@@ -25,10 +25,6 @@
 namespace browser_sync {
 namespace {
 
-ACTION_P(ReturnAndRelease, change_processor) {
-  return change_processor->release();
-}
-
 // TODO(zea): Expand this to make the dtc type paramterizable. This will let us
 // test the basic functionality of all UIDataTypeControllers. We'll need to have
 // intelligent default values for the methods queried in the dependent services
@@ -39,7 +35,7 @@
       : ui_thread_(BrowserThread::UI, &message_loop_),
         profile_sync_service_(&profile_),
         type_(syncer::PREFERENCES),
-        change_processor_(new FakeGenericChangeProcessor()) {}
+        change_processor_(NULL) {}
 
   virtual void SetUp() {
     profile_sync_factory_.reset(new ProfileSyncComponentsFactoryMock());
@@ -62,18 +58,14 @@
 
  protected:
   void SetStartExpectations() {
-    // Ownership gets passed to caller of CreateGenericChangeProcessor.
-    change_processor_.reset(new FakeGenericChangeProcessor());
+    scoped_ptr<FakeGenericChangeProcessor> p(new FakeGenericChangeProcessor());
+    change_processor_ = p.get();
+    scoped_ptr<GenericChangeProcessorFactory> f(
+        new FakeGenericChangeProcessorFactory(p.Pass()));
+    preference_dtc_->SetGenericChangeProcessorFactoryForTest(f.Pass());
     EXPECT_CALL(model_load_callback_, Run(_, _));
     EXPECT_CALL(*profile_sync_factory_, GetSyncableServiceForType(type_)).
         WillOnce(Return(syncable_service_.AsWeakPtr()));
-    EXPECT_CALL(*profile_sync_factory_,
-                CreateGenericChangeProcessor(_, _, _, _)).
-        WillOnce(ReturnAndRelease(&change_processor_));
-  }
-
-  void SetActivateExpectations() {
-    EXPECT_CALL(profile_sync_service_, ActivateDataType(type_, _, _));
   }
 
   void SetStopExpectations() {
@@ -102,7 +94,7 @@
   StartCallbackMock start_callback_;
   ModelLoadCallbackMock model_load_callback_;
   scoped_refptr<UIDataTypeController> preference_dtc_;
-  scoped_ptr<FakeGenericChangeProcessor> change_processor_;
+  FakeGenericChangeProcessor* change_processor_;
   syncer::FakeSyncableService syncable_service_;
 };
 
@@ -110,7 +102,6 @@
 // service has been told to start syncing and that the DTC is now in RUNNING
 // state.
 TEST_F(SyncUIDataTypeControllerTest, Start) {
-  SetActivateExpectations();
   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
 
   EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state());
@@ -123,7 +114,6 @@
 // Start and then stop the DTC. Verify that the service started and stopped
 // syncing, and that the DTC went from RUNNING to NOT_RUNNING.
 TEST_F(SyncUIDataTypeControllerTest, StartStop) {
-  SetActivateExpectations();
   SetStopExpectations();
   EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _));
 
@@ -140,7 +130,6 @@
 // Start the DTC when no user nodes are created. Verify that the callback
 // is called with OK_FIRST_RUN. Stop the DTC.
 TEST_F(SyncUIDataTypeControllerTest, StartStopFirstRun) {
-  SetActivateExpectations();
   SetStopExpectations();
   EXPECT_CALL(start_callback_, Run(DataTypeController::OK_FIRST_RUN, _, _));
   change_processor_->set_sync_model_has_user_created_nodes(false);
@@ -197,7 +186,6 @@
 // Start the DTC, but then trigger an unrecoverable error. Verify the syncer
 // gets stopped and the DTC is in NOT_RUNNING state.
 TEST_F(SyncUIDataTypeControllerTest, OnSingleDatatypeUnrecoverableError) {
-  SetActivateExpectations();
   EXPECT_CALL(profile_sync_service_, DisableBrokenDatatype(_,_,_)).
       WillOnce(InvokeWithoutArgs(preference_dtc_.get(),
                                  &UIDataTypeController::Stop));
diff --git a/chrome/browser/sync/managed_user_signin_manager_wrapper.cc b/chrome/browser/sync/managed_user_signin_manager_wrapper.cc
index 5fa2e17..6d54006 100644
--- a/chrome/browser/sync/managed_user_signin_manager_wrapper.cc
+++ b/chrome/browser/sync/managed_user_signin_manager_wrapper.cc
@@ -24,26 +24,19 @@
 }
 
 std::string ManagedUserSigninManagerWrapper::GetEffectiveUsername() const {
-  if (profile_->IsManaged()) {
+  const std::string& auth_username = original_->GetAuthenticatedUsername();
 #if defined(ENABLE_MANAGED_USERS)
-    DCHECK_EQ(std::string(), original_->GetAuthenticatedUsername());
+  if (auth_username.empty() && profile_->IsManaged())
     return managed_users::kManagedUserPseudoEmail;
-#else
-    NOTREACHED();
 #endif
-  }
-
-  return original_->GetAuthenticatedUsername();
+  return auth_username;
 }
 
 std::string ManagedUserSigninManagerWrapper::GetAccountIdToUse() const {
-  if (profile_->IsManaged()) {
+  const std::string& auth_account = original_->GetAuthenticatedAccountId();
 #if defined(ENABLE_MANAGED_USERS)
+  if (auth_account.empty() && profile_->IsManaged())
     return managed_users::kManagedUserPseudoEmail;
-#else
-    NOTREACHED();
 #endif
-  }
-
-  return original_->GetAuthenticatedAccountId();
+  return auth_account;
 }
diff --git a/chrome/browser/sync/profile_sync_components_factory.h b/chrome/browser/sync/profile_sync_components_factory.h
index a9329e2..1125bb6 100644
--- a/chrome/browser/sync/profile_sync_components_factory.h
+++ b/chrome/browser/sync/profile_sync_components_factory.h
@@ -94,13 +94,6 @@
       Profile* profile,
       const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs) = 0;
 
-  // Creating this in the factory helps us mock it out in testing.
-  virtual browser_sync::GenericChangeProcessor* CreateGenericChangeProcessor(
-      ProfileSyncService* profile_sync_service,
-      browser_sync::DataTypeErrorHandler* error_handler,
-      const base::WeakPtr<syncer::SyncableService>& local_service,
-      const base::WeakPtr<syncer::SyncMergeResult>& merge_result) = 0;
-
   // Legacy datatypes that need to be converted to the SyncableService API.
   virtual SyncComponents CreateBookmarkSyncComponents(
       ProfileSyncService* profile_sync_service,
diff --git a/chrome/browser/sync/profile_sync_components_factory_impl.cc b/chrome/browser/sync/profile_sync_components_factory_impl.cc
index 8b255f7..4ba88f4 100644
--- a/chrome/browser/sync/profile_sync_components_factory_impl.cc
+++ b/chrome/browser/sync/profile_sync_components_factory_impl.cc
@@ -108,7 +108,6 @@
 using browser_sync::DataTypeManagerObserver;
 using browser_sync::ExtensionDataTypeController;
 using browser_sync::ExtensionSettingDataTypeController;
-using browser_sync::GenericChangeProcessor;
 using browser_sync::PasswordDataTypeController;
 using browser_sync::ProxyDataTypeController;
 using browser_sync::SearchEngineDataTypeController;
@@ -438,31 +437,6 @@
   return new browser_sync::SyncBackendHostImpl(name, profile, sync_prefs);
 }
 
-browser_sync::GenericChangeProcessor*
-    ProfileSyncComponentsFactoryImpl::CreateGenericChangeProcessor(
-        ProfileSyncService* profile_sync_service,
-        browser_sync::DataTypeErrorHandler* error_handler,
-        const base::WeakPtr<syncer::SyncableService>& local_service,
-        const base::WeakPtr<syncer::SyncMergeResult>& merge_result) {
-  syncer::UserShare* user_share = profile_sync_service->GetUserShare();
-
-  scoped_ptr<syncer::AttachmentService> attachment_service(
-      // TODO(tim): Bug 339726. Remove merge_result->model_type hack! This
-      // method (CreateGenericChangeProcessor) will cease to exist in favor
-      // of a new SharedChangeProcessor::Connect, at which point we'll know
-      // the data type.
-      // TODO(maniscalco): Replace FakeAttachmentService with a real
-      // AttachmentService implementation once implemented (bug 356359).
-      new syncer::FakeAttachmentService(
-          CreateCustomAttachmentStoreForType(merge_result->model_type())));
-  return new GenericChangeProcessor(
-      error_handler,
-      local_service,
-      merge_result,
-      user_share,
-      attachment_service.Pass());
-}
-
 base::WeakPtr<syncer::SyncableService> ProfileSyncComponentsFactoryImpl::
     GetSyncableServiceForType(syncer::ModelType type) {
   if (!profile_) {  // For tests.
diff --git a/chrome/browser/sync/profile_sync_components_factory_impl.h b/chrome/browser/sync/profile_sync_components_factory_impl.h
index ccd1924..69f5625 100644
--- a/chrome/browser/sync/profile_sync_components_factory_impl.h
+++ b/chrome/browser/sync/profile_sync_components_factory_impl.h
@@ -45,12 +45,6 @@
       Profile* profile,
       const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs) OVERRIDE;
 
-  virtual browser_sync::GenericChangeProcessor* CreateGenericChangeProcessor(
-      ProfileSyncService* profile_sync_service,
-      browser_sync::DataTypeErrorHandler* error_handler,
-      const base::WeakPtr<syncer::SyncableService>& local_service,
-      const base::WeakPtr<syncer::SyncMergeResult>& merge_result) OVERRIDE;
-
   virtual base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
       syncer::ModelType type) OVERRIDE;
   virtual scoped_ptr<syncer::AttachmentStore>
diff --git a/chrome/browser/sync/profile_sync_components_factory_mock.cc b/chrome/browser/sync/profile_sync_components_factory_mock.cc
index 9ff2672..eaf5aea 100644
--- a/chrome/browser/sync/profile_sync_components_factory_mock.cc
+++ b/chrome/browser/sync/profile_sync_components_factory_mock.cc
@@ -5,6 +5,8 @@
 #include "chrome/browser/sync/profile_sync_components_factory_mock.h"
 #include "components/sync_driver/change_processor.h"
 #include "components/sync_driver/model_associator.h"
+#include "content/public/browser/browser_thread.h"
+#include "sync/api/attachments/fake_attachment_store.h"
 
 using browser_sync::AssociatorInterface;
 using browser_sync::ChangeProcessor;
@@ -29,7 +31,11 @@
 scoped_ptr<syncer::AttachmentStore>
     ProfileSyncComponentsFactoryMock::CreateCustomAttachmentStoreForType(
         syncer::ModelType type) {
-  return make_scoped_ptr(CreateCustomAttachmentStoreForTypeMock(type));
+  scoped_ptr<syncer::AttachmentStore> store(
+      new syncer::FakeAttachmentStore(
+          content::BrowserThread::GetMessageLoopProxyForThread(
+              content::BrowserThread::IO)));
+  return store.Pass();
 }
 
 ProfileSyncComponentsFactory::SyncComponents
diff --git a/chrome/browser/sync/profile_sync_components_factory_mock.h b/chrome/browser/sync/profile_sync_components_factory_mock.h
index dbda769..41acd9d 100644
--- a/chrome/browser/sync/profile_sync_components_factory_mock.h
+++ b/chrome/browser/sync/profile_sync_components_factory_mock.h
@@ -42,16 +42,8 @@
                    const std::string& name,
                    Profile* profile,
                    const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs));
-  MOCK_METHOD4(CreateGenericChangeProcessor,
-      browser_sync::GenericChangeProcessor*(
-          ProfileSyncService* profile_sync_service,
-          browser_sync::DataTypeErrorHandler* error_handler,
-          const base::WeakPtr<syncer::SyncableService>& local_service,
-          const base::WeakPtr<syncer::SyncMergeResult>& merge_result));
   MOCK_METHOD1(GetSyncableServiceForType,
                base::WeakPtr<syncer::SyncableService>(syncer::ModelType));
-  MOCK_METHOD1(CreateCustomAttachmentStoreForTypeMock,
-               syncer::AttachmentStore*(syncer::ModelType));
   virtual scoped_ptr<syncer::AttachmentStore>
       CreateCustomAttachmentStoreForType(syncer::ModelType type) OVERRIDE;
   MOCK_METHOD2(CreateBookmarkSyncComponents,
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index 7df9aa7..5fd1b8d 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -77,6 +77,7 @@
 #include "sync/internal_api/public/configure_reason.h"
 #include "sync/internal_api/public/http_bridge_network_resources.h"
 #include "sync/internal_api/public/network_resources.h"
+#include "sync/internal_api/public/sessions/type_debug_info_observer.h"
 #include "sync/internal_api/public/sync_core_proxy.h"
 #include "sync/internal_api/public/sync_encryption_handler.h"
 #include "sync/internal_api/public/util/experiments.h"
@@ -554,6 +555,30 @@
                     OnProtocolEvent(event));
 }
 
+void ProfileSyncService::OnDirectoryTypeCommitCounterUpdated(
+    syncer::ModelType type,
+    const syncer::CommitCounters& counters) {
+  FOR_EACH_OBSERVER(syncer::TypeDebugInfoObserver,
+                    type_debug_info_observers_,
+                    OnCommitCountersUpdated(type, counters));
+}
+
+void ProfileSyncService::OnDirectoryTypeUpdateCounterUpdated(
+    syncer::ModelType type,
+    const syncer::UpdateCounters& counters) {
+  FOR_EACH_OBSERVER(syncer::TypeDebugInfoObserver,
+                    type_debug_info_observers_,
+                    OnUpdateCountersUpdated(type, counters));
+}
+
+void ProfileSyncService::OnDirectoryTypeStatusCounterUpdated(
+    syncer::ModelType type,
+    const syncer::StatusCounters& counters) {
+  FOR_EACH_OBSERVER(syncer::TypeDebugInfoObserver,
+                    type_debug_info_observers_,
+                    OnStatusCountersUpdated(type, counters));
+}
+
 void ProfileSyncService::OnDataTypeRequestsSyncStartup(
     syncer::ModelType type) {
   DCHECK(syncer::UserTypes().Has(type));
@@ -935,6 +960,10 @@
   non_blocking_data_type_manager_.ConnectSyncBackend(
       backend_->GetSyncCoreProxy());
 
+  if (type_debug_info_observers_.might_have_observers()) {
+    backend_->EnableDirectoryTypeDebugInfoForwarding();
+  }
+
   // If we have a cached passphrase use it to decrypt/encrypt data now that the
   // backend is initialized. We want to call this before notifying observers in
   // case this operation affects the "passphrase required" status.
@@ -1909,17 +1938,6 @@
   return result.release();
 }
 
-void ProfileSyncService::ActivateDataType(
-    syncer::ModelType type, syncer::ModelSafeGroup group,
-    ChangeProcessor* change_processor) {
-  if (!backend_) {
-    NOTREACHED();
-    return;
-  }
-  DCHECK(backend_initialized_);
-  backend_->ActivateDataType(type, group, change_processor);
-}
-
 void ProfileSyncService::DeactivateDataType(syncer::ModelType type) {
   if (!backend_)
     return;
@@ -2106,6 +2124,22 @@
   }
 }
 
+void ProfileSyncService::AddTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* type_debug_info_observer) {
+  type_debug_info_observers_.AddObserver(type_debug_info_observer);
+  if (type_debug_info_observers_.might_have_observers() && backend_) {
+    backend_->EnableDirectoryTypeDebugInfoForwarding();
+  }
+}
+
+void ProfileSyncService::RemoveTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* type_debug_info_observer) {
+  type_debug_info_observers_.RemoveObserver(type_debug_info_observer);
+  if (!type_debug_info_observers_.might_have_observers() && backend_) {
+    backend_->DisableDirectoryTypeDebugInfoForwarding();
+  }
+}
+
 namespace {
 
 class GetAllNodesRequestHelper
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index 78b510d..46b019b 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -72,7 +72,10 @@
 namespace syncer {
 class BaseTransaction;
 class NetworkResources;
+struct CommitCounters;
+struct StatusCounters;
 struct SyncCredentials;
+struct UpdateCounters;
 struct UserShare;
 }  // namespace syncer
 
@@ -276,6 +279,9 @@
   void RemoveProtocolEventObserver(
       browser_sync::ProtocolEventObserver* observer);
 
+  void AddTypeDebugInfoObserver(syncer::TypeDebugInfoObserver* observer);
+  void RemoveTypeDebugInfoObserver(syncer::TypeDebugInfoObserver* observer);
+
   // Asynchronously fetches base::Value representations of all sync nodes and
   // returns them to the specified callback on this thread.
   //
@@ -385,6 +391,15 @@
       bool success) OVERRIDE;
   virtual void OnSyncCycleCompleted() OVERRIDE;
   virtual void OnProtocolEvent(const syncer::ProtocolEvent& event) OVERRIDE;
+  virtual void OnDirectoryTypeCommitCounterUpdated(
+      syncer::ModelType type,
+      const syncer::CommitCounters& counters) OVERRIDE;
+  virtual void OnDirectoryTypeUpdateCounterUpdated(
+      syncer::ModelType type,
+      const syncer::UpdateCounters& counters) OVERRIDE;
+  virtual void OnDirectoryTypeStatusCounterUpdated(
+      syncer::ModelType type,
+      const syncer::StatusCounters& counters) OVERRIDE;
   virtual void OnSyncConfigureRetry() OVERRIDE;
   virtual void OnConnectionStatusChange(
       syncer::ConnectionStatus status) OVERRIDE;
@@ -575,9 +590,6 @@
 
   // Overridden by tests.
   // TODO(zea): Remove these and have the dtc's call directly into the SBH.
-  virtual void ActivateDataType(
-      syncer::ModelType type, syncer::ModelSafeGroup group,
-      browser_sync::ChangeProcessor* change_processor);
   virtual void DeactivateDataType(syncer::ModelType type);
 
   // SyncPrefObserver implementation.
@@ -950,6 +962,7 @@
 
   ObserverList<ProfileSyncServiceBase::Observer> observers_;
   ObserverList<browser_sync::ProtocolEventObserver> protocol_event_observers_;
+  ObserverList<syncer::TypeDebugInfoObserver> type_debug_info_observers_;
 
   syncer::SyncJsController sync_js_controller_;
 
diff --git a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
index 346daa9..f57d693 100644
--- a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
@@ -49,7 +49,6 @@
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "components/sync_driver/data_type_controller.h"
-#include "components/sync_driver/generic_change_processor.h"
 #include "components/webdata/common/web_data_service_test_util.h"
 #include "components/webdata/common/web_database.h"
 #include "content/public/test/test_browser_thread.h"
@@ -84,7 +83,6 @@
 using browser_sync::AutofillDataTypeController;
 using browser_sync::AutofillProfileDataTypeController;
 using browser_sync::DataTypeController;
-using browser_sync::GenericChangeProcessor;
 using content::BrowserThread;
 using syncer::AUTOFILL;
 using syncer::BaseNode;
@@ -367,16 +365,6 @@
       arg5);
 }
 
-ACTION(MakeGenericChangeProcessor) {
-  syncer::UserShare* user_share = arg0->GetUserShare();
-  return new GenericChangeProcessor(
-      arg1,
-      arg2,
-      arg3,
-      user_share,
-      syncer::FakeAttachmentService::CreateForTest());
-}
-
 ACTION_P(MakeAutofillProfileSyncComponents, wds) {
   EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
   if (!BrowserThread::CurrentlyOn(BrowserThread::DB))
@@ -410,8 +398,6 @@
                               ProfileSyncService* service,
                               AutofillWebDataService* wds,
                               DataTypeController* dtc) OVERRIDE {
-    EXPECT_CALL(*factory, CreateGenericChangeProcessor(_,_,_,_)).
-        WillOnce(MakeGenericChangeProcessor());
     EXPECT_CALL(*factory, GetSyncableServiceForType(syncer::AUTOFILL)).
         WillOnce(MakeAutocompleteSyncComponents(wds));
   }
@@ -430,8 +416,6 @@
                               ProfileSyncService* service,
                               AutofillWebDataService* wds,
                               DataTypeController* dtc) OVERRIDE {
-    EXPECT_CALL(*factory, CreateGenericChangeProcessor(_,_,_,_)).
-        WillOnce(MakeGenericChangeProcessor());
     EXPECT_CALL(*factory,
         GetSyncableServiceForType(syncer::AUTOFILL_PROFILE)).
         WillOnce(MakeAutofillProfileSyncComponents(wds));
diff --git a/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc b/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc
index 6d9145c..44a493f 100644
--- a/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc
@@ -23,13 +23,13 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/sync/glue/bookmark_change_processor.h"
 #include "chrome/browser/sync/glue/bookmark_model_associator.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/base_bookmark_model_observer.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "components/sync_driver/data_type_error_handler.h"
 #include "components/sync_driver/data_type_error_handler_mock.h"
 #include "content/public/test/test_browser_thread.h"
diff --git a/chrome/browser/sync/profile_sync_service_mock.h b/chrome/browser/sync/profile_sync_service_mock.h
index b3e1a33..b6d8ae8 100644
--- a/chrome/browser/sync/profile_sync_service_mock.h
+++ b/chrome/browser/sync/profile_sync_service_mock.h
@@ -61,9 +61,6 @@
                const tracked_objects::Location&,
                std::string message));
   MOCK_CONST_METHOD0(GetUserShare, syncer::UserShare*());
-  MOCK_METHOD3(ActivateDataType,
-               void(syncer::ModelType, syncer::ModelSafeGroup,
-                    browser_sync::ChangeProcessor*));
   MOCK_METHOD1(DeactivateDataType, void(syncer::ModelType));
   MOCK_METHOD0(UnsuppressAndStart, void());
 
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.cc b/chrome/browser/sync/test/integration/bookmarks_helper.cc
index 11e4dd7..b90cc66 100644
--- a/chrome/browser/sync/test/integration/bookmarks_helper.cc
+++ b/chrome/browser/sync/test/integration/bookmarks_helper.cc
@@ -91,11 +91,15 @@
   virtual void BookmarkNodeAdded(BookmarkModel* model,
                                  const BookmarkNode* parent,
                                  int index) OVERRIDE {}
-  virtual void BookmarkNodeRemoved(BookmarkModel* model,
-                                   const BookmarkNode* parent,
-                                   int old_index,
-                                   const BookmarkNode* node) OVERRIDE {}
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE {}
+  virtual void BookmarkNodeRemoved(
+      BookmarkModel* model,
+      const BookmarkNode* parent,
+      int old_index,
+      const BookmarkNode* node,
+      const std::set<GURL>& removed_urls) OVERRIDE {}
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE {}
 
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE {
diff --git a/chrome/browser/sync/test/integration/fake_server_invalidation_service.cc b/chrome/browser/sync/test/integration/fake_server_invalidation_service.cc
new file mode 100644
index 0000000..c862519
--- /dev/null
+++ b/chrome/browser/sync/test/integration/fake_server_invalidation_service.cc
@@ -0,0 +1,87 @@
+// 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.
+
+#include "chrome/browser/sync/test/integration/fake_server_invalidation_service.h"
+
+#include <string>
+
+#include "base/macros.h"
+#include "chrome/browser/invalidation/invalidation_service_util.h"
+#include "sync/internal_api/public/base/invalidation.h"
+#include "sync/internal_api/public/base/model_type.h"
+#include "sync/notifier/object_id_invalidation_map.h"
+#
+
+namespace fake_server {
+
+FakeServerInvalidationService::FakeServerInvalidationService()
+    : client_id_(invalidation::GenerateInvalidatorClientId()),
+      identity_provider_(&token_service_) {
+  invalidator_registrar_.UpdateInvalidatorState(syncer::INVALIDATIONS_ENABLED);
+}
+
+FakeServerInvalidationService::~FakeServerInvalidationService() {
+}
+
+// static
+KeyedService* FakeServerInvalidationService::Build(
+    content::BrowserContext* context) {
+  return new FakeServerInvalidationService();
+}
+
+void FakeServerInvalidationService::RegisterInvalidationHandler(
+      syncer::InvalidationHandler* handler) {
+  invalidator_registrar_.RegisterHandler(handler);
+}
+
+void FakeServerInvalidationService::UpdateRegisteredInvalidationIds(
+      syncer::InvalidationHandler* handler,
+      const syncer::ObjectIdSet& ids) {
+  invalidator_registrar_.UpdateRegisteredIds(handler, ids);
+}
+
+void FakeServerInvalidationService::UnregisterInvalidationHandler(
+      syncer::InvalidationHandler* handler) {
+  invalidator_registrar_.UnregisterHandler(handler);
+}
+
+syncer::InvalidatorState FakeServerInvalidationService::GetInvalidatorState()
+    const {
+  return invalidator_registrar_.GetInvalidatorState();
+}
+
+std::string FakeServerInvalidationService::GetInvalidatorClientId() const {
+  return client_id_;
+}
+
+invalidation::InvalidationLogger*
+FakeServerInvalidationService::GetInvalidationLogger() {
+  return NULL;
+}
+
+void FakeServerInvalidationService::RequestDetailedStatus(
+    base::Callback<void(const base::DictionaryValue&)> caller) const {
+  base::DictionaryValue value;
+  caller.Run(value);
+}
+
+IdentityProvider* FakeServerInvalidationService::GetIdentityProvider() {
+  return &identity_provider_;
+}
+
+void FakeServerInvalidationService::OnCommit(
+    syncer::ModelTypeSet committed_model_types) {
+  syncer::ObjectIdSet object_ids = syncer::ModelTypeSetToObjectIdSet(
+      committed_model_types);
+  syncer::ObjectIdInvalidationMap invalidation_map;
+  for (syncer::ObjectIdSet::const_iterator it = object_ids.begin();
+       it != object_ids.end(); ++it) {
+    // TODO(pvalenzuela): Create more refined invalidations instead of
+    // invalidating all items of a given type.
+    invalidation_map.Insert(syncer::Invalidation::InitUnknownVersion(*it));
+  }
+  invalidator_registrar_.DispatchInvalidationsToHandlers(invalidation_map);
+}
+
+}  // namespace fake_server
diff --git a/chrome/browser/sync/test/integration/fake_server_invalidation_service.h b/chrome/browser/sync/test/integration/fake_server_invalidation_service.h
new file mode 100644
index 0000000..6b57503
--- /dev/null
+++ b/chrome/browser/sync/test/integration/fake_server_invalidation_service.h
@@ -0,0 +1,67 @@
+// 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.
+
+#ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_FAKE_SERVER_INVALIDATION_SERVICE_H_
+#define CHROME_BROWSER_SYNC_TEST_INTEGRATION_FAKE_SERVER_INVALIDATION_SERVICE_H_
+
+#include <string>
+#include <utility>
+
+#include "base/basictypes.h"
+#include "chrome/browser/invalidation/invalidation_service.h"
+#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
+#include "google_apis/gaia/fake_identity_provider.h"
+#include "sync/internal_api/public/base/model_type.h"
+#include "sync/notifier/invalidator_registrar.h"
+#include "sync/test/fake_server/fake_server.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace invalidation {
+class InvalidationLogger;
+}
+
+namespace fake_server {
+
+// An InvalidationService that is used in conjunction with FakeServer.
+class FakeServerInvalidationService : public invalidation::InvalidationService,
+                                      public FakeServer::Observer {
+ public:
+  FakeServerInvalidationService();
+  virtual ~FakeServerInvalidationService();
+
+  static KeyedService* Build(content::BrowserContext* context);
+
+  virtual void RegisterInvalidationHandler(
+      syncer::InvalidationHandler* handler) OVERRIDE;
+  virtual void UpdateRegisteredInvalidationIds(
+      syncer::InvalidationHandler* handler,
+      const syncer::ObjectIdSet& ids) OVERRIDE;
+  virtual void UnregisterInvalidationHandler(
+      syncer::InvalidationHandler* handler) OVERRIDE;
+
+  virtual syncer::InvalidatorState GetInvalidatorState() const OVERRIDE;
+  virtual std::string GetInvalidatorClientId() const OVERRIDE;
+  virtual invalidation::InvalidationLogger* GetInvalidationLogger() OVERRIDE;
+  virtual void RequestDetailedStatus(
+      base::Callback<void(const base::DictionaryValue&)> caller) const OVERRIDE;
+  virtual IdentityProvider* GetIdentityProvider() OVERRIDE;
+
+  // FakeServer::Observer:
+  virtual void OnCommit(syncer::ModelTypeSet committed_model_types) OVERRIDE;
+
+ private:
+  std::string client_id_;
+  syncer::InvalidatorRegistrar invalidator_registrar_;
+  FakeProfileOAuth2TokenService token_service_;
+  FakeIdentityProvider identity_provider_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeServerInvalidationService);
+};
+
+}  // namespace fake_server
+
+#endif  // CHROME_BROWSER_SYNC_TEST_INTEGRATION_FAKE_SERVER_INVALIDATION_SERVICE_H_
diff --git a/chrome/browser/sync/test/integration/multiple_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/multiple_client_passwords_sync_test.cc
index c1c5f6f..cce2033 100644
--- a/chrome/browser/sync/test/integration/multiple_client_passwords_sync_test.cc
+++ b/chrome/browser/sync/test/integration/multiple_client_passwords_sync_test.cc
@@ -5,17 +5,31 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/sync/test/integration/passwords_helper.h"
+#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
+#include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "components/password_manager/core/browser/password_form_data.h"
 
 using passwords_helper::AddLogin;
+using passwords_helper::AllProfilesContainSamePasswordFormsAsVerifier;
 using passwords_helper::AwaitAllProfilesContainSamePasswordForms;
+using passwords_helper::AwaitProfileContainsSamePasswordFormsAsVerifier;
 using passwords_helper::CreateTestPasswordForm;
 using passwords_helper::GetPasswordCount;
 using passwords_helper::GetPasswordStore;
+using passwords_helper::GetVerifierPasswordCount;
+using passwords_helper::GetVerifierPasswordStore;
+using passwords_helper::ProfileContainsSamePasswordFormsAsVerifier;
+using passwords_helper::SetDecryptionPassphrase;
+using passwords_helper::SetEncryptionPassphrase;
+using sync_integration_test_util::AwaitPassphraseAccepted;
+using sync_integration_test_util::AwaitPassphraseRequired;
 
 using autofill::PasswordForm;
 
+static const char* kValidPassphrase = "passphrase!";
+static const char* kAnotherValidPassphrase = "Mot de passe!";
+
 class MultipleClientPasswordsSyncTest : public SyncTest {
  public:
   MultipleClientPasswordsSyncTest() : SyncTest(MULTIPLE_CLIENT) {}
@@ -40,3 +54,90 @@
   ASSERT_TRUE(AwaitAllProfilesContainSamePasswordForms());
   ASSERT_EQ(num_clients(), GetPasswordCount(0));
 }
+
+IN_PROC_BROWSER_TEST_F(MultipleClientPasswordsSyncTest,
+                       SetPassphraseAndThenSetupSync) {
+  ASSERT_TRUE(SetupClients());
+
+  ASSERT_TRUE(GetClient(0)->SetupSync());
+  SetEncryptionPassphrase(0, kValidPassphrase, ProfileSyncService::EXPLICIT);
+  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService(0)));
+
+  // When client 1 hits a passphrase required state, we can infer that
+  // client 0's passphrase has been committed. to the server.
+  GetClient(1)->SetupSync();
+  ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService(1)));
+
+  // Setup client 2 *after* the passphrase has been committed.
+  ASSERT_FALSE(GetClient(2)->SetupSync());
+  ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService(2)));
+
+  // Get clients 1 and 2 out of the passphrase required state.
+  ASSERT_TRUE(SetDecryptionPassphrase(1, kValidPassphrase));
+  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService(1)));
+  ASSERT_TRUE(SetDecryptionPassphrase(2, kValidPassphrase));
+  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService(2)));
+
+  // For some reason, the tests won't pass unless these flags are set.
+  GetSyncService(1)->SetSyncSetupCompleted();
+  GetSyncService(1)->SetSetupInProgress(false);
+  GetSyncService(2)->SetSyncSetupCompleted();
+  GetSyncService(2)->SetSetupInProgress(false);
+
+  // Move around some passwords to make sure it's all working.
+  PasswordForm form0 = CreateTestPasswordForm(0);
+  AddLogin(GetPasswordStore(0), form0);
+
+  ASSERT_TRUE(AwaitAllProfilesContainSamePasswordForms());
+}
+
+IN_PROC_BROWSER_TEST_F(MultipleClientPasswordsSyncTest,
+                       SetDifferentPassphraseAndThenSetupSync) {
+  ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
+
+  ASSERT_TRUE(GetClient(0)->SetupSync());
+  SetEncryptionPassphrase(0, kValidPassphrase, ProfileSyncService::EXPLICIT);
+  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService((0))));
+
+  // When client 1 hits a passphrase required state, we can infer that
+  // client 0's passphrase has been committed. to the server.
+  GetClient(1)->SetupSync();
+  ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService(1)));
+
+  // Give client 1 the correct passphrase.
+  SetDecryptionPassphrase(1, kValidPassphrase);
+  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService((1))));
+
+  // For some reason, the tests won't pass unless these flags are set.
+  GetSyncService(1)->SetSetupInProgress(false);
+  GetSyncService(1)->SetSyncSetupCompleted();
+
+  // Give client 2 a different passphrase so it fails to sync.
+  ASSERT_FALSE(GetClient(2)->SetupSync());
+  ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService((2))));
+  SetDecryptionPassphrase(2, kAnotherValidPassphrase);
+  ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService((2))));
+
+  // Add a password on 0 while client 2 has different passphrases.
+  PasswordForm form0 = CreateTestPasswordForm(0);
+  AddLogin(GetVerifierPasswordStore(), form0);
+  AddLogin(GetPasswordStore(0), form0);
+
+  // It should sync to client 1.
+  ASSERT_TRUE(AwaitProfileContainsSamePasswordFormsAsVerifier(1));
+
+  // But it won't get synced to 2.
+  ASSERT_FALSE(ProfileContainsSamePasswordFormsAsVerifier(2));
+
+  // Update 2 with the correct passphrase, the password should now sync over.
+  ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService(2)));
+  ASSERT_TRUE(SetDecryptionPassphrase(2, kValidPassphrase));
+  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService(2)));
+
+  // For some reason, the tests won't pass unless these flags are set.
+  GetSyncService(2)->SetSetupInProgress(false);
+  GetSyncService(2)->SetSyncSetupCompleted();
+
+  ASSERT_TRUE(AwaitProfileContainsSamePasswordFormsAsVerifier(2));
+  ASSERT_TRUE(AllProfilesContainSamePasswordFormsAsVerifier());
+}
diff --git a/chrome/browser/sync/test/integration/passwords_helper.cc b/chrome/browser/sync/test/integration/passwords_helper.cc
index 7fd71e1..6a3fb0f 100644
--- a/chrome/browser/sync/test/integration/passwords_helper.cc
+++ b/chrome/browser/sync/test/integration/passwords_helper.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
+#include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/password_manager/core/browser/password_form_data.h"
@@ -177,8 +178,8 @@
 bool AllProfilesContainSamePasswordFormsAsVerifier() {
   for (int i = 0; i < test()->num_clients(); ++i) {
     if (!ProfileContainsSamePasswordFormsAsVerifier(i)) {
-      LOG(ERROR) << "Profile " << i << " does not contain the same password"
-                                       " forms as the verifier.";
+      DVLOG(1) << "Profile " << i << " does not contain the same password"
+                                     " forms as the verifier.";
       return false;
     }
   }
@@ -188,8 +189,8 @@
 bool AllProfilesContainSamePasswordForms() {
   for (int i = 1; i < test()->num_clients(); ++i) {
     if (!ProfilesContainSamePasswordForms(0, i)) {
-      LOG(ERROR) << "Profile " << i << " does not contain the same password"
-                                       " forms as Profile 0.";
+      DVLOG(1) << "Profile " << i << " does not contain the same password"
+                                     " forms as Profile 0.";
       return false;
     }
   }
@@ -265,6 +266,69 @@
   return !checker.TimedOut();
 }
 
+namespace {
+
+// Helper class used in the implementation of
+// AwaitProfileContainSamePasswordFormsAsVerifier.
+class SamePasswordFormsAsVerifierChecker
+    : public SingleClientStatusChangeChecker {
+ public:
+  explicit SamePasswordFormsAsVerifierChecker(int index);
+  virtual ~SamePasswordFormsAsVerifierChecker();
+
+  virtual bool IsExitConditionSatisfied() OVERRIDE;
+  virtual std::string GetDebugMessage() const OVERRIDE;
+
+ private:
+  int index_;
+
+  bool in_progress_;
+  bool needs_recheck_;
+};
+
+SamePasswordFormsAsVerifierChecker::SamePasswordFormsAsVerifierChecker(int i)
+    : SingleClientStatusChangeChecker(
+          sync_datatype_helper::test()->GetSyncService(i)),
+      index_(i),
+      in_progress_(false),
+      needs_recheck_(false) {
+}
+
+SamePasswordFormsAsVerifierChecker::~SamePasswordFormsAsVerifierChecker() {
+}
+
+// This method uses the same re-entrancy prevention trick as
+// the SamePasswordFormsChecker.
+bool SamePasswordFormsAsVerifierChecker::IsExitConditionSatisfied() {
+  if (in_progress_) {
+    LOG(WARNING) << "Setting flag and returning early to prevent nesting.";
+    needs_recheck_ = true;
+    return false;
+  }
+
+  // Keep retrying until we get a good reading.
+  bool result = false;
+  in_progress_ = true;
+  do {
+    needs_recheck_ = false;
+    result = ProfileContainsSamePasswordFormsAsVerifier(index_);
+  } while (needs_recheck_);
+  in_progress_ = false;
+  return result;
+}
+
+std::string SamePasswordFormsAsVerifierChecker::GetDebugMessage() const {
+  return "Waiting for passwords to match verifier";
+}
+
+}  //  namespace
+
+bool AwaitProfileContainsSamePasswordFormsAsVerifier(int index) {
+  SamePasswordFormsAsVerifierChecker checker(index);
+  checker.Wait();
+  return !checker.TimedOut();
+}
+
 int GetPasswordCount(int index) {
   std::vector<PasswordForm> forms;
   GetLogins(GetPasswordStore(index), forms);
diff --git a/chrome/browser/sync/test/integration/passwords_helper.h b/chrome/browser/sync/test/integration/passwords_helper.h
index b21fd53..2ce1f7d 100644
--- a/chrome/browser/sync/test/integration/passwords_helper.h
+++ b/chrome/browser/sync/test/integration/passwords_helper.h
@@ -79,6 +79,10 @@
 // it doesn't time out.
 bool AwaitAllProfilesContainSamePasswordForms();
 
+// Returns true if specified profile contains the same password forms as the
+// verifier and it doesn't time out.
+bool AwaitProfileContainsSamePasswordFormsAsVerifier(int index);
+
 // Returns the number of forms in the password store of the profile with index
 // |index|.
 int GetPasswordCount(int index);
diff --git a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
index 6fcf09e..ea1111a 100644
--- a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
@@ -10,11 +10,14 @@
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
 #include "components/bookmarks/core/browser/bookmark_service.h"
+#include "sync/test/fake_server/bookmark_entity_builder.h"
+#include "sync/test/fake_server/entity_builder_factory.h"
 #include "sync/test/fake_server/fake_server_verifier.h"
 #include "ui/base/layout.h"
 
 using bookmarks_helper::AddFolder;
 using bookmarks_helper::AddURL;
+using bookmarks_helper::CountBookmarksWithTitlesMatching;
 using bookmarks_helper::Create1xFaviconFromPNGFile;
 using bookmarks_helper::GetBookmarkBarNode;
 using bookmarks_helper::GetBookmarkModel;
@@ -183,6 +186,21 @@
     VerifyBookmarkModelMatchesFakeServer(0);
 }
 
+IN_PROC_BROWSER_TEST_F(SingleClientBookmarksSyncTest, InjectedBookmark) {
+  std::string title = "Montreal Canadiens";
+  fake_server::EntityBuilderFactory entity_builder_factory;
+  scoped_ptr<fake_server::FakeServerEntity> entity =
+      entity_builder_factory.NewBookmarkEntityBuilder(
+          title, GURL("http://canadiens.nhl.com")).Build();
+  fake_server_->InjectEntity(entity.Pass());
+
+  DisableVerifier();
+  ASSERT_TRUE(SetupClients());
+  ASSERT_TRUE(SetupSync());
+
+  ASSERT_EQ(1, CountBookmarksWithTitlesMatching(0, base::UTF8ToWide(title)));
+}
+
 // Test that a client doesn't mutate the favicon data in the process
 // of storing the favicon data from sync to the database or in the process
 // of requesting data from the database for sync.
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index 3c8b63a..91adcf6 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -21,7 +21,6 @@
 #include "base/threading/platform_thread.h"
 #include "base/values.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/google/google_url_tracker.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/invalidation/invalidation_service_factory.h"
@@ -36,6 +35,7 @@
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/sync/profile_sync_service.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/test/integration/fake_server_invalidation_service.h"
 #include "chrome/browser/sync/test/integration/p2p_invalidation_forwarder.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
@@ -50,6 +50,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "components/os_crypt/os_crypt.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "content/public/browser/web_contents.h"
@@ -234,6 +235,8 @@
 
   // Stop the local sync test server. This is a no-op if one wasn't started.
   TearDownLocalTestServer();
+
+  fake_server_.reset();
 }
 
 void SyncTest::SetUpCommandLine(base::CommandLine* cl) {
@@ -326,6 +329,7 @@
   browsers_.resize(num_clients_);
   clients_.resize(num_clients_);
   invalidation_forwarders_.resize(num_clients_);
+  fake_server_invalidation_services_.resize(num_clients_);
   for (int i = 0; i < num_clients_; ++i) {
     InitializeInstance(i);
   }
@@ -352,14 +356,6 @@
   EXPECT_FALSE(GetBrowser(index) == NULL) << "Could not create Browser "
                                           << index << ".";
 
-  invalidation::P2PInvalidationService* p2p_invalidation_service =
-      static_cast<invalidation::P2PInvalidationService*>(
-          InvalidationServiceFactory::GetInstance()->SetTestingFactoryAndUse(
-              GetProfile(index),
-              TestUsesSelfNotifications() ?
-                  BuildSelfNotifyingP2PInvalidationService
-                  : BuildRealisticP2PInvalidationService));
-  p2p_invalidation_service->UpdateCredentials(username_, password_);
 
   // Make sure the ProfileSyncService has been created before creating the
   // ProfileSyncServiceHarness - some tests expect the ProfileSyncService to
@@ -381,11 +377,7 @@
           password_);
   EXPECT_FALSE(GetClient(index) == NULL) << "Could not create Client "
                                          << index << ".";
-
-  // Start listening for and emitting notificaitons of commits.
-  invalidation_forwarders_[index] =
-      new P2PInvalidationForwarder(clients_[index]->service(),
-                                   p2p_invalidation_service);
+  InitializeInvalidations(index);
 
   test::WaitForBookmarkModelToLoad(
       BookmarkModelFactory::GetForProfile(GetProfile(index)));
@@ -395,6 +387,32 @@
       TemplateURLServiceFactory::GetForProfile(GetProfile(index)));
 }
 
+void SyncTest::InitializeInvalidations(int index) {
+  if (server_type_ == IN_PROCESS_FAKE_SERVER) {
+    CHECK(fake_server_.get());
+    fake_server::FakeServerInvalidationService* invalidation_service =
+        static_cast<fake_server::FakeServerInvalidationService*>(
+            InvalidationServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+                GetProfile(index),
+                fake_server::FakeServerInvalidationService::Build));
+    fake_server_->AddObserver(invalidation_service);
+    fake_server_invalidation_services_[index] = invalidation_service;
+  } else {
+    invalidation::P2PInvalidationService* p2p_invalidation_service =
+        static_cast<invalidation::P2PInvalidationService*>(
+            InvalidationServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+                GetProfile(index),
+                TestUsesSelfNotifications() ?
+                    BuildSelfNotifyingP2PInvalidationService
+                    : BuildRealisticP2PInvalidationService));
+    p2p_invalidation_service->UpdateCredentials(username_, password_);
+    // Start listening for and emitting notifications of commits.
+    invalidation_forwarders_[index] =
+        new P2PInvalidationForwarder(clients_[index]->service(),
+                                     p2p_invalidation_service);
+  }
+}
+
 bool SyncTest::SetupSync() {
   // Create sync profiles and clients if they haven't already been created.
   if (profiles_.empty()) {
@@ -434,10 +452,19 @@
   chrome::CloseAllBrowsers();
   content::RunAllPendingInMessageLoop();
 
+  if (fake_server_.get()) {
+    std::vector<fake_server::FakeServerInvalidationService*>::const_iterator it;
+    for (it = fake_server_invalidation_services_.begin();
+         it != fake_server_invalidation_services_.end(); ++it) {
+      fake_server_->RemoveObserver(*it);
+    }
+  }
+
   // All browsers should be closed at this point, or else we could see memory
   // corruption in QuitBrowser().
   CHECK_EQ(0U, chrome::GetTotalBrowserCount());
   invalidation_forwarders_.clear();
+  fake_server_invalidation_services_.clear();
   clients_.clear();
 }
 
@@ -605,8 +632,6 @@
       LOG(FATAL) << "Failed to set up local test server";
   } else if (server_type_ == IN_PROCESS_FAKE_SERVER) {
     fake_server_.reset(new fake_server::FakeServer());
-    // Similar to LOCAL_LIVE_SERVER, we must start this for XMPP.
-    SetUpLocalPythonTestServer();
     SetupMockGaiaResponses();
   } else if (server_type_ == EXTERNAL_LIVE_SERVER) {
     // Nothing to do; we'll just talk to the URL we were given.
@@ -725,6 +750,10 @@
 }
 
 void SyncTest::EnableNetwork(Profile* profile) {
+  // TODO(pvalenzuela): Remove this restriction when FakeServer's observers
+  // (namely FakeServerInvaldationService) are aware of a network disconnect.
+  ASSERT_NE(IN_PROCESS_FAKE_SERVER, server_type_)
+      << "FakeServer does not support EnableNetwork.";
   SetProxyConfig(profile->GetRequestContext(),
                  net::ProxyConfig::CreateDirect());
   if (notifications_enabled_) {
@@ -735,6 +764,10 @@
 }
 
 void SyncTest::DisableNetwork(Profile* profile) {
+  // TODO(pvalenzuela): Remove this restriction when FakeServer's observers
+  // (namely FakeServerInvaldationService) are aware of a network disconnect.
+  ASSERT_NE(IN_PROCESS_FAKE_SERVER, server_type_)
+      << "FakeServer does not support DisableNetwork.";
   DisableNotificationsImpl();
   // Set the current proxy configuration to a nonexistent proxy to effectively
   // disable networking.
diff --git a/chrome/browser/sync/test/integration/sync_test.h b/chrome/browser/sync/test/integration/sync_test.h
index b9e734d..6c32d83 100644
--- a/chrome/browser/sync/test/integration/sync_test.h
+++ b/chrome/browser/sync/test/integration/sync_test.h
@@ -32,6 +32,7 @@
 
 namespace fake_server {
 class FakeServer;
+class FakeServerInvalidationService;
 }
 
 namespace net {
@@ -363,6 +364,10 @@
   // of test being run and command line args passed in.
   void DecideServerType();
 
+  // Sets up the client-side invalidations infrastructure depending on the
+  // value of |server_type_|.
+  void InitializeInvalidations(int index);
+
   // Python sync test server, started on demand.
   syncer::LocalSyncTestServer sync_server_;
 
@@ -399,6 +404,10 @@
   // of this activity to its peer sync clients.
   ScopedVector<P2PInvalidationForwarder> invalidation_forwarders_;
 
+  // Collection of pointers to FakeServerInvalidation objects for each profile.
+  std::vector<fake_server::FakeServerInvalidationService*>
+      fake_server_invalidation_services_;
+
   // Sync profile against which changes to individual profiles are verified. We
   // don't need a corresponding verifier sync client because the contents of the
   // verifier profile are strictly local, and are not meant to be synced.
diff --git a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc
index ba688ce..2b3e38a 100644
--- a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc
@@ -1616,7 +1616,8 @@
   ASSERT_FALSE(ContainsDuplicateBookmarks(0));
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientBookmarksSyncTest, MC_DeleteBookmark) {
+// This test fails when run with FakeServer and FakeServerInvalidationService.
+IN_PROC_BROWSER_TEST_F(LegacyTwoClientBookmarksSyncTest, MC_DeleteBookmark) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
   ASSERT_TRUE(GetClient(1)->DisableSyncForDatatype(syncer::BOOKMARKS));
 
diff --git a/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc
index ed23199..53771a9 100644
--- a/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc
@@ -13,31 +13,32 @@
 using passwords_helper::AddLogin;
 using passwords_helper::AllProfilesContainSamePasswordForms;
 using passwords_helper::AllProfilesContainSamePasswordFormsAsVerifier;
+using passwords_helper::AwaitAllProfilesContainSamePasswordForms;
+using passwords_helper::AwaitProfileContainsSamePasswordFormsAsVerifier;
 using passwords_helper::CreateTestPasswordForm;
 using passwords_helper::GetPasswordCount;
 using passwords_helper::GetPasswordStore;
 using passwords_helper::GetVerifierPasswordCount;
 using passwords_helper::GetVerifierPasswordStore;
-using passwords_helper::ProfileContainsSamePasswordFormsAsVerifier;
 using passwords_helper::RemoveLogin;
 using passwords_helper::RemoveLogins;
 using passwords_helper::SetDecryptionPassphrase;
 using passwords_helper::SetEncryptionPassphrase;
 using passwords_helper::UpdateLogin;
-using sync_integration_test_util::AwaitCommitActivityCompletion;
 using sync_integration_test_util::AwaitPassphraseAccepted;
 using sync_integration_test_util::AwaitPassphraseRequired;
 
 using autofill::PasswordForm;
 
 static const char* kValidPassphrase = "passphrase!";
-static const char* kAnotherValidPassphrase = "another passphrase!";
 
 class TwoClientPasswordsSyncTest : public SyncTest {
  public:
   TwoClientPasswordsSyncTest() : SyncTest(TWO_CLIENT) {}
   virtual ~TwoClientPasswordsSyncTest() {}
 
+  virtual bool TestUsesSelfNotifications() OVERRIDE { return false; }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(TwoClientPasswordsSyncTest);
 };
@@ -62,8 +63,7 @@
   AddLogin(GetPasswordStore(0), form);
   ASSERT_EQ(1, GetPasswordCount(0));
 
-  ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
-  ASSERT_TRUE(AllProfilesContainSamePasswordFormsAsVerifier());
+  ASSERT_TRUE(AwaitAllProfilesContainSamePasswordForms());
 }
 
 IN_PROC_BROWSER_TEST_F(TwoClientPasswordsSyncTest, Race) {
@@ -77,65 +77,7 @@
   form1.password_value = base::ASCIIToUTF16("new_password");
   AddLogin(GetPasswordStore(1), form1);
 
-  ASSERT_TRUE(AwaitQuiescence());
-  ASSERT_TRUE(AllProfilesContainSamePasswordForms());
-}
-
-// TCM ID - 4577932.
-IN_PROC_BROWSER_TEST_F(LegacyTwoClientPasswordsSyncTest, DisablePasswords) {
-  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
-  ASSERT_TRUE(AllProfilesContainSamePasswordFormsAsVerifier());
-
-  ASSERT_TRUE(GetClient(1)->DisableSyncForDatatype(syncer::PASSWORDS));
-  PasswordForm form = CreateTestPasswordForm(0);
-  AddLogin(GetVerifierPasswordStore(), form);
-  ASSERT_EQ(1, GetVerifierPasswordCount());
-  AddLogin(GetPasswordStore(0), form);
-  ASSERT_EQ(1, GetPasswordCount(0));
-
-  ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
-  ASSERT_TRUE(ProfileContainsSamePasswordFormsAsVerifier(0));
-  ASSERT_FALSE(ProfileContainsSamePasswordFormsAsVerifier(1));
-
-  ASSERT_TRUE(GetClient(1)->EnableSyncForDatatype(syncer::PASSWORDS));
-  ASSERT_TRUE(AwaitQuiescence());
-  ASSERT_TRUE(AllProfilesContainSamePasswordFormsAsVerifier());
-  ASSERT_EQ(1, GetPasswordCount(1));
-}
-
-// TCM ID - 4649281.
-IN_PROC_BROWSER_TEST_F(TwoClientPasswordsSyncTest, DisableSync) {
-  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
-  ASSERT_TRUE(AllProfilesContainSamePasswordFormsAsVerifier());
-
-  ASSERT_TRUE(GetClient(1)->DisableSyncForAllDatatypes());
-  PasswordForm form = CreateTestPasswordForm(0);
-  AddLogin(GetVerifierPasswordStore(), form);
-  ASSERT_EQ(1, GetVerifierPasswordCount());
-  AddLogin(GetPasswordStore(0), form);
-  ASSERT_EQ(1, GetPasswordCount(0));
-
-  ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
-  ASSERT_TRUE(ProfileContainsSamePasswordFormsAsVerifier(0));
-  ASSERT_FALSE(ProfileContainsSamePasswordFormsAsVerifier(1));
-
-  ASSERT_TRUE(GetClient(1)->EnableSyncForAllDatatypes());
-  ASSERT_TRUE(AwaitQuiescence());
-  ASSERT_TRUE(AllProfilesContainSamePasswordFormsAsVerifier());
-  ASSERT_EQ(1, GetPasswordCount(1));
-}
-
-IN_PROC_BROWSER_TEST_F(TwoClientPasswordsSyncTest, SetPassphrase) {
-  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
-
-  SetEncryptionPassphrase(0, kValidPassphrase, ProfileSyncService::EXPLICIT);
-  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService((0))));
-  ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
-
-  ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService((1))));
-  ASSERT_TRUE(SetDecryptionPassphrase(1, kValidPassphrase));
-  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService((1))));
-  ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((1))));
+  ASSERT_TRUE(AwaitAllProfilesContainSamePasswordForms());
 }
 
 IN_PROC_BROWSER_TEST_F(TwoClientPasswordsSyncTest,
@@ -144,7 +86,6 @@
 
   SetEncryptionPassphrase(0, kValidPassphrase, ProfileSyncService::EXPLICIT);
   ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService((0))));
-  ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
 
   ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService((1))));
   ASSERT_TRUE(SetDecryptionPassphrase(1, kValidPassphrase));
@@ -154,8 +95,7 @@
   AddLogin(GetPasswordStore(0), form);
   ASSERT_EQ(1, GetPasswordCount(0));
 
-  ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
-  ASSERT_EQ(1, GetPasswordCount(1));
+  ASSERT_TRUE(AwaitAllProfilesContainSamePasswordForms());
 }
 
 // TCM ID - 4603879
@@ -166,14 +106,17 @@
   PasswordForm form = CreateTestPasswordForm(0);
   AddLogin(GetVerifierPasswordStore(), form);
   AddLogin(GetPasswordStore(0), form);
-  ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
+
+  // Wait for client 0 to commit and client 1 to receive the update.
+  ASSERT_TRUE(AwaitProfileContainsSamePasswordFormsAsVerifier(1));
 
   form.password_value = base::ASCIIToUTF16("new_password");
   UpdateLogin(GetVerifierPasswordStore(), form);
   UpdateLogin(GetPasswordStore(1), form);
-  ASSERT_TRUE(AwaitQuiescence());
-
   ASSERT_EQ(1, GetVerifierPasswordCount());
+
+  // Wait for client 1 to commit and client 0 to receive the update.
+  ASSERT_TRUE(AwaitProfileContainsSamePasswordFormsAsVerifier(0));
   ASSERT_TRUE(AllProfilesContainSamePasswordFormsAsVerifier());
 }
 
@@ -188,13 +131,16 @@
   PasswordForm form1 = CreateTestPasswordForm(1);
   AddLogin(GetVerifierPasswordStore(), form1);
   AddLogin(GetPasswordStore(0), form1);
-  ASSERT_TRUE(AwaitQuiescence());
+
+  // Wait for client 0 to commit and client 1 to receive the update.
+  ASSERT_TRUE(AwaitProfileContainsSamePasswordFormsAsVerifier(1));
 
   RemoveLogin(GetPasswordStore(1), form0);
   RemoveLogin(GetVerifierPasswordStore(), form0);
-  ASSERT_TRUE(AwaitQuiescence());
-
   ASSERT_EQ(1, GetVerifierPasswordCount());
+
+  // Wait for deletion from client 1 to propagate.
+  ASSERT_TRUE(AwaitProfileContainsSamePasswordFormsAsVerifier(0));
   ASSERT_TRUE(AllProfilesContainSamePasswordFormsAsVerifier());
 }
 
@@ -215,14 +161,14 @@
   PasswordForm form1 = CreateTestPasswordForm(1);
   AddLogin(GetVerifierPasswordStore(), form1);
   AddLogin(GetPasswordStore(0), form1);
-  ASSERT_TRUE(AwaitQuiescence());
+  ASSERT_TRUE(AwaitProfileContainsSamePasswordFormsAsVerifier(1));
+  ASSERT_TRUE(AllProfilesContainSamePasswordFormsAsVerifier());
 
   RemoveLogins(GetPasswordStore(1));
   RemoveLogins(GetVerifierPasswordStore());
-  ASSERT_TRUE(AwaitQuiescence());
-
-  ASSERT_EQ(0, GetVerifierPasswordCount());
+  ASSERT_TRUE(AwaitProfileContainsSamePasswordFormsAsVerifier(0));
   ASSERT_TRUE(AllProfilesContainSamePasswordFormsAsVerifier());
+  ASSERT_EQ(0, GetVerifierPasswordCount());
 }
 
 // TCM ID - 3694311
@@ -236,75 +182,7 @@
   AddLogin(GetPasswordStore(1), form1);
   PasswordForm form2 = CreateTestPasswordForm(2);
   AddLogin(GetPasswordStore(1), form2);
-  ASSERT_TRUE(AwaitQuiescence());
 
+  ASSERT_TRUE(AwaitAllProfilesContainSamePasswordForms());
   ASSERT_EQ(3, GetPasswordCount(0));
-  ASSERT_TRUE(AllProfilesContainSamePasswordForms());
-}
-
-IN_PROC_BROWSER_TEST_F(TwoClientPasswordsSyncTest,
-                       SetPassphraseAndThenSetupSync) {
-  ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
-
-  ASSERT_TRUE(GetClient(0)->SetupSync());
-  SetEncryptionPassphrase(0, kValidPassphrase, ProfileSyncService::EXPLICIT);
-  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService((0))));
-  ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
-
-  ASSERT_FALSE(GetClient(1)->SetupSync());
-  ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService((1))));
-  ASSERT_TRUE(SetDecryptionPassphrase(1, kValidPassphrase));
-  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService((1))));
-
-  // For some reason, the tests won't pass unless these flags are set.
-  GetSyncService((1))->SetSetupInProgress(false);
-  GetSyncService((1))->SetSyncSetupCompleted();
-
-  ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((1))));
-
-  // Following ensures types are enabled and active (see bug 87572).
-  syncer::ModelSafeRoutingInfo routes;
-  GetSyncService((0))->GetModelSafeRoutingInfo(&routes);
-  ASSERT_EQ(syncer::GROUP_PASSWORD, routes[syncer::PASSWORDS]);
-  routes.clear();
-  GetSyncService((1))->GetModelSafeRoutingInfo(&routes);
-  ASSERT_EQ(syncer::GROUP_PASSWORD, routes[syncer::PASSWORDS]);
-}
-
-IN_PROC_BROWSER_TEST_F(TwoClientPasswordsSyncTest,
-                       SetDifferentPassphraseAndThenSetupSync) {
-  ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
-
-  ASSERT_TRUE(GetClient(0)->SetupSync());
-  SetEncryptionPassphrase(0, kValidPassphrase, ProfileSyncService::EXPLICIT);
-  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService((0))));
-  ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
-
-  // Setup 1 with a different passphrase, so that it fails to sync.
-  ASSERT_FALSE(GetClient(1)->SetupSync());
-  ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService((1))));
-  ASSERT_FALSE(SetDecryptionPassphrase(1, kAnotherValidPassphrase));
-  ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService((1))));
-
-  // Add a password on 0 while clients have different passphrases.
-  PasswordForm form0 = CreateTestPasswordForm(0);
-  AddLogin(GetVerifierPasswordStore(), form0);
-  AddLogin(GetPasswordStore(0), form0);
-
-  ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
-
-  // Password hasn't been synced to 1 yet.
-  ASSERT_FALSE(AllProfilesContainSamePasswordFormsAsVerifier());
-
-  // Update 1 with the correct passphrase, the password should now sync over.
-  ASSERT_TRUE(AwaitPassphraseRequired(GetSyncService((1))));
-  ASSERT_TRUE(SetDecryptionPassphrase(1, kValidPassphrase));
-  ASSERT_TRUE(AwaitPassphraseAccepted(GetSyncService((1))));
-
-  // For some reason, the tests won't pass unless these flags are set.
-  GetSyncService((1))->SetSetupInProgress(false);
-  GetSyncService((1))->SetSyncSetupCompleted();
-
-  ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
-  ASSERT_TRUE(AllProfilesContainSamePasswordFormsAsVerifier());
 }
diff --git a/chrome/browser/sync_file_system/drive_backend/callback_helper.h b/chrome/browser/sync_file_system/drive_backend/callback_helper.h
index 822ba65..f48b122 100644
--- a/chrome/browser/sync_file_system/drive_backend/callback_helper.h
+++ b/chrome/browser/sync_file_system/drive_backend/callback_helper.h
@@ -138,6 +138,10 @@
     const tracked_objects::Location& from_here,
     const base::Callback<T>& callback) {
   DCHECK(task_runner->RunsTasksOnCurrentThread());
+
+  if (callback.is_null())
+    return base::Callback<T>();
+
   return base::Bind(&internal::RelayToTaskRunnerHelper<T>::Run,
                     make_scoped_refptr(task_runner), from_here,
                     callback);
diff --git a/chrome/browser/sync_file_system/drive_backend/callback_helper.h.pump b/chrome/browser/sync_file_system/drive_backend/callback_helper.h.pump
index eaeb547..cbd1c9f 100644
--- a/chrome/browser/sync_file_system/drive_backend/callback_helper.h.pump
+++ b/chrome/browser/sync_file_system/drive_backend/callback_helper.h.pump
@@ -73,6 +73,10 @@
     const tracked_objects::Location& from_here,
     const base::Callback<T>& callback) {
   DCHECK(task_runner->RunsTasksOnCurrentThread());
+
+  if (callback.is_null())
+    return base::Callback<T>();
+
   return base::Bind(&internal::RelayToTaskRunnerHelper<T>::Run,
                     make_scoped_refptr(task_runner), from_here,
                     callback);
diff --git a/chrome/browser/sync_file_system/drive_backend/callback_helper_unittest.cc b/chrome/browser/sync_file_system/drive_backend/callback_helper_unittest.cc
index b6a3984..fb83917 100644
--- a/chrome/browser/sync_file_system/drive_backend/callback_helper_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/callback_helper_unittest.cc
@@ -88,5 +88,13 @@
   thread.Stop();
 }
 
+TEST(DriveBackendCallbackHelperTest, PassNullFunctionTest) {
+  base::MessageLoop message_loop;
+  base::Closure closure = RelayCallbackToCurrentThread(
+      FROM_HERE,
+      base::Closure());
+  EXPECT_TRUE(closure.is_null());
+}
+
 }  // namespace drive_backend
 }  // namespace sync_file_system
diff --git a/chrome/browser/sync_file_system/drive_backend/conflict_resolver_unittest.cc b/chrome/browser/sync_file_system/drive_backend/conflict_resolver_unittest.cc
index 9a90fb8..5d6e029 100644
--- a/chrome/browser/sync_file_system/drive_backend/conflict_resolver_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/conflict_resolver_unittest.cc
@@ -56,22 +56,23 @@
     ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
     in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
 
-    fake_drive_service_.reset(new FakeDriveServiceWrapper);
-
-    drive_uploader_.reset(new FakeDriveUploader(fake_drive_service_.get()));
+    scoped_ptr<FakeDriveServiceWrapper>
+        fake_drive_service(new FakeDriveServiceWrapper);
+    scoped_ptr<drive::DriveUploaderInterface>
+        drive_uploader(new FakeDriveUploader(fake_drive_service.get()));
     fake_drive_helper_.reset(
-        new FakeDriveServiceHelper(fake_drive_service_.get(),
-                                   drive_uploader_.get(),
+        new FakeDriveServiceHelper(fake_drive_service.get(),
+                                   drive_uploader.get(),
                                    kSyncRootFolderTitle));
-    fake_remote_change_processor_.reset(new FakeRemoteChangeProcessor);
+    remote_change_processor_.reset(new FakeRemoteChangeProcessor);
 
     context_.reset(new SyncEngineContext(
-        fake_drive_service_.get(),
-        drive_uploader_.get(),
+        fake_drive_service.PassAs<drive::DriveServiceInterface>(),
+        drive_uploader.Pass(),
         base::MessageLoopProxy::current(),
         base::MessageLoopProxy::current(),
         base::MessageLoopProxy::current()));
-    context_->SetRemoteChangeProcessor(fake_remote_change_processor_.get());
+    context_->SetRemoteChangeProcessor(remote_change_processor_.get());
 
     RegisterSyncableFileSystem();
 
@@ -83,12 +84,7 @@
 
   virtual void TearDown() OVERRIDE {
     sync_task_manager_.reset();
-    fake_drive_service_.reset();
-    drive_uploader_.reset();
-
     RevokeSyncableFileSystem();
-
-    fake_remote_change_processor_.reset();
     fake_drive_helper_.reset();
     context_.reset();
     base::RunLoop().RunUntilIdle();
@@ -157,7 +153,7 @@
   }
 
   void CreateLocalFile(const fileapi::FileSystemURL& url) {
-    fake_remote_change_processor_->UpdateLocalFileMetadata(
+    remote_change_processor_->UpdateLocalFileMetadata(
         url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
                         SYNC_FILE_TYPE_FILE));
   }
@@ -210,7 +206,7 @@
     syncer->RunExclusive(CreateResultReceiver(&status));
     base::RunLoop().RunUntilIdle();
     if (status == SYNC_STATUS_OK)
-      fake_remote_change_processor_->ClearLocalChanges(url);
+      remote_change_processor_->ClearLocalChanges(url);
     return status;
   }
 
@@ -264,7 +260,7 @@
 
   void VerifyLocalChangeConsistency(
       const URLToFileChangesMap& expected_changes) {
-    fake_remote_change_processor_->VerifyConsistency(expected_changes);
+    remote_change_processor_->VerifyConsistency(expected_changes);
   }
 
  private:
@@ -273,10 +269,8 @@
   scoped_ptr<leveldb::Env> in_memory_env_;
 
   scoped_ptr<SyncEngineContext> context_;
-  scoped_ptr<FakeDriveServiceWrapper> fake_drive_service_;
-  scoped_ptr<drive::DriveUploaderInterface> drive_uploader_;
   scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
-  scoped_ptr<FakeRemoteChangeProcessor> fake_remote_change_processor_;
+  scoped_ptr<FakeRemoteChangeProcessor> remote_change_processor_;
 
   scoped_ptr<SyncTaskManager> sync_task_manager_;
 
diff --git a/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc b/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc
index 476a83f..b528b52 100644
--- a/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc
@@ -63,8 +63,8 @@
         &profile_, in_memory_env_.get());
     local_sync_service_->AddChangeObserver(this);
 
-    scoped_ptr<drive::FakeDriveService> drive_service(
-        new drive::FakeDriveService());
+    scoped_ptr<drive::FakeDriveService>
+        drive_service(new drive::FakeDriveService);
     drive_service->Initialize("test@example.com");
     ASSERT_TRUE(drive::test_util::SetUpTestEntries(drive_service.get()));
 
diff --git a/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.cc b/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.cc
index 0d3cb2c..0afa45c 100644
--- a/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.cc
@@ -232,6 +232,13 @@
   return google_apis::CancelCallback();
 }
 
+bool DriveServiceOnWorker::HasRefreshToken() const {
+  // TODO(peria): Cache the state and returns it directly, before migration of
+  //    SyncWorker to a worker thread.
+  DCHECK(wrapper_);
+  return wrapper_->HasRefreshToken();
+}
+
 void DriveServiceOnWorker::Initialize(const std::string& account_id) {
   NOTREACHED();
 }
@@ -266,11 +273,6 @@
   NOTREACHED();
 }
 
-bool DriveServiceOnWorker::HasRefreshToken() const {
-  NOTREACHED();
-  return false;
-}
-
 void DriveServiceOnWorker::ClearAccessToken() {
   NOTREACHED();
 }
diff --git a/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.h b/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.h
index 613dc5c..82f988a 100644
--- a/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.h
+++ b/chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.h
@@ -84,7 +84,9 @@
       const std::string& directory_resource_id,
       const google_apis::GetResourceListCallback& callback) OVERRIDE;
 
-  // Following methods are expected not to be accessed at all.
+  virtual bool HasRefreshToken() const OVERRIDE;
+
+  // Following virtual methods are expected not to be accessed at all.
   virtual void Initialize(const std::string& account_id) OVERRIDE;
   virtual void AddObserver(drive::DriveServiceObserver* observer) OVERRIDE;
   virtual void RemoveObserver(drive::DriveServiceObserver* observer) OVERRIDE;
@@ -94,7 +96,6 @@
   virtual bool HasAccessToken() const OVERRIDE;
   virtual void RequestAccessToken(
       const google_apis::AuthStatusCallback& callback) OVERRIDE;
-  virtual bool HasRefreshToken() const OVERRIDE;
   virtual void ClearAccessToken() OVERRIDE;
   virtual void ClearRefreshToken() OVERRIDE;
   virtual google_apis::CancelCallback GetAllResourceList(
diff --git a/chrome/browser/sync_file_system/drive_backend/drive_service_wrapper.cc b/chrome/browser/sync_file_system/drive_backend/drive_service_wrapper.cc
index d6c2f47..d0facd0 100644
--- a/chrome/browser/sync_file_system/drive_backend/drive_service_wrapper.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_service_wrapper.cc
@@ -87,6 +87,10 @@
                                              callback);
 }
 
+bool DriveServiceWrapper::HasRefreshToken() const {
+  return drive_service_->HasRefreshToken();
+}
+
 void DriveServiceWrapper::RemoveResourceFromDirectory(
     const std::string& parent_resource_id,
     const std::string& resource_id,
diff --git a/chrome/browser/sync_file_system/drive_backend/drive_service_wrapper.h b/chrome/browser/sync_file_system/drive_backend/drive_service_wrapper.h
index e03d424..75b27cb 100644
--- a/chrome/browser/sync_file_system/drive_backend/drive_service_wrapper.h
+++ b/chrome/browser/sync_file_system/drive_backend/drive_service_wrapper.h
@@ -60,6 +60,8 @@
       const std::string& directory_resource_id,
       const google_apis::GetResourceListCallback& callback);
 
+  bool HasRefreshToken() const;
+
   void RemoveResourceFromDirectory(
       const std::string& parent_resource_id,
       const std::string& resource_id,
diff --git a/chrome/browser/sync_file_system/drive_backend/list_changes_task_unittest.cc b/chrome/browser/sync_file_system/drive_backend/list_changes_task_unittest.cc
index e4fb489..355085e 100644
--- a/chrome/browser/sync_file_system/drive_backend/list_changes_task_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/list_changes_task_unittest.cc
@@ -42,15 +42,17 @@
     ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
     in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
 
-    fake_drive_service_.reset(new drive::FakeDriveService);
+    scoped_ptr<drive::FakeDriveService>
+        fake_drive_service(new drive::FakeDriveService);
 
-    drive_uploader_.reset(
-        new drive::DriveUploader(fake_drive_service_.get(),
-                                 base::MessageLoopProxy::current()));
+    scoped_ptr<drive::DriveUploaderInterface>
+        drive_uploader(new drive::DriveUploader(
+            fake_drive_service.get(),
+            base::MessageLoopProxy::current()));
 
     fake_drive_service_helper_.reset(
-        new FakeDriveServiceHelper(fake_drive_service_.get(),
-                                   drive_uploader_.get(),
+        new FakeDriveServiceHelper(fake_drive_service.get(),
+                                   drive_uploader.get(),
                                    kSyncRootFolderTitle));
 
     sync_task_manager_.reset(new SyncTaskManager(
@@ -58,12 +60,12 @@
         10 /* maximum_background_task */));
     sync_task_manager_->Initialize(SYNC_STATUS_OK);
 
-    context_.reset(
-        new SyncEngineContext(fake_drive_service_.get(),
-                              drive_uploader_.get(),
-                              base::MessageLoopProxy::current(),
-                              base::MessageLoopProxy::current(),
-                              base::MessageLoopProxy::current()));
+    context_.reset(new SyncEngineContext(
+        fake_drive_service.PassAs<drive::DriveServiceInterface>(),
+        drive_uploader.Pass(),
+        base::MessageLoopProxy::current(),
+        base::MessageLoopProxy::current(),
+        base::MessageLoopProxy::current()));
 
     SetUpRemoteFolders();
 
@@ -74,8 +76,6 @@
   virtual void TearDown() OVERRIDE {
     sync_task_manager_.reset();
     context_.reset();
-    fake_drive_service_.reset();
-    drive_uploader_.reset();
     base::RunLoop().RunUntilIdle();
   }
 
@@ -205,8 +205,6 @@
   base::ScopedTempDir database_dir_;
 
   scoped_ptr<SyncEngineContext> context_;
-  scoped_ptr<drive::FakeDriveService> fake_drive_service_;
-  scoped_ptr<drive::DriveUploaderInterface> drive_uploader_;
   scoped_ptr<FakeDriveServiceHelper> fake_drive_service_helper_;
 
   scoped_ptr<SyncTaskManager> sync_task_manager_;
diff --git a/chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer_unittest.cc b/chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer_unittest.cc
index 2763304..3984343 100644
--- a/chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer_unittest.cc
@@ -56,22 +56,23 @@
     ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
     in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
 
-    fake_drive_service_.reset(new FakeDriveServiceWrapper);
-
-    drive_uploader_.reset(new FakeDriveUploader(fake_drive_service_.get()));
+    scoped_ptr<FakeDriveServiceWrapper>
+        fake_drive_service(new FakeDriveServiceWrapper);
+    scoped_ptr<drive::DriveUploaderInterface>
+        drive_uploader(new FakeDriveUploader(fake_drive_service.get()));
     fake_drive_helper_.reset(new FakeDriveServiceHelper(
-        fake_drive_service_.get(),
-        drive_uploader_.get(),
+        fake_drive_service.get(),
+        drive_uploader.get(),
         kSyncRootFolderTitle));
-    fake_remote_change_processor_.reset(new FakeRemoteChangeProcessor);
+    remote_change_processor_.reset(new FakeRemoteChangeProcessor);
 
     context_.reset(new SyncEngineContext(
-        fake_drive_service_.get(),
-        drive_uploader_.get(),
+        fake_drive_service.PassAs<drive::DriveServiceInterface>(),
+        drive_uploader.Pass(),
         base::MessageLoopProxy::current(),
         base::MessageLoopProxy::current(),
         base::MessageLoopProxy::current()));
-    context_->SetRemoteChangeProcessor(fake_remote_change_processor_.get());
+    context_->SetRemoteChangeProcessor(remote_change_processor_.get());
 
     RegisterSyncableFileSystem();
 
@@ -83,12 +84,7 @@
 
   virtual void TearDown() OVERRIDE {
     sync_task_manager_.reset();
-    fake_drive_service_.reset();
-    drive_uploader_.reset();
-
     RevokeSyncableFileSystem();
-
-    fake_remote_change_processor_.reset();
     fake_drive_helper_.reset();
     context_.reset();
     base::RunLoop().RunUntilIdle();
@@ -243,12 +239,10 @@
   base::ScopedTempDir database_dir_;
   scoped_ptr<leveldb::Env> in_memory_env_;
 
-  scoped_ptr<FakeDriveServiceWrapper> fake_drive_service_;
-  scoped_ptr<drive::DriveUploaderInterface> drive_uploader_;
   scoped_ptr<SyncEngineContext> context_;
   scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
+  scoped_ptr<FakeRemoteChangeProcessor> remote_change_processor_;
   scoped_ptr<MetadataDatabase> metadata_database_;
-  scoped_ptr<FakeRemoteChangeProcessor> fake_remote_change_processor_;
   scoped_ptr<SyncTaskManager> sync_task_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(LocalToRemoteSyncerTest);
diff --git a/chrome/browser/sync_file_system/drive_backend/register_app_task_unittest.cc b/chrome/browser/sync_file_system/drive_backend/register_app_task_unittest.cc
index 3ea6cae..f4c810d 100644
--- a/chrome/browser/sync_file_system/drive_backend/register_app_task_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/register_app_task_unittest.cc
@@ -46,21 +46,24 @@
     ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
     in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
 
-    fake_drive_service_.reset(new drive::FakeDriveService);
-
-    drive_uploader_.reset(new drive::DriveUploader(
-        fake_drive_service_.get(), base::MessageLoopProxy::current()));
+    scoped_ptr<drive::FakeDriveService>
+        fake_drive_service(new drive::FakeDriveService);
+    scoped_ptr<drive::DriveUploaderInterface>
+        drive_uploader(new drive::DriveUploader(
+            fake_drive_service.get(),
+            base::MessageLoopProxy::current()));
 
     fake_drive_service_helper_.reset(new FakeDriveServiceHelper(
-        fake_drive_service_.get(), drive_uploader_.get(),
+        fake_drive_service.get(), drive_uploader.get(),
         kSyncRootFolderTitle));
 
     context_.reset(
-        new SyncEngineContext(fake_drive_service_.get(),
-                              drive_uploader_.get(),
-                              base::MessageLoopProxy::current(),
-                              base::MessageLoopProxy::current(),
-                              base::MessageLoopProxy::current()));
+        new SyncEngineContext(
+            fake_drive_service.PassAs<drive::DriveServiceInterface>(),
+            drive_uploader.Pass(),
+            base::MessageLoopProxy::current(),
+            base::MessageLoopProxy::current(),
+            base::MessageLoopProxy::current()));
 
     ASSERT_EQ(google_apis::HTTP_CREATED,
               fake_drive_service_helper_->AddOrphanedFolder(
@@ -69,8 +72,6 @@
 
   virtual void TearDown() OVERRIDE {
     context_.reset();
-    fake_drive_service_.reset();
-    drive_uploader_.reset();
     base::RunLoop().RunUntilIdle();
   }
 
@@ -246,8 +247,6 @@
   base::ScopedTempDir database_dir_;
 
   scoped_ptr<SyncEngineContext> context_;
-  scoped_ptr<drive::FakeDriveService> fake_drive_service_;
-  scoped_ptr<drive::DriveUploaderInterface> drive_uploader_;
   scoped_ptr<FakeDriveServiceHelper> fake_drive_service_helper_;
 
   DISALLOW_COPY_AND_ASSIGN(RegisterAppTaskTest);
diff --git a/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer_unittest.cc b/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer_unittest.cc
index 4c605ac..8d39f00 100644
--- a/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer_unittest.cc
@@ -55,23 +55,26 @@
     ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
     in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
 
-    fake_drive_service_.reset(new drive::FakeDriveService);
+    scoped_ptr<drive::FakeDriveService>
+        fake_drive_service(new drive::FakeDriveService);
 
-    drive_uploader_.reset(
-        new drive::DriveUploader(fake_drive_service_.get(),
-                                 base::MessageLoopProxy::current().get()));
+    scoped_ptr<drive::DriveUploaderInterface>
+        drive_uploader(new drive::DriveUploader(
+            fake_drive_service.get(),
+            base::MessageLoopProxy::current().get()));
     fake_drive_helper_.reset(
-        new FakeDriveServiceHelper(fake_drive_service_.get(),
-                                   drive_uploader_.get(),
+        new FakeDriveServiceHelper(fake_drive_service.get(),
+                                   drive_uploader.get(),
                                    kSyncRootFolderTitle));
-    fake_remote_change_processor_.reset(new FakeRemoteChangeProcessor);
+    remote_change_processor_.reset(new FakeRemoteChangeProcessor);
 
-    context_.reset(new SyncEngineContext(fake_drive_service_.get(),
-                                         drive_uploader_.get(),
-                                         base::MessageLoopProxy::current(),
-                                         base::MessageLoopProxy::current(),
-                                         base::MessageLoopProxy::current()));
-    context_->SetRemoteChangeProcessor(fake_remote_change_processor_.get());
+    context_.reset(new SyncEngineContext(
+        fake_drive_service.PassAs<drive::DriveServiceInterface>(),
+        drive_uploader.Pass(),
+        base::MessageLoopProxy::current(),
+        base::MessageLoopProxy::current(),
+        base::MessageLoopProxy::current()));
+    context_->SetRemoteChangeProcessor(remote_change_processor_.get());
 
     RegisterSyncableFileSystem();
 
@@ -83,13 +86,8 @@
 
   virtual void TearDown() OVERRIDE {
     sync_task_manager_.reset();
-
     RevokeSyncableFileSystem();
-
-    fake_remote_change_processor_.reset();
     fake_drive_helper_.reset();
-    fake_drive_service_.reset();
-    drive_uploader_.reset();
     context_.reset();
     base::RunLoop().RunUntilIdle();
   }
@@ -169,13 +167,13 @@
   }
 
   void CreateLocalFolder(const fileapi::FileSystemURL& url) {
-    fake_remote_change_processor_->UpdateLocalFileMetadata(
+    remote_change_processor_->UpdateLocalFileMetadata(
         url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
                         SYNC_FILE_TYPE_DIRECTORY));
   }
 
   void CreateLocalFile(const fileapi::FileSystemURL& url) {
-    fake_remote_change_processor_->UpdateLocalFileMetadata(
+    remote_change_processor_->UpdateLocalFileMetadata(
         url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
                         SYNC_FILE_TYPE_FILE));
   }
@@ -213,7 +211,7 @@
   }
 
   void VerifyConsistency() {
-    fake_remote_change_processor_->VerifyConsistency(expected_changes_);
+    remote_change_processor_->VerifyConsistency(expected_changes_);
   }
 
  private:
@@ -222,10 +220,8 @@
   scoped_ptr<leveldb::Env> in_memory_env_;
 
   scoped_ptr<SyncEngineContext> context_;
-  scoped_ptr<drive::FakeDriveService> fake_drive_service_;
-  scoped_ptr<drive::DriveUploaderInterface> drive_uploader_;
   scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
-  scoped_ptr<FakeRemoteChangeProcessor> fake_remote_change_processor_;
+  scoped_ptr<FakeRemoteChangeProcessor> remote_change_processor_;
 
   scoped_ptr<SyncTaskManager> sync_task_manager_;
 
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine.cc
index 82a03c7..9b50473 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_engine.cc
+++ b/chrome/browser/sync_file_system/drive_backend/sync_engine.cc
@@ -21,10 +21,16 @@
 #include "chrome/browser/sync_file_system/drive_backend/callback_helper.h"
 #include "chrome/browser/sync_file_system/drive_backend/conflict_resolver.h"
 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_service_on_worker.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_service_wrapper.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_uploader_on_worker.h"
+#include "chrome/browser/sync_file_system/drive_backend/drive_uploader_wrapper.h"
 #include "chrome/browser/sync_file_system/drive_backend/list_changes_task.h"
 #include "chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer.h"
 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
 #include "chrome/browser/sync_file_system/drive_backend/register_app_task.h"
+#include "chrome/browser/sync_file_system/drive_backend/remote_change_processor_on_worker.h"
+#include "chrome/browser/sync_file_system/drive_backend/remote_change_processor_wrapper.h"
 #include "chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.h"
 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.h"
@@ -183,12 +189,26 @@
 void SyncEngine::Initialize(const base::FilePath& base_dir,
                             base::SequencedTaskRunner* file_task_runner,
                             leveldb::Env* env_override) {
-  scoped_ptr<SyncEngineContext> sync_engine_context(
-      new SyncEngineContext(drive_service_.get(),
-                            drive_uploader_.get(),
-                            base::MessageLoopProxy::current(),
-                            worker_task_runner_,
-                            file_task_runner));
+  // DriveServiceWrapper and DriveServiceOnWorker relay communications
+  // between DriveService and syncers in SyncWorker.
+  scoped_ptr<drive::DriveServiceInterface>
+      drive_service_on_worker(
+          new DriveServiceOnWorker(drive_service_wrapper_->AsWeakPtr(),
+                                   base::MessageLoopProxy::current(),
+                                   worker_task_runner_));
+  scoped_ptr<drive::DriveUploaderInterface>
+      drive_uploader_on_worker(
+          new DriveUploaderOnWorker(drive_uploader_wrapper_->AsWeakPtr(),
+                                    base::MessageLoopProxy::current(),
+                                    worker_task_runner_));
+  scoped_ptr<SyncEngineContext>
+      sync_engine_context(
+          new SyncEngineContext(drive_service_on_worker.Pass(),
+                                drive_uploader_on_worker.Pass(),
+                                base::MessageLoopProxy::current(),
+                                worker_task_runner_,
+                                file_task_runner));
+
   worker_observer_.reset(
       new WorkerObserver(base::MessageLoopProxy::current(),
                          weak_ptr_factory_.GetWeakPtr()));
@@ -275,11 +295,20 @@
 }
 
 void SyncEngine::SetRemoteChangeProcessor(RemoteChangeProcessor* processor) {
+  remote_change_processor_ = processor;
+  remote_change_processor_wrapper_.reset(
+      new RemoteChangeProcessorWrapper(processor));
+
+  remote_change_processor_on_worker_.reset(new RemoteChangeProcessorOnWorker(
+      remote_change_processor_wrapper_->AsWeakPtr(),
+      base::MessageLoopProxy::current(), /* ui_task_runner */
+      worker_task_runner_));
+
   worker_task_runner_->PostTask(
       FROM_HERE,
       base::Bind(&SyncWorker::SetRemoteChangeProcessor,
                  base::Unretained(sync_worker_.get()),
-                 processor));
+                 remote_change_processor_on_worker_.get()));
 }
 
 LocalChangeProcessor* SyncEngine::GetLocalChangeProcessor() {
@@ -457,7 +486,9 @@
     ExtensionServiceInterface* extension_service,
     SigninManagerBase* signin_manager)
     : drive_service_(drive_service.Pass()),
+      drive_service_wrapper_(new DriveServiceWrapper(drive_service_.get())),
       drive_uploader_(drive_uploader.Pass()),
+      drive_uploader_wrapper_(new DriveUploaderWrapper(drive_uploader_.get())),
       notification_manager_(notification_manager),
       extension_service_(extension_service),
       signin_manager_(signin_manager),
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine.h b/chrome/browser/sync_file_system/drive_backend/sync_engine.h
index 7c200a4..d8b84d5 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_engine.h
+++ b/chrome/browser/sync_file_system/drive_backend/sync_engine.h
@@ -42,8 +42,12 @@
 
 namespace drive_backend {
 
+class DriveServiceWrapper;
+class DriveUploaderWrapper;
 class LocalToRemoteSyncer;
 class MetadataDatabase;
+class RemoteChangeProcessorOnWorker;
+class RemoteChangeProcessorWrapper;
 class RemoteToLocalSyncer;
 class SyncEngineInitializer;
 class SyncTaskManager;
@@ -164,7 +168,13 @@
   void UpdateRegisteredApps();
 
   scoped_ptr<drive::DriveServiceInterface> drive_service_;
+  scoped_ptr<DriveServiceWrapper> drive_service_wrapper_;
   scoped_ptr<drive::DriveUploaderInterface> drive_uploader_;
+  scoped_ptr<DriveUploaderWrapper> drive_uploader_wrapper_;
+  RemoteChangeProcessor* remote_change_processor_;
+  scoped_ptr<RemoteChangeProcessorWrapper> remote_change_processor_wrapper_;
+
+  scoped_ptr<RemoteChangeProcessorOnWorker> remote_change_processor_on_worker_;
 
   // These external services are not owned by SyncEngine.
   // The owner of the SyncEngine is responsible for their lifetime.
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine_context.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine_context.cc
index c9bd2d4..98dc4e1 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_engine_context.cc
+++ b/chrome/browser/sync_file_system/drive_backend/sync_engine_context.cc
@@ -18,13 +18,13 @@
 namespace drive_backend {
 
 SyncEngineContext::SyncEngineContext(
-    drive::DriveServiceInterface* drive_service,
-    drive::DriveUploaderInterface* drive_uploader,
+    scoped_ptr<drive::DriveServiceInterface> drive_service,
+    scoped_ptr<drive::DriveUploaderInterface> drive_uploader,
     base::SingleThreadTaskRunner* ui_task_runner,
     base::SequencedTaskRunner* worker_task_runner,
     base::SequencedTaskRunner* file_task_runner)
-    : drive_service_(drive_service),
-      drive_uploader_(drive_uploader),
+    : drive_service_(drive_service.Pass()),
+      drive_uploader_(drive_uploader.Pass()),
       remote_change_processor_(NULL),
       ui_task_runner_(ui_task_runner),
       worker_task_runner_(worker_task_runner),
@@ -33,11 +33,11 @@
 SyncEngineContext::~SyncEngineContext() {}
 
 drive::DriveServiceInterface* SyncEngineContext::GetDriveService() {
-  return drive_service_;
+  return drive_service_.get();
 }
 
 drive::DriveUploaderInterface* SyncEngineContext::GetDriveUploader() {
-  return drive_uploader_;
+  return drive_uploader_.get();
 }
 
 MetadataDatabase* SyncEngineContext::GetMetadataDatabase() {
@@ -72,6 +72,7 @@
 
 void SyncEngineContext::SetRemoteChangeProcessor(
     RemoteChangeProcessor* remote_change_processor) {
+  DCHECK(remote_change_processor);
   remote_change_processor_ = remote_change_processor;
 }
 
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine_context.h b/chrome/browser/sync_file_system/drive_backend/sync_engine_context.h
index eed5729..c4e4a7e 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_engine_context.h
+++ b/chrome/browser/sync_file_system/drive_backend/sync_engine_context.h
@@ -31,13 +31,17 @@
 class SyncEngineContext {
  public:
   SyncEngineContext(
-      drive::DriveServiceInterface* drive_service,
-      drive::DriveUploaderInterface* drive_uploader,
+      scoped_ptr<drive::DriveServiceInterface> drive_service,
+      scoped_ptr<drive::DriveUploaderInterface> drive_uploader,
       base::SingleThreadTaskRunner* ui_task_runner,
       base::SequencedTaskRunner* worker_task_runner,
       base::SequencedTaskRunner* file_task_runner);
   ~SyncEngineContext();
 
+  void SetMetadataDatabase(scoped_ptr<MetadataDatabase> metadata_database);
+  void SetRemoteChangeProcessor(
+      RemoteChangeProcessor* remote_change_processor);
+
   drive::DriveServiceInterface* GetDriveService();
   drive::DriveUploaderInterface* GetDriveUploader();
   MetadataDatabase* GetMetadataDatabase();
@@ -46,15 +50,12 @@
   base::SequencedTaskRunner* GetWorkerTaskRunner();
   base::SequencedTaskRunner* GetFileTaskRunner();
 
-  void SetMetadataDatabase(scoped_ptr<MetadataDatabase> metadata_database);
-  void SetRemoteChangeProcessor(RemoteChangeProcessor* remote_change_processor);
-
   scoped_ptr<MetadataDatabase> PassMetadataDatabase();
 
  private:
-  drive::DriveServiceInterface* drive_service_;
-  drive::DriveUploaderInterface* drive_uploader_;
-  RemoteChangeProcessor* remote_change_processor_;
+  scoped_ptr<drive::DriveServiceInterface> drive_service_;
+  scoped_ptr<drive::DriveUploaderInterface> drive_uploader_;
+  RemoteChangeProcessor* remote_change_processor_;  // Do not own
 
   scoped_ptr<MetadataDatabase> metadata_database_;
   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer_unittest.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer_unittest.cc
index 49f4057..8c35f62 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/sync_engine_initializer_unittest.cc
@@ -48,11 +48,12 @@
     ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
     in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
 
-    fake_drive_service_.reset(new drive::FakeDriveService());
+    scoped_ptr<drive::DriveServiceInterface>
+        fake_drive_service(new drive::FakeDriveService);
 
     sync_context_.reset(new SyncEngineContext(
-        fake_drive_service_.get(),
-        NULL /* drive_uploader */,
+        fake_drive_service.Pass(),
+        scoped_ptr<drive::DriveUploaderInterface>(),
         base::MessageLoopProxy::current(),
         base::MessageLoopProxy::current(),
         base::MessageLoopProxy::current()));
@@ -67,7 +68,6 @@
     sync_task_manager_.reset();
     metadata_database_.reset();
     sync_context_.reset();
-    fake_drive_service_.reset();
     base::RunLoop().RunUntilIdle();
   }
 
@@ -230,7 +230,6 @@
   scoped_ptr<MetadataDatabase> metadata_database_;
   scoped_ptr<SyncTaskManager> sync_task_manager_;
   scoped_ptr<SyncEngineContext> sync_context_;
-  scoped_ptr<drive::FakeDriveService> fake_drive_service_;
 
   DISALLOW_COPY_AND_ASSIGN(SyncEngineInitializerTest);
 };
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc
index 59363de..b40cad5 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc
@@ -108,11 +108,11 @@
     in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
 
     extension_service_.reset(new MockExtensionService);
-    scoped_ptr<drive::FakeDriveService> fake_drive_service(
-        new drive::FakeDriveService);
+    scoped_ptr<drive::DriveServiceInterface>
+        fake_drive_service(new drive::FakeDriveService);
 
     sync_engine_.reset(new drive_backend::SyncEngine(
-        fake_drive_service.PassAs<drive::DriveServiceInterface>(),
+        fake_drive_service.Pass(),
         scoped_ptr<drive::DriveUploaderInterface>(),
         base::MessageLoopProxy::current(),
         NULL /* notification_manager */,
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_worker.cc b/chrome/browser/sync_file_system/drive_backend/sync_worker.cc
index 7afb9d4..e803138 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_worker.cc
+++ b/chrome/browser/sync_file_system/drive_backend/sync_worker.cc
@@ -26,6 +26,8 @@
 #include "chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer.h"
 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
 #include "chrome/browser/sync_file_system/drive_backend/register_app_task.h"
+#include "chrome/browser/sync_file_system/drive_backend/remote_change_processor_on_worker.h"
+#include "chrome/browser/sync_file_system/drive_backend/remote_change_processor_wrapper.h"
 #include "chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.h"
 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.h"
@@ -191,8 +193,8 @@
 }
 
 void SyncWorker::SetRemoteChangeProcessor(
-    RemoteChangeProcessor* processor) {
-  context_->SetRemoteChangeProcessor(processor);
+    RemoteChangeProcessorOnWorker* remote_change_processor_on_worker) {
+  context_->SetRemoteChangeProcessor(remote_change_processor_on_worker);
 }
 
 RemoteServiceState SyncWorker::GetCurrentState() const {
@@ -531,13 +533,16 @@
   }
 
   if (status == SYNC_STATUS_OK) {
-    FOR_EACH_OBSERVER(
-        Observer, observers_,
-        OnFileStatusChanged(
-            syncer->url(),
-            SYNC_FILE_STATUS_SYNCED,
-            syncer->sync_action(),
-            SYNC_DIRECTION_REMOTE_TO_LOCAL));
+    if (syncer->sync_action() != SYNC_ACTION_NONE &&
+        syncer->url().is_valid()) {
+      FOR_EACH_OBSERVER(
+          Observer, observers_,
+          OnFileStatusChanged(
+              syncer->url(),
+              SYNC_FILE_STATUS_SYNCED,
+              syncer->sync_action(),
+              SYNC_DIRECTION_REMOTE_TO_LOCAL));
+    }
 
     if (syncer->sync_action() == SYNC_ACTION_DELETED &&
         syncer->url().is_valid() &&
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_worker.h b/chrome/browser/sync_file_system/drive_backend/sync_worker.h
index 28544e1..71ff888 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_worker.h
+++ b/chrome/browser/sync_file_system/drive_backend/sync_worker.h
@@ -44,6 +44,7 @@
 
 class LocalToRemoteSyncer;
 class MetadataDatabase;
+class RemoteChangeProcessorOnWorker;
 class RemoteToLocalSyncer;
 class SyncEngineContext;
 class SyncEngineInitializer;
@@ -96,7 +97,8 @@
       RemoteFileSyncService::UninstallFlag flag,
       const SyncStatusCallback& callback);
   void ProcessRemoteChange(const SyncFileCallback& callback);
-  void SetRemoteChangeProcessor(RemoteChangeProcessor* processor);
+  void SetRemoteChangeProcessor(
+      RemoteChangeProcessorOnWorker* remote_change_processor_on_worker);
   RemoteServiceState GetCurrentState() const;
   void GetOriginStatusMap(RemoteFileSyncService::OriginStatusMap* status_map);
   scoped_ptr<base::ListValue> DumpFiles(const GURL& origin);
diff --git a/chrome/browser/sync_file_system/drive_backend_v1/api_util.cc b/chrome/browser/sync_file_system/drive_backend_v1/api_util.cc
index d3d5835..2ec9791 100644
--- a/chrome/browser/sync_file_system/drive_backend_v1/api_util.cc
+++ b/chrome/browser/sync_file_system/drive_backend_v1/api_util.cc
@@ -310,7 +310,7 @@
                               google_apis::GDataErrorCode error,
                               scoped_ptr<google_apis::ResourceList> feed) {
   DCHECK(CalledOnValidThread());
-  DCHECK(IsStringASCII(directory_name));
+  DCHECK(base::IsStringASCII(directory_name));
 
   if (error != google_apis::HTTP_SUCCESS) {
     DVLOG(2) << "Error on getting Drive directory: " << error;
diff --git a/chrome/browser/task_manager/web_contents_resource_provider.cc b/chrome/browser/task_manager/web_contents_resource_provider.cc
index b29dd88..2fb79f1 100644
--- a/chrome/browser/task_manager/web_contents_resource_provider.cc
+++ b/chrome/browser/task_manager/web_contents_resource_provider.cc
@@ -51,8 +51,8 @@
     provider_->RemoveFromTaskManager(web_contents());
   }
 
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
-    provider_->RemoveFromTaskManager(web_contents);
+  virtual void WebContentsDestroyed() OVERRIDE {
+    provider_->RemoveFromTaskManager(web_contents());
     provider_->DeleteObserver(this);  // Deletes |this|.
   }
 
diff --git a/chrome/browser/test_presubmit.py b/chrome/browser/test_presubmit.py
new file mode 100755
index 0000000..1f7e939
--- /dev/null
+++ b/chrome/browser/test_presubmit.py
@@ -0,0 +1,666 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 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.
+
+"""Unit tests for Web Development Style Guide checker."""
+
+import os
+import re
+import sys
+import unittest
+
+test_dir = os.path.dirname(os.path.abspath(__file__))
+sys.path.extend([
+    os.path.normpath(os.path.join(test_dir, '..', '..', 'tools')),
+    os.path.join(test_dir),
+])
+
+import find_depot_tools # pylint: disable=W0611
+from testing_support.super_mox import SuperMoxTestBase
+from web_dev_style import css_checker, js_checker # pylint: disable=F0401
+
+
+class JsStyleGuideTest(SuperMoxTestBase):
+  def setUp(self):
+    SuperMoxTestBase.setUp(self)
+
+    input_api = self.mox.CreateMockAnything()
+    input_api.re = re
+    output_api = self.mox.CreateMockAnything()
+    self.checker = js_checker.JSChecker(input_api, output_api)
+
+  def GetHighlight(self, line, error):
+    """Returns the substring of |line| that is highlighted in |error|."""
+    error_lines = error.split('\n')
+    highlight = error_lines[error_lines.index(line) + 1]
+    return ''.join(ch1 for (ch1, ch2) in zip(line, highlight) if ch2 == '^')
+
+  def ShouldFailConstCheck(self, line):
+    """Checks that the 'const' checker flags |line| as a style error."""
+    error = self.checker.ConstCheck(1, line)
+    self.assertNotEqual('', error,
+        'Should be flagged as style error: ' + line)
+    self.assertEqual(self.GetHighlight(line, error), 'const')
+
+  def ShouldPassConstCheck(self, line):
+    """Checks that the 'const' checker doesn't flag |line| as a style error."""
+    self.assertEqual('', self.checker.ConstCheck(1, line),
+        'Should not be flagged as style error: ' + line)
+
+  def testConstFails(self):
+    lines = [
+        "const foo = 'bar';",
+        "    const bar = 'foo';",
+
+        # Trying to use |const| as a variable name
+        "var const = 0;",
+
+        "var x = 5; const y = 6;",
+        "for (var i=0, const e=10; i<e; i++) {",
+        "for (const x=0; x<foo; i++) {",
+        "while (const x = 7) {",
+    ]
+    for line in lines:
+      self.ShouldFailConstCheck(line)
+
+  def testConstPasses(self):
+    lines = [
+        # sanity check
+        "var foo = 'bar'",
+
+        # @const JsDoc tag
+        "/** @const */ var SEVEN = 7;",
+
+        # @const tag in multi-line comment
+        " * @const",
+        "   * @const",
+
+        # @constructor tag in multi-line comment
+        " * @constructor",
+        "   * @constructor",
+
+        # words containing 'const'
+        "if (foo.constructor) {",
+        "var deconstruction = 'something';",
+        "var madeUpWordconst = 10;",
+
+        # Strings containing the word |const|
+        "var str = 'const at the beginning';",
+        "var str = 'At the end: const';",
+
+        # doing this one with regex is probably not practical
+        #"var str = 'a const in the middle';",
+    ]
+    for line in lines:
+      self.ShouldPassConstCheck(line)
+
+  def ShouldFailChromeSendCheck(self, line):
+    """Checks that the 'chrome.send' checker flags |line| as a style error."""
+    error = self.checker.ChromeSendCheck(1, line)
+    self.assertNotEqual('', error,
+        'Should be flagged as style error: ' + line)
+    self.assertEqual(self.GetHighlight(line, error), ', []')
+
+  def ShouldPassChromeSendCheck(self, line):
+    """Checks that the 'chrome.send' checker doesn't flag |line| as a style
+       error.
+    """
+    self.assertEqual('', self.checker.ChromeSendCheck(1, line),
+        'Should not be flagged as style error: ' + line)
+
+  def testChromeSendFails(self):
+    lines = [
+        "chrome.send('message', []);",
+        "  chrome.send('message', []);",
+    ]
+    for line in lines:
+      self.ShouldFailChromeSendCheck(line)
+
+  def testChromeSendPasses(self):
+    lines = [
+        "chrome.send('message', constructArgs('foo', []));",
+        "  chrome.send('message', constructArgs('foo', []));",
+        "chrome.send('message', constructArgs([]));",
+        "  chrome.send('message', constructArgs([]));",
+    ]
+    for line in lines:
+      self.ShouldPassChromeSendCheck(line)
+
+  def ShouldFailEndJsDocCommentCheck(self, line):
+    """Checks that the **/ checker flags |line| as a style error."""
+    error = self.checker.EndJsDocCommentCheck(1, line)
+    self.assertNotEqual('', error,
+        'Should be flagged as style error: ' + line)
+    self.assertEqual(self.GetHighlight(line, error), '**/')
+
+  def ShouldPassEndJsDocCommentCheck(self, line):
+    """Checks that the **/ checker doesn't flag |line| as a style error."""
+    self.assertEqual('', self.checker.EndJsDocCommentCheck(1, line),
+        'Should not be flagged as style error: ' + line)
+
+  def testEndJsDocCommentFails(self):
+    lines = [
+        "/** @override **/",
+        "/** @type {number} @const **/",
+        "  **/",
+        "**/  ",
+    ]
+    for line in lines:
+      self.ShouldFailEndJsDocCommentCheck(line)
+
+  def testEndJsDocCommentPasses(self):
+    lines = [
+        "/***************/",  # visual separators
+        "  */",  # valid JSDoc comment ends
+        "*/  ",
+        "/**/",  # funky multi-line comment enders
+        "/** @override */",  # legit JSDoc one-liners
+    ]
+    for line in lines:
+      self.ShouldPassEndJsDocCommentCheck(line)
+
+  def ShouldFailGetElementByIdCheck(self, line):
+    """Checks that the 'getElementById' checker flags |line| as a style
+       error.
+    """
+    error = self.checker.GetElementByIdCheck(1, line)
+    self.assertNotEqual('', error,
+        'Should be flagged as style error: ' + line)
+    self.assertEqual(self.GetHighlight(line, error), 'document.getElementById')
+
+  def ShouldPassGetElementByIdCheck(self, line):
+    """Checks that the 'getElementById' checker doesn't flag |line| as a style
+       error.
+    """
+    self.assertEqual('', self.checker.GetElementByIdCheck(1, line),
+        'Should not be flagged as style error: ' + line)
+
+  def testGetElementByIdFails(self):
+    lines = [
+        "document.getElementById('foo');",
+        "  document.getElementById('foo');",
+        "var x = document.getElementById('foo');",
+        "if (document.getElementById('foo').hidden) {",
+    ]
+    for line in lines:
+      self.ShouldFailGetElementByIdCheck(line)
+
+  def testGetElementByIdPasses(self):
+    lines = [
+        "elem.ownerDocument.getElementById('foo');",
+        "  elem.ownerDocument.getElementById('foo');",
+        "var x = elem.ownerDocument.getElementById('foo');",
+        "if (elem.ownerDocument.getElementById('foo').hidden) {",
+        "doc.getElementById('foo');",
+        "  doc.getElementById('foo');",
+        "cr.doc.getElementById('foo');",
+        "  cr.doc.getElementById('foo');",
+        "var x = doc.getElementById('foo');",
+        "if (doc.getElementById('foo').hidden) {",
+    ]
+    for line in lines:
+      self.ShouldPassGetElementByIdCheck(line)
+
+  def ShouldFailInheritDocCheck(self, line):
+    """Checks that the '@inheritDoc' checker flags |line| as a style error."""
+    error = self.checker.InheritDocCheck(1, line)
+    self.assertNotEqual('', error,
+        msg='Should be flagged as style error: ' + line)
+    self.assertEqual(self.GetHighlight(line, error), '@inheritDoc')
+
+  def ShouldPassInheritDocCheck(self, line):
+    """Checks that the '@inheritDoc' checker doesn't flag |line| as a style
+       error.
+    """
+    self.assertEqual('', self.checker.InheritDocCheck(1, line),
+        msg='Should not be flagged as style error: ' + line)
+
+  def testInheritDocFails(self):
+    lines = [
+        " /** @inheritDoc */",
+        "   * @inheritDoc",
+    ]
+    for line in lines:
+      self.ShouldFailInheritDocCheck(line)
+
+  def testInheritDocPasses(self):
+    lines = [
+        "And then I said, but I won't @inheritDoc! Hahaha!",
+        " If your dad's a doctor, do you inheritDoc?",
+        "  What's up, inherit doc?",
+        "   this.inheritDoc(someDoc)",
+    ]
+    for line in lines:
+      self.ShouldPassInheritDocCheck(line)
+
+  def ShouldFailWrapperTypeCheck(self, line):
+    """Checks that the use of wrapper types (i.e. new Number(), @type {Number})
+       is a style error.
+    """
+    error = self.checker.WrapperTypeCheck(1, line)
+    self.assertNotEqual('', error,
+        msg='Should be flagged as style error: ' + line)
+    highlight = self.GetHighlight(line, error)
+    self.assertTrue(highlight in ('Boolean', 'Number', 'String'))
+
+  def ShouldPassWrapperTypeCheck(self, line):
+    """Checks that the wrapper type checker doesn't flag |line| as a style
+       error.
+    """
+    self.assertEqual('', self.checker.WrapperTypeCheck(1, line),
+        msg='Should not be flagged as style error: ' + line)
+
+  def testWrapperTypePasses(self):
+    lines = [
+        "/** @param {!ComplexType} */",
+        "  * @type {Object}",
+        "   * @param {Function=} opt_callback",
+        "    * @param {} num Number of things to add to {blah}.",
+        "   *  @return {!print_preview.PageNumberSet}",
+        " /* @returns {Number} */",  # Should be /** @return {Number} */
+        "* @param {!LocalStrings}"
+        " Your type of Boolean is false!",
+        "  Then I parameterized her Number from her friend!",
+        "   A String of Pearls",
+        "    types.params.aBoolean.typeString(someNumber)",
+    ]
+    for line in lines:
+      self.ShouldPassWrapperTypeCheck(line)
+
+  def testWrapperTypeFails(self):
+    lines = [
+        "  /**@type {String}*/(string)",
+        "   * @param{Number=} opt_blah A number",
+        "/** @private @return {!Boolean} */",
+        " * @param {number|String}",
+    ]
+    for line in lines:
+      self.ShouldFailWrapperTypeCheck(line)
+
+  def ShouldFailVarNameCheck(self, line):
+    """Checks that var unix_hacker, $dollar are style errors."""
+    error = self.checker.VarNameCheck(1, line)
+    self.assertNotEqual('', error,
+        msg='Should be flagged as style error: ' + line)
+    highlight = self.GetHighlight(line, error)
+    self.assertFalse('var ' in highlight);
+
+  def ShouldPassVarNameCheck(self, line):
+    """Checks that variableNamesLikeThis aren't style errors."""
+    self.assertEqual('', self.checker.VarNameCheck(1, line),
+        msg='Should not be flagged as style error: ' + line)
+
+  def testVarNameFails(self):
+    lines = [
+        "var private_;",
+        " var _super_private",
+        "  var unix_hacker = someFunc();",
+    ]
+    for line in lines:
+      self.ShouldFailVarNameCheck(line)
+
+  def testVarNamePasses(self):
+    lines = [
+        "  var namesLikeThis = [];",
+        " for (var i = 0; i < 10; ++i) { ",
+        "for (var i in obj) {",
+        " var one, two, three;",
+        "  var magnumPI = {};",
+        " var g_browser = 'da browzer';",
+        "/** @const */ var Bla = options.Bla;",  # goog.scope() replacement.
+        " var $ = function() {",                 # For legacy reasons.
+        "  var StudlyCaps = cr.define('bla')",   # Classes.
+        " var SCARE_SMALL_CHILDREN = [",         # TODO(dbeam): add @const in
+                                                 # front of all these vars like
+        "/** @const */ CONST_VAR = 1;",          # this line has (<--).
+    ]
+    for line in lines:
+      self.ShouldPassVarNameCheck(line)
+
+
+class CssStyleGuideTest(SuperMoxTestBase):
+  def setUp(self):
+    SuperMoxTestBase.setUp(self)
+
+    self.fake_file_name = 'fake.css'
+
+    self.fake_file = self.mox.CreateMockAnything()
+    self.mox.StubOutWithMock(self.fake_file, 'LocalPath')
+    self.fake_file.LocalPath().AndReturn(self.fake_file_name)
+    # Actual calls to NewContents() are defined in each test.
+    self.mox.StubOutWithMock(self.fake_file, 'NewContents')
+
+    self.input_api = self.mox.CreateMockAnything()
+    self.input_api.re = re
+    self.mox.StubOutWithMock(self.input_api, 'AffectedSourceFiles')
+    self.input_api.AffectedFiles(
+        include_deletes=False, file_filter=None).AndReturn([self.fake_file])
+
+    # Actual creations of PresubmitPromptWarning are defined in each test.
+    self.output_api = self.mox.CreateMockAnything()
+    self.mox.StubOutWithMock(self.output_api, 'PresubmitPromptWarning',
+                             use_mock_anything=True)
+
+    author_msg = ('Was the CSS checker useful? '
+                  'Send feedback or hate mail to dbeam@chromium.org.')
+    self.output_api = self.mox.CreateMockAnything()
+    self.mox.StubOutWithMock(self.output_api, 'PresubmitNotifyResult',
+                             use_mock_anything=True)
+    self.output_api.PresubmitNotifyResult(author_msg).AndReturn(None)
+
+  def VerifyContentsProducesOutput(self, contents, output):
+    self.fake_file.NewContents().AndReturn(contents.splitlines())
+    self.output_api.PresubmitPromptWarning(
+        self.fake_file_name + ':\n' + output.strip()).AndReturn(None)
+    self.mox.ReplayAll()
+    css_checker.CSSChecker(self.input_api, self.output_api).RunChecks()
+
+  def testCssAlphaWithAtBlock(self):
+    self.VerifyContentsProducesOutput("""
+<include src="../shared/css/cr/ui/overlay.css">
+<include src="chrome://resources/totally-cool.css" />
+
+/* A hopefully safely ignored comment and @media statement. /**/
+@media print {
+  div {
+    display: block;
+    color: red;
+  }
+}
+
+.rule {
+  z-index: 5;
+<if expr="not is macosx">
+  background-image: url(chrome://resources/BLAH); /* TODO(dbeam): Fix this. */
+  background-color: rgb(235, 239, 249);
+</if>
+<if expr="is_macosx">
+  background-color: white;
+  background-image: url(chrome://resources/BLAH2);
+</if>
+  color: black;
+}
+
+<if expr="is_macosx">
+.language-options-right {
+  visibility: hidden;
+  opacity: 1; /* TODO(dbeam): Fix this. */
+}
+</if>""", """
+- Alphabetize properties and list vendor specific (i.e. -webkit) above standard.
+    display: block;
+    color: red;
+
+    z-index: 5;
+    color: black;""")
+
+  def testCssAlphaWithNonStandard(self):
+    self.VerifyContentsProducesOutput("""
+div {
+  /* A hopefully safely ignored comment and @media statement. /**/
+  color: red;
+  -webkit-margin-start: 5px;
+}""", """
+- Alphabetize properties and list vendor specific (i.e. -webkit) above standard.
+    color: red;
+    -webkit-margin-start: 5px;""")
+
+  def testCssAlphaWithLongerDashedProps(self):
+    self.VerifyContentsProducesOutput("""
+div {
+  border-left: 5px;  /* A hopefully removed comment. */
+  border: 5px solid red;
+}""", """
+- Alphabetize properties and list vendor specific (i.e. -webkit) above standard.
+    border-left: 5px;
+    border: 5px solid red;""")
+
+  def testCssBracesHaveSpaceBeforeAndNothingAfter(self):
+    self.VerifyContentsProducesOutput("""
+/* Hello! */div/* Comment here*/{
+  display: block;
+}
+
+blah /* hey! */
+{
+  rule: value;
+}
+
+.this.is { /* allowed */
+  rule: value;
+}""", """
+- Start braces ({) end a selector, have a space before them and no rules after.
+    div{
+    {""")
+
+  def testCssClassesUseDashes(self):
+    self.VerifyContentsProducesOutput("""
+.className,
+.ClassName,
+.class-name /* We should not catch this. */,
+.class_name {
+  display: block;
+}""", """
+ - Classes use .dash-form.
+    .className,
+    .ClassName,
+    .class_name {""")
+
+  def testCssCloseBraceOnNewLine(self):
+    self.VerifyContentsProducesOutput("""
+@media { /* TODO(dbeam) Fix this case. */
+  .rule {
+    display: block;
+  }}
+
+@-webkit-keyframe blah {
+  100% { height: -500px 0; }
+}
+
+#rule {
+  rule: value; }""", """
+- Always put a rule closing brace (}) on a new line.
+    rule: value; }""")
+
+  def testCssColonsHaveSpaceAfter(self):
+    self.VerifyContentsProducesOutput("""
+div:not(.class):not([attr=5]), /* We should not catch this. */
+div:not(.class):not([attr]) /* Nor this. */ {
+  background: url(data:image/jpeg,asdfasdfsadf); /* Ignore this. */
+  background: -webkit-linear-gradient(left, red,
+                                      80% blah blee blar);
+  color: red;
+  display:block;
+}""", """
+- Colons (:) should have a space after them.
+    display:block;
+
+- Don't use data URIs in source files. Use grit instead.
+    background: url(data:image/jpeg,asdfasdfsadf);""")
+
+  def testCssFavorSingleQuotes(self):
+    self.VerifyContentsProducesOutput("""
+html[dir="rtl"] body,
+html[dir=ltr] body /* TODO(dbeam): Require '' around rtl in future? */ {
+  background: url("chrome://resources/BLAH");
+  font-family: "Open Sans";
+<if expr="is_macosx">
+  blah: blee;
+</if>
+}""", """
+- Use single quotes (') instead of double quotes (") in strings.
+    html[dir="rtl"] body,
+    background: url("chrome://resources/BLAH");
+    font-family: "Open Sans";""")
+
+  def testCssHexCouldBeShorter(self):
+    self.VerifyContentsProducesOutput("""
+#abc,
+#abc-,
+#abc-ghij,
+#abcdef-,
+#abcdef-ghij,
+#aaaaaa,
+#bbaacc {
+  background-color: #336699; /* Ignore short hex rule if not gray. */
+  color: #999999;
+  color: #666;
+}""", """
+- Use abbreviated hex (#rgb) when in form #rrggbb.
+    color: #999999; (replace with #999)
+
+- Use rgb() over #hex when not a shade of gray (like #333).
+    background-color: #336699; (replace with rgb(51, 102, 153))""")
+
+  def testCssUseMillisecondsForSmallTimes(self):
+    self.VerifyContentsProducesOutput("""
+.transition-0s /* This is gross but may happen. */ {
+  transform: one 0.2s;
+  transform: two .1s;
+  transform: tree 1s;
+  transform: four 300ms;
+}""", """
+- Use milliseconds for time measurements under 1 second.
+    transform: one 0.2s; (replace with 200ms)
+    transform: two .1s; (replace with 100ms)""")
+
+  def testCssNoDataUrisInSourceFiles(self):
+    self.VerifyContentsProducesOutput("""
+img {
+  background: url( data:image/jpeg,4\/\/350|\/|3|2 );
+  background: url('data:image/jpeg,4\/\/350|\/|3|2');
+}""", """
+- Don't use data URIs in source files. Use grit instead.
+    background: url( data:image/jpeg,4\/\/350|\/|3|2 );
+    background: url('data:image/jpeg,4\/\/350|\/|3|2');""")
+
+  def testCssOneRulePerLine(self):
+    self.VerifyContentsProducesOutput("""
+a:not([hidden]):not(.custom-appearance):not([version=1]):first-of-type,
+a:not([hidden]):not(.custom-appearance):not([version=1]):first-of-type ~
+    input[type='checkbox']:not([hidden]),
+div {
+  background: url(chrome://resources/BLAH);
+  rule: value; /* rule: value; */
+  rule: value; rule: value;
+}""", """
+- One rule per line (what not to do: color: red; margin: 0;).
+    rule: value; rule: value;""")
+
+  def testCssOneSelectorPerLine(self):
+    self.VerifyContentsProducesOutput("""
+a,
+div,a,
+div,/* Hello! */ span,
+#id.class([dir=rtl):not(.class):any(a, b, d) {
+  rule: value;
+}
+
+a,
+div,a {
+  some-other: rule here;
+}""", """
+- One selector per line (what not to do: a, b {}).
+    div,a,
+    div, span,
+    div,a {""")
+
+  def testCssPseudoElementDoubleColon(self):
+    self.VerifyContentsProducesOutput("""
+a:href,
+br::after,
+::-webkit-scrollbar-thumb,
+a:not([empty]):hover:focus:active, /* shouldn't catch here and above */
+abbr:after,
+.tree-label:empty:after,
+b:before,
+:-WebKit-ScrollBar {
+  rule: value;
+}""", """
+- Pseudo-elements should use double colon (i.e. ::after).
+    :after (should be ::after)
+    :after (should be ::after)
+    :before (should be ::before)
+    :-WebKit-ScrollBar (should be ::-WebKit-ScrollBar)
+    """)
+
+  def testCssRgbIfNotGray(self):
+    self.VerifyContentsProducesOutput("""
+#abc,
+#aaa,
+#aabbcc {
+  background: -webkit-linear-gradient(left, from(#abc), to(#def));
+  color: #bad;
+  color: #bada55;
+}""", """
+- Use rgb() over #hex when not a shade of gray (like #333).
+    background: -webkit-linear-gradient(left, from(#abc), to(#def)); """
+"""(replace with rgb(170, 187, 204), rgb(221, 238, 255))
+    color: #bad; (replace with rgb(187, 170, 221))
+    color: #bada55; (replace with rgb(186, 218, 85))""")
+
+  def testCssZeroLengthTerms(self):
+    self.VerifyContentsProducesOutput("""
+@-webkit-keyframe anim {
+  0% { /* Ignore key frames */
+    width: 0px;
+  }
+  10% {
+    width: 10px;
+  }
+  100% {
+    width: 100px;
+  }
+}
+
+/* http://crbug.com/359682 */
+#spinner-container #spinner {
+  -webkit-animation-duration: 1.0s;
+}
+
+.media-button.play > .state0.active,
+.media-button[state='0'] > .state0.normal /* blah */, /* blee */
+.media-button[state='0']:not(.disabled):hover > .state0.hover {
+  -webkit-animation: anim 0s;
+  -webkit-animation-duration: anim 0ms;
+  -webkit-transform: scale(0%),
+                     translateX(0deg),
+                     translateY(0rad),
+                     translateZ(0grad);
+  background-position-x: 0em;
+  background-position-y: 0ex;
+  border-width: 0em;
+  color: hsl(0, 0%, 85%); /* Shouldn't trigger error. */
+  opacity: .0;
+  opacity: 0.0;
+  opacity: 0.;
+}
+
+@page {
+  border-width: 0mm;
+  height: 0cm;
+  width: 0in;
+}""", """
+- Make all zero length terms (i.e. 0px) 0 unless inside of hsl() or part of"""
+""" @keyframe.
+    width: 0px;
+    -webkit-animation: anim 0s;
+    -webkit-animation-duration: anim 0ms;
+    -webkit-transform: scale(0%),
+    translateX(0deg),
+    translateY(0rad),
+    translateZ(0grad);
+    background-position-x: 0em;
+    background-position-y: 0ex;
+    border-width: 0em;
+    opacity: .0;
+    opacity: 0.0;
+    opacity: 0.;
+    border-width: 0mm;
+    height: 0cm;
+    width: 0in;
+""")
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc
index 078c9bd..d209599 100644
--- a/chrome/browser/themes/browser_theme_pack.cc
+++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -1451,7 +1451,6 @@
 
 void BrowserThemePack::RepackImages(const ImageCache& images,
                                     RawImages* reencoded_images) const {
-  typedef std::vector<ui::ScaleFactor> ScaleFactors;
   for (ImageCache::const_iterator it = images.begin();
        it != images.end(); ++it) {
     gfx::ImageSkia image_skia = *it->second.ToImageSkia();
diff --git a/chrome/browser/themes/theme_service_aurax11.cc b/chrome/browser/themes/theme_service_aurax11.cc
index b9313d5b..e67c25e 100644
--- a/chrome/browser/themes/theme_service_aurax11.cc
+++ b/chrome/browser/themes/theme_service_aurax11.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/themes/custom_theme_supplier.h"
 #include "chrome/common/pref_names.h"
 #include "ui/gfx/image/image.h"
+#include "ui/native_theme/native_theme_aura.h"
 #include "ui/views/linux_ui/linux_ui.h"
 
 namespace {
@@ -42,10 +43,15 @@
 
 void NativeThemeX11::StartUsingTheme() {
   pref_service_->SetBoolean(prefs::kUsesSystemTheme, true);
+  // Have the former theme notify its observers of change.
+  ui::NativeThemeAura::instance()->NotifyObservers();
 }
 
 void NativeThemeX11::StopUsingTheme() {
   pref_service_->SetBoolean(prefs::kUsesSystemTheme, false);
+  // Have the former theme notify its observers of change.
+  if (linux_ui_)
+    linux_ui_->GetNativeTheme(NULL)->NotifyObservers();
 }
 
 bool NativeThemeX11::GetColor(int id, SkColor* color) const {
diff --git a/chrome/browser/thumbnails/thumbnail_list_source.cc b/chrome/browser/thumbnails/thumbnail_list_source.cc
new file mode 100644
index 0000000..ad47041
--- /dev/null
+++ b/chrome/browser/thumbnails/thumbnail_list_source.cc
@@ -0,0 +1,158 @@
+// 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.
+
+#include "chrome/browser/thumbnails/thumbnail_list_source.h"
+
+#include <string>
+
+#include "base/base64.h"
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/strings/string_util.h"
+#include "chrome/browser/history/top_sites.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search/instant_io_context.h"
+#include "chrome/browser/thumbnails/thumbnail_service.h"
+#include "chrome/browser/thumbnails/thumbnail_service_factory.h"
+#include "chrome/common/url_constants.h"
+#include "net/base/escape.h"
+#include "net/url_request/url_request.h"
+
+namespace {
+
+const char kHtmlHeader[] =
+    "<!DOCTYPE html>\n<html>\n<head>\n<title>TopSites Thumbnails</title>\n"
+    "<meta charset=\"utf-8\">\n"
+    "<style type=\"text/css\">\nimg.thumb {border: 1px solid black;}\n"
+    "li {white-space: nowrap;}\n</style>\n";
+const char kHtmlBody[] = "</head>\n<body>\n";
+const char kHtmlFooter[] = "</body>\n</html>\n";
+
+// If |want_thumbnails| == true, then renders elements in |mvurl_list| that have
+// thumbnails, with their thumbnails. Otherwise renders elements in |mvurl_list|
+// that have no thumbnails.
+void RenderMostVisitedURLList(
+    const history::MostVisitedURLList& mvurl_list,
+    const std::vector<std::string>& base64_encoded_pngs,
+    bool want_thumbnails,
+    std::vector<std::string>* out) {
+  DCHECK_EQ(mvurl_list.size(), base64_encoded_pngs.size());
+  bool doing_forced_urls = true;
+  out->push_back("<div><b>Forced URLs:</b></div>\n"
+                 "<div><ul>\n");
+  for (size_t i = 0; i < mvurl_list.size(); ++i) {
+    const history::MostVisitedURL& mvurl = mvurl_list[i];
+    if (doing_forced_urls && mvurl.last_forced_time.is_null()) {
+      out->push_back("</ul></div>\n"
+                     "<div><b>Non-forced URLs:</b></div>\n"
+                     "<div><ul>\n");
+      doing_forced_urls = false;
+    }
+    bool has_thumbnail = !base64_encoded_pngs[i].empty();
+    if (has_thumbnail == want_thumbnails) {
+      out->push_back("<li>\n");
+      out->push_back(net::EscapeForHTML(mvurl.url.spec()) + "\n");
+      if (want_thumbnails) {
+        out->push_back("<div><img class=\"thumb\" "
+                       "src=\"data:image/png;base64," +
+                       base64_encoded_pngs[i] + "\"/></div>\n");
+      }
+      if (!mvurl.redirects.empty()) {
+        out->push_back("<ul>\n");
+        history::RedirectList::const_iterator jt;
+        for (jt = mvurl.redirects.begin();
+             jt != mvurl.redirects.end(); ++jt) {
+          out->push_back("<li>" + net::EscapeForHTML(jt->spec()) + "</li>\n");
+        }
+        out->push_back("</ul>\n");
+      }
+      out->push_back("</li>\n");
+    }
+  }
+  out->push_back("</ul></div>\n");
+}
+
+}  // namespace
+
+ThumbnailListSource::ThumbnailListSource(Profile* profile)
+    : thumbnail_service_(ThumbnailServiceFactory::GetForProfile(profile)),
+      profile_(profile),
+      weak_ptr_factory_(this) {
+}
+
+ThumbnailListSource::~ThumbnailListSource() {
+}
+
+std::string ThumbnailListSource::GetSource() const {
+  return chrome::kChromeUIThumbnailListHost;
+}
+
+void ThumbnailListSource::StartDataRequest(
+    const std::string& path,
+    int render_process_id,
+    int render_frame_id,
+    const content::URLDataSource::GotDataCallback& callback) {
+  profile_->GetTopSites()->GetMostVisitedURLs(
+      base::Bind(&ThumbnailListSource::OnMostVisitedURLsAvailable,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 callback), true);
+}
+
+std::string ThumbnailListSource::GetMimeType(const std::string& path) const {
+  return "text/html";
+}
+
+base::MessageLoop* ThumbnailListSource::MessageLoopForRequestPath(
+    const std::string& path) const {
+  // TopSites can be accessed from the IO thread.
+  return thumbnail_service_.get() ?
+      NULL : content::URLDataSource::MessageLoopForRequestPath(path);
+}
+
+bool ThumbnailListSource::ShouldServiceRequest(
+    const net::URLRequest* request) const {
+  if (request->url().SchemeIs(chrome::kChromeSearchScheme))
+    return InstantIOContext::ShouldServiceRequest(request);
+  return URLDataSource::ShouldServiceRequest(request);
+}
+
+bool ThumbnailListSource::ShouldReplaceExistingSource() const {
+  return false;
+}
+
+void ThumbnailListSource::OnMostVisitedURLsAvailable(
+    const content::URLDataSource::GotDataCallback& callback,
+    const history::MostVisitedURLList& mvurl_list) {
+  const size_t num_mv = mvurl_list.size();
+  size_t num_mv_with_thumb = 0;
+
+  // Encode all available thumbnails and store into |base64_encoded_pngs|.
+  std::vector<std::string> base64_encoded_pngs(num_mv);
+  for (size_t i = 0; i < num_mv; ++i) {
+    scoped_refptr<base::RefCountedMemory> data;
+    if (thumbnail_service_->GetPageThumbnail(mvurl_list[i].url, false, &data)) {
+      base::Base64Encode(std::string(data->front_as<char>(), data->size()),
+                         &base64_encoded_pngs[i]);
+      ++num_mv_with_thumb;
+    }
+  }
+
+  // Render HTML to embed URLs and thumbnails.
+  std::vector<std::string> out;
+  out.push_back(kHtmlHeader);
+  out.push_back(kHtmlBody);
+  if (num_mv_with_thumb > 0) {
+    out.push_back("<h2>TopSites URLs with Thumbnails</h2>\n");
+    RenderMostVisitedURLList(mvurl_list, base64_encoded_pngs, true, &out);
+  }
+  if (num_mv_with_thumb < num_mv) {
+    out.push_back("<h2>TopSites URLs without Thumbnails</h2>\n");
+    RenderMostVisitedURLList(mvurl_list, base64_encoded_pngs, false, &out);
+  }
+  out.push_back(kHtmlFooter);
+
+  std::string out_html = JoinString(out, "");
+  callback.Run(base::RefCountedString::TakeString(&out_html));
+}
diff --git a/chrome/browser/thumbnails/thumbnail_list_source.h b/chrome/browser/thumbnails/thumbnail_list_source.h
new file mode 100644
index 0000000..5eca3ec
--- /dev/null
+++ b/chrome/browser/thumbnails/thumbnail_list_source.h
@@ -0,0 +1,68 @@
+// 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.
+
+#ifndef CHROME_BROWSER_THUMBNAILS_THUMBNAIL_LIST_SOURCE_H_
+#define CHROME_BROWSER_THUMBNAILS_THUMBNAIL_LIST_SOURCE_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/history/history_types.h"
+#include "content/public/browser/url_data_source.h"
+
+class Profile;
+
+namespace base {
+class RefCountedMemory;
+}
+
+namespace thumbnails {
+class ThumbnailService;
+}
+
+// ThumbnailListSource renders a webpage to list all thumbnails stored in
+// TopSites, along with all associated URLs. The thumbnail images are embedded
+// into the HTML via Base64, so we can easily produce a dump of TopSites and
+// the thumbnails it stores.
+class ThumbnailListSource : public content::URLDataSource {
+ public:
+  explicit ThumbnailListSource(Profile* profile);
+
+  // content::URLDataSource implementation.
+  virtual std::string GetSource() const OVERRIDE;
+  virtual void StartDataRequest(
+      const std::string& path,
+      int render_process_id,
+      int render_frame_id,
+      const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
+  virtual std::string GetMimeType(const std::string& path) const OVERRIDE;
+  virtual base::MessageLoop* MessageLoopForRequestPath(
+      const std::string& path) const OVERRIDE;
+  virtual bool ShouldServiceRequest(
+      const net::URLRequest* request) const OVERRIDE;
+  virtual bool ShouldReplaceExistingSource() const OVERRIDE;
+
+ private:
+  virtual ~ThumbnailListSource();
+
+  void OnMostVisitedURLsAvailable(
+    const content::URLDataSource::GotDataCallback& callback,
+    const history::MostVisitedURLList& mvurl_list);
+
+  // ThumbnailService.
+  scoped_refptr<thumbnails::ThumbnailService> thumbnail_service_;
+
+  // Only used when servicing requests on the UI thread.
+  Profile* const profile_;
+
+  // For callbacks may be run after destruction.
+  base::WeakPtrFactory<ThumbnailListSource> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ThumbnailListSource);
+};
+
+
+#endif  // CHROME_BROWSER_THUMBNAILS_THUMBNAIL_LIST_SOURCE_H_
diff --git a/chrome/browser/translate/translate_tab_helper.cc b/chrome/browser/translate/translate_tab_helper.cc
index 9af958f..4fab072 100644
--- a/chrome/browser/translate/translate_tab_helper.cc
+++ b/chrome/browser/translate/translate_tab_helper.cc
@@ -29,6 +29,7 @@
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "net/http/http_status_code.h"
 #include "url/gurl.h"
@@ -301,8 +302,7 @@
   translate_driver_.DidNavigate(details);
 }
 
-void TranslateTabHelper::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void TranslateTabHelper::WebContentsDestroyed() {
   // Translation process can be interrupted.
   // Destroying the TranslateManager now guarantees that it never has to deal
   // with NULL WebContents.
@@ -514,6 +514,10 @@
   if (web_contents() != browser->tab_strip_model()->GetActiveWebContents())
     return;
 
+  content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
+  if (rvh->IsFocusedElementEditable())
+    return;
+
   // This ShowBubble function is also used for upating the existing bubble.
   // However, with the bubble shown, any browser windows are NOT activated
   // because the bubble takes the focus from the other widgets including the
diff --git a/chrome/browser/translate/translate_tab_helper.h b/chrome/browser/translate/translate_tab_helper.h
index d4195f4..10fb138 100644
--- a/chrome/browser/translate/translate_tab_helper.h
+++ b/chrome/browser/translate/translate_tab_helper.h
@@ -108,8 +108,7 @@
   virtual void DidNavigateAnyFrame(
       const content::LoadCommittedDetails& details,
       const content::FrameNavigateParams& params) OVERRIDE;
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // Initiates translation once the page is finished loading.
   void InitiateTranslation(const std::string& page_lang, int attempt);
diff --git a/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.cc b/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.cc
index ba7168a..e2f8451 100644
--- a/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.cc
+++ b/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.cc
@@ -57,6 +57,42 @@
 const char kLastUsedShippingAddressGuid[] = "last_used_shipping";
 const char kLastUsedCreditCardGuid[] = "last_used_card";
 
+// Constructs |inputs| for the SECTION_CC_BILLING section.
+void BuildCcBillingInputs(DetailInputs* inputs) {
+  const DetailInput kCcBillingInputs[] = {
+    { DetailInput::LONG, NAME_BILLING_FULL },
+    { DetailInput::LONG, ADDRESS_BILLING_STREET_ADDRESS },
+    { DetailInput::LONG, ADDRESS_BILLING_CITY },
+    { DetailInput::LONG, ADDRESS_BILLING_DEPENDENT_LOCALITY },
+    { DetailInput::LONG, ADDRESS_BILLING_STATE },
+    { DetailInput::LONG, ADDRESS_BILLING_ZIP },
+    { DetailInput::LONG, ADDRESS_BILLING_SORTING_CODE },
+    { DetailInput::LONG, ADDRESS_BILLING_COUNTRY },
+    { DetailInput::LONG, PHONE_BILLING_WHOLE_NUMBER },
+    { DetailInput::LONG, CREDIT_CARD_NUMBER },
+    { DetailInput::LONG, CREDIT_CARD_EXP_MONTH },
+    { DetailInput::LONG, CREDIT_CARD_EXP_4_DIGIT_YEAR },
+    { DetailInput::LONG, CREDIT_CARD_VERIFICATION_CODE },
+  };
+  common::BuildInputs(kCcBillingInputs, arraysize(kCcBillingInputs), inputs);
+}
+
+// Constructs |inputs| for the SECTION_SHIPPING section.
+void BuildShippingInputs(DetailInputs* inputs) {
+  const DetailInput kShippingInputs[] = {
+    { DetailInput::LONG, NAME_FULL },
+    { DetailInput::LONG, ADDRESS_HOME_STREET_ADDRESS },
+    { DetailInput::LONG, ADDRESS_HOME_CITY },
+    { DetailInput::LONG, ADDRESS_HOME_DEPENDENT_LOCALITY },
+    { DetailInput::LONG, ADDRESS_HOME_STATE },
+    { DetailInput::LONG, ADDRESS_HOME_ZIP },
+    { DetailInput::LONG, ADDRESS_HOME_SORTING_CODE },
+    { DetailInput::LONG, ADDRESS_HOME_COUNTRY },
+    { DetailInput::LONG, PHONE_HOME_WHOLE_NUMBER },
+  };
+  common::BuildInputs(kShippingInputs, arraysize(kShippingInputs), inputs);
+}
+
 base::string16 NullGetInfo(const AutofillType& type) {
   return base::string16();
 }
@@ -90,8 +126,12 @@
     FormStructure& form_structure,
     FullWallet* full_wallet,
     const base::string16& email_address) {
+  DCHECK(section == SECTION_CC_BILLING || section == SECTION_SHIPPING);
   DetailInputs inputs;
-  common::BuildInputsForSection(section, "US", &inputs, NULL);
+  if (section == SECTION_CC_BILLING)
+    BuildCcBillingInputs(&inputs);
+  else
+    BuildShippingInputs(&inputs);
 
   FillOutputForSectionWithComparator(
       section, inputs,
@@ -263,10 +303,22 @@
   const ServerFieldType full_billing_is_necessary_if[] = {
       ADDRESS_BILLING_LINE1,
       ADDRESS_BILLING_LINE2,
+      ADDRESS_BILLING_APT_NUM,
       ADDRESS_BILLING_CITY,
       ADDRESS_BILLING_STATE,
+      // ADDRESS_BILLING_ZIP,  // Postal code alone is a short form.
+      ADDRESS_BILLING_COUNTRY,
+      ADDRESS_BILLING_STREET_ADDRESS,
+      ADDRESS_BILLING_DEPENDENT_LOCALITY,
+      ADDRESS_BILLING_SORTING_CODE,
       PHONE_BILLING_WHOLE_NUMBER
   };
+  const ServerFieldType billing_phone_number_is_necessary_if[] = {
+      PHONE_BILLING_WHOLE_NUMBER
+  };
+  const ServerFieldType shipping_phone_number_is_necessary_if[] = {
+      PHONE_HOME_WHOLE_NUMBER
+  };
   const bool request_full_billing_address =
       IsSectionInputsUsedInFormStructure(
           SECTION_BILLING,
@@ -274,19 +326,21 @@
           arraysize(full_billing_is_necessary_if),
           form_structure_);
   const bool request_phone_numbers =
-      IsSectionInputUsedInFormStructure(
+      IsSectionInputsUsedInFormStructure(
           SECTION_BILLING,
-          PHONE_BILLING_WHOLE_NUMBER,
+          billing_phone_number_is_necessary_if,
+          arraysize(billing_phone_number_is_necessary_if),
           form_structure_) ||
-      IsSectionInputUsedInFormStructure(
+      IsSectionInputsUsedInFormStructure(
           SECTION_SHIPPING,
-          PHONE_HOME_WHOLE_NUMBER,
+          shipping_phone_number_is_necessary_if,
+          arraysize(shipping_phone_number_is_necessary_if),
           form_structure_);
 
   bool request_shipping_address = false;
   {
     DetailInputs inputs;
-    common::BuildInputsForSection(SECTION_SHIPPING, "US", &inputs, NULL);
+    BuildShippingInputs(&inputs);
     request_shipping_address = form_structure_.FillFields(
         common::TypesFromInputs(inputs),
         base::Bind(common::ServerTypeMatchesField, SECTION_SHIPPING),
@@ -334,6 +388,14 @@
   ScopedJavaLocalRef<jstring> jmerchant_domain =
       base::android::ConvertUTF8ToJavaString(
           env, source_url_.GetOrigin().spec());
+  const std::set<base::string16> availableShippingCountriesSet =
+      form_structure_.PossibleValues(ADDRESS_HOME_COUNTRY);
+  ScopedJavaLocalRef<jobjectArray> jshipping_countries =
+      base::android::ToJavaArrayOfStrings(
+          env,
+          std::vector<base::string16>(availableShippingCountriesSet.begin(),
+                                      availableShippingCountriesSet.end()));
+
   java_object_.Reset(Java_AutofillDialogControllerAndroid_create(
       env,
       reinterpret_cast<intptr_t>(this),
@@ -344,7 +406,8 @@
       last_used_choice_is_autofill, jlast_used_account_name.obj(),
       jlast_used_billing.obj(), jlast_used_shipping.obj(),
       jlast_used_card.obj(),
-      jmerchant_domain.obj()));
+      jmerchant_domain.obj(),
+      jshipping_countries.obj()));
 }
 
 void AutofillDialogControllerAndroid::Hide() {
diff --git a/chrome/browser/ui/android/autofill/autofill_dialog_result.cc b/chrome/browser/ui/android/autofill/autofill_dialog_result.cc
index 4c0f0d7..e596d7f 100644
--- a/chrome/browser/ui/android/autofill/autofill_dialog_result.cc
+++ b/chrome/browser/ui/android/autofill/autofill_dialog_result.cc
@@ -10,6 +10,7 @@
 #include "base/android/scoped_java_ref.h"
 #include "base/bind.h"
 #include "base/logging.h"
+#include "base/strings/string_split.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/autofill/data_model_wrapper.h"
 #include "components/autofill/content/browser/wallet/full_wallet.h"
@@ -45,27 +46,29 @@
 
   const base::string16 recipient_name =
       FETCH_JSTRING(UTF16, env, address, ResultAddress, Name);
+
   std::vector<base::string16> address_lines;
-  address_lines.push_back(
-      FETCH_JSTRING(UTF16, env, address, ResultAddress, Address1));
-  address_lines.push_back(
-      FETCH_JSTRING(UTF16, env, address, ResultAddress, Address2));
+  const base::string16 street_address =
+      FETCH_JSTRING(UTF16, env, address, ResultAddress, StreetAddress);
+  base::SplitString(street_address, base::char16('\n'), &address_lines);
+
   const base::string16 locality_name =
-      FETCH_JSTRING(UTF16, env, address, ResultAddress, City);
+      FETCH_JSTRING(UTF16, env, address, ResultAddress, Locality);
+  const base::string16 dependent_locality_name =
+      FETCH_JSTRING(UTF16, env, address, ResultAddress, DependentLocality);
   const base::string16 administrative_area_name =
-      FETCH_JSTRING(UTF16, env, address, ResultAddress, State);
+      FETCH_JSTRING(UTF16, env, address, ResultAddress, AdministrativeArea);
   const base::string16 postal_code_number =
       FETCH_JSTRING(UTF16, env, address, ResultAddress, PostalCode);
+  const base::string16 sorting_code =
+      FETCH_JSTRING(UTF16, env, address, ResultAddress, SortingCode);
   const base::string16 phone_number =
       FETCH_JSTRING(UTF16, env, address, ResultAddress, PhoneNumber);
   const std::string country_name_code =
       FETCH_JSTRING(UTF8, env, address, ResultAddress, CountryCode);
   DCHECK(!country_name_code.empty());
-
-  // TODO(aruslan): get these from the JavaWalletAddress.
-  const base::string16 dependent_locality_name;
-  const base::string16 sorting_code;
-  const std::string language_code;
+  const std::string language_code =
+      FETCH_JSTRING(UTF8, env, address, ResultAddress, LanguageCode);
 
   return scoped_ptr<wallet::Address>(new wallet::Address(
       country_name_code,
diff --git a/chrome/browser/ui/android/infobars/auto_login_prompter.cc b/chrome/browser/ui/android/infobars/auto_login_prompter.cc
index 2cc1f24..7d50998 100644
--- a/chrome/browser/ui/android/infobars/auto_login_prompter.cc
+++ b/chrome/browser/ui/android/infobars/auto_login_prompter.cc
@@ -97,7 +97,7 @@
   delete this;
 }
 
-void AutoLoginPrompter::WebContentsDestroyed(WebContents* web_contents) {
+void AutoLoginPrompter::WebContentsDestroyed() {
   // The WebContents was destroyed before the navigation completed.
   delete this;
 }
diff --git a/chrome/browser/ui/android/infobars/auto_login_prompter.h b/chrome/browser/ui/android/infobars/auto_login_prompter.h
index d55eb67..bfeb290 100644
--- a/chrome/browser/ui/android/infobars/auto_login_prompter.h
+++ b/chrome/browser/ui/android/infobars/auto_login_prompter.h
@@ -53,8 +53,7 @@
   virtual void DidStopLoading(
       content::RenderViewHost* render_view_host) OVERRIDE;
 
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // Add the infobar to the WebContents, if it's still needed.
   void AddInfoBarToWebContents();
diff --git a/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.cc b/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.cc
index c75c820..cc97dcc 100644
--- a/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.cc
+++ b/chrome/browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.cc
@@ -8,7 +8,6 @@
 #include "chrome/browser/ui/android/context_menu_helper.h"
 #include "content/public/browser/android/content_view_core.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_contents_view_delegate.h"
 #include "content/public/common/context_menu_params.h"
 
diff --git a/chrome/browser/ui/app_list/app_list.h b/chrome/browser/ui/app_list/app_list.h
deleted file mode 100644
index fcc321c..0000000
--- a/chrome/browser/ui/app_list/app_list.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_H_
-#define CHROME_BROWSER_UI_APP_LIST_APP_LIST_H_
-
-#include "ui/gfx/native_widget_types.h"
-
-class Profile;
-
-// A container for an AppListView that can be positioned and knows when it has
-// lost focus. Has platform-specific implementations.
-class AppList {
- public:
-  virtual ~AppList() {}
-  virtual void Show() = 0;
-  virtual void Hide() = 0;
-  virtual void MoveNearCursor() = 0;
-  virtual bool IsVisible() = 0;
-  virtual void Prerender() = 0;
-  virtual gfx::NativeWindow GetWindow() = 0;
-  virtual void SetProfile(Profile* profile) = 0;
-};
-
-#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_H_
diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate_impl.cc b/chrome/browser/ui/app_list/app_list_controller_delegate_impl.cc
index 682646b..c6865e9 100644
--- a/chrome/browser/ui/app_list/app_list_controller_delegate_impl.cc
+++ b/chrome/browser/ui/app_list/app_list_controller_delegate_impl.cc
@@ -74,7 +74,7 @@
   OnShowExtensionPrompt();
   chrome::ShowCreateChromeAppShortcutsDialog(
       parent_window, profile, extension,
-      base::Bind(&AppListControllerDelegateImpl::OnCloseExtensionPrompt,
+      base::Bind(&AppListControllerDelegateImpl::OnCloseCreateShortcutsPrompt,
                  base::Unretained(this)));
 }
 
@@ -127,3 +127,8 @@
 }
 
 void AppListControllerDelegateImpl::FillLaunchParams(AppLaunchParams* params) {}
+
+void AppListControllerDelegateImpl::OnCloseCreateShortcutsPrompt(
+    bool created) {
+  OnCloseExtensionPrompt();
+}
diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate_impl.h b/chrome/browser/ui/app_list/app_list_controller_delegate_impl.h
index 002799c..69ab305 100644
--- a/chrome/browser/ui/app_list/app_list_controller_delegate_impl.h
+++ b/chrome/browser/ui/app_list/app_list_controller_delegate_impl.h
@@ -56,6 +56,8 @@
   virtual void FillLaunchParams(AppLaunchParams* params);
 
  private:
+  void OnCloseCreateShortcutsPrompt(bool created);
+
   AppListService* service_;
 
   DISALLOW_COPY_AND_ASSIGN(AppListControllerDelegateImpl);
diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate_views.cc b/chrome/browser/ui/app_list/app_list_controller_delegate_views.cc
new file mode 100644
index 0000000..2ec4e9b
--- /dev/null
+++ b/chrome/browser/ui/app_list/app_list_controller_delegate_views.cc
@@ -0,0 +1,31 @@
+// 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.
+
+#include "chrome/browser/ui/app_list/app_list_controller_delegate_views.h"
+
+#include "chrome/browser/ui/app_list/app_list_service_views.h"
+
+AppListControllerDelegateViews::AppListControllerDelegateViews(
+    AppListServiceViews* service)
+    : AppListControllerDelegateImpl(service),
+      service_(service) {
+}
+
+AppListControllerDelegateViews::~AppListControllerDelegateViews() {}
+
+void AppListControllerDelegateViews::ViewClosing() {
+  service_->OnViewBeingDestroyed();
+}
+
+void AppListControllerDelegateViews::OnShowExtensionPrompt() {
+  service_->set_can_dismiss(false);
+}
+
+void AppListControllerDelegateViews::OnCloseExtensionPrompt() {
+  service_->set_can_dismiss(true);
+}
+
+bool AppListControllerDelegateViews::CanDoCreateShortcutsFlow() {
+  return true;
+}
diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate_views.h b/chrome/browser/ui/app_list/app_list_controller_delegate_views.h
new file mode 100644
index 0000000..c17d042
--- /dev/null
+++ b/chrome/browser/ui/app_list/app_list_controller_delegate_views.h
@@ -0,0 +1,31 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_CONTROLLER_DELEGATE_VIEWS_H_
+#define CHROME_BROWSER_UI_APP_LIST_APP_LIST_CONTROLLER_DELEGATE_VIEWS_H_
+
+#include "chrome/browser/ui/app_list/app_list_controller_delegate_impl.h"
+
+class AppListServiceViews;
+
+// Conveys messages from a views-backed app list to the AppListService that
+// created it.
+class AppListControllerDelegateViews : public AppListControllerDelegateImpl {
+ public:
+  explicit AppListControllerDelegateViews(AppListServiceViews* service);
+  virtual ~AppListControllerDelegateViews();
+
+  // AppListControllerDelegate overrides:
+  virtual void ViewClosing() OVERRIDE;
+  virtual void OnShowExtensionPrompt() OVERRIDE;
+  virtual void OnCloseExtensionPrompt() OVERRIDE;
+  virtual bool CanDoCreateShortcutsFlow() OVERRIDE;
+
+ private:
+  AppListServiceViews* service_;  // Weak. Owns us.
+
+  DISALLOW_COPY_AND_ASSIGN(AppListControllerDelegateViews);
+};
+
+#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_CONTROLLER_DELEGATE_VIEWS_H_
diff --git a/chrome/browser/ui/app_list/app_list_factory.h b/chrome/browser/ui/app_list/app_list_factory.h
deleted file mode 100644
index 56b1f05..0000000
--- a/chrome/browser/ui/app_list/app_list_factory.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_FACTORY_H_
-#define CHROME_BROWSER_UI_APP_LIST_APP_LIST_FACTORY_H_
-
-#include "base/callback_forward.h"
-#include "chrome/browser/ui/app_list/app_list.h"
-
-class AppListService;
-class Profile;
-
-namespace app_list {
-class PaginationModel;
-}
-
-// Factory for AppLists. Used to allow us to create fake app lists in tests.
-class AppListFactory {
- public:
-  virtual ~AppListFactory() {}
-  virtual AppList* CreateAppList(Profile* profile,
-                                 AppListService* service,
-                                 const base::Closure& on_should_dismiss) = 0;
-};
-
-#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_FACTORY_H_
diff --git a/chrome/browser/ui/app_list/app_list_service_impl.cc b/chrome/browser/ui/app_list/app_list_service_impl.cc
index de0470a..e09e252 100644
--- a/chrome/browser/ui/app_list/app_list_service_impl.cc
+++ b/chrome/browser/ui/app_list/app_list_service_impl.cc
@@ -71,6 +71,8 @@
     return;  // In a unit test.
 
   PrefService* local_state = g_browser_process->local_state();
+  if (!local_state)
+    return;  // In a unit test.
 
   int count = local_state->GetInteger(count_pref);
   local_state->SetInteger(count_pref, count + 1);
diff --git a/chrome/browser/ui/app_list/app_list_service_views.cc b/chrome/browser/ui/app_list/app_list_service_views.cc
new file mode 100644
index 0000000..7be99f9
--- /dev/null
+++ b/chrome/browser/ui/app_list/app_list_service_views.cc
@@ -0,0 +1,71 @@
+// 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.
+
+#include "chrome/browser/ui/app_list/app_list_service_views.h"
+
+#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
+#include "chrome/browser/ui/app_list/scoped_keep_alive.h"
+
+AppListServiceViews::AppListServiceViews(
+    scoped_ptr<AppListControllerDelegate> controller_delegate)
+    : shower_(this),
+      can_dismiss_(true),
+      controller_delegate_(controller_delegate.Pass()) {
+}
+
+AppListServiceViews::~AppListServiceViews() {}
+
+void AppListServiceViews::OnViewBeingDestroyed() {
+  can_dismiss_ = true;
+  shower_.HandleViewBeingDestroyed();
+}
+
+void AppListServiceViews::Init(Profile* initial_profile) {
+  PerformStartupChecks(initial_profile);
+}
+
+void AppListServiceViews::CreateForProfile(Profile* requested_profile) {
+  shower_.CreateViewForProfile(requested_profile);
+}
+
+void AppListServiceViews::ShowForProfile(Profile* requested_profile) {
+  DCHECK(requested_profile);
+  if (requested_profile->IsManaged())
+    return;
+
+  ScopedKeepAlive keep_alive;
+
+  InvalidatePendingProfileLoads();
+  SetProfilePath(requested_profile->GetPath());
+  shower_.ShowForProfile(requested_profile);
+  RecordAppListLaunch();
+}
+
+void AppListServiceViews::DismissAppList() {
+  if (!can_dismiss_)
+    return;
+
+  shower_.DismissAppList();
+}
+
+bool AppListServiceViews::IsAppListVisible() const {
+  return shower_.IsAppListVisible();
+}
+
+gfx::NativeWindow AppListServiceViews::GetAppListWindow() {
+  return shower_.GetWindow();
+}
+
+Profile* AppListServiceViews::GetCurrentAppListProfile() {
+  return shower_.profile();
+}
+
+AppListControllerDelegate* AppListServiceViews::GetControllerDelegate() {
+  return controller_delegate_.get();
+}
+
+AppListControllerDelegate*
+AppListServiceViews::GetControllerDelegateForCreate() {
+  return controller_delegate_.get();
+}
diff --git a/chrome/browser/ui/app_list/app_list_service_views.h b/chrome/browser/ui/app_list/app_list_service_views.h
new file mode 100644
index 0000000..925f4f1
--- /dev/null
+++ b/chrome/browser/ui/app_list/app_list_service_views.h
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_SERVICE_VIEWS_H_
+#define CHROME_BROWSER_UI_APP_LIST_APP_LIST_SERVICE_VIEWS_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/ui/app_list/app_list_service_impl.h"
+#include "chrome/browser/ui/app_list/app_list_shower_delegate.h"
+#include "chrome/browser/ui/app_list/app_list_shower_views.h"
+
+class AppListControllerDelegate;
+
+// AppListServiceViews manages a desktop app list that uses toolkit-views.
+class AppListServiceViews : public AppListServiceImpl,
+                            public AppListShowerDelegate {
+ public:
+  explicit AppListServiceViews(
+      scoped_ptr<AppListControllerDelegate> controller_delegate);
+  virtual ~AppListServiceViews();
+
+  // Set |can_dismiss| to prevent the app list dismissing when losing focus. For
+  // example, while showing a window-modal dialog.
+  void set_can_dismiss(bool can_dismiss) { can_dismiss_ = can_dismiss; }
+
+  AppListShower& shower() { return shower_; }
+
+  // Called by the AppListControllerDelegate when it is told that the app list
+  // view must be destroyed.
+  virtual void OnViewBeingDestroyed();
+
+  // AppListService overrides:
+  virtual void Init(Profile* initial_profile) OVERRIDE;
+  virtual void CreateForProfile(Profile* requested_profile) OVERRIDE;
+  virtual void ShowForProfile(Profile* requested_profile) OVERRIDE;
+  virtual void DismissAppList() OVERRIDE;
+  virtual bool IsAppListVisible() const OVERRIDE;
+  virtual gfx::NativeWindow GetAppListWindow() OVERRIDE;
+  virtual Profile* GetCurrentAppListProfile() OVERRIDE;
+  virtual AppListControllerDelegate* GetControllerDelegate() OVERRIDE;
+
+  // AppListShowerDelegate overrides:
+  virtual AppListControllerDelegate* GetControllerDelegateForCreate() OVERRIDE;
+
+ private:
+  // Responsible for creating the app list and responding to profile changes.
+  AppListShower shower_;
+
+  bool can_dismiss_;
+  scoped_ptr<AppListControllerDelegate> controller_delegate_;
+
+  DISALLOW_COPY_AND_ASSIGN(AppListServiceViews);
+};
+
+#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_SERVICE_VIEWS_H_
diff --git a/chrome/browser/ui/app_list/app_list_service_views_browsertest.cc b/chrome/browser/ui/app_list/app_list_service_views_browsertest.cc
new file mode 100644
index 0000000..7bee1a8
--- /dev/null
+++ b/chrome/browser/ui/app_list/app_list_service_views_browsertest.cc
@@ -0,0 +1,44 @@
+// 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.
+
+#include "chrome/browser/ui/app_list/app_list_service_views.h"
+
+#include "base/run_loop.h"
+#include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "ui/views/widget/widget.h"
+
+// Browser Test for AppListService on Views platforms.
+typedef InProcessBrowserTest AppListServiceViewsBrowserTest;
+
+// Test closing the native app list window as if via a request from the OS.
+IN_PROC_BROWSER_TEST_F(AppListServiceViewsBrowserTest, NativeClose) {
+  AppListService* service = test::GetAppListService();
+  EXPECT_FALSE(service->GetAppListWindow());
+
+  // Since the profile is loaded, this will create a view immediately. This is
+  // important, because anything asynchronous would need an interactive_uitest
+  // due to the possibility of the app list being dismissed, and
+  // AppListService::GetAppListWindow returning NULL.
+  service->ShowForProfile(browser()->profile());
+  gfx::NativeWindow window = service->GetAppListWindow();
+  EXPECT_TRUE(window);
+
+  views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
+  EXPECT_TRUE(widget);
+  widget->Close();
+
+  // Close is asynchronous (dismiss is not) so sink the message queue.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(service->GetAppListWindow());
+
+  // Show again to get some code coverage for possibly stale pointers.
+  service->ShowForProfile(browser()->profile());
+  EXPECT_TRUE(service->GetAppListWindow());
+  service->DismissAppList();  // Note: in Ash, this will invalidate the window.
+
+  // Note: no need to sink message queue.
+  EXPECT_FALSE(service->GetAppListWindow());
+}
diff --git a/chrome/browser/ui/app_list/app_list_shower.cc b/chrome/browser/ui/app_list/app_list_shower.cc
deleted file mode 100644
index d657c7c..0000000
--- a/chrome/browser/ui/app_list/app_list_shower.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// 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.
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "chrome/browser/ui/app_list/app_list_shower.h"
-#include "chrome/browser/ui/app_list/scoped_keep_alive.h"
-
-AppListShower::AppListShower(scoped_ptr<AppListFactory> factory,
-                             AppListService* service)
-    : factory_(factory.Pass()),
-      service_(service),
-      profile_(NULL),
-      can_close_app_list_(true) {
-}
-
-AppListShower::~AppListShower() {
-}
-
-void AppListShower::ShowForProfile(Profile* requested_profile) {
-  // If the app list is already displaying |profile| just activate it (in case
-  // we have lost focus).
-  if (IsAppListVisible() && (requested_profile == profile_)) {
-    app_list_->Show();
-    return;
-  }
-
-  if (!app_list_) {
-    CreateViewForProfile(requested_profile);
-  } else if (requested_profile != profile_) {
-    profile_ = requested_profile;
-    app_list_->SetProfile(requested_profile);
-  }
-
-  keep_alive_.reset(new ScopedKeepAlive);
-  if (!IsAppListVisible())
-    app_list_->MoveNearCursor();
-  app_list_->Show();
-}
-
-gfx::NativeWindow AppListShower::GetWindow() {
-  if (!IsAppListVisible())
-    return NULL;
-  return app_list_->GetWindow();
-}
-
-void AppListShower::CreateViewForProfile(Profile* requested_profile) {
-  profile_ = requested_profile;
-  app_list_.reset(factory_->CreateAppList(
-      profile_,
-      service_,
-      base::Bind(&AppListShower::DismissAppList, base::Unretained(this))));
-}
-
-void AppListShower::DismissAppList() {
-  if (app_list_ && can_close_app_list_) {
-    app_list_->Hide();
-    keep_alive_.reset();
-  }
-}
-
-void AppListShower::HandleViewBeingDestroyed() {
-  app_list_.reset();
-  profile_ = NULL;
-  can_close_app_list_ = true;
-
-  // We may end up here as the result of the OS deleting the AppList's
-  // widget (WidgetObserver::OnWidgetDestroyed). If this happens and there
-  // are no browsers around then deleting the keep alive will result in
-  // deleting the Widget again (by way of CloseAllSecondaryWidgets). When
-  // the stack unravels we end up back in the Widget that was deleted and
-  // crash. By delaying deletion of the keep alive we ensure the Widget has
-  // correctly been destroyed before ending the keep alive so that
-  // CloseAllSecondaryWidgets() won't attempt to delete the AppList's Widget
-  // again.
-  if (base::MessageLoop::current()) {  // NULL in tests.
-    base::MessageLoop::current()->PostTask(
-        FROM_HERE,
-        base::Bind(&AppListShower::ResetKeepAlive, base::Unretained(this)));
-    return;
-  }
-  keep_alive_.reset();
-}
-
-bool AppListShower::IsAppListVisible() const {
-  return app_list_ && app_list_->IsVisible();
-}
-
-void AppListShower::WarmupForProfile(Profile* profile) {
-  DCHECK(!profile_);
-  CreateViewForProfile(profile);
-  app_list_->Prerender();
-}
-
-bool AppListShower::HasView() const {
-  return !!app_list_;
-}
-
-void AppListShower::ResetKeepAlive() {
-  keep_alive_.reset();
-}
diff --git a/chrome/browser/ui/app_list/app_list_shower.h b/chrome/browser/ui/app_list/app_list_shower.h
deleted file mode 100644
index 4228d95..0000000
--- a/chrome/browser/ui/app_list/app_list_shower.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_SHOWER_H_
-#define CHROME_BROWSER_UI_APP_LIST_APP_LIST_SHOWER_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/ui/app_list/app_list.h"
-#include "chrome/browser/ui/app_list/app_list_factory.h"
-#include "ui/app_list/pagination_model.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace app_list {
-class AppListModel;
-}
-
-class AppListShowerUnitTest;
-class Profile;
-class ScopedKeepAlive;
-
-// Creates and shows an AppList as needed for non-Ash desktops. It is owned
-// by AppListService.
-class AppListShower {
- public:
-  AppListShower(scoped_ptr<AppListFactory> factory,
-                AppListService* service);
-  ~AppListShower();
-
-  void set_can_close(bool can_close) {
-    can_close_app_list_ = can_close;
-  }
-
-  void ShowForProfile(Profile* requested_profile);
-  gfx::NativeWindow GetWindow();
-
-  AppList* app_list() { return app_list_.get(); }
-  Profile* profile() const { return profile_; }
-
-  // Create or recreate, and initialize |app_list_| from |requested_profile|.
-  void CreateViewForProfile(Profile* requested_profile);
-
-  void DismissAppList();
-  void HandleViewBeingDestroyed();
-  bool IsAppListVisible() const;
-  void WarmupForProfile(Profile* profile);
-  bool HasView() const;
-
- private:
-  friend class ::AppListShowerUnitTest;
-
-  void ResetKeepAlive();
-
-  scoped_ptr<AppListFactory> factory_;
-  scoped_ptr<ScopedKeepAlive> keep_alive_;
-  scoped_ptr<AppList> app_list_;
-  AppListService* service_;  // Weak ptr, owns this.
-  Profile* profile_;
-  bool can_close_app_list_;
-
-  // Used to keep the browser process alive while the app list is visible.
-
-  DISALLOW_COPY_AND_ASSIGN(AppListShower);
-};
-
-#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_SHOWER_H_
diff --git a/chrome/browser/ui/app_list/app_list_shower_delegate.h b/chrome/browser/ui/app_list/app_list_shower_delegate.h
new file mode 100644
index 0000000..9283cf4
--- /dev/null
+++ b/chrome/browser/ui/app_list/app_list_shower_delegate.h
@@ -0,0 +1,23 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_SHOWER_DELEGATE_H_
+#define CHROME_BROWSER_UI_APP_LIST_APP_LIST_SHOWER_DELEGATE_H_
+
+namespace app_list {
+class AppListView;
+}
+
+class AppListControllerDelegate;
+
+// Allows platform-specific hooks for the AppListShower.
+class AppListShowerDelegate {
+ public:
+  virtual AppListControllerDelegate* GetControllerDelegateForCreate() = 0;
+  virtual void OnViewCreated() = 0;
+  virtual void OnViewDismissed() = 0;
+  virtual void MoveNearCursor(app_list::AppListView* view) = 0;
+};
+
+#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_SHOWER_DELEGATE_H_
diff --git a/chrome/browser/ui/app_list/app_list_shower_views.cc b/chrome/browser/ui/app_list/app_list_shower_views.cc
new file mode 100644
index 0000000..de3ddb6
--- /dev/null
+++ b/chrome/browser/ui/app_list/app_list_shower_views.cc
@@ -0,0 +1,138 @@
+// 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.
+
+#include "chrome/browser/ui/app_list/app_list_shower_views.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_list/app_list_shower_delegate.h"
+#include "chrome/browser/ui/app_list/app_list_view_delegate.h"
+#include "chrome/browser/ui/app_list/scoped_keep_alive.h"
+#include "ui/app_list/views/app_list_view.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/screen.h"
+
+AppListShower::AppListShower(AppListShowerDelegate* delegate)
+    : delegate_(delegate),
+      profile_(NULL),
+      app_list_(NULL),
+      window_icon_updated_(false) {
+}
+
+AppListShower::~AppListShower() {
+}
+
+void AppListShower::ShowForProfile(Profile* requested_profile) {
+  // If the app list is already displaying |profile| just activate it (in case
+  // we have lost focus).
+  if (IsAppListVisible() && (requested_profile == profile_)) {
+    Show();
+    return;
+  }
+
+  if (!HasView()) {
+    CreateViewForProfile(requested_profile);
+  } else if (requested_profile != profile_) {
+    profile_ = requested_profile;
+    UpdateViewForNewProfile();
+  }
+
+  keep_alive_.reset(new ScopedKeepAlive);
+  if (!IsAppListVisible())
+    delegate_->MoveNearCursor(app_list_);
+  Show();
+}
+
+gfx::NativeWindow AppListShower::GetWindow() {
+  if (!IsAppListVisible())
+    return NULL;
+  return app_list_->GetWidget()->GetNativeWindow();
+}
+
+void AppListShower::CreateViewForProfile(Profile* requested_profile) {
+  profile_ = requested_profile;
+  app_list_ = MakeViewForCurrentProfile();
+  delegate_->OnViewCreated();
+}
+
+void AppListShower::DismissAppList() {
+  if (HasView()) {
+    Hide();
+    delegate_->OnViewDismissed();
+    keep_alive_.reset();
+  }
+}
+
+void AppListShower::HandleViewBeingDestroyed() {
+  app_list_ = NULL;
+  profile_ = NULL;
+
+  // We may end up here as the result of the OS deleting the AppList's
+  // widget (WidgetObserver::OnWidgetDestroyed). If this happens and there
+  // are no browsers around then deleting the keep alive will result in
+  // deleting the Widget again (by way of CloseAllSecondaryWidgets). When
+  // the stack unravels we end up back in the Widget that was deleted and
+  // crash. By delaying deletion of the keep alive we ensure the Widget has
+  // correctly been destroyed before ending the keep alive so that
+  // CloseAllSecondaryWidgets() won't attempt to delete the AppList's Widget
+  // again.
+  if (base::MessageLoop::current()) {  // NULL in tests.
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(&AppListShower::ResetKeepAlive, base::Unretained(this)));
+    return;
+  }
+  keep_alive_.reset();
+}
+
+bool AppListShower::IsAppListVisible() const {
+  return app_list_ && app_list_->GetWidget()->IsVisible();
+}
+
+void AppListShower::WarmupForProfile(Profile* profile) {
+  DCHECK(!profile_);
+  CreateViewForProfile(profile);
+  app_list_->Prerender();
+}
+
+bool AppListShower::HasView() const {
+  return !!app_list_;
+}
+
+app_list::AppListView* AppListShower::MakeViewForCurrentProfile() {
+  // The view delegate will be owned by the app list view. The app list view
+  // manages its own lifetime.
+  AppListViewDelegate* view_delegate = new AppListViewDelegate(
+      profile_, delegate_->GetControllerDelegateForCreate());
+  app_list::AppListView* view = new app_list::AppListView(view_delegate);
+  gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
+  view->InitAsBubbleAtFixedLocation(NULL,
+                                    &pagination_model_,
+                                    cursor,
+                                    views::BubbleBorder::FLOAT,
+                                    false /* border_accepts_events */);
+  return view;
+}
+
+void AppListShower::UpdateViewForNewProfile() {
+  app_list_->SetProfileByPath(profile_->GetPath());
+}
+
+void AppListShower::Show() {
+  app_list_->GetWidget()->Show();
+  if (!window_icon_updated_) {
+    app_list_->GetWidget()->GetTopLevelWidget()->UpdateWindowIcon();
+    window_icon_updated_ = true;
+  }
+  app_list_->GetWidget()->Activate();
+}
+
+void AppListShower::Hide() {
+  app_list_->GetWidget()->Hide();
+}
+
+void AppListShower::ResetKeepAlive() {
+  keep_alive_.reset();
+}
diff --git a/chrome/browser/ui/app_list/app_list_shower_views.h b/chrome/browser/ui/app_list/app_list_shower_views.h
new file mode 100644
index 0000000..f574a2f
--- /dev/null
+++ b/chrome/browser/ui/app_list/app_list_shower_views.h
@@ -0,0 +1,75 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_SHOWER_VIEWS_H_
+#define CHROME_BROWSER_UI_APP_LIST_APP_LIST_SHOWER_VIEWS_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "ui/app_list/pagination_model.h"
+#include "ui/gfx/native_widget_types.h"
+
+namespace app_list {
+class AppListView;
+}
+
+class AppListShowerDelegate;
+class AppListShowerUnitTest;
+class Profile;
+class ScopedKeepAlive;
+
+// Creates and shows an AppList as needed for non-Ash desktops. It is owned by
+// AppListServiceViews.
+class AppListShower {
+ public:
+  explicit AppListShower(AppListShowerDelegate* delegate);
+  virtual ~AppListShower();
+
+  void ShowForProfile(Profile* requested_profile);
+  gfx::NativeWindow GetWindow();
+
+  app_list::AppListView* app_list() { return app_list_; }
+  Profile* profile() const { return profile_; }
+
+  // Create or recreate, and initialize |app_list_| from |requested_profile|.
+  void CreateViewForProfile(Profile* requested_profile);
+
+  void DismissAppList();
+
+  // Virtual functions mocked out in tests.
+  virtual void HandleViewBeingDestroyed();
+  virtual bool IsAppListVisible() const;
+  void WarmupForProfile(Profile* profile);
+  virtual bool HasView() const;
+
+ protected:
+  virtual app_list::AppListView* MakeViewForCurrentProfile();
+  virtual void UpdateViewForNewProfile();
+
+  // Shows the app list, activates it, and ensures the taskbar icon is updated.
+  virtual void Show();
+  virtual void Hide();
+
+ private:
+  friend class ::AppListShowerUnitTest;
+
+  void ResetKeepAlive();
+
+  AppListShowerDelegate* delegate_;  // Weak. Owns this.
+
+  // The profile currently shown by |app_list_|.
+  Profile* profile_;
+
+  // The view, once created. Owned by native widget.
+  app_list::AppListView* app_list_;
+
+  // Used to keep the browser process alive while the app list is visible.
+  scoped_ptr<ScopedKeepAlive> keep_alive_;
+
+  bool window_icon_updated_;
+  app_list::PaginationModel pagination_model_;
+
+  DISALLOW_COPY_AND_ASSIGN(AppListShower);
+};
+
+#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_SHOWER_VIEWS_H_
diff --git a/chrome/browser/ui/app_list/app_list_shower_views_unittest.cc b/chrome/browser/ui/app_list/app_list_shower_views_unittest.cc
new file mode 100644
index 0000000..fb2f747
--- /dev/null
+++ b/chrome/browser/ui/app_list/app_list_shower_views_unittest.cc
@@ -0,0 +1,166 @@
+// 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.
+
+#include "chrome/browser/ui/app_list/app_list_shower_views.h"
+
+#include "base/files/file_path.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_list/app_list_shower_delegate.h"
+#include "chrome/browser/ui/app_list/scoped_keep_alive.h"
+#include "chrome/browser/ui/app_list/test/fake_profile.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class FakeAppListShower : public AppListShower {
+ public:
+  explicit FakeAppListShower(AppListShowerDelegate* delegate)
+      : AppListShower(delegate), has_view_(false), visible_(false) {}
+
+  // AppListShower:
+  virtual void HandleViewBeingDestroyed() OVERRIDE {
+    AppListShower::HandleViewBeingDestroyed();
+    has_view_ = false;
+    visible_ = false;
+  }
+
+  virtual bool IsAppListVisible() const OVERRIDE { return visible_; }
+
+  virtual app_list::AppListView* MakeViewForCurrentProfile() OVERRIDE {
+    has_view_ = true;
+    return NULL;
+  }
+
+  virtual void UpdateViewForNewProfile() OVERRIDE {}
+
+  virtual void Show() OVERRIDE {
+    visible_ = true;
+  }
+
+  virtual void Hide() OVERRIDE {
+    visible_ = false;
+  }
+
+  virtual bool HasView() const OVERRIDE {
+    return has_view_;
+  }
+
+ private:
+  bool has_view_;
+  bool visible_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeAppListShower);
+};
+
+}  // namespace
+
+class AppListShowerUnitTest : public testing::Test,
+                              public AppListShowerDelegate {
+ public:
+  AppListShowerUnitTest()
+      : views_created_(0),
+        views_dismissed_(0) {}
+
+  virtual void SetUp() OVERRIDE {
+    shower_.reset(new FakeAppListShower(this));
+    profile1_ = CreateProfile("p1").Pass();
+    profile2_ = CreateProfile("p2").Pass();
+  }
+
+  virtual void TearDown() OVERRIDE {
+  }
+
+  scoped_ptr<FakeProfile> CreateProfile(const std::string& name) {
+    return make_scoped_ptr(new FakeProfile(name));
+  }
+
+  // AppListCreatorDelegate:
+  virtual AppListControllerDelegate* GetControllerDelegateForCreate() OVERRIDE {
+    return NULL;
+  }
+
+  bool HasKeepAlive() const {
+    return shower_->keep_alive_.get() != NULL;
+  }
+
+  virtual void OnViewCreated() OVERRIDE { ++views_created_; }
+  virtual void OnViewDismissed() OVERRIDE { ++views_dismissed_; }
+  virtual void MoveNearCursor(app_list::AppListView* view) OVERRIDE {}
+
+ protected:
+  scoped_ptr<FakeAppListShower> shower_;
+  scoped_ptr<FakeProfile> profile1_;
+  scoped_ptr<FakeProfile> profile2_;
+
+  int views_created_;
+  int views_dismissed_;
+};
+
+TEST_F(AppListShowerUnitTest, Preconditions) {
+  EXPECT_FALSE(shower_->IsAppListVisible());
+  EXPECT_FALSE(shower_->HasView());
+  EXPECT_FALSE(HasKeepAlive());
+}
+
+TEST_F(AppListShowerUnitTest, ShowForProfilePutsViewOnScreen) {
+  shower_->ShowForProfile(profile1_.get());
+  EXPECT_TRUE(shower_->IsAppListVisible());
+  EXPECT_TRUE(shower_->HasView());
+  EXPECT_TRUE(HasKeepAlive());
+}
+
+TEST_F(AppListShowerUnitTest, HidingViewRemovesKeepalive) {
+  shower_->ShowForProfile(profile1_.get());
+  shower_->DismissAppList();
+  EXPECT_FALSE(shower_->IsAppListVisible());
+  EXPECT_TRUE(shower_->HasView());
+  EXPECT_FALSE(HasKeepAlive());
+}
+
+TEST_F(AppListShowerUnitTest, HideAndShowReusesView) {
+  EXPECT_EQ(0, views_created_);
+  shower_->ShowForProfile(profile1_.get());
+  EXPECT_EQ(1, views_created_);
+  EXPECT_EQ(0, views_dismissed_);
+  shower_->DismissAppList();
+  EXPECT_EQ(1, views_dismissed_);
+  shower_->ShowForProfile(profile1_.get());
+  EXPECT_EQ(1, views_created_);
+}
+
+TEST_F(AppListShowerUnitTest, CloseAndShowRecreatesView) {
+  shower_->ShowForProfile(profile1_.get());
+  shower_->HandleViewBeingDestroyed();
+  // Destroying implies hiding. A separate notification shouldn't go out.
+  EXPECT_EQ(0, views_dismissed_);
+  shower_->ShowForProfile(profile1_.get());
+  EXPECT_EQ(2, views_created_);
+}
+
+TEST_F(AppListShowerUnitTest, CloseRemovesView) {
+  shower_->ShowForProfile(profile1_.get());
+  shower_->HandleViewBeingDestroyed();
+  EXPECT_FALSE(shower_->IsAppListVisible());
+  EXPECT_FALSE(shower_->HasView());
+  EXPECT_FALSE(HasKeepAlive());
+}
+
+TEST_F(AppListShowerUnitTest, CloseAppListClearsProfile) {
+  EXPECT_EQ(NULL, shower_->profile());
+  shower_->ShowForProfile(profile1_.get());
+  EXPECT_EQ(profile1_.get(), shower_->profile());
+  shower_->HandleViewBeingDestroyed();
+  EXPECT_EQ(NULL, shower_->profile());
+}
+
+TEST_F(AppListShowerUnitTest, SwitchingProfiles) {
+  shower_->ShowForProfile(profile1_.get());
+  EXPECT_EQ("p1", shower_->profile()->GetProfileName());
+  shower_->ShowForProfile(profile2_.get());
+  EXPECT_EQ("p2", shower_->profile()->GetProfileName());
+
+  // Shouldn't create new view for second profile - it should switch in place.
+  EXPECT_EQ(1, views_created_);
+  EXPECT_EQ(0, views_dismissed_);
+}
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.cc b/chrome/browser/ui/app_list/app_list_view_delegate.cc
index e9c2a50..2a3e219 100644
--- a/chrome/browser/ui/app_list/app_list_view_delegate.cc
+++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc
@@ -13,9 +13,10 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/feedback/feedback_util.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/search/hotword_service.h"
+#include "chrome/browser/search/hotword_service_factory.h"
 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
 #include "chrome/browser/ui/app_list/app_list_service.h"
 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
@@ -34,11 +35,16 @@
 #include "content/public/browser/page_navigator.h"
 #include "content/public/browser/user_metrics.h"
 #include "grit/theme_resources.h"
+#include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/app_list_view_delegate_observer.h"
 #include "ui/app_list/search_box_model.h"
 #include "ui/app_list/speech_ui_model.h"
 #include "ui/base/resource/resource_bundle.h"
 
+#if defined(USE_AURA)
+#include "ui/keyboard/keyboard_util.h"
+#endif
+
 #if defined(USE_ASH)
 #include "chrome/browser/ui/ash/app_list/app_sync_ui_state_watcher.h"
 #endif
@@ -47,6 +53,11 @@
 #include "chrome/browser/web_applications/web_app_win.h"
 #endif
 
+
+namespace chrome {
+const char kAppLauncherCategoryTag[] = "AppLauncher";
+}  // namespace chrome
+
 namespace {
 
 const int kAutoLaunchDefaultTimeoutMilliSec = 50;
@@ -143,6 +154,24 @@
   search_controller_.reset();
 }
 
+void AppListViewDelegate::OnHotwordStateChanged(bool started) {
+  if (started) {
+    if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_READY) {
+      OnSpeechRecognitionStateChanged(
+          app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING);
+    }
+  } else {
+    if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING)
+      OnSpeechRecognitionStateChanged(app_list::SPEECH_RECOGNITION_READY);
+  }
+}
+
+void AppListViewDelegate::OnHotwordRecognized() {
+  DCHECK_EQ(app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING,
+            speech_ui_->state());
+  ToggleSpeechRecognition();
+}
+
 void AppListViewDelegate::SigninManagerCreated(SigninManagerBase* manager) {
   scoped_observer_.Add(manager);
 }
@@ -290,8 +319,15 @@
 void AppListViewDelegate::ViewInitialized() {
   app_list::StartPageService* service =
       app_list::StartPageService::Get(profile_);
-  if (service)
+  if (service) {
     service->AppListShown();
+    if (service->HotwordEnabled()) {
+      HotwordService* hotword_service =
+          HotwordServiceFactory::GetForProfile(profile_);
+      if (hotword_service)
+        hotword_service->RequestHotwordSession(this);
+    }
+  }
 }
 
 void AppListViewDelegate::Dismiss()  {
@@ -303,8 +339,15 @@
 
   app_list::StartPageService* service =
       app_list::StartPageService::Get(profile_);
-  if (service)
+  if (service) {
     service->AppListHidden();
+    if (service->HotwordEnabled()) {
+      HotwordService* hotword_service =
+          HotwordServiceFactory::GetForProfile(profile_);
+      if (hotword_service)
+        hotword_service->StopHotwordSession(this);
+    }
+  }
 }
 
 gfx::ImageSkia AppListViewDelegate::GetWindowIcon() {
@@ -412,6 +455,21 @@
   return users_;
 }
 
+bool AppListViewDelegate::ShouldCenterWindow() const {
+  if (app_list::switches::IsCenteredAppListEnabled())
+    return true;
+
+  // keyboard depends upon Aura.
+#if defined(USE_AURA)
+  // If the virtual keyboard is enabled, use the new app list position. The old
+  // position is too tall, and doesn't fit in the left-over screen space.
+  if (keyboard::IsKeyboardEnabled())
+    return true;
+#endif
+
+  return false;
+}
+
 void AppListViewDelegate::AddObserver(
     app_list::AppListViewDelegateObserver* observer) {
   observers_.AddObserver(observer);
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.h b/chrome/browser/ui/app_list/app_list_view_delegate.h
index 945baab..60026af 100644
--- a/chrome/browser/ui/app_list/app_list_view_delegate.h
+++ b/chrome/browser/ui/app_list/app_list_view_delegate.h
@@ -14,6 +14,7 @@
 #include "base/observer_list.h"
 #include "base/scoped_observer.h"
 #include "chrome/browser/profiles/profile_info_cache_observer.h"
+#include "chrome/browser/search/hotword_client.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/ui/app_list/chrome_signin_delegate.h"
 #include "chrome/browser/ui/app_list/start_page_observer.h"
@@ -42,6 +43,7 @@
 
 class AppListViewDelegate : public app_list::AppListViewDelegate,
                             public app_list::StartPageObserver,
+                            public HotwordClient,
                             public ProfileInfoCacheObserver,
                             public SigninManagerBase::Observer,
                             public SigninManagerFactory::Observer {
@@ -86,6 +88,7 @@
   virtual content::WebContents* GetStartPageContents() OVERRIDE;
   virtual content::WebContents* GetSpeechRecognitionContents() OVERRIDE;
   virtual const Users& GetUsers() const OVERRIDE;
+  virtual bool ShouldCenterWindow() const OVERRIDE;
   virtual void AddObserver(
       app_list::AppListViewDelegateObserver* observer) OVERRIDE;
   virtual void RemoveObserver(
@@ -98,6 +101,10 @@
   virtual void OnSpeechRecognitionStateChanged(
       app_list::SpeechRecognitionState new_state) OVERRIDE;
 
+  // Overridden from HotwordClient:
+  virtual void OnHotwordStateChanged(bool started) OVERRIDE;
+  virtual void OnHotwordRecognized() OVERRIDE;
+
   // Overridden from SigninManagerFactory::Observer:
   virtual void SigninManagerCreated(SigninManagerBase* manager) OVERRIDE;
   virtual void SigninManagerShutdown(SigninManagerBase* manager) OVERRIDE;
diff --git a/chrome/browser/ui/app_list/search/common/webservice_search_provider.cc b/chrome/browser/ui/app_list/search/common/webservice_search_provider.cc
index 8b4318e..73bcf1db 100644
--- a/chrome/browser/ui/app_list/search/common/webservice_search_provider.cc
+++ b/chrome/browser/ui/app_list/search/common/webservice_search_provider.cc
@@ -90,7 +90,7 @@
   // Don't send anything for https except the hostname. Hostnames are OK
   // because they are visible when the TCP connection is established, but the
   // specific path may reveal private information.
-  if (LowerCaseEqualsASCII(query_as_url.scheme(), content::kHttpsScheme) &&
+  if (LowerCaseEqualsASCII(query_as_url.scheme(), url::kHttpsScheme) &&
       !query_as_url.path().empty() && query_as_url.path() != "/") {
     return true;
   }
diff --git a/chrome/browser/ui/app_list/search/omnibox_provider.cc b/chrome/browser/ui/app_list/search/omnibox_provider.cc
index 1793964..de71f00 100644
--- a/chrome/browser/ui/app_list/search/omnibox_provider.cc
+++ b/chrome/browser/ui/app_list/search/omnibox_provider.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/autocomplete/search_provider.h"
 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
 #include "chrome/browser/ui/browser_navigator.h"
-#include "chrome/common/metrics/proto/omnibox_event.pb.h"
+#include "components/metrics/proto/omnibox_event.pb.h"
 #include "grit/theme_resources.h"
 #include "ui/base/resource/resource_bundle.h"
 
diff --git a/chrome/browser/ui/app_list/start_page_service.cc b/chrome/browser/ui/app_list/start_page_service.cc
index 461e540..e574809 100644
--- a/chrome/browser/ui/app_list/start_page_service.cc
+++ b/chrome/browser/ui/app_list/start_page_service.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/media/media_stream_infobar_delegate.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search/hotword_service.h"
 #include "chrome/browser/search/hotword_service_factory.h"
 #include "chrome/browser/ui/app_list/recommended_apps.h"
 #include "chrome/browser/ui/app_list/start_page_observer.h"
@@ -104,14 +103,6 @@
       state_(app_list::SPEECH_RECOGNITION_OFF),
       speech_button_toggled_manually_(false),
       speech_result_obtained_(false) {
-#if defined(OS_CHROMEOS)
-  // Updates the default state to hotword listening, because this is
-  // the default behavior. This will be updated when the page is loaded and
-  // the nacl module is loaded.
-  if (app_list::switches::IsVoiceSearchEnabled())
-    state_ = app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING;
-#endif
-
   if (app_list::switches::IsExperimentalAppListEnabled())
     LoadContents();
 }
@@ -151,24 +142,8 @@
 
 bool StartPageService::HotwordEnabled() {
 #if defined(OS_CHROMEOS)
-  if (!HotwordService::DoesHotwordSupportLanguage(profile_))
-    return false;
-
-  const PrefService::Preference* preference =
-      profile_->GetPrefs()->FindPreference(prefs::kHotwordSearchEnabled);
-  if (!preference)
-    return false;
-
-  if (!HotwordServiceFactory::IsServiceAvailable(profile_))
-    return false;
-
-  // kHotwordSearchEnabled is off by default, but app-list is on by default.
-  // To achieve this, we'll return true if it's in the default status.
-  if (preference->IsDefaultValue())
-    return true;
-
-  bool isEnabled = false;
-  return preference->GetValue()->GetAsBoolean(&isEnabled) && isEnabled;
+  return HotwordServiceFactory::IsServiceAvailable(profile_) &&
+      profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled);
 #else
   return false;
 #endif
diff --git a/chrome/browser/ui/app_list/test/app_list_shower_unittest.cc b/chrome/browser/ui/app_list/test/app_list_shower_unittest.cc
deleted file mode 100644
index 0174963..0000000
--- a/chrome/browser/ui/app_list/test/app_list_shower_unittest.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// 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.
-
-#include "base/files/file_path.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/app_list/app_list.h"
-#include "chrome/browser/ui/app_list/app_list_factory.h"
-#include "chrome/browser/ui/app_list/app_list_shower.h"
-#include "chrome/browser/ui/app_list/scoped_keep_alive.h"
-#include "chrome/browser/ui/app_list/test/fake_profile.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-class FakeAppList : public AppList {
- public:
-  explicit FakeAppList(Profile* profile)
-      : profile_(profile) {
-  }
-
-  std::string profile_name() {
-    return profile_->GetProfileName();
-  }
-
-  // AppList overrides.
-  virtual void Show() OVERRIDE {
-    visible_ = true;
-  }
-
-  virtual void Hide() OVERRIDE {
-    visible_ = false;
-  }
-
-  virtual void MoveNearCursor() OVERRIDE {
-  }
-
-  virtual bool IsVisible() OVERRIDE {
-    return visible_;
-  }
-
-  virtual void Prerender() OVERRIDE {
-    prerendered_ = true;
-  }
-
-  virtual gfx::NativeWindow GetWindow() OVERRIDE {
-    return NULL;
-  }
-
-  virtual void SetProfile(Profile* profile) OVERRIDE {
-    profile_ = profile;
-  }
-
-  Profile* profile_;
-  bool visible_;
-  bool prerendered_;
-};
-
-class FakeFactory : public AppListFactory {
- public:
-  FakeFactory()
-      : views_created_(0) {
-  }
-
-  virtual AppList* CreateAppList(
-      Profile* profile,
-      AppListService* service,
-      const base::Closure& on_should_dismiss) OVERRIDE {
-    views_created_++;
-    return new FakeAppList(profile);
-  }
-
-  int views_created_;
-};
-
-class AppListShowerUnitTest : public testing::Test {
- public:
-  virtual void SetUp() OVERRIDE {
-    factory_ = new FakeFactory;
-    shower_.reset(
-        new AppListShower(scoped_ptr<AppListFactory>(factory_),
-                          NULL /* service */));
-    profile1_ = CreateProfile("p1").Pass();
-    profile2_ = CreateProfile("p2").Pass();
-  }
-
-  virtual void TearDown() OVERRIDE {
-  }
-
-  scoped_ptr<FakeProfile> CreateProfile(const std::string& name) {
-    return make_scoped_ptr(new FakeProfile(name));
-  }
-
-  FakeAppList* GetCurrentAppList() {
-    return static_cast<FakeAppList*>(shower_->app_list());
-  }
-
-  bool HasKeepAlive() const {
-    return shower_->keep_alive_.get() != NULL;
-  }
-
-  // Owned by |shower_|.
-  FakeFactory* factory_;
-  scoped_ptr<AppListShower> shower_;
-  scoped_ptr<FakeProfile> profile1_;
-  scoped_ptr<FakeProfile> profile2_;
-};
-
-TEST_F(AppListShowerUnitTest, Preconditions) {
-  EXPECT_FALSE(shower_->IsAppListVisible());
-  EXPECT_FALSE(shower_->HasView());
-  EXPECT_FALSE(HasKeepAlive());
-}
-
-TEST_F(AppListShowerUnitTest, ShowForProfilePutsViewOnScreen) {
-  shower_->ShowForProfile(profile1_.get());
-  EXPECT_TRUE(shower_->IsAppListVisible());
-  EXPECT_TRUE(shower_->HasView());
-  EXPECT_TRUE(HasKeepAlive());
-}
-
-TEST_F(AppListShowerUnitTest, HidingViewRemovesKeepalive) {
-  shower_->ShowForProfile(profile1_.get());
-  shower_->DismissAppList();
-  EXPECT_FALSE(shower_->IsAppListVisible());
-  EXPECT_TRUE(shower_->HasView());
-  EXPECT_FALSE(HasKeepAlive());
-}
-
-TEST_F(AppListShowerUnitTest, HideAndShowReusesView) {
-  shower_->ShowForProfile(profile1_.get());
-  shower_->DismissAppList();
-  shower_->ShowForProfile(profile1_.get());
-  EXPECT_EQ(1, factory_->views_created_);
-}
-
-TEST_F(AppListShowerUnitTest, CloseAndShowRecreatesView) {
-  shower_->ShowForProfile(profile1_.get());
-  shower_->HandleViewBeingDestroyed();
-  shower_->ShowForProfile(profile1_.get());
-  EXPECT_EQ(2, factory_->views_created_);
-}
-
-TEST_F(AppListShowerUnitTest, CloseRemovesView) {
-  shower_->ShowForProfile(profile1_.get());
-  shower_->HandleViewBeingDestroyed();
-  EXPECT_FALSE(shower_->IsAppListVisible());
-  EXPECT_FALSE(shower_->HasView());
-  EXPECT_FALSE(HasKeepAlive());
-}
-
-TEST_F(AppListShowerUnitTest, CloseAppListClearsProfile) {
-  EXPECT_EQ(NULL, shower_->profile());
-  shower_->ShowForProfile(profile1_.get());
-  EXPECT_EQ(profile1_.get(), shower_->profile());
-  shower_->HandleViewBeingDestroyed();
-  EXPECT_EQ(NULL, shower_->profile());
-}
-
-TEST_F(AppListShowerUnitTest, SwitchingProfiles) {
-  shower_->ShowForProfile(profile1_.get());
-  EXPECT_EQ("p1", GetCurrentAppList()->profile_name());
-  shower_->ShowForProfile(profile2_.get());
-  EXPECT_EQ("p2", GetCurrentAppList()->profile_name());
-
-  // Shouldn't create new view for second profile - it should switch in place.
-  EXPECT_EQ(1, factory_->views_created_);
-}
diff --git a/chrome/browser/ui/app_list/test/fake_profile.cc b/chrome/browser/ui/app_list/test/fake_profile.cc
index 41ebb25..3791b20 100644
--- a/chrome/browser/ui/app_list/test/fake_profile.cc
+++ b/chrome/browser/ui/app_list/test/fake_profile.cc
@@ -94,6 +94,11 @@
   return NULL;
 }
 
+content::BrowserPluginGuestManagerDelegate*
+FakeProfile::GetGuestManagerDelegate() {
+  return NULL;
+}
+
 quota::SpecialStoragePolicy* FakeProfile::GetSpecialStoragePolicy() {
   return NULL;
 }
diff --git a/chrome/browser/ui/app_list/test/fake_profile.h b/chrome/browser/ui/app_list/test/fake_profile.h
index 12ba769..6abdb2d 100644
--- a/chrome/browser/ui/app_list/test/fake_profile.h
+++ b/chrome/browser/ui/app_list/test/fake_profile.h
@@ -68,6 +68,8 @@
   virtual content::ResourceContext* GetResourceContext() OVERRIDE;
   virtual content::GeolocationPermissionContext*
       GetGeolocationPermissionContext() OVERRIDE;
+  virtual content::BrowserPluginGuestManagerDelegate*
+      GetGuestManagerDelegate() OVERRIDE;
   virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
   virtual scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() OVERRIDE;
   virtual Profile* GetOffTheRecordProfile() OVERRIDE;
diff --git a/chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.cc b/chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.cc
index 68fabac..a037376 100644
--- a/chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.cc
+++ b/chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.cc
@@ -7,7 +7,6 @@
 #include "chrome/browser/browser_shutdown.h"
 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/gfx/text_elider.h"
 
 #if defined(USE_AURA)
@@ -87,8 +86,7 @@
 }
 
 NativeAppModalDialog* JavaScriptAppModalDialog::CreateNativeDialog() {
-  gfx::NativeWindow parent_window =
-      web_contents()->GetView()->GetTopLevelNativeWindow();
+  gfx::NativeWindow parent_window = web_contents()->GetTopLevelNativeWindow();
 
 #if defined(USE_AURA)
   if (!parent_window->GetRootWindow()) {
diff --git a/chrome/browser/ui/apps/chrome_app_window_delegate.cc b/chrome/browser/ui/apps/chrome_app_window_delegate.cc
index b0ccf7e..3a72af3 100644
--- a/chrome/browser/ui/apps/chrome_app_window_delegate.cc
+++ b/chrome/browser/ui/apps/chrome_app_window_delegate.cc
@@ -22,7 +22,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/common/constants.h"
 
 #if defined(USE_ASH)
@@ -245,5 +244,5 @@
 
 bool ChromeAppWindowDelegate::IsWebContentsVisible(
     content::WebContents* web_contents) {
-  return platform_util::IsVisible(web_contents->GetView()->GetNativeView());
+  return platform_util::IsVisible(web_contents->GetNativeView());
 }
diff --git a/chrome/browser/ui/ash/accessibility/automation_manager_views.cc b/chrome/browser/ui/ash/accessibility/automation_manager_views.cc
index 92c8085..859704b 100644
--- a/chrome/browser/ui/ash/accessibility/automation_manager_views.cc
+++ b/chrome/browser/ui/ash/accessibility/automation_manager_views.cc
@@ -9,31 +9,35 @@
 #include "base/memory/singleton.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/api/automation_internal/automation_util.h"
-#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "content/public/browser/ax_event_notification_details.h"
+#include "content/public/browser/browser_context.h"
 #include "ui/views/accessibility/ax_aura_obj_cache.h"
 #include "ui/views/accessibility/ax_aura_obj_wrapper.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 
+using content::BrowserContext;
+
 // static
 AutomationManagerViews* AutomationManagerViews::GetInstance() {
   return Singleton<AutomationManagerViews>::get();
 }
 
-void AutomationManagerViews::Enable() {
+void AutomationManagerViews::Enable(BrowserContext* context) {
   enabled_ = true;
-  if (current_tree_serializer_.get())
-    current_tree_serializer_->Reset();
+  Reset();
+  SendEvent(context, current_tree_->GetRoot(), ui::AX_EVENT_LOAD_COMPLETE);
 }
 
 void AutomationManagerViews::Disable() {
   enabled_ = false;
+
+  // Reset the serializer to save memory.
   current_tree_serializer_->Reset();
 }
 
-void AutomationManagerViews::HandleEvent(Profile* profile,
+void AutomationManagerViews::HandleEvent(BrowserContext* context,
                                          views::View* view,
                                          ui::AXEvent event_type) {
   if (!enabled_) {
@@ -46,30 +50,40 @@
   if (!widget)
     return;
 
-  if (!profile && g_browser_process->profile_manager()) {
-    profile = g_browser_process->profile_manager()->GetLastUsedProfile();
+  if (!context && g_browser_process->profile_manager()) {
+    context = g_browser_process->profile_manager()->GetLastUsedProfile();
   }
-  if (!profile) {
-    LOG(WARNING) << "Accessibility notification but no profile";
+  if (!context) {
+    LOG(WARNING) << "Accessibility notification but no browser context";
     return;
   }
 
-  if (!current_tree_.get()) {
-    current_tree_.reset(new AXTreeSourceViews());
-    current_tree_serializer_.reset(
-        new ui::AXTreeSerializer<views::AXAuraObjWrapper*>(
-            current_tree_.get()));
-  }
-
-  ui::AXTreeUpdate out_update;
   views::AXAuraObjWrapper* aura_obj =
       views::AXAuraObjCache::GetInstance()->GetOrCreate(view);
-  current_tree_serializer_->SerializeChanges(aura_obj, &out_update);
+  SendEvent(context, aura_obj, event_type);
+}
+
+AutomationManagerViews::AutomationManagerViews() : enabled_(false) {}
+
+AutomationManagerViews::~AutomationManagerViews() {}
+
+void AutomationManagerViews::Reset() {
+  current_tree_.reset(new AXTreeSourceViews());
+  current_tree_serializer_.reset(
+      new ui::AXTreeSerializer<views::AXAuraObjWrapper*>(
+          current_tree_.get()));
+}
+
+void AutomationManagerViews::SendEvent(BrowserContext* context,
+                                       views::AXAuraObjWrapper* aura_obj,
+                                       ui::AXEvent event_type) {
+  ui::AXTreeUpdate update;
+  current_tree_serializer_->SerializeChanges(aura_obj, &update);
 
   // Route this event to special process/routing ids recognized by the
   // Automation API as the desktop tree.
   // TODO(dtseng): Would idealy define these special desktop constants in idl.
-  content::AXEventNotificationDetails detail(out_update.nodes,
+  content::AXEventNotificationDetails detail(update.nodes,
                                              event_type,
                                              aura_obj->GetID(),
                                              0, /* process_id */
@@ -77,9 +91,5 @@
   std::vector<content::AXEventNotificationDetails> details;
   details.push_back(detail);
   extensions::automation_util::DispatchAccessibilityEventsToAutomation(
-      details, profile);
+      details, context);
 }
-
-AutomationManagerViews::AutomationManagerViews() : enabled_(false) {}
-
-AutomationManagerViews::  ~AutomationManagerViews() {}
diff --git a/chrome/browser/ui/ash/accessibility/automation_manager_views.h b/chrome/browser/ui/ash/accessibility/automation_manager_views.h
index af34ff7..f9a1543 100644
--- a/chrome/browser/ui/ash/accessibility/automation_manager_views.h
+++ b/chrome/browser/ui/ash/accessibility/automation_manager_views.h
@@ -13,7 +13,9 @@
 
 template <typename T> struct DefaultSingletonTraits;
 
-class Profile;
+namespace content {
+class BrowserContext;
+}  // namespace content
 
 namespace views {
 class AXAuraObjWrapper;
@@ -27,13 +29,15 @@
   static AutomationManagerViews* GetInstance();
 
   // Enable automation support for views.
-  void Enable();
+  void Enable(content::BrowserContext* context);
 
   // Disable automation support for views.
   void Disable();
 
   // Handle an event fired upon a |View|.
-  void HandleEvent(Profile* profile, views::View* view, ui::AXEvent event_type);
+  void HandleEvent(content::BrowserContext* context,
+                   views::View* view,
+                   ui::AXEvent event_type);
 
  private:
   friend struct DefaultSingletonTraits<AutomationManagerViews>;
@@ -41,7 +45,14 @@
   AutomationManagerViews();
   ~AutomationManagerViews();
 
-  // Whether Views-based automation is enabled.
+    // Reset all state in this manager.
+  void Reset();
+
+  void SendEvent(content::BrowserContext* context,
+                 views::AXAuraObjWrapper* aura_obj,
+                 ui::AXEvent event_type);
+
+  // Whether automation support for views is enabled.
   bool enabled_;
 
   // Holds the active views-based accessibility tree. A tree currently consists
diff --git a/chrome/browser/ui/ash/accessibility/ax_root_obj_wrapper.cc b/chrome/browser/ui/ash/accessibility/ax_root_obj_wrapper.cc
index 39a5b8d..0a2246a 100644
--- a/chrome/browser/ui/ash/accessibility/ax_root_obj_wrapper.cc
+++ b/chrome/browser/ui/ash/accessibility/ax_root_obj_wrapper.cc
@@ -27,6 +27,9 @@
 
 void AXRootObjWrapper::GetChildren(
     std::vector<views::AXAuraObjWrapper*>* out_children) {
+  if (!ash::Shell::HasInstance())
+    return;
+
   // Only on ash is there a notion of a root with children.
   aura::Window::Windows children =
       ash::Shell::GetInstance()->GetAllRootWindows();
diff --git a/chrome/browser/ui/ash/ash_keyboard_controller_proxy.cc b/chrome/browser/ui/ash/ash_keyboard_controller_proxy.cc
index 8c5dfb4..356afd1 100644
--- a/chrome/browser/ui/ash/ash_keyboard_controller_proxy.cc
+++ b/chrome/browser/ui/ash/ash_keyboard_controller_proxy.cc
@@ -14,7 +14,6 @@
 #include "chrome/common/extensions/api/virtual_keyboard_private.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_function_dispatcher.h"
 #include "extensions/browser/extension_system.h"
diff --git a/chrome/browser/ui/ash/chrome_new_window_delegate_chromeos.cc b/chrome/browser/ui/ash/chrome_new_window_delegate_chromeos.cc
index acf1be1..81916fe 100644
--- a/chrome/browser/ui/ash/chrome_new_window_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/chrome_new_window_delegate_chromeos.cc
@@ -19,7 +19,6 @@
 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_system.h"
 
 ChromeNewWindowDelegateChromeos::ChromeNewWindowDelegateChromeos() {}
@@ -64,7 +63,7 @@
                              false));
   browser->window()->Show();
   browser->window()->Activate();
-  page->GetView()->Focus();
+  page->Focus();
 }
 
 void ChromeNewWindowDelegateChromeos::ShowKeyboardOverlay() {
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc
index 3bfe3df..138ad5a 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc
@@ -7,7 +7,6 @@
 #include "ash/accelerators/magnifier_key_scroller.h"
 #include "ash/accelerators/spoken_feedback_toggler.h"
 #include "ash/accessibility_delegate.h"
-#include "ash/media_delegate.h"
 #include "ash/wm/mru_window_tracker.h"
 #include "ash/wm/window_util.h"
 #include "base/command_line.h"
@@ -20,8 +19,6 @@
 #include "chrome/browser/chromeos/background/ash_user_wallpaper_delegate.h"
 #include "chrome/browser/chromeos/display/display_configuration_observer.h"
 #include "chrome/browser/chromeos/display/display_preferences.h"
-#include "chrome/browser/chromeos/extensions/media_player_api.h"
-#include "chrome/browser/chromeos/extensions/media_player_event_router.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -29,6 +26,7 @@
 #include "chrome/browser/speech/tts_controller.h"
 #include "chrome/browser/sync/sync_error_notifier_factory_ash.h"
 #include "chrome/browser/ui/ash/chrome_new_window_delegate_chromeos.h"
+#include "chrome/browser/ui/ash/media_delegate_chromeos.h"
 #include "chrome/browser/ui/ash/session_state_delegate_chromeos.h"
 #include "chrome/browser/ui/ash/system_tray_delegate_chromeos.h"
 #include "chrome/browser/ui/browser.h"
@@ -209,33 +207,6 @@
   DISALLOW_COPY_AND_ASSIGN(AccessibilityDelegateImpl);
 };
 
-class MediaDelegateImpl : public ash::MediaDelegate {
- public:
-  MediaDelegateImpl() {}
-  virtual ~MediaDelegateImpl() {}
-
-  virtual void HandleMediaNextTrack() OVERRIDE {
-    extensions::MediaPlayerAPI::Get(
-        ProfileManager::GetActiveUserProfile())->
-            media_player_event_router()->NotifyNextTrack();
-  }
-
-  virtual void HandleMediaPlayPause() OVERRIDE {
-    extensions::MediaPlayerAPI::Get(
-        ProfileManager::GetActiveUserProfile())->
-            media_player_event_router()->NotifyTogglePlayState();
-  }
-
-  virtual void HandleMediaPrevTrack() OVERRIDE {
-    extensions::MediaPlayerAPI::Get(
-        ProfileManager::GetActiveUserProfile())->
-            media_player_event_router()->NotifyPrevTrack();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MediaDelegateImpl);
-};
-
 }  // anonymous namespace
 
 bool ChromeShellDelegate::IsFirstRunAfterBoot() const {
@@ -268,7 +239,7 @@
 }
 
 ash::MediaDelegate* ChromeShellDelegate::CreateMediaDelegate() {
-  return new MediaDelegateImpl;
+  return new MediaDelegateChromeOS;
 }
 
 ash::SystemTrayDelegate* ChromeShellDelegate::CreateSystemTrayDelegate() {
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate_views.cc b/chrome/browser/ui/ash/chrome_shell_delegate_views.cc
index 1ce1cc0..3522aa5 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate_views.cc
+++ b/chrome/browser/ui/ash/chrome_shell_delegate_views.cc
@@ -61,6 +61,10 @@
   virtual void HandleMediaNextTrack() OVERRIDE {}
   virtual void HandleMediaPlayPause() OVERRIDE {}
   virtual void HandleMediaPrevTrack() OVERRIDE {}
+  virtual ash::MediaCaptureState GetMediaCaptureState(
+      content::BrowserContext* context) OVERRIDE {
+    return ash::MEDIA_CAPTURE_NONE;
+  }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MediaDelegateImpl);
diff --git a/chrome/browser/ui/ash/launcher/app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/app_window_launcher_controller.cc
index e12e8bb..6dacb2e 100644
--- a/chrome/browser/ui/ash/launcher/app_window_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/app_window_launcher_controller.cc
@@ -25,7 +25,7 @@
 std::string GetAppShelfId(AppWindow* app_window) {
   if (app_window->window_type_is_panel())
     return base::StringPrintf("panel:%d", app_window->session_id().id());
-  return app_window->extension()->id();
+  return app_window->extension_id();
 }
 
 bool ControlsWindow(aura::Window* window) {
@@ -84,12 +84,6 @@
   registry_.insert(registry);
 }
 
-void AppWindowLauncherController::OnAppWindowAdded(AppWindow* app_window) {
-  if (!ControlsWindow(app_window->GetNativeWindow()))
-    return;
-  RegisterApp(app_window);
-}
-
 void AppWindowLauncherController::OnAppWindowIconChanged(
     AppWindow* app_window) {
   if (!ControlsWindow(app_window->GetNativeWindow()))
@@ -105,9 +99,22 @@
                                app_window->app_icon().AsImageSkia());
 }
 
-void AppWindowLauncherController::OnAppWindowRemoved(AppWindow* app_window) {
-  // Do nothing here; app_window->window() has already been deleted and
-  // OnWindowDestroying() has been called, doing the removal.
+void AppWindowLauncherController::OnAppWindowShown(AppWindow* app_window) {
+  aura::Window* window = app_window->GetNativeWindow();
+  if (!ControlsWindow(window))
+    return;
+
+  if (!IsRegisteredApp(window))
+    RegisterApp(app_window);
+}
+
+void AppWindowLauncherController::OnAppWindowHidden(AppWindow* app_window) {
+  aura::Window* window = app_window->GetNativeWindow();
+  if (!ControlsWindow(window))
+    return;
+
+  if (IsRegisteredApp(window))
+    UnregisterApp(window);
 }
 
 // Called from aura::Window::~Window(), before delegate_->OnWindowDestroyed()
@@ -146,7 +153,7 @@
   window->AddObserver(this);
 
   // Find or create an item controller and launcher item.
-  std::string app_id = app_window->extension()->id();
+  std::string app_id = app_window->extension_id();
   ash::ShelfItemStatus status = ash::wm::IsActiveWindow(window)
                                     ? ash::STATUS_ACTIVE
                                     : ash::STATUS_RUNNING;
diff --git a/chrome/browser/ui/ash/launcher/app_window_launcher_controller.h b/chrome/browser/ui/ash/launcher/app_window_launcher_controller.h
index 5f51a62..98dc5ea 100644
--- a/chrome/browser/ui/ash/launcher/app_window_launcher_controller.h
+++ b/chrome/browser/ui/ash/launcher/app_window_launcher_controller.h
@@ -50,9 +50,9 @@
   virtual void AdditionalUserAddedToSession(Profile* profile);
 
   // Overridden from AppWindowRegistry::Observer:
-  virtual void OnAppWindowAdded(apps::AppWindow* app_window) OVERRIDE;
   virtual void OnAppWindowIconChanged(apps::AppWindow* app_window) OVERRIDE;
-  virtual void OnAppWindowRemoved(apps::AppWindow* app_window) OVERRIDE;
+  virtual void OnAppWindowShown(apps::AppWindow* app_window) OVERRIDE;
+  virtual void OnAppWindowHidden(apps::AppWindow* app_window) OVERRIDE;
 
   // Overriden from aura::WindowObserver:
   virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
diff --git a/chrome/browser/ui/ash/launcher/browser_status_monitor.cc b/chrome/browser/ui/ash/launcher/browser_status_monitor.cc
index f10792c..36b1935 100644
--- a/chrome/browser/ui/ash/launcher/browser_status_monitor.cc
+++ b/chrome/browser/ui/ash/launcher/browser_status_monitor.cc
@@ -60,14 +60,11 @@
       monitor_->SetShelfIDForBrowserWindowContents(browser, web_contents());
   }
 
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_content) OVERRIDE {
-    if (web_content == web_contents()) {
-      // We can only come here when there was a non standard termination like
-      // an app got un-installed while running, etc.
-      monitor_->WebContentsDestroyed(web_content);
-      // |this| is gone now.
-    }
+  virtual void WebContentsDestroyed() OVERRIDE {
+    // We can only come here when there was a non standard termination like
+    // an app got un-installed while running, etc.
+    monitor_->WebContentsDestroyed(web_contents());
+    // |this| is gone now.
   }
 
  private:
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
index e744037..9f073ac 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -84,6 +84,7 @@
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/keyboard/keyboard_util.h"
 #include "ui/wm/core/window_animations.h"
 
 #if defined(OS_CHROMEOS)
@@ -1102,6 +1103,9 @@
   RestoreUnpinnedRunningApplicationOrder(user_email);
   // Inform the system tray of the change.
   ash::Shell::GetInstance()->system_tray_delegate()->ActiveUserWasChanged();
+  // Force on-screen keyboard to reset.
+  if (keyboard::IsKeyboardEnabled())
+    ash::Shell::GetInstance()->CreateKeyboard();
 }
 
 void ChromeLauncherController::AdditionalUserAddedToSession(Profile* profile) {
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
index 02ff9a0..12a1133 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
@@ -41,6 +41,7 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/settings_window_manager.h"
@@ -91,14 +92,10 @@
   }
 
   // Overridden from AppWindowRegistry::Observer:
-  virtual void OnAppWindowAdded(AppWindow* app_window) OVERRIDE {}
-
   virtual void OnAppWindowIconChanged(AppWindow* app_window) OVERRIDE {
     ++icon_updates_;
   }
 
-  virtual void OnAppWindowRemoved(AppWindow* app_window) OVERRIDE {}
-
   int icon_updates() { return icon_updates_; }
 
  private:
@@ -1381,6 +1378,43 @@
   EXPECT_EQ(item_count, shelf_model()->item_count());
 }
 
+// Test that we get correct shelf presence with hidden app windows.
+IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest, HiddenAppWindows) {
+  int item_count = shelf_model()->item_count();
+  const Extension* extension = LoadAndLaunchPlatformApp("launch");
+  AppWindow::CreateParams params;
+
+  // Create a hidden window.
+  params.hidden = true;
+  AppWindow* window_1 = CreateAppWindowFromParams(extension, params);
+  EXPECT_EQ(item_count, shelf_model()->item_count());
+
+  // Create a visible window.
+  params.hidden = false;
+  AppWindow* window_2 = CreateAppWindowFromParams(extension, params);
+  ++item_count;
+  EXPECT_EQ(item_count, shelf_model()->item_count());
+
+  // Minimize the visible window.
+  window_2->Minimize();
+  EXPECT_EQ(item_count, shelf_model()->item_count());
+
+  // Hide the visible window.
+  window_2->Hide();
+  --item_count;
+  EXPECT_EQ(item_count, shelf_model()->item_count());
+
+  // Show the originally hidden window.
+  window_1->Show(AppWindow::SHOW_ACTIVE);
+  ++item_count;
+  EXPECT_EQ(item_count, shelf_model()->item_count());
+
+  // Close the originally hidden window.
+  CloseAppWindow(window_1);
+  --item_count;
+  EXPECT_EQ(item_count, shelf_model()->item_count());
+}
+
 // Test attention states of windows.
 IN_PROC_BROWSER_TEST_F(LauncherPlatformAppBrowserTest, WindowAttentionStatus) {
   const Extension* extension = LoadAndLaunchPlatformApp("launch");
@@ -2045,7 +2079,9 @@
 
   // Open a settings window. Number of browser items should remain unchanged,
   // number of shelf items should increase.
-  settings_manager->ShowForProfile(browser()->profile(), std::string());
+  settings_manager->ShowChromePageForProfile(
+      browser()->profile(),
+      chrome::GetSettingsUrl(std::string()));
   Browser* settings_browser =
       settings_manager->FindBrowserForProfile(browser()->profile());
   ASSERT_TRUE(settings_browser);
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
index 8d9c413..887cf81 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -683,8 +683,7 @@
 
  private:
   // Overridden WebContentsObserver methods.
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     message_loop_runner_->Quit();
   }
 
@@ -2303,6 +2302,80 @@
   EXPECT_FALSE(v2_app_5.window()->GetNativeWindow()->IsVisible());
   SwitchActiveUser(profile1->GetProfileName());
   EXPECT_TRUE(v2_app_5.window()->GetNativeWindow()->IsVisible());
+
+  // Switching to desktop #2, hiding the app window and creating an app should
+  // teleport there automatically.
+  SwitchActiveUser(profile2->GetProfileName());
+  v2_app_1.window()->Hide();
+  V2App v2_app_6(profile1, extension1_);
+  EXPECT_FALSE(v2_app_1.window()->GetNativeWindow()->IsVisible());
+  EXPECT_FALSE(v2_app_2.window()->GetNativeWindow()->IsVisible());
+  EXPECT_TRUE(v2_app_6.window()->GetNativeWindow()->IsVisible());
+}
+
+// Check that V2 applications hide correctly on the shelf when the app window
+// is hidden.
+TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerTest,
+       V2AppHiddenWindows) {
+  InitLauncherController();
+
+  TestingProfile* profile2 = CreateMultiUserProfile("user-2");
+  SwitchActiveUser(profile()->GetProfileName());
+  EXPECT_EQ(2, model_->item_count());
+
+  V2App v2_app_1(profile(), extension1_);
+  EXPECT_EQ(3, model_->item_count());
+  {
+    // Hide and show the app.
+    v2_app_1.window()->Hide();
+    EXPECT_EQ(2, model_->item_count());
+
+    v2_app_1.window()->Show(apps::AppWindow::SHOW_ACTIVE);
+    EXPECT_EQ(3, model_->item_count());
+  }
+  {
+    // Switch user, hide and show the app and switch back.
+    SwitchActiveUser(profile2->GetProfileName());
+    EXPECT_EQ(2, model_->item_count());
+
+    v2_app_1.window()->Hide();
+    EXPECT_EQ(2, model_->item_count());
+
+    v2_app_1.window()->Show(apps::AppWindow::SHOW_ACTIVE);
+    EXPECT_EQ(2, model_->item_count());
+
+    SwitchActiveUser(profile()->GetProfileName());
+    EXPECT_EQ(3, model_->item_count());
+  }
+  {
+    // Switch user, hide the app, switch back and then show it again.
+    SwitchActiveUser(profile2->GetProfileName());
+    EXPECT_EQ(2, model_->item_count());
+
+    v2_app_1.window()->Hide();
+    EXPECT_EQ(2, model_->item_count());
+
+    SwitchActiveUser(profile()->GetProfileName());
+    EXPECT_EQ(2, model_->item_count());
+
+    v2_app_1.window()->Show(apps::AppWindow::SHOW_ACTIVE);
+    EXPECT_EQ(3, model_->item_count());
+  }
+  {
+    // Create a second app, hide and show it and then hide both apps.
+    V2App v2_app_2(profile(), extension1_);
+    EXPECT_EQ(3, model_->item_count());
+
+    v2_app_2.window()->Hide();
+    EXPECT_EQ(3, model_->item_count());
+
+    v2_app_2.window()->Show(apps::AppWindow::SHOW_ACTIVE);
+    EXPECT_EQ(3, model_->item_count());
+
+    v2_app_1.window()->Hide();
+    v2_app_2.window()->Hide();
+    EXPECT_EQ(2, model_->item_count());
+  }
 }
 #endif  // defined(OS_CHROMEOS)
 
diff --git a/chrome/browser/ui/ash/launcher/launcher_favicon_loader.cc b/chrome/browser/ui/ash/launcher/launcher_favicon_loader.cc
index d1fc953..e6c84bb 100644
--- a/chrome/browser/ui/ash/launcher/launcher_favicon_loader.cc
+++ b/chrome/browser/ui/ash/launcher/launcher_favicon_loader.cc
@@ -41,7 +41,6 @@
 
   // content::WebContentObserver implementation.
   virtual void DidUpdateFaviconURL(
-    int32 page_id,
     const std::vector<content::FaviconURL>& candidates) OVERRIDE;
 
  private:
@@ -73,7 +72,6 @@
 };
 
 void FaviconBitmapHandler::DidUpdateFaviconURL(
-    int32 page_id,
     const std::vector<content::FaviconURL>& candidates) {
   // This function receives a complete list of faviocn urls for the page.
   // It may get called multiple times with the same list, and will also get
diff --git a/chrome/browser/ui/ash/launcher/launcher_favicon_loader_browsertest.cc b/chrome/browser/ui/ash/launcher/launcher_favicon_loader_browsertest.cc
index e408851..a13cc50 100644
--- a/chrome/browser/ui/ash/launcher/launcher_favicon_loader_browsertest.cc
+++ b/chrome/browser/ui/ash/launcher/launcher_favicon_loader_browsertest.cc
@@ -47,7 +47,7 @@
     loaded_ = true;
   }
 
-  virtual void DidUpdateFaviconURL(int32 page_id,
+  virtual void DidUpdateFaviconURL(
       const std::vector<content::FaviconURL>& candidates) OVERRIDE {
     if (!candidates.empty())
       got_favicons_ = true;
diff --git a/chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.cc
index 4f44d57..d7f7233 100644
--- a/chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.h"
 
 #include "apps/app_window.h"
+#include "apps/ui/native_app_window.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
@@ -57,7 +58,9 @@
     Profile* profile =
         Profile::FromBrowserContext(app_window->browser_context());
     if (multi_user_util::IsProfileFromActiveUser(profile) &&
-        !IsRegisteredApp(app_window->GetNativeWindow()))
+        !IsRegisteredApp(app_window->GetNativeWindow()) &&
+        (app_window->GetBaseWindow()->IsMinimized() ||
+         app_window->GetNativeWindow()->IsVisible()))
       RegisterApp(*it);
   }
 }
@@ -74,25 +77,50 @@
     apps::AppWindow* app_window) {
   if (!ControlsWindow(app_window->GetNativeWindow()))
     return;
+
   app_window_list_.push_back(app_window);
   Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
-  if (multi_user_util::IsProfileFromActiveUser(profile)) {
+  // If the window got created for a non active user but the user allowed to
+  // teleport to the current user's desktop, we teleport it now.
+  if (!multi_user_util::IsProfileFromActiveUser(profile) &&
+      UserHasAppOnActiveDesktop(app_window)) {
+    chrome::MultiUserWindowManager::GetInstance()->ShowWindowForUser(
+        app_window->GetNativeWindow(), multi_user_util::GetCurrentUserId());
+  }
+}
+
+void MultiProfileAppWindowLauncherController::OnAppWindowShown(
+    apps::AppWindow* app_window) {
+  if (!ControlsWindow(app_window->GetNativeWindow()))
+    return;
+
+  Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
+
+  if (multi_user_util::IsProfileFromActiveUser(profile) &&
+      !IsRegisteredApp(app_window->GetNativeWindow())) {
     RegisterApp(app_window);
-  } else {
-    // If the window got created for a non active user but the user allowed to
-    // teleport to the current user's desktop, we teleport it now.
-    if (UserHasAppOnActiveDesktop(app_window)) {
-      chrome::MultiUserWindowManager::GetInstance()->ShowWindowForUser(
-          app_window->GetNativeWindow(),
-          multi_user_util::GetCurrentUserId());
-      if (app_window->GetNativeWindow()->type() == ui::wm::WINDOW_TYPE_PANEL &&
-          !app_window->GetNativeWindow()->layer()->GetTargetOpacity()) {
-        // The panel layout manager only manages windows which are anchored.
-        // Since this window did never had an anchor, it would stay hidden. We
-        // therefore make it visible now.
-        app_window->GetNativeWindow()->layer()->SetOpacity(1.0f);
-      }
-    }
+    return;
+  }
+
+  // The panel layout manager only manages windows which are anchored.
+  // Since this window did never had an anchor, it would stay hidden. We
+  // therefore make it visible now.
+  if (UserHasAppOnActiveDesktop(app_window) &&
+      app_window->GetNativeWindow()->type() == ui::wm::WINDOW_TYPE_PANEL &&
+      !app_window->GetNativeWindow()->layer()->GetTargetOpacity()) {
+    app_window->GetNativeWindow()->layer()->SetOpacity(1.0f);
+  }
+}
+
+void MultiProfileAppWindowLauncherController::OnAppWindowHidden(
+    apps::AppWindow* app_window) {
+  if (!ControlsWindow(app_window->GetNativeWindow()))
+    return;
+
+  Profile* profile = Profile::FromBrowserContext(app_window->browser_context());
+  if (multi_user_util::IsProfileFromActiveUser(profile) &&
+      IsRegisteredApp(app_window->GetNativeWindow())) {
+    UnregisterApp(app_window->GetNativeWindow());
   }
 }
 
diff --git a/chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.h b/chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.h
index c31862c..546cdbe 100644
--- a/chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.h
+++ b/chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.h
@@ -23,6 +23,8 @@
   // Overridden from AppWindowRegistry::Observer:
   virtual void OnAppWindowAdded(apps::AppWindow* app_window) OVERRIDE;
   virtual void OnAppWindowRemoved(apps::AppWindow* app_window) OVERRIDE;
+  virtual void OnAppWindowShown(apps::AppWindow* app_window) OVERRIDE;
+  virtual void OnAppWindowHidden(apps::AppWindow* app_window) OVERRIDE;
 
  private:
   typedef std::vector<apps::AppWindow*> AppWindowList;
diff --git a/chrome/browser/ui/ash/media_delegate_chromeos.cc b/chrome/browser/ui/ash/media_delegate_chromeos.cc
new file mode 100644
index 0000000..ff92c70
--- /dev/null
+++ b/chrome/browser/ui/ash/media_delegate_chromeos.cc
@@ -0,0 +1,173 @@
+// 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.
+
+#include "chrome/browser/ui/ash/media_delegate_chromeos.h"
+
+#include "apps/app_window.h"
+#include "apps/app_window_registry.h"
+#include "ash/shell.h"
+#include "ash/system/tray/system_tray_notifier.h"
+#include "base/message_loop/message_loop.h"
+#include "chrome/browser/chromeos/extensions/media_player_api.h"
+#include "chrome/browser/chromeos/extensions/media_player_event_router.h"
+#include "chrome/browser/media/media_stream_capture_indicator.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/web_contents.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/process_manager.h"
+
+namespace {
+
+void GetMediaCaptureState(
+    const MediaStreamCaptureIndicator* indicator,
+    content::WebContents* web_contents,
+    int* media_state_out) {
+  if (indicator->IsCapturingVideo(web_contents))
+    *media_state_out |= ash::MEDIA_CAPTURE_VIDEO;
+  if (indicator->IsCapturingAudio(web_contents))
+    *media_state_out |= ash::MEDIA_CAPTURE_AUDIO;
+}
+
+void GetBrowserMediaCaptureState(
+    const MediaStreamCaptureIndicator* indicator,
+    const content::BrowserContext* context,
+    int* media_state_out) {
+
+  const BrowserList* desktop_list =
+      BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
+
+  for (BrowserList::BrowserVector::const_iterator iter = desktop_list->begin();
+       iter != desktop_list->end();
+       ++iter) {
+    TabStripModel* tab_strip_model = (*iter)->tab_strip_model();
+    for (int i = 0; i < tab_strip_model->count(); ++i) {
+      content::WebContents* web_contents = tab_strip_model->GetWebContentsAt(i);
+      if (web_contents->GetBrowserContext() != context)
+        continue;
+      GetMediaCaptureState(indicator, web_contents, media_state_out);
+      if (*media_state_out == ash::MEDIA_CAPTURE_AUDIO_VIDEO)
+        return;
+    }
+  }
+}
+
+void GetAppMediaCaptureState(
+    const MediaStreamCaptureIndicator* indicator,
+    content::BrowserContext* context,
+    int* media_state_out) {
+  const apps::AppWindowRegistry::AppWindowList& apps =
+      apps::AppWindowRegistry::Get(context)->app_windows();
+  for (apps::AppWindowRegistry::AppWindowList::const_iterator iter =
+           apps.begin();
+       iter != apps.end();
+       ++iter) {
+    GetMediaCaptureState(indicator, (*iter)->web_contents(), media_state_out);
+    if (*media_state_out == ash::MEDIA_CAPTURE_AUDIO_VIDEO)
+      return;
+  }
+}
+
+void GetExtensionMediaCaptureState(
+    const MediaStreamCaptureIndicator* indicator,
+    content::BrowserContext* context,
+    int* media_state_out) {
+  extensions::ProcessManager* process_manager =
+      extensions::ExtensionSystem::Get(context)->process_manager();
+  const extensions::ProcessManager::ViewSet view_set =
+      process_manager->GetAllViews();
+  for (extensions::ProcessManager::ViewSet::const_iterator iter =
+           view_set.begin();
+       iter != view_set.end();
+       ++iter) {
+    content::WebContents* web_contents =
+        content::WebContents::FromRenderViewHost(*iter);
+    // RVH may not have web contents.
+    if (!web_contents)
+      continue;
+    GetMediaCaptureState(indicator, web_contents, media_state_out);
+    if (*media_state_out == ash::MEDIA_CAPTURE_AUDIO_VIDEO)
+      return;
+  }
+}
+
+ash::MediaCaptureState GetMediaCaptureStateOfAllWebContents(
+    content::BrowserContext* context) {
+  if (!context)
+    return ash::MEDIA_CAPTURE_NONE;
+
+  scoped_refptr<MediaStreamCaptureIndicator> indicator =
+      MediaCaptureDevicesDispatcher::GetInstance()
+          ->GetMediaStreamCaptureIndicator();
+
+  int media_state = ash::MEDIA_CAPTURE_NONE;
+  // Browser windows
+  GetBrowserMediaCaptureState(indicator.get(), context, &media_state);
+  if (media_state == ash::MEDIA_CAPTURE_AUDIO_VIDEO)
+    return ash::MEDIA_CAPTURE_AUDIO_VIDEO;
+
+  // App windows
+  GetAppMediaCaptureState(indicator.get(), context, &media_state);
+  if (media_state == ash::MEDIA_CAPTURE_AUDIO_VIDEO)
+    return ash::MEDIA_CAPTURE_AUDIO_VIDEO;
+
+  // Extensions
+  GetExtensionMediaCaptureState(indicator.get(), context, &media_state);
+
+  return static_cast<ash::MediaCaptureState>(media_state);
+}
+
+}  // namespace
+
+MediaDelegateChromeOS::MediaDelegateChromeOS() : weak_ptr_factory_(this) {
+  MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this);
+}
+
+MediaDelegateChromeOS::~MediaDelegateChromeOS() {
+  MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this);
+}
+
+void MediaDelegateChromeOS::HandleMediaNextTrack() {
+  extensions::MediaPlayerAPI::Get(ProfileManager::GetActiveUserProfile())
+      ->media_player_event_router()
+      ->NotifyNextTrack();
+}
+
+void MediaDelegateChromeOS::HandleMediaPlayPause() {
+  extensions::MediaPlayerAPI::Get(ProfileManager::GetActiveUserProfile())
+      ->media_player_event_router()
+      ->NotifyTogglePlayState();
+}
+
+void MediaDelegateChromeOS::HandleMediaPrevTrack() {
+  extensions::MediaPlayerAPI::Get(ProfileManager::GetActiveUserProfile())
+      ->media_player_event_router()
+      ->NotifyPrevTrack();
+}
+
+ash::MediaCaptureState MediaDelegateChromeOS::GetMediaCaptureState(
+    content::BrowserContext* context) {
+  return GetMediaCaptureStateOfAllWebContents(context);
+}
+
+void MediaDelegateChromeOS::OnRequestUpdate(
+    int render_process_id,
+    int render_view_id,
+    const content::MediaStreamDevice& device,
+    const content::MediaRequestState state) {
+  base::MessageLoopForUI::current()->PostTask(
+      FROM_HERE,
+      base::Bind(&MediaDelegateChromeOS::NotifyMediaCaptureChange,
+                 weak_ptr_factory_.GetWeakPtr()));
+}
+
+void MediaDelegateChromeOS::NotifyMediaCaptureChange() {
+  ash::Shell::GetInstance()
+      ->system_tray_notifier()
+      ->NotifyMediaCaptureChanged();
+}
diff --git a/chrome/browser/ui/ash/media_delegate_chromeos.h b/chrome/browser/ui/ash/media_delegate_chromeos.h
new file mode 100644
index 0000000..7370432
--- /dev/null
+++ b/chrome/browser/ui/ash/media_delegate_chromeos.h
@@ -0,0 +1,39 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_ASH_MEDIA_DELEGATE_CHROMEOS_H_
+#define CHROME_BROWSER_UI_ASH_MEDIA_DELEGATE_CHROMEOS_H_
+
+#include "ash/media_delegate.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/media/media_capture_devices_dispatcher.h"
+
+class MediaDelegateChromeOS : public ash::MediaDelegate,
+                              MediaCaptureDevicesDispatcher::Observer {
+ public:
+  MediaDelegateChromeOS();
+  virtual ~MediaDelegateChromeOS();
+
+  // ash::MediaDelegate:
+  virtual void HandleMediaNextTrack() OVERRIDE;
+  virtual void HandleMediaPlayPause() OVERRIDE;
+  virtual void HandleMediaPrevTrack() OVERRIDE;
+  virtual ash::MediaCaptureState GetMediaCaptureState(
+      content::BrowserContext* context) OVERRIDE;
+
+  // MediaCaptureDevicesDispatcher::Observer:
+  virtual void OnRequestUpdate(int render_process_id,
+                               int render_view_id,
+                               const content::MediaStreamDevice& device,
+                               const content::MediaRequestState state) OVERRIDE;
+
+ private:
+  void NotifyMediaCaptureChange();
+
+  base::WeakPtrFactory<MediaDelegateChromeOS> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(MediaDelegateChromeOS);
+};
+
+#endif  // CHROME_BROWSER_UI_ASH_MEDIA_DELEGATE_CHROMEOS_H_
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager.h b/chrome/browser/ui/ash/multi_user/multi_user_window_manager.h
index af43f3e..2496ea5 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager.h
+++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager.h
@@ -101,7 +101,7 @@
 
   // See who owns this window. The return value is the user id or an empty
   // string if not assigned yet.
-  virtual const std::string& GetWindowOwner(aura::Window* window) = 0;
+  virtual const std::string& GetWindowOwner(aura::Window* window) const = 0;
 
   // Allows to show an owned window for another users. If the window is not
   // owned, this call will return immediately. (The FileManager for example
@@ -113,19 +113,21 @@
       aura::Window* window, const std::string& user_id) = 0;
 
   // Returns true when windows are shared among users.
-  virtual bool AreWindowsSharedAmongUsers() = 0;
+  virtual bool AreWindowsSharedAmongUsers() const = 0;
 
   // Get the owners for the visible windows and set them to |user_ids|.
-  virtual void GetOwnersOfVisibleWindows(std::set<std::string>* user_ids) = 0;
+  virtual void GetOwnersOfVisibleWindows(
+      std::set<std::string>* user_ids) const = 0;
 
   // A query call for a given window to see if it is on the given user's
   // desktop.
   virtual bool IsWindowOnDesktopOfUser(aura::Window* window,
-                                       const std::string& user_id) = 0;
+                                       const std::string& user_id) const = 0;
 
   // Get the user on which the window is currently shown. If an empty string is
   // passed back the window will be presented for every user.
-  virtual const std::string& GetUserPresentingWindow(aura::Window* window) = 0;
+  virtual const std::string& GetUserPresentingWindow(
+      aura::Window* window) const = 0;
 
   // Adds user to monitor starting and running V1/V2 application windows.
   // Returns immediately if the user (identified by a |profile|) is already
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc
index 50480bc..8ddeb0e 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.cc
@@ -14,6 +14,7 @@
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
+#include "ash/system/tray/system_tray_notifier.h"
 #include "ash/wm/window_state.h"
 #include "base/auto_reset.h"
 #include "base/message_loop/message_loop.h"
@@ -197,8 +198,6 @@
     MultiUserWindowManagerChromeOS::GetInstance()->SetWindowOwner(window,
                                                                   user_id_);
   }
-  virtual void OnAppWindowIconChanged(apps::AppWindow* app_window) OVERRIDE {}
-  virtual void OnAppWindowRemoved(apps::AppWindow* app_window) OVERRIDE {}
 
  private:
   std::string user_id_;
@@ -297,8 +296,8 @@
 }
 
 const std::string& MultiUserWindowManagerChromeOS::GetWindowOwner(
-    aura::Window* window) {
-  WindowToEntryMap::iterator it = window_to_entry_.find(window);
+    aura::Window* window) const {
+  WindowToEntryMap::const_iterator it = window_to_entry_.find(window);
   return it != window_to_entry_.end() ? it->second->owner()
                                       : base::EmptyString();
 }
@@ -319,8 +318,8 @@
       user_id);
 }
 
-bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() {
-  WindowToEntryMap::iterator it = window_to_entry_.begin();
+bool MultiUserWindowManagerChromeOS::AreWindowsSharedAmongUsers() const {
+  WindowToEntryMap::const_iterator it = window_to_entry_.begin();
   for (; it != window_to_entry_.end(); ++it) {
     if (it->second->owner() != it->second->show_for_user())
       return true;
@@ -329,9 +328,10 @@
 }
 
 void MultiUserWindowManagerChromeOS::GetOwnersOfVisibleWindows(
-    std::set<std::string>* user_ids) {
-  for (WindowToEntryMap::iterator it = window_to_entry_.begin();
-       it != window_to_entry_.end(); ++it) {
+    std::set<std::string>* user_ids) const {
+  for (WindowToEntryMap::const_iterator it = window_to_entry_.begin();
+       it != window_to_entry_.end();
+       ++it) {
     if (it->first->IsVisible())
       user_ids->insert(it->second->owner());
   }
@@ -339,14 +339,14 @@
 
 bool MultiUserWindowManagerChromeOS::IsWindowOnDesktopOfUser(
     aura::Window* window,
-    const std::string& user_id) {
+    const std::string& user_id) const {
   const std::string& presenting_user = GetUserPresentingWindow(window);
   return presenting_user.empty() || presenting_user == user_id;
 }
 
 const std::string& MultiUserWindowManagerChromeOS::GetUserPresentingWindow(
-    aura::Window* window) {
-  WindowToEntryMap::iterator it = window_to_entry_.find(window);
+    aura::Window* window) const {
+  WindowToEntryMap::const_iterator it = window_to_entry_.find(window);
   // If the window is not owned by anyone it is shown on all desktops and we
   // return the empty string.
   if (it == window_to_entry_.end())
@@ -399,6 +399,11 @@
   animation_.reset(
       new UserSwichAnimatorChromeOS(
           this, user_id, GetAdjustedAnimationTimeInMS(kUserFadeTimeMS)));
+  // Call notifier here instead of observing ActiveUserChanged because
+  // this must happen after MultiUserWindowManagerChromeOS is notified.
+  ash::Shell::GetInstance()
+      ->system_tray_notifier()
+      ->NotifyMediaCaptureChanged();
 }
 
 void MultiUserWindowManagerChromeOS::OnWindowDestroyed(aura::Window* window) {
@@ -499,7 +504,8 @@
   return animation_.get() != NULL && !animation_->IsAnimationFinished();
 }
 
-const std::string& MultiUserWindowManagerChromeOS::GetCurrentUserForTest() {
+const std::string& MultiUserWindowManagerChromeOS::GetCurrentUserForTest()
+    const {
   return current_user_id_;
 }
 
@@ -612,7 +618,7 @@
 }
 
 aura::Window* MultiUserWindowManagerChromeOS::GetOwningWindowInTransientChain(
-    aura::Window* window) {
+    aura::Window* window) const {
   if (!GetWindowOwner(window).empty())
     return NULL;
   aura::Window* parent = wm::GetTransientParent(window);
@@ -701,7 +707,7 @@
 }
 
 int MultiUserWindowManagerChromeOS::GetAdjustedAnimationTimeInMS(
-    int default_time_in_ms) {
+    int default_time_in_ms) const {
   return animation_speed_ == ANIMATION_SPEED_NORMAL ? default_time_in_ms :
       (animation_speed_ == ANIMATION_SPEED_FAST ? 10 : 0);
 }
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h
index 4812431..55d1618 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h
+++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h
@@ -75,16 +75,18 @@
   // MultiUserWindowManager overrides:
   virtual void SetWindowOwner(
       aura::Window* window, const std::string& user_id) OVERRIDE;
-  virtual const std::string& GetWindowOwner(aura::Window* window) OVERRIDE;
+  virtual const std::string& GetWindowOwner(
+      aura::Window* window) const OVERRIDE;
   virtual void ShowWindowForUser(
       aura::Window* window, const std::string& user_id) OVERRIDE;
-  virtual bool AreWindowsSharedAmongUsers() OVERRIDE;
+  virtual bool AreWindowsSharedAmongUsers() const OVERRIDE;
   virtual void GetOwnersOfVisibleWindows(
-      std::set<std::string>* user_ids) OVERRIDE;
-  virtual bool IsWindowOnDesktopOfUser(aura::Window* window,
-                                       const std::string& user_id) OVERRIDE;
+      std::set<std::string>* user_ids) const OVERRIDE;
+  virtual bool IsWindowOnDesktopOfUser(
+      aura::Window* window,
+      const std::string& user_id) const OVERRIDE;
   virtual const std::string& GetUserPresentingWindow(
-      aura::Window* window) OVERRIDE;
+      aura::Window* window) const OVERRIDE;
   virtual void AddUser(content::BrowserContext* context) OVERRIDE;
   virtual void AddObserver(Observer* observer) OVERRIDE;
   virtual void RemoveObserver(Observer* observer) OVERRIDE;
@@ -117,7 +119,7 @@
   bool IsAnimationRunningForTest();
 
   // Returns the current user for unit tests.
-  const std::string& GetCurrentUserForTest();
+  const std::string& GetCurrentUserForTest() const;
 
  protected:
   friend class UserSwichAnimatorChromeOS;
@@ -202,7 +204,7 @@
 
   // Find the first owned window in the chain.
   // Returns NULL when the window itself is owned.
-  aura::Window* GetOwningWindowInTransientChain(aura::Window* window);
+  aura::Window* GetOwningWindowInTransientChain(aura::Window* window) const;
 
   // A |window| and its children were attached as transient children to an
   // |owning_parent| and need to be registered. Note that the |owning_parent|
@@ -221,7 +223,7 @@
 
   // Get the animation time in milliseconds dependent on the |AnimationSpeed|
   // from the passed |default_time_in_ms|.
-  int GetAdjustedAnimationTimeInMS(int default_time_in_ms);
+  int GetAdjustedAnimationTimeInMS(int default_time_in_ms) const;
 
   // A lookup to see to which user the given window belongs to, where and if it
   // should get shown.
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.cc
index 3669648..0fcf0ce 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.cc
@@ -15,7 +15,7 @@
 }
 
 const std::string& MultiUserWindowManagerStub::GetWindowOwner(
-    aura::Window* window) {
+    aura::Window* window) const {
   return base::EmptyString();
 }
 
@@ -24,22 +24,22 @@
   NOTIMPLEMENTED();
 }
 
-bool MultiUserWindowManagerStub::AreWindowsSharedAmongUsers() {
+bool MultiUserWindowManagerStub::AreWindowsSharedAmongUsers() const {
   return false;
 }
 
 void MultiUserWindowManagerStub::GetOwnersOfVisibleWindows(
-    std::set<std::string>* user_ids) {
+    std::set<std::string>* user_ids) const {
 }
 
 bool MultiUserWindowManagerStub::IsWindowOnDesktopOfUser(
     aura::Window* window,
-    const std::string& user_id) {
+    const std::string& user_id) const {
   return true;
 }
 
 const std::string& MultiUserWindowManagerStub::GetUserPresentingWindow(
-    aura::Window* window) {
+    aura::Window* window) const {
   return base::EmptyString();
 }
 
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.h b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.h
index aea2cc3..0309e57 100644
--- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.h
+++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.h
@@ -23,16 +23,18 @@
   // MultiUserWindowManager overrides:
   virtual void SetWindowOwner(
       aura::Window* window, const std::string& user_id) OVERRIDE;
-  virtual const std::string& GetWindowOwner(aura::Window* window) OVERRIDE;
+  virtual const std::string& GetWindowOwner(
+      aura::Window* window) const OVERRIDE;
   virtual void ShowWindowForUser(
       aura::Window* window, const std::string& user_id) OVERRIDE;
-  virtual bool AreWindowsSharedAmongUsers() OVERRIDE;
+  virtual bool AreWindowsSharedAmongUsers() const OVERRIDE;
   virtual void GetOwnersOfVisibleWindows(
-      std::set<std::string>* user_ids) OVERRIDE;
-  virtual bool IsWindowOnDesktopOfUser(aura::Window* window,
-                                       const std::string& user_id) OVERRIDE;
+      std::set<std::string>* user_ids) const OVERRIDE;
+  virtual bool IsWindowOnDesktopOfUser(
+      aura::Window* window,
+      const std::string& user_id) const OVERRIDE;
   virtual const std::string& GetUserPresentingWindow(
-      aura::Window* window) OVERRIDE;
+      aura::Window* window) const OVERRIDE;
   virtual void AddUser(content::BrowserContext* context) OVERRIDE;
   virtual void AddObserver(Observer* observer) OVERRIDE;
   virtual void RemoveObserver(Observer* observer) OVERRIDE;
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
index 02eaccd..adcad4c 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
@@ -72,7 +72,6 @@
 #include "chrome/browser/chromeos/sim_dialog_delegate.h"
 #include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h"
 #include "chrome/browser/drive/drive_service_interface.h"
-#include "chrome/browser/feedback/tracing_manager.h"
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -1399,12 +1398,6 @@
 }
 
 // Overridden from apps::AppWindowRegistry::Observer.
-void SystemTrayDelegateChromeOS::OnAppWindowAdded(apps::AppWindow* app_window) {
-}
-
-void SystemTrayDelegateChromeOS::OnAppWindowIconChanged(
-    apps::AppWindow* app_window) {}
-
 void SystemTrayDelegateChromeOS::OnAppWindowRemoved(
     apps::AppWindow* app_window) {
   NotifyIfLastWindowClosed();
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
index 378df87..5064860 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
@@ -254,8 +254,6 @@
   virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
 
   // Overridden from apps::AppWindowRegistry::Observer:
-  virtual void OnAppWindowAdded(apps::AppWindow* app_window) OVERRIDE;
-  virtual void OnAppWindowIconChanged(apps::AppWindow* app_window) OVERRIDE;
   virtual void OnAppWindowRemoved(apps::AppWindow* app_window) OVERRIDE;
 
   void OnAccessibilityStatusChanged(
diff --git a/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc b/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc
index ef8abe1..3658a52 100644
--- a/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc
+++ b/chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.cc
@@ -18,7 +18,7 @@
 #include "ui/gfx/screen.h"
 #include "ui/views/widget/native_widget_aura.h"
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#if defined(USE_X11) && !defined(OS_CHROMEOS)
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h"
@@ -42,7 +42,7 @@
 
 namespace {
 
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#if defined(USE_X11) && !defined(OS_CHROMEOS)
 ui::NativeTheme* GetNativeThemeForWindow(aura::Window* window) {
   if (!window)
     return NULL;
@@ -84,7 +84,7 @@
 }
 
 void ChromeBrowserMainExtraPartsAura::PreEarlyInitialization() {
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#if defined(USE_X11) && !defined(OS_CHROMEOS)
   // TODO(erg): Refactor this into a dlopen call when we add a GTK3 port.
   views::LinuxUI* gtk2_ui = BuildGtk2UI();
   gtk2_ui->SetNativeThemeOverride(base::Bind(&GetNativeThemeForWindow));
@@ -100,7 +100,7 @@
 #endif
 #endif
 
-#if !defined(USE_ASH) && defined(OS_LINUX) && defined(USE_X11)
+#if defined(USE_X11) && !defined(OS_CHROMEOS)
   views::LinuxUI::instance()->Initialize();
 #endif
 }
diff --git a/chrome/browser/ui/auto_login_infobar_delegate.cc b/chrome/browser/ui/auto_login_infobar_delegate.cc
index 1149029..62dffb6 100644
--- a/chrome/browser/ui/auto_login_infobar_delegate.cc
+++ b/chrome/browser/ui/auto_login_infobar_delegate.cc
@@ -63,8 +63,7 @@
   virtual void OnUbertokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
 
   // Implementation of content::WebContentsObserver
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // Redirect tab to MergeSession URL, logging the user in and navigating
   // to the desired page.
@@ -97,8 +96,7 @@
 AutoLoginRedirector::~AutoLoginRedirector() {
 }
 
-void AutoLoginRedirector::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void AutoLoginRedirector::WebContentsDestroyed() {
   // The WebContents that started this has been destroyed. The request must be
   // cancelled and this object must be deleted.
   ubertoken_fetcher_.reset();
diff --git a/chrome/browser/ui/autofill/autofill_dialog_common.cc b/chrome/browser/ui/autofill/autofill_dialog_common.cc
index 4b5070c..e95c9be 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_common.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_common.cc
@@ -9,16 +9,6 @@
 #include "components/autofill/core/browser/autofill_country.h"
 #include "components/autofill/core/browser/autofill_field.h"
 #include "components/autofill/core/browser/autofill_type.h"
-#include "grit/chromium_strings.h"
-#include "grit/component_strings.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "grit/webkit_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-
-#if !defined(OS_ANDROID)
-#include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
-#endif  // !defined(OS_ANDROID)
 
 namespace autofill {
 namespace common {
@@ -45,16 +35,10 @@
   if (autofill_type.group() != field_type.group())
     return false;
 
-#if defined(OS_ANDROID)
-  // Street address (all lines) is matched to the first input address line.
-  if (server_type == ADDRESS_HOME_STREET_ADDRESS)
-    return autofill_type.GetStorableType() == ADDRESS_HOME_LINE1;
-#else
   // The page may ask for individual address lines; this roughly matches the
   // street address blob.
   if (server_type == ADDRESS_HOME_LINE1 || server_type == ADDRESS_HOME_LINE2)
     return autofill_type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS;
-#endif
 
   return autofill_type.GetStorableType() == server_type;
 }
@@ -86,166 +70,6 @@
   }
 }
 
-bool IsI18nInputEnabled() {
-#if defined(OS_ANDROID)
-  return false;
-#else
-  return true;
-#endif
-}
-
-void BuildI18nAddressInputs(AddressType address_type,
-                            const std::string& country_code,
-                            DetailInputs* inputs,
-                            std::string* language_code) {
-#if defined(OS_ANDROID)
-  NOTREACHED();
-#else
-  i18ninput::BuildAddressInputs(address_type, country_code, inputs,
-                                language_code);
-#endif
-}
-
-// Constructs |inputs| from template data for a given |dialog_section|.
-void BuildInputsForSection(DialogSection dialog_section,
-                           const std::string& country_code,
-                           DetailInputs* inputs,
-                           std::string* language_code) {
-  using l10n_util::GetStringUTF16;
-
-  const DetailInput kCCInputs[] = {
-    { DetailInput::LONG,
-      CREDIT_CARD_NUMBER,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARD_NUMBER) },
-    { DetailInput::SHORT,
-      CREDIT_CARD_EXP_MONTH,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_MONTH) },
-    { DetailInput::SHORT,
-      CREDIT_CARD_EXP_4_DIGIT_YEAR,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR) },
-    { DetailInput::SHORT_EOL,
-      CREDIT_CARD_VERIFICATION_CODE,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC),
-      1.5 },
-  };
-
-  const DetailInput kBillingInputs[] = {
-    { DetailInput::LONG,
-      NAME_BILLING_FULL,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARDHOLDER_NAME) },
-    { DetailInput::LONG,
-      ADDRESS_BILLING_LINE1,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1) },
-    { DetailInput::LONG,
-      ADDRESS_BILLING_LINE2,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2) },
-    { DetailInput::LONG,
-      ADDRESS_BILLING_CITY,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY) },
-    { DetailInput::SHORT,
-      ADDRESS_BILLING_STATE,
-      GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_STATE) },
-    { DetailInput::SHORT_EOL,
-      ADDRESS_BILLING_ZIP,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE) },
-    // We don't allow the user to change the country: http://crbug.com/247518
-    { DetailInput::NONE, ADDRESS_BILLING_COUNTRY },
-  };
-
-  const DetailInput kBillingPhoneInputs[] = {
-    { DetailInput::LONG,
-      PHONE_BILLING_WHOLE_NUMBER,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_PHONE_NUMBER) },
-  };
-
-  const DetailInput kEmailInputs[] = {
-    { DetailInput::LONG,
-      EMAIL_ADDRESS,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EMAIL) },
-  };
-
-  const DetailInput kShippingInputs[] = {
-    { DetailInput::LONG,
-      NAME_FULL,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESSEE_NAME) },
-    { DetailInput::LONG,
-      ADDRESS_HOME_LINE1,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1) },
-    { DetailInput::LONG,
-      ADDRESS_HOME_LINE2,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2) },
-    { DetailInput::LONG,
-      ADDRESS_HOME_CITY,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY) },
-    { DetailInput::SHORT,
-      ADDRESS_HOME_STATE,
-      GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_STATE) },
-    { DetailInput::SHORT_EOL,
-      ADDRESS_HOME_ZIP,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE) },
-    { DetailInput::NONE, ADDRESS_HOME_COUNTRY },
-  };
-
-  const DetailInput kShippingPhoneInputs[] = {
-    { DetailInput::LONG,
-      PHONE_HOME_WHOLE_NUMBER,
-      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_PHONE_NUMBER) },
-  };
-
-  switch (dialog_section) {
-    case SECTION_CC:
-      BuildInputs(kCCInputs, arraysize(kCCInputs), inputs);
-      break;
-
-    case SECTION_BILLING:
-      if (IsI18nInputEnabled()) {
-        BuildI18nAddressInputs(ADDRESS_TYPE_BILLING, country_code, inputs,
-                               language_code);
-      } else {
-        BuildInputs(kBillingInputs, arraysize(kBillingInputs), inputs);
-      }
-
-      BuildInputs(kBillingPhoneInputs, arraysize(kBillingPhoneInputs), inputs);
-      BuildInputs(kEmailInputs, arraysize(kEmailInputs), inputs);
-      break;
-
-    case SECTION_CC_BILLING:
-      BuildInputs(kCCInputs, arraysize(kCCInputs), inputs);
-
-      if (IsI18nInputEnabled()) {
-        // Wallet only supports US billing addresses.
-        const std::string hardcoded_country_code = "US";
-        BuildI18nAddressInputs(ADDRESS_TYPE_BILLING,
-                               hardcoded_country_code,
-                               inputs,
-                               language_code);
-        DCHECK_EQ(inputs->back().type, ADDRESS_BILLING_COUNTRY);
-        inputs->back().length = DetailInput::NONE;
-        const std::string& app_locale =
-            g_browser_process->GetApplicationLocale();
-        inputs->back().initial_value =
-            AutofillCountry(hardcoded_country_code, app_locale).name();
-      } else {
-        BuildInputs(kBillingInputs, arraysize(kBillingInputs), inputs);
-      }
-
-      BuildInputs(kBillingPhoneInputs, arraysize(kBillingPhoneInputs), inputs);
-      break;
-
-    case SECTION_SHIPPING:
-      if (IsI18nInputEnabled()) {
-        BuildI18nAddressInputs(ADDRESS_TYPE_SHIPPING, country_code, inputs,
-                               language_code);
-      } else {
-        BuildInputs(kShippingInputs, arraysize(kShippingInputs), inputs);
-      }
-
-      BuildInputs(
-          kShippingPhoneInputs, arraysize(kShippingPhoneInputs), inputs);
-      break;
-  }
-}
-
 AutofillMetrics::DialogUiEvent DialogSectionToUiItemAddedEvent(
     DialogSection section) {
   switch (section) {
diff --git a/chrome/browser/ui/autofill/autofill_dialog_common.h b/chrome/browser/ui/autofill/autofill_dialog_common.h
index ae2c6ff..f0e3fad 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_common.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_common.h
@@ -43,15 +43,10 @@
 // Returns true if the |type| belongs to the CREDIT_CARD field type group.
 bool IsCreditCardType(ServerFieldType type);
 
-// Constructs |inputs| from template data for a given |dialog_section|.
-// |country_country| specifies the country code that the inputs should be built
-// for. Sets the |language_code| to be used for address formatting, if
-// internationalized address input is enabled. The |language_code| parameter can
-// be NULL.
-void BuildInputsForSection(DialogSection dialog_section,
-                           const std::string& country_code,
-                           DetailInputs* inputs,
-                           std::string* language_code);
+// Constructs |inputs| from the array of inputs in |input_template|.
+void BuildInputs(const DetailInput input_template[],
+                 size_t template_size,
+                 DetailInputs* inputs);
 
 // Returns the AutofillMetrics::DIALOG_UI_*_ITEM_ADDED metric corresponding
 // to the |section|.
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
index 1f079f4..ec41f89 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
@@ -73,7 +73,6 @@
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/url_constants.h"
 #include "grit/chromium_strings.h"
 #include "grit/component_scaled_resources.h"
@@ -257,13 +256,12 @@
 // window might be a browser window for a Chrome tab, or it might be an app
 // window for a platform app.
 ui::BaseWindow* GetBaseWindowForWebContents(
-    const content::WebContents* web_contents) {
+    content::WebContents* web_contents) {
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
   if (browser)
     return browser->window();
 
-  gfx::NativeWindow native_window =
-      web_contents->GetView()->GetTopLevelNativeWindow();
+  gfx::NativeWindow native_window = web_contents->GetTopLevelNativeWindow();
   apps::AppWindow* app_window =
       apps::AppWindowRegistry::GetAppWindowForNativeWindowAnyProfile(
           native_window);
@@ -565,6 +563,97 @@
   return phone_message;
 }
 
+// Constructs |inputs| from template data for a given |dialog_section|.
+// |country_country| specifies the country code that the inputs should be built
+// for. Sets the |language_code| to be used for address formatting, if
+// internationalized address input is enabled. The |language_code| parameter can
+// be NULL.
+void BuildInputsForSection(DialogSection dialog_section,
+                           const std::string& country_code,
+                           DetailInputs* inputs,
+                           std::string* language_code) {
+  using l10n_util::GetStringUTF16;
+
+  const DetailInput kCCInputs[] = {
+    { DetailInput::LONG,
+      CREDIT_CARD_NUMBER,
+      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARD_NUMBER) },
+    { DetailInput::SHORT,
+      CREDIT_CARD_EXP_MONTH,
+      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_MONTH) },
+    { DetailInput::SHORT,
+      CREDIT_CARD_EXP_4_DIGIT_YEAR,
+      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR) },
+    { DetailInput::SHORT_EOL,
+      CREDIT_CARD_VERIFICATION_CODE,
+      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC),
+      1.5 },
+  };
+
+  const DetailInput kBillingPhoneInputs[] = {
+    { DetailInput::LONG,
+      PHONE_BILLING_WHOLE_NUMBER,
+      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_PHONE_NUMBER) },
+  };
+
+  const DetailInput kEmailInputs[] = {
+    { DetailInput::LONG,
+      EMAIL_ADDRESS,
+      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EMAIL) },
+  };
+
+  const DetailInput kShippingPhoneInputs[] = {
+    { DetailInput::LONG,
+      PHONE_HOME_WHOLE_NUMBER,
+      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_PHONE_NUMBER) },
+  };
+
+  switch (dialog_section) {
+    case SECTION_CC: {
+      common::BuildInputs(kCCInputs, arraysize(kCCInputs), inputs);
+      break;
+    }
+
+    case SECTION_BILLING: {
+      i18ninput::BuildAddressInputs(common::ADDRESS_TYPE_BILLING,
+                                    country_code, inputs, language_code);
+      common::BuildInputs(kBillingPhoneInputs, arraysize(kBillingPhoneInputs),
+                          inputs);
+      common::BuildInputs(kEmailInputs, arraysize(kEmailInputs), inputs);
+      break;
+    }
+
+    case SECTION_CC_BILLING: {
+      common::BuildInputs(kCCInputs, arraysize(kCCInputs), inputs);
+
+      // Wallet only supports US billing addresses.
+      const std::string hardcoded_country_code = "US";
+      i18ninput::BuildAddressInputs(common::ADDRESS_TYPE_BILLING,
+                                    hardcoded_country_code,
+                                    inputs,
+                                    language_code);
+      DCHECK_EQ(inputs->back().type, ADDRESS_BILLING_COUNTRY);
+      inputs->back().length = DetailInput::NONE;
+      const std::string& app_locale =
+          g_browser_process->GetApplicationLocale();
+      inputs->back().initial_value =
+          AutofillCountry(hardcoded_country_code, app_locale).name();
+
+      common::BuildInputs(kBillingPhoneInputs, arraysize(kBillingPhoneInputs),
+                          inputs);
+      break;
+    }
+
+    case SECTION_SHIPPING: {
+      i18ninput::BuildAddressInputs(common::ADDRESS_TYPE_SHIPPING,
+                                    country_code, inputs, language_code);
+      common::BuildInputs(kShippingPhoneInputs, arraysize(kShippingPhoneInputs),
+                          inputs);
+      break;
+    }
+  }
+}
+
 }  // namespace
 
 AutofillDialogViewDelegate::~AutofillDialogViewDelegate() {}
@@ -720,7 +809,7 @@
       country_code = model->GetDefaultCountryCode();
 
     DetailInputs* inputs = MutableRequestedFieldsForSection(section);
-    common::BuildInputsForSection(
+    BuildInputsForSection(
         section, country_code, inputs,
         MutableAddressLanguageCodeForSection(section));
   }
@@ -1351,7 +1440,7 @@
   const int kCardHeightPx = 190;
   const gfx::Size size(kCardWidthPx, kCardHeightPx);
   ui::ScaleFactor scale_factor = ui::GetScaleFactorForNativeView(
-      web_contents()->GetView()->GetNativeView());
+      web_contents()->GetNativeView());
   gfx::Canvas canvas(size, ui::GetImageScale(scale_factor), false);
 
   gfx::Rect display_rect(size);
@@ -2759,7 +2848,7 @@
       g_browser_process->local_state()->GetInt64(::prefs::kInstallDate));
 
   risk::GetFingerprint(
-      obfuscated_gaia_id, window_bounds, *web_contents(),
+      obfuscated_gaia_id, window_bounds, web_contents(),
       chrome::VersionInfo().Version(), charset, accept_languages, install_time,
       g_browser_process->GetApplicationLocale(), GetUserAgent(),
       base::Bind(&AutofillDialogControllerImpl::OnDidLoadRiskFingerprintData,
@@ -3066,8 +3155,8 @@
 
   DetailInputs inputs;
   std::string country_code = CountryCodeForSection(section);
-  common::BuildInputsForSection(section, country_code, &inputs,
-                                MutableAddressLanguageCodeForSection(section));
+  BuildInputsForSection(section, country_code, &inputs,
+                        MutableAddressLanguageCodeForSection(section));
   std::vector<ServerFieldType> types = common::TypesFromInputs(inputs);
 
   scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section);
@@ -3374,8 +3463,8 @@
 
   DetailInputs* inputs = MutableRequestedFieldsForSection(section);
   inputs->clear();
-  common::BuildInputsForSection(section, country_code, inputs,
-                                MutableAddressLanguageCodeForSection(section));
+  BuildInputsForSection(section, country_code, inputs,
+                        MutableAddressLanguageCodeForSection(section));
 
   if (!country_code.empty()) {
     GetValidator()->LoadRules(AutofillCountry::GetCountryCode(
diff --git a/chrome/browser/ui/autofill/autofill_dialog_i18n_input.cc b/chrome/browser/ui/autofill/autofill_dialog_i18n_input.cc
index e632cd8..5dc33e3 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_i18n_input.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_i18n_input.cc
@@ -59,18 +59,6 @@
     base::string16 placeholder = l10n_util::GetStringUTF16(component.name_id);
     DetailInput input = { length, server_type, placeholder };
     inputs->push_back(input);
-
-#if defined(OS_ANDROID)
-    if (component.field == ::i18n::addressinput::STREET_ADDRESS &&
-        component.length_hint == AddressUiComponent::HINT_LONG) {
-      // TODO(dbeam): support more than 2 address lines. http://crbug.com/324889
-      ServerFieldType server_type =
-          billing ? ADDRESS_BILLING_LINE2 : ADDRESS_HOME_LINE2;
-      base::string16 placeholder = l10n_util::GetStringUTF16(component.name_id);
-      DetailInput input = { length, server_type, placeholder };
-      inputs->push_back(input);
-    }
-#endif
   }
 
   ServerFieldType server_type =
@@ -147,14 +135,9 @@
       return billing ? ADDRESS_BILLING_ZIP : ADDRESS_HOME_ZIP;
     case ::i18n::addressinput::SORTING_CODE:
       return billing ? ADDRESS_BILLING_SORTING_CODE : ADDRESS_HOME_SORTING_CODE;
-#if defined(OS_ANDROID)
-    case ::i18n::addressinput::STREET_ADDRESS:
-      return billing ? ADDRESS_BILLING_LINE1 : ADDRESS_HOME_LINE1;
-#else
     case ::i18n::addressinput::STREET_ADDRESS:
       return billing ? ADDRESS_BILLING_STREET_ADDRESS :
                        ADDRESS_HOME_STREET_ADDRESS;
-#endif
     case ::i18n::addressinput::RECIPIENT:
       return billing ? NAME_BILLING_FULL : NAME_FULL;
     case ::i18n::addressinput::ORGANIZATION:
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
index a509107..96f125d 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
@@ -147,7 +147,7 @@
 
     int available_width = popup_width - RowWidthWithoutText(i);
 
-    // Each field recieves space in proportion to its length.
+    // Each field receives space in proportion to its length.
     int name_size = available_width * name_width / total_text_length;
     names_[i] = gfx::ElideText(names_[i],
                                GetNameFontListForRow(i),
@@ -177,8 +177,8 @@
     UpdateBoundsAndRedrawPopup();
   }
 
-  delegate_->OnPopupShown();
   controller_common_->RegisterKeyPressCallback();
+  delegate_->OnPopupShown();
 }
 
 void AutofillPopupControllerImpl::UpdateDataListValues(
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc
index fd4573f..9b8f81b 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc
@@ -72,31 +72,27 @@
   virtual ~AutofillPopupControllerBrowserTest() {}
 
   virtual void SetUpOnMainThread() OVERRIDE {
-    web_contents_ = browser()->tab_strip_model()->GetActiveWebContents();
-    ASSERT_TRUE(web_contents_ != NULL);
-    Observe(web_contents_);
+    content::WebContents* web_contents =
+        browser()->tab_strip_model()->GetActiveWebContents();
+    ASSERT_TRUE(web_contents != NULL);
+    Observe(web_contents);
 
     ContentAutofillDriver* driver =
-        ContentAutofillDriver::FromWebContents(web_contents_);
+        ContentAutofillDriver::FromWebContents(web_contents);
     autofill_external_delegate_.reset(
        new TestAutofillExternalDelegate(
-           web_contents_,
+           web_contents,
            driver->autofill_manager(),
            driver));
   }
 
   // Normally the WebContents will automatically delete the delegate, but here
   // the delegate is owned by this test, so we have to manually destroy.
-  virtual void WebContentsDestroyed(content::WebContents* web_contents)
-      OVERRIDE {
-    DCHECK_EQ(web_contents_, web_contents);
-
+  virtual void WebContentsDestroyed() OVERRIDE {
     autofill_external_delegate_.reset();
   }
 
  protected:
-  content::WebContents* web_contents_;
-
   scoped_ptr<TestAutofillExternalDelegate> autofill_external_delegate_;
 };
 
diff --git a/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc b/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc
index 6d31227..6db0c281 100644
--- a/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc
+++ b/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc
@@ -22,7 +22,9 @@
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
+#include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
+#include "grit/google_chrome_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/events/keycodes/keyboard_codes.h"
diff --git a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc
index 23ef6d0..0e1c45d 100644
--- a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc
+++ b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc
@@ -24,7 +24,6 @@
 #include "components/autofill/content/common/autofill_messages.h"
 #include "components/autofill/core/common/autofill_pref_names.h"
 #include "content/public/browser/render_view_host.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/gfx/rect.h"
 
 #if defined(OS_ANDROID)
@@ -123,8 +122,7 @@
     const std::vector<int>& identifiers,
     base::WeakPtr<AutofillPopupDelegate> delegate) {
   // Convert element_bounds to be in screen space.
-  gfx::Rect client_area;
-  web_contents_->GetView()->GetContainerBounds(&client_area);
+  gfx::Rect client_area = web_contents_->GetContainerBounds();
   gfx::RectF element_bounds_in_screen_space =
       element_bounds + client_area.OffsetFromOrigin();
 
@@ -133,7 +131,7 @@
       popup_controller_,
       delegate,
       web_contents(),
-      web_contents()->GetView()->GetNativeView(),
+      web_contents()->GetNativeView(),
       element_bounds_in_screen_space,
       text_direction);
 
@@ -169,8 +167,7 @@
     dialog_controller_->Hide();
 }
 
-void TabAutofillManagerDelegate::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void TabAutofillManagerDelegate::WebContentsDestroyed() {
   HideAutofillPopup();
 }
 
diff --git a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h
index 3b3a3f0..6c48706 100644
--- a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h
+++ b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h
@@ -70,8 +70,7 @@
       const base::string16& profile_full_name) OVERRIDE;
 
   // content::WebContentsObserver implementation.
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // Exposed for testing.
   AutofillDialogController* GetDialogControllerForTesting() {
diff --git a/chrome/browser/ui/blocked_content/blocked_window_params.cc b/chrome/browser/ui/blocked_content/blocked_window_params.cc
index 69fdaea..f3641a2 100644
--- a/chrome/browser/ui/blocked_content/blocked_window_params.cc
+++ b/chrome/browser/ui/blocked_content/blocked_window_params.cc
@@ -8,7 +8,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "third_party/WebKit/public/web/WebWindowFeatures.h"
 #include "url/gurl.h"
 
@@ -46,7 +45,7 @@
   nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
   nav_params.user_gesture = user_gesture_;
   nav_params.should_set_opener = !opener_suppressed_;
-  web_contents->GetView()->GetContainerBounds(&nav_params.window_bounds);
+  nav_params.window_bounds = web_contents->GetContainerBounds();
   if (features_.xSet)
     nav_params.window_bounds.set_x(features_.x);
   if (features_.ySet)
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
index 26f4e14..bc21ac4 100644
--- a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
@@ -34,7 +34,6 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_navigation_observer.h"
@@ -82,7 +81,7 @@
     close_loop_.Run();
   }
 
-  virtual void WebContentsDestroyed(WebContents* contents) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     close_loop_.Quit();
   }
 
@@ -388,7 +387,7 @@
                    DontCheckTitle);
 
   // Check that the new popup has (roughly) the requested size.
-  gfx::Size window_size = popup->GetView()->GetContainerSize();
+  gfx::Size window_size = popup->GetContainerBounds().size();
   EXPECT_TRUE(349 <= window_size.width() && window_size.width() <= 351);
   EXPECT_TRUE(249 <= window_size.height() && window_size.height() <= 251);
 }
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc
index d2c3bf3..01953d5 100644
--- a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc
+++ b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc
@@ -18,7 +18,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "content/public/browser/web_contents_view.h"
 #include "third_party/WebKit/public/web/WebWindowFeatures.h"
 
 #if defined(OS_ANDROID)
diff --git a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
index 12042ab..bd450eb 100644
--- a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
@@ -7,7 +7,6 @@
 #include "base/timer/timer.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
@@ -20,6 +19,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/test/browser_test_utils.h"
 
diff --git a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc
index 1200582..66b4376 100644
--- a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc
@@ -11,11 +11,11 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/test/test_browser_thread.h"
 #include "grit/generated_resources.h"
diff --git a/chrome/browser/ui/bookmarks/bookmark_editor_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_editor_unittest.cc
index f050cc6..d62f405 100644
--- a/chrome/browser/ui/bookmarks/bookmark_editor_unittest.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_editor_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/ui/bookmarks/bookmark_editor.h"
 
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/test_bookmark_client.h"
+#include "components/bookmarks/core/test/test_bookmark_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using base::ASCIIToUTF16;
diff --git a/chrome/browser/ui/bookmarks/bookmark_prompt_controller.cc b/chrome/browser/ui/bookmarks/bookmark_prompt_controller.cc
deleted file mode 100644
index 838ad57..0000000
--- a/chrome/browser/ui/bookmarks/bookmark_prompt_controller.cc
+++ /dev/null
@@ -1,397 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
-
-#include "base/bind.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/histogram.h"
-#include "base/prefs/pref_service.h"
-#include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/defaults.h"
-#include "chrome/browser/history/history_service.h"
-#include "chrome/browser/history/history_service_factory.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_version_info.h"
-#include "chrome/common/metrics/variations/variation_ids.h"
-#include "chrome/common/pref_names.h"
-#include "components/bookmarks/core/browser/bookmark_model.h"
-#include "components/bookmarks/core/browser/bookmark_prompt_prefs.h"
-#include "components/variations/variations_associated_data.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
-#include "content/public/browser/web_contents.h"
-
-using content::WebContents;
-
-namespace {
-
-const char kBookmarkPromptTrialName[] = "BookmarkPrompt";
-const char kBookmarkPromptDefaultGroup[] = "Disabled";
-const char kBookmarkPromptControlGroup[] = "Control";
-const char kBookmarkPromptExperimentGroup[] = "Experiment";
-
-// This enum is used for the BookmarkPrompt.DisabledReason histogram.
-enum PromptDisabledReason {
-  PROMPT_DISABLED_REASON_BY_IMPRESSION_COUNT,
-  PROMPT_DISABLED_REASON_BY_MANUAL,
-
-  PROMPT_DISABLED_REASON_LIMIT, // Keep this last.
-};
-
-// This enum represents reason why we display bookmark prompt and for the
-// BookmarkPrompt.DisplayReason histogram.
-enum PromptDisplayReason {
-  PROMPT_DISPLAY_REASON_NOT_DISPLAY, // We don't display the prompt.
-  PROMPT_DISPLAY_REASON_PERMANENT,
-  PROMPT_DISPLAY_REASON_SESSION,
-
-  PROMPT_DISPLAY_REASON_LIMIT, // Keep this last.
-};
-
-// We enable bookmark prompt experiment for users who have profile created
-// before |install_date| until |expiration_date|.
-struct ExperimentDateRange {
-  base::Time::Exploded install_date;
-  base::Time::Exploded expiration_date;
-};
-
-bool CanShowBookmarkPrompt(Browser* browser) {
-  BookmarkPromptPrefs prefs(browser->profile()->GetPrefs());
-  if (!prefs.IsBookmarkPromptEnabled())
-    return false;
-  return prefs.GetPromptImpressionCount() <
-         BookmarkPromptController::kMaxPromptImpressionCount;
-}
-
-const ExperimentDateRange* GetExperimentDateRange() {
-  switch (chrome::VersionInfo::GetChannel()) {
-    case chrome::VersionInfo::CHANNEL_BETA:
-    case chrome::VersionInfo::CHANNEL_DEV: {
-      // Experiment date range for M26 Beta/Dev
-      static const ExperimentDateRange kBetaAndDevRange = {
-        { 2013, 3, 0, 1, 0, 0, 0, 0 },   // Mar 1, 2013
-        { 2013, 4, 0, 1, 0, 0, 0, 0 },   // Apr 1, 2013
-      };
-      return &kBetaAndDevRange;
-    }
-    case chrome::VersionInfo::CHANNEL_CANARY: {
-      // Experiment date range for M26 Canary.
-      static const ExperimentDateRange kCanaryRange = {
-        { 2013, 1, 0, 17, 0, 0, 0, 0 },  // Jan 17, 2013
-        { 2013, 2, 0, 18, 0, 0, 0, 0 },  // Feb 17, 2013
-      };
-      return &kCanaryRange;
-    }
-    case chrome::VersionInfo::CHANNEL_STABLE: {
-      // Experiment date range for M26 Stable.
-      static const ExperimentDateRange kStableRange = {
-        { 2013, 4, 0, 5, 0, 0, 0, 0 },  // Apr 5, 2013
-        { 2013, 5, 0, 5, 0, 0, 0, 0 },  // May 5, 2013
-      };
-      return &kStableRange;
-    }
-    default:
-      return NULL;
-  }
-}
-
-bool IsActiveWebContents(Browser* browser, WebContents* web_contents) {
-  if (!browser->window()->IsActive())
-    return false;
-  return browser->tab_strip_model()->GetActiveWebContents() == web_contents;
-}
-
-bool IsBookmarked(Browser* browser, const GURL& url) {
-  BookmarkModel* model = BookmarkModelFactory::GetForProfile(
-      browser->profile());
-  return model && model->IsBookmarked(url);
-}
-
-bool IsEligiblePageTransitionForBookmarkPrompt(
-    content::PageTransition type) {
-  if (!content::PageTransitionIsMainFrame(type))
-    return false;
-
-  const content::PageTransition core_type =
-      PageTransitionStripQualifier(type);
-
-  if (core_type == content::PAGE_TRANSITION_RELOAD)
-    return false;
-
-  const int32 qualifier = content::PageTransitionGetQualifier(type);
-  return !(qualifier & content::PAGE_TRANSITION_FORWARD_BACK);
-}
-
-// CheckPromptTriger returns prompt display reason based on |visits|.
-PromptDisplayReason CheckPromptTriger(const history::VisitVector& visits) {
-  const base::Time now = base::Time::Now();
-  // We assume current visit is already in history database. Although, this
-  // assumption may be false. We'll display prompt next time.
-  int visit_permanent_count = 0;
-  int visit_session_count = 0;
-  for (history::VisitVector::const_iterator it = visits.begin();
-       it != visits.end(); ++it) {
-    if (!IsEligiblePageTransitionForBookmarkPrompt(it->transition))
-      continue;
-    ++visit_permanent_count;
-    if ((now - it->visit_time) <= base::TimeDelta::FromDays(1))
-      ++visit_session_count;
-  }
-
-  if (visit_permanent_count ==
-      BookmarkPromptController::kVisitCountForPermanentTrigger)
-    return PROMPT_DISPLAY_REASON_PERMANENT;
-
-  if (visit_session_count ==
-      BookmarkPromptController::kVisitCountForSessionTrigger)
-    return PROMPT_DISPLAY_REASON_SESSION;
-
-  return PROMPT_DISPLAY_REASON_NOT_DISPLAY;
-}
-
-}  // namespace
-
-// BookmarkPromptController
-
-// When impression count is greater than |kMaxPromptImpressionCount|, we
-// don't display bookmark prompt anymore.
-const int BookmarkPromptController::kMaxPromptImpressionCount = 5;
-
-// When user visited the URL 10 times, we show the bookmark prompt.
-const int BookmarkPromptController::kVisitCountForPermanentTrigger = 10;
-
-// When user visited the URL 3 times last 24 hours, we show the bookmark
-// prompt.
-const int BookmarkPromptController::kVisitCountForSessionTrigger = 3;
-
-BookmarkPromptController::BookmarkPromptController()
-    : browser_(NULL),
-      web_contents_(NULL) {
-  DCHECK(browser_defaults::bookmarks_enabled);
-  BrowserList::AddObserver(this);
-}
-
-BookmarkPromptController::~BookmarkPromptController() {
-  BrowserList::RemoveObserver(this);
-  SetBrowser(NULL);
-}
-
-// static
-void BookmarkPromptController::AddedBookmark(Browser* browser,
-                                             const GURL& url) {
-  BookmarkPromptController* controller =
-      g_browser_process->bookmark_prompt_controller();
-  if (controller)
-    controller->AddedBookmarkInternal(browser, url);
-}
-
-// static
-void BookmarkPromptController::ClosingBookmarkPrompt() {
-  BookmarkPromptController* controller =
-      g_browser_process->bookmark_prompt_controller();
-  if (controller)
-    controller->ClosingBookmarkPromptInternal();
-}
-
-// static
-void BookmarkPromptController::DisableBookmarkPrompt(
-    PrefService* prefs) {
-  UMA_HISTOGRAM_ENUMERATION("BookmarkPrompt.DisabledReason",
-                            PROMPT_DISABLED_REASON_BY_MANUAL,
-                            PROMPT_DISABLED_REASON_LIMIT);
-  BookmarkPromptPrefs prompt_prefs(prefs);
-  prompt_prefs.DisableBookmarkPrompt();
-}
-
-// Enable bookmark prompt controller feature for 1% of new users for one month
-// on canary. We'll change the date for stable channel once release date fixed.
-// static
-bool BookmarkPromptController::IsEnabled() {
-  // If manually create field trial available, we use it.
-  const std::string manual_group_name = base::FieldTrialList::FindFullName(
-      "BookmarkPrompt");
-  if (!manual_group_name.empty())
-    return manual_group_name == kBookmarkPromptExperimentGroup;
-
-  const ExperimentDateRange* date_range = GetExperimentDateRange();
-  if (!date_range)
-    return false;
-
-  scoped_refptr<base::FieldTrial> trial(
-      base::FieldTrialList::FactoryGetFieldTrial(
-          kBookmarkPromptTrialName, 100, kBookmarkPromptDefaultGroup,
-          date_range->expiration_date.year,
-          date_range->expiration_date.month,
-          date_range->expiration_date.day_of_month,
-          base::FieldTrial::ONE_TIME_RANDOMIZED,
-          NULL));
-  trial->AppendGroup(kBookmarkPromptControlGroup, 10);
-  trial->AppendGroup(kBookmarkPromptExperimentGroup, 10);
-
-  chrome_variations::AssociateGoogleVariationID(
-      chrome_variations::GOOGLE_UPDATE_SERVICE,
-      kBookmarkPromptTrialName, kBookmarkPromptDefaultGroup,
-      chrome_variations::BOOKMARK_PROMPT_TRIAL_DEFAULT);
-  chrome_variations::AssociateGoogleVariationID(
-      chrome_variations::GOOGLE_UPDATE_SERVICE,
-      kBookmarkPromptTrialName, kBookmarkPromptControlGroup,
-      chrome_variations::BOOKMARK_PROMPT_TRIAL_CONTROL);
-  chrome_variations::AssociateGoogleVariationID(
-      chrome_variations::GOOGLE_UPDATE_SERVICE,
-      kBookmarkPromptTrialName, kBookmarkPromptExperimentGroup,
-      chrome_variations::BOOKMARK_PROMPT_TRIAL_EXPERIMENT);
-
-  const base::Time start_date = base::Time::FromLocalExploded(
-      date_range->install_date);
-  const int64 install_time =
-      g_browser_process->local_state()->GetInt64(prefs::kInstallDate);
-  // This must be called after the pref is initialized.
-  DCHECK(install_time);
-  const base::Time install_date = base::Time::FromTimeT(install_time);
-
-  if (install_date < start_date) {
-    trial->Disable();
-    return false;
-  }
-  return trial->group_name() == kBookmarkPromptExperimentGroup;
-}
-
-void BookmarkPromptController::ActiveTabChanged(WebContents* old_contents,
-                                                WebContents* new_contents,
-                                                int index,
-                                                int reason) {
-  SetWebContents(new_contents);
-}
-
-void BookmarkPromptController::AddedBookmarkInternal(Browser* browser,
-                                                     const GURL& url) {
-  if (browser == browser_ && url == last_prompted_url_) {
-    last_prompted_url_ = GURL::EmptyGURL();
-    UMA_HISTOGRAM_TIMES("BookmarkPrompt.AddedBookmark",
-                        base::Time::Now() - last_prompted_time_);
-  }
-}
-
-void BookmarkPromptController::ClosingBookmarkPromptInternal() {
-  UMA_HISTOGRAM_TIMES("BookmarkPrompt.DisplayDuration",
-                      base::Time::Now() - last_prompted_time_);
-}
-
-void BookmarkPromptController::Observe(
-    int type,
-    const content::NotificationSource&,
-    const content::NotificationDetails&) {
-  DCHECK_EQ(type, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME);
-  query_url_consumer_.CancelAllRequests();
-  if (!CanShowBookmarkPrompt(browser_))
-    return;
-
-  const GURL url = web_contents_->GetURL();
-  if (!HistoryService::CanAddURL(url) || IsBookmarked(browser_, url))
-    return;
-
-  HistoryService* history_service = HistoryServiceFactory::GetForProfile(
-      browser_->profile(),
-      Profile::IMPLICIT_ACCESS);
-  if (!history_service)
-    return;
-
-  query_url_start_time_ = base::Time::Now();
-  history_service->QueryURL(
-      url, true, &query_url_consumer_,
-      base::Bind(&BookmarkPromptController::OnDidQueryURL,
-                 base::Unretained(this)));
-}
-
-void BookmarkPromptController::OnBrowserRemoved(Browser* browser) {
-  if (browser_ == browser)
-    SetBrowser(NULL);
-}
-
-void BookmarkPromptController::OnBrowserSetLastActive(Browser* browser) {
-  if (browser && browser->type() == Browser::TYPE_TABBED &&
-      !browser->profile()->IsOffTheRecord() &&
-      browser->CanSupportWindowFeature(Browser::FEATURE_LOCATIONBAR) &&
-      CanShowBookmarkPrompt(browser))
-    SetBrowser(browser);
-  else
-    SetBrowser(NULL);
-}
-
-void BookmarkPromptController::OnDidQueryURL(
-    CancelableRequestProvider::Handle handle,
-    bool success,
-    const history::URLRow* url_row,
-    history::VisitVector* visits) {
-  if (!success)
-    return;
-
-  const GURL url = web_contents_->GetURL();
-  if (url_row->url() != url) {
-    // The URL of web_contents_ is changed during QueryURL call. This is an
-    // edge case but can be happened.
-    return;
-  }
-
-  UMA_HISTOGRAM_TIMES("BookmarkPrompt.QueryURLDuration",
-                      base::Time::Now() - query_url_start_time_);
-
-  if (!browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR) ||
-      !CanShowBookmarkPrompt(browser_) ||
-      !IsActiveWebContents(browser_, web_contents_) ||
-      IsBookmarked(browser_, url))
-    return;
-
-  PromptDisplayReason reason = CheckPromptTriger(*visits);
-  UMA_HISTOGRAM_ENUMERATION("BookmarkPrompt.DisplayReason",
-                            reason,
-                            PROMPT_DISPLAY_REASON_LIMIT);
-  if (reason == PROMPT_DISPLAY_REASON_NOT_DISPLAY)
-    return;
-
-  BookmarkPromptPrefs prefs(browser_->profile()->GetPrefs());
-  prefs.IncrementPromptImpressionCount();
-  if (prefs.GetPromptImpressionCount() == kMaxPromptImpressionCount) {
-    UMA_HISTOGRAM_ENUMERATION("BookmarkPrompt.DisabledReason",
-                              PROMPT_DISABLED_REASON_BY_IMPRESSION_COUNT,
-                              PROMPT_DISABLED_REASON_LIMIT);
-    prefs.DisableBookmarkPrompt();
-  }
-  last_prompted_time_ = base::Time::Now();
-  last_prompted_url_ = web_contents_->GetURL();
-  browser_->window()->ShowBookmarkPrompt();
-}
-
-void BookmarkPromptController::SetBrowser(Browser* browser) {
-  if (browser_ == browser)
-    return;
-  if (browser_)
-    browser_->tab_strip_model()->RemoveObserver(this);
-  browser_ = browser;
-  if (browser_)
-    browser_->tab_strip_model()->AddObserver(this);
-  SetWebContents(browser_ ? browser_->tab_strip_model()->GetActiveWebContents()
-                          : NULL);
-}
-
-void BookmarkPromptController::SetWebContents(WebContents* web_contents) {
-  if (web_contents_) {
-    last_prompted_url_ = GURL::EmptyGURL();
-    query_url_consumer_.CancelAllRequests();
-    registrar_.Remove(
-        this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
-        content::Source<WebContents>(web_contents_));
-  }
-  web_contents_ = web_contents;
-  if (web_contents_) {
-    registrar_.Add(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
-                   content::Source<WebContents>(web_contents_));
-  }
-}
diff --git a/chrome/browser/ui/bookmarks/bookmark_prompt_controller.h b/chrome/browser/ui/bookmarks/bookmark_prompt_controller.h
deleted file mode 100644
index 20e8226..0000000
--- a/chrome/browser/ui/bookmarks/bookmark_prompt_controller.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_PROMPT_CONTROLLER_H_
-#define CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_PROMPT_CONTROLLER_H_
-
-#include "base/basictypes.h"
-#include "base/time/time.h"
-#include "chrome/browser/common/cancelable_request.h"
-#include "chrome/browser/history/history_types.h"
-#include "chrome/browser/ui/browser_list_observer.h"
-#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "url/gurl.h"
-
-class Browser;
-class PrefService;
-
-namespace content {
-class WebContents;
-}
-
-// BookmarkPromptController is a kind of singleton object held by
-// BrowserProcessImpl, and controls showing bookmark prompt for frequently
-// visited URLs.
-class BookmarkPromptController : public chrome::BrowserListObserver,
-                                 public content::NotificationObserver,
-                                 public TabStripModelObserver {
- public:
-  // When impression count is greater than |kMaxPromptImpressionCount|, we
-  // don't display bookmark prompt anymore.
-  static const int kMaxPromptImpressionCount;
-
-  // When user visited the URL 10 times, we show the bookmark prompt.
-  static const int kVisitCountForPermanentTrigger;
-
-  // When user visited the URL 3 times last 24 hours, we show the bookmark
-  // prompt.
-  static const int kVisitCountForSessionTrigger;
-
-  // An instance of BookmarkPromptController is constructed only if bookmark
-  // feature enabled.
-  BookmarkPromptController();
-  virtual ~BookmarkPromptController();
-
-  // Invoked when bookmark is added for |url| by clicking star icon in
-  // |browser|. Note: Clicking bookmark menu item in action box is also
-  // considered as clicking star icon.
-  static void AddedBookmark(Browser* browser, const GURL& url);
-
-  // Invoked when bookmark prompt is closing.
-  static void ClosingBookmarkPrompt();
-
-  // Disable bookmark prompt feature in a profile in |prefs|.
-  static void DisableBookmarkPrompt(PrefService* prefs);
-
-  // True if bookmark prompt feature is enabled, otherwise false.
-  static bool IsEnabled();
-
- private:
-  // TabStripModelObserver
-  virtual void ActiveTabChanged(content::WebContents* old_contents,
-                                content::WebContents* new_contents,
-                                int index,
-                                int reason) OVERRIDE;
-
-  void AddedBookmarkInternal(Browser* browser, const GURL& url);
-  void ClosingBookmarkPromptInternal();
-
-   // content::NotificationObserver:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) OVERRIDE;
-
-  // chrome::BrowserListObserver
-  virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
-  virtual void OnBrowserSetLastActive(Browser* browser) OVERRIDE;
-
-  // Callback for the HistoryService::QueryURL
-  void OnDidQueryURL(CancelableRequestProvider::Handle handle,
-                     bool success,
-                     const history::URLRow* url_row,
-                     history::VisitVector* visits);
-
-  // Set current active browser cache to |browser|. |browser| can be null.
-  void SetBrowser(Browser* browser);
-
-  // Set current active WebContents cache from |web_contents|. |web_contents|
-  // can be null.
-  void SetWebContents(content::WebContents* web_contents);
-
-  // Current active browser cache which we will display the prompt on it.
-  Browser* browser_;
-
-  // Current active WebContents cache which we will display the prompt for it.
-  content::WebContents* web_contents_;
-
-  // Remember last URL for recording metrics.
-  GURL last_prompted_url_;
-
-  // Last prompted time is used for measuring duration of prompt displaying
-  // time.
-  base::Time last_prompted_time_;
-
-  // Start time of HistoryService::QueryURL.
-  base::Time query_url_start_time_;
-
-  CancelableRequestConsumer query_url_consumer_;
-  content::NotificationRegistrar registrar_;
-
-  DISALLOW_COPY_AND_ASSIGN(BookmarkPromptController);
-};
-
-#endif  // CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_PROMPT_CONTROLLER_H_
diff --git a/chrome/browser/ui/bookmarks/bookmark_prompt_controller_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_prompt_controller_unittest.cc
deleted file mode 100644
index 4352b42..0000000
--- a/chrome/browser/ui/bookmarks/bookmark_prompt_controller_unittest.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
-
-#include "base/memory/scoped_ptr.h"
-#include "base/metrics/field_trial.h"
-#include "base/prefs/pref_service.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/test/base/browser_with_test_window_test.h"
-#include "chrome/test/base/test_browser_window.h"
-#include "chrome/test/base/testing_browser_process.h"
-#include "components/bookmarks/core/browser/bookmark_prompt_prefs.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
-#include "content/public/browser/web_contents.h"
-
-class BookmarkPromptControllerTest : public BrowserWithTestWindowTest {
- public:
-  BookmarkPromptControllerTest() : field_trial_list_(NULL), page_id_(0) {
-    base::FieldTrialList::CreateFieldTrial("BookmarkPrompt", "Experiment");
-  }
-
- protected:
-  int show_prompt_call_count() const {
-    return static_cast<MyTestBrowserWindow*>(browser()->window())->
-        show_prompt_call_count();
-  }
-
-  void Visit(const GURL& url) {
-    AddTab(browser(), url);
-
-    // Simulate page loaded.
-    ++page_id_;
-    content::WebContents* web_contents =
-        browser()->tab_strip_model()->GetActiveWebContents();
-    content::NotificationService::current()->Notify(
-        content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
-        content::Source<content::WebContents>(web_contents),
-        content::Details<int>(&page_id_));
-
-    // Wait until HistoryService::QueryURL completion.
-    static_cast<TestingProfile*>(browser()->profile())->
-        BlockUntilHistoryProcessesPendingRequests();
-  }
-
- private:
-  class MyTestBrowserWindow : public TestBrowserWindow {
-   public:
-    MyTestBrowserWindow() : show_prompt_call_count_(0) {}
-    int show_prompt_call_count() { return show_prompt_call_count_; }
-
-   private:
-    virtual bool IsActive() const OVERRIDE { return true; }
-    virtual void ShowBookmarkPrompt() OVERRIDE { ++show_prompt_call_count_; }
-    int show_prompt_call_count_;
-
-    DISALLOW_COPY_AND_ASSIGN(MyTestBrowserWindow);
-  };
-
-  virtual void SetUp() OVERRIDE {
-    TestingBrowserProcess::GetGlobal()->
-        SetBookmarkPromptController(new BookmarkPromptController);
-    BrowserWithTestWindowTest::SetUp();
-    ASSERT_TRUE(static_cast<TestingProfile*>(browser()->profile())->
-        CreateHistoryService(true, false));
-    static_cast<TestingProfile*>(browser()->profile())->
-        BlockUntilHistoryIndexIsRefreshed();
-    // Simulate browser activation.
-    BrowserList::SetLastActive(browser());
-  }
-
-  virtual void TearDown() OVERRIDE {
-    TestingBrowserProcess::GetGlobal()->
-        SetBookmarkPromptController(NULL);
-    static_cast<TestingProfile*>(browser()->profile())->
-        DestroyHistoryService();
-    BrowserWithTestWindowTest::TearDown();
-  }
-
-  virtual BrowserWindow* CreateBrowserWindow() OVERRIDE {
-    return new MyTestBrowserWindow;
-  }
-
-  base::FieldTrialList field_trial_list_;
-  int page_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(BookmarkPromptControllerTest);
-};
-
-// Test for maximum prompt impression count.
-TEST_F(BookmarkPromptControllerTest, MaxImpressionCountTest) {
-  BookmarkPromptPrefs prefs(browser()->profile()->GetPrefs());
-
-  // Simulate we've already display bookmark prompt many times.
-  for (int i = 0; i < BookmarkPromptController::kMaxPromptImpressionCount;
-       ++i) {
-    prefs.IncrementPromptImpressionCount();
-  }
-
-  // Visit the URL many times to display bookmark prompt.
-  GURL url("http://foo");
-  for (int visit_count = 1;
-       visit_count <= BookmarkPromptController::kVisitCountForSessionTrigger;
-       ++visit_count) {
-    Visit(url);
-  }
-
-  // Although, we don't display bookmark prompt since we've already displayed
-  // many times.
-  EXPECT_EQ(0, show_prompt_call_count());
-  EXPECT_EQ(BookmarkPromptController::kMaxPromptImpressionCount,
-            prefs.GetPromptImpressionCount());
-}
-
-// Test for session trigger and permanent trigger.
-TEST_F(BookmarkPromptControllerTest, TriggerTest) {
-  BookmarkPromptPrefs prefs(browser()->profile()->GetPrefs());
-
-  GURL url("http://foo");
-  for (int visit_count = 1;
-       visit_count < BookmarkPromptController::kVisitCountForPermanentTrigger;
-       ++visit_count) {
-    Visit(url);
-    if (visit_count < BookmarkPromptController::kVisitCountForSessionTrigger) {
-      EXPECT_EQ(0, show_prompt_call_count());
-      EXPECT_EQ(0, prefs.GetPromptImpressionCount());
-    } else {
-      EXPECT_EQ(1, show_prompt_call_count());
-      EXPECT_EQ(1, prefs.GetPromptImpressionCount());
-    }
-  }
-
-  Visit(url);
-
-  EXPECT_EQ(2, show_prompt_call_count());
-  EXPECT_EQ(2, prefs.GetPromptImpressionCount());
-}
diff --git a/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc b/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc
index ddfd86f..ae526df 100644
--- a/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_tab_helper.cc
@@ -112,14 +112,18 @@
   UpdateStarredStateForCurrentURL();
 }
 
-void BookmarkTabHelper::BookmarkNodeRemoved(BookmarkModel* model,
-                                            const BookmarkNode* parent,
-                                            int old_index,
-                                            const BookmarkNode* node) {
+void BookmarkTabHelper::BookmarkNodeRemoved(
+    BookmarkModel* model,
+    const BookmarkNode* parent,
+    int old_index,
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {
   UpdateStarredStateForCurrentURL();
 }
 
-void BookmarkTabHelper::BookmarkAllNodesRemoved(BookmarkModel* model) {
+void BookmarkTabHelper::BookmarkAllNodesRemoved(
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
   UpdateStarredStateForCurrentURL();
 }
 
diff --git a/chrome/browser/ui/bookmarks/bookmark_tab_helper.h b/chrome/browser/ui/bookmarks/bookmark_tab_helper.h
index 2a6bbbc..60ea5dd 100644
--- a/chrome/browser/ui/bookmarks/bookmark_tab_helper.h
+++ b/chrome/browser/ui/bookmarks/bookmark_tab_helper.h
@@ -72,8 +72,11 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
 
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE;
diff --git a/chrome/browser/ui/bookmarks/bookmark_ui_utils_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_ui_utils_unittest.cc
index 36a06ab..292fbf8 100644
--- a/chrome/browser/ui/bookmarks/bookmark_ui_utils_unittest.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_ui_utils_unittest.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
 
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/test_bookmark_client.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/test_bookmark_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if !defined(OS_ANDROID) && !defined(OS_IOS)
diff --git a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc
index 8deec49..c125265 100644
--- a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc
+++ b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.cc
@@ -180,8 +180,8 @@
     BookmarkModel* model,
     const BookmarkNode* parent,
     int old_index,
-    const BookmarkNode* node) {
-}
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {}
 
 void RecentlyUsedFoldersComboModel::BookmarkNodeChanged(
     BookmarkModel* model,
@@ -199,7 +199,8 @@
 }
 
 void RecentlyUsedFoldersComboModel::BookmarkAllNodesRemoved(
-    BookmarkModel* model) {
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
   // Changing is rare enough that we don't attempt to readjust the contents.
   // Update |items_| so we aren't left pointing to a deleted node.
   bool changed = false;
diff --git a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h
index 30addf3..7efcb05 100644
--- a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h
+++ b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h
@@ -53,7 +53,8 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE;
   virtual void BookmarkNodeFaviconChanged(BookmarkModel* model,
@@ -61,7 +62,9 @@
   virtual void BookmarkNodeChildrenReordered(
       BookmarkModel* model,
       const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
 
   // If necessary this function moves |node| into the corresponding folder for
   // the given |selected_index|.
diff --git a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc
index 6385cc4..012ae2f 100644
--- a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc
+++ b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc
@@ -8,9 +8,9 @@
 #include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/models/combobox_model_observer.h"
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 78dc3cc..1411716 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -169,7 +169,6 @@
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/page_zoom.h"
 #include "content/public/common/renderer_preferences.h"
@@ -880,7 +879,7 @@
   ScheduleUIUpdate(contents, content::INVALIDATE_TYPE_URL);
 
   if (contents_is_selected)
-    contents->GetView()->SetInitialFocus();
+    contents->SetInitialFocus();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1717,12 +1716,11 @@
   return true;
 }
 
-gfx::Size Browser::GetSizeForNewRenderView(
-    const WebContents* web_contents) const {
+gfx::Size Browser::GetSizeForNewRenderView(WebContents* web_contents) const {
   // When navigating away from NTP with unpinned bookmark bar, the bookmark bar
   // would disappear on non-NTP pages, resulting in a bigger size for the new
   // render view.
-  gfx::Size size = web_contents->GetView()->GetContainerSize();
+  gfx::Size size = web_contents->GetContainerBounds().size();
   // Don't change render view size if bookmark bar is currently not detached,
   // or there's no pending entry, or navigating to a NTP page.
   if (size.IsEmpty() || bookmark_bar_state_ != BookmarkBar::DETACHED)
@@ -1822,7 +1820,7 @@
   }
   tab_strip_model_->SetTabBlocked(index, blocked);
   if (!blocked && tab_strip_model_->GetActiveWebContents() == web_contents)
-    web_contents->GetView()->Focus();
+    web_contents->Focus();
 }
 
 web_modal::WebContentsModalDialogHost*
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index efc35f1..7172f5c 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -642,7 +642,7 @@
       const base::FilePath& plugin_path,
       const base::Callback<void(bool)>& callback) OVERRIDE;
   virtual gfx::Size GetSizeForNewRenderView(
-      const content::WebContents* web_contents) const OVERRIDE;
+      content::WebContents* web_contents) const OVERRIDE;
 
   // Overridden from CoreTabHelperDelegate:
   // Note that the caller is responsible for deleting |old_contents|.
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index 64322fe..96cf626 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -70,7 +70,6 @@
 #include "content/public/browser/resource_context.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/frame_navigate_params.h"
 #include "content/public/common/page_transition_types.h"
 #include "content/public/common/renderer_preferences.h"
@@ -205,7 +204,7 @@
       content::ResourceContext* resource_context,
       const GURL& current_url,
       const GURL& new_url) OVERRIDE {
-    return new_url.SchemeIs(content::kHttpsScheme);
+    return new_url.SchemeIs(url::kHttpsScheme);
   }
 };
 
@@ -313,7 +312,7 @@
     render_view_sizes_[rvh].rwhv_commit_size =
         web_contents()->GetRenderWidgetHostView()->GetViewBounds().size();
     render_view_sizes_[rvh].wcv_commit_size =
-        web_contents()->GetView()->GetContainerSize();
+        web_contents()->GetContainerBounds().size();
   }
 
  private:
@@ -632,7 +631,7 @@
     params_ = params;
   }
 
-  virtual void WebContentsDestroyed(WebContents* contents) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     // Make sure we don't close the tab while the observer is in scope.
     // See http://crbug.com/314036.
     FAIL() << "WebContents closed during navigation (http://crbug.com/314036).";
@@ -1120,7 +1119,7 @@
 
   ASSERT_TRUE(test_server()->Start());
   GURL http_url(test_server()->GetURL(std::string()));
-  ASSERT_TRUE(http_url.SchemeIs(content::kHttpScheme));
+  ASSERT_TRUE(http_url.SchemeIs(url::kHttpScheme));
   ui_test_utils::NavigateToURL(browser(), http_url);
   EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));
 }
@@ -1134,7 +1133,7 @@
                                      base::FilePath(kDocRoot));
   ASSERT_TRUE(test_server.Start());
   GURL https_url(test_server.GetURL("/"));
-  ASSERT_TRUE(https_url.SchemeIs(content::kHttpsScheme));
+  ASSERT_TRUE(https_url.SchemeIs(url::kHttpsScheme));
   ui_test_utils::NavigateToURL(browser(), https_url);
   EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS));
 }
@@ -1180,7 +1179,7 @@
 IN_PROC_BROWSER_TEST_F(BrowserTest, DISABLED_ConvertTabToAppShortcut) {
   ASSERT_TRUE(test_server()->Start());
   GURL http_url(test_server()->GetURL(std::string()));
-  ASSERT_TRUE(http_url.SchemeIs(content::kHttpScheme));
+  ASSERT_TRUE(http_url.SchemeIs(url::kHttpScheme));
 
   ASSERT_EQ(1, browser()->tab_strip_model()->count());
   WebContents* initial_tab = browser()->tab_strip_model()->GetWebContentsAt(0);
@@ -2602,7 +2601,7 @@
   const int height_inset =
       browser()->window()->GetRenderViewHeightInsetWithDetachedBookmarkBar();
   const gfx::Size initial_wcv_size =
-      web_contents->GetView()->GetContainerSize();
+      web_contents->GetContainerBounds().size();
   RenderViewSizeObserver observer(web_contents, browser()->window());
 
   // Navigate to a non-NTP page, without resizing WebContentsView.
@@ -2638,9 +2637,9 @@
 #if defined(OS_MACOSX)
   EXPECT_EQ(gfx::Size(wcv_commit_size0.width(),
                       wcv_commit_size0.height() + height_inset),
-            web_contents->GetView()->GetContainerSize());
+            web_contents->GetContainerBounds().size());
 #else
-  EXPECT_EQ(wcv_commit_size0, web_contents->GetView()->GetContainerSize());
+  EXPECT_EQ(wcv_commit_size0, web_contents->GetContainerBounds().size());
 #endif
 
   // Navigate to another non-NTP page, without resizing WebContentsView.
@@ -2657,7 +2656,7 @@
   EXPECT_EQ(rwhv_create_size1, rwhv_commit_size1);
   EXPECT_EQ(rwhv_commit_size1,
             web_contents->GetRenderWidgetHostView()->GetViewBounds().size());
-  EXPECT_EQ(wcv_commit_size1, web_contents->GetView()->GetContainerSize());
+  EXPECT_EQ(wcv_commit_size1, web_contents->GetContainerBounds().size());
 
   // Navigate from NTP to a non-NTP page, resizing WebContentsView while
   // navigation entry is pending.
@@ -2707,5 +2706,5 @@
                          wcv_resize_insets.height() + height_inset);
   EXPECT_EQ(exp_final_size,
             web_contents->GetRenderWidgetHostView()->GetViewBounds().size());
-  EXPECT_EQ(exp_final_size, web_contents->GetView()->GetContainerSize());
+  EXPECT_EQ(exp_final_size, web_contents->GetContainerBounds().size());
 }
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 14ee6d5..354932e 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -534,9 +534,6 @@
     case IDC_BOOKMARK_PAGE:
       BookmarkCurrentPage(browser_);
       break;
-    case IDC_BOOKMARK_PAGE_FROM_STAR:
-      BookmarkCurrentPageFromStar(browser_);
-      break;
     case IDC_PIN_TO_START_SCREEN:
       TogglePagePinnedToStartScreen(browser_);
       break;
@@ -562,6 +559,11 @@
     case IDC_TRANSLATE_PAGE:
       Translate(browser_);
       break;
+    case IDC_MANAGE_PASSWORDS_FOR_PAGE:
+      ManagePasswordsForPage(browser_);
+      break;
+
+    // Page encoding commands
     case IDC_ENCODING_AUTO_DETECT:
       browser_->ToggleEncodingAutoDetect();
       break;
@@ -920,7 +922,7 @@
 
   // Page-related commands
   command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
-  command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE_FROM_STAR, true);
+  command_updater_.UpdateCommandEnabled(IDC_MANAGE_PASSWORDS_FOR_PAGE, true);
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
@@ -1062,23 +1064,26 @@
       IDC_NEW_INCOGNITO_WINDOW,
       incognito_availability != IncognitoModePrefs::DISABLED);
 
-  // Bookmark manager and settings page/subpages are forced to open in normal
-  // mode. For this reason we disable these commands when incognito is forced.
-  const bool command_enabled =
-      incognito_availability != IncognitoModePrefs::FORCED &&
-      !profile->IsGuestSession();
+  const bool guest_session = profile->IsGuestSession();
+  const bool forced_incognito =
+      incognito_availability == IncognitoModePrefs::FORCED ||
+      guest_session;  // Guest always runs in Incognito mode.
   command_updater->UpdateCommandEnabled(
       IDC_SHOW_BOOKMARK_MANAGER,
-      browser_defaults::bookmarks_enabled && command_enabled);
+      browser_defaults::bookmarks_enabled && !forced_incognito);
   ExtensionService* extension_service = profile->GetExtensionService();
-  bool enable_extensions =
+  const bool enable_extensions =
       extension_service && extension_service->extensions_enabled();
-  command_updater->UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
-                                        enable_extensions && command_enabled);
 
-  command_updater->UpdateCommandEnabled(IDC_IMPORT_SETTINGS, command_enabled);
-  command_updater->UpdateCommandEnabled(IDC_OPTIONS, command_enabled);
-  command_updater->UpdateCommandEnabled(IDC_SHOW_SIGNIN, command_enabled);
+  // Bookmark manager and settings page/subpages are forced to open in normal
+  // mode. For this reason we disable these commands when incognito is forced.
+  command_updater->UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
+                                        enable_extensions && !forced_incognito);
+
+  command_updater->UpdateCommandEnabled(IDC_IMPORT_SETTINGS, !forced_incognito);
+  command_updater->UpdateCommandEnabled(IDC_OPTIONS,
+                                        !forced_incognito || guest_session);
+  command_updater->UpdateCommandEnabled(IDC_SHOW_SIGNIN, !forced_incognito);
 }
 
 void BrowserCommandController::UpdateCommandsForIncognitoAvailability() {
@@ -1244,11 +1249,12 @@
   // Settings page/subpages are forced to open in normal mode. We disable these
   // commands for guest sessions and when incognito is forced.
   const bool options_enabled = show_main_ui &&
-      !profile()->IsGuestSession() &&
       IncognitoModePrefs::GetAvailability(
           profile()->GetPrefs()) != IncognitoModePrefs::FORCED;
+  const bool guest_session = profile()->IsGuestSession();
   command_updater_.UpdateCommandEnabled(IDC_OPTIONS, options_enabled);
-  command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, options_enabled);
+  command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS,
+                                        options_enabled && !guest_session);
 
   command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
   command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
diff --git a/chrome/browser/ui/browser_command_controller_unittest.cc b/chrome/browser/ui/browser_command_controller_unittest.cc
index 449723d..b080e71 100644
--- a/chrome/browser/ui/browser_command_controller_unittest.cc
+++ b/chrome/browser/ui/browser_command_controller_unittest.cc
@@ -8,6 +8,7 @@
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/command_updater.h"
+#include "chrome/browser/prefs/incognito_mode_prefs.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/browser/ui/browser.h"
@@ -133,6 +134,32 @@
 #endif  // USE_AURA
 }
 
+TEST_F(BrowserCommandControllerTest, IncognitoCommands) {
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_OPTIONS));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_IMPORT_SETTINGS));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_SHOW_SIGNIN));
+
+  TestingProfile* testprofile = browser()->profile()->AsTestingProfile();
+  EXPECT_TRUE(testprofile);
+  testprofile->SetGuestSession(true);
+  chrome::BrowserCommandController
+    ::UpdateSharedCommandsForIncognitoAvailability(
+      browser()->command_controller()->command_updater(), testprofile);
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_OPTIONS));
+  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_IMPORT_SETTINGS));
+  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_SHOW_SIGNIN));
+
+  testprofile->SetGuestSession(false);
+  IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
+                                      IncognitoModePrefs::FORCED);
+  chrome::BrowserCommandController
+    ::UpdateSharedCommandsForIncognitoAvailability(
+      browser()->command_controller()->command_updater(), testprofile);
+  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_OPTIONS));
+  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_IMPORT_SETTINGS));
+  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_SHOW_SIGNIN));
+}
+
 TEST_F(BrowserCommandControllerTest, AppFullScreen) {
   // Enable for tabbed browser.
   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FULLSCREEN));
@@ -433,7 +460,8 @@
   testprofile->SetGuestSession(true);
 
   browser()->command_controller()->FullscreenStateChanged();
-  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_OPTIONS));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_OPTIONS));
+  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_IMPORT_SETTINGS));
 }
 
 TEST_F(BrowserCommandControllerTest, IncognitoModeOnSigninAllowedPrefChange) {
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 6216d5a..b266077 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -32,7 +32,6 @@
 #include "chrome/browser/sessions/tab_restore_service_factory.h"
 #include "chrome/browser/translate/translate_tab_helper.h"
 #include "chrome/browser/ui/accelerator_utils.h"
-#include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_command_controller.h"
@@ -72,7 +71,6 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/renderer_preferences.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/url_utils.h"
@@ -161,7 +159,7 @@
   return false;
 }
 
-void BookmarkCurrentPageInternal(Browser* browser, bool from_star) {
+void BookmarkCurrentPageInternal(Browser* browser) {
   content::RecordAction(UserMetricsAction("Star"));
 
   BookmarkModel* model =
@@ -181,8 +179,6 @@
     FaviconTabHelper::FromWebContents(web_contents)->SaveFavicon();
   }
   bookmark_utils::AddIfNotBookmarked(model, url, title);
-  if (from_star && !was_bookmarked)
-    BookmarkPromptController::AddedBookmark(browser, url);
   // Make sure the model actually added a bookmark before showing the star. A
   // bookmark isn't created if the url is invalid.
   if (browser->window()->IsActive() && model->IsBookmarked(url)) {
@@ -235,7 +231,7 @@
   WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
   new_tab->UserGestureDone();
   if (!new_tab->FocusLocationBarByDefault())
-    new_tab->GetView()->Focus();
+    new_tab->Focus();
   if (ignore_cache)
     new_tab->GetController().ReloadIgnoringCache(true);
   else
@@ -558,8 +554,7 @@
 
   if (browser->is_type_tabbed()) {
     AddTabAt(browser, GURL(), -1, true);
-    browser->tab_strip_model()->GetActiveWebContents()->GetView()->
-        RestoreFocus();
+    browser->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
   } else {
     ScopedTabbedBrowserDisplayer displayer(browser->profile(),
                                            browser->host_desktop_type());
@@ -569,7 +564,7 @@
     // The call to AddBlankTabAt above did not set the focus to the tab as its
     // window was not active, so we have to do it explicitly.
     // See http://crbug.com/6380.
-    b->tab_strip_model()->GetActiveWebContents()->GetView()->RestoreFocus();
+    b->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
   }
 }
 
@@ -743,11 +738,7 @@
     };
   }
 
-  BookmarkCurrentPageInternal(browser, false);
-}
-
-void BookmarkCurrentPageFromStar(Browser* browser) {
-  BookmarkCurrentPageInternal(browser, true);
+  BookmarkCurrentPageInternal(browser);
 }
 
 bool CanBookmarkCurrentPage(const Browser* browser) {
@@ -784,6 +775,18 @@
       web_contents, step, TranslateErrors::NONE);
 }
 
+void ManagePasswordsForPage(Browser* browser) {
+// TODO(mkwst): Implement this feature on Mac: http://crbug.com/261628
+#if !defined(OS_MACOSX)
+  if (!browser->window()->IsActive())
+    return;
+
+  WebContents* web_contents =
+      browser->tab_strip_model()->GetActiveWebContents();
+  chrome::ShowManagePasswordsBubble(web_contents);
+#endif
+}
+
 void TogglePagePinnedToStartScreen(Browser* browser) {
 #if defined(OS_WIN)
   MetroPinTabHelper::FromWebContents(
@@ -1059,12 +1062,9 @@
 }
 
 void ToggleSpeechInput(Browser* browser) {
-  WebContents* web_contents =
-      browser->tab_strip_model()->GetActiveWebContents();
-  web_contents->GetRenderViewHost()->ToggleSpeechInput();
-
   SearchTabHelper* search_tab_helper =
-      SearchTabHelper::FromWebContents(web_contents);
+      SearchTabHelper::FromWebContents(
+          browser->tab_strip_model()->GetActiveWebContents());
   // |search_tab_helper| can be null in unit tests.
   if (search_tab_helper)
     search_tab_helper->ToggleVoiceSearch();
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h
index b060450..fe63b0e 100644
--- a/chrome/browser/ui/browser_commands.h
+++ b/chrome/browser/ui/browser_commands.h
@@ -92,11 +92,11 @@
 void ConvertPopupToTabbedBrowser(Browser* browser);
 void Exit();
 void BookmarkCurrentPage(Browser* browser);
-void BookmarkCurrentPageFromStar(Browser* browser);
 bool CanBookmarkCurrentPage(const Browser* browser);
 void BookmarkAllTabs(Browser* browser);
 bool CanBookmarkAllTabs(const Browser* browser);
 void Translate(Browser* browser);
+void ManagePasswordsForPage(Browser* browser);
 void TogglePagePinnedToStartScreen(Browser* browser);
 void SavePage(Browser* browser);
 bool CanSavePage(const Browser* browser);
diff --git a/chrome/browser/ui/browser_dialogs.h b/chrome/browser/ui/browser_dialogs.h
index cff9e76..ac688d6 100644
--- a/chrome/browser/ui/browser_dialogs.h
+++ b/chrome/browser/ui/browser_dialogs.h
@@ -80,12 +80,12 @@
 #endif
 
 // Shows the create chrome app shortcut dialog box.
-// On Mac, this creates a shortcut without prompting.
 // |close_callback| may be null.
-void ShowCreateChromeAppShortcutsDialog(gfx::NativeWindow parent_window,
-                                        Profile* profile,
-                                        const extensions::Extension* app,
-                                        const base::Closure& close_callback);
+void ShowCreateChromeAppShortcutsDialog(
+    gfx::NativeWindow parent_window,
+    Profile* profile,
+    const extensions::Extension* app,
+    const base::Callback<void(bool /* created */)>& close_callback);
 
 // Shows a color chooser that reports to the given WebContents.
 content::ColorChooser* ShowColorChooser(content::WebContents* web_contents,
@@ -114,6 +114,13 @@
     content::WebContents* web_contents,
     const content::SignedCertificateTimestampIDStatusList& sct_ids_list);
 
+#if !defined(OS_MACOSX)
+// Shows the ManagePasswords bubble for a particular |web_contents|.
+//
+// TODO(mkwst): Implement this feature on Mac: http://crbug.com/261628
+void ShowManagePasswordsBubble(content::WebContents* web_contents);
+#endif
+
 }  // namespace chrome
 
 #endif  // CHROME_BROWSER_UI_BROWSER_DIALOGS_H_
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc
index 4d1d1c3..7c95050 100644
--- a/chrome/browser/ui/browser_focus_uitest.cc
+++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -33,7 +33,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 
@@ -287,7 +286,7 @@
 
       // Activate the location bar or the page.
       if (kFocusPage[i][j]) {
-        browser()->tab_strip_model()->GetWebContentsAt(j)->GetView()->Focus();
+        browser()->tab_strip_model()->GetWebContentsAt(j)->Focus();
       } else {
         chrome::FocusLocationBar(browser());
       }
diff --git a/chrome/browser/ui/browser_instant_controller.cc b/chrome/browser/ui/browser_instant_controller.cc
index 7bac258..3e95e32 100644
--- a/chrome/browser/ui/browser_instant_controller.cc
+++ b/chrome/browser/ui/browser_instant_controller.cc
@@ -25,9 +25,9 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
-using base::UserMetricsAction;
+
+// Helpers --------------------------------------------------------------------
 
 namespace {
 
@@ -40,8 +40,8 @@
 
 }  // namespace
 
-////////////////////////////////////////////////////////////////////////////////
-// BrowserInstantController, public:
+
+// BrowserInstantController ---------------------------------------------------
 
 BrowserInstantController::BrowserInstantController(Browser* browser)
     : browser_(browser),
@@ -120,9 +120,6 @@
     prerenderer->Cancel();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// BrowserInstantController, SearchModelObserver implementation:
-
 void BrowserInstantController::ModelChanged(
     const SearchModel::State& old_state,
     const SearchModel::State& new_state) {
@@ -133,9 +130,9 @@
     // the full story, it's necessary to look at other UMA actions as well,
     // such as tab switches.
     if (new_mode.is_search_results())
-      content::RecordAction(UserMetricsAction("InstantExtended.ShowSRP"));
+      content::RecordAction(base::UserMetricsAction("InstantExtended.ShowSRP"));
     else if (new_mode.is_ntp())
-      content::RecordAction(UserMetricsAction("InstantExtended.ShowNTP"));
+      content::RecordAction(base::UserMetricsAction("InstantExtended.ShowNTP"));
 
     instant_.SearchModeChanged(old_state.mode, new_mode);
   }
@@ -144,18 +141,7 @@
     instant_.InstantSupportChanged(new_state.instant_support);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// BrowserInstantController, InstantServiceObserver implementation:
-
 void BrowserInstantController::DefaultSearchProviderChanged() {
-  ReloadTabsInInstantProcess();
-}
-
-void BrowserInstantController::GoogleURLUpdated() {
-  ReloadTabsInInstantProcess();
-}
-
-void BrowserInstantController::ReloadTabsInInstantProcess() {
   InstantService* instant_service =
       InstantServiceFactory::GetForProfile(profile());
   if (!instant_service)
diff --git a/chrome/browser/ui/browser_instant_controller.h b/chrome/browser/ui/browser_instant_controller.h
index d9c70ca..3953c69 100644
--- a/chrome/browser/ui/browser_instant_controller.h
+++ b/chrome/browser/ui/browser_instant_controller.h
@@ -48,17 +48,12 @@
   void TabDeactivated(content::WebContents* contents);
 
  private:
-  // Overridden from search::SearchModelObserver:
+  // SearchModelObserver:
   virtual void ModelChanged(const SearchModel::State& old_state,
                             const SearchModel::State& new_state) OVERRIDE;
 
-  // Overridden from InstantServiceObserver:
+  // InstantServiceObserver:
   virtual void DefaultSearchProviderChanged() OVERRIDE;
-  virtual void GoogleURLUpdated() OVERRIDE;
-
-  // Reloads the tabs in instant process to ensure that their privileged status
-  // is still valid.
-  void ReloadTabsInInstantProcess();
 
   // Replaces the contents at tab |index| with |new_contents| and deletes the
   // existing contents.
diff --git a/chrome/browser/ui/browser_instant_controller_unittest.cc b/chrome/browser/ui/browser_instant_controller_unittest.cc
index d93ef56..1a8c1e0 100644
--- a/chrome/browser/ui/browser_instant_controller_unittest.cc
+++ b/chrome/browser/ui/browser_instant_controller_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/basictypes.h"
 #include "base/memory/scoped_vector.h"
+#include "base/metrics/field_trial.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/search/instant_service.h"
 #include "chrome/browser/search/instant_service_observer.h"
@@ -25,6 +26,13 @@
 namespace {
 
 class BrowserInstantControllerTest : public InstantUnitTestBase {
+ public:
+  virtual void SetUp() OVERRIDE {
+    ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
+        "EmbeddedSearch", "Group1 use_cacheable_ntp:1 prefetch_results:1"));
+    InstantUnitTestBase::SetUp();
+  }
+
  protected:
   friend class FakeWebContentsObserver;
 };
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc
index 2d65644..39cf2b5 100644
--- a/chrome/browser/ui/browser_navigator.cc
+++ b/chrome/browser/ui/browser_navigator.cc
@@ -39,7 +39,6 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_set.h"
@@ -340,7 +339,7 @@
       tab_util::GetSiteInstanceForNewTab(params.browser->profile(), url));
   if (params.source_contents) {
     create_params.initial_size =
-        params.source_contents->GetView()->GetContainerSize();
+        params.source_contents->GetContainerBounds().size();
     if (params.should_set_opener)
       create_params.opener = params.source_contents;
   }
@@ -661,7 +660,7 @@
       (params->disposition == NEW_FOREGROUND_TAB ||
        params->disposition == NEW_WINDOW) &&
       (params->tabstrip_add_types & TabStripModel::ADD_INHERIT_OPENER))
-    params->source_contents->GetView()->Focus();
+    params->source_contents->Focus();
 
   if (params->source_contents == params->target_contents ||
       (swapped_in_prerender && params->disposition == CURRENT_TAB)) {
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc
index 9a8e237..4af97b9 100644
--- a/chrome/browser/ui/browser_navigator_browsertest.cc
+++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "base/prefs/pref_service.h"
+#include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
@@ -26,8 +27,6 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "ipc/ipc_message.h"
 
 using content::WebContents;
 
@@ -131,7 +130,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   if (base_web_contents) {
     create_params.initial_size =
-        base_web_contents->GetView()->GetContainerSize();
+        base_web_contents->GetContainerBounds().size();
   }
   return WebContents::Create(create_params);
 }
@@ -736,7 +735,7 @@
   // All platforms should respect size however provided width > 400 (Mac has a
   // minimum window width of 400).
   EXPECT_EQ(p.window_bounds.size(),
-            p.target_contents->GetView()->GetContainerSize());
+            p.target_contents->GetContainerBounds().size());
 
   // We should have two windows, the new popup and the browser() provided by the
   // framework.
diff --git a/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc b/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc
index eeb0e7d..98052b0 100644
--- a/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc
+++ b/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc
@@ -39,16 +39,18 @@
   // MultiUserWindowManager overrides:
   virtual void SetWindowOwner(
       aura::Window* window, const std::string& user_id) OVERRIDE;
-  virtual const std::string& GetWindowOwner(aura::Window* window) OVERRIDE;
+  virtual const std::string& GetWindowOwner(
+      aura::Window* window) const OVERRIDE;
   virtual void ShowWindowForUser(
       aura::Window* window, const std::string& user_id) OVERRIDE;
-  virtual bool AreWindowsSharedAmongUsers() OVERRIDE;
+  virtual bool AreWindowsSharedAmongUsers() const OVERRIDE;
   virtual void GetOwnersOfVisibleWindows(
-      std::set<std::string>* user_ids) OVERRIDE;
-  virtual bool IsWindowOnDesktopOfUser(aura::Window* window,
-                                       const std::string& user_id) OVERRIDE;
+      std::set<std::string>* user_ids) const OVERRIDE;
+  virtual bool IsWindowOnDesktopOfUser(
+      aura::Window* window,
+      const std::string& user_id) const OVERRIDE;
   virtual const std::string& GetUserPresentingWindow(
-      aura::Window* window) OVERRIDE;
+      aura::Window* window) const OVERRIDE;
   virtual void AddUser(content::BrowserContext* profile) OVERRIDE;
   virtual void AddObserver(Observer* observer) OVERRIDE;
   virtual void RemoveObserver(Observer* observer) OVERRIDE;
@@ -95,7 +97,7 @@
 }
 
 const std::string& TestMultiUserWindowManager::GetWindowOwner(
-    aura::Window* window) {
+    aura::Window* window) const {
   // No matter which window will get queried - all browsers belong to the
   // original browser's user.
   return browser_owner_;
@@ -112,22 +114,22 @@
   created_window_shown_for_ = user_id;
 }
 
-bool TestMultiUserWindowManager::AreWindowsSharedAmongUsers() {
+bool TestMultiUserWindowManager::AreWindowsSharedAmongUsers() const {
   return browser_owner_ != desktop_owner_;
 }
 
 void TestMultiUserWindowManager::GetOwnersOfVisibleWindows(
-    std::set<std::string>* user_ids) {
+    std::set<std::string>* user_ids) const {
 }
 
 bool TestMultiUserWindowManager::IsWindowOnDesktopOfUser(
     aura::Window* window,
-    const std::string& user_id) {
+    const std::string& user_id) const {
   return GetUserPresentingWindow(window) == user_id;
 }
 
 const std::string& TestMultiUserWindowManager::GetUserPresentingWindow(
-    aura::Window* window) {
+    aura::Window* window) const {
   if (window == browser_window_)
     return desktop_owner_;
   if (created_window_ && window == created_window_)
diff --git a/chrome/browser/ui/browser_tabrestore.cc b/chrome/browser/ui/browser_tabrestore.cc
index 38a9a93..abe591c 100644
--- a/chrome/browser/ui/browser_tabrestore.cc
+++ b/chrome/browser/ui/browser_tabrestore.cc
@@ -17,7 +17,6 @@
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/session_storage_namespace.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 using content::WebContents;
 using content::NavigationController;
@@ -62,7 +61,7 @@
       browser->tab_strip_model()->GetActiveWebContents();
   if (base_web_contents) {
     create_params.initial_size =
-        base_web_contents->GetView()->GetContainerSize();
+        base_web_contents->GetContainerBounds().size();
   }
   WebContents* web_contents = content::WebContents::CreateWithSessionStorage(
       create_params,
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index 491b990..431c35a 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -226,10 +226,6 @@
   virtual void ShowBookmarkAppBubble(const WebApplicationInfo& web_app_info,
                                      const std::string& extension_id) = 0;
 
-  // Shows the bookmark prompt.
-  // TODO(yosin): Make ShowBookmarkPrompt pure virtual.
-  virtual void ShowBookmarkPrompt() {}
-
   // Shows the translate bubble.
   virtual void ShowTranslateBubble(content::WebContents* contents,
                                    translate::TranslateStep step,
diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc
index 08df687..821f669 100644
--- a/chrome/browser/ui/chrome_pages.cc
+++ b/chrome/browser/ui/chrome_pages.cc
@@ -108,6 +108,11 @@
   ShowSingletonTab(browser, url);
 }
 
+bool SettingsWindowEnabled() {
+  return CommandLine::ForCurrentProcess()->HasSwitch(
+      ::switches::kEnableSettingsWindow);
+}
+
 }  // namespace
 
 void ShowBookmarkManager(Browser* browser) {
@@ -124,6 +129,11 @@
 
 void ShowHistory(Browser* browser) {
   content::RecordAction(UserMetricsAction("ShowHistory"));
+  if (SettingsWindowEnabled()) {
+    SettingsWindowManager::GetInstance()->ShowChromePageForProfile(
+        browser->profile(), GURL(kChromeUIHistoryURL));
+    return;
+  }
   NavigateParams params(
       GetSingletonTabNavigateParams(browser, GURL(kChromeUIHistoryURL)));
   params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
@@ -146,6 +156,11 @@
 void ShowExtensions(Browser* browser,
                     const std::string& extension_to_highlight) {
   content::RecordAction(UserMetricsAction("ShowExtensions"));
+  if (SettingsWindowEnabled()) {
+    SettingsWindowManager::GetInstance()->ShowChromePageForProfile(
+        browser->profile(), GURL(kChromeUIExtensionsURL));
+    return;
+  }
   NavigateParams params(
       GetSingletonTabNavigateParams(browser, GURL(kChromeUIExtensionsURL)));
   params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE;
@@ -230,10 +245,8 @@
 }
 
 void ShowSettingsSubPage(Browser* browser, const std::string& sub_page) {
-  if (CommandLine::ForCurrentProcess()->HasSwitch(
-          ::switches::kEnableSettingsWindow)) {
-    SettingsWindowManager::GetInstance()->ShowForProfile(browser->profile(),
-                                                         sub_page);
+  if (SettingsWindowEnabled()) {
+    ShowSettingsSubPageForProfile(browser->profile(), sub_page);
     return;
   }
   ShowSettingsSubPageInTabbedBrowser(browser, sub_page);
@@ -241,9 +254,10 @@
 
 void ShowSettingsSubPageForProfile(Profile* profile,
                                    const std::string& sub_page) {
-  if (CommandLine::ForCurrentProcess()->HasSwitch(
-          ::switches::kEnableSettingsWindow)) {
-    SettingsWindowManager::GetInstance()->ShowForProfile(profile, sub_page);
+  if (SettingsWindowEnabled()) {
+    content::RecordAction(base::UserMetricsAction("ShowOptions"));
+    SettingsWindowManager::GetInstance()->ShowChromePageForProfile(
+        profile, GetSettingsUrl(sub_page));
     return;
   }
   Browser* browser =
diff --git a/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc b/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc
index da6396e..33fd605 100644
--- a/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc
+++ b/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc
@@ -6,7 +6,6 @@
 
 #include "chrome/browser/platform_util.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 ChromeWebModalDialogManagerDelegate::ChromeWebModalDialogManagerDelegate() {
 }
@@ -16,5 +15,5 @@
 
 bool ChromeWebModalDialogManagerDelegate::IsWebContentsVisible(
     content::WebContents* web_contents) {
-  return platform_util::IsVisible(web_contents->GetView()->GetNativeView());
+  return platform_util::IsVisible(web_contents->GetNativeView());
 }
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm b/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm
index d9a6a65..6d32c03 100644
--- a/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm
+++ b/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm
@@ -5,9 +5,9 @@
 #import "chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.h"
 
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 
 @implementation FakeAppDelegate
 
diff --git a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm
index a65e792..3147386 100644
--- a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm
+++ b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm
@@ -282,8 +282,13 @@
   if ([name isEqualToString:NSWindowDidBecomeMainNotification]) {
     apps::AppWindow* appWindow =
         apps::AppWindowRegistry::GetAppWindowForNativeWindowAnyProfile(window);
+
+    const extensions::Extension* extension = NULL;
     if (appWindow)
-      [self addMenuItems:appWindow->extension()];
+      extension = appWindow->GetExtension();
+
+    if (extension)
+      [self addMenuItems:extension];
     else
       [self removeMenuItems];
   } else if ([name isEqualToString:NSWindowWillCloseNotification]) {
diff --git a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h
index 0bc5110..716c573 100644
--- a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h
+++ b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h
@@ -8,7 +8,6 @@
 #import <Cocoa/Cocoa.h>
 #include <vector>
 
-#include "apps/app_window.h"
 #include "apps/size_constraints.h"
 #include "apps/ui/native_app_window.h"
 #include "base/mac/scoped_nsobject.h"
@@ -18,6 +17,10 @@
 #include "extensions/common/draggable_region.h"
 #include "ui/gfx/rect.h"
 
+namespace apps {
+class AppWindow;
+}
+
 class ExtensionKeybindingRegistryCocoa;
 class NativeAppWindowCocoa;
 @class ShellNSWindow;
@@ -156,13 +159,7 @@
   virtual ~NativeAppWindowCocoa();
 
   ShellNSWindow* window() const;
-
-  content::WebContents* web_contents() const {
-    return app_window_->web_contents();
-  }
-  const extensions::Extension* extension() const {
-    return app_window_->extension();
-  }
+  content::WebContents* WebContents() const;
 
   // Returns the WindowStyleMask based on the type of window frame.
   // Specifically, this includes NSResizableWindowMask if the window is
diff --git a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm
index 1b4af00..ecd390e 100644
--- a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm
@@ -18,7 +18,6 @@
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/common/extension.h"
 #include "third_party/skia/include/core/SkRegion.h"
 #include "ui/gfx/skia_util.h"
@@ -307,7 +306,7 @@
       shows_resize_controls_(true),
       shows_fullscreen_controls_(true),
       attention_request_id_(0) {
-  Observe(web_contents());
+  Observe(WebContents());
 
   base::scoped_nsobject<NSWindow> window;
   Class window_class;
@@ -330,7 +329,12 @@
                 styleMask:GetWindowStyleMask()
                   backing:NSBackingStoreBuffered
                     defer:NO]);
-  [window setTitle:base::SysUTF8ToNSString(extension()->name())];
+
+  std::string name;
+  const extensions::Extension* extension = app_window_->GetExtension();
+  if (extension)
+    name = extension->name();
+  [window setTitle:base::SysUTF8ToNSString(name)];
   [[window contentView] cr_setWantsLayer:YES];
 
   if (base::mac::IsOSSnowLeopard() &&
@@ -344,7 +348,7 @@
   window_controller_.reset(
       [[NativeAppWindowController alloc] initWithWindow:window.release()]);
 
-  NSView* view = web_contents()->GetView()->GetNativeView();
+  NSView* view = WebContents()->GetNativeView();
   [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
 
   InstallView();
@@ -382,7 +386,7 @@
 }
 
 void NativeAppWindowCocoa::InstallView() {
-  NSView* view = web_contents()->GetView()->GetNativeView();
+  NSView* view = WebContents()->GetNativeView();
   if (has_frame_) {
     [view setFrame:[[window() contentView] bounds]];
     [[window() contentView] addSubview:view];
@@ -415,7 +419,7 @@
 }
 
 void NativeAppWindowCocoa::UninstallView() {
-  NSView* view = web_contents()->GetView()->GetNativeView();
+  NSView* view = WebContents()->GetNativeView();
   [view removeFromSuperview];
 }
 
@@ -661,7 +665,7 @@
   // All ControlRegionViews should be added as children of the WebContentsView,
   // because WebContentsView will be removed and re-added when entering and
   // leaving fullscreen mode.
-  NSView* webView = web_contents()->GetView()->GetNativeView();
+  NSView* webView = WebContents()->GetNativeView();
   NSInteger webViewWidth = NSWidth([webView bounds]);
   NSInteger webViewHeight = NSHeight([webView bounds]);
 
@@ -711,7 +715,7 @@
 
 void NativeAppWindowCocoa::RenderViewCreated(content::RenderViewHost* rvh) {
   if (IsActive())
-    web_contents()->GetView()->RestoreFocus();
+    WebContents()->RestoreFocus();
 }
 
 bool NativeAppWindowCocoa::IsFrameless() const {
@@ -785,12 +789,12 @@
 
 void NativeAppWindowCocoa::WindowDidBecomeKey() {
   content::RenderWidgetHostView* rwhv =
-      web_contents()->GetRenderWidgetHostView();
+      WebContents()->GetRenderWidgetHostView();
   if (rwhv)
     rwhv->SetActive(true);
   app_window_->OnNativeWindowActivated();
 
-  web_contents()->GetView()->RestoreFocus();
+  WebContents()->RestoreFocus();
 }
 
 void NativeAppWindowCocoa::WindowDidResignKey() {
@@ -801,10 +805,10 @@
   if ([NSApp isActive] && ([NSApp keyWindow] == window()))
     return;
 
-  web_contents()->GetView()->StoreFocus();
+  WebContents()->StoreFocus();
 
   content::RenderWidgetHostView* rwhv =
-      web_contents()->GetRenderWidgetHostView();
+      WebContents()->GetRenderWidgetHostView();
   if (rwhv)
     rwhv->SetActive(false);
 }
@@ -940,6 +944,10 @@
   return static_cast<ShellNSWindow*>(window);
 }
 
+content::WebContents* NativeAppWindowCocoa::WebContents() const {
+  return app_window_->web_contents();
+}
+
 void NativeAppWindowCocoa::UpdateRestoredBounds() {
   if (IsRestored(*this))
     restored_bounds_ = [window() frame];
diff --git a/chrome/browser/ui/cocoa/apps/quit_with_apps_controller_mac.cc b/chrome/browser/ui/cocoa/apps/quit_with_apps_controller_mac.cc
index 9bdb3cf..6c34598 100644
--- a/chrome/browser/ui/cocoa/apps/quit_with_apps_controller_mac.cc
+++ b/chrome/browser/ui/cocoa/apps/quit_with_apps_controller_mac.cc
@@ -84,8 +84,6 @@
 }
 
 void QuitWithAppsController::ButtonClick(int button_index) {
-  typedef apps::AppWindowRegistry::AppWindowList AppWindowList;
-
   g_browser_process->notification_ui_manager()->CancelById(id());
   if (button_index == kQuitAllAppsButtonIndex) {
     apps::AppWindowRegistry::CloseAllAppWindows();
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa_browsertest.mm b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa_browsertest.mm
index 459c488..546dd98 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa_browsertest.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa_browsertest.mm
@@ -15,7 +15,6 @@
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/common/form_data.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_dialog_window_controller.mm b/chrome/browser/ui/cocoa/autofill/autofill_dialog_window_controller.mm
index b5e42db..05215d8 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_dialog_window_controller.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_dialog_window_controller.mm
@@ -20,7 +20,6 @@
 #import "chrome/browser/ui/cocoa/autofill/autofill_textfield.h"
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_window.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #import "ui/base/cocoa/flipped_view.h"
 #include "ui/base/cocoa/window_size_constants.h"
@@ -213,8 +212,7 @@
 
 - (CGFloat)maxHeight {
   NSRect dialogFrameRect = [[self window] frame];
-  NSRect browserFrameRect =
-      [webContents_->GetView()->GetTopLevelNativeWindow() frame];
+  NSRect browserFrameRect = [webContents_->GetTopLevelNativeWindow() frame];
   dialogFrameRect.size.height =
       NSMaxY(dialogFrameRect) - NSMinY(browserFrameRect);
   dialogFrameRect = [[self window] contentRectForFrameRect:dialogFrameRect];
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.mm
index 92fd47e..7293c4b 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.mm
@@ -17,7 +17,6 @@
 #include "components/autofill/content/browser/wallet/wallet_service_url.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 namespace {
 
@@ -77,7 +76,7 @@
   webContents_.reset(
       content::WebContents::Create(
           content::WebContents::CreateParams(dialog_->delegate()->profile())));
-  NSView* webContentView = webContents_->GetView()->GetNativeView();
+  NSView* webContentView = webContents_->GetNativeView();
   [self setView:webContentView];
 }
 
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_sign_in_container_unittest.mm b/chrome/browser/ui/cocoa/autofill/autofill_sign_in_container_unittest.mm
index 29780df..48ea1bd 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_sign_in_container_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_sign_in_container_unittest.mm
@@ -12,7 +12,6 @@
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "content/public/browser/web_contents_view.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 #import "ui/gfx/test/ui_cocoa_test_helper.h"
@@ -69,7 +68,7 @@
   // isKindOfClass would be the better choice, but
   // WebContentsViewCocoaClass is defined in content, and not public.
   bool hasWebView =[[container_ view] isEqual:
-      [container_ webContents]->GetView()->GetNativeView()];
+      [container_ webContents]->GetNativeView()];
 
   EXPECT_TRUE(hasWebView);
 }
diff --git a/chrome/browser/ui/cocoa/autofill/generated_credit_card_bubble_cocoa.mm b/chrome/browser/ui/cocoa/autofill/generated_credit_card_bubble_cocoa.mm
index 4ce5514..3176b3b 100644
--- a/chrome/browser/ui/cocoa/autofill/generated_credit_card_bubble_cocoa.mm
+++ b/chrome/browser/ui/cocoa/autofill/generated_credit_card_bubble_cocoa.mm
@@ -15,7 +15,6 @@
 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
 #include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
-#include "content/public/browser/web_contents_view.h"
 #include "skia/ext/skia_utils_mac.h"
 #include "ui/base/cocoa/window_size_constants.h"
 #include "ui/native_theme/native_theme.h"
@@ -195,7 +194,7 @@
 void GeneratedCreditCardBubbleCocoa::Show() {
   DCHECK(controller_.get());
   NSView* browser_view =
-      controller_->web_contents()->GetView()->GetNativeView();
+      controller_->web_contents()->GetNativeView();
   NSWindow* parent_window = [browser_view window];
   LocationBarViewMac* location_bar =
       [[parent_window windowController] locationBarBridge];
diff --git a/chrome/browser/ui/cocoa/autofill/new_credit_card_bubble_cocoa.mm b/chrome/browser/ui/cocoa/autofill/new_credit_card_bubble_cocoa.mm
index 2ac24ae..06bcd7a 100644
--- a/chrome/browser/ui/cocoa/autofill/new_credit_card_bubble_cocoa.mm
+++ b/chrome/browser/ui/cocoa/autofill/new_credit_card_bubble_cocoa.mm
@@ -16,7 +16,6 @@
 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "skia/ext/skia_utils_mac.h"
 #import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #include "ui/base/cocoa/window_size_constants.h"
@@ -199,8 +198,7 @@
 }
 
 void NewCreditCardBubbleCocoa::Show() {
-  NSView* browser_view =
-      controller_->web_contents()->GetView()->GetNativeView();
+  NSView* browser_view = controller_->web_contents()->GetNativeView();
   NSWindow* parent_window = [browser_view window];
   BrowserWindowController* bwc = [BrowserWindowController
       browserWindowControllerForWindow:parent_window];
diff --git a/chrome/browser/ui/cocoa/base_bubble_controller.h b/chrome/browser/ui/cocoa/base_bubble_controller.h
index 187a0cd..38bc2c4 100644
--- a/chrome/browser/ui/cocoa/base_bubble_controller.h
+++ b/chrome/browser/ui/cocoa/base_bubble_controller.h
@@ -24,6 +24,11 @@
  @private
   NSWindow* parentWindow_;  // weak
   NSPoint anchor_;
+  // Offset of the anchor point relative to the parent window's upper-left-hand
+  // corner. Used to ensure that if the parent window is resized with the bubble
+  // remaining visible, the bubble continues to be anchored correctly.
+  NSPoint anchorOffset_;
+
   IBOutlet InfoBubbleView* bubble_;  // to set arrow position
   // Bridge for tab change notifications.
   scoped_ptr<TabStripModelObserverBridge> tabStripObserverBridge_;
diff --git a/chrome/browser/ui/cocoa/base_bubble_controller.mm b/chrome/browser/ui/cocoa/base_bubble_controller.mm
index f35bc66..6dc5736 100644
--- a/chrome/browser/ui/cocoa/base_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/base_bubble_controller.mm
@@ -16,11 +16,15 @@
 #include "ui/base/l10n/l10n_util.h"
 
 @interface BaseBubbleController (Private)
+- (void)registerForNotifications;
 - (void)updateOriginFromAnchor;
 - (void)activateTabWithContents:(content::WebContents*)newContents
                previousContents:(content::WebContents*)oldContents
                         atIndex:(NSInteger)index
                          reason:(int)reason;
+- (void)recordAnchorOffset;
+- (void)parentWindowDidResize:(NSNotification*)notification;
+- (void)parentWindowWillClose:(NSNotification*)notification;
 - (void)closeCleanup;
 @end
 
@@ -42,13 +46,7 @@
     anchor_ = anchoredAt;
     shouldOpenAsKeyWindow_ = YES;
     shouldCloseOnResignKey_ = YES;
-
-    // Watch to see if the parent window closes, and if so, close this one.
-    NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
-    [center addObserver:self
-               selector:@selector(parentWindowWillClose:)
-                   name:NSWindowWillCloseNotification
-                 object:parentWindow_];
+    [self registerForNotifications];
   }
   return self;
 }
@@ -85,13 +83,7 @@
     [theWindow setContentView:contentView.get()];
     bubble_ = contentView.get();
 
-    // Watch to see if the parent window closes, and if so, close this one.
-    NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
-    [center addObserver:self
-               selector:@selector(parentWindowWillClose:)
-                   name:NSWindowWillCloseNotification
-                 object:parentWindow_];
-
+    [self registerForNotifications];
     [self awakeFromNib];
   }
   return self;
@@ -120,11 +112,35 @@
   [super dealloc];
 }
 
+- (void)registerForNotifications {
+  NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
+  // Watch to see if the parent window closes, and if so, close this one.
+  [center addObserver:self
+             selector:@selector(parentWindowWillClose:)
+                 name:NSWindowWillCloseNotification
+               object:parentWindow_];
+  // Watch for parent window's resizing, to ensure this one is always
+  // anchored correctly.
+  [center addObserver:self
+             selector:@selector(parentWindowDidResize:)
+                 name:NSWindowDidResizeNotification
+               object:parentWindow_];
+}
+
 - (void)setAnchorPoint:(NSPoint)anchor {
   anchor_ = anchor;
   [self updateOriginFromAnchor];
 }
 
+- (void)recordAnchorOffset {
+  // The offset of the anchor from the parent's upper-left-hand corner is kept
+  // to ensure the bubble stays anchored correctly if the parent is resized.
+  anchorOffset_ = NSMakePoint(NSMinX([parentWindow_ frame]),
+                              NSMaxY([parentWindow_ frame]));
+  anchorOffset_.x -= anchor_.x;
+  anchorOffset_.y -= anchor_.y;
+}
+
 - (NSBox*)separatorWithFrame:(NSRect)frame {
   frame.size.height = 1.0;
   base::scoped_nsobject<NSBox> spacer([[NSBox alloc] initWithFrame:frame]);
@@ -134,6 +150,15 @@
   return [spacer.release() autorelease];
 }
 
+- (void)parentWindowDidResize:(NSNotification*)notification {
+  DCHECK_EQ(parentWindow_, [notification object]);
+  NSPoint newOrigin = NSMakePoint(NSMinX([parentWindow_ frame]),
+                                  NSMaxY([parentWindow_ frame]));
+  newOrigin.x -= anchorOffset_.x;
+  newOrigin.y -= anchorOffset_.y;
+  [self setAnchorPoint:newOrigin];
+}
+
 - (void)parentWindowWillClose:(NSNotification*)notification {
   parentWindow_ = nil;
   [self close];
@@ -179,6 +204,7 @@
   else
     [window orderFront:nil];
   [self registerKeyStateEventTap];
+  [self recordAnchorOffset];
 }
 
 - (void)close {
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h
index 42f0061..2df470e 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h
@@ -41,8 +41,11 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE;
   virtual void BookmarkNodeFaviconChanged(BookmarkModel* model,
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm
index 5d88de1..0bf2e91 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.mm
@@ -66,15 +66,19 @@
     [controller_ nodeAdded:model parent:parent index:index];
 }
 
-void BookmarkBarBridge::BookmarkNodeRemoved(BookmarkModel* model,
-                                            const BookmarkNode* parent,
-                                            int old_index,
-                                            const BookmarkNode* node) {
+void BookmarkBarBridge::BookmarkNodeRemoved(
+    BookmarkModel* model,
+    const BookmarkNode* parent,
+    int old_index,
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {
   if (!batch_mode_)
     [controller_ nodeRemoved:model parent:parent index:old_index];
 }
 
-void BookmarkBarBridge::BookmarkAllNodesRemoved(BookmarkModel* model) {
+void BookmarkBarBridge::BookmarkAllNodesRemoved(
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
   [controller_ loaded:model];
 }
 
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm
index d284505..5695167 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm
@@ -122,7 +122,7 @@
   bridge->BookmarkNodeChanged(NULL, NULL);
   bridge->BookmarkNodeFaviconChanged(NULL, NULL);
   bridge->BookmarkNodeChildrenReordered(NULL, NULL);
-  bridge->BookmarkNodeRemoved(NULL, NULL, 0, NULL);
+  bridge->BookmarkNodeRemoved(NULL, NULL, 0, NULL, std::set<GURL>());
 
   // 8 calls above plus an initial Loaded() in init routine makes 9
   EXPECT_TRUE([controller.get()->callbacks_ count] == 9);
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm
index eeba838..64c9972 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm
@@ -51,7 +51,6 @@
 #include "components/bookmarks/core/browser/bookmark_utils.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_set.h"
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
index ec1faa1..e76da16 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
@@ -12,7 +12,6 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/extensions/test_extension_system.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
@@ -28,6 +27,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
index 5ef90f3..4a9d8b2 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
@@ -6,7 +6,6 @@
 #include "base/mac/scoped_nsobject.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h"
@@ -17,6 +16,7 @@
 #import "chrome/browser/ui/cocoa/view_resizer_pong.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm
index 9b36c19..3622718 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm
@@ -6,7 +6,6 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view.h"
@@ -17,6 +16,7 @@
 #import "chrome/browser/ui/cocoa/url_drop_target.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 #import "third_party/mozilla/NSPasteboard+Utils.h"
@@ -158,7 +158,8 @@
   TestingProfile* other_profile =
       testing_profile_manager()->CreateTestingProfile("other");
   other_profile->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(other_profile);
+  test::WaitForBookmarkModelToLoad(
+      BookmarkModelFactory::GetForProfile(other_profile));
 
   mock_controller_.reset(GetMockController(
       YES, BookmarkModelFactory::GetForProfile(other_profile)));
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm
index eb2b090..c5d989a 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm
@@ -6,7 +6,6 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h"
 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view.h"
@@ -18,6 +17,7 @@
 #import "chrome/browser/ui/cocoa/url_drop_target.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 #import "third_party/mozilla/NSPasteboard+Utils.h"
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm
index d6e6a48..fd79bef 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_editor_base_controller.mm
@@ -140,16 +140,20 @@
       [controller_ modelChangedPreserveSelection:YES];
   }
 
-  virtual void BookmarkNodeRemoved(BookmarkModel* model,
-                                   const BookmarkNode* parent,
-                                   int old_index,
-                                   const BookmarkNode* node) OVERRIDE {
+  virtual void BookmarkNodeRemoved(
+      BookmarkModel* model,
+      const BookmarkNode* parent,
+      int old_index,
+      const BookmarkNode* node,
+      const std::set<GURL>& removed_urls) OVERRIDE {
     [controller_ nodeRemoved:node fromParent:parent];
     if (node->is_folder())
       [controller_ modelChangedPreserveSelection:NO];
   }
 
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE {
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE {
     [controller_ modelChangedPreserveSelection:NO];
   }
 
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h
index ee83798..972bfaf 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h
@@ -54,8 +54,11 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE;
   virtual void BookmarkNodeFaviconChanged(BookmarkModel* model,
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm
index 9ec5907..f0d3115 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm
@@ -128,14 +128,18 @@
   InvalidateMenu();
 }
 
-void BookmarkMenuBridge::BookmarkNodeRemoved(BookmarkModel* model,
-                                             const BookmarkNode* parent,
-                                             int old_index,
-                                             const BookmarkNode* node) {
+void BookmarkMenuBridge::BookmarkNodeRemoved(
+    BookmarkModel* model,
+    const BookmarkNode* parent,
+    int old_index,
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {
   InvalidateMenu();
 }
 
-void BookmarkMenuBridge::BookmarkAllNodesRemoved(BookmarkModel* model) {
+void BookmarkMenuBridge::BookmarkAllNodesRemoved(
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
   InvalidateMenu();
 }
 
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h
index a60e9f8..a3818ee 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h
@@ -55,8 +55,11 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE;
 
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.mm
index e748818..679e5c1 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.mm
@@ -47,13 +47,15 @@
     BookmarkModel* model,
     const BookmarkNode* parent,
     int old_index,
-    const BookmarkNode* node) {
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {
   // See comment in BookmarkNodeMoved.
   Notify(YES);
 }
 
 void BookmarkModelObserverForCocoa::BookmarkAllNodesRemoved(
-    BookmarkModel* model) {
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
   Notify(YES);
 }
 
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index 106d1ba..e503c92 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -54,7 +54,6 @@
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util_mac.h"
@@ -74,7 +73,7 @@
 NSPoint GetPointForBubble(content::WebContents* web_contents,
                           int x_offset,
                           int y_offset) {
-  NSView* view = web_contents->GetView()->GetNativeView();
+  NSView* view = web_contents->GetNativeView();
   NSRect bounds = [view bounds];
   NSPoint point;
   point.x = NSMinX(bounds) + x_offset;
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm
index 5fd720a..efb847c 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -84,7 +84,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/locale_settings.h"
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm b/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm
index 403c00e..b8620ea 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm
@@ -34,7 +34,6 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #import "testing/gtest_mac.h"
 
 namespace {
@@ -356,17 +355,17 @@
 // visible.
 IN_PROC_BROWSER_TEST_F(BrowserWindowControllerTest,
                        AllowOverlappingViewsHistoryOverlay) {
-  content::WebContentsView* web_contents_view =
-      browser()->tab_strip_model()->GetActiveWebContents()->GetView();
-  EXPECT_TRUE(web_contents_view->GetAllowOverlappingViews());
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  EXPECT_TRUE(web_contents->GetAllowOverlappingViews());
 
   base::scoped_nsobject<HistoryOverlayController> overlay(
       [[HistoryOverlayController alloc] initForMode:kHistoryOverlayModeBack]);
-  [overlay showPanelForView:web_contents_view->GetNativeView()];
-  EXPECT_TRUE(web_contents_view->GetAllowOverlappingViews());
+  [overlay showPanelForView:web_contents->GetNativeView()];
+  EXPECT_TRUE(web_contents->GetAllowOverlappingViews());
 
   overlay.reset();
-  EXPECT_TRUE(web_contents_view->GetAllowOverlappingViews());
+  EXPECT_TRUE(web_contents->GetAllowOverlappingViews());
 }
 
 // Tests that status bubble's base frame does move when devTools are docked.
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
index 65c4c4a..3ca8021 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -41,7 +41,6 @@
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #import "ui/base/cocoa/focus_tracker.h"
 #include "ui/base/ui_base_types.h"
 
@@ -999,12 +998,12 @@
   // transitioning between composited and non-composited mode.
   // http://crbug.com/279472
   allowOverlappingViews = YES;
-  contents->GetView()->SetAllowOverlappingViews(allowOverlappingViews);
+  contents->SetAllowOverlappingViews(allowOverlappingViews);
 
   DevToolsWindow* devToolsWindow =
       DevToolsWindow::GetDockedInstanceForInspectedTab(contents);
   if (devToolsWindow) {
-    devToolsWindow->web_contents()->GetView()->
+    devToolsWindow->web_contents()->
         SetAllowOverlappingViews(allowOverlappingViews);
   }
 }
diff --git a/chrome/browser/ui/cocoa/certificate_viewer_mac_browsertest.mm b/chrome/browser/ui/cocoa/certificate_viewer_mac_browsertest.mm
index ca4d5b1..4f83ff5 100644
--- a/chrome/browser/ui/cocoa/certificate_viewer_mac_browsertest.mm
+++ b/chrome/browser/ui/cocoa/certificate_viewer_mac_browsertest.mm
@@ -11,7 +11,6 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/test_utils.h"
 #include "net/base/test_data_directory.h"
 #include "net/cert/x509_certificate.h"
@@ -34,7 +33,7 @@
   ASSERT_TRUE(cert.get());
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  gfx::NativeWindow window = web_contents->GetView()->GetTopLevelNativeWindow();
+  gfx::NativeWindow window = web_contents->GetTopLevelNativeWindow();
   WebContentsModalDialogManager* web_contents_modal_dialog_manager =
       WebContentsModalDialogManager::FromWebContents(web_contents);
   EXPECT_FALSE(web_contents_modal_dialog_manager->IsDialogActive());
diff --git a/chrome/browser/ui/cocoa/cocoa_profile_test.mm b/chrome/browser/ui/cocoa/cocoa_profile_test.mm
index b8eacf2..bc634ca 100644
--- a/chrome/browser/ui/cocoa/cocoa_profile_test.mm
+++ b/chrome/browser/ui/cocoa/cocoa_profile_test.mm
@@ -6,7 +6,7 @@
 
 #include "base/run_loop.h"
 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/ui/browser.h"
@@ -16,6 +16,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 
 CocoaProfileTest::CocoaProfileTest()
@@ -49,7 +50,8 @@
   ASSERT_TRUE(profile_);
 
   profile_->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(profile_);
+  test::WaitForBookmarkModelToLoad(
+      BookmarkModelFactory::GetForProfile(profile_));
 
   // TODO(shess): These are needed in case someone creates a browser
   // window off of browser_.  pkasting indicates that other
diff --git a/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm b/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
index 36529a9..9ec3864 100644
--- a/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
+++ b/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
@@ -11,7 +11,6 @@
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_window.h"
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/gfx/size.h"
 #include "ui/web_dialogs/web_dialog_delegate.h"
 #include "ui/web_dialogs/web_dialog_ui.h"
@@ -115,9 +114,8 @@
 
   window_.reset(
       [[ConstrainedWindowCustomWindow alloc] initWithContentRect:frame]);
-  [GetWebContents()->GetView()->GetNativeView() setFrame:frame];
-  [[window_ contentView]
-      addSubview:GetWebContents()->GetView()->GetNativeView()];
+  [GetWebContents()->GetNativeView() setFrame:frame];
+  [[window_ contentView] addSubview:GetWebContents()->GetNativeView()];
 
   base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
       [[CustomConstrainedWindowSheet alloc] initWithCustomWindow:window_]);
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm
index c3a2b4f..92a7b68 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm
@@ -13,7 +13,6 @@
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 using web_modal::WebContentsModalDialogManager;
 using web_modal::NativeWebContentsModalDialog;
@@ -90,5 +89,5 @@
   if (browser)
     return browser->window()->GetNativeWindow();
 
-  return web_contents_->GetView()->GetTopLevelNativeWindow();
+  return web_contents_->GetTopLevelNativeWindow();
 }
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm
index 76593a3..021c33e 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm
@@ -13,7 +13,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "url/gurl.h"
 
@@ -100,7 +99,7 @@
   content::WebContents* tab2 =
       browser()->tab_strip_model()->GetWebContentsAt(2);
   ASSERT_TRUE(tab2);
-  EXPECT_FALSE([tab2->GetView()->GetNativeView() superview]);
+  EXPECT_FALSE([tab2->GetNativeView() superview]);
 
   // Show dialog and verify that it's not visible yet.
   NiceMock<ConstrainedWindowDelegateMock> delegate;
@@ -109,7 +108,7 @@
 
   // Activate the tab and verify that the constrained window is shown.
   browser()->tab_strip_model()->ActivateTabAt(2, true);
-  EXPECT_TRUE([tab2->GetView()->GetNativeView() superview]);
+  EXPECT_TRUE([tab2->GetNativeView() superview]);
   EXPECT_TRUE([sheet_window_ isVisible]);
   EXPECT_EQ(1.0, [sheet_window_ alphaValue]);
 
diff --git a/chrome/browser/ui/cocoa/dev_tools_controller.mm b/chrome/browser/ui/cocoa/dev_tools_controller.mm
index 1d291de..5d65f1e 100644
--- a/chrome/browser/ui/cocoa/dev_tools_controller.mm
+++ b/chrome/browser/ui/cocoa/dev_tools_controller.mm
@@ -15,7 +15,6 @@
 #import "chrome/browser/ui/cocoa/view_id_util.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/base/cocoa/base_view.h"
 #include "ui/base/cocoa/focus_tracker.h"
 #include "ui/gfx/mac/scoped_ns_disable_screen_updates.h"
@@ -132,8 +131,8 @@
   if (devToolsWindow_) {
     const DevToolsContentsResizingStrategy& strategy =
         devToolsWindow_->GetContentsResizingStrategy();
-    devToolsWindow_->web_contents()->GetView()->SetOverlayView(
-        contents->GetView(),
+    devToolsWindow_->web_contents()->SetOverlayView(
+        contents,
         gfx::Point(strategy.insets().left(), strategy.insets().top()));
     [devToolsContainerView_ setContentsResizingStrategy:strategy];
   } else {
@@ -154,15 +153,14 @@
   // |devToolsView| is a WebContentsViewCocoa object, whose ViewID was
   // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to
   // VIEW_ID_DEV_TOOLS_DOCKED here.
-  NSView* devToolsView =
-      devToolsWindow_->web_contents()->GetView()->GetNativeView();
+  NSView* devToolsView = devToolsWindow_->web_contents()->GetNativeView();
   view_id_util::SetID(devToolsView, VIEW_ID_DEV_TOOLS_DOCKED);
 
   [devToolsContainerView_ showDevTools:devToolsView];
 }
 
 - (void)hideDevToolsView {
-  devToolsWindow_->web_contents()->GetView()->RemoveOverlayView();
+  devToolsWindow_->web_contents()->RemoveOverlayView();
   [devToolsContainerView_ hideDevTools];
   [focusTracker_ restoreFocusInWindow:[devToolsContainerView_ window]];
   focusTracker_.reset();
diff --git a/chrome/browser/ui/cocoa/dev_tools_controller_browsertest.mm b/chrome/browser/ui/cocoa/dev_tools_controller_browsertest.mm
index ad93cce..c850488 100644
--- a/chrome/browser/ui/cocoa/dev_tools_controller_browsertest.mm
+++ b/chrome/browser/ui/cocoa/dev_tools_controller_browsertest.mm
@@ -14,7 +14,6 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 class DevToolsControllerTest : public InProcessBrowserTest {
  public:
@@ -35,17 +34,15 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   DevToolsWindow* dev_tools =
       DevToolsWindow::GetDockedInstanceForInspectedTab(web_contents);
-  content::WebContentsView* dev_tools_view =
-      dev_tools->web_contents()->GetView();
 
   // Without the find bar.
-  EXPECT_TRUE(dev_tools_view->GetAllowOverlappingViews());
+  EXPECT_TRUE(dev_tools->web_contents()->GetAllowOverlappingViews());
 
   // With the find bar.
   browser()->GetFindBarController()->find_bar()->Show(false);
-  EXPECT_TRUE(dev_tools_view->GetAllowOverlappingViews());
+  EXPECT_TRUE(dev_tools->web_contents()->GetAllowOverlappingViews());
 
   // Without the find bar.
   browser()->GetFindBarController()->find_bar()->Hide(false);
-  EXPECT_TRUE(dev_tools_view->GetAllowOverlappingViews());
+  EXPECT_TRUE(dev_tools->web_contents()->GetAllowOverlappingViews());
 }
diff --git a/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm b/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm
index 48f937d..2e5270c 100644
--- a/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm
+++ b/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm
@@ -14,7 +14,6 @@
 #include "base/logging.h"
 #import "chrome/browser/ui/cocoa/animatable_image.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/theme_resources.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h"
 #include "third_party/skia/include/utils/mac/SkCGUtils.h"
@@ -49,8 +48,7 @@
     // against the left edge, and three times the download image's height from
     // the bottom of the tab, assuming there is enough room. If there isn't
     // enough, don't show the animation and let the shelf speak for itself.
-    gfx::Rect bounds;
-    webContents->GetView()->GetContainerBounds(&bounds);
+    gfx::Rect bounds = webContents->GetContainerBounds();
     imageWidth_ = [image size].width;
     CGFloat imageHeight = [image size].height;
 
@@ -60,7 +58,7 @@
       return nil;
     }
 
-    NSView* tabContentsView = webContents->GetView()->GetNativeView();
+    NSView* tabContentsView = webContents->GetNativeView();
     NSWindow* parentWindow = [tabContentsView window];
     if (!parentWindow) {
       // The tab is no longer frontmost.
diff --git a/chrome/browser/ui/cocoa/extensions/extension_view_mac.mm b/chrome/browser/ui/cocoa/extensions/extension_view_mac.mm
index b776789..f0a61c2 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_view_mac.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_view_mac.mm
@@ -9,7 +9,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_host.h"
 #include "extensions/common/view_type.h"
 
@@ -36,7 +35,7 @@
 }
 
 gfx::NativeView ExtensionViewMac::native_view() {
-  return extension_host_->host_contents()->GetView()->GetNativeView();
+  return extension_host_->host_contents()->GetNativeView();
 }
 
 content::RenderViewHost* ExtensionViewMac::render_view_host() const {
diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm
index fd7123b..b328234 100644
--- a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm
+++ b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm
@@ -24,7 +24,6 @@
 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h"
 #import "ui/base/cocoa/find_pasteboard.h"
 #import "ui/base/cocoa/focus_tracker.h"
@@ -328,7 +327,7 @@
   if (!(focusTracker_.get() &&
         [focusTracker_ restoreFocusInWindow:[findBarView_ window]])) {
     // Fall back to giving focus to the tab contents.
-    findBarBridge_->GetFindBarController()->web_contents()->GetView()->Focus();
+    findBarBridge_->GetFindBarController()->web_contents()->Focus();
   }
   focusTracker_.reset(nil);
 }
@@ -541,7 +540,7 @@
     return frame.origin.x;
 
   // Get the size of the container.
-  gfx::Rect containerRect(contents->GetView()->GetContainerSize());
+  gfx::Rect containerRect(contents->GetContainerBounds().size());
 
   // Position the FindBar on the top right corner.
   viewRect.set_x(
diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm
index b9269ad..0c7838d 100644
--- a/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm
+++ b/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm
@@ -144,10 +144,6 @@
   return NSDragOperationNone;
 }
 
-- (ViewID)viewID {
-  return VIEW_ID_FIND_IN_PAGE;
-}
-
 // Specifies that mouse events over this view should be ignored by the
 // render host.
 - (BOOL)nonWebContentView {
diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.mm b/chrome/browser/ui/cocoa/hung_renderer_controller.mm
index 524e5b4..5035873 100644
--- a/chrome/browser/ui/cocoa/hung_renderer_controller.mm
+++ b/chrome/browser/ui/cocoa/hung_renderer_controller.mm
@@ -51,7 +51,7 @@
   virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE {
     [controller_ renderProcessGone];
   }
-  virtual void WebContentsDestroyed(WebContents* tab) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     [controller_ renderProcessGone];
   }
 
diff --git a/chrome/browser/ui/cocoa/infobars/extension_infobar_controller.mm b/chrome/browser/ui/cocoa/infobars/extension_infobar_controller.mm
index 496478d..2c46ba3 100644
--- a/chrome/browser/ui/cocoa/infobars/extension_infobar_controller.mm
+++ b/chrome/browser/ui/cocoa/infobars/extension_infobar_controller.mm
@@ -17,7 +17,6 @@
 #include "chrome/browser/ui/cocoa/infobars/infobar_cocoa.h"
 #import "chrome/browser/ui/cocoa/menu_button.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_icon_set.h"
diff --git a/chrome/browser/ui/cocoa/location_bar/origin_chip_decoration.mm b/chrome/browser/ui/cocoa/location_bar/origin_chip_decoration.mm
index 225b2df..43ca9ad 100644
--- a/chrome/browser/ui/cocoa/location_bar/origin_chip_decoration.mm
+++ b/chrome/browser/ui/cocoa/location_bar/origin_chip_decoration.mm
@@ -186,7 +186,7 @@
 }
 
 NSString* OriginChipDecoration::GetToolTip() {
-  return label_.get();
+  return base::SysUTF16ToNSString(info_.Tooltip());
 }
 
 bool OriginChipDecoration::OnMousePressed(NSRect frame) {
diff --git a/chrome/browser/ui/cocoa/location_bar/star_decoration.mm b/chrome/browser/ui/cocoa/location_bar/star_decoration.mm
index eb090a5..5f68e1d 100644
--- a/chrome/browser/ui/cocoa/location_bar/star_decoration.mm
+++ b/chrome/browser/ui/cocoa/location_bar/star_decoration.mm
@@ -49,7 +49,7 @@
 }
 
 bool StarDecoration::OnMousePressed(NSRect frame) {
-  command_updater_->ExecuteCommand(IDC_BOOKMARK_PAGE_FROM_STAR);
+  command_updater_->ExecuteCommand(IDC_BOOKMARK_PAGE);
   return true;
 }
 
diff --git a/chrome/browser/ui/cocoa/panels/panel_window_controller_cocoa.mm b/chrome/browser/ui/cocoa/panels/panel_window_controller_cocoa.mm
index ef8f353..8337fcf 100644
--- a/chrome/browser/ui/cocoa/panels/panel_window_controller_cocoa.mm
+++ b/chrome/browser/ui/cocoa/panels/panel_window_controller_cocoa.mm
@@ -33,7 +33,6 @@
 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/ui_resources.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/image/image.h"
@@ -231,7 +230,7 @@
   NSRect contentFrame = [self contentRectForFrameRect:[[self window] frame]];
   contentFrame.origin = NSZeroPoint;
 
-  NSView* contentView = webContents->GetView()->GetNativeView();
+  NSView* contentView = webContents->GetNativeView();
   if (!NSEqualRects([contentView frame], contentFrame))
     [contentView setFrame:contentFrame];
 }
@@ -331,7 +330,7 @@
 }
 
 - (void)webContentsInserted:(WebContents*)contents {
-  NSView* view = contents->GetView()->GetNativeView();
+  NSView* view = contents->GetNativeView();
   [[[self window] contentView] addSubview:view];
   [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
 
@@ -339,7 +338,7 @@
 }
 
 - (void)webContentsDetached:(WebContents*)contents {
-  [contents->GetView()->GetNativeView() removeFromSuperview];
+  [contents->GetNativeView() removeFromSuperview];
 }
 
 - (PanelTitlebarViewCocoa*)titlebarView {
@@ -691,7 +690,7 @@
   content::WebContents* webContents = panel->GetWebContents();
   if (!webContents)
     return;
-  NSView* contentView = webContents->GetView()->GetNativeView();
+  NSView* contentView = webContents->GetNativeView();
   if (NSHeight([self contentRectForFrameRect:[[self window] frame]]) <= 0) {
     // No need to retain the view before it is removed from its superview
     // because WebContentsView keeps a reference to this view.
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm b/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm
index 2176f21..23b14c1 100644
--- a/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm
@@ -7,7 +7,7 @@
 #include "base/mac/scoped_nsobject.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/managed_mode/managed_user_service.h"
 #include "chrome/browser/managed_mode/managed_user_service_factory.h"
 #include "chrome/browser/prefs/pref_service_syncable.h"
@@ -22,6 +22,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 
 class AvatarIconControllerTest : public CocoaProfileTest {
  public:
@@ -108,7 +109,8 @@
   AutocompleteClassifierFactory::GetInstance()->SetTestingFactoryAndUse(
       profile, &AutocompleteClassifierFactory::BuildInstanceFor);
   profile->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(profile);
+  test::WaitForBookmarkModelToLoad(
+      BookmarkModelFactory::GetForProfile(profile));
 
   Browser* browser =
       new Browser(Browser::CreateParams(profile, chrome::GetActiveDesktop()));
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h
index 2b7b9da..453573a 100644
--- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h
+++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h
@@ -36,10 +36,19 @@
     // Shows a web view for adding secondary accounts.
     BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT,
     // Shows a view for confirming account removal.
-    BUBBLE_VIEW_MODE_ACCOUNT_REMOVAL
+    BUBBLE_VIEW_MODE_ACCOUNT_REMOVAL,
+    // Shows a view for ending new profile management preview.
+    BUBBLE_VIEW_MODE_END_PREVIEW
   };
 
  @private
+  enum TutorialMode {
+    TUTORIAL_MODE_NONE,             // No tutorial card shown.
+    TUTORIAL_MODE_ENABLE_PREVIEW,   // The enable-mirror-preview tutorial shown.
+    TUTORIAL_MODE_WELCOME,          // The welcome-to-mirror tutorial shown.
+    TUTORIAL_MODE_SEND_FEEDBACK     // The send-feedback tutorial shown.
+  };
+
   // The menu that contains the data from the backend.
   scoped_ptr<AvatarMenu> avatarMenu_;
 
@@ -52,14 +61,14 @@
 
   // The id for the account that the user has requested to remove from the
   // current profile. It is set in |showAccountRemovalView| and used in
-  // |removeAccountAndRelaunch|.
+  // |removeAccount|.
   std::string accountIdToRemove_;
 
   // Active view mode.
   BubbleViewMode viewMode_;
 
-  // Whether the tutorial card is showing in the last active view.
-  BOOL tutorialShowing_;
+  // The current tutorial mode.
+  TutorialMode tutorialMode_;
 
   // List of the full, un-elided accounts for the active profile. The keys are
   // generated used to tag the UI buttons, and the values are the original
@@ -114,8 +123,8 @@
 // account from the active profile if possible.
 - (IBAction)showAccountRemovalView:(id)sender;
 
-// Removes the current account |accountIdToRemove_| and relaunches the browser.
-- (IBAction)removeAccountAndRelaunch:(id)sender;
+// Removes the current account |accountIdToRemove_|.
+- (IBAction)removeAccount:(id)sender;
 
 // Reset the WebContents used by the Gaia embedded view.
 - (void)cleanUpEmbeddedViewContents;
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
index 12fa745..aa013c1 100644
--- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
+++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
@@ -25,6 +25,7 @@
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/signin/signin_promo.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/chrome_pages.h"
@@ -42,7 +43,6 @@
 #include "components/signin/core/browser/signin_manager.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "google_apis/gaia/oauth2_token_service.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
@@ -75,7 +75,6 @@
 const CGFloat kTitleFontSize = 15.0;
 const CGFloat kTextFontSize = 12.0;
 const CGFloat kProfileButtonHeight = 30;
-const int kOverlayHeight = 20;  // Height of the "Change" avatar photo overlay.
 const int kBezelThickness = 3;  // Width of the bezel on an NSButton.
 const int kImageTitleSpacing = 10;
 const int kBlueButtonHeight = 30;
@@ -86,18 +85,19 @@
 
 // Fixed size for the account removal view.
 const CGFloat kFixedAccountRemovalViewWidth = 280;
+// Fixed size for the end-preview view.
+const int kFixedEndPreviewViewWidth = 280;
 
-// Maximum number of times to show the tutorial in the profile avatar bubble.
-const int kProfileAvatarTutorialShowMax = 5;
+// Maximum number of times to show the welcome tutorial in the profile avatar
+// bubble.
+const int kProfileAvatarTutorialShowMax = 1;
 
 // The tag number for the primary account.
 const int kPrimaryProfileTag = -1;
 
 gfx::Image CreateProfileImage(const gfx::Image& icon, int imageSize) {
   return profiles::GetSizedAvatarIcon(
-      icon, true /* image is a square */,
-      imageSize + profiles::kAvatarIconPadding,
-      imageSize + profiles::kAvatarIconPadding);
+      icon, true /* image is a square */, imageSize, imageSize);
 }
 
 // Updates the window size and position.
@@ -348,7 +348,7 @@
 }
 
 - (void)drawRect:(NSRect)dirtyRect {
-  NSColor* backgroundColor = [NSColor colorWithCalibratedWhite:0 alpha:0.5f];
+  NSColor* backgroundColor = [NSColor colorWithCalibratedWhite:1 alpha:0.4f];
   [backgroundColor setFill];
   NSRectFillUsingOperation(dirtyRect, NSCompositeSourceAtop);
   [super drawRect:dirtyRect];
@@ -402,18 +402,22 @@
             userInfo:nil]);
     [self addTrackingArea:trackingArea_.get()];
 
+    NSRect bounds = NSMakeRect(0, 0, kLargeImageSide, kLargeImageSide);
     if (editingAllowed) {
-      // The avatar photo uses a frame of width profiles::kAvatarIconPadding,
-      // which we must subtract from the button's bounds.
-      changePhotoButton_.reset([self changePhotoButtonWithRect:NSMakeRect(
-          profiles::kAvatarIconPadding, profiles::kAvatarIconPadding,
-          kLargeImageSide - 2 * profiles::kAvatarIconPadding,
-          kOverlayHeight)]);
+      changePhotoButton_.reset([self changePhotoButtonWithRect:bounds]);
       [self addSubview:changePhotoButton_];
 
       // Hide the button until the image is hovered over.
       [changePhotoButton_ setHidden:YES];
     }
+
+    // Add the frame overlay last, so that both the photo and the button
+    // look like circles.
+    base::scoped_nsobject<NSImageView> frameOverlay(
+        [[NSImageView alloc] initWithFrame:bounds]);
+    [frameOverlay setImage:ui::ResourceBundle::GetSharedInstance().
+        GetNativeImageNamed(IDR_ICON_PROFILES_AVATAR_PHOTO_FRAME).AsNSImage()];
+    [self addSubview:frameOverlay];
   }
   return self;
 }
@@ -433,21 +437,9 @@
 - (TransparentBackgroundButton*)changePhotoButtonWithRect:(NSRect)rect {
   TransparentBackgroundButton* button =
       [[TransparentBackgroundButton alloc] initWithFrame:rect];
-
-  // The button has a centered white text and a transparent background.
-  base::scoped_nsobject<NSMutableParagraphStyle> textStyle(
-      [[NSMutableParagraphStyle alloc] init]);
-  [textStyle setAlignment:NSCenterTextAlignment];
-  NSDictionary* titleAttributes = @{
-      NSParagraphStyleAttributeName : textStyle,
-      NSForegroundColorAttributeName : [NSColor whiteColor]
-  };
-  NSString* buttonTitle = l10n_util::GetNSString(
-      IDS_PROFILES_PROFILE_CHANGE_PHOTO_BUTTON);
-  base::scoped_nsobject<NSAttributedString> attributedTitle(
-      [[NSAttributedString alloc] initWithString:buttonTitle
-                                      attributes:titleAttributes]);
-  [button setAttributedTitle:attributedTitle];
+  [button setImage:ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
+      IDR_ICON_PROFILES_EDIT_CAMERA).AsNSImage()];
+  [button setImagePosition:NSImageOnly];
   [button setTarget:self];
   [button setAction:@selector(editPhoto:)];
   return button;
@@ -663,17 +655,21 @@
 @end
 
 @interface ProfileChooserController ()
+// Builds the profile chooser view.
+- (NSView*)buildProfileChooserView;
+
 // Builds a tutorial card with a title label using |titleMessageId|, a content
 // label using |contentMessageId|, and a bottom row with a right-aligned link
 // using |linkMessageId|, and a left aligned button using |buttonMessageId|.
 // On click, the link would execute |linkAction|, and the button would execute
-// |buttonAction|.
-- (NSView*)tutorialViewWithTitle:(int)titleMessageId
-                  contentMessage:(int)contentMessageId
-                     linkMessage:(int)linkMessageId
-                   buttonMessage:(int)buttonMessageId
-                      linkAction:(SEL)linkAction
-                    buttonAction:(SEL)buttonAction;
+// |buttonAction|. It sets |tutorialMode_| to the given |mode|.
+- (NSView*)tutorialViewWithMode:(TutorialMode)mode
+                   titleMessage:(int)titleMessageId
+                 contentMessage:(int)contentMessageId
+                    linkMessage:(int)linkMessageId
+                  buttonMessage:(int)buttonMessageId
+                     linkAction:(SEL)linkAction
+                   buttonAction:(SEL)buttonAction;
 
 // Builds a a tutorial card for new profile management preview if needed. if
 // new profile management is not enabled yet, then it prompts the user to try
@@ -712,6 +708,9 @@
 // Creates the account removal view.
 - (NSView*)buildAccountRemovalView;
 
+// Creates the end-preview view.
+- (NSView*)buildEndPreviewView;
+
 // Creates a button with |text|, an icon given by |imageResourceId| and with
 // |action|. The icon |alternateImageResourceId| is displayed in the button's
 // hovered and pressed states.
@@ -727,9 +726,11 @@
                      frameOrigin:(NSPoint)frameOrigin
                           action:(SEL)action;
 
-// Creates an email account button with |title| and a remove icon.
+// Creates an email account button with |title| and a remove icon. |tag|
+// indicates which account the button refers to.
 - (NSButton*)accountButtonWithRect:(NSRect)rect
-                             title:(const std::string&)title;
+                             title:(const std::string&)title
+                               tag:(int)tag;
 
 @end
 
@@ -804,12 +805,13 @@
   [self initMenuContentsWithView:BUBBLE_VIEW_MODE_ACCOUNT_REMOVAL];
 }
 
-- (IBAction)removeAccountAndRelaunch:(id)sender {
+- (IBAction)removeAccount:(id)sender {
   DCHECK(!accountIdToRemove_.empty());
   ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile(
       browser_->profile())->RevokeCredentials(accountIdToRemove_);
   accountIdToRemove_.clear();
-  chrome::AttemptRestart();
+
+  [self initMenuContentsWithView:BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
 }
 
 - (IBAction)openTutorialLearnMoreURL:(id)sender {
@@ -835,6 +837,23 @@
   [self initMenuContentsWithView:BUBBLE_VIEW_MODE_PROFILE_CHOOSER];
 }
 
+- (IBAction)showSendFeedbackTutorial:(id)sender {
+  tutorialMode_ = TUTORIAL_MODE_SEND_FEEDBACK;
+  [self initMenuContentsWithView:BUBBLE_VIEW_MODE_PROFILE_CHOOSER];
+}
+
+- (IBAction)showEndPreviewView:(id)sender {
+  [self initMenuContentsWithView:BUBBLE_VIEW_MODE_END_PREVIEW];
+}
+
+- (IBAction)sendFeedback:(id)sender {
+  chrome::OpenFeedbackDialog(browser_);
+}
+
+- (IBAction)endPreviewAndRelaunch:(id)sender {
+  profiles::DisableNewProfileManagementPreview();
+}
+
 - (void)cleanUpEmbeddedViewContents {
   webContents_.reset();
 }
@@ -853,7 +872,7 @@
                          anchoredAt:point])) {
     browser_ = browser;
     viewMode_ = mode;
-    tutorialShowing_ = false;
+    tutorialMode_ = TUTORIAL_MODE_NONE;
     observer_.reset(new ActiveProfileObserverBridge(self, browser_));
 
     avatarMenu_.reset(new AvatarMenu(
@@ -878,19 +897,33 @@
   viewMode_ = viewToDisplay;
   NSView* contentView = [[self window] contentView];
   [contentView setSubviews:[NSArray array]];
+  NSView* subView;
 
-  if (viewMode_ == BUBBLE_VIEW_MODE_GAIA_SIGNIN ||
-      viewMode_ == BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT ||
-      viewMode_ == BUBBLE_VIEW_MODE_ACCOUNT_REMOVAL) {
-    bool isRemovalView = viewMode_ == BUBBLE_VIEW_MODE_ACCOUNT_REMOVAL;
-    NSView* subView = isRemovalView ?
-        [self buildAccountRemovalView] : [self buildGaiaEmbeddedView];
-    [contentView addSubview:subView];
-    SetWindowSize([self window],
-        NSMakeSize(NSWidth([subView frame]), NSHeight([subView frame])));
-    return;
+  switch (viewMode_) {
+    case BUBBLE_VIEW_MODE_GAIA_SIGNIN:
+    case BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT:
+      subView = [self buildGaiaEmbeddedView];
+      break;
+    case BUBBLE_VIEW_MODE_ACCOUNT_REMOVAL:
+      subView = [self buildAccountRemovalView];
+      break;
+    case BUBBLE_VIEW_MODE_END_PREVIEW:
+      subView = [self buildEndPreviewView];
+      break;
+    case BUBBLE_VIEW_MODE_PROFILE_CHOOSER:
+    case BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT:
+      subView = [self buildProfileChooserView];
   }
 
+  [contentView addSubview:subView];
+  SetWindowSize([self window],
+      NSMakeSize(NSWidth([subView frame]), NSHeight([subView frame])));
+}
+
+- (NSView*)buildProfileChooserView {
+  base::scoped_nsobject<NSView> container(
+      [[NSView alloc] initWithFrame:NSZeroRect]);
+
   NSView* tutorialView = nil;
   NSView* currentProfileView = nil;
   base::scoped_nsobject<NSMutableArray> otherProfiles(
@@ -914,7 +947,7 @@
   if (!currentProfileView)  // Guest windows don't have an active profile.
     currentProfileView = [self createGuestProfileView];
 
-  // |yOffset| is the next position at which to draw in |contentView|
+  // |yOffset| is the next position at which to draw in |container|
   // coordinates.
   CGFloat yOffset = 0;
 
@@ -923,37 +956,37 @@
     NSRect rect = NSMakeRect(0, yOffset, kFixedMenuWidth, 0);
     NSView* optionsView = [self createOptionsViewWithRect:rect
                                                enableLock:enableLock];
-    [contentView addSubview:optionsView];
+    [container addSubview:optionsView];
     rect.origin.y = NSMaxY([optionsView frame]);
 
     NSBox* separator = [self separatorWithFrame:rect];
-    [contentView addSubview:separator];
+    [container addSubview:separator];
     yOffset = NSMaxY([separator frame]);
   }
 
-  if (viewToDisplay == BUBBLE_VIEW_MODE_PROFILE_CHOOSER &&
+  if (viewMode_ == BUBBLE_VIEW_MODE_PROFILE_CHOOSER &&
       switches::IsFastUserSwitching()) {
     // Other profiles switcher. The profiles have already been sorted
     // by their y-coordinate, so they can be added in the existing order.
     for (NSView *otherProfileView in otherProfiles.get()) {
       [otherProfileView setFrameOrigin:NSMakePoint(0, yOffset)];
-      [contentView addSubview:otherProfileView];
+      [container addSubview:otherProfileView];
       yOffset = NSMaxY([otherProfileView frame]);
 
       NSBox* separator =
           [self separatorWithFrame:NSMakeRect(0, yOffset, kFixedMenuWidth, 0)];
-      [contentView addSubview:separator];
+      [container addSubview:separator];
       yOffset = NSMaxY([separator frame]);
     }
-  } else if (viewToDisplay == BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT) {
+  } else if (viewMode_ == BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT) {
     NSView* currentProfileAccountsView = [self createCurrentProfileAccountsView:
         NSMakeRect(0, yOffset, kFixedMenuWidth, 0)];
-    [contentView addSubview:currentProfileAccountsView];
+    [container addSubview:currentProfileAccountsView];
     yOffset = NSMaxY([currentProfileAccountsView frame]);
 
     NSBox* accountsSeparator = [self separatorWithFrame:
         NSMakeRect(0, yOffset, kFixedMenuWidth, 0)];
-    [contentView addSubview:accountsSeparator];
+    [container addSubview:accountsSeparator];
     yOffset = NSMaxY([accountsSeparator frame]);
   }
 
@@ -961,36 +994,48 @@
   if (currentProfileView) {
     yOffset += kVerticalSpacing;
     [currentProfileView setFrameOrigin:NSMakePoint(0, yOffset)];
-    [contentView addSubview:currentProfileView];
+    [container addSubview:currentProfileView];
     yOffset = NSMaxY([currentProfileView frame]) + kVerticalSpacing;
   }
 
   if (tutorialView) {
     [tutorialView setFrameOrigin:NSMakePoint(0, yOffset)];
-    [contentView addSubview:tutorialView];
+    [container addSubview:tutorialView];
     yOffset = NSMaxY([tutorialView frame]);
   } else {
-    tutorialShowing_ = false;
+    tutorialMode_ = TUTORIAL_MODE_NONE;
   }
 
-  SetWindowSize([self window], NSMakeSize(kFixedMenuWidth, yOffset));
+  [container setFrameSize:NSMakeSize(kFixedMenuWidth, yOffset)];
+  return container.autorelease();;
 }
 
 - (NSView*)buildPreviewTutorialIfNeeded:(const AvatarMenu::Item&)item {
   if (!switches::IsNewProfileManagement()) {
-    return [self tutorialViewWithTitle:IDS_PROFILES_PREVIEW_TUTORIAL_TITLE
-                        contentMessage:
-        IDS_PROFILES_PREVIEW_TUTORIAL_CONTENT_TEXT
-                           linkMessage:IDS_PROFILES_PROFILE_TUTORIAL_LEARN_MORE
-                         buttonMessage:IDS_PROFILES_TUTORIAL_TRY_BUTTON
-                            linkAction:@selector(openTutorialLearnMoreURL:)
-                          buttonAction:
+    return [self tutorialViewWithMode:TUTORIAL_MODE_ENABLE_PREVIEW
+                         titleMessage:IDS_PROFILES_PREVIEW_TUTORIAL_TITLE
+                       contentMessage:IDS_PROFILES_PREVIEW_TUTORIAL_CONTENT_TEXT
+                          linkMessage:IDS_PROFILES_PROFILE_TUTORIAL_LEARN_MORE
+                        buttonMessage:IDS_PROFILES_TUTORIAL_TRY_BUTTON
+                           linkAction:@selector(openTutorialLearnMoreURL:)
+                         buttonAction:
         @selector(enableNewProfileManagementPreview:)];
   }
 
   if (!switches::IsNewProfileManagementPreviewEnabled())
     return nil;
 
+  if (tutorialMode_ == TUTORIAL_MODE_SEND_FEEDBACK) {
+    return [self tutorialViewWithMode:TUTORIAL_MODE_SEND_FEEDBACK
+                         titleMessage:IDS_PROFILES_FEEDBACK_TUTORIAL_TITLE
+                       contentMessage:
+        IDS_PROFILES_FEEDBACK_TUTORIAL_CONTENT_TEXT
+                          linkMessage:IDS_PROFILES_END_PREVIEW
+                        buttonMessage:IDS_PROFILES_SEND_FEEDBACK_BUTTON
+                           linkAction:@selector(showEndPreviewView:)
+                         buttonAction:@selector(sendFeedback:)];
+  }
+
   Profile* profile = browser_->profile();
   const int showCount = profile->GetPrefs()->GetInteger(
       prefs::kProfileAvatarTutorialShown);
@@ -998,29 +1043,32 @@
   if (showCount > kProfileAvatarTutorialShowMax)
     return nil;
 
-  if (!tutorialShowing_) {
+  if (tutorialMode_ != TUTORIAL_MODE_WELCOME) {
     if (showCount == kProfileAvatarTutorialShowMax)
       return nil;
     profile->GetPrefs()->SetInteger(
         prefs::kProfileAvatarTutorialShown, showCount + 1);
-    tutorialShowing_ = true;
   }
 
-  return [self tutorialViewWithTitle:IDS_PROFILES_PREVIEW_ENABLED_TUTORIAL_TITLE
-                      contentMessage:
+  return [self tutorialViewWithMode:TUTORIAL_MODE_WELCOME
+                       titleMessage:IDS_PROFILES_PREVIEW_ENABLED_TUTORIAL_TITLE
+                     contentMessage:
       IDS_PROFILES_PREVIEW_ENABLED_TUTORIAL_CONTENT_TEXT
-                         linkMessage:IDS_PROFILES_PROFILE_TUTORIAL_LEARN_MORE
-                       buttonMessage:IDS_PROFILES_TUTORIAL_OK_BUTTON
-                          linkAction:@selector(openTutorialLearnMoreURL:)
-                        buttonAction:@selector(dismissTutorial:)];
+                        linkMessage:IDS_PROFILES_PROFILE_TUTORIAL_LEARN_MORE
+                      buttonMessage:IDS_PROFILES_TUTORIAL_OK_BUTTON
+                         linkAction:@selector(openTutorialLearnMoreURL:)
+                       buttonAction:@selector(dismissTutorial:)];
 }
 
-- (NSView*)tutorialViewWithTitle:(int)titleMessageId
-                  contentMessage:(int)contentMessageId
-                     linkMessage:(int)linkMessageId
-                   buttonMessage:(int)buttonMessageId
-                      linkAction:(SEL)linkAction
-                    buttonAction:(SEL)buttonAction {
+- (NSView*)tutorialViewWithMode:(TutorialMode)mode
+                   titleMessage:(int)titleMessageId
+                 contentMessage:(int)contentMessageId
+                    linkMessage:(int)linkMessageId
+                  buttonMessage:(int)buttonMessageId
+                     linkAction:(SEL)linkAction
+                   buttonAction:(SEL)buttonAction {
+  tutorialMode_ = mode;
+
   NSColor* tutorialBackgroundColor =
       gfx::SkColorToSRGBNSColor(profiles::kAvatarTutorialBackgroundColor);
   base::scoped_nsobject<NSView> container([[BackgroundColorView alloc]
@@ -1053,7 +1101,7 @@
   NSButton* learnMoreLink =
       [self linkButtonWithTitle:l10n_util::GetNSString(linkMessageId)
                     frameOrigin:NSZeroPoint
-                         action:@selector(linkAction:)];
+                         action:linkAction];
   [[learnMoreLink cell] setTextColor:[NSColor whiteColor]];
   CGFloat linkYOffset = yOffset + (NSHeight([tutorialOkButton frame]) -
                                    NSHeight([learnMoreLink frame])) / 2;
@@ -1157,6 +1205,26 @@
   [container addSubview:iconView];
   yOffset = NSMaxY([iconView frame]);
 
+  if (switches::IsNewProfileManagementPreviewEnabled()) {
+    base::scoped_nsobject<HoverImageButton> questionButton(
+        [[HoverImageButton alloc] initWithFrame:NSZeroRect]);
+    [questionButton setBordered:NO];
+    ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
+    [questionButton setDefaultImage:rb->GetNativeImageNamed(
+        IDR_ICON_PROFILES_MENU_QUESTION_STABLE).ToNSImage()];
+    [questionButton setHoverImage:rb->GetNativeImageNamed(
+        IDR_ICON_PROFILES_MENU_QUESTION_HOVER).ToNSImage()];
+    [questionButton setPressedImage:rb->GetNativeImageNamed(
+        IDR_ICON_PROFILES_MENU_QUESTION_SELECT).ToNSImage()];
+    [questionButton setTarget:self];
+    [questionButton setAction:@selector(showSendFeedbackTutorial:)];
+    [questionButton sizeToFit];
+    const CGFloat size = NSHeight([questionButton frame]) + 2;
+    [questionButton setFrame:
+        NSMakeRect(kHorizontalSpacing, yOffset - size, size, size)];
+    [container addSubview:questionButton];
+  }
+
   [container setFrameSize:NSMakeSize(kFixedMenuWidth, yOffset)];
   return container.autorelease();
 }
@@ -1349,19 +1417,19 @@
     // Save the original email address, as the button text could be elided.
     currentProfileAccounts_[i] = accounts[i];
     NSButton* accountButton = [self accountButtonWithRect:rect
-                                                    title:accounts[i]];
-    [accountButton setTag:i];
+                                                    title:accounts[i]
+                                                      tag:i];
     [container addSubview:accountButton];
     rect.origin.y = NSMaxY([accountButton frame]);
   }
 
   // The primary account should always be listed first.
   NSButton* accountButton = [self accountButtonWithRect:rect
-                                                  title:primaryAccount];
+                                                  title:primaryAccount
+                                                    tag:kPrimaryProfileTag];
   [container addSubview:accountButton];
   [container setFrameSize:NSMakeSize(NSWidth([container frame]),
                                      NSMaxY([accountButton frame]))];
-  [accountButton setTag:kPrimaryProfileTag];
   return container.autorelease();
 }
 
@@ -1383,7 +1451,7 @@
       content::Referrer(),
       content::PAGE_TRANSITION_AUTO_TOPLEVEL,
       std::string());
-  NSView* webview = webContents_->GetView()->GetNativeView();
+  NSView* webview = webContents_->GetNativeView();
   [webview setFrameSize:NSMakeSize(kFixedGaiaViewWidth, kFixedGaiaViewHeight)];
   [container addSubview:webview];
   yOffset = NSMaxY([webview frame]);
@@ -1420,22 +1488,22 @@
       browser_->profile())->GetAuthenticatedUsername();
   bool isPrimaryAccount = primaryAccount == accountIdToRemove_;
 
-  // Adds "remove and relaunch" button at the bottom if needed.
+  // Adds "remove account" button at the bottom if needed.
   if (!isPrimaryAccount) {
-    base::scoped_nsobject<NSButton> removeAndRelaunchButton(
+    base::scoped_nsobject<NSButton> removeAccountButton(
         [[BlueLabelButton alloc] initWithFrame:NSZeroRect]);
-    [removeAndRelaunchButton setTitle:l10n_util::GetNSString(
+    [removeAccountButton setTitle:l10n_util::GetNSString(
         IDS_PROFILES_ACCOUNT_REMOVAL_BUTTON)];
-    [removeAndRelaunchButton setTarget:self];
-    [removeAndRelaunchButton setAction:@selector(removeAccountAndRelaunch:)];
-    [removeAndRelaunchButton sizeToFit];
-    [removeAndRelaunchButton setAlignment:NSCenterTextAlignment];
+    [removeAccountButton setTarget:self];
+    [removeAccountButton setAction:@selector(removeAccount:)];
+    [removeAccountButton sizeToFit];
+    [removeAccountButton setAlignment:NSCenterTextAlignment];
     CGFloat xOffset = (kFixedAccountRemovalViewWidth -
-        NSWidth([removeAndRelaunchButton frame])) / 2;
-    [removeAndRelaunchButton setFrameOrigin:NSMakePoint(xOffset, yOffset)];
-    [container addSubview:removeAndRelaunchButton];
+        NSWidth([removeAccountButton frame])) / 2;
+    [removeAccountButton setFrameOrigin:NSMakePoint(xOffset, yOffset)];
+    [container addSubview:removeAccountButton];
 
-    yOffset = NSMaxY([removeAndRelaunchButton frame]) + kVerticalSpacing;
+    yOffset = NSMaxY([removeAccountButton frame]) + kVerticalSpacing;
   }
 
   NSView* contentView;
@@ -1478,6 +1546,57 @@
   return container.autorelease();
 }
 
+- (NSView*)buildEndPreviewView {
+  base::scoped_nsobject<NSView> container(
+      [[NSView alloc] initWithFrame:NSZeroRect]);
+  CGFloat availableWidth =
+      kFixedEndPreviewViewWidth - 2 * kHorizontalSpacing;
+  CGFloat yOffset = kVerticalSpacing;
+
+  // Adds the "end preview and relaunch" button at the bottom.
+  base::scoped_nsobject<NSButton> endPreviewAndRelaunchButton(
+      [[BlueLabelButton alloc] initWithFrame:NSZeroRect]);
+  [endPreviewAndRelaunchButton setTitle:l10n_util::GetNSString(
+      IDS_PROFILES_END_PREVIEW_AND_RELAUNCH)];
+  [endPreviewAndRelaunchButton setTarget:self];
+  [endPreviewAndRelaunchButton setAction:@selector(endPreviewAndRelaunch:)];
+  [endPreviewAndRelaunchButton sizeToFit];
+  [endPreviewAndRelaunchButton setAlignment:NSCenterTextAlignment];
+  CGFloat xOffset = (kFixedEndPreviewViewWidth -
+      NSWidth([endPreviewAndRelaunchButton frame])) / 2;
+  [endPreviewAndRelaunchButton setFrameOrigin:NSMakePoint(xOffset, yOffset)];
+  [container addSubview:endPreviewAndRelaunchButton];
+  yOffset = NSMaxY([endPreviewAndRelaunchButton frame]) + kVerticalSpacing;
+
+  // Adds the main text label.
+  NSPoint contentFrameOrigin = NSMakePoint(kHorizontalSpacing, yOffset);
+  NSString* contentStr =
+      l10n_util::GetNSString(IDS_PROFILES_END_PREVIEW_TEXT);
+  NSTextField* contentLabel = BuildLabel(contentStr, contentFrameOrigin,
+      GetDialogBackgroundColor(), nil /* text_color */);
+  [contentLabel setFrameSize:NSMakeSize(availableWidth, 0)];
+  [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:contentLabel];
+  [container addSubview:contentLabel];
+  yOffset = NSMaxY([contentLabel frame]) + kVerticalSpacing;
+
+  // Adds the title card.
+  NSBox* separator = [self separatorWithFrame:
+      NSMakeRect(0, yOffset, kFixedEndPreviewViewWidth, 0)];
+  [container addSubview:separator];
+  yOffset = NSMaxY([separator frame]) + kSmallVerticalSpacing;
+
+  NSView* titleView = BuildTitleCard(
+      NSMakeRect(0, yOffset, kFixedEndPreviewViewWidth, 0),
+      IDS_PROFILES_END_PREVIEW,
+      self /* backButtonTarget*/,
+      @selector(showSendFeedbackTutorial:) /* backButtonAction */);
+  [container addSubview:titleView];
+  yOffset = NSMaxY([titleView frame]);
+
+  [container setFrameSize:NSMakeSize(kFixedEndPreviewViewWidth, yOffset)];
+  return container.autorelease();
+}
+
 // Called when clicked on the settings link.
 - (BOOL)textView:(NSTextView*)textView
    clickedOnLink:(id)link
@@ -1534,20 +1653,39 @@
 }
 
 - (NSButton*)accountButtonWithRect:(NSRect)rect
-                             title:(const std::string&)title {
+                             title:(const std::string&)title
+                               tag:(int)tag {
   NSColor* backgroundColor = gfx::SkColorToCalibratedNSColor(
       profiles::kAvatarBubbleAccountsBackgroundColor);
   base::scoped_nsobject<BackgroundColorHoverButton> button(
       [[BackgroundColorHoverButton alloc] initWithFrame:rect
                                       imageTitleSpacing:0
                                         backgroundColor:backgroundColor]);
-
-  [button setTitle:ElideEmail(title, rect.size.width)];
+  ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
+  NSImage* defaultImage = rb->GetNativeImageNamed(IDR_CLOSE_1).AsNSImage();
+  CGFloat kDeleteButtonWidth = [defaultImage size].width;
+  CGFloat availableWidth = rect.size.width -
+      kDeleteButtonWidth - kHorizontalSpacing;
+  [button setTitle:ElideEmail(title, availableWidth)];
   [button setAlignment:NSLeftTextAlignment];
   [button setBordered:NO];
-  [button setTarget:self];
-  [button setAction:@selector(showAccountRemovalView:)];
 
+  // Delete button.
+  rect.origin = NSMakePoint(availableWidth, 0);
+  rect.size.width = kDeleteButtonWidth;
+  base::scoped_nsobject<HoverImageButton> deleteButton(
+      [[HoverImageButton alloc] initWithFrame:rect]);
+  [deleteButton setBordered:NO];
+  [deleteButton setDefaultImage:defaultImage];
+  [deleteButton setHoverImage:rb->GetNativeImageNamed(
+      IDR_CLOSE_1_H).ToNSImage()];
+  [deleteButton setPressedImage:rb->GetNativeImageNamed(
+      IDR_CLOSE_1_P).ToNSImage()];
+  [deleteButton setTarget:self];
+  [deleteButton setAction:@selector(showAccountRemovalView:)];
+  [deleteButton setTag:tag];
+
+  [button addSubview:deleteButton];
   return button.autorelease();
 }
 
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller_unittest.mm b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller_unittest.mm
index bafb0d2..8ebd298 100644
--- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller_unittest.mm
@@ -103,6 +103,8 @@
   StartProfileChooserController();
 
   NSArray* subviews = [[[controller() window] contentView] subviews];
+  EXPECT_EQ(1U, [subviews count]);
+  subviews = [[subviews objectAtIndex:0] subviews];
 
   // Three profiles means we should have one active card, one separator and
   // one option buttons view.
@@ -146,6 +148,8 @@
   StartProfileChooserController();
 
   NSArray* subviews = [[[controller() window] contentView] subviews];
+  EXPECT_EQ(1U, [subviews count]);
+  subviews = [[subviews objectAtIndex:0] subviews];
 
   // Three profiles means we should have one active card and a
   // fast user switcher which has two "other" profiles and 2 separators. In
@@ -200,6 +204,8 @@
   StartProfileChooserController();
 
   NSArray* subviews = [[[controller() window] contentView] subviews];
+  EXPECT_EQ(1U, [subviews count]);
+  subviews = [[subviews objectAtIndex:0] subviews];
 
   // Three profiles means we should have one active card, two "other" profiles,
   // each with a separator, and one option buttons view.
@@ -253,6 +259,8 @@
   StartProfileChooserController();
 
   NSArray* subviews = [[[controller() window] contentView] subviews];
+  EXPECT_EQ(1U, [subviews count]);
+  subviews = [[subviews objectAtIndex:0] subviews];
   NSString* sortedNames[] = { @"Another Test",
                               @"New Profile",
                               @"Test 1",
@@ -278,6 +286,8 @@
   EnableNewProfileManagement();
   StartProfileChooserController();
   NSArray* subviews = [[[controller() window] contentView] subviews];
+  EXPECT_EQ(1U, [subviews count]);
+  subviews = [[subviews objectAtIndex:0] subviews];
   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
 
@@ -294,6 +304,8 @@
   EnableNewAvatarMenuOnly();
   StartProfileChooserController();
   NSArray* subviews = [[[controller() window] contentView] subviews];
+  EXPECT_EQ(1U, [subviews count]);
+  subviews = [[subviews objectAtIndex:0] subviews];
   NSArray* activeCardSubviews = [[subviews objectAtIndex:4] subviews];
   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
 
@@ -314,6 +326,8 @@
 
   StartProfileChooserController();
   NSArray* subviews = [[[controller() window] contentView] subviews];
+  EXPECT_EQ(1U, [subviews count]);
+  subviews = [[subviews objectAtIndex:0] subviews];
   NSArray* activeCardSubviews = [[subviews objectAtIndex:2] subviews];
   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
 
@@ -334,6 +348,8 @@
 
   StartProfileChooserController();
   NSArray* subviews = [[[controller() window] contentView] subviews];
+  EXPECT_EQ(1U, [subviews count]);
+  subviews = [[subviews objectAtIndex:0] subviews];
   NSArray* activeCardSubviews = [[subviews objectAtIndex:4] subviews];
   NSArray* activeCardLinks = [[activeCardSubviews objectAtIndex:0] subviews];
 
@@ -365,6 +381,8 @@
   [controller() initMenuContentsWithView:BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT];
 
   NSArray* subviews = [[[controller() window] contentView] subviews];
+  EXPECT_EQ(1U, [subviews count]);
+  subviews = [[subviews objectAtIndex:0] subviews];
 
   // There should be one active card, one accounts container, two separators
   // and one option buttons view.
@@ -400,16 +418,20 @@
 
   NSButton* genericAccount =
       static_cast<NSButton*>([accountsListSubviews objectAtIndex:0]);
-  EXPECT_EQ(@selector(showAccountRemovalView:), [genericAccount action]);
-  EXPECT_EQ(controller(), [genericAccount target]);
-  EXPECT_NE(-1, [genericAccount tag]);
+  NSButton* genericAccountDelete =
+      static_cast<NSButton*>([[genericAccount subviews] objectAtIndex:0]);
+  EXPECT_EQ(@selector(showAccountRemovalView:), [genericAccountDelete action]);
+  EXPECT_EQ(controller(), [genericAccountDelete target]);
+  EXPECT_NE(-1, [genericAccountDelete tag]);
 
   // Primary accounts are always last.
   NSButton* primaryAccount =
       static_cast<NSButton*>([accountsListSubviews objectAtIndex:1]);
-  EXPECT_EQ(@selector(showAccountRemovalView:), [primaryAccount action]);
-  EXPECT_EQ(controller(), [primaryAccount target]);
-  EXPECT_EQ(-1, [primaryAccount tag]);
+  NSButton* primaryAccountDelete =
+      static_cast<NSButton*>([[primaryAccount subviews] objectAtIndex:0]);
+  EXPECT_EQ(@selector(showAccountRemovalView:), [primaryAccountDelete action]);
+  EXPECT_EQ(controller(), [primaryAccountDelete target]);
+  EXPECT_EQ(-1, [primaryAccountDelete tag]);
 
   // There should be another separator.
   EXPECT_TRUE([[subviews objectAtIndex:3] isKindOfClass:[NSBox class]]);
diff --git a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm
index 89a0cb5..3087ac4 100644
--- a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm
+++ b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm
@@ -8,7 +8,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
@@ -83,7 +82,7 @@
     // Initialize the web view.
     webContents_.reset(content::WebContents::Create(
         content::WebContents::CreateParams(profile)));
-    window.contentView = webContents_->GetView()->GetNativeView();
+    window.contentView = webContents_->GetNativeView();
     DCHECK(window.contentView);
 
     [[NSNotificationCenter defaultCenter]
diff --git a/chrome/browser/ui/cocoa/speech_recognition_bubble_cocoa.mm b/chrome/browser/ui/cocoa/speech_recognition_bubble_cocoa.mm
deleted file mode 100644
index 8c65dad..0000000
--- a/chrome/browser/ui/cocoa/speech_recognition_bubble_cocoa.mm
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2012 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "chrome/browser/speech/speech_recognition_bubble.h"
-
-#import "base/mac/scoped_nsobject.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/cocoa/browser_window_cocoa.h"
-#include "chrome/browser/ui/cocoa/browser_window_controller.h"
-#include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
-#import "chrome/browser/ui/cocoa/speech_recognition_window_controller.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "ui/gfx/image/image_skia_util_mac.h"
-
-using content::WebContents;
-
-namespace {
-
-// A class to bridge between the speech recognition C++ code and the Objective-C
-// bubble implementation. See chrome/browser/speech/speech_recognition_bubble.h
-// for more information on how this gets used.
-class SpeechRecognitionBubbleImpl : public SpeechRecognitionBubbleBase {
- public:
-  SpeechRecognitionBubbleImpl(int render_process_id,
-                              int render_view_id,
-                              Delegate* delegate,
-                              const gfx::Rect& element_rect);
-  virtual ~SpeechRecognitionBubbleImpl();
-  virtual void Show() OVERRIDE;
-  virtual void Hide() OVERRIDE;
-  virtual void UpdateLayout() OVERRIDE;
-  virtual void UpdateImage() OVERRIDE;
-
- private:
-  base::scoped_nsobject<SpeechRecognitionWindowController> window_;
-  Delegate* delegate_;
-  gfx::Rect element_rect_;
-};
-
-SpeechRecognitionBubbleImpl::SpeechRecognitionBubbleImpl(
-    int render_process_id,
-    int render_view_id,
-    Delegate* delegate,
-    const gfx::Rect& element_rect)
-    : SpeechRecognitionBubbleBase(render_process_id, render_view_id),
-      delegate_(delegate),
-      element_rect_(element_rect) {
-}
-
-SpeechRecognitionBubbleImpl::~SpeechRecognitionBubbleImpl() {
-  if (window_.get())
-    [window_.get() close];
-}
-
-void SpeechRecognitionBubbleImpl::UpdateImage() {
-  if (window_.get() && GetWebContents())
-    [window_.get() setImage:gfx::NSImageFromImageSkia(icon_image())];
-}
-
-void SpeechRecognitionBubbleImpl::Show() {
-  if (!GetWebContents())
-    return;
-
-  if (window_.get()) {
-    [window_.get() show];
-    return;
-  }
-
-  // Find the screen coordinates for the given tab and position the bubble's
-  // arrow anchor point inside that to point at the bottom-left of the html
-  // input element rect if the position is valid, otherwise point it towards
-  // the page icon in the omnibox.
-  gfx::NativeView view = GetWebContents()->GetView()->GetNativeView();
-  NSWindow* parent_window = [view window];
-  NSRect tab_bounds = [view bounds];
-  int anchor_x = tab_bounds.origin.x + element_rect_.x() +
-                 element_rect_.width() - kBubbleTargetOffsetX;
-  int anchor_y = tab_bounds.origin.y + tab_bounds.size.height -
-                 element_rect_.y() - element_rect_.height();
-
-  NSPoint anchor = NSMakePoint(anchor_x, anchor_y);
-  if (NSPointInRect(anchor, tab_bounds)) {
-    // Good, convert to window coordinates.
-    anchor = [view convertPoint:anchor toView:nil];
-  } else {
-    LocationBarViewMac* locationBar =
-        [[parent_window windowController] locationBarBridge];
-
-    if (locationBar) {
-      anchor = locationBar->GetPageInfoBubblePoint();
-    } else {
-      // This is very rare, but possible. Just use the top-left corner.
-      // See http://crbug.com/119237
-      anchor = NSMakePoint(NSMinX(tab_bounds), NSMaxY(tab_bounds));
-      anchor = [view convertPoint:anchor toView:nil];
-    }
-  }
-
-  anchor = [parent_window convertBaseToScreen:anchor];
-
-  window_.reset([[SpeechRecognitionWindowController alloc]
-      initWithParentWindow:parent_window
-                  delegate:delegate_
-                anchoredAt:anchor]);
-
-  UpdateLayout();
-  [window_.get() show];
-}
-
-void SpeechRecognitionBubbleImpl::Hide() {
-  if (!window_.get())
-    return;
-
-  [window_.get() close];
-  window_.reset();
-}
-
-void SpeechRecognitionBubbleImpl::UpdateLayout() {
-  if (!window_.get() || !GetWebContents())
-    return;
-
-  [window_.get() updateLayout:display_mode()
-                  messageText:message_text()
-                    iconImage:gfx::NSImageFromImageSkia(icon_image())];
-}
-
-}  // namespace
-
-SpeechRecognitionBubble* SpeechRecognitionBubble::CreateNativeBubble(
-    int render_process_id,
-    int render_view_id,
-    Delegate* delegate,
-    const gfx::Rect& element_rect) {
-  return new SpeechRecognitionBubbleImpl(render_process_id,
-                                         render_view_id,
-                                         delegate,
-                                         element_rect);
-}
diff --git a/chrome/browser/ui/cocoa/speech_recognition_window_controller.h b/chrome/browser/ui/cocoa/speech_recognition_window_controller.h
deleted file mode 100644
index 24fa890..0000000
--- a/chrome/browser/ui/cocoa/speech_recognition_window_controller.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_UI_COCOA_SPEECH_RECOGNITION_WINDOW_CONTROLLER_H_
-#define CHROME_BROWSER_UI_COCOA_SPEECH_RECOGNITION_WINDOW_CONTROLLER_H_
-
-#import <Cocoa/Cocoa.h>
-
-#include "chrome/browser/speech/speech_recognition_bubble.h"
-#include "chrome/browser/ui/cocoa/base_bubble_controller.h"
-
-// Controller for the speech recognition bubble window. This bubble window gets
-// displayed when the user starts speech input in a html input element.
-@interface SpeechRecognitionWindowController : BaseBubbleController {
- @private
-  SpeechRecognitionBubble::Delegate* delegate_;  // weak.
-  SpeechRecognitionBubbleBase::DisplayMode displayMode_;
-
-  // References below are weak, being obtained from the nib.
-  IBOutlet NSImageView* iconImage_;
-  IBOutlet NSTextField* instructionLabel_;
-  IBOutlet NSButton* cancelButton_;
-  IBOutlet NSButton* tryAgainButton_;
-  IBOutlet NSButton* micSettingsButton_;
-}
-
-// Initialize the window. |anchoredAt| is in screen coordinates.
-- (id)initWithParentWindow:(NSWindow*)parentWindow
-                  delegate:(SpeechRecognitionBubbleDelegate*)delegate
-                anchoredAt:(NSPoint)anchoredAt;
-
-// Handler for the cancel button.
-- (IBAction)cancel:(id)sender;
-
-// Handler for the try again button.
-- (IBAction)tryAgain:(id)sender;
-
-// Handler for the mic settings button.
-- (IBAction)micSettings:(id)sender;
-
-// Updates the UI with data related to the given display mode.
-- (void)updateLayout:(SpeechRecognitionBubbleBase::DisplayMode)mode
-         messageText:(const base::string16&)messageText
-           iconImage:(NSImage*)iconImage;
-
-// Makes the speech recognition bubble visible on screen.
-- (void)show;
-
-// Hides the speech recognition bubble away from screen. This does NOT release
-// the controller and the window.
-- (void)hide;
-
-// Sets the image to be displayed in the bubble's status ImageView. A future
-// call to updateLayout may change the image.
-// TODO(satish): Clean that up and move it into the platform independent
-// SpeechRecognitionBubbleBase class.
-- (void)setImage:(NSImage*)image;
-
-@end
-
-#endif  // CHROME_BROWSER_UI_COCOA_SPEECH_RECOGNITION_WINDOW_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/speech_recognition_window_controller.mm b/chrome/browser/ui/cocoa/speech_recognition_window_controller.mm
deleted file mode 100644
index 887f75a..0000000
--- a/chrome/browser/ui/cocoa/speech_recognition_window_controller.mm
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright (c) 2012 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.
-
-#import "speech_recognition_window_controller.h"
-
-#include "base/logging.h"
-#include "base/strings/sys_string_conversions.h"
-#include "chrome/browser/ui/cocoa/info_bubble_view.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#import "skia/ext/skia_utils_mac.h"
-#import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
-#include "ui/base/l10n/l10n_util_mac.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/image/image.h"
-
-const int kBubbleControlVerticalSpacing = 10;  // Space between controls.
-const int kBubbleHorizontalMargin = 5;  // Space on either sides of controls.
-const int kInstructionLabelMaxWidth = 150;
-
-@interface SpeechRecognitionWindowController (Private)
-- (NSSize)calculateContentSize;
-- (void)layout:(NSSize)size;
-@end
-
-@implementation SpeechRecognitionWindowController
-
-- (id)initWithParentWindow:(NSWindow*)parentWindow
-                  delegate:(SpeechRecognitionBubbleDelegate*)delegate
-                anchoredAt:(NSPoint)anchoredAt {
-  if ((self = [super initWithWindowNibPath:@"SpeechRecognitionBubble"
-                              parentWindow:parentWindow
-                                anchoredAt:anchoredAt])) {
-    DCHECK(delegate);
-    delegate_ = delegate;
-    displayMode_ = SpeechRecognitionBubbleBase::DISPLAY_MODE_WARM_UP;
-  }
-  return self;
-}
-
-- (void)awakeFromNib {
-  [super awakeFromNib];
-  InfoBubbleView* bubble = [self bubble];
-  [bubble setArrowLocation:info_bubble::kTopLeft];
-  NSSize arrowSize = NSMakeSize(0, info_bubble::kBubbleArrowHeight);
-  arrowSize = [bubble convertSize:arrowSize toView:nil];
-  NSPoint anchorPoint = self.anchorPoint;
-  anchorPoint.y += arrowSize.height / 2.0;
-  self.anchorPoint = anchorPoint;
-}
-
-- (IBAction)cancel:(id)sender {
-  delegate_->InfoBubbleButtonClicked(SpeechRecognitionBubble::BUTTON_CANCEL);
-}
-
-- (IBAction)tryAgain:(id)sender {
-  delegate_->InfoBubbleButtonClicked(SpeechRecognitionBubble::BUTTON_TRY_AGAIN);
-}
-
-- (IBAction)micSettings:(id)sender {
-  [[NSWorkspace sharedWorkspace] openFile:
-       @"/System/Library/PreferencePanes/Sound.prefPane"];
-}
-
-// Calculate the window dimensions to reflect the sum height and max width of
-// all controls, with appropriate spacing between and around them. The returned
-// size is in view coordinates.
-- (NSSize)calculateContentSize {
-  [GTMUILocalizerAndLayoutTweaker sizeToFitView:cancelButton_];
-  [GTMUILocalizerAndLayoutTweaker sizeToFitView:tryAgainButton_];
-  [GTMUILocalizerAndLayoutTweaker sizeToFitView:micSettingsButton_];
-  NSSize cancelSize = [cancelButton_ bounds].size;
-  NSSize tryAgainSize = [tryAgainButton_ bounds].size;
-  CGFloat newHeight = cancelSize.height + kBubbleControlVerticalSpacing;
-  CGFloat newWidth = cancelSize.width;
-  if (![tryAgainButton_ isHidden])
-    newWidth += tryAgainSize.width;
-
-  // The size of the bubble in warm up mode is fixed to be the same as in
-  // recording mode, so from warm up it can transition to recording without any
-  // UI jank.
-  bool isWarmUp = (displayMode_ ==
-                   SpeechRecognitionBubbleBase::DISPLAY_MODE_WARM_UP);
-
-  if (![iconImage_ isHidden]) {
-    NSSize size = [[iconImage_ image] size];
-    if (isWarmUp) {
-      NSImage* volumeIcon =
-          ResourceBundle::GetSharedInstance().GetNativeImageNamed(
-              IDR_SPEECH_INPUT_MIC_EMPTY).ToNSImage();
-      size = [volumeIcon size];
-    }
-    newHeight += size.height;
-    newWidth = std::max(newWidth, size.width + 2 * kBubbleHorizontalMargin);
-  }
-
-  if (![instructionLabel_ isHidden] || isWarmUp) {
-    [instructionLabel_ sizeToFit];
-    NSSize textSize = [[instructionLabel_ cell] cellSize];
-    NSRect boundsRect = NSMakeRect(0, 0, kInstructionLabelMaxWidth,
-                                   CGFLOAT_MAX);
-    NSSize multiLineSize =
-        [[instructionLabel_ cell] cellSizeForBounds:boundsRect];
-    if (textSize.width > multiLineSize.width)
-      textSize = multiLineSize;
-    newHeight += textSize.height + kBubbleControlVerticalSpacing;
-    newWidth = std::max(newWidth, textSize.width);
-  }
-
-  if (![micSettingsButton_ isHidden]) {
-    NSSize size = [micSettingsButton_ bounds].size;
-    newHeight += size.height;
-    newWidth = std::max(newWidth, size.width);
-  }
-
-  return NSMakeSize(newWidth + 2 * kBubbleHorizontalMargin,
-                    newHeight + 3 * kBubbleControlVerticalSpacing);
-}
-
-// Position the controls within the given content area bounds.
-- (void)layout:(NSSize)size {
-  int y = kBubbleControlVerticalSpacing;
-
-  NSRect cancelRect = [cancelButton_ bounds];
-
-  if ([tryAgainButton_ isHidden]) {
-    cancelRect.origin.x = (size.width - NSWidth(cancelRect)) / 2;
-  } else {
-    NSRect tryAgainRect = [tryAgainButton_ bounds];
-    cancelRect.origin.x = (size.width - NSWidth(cancelRect) -
-                           NSWidth(tryAgainRect)) / 2;
-    tryAgainRect.origin.x = cancelRect.origin.x + NSWidth(cancelRect);
-    tryAgainRect.origin.y = y;
-    [tryAgainButton_ setFrame:tryAgainRect];
-  }
-  cancelRect.origin.y = y;
-
-  if (![cancelButton_ isHidden]) {
-    [cancelButton_ setFrame:cancelRect];
-    y += NSHeight(cancelRect) + kBubbleControlVerticalSpacing;
-  }
-
-  NSRect rect;
-  if (![micSettingsButton_ isHidden]) {
-    rect = [micSettingsButton_ bounds];
-    rect.origin.x = (size.width - NSWidth(rect)) / 2;
-    rect.origin.y = y;
-    [micSettingsButton_ setFrame:rect];
-    y += rect.size.height + kBubbleControlVerticalSpacing;
-  }
-
-  if (![instructionLabel_ isHidden]) {
-    int spaceForIcon = 0;
-    if (![iconImage_ isHidden]) {
-      spaceForIcon = [[iconImage_ image] size].height +
-                     kBubbleControlVerticalSpacing;
-    }
-
-    rect = NSMakeRect(0, y, size.width, size.height - y - spaceForIcon -
-                      kBubbleControlVerticalSpacing * 2);
-    [instructionLabel_ setFrame:rect];
-    y = size.height - spaceForIcon - kBubbleControlVerticalSpacing;
-  }
-
-  if (![iconImage_ isHidden]) {
-    rect.size = [[iconImage_ image] size];
-    // In warm-up mode only the icon gets displayed so center it vertically.
-    if (displayMode_ == SpeechRecognitionBubbleBase::DISPLAY_MODE_WARM_UP)
-      y = (size.height - rect.size.height) / 2;
-    rect.origin.x = (size.width - NSWidth(rect)) / 2;
-    rect.origin.y = y;
-    [iconImage_ setFrame:rect];
-  }
-}
-
-- (void)updateLayout:(SpeechRecognitionBubbleBase::DisplayMode)mode
-         messageText:(const base::string16&)messageText
-           iconImage:(NSImage*)iconImage {
-  // The very first time this method is called, the child views would still be
-  // uninitialized and null. So we invoke [self window] first and that sets up
-  // the child views properly so we can do the layout calculations below.
-  NSWindow* window = [self window];
-  displayMode_ = mode;
-  BOOL is_message = (mode == SpeechRecognitionBubbleBase::DISPLAY_MODE_MESSAGE);
-  BOOL is_recording =
-      (mode == SpeechRecognitionBubbleBase::DISPLAY_MODE_RECORDING);
-  BOOL is_warm_up = (mode == SpeechRecognitionBubbleBase::DISPLAY_MODE_WARM_UP);
-  [iconImage_ setHidden:is_message];
-  [tryAgainButton_ setHidden:!is_message];
-  [micSettingsButton_ setHidden:!is_message];
-  [instructionLabel_ setHidden:!is_message && !is_recording];
-  [cancelButton_ setHidden:is_warm_up];
-
-  // Get the right set of controls to be visible.
-  if (is_message) {
-    [instructionLabel_ setStringValue:base::SysUTF16ToNSString(messageText)];
-  } else {
-    [iconImage_ setImage:iconImage];
-    [instructionLabel_ setStringValue:l10n_util::GetNSString(
-        IDS_SPEECH_INPUT_BUBBLE_HEADING)];
-  }
-
-  NSSize newSize = [self calculateContentSize];
-  [[self bubble] setFrameSize:newSize];
-
-  NSSize windowDelta = [[window contentView] convertSize:newSize toView:nil];
-  NSRect newFrame = [window frame];
-  newFrame.origin.y -= windowDelta.height - newFrame.size.height;
-  newFrame.size = windowDelta;
-  [window setFrame:newFrame display:YES];
-
-  [self layout:newSize];  // Layout all the child controls.
-}
-
-- (void)windowWillClose:(NSNotification*)notification {
-  delegate_->InfoBubbleFocusChanged();
-}
-
-- (void)show {
-  [self showWindow:nil];
-}
-
-- (void)hide {
-  [[self window] orderOut:nil];
-}
-
-- (void)setImage:(NSImage*)image {
-  [iconImage_ setImage:image];
-}
-
-@end  // implementation SpeechRecognitionWindowController
diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
index e1e228a..f08ed53 100644
--- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
+++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
@@ -15,7 +15,6 @@
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "net/cert/x509_certificate.h"
 #include "net/cert/x509_util_mac.h"
diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa_browsertest.mm b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa_browsertest.mm
index fe81885..c9db177 100644
--- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa_browsertest.mm
+++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa_browsertest.mm
@@ -15,7 +15,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/test_utils.h"
 #include "ui/base/cocoa/window_size_constants.h"
 
diff --git a/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.mm b/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.mm
index 5fdc5be..3e6d73c 100644
--- a/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.mm
+++ b/chrome/browser/ui/cocoa/tab_contents/chrome_web_contents_view_delegate_mac.mm
@@ -10,7 +10,6 @@
 #include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 ChromeWebContentsViewDelegateMac::ChromeWebContentsViewDelegateMac(
     content::WebContents* web_contents)
diff --git a/chrome/browser/ui/cocoa/tab_contents/overlayable_contents_controller.mm b/chrome/browser/ui/cocoa/tab_contents/overlayable_contents_controller.mm
index 0511375..50b743a 100644
--- a/chrome/browser/ui/cocoa/tab_contents/overlayable_contents_controller.mm
+++ b/chrome/browser/ui/cocoa/tab_contents/overlayable_contents_controller.mm
@@ -5,7 +5,6 @@
 #import "chrome/browser/ui/cocoa/tab_contents/overlayable_contents_controller.h"
 
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 @implementation OverlayableContentsController
 
diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm
index df5da7a..70732b0 100644
--- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm
+++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm
@@ -8,7 +8,6 @@
 #include "base/mac/mac_util.h"
 #import "chrome/browser/ui/cocoa/tab_contents/sad_tab_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 namespace chrome {
 
@@ -42,7 +41,7 @@
     webContents_ = webContents;
 
     if (webContents_) {  // NULL in unit_tests.
-      NSView* ns_view = webContents_->GetView()->GetNativeView();
+      NSView* ns_view = webContents_->GetNativeView();
       [[self view] setAutoresizingMask:
           (NSViewWidthSizable | NSViewHeightSizable)];
       [ns_view addSubview:[self view]];
diff --git a/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.mm b/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.mm
index e0b033b..b49b82d 100644
--- a/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.mm
+++ b/chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.mm
@@ -17,7 +17,6 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/base/cocoa/animation_utils.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/gfx/geometry/rect.h"
@@ -222,7 +221,7 @@
     contentsNativeView = fullscreenView->GetNativeView();
   } else {
     isEmbeddingFullscreenWidget_ = NO;
-    contentsNativeView = contents_->GetView()->GetNativeView();
+    contentsNativeView = contents_->GetNativeView();
   }
   [contentsNativeView setFrame:[self frameForContentsView]];
   if ([subviews count] == 0) {
@@ -242,7 +241,7 @@
   // transitioning between composited and non-composited mode.
   // http://crbug.com/279472
   if (!fullscreenView)
-    contents_->GetView()->SetAllowOverlappingViews(true);
+    contents_->SetAllowOverlappingViews(true);
 }
 
 - (void)changeWebContents:(WebContents*)newContents {
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
index 36c20f0..b89ffb1 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
@@ -57,7 +57,6 @@
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "grit/ui_resources.h"
@@ -1311,7 +1310,7 @@
 
 // Called before |contents| is deactivated.
 - (void)tabDeactivatedWithContents:(content::WebContents*)contents {
-  contents->GetView()->StoreFocus();
+  contents->StoreFocus();
 }
 
 // Called when a notification is received from the model to select a particular
@@ -1357,7 +1356,7 @@
 
   if (newContents) {
     newContents->WasShown();
-    newContents->GetView()->RestoreFocus();
+    newContents->RestoreFocus();
   }
 }
 
@@ -2235,5 +2234,5 @@
   //
   // Changing it? Do not forget to modify
   // -[TabStripController swapInTabAtIndex:] too.
-  return [web_contents->GetView()->GetNativeView() superview];
+  return [web_contents->GetNativeView() superview];
 }
diff --git a/chrome/browser/ui/cocoa/view_id_util_browsertest.mm b/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
index e5166f3..60bc4e0 100644
--- a/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
+++ b/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
@@ -7,7 +7,6 @@
 #include "base/prefs/pref_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/download/download_shelf.h"
 #include "chrome/browser/profiles/profile.h"
@@ -20,6 +19,7 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "extensions/common/switches.h"
 
 using content::OpenURLParams;
@@ -43,8 +43,7 @@
   }
 
   void DoTest() {
-    // Make sure FindBar is created to test
-    // VIEW_ID_FIND_IN_PAGE_TEXT_FIELD and VIEW_ID_FIND_IN_PAGE.
+    // Make sure FindBar is created to test VIEW_ID_FIND_IN_PAGE_TEXT_FIELD.
     chrome::ShowFindBar(browser());
 
     // Make sure docked devtools is created to test VIEW_ID_DEV_TOOLS_DOCKED
diff --git a/chrome/browser/ui/cocoa/web_dialog_window_controller.mm b/chrome/browser/ui/cocoa/web_dialog_window_controller.mm
index db0be89..8c31923 100644
--- a/chrome/browser/ui/cocoa/web_dialog_window_controller.mm
+++ b/chrome/browser/ui/cocoa/web_dialog_window_controller.mm
@@ -13,7 +13,6 @@
 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui_message_handler.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/gfx/size.h"
@@ -344,7 +343,7 @@
 - (void)loadDialogContents {
   webContents_.reset(WebContents::Create(
       WebContents::CreateParams(delegate_->browser_context())));
-  [[self window] setContentView:webContents_->GetView()->GetNativeView()];
+  [[self window] setContentView:webContents_->GetNativeView()];
   webContents_->SetDelegate(delegate_.get());
 
   // This must be done before loading the page; see the comments in
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm
index 3984236..1d67b3c 100644
--- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm
+++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.mm
@@ -10,7 +10,6 @@
 #import "chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h"
 #import "chrome/browser/ui/website_settings/permission_bubble_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 PermissionBubbleCocoa::PermissionBubbleCocoa(NSWindow* parent_window)
     : parent_window_(parent_window), delegate_(NULL), bubbleController_(nil) {}
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h
index f09dfc7..3ec26c4 100644
--- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h
+++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h
@@ -28,9 +28,6 @@
 
   // Bridge to the C++ class that created this object.
   PermissionBubbleCocoa* bridge_;  // Weak.
-
-  // Anchor's offset from parent window's upper-left-hand corner.
-  NSPoint anchorOffset_;
 }
 
 // Designated initializer.  |parentWindow| and |bridge| must both be non-nil.
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm
index 92c8fc5..e42710a 100644
--- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm
@@ -15,6 +15,7 @@
 #include "chrome/browser/ui/browser_finder.h"
 #import "chrome/browser/ui/chrome_style.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
+#import "chrome/browser/ui/cocoa/browser_window_utils.h"
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h"
 #import "chrome/browser/ui/cocoa/hover_close_button.h"
 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h"
@@ -27,6 +28,7 @@
 #include "chrome/browser/ui/website_settings/permission_bubble_request.h"
 #include "chrome/browser/ui/website_settings/permission_bubble_view.h"
 #include "chrome/browser/ui/website_settings/permission_menu_model.h"
+#include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/user_metrics.h"
 #include "grit/generated_resources.h"
 #include "skia/ext/skia_utils_mac.h"
@@ -127,6 +129,23 @@
 
 @end
 
+// The window used for the permission bubble controller.
+// Subclassed to allow browser-handled keyboard events to be passed from the
+// permission bubble to its parent window, which is a browser window.
+@interface PermissionBubbleWindow : InfoBubbleWindow
+@end
+
+@implementation PermissionBubbleWindow
+- (BOOL)performKeyEquivalent:(NSEvent*)event {
+  content::NativeWebKeyboardEvent wrappedEvent(event);
+  if ([BrowserWindowUtils shouldHandleKeyboardEvent:wrappedEvent]) {
+    return [BrowserWindowUtils handleKeyboardEvent:event
+                                          inWindow:[self parentWindow]];
+  }
+  return [super performKeyEquivalent:event];
+}
+@end
+
 @interface PermissionBubbleController ()
 
 // Returns an autoreleased NSView displaying the icon and label for |request|.
@@ -171,9 +190,6 @@
 // Called when the 'customize' button is pressed.
 - (void)onCustomize:(id)sender;
 
-// Called when the parent window is resized.
-- (void)parentWindowDidResize:(NSNotification*)notification;
-
 // Sets the width of both |viewA| and |viewB| to be the larger of the
 // two views' widths.  Does not change either view's origin or height.
 + (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB;
@@ -190,32 +206,23 @@
                     bridge:(PermissionBubbleCocoa*)bridge {
   DCHECK(parentWindow);
   DCHECK(bridge);
-  base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc]
-      initWithContentRect:ui::kWindowSizeDeterminedLater
-                styleMask:NSBorderlessWindowMask
-                  backing:NSBackingStoreBuffered
-                    defer:NO]);
+  base::scoped_nsobject<PermissionBubbleWindow> window(
+      [[PermissionBubbleWindow alloc]
+          initWithContentRect:ui::kWindowSizeDeterminedLater
+                    styleMask:NSBorderlessWindowMask
+                      backing:NSBackingStoreBuffered
+                        defer:NO]);
   [window setAllowedAnimations:info_bubble::kAnimateNone];
   if ((self = [super initWithWindow:window
                        parentWindow:parentWindow
                          anchoredAt:NSZeroPoint])) {
     [self setShouldCloseOnResignKey:NO];
     [[self bubble] setArrowLocation:info_bubble::kTopLeft];
-    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
-    [nc addObserver:self
-           selector:@selector(parentWindowDidResize:)
-               name:NSWindowDidResizeNotification
-             object:parentWindow];
     bridge_ = bridge;
   }
   return self;
 }
 
-- (void)dealloc {
-  [[NSNotificationCenter defaultCenter] removeObserver:self];
-  [super dealloc];
-}
-
 - (void)windowWillClose:(NSNotification*)notification {
   bridge_->OnBubbleClosing();
   [super windowWillClose:notification];
@@ -362,12 +369,6 @@
     [self setAnchorPoint:anchorPoint];
     [self showWindow:nil];
   }
-  // The offset of the anchor from the parent's upper-left-hand corner is kept
-  // to ensure the bubble stays anchored correctly if the parent is resized.
-  anchorOffset_ = NSMakePoint(NSMinX([[self parentWindow] frame]),
-                              NSMaxY([[self parentWindow] frame]));
-  anchorOffset_.x -= anchorPoint.x;
-  anchorOffset_.y -= anchorPoint.y;
 }
 
 - (NSView*)labelForRequest:(PermissionBubbleRequest*)request {
@@ -515,13 +516,12 @@
   [self onCustomize:nil];
 }
 
-- (void)parentWindowDidResize:(NSNotification*)notification {
-  DCHECK_EQ([self parentWindow], [notification object]);
-  NSPoint newOrigin = NSMakePoint(NSMinX([[self parentWindow] frame]),
-                                  NSMaxY([[self parentWindow] frame]));
-  newOrigin.x -= anchorOffset_.x;
-  newOrigin.y -= anchorOffset_.y;
-  [self setAnchorPoint:newOrigin];
+- (void)activateTabWithContents:(content::WebContents*)newContents
+               previousContents:(content::WebContents*)oldContents
+                        atIndex:(NSInteger)index
+                         reason:(int)reason {
+  // The show/hide of this bubble is handled by the PermissionBubbleManager.
+  // So bypass the base class, which would close the bubble here.
 }
 
 + (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB {
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc
index b96c1ab..23f01b9 100644
--- a/chrome/browser/ui/extensions/application_launch.cc
+++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -33,13 +33,14 @@
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/renderer_preferences.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
+#include "extensions/common/features/feature.h"
+#include "extensions/common/features/feature_provider.h"
 #include "grit/generated_resources.h"
 #include "ui/base/window_open_disposition.h"
 #include "ui/gfx/rect.h"
@@ -217,7 +218,7 @@
 
   // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
   //                focus explicitly.
-  web_contents->GetView()->SetInitialFocus();
+  web_contents->SetInitialFocus();
   return web_contents;
 }
 
@@ -323,7 +324,7 @@
   UMA_HISTOGRAM_ENUMERATION(
       "Extensions.AppLaunchContainer", params.container, 100);
 
-  if (extension->is_platform_app()) {
+  if (CanLaunchViaEvent(extension)) {
     // Remember what desktop the launch happened on so that when the app opens a
     // window we can open them on the right desktop.
     PerAppSettingsServiceFactory::GetForBrowserContext(profile)->
@@ -467,3 +468,10 @@
 
   return tab;
 }
+
+bool CanLaunchViaEvent(const extensions::Extension* extension) {
+  extensions::FeatureProvider* feature_provider =
+      extensions::FeatureProvider::GetAPIFeatures();
+  extensions::Feature* feature = feature_provider->GetFeature("app.runtime");
+  return feature->IsAvailableToExtension(extension).is_available();
+}
diff --git a/chrome/browser/ui/extensions/application_launch.h b/chrome/browser/ui/extensions/application_launch.h
index fb91d7c..a5c0b44 100644
--- a/chrome/browser/ui/extensions/application_launch.h
+++ b/chrome/browser/ui/extensions/application_launch.h
@@ -96,4 +96,8 @@
 content::WebContents* OpenAppShortcutWindow(Profile* profile,
                                             const GURL& url);
 
+// Whether the extension can be launched by sending a
+// chrome.app.runtime.onLaunched event.
+bool CanLaunchViaEvent(const extensions::Extension* extension);
+
 #endif  // CHROME_BROWSER_UI_EXTENSIONS_APPLICATION_LAUNCH_H_
diff --git a/chrome/browser/ui/fast_unload_controller.h b/chrome/browser/ui/fast_unload_controller.h
index 473ae38..7a8a452 100644
--- a/chrome/browser/ui/fast_unload_controller.h
+++ b/chrome/browser/ui/fast_unload_controller.h
@@ -20,7 +20,7 @@
 
 namespace content {
 class NotificationSource;
-class NotifictaionDetails;
+class NotificationDetails;
 class WebContents;
 }
 
diff --git a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
index 3af1373..1a2ab5d 100644
--- a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
+++ b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
@@ -36,14 +36,12 @@
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/browser_test_utils.h"
 #include "net/base/filename_util.h"
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 
 #if defined(OS_WIN)
-#include "content/public/browser/web_contents_view.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #endif
@@ -431,8 +429,14 @@
                             kFwd, kIgnoreCase, NULL));
 }
 
+// http://crbug.com/369169
+#if defined(OS_CHROMEOS)
+#define MAYBE_SingleOccurrence DISABLED_SingleOccurrence
+#else
+#define MAYBE_SingleOccurrence SingleOccurrence
+#endif
 // Search Back and Forward on a single occurrence.
-IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, SingleOccurrence) {
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_SingleOccurrence) {
   WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   ui_test_utils::NavigateToURL(browser(), GetURL("FindRandomTests.html"));
@@ -1591,8 +1595,7 @@
   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
 
   // Now get the region of the plugin before the find bar is shown.
-  HWND hwnd =
-      tab->GetView()->GetNativeView()->GetHost()->GetAcceleratedWidget();
+  HWND hwnd = tab->GetNativeView()->GetHost()->GetAcceleratedWidget();
   HWND child = NULL;
   EnumChildWindows(hwnd, EnumerateChildren,reinterpret_cast<LPARAM>(&child));
 
diff --git a/chrome/browser/ui/fullscreen/fullscreen_controller.cc b/chrome/browser/ui/fullscreen/fullscreen_controller.cc
index a99b0e3..53d83b1 100644
--- a/chrome/browser/ui/fullscreen/fullscreen_controller.cc
+++ b/chrome/browser/ui/fullscreen/fullscreen_controller.cc
@@ -27,7 +27,6 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/common/extension.h"
 
 #if defined(OS_MACOSX)
diff --git a/chrome/browser/ui/fullscreen/fullscreen_controller_state_unittest.cc b/chrome/browser/ui/fullscreen/fullscreen_controller_state_unittest.cc
index d7dd1cb..e065327 100644
--- a/chrome/browser/ui/fullscreen/fullscreen_controller_state_unittest.cc
+++ b/chrome/browser/ui/fullscreen/fullscreen_controller_state_unittest.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/url_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -525,7 +524,7 @@
   // TODO(miu): Need to make an adjustment to content::WebContentsViewMac for
   // the following to work:
 #if !defined(OS_MACOSX)
-  EXPECT_EQ(kCaptureSize, first_tab->GetView()->GetViewBounds().size());
+  EXPECT_EQ(kCaptureSize, first_tab->GetViewBounds().size());
 #endif
 
   // Switch back to the first tab and exit fullscreen.
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
index 74368aa..b56ddf3 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
+++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
@@ -1381,7 +1381,7 @@
 void Gtk2UI::OnStyleSet(GtkWidget* widget, GtkStyle* previous_style) {
   ClearAllThemeData();
   LoadGtkValues();
-  NativeThemeGtk2::instance()->NotifyNativeThemeObservers();
+  NativeThemeGtk2::instance()->NotifyObservers();
 }
 
 }  // namespace libgtk2ui
diff --git a/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp b/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp
index ea611e2..c804602 100644
--- a/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp
+++ b/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp
@@ -88,6 +88,13 @@
             'gconf_listener.h',
           ],
         }],
+        [ 'clang==1', {
+          # G_DEFINE_TYPE automatically generates a *get_instance_private inline function after glib 2.37.
+          # That's unused. Prevent to complain about it.
+          'cflags': [
+            '-Wno-unused-function',
+          ],
+        }],
       ],
     },
   ],
diff --git a/chrome/browser/ui/libgtk2ui/native_theme_gtk2.cc b/chrome/browser/ui/libgtk2ui/native_theme_gtk2.cc
index 2088824..8fa8f14 100644
--- a/chrome/browser/ui/libgtk2ui/native_theme_gtk2.cc
+++ b/chrome/browser/ui/libgtk2ui/native_theme_gtk2.cc
@@ -171,10 +171,6 @@
   canvas->drawRect(gfx::RectToSkRect(rect), paint);
 }
 
-void NativeThemeGtk2::NotifyNativeThemeObservers() {
-  NotifyObservers();
-}
-
 GdkColor NativeThemeGtk2::GetSystemGdkColor(ColorId color_id) const {
   switch (color_id) {
     // Windows
diff --git a/chrome/browser/ui/libgtk2ui/native_theme_gtk2.h b/chrome/browser/ui/libgtk2ui/native_theme_gtk2.h
index c9268c6..0eac692 100644
--- a/chrome/browser/ui/libgtk2ui/native_theme_gtk2.h
+++ b/chrome/browser/ui/libgtk2ui/native_theme_gtk2.h
@@ -33,9 +33,6 @@
       const gfx::Rect& rect,
       const MenuListExtraParams& menu_list) const OVERRIDE;
 
-  // A public helper to notify observers of native theme changes.
-  void NotifyNativeThemeObservers();
-
  private:
   NativeThemeGtk2();
   virtual ~NativeThemeGtk2();
diff --git a/chrome/browser/ui/metro_pin_tab_helper_win.cc b/chrome/browser/ui/metro_pin_tab_helper_win.cc
index 311acbb..bb334e2 100644
--- a/chrome/browser/ui/metro_pin_tab_helper_win.cc
+++ b/chrome/browser/ui/metro_pin_tab_helper_win.cc
@@ -419,7 +419,6 @@
 }
 
 void MetroPinTabHelper::DidUpdateFaviconURL(
-    int32 page_id,
     const std::vector<content::FaviconURL>& candidates) {
   favicon_url_candidates_ = candidates;
 }
diff --git a/chrome/browser/ui/metro_pin_tab_helper_win.h b/chrome/browser/ui/metro_pin_tab_helper_win.h
index 91f05fc..cbbbdaa 100644
--- a/chrome/browser/ui/metro_pin_tab_helper_win.h
+++ b/chrome/browser/ui/metro_pin_tab_helper_win.h
@@ -33,7 +33,6 @@
       const content::LoadCommittedDetails& details,
       const content::FrameNavigateParams& params) OVERRIDE;
   virtual void DidUpdateFaviconURL(
-      int32 page_id,
       const std::vector<content::FaviconURL>& candidates) OVERRIDE;
 
  private:
diff --git a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
index 5800fcf..345a9e8 100644
--- a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
+++ b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
@@ -19,7 +19,6 @@
 #include "chrome/browser/ui/search/search_tab_helper.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/base/window_open_disposition.h"
 #include "url/gurl.h"
 
@@ -101,8 +100,7 @@
 void OmniboxCurrentPageDelegateImpl::DoPrerender(
     const AutocompleteMatch& match) {
   content::WebContents* web_contents = controller_->GetWebContents();
-  gfx::Rect container_bounds;
-  web_contents->GetView()->GetContainerBounds(&container_bounds);
+  gfx::Rect container_bounds = web_contents->GetContainerBounds();
 
   InstantSearchPrerenderer* prerenderer =
       InstantSearchPrerenderer::GetForProfile(profile_);
diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.cc b/chrome/browser/ui/omnibox/omnibox_edit_model.cc
index bc17cfd..1d81416 100644
--- a/chrome/browser/ui/omnibox/omnibox_edit_model.cc
+++ b/chrome/browser/ui/omnibox/omnibox_edit_model.cc
@@ -103,7 +103,7 @@
 
 // Histogram name which counts the number of milliseconds a user takes
 // between focusing and opening an omnibox match.
-const char kFocusToOpenTimeHistogram[] = "Omnibox.FocusToOpenTime";
+const char kFocusToOpenTimeHistogram[] = "Omnibox.FocusToOpenTimeAnyPopupState";
 
 // Split the percentage match histograms into buckets based on the width of the
 // omnibox.
@@ -481,10 +481,10 @@
   // entire host, and the user hasn't edited the host or manually removed the
   // scheme.
   GURL perm_url(PermanentURL());
-  if (perm_url.SchemeIs(content::kHttpScheme) &&
-      url->SchemeIs(content::kHttpScheme) && perm_url.host() == url->host()) {
+  if (perm_url.SchemeIs(url::kHttpScheme) &&
+      url->SchemeIs(url::kHttpScheme) && perm_url.host() == url->host()) {
     *write_url = true;
-    base::string16 http = base::ASCIIToUTF16(content::kHttpScheme) +
+    base::string16 http = base::ASCIIToUTF16(url::kHttpScheme) +
         base::ASCIIToUTF16(content::kStandardSchemeSeparator);
     if (text->compare(0, http.length(), http) != 0)
       *text = http + *text;
@@ -712,63 +712,66 @@
               input_text, alternate_nav_url,
               AutocompleteInput::HasHTTPScheme(input_text))));
 
-  // We only care about cases where there is a selection (i.e. the popup is
-  // open).
-  if (popup_model()->IsOpen()) {
-    base::TimeDelta elapsed_time_since_last_change_to_default_match(
-        now - autocomplete_controller()->last_time_default_match_changed());
-    // These elapsed times don't really make sense for ZeroSuggest matches
-    // (because the user does not modify the omnibox for ZeroSuggest), so for
-    // those we set the elapsed times to something that will be ignored by
-    // metrics_log.cc.
-    if (match.provider &&
-        (match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST)) {
-      elapsed_time_since_user_first_modified_omnibox =
-          base::TimeDelta::FromMilliseconds(-1);
-      elapsed_time_since_last_change_to_default_match =
-          base::TimeDelta::FromMilliseconds(-1);
-    }
-    DCHECK_NE(OmniboxPopupModel::kNoMatch, index);
-    OmniboxLog log(
-        input_text,
-        just_deleted_text_,
-        input_.type(),
-        index,
-        -1,  // don't yet know tab ID; set later if appropriate
-        ClassifyPage(),
-        elapsed_time_since_user_first_modified_omnibox,
-        match.inline_autocompletion.length(),
-        elapsed_time_since_last_change_to_default_match,
-        result());
-
-    DCHECK(user_input_in_progress_ || (match.provider &&
-           (match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST)))
-        << "We didn't get here through the expected series of calls. "
-        << "time_user_first_modified_omnibox_ is not set correctly and other "
-        << "things may be wrong. Match provider: "
-        << (match.provider ? match.provider->GetName() : "NULL");
-    DCHECK(log.elapsed_time_since_user_first_modified_omnibox >=
-           log.elapsed_time_since_last_change_to_default_match)
-        << "We should've got the notification that the user modified the "
-        << "omnibox text at same time or before the most recent time the "
-        << "default match changed.";
-
-    if ((disposition == CURRENT_TAB) && delegate_->CurrentPageExists()) {
-      // If we know the destination is being opened in the current tab,
-      // we can easily get the tab ID.  (If it's being opened in a new
-      // tab, we don't know the tab ID yet.)
-      log.tab_id = delegate_->GetSessionID().id();
-    }
-    autocomplete_controller()->AddProvidersInfo(&log.providers_info);
-    content::NotificationService::current()->Notify(
-        chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
-        content::Source<Profile>(profile_),
-        content::Details<OmniboxLog>(&log));
-    HISTOGRAM_ENUMERATION("Omnibox.EventCount", 1, 2);
-    DCHECK(!last_omnibox_focus_.is_null())
-        << "An omnibox focus should have occurred before opening a match.";
-    UMA_HISTOGRAM_TIMES(kFocusToOpenTimeHistogram, now - last_omnibox_focus_);
+  base::TimeDelta elapsed_time_since_last_change_to_default_match(
+      now - autocomplete_controller()->last_time_default_match_changed());
+  // These elapsed times don't really make sense for ZeroSuggest matches
+  // (because the user does not modify the omnibox for ZeroSuggest), so for
+  // those we set the elapsed times to something that will be ignored by
+  // metrics_log.cc.  They also don't necessarily make sense if the omnibox
+  // dropdown is closed or the user used a paste-and-go action.  (In most
+  // cases when this happens, the user never modified the omnibox.)
+  if ((match.provider &&
+       (match.provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST)) ||
+      !popup_model()->IsOpen() || !pasted_text.empty()) {
+    const base::TimeDelta default_time_delta =
+        base::TimeDelta::FromMilliseconds(-1);
+    elapsed_time_since_user_first_modified_omnibox = default_time_delta;
+    elapsed_time_since_last_change_to_default_match = default_time_delta;
   }
+  // If the popup is closed or this is a paste-and-go action (meaning the
+  // contents of the dropdown are ignored regardless), we record for logging
+  // purposes a selected_index of 0 and a suggestion list as having a single
+  // entry of the match used.
+  ACMatches fake_single_entry_matches;
+  fake_single_entry_matches.push_back(match);
+  AutocompleteResult fake_single_entry_result;
+  fake_single_entry_result.AppendMatches(fake_single_entry_matches);
+  OmniboxLog log(
+      input_text,
+      just_deleted_text_,
+      input_.type(),
+      popup_model()->IsOpen(),
+      (!popup_model()->IsOpen() || !pasted_text.empty()) ? 0 : index,
+      !pasted_text.empty(),
+      -1,  // don't yet know tab ID; set later if appropriate
+      ClassifyPage(),
+      elapsed_time_since_user_first_modified_omnibox,
+      match.inline_autocompletion.length(),
+      elapsed_time_since_last_change_to_default_match,
+      (!popup_model()->IsOpen() || !pasted_text.empty()) ?
+          fake_single_entry_result : result());
+  DCHECK(!popup_model()->IsOpen() || !pasted_text.empty() ||
+         (log.elapsed_time_since_user_first_modified_omnibox >=
+          log.elapsed_time_since_last_change_to_default_match))
+      << "We should've got the notification that the user modified the "
+      << "omnibox text at same time or before the most recent time the "
+      << "default match changed.";
+
+  if ((disposition == CURRENT_TAB) && delegate_->CurrentPageExists()) {
+    // If we know the destination is being opened in the current tab,
+    // we can easily get the tab ID.  (If it's being opened in a new
+    // tab, we don't know the tab ID yet.)
+    log.tab_id = delegate_->GetSessionID().id();
+  }
+  autocomplete_controller()->AddProvidersInfo(&log.providers_info);
+  content::NotificationService::current()->Notify(
+      chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
+      content::Source<Profile>(profile_),
+      content::Details<OmniboxLog>(&log));
+  HISTOGRAM_ENUMERATION("Omnibox.EventCount", 1, 2);
+  DCHECK(!last_omnibox_focus_.is_null())
+      << "An omnibox focus should have occurred before opening a match.";
+  UMA_HISTOGRAM_TIMES(kFocusToOpenTimeHistogram, now - last_omnibox_focus_);
 
   TemplateURL* template_url = match.GetTemplateURL(profile_, false);
   if (template_url) {
diff --git a/chrome/browser/ui/omnibox/omnibox_navigation_observer.cc b/chrome/browser/ui/omnibox/omnibox_navigation_observer.cc
index 9e5a44a..51a19b7 100644
--- a/chrome/browser/ui/omnibox/omnibox_navigation_observer.cc
+++ b/chrome/browser/ui/omnibox/omnibox_navigation_observer.cc
@@ -108,8 +108,7 @@
     OnAllLoadingFinished();  // deletes |this|!
 }
 
-void OmniboxNavigationObserver::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void OmniboxNavigationObserver::WebContentsDestroyed() {
   delete this;
 }
 
diff --git a/chrome/browser/ui/omnibox/omnibox_navigation_observer.h b/chrome/browser/ui/omnibox/omnibox_navigation_observer.h
index 8253173..0b80411 100644
--- a/chrome/browser/ui/omnibox/omnibox_navigation_observer.h
+++ b/chrome/browser/ui/omnibox/omnibox_navigation_observer.h
@@ -82,8 +82,7 @@
       content::NavigationController::ReloadType reload_type) OVERRIDE;
   virtual void NavigationEntryCommitted(
       const content::LoadCommittedDetails& load_details) OVERRIDE;
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // net::URLFetcherDelegate:
   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
index 64dbaa2..2250313 100644
--- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
+++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/autocomplete/autocomplete_match.h"
 #include "chrome/browser/autocomplete/history_quick_provider.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
@@ -36,6 +35,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "net/dns/mock_host_resolver.h"
@@ -241,13 +241,6 @@
     ui_test_utils::WaitForTemplateURLServiceToLoad(model);
 
     ASSERT_TRUE(model->loaded());
-    // Remove built-in template urls, like google.com, bing.com etc., as they
-    // may appear as autocomplete suggests and interfere with our tests.
-    model->SetUserSelectedDefaultSearchProvider(NULL);
-    TemplateURLService::TemplateURLVector builtins = model->GetTemplateURLs();
-    for (TemplateURLService::TemplateURLVector::const_iterator
-         i = builtins.begin(); i != builtins.end(); ++i)
-      model->Remove(*i);
 
     TemplateURLData data;
     data.short_name = ASCIIToUTF16(kSearchShortName);
@@ -259,6 +252,16 @@
 
     data.SetKeyword(ASCIIToUTF16(kSearchKeyword2));
     model->Add(new TemplateURL(profile, data));
+
+    // Remove built-in template urls, like google.com, bing.com etc., as they
+    // may appear as autocomplete suggests and interfere with our tests.
+    TemplateURLService::TemplateURLVector urls = model->GetTemplateURLs();
+    for (TemplateURLService::TemplateURLVector::const_iterator i = urls.begin();
+         i != urls.end();
+         ++i) {
+      if ((*i)->prepopulate_id() != 0)
+        model->Remove(*i);
+    }
   }
 
   void AddHistoryEntry(const TestHistoryEntry& entry, const Time& time) {
diff --git a/chrome/browser/ui/panels/panel_host.cc b/chrome/browser/ui/panels/panel_host.cc
index 9d8bbd3..670ae73 100644
--- a/chrome/browser/ui/panels/panel_host.cc
+++ b/chrome/browser/ui/panels/panel_host.cc
@@ -208,7 +208,7 @@
   CloseContents(web_contents_.get());
 }
 
-void PanelHost::WebContentsDestroyed(content::WebContents* web_contents) {
+void PanelHost::WebContentsDestroyed() {
   // Web contents should only be destroyed by us.
   CHECK(!web_contents_.get());
 
diff --git a/chrome/browser/ui/panels/panel_host.h b/chrome/browser/ui/panels/panel_host.h
index 217d228..3277c3b 100644
--- a/chrome/browser/ui/panels/panel_host.h
+++ b/chrome/browser/ui/panels/panel_host.h
@@ -80,8 +80,7 @@
   virtual void RenderViewCreated(
       content::RenderViewHost* render_view_host) OVERRIDE;
   virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
 
   // extensions::ExtensionFunctionDispatcher::Delegate overrides.
diff --git a/chrome/browser/ui/panels/test_panel_notification_observer.h b/chrome/browser/ui/panels/test_panel_notification_observer.h
index 564b52a..92b0915 100644
--- a/chrome/browser/ui/panels/test_panel_notification_observer.h
+++ b/chrome/browser/ui/panels/test_panel_notification_observer.h
@@ -11,7 +11,7 @@
 
 namespace content {
 class MessageLoopRunner;
-class NotificaitonSource;
+class NotificationSource;
 }
 
 // Common base class for a custom notification observer that waits
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble.h b/chrome/browser/ui/passwords/manage_passwords_bubble.h
index f759ea9..1d60766 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble.h
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble.h
@@ -30,6 +30,7 @@
   ~ManagePasswordsBubble();
 
   ManagePasswordsBubbleModel* model() { return model_.get(); }
+  const ManagePasswordsBubbleModel* model() const { return model_.get(); }
 
  private:
   scoped_ptr<ManagePasswordsBubbleModel> model_;
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
index 687dca2..6eca416 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
@@ -7,35 +7,35 @@
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h"
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "components/password_manager/core/browser/password_store.h"
+#include "components/password_manager/core/common/password_manager_ui.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
-using content::WebContents;
 using autofill::PasswordFormMap;
+using content::WebContents;
 
 ManagePasswordsBubbleModel::ManagePasswordsBubbleModel(
     content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
-      web_contents_(web_contents),
       display_disposition_(
           password_manager::metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING),
       dismissal_reason_(password_manager::metrics_util::NOT_DISPLAYED) {
-  ManagePasswordsBubbleUIController* manage_passwords_bubble_ui_controller =
-      ManagePasswordsBubbleUIController::FromWebContents(web_contents_);
+  ManagePasswordsUIController* controller =
+      ManagePasswordsUIController::FromWebContents(web_contents);
 
-  if (manage_passwords_bubble_ui_controller->password_to_be_saved())
-    manage_passwords_bubble_state_ = PASSWORD_TO_BE_SAVED;
-  else
-    manage_passwords_bubble_state_ = MANAGE_PASSWORDS;
+  // TODO(mkwst): Reverse this logic. The controller should populate the model
+  // directly rather than the model pulling from the controller. Perhaps like
+  // `controller->PopulateModel(this)`.
+  state_ = controller->state();
+  if (password_manager::ui::IsPendingState(state_))
+    pending_credentials_ = controller->PendingCredentials();
+  best_matches_ = controller->best_matches();
 
   title_ = l10n_util::GetStringUTF16(
-      (manage_passwords_bubble_state_ == PASSWORD_TO_BE_SAVED) ?
-          IDS_SAVE_PASSWORD : IDS_MANAGE_PASSWORDS);
-  pending_credentials_ =
-      manage_passwords_bubble_ui_controller->PendingCredentials();
-  best_matches_ = manage_passwords_bubble_ui_controller->best_matches();
+      password_manager::ui::IsPendingState(state_) ? IDS_SAVE_PASSWORD
+                                                   : IDS_MANAGE_PASSWORDS);
   manage_link_ =
       l10n_util::GetStringUTF16(IDS_OPTIONS_PASSWORDS_MANAGE_PASSWORDS_LINK);
 }
@@ -44,19 +44,18 @@
 
 void ManagePasswordsBubbleModel::OnBubbleShown(
     ManagePasswordsBubble::DisplayReason reason) {
-  DCHECK(WaitingToSavePassword() ||
-         reason == ManagePasswordsBubble::USER_ACTION);
   if (reason == ManagePasswordsBubble::USER_ACTION) {
-    if (WaitingToSavePassword()) {
+    if (password_manager::ui::IsPendingState(state_)) {
       display_disposition_ =
           password_manager::metrics_util::MANUAL_WITH_PASSWORD_PENDING;
+    } else if (state_ == password_manager::ui::BLACKLIST_STATE) {
+      display_disposition_ = password_manager::metrics_util::MANUAL_BLACKLISTED;
     } else {
-      // TODO(mkwst): Deal with "Never save passwords" once we've decided how
-      // that flow should work.
       display_disposition_ =
           password_manager::metrics_util::MANUAL_MANAGE_PASSWORDS;
     }
   } else {
+    DCHECK(password_manager::ui::IsPendingState(state_));
     display_disposition_ =
         password_manager::metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING;
   }
@@ -75,31 +74,33 @@
   password_manager::metrics_util::LogUIDismissalReason(dismissal_reason_);
 }
 
-void ManagePasswordsBubbleModel::OnCloseWithoutLogging() {
-  dismissal_reason_ = password_manager::metrics_util::NOT_DISPLAYED;
-}
-
 void ManagePasswordsBubbleModel::OnNopeClicked() {
   dismissal_reason_ = password_manager::metrics_util::CLICKED_NOPE;
-  manage_passwords_bubble_state_ = PASSWORD_TO_BE_SAVED;
+  state_ = password_manager::ui::PENDING_PASSWORD_STATE;
 }
 
 void ManagePasswordsBubbleModel::OnNeverForThisSiteClicked() {
   dismissal_reason_ = password_manager::metrics_util::CLICKED_NEVER;
-  ManagePasswordsBubbleUIController* manage_passwords_bubble_ui_controller =
-      ManagePasswordsBubbleUIController::FromWebContents(web_contents_);
-  manage_passwords_bubble_ui_controller->NeverSavePassword();
-  manage_passwords_bubble_ui_controller->unset_password_to_be_saved();
-  manage_passwords_bubble_state_ = NEVER_SAVE_PASSWORDS;
+  ManagePasswordsUIController* manage_passwords_ui_controller =
+      ManagePasswordsUIController::FromWebContents(web_contents());
+  manage_passwords_ui_controller->NeverSavePassword();
+  state_ = password_manager::ui::BLACKLIST_STATE;
+}
+
+void ManagePasswordsBubbleModel::OnUnblacklistClicked() {
+  dismissal_reason_ = password_manager::metrics_util::CLICKED_UNBLACKLIST;
+  ManagePasswordsUIController* manage_passwords_ui_controller =
+      ManagePasswordsUIController::FromWebContents(web_contents());
+  manage_passwords_ui_controller->UnblacklistSite();
+  state_ = password_manager::ui::MANAGE_STATE;
 }
 
 void ManagePasswordsBubbleModel::OnSaveClicked() {
   dismissal_reason_ = password_manager::metrics_util::CLICKED_SAVE;
-  ManagePasswordsBubbleUIController* manage_passwords_bubble_ui_controller =
-      ManagePasswordsBubbleUIController::FromWebContents(web_contents_);
-  manage_passwords_bubble_ui_controller->SavePassword();
-  manage_passwords_bubble_ui_controller->unset_password_to_be_saved();
-  manage_passwords_bubble_state_ = MANAGE_PASSWORDS;
+  ManagePasswordsUIController* manage_passwords_ui_controller =
+      ManagePasswordsUIController::FromWebContents(web_contents());
+  manage_passwords_ui_controller->SavePassword();
+  state_ = password_manager::ui::MANAGE_STATE;
 }
 
 void ManagePasswordsBubbleModel::OnDoneClicked() {
@@ -108,17 +109,17 @@
 
 void ManagePasswordsBubbleModel::OnManageLinkClicked() {
   dismissal_reason_ = password_manager::metrics_util::CLICKED_MANAGE;
-  ManagePasswordsBubbleUIController::FromWebContents(web_contents_)
+  ManagePasswordsUIController::FromWebContents(web_contents())
       ->NavigateToPasswordManagerSettingsPage();
 }
 
 void ManagePasswordsBubbleModel::OnPasswordAction(
     const autofill::PasswordForm& password_form,
     PasswordAction action) {
-  if (!web_contents_)
+  if (!web_contents())
     return;
   Profile* profile =
-      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
+      Profile::FromBrowserContext(web_contents()->GetBrowserContext());
   password_manager::PasswordStore* password_store =
       PasswordStoreFactory::GetForProfile(profile, Profile::EXPLICIT_ACCESS)
           .get();
@@ -128,9 +129,3 @@
   else
     password_store->AddLogin(password_form);
 }
-
-void ManagePasswordsBubbleModel::WebContentsDestroyed(
-    content::WebContents* web_contents) {
-  // The WebContents have been destroyed.
-  web_contents_ = NULL;
-}
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.h b/chrome/browser/ui/passwords/manage_passwords_bubble_model.h
index d2c3718..e6ae6aa 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.h
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.h
@@ -8,6 +8,7 @@
 #include "chrome/browser/ui/passwords/manage_passwords_bubble.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
+#include "components/password_manager/core/common/password_manager_ui.h"
 #include "content/public/browser/web_contents_observer.h"
 
 class ManagePasswordsIconController;
@@ -20,18 +21,12 @@
 // password management actions.
 class ManagePasswordsBubbleModel : public content::WebContentsObserver {
  public:
-  enum ManagePasswordsBubbleState {
-    PASSWORD_TO_BE_SAVED,
-    MANAGE_PASSWORDS,
-    NEVER_SAVE_PASSWORDS,
-  };
-
   enum PasswordAction { REMOVE_PASSWORD, ADD_PASSWORD };
 
   // Creates a ManagePasswordsBubbleModel, which holds a raw pointer to the
   // WebContents in which it lives. Defaults to a display disposition of
   // AUTOMATIC_WITH_PASSWORD_PENDING, and a dismissal reason of NOT_DISPLAYED.
-  // The bubble's state is updated from the ManagePasswordsBubbleUIController
+  // The bubble's state is updated from the ManagePasswordsUIController
   // associated with |web_contents| upon creation.
   explicit ManagePasswordsBubbleModel(content::WebContents* web_contents);
   virtual ~ManagePasswordsBubbleModel();
@@ -49,6 +44,9 @@
   // by the user.
   void OnNeverForThisSiteClicked();
 
+  // Called by the view code when the site is unblacklisted.
+  void OnUnblacklistClicked();
+
   // Called by the view code when the save button in clicked by the user.
   void OnSaveClicked();
 
@@ -63,48 +61,35 @@
   void OnPasswordAction(const autofill::PasswordForm& password_form,
                         PasswordAction action);
 
-  // Called by the view code when the bubble is closed without ever displaying
-  // content to the user. We shouldn't log to UMA in this case.
-  void OnCloseWithoutLogging();
+  password_manager::ui::State state() const { return state_; }
 
-  ManagePasswordsBubbleState manage_passwords_bubble_state() {
-    return manage_passwords_bubble_state_;
-  }
-
-  bool WaitingToSavePassword() {
-    return manage_passwords_bubble_state() == PASSWORD_TO_BE_SAVED;
-  }
-
-  const base::string16& title() { return title_; }
-  const autofill::PasswordForm& pending_credentials() {
+  const base::string16& title() const { return title_; }
+  const autofill::PasswordForm& pending_credentials() const {
     return pending_credentials_;
   }
-  const autofill::PasswordFormMap& best_matches() { return best_matches_; }
-  const base::string16& manage_link() { return manage_link_; }
+  const autofill::PasswordFormMap& best_matches() const {
+    return best_matches_;
+  }
+  const base::string16& manage_link() const { return manage_link_; }
 
-  // Gets and sets the reason the bubble was displayed; exposed for testing.
+#if defined(UNIT_TEST)
+  // Gets and sets the reason the bubble was displayed.
   password_manager::metrics_util::UIDisplayDisposition display_disposition()
       const {
     return display_disposition_;
   }
 
-  // Gets the reason the bubble was dismissed; exposed for testing.
+  // Gets the reason the bubble was dismissed.
   password_manager::metrics_util::UIDismissalReason dismissal_reason() const {
     return dismissal_reason_;
   }
 
-  // State setter; exposed for testing.
-  void set_manage_passwords_bubble_state(ManagePasswordsBubbleState state) {
-    manage_passwords_bubble_state_ = state;
-  }
+  // State setter.
+  void set_state(password_manager::ui::State state) { state_ = state; }
+#endif
 
  private:
-  // content::WebContentsObserver
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
-
-  content::WebContents* web_contents_;
-  ManagePasswordsBubbleState manage_passwords_bubble_state_;
+  password_manager::ui::State state_;
   base::string16 title_;
   autofill::PasswordForm pending_credentials_;
   autofill::PasswordFormMap best_matches_;
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
index 2ee54d6..247ca72 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
@@ -4,12 +4,14 @@
 
 #include "base/metrics/histogram_samples.h"
 #include "base/prefs/pref_service.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/test/statistics_delta_reader.h"
 #include "chrome/browser/ui/passwords/manage_passwords_bubble.h"
 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
-#include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_mock.h"
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
+#include "components/password_manager/core/common/password_manager_ui.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/web_contents_tester.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -26,7 +28,7 @@
   virtual void SetUp() OVERRIDE {
     // Create the test UIController here so that it's bound to
     // |test_web_contents_| and therefore accessible to the model.
-    new ManagePasswordsBubbleUIControllerMock(test_web_contents_.get());
+    new ManagePasswordsUIControllerMock(test_web_contents_.get());
 
     model_.reset(new ManagePasswordsBubbleModel(test_web_contents_.get()));
   }
@@ -34,25 +36,38 @@
   virtual void TearDown() OVERRIDE { model_.reset(); }
 
   void PretendPasswordWaiting() {
-    model_->set_manage_passwords_bubble_state(
-        ManagePasswordsBubbleModel::PASSWORD_TO_BE_SAVED);
+    model_->set_state(password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE);
     model_->OnBubbleShown(ManagePasswordsBubble::AUTOMATIC);
+    controller()->SetState(
+        password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE);
   }
 
   void PretendManagingPasswords() {
-    model_->set_manage_passwords_bubble_state(
-        ManagePasswordsBubbleModel::MANAGE_PASSWORDS);
+    model_->set_state(password_manager::ui::MANAGE_STATE);
     model_->OnBubbleShown(ManagePasswordsBubble::USER_ACTION);
+    controller()->SetState(password_manager::ui::MANAGE_STATE);
   }
 
-  ManagePasswordsBubbleUIControllerMock* controller() {
-    return reinterpret_cast<ManagePasswordsBubbleUIControllerMock*>(
-        ManagePasswordsBubbleUIController::FromWebContents(
+  void PretendBlacklisted() {
+    model_->set_state(password_manager::ui::BLACKLIST_STATE);
+    model_->OnBubbleShown(ManagePasswordsBubble::USER_ACTION);
+
+    base::string16 kTestUsername = base::ASCIIToUTF16("test_username");
+    autofill::PasswordFormMap map;
+    map[kTestUsername] = &test_form_;
+    controller()->SetPasswordFormMap(map);
+    controller()->SetState(password_manager::ui::BLACKLIST_STATE);
+  }
+
+  ManagePasswordsUIControllerMock* controller() {
+    return static_cast<ManagePasswordsUIControllerMock*>(
+        ManagePasswordsUIController::FromWebContents(
             test_web_contents_.get()));
   }
 
  protected:
   scoped_ptr<ManagePasswordsBubbleModel> model_;
+  autofill::PasswordForm test_form_;
 
  private:
   content::TestBrowserThreadBundle thread_bundle_;
@@ -71,7 +86,6 @@
 
 TEST_F(ManagePasswordsBubbleModelTest, CloseWithoutLogging) {
   base::StatisticsDeltaReader statistics_delta_reader;
-  model_->OnCloseWithoutLogging();
   model_->OnBubbleHidden();
   EXPECT_EQ(model_->dismissal_reason(),
             password_manager::metrics_util::NOT_DISPLAYED);
@@ -90,6 +104,8 @@
   model_->OnBubbleHidden();
   EXPECT_EQ(model_->dismissal_reason(),
             password_manager::metrics_util::NO_DIRECT_INTERACTION);
+  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE,
+            model_->state());
   EXPECT_FALSE(controller()->saved_password());
   EXPECT_FALSE(controller()->never_saved_password());
 
@@ -106,6 +122,9 @@
   EXPECT_EQ(0,
             samples->GetCount(password_manager::metrics_util::CLICKED_MANAGE));
   EXPECT_EQ(0, samples->GetCount(password_manager::metrics_util::CLICKED_DONE));
+  EXPECT_EQ(
+      0,
+      samples->GetCount(password_manager::metrics_util::CLICKED_UNBLACKLIST));
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickSave) {
@@ -115,6 +134,7 @@
   model_->OnBubbleHidden();
   EXPECT_EQ(model_->dismissal_reason(),
             password_manager::metrics_util::CLICKED_SAVE);
+  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model_->state());
   EXPECT_TRUE(controller()->saved_password());
   EXPECT_FALSE(controller()->never_saved_password());
 
@@ -131,6 +151,9 @@
   EXPECT_EQ(0,
             samples->GetCount(password_manager::metrics_util::CLICKED_MANAGE));
   EXPECT_EQ(0, samples->GetCount(password_manager::metrics_util::CLICKED_DONE));
+  EXPECT_EQ(
+      0,
+      samples->GetCount(password_manager::metrics_util::CLICKED_UNBLACKLIST));
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickNope) {
@@ -140,6 +163,7 @@
   model_->OnBubbleHidden();
   EXPECT_EQ(model_->dismissal_reason(),
             password_manager::metrics_util::CLICKED_NOPE);
+  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE, model_->state());
   EXPECT_FALSE(controller()->saved_password());
   EXPECT_FALSE(controller()->never_saved_password());
 
@@ -156,6 +180,9 @@
   EXPECT_EQ(0,
             samples->GetCount(password_manager::metrics_util::CLICKED_MANAGE));
   EXPECT_EQ(0, samples->GetCount(password_manager::metrics_util::CLICKED_DONE));
+  EXPECT_EQ(
+      0,
+      samples->GetCount(password_manager::metrics_util::CLICKED_UNBLACKLIST));
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickNever) {
@@ -165,6 +192,7 @@
   model_->OnBubbleHidden();
   EXPECT_EQ(model_->dismissal_reason(),
             password_manager::metrics_util::CLICKED_NEVER);
+  EXPECT_EQ(password_manager::ui::BLACKLIST_STATE, model_->state());
   EXPECT_FALSE(controller()->saved_password());
   EXPECT_TRUE(controller()->never_saved_password());
 
@@ -181,6 +209,9 @@
   EXPECT_EQ(0,
             samples->GetCount(password_manager::metrics_util::CLICKED_MANAGE));
   EXPECT_EQ(0, samples->GetCount(password_manager::metrics_util::CLICKED_DONE));
+  EXPECT_EQ(
+      0,
+      samples->GetCount(password_manager::metrics_util::CLICKED_UNBLACKLIST));
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickManage) {
@@ -190,6 +221,7 @@
   model_->OnBubbleHidden();
   EXPECT_EQ(model_->dismissal_reason(),
             password_manager::metrics_util::CLICKED_MANAGE);
+  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model_->state());
   EXPECT_FALSE(controller()->saved_password());
   EXPECT_FALSE(controller()->never_saved_password());
 
@@ -206,6 +238,9 @@
   EXPECT_EQ(1,
             samples->GetCount(password_manager::metrics_util::CLICKED_MANAGE));
   EXPECT_EQ(0, samples->GetCount(password_manager::metrics_util::CLICKED_DONE));
+  EXPECT_EQ(
+      0,
+      samples->GetCount(password_manager::metrics_util::CLICKED_UNBLACKLIST));
 }
 
 TEST_F(ManagePasswordsBubbleModelTest, ClickDone) {
@@ -215,6 +250,7 @@
   model_->OnBubbleHidden();
   EXPECT_EQ(model_->dismissal_reason(),
             password_manager::metrics_util::CLICKED_DONE);
+  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model_->state());
   EXPECT_FALSE(controller()->saved_password());
   EXPECT_FALSE(controller()->never_saved_password());
 
@@ -231,12 +267,52 @@
   EXPECT_EQ(0,
             samples->GetCount(password_manager::metrics_util::CLICKED_MANAGE));
   EXPECT_EQ(1, samples->GetCount(password_manager::metrics_util::CLICKED_DONE));
+  EXPECT_EQ(
+      0,
+      samples->GetCount(password_manager::metrics_util::CLICKED_UNBLACKLIST));
 }
 
-TEST_F(ManagePasswordsBubbleModelTest, WaitingToSavePassword) {
-  EXPECT_FALSE(model_->WaitingToSavePassword());
+TEST_F(ManagePasswordsBubbleModelTest, ClickUnblacklist) {
+  base::StatisticsDeltaReader statistics_delta_reader;
+  PretendBlacklisted();
+  model_->OnUnblacklistClicked();
+  model_->OnBubbleHidden();
+  EXPECT_EQ(model_->dismissal_reason(),
+            password_manager::metrics_util::CLICKED_UNBLACKLIST);
+  EXPECT_EQ(password_manager::ui::MANAGE_STATE, model_->state());
+  EXPECT_FALSE(controller()->saved_password());
+  EXPECT_FALSE(controller()->never_saved_password());
 
-  model_->set_manage_passwords_bubble_state(
-      ManagePasswordsBubbleModel::PASSWORD_TO_BE_SAVED);
-  EXPECT_TRUE(model_->WaitingToSavePassword());
+  scoped_ptr<base::HistogramSamples> samples(
+      statistics_delta_reader.GetHistogramSamplesSinceCreation(
+          kUIDismissalReasonMetric));
+  EXPECT_EQ(
+      0,
+      samples->GetCount(password_manager::metrics_util::NO_DIRECT_INTERACTION));
+  EXPECT_EQ(0, samples->GetCount(password_manager::metrics_util::CLICKED_SAVE));
+  EXPECT_EQ(0, samples->GetCount(password_manager::metrics_util::CLICKED_NOPE));
+  EXPECT_EQ(0,
+            samples->GetCount(password_manager::metrics_util::CLICKED_NEVER));
+  EXPECT_EQ(0,
+            samples->GetCount(password_manager::metrics_util::CLICKED_MANAGE));
+  EXPECT_EQ(0, samples->GetCount(password_manager::metrics_util::CLICKED_DONE));
+  EXPECT_EQ(
+      1,
+      samples->GetCount(password_manager::metrics_util::CLICKED_UNBLACKLIST));
+}
+
+TEST_F(ManagePasswordsBubbleModelTest, PasswordPendingUserDecision) {
+  EXPECT_FALSE(password_manager::ui::IsPendingState(model_->state()));
+
+  model_->set_state(password_manager::ui::INACTIVE_STATE);
+  EXPECT_FALSE(password_manager::ui::IsPendingState(model_->state()));
+  model_->set_state(password_manager::ui::MANAGE_STATE);
+  EXPECT_FALSE(password_manager::ui::IsPendingState(model_->state()));
+  model_->set_state(password_manager::ui::BLACKLIST_STATE);
+  EXPECT_FALSE(password_manager::ui::IsPendingState(model_->state()));
+
+  model_->set_state(password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE);
+  EXPECT_TRUE(password_manager::ui::IsPendingState(model_->state()));
+  model_->set_state(password_manager::ui::PENDING_PASSWORD_STATE);
+  EXPECT_TRUE(password_manager::ui::IsPendingState(model_->state()));
 }
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.cc
deleted file mode 100644
index 987077b..0000000
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h"
-
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/password_manager/password_store_factory.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/chrome_pages.h"
-#include "chrome/browser/ui/omnibox/location_bar.h"
-#include "chrome/browser/ui/passwords/manage_passwords_icon.h"
-#include "chrome/common/url_constants.h"
-#include "components/password_manager/core/browser/password_store.h"
-#include "content/public/browser/notification_service.h"
-
-using autofill::PasswordFormMap;
-using password_manager::PasswordFormManager;
-
-namespace {
-
-password_manager::PasswordStore* GetPasswordStore(
-    content::WebContents* web_contents) {
-  return PasswordStoreFactory::GetForProfile(
-             Profile::FromBrowserContext(web_contents->GetBrowserContext()),
-             Profile::EXPLICIT_ACCESS).get();
-}
-
-} // namespace
-
-DEFINE_WEB_CONTENTS_USER_DATA_KEY(ManagePasswordsBubbleUIController);
-
-ManagePasswordsBubbleUIController::ManagePasswordsBubbleUIController(
-    content::WebContents* web_contents)
-    : content::WebContentsObserver(web_contents),
-      manage_passwords_icon_to_be_shown_(false),
-      password_to_be_saved_(false),
-      manage_passwords_bubble_needs_showing_(false),
-      autofill_blocked_(false) {
-  password_manager::PasswordStore* password_store =
-      GetPasswordStore(web_contents);
-  if (password_store)
-    password_store->AddObserver(this);
-}
-
-ManagePasswordsBubbleUIController::~ManagePasswordsBubbleUIController() {}
-
-void ManagePasswordsBubbleUIController::UpdateBubbleAndIconVisibility() {
-  #if !defined(OS_ANDROID)
-    Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
-    if (!browser)
-      return;
-    LocationBar* location_bar = browser->window()->GetLocationBar();
-    DCHECK(location_bar);
-    location_bar->UpdateManagePasswordsIconAndBubble();
-  #endif
-}
-
-void ManagePasswordsBubbleUIController::OnPasswordSubmitted(
-    PasswordFormManager* form_manager) {
-  form_manager_.reset(form_manager);
-  password_form_map_ = form_manager_->best_matches();
-  origin_ = PendingCredentials().origin;
-  manage_passwords_icon_to_be_shown_ = true;
-  password_to_be_saved_ = true;
-  manage_passwords_bubble_needs_showing_ = true;
-  autofill_blocked_ = false;
-  UpdateBubbleAndIconVisibility();
-}
-
-void ManagePasswordsBubbleUIController::OnPasswordAutofilled(
-    const PasswordFormMap& password_form_map) {
-  password_form_map_ = password_form_map;
-  origin_ = password_form_map_.begin()->second->origin;
-  manage_passwords_icon_to_be_shown_ = true;
-  password_to_be_saved_ = false;
-  manage_passwords_bubble_needs_showing_ = false;
-  autofill_blocked_ = false;
-  UpdateBubbleAndIconVisibility();
-}
-
-void ManagePasswordsBubbleUIController::OnBlacklistBlockedAutofill() {
-  manage_passwords_icon_to_be_shown_ = true;
-  password_to_be_saved_ = false;
-  manage_passwords_bubble_needs_showing_ = false;
-  autofill_blocked_ = true;
-  UpdateBubbleAndIconVisibility();
-}
-
-void ManagePasswordsBubbleUIController::WebContentsDestroyed(
-    content::WebContents* web_contents) {
-  password_manager::PasswordStore* password_store =
-      GetPasswordStore(web_contents);
-  if (password_store)
-    password_store->RemoveObserver(this);
-}
-
-void ManagePasswordsBubbleUIController::OnLoginsChanged(
-    const password_manager::PasswordStoreChangeList& changes) {
-  for (password_manager::PasswordStoreChangeList::const_iterator it =
-           changes.begin();
-       it != changes.end();
-       it++) {
-    const autofill::PasswordForm& changed_form = it->form();
-    if (changed_form.origin != origin_)
-      continue;
-
-    if (it->type() == password_manager::PasswordStoreChange::REMOVE) {
-      password_form_map_.erase(changed_form.username_value);
-    } else {
-      autofill::PasswordForm* new_form =
-          new autofill::PasswordForm(changed_form);
-      password_form_map_[changed_form.username_value] = new_form;
-    }
-  }
-}
-
-void ManagePasswordsBubbleUIController::
-    NavigateToPasswordManagerSettingsPage() {
-// TODO(mkwst): chrome_pages.h is compiled out of Android. Need to figure out
-// how this navigation should work there.
-#if !defined(OS_ANDROID)
-  chrome::ShowSettingsSubPage(
-      chrome::FindBrowserWithWebContents(web_contents()),
-      chrome::kPasswordManagerSubPage);
-#endif
-}
-
-void ManagePasswordsBubbleUIController::SavePassword() {
-  DCHECK(form_manager_.get());
-  form_manager_->Save();
-}
-
-void ManagePasswordsBubbleUIController::NeverSavePassword() {
-  DCHECK(form_manager_.get());
-  form_manager_->PermanentlyBlacklist();
-}
-
-void ManagePasswordsBubbleUIController::DidNavigateMainFrame(
-    const content::LoadCommittedDetails& details,
-    const content::FrameNavigateParams& params) {
-  if (details.is_in_page)
-    return;
-  // Reset password states for next page.
-  manage_passwords_icon_to_be_shown_ = false;
-  password_to_be_saved_ = false;
-  manage_passwords_bubble_needs_showing_ = false;
-  UpdateBubbleAndIconVisibility();
-}
-
-const autofill::PasswordForm& ManagePasswordsBubbleUIController::
-    PendingCredentials() const {
-  DCHECK(form_manager_);
-  return form_manager_->pending_credentials();
-}
-
-void ManagePasswordsBubbleUIController::UpdateIconAndBubbleState(
-    ManagePasswordsIcon* icon) {
-  ManagePasswordsIcon::State state = ManagePasswordsIcon::INACTIVE_STATE;
-
-  if (autofill_blocked_)
-    state = ManagePasswordsIcon::BLACKLISTED_STATE;
-  else if (password_to_be_saved_)
-    state = ManagePasswordsIcon::PENDING_STATE;
-  else if (manage_passwords_icon_to_be_shown_)
-    state = ManagePasswordsIcon::MANAGE_STATE;
-
-  icon->SetState(state);
-
-  if (manage_passwords_bubble_needs_showing_) {
-    DCHECK(state == ManagePasswordsIcon::PENDING_STATE);
-    icon->ShowBubbleWithoutUserInteraction();
-    manage_passwords_bubble_needs_showing_ = false;
-  }
-}
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h b/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h
deleted file mode 100644
index f99dca4..0000000
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_UI_CONTROLLER_H_
-#define CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_UI_CONTROLLER_H_
-
-#include "components/password_manager/core/browser/password_form_manager.h"
-#include "components/password_manager/core/browser/password_store.h"
-#include "components/password_manager/core/browser/password_store_change.h"
-#include "content/public/browser/navigation_details.h"
-#include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_user_data.h"
-
-namespace content {
-class WebContents;
-}
-
-class ManagePasswordsIcon;
-
-// Per-tab class to control the Omnibox password icon and bubble.
-class ManagePasswordsBubbleUIController
-    : public content::WebContentsObserver,
-      public content::WebContentsUserData<ManagePasswordsBubbleUIController>,
-      public password_manager::PasswordStore::Observer {
- public:
-  virtual ~ManagePasswordsBubbleUIController();
-
-  // Called when the user submits a form containing login information, so we
-  // can handle later requests to save or blacklist that login information.
-  // This stores the provided object in form_manager_ and triggers the UI to
-  // prompt the user about whether they would like to save the password.
-  void OnPasswordSubmitted(password_manager::PasswordFormManager* form_manager);
-
-  // Called when a form is autofilled with login information, so we can manage
-  // password credentials for the current site which are stored in
-  // |password_form_map|. This stores a copy of |password_form_map| and shows
-  // the manage password icon.
-  void OnPasswordAutofilled(const autofill::PasswordFormMap& password_form_map);
-
-  // Called when a form is _not_ autofilled due to user blacklisting.
-  void OnBlacklistBlockedAutofill();
-
-  // PasswordStore::Observer implementation.
-  virtual void OnLoginsChanged(
-      const password_manager::PasswordStoreChangeList& changes) OVERRIDE;
-
-  // Called from the model when the user chooses to save a password; passes the
-  // action off to the FormManager.
-  virtual void SavePassword();
-
-  // Called from the model when the user chooses to never save passwords; passes
-  // the action off to the FormManager.
-  virtual void NeverSavePassword();
-
-  // Open a new tab, pointing to the password manager settings page.
-  virtual void NavigateToPasswordManagerSettingsPage();
-
-  virtual const autofill::PasswordForm& PendingCredentials() const;
-
-  // Set the state of the Omnibox icon, and possibly show the associated bubble
-  // without user interaction.
-  virtual void UpdateIconAndBubbleState(ManagePasswordsIcon* icon);
-
-  bool manage_passwords_icon_to_be_shown() const {
-    return manage_passwords_icon_to_be_shown_;
-  }
-
-  bool password_to_be_saved() const {
-    return password_to_be_saved_;
-  }
-
-  bool manage_passwords_bubble_needs_showing() const {
-    return manage_passwords_bubble_needs_showing_;
-  }
-
-  void unset_password_to_be_saved() {
-    password_to_be_saved_ = false;
-  }
-
-  const autofill::PasswordFormMap best_matches() const {
-    return password_form_map_;
-  }
-
-  bool autofill_blocked() const { return autofill_blocked_; }
-  void set_autofill_blocked(bool autofill_blocked) {
-    autofill_blocked_ = autofill_blocked;
-  }
-
-  const GURL& origin() const { return origin_; }
-
- protected:
-  explicit ManagePasswordsBubbleUIController(
-      content::WebContents* web_contents);
-
- private:
-  friend class content::WebContentsUserData<ManagePasswordsBubbleUIController>;
-
-  // Called when a passwordform is autofilled, when a new passwordform is
-  // submitted, or when a navigation occurs to update the visibility of the
-  // manage passwords icon and bubble.
-  void UpdateBubbleAndIconVisibility();
-
-  // content::WebContentsObserver:
-  virtual void DidNavigateMainFrame(
-      const content::LoadCommittedDetails& details,
-      const content::FrameNavigateParams& params) OVERRIDE;
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
-
-  // Set by OnPasswordSubmitted() when the user submits a form containing login
-  // information.  If the user responds to a subsequent "Do you want to save
-  // this password?" prompt, we ask this object to save or blacklist the
-  // associated login information in Chrome's password store.
-  scoped_ptr<password_manager::PasswordFormManager> form_manager_;
-
-  // All previously stored credentials for a specific site.  Set by
-  // OnPasswordSubmitted() or OnPasswordAutofilled().
-  autofill::PasswordFormMap password_form_map_;
-
-  bool manage_passwords_icon_to_be_shown_;
-  bool password_to_be_saved_;
-  bool manage_passwords_bubble_needs_showing_;
-
-  // Stores whether autofill was blocked due to a user's decision to blacklist
-  // the current site ("Never save passwords for this site").
-  bool autofill_blocked_;
-
-  // The origin of the form we're currently dealing with; we'll use this to
-  // determine which PasswordStore changes we should care about when updating
-  // |password_form_map_|.
-  GURL origin_;
-
-  DISALLOW_COPY_AND_ASSIGN(ManagePasswordsBubbleUIController);
-};
-
-#endif  // CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_UI_CONTROLLER_H_
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_mock.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_mock.cc
deleted file mode 100644
index 6ea3414..0000000
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_mock.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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.
-
-#include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_mock.h"
-
-#include "content/public/browser/web_contents.h"
-
-ManagePasswordsBubbleUIControllerMock::ManagePasswordsBubbleUIControllerMock(
-    content::WebContents* contents)
-    : ManagePasswordsBubbleUIController(contents),
-      navigated_to_settings_page_(false),
-      saved_password_(false),
-      never_saved_password_(false) {
-  contents->SetUserData(UserDataKey(), this);
-}
-
-ManagePasswordsBubbleUIControllerMock::
-    ~ManagePasswordsBubbleUIControllerMock() {}
-
-void ManagePasswordsBubbleUIControllerMock::
-    NavigateToPasswordManagerSettingsPage() {
-  navigated_to_settings_page_ = true;
-}
-
-const autofill::PasswordForm&
-    ManagePasswordsBubbleUIControllerMock::PendingCredentials() const {
-  return pending_credentials_;
-}
-
-bool ManagePasswordsBubbleUIControllerMock::IsInstalled() const {
-  return web_contents()->GetUserData(UserDataKey()) == this;
-}
-
-void ManagePasswordsBubbleUIControllerMock::SavePassword() {
-  saved_password_ = true;
-}
-
-void ManagePasswordsBubbleUIControllerMock::NeverSavePassword() {
-  never_saved_password_ = true;
-}
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_mock.h b/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_mock.h
deleted file mode 100644
index 857fa15..0000000
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_mock.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_UI_CONTROLLER_MOCK_H_
-#define CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_UI_CONTROLLER_MOCK_H_
-
-#include "base/basictypes.h"
-#include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h"
-
-namespace content {
-class WebContents;
-}  // namespace content
-
-// This mock is used in tests to ensure that we're just testing the controller
-// behavior, and not the behavior of the bits and pieces it relies upon (like
-// FormManager).
-class ManagePasswordsBubbleUIControllerMock
-    : public ManagePasswordsBubbleUIController {
- public:
-  explicit ManagePasswordsBubbleUIControllerMock(
-      content::WebContents* contents);
-  virtual ~ManagePasswordsBubbleUIControllerMock();
-
-  // Navigation, surprisingly, is platform-specific; Android's settings page
-  // is native UI and therefore isn't available in a tab for unit tests.
-  //
-  // TODO(mkwst): Determine how to reasonably test this on that platform.
-  virtual void NavigateToPasswordManagerSettingsPage() OVERRIDE;
-  bool navigated_to_settings_page() const {
-    return navigated_to_settings_page_;
-  }
-
-  // We don't have a FormManager in tests, so stub these out.
-  virtual void SavePassword() OVERRIDE;
-  bool saved_password() const { return saved_password_; }
-
-  virtual void NeverSavePassword() OVERRIDE;
-  bool never_saved_password() const { return never_saved_password_; }
-
-  virtual const autofill::PasswordForm& PendingCredentials() const OVERRIDE;
-
-  // True if this controller is installed on |web_contents()|.
-  bool IsInstalled() const;
-
- private:
-  bool navigated_to_settings_page_;
-  bool saved_password_;
-  bool never_saved_password_;
-
-  autofill::PasswordForm pending_credentials_;
-
-  DISALLOW_COPY_AND_ASSIGN(ManagePasswordsBubbleUIControllerMock);
-};
-
-#endif  // CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_UI_CONTROLLER_MOCK_H_
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_unittest.cc
deleted file mode 100644
index 890a611..0000000
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_unittest.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// 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.
-
-#include "base/metrics/histogram_samples.h"
-#include "base/prefs/pref_service.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/test/statistics_delta_reader.h"
-#include "chrome/browser/ui/passwords/manage_passwords_bubble.h"
-#include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
-#include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller_mock.h"
-#include "chrome/browser/ui/passwords/manage_passwords_icon.h"
-#include "chrome/browser/ui/passwords/manage_passwords_icon_mock.h"
-#include "chrome/test/base/testing_profile.h"
-#include "components/autofill/core/common/password_form.h"
-#include "components/password_manager/core/browser/mock_password_manager_driver.h"
-#include "components/password_manager/core/browser/password_form_manager.h"
-#include "components/password_manager/core/browser/password_manager_driver.h"
-#include "components/password_manager/core/browser/stub_password_manager_client.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "content/public/test/web_contents_tester.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-class ManagePasswordsBubbleUIControllerTest : public testing::Test {
- public:
-  ManagePasswordsBubbleUIControllerTest()
-      : test_web_contents_(
-            content::WebContentsTester::CreateTestWebContents(&profile_,
-                                                              NULL)) {}
-
-  virtual void SetUp() OVERRIDE {
-    // Create the test UIController here so that it's bound to
-    // |test_web_contents_|, and will be retrieved correctly via
-    // ManagePasswordsBubbleUIController::FromWebContents in |controller()|.
-    new ManagePasswordsBubbleUIControllerMock(test_web_contents_.get());
-
-    test_form_.origin = GURL("http://example.com");
-  }
-
-  autofill::PasswordForm& test_form() { return test_form_; }
-
-  ManagePasswordsBubbleUIControllerMock* controller() {
-    return static_cast<ManagePasswordsBubbleUIControllerMock*>(
-        ManagePasswordsBubbleUIController::FromWebContents(
-            test_web_contents_.get()));
-  }
-
- private:
-  content::TestBrowserThreadBundle thread_bundle_;
-  TestingProfile profile_;
-  scoped_ptr<content::WebContents> test_web_contents_;
-
-  autofill::PasswordForm test_form_;
-};
-
-TEST_F(ManagePasswordsBubbleUIControllerTest, DefaultState) {
-  EXPECT_FALSE(controller()->autofill_blocked());
-  EXPECT_FALSE(controller()->manage_passwords_bubble_needs_showing());
-  EXPECT_FALSE(controller()->manage_passwords_icon_to_be_shown());
-  EXPECT_FALSE(controller()->never_saved_password());
-  EXPECT_FALSE(controller()->password_to_be_saved());
-  EXPECT_FALSE(controller()->saved_password());
-
-  EXPECT_EQ(GURL::EmptyGURL(), controller()->origin());
-
-  ManagePasswordsIconMock mock;
-  controller()->UpdateIconAndBubbleState(&mock);
-  EXPECT_EQ(ManagePasswordsIcon::INACTIVE_STATE, mock.state());
-  EXPECT_EQ(0, mock.bubble_shown_count());
-}
-
-TEST_F(ManagePasswordsBubbleUIControllerTest, PasswordAutofilled) {
-  base::string16 kTestUsername = base::ASCIIToUTF16("test_username");
-  autofill::PasswordFormMap map;
-  map[kTestUsername] = &test_form();
-  controller()->OnPasswordAutofilled(map);
-
-  EXPECT_TRUE(controller()->manage_passwords_icon_to_be_shown());
-
-  EXPECT_FALSE(controller()->autofill_blocked());
-  EXPECT_FALSE(controller()->manage_passwords_bubble_needs_showing());
-  EXPECT_FALSE(controller()->never_saved_password());
-  EXPECT_FALSE(controller()->password_to_be_saved());
-  EXPECT_FALSE(controller()->saved_password());
-
-  EXPECT_EQ(test_form().origin, controller()->origin());
-
-  ManagePasswordsIconMock mock;
-  controller()->UpdateIconAndBubbleState(&mock);
-  EXPECT_EQ(ManagePasswordsIcon::MANAGE_STATE, mock.state());
-  EXPECT_EQ(0, mock.bubble_shown_count());
-}
-
-TEST_F(ManagePasswordsBubbleUIControllerTest, PasswordSubmitted) {
-  password_manager::StubPasswordManagerClient client;
-  password_manager::MockPasswordManagerDriver driver;
-  password_manager::PasswordFormManager* test_form_manager =
-      new password_manager::PasswordFormManager(
-          NULL, &client, &driver, test_form(), false);
-  controller()->OnPasswordSubmitted(test_form_manager);
-
-  EXPECT_TRUE(controller()->manage_passwords_bubble_needs_showing());
-  EXPECT_TRUE(controller()->manage_passwords_icon_to_be_shown());
-  EXPECT_TRUE(controller()->password_to_be_saved());
-
-  EXPECT_FALSE(controller()->autofill_blocked());
-  EXPECT_FALSE(controller()->never_saved_password());
-  EXPECT_FALSE(controller()->saved_password());
-
-  // TODO(mkwst): This should be the value of test_form()->origin, but
-  // it's being masked by the stub implementation of
-  // ManagePasswordsBubbleUIControllerMock::PendingCredentials.
-  EXPECT_EQ(GURL::EmptyGURL(), controller()->origin());
-
-  ManagePasswordsIconMock mock;
-  controller()->UpdateIconAndBubbleState(&mock);
-  EXPECT_EQ(ManagePasswordsIcon::PENDING_STATE, mock.state());
-  EXPECT_EQ(1, mock.bubble_shown_count());
-}
-
-TEST_F(ManagePasswordsBubbleUIControllerTest, BlacklistBlockedAutofill) {
-  controller()->OnBlacklistBlockedAutofill();
-
-  EXPECT_TRUE(controller()->autofill_blocked());
-  EXPECT_TRUE(controller()->manage_passwords_icon_to_be_shown());
-
-  EXPECT_FALSE(controller()->manage_passwords_bubble_needs_showing());
-  EXPECT_FALSE(controller()->never_saved_password());
-  EXPECT_FALSE(controller()->password_to_be_saved());
-  EXPECT_FALSE(controller()->saved_password());
-
-  EXPECT_EQ(GURL::EmptyGURL(), controller()->origin());
-
-  ManagePasswordsIconMock mock;
-  controller()->UpdateIconAndBubbleState(&mock);
-  EXPECT_EQ(ManagePasswordsIcon::BLACKLISTED_STATE, mock.state());
-  EXPECT_EQ(0, mock.bubble_shown_count());
-}
diff --git a/chrome/browser/ui/passwords/manage_passwords_icon.cc b/chrome/browser/ui/passwords/manage_passwords_icon.cc
index 0914bba..cba65c1 100644
--- a/chrome/browser/ui/passwords/manage_passwords_icon.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_icon.cc
@@ -4,15 +4,16 @@
 
 #include "chrome/browser/ui/passwords/manage_passwords_icon.h"
 
-ManagePasswordsIcon::ManagePasswordsIcon() : state_(INACTIVE_STATE) {
+ManagePasswordsIcon::ManagePasswordsIcon()
+    : state_(password_manager::ui::INACTIVE_STATE) {
 }
 
 ManagePasswordsIcon::~ManagePasswordsIcon() {
 }
 
-void ManagePasswordsIcon::SetState(State state) {
+void ManagePasswordsIcon::SetState(password_manager::ui::State state) {
   if (state_ == state)
     return;
   state_ = state;
-  SetStateInternal(state);
+  UpdateVisibleUI();
 }
diff --git a/chrome/browser/ui/passwords/manage_passwords_icon.h b/chrome/browser/ui/passwords/manage_passwords_icon.h
index 0a44406..76daed5 100644
--- a/chrome/browser/ui/passwords/manage_passwords_icon.h
+++ b/chrome/browser/ui/passwords/manage_passwords_icon.h
@@ -6,47 +6,27 @@
 #define CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_ICON_H_
 
 #include "base/basictypes.h"
+#include "components/password_manager/core/common/password_manager_ui.h"
 
 // Abstract base class for platform-specific password management icon views.
 class ManagePasswordsIcon {
  public:
-  enum State {
-    // The icon should not be displayed.
-    INACTIVE_STATE,
-
-    // The user has blacklisted the current page; the icon should be visible,
-    // and correctly represent the password manager's disabled state.
-    BLACKLISTED_STATE,
-
-    // Offer the user the ability to manage passwords for the current page.
-    MANAGE_STATE,
-
-    // Offer the user the ability to save a pending password.
-    PENDING_STATE,
-  };
-
   // Get/set the icon's state. Implementations of this class must implement
   // SetStateInternal to do reasonable platform-specific things to represent
   // the icon's state to the user.
-  void SetState(State state);
-  State state() const { return state_; }
-
-  // Shows the bubble without user interaction; should only be called from
-  // ManagePasswordsUIController.
-  //
-  // TODO(mkwst): This shouldn't be the IconView's responsiblity. Move it
-  // somewhere else as part of the refactoring in http://crbug.com/365678.
-  virtual void ShowBubbleWithoutUserInteraction() = 0;
+  void SetState(password_manager::ui::State state);
+  password_manager::ui::State state() const { return state_; }
 
  protected:
   ManagePasswordsIcon();
   ~ManagePasswordsIcon();
 
-  // Called from SetState() iff the icon's state has changed.
-  virtual void SetStateInternal(State state) = 0;
+  // Called from SetState() iff the icon's state has changed in order to do
+  // whatever platform-specific UI work is necessary given the new state.
+  virtual void UpdateVisibleUI() = 0;
 
  private:
-  State state_;
+  password_manager::ui::State state_;
 
   DISALLOW_COPY_AND_ASSIGN(ManagePasswordsIcon);
 };
diff --git a/chrome/browser/ui/passwords/manage_passwords_icon_mock.cc b/chrome/browser/ui/passwords/manage_passwords_icon_mock.cc
index 64bdb16..b6150db 100644
--- a/chrome/browser/ui/passwords/manage_passwords_icon_mock.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_icon_mock.cc
@@ -4,15 +4,11 @@
 
 #include "chrome/browser/ui/passwords/manage_passwords_icon_mock.h"
 
-ManagePasswordsIconMock::ManagePasswordsIconMock() : bubble_shown_count_(0) {
+ManagePasswordsIconMock::ManagePasswordsIconMock() {
 }
 
 ManagePasswordsIconMock::~ManagePasswordsIconMock() {
 }
 
-void ManagePasswordsIconMock::ShowBubbleWithoutUserInteraction() {
-  ++bubble_shown_count_;
-}
-
-void ManagePasswordsIconMock::SetStateInternal(ManagePasswordsIcon::State) {
+void ManagePasswordsIconMock::UpdateVisibleUI() {
 }
diff --git a/chrome/browser/ui/passwords/manage_passwords_icon_mock.h b/chrome/browser/ui/passwords/manage_passwords_icon_mock.h
index 3781e6a..089c7e9 100644
--- a/chrome/browser/ui/passwords/manage_passwords_icon_mock.h
+++ b/chrome/browser/ui/passwords/manage_passwords_icon_mock.h
@@ -11,18 +11,13 @@
 class ManagePasswordsIconMock : public ManagePasswordsIcon {
  public:
   ManagePasswordsIconMock();
-  ~ManagePasswordsIconMock();
-
-  // ManagePasswordsIcon:
-  virtual void ShowBubbleWithoutUserInteraction() OVERRIDE;
-  int bubble_shown_count() const { return bubble_shown_count_; }
+  virtual ~ManagePasswordsIconMock();
 
  protected:
-  virtual void SetStateInternal(State state) OVERRIDE;
+  // ManagePasswordsIcon:
+  virtual void UpdateVisibleUI() OVERRIDE;
 
  private:
-  int bubble_shown_count_;
-
   DISALLOW_COPY_AND_ASSIGN(ManagePasswordsIconMock);
 };
 
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
new file mode 100644
index 0000000..8225840
--- /dev/null
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -0,0 +1,201 @@
+// 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.
+
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
+
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/password_manager/password_store_factory.h"
+#include "chrome/browser/ui/browser_command_controller.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/omnibox/location_bar.h"
+#include "chrome/browser/ui/passwords/manage_passwords_icon.h"
+#include "chrome/common/url_constants.h"
+#include "components/password_manager/core/browser/password_store.h"
+#include "content/public/browser/notification_service.h"
+
+using autofill::PasswordFormMap;
+using password_manager::PasswordFormManager;
+
+namespace {
+
+password_manager::PasswordStore* GetPasswordStore(
+    content::WebContents* web_contents) {
+  return PasswordStoreFactory::GetForProfile(
+             Profile::FromBrowserContext(web_contents->GetBrowserContext()),
+             Profile::EXPLICIT_ACCESS).get();
+}
+
+} // namespace
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(ManagePasswordsUIController);
+
+ManagePasswordsUIController::ManagePasswordsUIController(
+    content::WebContents* web_contents)
+    : content::WebContentsObserver(web_contents),
+      state_(password_manager::ui::INACTIVE_STATE) {
+  password_manager::PasswordStore* password_store =
+      GetPasswordStore(web_contents);
+  if (password_store)
+    password_store->AddObserver(this);
+}
+
+ManagePasswordsUIController::~ManagePasswordsUIController() {}
+
+void ManagePasswordsUIController::UpdateBubbleAndIconVisibility() {
+  #if !defined(OS_ANDROID)
+    Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
+    if (!browser)
+      return;
+    LocationBar* location_bar = browser->window()->GetLocationBar();
+    DCHECK(location_bar);
+    location_bar->UpdateManagePasswordsIconAndBubble();
+  #endif
+}
+
+void ManagePasswordsUIController::OnPasswordSubmitted(
+    PasswordFormManager* form_manager) {
+  form_manager_.reset(form_manager);
+  password_form_map_ = form_manager_->best_matches();
+  origin_ = PendingCredentials().origin;
+  state_ = password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE;
+  UpdateBubbleAndIconVisibility();
+}
+
+void ManagePasswordsUIController::OnPasswordAutofilled(
+    const PasswordFormMap& password_form_map) {
+  password_form_map_ = password_form_map;
+  origin_ = password_form_map_.begin()->second->origin;
+  state_ = password_manager::ui::MANAGE_STATE;
+  UpdateBubbleAndIconVisibility();
+}
+
+void ManagePasswordsUIController::OnBlacklistBlockedAutofill(
+    const PasswordFormMap& password_form_map) {
+  password_form_map_ = password_form_map;
+  origin_ = password_form_map_.begin()->second->origin;
+  state_ = password_manager::ui::BLACKLIST_STATE;
+  UpdateBubbleAndIconVisibility();
+}
+
+void ManagePasswordsUIController::WebContentsDestroyed() {
+  password_manager::PasswordStore* password_store =
+      GetPasswordStore(web_contents());
+  if (password_store)
+    password_store->RemoveObserver(this);
+}
+
+void ManagePasswordsUIController::OnLoginsChanged(
+    const password_manager::PasswordStoreChangeList& changes) {
+  for (password_manager::PasswordStoreChangeList::const_iterator it =
+           changes.begin();
+       it != changes.end();
+       it++) {
+    const autofill::PasswordForm& changed_form = it->form();
+    if (changed_form.origin != origin_)
+      continue;
+
+    if (it->type() == password_manager::PasswordStoreChange::REMOVE) {
+      password_form_map_.erase(changed_form.username_value);
+    } else {
+      autofill::PasswordForm* new_form =
+          new autofill::PasswordForm(changed_form);
+      password_form_map_[changed_form.username_value] = new_form;
+    }
+  }
+}
+
+void ManagePasswordsUIController::
+    NavigateToPasswordManagerSettingsPage() {
+// TODO(mkwst): chrome_pages.h is compiled out of Android. Need to figure out
+// how this navigation should work there.
+#if !defined(OS_ANDROID)
+  chrome::ShowSettingsSubPage(
+      chrome::FindBrowserWithWebContents(web_contents()),
+      chrome::kPasswordManagerSubPage);
+#endif
+}
+
+void ManagePasswordsUIController::SavePassword() {
+  DCHECK(PasswordPendingUserDecision());
+  DCHECK(form_manager_.get());
+  form_manager_->Save();
+  state_ = password_manager::ui::MANAGE_STATE;
+}
+
+void ManagePasswordsUIController::NeverSavePassword() {
+  DCHECK(PasswordPendingUserDecision());
+  DCHECK(form_manager_.get());
+  form_manager_->PermanentlyBlacklist();
+  state_ = password_manager::ui::BLACKLIST_STATE;
+  UpdateBubbleAndIconVisibility();
+}
+
+void ManagePasswordsUIController::UnblacklistSite() {
+  // We're in one of two states: either the user _just_ blacklisted the site
+  // by clicking "Never save" in the pending bubble, or the user is visiting
+  // a blacklisted site.
+  //
+  // Either way, |password_form_map_| has been populated with the relevant
+  // form. We can safely pull it out, send it over to the password store
+  // for removal, and update our internal state.
+  DCHECK(!password_form_map_.empty());
+  DCHECK(state_ == password_manager::ui::BLACKLIST_STATE);
+  password_manager::PasswordStore* password_store =
+      GetPasswordStore(web_contents());
+  if (password_store)
+    password_store->RemoveLogin(*password_form_map_.begin()->second);
+  state_ = password_manager::ui::MANAGE_STATE;
+  UpdateBubbleAndIconVisibility();
+}
+
+void ManagePasswordsUIController::DidNavigateMainFrame(
+    const content::LoadCommittedDetails& details,
+    const content::FrameNavigateParams& params) {
+  if (details.is_in_page)
+    return;
+  state_ = password_manager::ui::INACTIVE_STATE;
+  UpdateBubbleAndIconVisibility();
+}
+
+const autofill::PasswordForm& ManagePasswordsUIController::
+    PendingCredentials() const {
+  DCHECK(form_manager_);
+  return form_manager_->pending_credentials();
+}
+
+void ManagePasswordsUIController::UpdateIconAndBubbleState(
+    ManagePasswordsIcon* icon) {
+  if (state_ == password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE) {
+    // We must display the icon before showing the bubble, as the bubble would
+    // be otherwise unanchored. However, we can't change the controller's state
+    // until _after_ the bubble is shown, as our metrics depend on the
+    // distinction between PENDING_PASSWORD_AND_BUBBLE_STATE and
+    // PENDING_PASSWORD_STATE to determine if the bubble opened automagically
+    // or via user action.
+    icon->SetState(password_manager::ui::PENDING_PASSWORD_STATE);
+    ShowBubbleWithoutUserInteraction();
+    state_ = password_manager::ui::PENDING_PASSWORD_STATE;
+  } else  {
+    icon->SetState(state_);
+  }
+}
+
+void ManagePasswordsUIController::ShowBubbleWithoutUserInteraction() {
+  DCHECK_EQ(state_, password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE);
+#if !defined(OS_ANDROID)
+  Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
+  if (!browser || browser->toolbar_model()->input_in_progress())
+    return;
+  CommandUpdater* updater = browser->command_controller()->command_updater();
+  updater->ExecuteCommand(IDC_MANAGE_PASSWORDS_FOR_PAGE);
+#endif
+}
+
+bool ManagePasswordsUIController::PasswordPendingUserDecision() const {
+  return state_ == password_manager::ui::PENDING_PASSWORD_STATE ||
+         state_ == password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE;
+}
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
new file mode 100644
index 0000000..eed1a64
--- /dev/null
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
@@ -0,0 +1,138 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_
+#define CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_
+
+#include "components/password_manager/core/browser/password_form_manager.h"
+#include "components/password_manager/core/browser/password_store.h"
+#include "components/password_manager/core/browser/password_store_change.h"
+#include "components/password_manager/core/common/password_manager_ui.h"
+#include "content/public/browser/navigation_details.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+namespace content {
+class WebContents;
+}
+
+class ManagePasswordsIcon;
+
+// Per-tab class to control the Omnibox password icon and bubble.
+class ManagePasswordsUIController
+    : public content::WebContentsObserver,
+      public content::WebContentsUserData<ManagePasswordsUIController>,
+      public password_manager::PasswordStore::Observer {
+ public:
+  virtual ~ManagePasswordsUIController();
+
+  // Called when the user submits a form containing login information, so we
+  // can handle later requests to save or blacklist that login information.
+  // This stores the provided object in form_manager_ and triggers the UI to
+  // prompt the user about whether they would like to save the password.
+  void OnPasswordSubmitted(password_manager::PasswordFormManager* form_manager);
+
+  // Called when a form is autofilled with login information, so we can manage
+  // password credentials for the current site which are stored in
+  // |password_form_map|. This stores a copy of |password_form_map| and shows
+  // the manage password icon.
+  void OnPasswordAutofilled(const autofill::PasswordFormMap& password_form_map);
+
+  // Called when a form is _not_ autofilled due to user blacklisting. This
+  // stores a copy of |password_form_map| so that we can offer the user the
+  // ability to reenable the manager for this form.
+  void OnBlacklistBlockedAutofill(
+      const autofill::PasswordFormMap& password_form_map);
+
+  // PasswordStore::Observer implementation.
+  virtual void OnLoginsChanged(
+      const password_manager::PasswordStoreChangeList& changes) OVERRIDE;
+
+  // Called from the model when the user chooses to save a password; passes the
+  // action off to the FormManager. The controller MUST be in a pending state,
+  // and WILL be in MANAGE_STATE after this method executes.
+  virtual void SavePassword();
+
+  // Called from the model when the user chooses to never save passwords; passes
+  // the action off to the FormManager. The controller MUST be in a pending
+  // state, and WILL be in BLACKLIST_STATE after this method executes.
+  virtual void NeverSavePassword();
+
+  // Called from the model when the user chooses to unblacklist the site. The
+  // controller MUST be in BLACKLIST_STATE, and WILL be in MANAGE_STATE after
+  // this method executes.
+  virtual void UnblacklistSite();
+
+  // Open a new tab, pointing to the password manager settings page.
+  virtual void NavigateToPasswordManagerSettingsPage();
+
+  virtual const autofill::PasswordForm& PendingCredentials() const;
+
+  // Set the state of the Omnibox icon, and possibly show the associated bubble
+  // without user interaction.
+  virtual void UpdateIconAndBubbleState(ManagePasswordsIcon* icon);
+
+  password_manager::ui::State state() const { return state_; }
+
+  // True if a password is sitting around, waiting for a user to decide whether
+  // or not to save it.
+  bool PasswordPendingUserDecision() const;
+
+  const autofill::PasswordFormMap best_matches() const {
+    return password_form_map_;
+  }
+
+  const GURL& origin() const { return origin_; }
+
+ protected:
+  explicit ManagePasswordsUIController(
+      content::WebContents* web_contents);
+
+  // All previously stored credentials for a specific site. Set by
+  // OnPasswordSubmitted(), OnPasswordAutofilled(), or
+  // OnBlacklistBlockedAutofill(). Protected, not private, so we can mess with
+  // the value in ManagePasswordsUIControllerMock.
+  autofill::PasswordFormMap password_form_map_;
+
+  // The current state of the password manager. Protected so we can manipulate
+  // the value in tests.
+  password_manager::ui::State state_;
+
+ private:
+  friend class content::WebContentsUserData<ManagePasswordsUIController>;
+
+  // Shows the password bubble without user interaction. The controller MUST
+  // be in PENDING_PASSWORD_AND_BUBBLE_STATE.
+  void ShowBubbleWithoutUserInteraction();
+
+  // Called when a passwordform is autofilled, when a new passwordform is
+  // submitted, or when a navigation occurs to update the visibility of the
+  // manage passwords icon and bubble.
+  void UpdateBubbleAndIconVisibility();
+
+  // content::WebContentsObserver:
+  virtual void DidNavigateMainFrame(
+      const content::LoadCommittedDetails& details,
+      const content::FrameNavigateParams& params) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
+
+  // Set by OnPasswordSubmitted() when the user submits a form containing login
+  // information.  If the user responds to a subsequent "Do you want to save
+  // this password?" prompt, we ask this object to save or blacklist the
+  // associated login information in Chrome's password store.
+  scoped_ptr<password_manager::PasswordFormManager> form_manager_;
+
+  // Stores whether autofill was blocked due to a user's decision to blacklist
+  // the current site ("Never save passwords for this site").
+  bool autofill_blocked_;
+
+  // The origin of the form we're currently dealing with; we'll use this to
+  // determine which PasswordStore changes we should care about when updating
+  // |password_form_map_|.
+  GURL origin_;
+
+  DISALLOW_COPY_AND_ASSIGN(ManagePasswordsUIController);
+};
+
+#endif  // CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.cc
new file mode 100644
index 0000000..af999a8
--- /dev/null
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.cc
@@ -0,0 +1,41 @@
+// 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.
+
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h"
+
+#include "content/public/browser/web_contents.h"
+
+ManagePasswordsUIControllerMock::ManagePasswordsUIControllerMock(
+    content::WebContents* contents)
+    : ManagePasswordsUIController(contents),
+      navigated_to_settings_page_(false),
+      saved_password_(false),
+      never_saved_password_(false) {
+  contents->SetUserData(UserDataKey(), this);
+}
+
+ManagePasswordsUIControllerMock::
+    ~ManagePasswordsUIControllerMock() {}
+
+void ManagePasswordsUIControllerMock::
+    NavigateToPasswordManagerSettingsPage() {
+  navigated_to_settings_page_ = true;
+}
+
+const autofill::PasswordForm&
+    ManagePasswordsUIControllerMock::PendingCredentials() const {
+  return pending_credentials_;
+}
+
+bool ManagePasswordsUIControllerMock::IsInstalled() const {
+  return web_contents()->GetUserData(UserDataKey()) == this;
+}
+
+void ManagePasswordsUIControllerMock::SavePassword() {
+  saved_password_ = true;
+}
+
+void ManagePasswordsUIControllerMock::NeverSavePassword() {
+  never_saved_password_ = true;
+}
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h
new file mode 100644
index 0000000..d2d7de0
--- /dev/null
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h
@@ -0,0 +1,63 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_MOCK_H_
+#define CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_MOCK_H_
+
+#include "base/basictypes.h"
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
+#include "components/password_manager/core/common/password_manager_ui.h"
+
+namespace content {
+class WebContents;
+}  // namespace content
+
+// This mock is used in tests to ensure that we're just testing the controller
+// behavior, and not the behavior of the bits and pieces it relies upon (like
+// FormManager).
+class ManagePasswordsUIControllerMock
+    : public ManagePasswordsUIController {
+ public:
+  explicit ManagePasswordsUIControllerMock(
+      content::WebContents* contents);
+  virtual ~ManagePasswordsUIControllerMock();
+
+  // Navigation, surprisingly, is platform-specific; Android's settings page
+  // is native UI and therefore isn't available in a tab for unit tests.
+  //
+  // TODO(mkwst): Determine how to reasonably test this on that platform.
+  virtual void NavigateToPasswordManagerSettingsPage() OVERRIDE;
+  bool navigated_to_settings_page() const {
+    return navigated_to_settings_page_;
+  }
+
+  // We don't have a FormManager in tests, so stub these out.
+  virtual void SavePassword() OVERRIDE;
+  bool saved_password() const { return saved_password_; }
+
+  virtual void NeverSavePassword() OVERRIDE;
+  bool never_saved_password() const { return never_saved_password_; }
+
+  virtual const autofill::PasswordForm& PendingCredentials() const OVERRIDE;
+
+  // Sneaky setters for testing.
+  void SetPasswordFormMap(const autofill::PasswordFormMap& map) {
+    password_form_map_ = map;
+  }
+  void SetState(password_manager::ui::State state) { state_ = state; }
+
+  // True if this controller is installed on |web_contents()|.
+  bool IsInstalled() const;
+
+ private:
+  bool navigated_to_settings_page_;
+  bool saved_password_;
+  bool never_saved_password_;
+
+  autofill::PasswordForm pending_credentials_;
+
+  DISALLOW_COPY_AND_ASSIGN(ManagePasswordsUIControllerMock);
+};
+
+#endif  // CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_MOCK_H_
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
new file mode 100644
index 0000000..420a562
--- /dev/null
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -0,0 +1,133 @@
+// 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.
+
+#include "base/metrics/histogram_samples.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/statistics_delta_reader.h"
+#include "chrome/browser/ui/passwords/manage_passwords_bubble.h"
+#include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
+#include "chrome/browser/ui/passwords/manage_passwords_icon.h"
+#include "chrome/browser/ui/passwords/manage_passwords_icon_mock.h"
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/autofill/core/common/password_form.h"
+#include "components/password_manager/core/browser/mock_password_manager_driver.h"
+#include "components/password_manager/core/browser/password_form_manager.h"
+#include "components/password_manager/core/browser/password_manager_driver.h"
+#include "components/password_manager/core/browser/stub_password_manager_client.h"
+#include "components/password_manager/core/common/password_manager_ui.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/web_contents_tester.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class ManagePasswordsUIControllerTest : public testing::Test {
+ public:
+  ManagePasswordsUIControllerTest()
+      : test_web_contents_(
+            content::WebContentsTester::CreateTestWebContents(&profile_,
+                                                              NULL)) {}
+
+  virtual void SetUp() OVERRIDE {
+    // Create the test UIController here so that it's bound to
+    // |test_web_contents_|, and will be retrieved correctly via
+    // ManagePasswordsUIController::FromWebContents in |controller()|.
+    new ManagePasswordsUIControllerMock(test_web_contents_.get());
+
+    test_form_.origin = GURL("http://example.com");
+  }
+
+  autofill::PasswordForm& test_form() { return test_form_; }
+
+  ManagePasswordsUIControllerMock* controller() {
+    return static_cast<ManagePasswordsUIControllerMock*>(
+        ManagePasswordsUIController::FromWebContents(
+            test_web_contents_.get()));
+  }
+
+ private:
+  content::TestBrowserThreadBundle thread_bundle_;
+  TestingProfile profile_;
+  scoped_ptr<content::WebContents> test_web_contents_;
+
+  autofill::PasswordForm test_form_;
+};
+
+TEST_F(ManagePasswordsUIControllerTest, DefaultState) {
+  EXPECT_EQ(password_manager::ui::INACTIVE_STATE, controller()->state());
+  EXPECT_FALSE(controller()->PasswordPendingUserDecision());
+  EXPECT_EQ(GURL::EmptyGURL(), controller()->origin());
+
+  ManagePasswordsIconMock mock;
+  controller()->UpdateIconAndBubbleState(&mock);
+  EXPECT_EQ(password_manager::ui::INACTIVE_STATE, mock.state());
+}
+
+TEST_F(ManagePasswordsUIControllerTest, PasswordAutofilled) {
+  base::string16 kTestUsername = base::ASCIIToUTF16("test_username");
+  autofill::PasswordFormMap map;
+  map[kTestUsername] = &test_form();
+  controller()->OnPasswordAutofilled(map);
+
+  EXPECT_EQ(password_manager::ui::MANAGE_STATE, controller()->state());
+  EXPECT_FALSE(controller()->PasswordPendingUserDecision());
+  EXPECT_EQ(test_form().origin, controller()->origin());
+
+  ManagePasswordsIconMock mock;
+  controller()->UpdateIconAndBubbleState(&mock);
+  EXPECT_EQ(password_manager::ui::MANAGE_STATE, mock.state());
+}
+
+TEST_F(ManagePasswordsUIControllerTest, PasswordSubmitted) {
+  password_manager::StubPasswordManagerClient client;
+  password_manager::MockPasswordManagerDriver driver;
+  password_manager::PasswordFormManager* test_form_manager =
+      new password_manager::PasswordFormManager(
+          NULL, &client, &driver, test_form(), false);
+  controller()->OnPasswordSubmitted(test_form_manager);
+  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE,
+            controller()->state());
+  EXPECT_TRUE(controller()->PasswordPendingUserDecision());
+
+  // TODO(mkwst): This should be the value of test_form().origin, but
+  // it's being masked by the stub implementation of
+  // ManagePasswordsUIControllerMock::PendingCredentials.
+  EXPECT_EQ(GURL::EmptyGURL(), controller()->origin());
+
+  ManagePasswordsIconMock mock;
+  controller()->UpdateIconAndBubbleState(&mock);
+  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE, mock.state());
+}
+
+TEST_F(ManagePasswordsUIControllerTest, BlacklistBlockedAutofill) {
+  base::string16 kTestUsername = base::ASCIIToUTF16("test_username");
+  autofill::PasswordFormMap map;
+  map[kTestUsername] = &test_form();
+  controller()->OnBlacklistBlockedAutofill(map);
+
+  EXPECT_EQ(password_manager::ui::BLACKLIST_STATE, controller()->state());
+  EXPECT_FALSE(controller()->PasswordPendingUserDecision());
+  EXPECT_EQ(test_form().origin, controller()->origin());
+
+  ManagePasswordsIconMock mock;
+  controller()->UpdateIconAndBubbleState(&mock);
+  EXPECT_EQ(password_manager::ui::BLACKLIST_STATE, mock.state());
+}
+
+TEST_F(ManagePasswordsUIControllerTest, ClickedUnblacklist) {
+  base::string16 kTestUsername = base::ASCIIToUTF16("test_username");
+  autofill::PasswordFormMap map;
+  map[kTestUsername] = &test_form();
+  controller()->OnBlacklistBlockedAutofill(map);
+  controller()->UnblacklistSite();
+
+  EXPECT_EQ(password_manager::ui::MANAGE_STATE, controller()->state());
+  EXPECT_FALSE(controller()->PasswordPendingUserDecision());
+  EXPECT_EQ(test_form().origin, controller()->origin());
+
+  ManagePasswordsIconMock mock;
+  controller()->UpdateIconAndBubbleState(&mock);
+  EXPECT_EQ(password_manager::ui::MANAGE_STATE, mock.state());
+}
diff --git a/chrome/browser/ui/sad_tab_helper.cc b/chrome/browser/ui/sad_tab_helper.cc
index 8ad27ec..ab8a6e0 100644
--- a/chrome/browser/ui/sad_tab_helper.cc
+++ b/chrome/browser/ui/sad_tab_helper.cc
@@ -8,7 +8,6 @@
 #include "chrome/browser/browser_shutdown.h"
 #include "chrome/browser/ui/sad_tab.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(SadTabHelper);
 
diff --git a/chrome/browser/ui/search/instant_controller.cc b/chrome/browser/ui/search/instant_controller.cc
index 396904b..7361475 100644
--- a/chrome/browser/ui/search/instant_controller.cc
+++ b/chrome/browser/ui/search/instant_controller.cc
@@ -31,7 +31,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "net/base/escape.h"
 #include "net/base/network_change_notifier.h"
 #include "url/gurl.h"
@@ -91,7 +90,7 @@
     // page. (NOTE: in particular, we do not send the query to NTPs.)
     SearchTabHelper::FromWebContents(instant_tab_->contents())->Submit(
         search_terms);
-    instant_tab_->contents()->GetView()->Focus();
+    instant_tab_->contents()->Focus();
     EnsureSearchTermsAreSet(instant_tab_->contents(), search_terms);
     return true;
   }
diff --git a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
index bdb18dd..c01f4e30 100644
--- a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
+++ b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/autocomplete/autocomplete_result.h"
 #include "chrome/browser/autocomplete/search_provider.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -59,6 +58,7 @@
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "components/sessions/serialized_navigation_entry.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
@@ -68,7 +68,6 @@
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/url_data_source.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/bindings_policy.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc
index e9c9779..4bc6991 100644
--- a/chrome/browser/ui/search/search_tab_helper.cc
+++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -39,7 +39,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/page_transition_types.h"
 #include "content/public/common/referrer.h"
 #include "grit/generated_resources.h"
@@ -432,7 +431,7 @@
       // from changing the omnibox value and closing the popup without user
       // interaction.
       if (!omnibox->model()->popup_model()->IsOpen())
-        web_contents()->GetView()->Focus();
+        web_contents()->Focus();
       break;
   }
 #endif
diff --git a/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc b/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc
index f13247e..93fbef8 100644
--- a/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc
+++ b/chrome/browser/ui/search_engines/keyword_editor_controller_unittest.cc
@@ -2,20 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/message_loop/message_loop.h"
+#include "base/compiler_specific.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_service.h"
-#include "chrome/browser/search_engines/template_url_service_factory.h"
+#include "chrome/browser/search_engines/template_url_service_test_util.h"
 #include "chrome/browser/ui/search_engines/keyword_editor_controller.h"
 #include "chrome/browser/ui/search_engines/template_url_table_model.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/test/base/testing_pref_service_syncable.h"
 #include "chrome/test/base/testing_profile.h"
-#include "content/public/browser/notification_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/models/table_model_observer.h"
 
@@ -31,11 +27,35 @@
 class KeywordEditorControllerTest : public testing::Test,
                                     public ui::TableModelObserver {
  public:
-  // Initializes all of the state.
-  void Init(bool simulate_load_failure);
+  KeywordEditorControllerTest()
+      : simulate_load_failure_(false),
+        model_changed_count_(0),
+        items_changed_count_(0),
+        added_count_(0),
+        removed_count_(0) {}
 
-  virtual void SetUp() {
-    Init(false);
+  explicit KeywordEditorControllerTest(bool simulate_load_failure)
+      : simulate_load_failure_(simulate_load_failure),
+        model_changed_count_(0),
+        items_changed_count_(0),
+        added_count_(0),
+        removed_count_(0) {}
+
+  virtual void SetUp() OVERRIDE {
+    util_.SetUp();
+
+    if (simulate_load_failure_)
+      util_.model()->OnWebDataServiceRequestDone(0, NULL);
+    else
+      util_.ChangeModelToLoadState();
+
+    controller_.reset(new KeywordEditorController(util_.profile()));
+    controller_->table_model()->SetObserver(this);
+  }
+
+  virtual void TearDown() OVERRIDE {
+    controller_.reset();
+    util_.TearDown();
   }
 
   virtual void OnModelChanged() OVERRIDE {
@@ -69,35 +89,29 @@
   }
 
   void SimulateDefaultSearchIsManaged(const std::string& url) {
-    ASSERT_FALSE(url.empty());
-    TestingPrefServiceSyncable* service = profile_->GetTestingPrefService();
-    service->SetManagedPref(prefs::kDefaultSearchProviderEnabled,
-                            new base::FundamentalValue(true));
-    service->SetManagedPref(prefs::kDefaultSearchProviderSearchURL,
-                            new base::StringValue(url));
-    service->SetManagedPref(prefs::kDefaultSearchProviderName,
-                            new base::StringValue("managed"));
-    service->SetManagedPref(prefs::kDefaultSearchProviderKeyword,
-                            new base::StringValue("managed"));
-    // Clear the IDs that are not specified via policy.
-    service->SetManagedPref(prefs::kDefaultSearchProviderID,
-                            new base::StringValue(std::string()));
-    service->SetManagedPref(prefs::kDefaultSearchProviderPrepopulateID,
-                            new base::StringValue(std::string()));
-    model_->Observe(chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED,
-                    content::NotificationService::AllSources(),
-                    content::NotificationService::NoDetails());
+    util_.SetManagedDefaultSearchPreferences(true,
+                                             "managed",
+                                             "managed",
+                                             url,
+                                             std::string(),
+                                             std::string(),
+                                             std::string(),
+                                             std::string(),
+                                             std::string());
   }
 
-  TemplateURLTableModel* table_model() const {
-    return controller_->table_model();
-  }
+  TemplateURLTableModel* table_model() { return controller_->table_model(); }
+  KeywordEditorController* controller() { return controller_.get(); }
+  const TemplateURLServiceTestUtil* util() const { return &util_; }
 
- protected:
-  base::MessageLoopForUI message_loop_;
-  scoped_ptr<TestingProfile> profile_;
+  int items_changed_count() const { return items_changed_count_; }
+  int added_count() const { return added_count_; }
+  int removed_count() const { return removed_count_; }
+
+ private:
   scoped_ptr<KeywordEditorController> controller_;
-  TemplateURLService* model_;
+  TemplateURLServiceTestUtil util_;
+  bool simulate_load_failure_;
 
   int model_changed_count_;
   int items_changed_count_;
@@ -105,27 +119,16 @@
   int removed_count_;
 };
 
-void KeywordEditorControllerTest::Init(bool simulate_load_failure) {
-  ClearChangeCount();
-
-  // If init is called twice, make sure that the controller is destroyed before
-  // the profile is.
-  controller_.reset();
-  profile_.reset(new TestingProfile());
-  TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
-      profile_.get(), &TemplateURLServiceFactory::BuildInstanceFor);
-
-  model_ = TemplateURLServiceFactory::GetForProfile(profile_.get());
-  if (simulate_load_failure)
-    model_->OnWebDataServiceRequestDone(0, NULL);
-
-  controller_.reset(new KeywordEditorController(profile_.get()));
-  controller_->table_model()->SetObserver(this);
-}
+class KeywordEditorControllerNoWebDataTest
+    : public KeywordEditorControllerTest {
+ public:
+  KeywordEditorControllerNoWebDataTest() : KeywordEditorControllerTest(true) {}
+};
 
 // Tests adding a TemplateURL.
 TEST_F(KeywordEditorControllerTest, Add) {
-  controller_->AddTemplateURL(kA, kB, "http://c");
+  int original_row_count = table_model()->RowCount();
+  controller()->AddTemplateURL(kA, kB, "http://c");
 
   // Verify the observer was notified.
   VerifyChangeCount(0, 0, 1, 0);
@@ -133,13 +136,11 @@
     return;
 
   // Verify the TableModel has the new data.
-  ASSERT_EQ(1, table_model()->RowCount());
+  ASSERT_EQ(original_row_count + 1, table_model()->RowCount());
 
-  // Verify the TemplateURLService has the new entry.
-  ASSERT_EQ(1U, model_->GetTemplateURLs().size());
-
-  // Verify the entry is what we added.
-  const TemplateURL* turl = model_->GetTemplateURLs()[0];
+  // Verify the TemplateURLService has the new data.
+  const TemplateURL* turl = util()->model()->GetTemplateURLForKeyword(kB);
+  ASSERT_TRUE(turl);
   EXPECT_EQ(ASCIIToUTF16("a"), turl->short_name());
   EXPECT_EQ(ASCIIToUTF16("b"), turl->keyword());
   EXPECT_EQ("http://c", turl->url());
@@ -147,12 +148,12 @@
 
 // Tests modifying a TemplateURL.
 TEST_F(KeywordEditorControllerTest, Modify) {
-  controller_->AddTemplateURL(kA, kB, "http://c");
+  controller()->AddTemplateURL(kA, kB, "http://c");
   ClearChangeCount();
 
   // Modify the entry.
-  TemplateURL* turl = model_->GetTemplateURLs()[0];
-  controller_->ModifyTemplateURL(turl, kA1, kB1, "http://c1");
+  TemplateURL* turl = util()->model()->GetTemplateURLs()[0];
+  controller()->ModifyTemplateURL(turl, kA1, kB1, "http://c1");
 
   // Make sure it was updated appropriately.
   VerifyChangeCount(0, 1, 0, 0);
@@ -163,98 +164,98 @@
 
 // Tests making a TemplateURL the default search provider.
 TEST_F(KeywordEditorControllerTest, MakeDefault) {
-  controller_->AddTemplateURL(kA, kB, "http://c{searchTerms}");
+  int index = controller()->AddTemplateURL(kA, kB, "http://c{searchTerms}");
   ClearChangeCount();
 
-  const TemplateURL* turl = model_->GetTemplateURLs()[0];
-  int new_default = controller_->MakeDefaultTemplateURL(0);
-  EXPECT_EQ(0, new_default);
+  const TemplateURL* turl = util()->model()->GetTemplateURLForKeyword(kB);
+  int new_default = controller()->MakeDefaultTemplateURL(index);
+  EXPECT_EQ(index, new_default);
   // Making an item the default sends a handful of changes. Which are sent isn't
   // important, what is important is 'something' is sent.
-  ASSERT_TRUE(items_changed_count_ > 0 || added_count_ > 0 ||
-              removed_count_ > 0);
-  ASSERT_TRUE(model_->GetDefaultSearchProvider() == turl);
+  ASSERT_TRUE(items_changed_count() > 0 || added_count() > 0 ||
+              removed_count() > 0);
+  ASSERT_TRUE(util()->model()->GetDefaultSearchProvider() == turl);
 
   // Making it default a second time should fail.
-  new_default = controller_->MakeDefaultTemplateURL(0);
+  new_default = controller()->MakeDefaultTemplateURL(index);
   EXPECT_EQ(-1, new_default);
 }
 
 // Tests that a TemplateURL can't be made the default if the default search
 // provider is managed via policy.
 TEST_F(KeywordEditorControllerTest, CannotSetDefaultWhileManaged) {
-  controller_->AddTemplateURL(kA, kB, "http://c{searchTerms}");
-  controller_->AddTemplateURL(kA1, kB1, "http://d{searchTerms}");
+  controller()->AddTemplateURL(kA, kB, "http://c{searchTerms}");
+  controller()->AddTemplateURL(kA1, kB1, "http://d{searchTerms}");
   ClearChangeCount();
 
   const TemplateURL* turl1 =
-      model_->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
+      util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
   ASSERT_TRUE(turl1 != NULL);
   const TemplateURL* turl2 =
-      model_->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
+      util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
   ASSERT_TRUE(turl2 != NULL);
 
-  EXPECT_TRUE(controller_->CanMakeDefault(turl1));
-  EXPECT_TRUE(controller_->CanMakeDefault(turl2));
+  EXPECT_TRUE(controller()->CanMakeDefault(turl1));
+  EXPECT_TRUE(controller()->CanMakeDefault(turl2));
 
   SimulateDefaultSearchIsManaged(turl2->url());
-  EXPECT_TRUE(model_->is_default_search_managed());
+  EXPECT_TRUE(util()->model()->is_default_search_managed());
 
-  EXPECT_FALSE(controller_->CanMakeDefault(turl1));
-  EXPECT_FALSE(controller_->CanMakeDefault(turl2));
+  EXPECT_FALSE(controller()->CanMakeDefault(turl1));
+  EXPECT_FALSE(controller()->CanMakeDefault(turl2));
 }
 
 // Tests that a TemplateURL can't be edited if it is the managed default search
 // provider.
 TEST_F(KeywordEditorControllerTest, EditManagedDefault) {
-  controller_->AddTemplateURL(kA, kB, "http://c{searchTerms}");
-  controller_->AddTemplateURL(kA1, kB1, "http://d{searchTerms}");
+  controller()->AddTemplateURL(kA, kB, "http://c{searchTerms}");
+  controller()->AddTemplateURL(kA1, kB1, "http://d{searchTerms}");
   ClearChangeCount();
 
   const TemplateURL* turl1 =
-      model_->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
+      util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b"));
   ASSERT_TRUE(turl1 != NULL);
   const TemplateURL* turl2 =
-      model_->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
+      util()->model()->GetTemplateURLForKeyword(ASCIIToUTF16("b1"));
   ASSERT_TRUE(turl2 != NULL);
 
-  EXPECT_TRUE(controller_->CanEdit(turl1));
-  EXPECT_TRUE(controller_->CanEdit(turl2));
+  EXPECT_TRUE(controller()->CanEdit(turl1));
+  EXPECT_TRUE(controller()->CanEdit(turl2));
 
   // Simulate setting a managed default.  This will add another template URL to
   // the model.
   SimulateDefaultSearchIsManaged(turl2->url());
-  EXPECT_TRUE(model_->is_default_search_managed());
-  EXPECT_TRUE(controller_->CanEdit(turl1));
-  EXPECT_TRUE(controller_->CanEdit(turl2));
-  EXPECT_FALSE(controller_->CanEdit(model_->GetDefaultSearchProvider()));
+  EXPECT_TRUE(util()->model()->is_default_search_managed());
+  EXPECT_TRUE(controller()->CanEdit(turl1));
+  EXPECT_TRUE(controller()->CanEdit(turl2));
+  EXPECT_FALSE(
+      controller()->CanEdit(util()->model()->GetDefaultSearchProvider()));
 }
 
-TEST_F(KeywordEditorControllerTest, MakeDefaultNoWebData) {
-  // Simulate a failure to load Web Data.
-  Init(true);
-
-  controller_->AddTemplateURL(kA, kB, "http://c{searchTerms}");
+TEST_F(KeywordEditorControllerNoWebDataTest, MakeDefaultNoWebData) {
+  int index = controller()->AddTemplateURL(kA, kB, "http://c{searchTerms}");
   ClearChangeCount();
 
   // This should not result in a crash.
-  int new_default = controller_->MakeDefaultTemplateURL(0);
-  EXPECT_EQ(0, new_default);
+  int new_default = controller()->MakeDefaultTemplateURL(index);
+  EXPECT_EQ(index, new_default);
 }
 
 // Mutates the TemplateURLService and make sure table model is updating
 // appropriately.
 TEST_F(KeywordEditorControllerTest, MutateTemplateURLService) {
+  int original_row_count = table_model()->RowCount();
+
   TemplateURLData data;
   data.short_name = ASCIIToUTF16("b");
   data.SetKeyword(ASCIIToUTF16("a"));
-  TemplateURL* turl = new TemplateURL(profile_.get(), data);
-  model_->Add(turl);
+  TemplateURL* turl = new TemplateURL(util()->profile(), data);
+  util()->model()->Add(turl);
 
   // Table model should have updated.
   VerifyChangeCount(1, 0, 0, 0);
 
   // And should contain the newly added TemplateURL.
-  ASSERT_EQ(1, table_model()->RowCount());
-  ASSERT_EQ(0, table_model()->IndexOfTemplateURL(turl));
+  ASSERT_EQ(original_row_count + 1, table_model()->RowCount());
+  ASSERT_GE(table_model()->IndexOfTemplateURL(turl), 0);
 }
diff --git a/chrome/browser/ui/search_engines/search_engine_tab_helper.cc b/chrome/browser/ui/search_engines/search_engine_tab_helper.cc
index 7ebda48..db0a28f 100644
--- a/chrome/browser/ui/search_engines/search_engine_tab_helper.cc
+++ b/chrome/browser/ui/search_engines/search_engine_tab_helper.cc
@@ -55,7 +55,7 @@
   // If we relax the path constraint, we need to be sure to sanitize the path
   // elements and update AutocompletePopup to look for keywords using the path.
   // See http://b/issue?id=863583.
-  if (!url.SchemeIs(content::kHttpScheme) || (url.path().length() > 1))
+  if (!url.SchemeIs(url::kHttpScheme) || (url.path().length() > 1))
     return base::string16();
 
   return TemplateURLService::GenerateKeyword(url);
diff --git a/chrome/browser/ui/settings_window_manager.cc b/chrome/browser/ui/settings_window_manager.cc
index 1e991e4..fa00fed 100644
--- a/chrome/browser/ui/settings_window_manager.cc
+++ b/chrome/browser/ui/settings_window_manager.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
+#include "url/gurl.h"
 
 namespace chrome {
 
@@ -32,10 +33,8 @@
   observers_.RemoveObserver(observer);
 }
 
-void SettingsWindowManager::ShowForProfile(Profile* profile,
-                                           const std::string& sub_page) {
-  content::RecordAction(base::UserMetricsAction("ShowOptions"));
-  GURL gurl = chrome::GetSettingsUrl(sub_page);
+void SettingsWindowManager::ShowChromePageForProfile(Profile* profile,
+                                                     const GURL& gurl) {
   // Look for an existing browser window.
   Browser* browser = FindBrowserForProfile(profile);
   if (browser) {
diff --git a/chrome/browser/ui/settings_window_manager.h b/chrome/browser/ui/settings_window_manager.h
index 79b07d4..16eca89 100644
--- a/chrome/browser/ui/settings_window_manager.h
+++ b/chrome/browser/ui/settings_window_manager.h
@@ -13,6 +13,7 @@
 #include "chrome/browser/sessions/session_id.h"
 
 class Browser;
+class GURL;
 class Profile;
 
 namespace chrome {
@@ -29,9 +30,9 @@
   void AddObserver(SettingsWindowManagerObserver* observer);
   void RemoveObserver(SettingsWindowManagerObserver* observer);
 
-  // Shows an existing settings Browser window for |profile| or creates a new
-  // one. Navigates that window to |sub_page|.
-  void ShowForProfile(Profile* profile, const std::string& sub_page);
+  // Shows a chrome:// page (e.g. Settings, History) in an an existing system
+  // Browser window for |profile| or creates a new one.
+  void ShowChromePageForProfile(Profile* profile, const GURL& gurl);
 
   // If a Browser settings window for |profile| has already been created,
   // returns it, otherwise returns NULL.
diff --git a/chrome/browser/ui/settings_window_manager_browsertest.cc b/chrome/browser/ui/settings_window_manager_browsertest.cc
index 50aabfc..83f0cf3 100644
--- a/chrome/browser/ui/settings_window_manager_browsertest.cc
+++ b/chrome/browser/ui/settings_window_manager_browsertest.cc
@@ -11,12 +11,17 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_iterator.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/settings_window_manager_observer.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/test/test_utils.h"
+#include "url/gurl.h"
 
 namespace {
 
@@ -45,14 +50,17 @@
 
 class SettingsWindowManagerTest : public InProcessBrowserTest {
  public:
-  SettingsWindowManagerTest() : test_profile_(NULL) {
-    chrome::SettingsWindowManager::GetInstance()->AddObserver(&observer_);
+  SettingsWindowManagerTest()
+      : settings_manager_(chrome::SettingsWindowManager::GetInstance()),
+        test_profile_(NULL) {
+    settings_manager_->AddObserver(&observer_);
   }
   virtual ~SettingsWindowManagerTest() {
-    chrome::SettingsWindowManager::GetInstance()->RemoveObserver(&observer_);
+    settings_manager_->RemoveObserver(&observer_);
   }
 
   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+    command_line->AppendSwitch(::switches::kEnableSettingsWindow);
     command_line->AppendSwitch(::switches::kMultiProfiles);
   }
 
@@ -83,6 +91,11 @@
     }
   }
 
+  void ShowSettingsForProfile(Profile* profile) {
+    settings_manager_->ShowChromePageForProfile(
+        profile, GURL(chrome::kChromeUISettingsURL));
+  }
+
   void CloseBrowserSynchronously(Browser* browser) {
     content::WindowedNotificationObserver observer(
         chrome::NOTIFICATION_BROWSER_CLOSED,
@@ -91,7 +104,20 @@
     observer.Wait();
   }
 
+  void CloseNonDefaultBrowsers() {
+    std::list<Browser*> browsers_to_close;
+    for (chrome::BrowserIterator it; !it.done(); it.Next()) {
+      if (*it != browser())
+        browsers_to_close.push_back(*it);
+    }
+    for (std::list<Browser*>::iterator iter = browsers_to_close.begin();
+         iter != browsers_to_close.end(); ++iter) {
+      CloseBrowserSynchronously(*iter);
+    }
+  }
+
  protected:
+  chrome::SettingsWindowManager* settings_manager_;
   SettingsWindowTestObserver observer_;
   base::ScopedTempDir temp_profile_dir_;
   Profile* test_profile_;  // Owned by g_browser_process->profile_manager()
@@ -101,32 +127,29 @@
 
 
 IN_PROC_BROWSER_TEST_F(SettingsWindowManagerTest, OpenSettingsWindow) {
-  chrome::SettingsWindowManager* settings_manager =
-      chrome::SettingsWindowManager::GetInstance();
-
   // Open a settings window.
-  settings_manager->ShowForProfile(browser()->profile(), std::string());
+  ShowSettingsForProfile(browser()->profile());
   Browser* settings_browser =
-      settings_manager->FindBrowserForProfile(browser()->profile());
+      settings_manager_->FindBrowserForProfile(browser()->profile());
   ASSERT_TRUE(settings_browser);
   // Ensure the observer fired correctly.
   EXPECT_EQ(1u, observer_.new_settings_count());
   EXPECT_EQ(settings_browser, observer_.browser());
 
   // Open the settings again: no new window.
-  settings_manager->ShowForProfile(browser()->profile(), std::string());
+  ShowSettingsForProfile(browser()->profile());
   EXPECT_EQ(settings_browser,
-            settings_manager->FindBrowserForProfile(browser()->profile()));
+            settings_manager_->FindBrowserForProfile(browser()->profile()));
   EXPECT_EQ(1u, observer_.new_settings_count());
 
   // Close the settings window.
   CloseBrowserSynchronously(settings_browser);
-  EXPECT_FALSE(settings_manager->FindBrowserForProfile(browser()->profile()));
+  EXPECT_FALSE(settings_manager_->FindBrowserForProfile(browser()->profile()));
 
   // Open a new settings window.
-  settings_manager->ShowForProfile(browser()->profile(), std::string());
+  ShowSettingsForProfile(browser()->profile());
   Browser* settings_browser2 =
-      settings_manager->FindBrowserForProfile(browser()->profile());
+      settings_manager_->FindBrowserForProfile(browser()->profile());
   ASSERT_TRUE(settings_browser2);
   EXPECT_EQ(2u, observer_.new_settings_count());
 
@@ -135,24 +158,22 @@
 
 #if !defined(OS_CHROMEOS)
 IN_PROC_BROWSER_TEST_F(SettingsWindowManagerTest, SettingsWindowMultiProfile) {
-  chrome::SettingsWindowManager* settings_manager =
-      chrome::SettingsWindowManager::GetInstance();
   Profile* test_profile = CreateTestProfile();
   ASSERT_TRUE(test_profile);
 
   // Open a settings window.
-  settings_manager->ShowForProfile(browser()->profile(), std::string());
+  ShowSettingsForProfile(browser()->profile());
   Browser* settings_browser =
-      settings_manager->FindBrowserForProfile(browser()->profile());
+      settings_manager_->FindBrowserForProfile(browser()->profile());
   ASSERT_TRUE(settings_browser);
   // Ensure the observer fired correctly.
   EXPECT_EQ(1u, observer_.new_settings_count());
   EXPECT_EQ(settings_browser, observer_.browser());
 
   // Open a settings window for a new profile.
-  settings_manager->ShowForProfile(test_profile, std::string());
+  ShowSettingsForProfile(test_profile);
   Browser* settings_browser2 =
-      settings_manager->FindBrowserForProfile(test_profile);
+      settings_manager_->FindBrowserForProfile(test_profile);
   ASSERT_TRUE(settings_browser2);
   // Ensure the observer fired correctly.
   EXPECT_EQ(2u, observer_.new_settings_count());
@@ -162,3 +183,30 @@
   CloseBrowserSynchronously(settings_browser2);
 }
 #endif
+
+IN_PROC_BROWSER_TEST_F(SettingsWindowManagerTest, OpenSettingsChromePages) {
+  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
+
+  // Settings should open a new browser window.
+  chrome::ShowSettings(browser());
+  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
+
+  // History should open a new browser window.
+  CloseNonDefaultBrowsers();
+  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
+  chrome::ShowHistory(browser());
+  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
+
+  // Extensions should open a new browser window.
+  CloseNonDefaultBrowsers();
+  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
+  std::string extension_to_highlight;  // none
+  chrome::ShowExtensions(browser(), extension_to_highlight);
+  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
+
+  // Downloads should NOT open a new browser window.
+  CloseNonDefaultBrowsers();
+  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
+  chrome::ShowDownloads(browser());
+  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
+}
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc
index c22ed67..74d9db6 100644
--- a/chrome/browser/ui/startup/startup_browser_creator.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -425,8 +425,11 @@
     // This call can (in rare circumstances) block the UI thread.
     // Allow it until this bug is fixed.
     //  http://code.google.com/p/chromium/issues/detail?id=60641
-    GURL url;
-    {
+    GURL url = GURL(param.MaybeAsASCII());
+    // http://crbug.com/371030: Only use URLFixerUpper if we don't have a valid
+    // URL, otherwise we will look in the current directory for a file named
+    // 'about' if the browser was started with a about:foo argument.
+    if (!url.is_valid()) {
       base::ThreadRestrictions::ScopedAllowIO allow_io;
       url = URLFixerUpper::FixupRelativeFile(cur_dir, param);
     }
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
index f281cc0..9ea079f 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -88,7 +88,6 @@
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
@@ -494,7 +493,7 @@
       *out_app_contents = tab_in_app_window;
 
     // Platform apps fire off a launch event which may or may not open a window.
-    return (tab_in_app_window != NULL || extension->is_platform_app());
+    return (tab_in_app_window != NULL || CanLaunchViaEvent(extension));
   }
 
   if (url_string.empty())
diff --git a/chrome/browser/ui/sync/one_click_signin_helper.cc b/chrome/browser/ui/sync/one_click_signin_helper.cc
index 82c0af5..7e4fdfe 100644
--- a/chrome/browser/ui/sync/one_click_signin_helper.cc
+++ b/chrome/browser/ui/sync/one_click_signin_helper.cc
@@ -74,7 +74,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/frame_navigate_params.h"
 #include "content/public/common/page_transition_types.h"
 #include "google_apis/gaia/gaia_auth_util.h"
@@ -427,7 +426,7 @@
   virtual ~CurrentHistoryCleaner();
 
   // content::WebContentsObserver:
-  virtual void WebContentsDestroyed(content::WebContents* contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
   virtual void DidCommitProvisionalLoadForFrame(
       int64 frame_id,
       const base::string16& frame_unique_name,
@@ -480,8 +479,7 @@
   }
 }
 
-void CurrentHistoryCleaner::WebContentsDestroyed(
-    content::WebContents* contents) {
+void CurrentHistoryCleaner::WebContentsDestroyed() {
   delete this;  // Failure.
 }
 
@@ -664,6 +662,7 @@
                                 refresh_token, start_mode_,
                                 args_.web_contents,
                                 args_.confirmation_required,
+                                GURL(),
                                 args_.callback);
 }
 
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_observer.cc b/chrome/browser/ui/sync/one_click_signin_sync_observer.cc
index 376baeb..96c45c5 100644
--- a/chrome/browser/ui/sync/one_click_signin_sync_observer.cc
+++ b/chrome/browser/ui/sync/one_click_signin_sync_observer.cc
@@ -51,9 +51,8 @@
 
 OneClickSigninSyncObserver::~OneClickSigninSyncObserver() {}
 
-void OneClickSigninSyncObserver::WebContentsDestroyed(
-    content::WebContents* web_contents) {
-  ProfileSyncService* sync_service = GetSyncService(web_contents);
+void OneClickSigninSyncObserver::WebContentsDestroyed() {
+  ProfileSyncService* sync_service = GetSyncService(web_contents());
   if (sync_service)
     sync_service->RemoveObserver(this);
 
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_observer.h b/chrome/browser/ui/sync/one_click_signin_sync_observer.h
index 7d53a77..23dca83 100644
--- a/chrome/browser/ui/sync/one_click_signin_sync_observer.h
+++ b/chrome/browser/ui/sync/one_click_signin_sync_observer.h
@@ -31,7 +31,7 @@
 
  private:
   // content::WebContentsObserver:
-  virtual void WebContentsDestroyed(content::WebContents* contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // ProfileSyncServiceObserver:
   virtual void OnStateChanged() OVERRIDE;
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
index afcddd8..2353921 100644
--- a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
+++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
@@ -31,6 +31,7 @@
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/sync/one_click_signin_sync_observer.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
@@ -53,14 +54,17 @@
     StartSyncMode start_mode,
     content::WebContents* web_contents,
     ConfirmationRequired confirmation_required,
+    const GURL& continue_url,
     Callback sync_setup_completed_callback)
     : content::WebContentsObserver(web_contents),
       start_mode_(start_mode),
       desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE),
       confirmation_required_(confirmation_required),
+      continue_url_(continue_url),
       sync_setup_completed_callback_(sync_setup_completed_callback),
       weak_pointer_factory_(this) {
   DCHECK(profile);
+  DCHECK(web_contents || continue_url.is_empty());
   BrowserList::AddObserver(this);
 
   Initialize(profile, browser);
@@ -400,9 +404,17 @@
     case SHOW_SETTINGS_WITHOUT_CONFIGURE:
       ShowSettingsPage(false);  // Don't show sync config UI.
       break;
-    default:
+    case UNDO_SYNC:
       NOTREACHED();
   }
+
+  // Navigate to the |continue_url_| if one is set, unless the user first needs
+  // to configure Sync.
+  if (web_contents() && !continue_url_.is_empty() &&
+      start_mode_ != CONFIGURE_SYNC_FIRST) {
+    LoadContinueUrl();
+  }
+
   delete this;
 }
 
@@ -483,12 +495,15 @@
         }
       }
     } else {
-      // Sync is disabled - just display the settings page.
+      // Sync is disabled - just display the settings page or redirect to the
+      // |continue_url_|.
       FinishProfileSyncServiceSetup();
-      if (use_same_tab)
-        ShowSettingsPageInWebContents(web_contents(), std::string());
-      else
+      if (!use_same_tab)
         chrome::ShowSettings(browser_);
+      else if (!continue_url_.is_empty())
+        LoadContinueUrl();
+      else
+        ShowSettingsPageInWebContents(web_contents(), std::string());
     }
   }
 }
@@ -510,6 +525,12 @@
 void OneClickSigninSyncStarter::ShowSettingsPageInWebContents(
     content::WebContents* contents,
     const std::string& sub_page) {
+  if (!continue_url_.is_empty()) {
+    // The observer deletes itself once it's done.
+    DCHECK(!sub_page.empty());
+    new OneClickSigninSyncObserver(contents, continue_url_);
+  }
+
   GURL url = chrome::GetSettingsUrl(sub_page);
   content::OpenURLParams params(url,
                                 content::Referrer(),
@@ -525,3 +546,11 @@
   browser->tab_strip_model()->ActivateTabAt(content_index,
                                             false /* user_gesture */);
 }
+
+void OneClickSigninSyncStarter::LoadContinueUrl() {
+  web_contents()->GetController().LoadURL(
+      continue_url_,
+      content::Referrer(),
+      content::PAGE_TRANSITION_AUTO_TOPLEVEL,
+      std::string());
+}
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.h b/chrome/browser/ui/sync/one_click_signin_sync_starter.h
index e01ce23..be0b51c 100644
--- a/chrome/browser/ui/sync/one_click_signin_sync_starter.h
+++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.h
@@ -78,6 +78,9 @@
   // signin before signin completes.
   // |web_contents| is used to show the sync UI if it's showing a blank page
   // and not about to be closed. It can be NULL.
+  // If |web_contents| is non-NULL and the |continue_url| is non-empty, the
+  // |web_contents| will be navigated to the |continue_url| once both signin and
+  // Sync setup are complete.
   // |callback| is always executed before OneClickSigninSyncStarter is deleted.
   // It can be empty.
   OneClickSigninSyncStarter(Profile* profile,
@@ -88,6 +91,7 @@
                             StartSyncMode start_mode,
                             content::WebContents* web_contents,
                             ConfirmationRequired display_confirmation,
+                            const GURL& continue_url,
                             Callback callback);
 
   // chrome::BrowserListObserver override.
@@ -102,12 +106,9 @@
 
  private:
   friend class OneClickSigninSyncStarterTest;
-  FRIEND_TEST_ALL_PREFIXES(OneClickSigninSyncStarterTest,
-                           CallbackSigninFailed);
-  FRIEND_TEST_ALL_PREFIXES(OneClickSigninSyncStarterTest,
-                           CallbackSigninSucceeded);
-  FRIEND_TEST_ALL_PREFIXES(OneClickSigninSyncStarterTest,
-                           CallbackNull);
+  FRIEND_TEST_ALL_PREFIXES(OneClickSigninSyncStarterTest, CallbackSigninFailed);
+  FRIEND_TEST_ALL_PREFIXES(OneClickSigninSyncStarterTest, CallbackNull);
+  FRIEND_TEST_ALL_PREFIXES(OneClickSigninSyncStarterTest, LoadContinueUrl);
 
   virtual ~OneClickSigninSyncStarter();
 
@@ -202,6 +203,9 @@
   // the default "You are signed in" message is displayed.
   void DisplayFinalConfirmationBubble(const base::string16& custom_message);
 
+  // Loads the |continue_url_| in the current tab.
+  void LoadContinueUrl();
+
   Profile* profile_;
   Browser* browser_;
   scoped_ptr<SigninTracker> signin_tracker_;
@@ -209,6 +213,7 @@
   chrome::HostDesktopType desktop_type_;
   bool force_same_tab_navigation_;
   ConfirmationRequired confirmation_required_;
+  GURL continue_url_;
 
   // Callback executed when sync setup succeeds or fails.
   Callback sync_setup_completed_callback_;
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc
index 446b363..9dd7773 100644
--- a/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc
+++ b/chrome/browser/ui/sync/one_click_signin_sync_starter_unittest.cc
@@ -11,7 +11,10 @@
 #include "chrome/browser/signin/fake_signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -19,30 +22,23 @@
 const char* kTestingUsername = "fake_username";
 }  // namespace
 
-class OneClickSigninSyncStarterTest : public testing::Test {
+class OneClickSigninSyncStarterTest : public ChromeRenderViewHostTestHarness {
  public:
   OneClickSigninSyncStarterTest()
       : sync_starter_(NULL),
         failed_count_(0),
         succeeded_count_(0) {}
 
-  // testing::Test:
+  // ChromeRenderViewHostTestHarness:
   virtual void SetUp() OVERRIDE {
-    testing::Test::SetUp();
-
-    // Create the sign in manager required by OneClickSigninSyncStarter.
-    TestingProfile::Builder builder;
-    builder.AddTestingFactory(
-        SigninManagerFactory::GetInstance(),
-        &OneClickSigninSyncStarterTest::BuildSigninManager);
-    profile_ = builder.Build();
-
-    SigninManagerBase* signin_manager = static_cast<FakeSigninManager*>(
-        SigninManagerFactory::GetForProfile(profile_.get()));
+    ChromeRenderViewHostTestHarness::SetUp();
 
     // Disable sync to simplify the creation of a OneClickSigninSyncStarter.
     CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSync);
 
+    SigninManagerBase* signin_manager = static_cast<FakeSigninManager*>(
+        SigninManagerFactory::GetForProfile(profile()));
+
     signin_manager->Initialize(NULL);
     signin_manager->SetAuthenticatedUsername(kTestingUsername);
   }
@@ -54,24 +50,32 @@
       ++failed_count_;
   }
 
+  // ChromeRenderViewHostTestHarness:
+  virtual content::BrowserContext* CreateBrowserContext() OVERRIDE {
+    // Create the sign in manager required by OneClickSigninSyncStarter.
+    TestingProfile::Builder builder;
+    builder.AddTestingFactory(
+        SigninManagerFactory::GetInstance(),
+        &OneClickSigninSyncStarterTest::BuildSigninManager);
+    return builder.Build().release();
+  }
+
  protected:
-  void CreateSyncStarter(OneClickSigninSyncStarter::Callback callback) {
+  void CreateSyncStarter(OneClickSigninSyncStarter::Callback callback,
+                         const GURL& continue_url) {
     sync_starter_ = new OneClickSigninSyncStarter(
-        profile_.get(),
+        profile(),
         NULL,
         kTestingUsername,
         std::string(),
         "refresh_token",
         OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS,
-        NULL,
+        web_contents(),
         OneClickSigninSyncStarter::NO_CONFIRMATION,
+        continue_url,
         callback);
   }
 
-  content::TestBrowserThreadBundle thread_bundle_;
-
-  scoped_ptr<TestingProfile> profile_;
-
   // Deletes itself when SigninFailed() or SigninSuccess() is called.
   OneClickSigninSyncStarter* sync_starter_;
 
@@ -92,7 +96,8 @@
 // Verifies that the callback is invoked when sync setup fails.
 TEST_F(OneClickSigninSyncStarterTest, CallbackSigninFailed) {
   CreateSyncStarter(base::Bind(&OneClickSigninSyncStarterTest::Callback,
-                               base::Unretained(this)));
+                               base::Unretained(this)),
+                    GURL());
   sync_starter_->SigninFailed(GoogleServiceAuthError(
       GoogleServiceAuthError::REQUEST_CANCELED));
   EXPECT_EQ(1, failed_count_);
@@ -101,9 +106,24 @@
 
 // Verifies that there is no crash when the callback is NULL.
 TEST_F(OneClickSigninSyncStarterTest, CallbackNull) {
-  CreateSyncStarter(OneClickSigninSyncStarter::Callback());
+  CreateSyncStarter(OneClickSigninSyncStarter::Callback(), GURL());
   sync_starter_->SigninFailed(GoogleServiceAuthError(
       GoogleServiceAuthError::REQUEST_CANCELED));
   EXPECT_EQ(0, failed_count_);
   EXPECT_EQ(0, succeeded_count_);
 }
+
+// Verifies that the continue URL is loaded once signin completes.
+TEST_F(OneClickSigninSyncStarterTest, LoadContinueUrl) {
+  content::NavigationController& controller = web_contents()->GetController();
+  EXPECT_FALSE(controller.GetPendingEntry());
+
+  const GURL kTestURL = GURL("http://www.example.com");
+  CreateSyncStarter(base::Bind(&OneClickSigninSyncStarterTest::Callback,
+                               base::Unretained(this)),
+                    kTestURL);
+  sync_starter_->MergeSessionComplete(
+      GoogleServiceAuthError(GoogleServiceAuthError::NONE));
+  EXPECT_EQ(1, succeeded_count_);
+  EXPECT_EQ(kTestURL, controller.GetPendingEntry()->GetURL());
+}
diff --git a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
index 13067c4..e9bfc44 100644
--- a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
+++ b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
@@ -20,7 +20,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/browser/history/history_service.h"
@@ -30,6 +29,7 @@
 #include "chrome/test/base/testing_pref_service_syncable.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "components/user_prefs/pref_registry_syncable.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/ui/tab_contents/core_tab_helper.cc b/chrome/browser/ui/tab_contents/core_tab_helper.cc
index 99f93b2..d30bbaf 100644
--- a/chrome/browser/ui/tab_contents/core_tab_helper.cc
+++ b/chrome/browser/ui/tab_contents/core_tab_helper.cc
@@ -150,7 +150,7 @@
       web_contents()->GetRenderProcessHost()->GetID());
 }
 
-void CoreTabHelper::WebContentsDestroyed(WebContents* web_contents) {
+void CoreTabHelper::WebContentsDestroyed() {
   // OnCloseStarted isn't called in unit tests.
   if (!close_start_time_.is_null()) {
     bool fast_tab_close_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/chrome/browser/ui/tab_contents/core_tab_helper.h b/chrome/browser/ui/tab_contents/core_tab_helper.h
index a5ca820..e01482b 100644
--- a/chrome/browser/ui/tab_contents/core_tab_helper.h
+++ b/chrome/browser/ui/tab_contents/core_tab_helper.h
@@ -59,8 +59,7 @@
   virtual void DidStartLoading(
       content::RenderViewHost* render_view_host) OVERRIDE;
   virtual void WasShown() OVERRIDE;
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
   virtual void BeforeUnloadFired(const base::TimeTicks& proceed_time) OVERRIDE;
   virtual void BeforeUnloadDialogCancelled() OVERRIDE;
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index 9866e5a..05924e3 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -46,7 +46,7 @@
 #include "chrome/browser/safe_browsing/safe_browsing_tab_observer.h"
 #include "chrome/browser/thumbnails/thumbnail_tab_helper.h"
 #include "chrome/browser/ui/hung_plugin_tab_helper.h"
-#include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h"
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/pdf/pdf_tab_helper.h"
 #include "chrome/browser/ui/sad_tab_helper.h"
 #include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
@@ -154,7 +154,7 @@
       web_contents);
   extensions::WebNavigationTabObserver::CreateForWebContents(web_contents);
   HungPluginTabHelper::CreateForWebContents(web_contents);
-  ManagePasswordsBubbleUIController::CreateForWebContents(web_contents);
+  ManagePasswordsUIController::CreateForWebContents(web_contents);
   NavigationTimeHelper::CreateForWebContents(web_contents);
   PDFTabHelper::CreateForWebContents(web_contents);
   PermissionBubbleManager::CreateForWebContents(web_contents);
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc
index 02c2ccd..098d89d 100644
--- a/chrome/browser/ui/tabs/tab_strip_model.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -26,8 +26,6 @@
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
-
 using base::UserMetricsAction;
 using content::WebContents;
 
@@ -75,7 +73,7 @@
 
    private:
     // WebContentsObserver:
-    virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
+    virtual void WebContentsDestroyed() OVERRIDE {
       parent_->OnWebContentsDestroyed(this);
     }
 
@@ -163,7 +161,7 @@
  private:
   // Make sure that if someone deletes this WebContents out from under us, it
   // is properly removed from the tab strip.
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // The WebContents being tracked by this WebContentsData. The
   // WebContentsObserver does keep a reference, but when the WebContents is
@@ -226,13 +224,12 @@
   Observe(contents);
 }
 
-void TabStripModel::WebContentsData::WebContentsDestroyed(
-    WebContents* web_contents) {
-  DCHECK_EQ(contents_, web_contents);
+void TabStripModel::WebContentsData::WebContentsDestroyed() {
+  DCHECK_EQ(contents_, web_contents());
 
   // Note that we only detach the contents here, not close it - it's
   // already been closed. We just want to undo our bookkeeping.
-  int index = tab_strip_model_->GetIndexOfWebContents(web_contents);
+  int index = tab_strip_model_->GetIndexOfWebContents(web_contents());
   DCHECK_NE(TabStripModel::kNoTab, index);
   tab_strip_model_->DetachWebContentsAt(index);
 }
@@ -840,7 +837,7 @@
   if (WebContents* old_contents = GetActiveWebContents()) {
     if ((add_types & ADD_ACTIVE) == 0) {
       apps::ResizeWebContents(contents,
-                              old_contents->GetView()->GetContainerSize());
+                              old_contents->GetContainerBounds().size());
     }
   }
 }
diff --git a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
index 4c43196..1bbfaea 100644
--- a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
@@ -58,7 +58,7 @@
         tab_strip_(tab_strip) {
   }
 
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     WebContents* tab_to_delete = tab_to_delete_;
     tab_to_delete_ = NULL;
     TabStripModel* tab_strip_to_delete = tab_strip_;
diff --git a/chrome/browser/ui/toolbar/origin_chip_info.cc b/chrome/browser/ui/toolbar/origin_chip_info.cc
index 3026af8..84572f9 100644
--- a/chrome/browser/ui/toolbar/origin_chip_info.cc
+++ b/chrome/browser/ui/toolbar/origin_chip_info.cc
@@ -144,6 +144,10 @@
   return true;
 }
 
+base::string16 OriginChipInfo::Tooltip() const {
+  return base::UTF8ToUTF16(displayed_url_.spec());
+}
+
 // static
 bool OriginChip::IsMalware(const GURL& url, const content::WebContents* tab) {
   DCHECK(tab);
diff --git a/chrome/browser/ui/toolbar/origin_chip_info.h b/chrome/browser/ui/toolbar/origin_chip_info.h
index 9217924..d50f48b 100644
--- a/chrome/browser/ui/toolbar/origin_chip_info.h
+++ b/chrome/browser/ui/toolbar/origin_chip_info.h
@@ -33,6 +33,9 @@
   // Returns the label to be displayed by the origin chip.
   const base::string16& label() const { return label_; }
 
+  // Returns the tooltip to be used for the origin chip.
+  base::string16 Tooltip() const;
+
   // Returns the ID of the icon to be displayed by the origin chip. Note that
   // if |owner_|'s OnExtensionIconImageChanged() method was called with
   // anything else than NULL, that icon has precedence over whatever this method
diff --git a/chrome/browser/ui/toolbar/origin_chip_info_unittest.cc b/chrome/browser/ui/toolbar/origin_chip_info_unittest.cc
index 100469f..82df8aa 100644
--- a/chrome/browser/ui/toolbar/origin_chip_info_unittest.cc
+++ b/chrome/browser/ui/toolbar/origin_chip_info_unittest.cc
@@ -108,6 +108,7 @@
   SetURL(kExampleUrl, true);
 
   EXPECT_EQ(base::ASCIIToUTF16("example.com"), info()->label());
+  EXPECT_EQ(base::ASCIIToUTF16(kExampleUrl), info()->Tooltip());
   EXPECT_EQ(url(), info()->displayed_url());
   EXPECT_EQ(ToolbarModel::NONE, info()->security_level());
 }
@@ -118,22 +119,27 @@
   SetURL(kExampleUrlSecure, true);
 
   EXPECT_EQ(base::ASCIIToUTF16("Example [US] example.com"), info()->label());
+  EXPECT_EQ(base::ASCIIToUTF16(kExampleUrlSecure), info()->Tooltip());
   EXPECT_EQ(url(), info()->displayed_url());
   EXPECT_EQ(ToolbarModel::EV_SECURE, info()->security_level());
 }
 
 TEST_F(OriginChipInfoTest, ChromeOrigin) {
-  SetURL("chrome://version", true);
+  const char kChromeOrigin1[] = "chrome://version/";
+  SetURL(kChromeOrigin1, true);
 
   EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_TITLE),
             info()->label());
+  EXPECT_EQ(base::ASCIIToUTF16(kChromeOrigin1), info()->Tooltip());
   EXPECT_EQ(url(), info()->displayed_url());
   EXPECT_EQ(IDR_PRODUCT_LOGO_16, info()->icon());
 
   // chrome://flags has no title, so the title should be the product name.
-  SetURL("chrome://flags", true);
+  const char kChromeOrigin2[] = "chrome://flags/";
+  SetURL(kChromeOrigin2, true);
 
   EXPECT_EQ(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME), info()->label());
+  EXPECT_EQ(base::ASCIIToUTF16(kChromeOrigin2), info()->Tooltip());
   EXPECT_EQ(url(), info()->displayed_url());
   EXPECT_EQ(IDR_PRODUCT_LOGO_16, info()->icon());
 
@@ -167,9 +173,12 @@
   const extensions::IconImage* null_image = NULL;
 
   // Navigate to a URL from that extension.
-  SetURL(base::StringPrintf("chrome-extension://%s/index.html", kFooId), true);
+  const std::string extension_origin =
+      base::StringPrintf("chrome-extension://%s/index.html", kFooId);
+  SetURL(extension_origin, true);
   EXPECT_NE(null_image, icon_image());
   EXPECT_EQ(base::ASCIIToUTF16(kFooName), info()->label());
+  EXPECT_EQ(base::ASCIIToUTF16(extension_origin), info()->Tooltip());
 
   SetURL(kExampleUrl, true);
   EXPECT_EQ(null_image, icon_image());
diff --git a/chrome/browser/ui/toolbar/wrench_menu_model.cc b/chrome/browser/ui/toolbar/wrench_menu_model.cc
index 13dc110..b49610d 100644
--- a/chrome/browser/ui/toolbar/wrench_menu_model.cc
+++ b/chrome/browser/ui/toolbar/wrench_menu_model.cc
@@ -514,7 +514,7 @@
   AddSubMenuWithStringId(IDC_BOOKMARKS_MENU, IDS_BOOKMARKS_MENU,
                          bookmark_sub_menu_model_.get());
 
-  if (chrome::IsInstantExtendedAPIEnabled()) {
+  if (!browser_->profile()->IsOffTheRecord()) {
     recent_tabs_sub_menu_model_.reset(new RecentTabsSubMenuModel(provider_,
                                                                  browser_,
                                                                  NULL));
diff --git a/chrome/browser/ui/unload_controller.h b/chrome/browser/ui/unload_controller.h
index 33651c0..db64891 100644
--- a/chrome/browser/ui/unload_controller.h
+++ b/chrome/browser/ui/unload_controller.h
@@ -18,7 +18,7 @@
 
 namespace content {
 class NotificationSource;
-class NotifictaionDetails;
+class NotificationDetails;
 class WebContents;
 }
 
diff --git a/chrome/browser/ui/view_ids.h b/chrome/browser/ui/view_ids.h
index db53ca2..f02b67a 100644
--- a/chrome/browser/ui/view_ids.h
+++ b/chrome/browser/ui/view_ids.h
@@ -66,7 +66,6 @@
 
   // Find in page.
   VIEW_ID_FIND_IN_PAGE_TEXT_FIELD,
-  VIEW_ID_FIND_IN_PAGE,
 
   // Tab Container window.
   VIEW_ID_TAB_CONTAINER,
diff --git a/chrome/browser/ui/views/accessibility/invert_bubble_view.cc b/chrome/browser/ui/views/accessibility/invert_bubble_view.cc
index 151b8b8..028ec32 100644
--- a/chrome/browser/ui/views/accessibility/invert_bubble_view.cc
+++ b/chrome/browser/ui/views/accessibility/invert_bubble_view.cc
@@ -125,7 +125,6 @@
   // user to close it explicitly, which should be okay because it affects
   // a small minority of users, and only once.
   set_close_on_deactivate(false);
-  set_move_with_anchor(true);
 }
 
 void InvertBubbleView::LinkClicked(views::Link* source, int event_flags) {
diff --git a/chrome/browser/ui/views/app_list/linux/app_list_controller_delegate_linux.cc b/chrome/browser/ui/views/app_list/linux/app_list_controller_delegate_linux.cc
deleted file mode 100644
index e3ed29a..0000000
--- a/chrome/browser/ui/views/app_list/linux/app_list_controller_delegate_linux.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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.
-
-#include "chrome/browser/ui/views/app_list/linux/app_list_controller_delegate_linux.h"
-
-#include "chrome/browser/ui/views/app_list/linux/app_list_service_linux.h"
-
-AppListControllerDelegateLinux::AppListControllerDelegateLinux(
-    AppListServiceLinux* service)
-    : AppListControllerDelegateImpl(service),
-      service_(service) {
-}
-
-AppListControllerDelegateLinux::~AppListControllerDelegateLinux() {}
-
-void AppListControllerDelegateLinux::ViewClosing() {
-  service_->OnViewBeingDestroyed();
-}
-
-void AppListControllerDelegateLinux::OnShowExtensionPrompt() {
-  service_->set_can_close(false);
-}
-
-void AppListControllerDelegateLinux::OnCloseExtensionPrompt() {
-  service_->set_can_close(true);
-}
-
-bool AppListControllerDelegateLinux::CanDoCreateShortcutsFlow() {
-  return true;
-}
diff --git a/chrome/browser/ui/views/app_list/linux/app_list_controller_delegate_linux.h b/chrome/browser/ui/views/app_list/linux/app_list_controller_delegate_linux.h
deleted file mode 100644
index 2235aa6..0000000
--- a/chrome/browser/ui/views/app_list/linux/app_list_controller_delegate_linux.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_APP_LIST_LINUX_APP_LIST_CONTROLLER_DELEGATE_LINUX_H_
-#define CHROME_BROWSER_UI_VIEWS_APP_LIST_LINUX_APP_LIST_CONTROLLER_DELEGATE_LINUX_H_
-
-#include "base/files/file_path.h"
-#include "chrome/browser/ui/app_list/app_list_controller_delegate_impl.h"
-#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/native_widget_types.h"
-
-class AppListServiceLinux;
-class Profile;
-
-namespace extensions {
-class Extension;
-}
-
-// Linux-specific configuration and behaviour for the AppList.
-class AppListControllerDelegateLinux : public AppListControllerDelegateImpl {
- public:
-  explicit AppListControllerDelegateLinux(AppListServiceLinux* service);
-  virtual ~AppListControllerDelegateLinux();
-
-  // AppListControllerDelegate overrides:
-  virtual void ViewClosing() OVERRIDE;
-  virtual void OnShowExtensionPrompt() OVERRIDE;
-  virtual void OnCloseExtensionPrompt() OVERRIDE;
-  virtual bool CanDoCreateShortcutsFlow() OVERRIDE;
-
- private:
-  AppListServiceLinux* service_;
-
-  DISALLOW_COPY_AND_ASSIGN(AppListControllerDelegateLinux);
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_APP_LIST_LINUX_APP_LIST_CONTROLLER_DELEGATE_LINUX_H_
diff --git a/chrome/browser/ui/views/app_list/linux/app_list_linux.cc b/chrome/browser/ui/views/app_list/linux/app_list_linux.cc
index 87716c4..e513121 100644
--- a/chrome/browser/ui/views/app_list/linux/app_list_linux.cc
+++ b/chrome/browser/ui/views/app_list/linux/app_list_linux.cc
@@ -4,30 +4,12 @@
 
 #include "chrome/browser/ui/views/app_list/linux/app_list_linux.h"
 
-#include "base/command_line.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/thread_task_runner_handle.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/app_list/app_list_positioner.h"
 #include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/views/app_list_view.h"
 #include "ui/gfx/screen.h"
 #include "ui/views/linux_ui/linux_ui.h"
 #include "ui/views/widget/widget.h"
 
-AppListLinux::AppListLinux(app_list::AppListView* view,
-                           const base::Closure& on_should_dismiss)
-    : view_(view),
-      window_icon_updated_(false),
-      on_should_dismiss_(on_should_dismiss) {
-  view_->AddObserver(this);
-}
-
-AppListLinux::~AppListLinux() {
-  view_->RemoveObserver(this);
-}
-
 // static
 AppListPositioner::ScreenEdge AppListLinux::ShelfLocationInDisplay(
     const gfx::Display& display) {
@@ -71,11 +53,12 @@
 gfx::Point AppListLinux::FindAnchorPoint(const gfx::Size& view_size,
                                          const gfx::Display& display,
                                          const gfx::Point& cursor,
-                                         AppListPositioner::ScreenEdge edge) {
+                                         AppListPositioner::ScreenEdge edge,
+                                         bool center_window) {
   AppListPositioner positioner(display, view_size, 0);
 
-  // The experimental app list is placed in the center of the screen.
-  if (app_list::switches::IsExperimentalAppListPositionEnabled())
+  // Special case for app list in the center of the screen.
+  if (center_window)
     return positioner.GetAnchorPointForScreenCenter();
 
   gfx::Point anchor;
@@ -98,26 +81,14 @@
   return positioner.GetAnchorPointForShelfCursor(edge, cursor);
 }
 
-void AppListLinux::Show() {
-  view_->GetWidget()->Show();
-  if (!window_icon_updated_) {
-    view_->GetWidget()->GetTopLevelWidget()->UpdateWindowIcon();
-    window_icon_updated_ = true;
-  }
-  view_->GetWidget()->Activate();
-}
-
-void AppListLinux::Hide() {
-  view_->GetWidget()->Hide();
-}
-
-void AppListLinux::MoveNearCursor() {
+// static
+void AppListLinux::MoveNearCursor(app_list::AppListView* view) {
   gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
   gfx::Screen* screen =
-      gfx::Screen::GetScreenFor(view_->GetWidget()->GetNativeView());
+      gfx::Screen::GetScreenFor(view->GetWidget()->GetNativeView());
   gfx::Display display = screen->GetDisplayNearestPoint(cursor);
 
-  view_->SetBubbleArrow(views::BubbleBorder::FLOAT);
+  view->SetBubbleArrow(views::BubbleBorder::FLOAT);
 
   // In the Unity desktop environment, special case SCREEN_EDGE_LEFT. It is
   // always on the left side in Unity, but ShelfLocationInDisplay will not
@@ -131,32 +102,9 @@
     edge = AppListPositioner::SCREEN_EDGE_LEFT;
   else
     edge = ShelfLocationInDisplay(display);
-  view_->SetAnchorPoint(
-      FindAnchorPoint(view_->GetPreferredSize(), display, cursor, edge));
-}
-
-bool AppListLinux::IsVisible() {
-  return view_->GetWidget()->IsVisible();
-}
-
-void AppListLinux::Prerender() {
-  view_->Prerender();
-}
-
-gfx::NativeWindow AppListLinux::GetWindow() {
-  return view_->GetWidget()->GetNativeWindow();
-}
-
-void AppListLinux::SetProfile(Profile* profile) {
-  view_->SetProfileByPath(profile->GetPath());
-}
-
-void AppListLinux::OnActivationChanged(
-    views::Widget* /*widget*/, bool active) {
-  if (active)
-    return;
-
-  // Call |on_should_dismiss_| asynchronously. This must be done asynchronously
-  // or our caller will crash, as it expects the app list to remain alive.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, on_should_dismiss_);
+  view->SetAnchorPoint(FindAnchorPoint(view->GetPreferredSize(),
+                                       display,
+                                       cursor,
+                                       edge,
+                                       view->ShouldCenterWindow()));
 }
diff --git a/chrome/browser/ui/views/app_list/linux/app_list_linux.h b/chrome/browser/ui/views/app_list/linux/app_list_linux.h
index 68046d3..1640b53 100644
--- a/chrome/browser/ui/views/app_list/linux/app_list_linux.h
+++ b/chrome/browser/ui/views/app_list/linux/app_list_linux.h
@@ -5,10 +5,7 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_APP_LIST_LINUX_APP_LIST_LINUX_H_
 #define CHROME_BROWSER_UI_VIEWS_APP_LIST_LINUX_APP_LIST_LINUX_H_
 
-#include "base/callback.h"
-#include "chrome/browser/ui/app_list/app_list.h"
 #include "chrome/browser/ui/app_list/app_list_positioner.h"
-#include "ui/app_list/views/app_list_view_observer.h"
 
 namespace app_list {
 class AppListView;
@@ -20,16 +17,10 @@
 class Size;
 }  // namespace gfx
 
-// Responsible for positioning, hiding and showing an AppListView on Linux.
-// This includes watching window activation/deactivation messages to determine
-// if the user has clicked away from it.
-class AppListLinux : public AppList,
-                     public app_list::AppListViewObserver {
+// Responsible for positioning an AppListView on Linux.
+// TODO(tapted): Shouldn't be a class - move the static member functions out.
+class AppListLinux {
  public:
-  AppListLinux(app_list::AppListView* view,
-               const base::Closure& on_should_dismiss);
-  virtual ~AppListLinux();
-
   // Determines which screen edge the shelf is aligned to. This tries to find
   // the edge of the surface where the user normally launches apps from (so, for
   // example, on Gnome Classic, this is the applications menu, not the taskbar).
@@ -44,29 +35,10 @@
   static gfx::Point FindAnchorPoint(const gfx::Size& view_size,
                                     const gfx::Display& display,
                                     const gfx::Point& cursor,
-                                    AppListPositioner::ScreenEdge edge);
+                                    AppListPositioner::ScreenEdge edge,
+                                    bool center_window);
 
-  // AppList:
-  virtual void Show() OVERRIDE;
-  virtual void Hide() OVERRIDE;
-  virtual void MoveNearCursor() OVERRIDE;
-  virtual bool IsVisible() OVERRIDE;
-  virtual void Prerender() OVERRIDE;
-  virtual gfx::NativeWindow GetWindow() OVERRIDE;
-  virtual void SetProfile(Profile* profile) OVERRIDE;
-
-  // app_list::AppListViewObserver:
-  virtual void OnActivationChanged(views::Widget* widget, bool active) OVERRIDE;
-
- private:
-  // Weak pointer. The view manages its own lifetime.
-  app_list::AppListView* view_;
-  bool window_icon_updated_;
-
-  // Called to request |view_| be closed.
-  base::Closure on_should_dismiss_;
-
-  DISALLOW_COPY_AND_ASSIGN(AppListLinux);
+  static void MoveNearCursor(app_list::AppListView* view);
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_APP_LIST_LINUX_APP_LIST_LINUX_H_
diff --git a/chrome/browser/ui/views/app_list/linux/app_list_linux_unittest.cc b/chrome/browser/ui/views/app_list/linux/app_list_linux_unittest.cc
index a701353..beafb90 100644
--- a/chrome/browser/ui/views/app_list/linux/app_list_linux_unittest.cc
+++ b/chrome/browser/ui/views/app_list/linux/app_list_linux_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/views/app_list/linux/app_list_linux.h"
 
+#include "base/logging.h"
 #include "chrome/browser/ui/app_list/app_list_positioner.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/display.h"
@@ -52,6 +53,7 @@
     display_.set_work_area(
         gfx::Rect(0, kMenuBarSize, kScreenWidth, kScreenHeight - kMenuBarSize));
     cursor_ = gfx::Point();
+    center_window_ = false;
   }
 
   // Set the display work area.
@@ -100,6 +102,10 @@
     cursor_ = gfx::Point(x, y);
   }
 
+  void EnableWindowCentering() {
+    center_window_ = true;
+  }
+
   AppListPositioner::ScreenEdge ShelfEdge() const {
     return AppListLinux::ShelfLocationInDisplay(display_);
   }
@@ -108,12 +114,14 @@
     return AppListLinux::FindAnchorPoint(gfx::Size(kWindowWidth, kWindowHeight),
                                          display_,
                                          cursor_,
-                                         ShelfEdge());
+                                         ShelfEdge(),
+                                         center_window_);
   }
 
  private:
   gfx::Display display_;
   gfx::Point cursor_;
+  bool center_window_;
 };
 
 TEST_F(AppListLinuxUnitTest, ShelfLocationInDisplay) {
@@ -239,3 +247,13 @@
                        kScreenHeight - kShelfSize - kWindowHeight / 2),
             DoFindAnchorPoint());
 }
+
+TEST_F(AppListLinuxUnitTest, FindAnchorPointCentered) {
+  // Cursor on the top shelf; enable centered app list mode.
+  PlaceShelf(AppListPositioner::SCREEN_EDGE_TOP);
+  PlaceCursor(0, 0);
+  EnableWindowCentering();
+  // Expect the app list to be in the center of the screen (ignore the cursor).
+  EXPECT_EQ(gfx::Point(kScreenWidth / 2, kScreenHeight / 2),
+            DoFindAnchorPoint());
+}
diff --git a/chrome/browser/ui/views/app_list/linux/app_list_service_linux.cc b/chrome/browser/ui/views/app_list/linux/app_list_service_linux.cc
index 16b19ce..c4e45f0 100644
--- a/chrome/browser/ui/views/app_list/linux/app_list_service_linux.cc
+++ b/chrome/browser/ui/views/app_list/linux/app_list_service_linux.cc
@@ -5,14 +5,11 @@
 #include "chrome/browser/ui/views/app_list/linux/app_list_service_linux.h"
 
 #include "base/memory/singleton.h"
+#include "base/thread_task_runner_handle.h"
 #include "chrome/browser/shell_integration.h"
 #include "chrome/browser/shell_integration_linux.h"
-#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
-#include "chrome/browser/ui/app_list/app_list_factory.h"
-#include "chrome/browser/ui/app_list/app_list_shower.h"
-#include "chrome/browser/ui/app_list/app_list_view_delegate.h"
-#include "chrome/browser/ui/app_list/scoped_keep_alive.h"
-#include "chrome/browser/ui/views/app_list/linux/app_list_controller_delegate_linux.h"
+#include "chrome/browser/ui/app_list/app_list_controller_delegate_views.h"
+#include "chrome/browser/ui/app_list/app_list_shower_views.h"
 #include "chrome/browser/ui/views/app_list/linux/app_list_linux.h"
 #include "content/public/browser/browser_thread.h"
 #include "grit/chromium_strings.h"
@@ -20,42 +17,9 @@
 #include "ui/app_list/app_list_constants.h"
 #include "ui/app_list/views/app_list_view.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/screen.h"
 
 namespace {
 
-class AppListFactoryLinux : public AppListFactory {
- public:
-  explicit AppListFactoryLinux(AppListServiceLinux* service)
-      : service_(service) {}
-  virtual ~AppListFactoryLinux() {}
-
-  virtual AppList* CreateAppList(
-      Profile* profile,
-      AppListService* service,
-      const base::Closure& on_should_dismiss) OVERRIDE {
-    // The view delegate will be owned by the app list view. The app list view
-    // manages it's own lifetime.
-    AppListViewDelegate* view_delegate = new AppListViewDelegate(
-        profile, service->GetControllerDelegate());
-    app_list::AppListView* view = new app_list::AppListView(view_delegate);
-    gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
-    view->InitAsBubbleAtFixedLocation(NULL,
-                                      &pagination_model_,
-                                      cursor,
-                                      views::BubbleBorder::FLOAT,
-                                      false /* border_accepts_events */);
-    return new AppListLinux(view, on_should_dismiss);
-  }
-
- private:
-  // PaginationModel that is shared across all views.
-  app_list::PaginationModel pagination_model_;
-  AppListServiceLinux* service_;
-
-  DISALLOW_COPY_AND_ASSIGN(AppListFactoryLinux);
-};
-
 void CreateShortcuts() {
   std::string app_list_title =
       l10n_util::GetStringUTF8(IDS_APP_LIST_SHORTCUT_NAME);
@@ -77,65 +41,41 @@
                    LeakySingletonTraits<AppListServiceLinux> >::get();
 }
 
-void AppListServiceLinux::set_can_close(bool can_close) {
-  shower_->set_can_close(can_close);
-}
-
-void AppListServiceLinux::OnViewBeingDestroyed() {
-  shower_->HandleViewBeingDestroyed();
-}
-
-void AppListServiceLinux::Init(Profile* initial_profile) {
-  PerformStartupChecks(initial_profile);
-}
-
-void AppListServiceLinux::CreateForProfile(Profile* requested_profile) {
-  shower_->CreateViewForProfile(requested_profile);
-}
-
-void AppListServiceLinux::ShowForProfile(Profile* requested_profile) {
-  DCHECK(requested_profile);
-  if (requested_profile->IsManaged())
-    return;
-
-  ScopedKeepAlive keep_alive;
-
-  InvalidatePendingProfileLoads();
-  SetProfilePath(requested_profile->GetPath());
-  shower_->ShowForProfile(requested_profile);
-  RecordAppListLaunch();
-}
-
-void AppListServiceLinux::DismissAppList() {
-  shower_->DismissAppList();
-}
-
-bool AppListServiceLinux::IsAppListVisible() const {
-  return shower_->IsAppListVisible();
-}
-
-gfx::NativeWindow AppListServiceLinux::GetAppListWindow() {
-  return shower_->GetWindow();
-}
-
-Profile* AppListServiceLinux::GetCurrentAppListProfile() {
-  return shower_->profile();
-}
-
-AppListControllerDelegate* AppListServiceLinux::GetControllerDelegate() {
-  return controller_delegate_.get();
-}
-
 void AppListServiceLinux::CreateShortcut() {
   content::BrowserThread::PostTask(
       content::BrowserThread::FILE, FROM_HERE, base::Bind(&CreateShortcuts));
 }
 
+void AppListServiceLinux::OnActivationChanged(views::Widget* /*widget*/,
+                                              bool active) {
+  if (active)
+    return;
+
+  // Dismiss the app list asynchronously. This must be done asynchronously
+  // or our caller will crash, as it expects the app list to remain alive.
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::Bind(&AppListServiceLinux::DismissAppList, base::Unretained(this)));
+}
+
 AppListServiceLinux::AppListServiceLinux()
-    : shower_(new AppListShower(
-          scoped_ptr<AppListFactory>(new AppListFactoryLinux(this)),
-          this)),
-      controller_delegate_(new AppListControllerDelegateLinux(this)) {
+    : AppListServiceViews(scoped_ptr<AppListControllerDelegate>(
+          new AppListControllerDelegateViews(this))) {}
+
+void AppListServiceLinux::OnViewCreated() {
+  shower().app_list()->AddObserver(this);
+}
+
+void AppListServiceLinux::OnViewBeingDestroyed() {
+  shower().app_list()->RemoveObserver(this);
+  AppListServiceViews::OnViewBeingDestroyed();
+}
+
+void AppListServiceLinux::OnViewDismissed() {
+}
+
+void AppListServiceLinux::MoveNearCursor(app_list::AppListView* view) {
+  AppListLinux::MoveNearCursor(view);
 }
 
 // static
diff --git a/chrome/browser/ui/views/app_list/linux/app_list_service_linux.h b/chrome/browser/ui/views/app_list/linux/app_list_service_linux.h
index 81a2046..1dc35f2 100644
--- a/chrome/browser/ui/views/app_list/linux/app_list_service_linux.h
+++ b/chrome/browser/ui/views/app_list/linux/app_list_service_linux.h
@@ -5,44 +5,36 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_APP_LIST_LINUX_APP_LIST_SERVICE_LINUX_H_
 #define CHROME_BROWSER_UI_VIEWS_APP_LIST_LINUX_APP_LIST_SERVICE_LINUX_H_
 
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/ui/app_list/app_list_service_impl.h"
+#include "chrome/browser/ui/app_list/app_list_service_views.h"
+#include "ui/app_list/views/app_list_view_observer.h"
 
 template <typename T> struct DefaultSingletonTraits;
 
-class AppListShower;
-
 // AppListServiceLinux manages global resources needed for the app list to
 // operate, and controls when the app list is opened and closed.
-class AppListServiceLinux : public AppListServiceImpl {
+class AppListServiceLinux : public AppListServiceViews,
+                            public app_list::AppListViewObserver {
  public:
   virtual ~AppListServiceLinux();
 
   static AppListServiceLinux* GetInstance();
-  void set_can_close(bool can_close);
-  void OnViewBeingDestroyed();
-
-  // AppListService overrides:
-  virtual void Init(Profile* initial_profile) OVERRIDE;
-  virtual void CreateForProfile(Profile* requested_profile) OVERRIDE;
-  virtual void ShowForProfile(Profile* requested_profile) OVERRIDE;
-  virtual void DismissAppList() OVERRIDE;
-  virtual bool IsAppListVisible() const OVERRIDE;
-  virtual gfx::NativeWindow GetAppListWindow() OVERRIDE;
-  virtual Profile* GetCurrentAppListProfile() OVERRIDE;
-  virtual AppListControllerDelegate* GetControllerDelegate() OVERRIDE;
 
   // AppListServiceImpl overrides:
   virtual void CreateShortcut() OVERRIDE;
 
+  // app_list::AppListViewObserver overrides:
+  virtual void OnActivationChanged(views::Widget* widget, bool active) OVERRIDE;
+
  private:
   friend struct DefaultSingletonTraits<AppListServiceLinux>;
 
-  AppListServiceLinux();
+  // AppListShowerDelegate overrides:
+  virtual void OnViewCreated() OVERRIDE;
+  virtual void OnViewBeingDestroyed() OVERRIDE;
+  virtual void OnViewDismissed() OVERRIDE;
+  virtual void MoveNearCursor(app_list::AppListView* view) OVERRIDE;
 
-  // Responsible for putting views on the screen.
-  scoped_ptr<AppListShower> shower_;
-  scoped_ptr<AppListControllerDelegate> controller_delegate_;
+  AppListServiceLinux();
 
   DISALLOW_COPY_AND_ASSIGN(AppListServiceLinux);
 };
diff --git a/chrome/browser/ui/views/app_list/win/activation_tracker_win.cc b/chrome/browser/ui/views/app_list/win/activation_tracker_win.cc
index 932fc7e..f4ab2fe 100644
--- a/chrome/browser/ui/views/app_list/win/activation_tracker_win.cc
+++ b/chrome/browser/ui/views/app_list/win/activation_tracker_win.cc
@@ -5,6 +5,8 @@
 #include "chrome/browser/ui/views/app_list/win/activation_tracker_win.h"
 
 #include "base/time/time.h"
+#include "chrome/browser/ui/app_list/app_list_shower_views.h"
+#include "chrome/browser/ui/views/app_list/win/app_list_service_win.h"
 #include "ui/app_list/views/app_list_view.h"
 #include "ui/views/widget/widget.h"
 
@@ -16,17 +18,15 @@
 
 }  // namespace
 
-ActivationTrackerWin::ActivationTrackerWin(
-    app_list::AppListView* view,
-    const base::Closure& on_should_dismiss)
-    : view_(view),
-      on_should_dismiss_(on_should_dismiss),
+ActivationTrackerWin::ActivationTrackerWin(AppListServiceWin* service)
+    : service_(service),
       taskbar_has_focus_(false) {
-  view_->AddObserver(this);
+  service_->shower().app_list()->AddObserver(this);
 }
 
 ActivationTrackerWin::~ActivationTrackerWin() {
-  view_->RemoveObserver(this);
+  DCHECK(service_->shower().app_list());
+  service_->shower().app_list()->RemoveObserver(this);
   timer_.Stop();
 }
 
@@ -51,7 +51,7 @@
   if (!ShouldDismissAppList())
     return;
 
-  on_should_dismiss_.Run();
+  service_->DismissAppList();
 }
 
 bool ActivationTrackerWin::ShouldDismissAppList() {
@@ -92,7 +92,8 @@
   while (focused_hwnd) {
     // If the focused window is the right click menu (called a jump list) or
     // the app list, don't hide the launcher.
-    if (focused_hwnd == jump_list_hwnd || focused_hwnd == view_->GetHWND())
+    HWND app_list_hwnd = service_->shower().app_list()->GetHWND();
+    if (focused_hwnd == jump_list_hwnd || focused_hwnd == app_list_hwnd)
       return false;
 
     if (focused_hwnd == taskbar_hwnd) {
diff --git a/chrome/browser/ui/views/app_list/win/activation_tracker_win.h b/chrome/browser/ui/views/app_list/win/activation_tracker_win.h
index e347624..1fed8d4 100644
--- a/chrome/browser/ui/views/app_list/win/activation_tracker_win.h
+++ b/chrome/browser/ui/views/app_list/win/activation_tracker_win.h
@@ -5,20 +5,16 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_APP_LIST_WIN_ACTIVATION_TRACKER_WIN_H_
 #define CHROME_BROWSER_UI_VIEWS_APP_LIST_WIN_ACTIVATION_TRACKER_WIN_H_
 
-#include "base/basictypes.h"
-#include "base/callback.h"
+#include "base/macros.h"
 #include "base/timer/timer.h"
 #include "ui/app_list/views/app_list_view_observer.h"
 
-namespace app_list {
-class AppListView;
-}
+class AppListServiceWin;
 
 // Periodically checks to see if an AppListView has lost focus using a timer.
 class ActivationTrackerWin : public app_list::AppListViewObserver {
  public:
-  ActivationTrackerWin(app_list::AppListView* view,
-                       const base::Closure& on_should_dismiss);
+  explicit ActivationTrackerWin(AppListServiceWin* service);
   ~ActivationTrackerWin();
 
   // app_list::AppListViewObserver:
@@ -37,11 +33,7 @@
   // app list).
   bool ShouldDismissAppList();
 
-  // The window to track the active state of.
-  app_list::AppListView* view_;
-
-  // Called to request |view_| be closed.
-  base::Closure on_should_dismiss_;
+  AppListServiceWin* service_;  // Weak. Owns this.
 
   // Records whether, on the previous timer tick, the taskbar had focus without
   // the right mouse button being down. We allow the taskbar to have focus for
diff --git a/chrome/browser/ui/views/app_list/win/app_list_controller_delegate_win.cc b/chrome/browser/ui/views/app_list/win/app_list_controller_delegate_win.cc
index 222f4c7..4b21517 100644
--- a/chrome/browser/ui/views/app_list/win/app_list_controller_delegate_win.cc
+++ b/chrome/browser/ui/views/app_list/win/app_list_controller_delegate_win.cc
@@ -7,17 +7,15 @@
 #include "apps/app_window.h"
 #include "apps/app_window_registry.h"
 #include "chrome/browser/metro_utils/metro_chrome_win.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/app_list_icon_win.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/browser/ui/host_desktop.h"
-#include "chrome/browser/ui/views/app_list/win/app_list_service_win.h"
-#include "extensions/common/extension.h"
 #include "ui/base/resource/resource_bundle.h"
 
 AppListControllerDelegateWin::AppListControllerDelegateWin(
-    AppListServiceWin* service)
-    : AppListControllerDelegateImpl(service),
-      service_(service) {}
+    AppListServiceViews* service)
+    : AppListControllerDelegateViews(service) {}
 
 AppListControllerDelegateWin::~AppListControllerDelegateWin() {}
 
@@ -25,28 +23,12 @@
   return true;
 }
 
-void AppListControllerDelegateWin::ViewClosing() {
-  service_->OnViewBeingDestroyed();
-}
-
 gfx::ImageSkia AppListControllerDelegateWin::GetWindowIcon() {
   gfx::ImageSkia* resource = ResourceBundle::GetSharedInstance().
       GetImageSkiaNamed(GetAppListIconResourceId());
   return *resource;
 }
 
-void AppListControllerDelegateWin::OnShowExtensionPrompt() {
-  service_->set_can_close(false);
-}
-
-void AppListControllerDelegateWin::OnCloseExtensionPrompt() {
-  service_->set_can_close(true);
-}
-
-bool AppListControllerDelegateWin::CanDoCreateShortcutsFlow() {
-  return true;
-}
-
 void AppListControllerDelegateWin::FillLaunchParams(AppLaunchParams* params) {
   params->desktop_type = chrome::HOST_DESKTOP_TYPE_NATIVE;
   apps::AppWindow* any_existing_window =
diff --git a/chrome/browser/ui/views/app_list/win/app_list_controller_delegate_win.h b/chrome/browser/ui/views/app_list/win/app_list_controller_delegate_win.h
index c67cb57..34d42e9 100644
--- a/chrome/browser/ui/views/app_list/win/app_list_controller_delegate_win.h
+++ b/chrome/browser/ui/views/app_list/win/app_list_controller_delegate_win.h
@@ -5,38 +5,22 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_APP_LIST_WIN_APP_LIST_CONTROLLER_DELEGATE_WIN_H_
 #define CHROME_BROWSER_UI_VIEWS_APP_LIST_WIN_APP_LIST_CONTROLLER_DELEGATE_WIN_H_
 
-#include "base/files/file_path.h"
-#include "chrome/browser/ui/app_list/app_list_controller_delegate_impl.h"
-#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/native_widget_types.h"
-
-class AppListServiceWin;
-class Profile;
-
-namespace extensions {
-class Extension;
-}
+#include "chrome/browser/ui/app_list/app_list_controller_delegate_views.h"
 
 // Windows specific configuration and behaviour for the AppList.
-class AppListControllerDelegateWin : public AppListControllerDelegateImpl {
+class AppListControllerDelegateWin : public AppListControllerDelegateViews {
  public:
-  explicit AppListControllerDelegateWin(AppListServiceWin* service);
+  explicit AppListControllerDelegateWin(AppListServiceViews* service);
   virtual ~AppListControllerDelegateWin();
 
   // AppListControllerDelegate overrides:
   virtual bool ForceNativeDesktop() const OVERRIDE;
-  virtual void ViewClosing() OVERRIDE;
   virtual gfx::ImageSkia GetWindowIcon() OVERRIDE;
-  virtual void OnShowExtensionPrompt() OVERRIDE;
-  virtual void OnCloseExtensionPrompt() OVERRIDE;
-  virtual bool CanDoCreateShortcutsFlow() OVERRIDE;
 
  private:
   // AppListcontrollerDelegateImpl:
   virtual void FillLaunchParams(AppLaunchParams* params) OVERRIDE;
 
-  AppListServiceWin* service_;
-
   DISALLOW_COPY_AND_ASSIGN(AppListControllerDelegateWin);
 };
 
diff --git a/chrome/browser/ui/views/app_list/win/app_list_service_win.cc b/chrome/browser/ui/views/app_list/win/app_list_service_win.cc
index f5ac4fc..b213b93 100644
--- a/chrome/browser/ui/views/app_list/win/app_list_service_win.cc
+++ b/chrome/browser/ui/views/app_list/win/app_list_service_win.cc
@@ -26,12 +26,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/shell_integration.h"
-#include "chrome/browser/ui/app_list/app_list.h"
-#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
-#include "chrome/browser/ui/app_list/app_list_factory.h"
-#include "chrome/browser/ui/app_list/app_list_shower.h"
-#include "chrome/browser/ui/app_list/app_list_view_delegate.h"
-#include "chrome/browser/ui/app_list/scoped_keep_alive.h"
 #include "chrome/browser/ui/ash/app_list/app_list_service_ash.h"
 #include "chrome/browser/ui/views/app_list/win/activation_tracker_win.h"
 #include "chrome/browser/ui/views/app_list/win/app_list_controller_delegate_win.h"
@@ -47,7 +41,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "ui/app_list/views/app_list_view.h"
 #include "ui/base/win/shell.h"
-#include "ui/gfx/screen.h"
 
 // static
 AppListService* AppListService::Get(chrome::HostDesktopType desktop_type) {
@@ -249,43 +242,6 @@
   ui::win::SetAppIconForWindow(icon_path, hwnd);
 }
 
-class AppListFactoryWin : public AppListFactory {
- public:
-  explicit AppListFactoryWin(AppListServiceWin* service)
-      : service_(service) {
-  }
-
-  virtual ~AppListFactoryWin() {
-  }
-
-  virtual AppList* CreateAppList(
-      Profile* profile,
-      AppListService* service,
-      const base::Closure& on_should_dismiss) OVERRIDE {
-    // The view delegate will be owned by the app list view. The app list view
-    // manages it's own lifetime.
-    AppListViewDelegate* view_delegate =
-        new AppListViewDelegate(profile,
-                                service->GetControllerDelegate());
-    app_list::AppListView* view = new app_list::AppListView(view_delegate);
-    gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
-    view->InitAsBubbleAtFixedLocation(NULL,
-                                      &pagination_model_,
-                                      cursor,
-                                      views::BubbleBorder::FLOAT,
-                                      false /* border_accepts_events */);
-    SetWindowAttributes(view->GetHWND());
-    return new AppListWin(view, on_should_dismiss);
-  }
-
- private:
-  // PaginationModel that is shared across all views.
-  app_list::PaginationModel pagination_model_;
-  AppListServiceWin* service_;
-
-  DISALLOW_COPY_AND_ASSIGN(AppListFactoryWin);
-};
-
 }  // namespace
 
 // static
@@ -295,54 +251,18 @@
 }
 
 AppListServiceWin::AppListServiceWin()
-    : enable_app_list_on_next_init_(false),
-      shower_(new AppListShower(
-          scoped_ptr<AppListFactory>(new AppListFactoryWin(this)),
-          this)),
-      controller_delegate_(new AppListControllerDelegateWin(this)) {
+    : AppListServiceViews(scoped_ptr<AppListControllerDelegate>(
+          new AppListControllerDelegateWin(this))),
+      enable_app_list_on_next_init_(false) {
 }
 
 AppListServiceWin::~AppListServiceWin() {
 }
 
-void AppListServiceWin::set_can_close(bool can_close) {
-  shower_->set_can_close(can_close);
-}
-
-gfx::NativeWindow AppListServiceWin::GetAppListWindow() {
-  return shower_->GetWindow();
-}
-
-Profile* AppListServiceWin::GetCurrentAppListProfile() {
-  return shower_->profile();
-}
-
-AppListControllerDelegate* AppListServiceWin::GetControllerDelegate() {
-  return controller_delegate_.get();
-}
-
 void AppListServiceWin::ShowForProfile(Profile* requested_profile) {
-  DCHECK(requested_profile);
-  if (requested_profile->IsManaged())
-    return;
-
-  ScopedKeepAlive keep_alive;
-
+  AppListServiceViews::ShowForProfile(requested_profile);
   content::BrowserThread::PostBlockingPoolTask(
       FROM_HERE, base::Bind(SetDidRunForNDayActiveStats));
-
-  InvalidatePendingProfileLoads();
-  SetProfilePath(requested_profile->GetPath());
-  shower_->ShowForProfile(requested_profile);
-  RecordAppListLaunch();
-}
-
-void AppListServiceWin::DismissAppList() {
-  shower_->DismissAppList();
-}
-
-void AppListServiceWin::OnViewBeingDestroyed() {
-  shower_->HandleViewBeingDestroyed();
 }
 
 void AppListServiceWin::OnLoadProfileForWarmup(Profile* initial_profile) {
@@ -350,7 +270,7 @@
     return;
 
   base::Time before_warmup(base::Time::Now());
-  shower_->WarmupForProfile(initial_profile);
+  shower().WarmupForProfile(initial_profile);
   UMA_HISTOGRAM_TIMES("Apps.AppListWarmupDuration",
                       base::Time::Now() - before_warmup);
 }
@@ -380,15 +300,7 @@
   ScheduleWarmup();
 
   MigrateAppLauncherEnabledPref();
-  PerformStartupChecks(initial_profile);
-}
-
-void AppListServiceWin::CreateForProfile(Profile* profile) {
-  shower_->CreateViewForProfile(profile);
-}
-
-bool AppListServiceWin::IsAppListVisible() const {
-  return shower_->IsAppListVisible();
+  AppListServiceViews::Init(initial_profile);
 }
 
 void AppListServiceWin::CreateShortcut() {
@@ -430,7 +342,7 @@
 
   // We only need to initialize the view if there's no view already created and
   // there's no profile loading to be shown.
-  return !shower_->HasView() && !profile_loader().IsAnyProfileLoading();
+  return !shower().HasView() && !profile_loader().IsAnyProfileLoading();
 }
 
 void AppListServiceWin::LoadProfileForWarmup() {
@@ -445,3 +357,21 @@
       base::Bind(&AppListServiceWin::OnLoadProfileForWarmup,
                  base::Unretained(this)));
 }
+
+void AppListServiceWin::OnViewBeingDestroyed() {
+  activation_tracker_.reset();
+  AppListServiceViews::OnViewBeingDestroyed();
+}
+
+void AppListServiceWin::OnViewCreated() {
+  SetWindowAttributes(shower().app_list()->GetHWND());
+  activation_tracker_.reset(new ActivationTrackerWin(this));
+}
+
+void AppListServiceWin::OnViewDismissed() {
+  activation_tracker_->OnViewHidden();
+}
+
+void AppListServiceWin::MoveNearCursor(app_list::AppListView* view) {
+  AppListWin::MoveNearCursor(view);
+}
diff --git a/chrome/browser/ui/views/app_list/win/app_list_service_win.h b/chrome/browser/ui/views/app_list/win/app_list_service_win.h
index e4d0069..6181a74 100644
--- a/chrome/browser/ui/views/app_list/win/app_list_service_win.h
+++ b/chrome/browser/ui/views/app_list/win/app_list_service_win.h
@@ -6,36 +6,23 @@
 #define CHROME_BROWSER_UI_VIEWS_APP_LIST_WIN_APP_LIST_SERVICE_WIN_H_
 
 #include "base/memory/scoped_ptr.h"
-#include "chrome/browser/ui/app_list/app_list_service_impl.h"
+#include "chrome/browser/ui/app_list/app_list_service_views.h"
 
-namespace app_list{
-class AppListModel;
-}
+class ActivationTrackerWin;
 
-class AppListControllerDelegateWin;
-class AppListShower;
 template <typename T> struct DefaultSingletonTraits;
 
-class AppListServiceWin : public AppListServiceImpl {
+class AppListServiceWin : public AppListServiceViews {
  public:
-  AppListServiceWin();
   virtual ~AppListServiceWin();
 
   static AppListServiceWin* GetInstance();
-  void set_can_close(bool can_close);
-  void OnViewBeingDestroyed();
 
   // AppListService overrides:
   virtual void SetAppListNextPaintCallback(void (*callback)()) OVERRIDE;
   virtual void HandleFirstRun() OVERRIDE;
   virtual void Init(Profile* initial_profile) OVERRIDE;
-  virtual void CreateForProfile(Profile* requested_profile) OVERRIDE;
   virtual void ShowForProfile(Profile* requested_profile) OVERRIDE;
-  virtual void DismissAppList() OVERRIDE;
-  virtual bool IsAppListVisible() const OVERRIDE;
-  virtual gfx::NativeWindow GetAppListWindow() OVERRIDE;
-  virtual Profile* GetCurrentAppListProfile() OVERRIDE;
-  virtual AppListControllerDelegate* GetControllerDelegate() OVERRIDE;
 
   // AppListServiceImpl overrides:
   virtual void CreateShortcut() OVERRIDE;
@@ -43,6 +30,16 @@
  private:
   friend struct DefaultSingletonTraits<AppListServiceWin>;
 
+  // AppListServiceViews overrides:
+  virtual void OnViewBeingDestroyed();
+
+  // AppListShowerDelegate overrides:
+  virtual void OnViewCreated() OVERRIDE;
+  virtual void OnViewDismissed() OVERRIDE;
+  virtual void MoveNearCursor(app_list::AppListView* view) OVERRIDE;
+
+  AppListServiceWin();
+
   bool IsWarmupNeeded();
   void ScheduleWarmup();
 
@@ -54,11 +51,7 @@
   void OnLoadProfileForWarmup(Profile* initial_profile);
 
   bool enable_app_list_on_next_init_;
-
-  // Responsible for putting views on the screen.
-  scoped_ptr<AppListShower> shower_;
-
-  scoped_ptr<AppListControllerDelegateWin> controller_delegate_;
+  scoped_ptr<ActivationTrackerWin> activation_tracker_;
 
   DISALLOW_COPY_AND_ASSIGN(AppListServiceWin);
 };
diff --git a/chrome/browser/ui/views/app_list/win/app_list_win.cc b/chrome/browser/ui/views/app_list/win/app_list_win.cc
index c96ab6d..f2d4e82 100644
--- a/chrome/browser/ui/views/app_list/win/app_list_win.cc
+++ b/chrome/browser/ui/views/app_list/win/app_list_win.cc
@@ -4,8 +4,6 @@
 
 #include "chrome/browser/ui/views/app_list/win/app_list_win.h"
 
-#include "base/command_line.h"
-#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/app_list_positioner.h"
 #include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/views/app_list_view.h"
@@ -44,18 +42,12 @@
 
 }  // namespace
 
-AppListWin::AppListWin(app_list::AppListView* view,
-                       const base::Closure& on_should_dismiss)
-    : view_(view),
-      activation_tracker_(view, on_should_dismiss),
-      window_icon_updated_(false) {}
-
-AppListWin::~AppListWin() {}
-
+// static
 gfx::Point AppListWin::FindAnchorPoint(const gfx::Size& view_size,
                                        const gfx::Display& display,
                                        const gfx::Point& cursor,
-                                       const gfx::Rect& taskbar_rect) {
+                                       const gfx::Rect& taskbar_rect,
+                                       bool center_window) {
   AppListPositioner positioner(display, view_size, kMinDistanceFromEdge);
 
   // Subtract the taskbar area since the display's default work_area will not
@@ -63,8 +55,8 @@
   // never overlap the taskbar.
   positioner.WorkAreaSubtract(taskbar_rect);
 
-  // The experimental app list is placed in the center of the screen.
-  if (app_list::switches::IsExperimentalAppListPositionEnabled())
+  // Special case for app list in the center of the screen.
+  if (center_window)
     return positioner.GetAnchorPointForScreenCenter();
 
   // Find which edge of the screen the taskbar is attached to.
@@ -85,45 +77,19 @@
   return positioner.GetAnchorPointForShelfCursor(edge, cursor);
 }
 
-void AppListWin::Show() {
-  view_->GetWidget()->Show();
-  if (!window_icon_updated_) {
-    view_->GetWidget()->GetTopLevelWidget()->UpdateWindowIcon();
-    window_icon_updated_ = true;
-  }
-  view_->GetWidget()->Activate();
-}
-
-void AppListWin::Hide() {
-  view_->GetWidget()->Hide();
-  activation_tracker_.OnViewHidden();
-}
-
-void AppListWin::MoveNearCursor() {
+// static
+void AppListWin::MoveNearCursor(app_list::AppListView* view) {
   gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
   gfx::Screen* screen =
-      gfx::Screen::GetScreenFor(view_->GetWidget()->GetNativeView());
+      gfx::Screen::GetScreenFor(view->GetWidget()->GetNativeView());
   gfx::Display display = screen->GetDisplayNearestPoint(cursor);
 
-  view_->SetBubbleArrow(views::BubbleBorder::FLOAT);
+  view->SetBubbleArrow(views::BubbleBorder::FLOAT);
   gfx::Rect taskbar_rect;
   GetTaskbarRect(&taskbar_rect);
-  view_->SetAnchorPoint(FindAnchorPoint(view_->GetPreferredSize(), display,
-                                        cursor, taskbar_rect));
-}
-
-bool AppListWin::IsVisible() {
-  return view_->GetWidget()->IsVisible();
-}
-
-void AppListWin::Prerender() {
-  view_->Prerender();
-}
-
-gfx::NativeWindow AppListWin::GetWindow() {
-  return view_->GetWidget()->GetNativeWindow();
-}
-
-void AppListWin::SetProfile(Profile* profile) {
-  view_->SetProfileByPath(profile->GetPath());
+  view->SetAnchorPoint(FindAnchorPoint(view->GetPreferredSize(),
+                                       display,
+                                       cursor,
+                                       taskbar_rect,
+                                       view->ShouldCenterWindow()));
 }
diff --git a/chrome/browser/ui/views/app_list/win/app_list_win.h b/chrome/browser/ui/views/app_list/win/app_list_win.h
index 37d5643..95b9903 100644
--- a/chrome/browser/ui/views/app_list/win/app_list_win.h
+++ b/chrome/browser/ui/views/app_list/win/app_list_win.h
@@ -5,26 +5,21 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_APP_LIST_WIN_APP_LIST_WIN_H_
 #define CHROME_BROWSER_UI_VIEWS_APP_LIST_WIN_APP_LIST_WIN_H_
 
-#include "base/callback_forward.h"
-#include "chrome/browser/ui/app_list/app_list.h"
-#include "chrome/browser/ui/views/app_list/win/activation_tracker_win.h"
-#include "ui/app_list/views/app_list_view.h"
+namespace app_list {
+class AppListView;
+}
 
 namespace gfx {
 class Display;
 class Point;
+class Rect;
 class Size;
-}  // namespace gfx
+}
 
-// Responsible for positioning, hiding and showing an AppListView on Windows.
-// This includes watching window activation/deactivation messages to determine
-// if the user has clicked away from it.
-class AppListWin : public AppList {
+// Responsible for positioning an AppListView on Windows.
+// TODO(tapted): Shouldn't be a class - move the static member functions out.
+class AppListWin {
  public:
-  AppListWin(app_list::AppListView* view,
-             const base::Closure& on_should_dismiss);
-  virtual ~AppListWin();
-
   // Finds the position for a window to anchor it to the taskbar. This chooses
   // the most appropriate position for the window based on whether the taskbar
   // exists, the position of the taskbar, and the mouse cursor. Returns the
@@ -33,24 +28,10 @@
   static gfx::Point FindAnchorPoint(const gfx::Size& view_size,
                                     const gfx::Display& display,
                                     const gfx::Point& cursor,
-                                    const gfx::Rect& taskbar_rect);
+                                    const gfx::Rect& taskbar_rect,
+                                    bool center_window);
 
-  // AppList overrides.
-  virtual void Show() OVERRIDE;
-  virtual void Hide() OVERRIDE;
-  virtual void MoveNearCursor() OVERRIDE;
-  virtual bool IsVisible() OVERRIDE;
-  virtual void Prerender() OVERRIDE;
-  virtual gfx::NativeWindow GetWindow() OVERRIDE;
-  virtual void SetProfile(Profile* profile) OVERRIDE;
-
- private:
-  // Weak pointer. The view manages its own lifetime.
-  app_list::AppListView* view_;
-  ActivationTrackerWin activation_tracker_;
-  bool window_icon_updated_;
-
-  DISALLOW_COPY_AND_ASSIGN(AppListWin);
+  static void MoveNearCursor(app_list::AppListView* view);
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_APP_LIST_WIN_APP_LIST_WIN_H_
diff --git a/chrome/browser/ui/views/app_list/win/app_list_win_unittest.cc b/chrome/browser/ui/views/app_list/win/app_list_win_unittest.cc
index 607426e..5ac1ff9 100644
--- a/chrome/browser/ui/views/app_list/win/app_list_win_unittest.cc
+++ b/chrome/browser/ui/views/app_list/win/app_list_win_unittest.cc
@@ -54,6 +54,7 @@
     display_.set_work_area(gfx::Rect(0, 0, kScreenWidth, kScreenHeight));
     cursor_ = gfx::Point();
     taskbar_rect_ = gfx::Rect();
+    center_window_ = false;
   }
 
   // Set the display work area.
@@ -99,17 +100,23 @@
     cursor_ = gfx::Point(x, y);
   }
 
+  void EnableWindowCentering() {
+    center_window_ = true;
+  }
+
   gfx::Point DoFindAnchorPoint() const {
     return AppListWin::FindAnchorPoint(gfx::Size(kWindowWidth, kWindowHeight),
                                        display_,
                                        cursor_,
-                                       taskbar_rect_);
+                                       taskbar_rect_,
+                                       center_window_);
   }
 
  private:
   gfx::Display display_;
   gfx::Point cursor_;
   gfx::Rect taskbar_rect_;
+  bool center_window_;
 };
 
 TEST_F(AppListWinUnitTest, FindAnchorPointNoTaskbar) {
@@ -242,3 +249,13 @@
                      kMinDistanceFromEdge),
       DoFindAnchorPoint());
 }
+
+TEST_F(AppListWinUnitTest, FindAnchorPointCentered) {
+  // Cursor on the top taskbar; enable centered app list mode.
+  PlaceTaskbar(AppListPositioner::SCREEN_EDGE_TOP);
+  PlaceCursor(0, 0);
+  EnableWindowCentering();
+  // Expect the app list to be in the center of the screen (ignore the cursor).
+  EXPECT_EQ(gfx::Point(kScreenWidth / 2, kScreenHeight / 2),
+            DoFindAnchorPoint());
+}
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_tab_unittest.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_tab_unittest.cc
index 495da92..3dded73 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_tab_unittest.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_tab_unittest.cc
@@ -21,31 +21,49 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
 
+namespace {
+
+const char kTestExtensionId[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+
+}  // namespace
+
 using base::FilePath;
 using testing::Contains;
 using testing::Eq;
 
 class AppInfoPermissionsTabTest : public testing::Test {
  protected:
-  AppInfoPermissionsTabTest() : window(NULL) {};
+  AppInfoPermissionsTabTest() : window_(NULL) {};
 
-  gfx::NativeWindow window;
-  TestingProfile profile;
+  scoped_ptr<base::DictionaryValue> ValidAppManifest() {
+    return extensions::DictionaryBuilder()
+        .Set("name", "Test App Name")
+        .Set("version", "2.0")
+        .Set("manifest_version", 2)
+        .Set("app",
+             extensions::DictionaryBuilder().Set(
+                 "background",
+                 extensions::DictionaryBuilder().Set(
+                     "scripts",
+                     extensions::ListBuilder().Append("background.js"))))
+        .Build();
+  }
+
+  gfx::NativeWindow window_;
+  TestingProfile profile_;
 
   // We need the UI thread in order to construct UI elements in the view.
-  content::TestBrowserThreadBundle thread_bundle;
+  content::TestBrowserThreadBundle thread_bundle_;
 };
 
 // Tests that an app with no permissions is treated correctly.
 TEST_F(AppInfoPermissionsTabTest, NoPermissionsObtainedCorrectly) {
   scoped_refptr<const extensions::Extension> app =
       extensions::ExtensionBuilder()
-          .SetManifest(
-               extensions::DictionaryBuilder().Set("name", "Test App Name").Set(
-                   "version", "2.0"))
-          .SetID("cedabbhfglmiikkmdgcpjdkocfcmbkee")
+          .SetManifest(ValidAppManifest())
+          .SetID(kTestExtensionId)
           .Build();
-  AppInfoPermissionsTab tab(window, &profile, app, base::Closure());
+  AppInfoPermissionsTab tab(window_, &profile_, app, base::Closure());
 
   EXPECT_TRUE(tab.GetRequiredPermissions()->IsEmpty());
   EXPECT_TRUE(tab.GetRequiredPermissionMessages().empty());
@@ -62,40 +80,37 @@
 TEST_F(AppInfoPermissionsTabTest, RequiredPermissionsObtainedCorrectly) {
   scoped_refptr<const extensions::Extension> app =
       extensions::ExtensionBuilder()
-          .SetManifest(
-               extensions::DictionaryBuilder()
-                   .Set("name", "Test App Name")
-                   .Set("version", "2.0")
-                   .Set("permissions",
-                        extensions::ListBuilder()
-                            .Append("location")  // A valid permission with a
-                                                 // message
-                            .Append("bad_perm")  // An invalid permission
-                            .Append("browsingData")  // An valid permission with
-                                                     // no message
-                            .Append("tabs")))  // Another valid permission with
-                                               // a message
-          .SetID("cedabbhfglmiikkmdgcpjdkocfcmbkee")
+          .SetManifest(ValidAppManifest())
+          .MergeManifest(extensions::DictionaryBuilder().Set(
+              "permissions",
+              extensions::ListBuilder()
+                  .Append("desktopCapture")  // A valid permission with a
+                                             // message
+                  .Append("bad_perm")        // An invalid permission
+                  .Append("notifications")   // An valid permission with
+                                             // no message
+                  .Append("serial")))        // Another valid permission with
+                                             // a message
+          .SetID(kTestExtensionId)
           .Build();
-  AppInfoPermissionsTab tab(window, &profile, app, base::Closure());
+  AppInfoPermissionsTab tab(window_, &profile_, app, base::Closure());
 
   const extensions::PermissionSet* required_permissions =
       tab.GetRequiredPermissions();
   EXPECT_FALSE(required_permissions->IsEmpty());
-  EXPECT_EQ((size_t)3, required_permissions->GetAPIsAsStrings().size());
+  EXPECT_EQ(3U, required_permissions->GetAPIsAsStrings().size());
 
   EXPECT_TRUE(tab.GetOptionalPermissions()->IsEmpty());
   EXPECT_TRUE(tab.GetRetainedFilePermissions().empty());
 
   const std::vector<base::string16> required_permission_messages =
       tab.GetRequiredPermissionMessages();
-  EXPECT_EQ((size_t)2, required_permission_messages.size());
-  ASSERT_STREQ(l10n_util::GetStringUTF8(
-                   IDS_EXTENSION_PROMPT_WARNING_GEOLOCATION).c_str(),
-               base::UTF16ToUTF8(required_permission_messages[0]).c_str());
-  ASSERT_STREQ(
-      l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_TABS).c_str(),
-      base::UTF16ToUTF8(required_permission_messages[1]).c_str());
+  ASSERT_EQ(2U, required_permission_messages.size());
+  EXPECT_EQ(
+      l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_DESKTOP_CAPTURE),
+      base::UTF16ToUTF8(required_permission_messages[0]));
+  EXPECT_EQ(l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_SERIAL),
+            base::UTF16ToUTF8(required_permission_messages[1]));
 }
 
 // Tests that an app's optional permissions are detected and converted to
@@ -103,40 +118,36 @@
 TEST_F(AppInfoPermissionsTabTest, OptionalPermissionsObtainedCorrectly) {
   scoped_refptr<const extensions::Extension> app =
       extensions::ExtensionBuilder()
-          .SetManifest(
-               extensions::DictionaryBuilder()
-                   .Set("name", "Test App Name")
-                   .Set("version", "2.0")
-                   .Set("optional_permissions",
-                        extensions::ListBuilder()
-                            .Append("bookmarks")  // A valid permission with a
-                                                  // message
-                            .Append("bad_perm")   // An invalid permission
-                            .Append("cookies")    // A valid permission with
-                                                  // no message
-                            .Append("tabs")))  // Another valid permission with
-                                               // a message
-          .SetID("cedabbhfglmiikkmdgcpjdkocfcmbkee")
+          .SetManifest(ValidAppManifest())
+          .MergeManifest(extensions::DictionaryBuilder().Set(
+              "optional_permissions",
+              extensions::ListBuilder()
+                  .Append("clipboardRead")  // A valid permission with a
+                                            // message
+                  .Append("bad_perm")       // An invalid permission
+                  .Append("idle")           // A valid permission with
+                                            // no message
+                  .Append("serial")))       // Another valid permission with
+                                            // a message
+          .SetID(kTestExtensionId)
           .Build();
-  AppInfoPermissionsTab tab(window, &profile, app, base::Closure());
+  AppInfoPermissionsTab tab(window_, &profile_, app, base::Closure());
 
   const extensions::PermissionSet* optional_permissions =
       tab.GetOptionalPermissions();
   EXPECT_FALSE(optional_permissions->IsEmpty());
-  EXPECT_EQ((size_t)3, optional_permissions->GetAPIsAsStrings().size());
+  EXPECT_EQ(3U, optional_permissions->GetAPIsAsStrings().size());
 
   EXPECT_TRUE(tab.GetRequiredPermissions()->IsEmpty());
   EXPECT_TRUE(tab.GetRetainedFilePermissions().empty());
 
   const std::vector<base::string16> optional_permission_messages =
       tab.GetOptionalPermissionMessages();
-  EXPECT_EQ((size_t)2, optional_permission_messages.size());
-  ASSERT_STREQ(
-      l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_BOOKMARKS).c_str(),
-      base::UTF16ToUTF8(optional_permission_messages[0]).c_str());
-  ASSERT_STREQ(
-      l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_TABS).c_str(),
-      base::UTF16ToUTF8(optional_permission_messages[1]).c_str());
+  ASSERT_EQ(2U, optional_permission_messages.size());
+  EXPECT_EQ(l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_CLIPBOARD),
+            base::UTF16ToUTF8(optional_permission_messages[0]));
+  EXPECT_EQ(l10n_util::GetStringUTF8(IDS_EXTENSION_PROMPT_WARNING_SERIAL),
+            base::UTF16ToUTF8(optional_permission_messages[1]));
 }
 
 // Tests that an app's retained files are detected and converted to paths
@@ -144,29 +155,19 @@
 TEST_F(AppInfoPermissionsTabTest, RetainedFilePermissionsObtainedCorrectly) {
   scoped_refptr<const extensions::Extension> app =
       extensions::ExtensionBuilder()
-          .SetManifest(extensions::DictionaryBuilder()
-                           .Set("name", "Test App Name")
-                           .Set("version", "2.0")
-                           .Set("manifest_version", 2)
-                           .Set("app",
-                                extensions::DictionaryBuilder().Set(
-                                    "background",
-                                    extensions::DictionaryBuilder().Set(
-                                        "scripts",
-                                        extensions::ListBuilder().Append(
-                                            "background.js"))))
-                           .Set("permissions",
-                                extensions::ListBuilder().Append(
-                                    extensions::DictionaryBuilder().Set(
-                                        "fileSystem",
-                                        extensions::ListBuilder().Append(
-                                            "retainEntries")))))
-          .SetID("cedabbhfglmiikkmdgcpjdkocfcmbkee")
+          .SetManifest(ValidAppManifest())
+          .MergeManifest(extensions::DictionaryBuilder().Set(
+              "permissions",
+              extensions::ListBuilder().Append(
+                  extensions::DictionaryBuilder().Set(
+                      "fileSystem",
+                      extensions::ListBuilder().Append("retainEntries")))))
+          .SetID(kTestExtensionId)
           .Build();
-  AppInfoPermissionsTab tab(window, &profile, app, base::Closure());
+  AppInfoPermissionsTab tab(window_, &profile_, app, base::Closure());
 
   apps::SavedFilesService* files_service =
-      apps::SavedFilesService::Get(&profile);
+      apps::SavedFilesService::Get(&profile_);
   files_service->RegisterFileEntry(
       app->id(), "file_id_1", FilePath(FILE_PATH_LITERAL("file_1.ext")), false);
   files_service->RegisterFileEntry(
@@ -179,7 +180,7 @@
   const extensions::PermissionSet* required_permissions =
       tab.GetRequiredPermissions();
   EXPECT_FALSE(required_permissions->IsEmpty());
-  EXPECT_EQ((size_t)2, required_permissions->GetAPIsAsStrings().size());
+  EXPECT_EQ(2U, required_permissions->GetAPIsAsStrings().size());
 
   EXPECT_TRUE(tab.GetOptionalPermissions()->IsEmpty());
 
@@ -187,15 +188,12 @@
   // using Contains.
   const std::vector<FilePath> retained_files = tab.GetRetainedFilePermissions();
   std::vector<FilePath::StringType> retained_file_paths;
-  for (std::vector<FilePath>::const_iterator it = retained_files.begin();
-       it != retained_files.end();
-       it++) {
-    retained_file_paths.push_back(it->value());
-  }
+  for (size_t i = 0; i < retained_files.size(); ++i)
+    retained_file_paths.push_back(retained_files[i].value());
 
   // Since we have no guarantees on the order of retained files, make sure the
   // list is the expected length and all required entries are present.
-  EXPECT_EQ((size_t)3, retained_files.size());
+  ASSERT_EQ(3U, retained_files.size());
   EXPECT_THAT(
       retained_file_paths,
       Contains(Eq(FilePath::StringType(FILE_PATH_LITERAL("file_1.ext")))));
@@ -208,11 +206,11 @@
 
   const std::vector<base::string16> retained_file_messages =
       tab.GetRetainedFilePermissionMessages();
-  EXPECT_EQ((size_t)3, retained_file_messages.size());
-  ASSERT_STREQ("file_1.ext",
-               base::UTF16ToUTF8(retained_file_messages[0]).c_str());
-  ASSERT_STREQ("file_2.ext",
-               base::UTF16ToUTF8(retained_file_messages[1]).c_str());
-  ASSERT_STREQ("file_3.ext",
-               base::UTF16ToUTF8(retained_file_messages[2]).c_str());
+  ASSERT_EQ(3U, retained_file_messages.size());
+  EXPECT_THAT(retained_file_messages,
+              Contains(Eq(base::UTF8ToUTF16("file_1.ext"))));
+  EXPECT_THAT(retained_file_messages,
+              Contains(Eq(base::UTF8ToUTF16("file_2.ext"))));
+  EXPECT_THAT(retained_file_messages,
+              Contains(Eq(base::UTF8ToUTF16("file_3.ext"))));
 }
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_tab.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_tab.cc
index 8775148..ec1c04c 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_tab.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_tab.cc
@@ -433,7 +433,7 @@
 void AppInfoSummaryTab::CreateShortcuts() {
   DCHECK(CanCreateShortcuts());
   chrome::ShowCreateChromeAppShortcutsDialog(
-      parent_window_, profile_, app_, base::Closure());
+      parent_window_, profile_, app_, base::Callback<void(bool)>());
 }
 
 bool AppInfoSummaryTab::CanCreateShortcuts() const {
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
index 590164d..1be2fd9 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
@@ -40,6 +40,7 @@
 #include "ash/shell.h"
 #include "ash/wm/immersive_fullscreen_controller.h"
 #include "ash/wm/panels/panel_frame_view.h"
+#include "ash/wm/window_properties.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_state_delegate.h"
 #include "ash/wm/window_state_observer.h"
@@ -204,9 +205,8 @@
 
 void ChromeNativeAppWindowViews::InitializeDefaultWindow(
     const AppWindow::CreateParams& create_params) {
-  std::string app_name =
-      web_app::GenerateApplicationNameFromExtensionId(
-          app_window()->extension()->id());
+  std::string app_name = web_app::GenerateApplicationNameFromExtensionId(
+      app_window()->extension_id());
 
   views::Widget::InitParams init_params(views::Widget::InitParams::TYPE_WINDOW);
   init_params.delegate = this;
@@ -388,25 +388,46 @@
 
 // ui::BaseWindow implementation.
 
+gfx::Rect ChromeNativeAppWindowViews::GetRestoredBounds() const {
+#if defined(USE_ASH)
+  gfx::Rect* bounds = widget()->GetNativeWindow()->GetProperty(
+      ash::kRestoreBoundsOverrideKey);
+  if (bounds && !bounds->IsEmpty())
+    return *bounds;
+#endif
+  return widget()->GetRestoredBounds();
+}
+
 ui::WindowShowState ChromeNativeAppWindowViews::GetRestoredState() const {
+#if !defined(USE_ASH)
   if (IsMaximized())
     return ui::SHOW_STATE_MAXIMIZED;
-  if (IsFullscreen()) {
-#if defined(USE_ASH)
-    if (immersive_fullscreen_controller_.get() &&
-        immersive_fullscreen_controller_->IsEnabled()) {
-      // Restore windows which were previously in immersive fullscreen to
-      // maximized. Restoring the window to a different fullscreen type
-      // makes for a bad experience.
-      return ui::SHOW_STATE_MAXIMIZED;
-    }
-#endif
+  if (IsFullscreen())
     return ui::SHOW_STATE_FULLSCREEN;
-  }
-#if defined(USE_ASH)
+#else
   // Use kRestoreShowStateKey in case a window is minimized/hidden.
   ui::WindowShowState restore_state = widget()->GetNativeWindow()->GetProperty(
       aura::client::kRestoreShowStateKey);
+  if (widget()->GetNativeWindow()->GetProperty(
+          ash::kRestoreBoundsOverrideKey)) {
+    // If an override is given, we use that restore state (after filtering).
+    restore_state = widget()->GetNativeWindow()->GetProperty(
+                        ash::kRestoreShowStateOverrideKey);
+  } else {
+    // Otherwise first normal states are checked.
+    if (IsMaximized())
+      return ui::SHOW_STATE_MAXIMIZED;
+    if (IsFullscreen()) {
+      if (immersive_fullscreen_controller_.get() &&
+          immersive_fullscreen_controller_->IsEnabled()) {
+        // Restore windows which were previously in immersive fullscreen to
+        // maximized. Restoring the window to a different fullscreen type
+        // makes for a bad experience.
+        return ui::SHOW_STATE_MAXIMIZED;
+      }
+      return ui::SHOW_STATE_FULLSCREEN;
+    }
+  }
   // Whitelist states to return so that invalid and transient states
   // are not saved and used to restore windows when they are recreated.
   switch (restore_state) {
@@ -422,7 +443,7 @@
     case ui::SHOW_STATE_END:
       return ui::SHOW_STATE_NORMAL;
   }
-#endif
+#endif  // !defined(USE_ASH)
   return ui::SHOW_STATE_NORMAL;
 }
 
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views.h b/chrome/browser/ui/views/apps/chrome_native_app_window_views.h
index ec2b160..e5a65f4 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views.h
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views.h
@@ -48,6 +48,7 @@
   apps::AppWindowFrameView* CreateNonStandardAppFrame();
 
   // ui::BaseWindow implementation.
+  virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
   virtual ui::WindowShowState GetRestoredState() const OVERRIDE;
   virtual bool IsAlwaysOnTop() const OVERRIDE;
 
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.cc
index 77ae86a..dd90d06 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.cc
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.cc
@@ -116,16 +116,25 @@
   return views::HWNDForWidget(widget()->GetTopLevelWidget());
 }
 
+void ChromeNativeAppWindowViewsWin::EnsureCaptionStyleSet() {
+  // Windows seems to have issues maximizing windows without WS_CAPTION.
+  // The default views / Aura implementation will remove this if we are using
+  // frameless or colored windows, so we put it back here.
+  HWND hwnd = GetNativeAppWindowHWND();
+  int current_style = ::GetWindowLong(hwnd, GWL_STYLE);
+  ::SetWindowLong(hwnd, GWL_STYLE, current_style | WS_CAPTION);
+}
+
 void ChromeNativeAppWindowViewsWin::OnBeforeWidgetInit(
     views::Widget::InitParams* init_params,
     views::Widget* widget) {
   content::BrowserContext* browser_context = app_window()->browser_context();
-  const extensions::Extension* extension = app_window()->extension();
+  std::string extension_id = app_window()->extension_id();
   // If an app has any existing windows, ensure new ones are created on the
   // same desktop.
   apps::AppWindow* any_existing_window =
       apps::AppWindowRegistry::Get(browser_context)
-          ->GetCurrentAppWindowForApp(extension->id());
+          ->GetCurrentAppWindowForApp(extension_id);
   chrome::HostDesktopType desktop_type;
   if (any_existing_window) {
     desktop_type = chrome::GetHostDesktopTypeForNativeWindow(
@@ -133,8 +142,8 @@
   } else {
     PerAppSettingsService* settings =
         PerAppSettingsServiceFactory::GetForBrowserContext(browser_context);
-    if (settings->HasDesktopLastLaunchedFrom(extension->id())) {
-      desktop_type = settings->GetDesktopLastLaunchedFrom(extension->id());
+    if (settings->HasDesktopLastLaunchedFrom(extension_id)) {
+      desktop_type = settings->GetDesktopLastLaunchedFrom(extension_id);
     } else {
       // We don't know what desktop this app was last launched from, so take our
       // best guess as to what desktop the user is on.
@@ -151,7 +160,10 @@
     const apps::AppWindow::CreateParams& create_params) {
   ChromeNativeAppWindowViews::InitializeDefaultWindow(create_params);
 
-  const extensions::Extension* extension = app_window()->extension();
+  const extensions::Extension* extension = app_window()->GetExtension();
+  if (!extension)
+    return;
+
   std::string app_name =
       web_app::GenerateApplicationNameFromExtensionId(extension->id());
   base::string16 app_name_wide = base::UTF8ToWide(app_name);
@@ -169,6 +181,7 @@
       base::Bind(&ChromeNativeAppWindowViewsWin::OnShortcutInfoLoaded,
                  weak_ptr_factory_.GetWeakPtr()));
 
+  EnsureCaptionStyleSet();
   UpdateShelfMenu();
 }
 
@@ -203,6 +216,10 @@
     return;
   }
 
+  const extensions::Extension* extension = app_window()->GetExtension();
+  if (!extension)
+    return;
+
   // For the icon resources.
   base::FilePath chrome_path;
   if (!PathService::Get(base::FILE_EXE, &chrome_path))
@@ -213,8 +230,6 @@
     return;
 
   // Add item to install ephemeral apps.
-  const extensions::Extension* extension = app_window()->extension();
-  DCHECK(extension);
   if (extension->is_ephemeral()) {
     scoped_refptr<ShellLinkItem> link(new ShellLinkItem());
     link->set_title(l10n_util::GetStringUTF16(IDS_APP_INSTALL_TITLE));
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.h b/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.h
index 9da718e..70ab680 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.h
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.h
@@ -30,6 +30,7 @@
       const web_app::ShortcutInfo& shortcut_info);
 
   HWND GetNativeAppWindowHWND() const;
+  void EnsureCaptionStyleSet();
 
   // Overridden from ChromeNativeAppWindowViews:
   virtual void OnBeforeWidgetInit(views::Widget::InitParams* init_params,
diff --git a/chrome/browser/ui/views/auto_keep_alive.cc b/chrome/browser/ui/views/auto_keep_alive.cc
index f1443cd..ca57e2c 100644
--- a/chrome/browser/ui/views/auto_keep_alive.cc
+++ b/chrome/browser/ui/views/auto_keep_alive.cc
@@ -1,32 +1,33 @@
-// 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.

-

-#include "chrome/browser/ui/views/auto_keep_alive.h"

-

-#include "chrome/browser/lifetime/application_lifetime.h"

-

-#if defined(USE_AURA)

-#include "ui/aura/window.h"

-#include "ui/views/view_constants_aura.h"

-#endif

-

-AutoKeepAlive::AutoKeepAlive(gfx::NativeWindow window)

-    : keep_alive_available_(true) {

-#if defined(USE_AURA)

-  // In case of aura we want default to be keep alive not available.

-  keep_alive_available_ = false;

-  if (window) {

-    gfx::NativeWindow native_window = window->GetRootWindow();

-    if (native_window->GetProperty(views::kDesktopRootWindow))

-      keep_alive_available_ = true;

-  }

-#endif

-  if (keep_alive_available_)

-    chrome::IncrementKeepAliveCount();

-}

-

-AutoKeepAlive::~AutoKeepAlive() {

-  if (keep_alive_available_)

-    chrome::DecrementKeepAliveCount();

-}

+// 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.
+
+#include "chrome/browser/ui/views/auto_keep_alive.h"
+
+#include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/ui/host_desktop.h"
+#include "ui/aura/window.h"
+#include "ui/views/view_constants_aura.h"
+
+AutoKeepAlive::AutoKeepAlive(gfx::NativeWindow window)
+    : keep_alive_available_(false) {
+  // In case of aura we want default to be keep alive not available for ash
+  // because ash has keep alive set and we don't want additional keep alive
+  // count. If there is a |window|, use its root window's kDesktopRootWindow
+  // to test whether we are on desktop. Otherwise, use GetActiveDesktop().
+  if (window) {
+    gfx::NativeWindow native_window = window->GetRootWindow();
+    if (native_window->GetProperty(views::kDesktopRootWindow))
+      keep_alive_available_ = true;
+  } else if (chrome::GetActiveDesktop() != chrome::HOST_DESKTOP_TYPE_ASH) {
+    keep_alive_available_ = true;
+  }
+
+  if (keep_alive_available_)
+    chrome::IncrementKeepAliveCount();
+}
+
+AutoKeepAlive::~AutoKeepAlive() {
+  if (keep_alive_available_)
+    chrome::DecrementKeepAliveCount();
+}
diff --git a/chrome/browser/ui/views/auto_keep_alive.h b/chrome/browser/ui/views/auto_keep_alive.h
index 52d1b26..6efa54d 100644
--- a/chrome/browser/ui/views/auto_keep_alive.h
+++ b/chrome/browser/ui/views/auto_keep_alive.h
@@ -1,22 +1,22 @@
-// 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.

-

-#ifndef CHROME_BROWSER_UI_VIEWS_AUTO_KEEP_ALIVE_H_

-#define CHROME_BROWSER_UI_VIEWS_AUTO_KEEP_ALIVE_H_

-

-#include "ui/gfx/native_widget_types.h"

-

-// Class to scoped decrement keep alive count.

-class AutoKeepAlive {

- public:

-  explicit AutoKeepAlive(gfx::NativeWindow window);

-  ~AutoKeepAlive();

-

- private:

-  bool keep_alive_available_;

-

-  DISALLOW_COPY_AND_ASSIGN(AutoKeepAlive);

-};

-

-#endif  // CHROME_BROWSER_UI_VIEWS_AUTO_KEEP_ALIVE_H_

+// 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.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_AUTO_KEEP_ALIVE_H_
+#define CHROME_BROWSER_UI_VIEWS_AUTO_KEEP_ALIVE_H_
+
+#include "ui/gfx/native_widget_types.h"
+
+// Class to scoped decrement keep alive count.
+class AutoKeepAlive {
+ public:
+  explicit AutoKeepAlive(gfx::NativeWindow window);
+  ~AutoKeepAlive();
+
+ private:
+  bool keep_alive_available_;
+
+  DISALLOW_COPY_AND_ASSIGN(AutoKeepAlive);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_AUTO_KEEP_ALIVE_H_
diff --git a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
index 7a38f8e..6168bef 100644
--- a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
+++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
@@ -25,7 +25,6 @@
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/theme_resources.h"
 #include "grit/ui_resources.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -1257,7 +1256,7 @@
   // Listen for size changes on the browser.
   views::Widget* browser_widget =
       views::Widget::GetTopLevelWidgetForNativeView(
-          delegate_->GetWebContents()->GetView()->GetNativeView());
+          delegate_->GetWebContents()->GetNativeView());
   observer_.Add(browser_widget);
 
   // Listen for unhandled mouse presses on the non-client view.
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc b/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc
index 28820d8..db527c8 100644
--- a/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc
+++ b/chrome/browser/ui/views/autofill/autofill_popup_base_view.cc
@@ -43,9 +43,9 @@
 }
 
 void AutofillPopupBaseView::DoShow() {
-  if (!GetWidget()) {
+  const bool initialize_widget = !GetWidget();
+  if (initialize_widget) {
     observing_widget_->AddObserver(this);
-    views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this);
 
     views::FocusManager* focus_manager = observing_widget_->GetFocusManager();
     focus_manager->RegisterAccelerator(
@@ -77,6 +77,11 @@
 
   DoUpdateBoundsAndRedrawPopup();
   GetWidget()->Show();
+
+  // Showing the widget can change native focus (which would result in an
+  // immediate hiding of the popup). Only start observing after shown.
+  if (initialize_widget)
+    views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this);
 }
 
 void AutofillPopupBaseView::DoHide() {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
index 1ad31a6..08973c8 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -1024,14 +1024,17 @@
 void BookmarkBarView::BookmarkNodeRemoved(BookmarkModel* model,
                                           const BookmarkNode* parent,
                                           int old_index,
-                                          const BookmarkNode* node) {
+                                          const BookmarkNode* node,
+                                          const std::set<GURL>& removed_urls) {
   // Close the menu if the menu is showing for the deleted node.
   if (bookmark_menu_ && bookmark_menu_->node() == node)
     bookmark_menu_->Cancel();
   BookmarkNodeRemovedImpl(model, parent, old_index);
 }
 
-void BookmarkBarView::BookmarkAllNodesRemoved(BookmarkModel* model) {
+void BookmarkBarView::BookmarkAllNodesRemoved(
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
   UpdateOtherBookmarksVisibility();
 
   StopThrobbing(true);
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
index bc42924..b13acaf 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
@@ -216,8 +216,11 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE;
   virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
index 7333fe7..1f693b0 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -10,7 +10,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/chrome_content_browser_client.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile.h"
@@ -30,6 +29,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "chrome/test/base/view_event_test_base.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/test/test_browser_thread.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc
index 07a02b9..d833edc 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
 
 #include "base/prefs/pref_service.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url_service.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
@@ -15,6 +15,7 @@
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "ui/views/controls/button/text_button.h"
 
 class BookmarkBarViewInstantExtendedTest : public BrowserWithTestWindowTest {
@@ -46,7 +47,8 @@
 TEST_F(BookmarkBarViewInstantExtendedTest, AppsShortcutVisibility) {
   ScopedTestingLocalState local_state(TestingBrowserProcess::GetGlobal());
   profile()->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(profile());
+  test::WaitForBookmarkModelToLoad(
+      BookmarkModelFactory::GetForProfile(profile()));
   BookmarkBarView bookmark_bar_view(browser(), NULL);
   bookmark_bar_view.set_owned_by_client();
   browser()->profile()->GetPrefs()->SetBoolean(
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
index fadb01b..cbfdf75 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -275,7 +275,6 @@
       sync_promo_view_(NULL),
       remove_bookmark_(false),
       apply_edits_(true) {
-  set_move_with_anchor(true);
   set_margins(gfx::Insets(views::kPanelVertMargin, 0, 0, 0));
   // Compensate for built-in vertical padding in the anchor view's image.
   set_anchor_view_insets(gfx::Insets(2, 0, 2, 0));
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
index 1bdc68d..02f720c 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
@@ -8,12 +8,12 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/signin/fake_signin_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "components/signin/core/browser/signin_manager.h"
 
 namespace {
@@ -29,12 +29,12 @@
     BrowserWithTestWindowTest::SetUp();
 
     profile()->CreateBookmarkModel(true);
-    test::WaitForBookmarkModelToLoad(profile());
+    BookmarkModel* bookmark_model =
+        BookmarkModelFactory::GetForProfile(profile());
+    test::WaitForBookmarkModelToLoad(bookmark_model);
 
     bookmark_utils::AddIfNotBookmarked(
-        BookmarkModelFactory::GetForProfile(profile()),
-        GURL(kTestBookmarkURL),
-        base::string16());
+        bookmark_model, GURL(kTestBookmarkURL), base::string16());
   }
 
   virtual void TearDown() OVERRIDE {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc
index 2821d12..07ff4d4 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc
@@ -13,11 +13,11 @@
 #include "base/threading/sequenced_worker_pool.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/test/test_browser_thread.h"
 #include "grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
index f505a71..99a1eee 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
@@ -376,10 +376,12 @@
   Reset();
 }
 
-void BookmarkEditorView::BookmarkNodeRemoved(BookmarkModel* model,
-                                             const BookmarkNode* parent,
-                                             int index,
-                                             const BookmarkNode* node) {
+void BookmarkEditorView::BookmarkNodeRemoved(
+    BookmarkModel* model,
+    const BookmarkNode* parent,
+    int index,
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {
   if ((details_.type == EditDetails::EXISTING_NODE &&
        details_.existing_node->HasAncestor(node)) ||
       (parent_ && parent_->HasAncestor(node))) {
@@ -390,12 +392,15 @@
   }
 }
 
-void BookmarkEditorView::BookmarkAllNodesRemoved(BookmarkModel* model) {
+void BookmarkEditorView::BookmarkAllNodesRemoved(
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
   Reset();
 }
 
 void BookmarkEditorView::BookmarkNodeChildrenReordered(
-    BookmarkModel* model, const BookmarkNode* node) {
+    BookmarkModel* model,
+    const BookmarkNode* node) {
   Reset();
 }
 
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.h b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.h
index 9b05e43..c275cce 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.h
@@ -145,8 +145,11 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int index,
-                                   const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE {}
   virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc
index 3c780f5..ae68e7b 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc
@@ -10,10 +10,10 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/views/controls/textfield/textfield.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc
index 8a7dba6..fa2ba82 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc
@@ -7,11 +7,11 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/bookmarks/bookmark_stats.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "ui/views/controls/menu/menu_item_view.h"
 #include "ui/views/controls/menu/menu_runner.h"
 #include "ui/views/controls/menu/submenu_view.h"
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_prompt_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_prompt_view.cc
deleted file mode 100644
index 072925b..0000000
--- a/chrome/browser/ui/views/bookmarks/bookmark_prompt_view.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/ui/views/bookmarks/bookmark_prompt_view.h"
-
-#include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
-#include "grit/generated_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/controls/link.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/layout/layout_constants.h"
-#include "ui/views/widget/widget.h"
-
-namespace {
-
-// Horizontal padding of bookmark prompt.
-const int kHorizontalPadding = 20;
-
-}
-
-// static
-BookmarkPromptView* BookmarkPromptView::bookmark_bubble_ = NULL;
-
-// static
-void BookmarkPromptView::ShowPrompt(views::View* anchor_view,
-                                    PrefService* prefs) {
-  if (bookmark_bubble_)
-    return;
-  bookmark_bubble_ = new BookmarkPromptView(anchor_view, prefs);
-  views::BubbleDelegateView::CreateBubble(bookmark_bubble_)->Show();
-}
-
-BookmarkPromptView::BookmarkPromptView(views::View* anchor_view,
-                                       PrefService* prefs)
-    : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
-      dismiss_link_(NULL),
-      prefs_(prefs) {
-  // Compensate for built-in vertical padding in the anchor view's image.
-  set_anchor_view_insets(gfx::Insets(5, 0, 5, 0));
-}
-
-BookmarkPromptView::~BookmarkPromptView() {
-  DCHECK_NE(this, bookmark_bubble_);
-}
-
-void BookmarkPromptView::Init() {
-  SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
-                                        kHorizontalPadding, 0, 0));
-
-  views::Label* label = new views::Label(l10n_util::GetStringUTF16(
-      IDS_BOOKMARK_PROMPT_MESSAGE));
-  ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
-  label->SetFontList(rb->GetFontList(ui::ResourceBundle::MediumBoldFont));
-  AddChildView(label);
-
-  dismiss_link_ = new views::Link(l10n_util::GetStringUTF16(
-      IDS_BOOKMARK_PROMPT_DISMISS));
-  dismiss_link_->SetHorizontalAlignment(gfx::ALIGN_RIGHT);
-  dismiss_link_->set_listener(this);
-  AddChildView(dismiss_link_);
-}
-
-void BookmarkPromptView::LinkClicked(views::Link* source, int event_flags) {
-  DCHECK_EQ(source, dismiss_link_);
-  BookmarkPromptController::DisableBookmarkPrompt(prefs_);
-  GetWidget()->Close();
-}
-
-void BookmarkPromptView::WindowClosing() {
-  bookmark_bubble_ = NULL;
-  BookmarkPromptController::ClosingBookmarkPrompt();
-}
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_prompt_view.h b/chrome/browser/ui/views/bookmarks/bookmark_prompt_view.h
deleted file mode 100644
index 62b308e..0000000
--- a/chrome/browser/ui/views/bookmarks/bookmark_prompt_view.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_PROMPT_VIEW_H_
-#define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_PROMPT_VIEW_H_
-
-#include "base/basictypes.h"
-#include "ui/views/bubble/bubble_delegate.h"
-#include "ui/views/controls/link_listener.h"
-
-class PrefService;
-
-// BookmarkPromptView is a view intended to be used as the content of an
-// Bubble. BookmarkPromptView provides views for prompting user for action box
-// or star icon. Don't create a BookmarkPromptView directly, instead use
-// the static ShowPrompt() method.
-class BookmarkPromptView : public views::BubbleDelegateView,
-                           public views::LinkListener {
- public:
-  // Show the prompt bubble.
-  static void ShowPrompt(views::View* anchor_view, PrefService* prefs);
-
- private:
-  // Creates a BookmarkPromptView.
-  BookmarkPromptView(views::View* anchor_view, PrefService* prefs);
-
-  virtual ~BookmarkPromptView();
-
-  // views::BubbleDelegateView method.
-  virtual void Init() OVERRIDE;
-
-  // views::LinkListener method.
-  virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
-
-  // views::WidgetDelegate method.
-  virtual void WindowClosing() OVERRIDE;
-
-  // The bookmark bubble, if we're showing one.
-  static BookmarkPromptView* bookmark_bubble_;
-
-  // Link for dismissing the prompt.
-  views::Link* dismiss_link_;
-
-  // The pref service to use disabling bookmark prompt feature.
-  PrefService* prefs_;
-
-  DISALLOW_COPY_AND_ASSIGN(BookmarkPromptView);
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_PROMPT_VIEW_H_
diff --git a/chrome/browser/ui/views/color_chooser_aura.cc b/chrome/browser/ui/views/color_chooser_aura.cc
index 720f90c..f8d7602 100644
--- a/chrome/browser/ui/views/color_chooser_aura.cc
+++ b/chrome/browser/ui/views/color_chooser_aura.cc
@@ -8,7 +8,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/views/color_chooser/color_chooser_view.h"
 #include "ui/views/widget/widget.h"
 
@@ -17,7 +16,7 @@
     : web_contents_(web_contents) {
   view_ = new views::ColorChooserView(this, initial_color);
   widget_ = views::Widget::CreateWindowWithParent(
-      view_, web_contents->GetView()->GetTopLevelNativeWindow());
+      view_, web_contents->GetTopLevelNativeWindow());
   widget_->Show();
 }
 
diff --git a/chrome/browser/ui/views/color_chooser_win.cc b/chrome/browser/ui/views/color_chooser_win.cc
index 0fde020..d4f07c1 100644
--- a/chrome/browser/ui/views/color_chooser_win.cc
+++ b/chrome/browser/ui/views/color_chooser_win.cc
@@ -12,7 +12,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/views/color_chooser/color_chooser_listener.h"
 
 #if defined(USE_ASH)
@@ -104,7 +103,7 @@
 content::ColorChooser* ShowColorChooser(content::WebContents* web_contents,
                                         SkColor initial_color) {
 #if defined(USE_ASH)
-  gfx::NativeView native_view = web_contents->GetView()->GetNativeView();
+  gfx::NativeView native_view = web_contents->GetNativeView();
   if (GetHostDesktopTypeForNativeView(native_view) == HOST_DESKTOP_TYPE_ASH)
     return ColorChooserAura::Open(web_contents, initial_color);
 #endif
diff --git a/chrome/browser/ui/views/conflicting_module_view_win.cc b/chrome/browser/ui/views/conflicting_module_view_win.cc
index 0662ef4..eb4a1e0 100644
--- a/chrome/browser/ui/views/conflicting_module_view_win.cc
+++ b/chrome/browser/ui/views/conflicting_module_view_win.cc
@@ -56,7 +56,6 @@
       not_now_button_(NULL),
       help_center_url_(help_center_url) {
   set_close_on_deactivate(false);
-  set_move_with_anchor(true);
   set_close_on_esc(true);
 
   // Compensate for built-in vertical padding in the anchor view's image.
diff --git a/chrome/browser/ui/views/constrained_window_views_browsertest.cc b/chrome/browser/ui/views/constrained_window_views_browsertest.cc
index 3f19cb0..0ecaa75 100644
--- a/chrome/browser/ui/views/constrained_window_views_browsertest.cc
+++ b/chrome/browser/ui/views/constrained_window_views_browsertest.cc
@@ -20,6 +20,7 @@
 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "ipc/ipc_message.h"
diff --git a/chrome/browser/ui/views/create_application_shortcut_view.cc b/chrome/browser/ui/views/create_application_shortcut_view.cc
index a856748..a84cc04 100644
--- a/chrome/browser/ui/views/create_application_shortcut_view.cc
+++ b/chrome/browser/ui/views/create_application_shortcut_view.cc
@@ -240,7 +240,7 @@
     gfx::NativeWindow parent_window,
     Profile* profile,
     const extensions::Extension* app,
-    const base::Closure& close_callback) {
+    const base::Callback<void(bool)>& close_callback) {
   CreateBrowserModalDialogViews(
       new CreateChromeApplicationShortcutView(profile, app, close_callback),
       parent_window)->Show();
@@ -519,7 +519,7 @@
 CreateChromeApplicationShortcutView::CreateChromeApplicationShortcutView(
     Profile* profile,
     const extensions::Extension* app,
-    const base::Closure& close_callback)
+    const base::Callback<void(bool)>& close_callback)
         : CreateApplicationShortcutView(profile),
           close_callback_(close_callback),
           weak_ptr_factory_(this) {
@@ -543,13 +543,13 @@
 
 bool CreateChromeApplicationShortcutView::Accept() {
   if (!close_callback_.is_null())
-    close_callback_.Run();
+    close_callback_.Run(true);
   return CreateApplicationShortcutView::Accept();
 }
 
 bool CreateChromeApplicationShortcutView::Cancel() {
   if (!close_callback_.is_null())
-    close_callback_.Run();
+    close_callback_.Run(false);
   return CreateApplicationShortcutView::Cancel();
 }
 
diff --git a/chrome/browser/ui/views/create_application_shortcut_view.h b/chrome/browser/ui/views/create_application_shortcut_view.h
index 12aa0d7..64f58a4 100644
--- a/chrome/browser/ui/views/create_application_shortcut_view.h
+++ b/chrome/browser/ui/views/create_application_shortcut_view.h
@@ -126,7 +126,7 @@
   CreateChromeApplicationShortcutView(
       Profile* profile,
       const extensions::Extension* app,
-      const base::Closure& close_callback);
+      const base::Callback<void(bool)>& close_callback);
   virtual ~CreateChromeApplicationShortcutView();
   virtual bool Accept() OVERRIDE;
   virtual bool Cancel() OVERRIDE;
@@ -135,7 +135,7 @@
   void OnShortcutInfoLoaded(
       const web_app::ShortcutInfo& shortcut_info);
 
-  base::Closure close_callback_;
+  base::Callback<void(bool)> close_callback_;
 
   base::WeakPtrFactory<CreateChromeApplicationShortcutView> weak_ptr_factory_;
 
diff --git a/chrome/browser/ui/views/critical_notification_bubble_view.cc b/chrome/browser/ui/views/critical_notification_bubble_view.cc
index 7e53be6..622c391 100644
--- a/chrome/browser/ui/views/critical_notification_bubble_view.cc
+++ b/chrome/browser/ui/views/critical_notification_bubble_view.cc
@@ -57,7 +57,6 @@
       restart_button_(NULL),
       dismiss_button_(NULL) {
   set_close_on_deactivate(false);
-  set_move_with_anchor(true);
 }
 
 CriticalNotificationBubbleView::~CriticalNotificationBubbleView() {
diff --git a/chrome/browser/ui/views/download/download_started_animation_views.cc b/chrome/browser/ui/views/download/download_started_animation_views.cc
index fcde0a2..aaa37ca 100644
--- a/chrome/browser/ui/views/download/download_started_animation_views.cc
+++ b/chrome/browser/ui/views/download/download_started_animation_views.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/download/download_started_animation.h"
 
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/theme_resources.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/animation/linear_animation.h"
@@ -67,7 +66,7 @@
 
   // If we're too small to show the download image, then don't bother -
   // the shelf will be enough.
-  web_contents->GetView()->GetContainerBounds(&web_contents_bounds_);
+  web_contents_bounds_= web_contents->GetContainerBounds();
   if (web_contents_bounds_.height() < kDownloadImage->height())
     return;
 
@@ -78,7 +77,7 @@
   views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
   params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
   params.accept_events = false;
-  params.parent = web_contents->GetView()->GetNativeView();
+  params.parent = web_contents->GetNativeView();
   popup_->Init(params);
   popup_->SetOpacity(0x00);
   popup_->SetContentsView(this);
diff --git a/chrome/browser/ui/views/extensions/extension_dialog.cc b/chrome/browser/ui/views/extensions/extension_dialog.cc
index 1d8aec9..ba2c1c7 100644
--- a/chrome/browser/ui/views/extensions/extension_dialog.cc
+++ b/chrome/browser/ui/views/extensions/extension_dialog.cc
@@ -15,7 +15,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/base/base_window.h"
 #include "ui/gfx/screen.h"
 #include "ui/views/background.h"
@@ -78,7 +77,7 @@
   host->view()->SetVisible(true);
 
   // Ensure the DOM JavaScript can respond immediately to keyboard shortcuts.
-  host->host_contents()->GetView()->Focus();
+  host->host_contents()->Focus();
   return dialog;
 }
 
diff --git a/chrome/browser/ui/views/extensions/extension_message_bubble_view.cc b/chrome/browser/ui/views/extensions/extension_message_bubble_view.cc
index 09a9236..43532db 100644
--- a/chrome/browser/ui/views/extensions/extension_message_bubble_view.cc
+++ b/chrome/browser/ui/views/extensions/extension_message_bubble_view.cc
@@ -69,7 +69,6 @@
       action_taken_(false) {
   DCHECK(anchor_view->GetWidget());
   set_close_on_deactivate(controller_->CloseOnDeactivate());
-  set_move_with_anchor(true);
   set_close_on_esc(true);
 
   // Compensate for built-in vertical padding in the anchor view's image.
diff --git a/chrome/browser/ui/views/extensions/extension_popup.cc b/chrome/browser/ui/views/extensions/extension_popup.cc
index dcacc5a..5668586 100644
--- a/chrome/browser/ui/views/extensions/extension_popup.cc
+++ b/chrome/browser/ui/views/extensions/extension_popup.cc
@@ -23,7 +23,6 @@
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/gfx/insets.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/widget/widget.h"
@@ -84,8 +83,6 @@
   host->view()->set_container(this);
   // Use OnNativeFocusChange to check for child window activation on deactivate.
   set_close_on_deactivate(false);
-  // Make the bubble move with its anchor (during inspection, etc.).
-  set_move_with_anchor(true);
 
   // Wait to show the popup until the contained host finishes loading.
   registrar_.Add(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
@@ -251,7 +248,7 @@
   GetWidget()->Show();
 
   // Focus on the host contents when the bubble is first shown.
-  host()->host_contents()->GetView()->Focus();
+  host()->host_contents()->Focus();
 
   if (inspect_with_devtools_) {
     DevToolsWindow::OpenDevToolsWindow(host()->render_view_host(),
diff --git a/chrome/browser/ui/views/extensions/extension_view_views.cc b/chrome/browser/ui/views/extensions/extension_view_views.cc
index b7c7e59..77a1263 100644
--- a/chrome/browser/ui/views/extensions/extension_view_views.cc
+++ b/chrome/browser/ui/views/extensions/extension_view_views.cc
@@ -9,7 +9,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_host.h"
 #include "extensions/common/view_type.h"
 #include "ui/events/event.h"
@@ -134,13 +133,13 @@
 }
 
 void ExtensionViewViews::OnFocus() {
-  host()->host_contents()->GetView()->Focus();
+  host()->host_contents()->Focus();
 }
 
 void ExtensionViewViews::CreateWidgetHostView() {
   DCHECK(!initialized_);
   initialized_ = true;
-  Attach(host_->host_contents()->GetView()->GetNativeView());
+  Attach(host_->host_contents()->GetNativeView());
   host_->CreateRenderViewSoon();
   SetVisible(false);
 }
diff --git a/chrome/browser/ui/views/external_protocol_dialog.cc b/chrome/browser/ui/views/external_protocol_dialog.cc
index bab86c7..9883404 100644
--- a/chrome/browser/ui/views/external_protocol_dialog.cc
+++ b/chrome/browser/ui/views/external_protocol_dialog.cc
@@ -12,7 +12,6 @@
 #include "chrome/browser/ui/external_protocol_dialog_delegate.h"
 #include "chrome/browser/ui/views/constrained_window_views.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -137,6 +136,6 @@
       render_process_host_id_, routing_id_);
   gfx::NativeWindow parent_window = NULL;
   if (web_contents)
-    parent_window = web_contents->GetView()->GetTopLevelNativeWindow();
+    parent_window = web_contents->GetTopLevelNativeWindow();
   CreateBrowserModalDialogViews(this, parent_window)->Show();
 }
diff --git a/chrome/browser/ui/views/find_bar_host.cc b/chrome/browser/ui/views/find_bar_host.cc
index 284f848..636e587 100644
--- a/chrome/browser/ui/views/find_bar_host.cc
+++ b/chrome/browser/ui/views/find_bar_host.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/events/event.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/views/focus/external_focus_tracker.h"
@@ -169,7 +168,7 @@
 void FindBarHost::RestoreSavedFocus() {
   if (focus_tracker() == NULL) {
     // TODO(brettw): Focus() should be on WebContentsView.
-    find_bar_controller_->web_contents()->GetView()->Focus();
+    find_bar_controller_->web_contents()->Focus();
   } else {
     focus_tracker()->FocusLastFocusedExternalView();
   }
@@ -366,8 +365,7 @@
 
 void FindBarHost::GetWidgetPositionNative(gfx::Rect* avoid_overlapping_rect) {
   gfx::Rect frame_rect = host()->GetTopLevelWidget()->GetWindowBoundsInScreen();
-  content::WebContentsView* tab_view =
-      find_bar_controller_->web_contents()->GetView();
-  gfx::Rect webcontents_rect = tab_view->GetViewBounds();
+  gfx::Rect webcontents_rect =
+      find_bar_controller_->web_contents()->GetViewBounds();
   avoid_overlapping_rect->Offset(0, webcontents_rect.y() - frame_rect.y());
 }
diff --git a/chrome/browser/ui/views/find_bar_view.cc b/chrome/browser/ui/views/find_bar_view.cc
index f07c373..1698820 100644
--- a/chrome/browser/ui/views/find_bar_view.cc
+++ b/chrome/browser/ui/views/find_bar_view.cc
@@ -78,7 +78,6 @@
       find_previous_button_(NULL),
       find_next_button_(NULL),
       close_button_(NULL) {
-  set_id(VIEW_ID_FIND_IN_PAGE);
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
 
   find_text_ = new views::Textfield;
diff --git a/chrome/browser/ui/views/frame/app_panel_browser_frame_view.cc b/chrome/browser/ui/views/frame/app_panel_browser_frame_view.cc
deleted file mode 100644
index 53d45f0..0000000
--- a/chrome/browser/ui/views/frame/app_panel_browser_frame_view.cc
+++ /dev/null
@@ -1,515 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/ui/views/frame/app_panel_browser_frame_view.h"
-
-#include "base/compiler_specific.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/ui/views/frame/browser_frame.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/tab_icon_view.h"
-#include "content/public/browser/web_contents.h"
-#include "grit/chromium_strings.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "grit/ui_resources.h"
-#include "ui/base/hit_test.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/font_list.h"
-#include "ui/gfx/path.h"
-#include "ui/views/color_constants.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_delegate.h"
-
-using content::WebContents;
-
-namespace {
-
-// The frame border is only visible in restored mode and is hardcoded to 1 px on
-// each side regardless of the system window border size.
-const int kFrameBorderThickness = 1;
-// In the window corners, the resize areas don't actually expand bigger, but the
-// 16 px at the end of each edge triggers diagonal resizing.
-const int kResizeAreaCornerSize = 16;
-// The titlebar never shrinks too short to show the caption button plus some
-// padding below it.
-const int kCaptionButtonHeightWithPadding = 27;
-// The titlebar has a 2 px 3D edge along the bottom, and we reserve 2 px (1 for
-// border, 1 for padding) along the top.
-const int kTitlebarTopAndBottomEdgeThickness = 2;
-// The icon is inset 6 px from the left frame border.
-const int kIconLeftSpacing = 6;
-// The icon never shrinks below 16 px on a side.
-const int kIconMinimumSize = 16;
-// There is a 4 px gap between the icon and the title text.
-const int kIconTitleSpacing = 4;
-// There is a 5 px gap between the title text and the close button.
-const int kTitleCloseButtonSpacing = 5;
-// There is a 4 px gap between the close button and the frame border.
-const int kCloseButtonFrameBorderSpacing = 4;
-
-const SkColor kFrameColorAppPanel = SK_ColorWHITE;
-const SkColor kFrameColorAppPanelInactive = SK_ColorWHITE;
-
-}  // namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// AppPanelBrowserFrameView, public:
-
-AppPanelBrowserFrameView::AppPanelBrowserFrameView(BrowserFrame* frame,
-                                                   BrowserView* browser_view)
-    : BrowserNonClientFrameView(frame, browser_view),
-      close_button_(new views::ImageButton(this)),
-      window_icon_(NULL) {
-  DCHECK(browser_view->ShouldShowWindowIcon());
-  DCHECK(browser_view->ShouldShowWindowTitle());
-
-  frame->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM);
-
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  close_button_->SetImage(views::CustomButton::STATE_NORMAL,
-                          rb.GetImageSkiaNamed(IDR_CLOSE_2));
-  close_button_->SetImage(views::CustomButton::STATE_HOVERED,
-                          rb.GetImageSkiaNamed(IDR_CLOSE_2_H));
-  close_button_->SetImage(views::CustomButton::STATE_PRESSED,
-                          rb.GetImageSkiaNamed(IDR_CLOSE_2_P));
-  close_button_->SetAccessibleName(
-      l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE));
-  AddChildView(close_button_);
-
-  window_icon_ = new TabIconView(this, NULL);
-  window_icon_->set_is_light(true);
-  AddChildView(window_icon_);
-  window_icon_->Update();
-}
-
-AppPanelBrowserFrameView::~AppPanelBrowserFrameView() {
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// AppPanelBrowserFrameView, BrowserNonClientFrameView implementation:
-
-gfx::Rect AppPanelBrowserFrameView::GetBoundsForTabStrip(
-    views::View* tabstrip) const {
-  // App panels never show a tab strip.
-  NOTREACHED();
-  return gfx::Rect();
-}
-
-int AppPanelBrowserFrameView::GetTopInset() const {
-  return NonClientTopBorderHeight();
-}
-
-int AppPanelBrowserFrameView::GetThemeBackgroundXInset() const {
-  return 0;
-}
-
-void AppPanelBrowserFrameView::UpdateThrobber(bool running) {
-  window_icon_->Update();
-}
-
-gfx::Size AppPanelBrowserFrameView::GetMinimumSize() {
-  gfx::Size min_size(browser_view()->GetMinimumSize());
-  int border_thickness = NonClientBorderThickness();
-  min_size.Enlarge(2 * border_thickness,
-                   NonClientTopBorderHeight() + border_thickness);
-
-  min_size.set_width(std::max(min_size.width(),
-      (2 * FrameBorderThickness()) + kIconLeftSpacing + IconSize() +
-      kTitleCloseButtonSpacing + kCloseButtonFrameBorderSpacing));
-  return min_size;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// AppPanelBrowserFrameView, views::NonClientFrameView implementation:
-
-gfx::Rect AppPanelBrowserFrameView::GetBoundsForClientView() const {
-  return client_view_bounds_;
-}
-
-gfx::Rect AppPanelBrowserFrameView::GetWindowBoundsForClientBounds(
-    const gfx::Rect& client_bounds) const {
-  int top_height = NonClientTopBorderHeight();
-  int border_thickness = NonClientBorderThickness();
-  return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
-                   std::max(0, client_bounds.y() - top_height),
-                   client_bounds.width() + (2 * border_thickness),
-                   client_bounds.height() + top_height + border_thickness);
-}
-
-int AppPanelBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
-  if (!bounds().Contains(point))
-    return HTNOWHERE;
-
-  int frame_component = frame()->client_view()->NonClientHitTest(point);
-
-  // See if we're in the sysmenu region.  (We check the ClientView first to be
-  // consistent with OpaqueBrowserFrameView; it's not really necessary here.)
-  gfx::Rect sysmenu_rect(IconBounds());
-  // In maximized mode we extend the rect to the screen corner to take advantage
-  // of Fitts' Law.
-  if (frame()->IsMaximized())
-    sysmenu_rect.SetRect(0, 0, sysmenu_rect.right(), sysmenu_rect.bottom());
-  sysmenu_rect.set_x(GetMirroredXForRect(sysmenu_rect));
-  if (sysmenu_rect.Contains(point))
-    return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU;
-
-  if (frame_component != HTNOWHERE)
-    return frame_component;
-
-  // Then see if the point is within any of the window controls.
-  if (close_button_->visible() &&
-      close_button_->GetMirroredBounds().Contains(point))
-    return HTCLOSE;
-
-  int window_component = GetHTComponentForFrame(point,
-      NonClientBorderThickness(), NonClientBorderThickness(),
-      kResizeAreaCornerSize, kResizeAreaCornerSize,
-      frame()->widget_delegate()->CanResize());
-  // Fall back to the caption if no other component matches.
-  return (window_component == HTNOWHERE) ? HTCAPTION : window_component;
-}
-
-void AppPanelBrowserFrameView::GetWindowMask(const gfx::Size& size,
-                                             gfx::Path* window_mask) {
-  DCHECK(window_mask);
-
-  if (frame()->IsMaximized())
-    return;
-
-  // Redefine the window visible region for the new size.
-  window_mask->moveTo(0, 3);
-  window_mask->lineTo(1, 2);
-  window_mask->lineTo(1, 1);
-  window_mask->lineTo(2, 1);
-  window_mask->lineTo(3, 0);
-
-  window_mask->lineTo(SkIntToScalar(size.width() - 3), 0);
-  window_mask->lineTo(SkIntToScalar(size.width() - 2), 1);
-  window_mask->lineTo(SkIntToScalar(size.width() - 1), 1);
-  window_mask->lineTo(SkIntToScalar(size.width() - 1), 2);
-  window_mask->lineTo(SkIntToScalar(size.width()), 3);
-
-  window_mask->lineTo(SkIntToScalar(size.width()),
-                      SkIntToScalar(size.height()));
-  window_mask->lineTo(0, SkIntToScalar(size.height()));
-  window_mask->close();
-}
-
-void AppPanelBrowserFrameView::ResetWindowControls() {
-  // The close button isn't affected by this constraint.
-}
-
-void AppPanelBrowserFrameView::UpdateWindowIcon() {
-  window_icon_->SchedulePaint();
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// AppPanelBrowserFrameView, views::View overrides:
-
-void AppPanelBrowserFrameView::OnPaint(gfx::Canvas* canvas) {
-  if (frame()->IsMaximized())
-    PaintMaximizedFrameBorder(canvas);
-  else
-    PaintRestoredFrameBorder(canvas);
-  PaintTitleBar(canvas);
-  if (!frame()->IsMaximized())
-    PaintRestoredClientEdge(canvas);
-}
-
-void AppPanelBrowserFrameView::Layout() {
-  LayoutWindowControls();
-  LayoutTitleBar();
-  client_view_bounds_ = CalculateClientAreaBounds(width(), height());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// AppPanelBrowserFrameView, views::ButtonListener implementation:
-
-void AppPanelBrowserFrameView::ButtonPressed(views::Button* sender,
-                                             const ui::Event& event) {
-  if (sender == close_button_)
-    frame()->Close();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// AppPanelBrowserFrameView, TabIconView::TabContentsProvider implementation:
-
-bool AppPanelBrowserFrameView::ShouldTabIconViewAnimate() const {
-  // This function is queried during the creation of the window as the
-  // TabIconView we host is initialized, so we need to NULL check the selected
-  // WebContents because in this condition there is not yet a selected tab.
-  WebContents* current_tab = browser_view()->GetActiveWebContents();
-  return current_tab ? current_tab->IsLoading() : false;
-}
-
-gfx::ImageSkia AppPanelBrowserFrameView::GetFaviconForTabIconView() {
-  return frame()->widget_delegate()->GetWindowIcon();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// AppPanelBrowserFrameView, private:
-
-int AppPanelBrowserFrameView::FrameBorderThickness() const {
-  return frame()->IsMaximized() ? 0 : kFrameBorderThickness;
-}
-
-int AppPanelBrowserFrameView::NonClientBorderThickness() const {
-  return FrameBorderThickness() +
-      (frame()->IsMaximized() ? 0 : kClientEdgeThickness);
-}
-
-int AppPanelBrowserFrameView::NonClientTopBorderHeight() const {
-  return std::max(FrameBorderThickness() + IconSize(),
-                  FrameBorderThickness() + kCaptionButtonHeightWithPadding) +
-      TitlebarBottomThickness();
-}
-
-int AppPanelBrowserFrameView::TitlebarBottomThickness() const {
-  return kTitlebarTopAndBottomEdgeThickness +
-      (frame()->IsMaximized() ? 0 : kClientEdgeThickness);
-}
-
-int AppPanelBrowserFrameView::IconSize() const {
-#if defined(OS_WIN)
-  // This metric scales up if either the titlebar height or the titlebar font
-  // size are increased.
-  return GetSystemMetrics(SM_CYSMICON);
-#else
-  return std::max(BrowserFrame::GetTitleFontList().height(), kIconMinimumSize);
-#endif
-}
-
-gfx::Rect AppPanelBrowserFrameView::IconBounds() const {
-  int size = IconSize();
-  int frame_thickness = FrameBorderThickness();
-  // Our frame border has a different "3D look" than Windows'.  Theirs has a
-  // more complex gradient on the top that they push their icon/title below;
-  // then the maximized window cuts this off and the icon/title are centered
-  // in the remaining space.  Because the apparent shape of our border is
-  // simpler, using the same positioning makes things look slightly uncentered
-  // with restored windows, so when the window is restored, instead of
-  // calculating the remaining space from below the frame border, we calculate
-  // from below the top border-plus-padding.
-  int unavailable_px_at_top = frame()->IsMaximized() ?
-      frame_thickness : kTitlebarTopAndBottomEdgeThickness;
-  // When the icon is shorter than the minimum space we reserve for the caption
-  // button, we vertically center it.  We want to bias rounding to put extra
-  // space above the icon, since the 3D edge (+ client edge, for restored
-  // windows) below looks (to the eye) more like additional space than does the
-  // border + padding (or nothing at all, for maximized windows) above; hence
-  // the +1.
-  int y = unavailable_px_at_top + (NonClientTopBorderHeight() -
-      unavailable_px_at_top - size - TitlebarBottomThickness() + 1) / 2;
-  return gfx::Rect(frame_thickness + kIconLeftSpacing, y, size, size);
-}
-
-void AppPanelBrowserFrameView::PaintRestoredFrameBorder(gfx::Canvas* canvas) {
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-
-  gfx::ImageSkia* top_left_corner =
-      rb.GetImageSkiaNamed(IDR_WINDOW_TOP_LEFT_CORNER);
-  gfx::ImageSkia* top_right_corner =
-      rb.GetImageSkiaNamed(IDR_WINDOW_TOP_RIGHT_CORNER);
-  gfx::ImageSkia* top_edge = rb.GetImageSkiaNamed(IDR_WINDOW_TOP_CENTER);
-  gfx::ImageSkia* right_edge = rb.GetImageSkiaNamed(IDR_WINDOW_RIGHT_SIDE);
-  gfx::ImageSkia* left_edge = rb.GetImageSkiaNamed(IDR_WINDOW_LEFT_SIDE);
-  gfx::ImageSkia* bottom_left_corner =
-      rb.GetImageSkiaNamed(IDR_WINDOW_BOTTOM_LEFT_CORNER);
-  gfx::ImageSkia* bottom_right_corner =
-      rb.GetImageSkiaNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER);
-  gfx::ImageSkia* bottom_edge = rb.GetImageSkiaNamed(IDR_WINDOW_BOTTOM_CENTER);
-
-  // Window frame mode and color.
-  gfx::ImageSkia* theme_frame;
-  SkColor frame_color;
-  if (ShouldPaintAsActive()) {
-    theme_frame = rb.GetImageSkiaNamed(IDR_FRAME_APP_PANEL);
-    frame_color = kFrameColorAppPanel;
-  } else {
-    theme_frame = rb.GetImageSkiaNamed(IDR_FRAME_APP_PANEL);
-    frame_color = kFrameColorAppPanelInactive;
-  }
-
-  // Fill with the frame color first so we have a constant background for
-  // areas not covered by the theme image.
-  canvas->FillRect(gfx::Rect(0, 0, width(), theme_frame->height()),
-                   frame_color);
-
-  int remaining_height = height() - theme_frame->height();
-  if (remaining_height > 0) {
-    // Now fill down the sides.
-    canvas->FillRect(gfx::Rect(0, theme_frame->height(), left_edge->width(),
-                               remaining_height), frame_color);
-    canvas->FillRect(gfx::Rect(width() - right_edge->width(),
-                               theme_frame->height(), right_edge->width(),
-                               remaining_height), frame_color);
-    int center_width = width() - left_edge->width() - right_edge->width();
-    if (center_width > 0) {
-      // Now fill the bottom area.
-      canvas->FillRect(gfx::Rect(left_edge->width(),
-                                 height() - bottom_edge->height(), center_width,
-                                 bottom_edge->height()), frame_color);
-    }
-  }
-
-  // Draw the theme frame.
-  canvas->TileImageInt(*theme_frame, 0, 0, width(), theme_frame->height());
-
-  // Top.
-  canvas->DrawImageInt(*top_left_corner, 0, 0);
-  canvas->TileImageInt(*top_edge, top_left_corner->width(), 0,
-                       width() - top_right_corner->width(), top_edge->height());
-  canvas->DrawImageInt(*top_right_corner,
-                       width() - top_right_corner->width(), 0);
-
-  // Right.
-  canvas->TileImageInt(*right_edge, width() - right_edge->width(),
-      top_right_corner->height(), right_edge->width(),
-      height() - top_right_corner->height() - bottom_right_corner->height());
-
-  // Bottom.
-  canvas->DrawImageInt(*bottom_right_corner,
-                       width() - bottom_right_corner->width(),
-                       height() - bottom_right_corner->height());
-  canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(),
-      height() - bottom_edge->height(),
-      width() - bottom_left_corner->width() - bottom_right_corner->width(),
-      bottom_edge->height());
-  canvas->DrawImageInt(*bottom_left_corner, 0,
-                       height() - bottom_left_corner->height());
-
-  // Left.
-  canvas->TileImageInt(*left_edge, 0, top_left_corner->height(),
-      left_edge->width(),
-      height() - top_left_corner->height() - bottom_left_corner->height());
-}
-
-void AppPanelBrowserFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) {
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-
-  gfx::ImageSkia* frame_image = rb.GetImageSkiaNamed(IDR_FRAME_APP_PANEL);
-  canvas->TileImageInt(*frame_image, 0, FrameBorderThickness(), width(),
-                       frame_image->height());
-
-  // The bottom of the titlebar actually comes from the top of the Client Edge
-  // graphic, with the actual client edge clipped off the bottom.
-  gfx::ImageSkia* titlebar_bottom = rb.GetImageSkiaNamed(IDR_APP_TOP_CENTER);
-  int edge_height = titlebar_bottom->height() - kClientEdgeThickness;
-  canvas->TileImageInt(*titlebar_bottom, 0,
-                       frame()->client_view()->y() - edge_height,
-                       width(), edge_height);
-}
-
-void AppPanelBrowserFrameView::PaintTitleBar(gfx::Canvas* canvas) {
-  // The window icon is painted by the TabIconView.
-  views::WidgetDelegate* d = frame()->widget_delegate();
-  gfx::Rect rect = title_bounds_;
-  rect.set_x(GetMirroredXForRect(title_bounds_));
-  canvas->DrawStringRect(d->GetWindowTitle(), BrowserFrame::GetTitleFontList(),
-                         SK_ColorBLACK, rect);
-}
-
-void AppPanelBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) {
-  gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height());
-  int client_area_top = client_area_bounds.y();
-
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  gfx::ImageSkia* top_left = rb.GetImageSkiaNamed(IDR_APP_TOP_LEFT);
-  gfx::ImageSkia* top = rb.GetImageSkiaNamed(IDR_APP_TOP_CENTER);
-  gfx::ImageSkia* top_right = rb.GetImageSkiaNamed(IDR_APP_TOP_RIGHT);
-  gfx::ImageSkia* right = rb.GetImageSkiaNamed(IDR_CONTENT_RIGHT_SIDE);
-  gfx::ImageSkia* bottom_right =
-      rb.GetImageSkiaNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER);
-  gfx::ImageSkia* bottom = rb.GetImageSkiaNamed(IDR_CONTENT_BOTTOM_CENTER);
-  gfx::ImageSkia* bottom_left =
-      rb.GetImageSkiaNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER);
-  gfx::ImageSkia* left = rb.GetImageSkiaNamed(IDR_CONTENT_LEFT_SIDE);
-
-  // Top.
-  int top_edge_y = client_area_top - top->height();
-  canvas->DrawImageInt(*top_left, client_area_bounds.x() - top_left->width(),
-                       top_edge_y);
-  canvas->TileImageInt(*top, client_area_bounds.x(), top_edge_y,
-                       client_area_bounds.width(), top->height());
-  canvas->DrawImageInt(*top_right, client_area_bounds.right(), top_edge_y);
-
-  // Right.
-  int client_area_bottom =
-      std::max(client_area_top, client_area_bounds.bottom());
-  int client_area_height = client_area_bottom - client_area_top;
-  canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top,
-                       right->width(), client_area_height);
-
-  // Bottom.
-  canvas->DrawImageInt(*bottom_right, client_area_bounds.right(),
-                       client_area_bottom);
-  canvas->TileImageInt(*bottom, client_area_bounds.x(), client_area_bottom,
-                       client_area_bounds.width(), bottom_right->height());
-  canvas->DrawImageInt(*bottom_left,
-      client_area_bounds.x() - bottom_left->width(), client_area_bottom);
-
-  // Left.
-  canvas->TileImageInt(*left, client_area_bounds.x() - left->width(),
-      client_area_top, left->width(), client_area_height);
-
-  // Draw the color to fill in the edges.
-  canvas->DrawRect(gfx::Rect(
-      client_area_bounds.x() - kClientEdgeThickness,
-      client_area_top - kClientEdgeThickness,
-      client_area_bounds.width() + kClientEdgeThickness,
-      client_area_bottom - client_area_top + kClientEdgeThickness),
-      views::kClientEdgeColor);
-}
-
-void AppPanelBrowserFrameView::LayoutWindowControls() {
-  close_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
-                                   views::ImageButton::ALIGN_BOTTOM);
-  bool is_maximized = frame()->IsMaximized();
-  // There should always be the same number of non-border pixels visible to the
-  // side of the close button.  In maximized mode we extend the button to the
-  // screen corner to obey Fitts' Law.
-  int right_extra_width = is_maximized ? kCloseButtonFrameBorderSpacing : 0;
-  gfx::Size close_button_size = close_button_->GetPreferredSize();
-  int close_button_y =
-      (NonClientTopBorderHeight() - close_button_size.height()) / 2;
-  int top_extra_height = is_maximized ? close_button_y : 0;
-  close_button_->SetBounds(width() - FrameBorderThickness() -
-      kCloseButtonFrameBorderSpacing - close_button_size.width(),
-      close_button_y - top_extra_height,
-      close_button_size.width() + right_extra_width,
-      close_button_size.height() + top_extra_height);
-}
-
-void AppPanelBrowserFrameView::LayoutTitleBar() {
-  // Size the icon first; the window title is based on the icon position.
-  gfx::Rect icon_bounds(IconBounds());
-  window_icon_->SetBoundsRect(icon_bounds);
-
-  // Size the title.
-  int title_x = icon_bounds.right() + kIconTitleSpacing;
-  int title_height = BrowserFrame::GetTitleFontList().GetHeight();
-  // We bias the title position so that when the difference between the icon
-  // and title heights is odd, the extra pixel of the title is above the
-  // vertical midline rather than below.  This compensates for how the icon is
-  // already biased downwards (see IconBounds()) and helps prevent descenders
-  // on the title from overlapping the 3D edge at the bottom of the titlebar.
-  title_bounds_.SetRect(title_x,
-      icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2),
-      std::max(0, close_button_->x() - kTitleCloseButtonSpacing - title_x),
-      title_height);
-}
-
-gfx::Rect AppPanelBrowserFrameView::CalculateClientAreaBounds(int width,
-    int height) const {
-  int top_height = NonClientTopBorderHeight();
-  int border_thickness = NonClientBorderThickness();
-  return gfx::Rect(border_thickness, top_height,
-                   std::max(0, width - (2 * border_thickness)),
-                   std::max(0, height - top_height - border_thickness));
-}
diff --git a/chrome/browser/ui/views/frame/app_panel_browser_frame_view.h b/chrome/browser/ui/views/frame/app_panel_browser_frame_view.h
deleted file mode 100644
index bbb839b..0000000
--- a/chrome/browser/ui/views/frame/app_panel_browser_frame_view.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_APP_PANEL_BROWSER_FRAME_VIEW_H_
-#define CHROME_BROWSER_UI_VIEWS_FRAME_APP_PANEL_BROWSER_FRAME_VIEW_H_
-
-#include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h"
-#include "chrome/browser/ui/views/tab_icon_view_model.h"
-#include "ui/views/controls/button/button.h"
-
-class BrowserFrame;
-class BrowserView;
-class TabIconView;
-
-namespace views {
-class ImageButton;
-}
-
-// The frame view which is used for Application Panels.
-// TODO(rafaelw): Refactor. This shares much duplicated code with
-// OpaqueBrowserFrameView.
-class AppPanelBrowserFrameView : public BrowserNonClientFrameView,
-                                 public views::ButtonListener,
-                                 public chrome::TabIconViewModel {
- public:
-  // Constructs a non-client view for an BrowserFrame.
-  AppPanelBrowserFrameView(BrowserFrame* frame, BrowserView* browser_view);
-  virtual ~AppPanelBrowserFrameView();
-
-  // Overridden from BrowserNonClientFrameView:
-  virtual gfx::Rect GetBoundsForTabStrip(views::View* tabstrip) const OVERRIDE;
-  virtual int GetTopInset() const OVERRIDE;
-  virtual int GetThemeBackgroundXInset() const OVERRIDE;
-  virtual void UpdateThrobber(bool running) OVERRIDE;
-  virtual gfx::Size GetMinimumSize() OVERRIDE;
-
- protected:
-  // Overridden from views::NonClientFrameView:
-  virtual gfx::Rect GetBoundsForClientView() const OVERRIDE;
-  virtual gfx::Rect GetWindowBoundsForClientBounds(
-      const gfx::Rect& client_bounds) const OVERRIDE;
-  virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE;
-  virtual void GetWindowMask(const gfx::Size& size,
-                             gfx::Path* window_mask) OVERRIDE;
-  virtual void ResetWindowControls() OVERRIDE;
-  virtual void UpdateWindowIcon() OVERRIDE;
-
-  // Overridden from views::View:
-  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
-  virtual void Layout() OVERRIDE;
-
-  // Overridden from views::ButtonListener:
-  virtual void ButtonPressed(views::Button* sender,
-                             const ui::Event& event) OVERRIDE;
-
-  // Overridden from chrome::TabIconViewModel:
-  virtual bool ShouldTabIconViewAnimate() const OVERRIDE;
-  virtual gfx::ImageSkia GetFaviconForTabIconView() OVERRIDE;
-
- private:
-  // Returns the thickness of the border that makes up the window frame edges.
-  // This does not include any client edge.
-  int FrameBorderThickness() const;
-
-  // Returns the thickness of the entire nonclient left, right, and bottom
-  // borders, including both the window frame and any client edge.
-  int NonClientBorderThickness() const;
-
-  // Returns the height of the entire nonclient top border, including the window
-  // frame, any title area, and any connected client edge.
-  int NonClientTopBorderHeight() const;
-
-  // Returns the thickness of the nonclient portion of the 3D edge along the
-  // bottom of the titlebar.
-  int TitlebarBottomThickness() const;
-
-  // Returns the size of the titlebar icon.
-  int IconSize() const;
-
-  // Returns the bounds of the titlebar icon.
-  gfx::Rect IconBounds() const;
-
-  // Paint various sub-components of this view.  The *FrameBorder() function
-  // also paints the background of the titlebar area, since the top frame border
-  // and titlebar background are a contiguous component.
-  void PaintRestoredFrameBorder(gfx::Canvas* canvas);
-  void PaintMaximizedFrameBorder(gfx::Canvas* canvas);
-  void PaintTitleBar(gfx::Canvas* canvas);
-  void PaintRestoredClientEdge(gfx::Canvas* canvas);
-
-  // Layout various sub-components of this view.
-  void LayoutWindowControls();
-  void LayoutTitleBar();
-
-  // Returns the bounds of the client area for the specified view size.
-  gfx::Rect CalculateClientAreaBounds(int width, int height) const;
-
-  // The layout rect of the title, if visible.
-  gfx::Rect title_bounds_;
-
-  // Window controls.
-  views::ImageButton* close_button_;
-
-  // The Window icon.
-  TabIconView* window_icon_;
-
-  // The bounds of the ClientView.
-  gfx::Rect client_view_bounds_;
-
-  DISALLOW_COPY_AND_ASSIGN(AppPanelBrowserFrameView);
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_FRAME_APP_PANEL_BROWSER_FRAME_VIEW_H_
diff --git a/chrome/browser/ui/views/frame/browser_frame.cc b/chrome/browser/ui/views/frame/browser_frame.cc
index ca38b78..627effc 100644
--- a/chrome/browser/ui/views/frame/browser_frame.cc
+++ b/chrome/browser/ui/views/frame/browser_frame.cc
@@ -191,6 +191,15 @@
   return use_custom_frame_pref_.GetValue();
 }
 
+bool BrowserFrame::ShouldSaveWindowPlacement() const {
+  return native_browser_frame_->ShouldSaveWindowPlacement();
+}
+
+void BrowserFrame::GetWindowPlacement(gfx::Rect* bounds,
+                                      ui::WindowShowState* show_state) const {
+  return native_browser_frame_->GetWindowPlacement(bounds, show_state);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // BrowserFrame, views::Widget overrides:
 
diff --git a/chrome/browser/ui/views/frame/browser_frame.h b/chrome/browser/ui/views/frame/browser_frame.h
index 87bdea0..3fa17e7 100644
--- a/chrome/browser/ui/views/frame/browser_frame.h
+++ b/chrome/browser/ui/views/frame/browser_frame.h
@@ -79,6 +79,13 @@
   // Returns |true| if we should use the custom frame.
   bool UseCustomFrame() const;
 
+  // Returns true when the window placement should be saved.
+  bool ShouldSaveWindowPlacement() const;
+
+  // Retrieves the window placement (show state and bounds) for restoring.
+  void GetWindowPlacement(gfx::Rect* bounds,
+                          ui::WindowShowState* show_state) const;
+
   // Overridden from views::Widget:
   virtual views::internal::RootView* CreateRootView() OVERRIDE;
   virtual views::NonClientFrameView* CreateNonClientFrameView() OVERRIDE;
diff --git a/chrome/browser/ui/views/frame/browser_frame_ash.cc b/chrome/browser/ui/views/frame/browser_frame_ash.cc
index 5cd1ac0..eda4329 100644
--- a/chrome/browser/ui/views/frame/browser_frame_ash.cc
+++ b/chrome/browser/ui/views/frame/browser_frame_ash.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/views/frame/browser_frame_ash.h"
 
+#include "ash/wm/window_properties.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_state_delegate.h"
 #include "ash/wm/window_util.h"
@@ -97,6 +98,27 @@
   views::NativeWidgetAura::OnWindowTargetVisibilityChanged(visible);
 }
 
+bool BrowserFrameAsh::ShouldSaveWindowPlacement() const {
+  return NULL == GetWidget()->GetNativeWindow()->GetProperty(
+                     ash::kRestoreBoundsOverrideKey);
+}
+
+void BrowserFrameAsh::GetWindowPlacement(
+    gfx::Rect* bounds,
+    ui::WindowShowState* show_state) const {
+  gfx::Rect* override_bounds = GetWidget()->GetNativeWindow()->GetProperty(
+                                   ash::kRestoreBoundsOverrideKey);
+  if (override_bounds && !override_bounds->IsEmpty()) {
+    *bounds = *override_bounds;
+    *show_state = GetWidget()->GetNativeWindow()->GetProperty(
+                      ash::kRestoreShowStateOverrideKey);
+  } else {
+    *bounds = GetWidget()->GetRestoredBounds();
+    *show_state = GetWidget()->GetNativeWindow()->GetProperty(
+                      aura::client::kShowStateKey);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // BrowserFrameAsh, NativeBrowserFrame implementation:
 
diff --git a/chrome/browser/ui/views/frame/browser_frame_ash.h b/chrome/browser/ui/views/frame/browser_frame_ash.h
index e55be39..f64ac7f 100644
--- a/chrome/browser/ui/views/frame/browser_frame_ash.h
+++ b/chrome/browser/ui/views/frame/browser_frame_ash.h
@@ -38,6 +38,11 @@
   virtual const views::NativeWidget* AsNativeWidget() const OVERRIDE;
   virtual bool UsesNativeSystemMenu() const OVERRIDE;
   virtual int GetMinimizeButtonOffset() const OVERRIDE;
+  virtual bool ShouldSaveWindowPlacement() const OVERRIDE;
+  virtual void GetWindowPlacement(
+      gfx::Rect* bounds,
+      ui::WindowShowState* show_state) const OVERRIDE;
+
 
   virtual ~BrowserFrameAsh();
 
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index ed3cdb1..52f8024 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -107,7 +107,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_switches.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
@@ -141,14 +140,6 @@
 #include "ui/views/widget/widget.h"
 #include "ui/views/window/dialog_delegate.h"
 
-#if defined(USE_ASH)
-#include "ash/ash_switches.h"
-#include "ash/shelf/shelf.h"
-#include "ash/shelf/shelf_model.h"
-#include "ash/shell.h"
-#include "chrome/browser/ui/ash/ash_util.h"
-#endif
-
 #if defined(OS_WIN)
 #include "base/win/windows_version.h"
 #include "chrome/browser/jumplist_win.h"
@@ -257,10 +248,6 @@
     return browser_view_->contents_web_view_;
   }
 
-  virtual views::View* GetWindowSwitcherButton() const OVERRIDE {
-    return browser_view_->window_switcher_button();
-  }
-
   virtual bool DownloadShelfNeedsLayout() const OVERRIDE {
     DownloadShelfView* download_shelf = browser_view_->download_shelf_.get();
     // Re-layout the shelf either if it is visible or if its close animation
@@ -403,7 +390,6 @@
       top_container_(NULL),
       tabstrip_(NULL),
       toolbar_(NULL),
-      window_switcher_button_(NULL),
       find_bar_host_view_(NULL),
       infobar_container_(NULL),
       contents_web_view_(NULL),
@@ -832,7 +818,7 @@
       GetWidget()->IsVisible()) {
     // We only restore focus if our window is visible, to avoid invoking blur
     // handlers when we are eventually shown.
-    new_contents->GetView()->RestoreFocus();
+    new_contents->RestoreFocus();
   }
 
   // Update all the UI bits.
@@ -845,15 +831,17 @@
 }
 
 gfx::Rect BrowserView::GetRestoredBounds() const {
-  return frame_->GetRestoredBounds();
+  gfx::Rect bounds;
+  ui::WindowShowState state;
+  frame_->GetWindowPlacement(&bounds, &state);
+  return bounds;
 }
 
 ui::WindowShowState BrowserView::GetRestoredState() const {
-  if (IsMaximized())
-    return ui::SHOW_STATE_MAXIMIZED;
-  if (IsMinimized())
-    return ui::SHOW_STATE_MINIMIZED;
-  return ui::SHOW_STATE_NORMAL;
+  gfx::Rect bounds;
+  ui::WindowShowState state;
+  frame_->GetWindowPlacement(&bounds, &state);
+  return state;
 }
 
 gfx::Rect BrowserView::GetBounds() const {
@@ -942,13 +930,7 @@
 void BrowserView::RestoreFocus() {
   WebContents* selected_web_contents = GetActiveWebContents();
   if (selected_web_contents)
-    selected_web_contents->GetView()->RestoreFocus();
-}
-
-void BrowserView::SetWindowSwitcherButton(views::Button* button) {
-  if (window_switcher_button_)
-    RemoveChildView(window_switcher_button_);
-  window_switcher_button_ = button;
+    selected_web_contents->RestoreFocus();
 }
 
 void BrowserView::FullscreenStateChanged() {
@@ -1174,10 +1156,6 @@
                                     extension_id);
 }
 
-void BrowserView::ShowBookmarkPrompt() {
-  GetLocationBarView()->ShowBookmarkPrompt();
-}
-
 void BrowserView::ShowTranslateBubble(content::WebContents* web_contents,
                                       translate::TranslateStep step,
                                       TranslateErrors::Type error_type) {
@@ -1432,12 +1410,12 @@
   // window yet. Per http://crbug/342672 add them now since drawing the
   // WebContents requires root window specific data - information about
   // the screen the WebContents is drawn on, for example.
-  if (!contents->GetView()->GetNativeView()->GetRootWindow()) {
-    aura::Window* window = contents->GetView()->GetNativeView();
+  if (!contents->GetNativeView()->GetRootWindow()) {
+    aura::Window* window = contents->GetNativeView();
     aura::Window* root_window = GetNativeWindow()->GetRootWindow();
     aura::client::ParentWindowWithContext(
         window, root_window, root_window->GetBoundsInScreen());
-    DCHECK(contents->GetView()->GetNativeView()->GetRootWindow());
+    DCHECK(contents->GetNativeView()->GetRootWindow());
   }
   web_contents_close_handler_->TabInserted();
 
@@ -1471,7 +1449,7 @@
   // Some reports seem to show that the focus manager and/or focused view can
   // be garbage at that point, it is not clear why.
   if (!contents->IsBeingDestroyed())
-    contents->GetView()->StoreFocus();
+    contents->StoreFocus();
 }
 
 void BrowserView::TabStripEmpty() {
@@ -1613,7 +1591,8 @@
   // If IsFullscreen() is true, we've just changed into fullscreen mode, and
   // we're catching the going-into-fullscreen sizing and positioning calls,
   // which we want to ignore.
-  if (!IsFullscreen() && chrome::ShouldSaveWindowPlacement(browser_.get())) {
+  if (!IsFullscreen() && frame_->ShouldSaveWindowPlacement() &&
+      chrome::ShouldSaveWindowPlacement(browser_.get())) {
     WidgetDelegate::SaveWindowPlacement(bounds, show_state);
     chrome::SaveWindowPlacement(browser_.get(), bounds, show_state);
   }
@@ -1972,9 +1951,6 @@
   find_bar_host_view_ = new View();
   AddChildView(find_bar_host_view_);
 
-  if (window_switcher_button_)
-    AddChildView(window_switcher_button_);
-
   immersive_mode_controller_->Init(this);
 
   BrowserViewLayout* browser_view_layout = new BrowserViewLayout;
@@ -2507,7 +2483,7 @@
 bool BrowserView::DoCutCopyPasteForWebContents(
     WebContents* contents,
     void (WebContents::*method)()) {
-  gfx::NativeView native_view = contents->GetView()->GetContentNativeView();
+  gfx::NativeView native_view = contents->GetContentNativeView();
   if (!native_view)
     return false;
   if (native_view->HasFocus()) {
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 7f3221a..6a88847 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -239,12 +239,6 @@
   // when a new browser window is created.
   void RestoreFocus();
 
-  void SetWindowSwitcherButton(views::Button* button);
-
-  views::Button* window_switcher_button() {
-    return window_switcher_button_;
-  }
-
   // Called after the widget's fullscreen state is changed without going through
   // FullscreenController. This method does any processing which was skipped.
   // Only exiting fullscreen in this way is currently supported.
@@ -325,7 +319,6 @@
   virtual void ShowBookmarkAppBubble(
       const WebApplicationInfo& web_app_info,
       const std::string& extension_id) OVERRIDE;
-  virtual void ShowBookmarkPrompt() OVERRIDE;
   virtual void ShowTranslateBubble(content::WebContents* contents,
                                    translate::TranslateStep step,
                                    TranslateErrors::Type error_type) OVERRIDE;
@@ -635,11 +628,6 @@
   // The Toolbar containing the navigation buttons, menus and the address bar.
   ToolbarView* toolbar_;
 
-  // This button sits next to the tabs on the right hand side and it is used
-  // only in windows metro metro mode to allow the user to flip among browser
-  // windows.
-  views::Button* window_switcher_button_;
-
   // The Bookmark Bar View for this window. Lazily created. May be NULL for
   // non-tabbed browsers like popups. May not be visible.
   scoped_ptr<BookmarkBarView> bookmark_bar_view_;
diff --git a/chrome/browser/ui/views/frame/browser_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_view_browsertest.cc
index 236e774..e573e1b 100644
--- a/chrome/browser/ui/views/frame/browser_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_browsertest.cc
@@ -26,8 +26,7 @@
         other_(other) {}
   virtual ~TestWebContentsObserver() {}
 
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     other_->NotifyNavigationStateChanged(
         content::INVALIDATE_TYPE_URL | content::INVALIDATE_TYPE_LOAD);
   }
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc
index 7f22c40..601ed11 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout.cc
+++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -39,8 +39,6 @@
 // The visible height of the shadow above the tabs. Clicks in this area are
 // treated as clicks to the frame, rather than clicks to the tab.
 const int kTabShadowSize = 2;
-// The number of pixels the metro switcher is offset from the right edge.
-const int kWindowSwitcherOffsetX = 7;
 // The number of pixels the constrained window should overlap the bottom
 // of the omnibox.
 const int kConstrainedWindowOverlap = 3;
@@ -296,27 +294,16 @@
   if (bv_bounds.Contains(point))
     return HTCLIENT;
 
-  // If the point is within the bounds of the window switcher button, the point
-  // is considered to be within the client area.
-  views::View* window_switcher_button = delegate_->GetWindowSwitcherButton();
-  if (window_switcher_button && window_switcher_button->visible()) {
-    gfx::Point window_switcher_point(point_in_browser_view_coords);
-    views::View::ConvertPointToTarget(browser_view_, window_switcher_button,
-                                      &window_switcher_point);
-    if (window_switcher_button->HitTestPoint(window_switcher_point))
-      return HTCLIENT;
-  }
-
-  // If the point's y coordinate is above the top of the toolbar, but neither
-  // over the tabstrip nor over the window switcher button (per previous
-  // checking in this function), then we consider it in the window caption
-  // (e.g. the area to the right of the tabstrip underneath the window
-  // controls). However, note that we DO NOT return HTCAPTION here, because
-  // when the window is maximized the window controls will fall into this
-  // space (since the BrowserView is sized to entire size of the window at that
-  // point), and the HTCAPTION value will cause the window controls not to work.
-  // So we return HTNOWHERE so that the caller will hit-test the window controls
-  // before finally falling back to HTCAPTION.
+  // If the point's y coordinate is above the top of the toolbar, but not
+  // over the tabstrip (per previous checking in this function), then we
+  // consider it in the window caption (e.g. the area to the right of the
+  // tabstrip underneath the window controls). However, note that we DO NOT
+  // return HTCAPTION here, because when the window is maximized the window
+  // controls will fall into this space (since the BrowserView is sized to
+  // entire size of the window at that point), and the HTCAPTION value will
+  // cause the window controls not to work. So we return HTNOWHERE so that the
+  // caller will hit-test the window controls before finally falling back to
+  // HTCAPTION.
   bv_bounds = browser_view_->bounds();
   bv_bounds.set_height(toolbar_->y());
   if (bv_bounds.Contains(point))
@@ -402,39 +389,8 @@
 
   tab_strip_->SetVisible(true);
   tab_strip_->SetBoundsRect(tabstrip_bounds);
-  int bottom = tabstrip_bounds.bottom();
 
-  // The metro window switcher sits at the far right edge of the tabstrip
-  // a |kWindowSwitcherOffsetX| pixels from the right edge.
-  // Only visible if there is more than one type of window to switch between.
-  // TODO(mad): update this code when more window types than just incognito
-  // and regular are available.
-  views::View* switcher_button = delegate_->GetWindowSwitcherButton();
-  if (switcher_button) {
-    if (browser()->profile()->HasOffTheRecordProfile() &&
-        chrome::FindBrowserWithProfile(
-            browser()->profile()->GetOriginalProfile(),
-            browser()->host_desktop_type()) != NULL) {
-      switcher_button->SetVisible(true);
-      int width = browser_view_->width();
-      gfx::Size ps = switcher_button->GetPreferredSize();
-      if (width > ps.width()) {
-        switcher_button->SetBounds(width - ps.width() - kWindowSwitcherOffsetX,
-                                   0,
-                                   ps.width(),
-                                   ps.height());
-      }
-    } else {
-      // We hide the button if the incognito profile is not alive.
-      // Note that Layout() is not called to all browser windows automatically
-      // when a profile goes away but we rely in the metro_driver.dll to call
-      // ::SetWindowPos( , .. SWP_SHOWWINDOW) which causes this function to
-      // be called again. This works both in showing or hidding the button.
-      switcher_button->SetVisible(false);
-    }
-  }
-
-  return bottom;
+  return tabstrip_bounds.bottom();
 }
 
 int BrowserViewLayout::LayoutToolbar(int top) {
diff --git a/chrome/browser/ui/views/frame/browser_view_layout_delegate.h b/chrome/browser/ui/views/frame/browser_view_layout_delegate.h
index a2f2531..3f443d9 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout_delegate.h
+++ b/chrome/browser/ui/views/frame/browser_view_layout_delegate.h
@@ -21,7 +21,6 @@
   virtual ~BrowserViewLayoutDelegate() {}
 
   virtual views::View* GetContentsWebView() const = 0;
-  virtual views::View* GetWindowSwitcherButton() const = 0;
   virtual bool IsTabStripVisible() const = 0;
   virtual gfx::Rect GetBoundsForTabStripInBrowserView() const = 0;
   virtual int GetTopInsetInBrowserView() const = 0;
diff --git a/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc b/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc
index 461a40e..ff080b0 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc
@@ -41,11 +41,6 @@
   virtual views::View* GetContentsWebView() const OVERRIDE {
     return contents_web_view_;
   }
-  virtual views::View* GetWindowSwitcherButton() const OVERRIDE {
-    // TODO(jamescook): Add a test for Windows that exercises the layout for
-    // this button.
-    return NULL;
-  }
   virtual bool IsTabStripVisible() const OVERRIDE {
     return tab_strip_visible_;
   }
diff --git a/chrome/browser/ui/views/frame/browser_window_property_manager_browsertest_win.cc b/chrome/browser/ui/views/frame/browser_window_property_manager_browsertest_win.cc
index 41cbd3c..50b4492 100644
--- a/chrome/browser/ui/views/frame/browser_window_property_manager_browsertest_win.cc
+++ b/chrome/browser/ui/views/frame/browser_window_property_manager_browsertest_win.cc
@@ -82,6 +82,25 @@
                 browser->profile()->GetPath()).value(),
             prop_var.get().pwszVal);
   prop_var.Reset();
+  base::MessageLoop::current()->Quit();
+}
+
+void PostValidationTaskToUIThread(const base::Closure& validation_task) {
+  content::BrowserThread::PostTask(
+      content::BrowserThread::UI, FROM_HERE, validation_task);
+}
+
+// Posts a validation task to the FILE thread which bounces back to the UI
+// thread and then does validation. This is necessary because the icon profile
+// pref only gets set at the end of icon creation (which happens on the FILE
+// thread) and is set on the UI thread.
+void WaitAndValidateBrowserWindowProperties(
+    const base::Closure& validation_task) {
+  content::BrowserThread::PostTask(
+      content::BrowserThread::FILE,
+      FROM_HERE,
+      base::Bind(&PostValidationTaskToUIThread, validation_task));
+  content::RunMessageLoop();
 }
 
 }  // namespace
@@ -100,10 +119,9 @@
   DISALLOW_COPY_AND_ASSIGN(BrowserTestWithProfileShortcutManager);
 };
 
-// Test is flaky on Win7 bots. See crbug.com/332628.
 // Check that the window properties on Windows are properly set.
 IN_PROC_BROWSER_TEST_F(BrowserTestWithProfileShortcutManager,
-                       DISABLED_WindowProperties) {
+                       WindowProperties) {
 #if defined(USE_ASH)
   // Disable this test in Metro+Ash where Windows window properties aren't used.
   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
@@ -115,7 +133,8 @@
     return;
 
   // Single profile case. The profile name should not be shown.
-  ValidateBrowserWindowProperties(browser(), base::string16());
+  WaitAndValidateBrowserWindowProperties(base::Bind(
+      &ValidateBrowserWindowProperties, browser(), base::string16()));
 
   // If multiprofile mode is not enabled, we can't test the behavior when there
   // are multiple profiles.
@@ -138,13 +157,17 @@
   content::RunMessageLoop();
 
   // The default profile's name should be part of the relaunch name.
-  ValidateBrowserWindowProperties(
-      browser(), base::UTF8ToUTF16(browser()->profile()->GetProfileName()));
+  WaitAndValidateBrowserWindowProperties(
+      base::Bind(&ValidateBrowserWindowProperties,
+                 browser(),
+                 base::UTF8ToUTF16(browser()->profile()->GetProfileName())));
 
   // The second profile's name should be part of the relaunch name.
   Browser* profile2_browser =
       CreateBrowser(profile_manager->GetProfileByPath(path_profile2));
   size_t profile2_index = cache.GetIndexOfProfileWithPath(path_profile2);
-  ValidateBrowserWindowProperties(
-      profile2_browser, cache.GetNameOfProfileAtIndex(profile2_index));
+  WaitAndValidateBrowserWindowProperties(
+      base::Bind(&ValidateBrowserWindowProperties,
+                 profile2_browser,
+                 cache.GetNameOfProfileAtIndex(profile2_index)));
 }
diff --git a/chrome/browser/ui/views/frame/contents_web_view.cc b/chrome/browser/ui/views/frame/contents_web_view.cc
index 82576ca..234873c 100644
--- a/chrome/browser/ui/views/frame/contents_web_view.cc
+++ b/chrome/browser/ui/views/frame/contents_web_view.cc
@@ -7,7 +7,6 @@
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/views/status_bubble_views.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/aura/window.h"
 #include "ui/base/theme_provider.h"
 #include "ui/compositor/layer_tree_owner.h"
@@ -84,8 +83,7 @@
 void ContentsWebView::CloneWebContentsLayer() {
   if (!web_contents())
     return;
-  cloned_layer_tree_ = wm::RecreateLayers(
-      web_contents()->GetView()->GetNativeView());
+  cloned_layer_tree_ = wm::RecreateLayers(web_contents()->GetNativeView());
   if (!cloned_layer_tree_ || !cloned_layer_tree_->root()) {
     cloned_layer_tree_.reset();
     return;
diff --git a/chrome/browser/ui/views/frame/desktop_browser_frame_aura.cc b/chrome/browser/ui/views/frame/desktop_browser_frame_aura.cc
index b114390..8ef74b6 100644
--- a/chrome/browser/ui/views/frame/desktop_browser_frame_aura.cc
+++ b/chrome/browser/ui/views/frame/desktop_browser_frame_aura.cc
@@ -92,3 +92,20 @@
 int DesktopBrowserFrameAura::GetMinimizeButtonOffset() const {
   return browser_desktop_window_tree_host_->GetMinimizeButtonOffset();
 }
+
+bool DesktopBrowserFrameAura::ShouldSaveWindowPlacement() const {
+  // The placement can always be stored.
+  return true;
+}
+
+void DesktopBrowserFrameAura::GetWindowPlacement(
+    gfx::Rect* bounds,
+    ui::WindowShowState* show_state) const {
+  *bounds = GetWidget()->GetRestoredBounds();
+  if (IsMaximized())
+    *show_state = ui::SHOW_STATE_MAXIMIZED;
+  else if (IsMinimized())
+    *show_state = ui::SHOW_STATE_MINIMIZED;
+  else
+    *show_state = ui::SHOW_STATE_NORMAL;
+}
diff --git a/chrome/browser/ui/views/frame/desktop_browser_frame_aura.h b/chrome/browser/ui/views/frame/desktop_browser_frame_aura.h
index 66f3da2..bba21fb 100644
--- a/chrome/browser/ui/views/frame/desktop_browser_frame_aura.h
+++ b/chrome/browser/ui/views/frame/desktop_browser_frame_aura.h
@@ -46,6 +46,10 @@
   virtual const views::NativeWidget* AsNativeWidget() const OVERRIDE;
   virtual bool UsesNativeSystemMenu() const OVERRIDE;
   virtual int GetMinimizeButtonOffset() const OVERRIDE;
+  virtual bool ShouldSaveWindowPlacement() const OVERRIDE;
+  virtual void GetWindowPlacement(
+      gfx::Rect* bounds,
+      ui::WindowShowState* show_state) const OVERRIDE;
 
  private:
   // The BrowserView is our ClientView. This is a pointer to it.
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
index 62cc54b..38edf31 100644
--- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
@@ -448,17 +448,21 @@
 
   int button_x = frame()->GetMinimizeButtonOffset() -
       kNewAvatarButtonOffset - label_size.width();
-
   if (base::i18n::IsRTL())
     button_x = width() - frame()->GetMinimizeButtonOffset() +
         kNewAvatarButtonOffset;
-
   int button_y = frame()->IsMaximized() ? NonClientTopBorderHeight() : 1;
+
+  // If the window is maximized, the button is 2 pixels too tall. Determined
+  // via visual inspection.
+  int height_to_subtract = frame()->IsMaximized() ? 2 : 0;
+
   new_avatar_button()->SetBounds(
       button_x,
       button_y,
       label_size.width(),
-      button_y + gfx::win::GetSystemMetricsInDIP(SM_CXMENUSIZE));
+      button_y + gfx::win::GetSystemMetricsInDIP(SM_CXMENUSIZE) -
+          height_to_subtract);
 }
 
 void GlassBrowserFrameView::LayoutAvatar() {
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
index 6a81264..d7f12d2 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/aura/window.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
diff --git a/chrome/browser/ui/views/frame/native_browser_frame.h b/chrome/browser/ui/views/frame/native_browser_frame.h
index 1aea739..846d9e7 100644
--- a/chrome/browser/ui/views/frame/native_browser_frame.h
+++ b/chrome/browser/ui/views/frame/native_browser_frame.h
@@ -5,6 +5,9 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_FRAME_NATIVE_BROWSER_FRAME_H_
 #define CHROME_BROWSER_UI_VIEWS_FRAME_NATIVE_BROWSER_FRAME_H_
 
+#include "ui/base/ui_base_types.h"
+#include "ui/gfx/rect.h"
+
 class BrowserFrame;
 class BrowserView;
 
@@ -23,6 +26,13 @@
   // false means BrowserFrame handles showing the system menu.
   virtual bool UsesNativeSystemMenu() const = 0;
 
+  // Returns true when the window placement should be stored.
+  virtual bool ShouldSaveWindowPlacement() const = 0;
+
+  // Retrieves the window placement (show state and bounds) for restoring.
+  virtual void GetWindowPlacement(gfx::Rect* bounds,
+                                  ui::WindowShowState* show_state) const = 0;
+
  protected:
   friend class BrowserFrame;
 
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
index 7713dc4..979fa0b 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
@@ -325,25 +325,9 @@
     return tabstrip->IsRectInWindowCaption(rect_in_tabstrip_coords);
   }
 
-  // The window switcher button is to the right of the tabstrip but is
-  // part of the client view.
-  views::View* window_switcher_button =
-      browser_view()->window_switcher_button();
-  if (window_switcher_button && window_switcher_button->visible()) {
-    gfx::RectF rect_in_window_switcher_coords_f(rect);
-    View::ConvertRectToTarget(this, window_switcher_button,
-        &rect_in_window_switcher_coords_f);
-    gfx::Rect rect_in_window_switcher_coords = gfx::ToEnclosingRect(
-        rect_in_window_switcher_coords_f);
-
-    if (window_switcher_button->HitTestRect(rect_in_window_switcher_coords))
-      return false;
-  }
-
   // We claim |rect| because it is above the bottom of the tabstrip, but
-  // neither in the tabstrip nor in the window switcher button. In particular,
-  // the avatar label/button is left of the tabstrip and the window controls
-  // are right of the tabstrip.
+  // not in the tabstrip itself. In particular, the avatar label/button is left
+  // of the tabstrip and the window controls are right of the tabstrip.
   return true;
 }
 
@@ -503,15 +487,6 @@
   return browser_view()->GetTabStripHeight();
 }
 
-int OpaqueBrowserFrameView::GetAdditionalReservedSpaceInTabStrip() const {
-  // We don't have the sysmenu buttons in Windows 8 metro mode. However there
-  // are buttons like the window switcher which are drawn in the non client
-  // are in the BrowserView. We need to ensure that the tab strip does not
-  // draw on the window switcher button.
-  views::View* button = browser_view()->window_switcher_button();
-  return button ? button->width() : 0;
-}
-
 gfx::Size OpaqueBrowserFrameView::GetTabstripPreferredSize() const {
   gfx::Size s = browser_view()->tabstrip()->GetPreferredSize();
   return s;
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.h b/chrome/browser/ui/views/frame/opaque_browser_frame_view.h
index 3673128..9b07590 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.h
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.h
@@ -95,7 +95,6 @@
   virtual bool IsFullscreen() const OVERRIDE;
   virtual bool IsTabStripVisible() const OVERRIDE;
   virtual int GetTabStripHeight() const OVERRIDE;
-  virtual int GetAdditionalReservedSpaceInTabStrip() const OVERRIDE;
   virtual gfx::Size GetTabstripPreferredSize() const OVERRIDE;
 
  protected:
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc
index 4847dfa..d17cf76 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc
@@ -137,9 +137,6 @@
   available_width -= trailing_button_start_;
   available_width -= leading_button_start_;
 
-  if (delegate_->GetAdditionalReservedSpaceInTabStrip())
-    available_width -= delegate_->GetAdditionalReservedSpaceInTabStrip();
-
   const int caption_spacing = NewTabCaptionSpacing();
   const int tabstrip_width = available_width - caption_spacing;
   gfx::Rect bounds(leading_button_start_, GetTabStripInsetsTop(false),
@@ -391,6 +388,9 @@
   int button_x = host->width() - trailing_button_start_ -
       button_size_with_offset;
   int button_y = CaptionButtonY(false);
+  // If the window is maximized, the button is 1 pixel too short. Determined
+  // via visual inspection.
+  int extra_height = IsTitleBarCondensed() ? 1 : 0;
 
   trailing_button_start_ += button_size_with_offset;
   minimum_size_for_buttons_ += button_size_with_offset;
@@ -399,7 +399,7 @@
       button_x,
       button_y,
       label_size.width(),
-      button_y + kCaptionButtonHeightWithPadding);
+      button_y + kCaptionButtonHeightWithPadding + extra_height);
 }
 
 void OpaqueBrowserFrameViewLayout::LayoutAvatar(views::View* host) {
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_delegate.h b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_delegate.h
index 7c0e61a..b3bcf88 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_delegate.h
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_delegate.h
@@ -54,11 +54,6 @@
   virtual bool IsTabStripVisible() const = 0;
   virtual int GetTabStripHeight() const = 0;
 
-  // Various platforms need to be able to add more space to the
-  // tabstrip. Windows 8 metro mode uses this to account for the window
-  // switcher button.
-  virtual int GetAdditionalReservedSpaceInTabStrip() const = 0;
-
   // Returns the tabstrips preferred size so the frame layout can work around
   // it.
   virtual gfx::Size GetTabstripPreferredSize() const = 0;
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc
index ea8df4d..518380f 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc
@@ -128,10 +128,6 @@
     return IsTabStripVisible() ? Tab::GetMinimumUnselectedSize().height() : 0;
   }
 
-  virtual int GetAdditionalReservedSpaceInTabStrip() const OVERRIDE {
-    return 0;
-  }
-
   virtual gfx::Size GetTabstripPreferredSize() const OVERRIDE {
     // Measured from Tabstrip::GetPreferredSize().
     return IsTabStripVisible() ? gfx::Size(78, 29) : gfx::Size(0, 0);
diff --git a/chrome/browser/ui/views/hung_renderer_view.cc b/chrome/browser/ui/views/hung_renderer_view.cc
index a663391..5f3242a 100644
--- a/chrome/browser/ui/views/hung_renderer_view.cc
+++ b/chrome/browser/ui/views/hung_renderer_view.cc
@@ -21,7 +21,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/result_codes.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
@@ -156,8 +155,7 @@
   model_->TabDestroyed(this);
 }
 
-void HungPagesTableModel::WebContentsObserverImpl::WebContentsDestroyed(
-    WebContents* tab) {
+void HungPagesTableModel::WebContentsObserverImpl::WebContentsDestroyed() {
   model_->TabDestroyed(this);
 }
 
@@ -197,7 +195,7 @@
 // static
 bool HungRendererDialogView::IsFrameActive(WebContents* contents) {
   gfx::NativeView frame_view =
-      platform_util::GetTopLevel(contents->GetView()->GetNativeView());
+      platform_util::GetTopLevel(contents->GetNativeView());
   return platform_util::IsWindowActive(frame_view);
 }
 
@@ -244,7 +242,7 @@
     }
 
     gfx::NativeView frame_view =
-        platform_util::GetTopLevel(contents->GetView()->GetNativeView());
+        platform_util::GetTopLevel(contents->GetNativeView());
     views::Widget* insert_after =
         views::Widget::GetWidgetForNativeView(frame_view);
     if (insert_after)
@@ -441,7 +439,7 @@
     return;
 
   gfx::NativeView toplevel_view =
-      platform_util::GetTopLevel(contents->GetView()->GetNativeView());
+      platform_util::GetTopLevel(contents->GetNativeView());
   // Don't show the dialog if there is no root window for the renderer, because
   // it's invisible to the user (happens when the renderer is for prerendering
   // for example).
diff --git a/chrome/browser/ui/views/hung_renderer_view.h b/chrome/browser/ui/views/hung_renderer_view.h
index 2f4c945..2f661af 100644
--- a/chrome/browser/ui/views/hung_renderer_view.h
+++ b/chrome/browser/ui/views/hung_renderer_view.h
@@ -75,7 +75,7 @@
 
     // WebContentsObserver overrides:
     virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
-    virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE;
+    virtual void WebContentsDestroyed() OVERRIDE;
 
    private:
     HungPagesTableModel* model_;
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc
index 5328e2d..5f65f66 100644
--- a/chrome/browser/ui/views/infobars/infobar_view.cc
+++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -399,6 +399,7 @@
        infobars::InfoBarDelegate::WARNING_TYPE) ?
           IDS_ACCNAME_INFOBAR_WARNING : IDS_ACCNAME_INFOBAR_PAGE_ACTION);
   state->role = ui::AX_ROLE_ALERT;
+  state->keyboard_shortcut = base::ASCIIToUTF16("Alt+Shift+A");
 }
 
 gfx::Size InfoBarView::GetPreferredSize() {
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 7cf47bd..82d54b9 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -38,12 +38,11 @@
 #include "chrome/browser/ui/omnibox/location_bar_util.h"
 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
 #include "chrome/browser/ui/omnibox/omnibox_popup_view.h"
-#include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h"
 #include "chrome/browser/ui/passwords/manage_passwords_icon.h"
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/toolbar/origin_chip_info.h"
 #include "chrome/browser/ui/view_ids.h"
-#include "chrome/browser/ui/views/bookmarks/bookmark_prompt_view.h"
 #include "chrome/browser/ui/views/browser_dialogs.h"
 #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h"
 #include "chrome/browser/ui/views/location_bar/ev_bubble_view.h"
@@ -378,8 +377,7 @@
   open_pdf_in_reader_view_ = new OpenPDFInReaderView();
   AddChildView(open_pdf_in_reader_view_);
 
-  manage_passwords_icon_view_ = new ManagePasswordsIconView(delegate_);
-  manage_passwords_icon_view_->SetState(ManagePasswordsIcon::INACTIVE_STATE);
+  manage_passwords_icon_view_ = new ManagePasswordsIconView(command_updater());
   AddChildView(manage_passwords_icon_view_);
 
   translate_icon_view_ = new TranslateIconView(command_updater());
@@ -557,11 +555,6 @@
   translate_icon_view_->SetToggled(on);
 }
 
-void LocationBarView::ShowBookmarkPrompt() {
-  if (star_view_ && star_view_->visible())
-    BookmarkPromptView::ShowPrompt(star_view_, profile()->GetPrefs());
-}
-
 gfx::Point LocationBarView::GetOmniboxViewOrigin() const {
   gfx::Point origin(omnibox_view_->bounds().origin());
   // If the UI layout is RTL, the coordinate system is not transformed and
@@ -1193,7 +1186,7 @@
   if (!web_contents)
     return false;
   const bool was_visible = manage_passwords_icon_view_->visible();
-  ManagePasswordsBubbleUIController::FromWebContents(
+  ManagePasswordsUIController::FromWebContents(
       web_contents)->UpdateIconAndBubbleState(manage_passwords_icon_view_);
   return was_visible != manage_passwords_icon_view_->visible();
 }
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h
index 81eced4..7f9bd24 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -199,9 +199,6 @@
     toolbar_origin_chip_view_ = toolbar_origin_chip_view;
   }
 
-  // Shows the bookmark prompt.
-  void ShowBookmarkPrompt();
-
   // Returns the screen coordinates of the omnibox (where the URL text appears,
   // not where the icons are shown).
   gfx::Point GetOmniboxViewOrigin() const;
diff --git a/chrome/browser/ui/views/location_bar/origin_chip_view.cc b/chrome/browser/ui/views/location_bar/origin_chip_view.cc
index dd6c82f..8ab5a12 100644
--- a/chrome/browser/ui/views/location_bar/origin_chip_view.cc
+++ b/chrome/browser/ui/views/location_bar/origin_chip_view.cc
@@ -217,7 +217,7 @@
         host);
   }
   host_label_->SetText(host);
-  host_label_->SetTooltipText(host);
+  host_label_->SetTooltipText(base::UTF8ToUTF16(url.spec()));
   host_label_->SetElideBehavior(views::Label::NO_ELIDE);
 
   int icon = location_bar_view_->GetToolbarModel()->GetIconForSecurityLevel(
diff --git a/chrome/browser/ui/views/location_bar/page_info_helper.cc b/chrome/browser/ui/views/location_bar/page_info_helper.cc
index e92f809..c99c88d 100644
--- a/chrome/browser/ui/views/location_bar/page_info_helper.cc
+++ b/chrome/browser/ui/views/location_bar/page_info_helper.cc
@@ -29,10 +29,13 @@
   WebContents* tab = location_bar_->GetWebContents();
   if (!tab)
     return;
-  const NavigationController& controller = tab->GetController();
+
   // Important to use GetVisibleEntry to match what's showing in the omnibox.
-  NavigationEntry* nav_entry = controller.GetVisibleEntry();
-  DCHECK(nav_entry);
+  NavigationEntry* nav_entry = tab->GetController().GetVisibleEntry();
+  // The visible entry can be NULL in the case of window.open("").
+  if (!nav_entry)
+    return;
+
   location_bar_->delegate()->ShowWebsiteSettings(
       tab, nav_entry->GetURL(), nav_entry->GetSSL());
 }
diff --git a/chrome/browser/ui/views/location_bar/star_view.cc b/chrome/browser/ui/views/location_bar/star_view.cc
index 147cce8..ef0f870 100644
--- a/chrome/browser/ui/views/location_bar/star_view.cc
+++ b/chrome/browser/ui/views/location_bar/star_view.cc
@@ -16,7 +16,7 @@
 #include "ui/base/resource/resource_bundle.h"
 
 StarView::StarView(CommandUpdater* command_updater)
-    : BubbleIconView(command_updater, IDC_BOOKMARK_PAGE_FROM_STAR) {
+    : BubbleIconView(command_updater, IDC_BOOKMARK_PAGE) {
   set_id(VIEW_ID_STAR_BUTTON);
   SetToggled(false);
 }
diff --git a/chrome/browser/ui/views/location_bar/star_view_browsertest.cc b/chrome/browser/ui/views/location_bar/star_view_browsertest.cc
index c39b2d5..87a14eb 100644
--- a/chrome/browser/ui/views/location_bar/star_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/star_view_browsertest.cc
@@ -20,7 +20,6 @@
 #include "ui/base/ui_base_switches.h"
 
 #if defined(OS_WIN)
-#include "content/public/browser/web_contents_view.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #endif
@@ -113,8 +112,7 @@
   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
 
   // Now get the region of the plugin before the star view is shown.
-  HWND hwnd = tab->GetView()->GetNativeView()->GetHost()->
-      GetAcceleratedWidget();
+  HWND hwnd = tab->GetNativeView()->GetHost()->GetAcceleratedWidget();
   HWND child = NULL;
   EnumChildWindows(hwnd, EnumerateChildren,reinterpret_cast<LPARAM>(&child));
 
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
index 3ebdb82..80367b8 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -15,7 +15,6 @@
 #include "chrome/browser/ui/views/location_bar/zoom_view.h"
 #include "chrome/browser/ui/zoom/zoom_controller.h"
 #include "content/public/browser/notification_source.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -73,8 +72,7 @@
 
     // If we do not have an anchor view, parent the bubble to the content area.
     if (!anchor_to_view) {
-      zoom_bubble_->set_parent_window(
-          web_contents->GetView()->GetTopLevelNativeWindow());
+      zoom_bubble_->set_parent_window(web_contents->GetTopLevelNativeWindow());
     }
 
     views::BubbleDelegateView::CreateBubble(zoom_bubble_);
diff --git a/chrome/browser/ui/views/message_center/message_center_widget_delegate.cc b/chrome/browser/ui/views/message_center/message_center_widget_delegate.cc
index 1315661..e3ebc61 100644
--- a/chrome/browser/ui/views/message_center/message_center_widget_delegate.cc
+++ b/chrome/browser/ui/views/message_center/message_center_widget_delegate.cc
@@ -91,9 +91,15 @@
 void MessageCenterWidgetDelegate::OnWidgetActivationChanged(
     views::Widget* widget,
     bool active) {
+  // Some Linux users set 'focus-follows-mouse' where the activation is lost
+  // immediately after the mouse exists from the bubble, which is a really bad
+  // experience. Disable hiding until the bug around the focus is fixed.
+  // TODO(erg, pkotwicz): fix the activation issue and then remove this ifdef.
+#if !defined(OS_LINUX)
   if (!active) {
     tray_->SendHideMessageCenter();
   }
+#endif
 }
 
 void MessageCenterWidgetDelegate::OnWidgetClosing(views::Widget* widget) {
diff --git a/chrome/browser/ui/views/panels/panel_view.cc b/chrome/browser/ui/views/panels/panel_view.cc
index 017cfbe..4224926 100644
--- a/chrome/browser/ui/views/panels/panel_view.cc
+++ b/chrome/browser/ui/views/panels/panel_view.cc
@@ -20,7 +20,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/path.h"
 #include "ui/gfx/screen.h"
@@ -997,7 +996,7 @@
   if (focused_) {
     content::WebContents* web_contents = panel_->GetWebContents();
     if (web_contents)
-      web_contents->GetView()->RestoreFocus();
+      web_contents->RestoreFocus();
   }
 }
 
diff --git a/chrome/browser/ui/views/passwords/manage_password_item_view.cc b/chrome/browser/ui/views/passwords/manage_password_item_view.cc
index 8f0773e..c0dc2e4 100644
--- a/chrome/browser/ui/views/passwords/manage_password_item_view.cc
+++ b/chrome/browser/ui/views/passwords/manage_password_item_view.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/views/passwords/manage_password_item_view.h"
 
 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
+#include "components/password_manager/core/common/password_manager_ui.h"
 #include "grit/generated_resources.h"
 #include "grit/ui_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -15,21 +16,109 @@
 #include "ui/views/layout/grid_layout.h"
 #include "ui/views/layout/layout_constants.h"
 
+namespace {
+
+enum FieldType { USERNAME_FIELD, PASSWORD_FIELD };
+
+// Upper limit on the size of the username and password fields.
+const int kUsernameFieldSize = 30;
+const int kPasswordFieldSize = 22;
+
+// Returns the width of |type| field.
+int GetFieldWidth(FieldType type) {
+  return ui::ResourceBundle::GetSharedInstance()
+      .GetFontList(ui::ResourceBundle::SmallFont)
+      .GetExpectedTextWidth(type == USERNAME_FIELD ? kUsernameFieldSize
+                                                   : kPasswordFieldSize);
+}
+
+int FirstFieldWidth() {
+  return std::max(
+      GetFieldWidth(USERNAME_FIELD),
+      views::Label(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_DELETED))
+          .GetPreferredSize()
+          .width());
+}
+
+int SecondFieldWidth() {
+  return std::max(
+      GetFieldWidth(PASSWORD_FIELD),
+      views::Label(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_UNDO))
+          .GetPreferredSize()
+          .width());
+}
+
+enum ColumnSets { TWO_COLUMN_SET = 0, THREE_COLUMN_SET };
+
+void BuildColumnSet(views::GridLayout* layout, int column_set_id) {
+  views::ColumnSet* column_set = layout->AddColumnSet(column_set_id);
+
+  // The username/"Deleted!" field.
+  column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
+  column_set->AddColumn(views::GridLayout::FILL,
+                        views::GridLayout::FILL,
+                        0,
+                        views::GridLayout::FIXED,
+                        FirstFieldWidth(),
+                        FirstFieldWidth());
+
+  // The password/"Undo!" field.
+  column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
+  column_set->AddColumn(views::GridLayout::FILL,
+                        views::GridLayout::FILL,
+                        1,
+                        views::GridLayout::USE_PREF,
+                        SecondFieldWidth(),
+                        SecondFieldWidth());
+
+  // If we're in manage-mode, we need another column for the delete button.
+  if (column_set_id == THREE_COLUMN_SET) {
+    column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
+    column_set->AddColumn(views::GridLayout::TRAILING,
+                          views::GridLayout::FILL,
+                          0,
+                          views::GridLayout::USE_PREF,
+                          0,
+                          0);
+  }
+  column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
+}
+
+views::Label* GenerateUsernameLabel(const autofill::PasswordForm& form) {
+  views::Label* label = new views::Label(form.username_value);
+  label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+      ui::ResourceBundle::SmallFont));
+  label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  return label;
+}
+
+views::Label* GeneratePasswordLabel(const autofill::PasswordForm& form) {
+  views::Label* label = new views::Label(form.password_value);
+  label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+      ui::ResourceBundle::SmallFont));
+  label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  label->SetObscured(true);
+  return label;
+}
+
+}  // namespace
+
 // Pending View
 ManagePasswordItemView::PendingView::PendingView(
     ManagePasswordItemView* parent) {
   views::GridLayout* layout = new views::GridLayout(this);
   SetLayoutManager(layout);
 
-  parent->BuildColumnSet(layout, TWO_COLUMN_SET);
+  BuildColumnSet(layout, TWO_COLUMN_SET);
   layout->StartRowWithPadding(
       0, TWO_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
-  layout->AddView(parent->GenerateUsernameLabel());
-  layout->AddView(parent->GeneratePasswordLabel());
+  layout->AddView(GenerateUsernameLabel(parent->password_form_));
+  layout->AddView(GeneratePasswordLabel(parent->password_form_));
   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
 }
 
-ManagePasswordItemView::PendingView::~PendingView() {}
+ManagePasswordItemView::PendingView::~PendingView() {
+}
 
 // Manage View
 ManagePasswordItemView::ManageView::ManageView(ManagePasswordItemView* parent)
@@ -46,11 +135,11 @@
   delete_button_->SetImage(views::ImageButton::STATE_PRESSED,
                            rb->GetImageNamed(IDR_CLOSE_2_P).ToImageSkia());
 
-  parent->BuildColumnSet(layout, THREE_COLUMN_SET);
+  BuildColumnSet(layout, THREE_COLUMN_SET);
   layout->StartRowWithPadding(
       0, THREE_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
-  layout->AddView(parent->GenerateUsernameLabel());
-  layout->AddView(parent->GeneratePasswordLabel());
+  layout->AddView(GenerateUsernameLabel(parent->password_form_));
+  layout->AddView(GeneratePasswordLabel(parent->password_form_));
   layout->AddView(delete_button_);
   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
 }
@@ -61,7 +150,8 @@
   parent_->NotifyClickedDelete();
 }
 
-ManagePasswordItemView::ManageView::~ManageView() {}
+ManagePasswordItemView::ManageView::~ManageView() {
+}
 
 // Undo View
 ManagePasswordItemView::UndoView::UndoView(ManagePasswordItemView* parent)
@@ -72,14 +162,18 @@
   views::Label* text =
       new views::Label(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_DELETED));
   text->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  text->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+      ui::ResourceBundle::SmallFont));
 
   undo_link_ =
       new views::Link(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_UNDO));
   undo_link_->SetHorizontalAlignment(gfx::ALIGN_RIGHT);
   undo_link_->set_listener(this);
   undo_link_->SetUnderline(false);
+  undo_link_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+      ui::ResourceBundle::SmallFont));
 
-  parent->BuildColumnSet(layout, TWO_COLUMN_SET);
+  BuildColumnSet(layout, TWO_COLUMN_SET);
   layout->StartRowWithPadding(
       0, TWO_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
   layout->AddView(text);
@@ -93,20 +187,17 @@
   parent_->NotifyClickedUndo();
 }
 
-ManagePasswordItemView::UndoView::~UndoView() {}
+ManagePasswordItemView::UndoView::~UndoView() {
+}
 
 // ManagePasswordItemView
 ManagePasswordItemView::ManagePasswordItemView(
     ManagePasswordsBubbleModel* manage_passwords_bubble_model,
     autofill::PasswordForm password_form,
-    int field_1_width,
-    int field_2_width,
     Position position)
-    : manage_passwords_bubble_model_(manage_passwords_bubble_model),
+    : model_(manage_passwords_bubble_model),
       password_form_(password_form),
-      delete_password_(false),
-      field_1_width_(field_1_width),
-      field_2_width_(field_2_width) {
+      delete_password_(false) {
   views::FillLayout* layout = new views::FillLayout();
   SetLayoutManager(layout);
 
@@ -121,69 +212,19 @@
       GetNativeTheme()->GetSystemColor(
           ui::NativeTheme::kColorId_EnabledMenuButtonBorderColor)));
 
-  if (manage_passwords_bubble_model_->WaitingToSavePassword())
+  if (password_manager::ui::IsPendingState(model_->state())) {
     AddChildView(new PendingView(this));
-  else
+  } else {
     AddChildView(new ManageView(this));
+  }
   GetLayoutManager()->Layout(this);
 }
 
-ManagePasswordItemView::~ManagePasswordItemView() {}
-
-void ManagePasswordItemView::BuildColumnSet(views::GridLayout* layout,
-                                            int column_set_id) {
-  views::ColumnSet* column_set = layout->AddColumnSet(column_set_id);
-
-  // The username/"Deleted!" field.
-  column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
-  column_set->AddColumn(views::GridLayout::FILL,
-                        views::GridLayout::FILL,
-                        0,
-                        views::GridLayout::FIXED,
-                        field_1_width_,
-                        field_1_width_);
-
-  // The password/"Undo!" field.
-  column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
-  column_set->AddColumn(views::GridLayout::FILL,
-                        views::GridLayout::FILL,
-                        1,
-                        views::GridLayout::USE_PREF,
-                        field_2_width_,
-                        field_2_width_);
-
-  // If we're in manage-mode, we need another column for the delete button.
-  if (column_set_id == THREE_COLUMN_SET) {
-    column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
-    column_set->AddColumn(views::GridLayout::TRAILING,
-                          views::GridLayout::FILL,
-                          0,
-                          views::GridLayout::USE_PREF,
-                          0,
-                          0);
-  }
-  column_set->AddPaddingColumn(0, views::kItemLabelSpacing);
-}
-
-views::Label* ManagePasswordItemView::GenerateUsernameLabel() const {
-  views::Label* label = new views::Label(password_form_.username_value);
-  label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
-      ui::ResourceBundle::SmallFont));
-  label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  return label;
-}
-
-views::Label* ManagePasswordItemView::GeneratePasswordLabel() const {
-  views::Label* label = new views::Label(password_form_.password_value);
-  label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
-      ui::ResourceBundle::SmallFont));
-  label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  label->SetObscured(true);
-  return label;
+ManagePasswordItemView::~ManagePasswordItemView() {
 }
 
 void ManagePasswordItemView::Refresh() {
-  DCHECK(!manage_passwords_bubble_model_->WaitingToSavePassword());
+  DCHECK(!password_manager::ui::IsPendingState(model_->state()));
 
   RemoveAllChildViews(true);
   if (delete_password_)
@@ -194,10 +235,10 @@
 
   // After the view is consistent, notify the model that the password needs to
   // be updated (either removed or put back into the store, as appropriate.
-  manage_passwords_bubble_model_->OnPasswordAction(
-      password_form_,
-      delete_password_ ? ManagePasswordsBubbleModel::REMOVE_PASSWORD
-                       : ManagePasswordsBubbleModel::ADD_PASSWORD);
+  model_->OnPasswordAction(password_form_,
+                           delete_password_
+                               ? ManagePasswordsBubbleModel::REMOVE_PASSWORD
+                               : ManagePasswordsBubbleModel::ADD_PASSWORD);
 }
 
 void ManagePasswordItemView::NotifyClickedDelete() {
diff --git a/chrome/browser/ui/views/passwords/manage_password_item_view.h b/chrome/browser/ui/views/passwords/manage_password_item_view.h
index 793f915..f052d12 100644
--- a/chrome/browser/ui/views/passwords/manage_password_item_view.h
+++ b/chrome/browser/ui/views/passwords/manage_password_item_view.h
@@ -48,7 +48,6 @@
                                const ui::Event& event) OVERRIDE;
 
     views::ImageButton* delete_button_;
-
     ManagePasswordItemView* parent_;
   };
 
@@ -65,7 +64,6 @@
     virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
 
     views::Link* undo_link_;
-
     ManagePasswordItemView* parent_;
   };
 
@@ -74,33 +72,20 @@
   ManagePasswordItemView(
       ManagePasswordsBubbleModel* manage_passwords_bubble_model,
       autofill::PasswordForm password_form,
-      int field_1_width,
-      int field_2_width,
       Position position);
 
  private:
-  enum ColumnSets { TWO_COLUMN_SET = 0, THREE_COLUMN_SET };
-
   virtual ~ManagePasswordItemView();
 
-  views::Label* GenerateUsernameLabel() const;
-  views::Label* GeneratePasswordLabel() const;
-
-  // Build a two-label column set using the widths stored in |field_1_width_|
-  // and |field_2_width_|.
-  void BuildColumnSet(views::GridLayout*, int column_set_id);
-
   void NotifyClickedDelete();
   void NotifyClickedUndo();
 
   // Changes the views according to the state of |delete_password_|.
   void Refresh();
 
-  ManagePasswordsBubbleModel* manage_passwords_bubble_model_;
+  ManagePasswordsBubbleModel* model_;
   autofill::PasswordForm password_form_;
   bool delete_password_;
-  int field_1_width_;
-  int field_2_width_;
 
   DISALLOW_COPY_AND_ASSIGN(ManagePasswordItemView);
 };
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
index 0c3f0e0..2a94144 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
@@ -4,18 +4,18 @@
 
 #include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h"
 
-#include "base/metrics/histogram.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/views/passwords/manage_password_item_view.h"
 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h"
+#include "components/password_manager/core/common/password_manager_ui.h"
 #include "content/public/browser/notification_source.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/combobox_model.h"
@@ -24,6 +24,7 @@
 #include "ui/views/controls/button/blue_button.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/combobox/combobox.h"
+#include "ui/views/layout/fill_layout.h"
 #include "ui/views/layout/grid_layout.h"
 #include "ui/views/layout/layout_constants.h"
 
@@ -32,119 +33,28 @@
 
 namespace {
 
-enum FieldType { USERNAME_FIELD, PASSWORD_FIELD };
+const int kDesiredBubbleWidth = 370;
 
-// Upper limit on the size of the username and password fields.
-const int kUsernameFieldSize = 30;
-const int kPasswordFieldSize = 22;
+enum ColumnSetType {
+  // | | (FILL, FILL) | |
+  // Used for the bubble's header, the credentials list, and for simple
+  // messages like "No passwords".
+  SINGLE_VIEW_COLUMN_SET = 0,
 
-// Returns the width of |type| field.
-int GetFieldWidth(FieldType type) {
-  return ui::ResourceBundle::GetSharedInstance()
-      .GetFontList(ui::ResourceBundle::SmallFont)
-      .GetExpectedTextWidth(type == USERNAME_FIELD ? kUsernameFieldSize
-                                                   : kPasswordFieldSize);
-}
+  // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | |
+  // Used for buttons at the bottom of the bubble which should nest at the
+  // bottom-right corner.
+  DOUBLE_BUTTON_COLUMN_SET = 1,
 
-class SavePasswordRefusalComboboxModel : public ui::ComboboxModel {
- public:
-  enum { INDEX_NOPE = 0, INDEX_NEVER_FOR_THIS_SITE = 1, };
-
-  SavePasswordRefusalComboboxModel() {
-    items_.push_back(
-        l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_CANCEL_BUTTON));
-    items_.push_back(
-        l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON));
-  }
-  virtual ~SavePasswordRefusalComboboxModel() {}
-
- private:
-  // Overridden from ui::ComboboxModel:
-  virtual int GetItemCount() const OVERRIDE { return items_.size(); }
-  virtual base::string16 GetItemAt(int index) OVERRIDE { return items_[index]; }
-  virtual bool IsItemSeparatorAt(int index) OVERRIDE {
-    return items_[index].empty();
-  }
-  virtual int GetDefaultIndex() const OVERRIDE { return 0; }
-
-  std::vector<base::string16> items_;
-
-  DISALLOW_COPY_AND_ASSIGN(SavePasswordRefusalComboboxModel);
+  // | | (LEADING, CENTER) | | (TRAILING, CENTER) | |
+  // Used for buttons at the bottom of the bubble which should occupy
+  // the corners.
+  LINK_BUTTON_COLUMN_SET = 2,
 };
 
-}  // namespace
-
-
-// ManagePasswordsBubbleView --------------------------------------------------
-
-// static
-ManagePasswordsBubbleView* ManagePasswordsBubbleView::manage_passwords_bubble_ =
-    NULL;
-
-// static
-void ManagePasswordsBubbleView::ShowBubble(content::WebContents* web_contents,
-                                           DisplayReason reason) {
-  Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
-  DCHECK(browser);
-  DCHECK(browser->window());
-  DCHECK(browser->fullscreen_controller());
-
-  if (IsShowing())
-    return;
-
-  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
-  bool is_fullscreen = browser_view->IsFullscreen();
-  views::View* anchor_view = is_fullscreen ?
-      NULL : browser_view->GetLocationBarView()->manage_passwords_icon_view();
-  manage_passwords_bubble_ = new ManagePasswordsBubbleView(
-      web_contents, anchor_view, reason);
-
-  if (is_fullscreen) {
-    manage_passwords_bubble_->set_parent_window(
-        web_contents->GetView()->GetTopLevelNativeWindow());
-  }
-
-  views::BubbleDelegateView::CreateBubble(manage_passwords_bubble_);
-
-  // Adjust for fullscreen after creation as it relies on the content size.
-  if (is_fullscreen) {
-    manage_passwords_bubble_->AdjustForFullscreen(
-        browser_view->GetBoundsInScreen());
-  }
-
-  manage_passwords_bubble_->GetWidget()->Show();
-}
-
-// static
-void ManagePasswordsBubbleView::CloseBubble() {
-  if (manage_passwords_bubble_)
-    manage_passwords_bubble_->CloseWithoutLogging();
-}
-
-// static
-bool ManagePasswordsBubbleView::IsShowing() {
-  // The bubble may be in the process of closing.
-  return (manage_passwords_bubble_ != NULL) &&
-      manage_passwords_bubble_->GetWidget()->IsVisible();
-}
-
-ManagePasswordsBubbleView::ManagePasswordsBubbleView(
-    content::WebContents* web_contents,
-    views::View* anchor_view,
-    DisplayReason reason)
-    : ManagePasswordsBubble(web_contents, reason),
-      BubbleDelegateView(anchor_view,
-                         anchor_view ? views::BubbleBorder::TOP_RIGHT
-                                     : views::BubbleBorder::NONE) {
-  // Compensate for built-in vertical padding in the anchor view's image.
-  set_anchor_view_insets(gfx::Insets(5, 0, 5, 0));
-  set_notify_enter_exit_on_child(true);
-}
-
-ManagePasswordsBubbleView::~ManagePasswordsBubbleView() {}
-
-void ManagePasswordsBubbleView::BuildColumnSet(views::GridLayout* layout,
-                                               ColumnSetType type) {
+// Construct an appropriate ColumnSet for the given |type|, and add it
+// to |layout|.
+void BuildColumnSet(views::GridLayout* layout, ColumnSetType type) {
   views::ColumnSet* column_set = layout->AddColumnSet(type);
   column_set->AddPaddingColumn(0, views::kPanelHorizMargin);
   switch (type) {
@@ -191,6 +101,327 @@
   column_set->AddPaddingColumn(0, views::kPanelHorizMargin);
 }
 
+// Given a layout and a model, add an appropriate title using a
+// SINGLE_VIEW_COLUMN_SET, followed by a spacer row.
+void AddTitleRow(views::GridLayout* layout, ManagePasswordsBubbleModel* model) {
+  views::Label* title_label = new views::Label(model->title());
+  title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  title_label->SetMultiLine(true);
+  title_label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+      ui::ResourceBundle::MediumFont));
+
+  // Add the title to the layout with appropriate padding.
+  layout->StartRowWithPadding(
+      0, SINGLE_VIEW_COLUMN_SET, 0, views::kRelatedControlSmallVerticalSpacing);
+  layout->AddView(title_label);
+  layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
+}
+
+}  // namespace
+
+
+// Globals --------------------------------------------------------------------
+
+namespace chrome {
+
+void ShowManagePasswordsBubble(content::WebContents* web_contents) {
+  ManagePasswordsUIController* controller =
+      ManagePasswordsUIController::FromWebContents(web_contents);
+  ManagePasswordsBubbleView::ShowBubble(
+      web_contents,
+      controller->state() ==
+              password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE
+          ? ManagePasswordsBubbleView::AUTOMATIC
+          : ManagePasswordsBubbleView::USER_ACTION);
+}
+
+}  // namespace chrome
+
+
+// ManagePasswordsBubbleView::PendingView -------------------------------------
+
+ManagePasswordsBubbleView::PendingView::PendingView(
+    ManagePasswordsBubbleView* parent)
+    : parent_(parent) {
+  views::GridLayout* layout = new views::GridLayout(this);
+  layout->set_minimum_size(gfx::Size(kDesiredBubbleWidth, 0));
+  SetLayoutManager(layout);
+
+  // Create the pending credential item, save button and refusal combobox.
+  ManagePasswordItemView* item =
+      new ManagePasswordItemView(parent->model(),
+                                 parent->model()->pending_credentials(),
+                                 ManagePasswordItemView::FIRST_ITEM);
+  save_button_ = new views::BlueButton(
+      this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON));
+  save_button_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+      ui::ResourceBundle::SmallFont));
+
+  combobox_model_.reset(new SavePasswordRefusalComboboxModel());
+  refuse_combobox_.reset(new views::Combobox(combobox_model_.get()));
+  refuse_combobox_->set_listener(this);
+  refuse_combobox_->SetStyle(views::Combobox::STYLE_ACTION);
+  // TODO(mkwst): Need a mechanism to pipe a font list down into a combobox.
+
+  // Title row.
+  BuildColumnSet(layout, SINGLE_VIEW_COLUMN_SET);
+  AddTitleRow(layout, parent_->model());
+
+  // Credential row.
+  layout->StartRow(0, SINGLE_VIEW_COLUMN_SET);
+  layout->AddView(item);
+
+  // Button row.
+  BuildColumnSet(layout, DOUBLE_BUTTON_COLUMN_SET);
+  layout->StartRowWithPadding(
+      0, DOUBLE_BUTTON_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
+  layout->AddView(save_button_);
+  layout->AddView(refuse_combobox_.get());
+
+  // Extra padding for visual awesomeness.
+  layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+}
+
+ManagePasswordsBubbleView::PendingView::~PendingView() {
+}
+
+void ManagePasswordsBubbleView::PendingView::ButtonPressed(
+    views::Button* sender,
+    const ui::Event& event) {
+  DCHECK(sender == save_button_);
+  parent_->model()->OnSaveClicked();
+  parent_->Close();
+}
+
+void ManagePasswordsBubbleView::PendingView::OnPerformAction(
+    views::Combobox* source) {
+  DCHECK_EQ(source, refuse_combobox_);
+  switch (refuse_combobox_->selected_index()) {
+    case SavePasswordRefusalComboboxModel::INDEX_NOPE:
+      parent_->model()->OnNopeClicked();
+      break;
+    case SavePasswordRefusalComboboxModel::INDEX_NEVER_FOR_THIS_SITE:
+      parent_->model()->OnNeverForThisSiteClicked();
+      break;
+  }
+  parent_->Close();
+}
+
+// ManagePasswordsBubbleView::ManageView --------------------------------------
+
+ManagePasswordsBubbleView::ManageView::ManageView(
+    ManagePasswordsBubbleView* parent)
+    : parent_(parent) {
+  views::GridLayout* layout = new views::GridLayout(this);
+  layout->set_minimum_size(gfx::Size(kDesiredBubbleWidth, 0));
+  SetLayoutManager(layout);
+
+  // Add the title.
+  BuildColumnSet(layout, SINGLE_VIEW_COLUMN_SET);
+  AddTitleRow(layout, parent_->model());
+
+  // If we have a list of passwords to store for the current site, display
+  // them to the user for management. Otherwise, render a "No passwords for
+  // this site" message.
+  if (!parent_->model()->best_matches().empty()) {
+    for (autofill::PasswordFormMap::const_iterator i(
+             parent_->model()->best_matches().begin());
+         i != parent_->model()->best_matches().end();
+         ++i) {
+      ManagePasswordItemView* item = new ManagePasswordItemView(
+          parent_->model(),
+          *i->second,
+          i == parent_->model()->best_matches().begin()
+              ? ManagePasswordItemView::FIRST_ITEM
+              : ManagePasswordItemView::SUBSEQUENT_ITEM);
+
+      layout->StartRow(0, SINGLE_VIEW_COLUMN_SET);
+      layout->AddView(item);
+    }
+  } else {
+    views::Label* empty_label = new views::Label(
+        l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_NO_PASSWORDS));
+    empty_label->SetMultiLine(true);
+    empty_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+    empty_label->SetFontList(
+        ui::ResourceBundle::GetSharedInstance().GetFontList(
+            ui::ResourceBundle::SmallFont));
+
+    layout->StartRow(0, SINGLE_VIEW_COLUMN_SET);
+    layout->AddView(empty_label);
+    layout->AddPaddingRow(0, views::kRelatedControlSmallVerticalSpacing);
+  }
+
+  // Then add the "manage passwords" link and "Done" button.
+  manage_link_ = new views::Link(parent_->model()->manage_link());
+  manage_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  manage_link_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+      ui::ResourceBundle::SmallFont));
+  manage_link_->SetUnderline(false);
+  manage_link_->set_listener(this);
+
+  done_button_ =
+      new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_DONE));
+  done_button_->SetStyle(views::Button::STYLE_BUTTON);
+  done_button_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+      ui::ResourceBundle::SmallFont));
+
+  BuildColumnSet(layout, LINK_BUTTON_COLUMN_SET);
+  layout->StartRowWithPadding(
+      0, LINK_BUTTON_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
+  layout->AddView(manage_link_);
+  layout->AddView(done_button_);
+
+  // Extra padding for visual awesomeness.
+  layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+}
+
+ManagePasswordsBubbleView::ManageView::~ManageView() {
+}
+
+void ManagePasswordsBubbleView::ManageView::ButtonPressed(
+    views::Button* sender,
+    const ui::Event& event) {
+  DCHECK(sender == done_button_);
+  parent_->model()->OnDoneClicked();
+  parent_->Close();
+}
+
+void ManagePasswordsBubbleView::ManageView::LinkClicked(views::Link* source,
+                                                        int event_flags) {
+  DCHECK_EQ(source, manage_link_);
+  parent_->model()->OnManageLinkClicked();
+  parent_->Close();
+}
+
+// ManagePasswordsBubbleView::BlacklistedView ---------------------------------
+
+ManagePasswordsBubbleView::BlacklistedView::BlacklistedView(
+    ManagePasswordsBubbleView* parent)
+    : parent_(parent) {
+  views::GridLayout* layout = new views::GridLayout(this);
+  layout->set_minimum_size(gfx::Size(kDesiredBubbleWidth, 0));
+  SetLayoutManager(layout);
+
+  // Add the title.
+  BuildColumnSet(layout, SINGLE_VIEW_COLUMN_SET);
+  AddTitleRow(layout, parent_->model());
+
+  // Add the "Hey! You blacklisted this site!" text.
+  views::Label* blacklisted = new views::Label(
+      l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_BLACKLISTED));
+  blacklisted->SetMultiLine(true);
+  blacklisted->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+      ui::ResourceBundle::SmallFont));
+  layout->StartRow(0, SINGLE_VIEW_COLUMN_SET);
+  layout->AddView(blacklisted);
+  layout->AddPaddingRow(0, views::kRelatedControlSmallVerticalSpacing);
+
+  // Then add the "enable password manager" and "Done" buttons.
+  unblacklist_button_ = new views::BlueButton(
+      this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_UNBLACKLIST_BUTTON));
+  unblacklist_button_->SetFontList(
+      ui::ResourceBundle::GetSharedInstance().GetFontList(
+          ui::ResourceBundle::SmallFont));
+  done_button_ =
+      new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_DONE));
+  done_button_->SetStyle(views::Button::STYLE_BUTTON);
+  done_button_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+      ui::ResourceBundle::SmallFont));
+
+  BuildColumnSet(layout, DOUBLE_BUTTON_COLUMN_SET);
+  layout->StartRowWithPadding(
+      0, DOUBLE_BUTTON_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
+  layout->AddView(unblacklist_button_);
+  layout->AddView(done_button_);
+
+  // Extra padding for visual awesomeness.
+  layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+}
+
+ManagePasswordsBubbleView::BlacklistedView::~BlacklistedView() {
+}
+
+void ManagePasswordsBubbleView::BlacklistedView::ButtonPressed(
+    views::Button* sender,
+    const ui::Event& event) {
+  if (sender == done_button_)
+    parent_->model()->OnDoneClicked();
+  else if (sender == unblacklist_button_)
+    parent_->model()->OnUnblacklistClicked();
+  else
+    NOTREACHED();
+  parent_->Close();
+}
+
+// ManagePasswordsBubbleView --------------------------------------------------
+
+// static
+ManagePasswordsBubbleView* ManagePasswordsBubbleView::manage_passwords_bubble_ =
+    NULL;
+
+// static
+void ManagePasswordsBubbleView::ShowBubble(content::WebContents* web_contents,
+                                           DisplayReason reason) {
+  Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
+  DCHECK(browser);
+  DCHECK(browser->window());
+  DCHECK(browser->fullscreen_controller());
+
+  if (IsShowing())
+    return;
+
+  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
+  bool is_fullscreen = browser_view->IsFullscreen();
+  views::View* anchor_view = is_fullscreen ?
+      NULL : browser_view->GetLocationBarView()->manage_passwords_icon_view();
+  manage_passwords_bubble_ = new ManagePasswordsBubbleView(
+      web_contents, anchor_view, reason);
+
+  if (is_fullscreen) {
+    manage_passwords_bubble_->set_parent_window(
+        web_contents->GetTopLevelNativeWindow());
+  }
+
+  views::BubbleDelegateView::CreateBubble(manage_passwords_bubble_);
+
+  // Adjust for fullscreen after creation as it relies on the content size.
+  if (is_fullscreen) {
+    manage_passwords_bubble_->AdjustForFullscreen(
+        browser_view->GetBoundsInScreen());
+  }
+
+  manage_passwords_bubble_->GetWidget()->Show();
+}
+
+// static
+void ManagePasswordsBubbleView::CloseBubble() {
+  if (manage_passwords_bubble_)
+    manage_passwords_bubble_->Close();
+}
+
+// static
+bool ManagePasswordsBubbleView::IsShowing() {
+  // The bubble may be in the process of closing.
+  return (manage_passwords_bubble_ != NULL) &&
+      manage_passwords_bubble_->GetWidget()->IsVisible();
+}
+
+ManagePasswordsBubbleView::ManagePasswordsBubbleView(
+    content::WebContents* web_contents,
+    views::View* anchor_view,
+    DisplayReason reason)
+    : ManagePasswordsBubble(web_contents, reason),
+      BubbleDelegateView(anchor_view,
+                         anchor_view ? views::BubbleBorder::TOP_RIGHT
+                                     : views::BubbleBorder::NONE) {
+  // Compensate for built-in vertical padding in the anchor view's image.
+  set_anchor_view_insets(gfx::Insets(5, 0, 5, 0));
+  set_notify_enter_exit_on_child(true);
+}
+
+ManagePasswordsBubbleView::~ManagePasswordsBubbleView() {}
+
 void ManagePasswordsBubbleView::AdjustForFullscreen(
     const gfx::Rect& screen_bounds) {
   if (GetAnchorView())
@@ -209,124 +440,17 @@
   GetWidget()->Close();
 }
 
-void ManagePasswordsBubbleView::CloseWithoutLogging() {
-  model()->OnCloseWithoutLogging();
-  GetWidget()->Close();
-}
-
 void ManagePasswordsBubbleView::Init() {
-  using views::GridLayout;
-
-  GridLayout* layout = new GridLayout(this);
-  SetFocusable(true);
+  views::FillLayout* layout = new views::FillLayout();
   SetLayoutManager(layout);
-  BuildColumnSet(layout, SINGLE_VIEW_COLUMN_SET);
-  BuildColumnSet(layout, DOUBLE_BUTTON_COLUMN_SET);
-  BuildColumnSet(layout, LINK_BUTTON_COLUMN_SET);
+  SetFocusable(true);
 
-  // This calculates the necessary widths for credential columns in the bubble.
-  const int first_field_width = std::max(
-      GetFieldWidth(USERNAME_FIELD),
-      views::Label(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_DELETED))
-          .GetPreferredSize()
-          .width());
-
-  const int second_field_width = std::max(
-      GetFieldWidth(PASSWORD_FIELD),
-      views::Label(l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_UNDO))
-          .GetPreferredSize()
-          .width());
-
-  // Build and populate the header.
-  views::Label* title_label = new views::Label(model()->title());
-  title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  title_label->SetMultiLine(true);
-  title_label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
-      ui::ResourceBundle::MediumFont));
-
-  layout->StartRowWithPadding(
-      0, SINGLE_VIEW_COLUMN_SET, 0, views::kRelatedControlSmallVerticalSpacing);
-  layout->AddView(title_label);
-  layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
-
-  if (model()->WaitingToSavePassword()) {
-    // If we've got a password that we're deciding whether or not to save,
-    // then we need to display a single-view columnset containing the
-    // ManagePasswordItemView, followed by double-view columnset containing
-    // a "Save" and "Reject" button.
-    ManagePasswordItemView* item =
-        new ManagePasswordItemView(model(),
-                                   model()->pending_credentials(),
-                                   first_field_width,
-                                   second_field_width,
-                                   ManagePasswordItemView::FIRST_ITEM);
-    layout->StartRow(0, SINGLE_VIEW_COLUMN_SET);
-    layout->AddView(item);
-
-    refuse_combobox_ =
-        new views::Combobox(new SavePasswordRefusalComboboxModel());
-    refuse_combobox_->set_listener(this);
-    refuse_combobox_->SetStyle(views::Combobox::STYLE_ACTION);
-
-    save_button_ = new views::BlueButton(
-        this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_SAVE_BUTTON));
-
-    layout->StartRowWithPadding(
-        0, DOUBLE_BUTTON_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
-    layout->AddView(save_button_);
-    layout->AddView(refuse_combobox_);
-    layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
-  } else {
-    // If we have a list of passwords to store for the current site, display
-    // them to the user for management. Otherwise, render a "No passwords for
-    // this site" message.
-    //
-    // TODO(mkwst): Do we really want the "No passwords" case? It would probably
-    // be better to only clear the pending password upon navigation, rather than
-    // as soon as the bubble closes.
-    if (!model()->best_matches().empty()) {
-      for (autofill::PasswordFormMap::const_iterator i(
-               model()->best_matches().begin());
-           i != model()->best_matches().end();
-           ++i) {
-        ManagePasswordItemView* item = new ManagePasswordItemView(
-            model(),
-            *i->second,
-            first_field_width,
-            second_field_width,
-            i == model()->best_matches().begin()
-                ? ManagePasswordItemView::FIRST_ITEM
-                : ManagePasswordItemView::SUBSEQUENT_ITEM);
-
-        layout->StartRow(0, SINGLE_VIEW_COLUMN_SET);
-        layout->AddView(item);
-      }
-    } else {
-        views::Label* empty_label = new views::Label(
-            l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_NO_PASSWORDS));
-        empty_label->SetMultiLine(true);
-
-        layout->StartRow(0, SINGLE_VIEW_COLUMN_SET);
-        layout->AddView(empty_label);
-    }
-
-    // Build a "manage" link and "done" button, and throw them both into a new
-    // row
-    // containing a double-view columnset.
-    manage_link_ = new views::Link(model()->manage_link());
-    manage_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-    manage_link_->SetUnderline(false);
-    manage_link_->set_listener(this);
-
-    done_button_ =
-        new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_DONE));
-    done_button_->SetStyle(views::Button::STYLE_BUTTON);
-
-    layout->StartRowWithPadding(
-        0, LINK_BUTTON_COLUMN_SET, 0, views::kRelatedControlVerticalSpacing);
-    layout->AddView(manage_link_);
-    layout->AddView(done_button_);
-  }
+  if (password_manager::ui::IsPendingState(model()->state()))
+    AddChildView(new PendingView(this));
+  else if (model()->state() == password_manager::ui::BLACKLIST_STATE)
+    AddChildView(new BlacklistedView(this));
+  else
+    AddChildView(new ManageView(this));
 }
 
 void ManagePasswordsBubbleView::WindowClosing() {
@@ -335,37 +459,3 @@
   if (manage_passwords_bubble_ == this)
     manage_passwords_bubble_ = NULL;
 }
-
-void ManagePasswordsBubbleView::ButtonPressed(views::Button* sender,
-                                              const ui::Event& event) {
-  DCHECK(sender == save_button_ || sender == done_button_);
-
-  if (sender == save_button_)
-    model()->OnSaveClicked();
-  else
-    model()->OnDoneClicked();
-  Close();
-}
-
-void ManagePasswordsBubbleView::LinkClicked(views::Link* source,
-                                            int event_flags) {
-  DCHECK_EQ(source, manage_link_);
-  model()->OnManageLinkClicked();
-  Close();
-}
-
-void ManagePasswordsBubbleView::OnPerformAction(views::Combobox* source) {
-  DCHECK_EQ(source, refuse_combobox_);
-  switch (refuse_combobox_->selected_index()) {
-    case SavePasswordRefusalComboboxModel::INDEX_NOPE:
-      model()->OnNopeClicked();
-      break;
-    case SavePasswordRefusalComboboxModel::INDEX_NEVER_FOR_THIS_SITE:
-      model()->OnNeverForThisSiteClicked();
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-  Close();
-}
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h
index 39e1e50..c79d92a 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h
@@ -7,6 +7,7 @@
 
 #include "base/basictypes.h"
 #include "chrome/browser/ui/passwords/manage_passwords_bubble.h"
+#include "chrome/browser/ui/views/passwords/save_password_refusal_combobox_model.h"
 #include "ui/views/bubble/bubble_delegate.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/combobox/combobox.h"
@@ -26,12 +27,89 @@
 class GridLayout;
 }
 
+// The ManagePasswordsBubbleView controls the contents of the bubble which
+// pops up when Chrome offers to save a user's password, or when the user
+// interacts with the Omnibox icon. It has two distinct states:
+//
+// 1. PendingView: Offers the user the possibility of saving credentials.
+// 2. ManageView: Displays the current page's saved credentials.
+// 3. BlacklistedView: Informs the user that the current page is blacklisted.
+//
 class ManagePasswordsBubbleView : public ManagePasswordsBubble,
-                                  public views::BubbleDelegateView,
-                                  public views::ButtonListener,
-                                  public views::ComboboxListener,
-                                  public views::LinkListener {
+                                  public views::BubbleDelegateView {
  public:
+  // A view offering the user the ability to save credentials. Contains a
+  // single ManagePasswordItemView, along with a "Save Passwords" button
+  // and a rejection combobox.
+  class PendingView : public views::View,
+                      public views::ButtonListener,
+                      public views::ComboboxListener {
+   public:
+    explicit PendingView(ManagePasswordsBubbleView* parent);
+    virtual ~PendingView();
+
+   private:
+    // views::ButtonListener:
+    virtual void ButtonPressed(views::Button* sender,
+                               const ui::Event& event) OVERRIDE;
+
+    // Handles the event when the user changes an index of a combobox.
+    virtual void OnPerformAction(views::Combobox* source) OVERRIDE;
+
+    ManagePasswordsBubbleView* parent_;
+
+    views::BlueButton* save_button_;
+
+    // The combobox doesn't take ownership of its model. If we created a
+    // combobox we need to ensure that we delete the model here, and because the
+    // combobox uses the model in it's destructor, we need to make sure we
+    // delete the model _after_ the combobox itself is deleted.
+    scoped_ptr<SavePasswordRefusalComboboxModel> combobox_model_;
+    scoped_ptr<views::Combobox> refuse_combobox_;
+  };
+
+  // A view offering the user a list of her currently saved credentials
+  // for the current page, along with a "Manage passwords" link and a
+  // "Done" button.
+  class ManageView : public views::View,
+                     public views::ButtonListener,
+                     public views::LinkListener {
+   public:
+    explicit ManageView(ManagePasswordsBubbleView* parent);
+    virtual ~ManageView();
+
+   private:
+    // views::ButtonListener:
+    virtual void ButtonPressed(views::Button* sender,
+                               const ui::Event& event) OVERRIDE;
+
+    // views::LinkListener:
+    virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
+
+    ManagePasswordsBubbleView* parent_;
+
+    views::Link* manage_link_;
+    views::LabelButton* done_button_;
+  };
+
+  // A view offering the user the ability to re-enable the password manager for
+  // a specific site after she's decided to "never save passwords".
+  class BlacklistedView : public views::View, public views::ButtonListener {
+   public:
+    explicit BlacklistedView(ManagePasswordsBubbleView* parent);
+    virtual ~BlacklistedView();
+
+   private:
+    // views::ButtonListener:
+    virtual void ButtonPressed(views::Button* sender,
+                               const ui::Event& event) OVERRIDE;
+
+    ManagePasswordsBubbleView* parent_;
+
+    views::BlueButton* unblacklist_button_;
+    views::LabelButton* done_button_;
+  };
+
   // Shows the bubble.
   static void ShowBubble(content::WebContents* web_contents,
                          DisplayReason reason);
@@ -43,32 +121,11 @@
   static bool IsShowing();
 
  private:
-  enum ColumnSetType {
-    // | | (FILL, FILL) | |
-    // Used for the bubble's header, the credentials list, and for simple
-    // messages like "No passwords".
-    SINGLE_VIEW_COLUMN_SET = 0,
-
-    // | | (TRAILING, CENTER) | | (TRAILING, CENTER) | |
-    // Used for buttons at the bottom of the bubble which should nest at the
-    // bottom-right corner.
-    DOUBLE_BUTTON_COLUMN_SET = 1,
-
-    // | | (LEADING, CENTER) | | (TRAILING, CENTER) | |
-    // Used for buttons at the bottom of the bubble which should occupy
-    // the corners.
-    LINK_BUTTON_COLUMN_SET = 2,
-  };
-
   ManagePasswordsBubbleView(content::WebContents* web_contents,
                             views::View* anchor_view,
                             DisplayReason reason);
   virtual ~ManagePasswordsBubbleView();
 
-  // Construct an appropriate ColumnSet for the given |type|, and add it
-  // to |layout|.
-  void BuildColumnSet(views::GridLayout* layout, ColumnSetType type);
-
   // If the bubble is not anchored to a view, places the bubble in the top
   // right (left in RTL) of the |screen_bounds| that contain |web_contents_|'s
   // browser window. Because the positioning is based on the size of the
@@ -78,41 +135,15 @@
   // Close the bubble.
   void Close();
 
-  // Close the bubble without triggering UMA logging. We need this for the
-  // moment, as the current implementation can close the bubble without user
-  // interaction; we want to ensure that doesn't show up as a user action in
-  // our counts.
-  //
-  // TODO(mkwst): Throw this away once the icon is no longer responsible for
-  // creating the bubble.
-  void CloseWithoutLogging();
-
   // views::BubbleDelegateView:
   virtual void Init() OVERRIDE;
   virtual void WindowClosing() OVERRIDE;
 
-  // views::ButtonListener:
-  virtual void ButtonPressed(views::Button* sender,
-                             const ui::Event& event) OVERRIDE;
-
-  // views::LinkListener:
-  virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
-
-  // Handles the event when the user changes an index of a combobox.
-  virtual void OnPerformAction(views::Combobox* source) OVERRIDE;
-
   // Singleton instance of the Password bubble. The Password bubble can only be
   // shown on the active browser window, so there is no case in which it will be
   // shown twice at the same time.
   static ManagePasswordsBubbleView* manage_passwords_bubble_;
 
-  // The buttons that are shown in the bubble.
-  views::BlueButton* save_button_;
-  views::Combobox* refuse_combobox_;
-
-  views::Link* manage_link_;
-  views::LabelButton* done_button_;
-
   DISALLOW_COPY_AND_ASSIGN(ManagePasswordsBubbleView);
 };
 
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_browsertest.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_browsertest.cc
new file mode 100644
index 0000000..11f4e87
--- /dev/null
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_browsertest.cc
@@ -0,0 +1,117 @@
+// 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.
+
+#include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h"
+
+#include "base/metrics/histogram_samples.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/views/passwords/manage_passwords_view_test.h"
+#include "components/password_manager/core/browser/password_manager_metrics_util.h"
+#include "components/password_manager/core/browser/stub_password_manager_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char kDisplayDispositionMetric[] = "PasswordBubble.DisplayDisposition";
+
+}  // namespace
+
+typedef ManagePasswordsViewTest ManagePasswordsBubbleViewTest;
+
+IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, BasicOpenAndClose) {
+  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  ManagePasswordsBubbleView::ShowBubble(
+      browser()->tab_strip_model()->GetActiveWebContents(),
+      ManagePasswordsBubble::USER_ACTION);
+  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  ManagePasswordsBubbleView::CloseBubble();
+  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+
+  // And, just for grins, ensure that we can re-open the bubble.
+  ManagePasswordsBubbleView::ShowBubble(
+      browser()->tab_strip_model()->GetActiveWebContents(),
+      ManagePasswordsBubble::USER_ACTION);
+  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  ManagePasswordsBubbleView::CloseBubble();
+  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+}
+
+// Same as 'BasicOpenAndClose', but use the command rather than the static
+// method directly.
+IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, CommandControlsBubble) {
+  // The command only works if the icon is visible, so get into management mode.
+  SetupManagingPasswords();
+  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+  ExecuteManagePasswordsCommand();
+  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  ManagePasswordsBubbleView::CloseBubble();
+  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+
+  // And, just for grins, ensure that we can re-open the bubble.
+  ExecuteManagePasswordsCommand();
+  EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
+  ManagePasswordsBubbleView::CloseBubble();
+  EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
+}
+
+IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest,
+                       CommandExecutionInManagingState) {
+  SetupManagingPasswords();
+  ExecuteManagePasswordsCommand();
+
+  scoped_ptr<base::HistogramSamples> samples(
+      GetSamples(kDisplayDispositionMetric));
+  EXPECT_EQ(
+      0,
+      samples->GetCount(
+          password_manager::metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING));
+  EXPECT_EQ(0,
+            samples->GetCount(
+                password_manager::metrics_util::MANUAL_WITH_PASSWORD_PENDING));
+  EXPECT_EQ(1,
+            samples->GetCount(
+                password_manager::metrics_util::MANUAL_MANAGE_PASSWORDS));
+}
+
+IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest,
+                       CommandExecutionInAutomaticState) {
+  // Open with pending password: automagical!
+  SetupPendingPassword();
+
+  scoped_ptr<base::HistogramSamples> samples(
+      GetSamples(kDisplayDispositionMetric));
+  EXPECT_EQ(
+      1,
+      samples->GetCount(
+          password_manager::metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING));
+  EXPECT_EQ(0,
+            samples->GetCount(
+                password_manager::metrics_util::MANUAL_WITH_PASSWORD_PENDING));
+  EXPECT_EQ(0,
+            samples->GetCount(
+                password_manager::metrics_util::MANUAL_MANAGE_PASSWORDS));
+}
+
+IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest,
+                       CommandExecutionInPendingState) {
+  // Open once with pending password: automagical!
+  SetupPendingPassword();
+  ManagePasswordsBubbleView::CloseBubble();
+  // This opening should be measured as manual.
+  ExecuteManagePasswordsCommand();
+
+  scoped_ptr<base::HistogramSamples> samples(
+      GetSamples(kDisplayDispositionMetric));
+  EXPECT_EQ(
+      1,
+      samples->GetCount(
+          password_manager::metrics_util::AUTOMATIC_WITH_PASSWORD_PENDING));
+  EXPECT_EQ(1,
+            samples->GetCount(
+                password_manager::metrics_util::MANUAL_WITH_PASSWORD_PENDING));
+  EXPECT_EQ(0,
+            samples->GetCount(
+                password_manager::metrics_util::MANUAL_MANAGE_PASSWORDS));
+}
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_icon_view.cc
index 23a5950..72e3002 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_icon_view.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_view.cc
@@ -4,84 +4,66 @@
 
 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h"
 
-#include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h"
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/command_updater.h"
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/view_ids.h"
 #include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h"
+#include "components/password_manager/core/common/password_manager_ui.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 
-ManagePasswordsIconView::ManagePasswordsIconView(
-    LocationBarView::Delegate* location_bar_delegate)
-    : location_bar_delegate_(location_bar_delegate) {
+ManagePasswordsIconView::ManagePasswordsIconView(CommandUpdater* updater)
+    : BubbleIconView(updater, IDC_MANAGE_PASSWORDS_FOR_PAGE),
+      icon_id_(0),
+      tooltip_text_id_(0) {
   set_id(VIEW_ID_MANAGE_PASSWORDS_ICON_BUTTON);
   SetAccessibilityFocusable(true);
-  SetState(ManagePasswordsIcon::INACTIVE_STATE);
+  UpdateVisibleUI();
 }
 
 ManagePasswordsIconView::~ManagePasswordsIconView() {}
 
-void ManagePasswordsIconView::SetStateInternal(
-    ManagePasswordsIcon::State state) {
-  if (state == ManagePasswordsIcon::INACTIVE_STATE) {
+void ManagePasswordsIconView::UpdateVisibleUI() {
+  // If the icon is inactive: clear out it's image and tooltip, hide the icon,
+  // close any active bubble, and exit early.
+  if (state() == password_manager::ui::INACTIVE_STATE) {
+    icon_id_ = 0;
+    tooltip_text_id_ = 0;
+
     SetVisible(false);
     if (ManagePasswordsBubbleView::IsShowing())
       ManagePasswordsBubbleView::CloseBubble();
     return;
   }
 
-  // Start with the correct values for ManagePasswordsIcon::MANAGE_STATE, and
-  // adjust things accordingly if we're either in BLACKLISTED_STATE or
-  // PENDING_STATE.
-  int which_icon = IDR_SAVE_PASSWORD;
-  int which_text = IDS_PASSWORD_MANAGER_TOOLTIP_MANAGE;
-  if (state == ManagePasswordsIcon::BLACKLISTED_STATE)
-    which_icon = IDR_SAVE_PASSWORD_BLACKLISTED;
-  else if (state == ManagePasswordsIcon::PENDING_STATE)
-    which_text = IDS_PASSWORD_MANAGER_TOOLTIP_SAVE;
+  // Otherwise, start with the correct values for MANAGE_STATE, and adjust
+  // things accordingly if we're either in BLACKLIST_STATE or PENDING_STATE.
+  icon_id_ = IDR_SAVE_PASSWORD;
+  tooltip_text_id_ = IDS_PASSWORD_MANAGER_TOOLTIP_MANAGE;
+  if (state() == password_manager::ui::BLACKLIST_STATE)
+    icon_id_ = IDR_SAVE_PASSWORD_BLACKLISTED;
+  else if (password_manager::ui::IsPendingState(state()))
+    tooltip_text_id_ = IDS_PASSWORD_MANAGER_TOOLTIP_SAVE;
 
   SetVisible(true);
-  SetImage(
-      ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(which_icon));
-  SetTooltipText(l10n_util::GetStringUTF16(which_text));
-}
+  SetImage(ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(icon_id_));
+  SetTooltipText(l10n_util::GetStringUTF16(tooltip_text_id_));
 
-void ManagePasswordsIconView::ShowBubbleWithoutUserInteraction() {
-  // Suppress the bubble if the user is working in the omnibox.
-  if (location_bar_delegate_->GetToolbarModel()->input_in_progress())
-    return;
-
-  ManagePasswordsBubbleView::ShowBubble(
-      location_bar_delegate_->GetWebContents(),
-      ManagePasswordsBubbleView::AUTOMATIC);
-}
-
-bool ManagePasswordsIconView::GetTooltipText(const gfx::Point& p,
-                                             base::string16* tooltip) const {
-  // Don't show tooltip if the password bubble is displayed.
-  return !ManagePasswordsBubbleView::IsShowing() &&
-      ImageView::GetTooltipText(p, tooltip);
-}
-
-void ManagePasswordsIconView::OnGestureEvent(ui::GestureEvent* event) {
-  if (event->type() == ui::ET_GESTURE_TAP) {
-    ManagePasswordsBubbleView::ShowBubble(
-        location_bar_delegate_->GetWebContents(),
-        ManagePasswordsBubbleView::USER_ACTION);
-    event->SetHandled();
+  if (password_manager::ui::PENDING_PASSWORD_AND_BUBBLE_STATE) {
+    // We're about the automatically pop up a ManagePasswordsBubbleView.
+    // Force layout of the icon's parent now; the bubble will be incorrectly
+    // positioned otherwise, as the icon won't have been drawn into position.
+    parent()->Layout();
   }
 }
 
-bool ManagePasswordsIconView::OnMousePressed(const ui::MouseEvent& event) {
-  // Do nothing until the mouse button is released.
-  return true;
+bool ManagePasswordsIconView::IsBubbleShowing() const {
+  return ManagePasswordsBubbleView::IsShowing();
 }
 
-void ManagePasswordsIconView::OnMouseReleased(const ui::MouseEvent& event) {
-  if (event.IsOnlyLeftMouseButton() && HitTestPoint(event.location())) {
-    ManagePasswordsBubbleView::ShowBubble(
-        location_bar_delegate_->GetWebContents(),
-        ManagePasswordsBubbleView::USER_ACTION);
-  }
+void ManagePasswordsIconView::OnExecuting(
+    BubbleIconView::ExecuteSource source) {
 }
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_view.h b/chrome/browser/ui/views/passwords/manage_passwords_icon_view.h
index 7dd791c..39b0efc 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_icon_view.h
+++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_view.h
@@ -7,41 +7,37 @@
 
 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
 #include "chrome/browser/ui/passwords/manage_passwords_icon.h"
+#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "ui/views/controls/image_view.h"
 
-class ManagePasswordsBubbleUIController;
+class CommandUpdater;
+class ManagePasswordsUIController;
 
 // View for the password icon in the Omnibox.
 class ManagePasswordsIconView : public ManagePasswordsIcon,
-                                public views::ImageView {
+                                public BubbleIconView {
  public:
-  // Clicking on the ManagePasswordsIconView shows a ManagePasswordsBubbleView,
-  // which requires the current WebContents. Because the current WebContents
-  // changes as the user switches tabs, it cannot be provided in the
-  // constructor. Instead, a LocationBarView::Delegate is passed here so that it
-  // can be queried for the current WebContents as needed.
-  explicit ManagePasswordsIconView(
-      LocationBarView::Delegate* location_bar_delegate);
+  explicit ManagePasswordsIconView(CommandUpdater* updater);
   virtual ~ManagePasswordsIconView();
 
-  // ManagePasswordsIcon:
-  virtual void ShowBubbleWithoutUserInteraction() OVERRIDE;
+  // BubbleIconView:
+  virtual bool IsBubbleShowing() const OVERRIDE;
+  virtual void OnExecuting(BubbleIconView::ExecuteSource source) OVERRIDE;
+
+#if defined(UNIT_TEST)
+  int icon_id() const { return icon_id_; }
+  int tooltip_text_id() const { return tooltip_text_id_; }
+#endif
 
  protected:
   // ManagePasswordsIcon:
-  virtual void SetStateInternal(ManagePasswordsIcon::State state) OVERRIDE;
+  virtual void UpdateVisibleUI() OVERRIDE;
 
  private:
-  // views::ImageView:
-  virtual bool GetTooltipText(const gfx::Point& p,
-                              base::string16* tooltip) const OVERRIDE;
-  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
-  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
-  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
-
-  // The delegate used to get the currently visible WebContents.
-  LocationBarView::Delegate* location_bar_delegate_;
+  // The ID of the icon and text resources that are currently displayed.
+  int icon_id_;
+  int tooltip_text_id_;
 
   DISALLOW_COPY_AND_ASSIGN(ManagePasswordsIconView);
 };
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_view_browsertest.cc b/chrome/browser/ui/views/passwords/manage_passwords_icon_view_browsertest.cc
new file mode 100644
index 0000000..9f1331c
--- /dev/null
+++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_view_browsertest.cc
@@ -0,0 +1,46 @@
+// 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.
+
+#include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h"
+
+#include "chrome/browser/ui/passwords/manage_passwords_icon.h"
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h"
+#include "chrome/browser/ui/views/passwords/manage_passwords_view_test.h"
+#include "components/password_manager/core/common/password_manager_ui.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+typedef ManagePasswordsViewTest ManagePasswordsIconViewTest;
+
+IN_PROC_BROWSER_TEST_F(ManagePasswordsIconViewTest, DefaultStateIsInactive) {
+  EXPECT_EQ(password_manager::ui::INACTIVE_STATE, view()->state());
+  EXPECT_FALSE(view()->visible());
+  EXPECT_EQ(0, view()->icon_id());
+  EXPECT_EQ(0, view()->tooltip_text_id());
+}
+
+IN_PROC_BROWSER_TEST_F(ManagePasswordsIconViewTest, PendingState) {
+  SetupPendingPassword();
+  EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE, view()->state());
+  EXPECT_TRUE(view()->visible());
+  EXPECT_EQ(IDR_SAVE_PASSWORD, view()->icon_id());
+  EXPECT_EQ(IDS_PASSWORD_MANAGER_TOOLTIP_SAVE, view()->tooltip_text_id());
+}
+
+IN_PROC_BROWSER_TEST_F(ManagePasswordsIconViewTest, ManageState) {
+  SetupManagingPasswords();
+  EXPECT_EQ(password_manager::ui::MANAGE_STATE, view()->state());
+  EXPECT_TRUE(view()->visible());
+  EXPECT_EQ(IDR_SAVE_PASSWORD, view()->icon_id());
+  EXPECT_EQ(IDS_PASSWORD_MANAGER_TOOLTIP_MANAGE, view()->tooltip_text_id());
+}
+
+IN_PROC_BROWSER_TEST_F(ManagePasswordsIconViewTest, BlacklistedState) {
+  SetupBlackistedPassword();
+  EXPECT_EQ(password_manager::ui::BLACKLIST_STATE, view()->state());
+  EXPECT_TRUE(view()->visible());
+  EXPECT_EQ(IDR_SAVE_PASSWORD_BLACKLISTED, view()->icon_id());
+  EXPECT_EQ(IDS_PASSWORD_MANAGER_TOOLTIP_MANAGE, view()->tooltip_text_id());
+}
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_view_test.cc b/chrome/browser/ui/views/passwords/manage_passwords_view_test.cc
new file mode 100644
index 0000000..a8198c7
--- /dev/null
+++ b/chrome/browser/ui/views/passwords/manage_passwords_view_test.cc
@@ -0,0 +1,95 @@
+// 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.
+
+#include "chrome/browser/ui/views/passwords/manage_passwords_view_test.h"
+
+#include "base/test/statistics_delta_reader.h"
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_command_controller.h"
+#include "chrome/browser/ui/passwords/manage_passwords_icon.h"
+#include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h"
+#include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/interactive_test_utils.h"
+#include "components/autofill/core/common/password_form.h"
+#include "components/password_manager/core/browser/mock_password_manager_driver.h"
+#include "components/password_manager/core/browser/password_form_manager.h"
+#include "components/password_manager/core/browser/password_manager_driver.h"
+#include "components/password_manager/core/browser/password_manager_metrics_util.h"
+#include "components/password_manager/core/browser/stub_password_manager_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+void ManagePasswordsViewTest::SetUpOnMainThread() {
+  // Create the test UIController here so that it's bound to the currently
+  // active WebContents.
+  new ManagePasswordsUIControllerMock(
+      browser()->tab_strip_model()->GetActiveWebContents());
+}
+
+ManagePasswordsUIControllerMock* ManagePasswordsViewTest::controller() {
+  return static_cast<ManagePasswordsUIControllerMock*>(
+      ManagePasswordsUIController::FromWebContents(
+          browser()->tab_strip_model()->GetActiveWebContents()));
+}
+
+ManagePasswordsIconView* ManagePasswordsViewTest::view() {
+  BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
+  return browser_view->GetToolbarView()->location_bar()->
+      manage_passwords_icon_view();
+}
+
+void ManagePasswordsViewTest::ExecuteManagePasswordsCommand() {
+  // Show the window to ensure that it's active.
+  browser()->window()->Show();
+
+  CommandUpdater* updater = browser()->command_controller()->command_updater();
+  EXPECT_TRUE(updater->IsCommandEnabled(IDC_MANAGE_PASSWORDS_FOR_PAGE));
+  EXPECT_TRUE(updater->ExecuteCommand(IDC_MANAGE_PASSWORDS_FOR_PAGE));
+
+  // Wait for the command execution to pop up the bubble.
+  content::RunAllPendingInMessageLoop();
+}
+
+void ManagePasswordsViewTest::SetupManagingPasswords() {
+  base::string16 kTestUsername = base::ASCIIToUTF16("test_username");
+  autofill::PasswordFormMap map;
+  map[kTestUsername] = test_form();
+  controller()->OnPasswordAutofilled(map);
+  controller()->UpdateIconAndBubbleState(view());
+}
+
+void ManagePasswordsViewTest::SetupPendingPassword() {
+  password_manager::StubPasswordManagerClient client;
+  password_manager::MockPasswordManagerDriver driver;
+  scoped_ptr<password_manager::PasswordFormManager> test_form_manager(
+      new password_manager::PasswordFormManager(
+          NULL, &client, &driver, *test_form(), false));
+  controller()->OnPasswordSubmitted(test_form_manager.release());
+
+  // Wait for the command execution triggered by the automatic popup to pop up
+  // the bubble.
+  content::RunAllPendingInMessageLoop();
+  controller()->UpdateIconAndBubbleState(view());
+}
+
+void ManagePasswordsViewTest::SetupBlackistedPassword() {
+  base::string16 kTestUsername = base::ASCIIToUTF16("test_username");
+  autofill::PasswordFormMap map;
+  map[kTestUsername] = test_form();
+  controller()->OnBlacklistBlockedAutofill(map);
+  controller()->UpdateIconAndBubbleState(view());
+}
+
+base::HistogramSamples* ManagePasswordsViewTest::GetSamples(
+    const char* histogram) {
+  // Ensure that everything has been properly recorded before pulling samples.
+  content::RunAllPendingInMessageLoop();
+  return statistics_reader_.GetHistogramSamplesSinceCreation(
+      histogram).release();
+}
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_view_test.h b/chrome/browser/ui/views/passwords/manage_passwords_view_test.h
new file mode 100644
index 0000000..73743f8
--- /dev/null
+++ b/chrome/browser/ui/views/passwords/manage_passwords_view_test.h
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_PASSWORDS_MANAGE_PASSWORDS_VIEW_TEST_H_
+#define CHROME_BROWSER_UI_VIEWS_PASSWORDS_MANAGE_PASSWORDS_VIEW_TEST_H_
+
+#include "base/metrics/histogram_samples.h"
+#include "base/test/statistics_delta_reader.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/autofill/core/common/password_form.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class ManagePasswordsUIControllerMock;
+class ManagePasswordsIconView;
+
+// Test class for the various password management view bits and pieces. Sets
+// up a ManagePasswordsUIControllerMock, and provides some helper methods
+// to poke at the bubble, icon, and controller's state.
+class ManagePasswordsViewTest : public InProcessBrowserTest {
+ public:
+  ManagePasswordsViewTest() {}
+
+  // InProcessBrowserTest:
+  virtual void SetUpOnMainThread() OVERRIDE;
+
+  // Get the mock UI controller for the current WebContents.
+  ManagePasswordsUIControllerMock* controller();
+
+  // Get the icon view for the current WebContents.
+  ManagePasswordsIconView* view();
+
+  // Execute the browser command to open the manage passwords bubble.
+  void ExecuteManagePasswordsCommand();
+
+  // Put the controller, icon, and bubble into a managing-password state.
+  void SetupManagingPasswords();
+
+  // Put the controller, icon, and bubble into a pending-password state.
+  void SetupPendingPassword();
+
+  // Put the controller, icon, and bubble into a blacklisted state.
+  void SetupBlackistedPassword();
+
+  // Get samples for |histogram|.
+  base::HistogramSamples* GetSamples(const char* histogram);
+
+  autofill::PasswordForm* test_form() { return &test_form_; }
+
+ private:
+  autofill::PasswordForm test_form_;
+  base::StatisticsDeltaReader statistics_reader_;
+
+  DISALLOW_COPY_AND_ASSIGN(ManagePasswordsViewTest);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_PASSWORDS_MANAGE_PASSWORDS_VIEW_TEST_H_
diff --git a/chrome/browser/ui/views/passwords/save_password_refusal_combobox_model.cc b/chrome/browser/ui/views/passwords/save_password_refusal_combobox_model.cc
new file mode 100644
index 0000000..2ec5998
--- /dev/null
+++ b/chrome/browser/ui/views/passwords/save_password_refusal_combobox_model.cc
@@ -0,0 +1,33 @@
+// 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.
+
+#include "chrome/browser/ui/views/passwords/save_password_refusal_combobox_model.h"
+
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+SavePasswordRefusalComboboxModel::SavePasswordRefusalComboboxModel() {
+  items_.push_back(
+      l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_CANCEL_BUTTON));
+  items_.push_back(
+      l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON));
+}
+
+SavePasswordRefusalComboboxModel::~SavePasswordRefusalComboboxModel() {}
+
+int SavePasswordRefusalComboboxModel::GetItemCount() const {
+  return items_.size();
+}
+
+base::string16 SavePasswordRefusalComboboxModel::GetItemAt(int index) {
+  return items_[index];
+}
+
+bool SavePasswordRefusalComboboxModel::IsItemSeparatorAt(int index) {
+  return items_[index].empty();
+}
+
+int SavePasswordRefusalComboboxModel::GetDefaultIndex() const {
+  return 0;
+}
diff --git a/chrome/browser/ui/views/passwords/save_password_refusal_combobox_model.h b/chrome/browser/ui/views/passwords/save_password_refusal_combobox_model.h
new file mode 100644
index 0000000..e89f9db
--- /dev/null
+++ b/chrome/browser/ui/views/passwords/save_password_refusal_combobox_model.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_PASSWORDS_SAVE_PASSWORD_REFUSAL_COMBOBOX_MODEL_H_
+#define CHROME_BROWSER_UI_VIEWS_PASSWORDS_SAVE_PASSWORD_REFUSAL_COMBOBOX_MODEL_H_
+
+#include <vector>
+#include "base/basictypes.h"
+#include "base/strings/string16.h"
+#include "ui/base/models/combobox_model.h"
+
+class SavePasswordRefusalComboboxModel : public ui::ComboboxModel {
+ public:
+  enum { INDEX_NOPE = 0, INDEX_NEVER_FOR_THIS_SITE = 1 };
+
+  SavePasswordRefusalComboboxModel();
+  virtual ~SavePasswordRefusalComboboxModel();
+
+ private:
+  // Overridden from ui::ComboboxModel:
+  virtual int GetItemCount() const OVERRIDE;
+  virtual base::string16 GetItemAt(int index) OVERRIDE;
+  virtual bool IsItemSeparatorAt(int index) OVERRIDE;
+  virtual int GetDefaultIndex() const OVERRIDE;
+
+  std::vector<base::string16> items_;
+
+  DISALLOW_COPY_AND_ASSIGN(SavePasswordRefusalComboboxModel);
+};
+
+
+#endif  // CHROME_BROWSER_UI_VIEWS_PASSWORDS_SAVE_PASSWORD_REFUSAL_COMBOBOX_MODEL_H_
diff --git a/chrome/browser/ui/views/profiles/avatar_menu_bubble_view.cc b/chrome/browser/ui/views/profiles/avatar_menu_bubble_view.cc
index aa3b695..710e5e0 100644
--- a/chrome/browser/ui/views/profiles/avatar_menu_bubble_view.cc
+++ b/chrome/browser/ui/views/profiles/avatar_menu_bubble_view.cc
@@ -259,7 +259,9 @@
   set_notify_enter_exit_on_child(true);
 
   image_view_ = new ProfileImageView();
-  gfx::ImageSkia profile_icon = *item_.icon.ToImageSkia();
+  // GetSizedAvatarIcon will resize the icon in case it's too large.
+  const gfx::ImageSkia profile_icon = *profiles::GetSizedAvatarIcon(item_.icon,
+      false, profiles::kAvatarIconWidth, kItemHeight).ToImageSkia();
   if (item_.active || item_.signin_required)
     image_view_->SetImage(GetBadgedIcon(profile_icon));
   else
diff --git a/chrome/browser/ui/views/profiles/new_avatar_button.h b/chrome/browser/ui/views/profiles/new_avatar_button.h
index 898b85f..3fad44f 100644
--- a/chrome/browser/ui/views/profiles/new_avatar_button.h
+++ b/chrome/browser/ui/views/profiles/new_avatar_button.h
@@ -31,7 +31,9 @@
 
  private:
   friend class NewAvatarMenuButtonTest;
+  friend class ProfileChooserViewBrowserTest;
   FRIEND_TEST_ALL_PREFIXES(NewAvatarMenuButtonTest, SignOut);
+  FRIEND_TEST_ALL_PREFIXES(ProfileChooserViewBrowserTest, ViewProfileUMA);
 
   // ProfileInfoCacheObserver:
   virtual void OnProfileAdded(const base::FilePath& profile_path) OVERRIDE;
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
index d6f9276..7b44bcd 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile_metrics.h"
 #include "chrome/browser/profiles/profile_window.h"
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
@@ -152,36 +153,35 @@
       : views::ImageView(),
         change_photo_button_(NULL) {
     gfx::Image image = profiles::GetSizedAvatarIcon(
-        icon, true,
-        kLargeImageSide + profiles::kAvatarIconPadding,
-        kLargeImageSide + profiles::kAvatarIconPadding);
+        icon, true, kLargeImageSide, kLargeImageSide);
     SetImage(image.ToImageSkia());
     SetBoundsRect(bounds);
 
+    ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
+    views::ImageView* frame_overlay = new views::ImageView();
+    frame_overlay->SetImage(rb->GetImageNamed(
+        IDR_ICON_PROFILES_AVATAR_PHOTO_FRAME).ToImageSkia());
+    frame_overlay->SetVerticalAlignment(views::ImageView::CENTER);
+    frame_overlay->SetBoundsRect(bounds);
+    AddChildView(frame_overlay);
+
     if (!is_editing_allowed)
       return;
 
     set_notify_enter_exit_on_child(true);
 
     // Button overlay that appears when hovering over the image.
-    change_photo_button_ = new views::LabelButton(listener,
-        l10n_util::GetStringUTF16(IDS_PROFILES_PROFILE_CHANGE_PHOTO_BUTTON));
+    change_photo_button_ = new views::LabelButton(listener, base::string16());
     change_photo_button_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
     change_photo_button_->SetBorder(views::Border::NullBorder());
-    const SkColor color = SK_ColorWHITE;
-    change_photo_button_->SetTextColor(views::Button::STATE_NORMAL, color);
-    change_photo_button_->SetTextColor(views::Button::STATE_HOVERED, color);
 
-    const SkColor kBackgroundColor = SkColorSetARGB(125, 0, 0, 0);
+    const SkColor kBackgroundColor = SkColorSetARGB(65, 255, 255, 255);
     change_photo_button_->set_background(
         views::Background::CreateSolidBackground(kBackgroundColor));
-    // Need to take into account the border padding on the avatar.
-    const int kOverlayHeight = 20;
-    change_photo_button_->SetBounds(
-        bounds.origin().x(),
-        bounds.origin().y() + kLargeImageSide - kOverlayHeight,
-        kLargeImageSide,
-        kOverlayHeight);
+    change_photo_button_->SetImage(views::LabelButton::STATE_NORMAL,
+        *rb->GetImageSkiaNamed(IDR_ICON_PROFILES_EDIT_CAMERA));
+
+    change_photo_button_->SetBoundsRect(bounds);
     change_photo_button_->SetVisible(false);
     AddChildView(change_photo_button_);
   }
@@ -301,7 +301,7 @@
 // A title card with one back button right aligned and one label center aligned.
 class TitleCard : public views::View {
  public:
-   TitleCard(int message_id, views::ButtonListener* listener,
+  TitleCard(int message_id, views::ButtonListener* listener,
              views::ImageButton** back_button) {
     back_button_ = new views::ImageButton(listener);
     back_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
@@ -327,6 +327,37 @@
     AddChildView(title_label_);
   }
 
+  // Creates a new view that has the |title_card| with padding at the top, an
+  // edge-to-edge separator below, and the specified |view| at the bottom.
+  static views::View* AddPaddedTitleCard(views::View* view,
+                                         TitleCard* title_card,
+                                         int width) {
+    views::View* titled_view = new views::View();
+    views::GridLayout* layout = new views::GridLayout(titled_view);
+    titled_view->SetLayoutManager(layout);
+
+    // Column set 0 is a single column layout with horizontal padding at left
+    // and right, and column set 1 is a single column layout with no padding.
+    views::ColumnSet* columns = layout->AddColumnSet(0);
+    columns->AddPaddingColumn(1, views::kButtonHEdgeMarginNew);
+    int available_width = width - 2 * views::kButtonHEdgeMarginNew;
+    columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0,
+        views::GridLayout::FIXED, available_width, available_width);
+    columns->AddPaddingColumn(1, views::kButtonHEdgeMarginNew);
+    layout->AddColumnSet(1)->AddColumn(views::GridLayout::FILL,
+        views::GridLayout::FILL, 0,views::GridLayout::FIXED, width, width);
+
+    layout->StartRowWithPadding(1, 0, 0, views::kButtonVEdgeMarginNew);
+    layout->AddView(title_card);
+    layout->StartRowWithPadding(1, 1, 0, views::kRelatedControlVerticalSpacing);
+    layout->AddView(new views::Separator(views::Separator::HORIZONTAL));
+
+    layout->StartRow(1, 1);
+    layout->AddView(view);
+
+    return titled_view;
+  }
+
  private:
   virtual void Layout() OVERRIDE{
     back_button_->SetBounds(
@@ -335,9 +366,8 @@
   }
 
   virtual gfx::Size GetPreferredSize() OVERRIDE{
-    int height = profiles::kAvatarIconPadding * 2 +
-        std::max(title_label_->GetPreferredSize().height(),
-                 back_button_->GetPreferredSize().height());
+    int height = std::max(title_label_->GetPreferredSize().height(),
+        back_button_->GetPreferredSize().height());
     return gfx::Size(width(), height);
   }
 
@@ -395,10 +425,6 @@
 
   ResetView();
 
-  set_background(views::Background::CreateSolidBackground(
-      GetNativeTheme()->GetSystemColor(
-          ui::NativeTheme::kColorId_DialogBackground)));
-
   avatar_menu_.reset(new AvatarMenu(
       &g_browser_process->profile_manager()->GetProfileInfoCache(),
       this,
@@ -434,7 +460,7 @@
   tutorial_send_feedback_button_ = NULL;
   end_preview_and_relaunch_button_ = NULL;
   end_preview_cancel_button_ = NULL;
-  remove_account_and_relaunch_button_ = NULL;
+  remove_account_button_ = NULL;
   account_removal_cancel_button_ = NULL;
   gaia_signin_cancel_button_ = NULL;
   open_other_profile_indexes_map_.clear();
@@ -509,6 +535,10 @@
       layout = CreateSingleColumnLayout(this, kFixedMenuWidth);
       sub_view = CreateProfileChooserView(avatar_menu, last_tutorial_mode);
   }
+  sub_view->set_background(views::Background::CreateSolidBackground(
+      GetNativeTheme()->GetSystemColor(
+          ui::NativeTheme::kColorId_DialogBackground)));
+
   layout->StartRow(1, 0);
   layout->AddView(sub_view);
   Layout();
@@ -543,10 +573,15 @@
     // is indeed shown for the maximum number of times.
     browser_->profile()->GetPrefs()->SetInteger(
         prefs::kProfileAvatarTutorialShown, kProfileAvatarTutorialShowMax + 1);
+
+    ProfileMetrics::LogProfileUpgradeEnrollment(
+        ProfileMetrics::PROFILE_ENROLLMENT_CLOSE_WELCOME_CARD);
     ShowView(BUBBLE_VIEW_MODE_PROFILE_CHOOSER, avatar_menu_.get());
   } else if (sender == tutorial_enable_new_profile_management_button_) {
+    ProfileMetrics::LogProfileUpgradeEnrollment(
+        ProfileMetrics::PROFILE_ENROLLMENT_ACCEPT_NEW_PROFILE_MGMT);
     profiles::EnableNewProfileManagementPreview();
-  } else if (sender == remove_account_and_relaunch_button_) {
+  } else if (sender == remove_account_button_) {
     RemoveAccount();
   } else if (sender == account_removal_cancel_button_) {
     account_id_to_remove_.clear();
@@ -572,7 +607,12 @@
              sender == current_profile_photo_->change_photo_button()) {
     avatar_menu_->EditProfile(avatar_menu_->GetActiveProfileIndex());
   } else if (sender == signin_current_profile_link_) {
-    ShowView(BUBBLE_VIEW_MODE_GAIA_SIGNIN, avatar_menu_.get());
+    // Only show the inline signin if the new UI flag is flipped. Otherwise,
+    // use the tab signin page.
+    if (switches::IsNewProfileManagement())
+      ShowView(BUBBLE_VIEW_MODE_GAIA_SIGNIN, avatar_menu_.get());
+    else
+      chrome::ShowBrowserSignin(browser_, signin::SOURCE_MENU);
   } else {
     // Either one of the "other profiles", or one of the profile accounts
     // buttons was pressed.
@@ -603,7 +643,7 @@
     oauth2_token_service->RevokeCredentials(account_id_to_remove_);
   account_id_to_remove_.clear();
 
-  chrome::AttemptRestart();
+  ShowView(BUBBLE_VIEW_MODE_ACCOUNT_MANAGEMENT, avatar_menu_.get());
 }
 
 void ProfileChooserView::LinkClicked(views::Link* sender, int event_flags) {
@@ -619,6 +659,8 @@
   } else if (sender == add_account_link_) {
     ShowView(BUBBLE_VIEW_MODE_GAIA_ADD_ACCOUNT, avatar_menu_.get());
   } else if (sender == tutorial_learn_more_link_) {
+    ProfileMetrics::LogProfileUpgradeEnrollment(
+        ProfileMetrics::PROFILE_ENROLLMENT_LAUNCH_LEARN_MORE);
     // TODO(guohui): update |learn_more_url| once it is decided.
     const GURL lear_more_url("https://support.google.com/chrome/?hl=en#to");
     chrome::NavigateParams params(
@@ -668,7 +710,8 @@
 }
 
 views::View* ProfileChooserView::CreateProfileChooserView(
-    AvatarMenu* avatar_menu, TutorialMode last_tutorial_mode) {
+    AvatarMenu* avatar_menu,
+    TutorialMode last_tutorial_mode) {
   // TODO(guohui, noms): the view should be customized based on whether new
   // profile management preview is enabled or not.
 
@@ -704,6 +747,12 @@
   }
 
   if (tutorial_view) {
+    // Be sure not to track the tutorial display on View refresh, and only count
+    // the preview-promo view, shown when New Profile Management is off.
+    if (tutorial_mode_ != last_tutorial_mode && !is_new_profile_management) {
+      ProfileMetrics::LogProfileUpgradeEnrollment(
+          ProfileMetrics::PROFILE_ENROLLMENT_SHOW_PREVIEW_PROMO);
+    }
     layout->StartRow(1, 0);
     layout->AddView(tutorial_view);
   }
@@ -733,7 +782,7 @@
   layout->AddView(new views::Separator(views::Separator::HORIZONTAL));
 
   // Option buttons. Only available with the new profile management flag.
-  if (switches::IsNewProfileManagement()) {
+  if (option_buttons_view) {
     layout->StartRow(0, 0);
     layout->AddView(option_buttons_view);
   }
@@ -809,7 +858,7 @@
   title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   title_label->SetAutoColorReadabilityEnabled(false);
   title_label->SetEnabledColor(SK_ColorWHITE);
-  title_label ->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
+  title_label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
       ui::ResourceBundle::MediumFont));
   layout->StartRow(1, 0);
   layout->AddView(title_label);
@@ -886,7 +935,7 @@
   views::GridLayout* layout = CreateSingleColumnLayout(view, column_width);
   layout->SetInsets(views::kButtonVEdgeMarginNew,
                     views::kButtonHEdgeMarginNew,
-                    views::kRelatedControlVerticalSpacing,
+                    views::kUnrelatedControlVerticalSpacing,
                     views::kButtonHEdgeMarginNew);
 
   // Profile icon, centered.
@@ -901,7 +950,11 @@
         views::ImageButton::ALIGN_LEFT, views::ImageButton::ALIGN_MIDDLE);
     ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
     question_mark_button_->SetImage(views::ImageButton::STATE_NORMAL,
-                                    rb->GetImageSkiaNamed(IDR_QUESTION_MARK));
+        rb->GetImageSkiaNamed(IDR_ICON_PROFILES_MENU_QUESTION_STABLE));
+    question_mark_button_->SetImage(views::ImageButton::STATE_HOVERED,
+        rb->GetImageSkiaNamed(IDR_ICON_PROFILES_MENU_QUESTION_HOVER));
+    question_mark_button_->SetImage(views::ImageButton::STATE_PRESSED,
+        rb->GetImageSkiaNamed(IDR_ICON_PROFILES_MENU_QUESTION_SELECT));
     gfx::Size preferred_size = question_mark_button_->GetPreferredSize();
     question_mark_button_->SetBounds(
         0, 0, preferred_size.width(), preferred_size.height());
@@ -971,9 +1024,7 @@
     const int kSmallImageSide = 32;
 
     gfx::Image image = profiles::GetSizedAvatarIcon(
-        item.icon, true,
-        kSmallImageSide + profiles::kAvatarIconPadding,
-        kSmallImageSide + profiles::kAvatarIconPadding);
+        item.icon, true, kSmallImageSide, kSmallImageSide);
 
     views::LabelButton* button = new BackgroundColorHoverButton(
         this,
@@ -995,6 +1046,9 @@
 }
 
 views::View* ProfileChooserView::CreateOptionsView(bool enable_lock) {
+  if (!switches::IsNewProfileManagement())
+    return NULL;
+
   views::View* view = new views::View();
   views::GridLayout* layout;
 
@@ -1084,49 +1138,44 @@
                                              bool is_primary_account,
                                              int width) {
   ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
-  const gfx::ImageSkia* menu_marker =
+  const gfx::ImageSkia* default_image =
       rb->GetImageNamed(IDR_CLOSE_1).ToImageSkia();
+  int kDeleteButtonWidth = default_image->width();
+  int available_width = width -
+      kDeleteButtonWidth - views::kButtonHEdgeMarginNew;
 
   views::LabelButton* email_button = new BackgroundColorHoverButton(
-      this,
+      NULL,
       gfx::ElideEmail(base::UTF8ToUTF16(account),
                       rb->GetFontList(ui::ResourceBundle::BaseFont),
-                      width - menu_marker->width()),
+                      available_width),
       gfx::ImageSkia(),
       gfx::ImageSkia());
   layout->StartRow(1, 0);
   layout->AddView(email_button);
 
+  // Delete button.
+  views::ImageButton* delete_button = new views::ImageButton(this);
+  delete_button->SetImageAlignment(views::ImageButton::ALIGN_RIGHT,
+                                   views::ImageButton::ALIGN_MIDDLE);
+  delete_button->SetImage(views::ImageButton::STATE_NORMAL,
+                          default_image);
+  delete_button->SetImage(views::ImageButton::STATE_HOVERED,
+                          rb->GetImageSkiaNamed(IDR_CLOSE_1_H));
+  delete_button->SetImage(views::ImageButton::STATE_PRESSED,
+                          rb->GetImageSkiaNamed(IDR_CLOSE_1_P));
+  delete_button->SetBounds(
+      available_width, 0, kDeleteButtonWidth, kButtonHeight);
+
+  email_button->set_notify_enter_exit_on_child(true);
+  email_button->AddChildView(delete_button);
+
   // Save the original email address, as the button text could be elided.
-  current_profile_accounts_map_[email_button] = account;
+  current_profile_accounts_map_[delete_button] = account;
 }
 
 views::View* ProfileChooserView::CreateGaiaSigninView(
     bool add_secondary_account) {
-  views::View* view = new views::View();
-  views::GridLayout* layout =
-      CreateSingleColumnLayout(view, kFixedGaiaViewWidth);
-
-  // Adds title.
-  views::View* padded_title = new views::View();
-  int available_width = kFixedGaiaViewWidth - 2 * views::kButtonHEdgeMarginNew;
-  views::GridLayout* padded_layout = CreateSingleColumnLayout(
-      padded_title, available_width);
-  padded_layout->SetInsets(views::kButtonVEdgeMarginNew,
-                           views::kButtonHEdgeMarginNew,
-                           views::kButtonVEdgeMarginNew,
-                           views::kButtonHEdgeMarginNew);
-  padded_layout->StartRow(1, 0);
-  padded_layout->AddView(new TitleCard(
-      add_secondary_account ? IDS_PROFILES_GAIA_ADD_ACCOUNT_TITLE :
-                              IDS_PROFILES_GAIA_SIGNIN_TITLE,
-      this, &gaia_signin_cancel_button_));
-
-  layout->StartRow(1, 0);
-  layout->AddView(padded_title);
-  layout->StartRow(1, 0);
-  layout->AddView(new views::Separator(views::Separator::HORIZONTAL));
-
   // Adds Gaia signin webview
   Profile* profile = browser_->profile();
   views::WebView* web_view = new views::WebView(profile);
@@ -1139,28 +1188,23 @@
   web_view->SetPreferredSize(
       gfx::Size(kFixedGaiaViewWidth, kFixedGaiaViewHeight));
 
-  layout->StartRow(1, 0);
-  layout->AddView(web_view);
-
-  return view;
+  TitleCard* title_card = new TitleCard(
+      add_secondary_account ? IDS_PROFILES_GAIA_ADD_ACCOUNT_TITLE :
+                              IDS_PROFILES_GAIA_SIGNIN_TITLE,
+      this, &gaia_signin_cancel_button_);
+  return TitleCard::AddPaddedTitleCard(
+      web_view, title_card, kFixedGaiaViewWidth);
 }
 
 views::View* ProfileChooserView::CreateAccountRemovalView() {
   views::View* view = new views::View();
   views::GridLayout* layout = CreateSingleColumnLayout(
       view, kFixedAccountRemovalViewWidth - 2 * views::kButtonHEdgeMarginNew);
-  layout->SetInsets(views::kButtonVEdgeMarginNew,
+  layout->SetInsets(0,
                     views::kButtonHEdgeMarginNew,
                     views::kButtonVEdgeMarginNew,
                     views::kButtonHEdgeMarginNew);
 
-  // Adds title.
-  layout->StartRow(1, 0);
-  layout->AddView(new TitleCard(IDS_PROFILES_ACCOUNT_REMOVAL_TITLE, this,
-                                &account_removal_cancel_button_));
-  layout->StartRowWithPadding(1, 0, 0, views::kRelatedControlVerticalSpacing);
-  layout->AddView(new views::Separator(views::Separator::HORIZONTAL));
-
   const std::string& primary_account = SigninManagerFactory::GetForProfile(
       browser_->profile())->GetAuthenticatedUsername();
   bool is_primary_account = primary_account == account_id_to_remove_;
@@ -1196,18 +1240,21 @@
 
   // Adds button.
   if (!is_primary_account) {
-    remove_account_and_relaunch_button_ = new views::BlueButton(
+    remove_account_button_ = new views::BlueButton(
         this, l10n_util::GetStringUTF16(IDS_PROFILES_ACCOUNT_REMOVAL_BUTTON));
-    remove_account_and_relaunch_button_->SetHorizontalAlignment(
+    remove_account_button_->SetHorizontalAlignment(
         gfx::ALIGN_CENTER);
     layout->StartRowWithPadding(
         1, 0, 0, views::kUnrelatedControlVerticalSpacing);
-    layout->AddView(remove_account_and_relaunch_button_);
+    layout->AddView(remove_account_button_);
   } else {
     layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
   }
 
-  return view;
+  TitleCard* title_card = new TitleCard(IDS_PROFILES_ACCOUNT_REMOVAL_TITLE,
+      this, &account_removal_cancel_button_);
+  return TitleCard::AddPaddedTitleCard(view, title_card,
+      kFixedAccountRemovalViewWidth);
 }
 
 views::View* ProfileChooserView::CreateNewProfileManagementPreviewView() {
@@ -1225,18 +1272,11 @@
   views::View* view = new views::View();
   views::GridLayout* layout = CreateSingleColumnLayout(
       view, kFixedAccountRemovalViewWidth - 2 * views::kButtonHEdgeMarginNew);
-  layout->SetInsets(views::kButtonVEdgeMarginNew,
+  layout->SetInsets(0,
                     views::kButtonHEdgeMarginNew,
                     views::kButtonVEdgeMarginNew,
                     views::kButtonHEdgeMarginNew);
 
-  // Adds title.
-  layout->StartRow(1, 0);
-  layout->AddView(new TitleCard(IDS_PROFILES_END_PREVIEW, this,
-                                &end_preview_cancel_button_));
-  layout->StartRowWithPadding(1, 0, 0, views::kRelatedControlVerticalSpacing);
-  layout->AddView(new views::Separator(views::Separator::HORIZONTAL));
-
   // Adds main text.
   views::Label* content_label = new views::Label(
       l10n_util::GetStringUTF16(IDS_PROFILES_END_PREVIEW_TEXT));
@@ -1258,6 +1298,9 @@
       1, 0, 0, views::kUnrelatedControlVerticalSpacing);
   layout->AddView(end_preview_and_relaunch_button_);
 
-  return view;
+  TitleCard* title_card = new TitleCard(
+      IDS_PROFILES_END_PREVIEW, this, &end_preview_cancel_button_);
+  return TitleCard::AddPaddedTitleCard(
+      view, title_card, kFixedAccountRemovalViewWidth);
 }
 
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.h b/chrome/browser/ui/views/profiles/profile_chooser_view.h
index 66f76b6..b68f3b2 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.h
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.h
@@ -141,7 +141,7 @@
   // Creates the profile chooser view. |tutorial_shown| indicates if the "mirror
   // enabled" tutorial was shown or not in the last active view.
   views::View* CreateProfileChooserView(AvatarMenu* avatar_menu,
-                                        TutorialMode tutorial_mode);
+                                        TutorialMode last_tutorial_mode);
 
   // Creates the main profile card for the profile |avatar_item|. |is_guest|
   // is used to determine whether to show any Sign in/Sign out/Manage accounts
@@ -236,7 +236,7 @@
   views::ImageButton* gaia_signin_cancel_button_;
 
   // Links and buttons displayed in the account removal view.
-  views::LabelButton* remove_account_and_relaunch_button_;
+  views::LabelButton* remove_account_button_;
   views::ImageButton* account_removal_cancel_button_;
 
   // Links and buttons displayed in the end-preview view.
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc
new file mode 100644
index 0000000..af8fc1e
--- /dev/null
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc
@@ -0,0 +1,102 @@
+// 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.
+
+#include "chrome/browser/ui/views/profiles/profile_chooser_view.h"
+
+#include "base/command_line.h"
+#include "base/path_service.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile_metrics.h"
+#include "chrome/browser/profiles/profiles_state.h"
+#include "chrome/browser/ui/browser_dialogs.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/profiles/avatar_menu_button.h"
+#include "chrome/browser/ui/views/profiles/new_avatar_button.h"
+#include "chrome/browser/ui/views/profiles/user_manager_view.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/test_switches.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "chrome/test/base/uma_histogram_helper.h"
+#include "components/signin/core/common/profile_management_switches.h"
+#include "content/public/test/test_utils.h"
+#include "grit/generated_resources.h"
+#include "ui/views/controls/button/label_button.h"
+
+class ProfileChooserViewBrowserTest : public InProcessBrowserTest {
+ public:
+  ProfileChooserViewBrowserTest();
+  virtual ~ProfileChooserViewBrowserTest();
+
+ protected:
+  virtual void SetUp() OVERRIDE;
+  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE;
+  void OpenProfileChooserView();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ProfileChooserViewBrowserTest);
+};
+
+ProfileChooserViewBrowserTest::ProfileChooserViewBrowserTest() {
+}
+
+ProfileChooserViewBrowserTest::~ProfileChooserViewBrowserTest() {
+}
+
+void ProfileChooserViewBrowserTest::SetUp() {
+  InProcessBrowserTest::SetUp();
+  DCHECK(CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kNewAvatarMenu));
+}
+
+void ProfileChooserViewBrowserTest::SetUpCommandLine(
+    CommandLine* command_line) {
+  command_line->AppendSwitch(switches::kNewAvatarMenu);
+}
+
+void ProfileChooserViewBrowserTest::OpenProfileChooserView() {
+  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
+  NewAvatarButton* button = browser_view->frame()->GetNewAvatarMenuButton();
+  ASSERT_TRUE(button);
+
+  ProfileChooserView::clear_close_on_deactivate_for_testing();
+  ui::MouseEvent mouse_ev(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), 0,
+                          0);
+  button->NotifyClick(mouse_ev);
+  base::MessageLoop::current()->RunUntilIdle();
+  EXPECT_TRUE(ProfileChooserView::IsShowing());
+}
+
+#if defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_IOS)
+// This test doesn't make sense for ChromeOS since it has a different
+// multi-profiles menu in the system tray instead.
+//
+// Mobile platforms are also excluded due to a lack of avatar menu.
+#define MAYBE_ViewProfileUMA DISABLED_ViewProfileUMA
+#else
+#define MAYBE_ViewProfileUMA ViewProfileUMA
+#endif
+
+IN_PROC_BROWSER_TEST_F(ProfileChooserViewBrowserTest, MAYBE_ViewProfileUMA) {
+  UMAHistogramHelper histograms;
+  // If multiprofile mode is not enabled, you can't switch between profiles.
+  if (!profiles::IsMultipleProfilesEnabled())
+    return;
+
+  Profile* profile = browser()->profile();
+  profile->GetPrefs()->SetInteger(prefs::kProfileAvatarTutorialShown, 0);
+
+  ASSERT_NO_FATAL_FAILURE(OpenProfileChooserView());
+
+  histograms.Fetch();
+  histograms.ExpectUniqueSample("Profile.UpgradeEnrollment",
+      ProfileMetrics::PROFILE_ENROLLMENT_SHOW_PREVIEW_PROMO, 1);
+}
diff --git a/chrome/browser/ui/views/profiles/user_manager_view.cc b/chrome/browser/ui/views/profiles/user_manager_view.cc
index c0eb030..ed0bc6e 100644
--- a/chrome/browser/ui/views/profiles/user_manager_view.cc
+++ b/chrome/browser/ui/views/profiles/user_manager_view.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/views/auto_keep_alive.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/views/controls/webview/webview.h"
@@ -61,10 +60,9 @@
 // static
 UserManagerView* UserManagerView::instance_ = NULL;
 
-UserManagerView::UserManagerView(Profile* profile)
-    : web_view_(new views::WebView(profile)) {
-  SetLayoutManager(new views::FillLayout);
-  AddChildView(web_view_);
+UserManagerView::UserManagerView()
+    : web_view_(NULL),
+      keep_alive_(new AutoKeepAlive(NULL)) {
 }
 
 UserManagerView::~UserManagerView() {
@@ -85,7 +83,8 @@
   profiles::CreateGuestProfileForUserManager(
       profile_path_to_focus,
       tutorial_mode,
-      base::Bind(&UserManagerView::OnGuestProfileCreated));
+      base::Bind(&UserManagerView::OnGuestProfileCreated,
+                 base::Passed(make_scoped_ptr(new UserManagerView))));
 }
 
 // static
@@ -100,25 +99,32 @@
 }
 
 // static
-void UserManagerView::OnGuestProfileCreated(Profile* guest_profile,
-                                            const std::string& url) {
-  instance_ = new UserManagerView(guest_profile);
-  DialogDelegate::CreateDialogWidget(instance_, NULL, NULL);
+void UserManagerView::OnGuestProfileCreated(
+    scoped_ptr<UserManagerView> instance,
+    Profile* guest_profile,
+    const std::string& url) {
+  instance_ = instance.release();  // |instance_| takes over ownership.
+  instance_->Init(guest_profile, GURL(url));
+}
 
-  gfx::NativeWindow window = instance_->GetWidget()->GetNativeWindow();
-  instance_->keep_alive_.reset(new AutoKeepAlive(window));
+void UserManagerView::Init(Profile* guest_profile, const GURL& url) {
+  web_view_ = new views::WebView(guest_profile);
+  SetLayoutManager(new views::FillLayout);
+  AddChildView(web_view_);
+
+  DialogDelegate::CreateDialogWidget(this, NULL, NULL);
 
 #if defined(OS_WIN)
   // Set the app id for the task manager to the app id of its parent
   ui::win::SetAppIdForWindow(
       ShellIntegration::GetChromiumModelIdForProfile(
           guest_profile->GetPath()),
-      views::HWNDForWidget(instance_->GetWidget()));
+      views::HWNDForWidget(GetWidget()));
 #endif
-  instance_->GetWidget()->Show();
+  GetWidget()->Show();
 
-  instance_->web_view_->LoadInitialURL(GURL(url));
-  instance_->web_view_->RequestFocus();
+  web_view_->LoadInitialURL(url);
+  web_view_->RequestFocus();
 }
 
 gfx::Size UserManagerView::GetPreferredSize() {
diff --git a/chrome/browser/ui/views/profiles/user_manager_view.h b/chrome/browser/ui/views/profiles/user_manager_view.h
index 39230bf..da34390 100644
--- a/chrome/browser/ui/views/profiles/user_manager_view.h
+++ b/chrome/browser/ui/views/profiles/user_manager_view.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_PROFILES_USER_MANAGER_VIEW_H_
 #define CHROME_BROWSER_UI_VIEWS_PROFILES_USER_MANAGER_VIEW_H_
 
+#include "base/memory/scoped_ptr.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_window.h"
 #include "ui/views/window/dialog_delegate.h"
@@ -32,14 +33,20 @@
   static bool IsShowing();
 
  private:
-  explicit UserManagerView(Profile* profile);
+  friend struct base::DefaultDeleter<UserManagerView>;
+
+  UserManagerView();
   virtual ~UserManagerView();
 
   // Creates a new UserManagerView instance for the |guest_profile| and
   // shows the |url|.
-  static void OnGuestProfileCreated(Profile* guest_profile,
+  static void OnGuestProfileCreated(scoped_ptr<UserManagerView> instance,
+                                    Profile* guest_profile,
                                     const std::string& url);
 
+  // Creates dialog and initializes UI.
+  void Init(Profile* guest_profile, const GURL& url);
+
   // views::View:
   virtual gfx::Size GetPreferredSize() OVERRIDE;
 
diff --git a/chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc b/chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc
index c6187f9..d879b71 100644
--- a/chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc
+++ b/chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.cc
@@ -10,7 +10,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/views/sad_tab_view.cc b/chrome/browser/ui/views/sad_tab_view.cc
index 913025a..7cb679b 100644
--- a/chrome/browser/ui/views/sad_tab_view.cc
+++ b/chrome/browser/ui/views/sad_tab_view.cc
@@ -9,14 +9,13 @@
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/feedback/feedback_util.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/common/url_constants.h"
+#include "components/feedback/feedback_util.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -239,7 +238,7 @@
   // It is not possible to create a native_widget_win that has no parent in
   // and later re-parent it.
   // TODO(avi): This is a cheat. Can this be made cleaner?
-  sad_tab_params.parent = web_contents_->GetView()->GetNativeView();
+  sad_tab_params.parent = web_contents_->GetNativeView();
 
   set_owned_by_client();
 
@@ -248,9 +247,8 @@
   sad_tab->SetContentsView(this);
 
   views::Widget::ReparentNativeView(sad_tab->GetNativeView(),
-                                    web_contents_->GetView()->GetNativeView());
-  gfx::Rect bounds;
-  web_contents_->GetView()->GetContainerBounds(&bounds);
+                                    web_contents_->GetNativeView());
+  gfx::Rect bounds = web_contents_->GetContainerBounds();
   sad_tab->SetBounds(gfx::Rect(bounds.size()));
 }
 
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc
index 6107548..c143725 100644
--- a/chrome/browser/ui/views/session_crashed_bubble_view.cc
+++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -30,7 +30,6 @@
 #include "ui/views/controls/button/checkbox.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/label.h"
-#include "ui/views/controls/link.h"
 #include "ui/views/controls/separator.h"
 #include "ui/views/layout/grid_layout.h"
 #include "ui/views/layout/layout_constants.h"
@@ -94,7 +93,6 @@
       uma_option_(NULL),
       started_navigation_(false) {
   set_close_on_deactivate(false);
-  set_move_with_anchor(true);
   registrar_.Add(
       this,
       chrome::NOTIFICATION_TAB_CLOSING,
@@ -139,16 +137,6 @@
   text_label->SetEnabledColor(SK_ColorDKGRAY);
   text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
 
-  // Learn more link
-  views::Link* learn_more_link = NULL;
-  if (ShouldOfferMetricsReporting()) {
-    learn_more_link = new views::Link(
-        l10n_util::GetStringUTF16(IDS_LEARN_MORE));
-    learn_more_link->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-    learn_more_link->set_listener(this);
-    learn_more_link->SetUnderline(false);
-  }
-
   // Restore button.
   restore_button_ = new views::LabelButton(
       this, l10n_util::GetStringUTF16(IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON));
@@ -176,14 +164,10 @@
   cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
                 GridLayout::FIXED, kWidthOfDescriptionText, 0);
 
-  // Learn more link and restore button row
-  const int kLinkAndButtonColumnSetId = 2;
-  cs = layout->AddColumnSet(kLinkAndButtonColumnSetId);
+  // Restore button row
+  const int kButtonColumnSetId = 2;
+  cs = layout->AddColumnSet(kButtonColumnSetId);
   cs->AddPaddingColumn(0, kMarginWidth);
-  if (learn_more_link) {
-    cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
-                  GridLayout::USE_PREF, 0, 0);
-  }
   cs->AddPaddingColumn(1, views::kRelatedControlHorizontalSpacing);
   cs->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
                 GridLayout::USE_PREF, 0, 0);
@@ -199,14 +183,12 @@
   layout->AddView(text_label);
   layout->AddPaddingRow(0, kMarginHeight);
 
-  layout->StartRow(0, kLinkAndButtonColumnSetId);
-  if (learn_more_link)
-    layout->AddView(learn_more_link);
+  layout->StartRow(0, kButtonColumnSetId);
   layout->AddView(restore_button_);
   layout->AddPaddingRow(0, kMarginHeight);
 
   // Metrics reporting option.
-  if (learn_more_link)
+  if (ShouldOfferMetricsReporting())
     CreateUmaOptinView(layout);
 
   set_color(kWhiteBackgroundColor);
@@ -258,16 +240,6 @@
     CloseBubble();
 }
 
-void SessionCrashedBubbleView::LinkClicked(views::Link* source,
-                                           int event_flags) {
-  browser_->OpenURL(content::OpenURLParams(
-      GURL("https://support.google.com/chrome/answer/96817"),
-      content::Referrer(),
-      NEW_FOREGROUND_TAB,
-      content::PAGE_TRANSITION_LINK,
-      false));
-}
-
 void SessionCrashedBubbleView::DidStartNavigationToPendingEntry(
       const GURL& url,
       content::NavigationController::ReloadType reload_type) {
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.h b/chrome/browser/ui/views/session_crashed_bubble_view.h
index 4093e61..f6b0247 100644
--- a/chrome/browser/ui/views/session_crashed_bubble_view.h
+++ b/chrome/browser/ui/views/session_crashed_bubble_view.h
@@ -11,7 +11,6 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "ui/views/bubble/bubble_delegate.h"
 #include "ui/views/controls/button/button.h"
-#include "ui/views/controls/link_listener.h"
 
 namespace views {
 class Checkbox;
@@ -33,7 +32,6 @@
 class SessionCrashedBubbleView
     : public views::BubbleDelegateView,
       public views::ButtonListener,
-      public views::LinkListener,
       public content::WebContentsObserver,
       public content::NotificationObserver,
       public TabStripModelObserver {
@@ -56,9 +54,6 @@
   virtual void ButtonPressed(views::Button* sender,
                              const ui::Event& event) OVERRIDE;
 
-  // views::LinkListener methods.
-  virtual void LinkClicked(views::Link* source, int event_floags) OVERRIDE;
-
   // content::WebContentsObserver methods.
   virtual void DidStartNavigationToPendingEntry(
       const GURL& url,
diff --git a/chrome/browser/ui/views/simple_message_box_views.cc b/chrome/browser/ui/views/simple_message_box_views.cc
index 29d9e6d..b3da090 100644
--- a/chrome/browser/ui/views/simple_message_box_views.cc
+++ b/chrome/browser/ui/views/simple_message_box_views.cc
@@ -11,6 +11,7 @@
 #include "grit/generated_resources.h"
 #include "ui/aura/window.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/views/controls/message_box_view.h"
 #include "ui/views/widget/widget.h"
@@ -195,21 +196,26 @@
                                     MessageBoxType type,
                                     const base::string16& yes_text,
                                     const base::string16& no_text) {
-  // Views dialogs cannot be shown outside the UI thread message loop.
+  // Views dialogs cannot be shown outside the UI thread message loop or if the
+  // ResourceBundle is not initialized yet.
   // Fallback to logging with a default response or a Windows MessageBox.
-  if (!base::MessageLoopForUI::IsCurrent() ||
-      !base::MessageLoopForUI::current()->is_running()) {
 #if defined(OS_WIN)
+  if (!base::MessageLoopForUI::IsCurrent() ||
+      !base::MessageLoopForUI::current()->is_running() ||
+      !ResourceBundle::HasSharedInstance()) {
     int result = ui::MessageBox(views::HWNDForNativeWindow(parent), message,
                                 title, GetMessageBoxFlagsFromType(type));
     return (result == IDYES || result == IDOK) ?
         MESSAGE_BOX_RESULT_YES : MESSAGE_BOX_RESULT_NO;
+  }
 #else
+  if (!base::MessageLoopForUI::IsCurrent() ||
+      !ResourceBundle::HasSharedInstance()) {
     LOG(ERROR) << "Unable to show a dialog outside the UI thread message loop: "
                << title << " - " << message;
     return MESSAGE_BOX_RESULT_NO;
-#endif
   }
+#endif
 
   MessageBoxResult result = MESSAGE_BOX_RESULT_NO;
   SimpleMessageBoxViews* dialog = new SimpleMessageBoxViews(
diff --git a/chrome/browser/ui/views/speech_recognition_bubble_views.cc b/chrome/browser/ui/views/speech_recognition_bubble_views.cc
deleted file mode 100644
index 70ef972..0000000
--- a/chrome/browser/ui/views/speech_recognition_bubble_views.cc
+++ /dev/null
@@ -1,438 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/browser/speech/speech_recognition_bubble.h"
-
-#include <algorithm>
-
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
-#include "content/public/browser/resource_context.h"
-#include "content/public/browser/speech_recognition_manager.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/views/bubble/bubble_delegate.h"
-#include "ui/views/controls/button/label_button.h"
-#include "ui/views/controls/image_view.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/controls/link.h"
-#include "ui/views/controls/link_listener.h"
-#include "ui/views/layout/layout_constants.h"
-#include "ui/views/widget/widget_observer.h"
-
-using content::WebContents;
-
-namespace {
-
-const int kBubbleHorizMargin = 6;
-const int kBubbleVertMargin = 4;
-const int kBubbleHeadingVertMargin = 6;
-
-// This is the SpeechRecognitionBubble content and views bubble delegate.
-class SpeechRecognitionBubbleView : public views::BubbleDelegateView,
-                                    public views::ButtonListener,
-                                    public views::LinkListener {
- public:
-  SpeechRecognitionBubbleView(SpeechRecognitionBubbleDelegate* delegate,
-                              views::View* anchor_view,
-                              const gfx::Rect& element_rect,
-                              WebContents* web_contents);
-
-  void UpdateLayout(SpeechRecognitionBubbleBase::DisplayMode mode,
-                    const base::string16& message_text,
-                    const gfx::ImageSkia& image);
-  void SetImage(const gfx::ImageSkia& image);
-
-  // views::BubbleDelegateView methods.
-  virtual void OnWidgetActivationChanged(views::Widget* widget,
-                                         bool active) OVERRIDE;
-  virtual gfx::Rect GetAnchorRect() OVERRIDE;
-  virtual void Init() OVERRIDE;
-
-  // views::ButtonListener methods.
-  virtual void ButtonPressed(views::Button* source,
-                             const ui::Event& event) OVERRIDE;
-
-  // views::LinkListener methods.
-  virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
-
-  // views::View overrides.
-  virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
-  virtual gfx::Size GetPreferredSize() OVERRIDE;
-  virtual void Layout() OVERRIDE;
-
-  void set_notify_delegate_on_activation_change(bool notify) {
-    notify_delegate_on_activation_change_ = notify;
-  }
-
- private:
-  SpeechRecognitionBubbleDelegate* delegate_;
-  gfx::Rect element_rect_;
-  WebContents* web_contents_;
-  bool notify_delegate_on_activation_change_;
-  views::ImageView* icon_;
-  views::Label* heading_;
-  views::Label* message_;
-  views::LabelButton* try_again_;
-  views::LabelButton* cancel_;
-  views::Link* mic_settings_;
-  SpeechRecognitionBubbleBase::DisplayMode display_mode_;
-  const int kIconLayoutMinWidth;
-
-  DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionBubbleView);
-};
-
-SpeechRecognitionBubbleView::SpeechRecognitionBubbleView(
-    SpeechRecognitionBubbleDelegate* delegate,
-    views::View* anchor_view,
-    const gfx::Rect& element_rect,
-    WebContents* web_contents)
-    : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
-      delegate_(delegate),
-      element_rect_(element_rect),
-      web_contents_(web_contents),
-      notify_delegate_on_activation_change_(true),
-      icon_(NULL),
-      heading_(NULL),
-      message_(NULL),
-      try_again_(NULL),
-      cancel_(NULL),
-      mic_settings_(NULL),
-      display_mode_(SpeechRecognitionBubbleBase::DISPLAY_MODE_WARM_UP),
-      kIconLayoutMinWidth(ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-                          IDR_SPEECH_INPUT_MIC_EMPTY)->width()) {
-  // The bubble lifetime is managed by its controller; explicitly closing
-  // on deactivation will cause unexpected behavior.
-  set_close_on_deactivate(false);
-  // Prevent default behavior of bubble closure on escape key and handle
-  // it in the AcceleratorPressed() to avoid an unexpected behavior.
-  set_close_on_esc(false);
-
-  // Update the bubble's bounds when the window's bounds changes.
-  set_move_with_anchor(true);
-}
-
-void SpeechRecognitionBubbleView::OnWidgetActivationChanged(
-    views::Widget* widget, bool active) {
-  if (widget == GetWidget() && !active && notify_delegate_on_activation_change_)
-    delegate_->InfoBubbleFocusChanged();
-  BubbleDelegateView::OnWidgetActivationChanged(widget, active);
-}
-
-gfx::Rect SpeechRecognitionBubbleView::GetAnchorRect() {
-  gfx::Rect container_rect;
-  web_contents_->GetView()->GetContainerBounds(&container_rect);
-  gfx::Rect anchor(element_rect_);
-  anchor.Offset(container_rect.OffsetFromOrigin());
-  if (!container_rect.Intersects(anchor))
-    return BubbleDelegateView::GetAnchorRect();
-  return anchor;
-}
-
-void SpeechRecognitionBubbleView::Init() {
-  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  const gfx::FontList& font_list =
-      rb.GetFontList(ui::ResourceBundle::MediumFont);
-
-  heading_ = new views::Label(
-      l10n_util::GetStringUTF16(IDS_SPEECH_INPUT_BUBBLE_HEADING), font_list);
-  heading_->SetBorder(views::Border::CreateEmptyBorder(
-      kBubbleHeadingVertMargin, 0, kBubbleHeadingVertMargin, 0));
-  heading_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
-  AddChildView(heading_);
-
-  message_ = new views::Label(base::string16(), font_list);
-  message_->SetMultiLine(true);
-  AddChildView(message_);
-
-  icon_ = new views::ImageView();
-  icon_->SetHorizontalAlignment(views::ImageView::CENTER);
-  AddChildView(icon_);
-
-  cancel_ = new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_CANCEL));
-  cancel_->SetStyle(views::Button::STYLE_BUTTON);
-  AddChildView(cancel_);
-
-  try_again_ = new views::LabelButton(
-      this, l10n_util::GetStringUTF16(IDS_SPEECH_INPUT_TRY_AGAIN));
-  try_again_->SetStyle(views::Button::STYLE_BUTTON);
-  AddChildView(try_again_);
-
-  mic_settings_ = new views::Link(
-      l10n_util::GetStringUTF16(IDS_SPEECH_INPUT_MIC_SETTINGS));
-  mic_settings_->set_listener(this);
-  AddChildView(mic_settings_);
-}
-
-void SpeechRecognitionBubbleView::UpdateLayout(
-    SpeechRecognitionBubbleBase::DisplayMode mode,
-    const base::string16& message_text,
-    const gfx::ImageSkia& image) {
-  display_mode_ = mode;
-  bool is_message = (mode == SpeechRecognitionBubbleBase::DISPLAY_MODE_MESSAGE);
-  icon_->SetVisible(!is_message);
-  message_->SetVisible(is_message);
-  mic_settings_->SetVisible(is_message);
-  try_again_->SetVisible(is_message);
-  cancel_->SetVisible(
-      mode != SpeechRecognitionBubbleBase::DISPLAY_MODE_WARM_UP);
-  heading_->SetVisible(
-      mode == SpeechRecognitionBubbleBase::DISPLAY_MODE_RECORDING);
-
-  // Clickable elements should be enabled if and only if they are visible.
-  mic_settings_->SetEnabled(mic_settings_->visible());
-  try_again_->SetEnabled(try_again_->visible());
-  cancel_->SetEnabled(cancel_->visible());
-
-  if (is_message) {
-    message_->SetText(message_text);
-  } else {
-    SetImage(image);
-  }
-
-  if (icon_->visible())
-    icon_->ResetImageSize();
-
-  // When moving from warming up to recording state, the size of the content
-  // stays the same. So we wouldn't get a resize/layout call from the view
-  // system and we do it ourselves.
-  if (GetPreferredSize() == size())  // |size()| here is the current size.
-    Layout();
-
-  SizeToContents();
-}
-
-void SpeechRecognitionBubbleView::SetImage(const gfx::ImageSkia& image) {
-  icon_->SetImage(image);
-}
-
-void SpeechRecognitionBubbleView::ButtonPressed(views::Button* source,
-                                                const ui::Event& event) {
-  if (source == cancel_) {
-    delegate_->InfoBubbleButtonClicked(SpeechRecognitionBubble::BUTTON_CANCEL);
-  } else if (source == try_again_) {
-    delegate_->InfoBubbleButtonClicked(
-        SpeechRecognitionBubble::BUTTON_TRY_AGAIN);
-  } else {
-    NOTREACHED() << "Unknown button";
-  }
-}
-
-void SpeechRecognitionBubbleView::LinkClicked(views::Link* source,
-                                              int event_flags) {
-  DCHECK_EQ(mic_settings_, source);
-  content::SpeechRecognitionManager::GetInstance()->ShowAudioInputSettings();
-}
-
-bool SpeechRecognitionBubbleView::AcceleratorPressed(
-    const ui::Accelerator& accelerator) {
-  // The accelerator is added by BubbleDelegateView.
-  if (accelerator.key_code() == ui::VKEY_ESCAPE) {
-    delegate_->InfoBubbleButtonClicked(SpeechRecognitionBubble::BUTTON_CANCEL);
-    return true;
-  }
-
-  return BubbleDelegateView::AcceleratorPressed(accelerator);
-}
-
-gfx::Size SpeechRecognitionBubbleView::GetPreferredSize() {
-  int width = heading_->GetPreferredSize().width();
-  int control_width = cancel_->GetPreferredSize().width();
-  if (try_again_->visible()) {
-    control_width += try_again_->GetPreferredSize().width() +
-                     views::kRelatedButtonHSpacing;
-  }
-  width = std::max(width, control_width);
-  control_width = std::max(icon_->GetPreferredSize().width(),
-                           kIconLayoutMinWidth);
-  width = std::max(width, control_width);
-  if (mic_settings_->visible()) {
-    control_width = mic_settings_->GetPreferredSize().width();
-    width = std::max(width, control_width);
-  }
-
-  int height = cancel_->GetPreferredSize().height();
-  if (message_->visible()) {
-    height += message_->GetHeightForWidth(width) +
-              views::kLabelToControlVerticalSpacing;
-  }
-  if (heading_->visible())
-    height += heading_->GetPreferredSize().height();
-  if (icon_->visible())
-    height += icon_->GetImage().height();
-  if (mic_settings_->visible())
-    height += mic_settings_->GetPreferredSize().height();
-  width += kBubbleHorizMargin * 2;
-  height += kBubbleVertMargin * 2;
-
-  return gfx::Size(width, height);
-}
-
-void SpeechRecognitionBubbleView::Layout() {
-  int x = kBubbleHorizMargin;
-  int y = kBubbleVertMargin;
-  int available_width = width() - kBubbleHorizMargin * 2;
-  int available_height = height() - kBubbleVertMargin * 2;
-
-  if (message_->visible()) {
-    DCHECK(try_again_->visible());
-
-    int control_height = try_again_->GetPreferredSize().height();
-    int try_again_width = try_again_->GetPreferredSize().width();
-    int cancel_width = cancel_->GetPreferredSize().width();
-    y += available_height - control_height;
-    x += (available_width - cancel_width - try_again_width -
-          views::kRelatedButtonHSpacing) / 2;
-    try_again_->SetBounds(x, y, try_again_width, control_height);
-    cancel_->SetBounds(x + try_again_width + views::kRelatedButtonHSpacing, y,
-                       cancel_width, control_height);
-
-    control_height = message_->GetHeightForWidth(available_width);
-    message_->SetBounds(kBubbleHorizMargin, kBubbleVertMargin,
-                        available_width, control_height);
-    y = kBubbleVertMargin + control_height;
-
-    control_height = mic_settings_->GetPreferredSize().height();
-    mic_settings_->SetBounds(kBubbleHorizMargin, y, available_width,
-                             control_height);
-  } else {
-    DCHECK(icon_->visible());
-
-    int control_height = icon_->GetImage().height();
-    if (display_mode_ == SpeechRecognitionBubbleBase::DISPLAY_MODE_WARM_UP)
-      y = (available_height - control_height) / 2;
-    icon_->SetBounds(x, y, available_width, control_height);
-    y += control_height;
-
-    if (heading_->visible()) {
-      control_height = heading_->GetPreferredSize().height();
-      heading_->SetBounds(x, y, available_width, control_height);
-      y += control_height;
-    }
-
-    if (cancel_->visible()) {
-      control_height = cancel_->GetPreferredSize().height();
-      int width = cancel_->GetPreferredSize().width();
-      cancel_->SetBounds(x + (available_width - width) / 2, y, width,
-                         control_height);
-    }
-  }
-}
-
-// Implementation of SpeechRecognitionBubble.
-class SpeechRecognitionBubbleImpl
-    : public SpeechRecognitionBubbleBase,
-      public views::WidgetObserver {
- public:
-  SpeechRecognitionBubbleImpl(int render_process_id, int render_view_id,
-                              Delegate* delegate,
-                              const gfx::Rect& element_rect);
-  virtual ~SpeechRecognitionBubbleImpl();
-
-  // SpeechRecognitionBubble methods.
-  virtual void Show() OVERRIDE;
-  virtual void Hide() OVERRIDE;
-
-  // SpeechRecognitionBubbleBase methods.
-  virtual void UpdateLayout() OVERRIDE;
-  virtual void UpdateImage() OVERRIDE;
-
-  // views::WidgetObserver methods.
-  virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
-
- private:
-  Delegate* delegate_;
-  SpeechRecognitionBubbleView* bubble_;
-  gfx::Rect element_rect_;
-
-  DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionBubbleImpl);
-};
-
-SpeechRecognitionBubbleImpl::SpeechRecognitionBubbleImpl(
-    int render_process_id, int render_view_id, Delegate* delegate,
-    const gfx::Rect& element_rect)
-    : SpeechRecognitionBubbleBase(render_process_id, render_view_id),
-      delegate_(delegate),
-      bubble_(NULL),
-      element_rect_(element_rect) {
-}
-
-SpeechRecognitionBubbleImpl::~SpeechRecognitionBubbleImpl() {
-  if (bubble_) {
-    bubble_->GetWidget()->RemoveObserver(this);
-    bubble_->set_notify_delegate_on_activation_change(false);
-    bubble_->GetWidget()->Close();
-  }
-}
-
-void SpeechRecognitionBubbleImpl::OnWidgetDestroying(views::Widget* widget) {
-  bubble_ = NULL;
-}
-
-void SpeechRecognitionBubbleImpl::Show() {
-  WebContents* web_contents = GetWebContents();
-  if (!web_contents)
-    return;
-
-  if (!bubble_) {
-    views::View* icon = NULL;
-
-    // Anchor to the location bar, in case |element_rect| is offscreen.
-    Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
-    if (browser) {
-      BrowserView* browser_view =
-          BrowserView::GetBrowserViewForBrowser(browser);
-      icon = browser_view->GetLocationBarView() ?
-          browser_view->GetLocationBarView()->GetLocationBarAnchor() : NULL;
-    }
-
-    bubble_ = new SpeechRecognitionBubbleView(delegate_, icon, element_rect_,
-                                              web_contents);
-
-    if (!icon) {
-      // We dont't have an icon to attach to. Manually specify the web contents
-      // window as the parent.
-      bubble_->set_parent_window(
-          web_contents->GetView()->GetTopLevelNativeWindow());
-    }
-
-    views::BubbleDelegateView::CreateBubble(bubble_);
-    UpdateLayout();
-    bubble_->GetWidget()->AddObserver(this);
-   }
-  bubble_->GetWidget()->Show();
-}
-
-void SpeechRecognitionBubbleImpl::Hide() {
-  if (bubble_)
-    bubble_->GetWidget()->Hide();
-}
-
-void SpeechRecognitionBubbleImpl::UpdateLayout() {
-  if (bubble_ && GetWebContents())
-    bubble_->UpdateLayout(display_mode(), message_text(), icon_image());
-}
-
-void SpeechRecognitionBubbleImpl::UpdateImage() {
-  if (bubble_ && GetWebContents())
-    bubble_->SetImage(icon_image());
-}
-
-}  // namespace
-
-SpeechRecognitionBubble* SpeechRecognitionBubble::CreateNativeBubble(
-    int render_process_id,
-    int render_view_id,
-    SpeechRecognitionBubble::Delegate* delegate,
-    const gfx::Rect& element_rect) {
-  return new SpeechRecognitionBubbleImpl(render_process_id, render_view_id,
-      delegate, element_rect);
-}
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector.cc b/chrome/browser/ui/views/ssl_client_certificate_selector.cc
index 9175e8f..08eefd9 100644
--- a/chrome/browser/ui/views/ssl_client_certificate_selector.cc
+++ b/chrome/browser/ui/views/ssl_client_certificate_selector.cc
@@ -14,7 +14,6 @@
 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "net/cert/x509_certificate.h"
 #include "net/ssl/ssl_cert_request_info.h"
@@ -267,7 +266,7 @@
     net::X509Certificate* cert = GetSelectedCert();
     if (cert)
       ShowCertificateViewer(web_contents_,
-                            web_contents_->GetView()->GetTopLevelNativeWindow(),
+                            web_contents_->GetTopLevelNativeWindow(),
                             cert);
   }
 }
diff --git a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
index 07f6ec9..b1c19ee 100644
--- a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
+++ b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
@@ -16,7 +16,6 @@
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
index 1b56ee4..1b9d752 100644
--- a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
+++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
@@ -17,7 +17,6 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/aura/client/screen_position_client.h"
 #include "ui/aura/window.h"
 #include "ui/views/focus/focus_manager.h"
@@ -190,7 +189,7 @@
 aura::Window* ChromeWebContentsViewDelegateViews::GetActiveNativeView() {
   return web_contents_->GetFullscreenRenderWidgetHostView() ?
       web_contents_->GetFullscreenRenderWidgetHostView()->GetNativeView() :
-      web_contents_->GetView()->GetNativeView();
+      web_contents_->GetNativeView();
 }
 
 views::Widget* ChromeWebContentsViewDelegateViews::GetTopLevelWidget() {
@@ -208,7 +207,7 @@
     if (web_contents_->GetDelegate())
       web_contents_->GetDelegate()->SetFocusToLocationBar(false);
   } else {
-    web_contents_->GetView()->Focus();
+    web_contents_->Focus();
   }
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
index 624c229..54f836d 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -33,7 +33,6 @@
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "extensions/browser/extension_function_dispatcher.h"
 #include "ui/aura/env.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -589,7 +588,7 @@
     if (is_dragging_new_browser_) {
       content::WebContents* active_contents = source_dragged_contents();
       if (active_contents && !active_contents->FocusLocationBarByDefault())
-        active_contents->GetView()->Focus();
+        active_contents->Focus();
     }
     return;
   }
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index 6b0f8e2..76f2329 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -590,7 +590,7 @@
 
 }  // namespace
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
 // compositor. crbug.com/331924
 #define MAYBE_DragToSeparateWindow DISABLED_DragToSeparateWindow
@@ -669,7 +669,7 @@
 
 }  // namespace
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
 // compositor. crbug.com/331924
 #define MAYBE_DetachToOwnWindow DISABLED_DetachToOwnWindow
@@ -731,7 +731,7 @@
   EXPECT_FALSE(tab_strip2->GetWidget()->HasCapture());
 }
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
 // compositor. crbug.com/331924
 #define MAYBE_DetachToOwnWindowFromMaximizedWindow \
@@ -1023,7 +1023,7 @@
 
 }  // namespace
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
 // compositor. crbug.com/331924
 #define MAYBE_DragAll DISABLED_DragAll
@@ -1084,7 +1084,7 @@
 
 }  // namespace
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
 // compositor. crbug.com/331924
 #define MAYBE_DragAllToSeparateWindow DISABLED_DragAllToSeparateWindow
@@ -1157,7 +1157,7 @@
 
 }  // namespace
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
 // compositor. crbug.com/331924
 #define MAYBE_DragAllToSeparateWindowAndCancel \
@@ -1214,7 +1214,7 @@
   EXPECT_FALSE(browser2->window()->IsMaximized());
 }
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
 // compositor. crbug.com/331924
 #define MAYBE_DragDirectlyToSecondWindow DISABLED_DragDirectlyToSecondWindow
@@ -1269,7 +1269,7 @@
   EXPECT_FALSE(browser2->window()->IsMaximized());
 }
 
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
 // TODO(sky,sad): Disabled as it fails due to resize locks with a real
 // compositor. crbug.com/331924
 #define MAYBE_DragSingleTabToSeparateWindow \
diff --git a/chrome/browser/ui/views/tabs/window_finder_x11.cc b/chrome/browser/ui/views/tabs/window_finder_x11.cc
index eeca3e7..6d9e50e 100644
--- a/chrome/browser/ui/views/tabs/window_finder_x11.cc
+++ b/chrome/browser/ui/views/tabs/window_finder_x11.cc
@@ -4,12 +4,7 @@
 
 #include "chrome/browser/ui/views/tabs/window_finder.h"
 
-#include "base/debug/trace_event.h"
-#include "chrome/browser/ui/host_desktop.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_tree_host.h"
-#include "ui/base/x/x11_util.h"
-#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
+#include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
 
 #if defined(USE_ASH)
 aura::Window* GetLocalProcessWindowAtPointAsh(
@@ -17,166 +12,6 @@
     const std::set<aura::Window*>& ignore);
 #endif
 
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-// BaseWindowFinder
-//
-// Base class used to locate a window. A subclass need only override
-// ShouldStopIterating to determine when iteration should stop.
-class BaseWindowFinder : public ui::EnumerateWindowsDelegate {
- public:
-  explicit BaseWindowFinder(const std::set<aura::Window*>& ignore) {
-    std::set<aura::Window*>::iterator iter;
-    for (iter = ignore.begin(); iter != ignore.end(); iter++) {
-      XID xid = (*iter)->GetHost()->GetAcceleratedWidget();
-      ignore_.insert(xid);
-    }
-  }
-
-  virtual ~BaseWindowFinder() {}
-
- protected:
-  // Returns true if |window| is in the ignore list.
-  bool ShouldIgnoreWindow(XID window) {
-    return (ignore_.find(window) != ignore_.end());
-  }
-
-  // Returns true if iteration should stop, false otherwise.
-  virtual bool ShouldStopIterating(XID window) OVERRIDE {
-    return false;
-  }
-
- private:
-  std::set<XID> ignore_;
-
-  DISALLOW_COPY_AND_ASSIGN(BaseWindowFinder);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// TopMostFinder
-//
-// Helper class to determine if a particular point of a window is not obscured
-// by another window.
-class TopMostFinder : public BaseWindowFinder {
- public:
-  // Returns true if |window| is not obscured by another window at the
-  // location |screen_loc|, not including the windows in |ignore|.
-  static bool IsTopMostWindowAtPoint(XID window,
-                                     const gfx::Point& screen_loc,
-                                     const std::set<aura::Window*>& ignore) {
-    TopMostFinder finder(window, screen_loc, ignore);
-    return finder.is_top_most_;
-  }
-
- protected:
-  virtual bool ShouldStopIterating(XID window) OVERRIDE {
-    if (BaseWindowFinder::ShouldIgnoreWindow(window))
-      return false;
-
-    if (window == target_) {
-      // Window is topmost, stop iterating.
-      is_top_most_ = true;
-      return true;
-    }
-
-    if (!ui::IsWindowVisible(window)) {
-      // The window isn't visible, keep iterating.
-      return false;
-    }
-
-    // At this point we haven't found our target window, so this window is
-    // higher in the z-order than the target window.  If this window contains
-    // the point, then we can stop the search now because this window is
-    // obscuring the target window at this point.
-    return ui::WindowContainsPoint(window, screen_loc_);
-  }
-
- private:
-  TopMostFinder(XID window,
-                const gfx::Point& screen_loc,
-                const std::set<aura::Window*>& ignore)
-    : BaseWindowFinder(ignore),
-      target_(window),
-      screen_loc_(screen_loc),
-      is_top_most_(false) {
-    ui::EnumerateTopLevelWindows(this);
-  }
-
-  // The window we're looking for.
-  XID target_;
-
-  // Location of window to find.
-  gfx::Point screen_loc_;
-
-  // Is target_ the top most window? This is initially false but set to true
-  // in ShouldStopIterating if target_ is passed in.
-  bool is_top_most_;
-
-  DISALLOW_COPY_AND_ASSIGN(TopMostFinder);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// LocalProcessWindowFinder
-//
-// Helper class to determine if a particular point of a window from our process
-// is not obscured by another window.
-class LocalProcessWindowFinder : public BaseWindowFinder {
- public:
-  // Returns the XID from our process at screen_loc that is not obscured by
-  // another window. Returns 0 otherwise.
-  static XID GetProcessWindowAtPoint(const gfx::Point& screen_loc,
-                                     const std::set<aura::Window*>& ignore) {
-    LocalProcessWindowFinder finder(screen_loc, ignore);
-    if (finder.result_ &&
-        TopMostFinder::IsTopMostWindowAtPoint(finder.result_, screen_loc,
-                                              ignore)) {
-      return finder.result_;
-    }
-    return 0;
-  }
-
- protected:
-  virtual bool ShouldStopIterating(XID window) OVERRIDE {
-    if (BaseWindowFinder::ShouldIgnoreWindow(window))
-      return false;
-
-    // Check if this window is in our process.
-    if (!aura::WindowTreeHost::GetForAcceleratedWidget(window))
-      return false;
-
-    if (!ui::IsWindowVisible(window))
-      return false;
-
-    if (ui::WindowContainsPoint(window, screen_loc_)) {
-      result_ = window;
-      return true;
-    }
-
-    return false;
-  }
-
- private:
-  LocalProcessWindowFinder(const gfx::Point& screen_loc,
-                           const std::set<aura::Window*>& ignore)
-    : BaseWindowFinder(ignore),
-      screen_loc_(screen_loc),
-      result_(0) {
-    ui::EnumerateTopLevelWindows(this);
-  }
-
-  // Position of the mouse.
-  gfx::Point screen_loc_;
-
-  // The resulting window. This is initially null but set to true in
-  // ShouldStopIterating if an appropriate window is found.
-  XID result_;
-
-  DISALLOW_COPY_AND_ASSIGN(LocalProcessWindowFinder);
-};
-
-}  // namespace
-
 aura::Window* GetLocalProcessWindowAtPoint(
     chrome::HostDesktopType host_desktop_type,
     const gfx::Point& screen_point,
@@ -185,9 +20,9 @@
   if (host_desktop_type == chrome::HOST_DESKTOP_TYPE_ASH)
     return GetLocalProcessWindowAtPointAsh(screen_point, ignore);
 #endif
+
   // The X11 server is the canonical state of what the window stacking order
   // is.
-  XID xid =
-      LocalProcessWindowFinder::GetProcessWindowAtPoint(screen_point, ignore);
-  return views::DesktopWindowTreeHostX11::GetContentWindowForXID(xid);
+  views::X11TopmostWindowFinder finder;
+  return finder.FindLocalProcessWindowAt(screen_point, ignore);
 }
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc
index 2f03229..8751ad7 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -54,16 +54,19 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "ui/accessibility/ax_view_state.h"
+#include "ui/aura/window.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/theme_provider.h"
 #include "ui/base/window_open_disposition.h"
+#include "ui/compositor/layer.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/image/canvas_image_source.h"
+#include "ui/keyboard/keyboard_controller.h"
+#include "ui/native_theme/native_theme_aura.h"
 #include "ui/views/controls/menu/menu_listener.h"
 #include "ui/views/focus/view_storage.h"
 #include "ui/views/widget/tooltip_manager.h"
@@ -77,12 +80,6 @@
 #include "chrome/browser/ui/views/critical_notification_bubble_view.h"
 #endif
 
-#if defined(USE_AURA)
-#include "ui/aura/window.h"
-#include "ui/compositor/layer.h"
-#include "ui/native_theme/native_theme_aura.h"
-#endif
-
 #if !defined(OS_CHROMEOS)
 #include "chrome/browser/signin/signin_global_error_factory.h"
 #include "chrome/browser/sync/sync_global_error_factory.h"
@@ -406,12 +403,18 @@
   bool use_new_menu = false;
   bool supports_new_separators = false;
   // TODO: remove this.
-#if defined(USE_AURA) && !(defined(OS_LINUX) && !defined(OS_CHROMEOS))
+#if !defined(OS_LINUX) || defined(OS_CHROMEOS)
   supports_new_separators =
       GetNativeTheme() == ui::NativeThemeAura::instance();
   use_new_menu = supports_new_separators;
 #endif
 
+  if (keyboard::KeyboardController::GetInstance() &&
+      keyboard::KeyboardController::GetInstance()->keyboard_visible()) {
+    keyboard::KeyboardController::GetInstance()->HideKeyboard(
+        keyboard::KeyboardController::HIDE_REASON_AUTOMATIC);
+  }
+
   wrench_menu_.reset(new WrenchMenu(browser_, use_new_menu,
                                     supports_new_separators));
   wrench_menu_model_.reset(new WrenchMenuModel(this, browser_, use_new_menu));
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc
index ba6c6bd..2608055 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -261,8 +261,7 @@
   HandleLinkClicked(static_cast<LinkID>(source->id()));
 }
 
-void TranslateBubbleView::WebContentsDestroyed(
-    content::WebContents* web_contents) {
+void TranslateBubbleView::WebContentsDestroyed() {
   GetWidget()->CloseNow();
 }
 
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.h b/chrome/browser/ui/views/translate/translate_bubble_view.h
index 39d066b..91b38a3 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.h
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.h
@@ -70,8 +70,7 @@
   virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
 
   // content::WebContentsObserver method.
-  virtual void WebContentsDestroyed(content::WebContents* web_contents)
-      OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // Returns the current view state.
   TranslateBubbleModel::ViewState GetViewState() const;
diff --git a/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc b/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc
index 5f88794..d2c1198 100644
--- a/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc
+++ b/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc
@@ -10,7 +10,6 @@
 #include "components/web_modal/single_web_contents_dialog_manager.h"
 #include "components/web_modal/web_contents_modal_dialog_host.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/gfx/point.h"
 #include "ui/gfx/size.h"
 #include "ui/views/border.h"
diff --git a/chrome/browser/ui/views/web_dialog_view_browsertest.cc b/chrome/browser/ui/views/web_dialog_view_browsertest.cc
index 1e4fb26..e2c010d 100644
--- a/chrome/browser/ui/views/web_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/web_dialog_view_browsertest.cc
@@ -18,7 +18,6 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/views/controls/webview/web_dialog_view.h"
@@ -109,7 +108,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(web_contents != NULL);
   views::Widget::CreateWindowWithParent(
-      view, web_contents->GetView()->GetTopLevelNativeWindow());
+      view, web_contents->GetTopLevelNativeWindow());
   view->GetWidget()->Show();
 
   // TestWebDialogView should quit current message loop on size change.
diff --git a/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc b/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc
index 589bac9..a9c064a 100644
--- a/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc
+++ b/chrome/browser/ui/views/website_settings/permissions_bubble_view.cc
@@ -225,7 +225,6 @@
   customize_comboboxes_.clear();
   set_close_on_esc(false);
   set_close_on_deactivate(false);
-  set_move_with_anchor(true);
 
   SetLayoutManager(new views::BoxLayout(
       views::BoxLayout::kVertical, kBubbleOuterMargin, 0, kItemMajorSpacing));
diff --git a/chrome/browser/ui/website_settings/permission_bubble_manager.cc b/chrome/browser/ui/website_settings/permission_bubble_manager.cc
index 670a864..8816cee 100644
--- a/chrome/browser/ui/website_settings/permission_bubble_manager.cc
+++ b/chrome/browser/ui/website_settings/permission_bubble_manager.cc
@@ -5,9 +5,58 @@
 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
 
 #include "base/command_line.h"
+#include "base/metrics/user_metrics_action.h"
 #include "chrome/browser/ui/website_settings/permission_bubble_request.h"
 #include "chrome/common/chrome_switches.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/user_metrics.h"
+
+namespace {
+
+class CancelledRequest : public PermissionBubbleRequest {
+ public:
+  explicit CancelledRequest(PermissionBubbleRequest* cancelled)
+      : icon_(cancelled->GetIconID()),
+        message_text_(cancelled->GetMessageText()),
+        message_fragment_(cancelled->GetMessageTextFragment()),
+        user_gesture_(cancelled->HasUserGesture()),
+        hostname_(cancelled->GetRequestingHostname()) {}
+  virtual ~CancelledRequest() {}
+
+  virtual int GetIconID() const OVERRIDE {
+    return icon_;
+  }
+  virtual base::string16 GetMessageText() const OVERRIDE {
+    return message_text_;
+  }
+  virtual base::string16 GetMessageTextFragment() const OVERRIDE {
+    return message_fragment_;
+  }
+  virtual bool HasUserGesture() const OVERRIDE {
+    return user_gesture_;
+  }
+  virtual GURL GetRequestingHostname() const OVERRIDE {
+    return hostname_;
+  }
+
+  // These are all no-ops since the placeholder is non-forwarding.
+  virtual void PermissionGranted() OVERRIDE {}
+  virtual void PermissionDenied() OVERRIDE {}
+  virtual void Cancelled() OVERRIDE {}
+
+  virtual void RequestFinished() OVERRIDE {
+    delete this;
+  }
+
+ private:
+  int icon_;
+  base::string16 message_text_;
+  base::string16 message_fragment_;
+  bool user_gesture_;
+  GURL hostname_;
+};
+
+}  // namespace
 
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(PermissionBubbleManager);
 
@@ -44,6 +93,7 @@
 }
 
 void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) {
+  content::RecordAction(base::UserMetricsAction("PermissionBubbleRequest"));
   // TODO(gbillock): is there a race between an early request on a
   // newly-navigated page and the to-be-cleaned-up requests on the previous
   // page? We should maybe listen to DidStartNavigationToPendingEntry (and
@@ -79,6 +129,8 @@
   }
 
   if (bubble_showing_) {
+    content::RecordAction(
+        base::UserMetricsAction("PermissionBubbleRequestQueued"));
     queued_requests_.push_back(request);
     return;
   }
@@ -92,14 +144,54 @@
 }
 
 void PermissionBubbleManager::CancelRequest(PermissionBubbleRequest* request) {
-  // TODO(gbillock): implement
-  NOTREACHED();
+  // First look in the queued requests, where we can simply delete the request
+  // and go on.
+  std::vector<PermissionBubbleRequest*>::iterator requests_iter;
+  for (requests_iter = queued_requests_.begin();
+       requests_iter != queued_requests_.end();
+       requests_iter++) {
+    if (*requests_iter == request) {
+      (*requests_iter)->RequestFinished();
+      queued_requests_.erase(requests_iter);
+      return;
+    }
+  }
+
+  std::vector<bool>::iterator accepts_iter = accept_states_.begin();
+  for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin();
+       requests_iter != requests_.end();
+       requests_iter++, accepts_iter++) {
+    if (*requests_iter != request)
+      continue;
+
+    // We can simply erase the current entry in the request table if we aren't
+    // showing the dialog, or if we are showing it and it can accept the update.
+    bool can_erase = !bubble_showing_ ||
+                     !view_ || view_->CanAcceptRequestUpdate();
+    if (can_erase) {
+      (*requests_iter)->RequestFinished();
+      requests_.erase(requests_iter);
+      accept_states_.erase(accepts_iter);
+      ShowBubble();  // Will redraw the bubble if it is being shown.
+      return;
+    }
+
+    // Cancel the existing request and replace it with a dummy.
+    PermissionBubbleRequest* cancelled_request =
+        new CancelledRequest(*requests_iter);
+    (*requests_iter)->RequestFinished();
+    *requests_iter = cancelled_request;
+    return;
+  }
+
+  NOTREACHED();  // Callers should not cancel requests that are not pending.
 }
 
 void PermissionBubbleManager::SetView(PermissionBubbleView* view) {
   if (view == view_)
     return;
 
+  // Disengage from the existing view if there is one.
   if (view_ != NULL) {
     view_->SetDelegate(NULL);
     view_->Hide();
@@ -107,16 +199,14 @@
   }
 
   view_ = view;
-  if (view_)
-    view_->SetDelegate(this);
-  else
+  if (!view)
     return;
 
+  view->SetDelegate(this);
   ShowBubble();
 }
 
-void PermissionBubbleManager::DocumentOnLoadCompletedInMainFrame(
-    int32 page_id) {
+void PermissionBubbleManager::DocumentOnLoadCompletedInMainFrame() {
   request_url_has_loaded_ = true;
   // This is scheduled because while all calls to the browser have been
   // issued at DOMContentLoaded, they may be bouncing around in scheduled
@@ -132,25 +222,27 @@
 
 void PermissionBubbleManager::NavigationEntryCommitted(
     const content::LoadCommittedDetails& details) {
-  if (!request_url_.is_empty() &&
-      request_url_ != web_contents()->GetLastCommittedURL()) {
+  // No permissions requests pending.
+  if (request_url_.is_empty())
+    return;
+
+  // If we have navigated to a new url...
+  if (request_url_ != web_contents()->GetLastCommittedURL()) {
     // Kill off existing bubble and cancel any pending requests.
     CancelPendingQueue();
     FinalizeBubble();
   }
 }
 
-void PermissionBubbleManager::WebContentsDestroyed(
-    content::WebContents* web_contents) {
-  // If the web contents has been destroyed, do not attempt to notify
-  // the requests of any changes - simply close the bubble.
+void PermissionBubbleManager::WebContentsDestroyed() {
+  // If the web contents has been destroyed, treat the bubble as cancelled.
   CancelPendingQueue();
   FinalizeBubble();
 
   // The WebContents is going away; be aggressively paranoid and delete
   // ourselves lest other parts of the system attempt to add permission bubbles
   // or use us otherwise during the destruction.
-  web_contents->RemoveUserData(UserDataKey());
+  web_contents()->RemoveUserData(UserDataKey());
   // That was the equivalent of "delete this". This object is now destroyed;
   // returning from this function is the only safe thing to do.
 }
@@ -200,14 +292,21 @@
   FinalizeBubble();
 }
 
+// TODO(gbillock): find a better name for this method.
 void PermissionBubbleManager::ShowBubble() {
-  if (view_ && !bubble_showing_ && request_url_has_loaded_ &&
-      requests_.size()) {
-    // Note: this should appear above Show() for testing, since in that
-    // case we may do in-line calling of finalization.
-    bubble_showing_ = true;
-    view_->Show(requests_, accept_states_, customization_mode_);
-  }
+  if (!view_)
+    return;
+  if (requests_.empty())
+    return;
+  if (bubble_showing_)
+    return;
+  if (!request_url_has_loaded_)
+    return;
+
+  // Note: this should appear above Show() for testing, since in that
+  // case we may do in-line calling of finalization.
+  bubble_showing_ = true;
+  view_->Show(requests_, accept_states_, customization_mode_);
 }
 
 void PermissionBubbleManager::FinalizeBubble() {
diff --git a/chrome/browser/ui/website_settings/permission_bubble_manager.h b/chrome/browser/ui/website_settings/permission_bubble_manager.h
index bbf8e85..2e0eafc 100644
--- a/chrome/browser/ui/website_settings/permission_bubble_manager.h
+++ b/chrome/browser/ui/website_settings/permission_bubble_manager.h
@@ -48,7 +48,8 @@
   // removed and never shown. If the request is showing, it will continue to be
   // shown, but the user's action won't be reported back to the request object.
   // In some circumstances, we can remove the request from the bubble, and may
-  // do so. The caller may delete the request after calling this method.
+  // do so. The request will have RequestFinished executed on it if it is found,
+  // at which time the caller is free to delete the request.
   virtual void CancelRequest(PermissionBubbleRequest* request);
 
   // Sets the active view for the permission bubble. If this is NULL, it
@@ -67,14 +68,13 @@
 
   // TODO(leng): Finalize policy for permission requests with iFrames.
   // DocumentLoadedInFrame() might be needed as well.
-  virtual void DocumentOnLoadCompletedInMainFrame(int32 page_id) OVERRIDE;
+  virtual void DocumentOnLoadCompletedInMainFrame() OVERRIDE;
 
   // If a page on which permissions requests are pending is navigated,
   // they will be finalized as if canceled by the user.
   virtual void NavigationEntryCommitted(
       const content::LoadCommittedDetails& details) OVERRIDE;
-  virtual void WebContentsDestroyed(
-      content::WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // PermissionBubbleView::Delegate:
   virtual void ToggleAccept(int request_index, bool new_value) OVERRIDE;
@@ -101,8 +101,12 @@
 
   std::vector<PermissionBubbleRequest*> requests_;
   std::vector<PermissionBubbleRequest*> queued_requests_;
+
+  // URL of the main frame in the WebContents to which this manager is attached.
+  // TODO(gbillock): if there are iframes in the page, we need to deal with it.
   GURL request_url_;
   bool request_url_has_loaded_;
+
   std::vector<bool> accept_states_;
   bool customization_mode_;
 
diff --git a/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc b/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc
index b7bb2cd..0f43c4f 100644
--- a/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc
+++ b/chrome/browser/ui/website_settings/permission_bubble_manager_unittest.cc
@@ -17,11 +17,12 @@
 
 class MockView : public PermissionBubbleView {
  public:
-  MockView() : shown_(false), delegate_(NULL) {}
+  MockView() : shown_(false), can_accept_updates_(true), delegate_(NULL) {}
   virtual ~MockView() {}
 
   void Clear() {
     shown_ = false;
+    can_accept_updates_ = true;
     delegate_ = NULL;
     permission_requests_.clear();
     permission_states_.clear();
@@ -46,10 +47,11 @@
   }
 
   virtual bool CanAcceptRequestUpdate() OVERRIDE {
-    return true;
+    return can_accept_updates_;
   }
 
   bool shown_;
+  bool can_accept_updates_;
   Delegate* delegate_;
   std::vector<PermissionBubbleRequest*> permission_requests_;
   std::vector<bool> permission_states_;
@@ -85,8 +87,12 @@
     manager_->Accept();
   }
 
+  void Closing() {
+    manager_->Closing();
+  }
+
   void WaitForCoalescing() {
-    manager_->DocumentOnLoadCompletedInMainFrame(0);
+    manager_->DocumentOnLoadCompletedInMainFrame();
     base::MessageLoop::current()->RunUntilIdle();
   }
 
@@ -330,3 +336,58 @@
   EXPECT_TRUE(request1_.finished());
   EXPECT_TRUE(request2_.finished());
 }
+
+TEST_F(PermissionBubbleManagerTest, TestCancel) {
+  manager_->SetView(NULL);
+  manager_->AddRequest(&request1_);
+  WaitForCoalescing();
+
+  manager_->CancelRequest(&request1_);
+  EXPECT_TRUE(request1_.finished());
+  manager_->SetView(&view_);
+  EXPECT_FALSE(view_.shown_);
+
+  manager_->AddRequest(&request2_);
+  WaitForCoalescing();
+  EXPECT_TRUE(view_.shown_);
+}
+
+TEST_F(PermissionBubbleManagerTest, TestCancelWhileDialogShown) {
+  manager_->SetView(&view_);
+  manager_->AddRequest(&request1_);
+  WaitForCoalescing();
+
+  EXPECT_TRUE(view_.shown_);
+  EXPECT_FALSE(request1_.finished());
+  manager_->CancelRequest(&request1_);
+  EXPECT_TRUE(request1_.finished());
+}
+
+TEST_F(PermissionBubbleManagerTest, TestCancelWhileDialogShownNoUpdate) {
+  manager_->SetView(&view_);
+  view_.can_accept_updates_ = false;
+  manager_->AddRequest(&request1_);
+  WaitForCoalescing();
+
+  EXPECT_TRUE(view_.shown_);
+  EXPECT_FALSE(request1_.finished());
+  manager_->CancelRequest(&request1_);
+  EXPECT_TRUE(request1_.finished());
+  Closing();
+}
+
+TEST_F(PermissionBubbleManagerTest, TestCancelPendingRequest) {
+  manager_->SetView(&view_);
+  manager_->AddRequest(&request1_);
+  WaitForCoalescing();
+  manager_->AddRequest(&request2_);
+
+  EXPECT_TRUE(view_.shown_);
+  EXPECT_EQ(1u, view_.permission_requests_.size());
+  manager_->CancelRequest(&request2_);
+
+  EXPECT_TRUE(view_.shown_);
+  EXPECT_FALSE(request1_.finished());
+  EXPECT_TRUE(request2_.finished());
+}
+
diff --git a/chrome/browser/ui/website_settings/permission_bubble_view.h b/chrome/browser/ui/website_settings/permission_bubble_view.h
index 5835a47..a3229db 100644
--- a/chrome/browser/ui/website_settings/permission_bubble_view.h
+++ b/chrome/browser/ui/website_settings/permission_bubble_view.h
@@ -39,6 +39,8 @@
   // called with mostly-identical contents to the existing contents. This can
   // happen, for instance, if a new permission is requested and
   // CanAcceptRequestUpdate() is true.
+  // Important: the view must not store any of the request objects it receives
+  // in this call.
   virtual void Show(
       const std::vector<PermissionBubbleRequest*>& requests,
       const std::vector<bool>& accept_state,
diff --git a/chrome/browser/ui/webui/DEPS b/chrome/browser/ui/webui/DEPS
index 7d9e166..f3b4c54 100644
--- a/chrome/browser/ui/webui/DEPS
+++ b/chrome/browser/ui/webui/DEPS
@@ -11,6 +11,7 @@
   "+device/nfc",
   "+third_party/angle",       # For ANGLE version.
   "+third_party/zlib/zlib.h", # For compression level constants.
+  "+third_party/libaddressinput/chromium/cpp/include", # For i18n address input.
 
   # DOM Distiller.
   "+components/dom_distiller/core",
diff --git a/chrome/browser/ui/webui/OWNERS b/chrome/browser/ui/webui/OWNERS
index 648c511..7c0bb4a 100644
--- a/chrome/browser/ui/webui/OWNERS
+++ b/chrome/browser/ui/webui/OWNERS
@@ -8,6 +8,8 @@
 pam@chromium.org
 xiyuan@chromium.org
 
+per-file devtools_ui*=kaznacheev@chromium.org
+per-file devtools_ui*=pfeldman@chromium.org
 per-file inspect_ui*=kaznacheev@chromium.org
 per-file inspect_ui*=pfeldman@chromium.org
 per-file sync_setup_handler*=atwilson@chromium.org
diff --git a/chrome/browser/ui/webui/app_list/start_page_handler.cc b/chrome/browser/ui/webui/app_list/start_page_handler.cc
index 8987645..6047973 100644
--- a/chrome/browser/ui/webui/app_list/start_page_handler.cc
+++ b/chrome/browser/ui/webui/app_list/start_page_handler.cc
@@ -23,7 +23,6 @@
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/common/extension.h"
@@ -36,6 +35,10 @@
 
 namespace {
 
+#if defined(OS_CHROMEOS)
+const char kOldHotwordExtensionVersionString[] = "0.1.1.5014_0";
+#endif
+
 scoped_ptr<base::DictionaryValue> CreateAppInfo(
     const extensions::Extension* app) {
   scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
@@ -132,11 +135,25 @@
 
 #if defined(OS_CHROMEOS)
 void StartPageHandler::OnHotwordEnabledChanged() {
-  StartPageService* service = StartPageService::Get(
-      Profile::FromWebUI(web_ui()));
-  web_ui()->CallJavascriptFunction(
-      "appList.startPage.setHotwordEnabled",
-      base::FundamentalValue(service->HotwordEnabled()));
+  // If the hotword extension is new enough, we should use the new
+  // hotwordPrivate API to provide the feature.
+  // TODO(mukai): remove this after everything gets stable.
+  Profile* profile = Profile::FromWebUI(web_ui());
+  ExtensionService* extension_service =
+      extensions::ExtensionSystem::Get(profile)->extension_service();
+  if (!extension_service)
+    return;
+
+  const extensions::Extension* hotword_extension =
+      extension_service->GetExtensionById(
+          extension_misc::kHotwordExtensionId, false /* include_disabled */);
+  if (hotword_extension && hotword_extension->version()->CompareTo(
+          base::Version(kOldHotwordExtensionVersionString)) <= 0) {
+    StartPageService* service = StartPageService::Get(profile);
+    web_ui()->CallJavascriptFunction(
+        "appList.startPage.setHotwordEnabled",
+        base::FundamentalValue(service->HotwordEnabled()));
+  }
 }
 #endif
 
@@ -194,8 +211,8 @@
 
   AppListControllerDelegate* controller = AppListService::Get(
       chrome::GetHostDesktopTypeForNativeView(
-          web_ui()->GetWebContents()->GetView()->GetNativeView()))
-      ->GetControllerDelegate();
+          web_ui()->GetWebContents()->GetNativeView()))->
+              GetControllerDelegate();
   controller->ActivateApp(profile,
                           app,
                           AppListControllerDelegate::LAUNCH_FROM_APP_LIST,
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
index 6af9d52..d16820f 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
@@ -236,6 +236,9 @@
     case policy::EnrollmentStatus::STATUS_SUCCESS:
       ShowStep(kEnrollmentStepSuccess);
       return;
+    case policy::EnrollmentStatus::STATUS_NO_STATE_KEYS:
+      ShowError(IDS_ENTERPRISE_ENROLLMENT_STATUS_NO_STATE_KEYS, false);
+      return;
     case policy::EnrollmentStatus::STATUS_REGISTRATION_FAILED:
       // Some special cases for generating a nicer message that's more helpful.
       switch (status.client_status()) {
diff --git a/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc
index c5641ca..ee3c2fe 100644
--- a/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc
@@ -26,6 +26,7 @@
 #include "grit/browser_resources.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
+#include "grit/ui_strings.h"
 
 namespace {
 
@@ -173,7 +174,7 @@
   std::string extension_id =
       extension_service->component_loader()->Add(
           IDR_CONNECTIVITY_DIAGNOSTICS_MANIFEST,
-          base::FilePath(extension_misc::kConnectivityDiagnosticsPath));
+          base::FilePath(extension_misc::kConnectivityDiagnosticsKioskPath));
 
   const extensions::Extension* extension = extension_service->
       GetExtensionById(extension_id, true);
@@ -215,17 +216,23 @@
               &ErrorScreenHandler::HandleConfigureCerts);
   AddCallback("launchOobeGuestSession",
               &ErrorScreenHandler::HandleLaunchOobeGuestSession);
+  AddCallback("rollbackOkButtonClicked",
+              &ErrorScreenHandler::HandleRebootButtonClicked);
 }
 
 void ErrorScreenHandler::DeclareLocalizedValues(
     LocalizedValuesBuilder* builder) {
   builder->Add("loginErrorTitle", IDS_LOGIN_ERROR_TITLE);
+  builder->Add("rollbackErrorTitle", IDS_RESET_SCREEN_REVERT_ERROR);
   builder->Add("signinOfflineMessageBody", IDS_LOGIN_OFFLINE_MESSAGE);
   builder->Add("kioskOfflineMessageBody", IDS_KIOSK_OFFLINE_MESSAGE);
   builder->Add("kioskOnlineTitle", IDS_LOGIN_NETWORK_RESTORED_TITLE);
   builder->Add("kioskOnlineMessageBody", IDS_KIOSK_ONLINE_MESSAGE);
   builder->Add("autoEnrollmentOfflineMessageBody",
                IDS_LOGIN_AUTO_ENROLLMENT_OFFLINE_MESSAGE);
+  builder->AddF("rollbackErrorMessageBody",
+               IDS_RESET_SCREEN_REVERT_ERROR_EXPLANATION,
+               IDS_SHORT_PRODUCT_NAME);
   builder->Add("captivePortalTitle", IDS_LOGIN_MAYBE_CAPTIVE_PORTAL_TITLE);
   builder->Add("captivePortalMessage", IDS_LOGIN_MAYBE_CAPTIVE_PORTAL);
   builder->Add("captivePortalProxyMessage",
@@ -246,6 +253,7 @@
   builder->Add("diagnoseButton", IDS_DIAGNOSE_BUTTON);
   builder->Add("configureCertsButton", IDS_MANAGE_CERTIFICATES);
   builder->Add("continueButton", IDS_NETWORK_SELECTION_CONTINUE_BUTTON);
+  builder->Add("okButton", IDS_APP_OK);
 }
 
 void ErrorScreenHandler::Initialize() {
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index 567a07d..ffccadc 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -182,8 +182,11 @@
   builder->Add("createManagedUserFeatureName",
                IDS_CREATE_LOCALLY_MANAGED_USER_FEATURE_NAME);
 
-  // Strings used by no password warning dialog.
-  builder->Add("fatalErrorMessage", IDS_LOGIN_FATAL_ERROR_MESSAGE);
+  // Strings used by the fatal error dialog.
+  builder->Add("fatalErrorMessageGeneric", IDS_LOGIN_FATAL_ERROR_TEXT_GENERIC);
+  builder->Add("fatalErrorMessageInsecureURL",
+               IDS_LOGIN_FATAL_ERROR_TEXT_INSECURE_URL);
+  builder->Add("fatalErrorInstructions", IDS_LOGIN_FATAL_ERROR_INSTRUCTIONS);
   builder->Add("fatalErrorDismissButton", IDS_OK);
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc
index a2a26b5..567a8ad 100644
--- a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc
@@ -4,16 +4,58 @@
 
 #include "chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h"
 
+#include "base/bind.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
+#include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
 
 namespace {
 
 const char kJsScreenPath[] = "login.HIDDetectionScreen";
 
+// Variants of pairing state.
+const char kRemotePinCode[] = "bluetoothRemotePinCode";
+const char kRemotePasskey[] = "bluetoothRemotePasskey";
+
+// Possible ui-states for device-blocks.
+const char kSearchingState[] = "searching";
+const char kUSBConnectedState[] = "connected";
+const char kBTPairedState[] = "paired";
+const char kBTPairingState[] = "pairing";
+// Special state for notifications that don't switch ui-state, but add info.
+const char kBTUpdateState[] = "update";
+
+// Names of possible arguments used for ui update.
+const char kPincodeArgName[] = "pincode";
+const char kDeviceNameArgName[] = "name";
+const char kLabelArgName[] = "keyboard-label";
+
+// Standard length of pincode for pairing BT keyboards.
+const int kPincodeLength = 6;
+
+bool DeviceIsPointing(device::BluetoothDevice::DeviceType device_type) {
+  return device_type == device::BluetoothDevice::DEVICE_MOUSE ||
+         device_type == device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO ||
+         device_type == device::BluetoothDevice::DEVICE_TABLET;
+}
+
+bool DeviceIsPointing(const device::InputServiceLinux::InputDeviceInfo& info) {
+  return info.is_mouse || info.is_touchpad || info.is_touchscreen ||
+         info.is_tablet;
+}
+
+bool DeviceIsKeyboard(device::BluetoothDevice::DeviceType device_type) {
+  return device_type == device::BluetoothDevice::DEVICE_KEYBOARD ||
+         device_type == device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO;
+}
+
 }  // namespace
 
 namespace chromeos {
@@ -21,15 +63,35 @@
 HIDDetectionScreenHandler::HIDDetectionScreenHandler()
     : BaseScreenHandler(kJsScreenPath),
       delegate_(NULL),
-      show_on_init_(false) {
+      show_on_init_(false),
+      mouse_is_pairing_(false),
+      keyboard_is_pairing_(false),
+      switch_on_adapter_when_ready_(false),
+      skip_screen_if_devices_present_(true),
+      weak_ptr_factory_(this) {
 }
 
 HIDDetectionScreenHandler::~HIDDetectionScreenHandler() {
+  if (adapter_.get())
+    adapter_->RemoveObserver(this);
+  input_service_proxy_.RemoveObserver(this);
   if (delegate_)
     delegate_->OnActorDestroyed(this);
 }
 
-void HIDDetectionScreenHandler::PrepareToShow() {
+void HIDDetectionScreenHandler::OnStartDiscoverySession(
+    scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
+  VLOG(1) << "BT Discovery session started";
+  discovery_session_ = discovery_session.Pass();
+  UpdateDevices();
+}
+
+void HIDDetectionScreenHandler::SetPoweredError() {
+  LOG(ERROR) << "Failed to power BT adapter";
+}
+
+void HIDDetectionScreenHandler::FindDevicesError() {
+  VLOG(1) << "Failed to start Bluetooth discovery.";
 }
 
 void HIDDetectionScreenHandler::Show() {
@@ -37,10 +99,16 @@
     show_on_init_ = true;
     return;
   }
+  input_service_proxy_.AddObserver(this);
+  skip_screen_if_devices_present_ = true;
+  UpdateDevices();
   ShowScreen(OobeUI::kScreenHIDDetection, NULL);
 }
 
 void HIDDetectionScreenHandler::Hide() {
+  if (adapter_.get())
+    adapter_->RemoveObserver(this);
+  input_service_proxy_.RemoveObserver(this);
 }
 
 void HIDDetectionScreenHandler::SetDelegate(Delegate* delegate) {
@@ -52,12 +120,29 @@
 void HIDDetectionScreenHandler::DeclareLocalizedValues(
     LocalizedValuesBuilder* builder) {
   builder->Add("hidDetectionContinue", IDS_HID_DETECTION_CONTINUE_BUTTON);
+  builder->Add("hidDetectionInvitation", IDS_HID_DETECTION_INVITATION_TEXT);
+  builder->Add("hidDetectionPrerequisites",
+      IDS_HID_DETECTION_PRECONDITION_TEXT);
+  builder->Add("hidDetectionMouseSearching", IDS_HID_DETECTION_SEARCHING_MOUSE);
+  builder->Add("hidDetectionKeyboardSearching",
+      IDS_HID_DETECTION_SEARCHING_KEYBOARD);
+  builder->Add("hidDetectionUSBMouseConnected",
+      IDS_HID_DETECTION_CONNECTED_USB_MOUSE);
+  builder->Add("hidDetectionUSBKeyboardConnected",
+      IDS_HID_DETECTION_CONNECTED_USB_KEYBOARD);
+  builder->Add("hidDetectionBTMousePaired",
+      IDS_HID_DETECTION_PAIRED_BLUETOOTH_MOUSE);
+  builder->Add("hidDetectionBTEnterKey", IDS_HID_DETECTION_BLUETOOTH_ENTER_KEY);
 }
 
 void HIDDetectionScreenHandler::Initialize() {
   if (!page_is_ready() || !delegate_)
     return;
 
+  device::BluetoothAdapterFactory::GetAdapter(
+      base::Bind(&HIDDetectionScreenHandler::InitializeAdapter,
+                 weak_ptr_factory_.GetWeakPtr()));
+
   if (show_on_init_) {
     Show();
     show_on_init_ = false;
@@ -74,4 +159,343 @@
     delegate_->OnExit();
 }
 
+void HIDDetectionScreenHandler::InitializeAdapter(
+    scoped_refptr<device::BluetoothAdapter> adapter) {
+  adapter_ = adapter;
+  CHECK(adapter_.get());
+
+  adapter_->AddObserver(this);
+  UpdateDevices();
+}
+
+void HIDDetectionScreenHandler::StartBTDiscoverySession() {
+  adapter_->StartDiscoverySession(
+      base::Bind(&HIDDetectionScreenHandler::OnStartDiscoverySession,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&HIDDetectionScreenHandler::FindDevicesError,
+                 weak_ptr_factory_.GetWeakPtr()));
+}
+
+void HIDDetectionScreenHandler::RequestPinCode(
+    device::BluetoothDevice* device) {
+  VLOG(1) << "RequestPinCode id = " << device->GetDeviceID()
+          << " name = " << device->GetName();
+  device->CancelPairing();
+}
+
+void HIDDetectionScreenHandler::RequestPasskey(
+    device::BluetoothDevice* device) {
+  VLOG(1) << "RequestPassKey id = " << device->GetDeviceID()
+          << " name = " << device->GetName();
+  device->CancelPairing();
+}
+
+void HIDDetectionScreenHandler::DisplayPinCode(device::BluetoothDevice* device,
+                                               const std::string& pincode) {
+  VLOG(1) << "DisplayPinCode id = " << device->GetDeviceID()
+          << " name = " << device->GetName();
+  base::DictionaryValue params;
+  params.SetString("state", kBTPairingState);
+  params.SetString("pairing-state", kRemotePinCode);
+  params.SetString("pincode", pincode);
+  params.SetString(kDeviceNameArgName, device->GetName());
+  SendKeyboardDeviceNotification(&params);
+}
+
+void HIDDetectionScreenHandler::DisplayPasskey(
+    device::BluetoothDevice* device, uint32 passkey) {
+  VLOG(1) << "DisplayPassKey id = " << device->GetDeviceID()
+          << " name = " << device->GetName();
+  base::DictionaryValue params;
+  params.SetString("state", kBTPairingState);
+  params.SetString("pairing-state", kRemotePasskey);
+  params.SetInteger("passkey", passkey);
+  std::string pincode = base::UintToString(passkey);
+  pincode = std::string(kPincodeLength - pincode.length(), '0').append(pincode);
+  params.SetString("pincode", pincode);
+  params.SetString(kDeviceNameArgName, device->GetName());
+  SendKeyboardDeviceNotification(&params);
+}
+
+void HIDDetectionScreenHandler::KeysEntered(
+    device::BluetoothDevice* device, uint32 entered) {
+  VLOG(1) << "Keys entered";
+  base::DictionaryValue params;
+  params.SetString("state", kBTUpdateState);
+  params.SetInteger("keysEntered", entered);
+  SendKeyboardDeviceNotification(&params);
+}
+
+void HIDDetectionScreenHandler::ConfirmPasskey(
+    device::BluetoothDevice* device, uint32 passkey) {
+  VLOG(1) << "Confirm Passkey";
+  device->CancelPairing();
+}
+
+void HIDDetectionScreenHandler::AuthorizePairing(
+    device::BluetoothDevice* device) {
+  // There is never any circumstance where this will be called, since the
+  // HID detection screen  handler will only be used for outgoing pairing
+  // requests, but play it safe.
+  VLOG(1) << "Authorize pairing";
+  device->ConfirmPairing();
+}
+
+void HIDDetectionScreenHandler::AdapterPresentChanged(
+    device::BluetoothAdapter* adapter, bool present) {
+  if (present && switch_on_adapter_when_ready_) {
+    adapter_->SetPowered(
+        true,
+        base::Bind(&HIDDetectionScreenHandler::StartBTDiscoverySession,
+                   weak_ptr_factory_.GetWeakPtr()),
+        base::Bind(&HIDDetectionScreenHandler::SetPoweredError,
+                   weak_ptr_factory_.GetWeakPtr()));
+  }
+}
+
+void HIDDetectionScreenHandler::TryPairingAsPointingDevice(
+    device::BluetoothDevice* device) {
+  if (pointing_device_id_.empty() &&
+      DeviceIsPointing(device->GetDeviceType()) &&
+      device->IsPairable() && !device->IsPaired() && !mouse_is_pairing_) {
+    ConnectBTDevice(device);
+  }
+}
+
+void HIDDetectionScreenHandler::TryPairingAsKeyboardDevice(
+    device::BluetoothDevice* device) {
+  if (keyboard_device_id_.empty() &&
+      DeviceIsKeyboard(device->GetDeviceType()) &&
+      device->IsPairable() && !device->IsPaired() && !keyboard_is_pairing_) {
+    ConnectBTDevice(device);
+  }
+}
+
+void HIDDetectionScreenHandler::DeviceAdded(
+    device::BluetoothAdapter* adapter, device::BluetoothDevice* device) {
+  VLOG(1) << "BT input device added id = " << device->GetDeviceID() <<
+      " name = " << device->GetName();
+  TryPairingAsPointingDevice(device);
+  TryPairingAsKeyboardDevice(device);
+}
+
+void HIDDetectionScreenHandler::DeviceChanged(
+    device::BluetoothAdapter* adapter, device::BluetoothDevice* device) {
+  VLOG(1) << "BT device changed id = " << device->GetDeviceID() << " name = " <<
+      device->GetName();
+  TryPairingAsPointingDevice(device);
+  TryPairingAsKeyboardDevice(device);
+}
+
+void HIDDetectionScreenHandler::DeviceRemoved(
+    device::BluetoothAdapter* adapter, device::BluetoothDevice* device) {
+  VLOG(1) << "BT device removed id = " << device->GetDeviceID() << " name = " <<
+      device->GetName();
+}
+
+void HIDDetectionScreenHandler::OnInputDeviceAdded(
+    const InputDeviceInfo& info) {
+  VLOG(1) << "Input device added id = " << info.id << " name = " << info.name;
+  // TODO(merkulova): deal with all available device types, e.g. joystick.
+  if (!keyboard_device_id_.empty() && !pointing_device_id_.empty())
+    return;
+
+  if (pointing_device_id_.empty() && DeviceIsPointing(info)) {
+    pointing_device_id_ = info.id;
+    pointing_device_name_ = info.name;
+    pointing_device_connect_type_ = info.type;
+    SendPointingDeviceNotification();
+  }
+  if (keyboard_device_id_.empty() && info.is_keyboard) {
+    keyboard_device_id_ = info.id;
+    keyboard_device_name_ = info.name;
+    keyboard_device_connect_type_ = info.type;
+    SendKeyboardDeviceNotification(NULL);
+  }
+}
+
+void HIDDetectionScreenHandler::OnInputDeviceRemoved(const std::string& id) {
+  if (id == keyboard_device_id_) {
+    keyboard_device_id_.clear();
+    keyboard_device_name_.clear();
+    keyboard_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN;
+    SendKeyboardDeviceNotification(NULL);
+    UpdateDevices();
+  } else if (id == pointing_device_id_) {
+    pointing_device_id_.clear();
+    pointing_device_name_.clear();
+    pointing_device_connect_type_ = InputDeviceInfo::TYPE_UNKNOWN;
+    SendPointingDeviceNotification();
+    UpdateDevices();
+  }
+}
+
+void HIDDetectionScreenHandler::UpdateDevices() {
+  input_service_proxy_.GetDevices(
+      base::Bind(&HIDDetectionScreenHandler::OnGetInputDevicesList,
+                 base::Unretained(this)));
+}
+
+void HIDDetectionScreenHandler::UpdateBTDevices() {
+  if (!adapter_ || !adapter_->IsPresent() || !adapter_->IsPowered())
+    return;
+
+  // If no connected devices found as pointing device and keyboard, we try to
+  // connect some type-suitable active bluetooth device.
+  std::vector<device::BluetoothDevice*> bt_devices = adapter_->GetDevices();
+  for (std::vector<device::BluetoothDevice*>::const_iterator it =
+           bt_devices.begin();
+       it != bt_devices.end() &&
+           (keyboard_device_id_.empty() || pointing_device_id_.empty());
+       ++it) {
+    TryPairingAsPointingDevice(*it);
+    TryPairingAsKeyboardDevice(*it);
+  }
+}
+
+void HIDDetectionScreenHandler::OnGetInputDevicesList(
+    const std::vector<InputDeviceInfo>& devices) {
+  for (std::vector<InputDeviceInfo>::const_iterator it = devices.begin();
+       it != devices.end() &&
+       (pointing_device_id_.empty() || keyboard_device_id_.empty());
+       ++it) {
+    if (pointing_device_id_.empty() && DeviceIsPointing(*it)) {
+      pointing_device_id_ = it->id;
+      pointing_device_name_ = it->name;
+      pointing_device_connect_type_ = it->type;
+      SendPointingDeviceNotification();
+    }
+    if (keyboard_device_id_.empty() && it->is_keyboard) {
+      keyboard_device_id_ = it->id;
+      keyboard_device_name_ = it->name;
+      keyboard_device_connect_type_ = it->type;
+      SendKeyboardDeviceNotification(NULL);
+    }
+  }
+  // Skip screen if both devices are present and skip was requested.
+  if (!pointing_device_id_.empty() &&
+      !keyboard_device_id_.empty() &&
+      skip_screen_if_devices_present_) {
+    HandleOnContinue();
+  }
+  // Skip requested only once on dialog show.
+  skip_screen_if_devices_present_ = false;
+  if ((pointing_device_id_.empty() || keyboard_device_id_.empty()) &&
+      adapter_) {
+    if (!adapter_->IsPresent()) {
+      // Switch on BT adapter later when it's available.
+      switch_on_adapter_when_ready_ = true;
+    } else if (!adapter_->IsPowered()) {
+      adapter_->SetPowered(
+          true,
+          base::Bind(&HIDDetectionScreenHandler::StartBTDiscoverySession,
+                     weak_ptr_factory_.GetWeakPtr()),
+          base::Bind(&HIDDetectionScreenHandler::SetPoweredError,
+                     weak_ptr_factory_.GetWeakPtr()));
+    } else {
+      UpdateBTDevices();
+    }
+  }
+}
+
+void HIDDetectionScreenHandler::ConnectBTDevice(
+    device::BluetoothDevice* device) {
+  if (!device->IsPairable() || device->IsPaired())
+    return;
+  device::BluetoothDevice::DeviceType device_type = device->GetDeviceType();
+
+  if (device_type == device::BluetoothDevice::DEVICE_MOUSE ||
+      device_type == device::BluetoothDevice::DEVICE_TABLET) {
+    if (mouse_is_pairing_)
+      return;
+    mouse_is_pairing_ = true;
+  } else if (device_type == device::BluetoothDevice::DEVICE_KEYBOARD) {
+    if (keyboard_is_pairing_)
+      return;
+    keyboard_is_pairing_ = true;
+  } else if (device_type ==
+      device::BluetoothDevice::DEVICE_KEYBOARD_MOUSE_COMBO) {
+    if (mouse_is_pairing_ || keyboard_is_pairing_)
+      return;
+    mouse_is_pairing_ = true;
+    keyboard_is_pairing_ = true;
+  }
+  device->Connect(this,
+            base::Bind(&HIDDetectionScreenHandler::BTConnected,
+                       weak_ptr_factory_.GetWeakPtr(), device_type),
+            base::Bind(&HIDDetectionScreenHandler::BTConnectError,
+                       weak_ptr_factory_.GetWeakPtr(),
+                       device->GetAddress(), device_type));
+}
+
+void HIDDetectionScreenHandler::BTConnected(
+    device::BluetoothDevice::DeviceType device_type) {
+  if (DeviceIsPointing(device_type))
+    mouse_is_pairing_ = false;
+  if (DeviceIsKeyboard(device_type))
+    keyboard_is_pairing_ = false;
+}
+
+void HIDDetectionScreenHandler::BTConnectError(
+    const std::string& address,
+    device::BluetoothDevice::DeviceType device_type,
+    device::BluetoothDevice::ConnectErrorCode error_code) {
+  LOG(WARNING) << "BTConnectError while connecting " << address
+               << " error code = " << error_code;
+  if (DeviceIsPointing(device_type))
+    mouse_is_pairing_ = false;
+  if (DeviceIsKeyboard(device_type))
+    keyboard_is_pairing_ = false;
+
+  if (pointing_device_id_.empty() || keyboard_device_id_.empty())
+    UpdateDevices();
+}
+
+
+void HIDDetectionScreenHandler::SendPointingDeviceNotification() {
+  std::string state;
+  if (pointing_device_id_.empty())
+    state = kSearchingState;
+  else if (pointing_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH)
+    state = kBTPairedState;
+  else
+    state = kUSBConnectedState;
+  CallJS("setPointingDeviceState", state);
+}
+
+void HIDDetectionScreenHandler::SendKeyboardDeviceNotification(
+    base::DictionaryValue* params) {
+  base::DictionaryValue state_info;
+  if (params)
+    state_info.MergeDictionary(params);
+
+  base::string16 device_name;
+  if (!state_info.GetString(kDeviceNameArgName, &device_name)) {
+    device_name = l10n_util::GetStringUTF16(
+        IDS_HID_DETECTION_DEFAULT_KEYBOARD_NAME);
+  }
+
+  if (keyboard_device_id_.empty()) {
+    if (!state_info.HasKey("state")) {
+      state_info.SetString("state", kSearchingState);
+    } else if (state_info.HasKey(kPincodeArgName)) {
+      state_info.SetString(
+          kLabelArgName,
+          l10n_util::GetStringFUTF16(
+              IDS_HID_DETECTION_BLUETOOTH_REMOTE_PIN_CODE_REQUEST,
+              device_name));
+    }
+  } else if (keyboard_device_connect_type_ == InputDeviceInfo::TYPE_BLUETOOTH) {
+    state_info.SetString("state", kBTPairedState);
+    state_info.SetString(
+        kLabelArgName,
+        l10n_util::GetStringFUTF16(
+            IDS_HID_DETECTION_PAIRED_BLUETOOTH_KEYBOARD,
+            base::UTF8ToUTF16(keyboard_device_name_)));
+  } else {
+    state_info.SetString("state", kUSBConnectedState);
+  }
+  CallJS("setKeyboardDeviceState", state_info);
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h
index e3c8ad8..f8ff396 100644
--- a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.h
@@ -5,9 +5,20 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_HID_DETECTION_SCREEN_HANDLER_H_
 #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_HID_DETECTION_SCREEN_HANDLER_H_
 
+#include <string>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/device/input_service_proxy.h"
 #include "chrome/browser/chromeos/login/screens/hid_detection_screen_actor.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 #include "content/public/browser/web_ui.h"
+#include "device/bluetooth/bluetooth_adapter.h"
+#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/bluetooth_discovery_session.h"
 
 namespace base {
 class DictionaryValue;
@@ -16,14 +27,19 @@
 namespace chromeos {
 
 // WebUI implementation of HIDDetectionScreenActor.
-class HIDDetectionScreenHandler : public HIDDetectionScreenActor,
-                                  public BaseScreenHandler {
+class HIDDetectionScreenHandler
+    : public HIDDetectionScreenActor,
+      public BaseScreenHandler,
+      public device::BluetoothAdapter::Observer,
+      public device::BluetoothDevice::PairingDelegate,
+      public InputServiceProxy::Observer {
  public:
+  typedef device::InputServiceLinux::InputDeviceInfo InputDeviceInfo;
+
   HIDDetectionScreenHandler();
   virtual ~HIDDetectionScreenHandler();
 
   // HIDDetectionScreenActor implementation:
-  virtual void PrepareToShow() OVERRIDE;
   virtual void Show() OVERRIDE;
   virtual void Hide() OVERRIDE;
   virtual void SetDelegate(Delegate* delegate) OVERRIDE;
@@ -35,7 +51,59 @@
   // WebUIMessageHandler implementation:
   virtual void RegisterMessages() OVERRIDE;
 
+  // device::BluetoothDevice::PairingDelegate implementation:
+  virtual void RequestPinCode(device::BluetoothDevice* device) OVERRIDE;
+  virtual void RequestPasskey(device::BluetoothDevice* device) OVERRIDE;
+  virtual void DisplayPinCode(device::BluetoothDevice* device,
+                              const std::string& pincode) OVERRIDE;
+  virtual void DisplayPasskey(
+      device::BluetoothDevice* device, uint32 passkey) OVERRIDE;
+  virtual void KeysEntered(device::BluetoothDevice* device,
+                           uint32 entered) OVERRIDE;
+  virtual void ConfirmPasskey(
+      device::BluetoothDevice* device, uint32 passkey) OVERRIDE;
+  virtual void AuthorizePairing(device::BluetoothDevice* device) OVERRIDE;
+
+  // device::BluetoothAdapter::Observer implementation.
+  virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter,
+                                     bool present) OVERRIDE;
+  virtual void DeviceAdded(device::BluetoothAdapter* adapter,
+                           device::BluetoothDevice* device) OVERRIDE;
+  virtual void DeviceChanged(device::BluetoothAdapter* adapter,
+                             device::BluetoothDevice* device) OVERRIDE;
+  virtual void DeviceRemoved(device::BluetoothAdapter* adapter,
+                             device::BluetoothDevice* device) OVERRIDE;
+
+  // InputServiceProxy::Observer implementation.
+  virtual void OnInputDeviceAdded(const InputDeviceInfo& info) OVERRIDE;
+  virtual void OnInputDeviceRemoved(const std::string& id) OVERRIDE;
+
  private:
+  void InitializeAdapter(scoped_refptr<device::BluetoothAdapter> adapter);
+
+  // Sends a notification to the Web UI of the status of available Bluetooth/USB
+  // pointing device.
+  void SendPointingDeviceNotification();
+
+  // Sends a notification to the Web UI of the status of available Bluetooth/USB
+  // keyboard device.
+  void SendKeyboardDeviceNotification(base::DictionaryValue* params);
+
+  void OnGetInputDevicesList(const std::vector<InputDeviceInfo>& devices);
+
+  void StartBTDiscoverySession();
+
+  // Called by device::BluetoothDevice on a successful pairing and connection
+  // to a device.
+  void BTConnected(device::BluetoothDevice::DeviceType device_type);
+
+  // Called by device::BluetoothDevice in response to a failure to
+  // connect to the device with bluetooth address |address| due to an error
+  // encoded in |error_code|.
+  void BTConnectError(const std::string& address,
+                      device::BluetoothDevice::DeviceType device_type,
+                      device::BluetoothDevice::ConnectErrorCode error_code);
+
   // JS messages handlers.
   void HandleOnContinue();
 
@@ -44,6 +112,68 @@
   // Keeps whether screen should be shown right after initialization.
   bool show_on_init_;
 
+  // Displays in the UI a connecting to the device |device| message.
+  void DeviceConnecting(device::BluetoothDevice* device);
+
+  // Called by device::BluetoothAdapter in response to a successful request
+  // to initiate a discovery session.
+  void OnStartDiscoverySession(
+      scoped_ptr<device::BluetoothDiscoverySession> discovery_session);
+
+  // Called by device::BluetoothAdapter in response to a failure to
+  // initiate a discovery session.
+  void FindDevicesError();
+
+  // Called by device::BluetoothAdapter in response to a failure to
+  // power BT adapter.
+  void SetPoweredError();
+
+  // Called for revision of active devices. If current-placement is available
+  // for mouse or keyboard device, sets one of active devices as current or
+  // tries to connect some BT device if no appropriate devices are connected.
+  void UpdateDevices();
+
+  // Tries to connect some BT devices if no type-appropriate devices are
+  // connected.
+  void UpdateBTDevices();
+
+  // Tries to connect given BT device.
+  void ConnectBTDevice(device::BluetoothDevice* device);
+
+  // Tries to connect given BT device as pointing one.
+  void TryPairingAsPointingDevice(device::BluetoothDevice* device);
+
+  // Tries to connect given BT device as keyboard.
+  void TryPairingAsKeyboardDevice(device::BluetoothDevice* device);
+
+  // Default bluetooth adapter, used for all operations.
+  scoped_refptr<device::BluetoothAdapter> adapter_;
+
+  InputServiceProxy input_service_proxy_;
+
+  // The current device discovery session. Only one active discovery session is
+  // kept at a time and the instance that |discovery_session_| points to gets
+  // replaced by a new one when a new discovery session is initiated.
+  scoped_ptr<device::BluetoothDiscoverySession> discovery_session_;
+
+  // Current pointing device, if any.
+  std::string pointing_device_name_;
+  std::string pointing_device_id_;
+  bool mouse_is_pairing_;
+  InputDeviceInfo::Type pointing_device_connect_type_;
+
+  // Current keyboard device, if any.
+  std::string keyboard_device_name_;
+  std::string keyboard_device_id_;
+  bool keyboard_is_pairing_;
+  InputDeviceInfo::Type keyboard_device_connect_type_;
+
+  bool switch_on_adapter_when_ready_;
+
+  bool skip_screen_if_devices_present_;
+
+  base::WeakPtrFactory<HIDDetectionScreenHandler> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(HIDDetectionScreenHandler);
 };
 
diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
index f10494b..d89958a 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
@@ -148,6 +148,13 @@
     HandleOnLanguageChanged(startup_manifest->initial_locale_default());
   }
 
+  PrefService* prefs = g_browser_process->local_state();
+  if (prefs->GetBoolean(prefs::kFactoryResetRequested)) {
+    if (core_oobe_actor_)
+      core_oobe_actor_->ShowDeviceResetScreen();
+    return;
+  }
+
   // Make sure all our network technologies are turned on. On OOBE, the user
   // should be able to select any of the available networks on the device.
   NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
index 191cc69..93423ad 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -132,27 +132,28 @@
 }  // namespace
 
 // static
-const char OobeUI::kScreenOobeNetwork[]     = "connect";
-const char OobeUI::kScreenOobeEula[]        = "eula";
-const char OobeUI::kScreenOobeUpdate[]      = "update";
-const char OobeUI::kScreenOobeEnrollment[]  = "oauth-enrollment";
-const char OobeUI::kScreenOobeReset[]       = "reset";
-const char OobeUI::kScreenGaiaSignin[]      = "gaia-signin";
-const char OobeUI::kScreenAccountPicker[]   = "account-picker";
-const char OobeUI::kScreenKioskAutolaunch[] = "autolaunch";
-const char OobeUI::kScreenKioskEnable[]     = "kiosk-enable";
-const char OobeUI::kScreenErrorMessage[]    = "error-message";
-const char OobeUI::kScreenUserImagePicker[] = "user-image";
-const char OobeUI::kScreenTpmError[]        = "tpm-error-message";
-const char OobeUI::kScreenPasswordChanged[] = "password-changed";
+const char OobeUI::kScreenOobeHIDDetection[] = "hid-detection";
+const char OobeUI::kScreenOobeNetwork[]      = "connect";
+const char OobeUI::kScreenOobeEula[]         = "eula";
+const char OobeUI::kScreenOobeUpdate[]       = "update";
+const char OobeUI::kScreenOobeEnrollment[]   = "oauth-enrollment";
+const char OobeUI::kScreenOobeReset[]        = "reset";
+const char OobeUI::kScreenGaiaSignin[]       = "gaia-signin";
+const char OobeUI::kScreenAccountPicker[]    = "account-picker";
+const char OobeUI::kScreenKioskAutolaunch[]  = "autolaunch";
+const char OobeUI::kScreenKioskEnable[]      = "kiosk-enable";
+const char OobeUI::kScreenErrorMessage[]     = "error-message";
+const char OobeUI::kScreenUserImagePicker[]  = "user-image";
+const char OobeUI::kScreenTpmError[]         = "tpm-error-message";
+const char OobeUI::kScreenPasswordChanged[]  = "password-changed";
 const char OobeUI::kScreenManagedUserCreationFlow[]
-                                            = "managed-user-creation";
-const char OobeUI::kScreenTermsOfService[]  = "terms-of-service";
-const char OobeUI::kScreenWrongHWID[]       = "wrong-hwid";
-const char OobeUI::kScreenHIDDetection[]    = "hid-detection";
-const char OobeUI::kScreenAppLaunchSplash[] = "app-launch-splash";
-const char OobeUI::kScreenConfirmPassword[] = "confirm-password";
-const char OobeUI::kScreenFatalError[]      = "fatal-error";
+                                             = "managed-user-creation";
+const char OobeUI::kScreenTermsOfService[]   = "terms-of-service";
+const char OobeUI::kScreenWrongHWID[]        = "wrong-hwid";
+const char OobeUI::kScreenHIDDetection[]     = "hid-detection";
+const char OobeUI::kScreenAppLaunchSplash[]  = "app-launch-splash";
+const char OobeUI::kScreenConfirmPassword[]  = "confirm-password";
+const char OobeUI::kScreenFatalError[]       = "fatal-error";
 
 OobeUI::OobeUI(content::WebUI* web_ui, const GURL& url)
     : WebUIController(web_ui),
@@ -399,6 +400,7 @@
 
 void OobeUI::InitializeScreenMaps() {
   screen_names_.resize(SCREEN_UNKNOWN);
+  screen_names_[SCREEN_OOBE_HID_DETECTION] = kScreenOobeHIDDetection;
   screen_names_[SCREEN_OOBE_NETWORK] = kScreenOobeNetwork;
   screen_names_[SCREEN_OOBE_EULA] = kScreenOobeEula;
   screen_names_[SCREEN_OOBE_UPDATE] = kScreenOobeUpdate;
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
index 9659ac9..bec24da 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
@@ -52,6 +52,7 @@
   };
 
   // JS oobe/login screens names.
+  static const char kScreenOobeHIDDetection[];
   static const char kScreenOobeNetwork[];
   static const char kScreenOobeEula[];
   static const char kScreenOobeUpdate[];
diff --git a/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc
index bbb52da..4ae16a7 100644
--- a/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/login/help_app_launcher.h"
 #include "chrome/browser/chromeos/reset/metrics.h"
+#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/chromeos_switches.h"
@@ -23,6 +24,7 @@
 #include "grit/browser_resources.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
 
 namespace {
 
@@ -31,6 +33,8 @@
 // Reset screen id.
 const char kResetScreen[] = "reset";
 
+const int kErrorUIStateRollback = 7;
+
 }  // namespace
 
 namespace chromeos {
@@ -42,12 +46,13 @@
       restart_required_(true),
       reboot_was_requested_(false),
       rollback_available_(false),
-      weak_factory_(this) {
+      weak_ptr_factory_(this) {
 }
 
 ResetScreenHandler::~ResetScreenHandler() {
   if (delegate_)
     delegate_->OnActorDestroyed(this);
+  DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
 }
 
 void ResetScreenHandler::PrepareToShow() {
@@ -104,11 +109,12 @@
   } else {
     chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->
         CanRollbackCheck(base::Bind(&ResetScreenHandler::OnRollbackCheck,
-        weak_factory_.GetWeakPtr()));
+        weak_ptr_factory_.GetWeakPtr()));
   }
 }
 
 void ResetScreenHandler::Hide() {
+  DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
 }
 
 void ResetScreenHandler::SetDelegate(Delegate* delegate) {
@@ -128,6 +134,12 @@
   builder->AddF("resetRollbackOption",
                 IDS_RESET_SCREEN_ROLLBACK_OPTION,
                 IDS_SHORT_PRODUCT_NAME);
+  builder->AddF("resetRevertPromise",
+               IDS_RESET_SCREEN_PREPARING_REVERT_PROMISE,
+               IDS_SHORT_PRODUCT_NAME);
+  builder->AddF("resetRevertSpinnerMessage",
+                IDS_RESET_SCREEN_PREPARING_REVERT_SPINNER_MESSAGE,
+                IDS_SHORT_PRODUCT_NAME);
 
   // Different variants of the same UI elements for all dialog cases.
   builder->Add("resetButtonReset", IDS_RESET_SCREEN_RESET);
@@ -184,6 +196,7 @@
 void ResetScreenHandler::HandleOnCancel() {
   if (delegate_)
     delegate_->OnExit();
+  DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
 }
 
 void ResetScreenHandler::HandleOnRestart(bool should_rollback) {
@@ -197,6 +210,8 @@
 
 void ResetScreenHandler::HandleOnPowerwash(bool rollback_checked) {
   if (rollback_available_ && (rollback_checked || reboot_was_requested_)) {
+      CallJS("updateViewOnRollbackCall");
+      DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(this);
       chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->Rollback();
   } else {
     if (rollback_checked && !rollback_available_) {
@@ -214,4 +229,17 @@
   help_app_->ShowHelpTopic(HelpAppLauncher::HELP_POWERWASH);
 }
 
+void ResetScreenHandler::UpdateStatusChanged(
+    const UpdateEngineClient::Status& status) {
+  if (status.status == UpdateEngineClient::UPDATE_STATUS_ERROR) {
+    // Show error screen.
+    base::DictionaryValue params;
+    params.SetInteger("uiState", kErrorUIStateRollback);
+    ShowScreen(OobeUI::kScreenErrorMessage, &params);
+  } else if (status.status ==
+      UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT) {
+    DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
+  }
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h
index 6836e38..6cf926f 100644
--- a/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h
@@ -11,13 +11,15 @@
 #include "chrome/browser/chromeos/login/help_app_launcher.h"
 #include "chrome/browser/chromeos/login/screens/reset_screen_actor.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
+#include "chromeos/dbus/update_engine_client.h"
 #include "content/public/browser/web_ui.h"
 
 namespace chromeos {
 
 // WebUI implementation of ResetScreenActor.
 class ResetScreenHandler : public ResetScreenActor,
-                           public BaseScreenHandler {
+                           public BaseScreenHandler,
+                           public UpdateEngineClient::Observer {
  public:
   ResetScreenHandler();
   virtual ~ResetScreenHandler();
@@ -35,6 +37,10 @@
   // WebUIMessageHandler implementation:
   virtual void RegisterMessages() OVERRIDE;
 
+  // UpdateEngineClient::Observer implementation:
+  virtual void UpdateStatusChanged(
+      const UpdateEngineClient::Status& status) OVERRIDE;
+
   void OnRollbackCheck(bool can_rollback);
 
  private:
@@ -65,7 +71,7 @@
   // Keeps whether rollback option is available fo.
   bool rollback_available_;
 
-  base::WeakPtrFactory<ResetScreenHandler> weak_factory_;
+  base::WeakPtrFactory<ResetScreenHandler> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ResetScreenHandler);
 };
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 76f23df..b916b30 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -437,6 +437,8 @@
 
   builder->Add("fatalEnrollmentError",
                IDS_ENTERPRISE_ENROLLMENT_AUTH_FATAL_ERROR);
+  builder->Add("insecureURLEnrollmentError",
+               IDS_ENTERPRISE_ENROLLMENT_AUTH_INSECURE_URL_ERROR);
 
   if (chromeos::KioskModeSettings::Get()->IsKioskModeEnabled())
     builder->Add("demoLoginMessage", IDS_KIOSK_MODE_LOGIN_MESSAGE);
@@ -989,18 +991,15 @@
     }
     case chrome::NOTIFICATION_AUTH_SUPPLIED:
       has_pending_auth_ui_ = false;
-      if (IsSigninScreenHiddenByError()) {
-        // Hide error screen and reload auth extension.
-        HideOfflineMessage(network_state_informer_->state(),
-                           ErrorScreenActor::ERROR_REASON_PROXY_AUTH_SUPPLIED);
-      } else if (ui_state_ == UI_STATE_GAIA_SIGNIN) {
-        // Reload auth extension as proxy credentials are supplied.
+      // Reload auth extension as proxy credentials are supplied.
+      if (!IsSigninScreenHiddenByError() && ui_state_ == UI_STATE_GAIA_SIGNIN)
         ReloadGaiaScreen();
-      }
+      update_state_closure_.Cancel();
       break;
     case chrome::NOTIFICATION_AUTH_CANCELLED: {
       // Don't reload auth extension if proxy auth dialog was cancelled.
       has_pending_auth_ui_ = false;
+      update_state_closure_.Cancel();
       break;
     }
     default:
diff --git a/chrome/browser/ui/webui/chromeos/network_ui.cc b/chrome/browser/ui/webui/chromeos/network_ui.cc
index 8f4433d..7c3170c 100644
--- a/chrome/browser/ui/webui/chromeos/network_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/network_ui.cc
@@ -105,7 +105,7 @@
        it != network_list.end();
        ++it) {
     base::DictionaryValue* properties = new base::DictionaryValue;
-    (*it)->GetProperties(properties);
+    (*it)->GetStateProperties(properties);
     output->Set((*it)->path(), properties);
   }
 }
@@ -120,9 +120,9 @@
            favorite_list.begin();
        it != favorite_list.end();
        ++it) {
-    // Get the complete dictionary of FavoriteState properties.
-    const base::DictionaryValue& properties = (*it)->properties();
-    output->Set((*it)->path(), properties.DeepCopy());
+    base::DictionaryValue* properties = new base::DictionaryValue;
+    (*it)->GetStateProperties(properties);
+    output->Set((*it)->path(), properties);
   }
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/slow_trace_ui.cc b/chrome/browser/ui/webui/chromeos/slow_trace_ui.cc
index 208a816..e898fac 100644
--- a/chrome/browser/ui/webui/chromeos/slow_trace_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/slow_trace_ui.cc
@@ -8,9 +8,9 @@
 #include "base/memory/ref_counted_memory.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/string_number_conversions.h"
-#include "chrome/browser/feedback/tracing_manager.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/url_constants.h"
+#include "components/feedback/tracing_manager.h"
 #include "content/public/browser/url_data_source.h"
 #include "content/public/browser/web_ui.h"
 #include "grit/theme_resources.h"
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc b/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
index 9890575..ba8e0e5 100644
--- a/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
@@ -33,7 +33,7 @@
   bool contents_destroyed() { return contents_destroyed_; }
 
  private:
-  virtual void WebContentsDestroyed(WebContents* tab) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     contents_destroyed_ = true;
   }
 
diff --git a/chrome/browser/ui/webui/devtools_ui.cc b/chrome/browser/ui/webui/devtools_ui.cc
index 007a3fd..0c80d69 100644
--- a/chrome/browser/ui/webui/devtools_ui.cc
+++ b/chrome/browser/ui/webui/devtools_ui.cc
@@ -48,41 +48,49 @@
     "data:text/plain,Cannot load DevTools frontend from an untrusted origin";
 #endif  // defined(DEBUG_DEVTOOLS)
 
+// FetchRequest ---------------------------------------------------------------
 
 class FetchRequest : public net::URLFetcherDelegate {
  public:
   FetchRequest(net::URLRequestContextGetter* request_context,
                const GURL& url,
-               const content::URLDataSource::GotDataCallback& callback)
-      : callback_(callback) {
-    if (!url.is_valid()) {
-      OnURLFetchComplete(NULL);
-      return;
-    }
-
-    fetcher_.reset(net::URLFetcher::Create(url, net::URLFetcher::GET, this));
-    fetcher_->SetRequestContext(request_context);
-    fetcher_->Start();
-  }
+               const content::URLDataSource::GotDataCallback& callback);
 
  private:
   virtual ~FetchRequest() {}
-
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE {
-    std::string response;
-    if (source)
-      source->GetResponseAsString(&response);
-    else
-      response = kHttpNotFound;
-
-    callback_.Run(base::RefCountedString::TakeString(&response));
-    delete this;
-  }
-
+  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
   scoped_ptr<net::URLFetcher> fetcher_;
   content::URLDataSource::GotDataCallback callback_;
 };
 
+FetchRequest::FetchRequest(
+    net::URLRequestContextGetter* request_context,
+    const GURL& url,
+    const content::URLDataSource::GotDataCallback& callback)
+    : callback_(callback) {
+  if (!url.is_valid()) {
+    OnURLFetchComplete(NULL);
+    return;
+  }
+
+  fetcher_.reset(net::URLFetcher::Create(url, net::URLFetcher::GET, this));
+  fetcher_->SetRequestContext(request_context);
+  fetcher_->Start();
+}
+
+void FetchRequest::OnURLFetchComplete(const net::URLFetcher* source) {
+  std::string response;
+  if (source)
+    source->GetResponseAsString(&response);
+  else
+    response = kHttpNotFound;
+
+  callback_.Run(base::RefCountedString::TakeString(&response));
+  delete this;
+}
+
+// DevToolsDataSource ---------------------------------------------------------
+
 std::string GetMimeTypeForPath(const std::string& path) {
   std::string filename = PathWithoutParams(path);
   if (EndsWith(filename, ".html", false)) {
@@ -106,102 +114,130 @@
 // requests. Three types of requests could be handled based on the URL path:
 // 1. /bundled/: bundled DevTools frontend is served.
 // 2. /remote/: Remote DevTools frontend is served from App Engine.
-// 3. /localhost/: Remote frontend is served from localhost:9222. This is a
-// debug only feature hidden beihnd a compile time flag DEBUG_DEVTOOLS.
 class DevToolsDataSource : public content::URLDataSource {
  public:
-  explicit DevToolsDataSource(net::URLRequestContextGetter*
-    request_context) : request_context_(request_context) {
-  }
+  explicit DevToolsDataSource(net::URLRequestContextGetter* request_context);
 
   // content::URLDataSource implementation.
-  virtual std::string GetSource() const OVERRIDE {
-    return chrome::kChromeUIDevToolsHost;
-  }
+  virtual std::string GetSource() const OVERRIDE;
 
   virtual void StartDataRequest(
       const std::string& path,
       int render_process_id,
       int render_frame_id,
-      const content::URLDataSource::GotDataCallback& callback) OVERRIDE {
-    std::string bundled_path_prefix(chrome::kChromeUIDevToolsBundledPath);
-    bundled_path_prefix += "/";
-    if (StartsWithASCII(path, bundled_path_prefix, false)) {
-      StartBundledDataRequest(path.substr(bundled_path_prefix.length()),
-                              render_process_id,
-                              render_frame_id,
-                              callback);
-      return;
-    }
-    std::string remote_path_prefix(chrome::kChromeUIDevToolsRemotePath);
-    remote_path_prefix += "/";
-    if (StartsWithASCII(path, remote_path_prefix, false)) {
-      StartRemoteDataRequest(path.substr(remote_path_prefix.length()),
-                              render_process_id,
-                              render_frame_id,
-                              callback);
-      return;
-    }
-  }
+      const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
+
+ private:
+  // content::URLDataSource overrides.
+  virtual std::string GetMimeType(const std::string& path) const OVERRIDE;
+  virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE;
+  virtual bool ShouldServeMimeTypeAsContentTypeHeader() const OVERRIDE;
 
   // Serves bundled DevTools frontend from ResourceBundle.
   void StartBundledDataRequest(
       const std::string& path,
       int render_process_id,
       int render_frame_id,
-      const content::URLDataSource::GotDataCallback& callback) {
-    std::string filename = PathWithoutParams(path);
-
-    int resource_id =
-        content::DevToolsHttpHandler::GetFrontendResourceId(filename);
-
-    DLOG_IF(WARNING, -1 == resource_id) << "Unable to find dev tool resource: "
-        << filename << ". If you compiled with debug_devtools=1, try running"
-        " with --debug-devtools.";
-    const ResourceBundle& rb = ResourceBundle::GetSharedInstance();
-    scoped_refptr<base::RefCountedStaticMemory> bytes(rb.LoadDataResourceBytes(
-        resource_id));
-    callback.Run(bytes.get());
-  }
+      const content::URLDataSource::GotDataCallback& callback);
 
   // Serves remote DevTools frontend from hard-coded App Engine domain.
   void StartRemoteDataRequest(
       const std::string& path,
       int render_process_id,
       int render_frame_id,
-      const content::URLDataSource::GotDataCallback& callback) {
-    GURL url = GURL(kRemoteFrontendBase + path);
-    CHECK_EQ(url.host(), kRemoteFrontendDomain);
-    new FetchRequest(request_context_.get(), url, callback);
-  }
+      const content::URLDataSource::GotDataCallback& callback);
 
-  virtual std::string GetMimeType(const std::string& path) const OVERRIDE {
-    return GetMimeTypeForPath(path);
-  }
-
-  virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE {
-    return false;
-  }
-
-  virtual bool ShouldServeMimeTypeAsContentTypeHeader() const OVERRIDE {
-    return true;
-  }
-
- private:
   virtual ~DevToolsDataSource() {}
   scoped_refptr<net::URLRequestContextGetter> request_context_;
 
   DISALLOW_COPY_AND_ASSIGN(DevToolsDataSource);
 };
 
+DevToolsDataSource::DevToolsDataSource(
+    net::URLRequestContextGetter* request_context)
+    : request_context_(request_context) {
+}
+
+std::string DevToolsDataSource::GetSource() const {
+  return chrome::kChromeUIDevToolsHost;
+}
+
+void DevToolsDataSource::StartDataRequest(
+    const std::string& path,
+    int render_process_id,
+    int render_frame_id,
+    const content::URLDataSource::GotDataCallback& callback) {
+  // Serve request from local bundle.
+  std::string bundled_path_prefix(chrome::kChromeUIDevToolsBundledPath);
+  bundled_path_prefix += "/";
+  if (StartsWithASCII(path, bundled_path_prefix, false)) {
+    StartBundledDataRequest(path.substr(bundled_path_prefix.length()),
+                            render_process_id, render_frame_id, callback);
+    return;
+  }
+
+  // Serve request from remote location.
+  std::string remote_path_prefix(chrome::kChromeUIDevToolsRemotePath);
+  remote_path_prefix += "/";
+  if (StartsWithASCII(path, remote_path_prefix, false)) {
+    StartRemoteDataRequest(path.substr(remote_path_prefix.length()),
+                           render_process_id, render_frame_id, callback);
+    return;
+  }
+
+  callback.Run(NULL);
+}
+
+std::string DevToolsDataSource::GetMimeType(const std::string& path) const {
+  return GetMimeTypeForPath(path);
+}
+
+bool DevToolsDataSource::ShouldAddContentSecurityPolicy() const {
+  return false;
+}
+
+bool DevToolsDataSource::ShouldServeMimeTypeAsContentTypeHeader() const {
+  return true;
+}
+
+void DevToolsDataSource::StartBundledDataRequest(
+    const std::string& path,
+    int render_process_id,
+    int render_frame_id,
+    const content::URLDataSource::GotDataCallback& callback) {
+  std::string filename = PathWithoutParams(path);
+
+  int resource_id =
+      content::DevToolsHttpHandler::GetFrontendResourceId(filename);
+
+  DLOG_IF(WARNING, -1 == resource_id) << "Unable to find dev tool resource: "
+      << filename << ". If you compiled with debug_devtools=1, try running"
+      " with --debug-devtools.";
+  const ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+  scoped_refptr<base::RefCountedStaticMemory> bytes(rb.LoadDataResourceBytes(
+      resource_id));
+  callback.Run(bytes.get());
+}
+
+void DevToolsDataSource::StartRemoteDataRequest(
+    const std::string& path,
+    int render_process_id,
+    int render_frame_id,
+    const content::URLDataSource::GotDataCallback& callback) {
+  GURL url = GURL(kRemoteFrontendBase + path);
+  CHECK_EQ(url.host(), kRemoteFrontendDomain);
+  new FetchRequest(request_context_, url, callback);
+}
+
 }  // namespace
 
+// DevToolsUI -----------------------------------------------------------------
+
 // static
 GURL DevToolsUI::GetProxyURL(const std::string& frontend_url) {
   GURL url(frontend_url);
-  if (!url.is_valid() || url.host() != kRemoteFrontendDomain) {
+  if (!url.is_valid() || url.host() != kRemoteFrontendDomain)
     return GURL(kFallbackFrontendURL);
-  }
   return GURL(base::StringPrintf("%s://%s/%s/%s",
               content::kChromeDevToolsScheme,
               chrome::kChromeUIDevToolsHost,
diff --git a/chrome/browser/ui/webui/devtools_ui.h b/chrome/browser/ui/webui/devtools_ui.h
index cceeb84..75696ff 100644
--- a/chrome/browser/ui/webui/devtools_ui.h
+++ b/chrome/browser/ui/webui/devtools_ui.h
@@ -18,7 +18,6 @@
   explicit DevToolsUI(content::WebUI* web_ui);
 
  private:
-
   DevToolsUIBindings bindings_;
   DISALLOW_COPY_AND_ASSIGN(DevToolsUI);
 };
diff --git a/chrome/browser/ui/webui/downloads_dom_handler.cc b/chrome/browser/ui/webui/downloads_dom_handler.cc
index 2290e17..84ec86f 100644
--- a/chrome/browser/ui/webui/downloads_dom_handler.cc
+++ b/chrome/browser/ui/webui/downloads_dom_handler.cc
@@ -43,7 +43,6 @@
 #include "content/public/browser/url_data_source.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "extensions/browser/extension_system.h"
 #include "grit/generated_resources.h"
@@ -385,7 +384,7 @@
 
   gfx::Image* icon = g_browser_process->icon_manager()->LookupIconFromFilepath(
       file->GetTargetFilePath(), IconLoader::NORMAL);
-  gfx::NativeView view = web_contents->GetView()->GetNativeView();
+  gfx::NativeView view = web_contents->GetNativeView();
   {
     // Enable nested tasks during DnD, while |DragDownload()| blocks.
     base::MessageLoop::ScopedNestableTaskAllower allow(
diff --git a/chrome/browser/ui/webui/downloads_ui_browsertest.js b/chrome/browser/ui/webui/downloads_ui_browsertest.js
index f4e43c8..1cd786a 100644
--- a/chrome/browser/ui/webui/downloads_ui_browsertest.js
+++ b/chrome/browser/ui/webui/downloads_ui_browsertest.js
@@ -56,30 +56,31 @@
   /**
    * Creates a download object to be passed to the page, following the expected
    * backend format (see downloads_dom_handler.cc).
-   * @param {Number} A unique ID for the download.
-   * @param {Number} The time the download purportedly started.
+   * @param {number} A unique ID for the download.
+   * @param {number} The time the download purportedly started.
+   * @return {!Object} A fake download object.
+   * @private
    */
   createDownload_: function(id, timestamp) {
-    var download = {};
-    download.id = id;
-    download.started = timestamp;
-    download.otr = false;
-    download.state = Download.States.COMPLETE;
-    download.retry = false;
-    download.file_path = '/path/to/file';
-    download.file_url = 'http://google.com/' + timestamp;
-    download.file_name = 'download_' + timestamp;
-    download.url = 'http://google.com/' + timestamp;
-    download.file_externally_removed = false;
-    download.danger_type = Download.DangerType.NOT_DANGEROUS;
-    download.last_reason_text = '';
-    download.since_string = 'today';
-    download.date_string = 'today';
-    download.percent = 100;
-    download.progress_status_text = 'done';
-    download.received = 128;
-
-    return download;
+    return {
+      id: id,
+      started: timestamp,
+      otr: false,
+      state: Download.States.COMPLETE,
+      retry: false,
+      file_path: '/path/to/file',
+      file_url: 'http://google.com/' + timestamp,
+      file_name: 'download_' + timestamp,
+      url: 'http://google.com/' + timestamp,
+      file_externally_removed: false,
+      danger_type: Download.DangerType.NOT_DANGEROUS,
+      last_reason_text: '',
+      since_string: 'today',
+      date_string: 'today',
+      percent: 100,
+      progress_status_text: 'done',
+      received: 128,
+    };
   },
 
   /**
diff --git a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js b/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js
index 2ac9d32..aaa7478 100644
--- a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js
+++ b/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_browsertest.js
@@ -90,7 +90,7 @@
   appIdInput.value = testAppId;
 
   this.mockHandler.expects(once()).addKioskApp([testAppId]);
-  var keypress = document.createEvent("KeyboardEvents");
+  var keypress = document.createEvent('KeyboardEvents');
   keypress.initKeyboardEvent('keypress', true, true, null, 'Enter', '');
   appIdInput.dispatchEvent(keypress);
 });
diff --git a/chrome/browser/ui/webui/extensions/extension_loader_handler.cc b/chrome/browser/ui/webui/extensions/extension_loader_handler.cc
index 50dd4e4..6e43177 100644
--- a/chrome/browser/ui/webui/extensions/extension_loader_handler.cc
+++ b/chrome/browser/ui/webui/extensions/extension_loader_handler.cc
@@ -19,7 +19,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "extensions/browser/extension_system.h"
@@ -113,8 +112,7 @@
       NULL,
       kFileTypeIndex,
       base::FilePath::StringType(),
-      loader_handler_->web_ui()->
-          GetWebContents()->GetView()->GetTopLevelNativeWindow(),
+      loader_handler_->web_ui()->GetWebContents()->GetTopLevelNativeWindow(),
       NULL);
 
   content::RecordComputedAction("Options_LoadUnpackedExtension");
@@ -187,6 +185,11 @@
   installer->set_on_failure_callback(
       base::Bind(&ExtensionLoaderHandler::OnLoadFailure,
                  weak_ptr_factory_.GetWeakPtr()));
+
+  // We do our own error handling, so we don't want a load failure to trigger
+  // a dialog.
+  installer->set_be_noisy_on_failure(false);
+
   installer->Load(file_path);
 }
 
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js
index 2324d6d..cf1e95c 100644
--- a/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js
+++ b/chrome/browser/ui/webui/extensions/extension_settings_browsertest.js
@@ -99,7 +99,7 @@
   testGenPreamble: function() {
     GEN('  InstallGoodExtension();');
   }
-}
+};
 
 TEST_F('ExtensionSettingsWebUITestWithExtensionInstalled',
        'baseAccessibilityIsOk', function() {
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
index 9d5ad69..da10080 100644
--- a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
+++ b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
@@ -213,12 +213,16 @@
   if (suspicious_install)
     should_do_verification_check_ = true;
 
+  bool corrupt_install =
+      (disable_reasons & Extension::DISABLE_CORRUPTED) != 0;
+  extension_data->SetBoolean("corruptInstall", corrupt_install);
+
   bool managed_install =
       !management_policy_->UserMayModifySettings(extension, NULL);
   extension_data->SetBoolean("managedInstall", managed_install);
 
   // We should not get into a state where both are true.
-  DCHECK(managed_install == false || suspicious_install == false);
+  DCHECK(!managed_install || !suspicious_install);
 
   GURL icon =
       ExtensionIconSource::GetIconURL(extension,
@@ -457,12 +461,18 @@
       l10n_util::GetStringUTF16(IDS_EXTENSIONS_POLICY_CONTROLLED));
   source->AddString("extensionSettingsManagedMode",
       l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_MANAGED_USER));
+  source->AddString("extensionSettingsCorruptInstall",
+      l10n_util::GetStringUTF16(
+          IDS_EXTENSIONS_CORRUPTED_EXTENSION));
   source->AddString("extensionSettingsSuspiciousInstall",
       l10n_util::GetStringFUTF16(
           IDS_EXTENSIONS_ADDED_WITHOUT_KNOWLEDGE,
           l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)));
-  source->AddString("extensionSettingsSuspiciousInstallLearnMore",
+  source->AddString("extensionSettingsLearnMore",
       l10n_util::GetStringUTF16(IDS_LEARN_MORE));
+  source->AddString("extensionSettingsCorruptInstallHelpUrl",
+      base::ASCIIToUTF16(google_util::AppendGoogleLocaleParam(
+          GURL(chrome::kCorruptExtensionURL)).spec()));
   source->AddString("extensionSettingsSuspiciousInstallHelpUrl",
       base::ASCIIToUTF16(google_util::AppendGoogleLocaleParam(
           GURL(chrome::kRemoveNonCWSExtensionURL)).spec()));
@@ -477,16 +487,15 @@
   source->AddString("extensionSettingsUpdateButton",
       l10n_util::GetStringUTF16(IDS_EXTENSIONS_UPDATE_BUTTON));
   source->AddString(
-      "extensionSettingsAppsDevToolsPromoText",
-      l10n_util::GetStringUTF16(IDS_EXTENSIONS_APPS_DEV_TOOLS_PROMO_TEXT));
+      "extensionSettingsAppsDevToolsPromoHTML",
+      l10n_util::GetStringFUTF16(
+          IDS_EXTENSIONS_APPS_DEV_TOOLS_PROMO_HTML,
+          base::ASCIIToUTF16(google_util::AppendGoogleLocaleParam(
+              GURL(extension_urls::GetWebstoreItemDetailURLPrefix() +
+                       kAppsDeveloperToolsExtensionId)).spec())));
   source->AddString(
-      "extensionSettingsAppsDevToolsLinkText",
-      l10n_util::GetStringUTF16(IDS_EXTENSIONS_APPS_DEV_TOOLS_LINK_TEXT));
-  source->AddString(
-      "extensionSettingsAppsDevToolsUrl",
-      base::ASCIIToUTF16(google_util::AppendGoogleLocaleParam(
-          GURL(extension_urls::GetWebstoreItemDetailURLPrefix() +
-                   kAppsDeveloperToolsExtensionId)).spec()));
+      "extensionSettingsAppDevToolsPromoClose",
+      l10n_util::GetStringUTF16(IDS_CLOSE));
   source->AddString("extensionSettingsCrashMessage",
       l10n_util::GetStringUTF16(IDS_EXTENSIONS_CRASHED_EXTENSION));
   source->AddString("extensionSettingsInDevelopment",
diff --git a/chrome/browser/ui/webui/extensions/install_extension_handler.cc b/chrome/browser/ui/webui/extensions/install_extension_handler.cc
index d503e65..3a5ba35 100644
--- a/chrome/browser/ui/webui/extensions/install_extension_handler.cc
+++ b/chrome/browser/ui/webui/extensions/install_extension_handler.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/extensions/unpacked_installer.h"
 #include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "content/public/common/drop_data.h"
@@ -63,7 +62,7 @@
 void InstallExtensionHandler::HandleStartDragMessage(
     const base::ListValue* args) {
   content::DropData* drop_data =
-      web_ui()->GetWebContents()->GetView()->GetDropData();
+      web_ui()->GetWebContents()->GetDropData();
   if (!drop_data) {
     DLOG(ERROR) << "No current drop data.";
     return;
diff --git a/chrome/browser/ui/webui/extensions/pack_extension_handler.cc b/chrome/browser/ui/webui/extensions/pack_extension_handler.cc
index 717fb51..e7de840 100644
--- a/chrome/browser/ui/webui/extensions/pack_extension_handler.cc
+++ b/chrome/browser/ui/webui/extensions/pack_extension_handler.cc
@@ -9,7 +9,6 @@
 #include "chrome/browser/extensions/extension_creator.h"
 #include "chrome/browser/ui/chrome_select_file_policy.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "grit/generated_resources.h"
@@ -195,7 +194,7 @@
       &info,
       file_type_index,
       base::FilePath::StringType(),
-      web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(),
+      web_ui()->GetWebContents()->GetTopLevelNativeWindow(),
       NULL);
 }
 
diff --git a/chrome/browser/ui/webui/flash_ui.cc b/chrome/browser/ui/webui/flash_ui.cc
index e9f1222..6d79141 100644
--- a/chrome/browser/ui/webui/flash_ui.cc
+++ b/chrome/browser/ui/webui/flash_ui.cc
@@ -366,10 +366,9 @@
   AddPair(list,
           ASCIIToUTF16("Vertex shader version"),
           gpu_info.vertex_shader_version);
-  AddPair(list, ASCIIToUTF16("GL version"), gpu_info.gl_version);
   AddPair(list, ASCIIToUTF16("GL_VENDOR"), gpu_info.gl_vendor);
   AddPair(list, ASCIIToUTF16("GL_RENDERER"), gpu_info.gl_renderer);
-  AddPair(list, ASCIIToUTF16("GL_VERSION"), gpu_info.gl_version_string);
+  AddPair(list, ASCIIToUTF16("GL_VERSION"), gpu_info.gl_version);
   AddPair(list, ASCIIToUTF16("GL_EXTENSIONS"), gpu_info.gl_extensions);
 
   base::DictionaryValue flashInfo;
diff --git a/chrome/browser/ui/webui/gcm_internals_ui.cc b/chrome/browser/ui/webui/gcm_internals_ui.cc
index 54779c5..bc560a8 100644
--- a/chrome/browser/ui/webui/gcm_internals_ui.cc
+++ b/chrome/browser/ui/webui/gcm_internals_ui.cc
@@ -26,6 +26,72 @@
 
 namespace {
 
+void SetCheckinInfo(
+    const std::vector<gcm::GCMStatsRecorder::CheckinActivity>& checkins,
+    base::ListValue* checkin_info) {
+  std::vector<gcm::GCMStatsRecorder::CheckinActivity>::const_iterator it =
+      checkins.begin();
+  for (; it < checkins.end(); ++it) {
+    base::ListValue* row = new base::ListValue();
+    checkin_info->Append(row);
+
+    row->AppendDouble(it->time.ToJsTime());
+    row->AppendString(it->event);
+    row->AppendString(it->details);
+  }
+}
+
+void SetConnectionInfo(
+    const std::vector<gcm::GCMStatsRecorder::ConnectionActivity>& connections,
+    base::ListValue* connection_info) {
+  std::vector<gcm::GCMStatsRecorder::ConnectionActivity>::const_iterator it =
+      connections.begin();
+  for (; it < connections.end(); ++it) {
+    base::ListValue* row = new base::ListValue();
+    connection_info->Append(row);
+
+    row->AppendDouble(it->time.ToJsTime());
+    row->AppendString(it->event);
+    row->AppendString(it->details);
+  }
+}
+
+void SetRegistrationInfo(
+    const std::vector<gcm::GCMStatsRecorder::RegistrationActivity>&
+        registrations,
+    base::ListValue* registration_info) {
+  std::vector<gcm::GCMStatsRecorder::RegistrationActivity>::const_iterator it =
+      registrations.begin();
+  for (; it < registrations.end(); ++it) {
+    base::ListValue* row = new base::ListValue();
+    registration_info->Append(row);
+
+    row->AppendDouble(it->time.ToJsTime());
+    row->AppendString(it->app_id);
+    row->AppendString(it->sender_ids);
+    row->AppendString(it->event);
+    row->AppendString(it->details);
+  }
+}
+
+void SetReceivingInfo(
+    const std::vector<gcm::GCMStatsRecorder::ReceivingActivity>& receives,
+    base::ListValue* receive_info) {
+  std::vector<gcm::GCMStatsRecorder::ReceivingActivity>::const_iterator it =
+      receives.begin();
+  for (; it < receives.end(); ++it) {
+    base::ListValue* row = new base::ListValue();
+    receive_info->Append(row);
+
+    row->AppendDouble(it->time.ToJsTime());
+    row->AppendString(it->app_id);
+    row->AppendString(it->from);
+    row->AppendString(base::StringPrintf("%d", it->message_byte_size));
+    row->AppendString(it->event);
+    row->AppendString(it->details);
+  }
+}
+
 void SetSendingInfo(
     const std::vector<gcm::GCMStatsRecorder::SendingActivity>& sends,
     base::ListValue* send_info) {
@@ -116,6 +182,30 @@
     device_info->SetInteger("sendQueueSize", stats->send_queue_size);
     device_info->SetInteger("resendQueueSize", stats->resend_queue_size);
 
+    if (stats->recorded_activities.checkin_activities.size() > 0) {
+      base::ListValue* checkin_info = new base::ListValue();
+      results.Set("checkinInfo", checkin_info);
+      SetCheckinInfo(stats->recorded_activities.checkin_activities,
+                     checkin_info);
+    }
+    if (stats->recorded_activities.connection_activities.size() > 0) {
+      base::ListValue* connection_info = new base::ListValue();
+      results.Set("connectionInfo", connection_info);
+      SetConnectionInfo(stats->recorded_activities.connection_activities,
+                        connection_info);
+    }
+    if (stats->recorded_activities.registration_activities.size() > 0) {
+      base::ListValue* registration_info = new base::ListValue();
+      results.Set("registrationInfo", registration_info);
+      SetRegistrationInfo(stats->recorded_activities.registration_activities,
+                          registration_info);
+    }
+    if (stats->recorded_activities.receiving_activities.size() > 0) {
+      base::ListValue* receive_info = new base::ListValue();
+      results.Set("receiveInfo", receive_info);
+      SetReceivingInfo(stats->recorded_activities.receiving_activities,
+                       receive_info);
+    }
     if (stats->recorded_activities.sending_activities.size() > 0) {
       base::ListValue* send_info = new base::ListValue();
       results.Set("sendInfo", send_info);
diff --git a/chrome/browser/ui/webui/history_ui.cc b/chrome/browser/ui/webui/history_ui.cc
index e2fce58..24f4f78 100644
--- a/chrome/browser/ui/webui/history_ui.cc
+++ b/chrome/browser/ui/webui/history_ui.cc
@@ -1006,12 +1006,6 @@
 }
 
 // static
-const GURL HistoryUI::GetHistoryURLWithSearchText(const base::string16& text) {
-  return GURL(std::string(chrome::kChromeUIHistoryURL) + "#q=" +
-              net::EscapeQueryParamValue(base::UTF16ToUTF8(text), true));
-}
-
-// static
 base::RefCountedMemory* HistoryUI::GetFaviconResourceBytes(
       ui::ScaleFactor scale_factor) {
   return ResourceBundle::GetSharedInstance().
diff --git a/chrome/browser/ui/webui/history_ui.h b/chrome/browser/ui/webui/history_ui.h
index b94eaa3..d11dbc1 100644
--- a/chrome/browser/ui/webui/history_ui.h
+++ b/chrome/browser/ui/webui/history_ui.h
@@ -211,9 +211,6 @@
  public:
   explicit HistoryUI(content::WebUI* web_ui);
 
-  // Return the URL for a given search term.
-  static const GURL GetHistoryURLWithSearchText(const base::string16& text);
-
   static base::RefCountedMemory* GetFaviconResourceBytes(
       ui::ScaleFactor scale_factor);
 
diff --git a/chrome/browser/ui/webui/identity_internals_ui_browsertest.js b/chrome/browser/ui/webui/identity_internals_ui_browsertest.js
index 67a6cb6..765e892 100644
--- a/chrome/browser/ui/webui/identity_internals_ui_browsertest.js
+++ b/chrome/browser/ui/webui/identity_internals_ui_browsertest.js
@@ -31,7 +31,7 @@
 
   /**
    * Gets all of the token entries on the page.
-   * return {Element[]} Elements displaying token information.
+   * @return {!NodeList} Elements displaying token information.
    */
   getTokens: function() {
     return document.querySelectorAll('#token-list > div');
@@ -234,7 +234,7 @@
 IdentityInternalsWebUITestAsync.prototype = {
   __proto__: IdentityInternalsMultipleTokensWebUITest.prototype,
 
-  /** @inhritDoc */
+  /** @override */
   isAsync: true,
 };
 
@@ -243,7 +243,7 @@
   expectEquals(2, tokenListBefore.length);
   var tokenRevokeDone = identity_internals.tokenRevokeDone;
   identity_internals.tokenRevokeDone = this.continueTest(
-      WhenTestDone.ALWAYS, function (accessTokens) {
+      WhenTestDone.ALWAYS, function(accessTokens) {
         tokenRevokeDone.call(identity_internals, accessTokens);
         identity_internals.tokenRevokeDone = tokenRevokeDone;
         var tokenListAfter = this.getTokens();
diff --git a/chrome/browser/ui/webui/inspect_ui_browsertest.cc b/chrome/browser/ui/webui/inspect_ui_browsertest.cc
index f70ddb6..e9d9683 100644
--- a/chrome/browser/ui/webui/inspect_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/inspect_ui_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/devtools/device/adb/adb_device_provider.h"
 #include "chrome/browser/devtools/device/adb/mock_adb_server.h"
 #include "chrome/browser/devtools/device/devtools_android_bridge.h"
 #include "chrome/browser/ui/browser.h"
@@ -72,7 +73,7 @@
   scoped_refptr<DevToolsAndroidBridge> android_bridge =
       DevToolsAndroidBridge::Factory::GetForProfile(browser()->profile());
   AndroidDeviceManager::DeviceProviders providers;
-  providers.push_back(AndroidDeviceManager::GetAdbDeviceProvider());
+  providers.push_back(new AdbDeviceProvider());
   android_bridge->set_device_providers_for_test(providers);
 
   StartMockAdbServer();
diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h
index 1929063..a9f35d3 100644
--- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h
+++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h
@@ -87,7 +87,7 @@
   typedef std::map<std::string, DeviceDescription> DeviceDescriptionMap;
 
   // Message handlers:
-  // For when the page is ready to recieve device notifications.
+  // For when the page is ready to receive device notifications.
   void HandleStart(const base::ListValue* args);
 
   // For when a visibility change occurs.
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index 6ca3b5e..05b4db3 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -1201,7 +1201,7 @@
   CHECK(list->GetString(0, &domain));
   base::DictionaryValue* result = new base::DictionaryValue();
 
-  if (!IsStringASCII(domain)) {
+  if (!base::IsStringASCII(domain)) {
     result->SetString("error", "non-ASCII domain name");
   } else {
     net::TransportSecurityState* transport_security_state =
@@ -1209,26 +1209,62 @@
     if (!transport_security_state) {
       result->SetString("error", "no TransportSecurityState active");
     } else {
-      net::TransportSecurityState::DomainState state;
-      const bool found = transport_security_state->GetDomainState(
-          domain, true, &state);
-
-      result->SetBoolean("result", found);
-      if (found) {
-        result->SetInteger("mode", static_cast<int>(state.upgrade_mode));
-        result->SetBoolean("sts_subdomains", state.sts_include_subdomains);
-        result->SetBoolean("pkp_subdomains", state.pkp_include_subdomains);
-        result->SetDouble("sts_observed", state.sts_observed.ToDoubleT());
-        result->SetDouble("pkp_observed", state.pkp_observed.ToDoubleT());
-        result->SetString("domain", state.domain);
-        result->SetDouble("expiry", state.upgrade_expiry.ToDoubleT());
-        result->SetDouble("dynamic_spki_hashes_expiry",
-                          state.dynamic_spki_hashes_expiry.ToDoubleT());
-
+      net::TransportSecurityState::DomainState static_state;
+      const bool found_static = transport_security_state->GetStaticDomainState(
+          domain, true, &static_state);
+      if (found_static) {
+        result->SetBoolean("has_static_sts",
+                           found_static && static_state.ShouldUpgradeToSSL());
+        result->SetInteger("static_upgrade_mode",
+                           static_cast<int>(static_state.sts.upgrade_mode));
+        result->SetBoolean("static_sts_include_subdomains",
+                           static_state.sts.include_subdomains);
+        result->SetDouble("static_sts_observed",
+                          static_state.sts.last_observed.ToDoubleT());
+        result->SetDouble("static_sts_expiry",
+                          static_state.sts.expiry.ToDoubleT());
+        result->SetBoolean("has_static_pkp",
+                           found_static && static_state.HasPublicKeyPins());
+        result->SetBoolean("static_pkp_include_subdomains",
+                           static_state.pkp.include_subdomains);
+        result->SetDouble("static_pkp_observed",
+                          static_state.pkp.last_observed.ToDoubleT());
+        result->SetDouble("static_pkp_expiry",
+                          static_state.pkp.expiry.ToDoubleT());
         result->SetString("static_spki_hashes",
-                          HashesToBase64String(state.static_spki_hashes));
+                          HashesToBase64String(static_state.pkp.spki_hashes));
+      }
+
+      net::TransportSecurityState::DomainState dynamic_state;
+      const bool found_dynamic =
+          transport_security_state->GetDynamicDomainState(domain,
+                                                          &dynamic_state);
+      if (found_dynamic) {
+        result->SetInteger("dynamic_upgrade_mode",
+                           static_cast<int>(dynamic_state.sts.upgrade_mode));
+        result->SetBoolean("dynamic_sts_include_subdomains",
+                           dynamic_state.sts.include_subdomains);
+        result->SetBoolean("dynamic_pkp_include_subdomains",
+                           dynamic_state.pkp.include_subdomains);
+        result->SetDouble("dynamic_sts_observed",
+                          dynamic_state.sts.last_observed.ToDoubleT());
+        result->SetDouble("dynamic_pkp_observed",
+                          dynamic_state.pkp.last_observed.ToDoubleT());
+        result->SetDouble("dynamic_sts_expiry",
+                          dynamic_state.sts.expiry.ToDoubleT());
+        result->SetDouble("dynamic_pkp_expiry",
+                          dynamic_state.pkp.expiry.ToDoubleT());
         result->SetString("dynamic_spki_hashes",
-                          HashesToBase64String(state.dynamic_spki_hashes));
+                          HashesToBase64String(dynamic_state.pkp.spki_hashes));
+      }
+
+      result->SetBoolean("result", found_static || found_dynamic);
+      if (found_static) {
+        result->SetString("domain", static_state.domain);
+      } else if (found_dynamic) {
+        result->SetString("domain", dynamic_state.domain);
+      } else {
+        result->SetString("domain", domain);
       }
     }
   }
@@ -1242,7 +1278,7 @@
   // include subdomains>, <key pins>].
   std::string domain;
   CHECK(list->GetString(0, &domain));
-  if (!IsStringASCII(domain)) {
+  if (!base::IsStringASCII(domain)) {
     // Silently fail. The user will get a helpful error if they query for the
     // name.
     return;
@@ -1276,7 +1312,7 @@
   // |list| should be: [<domain to query>].
   std::string domain;
   CHECK(list->GetString(0, &domain));
-  if (!IsStringASCII(domain)) {
+  if (!base::IsStringASCII(domain)) {
     // There cannot be a unicode entry in the HSTS set.
     return;
   }
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
index 3d442ca..17a710d 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -623,7 +623,7 @@
         web_ui()->GetWebContents());
   chrome::ShowCreateChromeAppShortcutsDialog(
       browser->window()->GetNativeWindow(), browser->profile(), extension,
-      base::Closure());
+      base::Callback<void(bool)>());
 }
 
 void AppLauncherHandler::HandleReorderApps(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/ntp/foreign_session_handler.cc b/chrome/browser/ui/webui/ntp/foreign_session_handler.cc
index 74d7650..a2d593f 100644
--- a/chrome/browser/ui/webui/ntp/foreign_session_handler.cc
+++ b/chrome/browser/ui/webui/ntp/foreign_session_handler.cc
@@ -31,7 +31,6 @@
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/url_data_source.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -114,7 +113,7 @@
       iter_begin + 1;
   chrome::HostDesktopType host_desktop_type =
       chrome::GetHostDesktopTypeForNativeView(
-          web_ui->GetWebContents()->GetView()->GetNativeView());
+          web_ui->GetWebContents()->GetNativeView());
   SessionRestore::RestoreForeignSessionWindows(
       Profile::FromWebUI(web_ui), host_desktop_type, iter_begin, iter_end);
 }
diff --git a/chrome/browser/ui/webui/ntp/most_visited_handler.cc b/chrome/browser/ui/webui/ntp/most_visited_handler.cc
index 11a6fcd..3d02e74 100644
--- a/chrome/browser/ui/webui/ntp/most_visited_handler.cc
+++ b/chrome/browser/ui/webui/ntp/most_visited_handler.cc
@@ -25,6 +25,7 @@
 #include "chrome/browser/history/page_usage_data.h"
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/thumbnails/thumbnail_list_source.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -32,7 +33,6 @@
 #include "chrome/browser/ui/webui/favicon_source.h"
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
 #include "chrome/browser/ui/webui/ntp/ntp_stats.h"
-#include "chrome/browser/ui/webui/ntp/thumbnail_list_source.h"
 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
index cba7e20..ea62c10 100644
--- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
+++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -298,35 +298,6 @@
   int new_tab_html_idr = IDR_INCOGNITO_TAB_HTML;
   const char* new_tab_link = kLearnMoreIncognitoUrl;
 
-  // TODO(altimofeev): consider implementation without 'if def' usage.
-#if defined(OS_CHROMEOS)
-  if (profile_->IsGuestSession()) {
-    new_tab_description_ids = IDS_NEW_TAB_GUEST_SESSION_DESCRIPTION;
-    new_tab_heading_ids = IDS_NEW_TAB_GUEST_SESSION_HEADING;
-    new_tab_link_ids = IDS_NEW_TAB_GUEST_SESSION_LEARN_MORE_LINK;
-    new_tab_html_idr = IDR_GUEST_SESSION_TAB_HTML;
-    new_tab_link = kLearnMoreGuestSessionUrl;
-
-    policy::BrowserPolicyConnectorChromeOS* connector =
-        g_browser_process->platform_part()->browser_policy_connector_chromeos();
-    std::string enterprise_domain = connector->GetEnterpriseDomain();
-    if (!enterprise_domain.empty()) {
-      // Device is enterprise enrolled.
-      localized_strings.SetString("enterpriseInfoVisible", "true");
-      base::string16 enterprise_info = l10n_util::GetStringFUTF16(
-          IDS_DEVICE_OWNED_BY_NOTICE,
-          base::UTF8ToUTF16(enterprise_domain));
-      localized_strings.SetString("enterpriseInfoMessage", enterprise_info);
-      localized_strings.SetString("learnMore",
-          l10n_util::GetStringUTF16(IDS_LEARN_MORE));
-      localized_strings.SetString("enterpriseInfoHintLink",
-          GetUrlWithLang(GURL(chrome::kLearnMoreEnterpriseURL)));
-    } else {
-      localized_strings.SetString("enterpriseInfoVisible", "false");
-    }
-  }
-#endif
-
   if (profile_->IsGuestSession()) {
     localized_strings.SetString("guestTabDescription",
         l10n_util::GetStringUTF16(new_tab_description_ids));
@@ -366,11 +337,36 @@
   base::DictionaryValue localized_strings;
   localized_strings.SetString("title",
       l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
-  const char* new_tab_link = kLearnMoreGuestSessionUrl;
+  const char* guest_tab_link = kLearnMoreGuestSessionUrl;
+  int guest_tab_ids = IDR_GUEST_TAB_HTML;
   int guest_tab_description_ids = IDS_NEW_TAB_GUEST_SESSION_DESCRIPTION;
   int guest_tab_heading_ids = IDS_NEW_TAB_GUEST_SESSION_HEADING;
   int guest_tab_link_ids = IDS_NEW_TAB_GUEST_SESSION_LEARN_MORE_LINK;
 
+#if defined(OS_CHROMEOS)
+  guest_tab_ids = IDR_GUEST_SESSION_TAB_HTML;
+  guest_tab_link = kLearnMoreGuestSessionUrl;
+
+  policy::BrowserPolicyConnectorChromeOS* connector =
+      g_browser_process->platform_part()->browser_policy_connector_chromeos();
+  std::string enterprise_domain = connector->GetEnterpriseDomain();
+
+  if (!enterprise_domain.empty()) {
+    // Device is enterprise enrolled.
+    localized_strings.SetString("enterpriseInfoVisible", "true");
+    base::string16 enterprise_info = l10n_util::GetStringFUTF16(
+        IDS_DEVICE_OWNED_BY_NOTICE,
+        base::UTF8ToUTF16(enterprise_domain));
+    localized_strings.SetString("enterpriseInfoMessage", enterprise_info);
+    localized_strings.SetString("enterpriseLearnMore",
+        l10n_util::GetStringUTF16(IDS_LEARN_MORE));
+    localized_strings.SetString("enterpriseInfoHintLink",
+        GetUrlWithLang(GURL(chrome::kLearnMoreEnterpriseURL)));
+  } else {
+    localized_strings.SetString("enterpriseInfoVisible", "false");
+  }
+#endif
+
   localized_strings.SetString("guestTabDescription",
       l10n_util::GetStringUTF16(guest_tab_description_ids));
   localized_strings.SetString("guestTabHeading",
@@ -378,13 +374,12 @@
   localized_strings.SetString("learnMore",
       l10n_util::GetStringUTF16(guest_tab_link_ids));
   localized_strings.SetString("learnMoreLink",
-      GetUrlWithLang(GURL(new_tab_link)));
+      GetUrlWithLang(GURL(guest_tab_link)));
 
   webui::SetFontAndTextDirection(&localized_strings);
 
   static const base::StringPiece guest_tab_html(
-      ResourceBundle::GetSharedInstance().GetRawDataResource(
-          IDR_GUEST_TAB_HTML));
+      ResourceBundle::GetSharedInstance().GetRawDataResource(guest_tab_ids));
 
   std::string full_html = webui::GetI18nTemplateHtml(
       guest_tab_html, &localized_strings);
diff --git a/chrome/browser/ui/webui/ntp/recently_closed_tabs_handler.cc b/chrome/browser/ui/webui/ntp/recently_closed_tabs_handler.cc
index 0121b91..edd653e 100644
--- a/chrome/browser/ui/webui/ntp/recently_closed_tabs_handler.cc
+++ b/chrome/browser/ui/webui/ntp/recently_closed_tabs_handler.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "ui/base/webui/web_ui_util.h"
 
@@ -86,7 +85,7 @@
     return;
   chrome::HostDesktopType host_desktop_type =
       chrome::GetHostDesktopTypeForNativeView(
-          web_ui()->GetWebContents()->GetView()->GetNativeView());
+          web_ui()->GetWebContents()->GetNativeView());
   WindowOpenDisposition disposition = webui::GetDispositionFromClick(args, 2);
   tab_restore_service_->RestoreEntryById(delegate,
                                          static_cast<int>(session_to_restore),
diff --git a/chrome/browser/ui/webui/ntp/thumbnail_list_source.cc b/chrome/browser/ui/webui/ntp/thumbnail_list_source.cc
deleted file mode 100644
index f1c71b8..0000000
--- a/chrome/browser/ui/webui/ntp/thumbnail_list_source.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/browser/ui/webui/ntp/thumbnail_list_source.h"
-
-#include <string>
-
-#include "base/base64.h"
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/strings/string_util.h"
-#include "chrome/browser/history/top_sites.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search/instant_io_context.h"
-#include "chrome/browser/thumbnails/thumbnail_service.h"
-#include "chrome/browser/thumbnails/thumbnail_service_factory.h"
-#include "chrome/common/url_constants.h"
-#include "net/base/escape.h"
-#include "net/url_request/url_request.h"
-
-namespace {
-
-const char kHtmlHeader[] =
-    "<!DOCTYPE html>\n<html>\n<head>\n<title>TopSites Thumbnails</title>\n"
-    "<meta charset=\"utf-8\">\n"
-    "<style type=\"text/css\">\nimg.thumb {border: 1px solid black;}\n"
-    "li {white-space: nowrap;}\n</style>\n";
-const char kHtmlBody[] = "</head>\n<body>\n";
-const char kHtmlFooter[] = "</body>\n</html>\n";
-
-// If |want_thumbnails| == true, then renders elements in |mvurl_list| that have
-// thumbnails, with their thumbnails. Otherwise renders elements in |mvurl_list|
-// that have no thumbnails.
-void RenderMostVisitedURLList(
-    const history::MostVisitedURLList& mvurl_list,
-    const std::vector<std::string>& base64_encoded_pngs,
-    bool want_thumbnails,
-    std::vector<std::string>* out) {
-  DCHECK_EQ(mvurl_list.size(), base64_encoded_pngs.size());
-  bool doing_forced_urls = true;
-  out->push_back("<div><b>Forced URLs:</b></div>\n"
-                 "<div><ul>\n");
-  for (size_t i = 0; i < mvurl_list.size(); ++i) {
-    const history::MostVisitedURL& mvurl = mvurl_list[i];
-    if (doing_forced_urls && mvurl.last_forced_time.is_null()) {
-      out->push_back("</ul></div>\n"
-                     "<div><b>Non-forced URLs:</b></div>\n"
-                     "<div><ul>\n");
-      doing_forced_urls = false;
-    }
-    bool has_thumbnail = !base64_encoded_pngs[i].empty();
-    if (has_thumbnail == want_thumbnails) {
-      out->push_back("<li>\n");
-      out->push_back(net::EscapeForHTML(mvurl.url.spec()) + "\n");
-      if (want_thumbnails) {
-        out->push_back("<div><img class=\"thumb\" "
-                       "src=\"data:image/png;base64," +
-                       base64_encoded_pngs[i] + "\"/></div>\n");
-      }
-      if (!mvurl.redirects.empty()) {
-        out->push_back("<ul>\n");
-        history::RedirectList::const_iterator jt;
-        for (jt = mvurl.redirects.begin();
-             jt != mvurl.redirects.end(); ++jt) {
-          out->push_back("<li>" + net::EscapeForHTML(jt->spec()) + "</li>\n");
-        }
-        out->push_back("</ul>\n");
-      }
-      out->push_back("</li>\n");
-    }
-  }
-  out->push_back("</ul></div>\n");
-}
-
-}  // namespace
-
-ThumbnailListSource::ThumbnailListSource(Profile* profile)
-    : thumbnail_service_(ThumbnailServiceFactory::GetForProfile(profile)),
-      profile_(profile),
-      weak_ptr_factory_(this) {
-}
-
-ThumbnailListSource::~ThumbnailListSource() {
-}
-
-std::string ThumbnailListSource::GetSource() const {
-  return chrome::kChromeUIThumbnailListHost;
-}
-
-void ThumbnailListSource::StartDataRequest(
-    const std::string& path,
-    int render_process_id,
-    int render_frame_id,
-    const content::URLDataSource::GotDataCallback& callback) {
-  profile_->GetTopSites()->GetMostVisitedURLs(
-      base::Bind(&ThumbnailListSource::OnMostVisitedURLsAvailable,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 callback), true);
-}
-
-std::string ThumbnailListSource::GetMimeType(const std::string& path) const {
-  return "text/html";
-}
-
-base::MessageLoop* ThumbnailListSource::MessageLoopForRequestPath(
-    const std::string& path) const {
-  // TopSites can be accessed from the IO thread.
-  return thumbnail_service_.get() ?
-      NULL : content::URLDataSource::MessageLoopForRequestPath(path);
-}
-
-bool ThumbnailListSource::ShouldServiceRequest(
-    const net::URLRequest* request) const {
-  if (request->url().SchemeIs(chrome::kChromeSearchScheme))
-    return InstantIOContext::ShouldServiceRequest(request);
-  return URLDataSource::ShouldServiceRequest(request);
-}
-
-void ThumbnailListSource::OnMostVisitedURLsAvailable(
-    const content::URLDataSource::GotDataCallback& callback,
-    const history::MostVisitedURLList& mvurl_list) {
-  const size_t num_mv = mvurl_list.size();
-  size_t num_mv_with_thumb = 0;
-
-  // Encode all available thumbnails and store into |base64_encoded_pngs|.
-  std::vector<std::string> base64_encoded_pngs(num_mv);
-  for (size_t i = 0; i < num_mv; ++i) {
-    scoped_refptr<base::RefCountedMemory> data;
-    if (thumbnail_service_->GetPageThumbnail(mvurl_list[i].url, false, &data)) {
-      base::Base64Encode(std::string(data->front_as<char>(), data->size()),
-                         &base64_encoded_pngs[i]);
-      ++num_mv_with_thumb;
-    }
-  }
-
-  // Render HTML to embed URLs and thumbnails.
-  std::vector<std::string> out;
-  out.push_back(kHtmlHeader);
-  out.push_back(kHtmlBody);
-  if (num_mv_with_thumb > 0) {
-    out.push_back("<h2>TopSites URLs with Thumbnails</h2>\n");
-    RenderMostVisitedURLList(mvurl_list, base64_encoded_pngs, true, &out);
-  }
-  if (num_mv_with_thumb < num_mv) {
-    out.push_back("<h2>TopSites URLs without Thumbnails</h2>\n");
-    RenderMostVisitedURLList(mvurl_list, base64_encoded_pngs, false, &out);
-  }
-  out.push_back(kHtmlFooter);
-
-  std::string out_html = JoinString(out, "");
-  callback.Run(base::RefCountedString::TakeString(&out_html));
-}
diff --git a/chrome/browser/ui/webui/ntp/thumbnail_list_source.h b/chrome/browser/ui/webui/ntp/thumbnail_list_source.h
deleted file mode 100644
index 605c9c2..0000000
--- a/chrome/browser/ui/webui/ntp/thumbnail_list_source.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_UI_WEBUI_NTP_THUMBNAIL_LIST_SOURCE_H_
-#define CHROME_BROWSER_UI_WEBUI_NTP_THUMBNAIL_LIST_SOURCE_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/history/history_types.h"
-#include "content/public/browser/url_data_source.h"
-
-class Profile;
-
-namespace base {
-class RefCountedMemory;
-}
-
-namespace thumbnails {
-class ThumbnailService;
-}
-
-// ThumbnailListSource renders a webpage to list all thumbnails stored in
-// TopSites, along with all associated URLs. The thumbnail images are embedded
-// into the HTML via Base64, so we can easily produce a dump of TopSites and
-// the thumbnails it stores.
-class ThumbnailListSource : public content::URLDataSource {
- public:
-  explicit ThumbnailListSource(Profile* profile);
-
-  // content::URLDataSource implementation.
-  virtual std::string GetSource() const OVERRIDE;
-  virtual void StartDataRequest(
-      const std::string& path,
-      int render_process_id,
-      int render_frame_id,
-      const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
-  virtual std::string GetMimeType(const std::string& path) const OVERRIDE;
-  virtual base::MessageLoop* MessageLoopForRequestPath(
-      const std::string& path) const OVERRIDE;
-  virtual bool ShouldServiceRequest(
-      const net::URLRequest* request) const OVERRIDE;
-
- private:
-  virtual ~ThumbnailListSource();
-
-  void OnMostVisitedURLsAvailable(
-    const content::URLDataSource::GotDataCallback& callback,
-    const history::MostVisitedURLList& mvurl_list);
-
-  // ThumbnailService.
-  scoped_refptr<thumbnails::ThumbnailService> thumbnail_service_;
-
-  // Only used when servicing requests on the UI thread.
-  Profile* const profile_;
-
-  // For callbacks may be run after destruction.
-  base::WeakPtrFactory<ThumbnailListSource> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(ThumbnailListSource);
-};
-
-
-#endif  // CHROME_BROWSER_UI_WEBUI_NTP_THUMBNAIL_LIST_SOURCE_H_
diff --git a/chrome/browser/ui/webui/options/advanced_options_utils_win.cc b/chrome/browser/ui/webui/options/advanced_options_utils_win.cc
index ac1ca82..de9080e 100644
--- a/chrome/browser/ui/webui/options/advanced_options_utils_win.cc
+++ b/chrome/browser/ui/webui/options/advanced_options_utils_win.cc
@@ -15,7 +15,6 @@
 #include "chrome/browser/browser_process.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/views/win/hwnd_util.h"
 
 using content::BrowserThread;
@@ -62,7 +61,7 @@
   CRYPTUI_CERT_MGR_STRUCT cert_mgr = { 0 };
   cert_mgr.dwSize = sizeof(CRYPTUI_CERT_MGR_STRUCT);
   cert_mgr.hwndParent = views::HWNDForNativeWindow(
-      web_contents->GetView()->GetTopLevelNativeWindow());
+      web_contents->GetTopLevelNativeWindow());
   ::CryptUIDlgCertMgr(&cert_mgr);
 }
 
diff --git a/chrome/browser/ui/webui/options/autofill_options_browsertest.js b/chrome/browser/ui/webui/options/autofill_options_browsertest.js
index 690f292..4cbd76d 100644
--- a/chrome/browser/ui/webui/options/autofill_options_browsertest.js
+++ b/chrome/browser/ui/webui/options/autofill_options_browsertest.js
@@ -3,6 +3,26 @@
 // found in the LICENSE file.
 
 /**
+ * Returns the HTML element for the |field|.
+ * @param {string} field The field name for the element.
+ * @return {HTMLElement} The HTML element.
+ */
+function getField(field) {
+  return document.querySelector(
+      '#autofill-edit-address-overlay [field=' + field + ']');
+}
+
+/**
+ * Returns the size of the |list|.
+ * @param {HTMLElement} list The list to check.
+ * @return {int} The size of the list.
+ */
+function getListSize(list) {
+  // Remove 1 for placeholder input field.
+  return list.items.length - 1;
+}
+
+/**
  * TestFixture for autofill options WebUI testing.
  * @extends {testing.Test}
  * @constructor
@@ -47,7 +67,7 @@
        function() {
   assertEquals(this.browsePreload, document.location.href);
 
-  var phoneList = $('phone-list');
+  var phoneList = getField('phone');
   expectEquals(0, phoneList.validationRequests_);
   phoneList.doneValidating().then(function() {
     phoneList.focus();
@@ -61,3 +81,99 @@
     });
   });
 });
+
+TEST_F('AutofillEditAddressWebUITest',
+       'testInitialFormLayout',
+       function() {
+  assertEquals(this.browsePreload, document.location.href);
+
+  assertEquals(getField('country').value, '');
+  assertEquals(0, getListSize(getField('phone')));
+  assertEquals(0, getListSize(getField('email')));
+  assertEquals(0, getListSize(getField('fullName')));
+  assertEquals('', getField('city').value);
+
+  testDone();
+});
+
+TEST_F('AutofillEditAddressWebUITest',
+       'testLoadAddress',
+       function() {
+  assertEquals(this.browsePreload, document.location.href);
+
+  var testAddress = {
+    guid: 'GUID Value',
+    fullName: ['Full Name 1', 'Full Name 2'],
+    companyName: 'Company Name Value',
+    addrLines: 'First Line Value\nSecond Line Value',
+    dependentLocality: 'Dependent Locality Value',
+    city: 'City Value',
+    state: 'State Value',
+    postalCode: 'Postal Code Value',
+    sortingCode: 'Sorting Code Value',
+    country: 'CH',
+    phone: ['123', '456'],
+    email: ['a@b.c', 'x@y.z'],
+    languageCode: 'de',
+    components: [[
+       {field: 'postalCode', length: 'short'},
+       {field: 'sortingCode', length: 'short'},
+       {field: 'dependentLocality', length: 'short'},
+       {field: 'city', length: 'short'},
+       {field: 'state', length: 'short'},
+       {field: 'addrLines', length: 'long'},
+       {field: 'companyName', length: 'long'},
+       {field: 'country', length: 'long'},
+       {field: 'fullName', length: 'long', placeholder: 'Add name'}
+    ]]
+  };
+  AutofillEditAddressOverlay.loadAddress(testAddress);
+
+  assertEquals(testAddress.guid, AutofillEditAddressOverlay.getInstance().guid);
+  assertEquals(testAddress.languageCode,
+               AutofillEditAddressOverlay.getInstance().languageCode);
+
+  var lists = ['fullName', 'email', 'phone'];
+  for (var i in lists) {
+    var field = getField(lists[i]);
+    assertEquals(testAddress[lists[i]].length, getListSize(field));
+    assertTrue(field.getAttribute('placeholder').length > 0);
+    assertTrue(field instanceof cr.ui.List);
+  }
+
+  var inputs = ['companyName', 'dependentLocality', 'city', 'state',
+                'postalCode', 'sortingCode'];
+  for (var i in inputs) {
+    var field = getField(inputs[i]);
+    assertEquals(testAddress[inputs[i]], field.value);
+    assertTrue(field instanceof HTMLInputElement);
+  }
+
+  var addrLines = getField('addrLines');
+  assertEquals(testAddress.addrLines, addrLines.value);
+  assertTrue(addrLines instanceof HTMLTextAreaElement);
+
+  var country = getField('country');
+  assertEquals(testAddress.country, country.value);
+  assertTrue(country instanceof HTMLSelectElement);
+
+  testDone();
+});
+
+TEST_F('AutofillEditAddressWebUITest',
+       'testLoadAddressComponents',
+       function() {
+  assertEquals(this.browsePreload, document.location.href);
+
+  var testInput = {
+    languageCode: 'fr',
+    components: [[{field: 'city'}],
+                 [{field: 'state'}]]
+  };
+  AutofillEditAddressOverlay.loadAddressComponents(testInput);
+
+  assertEquals('fr', AutofillEditAddressOverlay.getInstance().languageCode);
+  expectEquals(2, $('autofill-edit-address-fields').children.length);
+
+  testDone();
+});
diff --git a/chrome/browser/ui/webui/options/autofill_options_handler.cc b/chrome/browser/ui/webui/options/autofill_options_handler.cc
index 60b5aeb..93b2351 100644
--- a/chrome/browser/ui/webui/options/autofill_options_handler.cc
+++ b/chrome/browser/ui/webui/options/autofill_options_handler.cc
@@ -28,6 +28,9 @@
 #include "content/public/browser/web_ui.h"
 #include "grit/component_strings.h"
 #include "grit/generated_resources.h"
+#include "grit/libaddressinput_strings.h"
+#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui.h"
+#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui_component.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/webui/web_ui_util.h"
 
@@ -36,11 +39,107 @@
 using autofill::AutofillProfile;
 using autofill::CreditCard;
 using autofill::PersonalDataManager;
+using i18n::addressinput::AddressUiComponent;
 
 namespace {
 
 const char kSettingsOrigin[] = "Chrome settings";
 
+static const char kFullNameField[] = "fullName";
+static const char kCompanyNameField[] = "companyName";
+static const char kAddressLineField[] = "addrLines";
+static const char kDependentLocalityField[] = "dependentLocality";
+static const char kCityField[] = "city";
+static const char kStateField[] = "state";
+static const char kPostalCodeField[] = "postalCode";
+static const char kSortingCodeField[] = "sortingCode";
+static const char kCountryField[] = "country";
+
+static const char kComponents[] = "components";
+static const char kLanguageCode[] = "languageCode";
+
+// Fills |components| with the address UI components that should be used to
+// input an address for |country_code| when UI BCP 47 language code is
+// |ui_language_code|. If |components_language_code| is not NULL, then sets it
+// to the BCP 47 language code that should be used to format the address for
+// display.
+void GetAddressComponents(const std::string& country_code,
+                          const std::string& ui_language_code,
+                          base::ListValue* address_components,
+                          std::string* components_language_code) {
+  DCHECK(address_components);
+
+  std::vector<AddressUiComponent> components =
+      i18n::addressinput::BuildComponents(
+          country_code, ui_language_code, components_language_code);
+  if (components.empty()) {
+    static const char kDefaultCountryCode[] = "US";
+    components = i18n::addressinput::BuildComponents(
+        kDefaultCountryCode, ui_language_code, components_language_code);
+  }
+  DCHECK(!components.empty());
+
+  base::ListValue* line = NULL;
+  static const char kField[] = "field";
+  static const char kLength[] = "length";
+  for (size_t i = 0; i < components.size(); ++i) {
+    if (i == 0 ||
+        components[i - 1].length_hint == AddressUiComponent::HINT_LONG ||
+        components[i].length_hint == AddressUiComponent::HINT_LONG) {
+      line = new base::ListValue;
+      address_components->Append(line);
+    }
+
+    scoped_ptr<base::DictionaryValue> component(new base::DictionaryValue);
+    component->SetString(
+        "name", l10n_util::GetStringUTF16(components[i].name_id));
+
+    switch (components[i].field) {
+      case i18n::addressinput::COUNTRY:
+        component->SetString(kField, kCountryField);
+        break;
+      case i18n::addressinput::ADMIN_AREA:
+        component->SetString(kField, kStateField);
+        break;
+      case i18n::addressinput::LOCALITY:
+        component->SetString(kField, kCityField);
+        break;
+      case i18n::addressinput::DEPENDENT_LOCALITY:
+        component->SetString(kField, kDependentLocalityField);
+        break;
+      case i18n::addressinput::SORTING_CODE:
+        component->SetString(kField, kSortingCodeField);
+        break;
+      case i18n::addressinput::POSTAL_CODE:
+        component->SetString(kField, kPostalCodeField);
+        break;
+      case i18n::addressinput::STREET_ADDRESS:
+        component->SetString(kField, kAddressLineField);
+        break;
+      case i18n::addressinput::ORGANIZATION:
+        component->SetString(kField, kCompanyNameField);
+        break;
+      case i18n::addressinput::RECIPIENT:
+        component->SetString(kField, kFullNameField);
+        component->SetString(
+            "placeholder",
+            l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_NAME));
+        break;
+    }
+
+    switch (components[i].length_hint) {
+      case AddressUiComponent::HINT_LONG:
+        component->SetString(kLength, "long");
+        break;
+      case AddressUiComponent::HINT_SHORT:
+        component->SetString(kLength, "short");
+        break;
+    }
+
+    line->Append(component.release());
+  }
+}
+
 // Sets data related to the country <select>.
 void SetCountryData(const PersonalDataManager& manager,
                     base::DictionaryValue* localized_strings) {
@@ -52,8 +151,6 @@
 
   // An ordered list of options to show in the <select>.
   scoped_ptr<base::ListValue> country_list(new base::ListValue());
-  // A dictionary of postal code and state info, keyed on country code.
-  scoped_ptr<base::DictionaryValue> country_data(new base::DictionaryValue());
   for (size_t i = 0; i < countries.size(); ++i) {
     scoped_ptr<base::DictionaryValue> option_details(
         new base::DictionaryValue());
@@ -62,18 +159,19 @@
         "value",
         countries[i] ? countries[i]->country_code() : "separator");
     country_list->Append(option_details.release());
-
-    if (!countries[i])
-      continue;
-
-    scoped_ptr<base::DictionaryValue> details(new base::DictionaryValue());
-    details->SetString("postalCodeLabel", countries[i]->postal_code_label());
-    details->SetString("stateLabel", countries[i]->state_label());
-    country_data->Set(countries[i]->country_code(), details.release());
-
   }
   localized_strings->Set("autofillCountrySelectList", country_list.release());
-  localized_strings->Set("autofillCountryData", country_data.release());
+
+  scoped_ptr<base::ListValue> defaultCountryComponents(new base::ListValue);
+  std::string defaultCountryLanguageCode;
+  GetAddressComponents(countries.front()->country_code(),
+                       g_browser_process->GetApplicationLocale(),
+                       defaultCountryComponents.get(),
+                       &defaultCountryLanguageCode);
+  localized_strings->Set("autofillDefaultCountryComponents",
+                         defaultCountryComponents.release());
+  localized_strings->SetString("autofillDefaultCountryLanguageCode",
+                               defaultCountryLanguageCode);
 }
 
 // Get the multi-valued element for |type| and return it in |ListValue| form.
@@ -107,68 +205,6 @@
   profile->SetRawMultiInfo(type, values);
 }
 
-// Get the multi-valued element for |type| and return it in |ListValue| form.
-void GetNameList(const AutofillProfile& profile,
-                 scoped_ptr<base::ListValue>* names) {
-  names->reset(new base::ListValue);
-
-  std::vector<base::string16> first_names;
-  std::vector<base::string16> middle_names;
-  std::vector<base::string16> last_names;
-  profile.GetRawMultiInfo(autofill::NAME_FIRST, &first_names);
-  profile.GetRawMultiInfo(autofill::NAME_MIDDLE, &middle_names);
-  profile.GetRawMultiInfo(autofill::NAME_LAST, &last_names);
-  DCHECK_EQ(first_names.size(), middle_names.size());
-  DCHECK_EQ(first_names.size(), last_names.size());
-
-  // |GetRawMultiInfo()| always returns at least one, potentially empty, item.
-  if (first_names.size() == 1 && first_names.front().empty() &&
-      middle_names.front().empty() && last_names.front().empty()) {
-    return;
-  }
-
-  for (size_t i = 0; i < first_names.size(); ++i) {
-    base::ListValue* name = new base::ListValue;  // owned by |list|
-    name->Set(0, new base::StringValue(first_names[i]));
-    name->Set(1, new base::StringValue(middle_names[i]));
-    name->Set(2, new base::StringValue(last_names[i]));
-    (*names)->Set(i, name);
-  }
-}
-
-// Set the multi-valued element for |type| from input |list| values.
-void SetNameList(const base::ListValue* names, AutofillProfile* profile) {
-  const size_t size = names->GetSize();
-  std::vector<base::string16> first_names(size);
-  std::vector<base::string16> middle_names(size);
-  std::vector<base::string16> last_names(size);
-
-  for (size_t i = 0; i < size; ++i) {
-    const base::ListValue* name;
-    bool success = names->GetList(i, &name);
-    DCHECK(success);
-
-    base::string16 first_name;
-    success = name->GetString(0, &first_name);
-    DCHECK(success);
-    first_names[i] = first_name;
-
-    base::string16 middle_name;
-    success = name->GetString(1, &middle_name);
-    DCHECK(success);
-    middle_names[i] = middle_name;
-
-    base::string16 last_name;
-    success = name->GetString(2, &last_name);
-    DCHECK(success);
-    last_names[i] = last_name;
-  }
-
-  profile->SetRawMultiInfo(autofill::NAME_FIRST, first_names);
-  profile->SetRawMultiInfo(autofill::NAME_MIDDLE, middle_names);
-  profile->SetRawMultiInfo(autofill::NAME_LAST, last_names);
-}
-
 // Pulls the phone number |index|, |phone_number_list|, and |country_code| from
 // the |args| input.
 void ExtractPhoneNumberInformation(const base::ListValue* args,
@@ -306,6 +342,10 @@
       base::Bind(&AutofillOptionsHandler::LoadAddressEditor,
                  base::Unretained(this)));
   web_ui()->RegisterMessageCallback(
+      "loadAddressEditorComponents",
+      base::Bind(&AutofillOptionsHandler::LoadAddressEditorComponents,
+                 base::Unretained(this)));
+  web_ui()->RegisterMessageCallback(
       "loadCreditCardEditor",
       base::Bind(&AutofillOptionsHandler::LoadCreditCardEditor,
                  base::Unretained(this)));
@@ -332,32 +372,12 @@
     base::DictionaryValue* localized_strings) {
   localized_strings->SetString("autofillEditAddressTitle",
       l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_ADDRESS_CAPTION));
-  localized_strings->SetString("autofillFirstNameLabel",
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_FIRST_NAME));
-  localized_strings->SetString("autofillMiddleNameLabel",
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_MIDDLE_NAME));
-  localized_strings->SetString("autofillLastNameLabel",
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_LAST_NAME));
-  localized_strings->SetString("autofillCompanyNameLabel",
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_COMPANY_NAME));
-  localized_strings->SetString("autofillAddrLine1Label",
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADDRESS_LINE_1));
-  localized_strings->SetString("autofillAddrLine2Label",
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADDRESS_LINE_2));
-  localized_strings->SetString("autofillCityLabel",
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_CITY));
   localized_strings->SetString("autofillCountryLabel",
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_COUNTRY));
+      l10n_util::GetStringUTF16(IDS_LIBADDRESSINPUT_I18N_COUNTRY_LABEL));
   localized_strings->SetString("autofillPhoneLabel",
       l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_PHONE));
   localized_strings->SetString("autofillEmailLabel",
       l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EMAIL));
-  localized_strings->SetString("autofillAddFirstNamePlaceholder",
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_FIRST_NAME));
-  localized_strings->SetString("autofillAddMiddleNamePlaceholder",
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_MIDDLE_NAME));
-  localized_strings->SetString("autofillAddLastNamePlaceholder",
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_LAST_NAME));
   localized_strings->SetString("autofillAddPhonePlaceholder",
       l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_PHONE));
   localized_strings->SetString("autofillAddEmailPlaceholder",
@@ -451,27 +471,60 @@
   base::DictionaryValue address;
   address.SetString("guid", profile->guid());
   scoped_ptr<base::ListValue> list;
-  GetNameList(*profile, &list);
-  address.Set("fullName", list.release());
-  address.SetString("companyName", profile->GetRawInfo(autofill::COMPANY_NAME));
-  address.SetString("addrLine1",
-                    profile->GetRawInfo(autofill::ADDRESS_HOME_LINE1));
-  address.SetString("addrLine2",
-                    profile->GetRawInfo(autofill::ADDRESS_HOME_LINE2));
-  address.SetString("city", profile->GetRawInfo(autofill::ADDRESS_HOME_CITY));
-  address.SetString("state", profile->GetRawInfo(autofill::ADDRESS_HOME_STATE));
-  address.SetString("postalCode",
+  GetValueList(*profile, autofill::NAME_FULL, &list);
+  address.Set(kFullNameField, list.release());
+  address.SetString(
+      kCompanyNameField, profile->GetRawInfo(autofill::COMPANY_NAME));
+  address.SetString(kAddressLineField,
+                    profile->GetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS));
+  address.SetString(
+      kCityField, profile->GetRawInfo(autofill::ADDRESS_HOME_CITY));
+  address.SetString(
+      kStateField, profile->GetRawInfo(autofill::ADDRESS_HOME_STATE));
+  address.SetString(
+      kDependentLocalityField,
+      profile->GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY));
+  address.SetString(kSortingCodeField,
+                    profile->GetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE));
+  address.SetString(kPostalCodeField,
                     profile->GetRawInfo(autofill::ADDRESS_HOME_ZIP));
-  address.SetString("country",
+  address.SetString(kCountryField,
                     profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY));
   GetValueList(*profile, autofill::PHONE_HOME_WHOLE_NUMBER, &list);
   address.Set("phone", list.release());
   GetValueList(*profile, autofill::EMAIL_ADDRESS, &list);
   address.Set("email", list.release());
+  address.SetString(kLanguageCode, profile->language_code());
+
+  scoped_ptr<base::ListValue> components(new base::ListValue);
+  GetAddressComponents(
+      base::UTF16ToUTF8(profile->GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)),
+      profile->language_code(), components.get(), NULL);
+  address.Set(kComponents, components.release());
 
   web_ui()->CallJavascriptFunction("AutofillOptions.editAddress", address);
 }
 
+void AutofillOptionsHandler::LoadAddressEditorComponents(
+    const base::ListValue* args) {
+  std::string country_code;
+  if (!args->GetString(0, &country_code)) {
+    NOTREACHED();
+    return;
+  }
+
+  base::DictionaryValue input;
+  scoped_ptr<base::ListValue> components(new base::ListValue);
+  std::string language_code;
+  GetAddressComponents(country_code, g_browser_process->GetApplicationLocale(),
+                       components.get(), &language_code);
+  input.Set(kComponents, components.release());
+  input.SetString(kLanguageCode, language_code);
+
+  web_ui()->CallJavascriptFunction(
+      "AutofillEditAddressOverlay.loadAddressComponents", input);
+}
+
 void AutofillOptionsHandler::LoadCreditCardEditor(const base::ListValue* args) {
   DCHECK(IsPersonalDataLoaded());
 
@@ -514,48 +567,53 @@
   if (!IsPersonalDataLoaded())
     return;
 
+  int arg_counter = 0;
   std::string guid;
-  if (!args->GetString(0, &guid)) {
+  if (!args->GetString(arg_counter++, &guid)) {
     NOTREACHED();
     return;
   }
 
   AutofillProfile profile(guid, kSettingsOrigin);
 
-  std::string country_code;
   base::string16 value;
   const base::ListValue* list_value;
-  if (args->GetList(1, &list_value))
-    SetNameList(list_value, &profile);
+  if (args->GetList(arg_counter++, &list_value))
+    SetValueList(list_value, autofill::NAME_FULL, &profile);
 
-  if (args->GetString(2, &value))
+  if (args->GetString(arg_counter++, &value))
     profile.SetRawInfo(autofill::COMPANY_NAME, value);
 
-  if (args->GetString(3, &value))
-    profile.SetRawInfo(autofill::ADDRESS_HOME_LINE1, value);
+  if (args->GetString(arg_counter++, &value))
+    profile.SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS, value);
 
-  if (args->GetString(4, &value))
-    profile.SetRawInfo(autofill::ADDRESS_HOME_LINE2, value);
+  if (args->GetString(arg_counter++, &value))
+    profile.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY, value);
 
-  if (args->GetString(5, &value))
+  if (args->GetString(arg_counter++, &value))
     profile.SetRawInfo(autofill::ADDRESS_HOME_CITY, value);
 
-  if (args->GetString(6, &value))
+  if (args->GetString(arg_counter++, &value))
     profile.SetRawInfo(autofill::ADDRESS_HOME_STATE, value);
 
-  if (args->GetString(7, &value))
+  if (args->GetString(arg_counter++, &value))
     profile.SetRawInfo(autofill::ADDRESS_HOME_ZIP, value);
 
-  if (args->GetString(8, &country_code))
-    profile.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY,
-                       base::ASCIIToUTF16(country_code));
+  if (args->GetString(arg_counter++, &value))
+    profile.SetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE, value);
 
-  if (args->GetList(9, &list_value))
+  if (args->GetString(arg_counter++, &value))
+    profile.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY, value);
+
+  if (args->GetList(arg_counter++, &list_value))
     SetValueList(list_value, autofill::PHONE_HOME_WHOLE_NUMBER, &profile);
 
-  if (args->GetList(10, &list_value))
+  if (args->GetList(arg_counter++, &list_value))
     SetValueList(list_value, autofill::EMAIL_ADDRESS, &profile);
 
+  if (args->GetString(arg_counter++, &value))
+    profile.set_language_code(base::UTF16ToUTF8(value));
+
   if (!base::IsValidGUID(profile.guid())) {
     profile.set_guid(base::GenerateGUID());
     personal_data_->AddProfile(profile);
diff --git a/chrome/browser/ui/webui/options/autofill_options_handler.h b/chrome/browser/ui/webui/options/autofill_options_handler.h
index 5d58d21..a98a986 100644
--- a/chrome/browser/ui/webui/options/autofill_options_handler.h
+++ b/chrome/browser/ui/webui/options/autofill_options_handler.h
@@ -55,6 +55,11 @@
   // |args| - A string, the GUID of the address to load.
   void LoadAddressEditor(const base::ListValue* args);
 
+  // Requests input form layout information for a specific country code. Calls
+  // into WebUI with the layout information.
+  // |args| - A string, the country code to load.
+  void LoadAddressEditorComponents(const base::ListValue* args);
+
   // Requests profile data for a specific credit card. Calls into WebUI with the
   // loaded profile data to open the credit card editor.
   // |args| - A string, the GUID of the credit card to load.
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc
index 3b0907e..147df63 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.cc
+++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -82,8 +82,8 @@
 #include "content/public/browser/url_data_source.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/page_zoom.h"
+#include "extensions/browser/extension_registry.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "grit/chromium_strings.h"
@@ -127,6 +127,7 @@
 #if defined(OS_WIN)
 #include "chrome/browser/extensions/settings_api_helpers.h"
 #include "chrome/installer/util/auto_launch_util.h"
+#include "content/public/browser/browser_url_handler.h"
 #endif  // defined(OS_WIN)
 
 #if defined(ENABLE_SERVICE_DISCOVERY)
@@ -139,6 +140,23 @@
 using content::DownloadManager;
 using content::OpenURLParams;
 using content::Referrer;
+using extensions::Extension;
+using extensions::ExtensionRegistry;
+
+namespace {
+
+#if defined(OS_WIN)
+void AppendExtensionData(const std::string& key,
+                         const Extension* extension,
+                         base::DictionaryValue* dict) {
+  scoped_ptr<base::DictionaryValue> details(new base::DictionaryValue);
+  details->SetString("id", extension ? extension->id() : std::string());
+  details->SetString("name", extension ? extension->name() : std::string());
+  dict->Set(key, details.release());
+}
+#endif  // defined(OS_WIN)
+
+}  // namespace
 
 namespace options {
 
@@ -302,7 +320,6 @@
     { "startupRestoreLastSession", IDS_OPTIONS_STARTUP_RESTORE_LAST_SESSION },
     { "settingsTitle", IDS_SETTINGS_TITLE },
     { "showAdvancedSettings", IDS_SETTINGS_SHOW_ADVANCED_SETTINGS },
-    { "sslCheckRevocation", IDS_OPTIONS_SSL_CHECKREVOCATION },
     { "startupSetPages", IDS_OPTIONS_STARTUP_SET_PAGES },
     { "startupShowNewTab", IDS_OPTIONS_STARTUP_SHOW_NEWTAB },
     { "startupShowPages", IDS_OPTIONS_STARTUP_SHOW_PAGES },
@@ -709,13 +726,16 @@
   web_ui()->RegisterMessageCallback(
       "refreshExtensionControlIndicators",
       base::Bind(
-          &BrowserOptionsHandler::SetupExtensionControlledIndicators,
+          &BrowserOptionsHandler::HandleRefreshExtensionControlIndicators,
           base::Unretained(this)));
 #endif  // defined(OS_WIN)
 }
 
 void BrowserOptionsHandler::Uninitialize() {
   registrar_.RemoveAll();
+#if defined(OS_WIN)
+  ExtensionRegistry::Get(Profile::FromWebUI(web_ui()))->RemoveObserver(this);
+#endif
 }
 
 void BrowserOptionsHandler::OnStateChanged() {
@@ -775,6 +795,8 @@
   AddTemplateUrlServiceObserver();
 
 #if defined(OS_WIN)
+  ExtensionRegistry::Get(Profile::FromWebUI(web_ui()))->AddObserver(this);
+
   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
   if (!command_line.HasSwitch(switches::kUserDataDir)) {
     BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
@@ -815,17 +837,14 @@
                  base::Unretained(this)));
 
 #if defined(OS_WIN)
-  const base::ListValue* empty = NULL;
   profile_pref_registrar_.Add(
       prefs::kURLsToRestoreOnStartup,
       base::Bind(&BrowserOptionsHandler::SetupExtensionControlledIndicators,
-                 base::Unretained(this),
-                 empty));
+                 base::Unretained(this)));
   profile_pref_registrar_.Add(
       prefs::kHomePage,
       base::Bind(&BrowserOptionsHandler::SetupExtensionControlledIndicators,
-                 base::Unretained(this),
-                 empty));
+                 base::Unretained(this)));
 #endif  // defined(OS_WIN)
 
 #if defined(OS_CHROMEOS)
@@ -868,10 +887,7 @@
   SetupManageCertificatesSection();
   SetupManagingSupervisedUsers();
   SetupEasyUnlock();
-
-#if defined(OS_WIN)
-  SetupExtensionControlledIndicators(NULL);
-#endif  // defined(OS_WIN)
+  SetupExtensionControlledIndicators();
 
 #if defined(OS_CHROMEOS)
   SetupAccessibilityFeatures();
@@ -1098,9 +1114,7 @@
           template_url_service_->is_default_search_managed() ||
           template_url_service_->IsExtensionControlledDefaultSearch()));
 
-#if defined(OS_WIN)
-  SetupExtensionControlledIndicators(NULL);
-#endif  // defined(OS_WIN)
+  SetupExtensionControlledIndicators();
 }
 
 void BrowserOptionsHandler::SetDefaultSearchEngine(
@@ -1130,6 +1144,19 @@
   }
 }
 
+void BrowserOptionsHandler::OnExtensionLoaded(
+    content::BrowserContext* browser_context,
+    const Extension* extension) {
+  SetupExtensionControlledIndicators();
+}
+
+void BrowserOptionsHandler::OnExtensionUnloaded(
+    content::BrowserContext* browser_context,
+    const Extension* extension,
+    extensions::UnloadedExtensionInfo::Reason reason) {
+  SetupExtensionControlledIndicators();
+}
+
 void BrowserOptionsHandler::Observe(
     int type,
     const content::NotificationSource& source,
@@ -1362,7 +1389,7 @@
       &info,
       0,
       base::FilePath::StringType(),
-      web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(),
+      web_ui()->GetWebContents()->GetTopLevelNativeWindow(),
       NULL);
 }
 
@@ -1527,6 +1554,11 @@
   HotwordServiceFactory::RetryHotwordExtension(Profile::FromWebUI(web_ui()));
 }
 
+void BrowserOptionsHandler::HandleRefreshExtensionControlIndicators(
+    const base::ListValue* args) {
+  SetupExtensionControlledIndicators();
+}
+
 #if defined(OS_CHROMEOS)
 void BrowserOptionsHandler::HandleOpenWallpaperManager(
     const base::ListValue* args) {
@@ -1719,38 +1751,44 @@
       has_pairing_value);
 }
 
+void BrowserOptionsHandler::SetupExtensionControlledIndicators() {
 #if defined(OS_WIN)
-// Setup the UI for showing which settings are extension controlled.
-void BrowserOptionsHandler::SetupExtensionControlledIndicators(
-    const base::ListValue* args) {
+  base::DictionaryValue extension_controlled;
+
+  // Check if an extension is overriding the Search Engine.
   const extensions::Extension* extension = extensions::OverridesSearchEngine(
       Profile::FromWebUI(web_ui()), NULL);
-  base::StringValue extension_id(extension ? extension->id() : std::string());
-  base::StringValue extension_name(
-      extension ? extension->name() : std::string());
-  web_ui()->CallJavascriptFunction(
-      "BrowserOptions.toggleSearchEngineControlled",
-      extension_id,
-      extension_name);
+  AppendExtensionData("searchEngine", extension, &extension_controlled);
 
+  // Check if an extension is overriding the Home page.
   extension = extensions::OverridesHomepage(Profile::FromWebUI(web_ui()), NULL);
-  extension_id = base::StringValue(extension ? extension->id() : std::string());
-  extension_name = base::StringValue(
-      extension ? extension->name() : std::string());
-  web_ui()->CallJavascriptFunction("BrowserOptions.toggleHomepageControlled",
-                                   extension_id,
-                                   extension_name);
+  AppendExtensionData("homePage", extension, &extension_controlled);
 
+  // Check if an extension is overriding the Startup pages.
   extension = extensions::OverridesStartupPages(
       Profile::FromWebUI(web_ui()), NULL);
-  extension_id = base::StringValue(extension ? extension->id() : std::string());
-  extension_name = base::StringValue(
-      extension ? extension->name() : std::string());
-  web_ui()->CallJavascriptFunction(
-      "BrowserOptions.toggleStartupPagesControlled",
-      extension_id,
-      extension_name);
-}
+  AppendExtensionData("startUpPage", extension, &extension_controlled);
+
+  // Check if an extension is overriding the NTP page.
+  GURL ntp_url(chrome::kChromeUINewTabURL);
+  bool ignored_param;
+  extension = NULL;
+  content::BrowserURLHandler::GetInstance()->RewriteURLIfNecessary(
+      &ntp_url,
+      web_ui()->GetWebContents()->GetBrowserContext(),
+      &ignored_param);
+  if (ntp_url.SchemeIs("chrome-extension")) {
+    using extensions::ExtensionRegistry;
+    ExtensionRegistry* registry = ExtensionRegistry::Get(
+        Profile::FromWebUI(web_ui()));
+    extension = registry->GetExtensionById(ntp_url.host(),
+                                           ExtensionRegistry::ENABLED);
+  }
+  AppendExtensionData("newTabPage", extension, &extension_controlled);
+
+  web_ui()->CallJavascriptFunction("BrowserOptions.toggleExtensionIndicators",
+                                   extension_controlled);
 #endif  // defined(OS_WIN)
+}
 
 }  // namespace options
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.h b/chrome/browser/ui/webui/options/browser_options_handler.h
index a705338..2aa6336 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.h
+++ b/chrome/browser/ui/webui/options/browser_options_handler.h
@@ -23,6 +23,7 @@
 #include "chrome/browser/ui/webui/options/options_ui.h"
 #include "components/signin/core/browser/signin_manager_base.h"
 #include "content/public/browser/notification_observer.h"
+#include "extensions/browser/extension_registry_observer.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "ui/base/models/table_model_observer.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
@@ -57,6 +58,7 @@
       public chromeos::system::PointerDeviceObserver::Observer,
 #endif
       public TemplateURLServiceObserver,
+      public extensions::ExtensionRegistryObserver,
       public content::NotificationObserver {
  public:
   BrowserOptionsHandler();
@@ -86,6 +88,15 @@
   // TemplateURLServiceObserver implementation.
   virtual void OnTemplateURLServiceChanged() OVERRIDE;
 
+  // extensions::ExtensionRegistryObserver:
+  virtual void OnExtensionLoaded(
+      content::BrowserContext* browser_context,
+      const extensions::Extension* extension) OVERRIDE;
+  virtual void OnExtensionUnloaded(
+      content::BrowserContext* browser_context,
+      const extensions::Extension* extension,
+      extensions::UnloadedExtensionInfo::Reason reason) OVERRIDE;
+
  private:
   // content::NotificationObserver implementation.
   virtual void Observe(int type,
@@ -270,6 +281,9 @@
   // Callback for "launchEasyUnlockSetup" message.
   void HandleLaunchEasyUnlockSetup(const base::ListValue* args);
 
+  // Callback for "refreshExtensionControlIndicators" message.
+  void HandleRefreshExtensionControlIndicators(const base::ListValue* args);
+
 #if defined(OS_CHROMEOS)
   // Opens the wallpaper manager component extension.
   void HandleOpenWallpaperManager(const base::ListValue* args);
@@ -311,10 +325,8 @@
   // Setup the UI for Easy Unlock.
   void SetupEasyUnlock();
 
-#if defined(OS_WIN)
   // Setup the UI for showing which settings are extension controlled.
-  void SetupExtensionControlledIndicators(const base::ListValue* args);
-#endif
+  void SetupExtensionControlledIndicators();
 
 #if defined(OS_CHROMEOS)
   // Setup the accessibility features for ChromeOS.
diff --git a/chrome/browser/ui/webui/options/certificate_manager_browsertest.js b/chrome/browser/ui/webui/options/certificate_manager_browsertest.js
index 693ccec..9019c69 100644
--- a/chrome/browser/ui/webui/options/certificate_manager_browsertest.js
+++ b/chrome/browser/ui/webui/options/certificate_manager_browsertest.js
@@ -21,7 +21,7 @@
    */
   browsePreload: 'chrome://settings-frame/certificates',
 
-  /** @inheritDoc */
+  /** @override */
   preLoad: function() {
     // We can't check cr.isChromeOS in the preLoad since "cr" doesn't exist yet.
     // This is copied from ui/webui/resources/js/cr.js, maybe
@@ -52,7 +52,7 @@
 CertificateManagerWebUIUnpopulatedTest.prototype = {
   __proto__: CertificateManagerWebUIBaseTest.prototype,
 
-  /** @inheritDoc */
+  /** @override */
   preLoad: function() {
     CertificateManagerWebUIBaseTest.prototype.preLoad.call(this);
 
@@ -147,7 +147,7 @@
 CertificateManagerWebUITest.prototype = {
   __proto__: CertificateManagerWebUIBaseTest.prototype,
 
-  /** @inheritDoc */
+  /** @override */
   preLoad: function() {
     CertificateManagerWebUIBaseTest.prototype.preLoad.call(this);
 
diff --git a/chrome/browser/ui/webui/options/certificate_manager_handler.cc b/chrome/browser/ui/webui/options/certificate_manager_handler.cc
index a94fd71..f5d3573 100644
--- a/chrome/browser/ui/webui/options/certificate_manager_handler.cc
+++ b/chrome/browser/ui/webui/options/certificate_manager_handler.cc
@@ -26,7 +26,6 @@
 #include "chrome/browser/ui/webui/certificate_viewer_webui.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "grit/generated_resources.h"
 #include "net/base/crypto_module.h"
 #include "net/base/net_errors.h"
@@ -1154,7 +1153,7 @@
 }
 
 gfx::NativeWindow CertificateManagerHandler::GetParentWindow() const {
-  return web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow();
+  return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
 }
 
 }  // namespace options
diff --git a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_browsertest.js b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_browsertest.js
index 777f062..43343fb 100644
--- a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_browsertest.js
+++ b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_browsertest.js
@@ -15,7 +15,7 @@
   browsePreload: 'chrome://settings-frame/settings',
 
   /**
-   * @inheritDoc
+   * @override
    */
   preLoad: function() {
     this.makeAndRegisterMockHandler([
@@ -68,7 +68,7 @@
 
 };
 
-TEST_F('BluetoothWebUITest','testEnableBluetooth', function() {
+TEST_F('BluetoothWebUITest', 'testEnableBluetooth', function() {
   assertEquals(this.browsePreload, document.location.href);
   expectFalse($('enable-bluetooth').checked);
   expectTrue($('bluetooth-paired-devices-list').parentNode.hidden);
@@ -82,7 +82,7 @@
   expectFalse($('bluetooth-paired-devices-list').parentNode.hidden);
 });
 
-TEST_F('BluetoothWebUITest','testAddDevices', function() {
+TEST_F('BluetoothWebUITest', 'testAddDevices', function() {
   assertEquals(this.browsePreload, document.location.href);
 
   var pairedDeviceList = $('bluetooth-paired-devices-list');
@@ -166,7 +166,7 @@
   connectButton.click();
 });
 
-TEST_F('BluetoothWebUITest','testDevicePairing', function() {
+TEST_F('BluetoothWebUITest', 'testDevicePairing', function() {
   assertEquals(this.browsePreload, document.location.href);
 
   var pairedDeviceList = $('bluetooth-paired-devices-list');
@@ -224,7 +224,7 @@
                                          fakeDevice.name));
 });
 
-TEST_F('BluetoothWebUITest','testConnectionState', function() {
+TEST_F('BluetoothWebUITest', 'testConnectionState', function() {
   assertEquals(this.browsePreload, document.location.href);
 
   var pairedDeviceList = $('bluetooth-paired-devices-list');
@@ -295,7 +295,7 @@
 });
 
 
-TEST_F('BluetoothWebUITest','testMaliciousInput', function() {
+TEST_F('BluetoothWebUITest', 'testMaliciousInput', function() {
   assertEquals(this.browsePreload, document.location.href);
 
   var unpairedDeviceList = $('bluetooth-unpaired-devices-list');
diff --git a/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc
index f78d184..de42877 100644
--- a/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/date_time_options_handler.cc
@@ -11,7 +11,6 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/system_clock_client.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -73,7 +72,7 @@
   // Make sure the clock status hasn't changed since the button was clicked.
   if (can_set_time_) {
     SetTimeDialog::ShowDialog(
-        web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow());
+        web_ui()->GetWebContents()->GetTopLevelNativeWindow());
   }
 }
 
diff --git a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
index 668455d..679bffb 100644
--- a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
@@ -142,7 +142,6 @@
   scoped_ptr<base::ListValue> js_resolutions(new base::ListValue);
 
   gfx::Size current_size = display_info.bounds_in_native().size();
-  gfx::Insets current_overscan = display_info.GetOverscanInsetsInPixel();
   int largest_index = -1;
   int largest_area = -1;
 
@@ -170,8 +169,6 @@
       resolution_info->SetBoolean("selected", true);
     }
 
-    resolution.Enlarge(
-        -current_overscan.width(), -current_overscan.height());
     resolution_info->SetInteger("width", resolution.width());
     resolution_info->SetInteger("height", resolution.height());
     resolution_info->SetDouble("refreshRate", display_mode.refresh_rate);
@@ -451,9 +448,7 @@
 
   const ash::DisplayInfo& display_info =
       GetDisplayManager()->GetDisplayInfo(display_id);
-  gfx::Insets current_overscan = display_info.GetOverscanInsetsInPixel();
   gfx::Size new_resolution = gfx::ToFlooredSize(gfx::SizeF(width, height));
-  new_resolution.Enlarge(current_overscan.width(), current_overscan.height());
   gfx::Size old_resolution = display_info.bounds_in_native().size();
   bool has_new_resolution = false;
   bool has_old_resolution = false;
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
index 9dd7a05..f236d88 100644
--- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
@@ -54,7 +54,6 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "grit/ash_resources.h"
 #include "grit/locale_settings.h"
@@ -1639,7 +1638,7 @@
 }
 
 gfx::NativeWindow InternetOptionsHandler::GetNativeWindow() const {
-  return web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow();
+  return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
 }
 
 void InternetOptionsHandler::NetworkCommandCallback(
diff --git a/chrome/browser/ui/webui/options/content_settings_exception_area_browsertest.js b/chrome/browser/ui/webui/options/content_settings_exception_area_browsertest.js
index 93da9c6..f9fc3df 100644
--- a/chrome/browser/ui/webui/options/content_settings_exception_area_browsertest.js
+++ b/chrome/browser/ui/webui/options/content_settings_exception_area_browsertest.js
@@ -12,9 +12,7 @@
 ContentSettingsExceptionAreaWebUITest.prototype = {
   __proto__: testing.Test.prototype,
 
-  /**
-   * Browse to the content settings exception area.
-   */
+  /** @override */
   browsePreload: 'chrome://settings-frame/contentExceptions',
 };
 
@@ -27,7 +25,63 @@
 GEN('#endif  // defined(OS_CHROMEOS)');
 // Test opening the content settings exception area has correct location.
 TEST_F('ContentSettingsExceptionAreaWebUITest',
-       'MAYBE_testOpenContentSettingsExceptionArea',
-       function() {
-         assertEquals(this.browsePreload, document.location.href);
-       });
+       'MAYBE_testOpenContentSettingsExceptionArea', function() {
+  assertEquals(this.browsePreload, document.location.href);
+});
+
+/**
+ * A class to asynchronously test the content settings exception area dialog.
+ * @extends {testing.Test}
+ * @constructor
+ */
+function ContentSettingsExceptionsAreaAsyncWebUITest() {}
+
+ContentSettingsExceptionsAreaAsyncWebUITest.prototype = {
+  __proto__: testing.Test.prototype,
+
+  /** @override */
+  browsePreload: 'chrome://settings-frame/contentExceptions',
+
+  /** @override */
+  isAsync: true,
+};
+
+// Adds and removes a location content setting exception.
+TEST_F('ContentSettingsExceptionsAreaAsyncWebUITest',
+       'testAddRemoveLocationExceptions', function() {
+  assertEquals(this.browsePreload, document.location.href);
+
+  /** @const */ var origin = 'http://google.com:80';
+  /** @const */ var setExceptions = ContentSettings.setExceptions;
+
+  var list = ContentSettings.getExceptionsList('cookies', 'normal');
+  assertEquals(1, list.items.length);
+
+  var setExceptionsCounter = 0;
+  var setExceptionsCallback = function() {
+    setExceptionsCounter++;
+    if (setExceptionsCounter == 1) {
+      // The first item is now the exception (edit items are always last).
+      expectEquals('block', list.dataModel.item(0).setting);
+      expectEquals(origin, list.dataModel.item(0).origin);
+
+      // Delete the item and verify it worked.
+      list.deleteItemAtIndex(0);
+    } else if (setExceptionsCounter == 2) {
+      // Verify the item was deleted, restore the original method, and finish.
+      expectEquals(1, list.items.length);
+      ContentSettings.setExceptions = setExceptions;
+      testDone();
+    }
+  };
+
+  // NOTE: if this test doesn't succeed, |ContentSettings.setExceptions| may not
+  // be restored to its original method. I know no easy way to fix this.
+  ContentSettings.setExceptions = function() {
+    setExceptions.apply(ContentSettings, arguments);
+    setExceptionsCallback();
+  };
+
+  // Add an item to the location exception area to start the test.
+  list.items[0].finishEdit(origin, 'block');
+});
diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc
index b672cbd..f7da58e 100644
--- a/chrome/browser/ui/webui/options/content_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/content_settings_handler.cc
@@ -1209,9 +1209,9 @@
   rv = args->GetString(2, &pattern);
   DCHECK(rv);
 
-  // The third argument to this handler is optional.
+  // The fourth argument to this handler is optional.
   std::string secondary_pattern;
-  if (args->GetSize() == 3U) {
+  if (args->GetSize() >= 4U) {
     rv = args->GetString(3, &secondary_pattern);
     DCHECK(rv);
   }
diff --git a/chrome/browser/ui/webui/options/font_settings_browsertest.js b/chrome/browser/ui/webui/options/font_settings_browsertest.js
index fd99eff..d59db3d 100644
--- a/chrome/browser/ui/webui/options/font_settings_browsertest.js
+++ b/chrome/browser/ui/webui/options/font_settings_browsertest.js
@@ -17,7 +17,7 @@
    */
   browsePreload: 'chrome://settings-frame/fonts',
 
-  /** @inheritDoc */
+  /** @override */
   preLoad: function() {
     this.makeAndRegisterMockHandler(['openAdvancedFontSettingsOptions']);
   }
diff --git a/chrome/browser/ui/webui/options/import_data_handler.cc b/chrome/browser/ui/webui/options/import_data_handler.cc
index 8155030..d8e8fe6 100644
--- a/chrome/browser/ui/webui/options/import_data_handler.cc
+++ b/chrome/browser/ui/webui/options/import_data_handler.cc
@@ -68,7 +68,9 @@
     { "noProfileFound", IDS_IMPORT_NO_PROFILE_FOUND },
     { "importSucceeded", IDS_IMPORT_SUCCEEDED },
     { "findYourImportedBookmarks", IDS_IMPORT_FIND_YOUR_BOOKMARKS },
+#if defined(OS_MACOSX)
     { "macPasswordKeychain", IDS_IMPORT_PASSWORD_KEYCHAIN_WARNING },
+#endif
   };
 
   RegisterStrings(localized_strings, resources, arraysize(resources));
diff --git a/chrome/browser/ui/webui/options/manage_profile_browsertest.js b/chrome/browser/ui/webui/options/manage_profile_browsertest.js
index 24d595b..83e4008 100644
--- a/chrome/browser/ui/webui/options/manage_profile_browsertest.js
+++ b/chrome/browser/ui/webui/options/manage_profile_browsertest.js
@@ -71,8 +71,8 @@
     OptionsPage.showPageByName(mode + 'Profile');
 
     var defaultProfile = {
-      name: "Default Name",
-      iconURL: "/default/path",
+      name: 'Default Name',
+      iconURL: '/default/path',
     };
     this.defaultIconURLs = ['/some/path',
                             defaultProfile.iconURL,
@@ -140,7 +140,7 @@
 
 // The checkbox label should change depending on whether the user is signed in.
 TEST_F('ManageProfileUITest', 'CreateManagedUserText', function() {
-  var signedInText =  $('create-profile-managed-signed-in');
+  var signedInText = $('create-profile-managed-signed-in');
   var notSignedInText = $('create-profile-managed-not-signed-in');
 
   ManageProfileOverlay.getInstance().initializePage();
@@ -338,7 +338,7 @@
 });
 
 // The name and email should be inserted into the confirmation dialog.
-TEST_F('ManageProfileUITest', 'CreateConfirmationText', function () {
+TEST_F('ManageProfileUITest', 'CreateConfirmationText', function() {
   var self = this;
   var custodianEmail = 'foo@example.com';
 
diff --git a/chrome/browser/ui/webui/options/manage_profile_handler.cc b/chrome/browser/ui/webui/options/manage_profile_handler.cc
index bc8c2d6..8c8471e 100644
--- a/chrome/browser/ui/webui/options/manage_profile_handler.cc
+++ b/chrome/browser/ui/webui/options/manage_profile_handler.cc
@@ -205,18 +205,23 @@
 
 void ManageProfileHandler::GenerateSignedinUserSpecificStrings(
     base::DictionaryValue* dictionary) {
+  std::string username;
+  std::string domain_name;
+
 #if !defined(OS_CHROMEOS)
   Profile* profile = Profile::FromWebUI(web_ui());
   DCHECK(profile);
   SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile);
-  DCHECK(manager);
-  std::string username = manager->GetAuthenticatedUsername();
-  std::string domain_name;
-  // If there is no one logged in or if the profile name is empty then the
-  // domain name is empty. This happens in browser tests.
-  if (!username.empty())
-    domain_name = "<span id=disconnect-managed-profile-domain-name>" +
-                  gaia::ExtractDomainName(username) + "</span>";
+  if (manager) {
+    username = manager->GetAuthenticatedUsername();
+    // If there is no one logged in or if the profile name is empty then the
+    // domain name is empty. This happens in browser tests.
+    if (!username.empty()) {
+      domain_name = "<span id=disconnect-managed-profile-domain-name>" +
+                    gaia::ExtractDomainName(username) + "</span>";
+    }
+  }
+#endif
 
   dictionary->SetString(
       "disconnectManagedProfileDomainInformation",
@@ -230,12 +235,6 @@
           IDS_PROFILES_DISCONNECT_MANAGED_PROFILE_TEXT,
           base::UTF8ToUTF16(username),
           base::UTF8ToUTF16(chrome::kSyncGoogleDashboardURL)));
-#else
-  dictionary->SetString("disconnectManagedProfileDomainInformation",
-                        base::string16());
-  dictionary->SetString("disconnectManagedProfileText",
-                        base::string16());
-#endif
 }
 
 void ManageProfileHandler::RequestDefaultProfileIcons(
diff --git a/chrome/browser/ui/webui/options/options_browsertest.js b/chrome/browser/ui/webui/options/options_browsertest.js
index 36fb747..9b15733 100644
--- a/chrome/browser/ui/webui/options/options_browsertest.js
+++ b/chrome/browser/ui/webui/options/options_browsertest.js
@@ -9,6 +9,11 @@
 /**
  * Wait for the method specified by |methodName|, on the |object| object, to be
  * called, then execute |afterFunction|.
+ * @param {*} object Object with callable property named |methodName|.
+ * @param {string} methodName The name of the property on |object| to use as a
+ *     callback.
+ * @param {!Function} afterFunction A function to call after object.methodName()
+ *     is called.
  */
 function waitForResponse(object, methodName, afterFunction) {
   var originalCallback = object[methodName];
@@ -24,6 +29,7 @@
 /**
   * Wait for the global window.onpopstate callback to be called (after a tab
   * history navigation), then execute |afterFunction|.
+  * @param {!Function} afterFunction A function to call after pop state events.
   */
 function waitForPopstate(afterFunction) {
   waitForResponse(window, 'onpopstate', afterFunction);
@@ -143,18 +149,22 @@
   this.mockHandler.expects(once()).defaultZoomFactorAction(NOT_NULL).
       will(callFunction(function() { }));
   defaultZoomFactor.selectedIndex = defaultZoomFactor.options.length - 1;
-  var event = { target: defaultZoomFactor };
+  var event = {target: defaultZoomFactor};
   if (defaultZoomFactor.onchange) defaultZoomFactor.onchange(event);
   testDone();
 });
 
-// If |confirmInterstitial| is true, the OK button of the Do Not Track
-// interstitial is pressed, otherwise the abort button is pressed.
+/**
+ * If |confirmInterstitial| is true, the OK button of the Do Not Track
+ * interstitial is pressed, otherwise the abort button is pressed.
+ * @param {boolean} confirmInterstitial Whether to confirm the Do Not Track
+ *     interstitial.
+ */
 OptionsWebUITest.prototype.testDoNotTrackInterstitial =
     function(confirmInterstitial) {
-  Preferences.prefsFetchedCallback({'enable_do_not_track': {'value': false } });
-  var buttonToClick = confirmInterstitial ? $('do-not-track-confirm-ok')
-                                          : $('do-not-track-confirm-cancel');
+  Preferences.prefsFetchedCallback({'enable_do_not_track': {'value': false}});
+  var buttonToClick = confirmInterstitial ? $('do-not-track-confirm-ok') :
+                                            $('do-not-track-confirm-cancel');
   var dntCheckbox = $('do-not-track-enabled');
   var dntOverlay = OptionsPage.registeredOverlayPages['donottrackconfirm'];
   assertFalse(dntCheckbox.checked);
@@ -180,7 +190,7 @@
       default:
         assertTrue(false);
     }
-  }
+  };
   dntOverlay.addEventListener('visibleChange', visibleChangeHandler);
 
   if (confirmInterstitial) {
@@ -192,7 +202,7 @@
   }
 
   dntCheckbox.click();
-}
+};
 
 TEST_F('OptionsWebUITest', 'EnableDoNotTrackAndConfirmInterstitial',
        function() {
@@ -207,9 +217,9 @@
 // Check that the "Do not Track" preference can be correctly disabled.
 // In order to do that, we need to enable it first.
 TEST_F('OptionsWebUITest', 'EnableAndDisableDoNotTrack', function() {
-  Preferences.prefsFetchedCallback({'enable_do_not_track': {'value': false } });
+  Preferences.prefsFetchedCallback({'enable_do_not_track': {'value': false}});
   var dntCheckbox = $('do-not-track-enabled');
-  var dntOverlay = OptionsPage.registeredOverlayPages['donottrackconfirm'];
+  var dntOverlay = OptionsPage.registeredOverlayPages.donottrackconfirm;
   assertFalse(dntCheckbox.checked);
 
   var visibleChangeCounter = 0;
@@ -237,17 +247,17 @@
   dntOverlay.addEventListener('visibleChange', visibleChangeHandler);
 
   this.mockHandler.expects(once()).setBooleanPref(
-      eq(["enable_do_not_track", true, 'Options_DoNotTrackCheckbox']));
+      eq(['enable_do_not_track', true, 'Options_DoNotTrackCheckbox']));
 
   var verifyCorrectEndState = function() {
     window.setTimeout(function() {
       assertFalse(dntOverlay.visible);
       assertFalse(dntCheckbox.checked);
       testDone();
-    }, 0)
+    }, 0);
   }
   this.mockHandler.expects(once()).setBooleanPref(
-      eq(["enable_do_not_track", false, 'Options_DoNotTrackCheckbox'])).will(
+      eq(['enable_do_not_track', false, 'Options_DoNotTrackCheckbox'])).will(
           callFunction(verifyCorrectEndState));
 
   dntCheckbox.click();
@@ -332,7 +342,7 @@
   isAsync: true,
 
   /** @override */
-  setUp: function () {
+  setUp: function() {
       // user-image-stream is a streaming video element used for capturing a
       // user image during OOBE.
       this.accessibilityAuditConfig.ignoreSelectors('videoWithoutCaptions',
@@ -455,7 +465,7 @@
   },
 };
 
-/*
+/**
  * Set by verifyHistory_ to incorporate a followup callback, then called by the
  * C++ fixture with the navigation history to be verified.
  * @type {Function}
diff --git a/chrome/browser/ui/webui/options/options_ui.cc b/chrome/browser/ui/webui/options/options_ui.cc
index 9abdda5..f3631be 100644
--- a/chrome/browser/ui/webui/options/options_ui.cc
+++ b/chrome/browser/ui/webui/options/options_ui.cc
@@ -377,8 +377,10 @@
         type != AutocompleteMatchType::HISTORY_TITLE &&
         type != AutocompleteMatchType::HISTORY_BODY &&
         type != AutocompleteMatchType::HISTORY_KEYWORD &&
-        type != AutocompleteMatchType::NAVSUGGEST)
+        type != AutocompleteMatchType::NAVSUGGEST &&
+        type != AutocompleteMatchType::NAVSUGGEST_PERSONALIZED) {
       continue;
+    }
     base::DictionaryValue* entry = new base::DictionaryValue();
     entry->SetString("title", match.description);
     entry->SetString("displayURL", match.contents);
diff --git a/chrome/browser/ui/webui/options/password_manager_handler.cc b/chrome/browser/ui/webui/options/password_manager_handler.cc
index b3125a6..9ad56cd 100644
--- a/chrome/browser/ui/webui/options/password_manager_handler.cc
+++ b/chrome/browser/ui/webui/options/password_manager_handler.cc
@@ -21,7 +21,6 @@
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
@@ -41,7 +40,7 @@
 
 #if !defined(OS_ANDROID)
 gfx::NativeWindow PasswordManagerHandler::GetNativeWindow() {
-  return web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow();
+  return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
 }
 #endif
 
diff --git a/chrome/browser/ui/webui/options/search_engine_manager_handler.cc b/chrome/browser/ui/webui/options/search_engine_manager_handler.cc
index 5886d15..ea2d68c 100644
--- a/chrome/browser/ui/webui/options/search_engine_manager_handler.cc
+++ b/chrome/browser/ui/webui/options/search_engine_manager_handler.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/ui/search_engines/keyword_editor_controller.h"
 #include "chrome/browser/ui/search_engines/template_url_table_model.h"
 #include "chrome/common/url_constants.h"
+#include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_ui.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension.h"
@@ -214,6 +215,9 @@
     return;
 
   list_controller_->MakeDefaultTemplateURL(index);
+
+  content::RecordAction(
+      base::UserMetricsAction("Options_SearchEngineSetDefault"));
 }
 
 void SearchEngineManagerHandler::RemoveSearchEngine(
@@ -226,8 +230,11 @@
   if (index < 0 || index >= list_controller_->table_model()->RowCount())
     return;
 
-  if (list_controller_->CanRemove(list_controller_->GetTemplateURL(index)))
+  if (list_controller_->CanRemove(list_controller_->GetTemplateURL(index))) {
     list_controller_->RemoveTemplateURL(index);
+    content::RecordAction(
+        base::UserMetricsAction("Options_SearchEngineRemoved"));
+  }
 }
 
 void SearchEngineManagerHandler::EditSearchEngine(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/options/settings_format_browsertest.js b/chrome/browser/ui/webui/options/settings_format_browsertest.js
index e2d06ac..5279a8c 100644
--- a/chrome/browser/ui/webui/options/settings_format_browsertest.js
+++ b/chrome/browser/ui/webui/options/settings_format_browsertest.js
@@ -151,7 +151,7 @@
     if (!element.name)
       this.fail('MISSING_RADIO_BUTTON_NAME', element);
 
-    if (!element.getAttribute("value"))
+    if (!element.getAttribute('value'))
       this.fail('MISSING_RADIO_BUTTON_VALUE', element);
   }
 });
diff --git a/chrome/browser/ui/webui/options/startup_page_list_browsertest.js b/chrome/browser/ui/webui/options/startup_page_list_browsertest.js
index 0cf7b7c..25e5fd4 100644
--- a/chrome/browser/ui/webui/options/startup_page_list_browsertest.js
+++ b/chrome/browser/ui/webui/options/startup_page_list_browsertest.js
@@ -27,7 +27,7 @@
 
   /**
    * Returns the list to be tested.
-   * @return {Element}
+   * @return {Element} The start-up pages list.
    * @protected
    */
   getList: function() {
@@ -103,7 +103,7 @@
   /**
    * Gets data associated with this fake data transfer.
    * @param {string} type The type of data to get.
-   * @returns {string} The requested type of data or '' if not set.
+   * @return {string} The requested type of data or '' if not set.
    */
   getData: function(type) {
     return this.data_[type] || '';
diff --git a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc
index 81baa1d..34d4611 100644
--- a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc
+++ b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h"
 
+#include <algorithm>
 #include <set>
 
 #include "base/strings/string16.h"
@@ -54,7 +55,9 @@
 }  // namespace
 
 PasswordManagerInternalsUI::PasswordManagerInternalsUI(content::WebUI* web_ui)
-    : WebUIController(web_ui) {
+    : WebUIController(web_ui),
+      WebContentsObserver(web_ui->GetWebContents()),
+      did_stop_loading_(false) {
   // Set up the chrome://password-manager-internals/ source.
   content::WebUIDataSource::Add(Profile::FromWebUI(web_ui),
                                 CreatePasswordManagerInternalsHTMLSource());
@@ -65,9 +68,27 @@
   NotifyAllPasswordManagerClients(PAGE_CLOSED);
 }
 
+void PasswordManagerInternalsUI::DidStopLoading(
+    content::RenderViewHost* /* render_view_host */) {
+  did_stop_loading_ = true;
+  if (log_buffer_.empty())
+    return;
+  LogInternal(log_buffer_);
+  log_buffer_.clear();
+}
+
 void PasswordManagerInternalsUI::LogSavePasswordProgress(
     const std::string& text) {
-  base::StringValue text_string_value(net::EscapeForHTML(text));
+  if (did_stop_loading_)
+    LogInternal(text);
+  else
+    log_buffer_.append(text);
+}
+
+void PasswordManagerInternalsUI::LogInternal(const std::string& text) {
+  std::string no_quotes(text);
+  std::replace(no_quotes.begin(), no_quotes.end(), '"', ' ');
+  base::StringValue text_string_value(net::EscapeForHTML(no_quotes));
   web_ui()->CallJavascriptFunction("addSavePasswordProgressLog",
                                    text_string_value);
 }
diff --git a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h
index 2f1f47e..c73486a 100644
--- a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h
+++ b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h
@@ -6,15 +6,21 @@
 #define CHROME_BROWSER_UI_WEBUI_PASSWORD_MANAGER_INTERNALS_PASSWORD_MANAGER_INTERNALS_UI_H_
 
 #include "components/password_manager/core/browser/password_manager_logger.h"
+#include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_ui_controller.h"
 
 class PasswordManagerInternalsUI
     : public content::WebUIController,
+      public content::WebContentsObserver,
       public password_manager::PasswordManagerLogger {
  public:
   explicit PasswordManagerInternalsUI(content::WebUI* web_ui);
   virtual ~PasswordManagerInternalsUI();
 
+  // WebContentsObserver implementation.
+  virtual void DidStopLoading(
+      content::RenderViewHost* render_view_host) OVERRIDE;
+
   // PasswordManagerLogger implementation.
   virtual void LogSavePasswordProgress(const std::string& text) OVERRIDE;
 
@@ -33,6 +39,17 @@
   void NotifyAllPasswordManagerClients(
       ClientNotificationType notification_type);
 
+  // Helper used by LogSavePasswordProgress, actually sends |text| to the
+  // internals page.
+  void LogInternal(const std::string& text);
+
+  // Whether the observed WebContents did stop loading.
+  bool did_stop_loading_;
+
+  // Stores the logs here until |did_stop_loading_| becomes true. At that point
+  // all stored logs are displayed and any new are displayed directly.
+  std::string log_buffer_;
+
   DISALLOW_COPY_AND_ASSIGN(PasswordManagerInternalsUI);
 };
 
diff --git a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui_browsertest.cc b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui_browsertest.cc
index 532adf4..817866b 100644
--- a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui_browsertest.cc
@@ -23,6 +23,10 @@
  protected:
   content::WebContents* GetWebContents();
 
+  // Opens a new tab, and navigates to the internals page in that. Also assigns
+  // the corresponding UI controller to |controller_|.
+  void OpenNewTabWithTheInternalsPage();
+
   PasswordManagerInternalsUI* controller() {
     return controller_;
   };
@@ -40,13 +44,7 @@
 
 void PasswordManagerInternalsWebUIBrowserTest::SetUpOnMainThread() {
   WebUIBrowserTest::SetUpOnMainThread();
-  std::string url_string("chrome://");
-  url_string += chrome::kChromeUIPasswordManagerInternalsHost;
-  ui_test_utils::NavigateToURL(browser(), GURL(url_string));
-  controller_ = static_cast<PasswordManagerInternalsUI*>(
-      GetWebContents()->GetWebUI()->GetController());
-  AddLibrary(base::FilePath(
-      FILE_PATH_LITERAL("password_manager_internals_browsertest.js")));
+  OpenNewTabWithTheInternalsPage();
 }
 
 void PasswordManagerInternalsWebUIBrowserTest::SetUpCommandLine(
@@ -60,8 +58,41 @@
   return browser()->tab_strip_model()->GetActiveWebContents();
 }
 
+void
+PasswordManagerInternalsWebUIBrowserTest::OpenNewTabWithTheInternalsPage() {
+  std::string url_string("chrome://");
+  url_string += chrome::kChromeUIPasswordManagerInternalsHost;
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(),
+      GURL(url_string),
+      NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
+  controller_ = static_cast<PasswordManagerInternalsUI*>(
+      GetWebContents()->GetWebUI()->GetController());
+  AddLibrary(base::FilePath(
+      FILE_PATH_LITERAL("password_manager_internals_browsertest.js")));
+}
+
 IN_PROC_BROWSER_TEST_F(PasswordManagerInternalsWebUIBrowserTest,
                        LogSavePasswordProgress) {
   controller()->LogSavePasswordProgress("<script> text for testing");
   ASSERT_TRUE(RunJavascriptTest("testLogText"));
 }
+
+// Test that if two tabs with the internals page are open, the second displays
+// the same logs. In particular, this checks that both the second tab gets the
+// logs created before the second tab was opened, and also that the second tab
+// waits with displaying until the internals page is ready (trying to display
+// the old logs just on construction time would fail).
+// TODO(vabr): Disabled until multiple tabs with the internals page can exist
+// without crashing.
+IN_PROC_BROWSER_TEST_F(PasswordManagerInternalsWebUIBrowserTest,
+                       DISABLED_LogSavePasswordProgress_MultipleTabsIdentical) {
+  // First, open one tab with the internals page, and log something.
+  controller()->LogSavePasswordProgress("<script> text for testing");
+  ASSERT_TRUE(RunJavascriptTest("testLogText"));
+  // Now open a second tab with the internals page, but do not log anything.
+  OpenNewTabWithTheInternalsPage();
+  // The previously logged text should have made it to the page.
+  ASSERT_TRUE(RunJavascriptTest("testLogText"));
+}
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index 6534f82..7b4a5b3 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -58,7 +58,6 @@
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "google_apis/gaia/oauth2_token_service.h"
 #include "printing/backend/print_backend.h"
@@ -829,7 +828,7 @@
     PostPrintToPdfTask();
   } else if (!select_file_dialog_.get() ||
              !select_file_dialog_->IsRunning(platform_util::GetTopLevel(
-                 preview_web_contents()->GetView()->GetNativeView()))) {
+                 preview_web_contents()->GetNativeView()))) {
     PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(
         web_ui()->GetController());
     // Pre-populating select file dialog with print job title.
@@ -938,7 +937,7 @@
   }
 
   gfx::NativeWindow modal_parent = platform_util::GetTopLevel(
-      preview_web_contents()->GetView()->GetNativeView());
+      preview_web_contents()->GetNativeView());
   print_dialog_cloud::CreatePrintDialogForBytes(
       preview_web_contents()->GetBrowserContext(),
       modal_parent,
@@ -1234,8 +1233,7 @@
       &file_type_info,
       0,
       base::FilePath::StringType(),
-      platform_util::GetTopLevel(
-          preview_web_contents()->GetView()->GetNativeView()),
+      platform_util::GetTopLevel(preview_web_contents()->GetNativeView()),
       NULL);
 }
 
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
index 959aa48..6a968d9 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -519,7 +519,7 @@
   base::FundamentalValue ui_identifier(id_);
   base::FundamentalValue request_id(preview_request_id);
   if (g_testing_delegate)
-    g_testing_delegate->DidRenderPreviewPage(*web_ui()->GetWebContents());
+    g_testing_delegate->DidRenderPreviewPage(web_ui()->GetWebContents());
   web_ui()->CallJavascriptFunction(
       "onDidPreviewPage", number, ui_identifier, request_id);
   if (g_testing_delegate && g_testing_delegate->IsAutoCancelEnabled())
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.h b/chrome/browser/ui/webui/print_preview/print_preview_ui.h
index 5d68c3b..7f32261 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.h
@@ -149,8 +149,7 @@
    public:
     virtual bool IsAutoCancelEnabled() = 0;
     virtual void DidGetPreviewPageCount(int page_count) = 0;
-    virtual void DidRenderPreviewPage(
-        const content::WebContents& preview_dialog) = 0;
+    virtual void DidRenderPreviewPage(content::WebContents* preview_dialog) = 0;
   };
 
   static void SetDelegateForTesting(TestingDelegate* delegate);
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc
index b0fe640..c3845c8 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui_browsertest.cc
@@ -25,7 +25,6 @@
 #include "content/public/test/test_utils.h"
 
 #if defined(OS_WIN)
-#include "content/public/browser/web_contents_view.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #endif
@@ -159,8 +158,7 @@
 
   // Now get the region of the plugin before and after the print preview is
   // shown. They should be different.
-  HWND hwnd = tab->GetView()->GetNativeView()->GetHost()->
-      GetAcceleratedWidget();
+  HWND hwnd = tab->GetNativeView()->GetHost()->GetAcceleratedWidget();
   HWND child = NULL;
   EnumChildWindows(hwnd, EnumerateChildren,reinterpret_cast<LPARAM>(&child));
 
diff --git a/chrome/browser/ui/webui/set_as_default_browser_ui.cc b/chrome/browser/ui/webui/set_as_default_browser_ui.cc
index dbaa853..6dbcd99 100644
--- a/chrome/browser/ui/webui/set_as_default_browser_ui.cc
+++ b/chrome/browser/ui/webui/set_as_default_browser_ui.cc
@@ -31,7 +31,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "content/public/browser/web_ui_message_handler.h"
@@ -352,7 +351,7 @@
           browser_->tab_strip_model()->GetActiveWebContents();
       window->Show();
       if (contents)
-        contents->GetView()->SetInitialFocus();
+        contents->SetInitialFocus();
     }
   }
 
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
index 41957ef..8cade65 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -13,6 +13,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/about_signin_internals_factory.h"
 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/signin/signin_promo.h"
 #include "chrome/browser/sync/profile_sync_service.h"
@@ -23,6 +24,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
+#include "components/signin/core/browser/about_signin_internals.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_error_controller.h"
 #include "components/signin/core/browser/signin_oauth_helper.h"
@@ -103,6 +105,10 @@
     browser = handler_->GetDesktopBrowser();
   }
 
+  AboutSigninInternals* about_signin_internals =
+    AboutSigninInternalsFactory::GetForProfile(profile_);
+  about_signin_internals->OnRefreshTokenReceived("Successful");
+
   signin::Source source = signin::GetSourceForPromoURL(current_url_);
   if (source == signin::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT) {
     ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->
@@ -156,6 +162,7 @@
           start_mode,
           contents,
           confirmation_required,
+          signin::GetNextPageURLForPromoURL(current_url_),
           base::Bind(&InlineLoginHandlerImpl::SyncStarterCallback, handler_));
     }
   }
@@ -168,6 +175,10 @@
   if (handler_)
     handler_->HandleLoginError(error.ToString());
 
+  AboutSigninInternals* about_signin_internals =
+    AboutSigninInternalsFactory::GetForProfile(profile_);
+  about_signin_internals->OnRefreshTokenReceived("Failure");
+
   base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
 }
 
@@ -193,7 +204,6 @@
 
   const GURL& current_url = web_ui()->GetWebContents()->GetURL();
   signin::Source source = signin::GetSourceForPromoURL(current_url);
-  DCHECK(source != signin::SOURCE_UNKNOWN);
   if (source == signin::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT ||
       source == signin::SOURCE_AVATAR_BUBBLE_SIGN_IN) {
     // Drop the leading slash in the path.
@@ -321,6 +331,11 @@
     return;
   }
 
+  AboutSigninInternals* about_signin_internals =
+      AboutSigninInternalsFactory::GetForProfile(Profile::FromWebUI(web_ui()));
+  about_signin_internals->OnAuthenticationResultReceived(
+      "GAIA Auth Successful");
+
   content::StoragePartition* partition =
       content::BrowserContext::GetStoragePartitionForSite(
           contents->GetBrowserContext(),
@@ -376,7 +391,6 @@
 
   const GURL& current_url = contents->GetLastCommittedURL();
   signin::Source source = signin::GetSourceForPromoURL(current_url);
-  DCHECK(source != signin::SOURCE_UNKNOWN);
   bool auto_close = signin::IsAutoCloseEnabledInURL(current_url);
 
   if (result == OneClickSigninSyncStarter::SYNC_SETUP_FAILURE) {
diff --git a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
index 492559c..7427e28 100644
--- a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
+++ b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
@@ -5,9 +5,11 @@
 #include "chrome/browser/ui/webui/signin/user_manager_screen_handler.h"
 
 #include "base/bind.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/value_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/profiles/profile_info_cache.h"
@@ -20,7 +22,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "google_apis/gaia/gaia_auth_fetcher.h"
 #include "google_apis/gaia/gaia_constants.h"
@@ -60,6 +61,8 @@
 const char kJsApiUserManagerLaunchGuest[] = "launchGuest";
 const char kJsApiUserManagerLaunchUser[] = "launchUser";
 const char kJsApiUserManagerRemoveUser[] = "removeUser";
+const char kJsApiUserManagerCustomButtonClicked[] = "customButtonClicked";
+const char kJsApiUserManagerAttemptUnlock[] = "attemptUnlock";
 
 const size_t kAvatarIconSize = 180;
 
@@ -119,13 +122,25 @@
                                          const base::string16& name) {
   for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) {
     if (info_cache.GetUserNameOfProfileAtIndex(i) == email &&
-        info_cache.GetNameOfProfileAtIndex(i) == name) {
+        (name.empty() || info_cache.GetNameOfProfileAtIndex(i) == name)) {
       return i;
     }
   }
   return std::string::npos;
 }
 
+extensions::ScreenlockPrivateEventRouter* GetScreenlockRouter(
+    const std::string& email) {
+  ProfileInfoCache& info_cache =
+      g_browser_process->profile_manager()->GetProfileInfoCache();
+  const size_t profile_index = GetIndexOfProfileWithEmailAndName(
+      info_cache, base::UTF8ToUTF16(email), base::string16());
+  Profile* profile = g_browser_process->profile_manager()
+      ->GetProfileByPath(info_cache.GetPathOfProfileAtIndex(profile_index));
+  return extensions::ScreenlockPrivateEventRouter::GetFactoryInstance()->Get(
+      profile);
+}
+
 } // namespace
 
 // ProfileUpdateObserver ------------------------------------------------------
@@ -196,13 +211,75 @@
 }
 
 UserManagerScreenHandler::~UserManagerScreenHandler() {
+  ScreenlockBridge::Get()->SetLockHandler(NULL);
+}
+
+void UserManagerScreenHandler::ShowBannerMessage(const std::string& message) {
+  web_ui()->CallJavascriptFunction(
+      "login.AccountPickerScreen.showBannerMessage",
+      base::StringValue(message));
+}
+
+void UserManagerScreenHandler::ShowUserPodButton(
+    const std::string& user_email,
+    const gfx::Image& icon,
+    const base::Closure& callback) {
+  GURL icon_url(webui::GetBitmapDataUrl(icon.AsBitmap()));
+  web_ui()->CallJavascriptFunction(
+      "login.AccountPickerScreen.showUserPodButton",
+      base::StringValue(user_email),
+      base::StringValue(icon_url.spec()));
+}
+
+void UserManagerScreenHandler::HideUserPodButton(
+    const std::string& user_email) {
+  web_ui()->CallJavascriptFunction(
+      "login.AccountPickerScreen.hideUserPodButton",
+      base::StringValue(user_email));
+}
+
+void UserManagerScreenHandler::EnableInput() {
+  // Nothing here because UI is not disabled when starting to authenticate.
+}
+
+void UserManagerScreenHandler::SetAuthType(
+    const std::string& user_email,
+    ScreenlockBridge::LockHandler::AuthType auth_type,
+    const std::string& auth_value) {
+  user_auth_type_map_[user_email] = auth_type;
+  web_ui()->CallJavascriptFunction(
+      "login.AccountPickerScreen.setAuthType",
+      base::StringValue(user_email),
+      base::FundamentalValue(auth_type),
+      base::StringValue(auth_value));
+}
+
+ScreenlockBridge::LockHandler::AuthType UserManagerScreenHandler::GetAuthType(
+      const std::string& user_email) const {
+  UserAuthTypeMap::const_iterator it = user_auth_type_map_.find(user_email);
+  if (it == user_auth_type_map_.end())
+    return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
+  return it->second;
+}
+
+void UserManagerScreenHandler::Unlock(const std::string& user_email) {
+  ProfileInfoCache& info_cache =
+      g_browser_process->profile_manager()->GetProfileInfoCache();
+  const size_t profile_index = GetIndexOfProfileWithEmailAndName(
+      info_cache, base::UTF8ToUTF16(user_email), base::string16());
+  DCHECK_LT(profile_index, info_cache.GetNumberOfProfiles());
+
+  authenticating_profile_index_ = profile_index;
+  ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL);
 }
 
 void UserManagerScreenHandler::HandleInitialize(const base::ListValue* args) {
   SendUserList();
   web_ui()->CallJavascriptFunction("cr.ui.Oobe.showUserManagerScreen");
   desktop_type_ = chrome::GetHostDesktopTypeForNativeView(
-      web_ui()->GetWebContents()->GetView()->GetNativeView());
+      web_ui()->GetWebContents()->GetNativeView());
+
+  ScreenlockBridge::Get()->SetLockHandler(this);
 }
 
 void UserManagerScreenHandler::HandleAddUser(const base::ListValue* args) {
@@ -326,6 +403,18 @@
                             ProfileMetrics::SWITCH_PROFILE_MANAGER);
 }
 
+void UserManagerScreenHandler::HandleCustomButtonClicked(
+    const base::ListValue* args) {
+  // TODO(xiyuan): Remove this. Deprecated now.
+}
+
+void UserManagerScreenHandler::HandleAttemptUnlock(
+    const base::ListValue* args) {
+  std::string email;
+  CHECK(args->GetString(0, &email));
+  GetScreenlockRouter(email)->OnAuthAttempted(GetAuthType(email), "");
+}
+
 void UserManagerScreenHandler::OnClientLoginSuccess(
     const ClientLoginResult& result) {
   chrome::SetLocalAuthCredentials(authenticating_profile_index_,
@@ -368,6 +457,12 @@
   web_ui()->RegisterMessageCallback(kJsApiUserManagerRemoveUser,
       base::Bind(&UserManagerScreenHandler::HandleRemoveUser,
                  base::Unretained(this)));
+  web_ui()->RegisterMessageCallback(kJsApiUserManagerCustomButtonClicked,
+      base::Bind(&UserManagerScreenHandler::HandleCustomButtonClicked,
+                 base::Unretained(this)));
+  web_ui()->RegisterMessageCallback(kJsApiUserManagerAttemptUnlock,
+      base::Bind(&UserManagerScreenHandler::HandleAttemptUnlock,
+                 base::Unretained(this)));
 
   const content::WebUI::MessageCallback& kDoNothingCallback =
       base::Bind(&HandleAndDoNothing);
@@ -487,6 +582,8 @@
   const ProfileInfoCache& info_cache =
       g_browser_process->profile_manager()->GetProfileInfoCache();
 
+  user_auth_type_map_.clear();
+
   // If the active user is a managed user, then they may not perform
   // certain actions (i.e. delete another user).
   bool active_user_is_managed = Profile::FromWebUI(web_ui())->IsManaged();
diff --git a/chrome/browser/ui/webui/signin/user_manager_screen_handler.h b/chrome/browser/ui/webui/signin/user_manager_screen_handler.h
index 302a88f..2d6be31 100644
--- a/chrome/browser/ui/webui/signin/user_manager_screen_handler.h
+++ b/chrome/browser/ui/webui/signin/user_manager_screen_handler.h
@@ -5,9 +5,13 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_SIGNIN_USER_MANAGER_SCREEN_HANDLER_H_
 #define CHROME_BROWSER_UI_WEBUI_SIGNIN_USER_MANAGER_SCREEN_HANDLER_H_
 
+#include <map>
+
+#include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/profiles/profile_metrics.h"
+#include "chrome/browser/signin/screenlock_bridge.h"
 #include "chrome/browser/ui/host_desktop.h"
 #include "content/public/browser/web_ui_message_handler.h"
 #include "google_apis/gaia/gaia_auth_consumer.h"
@@ -21,6 +25,7 @@
 }
 
 class UserManagerScreenHandler : public content::WebUIMessageHandler,
+                                 public ScreenlockBridge::LockHandler,
                                  public GaiaAuthConsumer {
  public:
   UserManagerScreenHandler();
@@ -31,6 +36,20 @@
 
   void GetLocalizedValues(base::DictionaryValue* localized_strings);
 
+  // ScreenlockBridge::LockHandler implementation.
+  virtual void ShowBannerMessage(const std::string& message) OVERRIDE;
+  virtual void ShowUserPodButton(const std::string& user_email,
+                                 const gfx::Image& icon,
+                                 const base::Closure& callback) OVERRIDE;
+  virtual void HideUserPodButton(const std::string& user_email) OVERRIDE;
+  virtual void EnableInput() OVERRIDE;
+  virtual void SetAuthType(const std::string& user_email,
+                           ScreenlockBridge::LockHandler::AuthType auth_type,
+                           const std::string& auth_value) OVERRIDE;
+  virtual ScreenlockBridge::LockHandler::AuthType GetAuthType(
+      const std::string& user_email) const OVERRIDE;
+  virtual void Unlock(const std::string& user_email) OVERRIDE;
+
  private:
   // An observer for any changes to Profiles in the ProfileInfoCache so that
   // all the visible user manager screens can be updated.
@@ -42,6 +61,8 @@
   void HandleLaunchGuest(const base::ListValue* args);
   void HandleLaunchUser(const base::ListValue* args);
   void HandleRemoveUser(const base::ListValue* args);
+  void HandleCustomButtonClicked(const base::ListValue* args);
+  void HandleAttemptUnlock(const base::ListValue* args);
 
   // Handle GAIA auth results.
   virtual void OnClientLoginSuccess(const ClientLoginResult& result) OVERRIDE;
@@ -71,6 +92,10 @@
   // Login password, held during on-line auth for saving later if correct.
   std::string password_attempt_;
 
+  typedef std::map<std::string, ScreenlockBridge::LockHandler::AuthType>
+      UserAuthTypeMap;
+  UserAuthTypeMap user_auth_type_map_;
+
   DISALLOW_COPY_AND_ASSIGN(UserManagerScreenHandler);
 };
 
diff --git a/chrome/browser/ui/webui/sync_internals_browsertest.js b/chrome/browser/ui/webui/sync_internals_browsertest.js
index a0dca23..b0f1ae7 100644
--- a/chrome/browser/ui/webui/sync_internals_browsertest.js
+++ b/chrome/browser/ui/webui/sync_internals_browsertest.js
@@ -61,98 +61,98 @@
  * @const
  */
 var HARD_CODED_ALL_NODES = [{
-  "nodes": [{
-    "ATTACHMENT_METADATA": "",
-    "BASE_SERVER_SPECIFICS": {},
-    "BASE_VERSION": "1396470970810000",
-    "CTIME": "Wednesday, December 31, 1969 4:00:00 PM",
-    "ID": "sZ:ADqtAZwzF4GOIyvkI2enSI62AU5p/7MNmvuSSyf7yXJ1SkJwpp1YL" +
-      "6bbMkF8inzqW+EO6n2aPJ/uXccW9GHxorBlnKoZAWHVzg==",
-    "IS_DEL": false,
-    "IS_DIR": true,
-    "IS_UNAPPLIED_UPDATE": false,
-    "IS_UNSYNCED": false,
-    "LOCAL_EXTERNAL_ID": "0",
-    "META_HANDLE": "387",
-    "MTIME": "Wednesday, December 31, 1969 4:00:00 PM",
-    "NON_UNIQUE_NAME": "Autofill",
-    "PARENT_ID": "r",
-    "SERVER_CTIME": "Wednesday, December 31, 1969 4:00:00 PM",
-    "SERVER_IS_DEL": false,
-    "SERVER_IS_DIR": true,
-    "SERVER_MTIME": "Wednesday, December 31, 1969 4:00:00 PM",
-    "SERVER_NON_UNIQUE_NAME": "Autofill",
-    "SERVER_PARENT_ID": "r",
-    "SERVER_SPECIFICS": {
-      "autofill": {
-        "usage_timestamp": []
+  'nodes': [{
+    'ATTACHMENT_METADATA': '',
+    'BASE_SERVER_SPECIFICS': {},
+    'BASE_VERSION': '1396470970810000',
+    'CTIME': 'Wednesday, December 31, 1969 4:00:00 PM',
+    'ID': 'sZ:ADqtAZwzF4GOIyvkI2enSI62AU5p/7MNmvuSSyf7yXJ1SkJwpp1YL' +
+      '6bbMkF8inzqW+EO6n2aPJ/uXccW9GHxorBlnKoZAWHVzg==',
+    'IS_DEL': false,
+    'IS_DIR': true,
+    'IS_UNAPPLIED_UPDATE': false,
+    'IS_UNSYNCED': false,
+    'LOCAL_EXTERNAL_ID': '0',
+    'META_HANDLE': '387',
+    'MTIME': 'Wednesday, December 31, 1969 4:00:00 PM',
+    'NON_UNIQUE_NAME': 'Autofill',
+    'PARENT_ID': 'r',
+    'SERVER_CTIME': 'Wednesday, December 31, 1969 4:00:00 PM',
+    'SERVER_IS_DEL': false,
+    'SERVER_IS_DIR': true,
+    'SERVER_MTIME': 'Wednesday, December 31, 1969 4:00:00 PM',
+    'SERVER_NON_UNIQUE_NAME': 'Autofill',
+    'SERVER_PARENT_ID': 'r',
+    'SERVER_SPECIFICS': {
+      'autofill': {
+        'usage_timestamp': []
       }
     },
-    "SERVER_UNIQUE_POSITION": "INVALID[]",
-    "SERVER_VERSION": "1396470970810000",
-    "SPECIFICS": {
-      "autofill": {
-        "usage_timestamp": []
+    'SERVER_UNIQUE_POSITION': 'INVALID[]',
+    'SERVER_VERSION': '1396470970810000',
+    'SPECIFICS': {
+      'autofill': {
+        'usage_timestamp': []
       }
     },
-    "SYNCING": false,
-    "TRANSACTION_VERSION": "1",
-    "UNIQUE_BOOKMARK_TAG": "",
-    "UNIQUE_CLIENT_TAG": "",
-    "UNIQUE_POSITION": "INVALID[]",
-    "UNIQUE_SERVER_TAG": "google_chrome_autofill",
-    "isDirty": false,
-    "serverModelType": "Autofill"
+    'SYNCING': false,
+    'TRANSACTION_VERSION': '1',
+    'UNIQUE_BOOKMARK_TAG': '',
+    'UNIQUE_CLIENT_TAG': '',
+    'UNIQUE_POSITION': 'INVALID[]',
+    'UNIQUE_SERVER_TAG': 'google_chrome_autofill',
+    'isDirty': false,
+    'serverModelType': 'Autofill'
   }, {
-    "ATTACHMENT_METADATA": "",
-    "BASE_SERVER_SPECIFICS": {},
-    "BASE_VERSION": "1394241139528639",
-    "CTIME": "Friday, March 7, 2014 5:12:19 PM",
-    "ID": "sZ:ADqtAZwzc/ol1iaz+yNLjjWak9PBE0o/hATzpqJsyq/HX2xzV2f88" +
-      "FaOrT7HDE4tyn7zx2LWgkAFvZfCA5mOy4p0XFgiY0L+mw==",
-    "IS_DEL": false,
-    "IS_DIR": false,
-    "IS_UNAPPLIED_UPDATE": false,
-    "IS_UNSYNCED": false,
-    "LOCAL_EXTERNAL_ID": "0",
-    "META_HANDLE": "2989",
-    "MTIME": "Friday, March 7, 2014 5:12:19 PM",
-    "NON_UNIQUE_NAME": "autofill_entry|Email|rlsynctet2",
-    "PARENT_ID": "sZ:ADqtAZwzF4GOIyvkI2enSI62AU5p/7MNmvuSSyf7yXJ1Sk" +
-      "Jwpp1YL6bbMkF8inzqW+EO6n2aPJ/uXccW9GHxorBlnKoZAWHVzg==",
-    "SERVER_CTIME": "Friday, March 7, 2014 5:12:19 PM",
-    "SERVER_IS_DEL": false,
-    "SERVER_IS_DIR": false,
-    "SERVER_MTIME": "Friday, March 7, 2014 5:12:19 PM",
-    "SERVER_NON_UNIQUE_NAME": "autofill_entry|Email|rlsynctet2",
-    "SERVER_PARENT_ID": "sZ:ADqtAZwzF4GOIyvkI2enSI62AU5p/7MNmvuSSyf" +
-      "7yXJ1SkJwpp1YL6bbMkF8inzqW+EO6n2aPJ/uXccW9GHxorBlnKoZAWHVzg==",
-    "SERVER_SPECIFICS": {
-      "autofill": {
-        "name": "Email",
-        "usage_timestamp": ["13038713887000000", "13038713890000000"],
-        "value": "rlsynctet2"
+    'ATTACHMENT_METADATA': '',
+    'BASE_SERVER_SPECIFICS': {},
+    'BASE_VERSION': '1394241139528639',
+    'CTIME': 'Friday, March 7, 2014 5:12:19 PM',
+    'ID': 'sZ:ADqtAZwzc/ol1iaz+yNLjjWak9PBE0o/hATzpqJsyq/HX2xzV2f88' +
+      'FaOrT7HDE4tyn7zx2LWgkAFvZfCA5mOy4p0XFgiY0L+mw==',
+    'IS_DEL': false,
+    'IS_DIR': false,
+    'IS_UNAPPLIED_UPDATE': false,
+    'IS_UNSYNCED': false,
+    'LOCAL_EXTERNAL_ID': '0',
+    'META_HANDLE': '2989',
+    'MTIME': 'Friday, March 7, 2014 5:12:19 PM',
+    'NON_UNIQUE_NAME': 'autofill_entry|Email|rlsynctet2',
+    'PARENT_ID': 'sZ:ADqtAZwzF4GOIyvkI2enSI62AU5p/7MNmvuSSyf7yXJ1Sk' +
+      'Jwpp1YL6bbMkF8inzqW+EO6n2aPJ/uXccW9GHxorBlnKoZAWHVzg==',
+    'SERVER_CTIME': 'Friday, March 7, 2014 5:12:19 PM',
+    'SERVER_IS_DEL': false,
+    'SERVER_IS_DIR': false,
+    'SERVER_MTIME': 'Friday, March 7, 2014 5:12:19 PM',
+    'SERVER_NON_UNIQUE_NAME': 'autofill_entry|Email|rlsynctet2',
+    'SERVER_PARENT_ID': 'sZ:ADqtAZwzF4GOIyvkI2enSI62AU5p/7MNmvuSSyf' +
+      '7yXJ1SkJwpp1YL6bbMkF8inzqW+EO6n2aPJ/uXccW9GHxorBlnKoZAWHVzg==',
+    'SERVER_SPECIFICS': {
+      'autofill': {
+        'name': 'Email',
+        'usage_timestamp': ['13038713887000000', '13038713890000000'],
+        'value': 'rlsynctet2'
       }
     },
-    "SERVER_UNIQUE_POSITION": "INVALID[]",
-    "SERVER_VERSION": "1394241139528639",
-    "SPECIFICS": {
-      "autofill": {
-        "name": "Email",
-        "usage_timestamp": ["13038713887000000", "13038713890000000"],
-        "value": "rlsynctet2"
+    'SERVER_UNIQUE_POSITION': 'INVALID[]',
+    'SERVER_VERSION': '1394241139528639',
+    'SPECIFICS': {
+      'autofill': {
+        'name': 'Email',
+        'usage_timestamp': ['13038713887000000', '13038713890000000'],
+        'value': 'rlsynctet2'
       }
     },
-    "SYNCING": false,
-    "TRANSACTION_VERSION": "1",
-    "UNIQUE_BOOKMARK_TAG": "",
-    "UNIQUE_CLIENT_TAG": "EvliorKUf1rLjT+BGkNZp586Tsk=",
-    "UNIQUE_POSITION": "INVALID[]",
-    "UNIQUE_SERVER_TAG": "",
-    "isDirty": false,
-    "serverModelType": "Autofill"
+    'SYNCING': false,
+    'TRANSACTION_VERSION': '1',
+    'UNIQUE_BOOKMARK_TAG': '',
+    'UNIQUE_CLIENT_TAG': 'EvliorKUf1rLjT+BGkNZp586Tsk=',
+    'UNIQUE_POSITION': 'INVALID[]',
+    'UNIQUE_SERVER_TAG': '',
+    'isDirty': false,
+    'serverModelType': 'Autofill'
   }],
-  "type": "Autofill"
+  'type': 'Autofill'
 }];
 
 /**
@@ -160,73 +160,73 @@
  * @const
  */
 HARD_CODED_ABOUT_INFO = {
-  "actionable_error": [
+  'actionable_error': [
     {
-      "is_valid": false,
-      "stat_name": "Error Type",
-      "stat_value": "Uninitialized"
+      'is_valid': false,
+      'stat_name': 'Error Type',
+      'stat_value': 'Uninitialized'
     },
     {
-      "is_valid": false,
-      "stat_name": "Action",
-      "stat_value": "Uninitialized"
+      'is_valid': false,
+      'stat_name': 'Action',
+      'stat_value': 'Uninitialized'
     },
     {
-      "is_valid": false,
-      "stat_name": "URL",
-      "stat_value": "Uninitialized"
+      'is_valid': false,
+      'stat_name': 'URL',
+      'stat_value': 'Uninitialized'
     },
     {
-      "is_valid": false,
-      "stat_name": "Error Description",
-      "stat_value": "Uninitialized"
+      'is_valid': false,
+      'stat_name': 'Error Description',
+      'stat_value': 'Uninitialized'
     }
   ],
-  "actionable_error_detected": false,
-  "details": [
+  'actionable_error_detected': false,
+  'details': [
     {
-      "data": [
+      'data': [
         {
-          "is_valid": true,
-          "stat_name": "Summary",
-          "stat_value": "Sync service initialized"
+          'is_valid': true,
+          'stat_name': 'Summary',
+          'stat_value': 'Sync service initialized'
         }
       ],
-      "is_sensitive": false,
-      "title": "Summary"
+      'is_sensitive': false,
+      'title': 'Summary'
     },
   ],
-  "type_status": [
+  'type_status': [
     {
-      "name": "Model Type",
-      "num_entries": "Total Entries",
-      "num_live": "Live Entries",
-      "status": "header",
-      "value": "Group Type"
+      'name': 'Model Type',
+      'num_entries': 'Total Entries',
+      'num_live': 'Live Entries',
+      'status': 'header',
+      'value': 'Group Type'
     },
     {
-      "name": "Bookmarks",
-      "num_entries": 2793,
-      "num_live": 2793,
-      "status": "ok",
-      "value": "Active: GROUP_UI"
+      'name': 'Bookmarks',
+      'num_entries': 2793,
+      'num_live': 2793,
+      'status': 'ok',
+      'value': 'Active: GROUP_UI'
     },
   ],
-  "unrecoverable_error_detected": false
+  'unrecoverable_error_detected': false
 };
 
 NETWORK_EVENT_DETAILS_1 = {
-  "details":"Notified types: Bookmarks, Autofill",
-  "proto":{},
-  "time":1395874542192.407,
-  "type":"Normal GetUpdate request"
+  'details': 'Notified types: Bookmarks, Autofill',
+  'proto': {},
+  'time': 1395874542192.407,
+  'type': 'Normal GetUpdate request',
 };
 
 NETWORK_EVENT_DETAILS_2 = {
-  "details":"Received error: SYNC_AUTH_ERROR",
-  "proto":{},
-  "time":1395874542192.837,
-  "type":"GetUpdates Response"
+  'details': 'Received error: SYNC_AUTH_ERROR',
+  'proto': {},
+  'time': 1395874542192.837,
+  'type': 'GetUpdates Response',
 };
 
 TEST_F('SyncInternalsWebUITest', 'Uninitialized', function() {
@@ -375,7 +375,7 @@
 TEST_F('SyncInternalsWebUITest', 'DumpSyncEventsToText', function() {
   // Dispatch an event.
   var connectionEvent = new Event('onConnectionStatusChange');
-  connectionEvent.details = {'status': 'CONNECTION_OK'}
+  connectionEvent.details = {'status': 'CONNECTION_OK'};
   chrome.sync.events.dispatchEvent(connectionEvent);
 
   // Click the dump-to-text button.
diff --git a/chrome/browser/ui/webui/sync_setup_browsertest.js b/chrome/browser/ui/webui/sync_setup_browsertest.js
index 6614e9b..9d995af 100644
--- a/chrome/browser/ui/webui/sync_setup_browsertest.js
+++ b/chrome/browser/ui/webui/sync_setup_browsertest.js
@@ -19,7 +19,7 @@
    */
   browsePreload: 'chrome://settings-frame',
 
-  /** @inheritDoc */
+  /** @override */
   preLoad: function() {
     this.makeAndRegisterMockHandler(['SyncSetupConfigure',
                                      'SyncSetupShowSetupUI',
@@ -54,7 +54,7 @@
 SyncSetupWebUITestAsync.prototype = {
   __proto__: SyncSetupWebUITest.prototype,
 
-  /** @inheritDoc */
+  /** @override */
   isAsync: true,
 };
 
diff --git a/chrome/browser/ui/webui/sync_setup_handler.cc b/chrome/browser/ui/webui/sync_setup_handler.cc
index 575afad..d3e6f69 100644
--- a/chrome/browser/ui/webui/sync_setup_handler.cc
+++ b/chrome/browser/ui/webui/sync_setup_handler.cc
@@ -228,6 +228,8 @@
           l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
           base::ASCIIToUTF16(google_util::StringAppendGoogleLocaleParam(
               chrome::kSyncGoogleDashboardURL))));
+  localized_strings->SetString("deleteProfileLabel",
+      l10n_util::GetStringUTF16(IDS_SYNC_STOP_DELETE_PROFILE_LABEL));
   localized_strings->SetString("stopSyncingTitle",
       l10n_util::GetStringUTF16(IDS_SYNC_STOP_SYNCING_DIALOG_TITLE));
   localized_strings->SetString("stopSyncingConfirm",
@@ -779,6 +781,12 @@
   if (GetSyncService())
     ProfileSyncService::SyncEvent(ProfileSyncService::STOP_FROM_OPTIONS);
   SigninManagerFactory::GetForProfile(GetProfile())->SignOut();
+
+  bool delete_profile = false;
+  if (args->GetBoolean(0, &delete_profile) && delete_profile) {
+    web_ui()->CallJavascriptFunction(
+        "BrowserOptions.deleteCurrentProfile");
+  }
 }
 #endif
 
diff --git a/chrome/browser/undo/bookmark_undo_service_test.cc b/chrome/browser/undo/bookmark_undo_service_test.cc
index 0161a0e..d29626d 100644
--- a/chrome/browser/undo/bookmark_undo_service_test.cc
+++ b/chrome/browser/undo/bookmark_undo_service_test.cc
@@ -6,10 +6,10 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
 #include "chrome/browser/undo/bookmark_undo_service_factory.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc
index 313e261..a588a94 100644
--- a/chrome/browser/web_applications/web_app.cc
+++ b/chrome/browser/web_applications/web_app.cc
@@ -442,8 +442,8 @@
       content::kFileScheme,
       content::kFileSystemScheme,
       content::kFtpScheme,
-      content::kHttpScheme,
-      content::kHttpsScheme,
+      url::kHttpScheme,
+      url::kHttpsScheme,
       extensions::kExtensionScheme,
   };
 
diff --git a/chrome/browser/web_applications/web_app_mac.mm b/chrome/browser/web_applications/web_app_mac.mm
index d2c7d49..531a232 100644
--- a/chrome/browser/web_applications/web_app_mac.mm
+++ b/chrome/browser/web_applications/web_app_mac.mm
@@ -36,6 +36,7 @@
 #include "extensions/common/extension.h"
 #include "grit/chrome_unscaled_resources.h"
 #include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
 #import "skia/ext/skia_utils_mac.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -465,24 +466,6 @@
 
 }  // namespace
 
-namespace chrome {
-
-void ShowCreateChromeAppShortcutsDialog(gfx::NativeWindow /*parent_window*/,
-                                        Profile* profile,
-                                        const extensions::Extension* app,
-                                        const base::Closure& close_callback) {
-  // Normally we would show a dialog, but since we always create the app
-  // shortcut in ~/Applications there are no options for the user to choose.
-  web_app::CreateShortcuts(web_app::SHORTCUT_CREATION_BY_USER,
-                           web_app::ShortcutLocations(),
-                           profile,
-                           app);
-  if (!close_callback.is_null())
-    close_callback.Run();
-}
-
-}  // namespace chrome
-
 namespace web_app {
 
 WebAppShortcutCreator::WebAppShortcutCreator(
@@ -862,6 +845,61 @@
       base::Bind(&LaunchShimOnFileThread, shortcut_info));
 }
 
+// Called when the app's ShortcutInfo (with icon) is loaded when creating app
+// shortcuts.
+void CreateAppShortcutInfoLoaded(
+    Profile* profile,
+    const extensions::Extension* app,
+    const base::Callback<void(bool)>& close_callback,
+    const web_app::ShortcutInfo& shortcut_info) {
+  base::scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]);
+
+  NSButton* continue_button = [alert
+      addButtonWithTitle:l10n_util::GetNSString(IDS_CREATE_SHORTCUTS_COMMIT)];
+  [continue_button setKeyEquivalent:@""];
+
+  NSButton* cancel_button =
+      [alert addButtonWithTitle:l10n_util::GetNSString(IDS_CANCEL)];
+  [cancel_button setKeyEquivalent:@"\r"];
+
+  [alert setMessageText:l10n_util::GetNSString(IDS_CREATE_SHORTCUTS_LABEL)];
+  [alert setAlertStyle:NSInformationalAlertStyle];
+
+  base::scoped_nsobject<NSButton> application_folder_checkbox(
+      [[NSButton alloc] initWithFrame:NSZeroRect]);
+  [application_folder_checkbox setButtonType:NSSwitchButton];
+  [application_folder_checkbox
+      setTitle:l10n_util::GetNSString(IDS_CREATE_SHORTCUTS_APP_FOLDER_CHKBOX)];
+  [application_folder_checkbox setState:NSOnState];
+  [application_folder_checkbox sizeToFit];
+  [alert setAccessoryView:application_folder_checkbox];
+
+  const int kIconPreviewSizePixels = 128;
+  const int kIconPreviewTargetSize = 64;
+  const gfx::Image* icon = shortcut_info.favicon.GetBest(
+      kIconPreviewSizePixels, kIconPreviewSizePixels);
+
+  if (icon && !icon->IsEmpty()) {
+    NSImage* icon_image = icon->ToNSImage();
+    [icon_image
+        setSize:NSMakeSize(kIconPreviewTargetSize, kIconPreviewTargetSize)];
+    [alert setIcon:icon_image];
+  }
+
+  bool dialog_accepted = false;
+  if ([alert runModal] == NSAlertFirstButtonReturn &&
+      [application_folder_checkbox state] == NSOnState) {
+    dialog_accepted = true;
+    web_app::CreateShortcuts(web_app::SHORTCUT_CREATION_BY_USER,
+                             web_app::ShortcutLocations(),
+                             profile,
+                             app);
+  }
+
+  if (!close_callback.is_null())
+    close_callback.Run(dialog_accepted);
+}
+
 namespace internals {
 
 bool CreatePlatformShortcuts(
@@ -914,3 +952,21 @@
 }  // namespace internals
 
 }  // namespace web_app
+
+namespace chrome {
+
+void ShowCreateChromeAppShortcutsDialog(
+    gfx::NativeWindow /*parent_window*/,
+    Profile* profile,
+    const extensions::Extension* app,
+    const base::Callback<void(bool)>& close_callback) {
+  web_app::UpdateShortcutInfoAndIconForApp(
+      app,
+      profile,
+      base::Bind(&web_app::CreateAppShortcutInfoLoaded,
+                 profile,
+                 app,
+                 close_callback));
+}
+
+}  // namespace chrome
diff --git a/chrome/browser/resources/web_dev_style/OWNERS b/chrome/browser/web_dev_style/OWNERS
similarity index 100%
rename from chrome/browser/resources/web_dev_style/OWNERS
rename to chrome/browser/web_dev_style/OWNERS
diff --git a/chrome/browser/resources/web_dev_style/__init__.py b/chrome/browser/web_dev_style/__init__.py
similarity index 100%
rename from chrome/browser/resources/web_dev_style/__init__.py
rename to chrome/browser/web_dev_style/__init__.py
diff --git a/chrome/browser/resources/web_dev_style/css_checker.py b/chrome/browser/web_dev_style/css_checker.py
similarity index 100%
rename from chrome/browser/resources/web_dev_style/css_checker.py
rename to chrome/browser/web_dev_style/css_checker.py
diff --git a/chrome/browser/web_dev_style/js_checker.py b/chrome/browser/web_dev_style/js_checker.py
new file mode 100644
index 0000000..0e224aa
--- /dev/null
+++ b/chrome/browser/web_dev_style/js_checker.py
@@ -0,0 +1,255 @@
+# Copyright (c) 2012 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.
+
+"""Presubmit script for Chromium JS resources.
+
+See chrome/browser/PRESUBMIT.py
+"""
+
+class JSChecker(object):
+  def __init__(self, input_api, output_api, file_filter=None):
+    self.input_api = input_api
+    self.output_api = output_api
+    self.file_filter = file_filter
+
+  def RegexCheck(self, line_number, line, regex, message):
+    """Searches for |regex| in |line| to check for a particular style
+       violation, returning a message like the one below if the regex matches.
+       The |regex| must have exactly one capturing group so that the relevant
+       part of |line| can be highlighted. If more groups are needed, use
+       "(?:...)" to make a non-capturing group. Sample message:
+
+       line 6: Use var instead of const.
+           const foo = bar();
+           ^^^^^
+    """
+    match = self.input_api.re.search(regex, line)
+    if match:
+      assert len(match.groups()) == 1
+      start = match.start(1)
+      length = match.end(1) - start
+      return '  line %d: %s\n%s\n%s' % (
+          line_number,
+          message,
+          line,
+          self.error_highlight(start, length))
+    return ''
+
+  def ChromeSendCheck(self, i, line):
+    """Checks for a particular misuse of 'chrome.send'."""
+    return self.RegexCheck(i, line, r"chrome\.send\('[^']+'\s*(, \[\])\)",
+        'Passing an empty array to chrome.send is unnecessary')
+
+  def ConstCheck(self, i, line):
+    """Check for use of the 'const' keyword."""
+    if self.input_api.re.search(r'\*\s+@const', line):
+      # Probably a JsDoc line
+      return ''
+
+    return self.RegexCheck(i, line, r'(?:^|\s|\()(const)\s',
+        'Use /** @const */ var varName; instead of const varName;')
+
+  def EndJsDocCommentCheck(self, i, line):
+    msg = 'End JSDoc comments with */ instead of **/'
+    def _check(regex):
+      return self.RegexCheck(i, line, regex, msg)
+    return _check(r'^\s*(\*\*/)\s*$') or _check(r'/\*\* @[a-zA-Z]+.* (\*\*/)')
+
+  def GetElementByIdCheck(self, i, line):
+    """Checks for use of 'document.getElementById' instead of '$'."""
+    return self.RegexCheck(i, line, r"(document\.getElementById)\('",
+        "Use $('id'), from chrome://resources/js/util.js, instead of "
+        "document.getElementById('id')")
+
+  def InheritDocCheck(self, i, line):
+    """Checks for use of '@inheritDoc' instead of '@override'."""
+    return self.RegexCheck(i, line, r"\* (@inheritDoc)",
+        "@inheritDoc is deprecated, use @override instead")
+
+  def WrapperTypeCheck(self, i, line):
+    """Check for wrappers (new String()) instead of builtins (string)."""
+    return self.RegexCheck(i, line,
+        r"(?:/\*)?\*.*?@(?:param|return|type) ?"     # /** @param/@return/@type
+        r"{[^}]*\b(String|Boolean|Number)\b[^}]*}",  # {(Boolean|Number|String)}
+        "Don't use wrapper types (i.e. new String() or @type {String})")
+
+  def VarNameCheck(self, i, line):
+    """See the style guide. http://goo.gl/uKir6"""
+    return self.RegexCheck(i, line,
+        r"var (?!g_\w+)([a-z]*[_$][\w_$]*)(?<! \$)",
+        "Please use var namesLikeThis <http://goo.gl/uKir6>")
+
+  def error_highlight(self, start, length):
+    """Takes a start position and a length, and produces a row of '^'s to
+       highlight the corresponding part of a string.
+    """
+    return start * ' ' + length * '^'
+
+  def _makeErrorOrWarning(self, error_text, filename):
+    """Takes a few lines of text indicating a style violation and turns it into
+       a PresubmitError (if |filename| is in a directory where we've already
+       taken out all the style guide violations) or a PresubmitPromptWarning
+       (if it's in a directory where we haven't done that yet).
+    """
+    # TODO(tbreisacher): Once we've cleaned up the style nits in all of
+    # resources/ we can get rid of this function.
+    path = self.input_api.os_path
+    resources = path.join(self.input_api.PresubmitLocalPath(), 'resources')
+    dirs = (
+        path.join(resources, 'bookmark_manager'),
+        path.join(resources, 'extensions'),
+        path.join(resources, 'file_manager'),
+        path.join(resources, 'help'),
+        path.join(resources, 'history'),
+        path.join(resources, 'memory_internals'),
+        path.join(resources, 'net_export'),
+        path.join(resources, 'net_internals'),
+        path.join(resources, 'network_action_predictor'),
+        path.join(resources, 'ntp4'),
+        path.join(resources, 'options'),
+        path.join(resources, 'password_manager_internals'),
+        path.join(resources, 'print_preview'),
+        path.join(resources, 'profiler'),
+        path.join(resources, 'sync_promo'),
+        path.join(resources, 'tracing'),
+        path.join(resources, 'uber'),
+    )
+    if filename.startswith(dirs):
+      return self.output_api.PresubmitError(error_text)
+    else:
+      return self.output_api.PresubmitPromptWarning(error_text)
+
+  def RunChecks(self):
+    """Check for violations of the Chromium JavaScript style guide. See
+       http://chromium.org/developers/web-development-style-guide#TOC-JavaScript
+    """
+
+    import sys
+    import warnings
+    old_path = sys.path
+    old_filters = warnings.filters
+
+    try:
+      closure_linter_path = self.input_api.os_path.join(
+          self.input_api.change.RepositoryRoot(),
+          "third_party",
+          "closure_linter")
+      gflags_path = self.input_api.os_path.join(
+          self.input_api.change.RepositoryRoot(),
+          "third_party",
+          "python_gflags")
+
+      sys.path.insert(0, closure_linter_path)
+      sys.path.insert(0, gflags_path)
+
+      warnings.filterwarnings('ignore', category=DeprecationWarning)
+
+      from closure_linter import checker, errors
+      from closure_linter.common import errorhandler
+
+    finally:
+      sys.path = old_path
+      warnings.filters = old_filters
+
+    class ErrorHandlerImpl(errorhandler.ErrorHandler):
+      """Filters out errors that don't apply to Chromium JavaScript code."""
+
+      def __init__(self, re):
+        self._errors = []
+        self.re = re
+
+      def HandleFile(self, filename, first_token):
+        self._filename = filename
+
+      def HandleError(self, error):
+        if (self._valid(error)):
+          error.filename = self._filename
+          self._errors.append(error)
+
+      def GetErrors(self):
+        return self._errors
+
+      def HasErrors(self):
+        return bool(self._errors)
+
+      def _valid(self, error):
+        """Check whether an error is valid. Most errors are valid, with a few
+           exceptions which are listed here.
+        """
+
+        is_grit_statement = bool(
+            self.re.search("</?(include|if)", error.token.line))
+
+        # Ignore missing spaces before "(" until Promise#catch issue is solved.
+        # http://crbug.com/338301
+        if (error.code == errors.MISSING_SPACE and error.token.string == '(' and
+           'catch(' in error.token.line):
+          return False
+
+        return not is_grit_statement and error.code not in [
+            errors.COMMA_AT_END_OF_LITERAL,
+            errors.JSDOC_ILLEGAL_QUESTION_WITH_PIPE,
+            errors.JSDOC_TAG_DESCRIPTION_ENDS_WITH_INVALID_CHARACTER,
+            errors.LINE_TOO_LONG,
+            errors.MISSING_JSDOC_TAG_THIS,
+        ]
+
+    results = []
+
+    affected_files = self.input_api.change.AffectedFiles(
+        file_filter=self.file_filter,
+        include_deletes=False)
+    affected_js_files = filter(lambda f: f.LocalPath().endswith('.js'),
+                               affected_files)
+    for f in affected_js_files:
+      error_lines = []
+
+      # Check for the following:
+      # * document.getElementById()
+      # * the 'const' keyword
+      # * Passing an empty array to 'chrome.send()'
+      for i, line in enumerate(f.NewContents(), start=1):
+        error_lines += filter(None, [
+            self.ChromeSendCheck(i, line),
+            self.ConstCheck(i, line),
+            self.GetElementByIdCheck(i, line),
+            self.InheritDocCheck(i, line),
+            self.WrapperTypeCheck(i, line),
+            self.VarNameCheck(i, line),
+        ])
+
+      # Use closure_linter to check for several different errors
+      error_handler = ErrorHandlerImpl(self.input_api.re)
+      js_checker = checker.JavaScriptStyleChecker(error_handler)
+      js_checker.Check(self.input_api.os_path.join(
+          self.input_api.change.RepositoryRoot(),
+          f.LocalPath()))
+
+      for error in error_handler.GetErrors():
+        highlight = self.error_highlight(
+            error.token.start_index, error.token.length)
+        error_msg = '  line %d: E%04d: %s\n%s\n%s' % (
+            error.token.line_number,
+            error.code,
+            error.message,
+            error.token.line.rstrip(),
+            highlight)
+        error_lines.append(error_msg)
+
+      if error_lines:
+        error_lines = [
+            'Found JavaScript style violations in %s:' %
+            f.LocalPath()] + error_lines
+        results.append(self._makeErrorOrWarning(
+            '\n'.join(error_lines), f.AbsoluteLocalPath()))
+
+    if results:
+      results.append(self.output_api.PresubmitNotifyResult(
+          'See the JavaScript style guide at '
+          'http://www.chromium.org/developers/web-development-style-guide'
+          '#TOC-JavaScript and if you have any feedback about the JavaScript '
+          'PRESUBMIT check, contact tbreisacher@chromium.org or '
+          'dbeam@chromium.org'))
+
+    return results
diff --git a/chrome/browser/web_resource/promo_resource_service_unittest.cc b/chrome/browser/web_resource/promo_resource_service_unittest.cc
index 97cac31..aef4c28 100644
--- a/chrome/browser/web_resource/promo_resource_service_unittest.cc
+++ b/chrome/browser/web_resource/promo_resource_service_unittest.cc
@@ -529,7 +529,7 @@
   GURL promo_server_url = NotificationPromo::PromoServerURL();
   EXPECT_FALSE(promo_server_url.is_empty());
   EXPECT_TRUE(promo_server_url.is_valid());
-  EXPECT_TRUE(promo_server_url.SchemeIs(content::kHttpsScheme));
+  EXPECT_TRUE(promo_server_url.SchemeIs(url::kHttpsScheme));
   // TODO(achuith): Test this better.
 }
 
diff --git a/chrome/browser/webdata/autocomplete_syncable_service.cc b/chrome/browser/webdata/autocomplete_syncable_service.cc
index 39cfe55..d8b9be2 100644
--- a/chrome/browser/webdata/autocomplete_syncable_service.cc
+++ b/chrome/browser/webdata/autocomplete_syncable_service.cc
@@ -286,7 +286,7 @@
 
 void AutocompleteSyncableService::AutofillEntriesChanged(
     const AutofillChangeList& changes) {
-  // Check if sync is on. If we recieve this notification prior to sync being
+  // Check if sync is on. If we receive this notification prior to sync being
   // started, we'll notify sync to start as soon as it can and later process
   // all entries when MergeData..() is called. If we receive this notification
   // sync has exited, it will be synced next time Chrome starts.
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index a648770..d9a31ca 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -100,15 +100,18 @@
   'conditions': [
     ['OS!="ios"', {
       'includes': [
+        '../apps/apps.gypi',
         'chrome_browser_extensions.gypi',
+        'chrome_debugger.gypi',
         'chrome_dll.gypi',
         'chrome_exe.gypi',
         'chrome_installer.gypi',
+        'chrome_plugin.gypi',
         'chrome_renderer.gypi',
         'chrome_tests.gypi',
         'chrome_tests_unit.gypi',
+        'chrome_utility.gypi',
         'policy_templates.gypi',
-        '../apps/apps.gypi',
       ],
       'targets': [
         {
@@ -127,250 +130,6 @@
             }]
           ],
         },
-        {
-          'target_name': 'debugger',
-          'type': 'static_library',
-          'variables': { 'enable_wexit_time_destructors': 1, },
-          'dependencies': [
-            'chrome_resources.gyp:chrome_extra_resources',
-            'chrome_resources.gyp:chrome_resources',
-            'chrome_resources.gyp:chrome_strings',
-            'chrome_resources.gyp:theme_resources',
-            'common/extensions/api/api.gyp:chrome_api',
-            '../base/base.gyp:base',
-            '../content/content.gyp:content_browser',
-            '../net/net.gyp:http_server',
-            '../net/net.gyp:net',
-            '../skia/skia.gyp:skia',
-            '../third_party/icu/icu.gyp:icui18n',
-            '../third_party/icu/icu.gyp:icuuc',
-            '../third_party/leveldatabase/leveldatabase.gyp:leveldatabase',
-            '../third_party/libusb/libusb.gyp:libusb',
-          ],
-          'include_dirs': [
-            '..',
-          ],
-          'sources': [
-            'browser/devtools/device/adb/adb_client_socket.cc',
-            'browser/devtools/device/adb/adb_client_socket.h',
-            'browser/devtools/device/android_device_manager.cc',
-            'browser/devtools/device/android_device_manager.h',
-            'browser/devtools/device/android_web_socket.cc',
-            'browser/devtools/device/devtools_android_bridge.cc',
-            'browser/devtools/device/devtools_android_bridge.h',
-            'browser/devtools/device/port_forwarding_controller.cc',
-            'browser/devtools/device/port_forwarding_controller.h',
-            'browser/devtools/device/usb/android_rsa.cc',
-            'browser/devtools/device/usb/android_rsa.h',
-            'browser/devtools/device/usb/android_usb_device.cc',
-            'browser/devtools/device/usb/android_usb_device.h',
-            'browser/devtools/device/usb/android_usb_socket.cc',
-            'browser/devtools/device/usb/android_usb_socket.h',
-            'browser/devtools/browser_list_tabcontents_provider.cc',
-            'browser/devtools/browser_list_tabcontents_provider.h',
-            'browser/devtools/devtools_contents_resizing_strategy.cc',
-            'browser/devtools/devtools_contents_resizing_strategy.h',
-            'browser/devtools/devtools_embedder_message_dispatcher.cc',
-            'browser/devtools/devtools_embedder_message_dispatcher.h',
-            'browser/devtools/devtools_file_helper.cc',
-            'browser/devtools/devtools_file_helper.h',
-            'browser/devtools/devtools_file_system_indexer.cc',
-            'browser/devtools/devtools_file_system_indexer.h',
-            'browser/devtools/devtools_protocol.cc',
-            'browser/devtools/devtools_protocol.h',
-            'browser/devtools/devtools_target_impl.cc',
-            'browser/devtools/devtools_target_impl.h',
-            'browser/devtools/devtools_targets_ui.cc',
-            'browser/devtools/devtools_targets_ui.h',
-            'browser/devtools/devtools_toggle_action.cc',
-            'browser/devtools/devtools_toggle_action.h',
-            'browser/devtools/devtools_ui_bindings.cc',
-            'browser/devtools/devtools_ui_bindings.h',
-            'browser/devtools/devtools_window.cc',
-            'browser/devtools/devtools_window.h',
-            'browser/devtools/remote_debugging_server.cc',
-            'browser/devtools/remote_debugging_server.h',
-          ],
-          'conditions': [
-            ['OS=="android"', {
-              'dependencies!': [
-                '../third_party/libusb/libusb.gyp:libusb',
-              ],
-              'sources!': [
-                'browser/devtools/device/usb/android_rsa.cc',
-                'browser/devtools/browser_list_tabcontents_provider.cc',
-                'browser/devtools/devtools_file_system_indexer.cc',
-                'browser/devtools/devtools_target_impl.cc',
-                'browser/devtools/devtools_window.cc',
-                'browser/devtools/devtools_window_base.cc',
-                'browser/devtools/remote_debugging_server.cc',
-              ],
-            }],
-            ['debug_devtools==1', {
-              'defines': [
-                'DEBUG_DEVTOOLS=1',
-               ],
-            }],
-          ],
-          # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-          'msvs_disabled_warnings': [ 4267, ],
-        },
-        {
-          'target_name': 'plugin',
-          'type': 'static_library',
-          'variables': { 'enable_wexit_time_destructors': 1, },
-          'dependencies': [
-            'chrome_resources.gyp:chrome_strings',
-            '../base/base.gyp:base',
-            '../content/content.gyp:content_plugin',
-          ],
-          'sources': [
-            'plugin/chrome_content_plugin_client.cc',
-            'plugin/chrome_content_plugin_client.h',
-          ],
-          'include_dirs': [
-            '..',
-            '<(grit_out_dir)',
-          ],
-        },
-        {
-          'target_name': 'utility',
-          'type': 'static_library',
-          'variables': { 'enable_wexit_time_destructors': 1, },
-          'dependencies': [
-            'common/extensions/api/api.gyp:chrome_api',
-            '../base/base.gyp:base',
-            '../components/components_strings.gyp:components_strings',
-            '../content/content.gyp:content_common',
-            '../content/content.gyp:content_utility',
-            '../media/media.gyp:media',
-            '../skia/skia.gyp:skia',
-            '../third_party/libexif/libexif.gyp:libexif',
-            '../third_party/libxml/libxml.gyp:libxml',
-            'common',
-            '<(DEPTH)/chrome/chrome_resources.gyp:chrome_resources',
-            '<(DEPTH)/chrome/chrome_resources.gyp:chrome_strings',
-          ],
-          'sources': [
-            'utility/chrome_content_utility_client.cc',
-            'utility/chrome_content_utility_client.h',
-            'utility/chrome_content_utility_ipc_whitelist.cc',
-            'utility/chrome_content_utility_ipc_whitelist.h',
-            'utility/cloud_print/bitmap_image.cc',
-            'utility/cloud_print/bitmap_image.h',
-            'utility/cloud_print/pwg_encoder.cc',
-            'utility/cloud_print/pwg_encoder.h',
-            'utility/extensions/unpacker.cc',
-            'utility/extensions/unpacker.h',
-            'utility/image_writer/error_messages.cc',
-            'utility/image_writer/error_messages.h',
-            'utility/image_writer/image_writer.cc',
-            'utility/image_writer/image_writer.h',
-            'utility/image_writer/image_writer_handler.cc',
-            'utility/image_writer/image_writer_handler.h',
-            'utility/importer/bookmark_html_reader.cc',
-            'utility/importer/bookmark_html_reader.h',
-            'utility/importer/bookmarks_file_importer.cc',
-            'utility/importer/bookmarks_file_importer.h',
-            'utility/importer/external_process_importer_bridge.cc',
-            'utility/importer/external_process_importer_bridge.h',
-            'utility/importer/favicon_reencode.cc',
-            'utility/importer/favicon_reencode.h',
-            'utility/importer/firefox_importer.cc',
-            'utility/importer/firefox_importer.h',
-            'utility/importer/ie_importer_win.cc',
-            'utility/importer/ie_importer_win.h',
-            'utility/importer/importer.cc',
-            'utility/importer/importer.h',
-            'utility/importer/importer_creator.cc',
-            'utility/importer/importer_creator.h',
-            'utility/importer/nss_decryptor.cc',
-            'utility/importer/nss_decryptor.h',
-            'utility/importer/nss_decryptor_mac.h',
-            'utility/importer/nss_decryptor_mac.mm',
-            'utility/importer/nss_decryptor_win.cc',
-            'utility/importer/nss_decryptor_win.h',
-            'utility/importer/safari_importer.h',
-            'utility/importer/safari_importer.mm',
-            'utility/media_galleries/image_metadata_extractor.cc',
-            'utility/media_galleries/image_metadata_extractor.h',
-            'utility/media_galleries/ipc_data_source.cc',
-            'utility/media_galleries/ipc_data_source.h',
-            'utility/media_galleries/itunes_pref_parser_win.cc',
-            'utility/media_galleries/itunes_pref_parser_win.h',
-            'utility/media_galleries/media_metadata_parser.cc',
-            'utility/media_galleries/media_metadata_parser.h',
-            'utility/profile_import_handler.cc',
-            'utility/profile_import_handler.h',
-            'utility/utility_message_handler.h',
-            'utility/web_resource_unpacker.cc',
-            'utility/web_resource_unpacker.h',
-          ],
-          'include_dirs': [
-            '..',
-            '<(grit_out_dir)',
-          ],
-          'export_dependent_settings': [
-            'common/extensions/api/api.gyp:chrome_api',
-          ],
-          'conditions': [
-            ['OS=="win" or OS=="mac"', {
-              'dependencies': [
-                '../components/components.gyp:wifi_component',
-              ],
-              'sources': [
-                'utility/media_galleries/iapps_xml_utils.cc',
-                'utility/media_galleries/iapps_xml_utils.h',
-                'utility/media_galleries/itunes_library_parser.cc',
-                'utility/media_galleries/itunes_library_parser.h',
-                'utility/media_galleries/picasa_album_table_reader.cc',
-                'utility/media_galleries/picasa_album_table_reader.h',
-                'utility/media_galleries/picasa_albums_indexer.cc',
-                'utility/media_galleries/picasa_albums_indexer.h',
-                'utility/media_galleries/pmp_column_reader.cc',
-                'utility/media_galleries/pmp_column_reader.h',
-              ],
-            }],
-            ['OS=="mac"', {
-              'sources': [
-                'utility/media_galleries/iphoto_library_parser.cc',
-                'utility/media_galleries/iphoto_library_parser.h',
-              ],
-            }],
-            ['use_openssl==1', {
-              'sources!': [
-                'utility/importer/nss_decryptor.cc',
-              ]
-            }],
-            ['OS!="win" and OS!="mac" and use_openssl==0', {
-              'dependencies': [
-                '../crypto/crypto.gyp:crypto',
-              ],
-              'sources': [
-                'utility/importer/nss_decryptor_system_nss.cc',
-                'utility/importer/nss_decryptor_system_nss.h',
-              ],
-            }],
-            ['OS=="android"', {
-              'dependencies!': [
-                '../third_party/libexif/libexif.gyp:libexif',
-              ],
-              'sources/': [
-                ['exclude', '^utility/importer/'],
-                ['exclude', '^utility/media_galleries/'],
-                ['exclude', '^utility/profile_import_handler\.cc'],
-              ],
-            }],
-            ['enable_mdns == 1', {
-              'sources': [
-                'utility/local_discovery/service_discovery_message_handler.cc',
-                'utility/local_discovery/service_discovery_message_handler.h',
-              ]
-            }],
-          ],
-          # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-          'msvs_disabled_warnings': [ 4267, ],
-        },
       ],
     }],  # OS!="ios"
     ['OS=="mac"', {
diff --git a/chrome/chrome_android.gypi b/chrome/chrome_android.gypi
index 00a3af2..8ba1f24 100644
--- a/chrome/chrome_android.gypi
+++ b/chrome/chrome_android.gypi
@@ -39,8 +39,7 @@
             }],
           ],
         }],
-        # TODO(dmikurube): Kill android_use_tcmalloc. http://crbug.com/345554
-        [ '(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and android_use_tcmalloc==1)', {
+        [ 'use_allocator!="none"', {
           'dependencies': [
             '../base/allocator/allocator.gyp:allocator', ],
         }],
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index c6e24a3..d04f617 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -21,7 +21,6 @@
         'chrome_resources.gyp:theme_resources',
         'common',
         'common_net',
-        'feedback_proto',
         'in_memory_url_index_cache_proto',
         'probe_message_proto',
         'safe_browsing_proto',
@@ -31,11 +30,14 @@
         '../components/components.gyp:bookmarks_core_browser',
         '../components/components.gyp:captive_portal',
         '../components/components.gyp:cloud_devices_common',
+        '../components/components.gyp:component_metrics_proto',
         '../components/components.gyp:data_reduction_proxy_browser',
         '../components/components.gyp:domain_reliability',
         '../components/components.gyp:favicon_base',
         '../components/components.gyp:favicon_core',
+        '../components/components.gyp:feedback_component',
         '../components/components.gyp:infobars_core',
+        '../components/components.gyp:metrics',
         '../components/components.gyp:navigation_metrics',
         '../components/components.gyp:os_crypt',
         '../components/components.gyp:password_manager_core_browser',
@@ -345,22 +347,9 @@
         'browser/browsing_data/browsing_data_cookie_helper.h',
         'browser/browsing_data/cookies_tree_model.cc',
         'browser/browsing_data/cookies_tree_model.h',
-        'browser/feedback/feedback_data.cc',
-        'browser/feedback/feedback_data.h',
         'browser/feedback/feedback_profile_observer.cc',
         'browser/feedback/feedback_profile_observer.h',
-        'browser/feedback/feedback_report.cc',
-        'browser/feedback/feedback_report.h',
-        'browser/feedback/feedback_util.cc',
-        'browser/feedback/feedback_util.h',
-        'browser/feedback/feedback_uploader.cc',
-        'browser/feedback/feedback_uploader.h',
-        'browser/feedback/feedback_uploader_chrome.cc',
-        'browser/feedback/feedback_uploader_chrome.h',
-        'browser/feedback/feedback_uploader_delegate.cc',
-        'browser/feedback/feedback_uploader_delegate.h',
-        'browser/feedback/feedback_uploader_factory.cc',
-        'browser/feedback/feedback_uploader_factory.h',
+        'browser/feedback/show_feedback_page.cc',
         'browser/feedback/system_logs/about_system_logs_fetcher.cc',
         'browser/feedback/system_logs/about_system_logs_fetcher.h',
         'browser/feedback/system_logs/scrubbed_system_logs_fetcher.cc',
@@ -371,8 +360,6 @@
         'browser/feedback/system_logs/log_sources/chrome_internal_log_source.h',
         'browser/feedback/system_logs/log_sources/memory_details_log_source.cc',
         'browser/feedback/system_logs/log_sources/memory_details_log_source.h',
-        'browser/feedback/tracing_manager.cc',
-        'browser/feedback/tracing_manager.h',
         'browser/captive_portal/captive_portal_login_detector.cc',
         'browser/captive_portal/captive_portal_login_detector.h',
         'browser/captive_portal/captive_portal_service.cc',
@@ -723,6 +710,8 @@
         'browser/guest_view/guest_view_constants.h',
         'browser/guest_view/guest_view_base.cc',
         'browser/guest_view/guest_view_base.h',
+        'browser/guest_view/guest_view_manager.cc',
+        'browser/guest_view/guest_view_manager.h',
         'browser/guest_view/guest_view.h',
         'browser/guest_view/web_view/context_menu_content_type_web_view.cc',
         'browser/guest_view/web_view/context_menu_content_type_web_view.h',
@@ -865,6 +854,8 @@
         'browser/idle_win.cc',
         'browser/image_decoder.cc',
         'browser/image_decoder.h',
+        'browser/image_holder.cc',
+        'browser/image_holder.h',
         'browser/importer/external_process_importer_client.cc',
         'browser/importer/external_process_importer_client.h',
         'browser/importer/external_process_importer_host.cc',
@@ -1071,8 +1062,6 @@
         'browser/media/desktop_media_picker.h',
         'browser/media/desktop_streams_registry.cc',
         'browser/media/desktop_streams_registry.h',
-        'browser/media/encrypted_media_message_filter_android.cc',
-        'browser/media/encrypted_media_message_filter_android.h',
         'browser/media/media_capture_devices_dispatcher.cc',
         'browser/media/media_capture_devices_dispatcher.h',
         'browser/media/media_device_id_salt.cc',
@@ -1213,6 +1202,10 @@
         'browser/metrics/metrics_service_android.cc',
         'browser/metrics/metrics_service.cc',
         'browser/metrics/metrics_service.h',
+        'browser/metrics/metrics_services_manager.cc',
+        'browser/metrics/metrics_services_manager.h',
+        'browser/metrics/metrics_state_manager.cc',
+        'browser/metrics/metrics_state_manager.h',
         'browser/metrics/perf_provider_chromeos.cc',
         'browser/metrics/perf_provider_chromeos.h',
         'browser/metrics/thread_watcher.cc',
@@ -1341,6 +1334,8 @@
         'browser/notifications/desktop_notification_service_factory.h',
         'browser/notifications/extension_welcome_notification.cc',
         'browser/notifications/extension_welcome_notification.h',
+        'browser/notifications/google_now_notification_stats_collector.cc',
+        'browser/notifications/google_now_notification_stats_collector.h',
         'browser/notifications/message_center_notification_manager.cc',
         'browser/notifications/message_center_notification_manager.h',
         'browser/notifications/message_center_notification_manager_win.cc',
@@ -1372,8 +1367,6 @@
         'browser/notifications/sync_notifier/chrome_notifier_service.h',
         'browser/notifications/sync_notifier/chrome_notifier_service_factory.cc',
         'browser/notifications/sync_notifier/chrome_notifier_service_factory.h',
-        'browser/notifications/sync_notifier/image_holder.cc',
-        'browser/notifications/sync_notifier/image_holder.h',
         'browser/notifications/sync_notifier/synced_notification.cc',
         'browser/notifications/sync_notifier/synced_notification.h',
         'browser/notifications/sync_notifier/synced_notification_app_info.cc',
@@ -1492,14 +1485,12 @@
         'browser/policy/cloud/user_cloud_policy_manager_factory.h',
         'browser/policy/cloud/user_policy_signin_service.cc',
         'browser/policy/cloud/user_policy_signin_service.h',
-        'browser/policy/cloud/user_policy_signin_service_android.cc',
-        'browser/policy/cloud/user_policy_signin_service_android.h',
         'browser/policy/cloud/user_policy_signin_service_base.cc',
         'browser/policy/cloud/user_policy_signin_service_base.h',
         'browser/policy/cloud/user_policy_signin_service_factory.cc',
         'browser/policy/cloud/user_policy_signin_service_factory.h',
-        'browser/policy/cloud/user_policy_signin_service_ios.h',
-        'browser/policy/cloud/user_policy_signin_service_ios.mm',
+        'browser/policy/cloud/user_policy_signin_service_mobile.cc',
+        'browser/policy/cloud/user_policy_signin_service_mobile.h',
         'browser/policy/configuration_policy_handler_list_factory.cc',
         'browser/policy/configuration_policy_handler_list_factory.h',
         'browser/policy/device_management_service_configuration.cc',
@@ -1742,6 +1733,8 @@
         'browser/profiles/profile.h',
         'browser/profiles/profile_android.cc',
         'browser/profiles/profile_android.h',
+        'browser/profiles/profile_avatar_downloader.cc',
+        'browser/profiles/profile_avatar_downloader.h',
         'browser/profiles/profile_destroyer.cc',
         'browser/profiles/profile_destroyer.h',
         'browser/profiles/profile_downloader.cc',
@@ -1917,6 +1910,7 @@
         'browser/safe_json_parser.h',
         'browser/screensaver_window_finder_x11.cc',
         'browser/screensaver_window_finder_x11.h',
+        'browser/search/hotword_client.h',
         'browser/search/hotword_service.cc',
         'browser/search/hotword_service.h',
         'browser/search/hotword_service_factory.cc',
@@ -1947,6 +1941,8 @@
         'browser/search/suggestions/suggestions_source.h',
         'browser/search_engines/default_search_manager.cc',
         'browser/search_engines/default_search_manager.h',
+        'browser/search_engines/default_search_pref_migration.cc',
+        'browser/search_engines/default_search_pref_migration.h',
         'browser/search_engines/default_search_policy_handler.cc',
         'browser/search_engines/default_search_policy_handler.h',
         'browser/search_engines/search_engine_type.h',
@@ -2054,6 +2050,8 @@
         'browser/signin/profile_oauth2_token_service_factory.h',
         'browser/signin/profile_oauth2_token_service_request.cc',
         'browser/signin/profile_oauth2_token_service_request.h',
+        'browser/signin/screenlock_bridge.cc',
+        'browser/signin/screenlock_bridge.h',
         'browser/signin/signin_error_notifier_ash.cc',
         'browser/signin/signin_error_notifier_ash.h',
         'browser/signin/signin_error_notifier_factory_ash.cc',
@@ -2078,14 +2076,8 @@
         'browser/site_details.h',
         'browser/speech/chrome_speech_recognition_manager_delegate.cc',
         'browser/speech/chrome_speech_recognition_manager_delegate.h',
-        'browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.cc',
-        'browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui.h',
         'browser/speech/extension_api/tts_extension_api_constants.cc',
         'browser/speech/extension_api/tts_extension_api_constants.h',
-        'browser/speech/speech_recognition_bubble.cc',
-        'browser/speech/speech_recognition_bubble.h',
-        'browser/speech/speech_recognition_bubble_controller.cc',
-        'browser/speech/speech_recognition_bubble_controller.h',
         'browser/speech/tts_android.cc',
         'browser/speech/tts_android.h',
         'browser/speech/tts_chromeos.cc',
@@ -2483,6 +2475,8 @@
         'browser/thumbnails/content_based_thumbnailing_algorithm.h',
         'browser/thumbnails/simple_thumbnail_crop.cc',
         'browser/thumbnails/simple_thumbnail_crop.h',
+        'browser/thumbnails/thumbnail_list_source.cc',
+        'browser/thumbnails/thumbnail_list_source.h',
         'browser/thumbnails/thumbnail_service.h',
         'browser/thumbnails/thumbnail_service_factory.cc',
         'browser/thumbnails/thumbnail_service_factory.h',
@@ -2774,6 +2768,8 @@
               'sources!': [
                 'browser/policy/managed_bookmarks_policy_handler.cc',
                 'browser/policy/managed_bookmarks_policy_handler.h',
+                'browser/policy/cloud/user_policy_signin_service_mobile.cc',
+                'browser/policy/cloud/user_policy_signin_service_mobile.h',
               ],
             }],
             ['OS=="ios"', {
@@ -2796,8 +2792,8 @@
                 ['include', '^browser/policy/cloud/user_policy_signin_service_base.h'],
                 ['include', '^browser/policy/cloud/user_policy_signin_service_factory.cc'],
                 ['include', '^browser/policy/cloud/user_policy_signin_service_factory.h'],
-                ['include', '^browser/policy/cloud/user_policy_signin_service_ios.h'],
-                ['include', '^browser/policy/cloud/user_policy_signin_service_ios.mm'],
+                ['include', '^browser/policy/cloud/user_policy_signin_service_mobile.cc'],
+                ['include', '^browser/policy/cloud/user_policy_signin_service_mobile.h'],
                 ['include', '^browser/policy/configuration_policy_handler_list_factory.cc'],
                 ['include', '^browser/policy/configuration_policy_handler_list_factory.h'],
                 ['include', '^browser/policy/managed_bookmarks_policy_handler.cc'],
@@ -2962,6 +2958,8 @@
             'browser/policy/cloud/user_policy_signin_service_base.h',
             'browser/policy/cloud/user_policy_signin_service_factory.cc',
             'browser/policy/cloud/user_policy_signin_service_factory.h',
+            'browser/policy/cloud/user_policy_signin_service_mobile.cc',
+            'browser/policy/cloud/user_policy_signin_service_mobile.h',
             'browser/profiles/avatar_menu_desktop.cc',
             'browser/profiles/avatar_menu_actions_desktop.cc',
             'browser/profiles/avatar_menu_actions_desktop.h',
@@ -3071,12 +3069,6 @@
             'browser/net/nss_context.h',
           ],
         }],
-        ['input_speech==0', {
-          'sources/': [
-            ['exclude', '^browser/speech/chrome_speech_recognition_manager_delegate_bubble_ui'],
-            ['exclude', '^browser/speech/speech_recognition_bubble'],
-          ],
-        }],
         ['notifications==0', {
           'sources/': [
             ['exclude', '^browser/notifications/'],
@@ -3146,6 +3138,7 @@
         }],
         ['OS=="android"', {
           'dependencies': [
+            '../components/components.gyp:cdm_browser',
             '../components/components.gyp:web_contents_delegate_android',
             'chrome_browser_jni_headers',
           ],
@@ -3217,11 +3210,6 @@
             'browser/download/download_shelf.cc',
             'browser/download/download_shelf_context_menu.cc',
             'browser/drive/drive_switches.cc',
-            'browser/feedback/proto/annotations.proto',
-            'browser/feedback/proto/chrome.proto',
-            'browser/feedback/proto/common.proto',
-            'browser/feedback/proto/dom.proto',
-            'browser/feedback/proto/math.proto',
             'browser/gpu/chrome_gpu_util.cc',
             'browser/idle_android.cc',
             'browser/idle.cc',
@@ -3524,25 +3512,6 @@
       'includes': [ '../build/protoc.gypi' ]
     },
     {
-      # Protobuf compiler / generate rule for feedback
-      'target_name': 'feedback_proto',
-      'type': 'static_library',
-      'sources': [
-        'browser/feedback/proto/annotations.proto',
-        'browser/feedback/proto/chrome.proto',
-        'browser/feedback/proto/common.proto',
-        'browser/feedback/proto/dom.proto',
-        'browser/feedback/proto/extension.proto',
-        'browser/feedback/proto/math.proto',
-        'browser/feedback/proto/web.proto',
-      ],
-      'variables': {
-        'proto_in_dir': 'browser/feedback/proto',
-        'proto_out_dir': 'chrome/browser/feedback/proto',
-      },
-      'includes': [ '../build/protoc.gypi' ]
-    },
-    {
       # Protobuf compiler / generator for the safebrowsing reporting
       # protocol buffer.
       'target_name': 'safe_browsing_report_proto',
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index a16601a..58cf1fd 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -36,7 +36,6 @@
         'debugger',
         'device_policy_proto',
         'drive_proto',
-        'feedback_proto',
         'in_memory_url_index_cache_proto',
         'installer_util',
         'safe_browsing_proto',
@@ -381,8 +380,12 @@
         'browser/chromeos/file_system_provider/mount_path_util.cc',
         'browser/chromeos/file_system_provider/mount_path_util.h',
         'browser/chromeos/file_system_provider/observer.h',
+        'browser/chromeos/file_system_provider/operations/get_metadata.cc',
+        'browser/chromeos/file_system_provider/operations/get_metadata.h',
         'browser/chromeos/file_system_provider/operations/operation.cc',
         'browser/chromeos/file_system_provider/operations/operation.h',
+        'browser/chromeos/file_system_provider/operations/read_directory.cc',
+        'browser/chromeos/file_system_provider/operations/read_directory.h',
         'browser/chromeos/file_system_provider/operations/unmount.cc',
         'browser/chromeos/file_system_provider/operations/unmount.h',
         'browser/chromeos/file_system_provider/provided_file_system.cc',
@@ -796,6 +799,8 @@
         'browser/chromeos/policy/recommendation_restorer_factory.h',
         'browser/chromeos/policy/server_backed_device_state.cc',
         'browser/chromeos/policy/server_backed_device_state.h',
+        'browser/chromeos/policy/server_backed_state_keys_broker.cc',
+        'browser/chromeos/policy/server_backed_state_keys_broker.h',
         'browser/chromeos/policy/user_cloud_external_data_manager.cc',
         'browser/chromeos/policy/user_cloud_external_data_manager.h',
         'browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc',
@@ -995,12 +1000,12 @@
             'browser/chromeos/extensions/file_manager/private_api_util.h',
             'browser/chromeos/extensions/file_system_provider/file_system_provider_api.cc',
             'browser/chromeos/extensions/file_system_provider/file_system_provider_api.h',
+            'browser/chromeos/extensions/file_system_provider/provider_function.cc',
+            'browser/chromeos/extensions/file_system_provider/provider_function.h',
             'browser/chromeos/extensions/first_run_private_api.cc',
             'browser/chromeos/extensions/first_run_private_api.h',
             'browser/chromeos/extensions/input_method_api.cc',
             'browser/chromeos/extensions/input_method_api.h',
-            'browser/chromeos/extensions/screenlock_private_api.cc',
-            'browser/chromeos/extensions/screenlock_private_api.h',
             'browser/chromeos/extensions/media_player_api.cc',
             'browser/chromeos/extensions/media_player_api.h',
             'browser/chromeos/extensions/wallpaper_manager_util.cc',
@@ -1076,16 +1081,13 @@
             '../ui/ozone/ozone.gyp:ozone',
           ],
           'sources!': [
+            'browser/chromeos/events/system_key_event_listener.cc',
+            'browser/chromeos/events/system_key_event_listener.h',
+            'browser/chromeos/events/xinput_hierarchy_changed_event_listener.cc',
+            'browser/chromeos/events/xinput_hierarchy_changed_event_listener.h',
             'browser/chromeos/input_method/input_method_engine.cc',
             'browser/chromeos/input_method/input_method_engine.h',
           ],
-          'sources/': [
-            ['exclude', '^browser/chromeos/events/'],
-            ['include', '^browser/chromeos/events/event_rewriter_controller.cc'],
-            ['include', '^browser/chromeos/events/event_rewriter_controller.h'],
-            ['include', '^browser/chromeos/events/keyboard_driven_event_rewriter.cc'],
-            ['include', '^browser/chromeos/events/keyboard_driven_event_rewriter.h'],
-          ],
         }],
       ],
     },
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index 779f594..83509f3 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -49,7 +49,6 @@
         '../third_party/icu/icu.gyp:icui18n',
         '../third_party/icu/icu.gyp:icuuc',
         '../third_party/leveldatabase/leveldatabase.gyp:leveldatabase',
-        '../third_party/libusb/libusb.gyp:libusb',
         '../third_party/webrtc/modules/modules.gyp:desktop_capture',
         '../ui/accessibility/accessibility.gyp:ax_gen',
         '../ui/base/strings/ui_strings.gyp:ui_strings',
@@ -117,6 +116,8 @@
         'browser/extensions/activity_log/database_string_table.h',
         'browser/extensions/activity_log/fullstream_ui_policy.cc',
         'browser/extensions/activity_log/fullstream_ui_policy.h',
+        'browser/extensions/activity_log/hashed_ad_network_database.cc',
+        'browser/extensions/activity_log/hashed_ad_network_database.h',
         'browser/extensions/activity_log/uma_policy.cc',
         'browser/extensions/activity_log/uma_policy.h',
         'browser/extensions/activity_log/web_request_constants.cc',
@@ -162,6 +163,8 @@
         'browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h',
         'browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc',
         'browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h',
+        'browser/extensions/api/bluetooth_low_energy/utils.cc',
+        'browser/extensions/api/bluetooth_low_energy/utils.h',
         'browser/extensions/api/bluetooth_socket/bluetooth_socket_api.cc',
         'browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h',
         'browser/extensions/api/bluetooth_socket/bluetooth_socket_event_dispatcher.cc',
@@ -184,6 +187,8 @@
         'browser/extensions/api/braille_display_private/brlapi_connection.h',
         'browser/extensions/api/braille_display_private/stub_braille_controller.cc',
         'browser/extensions/api/braille_display_private/stub_braille_controller.h',
+        'browser/extensions/api/browser/browser_api.cc',
+        'browser/extensions/api/browser/browser_api.h',
         'browser/extensions/api/browsing_data/browsing_data_api.cc',
         'browser/extensions/api/browsing_data/browsing_data_api.h',
         'browser/extensions/api/capture_web_contents_function.cc',
@@ -470,8 +475,8 @@
         'browser/extensions/api/push_messaging/push_messaging_invalidation_mapper.h',
         'browser/extensions/api/reading_list_private/reading_list_private_api.cc',
         'browser/extensions/api/reading_list_private/reading_list_private_api.h',
-        'browser/extensions/api/runtime/runtime_api.cc',
-        'browser/extensions/api/runtime/runtime_api.h',
+        'browser/extensions/api/screenlock_private/screenlock_private_api.cc',
+        'browser/extensions/api/screenlock_private/screenlock_private_api.h',
         'browser/extensions/api/serial/serial_api.cc',
         'browser/extensions/api/serial/serial_api.h',
         'browser/extensions/api/serial/serial_connection.cc',
@@ -579,10 +584,6 @@
         'browser/extensions/api/tabs/windows_util.h',
         'browser/extensions/api/top_sites/top_sites_api.cc',
         'browser/extensions/api/top_sites/top_sites_api.h',
-        'browser/extensions/api/usb/usb_api.cc',
-        'browser/extensions/api/usb/usb_api.h',
-        'browser/extensions/api/usb/usb_device_resource.cc',
-        'browser/extensions/api/usb/usb_device_resource.h',
         'browser/extensions/api/web_navigation/frame_navigation_state.cc',
         'browser/extensions/api/web_navigation/frame_navigation_state.h',
         'browser/extensions/api/web_navigation/web_navigation_api.cc',
@@ -651,6 +652,8 @@
         'browser/extensions/chrome_extensions_browser_client.h',
         'browser/extensions/chrome_notification_observer.cc',
         'browser/extensions/chrome_notification_observer.h',
+        'browser/extensions/api/runtime/chrome_runtime_api_delegate.cc',
+        'browser/extensions/api/runtime/chrome_runtime_api_delegate.h',
         'browser/extensions/component_loader.cc',
         'browser/extensions/component_loader.h',
         'browser/extensions/context_menu_matcher.cc',
@@ -1011,7 +1014,7 @@
             ['include', '^browser/extensions/api/preference/preference_api.cc'],
             ['include', '^browser/extensions/api/proxy/proxy_api.cc'],
             ['include', '^browser/extensions/api/proxy/proxy_api_constants.cc'],
-            ['include', '^browser/extensions/api/runtime/runtime_api.cc'],
+            ['include', '^browser/extensions/api/runtime/chrome_runtime_api_delegate.cc'],
             ['include', '^browser/extensions/api/tabs/tabs_constants.cc'],
             ['include', '^browser/extensions/api/web_navigation/frame_navigation_state.cc'],
             ['include', '^browser/extensions/api/web_navigation/web_navigation_api.cc'],
@@ -1027,7 +1030,6 @@
           ],
           'dependencies!': [
             '../device/bluetooth/bluetooth.gyp:device_bluetooth',
-            '../third_party/libusb/libusb.gyp:libusb'
           ],
         }],
         ['use_aura==1', {
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index 54befd9..1b82807 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -25,13 +25,13 @@
         'chrome_resources.gyp:theme_resources',
         'common',
         'common_net',
-        'feedback_proto',
         'in_memory_url_index_cache_proto',
         'safe_browsing_proto',
         'safe_browsing_report_proto',
         '../components/components.gyp:auto_login_parser',
         '../components/components.gyp:dom_distiller_core',
         '../components/components.gyp:dom_distiller_webui',
+        '../components/components.gyp:feedback_proto',
         '../components/components.gyp:onc_component',
         '../components/components.gyp:password_manager_core_browser',
         '../components/components_resources.gyp:components_resources',
@@ -135,12 +135,12 @@
         'browser/ui/app_list/app_context_menu.cc',
         'browser/ui/app_list/app_context_menu.h',
         'browser/ui/app_list/app_context_menu_delegate.h',
-        'browser/ui/app_list/app_list.h',
         'browser/ui/app_list/app_list_controller_delegate.cc',
         'browser/ui/app_list/app_list_controller_delegate.h',
         'browser/ui/app_list/app_list_controller_delegate_impl.cc',
         'browser/ui/app_list/app_list_controller_delegate_impl.h',
-        'browser/ui/app_list/app_list_factory.h',
+        'browser/ui/app_list/app_list_controller_delegate_views.cc',
+        'browser/ui/app_list/app_list_controller_delegate_views.h',
         'browser/ui/app_list/app_list_icon_win.cc',
         'browser/ui/app_list/app_list_icon_win.h',
         'browser/ui/app_list/app_list_positioner.cc',
@@ -152,8 +152,11 @@
         'browser/ui/app_list/app_list_service_impl.h',
         'browser/ui/app_list/app_list_service_mac.h',
         'browser/ui/app_list/app_list_service_mac.mm',
-        'browser/ui/app_list/app_list_shower.cc',
-        'browser/ui/app_list/app_list_shower.h',
+        'browser/ui/app_list/app_list_service_views.cc',
+        'browser/ui/app_list/app_list_service_views.h',
+        'browser/ui/app_list/app_list_shower_delegate.h',
+        'browser/ui/app_list/app_list_shower_views.cc',
+        'browser/ui/app_list/app_list_shower_views.h',
         'browser/ui/app_list/app_list_syncable_service.cc',
         'browser/ui/app_list/app_list_syncable_service.h',
         'browser/ui/app_list/app_list_syncable_service_factory.cc',
@@ -330,6 +333,8 @@
         'browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.h',
         'browser/ui/ash/launcher/multi_profile_browser_status_monitor.cc',
         'browser/ui/ash/launcher/multi_profile_browser_status_monitor.h',
+        'browser/ui/ash/media_delegate_chromeos.cc',
+        'browser/ui/ash/media_delegate_chromeos.h',
         'browser/ui/ash/multi_user/multi_user_context_menu.cc',
         'browser/ui/ash/multi_user/multi_user_context_menu.h',
         'browser/ui/ash/multi_user/multi_user_context_menu_chromeos.cc',
@@ -435,8 +440,6 @@
         'browser/ui/bookmarks/bookmark_drag_drop.h',
         'browser/ui/bookmarks/bookmark_editor.cc',
         'browser/ui/bookmarks/bookmark_editor.h',
-        'browser/ui/bookmarks/bookmark_prompt_controller.cc',
-        'browser/ui/bookmarks/bookmark_prompt_controller.h',
         'browser/ui/bookmarks/bookmark_tab_helper.cc',
         'browser/ui/bookmarks/bookmark_tab_helper.h',
         'browser/ui/bookmarks/bookmark_tab_helper_delegate.cc',
@@ -1002,9 +1005,6 @@
         'browser/ui/cocoa/screen_capture_notification_ui_cocoa.h',
         'browser/ui/cocoa/screen_capture_notification_ui_cocoa.mm',
         'browser/ui/cocoa/simple_message_box_mac.mm',
-        'browser/ui/cocoa/speech_recognition_bubble_cocoa.mm',
-        'browser/ui/cocoa/speech_recognition_window_controller.h',
-        'browser/ui/cocoa/speech_recognition_window_controller.mm',
         'browser/ui/cocoa/sprite_view.h',
         'browser/ui/cocoa/sprite_view.mm',
         'browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h',
@@ -1253,10 +1253,10 @@
         'browser/ui/passwords/manage_passwords_bubble.h',
         'browser/ui/passwords/manage_passwords_bubble_model.cc',
         'browser/ui/passwords/manage_passwords_bubble_model.h',
-        'browser/ui/passwords/manage_passwords_bubble_ui_controller.cc',
-        'browser/ui/passwords/manage_passwords_bubble_ui_controller.h',
         'browser/ui/passwords/manage_passwords_icon.cc',
         'browser/ui/passwords/manage_passwords_icon.h',
+        'browser/ui/passwords/manage_passwords_ui_controller.cc',
+        'browser/ui/passwords/manage_passwords_ui_controller.h',
         'browser/ui/passwords/password_manager_presenter.cc',
         'browser/ui/passwords/password_manager_presenter.h',
         'browser/ui/passwords/password_ui_view.h',
@@ -1447,8 +1447,6 @@
         'browser/ui/views/accessibility/accessibility_event_router_views.h',
         'browser/ui/views/accessibility/invert_bubble_view.cc',
         'browser/ui/views/accessibility/invert_bubble_view.h',
-        'browser/ui/views/app_list/linux/app_list_controller_delegate_linux.cc',
-        'browser/ui/views/app_list/linux/app_list_controller_delegate_linux.h',
         'browser/ui/views/app_list/linux/app_list_linux.cc',
         'browser/ui/views/app_list/linux/app_list_linux.h',
         'browser/ui/views/app_list/linux/app_list_service_linux.cc',
@@ -1529,8 +1527,6 @@
         'browser/ui/views/bookmarks/bookmark_menu_controller_views.h',
         'browser/ui/views/bookmarks/bookmark_menu_delegate.cc',
         'browser/ui/views/bookmarks/bookmark_menu_delegate.h',
-        'browser/ui/views/bookmarks/bookmark_prompt_view.cc',
-        'browser/ui/views/bookmarks/bookmark_prompt_view.h',
         'browser/ui/views/bookmarks/bookmark_sync_promo_view.cc',
         'browser/ui/views/bookmarks/bookmark_sync_promo_view.h',
         'browser/ui/views/certificate_viewer_win.cc',
@@ -1630,8 +1626,6 @@
         'browser/ui/views/first_run_bubble.h',
         'browser/ui/views/first_run_dialog.cc',
         'browser/ui/views/first_run_dialog.h',
-        'browser/ui/views/frame/app_panel_browser_frame_view.cc',
-        'browser/ui/views/frame/app_panel_browser_frame_view.h',
         'browser/ui/views/frame/browser_command_handler_x11.cc',
         'browser/ui/views/frame/browser_command_handler_x11.h',
         'browser/ui/views/frame/browser_frame.cc',
@@ -1828,12 +1822,14 @@
         'browser/ui/views/panels/panel_view.h',
         'browser/ui/views/panels/taskbar_window_thumbnailer_win.cc',
         'browser/ui/views/panels/taskbar_window_thumbnailer_win.h',
+        'browser/ui/views/passwords/manage_password_item_view.cc',
+        'browser/ui/views/passwords/manage_password_item_view.h',
         'browser/ui/views/passwords/manage_passwords_bubble_view.cc',
         'browser/ui/views/passwords/manage_passwords_bubble_view.h',
         'browser/ui/views/passwords/manage_passwords_icon_view.cc',
         'browser/ui/views/passwords/manage_passwords_icon_view.h',
-        'browser/ui/views/passwords/manage_password_item_view.cc',
-        'browser/ui/views/passwords/manage_password_item_view.h',
+        'browser/ui/views/passwords/save_password_refusal_combobox_model.cc',
+        'browser/ui/views/passwords/save_password_refusal_combobox_model.h',
         'browser/ui/views/password_generation_bubble_view.cc',
         'browser/ui/views/password_generation_bubble_view.h',
         'browser/ui/views/pdf_password_dialog.cc',
@@ -1868,7 +1864,6 @@
         'browser/ui/views/signed_certificate_timestamp_info_view.cc',
         'browser/ui/views/signed_certificate_timestamp_info_view.h',
         'browser/ui/views/simple_message_box_views.cc',
-        'browser/ui/views/speech_recognition_bubble_views.cc',
         'browser/ui/views/ssl_client_certificate_selector.cc',
         'browser/ui/views/ssl_client_certificate_selector.h',
         'browser/ui/views/session_crashed_bubble_view.cc',
@@ -2231,8 +2226,6 @@
         'browser/ui/webui/ntp/suggestions_source.h',
         'browser/ui/webui/ntp/suggestions_source_top_sites.cc',
         'browser/ui/webui/ntp/suggestions_source_top_sites.h',
-        'browser/ui/webui/ntp/thumbnail_list_source.cc',
-        'browser/ui/webui/ntp/thumbnail_list_source.h',
         'browser/ui/webui/ntp/thumbnail_source.cc',
         'browser/ui/webui/ntp/thumbnail_source.h',
         'browser/ui/webui/omnibox/omnibox_ui.cc',
@@ -2612,7 +2605,6 @@
             'browser/ui/startup/default_browser_prompt.h',
             'browser/ui/external_protocol_dialog_delegate.cc',
             'browser/ui/external_protocol_dialog_delegate.h',
-            'browser/ui/views/app_list/linux/app_list_service_linux.cc',
             'browser/ui/views/chrome_views_delegate_aura.cc',
             'browser/ui/views/external_protocol_dialog.cc',
             'browser/ui/views/external_protocol_dialog.h',
@@ -2641,6 +2633,7 @@
           ],
           'sources/': [
             ['exclude', '^browser/ui/views/frame/opaque_browser_frame_view*'],
+            ['exclude', '^browser/ui/views/app_list/linux/'],
           ],
         }],
         ['use_cups==1', {
@@ -2805,7 +2798,6 @@
             'browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc',
             'browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h',
             'browser/ui/bookmarks/bookmark_context_menu_controller.cc',
-            'browser/ui/bookmarks/bookmark_prompt_controller.cc',
             'browser/ui/browser.cc',
             'browser/ui/browser_command_controller.cc',
             'browser/ui/browser_finder.cc',
@@ -3037,11 +3029,8 @@
               ],
               'sources/': [
                 ['exclude', '^browser/ui/cocoa/*'],
-                ['exclude', '^browser/ui/views/frame/app_panel_browser_frame_view.cc'],
-                ['exclude', '^browser/ui/views/frame/app_panel_browser_frame_view.h'],
                 ['exclude', '^browser/ui/views/uninstall_view.cc'],
                 ['exclude', '^browser/ui/views/uninstall_view.h'],
-                ['include', '^browser/ui/views/speech_recognition_bubble_views.cc'],
                 ['include', '^browser/ui/window_sizer/window_sizer.cc'],
                 ['include', '^browser/ui/window_sizer/window_sizer.h'],
               ],
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index dbccd6c..eab0246 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -111,7 +111,6 @@
         'common/custom_handlers/protocol_handler.cc',
         'common/custom_handlers/protocol_handler.h',
         'common/descriptors_android.h',
-        'common/encrypted_media_messages_android.h',
         'common/extensions/api/bluetooth/bluetooth_manifest_data.cc',
         'common/extensions/api/bluetooth/bluetooth_manifest_data.h',
         'common/extensions/api/bluetooth/bluetooth_manifest_handler.cc',
@@ -179,10 +178,12 @@
         'common/extensions/manifest_handlers/app_isolation_info.h',
         'common/extensions/manifest_handlers/app_launch_info.cc',
         'common/extensions/manifest_handlers/app_launch_info.h',
+        'common/extensions/manifest_handlers/automation.h',
+        'common/extensions/manifest_handlers/automation.cc',
         'common/extensions/manifest_handlers/content_scripts_handler.cc',
         'common/extensions/manifest_handlers/content_scripts_handler.h',
-        'common/extensions/manifest_handlers/externally_connectable.cc',
-        'common/extensions/manifest_handlers/externally_connectable.h',
+        'common/extensions/manifest_handlers/mime_types_handler.cc',
+        'common/extensions/manifest_handlers/mime_types_handler.h',
         'common/extensions/manifest_handlers/minimum_chrome_version_checker.cc',
         'common/extensions/manifest_handlers/minimum_chrome_version_checker.h',
         'common/extensions/manifest_handlers/nacl_modules_handler.cc',
@@ -195,8 +196,6 @@
         'common/extensions/manifest_handlers/ui_overrides_handler.h',
         'common/extensions/manifest_url_handler.cc',
         'common/extensions/manifest_url_handler.h',
-        'common/extensions/mime_types_handler.cc',
-        'common/extensions/mime_types_handler.h',
         'common/extensions/permissions/chrome_api_permissions.cc',
         'common/extensions/permissions/chrome_api_permissions.h',
         'common/extensions/permissions/chrome_permission_message_provider.cc',
@@ -255,10 +254,6 @@
         'common/media/webrtc_logging_message_data.h',
         'common/metrics/caching_permuted_entropy_provider.cc',
         'common/metrics/caching_permuted_entropy_provider.h',
-        'common/metrics/metrics_log_base.cc',
-        'common/metrics/metrics_log_base.h',
-        'common/metrics/metrics_log_manager.cc',
-        'common/metrics/metrics_log_manager.h',
         'common/metrics/metrics_service_base.cc',
         'common/metrics/metrics_service_base.h',
         'common/metrics/variations/experiment_labels.cc',
@@ -686,14 +681,7 @@
       'type': 'static_library',
       'sources': [
         'common/metrics/proto/chrome_experiments.proto',
-        'common/metrics/proto/chrome_user_metrics_extension.proto',
-        'common/metrics/proto/histogram_event.proto',
-        'common/metrics/proto/omnibox_event.proto',
-        'common/metrics/proto/perf_data.proto',
         'common/metrics/proto/permuted_entropy_cache.proto',
-        'common/metrics/proto/profiler_event.proto',
-        'common/metrics/proto/system_profile.proto',
-        'common/metrics/proto/user_action_event.proto',
       ],
       'variables': {
         'proto_in_dir': 'common/metrics/proto',
diff --git a/chrome/chrome_debugger.gypi b/chrome/chrome_debugger.gypi
new file mode 100644
index 0000000..035a43d
--- /dev/null
+++ b/chrome/chrome_debugger.gypi
@@ -0,0 +1,102 @@
+# 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.
+
+{
+  'targets': [
+    {
+      'target_name': 'debugger',
+      'type': 'static_library',
+      'variables': { 'enable_wexit_time_destructors': 1, },
+      'dependencies': [
+        '../base/base.gyp:base',
+        '../content/content.gyp:content_browser',
+        '../net/net.gyp:http_server',
+        '../net/net.gyp:net',
+        '../skia/skia.gyp:skia',
+        '../third_party/icu/icu.gyp:icui18n',
+        '../third_party/icu/icu.gyp:icuuc',
+        '../third_party/leveldatabase/leveldatabase.gyp:leveldatabase',
+        '../third_party/libusb/libusb.gyp:libusb',
+        'chrome_resources.gyp:chrome_extra_resources',
+        'chrome_resources.gyp:chrome_resources',
+        'chrome_resources.gyp:chrome_strings',
+        'chrome_resources.gyp:theme_resources',
+        'common/extensions/api/api.gyp:chrome_api',
+      ],
+      'include_dirs': [
+        '..',
+      ],
+      'sources': [
+        'browser/devtools/device/adb/adb_client_socket.cc',
+        'browser/devtools/device/adb/adb_client_socket.h',
+        'browser/devtools/device/adb/adb_device_provider.cc',
+        'browser/devtools/device/adb/adb_device_provider.h',
+        'browser/devtools/device/android_device_manager.cc',
+        'browser/devtools/device/android_device_manager.h',
+        'browser/devtools/device/android_web_socket.cc',
+        'browser/devtools/device/devtools_android_bridge.cc',
+        'browser/devtools/device/devtools_android_bridge.h',
+        'browser/devtools/device/port_forwarding_controller.cc',
+        'browser/devtools/device/port_forwarding_controller.h',
+        'browser/devtools/device/self_device_provider.cc',
+        'browser/devtools/device/self_device_provider.h',
+        'browser/devtools/device/usb/android_rsa.cc',
+        'browser/devtools/device/usb/android_rsa.h',
+        'browser/devtools/device/usb/android_usb_device.cc',
+        'browser/devtools/device/usb/android_usb_device.h',
+        'browser/devtools/device/usb/android_usb_socket.cc',
+        'browser/devtools/device/usb/android_usb_socket.h',
+        'browser/devtools/device/usb/usb_device_provider.cc',
+        'browser/devtools/device/usb/usb_device_provider.h',
+        'browser/devtools/browser_list_tabcontents_provider.cc',
+        'browser/devtools/browser_list_tabcontents_provider.h',
+        'browser/devtools/devtools_contents_resizing_strategy.cc',
+        'browser/devtools/devtools_contents_resizing_strategy.h',
+        'browser/devtools/devtools_embedder_message_dispatcher.cc',
+        'browser/devtools/devtools_embedder_message_dispatcher.h',
+        'browser/devtools/devtools_file_helper.cc',
+        'browser/devtools/devtools_file_helper.h',
+        'browser/devtools/devtools_file_system_indexer.cc',
+        'browser/devtools/devtools_file_system_indexer.h',
+        'browser/devtools/devtools_protocol.cc',
+        'browser/devtools/devtools_protocol.h',
+        'browser/devtools/devtools_target_impl.cc',
+        'browser/devtools/devtools_target_impl.h',
+        'browser/devtools/devtools_targets_ui.cc',
+        'browser/devtools/devtools_targets_ui.h',
+        'browser/devtools/devtools_toggle_action.cc',
+        'browser/devtools/devtools_toggle_action.h',
+        'browser/devtools/devtools_ui_bindings.cc',
+        'browser/devtools/devtools_ui_bindings.h',
+        'browser/devtools/devtools_window.cc',
+        'browser/devtools/devtools_window.h',
+        'browser/devtools/remote_debugging_server.cc',
+        'browser/devtools/remote_debugging_server.h',
+      ],
+      'conditions': [
+        ['OS=="android"', {
+          'dependencies!': [
+            '../third_party/libusb/libusb.gyp:libusb',
+          ],
+          'sources!': [
+            'browser/devtools/device/usb/android_rsa.cc',
+            'browser/devtools/browser_list_tabcontents_provider.cc',
+            'browser/devtools/devtools_file_system_indexer.cc',
+            'browser/devtools/devtools_target_impl.cc',
+            'browser/devtools/devtools_window.cc',
+            'browser/devtools/devtools_window_base.cc',
+            'browser/devtools/remote_debugging_server.cc',
+          ],
+        }],
+        ['debug_devtools==1', {
+          'defines': [
+            'DEBUG_DEVTOOLS=1',
+           ],
+        }],
+      ],
+      # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+  ],
+}
diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi
index 7e1e83f..b7a23b1 100644
--- a/chrome/chrome_exe.gypi
+++ b/chrome/chrome_exe.gypi
@@ -141,8 +141,7 @@
             },
           ],
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
                 'dependencies': [
                   '<(allocator_target)',
                 ],
diff --git a/chrome/chrome_nibs.gyp b/chrome/chrome_nibs.gyp
index 84b0bf0..b2a661c 100644
--- a/chrome/chrome_nibs.gyp
+++ b/chrome/chrome_nibs.gyp
@@ -191,8 +191,6 @@
         'browser/ui/cocoa/one_click_signin_view_controller.mm',
         'browser/ui/cocoa/screen_capture_notification_ui_cocoa.h',
         'browser/ui/cocoa/screen_capture_notification_ui_cocoa.mm',
-        'browser/ui/cocoa/speech_recognition_window_controller.h',
-        'browser/ui/cocoa/speech_recognition_window_controller.mm',
         'browser/ui/cocoa/status_bubble_mac.h',
         'browser/ui/cocoa/status_bubble_mac.mm',
         'browser/ui/cocoa/styled_text_field.h',
diff --git a/chrome/chrome_nibs.gypi b/chrome/chrome_nibs.gypi
index 2cc0dea..3ad7f21 100644
--- a/chrome/chrome_nibs.gypi
+++ b/chrome/chrome_nibs.gypi
@@ -45,7 +45,6 @@
       'app/nibs/OneClickSigninBubble.xib',
       'app/nibs/OneClickSigninDialog.xib',
       'app/nibs/SaveAccessoryView.xib',
-      'app/nibs/SpeechRecognitionBubble.xib',
       'app/nibs/TaskManager.xib',
       'app/nibs/Toolbar.xib',
       'app/nibs/WrenchMenu.xib',
diff --git a/chrome/chrome_plugin.gypi b/chrome/chrome_plugin.gypi
new file mode 100644
index 0000000..3300540
--- /dev/null
+++ b/chrome/chrome_plugin.gypi
@@ -0,0 +1,26 @@
+# 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.
+
+{
+  'targets': [
+    {
+      'target_name': 'plugin',
+      'type': 'static_library',
+      'variables': { 'enable_wexit_time_destructors': 1, },
+      'dependencies': [
+        '../base/base.gyp:base',
+        '../content/content.gyp:content_plugin',
+        'chrome_resources.gyp:chrome_strings',
+      ],
+      'include_dirs': [
+        '..',
+        '<(grit_out_dir)',
+      ],
+      'sources': [
+        'plugin/chrome_content_plugin_client.cc',
+        'plugin/chrome_content_plugin_client.h',
+      ],
+    },
+  ],
+}
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index a4e5aab..9d6ef22 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -15,6 +15,7 @@
         'chrome_resources.gyp:chrome_strings',
         '../third_party/re2/re2.gyp:re2',
         '../components/components.gyp:autofill_content_renderer',
+        '../components/components.gyp:cdm_renderer',
         '../components/components.gyp:startup_metric_utils',
         '../components/components.gyp:plugins_renderer',
         '../components/components.gyp:translate_core_common',
@@ -23,6 +24,7 @@
         '../content/content.gyp:content_renderer',
         '../extensions/extensions.gyp:extensions_renderer',
         '../extensions/extensions_resources.gyp:extensions_resources',
+        '../media/cast/cast.gyp:cast_logging_proto',
         '../media/cast/cast.gyp:cast_sender',
         '../media/cast/cast.gyp:cast_transport',
         '../net/net.gyp:net',
@@ -46,28 +48,24 @@
       'sources': [
         'renderer/benchmarking_extension.cc',
         'renderer/benchmarking_extension.h',
-        'renderer/extensions/api_activity_logger.cc',
-        'renderer/extensions/api_activity_logger.h',
         'renderer/extensions/app_bindings.cc',
         'renderer/extensions/app_bindings.h',
-        'renderer/extensions/app_runtime_custom_bindings.cc',
-        'renderer/extensions/app_runtime_custom_bindings.h',
         'renderer/extensions/app_window_custom_bindings.cc',
         'renderer/extensions/app_window_custom_bindings.h',
         'renderer/extensions/cast_streaming_native_handler.cc',
         'renderer/extensions/cast_streaming_native_handler.h',
+        'renderer/extensions/chrome_extension_helper.cc',
+        'renderer/extensions/chrome_extension_helper.h',
+        'renderer/extensions/chrome_extensions_dispatcher_delegate.cc',
+        'renderer/extensions/chrome_extensions_dispatcher_delegate.h',
         'renderer/extensions/chrome_extensions_renderer_client.cc',
         'renderer/extensions/chrome_extensions_renderer_client.h',
         'renderer/extensions/chrome_v8_context.cc',
         'renderer/extensions/chrome_v8_context.h',
         'renderer/extensions/chrome_v8_extension_handler.cc',
         'renderer/extensions/chrome_v8_extension_handler.h',
-        'renderer/extensions/dispatcher.cc',
-        'renderer/extensions/dispatcher.h',
         'renderer/extensions/extension_frame_helper.cc',
         'renderer/extensions/extension_frame_helper.h',
-        'renderer/extensions/extension_helper.cc',
-        'renderer/extensions/extension_helper.h',
         'renderer/extensions/extension_localization_peer.cc',
         'renderer/extensions/extension_localization_peer.h',
         'renderer/extensions/file_browser_handler_custom_bindings.cc',
@@ -76,8 +74,6 @@
         'renderer/extensions/file_browser_private_custom_bindings.h',
         'renderer/extensions/media_galleries_custom_bindings.cc',
         'renderer/extensions/media_galleries_custom_bindings.h',
-        'renderer/extensions/messaging_bindings.cc',
-        'renderer/extensions/messaging_bindings.h',
         'renderer/extensions/page_actions_custom_bindings.cc',
         'renderer/extensions/page_actions_custom_bindings.h',
         'renderer/extensions/page_capture_custom_bindings.cc',
@@ -90,18 +86,12 @@
         'renderer/extensions/renderer_permissions_policy_delegate.h',
         'renderer/extensions/resource_request_policy.cc',
         'renderer/extensions/resource_request_policy.h',
-        'renderer/extensions/runtime_custom_bindings.cc',
-        'renderer/extensions/runtime_custom_bindings.h',
         'renderer/extensions/sync_file_system_custom_bindings.cc',
         'renderer/extensions/sync_file_system_custom_bindings.h',
         'renderer/extensions/tab_finder.cc',
         'renderer/extensions/tab_finder.h',
         'renderer/extensions/tabs_custom_bindings.cc',
         'renderer/extensions/tabs_custom_bindings.h',
-        'renderer/extensions/user_script_scheduler.cc',
-        'renderer/extensions/user_script_scheduler.h',
-        'renderer/extensions/user_script_slave.cc',
-        'renderer/extensions/user_script_slave.h',
         'renderer/extensions/webstore_bindings.cc',
         'renderer/extensions/webstore_bindings.h',
         'renderer/isolated_world_ids.h',
@@ -145,8 +135,6 @@
         'renderer/playback_extension.h',
         'renderer/principals_extension_bindings.cc',
         'renderer/principals_extension_bindings.h',
-        'renderer/resource_bundle_source_map.cc',
-        'renderer/resource_bundle_source_map.h',
         'renderer/resources/extensions/app_custom_bindings.js',
         'renderer/resources/extensions/app_window_custom_bindings.js',
         'renderer/resources/extensions/automation_custom_bindings.js',
@@ -189,6 +177,7 @@
         'renderer/resources/extensions/test_custom_bindings.js',
         'renderer/resources/extensions/tts_custom_bindings.js',
         'renderer/resources/extensions/tts_engine_custom_bindings.js',
+        'renderer/resources/extensions/uncaught_exception_handler.js',
         'renderer/resources/extensions/unload_event.js',
         'renderer/resources/extensions/utils.js',
         'renderer/resources/extensions/web_request_custom_bindings.js',
@@ -297,8 +286,6 @@
         'renderer/spellchecker/spellcheck_worditerator.cc',
         'renderer/spellchecker/spellcheck_worditerator.h',
         'renderer/spellchecker/spelling_engine.h',
-        'renderer/static_v8_external_string_resource.cc',
-        'renderer/static_v8_external_string_resource.h',
         'renderer/tts_dispatcher.cc',
         'renderer/tts_dispatcher.h',
         'renderer/translate/translate_helper.cc',
@@ -372,14 +359,14 @@
         }],
         ['OS=="android"', {
           'sources!': [
-            'renderer/prerender/prerender_media_load_deferrer.cc',
-            'renderer/prerender/prerender_media_load_deferrer.h',
             'renderer/extensions/app_window_custom_bindings.cc',
             'renderer/extensions/chrome_v8_extension_handler.cc',
             'renderer/extensions/file_browser_handler_custom_bindings.cc',
             'renderer/extensions/page_actions_custom_bindings.cc',
             'renderer/extensions/tabs_custom_bindings.cc',
             'renderer/extensions/tts_custom_bindings.cc',
+            'renderer/prerender/prerender_media_load_deferrer.cc',
+            'renderer/prerender/prerender_media_load_deferrer.h',
           ],
         }],
         ['OS=="win" and target_arch=="ia32"', {
diff --git a/chrome/chrome_repack_chrome_100_percent.gypi b/chrome/chrome_repack_chrome_100_percent.gypi
index b644df6..e7ed2cd 100644
--- a/chrome/chrome_repack_chrome_100_percent.gypi
+++ b/chrome/chrome_repack_chrome_100_percent.gypi
@@ -19,7 +19,7 @@
       }],
       ['use_ash==1', {
         'pak_inputs': [
-          '<(SHARED_INTERMEDIATE_DIR)/ash/ash_resources/ash_resources_100_percent.pak',
+          '<(SHARED_INTERMEDIATE_DIR)/ash/resources/ash_resources_100_percent.pak',
         ],
       }],
     ],
diff --git a/chrome/chrome_repack_chrome_200_percent.gypi b/chrome/chrome_repack_chrome_200_percent.gypi
index ccd1de2..dcb354f 100644
--- a/chrome/chrome_repack_chrome_200_percent.gypi
+++ b/chrome/chrome_repack_chrome_200_percent.gypi
@@ -19,7 +19,7 @@
       }],
       ['use_ash==1', {
         'pak_inputs': [
-          '<(SHARED_INTERMEDIATE_DIR)/ash/ash_resources/ash_resources_200_percent.pak',
+          '<(SHARED_INTERMEDIATE_DIR)/ash/resources/ash_resources_200_percent.pak',
         ],
       }],
     ],
diff --git a/chrome/chrome_resources.gyp b/chrome/chrome_resources.gyp
index ea06883..c41896f 100644
--- a/chrome/chrome_resources.gyp
+++ b/chrome/chrome_resources.gyp
@@ -114,6 +114,14 @@
           ],
         }],
         ['chromeos==1 and disable_nacl==0 and disable_nacl_untrusted==0', {
+          'copies' : [
+            {
+              'destination': '<(PRODUCT_DIR)/resources/chromeos/braille_ime',
+              'files': [
+                'browser/resources/chromeos/braille_ime/manifest.json',
+              ],
+            },
+          ],
           'dependencies': [
             '../chrome/third_party/chromevox/chromevox.gyp:chromevox_resources',
             'chromevox_strings',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 3afc5f9..f3ffa47 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -46,6 +46,7 @@
       'sources': [
         '../apps/app_shim/app_shim_quit_interactive_uitest_mac.mm',
         '../apps/app_window_interactive_uitest.cc',
+        '../ui/views/controls/webview/webview_interactive_uitest.cc',
         '../ui/views/corewm/desktop_capture_controller_unittest.cc',
         '../ui/views/widget/widget_interactive_uitest.cc',
         'browser/apps/app_browsertest_util.cc',
@@ -128,6 +129,10 @@
         'browser/ui/views/message_center/web_notification_tray_browsertest.cc',
         'browser/ui/views/omnibox/omnibox_view_views_browsertest.cc',
         'browser/ui/views/panels/panel_view_browsertest.cc',
+        'browser/ui/views/passwords/manage_passwords_view_test.cc',
+        'browser/ui/views/passwords/manage_passwords_view_test.h',
+        'browser/ui/views/passwords/manage_passwords_bubble_view_browsertest.cc',
+        'browser/ui/views/passwords/manage_passwords_icon_view_browsertest.cc',
         'browser/ui/views/ssl_client_certificate_selector_browsertest.cc',
         'browser/ui/views/status_icons/status_tray_state_changer_interactive_uitest_win.cc',
         'browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc',
@@ -185,11 +190,6 @@
         }],
         ['OS=="linux" and use_aura==1 and chromeos==0', {
           'sources!': [
-            # TODO(port): These tests fail because they don't have a Screen,
-            # but expect one.
-            # TODO(port): I have no idea about the crashes in here; there's
-            # nothing obviously wrong. It doesn't run on gtk today, either.
-            'browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc',
             # TODO(port): Everything here times out. Attempts have been made to
             # fix the individual failures, but each time I disable a test from
             # these suites, it seems like one or another starts timing out too.
@@ -232,6 +232,7 @@
         }],
         ['toolkit_views==1', {
           'dependencies': [
+            '../ui/views/controls/webview/webview_tests.gyp:webview_test_support',
             '../ui/views/views.gyp:views',
             '../ui/views/views.gyp:views_test_support',
           ],
@@ -258,6 +259,7 @@
         }],
         ['chromeos==1', {
           'dependencies': [
+            '../ash/ash.gyp:ash_resources',
             '../chromeos/chromeos.gyp:chromeos',
           ],
           'conditions': [
@@ -781,6 +783,7 @@
         '../extensions/common/api/api.gyp:extensions_api',
         '../google_apis/google_apis.gyp:google_apis_test_support',
         '../media/cast/cast.gyp:cast_test_utility',
+        '../media/media.gyp:media',
         '../net/net.gyp:net',
         '../net/net.gyp:net_test_support',
         '../skia/skia.gyp:skia',
@@ -802,6 +805,7 @@
         '../v8/tools/gyp/v8.gyp:v8',
         # Runtime dependencies
         '../ppapi/ppapi_internal.gyp:ppapi_tests',
+        '../remoting/remoting.gyp:remoting_browser_test_resources',
         '../third_party/mesa/mesa.gyp:osmesa',
         '../third_party/widevine/cdm/widevine_cdm.gyp:widevine_test_license_server',
       ],
@@ -819,6 +823,8 @@
         '../apps/app_shim/test/app_shim_host_manager_test_api_mac.cc',
         '../apps/app_shim/test/app_shim_host_manager_test_api_mac.h',
         '../apps/load_and_launch_browsertest.cc',
+        '../extensions/browser/api/usb/usb_apitest.cc',
+        '../extensions/browser/api/usb/usb_manual_apitest.cc',
         # TODO(blundell): Bring up a components_browsertests target and move
         # this test to be in that target. crbug.com/283846
         '../components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc',
@@ -826,6 +832,8 @@
         '../components/autofill/content/renderer/test_password_autofill_agent.cc',
         '../components/autofill/content/renderer/test_password_generation_agent.h',
         '../components/autofill/content/renderer/test_password_generation_agent.cc',
+        # TODO(rockot): Remove this once extensions_browsertests exists.
+        '../extensions/browser/api/runtime/runtime_apitest.cc',
         'app/chrome_command_ids.h',
         'app/chrome_dll.rc',
         'app/chrome_dll_resource.h',
@@ -869,6 +877,7 @@
         'browser/chromeos/accessibility/magnification_manager_browsertest.cc',
         'browser/chromeos/accessibility/speech_monitor.cc',
         'browser/chromeos/accessibility/speech_monitor.h',
+        'browser/chromeos/accessibility/touch_exploration_controller_browsertest.cc',
         'browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc',
         'browser/chromeos/app_mode/kiosk_app_update_service_browsertest.cc',
         'browser/chromeos/attestation/attestation_policy_browsertest.cc',
@@ -885,7 +894,9 @@
         'browser/chromeos/extensions/file_system_provider/file_system_provider_apitest.cc',
         'browser/chromeos/extensions/info_private_apitest.cc',
         'browser/chromeos/extensions/input_method_apitest_chromeos.cc',
+        'browser/chromeos/extensions/input_view_browsertest.cc',
         'browser/chromeos/extensions/virtual_keyboard_browsertest.cc',
+        'browser/chromeos/extensions/virtual_keyboard_browsertest.h',
         'browser/chromeos/extensions/wallpaper_apitest.cc',
         'browser/chromeos/extensions/wallpaper_private_apitest.cc',
         'browser/chromeos/file_manager/drive_test_util.cc',
@@ -1002,10 +1013,12 @@
         'browser/extensions/api/bluetooth/bluetooth_apitest.cc',
         'browser/extensions/api/bluetooth/bluetooth_private_apitest.cc',
         'browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc',
+        'browser/extensions/api/bluetooth_socket/bluetooth_socket_apitest.cc',
         'browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc',
         'browser/extensions/api/braille_display_private/braille_display_private_apitest.cc',
         'browser/extensions/api/braille_display_private/mock_braille_controller.cc',
         'browser/extensions/api/braille_display_private/mock_braille_controller.h',
+        'browser/extensions/api/browser/browser_apitest.cc',
         'browser/extensions/api/bookmarks/bookmark_apitest.cc',
         'browser/extensions/api/browsing_data/browsing_data_test.cc',
         'browser/extensions/api/cast_channel/cast_channel_apitest.cc',
@@ -1065,7 +1078,6 @@
         'browser/extensions/api/push_messaging/push_messaging_canary_test.cc',
         'browser/extensions/api/push_messaging/sync_setup_helper.cc',
         'browser/extensions/api/reading_list_private/reading_list_private_apitest.cc',
-        'browser/extensions/api/runtime/runtime_apitest.cc',
         'browser/extensions/api/serial/serial_apitest.cc',
         'browser/extensions/api/sessions/sessions_apitest.cc',
         'browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc',
@@ -1091,8 +1103,6 @@
         'browser/extensions/api/terminal/terminal_private_apitest.cc',
         'browser/extensions/api/test/apitest_apitest.cc',
         'browser/extensions/api/top_sites/top_sites_apitest.cc',
-        'browser/extensions/api/usb/usb_apitest.cc',
-        'browser/extensions/api/usb/usb_manual_apitest.cc',
         'browser/extensions/api/web_navigation/web_navigation_apitest.cc',
         'browser/extensions/api/web_request/web_request_apitest.cc',
         'browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc',
@@ -1108,6 +1118,7 @@
         'browser/extensions/browsertest_util_browsertest.cc',
         'browser/extensions/chrome_app_api_browsertest.cc',
         'browser/extensions/chrome_ui_overrides_browsertest.cc',
+        'browser/extensions/content_verifier_browsertest.cc',
         'browser/extensions/content_script_apitest.cc',
         'browser/extensions/content_security_policy_apitest.cc',
         'browser/extensions/convert_web_app_browsertest.cc',
@@ -1259,6 +1270,7 @@
         'browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc',
         'browser/printing/print_preview_dialog_controller_browsertest.cc',
         'browser/process_singleton_browsertest.cc',
+        'browser/profiles/host_zoom_map_browsertest.cc',
         'browser/profiles/profile_browsertest.cc',
         'browser/profiles/profile_list_desktop_browsertest.cc',
         'browser/profiles/profile_manager_browsertest.cc',
@@ -1288,7 +1300,6 @@
         'browser/sessions/tab_restore_browsertest.cc',
         'browser/signin/signin_browsertest.cc',
         'browser/speech/extension_api/tts_extension_apitest.cc',
-        'browser/speech/speech_recognition_bubble_browsertest.cc',
         'browser/spellchecker/spellcheck_service_browsertest.cc',
         'browser/ssl/ssl_browser_tests.cc',
         'browser/ssl/ssl_client_certificate_selector_test.cc',
@@ -1305,6 +1316,7 @@
         'browser/translate/translate_browsertest.cc',
         'browser/translate/translate_manager_browsertest.cc',
         'browser/ui/app_list/app_list_controller_browsertest.cc',
+        'browser/ui/app_list/app_list_service_views_browsertest.cc',
         'browser/ui/app_list/search/people/people_provider_browsertest.cc',
         'browser/ui/app_list/search/webstore/webstore_provider_browsertest.cc',
         'browser/ui/ash/accelerator_commands_browsertest.cc',
@@ -1383,6 +1395,7 @@
         'browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc',
         'browser/ui/views/profiles/avatar_menu_button_browsertest.cc',
         'browser/ui/views/profiles/new_avatar_menu_button_browsertest.cc',
+        'browser/ui/views/profiles/profile_chooser_view_browsertest.cc',
         'browser/ui/views/select_file_dialog_extension_browsertest.cc',
         'browser/ui/views/toolbar/browser_actions_container_browsertest.cc',
         'browser/ui/views/toolbar/toolbar_view_browsertest.cc',
@@ -1869,14 +1882,18 @@
         }],
         ['os_posix == 1 and OS != "mac" and OS != "android"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
             }],
           ],
         }],
+        ['OS=="win" or OS == "mac"', {
+          'dependencies': [
+            '../components/components.gyp:wifi_test_support',
+          ],
+        }],
         ['chromeos == 1 or OS=="win" or OS == "mac"', {
           'sources': [
             'browser/extensions/api/networking_private/networking_private_apitest.cc',
@@ -2137,8 +2154,7 @@
         }],
         ['os_posix == 1 and OS != "mac" and OS != "android"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
@@ -2192,6 +2208,8 @@
         'browser/sync/test/integration/extension_settings_helper.h',
         'browser/sync/test/integration/extensions_helper.cc',
         'browser/sync/test/integration/extensions_helper.h',
+        'browser/sync/test/integration/fake_server_invalidation_service.cc',
+        'browser/sync/test/integration/fake_server_invalidation_service.h',
         'browser/sync/test/integration/multi_client_status_change_checker.cc',
         'browser/sync/test/integration/multi_client_status_change_checker.h',
         'browser/sync/test/integration/passwords_helper.cc',
@@ -2646,8 +2664,7 @@
             }],
             ['os_posix == 1 and OS != "mac" and OS != "android"', {
               'conditions': [
-                # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-                ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+                ['use_allocator!="none"', {
                   'dependencies': [
                     '../base/allocator/allocator.gyp:allocator',
                   ],
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index e15e05a..2193656 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -21,7 +21,7 @@
         '../components/components.gyp:password_manager_core_browser_test_support',
         '../components/components.gyp:signin_core_browser_test_support',
         '../components/components.gyp:sync_driver_test_support',
-        '../components/components.gyp:sync_driver_test_support',
+        '../components/components.gyp:bookmarks_core_test_support',
         '../content/content.gyp:content_app_both',
         '../content/content_shell_and_tests.gyp:test_support_content',
         '../net/net.gyp:net',
@@ -48,10 +48,6 @@
         'browser/android/bookmarks/partner_bookmarks_shim_unittest.cc',
         'browser/android/mock_google_location_settings_helper.cc',
         'browser/android/mock_google_location_settings_helper.h',
-        'browser/bookmarks/bookmark_test_helpers.cc',
-        'browser/bookmarks/bookmark_test_helpers.h',
-        'browser/bookmarks/test_bookmark_client.cc',
-        'browser/bookmarks/test_bookmark_client.h',
         'browser/browsing_data/mock_browsing_data_appcache_helper.cc',
         'browser/browsing_data/mock_browsing_data_appcache_helper.h',
         'browser/browsing_data/mock_browsing_data_cookie_helper.cc',
@@ -201,6 +197,8 @@
         'browser/ui/fullscreen/fullscreen_controller_state_tests.h',
         'browser/ui/fullscreen/fullscreen_controller_test.cc',
         'browser/ui/fullscreen/fullscreen_controller_test.h',
+        'browser/ui/passwords/manage_passwords_ui_controller_mock.cc',
+        'browser/ui/passwords/manage_passwords_ui_controller_mock.h',
         'browser/ui/test/test_confirm_bubble_model.cc',
         'browser/ui/test/test_confirm_bubble_model.h',
         'browser/ui/views/find_bar_host_unittest_util_views.cc',
@@ -557,6 +555,7 @@
         '../extensions/browser/value_store/value_store_frontend_unittest.cc',
         '../extensions/browser/value_store/value_store_unittest.cc',
         '../extensions/browser/value_store/value_store_unittest.h',
+        '../extensions/browser/verified_contents_unittest.cc',
         '../extensions/common/api/sockets/sockets_manifest_permission_unittest.cc',
         '../extensions/common/csp_validator_unittest.cc',
         '../extensions/common/event_filter_unittest.cc',
@@ -569,6 +568,7 @@
         '../extensions/common/file_util_unittest.cc',
         '../extensions/common/id_util_unittest.cc',
         '../extensions/common/manifest_handler_unittest.cc',
+        '../extensions/common/manifest_handlers/externally_connectable_unittest.cc',
         '../extensions/common/manifest_handlers/shared_module_manifest_unittest.cc',
         '../extensions/common/message_bundle_unittest.cc',
         '../extensions/common/one_shot_event_unittest.cc',
@@ -598,14 +598,13 @@
         'browser/autocomplete/search_provider_unittest.cc',
         'browser/autocomplete/shortcuts_backend_unittest.cc',
         'browser/autocomplete/shortcuts_provider_unittest.cc',
+	'browser/autocomplete/zero_suggest_provider_unittest.cc',
         'browser/autofill/autofill_cc_infobar_delegate_unittest.cc',
         'browser/background/background_application_list_model_unittest.cc',
         'browser/background/background_contents_service_unittest.cc',
         'browser/background/background_mode_manager_unittest.cc',
-        'browser/bookmarks/bookmark_codec_unittest.cc',
         'browser/bookmarks/bookmark_expanded_state_tracker_unittest.cc',
         'browser/bookmarks/bookmark_html_writer_unittest.cc',
-        'browser/bookmarks/bookmark_index_unittest.cc',
         'browser/bookmarks/bookmark_model_unittest.cc',
         'browser/bookmarks/bookmark_node_data_unittest.cc',
         'browser/bookmarks/bookmark_utils_unittest.cc',
@@ -714,6 +713,8 @@
         'browser/chromeos/file_system_provider/fake_provided_file_system.h',
         'browser/chromeos/file_system_provider/fileapi/provider_async_file_util_unittest.cc',
         'browser/chromeos/file_system_provider/mount_path_util_unittest.cc',
+        'browser/chromeos/file_system_provider/operations/get_metadata_unittest.cc',
+        'browser/chromeos/file_system_provider/operations/read_directory_unittest.cc',
         'browser/chromeos/file_system_provider/provided_file_system_unittest.cc',
         'browser/chromeos/file_system_provider/request_manager_unittest.cc',
         'browser/chromeos/file_system_provider/service_unittest.cc',
@@ -762,6 +763,7 @@
         'browser/chromeos/policy/enterprise_install_attributes_unittest.cc',
         'browser/chromeos/policy/network_configuration_updater_unittest.cc',
         'browser/chromeos/policy/recommendation_restorer_unittest.cc',
+        'browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc',
         'browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc',
         'browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc',
         'browser/chromeos/power/power_data_collector_unittest.cc',
@@ -836,10 +838,10 @@
         'browser/extensions/activity_log/activity_log_unittest.cc',
         'browser/extensions/activity_log/activity_log_policy_unittest.cc',
         'browser/extensions/activity_log/ad_injection_unittest.cc',
-        'browser/extensions/activity_log/ad_network_database_unittest.cc',
         'browser/extensions/activity_log/counting_policy_unittest.cc',
         'browser/extensions/activity_log/database_string_table_unittest.cc',
         'browser/extensions/activity_log/fullstream_ui_policy_unittest.cc',
+        'browser/extensions/activity_log/hashed_ad_network_database_unittest.cc',
         'browser/extensions/activity_log/uma_policy_unittest.cc',
         'browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc',
         'browser/extensions/api/alarms/alarms_api_unittest.cc',
@@ -973,7 +975,6 @@
         'browser/extensions/webstore_installer_unittest.cc',
         'browser/external_protocol/external_protocol_handler_unittest.cc',
         'browser/favicon/favicon_handler_unittest.cc',
-        'browser/feedback/feedback_uploader_unittest.cc',
         'browser/file_select_helper_unittest.cc',
         'browser/first_run/first_run_unittest.cc',
         'browser/geolocation/chrome_geolocation_permission_context_unittest.cc',
@@ -1015,6 +1016,7 @@
         'browser/history/visit_database_unittest.cc',
         'browser/history/visit_filter_unittest.cc',
         'browser/history/visit_tracker_unittest.cc',
+        'browser/image_holder_unittest.cc',
         'browser/importer/firefox_profile_lock_unittest.cc',
         'browser/importer/profile_writer_unittest.cc',
         'browser/internal_auth_unittest.cc',
@@ -1080,6 +1082,7 @@
         'browser/metrics/metrics_log_serializer_unittest.cc',
         'browser/metrics/metrics_reporting_scheduler_unittest.cc',
         'browser/metrics/metrics_service_unittest.cc',
+        'browser/metrics/metrics_state_manager_unittest.cc',
         'browser/metrics/thread_watcher_unittest.cc',
         'browser/metrics/thread_watcher_android_unittest.cc',
         'browser/metrics/time_ticks_experiment_unittest.cc',
@@ -1119,7 +1122,6 @@
         'browser/notifications/message_center_settings_controller_unittest.cc',
         'browser/notifications/sync_notifier/chrome_notifier_delegate_unittest.cc',
         'browser/notifications/sync_notifier/chrome_notifier_service_unittest.cc',
-        'browser/notifications/sync_notifier/image_holder_unittest.cc',
         'browser/notifications/sync_notifier/synced_notification_unittest.cc',
         'browser/notifications/sync_notifier/synced_notification_app_info_unittest.cc',
         'browser/notifications/sync_notifier/synced_notification_app_info_service_unittest.cc',
@@ -1199,6 +1201,8 @@
         'browser/renderer_host/plugin_info_message_filter_unittest.cc',
         'browser/renderer_host/web_cache_manager_unittest.cc',
         'browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm',
+        'browser/resources/chromeos/braille_ime/braille_ime.js',
+        'browser/resources/chromeos/braille_ime/braille_ime_unittest.gtestjs',
         'browser/resources/google_now/background.js',
         'browser/resources/google_now/background_test_util.js',
         'browser/resources/google_now/background_unittest.gtestjs',
@@ -1246,6 +1250,7 @@
         'browser/search/search_android_unittest.cc',
         'browser/search/suggestions/suggestions_service_unittest.cc',
         'browser/search_engines/default_search_manager_unittest.cc',
+        'browser/search_engines/default_search_pref_migration_unittest.cc',
         'browser/search_engines/default_search_policy_handler_unittest.cc',
         'browser/search_engines/search_host_to_urls_map_unittest.cc',
         'browser/search_engines/search_provider_install_data_unittest.cc',
@@ -1282,7 +1287,6 @@
         'browser/signin/signin_promo_unittest.cc',
         'browser/signin/signin_tracker_unittest.cc',
         'browser/speech/extension_api/extension_manifests_tts_unittest.cc',
-        'browser/speech/speech_recognition_bubble_controller_unittest.cc',
         'browser/speech/tts_controller_unittest.cc',
         'browser/spellchecker/feedback_sender_unittest.cc',
         'browser/spellchecker/feedback_unittest.cc',
@@ -1422,6 +1426,17 @@
         'browser/translate/translate_manager_render_view_host_unittest.cc',
         'browser/translate/translate_service_unittest.cc',
         'browser/ui/android/tab_model/tab_model_unittest.cc',
+        'browser/ui/app_list/app_list_positioner_unittest.cc',
+        'browser/ui/app_list/app_list_service_mac_unittest.mm',
+        'browser/ui/app_list/app_list_service_unittest.cc',
+        'browser/ui/app_list/extension_app_model_builder_unittest.cc',
+        'browser/ui/app_list/app_list_shower_views_unittest.cc',
+        'browser/ui/app_list/profile_loader_unittest.cc',
+        'browser/ui/app_list/test/fake_profile.cc',
+        'browser/ui/app_list/test/fake_profile.h',
+        'browser/ui/app_list/test/fake_profile_store.cc',
+        'browser/ui/app_list/test/fake_profile_store.h',
+        'browser/ui/app_list/test/fast_show_pickler_unittest.cc',
         'browser/ui/ash/ime_controller_chromeos_unittest.cc',
         'browser/ui/ash/accessibility/ax_tree_source_views_unittest.cc',
         'browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc',
@@ -1459,7 +1474,6 @@
         'browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc',
         'browser/ui/bookmarks/bookmark_bubble_sign_in_delegate_unittest.cc',
         'browser/ui/bookmarks/bookmark_editor_unittest.cc',
-        'browser/ui/bookmarks/bookmark_prompt_controller_unittest.cc',
         'browser/ui/bookmarks/bookmark_ui_utils_unittest.cc',
         'browser/ui/bookmarks/bookmark_unittest.cc',
         'browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc',
@@ -1668,8 +1682,7 @@
         'browser/ui/panels/panel_mouse_watcher_unittest.cc',
         'browser/ui/passwords/manage_passwords_icon_mock.cc',
         'browser/ui/passwords/manage_passwords_bubble_model_unittest.cc',
-        'browser/ui/passwords/manage_passwords_bubble_ui_controller_mock.cc',
-        'browser/ui/passwords/manage_passwords_bubble_ui_controller_unittest.cc',
+        'browser/ui/passwords/manage_passwords_ui_controller_unittest.cc',
         'browser/ui/passwords/password_manager_presenter_unittest.cc',
         'browser/ui/search_engines/keyword_editor_controller_unittest.cc',
         'browser/ui/search/instant_page_unittest.cc',
@@ -1709,6 +1722,8 @@
         'browser/ui/toolbar/wrench_menu_model_unittest.cc',
         'browser/ui/views/accelerator_table_unittest.cc',
         'browser/ui/views/accessibility/accessibility_event_router_views_unittest.cc',
+        'browser/ui/views/app_list/linux/app_list_linux_unittest.cc',
+        'browser/ui/views/app_list/win/app_list_win_unittest.cc',
         'browser/ui/views/apps/app_info_dialog/app_info_permissions_tab_unittest.cc',
         'browser/ui/views/apps/shaped_app_window_targeter_unittest.cc',
         'browser/ui/views/autofill/autofill_dialog_views_unittest.cc',
@@ -1798,9 +1813,9 @@
         'common/extensions/extension_icon_set_unittest.cc',
         'common/extensions/extension_unittest.cc',
         'common/extensions/feature_switch_unittest.cc',
+        'common/extensions/manifest_handlers/automation_unittest.cc',
         'common/extensions/manifest_handlers/content_scripts_manifest_unittest.cc',
         'common/extensions/manifest_handlers/exclude_matches_manifest_unittest.cc',
-        'common/extensions/manifest_handlers/externally_connectable_unittest.cc',
         'common/extensions/manifest_handlers/settings_overrides_handler_unittest.cc',
         'common/extensions/manifest_handlers/ui_overrides_handler_unittest.cc',
         'common/extensions/manifest_tests/extension_manifest_test.cc',
@@ -1853,8 +1868,6 @@
         'common/mac/objc_method_swizzle_unittest.mm',
         'common/mac/objc_zombie_unittest.mm',
         'common/metrics/caching_permuted_entropy_provider_unittest.cc',
-        'common/metrics/metrics_log_base_unittest.cc',
-        'common/metrics/metrics_log_manager_unittest.cc',
         'common/metrics/variations/experiment_labels_unittest.cc',
         'common/metrics/variations/variations_util_unittest.cc',
         'common/multi_process_lock_unittest.cc',
@@ -1978,6 +1991,7 @@
         ['OS!="ios"', {
           'dependencies': [
             '../components/components.gyp:autofill_content_test_support',
+            '../components/components.gyp:component_metrics_proto',
             '../components/components.gyp:data_reduction_proxy_test_support',
             '../components/components_strings.gyp:components_strings',
             '../device/bluetooth/bluetooth.gyp:device_bluetooth_mocks',
@@ -2255,6 +2269,9 @@
           ],
         }],
         ['chromeos==1', {
+          'dependencies': [
+            '../ash/ash.gyp:ash_resources',
+          ],
           'sources!': [
             'browser/extensions/api/messaging/native_message_process_host_unittest.cc',
             'browser/extensions/api/messaging/native_messaging_host_manifest_unittest.cc',
@@ -2276,6 +2293,9 @@
           'sources': [
             'browser/extensions/updater/local_extension_cache_unittest.cc',
           ],
+          'sources/': [
+            ['exclude', '^browser/ui/views/app_list/linux/'],
+          ],
         }, { # else: chromeos == 0
           'sources/': [
             ['exclude', '^browser/chromeos/'],
@@ -2283,6 +2303,7 @@
             ['exclude', '^browser/ui/webui/chromeos/login'],
             ['exclude', '^browser/ui/webui/options/chromeos/'],
             ['exclude', '^browser/ui/webui/options/chromeos/'],
+            ['exclude', '^browser/resources/chromeos/'],
           ],
           'sources!': [
             'browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc',
@@ -2329,8 +2350,7 @@
         }],
         ['os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
@@ -2498,7 +2518,6 @@
             'browser/ui/browser_instant_controller_unittest.cc',
             'browser/ui/bookmarks/bookmark_bubble_sign_in_delegate_unittest.cc',
             'browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc',
-            'browser/ui/bookmarks/bookmark_prompt_controller_unittest.cc',
             'browser/ui/bookmarks/bookmark_unittest.cc',
             'browser/ui/browser_command_controller_unittest.cc',
             'browser/ui/browser_iterator_unittest.cc',
@@ -2676,20 +2695,21 @@
           'dependencies': [
             '../ui/app_list/app_list.gyp:app_list_test_support',
           ],
-          'sources': [
-            'browser/ui/app_list/extension_app_model_builder_unittest.cc',
-            'browser/ui/app_list/test/fast_show_pickler_unittest.cc',
+        }, {
+          'sources/': [
+            ['exclude', '^browser/ui/app_list/'],
+            ['exclude', '^browser/ui/views/app_list/'],
           ],
         }],
         ['use_ozone==1', {
           'sources!': [
+            # crbug.com/354036
+            'browser/chromeos/events/event_rewriter_unittest.cc',
+
             # crbug.com/362698
             'browser/chromeos/input_method/input_method_engine_unittest.cc',
             'browser/chromeos/input_method/input_method_manager_impl_unittest.cc',
           ],
-          'sources/': [
-            ['exclude', '^browser/chromeos/events/'],  # crbug.com/354036
-          ],
         }],
         ['enable_plugin_installation==0', {
           'sources!': [
@@ -2830,36 +2850,5 @@
         },
       ],
     }],
-    ['enable_app_list==1', {
-      'targets': [
-        {
-          # Unit tests for chrome app list, not run on any bots, this is for faster
-          # compile/link/test cycles during development.
-          'target_name': 'chrome_app_list_unittests',
-          'type': '<(gtest_target_type)',
-          'dependencies': [
-            '../base/base.gyp:run_all_unittests',
-            '../chrome/chrome.gyp:test_support_common',
-            '../skia/skia.gyp:skia',
-            '../testing/gtest.gyp:gtest',
-            'browser_ui',
-          ],
-          'sources': [
-            'browser/ui/app_list/app_list_positioner_unittest.cc',
-            'browser/ui/app_list/app_list_service_mac_unittest.mm',
-            'browser/ui/app_list/app_list_service_unittest.cc',
-            'browser/ui/app_list/profile_loader_unittest.cc',
-            'browser/ui/app_list/test/app_list_shower_unittest.cc',
-            'browser/ui/app_list/test/fake_profile.cc',
-            'browser/ui/app_list/test/fake_profile.h',
-            'browser/ui/app_list/test/fake_profile_store.cc',
-            'browser/ui/app_list/test/fake_profile_store.h',
-            'browser/ui/app_list/test/fast_show_pickler_unittest.cc',
-            'browser/ui/views/app_list/linux/app_list_linux_unittest.cc',
-            'browser/ui/views/app_list/win/app_list_win_unittest.cc',
-          ],
-        },
-      ],
-    }],
   ],  # 'conditions'
 }
diff --git a/chrome/chrome_utility.gypi b/chrome/chrome_utility.gypi
new file mode 100644
index 0000000..a5e1e44
--- /dev/null
+++ b/chrome/chrome_utility.gypi
@@ -0,0 +1,152 @@
+# 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.
+
+{
+  'targets': [
+    {
+      'target_name': 'utility',
+      'type': 'static_library',
+      'variables': { 'enable_wexit_time_destructors': 1, },
+      'dependencies': [
+        '../base/base.gyp:base',
+        '../components/components_strings.gyp:components_strings',
+        '../content/content.gyp:content_common',
+        '../content/content.gyp:content_utility',
+        '../media/media.gyp:media',
+        '../skia/skia.gyp:skia',
+        '../third_party/libexif/libexif.gyp:libexif',
+        '../third_party/libxml/libxml.gyp:libxml',
+        '<(DEPTH)/chrome/chrome_resources.gyp:chrome_resources',
+        '<(DEPTH)/chrome/chrome_resources.gyp:chrome_strings',
+        'common',
+        'common/extensions/api/api.gyp:chrome_api',
+      ],
+      'include_dirs': [
+        '..',
+        '<(grit_out_dir)',
+      ],
+      'export_dependent_settings': [
+        'common/extensions/api/api.gyp:chrome_api',
+      ],
+      'sources': [
+        'utility/chrome_content_utility_client.cc',
+        'utility/chrome_content_utility_client.h',
+        'utility/chrome_content_utility_ipc_whitelist.cc',
+        'utility/chrome_content_utility_ipc_whitelist.h',
+        'utility/cloud_print/bitmap_image.cc',
+        'utility/cloud_print/bitmap_image.h',
+        'utility/cloud_print/pwg_encoder.cc',
+        'utility/cloud_print/pwg_encoder.h',
+        'utility/extensions/unpacker.cc',
+        'utility/extensions/unpacker.h',
+        'utility/image_writer/error_messages.cc',
+        'utility/image_writer/error_messages.h',
+        'utility/image_writer/image_writer.cc',
+        'utility/image_writer/image_writer.h',
+        'utility/image_writer/image_writer_handler.cc',
+        'utility/image_writer/image_writer_handler.h',
+        'utility/image_writer/image_writer_win.cc',
+        'utility/importer/bookmark_html_reader.cc',
+        'utility/importer/bookmark_html_reader.h',
+        'utility/importer/bookmarks_file_importer.cc',
+        'utility/importer/bookmarks_file_importer.h',
+        'utility/importer/external_process_importer_bridge.cc',
+        'utility/importer/external_process_importer_bridge.h',
+        'utility/importer/favicon_reencode.cc',
+        'utility/importer/favicon_reencode.h',
+        'utility/importer/firefox_importer.cc',
+        'utility/importer/firefox_importer.h',
+        'utility/importer/ie_importer_win.cc',
+        'utility/importer/ie_importer_win.h',
+        'utility/importer/importer.cc',
+        'utility/importer/importer.h',
+        'utility/importer/importer_creator.cc',
+        'utility/importer/importer_creator.h',
+        'utility/importer/nss_decryptor.cc',
+        'utility/importer/nss_decryptor.h',
+        'utility/importer/nss_decryptor_mac.h',
+        'utility/importer/nss_decryptor_mac.mm',
+        'utility/importer/nss_decryptor_win.cc',
+        'utility/importer/nss_decryptor_win.h',
+        'utility/importer/safari_importer.h',
+        'utility/importer/safari_importer.mm',
+        'utility/media_galleries/image_metadata_extractor.cc',
+        'utility/media_galleries/image_metadata_extractor.h',
+        'utility/media_galleries/ipc_data_source.cc',
+        'utility/media_galleries/ipc_data_source.h',
+        'utility/media_galleries/itunes_pref_parser_win.cc',
+        'utility/media_galleries/itunes_pref_parser_win.h',
+        'utility/media_galleries/media_metadata_parser.cc',
+        'utility/media_galleries/media_metadata_parser.h',
+        'utility/profile_import_handler.cc',
+        'utility/profile_import_handler.h',
+        'utility/utility_message_handler.h',
+        'utility/web_resource_unpacker.cc',
+        'utility/web_resource_unpacker.h',
+      ],
+      'conditions': [
+        ['OS=="win" or OS=="mac"', {
+          'dependencies': [
+            '../components/components.gyp:wifi_component',
+          ],
+          'sources': [
+            'utility/media_galleries/iapps_xml_utils.cc',
+            'utility/media_galleries/iapps_xml_utils.h',
+            'utility/media_galleries/itunes_library_parser.cc',
+            'utility/media_galleries/itunes_library_parser.h',
+            'utility/media_galleries/picasa_album_table_reader.cc',
+            'utility/media_galleries/picasa_album_table_reader.h',
+            'utility/media_galleries/picasa_albums_indexer.cc',
+            'utility/media_galleries/picasa_albums_indexer.h',
+            'utility/media_galleries/pmp_column_reader.cc',
+            'utility/media_galleries/pmp_column_reader.h',
+          ],
+        }],
+        ['OS=="mac"', {
+          'sources': [
+            'utility/media_galleries/iphoto_library_parser.cc',
+            'utility/media_galleries/iphoto_library_parser.h',
+          ],
+        }],
+        ['use_openssl==1', {
+          'sources!': [
+            'utility/importer/nss_decryptor.cc',
+          ]
+        }],
+        ['OS!="win" and OS!="mac" and use_openssl==0', {
+          'dependencies': [
+            '../crypto/crypto.gyp:crypto',
+          ],
+          'sources': [
+            'utility/importer/nss_decryptor_system_nss.cc',
+            'utility/importer/nss_decryptor_system_nss.h',
+          ],
+        }],
+        ['OS=="android"', {
+          'dependencies!': [
+            '../third_party/libexif/libexif.gyp:libexif',
+          ],
+          'sources/': [
+            ['exclude', '^utility/importer/'],
+            ['exclude', '^utility/media_galleries/'],
+            ['exclude', '^utility/profile_import_handler\.cc'],
+          ],
+        }],
+        ['enable_mdns == 1', {
+          'sources': [
+            'utility/local_discovery/service_discovery_message_handler.cc',
+            'utility/local_discovery/service_discovery_message_handler.h',
+          ]
+        }],
+        ['OS!="win"', {
+          'sources': [
+            'utility/image_writer/image_writer_stub.cc',
+          ]
+        }],
+      ],
+      # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+  ],
+}
diff --git a/chrome/common/autocomplete_match_type.cc b/chrome/common/autocomplete_match_type.cc
index 37f8fe0..8d59145 100644
--- a/chrome/common/autocomplete_match_type.cc
+++ b/chrome/common/autocomplete_match_type.cc
@@ -26,6 +26,7 @@
     "extension-app",
     "contact",
     "bookmark-title",
+    "navsuggest-personalized",
   };
   COMPILE_ASSERT(arraysize(strings) == AutocompleteMatchType::NUM_TYPES,
                  strings_array_must_match_type_enum);
diff --git a/chrome/common/autocomplete_match_type.h b/chrome/common/autocomplete_match_type.h
index 41ca793..58440b4 100644
--- a/chrome/common/autocomplete_match_type.h
+++ b/chrome/common/autocomplete_match_type.h
@@ -33,11 +33,14 @@
     SEARCH_SUGGEST_PERSONALIZED = 11,  // A personalized suggested search.
     SEARCH_SUGGEST_PROFILE      = 12,  // A personalized suggested search for a
                                        // Google+ profile.
-    SEARCH_OTHER_ENGINE    = 13,  // A search with a non-default engine.
-    EXTENSION_APP          = 14,  // An Extension App with a title/url that
-                                  // contains the input.
-    CONTACT_DEPRECATED     = 15,  // One of the user's contacts (deprecated).
-    BOOKMARK_TITLE         = 16,  // A bookmark whose title contains the input.
+    SEARCH_OTHER_ENGINE         = 13,  // A search with a non-default engine.
+    EXTENSION_APP               = 14,  // An Extension App with a title/url that
+                                       // contains the input.
+    CONTACT_DEPRECATED          = 15,  // One of the user's contacts
+                                       // (deprecated).
+    BOOKMARK_TITLE              = 16,  // A bookmark whose title contains the
+                                       // input.
+    NAVSUGGEST_PERSONALIZED     = 17,  // A personalized suggestion URL.
     NUM_TYPES,
   };
 
diff --git a/chrome/common/cast_messages.h b/chrome/common/cast_messages.h
index 5b91f59..4191adc 100644
--- a/chrome/common/cast_messages.h
+++ b/chrome/common/cast_messages.h
@@ -63,27 +63,27 @@
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(media::cast::transport::RtpConfig)
-  IPC_STRUCT_TRAITS_MEMBER(history_ms)
+  IPC_STRUCT_TRAITS_MEMBER(ssrc)
   IPC_STRUCT_TRAITS_MEMBER(max_delay_ms)
   IPC_STRUCT_TRAITS_MEMBER(payload_type)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(media::cast::transport::CastTransportBaseConfig)
-  IPC_STRUCT_TRAITS_MEMBER(ssrc)
-  IPC_STRUCT_TRAITS_MEMBER(rtp_config)
   IPC_STRUCT_TRAITS_MEMBER(aes_key)
   IPC_STRUCT_TRAITS_MEMBER(aes_iv_mask)
 IPC_STRUCT_TRAITS_END()
 
+IPC_STRUCT_TRAITS_BEGIN(media::cast::transport::CastTransportRtpConfig)
+  IPC_STRUCT_TRAITS_MEMBER(config)
+  IPC_STRUCT_TRAITS_MEMBER(max_outstanding_frames)
+IPC_STRUCT_TRAITS_END()
+
 IPC_STRUCT_TRAITS_BEGIN(media::cast::transport::CastTransportAudioConfig)
-  IPC_STRUCT_TRAITS_MEMBER(base)
+  IPC_STRUCT_TRAITS_MEMBER(rtp)
   IPC_STRUCT_TRAITS_MEMBER(codec)
   IPC_STRUCT_TRAITS_MEMBER(frequency)
   IPC_STRUCT_TRAITS_MEMBER(channels)
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(media::cast::transport::CastTransportVideoConfig)
-  IPC_STRUCT_TRAITS_MEMBER(base)
+  IPC_STRUCT_TRAITS_MEMBER(rtp)
   IPC_STRUCT_TRAITS_MEMBER(codec)
 IPC_STRUCT_TRAITS_END()
 
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc
index 448d544..26e24ce 100644
--- a/chrome/common/chrome_content_client.cc
+++ b/chrome/common/chrome_content_client.cc
@@ -493,14 +493,6 @@
 #endif
 }
 
-bool ChromeContentClient::CanHandleWhileSwappedOut(
-    const IPC::Message& msg) {
-  // Any Chrome-specific messages (apart from those listed in
-  // CanSendWhileSwappedOut) that must be handled by the browser when sent from
-  // swapped out renderers.
-  return false;
-}
-
 std::string ChromeContentClient::GetProduct() const {
   return ::GetProduct();
 }
diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h
index 845d994..1a05f64 100644
--- a/chrome/common/chrome_content_client.h
+++ b/chrome/common/chrome_content_client.h
@@ -29,7 +29,6 @@
   virtual void AddAdditionalSchemes(
       std::vector<std::string>* standard_schemes,
       std::vector<std::string>* saveable_shemes) OVERRIDE;
-  virtual bool CanHandleWhileSwappedOut(const IPC::Message& msg) OVERRIDE;
   virtual std::string GetProduct() const OVERRIDE;
   virtual std::string GetUserAgent() const OVERRIDE;
   virtual base::string16 GetLocalizedString(int message_id) const OVERRIDE;
diff --git a/chrome/common/chrome_content_client_ios.mm b/chrome/common/chrome_content_client_ios.mm
index 9b625af..52a8d3d 100644
--- a/chrome/common/chrome_content_client_ios.mm
+++ b/chrome/common/chrome_content_client_ios.mm
@@ -35,12 +35,6 @@
   // No additional schemes for iOS.
 }
 
-bool ChromeContentClient::CanHandleWhileSwappedOut(
-    const IPC::Message& msg) {
-  NOTIMPLEMENTED();
-  return false;
-}
-
 std::string ChromeContentClient::GetProduct() const {
   chrome::VersionInfo version_info;
   std::string product("CriOS/");
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 8b011fe..6e5a0e5 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -307,6 +307,9 @@
 // Disables the menu on the NTP for accessing sessions from other devices.
 const char kDisableNTPOtherSessionsMenu[]   = "disable-ntp-other-sessions-menu";
 
+// Disable auto-reload of error pages if offline.
+const char kDisableOfflineAutoReload[]       = "disable-offline-auto-reload";
+
 // Disable the origin chip.
 const char kDisableOriginChip[]             = "disable-origin-chip";
 
@@ -543,6 +546,11 @@
 // Enable auto-reload of error pages if offline.
 const char kEnableOfflineAutoReload[]       = "enable-offline-auto-reload";
 
+// Enable/Disable offering a "Load stale copy" option to the user if offline.
+const char kEnableOfflineLoadStaleCache[]   = "enable-offline-load-stale-cache";
+const char kDisableOfflineLoadStaleCache[]  =
+    "disable-offline-load-stale-cache";
+
 // Controls which branch of the origin chip experiment is enabled. The first
 // flag (enable-origin-chip) is equivalent to the third
 // (enable-origin-chip-trailing-location-bar) and exists for backwards
@@ -727,9 +735,6 @@
 const char kFlagSwitchesBegin[]             = "flag-switches-begin";
 const char kFlagSwitchesEnd[]               = "flag-switches-end";
 
-// Alternative feedback server to use when submitting user feedback
-const char kFeedbackServer[]                = "feedback-server";
-
 // The file descriptor limit is set to the value of this switch, subject to the
 // OS hard limits. Useful for testing that file descriptor exhaustion is
 // handled gracefully.
@@ -1270,10 +1275,6 @@
 // testing flag.
 const char kUseSpdy[]                       = "use-spdy";
 
-// Disables use of the spelling web service and only provides suggestions.
-// This will only work if asynchronous spell checking is not disabled.
-const char kUseSpellingSuggestions[]        = "use-spelling-suggestions";
-
 // A string used to override the default user agent with a custom one.
 const char kUserAgent[]                     = "user-agent";
 
@@ -1324,6 +1325,12 @@
 const char kEnableAccessibilityTabSwitcher[] =
     "enable-accessibility-tab-switcher";
 
+// Enable Answers in Suggest.
+const char kEnableAnswersInSuggest[] = "enable-answers-in-suggest";
+
+// Enables app install alerts.
+const char kEnableAppInstallAlerts[]        = "enable-app-install-alerts";
+
 // Enables Contextual Search
 const char kEnableContextualSearch[]        = "contextual-search";
 
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index f868f3b..cefc7dc 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -93,6 +93,7 @@
 extern const char kDisableIPv6[];
 extern const char kDisableMinimizeOnSecondLauncherItemClick[];
 extern const char kDisableNTPOtherSessionsMenu[];
+extern const char kDisableOfflineAutoReload[];
 extern const char kDisableOriginChip[];
 extern const char kDisableOriginChipV2[];
 extern const char kDisablePasswordManagerReauthentication[];
@@ -158,6 +159,8 @@
 extern const char kEnableNetworkTime[];
 extern const char kEnableNpnHttpOnly[];
 extern const char kEnableOfflineAutoReload[];
+extern const char kEnableOfflineLoadStaleCache[];
+extern const char kDisableOfflineLoadStaleCache[];
 extern const char kEnableOriginChip[];
 extern const char kEnableOriginChipLeadingLocationBar[];
 extern const char kEnableOriginChipTrailingLocationBar[];
@@ -207,7 +210,6 @@
 extern const char kFastStart[];
 extern const char kFlagSwitchesBegin[];
 extern const char kFlagSwitchesEnd[];
-extern const char kFeedbackServer[];
 extern const char kFileDescriptorLimit[];
 extern const char kForceAppMode[];
 extern const char kForceFirstRun[];
@@ -345,7 +347,6 @@
 extern const char kUnlimitedStorage[];
 extern const char kUseSimpleCacheBackend[];
 extern const char kUseSpdy[];
-extern const char kUseSpellingSuggestions[];
 extern const char kUserAgent[];
 extern const char kUserDataDir[];
 extern const char kValidateCrx[];
@@ -364,6 +365,8 @@
 extern const char kDisableNewNTP[];
 extern const char kDisableZeroSuggest[];
 extern const char kEnableAccessibilityTabSwitcher[];
+extern const char kEnableAnswersInSuggest[];
+extern const char kEnableAppInstallAlerts[];
 extern const char kEnableContextualSearch[];
 extern const char kEnableNewNTP[];
 extern const char kEnableZeroSuggestEtherSerp[];
diff --git a/chrome/common/cloud_print/cloud_print_helpers.h b/chrome/common/cloud_print/cloud_print_helpers.h
index 3aba232..273e6d4 100644
--- a/chrome/common/cloud_print/cloud_print_helpers.h
+++ b/chrome/common/cloud_print/cloud_print_helpers.h
@@ -27,7 +27,7 @@
 // URL's path does not end with a slash. It is assumed that |path| does not
 // begin with a '/'.
 // NOTE: Since we ALWAYS want to append here, we simply append the path string
-// instead of calling url_utils::ResolveRelative. The input |url| may or may not
+// instead of calling url::ResolveRelative. The input |url| may or may not
 // contain a '/' at the end.
 std::string AppendPathToUrl(const GURL& url, const std::string& path);
 
diff --git a/chrome/common/common_message_generator.h b/chrome/common/common_message_generator.h
index 3fd05f6..462077e 100644
--- a/chrome/common/common_message_generator.h
+++ b/chrome/common/common_message_generator.h
@@ -27,7 +27,3 @@
 #if defined(ENABLE_WEBRTC)
 #include "chrome/common/media/webrtc_logging_messages.h"
 #endif
-
-#if defined(OS_ANDROID)
-#include "chrome/common/encrypted_media_messages_android.h"
-#endif
diff --git a/chrome/common/content_settings_helper.cc b/chrome/common/content_settings_helper.cc
index dda2cd5..e553eab 100644
--- a/chrome/common/content_settings_helper.cc
+++ b/chrome/common/content_settings_helper.cc
@@ -15,7 +15,7 @@
   std::string port_component(origin.IntPort() != url::PORT_UNSPECIFIED
                                  ? ":" + origin.port()
                                  : std::string());
-  std::string scheme_component(!origin.SchemeIs(content::kHttpScheme)
+  std::string scheme_component(!origin.SchemeIs(url::kHttpScheme)
                                    ? origin.scheme() +
                                      content::kStandardSchemeSeparator
                                    : std::string());
diff --git a/chrome/common/content_settings_pattern.cc b/chrome/common/content_settings_pattern.cc
index 340a211..bfaa66e 100644
--- a/chrome/common/content_settings_pattern.cc
+++ b/chrome/common/content_settings_pattern.cc
@@ -22,9 +22,9 @@
 namespace {
 
 std::string GetDefaultPort(const std::string& scheme) {
-  if (scheme == content::kHttpScheme)
+  if (scheme == url::kHttpScheme)
     return "80";
-  if (scheme == content::kHttpsScheme)
+  if (scheme == url::kHttpsScheme)
     return "443";
   return std::string();
 }
@@ -243,8 +243,8 @@
 
   // Test if the scheme is supported or a wildcard.
   if (!parts.is_scheme_wildcard &&
-      parts.scheme != std::string(content::kHttpScheme) &&
-      parts.scheme != std::string(content::kHttpsScheme)) {
+      parts.scheme != std::string(url::kHttpScheme) &&
+      parts.scheme != std::string(url::kHttpsScheme)) {
     return false;
   }
   return true;
@@ -278,8 +278,8 @@
 
   // Test if the scheme is supported or a wildcard.
   if (!parts.is_scheme_wildcard &&
-      parts.scheme != std::string(content::kHttpScheme) &&
-      parts.scheme != std::string(content::kHttpsScheme)) {
+      parts.scheme != std::string(url::kHttpScheme) &&
+      parts.scheme != std::string(url::kHttpsScheme)) {
     return false;
   }
   return true;
@@ -339,18 +339,18 @@
     // also have a "http" scheme.
     if (local_url->HostIsIPAddress()) {
       builder->WithScheme(local_url->scheme())->WithHost(local_url->host());
-    } else if (local_url->SchemeIs(content::kHttpScheme)) {
+    } else if (local_url->SchemeIs(url::kHttpScheme)) {
       builder->WithSchemeWildcard()->WithDomainWildcard()->WithHost(
           local_url->host());
-    } else if (local_url->SchemeIs(content::kHttpsScheme)) {
+    } else if (local_url->SchemeIs(url::kHttpsScheme)) {
       builder->WithScheme(local_url->scheme())->WithDomainWildcard()->WithHost(
           local_url->host());
     } else {
       // Unsupported scheme
     }
     if (local_url->port().empty()) {
-      if (local_url->SchemeIs(content::kHttpsScheme))
-        builder->WithPort(GetDefaultPort(content::kHttpsScheme));
+      if (local_url->SchemeIs(url::kHttpsScheme))
+        builder->WithPort(GetDefaultPort(url::kHttpsScheme));
       else
         builder->WithPortWildcard();
     } else {
diff --git a/chrome/common/encrypted_media_messages_android.h b/chrome/common/encrypted_media_messages_android.h
deleted file mode 100644
index 034fb3b..0000000
--- a/chrome/common/encrypted_media_messages_android.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2013 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.
-
-// IPC messages for EME on android.
-// Multiply-included message file, hence no include guard.
-
-#include <vector>
-
-#include "content/public/common/eme_codec.h"
-#include "ipc/ipc_message_macros.h"
-
-#define IPC_MESSAGE_START EncryptedMediaMsgStart
-
-IPC_STRUCT_BEGIN(SupportedKeySystemRequest)
-  IPC_STRUCT_MEMBER(std::string, key_system)
-  IPC_STRUCT_MEMBER(content::SupportedCodecs, codecs, content::EME_CODEC_NONE)
-IPC_STRUCT_END()
-
-IPC_STRUCT_BEGIN(SupportedKeySystemResponse)
-  IPC_STRUCT_MEMBER(std::string, key_system)
-  IPC_STRUCT_MEMBER(content::SupportedCodecs,
-                    compositing_codecs,
-                    content::EME_CODEC_NONE)
-  IPC_STRUCT_MEMBER(content::SupportedCodecs,
-                    non_compositing_codecs,
-                    content::EME_CODEC_NONE)
-IPC_STRUCT_END()
-
-// Messages sent from the renderer to the browser.
-
-// Synchronously get a list of supported EME key systems.
-IPC_SYNC_MESSAGE_CONTROL1_1(
-    ChromeViewHostMsg_GetSupportedKeySystems,
-    SupportedKeySystemRequest /* key system information request */,
-    SupportedKeySystemResponse /* key system information response */)
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json
index e1775c4..654eac7 100644
--- a/chrome/common/extensions/api/_api_features.json
+++ b/chrome/common/extensions/api/_api_features.json
@@ -9,6 +9,15 @@
 // Note that specifying "web_page", "blessed_web_page", or "all" as a context
 // type will require manually updating chrome/renderer/resources/dispatcher.cc.
 
+// To add a new whitelisted ID, SHA-1 it and force it to uppercase. In Bash:
+//
+// $ echo -n "aaaabbbbccccddddeeeeffffgggghhhh" | \
+// sha1sum | tr '[:lower:]' '[:upper:]'
+// 9A0417016F345C934A1A88F55CA17C05014EEEBA  -
+//
+// Google employees: please update http://go/chrome-api-whitelist to map
+// hashes back to ids.
+
 {
   "accessibilityFeatures": [{
     "platforms": ["chromeos"],
@@ -19,6 +28,10 @@
     "dependencies": ["permission:accessibilityFeatures.read"],
     "contexts": ["blessed_extension"]
   }],
+  "accessibilityPrivate": {
+    "dependencies": ["permission:accessibilityPrivate"],
+    "contexts": ["blessed_extension"]
+  },
   "activityLogPrivate": {
     "dependencies": ["permission:activityLogPrivate"],
     "contexts": ["blessed_extension"]
@@ -32,6 +45,11 @@
     "contexts": ["blessed_extension"]
   },
   "app": {
+    "blacklist": [
+      "2FC374607C2DF285634B67C64A2E356C607091C3",  // Quickoffice
+      "3727DD3E564B6055387425027AD74C58784ACC15",  // Quickoffice internal
+      "12E618C3C6E97495AAECF2AC12DEB082353241C6"   // QO component extension
+    ],
     "channel": "stable",
     "extension_types": ["hosted_app", "extension", "legacy_packaged_app"],
     "contexts": [
@@ -45,12 +63,23 @@
       "http://*/*", "https://*/*", "chrome-extension://*/*", "file://*/*"
     ]
   },
-  "app.runtime": {
+  "app.runtime": [{
     "channel": "stable",
     "contexts": ["blessed_extension"],
     "extension_types": ["platform_app"],
     "noparent": true
-  },
+  }, {
+    "channel": "stable",
+    "component_extensions_auto_granted": false,
+    "contexts": ["blessed_extension"],
+    "extension_types": ["extension"],
+    "noparent": true,
+    "whitelist": [
+      "2FC374607C2DF285634B67C64A2E356C607091C3",  // Quickoffice
+      "3727DD3E564B6055387425027AD74C58784ACC15",  // Quickoffice internal
+      "12E618C3C6E97495AAECF2AC12DEB082353241C6"   // QO component extension
+    ]
+  }],
   "app.window": {
     "channel": "stable",
     "contexts": ["blessed_extension"],
@@ -93,11 +122,11 @@
   },
   "automationInternal": {
     "internal": true,
-    "dependencies": ["permission:automation"],
+    "dependencies": ["manifest:automation"],
     "contexts": ["blessed_extension"]
   },
   "automation": {
-    "dependencies": ["permission:automation"],
+    "dependencies": ["manifest:automation"],
     "contexts": ["blessed_extension"]
   },
   "autotestPrivate": {
@@ -140,6 +169,10 @@
     "dependencies": ["permission:brailleDisplayPrivate"],
     "contexts": ["blessed_extension"]
   },
+  "browser": {
+    "dependencies": ["permission:browser"],
+    "contexts": ["blessed_extension"]
+  },
   "browserAction": {
     "dependencies": ["manifest:browser_action"],
     "contexts": ["blessed_extension"]
@@ -284,10 +317,6 @@
     "contexts": "all",
     "matches": ["<all_urls>"]
   },
-  "experimental.accessibility": {
-    "dependencies": ["permission:experimental"],
-    "contexts": ["blessed_extension"]
-  },
   "experimental.devtools.audits": {
     "dependencies": ["permission:experimental", "manifest:devtools_page"],
     "extension_types": ["platform_app"],
@@ -360,7 +389,6 @@
     "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
   },
   "screenlockPrivate": {
-    "platforms": ["chromeos"],
     "dependencies": ["permission:screenlockPrivate"],
     "extension_types": ["platform_app"],
     "contexts": ["blessed_extension", "unblessed_extension"]
@@ -481,6 +509,11 @@
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app", "platform_app"]
   },
+  "management.createAppShortcut": {
+    "dependencies": ["permission:management"],
+    "channel": "dev",
+    "contexts": ["blessed_extension"]
+  },
   // This is not a real API, only here for documentation purposes.
   // See http://crbug.com/275944 for background.
   "manifestTypes": {
@@ -589,49 +622,6 @@
     "dependencies": ["permission:rtcPrivate"],
     "contexts": ["blessed_extension"]
   },
-  "runtime": {
-    "channel": "stable",
-    "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
-    "contexts": ["blessed_extension"]
-  },
-  "runtime.connect": {
-    "contexts": "all",
-    "matches": ["<all_urls>"]
-  },
-  "runtime.getManifest": {
-    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
-  },
-  "runtime.getURL": {
-    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
-  },
-  "runtime.id": {
-    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
-  },
-  "runtime.lastError": {
-    "contexts": "all",
-    "extension_types": "all",
-    "matches": ["<all_urls>"]
-  },
-  "runtime.onConnect": {
-    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
-  },
-  "runtime.onMessage": {
-    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
-  },
-  "runtime.reload": {
-    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
-  },
-  "runtime.requestUpdateCheck": {
-    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
-  },
-  "runtime.sendMessage": {
-    "contexts": "all",
-    "matches": ["<all_urls>"]
-  },
-  "runtime.setUninstallURL": {
-    "channel": "dev",
-    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
-  },
   "scriptBadge": {
     "dependencies": ["manifest:script_badge"],
     "contexts": ["blessed_extension"]
@@ -713,20 +703,6 @@
     "dependencies": ["permission:ttsEngine"],
     "contexts": ["blessed_extension"]
   },
-  "types": {
-    "channel": "stable",
-    "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
-    "contexts": ["blessed_extension"]
-  },
-  "types.private": {
-    "channel": "dev",
-    "extension_types": ["extension"],
-    "location": "component"
-  },
-  "usb": {
-    "dependencies": ["permission:usb"],
-    "contexts": ["blessed_extension"]
-  },
   "virtualKeyboardPrivate": {
     "platforms": ["chromeos"],
     "dependencies": ["permission:virtualKeyboardPrivate"],
diff --git a/chrome/common/extensions/api/_manifest_features.json b/chrome/common/extensions/api/_manifest_features.json
index 4560f45..7f1a73d 100644
--- a/chrome/common/extensions/api/_manifest_features.json
+++ b/chrome/common/extensions/api/_manifest_features.json
@@ -6,6 +6,15 @@
 // See extensions/common/features/* to understand this file, in particular
 // feature.h, simple_feature.h, and base_feature_provider.h.
 
+// To add a new whitelisted ID, SHA-1 it and force it to uppercase. In Bash:
+//
+// $ echo -n "aaaabbbbccccddddeeeeffffgggghhhh" | \
+// sha1sum | tr '[:lower:]' '[:upper:]'
+// 9A0417016F345C934A1A88F55CA17C05014EEEBA  -
+//
+// Google employees: please update http://go/chrome-api-whitelist to map
+// hashes back to ids.
+
 {
   "app": {
     "channel": "stable",
@@ -29,6 +38,10 @@
     "channel": "stable",
     "extension_types": "all"
   },
+  "automation": {
+    "channel": "trunk",
+    "extension_types": ["extension", "legacy_packaged_app"]
+  },
   "bluetooth": {
     // Note: The "bluetooth" manifest permission is used by the
     // chrome.bluetooth, chrome.bluetoothSocket and chrome.bluetoothLowEnergy
@@ -169,10 +182,19 @@
       "location": "component"
     }
   ],
-  "file_handlers": {
+  "file_handlers": [
+  {
     "channel": "stable",
     "extension_types": ["platform_app"]
-  },
+  }, {
+    "channel": "stable",
+    "extension_types": [ "extension"],
+    "whitelist": [
+      "2FC374607C2DF285634B67C64A2E356C607091C3",  // Quickoffice
+      "3727DD3E564B6055387425027AD74C58784ACC15",  // Quickoffice internal
+      "12E618C3C6E97495AAECF2AC12DEB082353241C6"   // QO component extension
+    ]
+  }],
   "homepage_url": {
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app"]
@@ -328,10 +350,25 @@
     "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
     "min_manifest_version": 2
   },
-  "system_indicator": {
-    "channel": "dev",
-    "extension_types": ["extension", "legacy_packaged_app", "platform_app"]
-  },
+  "system_indicator": [
+    {
+      "channel": "dev",
+      "extension_types": ["extension", "legacy_packaged_app", "platform_app"]
+    },
+    {
+      "channel": "stable",
+      "whitelist": [
+        "F29716B08705C9D3C12CDFE3F638BAE709570C31",  // browser_tests
+        // See crbug.com/245730 for details on the Hangouts whitelist.
+        "53041A2FA309EECED01FFC751E7399186E860B2C",  // Hangouts
+        "312745D9BF916161191143F6490085EEA0434997",  // Hangouts beta
+        "A74A4D44C7CFCD8844830E6140C8D763E12DD8F3",  // Hangouts alpha
+        "E7E2461CE072DF036CF9592740196159E2D7C089",  // Hangouts debug
+        "49DA0B9CCEEA299186C6E7226FD66922D57543DC"   // Hangouts dev
+      ],
+      "extension_types": ["extension", "platform_app"]
+    }
+  ],
   "theme": {
     "channel": "stable",
     "extension_types": ["theme"]
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index 47e1712..fe9e0e5 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -25,6 +25,11 @@
     "channel": "dev",
     "extension_types": ["extension", "platform_app"]
   },
+  "accessibilityPrivate": {
+    "channel": "stable",
+    "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
+    "whitelist": [ "2FCBCE08B34CCA1728A85F1EFBD9A34DD2558B2E" ]
+  },
   "activeTab": {
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app"],
@@ -83,10 +88,6 @@
       ]
     }
   ],
-  "automation": {
-    "channel": "trunk",
-    "extension_types": ["extension", "legacy_packaged_app", "platform_app"]
-  },
   "autotestPrivate": {
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app"],
@@ -152,6 +153,10 @@
     "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
     "location": "component"
   },
+  "browser": {
+    "channel": "dev",
+    "extension_types": ["platform_app"]
+  },
   "browsingData": {
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app"]
@@ -375,7 +380,9 @@
     "whitelist": [
       "2FC374607C2DF285634B67C64A2E356C607091C3",  // Quickoffice
       "3727DD3E564B6055387425027AD74C58784ACC15",  // Quickoffice internal
-      "12E618C3C6E97495AAECF2AC12DEB082353241C6"   // QO component extension
+      "12E618C3C6E97495AAECF2AC12DEB082353241C6",  // QO component extension
+      "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2",  // http://crbug.com/312900
+      "D57DE394F36DC1C3220E7604C575D29C51A6C495"   // http://crbug.com/319444
     ]
   }],
   "fileSystem.directory": [{
@@ -395,7 +402,9 @@
     "whitelist": [
       "2FC374607C2DF285634B67C64A2E356C607091C3",  // Quickoffice
       "3727DD3E564B6055387425027AD74C58784ACC15",  // Quickoffice internal
-      "12E618C3C6E97495AAECF2AC12DEB082353241C6"   // QO component extension
+      "12E618C3C6E97495AAECF2AC12DEB082353241C6",  // QO component extension
+      "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2",  // http://crbug.com/312900
+      "D57DE394F36DC1C3220E7604C575D29C51A6C495"   // http://crbug.com/319444
     ]
   }],
   "fileSystemProvider": {
@@ -601,7 +610,10 @@
       "C7DA3A55C2355F994D3FDDAD120B426A0DF63843",  // CCD Testing
       "75E3CFFFC530582C583E4690EF97C70B9C8423B7",  // CCD Release
       "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2",  // http://crbug.com/312900.
-      "D57DE394F36DC1C3220E7604C575D29C51A6C495"   // http://crbug.com/319444.
+      "D57DE394F36DC1C3220E7604C575D29C51A6C495",  // http://crbug.com/319444.
+      "06BE211D5F014BAB34BC22D9DDA09C63A81D828E",  // Official XKB virtual kbd
+      "CFBF7EE448FA48960FFDA7CEB30F7A21B26AA981",  // Official m17n virtual kbd
+      "B9EF10DDFEA11EF77873CC5009809E5037FC4C7A"   // Google input tools
     ]
   },
   "mdns": {
@@ -707,10 +719,26 @@
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app"]
   },
-  "processes": {
+  "processes": [{
     "channel": "dev",
     "extension_types": ["extension"]
-  },
+  }, {
+    "channel": "beta",
+    "extension_types": ["extension"],
+    "whitelist": [
+      "7D7A4B147FE39908A5AF13F85E38989C54BBE41C",  // http://crbug.com/370700
+      "0EEDFC0EED87871237213F34EBC7B4982A195C95"   // http://crbug.com/370700
+    ]
+  }, {
+    "channel": "stable",
+    "extension_types": ["extension"],
+    "whitelist": [
+      "DF84F03F9B960409CCDE0D895B9650EBE81C0A8E",  // Hangout Services
+      "80B9DC58E5210749F052F5B4DB239C50CF72AEB6",  // Hangouts test extension
+      "7D7A4B147FE39908A5AF13F85E38989C54BBE41C",  // http://crbug.com/370700
+      "0EEDFC0EED87871237213F34EBC7B4982A195C95"   // http://crbug.com/370700
+    ]
+  }],
   "proxy": {
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app"]
@@ -745,12 +773,6 @@
       "312745D9BF916161191143F6490085EEA0434997"   // Google Talk debug
     ]
   },
-  // Note: runtime is not actually a permission, but some systems check these
-  // values to verify restrictions.
-  "runtime": {
-    "channel": "stable",
-    "extension_types": ["extension", "legacy_packaged_app", "platform_app"]
-  },
   "screenlockPrivate": {
     "channel": "stable",
     "extension_types": ["platform_app"],
@@ -793,10 +815,6 @@
     "channel": "stable",
     "extension_types": ["platform_app"]
   },
-  "systemIndicator": {
-    "channel": "dev",
-    "extension_types": ["extension", "legacy_packaged_app", "platform_app"]
-  },
   "system.cpu": {
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app", "platform_app"]
@@ -867,34 +885,6 @@
       "extension", "legacy_packaged_app", "hosted_app", "platform_app"
     ]
   },
-  "usb": [
-    {
-      "channel": "stable",
-      "extension_types": ["platform_app"]
-    },
-    {
-      "channel": "stable",
-      "extension_types": ["extension"],
-      "whitelist": [
-        "496B6890097EB6E19809ADEADD095A8721FBB2E0",  // FIDO U2F APIs
-        "E24F1786D842E91E74C27929B0B3715A4689A473"   // CryptoToken
-      ]
-    }
-  ],
-  "usbDevices": [
-    {
-      "channel": "stable",
-      "extension_types": ["platform_app"]
-    },
-    {
-      "channel": "stable",
-      "extension_types": ["extension"],
-      "whitelist": [
-        "496B6890097EB6E19809ADEADD095A8721FBB2E0",  // FIDO U2F APIs
-        "E24F1786D842E91E74C27929B0B3715A4689A473"   // CryptoToken
-      ]
-    }
-  ],
   "videoCapture": [
     {
       "channel": "stable",
@@ -939,6 +929,7 @@
     "channel": "stable",
     "extension_types": ["extension"],
     "whitelist": [
+      // Hangouts test extension
       "80B9DC58E5210749F052F5B4DB239C50CF72AEB6",
       // Hangout Services component extension.
       "DF84F03F9B960409CCDE0D895B9650EBE81C0A8E",
@@ -950,6 +941,7 @@
     "channel": "stable",
     "extension_types": ["extension"],
     "whitelist": [
+      // Hangouts test extension
       "80B9DC58E5210749F052F5B4DB239C50CF72AEB6",
       // Hangout Services component extension.
       "DF84F03F9B960409CCDE0D895B9650EBE81C0A8E"
diff --git a/chrome/common/extensions/api/accessibility_private.json b/chrome/common/extensions/api/accessibility_private.json
new file mode 100644
index 0000000..192fda2
--- /dev/null
+++ b/chrome/common/extensions/api/accessibility_private.json
@@ -0,0 +1,337 @@
+// 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.
+
+[
+  {
+    "namespace": "accessibilityPrivate",
+    "compiler_options": {
+      "implemented_in": "chrome/browser/accessibility/accessibility_extension_api.h"
+    },
+    "description": "none",
+    "types": [
+      {
+        "id": "CheckboxDetails",
+        "type": "object",
+        "description": "Information about the state of a checkbox.",
+        "properties": {
+          "isChecked": {"type": "boolean", "description": "True if this checkbox is checked."}
+        }
+      },
+      {
+        "id": "ComboBoxDetails",
+        "type": "object",
+        "description": "Information about the state of a combo box.",
+        "properties": {
+          "value": {"type": "string", "description": "The value of the combo box."},
+          "itemCount": {"type": "integer", "description": "The number of items in the combo box's list."},
+          "itemIndex": {"type": "integer", "description": "The 0-based index of the current value, or -1 if the user entered a value not from the list."}
+        }
+      },
+      {
+        "id": "ListBoxDetails",
+        "type": "object",
+        "description": "Information about the state of a list box.",
+        "properties": {
+          "value": {"type": "string", "description": "The value of the list box."},
+          "itemCount": {"type": "integer", "description": "The number of items in the list."},
+          "itemIndex": {"type": "integer", "description": "The 0-based index of the selected value, or -1 if no items are selected."}
+        }
+      },
+      {
+        "id": "MenuDetails",
+        "type": "object",
+        "description": "Information about the state of a drop-down menu.",
+        "properties": {
+        }
+      },
+      {
+        "id": "MenuItemDetails",
+        "type": "object",
+        "description": "Information about a menu item.",
+        "properties": {
+          "hasSubmenu": {"type": "boolean", "description": "True if this item opens a submenu."},
+          "itemCount": {"type": "integer", "description": "The number of items in the menu."},
+          "itemIndex": {"type": "integer", "description": "The 0-based index of this menu item."}
+        }
+      },
+      {
+        "id": "RadioButtonDetails",
+        "type": "object",
+        "description": "Information about the state of a radio button.",
+        "properties": {
+          "isChecked": {"type": "boolean", "description": "True if this radio button is checked."},
+          "itemCount": {"type": "integer", "description": "The number of radio buttons in this group."},
+          "itemIndex": {"type": "integer", "description": "The 0-based index of this radio button in this group."}
+        }
+      },
+      {
+        "id": "SliderDetails",
+        "type": "object",
+        "description": "Information about the state of a slider.",
+        "properties": {
+          "stringValue": {"type": "string", "description": "The value of the slider as a string."}
+        }
+      },
+      {
+        "id": "TabDetails",
+        "type": "object",
+        "description": "Additional accessibility information about a tab.",
+        "properties": {
+          "itemCount": {"type": "integer", "description": "The number of tabs in this group."},
+          "itemIndex": {"type": "integer", "description": "The 0-based index of this tab in this group."}
+        }
+      },
+      {
+        "id": "TextBoxDetails",
+        "type": "object",
+        "description": "Information about the state of a text box.",
+        "properties": {
+          "value": {"type": "string", "description": "The value of the text box - the entered text."},
+          "isPassword": {"type": "boolean", "description": "True if this control contains password text whose contents should be obscured."},
+          "selectionStart": {"type": "integer", "description": "The index of the character where the selection starts, if this control contains editable text."},
+          "selectionEnd": {"type": "integer", "description": "The index of the character where the selection ends, if this control contains editable text."}
+        }
+      },
+      {
+        "id": "TreeDetails",
+        "type": "object",
+        "description": "Information about the state of a tree control.",
+        "properties": {
+        }
+      },
+      {
+        "id": "TreeItemDetails",
+        "type": "object",
+        "description": "Information about a selected tree control item.",
+        "properties": {
+          "itemDepth": {"type": "integer", "description": "The 0-based depth of this tree item."},
+          "itemCount": {"type": "integer", "description": "The number of items in the current depth."},
+          "itemIndex": {"type": "integer", "description": "The 0-based index of this tree item at the current tree depth."},
+          "childrenCount": {"type": "integer", "description": "The number of children of the current tree item."},
+          "isItemExpanded": {"type": "boolean", "description": "True if this if this tree item is expanded."}
+        }
+      },
+      {
+        "id": "AlertInfo",
+        "type": "object",
+        "description": "Information about an alert",
+        "properties": {
+          "message": {
+            "type": "string",
+            "description": "The message the alert is showing."
+          }
+        }
+      },
+      {
+        "id": "AccessibilityObject",
+        "type": "object",
+        "description": "Parent class for accessibility information about an object.",
+        "properties": {
+          "type": {
+            "type": "string",
+            "description": "The type of this object, which determines the contents of 'details'.",
+            "enum": ["alert", "button", "checkbox", "combobox", "link", "menu", "menuitem", "radiobutton", "slider", "tab", "textbox", "tree", "treeitem", "window"]
+          },
+          "name": {
+            "type": "string",
+            "description": "The localized name of the object, like OK or Password. Do not rely on an exact string match because the text will be in the user's language and may change in the future."
+          },
+          "context": {
+            "type": "string",
+            "description": "The localized name of the context for the object, like the name of the surrounding toolbar or group of controls.",
+            "optional": true
+          },
+          "details": {
+            "description": "Other details like the state, depending on the type of object.",
+            "optional": true,
+            "choices": [
+              { "$ref": "CheckboxDetails" },
+              { "$ref": "ComboBoxDetails" },
+              { "$ref": "MenuDetails" },
+              { "$ref": "MenuItemDetails" },
+              { "$ref": "RadioButtonDetails" },
+              { "$ref": "SliderDetails" },
+              { "$ref": "TabDetails" },
+              { "$ref": "TextBoxDetails" },
+              { "$ref": "TreeDetails" },
+              { "$ref": "TreeItemDetails" }
+            ]
+          }
+        }
+      }
+    ],
+    "functions": [
+      {
+        "name": "setAccessibilityEnabled",
+        "type": "function",
+        "description": "Enables or disables the accessibility extension api. This must be set to true before event listeners or getFocusedControl will work.",
+        "parameters": [
+          {
+            "type": "boolean",
+            "name": "enabled",
+            "description": "True if accessibility support should be enabled."
+          }
+        ]
+      },
+      {
+        "name": "setNativeAccessibilityEnabled",
+        "type": "function",
+        "description": "Enables or disables native accessibility support. Once disabled, it is up to the calling extension to provide accessibility for web contents.",
+        "parameters": [
+          {
+            "type": "boolean",
+            "name": "enabled",
+            "description": "True if native accessibility support should be enabled."
+          }
+        ]
+      },
+      {
+        "name": "getFocusedControl",
+        "type": "function",
+        "description": "Gets information about the currently focused control.",
+        "parameters": [
+          {
+            "type": "function",
+            "name": "callback",
+            "parameters": [
+              {
+                "name": "control",
+                "description": "Details of the currently focused control, or null if nothing is focused.",
+                "$ref": "AccessibilityObject",
+                "optional": true
+              }
+            ]
+          }
+        ]
+      },
+      {
+        "name": "getAlertsForTab",
+        "type": "function",
+        "description": "Gets alerts being shown on the given tab.",
+        "parameters": [
+          {
+            "name": "tabId",
+            "type": "integer",
+            "minimum": 0
+          },
+          {
+            "type": "function",
+            "name": "callback",
+            "parameters": [
+              {
+                "name": "alerts",
+                "type": "array",
+                "items": { "$ref": "AlertInfo" },
+                "description": "Alerts being shown on the given tab."
+              }
+            ]
+          }
+        ]
+      }
+    ],
+    "events": [
+      {
+        "name": "onWindowOpened",
+        "type": "function",
+        "description": "Fired when a window is opened.",
+        "parameters": [
+          {
+            "$ref": "AccessibilityObject",
+            "name": "window",
+            "description": "Information about the window that was opened."
+          }
+        ]
+      },
+      {
+        "name": "onWindowClosed",
+        "type": "function",
+        "description": "Fired when a window is closed.",
+        "parameters": [
+          {
+            "$ref": "AccessibilityObject",
+            "name": "window",
+            "description": "Information about the window that was closed."
+          }
+        ]
+      },
+      {
+        "name": "onControlFocused",
+        "type": "function",
+        "description": "Fired when a control is focused.",
+        "parameters": [
+          {
+            "$ref": "AccessibilityObject",
+            "name": "control",
+            "description": "Details of the control that was focused."
+          }
+        ]
+      },
+      {
+        "name": "onControlAction",
+        "type": "function",
+        "description": "Fired when a control's action is taken, like pressing a button or toggling a checkbox.",
+        "parameters": [
+          {
+            "$ref": "AccessibilityObject",
+            "name": "control",
+            "description": "Details of the control whose action was taken."
+          }
+        ]
+      },
+      {
+        "name": "onTextChanged",
+        "type": "function",
+        "description": "Fired when text changes in an editable text control.",
+        "parameters": [
+          {
+            "$ref": "AccessibilityObject",
+            "name": "control",
+            "description": "Details of the control where the text changed."
+          }
+        ]
+      },
+      {
+        "name": "onMenuOpened",
+        "type": "function",
+        "description": "Fired when a menu is opened.",
+        "parameters": [
+          {
+            "$ref": "AccessibilityObject",
+            "name": "menu",
+            "description": "Information about the menu that was opened."
+          }
+        ]
+      },
+      {
+        "name": "onMenuClosed",
+        "type": "function",
+        "description": "Fired when a menu is closed.",
+        "parameters": [
+          {
+            "$ref": "AccessibilityObject",
+            "name": "menu",
+            "description": "Information about the menu that was closed."
+          }
+        ]
+      },
+      {
+        "name": "onChromeVoxLoadStateChanged",
+        "type": "function",
+        "description": "Fired ChromeVox load state changes.",
+        "parameters": [
+          {
+            "type": "boolean",
+            "name": "loading",
+            "description": "True if ChromeVox is loading; false if ChromeVox is unloading."
+          },
+          {
+            "type": "boolean",
+            "name": "makeAnnouncements",
+            "description": "Whether to make introductory announcements."
+          }
+        ]
+      }
+    ]
+  }
+]
diff --git a/chrome/common/extensions/api/alarms.idl b/chrome/common/extensions/api/alarms.idl
index 55349be..500d2ed 100644
--- a/chrome/common/extensions/api/alarms.idl
+++ b/chrome/common/extensions/api/alarms.idl
@@ -40,7 +40,7 @@
     double? periodInMinutes;
   };
 
-  callback AlarmCallback = void (Alarm alarm);
+  callback AlarmCallback = void (optional Alarm alarm);
   callback AlarmListCallback = void (Alarm[] alarms);
   callback ClearCallback = void (boolean wasCleared);
 
diff --git a/chrome/common/extensions/api/api.gyp b/chrome/common/extensions/api/api.gyp
index 7ba5fa1..d3f4b8b 100644
--- a/chrome/common/extensions/api/api.gyp
+++ b/chrome/common/extensions/api/api.gyp
@@ -36,6 +36,7 @@
         'conditions': [
           ['OS!="android"', {
             'schema_files': [
+              'accessibility_private.json',
               'activity_log_private.json',
               'alarms.idl',
               'app_current_window_internal.idl',
@@ -50,6 +51,7 @@
               'bluetooth_socket.idl',
               'bookmark_manager_private.json',
               'bookmarks.json',
+              'browser.idl',
               'braille_display_private.idl',
               'cast_channel.idl',
               'cloud_print_private.json',
@@ -67,7 +69,6 @@
               'echo_private.json',
               'enterprise_platform_keys_private.json',
               'events.json',
-              'experimental_accessibility.json',
               'feedback_private.idl',
               'file_browser_private.idl',
               'file_system.idl',
@@ -101,7 +102,7 @@
               'power.idl',
               'push_messaging.idl',
               'reading_list_private.json',
-              'runtime.json',
+              'screenlock_private.idl',
               'serial.idl',
               'sessions.json',
               'signed_in_devices.idl',
@@ -118,7 +119,6 @@
               'tabs.json',
               'terminal_private.json',
               'types.json',
-              'usb.idl',
               'virtual_keyboard_private.json',
               'web_navigation.json',
               'web_request.json',
@@ -145,7 +145,6 @@
                 'manifest_types.json',
                 'omnibox.json',
                 'permissions.json',
-                'runtime.json',
                 'sync_file_system.idl',
                 'tab_capture.idl',
                 'tabs.json',
@@ -163,7 +162,6 @@
               'file_browser_handler_internal.json',
               'first_run_private.json',
               'log_private.idl',
-              'screenlock_private.idl',
               'wallpaper.json',
               'wallpaper_private.json',
               'webcam_private.idl',
diff --git a/chrome/common/extensions/api/app_window.idl b/chrome/common/extensions/api/app_window.idl
index 0b2d3e8..daf90f4 100644
--- a/chrome/common/extensions/api/app_window.idl
+++ b/chrome/common/extensions/api/app_window.idl
@@ -106,20 +106,20 @@
     DOMString? type;
     // Allows the frame color to be set. Frame coloring is only available if the
     // frame type is <code>chrome</code>.<br>
-    // Frame coloring is experimental and only available in dev channel.
+    // Frame coloring is new in Chrome 36.
     DOMString? color;
     // Allows the frame color of the window when active to be set. Frame
     // coloring is only available if the frame type is <code>chrome</code>.<br>
     // Frame coloring is only available if the frame type is
     // <code>chrome</code>.<br>
-    // Frame coloring is experimental and only available in dev channel.
+    // Frame coloring is new in Chrome 36.
     DOMString? activeColor;
     // Allows the frame color of the window when inactive to be set differently
     // to the active color. Frame
     // coloring is only available if the frame type is <code>chrome</code>.<br>
     // <code>inactiveColor</code> must be used in conjunction with <code>
     // color</code>.<br>
-    // Frame coloring is experimental and only available in dev channel.
+    // Frame coloring is new in Chrome 36.
     DOMString? inactiveColor;
   };
 
@@ -212,7 +212,7 @@
     // draggability to the app's window. <code>-webkit-app-region: drag</code>
     // can be used to mark regions draggable. <code>no-drag</code> can be used
     // to disable this style on nested elements.<br>
-    // Use of <code>FrameOptions</code> is only supported in dev channel.
+    // Use of <code>FrameOptions</code> is new in M36.
     (DOMString or FrameOptions)? frame;
 
     // Size and position of the content in the window (excluding the titlebar).
@@ -244,7 +244,7 @@
 
     // If true, the window will stay above most other windows. If there are
     // multiple windows of this kind, the currently focused window will be in
-    // the foreground. Requires the <code>"app.window.alwaysOnTop"</code>
+    // the foreground. Requires the <code>"alwaysOnTopWindows"</code>
     // permission. Defaults to false.<br>
     // Call <code>setAlwaysOnTop()</code> on the window to change this property
     // after creation.<br>
@@ -271,9 +271,8 @@
     // Fullscreens the window.<br>
     // The user will be able to restore the window by pressing ESC. An
     // application can prevent the fullscreen state to be left when ESC is
-    // pressed by requesting the <b>app.window.fullscreen.overrideEsc</b>
-    // permission and canceling the event by calling .preventDefault(), like
-    // this:<br>
+    // pressed by requesting the <b>overrideEscFullscreen</b> permission and
+    // canceling the event by calling .preventDefault(), like this:<br>
     // <code>window.onKeyDown = function(e) { if (e.keyCode == 27 /* ESC */) {
     // e.preventDefault(); } };</code>
     static void fullscreen();
@@ -346,7 +345,7 @@
     [nodoc] long inactiveFrameColor;
 
     // Set whether the window should stay above most other windows. Requires the
-    // <code>"app.window.alwaysOnTop"</code> permission.
+    // <code>"alwaysOnTopWindows"</code> permission.
     static void setAlwaysOnTop(boolean alwaysOnTop);
 
     // The JavaScript 'window' object for the created child.
diff --git a/chrome/common/extensions/api/automation.idl b/chrome/common/extensions/api/automation.idl
index 3b280c7..9dd1072 100644
--- a/chrome/common/extensions/api/automation.idl
+++ b/chrome/common/extensions/api/automation.idl
@@ -95,5 +95,8 @@
     // loaded (the previous root node reference will stop working at or before
     // this point).
     [nocompile] static void getTree(RootCallback callback);
+
+    // Get the automation tree for the desktop.
+    [nocompile] static void getDesktop(RootCallback callback);
   };
 };
diff --git a/chrome/common/extensions/api/automation_internal.idl b/chrome/common/extensions/api/automation_internal.idl
index dbdb91b..6d8becc 100644
--- a/chrome/common/extensions/api/automation_internal.idl
+++ b/chrome/common/extensions/api/automation_internal.idl
@@ -84,6 +84,10 @@
     // in future updates.
     static void enableCurrentTab(EnableCallback callback);
 
+    // Enables desktop automation.
+    static void enableDesktop();
+
+    // Performs an action on an automation node.
     static void performAction(PerformActionRequiredParams args,
                               object opt_args);
   };
diff --git a/chrome/common/extensions/api/browser.idl b/chrome/common/extensions/api/browser.idl
new file mode 100644
index 0000000..99515dc
--- /dev/null
+++ b/chrome/common/extensions/api/browser.idl
@@ -0,0 +1,26 @@
+// 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.
+
+// Use the <code>chrome.browser</code> API to interact with the Chrome browser
+// associated with the current application and Chrome profile.
+[nodoc] namespace browser {
+  // Options for the $(ref:openTab) function.
+  dictionary OpenTabOptions {
+    // The URL to navigate to when the new tab is initially opened.
+    DOMString url;
+  };
+
+  callback Callback = void();
+
+  interface Functions {
+    // Opens a new tab in a browser window associated with the current
+    // application and Chrome profile. If no browser window for the Chrome
+    // profile is opened, a new one is opened prior to creating the new tab. The
+    // initial URL of the new tab is specified in |options|.
+    // |options|  : The $(ref:OpenTabOptions) for this function.
+    // |callback| : Called to indicate success or failure.
+    static void openTab(OpenTabOptions options,
+                        Callback callback);
+  };
+};
diff --git a/chrome/common/extensions/api/cast_streaming_rtp_stream.idl b/chrome/common/extensions/api/cast_streaming_rtp_stream.idl
index f1bae6e..afada05 100644
--- a/chrome/common/extensions/api/cast_streaming_rtp_stream.idl
+++ b/chrome/common/extensions/api/cast_streaming_rtp_stream.idl
@@ -48,10 +48,10 @@
     // Video height in pixels.
     long? height;
 
-    // 16 bytes AES key encoded in Base64.
+    // 32 bytes hex-encoded AES key.
     DOMString? aesKey;
 
-    // 16 bytes AES IV (Initialization vector) mask encoded in Base64.
+    // 32 bytes hex-encoded AES IV (Initialization vector) mask.
     DOMString? aesIvMask;
 
     // A list of codec specific params.
diff --git a/chrome/common/extensions/api/diagnostics.idl b/chrome/common/extensions/api/diagnostics.idl
index b498dbb..5f8f31d 100644
--- a/chrome/common/extensions/api/diagnostics.idl
+++ b/chrome/common/extensions/api/diagnostics.idl
@@ -19,7 +19,7 @@
   };
 
   dictionary SendPacketResult {
-    // The IP of the host which we recieves the ICMP reply from.
+    // The IP of the host which we receives the ICMP reply from.
     // The IP may differs from our target IP if the packet's ttl is used up.
     DOMString ip;
 
diff --git a/chrome/common/extensions/api/experimental_accessibility.json b/chrome/common/extensions/api/experimental_accessibility.json
deleted file mode 100644
index a658b60..0000000
--- a/chrome/common/extensions/api/experimental_accessibility.json
+++ /dev/null
@@ -1,337 +0,0 @@
-// 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.
-
-[
-  {
-    "namespace": "experimental.accessibility",
-    "compiler_options": {
-      "implemented_in": "chrome/browser/accessibility/accessibility_extension_api.h"
-    },
-    "description": "none",
-    "types": [
-      {
-        "id": "CheckboxDetails",
-        "type": "object",
-        "description": "Information about the state of a checkbox.",
-        "properties": {
-          "isChecked": {"type": "boolean", "description": "True if this checkbox is checked."}
-        }
-      },
-      {
-        "id": "ComboBoxDetails",
-        "type": "object",
-        "description": "Information about the state of a combo box.",
-        "properties": {
-          "value": {"type": "string", "description": "The value of the combo box."},
-          "itemCount": {"type": "integer", "description": "The number of items in the combo box's list."},
-          "itemIndex": {"type": "integer", "description": "The 0-based index of the current value, or -1 if the user entered a value not from the list."}
-        }
-      },
-      {
-        "id": "ListBoxDetails",
-        "type": "object",
-        "description": "Information about the state of a list box.",
-        "properties": {
-          "value": {"type": "string", "description": "The value of the list box."},
-          "itemCount": {"type": "integer", "description": "The number of items in the list."},
-          "itemIndex": {"type": "integer", "description": "The 0-based index of the selected value, or -1 if no items are selected."}
-        }
-      },
-      {
-        "id": "MenuDetails",
-        "type": "object",
-        "description": "Information about the state of a drop-down menu.",
-        "properties": {
-        }
-      },
-      {
-        "id": "MenuItemDetails",
-        "type": "object",
-        "description": "Information about a menu item.",
-        "properties": {
-          "hasSubmenu": {"type": "boolean", "description": "True if this item opens a submenu."},
-          "itemCount": {"type": "integer", "description": "The number of items in the menu."},
-          "itemIndex": {"type": "integer", "description": "The 0-based index of this menu item."}
-        }
-      },
-      {
-        "id": "RadioButtonDetails",
-        "type": "object",
-        "description": "Information about the state of a radio button.",
-        "properties": {
-          "isChecked": {"type": "boolean", "description": "True if this radio button is checked."},
-          "itemCount": {"type": "integer", "description": "The number of radio buttons in this group."},
-          "itemIndex": {"type": "integer", "description": "The 0-based index of this radio button in this group."}
-        }
-      },
-      {
-        "id": "SliderDetails",
-        "type": "object",
-        "description": "Information about the state of a slider.",
-        "properties": {
-          "stringValue": {"type": "string", "description": "The value of the slider as a string."}
-        }
-      },
-      {
-        "id": "TabDetails",
-        "type": "object",
-        "description": "Additional accessibility information about a tab.",
-        "properties": {
-          "itemCount": {"type": "integer", "description": "The number of tabs in this group."},
-          "itemIndex": {"type": "integer", "description": "The 0-based index of this tab in this group."}
-        }
-      },
-      {
-        "id": "TextBoxDetails",
-        "type": "object",
-        "description": "Information about the state of a text box.",
-        "properties": {
-          "value": {"type": "string", "description": "The value of the text box - the entered text."},
-          "isPassword": {"type": "boolean", "description": "True if this control contains password text whose contents should be obscured."},
-          "selectionStart": {"type": "integer", "description": "The index of the character where the selection starts, if this control contains editable text."},
-          "selectionEnd": {"type": "integer", "description": "The index of the character where the selection ends, if this control contains editable text."}
-        }
-      },
-      {
-        "id": "TreeDetails",
-        "type": "object",
-        "description": "Information about the state of a tree control.",
-        "properties": {
-        }
-      },
-      {
-        "id": "TreeItemDetails",
-        "type": "object",
-        "description": "Information about a selected tree control item.",
-        "properties": {
-          "itemDepth": {"type": "integer", "description": "The 0-based depth of this tree item."},
-          "itemCount": {"type": "integer", "description": "The number of items in the current depth."},
-          "itemIndex": {"type": "integer", "description": "The 0-based index of this tree item at the current tree depth."},
-          "childrenCount": {"type": "integer", "description": "The number of children of the current tree item."},
-          "isItemExpanded": {"type": "boolean", "description": "True if this if this tree item is expanded."}
-        }
-      },
-      {
-        "id": "AlertInfo",
-        "type": "object",
-        "description": "Information about an alert",
-        "properties": {
-          "message": {
-            "type": "string",
-            "description": "The message the alert is showing."
-          }
-        }
-      },
-      {
-        "id": "AccessibilityObject",
-        "type": "object",
-        "description": "Parent class for accessibility information about an object.",
-        "properties": {
-          "type": {
-            "type": "string",
-            "description": "The type of this object, which determines the contents of 'details'.",
-            "enum": ["alert", "button", "checkbox", "combobox", "link", "menu", "menuitem", "radiobutton", "slider", "tab", "textbox", "tree", "treeitem", "window"]
-          },
-          "name": {
-            "type": "string",
-            "description": "The localized name of the object, like OK or Password. Do not rely on an exact string match because the text will be in the user's language and may change in the future."
-          },
-          "context": {
-            "type": "string",
-            "description": "The localized name of the context for the object, like the name of the surrounding toolbar or group of controls.",
-            "optional": true
-          },
-          "details": {
-            "description": "Other details like the state, depending on the type of object.",
-            "optional": true,
-            "choices": [
-              { "$ref": "CheckboxDetails" },
-              { "$ref": "ComboBoxDetails" },
-              { "$ref": "MenuDetails" },
-              { "$ref": "MenuItemDetails" },
-              { "$ref": "RadioButtonDetails" },
-              { "$ref": "SliderDetails" },
-              { "$ref": "TabDetails" },
-              { "$ref": "TextBoxDetails" },
-              { "$ref": "TreeDetails" },
-              { "$ref": "TreeItemDetails" }
-            ]
-          }
-        }
-      }
-    ],
-    "functions": [
-      {
-        "name": "setAccessibilityEnabled",
-        "type": "function",
-        "description": "Enables or disables the accessibility extension api. This must be set to true before event listeners or getFocusedControl will work.",
-        "parameters": [
-          {
-            "type": "boolean",
-            "name": "enabled",
-            "description": "True if accessibility support should be enabled."
-          }
-        ]
-      },
-      {
-        "name": "setNativeAccessibilityEnabled",
-        "type": "function",
-        "description": "Enables or disables native accessibility support. Once disabled, it is up to the calling extension to provide accessibility for web contents.",
-        "parameters": [
-          {
-            "type": "boolean",
-            "name": "enabled",
-            "description": "True if native accessibility support should be enabled."
-          }
-        ]
-      },
-      {
-        "name": "getFocusedControl",
-        "type": "function",
-        "description": "Gets information about the currently focused control.",
-        "parameters": [
-          {
-            "type": "function",
-            "name": "callback",
-            "parameters": [
-              {
-                "name": "control",
-                "description": "Details of the currently focused control, or null if nothing is focused.",
-                "$ref": "AccessibilityObject",
-                "optional": true
-              }
-            ]
-          }
-        ]
-      },
-      {
-        "name": "getAlertsForTab",
-        "type": "function",
-        "description": "Gets alerts being shown on the given tab.",
-        "parameters": [
-          {
-            "name": "tabId",
-            "type": "integer",
-            "minimum": 0
-          },
-          {
-            "type": "function",
-            "name": "callback",
-            "parameters": [
-              {
-                "name": "alerts",
-                "type": "array",
-                "items": { "$ref": "AlertInfo" },
-                "description": "Alerts being shown on the given tab."
-              }
-            ]
-          }
-        ]
-      }
-    ],
-    "events": [
-      {
-        "name": "onWindowOpened",
-        "type": "function",
-        "description": "Fired when a window is opened.",
-        "parameters": [
-          {
-            "$ref": "AccessibilityObject",
-            "name": "window",
-            "description": "Information about the window that was opened."
-          }
-        ]
-      },
-      {
-        "name": "onWindowClosed",
-        "type": "function",
-        "description": "Fired when a window is closed.",
-        "parameters": [
-          {
-            "$ref": "AccessibilityObject",
-            "name": "window",
-            "description": "Information about the window that was closed."
-          }
-        ]
-      },
-      {
-        "name": "onControlFocused",
-        "type": "function",
-        "description": "Fired when a control is focused.",
-        "parameters": [
-          {
-            "$ref": "AccessibilityObject",
-            "name": "control",
-            "description": "Details of the control that was focused."
-          }
-        ]
-      },
-      {
-        "name": "onControlAction",
-        "type": "function",
-        "description": "Fired when a control's action is taken, like pressing a button or toggling a checkbox.",
-        "parameters": [
-          {
-            "$ref": "AccessibilityObject",
-            "name": "control",
-            "description": "Details of the control whose action was taken."
-          }
-        ]
-      },
-      {
-        "name": "onTextChanged",
-        "type": "function",
-        "description": "Fired when text changes in an editable text control.",
-        "parameters": [
-          {
-            "$ref": "AccessibilityObject",
-            "name": "control",
-            "description": "Details of the control where the text changed."
-          }
-        ]
-      },
-      {
-        "name": "onMenuOpened",
-        "type": "function",
-        "description": "Fired when a menu is opened.",
-        "parameters": [
-          {
-            "$ref": "AccessibilityObject",
-            "name": "menu",
-            "description": "Information about the menu that was opened."
-          }
-        ]
-      },
-      {
-        "name": "onMenuClosed",
-        "type": "function",
-        "description": "Fired when a menu is closed.",
-        "parameters": [
-          {
-            "$ref": "AccessibilityObject",
-            "name": "menu",
-            "description": "Information about the menu that was closed."
-          }
-        ]
-      },
-      {
-        "name": "onChromeVoxLoadStateChanged",
-        "type": "function",
-        "description": "Fired ChromeVox load state changes.",
-        "parameters": [
-          {
-            "type": "boolean",
-            "name": "loading",
-            "description": "True if ChromeVox is loading; false if ChromeVox is unloading."
-          },
-          {
-            "type": "boolean",
-            "name": "makeAnnouncements",
-            "description": "Whether to make introductory announcements."
-          }
-        ]
-      }
-    ]
-  }
-]
diff --git a/chrome/common/extensions/api/file_handlers/file_handlers_parser.cc b/chrome/common/extensions/api/file_handlers/file_handlers_parser.cc
index 8a55ed7..742d505 100644
--- a/chrome/common/extensions/api/file_handlers/file_handlers_parser.cc
+++ b/chrome/common/extensions/api/file_handlers/file_handlers_parser.cc
@@ -116,8 +116,6 @@
     return false;
   }
 
-  DCHECK(extension->is_platform_app());
-
   for (base::DictionaryValue::Iterator iter(*all_handlers); !iter.IsAtEnd();
        iter.Advance()) {
     // A file handler entry is a title and a list of MIME types to handle.
diff --git a/chrome/common/extensions/api/file_system_provider.idl b/chrome/common/extensions/api/file_system_provider.idl
index e10cb8c..f8ed6ba 100644
--- a/chrome/common/extensions/api/file_system_provider.idl
+++ b/chrome/common/extensions/api/file_system_provider.idl
@@ -29,6 +29,21 @@
     IO
   };
 
+  // Represents metadata of a file or a directory.
+  dictionary EntryMetadata {
+    // True if it is a directory.
+    boolean isDirectory;
+
+    // Name of this entry (not full path name).
+    DOMString name;
+
+    // File size in bytes.
+    double size;
+
+    // The last modified time of this entry.
+    [instanceOf=Date] object modificationTime;
+  };
+
   // Callback to receive the result of mount() function.
   // <code>fileSystemID</code> will be a unique ID for the file system just
   // mounted. The ID is used to distinguish multiple file systems mounted
@@ -51,6 +66,15 @@
   // Callback to handle an error raised from the browser.
   [nocompile] callback ErrorCallback = void([instanceOf=DOMError] object error);
 
+  // Success callback for the <code>onGetMetadataRequested</code> event.
+  callback MetadataCallback = void(EntryMetadata metadata);
+
+  // Success callback for the <code>onDirectoryRequested</code> event. If more
+  // entries will be returned, then <code>hasNext</code> must be true, and it
+  // has to be called again with additional entries. If no more entries are
+  // available, then <code>hasNext</code> must be set to false.
+  callback EntriesCallback = void(ResourceEntry[] entries, bool hasNext);
+
   interface Functions {
     // Mounts a file system with the given <code>displayName</code>.
     // <code>displayName</code> will be shown in the left panel of
@@ -67,22 +91,42 @@
     // the providing extension can decide to perform unmounting if not requested
     // (eg. in case of lost connection, or a file error). If there is no file
     // system with the requested id, or unmounting fails, then the
-    // <code>errorCallback</code> will be called.
+    // <code>errorCallback</code> must be called.
     static void unmount(long fileSystemId,
                         UnmountCallback successCallback,
                         [nocompile] ErrorCallback errorCallback);
   };
 
   interface Events {
-    // Raised, when the user requests unmounting of the file system with the
-    // <code>fileSystemId</code> identifier in the Files.app UI. In response,
-    // the <code>unmount</code> API method should be called. If unmounting is
-    // not possible (eg. due to pending operation), then <code>errorCallback
-    // </code> should be called, and <code>unmount</code> should not be called.
+    // Raised when unmounting for the file system with the <code>fileSystemId
+    // </code> identifier is requested. In the response, the <code>unmount
+    // </code> API method should be called together with <code>successCallback
+    // </code>. If unmounting is not possible (eg. due to a pending operation),
+    // then <code>errorCallback</code> must be called.
     [maxListeners=1] static void onUnmountRequested(
         long fileSystemId,
         ProviderSuccessCallback successCallback,
         ProviderErrorCallback errorCallback);
+
+    // Raised when metadata of a file or a directory at <code>entryPath</code>
+    // is requested. The metadata should be returned with the <code>
+    // successCallback</code> call. In case of an error, <code>errorCallback
+    // </code> must be called.
+    [maxListeners=1] static void onGetMetadataRequested(
+        long fileSystemId,
+        DOMString entryPath,
+        MetadataCallback successCallback,
+        ErrorCallback errorCallback);
+
+    // Raised when contents of a directory at <code>directoryPath</code> are
+    // requested. The results should be returned in chunks by calling the <code>
+    // successCallback</code> several times. In case of an error, <code>
+    // errorCallback</code> must be called.
+    [maxListeners=1] static void onReadDirectoryRequested(
+        long fileSystemId,
+        DOMString directoryPath,
+        EntriesCallback successCallback,
+        ErrorCallback errorCallback);
   };
 };
 
diff --git a/chrome/common/extensions/api/file_system_provider_internal.idl b/chrome/common/extensions/api/file_system_provider_internal.idl
index 80757bd..7a80d5b 100644
--- a/chrome/common/extensions/api/file_system_provider_internal.idl
+++ b/chrome/common/extensions/api/file_system_provider_internal.idl
@@ -19,6 +19,35 @@
         long fileSystemId,
         long requestId,
         fileSystemProvider.ProviderError error);
+
+    // Internal. Success callback of the <code>onGetMetadataRequested</code>
+    // event. Must be called if metadata is available.
+    static void getMetadataRequestedSuccess(
+        long fileSystemId,
+        long requestId,
+        fileSystemProvider.EntryMetadata metadata);
+
+    // Internal. Error callback of the <code>onGetMetadataRequested</code>
+    // event. Must be called when obtaining metadata fails.
+    static void getMetadataRequestedError(
+        long fileSystemId,
+        long requestId,
+        fileSystemProvider.ProviderError error);
+
+    // Internal. Success callback of the <code>onReadDirectoryRequested</code>
+    // event. Can be called multiple times per request.
+    static void readDirectoryRequestedSuccess(
+        long fileSystemId,
+        long requestId,
+        fileSystemProvider.EntryMetadata[] entries,
+        boolean hasNext);
+
+    // Internal. Error callback of the <code>onReadDirectoryRequested</code>
+    // event. Must be called when reading a directory fails.
+    static void readDirectoryRequestedError(
+        long fileSystemId,
+        long requestId,
+        fileSystemProvider.ProviderError error);
   };
 };
 
diff --git a/chrome/common/extensions/api/hotword_private.idl b/chrome/common/extensions/api/hotword_private.idl
index 7e1a60b..2a7383f 100644
--- a/chrome/common/extensions/api/hotword_private.idl
+++ b/chrome/common/extensions/api/hotword_private.idl
@@ -28,13 +28,18 @@
     boolean audioLoggingEnabled;
   };
 
+  // The type of the recognized hotword. Right now it only has 'search' but
+  // could be expanded to other types of actions in the future.
+  enum HotwordType { search };
+
   callback GenericDoneCallback = void ();
   callback StatusDetailsCallback = void(StatusDetails result);
 
   interface Functions {
     // Sets the current enabled state of hotword search.
     // True: enable hotword search. False: disable hotword search.
-    static void setEnabled(boolean state, optional GenericDoneCallback callback);
+    static void setEnabled(boolean state,
+                           optional GenericDoneCallback callback);
 
     // Retrieves the current state of hotword search.
     // The result is put into a StatusDetails object.
@@ -42,11 +47,27 @@
 
     // Sets the current enabled state of audio logging in the extension.
     // True: logging enabled. False: no logging.
-    static void setAudioLoggingEnabled(boolean state, optional GenericDoneCallback callback);
+    static void setAudioLoggingEnabled(boolean state,
+                                       optional GenericDoneCallback callback);
+
+    // Sets the current state of the browser-requested hotword session.
+    static void setHotwordSessionState(boolean started,
+                                       optional GenericDoneCallback callback);
+
+    // Notifies that a hotword has been recognized in the browser-requested
+    // hotword session.
+    static void notifyHotwordRecognition(HotwordType type,
+                                         optional GenericDoneCallback callback);
   };
 
   interface Events {
     // Fired when the hotword search enabled preference is changed.
     static void onEnabledChanged();
+
+    // Fired when the browser wants to start a hotword session.
+    static void onHotwordSessionRequested();
+
+    // Fired when the browser wants to stop the requested hotword session.
+    static void onHotwordSessionStopped();
   };
 };
diff --git a/chrome/common/extensions/api/management.json b/chrome/common/extensions/api/management.json
index d394004..d839278 100644
--- a/chrome/common/extensions/api/management.json
+++ b/chrome/common/extensions/api/management.json
@@ -297,6 +297,23 @@
             "parameters": []
           }
         ]
+      },
+      {
+        "name": "createAppShortcut",
+        "description": "Display options to create shortcuts for an app. On Mac, only packaged app shortcuts can be created. Note: This function is only available to Chrome users on the dev channel.",
+        "parameters": [
+          {
+            "name": "id",
+            "type": "string",
+            "description": "This should be the id from an app item of $(ref:management.ExtensionInfo)."
+          },
+          {
+            "name": "callback",
+            "type": "function",
+            "optional": true,
+            "parameters":  []
+          }
+        ]
       }
     ],
     "events": [
diff --git a/chrome/common/extensions/api/manifest_types.json b/chrome/common/extensions/api/manifest_types.json
index 592ca65..94544ec 100644
--- a/chrome/common/extensions/api/manifest_types.json
+++ b/chrome/common/extensions/api/manifest_types.json
@@ -13,32 +13,6 @@
     },
     "types": [
       {
-        "id": "ExternallyConnectable",
-        "type": "object",
-        // Note: description commented out because externally_connectable.html
-        // already describes it, and the repetition looks odd.
-        // "description": "The <code>externally_connectable</code> manifest property declares which extensions, apps, and web pages can connect to your extension via $(ref:runtime.connect) and $(ref:runtime.sendMessage).",
-        "properties": {
-          "ids": {
-            "description": "<p>The IDs of extensions or apps that are allowed to connect. If left empty or unspecified, no extensions or apps can connect.</p><p>The wildcard <code>\"*\"</code> will allow all extensions and apps to connect.</p>",
-            "optional": true,
-            "type": "array",
-            "items": {"type": "string"}
-          },
-          "matches": {
-            "description": "<p>The URL patterns for <em>web pages</em> that are allowed to connect. <em>This does not affect content scripts.</em> If left empty or unspecified, no web pages can connect.</p><p>Patterns cannot include wildcard domains nor subdomains of <a href=\"http://publicsuffix.org/list/\">(effective) top level domains</a>; <code>*://google.com/*</code> and <code>http://*.chromium.org/*</code> are valid, while <code>&lt;all_urls&gt;</code>, <code>http://*/*</code>, <code>*://*.com/*</code>, and even <code>http://*.appspot.com/*</code> are not.</p>",
-            "optional": true,
-            "type": "array",
-            "items": {"type": "string"}
-          },
-          "accepts_tls_channel_id": {
-            "description": "If <code>true</code>, messages sent via $(ref:runtime.connect) or $(ref:runtime.sendMessage) will set $(ref:runtime.MessageSender.tlsChannelId) if those methods request it to be. If <code>false</code>, $(ref:runtime.MessageSender.tlsChannelId) will never be set under any circumstance.",
-            "optional": true,
-            "type": "boolean"
-          }
-        }
-      },
-      {
         "id": "ChromeSettingsOverrides",
         "type": "object",
         "description": "Chrome settings which can be overriden by an extension.",
@@ -203,6 +177,34 @@
             }
           }
         }
+      },
+      {
+        "id": "automation",
+        "description": "This API provides programmatic access to the user interface elements of Chrome. This includes everything in the web view, and optionally Chrome's full user interface.",
+        "choices": [
+          { "type": "boolean",
+            "description": "If true, enables non-interactive access to the automation tree only for the sites for which the extension has a <a href='https://developer.chrome.com/extensions/declare_permissions#host-permissions'>host permission</a> or <a href='https://developer.chrome.com/extensions/declare_permissions#activeTab'>activeTab permission</a>)." },
+          { "type": "object",
+            "properties": {
+              "desktop": {
+                "description": "Whether to request permission to the whole ChromeOS desktop. If granted, this gives the extension access to every aspect of the desktop, and every site and app. If this permission is requested, all other permissions are implicitly included and do not need to be requested separately.",
+                "optional": true,
+                "type": "boolean"
+              },
+              "matches": {
+                "description": "A list of URL patterns for which this extension may request an automation tree. If not specified, automation permission will be granted for the sites for which the extension has a <a href='https://developer.chrome.com/extensions/declare_permissions#host-permissions'>host permission</a> or <a href='https://developer.chrome.com/extensions/declare_permissions#activeTab'>activeTab permission</a>).",
+                "optional": true,
+                "type": "array",
+                "items": { "type": "string" }
+              },
+              "interact": {
+                "description": "Whether the extension is allowed interactive access (true) or read-only access (false; default) to the automation tree.",
+                "optional": true,
+                "type": "boolean"
+              }
+            }
+          }
+        ]
       }
     ]
   }
diff --git a/chrome/common/extensions/api/networking_private.json b/chrome/common/extensions/api/networking_private.json
index 5d3a0ac..b9f66e8 100644
--- a/chrome/common/extensions/api/networking_private.json
+++ b/chrome/common/extensions/api/networking_private.json
@@ -182,7 +182,7 @@
       },
       {
         "name": "getVisibleNetworks",
-        "description": "Gets the list of visible networks, and returns a list of cached, read-only network properties for each.",
+        "description": "Returns a list of visible network objects with the following ONC properties: GUID, Type, Name, ConnectionState, ErrorState, WiFi.Security, WiFi.SignalStrength, Cellular.NetworkTechnology, Cellular.ActivationState, Cellular.RoamingState. Cellular.OutOfCredits",
         "parameters": [
           {
             "name": "type",
diff --git a/chrome/common/extensions/api/runtime.json b/chrome/common/extensions/api/runtime.json
deleted file mode 100644
index 55704f1..0000000
--- a/chrome/common/extensions/api/runtime.json
+++ /dev/null
@@ -1,471 +0,0 @@
-// Copyright (c) 2012 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.
-
-[
-  {
-    "namespace": "runtime",
-    "description": "Use the <code>chrome.runtime</code> API to retrieve the background page, return details about the manifest, and listen for and respond to events in the app or extension lifecycle. You can also use this API to convert the relative path of URLs to fully-qualified URLs.",
-    "types": [
-      {
-        "id": "Port",
-        "type": "object",
-        "nocompile": true,
-        "description": "An object which allows two way communication with other pages.",
-        "properties": {
-          "name": {"type": "string"},
-          "disconnect": { "type": "function" },
-          "onDisconnect": { "$ref": "events.Event" },
-          "onMessage": { "$ref": "events.Event" },
-          "postMessage": {"type": "function"},
-          "sender": {
-            "$ref": "MessageSender",
-            "optional": true,
-            "description": "This property will <b>only</b> be present on ports passed to onConnect/onConnectExternal listeners."
-          }
-        },
-        "additionalProperties": { "type": "any"}
-      },
-      {
-        "id": "MessageSender",
-        "type": "object",
-        "description": "An object containing information about the script context that sent a message or request.",
-        "properties": {
-          "tab": {"$ref": "tabs.Tab", "optional": true, "description": "The $(ref:tabs.Tab) which opened the connection, if any. This property will <strong>only</strong> be present when the connection was opened from a tab (including content scripts), and <strong>only</strong> if the receiver is an extension, not an app."},
-          "id": {"type": "string", "optional": true, "description": "The ID of the extension or app that opened the connection, if any."},
-          "url": {"type": "string", "optional": true, "description": "The URL of the page or frame that opened the connection, if any. This property will <strong>only</strong> be present when the connection was opened from a tab or content script."},
-          "tlsChannelId": {"type": "string", "optional": true, "description": "The TLS channel ID of the web page that opened the connection, if requested by the extension or app, and if available."}
-        }
-      }
-    ],
-    "properties": {
-      "lastError": {
-        "type": "object",
-        "optional": true,
-        "description": "This will be defined during an API method callback if there was an error",
-        "properties": {
-          "message": {
-            "optional": true,
-            "type": "string",
-            "description": "Details about the error which occurred."
-          }
-        }
-      },
-      "id": {
-        "type": "string",
-        "description": "The ID of the extension/app."
-      }
-    },
-    "functions": [
-      {
-        "name": "getBackgroundPage",
-        "type": "function",
-        "description": "Retrieves the JavaScript 'window' object for the background page running inside the current extension/app. If the background page is an event page, the system will ensure it is loaded before calling the callback. If there is no background page, an error is set.",
-        "parameters": [
-          {
-            "type": "function",
-            "name": "callback",
-            "parameters": [
-              {
-                "name": "backgroundPage",
-                // Note: Only optional because we don't support validation
-                // for custom callbacks.
-                "optional": true,
-                "type": "object",
-                "isInstanceOf": "Window",
-                "additionalProperties": { "type": "any" },
-                "description": "The JavaScript 'window' object for the background page."
-              }
-            ]
-          }
-        ]
-      },
-      {
-        "name": "getManifest",
-        "description": "Returns details about the app or extension from the manifest. The object returned is a serialization of the full <a href=\"manifest.html\">manifest file</a>.",
-        "type": "function",
-        "nocompile": true,
-        "parameters": [],
-        "returns": {
-          "type": "object",
-          "properties": {},
-          "additionalProperties": { "type": "any" },
-          "description": "The manifest details."
-        }
-      },
-      {
-        "name": "getURL",
-        "type": "function",
-        "nocompile": true,
-        "description": "Converts a relative path within an app/extension install directory to a fully-qualified URL.",
-        "parameters": [
-          {
-            "type": "string",
-            "name": "path",
-            "description": "A path to a resource within an app/extension expressed relative to its install directory."
-          }
-        ],
-        "returns": {
-          "type": "string",
-          "description": "The fully-qualified URL to the resource."
-        }
-      },
-      {
-        "name": "setUninstallURL",
-        "type": "function",
-        "description": "Sets the URL to be visited upon uninstallation. This may be used to clean up server-side data, do analytics, and implement surveys. Maximum 255 characters.",
-        "parameters": [
-          {
-            "type": "string",
-            "name": "url",
-            "maxLength": 255
-          }
-        ]
-      },
-      {
-        "name": "reload",
-        "description": "Reloads the app or extension.",
-        "type": "function",
-        "parameters": []
-      },
-      {
-        "name": "requestUpdateCheck",
-        "type": "function",
-        "description": "Requests an update check for this app/extension.",
-        "parameters": [
-          {
-            "type": "function",
-            "name": "callback",
-            "parameters": [
-              {
-                "name": "status",
-                "type": "string",
-                "enum": ["throttled", "no_update", "update_available"],
-                "description": "Result of the update check."
-              },
-              {
-                "name": "details",
-                "type": "object",
-                "optional": true,
-                "properties": {
-                  "version": {
-                    "type": "string",
-                    "description": "The version of the available update."
-                  }
-                },
-                "description": "If an update is available, this contains more information about the available update."
-              }
-            ]
-          }
-        ]
-      },
-      {
-        "name": "restart",
-        "description": "Restart the ChromeOS device when the app runs in kiosk mode. Otherwise, it's no-op.",
-        "type": "function",
-        "parameters": []
-      },
-      {
-        "name": "connect",
-        "type": "function",
-        "nocompile": true,
-        "description": "Attempts to connect to connect listeners within an extension/app (such as the background page), or other extensions/apps. This is useful for content scripts connecting to their extension processes, inter-app/extension communication, and <a href=\"manifest/externally_connectable.html\">web messaging</a>. Note that this does not connect to any listeners in a content script. Extensions may connect to content scripts embedded in tabs via $(ref:tabs.connect).",
-        "parameters": [
-          {"type": "string", "name": "extensionId", "optional": true, "description": "The ID of the extension or app to connect to. If omitted, a connection will be attempted with your own extension. Required if sending messages from a web page for <a href=\"manifest/externally_connectable.html\">web messaging</a>."},
-          {
-            "type": "object",
-            "name": "connectInfo",
-            "properties": {
-              "name": { "type": "string", "optional": true, "description": "Will be passed into onConnect for processes that are listening for the connection event." },
-              "includeTlsChannelId": { "type": "boolean", "optional": true, "description": "Whether the TLS channel ID will be passed into onConnectExternal for processes that are listening for the connection event." }
-            },
-            "optional": true
-          }
-        ],
-        "returns": {
-          "$ref": "Port",
-          "description": "Port through which messages can be sent and received. The port's $(ref:runtime.Port onDisconnect) event is fired if the extension/app does not exist. "
-        }
-      },
-      {
-        "name": "connectNative",
-        "type": "function",
-        "nocompile": true,
-        "description": "Connects to a native application in the host machine.",
-        "parameters": [
-          {
-            "type": "string",
-            "name": "application",
-            "description": "The name of the registered application to connect to."
-          }
-        ],
-        "returns": {
-          "$ref": "Port",
-          "description": "Port through which messages can be sent and received with the application"
-        }
-      },
-      {
-        "name": "sendMessage",
-        "type": "function",
-        "nocompile": true,
-        "allowAmbiguousOptionalArguments": true,
-        "description": "Sends a single message to event listeners within your extension/app or a different extension/app. Similar to $(ref:runtime.connect) but only sends a single message, with an optional response. If sending to your extension, the $(ref:runtime.onMessage) event will be fired in each page, or $(ref:runtime.onMessageExternal), if a different extension. Note that extensions cannot send messages to content scripts using this method. To send messages to content scripts, use $(ref:tabs.sendMessage).",
-        "parameters": [
-          {"type": "string", "name": "extensionId", "optional": true, "description": "The ID of the extension/app to send the message to. If omitted, the message will be sent to your own extension/app. Required if sending messages from a web page for <a href=\"manifest/externally_connectable.html\">web messaging</a>."},
-          { "type": "any", "name": "message" },
-          {
-            "type": "object",
-            "name": "options",
-            "properties": {
-              "includeTlsChannelId": { "type": "boolean", "optional": true, "description": "Whether the TLS channel ID will be passed into onMessageExternal for processes that are listening for the connection event." }
-            },
-            "optional": true
-          },
-          {
-            "type": "function",
-            "name": "responseCallback",
-            "optional": true,
-            "parameters": [
-              {
-                "name": "response",
-                "type": "any",
-                "description": "The JSON response object sent by the handler of the message. If an error occurs while connecting to the extension, the callback will be called with no arguments and $(ref:runtime.lastError) will be set to the error message."
-              }
-            ]
-          }
-        ]
-      },
-      {
-        "name": "sendNativeMessage",
-        "type": "function",
-        "nocompile": true,
-        "description": "Send a single message to a native application.",
-        "parameters": [
-          {
-            "name": "application",
-            "description": "The name of the native messaging host.",
-            "type": "string"
-          },
-          {
-            "name": "message",
-            "description": "The message that will be passed to the native messaging host.",
-            "type": "object",
-            "additionalProperties": {
-              "type": "any"
-            }
-          },
-          {
-            "type": "function",
-            "name": "responseCallback",
-            "optional": true,
-            "parameters": [
-              {
-                "name": "response",
-                "type": "any",
-                "description": "The response message sent by the native messaging host. If an error occurs while connecting to the native messaging host, the callback will be called with no arguments and $(ref:runtime.lastError) will be set to the error message.",
-                "additionalProperties": {
-                  "type": "any"
-                }
-              }
-            ]
-          }
-        ]
-      },
-      {
-        "name": "getPlatformInfo",
-        "type": "function",
-        "description": "Returns information about the current platform.",
-        "parameters": [
-          {
-            "type": "function",
-            "name": "callback",
-            "description": "Called with results",
-            "parameters": [
-              {
-                "name": "platformInfo",
-                "type": "object",
-                "properties": {
-                  "os": {
-                    "type": "string",
-                    "description": "The operating system chrome is running on.",
-                    "enum": ["mac", "win", "android", "cros", "linux", "openbsd"]
-                  },
-                  "arch": {
-                    "type": "string",
-                    "enum": ["arm", "x86-32", "x86-64"],
-                    "description": "The machine's processor architecture."
-                  },
-                  "nacl_arch" : {
-                    "description": "The native client architecture. This may be different from arch on some platforms.",
-                    "type": "string",
-                    "enum": ["arm", "x86-32", "x86-64"]
-                  }
-                }
-              }
-            ]
-          }
-        ]
-      },
-      {
-        "name": "getPackageDirectoryEntry",
-        "type": "function",
-        "description": "Returns a DirectoryEntry for the package directory.",
-        "parameters": [
-          {
-            "type": "function",
-            "name": "callback",
-            "parameters": [
-              {
-                "name": "directoryEntry",
-                "type": "object",
-                "additionalProperties": { "type": "any" },
-                "isInstanceOf": "DirectoryEntry"
-              }
-            ]
-          }
-        ]
-      }
-    ],
-    "events": [
-      {
-        "name": "onStartup",
-        "type": "function",
-        "description": "Fired when a profile that has this extension installed first starts up. This event is not fired when an incognito profile is started, even if this extension is operating in 'split' incognito mode."
-      },
-      {
-        "name": "onInstalled",
-        "type": "function",
-        "description": "Fired when the extension is first installed, when the extension is updated to a new version, and when Chrome is updated to a new version.",
-        "parameters": [
-          {
-            "type": "object",
-            "name": "details",
-            "properties": {
-              "reason": {
-                "type": "string",
-                "enum": ["install", "update", "chrome_update"],
-                "description": "The reason that this event is being dispatched."
-              },
-              "previousVersion": {
-                "type": "string",
-                "optional": true,
-                "description": "Indicates the previous version of the extension, which has just been updated. This is present only if 'reason' is 'update'."
-              }
-            }
-          }
-        ]
-      },
-      {
-        "name": "onSuspend",
-        "type": "function",
-        "description": "Sent to the event page just before it is unloaded. This gives the extension opportunity to do some clean up. Note that since the page is unloading, any asynchronous operations started while handling this event are not guaranteed to complete. If more activity for the event page occurs before it gets unloaded the onSuspendCanceled event will be sent and the page won't be unloaded. "
-      },
-      {
-        "name": "onSuspendCanceled",
-        "type": "function",
-        "description": "Sent after onSuspend to indicate that the app won't be unloaded after all."
-      },
-      {
-        "name": "onUpdateAvailable",
-        "type": "function",
-        "description": "Fired when an update is available, but isn't installed immediately because the app is currently running. If you do nothing, the update will be installed the next time the background page gets unloaded, if you want it to be installed sooner you can explicitly call chrome.runtime.reload().",
-        "parameters": [
-          {
-            "type": "object",
-            "name": "details",
-            "properties": {
-              "version": {
-                "type": "string",
-                "description": "The version number of the available update."
-              }
-            },
-            "additionalProperties": { "type": "any" },
-            "description": "The manifest details of the available update."
-          }
-        ]
-      },
-      {
-        // TODO(xiyuan): onBrowserUpdateAvailable is deprecated in favor of
-        // onRestartRequired. We should remove it when we are sure it is unused.
-        "name": "onBrowserUpdateAvailable",
-        "type": "function",
-        "description": "Fired when a Chrome update is available, but isn't installed immediately because a browser restart is required.",
-        "deprecated": "Please use $(ref:runtime.onRestartRequired).",
-        "parameters": []
-      },
-      {
-        "name": "onConnect",
-        "type": "function",
-        "nocompile": true,
-        "options": {
-          "unmanaged": true
-        },
-        "description": "Fired when a connection is made from either an extension process or a content script.",
-        "parameters": [
-          {"$ref": "Port", "name": "port"}
-        ]
-      },
-      {
-        "name": "onConnectExternal",
-        "type": "function",
-        "nocompile": true,
-        "options": {
-          "unmanaged": true
-        },
-        "description": "Fired when a connection is made from another extension.",
-        "parameters": [
-          {"$ref": "Port", "name": "port"}
-        ]
-      },
-      {
-        "name": "onMessage",
-        "type": "function",
-        "options": {
-          "unmanaged": true
-        },
-        "description": "Fired when a message is sent from either an extension process or a content script.",
-        "parameters": [
-          {"name": "message", "type": "any", "optional": true, "description": "The message sent by the calling script."},
-          {"name": "sender", "$ref": "MessageSender" },
-          {"name": "sendResponse", "type": "function", "description": "Function to call (at most once) when you have a response. The argument should be any JSON-ifiable object. If you have more than one <code>onMessage</code> listener in the same document, then only one may send a response. This function becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until <code>sendResponse</code> is called)." }
-        ],
-        "returns": {
-          "type": "boolean",
-          "optional": true,
-          "description": "Return true from the event listener if you wish to call <code>sendResponse</code> after the event listener returns."
-        }
-      },
-      {
-        "name": "onMessageExternal",
-        "type": "function",
-        "options": {
-          "unmanaged": true
-        },
-        "description": "Fired when a message is sent from another extension/app. Cannot be used in a content script.",
-        "parameters": [
-          {"name": "message", "type": "any", "optional": true, "description": "The message sent by the calling script."},
-          {"name": "sender", "$ref": "MessageSender" },
-          {"name": "sendResponse", "type": "function", "description": "Function to call (at most once) when you have a response. The argument should be any JSON-ifiable object. If you have more than one <code>onMessage</code> listener in the same document, then only one may send a response. This function becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until <code>sendResponse</code> is called)." }
-        ],
-        "returns": {
-          "type": "boolean",
-          "optional": true,
-          "description": "Return true from the event listener if you wish to call <code>sendResponse</code> after the event listener returns."
-        }
-      },
-      {
-        "name": "onRestartRequired",
-        "type": "function",
-        "description": "Fired when an app or the device that it runs on needs to be restarted. The app should close all its windows at its earliest convenient time to let the restart to happen. If the app does nothing, a restart will be enforced after a 24-hour grace period has passed. Currently, this event is only fired for Chrome OS kiosk apps.",
-        "parameters": [
-          {
-            "type": "string",
-            "name": "reason",
-            "description": "The reason that the event is being dispatched. 'app_update' is used when the restart is needed because the application is updated to a newer version. 'os_update' is used when the restart is needed because the browser/OS is updated to a newer version. 'periodic' is used when the system runs for more than the permitted uptime set in the enterprise policy.",
-            "enum": ["app_update", "os_update", "periodic"]
-          }
-        ]
-      }
-    ]
-  }
-]
diff --git a/chrome/common/extensions/api/screenlock_private.idl b/chrome/common/extensions/api/screenlock_private.idl
index 25953a4..2fecef7 100644
--- a/chrome/common/extensions/api/screenlock_private.idl
+++ b/chrome/common/extensions/api/screenlock_private.idl
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 // Control and monitor the screen locker.
-[platforms=("chromeos"), implemented_in="chrome/browser/chromeos/extensions/screenlock_private_api.h", permissions=screenlockPrivate]
+[permissions=screenlockPrivate, nodoc]
 namespace screenlockPrivate {
   // Supported authentication types shown on the user pod.
   // |offlinePassword|: The standard password field, which authenticates using
diff --git a/chrome/common/extensions/api/system_indicator/system_indicator_handler.cc b/chrome/common/extensions/api/system_indicator/system_indicator_handler.cc
index f3fcdf0..6ce19dc 100644
--- a/chrome/common/extensions/api/system_indicator/system_indicator_handler.cc
+++ b/chrome/common/extensions/api/system_indicator/system_indicator_handler.cc
@@ -10,8 +10,6 @@
 #include "chrome/common/extensions/api/extension_action/action_info.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/manifest_constants.h"
-#include "extensions/common/permissions/api_permission_set.h"
-#include "extensions/common/permissions/permissions_data.h"
 
 namespace extensions {
 
@@ -36,11 +34,6 @@
   if (!action_info.get())
     return false;
 
-  // Because the manifest was successfully parsed, auto-grant the permission.
-  // TODO(dewittj) Add this for all extension action APIs.
-  PermissionsData::GetInitialAPIPermissions(extension)->insert(
-      APIPermission::kSystemIndicator);
-
   ActionInfo::SetSystemIndicatorInfo(extension, action_info.release());
   return true;
 }
diff --git a/chrome/common/extensions/api/usb.idl b/chrome/common/extensions/api/usb.idl
deleted file mode 100644
index 6b6b74c..0000000
--- a/chrome/common/extensions/api/usb.idl
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Use the <code>chrome.usb</code> API to interact with connected USB
-// devices. This API provides access to USB operations from within the context
-// of an app. Using this API, apps can function as drivers for hardware devices.
-namespace usb {
-
-  // Direction, Recipient, RequestType, and TransferType all map to their
-  // namesakes within the USB specification.
-  enum Direction {in, out};
-  enum Recipient {device, _interface, endpoint, other};
-  enum RequestType {standard, class, vendor, reserved};
-  enum TransferType {control, interrupt, isochronous, bulk};
-
-  // For isochronous mode, SynchronizationType and UsageType map to their
-  // namesakes within the USB specification.
-  enum SynchronizationType {asynchronous, adaptive, synchronous};
-  enum UsageType {data, feedback, explicitFeedback};
-
-  // Returned by |getDevices| to identify a connected USB device.
-  dictionary Device {
-    // The id of the USB device. It remains unchanged until the device is
-    // unplugged.
-    long device;
-    long vendorId;
-    long productId;
-  };
-
-  // Returned by |openDevice| to be used for USB communication.
-  // Every time a device is opened, a new connection handle is created.
-  //
-  // A connection handle represents the underlying data structure that contains
-  // all the data we need to communicate with a USB device, including the status
-  // of interfaces, the pending transfers, the descriptors, and etc. A connectin
-  // handle id is different from a USB device id.
-  //
-  // All connection handles can work together if the device allows it.
-  // The connection handle will be automatically closed when the app is reloaded
-  // or suspended.
-  //
-  // When a connection handle is closed, all the interfaces it claimed will be
-  // released and all the transfers in progress will be canceled immediately.
-  dictionary ConnectionHandle {
-    // The id of the USB connection handle.
-    long handle;
-    long vendorId;
-    long productId;
-  };
-
-  dictionary EndpointDescriptor {
-    long address;
-    TransferType type;
-    Direction direction;
-    long maximumPacketSize;
-
-    // Used for isochronous mode.
-    SynchronizationType? synchronization;
-    UsageType? usage;
-
-    // If this is an interrupt endpoint, this will be 1-255.
-    long? pollingInterval;
-  };
-
-  dictionary InterfaceDescriptor {
-    long interfaceNumber;
-    long alternateSetting;
-    long interfaceClass;
-    long interfaceSubclass;
-    long interfaceProtocol;
-    DOMString? description;
-    EndpointDescriptor[] endpoints;
-  };
-
-  // ControlTransferInfo represents that parameters to a single USB control
-  // transfer.
-  dictionary ControlTransferInfo {
-    // The direction of this transfer.
-    Direction direction;
-
-    // The intended recipient for this transfer.
-    Recipient recipient;
-
-    // The type of this request.
-    RequestType requestType;
-
-    long request;
-    long value;
-    long index;
-
-    // If this transfer is an input transfer, then this field must be set to
-    // indicate the expected data length. If this is an output transfer, then
-    // this field is ignored.
-    long? length;
-
-    // The data payload carried by this transfer. If this is an output transfer
-    // then this field must be set.
-    ArrayBuffer? data;
-  };
-
-  // GenericTransferInfo is used by both bulk and interrupt transfers to
-  // specify the parameters of the transfer.
-  dictionary GenericTransferInfo {
-    // The direction of this transfer.
-    Direction direction;
-
-    long endpoint;
-
-    // If this is an input transfer then this field indicates the size of the
-    // input buffer. If this is an output transfer then this field is ignored.
-    long? length;
-
-    // If this is an output transfer then this field must be populated.
-    // Otherwise, it will be ignored.
-    ArrayBuffer? data;
-  };
-
-  // IsochronousTransferInfo describes a single multi-packet isochronous
-  // transfer.
-  dictionary IsochronousTransferInfo {
-    // All of the normal transfer parameters are encapsulated in the
-    // transferInfo parameters. Note that the data specified in this parameter
-    // block is split along packetLength boundaries to form the individual
-    // packets of the transfer.
-    GenericTransferInfo transferInfo;
-
-    // The total number of packets in this transfer.
-    long packets;
-
-    // The length of each of the packets in this transfer.
-    long packetLength;
-  };
-
-  dictionary TransferResultInfo {
-    // A value of 0 indicates that the transfer was a success. Other values
-    // indicate failure.
-    long? resultCode;
-
-    // If the transfer was an input transfer then this field will contain all
-    // of the input data requested.
-    ArrayBuffer? data;
-  };
-
-  // Describes the properties of devices which are found via |getDevices|.
-  dictionary EnumerateDevicesOptions {
-    long vendorId;
-    long productId;
-  };
-  
-  // Describes the properties of devices which are found via |findDevices|.
-  dictionary EnumerateDevicesAndRequestAccessOptions {
-    long vendorId;
-    long productId;
-    // The interface id to request access against.
-    // Only available on ChromeOS. It has no effect on other platforms.
-    long? interfaceId;
-  };
-
-  callback VoidCallback = void ();
-  callback GetDevicesCallback = void (Device[] devices);
-  callback RequestAccessCallback = void (boolean sucess);
-  callback OpenDeviceCallback = void (ConnectionHandle handle);
-  callback FindDevicesCallback = void (ConnectionHandle[] handles);
-  callback ListInterfacesCallback = void (InterfaceDescriptor[] descriptors);
-  callback CloseDeviceCallback = void ();
-  callback TransferCallback = void (TransferResultInfo info);
-  callback ResetDeviceCallback = void(boolean result);
-
-  interface Functions {
-    // Lists USB devices specified by vendorId/productId/interfaceId tuple.
-    // |options|: The properties to search for on target devices.
-    // |callback|: Invoked with a list of |Device|s on complete.
-    static void getDevices(EnumerateDevicesOptions options,
-                           GetDevicesCallback callback);
-
-    // This method is ChromeOS specific. Calling this method on other platforms
-    // will fail.
-    // Requests access from the permission broker to an OS claimed device if the
-    // given interface on the device is not claimed.
-    //
-    // |device|: The device to request access to.
-    // |interfaceId|: 
-    static void requestAccess(Device device,
-                              long interfaceId,
-                              RequestAccessCallback callback);
-
-    // Opens a USB device returned by |getDevices|.
-    // |device|: The device to open.
-    // |callback|: Invoked with the created ConnectionHandle on complete.
-    static void openDevice(Device device, OpenDeviceCallback callback);
-
-    // Finds USB devices specified by the vendorId/productId/interfaceId tuple
-    // and, if permissions allow, opens them for use.
-    //
-    // On Chrome OS, you can specify the interfaceId. In that case the method
-    // will request access from permission broker in the same way as in
-    // |requestUsbAcess|.
-    //
-    // If the access request is rejected, or the device is failed to be opened,
-    // its connection handle will not be created or returned.
-    //
-    // Calling this method is equivalent to calling |getDevices| followed by
-    // a series of |requestAccess| (if it is on ChromeOs) and |openDevice|
-    // calls, and returning all the successfully opened connection handles.
-    //
-    // |options|: The properties to search for on target devices.
-    // |callback|: Invoked with the opened ConnectionHandle on complete.
-    static void findDevices(EnumerateDevicesAndRequestAccessOptions options,
-                            FindDevicesCallback callback);
-
-    // Closes a connection handle. Invoking operations on a device after it
-    // has been closed is a safe operation, but causes no action to be taken.
-    // |handle|: The connection handle to close.
-    // |callback|: The callback to invoke once the device is closed.
-    static void closeDevice(ConnectionHandle handle,
-                            optional CloseDeviceCallback callback);
-
-    // Lists all the interfaces on the USB device.
-    // |handle|: The device from which the interfaces should be listed.
-    // |callback|: The callback to invoke when the interfaces are enumerated.
-    static void listInterfaces(ConnectionHandle handle,
-                               ListInterfacesCallback callback);
-
-    // Claims an interface on the specified USB device.
-    // Before you can transfer data with endpoints, you must claim their parent
-    // interfaces. Only one connection handle on the same host can claim each
-    // interface. If the interface is already claimed, this call will fail.
-    //
-    // You shall call releaseInterface when the interface is not needed anymore.
-    //
-    // |handle|: The device on which the interface is to be claimed.
-    // |interface|: The interface number to be claimed.
-    // |callback|: The callback to invoke once the interface is claimed.
-    static void claimInterface(ConnectionHandle handle, long interfaceNumber,
-                               VoidCallback callback);
-
-    // Releases a claim to an interface on the provided device.
-    // |handle|: The device on which the interface is to be released.
-    // |interface|: The interface number to be released.
-    // |callback|: The callback to invoke once the interface is released.
-    static void releaseInterface(ConnectionHandle handle, long interfaceNumber,
-                                 VoidCallback callback);
-
-    // Selects an alternate setting on a previously claimed interface on a
-    // device.
-    // |handle|: The device on which the interface settings are to be set.
-    // |interface|: The interface number to be set.
-    // |alternateSetting|: The alternate setting to set.
-    // |callback|: The callback to invoke once the interface setting is set.
-    static void setInterfaceAlternateSetting(ConnectionHandle handle,
-                                             long interfaceNumber,
-                                             long alternateSetting,
-                                             VoidCallback callback);
-
-    // Performs a control transfer on the specified device. See the
-    // ControlTransferInfo structure for the parameters required to make a
-    // transfer.
-    //
-    // Conceptually control transfer talks to the device itself. You do not need
-    // to claim interface 0 to perform a control transfer.
-    //
-    // |handle|: A connection handle to make the transfer on.
-    // |transferInfo|: The parameters to the transfer. See ControlTransferInfo.
-    // |callback|: Invoked once the transfer has completed.
-    static void controlTransfer(ConnectionHandle handle,
-                                ControlTransferInfo transferInfo,
-                                TransferCallback callback);
-
-    // Performs a bulk transfer on the specified device.
-    // |handle|: A connection handle to make the transfer on.
-    // |transferInfo|: The parameters to the transfer. See GenericTransferInfo.
-    // |callback|: Invoked once the transfer has completed.
-    static void bulkTransfer(ConnectionHandle handle,
-                             GenericTransferInfo transferInfo,
-                             TransferCallback callback);
-
-    // Performs an interrupt transfer on the specified device.
-    // |handle|: A connection handle to make the transfer on.
-    // |transferInfo|: The parameters to the transfer. See GenericTransferInfo.
-    // |callback|: Invoked once the transfer has completed.
-    static void interruptTransfer(ConnectionHandle handle,
-                                  GenericTransferInfo transferInfo,
-                                  TransferCallback callback);
-
-    // Performs an isochronous transfer on the specific device.
-    // |handle|: A connection handle to make the transfer on.
-    // |transferInfo|: The parameters to the transfer. See
-    // IsochronousTransferInfo.
-    // |callback|: Invoked once the transfer has been completed.
-    static void isochronousTransfer(ConnectionHandle handle,
-                                    IsochronousTransferInfo transferInfo,
-                                    TransferCallback callback);
-
-    // Tries to reset the USB device and restores it to the previous status.
-    // If the reset fails, the given connection handle will be closed and the 
-    // USB device will appear to be disconnected then reconnected. 
-    // In that case you must call |getDevices| or |findDevices| again to acquire
-    // the device.
-    //
-    // |handle|: A connection handle to reset.
-    // |callback|: Invoked once the device is reset with a boolean indicating
-    // whether the reset is completed successfully.
-    static void resetDevice(ConnectionHandle handle,
-                            ResetDeviceCallback callback);
-  };
-};
diff --git a/chrome/common/extensions/api/webrtc_logging_private.idl b/chrome/common/extensions/api/webrtc_logging_private.idl
index b07aed4..db4c947 100644
--- a/chrome/common/extensions/api/webrtc_logging_private.idl
+++ b/chrome/common/extensions/api/webrtc_logging_private.idl
@@ -57,7 +57,8 @@
                      DOMString securityOrigin,
                      GenericDoneCallback callback);
 
-    // Uploads the log. Logging must be stopped before this function is called.
+    // Uploads the log and the RTP dumps, if they exist. Logging and RTP dumping
+    // must be stopped before this function is called.
     static void upload(long tabId,
                        DOMString securityOrigin,
                        UploadDoneCallback callback);
@@ -66,5 +67,22 @@
     static void discard(long tabId,
                         DOMString securityOrigin,
                         GenericDoneCallback callback);
+
+    // Starts RTP dumping. If it has already been started for this render
+    // process, the call will be ignored.
+    static void startRtpDump(long tabId,
+                             DOMString securityOrigin,
+                             boolean incoming,
+                             boolean outgoing,
+                             GenericDoneCallback callback);
+
+    // Stops RTP dumping. After stop has finished, the dumps will be
+    // uploaded with the log if upload is called. Otherwise, the dumps will be
+    // discarded.
+    static void stopRtpDump(long tabId,
+                            DOMString securityOrigin,
+                            boolean incoming,
+                            boolean outgoing,
+                            GenericDoneCallback callback);
   };
 };
diff --git a/chrome/common/extensions/api/webstore_private.json b/chrome/common/extensions/api/webstore_private.json
index 34eda36..c5187e3 100644
--- a/chrome/common/extensions/api/webstore_private.json
+++ b/chrome/common/extensions/api/webstore_private.json
@@ -265,7 +265,7 @@
           {
             "name": "callback",
             "type": "function",
-            "description": "Called if the user is already signed in or if the sign-in method was invoked incorrectly (e.g. with an invalid continue URL), sign-in is unavailable (e.g. in Incognito), or the API was not called in response to a user gesture. Upon such a failure, chrome.runtime.lastError will be set to 'invalid_continue_url', 'signin_is_disallowed', 'signin_failed', 'merge_session_failed', or 'user_getsure_required'.",
+            "description": "Called if the user is already signed in or if the sign-in method was invoked incorrectly (e.g. with an invalid continue URL), sign-in is unavailable (e.g. in Incognito), or the API was not called in response to a user gesture. Upon such a failure, chrome.runtime.lastError will be set to 'invalid_continue_url', 'signin_is_disallowed', 'signin_failed', 'merge_session_failed', or 'user_gesture_required'.",
             "optional": true,
             "parameters": []
           }
diff --git a/chrome/common/extensions/api/webview.json b/chrome/common/extensions/api/webview.json
index e274343..1e279b9 100644
--- a/chrome/common/extensions/api/webview.json
+++ b/chrome/common/extensions/api/webview.json
@@ -46,6 +46,22 @@
         }
       },
       {
+        "id": "ContextMenuItem",
+        "type": "object",
+        "description": "An item in the context menu.",
+        "properties": {
+          "label": {
+            "type": "string",
+            "description": "label of the item",
+            "optional": true
+          },
+          "commandId": {
+            "type": "integer",
+            "description": "id of the input item"
+          }
+        }
+      },
+      {
         "id": "RemovalOptions",
         "type": "object",
         "description": "Options that determine exactly what data will be removed.",
@@ -630,6 +646,29 @@
         ]
       },
       {
+        "name": "showContextMenu",
+        "type": "function",
+        "parameters": [
+          {
+            "type": "integer",
+            "name": "instanceId",
+            "description": "The instance ID of the guest &lt;webview&gt; process. This not exposed to developers through the API."
+          },
+          {
+            "type": "integer",
+            "name": "requestId",
+            "description": "The strictly increasing request counter that serves as ID for the context menu. This not exposed to developers through the API."
+          },
+          {
+            "type": "array",
+            "name": "itemsToShow",
+            "items": {"$ref": "ContextMenuItem"},
+            "description": "Items to be shown in the context menu. These are top level items as opposed to children items.",
+            "optional": true
+          }
+        ]
+      },
+      {
         "name": "stop",
         "type": "function",
         "parameters": [
diff --git a/chrome/common/extensions/chrome_extensions_client.cc b/chrome/common/extensions/chrome_extensions_client.cc
index 3e91859..b1cf2eb 100644
--- a/chrome/common/extensions/chrome_extensions_client.cc
+++ b/chrome/common/extensions/chrome_extensions_client.cc
@@ -27,6 +27,7 @@
 #include "extensions/common/manifest_handler.h"
 #include "extensions/common/permissions/api_permission_set.h"
 #include "extensions/common/permissions/permission_message.h"
+#include "extensions/common/permissions/permissions_info.h"
 #include "extensions/common/switches.h"
 #include "extensions/common/url_pattern.h"
 #include "extensions/common/url_pattern_set.h"
@@ -56,7 +57,8 @@
     LAZY_INSTANCE_INITIALIZER;
 
 ChromeExtensionsClient::ChromeExtensionsClient()
-    :  chrome_api_permissions_(ChromeAPIPermissions()) {
+    : chrome_api_permissions_(ChromeAPIPermissions()),
+      extensions_api_permissions_(ExtensionsAPIPermissions()) {
 }
 
 ChromeExtensionsClient::~ChromeExtensionsClient() {
@@ -71,6 +73,10 @@
     ManifestHandler::FinalizeRegistration();
   }
 
+  // Set up permissions.
+  PermissionsInfo::GetInstance()->AddProvider(chrome_api_permissions_);
+  PermissionsInfo::GetInstance()->AddProvider(extensions_api_permissions_);
+
   // Set up the scripting whitelist.
   // Whitelist ChromeVox, an accessibility extension from Google that needs
   // the ability to script webui pages. This is temporary and is not
@@ -86,11 +92,6 @@
   scripting_whitelist_.push_back("angkfkebojeancgemegoedelbnjgcgme");
 }
 
-const PermissionsProvider&
-ChromeExtensionsClient::GetPermissionsProvider() const {
-  return chrome_api_permissions_;
-}
-
 const PermissionMessageProvider&
 ChromeExtensionsClient::GetPermissionMessageProvider() const {
   return permission_message_provider_;
diff --git a/chrome/common/extensions/chrome_extensions_client.h b/chrome/common/extensions/chrome_extensions_client.h
index d11c26f..39a10a9 100644
--- a/chrome/common/extensions/chrome_extensions_client.h
+++ b/chrome/common/extensions/chrome_extensions_client.h
@@ -11,6 +11,7 @@
 #include "chrome/common/extensions/permissions/chrome_api_permissions.h"
 #include "chrome/common/extensions/permissions/chrome_permission_message_provider.h"
 #include "extensions/common/extensions_client.h"
+#include "extensions/common/permissions/extensions_api_permissions.h"
 
 namespace extensions {
 
@@ -23,7 +24,6 @@
 
   virtual void Initialize() OVERRIDE;
 
-  virtual const PermissionsProvider& GetPermissionsProvider() const OVERRIDE;
   virtual const PermissionMessageProvider& GetPermissionMessageProvider() const
       OVERRIDE;
   virtual scoped_ptr<FeatureProvider> CreateFeatureProvider(
@@ -50,6 +50,7 @@
 
  private:
   const ChromeAPIPermissions chrome_api_permissions_;
+  const ExtensionsAPIPermissions extensions_api_permissions_;
   const ChromePermissionMessageProvider permission_message_provider_;
 
   // A whitelist of extensions that can script anywhere. Do not add to this
diff --git a/chrome/common/extensions/chrome_manifest_handlers.cc b/chrome/common/extensions/chrome_manifest_handlers.cc
index 877756c..136149e 100644
--- a/chrome/common/extensions/chrome_manifest_handlers.cc
+++ b/chrome/common/extensions/chrome_manifest_handlers.cc
@@ -26,16 +26,17 @@
 #include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h"
 #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
+#include "chrome/common/extensions/manifest_handlers/automation.h"
 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
-#include "chrome/common/extensions/manifest_handlers/externally_connectable.h"
+#include "chrome/common/extensions/manifest_handlers/mime_types_handler.h"
 #include "chrome/common/extensions/manifest_handlers/minimum_chrome_version_checker.h"
 #include "chrome/common/extensions/manifest_handlers/nacl_modules_handler.h"
 #include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h"
 #include "chrome/common/extensions/manifest_handlers/theme_handler.h"
 #include "chrome/common/extensions/manifest_handlers/ui_overrides_handler.h"
 #include "chrome/common/extensions/manifest_url_handler.h"
-#include "chrome/common/extensions/mime_types_handler.h"
 #include "extensions/common/api/sockets/sockets_manifest_handler.h"
+#include "extensions/common/manifest_handlers/externally_connectable.h"
 #include "extensions/common/manifest_handlers/icons_handler.h"
 #include "extensions/common/manifest_handlers/requirements_info.h"
 
@@ -46,6 +47,7 @@
 #if defined(ENABLE_EXTENSIONS)
   (new AppIsolationHandler)->Register();
   (new AppLaunchManifestHandler)->Register();
+  (new AutomationHandler)->Register();
   (new BluetoothManifestHandler)->Register();
   (new BrowserActionHandler)->Register();
   (new CommandsHandler)->Register();
diff --git a/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/OAuth.php b/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/OAuth.php
index e9c4bdf..d32db32 100644
--- a/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/OAuth.php
+++ b/chrome/common/extensions/docs/examples/apps/hello-php/lib/oauth/OAuth.php
@@ -827,7 +827,7 @@
       $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
 
       if (isset($parsed_parameters[$parameter])) {
-        // We have already recieved parameter(s) with this name, so add to the list
+        // We have already received parameter(s) with this name, so add to the list
         // of parameters with this name
 
         if (is_scalar($parsed_parameters[$parameter])) {
diff --git a/chrome/common/extensions/docs/server2/app.yaml b/chrome/common/extensions/docs/server2/app.yaml
index d6a5ed2..c1ec6cf 100644
--- a/chrome/common/extensions/docs/server2/app.yaml
+++ b/chrome/common/extensions/docs/server2/app.yaml
@@ -1,5 +1,5 @@
 application: chrome-apps-doc
-version: 3-22-0
+version: 3-22-1
 runtime: python27
 api_version: 1
 threadsafe: false
diff --git a/chrome/common/extensions/docs/server2/cron.yaml b/chrome/common/extensions/docs/server2/cron.yaml
index 7ad3e49..32e1383 100644
--- a/chrome/common/extensions/docs/server2/cron.yaml
+++ b/chrome/common/extensions/docs/server2/cron.yaml
@@ -2,4 +2,4 @@
 - description: Repopulates all cached data.
   url: /_cron
   schedule: every 5 minutes
-  target: 3-22-0
+  target: 3-22-1
diff --git a/chrome/common/extensions/docs/server2/local_file_system.py b/chrome/common/extensions/docs/server2/local_file_system.py
index 8655cfe..7d08594 100644
--- a/chrome/common/extensions/docs/server2/local_file_system.py
+++ b/chrome/common/extensions/docs/server2/local_file_system.py
@@ -69,6 +69,8 @@
   filesystem.
   '''
   def __init__(self, base_path):
+    # Enforce POSIX path, so path validity checks pass for Windows.
+    base_path = base_path.replace(os.sep, '/')
     AssertIsDirectory(base_path)
     self._base_path = _ConvertToFilepath(base_path)
 
diff --git a/chrome/common/extensions/docs/server2/path_canonicalizer.py b/chrome/common/extensions/docs/server2/path_canonicalizer.py
index 03a22f5..04ad9be 100644
--- a/chrome/common/extensions/docs/server2/path_canonicalizer.py
+++ b/chrome/common/extensions/docs/server2/path_canonicalizer.py
@@ -16,6 +16,10 @@
   normalized = normalized.replace('.', '').replace('-', '').replace('_', '')
   return normalized.lower()
 
+def _CommonNormalizedPrefix(first_file, second_file):
+  return posixpath.commonprefix((_Normalize(first_file),
+                                 _Normalize(second_file)))
+
 
 class PathCanonicalizer(object):
   '''Transforms paths into their canonical forms. Since the docserver has had
@@ -105,10 +109,9 @@
     # compared without symbols, not the simplified form of |path|,
     # which may matter.
     max_prefix = potential_paths[0]
-    max_prefix_length = len(posixpath.commonprefix((max_prefix, path)))
+    max_prefix_length = len(_CommonNormalizedPrefix(max_prefix, path))
     for path_for_file in potential_paths[1:]:
-      prefix_length = len(posixpath.commonprefix((path_for_file,
-          _Normalize(path))))
+      prefix_length = len(_CommonNormalizedPrefix(path_for_file, path))
       if prefix_length > max_prefix_length:
         max_prefix, max_prefix_length = path_for_file, prefix_length
 
diff --git a/chrome/common/extensions/docs/server2/path_canonicalizer_test.py b/chrome/common/extensions/docs/server2/path_canonicalizer_test.py
index 99414fc..395298f 100755
--- a/chrome/common/extensions/docs/server2/path_canonicalizer_test.py
+++ b/chrome/common/extensions/docs/server2/path_canonicalizer_test.py
@@ -6,8 +6,9 @@
 import posixpath
 import unittest
 
-from extensions_paths import PUBLIC_TEMPLATES
+from extensions_paths import PUBLIC_TEMPLATES, SERVER2
 from local_file_system import LocalFileSystem
+from test_file_system import TestFileSystem
 from object_store_creator import ObjectStoreCreator
 from path_canonicalizer import PathCanonicalizer
 from special_paths import SITE_VERIFICATION_FILE
@@ -116,6 +117,27 @@
     self._AssertRedirect('extensions/devtools_inspectedWindow',
                          'extensions/devtools.inspectedWindow')
 
+  def testUnderscoreSeparated(self):
+    file_system = TestFileSystem({
+      'pepper_dev': {
+        'c': {
+          'index.html': ''
+        }
+      },
+      'pepper_stable': {
+        'c': {
+          'index.html': ''
+        }
+      }
+    })
+    self._path_canonicalizer = PathCanonicalizer(
+        file_system,
+        ObjectStoreCreator.ForTest(),
+        ('.html', '.md'))
+    self._AssertIdentity('pepper_stable/c/index')
+    self._AssertRedirect('pepper_stable/c/index',
+                         'pepper_stable/c/index.html')
+
   def _AssertIdentity(self, path):
     self._AssertRedirect(path, path)
 
diff --git a/chrome/common/extensions/docs/static/css/out/site.css b/chrome/common/extensions/docs/static/css/out/site.css
index 08d82fd..22ef75f 100644
--- a/chrome/common/extensions/docs/static/css/out/site.css
+++ b/chrome/common/extensions/docs/static/css/out/site.css
@@ -1,4 +1,4 @@
 /*! 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.
- */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}button,input,select,textarea{font-family:sans-serif}body{margin:0}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}p,pre{margin:1.5em 0}blockquote{margin:1.5em 40px}h1{font-size:2em;line-height:1.5em;margin-top:0.75em;margin-bottom:0.75em}h2{font-size:1.5em;line-height:2em;margin-top:1em;margin-bottom:1em}h3{font-size:1.17em;line-height:1.28205em;margin-top:1.28205em;margin-bottom:1.28205em}h4{font-size:1em;line-height:1.5em;margin-top:1.5em;margin-bottom:1.5em}h5{font-size:0.83em;line-height:1.80723em;margin-top:1.80723em;margin-bottom:1.80723em}h6{font-size:0.67em;line-height:2.23881em;margin-top:2.23881em;margin-bottom:2.23881em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace, serif;_font-family:'courier new', monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}dl,menu,ol,ul{margin:1.5em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{margin:0 2px;border-color:#c0c0c0;border-top-style:solid;border-top-width:0.0625em;padding-top:0.4625em;border-bottom-style:solid;border-bottom-width:0.0625em;padding-bottom:0.9125em;border-left-style:solid;border-left-width:0.0625em;padding-left:0.875em;border-right-style:solid;border-right-width:0.0625em;padding-right:0.875em}legend{border:0;padding:0;*margin-left:-7px}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}* html{font-size:100%}html{font-size:16px;line-height:1.5em}* html{font-size:100%}html{font-size:16px;line-height:1.5em}.g-section:after{content:".";display:block;height:0;clear:both;visibility:hidden}.g-unit .g-section:after{clear:none}.g-unit .g-section{width:100%;overflow:hidden}.g-section,.g-unit{zoom:1}.g-split>.g-unit{float:right;text-align:right}.g-split>.g-first{float:left;text-align:left}.g-tpl-160 .g-unit,.g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-unit{display:block;margin:0 0 0 160px;width:auto;float:none}.g-tpl-160 .g-first,.g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-first{display:block;margin:0;width:160px;float:left}.g-tpl-25-75 .g-unit,.g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit{width:74.999%;float:right;display:inline;margin:0}.g-tpl-25-75 .g-first,.g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-first{width:24.999%;float:left;display:inline;margin:0}.g-tpl-75-25 .g-unit,.g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit{width:24.999%;float:right;display:inline;margin:0}.g-tpl-75-25 .g-first,.g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-first{width:74.999%;float:left;display:inline;margin:0}.g-tpl-33-67 .g-unit,.g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit{width:66.999%;float:right;display:inline;margin:0}.g-tpl-33-67 .g-first,.g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-first{width:32.999%;float:left;display:inline;margin:0}.g-tpl-67-33 .g-unit,.g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit{width:32.999%;float:right;display:inline;margin:0}.g-tpl-67-33 .g-first,.g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-first{width:66.999%;float:left;display:inline;margin:0}.g-tpl-50-50 .g-unit,.g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit{width:49.999%;float:right;display:inline;margin:0}.g-tpl-50-50 .g-first,.g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-first{width:49.999%;float:left;display:inline;margin:0}.g-tpl-nest .g-unit{float:left;width:auto;display:inline;margin:0}.g-tpl-nest-alt .g-unit{float:right;width:auto;display:inline;margin:0}.g-content{margin-right:30px}.g-last .g-content{margin-right:0}@media only screen and (max-width: 580px){.g-unit.g-unit{float:none !important}.g-content{margin-right:0}}*{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html,body{overflow-x:hidden;overflow-y:auto}img{max-width:100%}#gc-container{max-width:870px;margin:auto;width:90%}#gc-pagecontent>.g-section{margin:40px 0}main{margin-bottom:50px;position:relative}footer[role="contentinfo"]{padding:40px 0 50px}@media only screen and (max-width: 580px){#gc-container{width:auto}#gc-pagecontent{margin:auto;width:90%}#gc-pagecontent>.g-section{margin:20px 0}footer[role="contentinfo"]{padding:20px 30px}}@media only screen and (min-width: 581px) and (max-width: 990px){#gc-container{width:95%}}figure{margin:20px 0}figure img{border:1px solid #dbdbdb}table{width:100%;border-collapse:collapse;margin:2em 0;line-height:1.5em}table caption{margin-bottom:1em;text-align:left;font-weight:bold}th{border:1px solid #dbdbdb;font-weight:bold;background:#e8e8e8}tr{border-bottom:1px solid #dbdbdb}table+tr{border-top:1px solid #dbdbdb}td,th{padding:1em 1.5em;text-align:left;border:1px solid #dbdbdb}pre{background-color:#f7f7f7;box-shadow:0 2px 4px rgba(0,0,0,0.15),0 0 3px rgba(0,0,0,0.15);margin:1em 0 0 0;overflow:auto;padding:.99em;position:relative}pre a{text-decoration:underline !important}pre b{background:yellow}.element-invisible{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px 1px 1px 1px);clip:rect(1px, 1px, 1px, 1px)}.hidden{display:none}.label{color:inherit;text-transform:uppercase;margin-bottom:5px;font-size:11.2px;font-weight:bold}.published{font-size:11.2px;font-style:italic;color:#bebebe;line-height:16.8px}.description{margin:20px 0}.description:last-child{margin-bottom:0}.span-full{background:#f5f5f5;position:relative;padding:3em 0}.span-full::before,.span-full::after{content:'';height:100%;width:100%;top:0;position:absolute;background:#f5f5f5;z-index:-1}.span-full::before{left:-100%}.span-full::after{left:100%}.button{background:#0370ea;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #008dfd), color-stop(100%, #0370ea));background-image:-webkit-linear-gradient(top, #008dfd 0%,#0370ea 100%);background-image:-moz-linear-gradient(top, #008dfd 0%,#0370ea 100%);background-image:-o-linear-gradient(top, #008dfd 0%,#0370ea 100%);background-image:linear-gradient(top, #008dfd 0%,#0370ea 100%);border:1px solid #076bd2;border-radius:3px;color:#fff !important;display:inline-block;font-size:13px;font-weight:700;line-height:1.3;padding:5px 20px;text-align:center;text-decoration:none !important;text-shadow:1px 1px 1px #076bd2}.button:hover{background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(30%, #008dfd), color-stop(100%, #0370ea));background-image:-webkit-linear-gradient(top, #008dfd 30%,#0370ea 100%);background-image:-moz-linear-gradient(top, #008dfd 30%,#0370ea 100%);background-image:-o-linear-gradient(top, #008dfd 30%,#0370ea 100%);background-image:linear-gradient(top, #008dfd 30%,#0370ea 100%);cursor:pointer}.button a{color:inherit !important}.button-alt{background:#eee;background-image:-webkit-gradient(linear, 50% 100%, 50% 0%, color-stop(46%, #dcdcdc), color-stop(87%, #fafafa));background-image:-webkit-linear-gradient(bottom, #dcdcdc 46%,#fafafa 87%);background-image:-moz-linear-gradient(bottom, #dcdcdc 46%,#fafafa 87%);background-image:-o-linear-gradient(bottom, #dcdcdc 46%,#fafafa 87%);background-image:linear-gradient(bottom, #dcdcdc 46%,#fafafa 87%);border:1px solid #d6d6d6;border-radius:3px;color:#333 !important;display:inline-block;font-size:12px;font-weight:700;line-height:24px;padding:0 15px;text-align:center;text-decoration:none !important;text-shadow:none}.button-alt:hover{background-image:-webkit-gradient(linear, 50% 100%, 50% 0%, color-stop(20%, #dcdcdc), color-stop(87%, #fafafa));background-image:-webkit-linear-gradient(bottom, #dcdcdc 20%,#fafafa 87%);background-image:-moz-linear-gradient(bottom, #dcdcdc 20%,#fafafa 87%);background-image:-o-linear-gradient(bottom, #dcdcdc 20%,#fafafa 87%);background-image:linear-gradient(bottom, #dcdcdc 20%,#fafafa 87%);cursor:pointer}.google-button{background-color:#f5f5f5;border-radius:2px 0 0 0;border:1px solid rgba(0,0,0,0.1);padding:5px 12px;text-align:center;white-space:nowrap}.google-button:hover{border-color:#c6c6c6;-webkit-box-shadow:0 -1px 1px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 1px rgba(0,0,0,0.1);box-shadow:0 -1px 1px rgba(0,0,0,0.1)}.google-button:active{background-color:#f1f1f1;-webkit-box-shadow:inset 0 0px 2px rgba(0,0,0,0.2);-moz-box-shadow:inset 0 0px 2px rgba(0,0,0,0.2);box-shadow:inset 0 0px 2px rgba(0,0,0,0.2)}.screenshot,.screenshot img{margin:1em 0}p.note,p.caution,p.warning,div.note,div.caution,div.warning,aside.note,aside.caution,aside.warning{background-color:#f5f5f5;border-bottom:1px solid;border-top:1px solid;overflow:hidden;width:85%;margin:auto;padding:1em}p.note,div.note,aside.note{border-color:#36C}p.caution,div.caution,aside.caution{border-color:#FC3}p.warning,div.warning,aside.warning{border-color:#A03}p.warning em,p.warning strong,div.warning em,div.warning strong,aside.warning em,aside.warning strong{color:#A03}.permalink{display:none;margin-left:5px}.has-permalink:hover .permalink{display:initial}.no-permalink .permalink{display:none !important}#gc-footer .links a{margin-right:20px}#gc-footer #cc-info{font-size:11.2px}#social-buttons{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-pack:1;-webkit-justify-content:flex-end;-moz-justify-content:flex-end;-ms-justify-content:flex-end;-o-justify-content:flex-end;justify-content:flex-end;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center}#social-buttons>*{margin-left:10px}#social-buttons img{margin:-4px 0 0 1px}@media only screen and (max-width: 580px){.more-section .g-last .g-content{padding-bottom:0;border:none}.more-section .g-content{border:1px solid #dbdbdb;border-width:0 0 1px 0;padding-bottom:20px;margin-bottom:20px}#gc-footer .links a{display:inline-block}}#scroll-to-top,#send-feedback{border-bottom:none;bottom:0;position:fixed;z-index:5}#scroll-to-top{border-left:0;left:0}#send-feedback{border-right:0;right:0}html{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif;color:#777}body{font-size:13px;color:#777}h1,h2,h3,h4,h5,h6{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif;font-weight:600;color:#000}h1,h2{font-weight:300}h1{font-size:2.625em;line-height:1.14286em}h1+h1{margin-top:0em}h2{font-size:1.875em;line-height:1.6em;margin-top:1.6em;margin-bottom:0em;line-height:1.12em}h3{font-size:1.125em;line-height:1.33333em;margin-top:1.33333em;margin-bottom:0.53333em;line-height:1.12em}h4{font-size:1.1em;line-height:1.36364em;margin-top:0em;margin-bottom:0em}h5{font-size:1em;line-height:1.5em;margin-top:0em;margin-bottom:0em}h6{font-size:1em;line-height:1.5em;margin-top:0em;margin-bottom:0em}p{margin:1.5em 0}p.noindent,p.caption p{text-indent:0}p.caption{text-align:left}.lightbox p.caption{color:#fff}a,a:link,a:visited{color:#39c;font-weight:bold;text-decoration:none;word-wrap:break-word;transition:opacity 0.3s ease 0s}a:hover,a:focus,a:link:hover,a:link:focus,a:visited:hover,a:visited:focus{color:#39f}a.section-anchor{display:block;padding-top:3.33em}footer[role="contentinfo"]{font-size:0.84615385em}footer[role="contentinfo"] a,footer[role="contentinfo"] a:link,footer[role="contentinfo"] a:visited{color:#999;font-weight:normal;font-weight:600;text-decoration:none;word-wrap:break-word}footer[role="contentinfo"] a:hover,footer[role="contentinfo"] a:focus,footer[role="contentinfo"] a:link:hover,footer[role="contentinfo"] a:link:focus,footer[role="contentinfo"] a:visited:hover,footer[role="contentinfo"] a:visited:focus{color:#39f}img{vertical-align:middle}figcaption{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif;color:#aaa}blockquote{margin:0.75em 0.8em}cite{margin:0.75em 0.8em;color:#c3c3c3;font-style:normal}canvas{background:#fff;margin:1.5em 0}.code,code,pre{color:#080;font-family:"Source Code Pro",sans-serif}pre{margin:2em 0;word-wrap:break-word;position:relative}pre[data-filename]::after{content:attr(data-filename);background-color:#aaa;color:#fff;padding:2px 12px;position:absolute;right:0;top:0}pre a{text-decoration:underline}.static-code-container{line-height:1em;clear:both}code,kbd,samp{margin:1.5em 0;line-height:1em}dl,menu,ol,ul,.item-list ul{margin:0.8em 0}ul{padding-left:1.28em}ol{padding-left:1.52em}hr{height:1px;border:0;border-bottom:1px solid #dbdbdb;padding-bottom:-1px;margin:1.5em 0}.capitalize{text-transform:uppercase}[data-list-item]{display:list-item}.uncapitalize::first-letter{text-transform:lowercase}.capitalize::first-letter{text-transform:uppercase}.kbd{background-color:#f7f7f7;border:1px solid #ccc;color:#333;font-size:11px;line-height:1.4;text-shadow:0 1px 0 #fff;font-family:Arial,Helvetica,sans-serif;display:inline-block;padding:0.1em 0.6em;margin:0 0.1em;white-space:nowrap;-webkit-box-shadow:0 1px 0px rgba(0,0,0,0.2),0 0 0 2px #fff inset;-moz-box-shadow:0 1px 0px rgba(0,0,0,0.2),0 0 0 2px #fff inset;box-shadow:0 1px 0px rgba(0,0,0,0.2),0 0 0 2px #fff inset;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}#topnav{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;height:64px;position:relative}#logo{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-o-user-select:none;-ms-user-select:none;user-select:none}#logo a{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;color:#828282;font-size:2em;font-weight:400;letter-spacing:-1px}#logo a img{margin-bottom:-4px;height:40px;width:123px}#logo .collase-icon{display:none;background:url("../../images/burger-icon.png") 50% 100% no-repeat;background-size:cover;width:20px;height:20px}#logo .collase-icon.active{background-position:50% 0}#fatnav{height:100%;display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-pack:1;-webkit-justify-content:flex-end;-moz-justify-content:flex-end;-ms-justify-content:flex-end;-o-justify-content:flex-end;justify-content:flex-end;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;white-space:nowrap}#fatnav li{list-style:none}#fatnav>ul{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;padding:0;margin:0}#fatnav .toplevel{color:#aaa;font-weight:600;text-transform:uppercase;-webkit-user-select:none;-moz-user-select:none;-o-user-select:none;-ms-user-select:none;user-select:none}#fatnav .toplevel::after{content:'';background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPJJREFUeNpiyc/Pn8XAwDATiM8yEAaMQBwBxHxMQMIdiE8D8Vog1sGjyQGqbhkQK4A0PoKaFATEF4F4MRCrImnQBuJtQLwfiI2hYk9AGl2AuB2I/wAxiB8DxNeAeA4QzwXiS0DsCdXwHIj9gHgqSOFPIK4CYksgvgJVwALEyUCcBDWMAeoSkO2bGZAEQeAM1CmtUNth4BkQ+wJxHBC/hwkyoQXALyCuAWILIL4MxIugAbYFI3iNZ54BR4fNtcXo0QEy9B+ywBGtWMzoAAquBWLk6EDXhBIdLNDokINGRwBQAUiiCYhvI0VHN1LIjpjoAAgwAMoSTlKlzAY4AAAAAElFTkSuQmCC) no-repeat;background-size:9px;display:inline-block;height:5px;width:14px;margin-left:10px;margin-bottom:2px}#fatnav .pillar{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;padding:0 20px;cursor:pointer;z-index:1002}#fatnav .expandee{display:none;position:absolute;z-index:1001;left:0;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background-color:#f5f5f5;padding:20px 0;cursor:initial;margin:0}#fatnav .expandee a{font-weight:600;padding:0.5em 0;display:block;color:#828282}#fatnav .expandee a:hover{background-image:-webkit-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:-moz-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:-o-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%)}#fatnav .expandee li{white-space:nowrap}#fatnav .expandee li.submenu{color:#333;font-size:1.1em;font-weight:bold;cursor:pointer;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}#fatnav .expandee li.submenu.active{background-image:-webkit-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:-moz-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:-o-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%)}#fatnav .expandee li.submenu>ul{font-size:0.8em;padding:15px 0 0 0;margin:0}#fatnav .expandee li.submenu .category{border-bottom:1px solid #e8e8e8}#fatnav .expandee li.submenu .category:last-child{border:none}#fatnav .expandee li.submenu .category a{overflow:hidden;text-overflow:ellipsis}#fatnav .expandee li.submenu .category>ul{display:none}#fatnav .expandee li.submenu .category ul{padding:0}#search{display:-webkit-inline-flex;display:-moz-inline-flex;display:-ms-inline-flex;display:-o-inline-flex;display:inline-flex;-webkit-align-self:stretch;-moz-align-self:stretch;-ms-align-self:stretch;-o-align-self:stretch;align-self:stretch;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;width:auto;padding:0 20px;cursor:pointer}#search img{height:16px;width:16px;-webkit-user-select:none;-moz-user-select:none;-o-user-select:none;-ms-user-select:none;user-select:none}#search .expandee{padding:20px}#search .expandee input[type="search"]{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background:url("../../images/search.png") no-repeat 15px 55%;background-size:20px;background-color:white;border:1px solid #dbdbdb;padding:10px 10px 10px 40px;font-size:1.4em;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;font-family:inherit;font-weight:300}@media only screen and (min-width: 580px){#topnav{padding:15px 0 0}#fatnav .pillar.active{background:#f5f5f5 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAyCAMAAABI+VrBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALFQTFRF/////f39/v7+/Pz8+/v7+fn56+vr+vr69PT09vb28/Pz9fX1xcXF9/f3+Pj45+fn8PDwycnJ7+/v6enpzc3N19fX8fHx8vLy7u7u6Ojo7Ozs3Nzc5OTk7e3t4uLi2dnZ39/fxsbG29vb0dHR3d3d4ODg4+Pj6urqyMjI09PT5eXl0NDQ1dXV2NjYysrKx8fH5ubmzs7O3t7exMTE4eHh2tray8vLz8/PzMzM1NTU1tbWhgtdWwAAAOFJREFUeNok0NWSxCAURdFDhCQkMx3tuLe7jP//h829NC+rqIKNAK8hhGEQjmUyrm+ziVTs50O6jkA6b+J3gSCqpWfiGZxL1yKyhbIQEDQLxj7xTYy7SXoCY1RXbwLXy6OgfdevIbYFdulHaBuI7t3SIY5Nbhm4zAdF/Ow5gvTEEaR/W49Ov2eSIvjuW+Y4tdTCXHML+1XI/A7cwmmdM1nHLZwbl+kPPj9lunELq5LuRWy5hUFyC+uKI+hazabgCJpYcws5gsXS5F8qc02i9C9Jn9ejelHoMkJdhrJ5xb8AAwBmihB0TS21nQAAAABJRU5ErkJggg==) no-repeat right 0}#fatnav .pillar.active .toplevel::after{background-position:0% -5px}#fatnav .pillar.active .expandee{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-orient:vertical;-webkit-flex-direction:row;-moz-flex-direction:row;-ms-flex-direction:row;-o-flex-direction:row;flex-direction:row}#fatnav .pillar.active .expandee::after{position:absolute;background-image:-webkit-gradient(linear, 50% 100%, 50% 0%, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(211,211,211,0.5)), color-stop(50%, #d3d3d3), color-stop(75%, rgba(211,211,211,0.5)), color-stop(100%, rgba(255,255,255,0)));background-image:-webkit-linear-gradient(bottom, rgba(255,255,255,0) 0%,rgba(211,211,211,0.5) 25%,#d3d3d3 50%,rgba(211,211,211,0.5) 75%,rgba(255,255,255,0) 100%);background-image:-moz-linear-gradient(bottom, rgba(255,255,255,0) 0%,rgba(211,211,211,0.5) 25%,#d3d3d3 50%,rgba(211,211,211,0.5) 75%,rgba(255,255,255,0) 100%);background-image:-o-linear-gradient(bottom, rgba(255,255,255,0) 0%,rgba(211,211,211,0.5) 25%,#d3d3d3 50%,rgba(211,211,211,0.5) 75%,rgba(255,255,255,0) 100%);background-image:linear-gradient(bottom, rgba(255,255,255,0) 0%,rgba(211,211,211,0.5) 25%,#d3d3d3 50%,rgba(211,211,211,0.5) 75%,rgba(255,255,255,0) 100%);right:0;top:0;content:'';width:1px !important;height:100%}#fatnav .pillar .expandee{min-height:400px;font-size:0.9em;box-shadow:0 3px 4px rgba(0,0,0,0.12);top:64px}#fatnav .pillar .expandee .submenu{padding:0 20px;border-right:1px solid #e8e8e8}#fatnav .pillar .expandee .submenu:last-child{border:none}#search{margin-right:-4px}#search.active{background:#f5f5f5 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAyCAMAAABI+VrBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALFQTFRF/////f39/v7+/Pz8+/v7+fn56+vr+vr69PT09vb28/Pz9fX1xcXF9/f3+Pj45+fn8PDwycnJ7+/v6enpzc3N19fX8fHx8vLy7u7u6Ojo7Ozs3Nzc5OTk7e3t4uLi2dnZ39/fxsbG29vb0dHR3d3d4ODg4+Pj6urqyMjI09PT5eXl0NDQ1dXV2NjYysrKx8fH5ubmzs7O3t7exMTE4eHh2tray8vLz8/PzMzM1NTU1tbWhgtdWwAAAOFJREFUeNok0NWSxCAURdFDhCQkMx3tuLe7jP//h829NC+rqIKNAK8hhGEQjmUyrm+ziVTs50O6jkA6b+J3gSCqpWfiGZxL1yKyhbIQEDQLxj7xTYy7SXoCY1RXbwLXy6OgfdevIbYFdulHaBuI7t3SIY5Nbhm4zAdF/Ow5gvTEEaR/W49Ov2eSIvjuW+Y4tdTCXHML+1XI/A7cwmmdM1nHLZwbl+kPPj9lunELq5LuRWy5hUFyC+uKI+hazabgCJpYcws5gsXS5F8qc02i9C9Jn9ejelHoMkJdhrJ5xb8AAwBmihB0TS21nQAAAABJRU5ErkJggg==) no-repeat right 0}#search.active .expandee{display:block;top:64px}}@media only screen and (max-width: 580px){#topnav{-webkit-box-orient:vertical;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;height:auto}#fatnav{width:100%;max-height:0;overflow:hidden;background:#f5f5f5}#fatnav.active{max-height:5000px}#fatnav>ul{-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;-webkit-box-orient:vertical;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column}#fatnav .toplevel{width:100%;height:50px;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-box-pack:1;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;justify-content:center;display:-webkit-inline-flex;display:-moz-inline-flex;display:-ms-inline-flex;display:-o-inline-flex;display:inline-flex}#fatnav .pillar{-webkit-box-orient:vertical;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;padding:0;border-bottom:1px solid #dbdbdb}#fatnav .pillar.active .expandee{display:initial}#fatnav .expandee{position:relative;padding:0;background-color:rgba(229,229,229,0.7)}#fatnav .expandee li.submenu{padding:10px 15px}#fatnav .expandee li.submenu:not(:last-child){border-color:#ccc}#fatnav .expandee li.submenu>ul{background-color:inherit}#logo{height:50px;width:90%}#logo a{-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}#logo .collase-icon{display:initial}#search{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-box-ordinal-group:-1;-webkit-order:-1;-moz-order:-1;-ms-order:-1;-o-order:-1;order:-1;padding:15px 15px 0 15px}#search img{display:none}#search .expandee{display:block}}#gc-pagecontent .g-section h1,#gc-pagecontent .g-section h2,#gc-pagecontent .g-section h3{margin:0}#upcoming-events .screenshot,#featured .screenshot{margin-top:0}#upcoming-events article{border:1px solid #dbdbdb;border-width:0 0 1px 0;padding:20px 0}#upcoming-events article:first-child{padding-top:0}#upcoming-events article:last-child{padding-bottom:0;border:none}#site-sections{background-color:#f5f5f5;padding:20px;text-align:center}#site-sections h2{padding-top:20px}#site-sections h2::before{display:block;content:'';background:url("../../images/bucket-icons.png") 12px 50% no-repeat;width:100px;height:65px;background-size:cover;margin:auto;margin-bottom:20px}#site-sections h2.multidevice::before{background-position:-91px 50%}#site-sections h2.platform::before{background-position:-194px 50%}#developer-news{margin-top:4em}#developer-news .g-content{margin-right:20px}#developer-news h1{margin-bottom:40px !important}@media only screen and (min-width: 580px){#featured{padding-right:30px;padding-bottom:10px;border:1px solid #dbdbdb;border-width:0 1px 0 0}#featured img{margin-bottom:20px}}.pillar-content h1{font-size:42px}.pillar-content>.g-section{padding:3em 0}.pillar-content>.g-section:not(:last-of-type){border-bottom:1px solid #dbdbdb}.pillar-content>.g-section>h2{font-size:30px;margin-bottom:1.5em !important}.pillar-content .article-list article{position:relative;overflow:hidden;width:100%;padding:1.9em;background-color:#f5f5f5;box-shadow:0 2px 4px rgba(0,0,0,0.15),0 0 3px rgba(0,0,0,0.15);line-height:1.5em;margin-bottom:1.5em}.pillar-content .article-list article.new::after{content:'new';background:#2e82c9;position:absolute;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg);top:-4px;right:-20px;color:white;font-size:0.9em;width:60px;text-align:center;padding-top:8px}.pillar-content .article-list article p{font-weight:300}.pillar-content #further-resources .g-content h2::before{display:inline-block;content:'';background:url("../../images/further-resources-icons.svg") 0 50% no-repeat;width:50px;height:43px;background-size:cover;margin:auto;margin-bottom:5px;vertical-align:middle}.pillar-content #further-resources .g-content h2.school::before{background-position:0 50%}.pillar-content #further-resources .g-content h2.chat::before{background-position:-54px 50%}.pillar-content #further-resources .g-content h2.puzzle::before{background-position:-108px 50%}@media only screen and (max-width: 580px){.pillar-content>.g-section{padding:2em 0}}@media only screen and (min-width: 580px){.pillar-content .article-list{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-flex-wrap:wrap;-moz-flex-wrap:wrap;-ms-flex-wrap:wrap;-o-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:1;-webkit-justify-content:space-between;-moz-justify-content:space-between;-ms-justify-content:space-between;-o-justify-content:space-between;justify-content:space-between;-webkit-box-align:stretch;-webkit-align-items:stretch;-moz-align-items:stretch;-ms-align-items:stretch;-o-align-items:stretch;align-items:stretch}.pillar-content .article-list article{-webkit-box-flex:auto;-webkit-flex:auto;-moz-flex:auto;-ms-flex:auto;-o-flex:auto;flex:auto;margin-right:1.5em;width:45%}.pillar-content .article-list article:nth-child(2n),.pillar-content .article-list article:last-of-type{margin-right:0}}@media only screen and (min-width: 990px){.pillar-content .article-list article{width:30%}.pillar-content .article-list article:nth-child(2n){margin-right:1.5em}.pillar-content .article-list article:nth-child(3n),.pillar-content .article-list article:last-of-type{margin-right:0}}@supports not (flex-wrap: wrap){.pillar-content .article-list{display:block}@media only screen and (min-width: 580px){.pillar-content .article-list article{flex:none;float:left;width:48%}}@media only screen and (min-width: 990px){.pillar-content .article-list article{width:31.8058%}}}.load-more-articles{overflow:hidden;*zoom:1;margin:2em auto 0.3em;text-align:center;width:100%}.load-more-articles a,.load-more-articles a:hover{color:#000;transition:opacity 0.3s ease 0s}.nav-arrow{background-size:48px 48px;background:top center no-repeat;display:inline-block;opacity:0.5;transition:opacity 0.3s ease 0s;padding-top:50px}.nav-arrow:hover{opacity:1}.down-arrow{background-image:url("../../images/down-arrow.png")}.inline-toc{line-height:1.3em}.inline-toc a,.inline-toc a:link,.inline-toc a:visited{color:#aaa;font-weight:normal}.inline-toc a:hover,.inline-toc a:focus,.inline-toc a:link:hover,.inline-toc a:link:focus,.inline-toc a:visited:hover,.inline-toc a:visited:focus{color:#000}.inline-toc li li a,.inline-toc li li a:link,.inline-toc li li a:visited{color:#aaa}.inline-toc li li a:hover,.inline-toc li li a:focus,.inline-toc li li a:link:hover,.inline-toc li li a:link:focus,.inline-toc li li a:visited:hover,.inline-toc li li a:visited:focus{color:#000}.inline-toc a{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;padding:0.5em 0}.inline-toc .related{display:block}.inline-toc .related li a.active{color:#000}.inline-toc #toc{display:none}.inline-toc #toc .toplevel>a{font-weight:bold;color:#000}.inline-toc #toc .toplevel>a.hastoc::after{content:'+';-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;text-align:right}.inline-toc #toc .toplevel.active .toc{display:block}.inline-toc #toc .toplevel.active>a.hastoc::after{content:'-'}.inline-toc .toc{margin:0;padding:0;border-top:1px solid #dbdbdb}.inline-toc .toc .toc{display:none}.inline-toc .toc .toc li{padding-left:1em;border-bottom:1px solid #dbdbdb}#cc-info{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;font-style:italic;font-size:0.8em;color:#848484}#cc-info .cc-logo img{width:90px;height:32px}#cc-info .last-updated{-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}@media only screen and (min-width: 580px){.inline-toc{position:absolute;top:0;left:50%;margin-left:195px;width:240px;overflow:auto;overflow-x:hidden}.inline-toc.sticky{position:fixed}.inline-toc #toc{display:block}.article-content{width:70%;padding-right:5%;border-right:1px solid #f5f5f5}.cc-logo{margin:0 0 0 auto}}@media only screen and (min-width: 581px) and (max-width: 990px){.inline-toc{width:200px;margin-left:165px}}@media only screen and (max-width: 580px){.article-content [itemprop="articleBody"]>.collapsible{height:58px;overflow:hidden}.article-content [itemprop="articleBody"]>.collapsible.active{height:auto}.article-content [itemprop="articleBody"]>.collapsible.active h2::before{content:'-'}.article-content [itemprop="articleBody"]>.collapsible h2{position:relative;margin:0;padding:15px 15px 15px 0;border-top:1px solid #dbdbdb;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.article-content [itemprop="articleBody"]>.collapsible h2::before{position:absolute;right:0;content:'+'}.article-content [itemprop="articleBody"] .related{margin:20px 0}}.api{color:#333;font-size:14px}.api .api-summary td,.api .api-summary th{padding:5px 10px}.api .api-reference .description{margin-left:20px}.api .api-reference table.innerTable{margin:10px 0}.api .api-reference table.innerTable td,.api .api-reference table.innerTable th{padding:5px 10px;border:1px solid #eee}.api .api-reference table.innerTable th{background:none}.api .api-reference table.innerTable p{margin:0}.api .api-reference td,.api .api-reference th{vertical-align:top;border:1px solid #eee}.api .api-reference th{background:#fafafa}.api .api-reference h2{background-color:#e8e8e8;padding:20px;margin-left:-20px;margin-right:-20px}.api .api-reference h3{margin-top:3em}
+ */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}button,input,select,textarea{font-family:sans-serif}body{margin:0}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}p,pre{margin:1.5em 0}blockquote{margin:1.5em 40px}h1{font-size:2em;line-height:1.5em;margin-top:0.75em;margin-bottom:0.75em}h2{font-size:1.5em;line-height:2em;margin-top:1em;margin-bottom:1em}h3{font-size:1.17em;line-height:1.28205em;margin-top:1.28205em;margin-bottom:1.28205em}h4{font-size:1em;line-height:1.5em;margin-top:1.5em;margin-bottom:1.5em}h5{font-size:0.83em;line-height:1.80723em;margin-top:1.80723em;margin-bottom:1.80723em}h6{font-size:0.67em;line-height:2.23881em;margin-top:2.23881em;margin-bottom:2.23881em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace, serif;_font-family:'courier new', monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}dl,menu,ol,ul{margin:1.5em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{margin:0 2px;border-color:#c0c0c0;border-top-style:solid;border-top-width:0.0625em;padding-top:0.4625em;border-bottom-style:solid;border-bottom-width:0.0625em;padding-bottom:0.9125em;border-left-style:solid;border-left-width:0.0625em;padding-left:0.875em;border-right-style:solid;border-right-width:0.0625em;padding-right:0.875em}legend{border:0;padding:0;*margin-left:-7px}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}* html{font-size:100%}html{font-size:16px;line-height:1.5em}* html{font-size:100%}html{font-size:16px;line-height:1.5em}.g-section:after{content:".";display:block;height:0;clear:both;visibility:hidden}.g-unit .g-section:after{clear:none}.g-unit .g-section{width:100%;overflow:hidden}.g-section,.g-unit{zoom:1}.g-split>.g-unit{float:right;text-align:right}.g-split>.g-first{float:left;text-align:left}.g-tpl-160 .g-unit,.g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-unit{display:block;margin:0 0 0 160px;width:auto;float:none}.g-tpl-160 .g-first,.g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-160 .g-first{display:block;margin:0;width:160px;float:left}.g-tpl-25-75 .g-unit,.g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit{width:74.999%;float:right;display:inline;margin:0}.g-tpl-25-75 .g-first,.g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-25-75 .g-first{width:24.999%;float:left;display:inline;margin:0}.g-tpl-75-25 .g-unit,.g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit{width:24.999%;float:right;display:inline;margin:0}.g-tpl-75-25 .g-first,.g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-75-25 .g-first{width:74.999%;float:left;display:inline;margin:0}.g-tpl-33-67 .g-unit,.g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit{width:66.999%;float:right;display:inline;margin:0}.g-tpl-33-67 .g-first,.g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-33-67 .g-first{width:32.999%;float:left;display:inline;margin:0}.g-tpl-67-33 .g-unit,.g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit{width:32.999%;float:right;display:inline;margin:0}.g-tpl-67-33 .g-first,.g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-67-33 .g-first{width:66.999%;float:left;display:inline;margin:0}.g-tpl-50-50 .g-unit,.g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit{width:49.999%;float:right;display:inline;margin:0}.g-tpl-50-50 .g-first,.g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-unit .g-unit .g-unit .g-tpl-50-50 .g-first{width:49.999%;float:left;display:inline;margin:0}.g-tpl-nest .g-unit{float:left;width:auto;display:inline;margin:0}.g-tpl-nest-alt .g-unit{float:right;width:auto;display:inline;margin:0}.g-content{margin-right:30px}.g-last .g-content{margin-right:0}@media only screen and (max-width: 580px){.g-unit.g-unit{float:none !important}.g-content{margin-right:0}}*{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html,body{overflow-x:hidden;overflow-y:auto}img{max-width:100%}#gc-container{max-width:870px;margin:auto;width:90%}#gc-pagecontent>.g-section{margin:40px 0}main{margin-bottom:50px;position:relative}footer[role="contentinfo"]{padding:40px 0 50px}@media only screen and (max-width: 580px){#gc-container{width:auto}#gc-pagecontent{margin:auto;width:90%}#gc-pagecontent>.g-section{margin:20px 0}footer[role="contentinfo"]{padding:20px 30px}}@media only screen and (min-width: 581px) and (max-width: 990px){#gc-container{width:95%}}figure{margin:20px 0}figure img{border:1px solid #dbdbdb}table{width:100%;border-collapse:collapse;margin:2em 0;line-height:1.5em}table caption{margin-bottom:1em;text-align:left;font-weight:bold}th{border:1px solid #dbdbdb;font-weight:bold;background:#e8e8e8}tr{border-bottom:1px solid #dbdbdb}table+tr{border-top:1px solid #dbdbdb}td,th{padding:1em 1.5em;text-align:left;border:1px solid #dbdbdb}pre{background-color:#f7f7f7;box-shadow:0 2px 4px rgba(0,0,0,0.15),0 0 3px rgba(0,0,0,0.15);margin:1em 0 0 0;padding:.99em;position:relative;overflow-x:auto;word-wrap:normal;white-space:pre;font-size:0.95em;line-height:1.8em}pre a{text-decoration:underline !important}pre b{background:yellow;font-weight:normal}pre strike{text-decoration:none;background-image:-webkit-linear-gradient(transparent 7px, #cc1f1f 7px, #cc1f1f 9px, transparent 9px);background-image:-moz-linear-gradient(transparent 7px, #cc1f1f 7px, #cc1f1f 9px, transparent 9px);background-image:-ms-linear-gradient(transparent 7px, #cc1f1f 7px, #cc1f1f 9px, transparent 9px);background-image:-o-linear-gradient(transparent 7px, #cc1f1f 7px, #cc1f1f 9px, transparent 9px);background-image:linear-gradient(transparent 7px,#cc1f1f 7px,#cc1f1f 9px,transparent 9px)}pre[data-filename]::after{visibility:hidden}pre[data-filename]:hover::after{visibility:visible}.element-invisible{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px 1px 1px 1px);clip:rect(1px, 1px, 1px, 1px)}.hidden{display:none}.label{color:inherit;text-transform:uppercase;margin-bottom:5px;font-size:11.2px;font-weight:bold}.published{font-size:11.2px;font-style:italic;color:#bebebe;line-height:16.8px}.description{margin:20px 0}.description:last-child{margin-bottom:0}.span-full{background:#f5f5f5;position:relative;padding:3em 0}.span-full::before,.span-full::after{content:'';height:100%;width:100%;top:0;position:absolute;background:#f5f5f5;z-index:-1}.span-full::before{left:-100%}.span-full::after{left:100%}.button{background:#0370ea;background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #008dfd), color-stop(100%, #0370ea));background-image:-webkit-linear-gradient(top, #008dfd 0%,#0370ea 100%);background-image:-moz-linear-gradient(top, #008dfd 0%,#0370ea 100%);background-image:-o-linear-gradient(top, #008dfd 0%,#0370ea 100%);background-image:linear-gradient(top, #008dfd 0%,#0370ea 100%);border:1px solid #076bd2;border-radius:3px;color:#fff !important;display:inline-block;font-size:13px;font-weight:700;line-height:1.3;padding:5px 20px;text-align:center;text-decoration:none !important;text-shadow:1px 1px 1px #076bd2}.button:hover{background-image:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(30%, #008dfd), color-stop(100%, #0370ea));background-image:-webkit-linear-gradient(top, #008dfd 30%,#0370ea 100%);background-image:-moz-linear-gradient(top, #008dfd 30%,#0370ea 100%);background-image:-o-linear-gradient(top, #008dfd 30%,#0370ea 100%);background-image:linear-gradient(top, #008dfd 30%,#0370ea 100%);cursor:pointer}.button a{color:inherit !important}.button-alt{background:#eee;background-image:-webkit-gradient(linear, 50% 100%, 50% 0%, color-stop(46%, #dcdcdc), color-stop(87%, #fafafa));background-image:-webkit-linear-gradient(bottom, #dcdcdc 46%,#fafafa 87%);background-image:-moz-linear-gradient(bottom, #dcdcdc 46%,#fafafa 87%);background-image:-o-linear-gradient(bottom, #dcdcdc 46%,#fafafa 87%);background-image:linear-gradient(bottom, #dcdcdc 46%,#fafafa 87%);border:1px solid #d6d6d6;border-radius:3px;color:#333 !important;display:inline-block;font-size:12px;font-weight:700;line-height:24px;padding:0 15px;text-align:center;text-decoration:none !important;text-shadow:none}.button-alt:hover{background-image:-webkit-gradient(linear, 50% 100%, 50% 0%, color-stop(20%, #dcdcdc), color-stop(87%, #fafafa));background-image:-webkit-linear-gradient(bottom, #dcdcdc 20%,#fafafa 87%);background-image:-moz-linear-gradient(bottom, #dcdcdc 20%,#fafafa 87%);background-image:-o-linear-gradient(bottom, #dcdcdc 20%,#fafafa 87%);background-image:linear-gradient(bottom, #dcdcdc 20%,#fafafa 87%);cursor:pointer}.google-button{background-color:#f5f5f5;border-radius:2px 0 0 0;border:1px solid rgba(0,0,0,0.1);padding:5px 12px;text-align:center;white-space:nowrap}.google-button:hover{border-color:#c6c6c6;-webkit-box-shadow:0 -1px 1px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 1px rgba(0,0,0,0.1);box-shadow:0 -1px 1px rgba(0,0,0,0.1)}.google-button:active{background-color:#f1f1f1;-webkit-box-shadow:inset 0 0px 2px rgba(0,0,0,0.2);-moz-box-shadow:inset 0 0px 2px rgba(0,0,0,0.2);box-shadow:inset 0 0px 2px rgba(0,0,0,0.2)}.screenshot,.screenshot img{margin:1em 0}p.note,p.caution,p.warning,div.note,div.caution,div.warning,aside.note,aside.caution,aside.warning{background-color:#f5f5f5;border-bottom:1px solid;border-top:1px solid;overflow:hidden;width:85%;margin:auto;padding:1em}p.note,div.note,aside.note{border-color:#36C}p.caution,div.caution,aside.caution{border-color:#FC3}p.warning,div.warning,aside.warning{border-color:#A03}p.warning em,p.warning strong,div.warning em,div.warning strong,aside.warning em,aside.warning strong{color:#A03}.permalink{display:none;margin-left:5px}.has-permalink:hover .permalink{display:initial}.no-permalink .permalink{display:none !important}#gc-footer .links a{margin-right:20px}#gc-footer #cc-info{font-size:11.2px}#social-buttons{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-pack:1;-webkit-justify-content:flex-end;-moz-justify-content:flex-end;-ms-justify-content:flex-end;-o-justify-content:flex-end;justify-content:flex-end;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center}#social-buttons>*{margin-left:10px}#social-buttons img{margin:-4px 0 0 1px}@media only screen and (max-width: 580px){.more-section .g-last .g-content{padding-bottom:0;border:none}.more-section .g-content{border:1px solid #dbdbdb;border-width:0 0 1px 0;padding-bottom:20px;margin-bottom:20px}#gc-footer .links a{display:inline-block}}#scroll-to-top,#send-feedback{border-bottom:none;bottom:0;position:fixed;z-index:5}#scroll-to-top{border-left:0;left:0}#send-feedback{border-right:0;right:0}html{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif;color:#777}body{font-size:13px;color:#777}h1,h2,h3,h4,h5,h6{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif;font-weight:600;color:#000}h1,h2{font-weight:300}h1{font-size:2.625em;line-height:1.14286em}h1+h1{margin-top:0em}h2{font-size:1.875em;line-height:1.6em;margin-top:1.6em;margin-bottom:0em;line-height:1.12em}h3{font-size:1.125em;line-height:1.33333em;margin-top:1.33333em;margin-bottom:0.53333em;line-height:1.12em}h4{font-size:1.1em;line-height:1.36364em;margin-top:0em;margin-bottom:0em}h5{font-size:1em;line-height:1.5em;margin-top:0em;margin-bottom:0em}h6{font-size:1em;line-height:1.5em;margin-top:0em;margin-bottom:0em}p{margin:1.5em 0}p.noindent,p.caption p{text-indent:0}p.caption{text-align:left}.lightbox p.caption{color:#fff}a,a:link,a:visited{color:#39c;font-weight:bold;text-decoration:none;word-wrap:break-word;transition:opacity 0.3s ease 0s}a:hover,a:focus,a:link:hover,a:link:focus,a:visited:hover,a:visited:focus{color:#39f}a.section-anchor{display:block;padding-top:3.33em}footer[role="contentinfo"]{font-size:0.84615385em}footer[role="contentinfo"] a,footer[role="contentinfo"] a:link,footer[role="contentinfo"] a:visited{color:#999;font-weight:normal;font-weight:600;text-decoration:none;word-wrap:break-word}footer[role="contentinfo"] a:hover,footer[role="contentinfo"] a:focus,footer[role="contentinfo"] a:link:hover,footer[role="contentinfo"] a:link:focus,footer[role="contentinfo"] a:visited:hover,footer[role="contentinfo"] a:visited:focus{color:#39f}em{padding-right:2px}img{vertical-align:middle}figcaption{font-family:"Open Sans",Arial,"Lucida Grande",sans-serif;color:#aaa}blockquote{margin:0.75em 0.8em}cite{margin:0.75em 0.8em;color:#c3c3c3;font-style:normal}canvas{background:#fff;margin:1.5em 0}.code,code,pre{color:#080;font-family:"Source Code Pro",sans-serif}a>code{color:#39c}pre{margin:2em 0;word-wrap:break-word;position:relative}pre[data-filename]::after{content:attr(data-filename);background-color:#aaa;color:#fff;padding:2px 12px;position:absolute;right:0;top:0}pre a{text-decoration:underline}.static-code-container{line-height:1em;clear:both}code,kbd,samp{margin:1.5em 0;line-height:1em}dl,menu,ol,ul,.item-list ul{margin:0.8em 0}ul{padding-left:1.28em}ol{padding-left:1.52em}hr{height:1px;border:0;border-bottom:1px solid #dbdbdb;padding-bottom:-1px;margin:1.5em 0}.capitalize{text-transform:uppercase}[data-list-item]{display:list-item}.uncapitalize::first-letter{text-transform:lowercase}.capitalize::first-letter{text-transform:uppercase}.kbd{background-color:#f7f7f7;border:1px solid #ccc;color:#333;font-size:11px;line-height:1.4;text-shadow:0 1px 0 #fff;font-family:Arial,Helvetica,sans-serif;display:inline-block;padding:0.1em 0.6em;margin:0 0.1em;white-space:nowrap;-webkit-box-shadow:0 1px 0px rgba(0,0,0,0.2),0 0 0 2px #fff inset;-moz-box-shadow:0 1px 0px rgba(0,0,0,0.2),0 0 0 2px #fff inset;box-shadow:0 1px 0px rgba(0,0,0,0.2),0 0 0 2px #fff inset;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}#topnav{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;height:64px;position:relative}#logo{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-o-user-select:none;-ms-user-select:none;user-select:none}#logo a{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;color:#828282;font-size:2em;font-weight:400;letter-spacing:-1px}#logo a img{margin-bottom:-4px;height:40px;width:123px}#logo .collase-icon{display:none;background:url("../../images/burger-icon.png") 50% 100% no-repeat;background-size:cover;width:20px;height:20px}#logo .collase-icon.active{background-position:50% 0}#fatnav{height:100%;display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-pack:1;-webkit-justify-content:flex-end;-moz-justify-content:flex-end;-ms-justify-content:flex-end;-o-justify-content:flex-end;justify-content:flex-end;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;white-space:nowrap}#fatnav li{list-style:none}#fatnav>ul{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;padding:0;margin:0}#fatnav .toplevel{color:#aaa;font-weight:600;text-transform:uppercase;-webkit-user-select:none;-moz-user-select:none;-o-user-select:none;-ms-user-select:none;user-select:none}#fatnav .toplevel::after{content:'';background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPJJREFUeNpiyc/Pn8XAwDATiM8yEAaMQBwBxHxMQMIdiE8D8Vog1sGjyQGqbhkQK4A0PoKaFATEF4F4MRCrImnQBuJtQLwfiI2hYk9AGl2AuB2I/wAxiB8DxNeAeA4QzwXiS0DsCdXwHIj9gHgqSOFPIK4CYksgvgJVwALEyUCcBDWMAeoSkO2bGZAEQeAM1CmtUNth4BkQ+wJxHBC/hwkyoQXALyCuAWILIL4MxIugAbYFI3iNZ54BR4fNtcXo0QEy9B+ywBGtWMzoAAquBWLk6EDXhBIdLNDokINGRwBQAUiiCYhvI0VHN1LIjpjoAAgwAMoSTlKlzAY4AAAAAElFTkSuQmCC) no-repeat;background-size:9px;display:inline-block;height:5px;width:14px;margin-left:10px;margin-bottom:2px}#fatnav .pillar{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;padding:0 20px;cursor:pointer;z-index:1002}#fatnav .expandee{display:none;position:absolute;z-index:1001;left:0;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background-color:#f5f5f5;padding:20px 0;cursor:initial;margin:0}#fatnav .expandee a{font-weight:600;padding:0.5em 0;display:block;color:#828282}#fatnav .expandee a:hover{background-image:-webkit-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:-moz-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:-o-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%)}#fatnav .expandee li{white-space:nowrap}#fatnav .expandee li.submenu{color:#333;font-size:1.1em;font-weight:bold;cursor:pointer;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}#fatnav .expandee li.submenu.active{background-image:-webkit-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:-moz-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:-o-linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%);background-image:linear-gradient(205deg, rgba(229,229,229,0.7) 0%,rgba(233,233,233,0.7) 20%,rgba(244,244,244,0.7) 100%)}#fatnav .expandee li.submenu>ul{font-size:0.8em;padding:15px 0 0 0;margin:0}#fatnav .expandee li.submenu .category{border-bottom:1px solid #e8e8e8}#fatnav .expandee li.submenu .category:last-child{border:none}#fatnav .expandee li.submenu .category a{overflow:hidden;text-overflow:ellipsis}#fatnav .expandee li.submenu .category>ul{display:none}#fatnav .expandee li.submenu .category ul{padding:0}#search{display:-webkit-inline-flex;display:-moz-inline-flex;display:-ms-inline-flex;display:-o-inline-flex;display:inline-flex;-webkit-align-self:stretch;-moz-align-self:stretch;-ms-align-self:stretch;-o-align-self:stretch;align-self:stretch;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;width:auto;padding:0 20px;cursor:pointer}#search img{height:16px;width:16px;-webkit-user-select:none;-moz-user-select:none;-o-user-select:none;-ms-user-select:none;user-select:none}#search .expandee{padding:20px}#search .expandee input[type="search"]{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background:url("../../images/search.png") no-repeat 15px 55%;background-size:20px;background-color:white;border:1px solid #dbdbdb;padding:10px 10px 10px 40px;font-size:1.4em;-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;font-family:inherit;font-weight:300}@media only screen and (min-width: 580px){#topnav{padding:15px 0 0}#fatnav .pillar.active{background:#f5f5f5 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAyCAMAAABI+VrBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALFQTFRF/////f39/v7+/Pz8+/v7+fn56+vr+vr69PT09vb28/Pz9fX1xcXF9/f3+Pj45+fn8PDwycnJ7+/v6enpzc3N19fX8fHx8vLy7u7u6Ojo7Ozs3Nzc5OTk7e3t4uLi2dnZ39/fxsbG29vb0dHR3d3d4ODg4+Pj6urqyMjI09PT5eXl0NDQ1dXV2NjYysrKx8fH5ubmzs7O3t7exMTE4eHh2tray8vLz8/PzMzM1NTU1tbWhgtdWwAAAOFJREFUeNok0NWSxCAURdFDhCQkMx3tuLe7jP//h829NC+rqIKNAK8hhGEQjmUyrm+ziVTs50O6jkA6b+J3gSCqpWfiGZxL1yKyhbIQEDQLxj7xTYy7SXoCY1RXbwLXy6OgfdevIbYFdulHaBuI7t3SIY5Nbhm4zAdF/Ow5gvTEEaR/W49Ov2eSIvjuW+Y4tdTCXHML+1XI/A7cwmmdM1nHLZwbl+kPPj9lunELq5LuRWy5hUFyC+uKI+hazabgCJpYcws5gsXS5F8qc02i9C9Jn9ejelHoMkJdhrJ5xb8AAwBmihB0TS21nQAAAABJRU5ErkJggg==) no-repeat right 0}#fatnav .pillar.active .toplevel::after{background-position:0% -5px}#fatnav .pillar.active .expandee{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-orient:vertical;-webkit-flex-direction:row;-moz-flex-direction:row;-ms-flex-direction:row;-o-flex-direction:row;flex-direction:row}#fatnav .pillar.active .expandee::after{position:absolute;background-image:-webkit-gradient(linear, 50% 100%, 50% 0%, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(211,211,211,0.5)), color-stop(50%, #d3d3d3), color-stop(75%, rgba(211,211,211,0.5)), color-stop(100%, rgba(255,255,255,0)));background-image:-webkit-linear-gradient(bottom, rgba(255,255,255,0) 0%,rgba(211,211,211,0.5) 25%,#d3d3d3 50%,rgba(211,211,211,0.5) 75%,rgba(255,255,255,0) 100%);background-image:-moz-linear-gradient(bottom, rgba(255,255,255,0) 0%,rgba(211,211,211,0.5) 25%,#d3d3d3 50%,rgba(211,211,211,0.5) 75%,rgba(255,255,255,0) 100%);background-image:-o-linear-gradient(bottom, rgba(255,255,255,0) 0%,rgba(211,211,211,0.5) 25%,#d3d3d3 50%,rgba(211,211,211,0.5) 75%,rgba(255,255,255,0) 100%);background-image:linear-gradient(bottom, rgba(255,255,255,0) 0%,rgba(211,211,211,0.5) 25%,#d3d3d3 50%,rgba(211,211,211,0.5) 75%,rgba(255,255,255,0) 100%);right:0;top:0;content:'';width:1px !important;height:100%}#fatnav .pillar .expandee{min-height:400px;font-size:0.9em;box-shadow:0 3px 4px rgba(0,0,0,0.12);top:64px}#fatnav .pillar .expandee .submenu{padding:0 20px;border-right:1px solid #e8e8e8}#fatnav .pillar .expandee .submenu:last-child{border:none}#search{margin-right:-4px}#search.active{background:#f5f5f5 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAyCAMAAABI+VrBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALFQTFRF/////f39/v7+/Pz8+/v7+fn56+vr+vr69PT09vb28/Pz9fX1xcXF9/f3+Pj45+fn8PDwycnJ7+/v6enpzc3N19fX8fHx8vLy7u7u6Ojo7Ozs3Nzc5OTk7e3t4uLi2dnZ39/fxsbG29vb0dHR3d3d4ODg4+Pj6urqyMjI09PT5eXl0NDQ1dXV2NjYysrKx8fH5ubmzs7O3t7exMTE4eHh2tray8vLz8/PzMzM1NTU1tbWhgtdWwAAAOFJREFUeNok0NWSxCAURdFDhCQkMx3tuLe7jP//h829NC+rqIKNAK8hhGEQjmUyrm+ziVTs50O6jkA6b+J3gSCqpWfiGZxL1yKyhbIQEDQLxj7xTYy7SXoCY1RXbwLXy6OgfdevIbYFdulHaBuI7t3SIY5Nbhm4zAdF/Ow5gvTEEaR/W49Ov2eSIvjuW+Y4tdTCXHML+1XI/A7cwmmdM1nHLZwbl+kPPj9lunELq5LuRWy5hUFyC+uKI+hazabgCJpYcws5gsXS5F8qc02i9C9Jn9ejelHoMkJdhrJ5xb8AAwBmihB0TS21nQAAAABJRU5ErkJggg==) no-repeat right 0}#search.active .expandee{display:block;top:64px}}@media only screen and (max-width: 580px){#topnav{-webkit-box-orient:vertical;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;height:auto}#fatnav{width:100%;max-height:0;overflow:hidden;background:#f5f5f5}#fatnav.active{max-height:5000px}#fatnav>ul{-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;-webkit-box-orient:vertical;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column}#fatnav .toplevel{width:100%;height:50px;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-box-pack:1;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;justify-content:center;display:-webkit-inline-flex;display:-moz-inline-flex;display:-ms-inline-flex;display:-o-inline-flex;display:inline-flex}#fatnav .pillar{-webkit-box-orient:vertical;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;padding:0;border-bottom:1px solid #dbdbdb}#fatnav .pillar.active .expandee{display:initial}#fatnav .expandee{position:relative;padding:0;background-color:rgba(229,229,229,0.7)}#fatnav .expandee li.submenu{padding:10px 15px}#fatnav .expandee li.submenu:not(:last-child){border-color:#ccc}#fatnav .expandee li.submenu>ul{background-color:inherit}#logo{height:50px;width:90%}#logo a{-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}#logo .collase-icon{display:initial}#search{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;-webkit-box-ordinal-group:-1;-webkit-order:-1;-moz-order:-1;-ms-order:-1;-o-order:-1;order:-1;padding:15px 15px 0 15px}#search img{display:none}#search .expandee{display:block}}#gc-pagecontent .g-section h1,#gc-pagecontent .g-section h2,#gc-pagecontent .g-section h3{margin:0}#upcoming-events .screenshot,#featured .screenshot{margin-top:0}#upcoming-events article{border:1px solid #dbdbdb;border-width:0 0 1px 0;padding:20px 0}#upcoming-events article:first-child{padding-top:0}#upcoming-events article:last-child{padding-bottom:0;border:none}#site-sections{background-color:#f5f5f5;padding:20px;text-align:center}#site-sections h2{padding-top:20px}#site-sections h2::before{display:block;content:'';background:url("../../images/bucket-icons.png") 12px 50% no-repeat;width:100px;height:65px;background-size:cover;margin:auto;margin-bottom:20px}#site-sections h2.multidevice::before{background-position:-91px 50%}#site-sections h2.platform::before{background-position:-194px 50%}#developer-news{margin-top:4em}#developer-news .g-content{margin-right:20px}#developer-news h1{margin-bottom:40px !important}@media only screen and (min-width: 580px){#featured{padding-right:30px;padding-bottom:10px;border:1px solid #dbdbdb;border-width:0 1px 0 0}#featured img{margin-bottom:20px}}.pillar-content h1{font-size:42px}.pillar-content>.g-section{padding:3em 0}.pillar-content>.g-section:not(:last-of-type){border-bottom:1px solid #dbdbdb}.pillar-content>.g-section>h2{font-size:30px;margin-bottom:1.5em !important}.pillar-content .article-list article{position:relative;overflow:hidden;width:100%;padding:1.9em;background-color:#f5f5f5;box-shadow:0 2px 4px rgba(0,0,0,0.15),0 0 3px rgba(0,0,0,0.15);line-height:1.5em;margin-bottom:1.5em}.pillar-content .article-list article.new::after{content:'new';background:#2e82c9;position:absolute;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg);top:-4px;right:-20px;color:white;font-size:0.9em;width:60px;text-align:center;padding-top:8px}.pillar-content .article-list article p{font-weight:300}.pillar-content #further-resources .g-content h2::before{display:inline-block;content:'';background:url("../../images/further-resources-icons.svg") 0 50% no-repeat;width:50px;height:43px;background-size:cover;margin:auto;margin-bottom:5px;vertical-align:middle}.pillar-content #further-resources .g-content h2.school::before{background-position:0 50%}.pillar-content #further-resources .g-content h2.chat::before{background-position:-54px 50%}.pillar-content #further-resources .g-content h2.puzzle::before{background-position:-108px 50%}@media only screen and (max-width: 580px){.pillar-content>.g-section{padding:2em 0}}@media only screen and (min-width: 580px){.pillar-content .article-list{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-flex-wrap:wrap;-moz-flex-wrap:wrap;-ms-flex-wrap:wrap;-o-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:1;-webkit-justify-content:space-between;-moz-justify-content:space-between;-ms-justify-content:space-between;-o-justify-content:space-between;justify-content:space-between;-webkit-box-align:stretch;-webkit-align-items:stretch;-moz-align-items:stretch;-ms-align-items:stretch;-o-align-items:stretch;align-items:stretch}.pillar-content .article-list article{-webkit-box-flex:auto;-webkit-flex:auto;-moz-flex:auto;-ms-flex:auto;-o-flex:auto;flex:auto;margin-right:1.5em;width:45%}.pillar-content .article-list article:nth-child(2n),.pillar-content .article-list article:last-of-type{margin-right:0}}@media only screen and (min-width: 990px){.pillar-content .article-list article{width:30%}.pillar-content .article-list article:nth-child(2n){margin-right:1.5em}.pillar-content .article-list article:nth-child(3n),.pillar-content .article-list article:last-of-type{margin-right:0}}@supports not (flex-wrap: wrap){.pillar-content .article-list{display:block}@media only screen and (min-width: 580px){.pillar-content .article-list article{flex:none;float:left;width:48%}}@media only screen and (min-width: 990px){.pillar-content .article-list article{width:31.8058%}}}.load-more-articles{overflow:hidden;*zoom:1;margin:2em auto 0.3em;text-align:center;width:100%}.load-more-articles a,.load-more-articles a:hover{color:#000;transition:opacity 0.3s ease 0s}.nav-arrow{background-size:48px 48px;background:top center no-repeat;display:inline-block;opacity:0.5;transition:opacity 0.3s ease 0s;padding-top:50px}.nav-arrow:hover{opacity:1}.down-arrow{background-image:url("../../images/down-arrow.png")}.inline-toc{line-height:1.3em}.inline-toc a,.inline-toc a:link,.inline-toc a:visited{color:#aaa;font-weight:normal}.inline-toc a:hover,.inline-toc a:focus,.inline-toc a:link:hover,.inline-toc a:link:focus,.inline-toc a:visited:hover,.inline-toc a:visited:focus{color:#000}.inline-toc li li a,.inline-toc li li a:link,.inline-toc li li a:visited{color:#aaa}.inline-toc li li a:hover,.inline-toc li li a:focus,.inline-toc li li a:link:hover,.inline-toc li li a:link:focus,.inline-toc li li a:visited:hover,.inline-toc li li a:visited:focus{color:#000}.inline-toc a{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;padding:0.5em 0}.inline-toc .related{display:block}.inline-toc .related li a.active{color:#000}.inline-toc #toc{display:none}.inline-toc #toc .toplevel>a{font-weight:bold;color:#000}.inline-toc #toc .toplevel>a.hastoc::after{content:'+';-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;text-align:right}.inline-toc #toc .toplevel.active .toc{display:block}.inline-toc #toc .toplevel.active>a.hastoc::after{content:'-'}.inline-toc .toc{margin:0;padding:0;border-top:1px solid #dbdbdb}.inline-toc .toc .toc{display:none}.inline-toc .toc .toc li{padding-left:1em;border-bottom:1px solid #dbdbdb}#cc-info{display:-webkit-box;display:-webkit-flex;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;align-items:center;font-style:italic;font-size:0.8em;color:#848484}#cc-info .cc-logo img{width:90px;height:32px}#cc-info .last-updated{-webkit-box-flex:1;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}@media only screen and (min-width: 580px){.inline-toc{position:absolute;top:0;left:50%;margin-left:195px;width:240px;overflow:auto;overflow-x:hidden}.inline-toc.sticky{position:fixed}.inline-toc #toc{display:block}.article-content{width:70%;padding-right:5%;border-right:1px solid #f5f5f5}.cc-logo{margin:0 0 0 auto}}@media only screen and (min-width: 581px) and (max-width: 990px){.inline-toc{width:200px;margin-left:165px}}@media only screen and (max-width: 580px){.article-content [itemprop="articleBody"]>.collapsible{height:58px;overflow:hidden}.article-content [itemprop="articleBody"]>.collapsible.active{height:auto}.article-content [itemprop="articleBody"]>.collapsible.active h2::before{content:'-'}.article-content [itemprop="articleBody"]>.collapsible h2{position:relative;margin:0;padding:15px 15px 15px 0;border-top:1px solid #dbdbdb;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.article-content [itemprop="articleBody"]>.collapsible h2::before{position:absolute;right:0;content:'+'}.article-content [itemprop="articleBody"] .related{margin:20px 0}}.api{color:#333;font-size:14px}.api .api-summary td,.api .api-summary th{padding:5px 10px}.api .api-reference .description{margin-left:20px}.api .api-reference table.innerTable{margin:10px 0}.api .api-reference table.innerTable td,.api .api-reference table.innerTable th{padding:5px 10px;border:1px solid #eee}.api .api-reference table.innerTable th{background:none}.api .api-reference table.innerTable p{margin:0}.api .api-reference td,.api .api-reference th{vertical-align:top;border:1px solid #eee}.api .api-reference th{background:#fafafa}.api .api-reference h2{background-color:#e8e8e8;padding:20px;margin-left:-20px;margin-right:-20px}.api .api-reference h3{margin-top:3em}
diff --git a/chrome/common/extensions/docs/static/js/samples.js b/chrome/common/extensions/docs/static/js/samples.js
index 5abd04d..fc33768 100644
--- a/chrome/common/extensions/docs/static/js/samples.js
+++ b/chrome/common/extensions/docs/static/js/samples.js
@@ -5,9 +5,11 @@
 (function() {
   var searchBox = document.getElementById('search_input');
   var samples = document.getElementsByClassName('sample');
+  var SEARCH_PREFIX = 'search:';
 
   function filterSamples() {
     var searchText = searchBox.value.toLowerCase();
+    window.location.hash = SEARCH_PREFIX + encodeURIComponent(searchText);
     for (var i = 0; i < samples.length; ++i) {
       var sample = samples[i];
       var sampleTitle = '';
@@ -20,14 +22,24 @@
         sample.style.display = '';
     }
   }
+  function updateSearchBox(value) {
+    searchBox.value = value;
+    filterSamples();
+  }
   searchBox.addEventListener('search', filterSamples);
   searchBox.addEventListener('keyup', filterSamples);
 
   var apiFilterItems = document.getElementById('api_filter_items');
   apiFilterItems.addEventListener('click', function(event) {
     if (event.target instanceof HTMLAnchorElement) {
-      searchBox.value = event.target.innerText;
-      filterSamples();
+      updateSearchBox(event.target.innerText);
     }
   });
+
+  // If we have a #fragment that corresponds to a search, prefill the search box
+  // with it.
+  var fragment = window.location.hash.substr(1);
+  if (fragment.substr(0, SEARCH_PREFIX.length) == SEARCH_PREFIX) {
+    updateSearchBox(decodeURIComponent(fragment.substr(SEARCH_PREFIX.length)));
+  }
 })();
diff --git a/chrome/common/extensions/docs/static/sass/_html.scss b/chrome/common/extensions/docs/static/sass/_html.scss
index 82918bb..b02259e 100644
--- a/chrome/common/extensions/docs/static/sass/_html.scss
+++ b/chrome/common/extensions/docs/static/sass/_html.scss
@@ -41,14 +41,33 @@
   background-color: #f7f7f7;
   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15), 0 0 3px rgba(0, 0, 0, 0.15);
   margin: 1em 0 0 0;
-  overflow: auto;
   padding: .99em;
   position: relative;
+  overflow-x: auto; 
+  word-wrap: normal; 
+  white-space: pre;
+  font-size: 0.95em;
+  line-height: 1.8em;
   a {
     text-decoration: underline!important;
   }
   b {
     background: yellow;
+    font-weight: normal;
+  }
+  strike {
+    text-decoration: none;
+    background-image: -webkit-linear-gradient(transparent 7px,#cc1f1f 7px,#cc1f1f 9px,transparent 9px);
+    background-image:    -moz-linear-gradient(transparent 7px,#cc1f1f 7px,#cc1f1f 9px,transparent 9px);
+    background-image:     -ms-linear-gradient(transparent 7px,#cc1f1f 7px,#cc1f1f 9px,transparent 9px);
+    background-image:      -o-linear-gradient(transparent 7px,#cc1f1f 7px,#cc1f1f 9px,transparent 9px);
+    background-image:         linear-gradient(transparent 7px,#cc1f1f 7px,#cc1f1f 9px,transparent 9px);
+  }
+  &[data-filename]::after {
+    visibility: hidden;
+  }
+  &[data-filename]:hover::after {
+    visibility: visible;
   }
 }
 
diff --git a/chrome/common/extensions/docs/static/sass/_typography.scss b/chrome/common/extensions/docs/static/sass/_typography.scss
index b225168..ebb7035 100644
--- a/chrome/common/extensions/docs/static/sass/_typography.scss
+++ b/chrome/common/extensions/docs/static/sass/_typography.scss
@@ -114,6 +114,10 @@
   }
 }
 
+em {
+  padding-right: 2px; /* "kerning" adjustment */
+}
+
 img {
   vertical-align: middle;
 }
@@ -148,6 +152,10 @@
   //font-size: $monospace-font-size;
 }
 
+a > code {
+  color: $link-color;
+}
+
 pre {
   margin: 2em 0;
   word-wrap: break-word;
diff --git a/chrome/common/extensions/docs/templates/articles/manifest/externally_connectable.html b/chrome/common/extensions/docs/templates/articles/manifest/externally_connectable.html
index 91bee6d..fe02fa0 100644
--- a/chrome/common/extensions/docs/templates/articles/manifest/externally_connectable.html
+++ b/chrome/common/extensions/docs/templates/articles/manifest/externally_connectable.html
@@ -48,5 +48,5 @@
 
 <h2 id="reference">Reference</h2>
 <p class="api_reference">
-{{+partials.type type:apis.manifestTypes.byName.ExternallyConnectable/}}
+{{+partials.type type:apis.extensionsManifestTypes.byName.ExternallyConnectable/}}
 </p>
diff --git a/chrome/common/extensions/docs/templates/articles/single_purpose.html b/chrome/common/extensions/docs/templates/articles/single_purpose.html
new file mode 100644
index 0000000..bd59826
--- /dev/null
+++ b/chrome/common/extensions/docs/templates/articles/single_purpose.html
@@ -0,0 +1,240 @@
+<h1>Extensions Quality Guidelines FAQ</h1>
+
+<h2 id="one">1.) Why did Google launch a “single purpose” Chrome extensions policy?</h2>
+
+<p>For an overview of the policy announcement, please read this
+<a href="http://blog.chromium.org/2013/12/keeping-chrome-extensions-simple.html">Chromium blog post</a>.</p>
+
+<p>We launched this policy because
+multi-purpose extensions can crowd your browser UI
+and slow down your web browsing - sometimes significantly.
+Speed and simplicity have always been part of Chrome's core principles,
+so this policy will help us get back to the design that was originally intended.
+Also, unexpected changes to browser functionality and
+settings have become the number one user complaint for Chrome users,
+and this policy helps minimize the problem by ensuring
+that users understand what extensions are doing.
+</p>
+
+<h2 id="two">2.) Where can I find the “single purpose” policy?</h2>
+
+<p>
+Please refer to the
+<a href="https://developer.chrome.com/webstore/program_policies?csw=1#extensions">Extensions Quality Guidelines</a>
+section of the Chrome Web Store Developer Program Policies.
+</p>
+
+<h2 id="three">3.) What does “single purpose” actually mean?</h2>
+
+<p>
+“Single purpose” can refer to one of two aspects of an extension: 
+</p>
+
+<p>
+An extension can have a single purpose limited to a narrow
+<strong>focus area or subject matter</strong>
+(for example, news headlines", "weather", "comparison shopping").
+If the extension has a narrow focus area or subject matter,
+then it can offer various functions related
+to that focus area or subject matter.
+For example, a news headlines extension could have a browser action button
+that allows users to see news stories and replace the new tab page
+with news-only content,
+so long as all of those functions are narrowly focused
+on the news headline focus area. 
+</p>
+
+<p>
+Or, an extension can have a single purpose limited
+to a narrow <strong>browser function</strong>
+(for example, "new tab page", "tab management", or "browser history").
+If the extension is implemented in a single function,
+then it can offer content or features related to different areas or subjects.
+For example, an extension that replaces the new tab page could offer
+multiple unrelated features on the new tab page
+(for example, weather forecast, news headlines, search engine, and so on),
+but it can’t also provide a browser action button,
+change the browser’s homepage, or
+make any other changes to browser functionality.
+</p>
+
+<h2 id="four">4.) Will this policy affect my extension?</h2>
+
+<p>
+It depends.
+Particularly if your extension offers multiple features,
+please make sure that it has a single purpose.
+Ask yourself these questions:
+</p>
+
+<ul>
+  <li>Does my extension have a narrow focus area
+  or a narrow function as described above?</li>
+  <li>If my extension has a narrow focus area,
+  are all of the features directly related to that single purpose?</li>
+  <li>If my extension has multiple features,
+  does it only affect a narrow function of the browser?</li>
+  <li>Does my extension modify Chrome’s behavior in a predictable way,
+  in line with the extension's narrow, stated purpose?</li>
+</ul>
+
+<p>
+If you’re unsure, you can email
+<a href="mailto:chromewebstore-policy@google.com">chromewebstore-policy@</a>
+with your extension ID,
+and we’ll take a look and try to provide feedback within a week.
+If your extension does not have a single purpose,
+then you will need to remove functionality
+or split your extension into different extensions. 
+</p>
+
+<h2 id="five">5.) What will happen
+if I don’t make my extension compliant with this policy?</h2>
+
+<p>
+If you created your extension after December 2013,
+your extension will not be permitted in the Chrome Web Store.
+If you created your extension prior to December 2013,
+your item may be removed from the Chrome Web Store starting July 15, 2014.
+You will still be able to update the extension and file appeals.
+Please keep in mind that
+your re-published item will not be immediately published live in the store.
+The re-published item will undergo a compliance review
+before it can be restored.
+</p>
+
+<p>
+In order to minimize disruption for users,
+we recommend that you take a moment to carefully review your extensions
+and make necessary updates as soon as possible.
+You can email us at
+<a href="mailto:chromewebstore-policy@google.com">chromewebstore-policy@</a>
+with your extension ID, and we’ll try to provide feedback within a week.
+</p>
+
+<h2 id="six">6.) Can my extension make changes to the start page,
+homepage, or new tab settings?</h2>
+
+<p>
+Yes.
+If the purpose of your extension is to modify one narrow function of the browser
+(either the start page, homepage or new tab page, for example),
+and it does only that,
+then it would be compliant with the single purpose policy.
+Additionally,
+if the purpose of your extension is limited to one focus area or subject matter,
+then you can have various functions related to that one area or subject matter,
+including changes to start page, homepage or new tab page.
+</p>
+
+<p>
+Please note that your extension will only be able to make changes
+to Chrome settings pursuant to Chrome policies, as applicable.
+Please see this
+<a href="http://blog.chromium.org/2014/03/protecting-user-settings-on-windows.html">Chromium blog post</a>
+for more information.
+</p>
+
+<h2 id="seven">7.) Can my extension make changes to the default search settings?</h2>
+
+<p>
+Yes.
+If the only purpose of the extension is to change the default search settings,
+then it would be compliant with the single purpose policy.
+Additionally,
+if the single purpose of your extension is search as the narrow focus area,
+and nothing else, then you can offer various functions related to search,
+including changes to default search settings.
+</p>
+
+<h2 id="eight">8.) Can I bundle ad injection with some other type of functionality?</h2>
+
+<p>
+No.
+This violates the single purpose policy.
+However, if injecting ads is the single purpose of the extension and
+the extension is otherwise compliant with Chrome policies,
+then it would be acceptable.
+For example, a “related articles” extension that adds sponsored links
+to articles related to a page the user is visiting would be compliant
+with the single purpose policy because it has a single purpose limited
+to a narrow function of the browser.
+You also might want to explore the other monetization options described
+<a href="https://developer.chrome.com/webstore/money">here</a>.
+</p>
+
+<h2 id="nine">9.) Are toolbars permitted under this policy?</h2>
+
+<p>
+It depends on what the toolbar does.
+As described in
+<a href="#three">answer #3</a>,
+it must adhere to the narrow single purpose of the extension.
+Broad, multi-purpose toolbars are not allowed and
+toolbars that are implemented using content scripts
+to inject UI into every page are not recommended because
+they slow down every page load, clutter the UI,
+and can lead to security problems for users.
+Instead, consider using a
+<a href="https://developer.chrome.com/extensions/browserAction">browser action popup</a>,
+which was designed to solve this very problem.
+It's a better user experience, with no performance or security downsides.
+</p>
+
+<h2 id="ten">10.) What will happen to non-compliant extensions
+that were already installed by users?</h2>
+
+<p>
+All extensions will need to comply with the Extension Quality Guidelines.
+If a user installed a non-compliant extension,
+then you will need to update them to a compliant extension
+that is hosted in the Chrome Web Store.
+If the user is not updated to a compliant extension
+that is hosted in the Chrome Web Store,
+then the extension will be automatically disabled.
+You can find more information
+<a href="http://blog.chromium.org/2014/02/make-sure-to-get-your-extension-in.html">here</a>.
+</p>
+
+<h2 id="eleven">11.) If my extension is rejected from the Chrome Web Store
+because it doesn’t comply with the single purpose policy,
+what will happen after the requirement to host extensions
+in the Chrome Web Store comes into effect?</h2>
+
+<p>
+If your extension is rejected from the Chrome Web Store,
+you will need to make changes or appeal the decision.
+After the requirement to host extensions
+in the Chrome Web Store comes into effect,
+your extension must be hosted in the Chrome Web Store or
+it will be automatically disabled from the users’ browsers. 
+</p>
+
+<h2 id="twelve">12.) If my extension gets flagged for review under the single purpose policy,
+what will happen?</h2>
+
+<p>
+Our team will review it,
+and it may be removed from the Chrome Web Store.
+You’ll have a chance to make changes and appeal the decision.
+As noted above,
+if you created your extension before we announced the policy in December 2013,
+you have until July 15, 2014 to make changes.
+If your extension was created after the policy was announced,
+it needs to be compliant now.
+You can temporarily unpublish it and contact us at
+<a href="mailto:chromewebstore-policy@google.com">chromewebstore-policy@</a>
+with your extension ID if you’d like feedback.
+We’ll try to respond within a week.
+</p>
+
+<h2 id="thirteen">13.) I need help. Who should I contact?</h2>
+
+<p>
+You can email
+<a href="mailto:chromewebstore-policy@google.com">chromewebstore-policy@</a>
+with your extension ID,
+and we’ll take a look and try to provide feedback within a week.
+This is a lightweight review intended to give you an indication
+of whether your extension will comply with the new policy.
+</p>
diff --git a/chrome/common/extensions/docs/templates/json/chrome_sidenav.json b/chrome/common/extensions/docs/templates/json/chrome_sidenav.json
index d53b351..c7722af 100644
--- a/chrome/common/extensions/docs/templates/json/chrome_sidenav.json
+++ b/chrome/common/extensions/docs/templates/json/chrome_sidenav.json
@@ -521,6 +521,11 @@
                 "href": "/extensions/hosting_changes"
               },
               {
+                "title": "Extension Quality Guidelines FAQ",
+                "href": "/extensions/single_purpose"
+              },
+
+              {
                 "title": "Event Pages",
                 "href": "/extensions/event_pages"
               },
diff --git a/chrome/common/extensions/docs/templates/private/api_reference.html b/chrome/common/extensions/docs/templates/private/api_reference.html
index 0a3bc65..1da3d78 100644
--- a/chrome/common/extensions/docs/templates/private/api_reference.html
+++ b/chrome/common/extensions/docs/templates/private/api_reference.html
@@ -38,14 +38,14 @@
     {{/api.domEvents}}
   {{/api.domEvents}}
 </div>
-{{?samples_list}}
+{{?samplesForApi}}
   <h2 id="samples">Sample {{platformTitle}}</h2>
   <ul>
-  {{#sample:samples_list}}
+  {{#sample:samplesForApi}}
     <li><strong><a href="samples.html#{{sample.id}}">{{sample.name}}</a></strong>
     {{?sample.description}}
     &ndash; {{sample.description}}
     {{/sample.description}}</li>
-  {{/samples_list}}
+  {{/samplesForApi}}
   </ul>
-{{/samples_list}}
+{{/samplesForApi}}
diff --git a/chrome/common/extensions/docs/templates/public/extensions/single_purpose.html b/chrome/common/extensions/docs/templates/public/extensions/single_purpose.html
new file mode 100644
index 0000000..e251308
--- /dev/null
+++ b/chrome/common/extensions/docs/templates/public/extensions/single_purpose.html
@@ -0,0 +1 @@
+{{+partials.standard_extensions_article article:articles.single_purpose removeToc:true/}}
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc
index 3b5105b..9692cde 100644
--- a/chrome/common/extensions/extension_constants.cc
+++ b/chrome/common/extensions/extension_constants.cc
@@ -133,8 +133,16 @@
 const char kChromeVoxExtensionId[] =
     "mndnfokpggljbaajbnioimlmbfngpief";
 const char kChromeVoxExtensionPath[] = "chromeos/chromevox";
+const char kBrailleImeExtensionId[] =
+    "jddehjeebkoimngcbdkaahpobgicbffp";
+const char kBrailleImeExtensionPath[] =
+    "chromeos/braille_ime";
+const char kBrailleImeEngineId[] =
+    "_comp_ime_jddehjeebkoimngcbdkaahpobgicbffpbraille";
 const char kConnectivityDiagnosticsPath[] =
     "/usr/share/chromeos-assets/connectivity_diagnostics";
+const char kConnectivityDiagnosticsKioskPath[] =
+    "/usr/share/chromeos-assets/connectivity_diagnostics_kiosk";
 const char kConnectivityDiagnosticsLauncherPath[] =
     "/usr/share/chromeos-assets/connectivity_diagnostics_launcher";
 const char kSpeechSynthesisExtensionPath[] =
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h
index 73ea270..9406495 100644
--- a/chrome/common/extensions/extension_constants.h
+++ b/chrome/common/extensions/extension_constants.h
@@ -240,8 +240,14 @@
 // Path to preinstalled ChromeVox screen reader extension (relative to
 // |chrome::DIR_RESOURCES|).
 extern const char kChromeVoxExtensionPath[];
+// Extension id, path (relative to |chrome::DIR_RESOURCES|) and IME engine
+// id for the builtin-in Braille IME extension.
+extern const char kBrailleImeExtensionId[];
+extern const char kBrailleImeExtensionPath[];
+extern const char kBrailleImeEngineId[];
 // Path to preinstalled Connectivity Diagnostics extension.
 extern const char kConnectivityDiagnosticsPath[];
+extern const char kConnectivityDiagnosticsKioskPath[];
 extern const char kConnectivityDiagnosticsLauncherPath[];
 // Path to preinstalled speech synthesis extension.
 extern const char kSpeechSynthesisExtensionPath[];
diff --git a/chrome/common/extensions/manifest_handlers/automation.cc b/chrome/common/extensions/manifest_handlers/automation.cc
new file mode 100644
index 0000000..0338cd6
--- /dev/null
+++ b/chrome/common/extensions/manifest_handlers/automation.cc
@@ -0,0 +1,152 @@
+// 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.
+
+#include "chrome/common/extensions/manifest_handlers/automation.h"
+
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/common/extensions/api/manifest_types.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/manifest_constants.h"
+#include "extensions/common/permissions/api_permission_set.h"
+#include "extensions/common/permissions/permissions_data.h"
+#include "extensions/common/url_pattern.h"
+
+namespace extensions {
+
+namespace automation_errors {
+const char kErrorDesktopTrueInteractFalse[] =
+    "Cannot specify interactive=false if desktop=true is specified; "
+    "interactive=false will be ignored.";
+const char kErrorDesktopTrueMatchesSpecified[] =
+    "Cannot specify matches for Automation if desktop=true is specified; "
+    "matches will be ignored.";
+const char kErrorInvalidMatch[] = "Invalid match pattern '*': *";
+const char kErrorNoMatchesProvided[] = "No valid match patterns provided.";
+}
+
+namespace errors = manifest_errors;
+namespace keys = extensions::manifest_keys;
+using api::manifest_types::Automation;
+
+AutomationHandler::AutomationHandler() {
+}
+
+AutomationHandler::~AutomationHandler() {
+}
+
+bool AutomationHandler::Parse(Extension* extension, base::string16* error) {
+  const base::Value* automation = NULL;
+  CHECK(extension->manifest()->Get(keys::kAutomation, &automation));
+  std::vector<InstallWarning> install_warnings;
+  scoped_ptr<AutomationInfo> info =
+      AutomationInfo::FromValue(*automation, &install_warnings, error);
+  if (!error->empty())
+    return false;
+
+  extension->AddInstallWarnings(install_warnings);
+
+  if (!info)
+    return true;
+
+  extension->SetManifestData(keys::kAutomation, info.release());
+  return true;
+}
+
+const std::vector<std::string> AutomationHandler::Keys() const {
+  return SingleKey(keys::kAutomation);
+}
+
+// static
+const AutomationInfo* AutomationInfo::Get(const Extension* extension) {
+  return static_cast<AutomationInfo*>(
+      extension->GetManifestData(keys::kAutomation));
+}
+
+// static
+scoped_ptr<AutomationInfo> AutomationInfo::FromValue(
+    const base::Value& value,
+    std::vector<InstallWarning>* install_warnings,
+    base::string16* error) {
+  scoped_ptr<Automation> automation = Automation::FromValue(value, error);
+  if (!automation)
+    return scoped_ptr<AutomationInfo>();
+
+  if (automation->as_boolean) {
+    if (*automation->as_boolean)
+      return make_scoped_ptr(new AutomationInfo());
+    return scoped_ptr<AutomationInfo>();
+  }
+  const Automation::Object& automation_object = *automation->as_object;
+
+  bool desktop = false;
+  bool interact = false;
+  if (automation_object.desktop && *automation_object.desktop) {
+    desktop = true;
+    interact = true;
+    if (automation_object.interact && !*automation_object.interact) {
+      // TODO(aboxhall): Do we want to allow this?
+      install_warnings->push_back(
+          InstallWarning(automation_errors::kErrorDesktopTrueInteractFalse));
+    }
+  } else if (automation_object.interact && *automation_object.interact) {
+    interact = true;
+  }
+
+  URLPatternSet matches;
+  bool specified_matches = false;
+  if (automation_object.matches) {
+    if (desktop) {
+      install_warnings->push_back(
+          InstallWarning(automation_errors::kErrorDesktopTrueMatchesSpecified));
+    } else {
+      specified_matches = true;
+      for (std::vector<std::string>::iterator it =
+               automation_object.matches->begin();
+           it != automation_object.matches->end();
+           ++it) {
+        // TODO(aboxhall): Refactor common logic from content_scripts_handler,
+        // manifest_url_handler and user_script.cc into a single location and
+        // re-use here.
+        URLPattern pattern(URLPattern::SCHEME_ALL &
+                           ~URLPattern::SCHEME_CHROMEUI);
+        URLPattern::ParseResult parse_result = pattern.Parse(*it);
+        if (parse_result != URLPattern::PARSE_SUCCESS) {
+          install_warnings->push_back(
+              InstallWarning(ErrorUtils::FormatErrorMessage(
+                  automation_errors::kErrorInvalidMatch,
+                  *it,
+                  URLPattern::GetParseResultString(parse_result))));
+          continue;
+        }
+
+        matches.AddPattern(pattern);
+      }
+    }
+  }
+  if (specified_matches && matches.is_empty())
+    install_warnings->push_back(
+        InstallWarning(automation_errors::kErrorNoMatchesProvided));
+
+  return make_scoped_ptr(
+      new AutomationInfo(desktop, matches, interact, specified_matches));
+}
+
+AutomationInfo::AutomationInfo()
+    : desktop(false), interact(false), specified_matches(false) {
+}
+AutomationInfo::AutomationInfo(bool desktop,
+                               const URLPatternSet& matches,
+                               bool interact,
+                               bool specified_matches)
+    : desktop(desktop),
+      matches(matches),
+      interact(interact),
+      specified_matches(specified_matches) {
+}
+
+AutomationInfo::~AutomationInfo() {
+}
+
+}  // namespace extensions
diff --git a/chrome/common/extensions/manifest_handlers/automation.h b/chrome/common/extensions/manifest_handlers/automation.h
new file mode 100644
index 0000000..3890d59
--- /dev/null
+++ b/chrome/common/extensions/manifest_handlers/automation.h
@@ -0,0 +1,80 @@
+// 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.
+
+#ifndef CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_AUTOMATION_H_
+#define CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_AUTOMATION_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/manifest_handler.h"
+#include "extensions/common/url_pattern_set.h"
+#include "extensions/common/user_script.h"
+
+namespace extensions {
+
+class URLPatternSet;
+
+namespace automation_errors {
+extern const char kErrorInvalidMatchPattern[];
+extern const char kErrorDesktopTrueInteractFalse[];
+extern const char kErrorDesktopTrueMatchesSpecified[];
+extern const char kErrorURLMalformed[];
+extern const char kErrorInvalidMatch[];
+extern const char kErrorNoMatchesProvided[];
+}
+
+// Parses the automation manifest entry.
+class AutomationHandler : public ManifestHandler {
+ public:
+  AutomationHandler();
+  virtual ~AutomationHandler();
+
+  virtual bool Parse(Extension* extensions, base::string16* error) OVERRIDE;
+
+ private:
+  virtual const std::vector<std::string> Keys() const OVERRIDE;
+
+  DISALLOW_COPY_AND_ASSIGN(AutomationHandler);
+};
+
+// The parsed form of the automation manifest entry.
+struct AutomationInfo : public Extension::ManifestData {
+ public:
+  static const AutomationInfo* Get(const Extension* extension);
+  static scoped_ptr<AutomationInfo> FromValue(
+      const base::Value& value,
+      std::vector<InstallWarning>* install_warnings,
+      base::string16* error);
+
+  virtual ~AutomationInfo();
+
+  // true if the extension has requested 'desktop' permission.
+  const bool desktop;
+
+  // Returns the list of hosts that this extension can request an automation
+  // tree from.
+  const URLPatternSet matches;
+
+  // Whether the extension is allowed interactive access (true) or read-only
+  // access (false) to the automation tree.
+  const bool interact;
+
+  // Whether any matches were specified (false if automation was specified as a
+  // boolean, or no matches key was provided.
+  const bool specified_matches;
+
+ private:
+  AutomationInfo();
+  AutomationInfo(bool desktop,
+                 const URLPatternSet& matches,
+                 bool interact,
+                 bool specified_matches);
+  DISALLOW_COPY_AND_ASSIGN(AutomationInfo);
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_AUTOMATION_H_
diff --git a/chrome/common/extensions/manifest_handlers/automation_unittest.cc b/chrome/common/extensions/manifest_handlers/automation_unittest.cc
new file mode 100644
index 0000000..7a3062d
--- /dev/null
+++ b/chrome/common/extensions/manifest_handlers/automation_unittest.cc
@@ -0,0 +1,204 @@
+// 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.
+
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/common/extensions/manifest_handlers/automation.h"
+#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/manifest_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+class AutomationManifestTest : public ExtensionManifestTest {
+ public:
+  AutomationManifestTest() : channel_(chrome::VersionInfo::CHANNEL_UNKNOWN) {}
+
+ protected:
+  AutomationInfo* GetAutomationInfo(scoped_refptr<Extension> extension) {
+    return static_cast<AutomationInfo*>(
+        extension->GetManifestData(manifest_keys::kAutomation));
+  }
+
+ private:
+  ScopedCurrentChannel channel_;
+};
+
+TEST_F(AutomationManifestTest, AsBooleanFalse) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectSuccess("automation_boolean_false.json");
+  ASSERT_TRUE(extension.get());
+
+  const AutomationInfo* info = AutomationInfo::Get(extension.get());
+  ASSERT_FALSE(info);
+}
+
+TEST_F(AutomationManifestTest, AsBooleanTrue) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectSuccess("automation_boolean_true.json");
+  ASSERT_TRUE(extension.get());
+
+  const AutomationInfo* info = AutomationInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_FALSE(info->desktop);
+  EXPECT_FALSE(info->interact);
+  EXPECT_FALSE(info->specified_matches);
+  EXPECT_TRUE(info->matches.is_empty());
+}
+
+TEST_F(AutomationManifestTest, InteractTrue) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectSuccess("automation_interact_true.json");
+  ASSERT_TRUE(extension.get());
+
+  const AutomationInfo* info = AutomationInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_FALSE(info->desktop);
+  EXPECT_TRUE(info->interact);
+  EXPECT_FALSE(info->specified_matches);
+  EXPECT_TRUE(info->matches.is_empty());
+}
+
+TEST_F(AutomationManifestTest, Matches) {
+  scoped_refptr<Extension> extension = LoadAndExpectWarning(
+      "automation_matches.json",
+      ErrorUtils::FormatErrorMessage(
+          automation_errors::kErrorInvalidMatch,
+          "www.badpattern.com",
+          URLPattern::GetParseResultString(
+              URLPattern::PARSE_ERROR_MISSING_SCHEME_SEPARATOR)));
+  ASSERT_TRUE(extension.get());
+
+  const AutomationInfo* info = AutomationInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_FALSE(info->desktop);
+  EXPECT_FALSE(info->interact);
+  EXPECT_TRUE(info->specified_matches);
+  EXPECT_FALSE(info->matches.is_empty());
+
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com/")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.twitter.com/")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.twitter.com")));
+
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://www.bing.com/")));
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://www.bing.com")));
+}
+
+TEST_F(AutomationManifestTest, EmptyMatches) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectWarning("automation_empty_matches.json",
+                           automation_errors::kErrorNoMatchesProvided);
+  ASSERT_TRUE(extension.get());
+
+  const AutomationInfo* info = AutomationInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_FALSE(info->desktop);
+  EXPECT_FALSE(info->interact);
+  EXPECT_TRUE(info->specified_matches);
+  EXPECT_TRUE(info->matches.is_empty());
+}
+
+TEST_F(AutomationManifestTest, NoValidMatches) {
+  std::string error;
+  scoped_refptr<Extension> extension =
+      LoadExtension(Manifest("automation_no_valid_matches.json"), &error);
+  ASSERT_TRUE(extension.get());
+  EXPECT_EQ("", error);
+  EXPECT_EQ(2u, extension->install_warnings().size());
+  EXPECT_EQ(ErrorUtils::FormatErrorMessage(
+                automation_errors::kErrorInvalidMatch,
+                "www.badpattern.com",
+                URLPattern::GetParseResultString(
+                    URLPattern::PARSE_ERROR_MISSING_SCHEME_SEPARATOR)),
+            extension->install_warnings()[0].message);
+  EXPECT_EQ(automation_errors::kErrorNoMatchesProvided,
+            extension->install_warnings()[1].message);
+
+  const AutomationInfo* info = AutomationInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_FALSE(info->desktop);
+  EXPECT_FALSE(info->interact);
+  EXPECT_TRUE(info->specified_matches);
+  EXPECT_TRUE(info->matches.is_empty());
+}
+
+TEST_F(AutomationManifestTest, DesktopFalse) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectSuccess("automation_desktop_false.json");
+  ASSERT_TRUE(extension.get());
+
+  const AutomationInfo* info = AutomationInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_FALSE(info->desktop);
+  EXPECT_FALSE(info->interact);
+  EXPECT_FALSE(info->specified_matches);
+  EXPECT_TRUE(info->matches.is_empty());
+}
+
+TEST_F(AutomationManifestTest, DesktopTrue) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectSuccess("automation_desktop_true.json");
+  ASSERT_TRUE(extension.get());
+
+  const AutomationInfo* info = AutomationInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_TRUE(info->desktop);
+  EXPECT_TRUE(info->interact);
+  EXPECT_FALSE(info->specified_matches);
+  EXPECT_TRUE(info->matches.is_empty());
+}
+
+TEST_F(AutomationManifestTest, Desktop_InteractTrue) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectSuccess("automation_desktop_interact_true.json");
+  ASSERT_TRUE(extension.get());
+
+  const AutomationInfo* info = AutomationInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_TRUE(info->desktop);
+  EXPECT_TRUE(info->interact);
+  EXPECT_FALSE(info->specified_matches);
+  EXPECT_TRUE(info->matches.is_empty());
+}
+
+TEST_F(AutomationManifestTest, Desktop_InteractFalse) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectWarning("automation_desktop_interact_false.json",
+                           automation_errors::kErrorDesktopTrueInteractFalse);
+  ASSERT_TRUE(extension.get());
+
+  const AutomationInfo* info = AutomationInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_TRUE(info->desktop);
+  EXPECT_TRUE(info->interact);
+  EXPECT_FALSE(info->specified_matches);
+  EXPECT_TRUE(info->matches.is_empty());
+}
+
+TEST_F(AutomationManifestTest, Desktop_MatchesSpecified) {
+  scoped_refptr<Extension> extension = LoadAndExpectWarning(
+      "automation_desktop_matches_specified.json",
+      automation_errors::kErrorDesktopTrueMatchesSpecified);
+  ASSERT_TRUE(extension.get());
+
+  const AutomationInfo* info = AutomationInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_TRUE(info->desktop);
+  EXPECT_TRUE(info->interact);
+  EXPECT_FALSE(info->specified_matches);
+  EXPECT_TRUE(info->matches.is_empty());
+}
+
+}  // namespace extensions
diff --git a/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc b/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc
index 2753614..9a699b2 100644
--- a/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc
+++ b/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc
@@ -304,7 +304,7 @@
     return false;
   }
 
-  if (!IsStringUTF8(content)) {
+  if (!base::IsStringUTF8(content)) {
     *error = l10n_util::GetStringFUTF8(
         IDS_EXTENSION_BAD_FILE_ENCODING,
         relative_path.LossyDisplayName());
diff --git a/chrome/common/extensions/manifest_handlers/externally_connectable.cc b/chrome/common/extensions/manifest_handlers/externally_connectable.cc
deleted file mode 100644
index cacb13a..0000000
--- a/chrome/common/extensions/manifest_handlers/externally_connectable.cc
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2013 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.
-
-#include "chrome/common/extensions/manifest_handlers/externally_connectable.h"
-
-#include <algorithm>
-
-#include "base/stl_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/common/extensions/api/manifest_types.h"
-#include "extensions/common/error_utils.h"
-#include "extensions/common/manifest_constants.h"
-#include "extensions/common/permissions/api_permission_set.h"
-#include "extensions/common/permissions/permissions_data.h"
-#include "extensions/common/url_pattern.h"
-#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-#include "url/gurl.h"
-
-namespace rcd = net::registry_controlled_domains;
-
-namespace extensions {
-
-namespace externally_connectable_errors {
-const char kErrorInvalidMatchPattern[] = "Invalid match pattern '*'";
-const char kErrorInvalidId[] = "Invalid ID '*'";
-const char kErrorNothingSpecified[] =
-    "'externally_connectable' specifies neither 'matches' nor 'ids'; "
-    "nothing will be able to connect";
-const char kErrorTopLevelDomainsNotAllowed[] =
-    "\"*\" is an effective top level domain for which wildcard subdomains such "
-    "as \"*\" are not allowed";
-const char kErrorWildcardHostsNotAllowed[] =
-    "Wildcard domain patterns such as \"*\" are not allowed";
-}  // namespace externally_connectable_errors
-
-namespace keys = extensions::manifest_keys;
-namespace errors = externally_connectable_errors;
-using api::manifest_types::ExternallyConnectable;
-
-namespace {
-
-const char kAllIds[] = "*";
-
-template <typename T>
-std::vector<T> Sorted(const std::vector<T>& in) {
-  std::vector<T> out = in;
-  std::sort(out.begin(), out.end());
-  return out;
-}
-
-} // namespace
-
-ExternallyConnectableHandler::ExternallyConnectableHandler() {}
-
-ExternallyConnectableHandler::~ExternallyConnectableHandler() {}
-
-bool ExternallyConnectableHandler::Parse(Extension* extension,
-                                         base::string16* error) {
-  const base::Value* externally_connectable = NULL;
-  CHECK(extension->manifest()->Get(keys::kExternallyConnectable,
-                                   &externally_connectable));
-  std::vector<InstallWarning> install_warnings;
-  scoped_ptr<ExternallyConnectableInfo> info =
-      ExternallyConnectableInfo::FromValue(*externally_connectable,
-                                           &install_warnings,
-                                           error);
-  if (!info)
-    return false;
-  if (!info->matches.is_empty()) {
-    PermissionsData::GetInitialAPIPermissions(extension)->insert(
-        APIPermission::kWebConnectable);
-  }
-  extension->AddInstallWarnings(install_warnings);
-  extension->SetManifestData(keys::kExternallyConnectable, info.release());
-  return true;
-}
-
-const std::vector<std::string> ExternallyConnectableHandler::Keys() const {
-  return SingleKey(keys::kExternallyConnectable);
-}
-
-// static
-ExternallyConnectableInfo* ExternallyConnectableInfo::Get(
-    const Extension* extension) {
-  return static_cast<ExternallyConnectableInfo*>(
-      extension->GetManifestData(keys::kExternallyConnectable));
-}
-
-// static
-scoped_ptr<ExternallyConnectableInfo> ExternallyConnectableInfo::FromValue(
-    const base::Value& value,
-    std::vector<InstallWarning>* install_warnings,
-    base::string16* error) {
-  scoped_ptr<ExternallyConnectable> externally_connectable =
-      ExternallyConnectable::FromValue(value, error);
-  if (!externally_connectable)
-    return scoped_ptr<ExternallyConnectableInfo>();
-
-  URLPatternSet matches;
-
-  if (externally_connectable->matches) {
-    for (std::vector<std::string>::iterator it =
-             externally_connectable->matches->begin();
-         it != externally_connectable->matches->end(); ++it) {
-      // Safe to use SCHEME_ALL here; externally_connectable gives a page ->
-      // extension communication path, not the other way.
-      URLPattern pattern(URLPattern::SCHEME_ALL);
-      if (pattern.Parse(*it) != URLPattern::PARSE_SUCCESS) {
-        *error = ErrorUtils::FormatErrorMessageUTF16(
-            errors::kErrorInvalidMatchPattern, *it);
-        return scoped_ptr<ExternallyConnectableInfo>();
-      }
-
-      // Wildcard hosts are not allowed.
-      if (pattern.host().empty()) {
-        // Warning not error for forwards compatibility.
-        install_warnings->push_back(InstallWarning(
-            ErrorUtils::FormatErrorMessage(
-                errors::kErrorWildcardHostsNotAllowed, *it),
-            keys::kExternallyConnectable,
-            *it));
-        continue;
-      }
-
-      // Wildcards on subdomains of a TLD are not allowed.
-      size_t registry_length = rcd::GetRegistryLength(
-          pattern.host(),
-          // This means that things that look like TLDs - the foobar in
-          // http://google.foobar - count as TLDs.
-          rcd::INCLUDE_UNKNOWN_REGISTRIES,
-          // This means that effective TLDs like appspot.com count as TLDs;
-          // codereview.appspot.com and evil.appspot.com are different.
-          rcd::INCLUDE_PRIVATE_REGISTRIES);
-
-      if (registry_length == std::string::npos) {
-        // The URL parsing combined with host().empty() should have caught this.
-        NOTREACHED() << *it;
-        *error = ErrorUtils::FormatErrorMessageUTF16(
-            errors::kErrorInvalidMatchPattern, *it);
-        return scoped_ptr<ExternallyConnectableInfo>();
-      }
-
-      // Broad match patterns like "*.com", "*.co.uk", and even "*.appspot.com"
-      // are not allowed. However just "appspot.com" is ok.
-      if (registry_length == 0 && pattern.match_subdomains()) {
-        // Warning not error for forwards compatibility.
-        install_warnings->push_back(InstallWarning(
-            ErrorUtils::FormatErrorMessage(
-                errors::kErrorTopLevelDomainsNotAllowed,
-                pattern.host().c_str(),
-                *it),
-            keys::kExternallyConnectable,
-            *it));
-        continue;
-      }
-
-      matches.AddPattern(pattern);
-    }
-  }
-
-  std::vector<std::string> ids;
-  bool all_ids = false;
-
-  if (externally_connectable->ids) {
-    for (std::vector<std::string>::iterator it =
-             externally_connectable->ids->begin();
-         it != externally_connectable->ids->end(); ++it) {
-      if (*it == kAllIds) {
-        all_ids = true;
-      } else if (Extension::IdIsValid(*it)) {
-        ids.push_back(*it);
-      } else {
-        *error = ErrorUtils::FormatErrorMessageUTF16(
-            errors::kErrorInvalidId, *it);
-        return scoped_ptr<ExternallyConnectableInfo>();
-      }
-    }
-  }
-
-  if (!externally_connectable->matches &&
-      !externally_connectable->ids) {
-    install_warnings->push_back(InstallWarning(
-        errors::kErrorNothingSpecified,
-        keys::kExternallyConnectable));
-  }
-
-  bool accepts_tls_channel_id =
-      externally_connectable->accepts_tls_channel_id.get() &&
-      *externally_connectable->accepts_tls_channel_id;
-  return make_scoped_ptr(
-      new ExternallyConnectableInfo(matches, ids, all_ids,
-                                    accepts_tls_channel_id));
-}
-
-ExternallyConnectableInfo::~ExternallyConnectableInfo() {}
-
-ExternallyConnectableInfo::ExternallyConnectableInfo(
-    const URLPatternSet& matches,
-    const std::vector<std::string>& ids,
-    bool all_ids,
-    bool accepts_tls_channel_id)
-    : matches(matches), ids(Sorted(ids)), all_ids(all_ids),
-      accepts_tls_channel_id(accepts_tls_channel_id) {}
-
-bool ExternallyConnectableInfo::IdCanConnect(const std::string& id) {
-  if (all_ids)
-    return true;
-  DCHECK(base::STLIsSorted(ids));
-  return std::binary_search(ids.begin(), ids.end(), id);
-}
-
-}   // namespace extensions
diff --git a/chrome/common/extensions/manifest_handlers/externally_connectable.h b/chrome/common/extensions/manifest_handlers/externally_connectable.h
deleted file mode 100644
index db4b97a..0000000
--- a/chrome/common/extensions/manifest_handlers/externally_connectable.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_
-#define CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_
-
-#include <string>
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/install_warning.h"
-#include "extensions/common/manifest_handler.h"
-#include "extensions/common/url_pattern_set.h"
-
-class GURL;
-
-namespace base {
-class Value;
-}
-
-namespace extensions {
-
-// Error constants used when parsing the externally_connectable manifest entry.
-namespace externally_connectable_errors {
-extern const char kErrorInvalid[];
-extern const char kErrorInvalidMatchPattern[];
-extern const char kErrorInvalidId[];
-extern const char kErrorNothingSpecified[];
-extern const char kErrorTopLevelDomainsNotAllowed[];
-extern const char kErrorWildcardHostsNotAllowed[];
-}  // namespace externally_connectable_errors
-
-// Parses the externally_connectable manifest entry.
-class ExternallyConnectableHandler : public ManifestHandler {
- public:
-  ExternallyConnectableHandler();
-  virtual ~ExternallyConnectableHandler();
-
-  virtual bool Parse(Extension* extension, base::string16* error) OVERRIDE;
-
- private:
-  virtual const std::vector<std::string> Keys() const OVERRIDE;
-
-  DISALLOW_COPY_AND_ASSIGN(ExternallyConnectableHandler);
-};
-
-// The parsed form of the externally_connectable manifest entry.
-struct ExternallyConnectableInfo : public Extension::ManifestData {
- public:
-  // Gets the ExternallyConnectableInfo for |extension|, or NULL if none was
-  // specified.
-  static ExternallyConnectableInfo* Get(const Extension* extension);
-
-  // Tries to construct the info based on |value|, as it would have appeared in
-  // the manifest. Sets |error| and returns an empty scoped_ptr on failure.
-  static scoped_ptr<ExternallyConnectableInfo> FromValue(
-      const base::Value& value,
-      std::vector<InstallWarning>* install_warnings,
-      base::string16* error);
-
-  virtual ~ExternallyConnectableInfo();
-
-  // The URL patterns that are allowed to connect/sendMessage.
-  const URLPatternSet matches;
-
-  // The extension IDs that are allowed to connect/sendMessage. Sorted.
-  const std::vector<std::string> ids;
-
-  // True if any extension is allowed to connect. This would have corresponded
-  // to an ID of "*" in |ids|.
-  const bool all_ids;
-
-  // True if extension accepts the TLS channel ID, when requested by the
-  // connecting origin.
-  const bool accepts_tls_channel_id;
-
-  // Returns true if |ids| contains |id| or if |all_ids| is true.
-  //
-  // More convenient for callers than checking each individually, and it makes
-  // use of the sortedness of |ids|.
-  bool IdCanConnect(const std::string& id);
-
-  // Public only for testing. Use FromValue in production.
-  ExternallyConnectableInfo(const URLPatternSet& matches,
-                            const std::vector<std::string>& ids,
-                            bool all_ids,
-                            bool accepts_tls_channel_id);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ExternallyConnectableInfo);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_
diff --git a/chrome/common/extensions/manifest_handlers/externally_connectable_unittest.cc b/chrome/common/extensions/manifest_handlers/externally_connectable_unittest.cc
deleted file mode 100644
index 2e5d993..0000000
--- a/chrome/common/extensions/manifest_handlers/externally_connectable_unittest.cc
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2013 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.
-
-#include <algorithm>
-
-#include "chrome/common/extensions/features/feature_channel.h"
-#include "chrome/common/extensions/manifest_handlers/externally_connectable.h"
-#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
-#include "extensions/common/error_utils.h"
-#include "extensions/common/manifest_constants.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::ElementsAre;
-
-namespace extensions {
-
-namespace errors = externally_connectable_errors;
-
-class ExternallyConnectableTest : public ExtensionManifestTest {
- public:
-  ExternallyConnectableTest() : channel_(chrome::VersionInfo::CHANNEL_DEV) {}
-
- protected:
-  ExternallyConnectableInfo* GetExternallyConnectableInfo(
-      scoped_refptr<Extension> extension) {
-    return static_cast<ExternallyConnectableInfo*>(extension->GetManifestData(
-        manifest_keys::kExternallyConnectable));
-  }
-
- private:
-  ScopedCurrentChannel channel_;
-};
-
-TEST_F(ExternallyConnectableTest, IDsAndMatches) {
-  scoped_refptr<Extension> extension =
-      LoadAndExpectSuccess("externally_connectable_ids_and_matches.json");
-  ASSERT_TRUE(extension.get());
-
-  EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kWebConnectable));
-
-  ExternallyConnectableInfo* info =
-      ExternallyConnectableInfo::Get(extension.get());
-  ASSERT_TRUE(info);
-
-  EXPECT_THAT(info->ids, ElementsAre("abcdefghijklmnopabcdefghijklmnop",
-                                     "ponmlkjihgfedcbaponmlkjihgfedcba"));
-
-  EXPECT_FALSE(info->all_ids);
-
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com/")));
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://example.com/index.html")));
-
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/index.html")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com/")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com/")));
-
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org/")));
-  EXPECT_TRUE(
-      info->matches.MatchesURL(GURL("http://build.chromium.org/index.html")));
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org")));
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org/")));
-  EXPECT_FALSE(
-      info->matches.MatchesURL(GURL("http://foo.chromium.org/index.html")));
-
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com")));
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com/")));
-
-  // TLD-style patterns should match just the TLD.
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://appspot.com/foo.html")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://go/here")));
-
-  // TLD-style patterns should *not* match any subdomains of the TLD.
-  EXPECT_FALSE(
-      info->matches.MatchesURL(GURL("http://codereview.appspot.com/foo.html")));
-  EXPECT_FALSE(
-      info->matches.MatchesURL(GURL("http://chromium.com/index.html")));
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://here.go/somewhere")));
-
-  // Paths that don't have any wildcards should match the exact domain, but
-  // ignore the trailing slash. This is kind of a corner case, so let's test it.
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://no.wildcard.path")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://no.wildcard.path/")));
-  EXPECT_FALSE(info->matches.MatchesURL(
-        GURL("http://no.wildcard.path/index.html")));
-}
-
-TEST_F(ExternallyConnectableTest, IDs) {
-  scoped_refptr<Extension> extension =
-      LoadAndExpectSuccess("externally_connectable_ids.json");
-  ASSERT_TRUE(extension.get());
-
-  EXPECT_FALSE(extension->HasAPIPermission(APIPermission::kWebConnectable));
-
-  ExternallyConnectableInfo* info =
-      ExternallyConnectableInfo::Get(extension.get());
-  ASSERT_TRUE(info);
-
-  EXPECT_THAT(info->ids, ElementsAre("abcdefghijklmnopabcdefghijklmnop",
-                                     "ponmlkjihgfedcbaponmlkjihgfedcba"));
-
-  EXPECT_FALSE(info->all_ids);
-
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://google.com/index.html")));
-}
-
-TEST_F(ExternallyConnectableTest, Matches) {
-  scoped_refptr<Extension> extension =
-      LoadAndExpectSuccess("externally_connectable_matches.json");
-  ASSERT_TRUE(extension.get());
-
-  EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kWebConnectable));
-
-  ExternallyConnectableInfo* info =
-      ExternallyConnectableInfo::Get(extension.get());
-  ASSERT_TRUE(info);
-
-  EXPECT_THAT(info->ids, ElementsAre());
-
-  EXPECT_FALSE(info->all_ids);
-
-  EXPECT_FALSE(info->accepts_tls_channel_id);
-
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com/")));
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://example.com/index.html")));
-
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/index.html")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com/")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com/")));
-
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org/")));
-  EXPECT_TRUE(
-      info->matches.MatchesURL(GURL("http://build.chromium.org/index.html")));
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org")));
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org/")));
-  EXPECT_FALSE(
-      info->matches.MatchesURL(GURL("http://foo.chromium.org/index.html")));
-
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com")));
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com/")));
-}
-
-TEST_F(ExternallyConnectableTest, MatchesWithTlsChannelId) {
-  scoped_refptr<Extension> extension =
-      LoadAndExpectSuccess(
-          "externally_connectable_matches_tls_channel_id.json");
-  ASSERT_TRUE(extension.get());
-
-  EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kWebConnectable));
-
-  ExternallyConnectableInfo* info =
-      ExternallyConnectableInfo::Get(extension.get());
-  ASSERT_TRUE(info);
-
-  EXPECT_THAT(info->ids, ElementsAre());
-
-  EXPECT_FALSE(info->all_ids);
-
-  EXPECT_TRUE(info->accepts_tls_channel_id);
-
-  // The matches portion of the manifest is identical to those in
-  // externally_connectable_matches, so only a subset of the Matches tests is
-  // repeated here.
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com")));
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://example.com/index.html")));
-}
-
-TEST_F(ExternallyConnectableTest, AllIDs) {
-  scoped_refptr<Extension> extension =
-      LoadAndExpectSuccess("externally_connectable_all_ids.json");
-  ASSERT_TRUE(extension.get());
-
-  EXPECT_FALSE(extension->HasAPIPermission(APIPermission::kWebConnectable));
-
-  ExternallyConnectableInfo* info =
-      ExternallyConnectableInfo::Get(extension.get());
-  ASSERT_TRUE(info);
-
-  EXPECT_THAT(info->ids, ElementsAre("abcdefghijklmnopabcdefghijklmnop",
-                                     "ponmlkjihgfedcbaponmlkjihgfedcba"));
-
-  EXPECT_TRUE(info->all_ids);
-
-  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://google.com/index.html")));
-}
-
-TEST_F(ExternallyConnectableTest, IdCanConnect) {
-  // Not in order to test that ExternallyConnectableInfo sorts it.
-  std::string matches_ids_array[] = { "g", "h", "c", "i", "a", "z", "b" };
-  std::vector<std::string> matches_ids(
-      matches_ids_array, matches_ids_array + arraysize(matches_ids_array));
-
-  std::string nomatches_ids_array[] = { "2", "3", "1" };
-
-  // all_ids = false.
-  {
-    ExternallyConnectableInfo info(URLPatternSet(), matches_ids, false, false);
-    for (size_t i = 0; i < matches_ids.size(); ++i)
-      EXPECT_TRUE(info.IdCanConnect(matches_ids[i]));
-    for (size_t i = 0; i < arraysize(nomatches_ids_array); ++i)
-      EXPECT_FALSE(info.IdCanConnect(nomatches_ids_array[i]));
-  }
-
-  // all_ids = true.
-  {
-    ExternallyConnectableInfo info(URLPatternSet(), matches_ids, true, false);
-    for (size_t i = 0; i < matches_ids.size(); ++i)
-      EXPECT_TRUE(info.IdCanConnect(matches_ids[i]));
-    for (size_t i = 0; i < arraysize(nomatches_ids_array); ++i)
-      EXPECT_TRUE(info.IdCanConnect(nomatches_ids_array[i]));
-  }
-}
-
-TEST_F(ExternallyConnectableTest, ErrorWrongFormat) {
-  LoadAndExpectError("externally_connectable_error_wrong_format.json",
-                     "expected dictionary, got string");
-}
-
-TEST_F(ExternallyConnectableTest, ErrorBadID) {
-  LoadAndExpectError(
-      "externally_connectable_bad_id.json",
-      ErrorUtils::FormatErrorMessage(errors::kErrorInvalidId, "badid"));
-}
-
-TEST_F(ExternallyConnectableTest, ErrorBadMatches) {
-  LoadAndExpectError(
-      "externally_connectable_error_bad_matches.json",
-      ErrorUtils::FormatErrorMessage(errors::kErrorInvalidMatchPattern,
-                                     "www.yahoo.com"));
-}
-
-TEST_F(ExternallyConnectableTest, WarningNoAllURLs) {
-  scoped_refptr<Extension> extension = LoadAndExpectWarning(
-      "externally_connectable_error_all_urls.json",
-      ErrorUtils::FormatErrorMessage(errors::kErrorWildcardHostsNotAllowed,
-                                     "<all_urls>"));
-  ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
-  EXPECT_FALSE(info->matches.ContainsPattern(
-      URLPattern(URLPattern::SCHEME_ALL, "<all_urls>")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
-}
-
-TEST_F(ExternallyConnectableTest, WarningWildcardHost) {
-  scoped_refptr<Extension> extension = LoadAndExpectWarning(
-      "externally_connectable_error_wildcard_host.json",
-      ErrorUtils::FormatErrorMessage(errors::kErrorWildcardHostsNotAllowed,
-                                     "http://*/*"));
-  ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
-  EXPECT_FALSE(info->matches.ContainsPattern(
-      URLPattern(URLPattern::SCHEME_ALL, "http://*/*")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
-}
-
-TEST_F(ExternallyConnectableTest, WarningNoTLD) {
-  scoped_refptr<Extension> extension = LoadAndExpectWarning(
-      "externally_connectable_error_tld.json",
-      ErrorUtils::FormatErrorMessage(
-          errors::kErrorTopLevelDomainsNotAllowed,
-          "co.uk",
-          "http://*.co.uk/*"));
-  ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
-  EXPECT_FALSE(info->matches.ContainsPattern(
-      URLPattern(URLPattern::SCHEME_ALL, "http://*.co.uk/*")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
-}
-
-TEST_F(ExternallyConnectableTest, WarningNoEffectiveTLD) {
-  scoped_refptr<Extension> extension = LoadAndExpectWarning(
-      "externally_connectable_error_effective_tld.json",
-      ErrorUtils::FormatErrorMessage(
-          errors::kErrorTopLevelDomainsNotAllowed,
-          "appspot.com",
-          "http://*.appspot.com/*"));
-  ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
-  EXPECT_FALSE(info->matches.ContainsPattern(
-      URLPattern(URLPattern::SCHEME_ALL, "http://*.appspot.com/*")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
-}
-
-TEST_F(ExternallyConnectableTest, WarningUnknownTLD) {
-  scoped_refptr<Extension> extension = LoadAndExpectWarning(
-      "externally_connectable_error_unknown_tld.json",
-      ErrorUtils::FormatErrorMessage(
-          errors::kErrorTopLevelDomainsNotAllowed,
-          "notatld",
-          "http://*.notatld/*"));
-  ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
-  EXPECT_FALSE(info->matches.ContainsPattern(
-      URLPattern(URLPattern::SCHEME_ALL, "http://*.notatld/*")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
-  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
-}
-
-TEST_F(ExternallyConnectableTest, WarningNothingSpecified) {
-  LoadAndExpectWarning("externally_connectable_nothing_specified.json",
-                       errors::kErrorNothingSpecified);
-}
-
-}  // namespace extensions
diff --git a/chrome/common/extensions/manifest_handlers/mime_types_handler.cc b/chrome/common/extensions/manifest_handlers/mime_types_handler.cc
new file mode 100644
index 0000000..3e22d7f
--- /dev/null
+++ b/chrome/common/extensions/manifest_handlers/mime_types_handler.cc
@@ -0,0 +1,117 @@
+// 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.
+
+#include "chrome/common/extensions/manifest_handlers/mime_types_handler.h"
+
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/manifest.h"
+#include "extensions/common/manifest_constants.h"
+
+namespace keys = extensions::manifest_keys;
+namespace errors = extensions::manifest_errors;
+
+namespace {
+
+const char* const kMIMETypeHandlersWhitelist[] = {
+    extension_misc::kPdfExtensionId,
+    extension_misc::kQuickOfficeComponentExtensionId,
+    extension_misc::kQuickOfficeInternalExtensionId,
+    extension_misc::kQuickOfficeExtensionId,
+    extension_misc::kStreamsPrivateTestExtensionId};
+
+// Stored on the Extension.
+struct MimeTypesHandlerInfo : public extensions::Extension::ManifestData {
+  MimeTypesHandler handler_;
+
+  MimeTypesHandlerInfo();
+  virtual ~MimeTypesHandlerInfo();
+};
+
+MimeTypesHandlerInfo::MimeTypesHandlerInfo() {
+}
+
+MimeTypesHandlerInfo::~MimeTypesHandlerInfo() {
+}
+
+}  // namespace
+
+// static
+std::vector<std::string> MimeTypesHandler::GetMIMETypeWhitelist() {
+  std::vector<std::string> whitelist;
+  for (size_t i = 0; i < arraysize(kMIMETypeHandlersWhitelist); ++i)
+    whitelist.push_back(kMIMETypeHandlersWhitelist[i]);
+  return whitelist;
+}
+
+MimeTypesHandler::MimeTypesHandler() {
+}
+
+MimeTypesHandler::~MimeTypesHandler() {
+}
+
+void MimeTypesHandler::AddMIMEType(const std::string& mime_type) {
+  mime_type_set_.insert(mime_type);
+}
+
+bool MimeTypesHandler::CanHandleMIMEType(const std::string& mime_type) const {
+  return mime_type_set_.find(mime_type) != mime_type_set_.end();
+}
+
+// static
+MimeTypesHandler* MimeTypesHandler::GetHandler(
+    const extensions::Extension* extension) {
+  MimeTypesHandlerInfo* info = static_cast<MimeTypesHandlerInfo*>(
+      extension->GetManifestData(keys::kMimeTypesHandler));
+  if (info)
+    return &info->handler_;
+  return NULL;
+}
+
+MimeTypesHandlerParser::MimeTypesHandlerParser() {
+}
+
+MimeTypesHandlerParser::~MimeTypesHandlerParser() {
+}
+
+bool MimeTypesHandlerParser::Parse(extensions::Extension* extension,
+                                   base::string16* error) {
+  const base::ListValue* mime_types_value = NULL;
+  if (!extension->manifest()->GetList(keys::kMIMETypes,
+                                      &mime_types_value)) {
+    *error = base::ASCIIToUTF16(errors::kInvalidMimeTypesHandler);
+    return false;
+  }
+
+  scoped_ptr<MimeTypesHandlerInfo> info(new MimeTypesHandlerInfo);
+  info->handler_.set_extension_id(extension->id());
+  for (size_t i = 0; i < mime_types_value->GetSize(); ++i) {
+    std::string filter;
+    if (!mime_types_value->GetString(i, &filter)) {
+      *error = base::ASCIIToUTF16(errors::kInvalidMIMETypes);
+      return false;
+    }
+    info->handler_.AddMIMEType(filter);
+  }
+
+  std::string mime_types_handler;
+  if (extension->manifest()->GetString(keys::kMimeTypesHandler,
+                                       &mime_types_handler)) {
+    info->handler_.set_handler_url(mime_types_handler);
+  }
+
+  extension->SetManifestData(keys::kMimeTypesHandler, info.release());
+  return true;
+}
+
+const std::vector<std::string> MimeTypesHandlerParser::Keys() const {
+  std::vector<std::string> keys;
+  keys.push_back(keys::kMIMETypes);
+  keys.push_back(keys::kMimeTypesHandler);
+  return keys;
+}
diff --git a/chrome/common/extensions/manifest_handlers/mime_types_handler.h b/chrome/common/extensions/manifest_handlers/mime_types_handler.h
new file mode 100644
index 0000000..84e049f
--- /dev/null
+++ b/chrome/common/extensions/manifest_handlers/mime_types_handler.h
@@ -0,0 +1,67 @@
+// 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.
+
+#ifndef CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_MIME_TYPES_HANDLER_H_
+#define CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_MIME_TYPES_HANDLER_H_
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/manifest_handler.h"
+
+class MimeTypesHandler {
+ public:
+  // Returns list of extensions' ids that are allowed to use MIME type filters.
+  static std::vector<std::string> GetMIMETypeWhitelist();
+
+  static MimeTypesHandler* GetHandler(const extensions::Extension* extension);
+
+  MimeTypesHandler();
+  ~MimeTypesHandler();
+
+  // extension id
+  std::string extension_id() const { return extension_id_; }
+  void set_extension_id(const std::string& extension_id) {
+    extension_id_ = extension_id;
+  }
+
+  // Adds a MIME type filter to the handler.
+  void AddMIMEType(const std::string& mime_type);
+  // Tests if the handler has registered a filter for the MIME type.
+  bool CanHandleMIMEType(const std::string& mime_type) const;
+
+  // Set the URL that will be used to handle MIME type requests.
+  void set_handler_url(const std::string& handler_url) {
+    handler_url_ = handler_url;
+  }
+  // The URL that will be used to handle MIME type requests.
+  const std::string handler_url() const { return handler_url_; }
+
+ private:
+  // The id for the extension this action belongs to (as defined in the
+  // extension manifest).
+  std::string extension_id_;
+
+  // A list of MIME type filters.
+  std::set<std::string> mime_type_set_;
+
+  std::string handler_url_;
+};
+
+class MimeTypesHandlerParser : public extensions::ManifestHandler {
+ public:
+  MimeTypesHandlerParser();
+  virtual ~MimeTypesHandlerParser();
+
+  virtual bool Parse(extensions::Extension* extension,
+                     base::string16* error) OVERRIDE;
+
+ private:
+  virtual const std::vector<std::string> Keys() const OVERRIDE;
+};
+
+#endif  // CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_MIME_TYPES_HANDLER_H_
diff --git a/chrome/common/extensions/mime_types_handler.cc b/chrome/common/extensions/mime_types_handler.cc
deleted file mode 100644
index 410a3a7..0000000
--- a/chrome/common/extensions/mime_types_handler.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/common/extensions/mime_types_handler.h"
-
-#include "base/logging.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "extensions/common/error_utils.h"
-#include "extensions/common/manifest.h"
-#include "extensions/common/manifest_constants.h"
-
-namespace keys = extensions::manifest_keys;
-namespace errors = extensions::manifest_errors;
-
-namespace {
-
-const char* const kMIMETypeHandlersWhitelist[] = {
-    extension_misc::kPdfExtensionId,
-    extension_misc::kQuickOfficeComponentExtensionId,
-    extension_misc::kQuickOfficeInternalExtensionId,
-    extension_misc::kQuickOfficeExtensionId,
-    extension_misc::kStreamsPrivateTestExtensionId};
-
-// Stored on the Extension.
-struct MimeTypesHandlerInfo : public extensions::Extension::ManifestData {
-  MimeTypesHandler handler_;
-
-  MimeTypesHandlerInfo();
-  virtual ~MimeTypesHandlerInfo();
-};
-
-MimeTypesHandlerInfo::MimeTypesHandlerInfo() {
-}
-
-MimeTypesHandlerInfo::~MimeTypesHandlerInfo() {
-}
-
-}  // namespace
-
-// static
-std::vector<std::string> MimeTypesHandler::GetMIMETypeWhitelist() {
-  std::vector<std::string> whitelist;
-  for (size_t i = 0; i < arraysize(kMIMETypeHandlersWhitelist); ++i)
-    whitelist.push_back(kMIMETypeHandlersWhitelist[i]);
-  return whitelist;
-}
-
-MimeTypesHandler::MimeTypesHandler() {
-}
-
-MimeTypesHandler::~MimeTypesHandler() {
-}
-
-void MimeTypesHandler::AddMIMEType(const std::string& mime_type) {
-  mime_type_set_.insert(mime_type);
-}
-
-bool MimeTypesHandler::CanHandleMIMEType(const std::string& mime_type) const {
-  return mime_type_set_.find(mime_type) != mime_type_set_.end();
-}
-
-// static
-MimeTypesHandler* MimeTypesHandler::GetHandler(
-    const extensions::Extension* extension) {
-  MimeTypesHandlerInfo* info = static_cast<MimeTypesHandlerInfo*>(
-      extension->GetManifestData(keys::kMimeTypesHandler));
-  if (info)
-    return &info->handler_;
-  return NULL;
-}
-
-MimeTypesHandlerParser::MimeTypesHandlerParser() {
-}
-
-MimeTypesHandlerParser::~MimeTypesHandlerParser() {
-}
-
-bool MimeTypesHandlerParser::Parse(extensions::Extension* extension,
-                                   base::string16* error) {
-  const base::ListValue* mime_types_value = NULL;
-  if (!extension->manifest()->GetList(keys::kMIMETypes,
-                                      &mime_types_value)) {
-    *error = base::ASCIIToUTF16(errors::kInvalidMimeTypesHandler);
-    return false;
-  }
-
-  scoped_ptr<MimeTypesHandlerInfo> info(new MimeTypesHandlerInfo);
-  info->handler_.set_extension_id(extension->id());
-  for (size_t i = 0; i < mime_types_value->GetSize(); ++i) {
-    std::string filter;
-    if (!mime_types_value->GetString(i, &filter)) {
-      *error = base::ASCIIToUTF16(errors::kInvalidMIMETypes);
-      return false;
-    }
-    info->handler_.AddMIMEType(filter);
-  }
-
-  std::string mime_types_handler;
-  if (extension->manifest()->GetString(keys::kMimeTypesHandler,
-                                       &mime_types_handler)) {
-    info->handler_.set_handler_url(mime_types_handler);
-  }
-
-  extension->SetManifestData(keys::kMimeTypesHandler, info.release());
-  return true;
-}
-
-const std::vector<std::string> MimeTypesHandlerParser::Keys() const {
-  std::vector<std::string> keys;
-  keys.push_back(keys::kMIMETypes);
-  keys.push_back(keys::kMimeTypesHandler);
-  return keys;
-}
diff --git a/chrome/common/extensions/mime_types_handler.h b/chrome/common/extensions/mime_types_handler.h
deleted file mode 100644
index 90c8f44..0000000
--- a/chrome/common/extensions/mime_types_handler.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_COMMON_EXTENSIONS_MIME_TYPES_HANDLER_H_
-#define CHROME_COMMON_EXTENSIONS_MIME_TYPES_HANDLER_H_
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/manifest_handler.h"
-
-class MimeTypesHandler {
- public:
-  // Returns list of extensions' ids that are allowed to use MIME type filters.
-  static std::vector<std::string> GetMIMETypeWhitelist();
-
-  static MimeTypesHandler* GetHandler(const extensions::Extension* extension);
-
-  MimeTypesHandler();
-  ~MimeTypesHandler();
-
-  // extension id
-  std::string extension_id() const { return extension_id_; }
-  void set_extension_id(const std::string& extension_id) {
-    extension_id_ = extension_id;
-  }
-
-  // Adds a MIME type filter to the handler.
-  void AddMIMEType(const std::string& mime_type);
-  // Tests if the handler has registered a filter for the MIME type.
-  bool CanHandleMIMEType(const std::string& mime_type) const;
-
-  // Set the URL that will be used to handle MIME type requests.
-  void set_handler_url(const std::string& handler_url) {
-    handler_url_ = handler_url;
-  }
-  // The URL that will be used to handle MIME type requests.
-  const std::string handler_url() const { return handler_url_; }
-
- private:
-  // The id for the extension this action belongs to (as defined in the
-  // extension manifest).
-  std::string extension_id_;
-
-  // A list of MIME type filters.
-  std::set<std::string> mime_type_set_;
-
-  std::string handler_url_;
-};
-
-class MimeTypesHandlerParser : public extensions::ManifestHandler {
- public:
-  MimeTypesHandlerParser();
-  virtual ~MimeTypesHandlerParser();
-
-  virtual bool Parse(extensions::Extension* extension,
-                     base::string16* error) OVERRIDE;
-
- private:
-  virtual const std::vector<std::string> Keys() const OVERRIDE;
-};
-
-#endif  // CHROME_COMMON_EXTENSIONS_MIME_TYPES_HANDLER_H_
-
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc
index f999969..6fc12f1 100644
--- a/chrome/common/extensions/permissions/chrome_api_permissions.cc
+++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc
@@ -9,7 +9,6 @@
 #include "extensions/common/permissions/media_galleries_permission.h"
 #include "extensions/common/permissions/permission_message.h"
 #include "extensions/common/permissions/permissions_info.h"
-#include "extensions/common/permissions/socket_permission.h"
 #include "extensions/common/permissions/usb_device_permission.h"
 #include "grit/extensions_strings.h"
 #include "grit/generated_resources.h"
@@ -33,369 +32,326 @@
 
 std::vector<APIPermissionInfo*> ChromeAPIPermissions::GetAllPermissions()
     const {
-  struct PermissionRegistration {
-    APIPermission::ID id;
-    const char* name;
-    int flags;
-    int l10n_message_id;
-    PermissionMessage::ID message_id;
-    APIPermissionInfo::APIPermissionConstructor constructor;
-  } PermissionsToRegister[] = {
-        // Register permissions for all extension types.
-        {APIPermission::kBackground, "background"},
-        {APIPermission::kClipboardRead, "clipboardRead",
-         APIPermissionInfo::kFlagNone, IDS_EXTENSION_PROMPT_WARNING_CLIPBOARD,
-         PermissionMessage::kClipboard},
-        {APIPermission::kClipboardWrite, "clipboardWrite"},
-        {APIPermission::kDeclarativeContent, "declarativeContent"},
-        {APIPermission::kDeclarativeWebRequest, "declarativeWebRequest",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_DECLARATIVE_WEB_REQUEST,
-         PermissionMessage::kDeclarativeWebRequest},
-        {APIPermission::kDesktopCapture, "desktopCapture",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_DESKTOP_CAPTURE,
-         PermissionMessage::kDesktopCapture},
-        {APIPermission::kDns, "dns"},
-        {APIPermission::kDownloads, "downloads", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_DOWNLOADS, PermissionMessage::kDownloads},
-        {APIPermission::kDownloadsOpen, "downloads.open",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_DOWNLOADS_OPEN,
-         PermissionMessage::kDownloadsOpen},
-        {APIPermission::kDownloadsShelf, "downloads.shelf"},
-        {APIPermission::kIdentity, "identity"},
-        {APIPermission::kExperimental, "experimental",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        // NOTE(kalman): this is provided by a manifest property but needs to
-        // appear in the install permission dialogue, so we need a fake
-        // permission for it. See http://crbug.com/247857.
-        {APIPermission::kWebConnectable, "webConnectable",
-         APIPermissionInfo::kFlagCannotBeOptional |
-             APIPermissionInfo::kFlagInternal,
-         IDS_EXTENSION_PROMPT_WARNING_WEB_CONNECTABLE,
-         PermissionMessage::kWebConnectable},
-        {APIPermission::kGeolocation, "geolocation",
-         APIPermissionInfo::kFlagCannotBeOptional,
-         IDS_EXTENSION_PROMPT_WARNING_GEOLOCATION,
-         PermissionMessage::kGeolocation},
-        {APIPermission::kNotification, "notifications"},
-        {APIPermission::kUnlimitedStorage, "unlimitedStorage",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kGcm, "gcm"},
+  APIPermissionInfo::InitInfo permissions_to_register[] = {
+      // Register permissions for all extension types.
+      {APIPermission::kBackground, "background"},
+      {APIPermission::kClipboardRead, "clipboardRead",
+       APIPermissionInfo::kFlagNone, IDS_EXTENSION_PROMPT_WARNING_CLIPBOARD,
+       PermissionMessage::kClipboard},
+      {APIPermission::kClipboardWrite, "clipboardWrite"},
+      {APIPermission::kDeclarativeContent, "declarativeContent"},
+      {APIPermission::kDeclarativeWebRequest, "declarativeWebRequest",
+       APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_DECLARATIVE_WEB_REQUEST,
+       PermissionMessage::kDeclarativeWebRequest},
+      {APIPermission::kDesktopCapture, "desktopCapture",
+       APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_DESKTOP_CAPTURE,
+       PermissionMessage::kDesktopCapture},
+      {APIPermission::kDownloads, "downloads", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_DOWNLOADS, PermissionMessage::kDownloads},
+      {APIPermission::kDownloadsOpen, "downloads.open",
+       APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_DOWNLOADS_OPEN,
+       PermissionMessage::kDownloadsOpen},
+      {APIPermission::kDownloadsShelf, "downloads.shelf"},
+      {APIPermission::kIdentity, "identity"},
+      {APIPermission::kExperimental, "experimental",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      // NOTE(kalman): this is provided by a manifest property but needs to
+      // appear in the install permission dialogue, so we need a fake
+      // permission for it. See http://crbug.com/247857.
+      {APIPermission::kWebConnectable, "webConnectable",
+       APIPermissionInfo::kFlagCannotBeOptional |
+           APIPermissionInfo::kFlagInternal,
+       IDS_EXTENSION_PROMPT_WARNING_WEB_CONNECTABLE,
+       PermissionMessage::kWebConnectable},
+      {APIPermission::kGeolocation, "geolocation",
+       APIPermissionInfo::kFlagCannotBeOptional,
+       IDS_EXTENSION_PROMPT_WARNING_GEOLOCATION,
+       PermissionMessage::kGeolocation},
+      {APIPermission::kNotification, "notifications"},
+      {APIPermission::kUnlimitedStorage, "unlimitedStorage",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kGcm, "gcm"},
 
-        // Register extension permissions.
-        {APIPermission::kAccessibilityFeaturesModify,
-         "accessibilityFeatures.modify", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_ACCESSIBILITY_FEATURES_MODIFY,
-         PermissionMessage::kAccessibilityFeaturesModify},
-        {APIPermission::kAccessibilityFeaturesRead,
-         "accessibilityFeatures.read", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_ACCESSIBILITY_FEATURES_READ,
-         PermissionMessage::kAccessibilityFeaturesRead},
-        {APIPermission::kActiveTab, "activeTab"},
-        {APIPermission::kAdView, "adview"},
-        {APIPermission::kAlarms, "alarms"},
-        {APIPermission::kAutomation, "automation",
-         APIPermissionInfo::kFlagCannotBeOptional,
-         IDS_EXTENSION_PROMPT_WARNING_AUTOMATION,
-         PermissionMessage::kAutomation},
-        {APIPermission::kBookmark, "bookmarks", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_BOOKMARKS, PermissionMessage::kBookmarks},
-        {APIPermission::kBrailleDisplayPrivate, "brailleDisplayPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kBrowsingData, "browsingData"},
-        {APIPermission::kContentSettings, "contentSettings",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_CONTENT_SETTINGS,
-         PermissionMessage::kContentSettings},
-        {APIPermission::kContextMenus, "contextMenus"},
-        {APIPermission::kCookie, "cookies"},
-        {APIPermission::kFileBrowserHandler, "fileBrowserHandler",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kFontSettings, "fontSettings",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kHistory, "history", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_BROWSING_HISTORY,
-         PermissionMessage::kBrowsingHistory},
-        {APIPermission::kIdltest, "idltest"},
-        {APIPermission::kIdle, "idle"},
-        {APIPermission::kInfobars, "infobars"},
-        {APIPermission::kInput, "input", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_INPUT, PermissionMessage::kInput},
-        {APIPermission::kLocation, "location",
-         APIPermissionInfo::kFlagCannotBeOptional,
-         IDS_EXTENSION_PROMPT_WARNING_GEOLOCATION,
-         PermissionMessage::kGeolocation},
-        {APIPermission::kManagement, "management", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_MANAGEMENT,
-         PermissionMessage::kManagement},
-        {APIPermission::kNativeMessaging, "nativeMessaging",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_NATIVE_MESSAGING,
-         PermissionMessage::kNativeMessaging},
-        {APIPermission::kPower, "power", },
-        {APIPermission::kPrivacy, "privacy", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_PRIVACY, PermissionMessage::kPrivacy},
-        {APIPermission::kProcesses, "processes", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_TABS, PermissionMessage::kTabs},
-        {APIPermission::kSessions, "sessions"},
-        {APIPermission::kSignedInDevices, "signedInDevices",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_SIGNED_IN_DEVICES,
-         PermissionMessage::kSignedInDevices},
-        {APIPermission::kStorage, "storage"},
-        {APIPermission::kSyncFileSystem, "syncFileSystem",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_SYNCFILESYSTEM,
-         PermissionMessage::kSyncFileSystem},
-        {APIPermission::kTab, "tabs", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_TABS, PermissionMessage::kTabs},
-        {APIPermission::kTopSites, "topSites", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_BROWSING_HISTORY,
-         PermissionMessage::kBrowsingHistory},
-        {APIPermission::kTts, "tts", 0,
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kTtsEngine, "ttsEngine",
-         APIPermissionInfo::kFlagCannotBeOptional,
-         IDS_EXTENSION_PROMPT_WARNING_TTS_ENGINE,
-         PermissionMessage::kTtsEngine},
-        {APIPermission::kWallpaper, "wallpaper",
-         APIPermissionInfo::kFlagCannotBeOptional,
-         IDS_EXTENSION_PROMPT_WARNING_WALLPAPER, PermissionMessage::kWallpaper},
-        {APIPermission::kWebNavigation, "webNavigation",
-         APIPermissionInfo::kFlagNone, IDS_EXTENSION_PROMPT_WARNING_TABS,
-         PermissionMessage::kTabs},
-        {APIPermission::kWebRequest, "webRequest"},
-        {APIPermission::kWebRequestBlocking, "webRequestBlocking"},
-        {APIPermission::kWebView, "webview",
-         APIPermissionInfo::kFlagCannotBeOptional},
+      // Register extension permissions.
+      {APIPermission::kAccessibilityFeaturesModify,
+       "accessibilityFeatures.modify", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_ACCESSIBILITY_FEATURES_MODIFY,
+       PermissionMessage::kAccessibilityFeaturesModify},
+      {APIPermission::kAccessibilityFeaturesRead, "accessibilityFeatures.read",
+       APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_ACCESSIBILITY_FEATURES_READ,
+       PermissionMessage::kAccessibilityFeaturesRead},
+      {APIPermission::kAccessibilityPrivate, "accessibilityPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kActiveTab, "activeTab"},
+      {APIPermission::kAdView, "adview"},
+      {APIPermission::kAlarms, "alarms"},
+      {APIPermission::kBookmark, "bookmarks", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_BOOKMARKS, PermissionMessage::kBookmarks},
+      {APIPermission::kBrailleDisplayPrivate, "brailleDisplayPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kBrowsingData, "browsingData"},
+      {APIPermission::kContentSettings, "contentSettings",
+       APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_CONTENT_SETTINGS,
+       PermissionMessage::kContentSettings},
+      {APIPermission::kContextMenus, "contextMenus"},
+      {APIPermission::kCookie, "cookies"},
+      {APIPermission::kFileBrowserHandler, "fileBrowserHandler",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kFontSettings, "fontSettings",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kHistory, "history", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_BROWSING_HISTORY,
+       PermissionMessage::kBrowsingHistory},
+      {APIPermission::kIdltest, "idltest"},
+      {APIPermission::kIdle, "idle"},
+      {APIPermission::kInfobars, "infobars"},
+      {APIPermission::kInput, "input", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_INPUT, PermissionMessage::kInput},
+      {APIPermission::kLocation, "location",
+       APIPermissionInfo::kFlagCannotBeOptional,
+       IDS_EXTENSION_PROMPT_WARNING_GEOLOCATION,
+       PermissionMessage::kGeolocation},
+      {APIPermission::kManagement, "management", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_MANAGEMENT, PermissionMessage::kManagement},
+      {APIPermission::kNativeMessaging, "nativeMessaging",
+       APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_NATIVE_MESSAGING,
+       PermissionMessage::kNativeMessaging},
+      {APIPermission::kPower, "power"},
+      {APIPermission::kPrivacy, "privacy", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_PRIVACY, PermissionMessage::kPrivacy},
+      {APIPermission::kProcesses, "processes", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_TABS, PermissionMessage::kTabs},
+      {APIPermission::kSessions, "sessions"},
+      {APIPermission::kSignedInDevices, "signedInDevices",
+       APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_SIGNED_IN_DEVICES,
+       PermissionMessage::kSignedInDevices},
+      {APIPermission::kSyncFileSystem, "syncFileSystem",
+       APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_SYNCFILESYSTEM,
+       PermissionMessage::kSyncFileSystem},
+      {APIPermission::kTab, "tabs", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_TABS, PermissionMessage::kTabs},
+      {APIPermission::kTopSites, "topSites", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_BROWSING_HISTORY,
+       PermissionMessage::kBrowsingHistory},
+      {APIPermission::kTts, "tts", 0, APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kTtsEngine, "ttsEngine",
+       APIPermissionInfo::kFlagCannotBeOptional,
+       IDS_EXTENSION_PROMPT_WARNING_TTS_ENGINE, PermissionMessage::kTtsEngine},
+      {APIPermission::kWallpaper, "wallpaper",
+       APIPermissionInfo::kFlagCannotBeOptional,
+       IDS_EXTENSION_PROMPT_WARNING_WALLPAPER, PermissionMessage::kWallpaper},
+      {APIPermission::kWebNavigation, "webNavigation",
+       APIPermissionInfo::kFlagNone, IDS_EXTENSION_PROMPT_WARNING_TABS,
+       PermissionMessage::kTabs},
+      {APIPermission::kWebRequest, "webRequest"},
+      {APIPermission::kWebRequestBlocking, "webRequestBlocking"},
+      {APIPermission::kWebView, "webview",
+       APIPermissionInfo::kFlagCannotBeOptional},
 
-        // Register private permissions.
-        {APIPermission::kScreenlockPrivate, "screenlockPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional,
-         IDS_EXTENSION_PROMPT_WARNING_SCREENLOCK_PRIVATE,
-         PermissionMessage::kScreenlockPrivate},
-        {APIPermission::kActivityLogPrivate, "activityLogPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional,
-         IDS_EXTENSION_PROMPT_WARNING_ACTIVITY_LOG_PRIVATE,
-         PermissionMessage::kActivityLogPrivate},
-        {APIPermission::kAutoTestPrivate, "autotestPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kBookmarkManagerPrivate, "bookmarkManagerPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kCast, "cast",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kChromeosInfoPrivate, "chromeosInfoPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kCommandLinePrivate, "commandLinePrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kDeveloperPrivate, "developerPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kDiagnostics, "diagnostics",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kDial, "dial",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kDownloadsInternal, "downloadsInternal"},
-        {APIPermission::kFileBrowserHandlerInternal,
-         "fileBrowserHandlerInternal",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kFileBrowserPrivate, "fileBrowserPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kHotwordPrivate, "hotwordPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kIdentityPrivate, "identityPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kLogPrivate, "logPrivate"},
-        {APIPermission::kWebcamPrivate, "webcamPrivate"},
-        {APIPermission::kNetworkingPrivate, "networkingPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional,
-         IDS_EXTENSION_PROMPT_WARNING_NETWORKING_PRIVATE,
-         PermissionMessage::kNetworkingPrivate},
-        {APIPermission::kMediaPlayerPrivate, "mediaPlayerPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kMetricsPrivate, "metricsPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kMDns, "mdns",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kMusicManagerPrivate, "musicManagerPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional,
-         IDS_EXTENSION_PROMPT_WARNING_MUSIC_MANAGER_PRIVATE,
-         PermissionMessage::kMusicManagerPrivate},
-        {APIPermission::kPreferencesPrivate, "preferencesPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kSystemPrivate, "systemPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kCloudPrintPrivate, "cloudPrintPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kInputMethodPrivate, "inputMethodPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kEchoPrivate, "echoPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kFeedbackPrivate, "feedbackPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kImageWriterPrivate, "imageWriterPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kReadingListPrivate, "readingListPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kRtcPrivate, "rtcPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kTerminalPrivate, "terminalPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kVirtualKeyboardPrivate, "virtualKeyboardPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kWallpaperPrivate, "wallpaperPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kWebstorePrivate, "webstorePrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kMediaGalleriesPrivate, "mediaGalleriesPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kStreamsPrivate, "streamsPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kEnterprisePlatformKeysPrivate,
-         "enterprise.platformKeysPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kWebrtcAudioPrivate, "webrtcAudioPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kWebrtcLoggingPrivate, "webrtcLoggingPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kPrincipalsPrivate, "principalsPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kFirstRunPrivate, "firstRunPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kBluetoothPrivate, "bluetoothPrivate",
-         APIPermissionInfo::kFlagCannotBeOptional,
-         IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH_PRIVATE,
-         PermissionMessage::kBluetoothPrivate},
+      // Register private permissions.
+      {APIPermission::kScreenlockPrivate, "screenlockPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional,
+       IDS_EXTENSION_PROMPT_WARNING_SCREENLOCK_PRIVATE,
+       PermissionMessage::kScreenlockPrivate},
+      {APIPermission::kActivityLogPrivate, "activityLogPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional,
+       IDS_EXTENSION_PROMPT_WARNING_ACTIVITY_LOG_PRIVATE,
+       PermissionMessage::kActivityLogPrivate},
+      {APIPermission::kAutoTestPrivate, "autotestPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kBookmarkManagerPrivate, "bookmarkManagerPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kCast, "cast", APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kChromeosInfoPrivate, "chromeosInfoPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kCommandLinePrivate, "commandLinePrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kDeveloperPrivate, "developerPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kDiagnostics, "diagnostics",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kDial, "dial", APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kDownloadsInternal, "downloadsInternal"},
+      {APIPermission::kFileBrowserHandlerInternal, "fileBrowserHandlerInternal",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kFileBrowserPrivate, "fileBrowserPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kHotwordPrivate, "hotwordPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kIdentityPrivate, "identityPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kLogPrivate, "logPrivate"},
+      {APIPermission::kWebcamPrivate, "webcamPrivate"},
+      {APIPermission::kNetworkingPrivate, "networkingPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional,
+       IDS_EXTENSION_PROMPT_WARNING_NETWORKING_PRIVATE,
+       PermissionMessage::kNetworkingPrivate},
+      {APIPermission::kMediaPlayerPrivate, "mediaPlayerPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kMetricsPrivate, "metricsPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kMDns, "mdns", APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kMusicManagerPrivate, "musicManagerPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional,
+       IDS_EXTENSION_PROMPT_WARNING_MUSIC_MANAGER_PRIVATE,
+       PermissionMessage::kMusicManagerPrivate},
+      {APIPermission::kPreferencesPrivate, "preferencesPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kSystemPrivate, "systemPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kCloudPrintPrivate, "cloudPrintPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kInputMethodPrivate, "inputMethodPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kEchoPrivate, "echoPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kFeedbackPrivate, "feedbackPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kImageWriterPrivate, "imageWriterPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kReadingListPrivate, "readingListPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kRtcPrivate, "rtcPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kTerminalPrivate, "terminalPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kVirtualKeyboardPrivate, "virtualKeyboardPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kWallpaperPrivate, "wallpaperPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kWebstorePrivate, "webstorePrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kMediaGalleriesPrivate, "mediaGalleriesPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kStreamsPrivate, "streamsPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kEnterprisePlatformKeysPrivate,
+       "enterprise.platformKeysPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kWebrtcAudioPrivate, "webrtcAudioPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kWebrtcLoggingPrivate, "webrtcLoggingPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kPrincipalsPrivate, "principalsPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kFirstRunPrivate, "firstRunPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kBluetoothPrivate, "bluetoothPrivate",
+       APIPermissionInfo::kFlagCannotBeOptional,
+       IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH_PRIVATE,
+       PermissionMessage::kBluetoothPrivate},
 
-        // Full url access permissions.
-        {APIPermission::kDebugger, "debugger",
-         APIPermissionInfo::kFlagImpliesFullURLAccess |
-             APIPermissionInfo::kFlagCannotBeOptional,
-         IDS_EXTENSION_PROMPT_WARNING_DEBUGGER, PermissionMessage::kDebugger},
-        {APIPermission::kDevtools, "devtools",
-         APIPermissionInfo::kFlagImpliesFullURLAccess |
-             APIPermissionInfo::kFlagCannotBeOptional |
-             APIPermissionInfo::kFlagInternal},
-        {APIPermission::kPageCapture, "pageCapture",
-         APIPermissionInfo::kFlagImpliesFullURLAccess},
-        {APIPermission::kTabCapture, "tabCapture",
-         APIPermissionInfo::kFlagImpliesFullURLAccess},
-        {APIPermission::kTabCaptureForTab, "tabCaptureForTab",
-         APIPermissionInfo::kFlagInternal},
-        {APIPermission::kPlugin, "plugin",
-         APIPermissionInfo::kFlagImpliesFullURLAccess |
-             APIPermissionInfo::kFlagImpliesFullAccess |
-             APIPermissionInfo::kFlagCannotBeOptional |
-             APIPermissionInfo::kFlagInternal,
-         IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS,
-         PermissionMessage::kFullAccess},
-        {APIPermission::kProxy, "proxy",
-         APIPermissionInfo::kFlagImpliesFullURLAccess |
-             APIPermissionInfo::kFlagCannotBeOptional},
+      // Full url access permissions.
+      {APIPermission::kDebugger, "debugger",
+       APIPermissionInfo::kFlagImpliesFullURLAccess |
+           APIPermissionInfo::kFlagCannotBeOptional,
+       IDS_EXTENSION_PROMPT_WARNING_DEBUGGER, PermissionMessage::kDebugger},
+      {APIPermission::kDevtools, "devtools",
+       APIPermissionInfo::kFlagImpliesFullURLAccess |
+           APIPermissionInfo::kFlagCannotBeOptional |
+           APIPermissionInfo::kFlagInternal},
+      {APIPermission::kPageCapture, "pageCapture",
+       APIPermissionInfo::kFlagImpliesFullURLAccess},
+      {APIPermission::kTabCapture, "tabCapture",
+       APIPermissionInfo::kFlagImpliesFullURLAccess},
+      {APIPermission::kTabCaptureForTab, "tabCaptureForTab",
+       APIPermissionInfo::kFlagInternal},
+      {APIPermission::kPlugin, "plugin",
+       APIPermissionInfo::kFlagImpliesFullURLAccess |
+           APIPermissionInfo::kFlagImpliesFullAccess |
+           APIPermissionInfo::kFlagCannotBeOptional |
+           APIPermissionInfo::kFlagInternal,
+       IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS,
+       PermissionMessage::kFullAccess},
+      {APIPermission::kProxy, "proxy",
+       APIPermissionInfo::kFlagImpliesFullURLAccess |
+           APIPermissionInfo::kFlagCannotBeOptional},
 
-        // Platform-app permissions.
-        {APIPermission::kSerial, "serial", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_SERIAL, PermissionMessage::kSerial},
-        // Because warning messages for the "socket" permission vary based on
-        // the
-        // permissions parameters, no message ID or message text is specified
-        // here.
-        // The message ID and text used will be determined at run-time in the
-        // |SocketPermission| class.
-        {APIPermission::kSocket, "socket",
-         APIPermissionInfo::kFlagCannotBeOptional, 0, PermissionMessage::kNone,
-         &CreateAPIPermission<SocketPermission>},
-        {APIPermission::kAlwaysOnTopWindows, "app.window.alwaysOnTop"},
-        {APIPermission::kAudioCapture, "audioCapture",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_AUDIO_CAPTURE,
-         PermissionMessage::kAudioCapture},
-        {APIPermission::kVideoCapture, "videoCapture",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_VIDEO_CAPTURE,
-         PermissionMessage::kVideoCapture},
-        // The permission string for "fileSystem" is only shown when "write" or
-        // "directory" is present. Read-only access is only granted after the
-        // user
-        // has been shown a file or directory  chooser dialog and selected a
-        // file or
-        // directory . Selecting the file or directory  is considered consent to
-        // read it.
-        {APIPermission::kFileSystem, "fileSystem"},
-        {APIPermission::kFileSystemDirectory, "fileSystem.directory",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_FILE_SYSTEM_DIRECTORY,
-         PermissionMessage::kFileSystemDirectory},
-        {APIPermission::kFileSystemProvider, "fileSystemProvider"},
-        {APIPermission::kFileSystemRetainEntries, "fileSystem.retainEntries"},
-        {APIPermission::kFileSystemWrite, "fileSystem.write"},
-        {APIPermission::kFileSystemWriteDirectory, "fileSystem.writeDirectory",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_FILE_SYSTEM_WRITE_DIRECTORY,
-         PermissionMessage::kFileSystemWriteDirectory},
-        {APIPermission::kHid, "hid", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_HID, PermissionMessage::kHid},
-        // Because warning messages for the "mediaGalleries" permission vary
-        // based
-        // on the permissions parameters, no message ID or message text is
-        // specified here.
-        // The message ID and text used will be determined at run-time in the
-        // |MediaGalleriesPermission| class.
-        {APIPermission::kMediaGalleries, "mediaGalleries",
-         APIPermissionInfo::kFlagNone, 0, PermissionMessage::kNone,
-         &CreateAPIPermission<MediaGalleriesPermission>},
-        {APIPermission::kPushMessaging, "pushMessaging",
-         APIPermissionInfo::kFlagCannotBeOptional},
-        {APIPermission::kUsb, "usb", APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_USB, PermissionMessage::kUsb},
-        {APIPermission::kUsbDevice, "usbDevices", APIPermissionInfo::kFlagNone,
-         0, PermissionMessage::kNone,
-         &CreateAPIPermission<UsbDevicePermission>},
-        {APIPermission::kSystemIndicator, "systemIndicator",
-         APIPermissionInfo::kFlagNone,
-         IDS_EXTENSION_PROMPT_WARNING_SYSTEM_INDICATOR,
-         PermissionMessage::kSystemIndicator},
-        {APIPermission::kSystemCpu, "system.cpu"},
-        {APIPermission::kSystemMemory, "system.memory"},
-        {APIPermission::kSystemNetwork, "system.network"},
-        {APIPermission::kSystemDisplay, "system.display"},
-        {APIPermission::kSystemStorage, "system.storage"},
-        {APIPermission::kPointerLock, "pointerLock"},
-        {APIPermission::kFullscreen, "app.window.fullscreen"},
-        {APIPermission::kAudio, "audio"},
-        {APIPermission::kCastStreaming, "cast.streaming"},
-        {APIPermission::kOverrideEscFullscreen,
-         "app.window.fullscreen.overrideEsc"},
-        {APIPermission::kWindowShape, "app.window.shape"},
+      // Platform-app permissions.
+      {APIPermission::kSerial, "serial", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_SERIAL, PermissionMessage::kSerial},
+      {APIPermission::kAlwaysOnTopWindows, "app.window.alwaysOnTop"},
+      {APIPermission::kAudioCapture, "audioCapture",
+       APIPermissionInfo::kFlagNone, IDS_EXTENSION_PROMPT_WARNING_AUDIO_CAPTURE,
+       PermissionMessage::kAudioCapture},
+      {APIPermission::kVideoCapture, "videoCapture",
+       APIPermissionInfo::kFlagNone, IDS_EXTENSION_PROMPT_WARNING_VIDEO_CAPTURE,
+       PermissionMessage::kVideoCapture},
+      // The permission string for "fileSystem" is only shown when
+      // "write" or "directory" is present. Read-only access is only
+      // granted after the user has been shown a file or directory
+      // chooser dialog and selected a file or directory. Selecting
+      // the file or directory is considered consent to read it.
+      {APIPermission::kFileSystem, "fileSystem"},
+      {APIPermission::kFileSystemDirectory, "fileSystem.directory",
+       APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_FILE_SYSTEM_DIRECTORY,
+       PermissionMessage::kFileSystemDirectory},
+      {APIPermission::kFileSystemProvider, "fileSystemProvider"},
+      {APIPermission::kFileSystemRetainEntries, "fileSystem.retainEntries"},
+      {APIPermission::kFileSystemWrite, "fileSystem.write"},
+      {APIPermission::kFileSystemWriteDirectory, "fileSystem.writeDirectory",
+       APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_FILE_SYSTEM_WRITE_DIRECTORY,
+       PermissionMessage::kFileSystemWriteDirectory},
+      {APIPermission::kHid, "hid", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_HID, PermissionMessage::kHid},
+      // Because warning messages for the "mediaGalleries" permission
+      // vary based on the permissions parameters, no message ID or
+      // message text is specified here.  The message ID and text used
+      // will be determined at run-time in the
+      // |MediaGalleriesPermission| class.
+      {APIPermission::kMediaGalleries, "mediaGalleries",
+       APIPermissionInfo::kFlagNone, 0, PermissionMessage::kNone,
+       &CreateAPIPermission<MediaGalleriesPermission>},
+      {APIPermission::kPushMessaging, "pushMessaging",
+       APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kUsbDevice, "usbDevices", APIPermissionInfo::kFlagNone, 0,
+       PermissionMessage::kNone, &CreateAPIPermission<UsbDevicePermission>},
+      {APIPermission::kSystemCpu, "system.cpu"},
+      {APIPermission::kSystemMemory, "system.memory"},
+      {APIPermission::kSystemNetwork, "system.network"},
+      {APIPermission::kSystemDisplay, "system.display"},
+      {APIPermission::kSystemStorage, "system.storage"},
+      {APIPermission::kPointerLock, "pointerLock"},
+      {APIPermission::kFullscreen, "app.window.fullscreen"},
+      {APIPermission::kAudio, "audio"},
+      {APIPermission::kCastStreaming, "cast.streaming"},
+      {APIPermission::kOverrideEscFullscreen,
+       "app.window.fullscreen.overrideEsc"},
+      {APIPermission::kWindowShape, "app.window.shape"},
+      {APIPermission::kBrowser, "browser"},
 
-        // Settings override permissions.
-        {APIPermission::kHomepage, "homepage",
-         APIPermissionInfo::kFlagCannotBeOptional |
-             APIPermissionInfo::kFlagInternal,
-         IDS_EXTENSION_PROMPT_WARNING_HOME_PAGE_SETTING_OVERRIDE,
-         PermissionMessage::kHomepage},
-        {APIPermission::kSearchProvider, "searchProvider",
-         APIPermissionInfo::kFlagCannotBeOptional |
-             APIPermissionInfo::kFlagInternal,
-         IDS_EXTENSION_PROMPT_WARNING_SEARCH_SETTINGS_OVERRIDE,
-         PermissionMessage::kSearchProvider},
-        {APIPermission::kStartupPages, "startupPages",
-         APIPermissionInfo::kFlagCannotBeOptional |
-             APIPermissionInfo::kFlagInternal,
-         IDS_EXTENSION_PROMPT_WARNING_START_PAGE_SETTING_OVERRIDE,
-         PermissionMessage::kStartupPages}, };
+      // Settings override permissions.
+      {APIPermission::kHomepage, "homepage",
+       APIPermissionInfo::kFlagCannotBeOptional |
+           APIPermissionInfo::kFlagInternal,
+       IDS_EXTENSION_PROMPT_WARNING_HOME_PAGE_SETTING_OVERRIDE,
+       PermissionMessage::kHomepage},
+      {APIPermission::kSearchProvider, "searchProvider",
+       APIPermissionInfo::kFlagCannotBeOptional |
+           APIPermissionInfo::kFlagInternal,
+       IDS_EXTENSION_PROMPT_WARNING_SEARCH_SETTINGS_OVERRIDE,
+       PermissionMessage::kSearchProvider},
+      {APIPermission::kStartupPages, "startupPages",
+       APIPermissionInfo::kFlagCannotBeOptional |
+           APIPermissionInfo::kFlagInternal,
+       IDS_EXTENSION_PROMPT_WARNING_START_PAGE_SETTING_OVERRIDE,
+       PermissionMessage::kStartupPages},
+  };
 
   std::vector<APIPermissionInfo*> permissions;
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(PermissionsToRegister); ++i) {
-    const PermissionRegistration& pr = PermissionsToRegister[i];
-    permissions.push_back(new APIPermissionInfo(
-        pr.id, pr.name, pr.l10n_message_id,
-        pr.message_id ? pr.message_id : PermissionMessage::kNone,
-        pr.flags,
-        pr.constructor));
-  }
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(permissions_to_register); ++i)
+    permissions.push_back(new APIPermissionInfo(permissions_to_register[i]));
   return permissions;
 }
 
diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc
index 7884a2c..06df0f9 100644
--- a/chrome/common/extensions/permissions/permission_set_unittest.cc
+++ b/chrome/common/extensions/permissions/permission_set_unittest.cc
@@ -707,6 +707,7 @@
   skip.insert(APIPermission::kIdentity);
 
   // These are private.
+  skip.insert(APIPermission::kAccessibilityPrivate);
   skip.insert(APIPermission::kAutoTestPrivate);
   skip.insert(APIPermission::kBookmarkManagerPrivate);
   skip.insert(APIPermission::kBrailleDisplayPrivate);
@@ -751,6 +752,7 @@
   skip.insert(APIPermission::kDevtools);
 
   // Platform apps.
+  skip.insert(APIPermission::kBrowser);
   skip.insert(APIPermission::kFileSystem);
   skip.insert(APIPermission::kFileSystemProvider);
   skip.insert(APIPermission::kFileSystemRetainEntries);
diff --git a/chrome/common/extensions_api_resources.grd b/chrome/common/extensions_api_resources.grd
index 54d0806..6f77ab7 100644
--- a/chrome/common/extensions_api_resources.grd
+++ b/chrome/common/extensions_api_resources.grd
@@ -8,6 +8,7 @@
   </outputs>
   <release seq="1">
     <includes>
+      <include name="IDR_EXTENSION_API_JSON_ACCESSIBILITYPRIVATE" file="extensions\api\accessibility_private.json" type="BINDATA" />
       <include name="IDR_EXTENSION_API_JSON_APP" file="extensions\api\app.json" type="BINDATA" />
       <include name="IDR_EXTENSION_API_JSON_BROWSERACTION" file="extensions\api\browser_action.json" type="BINDATA" />
       <include name="IDR_EXTENSION_API_JSON_COMMANDS" file="extensions\api\commands.json" type="BINDATA" />
diff --git a/chrome/common/localized_error.cc b/chrome/common/localized_error.cc
index 46e1bc5..1645d11 100644
--- a/chrome/common/localized_error.cc
+++ b/chrome/common/localized_error.cc
@@ -490,7 +490,10 @@
 
 const char LocalizedError::kHttpErrorDomain[] = "http";
 
-LocalizedError::ErrorPageParams::ErrorPageParams() : suggest_reload(false) {
+LocalizedError::ErrorPageParams::ErrorPageParams()
+    : suggest_reload(false),
+      reload_tracking_id(-1),
+      search_tracking_id(-1) {
 }
 
 LocalizedError::ErrorPageParams::~ErrorPageParams() {
@@ -642,6 +645,7 @@
         l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_GOOGLE_SEARCH));
     error_strings->SetString("searchUrl", params->search_url.spec());
     error_strings->SetString("searchTerms", params->search_terms);
+    error_strings->SetInteger("searchTrackingId", params->search_tracking_id);
   }
 
   // Add the reload suggestion, if needed.
@@ -652,6 +656,7 @@
           "msg", l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_RELOAD));
       reload_button->SetString("reloadUrl", failed_url.spec());
       error_strings->Set("reloadButton", reload_button);
+      reload_button->SetInteger("reloadTrackingId", params->reload_tracking_id);
     } else {
       // If the page was created by a post, it can't be reloaded in the same
       // way, so just add a suggestion instead.
diff --git a/chrome/common/localized_error.h b/chrome/common/localized_error.h
index fe40b93..b4d69ff 100644
--- a/chrome/common/localized_error.h
+++ b/chrome/common/localized_error.h
@@ -34,6 +34,7 @@
 
     // Overrides whether reloading is suggested.
     bool suggest_reload;
+    int reload_tracking_id;
 
     // Overrides default suggestions.  Each entry must contain a header and may
     // optionally contain a body as well.  Must not be NULL.
@@ -45,6 +46,7 @@
     GURL search_url;
     // Default search terms.  Ignored if |search_url| is invalid.
     std::string search_terms;
+    int search_tracking_id;
   };
 
   // Fills |error_strings| with values to be used to build an error page used
diff --git a/chrome/common/metrics/metrics_log_base.cc b/chrome/common/metrics/metrics_log_base.cc
deleted file mode 100644
index 3eb4972..0000000
--- a/chrome/common/metrics/metrics_log_base.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/common/metrics/metrics_log_base.h"
-
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_samples.h"
-#include "chrome/common/chrome_version_info.h"
-#include "chrome/common/metrics/proto/histogram_event.pb.h"
-#include "chrome/common/metrics/proto/system_profile.pb.h"
-#include "chrome/common/metrics/proto/user_action_event.pb.h"
-#include "components/metrics/metrics_hashes.h"
-
-using base::Histogram;
-using base::HistogramBase;
-using base::HistogramSamples;
-using base::SampleCountIterator;
-using base::Time;
-using base::TimeDelta;
-using metrics::HistogramEventProto;
-using metrics::SystemProfileProto;
-using metrics::UserActionEventProto;
-
-namespace {
-
-// Any id less than 16 bytes is considered to be a testing id.
-bool IsTestingID(const std::string& id) {
-  return id.size() < 16;
-}
-
-SystemProfileProto::Channel AsProtobufChannel(
-    chrome::VersionInfo::Channel channel) {
-  switch (channel) {
-    case chrome::VersionInfo::CHANNEL_UNKNOWN:
-      return SystemProfileProto::CHANNEL_UNKNOWN;
-    case chrome::VersionInfo::CHANNEL_CANARY:
-      return SystemProfileProto::CHANNEL_CANARY;
-    case chrome::VersionInfo::CHANNEL_DEV:
-      return SystemProfileProto::CHANNEL_DEV;
-    case chrome::VersionInfo::CHANNEL_BETA:
-      return SystemProfileProto::CHANNEL_BETA;
-    case chrome::VersionInfo::CHANNEL_STABLE:
-      return SystemProfileProto::CHANNEL_STABLE;
-    default:
-      NOTREACHED();
-      return SystemProfileProto::CHANNEL_UNKNOWN;
-  }
-}
-
-}  // namespace
-
-MetricsLogBase::MetricsLogBase(const std::string& client_id,
-                               int session_id,
-                               LogType log_type,
-                               const std::string& version_string)
-    : num_events_(0),
-      locked_(false),
-      log_type_(log_type) {
-  DCHECK_NE(NO_LOG, log_type);
-  if (IsTestingID(client_id))
-    uma_proto_.set_client_id(0);
-  else
-    uma_proto_.set_client_id(Hash(client_id));
-
-  uma_proto_.set_session_id(session_id);
-  uma_proto_.mutable_system_profile()->set_build_timestamp(GetBuildTime());
-  uma_proto_.mutable_system_profile()->set_app_version(version_string);
-  uma_proto_.mutable_system_profile()->set_channel(
-      AsProtobufChannel(chrome::VersionInfo::GetChannel()));
-}
-
-MetricsLogBase::~MetricsLogBase() {}
-
-// static
-uint64 MetricsLogBase::Hash(const std::string& value) {
-  uint64 hash = metrics::HashMetricName(value);
-
-  // The following log is VERY helpful when folks add some named histogram into
-  // the code, but forgot to update the descriptive list of histograms.  When
-  // that happens, all we get to see (server side) is a hash of the histogram
-  // name.  We can then use this logging to find out what histogram name was
-  // being hashed to a given MD5 value by just running the version of Chromium
-  // in question with --enable-logging.
-  DVLOG(1) << "Metrics: Hash numeric [" << value << "]=[" << hash << "]";
-
-  return hash;
-}
-
-// static
-int64 MetricsLogBase::GetBuildTime() {
-  static int64 integral_build_time = 0;
-  if (!integral_build_time) {
-    Time time;
-    const char* kDateTime = __DATE__ " " __TIME__ " GMT";
-    bool result = Time::FromString(kDateTime, &time);
-    DCHECK(result);
-    integral_build_time = static_cast<int64>(time.ToTimeT());
-  }
-  return integral_build_time;
-}
-
-// static
-int64 MetricsLogBase::GetCurrentTime() {
-  return (base::TimeTicks::Now() - base::TimeTicks()).InSeconds();
-}
-
-void MetricsLogBase::CloseLog() {
-  DCHECK(!locked_);
-  locked_ = true;
-}
-
-void MetricsLogBase::GetEncodedLog(std::string* encoded_log) {
-  DCHECK(locked_);
-  uma_proto_.SerializeToString(encoded_log);
-}
-
-void MetricsLogBase::RecordUserAction(const std::string& key) {
-  DCHECK(!locked_);
-
-  UserActionEventProto* user_action = uma_proto_.add_user_action_event();
-  user_action->set_name_hash(Hash(key));
-  user_action->set_time(GetCurrentTime());
-
-  ++num_events_;
-}
-
-void MetricsLogBase::RecordHistogramDelta(const std::string& histogram_name,
-                                          const HistogramSamples& snapshot) {
-  DCHECK(!locked_);
-  DCHECK_NE(0, snapshot.TotalCount());
-
-  // We will ignore the MAX_INT/infinite value in the last element of range[].
-
-  HistogramEventProto* histogram_proto = uma_proto_.add_histogram_event();
-  histogram_proto->set_name_hash(Hash(histogram_name));
-  histogram_proto->set_sum(snapshot.sum());
-
-  for (scoped_ptr<SampleCountIterator> it = snapshot.Iterator();
-       !it->Done();
-       it->Next()) {
-    HistogramBase::Sample min;
-    HistogramBase::Sample max;
-    HistogramBase::Count count;
-    it->Get(&min, &max, &count);
-    HistogramEventProto::Bucket* bucket = histogram_proto->add_bucket();
-    bucket->set_min(min);
-    bucket->set_max(max);
-    bucket->set_count(count);
-  }
-
-  // Omit fields to save space (see rules in histogram_event.proto comments).
-  for (int i = 0; i < histogram_proto->bucket_size(); ++i) {
-    HistogramEventProto::Bucket* bucket = histogram_proto->mutable_bucket(i);
-    if (i + 1 < histogram_proto->bucket_size() &&
-        bucket->max() == histogram_proto->bucket(i + 1).min()) {
-      bucket->clear_max();
-    } else if (bucket->max() == bucket->min() + 1) {
-      bucket->clear_min();
-    }
-  }
-}
diff --git a/chrome/common/metrics/metrics_log_base.h b/chrome/common/metrics/metrics_log_base.h
deleted file mode 100644
index f0124d8..0000000
--- a/chrome/common/metrics/metrics_log_base.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2012 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.
-
-// This file defines a set of user experience metrics data recorded by
-// the MetricsService.  This is the unit of data that is sent to the server.
-
-#ifndef CHROME_COMMON_METRICS_METRICS_LOG_BASE_H_
-#define CHROME_COMMON_METRICS_METRICS_LOG_BASE_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/metrics/histogram.h"
-#include "base/time/time.h"
-#include "chrome/common/metrics/proto/chrome_user_metrics_extension.pb.h"
-#include "content/public/common/page_transition_types.h"
-
-class GURL;
-
-namespace base {
-class HistogramSamples;
-}  // namespace base
-
-// This class provides base functionality for logging metrics data.
-class MetricsLogBase {
- public:
-  // TODO(asvitkine): Remove the NO_LOG value.
-  enum LogType {
-    INITIAL_STABILITY_LOG,  // The initial log containing stability stats.
-    ONGOING_LOG,            // Subsequent logs in a session.
-    NO_LOG,                 // Placeholder value for when there is no log.
-  };
-
-  // Creates a new metrics log of the specified type.
-  // client_id is the identifier for this profile on this installation
-  // session_id is an integer that's incremented on each application launch
-  MetricsLogBase(const std::string& client_id,
-                 int session_id,
-                 LogType log_type,
-                 const std::string& version_string);
-  virtual ~MetricsLogBase();
-
-  // Computes the MD5 hash of the given string, and returns the first 8 bytes of
-  // the hash.
-  static uint64 Hash(const std::string& value);
-
-  // Get the GMT buildtime for the current binary, expressed in seconds since
-  // January 1, 1970 GMT.
-  // The value is used to identify when a new build is run, so that previous
-  // reliability stats, from other builds, can be abandoned.
-  static int64 GetBuildTime();
-
-  // Convenience function to return the current time at a resolution in seconds.
-  // This wraps base::TimeTicks, and hence provides an abstract time that is
-  // always incrementing for use in measuring time durations.
-  static int64 GetCurrentTime();
-
-  // Records a user-initiated action.
-  void RecordUserAction(const std::string& key);
-
-  // Record any changes in a given histogram for transmission.
-  void RecordHistogramDelta(const std::string& histogram_name,
-                            const base::HistogramSamples& snapshot);
-
-  // Stop writing to this record and generate the encoded representation.
-  // None of the Record* methods can be called after this is called.
-  void CloseLog();
-
-  // Fills |encoded_log| with the serialized protobuf representation of the
-  // record.  Must only be called after CloseLog() has been called.
-  void GetEncodedLog(std::string* encoded_log);
-
-  int num_events() { return num_events_; }
-
-  void set_hardware_class(const std::string& hardware_class) {
-    uma_proto_.mutable_system_profile()->mutable_hardware()->set_hardware_class(
-        hardware_class);
-  }
-
-  LogType log_type() const { return log_type_; }
-
- protected:
-  bool locked() const { return locked_; }
-
-  metrics::ChromeUserMetricsExtension* uma_proto() { return &uma_proto_; }
-  const metrics::ChromeUserMetricsExtension* uma_proto() const {
-    return &uma_proto_;
-  }
-
-  // TODO(isherman): Remove this once the XML pipeline is outta here.
-  int num_events_;  // the number of events recorded in this log
-
- private:
-  // locked_ is true when record has been packed up for sending, and should
-  // no longer be written to.  It is only used for sanity checking and is
-  // not a real lock.
-  bool locked_;
-
-  // The type of the log, i.e. initial or ongoing.
-  const LogType log_type_;
-
-  // Stores the protocol buffer representation for this log.
-  metrics::ChromeUserMetricsExtension uma_proto_;
-
-  DISALLOW_COPY_AND_ASSIGN(MetricsLogBase);
-};
-
-#endif  // CHROME_COMMON_METRICS_METRICS_LOG_BASE_H_
diff --git a/chrome/common/metrics/metrics_log_base_unittest.cc b/chrome/common/metrics/metrics_log_base_unittest.cc
deleted file mode 100644
index 4c77f60..0000000
--- a/chrome/common/metrics/metrics_log_base_unittest.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/common/metrics/metrics_log_base.h"
-
-#include <string>
-
-#include "base/base64.h"
-#include "base/metrics/bucket_ranges.h"
-#include "base/metrics/sample_vector.h"
-#include "chrome/common/metrics/proto/chrome_user_metrics_extension.pb.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-class TestMetricsLogBase : public MetricsLogBase {
- public:
-  TestMetricsLogBase()
-      : MetricsLogBase("client_id", 1, MetricsLogBase::ONGOING_LOG, "1.2.3.4") {
-  }
-  virtual ~TestMetricsLogBase() {}
-
-  using MetricsLogBase::uma_proto;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestMetricsLogBase);
-};
-
-}  // namespace
-
-TEST(MetricsLogBaseTest, LogType) {
-  MetricsLogBase log1("id", 0, MetricsLogBase::ONGOING_LOG, "1.2.3");
-  EXPECT_EQ(MetricsLogBase::ONGOING_LOG, log1.log_type());
-
-  MetricsLogBase log2("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "1.2.3");
-  EXPECT_EQ(MetricsLogBase::INITIAL_STABILITY_LOG, log2.log_type());
-}
-
-TEST(MetricsLogBaseTest, EmptyRecord) {
-  MetricsLogBase log("totally bogus client ID", 137,
-                     MetricsLogBase::ONGOING_LOG, "bogus version");
-  log.set_hardware_class("sample-class");
-  log.CloseLog();
-
-  std::string encoded;
-  log.GetEncodedLog(&encoded);
-
-  // A couple of fields are hard to mock, so these will be copied over directly
-  // for the expected output.
-  metrics::ChromeUserMetricsExtension parsed;
-  ASSERT_TRUE(parsed.ParseFromString(encoded));
-
-  metrics::ChromeUserMetricsExtension expected;
-  expected.set_client_id(5217101509553811875);  // Hashed bogus client ID
-  expected.set_session_id(137);
-  expected.mutable_system_profile()->set_build_timestamp(
-      parsed.system_profile().build_timestamp());
-  expected.mutable_system_profile()->set_app_version("bogus version");
-  expected.mutable_system_profile()->set_channel(
-      parsed.system_profile().channel());
-  expected.mutable_system_profile()->mutable_hardware()->set_hardware_class(
-      "sample-class");
-
-  EXPECT_EQ(expected.SerializeAsString(), encoded);
-}
-
-TEST(MetricsLogBaseTest, HistogramBucketFields) {
-  // Create buckets: 1-5, 5-7, 7-8, 8-9, 9-10, 10-11, 11-12.
-  base::BucketRanges ranges(8);
-  ranges.set_range(0, 1);
-  ranges.set_range(1, 5);
-  ranges.set_range(2, 7);
-  ranges.set_range(3, 8);
-  ranges.set_range(4, 9);
-  ranges.set_range(5, 10);
-  ranges.set_range(6, 11);
-  ranges.set_range(7, 12);
-
-  base::SampleVector samples(&ranges);
-  samples.Accumulate(3, 1);  // Bucket 1-5.
-  samples.Accumulate(6, 1);  // Bucket 5-7.
-  samples.Accumulate(8, 1);  // Bucket 8-9. (7-8 skipped)
-  samples.Accumulate(10, 1);  // Bucket 10-11. (9-10 skipped)
-  samples.Accumulate(11, 1);  // Bucket 11-12.
-
-  TestMetricsLogBase log;
-  log.RecordHistogramDelta("Test", samples);
-
-  const metrics::ChromeUserMetricsExtension* uma_proto = log.uma_proto();
-  const metrics::HistogramEventProto& histogram_proto =
-      uma_proto->histogram_event(uma_proto->histogram_event_size() - 1);
-
-  // Buckets with samples: 1-5, 5-7, 8-9, 10-11, 11-12.
-  // Should become: 1-/, 5-7, /-9, 10-/, /-12.
-  ASSERT_EQ(5, histogram_proto.bucket_size());
-
-  // 1-5 becomes 1-/ (max is same as next min).
-  EXPECT_TRUE(histogram_proto.bucket(0).has_min());
-  EXPECT_FALSE(histogram_proto.bucket(0).has_max());
-  EXPECT_EQ(1, histogram_proto.bucket(0).min());
-
-  // 5-7 stays 5-7 (no optimization possible).
-  EXPECT_TRUE(histogram_proto.bucket(1).has_min());
-  EXPECT_TRUE(histogram_proto.bucket(1).has_max());
-  EXPECT_EQ(5, histogram_proto.bucket(1).min());
-  EXPECT_EQ(7, histogram_proto.bucket(1).max());
-
-  // 8-9 becomes /-9 (min is same as max - 1).
-  EXPECT_FALSE(histogram_proto.bucket(2).has_min());
-  EXPECT_TRUE(histogram_proto.bucket(2).has_max());
-  EXPECT_EQ(9, histogram_proto.bucket(2).max());
-
-  // 10-11 becomes 10-/ (both optimizations apply, omit max is prioritized).
-  EXPECT_TRUE(histogram_proto.bucket(3).has_min());
-  EXPECT_FALSE(histogram_proto.bucket(3).has_max());
-  EXPECT_EQ(10, histogram_proto.bucket(3).min());
-
-  // 11-12 becomes /-12 (last record must keep max, min is same as max - 1).
-  EXPECT_FALSE(histogram_proto.bucket(4).has_min());
-  EXPECT_TRUE(histogram_proto.bucket(4).has_max());
-  EXPECT_EQ(12, histogram_proto.bucket(4).max());
-}
diff --git a/chrome/common/metrics/metrics_log_manager.cc b/chrome/common/metrics/metrics_log_manager.cc
deleted file mode 100644
index bd49de9..0000000
--- a/chrome/common/metrics/metrics_log_manager.cc
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/common/metrics/metrics_log_manager.h"
-
-#include <algorithm>
-
-#include "base/metrics/histogram.h"
-#include "base/sha1.h"
-#include "base/strings/string_util.h"
-#include "base/timer/elapsed_timer.h"
-#include "chrome/common/metrics/metrics_log_base.h"
-
-MetricsLogManager::SerializedLog::SerializedLog() {}
-MetricsLogManager::SerializedLog::~SerializedLog() {}
-
-bool MetricsLogManager::SerializedLog::IsEmpty() const {
-  return log_text_.empty();
-}
-
-void MetricsLogManager::SerializedLog::SwapLogText(std::string* log_text) {
-  log_text_.swap(*log_text);
-  if (log_text_.empty())
-    log_hash_.clear();
-  else
-    log_hash_ = base::SHA1HashString(log_text_);
-}
-
-void MetricsLogManager::SerializedLog::Clear() {
-  log_text_.clear();
-  log_hash_.clear();
-}
-
-void MetricsLogManager::SerializedLog::Swap(
-    MetricsLogManager::SerializedLog* other) {
-  log_text_.swap(other->log_text_);
-  log_hash_.swap(other->log_hash_);
-}
-
-MetricsLogManager::MetricsLogManager()
-    : unsent_logs_loaded_(false),
-      staged_log_type_(MetricsLogBase::NO_LOG),
-      max_ongoing_log_store_size_(0),
-      last_provisional_store_index_(-1),
-      last_provisional_store_type_(MetricsLogBase::INITIAL_STABILITY_LOG) {}
-
-MetricsLogManager::~MetricsLogManager() {}
-
-void MetricsLogManager::BeginLoggingWithLog(MetricsLogBase* log) {
-  DCHECK(!current_log_.get());
-  current_log_.reset(log);
-}
-
-void MetricsLogManager::FinishCurrentLog() {
-  DCHECK(current_log_.get());
-  current_log_->CloseLog();
-  SerializedLog compressed_log;
-  CompressCurrentLog(&compressed_log);
-  if (!compressed_log.IsEmpty())
-    StoreLog(&compressed_log, current_log_->log_type(), NORMAL_STORE);
-  current_log_.reset();
-}
-
-void MetricsLogManager::StageNextLogForUpload() {
-  // Prioritize initial logs for uploading.
-  std::vector<SerializedLog>* source_list =
-      unsent_initial_logs_.empty() ? &unsent_ongoing_logs_
-                                   : &unsent_initial_logs_;
-  LogType source_type = (source_list == &unsent_ongoing_logs_) ?
-      MetricsLogBase::ONGOING_LOG : MetricsLogBase::INITIAL_STABILITY_LOG;
-  // CHECK, rather than DCHECK, because swap()ing with an empty list causes
-  // hard-to-identify crashes much later.
-  CHECK(!source_list->empty());
-  DCHECK(staged_log_.IsEmpty());
-  DCHECK_EQ(MetricsLogBase::NO_LOG, staged_log_type_);
-  staged_log_.Swap(&source_list->back());
-  staged_log_type_ = source_type;
-  source_list->pop_back();
-
-  // If the staged log was the last provisional store, clear that.
-  if (last_provisional_store_index_ != -1) {
-    if (source_type == last_provisional_store_type_ &&
-        static_cast<unsigned int>(last_provisional_store_index_) ==
-            source_list->size()) {
-      last_provisional_store_index_ = -1;
-    }
-  }
-}
-
-bool MetricsLogManager::has_staged_log() const {
-  return !staged_log_.IsEmpty();
-}
-
-void MetricsLogManager::DiscardStagedLog() {
-  staged_log_.Clear();
-  staged_log_type_ = MetricsLogBase::NO_LOG;
-}
-
-void MetricsLogManager::DiscardCurrentLog() {
-  current_log_->CloseLog();
-  current_log_.reset();
-}
-
-void MetricsLogManager::PauseCurrentLog() {
-  DCHECK(!paused_log_.get());
-  paused_log_.reset(current_log_.release());
-}
-
-void MetricsLogManager::ResumePausedLog() {
-  DCHECK(!current_log_.get());
-  current_log_.reset(paused_log_.release());
-}
-
-void MetricsLogManager::StoreStagedLogAsUnsent(StoreType store_type) {
-  DCHECK(has_staged_log());
-
-  // If compressing the log failed, there's nothing to store.
-  if (staged_log_.IsEmpty())
-    return;
-
-  StoreLog(&staged_log_, staged_log_type_, store_type);
-  DiscardStagedLog();
-}
-
-void MetricsLogManager::StoreLog(SerializedLog* log,
-                                 LogType log_type,
-                                 StoreType store_type) {
-  DCHECK_NE(MetricsLogBase::NO_LOG, log_type);
-  std::vector<SerializedLog>* destination_list =
-      (log_type == MetricsLogBase::INITIAL_STABILITY_LOG) ?
-      &unsent_initial_logs_ : &unsent_ongoing_logs_;
-  destination_list->push_back(SerializedLog());
-  destination_list->back().Swap(log);
-
-  if (store_type == PROVISIONAL_STORE) {
-    last_provisional_store_index_ = destination_list->size() - 1;
-    last_provisional_store_type_ = log_type;
-  }
-}
-
-void MetricsLogManager::DiscardLastProvisionalStore() {
-  if (last_provisional_store_index_ == -1)
-    return;
-  std::vector<SerializedLog>* source_list =
-      (last_provisional_store_type_ == MetricsLogBase::ONGOING_LOG) ?
-          &unsent_ongoing_logs_ : &unsent_initial_logs_;
-  DCHECK_LT(static_cast<unsigned int>(last_provisional_store_index_),
-            source_list->size());
-  source_list->erase(source_list->begin() + last_provisional_store_index_);
-  last_provisional_store_index_ = -1;
-}
-
-void MetricsLogManager::PersistUnsentLogs() {
-  DCHECK(log_serializer_.get());
-  if (!log_serializer_.get())
-    return;
-  DCHECK(unsent_logs_loaded_);
-  if (!unsent_logs_loaded_)
-    return;
-
-  base::ElapsedTimer timer;
-  // Remove any ongoing logs that are over the serialization size limit.
-  if (max_ongoing_log_store_size_) {
-    for (std::vector<SerializedLog>::iterator it = unsent_ongoing_logs_.begin();
-         it != unsent_ongoing_logs_.end();) {
-      size_t log_size = it->log_text().length();
-      if (log_size > max_ongoing_log_store_size_) {
-        UMA_HISTOGRAM_COUNTS("UMA.Large Accumulated Log Not Persisted",
-                             static_cast<int>(log_size));
-        it = unsent_ongoing_logs_.erase(it);
-      } else {
-        ++it;
-      }
-    }
-  }
-  log_serializer_->SerializeLogs(unsent_initial_logs_,
-                                 MetricsLogBase::INITIAL_STABILITY_LOG);
-  log_serializer_->SerializeLogs(unsent_ongoing_logs_,
-                                 MetricsLogBase::ONGOING_LOG);
-  UMA_HISTOGRAM_TIMES("UMA.StoreLogsTime", timer.Elapsed());
-}
-
-void MetricsLogManager::LoadPersistedUnsentLogs() {
-  DCHECK(log_serializer_.get());
-  if (!log_serializer_.get())
-    return;
-
-  base::ElapsedTimer timer;
-  log_serializer_->DeserializeLogs(MetricsLogBase::INITIAL_STABILITY_LOG,
-                                   &unsent_initial_logs_);
-  log_serializer_->DeserializeLogs(MetricsLogBase::ONGOING_LOG,
-                                   &unsent_ongoing_logs_);
-  UMA_HISTOGRAM_TIMES("UMA.LoadLogsTime", timer.Elapsed());
-
-  unsent_logs_loaded_ = true;
-}
-
-void MetricsLogManager::CompressCurrentLog(SerializedLog* compressed_log) {
-  std::string log_text;
-  current_log_->GetEncodedLog(&log_text);
-  compressed_log->SwapLogText(&log_text);
-}
diff --git a/chrome/common/metrics/metrics_log_manager.h b/chrome/common/metrics/metrics_log_manager.h
deleted file mode 100644
index d9ff380..0000000
--- a/chrome/common/metrics/metrics_log_manager.h
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_COMMON_METRICS_METRICS_LOG_MANAGER_H_
-#define CHROME_COMMON_METRICS_METRICS_LOG_MANAGER_H_
-
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/common/metrics/metrics_log_base.h"
-
-// Manages all the log objects used by a MetricsService implementation. Keeps
-// track of both an in progress log and a log that is staged for uploading as
-// text, as well as saving logs to, and loading logs from, persistent storage.
-class MetricsLogManager {
- public:
-  typedef MetricsLogBase::LogType LogType;
-
-  MetricsLogManager();
-  ~MetricsLogManager();
-
-  class SerializedLog {
-   public:
-    SerializedLog();
-    ~SerializedLog();
-
-    const std::string& log_text() const { return log_text_; }
-    const std::string& log_hash() const { return log_hash_; }
-
-    // Returns true if the log is empty.
-    bool IsEmpty() const;
-
-    // Swaps log text with |log_text| and updates the hash. This is more
-    // performant than a regular setter as it avoids doing a large string copy.
-    void SwapLogText(std::string* log_text);
-
-    // Clears the log.
-    void Clear();
-
-    // Swaps log contents with |other|.
-    void Swap(SerializedLog* other);
-
-   private:
-    // Non-human readable log text (serialized proto).
-    std::string log_text_;
-
-    // Non-human readable SHA1 of |log_text| or empty if |log_text| is empty.
-    std::string log_hash_;
-
-    // Intentionally omits DISALLOW_COPY_AND_ASSIGN() so that it can be used
-    // in std::vector<SerializedLog>.
-  };
-
-  enum StoreType {
-    NORMAL_STORE,       // A standard store operation.
-    PROVISIONAL_STORE,  // A store operation that can be easily reverted later.
-  };
-
-  // Takes ownership of |log| and makes it the current_log. This should only be
-  // called if there is not a current log.
-  void BeginLoggingWithLog(MetricsLogBase* log);
-
-  // Returns the in-progress log.
-  MetricsLogBase* current_log() { return current_log_.get(); }
-
-  // Closes current_log(), compresses it, and stores the compressed log for
-  // later, leaving current_log() NULL.
-  void FinishCurrentLog();
-
-  // Returns true if there are any logs waiting to be uploaded.
-  bool has_unsent_logs() const {
-    return !unsent_initial_logs_.empty() || !unsent_ongoing_logs_.empty();
-  }
-
-  // Populates staged_log_text() with the next stored log to send.
-  // Should only be called if has_unsent_logs() is true.
-  void StageNextLogForUpload();
-
-  // Returns true if there is a log that needs to be, or is being, uploaded.
-  bool has_staged_log() const;
-
-  // The text of the staged log, as a serialized protobuf. Empty if there is no
-  // staged log, or if compression of the staged log failed.
-  const std::string& staged_log_text() const { return staged_log_.log_text(); }
-
-  // The SHA1 hash (non-human readable) of the staged log or empty if there is
-  // no staged log.
-  const std::string& staged_log_hash() const { return staged_log_.log_hash(); }
-
-  // Discards the staged log.
-  void DiscardStagedLog();
-
-  // Closes and discards |current_log|.
-  void DiscardCurrentLog();
-
-  // Sets current_log to NULL, but saves the current log for future use with
-  // ResumePausedLog(). Only one log may be paused at a time.
-  // TODO(stuartmorgan): Pause/resume support is really a workaround for a
-  // design issue in initial log writing; that should be fixed, and pause/resume
-  // removed.
-  void PauseCurrentLog();
-
-  // Restores the previously paused log (if any) to current_log().
-  // This should only be called if there is not a current log.
-  void ResumePausedLog();
-
-  // Saves the staged log, then clears staged_log().
-  // If |store_type| is PROVISIONAL_STORE, it can be dropped from storage with
-  // a later call to DiscardLastProvisionalStore (if it hasn't already been
-  // staged again).
-  // This is intended to be used when logs are being saved while an upload is in
-  // progress, in case the upload later succeeds.
-  // This can only be called if has_staged_log() is true.
-  void StoreStagedLogAsUnsent(StoreType store_type);
-
-  // Discards the last log stored with StoreStagedLogAsUnsent with |store_type|
-  // set to PROVISIONAL_STORE, as long as it hasn't already been re-staged. If
-  // the log is no longer present, this is a no-op.
-  void DiscardLastProvisionalStore();
-
-  // Sets the threshold for how large an onging log can be and still be written
-  // to persistant storage. Ongoing logs larger than this will be discarded
-  // before persisting. 0 is interpreted as no limit.
-  void set_max_ongoing_log_store_size(size_t max_size) {
-    max_ongoing_log_store_size_ = max_size;
-  }
-
-  // Interface for a utility class to serialize and deserialize logs for
-  // persistent storage.
-  class LogSerializer {
-   public:
-    virtual ~LogSerializer() {}
-
-    // Serializes |logs| to persistent storage, replacing any previously
-    // serialized logs of the same type.
-    virtual void SerializeLogs(const std::vector<SerializedLog>& logs,
-                               LogType log_type) = 0;
-
-    // Populates |logs| with logs of type |log_type| deserialized from
-    // persistent storage.
-    virtual void DeserializeLogs(LogType log_type,
-                                 std::vector<SerializedLog>* logs) = 0;
-  };
-
-  // Sets the serializer to use for persisting and loading logs; takes ownership
-  // of |serializer|.
-  void set_log_serializer(LogSerializer* serializer) {
-    log_serializer_.reset(serializer);
-  }
-
-  // Saves any unsent logs to persistent storage using the current log
-  // serializer. Can only be called after set_log_serializer.
-  void PersistUnsentLogs();
-
-  // Loads any unsent logs from persistent storage using the current log
-  // serializer. Can only be called after set_log_serializer.
-  void LoadPersistedUnsentLogs();
-
- private:
-  // Saves |log| as the given type (or discards it in accordance with
-  // |max_ongoing_log_store_size_|).
-  // NOTE: This clears the contents of |log| (to avoid an expensive copy),
-  // so the log should be discarded after this call.
-  void StoreLog(SerializedLog* log,
-                LogType log_type,
-                StoreType store_type);
-
-  // Compresses |current_log_| into |compressed_log|.
-  void CompressCurrentLog(SerializedLog* compressed_log);
-
-  // Tracks whether unsent logs (if any) have been loaded from the serializer.
-  bool unsent_logs_loaded_;
-
-  // The log that we are still appending to.
-  scoped_ptr<MetricsLogBase> current_log_;
-
-  // A paused, previously-current log.
-  scoped_ptr<MetricsLogBase> paused_log_;
-
-  // Helper class to handle serialization/deserialization of logs for persistent
-  // storage. May be NULL.
-  scoped_ptr<LogSerializer> log_serializer_;
-
-  // The current staged log, ready for upload to the server.
-  SerializedLog staged_log_;
-  LogType staged_log_type_;
-
-  // Logs from a previous session that have not yet been sent.
-  // Note that the vector has the oldest logs listed first (early in the
-  // vector), and we'll discard old logs if we have gathered too many logs.
-  std::vector<SerializedLog> unsent_initial_logs_;
-  std::vector<SerializedLog> unsent_ongoing_logs_;
-
-  size_t max_ongoing_log_store_size_;
-
-  // The index and type of the last provisional store. If nothing has been
-  // provisionally stored, or the last provisional store has already been
-  // re-staged, the index will be -1;
-  // This is necessary because during an upload there are two logs (staged
-  // and current) and a client might store them in either order, so it's
-  // not necessarily the case that the provisional store is the last store.
-  int last_provisional_store_index_;
-  LogType last_provisional_store_type_;
-
-  DISALLOW_COPY_AND_ASSIGN(MetricsLogManager);
-};
-
-#endif  // CHROME_COMMON_METRICS_METRICS_LOG_MANAGER_H_
diff --git a/chrome/common/metrics/metrics_log_manager_unittest.cc b/chrome/common/metrics/metrics_log_manager_unittest.cc
deleted file mode 100644
index 899cc0b..0000000
--- a/chrome/common/metrics/metrics_log_manager_unittest.cc
+++ /dev/null
@@ -1,423 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/common/metrics/metrics_log_manager.h"
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/sha1.h"
-#include "chrome/common/metrics/metrics_log_base.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-// Dummy serializer that just stores logs in memory.
-class DummyLogSerializer : public MetricsLogManager::LogSerializer {
- public:
-  virtual void SerializeLogs(
-      const std::vector<MetricsLogManager::SerializedLog>& logs,
-      MetricsLogManager::LogType log_type) OVERRIDE {
-    persisted_logs_[log_type] = logs;
-  }
-
-  virtual void DeserializeLogs(
-      MetricsLogManager::LogType log_type,
-      std::vector<MetricsLogManager::SerializedLog>* logs) OVERRIDE {
-    ASSERT_NE(static_cast<void*>(NULL), logs);
-    *logs = persisted_logs_[log_type];
-  }
-
-  // Returns the number of logs of the given type.
-  size_t TypeCount(MetricsLogManager::LogType log_type) {
-    return persisted_logs_[log_type].size();
-  }
-
-  // In-memory "persitent storage".
-  std::vector<MetricsLogManager::SerializedLog> persisted_logs_[2];
-};
-
-}  // namespace
-
-TEST(MetricsLogManagerTest, StandardFlow) {
-  MetricsLogManager log_manager;
-
-  // Make sure a new manager has a clean slate.
-  EXPECT_EQ(NULL, log_manager.current_log());
-  EXPECT_FALSE(log_manager.has_staged_log());
-  EXPECT_FALSE(log_manager.has_unsent_logs());
-
-  // Check that the normal flow works.
-  MetricsLogBase* initial_log =
-      new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
-  log_manager.BeginLoggingWithLog(initial_log);
-  EXPECT_EQ(initial_log, log_manager.current_log());
-  EXPECT_FALSE(log_manager.has_staged_log());
-
-  log_manager.FinishCurrentLog();
-  EXPECT_EQ(NULL, log_manager.current_log());
-  EXPECT_TRUE(log_manager.has_unsent_logs());
-  EXPECT_FALSE(log_manager.has_staged_log());
-
-  MetricsLogBase* second_log =
-      new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
-  log_manager.BeginLoggingWithLog(second_log);
-  EXPECT_EQ(second_log, log_manager.current_log());
-
-  log_manager.StageNextLogForUpload();
-  EXPECT_TRUE(log_manager.has_staged_log());
-  EXPECT_FALSE(log_manager.staged_log_text().empty());
-
-  log_manager.DiscardStagedLog();
-  EXPECT_EQ(second_log, log_manager.current_log());
-  EXPECT_FALSE(log_manager.has_staged_log());
-  EXPECT_FALSE(log_manager.has_unsent_logs());
-  EXPECT_TRUE(log_manager.staged_log_text().empty());
-
-  EXPECT_FALSE(log_manager.has_unsent_logs());
-}
-
-TEST(MetricsLogManagerTest, AbandonedLog) {
-  MetricsLogManager log_manager;
-
-  MetricsLogBase* dummy_log =
-      new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
-  log_manager.BeginLoggingWithLog(dummy_log);
-  EXPECT_EQ(dummy_log, log_manager.current_log());
-
-  log_manager.DiscardCurrentLog();
-  EXPECT_EQ(NULL, log_manager.current_log());
-  EXPECT_FALSE(log_manager.has_staged_log());
-}
-
-TEST(MetricsLogManagerTest, InterjectedLog) {
-  MetricsLogManager log_manager;
-
-  MetricsLogBase* ongoing_log =
-      new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
-  MetricsLogBase* temp_log =
-      new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
-
-  log_manager.BeginLoggingWithLog(ongoing_log);
-  EXPECT_EQ(ongoing_log, log_manager.current_log());
-
-  log_manager.PauseCurrentLog();
-  EXPECT_EQ(NULL, log_manager.current_log());
-
-  log_manager.BeginLoggingWithLog(temp_log);
-  EXPECT_EQ(temp_log, log_manager.current_log());
-  log_manager.FinishCurrentLog();
-  EXPECT_EQ(NULL, log_manager.current_log());
-
-  log_manager.ResumePausedLog();
-  EXPECT_EQ(ongoing_log, log_manager.current_log());
-
-  EXPECT_FALSE(log_manager.has_staged_log());
-  log_manager.StageNextLogForUpload();
-  log_manager.DiscardStagedLog();
-  EXPECT_FALSE(log_manager.has_unsent_logs());
-}
-
-TEST(MetricsLogManagerTest, InterjectedLogPreservesType) {
-  MetricsLogManager log_manager;
-  DummyLogSerializer* serializer = new DummyLogSerializer;
-  log_manager.set_log_serializer(serializer);
-  log_manager.LoadPersistedUnsentLogs();
-
-  MetricsLogBase* ongoing_log =
-      new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
-  MetricsLogBase* temp_log =
-      new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
-
-  log_manager.BeginLoggingWithLog(ongoing_log);
-  log_manager.PauseCurrentLog();
-  log_manager.BeginLoggingWithLog(temp_log);
-  log_manager.FinishCurrentLog();
-  log_manager.ResumePausedLog();
-  log_manager.StageNextLogForUpload();
-  log_manager.DiscardStagedLog();
-
-  // Verify that the remaining log (which is the original ongoing log) still
-  // has the right type.
-  log_manager.FinishCurrentLog();
-  log_manager.PersistUnsentLogs();
-  EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
-  EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-}
-
-TEST(MetricsLogManagerTest, StoreAndLoad) {
-  std::vector<MetricsLogManager::SerializedLog> initial_logs;
-  std::vector<MetricsLogManager::SerializedLog> ongoing_logs;
-
-  // Set up some in-progress logging in a scoped log manager simulating the
-  // leadup to quitting, then persist as would be done on quit.
-  {
-    MetricsLogManager log_manager;
-    DummyLogSerializer* serializer = new DummyLogSerializer;
-    log_manager.set_log_serializer(serializer);
-    log_manager.LoadPersistedUnsentLogs();
-
-    // Simulate a log having already been unsent from a previous session.
-    MetricsLogManager::SerializedLog log;
-    std::string text = "proto";
-    log.SwapLogText(&text);
-    serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG].push_back(log);
-    EXPECT_FALSE(log_manager.has_unsent_logs());
-    log_manager.LoadPersistedUnsentLogs();
-    EXPECT_TRUE(log_manager.has_unsent_logs());
-
-    MetricsLogBase* log1 =
-        new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
-    MetricsLogBase* log2 =
-        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
-    log_manager.BeginLoggingWithLog(log1);
-    log_manager.FinishCurrentLog();
-    log_manager.BeginLoggingWithLog(log2);
-    log_manager.StageNextLogForUpload();
-    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
-    log_manager.FinishCurrentLog();
-
-    // Nothing should be written out until PersistUnsentLogs is called.
-    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
-    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-    log_manager.PersistUnsentLogs();
-    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
-    EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-
-    // Save the logs to transfer over to a new serializer (since log_manager
-    // owns |serializer|, so it's about to go away.
-    initial_logs =
-        serializer->persisted_logs_[MetricsLogBase::INITIAL_STABILITY_LOG];
-    ongoing_logs = serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG];
-  }
-
-  // Now simulate the relaunch, ensure that the log manager restores
-  // everything correctly, and verify that once the are handled they are not
-  // re-persisted.
-  {
-    MetricsLogManager log_manager;
-
-    DummyLogSerializer* serializer = new DummyLogSerializer;
-    serializer->persisted_logs_[MetricsLogBase::INITIAL_STABILITY_LOG] =
-        initial_logs;
-    serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG] = ongoing_logs;
-
-    log_manager.set_log_serializer(serializer);
-    log_manager.LoadPersistedUnsentLogs();
-    EXPECT_TRUE(log_manager.has_unsent_logs());
-
-    log_manager.StageNextLogForUpload();
-    log_manager.DiscardStagedLog();
-    // The initial log should be sent first; update the persisted storage to
-    // verify.
-    log_manager.PersistUnsentLogs();
-    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
-    EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-
-    // Handle the first ongoing log.
-    log_manager.StageNextLogForUpload();
-    log_manager.DiscardStagedLog();
-    EXPECT_TRUE(log_manager.has_unsent_logs());
-
-    // Handle the last log.
-    log_manager.StageNextLogForUpload();
-    log_manager.DiscardStagedLog();
-    EXPECT_FALSE(log_manager.has_unsent_logs());
-
-    // Nothing should have changed "on disk" since PersistUnsentLogs hasn't been
-    // called again.
-    EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-    // Persist, and make sure nothing is left.
-    log_manager.PersistUnsentLogs();
-    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
-    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-  }
-}
-
-TEST(MetricsLogManagerTest, StoreStagedLogTypes) {
-  // Ensure that types are preserved when storing staged logs.
-  {
-    MetricsLogManager log_manager;
-    DummyLogSerializer* serializer = new DummyLogSerializer;
-    log_manager.set_log_serializer(serializer);
-    log_manager.LoadPersistedUnsentLogs();
-
-    MetricsLogBase* log =
-        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
-    log_manager.BeginLoggingWithLog(log);
-    log_manager.FinishCurrentLog();
-    log_manager.StageNextLogForUpload();
-    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
-    log_manager.PersistUnsentLogs();
-
-    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
-    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-  }
-
-  {
-    MetricsLogManager log_manager;
-    DummyLogSerializer* serializer = new DummyLogSerializer;
-    log_manager.set_log_serializer(serializer);
-    log_manager.LoadPersistedUnsentLogs();
-
-    MetricsLogBase* log =
-        new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
-    log_manager.BeginLoggingWithLog(log);
-    log_manager.FinishCurrentLog();
-    log_manager.StageNextLogForUpload();
-    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
-    log_manager.PersistUnsentLogs();
-
-    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
-    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-  }
-}
-
-TEST(MetricsLogManagerTest, LargeLogDiscarding) {
-  MetricsLogManager log_manager;
-  DummyLogSerializer* serializer = new DummyLogSerializer;
-  log_manager.set_log_serializer(serializer);
-  log_manager.LoadPersistedUnsentLogs();
-
-  // Set the size threshold very low, to verify that it's honored.
-  log_manager.set_max_ongoing_log_store_size(1);
-
-  MetricsLogBase* log1 =
-      new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
-  MetricsLogBase* log2 =
-      new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
-  log_manager.BeginLoggingWithLog(log1);
-  log_manager.FinishCurrentLog();
-  log_manager.BeginLoggingWithLog(log2);
-  log_manager.FinishCurrentLog();
-
-  // Only the ongoing log should be written out, due to the threshold.
-  log_manager.PersistUnsentLogs();
-  EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
-  EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-}
-
-TEST(MetricsLogManagerTest, ProvisionalStoreStandardFlow) {
-  // Ensure that provisional store works, and discards the correct log.
-  {
-    MetricsLogManager log_manager;
-    DummyLogSerializer* serializer = new DummyLogSerializer;
-    log_manager.set_log_serializer(serializer);
-    log_manager.LoadPersistedUnsentLogs();
-
-    MetricsLogBase* log1 =
-        new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
-    MetricsLogBase* log2 =
-        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
-    log_manager.BeginLoggingWithLog(log1);
-    log_manager.FinishCurrentLog();
-    log_manager.BeginLoggingWithLog(log2);
-    log_manager.StageNextLogForUpload();
-    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
-    log_manager.FinishCurrentLog();
-    log_manager.DiscardLastProvisionalStore();
-
-    log_manager.PersistUnsentLogs();
-    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
-    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-  }
-}
-
-TEST(MetricsLogManagerTest, ProvisionalStoreNoop) {
-  // Ensure that trying to drop a sent log is a no-op, even if another log has
-  // since been staged.
-  {
-    MetricsLogManager log_manager;
-    DummyLogSerializer* serializer = new DummyLogSerializer;
-    log_manager.set_log_serializer(serializer);
-    log_manager.LoadPersistedUnsentLogs();
-
-    MetricsLogBase* log1 =
-        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
-    MetricsLogBase* log2 =
-        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
-    log_manager.BeginLoggingWithLog(log1);
-    log_manager.FinishCurrentLog();
-    log_manager.StageNextLogForUpload();
-    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
-    log_manager.StageNextLogForUpload();
-    log_manager.DiscardStagedLog();
-    log_manager.BeginLoggingWithLog(log2);
-    log_manager.FinishCurrentLog();
-    log_manager.StageNextLogForUpload();
-    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
-    log_manager.DiscardLastProvisionalStore();
-
-    log_manager.PersistUnsentLogs();
-    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-  }
-
-  // Ensure that trying to drop more than once is a no-op
-  {
-    MetricsLogManager log_manager;
-    DummyLogSerializer* serializer = new DummyLogSerializer;
-    log_manager.set_log_serializer(serializer);
-    log_manager.LoadPersistedUnsentLogs();
-
-    MetricsLogBase* log1 =
-        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
-    MetricsLogBase* log2 =
-        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
-    log_manager.BeginLoggingWithLog(log1);
-    log_manager.FinishCurrentLog();
-    log_manager.StageNextLogForUpload();
-    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
-    log_manager.BeginLoggingWithLog(log2);
-    log_manager.FinishCurrentLog();
-    log_manager.StageNextLogForUpload();
-    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
-    log_manager.DiscardLastProvisionalStore();
-    log_manager.DiscardLastProvisionalStore();
-
-    log_manager.PersistUnsentLogs();
-    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
-  }
-}
-
-TEST(MetricsLogManagerTest, SerializedLog) {
-  const char kFooText[] = "foo";
-  const std::string foo_hash = base::SHA1HashString(kFooText);
-  const char kBarText[] = "bar";
-  const std::string bar_hash = base::SHA1HashString(kBarText);
-
-  MetricsLogManager::SerializedLog log;
-  EXPECT_TRUE(log.log_text().empty());
-  EXPECT_TRUE(log.log_hash().empty());
-
-  std::string foo = kFooText;
-  log.SwapLogText(&foo);
-  EXPECT_TRUE(foo.empty());
-  EXPECT_FALSE(log.IsEmpty());
-  EXPECT_EQ(kFooText, log.log_text());
-  EXPECT_EQ(foo_hash, log.log_hash());
-
-  std::string bar = kBarText;
-  log.SwapLogText(&bar);
-  EXPECT_EQ(kFooText, bar);
-  EXPECT_FALSE(log.IsEmpty());
-  EXPECT_EQ(kBarText, log.log_text());
-  EXPECT_EQ(bar_hash, log.log_hash());
-
-  log.Clear();
-  EXPECT_TRUE(log.IsEmpty());
-  EXPECT_TRUE(log.log_text().empty());
-  EXPECT_TRUE(log.log_hash().empty());
-
-  MetricsLogManager::SerializedLog log2;
-  foo = kFooText;
-  log2.SwapLogText(&foo);
-  log.Swap(&log2);
-  EXPECT_FALSE(log.IsEmpty());
-  EXPECT_EQ(kFooText, log.log_text());
-  EXPECT_EQ(foo_hash, log.log_hash());
-  EXPECT_TRUE(log2.IsEmpty());
-  EXPECT_TRUE(log2.log_text().empty());
-  EXPECT_TRUE(log2.log_hash().empty());
-}
diff --git a/chrome/common/metrics/metrics_service_base.cc b/chrome/common/metrics/metrics_service_base.cc
index 66e8238..a0a8182 100644
--- a/chrome/common/metrics/metrics_service_base.cc
+++ b/chrome/common/metrics/metrics_service_base.cc
@@ -6,7 +6,7 @@
 
 #include <cstdlib>
 
-#include "chrome/common/metrics/metrics_log_base.h"
+#include "components/metrics/metrics_log_base.h"
 
 using base::Histogram;
 
diff --git a/chrome/common/metrics/metrics_service_base.h b/chrome/common/metrics/metrics_service_base.h
index f3a4a67..d2e9043 100644
--- a/chrome/common/metrics/metrics_service_base.h
+++ b/chrome/common/metrics/metrics_service_base.h
@@ -9,7 +9,7 @@
 #include "base/metrics/histogram_base.h"
 #include "base/metrics/histogram_flattener.h"
 #include "base/metrics/histogram_snapshot_manager.h"
-#include "chrome/common/metrics/metrics_log_manager.h"
+#include "components/metrics/metrics_log_manager.h"
 
 namespace base {
 class HistogramSamples;
@@ -48,7 +48,7 @@
   void RecordCurrentStabilityHistograms();
 
   // Manager for the various in-flight logs.
-  MetricsLogManager log_manager_;
+  metrics::MetricsLogManager log_manager_;
 
  private:
   // |histogram_snapshot_manager_| prepares histogram deltas for transmission.
diff --git a/chrome/common/metrics/proto/chrome_user_metrics_extension.proto b/chrome/common/metrics/proto/chrome_user_metrics_extension.proto
deleted file mode 100644
index a5a6de0..0000000
--- a/chrome/common/metrics/proto/chrome_user_metrics_extension.proto
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2012 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.
-//
-// Protocol buffer for Chrome UMA (User Metrics Analysis).
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package metrics;
-
-import "histogram_event.proto";
-import "omnibox_event.proto";
-import "profiler_event.proto";
-import "system_profile.proto";
-import "user_action_event.proto";
-import "perf_data.proto";
-
-// Next tag: 11
-message ChromeUserMetricsExtension {
-  // The product (i.e. end user application) for a given UMA log.
-  enum Product {
-    // Google Chrome product family.
-    CHROME = 0;
-  }
-  // The product corresponding to this log. Note: The default value is Chrome,
-  // so Chrome products will not transmit this field.
-  optional Product product = 10 [default = CHROME];
-
-  // The id of the client install that generated these events.
-  //
-  // For Chrome clients, this id is unique to a top-level (one level above the
-  // "Default" directory) Chrome user data directory [1], and so is shared among
-  // all Chrome user profiles contained in this user data directory.
-  // An id of 0 is reserved for test data (monitoring and internal testing) and
-  // should normally be ignored in analysis of the data.
-  // [1] http://www.chromium.org/user-experience/user-data-directory
-  optional fixed64 client_id = 1;
-
-  // The session id for this user.
-  // Values such as tab ids are only meaningful within a particular session.
-  // The client keeps track of the session id and sends it with each event.
-  // The session id is simply an integer that is incremented each time the user
-  // relaunches Chrome.
-  optional int32 session_id = 2;
-
-  // Information about the user's browser and system configuration.
-  optional SystemProfileProto system_profile = 3;
-
-  // This message will log one or more of the following event types:
-  repeated UserActionEventProto user_action_event = 4;
-  repeated OmniboxEventProto omnibox_event = 5;
-  repeated HistogramEventProto histogram_event = 6;
-  repeated ProfilerEventProto profiler_event = 7;
-
-  repeated PerfDataProto perf_data = 8;
-}
diff --git a/chrome/common/metrics/proto/histogram_event.proto b/chrome/common/metrics/proto/histogram_event.proto
deleted file mode 100644
index e004dca..0000000
--- a/chrome/common/metrics/proto/histogram_event.proto
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2012 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.
-//
-// Histogram-collected metrics.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package metrics;
-
-// Next tag: 4
-message HistogramEventProto {
-  // The name of the histogram, hashed.
-  optional fixed64 name_hash = 1;
-
-  // The sum of all the sample values.
-  // Together with the total count of the sample values, this allows us to
-  // compute the average value.  The count of all sample values is just the sum
-  // of the counts of all the buckets.
-  optional int64 sum = 2;
-
-  // The per-bucket data.
-  message Bucket {
-    // Each bucket's range is bounded by min <= x < max.
-    // It is valid to omit one of these two fields in a bucket, but not both.
-    // If the min field is omitted, its value is assumed to be equal to max - 1.
-    // If the max field is omitted, its value is assumed to be equal to the next
-    // bucket's min value (possibly computed per above).  The last bucket in a
-    // histogram should always include the max field.
-    optional int64 min = 1;
-    optional int64 max = 2;
-
-    // The bucket's index in the list of buckets, sorted in ascending order.
-    // This field was intended to provide extra redundancy to detect corrupted
-    // records, but was never used.  As of M31, it is no longer sent by Chrome
-    // clients to reduce the UMA upload size.
-    optional int32 bucket_index = 3 [deprecated = true];
-
-    // The number of entries in this bucket.
-    optional int64 count = 4;
-  }
-  repeated Bucket bucket = 3;
-}
diff --git a/chrome/common/metrics/proto/omnibox_event.proto b/chrome/common/metrics/proto/omnibox_event.proto
deleted file mode 100644
index f94c63d..0000000
--- a/chrome/common/metrics/proto/omnibox_event.proto
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright (c) 2012 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.
-//
-// Stores information about an omnibox interaction.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package metrics;
-
-// Next tag: 15
-message OmniboxEventProto {
-  // The timestamp for the event, in seconds since the epoch.
-  optional int64 time = 1;
-
-  // The id of the originating tab for this omnibox interaction.
-  // This is the current tab *unless* the user opened the target in a new tab.
-  // In those cases, this is unset.  Tab ids are unique for a given session_id
-  // (in the containing protocol buffer ChromeUserMetricsExtensionProto).
-  optional int32 tab_id = 2;
-
-  // The number of characters the user had typed before autocompleting.
-  optional int32 typed_length = 3;
-
-  // Whether the user deleted text immediately before selecting an omnibox
-  // suggestion.  This is usually the result of pressing backspace or delete.
-  optional bool just_deleted_text = 11;
-
-  // The number of terms that the user typed in the omnibox.
-  optional int32 num_typed_terms = 4;
-
-  // The index of the item that the user selected in the omnibox popup list.
-  // This corresponds the index of the |suggestion| below.
-  optional int32 selected_index = 5;
-
-  // Whether or not the top match was hidden in the omnibox suggestions
-  // dropdown.
-  optional bool is_top_result_hidden_in_dropdown = 14;
-
-  // The length of the inline autocomplete text in the omnibox.
-  // The sum |typed_length| + |completed_length| gives the full length of the
-  // user-visible text in the omnibox.
-  // This field is only set for inlineable suggestions selected at position 0
-  // (|selected_index| = 0) and will be omitted otherwise.
-  optional int32 completed_length = 6;
-
-  // The amount of time, in milliseconds, since the user first began modifying
-  // the text in the omnibox.  If at some point after modifying the text, the
-  // user reverts the modifications (thus seeing the current web page's URL
-  // again), then writes in the omnibox again, this elapsed time should start
-  // from the time of the second series of modification.
-  optional int64 typing_duration_ms = 7;
-
-  // The amount of time, in milliseconds, since the last time the default
-  // (inline) match changed.  This may be longer than the time since the
-  // last keystroke.  (The last keystroke may not have changed the default
-  // match.)  It may also be shorter than the time since the last keystroke
-  // because the default match might have come from an asynchronous
-  // provider.  Regardless, it should always be less than or equal to
-  // the field |typing_duration_ms|.
-  optional int64 duration_since_last_default_match_update_ms = 13;
-
-  // The type of page currently displayed when the user used the omnibox.
-  enum PageClassification {
-    // An invalid URL; shouldn't happen.
-    INVALID_SPEC = 0;
-
-    // chrome://newtab/.  This can be either the built-in version or a
-    // replacement new tab page from an extension.  Note that when Instant
-    // Extended is enabled, the new tab page will be reported as either
-    // INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS or
-    // INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS below,
-    // unless an extension is replacing the new tab page, in which case
-    // it will still be reported as NTP.
-    NTP = 1;
-
-    // about:blank.
-    BLANK = 2;
-
-    // The user's home page.  Note that if the home page is set to any
-    // of the new tab page versions or to about:blank, then we'll
-    // classify the page into those categories, not HOME_PAGE.
-    HOME_PAGE = 3;
-
-    // The catch-all entry of everything not included somewhere else
-    // on this list.
-    OTHER = 4;
-
-    // The instant new tab page enum value was deprecated on August 2, 2013.
-    OBSOLETE_INSTANT_NTP = 5;
-
-    // The user is on a search result page that's doing search term
-    // replacement, meaning the search terms should've appeared in the omnibox
-    // before the user started editing it, not the URL of the page.
-    SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT = 6;
-
-    // The new tab page in which this omnibox interaction first started
-    // with the user having focus in the omnibox.
-    INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS = 7;
-
-    // The new tab page in which this omnibox interaction first started
-    // with the user having focus in the fakebox.
-    INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS = 8;
-
-    // The user is on a search result page that's not doing search term
-    // replacement, meaning the URL of the page should've appeared in the
-    // omnibox before the user started editing it, not the search terms.
-    SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT = 9;
-
-    // When adding new classifications, please consider adding them in
-    // chrome/browser/resources/omnibox/omnibox.html
-    // so that these new options are displayed on about:omnibox.
-  }
-  optional PageClassification current_page_classification = 10;
-
-  // What kind of input the user provided.
-  enum InputType {
-    INVALID = 0;        // Empty input (should not reach here)
-    UNKNOWN = 1;        // Valid input whose type cannot be determined
-    REQUESTED_URL = 2;  // DEPRECATED. Input autodetected as UNKNOWN, which the
-                        // user wants to treat as an URL by specifying a
-                        // desired_tld
-    URL = 3;            // Input autodetected as a URL
-    QUERY = 4;          // Input autodetected as a query
-    FORCED_QUERY = 5;   // Input forced to be a query by an initial '?'
-  }
-  optional InputType input_type = 8;
-
-  // An enum used in multiple places below.
-  enum ProviderType {
-    UNKNOWN_PROVIDER = 0;  // Unknown provider (should not reach here)
-    HISTORY_URL = 1;       // URLs in history, or user-typed URLs
-    HISTORY_CONTENTS = 2;  // Matches for page contents of pages in history
-    HISTORY_QUICK = 3;     // Matches for recently or frequently visited pages
-                           // in history
-    SEARCH = 4;            // Search suggestions for the default search engine
-    KEYWORD = 5;           // Keyword-triggered searches
-    BUILTIN = 6;           // Built-in URLs, such as chrome://version
-    SHORTCUTS = 7;         // Recently selected omnibox suggestions
-    EXTENSION_APPS = 8;    // Custom suggestions from extensions and/or apps
-    CONTACT = 9;           // DEPRECATED. The user's contacts
-    BOOKMARK = 10;         // The user's bookmarks
-    ZERO_SUGGEST = 11;     // Suggestions based on the current page
-    // This enum value is currently only used by Android GSA. It represents
-    // a suggestion from the phone.
-    ON_DEVICE = 12;
-  }
-
-  // The result set displayed on the completion popup
-  // Next tag: 6
-  message Suggestion {
-    // Where does this result come from?
-    optional ProviderType provider = 1;
-
-    // What kind of result this is.
-    // This corresponds to the AutocompleteMatch::Type enumeration in
-    // chrome/browser/autocomplete/autocomplete_match.h (except for Android
-    // GSA result types).
-    enum ResultType {
-      UNKNOWN_RESULT_TYPE = 0;    // Unknown type (should not reach here)
-      URL_WHAT_YOU_TYPED = 1;     // The input as a URL
-      HISTORY_URL = 2;            // A past page whose URL contains the input
-      HISTORY_TITLE = 3;          // A past page whose title contains the input
-      HISTORY_BODY = 4;           // A past page whose body contains the input
-      HISTORY_KEYWORD = 5;        // A past page whose keyword contains the
-                                  // input
-      NAVSUGGEST = 6;             // A suggested URL
-      SEARCH_WHAT_YOU_TYPED = 7;  // The input as a search query (with the
-                                  // default engine)
-      SEARCH_HISTORY = 8;         // A past search (with the default engine)
-                                  // containing the input
-      SEARCH_SUGGEST = 9;         // A suggested search (with the default
-                                  // engine) query that doesn't fall into one of
-                                  // the more specific suggestion categories
-                                  // below.
-      SEARCH_OTHER_ENGINE = 10;   // A search with a non-default engine
-      EXTENSION_APP = 11;         // An Extension App with a title/url that
-                                  // contains the input
-      CONTACT = 12;               // DEPRECATED. One of the user's contacts
-      BOOKMARK_TITLE = 13;        // A bookmark whose title contains the input.
-      SEARCH_SUGGEST_ENTITY = 14; // A suggested search for an entity.
-      SEARCH_SUGGEST_INFINITE = 15; // A suggested search to complete the tail
-                                    // of the query.
-      SEARCH_SUGGEST_PERSONALIZED = 16; // A personalized suggested search.
-      SEARCH_SUGGEST_PROFILE = 17; // A personalized suggested search for a
-                                   // Google+ profile.      
-      APP_RESULT = 18;             // Result from an installed app
-                                   // (eg: a gmail email).
-                                   // Used by Android GSA for on-device
-                                   // suggestion logging.
-      APP = 19;                    // An app result (eg: the gmail app).
-                                   // Used by Android GSA for on-device
-                                   // suggestion logging.
-    }
-    optional ResultType result_type = 2;
-
-    // The relevance score for this suggestion.
-    optional int32 relevance = 3;
-
-    // How many times this result was typed in / selected from the omnibox.
-    // Only set for some providers and result_types.  At the time of
-    // writing this comment, it is only set for HistoryURL and
-    // HistoryQuickProvider matches.
-    optional int32 typed_count = 5;
-
-    // Whether this item is starred (bookmarked) or not.
-    optional bool is_starred = 4;
-  }
-  repeated Suggestion suggestion = 9;
-
-  // A data structure that holds per-provider information, general information
-  // not associated with a particular result.
-  // Next tag: 5
-  message ProviderInfo {
-    // Which provider generated this ProviderInfo entry.
-    optional ProviderType provider = 1;
-
-    // The provider's done() value, i.e., whether it's completed processing
-    // the query.  Providers which don't do any asynchronous processing
-    // will always be done.
-    optional bool provider_done = 2;
-
-    // The set of field trials that have triggered in the most recent query,
-    // possibly affecting the shown suggestions.  Each element is a hash
-    // of the corresponding field trial name.
-    // See chrome/browser/autocomplete/search_provider.cc for a specific usage
-    // example.
-    repeated fixed32 field_trial_triggered = 3;
-
-    // Same as above except that the set of field trials is a union of all field
-    // trials that have triggered within the current omnibox session including
-    // the most recent query.
-    // See AutocompleteController::ResetSession() for more details on the
-    // definition of a session.
-    // See chrome/browser/autocomplete/search_provider.cc for a specific usage
-    // example.
-    repeated fixed32 field_trial_triggered_in_session = 4;
-  }
-  // A list of diagnostic information about each provider.  Providers
-  // will appear at most once in this list.
-  repeated ProviderInfo provider_info = 12;
-}
diff --git a/chrome/common/metrics/proto/perf_data.proto b/chrome/common/metrics/proto/perf_data.proto
deleted file mode 100644
index e233034..0000000
--- a/chrome/common/metrics/proto/perf_data.proto
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright (c) 2012 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.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package metrics;
-
-// Stores information from a perf session generated via running:
-// "perf record"
-//
-// See $kernel/tools/perf/design.txt for more details.
-
-// Please do not modify this protobuf directly, except to mirror the upstream
-// version found here:
-// https://chromium.googlesource.com/chromiumos/platform/chromiumos-wide-profiling/+/master/perf_data.proto
-// with some fields omitted for privacy reasons. Because it is a read-only copy
-// of the upstream protobuf, "Next tag:" comments are also absent.
-
-message PerfDataProto {
-
-  // Perf event attribute. Stores the event description.
-  // This data structure is defined in the linux kernel:
-  // $kernel/tools/perf/util/event.h.
-  message PerfEventAttr {
-    // Type of the event. Type is an enumeration and can be:
-    // IP: an instruction-pointer was stored in the event.
-    // MMAP: a DLL was loaded.
-    // FORK: a process was forked.
-    // etc.
-    optional uint32 type = 1;
-
-    // Size of the event data in bytes.
-    optional uint32 size = 2;
-
-    // The config stores the CPU-specific counter information.
-    optional uint64 config = 3;
-
-    // Sample period of the event. Indicates how often the event is
-    // triggered in terms of # of events. After |sample_period| events, an event
-    // will be recorded and stored.
-    optional uint64 sample_period = 4;
-
-    // Sample frequency of the event. Indicates how often the event is
-    // triggered in terms of # per second. The kernel will try to record
-    // |sample_freq| events per second.
-    optional uint64 sample_freq = 5;
-
-    // Sample type is a bitfield that records attributes of the sample. Example,
-    // whether an entire callchain was recorded, etc.
-    optional uint64 sample_type = 6;
-
-    // Bitfield that indicates whether reads on the counter will return the
-    // total time enabled and total time running.
-    optional uint64 read_format = 7;
-
-    // Indicates whether the counter starts off disabled.
-    optional bool disabled = 8;
-
-    // Indicates whether child processes inherit the counter.
-    optional bool inherit = 9;
-
-    // Indicates whether the counter is pinned to a particular CPU.
-    optional bool pinned = 10;
-
-    // Indicates whether this counter's group has exclusive access to the CPU's
-    // counters.
-    optional bool exclusive = 11;
-
-    // The following bits restrict events to be counted when the CPU is in user,
-    // kernel, hypervisor or idle modes.
-    optional bool exclude_user = 12;
-    optional bool exclude_kernel = 13;
-    optional bool exclude_hv = 14;
-    optional bool exclude_idle = 15;
-
-    // Indicates whether mmap events should be recorded.
-    optional bool mmap = 16;
-
-    // Indicates whether process comm information should be recorded upon
-    // process creation.
-    optional bool comm = 17;
-
-    // Indicates that we are in frequency mode, not period mode.
-    optional bool freq = 18;
-
-    // Indicates whether we have per-task counts.
-    optional bool inherit_stat = 19;
-
-    // Indicates whether we enable perf events after an exec() function call.
-    optional bool enable_on_exec = 20;
-
-    // Indicates whether we trace fork/exit.
-    optional bool task = 21;
-
-    // Indicates whether we are using a watermark to wake up.
-    optional bool watermark = 22;
-
-    // CPUs often "skid" when recording events. That means the instruction
-    // pointer may not be the same as the one that caused the counter overflow.
-    // Indicates the capabilities of the CPU in terms of recording precise
-    // instruction pointer.
-    optional uint32 precise_ip = 23;
-
-    // Indicates whether we have non-exec mmap data.
-    optional bool mmap_data = 24;
-
-    // If set, all the event types will have the same sample_type.
-    optional bool sample_id_all = 25;
-
-    // Indicates whether we are counting events from the host (when running a
-    // VM).
-    optional bool exclude_host = 26;
-
-    // Exclude events that happen on a guest OS.
-    optional bool exclude_guest = 27;
-
-    // Contains the number of events after which we wake up.
-    optional uint32 wakeup_events = 28;
-
-    // Contains the number of bytes after which we wake up.
-    optional uint32 wakeup_watermark = 29;
-
-    // Information about the type of the breakpoint.
-    optional uint32 bp_type = 30;
-
-    // Contains the breakpoint address.
-    optional uint64 bp_addr = 31;
-
-    // This is an extension of config (see above).
-    optional uint64 config1 = 32;
-
-    // The length of the breakpoint data in bytes.
-    optional uint64 bp_len = 33;
-
-    // This is an extension of config (see above).
-    optional uint64 config2 = 34;
-
-    // Contains the type of branch, example: user, kernel, call, return, etc.
-    optional uint64 branch_sample_type = 35;
-  }
-
-  // Describes a perf.data file attribute.
-  message PerfFileAttr {
-    optional PerfEventAttr attr = 1;
-
-    // List of perf file attribute ids. Each id describes an event.
-    repeated uint64 ids = 2;
-  }
-
-  // This message contains information about a perf sample itself, as opposed to
-  // a perf event captured by a sample.
-  message SampleInfo {
-    // Process ID / thread ID from which this sample was taken.
-    optional uint32 pid = 1;
-    optional uint32 tid = 2;
-
-    // Time this sample was taken (NOT the same as an event time).
-    // It is the number of nanoseconds since bootup.
-    optional uint64 sample_time_ns = 3;
-
-    // The ID of the sample's event type (cycles, instructions, etc).
-    // The event type IDs are defined in PerfFileAttr.
-    optional uint64 id = 4;
-
-    // The CPU on which this sample was taken.
-    optional uint32 cpu = 5;
-  }
-
-  message CommEvent {
-    // Process id.
-    optional uint32 pid = 1;
-
-    // Thread id.
-    optional uint32 tid = 2;
-
-    // Comm string's md5 prefix.
-    // The comm string was field 3 and has been intentionally left out.
-    optional uint64 comm_md5_prefix = 4;
-
-    // Time the sample was taken.
-    // Deprecated, use |sample_info| instead.
-    optional uint64 sample_time = 5 [deprecated=true];
-
-    // Info about the perf sample containing this event.
-    optional SampleInfo sample_info = 6;
-  }
-
-  message MMapEvent {
-    // Process id.
-    optional uint32 pid = 1;
-
-    // Thread id.
-    optional uint32 tid = 2;
-
-    // Start address.
-    optional uint64 start = 3;
-
-    // Length.
-    optional uint64 len = 4;
-
-    // PG Offset.
-    optional uint64 pgoff = 5;
-
-    // Filename's md5 prefix.
-    // The filename was field 6 and has been intentionally left out.
-    optional uint64 filename_md5_prefix = 7;
-
-    // Info about the perf sample containing this event.
-    optional SampleInfo sample_info = 8;
-  }
-
-  message BranchStackEntry {
-    // Branch source address.
-    optional uint64 from_ip = 1;
-
-    // Branch destination address.
-    optional uint64 to_ip = 2;
-
-    // Indicates a mispredicted branch.
-    optional bool mispredicted = 3;
-  }
-
-  message SampleEvent {
-    // Instruction pointer.
-    optional uint64 ip = 1;
-
-    // Process id.
-    optional uint32 pid = 2;
-
-    // Thread id.
-    optional uint32 tid = 3;
-
-    // The time after boot when the sample was recorded, in nanoseconds.
-    optional uint64 sample_time_ns = 4;
-
-    // The address of the sample.
-    optional uint64 addr = 5;
-
-    // The id of the sample.
-    optional uint64 id = 6;
-
-    // The stream id of the sample.
-    optional uint64 stream_id = 7;
-
-    // The period of the sample.
-    optional uint64 period = 8;
-
-    // The CPU where the event was recorded.
-    optional uint32 cpu = 9;
-
-    // The raw size of the event in bytes.
-    optional uint32 raw_size = 10;
-
-    // Sample callchain info.
-    repeated uint64 callchain = 11;
-
-    // Branch stack info.
-    repeated BranchStackEntry branch_stack = 12;
-  }
-
-  // ForkEvent is used for both FORK and EXIT events, which have the same data
-  // format.  We don't want to call this "ForkOrExitEvent", in case a separate
-  // exit event is introduced in the future.
-  message ForkEvent {
-    // Forked process ID.
-    optional uint32 pid = 1;
-
-    // Parent process ID.
-    optional uint32 ppid = 2;
-
-    // Forked process thread ID.
-    optional uint32 tid = 3;
-
-    // Parent process thread ID.
-    optional uint32 ptid = 4;
-
-    // Time of fork event in nanoseconds since bootup.
-    optional uint64 fork_time_ns = 5;
-
-    // Info about the perf sample containing this event.
-    optional SampleInfo sample_info = 11;
-  }
-
-  message EventHeader {
-    // Type of event.
-    optional uint32 type = 1;
-    optional uint32 misc = 2;
-    // Size of event.
-    optional uint32 size = 3;
-  }
-
-  message PerfEvent {
-    optional EventHeader header = 1;
-
-    optional MMapEvent mmap_event = 2;
-    optional SampleEvent sample_event = 3;
-    optional CommEvent comm_event = 4;
-    optional ForkEvent fork_event = 5;
-  }
-
-  message PerfEventStats {
-    // Total number of events read from perf data.
-    optional uint32 num_events_read = 1;
-
-    // Total number of various types of events.
-    optional uint32 num_sample_events = 2;
-    optional uint32 num_mmap_events = 3;
-    optional uint32 num_fork_events = 4;
-    optional uint32 num_exit_events = 5;
-
-    // Number of sample events that were successfully mapped by the address
-    // mapper, a quipper module that is used to obscure addresses and convert
-    // them to DSO name + offset.  Sometimes it fails to process sample events.
-    // This field allows us to track the success rate of the address mapper.
-    optional uint32 num_sample_events_mapped = 6;
-
-    // Whether address remapping was enabled.
-    optional bool did_remap = 7;
-  }
-
-  message PerfBuildID {
-    // Misc field in perf_event_header.
-    // Indicates whether the file is mapped in kernel mode or user mode.
-    optional uint32 misc = 1;
-
-    // Process ID.
-    optional uint32 pid = 2;
-
-    // Build id.  Should always contain kBuildIDArraySize bytes of data.
-    // perf_reader.h in Chrome OS defines kBuildIDArraySize = 20.
-    optional bytes build_hash = 3;
-
-    // Filename Md5sum prefix.
-    // The filename was field 4 and has been intentionally left out.
-    optional uint64 filename_md5_prefix = 5;
-  }
-
-  repeated PerfFileAttr file_attrs = 1;
-  repeated PerfEvent events = 2;
-
-  // Time when quipper generated this perf data / protobuf, given as seconds
-  // since the epoch.
-  optional uint64 timestamp_sec = 3;
-
-  // Records some stats about the serialized perf events.
-  optional PerfEventStats stats = 4;
-
-  // Not added from original: repeated uint64 metadata_mask = 5;
-  // Not added from original: repeated PerfStringMetadata string_metadata = 6;
-
-  // Build ID metadata.
-  repeated PerfBuildID build_ids = 7;
-}
diff --git a/chrome/common/metrics/proto/profiler_event.proto b/chrome/common/metrics/proto/profiler_event.proto
deleted file mode 100644
index c42bc5a..0000000
--- a/chrome/common/metrics/proto/profiler_event.proto
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2012 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.
-//
-// Performance metrics collected via Chrome's built-in profiler.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package metrics;
-
-
-// Next tag: 4
-message ProfilerEventProto {
-  // The type of this profile.
-  enum ProfileType {
-    UNKNOWN_PROFILE = 0;  // Unknown type (should not reach here).
-    STARTUP_PROFILE = 1;  // Startup profile, logged approximately 60 seconds
-                          // after launch.
-  }
-  optional ProfileType profile_type = 1;
-
-  // The source based upon which "time" measurements are made.
-  // We currently only measure wall clock time; but we are exploring other
-  // measurement sources as well, such as CPU time or TCMalloc statistics.
-  enum TimeSource {
-    UNKNOWN_TIME_SOURCE = 0;  // Unknown source (should not reach here).
-    WALL_CLOCK_TIME = 1;      // Total time elapsed between the start and end of
-                              // the task's execution.
-  }
-  optional TimeSource time_source = 2;
-
-  // Data for a single tracked object (typically, a Task).
-  message TrackedObject {
-    // The name of the thread from which this task was posted, hashed.
-    optional fixed64 birth_thread_name_hash = 1;
-
-    // The name of the thread on which this task was executed, hashed.
-    optional fixed64 exec_thread_name_hash = 2;
-
-    // The source file name from which this task was posted, hashed.
-    optional fixed64 source_file_name_hash = 3;
-
-    // Function name from which this task was posted, hashed.
-    optional fixed64 source_function_name_hash = 4;
-
-    // The line number within the source file from which this task was posted.
-    optional int32 source_line_number = 5;
-
-    // The number of times this task was executed.
-    optional int32 exec_count = 6;
-
-    // The total execution time for instances this task.
-    optional int32 exec_time_total = 7;
-
-    // The execution time for a uniformly randomly sampled instance of this
-    // task.
-    optional int32 exec_time_sampled = 8;
-
-    // The total time instances this task spent waiting (e.g. in a message loop)
-    // before they were run.
-    optional int32 queue_time_total = 9;
-
-    // The time that a uniformly randomly sampled instance of this task spent
-    // waiting (e.g.  in a message loop) before it was run.
-    optional int32 queue_time_sampled = 10;
-
-    // The type of process within which this task was executed.
-    enum ProcessType {
-      UNKNOWN = 0;  // Should not reach here
-      BROWSER = 1;
-      RENDERER = 2;
-      PLUGIN = 3;
-      WORKER = 4;
-      NACL_LOADER = 5;
-      UTILITY = 6;
-      PROFILE_IMPORT = 7;
-      ZYGOTE = 8;
-      SANDBOX_HELPER = 9;
-      NACL_BROKER = 10;
-      GPU = 11;
-      PPAPI_PLUGIN = 12;
-      PPAPI_BROKER = 13;
-    }
-    optional ProcessType process_type = 11;
-
-    // The local PID for the process within which this task was executed.
-    optional uint32 process_id = 12;
-  }
-  repeated TrackedObject tracked_object = 3;
-}
diff --git a/chrome/common/metrics/proto/system_profile.proto b/chrome/common/metrics/proto/system_profile.proto
deleted file mode 100644
index fd339ec..0000000
--- a/chrome/common/metrics/proto/system_profile.proto
+++ /dev/null
@@ -1,509 +0,0 @@
-// Copyright (c) 2012 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.
-//
-// Stores information about the user's brower and system configuration.
-// The system configuration fields are recorded once per client session.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package metrics;
-
-// Next tag: 19
-message SystemProfileProto {
-  // The time when the client was compiled/linked, in seconds since the epoch.
-  optional int64 build_timestamp = 1;
-
-  // A version number string for the application.
-  // Most commonly this is the browser version number found in a user agent
-  // string, and is typically a 4-tuple of numbers separated by periods.  In
-  // cases where the user agent version might be ambiguous (example: Linux 64-
-  // bit build, rather than 32-bit build, or a Windows version used in some
-  // special context, such as ChromeFrame running in IE), then this may include
-  // some additional postfix to provide clarification not available in the UA
-  // string.
-  //
-  // An example of a browser version 4-tuple is "5.0.322.0".  Currently used
-  // postfixes are:
-  //
-  //   "-64": a 64-bit build
-  //   "-F": Chrome is running under control of ChromeFrame
-  //   "-devel": this is not an official build of Chrome
-  //
-  // A full version number string could look similar to:
-  // "5.0.322.0-F-devel".
-  //
-  // This value, when available, is more trustworthy than the UA string
-  // associated with the request; and including the postfix, may be more
-  // specific.
-  optional string app_version = 2;
-
-  // The brand code or distribution tag assigned to a partner, if available.
-  // Brand codes are only available on Windows.  Not every Windows install
-  // though will have a brand code.
-  optional string brand_code = 12;
-
-  // The possible channels for an installation, from least to most stable.
-  enum Channel {
-    CHANNEL_UNKNOWN = 0;  // Unknown channel -- perhaps an unofficial build?
-    CHANNEL_CANARY = 1;
-    CHANNEL_DEV = 2;
-    CHANNEL_BETA = 3;
-    CHANNEL_STABLE = 4;
-  }
-  optional Channel channel = 10;
-
-  // The date the user enabled UMA, in seconds since the epoch.
-  // If the user has toggled the UMA enabled state multiple times, this will
-  // be the most recent date on which UMA was enabled.
-  // For privacy, this is rounded to the nearest hour.
-  optional int64 uma_enabled_date = 3;
-
-  // The time when the client was installed, in seconds since the epoch.
-  // For privacy, this is rounded to the nearest hour.
-  optional int64 install_date = 16;
-
-  // The user's selected application locale, i.e. the user interface language.
-  // The locale includes a language code and, possibly, also a country code,
-  // e.g. "en-US".
-  optional string application_locale = 4;
-
-  // Information on the user's operating system.
-  message OS {
-    // The user's operating system.
-    optional string name = 1;
-
-    // The version of the OS.  The meaning of this field is OS-dependent.
-    optional string version = 2;
-
-    // The fingerprint of the build.  This field is used only on Android.
-    optional string fingerprint = 3;
-  }
-  optional OS os = 5;
-
-  // Next tag for Hardware: 16
-  // Information on the user's hardware.
-  message Hardware {
-    // The CPU architecture (x86, PowerPC, x86_64, ...)
-    optional string cpu_architecture = 1;
-
-    // The amount of RAM present on the system, in megabytes.
-    optional int64 system_ram_mb = 2;
-
-    // The base memory address that chrome.dll was loaded at.
-    // (Logged only on Windows.)
-    optional int64 dll_base = 3;
-
-    // The Chrome OS device hardware class ID is a unique string associated with
-    // each Chrome OS device product revision generally assigned at hardware
-    // qualification time.  The hardware class effectively identifies the
-    // configured system components such as CPU, WiFi adapter, etc.
-    //
-    // An example of such a hardware class is "IEC MARIO PONY 6101".  An
-    // internal database associates this hardware class with the qualified
-    // device specifications including OEM information, schematics, hardware
-    // qualification reports, test device tags, etc.
-    optional string hardware_class = 4;
-
-    // The number of physical screens.
-    optional int32 screen_count = 5;
-
-    // The screen dimensions of the primary screen, in pixels.
-    optional int32 primary_screen_width = 6;
-    optional int32 primary_screen_height = 7;
-
-    // The device scale factor of the primary screen.
-    optional float primary_screen_scale_factor = 12;
-
-    // Max DPI for any attached screen. (Windows only)
-    optional float max_dpi_x = 9;
-    optional float max_dpi_y = 10;
-
-    // Information on the CPU obtained by CPUID.
-    message CPU {
-      // A 12 character string naming the vendor, e.g. "GeniuneIntel".
-      optional string vendor_name = 1;
-
-      // The signature reported by CPUID (from EAX).
-      optional uint32 signature = 2;
-    }
-    optional CPU cpu = 13;
-
-    // Information on the GPU
-    message Graphics {
-      // The GPU manufacturer's vendor id.
-      optional uint32 vendor_id = 1;
-
-      // The GPU manufacturer's device id for the chip set.
-      optional uint32 device_id = 2;
-
-      // The driver version on the GPU.
-      optional string driver_version = 3;
-
-      // The driver date on the GPU.
-      optional string driver_date = 4;
-
-      // The GPU performance statistics.
-      // See http://src.chromium.org/viewvc/chrome/trunk/src/content/public/common/gpu_performance_stats.h?view=markup
-      // for details.  Currently logged only on Windows.
-      message PerformanceStatistics {
-        optional float graphics_score = 1;
-        optional float gaming_score = 2;
-        optional float overall_score = 3;
-      }
-      optional PerformanceStatistics performance_statistics = 5;
-
-      // The GL_VENDOR string. An example of a gl_vendor string is
-      // "Imagination Technologies". "" if we are not using OpenGL.
-      optional string gl_vendor = 6;
-
-      // The GL_RENDERER string. An example of a gl_renderer string is
-      // "PowerVR SGX 540". "" if we are not using OpenGL.
-      optional string gl_renderer = 7;
-    }
-    optional Graphics gpu = 8;
-
-    // Information about Bluetooth devices paired with the system.
-    message Bluetooth {
-      // Whether Bluetooth is present on this system.
-      optional bool is_present = 1;
-
-      // Whether Bluetooth is enabled on this system.
-      optional bool is_enabled = 2;
-
-      // Describes a paired device.
-      message PairedDevice {
-        // Assigned class of the device. This is a bitfield according to the
-        // Bluetooth specification available at the following URL:
-        // https://www.bluetooth.org/en-us/specification/assigned-numbers-overview/baseband
-        optional uint32 bluetooth_class = 1;
-
-        // Decoded device type.
-        enum Type {
-          DEVICE_UNKNOWN = 0;
-          DEVICE_COMPUTER = 1;
-          DEVICE_PHONE = 2;
-          DEVICE_MODEM = 3;
-          DEVICE_AUDIO = 4;
-          DEVICE_CAR_AUDIO = 5;
-          DEVICE_VIDEO = 6;
-          DEVICE_PERIPHERAL = 7;
-          DEVICE_JOYSTICK = 8;
-          DEVICE_GAMEPAD = 9;
-          DEVICE_KEYBOARD = 10;
-          DEVICE_MOUSE = 11;
-          DEVICE_TABLET = 12;
-          DEVICE_KEYBOARD_MOUSE_COMBO = 13;
-        }
-        optional Type type = 2;
-
-        // Vendor prefix of the Bluetooth address, these are OUI registered by
-        // the IEEE and are encoded with the first byte in bits 16-23, the
-        // second byte in bits 8-15 and the third byte in bits 0-7.
-        //
-        // ie. Google's OUI (00:1A:11) is encoded as 0x00001A11
-        optional uint32 vendor_prefix = 4;
-
-        // The Vendor ID of a device, returned in vendor_id below, can be
-        // either allocated by the Bluetooth SIG or USB IF, providing two
-        // completely overlapping namespaces for identifiers.
-        //
-        // This field should be read along with vendor_id to correctly
-        // identify the vendor. For example Google is identified by either
-        // vendor_id_source = VENDOR_ID_BLUETOOTH, vendor_id = 0x00E0 or
-        // vendor_id_source = VENDOR_ID_USB, vendor_id = 0x18D1.
-        //
-        // If the device does not support the Device ID specification the
-        // unknown value will be set.
-        enum VendorIDSource {
-          VENDOR_ID_UNKNOWN = 0;
-          VENDOR_ID_BLUETOOTH = 1;
-          VENDOR_ID_USB = 2;
-        }
-        optional VendorIDSource vendor_id_source = 8;
-
-        // Vendor ID of the device, where available.
-        optional uint32 vendor_id = 5;
-
-        // Product ID of the device, where available.
-        optional uint32 product_id = 6;
-
-        // Device ID of the device, generally the release or version number in
-        // BCD format, where available.
-        optional uint32 device_id = 7;
-      }
-      repeated PairedDevice paired_device = 3;
-    }
-    optional Bluetooth bluetooth = 11;
-
-    // Whether the internal display produces touch events. Omitted if unknown.
-    // Logged on ChromeOS only.
-    optional bool internal_display_supports_touch = 14;
-
-    // Vendor ids and product ids of external touchscreens.
-    message TouchScreen {
-      // Touch screen vendor id.
-      optional uint32 vendor_id = 1;
-      // Touch screen product id.
-      optional uint32 product_id = 2;
-    }
-    // Lists vendor and product ids of external touchscreens.
-    // Logged on ChromeOS only.
-    repeated TouchScreen external_touchscreen = 15;
-  }
-  optional Hardware hardware = 6;
-
-  // Information about the network connection.
-  message Network {
-    // Set to true if connection_type changed during the lifetime of the log.
-    optional bool connection_type_is_ambiguous = 1;
-
-    // See net::NetworkChangeNotifier::ConnectionType.
-    enum ConnectionType {
-      CONNECTION_UNKNOWN = 0;
-      CONNECTION_ETHERNET = 1;
-      CONNECTION_WIFI = 2;
-      CONNECTION_2G = 3;
-      CONNECTION_3G = 4;
-      CONNECTION_4G = 5;
-    }
-    // The connection type according to NetworkChangeNotifier.
-    optional ConnectionType connection_type = 2;
-
-    // Set to true if wifi_phy_layer_protocol changed during the lifetime of the log.
-    optional bool wifi_phy_layer_protocol_is_ambiguous = 3;
-
-    // See net::WifiPHYLayerProtocol.
-    enum WifiPHYLayerProtocol {
-      WIFI_PHY_LAYER_PROTOCOL_NONE = 0;
-      WIFI_PHY_LAYER_PROTOCOL_ANCIENT = 1;
-      WIFI_PHY_LAYER_PROTOCOL_A = 2;
-      WIFI_PHY_LAYER_PROTOCOL_B = 3;
-      WIFI_PHY_LAYER_PROTOCOL_G = 4;
-      WIFI_PHY_LAYER_PROTOCOL_N = 5;
-      WIFI_PHY_LAYER_PROTOCOL_UNKNOWN = 6;
-    }
-    // The physical layer mode of the associated wifi access point, if any.
-    optional WifiPHYLayerProtocol wifi_phy_layer_protocol = 4;
-  }
-  optional Network network = 13;
-
-  // Information on the Google Update install that is managing this client.
-  message GoogleUpdate {
-    // Whether the Google Update install is system-level or user-level.
-    optional bool is_system_install = 1;
-
-    // The date at which Google Update last started performing an automatic
-    // update check, in seconds since the Unix epoch.
-    optional int64 last_automatic_start_timestamp = 2;
-
-    // The date at which Google Update last successfully sent an update check
-    // and recieved an intact response from the server, in seconds since the
-    // Unix epoch. (The updates don't need to be successfully installed.)
-    optional int64 last_update_check_timestamp = 3;
-
-    // Describes a product being managed by Google Update. (This can also
-    // describe Google Update itself.)
-    message ProductInfo {
-      // The current version of the product that is installed.
-      optional string version = 1;
-
-      // The date at which Google Update successfully updated this product,
-      // stored in seconds since the Unix epoch.  This is updated when an update
-      // is successfully applied, or if the server reports that no update
-      // is available.
-      optional int64 last_update_success_timestamp = 2;
-
-      // The result reported by the product updater on its last run.
-      enum InstallResult {
-        INSTALL_RESULT_SUCCESS = 0;
-        INSTALL_RESULT_FAILED_CUSTOM_ERROR = 1;
-        INSTALL_RESULT_FAILED_MSI_ERROR = 2;
-        INSTALL_RESULT_FAILED_SYSTEM_ERROR = 3;
-        INSTALL_RESULT_EXIT_CODE = 4;
-      }
-      optional InstallResult last_result = 3;
-
-      // The error code reported by the product updater on its last run.  This
-      // will typically be a error code specific to the product installer.
-      optional int32 last_error = 4;
-
-      // The extra error code reported by the product updater on its last run.
-      // This will typically be a Win32 error code.
-      optional int32 last_extra_error = 5;
-    }
-    optional ProductInfo google_update_status = 4;
-    optional ProductInfo client_status = 5;
-  }
-  optional GoogleUpdate google_update = 11;
-
-  // Information on all installed plugins.
-  message Plugin {
-    // The plugin's self-reported name and filename (without path).
-    optional string name = 1;
-    optional string filename = 2;
-
-    // The plugin's version.
-    optional string version = 3;
-
-    // True if the plugin is disabled.
-    // If a client has multiple local Chrome user accounts, this is logged based
-    // on the first user account launched during the current session.
-    optional bool is_disabled = 4;
-
-    // True if the plugin is PPAPI.
-    optional bool is_pepper = 5;
-  }
-  repeated Plugin plugin = 7;
-
-  // Figures that can be used to generate application stability metrics.
-  // All values are counts of events since the last time that these
-  // values were reported.
-  // Next tag: 24
-  message Stability {
-    // Total amount of time that the program was running, in seconds,
-    // since the last time a log was recorded, as measured using a client-side
-    // clock implemented via TimeTicks, which guarantees that it is monotonic
-    // and does not jump if the user changes his/her clock.  The TimeTicks
-    // implementation also makes the clock not count time the computer is
-    // suspended.
-    optional int64 incremental_uptime_sec = 1;
-
-    // Total amount of time that the program was running, in seconds,
-    // since startup, as measured using a client-side clock implemented
-    // via TimeTicks, which guarantees that it is monotonic and does not
-    // jump if the user changes his/her clock.  The TimeTicks implementation
-    // also makes the clock not count time the computer is suspended.
-    // This field was added for M-35.
-    optional int64 uptime_sec = 23;
-
-    // Page loads along with renderer crashes and hangs, since page load count
-    // roughly corresponds to usage.
-    optional int32 page_load_count = 2;
-    optional int32 renderer_crash_count = 3;
-    optional int32 renderer_hang_count = 4;
-
-    // Number of renderer crashes that were for extensions.
-    // TODO(isherman): Figure out whether this is also counted in
-    // |renderer_crash_count|.
-    optional int32 extension_renderer_crash_count = 5;
-
-    // Number of non-renderer child process crashes.
-    optional int32 child_process_crash_count = 6;
-
-    // Number of times the browser has crashed while logged in as the "other
-    // user" (guest) account.
-    // Logged on ChromeOS only.
-    optional int32 other_user_crash_count = 7;
-
-    // Number of times the kernel has crashed.
-    // Logged on ChromeOS only.
-    optional int32 kernel_crash_count = 8;
-
-    // Number of times the system has shut down uncleanly.
-    // Logged on ChromeOS only.
-    optional int32 unclean_system_shutdown_count = 9;
-
-    //
-    // All the remaining fields in the Stability are recorded at most once per
-    // client session.
-    //
-
-    // The number of times the program was launched.
-    // This will typically be equal to 1.  However, it is possible that Chrome
-    // was unable to upload stability metrics for previous launches (e.g. due to
-    // crashing early during startup), and hence this value might be greater
-    // than 1.
-    optional int32 launch_count = 15;
-    // The number of times that it didn't exit cleanly (which we assume to be
-    // mostly crashes).
-    optional int32 crash_count = 16;
-
-    // The number of times the program began, but did not complete, the shutdown
-    // process.  (For example, this may occur when Windows is shutting down, and
-    // it only gives the process a few seconds to clean up.)
-    optional int32 incomplete_shutdown_count = 17;
-
-    // The number of times the program was able register with breakpad crash
-    // services.
-    optional int32 breakpad_registration_success_count = 18;
-
-    // The number of times the program failed to register with breakpad crash
-    // services.  If crash registration fails then when the program crashes no
-    // crash report will be generated.
-    optional int32 breakpad_registration_failure_count = 19;
-
-    // The number of times the program has run under a debugger.  This should
-    // be an exceptional condition.  Running under a debugger prevents crash
-    // dumps from being generated.
-    optional int32 debugger_present_count = 20;
-
-    // The number of times the program has run without a debugger attached.
-    // This should be most common scenario and should be very close to
-    // |launch_count|.
-    optional int32 debugger_not_present_count = 21;
-
-    // Stability information for all installed plugins.
-    message PluginStability {
-      // The relevant plugin's information (name, etc.)
-      optional Plugin plugin = 1;
-
-      // The number of times this plugin's process was launched.
-      optional int32 launch_count = 2;
-
-      // The number of times this plugin was instantiated on a web page.
-      // This will be >= |launch_count|.
-      // (A page load with multiple sections drawn by this plugin will
-      // increase this count multiple times.)
-      optional int32 instance_count = 3;
-
-      // The number of times this plugin process crashed.
-      // This value will be <= |launch_count|.
-      optional int32 crash_count = 4;
-
-      // The number of times this plugin could not be loaded.
-      optional int32 loading_error_count = 5;
-    }
-    repeated PluginStability plugin_stability = 22;
-  }
-  optional Stability stability = 8;
-
-  // Description of a field trial or experiment that the user is currently
-  // enrolled in.
-  // All metrics reported in this upload can potentially be influenced by the
-  // field trial.
-  message FieldTrial {
-    // The name of the field trial, as a 32-bit identifier.
-    // Currently, the identifier is a hash of the field trial's name.
-    optional fixed32 name_id = 1;
-
-    // The user's group within the field trial, as a 32-bit identifier.
-    // Currently, the identifier is a hash of the group's name.
-    optional fixed32 group_id = 2;
-  }
-  repeated FieldTrial field_trial = 9;
-
-  // Number of users currently signed into a multiprofile session.
-  // A zero value indicates that the user count changed while the log is open.
-  // Logged only on ChromeOS.
-  optional uint32 multi_profile_user_count = 17;
-
-  // Information about extensions that are installed, masked to provide better
-  // privacy.  Only extensions from a single profile are reported; this will
-  // generally be the profile used when the browser is started.  The profile
-  // reported on will remain consistent at least until the browser is
-  // relaunched (or the profile is deleted by the user).
-  //
-  // Each client first picks a value for client_key derived from its UMA
-  // client_id:
-  //   client_key = client_id % 4096
-  // Then, each installed extension is mapped into a hash bucket according to
-  //   bucket = CityHash64(StringPrintf("%d:%s",
-  //                                    client_key, extension_id)) % 1024
-  // The client reports the set of hash buckets occupied by all installed
-  // extensions.  If multiple extensions map to the same bucket, that bucket is
-  // still only reported once.
-  repeated int32 occupied_extension_bucket = 18;
-}
diff --git a/chrome/common/metrics/proto/user_action_event.proto b/chrome/common/metrics/proto/user_action_event.proto
deleted file mode 100644
index ff688b6..0000000
--- a/chrome/common/metrics/proto/user_action_event.proto
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012 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.
-//
-// Stores information about an event that occurs in response to a user action,
-// e.g. an interaction with a browser UI element.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package metrics;
-
-// Next tag: 3
-message UserActionEventProto {
-  // The name of the action, hashed.
-  optional fixed64 name_hash = 1;
-
-  // The timestamp for the event, in seconds since the epoch.
-  optional int64 time = 2;
-}
diff --git a/chrome/common/net/url_fixer_upper.cc b/chrome/common/net/url_fixer_upper.cc
index 34966da..ea6555f 100644
--- a/chrome/common/net/url_fixer_upper.cc
+++ b/chrome/common/net/url_fixer_upper.cc
@@ -52,7 +52,7 @@
 void UTF8PartsToUTF16Parts(const std::string& text_utf8,
                            const url::Parsed& parts_utf8,
                            url::Parsed* parts) {
-  if (IsStringASCII(text_utf8)) {
+  if (base::IsStringASCII(text_utf8)) {
     *parts = parts_utf8;
     return;
   }
@@ -81,7 +81,7 @@
   // This implementation is not so fast since it converts the text encoding
   // twice. Please feel free to file a bug if this function hurts the
   // performance of Chrome.
-  DCHECK(IsStringUTF8(input));
+  DCHECK(base::IsStringUTF8(input));
   base::string16 input16 = base::UTF8ToUTF16(input);
   base::string16 output16;
   base::TrimPositions result =
@@ -424,7 +424,7 @@
       // Couldn't determine the scheme, so just pick one.
       parts->scheme.reset();
       scheme = StartsWithASCII(*text, "ftp.", false) ?
-          content::kFtpScheme : content::kHttpScheme;
+          content::kFtpScheme : url::kHttpScheme;
     }
   }
 
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index cf188b6..65db79a 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -471,14 +471,12 @@
 // Disables the listed protocol schemes.
 const char kDisabledSchemes[] = "protocol.disabled_schemes";
 
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_IOS)
 // Last time that a check for cloud policy management was done. This time is
 // recorded on Android so that retries aren't attempted on every startup.
 // Instead the cloud policy registration is retried at least 1 or 3 days later.
 const char kLastPolicyCheckTime[] = "policy.last_policy_check_time";
-#endif
 
-#if defined(OS_ANDROID) || defined(OS_IOS)
 // A list of bookmarks to include in a Managed Bookmarks root node. Each
 // list item is a dictionary containing a "name" and an "url" entry, detailing
 // the bookmark name and target URL respectively.
@@ -1299,6 +1297,9 @@
 // Preference storing Easy Unlock pairing data.
 extern const char kEasyUnlockPairing[] = "easy_unlock.pairing";
 
+// A cache of zero suggest results using JSON serialized into a string.
+const char kZeroSuggestCachedResults[] = "zerosuggest.cachedresults";
+
 // *************** LOCAL STATE ***************
 // These are attached to the machine/installation
 
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 5a9538a..14cd0a2 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -173,10 +173,8 @@
 extern const char kSpdyServers[];
 extern const char kAlternateProtocolServers[];
 extern const char kDisabledSchemes[];
-#if defined(OS_ANDROID)
-extern const char kLastPolicyCheckTime[];
-#endif
 #if defined(OS_ANDROID) || defined(OS_IOS)
+extern const char kLastPolicyCheckTime[];
 extern const char kManagedBookmarks[];
 #endif
 extern const char kInstantUIZeroSuggestUrlPrefix[];
@@ -411,6 +409,8 @@
 extern const char kEasyUnlockShowTutorial[];
 extern const char kEasyUnlockPairing[];
 
+extern const char kZeroSuggestCachedResults[];
+
 // Local state prefs. Please add Profile prefs above instead.
 extern const char kCertRevocationCheckingEnabled[];
 extern const char kCertRevocationCheckingRequiredLocalAnchors[];
diff --git a/chrome/common/search_urls.cc b/chrome/common/search_urls.cc
index 9856842..b1277b6 100644
--- a/chrome/common/search_urls.cc
+++ b/chrome/common/search_urls.cc
@@ -14,8 +14,8 @@
   return my_url.host() == other_url.host() &&
          my_url.port() == other_url.port() &&
          (my_url.scheme() == other_url.scheme() ||
-          (my_url.SchemeIs(content::kHttpsScheme) &&
-           other_url.SchemeIs(content::kHttpScheme)));
+          (my_url.SchemeIs(url::kHttpsScheme) &&
+           other_url.SchemeIs(url::kHttpScheme)));
 }
 }  // namespace
 
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 8c7dce3..916375f 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -354,7 +354,7 @@
     "https://support.google.com/chrome/?p=settings_password";
 #endif
 
-const char kSettingsApiLearnMoreURL[] =
+const char kExtensionControlledSettingLearnMoreURL[] =
     "https://support.google.com/chrome/?p=ui_settings_api_extension";
 
 const char kChromeHelpViaKeyboardURL[] =
@@ -493,9 +493,6 @@
 const char kBlockedPluginLearnMoreURL[] =
     "https://support.google.com/chrome/?p=ib_blocked_plugin";
 
-const char kSpeechInputAboutURL[] =
-    "https://support.google.com/chrome/?p=ui_speech_input";
-
 const char kHotwordLearnMoreURL[] =
     "https://support.google.com/chrome/?p=ui_hotword_search";
 
@@ -551,6 +548,9 @@
     "https://support.google.com/chrome/answer/2811969?"
     "p=ui_remove_non_cws_extensions&rd=1";
 
+const char kCorruptExtensionURL[] =
+    "https://support.google.com/chrome/?p=settings_corrupt_extension";
+
 const char kNotificationsHelpURL[] =
     "https://support.google.com/chrome/?p=ui_notifications";
 
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index a153dda..a1619f9 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -337,8 +337,9 @@
 
 extern const char kPasswordManagerLearnMoreURL[];
 
-// "Learn more" URL for the Settings API bubble.
-extern const char kSettingsApiLearnMoreURL[];
+// "Learn more" URL for the Settings API, NTP bubble and other settings bubbles
+// showing which extension is controlling them.
+extern const char kExtensionControlledSettingLearnMoreURL[];
 
 // General help links for Chrome, opened using various actions.
 extern const char kChromeHelpViaKeyboardURL[];
@@ -424,9 +425,6 @@
 // The URL for the "Learn more" page for the blocked plugin infobar.
 extern const char kBlockedPluginLearnMoreURL[];
 
-// The URL for the "About Voice Recognition" menu item.
-extern const char kSpeechInputAboutURL[];
-
 // The URL for the "Learn more" page for hotword search voice trigger.
 extern const char kHotwordLearnMoreURL[];
 
@@ -466,6 +464,9 @@
 // The URL for the Learn More link of the non-CWS bubble.
 extern const char kRemoveNonCWSExtensionURL[];
 
+// The URL for the Learn More link for the corrupt extension message.
+extern const char kCorruptExtensionURL[];
+
 extern const char kNotificationsHelpURL[];
 
 // The Welcome Notification More Info URL.
diff --git a/chrome/common_constants.gyp b/chrome/common_constants.gyp
index 50b3574..8df1796 100644
--- a/chrome/common_constants.gyp
+++ b/chrome/common_constants.gyp
@@ -13,9 +13,6 @@
 
   'target_defaults': {
     'sources': [
-      # TODO(yoz): Create an extension_constants target for these.
-      '../extensions/common/constants.cc',
-      '../extensions/common/constants.h',
       'common/chrome_constants.cc',
       'common/chrome_constants.h',
       'common/chrome_icon_resources_win.cc',
diff --git a/chrome/installer/setup/DEPS b/chrome/installer/setup/DEPS
index 3a8062c..a96cf4b 100644
--- a/chrome/installer/setup/DEPS
+++ b/chrome/installer/setup/DEPS
@@ -1,5 +1,4 @@
 include_rules = [
   "+chrome/app",
   "+courgette",
-  "+extensions/common/constants.h",
 ]
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index 5b64ab6..57fe5e5 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -1353,8 +1353,10 @@
   MasterPreferences uninstall_prefs(uninstall_cmd);
   InstallerState uninstall_state;
   uninstall_state.Initialize(uninstall_cmd, uninstall_prefs, *original_state);
-  const Product* chrome_frame_product = uninstall_state.FindProduct(
-      BrowserDistribution::CHROME_FRAME);
+  // Post M32, uninstall_prefs and uninstall_state won't have Chrome Frame in
+  // them since they've lost the power to do Chrome Frame installs.
+  const Product* chrome_frame_product = uninstall_state.AddProductFromState(
+      BrowserDistribution::CHROME_FRAME, *chrome_frame_state);
   if (chrome_frame_product) {
     // No shared state should be left behind.
     const bool remove_all = true;
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
index 9150214..353e390 100644
--- a/chrome/installer/setup/uninstall.cc
+++ b/chrome/installer/setup/uninstall.cc
@@ -24,7 +24,7 @@
 #include "base/win/shortcut.h"
 #include "base/win/windows_version.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_paths_internal.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_result_codes.h"
 #include "chrome/installer/launcher_support/chrome_launcher_support.h"
 #include "chrome/installer/setup/install.h"
@@ -47,7 +47,6 @@
 #include "chrome/installer/util/shell_util.h"
 #include "chrome/installer/util/util_constants.h"
 #include "content/public/common/result_codes.h"
-#include "extensions/common/constants.h"
 #include "rlz/lib/rlz_lib.h"
 
 using base::win::RegKey;
@@ -388,20 +387,25 @@
   return DELETE_FAILED;
 }
 
+// Get the user data directory, which is *not* DIR_USER_DATA for Chrome Frame.
+// TODO(grt): Remove Chrome Frame uninstall support when usage is low enough.
 base::FilePath GetUserDataDir(const Product& product) {
-  // Obtain the location of the user profile data.
-  base::FilePath user_data_dir = product.GetUserDataPath();
-  LOG_IF(ERROR, user_data_dir.empty())
-      << "Could not retrieve user's profile directory.";
-
-  return user_data_dir;
+  base::FilePath path;
+  bool is_chrome_frame = product.is_chrome_frame();
+  int key = is_chrome_frame ? base::DIR_LOCAL_APP_DATA : chrome::DIR_USER_DATA;
+  if (!PathService::Get(key, &path))
+    return base::FilePath();
+  if (is_chrome_frame) {
+    path = path.Append(product.distribution()->GetInstallSubDir());
+    path = path.Append(chrome::kUserDataDirname);
+  }
+  return path;
 }
 
 // Creates a copy of the local state file and returns a path to the copy.
 base::FilePath BackupLocalStateFile(const base::FilePath& user_data_dir) {
   base::FilePath backup;
-  base::FilePath state_file(
-      user_data_dir.Append(chrome::kLocalStateFilename));
+  base::FilePath state_file(user_data_dir.Append(chrome::kLocalStateFilename));
   if (!base::CreateTemporaryFile(&backup))
     LOG(ERROR) << "Failed to create temporary file for Local State.";
   else
@@ -1043,7 +1047,7 @@
     // Delete Software\Classes\.crx,
     base::string16 ext_association(ShellUtil::kRegClasses);
     ext_association.append(L"\\");
-    ext_association.append(extensions::kExtensionFileExtension);
+    ext_association.append(L".crx");
     InstallUtil::DeleteRegistryKey(roots[i], ext_association);
   }
 }
@@ -1327,7 +1331,14 @@
   // (aka non-multi) installation or we are the Chrome Binaries.
 
   base::FilePath user_data_dir(GetUserDataDir(product));
-  base::FilePath backup_state_file(BackupLocalStateFile(user_data_dir));
+  base::FilePath backup_state_file;
+  if (!user_data_dir.empty()) {
+    backup_state_file = BackupLocalStateFile(user_data_dir);
+  } else {
+    LOG(ERROR) << "Could not retrieve the user's profile directory.";
+    ret = installer::UNINSTALL_FAILED;
+    delete_profile = false;
+  }
 
   if (product.is_chrome_app_host()) {
     DeleteAppHostFilesAndFolders(installer_state, product_state->version());
diff --git a/chrome/installer/util/auto_launch_util.cc b/chrome/installer/util/auto_launch_util.cc
index 6dd5d35..7ad2315 100644
--- a/chrome/installer/util/auto_launch_util.cc
+++ b/chrome/installer/util/auto_launch_util.cc
@@ -12,10 +12,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/win_util.h"
 #include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
-#include "chrome/installer/util/browser_distribution.h"
-#include "chrome/installer/util/product.h"
 #include "chrome/installer/util/util_constants.h"
 #include "crypto/sha2.h"
 
@@ -36,25 +35,15 @@
   FLAG_PRESERVE,  // Preserve the value that the flag has currently.
 };
 
-// A helper function that takes a |profile_path| and builds a registry key
+// A helper function that takes a |profile_directory| and builds a registry key
 // name to use when deciding where to read/write the auto-launch value
 // to/from. It takes into account the name of the profile (so that different
 // installations of Chrome don't conflict, and so the in the future different
 // profiles can be auto-launched (or not) separately).
 base::string16 ProfileToKeyName(const base::string16& profile_directory) {
   base::FilePath path;
-  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
-  if (command_line.HasSwitch(switches::kUserDataDir)) {
-    path = command_line.GetSwitchValuePath(switches::kUserDataDir);
-  } else {
-    // Get the path from the same source as the installer, to make sure there
-    // are no differences.
-    BrowserDistribution* distribution =
-        BrowserDistribution::GetSpecificDistribution(
-            BrowserDistribution::CHROME_BROWSER);
-    installer::Product product(distribution);
-    path = product.GetUserDataPath();
-  }
+  const bool success = PathService::Get(chrome::DIR_USER_DATA, &path);
+  DCHECK(success);
   path = path.Append(profile_directory);
 
   std::string input(path.AsUTF8Unsafe());
@@ -212,8 +201,7 @@
       cmd_line += ASCIIToUTF16("\"");
     }
 
-    base::win::AddCommandToAutoRun(
-        HKEY_CURRENT_USER, key_name, cmd_line);
+    base::win::AddCommandToAutoRun(HKEY_CURRENT_USER, key_name, cmd_line);
   } else {
     base::win::RemoveCommandFromAutoRun(HKEY_CURRENT_USER, key_name);
   }
diff --git a/chrome/installer/util/helper.cc b/chrome/installer/util/helper.cc
index df63dc0..f76213d 100644
--- a/chrome/installer/util/helper.cc
+++ b/chrome/installer/util/helper.cc
@@ -12,39 +12,17 @@
 #include "chrome/installer/util/installation_state.h"
 #include "chrome/installer/util/util_constants.h"
 
-namespace {
-
-base::FilePath GetChromeInstallBasePath(bool system,
-                                        BrowserDistribution* distribution,
-                                        const wchar_t* sub_path) {
-  base::FilePath install_path;
-  if (system) {
-    PathService::Get(base::DIR_PROGRAM_FILES, &install_path);
-  } else {
-    PathService::Get(base::DIR_LOCAL_APP_DATA, &install_path);
-  }
-
-  if (!install_path.empty()) {
-    install_path = install_path.Append(distribution->GetInstallSubDir());
-    install_path = install_path.Append(sub_path);
-  }
-
-  return install_path;
-}
-
-}  // namespace
-
 namespace installer {
 
 base::FilePath GetChromeInstallPath(bool system_install,
                                     BrowserDistribution* dist) {
-  return GetChromeInstallBasePath(system_install, dist, kInstallBinaryDir);
-}
-
-base::FilePath GetChromeUserDataPath(BrowserDistribution* dist) {
-  // TODO(msw): Remove this method and make callers use PathService directly to
-  // obtain the right DIR_USER_DATA.
-  return GetChromeInstallBasePath(false, dist, kInstallUserDataDir);
+  base::FilePath install_path;
+  int key = system_install ? base::DIR_PROGRAM_FILES : base::DIR_LOCAL_APP_DATA;
+  if (PathService::Get(key, &install_path)) {
+    install_path = install_path.Append(dist->GetInstallSubDir());
+    install_path = install_path.Append(kInstallBinaryDir);
+  }
+  return install_path;
 }
 
 BrowserDistribution* GetBinariesDistribution(bool system_install) {
diff --git a/chrome/installer/util/helper.h b/chrome/installer/util/helper.h
index 152a160..940db44 100644
--- a/chrome/installer/util/helper.h
+++ b/chrome/installer/util/helper.h
@@ -22,14 +22,8 @@
 // system_install: if true, the function returns system wide location
 //                 (ProgramFiles\Google). Otherwise it returns user specific
 //                 location (Document And Settings\<user>\Local Settings...)
-base::FilePath GetChromeInstallPath(bool system_install, BrowserDistribution* dist);
-
-// Returns the path to the directory that holds the user data.  This is always
-// inside a user's local application data folder (e.g., "AppData\Local" or
-// "Local Settings\Application Data" in %USERPROFILE%). Note that this is the
-// default user data directory and does not take into account that it can be
-// overriden with a command line parameter.
-base::FilePath GetChromeUserDataPath(BrowserDistribution* dist);
+base::FilePath GetChromeInstallPath(bool system_install,
+                                    BrowserDistribution* dist);
 
 // Returns the distribution corresponding to the current process's binaries.
 // In the case of a multi-install product, this will be the CHROME_BINARIES
diff --git a/chrome/installer/util/installer_state.cc b/chrome/installer/util/installer_state.cc
index a5ed9d9..e6cc475 100644
--- a/chrome/installer/util/installer_state.cc
+++ b/chrome/installer/util/installer_state.cc
@@ -661,7 +661,7 @@
         FileVersionInfo::CreateFileVersionInfo(chrome_exe));
     if (file_version_info) {
       base::string16 version_string = file_version_info->file_version();
-      if (!version_string.empty() && IsStringASCII(version_string))
+      if (!version_string.empty() && base::IsStringASCII(version_string))
         existing_versions->insert(base::UTF16ToASCII(version_string));
     }
   }
diff --git a/chrome/installer/util/product.cc b/chrome/installer/util/product.cc
index 1d11a7e..7ade852 100644
--- a/chrome/installer/util/product.cc
+++ b/chrome/installer/util/product.cc
@@ -62,10 +62,6 @@
   operations_->ReadOptions(uninstall_command, &options_);
 }
 
-base::FilePath Product::GetUserDataPath() const {
-  return GetChromeUserDataPath(distribution_);
-}
-
 bool Product::LaunchChrome(const base::FilePath& application_path) const {
   bool success = !application_path.empty();
   if (success) {
diff --git a/chrome/installer/util/product.h b/chrome/installer/util/product.h
index c9da906..a815fb2 100644
--- a/chrome/installer/util/product.h
+++ b/chrome/installer/util/product.h
@@ -81,13 +81,6 @@
       return options_.erase(option) != 0;
   }
 
-  // Returns the path to the directory that holds the user data.  This is always
-  // inside a user's local application data folder (e.g., "AppData\Local" or
-  // "Local Settings\Application Data" in %USERPROFILE%). Note that this is the
-  // default user data directory and does not take into account that it can be
-  // overriden with a command line parameter.
-  base::FilePath GetUserDataPath() const;
-
   // Launches Chrome without waiting for it to exit.
   bool LaunchChrome(const base::FilePath& application_path) const;
 
diff --git a/chrome/installer/util/product_unittest.cc b/chrome/installer/util/product_unittest.cc
index fa4c27e..eabade7 100644
--- a/chrome/installer/util/product_unittest.cc
+++ b/chrome/installer/util/product_unittest.cc
@@ -5,8 +5,10 @@
 #include "chrome/installer/util/product_unittest.h"
 
 #include "base/logging.h"
+#include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/test_reg_util_win.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/installer/util/chrome_frame_distribution.h"
 #include "chrome/installer/util/google_update_constants.h"
 #include "chrome/installer/util/installation_state.h"
@@ -45,14 +47,7 @@
  protected:
 };
 
-// This test is flaky on Win, see http://crbug.com/100567
-#if defined(OS_WIN)
-#define MAYBE_ProductInstallBasic DISABLED_ProductInstallBasic
-#else
-#define MAYBE_ProductInstallBasic ProductInstallBasic
-#endif
-
-TEST_F(ProductTest, MAYBE_ProductInstallBasic) {
+TEST_F(ProductTest, ProductInstallBasic) {
   // TODO(tommi): We should mock this and use our mocked distribution.
   const bool multi_install = false;
   const bool system_level = true;
@@ -70,17 +65,16 @@
   BrowserDistribution* distribution = product->distribution();
   EXPECT_EQ(BrowserDistribution::CHROME_BROWSER, distribution->GetType());
 
-  base::FilePath user_data(product->GetUserDataPath());
-  EXPECT_FALSE(user_data.empty());
-  EXPECT_NE(std::wstring::npos,
-            user_data.value().find(installer::kInstallUserDataDir));
+  base::FilePath user_data_dir;
+  ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
+  EXPECT_FALSE(user_data_dir.empty());
 
   base::FilePath program_files;
-  PathService::Get(base::DIR_PROGRAM_FILES, &program_files);
+  ASSERT_TRUE(PathService::Get(base::DIR_PROGRAM_FILES, &program_files));
   // The User Data path should never be under program files, even though
   // system_level is true.
   EXPECT_EQ(std::wstring::npos,
-            user_data.value().find(program_files.value()));
+            user_data_dir.value().find(program_files.value()));
 
   // There should be no installed version in the registry.
   machine_state.Initialize();
diff --git a/chrome/installer/util/user_experiment.cc b/chrome/installer/util/user_experiment.cc
index 73de5a6..68e4eac 100644
--- a/chrome/installer/util/user_experiment.cc
+++ b/chrome/installer/util/user_experiment.cc
@@ -11,6 +11,7 @@
 
 #include "base/command_line.h"
 #include "base/files/file_path.h"
+#include "base/path_service.h"
 #include "base/process/launch.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -20,6 +21,7 @@
 #include "base/win/scoped_handle.h"
 #include "base/win/windows_version.h"
 #include "chrome/common/attrition_experiments.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_result_codes.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/installer/util/browser_distribution.h"
@@ -85,11 +87,14 @@
   return ::GetFileTime(file, NULL, NULL, &time) ? FileTimeToHours(time) : -1;
 }
 
-// Returns the directory last-write time age in hours, relative to current
-// time, so if it returns 14 it means that the directory was last written 14
-// hours ago. Returns -1 if there was an error retrieving the directory.
-int GetDirectoryWriteAgeInHours(const wchar_t* path) {
-  int dir_time = GetDirectoryWriteTimeInHours(path);
+// Returns the time in hours since the last write to the user data directory.
+// A return value of 14 means that the directory was last written 14 hours ago.
+// Returns -1 if there was an error retrieving the directory.
+int GetUserDataDirectoryWriteAgeInHours() {
+  base::FilePath user_data_dir;
+  if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
+    return -1;
+  int dir_time = GetDirectoryWriteTimeInHours(user_data_dir.value().c_str());
   if (dir_time < 0)
     return dir_time;
   FILETIME time;
@@ -425,21 +430,17 @@
         return;
       }
     }
-    // Check browser usage inactivity by the age of the last-write time of the
-    // most recently-used chrome user data directory.
-    BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
-        BrowserDistribution::CHROME_BROWSER);
-    base::FilePath user_data_dir(GetChromeUserDataPath(dist));
-
     const bool experiment_enabled = false;
-    const int kThirtyDays = 30 * 24;
-
-    int dir_age_hours = GetDirectoryWriteAgeInHours(
-        user_data_dir.value().c_str());
     if (!experiment_enabled) {
       VLOG(1) << "Toast experiment is disabled.";
       return;
-    } else if (dir_age_hours < 0) {
+    }
+
+    // Check browser usage inactivity by the age of the last-write time of the
+    // relevant chrome user data directory.
+    const int kThirtyDays = 30 * 24;
+    const int dir_age_hours = GetUserDataDirectoryWriteAgeInHours();
+    if (dir_age_hours < 0) {
       // This means that we failed to find the user data dir. The most likely
       // cause is that this user has not ever used chrome at all which can
       // happen in a system-level install.
diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc
index b4639e5..8800c5c 100644
--- a/chrome/installer/util/util_constants.cc
+++ b/chrome/installer/util/util_constants.cc
@@ -238,7 +238,6 @@
 const wchar_t kInstallBinaryDir[] = L"Application";
 const wchar_t kInstallerDir[] = L"Installer";
 const wchar_t kInstallTempDir[] = L"Temp";
-const wchar_t kInstallUserDataDir[] = L"User Data";
 const wchar_t kLnkExt[] = L".lnk";
 const wchar_t kNaClExe[] = L"nacl64.exe";
 const wchar_t kSetupExe[] = L"setup.exe";
diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h
index d5d6281..09416e4 100644
--- a/chrome/installer/util/util_constants.h
+++ b/chrome/installer/util/util_constants.h
@@ -224,7 +224,6 @@
 extern const wchar_t kInstallBinaryDir[];
 extern const wchar_t kInstallerDir[];
 extern const wchar_t kInstallTempDir[];
-extern const wchar_t kInstallUserDataDir[];
 extern const wchar_t kLnkExt[];
 extern const wchar_t kNaClExe[];
 extern const wchar_t kSetupExe[];
diff --git a/chrome/renderer/DEPS b/chrome/renderer/DEPS
index d65e9df..b607af8 100644
--- a/chrome/renderer/DEPS
+++ b/chrome/renderer/DEPS
@@ -3,6 +3,7 @@
   "+components/autofill/content/common",
   "+components/autofill/content/renderer",
   "+components/autofill/core/common",
+  "+components/cdm/renderer",
   "+components/nacl/renderer",
   "+components/plugins/renderer",
   "+components/signin/core/common",
diff --git a/chrome/renderer/autofill/page_click_tracker_browsertest.cc b/chrome/renderer/autofill/page_click_tracker_browsertest.cc
index 4c5c818..52b00ff 100644
--- a/chrome/renderer/autofill/page_click_tracker_browsertest.cc
+++ b/chrome/renderer/autofill/page_click_tracker_browsertest.cc
@@ -167,7 +167,7 @@
   EXPECT_FALSE(test_listener_.form_control_element_lost_focus_called_);
   test_listener_.ClearResults();
 
-  // Select another text field to test that the notifcation for the
+  // Select another text field to test that the notification for the
   // first text field losing focus is sent.
   EXPECT_TRUE(SimulateElementClick("text_2"));
   EXPECT_TRUE(test_listener_.form_control_element_lost_focus_called_);
@@ -205,7 +205,7 @@
   EXPECT_FALSE(test_listener_.form_control_element_lost_focus_called_);
   test_listener_.ClearResults();
 
-  // Select another textarea field to test that the notifcation for the
+  // Select another textarea field to test that the notification for the
   // first textarea field losing focus is sent.
   EXPECT_TRUE(SimulateElementClick("textarea_2"));
   EXPECT_TRUE(test_listener_.form_control_element_lost_focus_called_);
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
index 456be28..7d061db 100644
--- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -1044,12 +1044,16 @@
   EXPECT_TRUE(password_autofill_->AcceptSuggestion(
       username_element_, kAliceUsername, kAlicePassword));
   CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
+  int username_length = strlen(kAliceUsername);
+  CheckUsernameSelection(username_length, username_length);
 
   // Try accepting a suggestion with a password different from the one that was
   // initially sent to the renderer.
   EXPECT_TRUE(password_autofill_->AcceptSuggestion(
       username_element_, kBobUsername, kCarolPassword));
   CheckTextFieldsDOMState(kBobUsername, true, kCarolPassword, true);
+  username_length = strlen(kBobUsername);
+  CheckUsernameSelection(username_length, username_length);
 }
 
 // Tests that logging is off by default.
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index f246fd4..044a9af 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -31,10 +31,10 @@
 #include "chrome/renderer/chrome_render_process_observer.h"
 #include "chrome/renderer/chrome_render_view_observer.h"
 #include "chrome/renderer/content_settings_observer.h"
+#include "chrome/renderer/extensions/chrome_extension_helper.h"
+#include "chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h"
 #include "chrome/renderer/extensions/chrome_extensions_renderer_client.h"
-#include "chrome/renderer/extensions/dispatcher.h"
 #include "chrome/renderer/extensions/extension_frame_helper.h"
-#include "chrome/renderer/extensions/extension_helper.h"
 #include "chrome/renderer/extensions/renderer_permissions_policy_delegate.h"
 #include "chrome/renderer/extensions/resource_request_policy.h"
 #include "chrome/renderer/external_extension.h"
@@ -81,6 +81,8 @@
 #include "extensions/common/extension_set.h"
 #include "extensions/common/extension_urls.h"
 #include "extensions/common/switches.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/extension_helper.h"
 #include "extensions/renderer/script_context.h"
 #include "grit/generated_resources.h"
 #include "grit/locale_settings.h"
@@ -242,10 +244,14 @@
 
   chrome_observer_.reset(new ChromeRenderProcessObserver(this));
 
+  extension_dispatcher_delegate_.reset(
+      new ChromeExtensionsDispatcherDelegate());
   // ChromeRenderViewTest::SetUp() creates its own ExtensionDispatcher and
-  // injects it using SetExtensionDispatcherForTest(). Don't overwrite it.
-  if (!extension_dispatcher_)
-    extension_dispatcher_.reset(new extensions::Dispatcher());
+  // injects it using SetExtensionDispatcher(). Don't overwrite it.
+  if (!extension_dispatcher_) {
+    extension_dispatcher_.reset(
+        new extensions::Dispatcher(extension_dispatcher_delegate_.get()));
+  }
   permissions_policy_delegate_.reset(
       new extensions::RendererPermissionsPolicyDelegate(
           extension_dispatcher_.get()));
@@ -413,6 +419,7 @@
 void ChromeContentRendererClient::RenderViewCreated(
     content::RenderView* render_view) {
   new extensions::ExtensionHelper(render_view, extension_dispatcher_.get());
+  new extensions::ChromeExtensionHelper(render_view);
   new PageLoadHistograms(render_view);
 #if defined(ENABLE_PRINTING)
   new printing::PrintWebViewHelper(render_view);
@@ -1324,18 +1331,18 @@
 }
 
 bool ChromeContentRendererClient::IsAdblockWithWebRequestInstalled() {
-  return g_current_client->extension_dispatcher_->
-      IsAdblockWithWebRequestInstalled();
+  return g_current_client->extension_dispatcher_delegate_
+      ->IsAdblockWithWebRequestInstalled();
 }
 
 bool ChromeContentRendererClient::IsAdblockPlusWithWebRequestInstalled() {
-  return g_current_client->extension_dispatcher_->
-      IsAdblockPlusWithWebRequestInstalled();
+  return g_current_client->extension_dispatcher_delegate_
+      ->IsAdblockPlusWithWebRequestInstalled();
 }
 
 bool ChromeContentRendererClient::IsOtherExtensionWithWebRequestInstalled() {
-  return g_current_client->extension_dispatcher_->
-      IsOtherExtensionWithWebRequestInstalled();
+  return g_current_client->extension_dispatcher_delegate_
+      ->IsOtherExtensionWithWebRequestInstalled();
 }
 
 const void* ChromeContentRendererClient::CreatePPAPIInterface(
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index ba227e3..7fe7a82 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -15,6 +15,7 @@
 #include "content/public/renderer/content_renderer_client.h"
 #include "ipc/ipc_channel_proxy.h"
 
+class ChromeExtensionsDispatcherDelegate;
 class ChromeRenderProcessObserver;
 class PrescientNetworkingDispatcher;
 class RendererNetPredictor;
@@ -189,6 +190,7 @@
                             blink::WebPluginParams* params);
 
   scoped_ptr<ChromeRenderProcessObserver> chrome_observer_;
+  scoped_ptr<ChromeExtensionsDispatcherDelegate> extension_dispatcher_delegate_;
   scoped_ptr<extensions::Dispatcher> extension_dispatcher_;
   scoped_ptr<extensions::RendererPermissionsPolicyDelegate>
       permissions_policy_delegate_;
diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc
index 46c2012..1bfc461 100644
--- a/chrome/renderer/content_settings_observer.cc
+++ b/chrome/renderer/content_settings_observer.cc
@@ -9,12 +9,12 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/common/url_constants.h"
-#include "chrome/renderer/extensions/dispatcher.h"
 #include "content/public/renderer/document_state.h"
 #include "content/public/renderer/navigation_state.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_view.h"
 #include "extensions/common/constants.h"
+#include "extensions/renderer/dispatcher.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
 #include "third_party/WebKit/public/web/WebDataSource.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
diff --git a/chrome/renderer/content_settings_observer_browsertest.cc b/chrome/renderer/content_settings_observer_browsertest.cc
index d444ccf..5bbed1f 100644
--- a/chrome/renderer/content_settings_observer_browsertest.cc
+++ b/chrome/renderer/content_settings_observer_browsertest.cc
@@ -121,7 +121,7 @@
   ProcessPendingMessages();
 
   // 4. Verify that the notification that javascript was blocked is sent after
-  //    the navigation notifiction is sent.
+  //    the navigation notification is sent.
   int navigation_index = -1;
   int block_index = -1;
   for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
diff --git a/chrome/renderer/extensions/api_activity_logger.cc b/chrome/renderer/extensions/api_activity_logger.cc
deleted file mode 100644
index d29bd9b..0000000
--- a/chrome/renderer/extensions/api_activity_logger.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2013 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.
-
-#include <string>
-
-#include "base/bind.h"
-#include "chrome/renderer/extensions/api_activity_logger.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/public/renderer/v8_value_converter.h"
-#include "extensions/common/extension_messages.h"
-#include "extensions/renderer/activity_log_converter_strategy.h"
-#include "extensions/renderer/script_context.h"
-
-using content::V8ValueConverter;
-
-namespace extensions {
-
-APIActivityLogger::APIActivityLogger(ScriptContext* context)
-    : ObjectBackedNativeHandler(context) {
-  RouteFunction("LogEvent", base::Bind(&APIActivityLogger::LogEvent));
-  RouteFunction("LogAPICall", base::Bind(&APIActivityLogger::LogAPICall));
-}
-
-// static
-void APIActivityLogger::LogAPICall(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  LogInternal(APICALL, args);
-}
-
-// static
-void APIActivityLogger::LogEvent(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  LogInternal(EVENT, args);
-}
-
-// static
-void APIActivityLogger::LogInternal(
-    const CallType call_type,
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  DCHECK_GT(args.Length(), 2);
-  DCHECK(args[0]->IsString());
-  DCHECK(args[1]->IsString());
-  DCHECK(args[2]->IsArray());
-
-  std::string ext_id = *v8::String::Utf8Value(args[0]);
-  ExtensionHostMsg_APIActionOrEvent_Params params;
-  params.api_call = *v8::String::Utf8Value(args[1]);
-  if (args.Length() == 4)  // Extras are optional.
-    params.extra = *v8::String::Utf8Value(args[3]);
-  else
-    params.extra = "";
-
-  // Get the array of api call arguments.
-  v8::Local<v8::Array> arg_array = v8::Local<v8::Array>::Cast(args[2]);
-  if (arg_array->Length() > 0) {
-    scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
-    ActivityLogConverterStrategy strategy;
-    converter->SetFunctionAllowed(true);
-    converter->SetStrategy(&strategy);
-    scoped_ptr<base::ListValue> arg_list(new base::ListValue());
-    for (size_t i = 0; i < arg_array->Length(); ++i) {
-      arg_list->Set(i,
-                    converter->FromV8Value(arg_array->Get(i),
-                    args.GetIsolate()->GetCurrentContext()));
-    }
-    params.arguments.Swap(arg_list.get());
-  }
-
-  if (call_type == APICALL) {
-    content::RenderThread::Get()->Send(
-        new ExtensionHostMsg_AddAPIActionToActivityLog(ext_id, params));
-  } else if (call_type == EVENT) {
-    content::RenderThread::Get()->Send(
-        new ExtensionHostMsg_AddEventToActivityLog(ext_id, params));
-  }
-}
-
-}  // namespace extensions
diff --git a/chrome/renderer/extensions/api_activity_logger.h b/chrome/renderer/extensions/api_activity_logger.h
deleted file mode 100644
index 7eb4565..0000000
--- a/chrome/renderer/extensions/api_activity_logger.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2013 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.
-
-#ifndef CHROME_RENDERER_EXTENSIONS_API_ACTIVITY_LOGGER_H_
-#define CHROME_RENDERER_EXTENSIONS_API_ACTIVITY_LOGGER_H_
-
-#include <string>
-
-#include "extensions/common/features/feature.h"
-#include "extensions/renderer/object_backed_native_handler.h"
-#include "v8/include/v8.h"
-
-namespace extensions {
-
-// Used to log extension API calls and events that are implemented with custom
-// bindings.The actions are sent via IPC to extensions::ActivityLog for
-// recording and display.
-class APIActivityLogger : public ObjectBackedNativeHandler {
- public:
-  explicit APIActivityLogger(ScriptContext* context);
-
- private:
-   // Used to distinguish API calls & events from each other in LogInternal.
-   enum CallType {
-     APICALL,
-     EVENT
-   };
-
-   // This is ultimately invoked in bindings.js with JavaScript arguments.
-   //    arg0 - extension ID as a string
-   //    arg1 - API call name as a string
-   //    arg2 - arguments to the API call
-   //    arg3 - any extra logging info as a string (optional)
-   static void LogAPICall(const v8::FunctionCallbackInfo<v8::Value>& args);
-
-   // This is ultimately invoked in bindings.js with JavaScript arguments.
-   //    arg0 - extension ID as a string
-   //    arg1 - Event name as a string
-   //    arg2 - Event arguments
-   //    arg3 - any extra logging info as a string (optional)
-   static void LogEvent(const v8::FunctionCallbackInfo<v8::Value>& args);
-
-   // LogAPICall and LogEvent are really the same underneath except for
-   // how they are ultimately dispatched to the log.
-   static void LogInternal(const CallType call_type,
-                           const v8::FunctionCallbackInfo<v8::Value>& args);
-
-  DISALLOW_COPY_AND_ASSIGN(APIActivityLogger);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_RENDERER_EXTENSIONS_API_ACTIVITY_LOGGER_H_
diff --git a/chrome/renderer/extensions/app_bindings.cc b/chrome/renderer/extensions/app_bindings.cc
index 6ec369c..f08213c 100644
--- a/chrome/renderer/extensions/app_bindings.cc
+++ b/chrome/renderer/extensions/app_bindings.cc
@@ -11,14 +11,14 @@
 #include "base/values.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
-#include "chrome/renderer/extensions/dispatcher.h"
-#include "chrome/renderer/extensions/extension_helper.h"
 #include "content/public/renderer/render_view.h"
 #include "content/public/renderer/v8_value_converter.h"
 #include "extensions/common/extension_messages.h"
 #include "extensions/common/extension_set.h"
 #include "extensions/common/manifest.h"
 #include "extensions/renderer/console.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/extension_helper.h"
 #include "extensions/renderer/script_context.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
diff --git a/chrome/renderer/extensions/app_runtime_custom_bindings.cc b/chrome/renderer/extensions/app_runtime_custom_bindings.cc
deleted file mode 100644
index 3d1016a..0000000
--- a/chrome/renderer/extensions/app_runtime_custom_bindings.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/renderer/extensions/app_runtime_custom_bindings.h"
-
-#include "base/bind.h"
-#include "base/strings/string_number_conversions.h"
-#include "third_party/WebKit/public/platform/WebCString.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/web/WebBlob.h"
-#include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
-
-using blink::WebBlob;
-using blink::WebSerializedScriptValue;
-using blink::WebString;
-
-namespace {
-
-void DeserializeString(const v8::FunctionCallbackInfo<v8::Value> &args) {
-  DCHECK(args.Length() == 1);
-  DCHECK(args[0]->IsString());
-
-  std::string data_v8(*v8::String::Utf8Value(args[0]));
-  WebString data_webstring = WebString::fromUTF8(data_v8);
-  WebSerializedScriptValue serialized =
-      WebSerializedScriptValue::fromString(data_webstring);
-  args.GetReturnValue().Set(serialized.deserialize());
-}
-
-void SerializeToString(const v8::FunctionCallbackInfo<v8::Value> &args) {
-  DCHECK(args.Length() == 1);
-  WebSerializedScriptValue data =
-      WebSerializedScriptValue::serialize(args[0]);
-  WebString data_webstring = data.toString();
-
-  std::string v = std::string(data_webstring.utf8());
-  args.GetReturnValue()
-      .Set(v8::String::NewFromUtf8(args.GetIsolate(), v.c_str()));
-}
-
-void CreateBlob(const v8::FunctionCallbackInfo<v8::Value> &args) {
-  DCHECK(args.Length() == 2);
-  DCHECK(args[0]->IsString());
-  DCHECK(args[1]->IsNumber());
-
-  std::string blob_file_path(*v8::String::Utf8Value(args[0]));
-  std::string blob_length_string(*v8::String::Utf8Value(args[1]));
-  int64 blob_length = 0;
-  DCHECK(base::StringToInt64(blob_length_string, &blob_length));
-  blink::WebBlob web_blob = WebBlob::createFromFile(
-      WebString::fromUTF8(blob_file_path), blob_length);
-  args.GetReturnValue().Set(web_blob.toV8Value());
-}
-
-}  // namespace
-
-namespace extensions {
-
-AppRuntimeCustomBindings::AppRuntimeCustomBindings(ScriptContext* context)
-    : ObjectBackedNativeHandler(context) {
-  RouteFunction("DeserializeString", base::Bind(&DeserializeString));
-  RouteFunction("SerializeToString", base::Bind(&SerializeToString));
-  RouteFunction("CreateBlob", base::Bind(&CreateBlob));
-}
-
-}  // namespace extensions
diff --git a/chrome/renderer/extensions/app_runtime_custom_bindings.h b/chrome/renderer/extensions/app_runtime_custom_bindings.h
deleted file mode 100644
index f83c0f7..0000000
--- a/chrome/renderer/extensions/app_runtime_custom_bindings.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_RENDERER_EXTENSIONS_APP_RUNTIME_CUSTOM_BINDINGS_H_
-#define CHROME_RENDERER_EXTENSIONS_APP_RUNTIME_CUSTOM_BINDINGS_H_
-
-#include "extensions/renderer/object_backed_native_handler.h"
-
-namespace extensions {
-
-// The native component of custom bindings for the chrome.app.runtime API.
-class AppRuntimeCustomBindings : public ObjectBackedNativeHandler {
- public:
-  explicit AppRuntimeCustomBindings(ScriptContext* context);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AppRuntimeCustomBindings);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_RENDERER_EXTENSIONS_APP_RUNTIME_CUSTOM_BINDINGS_H_
diff --git a/chrome/renderer/extensions/app_window_custom_bindings.cc b/chrome/renderer/extensions/app_window_custom_bindings.cc
index fe0ccac..d9df7b4 100644
--- a/chrome/renderer/extensions/app_window_custom_bindings.cc
+++ b/chrome/renderer/extensions/app_window_custom_bindings.cc
@@ -8,13 +8,13 @@
 
 #include "base/command_line.h"
 #include "chrome/common/chrome_switches.h"
-#include "chrome/renderer/extensions/dispatcher.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/render_view.h"
 #include "content/public/renderer/render_view_observer.h"
 #include "content/public/renderer/render_view_visitor.h"
 #include "content/public/renderer/v8_value_converter.h"
 #include "extensions/common/extension_messages.h"
+#include "extensions/renderer/dispatcher.h"
 #include "extensions/renderer/scoped_persistent.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/script_context_set.h"
diff --git a/chrome/renderer/extensions/cast_streaming_native_handler.cc b/chrome/renderer/extensions/cast_streaming_native_handler.cc
index 424ba05..c3fee5b 100644
--- a/chrome/renderer/extensions/cast_streaming_native_handler.cc
+++ b/chrome/renderer/extensions/cast_streaming_native_handler.cc
@@ -7,9 +7,9 @@
 #include <functional>
 #include <iterator>
 
-#include "base/base64.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
+#include "base/strings/string_number_conversions.h"
 #include "chrome/common/extensions/api/cast_streaming_rtp_stream.h"
 #include "chrome/common/extensions/api/cast_streaming_udp_transport.h"
 #include "chrome/renderer/media/cast_rtp_stream.h"
@@ -55,6 +55,16 @@
   ext_params->value = cast_params.value;
 }
 
+namespace {
+bool HexDecode(const std::string& input, std::string* output) {
+  std::vector<uint8> bytes;
+  if (!base::HexStringToBytes(input, &bytes))
+    return false;
+  output->assign(reinterpret_cast<const char*>(&bytes[0]), bytes.size());
+  return true;
+}
+}  // namespace
+
 bool ToCastRtpPayloadParamsOrThrow(v8::Isolate* isolate,
                                    const RtpPayloadParams& ext_params,
                                    CastRtpPayloadParams* cast_params) {
@@ -72,14 +82,13 @@
   cast_params->width = ext_params.width ? *ext_params.width : 0;
   cast_params->height = ext_params.height ? *ext_params.height : 0;
   if (ext_params.aes_key &&
-      !base::Base64Decode(*ext_params.aes_key, &cast_params->aes_key)) {
+      !HexDecode(*ext_params.aes_key, &cast_params->aes_key)) {
     isolate->ThrowException(v8::Exception::Error(
         v8::String::NewFromUtf8(isolate, kInvalidAesKey)));
     return false;
   }
   if (ext_params.aes_iv_mask &&
-      !base::Base64Decode(*ext_params.aes_iv_mask,
-                          &cast_params->aes_iv_mask)) {
+      !HexDecode(*ext_params.aes_iv_mask, &cast_params->aes_iv_mask)) {
     isolate->ThrowException(v8::Exception::Error(
         v8::String::NewFromUtf8(isolate, kInvalidAesIvMask)));
     return false;
diff --git a/chrome/renderer/extensions/chrome_extension_helper.cc b/chrome/renderer/extensions/chrome_extension_helper.cc
new file mode 100644
index 0000000..05ffc18
--- /dev/null
+++ b/chrome/renderer/extensions/chrome_extension_helper.cc
@@ -0,0 +1,60 @@
+// 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.
+
+#include "chrome/renderer/extensions/chrome_extension_helper.h"
+
+#include "base/strings/string16.h"
+#include "chrome/common/extensions/chrome_extension_messages.h"
+#include "chrome/renderer/web_apps.h"
+#include "content/public/common/url_constants.h"
+#include "content/public/renderer/render_view.h"
+#include "ipc/ipc_message_macros.h"
+#include "third_party/WebKit/public/web/WebView.h"
+#include "url/gurl.h"
+
+namespace extensions {
+
+ChromeExtensionHelper::ChromeExtensionHelper(content::RenderView* render_view)
+    : content::RenderViewObserver(render_view),
+      content::RenderViewObserverTracker<ChromeExtensionHelper>(render_view) {
+}
+
+ChromeExtensionHelper::~ChromeExtensionHelper() {
+}
+
+bool ChromeExtensionHelper::OnMessageReceived(
+    const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(ChromeExtensionHelper, message)
+    IPC_MESSAGE_HANDLER(ChromeExtensionMsg_GetApplicationInfo,
+                        OnGetApplicationInfo)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+void ChromeExtensionHelper::OnGetApplicationInfo(int page_id) {
+  WebApplicationInfo app_info;
+  if (page_id == render_view()->GetPageId()) {
+    base::string16 error;
+    web_apps::ParseWebAppFromWebDocument(
+        render_view()->GetWebView()->mainFrame(), &app_info, &error);
+  }
+
+  // Prune out any data URLs in the set of icons.  The browser process expects
+  // any icon with a data URL to have originated from a favicon.  We don't want
+  // to decode arbitrary data URLs in the browser process.  See
+  // http://b/issue?id=1162972
+  for (size_t i = 0; i < app_info.icons.size(); ++i) {
+    if (app_info.icons[i].url.SchemeIs(content::kDataScheme)) {
+      app_info.icons.erase(app_info.icons.begin() + i);
+      --i;
+    }
+  }
+
+  Send(new ChromeExtensionHostMsg_DidGetApplicationInfo(
+      routing_id(), page_id, app_info));
+}
+
+}  // namespace extensions
diff --git a/chrome/renderer/extensions/chrome_extension_helper.h b/chrome/renderer/extensions/chrome_extension_helper.h
new file mode 100644
index 0000000..e26ccda
--- /dev/null
+++ b/chrome/renderer/extensions/chrome_extension_helper.h
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef CHROME_RENDERER_EXTENSIONS_CHROME_EXTENSION_HELPER_H_
+#define CHROME_RENDERER_EXTENSIONS_CHROME_EXTENSION_HELPER_H_
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/renderer/render_view_observer.h"
+#include "content/public/renderer/render_view_observer_tracker.h"
+
+struct WebApplicationInfo;
+
+namespace extensions {
+
+// RenderView plumbing for Chrome-specific extension features.
+// See also extensions/renderer/extension_helper.h.
+class ChromeExtensionHelper
+    : public content::RenderViewObserver,
+      public content::RenderViewObserverTracker<ChromeExtensionHelper> {
+ public:
+  explicit ChromeExtensionHelper(content::RenderView* render_view);
+  virtual ~ChromeExtensionHelper();
+
+ private:
+  // RenderViewObserver implementation.
+  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
+  // IPC message handlers.
+  void OnGetApplicationInfo(int page_id);
+
+  // The app info that we are processing. This is used when installing an app
+  // via application definition. The in-progress web app is stored here while
+  // its manifest and icons are downloaded.
+  scoped_ptr<WebApplicationInfo> pending_app_info_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeExtensionHelper);
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_RENDERER_EXTENSIONS_CHROME_EXTENSION_HELPER_H_
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
new file mode 100644
index 0000000..a7ffbb2
--- /dev/null
+++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
@@ -0,0 +1,355 @@
+// 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.
+
+#include "chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h"
+
+#include "base/command_line.h"
+#include "base/sha1.h"
+#include "base/strings/string_number_conversions.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/chrome_version_info.h"
+#include "chrome/common/crash_keys.h"
+#include "chrome/common/extensions/features/feature_channel.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/renderer/extensions/app_bindings.h"
+#include "chrome/renderer/extensions/app_window_custom_bindings.h"
+#include "chrome/renderer/extensions/chrome_v8_context.h"
+#include "chrome/renderer/extensions/file_browser_handler_custom_bindings.h"
+#include "chrome/renderer/extensions/file_browser_private_custom_bindings.h"
+#include "chrome/renderer/extensions/media_galleries_custom_bindings.h"
+#include "chrome/renderer/extensions/page_actions_custom_bindings.h"
+#include "chrome/renderer/extensions/page_capture_custom_bindings.h"
+#include "chrome/renderer/extensions/pepper_request_natives.h"
+#include "chrome/renderer/extensions/sync_file_system_custom_bindings.h"
+#include "chrome/renderer/extensions/tab_finder.h"
+#include "chrome/renderer/extensions/tabs_custom_bindings.h"
+#include "chrome/renderer/extensions/webstore_bindings.h"
+#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/render_view.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/permissions/api_permission_set.h"
+#include "extensions/common/permissions/manifest_permission_set.h"
+#include "extensions/common/permissions/permission_set.h"
+#include "extensions/common/permissions/permissions_data.h"
+#include "extensions/common/url_pattern_set.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/native_handler.h"
+#include "extensions/renderer/resource_bundle_source_map.h"
+#include "extensions/renderer/script_context.h"
+#include "grit/renderer_resources.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
+
+#if defined(ENABLE_WEBRTC)
+#include "chrome/renderer/extensions/cast_streaming_native_handler.h"
+#endif
+
+using extensions::NativeHandler;
+
+ChromeExtensionsDispatcherDelegate::ChromeExtensionsDispatcherDelegate()
+    : webrequest_adblock_(false),
+      webrequest_adblock_plus_(false),
+      webrequest_other_(false) {
+}
+
+ChromeExtensionsDispatcherDelegate::~ChromeExtensionsDispatcherDelegate() {
+}
+
+scoped_ptr<extensions::ScriptContext>
+ChromeExtensionsDispatcherDelegate::CreateScriptContext(
+    const v8::Handle<v8::Context>& v8_context,
+    blink::WebFrame* frame,
+    const extensions::Extension* extension,
+    extensions::Feature::Context context_type) {
+  return scoped_ptr<extensions::ScriptContext>(new extensions::ChromeV8Context(
+      v8_context, frame, extension, context_type));
+}
+
+void ChromeExtensionsDispatcherDelegate::InitOriginPermissions(
+    const extensions::Extension* extension,
+    extensions::Feature::Context context_type) {
+  // TODO(jstritar): We should try to remove this special case. Also, these
+  // whitelist entries need to be updated when the kManagement permission
+  // changes.
+  if (context_type == extensions::Feature::BLESSED_EXTENSION_CONTEXT &&
+      extension->HasAPIPermission(extensions::APIPermission::kManagement)) {
+    blink::WebSecurityPolicy::addOriginAccessWhitelistEntry(
+        extension->url(),
+        blink::WebString::fromUTF8(content::kChromeUIScheme),
+        blink::WebString::fromUTF8(chrome::kChromeUIExtensionIconHost),
+        false);
+  }
+}
+
+void ChromeExtensionsDispatcherDelegate::RegisterNativeHandlers(
+    extensions::Dispatcher* dispatcher,
+    extensions::ModuleSystem* module_system,
+    extensions::ScriptContext* context) {
+#if !defined(ENABLE_EXTENSIONS)
+  return;
+#endif
+  module_system->RegisterNativeHandler(
+      "app",
+      scoped_ptr<NativeHandler>(
+          new extensions::AppBindings(dispatcher, context)));
+  module_system->RegisterNativeHandler(
+      "app_window_natives",
+      scoped_ptr<NativeHandler>(
+          new extensions::AppWindowCustomBindings(dispatcher, context)));
+  module_system->RegisterNativeHandler(
+      "sync_file_system",
+      scoped_ptr<NativeHandler>(
+          new extensions::SyncFileSystemCustomBindings(context)));
+  module_system->RegisterNativeHandler(
+      "file_browser_handler",
+      scoped_ptr<NativeHandler>(
+          new extensions::FileBrowserHandlerCustomBindings(context)));
+  module_system->RegisterNativeHandler(
+      "file_browser_private",
+      scoped_ptr<NativeHandler>(
+          new extensions::FileBrowserPrivateCustomBindings(context)));
+  module_system->RegisterNativeHandler(
+      "mediaGalleries",
+      scoped_ptr<NativeHandler>(
+          new extensions::MediaGalleriesCustomBindings(context)));
+  module_system->RegisterNativeHandler(
+      "page_actions",
+      scoped_ptr<NativeHandler>(
+          new extensions::PageActionsCustomBindings(dispatcher, context)));
+  module_system->RegisterNativeHandler(
+      "page_capture",
+      scoped_ptr<NativeHandler>(
+          new extensions::PageCaptureCustomBindings(context)));
+  module_system->RegisterNativeHandler(
+      "pepper_request_natives",
+      scoped_ptr<NativeHandler>(new extensions::PepperRequestNatives(context)));
+  module_system->RegisterNativeHandler(
+      "tabs",
+      scoped_ptr<NativeHandler>(new extensions::TabsCustomBindings(context)));
+  module_system->RegisterNativeHandler(
+      "webstore",
+      scoped_ptr<NativeHandler>(new extensions::WebstoreBindings(context)));
+#if defined(ENABLE_WEBRTC)
+  module_system->RegisterNativeHandler(
+      "cast_streaming_natives",
+      scoped_ptr<NativeHandler>(
+          new extensions::CastStreamingNativeHandler(context)));
+#endif
+}
+
+void ChromeExtensionsDispatcherDelegate::PopulateSourceMap(
+    extensions::ResourceBundleSourceMap* source_map) {
+  // Libraries.
+  source_map->RegisterSource("pepper_request", IDR_PEPPER_REQUEST_JS);
+
+  // Custom bindings.
+  source_map->RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("app.window", IDR_APP_WINDOW_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("automation", IDR_AUTOMATION_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("automationEvent", IDR_AUTOMATION_EVENT_JS);
+  source_map->RegisterSource("automationNode", IDR_AUTOMATION_NODE_JS);
+  source_map->RegisterSource("automationTree", IDR_AUTOMATION_TREE_JS);
+  source_map->RegisterSource("browserAction",
+                             IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("declarativeContent",
+                             IDR_DECLARATIVE_CONTENT_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("declarativeWebRequest",
+                             IDR_DECLARATIVE_WEBREQUEST_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("desktopCapture",
+                             IDR_DESKTOP_CAPTURE_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("developerPrivate",
+                             IDR_DEVELOPER_PRIVATE_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("downloads", IDR_DOWNLOADS_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("feedbackPrivate",
+                             IDR_FEEDBACK_PRIVATE_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("fileBrowserHandler",
+                             IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("fileBrowserPrivate",
+                             IDR_FILE_BROWSER_PRIVATE_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("fileSystem", IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("fileSystemProvider",
+                             IDR_FILE_SYSTEM_PROVIDER_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("gcm", IDR_GCM_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("identity", IDR_IDENTITY_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("imageWriterPrivate",
+                             IDR_IMAGE_WRITER_PRIVATE_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("mediaGalleries",
+                             IDR_MEDIA_GALLERIES_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("notifications",
+                             IDR_NOTIFICATIONS_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("omnibox", IDR_OMNIBOX_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("pageActions",
+                             IDR_PAGE_ACTIONS_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("pageCapture",
+                             IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("syncFileSystem",
+                             IDR_SYNC_FILE_SYSTEM_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("systemIndicator",
+                             IDR_SYSTEM_INDICATOR_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("tabCapture", IDR_TAB_CAPTURE_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("tabs", IDR_TABS_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("webRequest", IDR_WEB_REQUEST_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("webRequestInternal",
+                             IDR_WEB_REQUEST_INTERNAL_CUSTOM_BINDINGS_JS);
+#if defined(ENABLE_WEBRTC)
+  source_map->RegisterSource("cast.streaming.rtpStream",
+                             IDR_CAST_STREAMING_RTP_STREAM_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("cast.streaming.session",
+                             IDR_CAST_STREAMING_SESSION_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource(
+      "cast.streaming.udpTransport",
+      IDR_CAST_STREAMING_UDP_TRANSPORT_CUSTOM_BINDINGS_JS);
+#endif
+  source_map->RegisterSource("webstore", IDR_WEBSTORE_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("windowControls", IDR_WINDOW_CONTROLS_JS);
+
+  // Custom types sources.
+  source_map->RegisterSource("ChromeSetting", IDR_CHROME_SETTING_JS);
+  source_map->RegisterSource("ContentSetting", IDR_CONTENT_SETTING_JS);
+  source_map->RegisterSource("ChromeDirectSetting",
+                             IDR_CHROME_DIRECT_SETTING_JS);
+
+  // Platform app sources that are not API-specific..
+  source_map->RegisterSource("tagWatcher", IDR_TAG_WATCHER_JS);
+  source_map->RegisterSource("webview", IDR_WEBVIEW_CUSTOM_BINDINGS_JS);
+  // Note: webView not webview so that this doesn't interfere with the
+  // chrome.webview API bindings.
+  source_map->RegisterSource("webView", IDR_WEB_VIEW_JS);
+  source_map->RegisterSource("webViewExperimental",
+                             IDR_WEB_VIEW_EXPERIMENTAL_JS);
+  source_map->RegisterSource("webViewRequest",
+                             IDR_WEB_VIEW_REQUEST_CUSTOM_BINDINGS_JS);
+  source_map->RegisterSource("denyWebView", IDR_WEB_VIEW_DENY_JS);
+  source_map->RegisterSource("adView", IDR_AD_VIEW_JS);
+  source_map->RegisterSource("denyAdView", IDR_AD_VIEW_DENY_JS);
+  source_map->RegisterSource("injectAppTitlebar", IDR_INJECT_APP_TITLEBAR_JS);
+}
+
+void ChromeExtensionsDispatcherDelegate::RequireAdditionalModules(
+    extensions::ModuleSystem* module_system,
+    const extensions::Extension* extension,
+    extensions::Feature::Context context_type,
+    bool is_within_platform_app) {
+  if (context_type == extensions::Feature::BLESSED_EXTENSION_CONTEXT &&
+      is_within_platform_app &&
+      extensions::GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV &&
+      CommandLine::ForCurrentProcess()->HasSwitch(
+          ::switches::kEnableAppWindowControls)) {
+    module_system->Require("windowControls");
+  }
+
+  // We used to limit WebView to |BLESSED_EXTENSION_CONTEXT| within platform
+  // apps. An ext/app runs in a blessed extension context, if it is the active
+  // extension in the current process, in other words, if it is loaded in a top
+  // frame. To support webview in a non-frame extension, we have to allow
+  // unblessed extension context as well.
+  // Note: setting up the WebView class here, not the chrome.webview API.
+  // The API will be automatically set up when first used.
+  if (context_type == extensions::Feature::BLESSED_EXTENSION_CONTEXT ||
+      context_type == extensions::Feature::UNBLESSED_EXTENSION_CONTEXT) {
+    if (extension->HasAPIPermission(extensions::APIPermission::kWebView)) {
+      module_system->Require("webView");
+      if (extensions::GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV) {
+        module_system->Require("webViewExperimental");
+      } else {
+        // TODO(asargent) We need a whitelist for webview experimental.
+        // crbug.com/264852
+        std::string id_hash = base::SHA1HashString(extension->id());
+        std::string hexencoded_id_hash =
+            base::HexEncode(id_hash.c_str(), id_hash.length());
+        if (hexencoded_id_hash == "8C3741E3AF0B93B6E8E0DDD499BB0B74839EA578" ||
+            hexencoded_id_hash == "E703483CEF33DEC18B4B6DD84B5C776FB9182BDB" ||
+            hexencoded_id_hash == "1A26E32DE447A17CBE5E9750CDBA78F58539B39C" ||
+            hexencoded_id_hash == "59048028102D7B4C681DBC7BC6CD980C3DC66DA3") {
+          module_system->Require("webViewExperimental");
+        }
+      }
+    } else {
+      module_system->Require("denyWebView");
+    }
+  }
+
+  // Same comment as above for <adview> tag.
+  if (context_type == extensions::Feature::BLESSED_EXTENSION_CONTEXT &&
+      is_within_platform_app) {
+    if (CommandLine::ForCurrentProcess()->HasSwitch(
+            ::switches::kEnableAdview)) {
+      if (extension->HasAPIPermission(extensions::APIPermission::kAdView)) {
+        module_system->Require("adView");
+      } else {
+        module_system->Require("denyAdView");
+      }
+    }
+  }
+}
+
+void ChromeExtensionsDispatcherDelegate::OnActiveExtensionsUpdated(
+    const std::set<std::string>& extension_ids) {
+  // In single-process mode, the browser process reports the active extensions.
+  if (CommandLine::ForCurrentProcess()->HasSwitch(::switches::kSingleProcess))
+    return;
+  crash_keys::SetActiveExtensions(extension_ids);
+}
+
+void ChromeExtensionsDispatcherDelegate::SetChannel(int channel) {
+  extensions::SetCurrentChannel(
+      static_cast<chrome::VersionInfo::Channel>(channel));
+}
+
+void ChromeExtensionsDispatcherDelegate::ClearTabSpecificPermissions(
+    const extensions::Dispatcher* dispatcher,
+    int tab_id,
+    const std::vector<std::string>& extension_ids) {
+  for (std::vector<std::string>::const_iterator it = extension_ids.begin();
+       it != extension_ids.end();
+       ++it) {
+    const extensions::Extension* extension =
+        dispatcher->extensions()->GetByID(*it);
+    if (extension)
+      extensions::PermissionsData::ClearTabSpecificPermissions(extension,
+                                                               tab_id);
+  }
+}
+
+void ChromeExtensionsDispatcherDelegate::UpdateTabSpecificPermissions(
+    const extensions::Dispatcher* dispatcher,
+    int page_id,
+    int tab_id,
+    const std::string& extension_id,
+    const extensions::URLPatternSet& origin_set) {
+  content::RenderView* view = extensions::TabFinder::Find(tab_id);
+
+  // For now, the message should only be sent to the render view that contains
+  // the target tab. This may change. Either way, if this is the target tab it
+  // gives us the chance to check against the page ID to avoid races.
+  DCHECK(view);
+  if (view && view->GetPageId() != page_id)
+    return;
+
+  const extensions::Extension* extension =
+      dispatcher->extensions()->GetByID(extension_id);
+  if (!extension)
+    return;
+
+  extensions::PermissionsData::UpdateTabSpecificPermissions(
+      extension,
+      tab_id,
+      new extensions::PermissionSet(extensions::APIPermissionSet(),
+                                    extensions::ManifestPermissionSet(),
+                                    origin_set,
+                                    extensions::URLPatternSet()));
+}
+
+void ChromeExtensionsDispatcherDelegate::HandleWebRequestAPIUsage(
+    bool adblock,
+    bool adblock_plus,
+    bool other) {
+  webrequest_adblock_ = adblock;
+  webrequest_adblock_plus_ = adblock_plus;
+  webrequest_other_ = other;
+}
diff --git a/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h
new file mode 100644
index 0000000..5a24e2b
--- /dev/null
+++ b/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h
@@ -0,0 +1,74 @@
+// 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.
+
+#ifndef CHROME_RENDERER_EXTENSIONS_CHROME_EXTENSIONS_DISPATCHER_DELEGATE_H_
+#define CHROME_RENDERER_EXTENSIONS_CHROME_EXTENSIONS_DISPATCHER_DELEGATE_H_
+
+#include "extensions/renderer/dispatcher_delegate.h"
+
+class ChromeExtensionsDispatcherDelegate
+    : public extensions::DispatcherDelegate {
+ public:
+  ChromeExtensionsDispatcherDelegate();
+  virtual ~ChromeExtensionsDispatcherDelegate();
+
+  // TODO(mpcomplete): remove. http://crbug.com/100411
+  bool IsAdblockWithWebRequestInstalled() const { return webrequest_adblock_; }
+
+  bool IsAdblockPlusWithWebRequestInstalled() const {
+    return webrequest_adblock_plus_;
+  }
+
+  bool IsOtherExtensionWithWebRequestInstalled() const {
+    return webrequest_other_;
+  }
+
+ private:
+  // extensions::DispatcherDelegate implementation.
+  virtual scoped_ptr<extensions::ScriptContext> CreateScriptContext(
+      const v8::Handle<v8::Context>& v8_context,
+      blink::WebFrame* frame,
+      const extensions::Extension* extension,
+      extensions::Feature::Context context_type) OVERRIDE;
+  virtual void InitOriginPermissions(
+      const extensions::Extension* extension,
+      extensions::Feature::Context context_type) OVERRIDE;
+  virtual void RegisterNativeHandlers(
+      extensions::Dispatcher* dispatcher,
+      extensions::ModuleSystem* module_system,
+      extensions::ScriptContext* context) OVERRIDE;
+  virtual void PopulateSourceMap(
+      extensions::ResourceBundleSourceMap* source_map) OVERRIDE;
+  virtual void RequireAdditionalModules(
+      extensions::ModuleSystem* module_system,
+      const extensions::Extension* extension,
+      extensions::Feature::Context context_type,
+      bool is_within_platform_app) OVERRIDE;
+  virtual void OnActiveExtensionsUpdated(
+      const std::set<std::string>& extensions_ids) OVERRIDE;
+  virtual void SetChannel(int channel) OVERRIDE;
+  virtual void ClearTabSpecificPermissions(
+      const extensions::Dispatcher* dispatcher,
+      int tab_id,
+      const std::vector<std::string>& extension_ids) OVERRIDE;
+  virtual void UpdateTabSpecificPermissions(
+      const extensions::Dispatcher* dispatcher,
+      int page_id,
+      int tab_id,
+      const std::string& extension_id,
+      const extensions::URLPatternSet& origin_set) OVERRIDE;
+  virtual void HandleWebRequestAPIUsage(bool adblock,
+                                        bool adblock_plus,
+                                        bool other_webrequest) OVERRIDE;
+
+  // Status of webrequest usage for known extensions.
+  // TODO(mpcomplete): remove. http://crbug.com/100411
+  bool webrequest_adblock_;
+  bool webrequest_adblock_plus_;
+  bool webrequest_other_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeExtensionsDispatcherDelegate);
+};
+
+#endif  // CHROME_RENDERER_EXTENSIONS_CHROME_EXTENSIONS_DISPATCHER_DELEGATE_H_
diff --git a/chrome/renderer/extensions/chrome_extensions_renderer_client.cc b/chrome/renderer/extensions/chrome_extensions_renderer_client.cc
index cd0b732..c3ef38d 100644
--- a/chrome/renderer/extensions/chrome_extensions_renderer_client.cc
+++ b/chrome/renderer/extensions/chrome_extensions_renderer_client.cc
@@ -26,12 +26,3 @@
 int ChromeExtensionsRendererClient::GetLowestIsolatedWorldId() const {
   return chrome::ISOLATED_WORLD_ID_EXTENSIONS;
 }
-
-void ChromeExtensionsRendererClient::RegisterNativeHandlers(
-    extensions::ModuleSystem* module_system,
-    extensions::ScriptContext* context) {
-}
-
-void ChromeExtensionsRendererClient::PopulateSourceMap(
-    ResourceBundleSourceMap* source_map) {
-}
diff --git a/chrome/renderer/extensions/chrome_extensions_renderer_client.h b/chrome/renderer/extensions/chrome_extensions_renderer_client.h
index 092e52f..801bc1a 100644
--- a/chrome/renderer/extensions/chrome_extensions_renderer_client.h
+++ b/chrome/renderer/extensions/chrome_extensions_renderer_client.h
@@ -20,10 +20,6 @@
   // extensions::ExtensionsRendererClient implementation.
   virtual bool IsIncognitoProcess() const OVERRIDE;
   virtual int GetLowestIsolatedWorldId() const OVERRIDE;
-  virtual void RegisterNativeHandlers(
-      extensions::ModuleSystem* module_system,
-      extensions::ScriptContext* context) OVERRIDE;
-  virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) OVERRIDE;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ChromeExtensionsRendererClient);
diff --git a/chrome/renderer/extensions/chrome_v8_context.cc b/chrome/renderer/extensions/chrome_v8_context.cc
index 795d298..8d58f70 100644
--- a/chrome/renderer/extensions/chrome_v8_context.cc
+++ b/chrome/renderer/extensions/chrome_v8_context.cc
@@ -7,21 +7,22 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string_split.h"
 #include "base/values.h"
-#include "chrome/renderer/extensions/user_script_slave.h"
 #include "extensions/common/extension_api.h"
 #include "extensions/common/extension_urls.h"
 #include "extensions/common/features/base_feature_provider.h"
 #include "extensions/renderer/module_system.h"
+#include "extensions/renderer/user_script_slave.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
 #include "v8/include/v8.h"
 
 namespace extensions {
 
-ChromeV8Context::ChromeV8Context(v8::Handle<v8::Context> v8_context,
+ChromeV8Context::ChromeV8Context(const v8::Handle<v8::Context>& v8_context,
                                  blink::WebFrame* web_frame,
                                  const Extension* extension,
                                  Feature::Context context_type)
     : ScriptContext(v8_context, web_frame, extension, context_type),
-      pepper_request_proxy_(this) {}
+      pepper_request_proxy_(this) {
+}
 
 }  // namespace extensions
diff --git a/chrome/renderer/extensions/chrome_v8_context.h b/chrome/renderer/extensions/chrome_v8_context.h
index 41c8403..d4779db 100644
--- a/chrome/renderer/extensions/chrome_v8_context.h
+++ b/chrome/renderer/extensions/chrome_v8_context.h
@@ -32,7 +32,7 @@
 // Chrome's wrapper for a v8 context.
 class ChromeV8Context : public ScriptContext {
  public:
-  ChromeV8Context(v8::Handle<v8::Context> context,
+  ChromeV8Context(const v8::Handle<v8::Context>& context,
                   blink::WebFrame* frame,
                   const Extension* extension,
                   Feature::Context context_type);
diff --git a/chrome/renderer/extensions/dispatcher.cc b/chrome/renderer/extensions/dispatcher.cc
deleted file mode 100644
index 28254f6..0000000
--- a/chrome/renderer/extensions/dispatcher.cc
+++ /dev/null
@@ -1,1722 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/renderer/extensions/dispatcher.h"
-
-#include "base/callback.h"
-#include "base/command_line.h"
-#include "base/debug/alias.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/metrics/user_metrics_action.h"
-#include "base/sha1.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/values.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/chrome_version_info.h"
-#include "chrome/common/crash_keys.h"
-#include "chrome/common/extensions/features/feature_channel.h"
-#include "chrome/common/extensions/manifest_handlers/externally_connectable.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/renderer/chrome_render_process_observer.h"
-#include "chrome/renderer/extensions/api_activity_logger.h"
-#include "chrome/renderer/extensions/app_bindings.h"
-#include "chrome/renderer/extensions/app_runtime_custom_bindings.h"
-#include "chrome/renderer/extensions/app_window_custom_bindings.h"
-#include "chrome/renderer/extensions/chrome_v8_context.h"
-#include "chrome/renderer/extensions/extension_helper.h"
-#include "chrome/renderer/extensions/file_browser_handler_custom_bindings.h"
-#include "chrome/renderer/extensions/file_browser_private_custom_bindings.h"
-#include "chrome/renderer/extensions/media_galleries_custom_bindings.h"
-#include "chrome/renderer/extensions/messaging_bindings.h"
-#include "chrome/renderer/extensions/page_actions_custom_bindings.h"
-#include "chrome/renderer/extensions/page_capture_custom_bindings.h"
-#include "chrome/renderer/extensions/pepper_request_natives.h"
-#include "chrome/renderer/extensions/runtime_custom_bindings.h"
-#include "chrome/renderer/extensions/sync_file_system_custom_bindings.h"
-#include "chrome/renderer/extensions/tab_finder.h"
-#include "chrome/renderer/extensions/tabs_custom_bindings.h"
-#include "chrome/renderer/extensions/user_script_slave.h"
-#include "chrome/renderer/extensions/webstore_bindings.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/public/renderer/render_view.h"
-#include "content/public/renderer/v8_value_converter.h"
-#include "extensions/common/api/messaging/message.h"
-#include "extensions/common/constants.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/extension_api.h"
-#include "extensions/common/extension_messages.h"
-#include "extensions/common/extension_urls.h"
-#include "extensions/common/features/feature.h"
-#include "extensions/common/features/feature_provider.h"
-#include "extensions/common/features/json_feature_provider_source.h"
-#include "extensions/common/manifest.h"
-#include "extensions/common/manifest_constants.h"
-#include "extensions/common/manifest_handlers/background_info.h"
-#include "extensions/common/manifest_handlers/sandboxed_page_info.h"
-#include "extensions/common/message_bundle.h"
-#include "extensions/common/permissions/permission_set.h"
-#include "extensions/common/permissions/permissions_data.h"
-#include "extensions/common/switches.h"
-#include "extensions/common/view_type.h"
-#include "extensions/renderer/api_definitions_natives.h"
-#include "extensions/renderer/binding_generating_native_handler.h"
-#include "extensions/renderer/blob_native_handler.h"
-#include "extensions/renderer/content_watcher.h"
-#include "extensions/renderer/context_menus_custom_bindings.h"
-#include "extensions/renderer/css_native_handler.h"
-#include "extensions/renderer/document_custom_bindings.h"
-#include "extensions/renderer/dom_activity_logger.h"
-#include "extensions/renderer/event_bindings.h"
-#include "extensions/renderer/extension_groups.h"
-#include "extensions/renderer/extensions_renderer_client.h"
-#include "extensions/renderer/file_system_natives.h"
-#include "extensions/renderer/i18n_custom_bindings.h"
-#include "extensions/renderer/id_generator_custom_bindings.h"
-#include "extensions/renderer/logging_native_handler.h"
-#include "extensions/renderer/module_system.h"
-#include "extensions/renderer/object_backed_native_handler.h"
-#include "extensions/renderer/render_view_observer_natives.h"
-#include "extensions/renderer/request_sender.h"
-#include "extensions/renderer/safe_builtins.h"
-#include "extensions/renderer/script_context.h"
-#include "extensions/renderer/script_context_set.h"
-#include "extensions/renderer/send_request_natives.h"
-#include "extensions/renderer/set_icon_natives.h"
-#include "extensions/renderer/utils_native_handler.h"
-#include "grit/common_resources.h"
-#include "grit/extensions_resources.h"
-#include "grit/renderer_resources.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/platform/WebURLRequest.h"
-#include "third_party/WebKit/public/web/WebCustomElement.h"
-#include "third_party/WebKit/public/web/WebDataSource.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
-#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
-#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
-#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
-#include "third_party/WebKit/public/web/WebView.h"
-#include "ui/base/layout.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "v8/include/v8.h"
-
-#if defined(ENABLE_WEBRTC)
-#include "chrome/renderer/extensions/cast_streaming_native_handler.h"
-#endif
-
-using base::UserMetricsAction;
-using blink::WebDataSource;
-using blink::WebDocument;
-using blink::WebFrame;
-using blink::WebScopedUserGesture;
-using blink::WebSecurityPolicy;
-using blink::WebString;
-using blink::WebVector;
-using blink::WebView;
-using content::RenderThread;
-using content::RenderView;
-
-namespace extensions {
-
-namespace {
-
-static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000;
-static const int64 kMaxExtensionIdleHandlerDelayMs = 5*60*1000;
-static const char kEventDispatchFunction[] = "dispatchEvent";
-static const char kOnSuspendEvent[] = "runtime.onSuspend";
-static const char kOnSuspendCanceledEvent[] = "runtime.onSuspendCanceled";
-
-// Returns the global value for "chrome" from |context|. If one doesn't exist
-// creates a new object for it.
-//
-// Note that this isn't necessarily an object, since webpages can write, for
-// example, "window.chrome = true".
-v8::Handle<v8::Value> GetOrCreateChrome(ScriptContext* context) {
-  v8::Handle<v8::String> chrome_string(
-      v8::String::NewFromUtf8(context->isolate(), "chrome"));
-  v8::Handle<v8::Object> global(context->v8_context()->Global());
-  v8::Handle<v8::Value> chrome(global->Get(chrome_string));
-  if (chrome->IsUndefined()) {
-    chrome = v8::Object::New(context->isolate());
-    global->Set(chrome_string, chrome);
-  }
-  return chrome;
-}
-
-// Returns |value| cast to an object if possible, else an empty handle.
-v8::Handle<v8::Object> AsObjectOrEmpty(v8::Handle<v8::Value> value) {
-  return value->IsObject() ? value.As<v8::Object>() : v8::Handle<v8::Object>();
-}
-
-class TestFeaturesNativeHandler : public ObjectBackedNativeHandler {
- public:
-  explicit TestFeaturesNativeHandler(ScriptContext* context)
-      : ObjectBackedNativeHandler(context) {
-    RouteFunction("GetAPIFeatures",
-        base::Bind(&TestFeaturesNativeHandler::GetAPIFeatures,
-                   base::Unretained(this)));
-  }
-
- private:
-  void GetAPIFeatures(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    JSONFeatureProviderSource source("api");
-    source.LoadJSON(IDR_CHROME_EXTENSION_API_FEATURES);
-    source.LoadJSON(IDR_EXTENSION_API_FEATURES);
-    scoped_ptr<content::V8ValueConverter> converter(
-        content::V8ValueConverter::create());
-    args.GetReturnValue().Set(
-        converter->ToV8Value(&source.dictionary(), context()->v8_context()));
-  }
-};
-
-class UserGesturesNativeHandler : public ObjectBackedNativeHandler {
- public:
-  explicit UserGesturesNativeHandler(ScriptContext* context)
-      : ObjectBackedNativeHandler(context) {
-    RouteFunction("IsProcessingUserGesture",
-        base::Bind(&UserGesturesNativeHandler::IsProcessingUserGesture,
-                   base::Unretained(this)));
-    RouteFunction("RunWithUserGesture",
-        base::Bind(&UserGesturesNativeHandler::RunWithUserGesture,
-                   base::Unretained(this)));
-    RouteFunction("RunWithoutUserGesture",
-        base::Bind(&UserGesturesNativeHandler::RunWithoutUserGesture,
-                   base::Unretained(this)));
-  }
-
- private:
-  void IsProcessingUserGesture(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    args.GetReturnValue().Set(v8::Boolean::New(
-        args.GetIsolate(),
-        blink::WebUserGestureIndicator::isProcessingUserGesture()));
-  }
-
-  void RunWithUserGesture(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    blink::WebScopedUserGesture user_gesture;
-    CHECK_EQ(args.Length(), 1);
-    CHECK(args[0]->IsFunction());
-    v8::Handle<v8::Value> no_args;
-    context()->CallFunction(v8::Handle<v8::Function>::Cast(args[0]),
-                            0, &no_args);
-  }
-
-  void RunWithoutUserGesture(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    blink::WebUserGestureIndicator::consumeUserGesture();
-    CHECK_EQ(args.Length(), 1);
-    CHECK(args[0]->IsFunction());
-    v8::Handle<v8::Value> no_args;
-    context()->CallFunction(v8::Handle<v8::Function>::Cast(args[0]),
-                            0, &no_args);
-  }
-};
-
-class V8ContextNativeHandler : public ObjectBackedNativeHandler {
- public:
-  V8ContextNativeHandler(ScriptContext* context, Dispatcher* dispatcher)
-      : ObjectBackedNativeHandler(context),
-        context_(context),
-        dispatcher_(dispatcher) {
-    RouteFunction("GetAvailability",
-        base::Bind(&V8ContextNativeHandler::GetAvailability,
-                   base::Unretained(this)));
-    RouteFunction("GetModuleSystem",
-        base::Bind(&V8ContextNativeHandler::GetModuleSystem,
-                   base::Unretained(this)));
-  }
-
- private:
-  void GetAvailability(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    CHECK_EQ(args.Length(), 1);
-    v8::Isolate* isolate = args.GetIsolate();
-    std::string api_name = *v8::String::Utf8Value(args[0]->ToString());
-    Feature::Availability availability = context_->GetAvailability(api_name);
-
-    v8::Handle<v8::Object> ret = v8::Object::New(isolate);
-    ret->Set(v8::String::NewFromUtf8(isolate, "is_available"),
-             v8::Boolean::New(isolate, availability.is_available()));
-    ret->Set(v8::String::NewFromUtf8(isolate, "message"),
-             v8::String::NewFromUtf8(isolate, availability.message().c_str()));
-    ret->Set(v8::String::NewFromUtf8(isolate, "result"),
-             v8::Integer::New(isolate, availability.result()));
-    args.GetReturnValue().Set(ret);
-  }
-
-  void GetModuleSystem(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    CHECK_EQ(args.Length(), 1);
-    CHECK(args[0]->IsObject());
-    v8::Handle<v8::Context> v8_context =
-        v8::Handle<v8::Object>::Cast(args[0])->CreationContext();
-    ScriptContext* context =
-        dispatcher_->script_context_set().GetByV8Context(v8_context);
-    args.GetReturnValue().Set(context->module_system()->NewInstance());
-  }
-
-  ScriptContext* context_;
-  Dispatcher* dispatcher_;
-};
-
-class ChromeNativeHandler : public ObjectBackedNativeHandler {
- public:
-  explicit ChromeNativeHandler(ScriptContext* context)
-      : ObjectBackedNativeHandler(context) {
-    RouteFunction("GetChrome",
-        base::Bind(&ChromeNativeHandler::GetChrome, base::Unretained(this)));
-  }
-
-  void GetChrome(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    args.GetReturnValue().Set(GetOrCreateChrome(context()));
-  }
-};
-
-class PrintNativeHandler : public ObjectBackedNativeHandler {
- public:
-  explicit PrintNativeHandler(ScriptContext* context)
-      : ObjectBackedNativeHandler(context) {
-    RouteFunction("Print",
-        base::Bind(&PrintNativeHandler::Print,
-                   base::Unretained(this)));
-  }
-
-  void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    if (args.Length() < 1)
-      return;
-
-    std::vector<std::string> components;
-    for (int i = 0; i < args.Length(); ++i)
-      components.push_back(*v8::String::Utf8Value(args[i]->ToString()));
-
-    LOG(ERROR) << JoinString(components, ',');
-  }
-};
-
-class LazyBackgroundPageNativeHandler : public ObjectBackedNativeHandler {
- public:
-  explicit LazyBackgroundPageNativeHandler(ScriptContext* context)
-      : ObjectBackedNativeHandler(context) {
-    RouteFunction("IncrementKeepaliveCount",
-        base::Bind(&LazyBackgroundPageNativeHandler::IncrementKeepaliveCount,
-                   base::Unretained(this)));
-    RouteFunction("DecrementKeepaliveCount",
-        base::Bind(&LazyBackgroundPageNativeHandler::DecrementKeepaliveCount,
-                   base::Unretained(this)));
-  }
-
-  void IncrementKeepaliveCount(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    if (!context())
-      return;
-    RenderView* render_view = context()->GetRenderView();
-    if (IsContextLazyBackgroundPage(render_view, context()->extension())) {
-      render_view->Send(new ExtensionHostMsg_IncrementLazyKeepaliveCount(
-          render_view->GetRoutingID()));
-    }
-  }
-
-  void DecrementKeepaliveCount(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    if (!context())
-      return;
-    RenderView* render_view = context()->GetRenderView();
-    if (IsContextLazyBackgroundPage(render_view, context()->extension())) {
-      render_view->Send(new ExtensionHostMsg_DecrementLazyKeepaliveCount(
-          render_view->GetRoutingID()));
-    }
-  }
-
- private:
-  bool IsContextLazyBackgroundPage(RenderView* render_view,
-                                   const Extension* extension) {
-    if (!render_view)
-      return false;
-
-    ExtensionHelper* helper = ExtensionHelper::Get(render_view);
-    return (extension && BackgroundInfo::HasLazyBackgroundPage(extension) &&
-            helper->view_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
-  }
-};
-
-class ProcessInfoNativeHandler : public ObjectBackedNativeHandler {
- public:
-  ProcessInfoNativeHandler(ScriptContext* context,
-                           const std::string& extension_id,
-                           const std::string& context_type,
-                           bool is_incognito_context,
-                           int manifest_version,
-                           bool send_request_disabled)
-      : ObjectBackedNativeHandler(context),
-        extension_id_(extension_id),
-        context_type_(context_type),
-        is_incognito_context_(is_incognito_context),
-        manifest_version_(manifest_version),
-        send_request_disabled_(send_request_disabled) {
-    RouteFunction("GetExtensionId",
-        base::Bind(&ProcessInfoNativeHandler::GetExtensionId,
-                   base::Unretained(this)));
-    RouteFunction("GetContextType",
-        base::Bind(&ProcessInfoNativeHandler::GetContextType,
-                   base::Unretained(this)));
-    RouteFunction("InIncognitoContext",
-        base::Bind(&ProcessInfoNativeHandler::InIncognitoContext,
-                   base::Unretained(this)));
-    RouteFunction("GetManifestVersion",
-        base::Bind(&ProcessInfoNativeHandler::GetManifestVersion,
-                   base::Unretained(this)));
-    RouteFunction("IsSendRequestDisabled",
-        base::Bind(&ProcessInfoNativeHandler::IsSendRequestDisabled,
-                   base::Unretained(this)));
-    RouteFunction("HasSwitch",
-        base::Bind(&ProcessInfoNativeHandler::HasSwitch,
-                   base::Unretained(this)));
-  }
-
- private:
-  void GetExtensionId(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    args.GetReturnValue()
-        .Set(v8::String::NewFromUtf8(args.GetIsolate(), extension_id_.c_str()));
-  }
-
-  void GetContextType(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    args.GetReturnValue()
-        .Set(v8::String::NewFromUtf8(args.GetIsolate(), context_type_.c_str()));
-  }
-
-  void InIncognitoContext(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    args.GetReturnValue().Set(is_incognito_context_);
-  }
-
-  void GetManifestVersion(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    args.GetReturnValue().Set(static_cast<int32_t>(manifest_version_));
-  }
-
-  void IsSendRequestDisabled(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    if (send_request_disabled_) {
-      args.GetReturnValue().Set(v8::String::NewFromUtf8(args.GetIsolate(),
-          "sendRequest and onRequest are obsolete."
-          " Please use sendMessage and onMessage instead."));
-    }
-  }
-
-  void HasSwitch(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    CHECK(args.Length() == 1 && args[0]->IsString());
-    bool has_switch = CommandLine::ForCurrentProcess()->HasSwitch(
-        *v8::String::Utf8Value(args[0]));
-    args.GetReturnValue().Set(v8::Boolean::New(args.GetIsolate(), has_switch));
-  }
-
-  std::string extension_id_;
-  std::string context_type_;
-  bool is_incognito_context_;
-  int manifest_version_;
-  bool send_request_disabled_;
-};
-
-void InstallAppBindings(ModuleSystem* module_system,
-                        v8::Handle<v8::Object> chrome) {
-  module_system->SetLazyField(chrome, "app", "app", "chromeApp");
-}
-
-void InstallWebstoreBindings(ModuleSystem* module_system,
-                             v8::Handle<v8::Object> chrome) {
-  module_system->SetLazyField(chrome, "webstore", "webstore", "chromeWebstore");
-}
-
-// Calls a method |method_name| in a module |module_name| belonging to the
-// module system from |context|. Intended as a callback target from
-// ScriptContextSet::ForEach.
-void CallModuleMethod(const std::string& module_name,
-                      const std::string& method_name,
-                      const base::ListValue* args,
-                      ScriptContext* context) {
-  v8::HandleScope handle_scope(context->isolate());
-  v8::Context::Scope context_scope(context->v8_context());
-
-  scoped_ptr<content::V8ValueConverter> converter(
-      content::V8ValueConverter::create());
-
-  std::vector<v8::Handle<v8::Value> > arguments;
-  for (base::ListValue::const_iterator it = args->begin(); it != args->end();
-       ++it) {
-    arguments.push_back(converter->ToV8Value(*it, context->v8_context()));
-  }
-
-  context->module_system()->CallModuleMethod(
-      module_name, method_name, &arguments);
-}
-
-}  // namespace
-
-Dispatcher::Dispatcher()
-    : content_watcher_(new ContentWatcher()),
-      is_webkit_initialized_(false),
-      webrequest_adblock_(false),
-      webrequest_adblock_plus_(false),
-      webrequest_other_(false),
-      source_map_(&ResourceBundle::GetSharedInstance()),
-      v8_schema_registry_(new V8SchemaRegistry) {
-  const CommandLine& command_line = *(CommandLine::ForCurrentProcess());
-  is_extension_process_ =
-      command_line.HasSwitch(extensions::switches::kExtensionProcess) ||
-      command_line.HasSwitch(::switches::kSingleProcess);
-
-  if (is_extension_process_) {
-    RenderThread::Get()->SetIdleNotificationDelayInMs(
-        kInitialExtensionIdleHandlerDelayMs);
-  }
-
-  RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension());
-
-  user_script_slave_.reset(new UserScriptSlave(&extensions_));
-  request_sender_.reset(new RequestSender(this));
-  PopulateSourceMap();
-  // Register JS sources from the extensions module embedder.
-  ExtensionsRendererClient::Get()->PopulateSourceMap(&source_map_);
-  PopulateLazyBindingsMap();
-}
-
-Dispatcher::~Dispatcher() {
-}
-
-bool Dispatcher::OnControlMessageReceived(const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(Dispatcher, message)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_SetChannel, OnSetChannel)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect, OnDispatchOnConnect)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnDeliverMessage)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect,
-                        OnDispatchOnDisconnect)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_SetFunctionNames, OnSetFunctionNames)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_SetSystemFont, OnSetSystemFont)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnUnloaded)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingWhitelist,
-                        OnSetScriptingWhitelist)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_ActivateExtension, OnActivateExtension)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdatePermissions, OnUpdatePermissions)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateTabSpecificPermissions,
-                        OnUpdateTabSpecificPermissions)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_ClearTabSpecificPermissions,
-                        OnClearTabSpecificPermissions)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts, OnUpdateUserScripts)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_UsingWebRequestAPI, OnUsingWebRequestAPI)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_ShouldSuspend, OnShouldSuspend)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_Suspend, OnSuspend)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_CancelSuspend, OnCancelSuspend)
-    IPC_MESSAGE_FORWARD(ExtensionMsg_WatchPages,
-                        content_watcher_.get(), ContentWatcher::OnWatchPages)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-
-  return handled;
-}
-
-void Dispatcher::WebKitInitialized() {
-  // For extensions, we want to ensure we call the IdleHandler every so often,
-  // even if the extension keeps up activity.
-  if (is_extension_process_) {
-    forced_idle_timer_.reset(new base::RepeatingTimer<content::RenderThread>);
-    forced_idle_timer_->Start(FROM_HERE,
-        base::TimeDelta::FromMilliseconds(kMaxExtensionIdleHandlerDelayMs),
-        RenderThread::Get(), &RenderThread::IdleHandler);
-  }
-
-  // Initialize host permissions for any extensions that were activated before
-  // WebKit was initialized.
-  for (std::set<std::string>::iterator iter = active_extension_ids_.begin();
-       iter != active_extension_ids_.end(); ++iter) {
-    const Extension* extension = extensions_.GetByID(*iter);
-    CHECK(extension);
-  }
-
-  EnableCustomElementWhiteList();
-
-  is_webkit_initialized_ = true;
-}
-
-void Dispatcher::IdleNotification() {
-  if (is_extension_process_) {
-    // Dampen the forced delay as well if the extension stays idle for long
-    // periods of time.
-    int64 forced_delay_ms = std::max(
-        RenderThread::Get()->GetIdleNotificationDelayInMs(),
-        kMaxExtensionIdleHandlerDelayMs);
-    forced_idle_timer_->Stop();
-    forced_idle_timer_->Start(FROM_HERE,
-        base::TimeDelta::FromMilliseconds(forced_delay_ms),
-        RenderThread::Get(), &RenderThread::IdleHandler);
-  }
-}
-
-void Dispatcher::OnRenderProcessShutdown() {
-  v8_schema_registry_.reset();
-  forced_idle_timer_.reset();
-}
-
-void Dispatcher::OnSetFunctionNames(
-    const std::vector<std::string>& names) {
-  function_names_.clear();
-  for (size_t i = 0; i < names.size(); ++i)
-    function_names_.insert(names[i]);
-}
-
-void Dispatcher::OnSetSystemFont(const std::string& font_family,
-                                 const std::string& font_size) {
-  system_font_family_ = font_family;
-  system_font_size_ = font_size;
-}
-
-void Dispatcher::OnSetChannel(int channel) {
-  SetCurrentChannel(static_cast<chrome::VersionInfo::Channel>(channel));
-}
-
-void Dispatcher::OnMessageInvoke(const std::string& extension_id,
-                                 const std::string& module_name,
-                                 const std::string& function_name,
-                                 const base::ListValue& args,
-                                 bool user_gesture) {
-  InvokeModuleSystemMethod(
-      NULL, extension_id, module_name, function_name, args, user_gesture);
-}
-
-void Dispatcher::OnDispatchOnConnect(
-    int target_port_id,
-    const std::string& channel_name,
-    const base::DictionaryValue& source_tab,
-    const ExtensionMsg_ExternalConnectionInfo& info,
-    const std::string& tls_channel_id) {
-  DCHECK(!ContainsKey(port_to_tab_id_map_, target_port_id));
-  DCHECK_EQ(1, target_port_id % 2);  // target renderer ports have odd IDs.
-  int sender_tab_id = -1;
-  source_tab.GetInteger("id", &sender_tab_id);
-  port_to_tab_id_map_[target_port_id] = sender_tab_id;
-
-  MessagingBindings::DispatchOnConnect(script_context_set_.GetAll(),
-                                       target_port_id,
-                                       channel_name,
-                                       source_tab,
-                                       info.source_id,
-                                       info.target_id,
-                                       info.source_url,
-                                       tls_channel_id,
-                                       NULL);  // All render views.
-}
-
-void Dispatcher::OnDeliverMessage(int target_port_id,
-                                  const Message& message) {
-  scoped_ptr<RequestSender::ScopedTabID> scoped_tab_id;
-  std::map<int, int>::const_iterator it =
-      port_to_tab_id_map_.find(target_port_id);
-  if (it != port_to_tab_id_map_.end()) {
-    scoped_tab_id.reset(new RequestSender::ScopedTabID(request_sender(),
-                                                       it->second));
-  }
-
-  MessagingBindings::DeliverMessage(script_context_set_.GetAll(),
-                                    target_port_id,
-                                    message,
-                                    NULL);  // All render views.
-}
-
-void Dispatcher::OnDispatchOnDisconnect(int port_id,
-                                        const std::string& error_message) {
-  MessagingBindings::DispatchOnDisconnect(script_context_set_.GetAll(),
-                                          port_id,
-                                          error_message,
-                                          NULL);  // All render views.
-}
-
-void Dispatcher::OnLoaded(
-    const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions) {
-  std::vector<ExtensionMsg_Loaded_Params>::const_iterator i;
-  for (i = loaded_extensions.begin(); i != loaded_extensions.end(); ++i) {
-    std::string error;
-    scoped_refptr<const Extension> extension = i->ConvertToExtension(&error);
-    if (!extension.get()) {
-      extension_load_errors_[i->id] = error;
-      continue;
-    }
-    OnLoadedInternal(extension);
-  }
-  // Update the available bindings for all contexts. These may have changed if
-  // an externally_connectable extension was loaded that can connect to an
-  // open webpage.
-  AddOrRemoveBindings("");
-}
-
-void Dispatcher::OnLoadedInternal(scoped_refptr<const Extension> extension) {
-  extensions_.Insert(extension);
-}
-
-void Dispatcher::OnUnloaded(const std::string& id) {
-  extensions_.Remove(id);
-  active_extension_ids_.erase(id);
-
-  // If the extension is later reloaded with a different set of permissions,
-  // we'd like it to get a new isolated world ID, so that it can pick up the
-  // changed origin whitelist.
-  user_script_slave_->RemoveIsolatedWorld(id);
-
-  // Invalidate all of the contexts that were removed.
-  // TODO(kalman): add an invalidation observer interface to ScriptContext.
-  ScriptContextSet::ContextSet removed_contexts =
-      script_context_set_.OnExtensionUnloaded(id);
-  for (ScriptContextSet::ContextSet::iterator it = removed_contexts.begin();
-       it != removed_contexts.end();
-       ++it) {
-    request_sender_->InvalidateSource(*it);
-  }
-
-  // Update the available bindings for the remaining contexts. These may have
-  // changed if an externally_connectable extension is unloaded and a webpage
-  // is no longer accessible.
-  AddOrRemoveBindings("");
-
-  // Invalidates the messages map for the extension in case the extension is
-  // reloaded with a new messages map.
-  EraseL10nMessagesMap(id);
-
-  // We don't do anything with existing platform-app stylesheets. They will
-  // stay resident, but the URL pattern corresponding to the unloaded
-  // extension's URL just won't match anything anymore.
-}
-
-void Dispatcher::OnSetScriptingWhitelist(
-    const ExtensionsClient::ScriptingWhitelist& extension_ids) {
-  ExtensionsClient::Get()->SetScriptingWhitelist(extension_ids);
-}
-
-bool Dispatcher::IsExtensionActive(
-    const std::string& extension_id) const {
-  bool is_active =
-      active_extension_ids_.find(extension_id) != active_extension_ids_.end();
-  if (is_active)
-    CHECK(extensions_.Contains(extension_id));
-  return is_active;
-}
-
-v8::Handle<v8::Object> Dispatcher::GetOrCreateObject(
-    v8::Handle<v8::Object> object,
-    const std::string& field,
-    v8::Isolate* isolate) {
-  v8::Handle<v8::String> key = v8::String::NewFromUtf8(isolate, field.c_str());
-  // If the object has a callback property, it is assumed it is an unavailable
-  // API, so it is safe to delete. This is checked before GetOrCreateObject is
-  // called.
-  if (object->HasRealNamedCallbackProperty(key)) {
-    object->Delete(key);
-  } else if (object->HasRealNamedProperty(key)) {
-    v8::Handle<v8::Value> value = object->Get(key);
-    CHECK(value->IsObject());
-    return v8::Handle<v8::Object>::Cast(value);
-  }
-
-  v8::Handle<v8::Object> new_object = v8::Object::New(isolate);
-  object->Set(key, new_object);
-  return new_object;
-}
-
-void Dispatcher::AddOrRemoveBindingsForContext(ScriptContext* context) {
-  v8::HandleScope handle_scope(context->isolate());
-  v8::Context::Scope context_scope(context->v8_context());
-
-  // TODO(kalman): Make the bindings registration have zero overhead then run
-  // the same code regardless of context type.
-  switch (context->context_type()) {
-    case Feature::UNSPECIFIED_CONTEXT:
-    case Feature::WEB_PAGE_CONTEXT:
-    case Feature::BLESSED_WEB_PAGE_CONTEXT: {
-      // Web page context; it's too expensive to run the full bindings code.
-      // Hard-code that the app and webstore APIs are available...
-      RegisterBinding("app", context);
-      RegisterBinding("webstore", context);
-
-      // ... and that the runtime API might be available if any extension can
-      // connect to it.
-      bool runtime_is_available = false;
-      for (ExtensionSet::const_iterator it = extensions_.begin();
-           it != extensions_.end(); ++it) {
-        ExternallyConnectableInfo* info =
-            static_cast<ExternallyConnectableInfo*>((*it)->GetManifestData(
-                manifest_keys::kExternallyConnectable));
-        if (info && info->matches.MatchesURL(context->GetURL())) {
-          runtime_is_available = true;
-          break;
-        }
-      }
-      if (runtime_is_available)
-        RegisterBinding("runtime", context);
-      break;
-    }
-
-    case Feature::BLESSED_EXTENSION_CONTEXT:
-    case Feature::UNBLESSED_EXTENSION_CONTEXT:
-    case Feature::CONTENT_SCRIPT_CONTEXT: {
-      // Extension context; iterate through all the APIs and bind the available
-      // ones.
-      FeatureProvider* api_feature_provider = FeatureProvider::GetAPIFeatures();
-      const std::vector<std::string>& apis =
-          api_feature_provider->GetAllFeatureNames();
-      for (std::vector<std::string>::const_iterator it = apis.begin();
-          it != apis.end(); ++it) {
-        const std::string& api_name = *it;
-        Feature* feature = api_feature_provider->GetFeature(api_name);
-        DCHECK(feature);
-
-        // Internal APIs are included via require(api_name) from internal code
-        // rather than chrome[api_name].
-        if (feature->IsInternal())
-          continue;
-
-        // If this API has a parent feature (and isn't marked 'noparent'),
-        // then this must be a function or event, so we should not register.
-        if (api_feature_provider->GetParent(feature) != NULL)
-          continue;
-
-        if (context->IsAnyFeatureAvailableToContext(*feature))
-          RegisterBinding(api_name, context);
-      }
-      if (CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType)) {
-        RegisterBinding("test", context);
-      }
-      break;
-    }
-  }
-}
-
-v8::Handle<v8::Object> Dispatcher::GetOrCreateBindObjectIfAvailable(
-    const std::string& api_name,
-    std::string* bind_name,
-    ScriptContext* context) {
-  std::vector<std::string> split;
-  base::SplitString(api_name, '.', &split);
-
-  v8::Handle<v8::Object> bind_object;
-
-  // Check if this API has an ancestor. If the API's ancestor is available and
-  // the API is not available, don't install the bindings for this API. If
-  // the API is available and its ancestor is not, delete the ancestor and
-  // install the bindings for the API. This is to prevent loading the ancestor
-  // API schema if it will not be needed.
-  //
-  // For example:
-  //  If app is available and app.window is not, just install app.
-  //  If app.window is available and app is not, delete app and install
-  //  app.window on a new object so app does not have to be loaded.
-  FeatureProvider* api_feature_provider = FeatureProvider::GetAPIFeatures();
-  std::string ancestor_name;
-  bool only_ancestor_available = false;
-
-  for (size_t i = 0; i < split.size() - 1; ++i) {
-    ancestor_name += (i ? ".": "") + split[i];
-    if (api_feature_provider->GetFeature(ancestor_name) &&
-        context->GetAvailability(ancestor_name).is_available() &&
-        !context->GetAvailability(api_name).is_available()) {
-      only_ancestor_available = true;
-      break;
-    }
-
-    if (bind_object.IsEmpty()) {
-      bind_object = AsObjectOrEmpty(GetOrCreateChrome(context));
-      if (bind_object.IsEmpty())
-        return v8::Handle<v8::Object>();
-    }
-    bind_object = GetOrCreateObject(bind_object, split[i], context->isolate());
-  }
-
-  if (only_ancestor_available)
-    return v8::Handle<v8::Object>();
-
-  if (bind_name)
-    *bind_name = split.back();
-
-  return bind_object.IsEmpty() ?
-      AsObjectOrEmpty(GetOrCreateChrome(context)) : bind_object;
-}
-
-void Dispatcher::RegisterBinding(const std::string& api_name,
-                                 ScriptContext* context) {
-  std::string bind_name;
-  v8::Handle<v8::Object> bind_object =
-      GetOrCreateBindObjectIfAvailable(api_name, &bind_name, context);
-
-  // Empty if the bind object failed to be created, probably because the
-  // extension overrode chrome with a non-object, e.g. window.chrome = true.
-  if (bind_object.IsEmpty())
-    return;
-
-  v8::Local<v8::String> v8_api_name =
-      v8::String::NewFromUtf8(context->isolate(), api_name.c_str());
-  if (bind_object->HasRealNamedProperty(v8_api_name)) {
-    // The bind object may already have the property if the API has been
-    // registered before (or if the extension has put something there already,
-    // but, whatevs).
-    //
-    // In the former case, we need to re-register the bindings for the APIs
-    // which the extension now has permissions for (if any), but not touch any
-    // others so that we don't destroy state such as event listeners.
-    //
-    // TODO(kalman): Only register available APIs to make this all moot.
-    if (bind_object->HasRealNamedCallbackProperty(v8_api_name))
-      return;  // lazy binding still there, nothing to do
-    if (bind_object->Get(v8_api_name)->IsObject())
-      return;  // binding has already been fully installed
-  }
-
-  ModuleSystem* module_system = context->module_system();
-  if (lazy_bindings_map_.find(api_name) != lazy_bindings_map_.end()) {
-    InstallBindings(module_system, context->v8_context(), api_name);
-  } else if (!source_map_.Contains(api_name)) {
-    module_system->RegisterNativeHandler(
-        api_name,
-        scoped_ptr<NativeHandler>(new BindingGeneratingNativeHandler(
-            module_system,
-            api_name,
-            "binding")));
-    module_system->SetNativeLazyField(bind_object,
-                                      bind_name,
-                                      api_name,
-                                      "binding");
-  } else {
-    module_system->SetLazyField(bind_object,
-                                bind_name,
-                                api_name,
-                                "binding");
-  }
-}
-
-// NOTE: please use the naming convention "foo_natives" for these.
-void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system,
-                                        ScriptContext* context) {
-  module_system->RegisterNativeHandler(
-      "event_natives",
-      scoped_ptr<NativeHandler>(new EventBindings(this, context)));
-  module_system->RegisterNativeHandler("messaging_natives",
-      scoped_ptr<NativeHandler>(MessagingBindings::Get(this, context)));
-  module_system->RegisterNativeHandler("apiDefinitions",
-      scoped_ptr<NativeHandler>(new ApiDefinitionsNatives(this, context)));
-  module_system->RegisterNativeHandler(
-      "sendRequest",
-      scoped_ptr<NativeHandler>(
-          new SendRequestNatives(request_sender_.get(), context)));
-  module_system->RegisterNativeHandler(
-      "setIcon",
-      scoped_ptr<NativeHandler>(
-          new SetIconNatives(request_sender_.get(), context)));
-  module_system->RegisterNativeHandler(
-      "activityLogger",
-      scoped_ptr<NativeHandler>(new APIActivityLogger(context)));
-  module_system->RegisterNativeHandler(
-      "renderViewObserverNatives",
-      scoped_ptr<NativeHandler>(new RenderViewObserverNatives(context)));
-
-  // Natives used by multiple APIs.
-  module_system->RegisterNativeHandler("file_system_natives",
-      scoped_ptr<NativeHandler>(new FileSystemNatives(context)));
-
-  // Custom bindings.
-  module_system->RegisterNativeHandler("app",
-      scoped_ptr<NativeHandler>(new AppBindings(this, context)));
-  module_system->RegisterNativeHandler(
-      "app_runtime",
-      scoped_ptr<NativeHandler>(new AppRuntimeCustomBindings(context)));
-  module_system->RegisterNativeHandler("app_window_natives",
-      scoped_ptr<NativeHandler>(
-          new AppWindowCustomBindings(this, context)));
-  module_system->RegisterNativeHandler("blob_natives",
-      scoped_ptr<NativeHandler>(new BlobNativeHandler(context)));
-  module_system->RegisterNativeHandler(
-      "context_menus",
-      scoped_ptr<NativeHandler>(new ContextMenusCustomBindings(context)));
-  module_system->RegisterNativeHandler(
-      "css_natives", scoped_ptr<NativeHandler>(new CssNativeHandler(context)));
-  module_system->RegisterNativeHandler(
-      "document_natives",
-      scoped_ptr<NativeHandler>(new DocumentCustomBindings(context)));
-  module_system->RegisterNativeHandler(
-      "sync_file_system",
-      scoped_ptr<NativeHandler>(new SyncFileSystemCustomBindings(context)));
-  module_system->RegisterNativeHandler(
-      "file_browser_handler",
-      scoped_ptr<NativeHandler>(new FileBrowserHandlerCustomBindings(context)));
-  module_system->RegisterNativeHandler(
-      "file_browser_private",
-      scoped_ptr<NativeHandler>(new FileBrowserPrivateCustomBindings(context)));
-  module_system->RegisterNativeHandler(
-      "i18n", scoped_ptr<NativeHandler>(new I18NCustomBindings(context)));
-  module_system->RegisterNativeHandler(
-      "id_generator",
-      scoped_ptr<NativeHandler>(new IdGeneratorCustomBindings(context)));
-  module_system->RegisterNativeHandler(
-      "mediaGalleries",
-      scoped_ptr<NativeHandler>(new MediaGalleriesCustomBindings(context)));
-  module_system->RegisterNativeHandler(
-      "page_actions",
-      scoped_ptr<NativeHandler>(new PageActionsCustomBindings(this, context)));
-  module_system->RegisterNativeHandler(
-      "page_capture",
-      scoped_ptr<NativeHandler>(new PageCaptureCustomBindings(context)));
-  module_system->RegisterNativeHandler(
-      "pepper_request_natives",
-      scoped_ptr<NativeHandler>(new PepperRequestNatives(context)));
-  module_system->RegisterNativeHandler(
-      "runtime", scoped_ptr<NativeHandler>(new RuntimeCustomBindings(context)));
-  module_system->RegisterNativeHandler(
-      "tabs", scoped_ptr<NativeHandler>(new TabsCustomBindings(context)));
-  module_system->RegisterNativeHandler(
-      "webstore", scoped_ptr<NativeHandler>(new WebstoreBindings(context)));
-#if defined(ENABLE_WEBRTC)
-  module_system->RegisterNativeHandler("cast_streaming_natives",
-      scoped_ptr<NativeHandler>(new CastStreamingNativeHandler(context)));
-#endif
-}
-
-void Dispatcher::PopulateSourceMap() {
-  // Libraries.
-  source_map_.RegisterSource("entryIdManager", IDR_ENTRY_ID_MANAGER);
-  source_map_.RegisterSource(kEventBindings, IDR_EVENT_BINDINGS_JS);
-  source_map_.RegisterSource("imageUtil", IDR_IMAGE_UTIL_JS);
-  source_map_.RegisterSource("json_schema", IDR_JSON_SCHEMA_JS);
-  source_map_.RegisterSource("lastError", IDR_LAST_ERROR_JS);
-  source_map_.RegisterSource("messaging", IDR_MESSAGING_JS);
-  source_map_.RegisterSource("messaging_utils", IDR_MESSAGING_UTILS_JS);
-  source_map_.RegisterSource("pepper_request", IDR_PEPPER_REQUEST_JS);
-  source_map_.RegisterSource(kSchemaUtils, IDR_SCHEMA_UTILS_JS);
-  source_map_.RegisterSource("sendRequest", IDR_SEND_REQUEST_JS);
-  source_map_.RegisterSource("setIcon", IDR_SET_ICON_JS);
-  source_map_.RegisterSource("test", IDR_TEST_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("unload_event", IDR_UNLOAD_EVENT_JS);
-  source_map_.RegisterSource("utils", IDR_UTILS_JS);
-
-  // Custom bindings.
-  source_map_.RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("app.runtime", IDR_APP_RUNTIME_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("app.window", IDR_APP_WINDOW_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("automation", IDR_AUTOMATION_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("automationEvent", IDR_AUTOMATION_EVENT_JS);
-  source_map_.RegisterSource("automationNode", IDR_AUTOMATION_NODE_JS);
-  source_map_.RegisterSource("automationTree", IDR_AUTOMATION_TREE_JS);
-  source_map_.RegisterSource("browserAction",
-                             IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("contextMenus",
-                             IDR_CONTEXT_MENUS_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("declarativeContent",
-                             IDR_DECLARATIVE_CONTENT_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("declarativeWebRequest",
-                             IDR_DECLARATIVE_WEBREQUEST_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("desktopCapture",
-                             IDR_DESKTOP_CAPTURE_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("developerPrivate",
-                             IDR_DEVELOPER_PRIVATE_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("downloads",
-                             IDR_DOWNLOADS_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("extension", IDR_EXTENSION_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("feedbackPrivate",
-                             IDR_FEEDBACK_PRIVATE_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("fileBrowserHandler",
-                             IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("fileBrowserPrivate",
-                             IDR_FILE_BROWSER_PRIVATE_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("fileSystem",
-                             IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("fileSystemProvider",
-                             IDR_FILE_SYSTEM_PROVIDER_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("gcm",
-                             IDR_GCM_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("i18n", IDR_I18N_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("identity", IDR_IDENTITY_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("imageWriterPrivate",
-                             IDR_IMAGE_WRITER_PRIVATE_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("mediaGalleries",
-                             IDR_MEDIA_GALLERIES_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("notifications",
-                             IDR_NOTIFICATIONS_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("omnibox", IDR_OMNIBOX_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("pageActions",
-                             IDR_PAGE_ACTIONS_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("pageCapture",
-                             IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("permissions", IDR_PERMISSIONS_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("runtime", IDR_RUNTIME_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("syncFileSystem",
-                             IDR_SYNC_FILE_SYSTEM_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("systemIndicator",
-                             IDR_SYSTEM_INDICATOR_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("tabCapture", IDR_TAB_CAPTURE_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("tabs", IDR_TABS_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("webRequest", IDR_WEB_REQUEST_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("webRequestInternal",
-                             IDR_WEB_REQUEST_INTERNAL_CUSTOM_BINDINGS_JS);
-#if defined(ENABLE_WEBRTC)
-  source_map_.RegisterSource("cast.streaming.rtpStream",
-                             IDR_CAST_STREAMING_RTP_STREAM_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("cast.streaming.session",
-                             IDR_CAST_STREAMING_SESSION_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource(
-      "cast.streaming.udpTransport",
-      IDR_CAST_STREAMING_UDP_TRANSPORT_CUSTOM_BINDINGS_JS);
-#endif
-  source_map_.RegisterSource("webstore", IDR_WEBSTORE_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("windowControls", IDR_WINDOW_CONTROLS_JS);
-  source_map_.RegisterSource("binding", IDR_BINDING_JS);
-
-  // Custom types sources.
-  source_map_.RegisterSource("ChromeSetting", IDR_CHROME_SETTING_JS);
-  source_map_.RegisterSource("StorageArea", IDR_STORAGE_AREA_JS);
-  source_map_.RegisterSource("ContentSetting", IDR_CONTENT_SETTING_JS);
-  source_map_.RegisterSource("ChromeDirectSetting",
-                             IDR_CHROME_DIRECT_SETTING_JS);
-
-  // Platform app sources that are not API-specific..
-  source_map_.RegisterSource("tagWatcher", IDR_TAG_WATCHER_JS);
-  source_map_.RegisterSource("webview", IDR_WEBVIEW_CUSTOM_BINDINGS_JS);
-  // Note: webView not webview so that this doesn't interfere with the
-  // chrome.webview API bindings.
-  source_map_.RegisterSource("webView", IDR_WEB_VIEW_JS);
-  source_map_.RegisterSource("webViewExperimental",
-                             IDR_WEB_VIEW_EXPERIMENTAL_JS);
-  source_map_.RegisterSource("webViewRequest",
-                             IDR_WEB_VIEW_REQUEST_CUSTOM_BINDINGS_JS);
-  source_map_.RegisterSource("denyWebView", IDR_WEB_VIEW_DENY_JS);
-  source_map_.RegisterSource("adView", IDR_AD_VIEW_JS);
-  source_map_.RegisterSource("denyAdView", IDR_AD_VIEW_DENY_JS);
-  source_map_.RegisterSource("platformApp", IDR_PLATFORM_APP_JS);
-  source_map_.RegisterSource("injectAppTitlebar", IDR_INJECT_APP_TITLEBAR_JS);
-}
-
-void Dispatcher::PopulateLazyBindingsMap() {
-  lazy_bindings_map_["app"] = InstallAppBindings;
-  lazy_bindings_map_["webstore"] = InstallWebstoreBindings;
-}
-
-void Dispatcher::InstallBindings(ModuleSystem* module_system,
-                                 v8::Handle<v8::Context> v8_context,
-                                 const std::string& api) {
-  std::map<std::string, BindingInstaller>::const_iterator lazy_binding =
-      lazy_bindings_map_.find(api);
-  if (lazy_binding != lazy_bindings_map_.end()) {
-    v8::Handle<v8::Object> global(v8_context->Global());
-    v8::Handle<v8::Object> chrome =
-        global->Get(v8::String::NewFromUtf8(v8_context->GetIsolate(), "chrome"))
-            ->ToObject();
-    (*lazy_binding->second)(module_system, chrome);
-  } else {
-    module_system->Require(api);
-  }
-}
-
-void Dispatcher::DidCreateScriptContext(
-    WebFrame* frame, v8::Handle<v8::Context> v8_context, int extension_group,
-    int world_id) {
-#if !defined(ENABLE_EXTENSIONS)
-  return;
-#endif
-
-  std::string extension_id = GetExtensionID(frame, world_id);
-
-  const Extension* extension = extensions_.GetByID(extension_id);
-  if (!extension && !extension_id.empty()) {
-    // There are conditions where despite a context being associated with an
-    // extension, no extension actually gets found.  Ignore "invalid" because
-    // CSP blocks extension page loading by switching the extension ID to
-    // "invalid". This isn't interesting.
-    if (extension_id != "invalid") {
-      LOG(ERROR) << "Extension \"" << extension_id << "\" not found";
-      RenderThread::Get()->RecordAction(
-          UserMetricsAction("ExtensionNotFound_ED"));
-    }
-
-    extension_id = "";
-  }
-
-  Feature::Context context_type =
-      ClassifyJavaScriptContext(extension,
-                                extension_group,
-                                ScriptContext::GetDataSourceURLForFrame(frame),
-                                frame->document().securityOrigin());
-
-  ScriptContext* context =
-      new ChromeV8Context(v8_context, frame, extension, context_type);
-  script_context_set_.Add(context);
-
-  if (extension)
-    InitOriginPermissions(extension, context_type);
-
-  {
-    scoped_ptr<ModuleSystem> module_system(new ModuleSystem(context,
-                                                            &source_map_));
-    context->set_module_system(module_system.Pass());
-  }
-  ModuleSystem* module_system = context->module_system();
-
-  // Enable natives in startup.
-  ModuleSystem::NativesEnabledScope natives_enabled_scope(
-      module_system);
-
-  // Register the core extensions native handlers.
-  RegisterNativeHandlers(module_system, context);
-
-  // Register native handlers from the extensions embedder.
-  ExtensionsRendererClient::Get()->RegisterNativeHandlers(module_system,
-                                                          context);
-
-  module_system->RegisterNativeHandler("chrome",
-      scoped_ptr<NativeHandler>(new ChromeNativeHandler(context)));
-  module_system->RegisterNativeHandler("print",
-      scoped_ptr<NativeHandler>(new PrintNativeHandler(context)));
-  module_system->RegisterNativeHandler(
-      "lazy_background_page",
-      scoped_ptr<NativeHandler>(new LazyBackgroundPageNativeHandler(context)));
-  module_system->RegisterNativeHandler("logging",
-      scoped_ptr<NativeHandler>(new LoggingNativeHandler(context)));
-  module_system->RegisterNativeHandler("schema_registry",
-      v8_schema_registry_->AsNativeHandler());
-  module_system->RegisterNativeHandler("v8_context",
-      scoped_ptr<NativeHandler>(new V8ContextNativeHandler(context, this)));
-  module_system->RegisterNativeHandler("test_features",
-      scoped_ptr<NativeHandler>(new TestFeaturesNativeHandler(context)));
-  module_system->RegisterNativeHandler("user_gestures",
-      scoped_ptr<NativeHandler>(new UserGesturesNativeHandler(context)));
-  module_system->RegisterNativeHandler("utils",
-      scoped_ptr<NativeHandler>(new UtilsNativeHandler(context)));
-
-  int manifest_version = extension ? extension->manifest_version() : 1;
-  bool send_request_disabled =
-      (extension && Manifest::IsUnpackedLocation(extension->location()) &&
-       BackgroundInfo::HasLazyBackgroundPage(extension));
-  module_system->RegisterNativeHandler(
-      "process",
-      scoped_ptr<NativeHandler>(new ProcessInfoNativeHandler(
-          context,
-          context->GetExtensionID(),
-          context->GetContextTypeDescription(),
-          ChromeRenderProcessObserver::is_incognito_process(),
-          manifest_version,
-          send_request_disabled)));
-
-  // chrome.Event is part of the public API (although undocumented). Make it
-  // lazily evalulate to Event from event_bindings.js. For extensions only
-  // though, not all webpages!
-  if (context->extension()) {
-    v8::Handle<v8::Object> chrome = AsObjectOrEmpty(GetOrCreateChrome(context));
-    if (!chrome.IsEmpty())
-      module_system->SetLazyField(chrome, "Event", kEventBindings, "Event");
-  }
-
-  AddOrRemoveBindingsForContext(context);
-
-  bool is_within_platform_app = IsWithinPlatformApp();
-  // Inject custom JS into the platform app context.
-  if (is_within_platform_app) {
-    module_system->Require("platformApp");
-  }
-
-  if (context_type == Feature::BLESSED_EXTENSION_CONTEXT &&
-      is_within_platform_app &&
-      GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV &&
-      CommandLine::ForCurrentProcess()->HasSwitch(
-          ::switches::kEnableAppWindowControls)) {
-    module_system->Require("windowControls");
-  }
-
-  // We used to limit WebView to |BLESSED_EXTENSION_CONTEXT| within platform
-  // apps. An ext/app runs in a blessed extension context, if it is the active
-  // extension in the current process, in other words, if it is loaded in a top
-  // frame. To support webview in a non-frame extension, we have to allow
-  // unblessed extension context as well.
-  // Note: setting up the WebView class here, not the chrome.webview API.
-  // The API will be automatically set up when first used.
-  if (context_type == Feature::BLESSED_EXTENSION_CONTEXT ||
-      context_type == Feature::UNBLESSED_EXTENSION_CONTEXT) {
-    if (extension->HasAPIPermission(APIPermission::kWebView)) {
-      module_system->Require("webView");
-      if (GetCurrentChannel() <= chrome::VersionInfo::CHANNEL_DEV) {
-        module_system->Require("webViewExperimental");
-      } else {
-        // TODO(asargent) We need a whitelist for webview experimental.
-        // crbug.com/264852
-        std::string id_hash = base::SHA1HashString(extension->id());
-        std::string hexencoded_id_hash = base::HexEncode(id_hash.c_str(),
-                                                        id_hash.length());
-        if (hexencoded_id_hash == "8C3741E3AF0B93B6E8E0DDD499BB0B74839EA578" ||
-            hexencoded_id_hash == "E703483CEF33DEC18B4B6DD84B5C776FB9182BDB" ||
-            hexencoded_id_hash == "1A26E32DE447A17CBE5E9750CDBA78F58539B39C" ||
-            hexencoded_id_hash == "59048028102D7B4C681DBC7BC6CD980C3DC66DA3") {
-          module_system->Require("webViewExperimental");
-        }
-      }
-    } else {
-      module_system->Require("denyWebView");
-    }
-  }
-
-  // Same comment as above for <adview> tag.
-  if (context_type == Feature::BLESSED_EXTENSION_CONTEXT &&
-      is_within_platform_app) {
-    if (CommandLine::ForCurrentProcess()->HasSwitch(
-            ::switches::kEnableAdview)) {
-      if (extension->HasAPIPermission(APIPermission::kAdView)) {
-        module_system->Require("adView");
-      } else {
-        module_system->Require("denyAdView");
-      }
-    }
-  }
-
-  VLOG(1) << "Num tracked contexts: " << script_context_set_.size();
-}
-
-std::string Dispatcher::GetExtensionID(const WebFrame* frame, int world_id) {
-  if (world_id != 0) {
-    // Isolated worlds (content script).
-    return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id);
-  }
-
-  // TODO(kalman): Delete this check.
-  if (frame->document().securityOrigin().isUnique())
-    return std::string();
-
-  // Extension pages (chrome-extension:// URLs).
-  GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame);
-  return extensions_.GetExtensionOrAppIDByURL(frame_url);
-}
-
-bool Dispatcher::IsWithinPlatformApp() {
-  for (std::set<std::string>::iterator iter = active_extension_ids_.begin();
-       iter != active_extension_ids_.end(); ++iter) {
-    const Extension* extension = extensions_.GetByID(*iter);
-    if (extension && extension->is_platform_app())
-      return true;
-  }
-  return false;
-}
-
-void Dispatcher::WillReleaseScriptContext(
-    WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) {
-  ScriptContext* context = script_context_set_.GetByV8Context(v8_context);
-  if (!context)
-    return;
-
-  context->DispatchOnUnloadEvent();
-  // TODO(kalman): add an invalidation observer interface to ScriptContext.
-  request_sender_->InvalidateSource(context);
-
-  script_context_set_.Remove(context);
-  VLOG(1) << "Num tracked contexts: " << script_context_set_.size();
-}
-
-void Dispatcher::DidCreateDocumentElement(blink::WebFrame* frame) {
-  if (IsWithinPlatformApp()) {
-    // WebKit doesn't let us define an additional user agent stylesheet, so we
-    // insert the default platform app stylesheet into all documents that are
-    // loaded in each app.
-    std::string stylesheet =
-        ResourceBundle::GetSharedInstance().
-            GetRawDataResource(IDR_PLATFORM_APP_CSS).as_string();
-    ReplaceFirstSubstringAfterOffset(&stylesheet, 0,
-                                     "$FONTFAMILY", system_font_family_);
-    ReplaceFirstSubstringAfterOffset(&stylesheet, 0,
-                                     "$FONTSIZE", system_font_size_);
-    frame->document().insertStyleSheet(WebString::fromUTF8(stylesheet));
-  }
-
-  content_watcher_->DidCreateDocumentElement(frame);
-}
-
-void Dispatcher::DidMatchCSS(
-    blink::WebFrame* frame,
-    const blink::WebVector<blink::WebString>& newly_matching_selectors,
-    const blink::WebVector<blink::WebString>& stopped_matching_selectors) {
-  content_watcher_->DidMatchCSS(
-      frame, newly_matching_selectors, stopped_matching_selectors);
-}
-
-
-void Dispatcher::OnActivateExtension(const std::string& extension_id) {
-  const Extension* extension = extensions_.GetByID(extension_id);
-  if (!extension) {
-    // Extension was activated but was never loaded. This probably means that
-    // the renderer failed to load it (or the browser failed to tell us when it
-    // did). Failures shouldn't happen, but instead of crashing there (which
-    // executes on all renderers) be conservative and only crash in the renderer
-    // of the extension which failed to load; this one.
-    std::string& error = extension_load_errors_[extension_id];
-    char minidump[256];
-    base::debug::Alias(&minidump);
-    base::snprintf(minidump, arraysize(minidump),
-        "e::dispatcher:%s:%s", extension_id.c_str(), error.c_str());
-    CHECK(extension) << extension_id << " was never loaded: " << error;
-  }
-
-  active_extension_ids_.insert(extension_id);
-
-  // This is called when starting a new extension page, so start the idle
-  // handler ticking.
-  RenderThread::Get()->ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayMs);
-
-  UpdateActiveExtensions();
-
-  if (is_webkit_initialized_) {
-    DOMActivityLogger::AttachToWorld(DOMActivityLogger::kMainWorldId,
-                                     extension_id);
-  }
-}
-
-void Dispatcher::InitOriginPermissions(const Extension* extension,
-                                       Feature::Context context_type) {
-  // TODO(jstritar): We should try to remove this special case. Also, these
-  // whitelist entries need to be updated when the kManagement permission
-  // changes.
-  if (context_type == Feature::BLESSED_EXTENSION_CONTEXT &&
-      extension->HasAPIPermission(APIPermission::kManagement)) {
-    WebSecurityPolicy::addOriginAccessWhitelistEntry(
-        extension->url(),
-        WebString::fromUTF8(content::kChromeUIScheme),
-        WebString::fromUTF8(chrome::kChromeUIExtensionIconHost),
-        false);
-  }
-
-  AddOrRemoveOriginPermissions(
-      UpdatedExtensionPermissionsInfo::ADDED,
-      extension,
-      PermissionsData::GetEffectiveHostPermissions(extension));
-}
-
-void Dispatcher::AddOrRemoveOriginPermissions(
-    UpdatedExtensionPermissionsInfo::Reason reason,
-    const Extension* extension,
-    const URLPatternSet& origins) {
-  for (URLPatternSet::const_iterator i = origins.begin();
-       i != origins.end(); ++i) {
-    const char* schemes[] = {
-      content::kHttpScheme,
-      content::kHttpsScheme,
-      content::kFileScheme,
-      content::kChromeUIScheme,
-      content::kFtpScheme,
-    };
-    for (size_t j = 0; j < arraysize(schemes); ++j) {
-      if (i->MatchesScheme(schemes[j])) {
-        ((reason == UpdatedExtensionPermissionsInfo::REMOVED) ?
-         WebSecurityPolicy::removeOriginAccessWhitelistEntry :
-         WebSecurityPolicy::addOriginAccessWhitelistEntry)(
-              extension->url(),
-              WebString::fromUTF8(schemes[j]),
-              WebString::fromUTF8(i->host()),
-              i->match_subdomains());
-      }
-    }
-  }
-}
-
-void Dispatcher::EnableCustomElementWhiteList() {
-  blink::WebCustomElement::addEmbedderCustomElementName("webview");
-  // TODO(fsamuel): Add <adview> to the whitelist once it has been converted
-  // into a custom element.
-  blink::WebCustomElement::addEmbedderCustomElementName("browser-plugin");
-}
-
-void Dispatcher::AddOrRemoveBindings(const std::string& extension_id) {
-  script_context_set().ForEach(
-      extension_id,
-      NULL,  // all render views
-      base::Bind(&Dispatcher::AddOrRemoveBindingsForContext,
-                 base::Unretained(this)));
-}
-
-void Dispatcher::OnUpdatePermissions(
-  const ExtensionMsg_UpdatePermissions_Params& params) {
-  int reason_id = params.reason_id;
-  const std::string& extension_id = params.extension_id;
-  const APIPermissionSet& apis = params.apis;
-  const ManifestPermissionSet& manifest_permissions =
-      params.manifest_permissions;
-  const URLPatternSet& explicit_hosts = params.explicit_hosts;
-  const URLPatternSet& scriptable_hosts = params.scriptable_hosts;
-
-  const Extension* extension = extensions_.GetByID(extension_id);
-  if (!extension)
-    return;
-
-  scoped_refptr<const PermissionSet> delta =
-      new PermissionSet(apis, manifest_permissions,
-                        explicit_hosts, scriptable_hosts);
-  scoped_refptr<const PermissionSet> old_active =
-      extension->GetActivePermissions();
-  UpdatedExtensionPermissionsInfo::Reason reason =
-      static_cast<UpdatedExtensionPermissionsInfo::Reason>(reason_id);
-
-  const PermissionSet* new_active = NULL;
-  switch (reason) {
-    case UpdatedExtensionPermissionsInfo::ADDED:
-      new_active = PermissionSet::CreateUnion(old_active.get(), delta.get());
-      break;
-    case UpdatedExtensionPermissionsInfo::REMOVED:
-      new_active =
-          PermissionSet::CreateDifference(old_active.get(), delta.get());
-      break;
-  }
-
-  PermissionsData::SetActivePermissions(extension, new_active);
-  AddOrRemoveOriginPermissions(reason, extension, explicit_hosts);
-  AddOrRemoveBindings(extension->id());
-}
-
-void Dispatcher::OnUpdateTabSpecificPermissions(
-    int page_id,
-    int tab_id,
-    const std::string& extension_id,
-    const URLPatternSet& origin_set) {
-  RenderView* view = TabFinder::Find(tab_id);
-
-  // For now, the message should only be sent to the render view that contains
-  // the target tab. This may change. Either way, if this is the target tab it
-  // gives us the chance to check against the page ID to avoid races.
-  DCHECK(view);
-  if (view && view->GetPageId() != page_id)
-    return;
-
-  const Extension* extension = extensions_.GetByID(extension_id);
-  if (!extension)
-    return;
-
-  PermissionsData::UpdateTabSpecificPermissions(
-      extension,
-      tab_id,
-      new PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
-                        origin_set, URLPatternSet()));
-}
-
-void Dispatcher::OnClearTabSpecificPermissions(
-    int tab_id,
-    const std::vector<std::string>& extension_ids) {
-  for (std::vector<std::string>::const_iterator it = extension_ids.begin();
-       it != extension_ids.end(); ++it) {
-    const Extension* extension = extensions_.GetByID(*it);
-    if (extension)
-      PermissionsData::ClearTabSpecificPermissions(extension, tab_id);
-  }
-}
-
-void Dispatcher::OnUpdateUserScripts(
-    base::SharedMemoryHandle scripts) {
-  DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle";
-  user_script_slave_->UpdateScripts(scripts);
-  UpdateActiveExtensions();
-}
-
-void Dispatcher::UpdateActiveExtensions() {
-  // In single-process mode, the browser process reports the active extensions.
-  if (CommandLine::ForCurrentProcess()->HasSwitch(::switches::kSingleProcess))
-    return;
-
-  std::set<std::string> active_extensions = active_extension_ids_;
-  user_script_slave_->GetActiveExtensions(&active_extensions);
-  crash_keys::SetActiveExtensions(active_extensions);
-}
-
-void Dispatcher::OnUsingWebRequestAPI(
-    bool adblock, bool adblock_plus, bool other) {
-  webrequest_adblock_ = adblock;
-  webrequest_adblock_plus_ = adblock_plus;
-  webrequest_other_ = other;
-}
-
-void Dispatcher::OnShouldSuspend(const std::string& extension_id,
-                                 int sequence_id) {
-  RenderThread::Get()->Send(
-      new ExtensionHostMsg_ShouldSuspendAck(extension_id, sequence_id));
-}
-
-void Dispatcher::OnSuspend(const std::string& extension_id) {
-  // Dispatch the suspend event. This doesn't go through the standard event
-  // dispatch machinery because it requires special handling. We need to let
-  // the browser know when we are starting and stopping the event dispatch, so
-  // that it still considers the extension idle despite any activity the suspend
-  // event creates.
-  DispatchEvent(extension_id, kOnSuspendEvent);
-  RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id));
-}
-
-void Dispatcher::OnCancelSuspend(const std::string& extension_id) {
-  DispatchEvent(extension_id, kOnSuspendCanceledEvent);
-}
-
-// TODO(kalman): This is checking for the wrong thing, it should be checking if
-// the frame's security origin is unique. The extension sandbox directive is
-// checked for in extensions/common/manifest_handlers/csp_info.cc.
-bool Dispatcher::IsSandboxedPage(const GURL& url) const {
-  if (url.SchemeIs(kExtensionScheme)) {
-    const Extension* extension = extensions_.GetByID(url.host());
-    if (extension) {
-      return SandboxedPageInfo::IsSandboxedPage(extension, url.path());
-    }
-  }
-  return false;
-}
-
-Feature::Context Dispatcher::ClassifyJavaScriptContext(
-    const Extension* extension,
-    int extension_group,
-    const GURL& url,
-    const blink::WebSecurityOrigin& origin) {
-  DCHECK_GE(extension_group, 0);
-  if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) {
-    return extension ?  // TODO(kalman): when does this happen?
-        Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
-  }
-
-  // We have an explicit check for sandboxed pages before checking whether the
-  // extension is active in this process because:
-  // 1. Sandboxed pages run in the same process as regular extension pages, so
-  //    the extension is considered active.
-  // 2. ScriptContext creation (which triggers bindings injection) happens
-  //    before the SecurityContext is updated with the sandbox flags (after
-  //    reading the CSP header), so the caller can't check if the context's
-  //    security origin is unique yet.
-  if (IsSandboxedPage(url))
-    return Feature::WEB_PAGE_CONTEXT;
-
-  if (extension && IsExtensionActive(extension->id())) {
-    // |extension| is active in this process, but it could be either a true
-    // extension process or within the extent of a hosted app. In the latter
-    // case this would usually be considered a (blessed) web page context,
-    // unless the extension in question is a component extension, in which case
-    // we cheat and call it blessed.
-    return (extension->is_hosted_app() &&
-            extension->location() != Manifest::COMPONENT) ?
-        Feature::BLESSED_WEB_PAGE_CONTEXT : Feature::BLESSED_EXTENSION_CONTEXT;
-  }
-
-  // TODO(kalman): This isUnique() check is wrong, it should be performed as
-  // part of IsSandboxedPage().
-  if (!origin.isUnique() && extensions_.ExtensionBindingsAllowed(url)) {
-    if (!extension)  // TODO(kalman): when does this happen?
-      return Feature::UNSPECIFIED_CONTEXT;
-    return extension->is_hosted_app() ?
-        Feature::BLESSED_WEB_PAGE_CONTEXT :
-        Feature::UNBLESSED_EXTENSION_CONTEXT;
-  }
-
-  if (url.is_valid())
-    return Feature::WEB_PAGE_CONTEXT;
-
-  return Feature::UNSPECIFIED_CONTEXT;
-}
-
-void Dispatcher::OnExtensionResponse(int request_id,
-                                     bool success,
-                                     const base::ListValue& response,
-                                     const std::string& error) {
-  request_sender_->HandleResponse(request_id, success, response, error);
-}
-
-bool Dispatcher::CheckContextAccessToExtensionAPI(
-    const std::string& function_name,
-    ScriptContext* context) const {
-  if (!context) {
-    DLOG(ERROR) << "Not in a v8::Context";
-    return false;
-  }
-
-  if (!context->extension()) {
-    context->isolate()->ThrowException(v8::Exception::Error(
-        v8::String::NewFromUtf8(context->isolate(), "Not in an extension.")));
-    return false;
-  }
-
-  // Theoretically we could end up with bindings being injected into sandboxed
-  // frames, for example content scripts. Don't let them execute API functions.
-  blink::WebFrame* frame = context->web_frame();
-  if (IsSandboxedPage(ScriptContext::GetDataSourceURLForFrame(frame))) {
-    static const char kMessage[] =
-        "%s cannot be used within a sandboxed frame.";
-    std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
-    context->isolate()->ThrowException(v8::Exception::Error(
-        v8::String::NewFromUtf8(context->isolate(), error_msg.c_str())));
-    return false;
-  }
-
-  Feature::Availability availability = context->GetAvailability(function_name);
-  if (!availability.is_available()) {
-    context->isolate()->ThrowException(
-        v8::Exception::Error(v8::String::NewFromUtf8(
-            context->isolate(), availability.message().c_str())));
-  }
-
-  return availability.is_available();
-}
-
-void Dispatcher::DispatchEvent(const std::string& extension_id,
-                               const std::string& event_name) const {
-  base::ListValue args;
-  args.Set(0, new base::StringValue(event_name));
-  args.Set(1, new base::ListValue());
-
-  // Needed for Windows compilation, since kEventBindings is declared extern.
-  const char* local_event_bindings = kEventBindings;
-  script_context_set_.ForEach(extension_id,
-                              NULL,  // all render views
-                              base::Bind(&CallModuleMethod,
-                                         local_event_bindings,
-                                         kEventDispatchFunction,
-                                         &args));
-}
-
-void Dispatcher::InvokeModuleSystemMethod(
-      content::RenderView* render_view,
-      const std::string& extension_id,
-      const std::string& module_name,
-      const std::string& function_name,
-      const base::ListValue& args,
-      bool user_gesture) {
-  scoped_ptr<WebScopedUserGesture> web_user_gesture;
-  if (user_gesture)
-    web_user_gesture.reset(new WebScopedUserGesture);
-
-  script_context_set_.ForEach(
-      extension_id,
-      render_view,
-      base::Bind(&CallModuleMethod, module_name, function_name, &args));
-
-  // Reset the idle handler each time there's any activity like event or message
-  // dispatch, for which Invoke is the chokepoint.
-  if (is_extension_process_) {
-    RenderThread::Get()->ScheduleIdleHandler(
-        kInitialExtensionIdleHandlerDelayMs);
-  }
-
-  // Tell the browser process when an event has been dispatched with a lazy
-  // background page active.
-  const Extension* extension = extensions_.GetByID(extension_id);
-  if (extension && BackgroundInfo::HasLazyBackgroundPage(extension) &&
-      module_name == kEventBindings &&
-      function_name == kEventDispatchFunction) {
-    RenderView* background_view =
-        ExtensionHelper::GetBackgroundPage(extension_id);
-    if (background_view) {
-      background_view->Send(new ExtensionHostMsg_EventAck(
-          background_view->GetRoutingID()));
-    }
-  }
-}
-
-void Dispatcher::ClearPortData(int port_id) {
-  // Only the target port side has entries in |port_to_tab_id_map_|. If
-  // |port_id| is a source port, std::map::erase() will just silently fail
-  // here as a no-op.
-  port_to_tab_id_map_.erase(port_id);
-}
-
-}  // namespace extensions
diff --git a/chrome/renderer/extensions/dispatcher.h b/chrome/renderer/extensions/dispatcher.h
deleted file mode 100644
index a04b0f1..0000000
--- a/chrome/renderer/extensions/dispatcher.h
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_RENDERER_EXTENSIONS_DISPATCHER_H_
-#define CHROME_RENDERER_EXTENSIONS_DISPATCHER_H_
-
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/memory/shared_memory.h"
-#include "base/timer/timer.h"
-#include "chrome/renderer/resource_bundle_source_map.h"
-#include "content/public/renderer/render_process_observer.h"
-#include "extensions/common/event_filter.h"
-#include "extensions/common/extension_set.h"
-#include "extensions/common/extensions_client.h"
-#include "extensions/common/features/feature.h"
-#include "extensions/renderer/script_context.h"
-#include "extensions/renderer/script_context_set.h"
-#include "extensions/renderer/v8_schema_registry.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/platform/WebVector.h"
-#include "v8/include/v8.h"
-
-class ChromeRenderViewTest;
-class GURL;
-class ModuleSystem;
-class URLPattern;
-struct ExtensionMsg_ExternalConnectionInfo;
-struct ExtensionMsg_Loaded_Params;
-struct ExtensionMsg_UpdatePermissions_Params;
-
-namespace blink {
-class WebFrame;
-class WebSecurityOrigin;
-}
-
-namespace base {
-class DictionaryValue;
-class ListValue;
-}
-
-namespace content {
-class RenderThread;
-}
-
-namespace extensions {
-class ContentWatcher;
-class Extension;
-class FilteredEventRouter;
-class ManifestPermissionSet;
-class RequestSender;
-class ScriptContext;
-class UserScriptSlave;
-struct Message;
-
-// Dispatches extension control messages sent to the renderer and stores
-// renderer extension related state.
-class Dispatcher : public content::RenderProcessObserver {
- public:
-  Dispatcher();
-  virtual ~Dispatcher();
-
-  const std::set<std::string>& function_names() const {
-    return function_names_;
-  }
-
-  bool is_extension_process() const { return is_extension_process_; }
-  const ExtensionSet* extensions() const { return &extensions_; }
-  const ScriptContextSet& script_context_set() const {
-    return script_context_set_;
-  }
-  UserScriptSlave* user_script_slave() {
-    return user_script_slave_.get();
-  }
-  V8SchemaRegistry* v8_schema_registry() {
-    return v8_schema_registry_.get();
-  }
-  ContentWatcher* content_watcher() {
-    return content_watcher_.get();
-  }
-  RequestSender* request_sender() {
-    return request_sender_.get();
-  }
-
-  bool IsExtensionActive(const std::string& extension_id) const;
-
-  // Finds the extension ID for the JavaScript context associated with the
-  // specified |frame| and isolated world. If |world_id| is zero, finds the
-  // extension ID associated with the main world's JavaScript context. If the
-  // JavaScript context isn't from an extension, returns empty string.
-  std::string GetExtensionID(const blink::WebFrame* frame, int world_id);
-
-  void DidCreateScriptContext(blink::WebFrame* frame,
-                              v8::Handle<v8::Context> context,
-                              int extension_group,
-                              int world_id);
-  void WillReleaseScriptContext(blink::WebFrame* frame,
-                                v8::Handle<v8::Context> context,
-                                int world_id);
-
-  void DidCreateDocumentElement(blink::WebFrame* frame);
-
-  void DidMatchCSS(
-      blink::WebFrame* frame,
-      const blink::WebVector<blink::WebString>& newly_matching_selectors,
-      const blink::WebVector<blink::WebString>& stopped_matching_selectors);
-
-  // TODO(mpcomplete): remove. http://crbug.com/100411
-  bool IsAdblockWithWebRequestInstalled() const {
-    return webrequest_adblock_;
-  }
-  bool IsAdblockPlusWithWebRequestInstalled() const {
-    return webrequest_adblock_plus_;
-  }
-  bool IsOtherExtensionWithWebRequestInstalled() const {
-    return webrequest_other_;
-  }
-
-  void OnExtensionResponse(int request_id,
-                           bool success,
-                           const base::ListValue& response,
-                           const std::string& error);
-
-  // Checks that the current context contains an extension that has permission
-  // to execute the specified function. If it does not, a v8 exception is thrown
-  // and the method returns false. Otherwise returns true.
-  bool CheckContextAccessToExtensionAPI(const std::string& function_name,
-                                        ScriptContext* context) const;
-
-  // Dispatches the event named |event_name| to all render views.
-  void DispatchEvent(const std::string& extension_id,
-                     const std::string& event_name) const;
-
-  // Shared implementation of the various MessageInvoke IPCs.
-  void InvokeModuleSystemMethod(
-      content::RenderView* render_view,
-      const std::string& extension_id,
-      const std::string& module_name,
-      const std::string& function_name,
-      const base::ListValue& args,
-      bool user_gesture);
-
-  void ClearPortData(int port_id);
-
- private:
-  friend class ::ChromeRenderViewTest;
-  FRIEND_TEST_ALL_PREFIXES(RendererPermissionsPolicyDelegateTest,
-                           CannotScriptWebstore);
-  typedef void (*BindingInstaller)(ModuleSystem* module_system,
-                                  v8::Handle<v8::Object> chrome);
-
-  // RenderProcessObserver implementation:
-  virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE;
-  virtual void WebKitInitialized() OVERRIDE;
-  virtual void IdleNotification() OVERRIDE;
-  virtual void OnRenderProcessShutdown() OVERRIDE;
-
-  void OnSetChannel(int channel);
-  void OnMessageInvoke(const std::string& extension_id,
-                       const std::string& module_name,
-                       const std::string& function_name,
-                       const base::ListValue& args,
-                       bool user_gesture);
-  void OnDispatchOnConnect(int target_port_id,
-                           const std::string& channel_name,
-                           const base::DictionaryValue& source_tab,
-                           const ExtensionMsg_ExternalConnectionInfo& info,
-                           const std::string& tls_channel_id);
-  void OnDeliverMessage(int target_port_id, const Message& message);
-  void OnDispatchOnDisconnect(int port_id, const std::string& error_message);
-  void OnSetFunctionNames(const std::vector<std::string>& names);
-  void OnSetSystemFont(const std::string& font_family,
-                       const std::string& font_size);
-  void OnLoaded(
-      const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions);
-  void OnLoadedInternal(scoped_refptr<const Extension> extension);
-  void OnUnloaded(const std::string& id);
-  void OnSetScriptingWhitelist(
-      const ExtensionsClient::ScriptingWhitelist& extension_ids);
-  void OnPageActionsUpdated(const std::string& extension_id,
-      const std::vector<std::string>& page_actions);
-  void OnActivateExtension(const std::string& extension_id);
-  void OnUpdatePermissions(const ExtensionMsg_UpdatePermissions_Params& params);
-  void OnUpdateTabSpecificPermissions(int page_id,
-                                      int tab_id,
-                                      const std::string& extension_id,
-                                      const URLPatternSet& origin_set);
-  void OnClearTabSpecificPermissions(
-      int tab_id,
-      const std::vector<std::string>& extension_ids);
-  void OnUpdateUserScripts(base::SharedMemoryHandle table);
-  void OnUsingWebRequestAPI(
-      bool adblock,
-      bool adblock_plus,
-      bool other_webrequest);
-  void OnShouldSuspend(const std::string& extension_id, int sequence_id);
-  void OnSuspend(const std::string& extension_id);
-  void OnCancelSuspend(const std::string& extension_id);
-
-  // Update the list of active extensions that will be reported when we crash.
-  void UpdateActiveExtensions();
-
-  // Sets up the host permissions for |extension|.
-  void InitOriginPermissions(const Extension* extension,
-                             Feature::Context context_type);
-  void AddOrRemoveOriginPermissions(
-      UpdatedExtensionPermissionsInfo::Reason reason,
-      const Extension* extension,
-      const URLPatternSet& origins);
-
-  // Enable custom element whitelist in Apps.
-  void EnableCustomElementWhiteList();
-
-  // Adds or removes bindings for every context belonging to |extension_id|, or
-  // or all contexts if |extension_id| is empty.
-  void AddOrRemoveBindings(const std::string& extension_id);
-
-  void RegisterNativeHandlers(ModuleSystem* module_system,
-                              ScriptContext* context);
-  void AddOrRemoveBindingsForContext(ScriptContext* context);
-  void RegisterBinding(const std::string& api_name, ScriptContext* context);
-  v8::Handle<v8::Object> GetOrCreateBindObjectIfAvailable(
-      const std::string& api_name,
-      std::string* bind_name,
-      ScriptContext* context);
-
-  // Inserts static source code into |source_map_|.
-  void PopulateSourceMap();
-
-  // Inserts BindingInstallers into |lazy_bindings_map_|.
-  void PopulateLazyBindingsMap();
-
-  // Sets up the bindings for the given api.
-  void InstallBindings(ModuleSystem* module_system,
-                       v8::Handle<v8::Context> v8_context,
-                       const std::string& api);
-
-  // Returns whether the current renderer hosts a platform app.
-  bool IsWithinPlatformApp();
-
-  bool IsSandboxedPage(const GURL& url) const;
-
-  // Returns the Feature::Context type of context for a JavaScript context.
-  Feature::Context ClassifyJavaScriptContext(
-      const Extension* extension,
-      int extension_group,
-      const GURL& url,
-      const blink::WebSecurityOrigin& origin);
-
-  // Gets |field| from |object| or creates it as an empty object if it doesn't
-  // exist.
-  v8::Handle<v8::Object> GetOrCreateObject(v8::Handle<v8::Object> object,
-                                           const std::string& field,
-                                           v8::Isolate* isolate);
-
-  // True if this renderer is running extensions.
-  bool is_extension_process_;
-
-  // Contains all loaded extensions.  This is essentially the renderer
-  // counterpart to ExtensionService in the browser. It contains information
-  // about all extensions currently loaded by the browser.
-  ExtensionSet extensions_;
-
-  // The IDs of extensions that failed to load, mapped to the error message
-  // generated on failure.
-  std::map<std::string, std::string> extension_load_errors_;
-
-  // All the bindings contexts that are currently loaded for this renderer.
-  // There is zero or one for each v8 context.
-  ScriptContextSet script_context_set_;
-
-  scoped_ptr<UserScriptSlave> user_script_slave_;
-
-  scoped_ptr<ContentWatcher> content_watcher_;
-
-  // Same as above, but on a longer timer and will run even if the process is
-  // not idle, to ensure that IdleHandle gets called eventually.
-  scoped_ptr<base::RepeatingTimer<content::RenderThread> > forced_idle_timer_;
-
-  // All declared function names.
-  std::set<std::string> function_names_;
-
-  // The extensions and apps that are active in this process.
-  std::set<std::string> active_extension_ids_;
-
-  // True once WebKit has been initialized (and it is therefore safe to poke).
-  bool is_webkit_initialized_;
-
-  // Status of webrequest usage for known extensions.
-  // TODO(mpcomplete): remove. http://crbug.com/100411
-  bool webrequest_adblock_;
-  bool webrequest_adblock_plus_;
-  bool webrequest_other_;
-
-  ResourceBundleSourceMap source_map_;
-
-  // Cache for the v8 representation of extension API schemas.
-  scoped_ptr<V8SchemaRegistry> v8_schema_registry_;
-
-  // Bindings that are defined lazily and have BindingInstallers to install
-  // them.
-  std::map<std::string, BindingInstaller> lazy_bindings_map_;
-
-  // Sends API requests to the extension host.
-  scoped_ptr<RequestSender> request_sender_;
-
-  // The platforms system font family and size;
-  std::string system_font_family_;
-  std::string system_font_size_;
-
-  // Mapping of port IDs to tabs. If there is no tab, the value would be -1.
-  std::map<int, int> port_to_tab_id_map_;
-
-  DISALLOW_COPY_AND_ASSIGN(Dispatcher);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_RENDERER_EXTENSIONS_DISPATCHER_H_
diff --git a/chrome/renderer/extensions/event_unittest.cc b/chrome/renderer/extensions/event_unittest.cc
index 6614c54..b767363 100644
--- a/chrome/renderer/extensions/event_unittest.cc
+++ b/chrome/renderer/extensions/event_unittest.cc
@@ -17,6 +17,8 @@
     RegisterModule(kEventBindings, IDR_EVENT_BINDINGS_JS);
     RegisterModule("json_schema", IDR_JSON_SCHEMA_JS);
     RegisterModule(kSchemaUtils, IDR_SCHEMA_UTILS_JS);
+    RegisterModule("uncaught_exception_handler",
+                   IDR_UNCAUGHT_EXCEPTION_HANDLER_JS);
     RegisterModule("unload_event", IDR_UNLOAD_EVENT_JS);
     RegisterModule("utils", IDR_UTILS_JS);
 
diff --git a/chrome/renderer/extensions/extension_frame_helper.cc b/chrome/renderer/extensions/extension_frame_helper.cc
index f9b75e1..c88c4cd 100644
--- a/chrome/renderer/extensions/extension_frame_helper.cc
+++ b/chrome/renderer/extensions/extension_frame_helper.cc
@@ -4,10 +4,10 @@
 
 #include "chrome/renderer/extensions/extension_frame_helper.h"
 
-#include "chrome/renderer/extensions/dispatcher.h"
 #include "content/public/renderer/render_frame.h"
 #include "extensions/common/extension_messages.h"
 #include "extensions/renderer/console.h"
+#include "extensions/renderer/dispatcher.h"
 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
 
diff --git a/chrome/renderer/extensions/extension_helper.cc b/chrome/renderer/extensions/extension_helper.cc
deleted file mode 100644
index 92108e7..0000000
--- a/chrome/renderer/extensions/extension_helper.cc
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/renderer/extensions/extension_helper.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/json/json_string_value_serializer.h"
-#include "base/lazy_instance.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/extensions/chrome_extension_messages.h"
-#include "chrome/common/render_messages.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/renderer/extensions/chrome_v8_context.h"
-#include "chrome/renderer/extensions/dispatcher.h"
-#include "chrome/renderer/extensions/messaging_bindings.h"
-#include "chrome/renderer/extensions/user_script_scheduler.h"
-#include "chrome/renderer/extensions/user_script_slave.h"
-#include "chrome/renderer/web_apps.h"
-#include "content/public/renderer/render_view.h"
-#include "content/public/renderer/render_view_visitor.h"
-#include "extensions/common/api/messaging/message.h"
-#include "extensions/common/constants.h"
-#include "extensions/common/extension_messages.h"
-#include "extensions/renderer/console.h"
-#include "third_party/WebKit/public/platform/WebURLRequest.h"
-#include "third_party/WebKit/public/web/WebConsoleMessage.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
-#include "third_party/WebKit/public/web/WebView.h"
-
-using content::ConsoleMessageLevel;
-using blink::WebConsoleMessage;
-using blink::WebDataSource;
-using blink::WebFrame;
-using blink::WebLocalFrame;
-using blink::WebURLRequest;
-using blink::WebScopedUserGesture;
-using blink::WebView;
-
-namespace extensions {
-
-namespace {
-// Keeps a mapping from the frame pointer to a UserScriptScheduler object.
-// We store this mapping per process, because a frame can jump from one
-// document to another with adoptNode, and so having the object be a
-// RenderViewObserver means it might miss some notifications after it moves.
-typedef std::map<WebFrame*, UserScriptScheduler*> SchedulerMap;
-static base::LazyInstance<SchedulerMap> g_schedulers =
-    LAZY_INSTANCE_INITIALIZER;
-
-// A RenderViewVisitor class that iterates through the set of available
-// views, looking for a view of the given type, in the given browser window
-// and within the given extension.
-// Used to accumulate the list of views associated with an extension.
-class ViewAccumulator : public content::RenderViewVisitor {
- public:
-  ViewAccumulator(const std::string& extension_id,
-                  int browser_window_id,
-                  ViewType view_type)
-      : extension_id_(extension_id),
-        browser_window_id_(browser_window_id),
-        view_type_(view_type) {
-  }
-
-  std::vector<content::RenderView*> views() { return views_; }
-
-  // Returns false to terminate the iteration.
-  virtual bool Visit(content::RenderView* render_view) OVERRIDE {
-    ExtensionHelper* helper = ExtensionHelper::Get(render_view);
-    if (!ViewTypeMatches(helper->view_type(), view_type_))
-      return true;
-
-    GURL url = render_view->GetWebView()->mainFrame()->document().url();
-    if (!url.SchemeIs(kExtensionScheme))
-      return true;
-    const std::string& extension_id = url.host();
-    if (extension_id != extension_id_)
-      return true;
-
-    if (browser_window_id_ != extension_misc::kUnknownWindowId &&
-        helper->browser_window_id() != browser_window_id_) {
-      return true;
-    }
-
-    views_.push_back(render_view);
-
-    if (view_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE)
-      return false;  // There can be only one...
-    return true;
-  }
-
- private:
-  // Returns true if |type| "isa" |match|.
-  static bool ViewTypeMatches(ViewType type, ViewType match) {
-    if (type == match)
-      return true;
-
-    // INVALID means match all.
-    if (match == VIEW_TYPE_INVALID)
-      return true;
-
-    return false;
-  }
-
-  std::string extension_id_;
-  int browser_window_id_;
-  ViewType view_type_;
-  std::vector<content::RenderView*> views_;
-};
-
-}  // namespace
-
-// static
-std::vector<content::RenderView*> ExtensionHelper::GetExtensionViews(
-    const std::string& extension_id,
-    int browser_window_id,
-    ViewType view_type) {
-  ViewAccumulator accumulator(extension_id, browser_window_id, view_type);
-  content::RenderView::ForEach(&accumulator);
-  return accumulator.views();
-}
-
-// static
-content::RenderView* ExtensionHelper::GetBackgroundPage(
-    const std::string& extension_id) {
-  ViewAccumulator accumulator(extension_id, extension_misc::kUnknownWindowId,
-                              VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
-  content::RenderView::ForEach(&accumulator);
-  CHECK_LE(accumulator.views().size(), 1u);
-  if (accumulator.views().size() == 0)
-    return NULL;
-  return accumulator.views()[0];
-}
-
-ExtensionHelper::ExtensionHelper(content::RenderView* render_view,
-                                 Dispatcher* dispatcher)
-    : content::RenderViewObserver(render_view),
-      content::RenderViewObserverTracker<ExtensionHelper>(render_view),
-      dispatcher_(dispatcher),
-      pending_app_icon_requests_(0),
-      view_type_(VIEW_TYPE_INVALID),
-      tab_id_(-1),
-      browser_window_id_(-1) {
-}
-
-ExtensionHelper::~ExtensionHelper() {
-}
-
-bool ExtensionHelper::OnMessageReceived(const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(ExtensionHelper, message)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_Response, OnExtensionResponse)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnExtensionMessageInvoke)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect,
-                        OnExtensionDispatchOnConnect)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnExtensionDeliverMessage)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect,
-                        OnExtensionDispatchOnDisconnect)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_ExecuteCode, OnExecuteCode)
-    IPC_MESSAGE_HANDLER(ChromeExtensionMsg_GetApplicationInfo,
-                        OnGetApplicationInfo)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_SetTabId, OnSetTabId)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateBrowserWindowId,
-                        OnUpdateBrowserWindowId)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_NotifyRenderViewType,
-                        OnNotifyRendererViewType)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_AddMessageToConsole,
-                        OnAddMessageToConsole)
-    IPC_MESSAGE_HANDLER(ExtensionMsg_AppWindowClosed,
-                        OnAppWindowClosed);
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-void ExtensionHelper::DidFinishDocumentLoad(WebLocalFrame* frame) {
-  dispatcher_->user_script_slave()->InjectScripts(
-      frame, UserScript::DOCUMENT_END);
-
-  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
-  if (i != g_schedulers.Get().end())
-    i->second->DidFinishDocumentLoad();
-}
-
-void ExtensionHelper::DidFinishLoad(blink::WebLocalFrame* frame) {
-  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
-  if (i != g_schedulers.Get().end())
-    i->second->DidFinishLoad();
-}
-
-void ExtensionHelper::DidCreateDocumentElement(WebLocalFrame* frame) {
-  dispatcher_->user_script_slave()->InjectScripts(
-      frame, UserScript::DOCUMENT_START);
-  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
-  if (i != g_schedulers.Get().end())
-    i->second->DidCreateDocumentElement();
-
-  dispatcher_->DidCreateDocumentElement(frame);
-}
-
-void ExtensionHelper::DidStartProvisionalLoad(blink::WebLocalFrame* frame) {
-  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
-  if (i != g_schedulers.Get().end())
-    i->second->DidStartProvisionalLoad();
-}
-
-void ExtensionHelper::DraggableRegionsChanged(blink::WebFrame* frame) {
-  blink::WebVector<blink::WebDraggableRegion> webregions =
-      frame->document().draggableRegions();
-  std::vector<DraggableRegion> regions;
-  for (size_t i = 0; i < webregions.size(); ++i) {
-    DraggableRegion region;
-    region.bounds = webregions[i].bounds;
-    region.draggable = webregions[i].draggable;
-    regions.push_back(region);
-  }
-  Send(new ExtensionHostMsg_UpdateDraggableRegions(routing_id(), regions));
-}
-
-void ExtensionHelper::FrameDetached(WebFrame* frame) {
-  // This could be called before DidCreateDataSource, in which case the frame
-  // won't be in the map.
-  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
-  if (i == g_schedulers.Get().end())
-    return;
-
-  delete i->second;
-  g_schedulers.Get().erase(i);
-}
-
-void ExtensionHelper::DidMatchCSS(
-    blink::WebLocalFrame* frame,
-    const blink::WebVector<blink::WebString>& newly_matching_selectors,
-    const blink::WebVector<blink::WebString>& stopped_matching_selectors) {
-  dispatcher_->DidMatchCSS(
-      frame, newly_matching_selectors, stopped_matching_selectors);
-}
-
-void ExtensionHelper::DidCreateDataSource(WebLocalFrame* frame,
-                                          WebDataSource* ds) {
-  // Check first if we created a scheduler for the frame, since this function
-  // gets called for navigations within the document.
-  if (g_schedulers.Get().count(frame))
-    return;
-
-  g_schedulers.Get()[frame] = new UserScriptScheduler(frame, dispatcher_);
-}
-
-void ExtensionHelper::OnExtensionResponse(int request_id,
-                                          bool success,
-                                          const base::ListValue& response,
-                                          const std::string& error) {
-  dispatcher_->OnExtensionResponse(request_id,
-                                   success,
-                                   response,
-                                   error);
-}
-
-void ExtensionHelper::OnExtensionMessageInvoke(const std::string& extension_id,
-                                               const std::string& module_name,
-                                               const std::string& function_name,
-                                               const base::ListValue& args,
-                                               bool user_gesture) {
-  dispatcher_->InvokeModuleSystemMethod(
-      render_view(), extension_id, module_name, function_name, args,
-      user_gesture);
-}
-
-void ExtensionHelper::OnExtensionDispatchOnConnect(
-    int target_port_id,
-    const std::string& channel_name,
-    const base::DictionaryValue& source_tab,
-    const ExtensionMsg_ExternalConnectionInfo& info,
-    const std::string& tls_channel_id) {
-  MessagingBindings::DispatchOnConnect(
-      dispatcher_->script_context_set().GetAll(),
-      target_port_id,
-      channel_name,
-      source_tab,
-      info.source_id,
-      info.target_id,
-      info.source_url,
-      tls_channel_id,
-      render_view());
-}
-
-void ExtensionHelper::OnExtensionDeliverMessage(int target_id,
-                                                const Message& message) {
-  MessagingBindings::DeliverMessage(dispatcher_->script_context_set().GetAll(),
-                                    target_id,
-                                    message,
-                                    render_view());
-}
-
-void ExtensionHelper::OnExtensionDispatchOnDisconnect(
-    int port_id,
-    const std::string& error_message) {
-  MessagingBindings::DispatchOnDisconnect(
-      dispatcher_->script_context_set().GetAll(),
-      port_id,
-      error_message,
-      render_view());
-}
-
-void ExtensionHelper::OnExecuteCode(
-    const ExtensionMsg_ExecuteCode_Params& params) {
-  WebView* webview = render_view()->GetWebView();
-  WebFrame* main_frame = webview->mainFrame();
-  if (!main_frame) {
-    base::ListValue val;
-    Send(new ExtensionHostMsg_ExecuteCodeFinished(routing_id(),
-                                                  params.request_id,
-                                                  "No main frame",
-                                                  -1,
-                                                  GURL(std::string()),
-                                                  val));
-    return;
-  }
-
-  // chrome.tabs.executeScript() only supports execution in either the top frame
-  // or all frames.  We handle both cases in the top frame.
-  SchedulerMap::iterator i = g_schedulers.Get().find(main_frame);
-  if (i != g_schedulers.Get().end())
-    i->second->ExecuteCode(params);
-}
-
-void ExtensionHelper::OnGetApplicationInfo(int page_id) {
-  WebApplicationInfo app_info;
-  if (page_id == render_view()->GetPageId()) {
-    base::string16 error;
-    web_apps::ParseWebAppFromWebDocument(
-        render_view()->GetWebView()->mainFrame(), &app_info, &error);
-  }
-
-  // Prune out any data URLs in the set of icons.  The browser process expects
-  // any icon with a data URL to have originated from a favicon.  We don't want
-  // to decode arbitrary data URLs in the browser process.  See
-  // http://b/issue?id=1162972
-  for (size_t i = 0; i < app_info.icons.size(); ++i) {
-    if (app_info.icons[i].url.SchemeIs(content::kDataScheme)) {
-      app_info.icons.erase(app_info.icons.begin() + i);
-      --i;
-    }
-  }
-
-  Send(new ChromeExtensionHostMsg_DidGetApplicationInfo(
-      routing_id(), page_id, app_info));
-}
-
-void ExtensionHelper::OnNotifyRendererViewType(ViewType type) {
-  view_type_ = type;
-}
-
-void ExtensionHelper::OnSetTabId(int init_tab_id) {
-  CHECK_EQ(tab_id_, -1);
-  CHECK_GE(init_tab_id, 0);
-  tab_id_ = init_tab_id;
-}
-
-void ExtensionHelper::OnUpdateBrowserWindowId(int window_id) {
-  browser_window_id_ = window_id;
-}
-
-void ExtensionHelper::OnAddMessageToConsole(ConsoleMessageLevel level,
-                                            const std::string& message) {
-  console::AddMessage(render_view(), level, message);
-}
-
-void ExtensionHelper::OnAppWindowClosed() {
-  v8::HandleScope scope(v8::Isolate::GetCurrent());
-  v8::Handle<v8::Context> v8_context =
-      render_view()->GetWebView()->mainFrame()->mainWorldScriptContext();
-  ScriptContext* script_context =
-      dispatcher_->script_context_set().GetByV8Context(v8_context);
-  if (!script_context)
-    return;
-  script_context->module_system()->CallModuleMethod("app.window",
-                                                    "onAppWindowClosed");
-}
-
-}  // namespace extensions
diff --git a/chrome/renderer/extensions/extension_helper.h b/chrome/renderer/extensions/extension_helper.h
deleted file mode 100644
index c06a5f0..0000000
--- a/chrome/renderer/extensions/extension_helper.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_RENDERER_EXTENSIONS_EXTENSION_HELPER_H_
-#define CHROME_RENDERER_EXTENSIONS_EXTENSION_HELPER_H_
-
-#include <map>
-#include <vector>
-
-#include "base/memory/linked_ptr.h"
-#include "base/memory/scoped_ptr.h"
-#include "content/public/common/console_message_level.h"
-#include "content/public/renderer/render_view_observer.h"
-#include "content/public/renderer/render_view_observer_tracker.h"
-#include "extensions/common/view_type.h"
-#include "third_party/WebKit/public/platform/WebURLResponse.h"
-
-class GURL;
-class SkBitmap;
-struct ExtensionMsg_ExecuteCode_Params;
-struct ExtensionMsg_ExternalConnectionInfo;
-struct WebApplicationInfo;
-
-namespace base {
-class DictionaryValue;
-class ListValue;
-}
-
-namespace extensions {
-class Dispatcher;
-struct Message;
-
-// RenderView-level plumbing for extension features.
-class ExtensionHelper
-    : public content::RenderViewObserver,
-      public content::RenderViewObserverTracker<ExtensionHelper> {
- public:
-  // Returns a list of extension RenderViews that match the given filter
-  // criteria. If |browser_window_id| is not extension_misc::kUnknownWindowId,
-  // the list is restricted to views in that browser window.
-  static std::vector<content::RenderView*> GetExtensionViews(
-      const std::string& extension_id,
-      int browser_window_id,
-      ViewType view_type);
-
-  // Returns the given extension's background page, or NULL if none.
-  static content::RenderView* GetBackgroundPage(
-      const std::string& extension_id);
-
-  ExtensionHelper(content::RenderView* render_view, Dispatcher* dispatcher);
-  virtual ~ExtensionHelper();
-
-  int tab_id() const { return tab_id_; }
-  int browser_window_id() const { return browser_window_id_; }
-  ViewType view_type() const { return view_type_; }
-  Dispatcher* dispatcher() const { return dispatcher_; }
-
- private:
-  // RenderViewObserver implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-  virtual void DidFinishDocumentLoad(blink::WebLocalFrame* frame) OVERRIDE;
-  virtual void DidFinishLoad(blink::WebLocalFrame* frame) OVERRIDE;
-  virtual void DidCreateDocumentElement(blink::WebLocalFrame* frame) OVERRIDE;
-  virtual void DidStartProvisionalLoad(blink::WebLocalFrame* frame) OVERRIDE;
-  virtual void FrameDetached(blink::WebFrame* frame) OVERRIDE;
-  virtual void DidMatchCSS(
-      blink::WebLocalFrame* frame,
-      const blink::WebVector<blink::WebString>& newly_matching_selectors,
-      const blink::WebVector<blink::WebString>& stopped_matching_selectors)
-      OVERRIDE;
-  virtual void DidCreateDataSource(blink::WebLocalFrame* frame,
-                                   blink::WebDataSource* ds) OVERRIDE;
-  virtual void DraggableRegionsChanged(blink::WebFrame* frame) OVERRIDE;
-
-  void OnExtensionResponse(int request_id, bool success,
-                           const base::ListValue& response,
-                           const std::string& error);
-  void OnExtensionMessageInvoke(const std::string& extension_id,
-                                const std::string& module_name,
-                                const std::string& function_name,
-                                const base::ListValue& args,
-                                bool user_gesture);
-  void OnExtensionDispatchOnConnect(
-      int target_port_id,
-      const std::string& channel_name,
-      const base::DictionaryValue& source_tab,
-      const ExtensionMsg_ExternalConnectionInfo& info,
-      const std::string& tls_channel_id);
-  void OnExtensionDeliverMessage(int target_port_id,
-                                 const Message& message);
-  void OnExtensionDispatchOnDisconnect(int port_id,
-                                       const std::string& error_message);
-  void OnExecuteCode(const ExtensionMsg_ExecuteCode_Params& params);
-  void OnGetApplicationInfo(int page_id);
-  void OnNotifyRendererViewType(ViewType view_type);
-  void OnSetTabId(int tab_id);
-  void OnUpdateBrowserWindowId(int window_id);
-  void OnAddMessageToConsole(content::ConsoleMessageLevel level,
-                             const std::string& message);
-  void OnAppWindowClosed();
-
-  Dispatcher* dispatcher_;
-
-  // The app info that we are processing. This is used when installing an app
-  // via application definition. The in-progress web app is stored here while
-  // its manifest and icons are downloaded.
-  scoped_ptr<WebApplicationInfo> pending_app_info_;
-
-  // The number of app icon requests outstanding. When this reaches zero, we're
-  // done processing an app definition file.
-  int pending_app_icon_requests_;
-
-  // Type of view attached with RenderView.
-  ViewType view_type_;
-
-  // Id of the tab which the RenderView is attached to.
-  int tab_id_;
-
-  // Id number of browser window which RenderView is attached to.
-  int browser_window_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExtensionHelper);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_RENDERER_EXTENSIONS_EXTENSION_HELPER_H_
diff --git a/chrome/renderer/extensions/extension_localization_peer_unittest.cc b/chrome/renderer/extensions/extension_localization_peer_unittest.cc
index 11cb27f..c8e6f7c 100644
--- a/chrome/renderer/extensions/extension_localization_peer_unittest.cc
+++ b/chrome/renderer/extensions/extension_localization_peer_unittest.cc
@@ -14,7 +14,6 @@
 #include "net/url_request/url_request_status.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "webkit/child/resource_loader_bridge.h"
 
 using testing::_;
 using testing::DoAll;
diff --git a/chrome/renderer/extensions/messaging_bindings.cc b/chrome/renderer/extensions/messaging_bindings.cc
deleted file mode 100644
index 1590724..0000000
--- a/chrome/renderer/extensions/messaging_bindings.cc
+++ /dev/null
@@ -1,448 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/renderer/extensions/messaging_bindings.h"
-
-#include <map>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/lazy_instance.h"
-#include "base/message_loop/message_loop.h"
-#include "base/values.h"
-#include "chrome/common/extensions/manifest_handlers/externally_connectable.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/renderer/extensions/dispatcher.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/public/renderer/render_view.h"
-#include "content/public/renderer/v8_value_converter.h"
-#include "extensions/common/api/messaging/message.h"
-#include "extensions/common/extension_messages.h"
-#include "extensions/renderer/event_bindings.h"
-#include "extensions/renderer/object_backed_native_handler.h"
-#include "extensions/renderer/scoped_persistent.h"
-#include "extensions/renderer/script_context.h"
-#include "extensions/renderer/script_context_set.h"
-#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
-#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
-#include "third_party/WebKit/public/web/WebScopedWindowFocusAllowedIndicator.h"
-#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
-#include "third_party/WebKit/public/web/WebUserGestureToken.h"
-#include "v8/include/v8.h"
-
-// Message passing API example (in a content script):
-// var extension =
-//    new chrome.Extension('00123456789abcdef0123456789abcdef0123456');
-// var port = runtime.connect();
-// port.postMessage('Can you hear me now?');
-// port.onmessage.addListener(function(msg, port) {
-//   alert('response=' + msg);
-//   port.postMessage('I got your reponse');
-// });
-
-using content::RenderThread;
-using content::V8ValueConverter;
-
-namespace extensions {
-
-namespace {
-
-struct ExtensionData {
-  struct PortData {
-    int ref_count;  // how many contexts have a handle to this port
-    PortData() : ref_count(0) {}
-  };
-  std::map<int, PortData> ports;  // port ID -> data
-};
-
-base::LazyInstance<ExtensionData> g_extension_data =
-    LAZY_INSTANCE_INITIALIZER;
-
-bool HasPortData(int port_id) {
-  return g_extension_data.Get().ports.find(port_id) !=
-      g_extension_data.Get().ports.end();
-}
-
-ExtensionData::PortData& GetPortData(int port_id) {
-  return g_extension_data.Get().ports[port_id];
-}
-
-void ClearPortData(int port_id) {
-  g_extension_data.Get().ports.erase(port_id);
-}
-
-const char kPortClosedError[] = "Attempting to use a disconnected port object";
-const char kReceivingEndDoesntExistError[] =
-    "Could not establish connection. Receiving end does not exist.";
-
-class ExtensionImpl : public ObjectBackedNativeHandler {
- public:
-  ExtensionImpl(Dispatcher* dispatcher, ScriptContext* context)
-      : ObjectBackedNativeHandler(context), dispatcher_(dispatcher) {
-    RouteFunction("CloseChannel",
-        base::Bind(&ExtensionImpl::CloseChannel, base::Unretained(this)));
-    RouteFunction("PortAddRef",
-        base::Bind(&ExtensionImpl::PortAddRef, base::Unretained(this)));
-    RouteFunction("PortRelease",
-        base::Bind(&ExtensionImpl::PortRelease, base::Unretained(this)));
-    RouteFunction("PostMessage",
-        base::Bind(&ExtensionImpl::PostMessage, base::Unretained(this)));
-    // TODO(fsamuel, kalman): Move BindToGC out of messaging natives.
-    RouteFunction("BindToGC",
-        base::Bind(&ExtensionImpl::BindToGC, base::Unretained(this)));
-  }
-
-  virtual ~ExtensionImpl() {}
-
- private:
-  void ClearPortDataAndNotifyDispatcher(int port_id) {
-    ClearPortData(port_id);
-    dispatcher_->ClearPortData(port_id);
-  }
-
-  bool ShouldForwardUserGesture() {
-    return blink::WebUserGestureIndicator::isProcessingUserGesture() &&
-           !blink::WebUserGestureIndicator::currentUserGestureToken()
-                .wasForwarded();
-  }
-
-  // Sends a message along the given channel.
-  void PostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    content::RenderView* renderview = context()->GetRenderView();
-    if (!renderview)
-      return;
-
-    // Arguments are (int32 port_id, string message).
-    CHECK(args.Length() == 2 &&
-          args[0]->IsInt32() &&
-          args[1]->IsString());
-
-    int port_id = args[0]->Int32Value();
-    if (!HasPortData(port_id)) {
-      args.GetIsolate()->ThrowException(v8::Exception::Error(
-          v8::String::NewFromUtf8(args.GetIsolate(), kPortClosedError)));
-      return;
-    }
-
-    renderview->Send(new ExtensionHostMsg_PostMessage(
-        renderview->GetRoutingID(),
-        port_id,
-        Message(*v8::String::Utf8Value(args[1]), ShouldForwardUserGesture())));
-  }
-
-  // Forcefully disconnects a port.
-  void CloseChannel(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    // Arguments are (int32 port_id, boolean notify_browser).
-    CHECK_EQ(2, args.Length());
-    CHECK(args[0]->IsInt32());
-    CHECK(args[1]->IsBoolean());
-
-    int port_id = args[0]->Int32Value();
-    if (!HasPortData(port_id))
-      return;
-
-    // Send via the RenderThread because the RenderView might be closing.
-    bool notify_browser = args[1]->BooleanValue();
-    if (notify_browser) {
-      content::RenderThread::Get()->Send(
-          new ExtensionHostMsg_CloseChannel(port_id, std::string()));
-    }
-
-    ClearPortDataAndNotifyDispatcher(port_id);
-  }
-
-  // A new port has been created for a context.  This occurs both when script
-  // opens a connection, and when a connection is opened to this script.
-  void PortAddRef(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    // Arguments are (int32 port_id).
-    CHECK_EQ(1, args.Length());
-    CHECK(args[0]->IsInt32());
-
-    int port_id = args[0]->Int32Value();
-    ++GetPortData(port_id).ref_count;
-  }
-
-  // The frame a port lived in has been destroyed.  When there are no more
-  // frames with a reference to a given port, we will disconnect it and notify
-  // the other end of the channel.
-  void PortRelease(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    // Arguments are (int32 port_id).
-    CHECK_EQ(1, args.Length());
-    CHECK(args[0]->IsInt32());
-
-    int port_id = args[0]->Int32Value();
-    if (HasPortData(port_id) && --GetPortData(port_id).ref_count == 0) {
-      // Send via the RenderThread because the RenderView might be closing.
-      content::RenderThread::Get()->Send(
-          new ExtensionHostMsg_CloseChannel(port_id, std::string()));
-      ClearPortDataAndNotifyDispatcher(port_id);
-    }
-  }
-
-  // Holds a |callback| to run sometime after |object| is GC'ed. |callback| will
-  // not be executed re-entrantly to avoid running JS in an unexpected state.
-  class GCCallback {
-   public:
-    static void Bind(v8::Handle<v8::Object> object,
-                     v8::Handle<v8::Function> callback,
-                     v8::Isolate* isolate) {
-      GCCallback* cb = new GCCallback(object, callback, isolate);
-      cb->object_.SetWeak(cb, NearDeathCallback);
-    }
-
-   private:
-    static void NearDeathCallback(
-        const v8::WeakCallbackData<v8::Object, GCCallback>& data) {
-      // v8 says we need to explicitly reset weak handles from their callbacks.
-      // It's not implicit as one might expect.
-      data.GetParameter()->object_.reset();
-      base::MessageLoop::current()->PostTask(
-          FROM_HERE,
-          base::Bind(&GCCallback::RunCallback,
-                     base::Owned(data.GetParameter())));
-    }
-
-    GCCallback(v8::Handle<v8::Object> object,
-               v8::Handle<v8::Function> callback,
-               v8::Isolate* isolate)
-        : object_(object), callback_(callback), isolate_(isolate) {}
-
-    void RunCallback() {
-      v8::HandleScope handle_scope(isolate_);
-      v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_);
-      v8::Handle<v8::Context> context = callback->CreationContext();
-      if (context.IsEmpty())
-        return;
-      v8::Context::Scope context_scope(context);
-      blink::WebScopedMicrotaskSuppression suppression;
-      callback->Call(context->Global(), 0, NULL);
-    }
-
-    ScopedPersistent<v8::Object> object_;
-    ScopedPersistent<v8::Function> callback_;
-    v8::Isolate* isolate_;
-
-    DISALLOW_COPY_AND_ASSIGN(GCCallback);
-  };
-
-  // void BindToGC(object, callback)
-  //
-  // Binds |callback| to be invoked *sometime after* |object| is garbage
-  // collected. We don't call the method re-entrantly so as to avoid executing
-  // JS in some bizarro undefined mid-GC state.
-  void BindToGC(const v8::FunctionCallbackInfo<v8::Value>& args) {
-    CHECK(args.Length() == 2 && args[0]->IsObject() && args[1]->IsFunction());
-    GCCallback::Bind(args[0].As<v8::Object>(),
-                     args[1].As<v8::Function>(),
-                     args.GetIsolate());
-  }
-
-  // Dispatcher handle. Not owned.
-  Dispatcher* dispatcher_;
-};
-
-}  // namespace
-
-ObjectBackedNativeHandler* MessagingBindings::Get(Dispatcher* dispatcher,
-                                                  ScriptContext* context) {
-  return new ExtensionImpl(dispatcher, context);
-}
-
-// static
-void MessagingBindings::DispatchOnConnect(
-    const ScriptContextSet::ContextSet& contexts,
-    int target_port_id,
-    const std::string& channel_name,
-    const base::DictionaryValue& source_tab,
-    const std::string& source_extension_id,
-    const std::string& target_extension_id,
-    const GURL& source_url,
-    const std::string& tls_channel_id,
-    content::RenderView* restrict_to_render_view) {
-  v8::Isolate* isolate = v8::Isolate::GetCurrent();
-  v8::HandleScope handle_scope(isolate);
-
-  scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
-
-  bool port_created = false;
-  std::string source_url_spec = source_url.spec();
-
-  // TODO(kalman): pass in the full ScriptContextSet; call ForEach.
-  for (ScriptContextSet::ContextSet::const_iterator it = contexts.begin();
-       it != contexts.end();
-       ++it) {
-    if (restrict_to_render_view &&
-        restrict_to_render_view != (*it)->GetRenderView()) {
-      continue;
-    }
-
-    // TODO(kalman): remove when ContextSet::ForEach is available.
-    if ((*it)->v8_context().IsEmpty())
-      continue;
-
-    v8::Handle<v8::Value> tab = v8::Null(isolate);
-    v8::Handle<v8::Value> tls_channel_id_value = v8::Undefined(isolate);
-    const Extension* extension = (*it)->extension();
-    if (extension) {
-      if (!source_tab.empty() && !extension->is_platform_app())
-        tab = converter->ToV8Value(&source_tab, (*it)->v8_context());
-
-      ExternallyConnectableInfo* externally_connectable =
-          ExternallyConnectableInfo::Get(extension);
-      if (externally_connectable &&
-          externally_connectable->accepts_tls_channel_id) {
-        tls_channel_id_value =
-            v8::String::NewFromUtf8(isolate,
-                                    tls_channel_id.c_str(),
-                                    v8::String::kNormalString,
-                                    tls_channel_id.size());
-      }
-    }
-
-    v8::Handle<v8::Value> arguments[] = {
-      // portId
-      v8::Integer::New(isolate, target_port_id),
-      // channelName
-      v8::String::NewFromUtf8(isolate,
-                              channel_name.c_str(),
-                              v8::String::kNormalString,
-                              channel_name.size()),
-      // sourceTab
-      tab,
-      // sourceExtensionId
-      v8::String::NewFromUtf8(isolate,
-                              source_extension_id.c_str(),
-                              v8::String::kNormalString,
-                              source_extension_id.size()),
-      // targetExtensionId
-      v8::String::NewFromUtf8(isolate,
-                              target_extension_id.c_str(),
-                              v8::String::kNormalString,
-                              target_extension_id.size()),
-      // sourceUrl
-      v8::String::NewFromUtf8(isolate,
-                              source_url_spec.c_str(),
-                              v8::String::kNormalString,
-                              source_url_spec.size()),
-      // tlsChannelId
-      tls_channel_id_value,
-    };
-
-    v8::Handle<v8::Value> retval = (*it)->module_system()->CallModuleMethod(
-        "messaging",
-        "dispatchOnConnect",
-        arraysize(arguments), arguments);
-
-    if (retval.IsEmpty()) {
-      LOG(ERROR) << "Empty return value from dispatchOnConnect.";
-      continue;
-    }
-
-    CHECK(retval->IsBoolean());
-    port_created |= retval->BooleanValue();
-  }
-
-  // If we didn't create a port, notify the other end of the channel (treat it
-  // as a disconnect).
-  if (!port_created) {
-    content::RenderThread::Get()->Send(
-        new ExtensionHostMsg_CloseChannel(
-            target_port_id, kReceivingEndDoesntExistError));
-  }
-}
-
-// static
-void MessagingBindings::DeliverMessage(
-    const ScriptContextSet::ContextSet& contexts,
-    int target_port_id,
-    const Message& message,
-    content::RenderView* restrict_to_render_view) {
-  scoped_ptr<blink::WebScopedUserGesture> web_user_gesture;
-  scoped_ptr<blink::WebScopedWindowFocusAllowedIndicator> allow_window_focus;
-  if (message.user_gesture) {
-    web_user_gesture.reset(new blink::WebScopedUserGesture);
-    blink::WebUserGestureIndicator::currentUserGestureToken().setForwarded();
-    allow_window_focus.reset(new blink::WebScopedWindowFocusAllowedIndicator);
-  }
-
-  v8::Isolate* isolate = v8::Isolate::GetCurrent();
-  v8::HandleScope handle_scope(isolate);
-
-  // TODO(kalman): pass in the full ScriptContextSet; call ForEach.
-  for (ScriptContextSet::ContextSet::const_iterator it = contexts.begin();
-       it != contexts.end();
-       ++it) {
-    if (restrict_to_render_view &&
-        restrict_to_render_view != (*it)->GetRenderView()) {
-      continue;
-    }
-
-    // TODO(kalman): remove when ContextSet::ForEach is available.
-    if ((*it)->v8_context().IsEmpty())
-      continue;
-
-    // Check to see whether the context has this port before bothering to create
-    // the message.
-    v8::Handle<v8::Value> port_id_handle =
-        v8::Integer::New(isolate, target_port_id);
-    v8::Handle<v8::Value> has_port = (*it)->module_system()->CallModuleMethod(
-        "messaging",
-        "hasPort",
-        1, &port_id_handle);
-
-    CHECK(!has_port.IsEmpty());
-    if (!has_port->BooleanValue())
-      continue;
-
-    std::vector<v8::Handle<v8::Value> > arguments;
-    arguments.push_back(v8::String::NewFromUtf8(isolate,
-                                                message.data.c_str(),
-                                                v8::String::kNormalString,
-                                                message.data.size()));
-    arguments.push_back(port_id_handle);
-    (*it)->module_system()->CallModuleMethod("messaging",
-                                             "dispatchOnMessage",
-                                             &arguments);
-  }
-}
-
-// static
-void MessagingBindings::DispatchOnDisconnect(
-    const ScriptContextSet::ContextSet& contexts,
-    int port_id,
-    const std::string& error_message,
-    content::RenderView* restrict_to_render_view) {
-  v8::Isolate* isolate = v8::Isolate::GetCurrent();
-  v8::HandleScope handle_scope(isolate);
-
-  // TODO(kalman): pass in the full ScriptContextSet; call ForEach.
-  for (ScriptContextSet::ContextSet::const_iterator it = contexts.begin();
-       it != contexts.end();
-       ++it) {
-    if (restrict_to_render_view &&
-        restrict_to_render_view != (*it)->GetRenderView()) {
-      continue;
-    }
-
-    // TODO(kalman): remove when ContextSet::ForEach is available.
-    if ((*it)->v8_context().IsEmpty())
-      continue;
-
-    std::vector<v8::Handle<v8::Value> > arguments;
-    arguments.push_back(v8::Integer::New(isolate, port_id));
-    if (!error_message.empty()) {
-      arguments.push_back(
-          v8::String::NewFromUtf8(isolate, error_message.c_str()));
-    } else {
-      arguments.push_back(v8::Null(isolate));
-    }
-    (*it)->module_system()->CallModuleMethod("messaging",
-                                             "dispatchOnDisconnect",
-                                             &arguments);
-  }
-}
-
-}  // namespace extensions
diff --git a/chrome/renderer/extensions/messaging_bindings.h b/chrome/renderer/extensions/messaging_bindings.h
deleted file mode 100644
index ab3c093..0000000
--- a/chrome/renderer/extensions/messaging_bindings.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_RENDERER_EXTENSIONS_MESSAGING_BINDINGS_H_
-#define CHROME_RENDERER_EXTENSIONS_MESSAGING_BINDINGS_H_
-
-#include <string>
-
-#include "extensions/renderer/script_context_set.h"
-
-namespace base {
-class DictionaryValue;
-}
-
-namespace content {
-class RenderView;
-}
-
-namespace v8 {
-class Extension;
-}
-
-namespace extensions {
-class Dispatcher;
-struct Message;
-class ObjectBackedNativeHandler;
-
-// Manually implements JavaScript bindings for extension messaging.
-//
-// TODO(aa): This should all get re-implemented using SchemaGeneratedBindings.
-// If anything needs to be manual for some reason, it should be implemented in
-// its own class.
-class MessagingBindings {
- public:
-  // Creates an instance of the extension.
-  static ObjectBackedNativeHandler* Get(Dispatcher* dispatcher,
-                                        ScriptContext* context);
-
-  // Dispatches the onConnect content script messaging event to some contexts
-  // in |contexts|. If |restrict_to_render_view| is specified, only contexts in
-  // that render view will receive the message.
-  static void DispatchOnConnect(const ScriptContextSet::ContextSet& contexts,
-                                int target_port_id,
-                                const std::string& channel_name,
-                                const base::DictionaryValue& source_tab,
-                                const std::string& source_extension_id,
-                                const std::string& target_extension_id,
-                                const GURL& source_url,
-                                const std::string& tls_channel_id,
-                                content::RenderView* restrict_to_render_view);
-
-  // Delivers a message sent using content script messaging to some of the
-  // contexts in |bindings_context_set|. If |restrict_to_render_view| is
-  // specified, only contexts in that render view will receive the message.
-  static void DeliverMessage(const ScriptContextSet::ContextSet& context_set,
-                             int target_port_id,
-                             const Message& message,
-                             content::RenderView* restrict_to_render_view);
-
-  // Dispatches the onDisconnect event in response to the channel being closed.
-  static void DispatchOnDisconnect(
-      const ScriptContextSet::ContextSet& context_set,
-      int port_id,
-      const std::string& error_message,
-      content::RenderView* restrict_to_render_view);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_RENDERER_EXTENSIONS_MESSAGING_BINDINGS_H_
diff --git a/chrome/renderer/extensions/page_actions_custom_bindings.cc b/chrome/renderer/extensions/page_actions_custom_bindings.cc
index fa74cfb..32237a2 100644
--- a/chrome/renderer/extensions/page_actions_custom_bindings.cc
+++ b/chrome/renderer/extensions/page_actions_custom_bindings.cc
@@ -8,8 +8,8 @@
 
 #include "base/bind.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
-#include "chrome/renderer/extensions/dispatcher.h"
 #include "extensions/common/extension.h"
+#include "extensions/renderer/dispatcher.h"
 #include "extensions/renderer/script_context.h"
 #include "v8/include/v8.h"
 
diff --git a/chrome/renderer/extensions/renderer_permissions_policy_delegate.cc b/chrome/renderer/extensions/renderer_permissions_policy_delegate.cc
index 2774064..63744c2 100644
--- a/chrome/renderer/extensions/renderer_permissions_policy_delegate.cc
+++ b/chrome/renderer/extensions/renderer_permissions_policy_delegate.cc
@@ -7,10 +7,10 @@
 #include "base/command_line.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
-#include "chrome/renderer/extensions/dispatcher.h"
 #include "extensions/common/extensions_client.h"
 #include "extensions/common/manifest_constants.h"
 #include "extensions/common/switches.h"
+#include "extensions/renderer/dispatcher.h"
 
 namespace extensions {
 
diff --git a/chrome/renderer/extensions/renderer_permissions_policy_delegate_unittest.cc b/chrome/renderer/extensions/renderer_permissions_policy_delegate_unittest.cc
index 4cd5d97..b17d76e 100644
--- a/chrome/renderer/extensions/renderer_permissions_policy_delegate_unittest.cc
+++ b/chrome/renderer/extensions/renderer_permissions_policy_delegate_unittest.cc
@@ -5,7 +5,7 @@
 #include "base/command_line.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
-#include "chrome/renderer/extensions/dispatcher.h"
+#include "chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h"
 #include "chrome/renderer/extensions/renderer_permissions_policy_delegate.h"
 #include "content/public/test/mock_render_process_host.h"
 #include "content/public/test/mock_render_thread.h"
@@ -13,6 +13,7 @@
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/extension_messages.h"
 #include "extensions/common/permissions/permissions_data.h"
+#include "extensions/renderer/dispatcher.h"
 #include "extensions/renderer/test_extensions_renderer_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -30,7 +31,10 @@
     render_thread_.reset(new content::MockRenderThread());
     renderer_client_.reset(new TestExtensionsRendererClient);
     ExtensionsRendererClient::Set(renderer_client_.get());
-    extension_dispatcher_.reset(new Dispatcher());
+    extension_dispatcher_delegate_.reset(
+        new ChromeExtensionsDispatcherDelegate());
+    extension_dispatcher_.reset(
+        new Dispatcher(extension_dispatcher_delegate_.get()));
     policy_delegate_.reset(
         new RendererPermissionsPolicyDelegate(extension_dispatcher_.get()));
   }
@@ -38,6 +42,7 @@
  protected:
   scoped_ptr<content::MockRenderThread> render_thread_;
   scoped_ptr<ExtensionsRendererClient> renderer_client_;
+  scoped_ptr<DispatcherDelegate> extension_dispatcher_delegate_;
   scoped_ptr<Dispatcher> extension_dispatcher_;
   scoped_ptr<RendererPermissionsPolicyDelegate> policy_delegate_;
 };
diff --git a/chrome/renderer/extensions/runtime_custom_bindings.cc b/chrome/renderer/extensions/runtime_custom_bindings.cc
deleted file mode 100644
index bc36d78..0000000
--- a/chrome/renderer/extensions/runtime_custom_bindings.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/renderer/extensions/runtime_custom_bindings.h"
-
-#include "base/bind.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/values.h"
-#include "chrome/renderer/extensions/api_activity_logger.h"
-#include "chrome/renderer/extensions/extension_helper.h"
-#include "content/public/renderer/render_view.h"
-#include "content/public/renderer/v8_value_converter.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/extension_messages.h"
-#include "extensions/common/features/feature.h"
-#include "extensions/common/features/feature_provider.h"
-#include "extensions/common/manifest.h"
-#include "extensions/renderer/script_context.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebView.h"
-
-using content::V8ValueConverter;
-
-namespace extensions {
-
-RuntimeCustomBindings::RuntimeCustomBindings(ScriptContext* context)
-    : ObjectBackedNativeHandler(context) {
-  RouteFunction("GetManifest",
-                base::Bind(&RuntimeCustomBindings::GetManifest,
-                           base::Unretained(this)));
-  RouteFunction("OpenChannelToExtension",
-                base::Bind(&RuntimeCustomBindings::OpenChannelToExtension,
-                           base::Unretained(this)));
-  RouteFunction("OpenChannelToNativeApp",
-                base::Bind(&RuntimeCustomBindings::OpenChannelToNativeApp,
-                           base::Unretained(this)));
-  RouteFunction("GetExtensionViews",
-                base::Bind(&RuntimeCustomBindings::GetExtensionViews,
-                           base::Unretained(this)));
-}
-
-RuntimeCustomBindings::~RuntimeCustomBindings() {}
-
-void RuntimeCustomBindings::OpenChannelToExtension(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  // Get the current RenderView so that we can send a routed IPC message from
-  // the correct source.
-  content::RenderView* renderview = context()->GetRenderView();
-  if (!renderview)
-    return;
-
-  // The Javascript code should validate/fill the arguments.
-  CHECK_EQ(args.Length(), 3);
-  CHECK(args[0]->IsString() && args[1]->IsString() && args[2]->IsBoolean());
-
-  ExtensionMsg_ExternalConnectionInfo info;
-
-  // For messaging APIs, hosted apps should be considered a web page so hide
-  // its extension ID.
-  const Extension* extension = context()->extension();
-  if (extension && !extension->is_hosted_app())
-    info.source_id = extension->id();
-
-  info.target_id = *v8::String::Utf8Value(args[0]->ToString());
-  info.source_url = context()->GetURL();
-  std::string channel_name = *v8::String::Utf8Value(args[1]->ToString());
-  bool include_tls_channel_id =
-      args.Length() > 2 ? args[2]->BooleanValue() : false;
-  int port_id = -1;
-  renderview->Send(new ExtensionHostMsg_OpenChannelToExtension(
-      renderview->GetRoutingID(), info, channel_name, include_tls_channel_id,
-      &port_id));
-  args.GetReturnValue().Set(static_cast<int32_t>(port_id));
-}
-
-void RuntimeCustomBindings::OpenChannelToNativeApp(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  // Verify that the extension has permission to use native messaging.
-  Feature::Availability availability =
-      FeatureProvider::GetPermissionFeatures()
-          ->GetFeature("nativeMessaging")
-          ->IsAvailableToContext(context()->extension(),
-                                 context()->context_type(),
-                                 context()->GetURL());
-  if (!availability.is_available())
-    return;
-
-  // Get the current RenderView so that we can send a routed IPC message from
-  // the correct source.
-  content::RenderView* renderview = context()->GetRenderView();
-  if (!renderview)
-    return;
-
-  // The Javascript code should validate/fill the arguments.
-  CHECK(args.Length() >= 2 &&
-        args[0]->IsString() &&
-        args[1]->IsString());
-
-  std::string extension_id = *v8::String::Utf8Value(args[0]->ToString());
-  std::string native_app_name = *v8::String::Utf8Value(args[1]->ToString());
-
-  int port_id = -1;
-  renderview->Send(new ExtensionHostMsg_OpenChannelToNativeApp(
-      renderview->GetRoutingID(),
-      extension_id,
-      native_app_name,
-      &port_id));
-  args.GetReturnValue().Set(static_cast<int32_t>(port_id));
-}
-
-void RuntimeCustomBindings::GetManifest(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  CHECK(context()->extension());
-
-  scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
-  args.GetReturnValue().Set(
-      converter->ToV8Value(context()->extension()->manifest()->value(),
-                           context()->v8_context()));
-}
-
-void RuntimeCustomBindings::GetExtensionViews(
-    const v8::FunctionCallbackInfo<v8::Value>& args) {
-  if (args.Length() != 2)
-    return;
-
-  if (!args[0]->IsInt32() || !args[1]->IsString())
-    return;
-
-  // |browser_window_id| == extension_misc::kUnknownWindowId means getting
-  // all views for the current extension.
-  int browser_window_id = args[0]->Int32Value();
-
-  std::string view_type_string = *v8::String::Utf8Value(args[1]->ToString());
-  StringToUpperASCII(&view_type_string);
-  // |view_type| == VIEW_TYPE_INVALID means getting any type of
-  // views.
-  ViewType view_type = VIEW_TYPE_INVALID;
-  if (view_type_string == kViewTypeBackgroundPage) {
-    view_type = VIEW_TYPE_EXTENSION_BACKGROUND_PAGE;
-  } else if (view_type_string == kViewTypeInfobar) {
-    view_type = VIEW_TYPE_EXTENSION_INFOBAR;
-  } else if (view_type_string == kViewTypeTabContents) {
-    view_type = VIEW_TYPE_TAB_CONTENTS;
-  } else if (view_type_string == kViewTypePopup) {
-    view_type = VIEW_TYPE_EXTENSION_POPUP;
-  } else if (view_type_string == kViewTypeExtensionDialog) {
-    view_type = VIEW_TYPE_EXTENSION_DIALOG;
-  } else if (view_type_string == kViewTypeAppWindow) {
-    view_type = VIEW_TYPE_APP_WINDOW;
-  } else if (view_type_string == kViewTypePanel) {
-    view_type = VIEW_TYPE_PANEL;
-  } else if (view_type_string != kViewTypeAll) {
-    return;
-  }
-
-  std::string extension_id = context()->GetExtensionID();
-  if (extension_id.empty())
-    return;
-
-  std::vector<content::RenderView*> views = ExtensionHelper::GetExtensionViews(
-      extension_id, browser_window_id, view_type);
-  v8::Local<v8::Array> v8_views = v8::Array::New(args.GetIsolate());
-  int v8_index = 0;
-  for (size_t i = 0; i < views.size(); ++i) {
-    v8::Local<v8::Context> context =
-        views[i]->GetWebView()->mainFrame()->mainWorldScriptContext();
-    if (!context.IsEmpty()) {
-      v8::Local<v8::Value> window = context->Global();
-      DCHECK(!window.IsEmpty());
-      v8_views->Set(v8::Integer::New(args.GetIsolate(), v8_index++), window);
-    }
-  }
-
-  args.GetReturnValue().Set(v8_views);
-}
-
-}  // namespace extensions
diff --git a/chrome/renderer/extensions/runtime_custom_bindings.h b/chrome/renderer/extensions/runtime_custom_bindings.h
deleted file mode 100644
index ce2ba03..0000000
--- a/chrome/renderer/extensions/runtime_custom_bindings.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_RENDERER_EXTENSIONS_RUNTIME_CUSTOM_BINDINGS_H_
-#define CHROME_RENDERER_EXTENSIONS_RUNTIME_CUSTOM_BINDINGS_H_
-
-#include "base/compiler_specific.h"
-#include "extensions/renderer/object_backed_native_handler.h"
-#include "v8/include/v8.h"
-
-namespace extensions {
-
-// The native component of custom bindings for the chrome.runtime API.
-class RuntimeCustomBindings : public ObjectBackedNativeHandler {
- public:
-  explicit RuntimeCustomBindings(ScriptContext* context);
-
-  virtual ~RuntimeCustomBindings();
-
-  // Creates a new messaging channel to the given extension.
-  void OpenChannelToExtension(const v8::FunctionCallbackInfo<v8::Value>& args);
-
-  // Creates a new messaging channels for the specified native application.
-  void OpenChannelToNativeApp(const v8::FunctionCallbackInfo<v8::Value>& args);
-
- private:
-  void GetManifest(const v8::FunctionCallbackInfo<v8::Value>& args);
-  void GetExtensionViews(const v8::FunctionCallbackInfo<v8::Value>& args);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_RENDERER_EXTENSIONS_RUNTIME_CUSTOM_BINDINGS_H_
diff --git a/chrome/renderer/extensions/tab_finder.cc b/chrome/renderer/extensions/tab_finder.cc
index 76623aa..6884622 100644
--- a/chrome/renderer/extensions/tab_finder.cc
+++ b/chrome/renderer/extensions/tab_finder.cc
@@ -4,8 +4,8 @@
 
 #include "chrome/renderer/extensions/tab_finder.h"
 
-#include "chrome/renderer/extensions/extension_helper.h"
 #include "content/public/renderer/render_view.h"
+#include "extensions/renderer/extension_helper.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
 #include "third_party/WebKit/public/web/WebView.h"
 
diff --git a/chrome/renderer/extensions/user_script_scheduler.cc b/chrome/renderer/extensions/user_script_scheduler.cc
deleted file mode 100644
index e36ac59..0000000
--- a/chrome/renderer/extensions/user_script_scheduler.cc
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/renderer/extensions/user_script_scheduler.h"
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "chrome/renderer/chrome_render_process_observer.h"
-#include "chrome/renderer/extensions/chrome_v8_context.h"
-#include "chrome/renderer/extensions/dispatcher.h"
-#include "chrome/renderer/extensions/extension_helper.h"
-#include "chrome/renderer/extensions/user_script_slave.h"
-#include "content/public/renderer/render_view.h"
-#include "content/public/renderer/v8_value_converter.h"
-#include "extensions/common/error_utils.h"
-#include "extensions/common/extension_messages.h"
-#include "extensions/common/manifest_constants.h"
-#include "extensions/common/permissions/permissions_data.h"
-#include "extensions/renderer/dom_activity_logger.h"
-#include "extensions/renderer/extension_groups.h"
-#include "extensions/renderer/script_context.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/platform/WebVector.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
-#include "third_party/WebKit/public/web/WebView.h"
-#include "v8/include/v8.h"
-
-namespace {
-// The length of time to wait after the DOM is complete to try and run user
-// scripts.
-const int kUserScriptIdleTimeoutMs = 200;
-}
-
-using blink::WebDocument;
-using blink::WebFrame;
-using blink::WebString;
-using blink::WebVector;
-using blink::WebView;
-
-namespace extensions {
-
-UserScriptScheduler::UserScriptScheduler(WebFrame* frame,
-                                         Dispatcher* dispatcher)
-    : weak_factory_(this),
-      frame_(frame),
-      current_location_(UserScript::UNDEFINED),
-      has_run_idle_(false),
-      dispatcher_(dispatcher) {
-  for (int i = UserScript::UNDEFINED; i < UserScript::RUN_LOCATION_LAST; ++i) {
-    pending_execution_map_[static_cast<UserScript::RunLocation>(i)] =
-      std::queue<linked_ptr<ExtensionMsg_ExecuteCode_Params> >();
-  }
-}
-
-UserScriptScheduler::~UserScriptScheduler() {
-}
-
-void UserScriptScheduler::ExecuteCode(
-    const ExtensionMsg_ExecuteCode_Params& params) {
-  UserScript::RunLocation run_at =
-    static_cast<UserScript::RunLocation>(params.run_at);
-  if (current_location_ < run_at) {
-    pending_execution_map_[run_at].push(
-        linked_ptr<ExtensionMsg_ExecuteCode_Params>(
-            new ExtensionMsg_ExecuteCode_Params(params)));
-    return;
-  }
-
-  ExecuteCodeImpl(params);
-}
-
-void UserScriptScheduler::DidCreateDocumentElement() {
-  current_location_ = UserScript::DOCUMENT_START;
-  MaybeRun();
-}
-
-void UserScriptScheduler::DidFinishDocumentLoad() {
-  current_location_ = UserScript::DOCUMENT_END;
-  MaybeRun();
-  // Schedule a run for DOCUMENT_IDLE
-  base::MessageLoop::current()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&UserScriptScheduler::IdleTimeout, weak_factory_.GetWeakPtr()),
-      base::TimeDelta::FromMilliseconds(kUserScriptIdleTimeoutMs));
-}
-
-void UserScriptScheduler::DidFinishLoad() {
-  current_location_ = UserScript::DOCUMENT_IDLE;
-  // Ensure that running scripts does not keep any progress UI running.
-  base::MessageLoop::current()->PostTask(
-      FROM_HERE,
-      base::Bind(&UserScriptScheduler::MaybeRun, weak_factory_.GetWeakPtr()));
-}
-
-void UserScriptScheduler::DidStartProvisionalLoad() {
-  // The frame is navigating, so reset the state since we'll want to inject
-  // scripts once the load finishes.
-  current_location_ = UserScript::UNDEFINED;
-  has_run_idle_ = false;
-  weak_factory_.InvalidateWeakPtrs();
-  std::map<UserScript::RunLocation, ExecutionQueue>::iterator itr =
-    pending_execution_map_.begin();
-  for (itr = pending_execution_map_.begin();
-       itr != pending_execution_map_.end(); ++itr) {
-    while (!itr->second.empty())
-      itr->second.pop();
-  }
-}
-
-void UserScriptScheduler::IdleTimeout() {
-  current_location_ = UserScript::DOCUMENT_IDLE;
-  MaybeRun();
-}
-
-void UserScriptScheduler::MaybeRun() {
-  if (current_location_ == UserScript::UNDEFINED)
-    return;
-
-  if (!has_run_idle_ && current_location_ == UserScript::DOCUMENT_IDLE) {
-    has_run_idle_ = true;
-    dispatcher_->user_script_slave()->InjectScripts(
-        frame_, UserScript::DOCUMENT_IDLE);
-  }
-
-  // Run all tasks from the current time and earlier.
-  for (int i = UserScript::DOCUMENT_START;
-       i <= current_location_; ++i) {
-    UserScript::RunLocation run_time = static_cast<UserScript::RunLocation>(i);
-    while (!pending_execution_map_[run_time].empty()) {
-      linked_ptr<ExtensionMsg_ExecuteCode_Params>& params =
-        pending_execution_map_[run_time].front();
-      ExecuteCodeImpl(*params);
-      pending_execution_map_[run_time].pop();
-    }
-  }
-}
-
-void UserScriptScheduler::ExecuteCodeImpl(
-    const ExtensionMsg_ExecuteCode_Params& params) {
-  const Extension* extension = dispatcher_->extensions()->GetByID(
-      params.extension_id);
-  content::RenderView* render_view =
-      content::RenderView::FromWebView(frame_->view());
-  ExtensionHelper* extension_helper = ExtensionHelper::Get(render_view);
-  base::ListValue execution_results;
-
-  // Since extension info is sent separately from user script info, they can
-  // be out of sync. We just ignore this situation.
-  if (!extension) {
-    render_view->Send(
-        new ExtensionHostMsg_ExecuteCodeFinished(render_view->GetRoutingID(),
-                                                 params.request_id,
-                                                 std::string(),  // no error
-                                                 -1,
-                                                 GURL(std::string()),
-                                                 execution_results));
-    return;
-  }
-
-  std::vector<WebFrame*> frame_vector;
-  frame_vector.push_back(frame_);
-  if (params.all_frames)
-    GetAllChildFrames(frame_, &frame_vector);
-
-  std::string error;
-
-  scoped_ptr<blink::WebScopedUserGesture> gesture;
-  if (params.user_gesture)
-    gesture.reset(new blink::WebScopedUserGesture);
-
-  GURL top_url = frame_->document().url();
-
-  for (std::vector<WebFrame*>::iterator frame_it = frame_vector.begin();
-       frame_it != frame_vector.end(); ++frame_it) {
-    WebFrame* child_frame = *frame_it;
-    CHECK(child_frame) << top_url;
-
-    // We recheck access here in the renderer for extra safety against races
-    // with navigation.
-    //
-    // But different frames can have different URLs, and the extension might
-    // only have access to a subset of them. For the top frame, we can
-    // immediately send an error and stop because the browser process
-    // considers that an error too.
-    //
-    // For child frames, we just skip ones the extension doesn't have access
-    // to and carry on.
-
-    bool can_execute_script =
-        PermissionsData::CanExecuteScriptOnPage(extension,
-                                                child_frame->document().url(),
-                                                top_url,
-                                                extension_helper->tab_id(),
-                                                NULL,
-                                                -1,
-                                                NULL);
-    if ((!params.is_web_view && !can_execute_script) ||
-        (params.is_web_view &&
-         child_frame->document().url() != params.webview_src)) {
-      if (child_frame->parent()) {
-        continue;
-      } else {
-        error = ErrorUtils::FormatErrorMessage(
-            manifest_errors::kCannotAccessPage,
-            child_frame->document().url().spec());
-        break;
-      }
-    }
-
-    if (params.is_javascript) {
-      WebScriptSource source(WebString::fromUTF8(params.code), params.file_url);
-      v8::HandleScope scope(v8::Isolate::GetCurrent());
-
-      scoped_ptr<content::V8ValueConverter> v8_converter(
-          content::V8ValueConverter::create());
-      v8::Local<v8::Value> script_value;
-
-      if (params.in_main_world) {
-        DOMActivityLogger::AttachToWorld(DOMActivityLogger::kMainWorldId,
-                                         extension->id());
-        script_value = child_frame->executeScriptAndReturnValue(source);
-      } else {
-        blink::WebVector<v8::Local<v8::Value> > results;
-        std::vector<WebScriptSource> sources;
-        sources.push_back(source);
-        int isolated_world_id =
-            dispatcher_->user_script_slave()->GetIsolatedWorldIdForExtension(
-                extension, child_frame);
-        DOMActivityLogger::AttachToWorld(isolated_world_id, extension->id());
-        child_frame->executeScriptInIsolatedWorld(
-            isolated_world_id, &sources.front(),
-            sources.size(), EXTENSION_GROUP_CONTENT_SCRIPTS, &results);
-        // We only expect one value back since we only pushed one source
-        if (results.size() == 1 && !results[0].IsEmpty())
-          script_value = results[0];
-      }
-
-      if (params.wants_result && !script_value.IsEmpty()) {
-        // It's safe to always use the main world context when converting here.
-        // V8ValueConverterImpl shouldn't actually care about the context scope,
-        // and it switches to v8::Object's creation context when encountered.
-        v8::Local<v8::Context> context = child_frame->mainWorldScriptContext();
-        base::Value* result = v8_converter->FromV8Value(script_value, context);
-        // Always append an execution result (i.e. no result == null result) so
-        // that |execution_results| lines up with the frames.
-        execution_results.Append(
-            result ? result : base::Value::CreateNullValue());
-      }
-    } else {
-      child_frame->document().insertStyleSheet(
-          WebString::fromUTF8(params.code));
-    }
-  }
-
-  render_view->Send(new ExtensionHostMsg_ExecuteCodeFinished(
-      render_view->GetRoutingID(),
-      params.request_id,
-      error,
-      render_view->GetPageId(),
-      ScriptContext::GetDataSourceURLForFrame(frame_),
-      execution_results));
-}
-
-bool UserScriptScheduler::GetAllChildFrames(
-    WebFrame* parent_frame,
-    std::vector<WebFrame*>* frames_vector) const {
-  if (!parent_frame)
-    return false;
-
-  for (WebFrame* child_frame = parent_frame->firstChild(); child_frame;
-       child_frame = child_frame->nextSibling()) {
-    frames_vector->push_back(child_frame);
-    GetAllChildFrames(child_frame, frames_vector);
-  }
-  return true;
-}
-
-}  // namespace extensions
diff --git a/chrome/renderer/extensions/user_script_scheduler.h b/chrome/renderer/extensions/user_script_scheduler.h
deleted file mode 100644
index 5dc24f8..0000000
--- a/chrome/renderer/extensions/user_script_scheduler.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SCHEDULER_H_
-#define CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SCHEDULER_H_
-
-#include <map>
-#include <queue>
-
-#include "base/memory/linked_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "extensions/common/user_script.h"
-
-class RenderView;
-struct ExtensionMsg_ExecuteCode_Params;
-
-namespace blink {
-class WebFrame;
-}
-
-namespace extensions {
-class Dispatcher;
-
-// Implements support for injecting scripts at different times in the document
-// loading process. The different possible time are described in
-// UserScript::RunLocation.
-//
-// Currently, determining idleness is simple: it is whichever of the following
-// happens first:
-//
-// a) When the initial DOM for a page is complete + kUserScriptIdleTimeout,
-// b) or when the page has completely loaded including all subresources.
-//
-// The intent of this mechanism is to prevent user scripts from slowing down
-// fast pages (run after load), while still allowing them to run relatively
-// timely for pages with lots of slow subresources.
-//
-// NOTE: this class does not inherit from RenderViewObserver on purpose.  The
-// reason is that this object is per frame, and a frame can move across
-// RenderViews thanks to adoptNode.  So we have each RenderView's
-// ExtensionHelper proxy these calls to the renderer process' Dispatcher,
-// which contains the mapping from WebFrame to us.
-class UserScriptScheduler {
- public:
-  UserScriptScheduler(blink::WebFrame* frame, Dispatcher* dispatcher);
-  ~UserScriptScheduler();
-
-  void ExecuteCode(const ExtensionMsg_ExecuteCode_Params& params);
-  void DidCreateDocumentElement();
-  void DidFinishDocumentLoad();
-  void DidFinishLoad();
-  void DidStartProvisionalLoad();
-
- private:
-  typedef
-    std::queue<linked_ptr<ExtensionMsg_ExecuteCode_Params> >
-    ExecutionQueue;
-
-  // Run user scripts, except if they've already run for this frame, or the
-  // frame has been destroyed.
-  void MaybeRun();
-
-  // Backend for the IPC Message ExecuteCode in addition to being used
-  // internally.
-  void ExecuteCodeImpl(const ExtensionMsg_ExecuteCode_Params& params);
-
-  // Get all child frames of parent_frame, returned by frames_vector.
-  bool GetAllChildFrames(blink::WebFrame* parent_frame,
-                         std::vector<blink::WebFrame*>* frames_vector) const;
-
-  // Call to signify thet the idle timeout has expired.
-  void IdleTimeout();
-
-  base::WeakPtrFactory<UserScriptScheduler> weak_factory_;
-
-  // The Frame we will run scripts in.
-  blink::WebFrame* frame_;
-
-  // The current location in the document loading process.
-  // Will be UserScript::UNDEFINED if it is before any scripts should be run.
-  UserScript::RunLocation current_location_;
-
-  // Whether we have already run the idle scripts.
-  bool has_run_idle_;
-
-  // This is only used if we're for the main frame.
-  std::map<UserScript::RunLocation, ExecutionQueue> pending_execution_map_;
-
-  Dispatcher* dispatcher_;
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SCHEDULER_H_
diff --git a/chrome/renderer/extensions/user_script_slave.cc b/chrome/renderer/extensions/user_script_slave.cc
deleted file mode 100644
index f4fcd40..0000000
--- a/chrome/renderer/extensions/user_script_slave.cc
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/renderer/extensions/user_script_slave.h"
-
-#include <map>
-
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/memory/shared_memory.h"
-#include "base/metrics/histogram.h"
-#include "base/pickle.h"
-#include "base/strings/stringprintf.h"
-#include "base/timer/elapsed_timer.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/renderer/isolated_world_ids.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/public/renderer/render_view.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/extension_messages.h"
-#include "extensions/common/extension_set.h"
-#include "extensions/common/manifest_handlers/csp_info.h"
-#include "extensions/common/permissions/permissions_data.h"
-#include "extensions/renderer/dom_activity_logger.h"
-#include "extensions/renderer/extension_groups.h"
-#include "extensions/renderer/extensions_renderer_client.h"
-#include "extensions/renderer/script_context.h"
-#include "grit/renderer_resources.h"
-#include "third_party/WebKit/public/platform/WebURLRequest.h"
-#include "third_party/WebKit/public/platform/WebVector.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
-#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
-#include "third_party/WebKit/public/web/WebView.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "url/gurl.h"
-
-using blink::WebFrame;
-using blink::WebSecurityOrigin;
-using blink::WebSecurityPolicy;
-using blink::WebString;
-using blink::WebVector;
-using blink::WebView;
-using content::RenderThread;
-
-namespace extensions {
-
-// These two strings are injected before and after the Greasemonkey API and
-// user script to wrap it in an anonymous scope.
-static const char kUserScriptHead[] = "(function (unsafeWindow) {\n";
-static const char kUserScriptTail[] = "\n})(window);";
-
-int UserScriptSlave::GetIsolatedWorldIdForExtension(const Extension* extension,
-                                                    WebFrame* frame) {
-  static int g_next_isolated_world_id =
-      ExtensionsRendererClient::Get()->GetLowestIsolatedWorldId();
-
-  IsolatedWorldMap::iterator iter = isolated_world_ids_.find(extension->id());
-  if (iter != isolated_world_ids_.end()) {
-    // We need to set the isolated world origin and CSP even if it's not a new
-    // world since these are stored per frame, and we might not have used this
-    // isolated world in this frame before.
-    frame->setIsolatedWorldSecurityOrigin(
-        iter->second,
-        WebSecurityOrigin::create(extension->url()));
-    frame->setIsolatedWorldContentSecurityPolicy(
-        iter->second,
-        WebString::fromUTF8(CSPInfo::GetContentSecurityPolicy(extension)));
-    return iter->second;
-  }
-
-  int new_id = g_next_isolated_world_id;
-  ++g_next_isolated_world_id;
-
-  // This map will tend to pile up over time, but realistically, you're never
-  // going to have enough extensions for it to matter.
-  isolated_world_ids_[extension->id()] = new_id;
-  frame->setIsolatedWorldSecurityOrigin(
-      new_id,
-      WebSecurityOrigin::create(extension->url()));
-  frame->setIsolatedWorldContentSecurityPolicy(
-      new_id,
-      WebString::fromUTF8(CSPInfo::GetContentSecurityPolicy(extension)));
-  return new_id;
-}
-
-std::string UserScriptSlave::GetExtensionIdForIsolatedWorld(
-    int isolated_world_id) {
-  for (IsolatedWorldMap::iterator iter = isolated_world_ids_.begin();
-       iter != isolated_world_ids_.end(); ++iter) {
-    if (iter->second == isolated_world_id)
-      return iter->first;
-  }
-  return std::string();
-}
-
-void UserScriptSlave::RemoveIsolatedWorld(const std::string& extension_id) {
-  isolated_world_ids_.erase(extension_id);
-}
-
-UserScriptSlave::UserScriptSlave(const ExtensionSet* extensions)
-    : script_deleter_(&scripts_), extensions_(extensions) {
-  api_js_ = ResourceBundle::GetSharedInstance().GetRawDataResource(
-      IDR_GREASEMONKEY_API_JS);
-}
-
-UserScriptSlave::~UserScriptSlave() {}
-
-void UserScriptSlave::GetActiveExtensions(
-    std::set<std::string>* extension_ids) {
-  for (size_t i = 0; i < scripts_.size(); ++i) {
-    DCHECK(!scripts_[i]->extension_id().empty());
-    extension_ids->insert(scripts_[i]->extension_id());
-  }
-}
-
-bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) {
-  scripts_.clear();
-
-  bool only_inject_incognito =
-      ExtensionsRendererClient::Get()->IsIncognitoProcess();
-
-  // Create the shared memory object (read only).
-  shared_memory_.reset(new base::SharedMemory(shared_memory, true));
-  if (!shared_memory_.get())
-    return false;
-
-  // First get the size of the memory block.
-  if (!shared_memory_->Map(sizeof(Pickle::Header)))
-    return false;
-  Pickle::Header* pickle_header =
-      reinterpret_cast<Pickle::Header*>(shared_memory_->memory());
-
-  // Now map in the rest of the block.
-  int pickle_size = sizeof(Pickle::Header) + pickle_header->payload_size;
-  shared_memory_->Unmap();
-  if (!shared_memory_->Map(pickle_size))
-    return false;
-
-  // Unpickle scripts.
-  uint64 num_scripts = 0;
-  Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()),
-                pickle_size);
-  PickleIterator iter(pickle);
-  CHECK(pickle.ReadUInt64(&iter, &num_scripts));
-
-  scripts_.reserve(num_scripts);
-  for (uint64 i = 0; i < num_scripts; ++i) {
-    scripts_.push_back(new UserScript());
-    UserScript* script = scripts_.back();
-    script->Unpickle(pickle, &iter);
-
-    // Note that this is a pointer into shared memory. We don't own it. It gets
-    // cleared up when the last renderer or browser process drops their
-    // reference to the shared memory.
-    for (size_t j = 0; j < script->js_scripts().size(); ++j) {
-      const char* body = NULL;
-      int body_length = 0;
-      CHECK(pickle.ReadData(&iter, &body, &body_length));
-      script->js_scripts()[j].set_external_content(
-          base::StringPiece(body, body_length));
-    }
-    for (size_t j = 0; j < script->css_scripts().size(); ++j) {
-      const char* body = NULL;
-      int body_length = 0;
-      CHECK(pickle.ReadData(&iter, &body, &body_length));
-      script->css_scripts()[j].set_external_content(
-          base::StringPiece(body, body_length));
-    }
-
-    if (only_inject_incognito && !script->is_incognito_enabled()) {
-      // This script shouldn't run in an incognito tab.
-      delete script;
-      scripts_.pop_back();
-    }
-  }
-
-  return true;
-}
-
-void UserScriptSlave::InjectScripts(WebFrame* frame,
-                                    UserScript::RunLocation location) {
-  GURL data_source_url = ScriptContext::GetDataSourceURLForFrame(frame);
-  if (data_source_url.is_empty())
-    return;
-
-  if (frame->isViewSourceModeEnabled())
-    data_source_url = GURL(content::kViewSourceScheme + std::string(":") +
-                           data_source_url.spec());
-
-  base::ElapsedTimer timer;
-  int num_css = 0;
-  int num_scripts = 0;
-
-  ExecutingScriptsMap extensions_executing_scripts;
-
-  for (size_t i = 0; i < scripts_.size(); ++i) {
-    std::vector<WebScriptSource> sources;
-    UserScript* script = scripts_[i];
-
-    if (frame->parent() && !script->match_all_frames())
-      continue;  // Only match subframes if the script declared it wanted to.
-
-    const Extension* extension = extensions_->GetByID(script->extension_id());
-
-    // Since extension info is sent separately from user script info, they can
-    // be out of sync. We just ignore this situation.
-    if (!extension)
-      continue;
-
-    // Content scripts are not tab-specific.
-    const int kNoTabId = -1;
-    // We don't have a process id in this context.
-    const int kNoProcessId = -1;
-    if (!PermissionsData::CanExecuteScriptOnPage(extension,
-                                                 data_source_url,
-                                                 frame->top()->document().url(),
-                                                 kNoTabId,
-                                                 script,
-                                                 kNoProcessId,
-                                                 NULL)) {
-      continue;
-    }
-
-    if (location == UserScript::DOCUMENT_START) {
-      num_css += script->css_scripts().size();
-      for (UserScript::FileList::const_iterator iter =
-               script->css_scripts().begin();
-           iter != script->css_scripts().end();
-           ++iter) {
-        frame->document().insertStyleSheet(
-            WebString::fromUTF8(iter->GetContent().as_string()));
-      }
-    }
-
-    if (script->run_location() == location) {
-      num_scripts += script->js_scripts().size();
-      for (size_t j = 0; j < script->js_scripts().size(); ++j) {
-        UserScript::File &file = script->js_scripts()[j];
-        std::string content = file.GetContent().as_string();
-
-        // We add this dumb function wrapper for standalone user script to
-        // emulate what Greasemonkey does.
-        // TODO(aa): I think that maybe "is_standalone" scripts don't exist
-        // anymore. Investigate.
-        if (script->is_standalone() || script->emulate_greasemonkey()) {
-          content.insert(0, kUserScriptHead);
-          content += kUserScriptTail;
-        }
-        sources.push_back(
-            WebScriptSource(WebString::fromUTF8(content), file.url()));
-      }
-    }
-
-    if (!sources.empty()) {
-      // Emulate Greasemonkey API for scripts that were converted to extensions
-      // and "standalone" user scripts.
-      if (script->is_standalone() || script->emulate_greasemonkey()) {
-        sources.insert(sources.begin(),
-            WebScriptSource(WebString::fromUTF8(api_js_.as_string())));
-      }
-
-      int isolated_world_id = GetIsolatedWorldIdForExtension(extension, frame);
-
-      base::ElapsedTimer exec_timer;
-      DOMActivityLogger::AttachToWorld(isolated_world_id, extension->id());
-      frame->executeScriptInIsolatedWorld(
-          isolated_world_id, &sources.front(), sources.size(),
-          EXTENSION_GROUP_CONTENT_SCRIPTS);
-      UMA_HISTOGRAM_TIMES("Extensions.InjectScriptTime", exec_timer.Elapsed());
-
-      for (std::vector<WebScriptSource>::const_iterator iter = sources.begin();
-           iter != sources.end(); ++iter) {
-        extensions_executing_scripts[extension->id()].insert(
-            GURL(iter->url).path());
-      }
-    }
-  }
-
-  // Notify the browser if any extensions are now executing scripts.
-  if (!extensions_executing_scripts.empty()) {
-    blink::WebFrame* top_frame = frame->top();
-    content::RenderView* render_view =
-        content::RenderView::FromWebView(top_frame->view());
-    render_view->Send(new ExtensionHostMsg_ContentScriptsExecuting(
-        render_view->GetRoutingID(),
-        extensions_executing_scripts,
-        render_view->GetPageId(),
-        ScriptContext::GetDataSourceURLForFrame(top_frame)));
-  }
-
-  // Log debug info.
-  if (location == UserScript::DOCUMENT_START) {
-    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_CssCount", num_css);
-    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_ScriptCount", num_scripts);
-    if (num_css || num_scripts)
-      UMA_HISTOGRAM_TIMES("Extensions.InjectStart_Time", timer.Elapsed());
-  } else if (location == UserScript::DOCUMENT_END) {
-    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectEnd_ScriptCount", num_scripts);
-    if (num_scripts)
-      UMA_HISTOGRAM_TIMES("Extensions.InjectEnd_Time", timer.Elapsed());
-  } else if (location == UserScript::DOCUMENT_IDLE) {
-    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectIdle_ScriptCount", num_scripts);
-    if (num_scripts)
-      UMA_HISTOGRAM_TIMES("Extensions.InjectIdle_Time", timer.Elapsed());
-  } else {
-    NOTREACHED();
-  }
-}
-
-}  // namespace extensions
diff --git a/chrome/renderer/extensions/user_script_slave.h b/chrome/renderer/extensions/user_script_slave.h
deleted file mode 100644
index 2c7211b..0000000
--- a/chrome/renderer/extensions/user_script_slave.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SLAVE_H_
-#define CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SLAVE_H_
-
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/shared_memory.h"
-#include "base/stl_util.h"
-#include "base/strings/string_piece.h"
-#include "extensions/common/user_script.h"
-#include "third_party/WebKit/public/web/WebScriptSource.h"
-
-class GURL;
-
-namespace blink {
-class WebFrame;
-}
-
-using blink::WebScriptSource;
-
-namespace extensions {
-class Extension;
-class ExtensionSet;
-
-// Manages installed UserScripts for a render process.
-class UserScriptSlave {
- public:
-  explicit UserScriptSlave(const ExtensionSet* extensions);
-  ~UserScriptSlave();
-
-  // Returns the unique set of extension IDs this UserScriptSlave knows about.
-  void GetActiveExtensions(std::set<std::string>* extension_ids);
-
-  // Update the parsed scripts from shared memory.
-  bool UpdateScripts(base::SharedMemoryHandle shared_memory);
-
-  // Inject the appropriate scripts into a frame based on its URL.
-  // TODO(aa): Extract a UserScriptFrame interface out of this to improve
-  // testability.
-  void InjectScripts(blink::WebFrame* frame, UserScript::RunLocation location);
-
-  // Gets the isolated world ID to use for the given |extension| in the given
-  // |frame|. If no isolated world has been created for that extension,
-  // one will be created and initialized.
-  int GetIsolatedWorldIdForExtension(const Extension* extension,
-                                     blink::WebFrame* frame);
-
-  // Gets the id of the extension running in a given isolated world. If no such
-  // isolated world exists, or no extension is running in it, returns empty
-  // string.
-  std::string GetExtensionIdForIsolatedWorld(int isolated_world_id);
-
-  void RemoveIsolatedWorld(const std::string& extension_id);
-
- private:
-  // Shared memory containing raw script data.
-  scoped_ptr<base::SharedMemory> shared_memory_;
-
-  // Parsed script data.
-  std::vector<UserScript*> scripts_;
-  STLElementDeleter<std::vector<UserScript*> > script_deleter_;
-
-  // Greasemonkey API source that is injected with the scripts.
-  base::StringPiece api_js_;
-
-  // Extension metadata.
-  const ExtensionSet* extensions_;
-
-  typedef std::map<std::string, int> IsolatedWorldMap;
-  IsolatedWorldMap isolated_world_ids_;
-
-  DISALLOW_COPY_AND_ASSIGN(UserScriptSlave);
-};
-
-}  // namespace extensions
-
-#endif  // CHROME_RENDERER_EXTENSIONS_USER_SCRIPT_SLAVE_H_
diff --git a/chrome/renderer/media/cast_rtp_stream.cc b/chrome/renderer/media/cast_rtp_stream.cc
index 10cf142..5557582 100644
--- a/chrome/renderer/media/cast_rtp_stream.cc
+++ b/chrome/renderer/media/cast_rtp_stream.cc
@@ -150,10 +150,12 @@
 
 bool ToAudioSenderConfig(const CastRtpParams& params,
                          AudioSenderConfig* config) {
-  config->sender_ssrc = params.payload.ssrc;
+  config->rtp_config.ssrc = params.payload.ssrc;
   config->incoming_feedback_ssrc = params.payload.feedback_ssrc;
   config->rtp_config.payload_type = params.payload.payload_type;
   config->rtp_config.max_delay_ms = params.payload.max_latency_ms;
+  config->rtp_config.aes_key = params.payload.aes_key;
+  config->rtp_config.aes_iv_mask = params.payload.aes_iv_mask;
   config->use_external_encoder = false;
   config->frequency = params.payload.clock_rate;
   config->channels = params.payload.channels;
@@ -168,10 +170,12 @@
 
 bool ToVideoSenderConfig(const CastRtpParams& params,
                          VideoSenderConfig* config) {
-  config->sender_ssrc = params.payload.ssrc;
+  config->rtp_config.ssrc = params.payload.ssrc;
   config->incoming_feedback_ssrc = params.payload.feedback_ssrc;
   config->rtp_config.payload_type = params.payload.payload_type;
   config->rtp_config.max_delay_ms = params.payload.max_latency_ms;
+  config->rtp_config.aes_key = params.payload.aes_key;
+  config->rtp_config.aes_iv_mask = params.payload.aes_iv_mask;
   config->use_external_encoder = false;
   config->width = params.payload.width;
   config->height = params.payload.height;
@@ -226,24 +230,15 @@
       return;
     }
 
-    // Capture time is calculated using the time when the first frame
-    // is delivered. Doing so has less jitter because each frame has
-    // a TimeDelta from the first frame. However there is a delay between
-    // capture and delivery here for the first frame. We do not account
-    // for this delay.
-    if (first_frame_timestamp_.is_null())
-      first_frame_timestamp_ = base::TimeTicks::Now() - frame->timestamp();
+    const base::TimeTicks now = base::TimeTicks::Now();
 
     // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc
     TRACE_EVENT_INSTANT2(
         "mirroring", "MediaStreamVideoSink::OnVideoFrame",
         TRACE_EVENT_SCOPE_THREAD,
-        "timestamp",
-        (first_frame_timestamp_ + frame->timestamp()).ToInternalValue(),
+        "timestamp",  now.ToInternalValue(),
         "time_delta", frame->timestamp().ToInternalValue());
-
-    frame_input_->InsertRawVideoFrame(
-        frame, first_frame_timestamp_ + frame->timestamp());
+    frame_input_->InsertRawVideoFrame(frame, now);
   }
 
   // Attach this sink to a video track represented by |track_|.
@@ -263,7 +258,6 @@
   bool sink_added_;
   gfx::Size expected_coded_size_;
   CastRtpStream::ErrorCallback error_callback_;
-  base::TimeTicks first_frame_timestamp_;
 
   DISALLOW_COPY_AND_ASSIGN(CastVideoSink);
 };
diff --git a/chrome/renderer/media/cast_session_delegate.cc b/chrome/renderer/media/cast_session_delegate.cc
index 35aa7ca..9514e13 100644
--- a/chrome/renderer/media/cast_session_delegate.cc
+++ b/chrome/renderer/media/cast_session_delegate.cc
@@ -15,6 +15,7 @@
 #include "media/cast/cast_sender.h"
 #include "media/cast/logging/log_serializer.h"
 #include "media/cast/logging/logging_defines.h"
+#include "media/cast/logging/proto/raw_events.pb.h"
 #include "media/cast/logging/raw_event_subscriber_bundle.h"
 #include "media/cast/transport/cast_transport_config.h"
 #include "media/cast/transport/cast_transport_sender.h"
@@ -50,13 +51,6 @@
   }
 
   audio_frame_input_available_callback_ = callback;
-  media::cast::transport::CastTransportAudioConfig transport_config;
-  transport_config.base.ssrc = config.sender_ssrc;
-  transport_config.codec = config.codec;
-  transport_config.base.rtp_config = config.rtp_config;
-  transport_config.frequency = config.frequency;
-  transport_config.channels = config.channels;
-  cast_transport_->InitializeAudio(transport_config);
   cast_sender_->InitializeAudio(
       config,
       base::Bind(&CastSessionDelegate::InitializationResultCB,
@@ -79,11 +73,6 @@
 
   video_frame_input_available_callback_ = callback;
 
-  media::cast::transport::CastTransportVideoConfig transport_config;
-  transport_config.base.ssrc = config.sender_ssrc;
-  transport_config.codec = config.codec;
-  transport_config.base.rtp_config = config.rtp_config;
-  cast_transport_->InitializeVideo(transport_config);
   cast_sender_->InitializeVideo(
       config,
       base::Bind(&CastSessionDelegate::InitializationResultCB,
diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc
index 71937fd..818d401 100644
--- a/chrome/renderer/media/chrome_key_systems.cc
+++ b/chrome/renderer/media/chrome_key_systems.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/common/render_messages.h"
+#include "components/cdm/renderer/widevine_key_systems.h"
 #include "content/public/renderer/render_thread.h"
 
 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
@@ -23,10 +24,6 @@
 #include "base/version.h"
 #endif
 
-#if defined(OS_ANDROID)
-#include "chrome/common/encrypted_media_messages_android.h"
-#endif
-
 using content::KeySystemInfo;
 using content::SupportedCodecs;
 
@@ -99,76 +96,12 @@
   info.key_system = kExternalClearKeyCrashKeySystem;
   concrete_key_systems->push_back(info);
 }
-#endif  // defined(ENABLE_PEPPER_CDMS)
-
 
 #if defined(WIDEVINE_CDM_AVAILABLE)
-enum WidevineCdmType {
-  WIDEVINE,
-  WIDEVINE_HR,
-#if defined(OS_ANDROID)
-  WIDEVINE_HR_NON_COMPOSITING,
-#endif
-};
-
-#if !defined(OS_ANDROID)
-static bool IsWidevineHrSupported() {
-  // TODO(jrummell): Need to call CheckPlatformState() but it is
-  // asynchronous, and needs to be done in the browser.
-  return false;
-}
-#endif
-
-// Return |name|'s parent key system.
-static std::string GetDirectParentName(std::string name) {
-  int last_period = name.find_last_of('.');
-  DCHECK_GT(last_period, 0);
-  return name.substr(0, last_period);
-}
-
-static void AddWidevineWithCodecs(
-    WidevineCdmType widevine_cdm_type,
-    SupportedCodecs supported_codecs,
-    std::vector<KeySystemInfo>* concrete_key_systems) {
-  KeySystemInfo info(kWidevineKeySystem);
-
-  switch (widevine_cdm_type) {
-    case WIDEVINE:
-      // For standard Widevine, add parent name.
-      info.parent_key_system = GetDirectParentName(kWidevineKeySystem);
-      break;
-    case WIDEVINE_HR:
-      info.key_system.append(".hr");
-      break;
-#if defined(OS_ANDROID)
-    case WIDEVINE_HR_NON_COMPOSITING:
-      info.key_system.append(".hrnoncompositing");
-      break;
-#endif
-    default:
-      NOTREACHED();
-  }
-
-  // TODO(xhwang): A container or an initDataType may be supported even though
-  // there are no codecs supported in that container. Fix this when we support
-  // initDataType.
-  info.supported_codecs = supported_codecs;
-
-#if defined(ENABLE_PEPPER_CDMS)
-  info.pepper_type = kWidevineCdmPluginMimeType;
-#endif  // defined(ENABLE_PEPPER_CDMS)
-
-  concrete_key_systems->push_back(info);
-}
-
-#if defined(ENABLE_PEPPER_CDMS)
-// When the adapter is registered, a name-value pair is inserted in
-// additional_param_* that lists the supported codecs. The name is "codecs" and
-// the value is a comma-delimited list of codecs.
 // This function finds "codecs" and parses the value into the vector |codecs|.
 // Converts the codec strings to UTF-8 since we only expect ASCII strings and
 // this simplifies the rest of the code in this file.
-void GetSupportedCodecs(
+void GetSupportedCodecsForPepperCdm(
     const std::vector<base::string16>& additional_param_names,
     const std::vector<base::string16>& additional_param_values,
     std::vector<std::string>* codecs) {
@@ -212,7 +145,9 @@
   }
 
   std::vector<std::string> codecs;
-  GetSupportedCodecs(additional_param_names, additional_param_values, &codecs);
+  GetSupportedCodecsForPepperCdm(additional_param_names,
+                                 additional_param_values,
+                                 &codecs);
 
   SupportedCodecs supported_codecs = content::EME_CODEC_NONE;
   for (size_t i = 0; i < codecs.size(); ++i) {
@@ -230,52 +165,23 @@
 #endif  // defined(USE_PROPRIETARY_CODECS)
   }
 
-  AddWidevineWithCodecs(WIDEVINE, supported_codecs, concrete_key_systems);
-
-  if (IsWidevineHrSupported())
-    AddWidevineWithCodecs(WIDEVINE_HR, supported_codecs, concrete_key_systems);
+  cdm::AddWidevineWithCodecs(cdm::WIDEVINE,
+                             supported_codecs,
+                             concrete_key_systems);
 }
-#elif defined(OS_ANDROID)
-static void AddAndroidWidevine(
-    std::vector<KeySystemInfo>* concrete_key_systems) {
-  SupportedKeySystemRequest request;
-  SupportedKeySystemResponse response;
-
-  request.key_system = kWidevineKeySystem;
-  request.codecs = content::EME_CODEC_WEBM_ALL | content::EME_CODEC_MP4_ALL;
-  content::RenderThread::Get()->Send(
-      new ChromeViewHostMsg_GetSupportedKeySystems(request, &response));
-  DCHECK(response.compositing_codecs & content::EME_CODEC_ALL)
-      << "unrecognized codec";
-  DCHECK(response.non_compositing_codecs & content::EME_CODEC_ALL)
-      << "unrecognized codec";
-  if (response.compositing_codecs != content::EME_CODEC_NONE) {
-    AddWidevineWithCodecs(
-        WIDEVINE,
-        static_cast<SupportedCodecs>(response.compositing_codecs),
-        concrete_key_systems);
-  }
-
-  if (response.non_compositing_codecs != content::EME_CODEC_NONE) {
-    AddWidevineWithCodecs(
-        WIDEVINE_HR_NON_COMPOSITING,
-        static_cast<SupportedCodecs>(response.non_compositing_codecs),
-        concrete_key_systems);
-  }
-}
-#endif  // defined(ENABLE_PEPPER_CDMS)
 #endif  // defined(WIDEVINE_CDM_AVAILABLE)
+#endif  // defined(ENABLE_PEPPER_CDMS)
 
 void AddChromeKeySystems(std::vector<KeySystemInfo>* key_systems_info) {
 #if defined(ENABLE_PEPPER_CDMS)
   AddExternalClearKey(key_systems_info);
-#endif
 
 #if defined(WIDEVINE_CDM_AVAILABLE)
-#if defined(ENABLE_PEPPER_CDMS)
   AddPepperBasedWidevine(key_systems_info);
-#elif defined(OS_ANDROID)
-  AddAndroidWidevine(key_systems_info);
-#endif
-#endif
+#endif  // defined(WIDEVINE_CDM_AVAILABLE)
+#endif  // defined(ENABLE_PEPPER_CDMS)
+
+#if defined(OS_ANDROID)
+  cdm::AddAndroidWidevine(key_systems_info);
+#endif  // defined(OS_ANDROID)
 }
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc
index 5ef563f..0235dee 100644
--- a/chrome/renderer/net/net_error_helper.cc
+++ b/chrome/renderer/net/net_error_helper.cc
@@ -20,6 +20,7 @@
 #include "content/public/common/content_client.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/renderer/content_renderer_client.h"
+#include "content/public/renderer/document_state.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/render_view.h"
@@ -42,6 +43,7 @@
 using base::JSONWriter;
 using chrome_common_net::DnsProbeStatus;
 using chrome_common_net::DnsProbeStatusToString;
+using content::DocumentState;
 using content::RenderFrame;
 using content::RenderFrameObserver;
 using content::RenderThread;
@@ -156,6 +158,10 @@
   return core_.ShouldSuppressErrorPage(GetFrameType(frame), url);
 }
 
+void NetErrorHelper::TrackClick(int tracking_id) {
+  core_.TrackClick(tracking_id);
+}
+
 void NetErrorHelper::GenerateLocalizedErrorPage(
     const blink::WebURLError& error,
     bool is_failed_post,
@@ -171,10 +177,15 @@
   if (template_html.empty()) {
     NOTREACHED() << "unable to load template.";
   } else {
+    CommandLine* command_line = CommandLine::ForCurrentProcess();
+    bool load_stale_cache_enabled =
+        command_line->HasSwitch(switches::kEnableOfflineLoadStaleCache);
+
     base::DictionaryValue error_strings;
     LocalizedError::GetStrings(error.reason, error.domain.utf8(),
                                error.unreachableURL, is_failed_post,
-                               error.staleCopyInCache && !is_failed_post,
+                               (load_stale_cache_enabled &&
+                                error.staleCopyInCache && !is_failed_post),
                                RenderThread::Get()->GetLocale(),
                                render_frame()->GetRenderView()->
                                    GetAcceptLanguages(),
@@ -202,12 +213,17 @@
 
 void NetErrorHelper::UpdateErrorPage(const blink::WebURLError& error,
                                      bool is_failed_post) {
+    CommandLine* command_line = CommandLine::ForCurrentProcess();
+    bool load_stale_cache_enabled =
+        command_line->HasSwitch(switches::kEnableOfflineLoadStaleCache);
+
   base::DictionaryValue error_strings;
   LocalizedError::GetStrings(error.reason,
                              error.domain.utf8(),
                              error.unreachableURL,
                              is_failed_post,
-                             error.staleCopyInCache && !is_failed_post,
+                             (load_stale_cache_enabled &&
+                              error.staleCopyInCache && !is_failed_post),
                              RenderThread::Get()->GetLocale(),
                              render_frame()->GetRenderView()->
                                  GetAcceptLanguages(),
@@ -256,6 +272,25 @@
   correction_fetcher_.reset();
 }
 
+void NetErrorHelper::SendTrackingRequest(
+    const GURL& tracking_url,
+    const std::string& tracking_request_body) {
+  blink::WebView* web_view = render_frame()->GetRenderView()->GetWebView();
+  if (!web_view)
+    return;
+  blink::WebFrame* frame = web_view->mainFrame();
+
+  // If there's already a pending tracking request, this will cancel it.
+  tracking_fetcher_.reset(content::ResourceFetcher::Create(tracking_url));
+  tracking_fetcher_->SetMethod("POST");
+  tracking_fetcher_->SetBody(tracking_request_body);
+  tracking_fetcher_->SetHeader("Content-Type", "application/json");
+  tracking_fetcher_->Start(
+      frame, blink::WebURLRequest::TargetIsMainFrame,
+      base::Bind(&NetErrorHelper::OnTrackingRequestComplete,
+                 base::Unretained(this)));
+}
+
 void NetErrorHelper::ReloadPage() {
   render_frame()->GetWebFrame()->reload(false);
 }
@@ -305,3 +340,9 @@
         LocaleIsRTL());
   }
 }
+
+void NetErrorHelper::OnTrackingRequestComplete(
+    const blink::WebURLResponse& response,
+    const std::string& data) {
+  tracking_fetcher_.reset();
+}
diff --git a/chrome/renderer/net/net_error_helper.h b/chrome/renderer/net/net_error_helper.h
index 173146f..de2aef6 100644
--- a/chrome/renderer/net/net_error_helper.h
+++ b/chrome/renderer/net/net_error_helper.h
@@ -18,16 +18,16 @@
 
 class GURL;
 
-namespace content {
-class ResourceFetcher;
-}
-
 namespace blink {
 class WebFrame;
 class WebURLResponse;
 struct WebURLError;
 }
 
+namespace content {
+class ResourceFetcher;
+}
+
 // Listens for NetErrorInfo messages from the NetErrorTabHelper on the
 // browser side and updates the error page with more details (currently, just
 // DNS probe results) if/when available.
@@ -74,6 +74,9 @@
   // suppressed.
   bool ShouldSuppressErrorPage(blink::WebFrame* frame, const GURL& url);
 
+  // Called when a link with the given tracking ID is pressed.
+  void TrackClick(int tracking_id);
+
  private:
   // NetErrorHelperCore::Delegate implementation:
   virtual void GenerateLocalizedErrorPage(
@@ -92,6 +95,9 @@
       const GURL& navigation_correction_url,
       const std::string& navigation_correction_request_body) OVERRIDE;
   virtual void CancelFetchNavigationCorrections() OVERRIDE;
+  virtual void SendTrackingRequest(
+      const GURL& tracking_url,
+      const std::string& tracking_request_body) OVERRIDE;
   virtual void ReloadPage() OVERRIDE;
   virtual void LoadPageFromCache(const GURL& page_url) OVERRIDE;
 
@@ -105,7 +111,11 @@
   void OnNavigationCorrectionsFetched(const blink::WebURLResponse& response,
                                       const std::string& data);
 
+  void OnTrackingRequestComplete(const blink::WebURLResponse& response,
+                                 const std::string& data);
+
   scoped_ptr<content::ResourceFetcher> correction_fetcher_;
+  scoped_ptr<content::ResourceFetcher> tracking_fetcher_;
 
   NetErrorHelperCore core_;
 
diff --git a/chrome/renderer/net/net_error_helper_core.cc b/chrome/renderer/net/net_error_helper_core.cc
index cd681a5..b169d49 100644
--- a/chrome/renderer/net/net_error_helper_core.cc
+++ b/chrome/renderer/net/net_error_helper_core.cc
@@ -4,17 +4,22 @@
 
 #include "chrome/renderer/net/net_error_helper_core.h"
 
+#include <set>
 #include <string>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/i18n/rtl.h"
 #include "base/json/json_reader.h"
+#include "base/json/json_value_converter.h"
 #include "base/json/json_writer.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/memory/scoped_vector.h"
 #include "base/metrics/histogram.h"
 #include "base/strings/string16.h"
+#include "base/strings/string_util.h"
 #include "base/values.h"
 #include "chrome/common/localized_error.h"
 #include "grit/generated_resources.h"
@@ -49,6 +54,50 @@
   {IDS_ERRORPAGES_SUGGESTION_CORRECTED_URL, "emphasizedUrlCorrection"},
 };
 
+struct NavigationCorrection {
+  NavigationCorrection() : is_porn(false), is_soft_porn(false) {
+  }
+
+  static void RegisterJSONConverter(
+      base::JSONValueConverter<NavigationCorrection>* converter) {
+    converter->RegisterStringField("correctionType",
+                                   &NavigationCorrection::correction_type);
+    converter->RegisterStringField("urlCorrection",
+                                   &NavigationCorrection::url_correction);
+    converter->RegisterStringField("clickType",
+                                   &NavigationCorrection::click_type);
+    converter->RegisterStringField("clickData",
+                                   &NavigationCorrection::click_data);
+    converter->RegisterBoolField("isPorn", &NavigationCorrection::is_porn);
+    converter->RegisterBoolField("isSoftPorn",
+                                 &NavigationCorrection::is_soft_porn);
+  }
+
+  std::string correction_type;
+  std::string url_correction;
+  std::string click_type;
+  std::string click_data;
+  bool is_porn;
+  bool is_soft_porn;
+};
+
+struct NavigationCorrectionResponse {
+  std::string event_id;
+  std::string fingerprint;
+  ScopedVector<NavigationCorrection> corrections;
+
+  static void RegisterJSONConverter(
+      base::JSONValueConverter<NavigationCorrectionResponse>* converter) {
+    converter->RegisterStringField("result.eventId",
+                                   &NavigationCorrectionResponse::event_id);
+    converter->RegisterStringField("result.fingerprint",
+                                   &NavigationCorrectionResponse::fingerprint);
+    converter->RegisterRepeatedMessage(
+        "result.UrlCorrections",
+        &NavigationCorrectionResponse::corrections);
+  }
+};
+
 base::TimeDelta GetAutoReloadTime(size_t reload_count) {
   static const int kDelaysMs[] = {
     0, 5000, 30000, 60000, 300000, 600000, 1800000
@@ -75,70 +124,122 @@
   return url.ReplaceComponents(remove_params);
 }
 
-// If URL correction information should be retrieved remotely for a main frame
-// load that failed with |error|, returns true and sets
-// |correction_request_body| to be the body for the correction request.
-bool GetFixUrlRequestBody(const blink::WebURLError& error,
-                          const std::string& language,
-                          const std::string& country_code,
-                          const std::string& api_key,
-                          std::string* correction_request_body) {
-  // Parameter to send to the correction service indicating the error type.
-  std::string error_param;
-
-  std::string domain = error.domain.utf8();
-  if (domain == "http" && error.reason == 404) {
-    error_param = "http404";
-  } else if (IsDnsError(error)) {
-    error_param = "dnserror";
-  } else if (domain == net::kErrorDomain &&
-             (error.reason == net::ERR_CONNECTION_FAILED ||
-              error.reason == net::ERR_CONNECTION_REFUSED ||
-              error.reason == net::ERR_ADDRESS_UNREACHABLE ||
-              error.reason == net::ERR_CONNECTION_TIMED_OUT)) {
-    error_param = "connectionFailure";
-  } else {
-    return false;
-  }
-
-  // Don't use the correction service for HTTPS (for privacy reasons).
-  GURL unreachable_url(error.unreachableURL);
-  if (unreachable_url.SchemeIsSecure())
-    return false;
-
+// Sanitizes and formats a URL for upload to the error correction service.
+std::string PrepareUrlForUpload(const GURL& url) {
   // TODO(yuusuke): Change to net::FormatUrl when Link Doctor becomes
   // unicode-capable.
-  std::string spec_to_send = SanitizeURL(unreachable_url).spec();
+  std::string spec_to_send = SanitizeURL(url).spec();
 
   // Notify navigation correction service of the url truncation by sending of
   // "?" at the end.
-  if (unreachable_url.has_query())
+  if (url.has_query())
     spec_to_send.append("?");
+  return spec_to_send;
+}
 
-  // Assemble request body, which is a JSON string.
-  // TODO(mmenke):  Investigate open sourcing the relevant protocol buffers and
-  //                using those directly instead.
+// Given a WebURLError, returns true if the FixURL service should be used
+// for that error.  Also sets |error_param| to the string that should be sent to
+// the FixURL service to identify the error type.
+bool ShouldUseFixUrlServiceForError(const blink::WebURLError& error,
+                                    std::string* error_param) {
+  error_param->clear();
 
-  base::DictionaryValue request_dict;
-  request_dict.SetString("method", "linkdoctor.fixurl.fixurl");
-  request_dict.SetString("apiVersion", "v1");
+  // Don't use the correction service for HTTPS (for privacy reasons).
+  GURL unreachable_url(error.unreachableURL);
+  if (GURL(unreachable_url).SchemeIsSecure())
+    return false;
 
-  base::DictionaryValue* params_dict = new base::DictionaryValue();
-  request_dict.Set("params", params_dict);
+  std::string domain = error.domain.utf8();
+  if (domain == "http" && error.reason == 404) {
+    *error_param = "http404";
+    return true;
+  }
+  if (IsDnsError(error)) {
+    *error_param = "dnserror";
+    return true;
+  }
+  if (domain == net::kErrorDomain &&
+      (error.reason == net::ERR_CONNECTION_FAILED ||
+       error.reason == net::ERR_CONNECTION_REFUSED ||
+       error.reason == net::ERR_ADDRESS_UNREACHABLE ||
+       error.reason == net::ERR_CONNECTION_TIMED_OUT)) {
+    *error_param = "connectionFailure";
+    return true;
+  }
+  return false;
+}
 
-  params_dict->SetString("key", api_key);
-  params_dict->SetString("urlQuery", spec_to_send);
+// Creates a request body for use with the fixurl service.  Sets parameters
+// shared by all types of requests to the service.  |correction_params| must
+// contain the parameters specific to the actual request type.
+std::string CreateRequestBody(
+    const std::string& method,
+    const std::string& error_param,
+    const NetErrorHelperCore::NavigationCorrectionParams& correction_params,
+    scoped_ptr<base::DictionaryValue> params_dict) {
+  // Set params common to all request types.
+  params_dict->SetString("key", correction_params.api_key);
   params_dict->SetString("clientName", "chrome");
   params_dict->SetString("error", error_param);
 
-  if (!language.empty())
-    params_dict->SetString("language", language);
+  if (!correction_params.language.empty())
+    params_dict->SetString("language", correction_params.language);
 
-  if (!country_code.empty())
-    params_dict->SetString("originCountry", country_code);
+  if (!correction_params.country_code.empty())
+    params_dict->SetString("originCountry", correction_params.country_code);
 
-  base::JSONWriter::Write(&request_dict, correction_request_body);
-  return true;
+  base::DictionaryValue request_dict;
+  request_dict.SetString("method", method);
+  request_dict.SetString("apiVersion", "v1");
+  request_dict.Set("params", params_dict.release());
+
+  std::string request_body;
+  bool success = base::JSONWriter::Write(&request_dict, &request_body);
+  DCHECK(success);
+  return request_body;
+}
+
+// If URL correction information should be retrieved remotely for a main frame
+// load that failed with |error|, returns true and sets
+// |correction_request_body| to be the body for the correction request.
+std::string CreateFixUrlRequestBody(
+    const blink::WebURLError& error,
+    const NetErrorHelperCore::NavigationCorrectionParams& correction_params) {
+  std::string error_param;
+  bool result = ShouldUseFixUrlServiceForError(error, &error_param);
+  DCHECK(result);
+
+  // TODO(mmenke):  Investigate open sourcing the relevant protocol buffers and
+  //                using those directly instead.
+  scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
+  params->SetString("urlQuery", PrepareUrlForUpload(error.unreachableURL));
+  return CreateRequestBody("linkdoctor.fixurl.fixurl", error_param,
+                           correction_params, params.Pass());
+}
+
+std::string CreateClickTrackingUrlRequestBody(
+    const blink::WebURLError& error,
+    const NetErrorHelperCore::NavigationCorrectionParams& correction_params,
+    const NavigationCorrectionResponse& response,
+    const NavigationCorrection& correction) {
+  std::string error_param;
+  bool result = ShouldUseFixUrlServiceForError(error, &error_param);
+  DCHECK(result);
+
+  scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
+
+  params->SetString("originalUrlQuery",
+                    PrepareUrlForUpload(error.unreachableURL));
+
+  params->SetString("clickedUrlCorrection", correction.url_correction);
+  params->SetString("clickType", correction.click_type);
+  params->SetString("clickData", correction.click_data);
+
+  params->SetString("eventId", response.event_id);
+  params->SetString("fingerprint", response.fingerprint);
+
+  return CreateRequestBody("linkdoctor.fixurl.clicktracking", error_param,
+                           correction_params, params.Pass());
 }
 
 base::string16 FormatURLForDisplay(const GURL& url, bool is_rtl,
@@ -153,74 +254,68 @@
   return url_for_display;
 }
 
-LocalizedError::ErrorPageParams* ParseAdditionalSuggestions(
-    const std::string& data,
-    const GURL& original_url,
-    const GURL& search_url,
+scoped_ptr<NavigationCorrectionResponse> ParseNavigationCorrectionResponse(
+    const std::string raw_response) {
+  // TODO(mmenke):  Open source related protocol buffers and use them directly.
+  scoped_ptr<base::Value> parsed(base::JSONReader::Read(raw_response));
+  scoped_ptr<NavigationCorrectionResponse> response(
+      new NavigationCorrectionResponse());
+  base::JSONValueConverter<NavigationCorrectionResponse> converter;
+  if (!parsed || !converter.Convert(*parsed, response.get()))
+    response.reset();
+  return response.Pass();
+}
+
+scoped_ptr<LocalizedError::ErrorPageParams> CreateErrorPageParams(
+    const NavigationCorrectionResponse& response,
+    const blink::WebURLError& error,
+    const NetErrorHelperCore::NavigationCorrectionParams& correction_params,
     const std::string& accept_languages,
     bool is_rtl) {
-  scoped_ptr<base::Value> parsed(base::JSONReader::Read(data));
-  if (!parsed)
-    return NULL;
-  // TODO(mmenke):  Open source related protocol buffers and use them directly.
-  base::DictionaryValue* parsed_dict;
-  base::ListValue* corrections;
-  if (!parsed->GetAsDictionary(&parsed_dict))
-    return NULL;
-  if (!parsed_dict->GetList("result.UrlCorrections", &corrections))
-    return NULL;
-
   // Version of URL for display in suggestions.  It has to be sanitized first
   // because any received suggestions will be relative to the sanitized URL.
   base::string16 original_url_for_display =
-      FormatURLForDisplay(SanitizeURL(original_url), is_rtl, accept_languages);
+      FormatURLForDisplay(SanitizeURL(GURL(error.unreachableURL)), is_rtl,
+                          accept_languages);
 
   scoped_ptr<LocalizedError::ErrorPageParams> params(
       new LocalizedError::ErrorPageParams());
   params->override_suggestions.reset(new base::ListValue());
   scoped_ptr<base::ListValue> parsed_corrections(new base::ListValue());
-  for (base::ListValue::iterator it = corrections->begin();
-       it != corrections->end(); ++it) {
-    base::DictionaryValue* correction;
-    if (!(*it)->GetAsDictionary(&correction))
-      continue;
-
+  for (ScopedVector<NavigationCorrection>::const_iterator it =
+           response.corrections.begin();
+       it != response.corrections.end(); ++it) {
     // Doesn't seem like a good idea to show these.
-    bool is_porn;
-    if (correction->GetBoolean("isPorn", &is_porn) && is_porn)
-      continue;
-    if (correction->GetBoolean("isSoftPorn", &is_porn) && is_porn)
+    if ((*it)->is_porn || (*it)->is_soft_porn)
       continue;
 
-    std::string correction_type;
-    std::string url_correction;
-    if (!correction->GetString("correctionType", &correction_type) ||
-        !correction->GetString("urlCorrection", &url_correction)) {
-      continue;
-    }
+    int tracking_id = it - response.corrections.begin();
 
-    std::string click_tracking_url;
-    correction->GetString("clickTrackingUrl", &click_tracking_url);
-
-    if (correction_type == "reloadPage") {
+    if ((*it)->correction_type == "reloadPage") {
       params->suggest_reload = true;
+      params->reload_tracking_id = tracking_id;
       continue;
     }
 
-    if (correction_type == "webSearchQuery") {
+    if ((*it)->correction_type == "webSearchQuery") {
       // If there are mutliple searches suggested, use the first suggestion.
       if (params->search_terms.empty()) {
-        params->search_url = search_url;
-        params->search_terms = url_correction;
+        params->search_url = correction_params.search_url;
+        params->search_terms = (*it)->url_correction;
+        params->search_tracking_id = tracking_id;
       }
       continue;
     }
 
+    // Allow reload page and web search query to be empty strings, but not
+    // links.
+    if ((*it)->url_correction.empty())
+      continue;
     size_t correction_index;
     for (correction_index = 0;
          correction_index < arraysize(kCorrectionResourceTable);
          ++correction_index) {
-      if (correction_type !=
+      if ((*it)->correction_type !=
               kCorrectionResourceTable[correction_index].correction_type) {
         continue;
       }
@@ -228,23 +323,21 @@
       suggest->SetString("header",
           l10n_util::GetStringUTF16(
               kCorrectionResourceTable[correction_index].resource_id));
-      suggest->SetString("urlCorrection",
-          !click_tracking_url.empty() ? click_tracking_url :
-                                        url_correction);
+      suggest->SetString("urlCorrection", (*it)->url_correction);
       suggest->SetString(
           "urlCorrectionForDisplay",
-          FormatURLForDisplay(GURL(url_correction), is_rtl, accept_languages));
+          FormatURLForDisplay(GURL((*it)->url_correction), is_rtl,
+                              accept_languages));
       suggest->SetString("originalUrlForDisplay", original_url_for_display);
+      suggest->SetInteger("trackingId", tracking_id);
       params->override_suggestions->Append(suggest);
       break;
     }
   }
 
-  if (params->override_suggestions->empty() &&
-      !params->search_url.is_valid()) {
-    return NULL;
-  }
-  return params.release();
+  if (params->override_suggestions->empty() && !params->search_url.is_valid())
+    params.reset();
+  return params.Pass();
 }
 
 }  // namespace
@@ -254,6 +347,7 @@
       : error(error),
         was_failed_post(was_failed_post),
         needs_dns_updates(false),
+        needs_load_navigation_corrections(false),
         reload_button_in_page(false),
         load_stale_button_in_page(false),
         is_finished_loading(false) {
@@ -269,17 +363,21 @@
   // probe status.
   bool needs_dns_updates;
 
-  // Navigation correction service url, which will be used in response to
-  // certain types of network errors.  This is also stored by the
-  // NetErrorHelperCore itself, but it stored here as well in case its modified
-  // in the middle of an error page load.  Empty when no error page should be
-  // fetched, or if there's already a fetch in progress.
-  GURL navigation_correction_url;
+  // True if a blank page was loaded, and navigation corrections need to be
+  // loaded to generate the real error page.
+  bool needs_load_navigation_corrections;
 
-  // Request body to use when requesting corrections from a web service.
-  // TODO(mmenke):  Investigate loading the error page at the same time as
-  //                the blank page is loading, to get rid of these.
-  std::string navigation_correction_request_body;
+  // Navigation correction service paramers, which will be used in response to
+  // certain types of network errors.  They are all stored here in case they
+  // change over the course of displaying the error page.
+  scoped_ptr<NetErrorHelperCore::NavigationCorrectionParams>
+      navigation_correction_params;
+
+  scoped_ptr<NavigationCorrectionResponse> navigation_correction_response;
+
+  // All the navigation corrections that have been clicked, for tracking
+  // purposes.
+  std::set<int> clicked_corrections;
 
   // Track if specific buttons are included in an error page, for statistics.
   bool reload_button_in_page;
@@ -290,6 +388,12 @@
   bool is_finished_loading;
 };
 
+NetErrorHelperCore::NavigationCorrectionParams::NavigationCorrectionParams() {
+}
+
+NetErrorHelperCore::NavigationCorrectionParams::~NavigationCorrectionParams() {
+}
+
 bool NetErrorHelperCore::IsReloadableError(
     const NetErrorHelperCore::ErrorPageInfo& info) {
   return info.error.domain.utf8() == net::kErrorDomain &&
@@ -328,14 +432,10 @@
                                      net::GetAllErrorCodesForUma());
     UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtStop", auto_reload_count_);
   }
-  if (committed_error_page_info_) {
-    committed_error_page_info_->navigation_correction_url = GURL();
-    committed_error_page_info_->navigation_correction_request_body.clear();
-  }
-  if (pending_error_page_info_) {
-    pending_error_page_info_->navigation_correction_url = GURL();
-    pending_error_page_info_->navigation_correction_request_body.clear();
-  }
+  if (committed_error_page_info_)
+    committed_error_page_info_->needs_load_navigation_corrections = false;
+  if (pending_error_page_info_)
+    pending_error_page_info_->needs_load_navigation_corrections = false;
   delegate_->CancelFetchNavigationCorrections();
   auto_reload_timer_->Stop();
   can_auto_reload_page_ = false;
@@ -422,14 +522,16 @@
 
   delegate_->EnablePageHelperFunctions();
 
-  if (committed_error_page_info_->navigation_correction_url.is_valid()) {
+  if (committed_error_page_info_->needs_load_navigation_corrections) {
     // If there is another pending error page load, |fix_url| should have been
     // cleared.
     DCHECK(!pending_error_page_info_);
     DCHECK(!committed_error_page_info_->needs_dns_updates);
     delegate_->FetchNavigationCorrections(
-        committed_error_page_info_->navigation_correction_url,
-        committed_error_page_info_->navigation_correction_request_body);
+        committed_error_page_info_->navigation_correction_params->url,
+        CreateFixUrlRequestBody(
+            committed_error_page_info_->error,
+            *committed_error_page_info_->navigation_correction_params));
   } else if (auto_reload_enabled_ &&
              IsReloadableError(*committed_error_page_info_)) {
     MaybeStartAutoReloadTimer();
@@ -452,69 +554,21 @@
     // If navigation corrections were needed before, that should have been
     // cancelled earlier by starting a new page load (Which has now failed).
     DCHECK(!committed_error_page_info_ ||
-           !committed_error_page_info_->navigation_correction_url.is_valid());
+           !committed_error_page_info_->needs_load_navigation_corrections);
 
-    std::string navigation_correction_request_body;
-
-    if (navigation_correction_url_.is_valid() &&
-        GetFixUrlRequestBody(error, language_, country_code_, api_key_,
-                             &navigation_correction_request_body)) {
-      pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post));
-      pending_error_page_info_->navigation_correction_url =
-          navigation_correction_url_;
-      pending_error_page_info_->navigation_correction_request_body =
-          navigation_correction_request_body;
-      return;
-    }
-
-    // The last probe status needs to be reset if this is a DNS error.  This
-    // means that if a DNS error page is committed but has not yet finished
-    // loading, a DNS probe status scheduled to be sent to it may be thrown
-    // out, but since the new error page should trigger a new DNS probe, it
-    // will just get the results for the next page load.
-    if (IsDnsError(error))
-      last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE;
-  }
-
-  GenerateLocalErrorPage(frame_type, error, is_failed_post,
-                         scoped_ptr<LocalizedError::ErrorPageParams>(),
-                         error_html);
-}
-
-void NetErrorHelperCore::GenerateLocalErrorPage(
-    FrameType frame_type,
-    const blink::WebURLError& error,
-    bool is_failed_post,
-    scoped_ptr<LocalizedError::ErrorPageParams> params,
-    std::string* error_html) {
-  if (frame_type == MAIN_FRAME) {
     pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post));
-    // Skip DNS logic if suggestions were received from a remote server.
-    if (IsDnsError(error) && !params) {
-      // This is not strictly necessary, but waiting for a new status to be
-      // sent as a result of the DidFinishLoading call keeps the histograms
-      // consistent with older versions of the code, at no real cost.
-      last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE;
+    pending_error_page_info_->navigation_correction_params.reset(
+        new NavigationCorrectionParams(navigation_correction_params_));
+    GetErrorHtmlForMainFrame(pending_error_page_info_.get(), error_html);
+  } else {
+    // These values do not matter, as error pages in iframes hide the buttons.
+    bool reload_button_in_page;
+    bool load_stale_button_in_page;
 
-      delegate_->GenerateLocalizedErrorPage(
-          GetUpdatedError(error), is_failed_post, params.Pass(),
-          &pending_error_page_info_->reload_button_in_page,
-          &pending_error_page_info_->load_stale_button_in_page,
-          error_html);
-      pending_error_page_info_->needs_dns_updates = true;
-      return;
-    }
-  }
-
-  bool reload_button_in_page = false;
-  bool load_stale_button_in_page = false;
-  delegate_->GenerateLocalizedErrorPage(
-      error, is_failed_post, params.Pass(),
-      &reload_button_in_page, &load_stale_button_in_page, error_html);
-  if (pending_error_page_info_ && frame_type == MAIN_FRAME) {
-    pending_error_page_info_->reload_button_in_page = reload_button_in_page;
-    pending_error_page_info_->load_stale_button_in_page =
-        load_stale_button_in_page;
+    delegate_->GenerateLocalizedErrorPage(
+        error, is_failed_post, scoped_ptr<LocalizedError::ErrorPageParams>(),
+        &reload_button_in_page, &load_stale_button_in_page,
+        error_html);
   }
 }
 
@@ -539,11 +593,43 @@
     const std::string& country_code,
     const std::string& api_key,
     const GURL& search_url) {
-  navigation_correction_url_ = navigation_correction_url;
-  language_ = language;
-  country_code_ = country_code;
-  api_key_ = api_key;
-  search_url_ = search_url;
+  navigation_correction_params_.url = navigation_correction_url;
+  navigation_correction_params_.language = language;
+  navigation_correction_params_.country_code = country_code;
+  navigation_correction_params_.api_key = api_key;
+  navigation_correction_params_.search_url = search_url;
+}
+
+void NetErrorHelperCore::GetErrorHtmlForMainFrame(
+    ErrorPageInfo* pending_error_page_info,
+    std::string* error_html) {
+  std::string error_param;
+  blink::WebURLError error = pending_error_page_info->error;
+
+  if (pending_error_page_info->navigation_correction_params &&
+      pending_error_page_info->navigation_correction_params->url.is_valid() &&
+      ShouldUseFixUrlServiceForError(error, &error_param)) {
+    pending_error_page_info->needs_load_navigation_corrections = true;
+    return;
+  }
+
+  if (IsDnsError(pending_error_page_info->error)) {
+    // The last probe status needs to be reset if this is a DNS error.  This
+    // means that if a DNS error page is committed but has not yet finished
+    // loading, a DNS probe status scheduled to be sent to it may be thrown
+    // out, but since the new error page should trigger a new DNS probe, it
+    // will just get the results for the next page load.
+    last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE;
+    pending_error_page_info->needs_dns_updates = true;
+    error = GetUpdatedError(error);
+  }
+
+  delegate_->GenerateLocalizedErrorPage(
+      error, pending_error_page_info->was_failed_post,
+      scoped_ptr<LocalizedError::ErrorPageParams>(),
+      &pending_error_page_info->reload_button_in_page,
+      &pending_error_page_info->load_stale_button_in_page,
+      error_html);
 }
 
 void NetErrorHelperCore::UpdateErrorPage() {
@@ -576,20 +662,40 @@
   // and is cancelled with a new load.
   DCHECK(!pending_error_page_info_);
   DCHECK(committed_error_page_info_->is_finished_loading);
+  DCHECK(committed_error_page_info_->needs_load_navigation_corrections);
+  DCHECK(committed_error_page_info_->navigation_correction_params);
 
-  scoped_ptr<LocalizedError::ErrorPageParams> params(
-    ParseAdditionalSuggestions(
-        corrections, GURL(committed_error_page_info_->error.unreachableURL),
-        search_url_, accept_languages, is_rtl));
+  pending_error_page_info_.reset(
+      new ErrorPageInfo(committed_error_page_info_->error,
+                        committed_error_page_info_->was_failed_post));
+  pending_error_page_info_->navigation_correction_response =
+      ParseNavigationCorrectionResponse(corrections);
+
   std::string error_html;
-  GenerateLocalErrorPage(MAIN_FRAME,
-                         committed_error_page_info_->error,
-                         committed_error_page_info_->was_failed_post,
-                         params.Pass(),
-                         &error_html);
-
-  // |error_page_info| may have been destroyed by this point, since
-  // |pending_error_page_info_| was set to a new ErrorPageInfo.
+  scoped_ptr<LocalizedError::ErrorPageParams> params;
+  if (pending_error_page_info_->navigation_correction_response) {
+    // Copy navigation correction parameters used for the request, so tracking
+    // requests can still be sent if the configuration changes.
+    pending_error_page_info_->navigation_correction_params.reset(
+        new NavigationCorrectionParams(
+            *committed_error_page_info_->navigation_correction_params));
+    params = CreateErrorPageParams(
+          *pending_error_page_info_->navigation_correction_response,
+          pending_error_page_info_->error,
+          *pending_error_page_info_->navigation_correction_params,
+          accept_languages, is_rtl);
+    delegate_->GenerateLocalizedErrorPage(
+        pending_error_page_info_->error,
+        pending_error_page_info_->was_failed_post,
+        params.Pass(),
+        &pending_error_page_info_->reload_button_in_page,
+        &pending_error_page_info_->load_stale_button_in_page,
+        &error_html);
+  } else {
+    // Since |navigation_correction_params| in |pending_error_page_info_| is
+    // NULL, this won't trigger another attempt to load corrections.
+    GetErrorHtmlForMainFrame(pending_error_page_info_.get(), &error_html);
+  }
 
   // TODO(mmenke):  Once the new API is in place, look into replacing this
   //                double page load by just updating the error page, like DNS
@@ -726,3 +832,39 @@
   }
 }
 
+void NetErrorHelperCore::TrackClick(int tracking_id) {
+  // It's technically possible for |navigation_correction_params| to be NULL but
+  // for |navigation_correction_response| not to be NULL, if the paramters
+  // changed between loading the original error page and loading the error page
+  if (!committed_error_page_info_ ||
+      !committed_error_page_info_->navigation_correction_response) {
+    return;
+  }
+
+  NavigationCorrectionResponse* response =
+      committed_error_page_info_->navigation_correction_response.get();
+
+  // |tracking_id| is less than 0 when the error page was not generated by the
+  // navigation correction service.  |tracking_id| should never be greater than
+  // the array size, but best to be safe, since it contains data from a remote
+  // site, though none of that data should make it into Javascript callbacks.
+  if (tracking_id < 0 ||
+      static_cast<size_t>(tracking_id) >= response->corrections.size()) {
+    return;
+  }
+
+  // Only report a clicked link once.
+  if (committed_error_page_info_->clicked_corrections.count(tracking_id))
+    return;
+
+  committed_error_page_info_->clicked_corrections.insert(tracking_id);
+  std::string request_body = CreateClickTrackingUrlRequestBody(
+      committed_error_page_info_->error,
+      *committed_error_page_info_->navigation_correction_params,
+      *response,
+      *response->corrections[tracking_id]);
+  delegate_->SendTrackingRequest(
+      committed_error_page_info_->navigation_correction_params->url,
+      request_body);
+}
+
diff --git a/chrome/renderer/net/net_error_helper_core.h b/chrome/renderer/net/net_error_helper_core.h
index 2c76e7a..62a33fc 100644
--- a/chrome/renderer/net/net_error_helper_core.h
+++ b/chrome/renderer/net/net_error_helper_core.h
@@ -83,6 +83,12 @@
     // ongoing.
     virtual void CancelFetchNavigationCorrections() = 0;
 
+    // Sends an HTTP request used to track which link on the page was clicked to
+    // the navigation correction service.
+    virtual void SendTrackingRequest(
+        const GURL& tracking_url,
+        const std::string& tracking_request_body) = 0;
+
     // Starts a reload of the page in the observed frame.
     virtual void ReloadPage() = 0;
 
@@ -93,6 +99,19 @@
     virtual ~Delegate() {}
   };
 
+  struct NavigationCorrectionParams {
+    NavigationCorrectionParams();
+    ~NavigationCorrectionParams();
+
+    // URL used both for getting the suggestions and tracking clicks.
+    GURL url;
+
+    std::string language;
+    std::string country_code;
+    std::string api_key;
+    GURL search_url;
+  };
+
   explicit NetErrorHelperCore(Delegate* delegate);
   ~NetErrorHelperCore();
 
@@ -162,21 +181,26 @@
   // care of in JavaScript.
   void ExecuteButtonPress(Button button);
 
+  // Reports to the correction service that the link with the given tracking
+  // ID was clicked.  Only pages generated with information from the service
+  // have links with tracking IDs.  Duplicate requests from the same page with
+  // the same tracking ID are ignored.
+  void TrackClick(int tracking_id);
+
  private:
   struct ErrorPageInfo;
 
+  // Gets HTML for a main frame error page.  Depending on
+  // |pending_error_page_info|, may use the navigation correction service, or
+  // show a DNS probe error page.  May modify |pending_error_page_info|.
+  void GetErrorHtmlForMainFrame(ErrorPageInfo* pending_error_page_info,
+                                std::string* error_html);
+
   // Updates the currently displayed error page with a new error based on the
   // most recently received DNS probe result.  The page must have finished
   // loading before this is called.
   void UpdateErrorPage();
 
-  void GenerateLocalErrorPage(
-      FrameType frame_type,
-      const blink::WebURLError& error,
-      bool is_failed_post,
-      scoped_ptr<LocalizedError::ErrorPageParams> params,
-      std::string* error_html);
-
   blink::WebURLError GetUpdatedError(const blink::WebURLError& error) const;
 
   void Reload();
@@ -199,11 +223,7 @@
   // not an error page.
   scoped_ptr<ErrorPageInfo> committed_error_page_info_;
 
-  GURL navigation_correction_url_;
-  std::string language_;
-  std::string country_code_;
-  std::string api_key_;
-  GURL search_url_;
+  NavigationCorrectionParams navigation_correction_params_;
 
   bool auto_reload_enabled_;
   scoped_ptr<base::Timer> auto_reload_timer_;
diff --git a/chrome/renderer/net/net_error_helper_core_unittest.cc b/chrome/renderer/net/net_error_helper_core_unittest.cc
index 4820f21..66367bc 100644
--- a/chrome/renderer/net/net_error_helper_core_unittest.cc
+++ b/chrome/renderer/net/net_error_helper_core_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/renderer/net/net_error_helper_core.h"
 
+#include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
@@ -21,13 +22,22 @@
 
 const char kFailedUrl[] = "http://failed/";
 const char kFailedHttpsUrl[] = "https://failed/";
+
 const char kNavigationCorrectionUrl[] = "http://navigation.corrections/";
+const char kLanguage[] = "en";
+const char kCountry[] = "us";
+const char kApiKey[] = "api_key";
 const char kSearchUrl[] = "http://www.google.com/search";
+
 const char kSuggestedSearchTerms[] = "Happy Goats";
+const char kNavigationCorrectionEventId[] = "#007";
+const char kNavigationCorrectionFingerprint[] = "RandumStuff";
 
 struct NavigationCorrection {
   const char* correction_type;
   const char* url_correction;
+  const char* click_type;
+  const char* click_data;
   bool is_porn;
   bool is_soft_porn;
 
@@ -35,6 +45,8 @@
     base::DictionaryValue* dict = new base::DictionaryValue();
     dict->SetString("correctionType", correction_type);
     dict->SetString("urlCorrection", url_correction);
+    dict->SetString("clickType", click_type);
+    dict->SetString("clickData", click_data);
     dict->SetBoolean("isPorn", is_porn);
     dict->SetBoolean("isSoftPorn", is_soft_porn);
     return dict;
@@ -42,15 +54,15 @@
 };
 
 const NavigationCorrection kDefaultCorrections[] = {
-  {"reloadPage", kFailedUrl, false, false},
-  {"urlCorrection", "http://somewhere_else/", false, false},
-  {"contentOverlap", "http://somewhere_else_entirely/", false, false},
+  {"reloadPage", kFailedUrl, "rld", "data1", false, false},
+  {"urlCorrection", "http://somewhere_else/", "btn", "data2", false, false},
+  {"contentOverlap", "http://pony_island/", "btn", "data3", false, false},
 
   // Porn should be ignored.
-  {"emphasizedUrlCorrection", "http://porn/", true, false},
-  {"sitemap", "http://more_porn/", false, true},
+  {"emphasizedUrlCorrection", "http://porn/", "btn", "data4", true, false},
+  {"sitemap", "http://more_porn/", "btn", "data5", false, true},
 
-  {"webSearchQuery", kSuggestedSearchTerms, false, false},
+  {"webSearchQuery", kSuggestedSearchTerms, "frm", "data6", false, false},
 };
 
 std::string SuggestionsToResponse(const NavigationCorrection* corrections,
@@ -61,12 +73,28 @@
 
   scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue());
   response->Set("result.UrlCorrections", url_corrections);
+  response->SetString("result.eventId", kNavigationCorrectionEventId);
+  response->SetString("result.fingerprint", kNavigationCorrectionFingerprint);
 
   std::string json;
   base::JSONWriter::Write(response.get(), &json);
   return json;
 }
 
+testing::AssertionResult StringValueEquals(
+    const base::DictionaryValue& dict,
+    const std::string& key,
+    const std::string& expected_value) {
+  std::string actual_value;
+  if (!dict.GetString(key, &actual_value))
+    return testing::AssertionFailure() << key << " not found.";
+  if (actual_value != expected_value) {
+    return testing::AssertionFailure()
+        << "actual: " << actual_value << "\n expected: " << expected_value;
+  }
+  return testing::AssertionSuccess();
+}
+
 // Creates a string from an error that is used as a mock locally generated
 // error page for that error.
 std::string ErrorToString(const WebURLError& error, bool is_failed_post) {
@@ -121,7 +149,8 @@
         error_html_update_count_(0),
         reload_count_(0),
         load_stale_count_(0),
-        enable_page_helper_functions_count_(0) {
+        enable_page_helper_functions_count_(0),
+        tracking_request_count_(0) {
     core_.set_auto_reload_enabled(false);
     core_.set_timer_for_testing(scoped_ptr<base::Timer>(timer_));
   }
@@ -162,6 +191,12 @@
     return last_error_page_params_.get();
   }
 
+  const GURL& last_tracking_url() const { return last_tracking_url_; }
+  const std::string& last_tracking_request_body() const {
+    return last_tracking_request_body_;
+  }
+  int tracking_request_count() const { return tracking_request_count_; }
+
   base::MockTimer* timer() { return timer_; }
 
   void NavigationCorrectionsLoadSuccess(
@@ -226,7 +261,7 @@
  private:
   void SetNavigationCorrectionURL(const GURL& navigation_correction_url) {
     core().OnSetNavigationCorrectionInfo(navigation_correction_url,
-                                         "en", "us", "api_key",
+                                         kLanguage, kCountry, kApiKey,
                                          GURL(kSearchUrl));
   }
 
@@ -270,6 +305,20 @@
 
     url_being_fetched_ = navigation_correction_url;
     request_body_ = navigation_correction_request_body;
+
+    // Check the body of the request.
+
+    base::JSONReader reader;
+    scoped_ptr<base::Value> parsed_body(reader.Read(
+        navigation_correction_request_body));
+    ASSERT_TRUE(parsed_body);
+    base::DictionaryValue* dict = NULL;
+    ASSERT_TRUE(parsed_body->GetAsDictionary(&dict));
+
+    EXPECT_TRUE(StringValueEquals(*dict, "params.urlQuery", kFailedUrl));
+    EXPECT_TRUE(StringValueEquals(*dict, "params.language", kLanguage));
+    EXPECT_TRUE(StringValueEquals(*dict, "params.originCountry", kCountry));
+    EXPECT_TRUE(StringValueEquals(*dict, "params.key", kApiKey));
   }
 
   virtual void CancelFetchNavigationCorrections() OVERRIDE {
@@ -286,6 +335,28 @@
     load_stale_url_ = error_url;
   }
 
+  virtual void SendTrackingRequest(
+      const GURL& tracking_url,
+      const std::string& tracking_request_body) OVERRIDE {
+    last_tracking_url_ = tracking_url;
+    last_tracking_request_body_ = tracking_request_body;
+    tracking_request_count_++;
+
+    // Check the body of the request.
+
+    base::JSONReader reader;
+    scoped_ptr<base::Value> parsed_body(reader.Read(tracking_request_body));
+    ASSERT_TRUE(parsed_body);
+    base::DictionaryValue* dict = NULL;
+    ASSERT_TRUE(parsed_body->GetAsDictionary(&dict));
+
+    EXPECT_TRUE(StringValueEquals(*dict, "params.originalUrlQuery",
+                                  kFailedUrl));
+    EXPECT_TRUE(StringValueEquals(*dict, "params.language", kLanguage));
+    EXPECT_TRUE(StringValueEquals(*dict, "params.originCountry", kCountry));
+    EXPECT_TRUE(StringValueEquals(*dict, "params.key", kApiKey));
+  }
+
   base::MockTimer* timer_;
 
   NetErrorHelperCore core_;
@@ -312,6 +383,10 @@
   GURL load_stale_url_;
 
   int enable_page_helper_functions_count_;
+
+  GURL last_tracking_url_;
+  std::string last_tracking_request_body_;
+  int tracking_request_count_;
 };
 
 //------------------------------------------------------------------------------
@@ -1573,7 +1648,7 @@
 // Checks corrections are is used when there are no search suggestions.
 TEST_F(NetErrorHelperCoreTest, CorrectionsWithoutSearch) {
   const NavigationCorrection kCorrections[] = {
-    {"urlCorrection", "http://somewhere_else/", false, false},
+    {"urlCorrection", "http://somewhere_else/", "btn", "data", false, false},
   };
 
   // Original page starts loading.
@@ -1621,7 +1696,7 @@
 // Checks corrections are used when there are only search suggestions.
 TEST_F(NetErrorHelperCoreTest, CorrectionsOnlySearchSuggestion) {
   const NavigationCorrection kCorrections[] = {
-    {"webSearchQuery", kSuggestedSearchTerms, false, false},
+    {"webSearchQuery", kSuggestedSearchTerms, "frm", "data", false, false},
   };
 
   // Original page starts loading.
@@ -1739,6 +1814,94 @@
   core().OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
 }
 
+TEST_F(NetErrorHelperCoreTest, CorrectionClickTracking) {
+  // Go through the standard navigation correction steps.
+
+  // Original page starts loading.
+  EnableNavigationCorrections();
+  core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
+                     NetErrorHelperCore::NON_ERROR_PAGE);
+
+  // It fails.
+  std::string html;
+  core().GetErrorHTML(NetErrorHelperCore::MAIN_FRAME,
+                      NetError(net::ERR_NAME_NOT_RESOLVED),
+                      false, &html);
+  EXPECT_TRUE(html.empty());
+  EXPECT_FALSE(is_url_being_fetched());
+  EXPECT_FALSE(last_error_page_params());
+
+  // The blank page loads.
+  core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
+                      NetErrorHelperCore::ERROR_PAGE);
+  core().OnCommitLoad(NetErrorHelperCore::MAIN_FRAME);
+
+  // Corrections retrieval starts when the error page finishes loading.
+  EXPECT_FALSE(is_url_being_fetched());
+  EXPECT_FALSE(last_error_page_params());
+  core().OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
+  EXPECT_TRUE(is_url_being_fetched());
+  EXPECT_FALSE(last_error_page_params());
+
+  // Corrections are retrieved.
+  NavigationCorrectionsLoadSuccess(kDefaultCorrections,
+                                   arraysize(kDefaultCorrections));
+  EXPECT_EQ(1, error_html_update_count());
+  EXPECT_EQ(NetErrorString(net::ERR_NAME_NOT_RESOLVED), last_error_html());
+  ExpectDefaultNavigationCorrections();
+  EXPECT_FALSE(is_url_being_fetched());
+
+  // Corrections load.
+  core().OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
+                      NetErrorHelperCore::ERROR_PAGE);
+  core().OnCommitLoad(NetErrorHelperCore::MAIN_FRAME);
+  core().OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
+
+  EXPECT_EQ(0, tracking_request_count());
+
+  // Invalid clicks should be ignored.
+  core().TrackClick(-1);
+  core().TrackClick(arraysize(kDefaultCorrections));
+  EXPECT_EQ(0, tracking_request_count());
+
+  for (size_t i = 0; i < arraysize(kDefaultCorrections); ++i) {
+    // Skip links that do not appear in the page.
+    if (kDefaultCorrections[i].is_porn || kDefaultCorrections[i].is_soft_porn)
+      continue;
+
+    int old_tracking_request_count = tracking_request_count();
+    core().TrackClick(i);
+    EXPECT_EQ(old_tracking_request_count + 1, tracking_request_count());
+    EXPECT_EQ(GURL(kNavigationCorrectionUrl), last_tracking_url());
+
+    // Make sure all expected strings appear in output.
+    EXPECT_TRUE(last_tracking_request_body().find(
+                    kDefaultCorrections[i].url_correction));
+    EXPECT_TRUE(last_tracking_request_body().find(
+                    kDefaultCorrections[i].click_data));
+    EXPECT_TRUE(last_tracking_request_body().find(
+                    kDefaultCorrections[i].click_type));
+    EXPECT_TRUE(last_tracking_request_body().find(
+                    kNavigationCorrectionEventId));
+    EXPECT_TRUE(last_tracking_request_body().find(
+                    kNavigationCorrectionFingerprint));
+  }
+
+  // Make sure duplicate tracking requests are ignored.
+  for (size_t i = 0; i < arraysize(kDefaultCorrections); ++i) {
+    // Skip links that do not appear in the page.
+    if (kDefaultCorrections[i].is_porn || kDefaultCorrections[i].is_soft_porn)
+      continue;
+
+    int old_tracking_request_count = tracking_request_count();
+    core().TrackClick(i);
+    EXPECT_EQ(old_tracking_request_count, tracking_request_count());
+  }
+
+  EXPECT_EQ(0, update_count());
+  EXPECT_EQ(1, error_html_update_count());
+}
+
 TEST_F(NetErrorHelperCoreTest, AutoReloadDisabled) {
   DoErrorLoad(net::ERR_CONNECTION_RESET);
 
@@ -2023,5 +2186,3 @@
   EXPECT_EQ(1, load_stale_count());
   EXPECT_EQ(GURL(kFailedUrl), load_stale_url());
 }
-
-
diff --git a/chrome/renderer/net/net_error_page_controller.cc b/chrome/renderer/net/net_error_page_controller.cc
index fcd8c74..42a2c20 100644
--- a/chrome/renderer/net/net_error_page_controller.cc
+++ b/chrome/renderer/net/net_error_page_controller.cc
@@ -72,6 +72,20 @@
   return true;
 }
 
+bool NetErrorPageController::TrackClick(const gin::Arguments& args) {
+  if (!render_frame())
+    return false;
+
+  if (!args.PeekNext()->IsInt32())
+    return false;
+
+  NetErrorHelper* net_error_helper =
+      content::RenderFrameObserverTracker<NetErrorHelper>::Get(render_frame());
+  DCHECK(net_error_helper);
+  net_error_helper->TrackClick(args.PeekNext()->Int32Value());
+  return true;
+}
+
 NetErrorPageController::NetErrorPageController(
     content::RenderFrame* render_frame) : RenderFrameObserver(render_frame) {}
 
@@ -85,7 +99,9 @@
                  &NetErrorPageController::LoadStaleButtonClick)
       .SetMethod("reloadButtonClick",
                  &NetErrorPageController::ReloadButtonClick)
-      .SetMethod("moreButtonClick", &NetErrorPageController::MoreButtonClick);
+      .SetMethod("moreButtonClick", &NetErrorPageController::MoreButtonClick)
+      .SetMethod("trackClick",
+                 &NetErrorPageController::TrackClick);
 }
 
 void NetErrorPageController::OnDestruct() {}
diff --git a/chrome/renderer/net/net_error_page_controller.h b/chrome/renderer/net/net_error_page_controller.h
index a3a615f..9c5314a 100644
--- a/chrome/renderer/net/net_error_page_controller.h
+++ b/chrome/renderer/net/net_error_page_controller.h
@@ -7,6 +7,7 @@
 
 #include "base/macros.h"
 #include "content/public/renderer/render_frame_observer.h"
+#include "gin/arguments.h"
 #include "gin/wrappable.h"
 
 
@@ -38,6 +39,10 @@
   // Execute a "More" button click.
   bool MoreButtonClick();
 
+  // Track a click when the page has suggestions from the navigation correction
+  // service.
+  bool TrackClick(const gin::Arguments& args);
+
   // gin::WrappableBase
   virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
       v8::Isolate* isolate) OVERRIDE;
diff --git a/chrome/renderer/pepper/pepper_extensions_common_host.cc b/chrome/renderer/pepper/pepper_extensions_common_host.cc
index f48d6b4..6f19ea5 100644
--- a/chrome/renderer/pepper/pepper_extensions_common_host.cc
+++ b/chrome/renderer/pepper/pepper_extensions_common_host.cc
@@ -8,10 +8,10 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/values.h"
 #include "chrome/renderer/extensions/chrome_v8_context.h"
-#include "chrome/renderer/extensions/dispatcher.h"
-#include "chrome/renderer/extensions/extension_helper.h"
 #include "content/public/renderer/render_view.h"
 #include "content/public/renderer/renderer_ppapi_host.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/extension_helper.h"
 #include "ppapi/c/pp_errors.h"
 #include "ppapi/host/dispatch_host_message.h"
 #include "ppapi/host/host_message_context.h"
diff --git a/chrome/renderer/printing/print_web_view_helper.cc b/chrome/renderer/printing/print_web_view_helper.cc
index 259601e..29340a3 100644
--- a/chrome/renderer/printing/print_web_view_helper.cc
+++ b/chrome/renderer/printing/print_web_view_helper.cc
@@ -878,7 +878,7 @@
     return;
 
   blink::WebDocument document = main_frame->document();
-  // <object> with id="pdf-viewer" is created in
+  // <object>/<iframe> with id="pdf-viewer" is created in
   // chrome/browser/resources/print_preview/print_preview.js
   blink::WebElement pdf_element = document.getElementById("pdf-viewer");
   if (pdf_element.isNull()) {
@@ -886,12 +886,29 @@
     return;
   }
 
+  // The out-of-process plugin element is nested within a frame.
+  blink::WebLocalFrame* plugin_frame = pdf_element.document().frame();
+  blink::WebElement plugin_element = pdf_element;
+  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kOutOfProcessPdf)) {
+    if (!pdf_element.hasTagName("iframe")) {
+      NOTREACHED();
+      return;
+    }
+    plugin_frame = blink::WebLocalFrame::fromFrameOwnerElement(pdf_element);
+    // <object> with id="plugin" is created in
+    // chrome/browser/resources/pdf/pdf.js.
+    plugin_element = plugin_frame->document().getElementById("plugin");
+    if (plugin_element.isNull()) {
+      NOTREACHED();
+      return;
+    }
+  }
+
   // Set |print_for_preview_| flag and autoreset it to back to original
   // on return.
   base::AutoReset<bool> set_printing_flag(&print_for_preview_, true);
 
-  blink::WebLocalFrame* pdf_frame = pdf_element.document().frame();
-  if (!UpdatePrintSettings(pdf_frame, pdf_element, job_settings)) {
+  if (!UpdatePrintSettings(plugin_frame, plugin_element, job_settings)) {
     LOG(ERROR) << "UpdatePrintSettings failed";
     DidFinishPrinting(FAIL_PRINT);
     return;
@@ -910,7 +927,7 @@
   print_params.printable_area = gfx::Rect(print_params.page_size);
 
   // Render Pages for printing.
-  if (!RenderPagesForPrint(pdf_frame, pdf_element)) {
+  if (!RenderPagesForPrint(plugin_frame, plugin_element)) {
     LOG(ERROR) << "RenderPagesForPrint failed";
     DidFinishPrinting(FAIL_PRINT);
   }
diff --git a/chrome/renderer/printing/print_web_view_helper_browsertest.cc b/chrome/renderer/printing/print_web_view_helper_browsertest.cc
index a8563b7..0b36227 100644
--- a/chrome/renderer/printing/print_web_view_helper_browsertest.cc
+++ b/chrome/renderer/printing/print_web_view_helper_browsertest.cc
@@ -3,12 +3,14 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
+#include "base/run_loop.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/print_messages.h"
 #include "chrome/renderer/mock_printer.h"
 #include "chrome/renderer/printing/print_web_view_helper.h"
 #include "chrome/test/base/chrome_render_view_test.h"
 #include "content/public/renderer/render_view.h"
+#include "ipc/ipc_listener.h"
 #include "printing/print_job_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/WebString.h"
@@ -102,6 +104,24 @@
 }
 #endif  // !defined(OS_CHROMEOS)
 
+class DidPreviewPageListener : public IPC::Listener {
+ public:
+  explicit DidPreviewPageListener(base::RunLoop* run_loop)
+      : run_loop_(run_loop) {}
+
+  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
+    if (message.type() == PrintHostMsg_MetafileReadyForPrinting::ID ||
+        message.type() == PrintHostMsg_PrintPreviewFailed::ID ||
+        message.type() == PrintHostMsg_PrintPreviewCancelled::ID)
+      run_loop_->Quit();
+    return false;
+  }
+
+ private:
+  base::RunLoop* const run_loop_;
+  DISALLOW_COPY_AND_ASSIGN(DidPreviewPageListener);
+};
+
 }  // namespace
 
 class PrintWebViewHelperTestBase : public ChromeRenderViewTest {
@@ -175,8 +195,12 @@
   void OnPrintPreview(const base::DictionaryValue& dict) {
     PrintWebViewHelper* print_web_view_helper = PrintWebViewHelper::Get(view_);
     print_web_view_helper->OnInitiatePrintPreview(false);
+    base::RunLoop run_loop;
+    DidPreviewPageListener filter(&run_loop);
+    render_thread_->sink().AddFilter(&filter);
     print_web_view_helper->OnPrintPreview(dict);
-    ProcessPendingMessages();
+    run_loop.Run();
+    render_thread_->sink().RemoveFilter(&filter);
   }
 
   void OnPrintForPrintPreview(const base::DictionaryValue& dict) {
diff --git a/chrome/renderer/resource_bundle_source_map.cc b/chrome/renderer/resource_bundle_source_map.cc
deleted file mode 100644
index 6a7ff02..0000000
--- a/chrome/renderer/resource_bundle_source_map.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "chrome/renderer/resource_bundle_source_map.h"
-
-#include "ui/base/resource/resource_bundle.h"
-
-ResourceBundleSourceMap::ResourceBundleSourceMap(
-    const ui::ResourceBundle* resource_bundle)
-    : resource_bundle_(resource_bundle) {
-}
-
-ResourceBundleSourceMap::~ResourceBundleSourceMap() {
-}
-
-void ResourceBundleSourceMap::RegisterSource(const std::string& name,
-                                             int resource_id) {
-  resource_id_map_[name] = resource_id;
-}
-
-v8::Handle<v8::Value> ResourceBundleSourceMap::GetSource(
-    v8::Isolate* isolate,
-    const std::string& name) {
-  if (!Contains(name))
-    return v8::Undefined(isolate);
-  int resource_id = resource_id_map_[name];
-  return ConvertString(isolate,
-                       resource_bundle_->GetRawDataResource(resource_id));
-}
-
-bool ResourceBundleSourceMap::Contains(const std::string& name) {
-  return !!resource_id_map_.count(name);
-}
-
-v8::Handle<v8::String> ResourceBundleSourceMap::ConvertString(
-    v8::Isolate* isolate,
-    const base::StringPiece& string) {
-  // v8 takes ownership of the StaticV8ExternalAsciiStringResource (see
-  // v8::String::NewExternal()).
-  return v8::String::NewExternal(
-      isolate, new StaticV8ExternalAsciiStringResource(string));
-}
diff --git a/chrome/renderer/resource_bundle_source_map.h b/chrome/renderer/resource_bundle_source_map.h
deleted file mode 100644
index fddea7c..0000000
--- a/chrome/renderer/resource_bundle_source_map.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_
-#define CHROME_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_
-
-#include "base/compiler_specific.h"
-#include "base/memory/linked_ptr.h"
-#include "base/strings/string_piece.h"
-#include "chrome/renderer/static_v8_external_string_resource.h"
-#include "extensions/renderer/module_system.h"
-#include "v8/include/v8.h"
-
-#include <map>
-#include <string>
-
-namespace ui {
-  class ResourceBundle;
-}
-
-class ResourceBundleSourceMap : public extensions::ModuleSystem::SourceMap {
- public:
-  explicit ResourceBundleSourceMap(const ui::ResourceBundle* resource_bundle);
-  virtual ~ResourceBundleSourceMap();
-
-  virtual v8::Handle<v8::Value> GetSource(v8::Isolate* isolate,
-                                          const std::string& name) OVERRIDE;
-  virtual bool Contains(const std::string& name) OVERRIDE;
-
-  void RegisterSource(const std::string& name, int resource_id);
-
- private:
-  v8::Handle<v8::String> ConvertString(v8::Isolate* isolate,
-                                       const base::StringPiece& string);
-
-  const ui::ResourceBundle* resource_bundle_;
-  std::map<std::string, int> resource_id_map_;
-};
-
-#endif  // CHROME_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_
diff --git a/chrome/renderer/resources/extensions/app_custom_bindings.js b/chrome/renderer/resources/extensions/app_custom_bindings.js
index 2ba59e6..e757502 100644
--- a/chrome/renderer/resources/extensions/app_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/app_custom_bindings.js
@@ -71,7 +71,5 @@
 if (extensionId)
   app.installState = wrapForLogging(app.installState);
 
-// This must match InstallAppBindings() in
-// chrome/renderer/extensions/dispatcher.cc.
-exports.chromeApp = app;
+exports.binding = app;
 exports.onInstallStateResponse = onInstallStateResponse;
diff --git a/chrome/renderer/resources/extensions/automation/automation_tree.js b/chrome/renderer/resources/extensions/automation/automation_tree.js
index 6d8afc5..43d5350 100644
--- a/chrome/renderer/resources/extensions/automation/automation_tree.js
+++ b/chrome/renderer/resources/extensions/automation/automation_tree.js
@@ -136,7 +136,7 @@
         }
       }
 
-      if (nodeData.role == 'root_web_area') {
+      if (nodeData.role == 'root_web_area' || nodeData.role == 'desktop') {
         this.root = node;
         didUpdateRoot = true;
       }
diff --git a/chrome/renderer/resources/extensions/automation_custom_bindings.js b/chrome/renderer/resources/extensions/automation_custom_bindings.js
index fae3ee1..dd783b2 100644
--- a/chrome/renderer/resources/extensions/automation_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/automation_custom_bindings.js
@@ -52,6 +52,20 @@
       }
     });
   });
+
+  var desktopTree = null;
+  apiFunctions.setHandleRequest('getDesktop', function(callback) {
+    var id = createAutomationTreeID(0, 0);
+    desktopTree = idToAutomationTree[id];
+    if (!desktopTree) {
+      desktopTree = new AutomationTree(0, 0);
+      idToAutomationTree[id] = desktopTree;
+      // TODO(dtseng): Disable desktop tree once desktop object goes out of
+      // scope.
+      automationInternal.enableDesktop();
+    }
+    window.setTimeout(function() { callback(desktopTree); }, 0);
+  });
 });
 
 // Listen to the automationInternal.onaccessibilityEvent event, which is
@@ -70,7 +84,6 @@
     idToAutomationTree[id] = targetTree;
   }
   privates(targetTree).impl.update(data);
-
   var eventType = data.eventType;
   if (eventType == 'load_complete' || eventType == 'layout_complete') {
     // If the tree wasn't available when getTree() was called, the callback will
diff --git a/chrome/renderer/resources/extensions/event.js b/chrome/renderer/resources/extensions/event.js
index 8beca3d..74f3ee06 100644
--- a/chrome/renderer/resources/extensions/event.js
+++ b/chrome/renderer/resources/extensions/event.js
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
   var eventNatives = requireNative('event_natives');
+  var handleUncaughtException = require('uncaught_exception_handler').handle;
   var logging = requireNative('logging');
   var schemaRegistry = requireNative('schema_registry');
   var sendRequest = require('sendRequest').sendRequest;
@@ -380,10 +381,11 @@
         if (result !== undefined)
           $Array.push(results, result);
       } catch (e) {
-        console.error(
+        handleUncaughtException(
           'Error in event handler for ' +
-          (this.eventName ? this.eventName : '(unknown)') +
-          ': ' + e.message + '\nStack trace: ' + e.stack);
+              (this.eventName ? this.eventName : '(unknown)') +
+              ': ' + e.message + '\nStack trace: ' + e.stack,
+          e);
       }
     }
     if (results.length)
diff --git a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js
index b896138..f59900c 100644
--- a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js
@@ -11,6 +11,34 @@
 var fileSystemNatives = requireNative('file_system_natives');
 var GetDOMError = fileSystemNatives.GetDOMError;
 
+/**
+ * Annotates a date with its serialized value.
+ * @param {Date} date Input date.
+ * @return {Date} Date with an extra <code>value</code> attribute.
+ */
+function annotateDate(date) {
+  // Copy in case the input date is frozen.
+  var result = new Date(date.getTime());
+  result.value = result.toString();
+  return result;
+}
+
+/**
+ * Annotates an entry metadata by serializing its modifiedTime value.
+ * @param {EntryMetadata} metadata Input metadata.
+ * @return {EntryMetadata} metadata Annotated metadata, which can be passed
+ *     back to the C++ layer.
+ */
+function annotateMetadata(metadata) {
+  var result = {
+    isDirectory: metadata.isDirectory,
+    name: metadata.name,
+    size: metadata.size,
+    modificationTime: annotateDate(metadata.modificationTime)
+  };
+  return result;
+}
+
 binding.registerCustomHook(function(bindingsAPI) {
   var apiFunctions = bindingsAPI.apiFunctions;
 
@@ -97,4 +125,40 @@
       dispatch([fileSystemId, onSuccessCallback, onErrorCallback]);
     });
 
+eventBindings.registerArgumentMassager(
+    'fileSystemProvider.onGetMetadataRequested',
+    function(args, dispatch) {
+      var fileSystemId = args[0];
+      var requestId = args[1];
+      var entryPath = args[2];
+      var onSuccessCallback = function(metadata) {
+        fileSystemProviderInternal.getMetadataRequestedSuccess(
+            fileSystemId, requestId, annotateMetadata(metadata));
+      };
+      var onErrorCallback = function(error) {
+        fileSystemProviderInternal.getMetadataRequestedError(
+          fileSystemId, requestId, error);
+      }
+      dispatch([fileSystemId, entryPath, onSuccessCallback, onErrorCallback]);
+    });
+
+eventBindings.registerArgumentMassager(
+    'fileSystemProvider.onReadDirectoryRequested',
+    function(args, dispatch) {
+      var fileSystemId = args[0];
+      var requestId = args[1];
+      var directoryPath = args[2];
+      var onSuccessCallback = function(entries, hasNext) {
+        var annotatedEntries = entries.map(annotateMetadata);
+        fileSystemProviderInternal.readDirectoryRequestedSuccess(
+            fileSystemId, requestId, annotatedEntries, hasNext);
+      };
+      var onErrorCallback = function(error) {
+        fileSystemProviderInternal.readDirectoryRequestedError(
+            fileSystemId, requestId, error);
+      }
+      dispatch([
+          fileSystemId, directoryPath, onSuccessCallback, onErrorCallback]);
+    });
+
 exports.binding = binding.generate();
diff --git a/chrome/renderer/resources/extensions/last_error.js b/chrome/renderer/resources/extensions/last_error.js
index 1d2b565..6d85b11 100644
--- a/chrome/renderer/resources/extensions/last_error.js
+++ b/chrome/renderer/resources/extensions/last_error.js
@@ -28,7 +28,7 @@
   clear(targetChrome);  // in case somebody has set a sneaky getter/setter
 
   var errorObject = { message: message };
-  if (GetAvailability('extension.lastError').is_available)
+  if (targetChrome && targetChrome.extension)
     targetChrome.extension.lastError = errorObject;
 
   assertRuntimeIsAvailable();
@@ -64,8 +64,8 @@
   if (!targetChrome)
     throw new Error('No target chrome to clear error');
 
-  if (GetAvailability('extension.lastError').is_available)
-    delete targetChrome.extension.lastError;
+  if (targetChrome && targetChrome.extension)
+   delete targetChrome.extension.lastError;
 
   assertRuntimeIsAvailable();
   delete targetChrome.runtime.lastError;
diff --git a/chrome/renderer/resources/extensions/send_request.js b/chrome/renderer/resources/extensions/send_request.js
index 9117e96..808c6cd 100644
--- a/chrome/renderer/resources/extensions/send_request.js
+++ b/chrome/renderer/resources/extensions/send_request.js
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+var handleUncaughtException = require('uncaught_exception_handler').handle;
 var lastError = require('lastError');
 var logging = requireNative('logging');
 var natives = requireNative('sendRequest');
@@ -23,7 +24,7 @@
     var errorMessage = "Error in response to " + name + ": " + e;
     if (request.stack && request.stack != '')
       errorMessage += "\n" + request.stack;
-    console.error(errorMessage);
+    handleUncaughtException(errorMessage, e);
   }
 }
 
diff --git a/chrome/renderer/resources/extensions/test_custom_bindings.js b/chrome/renderer/resources/extensions/test_custom_bindings.js
index fe60eb2..52db024 100644
--- a/chrome/renderer/resources/extensions/test_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/test_custom_bindings.js
@@ -12,6 +12,7 @@
     requireNative('apiDefinitions').GetExtensionAPIDefinitionsForTest;
 var GetAvailability = requireNative('v8_context').GetAvailability;
 var GetAPIFeatures = requireNative('test_features').GetAPIFeatures;
+var uncaughtExceptionHandler = require('uncaught_exception_handler');
 var userGestures = requireNative('user_gestures');
 
 binding.registerCustomHook(function(api) {
@@ -91,10 +92,13 @@
 
     try {
       chromeTest.log("( RUN      ) " + testName(currentTest));
+      uncaughtExceptionHandler.setHandler(function(message, e) {
+        if (e !== failureException)
+          chromeTest.fail('uncaught exception: ' + message);
+      });
       currentTest.call();
     } catch (e) {
-      if (e !== failureException)
-        chromeTest.fail('uncaught exception: ' + e);
+      uncaughtExceptionHandler.handle(e.message, e);
     }
   });
 
@@ -250,7 +254,7 @@
   function safeFunctionApply(func, args) {
     try {
       if (func)
-        $Function.apply(func, null, args);
+        return $Function.apply(func, undefined, args);
     } catch (e) {
       var msg = "uncaught exception " + e;
       chromeTest.fail(msg);
@@ -272,11 +276,13 @@
         chromeTest.assertLastError(expectedError);
       }
 
+      var result;
       if (func) {
-        safeFunctionApply(func, arguments);
+        result = safeFunctionApply(func, arguments);
       }
 
       callbackCompleted();
+      return result;
     };
   });
 
@@ -341,6 +347,11 @@
     chromeTest.assertEq(typeof(callback), 'function');
     return userGestures.RunWithoutUserGesture(callback);
   });
+
+  apiFunctions.setHandleRequest('setExceptionHandler', function(callback) {
+    chromeTest.assertEq(typeof(callback), 'function');
+    uncaughtExceptionHandler.setHandler(callback);
+  });
 });
 
 exports.binding = binding.generate();
diff --git a/chrome/renderer/resources/extensions/uncaught_exception_handler.js b/chrome/renderer/resources/extensions/uncaught_exception_handler.js
new file mode 100644
index 0000000..a3709b5
--- /dev/null
+++ b/chrome/renderer/resources/extensions/uncaught_exception_handler.js
@@ -0,0 +1,21 @@
+// 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.
+
+// Handles uncaught exceptions thrown by extensions. By default this is to
+// log an error message, but tests may override this behaviour.
+
+var handler = function(message, e) {
+  console.error(message);
+};
+
+// |message| The message associated with the error.
+// |e|       The object that was thrown.
+exports.handle = function(message, e) {
+  handler(message, e);
+};
+
+// |newHandler| A function which matches |exports.handle|.
+exports.setHandler = function(newHandler) {
+  handler = newHandler;
+};
diff --git a/chrome/renderer/resources/extensions/web_view.js b/chrome/renderer/resources/extensions/web_view.js
index 7267212..3a8627c 100644
--- a/chrome/renderer/resources/extensions/web_view.js
+++ b/chrome/renderer/resources/extensions/web_view.js
@@ -66,6 +66,14 @@
     evt: CreateEvent('webview.onContentLoad'),
     fields: []
   },
+  'contextmenu': {
+    evt: CreateEvent('webview.contextmenu'),
+    cancelable: true,
+    customHandler: function(webViewInternal, event, webViewEvent) {
+      webViewInternal.maybeHandleContextMenu(event, webViewEvent);
+    },
+    fields: ['items']
+  },
   'dialog': {
     cancelable: true,
     customHandler: function(webViewInternal, event, webViewEvent) {
@@ -1186,6 +1194,21 @@
 };
 
 /**
+ * Calls to show contextmenu right away instead of dispatching a 'contextmenu'
+ * event.
+ * This will be overridden in web_view_experimental.js to implement contextmenu
+ * API.
+ * @private
+ */
+WebViewInternal.prototype.maybeHandleContextMenu = function(e, webViewEvent) {
+  var requestId = e.requestId;
+  // Setting |params| = undefined will show the context menu unmodified, hence
+  // the 'contextmenu' API is disabled for stable channel.
+  var params = undefined;
+  WebView.showContextMenu(this.instanceId, requestId, params);
+};
+
+/**
  * Implemented when the experimental API is available.
  * @private
  */
diff --git a/chrome/renderer/resources/extensions/web_view_experimental.js b/chrome/renderer/resources/extensions/web_view_experimental.js
index 1b6a8c0..62b3a24 100644
--- a/chrome/renderer/resources/extensions/web_view_experimental.js
+++ b/chrome/renderer/resources/extensions/web_view_experimental.js
@@ -137,6 +137,45 @@
   );
 };
 
+/** @private */
+WebViewInternal.prototype.maybeHandleContextMenu = function(e, webViewEvent) {
+  var requestId = e.requestId;
+  var self = this;
+  // Construct the event.menu object.
+  var actionTaken = false;
+  var validateCall = function() {
+    var ERROR_MSG_CONTEXT_MENU_ACTION_ALREADY_TAKEN = '<webview>: ' +
+        'An action has already been taken for this "contextmenu" event.';
+
+    if (actionTaken) {
+      throw new Error(ERROR_MSG_CONTEXT_MENU_ACTION_ALREADY_TAKEN);
+    }
+    actionTaken = true;
+  };
+  var menu = {
+    show: function(items) {
+      validateCall();
+      // TODO(lazyboy): WebViewShowContextFunction doesn't do anything useful
+      // with |items|, implement.
+      WebView.showContextMenu(self.instanceId, requestId, items);
+    }
+  };
+  webViewEvent.menu = menu;
+  var webviewNode = this.webviewNode;
+  var defaultPrevented = !webviewNode.dispatchEvent(webViewEvent);
+  if (actionTaken) {
+    return;
+  }
+  if (!defaultPrevented) {
+    actionTaken = true;
+    // The default action is equivalent to just showing the context menu as is.
+    WebView.showContextMenu(self.instanceId, requestId, undefined);
+
+    // TODO(lazyboy): Figure out a way to show warning message only when
+    // listeners are registered for this event.
+  } //  else we will ignore showing the context menu completely.
+};
+
 /**
  * @private
  */
diff --git a/chrome/renderer/resources/extensions/webstore_custom_bindings.js b/chrome/renderer/resources/extensions/webstore_custom_bindings.js
index c31f40f..b720106 100644
--- a/chrome/renderer/resources/extensions/webstore_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/webstore_custom_bindings.js
@@ -84,9 +84,7 @@
   onDownloadProgress: installer.onDownloadProgress
 };
 
-// This must match the name in InstallWebstoreBindings in
-// chrome/renderer/extensions/dispatcher.cc.
-exports.chromeWebstore = chromeWebstore;
+exports.binding = chromeWebstore;
 
 // Called by webstore_bindings.cc.
 exports.onInstallResponse =
diff --git a/chrome/renderer/resources/neterror.css b/chrome/renderer/resources/neterror.css
index 41bffb0..fc2e153 100644
--- a/chrome/renderer/resources/neterror.css
+++ b/chrome/renderer/resources/neterror.css
@@ -2,6 +2,13 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file. */
 
+/*******************************************************************************
+ *
+ * Note:  This is also used by a file in chrome/browser/resources/ssl.  When
+ *        updating this file, make sure nothing in that directory regresses.
+ *
+ ******************************************************************************/
+
 body {
   background-color: #E6E6E6;
   font-family: Helvetica, Arial, sans-serif;
diff --git a/chrome/renderer/resources/neterror.html b/chrome/renderer/resources/neterror.html
index e0eaf7c..a6ba1db 100644
--- a/chrome/renderer/resources/neterror.html
+++ b/chrome/renderer/resources/neterror.html
@@ -21,8 +21,10 @@
         </h1>
         <div id="buttons">
           <button id="reload-button" class="blue-button text-button"
-              onclick="reloadButtonClick(this.url);"
-              jsselect="reloadButton" jsvalues=".url:reloadUrl"
+              onclick="trackClick(this.trackingId);
+                       reloadButtonClick(this.url);"
+              jsselect="reloadButton"
+              jsvalues=".url:reloadUrl; .trackingId:reloadTrackingId"
               jscontent="msg"></button>
           <button id="stale-load-button" class="blue-button text-button"
               onclick="loadStaleButtonClick()"
@@ -49,7 +51,8 @@
               jsdisplay="diagnose"></button>
           <div id="diagnose-frame" class="hidden"></div>
           <form class="suggestions" jsdisplay="searchUrl"
-              jsvalues=".url:searchUrl" onsubmit="return search(this.url)">
+              jsvalues=".url:searchUrl; .trackingId:searchTrackingId"
+              onsubmit="trackClick(this.trackingId); return search(this.url);">
             <div class="suggestion-header" jscontent="searchHeader"></div>
             <div id="search-container">
               <input type="text" name="q" id="search-box"
diff --git a/chrome/renderer/resources/neterror.js b/chrome/renderer/resources/neterror.js
index d1f4c5f..b518a87 100644
--- a/chrome/renderer/resources/neterror.js
+++ b/chrome/renderer/resources/neterror.js
@@ -60,6 +60,23 @@
   return false;
 }
 
+// Use to track clicks on elements generated by the navigation correction
+// service.  If |trackingId| is negative, the element does not come from the
+// correction service.
+function trackClick(trackingId) {
+  // This can't be done with XHRs because XHRs are cancelled on navigation
+  // start, and because these are cross-site requests.
+  if (trackingId >= 0 && errorPageController)
+    errorPageController.trackClick(trackingId);
+}
+
+// Called when an <a> tag generated by the navigation correction service is
+// clicked.  Separate function from trackClick so the resources don't have to
+// be updated if new data is added to jstdata.
+function linkClicked(jstdata) {
+  trackClick(jstdata.trackingId);
+}
+
 // Implements button clicks.  This function is needed during the transition
 // between implementing these in trunk chromium and implementing them in
 // iOS.
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd
index a8f8763..b810508 100644
--- a/chrome/renderer/resources/renderer_resources.grd
+++ b/chrome/renderer/resources/renderer_resources.grd
@@ -96,6 +96,7 @@
         <include name="IDR_TEST_CUSTOM_BINDINGS_JS" file="extensions\test_custom_bindings.js" type="BINDATA" />
         <include name="IDR_TTS_CUSTOM_BINDINGS_JS" file="extensions\tts_custom_bindings.js" type="BINDATA" />
         <include name="IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS" file="extensions\tts_engine_custom_bindings.js" type="BINDATA" />
+        <include name="IDR_UNCAUGHT_EXCEPTION_HANDLER_JS" file="extensions\uncaught_exception_handler.js" type="BINDATA" />
         <include name="IDR_UNLOAD_EVENT_JS" file="extensions\unload_event.js" type="BINDATA" />
         <include name="IDR_UTILS_JS" file="extensions\utils.js" type="BINDATA" />
         <include name="IDR_WINDOW_CONTROLS_JS" file="extensions\window_controls.js" type="BINDATA" />
diff --git a/chrome/renderer/safe_browsing/phishing_classifier.cc b/chrome/renderer/safe_browsing/phishing_classifier.cc
index f48e6c1..3f2e98c 100644
--- a/chrome/renderer/safe_browsing/phishing_classifier.cc
+++ b/chrome/renderer/safe_browsing/phishing_classifier.cc
@@ -118,7 +118,7 @@
   // Check whether the URL is one that we should classify.
   // Currently, we only classify http: URLs that are GET requests.
   GURL url(frame->document().url());
-  if (!url.SchemeIs(content::kHttpScheme)) {
+  if (!url.SchemeIs(url::kHttpScheme)) {
     RunFailureCallback();
     return;
   }
diff --git a/chrome/renderer/security_filter_peer.cc b/chrome/renderer/security_filter_peer.cc
index 5f795f8..408a053 100644
--- a/chrome/renderer/security_filter_peer.cc
+++ b/chrome/renderer/security_filter_peer.cc
@@ -11,11 +11,8 @@
 #include "net/http/http_response_headers.h"
 #include "ui/base/l10n/l10n_util.h"
 
-SecurityFilterPeer::SecurityFilterPeer(
-    webkit_glue::ResourceLoaderBridge* resource_loader_bridge,
-    content::RequestPeer* peer)
-    : original_peer_(peer),
-      resource_loader_bridge_(resource_loader_bridge) {
+SecurityFilterPeer::SecurityFilterPeer(content::RequestPeer* peer)
+    : original_peer_(peer) {
 }
 
 SecurityFilterPeer::~SecurityFilterPeer() {
@@ -46,7 +43,7 @@
       if (ResourceType::IsFrame(resource_type))
         return CreateSecurityFilterPeerForFrame(peer, os_error);
       // Any other content is entirely filtered-out.
-      return new ReplaceContentPeer(NULL, peer, std::string(), std::string());
+      return new ReplaceContentPeer(peer, std::string(), std::string());
     default:
       // For other errors, we use our normal error handling.
       return NULL;
@@ -64,7 +61,7 @@
       "<body style='background-color:#990000;color:white;'>"
       "%s</body></html>",
       l10n_util::GetStringUTF8(IDS_UNSAFE_FRAME_MESSAGE).c_str());
-  return new ReplaceContentPeer(NULL, peer, "text/html", html);
+  return new ReplaceContentPeer(peer, "text/html", html);
 }
 
 void SecurityFilterPeer::OnUploadProgress(uint64 position, uint64 size) {
@@ -133,13 +130,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 // BufferedPeer
 
-BufferedPeer::BufferedPeer(
-    webkit_glue::ResourceLoaderBridge* resource_loader_bridge,
-    content::RequestPeer* peer,
-    const std::string& mime_type)
-    : SecurityFilterPeer(resource_loader_bridge, peer),
-      mime_type_(mime_type) {
-}
+BufferedPeer::BufferedPeer(content::RequestPeer* peer,
+                           const std::string& mime_type)
+    : SecurityFilterPeer(peer), mime_type_(mime_type) {}
 
 BufferedPeer::~BufferedPeer() {
 }
@@ -188,15 +181,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 // ReplaceContentPeer
 
-ReplaceContentPeer::ReplaceContentPeer(
-    webkit_glue::ResourceLoaderBridge* resource_loader_bridge,
-    content::RequestPeer* peer,
-    const std::string& mime_type,
-    const std::string& data)
-    : SecurityFilterPeer(resource_loader_bridge, peer),
+ReplaceContentPeer::ReplaceContentPeer(content::RequestPeer* peer,
+                                       const std::string& mime_type,
+                                       const std::string& data)
+    : SecurityFilterPeer(peer),
       mime_type_(mime_type),
-      data_(data) {
-}
+      data_(data) {}
 
 ReplaceContentPeer::~ReplaceContentPeer() {
 }
diff --git a/chrome/renderer/security_filter_peer.h b/chrome/renderer/security_filter_peer.h
index ca98e18..d9b561c 100644
--- a/chrome/renderer/security_filter_peer.h
+++ b/chrome/renderer/security_filter_peer.h
@@ -9,10 +9,6 @@
 #include "webkit/common/resource_response_info.h"
 #include "webkit/common/resource_type.h"
 
-namespace webkit_glue {
-class ResourceLoaderBridge;
-}
-
 // The SecurityFilterPeer is a proxy to a
 // content::RequestPeer instance.  It is used to pre-process
 // unsafe resources (such as mixed-content resource).
@@ -53,11 +49,9 @@
                                   int64 total_transfer_size) OVERRIDE;
 
  protected:
-  SecurityFilterPeer(webkit_glue::ResourceLoaderBridge* resource_loader_bridge,
-                     content::RequestPeer* peer);
+  explicit SecurityFilterPeer(content::RequestPeer* peer);
 
   content::RequestPeer* original_peer_;
-  webkit_glue::ResourceLoaderBridge* resource_loader_bridge_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(SecurityFilterPeer);
@@ -67,9 +61,7 @@
 // Subclasses should implement DataReady() to process the data as necessary.
 class BufferedPeer : public SecurityFilterPeer {
  public:
-  BufferedPeer(webkit_glue::ResourceLoaderBridge* resource_loader_bridge,
-               content::RequestPeer* peer,
-               const std::string& mime_type);
+  BufferedPeer(content::RequestPeer* peer, const std::string& mime_type);
   virtual ~BufferedPeer();
 
   // content::RequestPeer Implementation.
@@ -104,16 +96,13 @@
 
 // The ReplaceContentPeer cancels the request and serves the provided data as
 // content instead.
-// TODO(jcampan): we do not as of now cancel the request, as we do not have
-// access to the resource_loader_bridge in the SecurityFilterPeer factory
-// method.  For now the resource is still being fetched, but ignored, as once
-// we have provided the replacement content, the associated pending request
+// TODO(jcampan): For now the resource is still being fetched, but ignored, as
+// once we have provided the replacement content, the associated pending request
 // in ResourceDispatcher is removed and further OnReceived* notifications are
 // ignored.
 class ReplaceContentPeer : public SecurityFilterPeer {
  public:
-  ReplaceContentPeer(webkit_glue::ResourceLoaderBridge* resource_loader_bridge,
-                     content::RequestPeer* peer,
+  ReplaceContentPeer(content::RequestPeer* peer,
                      const std::string& mime_type,
                      const std::string& data);
   virtual ~ReplaceContentPeer();
diff --git a/chrome/renderer/static_v8_external_string_resource.cc b/chrome/renderer/static_v8_external_string_resource.cc
deleted file mode 100644
index 4395ffc..0000000
--- a/chrome/renderer/static_v8_external_string_resource.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/renderer/static_v8_external_string_resource.h"
-
-StaticV8ExternalAsciiStringResource::StaticV8ExternalAsciiStringResource(
-    const base::StringPiece& buffer)
-    : buffer_(buffer) {
-}
-
-StaticV8ExternalAsciiStringResource::~StaticV8ExternalAsciiStringResource() {
-}
-
-const char* StaticV8ExternalAsciiStringResource::data() const {
-  return buffer_.data();
-}
-
-size_t StaticV8ExternalAsciiStringResource::length() const {
-  return buffer_.length();
-}
diff --git a/chrome/renderer/static_v8_external_string_resource.h b/chrome/renderer/static_v8_external_string_resource.h
deleted file mode 100644
index 6459622..0000000
--- a/chrome/renderer/static_v8_external_string_resource.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_RENDERER_EXTENSIONS_STATIC_V8_EXTERNAL_STRING_RESOURCE_H_
-#define CHROME_RENDERER_EXTENSIONS_STATIC_V8_EXTERNAL_STRING_RESOURCE_H_
-
-#include "base/compiler_specific.h"
-#include "base/strings/string_piece.h"
-#include "v8/include/v8.h"
-
-// A very simple implementation of v8::ExternalAsciiStringResource that just
-// wraps a buffer. The buffer must outlive the v8 runtime instance this resource
-// is used in.
-class StaticV8ExternalAsciiStringResource
-    : public v8::String::ExternalAsciiStringResource {
- public:
-  explicit StaticV8ExternalAsciiStringResource(const base::StringPiece& buffer);
-  virtual ~StaticV8ExternalAsciiStringResource();
-
-  virtual const char* data() const OVERRIDE;
-  virtual size_t length() const OVERRIDE;
-
- private:
-  base::StringPiece buffer_;
-};
-
-#endif // CHROME_RENDERER_EXTENSIONS_STATIC_V8_EXTERNAL_STRING_RESOURCE_H_
diff --git a/chrome/test/base/chrome_render_view_test.cc b/chrome/test/base/chrome_render_view_test.cc
index a1ddd2f..92425b1 100644
--- a/chrome/test/base/chrome_render_view_test.cc
+++ b/chrome/test/base/chrome_render_view_test.cc
@@ -9,7 +9,7 @@
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/common/render_messages.h"
 #include "chrome/renderer/chrome_content_renderer_client.h"
-#include "chrome/renderer/extensions/dispatcher.h"
+#include "chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h"
 #include "chrome/renderer/spellchecker/spellcheck.h"
 #include "chrome/test/base/chrome_unit_test_suite.h"
 #include "components/autofill/content/renderer/autofill_agent.h"
@@ -21,6 +21,7 @@
 #include "content/public/renderer/render_view.h"
 #include "extensions/browser/extension_function_dispatcher.h"
 #include "extensions/common/extension.h"
+#include "extensions/renderer/dispatcher.h"
 #include "extensions/renderer/event_bindings.h"
 #include "third_party/WebKit/public/platform/WebURLRequest.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
@@ -93,8 +94,11 @@
 
 content::ContentRendererClient*
     ChromeRenderViewTest::CreateContentRendererClient() {
+  extension_dispatcher_delegate_.reset(
+      new ChromeExtensionsDispatcherDelegate());
   ChromeContentRendererClient* client = new ChromeContentRendererClient();
-  client->SetExtensionDispatcherForTest(new extensions::Dispatcher);
+  client->SetExtensionDispatcherForTest(
+      new extensions::Dispatcher(extension_dispatcher_delegate_.get()));
 #if defined(ENABLE_SPELLCHECK)
   client->SetSpellcheck(new SpellCheck());
 #endif
diff --git a/chrome/test/base/chrome_render_view_test.h b/chrome/test/base/chrome_render_view_test.h
index 5c4824f..19ee8d2 100644
--- a/chrome/test/base/chrome_render_view_test.h
+++ b/chrome/test/base/chrome_render_view_test.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "base/memory/scoped_ptr.h"
 #include "chrome/renderer/chrome_mock_render_thread.h"
 #include "content/public/test/render_view_test.h"
 
@@ -16,6 +17,10 @@
 class TestPasswordGenerationAgent;
 }
 
+namespace extensions {
+class DispatcherDelegate;
+}
+
 class ChromeRenderViewTest : public content::RenderViewTest {
  public:
   ChromeRenderViewTest();
@@ -30,6 +35,8 @@
   virtual content::ContentRendererClient*
       CreateContentRendererClient() OVERRIDE;
 
+  scoped_ptr<extensions::DispatcherDelegate> extension_dispatcher_delegate_;
+
   autofill::TestPasswordAutofillAgent* password_autofill_;
   autofill::TestPasswordGenerationAgent* password_generation_;
   autofill::AutofillAgent* autofill_agent_;
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc
index 5b8c7c7..82c0706 100644
--- a/chrome/test/base/in_process_browser_test.cc
+++ b/chrome/test/base/in_process_browser_test.cc
@@ -150,6 +150,13 @@
   DCHECK(!g_browser_process);
 
   CommandLine* command_line = CommandLine::ForCurrentProcess();
+
+  // Auto-reload breaks many browser tests, which assume error pages won't be
+  // reloaded out from under them. Tests that expect or desire this behavior can
+  // append switches::kEnableOfflineAutoReload, which will override the disable
+  // here.
+  command_line->AppendSwitch(switches::kDisableOfflineAutoReload);
+
   // Allow subclasses to change the command line before running any tests.
   SetUpCommandLine(command_line);
   // Add command line arguments that are used by all InProcessBrowserTests.
diff --git a/chrome/test/base/interactive_test_utils_win.cc b/chrome/test/base/interactive_test_utils_win.cc
index 3c97383..4858cf6 100644
--- a/chrome/test/base/interactive_test_utils_win.cc
+++ b/chrome/test/base/interactive_test_utils_win.cc
@@ -9,43 +9,32 @@
 #include "base/path_service.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
+#include "chrome/browser/ui/host_desktop.h"
+#include "chrome/test/base/interactive_test_utils_aura.h"
+#include "ui/aura/window_tree_host.h"
 #include "ui/base/test/ui_controls.h"
 #include "ui/base/win/foreground_helper.h"
 #include "ui/views/focus/focus_manager.h"
 
-#if defined(USE_AURA)
-#include "chrome/browser/ui/host_desktop.h"
-#include "chrome/test/base/interactive_test_utils_aura.h"
-#include "ui/aura/window_tree_host.h"
-#endif
-
 namespace ui_test_utils {
 
 void HideNativeWindow(gfx::NativeWindow window) {
-#if defined(USE_AURA)
   if (chrome::GetHostDesktopTypeForNativeWindow(window) ==
       chrome::HOST_DESKTOP_TYPE_ASH) {
     HideNativeWindowAura(window);
     return;
   }
   HWND hwnd = window->GetHost()->GetAcceleratedWidget();
-#else
-  HWND hwnd = window;
-#endif
   ::ShowWindow(hwnd, SW_HIDE);
 }
 
 bool ShowAndFocusNativeWindow(gfx::NativeWindow window) {
-#if defined(USE_AURA)
   if (chrome::GetHostDesktopTypeForNativeWindow(window) ==
       chrome::HOST_DESKTOP_TYPE_ASH)
     ShowAndFocusNativeWindowAura(window);
   window->Show();
   // Always make sure the window hosting ash is visible and focused.
   HWND hwnd = window->GetHost()->GetAcceleratedWidget();
-#else
-  HWND hwnd = window;
-#endif
 
   ::ShowWindow(hwnd, SW_SHOW);
 
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc
index c15e41b..390d9ef 100644
--- a/chrome/test/base/testing_browser_process.cc
+++ b/chrome/test/base/testing_browser_process.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/extensions/chrome_extensions_browser_client.h"
 #include "chrome/browser/printing/print_job_manager.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
 #include "chrome/test/base/testing_browser_process_platform_part.h"
 #include "content/public/browser/notification_service.h"
 #include "net/url_request/url_request_context_getter.h"
@@ -340,15 +339,6 @@
   return NULL;
 }
 
-BookmarkPromptController* TestingBrowserProcess::bookmark_prompt_controller() {
-#if defined(OS_IOS)
-  NOTIMPLEMENTED();
-  return NULL;
-#else
-  return bookmark_prompt_controller_.get();
-#endif
-}
-
 MediaFileSystemRegistry* TestingBrowserProcess::media_file_system_registry() {
 #if defined(OS_IOS) || defined(OS_ANDROID)
   NOTIMPLEMENTED();
@@ -370,13 +360,6 @@
 }
 #endif
 
-void TestingBrowserProcess::SetBookmarkPromptController(
-    BookmarkPromptController* controller) {
-#if !defined(OS_IOS)
-  bookmark_prompt_controller_.reset(controller);
-#endif
-}
-
 void TestingBrowserProcess::SetSystemRequestContext(
     net::URLRequestContextGetter* context_getter) {
   system_request_context_ = context_getter;
diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h
index bcd9d0b..f15227a 100644
--- a/chrome/test/base/testing_browser_process.h
+++ b/chrome/test/base/testing_browser_process.h
@@ -111,7 +111,6 @@
   virtual CRLSetFetcher* crl_set_fetcher() OVERRIDE;
   virtual component_updater::PnaclComponentInstaller*
       pnacl_component_installer() OVERRIDE;
-  virtual BookmarkPromptController* bookmark_prompt_controller() OVERRIDE;
   virtual MediaFileSystemRegistry* media_file_system_registry() OVERRIDE;
   virtual bool created_local_state() const OVERRIDE;
 
@@ -126,7 +125,6 @@
   void SetIOThread(IOThread* io_thread);
   void SetBrowserPolicyConnector(policy::BrowserPolicyConnector* connector);
   void SetSafeBrowsingService(SafeBrowsingService* sb_service);
-  void SetBookmarkPromptController(BookmarkPromptController* controller);
   void SetSystemRequestContext(net::URLRequestContextGetter* context_getter);
 
  private:
@@ -157,7 +155,6 @@
 
   scoped_ptr<prerender::PrerenderTracker> prerender_tracker_;
   scoped_refptr<SafeBrowsingService> sb_service_;
-  scoped_ptr<BookmarkPromptController> bookmark_prompt_controller_;
 #endif  // !defined(OS_IOS)
 
 #if !defined(OS_IOS) && !defined(OS_ANDROID)
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index 5c423d2..e9eda9d 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -28,6 +28,7 @@
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
 #include "chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h"
+#include "chrome/browser/guest_view/guest_view_manager.h"
 #include "chrome/browser/history/history_backend.h"
 #include "chrome/browser/history/history_db_task.h"
 #include "chrome/browser/history/history_service.h"
@@ -827,6 +828,11 @@
   return ChromeGeolocationPermissionContextFactory::GetForProfile(this);
 }
 
+content::BrowserPluginGuestManagerDelegate*
+    TestingProfile::GetGuestManagerDelegate() {
+  return GuestViewManager::FromBrowserContext(this);
+}
+
 std::wstring TestingProfile::GetName() {
   return std::wstring();
 }
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h
index 2644b99..88d69b0 100644
--- a/chrome/test/base/testing_profile.h
+++ b/chrome/test/base/testing_profile.h
@@ -222,6 +222,8 @@
   virtual content::ResourceContext* GetResourceContext() OVERRIDE;
   virtual content::GeolocationPermissionContext*
       GetGeolocationPermissionContext() OVERRIDE;
+  virtual content::BrowserPluginGuestManagerDelegate*
+      GetGuestManagerDelegate() OVERRIDE;
   virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
 
   virtual TestingProfile* AsTestingProfile() OVERRIDE;
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc
index 39ab299..5c23911 100644
--- a/chrome/test/base/ui_test_utils.cc
+++ b/chrome/test/base/ui_test_utils.cc
@@ -64,7 +64,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/geoposition.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/download_test_observer.h"
diff --git a/chrome/test/base/v8_unit_test.cc b/chrome/test/base/v8_unit_test.cc
index 4e0c307..694c982 100644
--- a/chrome/test/base/v8_unit_test.cc
+++ b/chrome/test/base/v8_unit_test.cc
@@ -45,13 +45,12 @@
 
 }  // namespace
 
-V8UnitTest::V8UnitTest()
-    : isolate_(v8::Isolate::GetCurrent()),
-      handle_scope_(isolate_) {
+V8UnitTest::V8UnitTest() : handle_scope_(isolate_scope_.isolate()) {
   InitPathsAndLibraries();
 }
 
-V8UnitTest::~V8UnitTest() {}
+V8UnitTest::~V8UnitTest() {
+}
 
 void V8UnitTest::AddLibrary(const base::FilePath& library_path) {
   user_libraries_.push_back(library_path);
@@ -67,8 +66,9 @@
     base::FilePath library_file(*user_libraries_iterator);
     if (!user_libraries_iterator->IsAbsolute()) {
       base::FilePath gen_file = gen_test_data_directory.Append(library_file);
-      library_file = base::PathExists(gen_file) ? gen_file :
-          test_data_directory.Append(*user_libraries_iterator);
+      library_file = base::PathExists(gen_file)
+                         ? gen_file
+                         : test_data_directory.Append(*user_libraries_iterator);
     }
     library_file = base::MakeAbsoluteFilePath(library_file);
     if (!base::ReadFileToString(library_file, &library_content)) {
@@ -82,21 +82,21 @@
   return true;
 }
 
-bool V8UnitTest::RunJavascriptTestF(
-    const std::string& testFixture, const std::string& testName) {
+bool V8UnitTest::RunJavascriptTestF(const std::string& testFixture,
+                                    const std::string& testName) {
   had_errors = false;
   testResult_ok = false;
   std::string test_js;
   if (!ExecuteJavascriptLibraries())
     return false;
 
-  v8::HandleScope handle_scope(isolate_);
+  v8::HandleScope handle_scope(isolate());
   v8::Local<v8::Context> context =
-      v8::Local<v8::Context>::New(isolate_, context_);
+      v8::Local<v8::Context>::New(isolate(), context_);
   v8::Context::Scope context_scope(context);
 
   v8::Handle<v8::Value> functionProperty =
-      context->Global()->Get(v8::String::NewFromUtf8(isolate_, "runTest"));
+      context->Global()->Get(v8::String::NewFromUtf8(isolate(), "runTest"));
   EXPECT_FALSE(functionProperty.IsEmpty());
   if (::testing::Test::HasNonfatalFailure())
     return false;
@@ -106,22 +106,20 @@
   v8::Handle<v8::Function> function =
       v8::Handle<v8::Function>::Cast(functionProperty);
 
-  v8::Local<v8::Array> params = v8::Array::New(isolate_);
+  v8::Local<v8::Array> params = v8::Array::New(isolate());
   params->Set(0,
-              v8::String::NewFromUtf8(isolate_,
+              v8::String::NewFromUtf8(isolate(),
                                       testFixture.data(),
                                       v8::String::kNormalString,
                                       testFixture.size()));
   params->Set(1,
-              v8::String::NewFromUtf8(isolate_,
+              v8::String::NewFromUtf8(isolate(),
                                       testName.data(),
                                       v8::String::kNormalString,
                                       testName.size()));
   v8::Handle<v8::Value> args[] = {
-    v8::Boolean::New(isolate_, false),
-    v8::String::NewFromUtf8(isolate_, "RUN_TEST_F"),
-    params
-  };
+      v8::Boolean::New(isolate(), false),
+      v8::String::NewFromUtf8(isolate(), "RUN_TEST_F"), params};
 
   v8::TryCatch try_catch;
   v8::Handle<v8::Value> result = function->Call(context->Global(), 3, args);
@@ -137,8 +135,8 @@
 void V8UnitTest::InitPathsAndLibraries() {
   ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory));
   test_data_directory = test_data_directory.AppendASCII("webui");
-  ASSERT_TRUE(PathService::Get(chrome::DIR_GEN_TEST_DATA,
-                               &gen_test_data_directory));
+  ASSERT_TRUE(
+      PathService::Get(chrome::DIR_GEN_TEST_DATA, &gen_test_data_directory));
 
   base::FilePath mockPath;
   ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &mockPath));
@@ -164,57 +162,57 @@
 }
 
 void V8UnitTest::SetUp() {
-  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_);
-  v8::Handle<v8::String> logString = v8::String::NewFromUtf8(isolate_, "log");
+  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate());
+  v8::Handle<v8::String> logString = v8::String::NewFromUtf8(isolate(), "log");
   v8::Handle<v8::FunctionTemplate> logFunction =
-      v8::FunctionTemplate::New(isolate_, &V8UnitTest::Log);
+      v8::FunctionTemplate::New(isolate(), &V8UnitTest::Log);
   global->Set(logString, logFunction);
 
   // Set up chrome object for chrome.send().
-  v8::Handle<v8::ObjectTemplate> chrome = v8::ObjectTemplate::New(isolate_);
-  global->Set(v8::String::NewFromUtf8(isolate_, "chrome"), chrome);
-  chrome->Set(v8::String::NewFromUtf8(isolate_, "send"),
-              v8::FunctionTemplate::New(isolate_, &V8UnitTest::ChromeSend));
+  v8::Handle<v8::ObjectTemplate> chrome = v8::ObjectTemplate::New(isolate());
+  global->Set(v8::String::NewFromUtf8(isolate(), "chrome"), chrome);
+  chrome->Set(v8::String::NewFromUtf8(isolate(), "send"),
+              v8::FunctionTemplate::New(isolate(), &V8UnitTest::ChromeSend));
 
   // Set up console object for console.log(), etc.
-  v8::Handle<v8::ObjectTemplate> console = v8::ObjectTemplate::New(isolate_);
-  global->Set(v8::String::NewFromUtf8(isolate_, "console"), console);
+  v8::Handle<v8::ObjectTemplate> console = v8::ObjectTemplate::New(isolate());
+  global->Set(v8::String::NewFromUtf8(isolate(), "console"), console);
   console->Set(logString, logFunction);
-  console->Set(v8::String::NewFromUtf8(isolate_, "info"), logFunction);
-  console->Set(v8::String::NewFromUtf8(isolate_, "warn"), logFunction);
-  console->Set(v8::String::NewFromUtf8(isolate_, "error"),
-               v8::FunctionTemplate::New(isolate_, &V8UnitTest::Error));
+  console->Set(v8::String::NewFromUtf8(isolate(), "info"), logFunction);
+  console->Set(v8::String::NewFromUtf8(isolate(), "warn"), logFunction);
+  console->Set(v8::String::NewFromUtf8(isolate(), "error"),
+               v8::FunctionTemplate::New(isolate(), &V8UnitTest::Error));
 
-  context_.Reset(isolate_, v8::Context::New(isolate_, NULL, global));
+  context_.Reset(isolate(), v8::Context::New(isolate(), NULL, global));
 }
 
 void V8UnitTest::SetGlobalStringVar(const std::string& var_name,
                                     const std::string& value) {
   v8::Local<v8::Context> context =
-      v8::Local<v8::Context>::New(isolate_, context_);
+      v8::Local<v8::Context>::New(isolate(), context_);
   v8::Context::Scope context_scope(context);
   context->Global()->Set(
-      v8::String::NewFromUtf8(isolate_,
+      v8::String::NewFromUtf8(isolate(),
                               var_name.c_str(),
                               v8::String::kNormalString,
                               var_name.length()),
       v8::String::NewFromUtf8(
-          isolate_, value.c_str(), v8::String::kNormalString, value.length()));
+          isolate(), value.c_str(), v8::String::kNormalString, value.length()));
 }
 
 void V8UnitTest::ExecuteScriptInContext(const base::StringPiece& script_source,
                                         const base::StringPiece& script_name) {
-  v8::HandleScope handle_scope(isolate_);
+  v8::HandleScope handle_scope(isolate());
   v8::Local<v8::Context> context =
-      v8::Local<v8::Context>::New(isolate_, context_);
+      v8::Local<v8::Context>::New(isolate(), context_);
   v8::Context::Scope context_scope(context);
   v8::Handle<v8::String> source =
-      v8::String::NewFromUtf8(isolate_,
+      v8::String::NewFromUtf8(isolate(),
                               script_source.data(),
                               v8::String::kNormalString,
                               script_source.size());
   v8::Handle<v8::String> name =
-      v8::String::NewFromUtf8(isolate_,
+      v8::String::NewFromUtf8(isolate(),
                               script_name.data(),
                               v8::String::kNormalString,
                               script_name.size());
@@ -251,13 +249,13 @@
 }
 
 void V8UnitTest::TestFunction(const std::string& function_name) {
-  v8::HandleScope handle_scope(isolate_);
+  v8::HandleScope handle_scope(isolate());
   v8::Local<v8::Context> context =
-      v8::Local<v8::Context>::New(isolate_, context_);
+      v8::Local<v8::Context>::New(isolate(), context_);
   v8::Context::Scope context_scope(context);
 
   v8::Handle<v8::Value> functionProperty = context->Global()->Get(
-      v8::String::NewFromUtf8(isolate_, function_name.c_str()));
+      v8::String::NewFromUtf8(isolate(), function_name.c_str()));
   ASSERT_FALSE(functionProperty.IsEmpty());
   ASSERT_TRUE(functionProperty->IsFunction());
   v8::Handle<v8::Function> function =
diff --git a/chrome/test/base/v8_unit_test.h b/chrome/test/base/v8_unit_test.h
index 7d64b84..4b056d3 100644
--- a/chrome/test/base/v8_unit_test.h
+++ b/chrome/test/base/v8_unit_test.h
@@ -68,13 +68,35 @@
   static void ChromeSend(const v8::FunctionCallbackInfo<v8::Value>& args);
 
  private:
+  // A helper class to ensure that the lifetimes of the Isolate and the
+  // HandleScope are correctly nested.
+  class IsolateScope {
+   public:
+    IsolateScope() : isolate_(v8::Isolate::New()) { isolate_->Enter(); }
+
+    ~IsolateScope() {
+      isolate_->Exit();
+      isolate_->Dispose();
+    }
+
+    v8::Isolate* isolate() const { return isolate_; }
+
+   private:
+    v8::Isolate* isolate_;
+
+    DISALLOW_COPY_AND_ASSIGN(IsolateScope);
+  };
+
+  // A handy shortcut.
+  v8::Isolate* isolate() const { return isolate_scope_.isolate(); }
+
   // Executes all added javascript libraries. Returns true if no errors.
   bool ExecuteJavascriptLibraries();
 
   // Initializes paths and libraries.
   void InitPathsAndLibraries();
 
-  v8::Isolate* isolate_;
+  IsolateScope isolate_scope_;
 
   // Handle scope that is used throughout the life of this class.
   v8::HandleScope handle_scope_;
diff --git a/chrome/test/base/view_event_test_base.cc b/chrome/test/base/view_event_test_base.cc
index aae31d9..bdba76a 100644
--- a/chrome/test/base/view_event_test_base.cc
+++ b/chrome/test/base/view_event_test_base.cc
@@ -134,7 +134,7 @@
   context = ash::Shell::GetPrimaryRootWindow();
   context->GetHost()->Show();
 #endif  // !OS_WIN
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
 #elif defined(USE_AURA)
   // Instead of using the ash shell, use an AuraTestHelper to create and manage
   // the test screen.
diff --git a/chrome/test/base/web_ui_browsertest.cc b/chrome/test/base/web_ui_browsertest.cc
index 36e5557..1e07c09 100644
--- a/chrome/test/base/web_ui_browsertest.cc
+++ b/chrome/test/base/web_ui_browsertest.cc
@@ -277,9 +277,8 @@
 
  private:
   // ChromeContentBrowserClient implementation:
-  virtual content::WebContentsViewPort* OverrideCreateWebContentsView(
-      content::WebContents* web_contents,
-      content::RenderViewHostDelegateView** view) OVERRIDE {
+  virtual content::WebContentsViewDelegate* GetWebContentsViewDelegate(
+      content::WebContents* web_contents) OVERRIDE {
     preview_dialog_ = web_contents;
     observer_.reset(new WebUIJsInjectionReadyObserver(
         preview_dialog_, browser_test_, preload_test_fixture_,
diff --git a/chrome/test/chromedriver/chrome/version.cc b/chrome/test/chromedriver/chrome/version.cc
index 06ba742..7751755 100644
--- a/chrome/test/chromedriver/chrome/version.cc
+++ b/chrome/test/chromedriver/chrome/version.cc
@@ -9,7 +9,7 @@
 namespace {
 
 // This variable must be able to be found and parsed by the upload script.
-const int kMinimumSupportedChromeVersion[] = {33, 0, 1751, 0};
+const int kMinimumSupportedChromeVersion[] = {33, 0, 1750, 0};
 
 }  // namespace
 
diff --git a/chrome/test/chromedriver/chrome_launcher.cc b/chrome/test/chromedriver/chrome_launcher.cc
index ffc2428..24037f5 100644
--- a/chrome/test/chromedriver/chrome_launcher.cc
+++ b/chrome/test/chromedriver/chrome_launcher.cc
@@ -40,6 +40,7 @@
 #include "chrome/test/chromedriver/chrome/web_view.h"
 #include "chrome/test/chromedriver/net/port_server.h"
 #include "chrome/test/chromedriver/net/url_request_context_getter.h"
+#include "crypto/rsa_private_key.h"
 #include "crypto/sha2.h"
 #include "third_party/zlib/google/zip.h"
 
@@ -496,15 +497,37 @@
   if (!base::Base64Decode(extension_base64, &decoded_extension))
     return Status(kUnknownError, "cannot base64 decode");
 
-  // Get extension's ID from public key in crx file.
-  // Assumes crx v2. See http://developer.chrome.com/extensions/crx.html.
-  std::string key_len_str = decoded_extension.substr(8, 4);
-  if (key_len_str.size() != 4)
-    return Status(kUnknownError, "cannot extract public key length");
-  uint32 key_len = *reinterpret_cast<const uint32*>(key_len_str.c_str());
-  std::string public_key = decoded_extension.substr(16, key_len);
-  if (key_len != public_key.size())
-    return Status(kUnknownError, "invalid public key length");
+  // If the file is a crx file, extract the extension's ID from its public key.
+  // Otherwise generate a random public key and use its derived extension ID.
+  std::string public_key;
+  std::string magic_header = decoded_extension.substr(0, 4);
+  if (magic_header.size() != 4)
+    return Status(kUnknownError, "cannot extract magic number");
+
+  const bool is_crx_file = magic_header == "Cr24";
+
+  if (is_crx_file) {
+    // Assume a CRX v2 file - see https://developer.chrome.com/extensions/crx.
+    std::string key_len_str = decoded_extension.substr(8, 4);
+    if (key_len_str.size() != 4)
+      return Status(kUnknownError, "cannot extract public key length");
+    uint32 key_len = *reinterpret_cast<const uint32*>(key_len_str.c_str());
+    public_key = decoded_extension.substr(16, key_len);
+    if (key_len != public_key.size())
+      return Status(kUnknownError, "invalid public key length");
+  } else {
+    // Not a CRX file. Generate RSA keypair to get a valid extension id.
+    scoped_ptr<crypto::RSAPrivateKey> key_pair(
+        crypto::RSAPrivateKey::Create(2048));
+    if (!key_pair)
+      return Status(kUnknownError, "cannot generate RSA key pair");
+    std::vector<uint8> public_key_vector;
+    if (!key_pair->ExportPublicKey(&public_key_vector))
+      return Status(kUnknownError, "cannot extract public key");
+    public_key =
+        std::string(reinterpret_cast<char*>(&public_key_vector.front()),
+                    public_key_vector.size());
+  }
   std::string public_key_base64;
   base::Base64Encode(public_key, &public_key_base64);
   std::string id = GenerateExtensionId(public_key);
@@ -543,13 +566,15 @@
       return Status(kUnknownError, "'key' in manifest is not base64 encoded");
     std::string manifest_id = GenerateExtensionId(manifest_key);
     if (id != manifest_id) {
-      LOG(WARNING)
-          << "Public key in crx header is different from key in manifest"
-          << std::endl << "key from header:   " << public_key_base64
-          << std::endl << "key from manifest: " << manifest_key_base64
-          << std::endl << "generated extension id from header key:   " << id
-          << std::endl << "generated extension id from manifest key: "
-          << manifest_id;
+      if (is_crx_file) {
+        LOG(WARNING)
+            << "Public key in crx header is different from key in manifest"
+            << std::endl << "key from header:   " << public_key_base64
+            << std::endl << "key from manifest: " << manifest_key_base64
+            << std::endl << "generated extension id from header key:   " << id
+            << std::endl << "generated extension id from manifest key: "
+            << manifest_id;
+      }
       id = manifest_id;
     }
   } else {
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index d5ee27e..bce431b 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -768,12 +768,17 @@
     return base64.b64encode(open(ext_path, 'rb').read())
 
   def testExtensionsInstall(self):
-    """Checks that chromedriver can take the extensions."""
+    """Checks that chromedriver can take the extensions in crx format."""
     crx_1 = os.path.join(_TEST_DATA_DIR, 'ext_test_1.crx')
     crx_2 = os.path.join(_TEST_DATA_DIR, 'ext_test_2.crx')
     self.CreateDriver(chrome_extensions=[self._PackExtension(crx_1),
                                          self._PackExtension(crx_2)])
 
+  def testExtensionsInstallZip(self):
+    """Checks that chromedriver can take the extensions in zip format."""
+    zip_1 = os.path.join(_TEST_DATA_DIR, 'ext_test_1.zip')
+    self.CreateDriver(chrome_extensions=[self._PackExtension(zip_1)])
+
   def testWaitsForExtensionToLoad(self):
     did_load_event = threading.Event()
     server = webserver.SyncWebServer()
diff --git a/chrome/test/nacl/nacl_browsertest.cc b/chrome/test/nacl/nacl_browsertest.cc
index cd31331..b9d11b5 100644
--- a/chrome/test/nacl/nacl_browsertest.cc
+++ b/chrome/test/nacl/nacl_browsertest.cc
@@ -37,25 +37,11 @@
   RunLoadTest(FILE_PATH_LITERAL("nacl_load_test.html"));
 })
 
-// ASan does not work with libc-free context, so disable the test.
-#if defined(OS_LINUX) && !defined(ADDRESS_SANITIZER)
-#  define MAYBE_NonSfiMessaging NonSfiMessaging
-#else
-#  define MAYBE_NonSfiMessaging DISABLED_NonSfiMessaging
-#endif
-
-IN_PROC_BROWSER_TEST_F(NaClBrowserTestNonSfiMode, MAYBE_NonSfiMessaging) {
+IN_PROC_BROWSER_TEST_F(NaClBrowserTestNonSfiMode, MAYBE_NONSFI(Messaging)) {
   RunLoadTest(FILE_PATH_LITERAL("libc_free.html"));
 }
 
-// ASan does not work with libc-free context, so disable the test.
-#if defined(OS_LINUX) && !defined(ADDRESS_SANITIZER)
-#  define MAYBE_NonSfiIrt NonSfiIrt
-#else
-#  define MAYBE_NonSfiIrt DISABLED_NonSfiIrt
-#endif
-
-IN_PROC_BROWSER_TEST_F(NaClBrowserTestNonSfiMode, MAYBE_NonSfiIrt) {
+IN_PROC_BROWSER_TEST_F(NaClBrowserTestNonSfiMode, MAYBE_NONSFI(Irt)) {
   RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_test.html"));
 }
 
@@ -129,34 +115,31 @@
 IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, ManifestFile) {
   RunNaClIntegrationTest(FILE_PATH_LITERAL("pm_manifest_file_test.html"));
 }
-IN_PROC_BROWSER_TEST_F(NaClBrowserTestGLibc, ManifestFile) {
+IN_PROC_BROWSER_TEST_F(NaClBrowserTestGLibc, MAYBE_GLIBC(ManifestFile)) {
   RunNaClIntegrationTest(FILE_PATH_LITERAL("pm_manifest_file_test.html"));
 }
 IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, PreInitManifestFile) {
   RunNaClIntegrationTest(FILE_PATH_LITERAL(
       "pm_pre_init_manifest_file_test.html"));
 }
-IN_PROC_BROWSER_TEST_F(NaClBrowserTestGLibc, PreInitManifestFile) {
+IN_PROC_BROWSER_TEST_F(NaClBrowserTestGLibc,
+                       MAYBE_GLIBC(PreInitManifestFile)) {
   RunNaClIntegrationTest(FILE_PATH_LITERAL(
       "pm_pre_init_manifest_file_test.html"));
 }
 IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, IrtManifestFile) {
   RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_manifest_file_test.html"));
 }
-
-// The NonSFI test is currently available only on linux-x86-32
-// architecture.
-#if defined(OS_LINUX) && defined(ARCH_CPU_X86)
-#define MAYBE_NONSFI(test_name) test_name
-#else
-#define MAYBE_NONSFI(test_name) DISABLED_##test_name
-#endif
+IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclNonSfi,
+                       MAYBE_PNACL_NONSFI(IrtManifestFile)) {
+  RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_manifest_file_test.html"));
+}
 
 IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, IrtException) {
   RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_exception_test.html"));
 }
 IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclNonSfi,
-                       MAYBE_NONSFI(IrtException)) {
+                       MAYBE_PNACL_NONSFI(IrtException)) {
   RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_exception_test.html"));
 }
 
diff --git a/chrome/test/nacl/nacl_browsertest_util.h b/chrome/test/nacl/nacl_browsertest_util.h
index 22fd852..bfe8709 100644
--- a/chrome/test/nacl/nacl_browsertest_util.h
+++ b/chrome/test/nacl/nacl_browsertest_util.h
@@ -125,8 +125,8 @@
 
 class NaClBrowserTestPnaclNonSfi : public NaClBrowserTestBase {
  public:
-  virtual base::FilePath::StringType Variant() OVERRIDE;
   virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE;
+  virtual base::FilePath::StringType Variant() OVERRIDE;
 };
 
 // Class used to test that when --disable-pnacl is specified the PNaCl mime
@@ -159,31 +159,40 @@
 // and sometimes time out.  Disable until it is made faster:
 // https://code.google.com/p/chromium/issues/detail?id=177555
 #if (defined(OS_WIN) && !defined(NDEBUG))
-#define MAYBE_PNACL(test_name) DISABLED_##test_name
+#  define MAYBE_PNACL(test_name) DISABLED_##test_name
 #else
-#define MAYBE_PNACL(test_name) test_name
+#  define MAYBE_PNACL(test_name) test_name
 #endif
 
-#if defined(ARCH_CPU_ARM_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY)
+// NaCl glibc tests are included for x86 only, as there is no glibc support
+// for other architectures (ARM/MIPS).
+#if defined(ARCH_CPU_X86_FAMILY)
+#  define MAYBE_GLIBC(test_name) test_name
+#else
+#  define MAYBE_GLIBC(test_name) DISABLED_##test_name
+#endif
 
-// There is no support for Glibc on ARM and MIPS NaCl.
+// ASan does not work with libc-free context, so disable the test.
+#if defined(OS_LINUX) && !defined(ADDRESS_SANITIZER)
+#  define MAYBE_NONSFI(test_case) test_case
+#else
+#  define MAYBE_NONSFI(test_case) DISABLED_##test_case
+#endif
+
+// Currently, translation from pexe to non-sfi nexe is supported only for
+// x86-32 binary.
+#if defined(OS_LINUX) && defined(ARCH_CPU_X86)
+#  define MAYBE_PNACL_NONSFI(test_case) test_case
+#else
+#  define MAYBE_PNACL_NONSFI(test_case) DISABLED_##test_case
+#endif
+
 #define NACL_BROWSER_TEST_F(suite, name, body) \
 IN_PROC_BROWSER_TEST_F(suite##Newlib, name) \
 body \
-IN_PROC_BROWSER_TEST_F(suite##Pnacl, MAYBE_PNACL(name)) \
-body
-
-#else
-
-// Otherwise, we have Glibc, Newlib and Pnacl tests
-#define NACL_BROWSER_TEST_F(suite, name, body) \
-IN_PROC_BROWSER_TEST_F(suite##Newlib, name) \
-body \
-IN_PROC_BROWSER_TEST_F(suite##GLibc, name) \
+IN_PROC_BROWSER_TEST_F(suite##GLibc, MAYBE_GLIBC(name)) \
 body \
 IN_PROC_BROWSER_TEST_F(suite##Pnacl, MAYBE_PNACL(name)) \
 body
 
-#endif
-
 #endif  // CHROME_TEST_NACL_NACL_BROWSERTEST_UTIL_H_
diff --git a/chrome/test/nacl_test_injection/buildbot_chrome_nacl_stage.py b/chrome/test/nacl_test_injection/buildbot_chrome_nacl_stage.py
index b31c9f6..ca198f4 100755
--- a/chrome/test/nacl_test_injection/buildbot_chrome_nacl_stage.py
+++ b/chrome/test/nacl_test_injection/buildbot_chrome_nacl_stage.py
@@ -225,9 +225,12 @@
                options.json_build_results_output_file)
 
   # Download the toolchain(s).
-  RunCommand([python,
-              os.path.join(nacl_dir, 'build', 'download_toolchains.py'),
-              '--keep', '--no-arm-trusted', '--no-pnacl', 'TOOL_REVISIONS'],
+  pkg_ver_dir = os.path.join(nacl_dir, 'build', 'package_version')
+  RunCommand([python, os.path.join(pkg_ver_dir, 'package_version.py'),
+              '--exclude', 'arm_trusted',
+              '--exclude', 'pnacl_newlib',
+              '--exclude', 'nacl_arm_newlib',
+              'sync', '--extract'],
              nacl_dir, os.environ)
 
   CleanTempDir()
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc
index 1f5f2f0..8bec4b6 100644
--- a/chrome/test/ppapi/ppapi_browsertest.cc
+++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/javascript_test_observer.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "chrome/test/nacl/nacl_browsertest_util.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/test_renderer_host.h"
@@ -57,21 +58,6 @@
       RunTestWithSSLServer(STRIP_PREFIXES(test_name)); \
     }
 
-// NaCl glibc tests are included for x86 only, as there is no glibc support
-// for other architectures (ARM/MIPS).
-#if defined(ARCH_CPU_X86_FAMILY)
-#define MAYBE_GLIBC(test_name) test_name
-#else
-#define MAYBE_GLIBC(test_name) DISABLED_##test_name
-#endif
-
-// The NonSFI test is currently available only on linux-x86-32 architecture.
-#if defined(OS_LINUX) && defined(ARCH_CPU_X86)
-#define MAYBE_NONSFI(test_name) test_name
-#else
-#define MAYBE_NONSFI(test_name) DISABLED_##test_name
-#endif
-
 #if defined(DISABLE_NACL)
 
 #define TEST_PPAPI_NACL(test_name)
@@ -92,7 +78,7 @@
       RunTestViaHTTP(STRIP_PREFIXES(test_name)); \
     } \
     IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, \
-                           MAYBE_NONSFI(test_name)) { \
+                           MAYBE_PNACL_NONSFI(test_name)) { \
       RunTestViaHTTP(STRIP_PREFIXES(test_name)); \
     }
 
@@ -114,7 +100,7 @@
       RunTestWithSSLServer(STRIP_PREFIXES(test_name)); \
     } \
     IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, \
-                           MAYBE_NONSFI(test_name)) { \
+                           MAYBE_PNACL_NONSFI(test_name)) { \
       RunTestWithSSLServer(STRIP_PREFIXES(test_name)); \
     }
 
@@ -210,7 +196,6 @@
 TEST_PPAPI_OUT_OF_PROCESS(TraceEvent)
 TEST_PPAPI_NACL(TraceEvent)
 
-TEST_PPAPI_IN_PROCESS(InputEvent)
 TEST_PPAPI_OUT_OF_PROCESS(InputEvent)
 TEST_PPAPI_NACL(InputEvent)
 
@@ -221,7 +206,6 @@
 #define MAYBE_ImeInputEvent ImeInputEvent
 #endif
 
-TEST_PPAPI_IN_PROCESS(MAYBE_ImeInputEvent)
 TEST_PPAPI_OUT_OF_PROCESS(MAYBE_ImeInputEvent)
 TEST_PPAPI_NACL(MAYBE_ImeInputEvent)
 
@@ -351,7 +335,8 @@
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, TCPSocket) {
   RUN_TCPSOCKET_SUBTESTS;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(TCPSocket)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(TCPSocket)) {
   RUN_TCPSOCKET_SUBTESTS;
 }
 
@@ -391,7 +376,8 @@
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, UDPSocket) {
   RUN_UDPSOCKET_SUBTESTS;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(UDPSocket)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(UDPSocket)) {
   RUN_UDPSOCKET_SUBTESTS;
 }
 
@@ -438,7 +424,8 @@
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, HostResolver) {
   RUN_HOST_RESOLVER_SUBTESTS;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(HostResolver)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(HostResolver)) {
   RUN_HOST_RESOLVER_SUBTESTS;
 }
 
@@ -552,7 +539,7 @@
 #else
 #define MAYBE_URLLoader_BasicFilePOST URLLoader_BasicFilePOST
 #endif
-IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, URLLoader0) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(URLLoader0)) {
   RunTestViaHTTP(
       LIST_TEST(URLLoader_BasicGET)
       LIST_TEST(URLLoader_BasicPOST)
@@ -562,13 +549,13 @@
   );
 }
 
-IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, URLLoader1) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(URLLoader1)) {
   RUN_URLLOADER_SUBTESTS_1;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, URLLoader2) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(URLLoader2)) {
   RUN_URLLOADER_SUBTESTS_2;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, URLLoader3) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClGLibcTest, MAYBE_GLIBC(URLLoader3)) {
   RUN_URLLOADER_SUBTESTS_3;
 }
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, URLLoader0) {
@@ -583,16 +570,20 @@
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, URLLoader3) {
   RUN_URLLOADER_SUBTESTS_3;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(URLLoader0)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(URLLoader0)) {
   RUN_URLLOADER_SUBTESTS_0;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(URLLoader1)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(URLLoader1)) {
   RUN_URLLOADER_SUBTESTS_1;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(URLLoader2)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(URLLoader2)) {
   RUN_URLLOADER_SUBTESTS_2;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(URLLoader3)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(URLLoader3)) {
   RUN_URLLOADER_SUBTESTS_3;
 }
 
@@ -684,22 +675,6 @@
 #undef PostMessage
 #endif
 
-IN_PROC_BROWSER_TEST_F(PPAPITest, PostMessage) {
-  RunTestViaHTTP(
-      LIST_TEST(PostMessage_SendInInit)
-      LIST_TEST(PostMessage_SendingData)
-      LIST_TEST(PostMessage_SendingString)
-      LIST_TEST(PostMessage_SendingArrayBuffer)
-      LIST_TEST(DISABLED_PostMessage_SendingArray)
-      LIST_TEST(DISABLED_PostMessage_SendingDictionary)
-      LIST_TEST(DISABLED_PostMessage_SendingResource)
-      LIST_TEST(DISABLED_PostMessage_SendingComplexVar)
-      LIST_TEST(PostMessage_MessageEvent)
-      LIST_TEST(PostMessage_NoHandler)
-      LIST_TEST(PostMessage_ExtraParam)
-  );
-}
-
 // Flaky: crbug.com/269530
 #if defined(OS_WIN)
 #define MAYBE_PostMessage DISABLED_PostMessage
@@ -718,7 +693,8 @@
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, PostMessage) {
   RUN_POSTMESSAGE_SUBTESTS;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(PostMessage)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(PostMessage)) {
   RUN_POSTMESSAGE_SUBTESTS;
 }
 
@@ -726,8 +702,8 @@
 TEST_PPAPI_OUT_OF_PROCESS(Memory)
 TEST_PPAPI_NACL(Memory)
 
-TEST_PPAPI_IN_PROCESS(VideoDecoder)
-TEST_PPAPI_OUT_OF_PROCESS(VideoDecoder)
+TEST_PPAPI_IN_PROCESS(VideoDecoderDev)
+TEST_PPAPI_OUT_OF_PROCESS(VideoDecoderDev)
 
 // FileIO tests.
 #define RUN_FILEIO_SUBTESTS \
@@ -812,11 +788,11 @@
   RUN_FILEIO_PRIVATE_SUBTESTS;
 }
 
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(FileIO)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_PNACL_NONSFI(FileIO)) {
   RUN_FILEIO_SUBTESTS;
 }
 IN_PROC_BROWSER_TEST_F(PPAPIPrivateNaClPNaClTest,
-                       MAYBE_NONSFI(FILEIO_Private)) {
+                       MAYBE_PNACL_NONSFI(FILEIO_Private)) {
   RUN_FILEIO_PRIVATE_SUBTESTS;
 }
 
@@ -875,7 +851,9 @@
   RUN_FILEREF_SUBTESTS_2;
 }
 // Flaky on 32-bit linux bot; http://crbug.com/308908
-#if defined(OS_LINUX) && defined(ARCH_CPU_X86)
+// Glibc not available on ARM
+#if (defined(OS_LINUX) && defined(ARCH_CPU_X86)) \
+    || defined(ARCH_CPU_ARM_FAMILY)
 #define MAYBE_NaCl_Glibc_FileRef1 DISABLED_FileRef1
 #define MAYBE_NaCl_Glibc_FileRef2 DISABLED_FileRef2
 #else
@@ -894,10 +872,12 @@
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, FileRef2) {
   RUN_FILEREF_SUBTESTS_2;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(FileRef1)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(FileRef1)) {
   RUN_FILEREF_SUBTESTS_1;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(FileRef2)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(FileRef2)) {
   RUN_FILEREF_SUBTESTS_2;
 }
 
@@ -957,7 +937,8 @@
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, NetAddress) {
   RUN_NETADDRESS_SUBTESTS;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(NetAddress)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(NetAddress)) {
   RUN_NETADDRESS_SUBTESTS;
 }
 
@@ -1005,7 +986,7 @@
   RUN_NETADDRESS_PRIVATE_UNTRUSTED_SUBTESTS;
 }
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
-                       MAYBE_NONSFI(NetAddressPrivate)) {
+                       MAYBE_PNACL_NONSFI(NetAddressPrivate)) {
   RUN_NETADDRESS_PRIVATE_UNTRUSTED_SUBTESTS;
 }
 
@@ -1030,7 +1011,7 @@
   RUN_NETWORK_MONITOR_SUBTESTS;
 }
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
-                       MAYBE_NONSFI(NetworkMonitor)) {
+                       MAYBE_PNACL_NONSFI(NetworkMonitor)) {
   RUN_NETWORK_MONITOR_SUBTESTS;
 }
 
@@ -1118,10 +1099,12 @@
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, WebSocket2) {
   RUN_WEBSOCKET_SUBTESTS_2;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(WebSocket1)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(WebSocket1)) {
   RUN_WEBSOCKET_SUBTESTS_1;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(WebSocket2)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(WebSocket2)) {
   RUN_WEBSOCKET_SUBTESTS_2;
 }
 
@@ -1148,7 +1131,8 @@
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, AudioConfig) {
   RUN_AUDIO_CONFIG_SUBTESTS;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(AudioConfig)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(AudioConfig)) {
   RUN_AUDIO_CONFIG_SUBTESTS;
 }
 
@@ -1177,7 +1161,8 @@
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, Audio) {
   RUN_AUDIO_SUBTESTS;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(Audio)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
+                       MAYBE_PNACL_NONSFI(Audio)) {
   RUN_AUDIO_SUBTESTS;
 }
 
@@ -1197,7 +1182,7 @@
   RUN_AUDIO_THREAD_CREATOR_SUBTESTS;
 }
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest,
-                       MAYBE_NONSFI(AudioThreadCreator)) {
+                       MAYBE_PNACL_NONSFI(AudioThreadCreator)) {
   RUN_AUDIO_THREAD_CREATOR_SUBTESTS;
 }
 
@@ -1289,7 +1274,7 @@
 IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClTest, View) {
   RUN_VIEW_SUBTESTS;
 }
-IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_NONSFI(View)) {
+IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_PNACL_NONSFI(View)) {
   RUN_VIEW_SUBTESTS;
 }
 
diff --git a/chrome/test/remoting/remote_desktop_browsertest.cc b/chrome/test/remoting/remote_desktop_browsertest.cc
index fe2b80e..3d9f4a7 100644
--- a/chrome/test/remoting/remote_desktop_browsertest.cc
+++ b/chrome/test/remoting/remote_desktop_browsertest.cc
@@ -5,6 +5,9 @@
 #include "chrome/test/remoting/remote_desktop_browsertest.h"
 
 #include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/json/json_reader.h"
+#include "base/path_service.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/unpacked_installer.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
@@ -192,6 +195,8 @@
   if (web_contents != active_web_contents())
     web_contents_stack_.push_back(web_contents);
 
+  app_web_content_ = web_contents;
+
   if (is_platform_app()) {
     EXPECT_EQ(GetFirstAppWindowWebContents(), active_web_contents());
   } else {
@@ -639,6 +644,58 @@
   return result;
 }
 
+// static
+bool RemoteDesktopBrowserTest::LoadScript(
+    content::WebContents* web_contents,
+    const base::FilePath::StringType& path) {
+  std::string script;
+  base::FilePath src_dir;
+  _ASSERT_TRUE(PathService::Get(base::DIR_EXE, &src_dir));
+  base::FilePath script_path = src_dir.Append(path);
+
+  if (!base::ReadFileToString(script_path, &script)) {
+    LOG(ERROR) << "Failed to load script " << script_path.value();
+    return false;
+  }
+
+  return content::ExecuteScript(web_contents, script);
+}
+
+// static
+void RemoteDesktopBrowserTest::RunJavaScriptTest(
+    content::WebContents* web_contents,
+    const std::string& testName,
+    const std::string& testData) {
+  std::string result;
+  std::string script = "browserTest.runTest(browserTest." + testName + ", " +
+                       testData + ");";
+
+  LOG(INFO) << "Executing " << script;
+
+  ASSERT_TRUE(
+      content::ExecuteScriptAndExtractString(web_contents, script, &result));
+
+  // Read in the JSON
+  base::JSONReader reader;
+  scoped_ptr<base::Value> value;
+  value.reset(reader.Read(result, base::JSON_ALLOW_TRAILING_COMMAS));
+
+  // Convert to dictionary
+  base::DictionaryValue* dict_value = NULL;
+  ASSERT_TRUE(value->GetAsDictionary(&dict_value));
+
+  bool succeeded;
+  std::string error_message;
+  std::string stack_trace;
+
+  // Extract the fields
+  ASSERT_TRUE(dict_value->GetBoolean("succeeded", &succeeded));
+  ASSERT_TRUE(dict_value->GetString("error_message", &error_message));
+  ASSERT_TRUE(dict_value->GetString("stack_trace", &stack_trace));
+
+  EXPECT_TRUE(succeeded) << error_message << "\n" << stack_trace;
+}
+
 void RemoteDesktopBrowserTest::ClickOnControl(const std::string& name) {
   ASSERT_TRUE(HtmlElementVisible(name));
 
diff --git a/chrome/test/remoting/remote_desktop_browsertest.h b/chrome/test/remoting/remote_desktop_browsertest.h
index d4aeda3..fbccea6 100644
--- a/chrome/test/remoting/remote_desktop_browsertest.h
+++ b/chrome/test/remoting/remote_desktop_browsertest.h
@@ -187,6 +187,10 @@
     return client_web_content_;
   }
 
+  content::WebContents* app_web_content() {
+    return app_web_content_;
+  }
+
   // Whether to perform the cleanup tasks (uninstalling chromoting, etc).
   // This is useful for diagnostic purposes.
   bool NoCleanup() { return no_cleanup_; }
@@ -205,45 +209,60 @@
     return active_web_contents()->GetURL();
   }
 
-  // Helpers to execute javascript code on a web page.
+  // Helpers to execute JavaScript code on a web page.
 
-  // Helper to execute a javascript code snippet in the active WebContents.
+  // Helper to execute a JavaScript code snippet in the active WebContents.
   void ExecuteScript(const std::string& script);
 
-  // Helper to execute a javascript code snippet in the active WebContents
+  // Helper to execute a JavaScript code snippet in the active WebContents
   // and wait for page load to complete.
   void ExecuteScriptAndWaitForAnyPageLoad(const std::string& script);
 
-  // Helper to execute a javascript code snippet in the active WebContents
+  // Helper to execute a JavaScript code snippet in the active WebContents
   // and extract the boolean result.
   bool ExecuteScriptAndExtractBool(const std::string& script) {
     return ExecuteScriptAndExtractBool(active_web_contents(), script);
   }
 
-  // Helper to execute a javascript code snippet and extract the boolean result.
+  // Helper to execute a JavaScript code snippet and extract the boolean result.
   static bool ExecuteScriptAndExtractBool(content::WebContents* web_contents,
                                           const std::string& script);
 
-  // Helper to execute a javascript code snippet in the active WebContents
+  // Helper to execute a JavaScript code snippet in the active WebContents
   // and extract the int result.
   int ExecuteScriptAndExtractInt(const std::string& script) {
     return ExecuteScriptAndExtractInt(active_web_contents(), script);
   }
 
-  // Helper to execute a javascript code snippet and extract the int result.
+  // Helper to execute a JavaScript code snippet and extract the int result.
   static int ExecuteScriptAndExtractInt(content::WebContents* web_contents,
                                         const std::string& script);
 
-  // Helper to execute a javascript code snippet in the active WebContents
+  // Helper to execute a JavaScript code snippet in the active WebContents
   // and extract the string result.
   std::string ExecuteScriptAndExtractString(const std::string& script) {
     return ExecuteScriptAndExtractString(active_web_contents(), script);
   }
 
-  // Helper to execute a javascript code snippet and extract the string result.
+  // Helper to execute a JavaScript code snippet and extract the string result.
   static std::string ExecuteScriptAndExtractString(
       content::WebContents* web_contents, const std::string& script);
 
+  // Helper to load a JavaScript file from |path| and inject it to
+  // current web_content.  The variable |path| is relative to the directory of
+  // the |browsertest| executable.
+  static bool LoadScript(content::WebContents* web_contents,
+                         const base::FilePath::StringType& path);
+
+  // Helper to execute a JavaScript browser test.  It creates an object using
+  // the |browserTest.testName| ctor and calls |run| on the created object with
+  // |testData|, which can be any arbitrary object literal. The script
+  // browser_test.js must be loaded (using LoadScript) before calling this
+  // function.
+  void RunJavaScriptTest(content::WebContents* web_contents,
+                         const std::string& testName,
+                         const std::string& testData);
+
   // Helper to check whether an html element with the given name exists in
   // the active WebContents.
   bool HtmlElementExists(const std::string& name) {
@@ -314,6 +333,9 @@
   // will get acknowledgments of actions completed on the host.
   content::WebContents* client_web_content_;
 
+  // WebContent of the landing page in the chromoting app.
+  content::WebContents* app_web_content_;
+
   bool no_cleanup_;
   bool no_install_;
   const Extension* extension_;
diff --git a/chrome/utility/image_writer/error_messages.cc b/chrome/utility/image_writer/error_messages.cc
index 40fceb0..2847f22 100644
--- a/chrome/utility/image_writer/error_messages.cc
+++ b/chrome/utility/image_writer/error_messages.cc
@@ -8,7 +8,7 @@
 namespace error {
 
 const char kCleanUp[] = "Failed to clean up after write operation.";
-const char kCloseDevice[] = "Failed to close usb device file.";
+const char kCloseDevice[] = "Failed to close usb device.";
 const char kCloseImage[] = "Failed to close image file.";
 const char kInvalidDevice[] = "Invalid device path.";
 const char kNoOperationInProgress[] = "No operation in progress.";
@@ -18,6 +18,7 @@
 const char kReadDevice[] = "Failed to read device.";
 const char kReadImage[] = "Failed to read image.";
 const char kWriteImage[] = "Writing image to device failed.";
+const char kUnmountVolumes[] = "Unable to unmount the device.";
 const char kVerificationFailed[] = "Verification failed.";
 
 }  // namespace error
diff --git a/chrome/utility/image_writer/error_messages.h b/chrome/utility/image_writer/error_messages.h
index 02ff14a..56527c6 100644
--- a/chrome/utility/image_writer/error_messages.h
+++ b/chrome/utility/image_writer/error_messages.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_ERROR_MESSAGES_H_
-#define CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_ERROR_MESSAGES_H_
+#ifndef CHROME_UTILITY_IMAGE_WRITER_ERROR_MESSAGES_H_
+#define CHROME_UTILITY_IMAGE_WRITER_ERROR_MESSAGES_H_
 
 namespace image_writer {
 namespace error {
@@ -19,9 +19,10 @@
 extern const char kReadDevice[];
 extern const char kReadImage[];
 extern const char kWriteImage[];
+extern const char kUnmountVolumes[];
 extern const char kVerificationFailed[];
 
 }  // namespace error
 }  // namespace image_writer
 
-#endif  // CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_ERROR_MESSAGES_H_
+#endif  // CHROME_UTILITY_IMAGE_WRITER_ERROR_MESSAGES_H_
diff --git a/chrome/utility/image_writer/image_writer.cc b/chrome/utility/image_writer/image_writer.cc
index de2caeb..13175d7 100644
--- a/chrome/utility/image_writer/image_writer.cc
+++ b/chrome/utility/image_writer/image_writer.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/utility/image_writer/image_writer.h"
-
+#include "base/memory/aligned_memory.h"
 #include "chrome/utility/image_writer/error_messages.h"
+#include "chrome/utility/image_writer/image_writer.h"
 #include "chrome/utility/image_writer/image_writer_handler.h"
 #include "content/public/utility/utility_thread.h"
 
@@ -12,112 +12,56 @@
 
 // Since block devices like large sequential access and IPC is expensive we're
 // doing work in 1MB chunks.
-const int kBurningBlockSize = 1 << 20;
+const int kBurningBlockSize = 1 << 20;  // 1 MB
+const int kMemoryAlignment = 4096;
 
-ImageWriter::ImageWriter(ImageWriterHandler* handler)
-    : bytes_processed_(0),
+ImageWriter::ImageWriter(ImageWriterHandler* handler,
+                         const base::FilePath& image_path,
+                         const base::FilePath& device_path)
+    : image_path_(image_path),
+      device_path_(device_path),
+      bytes_processed_(0),
+      running_(false),
       handler_(handler) {}
 
 ImageWriter::~ImageWriter() {
-  CleanUp();
-}
-
-void ImageWriter::Write(const base::FilePath& image_path,
-                        const base::FilePath& device_path) {
-  if (IsRunning()) {
-    handler_->SendFailed(error::kOperationAlreadyInProgress);
-    return;
-  }
-
-  image_path_ = image_path;
-  device_path_ = device_path;
-  bytes_processed_ = 0;
-
-  image_file_.Initialize(image_path_,
-                         base::File::FLAG_OPEN | base::File::FLAG_READ);
-
-  if (!image_file_.IsValid()) {
-    DLOG(ERROR) << "Unable to open file for read: " << image_path_.value();
-    Error(error::kOpenImage);
-    return;
-  }
-
 #if defined(OS_WIN)
-  // Windows requires that device files be opened with FILE_FLAG_NO_BUFFERING
-  // and FILE_FLAG_WRITE_THROUGH.  These two flags are not part of base::File.
-  device_file_ =
-      base::File(CreateFile(device_path.value().c_str(),
-                            GENERIC_WRITE,
-                            FILE_SHARE_WRITE,
-                            NULL,
-                            OPEN_EXISTING,
-                            FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
-                            NULL));
-
-  if (!device_file_.IsValid()) {
-    Error(error::kOpenDevice);
-    return;
-  }
-#else
-  device_file_.Initialize(device_path_,
-                          base::File::FLAG_OPEN | base::File::FLAG_WRITE);
-
-  if (!device_file_.IsValid()) {
-    DLOG(ERROR) << "Unable to open file for write(" <<
-                   device_file_.error_details() << "): " <<
-                   device_path_.value();
-    Error(error::kOpenDevice);
-    return;
+  for (std::vector<HANDLE>::const_iterator it = volume_handles_.begin();
+       it != volume_handles_.end();
+       ++it) {
+    CloseHandle(*it);
   }
 #endif
+}
+
+void ImageWriter::Write() {
+  if (!InitializeFiles()) {
+    return;
+  }
 
   PostProgress(0);
-
   PostTask(base::Bind(&ImageWriter::WriteChunk, AsWeakPtr()));
 }
 
-void ImageWriter::Verify(const base::FilePath& image_path,
-                         const base::FilePath& device_path) {
-  if (IsRunning()) {
-    handler_->SendFailed(error::kOperationAlreadyInProgress);
-    return;
-  }
-
-  image_path_ = image_path;
-  device_path_ = device_path;
-  bytes_processed_ = 0;
-
-  image_file_.Initialize(image_path_,
-                         base::File::FLAG_OPEN | base::File::FLAG_READ);
-
-  if (!image_file_.IsValid()) {
-    DLOG(ERROR) << "Unable to open file for read: " << image_path_.value();
-    Error(error::kOpenImage);
-    return;
-  }
-
-  device_file_.Initialize(device_path_,
-                          base::File::FLAG_OPEN | base::File::FLAG_READ);
-
-  if (!device_file_.IsValid()) {
-    DLOG(ERROR) << "Unable to open file for read: " << device_path_.value();
-    Error(error::kOpenDevice);
+void ImageWriter::Verify() {
+  if (!InitializeFiles()) {
     return;
   }
 
   PostProgress(0);
-
   PostTask(base::Bind(&ImageWriter::VerifyChunk, AsWeakPtr()));
 }
 
 void ImageWriter::Cancel() {
-  CleanUp();
+  running_ = false;
   handler_->SendCancelled();
 }
 
-bool ImageWriter::IsRunning() const {
-  return image_file_.IsValid() || device_file_.IsValid();
-}
+bool ImageWriter::IsRunning() const { return running_; }
+
+const base::FilePath& ImageWriter::GetImagePath() { return image_path_; }
+
+const base::FilePath& ImageWriter::GetDevicePath() { return device_path_; }
 
 void ImageWriter::PostTask(const base::Closure& task) {
   base::MessageLoop::current()->PostTask(FROM_HERE, task);
@@ -128,26 +72,73 @@
 }
 
 void ImageWriter::Error(const std::string& message) {
-  CleanUp();
+  running_ = false;
   handler_->SendFailed(message);
 }
 
+bool ImageWriter::InitializeFiles() {
+  if (!image_file_.IsValid()) {
+    image_file_.Initialize(image_path_,
+                           base::File::FLAG_OPEN | base::File::FLAG_READ |
+                               base::File::FLAG_EXCLUSIVE_READ);
+
+    if (!image_file_.IsValid()) {
+      DLOG(ERROR) << "Unable to open file for read: " << image_path_.value();
+      Error(error::kOpenImage);
+      return false;
+    }
+  }
+
+  if (!device_file_.IsValid()) {
+#if defined(OS_WIN)
+    // Windows requires that device files be opened with FILE_FLAG_NO_BUFFERING
+    // and FILE_FLAG_WRITE_THROUGH.  These two flags are not part of base::File.
+    device_file_ =
+        base::File(CreateFile(device_path_.value().c_str(),
+                              GENERIC_READ | GENERIC_WRITE,
+                              FILE_SHARE_READ | FILE_SHARE_WRITE,
+                              NULL,
+                              OPEN_EXISTING,
+                              FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
+                              NULL));
+#else
+    device_file_.Initialize(
+        device_path_,
+        base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE |
+            base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_EXCLUSIVE_WRITE);
+#endif
+    if (!device_file_.IsValid()) {
+      Error(error::kOpenDevice);
+      return false;
+    }
+  }
+
+  bytes_processed_ = 0;
+  running_ = true;
+
+  return true;
+}
+
 void ImageWriter::WriteChunk() {
   if (!IsRunning()) {
     return;
   }
 
-  scoped_ptr<char[]> buffer(new char[kBurningBlockSize]);
+  // DASD buffers require memory alignment on some systems.
+  scoped_ptr<char, base::AlignedFreeDeleter> buffer(static_cast<char*>(
+      base::AlignedAlloc(kBurningBlockSize, kMemoryAlignment)));
   memset(buffer.get(), 0, kBurningBlockSize);
 
   int bytes_read = image_file_.Read(bytes_processed_, buffer.get(),
                                     kBurningBlockSize);
 
   if (bytes_read > 0) {
-    // Always attempt to write a whole block, as Windows requires 512-byte
+    // Always attempt to write a whole block, as writing DASD requires sector-
     // aligned writes to devices.
-    int bytes_written = device_file_.Write(bytes_processed_, buffer.get(),
-                                           kBurningBlockSize);
+    int bytes_to_write = bytes_read + (kMemoryAlignment - 1) -
+                         (bytes_read - 1) % kMemoryAlignment;
+    int bytes_written =
+        device_file_.Write(bytes_processed_, buffer.get(), bytes_to_write);
 
     if (bytes_written < bytes_read) {
       Error(error::kWriteImage);
@@ -161,7 +152,7 @@
   } else if (bytes_read == 0) {
     // End of file.
     device_file_.Flush();
-    CleanUp();
+    running_ = false;
     handler_->SendSucceeded();
   } else {
     // Unable to read entire file.
@@ -175,7 +166,9 @@
   }
 
   scoped_ptr<char[]> image_buffer(new char[kBurningBlockSize]);
-  scoped_ptr<char[]> device_buffer(new char[kBurningBlockSize]);
+  // DASD buffers require memory alignment on some systems.
+  scoped_ptr<char, base::AlignedFreeDeleter> device_buffer(static_cast<char*>(
+      base::AlignedAlloc(kBurningBlockSize, kMemoryAlignment)));
 
   int bytes_read = image_file_.Read(bytes_processed_, image_buffer.get(),
                                     kBurningBlockSize);
@@ -184,7 +177,7 @@
     if (device_file_.Read(bytes_processed_,
                           device_buffer.get(),
                           kBurningBlockSize) < bytes_read) {
-      LOG(ERROR) << "Failed to read " << kBurningBlockSize << " bytes of "
+      LOG(ERROR) << "Failed to read " << bytes_read << " bytes of "
                  << "device at offset " << bytes_processed_;
       Error(error::kReadDevice);
       return;
@@ -203,8 +196,8 @@
     PostTask(base::Bind(&ImageWriter::VerifyChunk, AsWeakPtr()));
   } else if (bytes_read == 0) {
     // End of file.
-    CleanUp();
     handler_->SendSucceeded();
+    running_ = false;
   } else {
     // Unable to read entire file.
     LOG(ERROR) << "Failed to read " << kBurningBlockSize << " bytes of image "
@@ -213,9 +206,4 @@
   }
 }
 
-void ImageWriter::CleanUp() {
-  image_file_.Close();
-  device_file_.Close();
-}
-
 }  // namespace image_writer
diff --git a/chrome/utility/image_writer/image_writer.h b/chrome/utility/image_writer/image_writer.h
index 70633e7..11bd154 100644
--- a/chrome/utility/image_writer/image_writer.h
+++ b/chrome/utility/image_writer/image_writer.h
@@ -5,6 +5,13 @@
 #ifndef CHROME_UTILITY_IMAGE_WRITER_IMAGE_WRITER_H_
 #define CHROME_UTILITY_IMAGE_WRITER_IMAGE_WRITER_H_
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
+#include <string>
+#include <vector>
+
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/files/file.h"
@@ -20,21 +27,32 @@
 // messages.
 class ImageWriter : public base::SupportsWeakPtr<ImageWriter> {
  public:
-  explicit ImageWriter(ImageWriterHandler* handler);
+  explicit ImageWriter(ImageWriterHandler* handler,
+                       const base::FilePath& image_path,
+                       const base::FilePath& device_path);
   virtual ~ImageWriter();
 
-  // Starts a write from |image_path| to |device_path|.
-  void Write(const base::FilePath& image_path,
-             const base::FilePath& device_path);
-  // Starts verifying that |image_path| and |device_path| have the same size and
-  // contents.
-  void Verify(const base::FilePath& image_path,
-              const base::FilePath& device_path);
+  // Starts a write from |image_path_| to |device_path_|.
+  void Write();
+  // Starts verifying that |image_path_| and |device_path_| have the same size
+  // and contents.
+  void Verify();
   // Cancels any pending writes or verifications.
   void Cancel();
 
   // Returns whether an operation is in progress.
   bool IsRunning() const;
+  // Checks if a path is a valid target device.
+  // This method has OS-specific implementations.
+  bool IsValidDevice();
+  // Unmounts all volumes on the target device.
+  // This method has OS-specific implementations.
+  bool UnmountVolumes();
+
+  // Return the current image path.
+  const base::FilePath& GetImagePath();
+  // Return the current device path.
+  const base::FilePath& GetDevicePath();
 
  private:
   // Convenience wrappers.
@@ -42,19 +60,24 @@
   void PostProgress(int64 progress);
   void Error(const std::string& message);
 
+  // Initializes the files.
+  bool InitializeFiles();
+
   // Work loops.
   void WriteChunk();
   void VerifyChunk();
 
-  // Cleans up file handles.
-  void CleanUp();
-
   base::FilePath image_path_;
   base::FilePath device_path_;
 
   base::File image_file_;
   base::File device_file_;
   int64 bytes_processed_;
+  bool running_;
+
+#if defined(OS_WIN)
+  std::vector<HANDLE> volume_handles_;
+#endif
 
   ImageWriterHandler* handler_;
 };
diff --git a/chrome/utility/image_writer/image_writer_handler.cc b/chrome/utility/image_writer/image_writer_handler.cc
index e9a258e..2fe78c9 100644
--- a/chrome/utility/image_writer/image_writer_handler.cc
+++ b/chrome/utility/image_writer/image_writer_handler.cc
@@ -8,19 +8,9 @@
 #include "chrome/utility/image_writer/image_writer_handler.h"
 #include "content/public/utility/utility_thread.h"
 
-#if defined(OS_WIN)
-#include <windows.h>
-#include <setupapi.h>
-#include <winioctl.h>
-#endif
-
 namespace image_writer {
 
-#if defined(OS_WIN)
-const size_t kStorageQueryBufferSize = 1024;
-#endif
-
-ImageWriterHandler::ImageWriterHandler() : image_writer_(this) {}
+ImageWriterHandler::ImageWriterHandler() {}
 ImageWriterHandler::~ImageWriterHandler() {}
 
 void ImageWriterHandler::SendSucceeded() {
@@ -59,93 +49,55 @@
 
 void ImageWriterHandler::OnWriteStart(const base::FilePath& image,
                                       const base::FilePath& device) {
-  if (!IsValidDevice(device)) {
-    Send(new ChromeUtilityHostMsg_ImageWriter_Failed(error::kInvalidDevice));
+  if (!image_writer_.get() || image != image_writer_->GetImagePath() ||
+      device != image_writer_->GetDevicePath()) {
+    image_writer_.reset(new ImageWriter(this, image, device));
+  }
+
+  if (image_writer_->IsRunning()) {
+    SendFailed(error::kOperationAlreadyInProgress);
     return;
   }
 
-  if (image_writer_.IsRunning()) {
-    Send(new ChromeUtilityHostMsg_ImageWriter_Failed(
-        error::kOperationAlreadyInProgress));
+  if (!image_writer_->IsValidDevice()) {
+    SendFailed(error::kInvalidDevice);
     return;
   }
-  image_writer_.Write(image, device);
+
+  if (!image_writer_->UnmountVolumes()) {
+    SendFailed(error::kUnmountVolumes);
+    return;
+  }
+
+  image_writer_->Write();
 }
 
 void ImageWriterHandler::OnVerifyStart(const base::FilePath& image,
                                        const base::FilePath& device) {
-  if (!IsValidDevice(device)) {
-    Send(new ChromeUtilityHostMsg_ImageWriter_Failed(error::kInvalidDevice));
+  if (!image_writer_.get() || image != image_writer_->GetImagePath() ||
+      device != image_writer_->GetDevicePath()) {
+    image_writer_.reset(new ImageWriter(this, image, device));
+  }
+
+  if (image_writer_->IsRunning()) {
+    SendFailed(error::kOperationAlreadyInProgress);
     return;
   }
 
-  if (image_writer_.IsRunning()) {
-    Send(new ChromeUtilityHostMsg_ImageWriter_Failed(
-        error::kOperationAlreadyInProgress));
+  if (!image_writer_->IsValidDevice()) {
+    SendFailed(error::kInvalidDevice);
     return;
   }
-  image_writer_.Verify(image, device);
+
+  image_writer_->Verify();
 }
 
 void ImageWriterHandler::OnCancel() {
-  if (image_writer_.IsRunning()) {
-    image_writer_.Cancel();
+  if (image_writer_.get()) {
+    image_writer_->Cancel();
   } else {
     SendCancelled();
   }
 }
 
-bool ImageWriterHandler::IsValidDevice(const base::FilePath& device) {
-#if defined(OS_WIN)
-  base::win::ScopedHandle device_handle(
-      CreateFile(device.value().c_str(),
-                 // Desired access, which is none as we only need metadata.
-                 0,
-                 // Required to be read + write for devices.
-                 FILE_SHARE_READ | FILE_SHARE_WRITE,
-                 NULL,           // Optional security attributes.
-                 OPEN_EXISTING,  // Devices already exist.
-                 0,              // No optional flags.
-                 NULL));         // No template file.
-
-  if (!device_handle) {
-    PLOG(ERROR) << "Opening device handle failed.";
-    return false;
-  }
-
-  STORAGE_PROPERTY_QUERY query = STORAGE_PROPERTY_QUERY();
-  query.PropertyId = StorageDeviceProperty;
-  query.QueryType = PropertyStandardQuery;
-  DWORD bytes_returned;
-
-  scoped_ptr<char[]> output_buf(new char[kStorageQueryBufferSize]);
-  BOOL status = DeviceIoControl(
-      device_handle,                   // Device handle.
-      IOCTL_STORAGE_QUERY_PROPERTY,    // Flag to request device properties.
-      &query,                          // Query parameters.
-      sizeof(STORAGE_PROPERTY_QUERY),  // query parameters size.
-      output_buf.get(),                // output buffer.
-      kStorageQueryBufferSize,         // Size of buffer.
-      &bytes_returned,                 // Number of bytes returned.
-                                       // Must not be null.
-      NULL);                           // Optional unused overlapped perameter.
-
-  if (status == FALSE) {
-    PLOG(ERROR) << "Storage property query failed.";
-    return false;
-  }
-
-  STORAGE_DEVICE_DESCRIPTOR* device_descriptor =
-      reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(output_buf.get());
-
-  if (device_descriptor->RemovableMedia)
-    return true;
-
-#else
-  // Other platforms will have to be added as they are supported.
-  NOTIMPLEMENTED();
-#endif
-  return false;
-}
-
 }  // namespace image_writer
diff --git a/chrome/utility/image_writer/image_writer_handler.h b/chrome/utility/image_writer/image_writer_handler.h
index 5763f96..4d241cf 100644
--- a/chrome/utility/image_writer/image_writer_handler.h
+++ b/chrome/utility/image_writer/image_writer_handler.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_UTILITY_IMAGE_WRITER_IMAGE_WRITER_HANDLER_H_
 #define CHROME_UTILITY_IMAGE_WRITER_IMAGE_WRITER_HANDLER_H_
 
+#include <string>
+
 #include "chrome/utility/image_writer/image_writer.h"
 #include "chrome/utility/utility_message_handler.h"
 #include "ipc/ipc_message.h"
@@ -40,10 +42,7 @@
   void OnVerifyStart(const base::FilePath& image, const base::FilePath& device);
   void OnCancel();
 
-  // Checks if a path is a valid target device.
-  bool IsValidDevice(const base::FilePath& device);
-
-  ImageWriter image_writer_;
+  scoped_ptr<ImageWriter> image_writer_;
 };
 
 }  // namespace image_writer
diff --git a/chrome/utility/image_writer/image_writer_stub.cc b/chrome/utility/image_writer/image_writer_stub.cc
new file mode 100644
index 0000000..264de9d
--- /dev/null
+++ b/chrome/utility/image_writer/image_writer_stub.cc
@@ -0,0 +1,22 @@
+// 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.
+
+#include "chrome/utility/image_writer/image_writer.h"
+
+// This file contains the default version of the platform-specific methods of
+// the ImageWriter.  Add new platforms by creating a new version of these
+// methods and updating the compliation rules appropriately.
+namespace image_writer {
+
+bool ImageWriter::IsValidDevice() {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool ImageWriter::UnmountVolumes() {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+}  // namespace image_writer
diff --git a/chrome/utility/image_writer/image_writer_unittest.cc b/chrome/utility/image_writer/image_writer_unittest.cc
index 0673e00..0cc0c5b 100644
--- a/chrome/utility/image_writer/image_writer_unittest.cc
+++ b/chrome/utility/image_writer/image_writer_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <string>
+
 #include "base/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
@@ -59,11 +61,38 @@
   MOCK_METHOD1(OnMessageReceived, bool(const IPC::Message& message));
 };
 
+// This Mock has the additional feature that it will start verification when
+// the write completes.
+class VerifyingHandler : public MockHandler {
+ public:
+  VerifyingHandler() : image_writer_(NULL), verified_(false) {}
+
+  virtual void SendSucceeded() OVERRIDE {
+    MockHandler::SendSucceeded();
+    if (!verified_) {
+      image_writer_->Verify();
+      verified_ = true;
+    }
+  }
+  ImageWriter* image_writer_;
+
+ private:
+  bool verified_;
+};
+
 }  // namespace
 
+TEST_F(ImageWriterUtilityTest, Getters) {
+  MockHandler mock_handler;
+  ImageWriter image_writer(&mock_handler, image_path_, device_path_);
+
+  EXPECT_EQ(image_path_, image_writer.GetImagePath());
+  EXPECT_EQ(device_path_, image_writer.GetDevicePath());
+}
+
 TEST_F(ImageWriterUtilityTest, WriteSuccessful) {
   MockHandler mock_handler;
-  ImageWriter image_writer(&mock_handler);
+  ImageWriter image_writer(&mock_handler, image_path_, device_path_);
 
   EXPECT_CALL(mock_handler, SendProgress(_)).Times(AnyNumber());
   EXPECT_CALL(mock_handler, SendProgress(kTestFileSize)).Times(1);
@@ -72,39 +101,39 @@
   EXPECT_CALL(mock_handler, SendFailed(_)).Times(0);
 
   FillDefault(image_path_);
-  image_writer.Write(image_path_, device_path_);
+  image_writer.Write();
   base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(ImageWriterUtilityTest, WriteInvalidImageFile) {
   MockHandler mock_handler;
-  ImageWriter image_writer(&mock_handler);
+  ImageWriter image_writer(&mock_handler, image_path_, device_path_);
 
   EXPECT_CALL(mock_handler, SendProgress(_)).Times(0);
   EXPECT_CALL(mock_handler, SendSucceeded()).Times(0);
   EXPECT_CALL(mock_handler, SendFailed(error::kOpenImage)).Times(1);
 
   ASSERT_TRUE(base::DeleteFile(image_path_, false));
-  image_writer.Write(image_path_, device_path_);
+  image_writer.Write();
   base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(ImageWriterUtilityTest, WriteInvalidDeviceFile) {
   MockHandler mock_handler;
-  ImageWriter image_writer(&mock_handler);
+  ImageWriter image_writer(&mock_handler, image_path_, device_path_);
 
   EXPECT_CALL(mock_handler, SendProgress(_)).Times(0);
   EXPECT_CALL(mock_handler, SendSucceeded()).Times(0);
   EXPECT_CALL(mock_handler, SendFailed(error::kOpenDevice)).Times(1);
 
   ASSERT_TRUE(base::DeleteFile(device_path_, false));
-  image_writer.Write(image_path_, device_path_);
+  image_writer.Write();
   base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(ImageWriterUtilityTest, VerifySuccessful) {
   MockHandler mock_handler;
-  ImageWriter image_writer(&mock_handler);
+  ImageWriter image_writer(&mock_handler, image_path_, device_path_);
 
   EXPECT_CALL(mock_handler, SendProgress(_)).Times(AnyNumber());
   EXPECT_CALL(mock_handler, SendProgress(kTestFileSize)).Times(1);
@@ -115,14 +144,14 @@
   FillDefault(image_path_);
   FillDefault(device_path_);
 
-  image_writer.Verify(image_path_, device_path_);
+  image_writer.Verify();
 
   base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(ImageWriterUtilityTest, VerifyInvalidImageFile) {
   MockHandler mock_handler;
-  ImageWriter image_writer(&mock_handler);
+  ImageWriter image_writer(&mock_handler, image_path_, device_path_);
 
   EXPECT_CALL(mock_handler, SendProgress(_)).Times(0);
   EXPECT_CALL(mock_handler, SendSucceeded()).Times(0);
@@ -130,14 +159,14 @@
 
   ASSERT_TRUE(base::DeleteFile(image_path_, false));
 
-  image_writer.Verify(image_path_, device_path_);
+  image_writer.Verify();
 
   base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(ImageWriterUtilityTest, VerifyInvalidDeviceFile) {
   MockHandler mock_handler;
-  ImageWriter image_writer(&mock_handler);
+  ImageWriter image_writer(&mock_handler, image_path_, device_path_);
 
   EXPECT_CALL(mock_handler, SendProgress(_)).Times(0);
   EXPECT_CALL(mock_handler, SendSucceeded()).Times(0);
@@ -145,28 +174,28 @@
 
   ASSERT_TRUE(base::DeleteFile(device_path_, false));
 
-  image_writer.Verify(image_path_, device_path_);
+  image_writer.Verify();
 
   base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(ImageWriterUtilityTest, VerifyEmptyDevice) {
   MockHandler mock_handler;
-  ImageWriter image_writer(&mock_handler);
+  ImageWriter image_writer(&mock_handler, image_path_, device_path_);
 
   EXPECT_CALL(mock_handler, SendProgress(_)).Times(AnyNumber());
   EXPECT_CALL(mock_handler, SendSucceeded()).Times(0);
   EXPECT_CALL(mock_handler, SendFailed(error::kReadDevice)).Times(1);
 
   FillDefault(image_path_);
-  image_writer.Verify(image_path_, device_path_);
+  image_writer.Verify();
 
   base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(ImageWriterUtilityTest, VerifyFailed) {
   MockHandler mock_handler;
-  ImageWriter image_writer(&mock_handler);
+  ImageWriter image_writer(&mock_handler, image_path_, device_path_);
 
   EXPECT_CALL(mock_handler, SendProgress(_)).Times(AnyNumber());
   EXPECT_CALL(mock_handler, SendSucceeded()).Times(0);
@@ -174,24 +203,26 @@
 
   FillDefault(image_path_);
   FillFile(device_path_, ~kTestPattern);
-  image_writer.Verify(image_path_, device_path_);
+  image_writer.Verify();
 
   base::RunLoop().RunUntilIdle();
 }
 
-TEST_F(ImageWriterUtilityTest, WriteThenVerify) {
-  MockHandler mock_handler;
-  ImageWriter image_writer(&mock_handler);
+TEST_F(ImageWriterUtilityTest, WriteWithVerifySuccessful) {
+  VerifyingHandler mock_handler;
+  ImageWriter image_writer(&mock_handler, image_path_, device_path_);
+
+  mock_handler.image_writer_ = &image_writer;
 
   EXPECT_CALL(mock_handler, SendProgress(_)).Times(AnyNumber());
+  EXPECT_CALL(mock_handler, SendProgress(kTestFileSize)).Times(2);
+  EXPECT_CALL(mock_handler, SendProgress(0)).Times(2);
   EXPECT_CALL(mock_handler, SendSucceeded()).Times(2);
   EXPECT_CALL(mock_handler, SendFailed(_)).Times(0);
 
-  image_writer.Write(image_path_, device_path_);
+  FillDefault(image_path_);
 
-  base::RunLoop().RunUntilIdle();
-
-  image_writer.Verify(image_path_, device_path_);
+  image_writer.Write();
 
   base::RunLoop().RunUntilIdle();
 }
diff --git a/chrome/utility/image_writer/image_writer_win.cc b/chrome/utility/image_writer/image_writer_win.cc
new file mode 100644
index 0000000..b3cec95
--- /dev/null
+++ b/chrome/utility/image_writer/image_writer_win.cc
@@ -0,0 +1,183 @@
+// 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.
+
+#include <windows.h>
+#include <setupapi.h>
+#include <winioctl.h>
+
+#include "chrome/utility/image_writer/error_messages.h"
+#include "chrome/utility/image_writer/image_writer.h"
+
+namespace image_writer {
+
+const size_t kStorageQueryBufferSize = 1024;
+
+bool ImageWriter::IsValidDevice() {
+  base::win::ScopedHandle device_handle(
+      CreateFile(device_path_.value().c_str(),
+                 GENERIC_READ | GENERIC_WRITE,
+                 FILE_SHARE_READ | FILE_SHARE_WRITE,
+                 NULL,
+                 OPEN_EXISTING,
+                 FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
+                 NULL));
+  if (device_handle == INVALID_HANDLE_VALUE) {
+    Error(error::kOpenDevice);
+    return false;
+  }
+
+  STORAGE_PROPERTY_QUERY query = STORAGE_PROPERTY_QUERY();
+  query.PropertyId = StorageDeviceProperty;
+  query.QueryType = PropertyStandardQuery;
+  DWORD bytes_returned;
+
+  scoped_ptr<char[]> output_buf(new char[kStorageQueryBufferSize]);
+  BOOL status = DeviceIoControl(
+      device_handle,                   // Device handle.
+      IOCTL_STORAGE_QUERY_PROPERTY,    // Flag to request device properties.
+      &query,                          // Query parameters.
+      sizeof(STORAGE_PROPERTY_QUERY),  // query parameters size.
+      output_buf.get(),                // output buffer.
+      kStorageQueryBufferSize,         // Size of buffer.
+      &bytes_returned,                 // Number of bytes returned.
+                                       // Must not be null.
+      NULL);                           // Optional unused overlapped perameter.
+
+  if (!status) {
+    PLOG(ERROR) << "Storage property query failed";
+    return false;
+  }
+
+  STORAGE_DEVICE_DESCRIPTOR* device_descriptor =
+      reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(output_buf.get());
+
+  return device_descriptor->RemovableMedia == TRUE;
+}
+
+bool ImageWriter::UnmountVolumes() {
+  if (!InitializeFiles()) {
+    return false;
+  }
+
+  STORAGE_DEVICE_NUMBER sdn = {0};
+  DWORD bytes_returned;
+
+  BOOL status = DeviceIoControl(
+      device_file_.GetPlatformFile(),
+      IOCTL_STORAGE_GET_DEVICE_NUMBER,
+      NULL,             // Unused, must be NULL.
+      0,                // Unused, must be 0.
+      &sdn,             // An input buffer to hold the STORAGE_DEVICE_NUMBER
+      sizeof(sdn),      // The size of the input buffer.
+      &bytes_returned,  // the actual number of bytes returned.
+      NULL);            // Unused overlap.
+  if (!status) {
+    PLOG(ERROR) << "Unable to get device number.";
+    return false;
+  }
+
+  ULONG device_number = sdn.DeviceNumber;
+
+  TCHAR volume_path[MAX_PATH + 1];
+  HANDLE volume_finder = FindFirstVolume(volume_path, MAX_PATH + 1);
+  if (volume_finder == INVALID_HANDLE_VALUE) {
+    return false;
+  }
+
+  HANDLE volume_handle;
+  bool first_volume = true;
+  bool success = true;
+
+  while (first_volume ||
+         FindNextVolume(volume_finder, volume_path, MAX_PATH + 1)) {
+    first_volume = false;
+
+    size_t length = wcsnlen(volume_path, MAX_PATH + 1);
+    if (length < 1) {
+      continue;
+    }
+    volume_path[length - 1] = L'\0';
+
+    volume_handle = CreateFile(volume_path,
+                               GENERIC_READ | GENERIC_WRITE,
+                               FILE_SHARE_READ | FILE_SHARE_WRITE,
+                               NULL,
+                               OPEN_EXISTING,
+                               0,
+                               NULL);
+    if (volume_handle == INVALID_HANDLE_VALUE) {
+      PLOG(ERROR) << "Opening volume handle failed.";
+      success = false;
+      break;
+    }
+
+    volume_handles_.push_back(volume_handle);
+
+    VOLUME_DISK_EXTENTS disk_extents = {0};
+    status = DeviceIoControl(volume_handle,
+                             IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
+                             NULL,
+                             0,
+                             &disk_extents,
+                             sizeof(disk_extents),
+                             &bytes_returned,
+                             NULL);
+
+    if (!status) {
+      DWORD error = GetLastError();
+      if (error == ERROR_MORE_DATA || error == ERROR_INVALID_FUNCTION ||
+          error == ERROR_NOT_READY) {
+        continue;
+      } else {
+        PLOG(ERROR) << "Unable to get volume disk extents.";
+        success = false;
+        break;
+      }
+    }
+
+    if (disk_extents.NumberOfDiskExtents != 1 ||
+        disk_extents.Extents[0].DiskNumber != device_number) {
+      continue;
+    }
+
+    status = DeviceIoControl(volume_handle,
+                             FSCTL_LOCK_VOLUME,
+                             NULL,
+                             0,
+                             NULL,
+                             0,
+                             &bytes_returned,
+                             NULL);
+    if (!status) {
+      PLOG(ERROR) << "Unable to lock volume.";
+      success = false;
+      break;
+    }
+
+    status = DeviceIoControl(volume_handle,
+                             FSCTL_DISMOUNT_VOLUME,
+                             NULL,
+                             0,
+                             NULL,
+                             0,
+                             &bytes_returned,
+                             NULL);
+    if (!status) {
+      DWORD error = GetLastError();
+      if (error != ERROR_NOT_SUPPORTED) {
+        PLOG(ERROR) << "Unable to dismount volume.";
+        success = false;
+        break;
+      }
+    }
+  }
+
+  if (volume_finder != INVALID_HANDLE_VALUE) {
+    FindVolumeClose(volume_finder);
+  }
+
+  return success;
+}
+
+}  // namespace image_writer
diff --git a/chrome/utility/importer/ie_importer_win.cc b/chrome/utility/importer/ie_importer_win.cc
index 540cf59..1ba2d6b 100644
--- a/chrome/utility/importer/ie_importer_win.cc
+++ b/chrome/utility/importer/ie_importer_win.cc
@@ -468,8 +468,8 @@
 }
 
 void IEImporter::ImportHistory() {
-  const std::string kSchemes[] = {content::kHttpScheme,
-                                  content::kHttpsScheme,
+  const std::string kSchemes[] = {url::kHttpScheme,
+                                  url::kHttpsScheme,
                                   content::kFtpScheme,
                                   content::kFileScheme};
   int total_schemes = arraysize(kSchemes);
@@ -602,8 +602,8 @@
       continue;
 
     GURL url(ac_list[i].key.c_str());
-    if (!(LowerCaseEqualsASCII(url.scheme(), content::kHttpScheme) ||
-        LowerCaseEqualsASCII(url.scheme(), content::kHttpsScheme))) {
+    if (!(LowerCaseEqualsASCII(url.scheme(), url::kHttpScheme) ||
+          LowerCaseEqualsASCII(url.scheme(), url::kHttpsScheme))) {
       continue;
     }
 
diff --git a/chromeos/DEPS b/chromeos/DEPS
index 63bcc90..ea93903 100644
--- a/chromeos/DEPS
+++ b/chromeos/DEPS
@@ -1,8 +1,10 @@
 include_rules = [
   "+crypto",
   "+net",
+  "+policy/proto",
   "+third_party/cros_system_api",
   "+third_party/libxml",
+  "+third_party/protobuf",
   "+ui/gfx/geometry",
   "+ui/gfx/x"
 ]
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index d6cf1bb..e2e332a 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -16,6 +16,7 @@
       'dependencies': [
         '../base/base.gyp:base',
         '../base/base.gyp:base_prefs',
+        '../components/components.gyp:cloud_policy_proto',
         '../components/components.gyp:onc_component',
         '../crypto/crypto.gyp:crypto',
         '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
@@ -25,6 +26,7 @@
         '../net/net.gyp:net',
         '../third_party/icu/icu.gyp:icui18n',
         '../third_party/libxml/libxml.gyp:libxml',
+        '../third_party/protobuf/protobuf.gyp:protobuf_lite',
         '../ui/gfx/gfx.gyp:gfx_geometry',
         '../url/url.gyp:url_lib',
         'cryptohome_proto',
@@ -545,8 +547,7 @@
         '..',
       ],
       'conditions': [
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        [ '(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+        [ 'use_allocator!="none"', {
            'dependencies': [
               '../base/allocator/allocator.gyp:allocator',
             ],
diff --git a/chromeos/chromeos_paths.cc b/chromeos/chromeos_paths.cc
index 25174d4..a9963af 100644
--- a/chromeos/chromeos_paths.cc
+++ b/chromeos/chromeos_paths.cc
@@ -4,8 +4,10 @@
 
 #include "chromeos/chromeos_paths.h"
 
+#include "base/file_util.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
+#include "base/sys_info.h"
 
 namespace chromeos {
 
@@ -77,4 +79,26 @@
   PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
 }
 
+void RegisterStubPathOverrides(const base::FilePath& stubs_dir) {
+  CHECK(!base::SysInfo::IsRunningOnChromeOS());
+  // Override these paths on the desktop, so that enrollment and cloud
+  // policy work and can be tested.
+  base::FilePath parent = base::MakeAbsoluteFilePath(stubs_dir);
+  PathService::Override(
+      DIR_USER_POLICY_KEYS,
+      parent.AppendASCII("stub_user_policy"));
+  const bool is_absolute = true;
+  const bool create = false;
+  PathService::OverrideAndCreateIfNeeded(
+      FILE_OWNER_KEY,
+      parent.AppendASCII("stub_owner.key"),
+      is_absolute,
+      create);
+  PathService::OverrideAndCreateIfNeeded(
+      FILE_INSTALL_ATTRIBUTES,
+      parent.AppendASCII("stub_install_attributes.pb"),
+      is_absolute,
+      create);
+}
+
 }  // namespace chromeos
diff --git a/chromeos/chromeos_paths.h b/chromeos/chromeos_paths.h
index d25ac43..fe9be13 100644
--- a/chromeos/chromeos_paths.h
+++ b/chromeos/chromeos_paths.h
@@ -7,6 +7,10 @@
 
 #include "chromeos/chromeos_export.h"
 
+namespace base {
+class FilePath;
+}
+
 // This file declares path keys for the chromeos module.  These can be used with
 // the PathService to access various special directories and files.
 
@@ -40,6 +44,11 @@
 // Call once to register the provider for the path keys defined above.
 CHROMEOS_EXPORT void RegisterPathProvider();
 
+// Overrides some of the paths listed above so that those files can be used
+// when not running on ChromeOS. The stubs files will be relative to
+// |stubs_dir|. It is not valid to call this when running on ChromeOS.
+CHROMEOS_EXPORT void RegisterStubPathOverrides(const base::FilePath& stubs_dir);
+
 }  // namespace chromeos
 
 #endif  // CHROMEOS_CHROMEOS_PATHS_H_
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc
index b69b538..6478063 100644
--- a/chromeos/chromeos_switches.cc
+++ b/chromeos/chromeos_switches.cc
@@ -75,6 +75,9 @@
 // Enables MTP support in Files.app.
 const char kEnableFileManagerMTP[] = "enable-filemanager-mtp";
 
+// Enable explicit HID detection on OOBE.
+const char kEnableHIDDetectionOnOOBE[]     = "enable-hid-detection-on-oobe";
+
 // Enables notifications about captive portals in session.
 const char kEnableNetworkPortalNotification[] =
     "enable-network-portal-notification";
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h
index 18b7685..01ab36b 100644
--- a/chromeos/chromeos_switches.h
+++ b/chromeos/chromeos_switches.h
@@ -40,6 +40,7 @@
 CHROMEOS_EXPORT extern const char kEnableCarrierSwitching[];
 CHROMEOS_EXPORT extern const char kEnableConsumerManagement[];
 CHROMEOS_EXPORT extern const char kEnableFileManagerMTP[];
+CHROMEOS_EXPORT extern const char kEnableHIDDetectionOnOOBE[];
 CHROMEOS_EXPORT extern const char kEnableKioskMode[];
 CHROMEOS_EXPORT extern const char kEnableNetworkPortalNotification[];
 CHROMEOS_EXPORT extern const char kEnableRequestTabletSite[];
diff --git a/chromeos/dbus/cros_disks_client.cc b/chromeos/dbus/cros_disks_client.cc
index fae607d..cca2b17 100644
--- a/chromeos/dbus/cros_disks_client.cc
+++ b/chromeos/dbus/cros_disks_client.cc
@@ -148,17 +148,21 @@
   }
 
   // CrosDisksClient override.
-  virtual void FormatDevice(const std::string& device_path,
-                            const std::string& filesystem,
-                            const FormatDeviceCallback& callback,
-                            const base::Closure& error_callback) OVERRIDE {
+  virtual void Format(const std::string& device_path,
+                      const std::string& filesystem,
+                      const base::Closure& callback,
+                      const base::Closure& error_callback) OVERRIDE {
     dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
-                                 cros_disks::kFormatDevice);
+                                 cros_disks::kFormat);
     dbus::MessageWriter writer(&method_call);
     writer.AppendString(device_path);
     writer.AppendString(filesystem);
+    // No format option is currently specified, but we can later use this
+    // argument to specify options for the format operation.
+    std::vector<std::string> format_options;
+    writer.AppendArrayOfStrings(format_options);
     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-                       base::Bind(&CrosDisksClientImpl::OnFormatDevice,
+                       base::Bind(&CrosDisksClientImpl::OnFormat,
                                   weak_ptr_factory_.GetWeakPtr(),
                                   callback,
                                   error_callback));
@@ -183,9 +187,8 @@
   }
 
   // CrosDisksClient override.
-  virtual void SetUpConnections(
-      const MountEventHandler& mount_event_handler,
-      const MountCompletedHandler& mount_completed_handler) OVERRIDE {
+  virtual void SetMountEventHandler(
+      const MountEventHandler& mount_event_handler) OVERRIDE {
     static const SignalEventTuple kSignalEventTuples[] = {
       { cros_disks::kDeviceAdded, CROS_DISKS_DEVICE_ADDED },
       { cros_disks::kDeviceScanned, CROS_DISKS_DEVICE_SCANNED },
@@ -193,7 +196,6 @@
       { cros_disks::kDiskAdded, CROS_DISKS_DISK_ADDED },
       { cros_disks::kDiskChanged, CROS_DISKS_DISK_CHANGED },
       { cros_disks::kDiskRemoved, CROS_DISKS_DISK_REMOVED },
-      { cros_disks::kFormattingFinished, CROS_DISKS_FORMATTING_FINISHED },
     };
     const size_t kNumSignalEventTuples = arraysize(kSignalEventTuples);
 
@@ -208,6 +210,11 @@
           base::Bind(&CrosDisksClientImpl::OnSignalConnected,
                      weak_ptr_factory_.GetWeakPtr()));
     }
+  }
+
+  // CrosDisksClient override.
+  virtual void SetMountCompletedHandler(
+      const MountCompletedHandler& mount_completed_handler) OVERRIDE {
     proxy_->ConnectToSignal(
         cros_disks::kCrosDisksInterface,
         cros_disks::kMountCompleted,
@@ -218,6 +225,19 @@
                    weak_ptr_factory_.GetWeakPtr()));
   }
 
+  // CrosDisksClient override.
+  virtual void SetFormatCompletedHandler(
+      const FormatCompletedHandler& format_completed_handler) OVERRIDE {
+    proxy_->ConnectToSignal(
+        cros_disks::kCrosDisksInterface,
+        cros_disks::kFormatCompleted,
+        base::Bind(&CrosDisksClientImpl::OnFormatCompleted,
+                   weak_ptr_factory_.GetWeakPtr(),
+                   format_completed_handler),
+        base::Bind(&CrosDisksClientImpl::OnSignalConnected,
+                   weak_ptr_factory_.GetWeakPtr()));
+  }
+
  protected:
   virtual void Init(dbus::Bus* bus) OVERRIDE {
     proxy_ = bus->GetObjectProxy(
@@ -227,7 +247,7 @@
 
  private:
   // A struct to contain a pair of signal name and mount event type.
-  // Used by SetUpConnections.
+  // Used by SetMountEventHandler.
   struct SignalEventTuple {
     const char *signal_name;
     MountEventType event_type;
@@ -262,7 +282,7 @@
     // make this fail if reader is not able to read the error code value from
     // the response.
     dbus::MessageReader reader(response);
-    unsigned int error_code;
+    uint32 error_code = 0;
     if (reader.PopUint32(&error_code) &&
         static_cast<MountError>(error_code) != MOUNT_ERROR_NONE) {
       error_callback.Run();
@@ -292,23 +312,15 @@
     callback.Run(device_paths);
   }
 
-  // Handles the result of FormatDevice and calls |callback| or
-  // |error_callback|.
-  void OnFormatDevice(const FormatDeviceCallback& callback,
-                      const base::Closure& error_callback,
-                      dbus::Response* response) {
+  // Handles the result of Format and calls |callback| or |error_callback|.
+  void OnFormat(const base::Closure& callback,
+                const base::Closure& error_callback,
+                dbus::Response* response) {
     if (!response) {
       error_callback.Run();
       return;
     }
-    dbus::MessageReader reader(response);
-    bool success = false;
-    if (!reader.PopBool(&success)) {
-      LOG(ERROR) << "Invalid response: " << response->ToString();
-      error_callback.Run();
-      return;
-    }
-    callback.Run(success);
+    callback.Run();
   }
 
   // Handles the result of GetDeviceProperties and calls |callback| or
@@ -341,9 +353,9 @@
   // Handles MountCompleted signal and calls |handler|.
   void OnMountCompleted(MountCompletedHandler handler, dbus::Signal* signal) {
     dbus::MessageReader reader(signal);
-    unsigned int error_code = 0;
+    uint32 error_code = 0;
     std::string source_path;
-    unsigned int mount_type = 0;
+    uint32 mount_type = 0;
     std::string mount_path;
     if (!reader.PopUint32(&error_code) ||
         !reader.PopString(&source_path) ||
@@ -356,6 +368,18 @@
                 static_cast<MountType>(mount_type), mount_path);
   }
 
+  // Handles FormatCompleted signal and calls |handler|.
+  void OnFormatCompleted(FormatCompletedHandler handler, dbus::Signal* signal) {
+    dbus::MessageReader reader(signal);
+    uint32 error_code = 0;
+    std::string device_path;
+    if (!reader.PopUint32(&error_code) || !reader.PopString(&device_path)) {
+      LOG(ERROR) << "Invalid signal: " << signal->ToString();
+      return;
+    }
+    handler.Run(static_cast<FormatError>(error_code), device_path);
+  }
+
   // Handles the result of signal connection setup.
   void OnSignalConnected(const std::string& interface,
                          const std::string& signal,
@@ -444,10 +468,10 @@
         FROM_HERE, base::Bind(callback, device_paths));
   }
 
-  virtual void FormatDevice(const std::string& device_path,
-                            const std::string& filesystem,
-                            const FormatDeviceCallback& callback,
-                            const base::Closure& error_callback) OVERRIDE {
+  virtual void Format(const std::string& device_path,
+                      const std::string& filesystem,
+                      const base::Closure& callback,
+                      const base::Closure& error_callback) OVERRIDE {
     base::MessageLoopProxy::current()->PostTask(FROM_HERE, error_callback);
   }
 
@@ -458,13 +482,21 @@
     base::MessageLoopProxy::current()->PostTask(FROM_HERE, error_callback);
   }
 
-  virtual void SetUpConnections(
-      const MountEventHandler& mount_event_handler,
-      const MountCompletedHandler& mount_completed_handler) OVERRIDE {
+  virtual void SetMountEventHandler(
+      const MountEventHandler& mount_event_handler) OVERRIDE {
     mount_event_handler_ = mount_event_handler;
+  }
+
+  virtual void SetMountCompletedHandler(
+      const MountCompletedHandler& mount_completed_handler) OVERRIDE {
     mount_completed_handler_ = mount_completed_handler;
   }
 
+  virtual void SetFormatCompletedHandler(
+      const FormatCompletedHandler& format_completed_handler) OVERRIDE {
+    format_completed_handler_ = format_completed_handler;
+  }
+
  private:
   // Performs file actions for Mount().
   static MountError PerformFakeMount(const std::string& source_path,
@@ -532,6 +564,7 @@
 
   MountEventHandler mount_event_handler_;
   MountCompletedHandler mount_completed_handler_;
+  FormatCompletedHandler format_completed_handler_;
 
   base::WeakPtrFactory<CrosDisksClientStubImpl> weak_ptr_factory_;
 
diff --git a/chromeos/dbus/cros_disks_client.h b/chromeos/dbus/cros_disks_client.h
index 92871da..095566f 100644
--- a/chromeos/dbus/cros_disks_client.h
+++ b/chromeos/dbus/cros_disks_client.h
@@ -91,7 +91,6 @@
   CROS_DISKS_DEVICE_ADDED,
   CROS_DISKS_DEVICE_REMOVED,
   CROS_DISKS_DEVICE_SCANNED,
-  CROS_DISKS_FORMATTING_FINISHED,
 };
 
 // Additional unmount flags to be added to unmount request.
@@ -192,17 +191,13 @@
  public:
   // A callback to handle the result of EnumerateAutoMountableDevices.
   // The argument is the enumerated device paths.
-  typedef base::Callback<void(const std::vector<std::string>& device_paths)
-                         > EnumerateAutoMountableDevicesCallback;
-
-  // A callback to handle the result of FormatDevice.
-  // The argument is true when formatting succeeded.
-  typedef base::Callback<void(bool format_succeeded)> FormatDeviceCallback;
+  typedef base::Callback<void(const std::vector<std::string>& device_paths)>
+      EnumerateAutoMountableDevicesCallback;
 
   // A callback to handle the result of GetDeviceProperties.
   // The argument is the information about the specified device.
-  typedef base::Callback<void(const DiskInfo& disk_info)
-                         > GetDevicePropertiesCallback;
+  typedef base::Callback<void(const DiskInfo& disk_info)>
+      GetDevicePropertiesCallback;
 
   // A callback to handle MountCompleted signal.
   // The first argument is the error code.
@@ -212,15 +207,22 @@
   typedef base::Callback<void(MountError error_code,
                               const std::string& source_path,
                               MountType mount_type,
-                              const std::string& mount_path)
-                         > MountCompletedHandler;
+                              const std::string& mount_path)>
+      MountCompletedHandler;
+
+  // A callback to handle FormatCompleted signal.
+  // The first argument is the error code.
+  // The second argument is the device path.
+  typedef base::Callback<void(FormatError error_code,
+                              const std::string& device_path)>
+      FormatCompletedHandler;
 
   // A callback to handle mount events.
   // The first argument is the event type.
   // The second argument is the device path.
   typedef base::Callback<void(MountEventType event_type,
-                              const std::string& device_path)
-                         > MountEventHandler;
+                              const std::string& device_path)>
+      MountEventHandler;
 
   virtual ~CrosDisksClient();
 
@@ -252,12 +254,12 @@
       const EnumerateAutoMountableDevicesCallback& callback,
       const base::Closure& error_callback) = 0;
 
-  // Calls FormatDevice method.  |callback| is called after the method call
-  // succeeds, otherwise, |error_callback| is called.
-  virtual void FormatDevice(const std::string& device_path,
-                            const std::string& filesystem,
-                            const FormatDeviceCallback& callback,
-                            const base::Closure& error_callback) = 0;
+  // Calls Format method.  |callback| is called after the method call succeeds,
+  // otherwise, |error_callback| is called.
+  virtual void Format(const std::string& device_path,
+                      const std::string& filesystem,
+                      const base::Closure& callback,
+                      const base::Closure& error_callback) = 0;
 
   // Calls GetDeviceProperties method.  |callback| is called after the method
   // call succeeds, otherwise, |error_callback| is called.
@@ -265,13 +267,21 @@
                                    const GetDevicePropertiesCallback& callback,
                                    const base::Closure& error_callback) = 0;
 
-  // Registers given callback for events.
-  // |mount_event_handler| is called when mount event signal is received.
-  // |mount_completed_handler| is called when MountCompleted signal is received.
-  virtual void SetUpConnections(
-      const MountEventHandler& mount_event_handler,
+  // Registers |mount_event_handler| as a callback to be invoked when a mount
+  // event signal is received.
+  virtual void SetMountEventHandler(
+      const MountEventHandler& mount_event_handler) = 0;
+
+  // Registers |mount_completed_handler| as a callback to be invoked when a
+  // MountCompleted signal is received.
+  virtual void SetMountCompletedHandler(
       const MountCompletedHandler& mount_completed_handler) = 0;
 
+  // Registers |format_completed_handler| as a callback to be invoked when a
+  // FormatCompleted signal is received.
+  virtual void SetFormatCompletedHandler(
+      const FormatCompletedHandler& format_completed_handler) = 0;
+
   // Factory function, creates a new instance and returns ownership.
   // For normal usage, access the singleton via DBusThreadManager::Get().
   static CrosDisksClient* Create(DBusClientImplementationType type);
diff --git a/chromeos/dbus/debug_daemon_client.cc b/chromeos/dbus/debug_daemon_client.cc
index 2c81c17..8a8804f 100644
--- a/chromeos/dbus/debug_daemon_client.cc
+++ b/chromeos/dbus/debug_daemon_client.cc
@@ -18,6 +18,7 @@
 #include "base/platform_file.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/strings/string_util.h"
+#include "base/task_runner_util.h"
 #include "base/threading/worker_pool.h"
 #include "chromeos/dbus/pipe_reader.h"
 #include "dbus/bus.h"
@@ -53,8 +54,8 @@
     // issue the D-Bus request to stop tracing and collect results.
     base::WorkerPool::PostTaskAndReply(
         FROM_HERE,
-        base::Bind(&DebugDaemonClientImpl::CheckValidity,
-                   file_descriptor),
+        base::Bind(&dbus::FileDescriptor::CheckValidity,
+                   base::Unretained(file_descriptor)),
         base::Bind(&DebugDaemonClientImpl::OnCheckValidityGetDebugLogs,
                    weak_ptr_factory_.GetWeakPtr(),
                    base::Owned(file_descriptor),
@@ -221,33 +222,27 @@
       return false;
     }
 
+    scoped_refptr<base::TaskRunner> task_runner =
+        base::WorkerPool::GetTaskRunner(true /* task_is_slow */);
+
     pipe_reader_.reset(new PipeReaderForString(
-        base::WorkerPool::GetTaskRunner(true /* task_is_slow */),
+        task_runner,
         base::Bind(&DebugDaemonClientImpl::OnIOComplete,
                    weak_ptr_factory_.GetWeakPtr())));
-    int write_fd = -1;
-    if (!pipe_reader_->StartIO()) {
-      LOG(ERROR) << "Cannot create pipe reader";
-      // NB: continue anyway to shutdown tracing; toss trace data
-      write_fd = HANDLE_EINTR(open("/dev/null", O_WRONLY));
-      // TODO(sleffler) if this fails AppendFileDescriptor will abort
-    } else {
-      write_fd = pipe_reader_->write_fd();
-    }
 
-    dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(write_fd);
-    // Punt descriptor validity check to a worker thread; on return we'll
+    base::File pipe_write_end = pipe_reader_->StartIO();
+    // Create dbus::FileDescriptor on the worker thread; on return we'll
     // issue the D-Bus request to stop tracing and collect results.
-    base::WorkerPool::PostTaskAndReply(
+    base::PostTaskAndReplyWithResult(
+        task_runner,
         FROM_HERE,
-        base::Bind(&DebugDaemonClientImpl::CheckValidity,
-                   file_descriptor),
-        base::Bind(&DebugDaemonClientImpl::OnCheckValidityRequestStopSystem,
-                   weak_ptr_factory_.GetWeakPtr(),
-                   base::Owned(file_descriptor),
-                   callback),
-        false);
-
+        base::Bind(
+            &DebugDaemonClientImpl::CreateFileDescriptorToStopSystemTracing,
+            base::Passed(&pipe_write_end)),
+        base::Bind(
+            &DebugDaemonClientImpl::OnCreateFileDescriptorRequestStopSystem,
+            weak_ptr_factory_.GetWeakPtr(),
+            callback));
     return true;
   }
 
@@ -316,11 +311,6 @@
   }
 
  private:
-  // Called to check descriptor validity on a thread where i/o is permitted.
-  static void CheckValidity(dbus::FileDescriptor* file_descriptor) {
-    file_descriptor->CheckValidity();
-  }
-
   // Called when a CheckValidity response is received.
   void OnCheckValidityGetDebugLogs(dbus::FileDescriptor* file_descriptor,
                                    const GetDebugLogsCallback& callback) {
@@ -469,10 +459,28 @@
     }
   }
 
+  // Creates dbus::FileDescriptor from base::File.
+  static scoped_ptr<dbus::FileDescriptor>
+  CreateFileDescriptorToStopSystemTracing(base::File pipe_write_end) {
+    if (!pipe_write_end.IsValid()) {
+      LOG(ERROR) << "Cannot create pipe reader";
+      // NB: continue anyway to shutdown tracing; toss trace data
+      pipe_write_end.Initialize(base::FilePath(FILE_PATH_LITERAL("/dev/null")),
+                                base::File::FLAG_OPEN | base::File::FLAG_WRITE);
+      // TODO(sleffler) if this fails AppendFileDescriptor will abort
+    }
+    scoped_ptr<dbus::FileDescriptor> file_descriptor(new dbus::FileDescriptor);
+    file_descriptor->PutValue(pipe_write_end.TakePlatformFile());
+    file_descriptor->CheckValidity();
+    return file_descriptor.Pass();
+  }
+
   // Called when a CheckValidity response is received.
-  void OnCheckValidityRequestStopSystem(
-      dbus::FileDescriptor* file_descriptor,
-      const StopSystemTracingCallback& callback) {
+  void OnCreateFileDescriptorRequestStopSystem(
+      const StopSystemTracingCallback& callback,
+      scoped_ptr<dbus::FileDescriptor> file_descriptor) {
+    DCHECK(file_descriptor);
+
     // Issue the dbus request to stop system tracing
     dbus::MethodCall method_call(
         debugd::kDebugdInterface,
@@ -488,8 +496,6 @@
         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing,
                    weak_ptr_factory_.GetWeakPtr()));
-
-    pipe_reader_->CloseWriteFD();  // close our copy of fd after send
   }
 
   // Called when a response for RequestStopSystemTracing() is received.
diff --git a/chromeos/dbus/fake_cros_disks_client.cc b/chromeos/dbus/fake_cros_disks_client.cc
index 2578077..344a98e 100644
--- a/chromeos/dbus/fake_cros_disks_client.cc
+++ b/chromeos/dbus/fake_cros_disks_client.cc
@@ -13,8 +13,8 @@
 FakeCrosDisksClient::FakeCrosDisksClient()
     : unmount_call_count_(0),
       unmount_success_(true),
-      format_device_call_count_(0),
-      format_device_success_(true) {
+      format_call_count_(0),
+      format_success_(true) {
 }
 
 FakeCrosDisksClient::~FakeCrosDisksClient() {
@@ -51,19 +51,18 @@
     const base::Closure& error_callback) {
 }
 
-void FakeCrosDisksClient::FormatDevice(const std::string& device_path,
-                                       const std::string& filesystem,
-                                       const FormatDeviceCallback& callback,
-                                       const base::Closure& error_callback) {
+void FakeCrosDisksClient::Format(const std::string& device_path,
+                                 const std::string& filesystem,
+                                 const base::Closure& callback,
+                                 const base::Closure& error_callback) {
   DCHECK(!callback.is_null());
   DCHECK(!error_callback.is_null());
 
-  format_device_call_count_++;
-  last_format_device_device_path_ = device_path;
-  last_format_device_filesystem_ = filesystem;
-  if (format_device_success_) {
-    base::MessageLoopProxy::current()->PostTask(FROM_HERE,
-                                                base::Bind(callback, true));
+  format_call_count_++;
+  last_format_device_path_ = device_path;
+  last_format_filesystem_ = filesystem;
+  if (format_success_) {
+    base::MessageLoopProxy::current()->PostTask(FROM_HERE, callback);
   } else {
     base::MessageLoopProxy::current()->PostTask(FROM_HERE, error_callback);
   }
@@ -75,13 +74,21 @@
     const base::Closure& error_callback) {
 }
 
-void FakeCrosDisksClient::SetUpConnections(
-    const MountEventHandler& mount_event_handler,
-    const MountCompletedHandler& mount_completed_handler) {
+void FakeCrosDisksClient::SetMountEventHandler(
+    const MountEventHandler& mount_event_handler) {
   mount_event_handler_ = mount_event_handler;
+}
+
+void FakeCrosDisksClient::SetMountCompletedHandler(
+    const MountCompletedHandler& mount_completed_handler) {
   mount_completed_handler_ = mount_completed_handler;
 }
 
+void FakeCrosDisksClient::SetFormatCompletedHandler(
+    const FormatCompletedHandler& format_completed_handler) {
+  format_completed_handler_ = format_completed_handler;
+}
+
 bool FakeCrosDisksClient::SendMountEvent(MountEventType event,
                                          const std::string& path) {
   if (mount_event_handler_.is_null())
@@ -101,4 +108,13 @@
   return true;
 }
 
+bool FakeCrosDisksClient::SendFormatCompletedEvent(
+    FormatError error_code,
+    const std::string& device_path) {
+  if (format_completed_handler_.is_null())
+    return false;
+  format_completed_handler_.Run(error_code, device_path);
+  return true;
+}
+
 }  // namespace chromeos
diff --git a/chromeos/dbus/fake_cros_disks_client.h b/chromeos/dbus/fake_cros_disks_client.h
index 855a3c1..23e4c36 100644
--- a/chromeos/dbus/fake_cros_disks_client.h
+++ b/chromeos/dbus/fake_cros_disks_client.h
@@ -33,25 +33,31 @@
   virtual void EnumerateAutoMountableDevices(
       const EnumerateAutoMountableDevicesCallback& callback,
       const base::Closure& error_callback) OVERRIDE;
-  virtual void FormatDevice(const std::string& device_path,
-                            const std::string& filesystem,
-                            const FormatDeviceCallback& callback,
-                            const base::Closure& error_callback) OVERRIDE;
+  virtual void Format(const std::string& device_path,
+                      const std::string& filesystem,
+                      const base::Closure& callback,
+                      const base::Closure& error_callback) OVERRIDE;
   virtual void GetDeviceProperties(
       const std::string& device_path,
       const GetDevicePropertiesCallback& callback,
       const base::Closure& error_callback) OVERRIDE;
-  virtual void SetUpConnections(
-      const MountEventHandler& mount_event_handler,
+  virtual void SetMountEventHandler(
+      const MountEventHandler& mount_event_handler) OVERRIDE;
+  virtual void SetMountCompletedHandler(
       const MountCompletedHandler& mount_completed_handler) OVERRIDE;
+  virtual void SetFormatCompletedHandler(
+      const FormatCompletedHandler& format_completed_handler) OVERRIDE;
 
   // Used in tests to simulate signals sent by cros disks layer.
-  // Invokes handlers set in |SetUpConnections|.
+  // Invokes handlers set in |SetMountEventHandler|, |SetMountCompletedHandler|,
+  // and |SetFormatCompletedHandler|.
   bool SendMountEvent(MountEventType event, const std::string& path);
   bool SendMountCompletedEvent(MountError error_code,
                                const std::string& source_path,
                                MountType mount_type,
                                const std::string& mount_path);
+  bool SendFormatCompletedEvent(FormatError error_code,
+                                const std::string& device_path);
 
   // Returns how many times Unmount() was called.
   int unmount_call_count() const {
@@ -79,42 +85,40 @@
     unmount_listener_ = listener;
   }
 
-  // Returns how many times FormatDevice() was called.
-  int format_device_call_count() const {
-    return format_device_call_count_;
+  // Returns how many times Format() was called.
+  int format_call_count() const {
+    return format_call_count_;
   }
 
-  // Returns the |device_path| parameter from the last invocation of
-  // FormatDevice().
-  const std::string& last_format_device_device_path() const {
-    return last_format_device_device_path_;
+  // Returns the |device_path| parameter from the last invocation of Format().
+  const std::string& last_format_device_path() const {
+    return last_format_device_path_;
   }
 
-  // Returns the |filesystem| parameter from the last invocation of
-  // FormatDevice().
-  const std::string& last_format_device_filesystem() const {
-    return last_format_device_filesystem_;
+  // Returns the |filesystem| parameter from the last invocation of Format().
+  const std::string& last_format_filesystem() const {
+    return last_format_filesystem_;
   }
 
-  // Makes the subsequent FormatDevice() calls fail. FormatDevice() succeeds by
-  // default.
-  void MakeFormatDeviceFail() {
-    format_device_success_ = false;
+  // Makes the subsequent Format() calls fail. Format() succeeds by default.
+  void MakeFormatFail() {
+    format_success_ = false;
   }
 
  private:
   MountEventHandler mount_event_handler_;
   MountCompletedHandler mount_completed_handler_;
+  FormatCompletedHandler format_completed_handler_;
 
   int unmount_call_count_;
   std::string last_unmount_device_path_;
   UnmountOptions last_unmount_options_;
   bool unmount_success_;
   base::Closure unmount_listener_;
-  int format_device_call_count_;
-  std::string last_format_device_device_path_;
-  std::string last_format_device_filesystem_;
-  bool format_device_success_;
+  int format_call_count_;
+  std::string last_format_device_path_;
+  std::string last_format_filesystem_;
+  bool format_success_;
 };
 
 }  // namespace chromeos
diff --git a/chromeos/dbus/fake_cryptohome_client.cc b/chromeos/dbus/fake_cryptohome_client.cc
index 0a54ff0..1796e04 100644
--- a/chromeos/dbus/fake_cryptohome_client.cc
+++ b/chromeos/dbus/fake_cryptohome_client.cc
@@ -5,12 +5,28 @@
 #include "chromeos/dbus/fake_cryptohome_client.h"
 
 #include "base/bind.h"
+#include "base/file_util.h"
 #include "base/location.h"
 #include "base/message_loop/message_loop.h"
+#include "base/path_service.h"
+#include "base/threading/worker_pool.h"
+#include "chromeos/chromeos_paths.h"
 #include "chromeos/dbus/cryptohome/key.pb.h"
 #include "chromeos/dbus/cryptohome/rpc.pb.h"
 #include "crypto/nss_util.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
+#include "third_party/protobuf/src/google/protobuf/io/coded_stream.h"
+#include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream.h"
+#include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h"
+
+namespace {
+
+// Helper to asynchronously write a file in the WorkerPool.
+void PersistFile(const base::FilePath& path, const std::string& content) {
+  base::WriteFile(path, content.data(), content.size());
+}
+
+}  // namespace
 
 namespace chromeos {
 
@@ -20,8 +36,11 @@
       tpm_is_ready_counter_(0),
       unmount_result_(true),
       system_salt_(GetStubSystemSalt()),
-      locked_(false),
-      weak_ptr_factory_(this) {}
+      weak_ptr_factory_(this) {
+  base::FilePath cache_path;
+  locked_ = PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, &cache_path) &&
+            base::PathExists(cache_path);
+}
 
 FakeCryptohomeClient::~FakeCryptohomeClient() {}
 
@@ -246,6 +265,58 @@
 bool FakeCryptohomeClient::InstallAttributesFinalize(bool* successful) {
   locked_ = true;
   *successful = true;
+
+  // Persist the install attributes so that they can be reloaded if the
+  // browser is restarted. This is used for ease of development when device
+  // enrollment is required.
+  // The cryptohome::SerializedInstallAttributes protobuf lives in
+  // chrome/browser/chromeos, so it can't be used directly here; use the
+  // low-level protobuf API instead to just write the name-value pairs.
+  // The cache file is read by EnterpriseInstallAttributes::ReadCacheFile.
+  base::FilePath cache_path;
+  if (!PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, &cache_path))
+    return false;
+
+  std::string result;
+  {
+    // |result| can be used only after the StringOutputStream goes out of
+    // scope.
+    google::protobuf::io::StringOutputStream result_stream(&result);
+    google::protobuf::io::CodedOutputStream result_output(&result_stream);
+
+    // These tags encode a variable-length value on the wire, which can be
+    // used to encode strings, bytes and messages. We only needs constants
+    // for tag numbers 1 and 2 (see install_attributes.proto).
+    const int kVarLengthTag1 = (1 << 3) | 0x2;
+    const int kVarLengthTag2 = (2 << 3) | 0x2;
+
+    typedef std::map<std::string, std::vector<uint8> >::const_iterator Iter;
+    for (Iter it = install_attrs_.begin(); it != install_attrs_.end(); ++it) {
+      std::string attr;
+      {
+        google::protobuf::io::StringOutputStream attr_stream(&attr);
+        google::protobuf::io::CodedOutputStream attr_output(&attr_stream);
+
+        attr_output.WriteVarint32(kVarLengthTag1);
+        attr_output.WriteVarint32(it->first.size());
+        attr_output.WriteString(it->first);
+        attr_output.WriteVarint32(kVarLengthTag2);
+        attr_output.WriteVarint32(it->second.size());
+        attr_output.WriteRaw(it->second.data(), it->second.size());
+      }
+
+      // Two CodedOutputStreams are needed because inner messages must be
+      // prefixed by their total length, which can't be easily computed before
+      // writing their tags and values.
+      result_output.WriteVarint32(kVarLengthTag2);
+      result_output.WriteVarint32(attr.size());
+      result_output.WriteRaw(attr.data(), attr.size());
+    }
+  }
+
+  base::WorkerPool::PostTask(
+      FROM_HERE, base::Bind(&PersistFile, cache_path, result), false);
+
   return true;
 }
 
diff --git a/chromeos/dbus/fake_session_manager_client.cc b/chromeos/dbus/fake_session_manager_client.cc
index 21f50c6..c5fe549 100644
--- a/chromeos/dbus/fake_session_manager_client.cc
+++ b/chromeos/dbus/fake_session_manager_client.cc
@@ -46,14 +46,11 @@
                                           const std::string& command_line) {
 }
 
-void FakeSessionManagerClient::StartSession(
-    const std::string& user_email,
-    const StartSessionCallback& callback) {
+void FakeSessionManagerClient::StartSession(const std::string& user_email) {
   DCHECK_EQ(0UL, user_sessions_.count(user_email));
   std::string user_id_hash =
       CryptohomeClient::GetStubSanitizedUsername(user_email);
   user_sessions_[user_email] = user_id_hash;
-  base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true));
 }
 
 void FakeSessionManagerClient::StopSession() {
@@ -117,7 +114,6 @@
 void FakeSessionManagerClient::StorePolicyForUser(
     const std::string& username,
     const std::string& policy_blob,
-    const std::string& policy_key,
     const StorePolicyCallback& callback) {
   user_policies_[username] = policy_blob;
   base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true));
@@ -136,6 +132,12 @@
     const std::vector<std::string>& flags) {
 }
 
+void FakeSessionManagerClient::GetServerBackedStateKeys(
+    const StateKeysCallback& callback) {
+  base::MessageLoop::current()->PostTask(
+      FROM_HERE, base::Bind(callback, server_backed_state_keys_));
+}
+
 const std::string& FakeSessionManagerClient::device_policy() const {
   return device_policy_;
 }
diff --git a/chromeos/dbus/fake_session_manager_client.h b/chromeos/dbus/fake_session_manager_client.h
index e0cabce..2f4bb9a 100644
--- a/chromeos/dbus/fake_session_manager_client.h
+++ b/chromeos/dbus/fake_session_manager_client.h
@@ -7,6 +7,7 @@
 
 #include <map>
 #include <string>
+#include <vector>
 
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
@@ -30,8 +31,7 @@
   virtual bool HasObserver(Observer* observer) OVERRIDE;
   virtual void EmitLoginPromptVisible() OVERRIDE;
   virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE;
-  virtual void StartSession(const std::string& user_email,
-                            const StartSessionCallback& callback) OVERRIDE;
+  virtual void StartSession(const std::string& user_email) OVERRIDE;
   virtual void StopSession() OVERRIDE;
   virtual void StartDeviceWipe() OVERRIDE;
   virtual void RequestLockScreen() OVERRIDE;
@@ -53,7 +53,6 @@
                                  const StorePolicyCallback& callback) OVERRIDE;
   virtual void StorePolicyForUser(const std::string& username,
                                   const std::string& policy_blob,
-                                  const std::string& policy_key,
                                   const StorePolicyCallback& callback) OVERRIDE;
   virtual void StoreDeviceLocalAccountPolicy(
       const std::string& account_id,
@@ -61,6 +60,8 @@
       const StorePolicyCallback& callback) OVERRIDE;
   virtual void SetFlagsForUser(const std::string& username,
                                const std::vector<std::string>& flags) OVERRIDE;
+  virtual void GetServerBackedStateKeys(const StateKeysCallback& callback)
+      OVERRIDE;
 
   const std::string& device_policy() const;
   void set_device_policy(const std::string& policy_blob);
@@ -77,6 +78,13 @@
   // Notify observers about a property change completion.
   void OnPropertyChangeComplete(bool success);
 
+  // Configures the list of state keys used to satisfy
+  // GetServerBackedStateKeys() requests.
+  void set_server_backed_state_keys(
+      const std::vector<std::string>& state_keys) {
+    server_backed_state_keys_ = state_keys;
+  }
+
   int start_device_wipe_call_count() const {
     return start_device_wipe_call_count_;
   }
@@ -97,6 +105,7 @@
   std::map<std::string, std::string> device_local_account_policy_;
   ObserverList<Observer> observers_;
   SessionManagerClient::ActiveSessionsMap user_sessions_;
+  std::vector<std::string> server_backed_state_keys_;
 
   int start_device_wipe_call_count_;
   int notify_lock_screen_shown_call_count_;
diff --git a/chromeos/dbus/fake_shill_ipconfig_client.cc b/chromeos/dbus/fake_shill_ipconfig_client.cc
index 625d7b4..ccb2e5e 100644
--- a/chromeos/dbus/fake_shill_ipconfig_client.cc
+++ b/chromeos/dbus/fake_shill_ipconfig_client.cc
@@ -90,6 +90,21 @@
       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
 }
 
+ShillIPConfigClient::TestInterface*
+FakeShillIPConfigClient::GetTestInterface() {
+  return this;
+}
+
+// ShillIPConfigClient::TestInterface overrides
+
+void FakeShillIPConfigClient::AddIPConfig(
+    const std::string& ip_config_path,
+    const base::DictionaryValue& properties) {
+  ipconfigs_.SetWithoutPathExpansion(ip_config_path, properties.DeepCopy());
+}
+
+// Private methods
+
 void FakeShillIPConfigClient::PassProperties(
     const base::DictionaryValue* values,
     const DictionaryValueCallback& callback) const {
diff --git a/chromeos/dbus/fake_shill_ipconfig_client.h b/chromeos/dbus/fake_shill_ipconfig_client.h
index ec5dee2..ff25246 100644
--- a/chromeos/dbus/fake_shill_ipconfig_client.h
+++ b/chromeos/dbus/fake_shill_ipconfig_client.h
@@ -14,7 +14,9 @@
 namespace chromeos {
 
 // A fake implementation of ShillIPConfigClient.
-class CHROMEOS_EXPORT FakeShillIPConfigClient : public ShillIPConfigClient {
+class CHROMEOS_EXPORT FakeShillIPConfigClient
+    : public ShillIPConfigClient,
+      public ShillIPConfigClient::TestInterface {
  public:
   FakeShillIPConfigClient();
   virtual ~FakeShillIPConfigClient();
@@ -40,6 +42,11 @@
                              const VoidDBusMethodCallback& callback) OVERRIDE;
   virtual void Remove(const dbus::ObjectPath& ipconfig_path,
                       const VoidDBusMethodCallback& callback) OVERRIDE;
+  virtual ShillIPConfigClient::TestInterface* GetTestInterface() OVERRIDE;
+
+  // ShillIPConfigClient::TestInterface overrides.
+  virtual void AddIPConfig(const std::string& ip_config_path,
+                           const base::DictionaryValue& properties) OVERRIDE;
 
  private:
   // Runs callback with |values|.
diff --git a/chromeos/dbus/fake_shill_manager_client.cc b/chromeos/dbus/fake_shill_manager_client.cc
index 8c8c2b8..452f16d 100644
--- a/chromeos/dbus/fake_shill_manager_client.cc
+++ b/chromeos/dbus/fake_shill_manager_client.cc
@@ -14,6 +14,7 @@
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/shill_device_client.h"
+#include "chromeos/dbus/shill_ipconfig_client.h"
 #include "chromeos/dbus/shill_profile_client.h"
 #include "chromeos/dbus/shill_property_changed_observer.h"
 #include "chromeos/dbus/shill_service_client.h"
@@ -547,12 +548,16 @@
   DBusThreadManager* dbus_manager = DBusThreadManager::Get();
   ShillServiceClient::TestInterface* services =
       dbus_manager->GetShillServiceClient()->GetTestInterface();
+  DCHECK(services);
   ShillProfileClient::TestInterface* profiles =
       dbus_manager->GetShillProfileClient()->GetTestInterface();
+  DCHECK(profiles);
   ShillDeviceClient::TestInterface* devices =
       dbus_manager->GetShillDeviceClient()->GetTestInterface();
-  if (!services || !profiles || !devices)
-    return;
+  DCHECK(devices);
+  ShillIPConfigClient::TestInterface* ip_configs =
+      dbus_manager->GetShillIPConfigClient()->GetTestInterface();
+  DCHECK(ip_configs);
 
   const std::string shared_profile = ShillProfileClient::GetSharedProfilePath();
   profiles->AddProfile(shared_profile, std::string());
@@ -563,12 +568,36 @@
   bool enabled;
   std::string state;
 
+  // IPConfigs
+  base::DictionaryValue ipconfig_v4_dictionary;
+  ipconfig_v4_dictionary.SetStringWithoutPathExpansion(
+      shill::kAddressProperty, "0.0.0.0");
+  ipconfig_v4_dictionary.SetStringWithoutPathExpansion(
+      shill::kGatewayProperty, "0.0.0.1");
+  ipconfig_v4_dictionary.SetIntegerWithoutPathExpansion(
+      shill::kPrefixlenProperty, 0);
+  ipconfig_v4_dictionary.SetStringWithoutPathExpansion(
+      shill::kMethodProperty, shill::kTypeIPv4);
+  ip_configs->AddIPConfig("ipconfig_v4_path", ipconfig_v4_dictionary);
+  base::DictionaryValue ipconfig_v6_dictionary;
+  ipconfig_v6_dictionary.SetStringWithoutPathExpansion(
+      shill::kAddressProperty, "0:0:0:0:0:0:0:0");
+  ipconfig_v6_dictionary.SetStringWithoutPathExpansion(
+      shill::kMethodProperty, shill::kTypeIPv6);
+  ip_configs->AddIPConfig("ipconfig_v6_path", ipconfig_v6_dictionary);
+
   // Ethernet
   state = GetInitialStateForType(shill::kTypeEthernet, &enabled);
   if (state == shill::kStateOnline) {
     AddTechnology(shill::kTypeEthernet, enabled);
     devices->AddDevice(
         "/device/eth1", shill::kTypeEthernet, "stub_eth_device1");
+    base::ListValue eth_ip_configs;
+    eth_ip_configs.AppendString("ipconfig_v4_path");
+    eth_ip_configs.AppendString("ipconfig_v6_path");
+    devices->SetDeviceProperty("/device/eth1",
+                               shill::kIPConfigsProperty,
+                               eth_ip_configs);
     services->AddService("eth1", "eth1",
                          shill::kTypeEthernet,
                          state,
@@ -586,6 +615,12 @@
     }
     AddTechnology(shill::kTypeWifi, enabled);
     devices->AddDevice("/device/wifi1", shill::kTypeWifi, "stub_wifi_device1");
+    base::ListValue wifi_ip_configs;
+    wifi_ip_configs.AppendString("ipconfig_v4_path");
+    wifi_ip_configs.AppendString("ipconfig_v6_path");
+    devices->SetDeviceProperty("/device/wifi1",
+                               shill::kIPConfigsProperty,
+                               wifi_ip_configs);
 
     services->AddService("wifi1",
                          "wifi1",
diff --git a/chromeos/dbus/fake_shill_service_client.cc b/chromeos/dbus/fake_shill_service_client.cc
index 30673f3..ef4ffe6 100644
--- a/chromeos/dbus/fake_shill_service_client.cc
+++ b/chromeos/dbus/fake_shill_service_client.cc
@@ -89,7 +89,8 @@
                                                   NULL);
     call_status = DBUS_METHOD_CALL_SUCCESS;
   } else {
-    LOG(ERROR) << "Properties not found for: " << service_path.value();
+    // This may happen if we remove services from the list.
+    VLOG(2) << "Properties not found for: " << service_path.value();
     result_properties.reset(new base::DictionaryValue);
     call_status = DBUS_METHOD_CALL_FAILURE;
   }
diff --git a/chromeos/dbus/fake_update_engine_client.cc b/chromeos/dbus/fake_update_engine_client.cc
index 76a2149..e0c46a4 100644
--- a/chromeos/dbus/fake_update_engine_client.cc
+++ b/chromeos/dbus/fake_update_engine_client.cc
@@ -21,9 +21,11 @@
 }
 
 void FakeUpdateEngineClient::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
 }
 
 void FakeUpdateEngineClient::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
 }
 
 bool FakeUpdateEngineClient::HasObserver(Observer* observer) {
@@ -58,6 +60,11 @@
   return last_status;
 }
 
+void FakeUpdateEngineClient::NotifyObserversThatStatusChanged(
+    const UpdateEngineClient::Status& status) {
+  FOR_EACH_OBSERVER(Observer, observers_, UpdateStatusChanged(status));
+}
+
 void FakeUpdateEngineClient::SetChannel(const std::string& target_channel,
                                         bool is_powerwash_allowed) {
 }
diff --git a/chromeos/dbus/fake_update_engine_client.h b/chromeos/dbus/fake_update_engine_client.h
index 146db8b..91384de 100644
--- a/chromeos/dbus/fake_update_engine_client.h
+++ b/chromeos/dbus/fake_update_engine_client.h
@@ -44,6 +44,10 @@
     status_queue_.push(status);
   }
 
+  // Sends status change notification.
+  void NotifyObserversThatStatusChanged(
+      const UpdateEngineClient::Status& status);
+
   // Sets the default UpdateEngineClient::Status. GetLastStatus() returns the
   // value set here if |status_queue_| is empty.
   void set_default_status(const UpdateEngineClient::Status& status);
@@ -68,6 +72,7 @@
   int can_rollback_call_count() const { return can_rollback_call_count_; }
 
  private:
+  ObserverList<Observer> observers_;
   std::queue<UpdateEngineClient::Status> status_queue_;
   UpdateEngineClient::Status default_status_;
   UpdateEngineClient::UpdateCheckResult update_check_result_;
diff --git a/chromeos/dbus/mock_session_manager_client.h b/chromeos/dbus/mock_session_manager_client.h
index aa7e271..c0e4531 100644
--- a/chromeos/dbus/mock_session_manager_client.h
+++ b/chromeos/dbus/mock_session_manager_client.h
@@ -24,8 +24,7 @@
   MOCK_METHOD1(HasObserver, bool(Observer*));
   MOCK_METHOD0(EmitLoginPromptVisible, void(void));
   MOCK_METHOD2(RestartJob, void(int, const std::string&));
-  MOCK_METHOD2(StartSession,
-               void(const std::string&, const StartSessionCallback&));
+  MOCK_METHOD1(StartSession, void(const std::string&));
   MOCK_METHOD0(StopSession, void(void));
   MOCK_METHOD0(StartDeviceWipe, void(void));
   MOCK_METHOD0(RequestLockScreen, void(void));
@@ -43,10 +42,9 @@
   MOCK_METHOD2(StoreDevicePolicy,
                void(const std::string&,
                     const StorePolicyCallback&));
-  MOCK_METHOD4(StorePolicyForUser,
+  MOCK_METHOD3(StorePolicyForUser,
                void(const std::string&,
                     const std::string&,
-                    const std::string&,
                     const StorePolicyCallback&));
   MOCK_METHOD3(StoreDeviceLocalAccountPolicy,
                void(const std::string&,
@@ -55,6 +53,7 @@
   MOCK_METHOD2(SetFlagsForUser,
                void(const std::string&,
                     const std::vector<std::string>&));
+  MOCK_METHOD1(GetServerBackedStateKeys, void(const StateKeysCallback&));
 };
 
 }  // namespace chromeos
diff --git a/chromeos/dbus/pipe_reader.cc b/chromeos/dbus/pipe_reader.cc
index 1e91d75..497f514 100644
--- a/chromeos/dbus/pipe_reader.cc
+++ b/chromeos/dbus/pipe_reader.cc
@@ -5,7 +5,6 @@
 #include "chromeos/dbus/pipe_reader.h"
 
 #include "base/bind.h"
-#include "base/platform_file.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/task_runner.h"
 #include "net/base/file_stream.h"
@@ -16,39 +15,26 @@
 
 PipeReader::PipeReader(const scoped_refptr<base::TaskRunner>& task_runner,
                        const IOCompleteCallback& callback)
-    : write_fd_(-1),
-      io_buffer_(new net::IOBufferWithSize(4096)),
+    : io_buffer_(new net::IOBufferWithSize(4096)),
       task_runner_(task_runner),
       callback_(callback),
       weak_ptr_factory_(this) {}
 
 PipeReader::~PipeReader() {
-  CloseWriteFD();
 }
 
-void PipeReader::CloseWriteFD() {
-  if (write_fd_ == -1)
-    return;
-  if (IGNORE_EINTR(close(write_fd_)) < 0)
-    PLOG(ERROR) << "close";
-  write_fd_ = -1;
-}
-
-bool PipeReader::StartIO() {
+base::File PipeReader::StartIO() {
   // Use a pipe to collect data
   int pipe_fds[2];
   const int status = HANDLE_EINTR(pipe(pipe_fds));
   if (status < 0) {
     PLOG(ERROR) << "pipe";
-    return false;
+    return base::File();
   }
-  write_fd_ = pipe_fds[1];
-  base::PlatformFile data_file_ = pipe_fds[0];
-  // Pass ownership of pipe_fds[0] to data_stream_, which will will close it.
+  base::File pipe_write_end(pipe_fds[1]);
+  // Pass ownership of pipe_fds[0] to data_stream_, which will close it.
   data_stream_.reset(new net::FileStream(
-      data_file_,
-      base::PLATFORM_FILE_READ | base::PLATFORM_FILE_ASYNC,
-      task_runner_));
+      base::File(pipe_fds[0]), task_runner_));
 
   // Post an initial async read to setup data collection
   int rv = data_stream_->Read(
@@ -56,9 +42,9 @@
       base::Bind(&PipeReader::OnDataReady, weak_ptr_factory_.GetWeakPtr()));
   if (rv != net::ERR_IO_PENDING) {
     LOG(ERROR) << "Unable to post initial read";
-    return false;
+    return base::File();
   }
-  return true;
+  return pipe_write_end.Pass();
 }
 
 void PipeReader::OnDataReady(int byte_count) {
@@ -90,7 +76,6 @@
   data_.append(data, byte_count);
 }
 
-
 void PipeReaderForString::GetData(std::string* data) {
   data_.swap(*data);
 }
diff --git a/chromeos/dbus/pipe_reader.h b/chromeos/dbus/pipe_reader.h
index 59d291b..41dcb5e 100644
--- a/chromeos/dbus/pipe_reader.h
+++ b/chromeos/dbus/pipe_reader.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/callback.h"
+#include "base/files/file.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -27,10 +28,6 @@
 // string.  To use:
 //   - Instantiate the appropriate subclass of PipeReader
 //   - Call StartIO() which will create the appropriate FDs.
-//   - Call GetWriteFD() which will return a file descriptor that can
-//     be sent to a separate process which will write data there.
-//   - After handing off the FD, call CloseWriteFD() so there is
-//     only one copy of the FD open.
 //   - As data is received, the PipeReader will collect this data
 //     as appropriate to the subclass.
 //   - When the there is no more data to read, the PipeReader calls
@@ -43,14 +40,12 @@
              const IOCompleteCallback& callback);
   virtual ~PipeReader();
 
-  // Closes writeable descriptor; normally used in parent process after fork.
-  void CloseWriteFD();
-
-  // Starts data collection.  Returns true if stream was setup correctly.
+  // Starts data collection.
+  // Returns the write end of the pipe if stream was setup correctly.
   // On success data will automatically be accumulated into a string that
   // can be retrieved with PipeReader::data().  To shutdown collection delete
   // the instance and/or use PipeReader::OnDataReady(-1).
-  bool StartIO();
+  base::File StartIO();
 
   // Called when pipe data are available.  Can also be used to shutdown
   // data collection by passing -1 for |byte_count|.
@@ -60,11 +55,7 @@
   // with incoming data.
   virtual void AcceptData(const char *data, int length) = 0;
 
-  // Getter for |write_fd_|.
-  int write_fd() const { return write_fd_; }
-
  private:
-  int write_fd_;
   scoped_ptr<net::FileStream> data_stream_;
   scoped_refptr<net::IOBufferWithSize> io_buffer_;
   scoped_refptr<base::TaskRunner> task_runner_;
@@ -94,6 +85,6 @@
   DISALLOW_COPY_AND_ASSIGN(PipeReaderForString);
 };
 
-}
+}  // namespace chromeos
 
 #endif  // CHROMEOS_DBUS_PIPE_READER_H_
diff --git a/chromeos/dbus/session_manager_client.cc b/chromeos/dbus/session_manager_client.cc
index 486ce59..bfa9aa4 100644
--- a/chromeos/dbus/session_manager_client.cc
+++ b/chromeos/dbus/session_manager_client.cc
@@ -4,27 +4,63 @@
 
 #include "chromeos/dbus/session_manager_client.h"
 
-#include <map>
-
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/file_util.h"
 #include "base/files/file_path.h"
 #include "base/location.h"
 #include "base/path_service.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "base/task_runner_util.h"
 #include "base/threading/worker_pool.h"
 #include "chromeos/chromeos_paths.h"
 #include "chromeos/dbus/blocking_method_caller.h"
 #include "chromeos/dbus/cryptohome_client.h"
+#include "crypto/sha2.h"
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "dbus/object_path.h"
 #include "dbus/object_proxy.h"
+#include "policy/proto/device_management_backend.pb.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace chromeos {
 
+namespace {
+
+// Returns a location for |file| that is specific to the given |username|.
+// These paths will be relative to DIR_USER_POLICY_KEYS, and can be used only
+// to store stub files.
+base::FilePath GetUserFilePath(const std::string& username, const char* file) {
+  base::FilePath keys_path;
+  if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &keys_path))
+    return base::FilePath();
+  const std::string sanitized =
+      CryptohomeClient::GetStubSanitizedUsername(username);
+  return keys_path.AppendASCII(sanitized).AppendASCII(file);
+}
+
+// Helper to asynchronously retrieve a file's content.
+std::string GetFileContent(const base::FilePath& path) {
+  std::string result;
+  if (!path.empty())
+    base::ReadFileToString(path, &result);
+  return result;
+}
+
+// Helper to write a file in a background thread.
+void StoreFile(const base::FilePath& path, const std::string& data) {
+  const int size = static_cast<int>(data.size());
+  if (path.empty() ||
+      !base::CreateDirectory(path.DirName()) ||
+      base::WriteFile(path, data.data(), size) != size) {
+    LOG(WARNING) << "Failed to write to " << path.value();
+  }
+}
+
+}  // namespace
+
 // The SessionManagerClient implementation used in production.
 class SessionManagerClientImpl : public SessionManagerClient {
  public:
@@ -71,8 +107,7 @@
                    weak_ptr_factory_.GetWeakPtr()));
   }
 
-  virtual void StartSession(const std::string& user_email,
-                            const StartSessionCallback& callback) OVERRIDE {
+  virtual void StartSession(const std::string& user_email) OVERRIDE {
     dbus::MethodCall method_call(login_manager::kSessionManagerInterface,
                                  login_manager::kSessionManagerStartSession);
     dbus::MessageWriter writer(&method_call);
@@ -82,8 +117,7 @@
         &method_call,
         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::Bind(&SessionManagerClientImpl::OnStartSession,
-                   weak_ptr_factory_.GetWeakPtr(),
-                   callback));
+                   weak_ptr_factory_.GetWeakPtr()));
   }
 
   virtual void StopSession() OVERRIDE {
@@ -204,7 +238,6 @@
   virtual void StorePolicyForUser(
       const std::string& username,
       const std::string& policy_blob,
-      const std::string& ignored_policy_key,
       const StorePolicyCallback& callback) OVERRIDE {
     CallStorePolicyByUsername(login_manager::kSessionManagerStorePolicyForUser,
                               username,
@@ -236,6 +269,20 @@
         dbus::ObjectProxy::EmptyResponseCallback());
   }
 
+  virtual void GetServerBackedStateKeys(const StateKeysCallback& callback)
+      OVERRIDE {
+    dbus::MethodCall method_call(
+        login_manager::kSessionManagerInterface,
+        login_manager::kSessionManagerGetServerBackedStateKeys);
+
+    session_manager_proxy_->CallMethod(
+        &method_call,
+        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::Bind(&SessionManagerClientImpl::OnGetServerBackedStateKeys,
+                   weak_ptr_factory_.GetWeakPtr(),
+                   callback));
+  }
+
  protected:
   virtual void Init(dbus::Bus* bus) OVERRIDE {
     session_manager_proxy_ = bus->GetObjectProxy(
@@ -334,18 +381,10 @@
   }
 
   // Called when kSessionManagerStartSession method is complete.
-  void OnStartSession(const StartSessionCallback& callback,
-                      dbus::Response* response) {
-    bool success = false;
-    if (!response) {
-      LOG(ERROR) << "Failed to call "
-                 << login_manager::kSessionManagerStartSession;
-    } else {
-      dbus::MessageReader reader(response);
-      if (!reader.PopBool(&success))
-        LOG(ERROR) << "Invalid response: " << response->ToString();
-    }
-    callback.Run(success);
+  void OnStartSession(dbus::Response* response) {
+    LOG_IF(ERROR, !response)
+        << "Failed to call "
+        << login_manager::kSessionManagerStartSession;
   }
 
   // Called when kSessionManagerStopSession method is complete.
@@ -482,6 +521,39 @@
     LOG_IF(ERROR, !success) << "Failed to connect to " << signal_name;
   }
 
+  // Called when kSessionManagerGetServerBackedStateKeys method is complete.
+  void OnGetServerBackedStateKeys(const StateKeysCallback& callback,
+                                  dbus::Response* response) {
+    std::vector<std::string> state_keys;
+    if (!response) {
+      LOG(ERROR) << "Failed to call "
+                 << login_manager::kSessionManagerStartSession;
+    } else {
+      dbus::MessageReader reader(response);
+      dbus::MessageReader array_reader(NULL);
+
+      if (!reader.PopArray(&array_reader)) {
+        LOG(ERROR) << "Bad response: " << response->ToString();
+      } else {
+        while (array_reader.HasMoreData()) {
+          const uint8* data = NULL;
+          size_t size = 0;
+          if (!array_reader.PopArrayOfBytes(&data, &size)) {
+            LOG(ERROR) << "Bad response: " << response->ToString();
+            state_keys.clear();
+            break;
+          }
+          state_keys.push_back(
+              std::string(reinterpret_cast<const char*>(data), size));
+        }
+      }
+    }
+
+    if (!callback.is_null())
+      callback.Run(state_keys);
+  }
+
+
   dbus::ObjectProxy* session_manager_proxy_;
   scoped_ptr<BlockingMethodCaller> blocking_method_caller_;
   ObserverList<Observer> observers_;
@@ -528,10 +600,7 @@
   }
   virtual void EmitLoginPromptVisible() OVERRIDE {}
   virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {}
-  virtual void StartSession(const std::string& user_email,
-                            const StartSessionCallback& callback) OVERRIDE {
-    callback.Run(true);
-  }
+  virtual void StartSession(const std::string& user_email) OVERRIDE {}
   virtual void StopSession() OVERRIDE {}
   virtual void StartDeviceWipe() OVERRIDE {}
   virtual void RequestLockScreen() OVERRIDE {
@@ -548,58 +617,94 @@
       const ActiveSessionsCallback& callback) OVERRIDE {}
   virtual void RetrieveDevicePolicy(
       const RetrievePolicyCallback& callback) OVERRIDE {
-    callback.Run(device_policy_);
+    base::FilePath owner_key_path;
+    if (!PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) {
+      callback.Run("");
+      return;
+    }
+    base::FilePath device_policy_path =
+        owner_key_path.DirName().AppendASCII("stub_device_policy");
+    base::PostTaskAndReplyWithResult(
+        base::WorkerPool::GetTaskRunner(false),
+        FROM_HERE,
+        base::Bind(&GetFileContent, device_policy_path),
+        callback);
   }
   virtual void RetrievePolicyForUser(
       const std::string& username,
       const RetrievePolicyCallback& callback) OVERRIDE {
-    callback.Run(user_policies_[username]);
+    base::PostTaskAndReplyWithResult(
+        base::WorkerPool::GetTaskRunner(false),
+        FROM_HERE,
+        base::Bind(&GetFileContent, GetUserFilePath(username, "stub_policy")),
+        callback);
   }
   virtual std::string BlockingRetrievePolicyForUser(
       const std::string& username) OVERRIDE {
-    return user_policies_[username];
+    return GetFileContent(GetUserFilePath(username, "stub_policy"));
   }
   virtual void RetrieveDeviceLocalAccountPolicy(
       const std::string& account_name,
       const RetrievePolicyCallback& callback) OVERRIDE {
-    callback.Run(user_policies_[account_name]);
+    RetrievePolicyForUser(account_name, callback);
   }
   virtual void StoreDevicePolicy(const std::string& policy_blob,
                                  const StorePolicyCallback& callback) OVERRIDE {
-    device_policy_ = policy_blob;
-    callback.Run(true);
+    enterprise_management::PolicyFetchResponse response;
+    base::FilePath owner_key_path;
+    if (!response.ParseFromString(policy_blob) ||
+        !PathService::Get(chromeos::FILE_OWNER_KEY, &owner_key_path)) {
+      callback.Run(false);
+      return;
+    }
+
+    if (response.has_new_public_key()) {
+      base::WorkerPool::PostTask(
+          FROM_HERE,
+          base::Bind(&StoreFile, owner_key_path, response.new_public_key()),
+          false);
+    }
+
+    // Chrome will attempt to retrieve the device policy right after storing
+    // during enrollment, so make sure it's written before signaling
+    // completion.
+    // Note also that the owner key will be written before the device policy,
+    // if it was present in the blob.
+    base::FilePath device_policy_path =
+        owner_key_path.DirName().AppendASCII("stub_device_policy");
+    base::WorkerPool::PostTaskAndReply(
+        FROM_HERE,
+        base::Bind(&StoreFile, device_policy_path, policy_blob),
+        base::Bind(callback, true),
+        false);
   }
   virtual void StorePolicyForUser(
       const std::string& username,
       const std::string& policy_blob,
-      const std::string& policy_key,
       const StorePolicyCallback& callback) OVERRIDE {
-    if (policy_key.empty()) {
-      user_policies_[username] = policy_blob;
-      callback.Run(true);
-      return;
-    }
     // The session manager writes the user policy key to a well-known
     // location. Do the same with the stub impl, so that user policy works and
     // can be tested on desktop builds.
-    // TODO(joaodasilva): parse the PolicyFetchResponse in |policy_blob| to get
-    // the policy key directly, after moving the policy protobufs to a top-level
-    // directory. The |policy_key| argument to this method can then be removed.
-    // http://crbug.com/240269
-    base::FilePath key_path;
-    if (!PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &key_path)) {
+    enterprise_management::PolicyFetchResponse response;
+    if (!response.ParseFromString(policy_blob)) {
       callback.Run(false);
       return;
     }
-    const std::string sanitized =
-        CryptohomeClient::GetStubSanitizedUsername(username);
-    key_path = key_path.AppendASCII(sanitized).AppendASCII("policy.pub");
-    // Assume that the key write is successful.
-    user_policies_[username] = policy_blob;
+
+    if (response.has_new_public_key()) {
+      base::FilePath key_path = GetUserFilePath(username, "policy.pub");
+      base::WorkerPool::PostTask(
+          FROM_HERE,
+          base::Bind(&StoreFile, key_path, response.new_public_key()),
+          false);
+    }
+
+    // This file isn't read directly by Chrome, but is used by this class to
+    // reload the user policy across restarts.
+    base::FilePath stub_policy_path = GetUserFilePath(username, "stub_policy");
     base::WorkerPool::PostTaskAndReply(
         FROM_HERE,
-        base::Bind(&SessionManagerClientStubImpl::StoreFileInBackground,
-                   key_path, policy_key),
+        base::Bind(&StoreFile, stub_policy_path, policy_blob),
         base::Bind(callback, true),
         false);
   }
@@ -607,27 +712,26 @@
       const std::string& account_name,
       const std::string& policy_blob,
       const StorePolicyCallback& callback) OVERRIDE {
-    user_policies_[account_name] = policy_blob;
-    callback.Run(true);
+    StorePolicyForUser(account_name, policy_blob, callback);
   }
   virtual void SetFlagsForUser(const std::string& username,
                                const std::vector<std::string>& flags) OVERRIDE {
   }
 
-  static void StoreFileInBackground(const base::FilePath& path,
-                                    const std::string& data) {
-    const int size = static_cast<int>(data.size());
-    if (!base::CreateDirectory(path.DirName()) ||
-        base::WriteFile(path, data.data(), size) != size) {
-      LOG(WARNING) << "Failed to write policy key to " << path.value();
-    }
+  virtual void GetServerBackedStateKeys(const StateKeysCallback& callback)
+      OVERRIDE {
+    std::vector<std::string> state_keys;
+    for (int i = 0; i < 5; ++i)
+      state_keys.push_back(crypto::SHA256HashString(base::IntToString(i)));
+
+    if (!callback.is_null())
+      callback.Run(state_keys);
   }
 
  private:
   StubDelegate* delegate_;  // Weak pointer; may be NULL.
   ObserverList<Observer> observers_;
   std::string device_policy_;
-  std::map<std::string, std::string> user_policies_;
 
   DISALLOW_COPY_AND_ASSIGN(SessionManagerClientStubImpl);
 };
diff --git a/chromeos/dbus/session_manager_client.h b/chromeos/dbus/session_manager_client.h
index 9e3ca89..d4c0706 100644
--- a/chromeos/dbus/session_manager_client.h
+++ b/chromeos/dbus/session_manager_client.h
@@ -7,6 +7,7 @@
 
 #include <map>
 #include <string>
+#include <vector>
 
 #include "base/callback.h"
 #include "base/observer_list.h"
@@ -70,13 +71,8 @@
   // Restarts a job referenced by |pid| with the provided command line.
   virtual void RestartJob(int pid, const std::string& command_line) = 0;
 
-  // Used for StartSession. Takes a boolean indicating whether the
-  // operation was successful or not.
-  typedef base::Callback<void(bool success)> StartSessionCallback;
-
   // Starts the session for the user.
-  virtual void StartSession(const std::string& user_email,
-                            const StartSessionCallback& callback) = 0;
+  virtual void StartSession(const std::string& user_email) = 0;
 
   // Stops the current session.
   virtual void StopSession() = 0;
@@ -156,11 +152,8 @@
 
   // Attempts to asynchronously store |policy_blob| as user policy for the given
   // |username|. Upon completion of the store attempt, we will call callback.
-  // The |policy_key| argument is not sent to the session manager, but is used
-  // by the stub implementation to enable policy validation on desktop builds.
   virtual void StorePolicyForUser(const std::string& username,
                                   const std::string& policy_blob,
-                                  const std::string& policy_key,
                                   const StorePolicyCallback& callback) = 0;
 
   // Sends a request to store a policy blob for the specified device-local
@@ -175,6 +168,18 @@
   virtual void SetFlagsForUser(const std::string& username,
                                const std::vector<std::string>& flags) = 0;
 
+  typedef base::Callback<void(const std::vector<std::string>& state_keys)>
+      StateKeysCallback;
+
+  // Get the currently valid server-backed state keys for the device.
+  // Server-backed state keys are opaque, device-unique, time-dependent,
+  // client-determined identifiers that are used for keying state in the cloud
+  // for the device to retrieve after a device factory reset.
+  //
+  // The state keys are returned asynchronously via |callback|. The callback
+  // will be invoked with an empty state key vector in case of errors.
+  virtual void GetServerBackedStateKeys(const StateKeysCallback& callback) = 0;
+
   // Creates the instance.
   static SessionManagerClient* Create(DBusClientImplementationType type);
 
diff --git a/chromeos/dbus/shill_ipconfig_client.cc b/chromeos/dbus/shill_ipconfig_client.cc
index 7af7fa2..48861ed 100644
--- a/chromeos/dbus/shill_ipconfig_client.cc
+++ b/chromeos/dbus/shill_ipconfig_client.cc
@@ -51,6 +51,7 @@
                              const VoidDBusMethodCallback& callback) OVERRIDE;
   virtual void Remove(const dbus::ObjectPath& ipconfig_path,
                       const VoidDBusMethodCallback& callback) OVERRIDE;
+  virtual ShillIPConfigClient::TestInterface* GetTestInterface() OVERRIDE;
 
  protected:
   virtual void Init(dbus::Bus* bus) OVERRIDE {
@@ -164,6 +165,11 @@
   GetHelper(ipconfig_path)->CallVoidMethod(&method_call, callback);
 }
 
+ShillIPConfigClient::TestInterface*
+ShillIPConfigClientImpl::GetTestInterface() {
+  return NULL;
+}
+
 }  // namespace
 
 ShillIPConfigClient::ShillIPConfigClient() {}
diff --git a/chromeos/dbus/shill_ipconfig_client.h b/chromeos/dbus/shill_ipconfig_client.h
index ef144b2..379d8e9 100644
--- a/chromeos/dbus/shill_ipconfig_client.h
+++ b/chromeos/dbus/shill_ipconfig_client.h
@@ -37,6 +37,17 @@
  public:
   typedef ShillClientHelper::PropertyChangedHandler PropertyChangedHandler;
   typedef ShillClientHelper::DictionaryValueCallback DictionaryValueCallback;
+
+  class TestInterface {
+   public:
+    // Adds an IPConfig entry.
+    virtual void AddIPConfig(const std::string& ip_config_path,
+                             const base::DictionaryValue& properties) = 0;
+
+   protected:
+    virtual ~TestInterface() {}
+  };
+
   virtual ~ShillIPConfigClient();
 
   // Factory function, creates a new instance which is owned by the caller.
@@ -81,6 +92,9 @@
   virtual void Remove(const dbus::ObjectPath& ipconfig_path,
                       const VoidDBusMethodCallback& callback) = 0;
 
+  // Returns an interface for testing (stub only), or returns NULL.
+  virtual ShillIPConfigClient::TestInterface* GetTestInterface() = 0;
+
  protected:
   friend class ShillIPConfigClientTest;
 
diff --git a/chromeos/disks/disk_mount_manager.cc b/chromeos/disks/disk_mount_manager.cc
index a781107..58f1608 100644
--- a/chromeos/disks/disk_mount_manager.cc
+++ b/chromeos/disks/disk_mount_manager.cc
@@ -31,11 +31,15 @@
     DCHECK(dbus_thread_manager);
     cros_disks_client_ = dbus_thread_manager->GetCrosDisksClient();
     DCHECK(cros_disks_client_);
-    cros_disks_client_->SetUpConnections(
+    cros_disks_client_->SetMountEventHandler(
         base::Bind(&DiskMountManagerImpl::OnMountEvent,
-                   weak_ptr_factory_.GetWeakPtr()),
+                   weak_ptr_factory_.GetWeakPtr()));
+    cros_disks_client_->SetMountCompletedHandler(
         base::Bind(&DiskMountManagerImpl::OnMountCompleted,
                    weak_ptr_factory_.GetWeakPtr()));
+    cros_disks_client_->SetFormatCompletedHandler(
+        base::Bind(&DiskMountManagerImpl::OnFormatCompleted,
+                   weak_ptr_factory_.GetWeakPtr()));
   }
 
   virtual ~DiskMountManagerImpl() {
@@ -103,7 +107,7 @@
     MountPointMap::const_iterator mount_point = mount_points_.find(mount_path);
     if (mount_point == mount_points_.end()) {
       LOG(ERROR) << "Mount point with path \"" << mount_path << "\" not found.";
-      OnFormatDevice(mount_path, false);
+      OnFormatCompleted(FORMAT_ERROR_UNKNOWN, mount_path);
       return;
     }
 
@@ -111,7 +115,7 @@
     DiskMap::const_iterator disk = disks_.find(device_path);
     if (disk == disks_.end()) {
       LOG(ERROR) << "Device with path \"" << device_path << "\" not found.";
-      OnFormatDevice(device_path, false);
+      OnFormatCompleted(FORMAT_ERROR_UNKNOWN, device_path);
       return;
     }
 
@@ -280,7 +284,7 @@
     if (success) {
       // Do standard processing for Unmount event.
       OnUnmountPath(UnmountPathCallback(), true, mount_path);
-      LOG(INFO) << mount_path <<  " unmounted.";
+      VLOG(1) << mount_path <<  " unmounted.";
     }
     // This is safe as long as all callbacks are called on the same thread as
     // UnmountDeviceRecursively.
@@ -378,7 +382,7 @@
         disks_.find(device_path) != disks_.end()) {
       FormatUnmountedDevice(device_path);
     } else {
-      OnFormatDevice(device_path, false);
+      OnFormatCompleted(FORMAT_ERROR_UNKNOWN, device_path);
     }
   }
 
@@ -388,23 +392,27 @@
     DCHECK(disk != disks_.end() && disk->second->mount_path().empty());
 
     const char kFormatVFAT[] = "vfat";
-    cros_disks_client_->FormatDevice(
+    cros_disks_client_->Format(
         device_path,
         kFormatVFAT,
-        base::Bind(&DiskMountManagerImpl::OnFormatDevice,
+        base::Bind(&DiskMountManagerImpl::OnFormatStarted,
                    weak_ptr_factory_.GetWeakPtr(),
                    device_path),
-        base::Bind(&DiskMountManagerImpl::OnFormatDevice,
+        base::Bind(&DiskMountManagerImpl::OnFormatCompleted,
                    weak_ptr_factory_.GetWeakPtr(),
-                   device_path,
-                   false));
+                   FORMAT_ERROR_UNKNOWN,
+                   device_path));
   }
 
-  // Callback for FormatDevice.
-  // TODO(tbarzic): Pass FormatError instead of bool.
-  void OnFormatDevice(const std::string& device_path, bool success) {
-    FormatError error_code = success ? FORMAT_ERROR_NONE : FORMAT_ERROR_UNKNOWN;
-    NotifyFormatStatusUpdate(FORMAT_STARTED, error_code, device_path);
+  // Callback for Format.
+  void OnFormatStarted(const std::string& device_path) {
+    NotifyFormatStatusUpdate(FORMAT_STARTED, FORMAT_ERROR_NONE, device_path);
+  }
+
+  // Callback to handle FormatCompleted signal and Format method call failure.
+  void OnFormatCompleted(FormatError error_code,
+                         const std::string& device_path) {
+    NotifyFormatStatusUpdate(FORMAT_COMPLETED, error_code, device_path);
   }
 
   // Callbcak for GetDeviceProperties.
@@ -513,20 +521,6 @@
         NotifyDeviceStatusUpdate(DEVICE_SCANNED, device_path);
         break;
       }
-      case CROS_DISKS_FORMATTING_FINISHED: {
-        std::string path;
-        FormatError error_code;
-        ParseFormatFinishedPath(device_path, &path, &error_code);
-
-        if (!path.empty()) {
-          NotifyFormatStatusUpdate(FORMAT_COMPLETED, error_code, path);
-          break;
-        }
-
-        LOG(ERROR) << "Error while handling disks metadata. Cannot find "
-                   << "device that is being formatted.";
-        break;
-      }
       default: {
         LOG(ERROR) << "Unknown event: " << event;
       }
@@ -560,31 +554,6 @@
                       OnFormatEvent(event, error_code, device_path));
   }
 
-  // Converts file path to device path.
-  void ParseFormatFinishedPath(const std::string& received_path,
-                               std::string* device_path,
-                               FormatError* error_code) {
-    // TODO(tbarzic): Refactor error handling code like here.
-    // Appending "!" is not the best way to indicate error.  This kind of trick
-    // also makes it difficult to simplify the code paths.
-    bool success = !StartsWithASCII(received_path, "!", true);
-    *error_code = success ? FORMAT_ERROR_NONE : FORMAT_ERROR_UNKNOWN;
-
-    std::string path = received_path.substr(success ? 0 : 1);
-
-    // Depending on cros disks implementation the event may return either file
-    // path or device path. We want to use device path.
-    for (DiskMountManager::DiskMap::iterator it = disks_.begin();
-         it != disks_.end(); ++it) {
-      // Skip the leading '!' on the failure case.
-      if (it->second->file_path() == path ||
-          it->second->device_path() == path) {
-        *device_path = it->second->device_path();
-        return;
-      }
-    }
-  }
-
   // Finds system path prefix from |system_path|.
   const std::string& FindSystemPathPrefix(const std::string& system_path) {
     if (system_path.empty())
diff --git a/chromeos/disks/disk_mount_manager_unittest.cc b/chromeos/disks/disk_mount_manager_unittest.cc
index 36e67ad..fd2fab0 100644
--- a/chromeos/disks/disk_mount_manager_unittest.cc
+++ b/chromeos/disks/disk_mount_manager_unittest.cc
@@ -207,7 +207,7 @@
 // Tests that the observer gets notified on attempt to format non existent mount
 // point.
 TEST_F(DiskMountManagerTest, Format_NotMounted) {
-  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
+  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                        chromeos::FORMAT_ERROR_UNKNOWN,
                                        "/mount/non_existent"))
       .Times(1);
@@ -216,7 +216,7 @@
 
 // Tests that it is not possible to format archive mount point.
 TEST_F(DiskMountManagerTest, Format_Archive) {
-  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
+  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                        chromeos::FORMAT_ERROR_UNKNOWN,
                                        "/archive/source_path"))
       .Times(1);
@@ -243,7 +243,7 @@
                            "/device/mount_path")))
         .Times(1);
 
-    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
+    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                          chromeos::FORMAT_ERROR_UNKNOWN,
                                          "/device/source_path"))
         .Times(1);
@@ -261,7 +261,7 @@
             fake_cros_disks_client_->last_unmount_device_path());
   EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
             fake_cros_disks_client_->last_unmount_options());
-  EXPECT_EQ(0, fake_cros_disks_client_->format_device_call_count());
+  EXPECT_EQ(0, fake_cros_disks_client_->format_call_count());
 
   // The device mount should still be here.
   EXPECT_TRUE(HasMountPoint("/device/mount_path"));
@@ -271,7 +271,7 @@
 // process.
 TEST_F(DiskMountManagerTest, Format_FormatFailsToStart) {
   // Before formatting mounted device, the device should be unmounted.
-  // In this test, unmount will succeed, but call to FormatDevice method will
+  // In this test, unmount will succeed, but call to Format method will
   // fail.
 
   // Set up expectations for observer mock.
@@ -287,13 +287,13 @@
                            "/device/mount_path")))
         .Times(1);
 
-    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
+    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                          chromeos::FORMAT_ERROR_UNKNOWN,
                                          "/device/source_path"))
         .Times(1);
   }
 
-  fake_cros_disks_client_->MakeFormatDeviceFail();
+  fake_cros_disks_client_->MakeFormatFail();
   // Start the test.
   DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
 
@@ -305,11 +305,10 @@
             fake_cros_disks_client_->last_unmount_device_path());
   EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
             fake_cros_disks_client_->last_unmount_options());
-  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
+  EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
   EXPECT_EQ("/device/source_path",
-            fake_cros_disks_client_->last_format_device_device_path());
-  EXPECT_EQ("vfat",
-            fake_cros_disks_client_->last_format_device_filesystem());
+            fake_cros_disks_client_->last_format_device_path());
+  EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
 
   // The device mount should be gone.
   EXPECT_FALSE(HasMountPoint("/device/mount_path"));
@@ -323,9 +322,9 @@
   // is successfully started.
 
   // Set up expectations for observer mock.
-  // The observer should get two FORMAT_STARTED events, one for each format
-  // request, but with different error codes (the formatting will be started
-  // only for the first request).
+  // The observer should get a FORMAT_STARTED event for one format request and a
+  // FORMAT_COMPLETED with an error code for the other format request. The
+  // formatting will be started only for the first request.
   // There should be only one UNMOUNTING event. The result of the second one
   // should not be reported as the mount point will go away after the first
   // request.
@@ -342,7 +341,7 @@
                            "/device/mount_path")))
         .Times(1);
 
-    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
+    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
                                          chromeos::FORMAT_ERROR_UNKNOWN,
                                          "/device/source_path"))
         .Times(1);
@@ -368,11 +367,11 @@
             fake_cros_disks_client_->last_unmount_device_path());
   EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
             fake_cros_disks_client_->last_unmount_options());
-  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
+  EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
   EXPECT_EQ("/device/source_path",
-            fake_cros_disks_client_->last_format_device_device_path());
+            fake_cros_disks_client_->last_format_device_path());
   EXPECT_EQ("vfat",
-            fake_cros_disks_client_->last_format_device_filesystem());
+            fake_cros_disks_client_->last_format_filesystem());
 
   // The device mount should be gone.
   EXPECT_FALSE(HasMountPoint("/device/mount_path"));
@@ -380,13 +379,13 @@
 
 // Tests the case when the format process actually starts and fails.
 TEST_F(DiskMountManagerTest, Format_FormatFails) {
-  // Both unmount and format device cals are successfull in this test.
+  // Both unmount and format device cals are successful in this test.
 
   // Set up expectations for observer mock.
   // The observer should get notified that the device was unmounted and that
   // formatting has started.
   // After the formatting starts, the test will simulate failing
-  // FORMATTING_FINISHED signal, so the observer should also be notified the
+  // FORMAT_COMPLETED signal, so the observer should also be notified the
   // formatting has failed (FORMAT_COMPLETED event).
   {
     InSequence s;
@@ -412,7 +411,7 @@
   // Start the test.
   DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
 
-  // Wait for Unmount and FormatDevice calls to end.
+  // Wait for Unmount and Format calls to end.
   message_loop_.RunUntilIdle();
 
   EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
@@ -420,76 +419,25 @@
             fake_cros_disks_client_->last_unmount_device_path());
   EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
             fake_cros_disks_client_->last_unmount_options());
-  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
+  EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
   EXPECT_EQ("/device/source_path",
-            fake_cros_disks_client_->last_format_device_device_path());
-  EXPECT_EQ("vfat",
-            fake_cros_disks_client_->last_format_device_filesystem());
+            fake_cros_disks_client_->last_format_device_path());
+  EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
 
   // The device should be unmounted by now.
   EXPECT_FALSE(HasMountPoint("/device/mount_path"));
 
-  // Send failing FORMATTING_FINISHED signal.
+  // Send failing FORMAT_COMPLETED signal.
   // The failure is marked by ! in fromt of the path (but this should change
   // soon).
-  fake_cros_disks_client_->SendMountEvent(
-      chromeos::CROS_DISKS_FORMATTING_FINISHED, "!/device/source_path");
-}
-
-// Tests the same case as Format_FormatFails, but the FORMATTING_FINISHED event
-// is sent with file_path of the formatted device (instead of its device path).
-TEST_F(DiskMountManagerTest, Format_FormatFailsAndReturnFilePath) {
-  // Set up expectations for observer mock.
-  {
-    InSequence s;
-
-    EXPECT_CALL(observer_,
-        OnMountEvent(DiskMountManager::UNMOUNTING,
-                     chromeos::MOUNT_ERROR_NONE,
-                     Field(&DiskMountManager::MountPointInfo::mount_path,
-                           "/device/mount_path")))
-        .Times(1);
-
-    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
-                                         chromeos::FORMAT_ERROR_NONE,
-                                         "/device/source_path"))
-        .Times(1);
-
-    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
-                                         chromeos::FORMAT_ERROR_UNKNOWN,
-                                         "/device/source_path"))
-        .Times(1);
-  }
-
-  // Start test.
-  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
-
-  // Wait for Unmount and FormatDevice calls to end.
-  message_loop_.RunUntilIdle();
-
-  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
-  EXPECT_EQ("/device/mount_path",
-            fake_cros_disks_client_->last_unmount_device_path());
-  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
-            fake_cros_disks_client_->last_unmount_options());
-  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
-  EXPECT_EQ("/device/source_path",
-            fake_cros_disks_client_->last_format_device_device_path());
-  EXPECT_EQ("vfat",
-            fake_cros_disks_client_->last_format_device_filesystem());
-
-  // The device should be unmounted by now.
-  EXPECT_FALSE(HasMountPoint("/device/mount_path"));
-
-  // Send failing FORMATTING_FINISHED signal with the device's file path.
-  fake_cros_disks_client_->SendMountEvent(
-      chromeos::CROS_DISKS_FORMATTING_FINISHED, "!/device/file_path");
+  fake_cros_disks_client_->SendFormatCompletedEvent(
+      chromeos::FORMAT_ERROR_UNKNOWN, "/device/source_path");
 }
 
 // Tests the case when formatting completes successfully.
 TEST_F(DiskMountManagerTest, Format_FormatSuccess) {
   // Set up cros disks client mocks.
-  // Both unmount and format device cals are successfull in this test.
+  // Both unmount and format device cals are successful in this test.
 
   // Set up expectations for observer mock.
   // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED
@@ -518,7 +466,7 @@
   // Start the test.
   DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
 
-  // Wait for Unmount and FormatDevice calls to end.
+  // Wait for Unmount and Format calls to end.
   message_loop_.RunUntilIdle();
 
   EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
@@ -526,24 +474,23 @@
             fake_cros_disks_client_->last_unmount_device_path());
   EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
             fake_cros_disks_client_->last_unmount_options());
-  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
+  EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
   EXPECT_EQ("/device/source_path",
-            fake_cros_disks_client_->last_format_device_device_path());
-  EXPECT_EQ("vfat",
-            fake_cros_disks_client_->last_format_device_filesystem());
+            fake_cros_disks_client_->last_format_device_path());
+  EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
 
   // The device should be unmounted by now.
   EXPECT_FALSE(HasMountPoint("/device/mount_path"));
 
   // Simulate cros_disks reporting success.
-  fake_cros_disks_client_->SendMountEvent(
-      chromeos::CROS_DISKS_FORMATTING_FINISHED, "/device/source_path");
+  fake_cros_disks_client_->SendFormatCompletedEvent(
+      chromeos::FORMAT_ERROR_NONE, "/device/source_path");
 }
 
 // Tests that it's possible to format the device twice in a row (this may not be
 // true if the list of pending formats is not properly cleared).
 TEST_F(DiskMountManagerTest, Format_ConsecutiveFormatCalls) {
-  // All unmount and format device cals are successfull in this test.
+  // All unmount and format device cals are successful in this test.
   // Each of the should be made twice (once for each formatting task).
 
   // Set up expectations for observer mock.
@@ -579,7 +526,7 @@
   // Start the test.
   DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
 
-  // Wait for Unmount and FormatDevice calls to end.
+  // Wait for Unmount and Format calls to end.
   message_loop_.RunUntilIdle();
 
   EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
@@ -587,18 +534,17 @@
             fake_cros_disks_client_->last_unmount_device_path());
   EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
             fake_cros_disks_client_->last_unmount_options());
-  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
+  EXPECT_EQ(1, fake_cros_disks_client_->format_call_count());
   EXPECT_EQ("/device/source_path",
-            fake_cros_disks_client_->last_format_device_device_path());
-  EXPECT_EQ("vfat",
-            fake_cros_disks_client_->last_format_device_filesystem());
+            fake_cros_disks_client_->last_format_device_path());
+  EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
 
   // The device should be unmounted by now.
   EXPECT_FALSE(HasMountPoint("/device/mount_path"));
 
   // Simulate cros_disks reporting success.
-  fake_cros_disks_client_->SendMountEvent(
-      chromeos::CROS_DISKS_FORMATTING_FINISHED, "/device/source_path");
+  fake_cros_disks_client_->SendFormatCompletedEvent(
+      chromeos::FORMAT_ERROR_NONE, "/device/source_path");
 
   // Simulate the device remounting.
   fake_cros_disks_client_->SendMountCompletedEvent(
@@ -612,7 +558,7 @@
   // Try formatting again.
   DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
 
-  // Wait for Unmount and FormatDevice calls to end.
+  // Wait for Unmount and Format calls to end.
   message_loop_.RunUntilIdle();
 
   EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
@@ -620,15 +566,14 @@
             fake_cros_disks_client_->last_unmount_device_path());
   EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
             fake_cros_disks_client_->last_unmount_options());
-  EXPECT_EQ(2, fake_cros_disks_client_->format_device_call_count());
+  EXPECT_EQ(2, fake_cros_disks_client_->format_call_count());
   EXPECT_EQ("/device/source_path",
-            fake_cros_disks_client_->last_format_device_device_path());
-  EXPECT_EQ("vfat",
-            fake_cros_disks_client_->last_format_device_filesystem());
+            fake_cros_disks_client_->last_format_device_path());
+  EXPECT_EQ("vfat", fake_cros_disks_client_->last_format_filesystem());
 
   // Simulate cros_disks reporting success.
-  fake_cros_disks_client_->SendMountEvent(
-      chromeos::CROS_DISKS_FORMATTING_FINISHED, "/device/source_path");
+  fake_cros_disks_client_->SendFormatCompletedEvent(
+      chromeos::FORMAT_ERROR_NONE, "/device/source_path");
 }
 
 }  // namespace
diff --git a/chromeos/network/device_state.cc b/chromeos/network/device_state.cc
index 9019d33..0880ef7 100644
--- a/chromeos/network/device_state.cc
+++ b/chromeos/network/device_state.cc
@@ -8,12 +8,14 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "chromeos/network/network_event_log.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace chromeos {
 
 DeviceState::DeviceState(const std::string& path)
     : ManagedState(MANAGED_TYPE_DEVICE, path),
+      allow_roaming_(false),
       provider_requires_roaming_(false),
       support_network_scan_(false),
       scanning_(false),
@@ -38,6 +40,8 @@
     return GetBooleanValue(key, value, &scanning_);
   } else if (key == shill::kSupportNetworkScanProperty) {
     return GetBooleanValue(key, value, &support_network_scan_);
+  } else if (key == shill::kCellularAllowRoamingProperty) {
+    return GetBooleanValue(key, value, &allow_roaming_);
   } else if (key == shill::kProviderRequiresRoamingProperty) {
     return GetBooleanValue(key, value, &provider_requires_roaming_);
   } else if (key == shill::kHomeProviderProperty) {
@@ -118,6 +122,12 @@
     return GetBooleanValue(key, value, &sim_present_);
   } else if (key == shill::kEapAuthenticationCompletedProperty) {
     return GetBooleanValue(key, value, &eap_authentication_completed_);
+  } else if (key == shill::kIPConfigsProperty) {
+    // If kIPConfigsProperty changes, clear any previous ip_configs_.
+    // ShillPropertyhandler will request the IPConfig objects which will trigger
+    // calls to IPConfigPropertiesChanged.
+    ip_configs_.Clear();
+    return false;  // No actual state change.
   }
   return false;
 }
@@ -132,6 +142,22 @@
   return false;
 }
 
+void DeviceState::IPConfigPropertiesChanged(
+    const std::string& ip_config_path,
+    const base::DictionaryValue& properties) {
+  base::DictionaryValue* ip_config = NULL;
+  if (ip_configs_.GetDictionaryWithoutPathExpansion(
+          ip_config_path, &ip_config)) {
+    NET_LOG_EVENT("IPConfig Updated: " + ip_config_path, path());
+    ip_config->Clear();
+  } else {
+    NET_LOG_EVENT("IPConfig Added: " + ip_config_path, path());
+    ip_config = new base::DictionaryValue;
+    ip_configs_.SetWithoutPathExpansion(ip_config_path, ip_config);
+  }
+  ip_config->MergeDictionary(&properties);
+}
+
 std::string DeviceState::GetFormattedMacAddress() const {
   if (mac_address_.size() % 2 != 0)
     return mac_address_;
diff --git a/chromeos/network/device_state.h b/chromeos/network/device_state.h
index f0d622f..1da679c 100644
--- a/chromeos/network/device_state.h
+++ b/chromeos/network/device_state.h
@@ -26,6 +26,9 @@
   virtual bool InitialPropertiesReceived(
       const base::DictionaryValue& properties) OVERRIDE;
 
+  void IPConfigPropertiesChanged(const std::string& ip_config_path,
+                                 const base::DictionaryValue& properties);
+
   // Accessors
   const std::string& mac_address() const { return mac_address_; }
 
@@ -34,6 +37,7 @@
 
   // Cellular specific accessors
   const std::string& home_provider_id() const { return home_provider_id_; }
+  bool allow_roaming() const { return allow_roaming_; }
   bool provider_requires_roaming() const { return provider_requires_roaming_; }
   bool support_network_scan() const { return support_network_scan_; }
   bool scanning() const { return scanning_; }
@@ -47,7 +51,11 @@
   const std::string& iccid() const { return iccid_; }
   const std::string& mdn() const { return mdn_; }
   const CellularScanResults& scan_results() const { return scan_results_; }
+
+  // Do not use this. It exists temporarily for internet_options_handler.cc
+  // which is being deprecated.
   const base::DictionaryValue& properties() const { return properties_; }
+  const base::DictionaryValue& ip_configs() const { return ip_configs_; }
 
   // Ethernet specific accessors
   bool eap_authentication_completed() const {
@@ -63,6 +71,7 @@
 
   // Cellular specific properties
   std::string home_provider_id_;
+  bool allow_roaming_;
   bool provider_requires_roaming_;
   bool support_network_scan_;
   bool scanning_;
@@ -81,10 +90,12 @@
   // Ethernet specific properties
   bool eap_authentication_completed_;
 
-  // Keep all Device properties in a dictionary. Devices are limited and should
-  // change rarely if ever, so the overhead for this is small.
+  // Keep all Device properties in a dictionary for now. See comment above.
   base::DictionaryValue properties_;
 
+  // Dictionary of IPConfig properties, keyed by IpConfig path.
+  base::DictionaryValue ip_configs_;
+
   DISALLOW_COPY_AND_ASSIGN(DeviceState);
 };
 
diff --git a/chromeos/network/favorite_state.cc b/chromeos/network/favorite_state.cc
index efe4b38..002ff4f 100644
--- a/chromeos/network/favorite_state.cc
+++ b/chromeos/network/favorite_state.cc
@@ -25,13 +25,6 @@
 
 bool FavoriteState::PropertyChanged(const std::string& key,
                                     const base::Value& value) {
-  // All property values except UIData (which may contain a lengthy
-  // certificate pattern) and passphrase entries get stored in |properties_|.
-  if (key != shill::kUIDataProperty &&
-      !shill_property_util::IsPassphraseKey(key)) {
-    properties_.SetWithoutPathExpansion(key, value.DeepCopy());
-  }
-
   if (ManagedStatePropertyChanged(key, value))
     return true;
   if (key == shill::kProfileProperty) {
@@ -44,10 +37,6 @@
       return false;
     }
     ui_data_ = *new_ui_data;
-
-    // Add ONCSource to |properties_| for debugging.
-    properties_.SetStringWithoutPathExpansion(NetworkUIData::kKeyONCSource,
-                                              ui_data_.GetONCSourceAsString());
     return true;
   } else if (key == shill::kGuidProperty) {
     return GetStringValue(key, value, &guid_);
@@ -78,6 +67,18 @@
   return false;
 }
 
+void FavoriteState::GetStateProperties(
+    base::DictionaryValue* dictionary) const {
+  ManagedState::GetStateProperties(dictionary);
+
+  dictionary->SetStringWithoutPathExpansion(shill::kGuidProperty, guid());
+  dictionary->SetStringWithoutPathExpansion(shill::kProfileProperty,
+                                            profile_path());
+  // Add ONCSource for debugging.
+  dictionary->SetStringWithoutPathExpansion(NetworkUIData::kKeyONCSource,
+                                            ui_data_.GetONCSourceAsString());
+}
+
 bool FavoriteState::IsFavorite() const {
   // kTypeEthernetEap is always a favorite. We need this check because it does
   // not show up in the visible list, but its properties may not be available
diff --git a/chromeos/network/favorite_state.h b/chromeos/network/favorite_state.h
index bb468a7..349b85b 100644
--- a/chromeos/network/favorite_state.h
+++ b/chromeos/network/favorite_state.h
@@ -30,13 +30,14 @@
   // ManagedState overrides
   virtual bool PropertyChanged(const std::string& key,
                                const base::Value& value) OVERRIDE;
+  virtual void GetStateProperties(
+      base::DictionaryValue* dictionary) const OVERRIDE;
 
   // Accessors
   const std::string& profile_path() const { return profile_path_; }
   const NetworkUIData& ui_data() const { return ui_data_; }
   const base::DictionaryValue& proxy_config() const { return proxy_config_; }
   const std::string& guid() const { return guid_; }
-  const base::DictionaryValue& properties() const { return properties_; }
 
   // Returns true if this is a favorite stored in a profile (see note above).
   bool IsFavorite() const;
@@ -53,11 +54,6 @@
   // provides proxy configuration. crbug.com/241775
   base::DictionaryValue proxy_config_;
 
-  // Keep all Favorite properties in a dictionary so that all configured
-  // properties can be examined for debugging. Since the Favorite list is
-  // mostly fixed, the overhead should be reasonable.
-  base::DictionaryValue properties_;
-
   DISALLOW_COPY_AND_ASSIGN(FavoriteState);
 };
 
diff --git a/chromeos/network/managed_network_configuration_handler.h b/chromeos/network/managed_network_configuration_handler.h
index bc58492..7ed8c17 100644
--- a/chromeos/network/managed_network_configuration_handler.h
+++ b/chromeos/network/managed_network_configuration_handler.h
@@ -60,7 +60,7 @@
   virtual void GetProperties(
       const std::string& service_path,
       const network_handler::DictionaryResultCallback& callback,
-      const network_handler::ErrorCallback& error_callback) const = 0;
+      const network_handler::ErrorCallback& error_callback) = 0;
 
   // Provides the managed properties of the network with |service_path| to
   // |callback|. |userhash| is only used to ensure that the user's policy is
diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/managed_network_configuration_handler_impl.cc
index f233147..5415a76 100644
--- a/chromeos/network/managed_network_configuration_handler_impl.cc
+++ b/chromeos/network/managed_network_configuration_handler_impl.cc
@@ -18,6 +18,7 @@
 #include "chromeos/dbus/shill_manager_client.h"
 #include "chromeos/dbus/shill_profile_client.h"
 #include "chromeos/dbus/shill_service_client.h"
+#include "chromeos/network/device_state.h"
 #include "chromeos/network/network_configuration_handler.h"
 #include "chromeos/network/network_event_log.h"
 #include "chromeos/network/network_policy_observer.h"
@@ -83,17 +84,6 @@
   return it->second;
 }
 
-void TranslatePropertiesToOncAndRunCallback(
-    const network_handler::DictionaryResultCallback& callback,
-    const std::string& service_path,
-    const base::DictionaryValue& shill_properties) {
-  scoped_ptr<base::DictionaryValue> onc_network(
-      onc::TranslateShillServiceToONCPart(
-          shill_properties,
-          &onc::kNetworkWithStateSignature));
-  callback.Run(service_path, *onc_network);
-}
-
 }  // namespace
 
 struct ManagedNetworkConfigurationHandlerImpl::Policies {
@@ -169,9 +159,14 @@
     // properties _might_ be user configured.
   }
 
+  scoped_ptr<base::DictionaryValue> properties_copy(
+      shill_properties.DeepCopy());
+  // Add the IPConfigs to the dictionary before the ONC translation.
+  GetIPConfigs(service_path, properties_copy.get());
+
   scoped_ptr<base::DictionaryValue> active_settings(
       onc::TranslateShillServiceToONCPart(
-          shill_properties,
+          *properties_copy,
           &onc::kNetworkWithStateSignature));
 
   std::string guid;
@@ -212,13 +207,31 @@
 void ManagedNetworkConfigurationHandlerImpl::GetProperties(
     const std::string& service_path,
     const network_handler::DictionaryResultCallback& callback,
-    const network_handler::ErrorCallback& error_callback) const {
+    const network_handler::ErrorCallback& error_callback) {
   network_configuration_handler_->GetProperties(
       service_path,
-      base::Bind(&TranslatePropertiesToOncAndRunCallback, callback),
+      base::Bind(&ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 callback),
       error_callback);
 }
 
+void ManagedNetworkConfigurationHandlerImpl::GetPropertiesCallback(
+    const network_handler::DictionaryResultCallback& callback,
+    const std::string& service_path,
+    const base::DictionaryValue& shill_properties) {
+  scoped_ptr<base::DictionaryValue> properties_copy(
+      shill_properties.DeepCopy());
+  // Add the IPConfigs to the dictionary before the ONC translation.
+  GetIPConfigs(service_path, properties_copy.get());
+
+  scoped_ptr<base::DictionaryValue> onc_network(
+      onc::TranslateShillServiceToONCPart(
+          *properties_copy,
+          &onc::kNetworkWithStateSignature));
+  callback.Run(service_path, *onc_network);
+}
+
 void ManagedNetworkConfigurationHandlerImpl::SetProperties(
     const std::string& service_path,
     const base::DictionaryValue& user_settings,
@@ -596,4 +609,34 @@
       NetworkPolicyObserver, observers_, PolicyApplied(service_path));
 }
 
+void ManagedNetworkConfigurationHandlerImpl::GetIPConfigs(
+    const std::string& service_path,
+    base::DictionaryValue* properties) {
+  std::string connection_state;
+  properties->GetStringWithoutPathExpansion(
+      shill::kStateProperty, &connection_state);
+  if (!NetworkState::StateIsConnected(connection_state))
+    return;
+
+  // Get the IPConfig properties from the device and store them in "IPConfigs"
+  // (plural) in the properties dictionary. (Note: Shill only provides a single
+  // "IPConfig" property for a network service, but a consumer of this API may
+  // want information about all ipv4 and ipv6 IPConfig properties.
+  std::string device;
+  properties->GetStringWithoutPathExpansion(shill::kDeviceProperty, &device);
+  const DeviceState* device_state =
+      network_state_handler_->GetDeviceState(device);
+  if (!device_state) {
+    NET_LOG_ERROR("GetIPConfigs: no device: " + device, service_path);
+    return;
+  }
+  // Convert IPConfig dictionary to a ListValue.
+  base::ListValue* ip_configs = new base::ListValue;
+  for (base::DictionaryValue::Iterator iter(device_state->ip_configs());
+       !iter.IsAtEnd(); iter.Advance()) {
+    ip_configs->Append(iter.value().DeepCopy());
+  }
+  properties->SetWithoutPathExpansion(shill::kIPConfigsProperty, ip_configs);
+}
+
 }  // namespace chromeos
diff --git a/chromeos/network/managed_network_configuration_handler_impl.h b/chromeos/network/managed_network_configuration_handler_impl.h
index 54cf226..3580b6f 100644
--- a/chromeos/network/managed_network_configuration_handler_impl.h
+++ b/chromeos/network/managed_network_configuration_handler_impl.h
@@ -43,7 +43,7 @@
   virtual void GetProperties(
       const std::string& service_path,
       const network_handler::DictionaryResultCallback& callback,
-      const network_handler::ErrorCallback& error_callback) const OVERRIDE;
+      const network_handler::ErrorCallback& error_callback) OVERRIDE;
 
   virtual void GetManagedProperties(
       const std::string& userhash,
@@ -120,11 +120,21 @@
       const std::string& service_path,
       const base::DictionaryValue& shill_properties);
 
+  void GetPropertiesCallback(
+      const network_handler::DictionaryResultCallback& callback,
+      const std::string& service_path,
+      const base::DictionaryValue& shill_properties);
+
   const Policies* GetPoliciesForUser(const std::string& userhash) const;
   const Policies* GetPoliciesForProfile(const NetworkProfile& profile) const;
 
   void OnPolicyAppliedToNetwork(const std::string& service_path);
 
+  // Helper method to append "IPConfigs" property to |properties| by extracting
+  // them from the associated DeviceState.
+  void GetIPConfigs(const std::string& service_path,
+                    base::DictionaryValue* properties);
+
   // If present, the empty string maps to the device policy.
   UserToPoliciesMap policies_by_user_;
 
diff --git a/chromeos/network/managed_state.cc b/chromeos/network/managed_state.cc
index 62e9db4..4bbece8 100644
--- a/chromeos/network/managed_state.cc
+++ b/chromeos/network/managed_state.cc
@@ -77,6 +77,11 @@
   return false;
 }
 
+void ManagedState::GetStateProperties(base::DictionaryValue* dictionary) const {
+  dictionary->SetStringWithoutPathExpansion(shill::kNameProperty, name());
+  dictionary->SetStringWithoutPathExpansion(shill::kTypeProperty, type());
+}
+
 bool ManagedState::ManagedStatePropertyChanged(const std::string& key,
                                                const base::Value& value) {
   if (key == shill::kNameProperty) {
diff --git a/chromeos/network/managed_state.h b/chromeos/network/managed_state.h
index 4e7b9fa..8b56394 100644
--- a/chromeos/network/managed_state.h
+++ b/chromeos/network/managed_state.h
@@ -64,6 +64,10 @@
   virtual bool InitialPropertiesReceived(
       const base::DictionaryValue& properties);
 
+  // Fills |dictionary| with a minimal set of state properties for the network
+  // type. See implementations for which properties are included.
+  virtual void GetStateProperties(base::DictionaryValue* dictionary) const;
+
   const ManagedType managed_type() const { return managed_type_; }
   const std::string& path() const { return path_; }
   const std::string& name() const { return name_; }
diff --git a/chromeos/network/mock_managed_network_configuration_handler.h b/chromeos/network/mock_managed_network_configuration_handler.h
index 4bde68d..bc8954a 100644
--- a/chromeos/network/mock_managed_network_configuration_handler.h
+++ b/chromeos/network/mock_managed_network_configuration_handler.h
@@ -22,11 +22,10 @@
   // ManagedNetworkConfigurationHandler overrides
   MOCK_METHOD1(AddObserver, void(NetworkPolicyObserver* observer));
   MOCK_METHOD1(RemoveObserver, void(NetworkPolicyObserver* observer));
-  MOCK_CONST_METHOD3(
-      GetProperties,
-      void(const std::string& service_path,
-           const network_handler::DictionaryResultCallback& callback,
-           const network_handler::ErrorCallback& error_callback));
+  MOCK_METHOD3(GetProperties,
+               void(const std::string& service_path,
+                    const network_handler::DictionaryResultCallback& callback,
+                    const network_handler::ErrorCallback& error_callback));
   MOCK_METHOD4(GetManagedProperties,
                void(const std::string& userhash,
                     const std::string& service_path,
diff --git a/chromeos/network/network_connection_handler.cc b/chromeos/network/network_connection_handler.cc
index 4bf397e..f01cbe6 100644
--- a/chromeos/network/network_connection_handler.cc
+++ b/chromeos/network/network_connection_handler.cc
@@ -87,7 +87,8 @@
 
 std::string GetDefaultUserProfilePath(const NetworkState* network) {
   if (!NetworkHandler::IsInitialized() ||
-      !LoginState::Get()->UserHasNetworkProfile() ||
+      (LoginState::IsInitialized() &&
+       !LoginState::Get()->UserHasNetworkProfile()) ||
       (network && network->type() == shill::kTypeWifi &&
        network->security() == shill::kSecurityNone)) {
     return NetworkProfileHandler::GetSharedProfilePath();
diff --git a/chromeos/network/network_device_handler_impl.cc b/chromeos/network/network_device_handler_impl.cc
index ce0d787..85ff215 100644
--- a/chromeos/network/network_device_handler_impl.cc
+++ b/chromeos/network/network_device_handler_impl.cc
@@ -465,15 +465,7 @@
   for (NetworkStateHandler::DeviceStateList::const_iterator it = list.begin();
       it != list.end(); ++it) {
     const DeviceState* device_state = *it;
-    bool current_device_value;
-    if (!device_state->properties().GetBooleanWithoutPathExpansion(
-             shill::kCellularAllowRoamingProperty, &current_device_value)) {
-      NET_LOG_ERROR(
-          "Could not get \"allow roaming\" property from cellular "
-          "device.",
-          device_state->path());
-      continue;
-    }
+    bool current_allow_roaming = device_state->allow_roaming();
 
     // If roaming is required by the provider, always try to set to true.
     bool new_device_value =
@@ -481,7 +473,7 @@
 
     // Only set the value if the current value is different from
     // |new_device_value|.
-    if (new_device_value == current_device_value)
+    if (new_device_value == current_allow_roaming)
       continue;
 
     SetDevicePropertyInternal(device_state->path(),
diff --git a/chromeos/network/network_state.cc b/chromeos/network/network_state.cc
index 5b2a85d..f473fcd 100644
--- a/chromeos/network/network_state.cc
+++ b/chromeos/network/network_state.cc
@@ -90,37 +90,6 @@
     else
       error_.clear();
     return true;
-  } else if (key == IPConfigProperty(shill::kAddressProperty)) {
-    return GetStringValue(key, value, &ip_address_);
-  } else if (key == IPConfigProperty(shill::kGatewayProperty)) {
-    return GetStringValue(key, value, &gateway_);
-  } else if (key == IPConfigProperty(shill::kNameServersProperty)) {
-    const base::ListValue* dns_servers;
-    if (!value.GetAsList(&dns_servers))
-      return false;
-    dns_servers_.clear();
-    ConvertListValueToStringVector(*dns_servers, &dns_servers_);
-    return true;
-  } else if (key == IPConfigProperty(shill::kPrefixlenProperty)) {
-    return GetIntegerValue(key, value, &prefix_length_);
-  } else if (key == IPConfigProperty(
-      shill::kWebProxyAutoDiscoveryUrlProperty)) {
-    std::string url_string;
-    if (!GetStringValue(key, value, &url_string))
-      return false;
-    if (url_string.empty()) {
-      web_proxy_auto_discovery_url_ = GURL();
-    } else {
-      GURL gurl(url_string);
-      if (!gurl.is_valid()) {
-        web_proxy_auto_discovery_url_ = gurl;
-      } else {
-        NET_LOG_ERROR("Invalid WebProxyAutoDiscoveryUrl: " + url_string,
-                      path());
-        web_proxy_auto_discovery_url_ = GURL();
-      }
-    }
-    return true;
   } else if (key == shill::kActivationStateProperty) {
     return GetStringValue(key, value, &activation_state_);
   } else if (key == shill::kRoamingStateProperty) {
@@ -170,59 +139,84 @@
   return changed;
 }
 
-void NetworkState::GetProperties(base::DictionaryValue* dictionary) const {
-  // Keep care that these properties are the same as in |PropertyChanged|.
-  dictionary->SetStringWithoutPathExpansion(shill::kNameProperty, name());
-  dictionary->SetStringWithoutPathExpansion(shill::kTypeProperty, type());
-  dictionary->SetIntegerWithoutPathExpansion(shill::kSignalStrengthProperty,
-                                             signal_strength_);
+void NetworkState::GetStateProperties(base::DictionaryValue* dictionary) const {
+  ManagedState::GetStateProperties(dictionary);
+
+  // Properties shared by all types.
+  dictionary->SetStringWithoutPathExpansion(shill::kGuidProperty, guid());
   dictionary->SetStringWithoutPathExpansion(shill::kStateProperty,
-                                            connection_state_);
-  dictionary->SetBooleanWithoutPathExpansion(shill::kConnectableProperty,
-                                             connectable_);
-
-  dictionary->SetStringWithoutPathExpansion(shill::kErrorProperty, error_);
-
-  // IPConfig properties
-  base::DictionaryValue* ipconfig_properties = new base::DictionaryValue;
-  ipconfig_properties->SetStringWithoutPathExpansion(shill::kAddressProperty,
-                                                     ip_address_);
-  ipconfig_properties->SetStringWithoutPathExpansion(shill::kGatewayProperty,
-                                                     gateway_);
-  base::ListValue* name_servers = new base::ListValue;
-  name_servers->AppendStrings(dns_servers_);
-  ipconfig_properties->SetWithoutPathExpansion(shill::kNameServersProperty,
-                                               name_servers);
-  ipconfig_properties->SetStringWithoutPathExpansion(
-      shill::kWebProxyAutoDiscoveryUrlProperty,
-      web_proxy_auto_discovery_url_.spec());
-  dictionary->SetWithoutPathExpansion(shill::kIPConfigProperty,
-                                      ipconfig_properties);
-
-  dictionary->SetStringWithoutPathExpansion(shill::kActivationStateProperty,
-                                            activation_state_);
-  dictionary->SetStringWithoutPathExpansion(shill::kRoamingStateProperty,
-                                            roaming_);
+                                            connection_state());
   dictionary->SetStringWithoutPathExpansion(shill::kSecurityProperty,
-                                            security_);
-  dictionary->SetStringWithoutPathExpansion(shill::kEapMethodProperty,
-                                            eap_method_);
+                                            security());
+  if (!error().empty())
+    dictionary->SetStringWithoutPathExpansion(shill::kErrorProperty, error());
 
-  // ui_data_ (contains ONC source) is intentionally omitted.
+  if (!NetworkTypePattern::Wireless().MatchesType(type()))
+    return;
 
-  dictionary->SetStringWithoutPathExpansion(
-      shill::kNetworkTechnologyProperty,
-      network_technology_);
-  dictionary->SetStringWithoutPathExpansion(shill::kDeviceProperty,
-                                            device_path_);
-  dictionary->SetStringWithoutPathExpansion(shill::kGuidProperty, guid_);
-  dictionary->SetStringWithoutPathExpansion(shill::kProfileProperty,
-                                            profile_path_);
-  dictionary->SetBooleanWithoutPathExpansion(
-      shill::kActivateOverNonCellularNetworkProperty,
-      activate_over_non_cellular_networks_);
-  dictionary->SetBooleanWithoutPathExpansion(shill::kOutOfCreditsProperty,
-                                             cellular_out_of_credits_);
+  // Wireless properties
+  dictionary->SetBooleanWithoutPathExpansion(shill::kConnectableProperty,
+                                             connectable());
+  dictionary->SetIntegerWithoutPathExpansion(shill::kSignalStrengthProperty,
+                                             signal_strength());
+
+  // Wifi properties
+  if (NetworkTypePattern::WiFi().MatchesType(type())) {
+    dictionary->SetStringWithoutPathExpansion(shill::kEapMethodProperty,
+                                              eap_method());
+  }
+
+  // Mobile properties
+  if (NetworkTypePattern::Mobile().MatchesType(type())) {
+    dictionary->SetStringWithoutPathExpansion(
+        shill::kNetworkTechnologyProperty,
+        network_technology());
+    dictionary->SetStringWithoutPathExpansion(shill::kActivationStateProperty,
+                                              activation_state());
+    dictionary->SetStringWithoutPathExpansion(shill::kRoamingStateProperty,
+                                              roaming());
+    dictionary->SetBooleanWithoutPathExpansion(shill::kOutOfCreditsProperty,
+                                               cellular_out_of_credits());
+  }
+}
+
+void NetworkState::IPConfigPropertiesChanged(
+    const base::DictionaryValue& properties) {
+  for (base::DictionaryValue::Iterator iter(properties);
+       !iter.IsAtEnd(); iter.Advance()) {
+    std::string key = iter.key();
+    const base::Value& value = iter.value();
+
+    if (key == shill::kAddressProperty) {
+      GetStringValue(key, value, &ip_address_);
+    } else if (key == shill::kGatewayProperty) {
+      GetStringValue(key, value, &gateway_);
+    } else if (key == shill::kNameServersProperty) {
+      const base::ListValue* dns_servers;
+      if (value.GetAsList(&dns_servers)) {
+        dns_servers_.clear();
+        ConvertListValueToStringVector(*dns_servers, &dns_servers_);
+      }
+    } else if (key == shill::kPrefixlenProperty) {
+      GetIntegerValue(key, value, &prefix_length_);
+    } else if (key == shill::kWebProxyAutoDiscoveryUrlProperty) {
+      std::string url_string;
+      if (GetStringValue(key, value, &url_string)) {
+        if (url_string.empty()) {
+          web_proxy_auto_discovery_url_ = GURL();
+        } else {
+          GURL gurl(url_string);
+          if (gurl.is_valid()) {
+            web_proxy_auto_discovery_url_ = gurl;
+          } else {
+            NET_LOG_ERROR("Invalid WebProxyAutoDiscoveryUrl: " + url_string,
+                          path());
+            web_proxy_auto_discovery_url_ = GURL();
+          }
+        }
+      }
+    }
+  }
 }
 
 bool NetworkState::RequiresActivation() const {
@@ -288,9 +282,4 @@
   return !error.empty() && error != kErrorUnknown;
 }
 
-// static
-std::string NetworkState::IPConfigProperty(const char* key) {
-  return base::StringPrintf("%s.%s", shill::kIPConfigProperty, key);
-}
-
 }  // namespace chromeos
diff --git a/chromeos/network/network_state.h b/chromeos/network/network_state.h
index 8a74bcd..d0ee74a 100644
--- a/chromeos/network/network_state.h
+++ b/chromeos/network/network_state.h
@@ -36,17 +36,16 @@
                                const base::Value& value) OVERRIDE;
   virtual bool InitialPropertiesReceived(
       const base::DictionaryValue& properties) OVERRIDE;
+  virtual void GetStateProperties(
+      base::DictionaryValue* dictionary) const OVERRIDE;
 
-  // Fills |dictionary| with the state properties. All properties that are
-  // parsed by PropertyChanged are stored in |dictionary|, except |ui_data_|.
-  void GetProperties(base::DictionaryValue* dictionary) const;
+  void IPConfigPropertiesChanged(const base::DictionaryValue& properties);
 
   // Returns true, if the network requires a service activation.
   bool RequiresActivation() const;
 
   // Accessors
   const std::string& security() const { return security_; }
-  const std::string& eap_method() const { return eap_method_; }
   const std::string& device_path() const { return device_path_; }
   const std::string& guid() const { return guid_; }
   const std::string& connection_state() const { return connection_state_; }
@@ -54,7 +53,6 @@
   const std::string& error() const { return error_; }
   const std::string& last_error() const { return last_error_; }
   void clear_last_error() { last_error_.clear(); }
-  bool connectable() const { return connectable_; }
 
   const NetworkUIData& ui_data() const { return ui_data_; }
 
@@ -68,8 +66,12 @@
   }
 
   // Wireless property accessors
+  bool connectable() const { return connectable_; }
   int signal_strength() const { return signal_strength_; }
 
+  // Wifi property accessors
+  const std::string& eap_method() const { return eap_method_; }
+
   // Cellular property accessors
   const std::string& network_technology() const {
     return network_technology_;
@@ -102,10 +104,6 @@
   static bool StateIsConnecting(const std::string& connection_state);
   static bool ErrorIsValid(const std::string& error);
 
-  // Helper to return a full prefixed version of an IPConfig property key.
-  static std::string IPConfigProperty(const char* key);
-
-
  private:
   friend class MobileActivatorTest;
   friend class NetworkStateHandler;
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc
index 8e906ea..1f06197 100644
--- a/chromeos/network/network_state_handler.cc
+++ b/chromeos/network/network_state_handler.cc
@@ -415,16 +415,6 @@
   return list.front();
 }
 
-void NetworkStateHandler::GetNetworkStatePropertiesForTest(
-    base::DictionaryValue* dictionary) const {
-  for (ManagedStateList::const_iterator iter = network_list_.begin();
-       iter != network_list_.end(); ++iter) {
-    base::DictionaryValue* network_dict = new base::DictionaryValue;
-    (*iter)->AsNetworkState()->GetProperties(network_dict);
-    dictionary->SetWithoutPathExpansion((*iter)->path(), network_dict);
-  }
-}
-
 //------------------------------------------------------------------------------
 // ShillPropertyHandler::Delegate overrides
 
@@ -641,6 +631,24 @@
   }
 }
 
+void NetworkStateHandler::UpdateIPConfigProperties(
+    ManagedState::ManagedType type,
+    const std::string& path,
+    const std::string& ip_config_path,
+    const base::DictionaryValue& properties)  {
+  if (type == ManagedState::MANAGED_TYPE_NETWORK) {
+    NetworkState* network = GetModifiableNetworkState(path);
+    if (!network)
+      return;
+    network->IPConfigPropertiesChanged(properties);
+  } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
+    DeviceState* device = GetModifiableDeviceState(path);
+    if (!device)
+      return;
+    device->IPConfigPropertiesChanged(ip_config_path, properties);
+  }
+}
+
 void NetworkStateHandler::CheckPortalListChanged(
     const std::string& check_portal_list) {
   check_portal_list_ = check_portal_list;
diff --git a/chromeos/network/network_state_handler.h b/chromeos/network/network_state_handler.h
index 72d4029..314a975 100644
--- a/chromeos/network/network_state_handler.h
+++ b/chromeos/network/network_state_handler.h
@@ -49,15 +49,6 @@
 // keep properties up to date by managing the appropriate Shill observers.
 // It will invoke its own more specific observer methods when the specified
 // changes occur.
-//
-// Most *ByType or *ForType methods will accept any of the following for |type|.
-// See individual methods for specific notes.
-// * Any type defined in service_constants.h (e.g. shill::kTypeWifi)
-// * kMatchTypeDefault returns the default (active) network
-// * kMatchTypeNonVirtual returns the primary non virtual network
-// * kMatchTypeWired returns the primary wired network
-// * kMatchTypeWireless returns the primary wireless network
-// * kMatchTypeMobile returns the primary cellular or wimax network
 
 class CHROMEOS_EXPORT NetworkStateHandler
     : public internal::ShillPropertyHandler::Listener {
@@ -122,9 +113,10 @@
   // observe this class and implement NetworkPropertyChanged().
   const NetworkState* GetNetworkState(const std::string& service_path) const;
 
-  // Returns the default network (which includes VPNs) based on the
-  // Shill Manager.DefaultNetwork property. Normally this is the same as
-  // ConnectedNetworkByType(kMatchTypeDefault), but the timing might differ.
+  // Returns the default network (which includes VPNs) based on the Shill
+  // Manager.DefaultNetwork property. Normally this is the same as
+  // ConnectedNetworkByType(NetworkTypePattern::Default()), but the timing might
+  // differ.
   const NetworkState* DefaultNetwork() const;
 
   // Returns the FavoriteState associated to DefaultNetwork. Returns NULL if,
@@ -220,11 +212,6 @@
   // connected using EAP, returns NULL.
   const FavoriteState* GetEAPForEthernet(const std::string& service_path) const;
 
-  // Generates a DictionaryValue of all NetworkState properties. Currently
-  // provided for debugging purposes only.
-  void GetNetworkStatePropertiesForTest(
-      base::DictionaryValue* dictionary) const;
-
   // Construct and initialize an instance for testing.
   static NetworkStateHandler* InitializeForTest();
 
@@ -266,6 +253,14 @@
       const std::string& key,
       const base::Value& value) OVERRIDE;
 
+  // Called by ShillPropertyHandler when a watched network or device
+  // IPConfig property changes.
+  virtual void UpdateIPConfigProperties(
+      ManagedState::ManagedType type,
+      const std::string& path,
+      const std::string& ip_config_path,
+      const base::DictionaryValue& properties) OVERRIDE;
+
   // Called by ShillPropertyHandler when the portal check list manager property
   // changes.
   virtual void CheckPortalListChanged(
diff --git a/chromeos/network/onc/onc_signature.cc b/chromeos/network/onc/onc_signature.cc
index a5f8cc3..f647450 100644
--- a/chromeos/network/onc/onc_signature.cc
+++ b/chromeos/network/onc/onc_signature.cc
@@ -279,6 +279,8 @@
 const OncFieldSignature network_with_state_fields[] = {
     { ::onc::network_config::kCellular, &kCellularWithStateSignature},
     { ::onc::network_config::kConnectionState, &kStringSignature},
+    { ::onc::network_config::kConnectable, &kBoolSignature},
+    { ::onc::network_config::kErrorState, &kStringSignature},
     { ::onc::network_config::kWiFi, &kWiFiWithStateSignature},
     {NULL}};
 
diff --git a/chromeos/network/onc/onc_translation_tables.cc b/chromeos/network/onc/onc_translation_tables.cc
index c520cf9..e09c030 100644
--- a/chromeos/network/onc/onc_translation_tables.cc
+++ b/chromeos/network/onc/onc_translation_tables.cc
@@ -171,6 +171,9 @@
     // onc_translator_shill_to_onc.cc. It is only converted when going from
     // Shill->ONC, and ignored otherwise.
     // { ::onc::network_config::kConnectionState, shill::kStateProperty },
+
+    { ::onc::network_config::kConnectable, shill::kConnectableProperty },
+    { ::onc::network_config::kErrorState, shill::kErrorProperty },
     {NULL}};
 
 const FieldTranslationEntry ipconfig_fields[] = {
@@ -178,6 +181,9 @@
     { ::onc::ipconfig::kGateway, shill::kGatewayProperty},
     { ::onc::ipconfig::kRoutingPrefix, shill::kPrefixlenProperty},
     { ::onc::ipconfig::kNameServers, shill::kNameServersProperty},
+    // This field is converted during translation, see ShillToONCTranslator::
+    // TranslateIPConfig. It is only converted from Shill->ONC.
+    // { ::onc::ipconfig::kType, shill::kMethodProperty},
     {NULL}};
 
 struct OncValueTranslationEntry {
diff --git a/chromeos/network/onc/onc_translator_shill_to_onc.cc b/chromeos/network/onc/onc_translator_shill_to_onc.cc
index 7716fbf..11b802f 100644
--- a/chromeos/network/onc/onc_translator_shill_to_onc.cc
+++ b/chromeos/network/onc/onc_translator_shill_to_onc.cc
@@ -319,15 +319,17 @@
   std::string shill_ip_method;
   shill_dictionary_->GetStringWithoutPathExpansion(shill::kMethodProperty,
                                                    &shill_ip_method);
-  if (shill_ip_method != shill::kTypeIPv4 &&
-      shill_ip_method != shill::kTypeIPv6) {
-    LOG(ERROR) << "Unhandled IPConfig Method value " << shill_ip_method;
-    return;
+  std::string type;
+  if (shill_ip_method == shill::kTypeIPv4 ||
+      shill_ip_method == shill::kTypeDHCP) {
+    type = ::onc::ipconfig::kIPv4;
+  } else if (shill_ip_method == shill::kTypeIPv6 ||
+             shill_ip_method == shill::kTypeDHCP6) {
+    type = ::onc::ipconfig::kIPv6;
+  } else {
+    return;  // Ignore unhandled IPConfig types, e.g. bootp, zeroconf, ppp
   }
 
-  std::string type = ::onc::ipconfig::kIPv4;
-  if (shill_ip_method == shill::kTypeIPv6)
-    type = ::onc::ipconfig::kIPv6;
   onc_object_->SetStringWithoutPathExpansion(::onc::ipconfig::kType, type);
 }
 
diff --git a/chromeos/network/onc/onc_utils.cc b/chromeos/network/onc/onc_utils.cc
index aa612d9..0db412d 100644
--- a/chromeos/network/onc/onc_utils.cc
+++ b/chromeos/network/onc/onc_utils.cc
@@ -651,5 +651,20 @@
                                        network_config);
 }
 
+NetworkTypePattern NetworkTypePatternFromOncType(const std::string& type) {
+  if (type == ::onc::network_type::kAllTypes)
+    return NetworkTypePattern::Default();
+  if (type == ::onc::network_type::kCellular)
+    return NetworkTypePattern::Cellular();
+  if (type == ::onc::network_type::kEthernet)
+    return NetworkTypePattern::Ethernet();
+  if (type == ::onc::network_type::kVPN)
+    return NetworkTypePattern::VPN();
+  if (type == ::onc::network_type::kWiFi)
+    return NetworkTypePattern::WiFi();
+  NOTREACHED();
+  return NetworkTypePattern::Default();
+}
+
 }  // namespace onc
 }  // namespace chromeos
diff --git a/chromeos/network/onc/onc_utils.h b/chromeos/network/onc/onc_utils.h
index ec001b0..c89c26a 100644
--- a/chromeos/network/onc/onc_utils.h
+++ b/chromeos/network/onc/onc_utils.h
@@ -13,6 +13,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "chromeos/chromeos_export.h"
+#include "chromeos/network/shill_property_util.h"
 #include "components/onc/onc_constants.h"
 
 namespace base {
@@ -125,6 +126,10 @@
     const CertPEMsByGUIDMap& certs_by_guid,
     base::DictionaryValue* network_config);
 
+// Returns a network type pattern for matching the ONC type string.
+CHROMEOS_EXPORT NetworkTypePattern NetworkTypePatternFromOncType(
+    const std::string& type);
+
 }  // namespace onc
 }  // namespace chromeos
 
diff --git a/chromeos/network/shill_property_handler.cc b/chromeos/network/shill_property_handler.cc
index 8ae24fb..13f34c1 100644
--- a/chromeos/network/shill_property_handler.cc
+++ b/chromeos/network/shill_property_handler.cc
@@ -489,16 +489,17 @@
     }
   }
   listener_->UpdateManagedStateProperties(type, path, properties);
-  // Request IPConfig parameters for networks.
-  if (type == ManagedState::MANAGED_TYPE_NETWORK &&
-      properties.HasKey(shill::kIPConfigProperty)) {
-    std::string ip_config_path;
-    if (properties.GetString(shill::kIPConfigProperty, &ip_config_path)) {
-      DBusThreadManager::Get()->GetShillIPConfigClient()->GetProperties(
-          dbus::ObjectPath(ip_config_path),
-          base::Bind(&ShillPropertyHandler::GetIPConfigCallback,
-                     AsWeakPtr(), path));
-    }
+
+  if (type == ManagedState::MANAGED_TYPE_NETWORK) {
+    // Request IPConfig properties.
+    const base::Value* value;
+    if (properties.GetWithoutPathExpansion(shill::kIPConfigProperty, &value))
+      RequestIPConfig(type, path, *value);
+  } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
+    // Clear and request IPConfig properties for each entry in IPConfigs.
+    const base::Value* value;
+    if (properties.GetWithoutPathExpansion(shill::kIPConfigsProperty, &value))
+      RequestIPConfigsList(type, path, *value);
   }
 
   // Notify the listener only when all updates for that type have completed.
@@ -518,70 +519,64 @@
     const std::string& path,
     const std::string& key,
     const base::Value& value) {
+  if (type == ManagedState::MANAGED_TYPE_NETWORK &&
+      key == shill::kIPConfigProperty) {
+    RequestIPConfig(type, path, value);
+  } else if (type == ManagedState::MANAGED_TYPE_DEVICE &&
+      key == shill::kIPConfigsProperty) {
+    RequestIPConfigsList(type, path, value);
+  }
+
   if (type == ManagedState::MANAGED_TYPE_NETWORK)
-    NetworkServicePropertyChangedCallback(path, key, value);
+    listener_->UpdateNetworkServiceProperty(path, key, value);
   else if (type == ManagedState::MANAGED_TYPE_DEVICE)
-    NetworkDevicePropertyChangedCallback(path, key, value);
+    listener_->UpdateDeviceProperty(path, key, value);
   else
     NOTREACHED();
 }
 
-void ShillPropertyHandler::NetworkServicePropertyChangedCallback(
+void ShillPropertyHandler::RequestIPConfig(
+    ManagedState::ManagedType type,
     const std::string& path,
-    const std::string& key,
-    const base::Value& value) {
-  if (key == shill::kIPConfigProperty) {
-    // Request the IPConfig for the network and update network properties
-    // when the request completes.
-    std::string ip_config_path;
-    value.GetAsString(&ip_config_path);
-    DCHECK(!ip_config_path.empty());
-    DBusThreadManager::Get()->GetShillIPConfigClient()->GetProperties(
-        dbus::ObjectPath(ip_config_path),
-        base::Bind(&ShillPropertyHandler::GetIPConfigCallback,
-                   AsWeakPtr(), path));
-  } else {
-    listener_->UpdateNetworkServiceProperty(path, key, value);
+    const base::Value& ip_config_path_value) {
+  std::string ip_config_path;
+  if (!ip_config_path_value.GetAsString(&ip_config_path) ||
+      ip_config_path.empty()) {
+    NET_LOG_ERROR("Invalid IPConfig", path);
+    return;
+  }
+  DBusThreadManager::Get()->GetShillIPConfigClient()->GetProperties(
+      dbus::ObjectPath(ip_config_path),
+      base::Bind(&ShillPropertyHandler::GetIPConfigCallback,
+                 AsWeakPtr(), type, path, ip_config_path));
+}
+
+void ShillPropertyHandler::RequestIPConfigsList(
+    ManagedState::ManagedType type,
+    const std::string& path,
+    const base::Value& ip_config_list_value) {
+  const base::ListValue* ip_configs;
+  if (!ip_config_list_value.GetAsList(&ip_configs))
+    return;
+  for (base::ListValue::const_iterator iter = ip_configs->begin();
+       iter != ip_configs->end(); ++iter) {
+    RequestIPConfig(type, path, **iter);
   }
 }
 
 void ShillPropertyHandler::GetIPConfigCallback(
-    const std::string& service_path,
+    ManagedState::ManagedType type,
+    const std::string& path,
+    const std::string& ip_config_path,
     DBusMethodCallStatus call_status,
     const base::DictionaryValue& properties)  {
   if (call_status != DBUS_METHOD_CALL_SUCCESS) {
     NET_LOG_ERROR("Failed to get IP Config properties",
-                  base::StringPrintf("%s: %d",
-                                     service_path.c_str(), call_status));
+                  base::StringPrintf("%s: %d", path.c_str(), call_status));
     return;
   }
-  UpdateIPConfigProperty(service_path, properties, shill::kAddressProperty);
-  UpdateIPConfigProperty(service_path, properties, shill::kNameServersProperty);
-  UpdateIPConfigProperty(service_path, properties, shill::kPrefixlenProperty);
-  UpdateIPConfigProperty(service_path, properties, shill::kGatewayProperty);
-  UpdateIPConfigProperty(service_path, properties,
-                         shill::kWebProxyAutoDiscoveryUrlProperty);
-}
-
-void ShillPropertyHandler::UpdateIPConfigProperty(
-    const std::string& service_path,
-    const base::DictionaryValue& properties,
-    const char* property) {
-  const base::Value* value;
-  if (!properties.GetWithoutPathExpansion(property, &value)) {
-    LOG(ERROR) << "Failed to get IPConfig property: " << property
-               << ", for: " << service_path;
-    return;
-  }
-  listener_->UpdateNetworkServiceProperty(
-      service_path, NetworkState::IPConfigProperty(property), *value);
-}
-
-void ShillPropertyHandler::NetworkDevicePropertyChangedCallback(
-    const std::string& path,
-    const std::string& key,
-    const base::Value& value) {
-  listener_->UpdateDeviceProperty(path, key, value);
+  NET_LOG_EVENT("IP Config properties received", path);
+  listener_->UpdateIPConfigProperties(type, path, ip_config_path, properties);
 }
 
 }  // namespace internal
diff --git a/chromeos/network/shill_property_handler.h b/chromeos/network/shill_property_handler.h
index e484e98..5a78f19 100644
--- a/chromeos/network/shill_property_handler.h
+++ b/chromeos/network/shill_property_handler.h
@@ -71,6 +71,13 @@
         const std::string& key,
         const base::Value& value) = 0;
 
+    // Called when a watched network or device IPConfig property changes.
+    virtual void UpdateIPConfigProperties(
+        ManagedState::ManagedType type,
+        const std::string& path,
+        const std::string& ip_config_path,
+        const base::DictionaryValue& properties) = 0;
+
     // Called when the list of devices with portal check enabled changes.
     virtual void CheckPortalListChanged(
          const std::string& check_portal_list) = 0;
@@ -187,23 +194,30 @@
                                const std::string& path,
                                const std::string& key,
                                const base::Value& value);
-  void NetworkServicePropertyChangedCallback(const std::string& path,
-                                             const std::string& key,
-                                             const base::Value& value);
 
-  // Callback for getting the IPConfig property of a Network. Handled here
-  // instead of in NetworkState so that all asynchronous requests are done
+  // Request a single IPConfig object corresponding to |ip_config_path_value|
+  // from Shill.IPConfigClient and trigger a call to UpdateIPConfigProperties
+  // for the network or device corresponding to |type| and |path|.
+  void RequestIPConfig(ManagedState::ManagedType type,
+                       const std::string& path,
+                       const base::Value& ip_config_path_value);
+
+  // Request the IPConfig objects corresponding to entries in
+  // |ip_config_list_value| from Shill.IPConfigClient and trigger a call to
+  // UpdateIPConfigProperties with each object for the network or device
+  // corresponding to |type| and |path|.
+  void RequestIPConfigsList(ManagedState::ManagedType type,
+                            const std::string& path,
+                            const base::Value& ip_config_list_value);
+
+  // Callback for getting the IPConfig property of a network or device. Handled
+  // here instead of in NetworkState so that all asynchronous requests are done
   // in a single place (also simplifies NetworkState considerably).
-  void GetIPConfigCallback(const std::string& service_path,
+  void GetIPConfigCallback(ManagedState::ManagedType type,
+                           const std::string& path,
+                           const std::string& ip_config_path,
                            DBusMethodCallStatus call_status,
                            const base::DictionaryValue& properties);
-  void UpdateIPConfigProperty(const std::string& service_path,
-                              const base::DictionaryValue& properties,
-                              const char* property);
-
-  void NetworkDevicePropertyChangedCallback(const std::string& path,
-                                            const std::string& key,
-                                            const base::Value& value);
 
   // Pointer to containing class (owns this)
   Listener* listener_;
diff --git a/chromeos/network/shill_property_handler_unittest.cc b/chromeos/network/shill_property_handler_unittest.cc
index a6b7b8e..7655d84 100644
--- a/chromeos/network/shill_property_handler_unittest.cc
+++ b/chromeos/network/shill_property_handler_unittest.cc
@@ -69,6 +69,14 @@
     AddPropertyUpdate(shill::kDevicesProperty, device_path);
   }
 
+  virtual void UpdateIPConfigProperties(
+      ManagedState::ManagedType type,
+      const std::string& path,
+      const std::string& ip_config_path,
+      const base::DictionaryValue& properties) OVERRIDE {
+    AddPropertyUpdate(shill::kIPConfigsProperty, ip_config_path);
+  }
+
   virtual void TechnologyListChanged() OVERRIDE {
     ++technology_list_updates_;
   }
@@ -463,20 +471,19 @@
       base::StringValue(kTestIPConfigPath),
       base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
   message_loop_.RunUntilIdle();
-  // IPConfig property change on the service should trigger property updates for
-  // IP Address, DNS, prefixlen, and gateway.
-  EXPECT_EQ(4, listener_->property_updates(
-      shill::kServicesProperty)[kTestServicePath1]);
+  // IPConfig property change on the service should trigger an IPConfigs update.
+  EXPECT_EQ(1, listener_->property_updates(
+      shill::kIPConfigsProperty)[kTestIPConfigPath]);
 
   // Now, Add a new watched service with the IPConfig already set.
   const std::string kTestServicePath2("test_wifi_service2");
   AddServiceWithIPConfig(shill::kTypeWifi, kTestServicePath2,
                          shill::kStateIdle, kTestIPConfigPath, true);
   message_loop_.RunUntilIdle();
-  // A watched service with the IPConfig property already set must trigger
-  // property updates for IP Address, DNS, prefixlen, and gateway when added.
-  EXPECT_EQ(4, listener_->property_updates(
-      shill::kServicesProperty)[kTestServicePath2]);
+  // A watched service with the IPConfig property already set should trigger an
+  // additional IPConfigs update.
+  EXPECT_EQ(2, listener_->property_updates(
+      shill::kIPConfigsProperty)[kTestIPConfigPath]);
 }
 
 TEST_F(ShillPropertyHandlerTest, ShillPropertyHandlerServiceCompleteList) {
diff --git a/chromeos/network/shill_property_util.cc b/chromeos/network/shill_property_util.cc
index 35e4bb1..ff3980a 100644
--- a/chromeos/network/shill_property_util.cc
+++ b/chromeos/network/shill_property_util.cc
@@ -88,7 +88,7 @@
     return std::string();
   }
 
-  if (IsStringUTF8(ssid))
+  if (base::IsStringUTF8(ssid))
     return ssid;
 
   // Detect encoding and convert to UTF-8.
diff --git a/chromeos/network/shill_property_util.h b/chromeos/network/shill_property_util.h
index 4ae1df5..3abcc1c 100644
--- a/chromeos/network/shill_property_util.h
+++ b/chromeos/network/shill_property_util.h
@@ -81,7 +81,7 @@
   // Matches any network.
   static NetworkTypePattern Default();
 
-  // Matches wireless networks
+  // Matches wireless (WiFi, cellular, etc.) networks
   static NetworkTypePattern Wireless();
 
   // Matches cellular or wimax networks.
diff --git a/chromeos/system/statistics_provider.cc b/chromeos/system/statistics_provider.cc
index 93557b9..7fc6327 100644
--- a/chromeos/system/statistics_provider.cc
+++ b/chromeos/system/statistics_provider.cc
@@ -11,6 +11,7 @@
 #include "base/logging.h"
 #include "base/memory/singleton.h"
 #include "base/path_service.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/synchronization/cancellation_flag.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/sys_info.h"
@@ -37,6 +38,7 @@
 
 const char kHardwareClassCrosSystemKey[] = "hwid";
 const char kUnknownHardwareClass[] = "unknown";
+const char kSerialNumber[] = "sn";
 
 // File to get machine hardware info from, and key/value delimiters of
 // the file.
@@ -269,6 +271,17 @@
     oem_manifest_loaded_ = true;
   }
 
+  if (!base::SysInfo::IsRunningOnChromeOS() &&
+      machine_info_.find(kSerialNumber) == machine_info_.end()) {
+    // Set stub value for testing. A time value is appended to avoid clashes of
+    // the same serial for the same domain, which would invalidate earlier
+    // enrollments. A fake /tmp/machine-info file should be used instead if
+    // a stable serial is needed, e.g. to test re-enrollment.
+    base::TimeDelta time = base::Time::Now() - base::Time::UnixEpoch();
+    machine_info_[kSerialNumber] =
+        "stub_serial_number_" + base::Int64ToString(time.InSeconds());
+  }
+
   // Finished loading the statistics.
   on_statistics_loaded_.Signal();
   VLOG(1) << "Finished loading statistics.";
diff --git a/cloud_print/cloud_print.gyp b/cloud_print/cloud_print.gyp
index feb8311..e54dc86 100644
--- a/cloud_print/cloud_print.gyp
+++ b/cloud_print/cloud_print.gyp
@@ -52,8 +52,7 @@
           ],
         }],
         # See http://crbug.com/162998#c4 for why this is needed.
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and use_allocator!="none"', {
           'dependencies': [
             '../base/allocator/allocator.gyp:allocator',
           ],
diff --git a/components/DEPS b/components/DEPS
index 9a3d245..0505b37 100644
--- a/components/DEPS
+++ b/components/DEPS
@@ -6,16 +6,7 @@
   # components/ are not allowed.
   "-components",
 
-  # Components should only depend on the public Content API, and on
-  # layers below the Content Module. They must not depend on the
-  # implementation of the Content Module.
-  #
-  # Subdirectories of e.g. src/components/component_name should add
-  # the additional parts of the Content API that they need,
-  # e.g. components/component_name/browser/DEPS would add a
-  # "+content/public/browser" rule.
-  "+content/public/common",
-
-  # Dependencies of variations component.
-  "+third_party/mt19937ar",
+  # Components that wish to use the content API or IPC must explicitly declare 
+  # these dependencies; see ./README.
+  "-ipc",
 ]
diff --git a/components/OWNERS b/components/OWNERS
index 8327c90..9f8bcb9 100644
--- a/components/OWNERS
+++ b/components/OWNERS
@@ -16,9 +16,9 @@
 # Temporary for the duration of the bookmarks componentization.
 per-file bookmarks*=droger@chromium.org
 
-per-file chrome_proxy*=bengr@chromium.org
-per-file chrome_proxy*=marq@chromium.org
-per-file chrome_proxy*=bolian@chromium.org
+per-file data_reduction_proxy*=bengr@chromium.org
+per-file data_reduction_proxy*=marq@chromium.org
+per-file data_reduction_proxy*=bolian@chromium.org
 
 per-file cloud_devices*=gene@chromium.org
 per-file cloud_devices*=noamsml@chromium.org
diff --git a/components/README b/components/README
index 7201320..8112f6e 100644
--- a/components/README
+++ b/components/README
@@ -1,19 +1,19 @@
 This directory is for features that are intended for reuse across multiple
 embedders (e.g., Android WebView and Chrome).
 
-By default, subdirectories have the Content Module as the uppermost layer they
-depend on, i.e., they may depend only on the Content API (content/public) and
-on lower layers (e.g. base/, net/, ipc/ etc.). Individual subdirectories may
-further restrict their dependencies, e.g., a component that is used by Chrome
-for iOS (which does not use the content API) will either disallow usage of
-content/public or be in the form of a layered component
+By default, components can depend only on the lower layers of the Chromium
+codebase(e.g. base/, net/, etc.). Individual components may additionally allow
+dependencies on the content API and IPC; however, if such a component is used
+by Chrome for iOS (which does not use the content API or IPC), the component
+will have to be in the form of a layered component
 (http://www.chromium.org/developers/design-documents/layered-components-design).
 
 Components that have bits of code that need to live in different
 processes (e.g. some code in the browser process, some in the renderer
 process, etc.) should separate the code into different subdirectories.
 Hence for a component named 'foo' you might end up with a structure
-like the following:
+like the following (assuming that foo is not used by iOS and thus does not
+need to be a layered component):
 
 components/foo          - DEPS, OWNERS, foo.gypi
 components/foo/browser  - code that needs the browser process
@@ -36,6 +36,4 @@
 Code in a component should be placed in a namespace corresponding to
 the name of the component; e.g. for a component living in
 //components/foo, code in that component should be in the foo::
-namespace. Note that it used to be the rule that all code under
-//components should be in the components:: namespace; this is being
-phased out.
+namespace.
diff --git a/components/auto_login_parser.target.darwin-arm.mk b/components/auto_login_parser.target.darwin-arm.mk
index 9ec4a6a..e89a1d9 100644
--- a/components/auto_login_parser.target.darwin-arm.mk
+++ b/components/auto_login_parser.target.darwin-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/auto_login_parser.target.darwin-x86.mk b/components/auto_login_parser.target.darwin-x86.mk
index 7e82b4c..95074cf 100644
--- a/components/auto_login_parser.target.darwin-x86.mk
+++ b/components/auto_login_parser.target.darwin-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/auto_login_parser.target.darwin-x86_64.mk b/components/auto_login_parser.target.darwin-x86_64.mk
index 3cb5bdd..e90cf3e 100644
--- a/components/auto_login_parser.target.darwin-x86_64.mk
+++ b/components/auto_login_parser.target.darwin-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/auto_login_parser.target.linux-arm.mk b/components/auto_login_parser.target.linux-arm.mk
index 9ec4a6a..e89a1d9 100644
--- a/components/auto_login_parser.target.linux-arm.mk
+++ b/components/auto_login_parser.target.linux-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/auto_login_parser.target.linux-x86.mk b/components/auto_login_parser.target.linux-x86.mk
index 7e82b4c..95074cf 100644
--- a/components/auto_login_parser.target.linux-x86.mk
+++ b/components/auto_login_parser.target.linux-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/auto_login_parser.target.linux-x86_64.mk b/components/auto_login_parser.target.linux-x86_64.mk
index 3cb5bdd..e90cf3e 100644
--- a/components/auto_login_parser.target.linux-x86_64.mk
+++ b/components/auto_login_parser.target.linux-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/autofill/DEPS b/components/autofill/DEPS
index 9c56889..3f87406 100644
--- a/components/autofill/DEPS
+++ b/components/autofill/DEPS
@@ -7,6 +7,4 @@
   # Autofill is a layered component; subdirectories must explicitly introduce
   # the ability to use the content layer as appropriate.
   "-components/autofill/content",
-  "-content/public/common",
-  "-ipc",
 ]
diff --git a/components/autofill/content/browser/risk/fingerprint.cc b/components/autofill/content/browser/risk/fingerprint.cc
index 1f412c5..5c741b4 100644
--- a/components/autofill/content/browser/risk/fingerprint.cc
+++ b/components/autofill/content/browser/risk/fingerprint.cc
@@ -34,7 +34,6 @@
 #include "content/public/browser/render_widget_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/geoposition.h"
 #include "content/public/common/webplugininfo.h"
 #include "gpu/config/gpu_info.h"
@@ -531,7 +530,7 @@
 void GetFingerprint(
     uint64 obfuscated_gaia_id,
     const gfx::Rect& window_bounds,
-    const content::WebContents& web_contents,
+    content::WebContents* web_contents,
     const std::string& version,
     const std::string& charset,
     const std::string& accept_languages,
@@ -539,12 +538,11 @@
     const std::string& app_locale,
     const std::string& user_agent,
     const base::Callback<void(scoped_ptr<Fingerprint>)>& callback) {
-  gfx::Rect content_bounds;
-  web_contents.GetView()->GetContainerBounds(&content_bounds);
+  gfx::Rect content_bounds = web_contents->GetContainerBounds();
 
   blink::WebScreenInfo screen_info;
   content::RenderWidgetHostView* host_view =
-      web_contents.GetRenderWidgetHostView();
+      web_contents->GetRenderWidgetHostView();
   if (host_view)
     host_view->GetRenderWidgetHost()->GetWebScreenInfo(&screen_info);
 
diff --git a/components/autofill/content/browser/risk/fingerprint.h b/components/autofill/content/browser/risk/fingerprint.h
index 9b490c3..6cef2f9 100644
--- a/components/autofill/content/browser/risk/fingerprint.h
+++ b/components/autofill/content/browser/risk/fingerprint.h
@@ -53,7 +53,7 @@
 void GetFingerprint(
     uint64 obfuscated_gaia_id,
     const gfx::Rect& window_bounds,
-    const content::WebContents& web_contents,
+    content::WebContents* web_contents,
     const std::string& version,
     const std::string& charset,
     const std::string& accept_languages,
diff --git a/components/autofill/content/browser/wallet/wallet_address.cc b/components/autofill/content/browser/wallet/wallet_address.cc
index 643b283..30825c9 100644
--- a/components/autofill/content/browser/wallet/wallet_address.cc
+++ b/components/autofill/content/browser/wallet/wallet_address.cc
@@ -330,7 +330,7 @@
 base::string16 Address::GetInfo(const AutofillType& type,
                                 const std::string& app_locale) const {
   if (type.html_type() == HTML_TYPE_COUNTRY_CODE) {
-    DCHECK(IsStringASCII(country_name_code()));
+    DCHECK(base::IsStringASCII(country_name_code()));
     return base::ASCIIToUTF16(country_name_code());
   }
 
diff --git a/components/autofill/content/browser/wallet/wallet_service_url.cc b/components/autofill/content/browser/wallet/wallet_service_url.cc
index 86b6b53..310b927 100644
--- a/components/autofill/content/browser/wallet/wallet_service_url.cc
+++ b/components/autofill/content/browser/wallet/wallet_service_url.cc
@@ -180,11 +180,10 @@
 
   *user_index = 0;
   std::string query_str = url.query();
-  url_parse::Component query(0, query_str.length());
-  url_parse::Component key, value;
+  url::Component query(0, query_str.length());
+  url::Component key, value;
   const char kUserIndexKey[] = "authuser";
-  while (url_parse::ExtractQueryKeyValue(query_str.c_str(), &query, &key,
-                                         &value)) {
+  while (url::ExtractQueryKeyValue(query_str.c_str(), &query, &key, &value)) {
     if (key.is_nonempty() &&
         query_str.substr(key.begin, key.len) == kUserIndexKey) {
       base::StringToSizeT(query_str.substr(value.begin, value.len), user_index);
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index 7cd6e92..80326c3 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -260,7 +260,7 @@
   element_ = *element;
 }
 
-void AutofillAgent::OrientationChangeEvent(int orientation) {
+void AutofillAgent::OrientationChangeEvent() {
   HidePopup();
 }
 
@@ -280,7 +280,7 @@
   GURL url(form.document().url());
   content::SSLStatus ssl_status =
       render_view()->GetSSLStatusOfFrame(form.document().frame());
-  bool is_safe = url.SchemeIs(content::kHttpsScheme) &&
+  bool is_safe = url.SchemeIs(url::kHttpsScheme) &&
       !net::IsCertStatusError(ssl_status.cert_status);
   bool allow_unsafe = CommandLine::ForCurrentProcess()->HasSwitch(
       ::switches::kReduceSecurityForTesting);
@@ -640,24 +640,24 @@
   gfx::RectF bounding_box_scaled =
       GetScaledBoundingBox(web_view_->pageScaleFactor(), &element_);
 
+  std::vector<base::string16> data_list_values;
+  std::vector<base::string16> data_list_labels;
   const WebInputElement* input_element = toWebInputElement(&element);
   if (input_element) {
     // Find the datalist values and send them to the browser process.
-    std::vector<base::string16> data_list_values;
-    std::vector<base::string16> data_list_labels;
     GetDataListSuggestions(*input_element,
                            datalist_only,
                            &data_list_values,
                            &data_list_labels);
     TrimStringVectorForIPC(&data_list_values);
     TrimStringVectorForIPC(&data_list_labels);
-
-    Send(new AutofillHostMsg_SetDataList(routing_id(),
-                                         data_list_values,
-                                         data_list_labels));
   }
 
   is_popup_possibly_visible_ = true;
+  Send(new AutofillHostMsg_SetDataList(routing_id(),
+                                       data_list_values,
+                                       data_list_labels));
+
   Send(new AutofillHostMsg_QueryFormFieldAutofill(routing_id(),
                                                   autofill_query_id_,
                                                   form,
diff --git a/components/autofill/content/renderer/autofill_agent.h b/components/autofill/content/renderer/autofill_agent.h
index deca235..8d30f24 100644
--- a/components/autofill/content/renderer/autofill_agent.h
+++ b/components/autofill/content/renderer/autofill_agent.h
@@ -67,7 +67,7 @@
   virtual void ZoomLevelChanged() OVERRIDE;
   virtual void DidChangeScrollOffset(blink::WebLocalFrame* frame) OVERRIDE;
   virtual void FocusedNodeChanged(const blink::WebNode& node) OVERRIDE;
-  virtual void OrientationChangeEvent(int orientation) OVERRIDE;
+  virtual void OrientationChangeEvent() OVERRIDE;
 
   // PageClickListener:
   virtual void FormControlElementClicked(
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 6667a9d..9e1e1db 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -17,6 +17,9 @@
 #include "components/autofill/core/common/password_autofill_util.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/autofill/core/common/password_form_fill_data.h"
+#include "content/public/common/page_transition_types.h"
+#include "content/public/renderer/document_state.h"
+#include "content/public/renderer/navigation_state.h"
 #include "content/public/renderer/render_view.h"
 #include "third_party/WebKit/public/platform/WebVector.h"
 #include "third_party/WebKit/public/web/WebAutofillClient.h"
@@ -380,8 +383,7 @@
   base::string16 current_username = username_element.value();
   username_element.setValue(username, true);
   username_element.setAutofilled(true);
-  username_element.setSelectionRange(current_username.length(),
-                                     username.length());
+  username_element.setSelectionRange(username.length(), username.length());
 
   password_info.password_field.setValue(password, true);
   password_info.password_field.setAutofilled(true);
@@ -643,7 +645,17 @@
       logger->LogBoolean(Logger::STRING_FORM_FRAME_EQ_FRAME,
                          form_frame == frame);
     }
-    if (!blink::WebUserGestureIndicator::isProcessingUserGesture()) {
+    // Bug fix for crbug.com/368690. isProcessingUserGesture() is false when
+    // the user is performing actions outside the page (e.g. typed url,
+    // history navigation). We don't want to trigger saving in these cases.
+    content::DocumentState* document_state =
+        content::DocumentState::FromDataSource(
+            frame->provisionalDataSource());
+    content::NavigationState* navigation_state =
+        document_state->navigation_state();
+    if (content::PageTransitionIsWebTriggerable(
+            navigation_state->transition_type()) &&
+        !blink::WebUserGestureIndicator::isProcessingUserGesture()) {
       // If onsubmit has been called, try and save that form.
       if (provisionally_saved_forms_[form_frame].get()) {
         if (logger) {
diff --git a/components/autofill/core/browser/address.cc b/components/autofill/core/browser/address.cc
index de65147..79cdef9 100644
--- a/components/autofill/core/browser/address.cc
+++ b/components/autofill/core/browser/address.cc
@@ -107,7 +107,7 @@
 
     case ADDRESS_HOME_COUNTRY:
       DCHECK(value.empty() ||
-             (value.length() == 2u && IsStringASCII(value)));
+             (value.length() == 2u && base::IsStringASCII(value)));
       country_code_ = base::UTF16ToASCII(value);
       break;
 
@@ -144,7 +144,7 @@
                       const base::string16& value,
                       const std::string& app_locale) {
   if (type.html_type() == HTML_TYPE_COUNTRY_CODE) {
-    if (!value.empty() && (value.size() != 2u || !IsStringASCII(value))) {
+    if (!value.empty() && (value.size() != 2u || !base::IsStringASCII(value))) {
       country_code_ = std::string();
       return false;
     }
diff --git a/components/autofill/core/browser/validation.cc b/components/autofill/core/browser/validation.cc
index e1edf73..62509cb 100644
--- a/components/autofill/core/browser/validation.cc
+++ b/components/autofill/core/browser/validation.cc
@@ -182,7 +182,7 @@
   //   http://www.socialsecurity.gov/employer/stateweb.htm
   //   http://www.socialsecurity.gov/employer/ssnvhighgroup.htm
 
-  if (number_string.length() != 9 || !IsStringASCII(number_string))
+  if (number_string.length() != 9 || !base::IsStringASCII(number_string))
     return false;
 
   int area;
diff --git a/components/autofill/core/common/forms_seen_state.h b/components/autofill/core/common/forms_seen_state.h
index da417f9..f789264 100644
--- a/components/autofill/core/common/forms_seen_state.h
+++ b/components/autofill/core/common/forms_seen_state.h
@@ -1,4 +1,4 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
+// 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.
 
diff --git a/components/autofill_content_browser.target.darwin-arm.mk b/components/autofill_content_browser.target.darwin-arm.mk
index 84c8386..a9c713b 100644
--- a/components/autofill_content_browser.target.darwin-arm.mk
+++ b/components/autofill_content_browser.target.darwin-arm.mk
@@ -63,7 +63,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -112,11 +111,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -217,7 +211,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -266,11 +259,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_browser.target.darwin-arm64.mk b/components/autofill_content_browser.target.darwin-arm64.mk
index 14f601e..6558bdd 100644
--- a/components/autofill_content_browser.target.darwin-arm64.mk
+++ b/components/autofill_content_browser.target.darwin-arm64.mk
@@ -108,11 +108,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -257,11 +252,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_browser.target.darwin-mips.mk b/components/autofill_content_browser.target.darwin-mips.mk
index 13edc9e..a2b83b3 100644
--- a/components/autofill_content_browser.target.darwin-mips.mk
+++ b/components/autofill_content_browser.target.darwin-mips.mk
@@ -111,11 +111,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -264,11 +259,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_browser.target.darwin-x86.mk b/components/autofill_content_browser.target.darwin-x86.mk
index 2bf7337..a412ad1 100644
--- a/components/autofill_content_browser.target.darwin-x86.mk
+++ b/components/autofill_content_browser.target.darwin-x86.mk
@@ -65,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -113,11 +112,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -218,7 +212,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -266,11 +259,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_browser.target.darwin-x86_64.mk b/components/autofill_content_browser.target.darwin-x86_64.mk
index 4904267..b05bcf3 100644
--- a/components/autofill_content_browser.target.darwin-x86_64.mk
+++ b/components/autofill_content_browser.target.darwin-x86_64.mk
@@ -65,7 +65,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -113,11 +112,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -219,7 +213,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -267,11 +260,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_browser.target.linux-arm.mk b/components/autofill_content_browser.target.linux-arm.mk
index 84c8386..a9c713b 100644
--- a/components/autofill_content_browser.target.linux-arm.mk
+++ b/components/autofill_content_browser.target.linux-arm.mk
@@ -63,7 +63,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -112,11 +111,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -217,7 +211,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -266,11 +259,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_browser.target.linux-arm64.mk b/components/autofill_content_browser.target.linux-arm64.mk
index 14f601e..6558bdd 100644
--- a/components/autofill_content_browser.target.linux-arm64.mk
+++ b/components/autofill_content_browser.target.linux-arm64.mk
@@ -108,11 +108,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -257,11 +252,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_browser.target.linux-mips.mk b/components/autofill_content_browser.target.linux-mips.mk
index 13edc9e..a2b83b3 100644
--- a/components/autofill_content_browser.target.linux-mips.mk
+++ b/components/autofill_content_browser.target.linux-mips.mk
@@ -111,11 +111,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -264,11 +259,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_browser.target.linux-x86.mk b/components/autofill_content_browser.target.linux-x86.mk
index 2bf7337..a412ad1 100644
--- a/components/autofill_content_browser.target.linux-x86.mk
+++ b/components/autofill_content_browser.target.linux-x86.mk
@@ -65,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -113,11 +112,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -218,7 +212,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -266,11 +259,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_browser.target.linux-x86_64.mk b/components/autofill_content_browser.target.linux-x86_64.mk
index 4904267..b05bcf3 100644
--- a/components/autofill_content_browser.target.linux-x86_64.mk
+++ b/components/autofill_content_browser.target.linux-x86_64.mk
@@ -65,7 +65,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -113,11 +112,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -219,7 +213,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -267,11 +260,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_common.target.darwin-arm.mk b/components/autofill_content_common.target.darwin-arm.mk
index eea7fc5..fa4f71f 100644
--- a/components/autofill_content_common.target.darwin-arm.mk
+++ b/components/autofill_content_common.target.darwin-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -92,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -171,7 +165,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -220,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_common.target.darwin-arm64.mk b/components/autofill_content_common.target.darwin-arm64.mk
index 5c6b80b..9f8113d 100644
--- a/components/autofill_content_common.target.darwin-arm64.mk
+++ b/components/autofill_content_common.target.darwin-arm64.mk
@@ -88,11 +88,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -211,11 +206,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_common.target.darwin-mips.mk b/components/autofill_content_common.target.darwin-mips.mk
index 1808364..aa2fd8e 100644
--- a/components/autofill_content_common.target.darwin-mips.mk
+++ b/components/autofill_content_common.target.darwin-mips.mk
@@ -91,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -218,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_common.target.darwin-x86.mk b/components/autofill_content_common.target.darwin-x86.mk
index 1b332e9..0b7f52f 100644
--- a/components/autofill_content_common.target.darwin-x86.mk
+++ b/components/autofill_content_common.target.darwin-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -173,7 +167,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -221,11 +214,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_common.target.darwin-x86_64.mk b/components/autofill_content_common.target.darwin-x86_64.mk
index 27f9034..34cef21 100644
--- a/components/autofill_content_common.target.darwin-x86_64.mk
+++ b/components/autofill_content_common.target.darwin-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -173,7 +167,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -221,11 +214,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_common.target.linux-arm.mk b/components/autofill_content_common.target.linux-arm.mk
index eea7fc5..fa4f71f 100644
--- a/components/autofill_content_common.target.linux-arm.mk
+++ b/components/autofill_content_common.target.linux-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -92,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -171,7 +165,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -220,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_common.target.linux-arm64.mk b/components/autofill_content_common.target.linux-arm64.mk
index 5c6b80b..9f8113d 100644
--- a/components/autofill_content_common.target.linux-arm64.mk
+++ b/components/autofill_content_common.target.linux-arm64.mk
@@ -88,11 +88,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -211,11 +206,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_common.target.linux-mips.mk b/components/autofill_content_common.target.linux-mips.mk
index 1808364..aa2fd8e 100644
--- a/components/autofill_content_common.target.linux-mips.mk
+++ b/components/autofill_content_common.target.linux-mips.mk
@@ -91,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -218,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_common.target.linux-x86.mk b/components/autofill_content_common.target.linux-x86.mk
index 1b332e9..0b7f52f 100644
--- a/components/autofill_content_common.target.linux-x86.mk
+++ b/components/autofill_content_common.target.linux-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -173,7 +167,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -221,11 +214,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_common.target.linux-x86_64.mk b/components/autofill_content_common.target.linux-x86_64.mk
index 27f9034..34cef21 100644
--- a/components/autofill_content_common.target.linux-x86_64.mk
+++ b/components/autofill_content_common.target.linux-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -173,7 +167,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -221,11 +214,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_renderer.target.darwin-arm.mk b/components/autofill_content_renderer.target.darwin-arm.mk
index 8b1f665..a706d7f 100644
--- a/components/autofill_content_renderer.target.darwin-arm.mk
+++ b/components/autofill_content_renderer.target.darwin-arm.mk
@@ -52,7 +52,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -102,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -197,7 +191,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -247,11 +240,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_renderer.target.darwin-arm64.mk b/components/autofill_content_renderer.target.darwin-arm64.mk
index 352ad6d..8ab766d 100644
--- a/components/autofill_content_renderer.target.darwin-arm64.mk
+++ b/components/autofill_content_renderer.target.darwin-arm64.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -238,11 +233,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_renderer.target.darwin-mips.mk b/components/autofill_content_renderer.target.darwin-mips.mk
index 57a1883..6949021 100644
--- a/components/autofill_content_renderer.target.darwin-mips.mk
+++ b/components/autofill_content_renderer.target.darwin-mips.mk
@@ -101,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -245,11 +240,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_renderer.target.darwin-x86.mk b/components/autofill_content_renderer.target.darwin-x86.mk
index e80aa12..62d602e 100644
--- a/components/autofill_content_renderer.target.darwin-x86.mk
+++ b/components/autofill_content_renderer.target.darwin-x86.mk
@@ -54,7 +54,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -103,11 +102,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -199,7 +193,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -248,11 +241,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_renderer.target.darwin-x86_64.mk b/components/autofill_content_renderer.target.darwin-x86_64.mk
index 3964bb3..0016f8d 100644
--- a/components/autofill_content_renderer.target.darwin-x86_64.mk
+++ b/components/autofill_content_renderer.target.darwin-x86_64.mk
@@ -54,7 +54,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -103,11 +102,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -199,7 +193,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -248,11 +241,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_renderer.target.linux-arm.mk b/components/autofill_content_renderer.target.linux-arm.mk
index 8b1f665..a706d7f 100644
--- a/components/autofill_content_renderer.target.linux-arm.mk
+++ b/components/autofill_content_renderer.target.linux-arm.mk
@@ -52,7 +52,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -102,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -197,7 +191,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -247,11 +240,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_renderer.target.linux-arm64.mk b/components/autofill_content_renderer.target.linux-arm64.mk
index 352ad6d..8ab766d 100644
--- a/components/autofill_content_renderer.target.linux-arm64.mk
+++ b/components/autofill_content_renderer.target.linux-arm64.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -238,11 +233,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_renderer.target.linux-mips.mk b/components/autofill_content_renderer.target.linux-mips.mk
index 57a1883..6949021 100644
--- a/components/autofill_content_renderer.target.linux-mips.mk
+++ b/components/autofill_content_renderer.target.linux-mips.mk
@@ -101,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -245,11 +240,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_renderer.target.linux-x86.mk b/components/autofill_content_renderer.target.linux-x86.mk
index e80aa12..62d602e 100644
--- a/components/autofill_content_renderer.target.linux-x86.mk
+++ b/components/autofill_content_renderer.target.linux-x86.mk
@@ -54,7 +54,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -103,11 +102,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -199,7 +193,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -248,11 +241,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_renderer.target.linux-x86_64.mk b/components/autofill_content_renderer.target.linux-x86_64.mk
index 3964bb3..0016f8d 100644
--- a/components/autofill_content_renderer.target.linux-x86_64.mk
+++ b/components/autofill_content_renderer.target.linux-x86_64.mk
@@ -54,7 +54,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -103,11 +102,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -199,7 +193,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -248,11 +241,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_content_risk_proto.target.darwin-arm.mk b/components/autofill_content_risk_proto.target.darwin-arm.mk
index e1b0475..4c757f3 100644
--- a/components/autofill_content_risk_proto.target.darwin-arm.mk
+++ b/components/autofill_content_risk_proto.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_content_risk_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['autofill/content/browser/risk/proto/fingerprint.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'autofill/content/browser/risk/proto', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +65,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -155,7 +155,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/autofill_content_risk_proto.target.darwin-arm64.mk b/components/autofill_content_risk_proto.target.darwin-arm64.mk
index 9320d2a..9433230 100644
--- a/components/autofill_content_risk_proto.target.darwin-arm64.mk
+++ b/components/autofill_content_risk_proto.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_content_risk_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['autofill/content/browser/risk/proto/fingerprint.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'autofill/content/browser/risk/proto', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_content_risk_proto.target.darwin-mips.mk b/components/autofill_content_risk_proto.target.darwin-mips.mk
index 6c35fae..d5f87c2 100644
--- a/components/autofill_content_risk_proto.target.darwin-mips.mk
+++ b/components/autofill_content_risk_proto.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_content_risk_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['autofill/content/browser/risk/proto/fingerprint.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'autofill/content/browser/risk/proto', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_content_risk_proto.target.darwin-x86.mk b/components/autofill_content_risk_proto.target.darwin-x86.mk
index d8c9d7a..0fdcf19 100644
--- a/components/autofill_content_risk_proto.target.darwin-x86.mk
+++ b/components/autofill_content_risk_proto.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_content_risk_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['autofill/content/browser/risk/proto/fingerprint.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'autofill/content/browser/risk/proto', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/autofill_content_risk_proto.target.darwin-x86_64.mk b/components/autofill_content_risk_proto.target.darwin-x86_64.mk
index d96f588..bdb4560 100644
--- a/components/autofill_content_risk_proto.target.darwin-x86_64.mk
+++ b/components/autofill_content_risk_proto.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_content_risk_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['autofill/content/browser/risk/proto/fingerprint.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'autofill/content/browser/risk/proto', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/autofill_content_risk_proto.target.linux-arm.mk b/components/autofill_content_risk_proto.target.linux-arm.mk
index e1b0475..4c757f3 100644
--- a/components/autofill_content_risk_proto.target.linux-arm.mk
+++ b/components/autofill_content_risk_proto.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_content_risk_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['autofill/content/browser/risk/proto/fingerprint.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'autofill/content/browser/risk/proto', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +65,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -155,7 +155,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/autofill_content_risk_proto.target.linux-arm64.mk b/components/autofill_content_risk_proto.target.linux-arm64.mk
index 9320d2a..9433230 100644
--- a/components/autofill_content_risk_proto.target.linux-arm64.mk
+++ b/components/autofill_content_risk_proto.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_content_risk_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['autofill/content/browser/risk/proto/fingerprint.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'autofill/content/browser/risk/proto', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_content_risk_proto.target.linux-mips.mk b/components/autofill_content_risk_proto.target.linux-mips.mk
index 6c35fae..d5f87c2 100644
--- a/components/autofill_content_risk_proto.target.linux-mips.mk
+++ b/components/autofill_content_risk_proto.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_content_risk_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['autofill/content/browser/risk/proto/fingerprint.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'autofill/content/browser/risk/proto', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_content_risk_proto.target.linux-x86.mk b/components/autofill_content_risk_proto.target.linux-x86.mk
index d8c9d7a..0fdcf19 100644
--- a/components/autofill_content_risk_proto.target.linux-x86.mk
+++ b/components/autofill_content_risk_proto.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_content_risk_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['autofill/content/browser/risk/proto/fingerprint.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'autofill/content/browser/risk/proto', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/autofill_content_risk_proto.target.linux-x86_64.mk b/components/autofill_content_risk_proto.target.linux-x86_64.mk
index d96f588..bdb4560 100644
--- a/components/autofill_content_risk_proto.target.linux-x86_64.mk
+++ b/components/autofill_content_risk_proto.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_content_risk_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['autofill/content/browser/risk/proto/fingerprint.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'autofill/content/browser/risk/proto', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/components/autofill/content/browser/risk/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/components/autofill/content/browser/risk/proto/fingerprint_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/autofill_core_browser.target.darwin-arm.mk b/components/autofill_core_browser.target.darwin-arm.mk
index 9ae994f..3b58a72 100644
--- a/components/autofill_core_browser.target.darwin-arm.mk
+++ b/components/autofill_core_browser.target.darwin-arm.mk
@@ -88,7 +88,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,11 +136,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -240,7 +234,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -289,11 +282,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_browser.target.darwin-arm64.mk b/components/autofill_core_browser.target.darwin-arm64.mk
index 72674d9..70a45de 100644
--- a/components/autofill_core_browser.target.darwin-arm64.mk
+++ b/components/autofill_core_browser.target.darwin-arm64.mk
@@ -133,11 +133,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -280,11 +275,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_browser.target.darwin-mips.mk b/components/autofill_core_browser.target.darwin-mips.mk
index 281c676..8d9a8bf 100644
--- a/components/autofill_core_browser.target.darwin-mips.mk
+++ b/components/autofill_core_browser.target.darwin-mips.mk
@@ -136,11 +136,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -287,11 +282,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_browser.target.darwin-x86.mk b/components/autofill_core_browser.target.darwin-x86.mk
index 149befe..3bca39b 100644
--- a/components/autofill_core_browser.target.darwin-x86.mk
+++ b/components/autofill_core_browser.target.darwin-x86.mk
@@ -90,7 +90,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,11 +137,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -241,7 +235,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -289,11 +282,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_browser.target.darwin-x86_64.mk b/components/autofill_core_browser.target.darwin-x86_64.mk
index 9aa5e14..438f352 100644
--- a/components/autofill_core_browser.target.darwin-x86_64.mk
+++ b/components/autofill_core_browser.target.darwin-x86_64.mk
@@ -90,7 +90,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,11 +137,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -242,7 +236,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -290,11 +283,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_browser.target.linux-arm.mk b/components/autofill_core_browser.target.linux-arm.mk
index 9ae994f..3b58a72 100644
--- a/components/autofill_core_browser.target.linux-arm.mk
+++ b/components/autofill_core_browser.target.linux-arm.mk
@@ -88,7 +88,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,11 +136,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -240,7 +234,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -289,11 +282,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_browser.target.linux-arm64.mk b/components/autofill_core_browser.target.linux-arm64.mk
index 72674d9..70a45de 100644
--- a/components/autofill_core_browser.target.linux-arm64.mk
+++ b/components/autofill_core_browser.target.linux-arm64.mk
@@ -133,11 +133,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -280,11 +275,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_browser.target.linux-mips.mk b/components/autofill_core_browser.target.linux-mips.mk
index 281c676..8d9a8bf 100644
--- a/components/autofill_core_browser.target.linux-mips.mk
+++ b/components/autofill_core_browser.target.linux-mips.mk
@@ -136,11 +136,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -287,11 +282,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_browser.target.linux-x86.mk b/components/autofill_core_browser.target.linux-x86.mk
index 149befe..3bca39b 100644
--- a/components/autofill_core_browser.target.linux-x86.mk
+++ b/components/autofill_core_browser.target.linux-x86.mk
@@ -90,7 +90,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,11 +137,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -241,7 +235,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -289,11 +282,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_browser.target.linux-x86_64.mk b/components/autofill_core_browser.target.linux-x86_64.mk
index 9aa5e14..438f352 100644
--- a/components/autofill_core_browser.target.linux-x86_64.mk
+++ b/components/autofill_core_browser.target.linux-x86_64.mk
@@ -90,7 +90,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,11 +137,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -242,7 +236,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -290,11 +283,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_common.target.darwin-arm.mk b/components/autofill_core_common.target.darwin-arm.mk
index dbed282..c64ff0e 100644
--- a/components/autofill_core_common.target.darwin-arm.mk
+++ b/components/autofill_core_common.target.darwin-arm.mk
@@ -61,7 +61,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -110,11 +109,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -186,7 +180,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -235,11 +228,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_common.target.darwin-arm64.mk b/components/autofill_core_common.target.darwin-arm64.mk
index 99d6a04..8e84e87 100644
--- a/components/autofill_core_common.target.darwin-arm64.mk
+++ b/components/autofill_core_common.target.darwin-arm64.mk
@@ -106,11 +106,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -226,11 +221,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_common.target.darwin-mips.mk b/components/autofill_core_common.target.darwin-mips.mk
index 80436f5..51bc80f 100644
--- a/components/autofill_core_common.target.darwin-mips.mk
+++ b/components/autofill_core_common.target.darwin-mips.mk
@@ -109,11 +109,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -233,11 +228,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_common.target.darwin-x86.mk b/components/autofill_core_common.target.darwin-x86.mk
index 9ad59c9..40cf275 100644
--- a/components/autofill_core_common.target.darwin-x86.mk
+++ b/components/autofill_core_common.target.darwin-x86.mk
@@ -63,7 +63,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -110,11 +109,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -187,7 +181,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -234,11 +227,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_common.target.darwin-x86_64.mk b/components/autofill_core_common.target.darwin-x86_64.mk
index b94b7bd..6c9a4a1 100644
--- a/components/autofill_core_common.target.darwin-x86_64.mk
+++ b/components/autofill_core_common.target.darwin-x86_64.mk
@@ -63,7 +63,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -111,11 +110,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -188,7 +182,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -236,11 +229,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_common.target.linux-arm.mk b/components/autofill_core_common.target.linux-arm.mk
index dbed282..c64ff0e 100644
--- a/components/autofill_core_common.target.linux-arm.mk
+++ b/components/autofill_core_common.target.linux-arm.mk
@@ -61,7 +61,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -110,11 +109,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -186,7 +180,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -235,11 +228,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_common.target.linux-arm64.mk b/components/autofill_core_common.target.linux-arm64.mk
index 99d6a04..8e84e87 100644
--- a/components/autofill_core_common.target.linux-arm64.mk
+++ b/components/autofill_core_common.target.linux-arm64.mk
@@ -106,11 +106,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -226,11 +221,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_common.target.linux-mips.mk b/components/autofill_core_common.target.linux-mips.mk
index 80436f5..51bc80f 100644
--- a/components/autofill_core_common.target.linux-mips.mk
+++ b/components/autofill_core_common.target.linux-mips.mk
@@ -109,11 +109,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -233,11 +228,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_common.target.linux-x86.mk b/components/autofill_core_common.target.linux-x86.mk
index 9ad59c9..40cf275 100644
--- a/components/autofill_core_common.target.linux-x86.mk
+++ b/components/autofill_core_common.target.linux-x86.mk
@@ -63,7 +63,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -110,11 +109,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -187,7 +181,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -234,11 +227,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_core_common.target.linux-x86_64.mk b/components/autofill_core_common.target.linux-x86_64.mk
index b94b7bd..6c9a4a1 100644
--- a/components/autofill_core_common.target.linux-x86_64.mk
+++ b/components/autofill_core_common.target.linux-x86_64.mk
@@ -63,7 +63,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -111,11 +110,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -188,7 +182,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -236,11 +229,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/autofill_jni_headers.target.darwin-arm.mk b/components/autofill_jni_headers.target.darwin-arm.mk
index ff7ca53..13a0700 100644
--- a/components/autofill_jni_headers.target.darwin-arm.mk
+++ b/components/autofill_jni_headers.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/autofill/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['autofill/core/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/autofill/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -54,7 +55,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/autofill_jni_headers.target.darwin-arm64.mk b/components/autofill_jni_headers.target.darwin-arm64.mk
index 98e8284..af4d52c 100644
--- a/components/autofill_jni_headers.target.darwin-arm64.mk
+++ b/components/autofill_jni_headers.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/autofill/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['autofill/core/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/autofill/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_jni_headers.target.darwin-mips.mk b/components/autofill_jni_headers.target.darwin-mips.mk
index bd48011..d72a186 100644
--- a/components/autofill_jni_headers.target.darwin-mips.mk
+++ b/components/autofill_jni_headers.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/autofill/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['autofill/core/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/autofill/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_jni_headers.target.darwin-x86.mk b/components/autofill_jni_headers.target.darwin-x86.mk
index e2ee604..9765f9f 100644
--- a/components/autofill_jni_headers.target.darwin-x86.mk
+++ b/components/autofill_jni_headers.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/autofill/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['autofill/core/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/autofill/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -56,7 +57,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/autofill_jni_headers.target.darwin-x86_64.mk b/components/autofill_jni_headers.target.darwin-x86_64.mk
index a261b75..64ddd41 100644
--- a/components/autofill_jni_headers.target.darwin-x86_64.mk
+++ b/components/autofill_jni_headers.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/autofill/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['autofill/core/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/autofill/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -56,7 +57,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/autofill_jni_headers.target.linux-arm.mk b/components/autofill_jni_headers.target.linux-arm.mk
index ff7ca53..13a0700 100644
--- a/components/autofill_jni_headers.target.linux-arm.mk
+++ b/components/autofill_jni_headers.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/autofill/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['autofill/core/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/autofill/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -54,7 +55,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/autofill_jni_headers.target.linux-arm64.mk b/components/autofill_jni_headers.target.linux-arm64.mk
index 98e8284..af4d52c 100644
--- a/components/autofill_jni_headers.target.linux-arm64.mk
+++ b/components/autofill_jni_headers.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/autofill/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['autofill/core/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/autofill/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_jni_headers.target.linux-mips.mk b/components/autofill_jni_headers.target.linux-mips.mk
index bd48011..d72a186 100644
--- a/components/autofill_jni_headers.target.linux-mips.mk
+++ b/components/autofill_jni_headers.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/autofill/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['autofill/core/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/autofill/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_jni_headers.target.linux-x86.mk b/components/autofill_jni_headers.target.linux-x86.mk
index e2ee604..9765f9f 100644
--- a/components/autofill_jni_headers.target.linux-x86.mk
+++ b/components/autofill_jni_headers.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/autofill/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['autofill/core/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/autofill/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -56,7 +57,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/autofill_jni_headers.target.linux-x86_64.mk b/components/autofill_jni_headers.target.linux-x86_64.mk
index a261b75..64ddd41 100644
--- a/components/autofill_jni_headers.target.linux-x86_64.mk
+++ b/components/autofill_jni_headers.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_autofill_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/autofill/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['autofill/core/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/autofill/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill/jni/PersonalAutofillPopulator_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -56,7 +57,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/autofill_regexes.target.darwin-arm.mk b/components/autofill_regexes.target.darwin-arm.mk
index d99dfb8..5c525f3 100644
--- a/components/autofill_regexes.target.darwin-arm.mk
+++ b/components/autofill_regexes.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "autofill_regexes":
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_regexes.target.darwin-arm64.mk b/components/autofill_regexes.target.darwin-arm64.mk
index d99dfb8..5c525f3 100644
--- a/components/autofill_regexes.target.darwin-arm64.mk
+++ b/components/autofill_regexes.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "autofill_regexes":
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_regexes.target.darwin-mips.mk b/components/autofill_regexes.target.darwin-mips.mk
index d99dfb8..5c525f3 100644
--- a/components/autofill_regexes.target.darwin-mips.mk
+++ b/components/autofill_regexes.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "autofill_regexes":
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_regexes.target.darwin-x86.mk b/components/autofill_regexes.target.darwin-x86.mk
index d99dfb8..5c525f3 100644
--- a/components/autofill_regexes.target.darwin-x86.mk
+++ b/components/autofill_regexes.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "autofill_regexes":
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_regexes.target.darwin-x86_64.mk b/components/autofill_regexes.target.darwin-x86_64.mk
index d99dfb8..5c525f3 100644
--- a/components/autofill_regexes.target.darwin-x86_64.mk
+++ b/components/autofill_regexes.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "autofill_regexes":
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_regexes.target.linux-arm.mk b/components/autofill_regexes.target.linux-arm.mk
index d99dfb8..5c525f3 100644
--- a/components/autofill_regexes.target.linux-arm.mk
+++ b/components/autofill_regexes.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "autofill_regexes":
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_regexes.target.linux-arm64.mk b/components/autofill_regexes.target.linux-arm64.mk
index d99dfb8..5c525f3 100644
--- a/components/autofill_regexes.target.linux-arm64.mk
+++ b/components/autofill_regexes.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "autofill_regexes":
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_regexes.target.linux-mips.mk b/components/autofill_regexes.target.linux-mips.mk
index d99dfb8..5c525f3 100644
--- a/components/autofill_regexes.target.linux-mips.mk
+++ b/components/autofill_regexes.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "autofill_regexes":
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_regexes.target.linux-x86.mk b/components/autofill_regexes.target.linux-x86.mk
index d99dfb8..5c525f3 100644
--- a/components/autofill_regexes.target.linux-x86.mk
+++ b/components/autofill_regexes.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "autofill_regexes":
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/autofill_regexes.target.linux-x86_64.mk b/components/autofill_regexes.target.linux-x86_64.mk
index d99dfb8..5c525f3 100644
--- a/components/autofill_regexes.target.linux-x86_64.mk
+++ b/components/autofill_regexes.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "autofill_regexes":
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/autofill_regex_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/bookmarks.gypi b/components/bookmarks.gypi
index 74115dd..f056d62 100644
--- a/components/bookmarks.gypi
+++ b/components/bookmarks.gypi
@@ -27,6 +27,7 @@
       'sources': [
         'bookmarks/core/browser/base_bookmark_model_observer.cc',
         'bookmarks/core/browser/base_bookmark_model_observer.h',
+        'bookmarks/core/browser/bookmark_client.cc',
         'bookmarks/core/browser/bookmark_client.h',
         'bookmarks/core/browser/bookmark_codec.cc',
         'bookmarks/core/browser/bookmark_codec.h',
@@ -43,12 +44,11 @@
         'bookmarks/core/browser/bookmark_node.h',
         'bookmarks/core/browser/bookmark_node_data.cc',
         'bookmarks/core/browser/bookmark_node_data.h',
+        'bookmarks/core/browser/bookmark_node_data_ios.cc',
         'bookmarks/core/browser/bookmark_node_data_mac.cc',
         'bookmarks/core/browser/bookmark_node_data_views.cc',
         'bookmarks/core/browser/bookmark_pasteboard_helper_mac.h',
         'bookmarks/core/browser/bookmark_pasteboard_helper_mac.mm',
-        'bookmarks/core/browser/bookmark_prompt_prefs.cc',
-        'bookmarks/core/browser/bookmark_prompt_prefs.h',
         'bookmarks/core/browser/bookmark_service.h',
         'bookmarks/core/browser/bookmark_storage.cc',
         'bookmarks/core/browser/bookmark_storage.h',
@@ -57,14 +57,6 @@
         'bookmarks/core/browser/scoped_group_bookmark_actions.cc',
         'bookmarks/core/browser/scoped_group_bookmark_actions.h',
       ],
-      'conditions': [
-        ['OS=="android"', {
-          'sources!': [
-            'bookmarks/core/browser/scoped_group_bookmark_actions.cc',
-            'bookmarks/core/browser/scoped_group_bookmark_actions.h',
-          ],
-        }]
-      ],
     },
     {
       'target_name': 'bookmarks_core_common',
@@ -82,5 +74,23 @@
         'bookmarks/core/common/bookmark_pref_names.h',
       ],
     },
+    {
+      'target_name': 'bookmarks_core_test_support',
+      'type': 'static_library',
+      'include_dirs': [
+        '..',
+      ],
+      'dependencies': [
+        '../base/base.gyp:base',
+        '../url/url.gyp:url_lib',
+        'bookmarks_core_browser',
+      ],
+      'sources': [
+        'bookmarks/core/test/bookmark_test_helpers.cc',
+        'bookmarks/core/test/bookmark_test_helpers.h',
+        'bookmarks/core/test/test_bookmark_client.cc',
+        'bookmarks/core/test/test_bookmark_client.h',
+      ],
+    },
   ],
 }
diff --git a/components/bookmarks/DEPS b/components/bookmarks/DEPS
index 7b35635..3dcea05 100644
--- a/components/bookmarks/DEPS
+++ b/components/bookmarks/DEPS
@@ -1,7 +1,4 @@
 include_rules = [
-  # Bookmarks is a component that is not allowed to uses content/ so that it
-  # can be shared on iOS.
-  "-content",
   "+components/favicon_base",
   "+components/query_parser",
   "+components/startup_metric_utils",
diff --git a/components/bookmarks/core/browser/base_bookmark_model_observer.cc b/components/bookmarks/core/browser/base_bookmark_model_observer.cc
index 660b80b..a150c16 100644
--- a/components/bookmarks/core/browser/base_bookmark_model_observer.cc
+++ b/components/bookmarks/core/browser/base_bookmark_model_observer.cc
@@ -27,14 +27,18 @@
   BookmarkModelChanged();
 }
 
-void BaseBookmarkModelObserver::BookmarkNodeRemoved(BookmarkModel* model,
-                                                    const BookmarkNode* parent,
-                                                    int old_index,
-                                                    const BookmarkNode* node) {
+void BaseBookmarkModelObserver::BookmarkNodeRemoved(
+    BookmarkModel* model,
+    const BookmarkNode* parent,
+    int old_index,
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {
   BookmarkModelChanged();
 }
 
-void BaseBookmarkModelObserver::BookmarkAllNodesRemoved(BookmarkModel* model) {
+void BaseBookmarkModelObserver::BookmarkAllNodesRemoved(
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
   BookmarkModelChanged();
 }
 
diff --git a/components/bookmarks/core/browser/base_bookmark_model_observer.h b/components/bookmarks/core/browser/base_bookmark_model_observer.h
index 02453e6..a20394d 100644
--- a/components/bookmarks/core/browser/base_bookmark_model_observer.h
+++ b/components/bookmarks/core/browser/base_bookmark_model_observer.h
@@ -32,8 +32,11 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
   virtual void BookmarkNodeChanged(BookmarkModel* model,
                                    const BookmarkNode* node) OVERRIDE;
   virtual void BookmarkNodeFaviconChanged(BookmarkModel* model,
diff --git a/components/bookmarks/core/browser/bookmark_client.cc b/components/bookmarks/core/browser/bookmark_client.cc
new file mode 100644
index 0000000..03b1c5c
--- /dev/null
+++ b/components/bookmarks/core/browser/bookmark_client.cc
@@ -0,0 +1,26 @@
+// 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.
+
+#include "components/bookmarks/core/browser/bookmark_client.h"
+
+#include "base/logging.h"
+
+base::CancelableTaskTracker::TaskId BookmarkClient::GetFaviconImageForURL(
+    const GURL& page_url,
+    int icon_types,
+    int desired_size_in_dip,
+    const FaviconImageCallback& callback,
+    base::CancelableTaskTracker* tracker) {
+  return base::CancelableTaskTracker::kBadTaskId;
+}
+
+bool BookmarkClient::SupportsTypedCountForNodes() {
+  return false;
+}
+
+void BookmarkClient::GetTypedCountForNodes(
+    const NodeSet& nodes,
+    NodeTypedCountPairs* node_typed_count_pairs) {
+  NOTREACHED();
+}
diff --git a/components/bookmarks/core/browser/bookmark_client.h b/components/bookmarks/core/browser/bookmark_client.h
index 20e61b8..b4fc35e 100644
--- a/components/bookmarks/core/browser/bookmark_client.h
+++ b/components/bookmarks/core/browser/bookmark_client.h
@@ -37,6 +37,9 @@
   typedef std::pair<const BookmarkNode*, int> NodeTypedCountPair;
   typedef std::vector<NodeTypedCountPair> NodeTypedCountPairs;
 
+  // Returns true if the embedder favors touch icons over favicons.
+  virtual bool PreferTouchIcon() = 0;
+
   // Requests the favicon of any of |icon_types| whose pixel sizes most
   // closely match |desired_size_in_dip| (if value is 0, the largest favicon
   // is returned) and desired scale factor for |page_url|. |callback| is run
@@ -47,28 +50,21 @@
       int icon_types,
       int desired_size_in_dip,
       const FaviconImageCallback& callback,
-      base::CancelableTaskTracker* tracker) = 0;
+      base::CancelableTaskTracker* tracker);
 
   // Returns true if the embedder supports typed count for URL.
-  virtual bool SupportsTypedCountForNodes() = 0;
+  virtual bool SupportsTypedCountForNodes();
 
   // Retrieves the number of time each BookmarkNode URL has been typed in
   // the Omnibox by the user.
   virtual void GetTypedCountForNodes(
       const NodeSet& nodes,
-      NodeTypedCountPairs* node_typed_count_pairs) = 0;
+      NodeTypedCountPairs* node_typed_count_pairs);
 
   // Wrapper around RecordAction defined in base/metrics/user_metrics.h
   // that ensure that the action is posted from the correct thread.
   virtual void RecordAction(const base::UserMetricsAction& action) = 0;
 
-  // Notifies the history backend about urls of removed bookmarks.
-  // TODO(sdefresne): remove this method from the BookmarkClient (by having
-  // the client register itself as a BookmarkModelObserver if it is interested
-  // in the events), http://crbug.com/364433
-  virtual void NotifyHistoryAboutRemovedBookmarks(
-      const std::set<GURL>& removed_bookmark_urls) = 0;
-
  protected:
   virtual ~BookmarkClient() {}
 };
diff --git a/components/bookmarks/core/browser/bookmark_codec.cc b/components/bookmarks/core/browser/bookmark_codec.cc
index 77357af..bbf8aa5 100644
--- a/components/bookmarks/core/browser/bookmark_codec.cc
+++ b/components/bookmarks/core/browser/bookmark_codec.cc
@@ -464,7 +464,7 @@
 void BookmarkCodec::UpdateChecksumWithUrlNode(const std::string& id,
                                               const base::string16& title,
                                               const std::string& url) {
-  DCHECK(IsStringUTF8(url));
+  DCHECK(base::IsStringUTF8(url));
   UpdateChecksum(id);
   UpdateChecksum(title);
   UpdateChecksum(kTypeURL);
diff --git a/components/bookmarks/core/browser/bookmark_codec_unittest.cc b/components/bookmarks/core/browser/bookmark_codec_unittest.cc
new file mode 100644
index 0000000..4321eb9
--- /dev/null
+++ b/components/bookmarks/core/browser/bookmark_codec_unittest.cc
@@ -0,0 +1,475 @@
+// 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.
+
+#include "components/bookmarks/core/browser/bookmark_codec.h"
+
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/json/json_file_value_serializer.h"
+#include "base/json/json_string_value_serializer.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/path_service.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/test_bookmark_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::ASCIIToUTF16;
+
+namespace {
+
+const char kUrl1Title[] = "url1";
+const char kUrl1Url[] = "http://www.url1.com";
+const char kUrl2Title[] = "url2";
+const char kUrl2Url[] = "http://www.url2.com";
+const char kUrl3Title[] = "url3";
+const char kUrl3Url[] = "http://www.url3.com";
+const char kUrl4Title[] = "url4";
+const char kUrl4Url[] = "http://www.url4.com";
+const char kFolder1Title[] = "folder1";
+const char kFolder2Title[] = "folder2";
+
+const base::FilePath& GetTestDataDir() {
+  CR_DEFINE_STATIC_LOCAL(base::FilePath, dir, ());
+  if (dir.empty()) {
+    PathService::Get(base::DIR_SOURCE_ROOT, &dir);
+    dir = dir.AppendASCII("components");
+    dir = dir.AppendASCII("test");
+    dir = dir.AppendASCII("data");
+  }
+  return dir;
+}
+
+// Helper to get a mutable bookmark node.
+BookmarkNode* AsMutable(const BookmarkNode* node) {
+  return const_cast<BookmarkNode*>(node);
+}
+
+// Helper to verify the two given bookmark nodes.
+void AssertNodesEqual(const BookmarkNode* expected,
+                      const BookmarkNode* actual) {
+  ASSERT_TRUE(expected);
+  ASSERT_TRUE(actual);
+  EXPECT_EQ(expected->id(), actual->id());
+  EXPECT_EQ(expected->GetTitle(), actual->GetTitle());
+  EXPECT_EQ(expected->type(), actual->type());
+  EXPECT_TRUE(expected->date_added() == actual->date_added());
+  if (expected->is_url()) {
+    EXPECT_EQ(expected->url(), actual->url());
+  } else {
+    EXPECT_TRUE(expected->date_folder_modified() ==
+                actual->date_folder_modified());
+    ASSERT_EQ(expected->child_count(), actual->child_count());
+    for (int i = 0; i < expected->child_count(); ++i)
+      AssertNodesEqual(expected->GetChild(i), actual->GetChild(i));
+  }
+}
+
+// Verifies that the two given bookmark models are the same.
+void AssertModelsEqual(BookmarkModel* expected, BookmarkModel* actual) {
+  ASSERT_NO_FATAL_FAILURE(AssertNodesEqual(expected->bookmark_bar_node(),
+                                           actual->bookmark_bar_node()));
+  ASSERT_NO_FATAL_FAILURE(
+      AssertNodesEqual(expected->other_node(), actual->other_node()));
+  ASSERT_NO_FATAL_FAILURE(
+      AssertNodesEqual(expected->mobile_node(), actual->mobile_node()));
+}
+
+}  // namespace
+
+class BookmarkCodecTest : public testing::Test {
+ protected:
+  // Helpers to create bookmark models with different data.
+  BookmarkModel* CreateTestModel1() {
+    scoped_ptr<BookmarkModel> model(client_.CreateModel(false));
+    const BookmarkNode* bookmark_bar = model->bookmark_bar_node();
+    model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url));
+    return model.release();
+  }
+  BookmarkModel* CreateTestModel2() {
+    scoped_ptr<BookmarkModel> model(client_.CreateModel(false));
+    const BookmarkNode* bookmark_bar = model->bookmark_bar_node();
+    model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url));
+    model->AddURL(bookmark_bar, 1, ASCIIToUTF16(kUrl2Title), GURL(kUrl2Url));
+    return model.release();
+  }
+  BookmarkModel* CreateTestModel3() {
+    scoped_ptr<BookmarkModel> model(client_.CreateModel(false));
+    const BookmarkNode* bookmark_bar = model->bookmark_bar_node();
+    model->AddURL(bookmark_bar, 0, ASCIIToUTF16(kUrl1Title), GURL(kUrl1Url));
+    const BookmarkNode* folder1 =
+        model->AddFolder(bookmark_bar, 1, ASCIIToUTF16(kFolder1Title));
+    model->AddURL(folder1, 0, ASCIIToUTF16(kUrl2Title), GURL(kUrl2Url));
+    return model.release();
+  }
+
+  void GetBookmarksBarChildValue(base::Value* value,
+                                 size_t index,
+                                 base::DictionaryValue** result_value) {
+    ASSERT_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
+
+    base::DictionaryValue* d_value = static_cast<base::DictionaryValue*>(value);
+    base::Value* roots;
+    ASSERT_TRUE(d_value->Get(BookmarkCodec::kRootsKey, &roots));
+    ASSERT_EQ(base::Value::TYPE_DICTIONARY, roots->GetType());
+
+    base::DictionaryValue* roots_d_value =
+        static_cast<base::DictionaryValue*>(roots);
+    base::Value* bb_value;
+    ASSERT_TRUE(
+        roots_d_value->Get(BookmarkCodec::kRootFolderNameKey, &bb_value));
+    ASSERT_EQ(base::Value::TYPE_DICTIONARY, bb_value->GetType());
+
+    base::DictionaryValue* bb_d_value =
+        static_cast<base::DictionaryValue*>(bb_value);
+    base::Value* bb_children_value;
+    ASSERT_TRUE(
+        bb_d_value->Get(BookmarkCodec::kChildrenKey, &bb_children_value));
+    ASSERT_EQ(base::Value::TYPE_LIST, bb_children_value->GetType());
+
+    base::ListValue* bb_children_l_value =
+        static_cast<base::ListValue*>(bb_children_value);
+    base::Value* child_value;
+    ASSERT_TRUE(bb_children_l_value->Get(index, &child_value));
+    ASSERT_EQ(base::Value::TYPE_DICTIONARY, child_value->GetType());
+
+    *result_value = static_cast<base::DictionaryValue*>(child_value);
+  }
+
+  base::Value* EncodeHelper(BookmarkModel* model, std::string* checksum) {
+    BookmarkCodec encoder;
+    // Computed and stored checksums should be empty.
+    EXPECT_EQ("", encoder.computed_checksum());
+    EXPECT_EQ("", encoder.stored_checksum());
+
+    scoped_ptr<base::Value> value(encoder.Encode(model));
+    const std::string& computed_checksum = encoder.computed_checksum();
+    const std::string& stored_checksum = encoder.stored_checksum();
+
+    // Computed and stored checksums should not be empty and should be equal.
+    EXPECT_FALSE(computed_checksum.empty());
+    EXPECT_FALSE(stored_checksum.empty());
+    EXPECT_EQ(computed_checksum, stored_checksum);
+
+    *checksum = computed_checksum;
+    return value.release();
+  }
+
+  bool Decode(BookmarkCodec* codec,
+              BookmarkModel* model,
+              const base::Value& value) {
+    int64 max_id;
+    bool result = codec->Decode(AsMutable(model->bookmark_bar_node()),
+                                AsMutable(model->other_node()),
+                                AsMutable(model->mobile_node()),
+                                &max_id,
+                                value);
+    model->set_next_node_id(max_id);
+    AsMutable(model->root_node())->SetMetaInfoMap(codec->model_meta_info_map());
+    AsMutable(model->root_node())
+        ->set_sync_transaction_version(codec->model_sync_transaction_version());
+
+    return result;
+  }
+
+  BookmarkModel* DecodeHelper(const base::Value& value,
+                              const std::string& expected_stored_checksum,
+                              std::string* computed_checksum,
+                              bool expected_changes) {
+    BookmarkCodec decoder;
+    // Computed and stored checksums should be empty.
+    EXPECT_EQ("", decoder.computed_checksum());
+    EXPECT_EQ("", decoder.stored_checksum());
+
+    scoped_ptr<BookmarkModel> model(client_.CreateModel(false));
+    EXPECT_TRUE(Decode(&decoder, model.get(), value));
+
+    *computed_checksum = decoder.computed_checksum();
+    const std::string& stored_checksum = decoder.stored_checksum();
+
+    // Computed and stored checksums should not be empty.
+    EXPECT_FALSE(computed_checksum->empty());
+    EXPECT_FALSE(stored_checksum.empty());
+
+    // Stored checksum should be as expected.
+    EXPECT_EQ(expected_stored_checksum, stored_checksum);
+
+    // The two checksums should be equal if expected_changes is true; otherwise
+    // they should be different.
+    if (expected_changes)
+      EXPECT_NE(*computed_checksum, stored_checksum);
+    else
+      EXPECT_EQ(*computed_checksum, stored_checksum);
+
+    return model.release();
+  }
+
+  void CheckIDs(const BookmarkNode* node, std::set<int64>* assigned_ids) {
+    DCHECK(node);
+    int64 node_id = node->id();
+    EXPECT_TRUE(assigned_ids->find(node_id) == assigned_ids->end());
+    assigned_ids->insert(node_id);
+    for (int i = 0; i < node->child_count(); ++i)
+      CheckIDs(node->GetChild(i), assigned_ids);
+  }
+
+  void ExpectIDsUnique(BookmarkModel* model) {
+    std::set<int64> assigned_ids;
+    CheckIDs(model->bookmark_bar_node(), &assigned_ids);
+    CheckIDs(model->other_node(), &assigned_ids);
+    CheckIDs(model->mobile_node(), &assigned_ids);
+  }
+
+  test::TestBookmarkClient client_;
+};
+
+TEST_F(BookmarkCodecTest, ChecksumEncodeDecodeTest) {
+  scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel1());
+  std::string enc_checksum;
+  scoped_ptr<base::Value> value(
+      EncodeHelper(model_to_encode.get(), &enc_checksum));
+
+  EXPECT_TRUE(value.get() != NULL);
+
+  std::string dec_checksum;
+  scoped_ptr<BookmarkModel> decoded_model(
+      DecodeHelper(*value.get(), enc_checksum, &dec_checksum, false));
+}
+
+TEST_F(BookmarkCodecTest, ChecksumEncodeIdenticalModelsTest) {
+  // Encode two identical models and make sure the check-sums are same as long
+  // as the data is the same.
+  scoped_ptr<BookmarkModel> model1(CreateTestModel1());
+  std::string enc_checksum1;
+  scoped_ptr<base::Value> value1(EncodeHelper(model1.get(), &enc_checksum1));
+  EXPECT_TRUE(value1.get() != NULL);
+
+  scoped_ptr<BookmarkModel> model2(CreateTestModel1());
+  std::string enc_checksum2;
+  scoped_ptr<base::Value> value2(EncodeHelper(model2.get(), &enc_checksum2));
+  EXPECT_TRUE(value2.get() != NULL);
+
+  ASSERT_EQ(enc_checksum1, enc_checksum2);
+}
+
+TEST_F(BookmarkCodecTest, ChecksumManualEditTest) {
+  scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel1());
+  std::string enc_checksum;
+  scoped_ptr<base::Value> value(
+      EncodeHelper(model_to_encode.get(), &enc_checksum));
+
+  EXPECT_TRUE(value.get() != NULL);
+
+  // Change something in the encoded value before decoding it.
+  base::DictionaryValue* child1_value;
+  GetBookmarksBarChildValue(value.get(), 0, &child1_value);
+  std::string title;
+  ASSERT_TRUE(child1_value->GetString(BookmarkCodec::kNameKey, &title));
+  child1_value->SetString(BookmarkCodec::kNameKey, title + "1");
+
+  std::string dec_checksum;
+  scoped_ptr<BookmarkModel> decoded_model1(
+      DecodeHelper(*value.get(), enc_checksum, &dec_checksum, true));
+
+  // Undo the change and make sure the checksum is same as original.
+  child1_value->SetString(BookmarkCodec::kNameKey, title);
+  scoped_ptr<BookmarkModel> decoded_model2(
+      DecodeHelper(*value.get(), enc_checksum, &dec_checksum, false));
+}
+
+TEST_F(BookmarkCodecTest, ChecksumManualEditIDsTest) {
+  scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel3());
+
+  // The test depends on existence of multiple children under bookmark bar, so
+  // make sure that's the case.
+  int bb_child_count = model_to_encode->bookmark_bar_node()->child_count();
+  ASSERT_GT(bb_child_count, 1);
+
+  std::string enc_checksum;
+  scoped_ptr<base::Value> value(
+      EncodeHelper(model_to_encode.get(), &enc_checksum));
+
+  EXPECT_TRUE(value.get() != NULL);
+
+  // Change IDs for all children of bookmark bar to be 1.
+  base::DictionaryValue* child_value;
+  for (int i = 0; i < bb_child_count; ++i) {
+    GetBookmarksBarChildValue(value.get(), i, &child_value);
+    std::string id;
+    ASSERT_TRUE(child_value->GetString(BookmarkCodec::kIdKey, &id));
+    child_value->SetString(BookmarkCodec::kIdKey, "1");
+  }
+
+  std::string dec_checksum;
+  scoped_ptr<BookmarkModel> decoded_model(
+      DecodeHelper(*value.get(), enc_checksum, &dec_checksum, true));
+
+  ExpectIDsUnique(decoded_model.get());
+
+  // add a few extra nodes to bookmark model and make sure IDs are still uniuqe.
+  const BookmarkNode* bb_node = decoded_model->bookmark_bar_node();
+  decoded_model->AddURL(
+      bb_node, 0, ASCIIToUTF16("new url1"), GURL("http://newurl1.com"));
+  decoded_model->AddURL(
+      bb_node, 0, ASCIIToUTF16("new url2"), GURL("http://newurl2.com"));
+
+  ExpectIDsUnique(decoded_model.get());
+}
+
+TEST_F(BookmarkCodecTest, PersistIDsTest) {
+  scoped_ptr<BookmarkModel> model_to_encode(CreateTestModel3());
+  BookmarkCodec encoder;
+  scoped_ptr<base::Value> model_value(encoder.Encode(model_to_encode.get()));
+
+  scoped_ptr<BookmarkModel> decoded_model(client_.CreateModel(false));
+  BookmarkCodec decoder;
+  ASSERT_TRUE(Decode(&decoder, decoded_model.get(), *model_value.get()));
+  ASSERT_NO_FATAL_FAILURE(
+      AssertModelsEqual(model_to_encode.get(), decoded_model.get()));
+
+  // Add a couple of more items to the decoded bookmark model and make sure
+  // ID persistence is working properly.
+  const BookmarkNode* bookmark_bar = decoded_model->bookmark_bar_node();
+  decoded_model->AddURL(bookmark_bar,
+                        bookmark_bar->child_count(),
+                        ASCIIToUTF16(kUrl3Title),
+                        GURL(kUrl3Url));
+  const BookmarkNode* folder2_node = decoded_model->AddFolder(
+      bookmark_bar, bookmark_bar->child_count(), ASCIIToUTF16(kFolder2Title));
+  decoded_model->AddURL(
+      folder2_node, 0, ASCIIToUTF16(kUrl4Title), GURL(kUrl4Url));
+
+  BookmarkCodec encoder2;
+  scoped_ptr<base::Value> model_value2(encoder2.Encode(decoded_model.get()));
+
+  scoped_ptr<BookmarkModel> decoded_model2(client_.CreateModel(false));
+  BookmarkCodec decoder2;
+  ASSERT_TRUE(Decode(&decoder2, decoded_model2.get(), *model_value2.get()));
+  ASSERT_NO_FATAL_FAILURE(
+      AssertModelsEqual(decoded_model.get(), decoded_model2.get()));
+}
+
+TEST_F(BookmarkCodecTest, CanDecodeModelWithoutMobileBookmarks) {
+  base::FilePath test_data_directory;
+  base::FilePath test_file =
+      GetTestDataDir().AppendASCII("bookmarks/model_without_sync.json");
+  ASSERT_TRUE(base::PathExists(test_file));
+
+  JSONFileValueSerializer serializer(test_file);
+  scoped_ptr<base::Value> root(serializer.Deserialize(NULL, NULL));
+
+  scoped_ptr<BookmarkModel> decoded_model(client_.CreateModel(false));
+  BookmarkCodec decoder;
+  ASSERT_TRUE(Decode(&decoder, decoded_model.get(), *root.get()));
+  ExpectIDsUnique(decoded_model.get());
+
+  const BookmarkNode* bbn = decoded_model->bookmark_bar_node();
+  ASSERT_EQ(1, bbn->child_count());
+
+  const BookmarkNode* child = bbn->GetChild(0);
+  EXPECT_EQ(BookmarkNode::FOLDER, child->type());
+  EXPECT_EQ(ASCIIToUTF16("Folder A"), child->GetTitle());
+  ASSERT_EQ(1, child->child_count());
+
+  child = child->GetChild(0);
+  EXPECT_EQ(BookmarkNode::URL, child->type());
+  EXPECT_EQ(ASCIIToUTF16("Bookmark Manager"), child->GetTitle());
+
+  const BookmarkNode* other = decoded_model->other_node();
+  ASSERT_EQ(1, other->child_count());
+
+  child = other->GetChild(0);
+  EXPECT_EQ(BookmarkNode::FOLDER, child->type());
+  EXPECT_EQ(ASCIIToUTF16("Folder B"), child->GetTitle());
+  ASSERT_EQ(1, child->child_count());
+
+  child = child->GetChild(0);
+  EXPECT_EQ(BookmarkNode::URL, child->type());
+  EXPECT_EQ(ASCIIToUTF16("Get started with Google Chrome"), child->GetTitle());
+
+  ASSERT_TRUE(decoded_model->mobile_node() != NULL);
+}
+
+TEST_F(BookmarkCodecTest, EncodeAndDecodeMetaInfo) {
+  // Add meta info and encode.
+  scoped_ptr<BookmarkModel> model(CreateTestModel1());
+  model->SetNodeMetaInfo(model->root_node(), "model_info", "value1");
+  model->SetNodeMetaInfo(
+      model->bookmark_bar_node()->GetChild(0), "node_info", "value2");
+  std::string checksum;
+  scoped_ptr<base::Value> value(EncodeHelper(model.get(), &checksum));
+  ASSERT_TRUE(value.get() != NULL);
+
+  // Decode and check for meta info.
+  model.reset(DecodeHelper(*value, checksum, &checksum, false));
+  std::string meta_value;
+  EXPECT_TRUE(model->root_node()->GetMetaInfo("model_info", &meta_value));
+  EXPECT_EQ("value1", meta_value);
+  EXPECT_FALSE(model->root_node()->GetMetaInfo("other_key", &meta_value));
+  const BookmarkNode* bbn = model->bookmark_bar_node();
+  ASSERT_EQ(1, bbn->child_count());
+  const BookmarkNode* child = bbn->GetChild(0);
+  EXPECT_TRUE(child->GetMetaInfo("node_info", &meta_value));
+  EXPECT_EQ("value2", meta_value);
+  EXPECT_FALSE(child->GetMetaInfo("other_key", &meta_value));
+}
+
+TEST_F(BookmarkCodecTest, EncodeAndDecodeSyncTransactionVersion) {
+  // Add sync transaction version and encode.
+  scoped_ptr<BookmarkModel> model(CreateTestModel2());
+  model->SetNodeSyncTransactionVersion(model->root_node(), 1);
+  const BookmarkNode* bbn = model->bookmark_bar_node();
+  model->SetNodeSyncTransactionVersion(bbn->GetChild(1), 42);
+
+  std::string checksum;
+  scoped_ptr<base::Value> value(EncodeHelper(model.get(), &checksum));
+  ASSERT_TRUE(value.get() != NULL);
+
+  // Decode and verify.
+  model.reset(DecodeHelper(*value, checksum, &checksum, false));
+  EXPECT_EQ(1, model->root_node()->sync_transaction_version());
+  bbn = model->bookmark_bar_node();
+  EXPECT_EQ(42, bbn->GetChild(1)->sync_transaction_version());
+  EXPECT_EQ(BookmarkNode::kInvalidSyncTransactionVersion,
+            bbn->GetChild(0)->sync_transaction_version());
+}
+
+// Verifies that we can still decode the old codec format after changing the
+// way meta info is stored.
+TEST_F(BookmarkCodecTest, CanDecodeMetaInfoAsString) {
+  base::FilePath test_data_directory;
+  base::FilePath test_file =
+      GetTestDataDir().AppendASCII("bookmarks/meta_info_as_string.json");
+  ASSERT_TRUE(base::PathExists(test_file));
+
+  JSONFileValueSerializer serializer(test_file);
+  scoped_ptr<base::Value> root(serializer.Deserialize(NULL, NULL));
+
+  scoped_ptr<BookmarkModel> model(client_.CreateModel(false));
+  BookmarkCodec decoder;
+  ASSERT_TRUE(Decode(&decoder, model.get(), *root.get()));
+
+  EXPECT_EQ(1, model->root_node()->sync_transaction_version());
+  const BookmarkNode* bbn = model->bookmark_bar_node();
+  EXPECT_EQ(BookmarkNode::kInvalidSyncTransactionVersion,
+            bbn->GetChild(0)->sync_transaction_version());
+  EXPECT_EQ(42, bbn->GetChild(1)->sync_transaction_version());
+
+  const char kSyncTransactionVersionKey[] = "sync.transaction_version";
+  const char kNormalKey[] = "key";
+  const char kNestedKey[] = "nested.key";
+  std::string meta_value;
+  EXPECT_FALSE(
+      model->root_node()->GetMetaInfo(kSyncTransactionVersionKey, &meta_value));
+  EXPECT_FALSE(
+      bbn->GetChild(1)->GetMetaInfo(kSyncTransactionVersionKey, &meta_value));
+  EXPECT_TRUE(bbn->GetChild(0)->GetMetaInfo(kNormalKey, &meta_value));
+  EXPECT_EQ("value", meta_value);
+  EXPECT_TRUE(bbn->GetChild(1)->GetMetaInfo(kNormalKey, &meta_value));
+  EXPECT_EQ("value2", meta_value);
+  EXPECT_TRUE(bbn->GetChild(0)->GetMetaInfo(kNestedKey, &meta_value));
+  EXPECT_EQ("value3", meta_value);
+}
diff --git a/components/bookmarks/core/browser/bookmark_expanded_state_tracker.cc b/components/bookmarks/core/browser/bookmark_expanded_state_tracker.cc
index daeccc4..2a7bf34 100644
--- a/components/bookmarks/core/browser/bookmark_expanded_state_tracker.cc
+++ b/components/bookmarks/core/browser/bookmark_expanded_state_tracker.cc
@@ -80,7 +80,8 @@
     BookmarkModel* model,
     const BookmarkNode* parent,
     int old_index,
-    const BookmarkNode* node) {
+    const BookmarkNode* node,
+    const std::set<GURL>& removed_urls) {
   if (!node->is_folder())
     return;  // Only care about folders.
 
@@ -89,7 +90,8 @@
 }
 
 void BookmarkExpandedStateTracker::BookmarkAllNodesRemoved(
-    BookmarkModel* model) {
+    BookmarkModel* model,
+    const std::set<GURL>& removed_urls) {
   // Ask for the nodes again, which removes any nodes that were deleted.
   GetExpandedNodes();
 }
diff --git a/components/bookmarks/core/browser/bookmark_expanded_state_tracker.h b/components/bookmarks/core/browser/bookmark_expanded_state_tracker.h
index 2077572..77d3391 100644
--- a/components/bookmarks/core/browser/bookmark_expanded_state_tracker.h
+++ b/components/bookmarks/core/browser/bookmark_expanded_state_tracker.h
@@ -37,8 +37,11 @@
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) OVERRIDE;
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) OVERRIDE;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) OVERRIDE;
+  virtual void BookmarkAllNodesRemoved(
+      BookmarkModel* model,
+      const std::set<GURL>& removed_urls) OVERRIDE;
 
   // Updates the value for |prefs::kBookmarkEditorExpandedNodes| from
   // GetExpandedNodes().
diff --git a/components/bookmarks/core/browser/bookmark_model.cc b/components/bookmarks/core/browser/bookmark_model.cc
index 4a0bdb8..db0274a 100644
--- a/components/bookmarks/core/browser/bookmark_model.cc
+++ b/components/bookmarks/core/browser/bookmark_model.cc
@@ -193,13 +193,8 @@
   if (store_.get())
     store_->ScheduleSave();
 
-  // TODO(sdefresne): remove this method from the BookmarkClient (by having
-  // the client register itself as a BookmarkModelObserver if it is interested
-  // in the events), http://crbug.com/364433
-  client_->NotifyHistoryAboutRemovedBookmarks(removed_urls);
-
   FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
-                    BookmarkAllNodesRemoved(this));
+                    BookmarkAllNodesRemoved(this, removed_urls));
 }
 
 void BookmarkModel::Move(const BookmarkNode* node,
@@ -271,12 +266,20 @@
   DCHECK(node);
   if (node->favicon_state() == BookmarkNode::INVALID_FAVICON) {
     BookmarkNode* mutable_node = AsMutable(node);
-    mutable_node->set_favicon_state(BookmarkNode::LOADING_FAVICON);
-    LoadFavicon(mutable_node);
+    LoadFavicon(
+        mutable_node,
+        client_->PreferTouchIcon() ?
+            favicon_base::TOUCH_ICON :
+            favicon_base::FAVICON);
   }
   return node->favicon();
 }
 
+favicon_base::IconType BookmarkModel::GetFaviconType(const BookmarkNode* node) {
+  DCHECK(node);
+  return node->favicon_type();
+}
+
 void BookmarkModel::SetTitle(const BookmarkNode* node,
                              const base::string16& title) {
   if (!node) {
@@ -764,13 +767,10 @@
   if (store_.get())
     store_->ScheduleSave();
 
-  // TODO(sdefresne): remove this method from the BookmarkClient (by having
-  // the client register itself as a BookmarkModelObserver if it is interested
-  // in the events), http://crbug.com/364433
-  client_->NotifyHistoryAboutRemovedBookmarks(removed_urls);
-
-  FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
-                    BookmarkNodeRemoved(this, parent, index, node.get()));
+  FOR_EACH_OBSERVER(
+      BookmarkModelObserver,
+      observers_,
+      BookmarkNodeRemoved(this, parent, index, node.get(), removed_urls));
 }
 
 void BookmarkModel::RemoveNodeFromURLSet(BookmarkNode* node) {
@@ -868,28 +868,40 @@
 
 void BookmarkModel::OnFaviconDataAvailable(
     BookmarkNode* node,
+    favicon_base::IconType icon_type,
     const favicon_base::FaviconImageResult& image_result) {
   DCHECK(node);
   node->set_favicon_load_task_id(base::CancelableTaskTracker::kBadTaskId);
   node->set_favicon_state(BookmarkNode::LOADED_FAVICON);
   if (!image_result.image.IsEmpty()) {
+    node->set_favicon_type(icon_type);
     node->set_favicon(image_result.image);
     node->set_icon_url(image_result.icon_url);
     FaviconLoaded(node);
+  } else if (icon_type == favicon_base::TOUCH_ICON) {
+    // Couldn't load the touch icon, fallback to the regular favicon.
+    DCHECK(client_->PreferTouchIcon());
+    LoadFavicon(node, favicon_base::FAVICON);
   }
 }
 
-void BookmarkModel::LoadFavicon(BookmarkNode* node) {
+void BookmarkModel::LoadFavicon(
+    BookmarkNode* node,
+    favicon_base::IconType icon_type) {
   if (node->is_folder())
     return;
 
   DCHECK(node->url().is_valid());
+  node->set_favicon_state(BookmarkNode::LOADING_FAVICON);
   base::CancelableTaskTracker::TaskId taskId = client_->GetFaviconImageForURL(
       node->url(),
-      favicon_base::FAVICON,
-      gfx::kFaviconSize,
+      icon_type,
+      icon_type == favicon_base::FAVICON ? gfx::kFaviconSize : 0,
       base::Bind(
-          &BookmarkModel::OnFaviconDataAvailable, base::Unretained(this), node),
+          &BookmarkModel::OnFaviconDataAvailable,
+          base::Unretained(this),
+          node,
+          icon_type),
       &cancelable_task_tracker_);
   if (taskId != base::CancelableTaskTracker::kBadTaskId)
     node->set_favicon_load_task_id(taskId);
diff --git a/components/bookmarks/core/browser/bookmark_model.h b/components/bookmarks/core/browser/bookmark_model.h
index 5f51c4b..4c4a313 100644
--- a/components/bookmarks/core/browser/bookmark_model.h
+++ b/components/bookmarks/core/browser/bookmark_model.h
@@ -144,6 +144,10 @@
   // loaded it is loaded and the observer of the model notified when done.
   const gfx::Image& GetFavicon(const BookmarkNode* node);
 
+  // Returns the type of the favicon for |node|. If the favicon has not yet
+  // been loaded, it returns |favicon_base::INVALID_ICON|.
+  favicon_base::IconType GetFaviconType(const BookmarkNode* node);
+
   // Sets the title of |node|.
   void SetTitle(const BookmarkNode* node, const base::string16& title);
 
@@ -332,11 +336,12 @@
   // favicon, FaviconLoaded is invoked.
   void OnFaviconDataAvailable(
       BookmarkNode* node,
+      favicon_base::IconType icon_type,
       const favicon_base::FaviconImageResult& image_result);
 
   // Invoked from the node to load the favicon. Requests the favicon from the
   // favicon service.
-  void LoadFavicon(BookmarkNode* node);
+  void LoadFavicon(BookmarkNode* node, favicon_base::IconType icon_type);
 
   // Called to notify the observers that the favicon has been loaded.
   void FaviconLoaded(const BookmarkNode* node);
diff --git a/components/bookmarks/core/browser/bookmark_model_observer.h b/components/bookmarks/core/browser/bookmark_model_observer.h
index 32bca85..2377ae4 100644
--- a/components/bookmarks/core/browser/bookmark_model_observer.h
+++ b/components/bookmarks/core/browser/bookmark_model_observer.h
@@ -5,8 +5,11 @@
 #ifndef COMPONENTS_BOOKMARKS_CORE_BROWSER_BOOKMARK_MODEL_OBSERVER_H_
 #define COMPONENTS_BOOKMARKS_CORE_BROWSER_BOOKMARK_MODEL_OBSERVER_H_
 
+#include <set>
+
 class BookmarkModel;
 class BookmarkNode;
+class GURL;
 
 // Observer for the BookmarkModel.
 class BookmarkModelObserver {
@@ -45,10 +48,13 @@
   // |old_index| the index of the removed node in |parent| before it was
   // removed.
   // |node| is the node that was removed.
+  // |removed_urls| is populated with the urls which no longer have any
+  // bookmarks associated with them.
   virtual void BookmarkNodeRemoved(BookmarkModel* model,
                                    const BookmarkNode* parent,
                                    int old_index,
-                                   const BookmarkNode* node) = 0;
+                                   const BookmarkNode* node,
+                                   const std::set<GURL>& removed_urls) = 0;
 
   // Invoked before the title or url of a node is changed.
   virtual void OnWillChangeBookmarkNode(BookmarkModel* model,
@@ -97,7 +103,10 @@
   virtual void OnWillRemoveAllBookmarks(BookmarkModel* model) {}
 
   // Invoked when all non-permanent bookmark nodes have been removed.
-  virtual void BookmarkAllNodesRemoved(BookmarkModel* model) = 0;
+  // |removed_urls| is populated with the urls which no longer have any
+  // bookmarks associated with them.
+  virtual void BookmarkAllNodesRemoved(BookmarkModel* model,
+                                       const std::set<GURL>& removed_urls) = 0;
 
   // Invoked before a set of model changes that is initiated by a single user
   // action. For example, this is called a single time when pasting from the
diff --git a/components/bookmarks/core/browser/bookmark_node.cc b/components/bookmarks/core/browser/bookmark_node.cc
index 6d178c0..13246c0 100644
--- a/components/bookmarks/core/browser/bookmark_node.cc
+++ b/components/bookmarks/core/browser/bookmark_node.cc
@@ -103,6 +103,7 @@
   id_ = id;
   type_ = url_.is_empty() ? FOLDER : URL;
   date_added_ = base::Time::Now();
+  favicon_type_ = favicon_base::INVALID_ICON;
   favicon_state_ = INVALID_FAVICON;
   favicon_load_task_id_ = base::CancelableTaskTracker::kBadTaskId;
   meta_info_map_.reset();
@@ -112,6 +113,7 @@
 void BookmarkNode::InvalidateFavicon() {
   icon_url_ = GURL();
   favicon_ = gfx::Image();
+  favicon_type_ = favicon_base::INVALID_ICON;
   favicon_state_ = INVALID_FAVICON;
 }
 
diff --git a/components/bookmarks/core/browser/bookmark_node.h b/components/bookmarks/core/browser/bookmark_node.h
index d4246d0..6ed275b 100644
--- a/components/bookmarks/core/browser/bookmark_node.h
+++ b/components/bookmarks/core/browser/bookmark_node.h
@@ -8,6 +8,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/task/cancelable_task_tracker.h"
 #include "base/time/time.h"
+#include "components/favicon_base/favicon_types.h"
 #include "ui/base/models/tree_node_model.h"
 #include "ui/gfx/image/image.h"
 #include "url/gurl.h"
@@ -127,9 +128,15 @@
     icon_url_ = icon_url;
   }
 
+  // Returns the favicon. In nearly all cases you should use the method
+  // BookmarkModel::GetFavicon rather than this one as it takes care of
+  // loading the favicon if it isn't already loaded.
   const gfx::Image& favicon() const { return favicon_; }
   void set_favicon(const gfx::Image& icon) { favicon_ = icon; }
 
+  favicon_base::IconType favicon_type() const { return favicon_type_; }
+  void set_favicon_type(favicon_base::IconType type) { favicon_type_ = type; }
+
   FaviconState favicon_state() const { return favicon_state_; }
   void set_favicon_state(FaviconState state) { favicon_state_ = state; }
 
@@ -159,6 +166,9 @@
   // The favicon of this node.
   gfx::Image favicon_;
 
+  // The type of favicon currently loaded.
+  favicon_base::IconType favicon_type_;
+
   // The URL of the node's favicon.
   GURL icon_url_;
 
diff --git a/components/bookmarks/core/browser/bookmark_node_data_ios.cc b/components/bookmarks/core/browser/bookmark_node_data_ios.cc
new file mode 100644
index 0000000..861b2eb
--- /dev/null
+++ b/components/bookmarks/core/browser/bookmark_node_data_ios.cc
@@ -0,0 +1,22 @@
+// 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.
+
+#include "components/bookmarks/core/browser/bookmark_node_data.h"
+
+#include "base/logging.h"
+
+// static
+bool BookmarkNodeData::ClipboardContainsBookmarks() {
+  NOTREACHED();
+  return false;
+}
+
+void BookmarkNodeData::WriteToClipboard(ui::ClipboardType type) {
+  NOTREACHED();
+}
+
+bool BookmarkNodeData::ReadFromClipboard(ui::ClipboardType type) {
+  NOTREACHED();
+  return false;
+}
diff --git a/components/bookmarks/core/browser/bookmark_prompt_prefs.cc b/components/bookmarks/core/browser/bookmark_prompt_prefs.cc
deleted file mode 100644
index 9e3de77..0000000
--- a/components/bookmarks/core/browser/bookmark_prompt_prefs.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.
-
-#include "components/bookmarks/core/browser/bookmark_prompt_prefs.h"
-
-#include "base/prefs/pref_service.h"
-#include "components/bookmarks/core/common/bookmark_pref_names.h"
-#include "components/user_prefs/pref_registry_syncable.h"
-
-BookmarkPromptPrefs::BookmarkPromptPrefs(PrefService* user_prefs)
-    : prefs_(user_prefs) {
-}
-
-BookmarkPromptPrefs::~BookmarkPromptPrefs() {
-}
-
-void BookmarkPromptPrefs::DisableBookmarkPrompt() {
-  prefs_->SetBoolean(prefs::kBookmarkPromptEnabled, false);
-}
-
-int BookmarkPromptPrefs::GetPromptImpressionCount() const {
-  return prefs_->GetInteger(prefs::kBookmarkPromptImpressionCount);
-}
-
-void BookmarkPromptPrefs::IncrementPromptImpressionCount() {
-  prefs_->SetInteger(prefs::kBookmarkPromptImpressionCount,
-                     GetPromptImpressionCount() + 1);
-}
-
-bool BookmarkPromptPrefs::IsBookmarkPromptEnabled() const {
-  return prefs_->GetBoolean(prefs::kBookmarkPromptEnabled);
-}
-
-// static
-void BookmarkPromptPrefs::RegisterProfilePrefs(
-    user_prefs::PrefRegistrySyncable* registry) {
-  // We always register preferences without checking FieldTrial, because
-  // we may not receive field trial list from the server yet.
-  registry->RegisterBooleanPref(
-      prefs::kBookmarkPromptEnabled,
-      true,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-  registry->RegisterIntegerPref(
-      prefs::kBookmarkPromptImpressionCount,
-      0,
-      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-}
diff --git a/components/bookmarks/core/browser/bookmark_prompt_prefs.h b/components/bookmarks/core/browser/bookmark_prompt_prefs.h
deleted file mode 100644
index c258ed6..0000000
--- a/components/bookmarks/core/browser/bookmark_prompt_prefs.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// 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.
-
-#ifndef COMPONENTS_BOOKMARKS_CORE_BROWSER_BOOKMARK_PROMPT_PREFS_H_
-#define COMPONENTS_BOOKMARKS_CORE_BROWSER_BOOKMARK_PROMPT_PREFS_H_
-
-#include "base/basictypes.h"
-
-class PrefService;
-
-namespace user_prefs {
-class PrefRegistrySyncable;
-}
-
-// Helper class for getting, changing bookmark prompt related preferences.
-class BookmarkPromptPrefs {
- public:
-  // Constructs and associates to |prefs|. Further operations occurred on
-  // associated |prefs|.
-  explicit BookmarkPromptPrefs(PrefService* prefs);
-  ~BookmarkPromptPrefs();
-
-  // Disables bookmark prompt feature.
-  void DisableBookmarkPrompt();
-
-  // Returns number of times bookmark prompt displayed so far.
-  int GetPromptImpressionCount() const;
-
-  // Increments bookmark prompt impression counter.
-  void IncrementPromptImpressionCount();
-
-  // Returns true if bookmark prompt feature enabled, otherwise false.
-  bool IsBookmarkPromptEnabled() const;
-
-  // Registers user preferences used by bookmark prompt feature.
-  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
-
- private:
-  PrefService* prefs_;  // Weak.
-
-  DISALLOW_COPY_AND_ASSIGN(BookmarkPromptPrefs);
-};
-
-#endif  // COMPONENTS_BOOKMARKS_CORE_BROWSER_BOOKMARK_PROMPT_PREFS_H_
diff --git a/components/bookmarks/core/browser/bookmark_utils.cc b/components/bookmarks/core/browser/bookmark_utils.cc
index 3f77b1d..9877b2f 100644
--- a/components/bookmarks/core/browser/bookmark_utils.cc
+++ b/components/bookmarks/core/browser/bookmark_utils.cc
@@ -16,6 +16,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/browser/scoped_group_bookmark_actions.h"
 #include "components/bookmarks/core/common/bookmark_pref_names.h"
 #include "components/query_parser/query_parser.h"
 #include "components/user_prefs/pref_registry_syncable.h"
@@ -23,10 +24,6 @@
 #include "ui/base/models/tree_node_iterator.h"
 #include "url/gurl.h"
 
-#if !defined(OS_ANDROID)
-#include "components/bookmarks/core/browser/scoped_group_bookmark_actions.h"
-#endif
-
 using base::Time;
 
 namespace {
@@ -182,9 +179,7 @@
       WriteToClipboard(ui::CLIPBOARD_TYPE_COPY_PASTE);
 
   if (remove_nodes) {
-#if !defined(OS_ANDROID)
     ScopedGroupBookmarkActions group_cut(model);
-#endif
     for (size_t i = 0; i < filtered_nodes.size(); ++i) {
       int index = filtered_nodes[i]->parent()->GetIndexOf(filtered_nodes[i]);
       if (index > -1)
@@ -205,9 +200,7 @@
 
   if (index == -1)
     index = parent->child_count();
-#if !defined(OS_ANDROID)
   ScopedGroupBookmarkActions group_paste(model);
-#endif
   CloneBookmarkNode(model, bookmark_data.elements, parent, index, true);
 }
 
diff --git a/components/bookmarks/core/common/bookmark_pref_names.cc b/components/bookmarks/core/common/bookmark_pref_names.cc
index 9138643..a3b8089 100644
--- a/components/bookmarks/core/common/bookmark_pref_names.cc
+++ b/components/bookmarks/core/common/bookmark_pref_names.cc
@@ -10,13 +10,6 @@
 // the bookmark editor.
 const char kBookmarkEditorExpandedNodes[] = "bookmark_editor.expanded_nodes";
 
-// Boolean that is true when bookmark prompt is enabled.
-const char kBookmarkPromptEnabled[] = "bookmark_prompt_enabled";
-
-// Number of times bookmark prompt displayed.
-const char kBookmarkPromptImpressionCount[] =
-    "bookmark_prompt_impression_count";
-
 // Boolean which specifies whether the bookmark bar is visible on all tabs.
 const char kShowBookmarkBar[] = "bookmark_bar.show_on_all_tabs";
 
diff --git a/components/bookmarks/core/test/bookmark_index_unittest.cc b/components/bookmarks/core/test/bookmark_index_unittest.cc
new file mode 100644
index 0000000..0c4d302
--- /dev/null
+++ b/components/bookmarks/core/test/bookmark_index_unittest.cc
@@ -0,0 +1,463 @@
+// 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.
+
+#include "components/bookmarks/core/browser/bookmark_index.h"
+
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/bookmarks/core/browser/bookmark_match.h"
+#include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
+#include "components/bookmarks/core/test/test_bookmark_client.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::ASCIIToUTF16;
+
+namespace {
+
+class BookmarkClientMock : public test::TestBookmarkClient {
+ public:
+  BookmarkClientMock(const std::map<GURL, int>& typed_count_map)
+      : typed_count_map_(typed_count_map) {}
+
+  virtual bool SupportsTypedCountForNodes() OVERRIDE { return true; }
+
+  virtual void GetTypedCountForNodes(
+      const NodeSet& nodes,
+      NodeTypedCountPairs* node_typed_count_pairs) OVERRIDE {
+    for (NodeSet::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
+      const BookmarkNode* node = *it;
+      std::map<GURL, int>::const_iterator found =
+          typed_count_map_.find(node->url());
+      if (found == typed_count_map_.end())
+        continue;
+
+      node_typed_count_pairs->push_back(std::make_pair(node, found->second));
+    }
+  }
+
+ private:
+  const std::map<GURL, int> typed_count_map_;
+
+  DISALLOW_COPY_AND_ASSIGN(BookmarkClientMock);
+};
+
+}
+
+class BookmarkIndexTest : public testing::Test {
+ public:
+  BookmarkIndexTest() : model_(client_.CreateModel(false)) {}
+
+  typedef std::pair<std::string, std::string> TitleAndURL;
+
+  void AddBookmarks(const char** titles, const char** urls, size_t count) {
+    // The pair is (title, url).
+    std::vector<TitleAndURL> bookmarks;
+    for (size_t i = 0; i < count; ++i) {
+      TitleAndURL bookmark(titles[i], urls[i]);
+      bookmarks.push_back(bookmark);
+    }
+    AddBookmarks(bookmarks);
+  }
+
+  void AddBookmarks(const std::vector<TitleAndURL> bookmarks) {
+    for (size_t i = 0; i < bookmarks.size(); ++i) {
+      model_->AddURL(model_->other_node(), static_cast<int>(i),
+                     ASCIIToUTF16(bookmarks[i].first),
+                     GURL(bookmarks[i].second));
+    }
+  }
+
+  void ExpectMatches(const std::string& query,
+                     const char** expected_titles,
+                     size_t expected_count) {
+    std::vector<std::string> title_vector;
+    for (size_t i = 0; i < expected_count; ++i)
+      title_vector.push_back(expected_titles[i]);
+    ExpectMatches(query, title_vector);
+  }
+
+  void ExpectMatches(const std::string& query,
+                     const std::vector<std::string>& expected_titles) {
+    std::vector<BookmarkMatch> matches;
+    model_->GetBookmarksMatching(ASCIIToUTF16(query), 1000, &matches);
+    ASSERT_EQ(expected_titles.size(), matches.size());
+    for (size_t i = 0; i < expected_titles.size(); ++i) {
+      bool found = false;
+      for (size_t j = 0; j < matches.size(); ++j) {
+        if (ASCIIToUTF16(expected_titles[i]) == matches[j].node->GetTitle()) {
+          matches.erase(matches.begin() + j);
+          found = true;
+          break;
+        }
+      }
+      ASSERT_TRUE(found);
+    }
+  }
+
+  void ExtractMatchPositions(const std::string& string,
+                             BookmarkMatch::MatchPositions* matches) {
+    std::vector<std::string> match_strings;
+    base::SplitString(string, ':', &match_strings);
+    for (size_t i = 0; i < match_strings.size(); ++i) {
+      std::vector<std::string> chunks;
+      base::SplitString(match_strings[i], ',', &chunks);
+      ASSERT_EQ(2U, chunks.size());
+      matches->push_back(BookmarkMatch::MatchPosition());
+      int chunks0, chunks1;
+      base::StringToInt(chunks[0], &chunks0);
+      base::StringToInt(chunks[1], &chunks1);
+      matches->back().first = chunks0;
+      matches->back().second = chunks1;
+    }
+  }
+
+  void ExpectMatchPositions(
+      const BookmarkMatch::MatchPositions& actual_positions,
+      const BookmarkMatch::MatchPositions& expected_positions) {
+    ASSERT_EQ(expected_positions.size(), actual_positions.size());
+    for (size_t i = 0; i < expected_positions.size(); ++i) {
+      EXPECT_EQ(expected_positions[i].first, actual_positions[i].first);
+      EXPECT_EQ(expected_positions[i].second, actual_positions[i].second);
+    }
+  }
+
+ protected:
+  test::TestBookmarkClient client_;
+  scoped_ptr<BookmarkModel> model_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BookmarkIndexTest);
+};
+
+// Various permutations with differing input, queries and output that exercises
+// all query paths.
+TEST_F(BookmarkIndexTest, GetBookmarksMatching) {
+  struct TestData {
+    const std::string titles;
+    const std::string query;
+    const std::string expected;
+  } data[] = {
+    // Trivial test case of only one term, exact match.
+    { "a;b",                        "A",        "a" },
+
+    // Prefix match, one term.
+    { "abcd;abc;b",                 "abc",      "abcd;abc" },
+
+    // Prefix match, multiple terms.
+    { "abcd cdef;abcd;abcd cdefg",  "abc cde",  "abcd cdef;abcd cdefg"},
+
+    // Exact and prefix match.
+    { "ab cdef;abcd;abcd cdefg",    "ab cdef",  "ab cdef"},
+
+    // Exact and prefix match.
+    { "ab cdef ghij;ab;cde;cdef;ghi;cdef ab;ghij ab",
+      "ab cde ghi",
+      "ab cdef ghij"},
+
+    // Title with term multiple times.
+    { "ab ab",                      "ab",       "ab ab"},
+
+    // Make sure quotes don't do a prefix match.
+    { "think",                      "\"thi\"",  ""},
+
+    // Prefix matches against multiple candidates.
+    { "abc1 abc2 abc3 abc4", "abc", "abc1 abc2 abc3 abc4"},
+  };
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
+    std::vector<std::string> titles;
+    base::SplitString(data[i].titles, ';', &titles);
+    std::vector<TitleAndURL> bookmarks;
+    for (size_t j = 0; j < titles.size(); ++j) {
+      TitleAndURL bookmark(titles[j], "about:blank");
+      bookmarks.push_back(bookmark);
+    }
+    AddBookmarks(bookmarks);
+
+    std::vector<std::string> expected;
+    if (!data[i].expected.empty())
+      base::SplitString(data[i].expected, ';', &expected);
+
+    ExpectMatches(data[i].query, expected);
+
+    model_ = client_.CreateModel(false);
+  }
+}
+
+// Analogous to GetBookmarksMatching, this test tests various permutations
+// of title, URL, and input to see if the title/URL matches the input as
+// expected.
+TEST_F(BookmarkIndexTest, GetBookmarksMatchingWithURLs) {
+  struct TestData {
+    const std::string query;
+    const std::string title;
+    const std::string url;
+    const bool should_be_retrieved;
+  } data[] = {
+    // Test single-word inputs.  Include both exact matches and prefix matches.
+    { "foo", "Foo",    "http://www.bar.com/",    true  },
+    { "foo", "Foodie", "http://www.bar.com/",    true  },
+    { "foo", "Bar",    "http://www.foo.com/",    true  },
+    { "foo", "Bar",    "http://www.foodie.com/", true  },
+    { "foo", "Foo",    "http://www.foo.com/",    true  },
+    { "foo", "Bar",    "http://www.bar.com/",    false },
+    { "foo", "Bar",    "http://www.bar.com/blah/foo/blah-again/ ",    true  },
+    { "foo", "Bar",    "http://www.bar.com/blah/foodie/blah-again/ ", true  },
+    { "foo", "Bar",    "http://www.bar.com/blah-foo/blah-again/ ",    true  },
+    { "foo", "Bar",    "http://www.bar.com/blah-foodie/blah-again/ ", true  },
+    { "foo", "Bar",    "http://www.bar.com/blahafoo/blah-again/ ",    false },
+
+    // Test multi-word inputs.
+    { "foo bar", "Foo Bar",      "http://baz.com/",   true  },
+    { "foo bar", "Foodie Bar",   "http://baz.com/",   true  },
+    { "bar foo", "Foo Bar",      "http://baz.com/",   true  },
+    { "bar foo", "Foodie Barly", "http://baz.com/",   true  },
+    { "foo bar", "Foo Baz",      "http://baz.com/",   false },
+    { "foo bar", "Foo Baz",      "http://bar.com/",   true  },
+    { "foo bar", "Foo Baz",      "http://barly.com/", true  },
+    { "foo bar", "Foodie Baz",   "http://barly.com/", true  },
+    { "bar foo", "Foo Baz",      "http://bar.com/",   true  },
+    { "bar foo", "Foo Baz",      "http://barly.com/", true  },
+    { "foo bar", "Baz Bar",      "http://blah.com/foo",         true  },
+    { "foo bar", "Baz Barly",    "http://blah.com/foodie",      true  },
+    { "foo bar", "Baz Bur",      "http://blah.com/foo/bar",     true  },
+    { "foo bar", "Baz Bur",      "http://blah.com/food/barly",  true  },
+    { "foo bar", "Baz Bur",      "http://bar.com/blah/foo",     true  },
+    { "foo bar", "Baz Bur",      "http://barly.com/blah/food",  true  },
+    { "foo bar", "Baz Bur",      "http://bar.com/blah/flub",    false },
+    { "foo bar", "Baz Bur",      "http://foo.com/blah/flub",    false }
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
+    model_ = client_.CreateModel(true);
+    std::vector<TitleAndURL> bookmarks;
+    bookmarks.push_back(TitleAndURL(data[i].title, data[i].url));
+    AddBookmarks(bookmarks);
+
+    std::vector<std::string> expected;
+    if (data[i].should_be_retrieved)
+      expected.push_back(data[i].title);
+
+    ExpectMatches(data[i].query, expected);
+  }
+}
+
+TEST_F(BookmarkIndexTest, Normalization) {
+  struct TestData {
+    const char* title;
+    const char* query;
+  } data[] = {
+    { "fooa\xcc\x88-test", "foo\xc3\xa4-test" },
+    { "fooa\xcc\x88-test", "fooa\xcc\x88-test" },
+    { "fooa\xcc\x88-test", "foo\xc3\xa4" },
+    { "fooa\xcc\x88-test", "fooa\xcc\x88" },
+    { "fooa\xcc\x88-test", "foo" },
+    { "foo\xc3\xa4-test", "foo\xc3\xa4-test" },
+    { "foo\xc3\xa4-test", "fooa\xcc\x88-test" },
+    { "foo\xc3\xa4-test", "foo\xc3\xa4" },
+    { "foo\xc3\xa4-test", "fooa\xcc\x88" },
+    { "foo\xc3\xa4-test", "foo" },
+    { "foo", "foo" }
+  };
+
+  GURL url("about:blank");
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
+    model_->AddURL(model_->other_node(), 0, base::UTF8ToUTF16(data[i].title),
+                   url);
+    std::vector<BookmarkMatch> matches;
+    model_->GetBookmarksMatching(
+        base::UTF8ToUTF16(data[i].query), 10, &matches);
+    EXPECT_EQ(1u, matches.size());
+    model_ = client_.CreateModel(false);
+  }
+}
+
+// Makes sure match positions are updated appropriately for title matches.
+TEST_F(BookmarkIndexTest, MatchPositionsTitles) {
+  struct TestData {
+    const std::string title;
+    const std::string query;
+    const std::string expected_title_match_positions;
+  } data[] = {
+    // Trivial test case of only one term, exact match.
+    { "a",                        "A",        "0,1" },
+    { "foo bar",                  "bar",      "4,7" },
+    { "fooey bark",               "bar foo",  "0,3:6,9" },
+    // Non-trivial tests.
+    { "foobar foo",               "foobar foo",   "0,6:7,10" },
+    { "foobar foo",               "foo foobar",   "0,6:7,10" },
+    { "foobar foobar",            "foobar foo",   "0,6:7,13" },
+    { "foobar foobar",            "foo foobar",   "0,6:7,13" },
+  };
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
+    std::vector<TitleAndURL> bookmarks;
+    TitleAndURL bookmark(data[i].title, "about:blank");
+    bookmarks.push_back(bookmark);
+    AddBookmarks(bookmarks);
+
+    std::vector<BookmarkMatch> matches;
+    model_->GetBookmarksMatching(ASCIIToUTF16(data[i].query), 1000, &matches);
+    ASSERT_EQ(1U, matches.size());
+
+    BookmarkMatch::MatchPositions expected_title_matches;
+    ExtractMatchPositions(data[i].expected_title_match_positions,
+                          &expected_title_matches);
+    ExpectMatchPositions(matches[0].title_match_positions,
+                         expected_title_matches);
+
+    model_ = client_.CreateModel(false);
+  }
+}
+
+// Makes sure match positions are updated appropriately for URL matches.
+TEST_F(BookmarkIndexTest, MatchPositionsURLs) {
+  // The encoded stuff between /wiki/ and the # is 第二次世界大戦
+  const std::string ja_wiki_url = "http://ja.wikipedia.org/wiki/%E7%AC%AC%E4"
+      "%BA%8C%E6%AC%A1%E4%B8%96%E7%95%8C%E5%A4%A7%E6%88%A6#.E3.83.B4.E3.82.A7"
+      ".E3.83.AB.E3.82.B5.E3.82.A4.E3.83.A6.E4.BD.93.E5.88.B6";
+  struct TestData {
+    const std::string query;
+    const std::string url;
+    const std::string expected_url_match_positions;
+  } data[] = {
+    { "foo",        "http://www.foo.com/",    "11,14" },
+    { "foo",        "http://www.foodie.com/", "11,14" },
+    { "foo",        "http://www.foofoo.com/", "11,14" },
+    { "www",        "http://www.foo.com/",    "7,10"  },
+    { "foo",        "http://www.foodie.com/blah/foo/fi", "11,14:27,30"      },
+    { "foo",        "http://www.blah.com/blah/foo/fi",   "25,28"            },
+    { "foo www",    "http://www.foodie.com/blah/foo/fi", "7,10:11,14:27,30" },
+    { "www foo",    "http://www.foodie.com/blah/foo/fi", "7,10:11,14:27,30" },
+    { "www bla",    "http://www.foodie.com/blah/foo/fi", "7,10:22,25"       },
+    { "http",       "http://www.foo.com/",               "0,4"              },
+    { "http www",   "http://www.foo.com/",               "0,4:7,10"         },
+    { "http foo",   "http://www.foo.com/",               "0,4:11,14"        },
+    { "http foo",   "http://www.bar.com/baz/foodie/hi",  "0,4:23,26"        },
+    { "第二次",      ja_wiki_url,                         "29,56"            },
+    { "ja 第二次",   ja_wiki_url,                         "7,9:29,56"        },
+    { "第二次 E3.8", ja_wiki_url,                         "29,56:94,98:103,107:"
+                                                         "112,116:121,125:"
+                                                         "130,134:139,143"  }
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
+    model_ = client_.CreateModel(true);
+    std::vector<TitleAndURL> bookmarks;
+    TitleAndURL bookmark("123456", data[i].url);
+    bookmarks.push_back(bookmark);
+    AddBookmarks(bookmarks);
+
+    std::vector<BookmarkMatch> matches;
+    model_->GetBookmarksMatching(
+        base::UTF8ToUTF16(data[i].query), 1000, &matches);
+    ASSERT_EQ(1U, matches.size()) << data[i].url << data[i].query;
+
+    BookmarkMatch::MatchPositions expected_url_matches;
+    ExtractMatchPositions(data[i].expected_url_match_positions,
+                          &expected_url_matches);
+    ExpectMatchPositions(matches[0].url_match_positions, expected_url_matches);
+  }
+}
+
+// Makes sure index is updated when a node is removed.
+TEST_F(BookmarkIndexTest, Remove) {
+  const char* titles[] = { "a", "b" };
+  const char* urls[] = { "about:blank", "about:blank" };
+  AddBookmarks(titles, urls, ARRAYSIZE_UNSAFE(titles));
+
+  // Remove the node and make sure we don't get back any results.
+  model_->Remove(model_->other_node(), 0);
+  ExpectMatches("A", NULL, 0U);
+}
+
+// Makes sure index is updated when a node's title is changed.
+TEST_F(BookmarkIndexTest, ChangeTitle) {
+  const char* titles[] = { "a", "b" };
+  const char* urls[] = { "about:blank", "about:blank" };
+  AddBookmarks(titles, urls, ARRAYSIZE_UNSAFE(titles));
+
+  // Remove the node and make sure we don't get back any results.
+  const char* expected[] = { "blah" };
+  model_->SetTitle(model_->other_node()->GetChild(0), ASCIIToUTF16("blah"));
+  ExpectMatches("BlAh", expected, ARRAYSIZE_UNSAFE(expected));
+}
+
+// Makes sure no more than max queries is returned.
+TEST_F(BookmarkIndexTest, HonorMax) {
+  const char* titles[] = { "abcd", "abcde" };
+  const char* urls[] = { "about:blank", "about:blank" };
+  AddBookmarks(titles, urls, ARRAYSIZE_UNSAFE(titles));
+
+  std::vector<BookmarkMatch> matches;
+  model_->GetBookmarksMatching(ASCIIToUTF16("ABc"), 1, &matches);
+  EXPECT_EQ(1U, matches.size());
+}
+
+// Makes sure if the lower case string of a bookmark title is more characters
+// than the upper case string no match positions are returned.
+TEST_F(BookmarkIndexTest, EmptyMatchOnMultiwideLowercaseString) {
+  const BookmarkNode* n1 = model_->AddURL(model_->other_node(), 0,
+                                          base::WideToUTF16(L"\u0130 i"),
+                                          GURL("http://www.google.com"));
+
+  std::vector<BookmarkMatch> matches;
+  model_->GetBookmarksMatching(ASCIIToUTF16("i"), 100, &matches);
+  ASSERT_EQ(1U, matches.size());
+  EXPECT_TRUE(matches[0].node == n1);
+  EXPECT_TRUE(matches[0].title_match_positions.empty());
+}
+
+TEST_F(BookmarkIndexTest, GetResultsSortedByTypedCount) {
+  struct TestData {
+    const GURL url;
+    const char* title;
+    const int typed_count;
+  } data[] = {
+    { GURL("http://www.google.com/"),      "Google",           100 },
+    { GURL("http://maps.google.com/"),     "Google Maps",       40 },
+    { GURL("http://docs.google.com/"),     "Google Docs",       50 },
+    { GURL("http://reader.google.com/"),   "Google Reader",     80 },
+  };
+
+  std::map<GURL, int> typed_count_map;
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i)
+    typed_count_map.insert(std::make_pair(data[i].url, data[i].typed_count));
+
+  BookmarkClientMock client(typed_count_map);
+  scoped_ptr<BookmarkModel> model = client.CreateModel(false);
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i)
+    // Populate the BookmarkIndex.
+    model->AddURL(
+        model->other_node(), i, base::UTF8ToUTF16(data[i].title), data[i].url);
+
+  // Populate match nodes.
+  std::vector<BookmarkMatch> matches;
+  model->GetBookmarksMatching(ASCIIToUTF16("google"), 4, &matches);
+
+  // The resulting order should be:
+  // 1. Google (google.com) 100
+  // 2. Google Reader (google.com/reader) 80
+  // 3. Google Docs (docs.google.com) 50
+  // 4. Google Maps (maps.google.com) 40
+  EXPECT_EQ(4, static_cast<int>(matches.size()));
+  EXPECT_EQ(data[0].url, matches[0].node->url());
+  EXPECT_EQ(data[3].url, matches[1].node->url());
+  EXPECT_EQ(data[2].url, matches[2].node->url());
+  EXPECT_EQ(data[1].url, matches[3].node->url());
+
+  matches.clear();
+  // Select top two matches.
+  model->GetBookmarksMatching(ASCIIToUTF16("google"), 2, &matches);
+
+  EXPECT_EQ(2, static_cast<int>(matches.size()));
+  EXPECT_EQ(data[0].url, matches[0].node->url());
+  EXPECT_EQ(data[3].url, matches[1].node->url());
+}
diff --git a/components/bookmarks/core/test/bookmark_test_helpers.cc b/components/bookmarks/core/test/bookmark_test_helpers.cc
new file mode 100644
index 0000000..86d9ee2
--- /dev/null
+++ b/components/bookmarks/core/test/bookmark_test_helpers.cc
@@ -0,0 +1,139 @@
+// 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.
+
+#include "components/bookmarks/core/test/bookmark_test_helpers.h"
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/bookmarks/core/browser/base_bookmark_model_observer.h"
+#include "components/bookmarks/core/browser/bookmark_model.h"
+#include "url/gurl.h"
+
+namespace {
+
+// BookmarkLoadObserver is used when blocking until the BookmarkModel finishes
+// loading. As soon as the BookmarkModel finishes loading the message loop is
+// quit.
+class BookmarkLoadObserver : public BaseBookmarkModelObserver {
+ public:
+  explicit BookmarkLoadObserver(const base::Closure& quit_task);
+  virtual ~BookmarkLoadObserver();
+
+ private:
+  // BaseBookmarkModelObserver:
+  virtual void BookmarkModelChanged() OVERRIDE;
+  virtual void BookmarkModelLoaded(BookmarkModel* model,
+                                   bool ids_reassigned) OVERRIDE;
+
+  base::Closure quit_task_;
+
+  DISALLOW_COPY_AND_ASSIGN(BookmarkLoadObserver);
+};
+
+BookmarkLoadObserver::BookmarkLoadObserver(const base::Closure& quit_task)
+    : quit_task_(quit_task) {}
+
+BookmarkLoadObserver::~BookmarkLoadObserver() {}
+
+void BookmarkLoadObserver::BookmarkModelChanged() {}
+
+void BookmarkLoadObserver::BookmarkModelLoaded(BookmarkModel* model,
+                                               bool ids_reassigned) {
+  quit_task_.Run();
+}
+
+// Helper function which does the actual work of creating the nodes for
+// a particular level in the hierarchy.
+std::string::size_type AddNodesFromString(BookmarkModel* model,
+                                          const BookmarkNode* node,
+                                          const std::string& model_string,
+                                          std::string::size_type start_pos) {
+  DCHECK(node);
+  int index = node->child_count();
+  static const std::string folder_tell(":[");
+  std::string::size_type end_pos = model_string.find(' ', start_pos);
+  while (end_pos != std::string::npos) {
+    std::string::size_type part_length = end_pos - start_pos;
+    std::string node_name = model_string.substr(start_pos, part_length);
+    // Are we at the end of a folder group?
+    if (node_name != "]") {
+      // No, is it a folder?
+      std::string tell;
+      if (part_length > 2)
+        tell = node_name.substr(part_length - 2, 2);
+      if (tell == folder_tell) {
+        node_name = node_name.substr(0, part_length - 2);
+        const BookmarkNode* new_node =
+            model->AddFolder(node, index, base::UTF8ToUTF16(node_name));
+        end_pos = AddNodesFromString(model, new_node, model_string,
+                                     end_pos + 1);
+      } else {
+        std::string url_string("http://");
+        url_string += std::string(node_name.begin(), node_name.end());
+        url_string += ".com";
+        model->AddURL(
+            node, index, base::UTF8ToUTF16(node_name), GURL(url_string));
+        ++end_pos;
+      }
+      ++index;
+      start_pos = end_pos;
+      end_pos = model_string.find(' ', start_pos);
+    } else {
+      ++end_pos;
+      break;
+    }
+  }
+  return end_pos;
+}
+
+}  // namespace
+
+namespace test {
+
+void WaitForBookmarkModelToLoad(BookmarkModel* model) {
+  if (model->loaded())
+    return;
+  base::RunLoop run_loop;
+  base::MessageLoop::ScopedNestableTaskAllower allow(
+      base::MessageLoop::current());
+
+  BookmarkLoadObserver observer(run_loop.QuitClosure());
+  model->AddObserver(&observer);
+  run_loop.Run();
+  model->RemoveObserver(&observer);
+  DCHECK(model->loaded());
+}
+
+std::string ModelStringFromNode(const BookmarkNode* node) {
+  // Since the children of the node are not available as a vector,
+  // we'll just have to do it the hard way.
+  int child_count = node->child_count();
+  std::string child_string;
+  for (int i = 0; i < child_count; ++i) {
+    const BookmarkNode* child = node->GetChild(i);
+    if (child->is_folder()) {
+      child_string += base::UTF16ToUTF8(child->GetTitle()) + ":[ " +
+          ModelStringFromNode(child) + "] ";
+    } else {
+      child_string += base::UTF16ToUTF8(child->GetTitle()) + " ";
+    }
+  }
+  return child_string;
+}
+
+void AddNodesFromModelString(BookmarkModel* model,
+                             const BookmarkNode* node,
+                             const std::string& model_string) {
+  DCHECK(node);
+  std::string::size_type start_pos = 0;
+  std::string::size_type end_pos =
+      AddNodesFromString(model, node, model_string, start_pos);
+  DCHECK(end_pos == std::string::npos);
+}
+
+}  // namespace test
diff --git a/components/bookmarks/core/test/bookmark_test_helpers.h b/components/bookmarks/core/test/bookmark_test_helpers.h
new file mode 100644
index 0000000..a6467fa
--- /dev/null
+++ b/components/bookmarks/core/test/bookmark_test_helpers.h
@@ -0,0 +1,45 @@
+// 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.
+
+#ifndef COMPONENTS_BOOKMARKS_CORE_TEST_BOOKMARK_TEST_HELPERS_H_
+#define COMPONENTS_BOOKMARKS_CORE_TEST_BOOKMARK_TEST_HELPERS_H_
+
+#include <string>
+
+class BookmarkModel;
+class BookmarkNode;
+
+namespace test {
+
+// Blocks until |model| finishes loading.
+void WaitForBookmarkModelToLoad(BookmarkModel* model);
+
+// Return the descendants of |node| as a string useful for verifying node
+// modifications. The format of the resulting string is:
+//
+//           result = node " " , { node " " }
+//             node = bookmark title | folder
+//           folder = folder title ":[ " { node " " } "]"
+//   bookmark title = (* string with no spaces *)
+//     folder title = (* string with no spaces *)
+//
+// Example: "a f1:[ b d c ] d f2:[ e f g ] h "
+//
+// (Logically, we should use |string16|s, but it's more convenient for test
+// purposes to use (UTF-8) |std::string|s.)
+std::string ModelStringFromNode(const BookmarkNode* node);
+
+// Create and add the node hierarchy specified by |model_string| to the
+// bookmark node given by |node|. The string has the same format as
+// specified for ModelStringFromNode(). The new nodes added to |node|
+// are appended to the end of node's existing subnodes, if any.
+// |model| must be the model of which |node| is a member.
+// NOTE: The string format is very rigid and easily broken if not followed
+//       exactly (since we're using a very simple parser).
+void AddNodesFromModelString(BookmarkModel* model,
+                             const BookmarkNode* node,
+                             const std::string& model_string);
+}  // namespace test
+
+#endif  // COMPONENTS_BOOKMARKS_CORE_TEST_BOOKMARK_TEST_HELPERS_H_
diff --git a/components/bookmarks/core/test/test_bookmark_client.cc b/components/bookmarks/core/test/test_bookmark_client.cc
new file mode 100644
index 0000000..4169029
--- /dev/null
+++ b/components/bookmarks/core/test/test_bookmark_client.cc
@@ -0,0 +1,25 @@
+// 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.
+
+#include "components/bookmarks/core/test/test_bookmark_client.h"
+
+#include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/browser/bookmark_storage.h"
+
+namespace test {
+
+scoped_ptr<BookmarkModel> TestBookmarkClient::CreateModel(bool index_urls) {
+  scoped_ptr<BookmarkModel> bookmark_model(new BookmarkModel(this, index_urls));
+  bookmark_model->DoneLoading(bookmark_model->CreateLoadDetails(std::string()));
+  return bookmark_model.Pass();
+}
+
+bool TestBookmarkClient::PreferTouchIcon() {
+  return false;
+}
+
+void TestBookmarkClient::RecordAction(const base::UserMetricsAction& action) {
+}
+
+}  // namespace test
diff --git a/components/bookmarks/core/test/test_bookmark_client.h b/components/bookmarks/core/test/test_bookmark_client.h
new file mode 100644
index 0000000..284fc3e
--- /dev/null
+++ b/components/bookmarks/core/test/test_bookmark_client.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef COMPONENTS_BOOKMARKS_CORE_TEST_TEST_BOOKMARK_CLIENT_H_
+#define COMPONENTS_BOOKMARKS_CORE_TEST_TEST_BOOKMARK_CLIENT_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "components/bookmarks/core/browser/bookmark_client.h"
+
+class BookmarkModel;
+
+namespace test {
+
+class TestBookmarkClient : public BookmarkClient {
+ public:
+  TestBookmarkClient() {}
+  virtual ~TestBookmarkClient() {}
+
+  // Create a BookmarkModel using this object as its client. The returned
+  // BookmarkModel* is owned by the caller.
+  scoped_ptr<BookmarkModel> CreateModel(bool index_urls);
+
+ private:
+  // BookmarkClient:
+  virtual bool PreferTouchIcon() OVERRIDE;
+  virtual void RecordAction(const base::UserMetricsAction& action) OVERRIDE;
+
+  DISALLOW_COPY_AND_ASSIGN(TestBookmarkClient);
+};
+
+}  // namespace test
+
+#endif  // COMPONENTS_BOOKMARKS_CORE_TEST_TEST_BOOKMARK_CLIENT_H_
diff --git a/components/breakpad/app/DEPS b/components/breakpad/app/DEPS
index 1a1417f..4080651 100644
--- a/components/breakpad/app/DEPS
+++ b/components/breakpad/app/DEPS
@@ -1,7 +1,6 @@
 include_rules = [
   "+sandbox",
 
-  "-content/public/common",
   "+content/public/common/content_descriptors.h",
   "+content/public/common/result_codes.h",
   "+third_party/lss/linux_syscall_support.h",
diff --git a/components/breakpad/app/breakpad_linux.cc b/components/breakpad/app/breakpad_linux.cc
index b63ce6b..dd91b86 100644
--- a/components/breakpad/app/breakpad_linux.cc
+++ b/components/breakpad/app/breakpad_linux.cc
@@ -34,6 +34,7 @@
 #include "base/posix/global_descriptors.h"
 #include "base/process/memory.h"
 #include "base/strings/string_util.h"
+#include "breakpad/src/client/linux/crash_generation/crash_generation_client.h"
 #include "breakpad/src/client/linux/handler/exception_handler.h"
 #include "breakpad/src/client/linux/minidump_writer/directory_reader.h"
 #include "breakpad/src/common/linux/linux_libc_support.h"
@@ -768,88 +769,101 @@
 }
 #else
 // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer
-bool NonBrowserCrashHandler(const void* crash_context,
-                            size_t crash_context_size,
-                            void* context) {
-  const int fd = reinterpret_cast<intptr_t>(context);
-  int fds[2] = { -1, -1 };
-  if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
-    static const char msg[] = "Failed to create socket for crash dumping.\n";
-    WriteLog(msg, sizeof(msg) - 1);
-    return false;
+class NonBrowserCrashHandler : public google_breakpad::CrashGenerationClient {
+ public:
+  NonBrowserCrashHandler()
+      : server_fd_(base::GlobalDescriptors::GetInstance()->Get(
+            kCrashDumpSignal)) {
   }
 
-  // Start constructing the message to send to the browser.
-  char distro[kDistroSize + 1] = {0};
-  PopulateDistro(distro, NULL);
+  virtual ~NonBrowserCrashHandler() {}
 
-  char b;  // Dummy variable for sys_read below.
-  const char* b_addr = &b;  // Get the address of |b| so we can create the
-                            // expected /proc/[pid]/syscall content in the
-                            // browser to convert namespace tids.
+  virtual bool RequestDump(const void* crash_context,
+                           size_t crash_context_size) OVERRIDE {
+    int fds[2] = { -1, -1 };
+    if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
+      static const char msg[] = "Failed to create socket for crash dumping.\n";
+      WriteLog(msg, sizeof(msg) - 1);
+      return false;
+    }
 
-  // The length of the control message:
-  static const unsigned kControlMsgSize = sizeof(fds);
-  static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize);
-  static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize);
+    // Start constructing the message to send to the browser.
+    char distro[kDistroSize + 1] = {0};
+    PopulateDistro(distro, NULL);
 
-  struct kernel_msghdr msg;
-  my_memset(&msg, 0, sizeof(struct kernel_msghdr));
-  struct kernel_iovec iov[kCrashIovSize];
-  iov[0].iov_base = const_cast<void*>(crash_context);
-  iov[0].iov_len = crash_context_size;
-  iov[1].iov_base = distro;
-  iov[1].iov_len = kDistroSize + 1;
-  iov[2].iov_base = &b_addr;
-  iov[2].iov_len = sizeof(b_addr);
-  iov[3].iov_base = &fds[0];
-  iov[3].iov_len = sizeof(fds[0]);
-  iov[4].iov_base = &g_process_start_time;
-  iov[4].iov_len = sizeof(g_process_start_time);
-  iov[5].iov_base = &base::g_oom_size;
-  iov[5].iov_len = sizeof(base::g_oom_size);
-  google_breakpad::SerializedNonAllocatingMap* serialized_map;
-  iov[6].iov_len = g_crash_keys->Serialize(
-      const_cast<const google_breakpad::SerializedNonAllocatingMap**>(
-          &serialized_map));
-  iov[6].iov_base = serialized_map;
+    char b;  // Dummy variable for sys_read below.
+    const char* b_addr = &b;  // Get the address of |b| so we can create the
+                              // expected /proc/[pid]/syscall content in the
+                              // browser to convert namespace tids.
+
+    // The length of the control message:
+    static const unsigned kControlMsgSize = sizeof(fds);
+    static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize);
+    static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize);
+
+    struct kernel_msghdr msg;
+    my_memset(&msg, 0, sizeof(struct kernel_msghdr));
+    struct kernel_iovec iov[kCrashIovSize];
+    iov[0].iov_base = const_cast<void*>(crash_context);
+    iov[0].iov_len = crash_context_size;
+    iov[1].iov_base = distro;
+    iov[1].iov_len = kDistroSize + 1;
+    iov[2].iov_base = &b_addr;
+    iov[2].iov_len = sizeof(b_addr);
+    iov[3].iov_base = &fds[0];
+    iov[3].iov_len = sizeof(fds[0]);
+    iov[4].iov_base = &g_process_start_time;
+    iov[4].iov_len = sizeof(g_process_start_time);
+    iov[5].iov_base = &base::g_oom_size;
+    iov[5].iov_len = sizeof(base::g_oom_size);
+    google_breakpad::SerializedNonAllocatingMap* serialized_map;
+    iov[6].iov_len = g_crash_keys->Serialize(
+        const_cast<const google_breakpad::SerializedNonAllocatingMap**>(
+            &serialized_map));
+    iov[6].iov_base = serialized_map;
 #if defined(ADDRESS_SANITIZER)
-  iov[7].iov_base = const_cast<char*>(g_asan_report_str);
-  iov[7].iov_len = kMaxAsanReportSize + 1;
+    iov[7].iov_base = const_cast<char*>(g_asan_report_str);
+    iov[7].iov_len = kMaxAsanReportSize + 1;
 #endif
 
-  msg.msg_iov = iov;
-  msg.msg_iovlen = kCrashIovSize;
-  char cmsg[kControlMsgSpaceSize];
-  my_memset(cmsg, 0, kControlMsgSpaceSize);
-  msg.msg_control = cmsg;
-  msg.msg_controllen = sizeof(cmsg);
+    msg.msg_iov = iov;
+    msg.msg_iovlen = kCrashIovSize;
+    char cmsg[kControlMsgSpaceSize];
+    my_memset(cmsg, 0, kControlMsgSpaceSize);
+    msg.msg_control = cmsg;
+    msg.msg_controllen = sizeof(cmsg);
 
-  struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
-  hdr->cmsg_level = SOL_SOCKET;
-  hdr->cmsg_type = SCM_RIGHTS;
-  hdr->cmsg_len = kControlMsgLenSize;
-  ((int*) CMSG_DATA(hdr))[0] = fds[0];
-  ((int*) CMSG_DATA(hdr))[1] = fds[1];
+    struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
+    hdr->cmsg_level = SOL_SOCKET;
+    hdr->cmsg_type = SCM_RIGHTS;
+    hdr->cmsg_len = kControlMsgLenSize;
+    ((int*) CMSG_DATA(hdr))[0] = fds[0];
+    ((int*) CMSG_DATA(hdr))[1] = fds[1];
 
-  if (HANDLE_EINTR(sys_sendmsg(fd, &msg, 0)) < 0) {
-    static const char errmsg[] = "Failed to tell parent about crash.\n";
-    WriteLog(errmsg, sizeof(errmsg) - 1);
+    if (HANDLE_EINTR(sys_sendmsg(server_fd_, &msg, 0)) < 0) {
+      static const char errmsg[] = "Failed to tell parent about crash.\n";
+      WriteLog(errmsg, sizeof(errmsg) - 1);
+      IGNORE_RET(sys_close(fds[1]));
+      return false;
+    }
     IGNORE_RET(sys_close(fds[1]));
-    return false;
-  }
-  IGNORE_RET(sys_close(fds[1]));
 
-  if (HANDLE_EINTR(sys_read(fds[0], &b, 1)) != 1) {
-    static const char errmsg[] = "Parent failed to complete crash dump.\n";
-    WriteLog(errmsg, sizeof(errmsg) - 1);
+    if (HANDLE_EINTR(sys_read(fds[0], &b, 1)) != 1) {
+      static const char errmsg[] = "Parent failed to complete crash dump.\n";
+      WriteLog(errmsg, sizeof(errmsg) - 1);
+    }
+
+    return true;
   }
 
-  return true;
-}
+ private:
+  // The pipe FD to the browser process, which will handle the crash dumping.
+  const int server_fd_;
+
+  DISALLOW_COPY_AND_ASSIGN(NonBrowserCrashHandler);
+};
 
 void EnableNonBrowserCrashDumping() {
-  const int fd = base::GlobalDescriptors::GetInstance()->Get(kCrashDumpSignal);
   g_is_crash_reporter_enabled = true;
   // We deliberately leak this object.
   DCHECK(!g_breakpad);
@@ -858,10 +872,10 @@
       MinidumpDescriptor("/tmp"),  // Unused but needed or Breakpad will assert.
       NULL,
       NULL,
-      reinterpret_cast<void*>(fd),  // Param passed to the crash handler.
+      NULL,
       true,
       -1);
-  g_breakpad->set_crash_handler(NonBrowserCrashHandler);
+  g_breakpad->set_crash_generation_client(new NonBrowserCrashHandler());
 }
 #endif  // defined(OS_ANDROID)
 
diff --git a/components/breakpad/app/breakpad_win.cc b/components/breakpad/app/breakpad_win.cc
index 1550938..76f8fe7 100644
--- a/components/breakpad/app/breakpad_win.cc
+++ b/components/breakpad/app/breakpad_win.cc
@@ -25,6 +25,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/lock.h"
 #include "base/win/metro.h"
 #include "base/win/pe_image.h"
 #include "base/win/registry.h"
@@ -86,13 +87,16 @@
                                                  NTSTATUS ExitStatus);
 char* g_real_terminate_process_stub = NULL;
 
-static size_t g_dynamic_keys_offset = 0;
+base::Lock* g_dynamic_entries_lock = NULL;
+// Under *g_dynamic_entries_lock.
+size_t g_dynamic_keys_offset = 0;
 typedef std::map<std::wstring, google_breakpad::CustomInfoEntry*>
     DynamicEntriesMap;
+// Under *g_dynamic_entries_lock.
 DynamicEntriesMap* g_dynamic_entries = NULL;
-// Allow for 128 entries. POSIX uses 64 entries of 256 bytes, so Windows needs
-// 256 entries of 64 bytes to match. See CustomInfoEntry::kValueMaxLength in
-// Breakpad.
+
+// Allow for 256 dynamic entries in addition to the fixed set of entries
+// set up in this file.
 const size_t kMaxDynamicEntries = 256;
 
 // Maximum length for plugin path to include in plugin crash reports.
@@ -151,32 +155,6 @@
                             0, 0, NULL);
 }
 
-extern "C" void DumpProcessAbnormalSignature() {
-  if (!g_breakpad)
-    return;
-  g_custom_entries->push_back(
-      google_breakpad::CustomInfoEntry(L"unusual-crash-signature", L""));
-  g_breakpad->WriteMinidump();
-}
-
-// Reduces the size of the string |str| to a max of 64 chars. Required because
-// breakpad's CustomInfoEntry raises an invalid_parameter error if the string
-// we want to set is longer.
-std::wstring TrimToBreakpadMax(const std::wstring& str) {
-  std::wstring shorter(str);
-  return shorter.substr(0,
-      google_breakpad::CustomInfoEntry::kValueMaxLength - 1);
-}
-
-static void SetIntegerValue(size_t offset, int value) {
-  if (!g_custom_entries)
-    return;
-
-  base::wcslcpy((*g_custom_entries)[offset].value,
-                base::StringPrintf(L"%d", value).c_str(),
-                google_breakpad::CustomInfoEntry::kValueMaxLength);
-}
-
 // Appends the plugin path to |g_custom_entries|.
 void SetPluginPath(const std::wstring& path) {
   DCHECK(g_custom_entries);
@@ -318,6 +296,8 @@
     g_custom_entries->push_back(
         google_breakpad::CustomInfoEntry(L"unspecified-crash-key", L""));
   }
+
+  g_dynamic_entries_lock = new base::Lock;
   g_dynamic_entries = new DynamicEntriesMap;
 
   static google_breakpad::CustomClientInfo custom_client_info;
@@ -436,6 +416,9 @@
   // If we already have a value for this key, update it; otherwise, insert
   // the new value if we have not exhausted the pre-allocated slots for dynamic
   // entries.
+  DCHECK(g_dynamic_entries_lock);
+  base::AutoLock lock(*g_dynamic_entries_lock);
+
   DynamicEntriesMap::iterator it = g_dynamic_entries->find(safe_key);
   google_breakpad::CustomInfoEntry* entry = NULL;
   if (it == g_dynamic_entries->end()) {
@@ -455,6 +438,9 @@
   if (!g_dynamic_entries)
     return;
 
+  DCHECK(g_dynamic_entries_lock);
+  base::AutoLock lock(*g_dynamic_entries_lock);
+
   std::wstring key_string(key);
   DynamicEntriesMap::iterator it = g_dynamic_entries->find(key_string);
   if (it == g_dynamic_entries->end())
@@ -465,8 +451,8 @@
 
 }  // namespace
 
-bool WrapMessageBoxWithSEH(const wchar_t* text, const wchar_t* caption,
-                           UINT flags, bool* exit_now) {
+static bool WrapMessageBoxWithSEH(const wchar_t* text, const wchar_t* caption,
+                                  UINT flags, bool* exit_now) {
   // We wrap the call to MessageBoxW with a SEH handler because it some
   // machines with CursorXP, PeaDict or with FontExplorer installed it crashes
   // uncontrollably here. Being this a best effort deal we better go away.
@@ -534,8 +520,8 @@
   return EXCEPTION_CONTINUE_SEARCH;
 }
 
-NTSTATUS WINAPI HookNtTerminateProcess(HANDLE ProcessHandle,
-                                       NTSTATUS ExitStatus) {
+static NTSTATUS WINAPI HookNtTerminateProcess(HANDLE ProcessHandle,
+                                              NTSTATUS ExitStatus) {
   if (g_breakpad &&
       (ProcessHandle == ::GetCurrentProcess() || ProcessHandle == NULL)) {
     NT_TIB* tib = reinterpret_cast<NT_TIB*>(NtCurrentTeb());
diff --git a/components/breakpad/tools/generate_breakpad_symbols.py b/components/breakpad/tools/generate_breakpad_symbols.py
index 4007d1d..6c25566 100755
--- a/components/breakpad/tools/generate_breakpad_symbols.py
+++ b/components/breakpad/tools/generate_breakpad_symbols.py
@@ -153,15 +153,14 @@
       output_path = os.path.join(
           options.symbols_dir, os.path.basename(binary))
       if os.path.isdir(output_path):
-        dir_stat = os.stat(output_path)
-        bin_stat = os.stat(binary)
         if os.path.getmtime(binary) < os.path.getmtime(output_path):
           should_dump_syms = False
           reason = "symbols are more current than binary"
 
       if not should_dump_syms:
-        with print_lock:
-          print "Skipping %s (%s)" % (binary, reason)
+        if options.verbose:
+          with print_lock:
+            print "Skipping %s (%s)" % (binary, reason)
         queue.task_done()
         continue
 
@@ -169,6 +168,9 @@
         with print_lock:
           print "Generating symbols for %s" % binary
 
+      if os.path.isdir(output_path):
+        os.utime(output_path, None)
+
       syms = GetCommandOutput([GetDumpSymsBinary(options.build_dir), '-r',
                                binary])
       module_line = re.match("MODULE [^ ]+ [^ ]+ ([0-9A-F]+) (.*)\n", syms)
diff --git a/components/cdm.gypi b/components/cdm.gypi
new file mode 100644
index 0000000..14f9234
--- /dev/null
+++ b/components/cdm.gypi
@@ -0,0 +1,62 @@
+# 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.
+
+{
+  'targets': [
+    {
+      'target_name': 'cdm_common',
+      'type': 'static_library',
+      'dependencies': [
+        '../base/base.gyp:base',
+        '../content/content.gyp:content_common',
+        '../ipc/ipc.gyp:ipc',
+      ],
+      'sources': [
+        'cdm/common/cdm_message_generator.cc',
+        'cdm/common/cdm_message_generator.h',
+        'cdm/common/cdm_messages_android.h',
+      ],
+    },
+    {
+      'target_name': 'cdm_renderer',
+      'type': 'static_library',
+      'dependencies': [
+        'cdm_common',
+        '../base/base.gyp:base',
+        '../content/content.gyp:content_common',
+        '../content/content.gyp:content_renderer',
+        '../third_party/widevine/cdm/widevine_cdm.gyp:widevine_cdm_version_h',
+      ],
+      'include_dirs': [
+        # Needed by widevine_key_systems.cc.
+        '<(SHARED_INTERMEDIATE_DIR)',
+      ],
+      'sources': [
+        'cdm/renderer/widevine_key_systems.cc',
+        'cdm/renderer/widevine_key_systems.h',
+      ],
+    },
+  ],
+  'conditions': [
+    ['OS == "android"', {
+      'targets': [
+        {
+          'target_name': 'cdm_browser',
+          'type': 'static_library',
+          'dependencies': [
+            'cdm_common',
+            '../base/base.gyp:base',
+            '../content/content.gyp:content_browser',
+            '../content/content.gyp:content_common',
+            '../media/media.gyp:media',
+          ],
+          'sources': [
+            'cdm/browser/cdm_message_filter_android.cc',
+            'cdm/browser/cdm_message_filter_android.h',
+          ],
+        },
+      ],
+    }],
+  ],
+}
diff --git a/components/cdm/DEPS b/components/cdm/DEPS
new file mode 100644
index 0000000..1c40d98
--- /dev/null
+++ b/components/cdm/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+ipc",
+]
diff --git a/components/cdm/OWNERS b/components/cdm/OWNERS
new file mode 100644
index 0000000..1f6205e
--- /dev/null
+++ b/components/cdm/OWNERS
@@ -0,0 +1,3 @@
+ddorwin@chromium.org
+scherkus@chromium.org
+xhwang@chromium.org
diff --git a/components/cdm/browser/DEPS b/components/cdm/browser/DEPS
new file mode 100644
index 0000000..d0fb59f
--- /dev/null
+++ b/components/cdm/browser/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+  "+content/public/browser",
+  "+media/base/android",
+]
diff --git a/components/cdm/browser/cdm_message_filter_android.cc b/components/cdm/browser/cdm_message_filter_android.cc
new file mode 100644
index 0000000..82dac5e
--- /dev/null
+++ b/components/cdm/browser/cdm_message_filter_android.cc
@@ -0,0 +1,115 @@
+// 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.
+
+#include "components/cdm/browser/cdm_message_filter_android.h"
+
+#include <string>
+
+#include "components/cdm/common/cdm_messages_android.h"
+#include "ipc/ipc_message_macros.h"
+#include "media/base/android/media_codec_bridge.h"
+#include "media/base/android/media_drm_bridge.h"
+
+using content::BrowserThread;
+using content::SupportedCodecs;
+using media::MediaCodecBridge;
+using media::MediaDrmBridge;
+
+namespace cdm {
+
+const size_t kMaxKeySystemLength = 256;
+
+enum CodecType {
+  CODEC_AUDIO,
+  CODEC_VIDEO
+};
+
+struct CodecInfo {
+  SupportedCodecs codec;
+  CodecType codec_type;
+  const char* codec_name;
+  const char* container_mime_type;
+};
+
+const CodecInfo kCodecsToQuery[] = {
+  {content::EME_CODEC_WEBM_VORBIS, CODEC_AUDIO, "vorbis", "video/webm"},
+  {content::EME_CODEC_WEBM_VP8, CODEC_VIDEO, "vp8", "video/webm"},
+  {content::EME_CODEC_WEBM_VP9, CODEC_VIDEO, "vp9", "video/webm"},
+#if defined(USE_PROPRIETARY_CODECS)
+  {content::EME_CODEC_MP4_AAC, CODEC_AUDIO, "mp4a", "video/mp4"},
+  {content::EME_CODEC_MP4_AVC1, CODEC_VIDEO, "avc1", "video/mp4"}
+#endif  // defined(USE_PROPRIETARY_CODECS)
+};
+
+static SupportedCodecs GetSupportedCodecs(
+    const SupportedKeySystemRequest& request,
+    bool video_must_be_compositable) {
+  const std::string& key_system = request.key_system;
+  SupportedCodecs supported_codecs = content::EME_CODEC_NONE;
+
+  for (size_t i = 0; i < arraysize(kCodecsToQuery); ++i) {
+    const CodecInfo& info = kCodecsToQuery[i];
+    // TODO(qinmin): Remove the composition logic when secure contents can be
+    // composited.
+    bool is_secure = (info.codec_type == CODEC_VIDEO)
+                         ? (!video_must_be_compositable) : false;
+    if ((request.codecs & info.codec) &&
+        MediaDrmBridge::IsKeySystemSupportedWithType(
+            key_system, info.container_mime_type) &&
+        MediaCodecBridge::CanDecode(info.codec_name, is_secure)) {
+      supported_codecs |= info.codec;
+    }
+  }
+
+  return supported_codecs;
+}
+
+CdmMessageFilterAndroid::CdmMessageFilterAndroid()
+    : BrowserMessageFilter(EncryptedMediaMsgStart) {}
+
+CdmMessageFilterAndroid::~CdmMessageFilterAndroid() {}
+
+bool CdmMessageFilterAndroid::OnMessageReceived(
+    const IPC::Message& message, bool* message_was_ok) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP_EX(
+      CdmMessageFilterAndroid, message, *message_was_ok)
+    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_GetSupportedKeySystems,
+                        OnGetSupportedKeySystems)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP_EX()
+  return handled;
+}
+
+void CdmMessageFilterAndroid::OverrideThreadForMessage(
+    const IPC::Message& message, BrowserThread::ID* thread) {
+  // Move the IPC handling to FILE thread as it is not very cheap.
+  if (message.type() == ChromeViewHostMsg_GetSupportedKeySystems::ID)
+    *thread = BrowserThread::FILE;
+}
+
+void CdmMessageFilterAndroid::OnGetSupportedKeySystems(
+    const SupportedKeySystemRequest& request,
+    SupportedKeySystemResponse* response) {
+  if (!response) {
+    NOTREACHED() << "NULL response pointer provided.";
+    return;
+  }
+
+  if (request.key_system.size() > kMaxKeySystemLength) {
+    NOTREACHED() << "Invalid key system: " << request.key_system;
+    return;
+  }
+
+  if (!MediaDrmBridge::IsKeySystemSupported(request.key_system))
+    return;
+
+  DCHECK(request.codecs & content::EME_CODEC_ALL) << "unrecognized codec";
+  response->key_system = request.key_system;
+  // TODO(qinmin): check composition is supported or not.
+  response->compositing_codecs = GetSupportedCodecs(request, true);
+  response->non_compositing_codecs = GetSupportedCodecs(request, false);
+}
+
+}  // namespace cdm
diff --git a/components/cdm/browser/cdm_message_filter_android.h b/components/cdm/browser/cdm_message_filter_android.h
new file mode 100644
index 0000000..b639fa8
--- /dev/null
+++ b/components/cdm/browser/cdm_message_filter_android.h
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef COMPONENTS_CDM_BROWSER_CDM_MESSAGE_FILTER_ANDROID_H_
+#define COMPONENTS_CDM_BROWSER_CDM_MESSAGE_FILTER_ANDROID_H_
+
+#include "base/basictypes.h"
+#include "content/public/browser/browser_message_filter.h"
+
+struct SupportedKeySystemRequest;
+struct SupportedKeySystemResponse;
+
+namespace cdm {
+
+// Message filter for EME on android. It is responsible for getting the
+// SupportedKeySystems information and passing it back to renderer.
+class CdmMessageFilterAndroid
+    : public content::BrowserMessageFilter {
+ public:
+  CdmMessageFilterAndroid();
+
+ private:
+  virtual ~CdmMessageFilterAndroid();
+
+  // BrowserMessageFilter implementation.
+  virtual bool OnMessageReceived(const IPC::Message& message,
+                                 bool* message_was_ok) OVERRIDE;
+  virtual void OverrideThreadForMessage(
+      const IPC::Message& message,
+      content::BrowserThread::ID* thread) OVERRIDE;
+
+  // Retrieve the supported key systems.
+  void OnGetSupportedKeySystems(
+      const SupportedKeySystemRequest& request,
+      SupportedKeySystemResponse* response);
+
+  DISALLOW_COPY_AND_ASSIGN(CdmMessageFilterAndroid);
+};
+
+}  // namespace cdm
+
+#endif  // COMPONENTS_CDM_BROWSER_CDM_MESSAGE_FILTER_ANDROID_H_
diff --git a/components/cdm/common/DEPS b/components/cdm/common/DEPS
new file mode 100644
index 0000000..d5923ee
--- /dev/null
+++ b/components/cdm/common/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+content/public/common",
+]
diff --git a/components/cdm/common/OWNERS b/components/cdm/common/OWNERS
new file mode 100644
index 0000000..acdf360
--- /dev/null
+++ b/components/cdm/common/OWNERS
@@ -0,0 +1,13 @@
+# Changes to IPC messages require a security review to avoid introducing
+# new sandbox escapes.
+per-file encrypted_media_messages*.h=set noparent
+per-file encrypted_media_messages*.h=cdn@chromium.org
+per-file encrypted_media_messages*.h=cevans@chromium.org
+per-file encrypted_media_messages*.h=dcheng@chromium.org
+per-file encrypted_media_messages*.h=inferno@chromium.org
+per-file encrypted_media_messages*.h=jln@chromium.org
+per-file encrypted_media_messages*.h=jschuh@chromium.org
+per-file encrypted_media_messages*.h=kenrb@chromium.org
+per-file encrypted_media_messages*.h=nasko@chromium.org
+per-file encrypted_media_messages*.h=palmer@chromium.org
+per-file encrypted_media_messages*.h=tsepez@chromium.org
diff --git a/components/cdm/common/cdm_message_generator.cc b/components/cdm/common/cdm_message_generator.cc
new file mode 100644
index 0000000..2aabce7
--- /dev/null
+++ b/components/cdm/common/cdm_message_generator.cc
@@ -0,0 +1,34 @@
+// 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.
+
+// Get basic type definitions.
+#define IPC_MESSAGE_IMPL
+#include "components/cdm/common/cdm_message_generator.h"
+
+// Generate constructors.
+#include "ipc/struct_constructor_macros.h"
+#include "components/cdm/common/cdm_message_generator.h"
+
+// Generate destructors.
+#include "ipc/struct_destructor_macros.h"
+#include "components/cdm/common/cdm_message_generator.h"
+
+// Generate param traits write methods.
+#include "ipc/param_traits_write_macros.h"
+namespace IPC {
+#include "components/cdm/common/cdm_message_generator.h"
+}  // namespace IPC
+
+// Generate param traits read methods.
+#include "ipc/param_traits_read_macros.h"
+namespace IPC {
+#include "components/cdm/common/cdm_message_generator.h"
+}  // namespace IPC
+
+// Generate param traits log methods.
+#include "ipc/param_traits_log_macros.h"
+namespace IPC {
+#include "components/cdm/common/cdm_message_generator.h"
+}  // namespace IPC
+
diff --git a/components/cdm/common/cdm_message_generator.h b/components/cdm/common/cdm_message_generator.h
new file mode 100644
index 0000000..b528207
--- /dev/null
+++ b/components/cdm/common/cdm_message_generator.h
@@ -0,0 +1,11 @@
+// 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.
+
+// Multiply-included file, no traditional include guard.
+
+#include "base/basictypes.h"  // for OS_ANDROID and some basic types.
+
+#if defined(OS_ANDROID)
+#include "components/cdm/common/cdm_messages_android.h"
+#endif
diff --git a/components/cdm/common/cdm_messages_android.h b/components/cdm/common/cdm_messages_android.h
new file mode 100644
index 0000000..e63f81b
--- /dev/null
+++ b/components/cdm/common/cdm_messages_android.h
@@ -0,0 +1,36 @@
+// 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.
+
+// IPC messages for EME on android.
+// Multiply-included message file, hence no include guard.
+
+#include <vector>
+
+#include "content/public/common/eme_codec.h"
+#include "ipc/ipc_message_macros.h"
+
+#define IPC_MESSAGE_START EncryptedMediaMsgStart
+
+IPC_STRUCT_BEGIN(SupportedKeySystemRequest)
+  IPC_STRUCT_MEMBER(std::string, key_system)
+  IPC_STRUCT_MEMBER(content::SupportedCodecs, codecs, content::EME_CODEC_NONE)
+IPC_STRUCT_END()
+
+IPC_STRUCT_BEGIN(SupportedKeySystemResponse)
+  IPC_STRUCT_MEMBER(std::string, key_system)
+  IPC_STRUCT_MEMBER(content::SupportedCodecs,
+                    compositing_codecs,
+                    content::EME_CODEC_NONE)
+  IPC_STRUCT_MEMBER(content::SupportedCodecs,
+                    non_compositing_codecs,
+                    content::EME_CODEC_NONE)
+IPC_STRUCT_END()
+
+// Messages sent from the renderer to the browser.
+
+// Synchronously get a list of supported EME key systems.
+IPC_SYNC_MESSAGE_CONTROL1_1(
+    ChromeViewHostMsg_GetSupportedKeySystems,
+    SupportedKeySystemRequest /* key system information request */,
+    SupportedKeySystemResponse /* key system information response */)
diff --git a/components/cdm/renderer/DEPS b/components/cdm/renderer/DEPS
new file mode 100644
index 0000000..725e151
--- /dev/null
+++ b/components/cdm/renderer/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+content/public/renderer",
+]
diff --git a/components/cdm/renderer/widevine_key_systems.cc b/components/cdm/renderer/widevine_key_systems.cc
new file mode 100644
index 0000000..d42ec7d
--- /dev/null
+++ b/components/cdm/renderer/widevine_key_systems.cc
@@ -0,0 +1,93 @@
+// 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.
+
+#include "components/cdm/renderer/widevine_key_systems.h"
+
+#include <string>
+#include <vector>
+
+#include "base/logging.h"
+#include "components/cdm/common/cdm_messages_android.h"
+#include "content/public/renderer/key_system_info.h"
+#include "content/public/renderer/render_thread.h"
+
+#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
+
+#if defined(WIDEVINE_CDM_AVAILABLE)
+
+using content::KeySystemInfo;
+using content::SupportedCodecs;
+
+namespace cdm {
+
+// Return |name|'s parent key system.
+static std::string GetDirectParentName(std::string name) {
+  int last_period = name.find_last_of('.');
+  DCHECK_GT(last_period, 0);
+  return name.substr(0, last_period);
+}
+
+void AddWidevineWithCodecs(WidevineCdmType widevine_cdm_type,
+                           SupportedCodecs supported_codecs,
+                           std::vector<KeySystemInfo>* concrete_key_systems) {
+  KeySystemInfo info(kWidevineKeySystem);
+
+  switch (widevine_cdm_type) {
+    case WIDEVINE:
+      // For standard Widevine, add parent name.
+      info.parent_key_system = GetDirectParentName(kWidevineKeySystem);
+      break;
+#if defined(OS_ANDROID)
+    case WIDEVINE_HR_NON_COMPOSITING:
+      info.key_system.append(".hrnoncompositing");
+      break;
+#endif  // defined(OS_ANDROID)
+    default:
+      NOTREACHED();
+  }
+
+  // TODO(xhwang): A container or an initDataType may be supported even though
+  // there are no codecs supported in that container. Fix this when we support
+  // initDataType.
+  info.supported_codecs = supported_codecs;
+
+#if defined(ENABLE_PEPPER_CDMS)
+  info.pepper_type = kWidevineCdmPluginMimeType;
+#endif  // defined(ENABLE_PEPPER_CDMS)
+
+  concrete_key_systems->push_back(info);
+}
+
+#if defined(OS_ANDROID)
+void AddAndroidWidevine(std::vector<KeySystemInfo>* concrete_key_systems) {
+  SupportedKeySystemRequest request;
+  SupportedKeySystemResponse response;
+
+  request.key_system = kWidevineKeySystem;
+  request.codecs = content::EME_CODEC_WEBM_ALL | content::EME_CODEC_MP4_ALL;
+  content::RenderThread::Get()->Send(
+      new ChromeViewHostMsg_GetSupportedKeySystems(request, &response));
+  DCHECK(response.compositing_codecs & content::EME_CODEC_ALL)
+      << "unrecognized codec";
+  DCHECK(response.non_compositing_codecs & content::EME_CODEC_ALL)
+      << "unrecognized codec";
+  if (response.compositing_codecs != content::EME_CODEC_NONE) {
+    AddWidevineWithCodecs(
+        WIDEVINE,
+        static_cast<SupportedCodecs>(response.compositing_codecs),
+        concrete_key_systems);
+  }
+
+  if (response.non_compositing_codecs != content::EME_CODEC_NONE) {
+    AddWidevineWithCodecs(
+        WIDEVINE_HR_NON_COMPOSITING,
+        static_cast<SupportedCodecs>(response.non_compositing_codecs),
+        concrete_key_systems);
+  }
+}
+#endif  // OS_ANDROID
+
+}  // namespace cdm
+
+#endif  // defined(WIDEVINE_CDM_AVAILABLE)
diff --git a/components/cdm/renderer/widevine_key_systems.h b/components/cdm/renderer/widevine_key_systems.h
new file mode 100644
index 0000000..3bed60c
--- /dev/null
+++ b/components/cdm/renderer/widevine_key_systems.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef COMPONENTS_CDM_RENDERER_WIDEVINE_KEY_SYSTEMS_H_
+#define COMPONENTS_CDM_RENDERER_WIDEVINE_KEY_SYSTEMS_H_
+
+#include <vector>
+
+#include "content/public/renderer/key_system_info.h"
+
+namespace cdm {
+
+enum WidevineCdmType {
+  WIDEVINE,
+#if defined(OS_ANDROID)
+  WIDEVINE_HR_NON_COMPOSITING,
+#endif  // defined(OS_ANDROID)
+};
+
+void AddWidevineWithCodecs(
+    WidevineCdmType widevine_cdm_type,
+    content::SupportedCodecs supported_codecs,
+    std::vector<content::KeySystemInfo>* concrete_key_systems);
+
+#if defined(OS_ANDROID)
+void AddAndroidWidevine(
+    std::vector<content::KeySystemInfo>* concrete_key_systems);
+#endif  // defined(OS_ANDROID)
+
+}  // namespace cdm
+
+#endif  // COMPONENTS_CDM_RENDERER_WIDEVINE_KEY_SYSTEMS_H_
diff --git a/components/cdm_browser.target.darwin-arm.mk b/components/cdm_browser.target.darwin-arm.mk
new file mode 100644
index 0000000..2805a14
--- /dev/null
+++ b/components/cdm_browser.target.darwin-arm.mk
@@ -0,0 +1,285 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_accessibility_ax_gen_gyp,,,$(GYP_VAR_PREFIX))/ui_accessibility_ax_gen_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/browser/cdm_message_filter_android.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES := \
+	ui_accessibility_ax_gen_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_browser_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_browser
+cdm_browser: components_cdm_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_browser.target.darwin-arm64.mk b/components/cdm_browser.target.darwin-arm64.mk
new file mode 100644
index 0000000..9f95536
--- /dev/null
+++ b/components/cdm_browser.target.darwin-arm64.mk
@@ -0,0 +1,269 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_accessibility_ax_gen_gyp,,,$(GYP_VAR_PREFIX))/ui_accessibility_ax_gen_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/browser/cdm_message_filter_android.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES := \
+	ui_accessibility_ax_gen_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_browser_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_browser
+cdm_browser: components_cdm_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_browser.target.darwin-mips.mk b/components/cdm_browser.target.darwin-mips.mk
new file mode 100644
index 0000000..7b5d662
--- /dev/null
+++ b/components/cdm_browser.target.darwin-mips.mk
@@ -0,0 +1,281 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_accessibility_ax_gen_gyp,,,$(GYP_VAR_PREFIX))/ui_accessibility_ax_gen_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/browser/cdm_message_filter_android.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES := \
+	ui_accessibility_ax_gen_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_browser_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_browser
+cdm_browser: components_cdm_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_browser.target.darwin-x86.mk b/components/cdm_browser.target.darwin-x86.mk
new file mode 100644
index 0000000..5e58740
--- /dev/null
+++ b/components/cdm_browser.target.darwin-x86.mk
@@ -0,0 +1,281 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_accessibility_ax_gen_gyp,,,$(GYP_VAR_PREFIX))/ui_accessibility_ax_gen_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/browser/cdm_message_filter_android.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES := \
+	ui_accessibility_ax_gen_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_browser_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_browser
+cdm_browser: components_cdm_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_browser.target.darwin-x86_64.mk b/components/cdm_browser.target.darwin-x86_64.mk
new file mode 100644
index 0000000..afbc2c1
--- /dev/null
+++ b/components/cdm_browser.target.darwin-x86_64.mk
@@ -0,0 +1,281 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_accessibility_ax_gen_gyp,,,$(GYP_VAR_PREFIX))/ui_accessibility_ax_gen_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/browser/cdm_message_filter_android.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES := \
+	ui_accessibility_ax_gen_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_browser_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_browser
+cdm_browser: components_cdm_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_browser.target.linux-arm.mk b/components/cdm_browser.target.linux-arm.mk
new file mode 100644
index 0000000..2805a14
--- /dev/null
+++ b/components/cdm_browser.target.linux-arm.mk
@@ -0,0 +1,285 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_accessibility_ax_gen_gyp,,,$(GYP_VAR_PREFIX))/ui_accessibility_ax_gen_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/browser/cdm_message_filter_android.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES := \
+	ui_accessibility_ax_gen_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_browser_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_browser
+cdm_browser: components_cdm_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_browser.target.linux-arm64.mk b/components/cdm_browser.target.linux-arm64.mk
new file mode 100644
index 0000000..9f95536
--- /dev/null
+++ b/components/cdm_browser.target.linux-arm64.mk
@@ -0,0 +1,269 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_accessibility_ax_gen_gyp,,,$(GYP_VAR_PREFIX))/ui_accessibility_ax_gen_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/browser/cdm_message_filter_android.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES := \
+	ui_accessibility_ax_gen_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_browser_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_browser
+cdm_browser: components_cdm_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_browser.target.linux-mips.mk b/components/cdm_browser.target.linux-mips.mk
new file mode 100644
index 0000000..7b5d662
--- /dev/null
+++ b/components/cdm_browser.target.linux-mips.mk
@@ -0,0 +1,281 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_accessibility_ax_gen_gyp,,,$(GYP_VAR_PREFIX))/ui_accessibility_ax_gen_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/browser/cdm_message_filter_android.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES := \
+	ui_accessibility_ax_gen_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_browser_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_browser
+cdm_browser: components_cdm_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_browser.target.linux-x86.mk b/components/cdm_browser.target.linux-x86.mk
new file mode 100644
index 0000000..5e58740
--- /dev/null
+++ b/components/cdm_browser.target.linux-x86.mk
@@ -0,0 +1,281 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_accessibility_ax_gen_gyp,,,$(GYP_VAR_PREFIX))/ui_accessibility_ax_gen_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/browser/cdm_message_filter_android.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES := \
+	ui_accessibility_ax_gen_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_browser_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_browser
+cdm_browser: components_cdm_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_browser.target.linux-x86_64.mk b/components/cdm_browser.target.linux-x86_64.mk
new file mode 100644
index 0000000..afbc2c1
--- /dev/null
+++ b/components/cdm_browser.target.linux-x86_64.mk
@@ -0,0 +1,281 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_accessibility_ax_gen_gyp,,,$(GYP_VAR_PREFIX))/ui_accessibility_ax_gen_gyp.a
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/browser/cdm_message_filter_android.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DMEDIA_DISABLE_LIBVPX' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES := \
+	ui_accessibility_ax_gen_gyp
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_browser_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_browser
+cdm_browser: components_cdm_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_common.target.darwin-arm.mk b/components/cdm_common.target.darwin-arm.mk
new file mode 100644
index 0000000..37d5d60
--- /dev/null
+++ b/components/cdm_common.target.darwin-arm.mk
@@ -0,0 +1,279 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/common/cdm_message_generator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_common_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_common
+cdm_common: components_cdm_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_common.target.darwin-arm64.mk b/components/cdm_common.target.darwin-arm64.mk
new file mode 100644
index 0000000..087e24a
--- /dev/null
+++ b/components/cdm_common.target.darwin-arm64.mk
@@ -0,0 +1,263 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/common/cdm_message_generator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_common_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_common
+cdm_common: components_cdm_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_common.target.darwin-mips.mk b/components/cdm_common.target.darwin-mips.mk
new file mode 100644
index 0000000..5df6b33
--- /dev/null
+++ b/components/cdm_common.target.darwin-mips.mk
@@ -0,0 +1,275 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/common/cdm_message_generator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_common_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_common
+cdm_common: components_cdm_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_common.target.darwin-x86.mk b/components/cdm_common.target.darwin-x86.mk
new file mode 100644
index 0000000..ea59e30
--- /dev/null
+++ b/components/cdm_common.target.darwin-x86.mk
@@ -0,0 +1,275 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/common/cdm_message_generator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_common_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_common
+cdm_common: components_cdm_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_common.target.darwin-x86_64.mk b/components/cdm_common.target.darwin-x86_64.mk
new file mode 100644
index 0000000..2fb2dac
--- /dev/null
+++ b/components/cdm_common.target.darwin-x86_64.mk
@@ -0,0 +1,275 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/common/cdm_message_generator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_common_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_common
+cdm_common: components_cdm_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_common.target.linux-arm.mk b/components/cdm_common.target.linux-arm.mk
new file mode 100644
index 0000000..37d5d60
--- /dev/null
+++ b/components/cdm_common.target.linux-arm.mk
@@ -0,0 +1,279 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/common/cdm_message_generator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_common_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_common
+cdm_common: components_cdm_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_common.target.linux-arm64.mk b/components/cdm_common.target.linux-arm64.mk
new file mode 100644
index 0000000..087e24a
--- /dev/null
+++ b/components/cdm_common.target.linux-arm64.mk
@@ -0,0 +1,263 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/common/cdm_message_generator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_common_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_common
+cdm_common: components_cdm_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_common.target.linux-mips.mk b/components/cdm_common.target.linux-mips.mk
new file mode 100644
index 0000000..5df6b33
--- /dev/null
+++ b/components/cdm_common.target.linux-mips.mk
@@ -0,0 +1,275 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/common/cdm_message_generator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_common_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_common
+cdm_common: components_cdm_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_common.target.linux-x86.mk b/components/cdm_common.target.linux-x86.mk
new file mode 100644
index 0000000..ea59e30
--- /dev/null
+++ b/components/cdm_common.target.linux-x86.mk
@@ -0,0 +1,275 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/common/cdm_message_generator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_common_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_common
+cdm_common: components_cdm_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_common.target.linux-x86_64.mk b/components/cdm_common.target.linux-x86_64.mk
new file mode 100644
index 0000000..2fb2dac
--- /dev/null
+++ b/components/cdm_common.target.linux-x86_64.mk
@@ -0,0 +1,275 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/common/cdm_message_generator.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_common_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_common
+cdm_common: components_cdm_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_renderer.target.darwin-arm.mk b/components/cdm_renderer.target.darwin-arm.mk
new file mode 100644
index 0000000..72077c0
--- /dev/null
+++ b/components/cdm_renderer.target.darwin-arm.mk
@@ -0,0 +1,284 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_widevine_cdm_widevine_cdm_version_h_gyp,,,$(GYP_VAR_PREFIX))/widevine_cdm_version_h.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/renderer/widevine_key_systems.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_renderer
+cdm_renderer: components_cdm_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_renderer.target.darwin-arm64.mk b/components/cdm_renderer.target.darwin-arm64.mk
new file mode 100644
index 0000000..061fce3
--- /dev/null
+++ b/components/cdm_renderer.target.darwin-arm64.mk
@@ -0,0 +1,268 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_widevine_cdm_widevine_cdm_version_h_gyp,,,$(GYP_VAR_PREFIX))/widevine_cdm_version_h.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/renderer/widevine_key_systems.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_renderer
+cdm_renderer: components_cdm_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_renderer.target.darwin-mips.mk b/components/cdm_renderer.target.darwin-mips.mk
new file mode 100644
index 0000000..f86a7e8
--- /dev/null
+++ b/components/cdm_renderer.target.darwin-mips.mk
@@ -0,0 +1,280 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_widevine_cdm_widevine_cdm_version_h_gyp,,,$(GYP_VAR_PREFIX))/widevine_cdm_version_h.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/renderer/widevine_key_systems.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_renderer
+cdm_renderer: components_cdm_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_renderer.target.darwin-x86.mk b/components/cdm_renderer.target.darwin-x86.mk
new file mode 100644
index 0000000..a11ac0e
--- /dev/null
+++ b/components/cdm_renderer.target.darwin-x86.mk
@@ -0,0 +1,280 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_widevine_cdm_widevine_cdm_version_h_gyp,,,$(GYP_VAR_PREFIX))/widevine_cdm_version_h.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/renderer/widevine_key_systems.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_renderer
+cdm_renderer: components_cdm_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_renderer.target.darwin-x86_64.mk b/components/cdm_renderer.target.darwin-x86_64.mk
new file mode 100644
index 0000000..46a644b
--- /dev/null
+++ b/components/cdm_renderer.target.darwin-x86_64.mk
@@ -0,0 +1,280 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_widevine_cdm_widevine_cdm_version_h_gyp,,,$(GYP_VAR_PREFIX))/widevine_cdm_version_h.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/renderer/widevine_key_systems.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_renderer
+cdm_renderer: components_cdm_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_renderer.target.linux-arm.mk b/components/cdm_renderer.target.linux-arm.mk
new file mode 100644
index 0000000..72077c0
--- /dev/null
+++ b/components/cdm_renderer.target.linux-arm.mk
@@ -0,0 +1,284 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_widevine_cdm_widevine_cdm_version_h_gyp,,,$(GYP_VAR_PREFIX))/widevine_cdm_version_h.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/renderer/widevine_key_systems.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_renderer
+cdm_renderer: components_cdm_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_renderer.target.linux-arm64.mk b/components/cdm_renderer.target.linux-arm64.mk
new file mode 100644
index 0000000..061fce3
--- /dev/null
+++ b/components/cdm_renderer.target.linux-arm64.mk
@@ -0,0 +1,268 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_widevine_cdm_widevine_cdm_version_h_gyp,,,$(GYP_VAR_PREFIX))/widevine_cdm_version_h.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/renderer/widevine_key_systems.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_renderer
+cdm_renderer: components_cdm_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_renderer.target.linux-mips.mk b/components/cdm_renderer.target.linux-mips.mk
new file mode 100644
index 0000000..f86a7e8
--- /dev/null
+++ b/components/cdm_renderer.target.linux-mips.mk
@@ -0,0 +1,280 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_widevine_cdm_widevine_cdm_version_h_gyp,,,$(GYP_VAR_PREFIX))/widevine_cdm_version_h.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/renderer/widevine_key_systems.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_renderer
+cdm_renderer: components_cdm_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_renderer.target.linux-x86.mk b/components/cdm_renderer.target.linux-x86.mk
new file mode 100644
index 0000000..a11ac0e
--- /dev/null
+++ b/components/cdm_renderer.target.linux-x86.mk
@@ -0,0 +1,280 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_widevine_cdm_widevine_cdm_version_h_gyp,,,$(GYP_VAR_PREFIX))/widevine_cdm_version_h.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/renderer/widevine_key_systems.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_renderer
+cdm_renderer: components_cdm_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/cdm_renderer.target.linux-x86_64.mk b/components/cdm_renderer.target.linux-x86_64.mk
new file mode 100644
index 0000000..46a644b
--- /dev/null
+++ b/components/cdm_renderer.target.linux-x86_64.mk
@@ -0,0 +1,280 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_cdm_renderer_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES := \
+	$(call intermediates-dir-for,GYP,third_party_widevine_cdm_widevine_cdm_version_h_gyp,,,$(GYP_VAR_PREFIX))/widevine_cdm_version_h.stamp
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/cdm/renderer/widevine_key_systems.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DLIBPEERCONNECTION_LIB=1' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(gyp_shared_intermediate_dir) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(LOCAL_PATH)/third_party/WebKit \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_cdm_renderer_gyp
+
+# Alias gyp target name.
+.PHONY: cdm_renderer
+cdm_renderer: components_cdm_renderer_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/components.gyp b/components/components.gyp
index e7b7491..47576cc 100644
--- a/components/components.gyp
+++ b/components/components.gyp
@@ -22,6 +22,7 @@
     'domain_reliability.gypi',
     'favicon.gypi',
     'favicon_base.gypi',
+    'feedback.gypi',  # crbug.com/368738
     'infobars.gypi',
     'json_schema.gypi',
     'keyed_service.gypi',
@@ -47,6 +48,7 @@
   'conditions': [
     ['OS != "ios"', {
       'includes': [
+        'cdm.gypi',
         'navigation_interception.gypi',
         'plugins.gypi',
         'sessions.gypi',
diff --git a/components/components_resources.target.darwin-arm.mk b/components/components_resources.target.darwin-arm.mk
index df25dba..06a7435 100644
--- a/components/components_resources.target.darwin-arm.mk
+++ b/components/components_resources.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 ### Rules for action "generate_components_scaled_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_resources.target.darwin-arm64.mk b/components/components_resources.target.darwin-arm64.mk
index df25dba..06a7435 100644
--- a/components/components_resources.target.darwin-arm64.mk
+++ b/components/components_resources.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 ### Rules for action "generate_components_scaled_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_resources.target.darwin-mips.mk b/components/components_resources.target.darwin-mips.mk
index df25dba..06a7435 100644
--- a/components/components_resources.target.darwin-mips.mk
+++ b/components/components_resources.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 ### Rules for action "generate_components_scaled_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_resources.target.darwin-x86.mk b/components/components_resources.target.darwin-x86.mk
index df25dba..06a7435 100644
--- a/components/components_resources.target.darwin-x86.mk
+++ b/components/components_resources.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 ### Rules for action "generate_components_scaled_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_resources.target.darwin-x86_64.mk b/components/components_resources.target.darwin-x86_64.mk
index df25dba..06a7435 100644
--- a/components/components_resources.target.darwin-x86_64.mk
+++ b/components/components_resources.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 ### Rules for action "generate_components_scaled_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_resources.target.linux-arm.mk b/components/components_resources.target.linux-arm.mk
index df25dba..06a7435 100644
--- a/components/components_resources.target.linux-arm.mk
+++ b/components/components_resources.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 ### Rules for action "generate_components_scaled_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_resources.target.linux-arm64.mk b/components/components_resources.target.linux-arm64.mk
index df25dba..06a7435 100644
--- a/components/components_resources.target.linux-arm64.mk
+++ b/components/components_resources.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 ### Rules for action "generate_components_scaled_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_resources.target.linux-mips.mk b/components/components_resources.target.linux-mips.mk
index df25dba..06a7435 100644
--- a/components/components_resources.target.linux-mips.mk
+++ b/components/components_resources.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 ### Rules for action "generate_components_scaled_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_resources.target.linux-x86.mk b/components/components_resources.target.linux-x86.mk
index df25dba..06a7435 100644
--- a/components/components_resources.target.linux-x86.mk
+++ b/components/components_resources.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 ### Rules for action "generate_components_scaled_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_resources.target.linux-x86_64.mk b/components/components_resources.target.linux-x86_64.mk
index df25dba..06a7435 100644
--- a/components/components_resources.target.linux-x86_64.mk
+++ b/components/components_resources.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 ### Rules for action "generate_components_scaled_resources":
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/grit/component_scaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_strings.target.darwin-arm.mk b/components/components_strings.target.darwin-arm.mk
index 695ba63..a053686 100644
--- a/components/components_strings.target.darwin-arm.mk
+++ b/components/components_strings.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_strings":
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_strings.target.darwin-arm64.mk b/components/components_strings.target.darwin-arm64.mk
index 695ba63..a053686 100644
--- a/components/components_strings.target.darwin-arm64.mk
+++ b/components/components_strings.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_strings":
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_strings.target.darwin-mips.mk b/components/components_strings.target.darwin-mips.mk
index 695ba63..a053686 100644
--- a/components/components_strings.target.darwin-mips.mk
+++ b/components/components_strings.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_strings":
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_strings.target.darwin-x86.mk b/components/components_strings.target.darwin-x86.mk
index 695ba63..a053686 100644
--- a/components/components_strings.target.darwin-x86.mk
+++ b/components/components_strings.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_strings":
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_strings.target.darwin-x86_64.mk b/components/components_strings.target.darwin-x86_64.mk
index 695ba63..a053686 100644
--- a/components/components_strings.target.darwin-x86_64.mk
+++ b/components/components_strings.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_strings":
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_strings.target.linux-arm.mk b/components/components_strings.target.linux-arm.mk
index 695ba63..a053686 100644
--- a/components/components_strings.target.linux-arm.mk
+++ b/components/components_strings.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_strings":
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_strings.target.linux-arm64.mk b/components/components_strings.target.linux-arm64.mk
index 695ba63..a053686 100644
--- a/components/components_strings.target.linux-arm64.mk
+++ b/components/components_strings.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_strings":
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_strings.target.linux-mips.mk b/components/components_strings.target.linux-mips.mk
index 695ba63..a053686 100644
--- a/components/components_strings.target.linux-mips.mk
+++ b/components/components_strings.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_strings":
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_strings.target.linux-x86.mk b/components/components_strings.target.linux-x86.mk
index 695ba63..a053686 100644
--- a/components/components_strings.target.linux-x86.mk
+++ b/components/components_strings.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_strings":
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_strings.target.linux-x86_64.mk b/components/components_strings.target.linux-x86_64.mk
index 695ba63..a053686 100644
--- a/components/components_strings.target.linux-x86_64.mk
+++ b/components/components_strings.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_components_strings":
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/components/strings/grit/component_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index fc31dea..ebc1d56 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -63,9 +63,13 @@
             'autofill/core/common/form_field_data_unittest.cc',
             'autofill/core/common/password_form_fill_data_unittest.cc',
             'autofill/core/common/save_password_progress_logger_unittest.cc',
+            'bookmarks/core/browser/bookmark_codec_unittest.cc',
+            'bookmarks/core/test/bookmark_index_unittest.cc',
             'captive_portal/captive_portal_detector_unittest.cc',
             'cloud_devices/common/cloud_devices_urls_unittest.cc',
             'cloud_devices/common/printer_description_unittest.cc',
+            'data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler_unittest.cc',
+            'data_reduction_proxy/browser/data_reduction_proxy_config_service_unittest.cc',
             'data_reduction_proxy/browser/data_reduction_proxy_metrics_unittest.cc',
             'data_reduction_proxy/browser/data_reduction_proxy_settings_unittest.cc',
             'data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy_unittest.cc',
@@ -88,6 +92,7 @@
             'domain_reliability/test_util.h',
             'domain_reliability/uploader_unittest.cc',
             'domain_reliability/util_unittest.cc',
+            'feedback/feedback_uploader_unittest.cc',
             'json_schema/json_schema_validator_unittest.cc',
             'json_schema/json_schema_validator_unittest_base.cc',
             'json_schema/json_schema_validator_unittest_base.h',
@@ -95,6 +100,8 @@
             'keyed_service/core/dependency_graph_unittest.cc',
             'language_usage_metrics/language_usage_metrics_unittest.cc',
             'metrics/metrics_hashes_unittest.cc',
+            'metrics/metrics_log_base_unittest.cc',
+            'metrics/metrics_log_manager_unittest.cc',
             'navigation_interception/intercept_navigation_resource_throttle_unittest.cc',
             'os_crypt/ie7_password_win_unittest.cc',
             'os_crypt/keychain_password_mac_unittest.mm',
@@ -194,6 +201,10 @@
             'components_strings.gyp:components_strings',
             '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber',
 
+            # Dependencies of bookmarks
+            'components.gyp:bookmarks_core_browser',
+            'components.gyp:bookmarks_core_test_support',
+            
             # Dependencies of captive_portal
             'components.gyp:captive_portal_test_support',
             '../net/net.gyp:net_test_support',
@@ -214,6 +225,9 @@
             # Dependencies of domain_reliability
             'components.gyp:domain_reliability',
 
+            # Dependencies of feedback
+            'components.gyp:feedback_component',
+
             # Dependencies of json_schema
             'components.gyp:json_schema',
 
@@ -319,6 +333,8 @@
                 ['include', '^test/run_all_unittests\\.cc$'],
                 ['include', '^auto_login_parser/'],
                 ['include', '^autofill/core/'],
+                ['include', '^bookmarks/'],
+                ['include', '^data_reduction_proxy/'],
                 ['include', '^dom_distiller/'],
                 ['include', '^json_schema/'],
                 ['include', '^keyed_service/core/'],
@@ -434,8 +450,7 @@
                 '../base/allocator/allocator.gyp:allocator',
               ],
             }],
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['OS=="linux" and component=="shared_library" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+            ['OS=="linux" and component=="shared_library" and use_allocator!="none"', {
             'dependencies': [
                 '<(DEPTH)/base/allocator/allocator.gyp:allocator',
             ],
@@ -605,7 +620,6 @@
             '../skia/skia.gyp:skia',
             '../testing/gmock.gyp:gmock',
             '../testing/gtest.gyp:gtest',
-            '../testing/gmock.gyp:gmock',
           ],
           'include_dirs': [
             '..',
diff --git a/components/cronet.gypi b/components/cronet.gypi
index 4c60803..d749c8e 100644
--- a/components/cronet.gypi
+++ b/components/cronet.gypi
@@ -133,9 +133,11 @@
           ],
           'copies': [
             {
-              'destination': '<(package_dir)',
+              'destination': '<(package_dir)/libs',
               'files': [
                 '<(PRODUCT_DIR)/lib.java/<(java_lib)',
+                '<(PRODUCT_DIR)/lib.java/base_java.jar',
+                '<(PRODUCT_DIR)/lib.java/net_java.jar',
               ],
             },
           ],
diff --git a/components/cronet/android/cronet_jni.cc b/components/cronet/android/cronet_jni.cc
index c4fef7c..6a370a3 100644
--- a/components/cronet/android/cronet_jni.cc
+++ b/components/cronet/android/cronet_jni.cc
@@ -10,19 +10,20 @@
 #include "components/cronet/android/org_chromium_net_UrlRequest.h"
 #include "components/cronet/android/org_chromium_net_UrlRequestContext.h"
 #include "net/android/net_jni_registrar.h"
+#include "url/android/url_jni_registrar.h"
 
 namespace {
 
 const base::android::RegistrationMethod kCronetRegisteredMethods[] = {
-    {"BaseAndroid", base::android::RegisterJni},
-    {"NetAndroid", net::android::RegisterJni},
-    {"UrlRequest", cronet::UrlRequestRegisterJni},
-    {"UrlRequestContext", cronet::UrlRequestContextRegisterJni},
+  {"BaseAndroid", base::android::RegisterJni},
+  {"NetAndroid", net::android::RegisterJni},
+  {"UrlAndroid", url::android::RegisterJni},
+  {"UrlRequest", cronet::UrlRequestRegisterJni},
+  {"UrlRequestContext", cronet::UrlRequestContextRegisterJni},
 };
 
 base::AtExitManager* g_at_exit_manager = NULL;
 
-
 }  // namespace
 
 // Checks the available version of JNI. Also, caches Java reflection artifacts.
diff --git a/components/cronet/android/org_chromium_net_UrlRequest.cc b/components/cronet/android/org_chromium_net_UrlRequest.cc
index 7e3d35f..7d3cf6b 100644
--- a/components/cronet/android/org_chromium_net_UrlRequest.cc
+++ b/components/cronet/android/org_chromium_net_UrlRequest.cc
@@ -5,6 +5,7 @@
 #include "components/cronet/android/org_chromium_net_UrlRequest.h"
 
 #include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
 #include "base/macros.h"
 #include "components/cronet/android/url_request_context_peer.h"
 #include "components/cronet/android/url_request_peer.h"
@@ -12,6 +13,8 @@
 #include "net/base/net_errors.h"
 #include "net/base/request_priority.h"
 
+using base::android::ConvertUTF8ToJavaString;
+
 namespace cronet {
 namespace {
 
@@ -263,7 +266,7 @@
            "System error: %s(%d)",
            net::ErrorToString(error_code),
            error_code);
-  return env->NewStringUTF(buffer);
+  return ConvertUTF8ToJavaString(env, buffer).Release();
 }
 
 static jint GetHttpStatusCode(JNIEnv* env,
@@ -282,7 +285,7 @@
   }
   std::string type = request->content_type();
   if (!type.empty()) {
-    return env->NewStringUTF(type.c_str());
+    return ConvertUTF8ToJavaString(env, type.c_str()).Release();
   } else {
     return NULL;
   }
diff --git a/components/cronet/android/org_chromium_net_UrlRequestContext.cc b/components/cronet/android/org_chromium_net_UrlRequestContext.cc
index 2beaeeb..38b6e81 100644
--- a/components/cronet/android/org_chromium_net_UrlRequestContext.cc
+++ b/components/cronet/android/org_chromium_net_UrlRequestContext.cc
@@ -55,7 +55,7 @@
 }
 
 static jstring GetVersion(JNIEnv* env, jclass unused) {
-  return env->NewStringUTF(kVersion);
+  return base::android::ConvertUTF8ToJavaString(env, kVersion).Release();
 }
 
 // Sets global user-agent to be used for all subsequent requests.
diff --git a/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java b/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java
index f24fbed..f667037 100644
--- a/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java
+++ b/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleActivity.java
@@ -9,6 +9,7 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.Environment;
 import android.util.Log;
 import android.widget.EditText;
 import android.widget.Toast;
@@ -223,7 +224,8 @@
     }
 
     public void startNetLog() {
-        mRequestContext.startNetLogToFile("/sdcard/cronet_sample_netlog.json");
+        mRequestContext.startNetLogToFile(
+                Environment.getExternalStorageDirectory().getPath() + "/cronet_sample_netlog.json");
     }
 
     public void stopNetLog() {
diff --git a/components/data_reduction_proxy.gypi b/components/data_reduction_proxy.gypi
index ed6e878..869ef06 100644
--- a/components/data_reduction_proxy.gypi
+++ b/components/data_reduction_proxy.gypi
@@ -18,9 +18,15 @@
         '..',
       ],
       'sources': [
+        'data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc',
+        'data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h',
+        'data_reduction_proxy/browser/data_reduction_proxy_config_service.cc',
+        'data_reduction_proxy/browser/data_reduction_proxy_config_service.h',
         'data_reduction_proxy/browser/data_reduction_proxy_configurator.h',
         'data_reduction_proxy/browser/data_reduction_proxy_metrics.cc',
         'data_reduction_proxy/browser/data_reduction_proxy_metrics.h',
+        'data_reduction_proxy/browser/data_reduction_proxy_prefs.cc',
+        'data_reduction_proxy/browser/data_reduction_proxy_prefs.h',
         'data_reduction_proxy/browser/data_reduction_proxy_settings.cc',
         'data_reduction_proxy/browser/data_reduction_proxy_settings.h',
         'data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc',
@@ -32,6 +38,7 @@
       'type': 'static_library',
       'dependencies': [
         '../base/base.gyp:base',
+        '../components/components.gyp:user_prefs',
       ],
       'include_dirs': [
         '..',
diff --git a/components/data_reduction_proxy/DEPS b/components/data_reduction_proxy/DEPS
index a9486c4..bfc9d61 100644
--- a/components/data_reduction_proxy/DEPS
+++ b/components/data_reduction_proxy/DEPS
@@ -1,6 +1,5 @@
 include_rules = [
+  "+components/user_prefs",
   "+crypto",
   "+net",
-  # Data reduction proxy is used by iOS, which does not use content.
-  "-content",
 ]
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc
new file mode 100644
index 0000000..04665fb
--- /dev/null
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc
@@ -0,0 +1,118 @@
+// 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.
+
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h"
+#include "net/base/auth.h"
+
+namespace {
+// The minimum interval allowed, in milliseconds, between data reduction proxy
+// auth requests.
+const int64 kMinAuthRequestIntervalMs = 500;
+
+// The minimum interval allowed, in milliseconds, between data reduction proxy
+// auth token invalidation.
+const int64 kMinTokenInvalidationIntervalMs = 60 * 60 * 1000;
+
+// The maximum number of data reduction proxy authentication failures to
+// accept before giving up.
+const int kMaxBackToBackFailures = 5;
+}
+
+namespace data_reduction_proxy {
+
+int64 DataReductionProxyAuthRequestHandler::auth_request_timestamp_ = 0;
+
+int DataReductionProxyAuthRequestHandler::back_to_back_failure_count_ = 0;
+
+int64
+DataReductionProxyAuthRequestHandler::auth_token_invalidation_timestamp_ = 0;
+
+
+DataReductionProxyAuthRequestHandler::DataReductionProxyAuthRequestHandler() {
+}
+
+DataReductionProxyAuthRequestHandler::~DataReductionProxyAuthRequestHandler() {
+}
+
+DataReductionProxyAuthRequestHandler::TryHandleResult
+DataReductionProxyAuthRequestHandler::TryHandleAuthentication(
+    net::AuthChallengeInfo* auth_info,
+    base::string16* user,
+    base::string16* password) {
+  if (!auth_info) {
+    return TRY_HANDLE_RESULT_IGNORE;
+  }
+  DCHECK(user);
+  DCHECK(password);
+
+  if (!IsAcceptableAuthChallenge(auth_info)) {
+    *user = base::string16();
+    *password = base::string16();
+    return TRY_HANDLE_RESULT_IGNORE;
+  }
+
+  base::TimeTicks auth_request =
+      base::TimeTicks::FromInternalValue(auth_request_timestamp_);
+  base::TimeTicks auth_token_invalidation =
+      base::TimeTicks::FromInternalValue(auth_token_invalidation_timestamp_);
+
+
+  base::TimeTicks now = Now();
+  if ((now - auth_request).InMilliseconds() < kMinAuthRequestIntervalMs) {
+    // We've received back-to-back failures. There are two possibilities:
+    // 1) Our auth token has expired and we should invalidate it, or
+    // 2) We're receiving spurious failures from the service.
+    //
+    // If we haven't recently invalidated our token, we do that here
+    // and make several attempts to authenticate. Otherwise, we fail.
+    back_to_back_failure_count_++;
+    if ((now - auth_token_invalidation).InMilliseconds() <
+        kMinTokenInvalidationIntervalMs) {
+      auth_token_invalidation_timestamp_ = now.ToInternalValue();
+      back_to_back_failure_count_ = 0;
+    } else {
+      if (back_to_back_failure_count_ > kMaxBackToBackFailures) {
+        DLOG(WARNING) << "Interpreting frequent data reduction proxy auth "
+            << "requests as an authorization failure.";
+        back_to_back_failure_count_ = 0;
+        *user = base::string16();
+        *password = base::string16();
+        return TRY_HANDLE_RESULT_CANCEL;
+      }
+    }
+  } else {
+    back_to_back_failure_count_ = 0;
+  }
+  auth_request_timestamp_ = now.ToInternalValue();
+
+  *password = GetTokenForAuthChallenge(auth_info);
+
+  if (*password == base::string16()) {
+    *user = base::string16();
+    DLOG(WARNING) << "Data reduction proxy auth produced null token.";
+    return TRY_HANDLE_RESULT_CANCEL;
+  }
+  *user = base::UTF8ToUTF16("fw-cookie");
+  return TRY_HANDLE_RESULT_PROCEED;
+}
+
+bool DataReductionProxyAuthRequestHandler::IsAcceptableAuthChallenge(
+    net::AuthChallengeInfo* auth_info) {
+  return DataReductionProxySettings::IsAcceptableAuthChallenge(auth_info);
+}
+
+base::string16 DataReductionProxyAuthRequestHandler::GetTokenForAuthChallenge(
+    net::AuthChallengeInfo* auth_info) {
+  return DataReductionProxySettings::GetTokenForAuthChallenge(auth_info);
+}
+
+base::TimeTicks DataReductionProxyAuthRequestHandler::Now() {
+  return base::TimeTicks::Now();
+}
+
+}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h b/components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h
new file mode 100644
index 0000000..4de3757
--- /dev/null
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h
@@ -0,0 +1,72 @@
+// 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.
+
+#ifndef COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_AUTH_REQUEST_HANDLER_H_
+#define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_AUTH_REQUEST_HANDLER_H_
+
+#include "base/gtest_prod_util.h"
+#include "base/strings/string16.h"
+#include "base/time/time.h"
+
+namespace net {
+class AuthChallengeInfo;
+}
+
+namespace data_reduction_proxy {
+
+class DataReductionProxyAuthRequestHandler {
+ public:
+  enum TryHandleResult {
+    TRY_HANDLE_RESULT_IGNORE,
+    TRY_HANDLE_RESULT_PROCEED,
+    TRY_HANDLE_RESULT_CANCEL
+  };
+
+  DataReductionProxyAuthRequestHandler();
+  virtual ~DataReductionProxyAuthRequestHandler();
+
+  // Returns |PROCEED| if the authentication challenge provided is one that the
+  // data reduction proxy should handle and |IGNORE| if not. Returns |CANCEL| if
+  // there are a string of |MAX_BACK_TO_BACK_FAILURES| successive retries.
+  TryHandleResult TryHandleAuthentication(net::AuthChallengeInfo* auth_info,
+                                          base::string16* user,
+                                          base::string16* password);
+
+ protected:
+  // Visible for testing.
+  virtual bool IsAcceptableAuthChallenge(net::AuthChallengeInfo* auth_info);
+
+  // Visible for testing.
+  virtual base::string16 GetTokenForAuthChallenge(
+      net::AuthChallengeInfo* auth_info);
+
+  // Visible for testing.
+  virtual base::TimeTicks Now();
+
+ private:
+  FRIEND_TEST_ALL_PREFIXES(DataReductionProxyAuthRequestHandlerTest,
+                           CancelAfterSuccessiveAuthAttempts);
+
+
+
+  // System timestamp of the last data reduction proxy authentication request.
+  // This is used to cancel data reduction proxy auth requests that are denied
+  // rather than loop forever trying a rejected token.
+  static int64 auth_request_timestamp_;
+
+  // The number of back to back data reduction proxy authentication failures
+  // that occurred with no more than |MIN_AUTH_REQUEST_INTERVAL_MS| between each
+  // adjacent pair of them.
+  static int back_to_back_failure_count_;
+
+  // System timestamp of the last data reduction proxy auth token invalidation.
+  // This is used to expire old tokens on back-to-back failures, and distinguish
+  // invalidation from repeat failures due to the client not being authorized.
+  static int64 auth_token_invalidation_timestamp_;
+
+  DISALLOW_COPY_AND_ASSIGN(DataReductionProxyAuthRequestHandler);
+};
+
+}  // namespace data_reduction_proxy
+#endif  // COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_AUTH_REQUEST_HANDLER_H_
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler_unittest.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler_unittest.cc
new file mode 100644
index 0000000..19c6dee
--- /dev/null
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler_unittest.cc
@@ -0,0 +1,147 @@
+// 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.
+
+
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h"
+
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
+#include "net/base/auth.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace data_reduction_proxy {
+
+namespace {
+
+const char kInvalidTestRealm[] = "invalid-test-realm";
+const char kTestChallenger[] = "https://test-challenger.com:443";
+const char kTestRealm[] = "test-realm";
+const char kTestToken[] = "test-token";
+const char kTestUser[] = "fw-cookie";
+
+}  // namespace
+
+// Test class that overrides underlying calls to see if an auth challenge is
+// acceptible for the data reduction proxy, and to get a valid token if so.
+class TestDataReductionProxyAuthRequestHandler
+    : public DataReductionProxyAuthRequestHandler {
+ public:
+  TestDataReductionProxyAuthRequestHandler(int time_step_ms,
+                                           int64 initial_time_ms)
+      : time_step_ms_(time_step_ms),
+        now_(base::TimeTicks() +
+             base::TimeDelta::FromMilliseconds(initial_time_ms)) {}
+ protected:
+  // Test implementation.
+  virtual bool IsAcceptableAuthChallenge(
+      net::AuthChallengeInfo* auth_info) OVERRIDE {
+    if (net::HostPortPair::FromString(
+        kTestChallenger).Equals(auth_info->challenger) &&
+        auth_info->realm == kTestRealm) {
+    return true;
+    }
+    return false;
+  }
+
+  // Test implementation.
+  virtual base::string16 GetTokenForAuthChallenge(
+      net::AuthChallengeInfo* auth_info) OVERRIDE {
+    return base::ASCIIToUTF16(kTestToken);
+  }
+
+  virtual base::TimeTicks Now() OVERRIDE {
+    now_ += base::TimeDelta::FromMilliseconds(time_step_ms_);
+    return now_;
+  }
+  int time_step_ms_;
+  base::TimeTicks now_;
+};
+
+class DataReductionProxyAuthRequestHandlerTest : public testing::Test {
+ public:
+  // Checks that |PROCEED| was returned with expected user and password.
+  void ExpectProceed(
+      DataReductionProxyAuthRequestHandler::TryHandleResult result,
+      const base::string16& user,
+      const base::string16& password) {
+    base::string16 expected_user = base::ASCIIToUTF16(kTestUser);
+    base::string16 expected_password = base::ASCIIToUTF16(kTestToken);
+    EXPECT_EQ(DataReductionProxyAuthRequestHandler::TRY_HANDLE_RESULT_PROCEED,
+              result);
+    EXPECT_EQ(expected_user, user);
+    EXPECT_EQ(expected_password, password);
+  }
+
+  // Checks that |CANCEL| was returned.
+  void ExpectCancel(
+      DataReductionProxyAuthRequestHandler::TryHandleResult result,
+      const base::string16& user,
+      const base::string16& password) {
+    EXPECT_EQ(DataReductionProxyAuthRequestHandler::TRY_HANDLE_RESULT_CANCEL,
+              result);
+    EXPECT_EQ(base::string16(), user);
+    EXPECT_EQ(base::string16(), password);
+  }
+
+  // Checks that |IGNORE| was returned.
+  void ExpectIgnore(
+      DataReductionProxyAuthRequestHandler::TryHandleResult result,
+      const base::string16& user,
+      const base::string16& password) {
+    EXPECT_EQ(DataReductionProxyAuthRequestHandler::TRY_HANDLE_RESULT_IGNORE,
+              result);
+    EXPECT_EQ(base::string16(), user);
+    EXPECT_EQ(base::string16(), password);
+  }
+};
+
+TEST_F(DataReductionProxyAuthRequestHandlerTest,
+       CancelAfterSuccessiveAuthAttempts) {
+  DataReductionProxyAuthRequestHandler::auth_request_timestamp_ = 0;
+  DataReductionProxyAuthRequestHandler::back_to_back_failure_count_ = 0;
+  DataReductionProxyAuthRequestHandler::auth_token_invalidation_timestamp_ = 0;
+  scoped_refptr<net::AuthChallengeInfo> auth_info(new net::AuthChallengeInfo);
+  auth_info->realm =  kTestRealm;
+  auth_info->challenger = net::HostPortPair::FromString(kTestChallenger);
+  TestDataReductionProxyAuthRequestHandler handler(499, 3600001);
+  base::string16 user, password;
+  DataReductionProxyAuthRequestHandler::TryHandleResult result =
+      handler.TryHandleAuthentication(auth_info.get(), &user, &password);
+  ExpectProceed(result, user, password);
+
+  // Successive retries should also succeed up to a maximum count.
+  for (int i = 0; i < 5; ++i) {
+    user = base::string16();
+    password = base::string16();
+    result = handler.TryHandleAuthentication(auth_info.get(), &user, &password);
+    ExpectProceed(result, user, password);
+  }
+
+  // Then another retry should fail.
+  user = base::string16();
+  password = base::string16();
+  result = handler.TryHandleAuthentication(auth_info.get(), &user, &password);
+  ExpectCancel(result, user, password);
+
+  // After canceling, the next one should proceed.
+  user = base::string16();
+  password = base::string16();
+  result = handler.TryHandleAuthentication(auth_info.get(), &user, &password);
+  ExpectProceed(result, user, password);
+}
+
+TEST_F(DataReductionProxyAuthRequestHandlerTest, Ignore) {
+  scoped_refptr<net::AuthChallengeInfo> auth_info(new net::AuthChallengeInfo);
+  auth_info->realm =  kInvalidTestRealm;
+  auth_info->challenger = net::HostPortPair::FromString(kTestChallenger);
+  TestDataReductionProxyAuthRequestHandler handler(100, 3600001);
+  base::string16 user, password;
+  DataReductionProxyAuthRequestHandler::TryHandleResult result =
+      handler.TryHandleAuthentication(auth_info.get(), &user, &password);
+  ExpectIgnore(result, user, password);
+}
+
+}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc
new file mode 100644
index 0000000..84b2e56
--- /dev/null
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc
@@ -0,0 +1,198 @@
+// 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.
+
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h"
+
+#include "base/bind.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/string_util.h"
+
+namespace data_reduction_proxy {
+
+DataReductionProxyConfigService::DataReductionProxyConfigService(
+    scoped_ptr<net::ProxyConfigService> base_service)
+    : config_read_pending_(true),
+      registered_observer_(false),
+      enabled_(false),
+      restricted_(false) {
+  base_service_ = base_service.Pass();
+}
+
+DataReductionProxyConfigService::~DataReductionProxyConfigService() {
+  if (registered_observer_ && base_service_.get())
+    base_service_->RemoveObserver(this);
+}
+
+void DataReductionProxyConfigService::AddObserver(
+    net::ProxyConfigService::Observer* observer) {
+  RegisterObserver();
+  observers_.AddObserver(observer);
+}
+
+void DataReductionProxyConfigService::RemoveObserver(
+    net::ProxyConfigService::Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+net::ProxyConfigService::ConfigAvailability
+DataReductionProxyConfigService::GetLatestProxyConfig(
+    net::ProxyConfig* config) {
+  RegisterObserver();
+
+  if (enabled_) {
+    *config = config_;
+    return net::ProxyConfigService::CONFIG_VALID;
+  }
+
+  // Ask the base service if available.
+  net::ProxyConfig system_config;
+  ConfigAvailability system_availability =
+      net::ProxyConfigService::CONFIG_UNSET;
+  if (base_service_.get()) {
+    system_availability = base_service_->GetLatestProxyConfig(&system_config);
+    *config = system_config;
+  }
+  if (system_availability == net::ProxyConfigService::CONFIG_UNSET) {
+    *config = net::ProxyConfig::CreateDirect();
+  }
+
+  return net::ProxyConfigService::CONFIG_VALID;
+}
+
+void DataReductionProxyConfigService::OnLazyPoll() {
+  if (base_service_.get())
+    base_service_->OnLazyPoll();
+}
+
+void DataReductionProxyConfigService::UpdateProxyConfig(
+    bool enabled,
+    const net::ProxyConfig& config) {
+
+  config_read_pending_ = false;
+  enabled_ = enabled;
+  config_ = config;
+
+  if (!observers_.might_have_observers())
+    return;
+
+  // Evaluate the proxy configuration. If GetLatestProxyConfig returns
+  // CONFIG_PENDING, we are using the system proxy service, but it doesn't have
+  // a valid configuration yet. Once it is ready, OnProxyConfigChanged() will be
+  // called and broadcast the proxy configuration.
+  // Note: If a switch between a preference proxy configuration and the system
+  // proxy configuration occurs an unnecessary notification might get sent if
+  // the two configurations agree. This case should be rare however, so we don't
+  // handle that case specially.
+  net::ProxyConfig new_config;
+  ConfigAvailability availability = GetLatestProxyConfig(&new_config);
+  if (availability != CONFIG_PENDING) {
+    FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
+                      OnProxyConfigChanged(new_config, availability));
+  }
+}
+
+void DataReductionProxyConfigService::OnProxyConfigChanged(
+    const net::ProxyConfig& config,
+    ConfigAvailability availability) {
+
+  // Check whether the data reduction proxy is enabled. In this case that proxy
+  // configuration takes precedence and the change event from the delegate proxy
+  // service can be disregarded.
+  if (!enabled_) {
+    net::ProxyConfig actual_config;
+    availability = GetLatestProxyConfig(&actual_config);
+    FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
+                      OnProxyConfigChanged(actual_config, availability));
+  }
+}
+
+void DataReductionProxyConfigService::RegisterObserver() {
+  if (!registered_observer_ && base_service_.get()) {
+    base_service_->AddObserver(this);
+    registered_observer_ = true;
+  }
+}
+
+DataReductionProxyConfigTracker::DataReductionProxyConfigTracker(
+    DataReductionProxyConfigService* config_service,
+    base::TaskRunner* task_runner)
+    : config_service_(config_service),
+      task_runner_(task_runner) {
+  DCHECK(config_service);
+}
+
+DataReductionProxyConfigTracker::~DataReductionProxyConfigTracker() {
+}
+
+void DataReductionProxyConfigTracker::Enable(
+    bool primary_restricted,
+    bool fallback_restricted,
+    const std::string& primary_origin,
+    const std::string& fallback_origin) {
+
+  std::vector<std::string> proxies;
+  if (!primary_restricted) {
+    std::string trimmed_primary;
+    base::TrimString(primary_origin, "/", &trimmed_primary);
+    if (!trimmed_primary.empty())
+      proxies.push_back(trimmed_primary);
+  }
+  if (!fallback_restricted) {
+    std::string trimmed_fallback;
+    base::TrimString(fallback_origin, "/", &trimmed_fallback);
+    if (!trimmed_fallback.empty())
+      proxies.push_back(trimmed_fallback);
+  }
+  if (proxies.empty()) {
+    std::string mode;
+    Disable();
+    return;
+  }
+
+  net::ProxyConfig config;
+  config.proxy_rules().ParseFromString(
+      "http=" + JoinString(proxies, ",") + ",direct://;");
+  config.proxy_rules().bypass_rules.ParseFromString(
+      JoinString(bypass_rules_, ", "));
+  UpdateProxyConfigOnIOThread(true, config);
+}
+
+
+void DataReductionProxyConfigTracker::Disable() {
+  net::ProxyConfig config = net::ProxyConfig::CreateDirect();
+  UpdateProxyConfigOnIOThread(false, config);
+}
+
+void DataReductionProxyConfigTracker::AddHostPatternToBypass(
+    const std::string& pattern) {
+  bypass_rules_.push_back(pattern);
+}
+
+void DataReductionProxyConfigTracker::AddURLPatternToBypass(
+    const std::string& pattern) {
+  size_t pos = pattern.find("/");
+  if (pattern.find("/", pos + 1) == pos + 1)
+    pos = pattern.find("/", pos + 2);
+
+  std::string host_pattern;
+  if (pos != std::string::npos)
+    host_pattern = pattern.substr(0, pos);
+  else
+    host_pattern = pattern;
+
+  AddHostPatternToBypass(host_pattern);
+}
+
+void DataReductionProxyConfigTracker::UpdateProxyConfigOnIOThread(
+    bool enabled,
+    const net::ProxyConfig& config) {
+  task_runner_->PostTask(FROM_HERE,
+      base::Bind(
+          &DataReductionProxyConfigService::UpdateProxyConfig,
+          base::Unretained(config_service_),
+          enabled, config));
+}
+
+}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h b/components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h
new file mode 100644
index 0000000..28e80e1
--- /dev/null
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h
@@ -0,0 +1,126 @@
+// 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.
+
+#ifndef COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_CONFIG_SERVICE_H_
+#define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_CONFIG_SERVICE_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
+#include "base/task_runner.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service.h"
+
+class PrefService;
+
+namespace net {
+class ProxyConfig;
+}
+
+namespace data_reduction_proxy {
+
+// A net::ProxyConfigService implementation that applies data reduction proxy
+// settings as overrides to the proxy configuration determined by a
+// baseline delegate ProxyConfigService.
+class DataReductionProxyConfigService
+    : public net::ProxyConfigService,
+      public net::ProxyConfigService::Observer {
+ public:
+  // Takes ownership of the passed |base_service|.
+  DataReductionProxyConfigService(
+      scoped_ptr<net::ProxyConfigService> base_service);
+  virtual ~DataReductionProxyConfigService();
+
+  // ProxyConfigService implementation:
+  virtual void AddObserver(
+      net::ProxyConfigService::Observer* observer) OVERRIDE;
+  virtual void RemoveObserver(
+      net::ProxyConfigService::Observer* observer) OVERRIDE;
+  virtual ConfigAvailability GetLatestProxyConfig(
+      net::ProxyConfig* config) OVERRIDE;
+  virtual void OnLazyPoll() OVERRIDE;
+
+  // Method on IO thread that receives the data reduction proxy settings pushed
+  // from DataReductionProxyConfiguratorImpl.
+  void UpdateProxyConfig(bool enabled,
+                         const net::ProxyConfig& config);
+
+ private:
+  friend class DataReductionProxyConfigServiceTest;
+
+  // ProxyConfigService::Observer implementation:
+  virtual void OnProxyConfigChanged(const net::ProxyConfig& config,
+                                    ConfigAvailability availability) OVERRIDE;
+
+  // Makes sure that the observer registration with the base service is set up.
+  void RegisterObserver();
+
+  scoped_ptr<net::ProxyConfigService> base_service_;
+  ObserverList<net::ProxyConfigService::Observer, true> observers_;
+
+  // Configuration as defined by the data reduction proxy.
+  net::ProxyConfig config_;
+
+  // Flag that indicates that a PrefProxyConfigTracker needs to inform us
+  // about a proxy configuration before we may return any configuration.
+  bool config_read_pending_;
+
+  // Indicates whether the base service registration is done.
+  bool registered_observer_;
+
+  // The data reduction proxy is enabled.
+  bool enabled_;
+
+  // Use of the data reduction proxy is restricted to HTTP proxying only.
+  bool restricted_;
+
+  DISALLOW_COPY_AND_ASSIGN(DataReductionProxyConfigService);
+};
+
+// A data_reduction_proxy::DataReductionProxyConfigurator implementation that
+// tracks changes to the data reduction proxy configuration and notifies an
+// associated DataReductionProxyConfigService. Configuration changes include
+// adding URL and host patterns to bypass and enabling and disabling use of the
+// proxy.
+class DataReductionProxyConfigTracker : public DataReductionProxyConfigurator {
+ public:
+  DataReductionProxyConfigTracker(
+      DataReductionProxyConfigService* config_service,
+      base::TaskRunner* task_runner);
+  virtual ~DataReductionProxyConfigTracker();
+
+  virtual void Enable(bool primary_restricted,
+                      bool fallback_restricted,
+                      const std::string& primary_origin,
+                      const std::string& fallback_origin) OVERRIDE;
+  virtual void Disable() OVERRIDE;
+  virtual void AddHostPatternToBypass(const std::string& pattern) OVERRIDE;
+  virtual void AddURLPatternToBypass(const std::string& pattern) OVERRIDE;
+
+ private:
+  FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigServiceTest,
+                           TrackerEnable);
+  FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigServiceTest,
+                           TrackerRestricted);
+  FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigServiceTest,
+                           TrackerBypassList);
+
+  void UpdateProxyConfigOnIOThread(bool enabled,
+                                   const net::ProxyConfig& config);
+
+  DataReductionProxyConfigService* config_service_;
+  std::vector<std::string> bypass_rules_;
+  scoped_refptr<base::TaskRunner> task_runner_;
+
+  DISALLOW_COPY_AND_ASSIGN(DataReductionProxyConfigTracker);
+};
+
+}  //  namespace data_reduction_proxy
+
+#endif  // COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_CONFIG_SERVICE_H_
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_config_service_unittest.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_config_service_unittest.cc
new file mode 100644
index 0000000..657308a
--- /dev/null
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_config_service_unittest.cc
@@ -0,0 +1,293 @@
+// 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.
+
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h"
+
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/test/test_simple_task_runner.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::Mock;
+
+namespace {
+
+// Test system proxy rules.
+static const char kSystemProxyRules[] = "http=http://system.com:80,direct://";
+
+// Test data reduction proxy rules.
+static const char kDataReductionProxyRules[] =
+    "http=https://foo.com:443,http://bar.com:80,direct://";
+
+// Test data reduction proxy rules when in restricted mode.
+static const char kDataReductionProxyRestrictedRules[] =
+    "http=http://bar.com:80,direct://";
+
+}  // namespace
+
+namespace data_reduction_proxy {
+
+class TestProxyConfigService : public net::ProxyConfigService {
+ public:
+  TestProxyConfigService()
+      : availability_(net::ProxyConfigService::CONFIG_VALID) {
+    config_.proxy_rules().ParseFromString(kSystemProxyRules);
+  }
+
+  void SetProxyConfig(const net::ProxyConfig config,
+                      ConfigAvailability availability) {
+    config_ = config;
+    availability_ = availability;
+    FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
+                      OnProxyConfigChanged(config, availability));
+  }
+
+  virtual void AddObserver(
+      net::ProxyConfigService::Observer* observer) OVERRIDE {
+    observers_.AddObserver(observer);
+  }
+
+  virtual void RemoveObserver(
+      net::ProxyConfigService::Observer* observer) OVERRIDE {
+    observers_.RemoveObserver(observer);
+  }
+
+  virtual ConfigAvailability GetLatestProxyConfig(
+      net::ProxyConfig* config) OVERRIDE {
+    *config = config_;
+    return availability_;
+  }
+
+ private:
+  net::ProxyConfig config_;
+  ConfigAvailability availability_;
+  ObserverList<net::ProxyConfigService::Observer, true> observers_;
+};
+
+
+// A mock observer for capturing callbacks.
+class MockObserver : public net::ProxyConfigService::Observer {
+ public:
+  MOCK_METHOD2(OnProxyConfigChanged,
+               void(const net::ProxyConfig&,
+                    net::ProxyConfigService::ConfigAvailability));
+};
+
+
+class DataReductionProxyConfigServiceTest : public testing::Test {
+ public:
+  virtual void SetUp() {
+    observer_.reset(new MockObserver());
+    base_service_ = new TestProxyConfigService();
+    scoped_ptr<net::ProxyConfigService> base_service(base_service_);
+    config_service_.reset(
+        new DataReductionProxyConfigService(base_service.Pass()));
+  }
+
+  void EnableDataReductionProxy(bool data_reduction_proxy_enabled) {
+    config_service_->enabled_ = data_reduction_proxy_enabled;
+    config_service_->config_.proxy_rules().ParseFromString(
+        kDataReductionProxyRules);
+  }
+
+  scoped_ptr<net::ProxyConfigService::Observer> observer_;
+
+  // Holds a weak pointer to the base service. Ownership is passed to
+  // |config_service_|.
+  TestProxyConfigService* base_service_;
+
+  scoped_ptr<DataReductionProxyConfigService> config_service_;
+};
+
+// Compares proxy configurations, but allows different identifiers.
+MATCHER_P(ProxyConfigMatches, config, "") {
+  net::ProxyConfig reference(config);
+  reference.set_id(arg.id());
+  return reference.Equals(arg);
+}
+
+TEST_F(DataReductionProxyConfigServiceTest, GetLatestProxyConfigEnabled) {
+  // Set up the |config_service_| as though Enable had been previously called
+  // and check that |GetLatestProxyConfigEnabled| return rules for the data
+  // reduction proxy.
+  EnableDataReductionProxy(true);
+  net::ProxyConfig::ProxyRules expected_rules;
+  expected_rules.ParseFromString(kDataReductionProxyRules);
+  net::ProxyConfig latest_config;
+  EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
+            config_service_->GetLatestProxyConfig(&latest_config));
+  ASSERT_TRUE(latest_config.proxy_rules().Equals(expected_rules));
+}
+
+TEST_F(DataReductionProxyConfigServiceTest, GetLatestProxyConfigDisabledValid) {
+  // Set up the |config_service_| with the data reduction proxy disabled and
+  // check that the underlying system config is returned.
+  EnableDataReductionProxy(false);
+  net::ProxyConfig::ProxyRules expected_rules;
+  expected_rules.ParseFromString(kSystemProxyRules);
+  net::ProxyConfig latest_config;
+  EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
+            config_service_->GetLatestProxyConfig(&latest_config));
+  ASSERT_TRUE(latest_config.proxy_rules().Equals(expected_rules));
+}
+
+TEST_F(DataReductionProxyConfigServiceTest, GetLatestProxyConfigDisabledUnset) {
+  // Set up the |config_service_| with the data reduction proxy disabled and
+  // check that direct is returned if the the underlying system config is unset.
+  EnableDataReductionProxy(false);
+  base_service_->SetProxyConfig(net::ProxyConfig(),
+                                net::ProxyConfigService::CONFIG_UNSET);
+  net::ProxyConfig latest_config;
+  EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
+            config_service_->GetLatestProxyConfig(&latest_config));
+  ASSERT_TRUE(latest_config.Equals(net::ProxyConfig()));
+}
+
+TEST_F(DataReductionProxyConfigServiceTest, UpdateProxyConfig) {
+  MockObserver observer;
+  base::MessageLoopForUI loop;
+  config_service_->AddObserver(&observer);
+  // Firing the observers in the delegate should trigger a notification.
+  net::ProxyConfig config2;
+  config2.set_auto_detect(true);
+  EXPECT_CALL(observer, OnProxyConfigChanged(
+      ProxyConfigMatches(config2),
+      net::ProxyConfigService::CONFIG_VALID)).Times(1);
+  base_service_->SetProxyConfig(config2, net::ProxyConfigService::CONFIG_VALID);
+  loop.RunUntilIdle();
+  Mock::VerifyAndClearExpectations(&observer);
+
+  // Enable the data reduction proxy, which should trigger a notification.
+  net::ProxyConfig system_config;
+  system_config.proxy_rules().ParseFromString(kSystemProxyRules);
+  base_service_->SetProxyConfig(system_config,
+                                net::ProxyConfigService::CONFIG_VALID);
+  net::ProxyConfig data_reduction_proxy_config;
+  data_reduction_proxy_config.proxy_rules().ParseFromString(
+      kDataReductionProxyRules);
+
+  EXPECT_CALL(observer, OnProxyConfigChanged(
+      ProxyConfigMatches(data_reduction_proxy_config),
+      net::ProxyConfigService::CONFIG_VALID)).Times(1);
+  config_service_->UpdateProxyConfig(true, data_reduction_proxy_config);
+  loop.RunUntilIdle();
+  Mock::VerifyAndClearExpectations(&observer);
+
+
+  // Disable the data reduction proxy, which should trigger a notification.
+  base_service_->SetProxyConfig(system_config,
+                                net::ProxyConfigService::CONFIG_VALID);
+  EXPECT_CALL(observer, OnProxyConfigChanged(
+                  ProxyConfigMatches(system_config),
+                  net::ProxyConfigService::CONFIG_VALID)).Times(1);
+  config_service_->UpdateProxyConfig(false, data_reduction_proxy_config);
+  loop.RunUntilIdle();
+  Mock::VerifyAndClearExpectations(&observer);
+
+  config_service_->RemoveObserver(&observer);
+}
+
+TEST_F(DataReductionProxyConfigServiceTest, TrackerEnable) {
+  MockObserver observer;
+  //base::MessageLoopForUI loop;
+  config_service_->AddObserver(&observer);
+  scoped_refptr<base::TestSimpleTaskRunner> task_runner_(
+      new base::TestSimpleTaskRunner());
+  DataReductionProxyConfigTracker tracker(config_service_.get(),
+                                          task_runner_.get());
+  net::ProxyConfig expected_config;
+  expected_config.proxy_rules().ParseFromString(kDataReductionProxyRules);
+  EXPECT_CALL(observer, OnProxyConfigChanged(
+                  ProxyConfigMatches(expected_config),
+                  net::ProxyConfigService::CONFIG_VALID)).Times(1);
+  tracker.Enable(false,
+                 false,
+                 "https://foo.com:443",
+                 "http://bar.com:80");
+  task_runner_->RunUntilIdle();
+  Mock::VerifyAndClearExpectations(&observer);
+
+  config_service_->RemoveObserver(&observer);
+}
+
+TEST_F(DataReductionProxyConfigServiceTest, TrackerEnableRestricted) {
+  MockObserver observer;
+  //base::MessageLoopForUI loop;
+  config_service_->AddObserver(&observer);
+  scoped_refptr<base::TestSimpleTaskRunner> task_runner_(
+      new base::TestSimpleTaskRunner());
+  DataReductionProxyConfigTracker tracker(config_service_.get(),
+                                          task_runner_.get());
+  net::ProxyConfig expected_config;
+  expected_config.proxy_rules().ParseFromString(
+      kDataReductionProxyRestrictedRules);
+  EXPECT_CALL(observer, OnProxyConfigChanged(
+                  ProxyConfigMatches(expected_config),
+                  net::ProxyConfigService::CONFIG_VALID)).Times(1);
+  tracker.Enable(true,
+                 false,
+                 "https://foo.com:443",
+                 "http://bar.com:80");
+  task_runner_->RunUntilIdle();
+  Mock::VerifyAndClearExpectations(&observer);
+
+  config_service_->RemoveObserver(&observer);
+}
+
+TEST_F(DataReductionProxyConfigServiceTest, TrackerDisable) {
+  MockObserver observer;
+  //base::MessageLoopForUI loop;
+  config_service_->AddObserver(&observer);
+  scoped_refptr<base::TestSimpleTaskRunner> task_runner_(
+      new base::TestSimpleTaskRunner());
+  DataReductionProxyConfigTracker tracker(config_service_.get(),
+                                          task_runner_.get());
+  net::ProxyConfig expected_config;
+  expected_config.proxy_rules().ParseFromString(kSystemProxyRules);
+  EXPECT_CALL(observer, OnProxyConfigChanged(
+                  ProxyConfigMatches(expected_config),
+                  net::ProxyConfigService::CONFIG_VALID)).Times(1);
+  tracker.Disable();
+  task_runner_->RunUntilIdle();
+  //loop.RunUntilIdle();
+  Mock::VerifyAndClearExpectations(&observer);
+
+  config_service_->RemoveObserver(&observer);
+}
+
+
+TEST_F(DataReductionProxyConfigServiceTest, TrackerBypassList) {
+  base::MessageLoopForUI loop;
+  scoped_refptr<base::TestSimpleTaskRunner> task_runner_(
+      new base::TestSimpleTaskRunner());
+  DataReductionProxyConfigTracker tracker(config_service_.get(),
+                                          task_runner_.get());
+  tracker.AddHostPatternToBypass("http://www.google.com");
+  tracker.AddHostPatternToBypass("fefe:13::abc/33");
+  tracker.AddURLPatternToBypass("foo.org/images/*");
+  tracker.AddURLPatternToBypass("http://foo.com/*");
+  tracker.AddURLPatternToBypass("http://baz.com:22/bar/*");
+  tracker.AddURLPatternToBypass("http://*bat.com/bar/*");
+
+  std::string expected[] = {
+    "http://www.google.com",
+    "fefe:13::abc/33",
+    "foo.org",
+    "http://foo.com",
+    "http://baz.com:22",
+    "http://*bat.com"
+  };
+
+  ASSERT_EQ(tracker.bypass_rules_.size(), 6u);
+  int i = 0;
+  for (std::vector<std::string>::iterator it = tracker.bypass_rules_.begin();
+       it != tracker.bypass_rules_.end(); ++it) {
+    EXPECT_EQ(expected[i++], *it);
+  }
+}
+
+}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h b/components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h
index 7f66e11..02f8467 100644
--- a/components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h
@@ -19,9 +19,12 @@
   DataReductionProxyConfigurator() {}
   virtual ~DataReductionProxyConfigurator() {}
 
-  // Enable the data reduction proxy. If |restricted|, only the fallback_origin
-  // will be used.
-  virtual void Enable(bool restricted,
+  // Enable the data reduction proxy. If |primary_restricted|, the
+  // |primary_origin| may not be used. If |fallback_restricted|, the
+  // |fallback_origin| may not be used. If both are restricted, then the
+  // proxy configuration will be the same as when |Disable()| is called.
+  virtual void Enable(bool primary_restricted,
+                      bool fallback_restricted,
                       const std::string& primary_origin,
                       const std::string& fallback_origin) = 0;
 
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc
new file mode 100644
index 0000000..1d25a51
--- /dev/null
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc
@@ -0,0 +1,64 @@
+// 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.
+
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_prefs.h"
+
+#include "base/prefs/pref_registry_simple.h"
+#include "components/data_reduction_proxy/common/data_reduction_proxy_pref_names.h"
+#include "components/user_prefs/pref_registry_syncable.h"
+
+namespace data_reduction_proxy {
+
+void RegisterSyncableProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
+  registry->RegisterBooleanPref(
+      data_reduction_proxy::prefs::kDataReductionProxyEnabled,
+      false,
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+  registry->RegisterBooleanPref(
+      data_reduction_proxy::prefs::kDataReductionProxyWasEnabledBefore,
+      false,
+      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+}
+
+void RegisterSimpleProfilePrefs(PrefRegistrySimple* registry) {
+  registry->RegisterBooleanPref(
+      data_reduction_proxy::prefs::kDataReductionProxyEnabled,
+      false);
+  registry->RegisterBooleanPref(
+      data_reduction_proxy::prefs::kDataReductionProxyWasEnabledBefore,
+      false);
+}
+
+void RegisterPrefs(PrefRegistrySimple* registry) {
+  registry->RegisterInt64Pref(
+      prefs::kHttpReceivedContentLength, 0);
+  registry->RegisterInt64Pref(
+      prefs::kHttpOriginalContentLength, 0);
+#if defined(OS_ANDROID) || defined(OS_IOS)
+  registry->RegisterListPref(
+      prefs::kDailyHttpOriginalContentLength);
+  registry->RegisterListPref(
+      prefs::kDailyHttpReceivedContentLength);
+  registry->RegisterListPref(
+      prefs::kDailyOriginalContentLengthWithDataReductionProxyEnabled);
+  registry->RegisterListPref(
+      prefs::kDailyContentLengthWithDataReductionProxyEnabled);
+  registry->RegisterListPref(
+      prefs::kDailyContentLengthHttpsWithDataReductionProxyEnabled);
+  registry->RegisterListPref(
+      prefs::kDailyContentLengthShortBypassWithDataReductionProxyEnabled);
+  registry->RegisterListPref(
+      prefs::kDailyContentLengthLongBypassWithDataReductionProxyEnabled);
+  registry->RegisterListPref(
+      prefs::kDailyContentLengthUnknownWithDataReductionProxyEnabled);
+  registry->RegisterListPref(
+      prefs::kDailyOriginalContentLengthViaDataReductionProxy);
+  registry->RegisterListPref(
+      prefs::kDailyContentLengthViaDataReductionProxy);
+  registry->RegisterInt64Pref(
+      prefs::kDailyHttpContentLengthLastUpdateDate, 0L);
+#endif
+}
+
+}  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_prefs.h b/components/data_reduction_proxy/browser/data_reduction_proxy_prefs.h
new file mode 100644
index 0000000..0bdc964
--- /dev/null
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_prefs.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_PREFS_H_
+#define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_PREFS_H_
+
+#include "base/macros.h"
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+class PrefRegistrySimple;
+
+namespace data_reduction_proxy {
+
+// Registers the data reduction proxy's profile prefs on platforms that use
+// syncable prefs.
+void RegisterSyncableProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry);
+
+// Registers the data reduction proxy's profile prefs on platforms that do not
+// use syncable prefs.
+void RegisterSimpleProfilePrefs(PrefRegistrySimple* registry);
+
+// Registers local state, i.e., profile-agnostic prefs for the data
+// reduction proxy.
+void RegisterPrefs(PrefRegistrySimple* registry);
+
+}  // namespace data_reduction_proxy
+
+#endif  // COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_PREFS_H_
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc
index b3d4c71..3683936 100644
--- a/components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc
@@ -63,28 +63,57 @@
   return val;
 }
 
-bool IsProxyOriginSetOnCommandLine() {
+}  // namespace
+
+namespace data_reduction_proxy {
+
+std::string DataReductionProxySettings::key_;
+bool DataReductionProxySettings::allowed_;
+bool DataReductionProxySettings::promo_allowed_;
+
+// static
+bool DataReductionProxySettings::IsProxyOriginSetOnCommandLine() {
   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
   return command_line.HasSwitch(
       data_reduction_proxy::switches::kDataReductionProxy);
 }
 
-bool IsEnableSpdyProxyAuthSetOnCommandLine() {
+// static
+bool DataReductionProxySettings::IsProxyKeySetOnCommandLine() {
   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
   return command_line.HasSwitch(
       data_reduction_proxy::switches::kEnableDataReductionProxy);
 }
 
-}  // namespace
+// static
+bool DataReductionProxySettings::IsIncludedInFieldTrialOrFlags() {
+  return (base::FieldTrialList::FindFullName(
+              "DataCompressionProxyRollout") == kEnabled ||
+          IsProxyOriginSetOnCommandLine());
+}
 
-namespace data_reduction_proxy {
+// static
+void DataReductionProxySettings::SetKey(const std::string& key) {
+  key_ = key;
+}
+
+// static
+void DataReductionProxySettings::SetAllowed(bool allowed) {
+  allowed_ = allowed;
+}
+
+// static
+void DataReductionProxySettings::SetPromoAllowed(bool promo_allowed) {
+  promo_allowed_ = promo_allowed;
+}
 
 DataReductionProxySettings::DataReductionProxySettings()
     : restricted_by_carrier_(false),
       enabled_by_user_(false),
       prefs_(NULL),
       local_state_prefs_(NULL),
-      url_request_context_getter_(NULL) {
+      url_request_context_getter_(NULL),
+      fallback_allowed_(true) {
 }
 
 DataReductionProxySettings::~DataReductionProxySettings() {
@@ -104,17 +133,14 @@
 void DataReductionProxySettings::InitDataReductionProxySettings(
     PrefService* prefs,
     PrefService* local_state_prefs,
-    net::URLRequestContextGetter* url_request_context_getter,
-    scoped_ptr<DataReductionProxyConfigurator> config) {
+    net::URLRequestContextGetter* url_request_context_getter) {
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(prefs);
   DCHECK(local_state_prefs);
   DCHECK(url_request_context_getter);
-  DCHECK(config);
   prefs_ = prefs;
   local_state_prefs_ = local_state_prefs;
   url_request_context_getter_ = url_request_context_getter;
-  config_ = config.Pass();
   InitPrefMembers();
   RecordDataReductionInit();
 
@@ -129,6 +155,23 @@
   MaybeActivateDataReductionProxy(true);
 }
 
+void DataReductionProxySettings::InitDataReductionProxySettings(
+    PrefService* prefs,
+    PrefService* local_state_prefs,
+    net::URLRequestContextGetter* url_request_context_getter,
+    scoped_ptr<DataReductionProxyConfigurator> config) {
+  InitDataReductionProxySettings(prefs,
+                                 local_state_prefs,
+                                 url_request_context_getter);
+  SetProxyConfigurator(config.Pass());
+}
+
+void DataReductionProxySettings::SetProxyConfigurator(
+    scoped_ptr<DataReductionProxyConfigurator> configurator) {
+  DCHECK(configurator);
+  config_ = configurator.Pass();
+}
+
 // static
 void DataReductionProxySettings::InitDataReductionProxySession(
     net::HttpNetworkSession* session) {
@@ -139,12 +182,12 @@
 // (typically once per session).
 // TODO(bengr):Pass a configuration struct into DataReductionProxyConfigurator's
 // constructor. The struct would carry everything in the preprocessor flags.
-#if defined(SPDY_PROXY_AUTH_ORIGIN) && defined(SPDY_PROXY_AUTH_VALUE)
+  if (key_.empty())
+    return;
   DCHECK(session);
   net::HttpAuthCache* auth_cache = session->http_auth_cache();
   DCHECK(auth_cache);
   InitDataReductionAuthentication(auth_cache);
-#endif  // defined(SPDY_PROXY_AUTH_ORIGIN) && defined(SPDY_PROXY_AUTH_VALUE)
 }
 
 // static
@@ -192,16 +235,13 @@
 // TODO(bengr): Use a configuration struct to carry field trial state as well.
 // static
 bool DataReductionProxySettings::IsDataReductionProxyAllowed() {
-  return IsProxyOriginSetOnCommandLine() ||
-      (FieldTrialList::FindFullName("DataCompressionProxyRollout") == kEnabled);
+  return allowed_;
 }
 
 // static
 bool DataReductionProxySettings::IsDataReductionProxyPromoAllowed() {
   return IsProxyOriginSetOnCommandLine() ||
-      (IsDataReductionProxyAllowed() &&
-        FieldTrialList::FindFullName("DataCompressionProxyPromoVisibility") ==
-            kEnabled);
+      (IsDataReductionProxyAllowed() && promo_allowed_);
 }
 
 // static
@@ -250,6 +290,7 @@
 #endif
 }
 
+// static
 bool DataReductionProxySettings::IsAcceptableAuthChallenge(
     net::AuthChallengeInfo* auth_info) {
   // Challenge realm must start with the authentication realm name.
@@ -269,6 +310,7 @@
   return false;
 }
 
+// static
 base::string16 DataReductionProxySettings::GetTokenForAuthChallenge(
     net::AuthChallengeInfo* auth_info) {
   if (auth_info->realm.length() > strlen(kAuthenticationRealmName)) {
@@ -289,7 +331,7 @@
 
 bool DataReductionProxySettings::IsDataReductionProxyEnabled() {
   return spdy_proxy_auth_enabled_.GetValue() ||
-      IsEnableSpdyProxyAuthSetOnCommandLine();
+      IsProxyKeySetOnCommandLine();
 }
 
 bool DataReductionProxySettings::IsDataReductionProxyManaged() {
@@ -383,7 +425,6 @@
   }
   DVLOG(1) << "The data reduction proxy is restricted to the configured "
            << "fallback proxy.";
-
   if (enabled_by_user_) {
     if (!restricted_by_carrier_) {
       // Restrict the proxy.
@@ -474,7 +515,6 @@
     bool at_startup) {
   DCHECK(thread_checker_.CalledOnValidThread());
   PrefService* prefs = GetOriginalProfilePrefs();
-
   // TODO(marq): Consider moving this so stats are wiped the first time the
   // proxy settings are actually (not maybe) turned on.
   if (spdy_proxy_auth_enabled_.GetValue() &&
@@ -505,7 +545,10 @@
 
   LogProxyState(enabled, restricted, at_startup);
   if (enabled) {
-    config_->Enable(restricted, GetDataReductionProxyOrigin(), fallback);
+    config_->Enable(restricted,
+                    !fallback_allowed_,
+                    GetDataReductionProxyOrigin(),
+                    fallback);
   } else {
     config_->Disable();
   }
@@ -619,17 +662,12 @@
   if (command_line.HasSwitch(switches::kDataReductionProxy)) {
     // If an origin is provided via a switch, then only consider the value
     // that is provided by a switch. Do not use the preprocessor constant.
-    // Don't expose SPDY_PROXY_AUTH_VALUE to a proxy passed in via the command
-    // line.
+    // Don't expose |key_| to a proxy passed in via the command line.
     if (!command_line.HasSwitch(switches::kDataReductionProxyKey))
       return base::string16();
     key = command_line.GetSwitchValueASCII(switches::kDataReductionProxyKey);
   } else {
-#if defined(SPDY_PROXY_AUTH_VALUE)
-    key = SPDY_PROXY_AUTH_VALUE;
-#else
-    return base::string16();
-#endif
+    key = key_;
   }
 
   DCHECK(!key.empty());
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_settings.h b/components/data_reduction_proxy/browser/data_reduction_proxy_settings.h
index 2ccc3fa..4fd7711 100644
--- a/components/data_reduction_proxy/browser/data_reduction_proxy_settings.h
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_settings.h
@@ -89,6 +89,22 @@
   // TODO(marq): Consider instead using a std::pair instead of a vector.
   typedef std::vector<GURL> DataReductionProxyList;
 
+  // Returns true of the data reduction proxy origin is set on the command line.
+  static bool IsProxyOriginSetOnCommandLine();
+
+  // Returns true if the data reduction proxy key is set on the command line.
+  static bool IsProxyKeySetOnCommandLine();
+
+  // Returns true if this application instance is part of the data reduction
+  // proxy field trial, or if it a proxy origin is set in flags. This is a
+  // convenience method for platforms like Chrome on Android and iOS, to
+  // determine if the data reduction proxy is allowed.
+  static bool IsIncludedInFieldTrialOrFlags();
+
+  static void SetKey(const std::string& key);
+  static void SetAllowed(bool allowed);
+  static void SetPromoAllowed(bool promo_allowed);
+
   DataReductionProxySettings();
   virtual ~DataReductionProxySettings();
 
@@ -99,17 +115,31 @@
   void InitDataReductionProxySettings(
       PrefService* prefs,
       PrefService* local_state_prefs,
+      net::URLRequestContextGetter* url_request_context_getter);
+
+  // Initializes the data reduction proxy with profile and local state prefs,
+  // a |UrlRequestContextGetter| for canary probes, and a proxy configurator.
+  // The caller must ensure that all parameters remain alive for the lifetime of
+  // the |DataReductionProxySettings| instance.
+  // TODO(marq): Remove when iOS supports the new interface above.
+  void InitDataReductionProxySettings(
+      PrefService* prefs,
+      PrefService* local_state_prefs,
       net::URLRequestContextGetter* url_request_context_getter,
       scoped_ptr<DataReductionProxyConfigurator> config);
 
+  // Sets the logic the embedder uses to set the networking configuration that
+  // causes traffic to be proxied.
+  void SetProxyConfigurator(
+      scoped_ptr<DataReductionProxyConfigurator> configurator);
+
   // If proxy authentication is compiled in, pre-cache authentication
   // keys for all configured proxies in |session|.
   static void InitDataReductionProxySession(net::HttpNetworkSession* session);
 
-  // Returns true if the data reduction proxy is allowed to be used on this
-  // instance of Chrome. This could return false, for example, if this instance
-  // is not part of the field trial, or if the proxy name is not configured
-  // via gyp.
+  // Returns true if the data reduction proxy is allowed to be used. This could
+  // return false, for example, if this instance is not part of the field trial,
+  // or if the proxy name is not configured via gyp.
   static bool IsDataReductionProxyAllowed();
 
   // Returns true if a screen promoting the data reduction proxy is allowed to
@@ -133,12 +163,13 @@
 
   // Returns true if |auth_info| represents an authentication challenge from
   // a compatible, configured proxy.
-  bool IsAcceptableAuthChallenge(net::AuthChallengeInfo* auth_info);
+  static bool IsAcceptableAuthChallenge(net::AuthChallengeInfo* auth_info);
 
   // Returns a UTF16 string suitable for use as an authentication token in
   // response to the challenge represented by |auth_info|. If the token can't
   // be correctly generated for |auth_info|, returns an empty UTF16 string.
-  base::string16 GetTokenForAuthChallenge(net::AuthChallengeInfo* auth_info);
+  static base::string16 GetTokenForAuthChallenge(
+      net::AuthChallengeInfo* auth_info);
 
   // Returns true if the proxy is enabled.
   bool IsDataReductionProxyEnabled();
@@ -151,6 +182,16 @@
   // probe succeeds.
   void SetDataReductionProxyEnabled(bool enabled);
 
+  // If |allowed|, the fallback proxy will be included in the proxy
+  // configuration.
+  void set_fallback_allowed(bool allowed) {
+    fallback_allowed_ = allowed;
+  }
+
+  bool fallback_allowed() const {
+    return fallback_allowed_;
+  }
+
   // Returns the time in microseconds that the last update was made to the
   // daily original and received content lengths.
   int64 GetDataReductionLastUpdateTime();
@@ -264,6 +305,10 @@
   // the data reduction proxy feature isn't available.
   static base::string16 AuthHashForSalt(int64 salt);
 
+  static std::string key_;
+  static bool allowed_;
+  static bool promo_allowed_;
+
   bool restricted_by_carrier_;
   bool enabled_by_user_;
 
@@ -279,6 +324,8 @@
 
   base::ThreadChecker thread_checker_;
 
+  bool fallback_allowed_;
+
   DISALLOW_COPY_AND_ASSIGN(DataReductionProxySettings);
 };
 
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.cc
index 325500d..d647514 100644
--- a/components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.cc
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.cc
@@ -49,16 +49,20 @@
   return FAILED_PROXY_ALREADY_DISABLED;
 }
 
-void TestDataReductionProxyConfig::Enable(bool restricted,
-                                   const std::string& primary_origin,
-                                   const std::string& fallback_origin) {
+void TestDataReductionProxyConfig::Enable(
+    bool restricted,
+    bool fallback_restricted,
+    const std::string& primary_origin,
+    const std::string& fallback_origin) {
   enabled_ = true;
   restricted_ = restricted;
+  fallback_restricted_ = fallback_restricted;
 }
 
 void TestDataReductionProxyConfig::Disable() {
   enabled_ = false;
   restricted_ = false;
+  fallback_restricted_ = false;
 }
 
 DataReductionProxySettingsTestBase::DataReductionProxySettingsTestBase()
@@ -68,6 +72,7 @@
 DataReductionProxySettingsTestBase::~DataReductionProxySettingsTestBase() {}
 
 void DataReductionProxySettingsTestBase::AddProxyToCommandLine() {
+  DataReductionProxySettings::SetAllowed(true);
   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
       switches::kDataReductionProxy, kDataReductionProxy);
   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
@@ -78,6 +83,7 @@
 
 // testing::Test implementation:
 void DataReductionProxySettingsTestBase::SetUp() {
+  DataReductionProxySettings::SetAllowed(true);
   PrefRegistrySimple* registry = pref_service_.registry();
   registry->RegisterListPref(prefs::kDailyHttpOriginalContentLength);
   registry->RegisterListPref(prefs::kDailyHttpReceivedContentLength);
@@ -107,7 +113,7 @@
 template <class C>
 void DataReductionProxySettingsTestBase::ResetSettings() {
   MockDataReductionProxySettings<C>* settings =
-      new MockDataReductionProxySettings<C>;
+      new MockDataReductionProxySettings<C>();
   EXPECT_CALL(*settings, GetOriginalProfilePrefs())
       .Times(AnyNumber())
       .WillRepeatedly(Return(&pref_service_));
@@ -160,10 +166,13 @@
     int expected_calls);
 
 void DataReductionProxySettingsTestBase::CheckProxyConfigs(
-    bool expected_enabled, bool expected_restricted) {
+    bool expected_enabled,
+    bool expected_restricted,
+    bool expected_fallback_restricted) {
   TestDataReductionProxyConfig* config =
       static_cast<TestDataReductionProxyConfig*>(settings_->config_.get());
   ASSERT_EQ(expected_restricted, config->restricted_);
+  ASSERT_EQ(expected_fallback_restricted, config->fallback_restricted_);
   ASSERT_EQ(expected_enabled, config->enabled_);
 }
 
@@ -173,7 +182,8 @@
     const std::string& response,
     bool request_succeeded,
     bool expected_enabled,
-    bool expected_restricted) {
+    bool expected_restricted,
+    bool expected_fallback_restricted) {
   pref_service_.SetBoolean(prefs::kDataReductionProxyEnabled,
                            initially_enabled);
   if (initially_enabled)
@@ -187,14 +197,17 @@
                  initially_enabled ? 1 : 0);
   settings_->MaybeActivateDataReductionProxy(false);
   base::MessageLoop::current()->RunUntilIdle();
-  CheckProxyConfigs(expected_enabled, expected_restricted);
+  CheckProxyConfigs(expected_enabled,
+                    expected_restricted,
+                    expected_fallback_restricted);
 }
 
 void DataReductionProxySettingsTestBase::CheckProbeOnIPChange(
     const std::string& probe_url,
     const std::string& response,
     bool request_succeeded,
-    bool expected_restricted) {
+    bool expected_restricted,
+    bool expected_fallback_restricted) {
   SetProbeResult(probe_url,
                  response,
                  FetchResult(!settings_->restricted_by_carrier_,
@@ -203,22 +216,28 @@
                  1);
   settings_->OnIPAddressChanged();
   base::MessageLoop::current()->RunUntilIdle();
-  CheckProxyConfigs(true, expected_restricted);
+  CheckProxyConfigs(true, expected_restricted, expected_fallback_restricted);
 }
 
 void DataReductionProxySettingsTestBase::CheckOnPrefChange(
     bool enabled,
-    bool expected_enabled) {
+    bool expected_enabled,
+    bool managed) {
   // Always have a sucessful probe for pref change tests.
   SetProbeResult(kProbeURLWithOKResponse,
                  "OK",
                  FetchResult(enabled, true),
                  true,
                  expected_enabled ? 1 : 0);
-  pref_service_.SetBoolean(prefs::kDataReductionProxyEnabled, enabled);
+  if (managed) {
+    pref_service_.SetManagedPref(prefs::kDataReductionProxyEnabled,
+                                 base::Value::CreateBooleanValue(enabled));
+  } else {
+    pref_service_.SetBoolean(prefs::kDataReductionProxyEnabled, enabled);
+  }
   base::MessageLoop::current()->RunUntilIdle();
   // Never expect the proxy to be restricted for pref change tests.
-  CheckProxyConfigs(expected_enabled, false);
+  CheckProxyConfigs(expected_enabled, false, false);
 }
 
 void DataReductionProxySettingsTestBase::CheckInitDataReductionProxy(
@@ -232,16 +251,15 @@
                  enabled_at_startup ? 1 : 0);
   scoped_ptr<DataReductionProxyConfigurator> configurator(
       new TestDataReductionProxyConfig());
+  settings_->SetProxyConfigurator(configurator.Pass());
   scoped_refptr<net::TestURLRequestContextGetter> request_context =
       new net::TestURLRequestContextGetter(base::MessageLoopProxy::current());
-  settings_->InitDataReductionProxySettings(
-      &pref_service_,
-      &pref_service_,
-      request_context.get(),
-      configurator.Pass());
+  settings_->InitDataReductionProxySettings(&pref_service_,
+                                            &pref_service_,
+                                            request_context.get());
 
   base::MessageLoop::current()->RunUntilIdle();
-  CheckProxyConfigs(enabled_at_startup, false);
+  CheckProxyConfigs(enabled_at_startup, false, false);
 }
 
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.h b/components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.h
index d96b46e..f0cc648 100644
--- a/components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.h
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.h
@@ -22,9 +22,10 @@
 class TestDataReductionProxyConfig : public DataReductionProxyConfigurator {
  public:
   TestDataReductionProxyConfig()
-      : enabled_(false), restricted_(false) {}
+      : enabled_(false), restricted_(false), fallback_restricted_(false) {}
   virtual ~TestDataReductionProxyConfig() {}
   virtual void Enable(bool restricted,
+                      bool fallback_restricted,
                       const std::string& primary_origin,
                       const std::string& fallback_origin) OVERRIDE;
   virtual void Disable() OVERRIDE;
@@ -38,6 +39,11 @@
   // Describes whether the proxy has been put in a restricted mode. True if
   // |Enable| is called with |restricted| set to true. Defaults to false.
   bool restricted_;
+
+  // Describes whether the proxy has been put in a mode where the fallback
+  // configuration has been disallowed. True if |Enable| is called with
+  // |fallback_restricted| set to true. Defaults to false.
+  bool fallback_restricted_;
 };
 
 template <class C>
@@ -85,18 +91,22 @@
                               bool success,
                               int expected_calls) = 0;
 
-  void CheckProxyConfigs(bool expected_enabled, bool expected_restricted);
+  void CheckProxyConfigs(bool expected_enabled,
+                         bool expected_restricted,
+                         bool expected_fallback_restricted);
   void CheckProbe(bool initially_enabled,
                   const std::string& probe_url,
                   const std::string& response,
                   bool request_success,
                   bool expected_enabled,
-                  bool expected_restricted);
+                  bool expected_restricted,
+                  bool expected_fallback_restricted);
   void CheckProbeOnIPChange(const std::string& probe_url,
                             const std::string& response,
                             bool request_success,
-                            bool expected_enabled);
-  void CheckOnPrefChange(bool enabled, bool expected_enabled);
+                            bool expected_enabled,
+                            bool expected_fallback_restricted);
+  void CheckOnPrefChange(bool enabled, bool expected_enabled, bool managed);
   void CheckInitDataReductionProxy(bool enabled_at_startup);
 
   TestingPrefServiceSimple pref_service_;
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_settings_unittest.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_settings_unittest.cc
index 1ad5829..ddb56a9 100644
--- a/components/data_reduction_proxy/browser/data_reduction_proxy_settings_unittest.cc
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_settings_unittest.cc
@@ -135,16 +135,21 @@
 }
 
 TEST_F(DataReductionProxySettingsTest, TestIsProxyEnabledOrManaged) {
+  AddProxyToCommandLine();
   settings_->InitPrefMembers();
+    base::MessageLoopForUI loop;
+    // The proxy is disabled initially.
+    settings_->enabled_by_user_ = false;
+    settings_->SetProxyConfigs(false, false, false);
+
   EXPECT_FALSE(settings_->IsDataReductionProxyEnabled());
   EXPECT_FALSE(settings_->IsDataReductionProxyManaged());
 
-  pref_service_.SetBoolean(prefs::kDataReductionProxyEnabled, true);
+  CheckOnPrefChange(true, true, false);
   EXPECT_TRUE(settings_->IsDataReductionProxyEnabled());
   EXPECT_FALSE(settings_->IsDataReductionProxyManaged());
 
-  pref_service_.SetManagedPref(prefs::kDataReductionProxyEnabled,
-                               base::Value::CreateBooleanValue(true));
+  CheckOnPrefChange(true, true, true);
   EXPECT_TRUE(settings_->IsDataReductionProxyEnabled());
   EXPECT_TRUE(settings_->IsDataReductionProxyManaged());
 }
@@ -177,7 +182,8 @@
     auth_info->challenger = net::HostPortPair::FromString(tests[i].host);
     auth_info->realm = tests[i].realm;
     EXPECT_EQ(tests[i].expected_to_succeed,
-              settings_->IsAcceptableAuthChallenge(auth_info.get()));
+              DataReductionProxySettings::IsAcceptableAuthChallenge(
+                  auth_info.get()));
   }
 }
 
@@ -201,7 +207,8 @@
     auth_info->challenger =
         net::HostPortPair::FromString(kDataReductionProxy);
     auth_info->realm = tests[i].realm;
-    base::string16 token = settings_->GetTokenForAuthChallenge(auth_info.get());
+    base::string16 token =
+        DataReductionProxySettings::GetTokenForAuthChallenge(auth_info.get());
     EXPECT_EQ(tests[i].expected_empty_token, token.empty());
   }
 }
@@ -285,14 +292,14 @@
   base::MessageLoopForUI loop;
   // The proxy is enabled and unrestructed initially.
   // Request succeeded but with bad response, expect proxy to be restricted.
-  CheckProbe(true, kProbeURLWithBadResponse, "Bad", true, true, true);
+  CheckProbe(true, kProbeURLWithBadResponse, "Bad", true, true, true, false);
   // Request succeeded with valid response, expect proxy to be unrestricted.
-  CheckProbe(true, kProbeURLWithOKResponse, "OK", true, true, false);
+  CheckProbe(true, kProbeURLWithOKResponse, "OK", true, true, false, false);
   // Request failed, expect proxy to be enabled but restricted.
-  CheckProbe(true, kProbeURLWithNoResponse, "", false, true, true);
+  CheckProbe(true, kProbeURLWithNoResponse, "", false, true, true, false);
   // The proxy is disabled initially. Probes should not be emitted to change
   // state.
-  CheckProbe(false, kProbeURLWithOKResponse, "OK", true, false, false);
+  CheckProbe(false, kProbeURLWithOKResponse, "OK", true, false, false, false);
 }
 
 TEST_F(DataReductionProxySettingsTest, TestOnIPAddressChanged) {
@@ -308,13 +315,13 @@
   settings_->SetProxyConfigs(true, false, true);
   // IP address change triggers a probe that succeeds. Proxy remains
   // unrestricted.
-  CheckProbeOnIPChange(kProbeURLWithOKResponse, "OK", true, false);
+  CheckProbeOnIPChange(kProbeURLWithOKResponse, "OK", true, false, false);
   // IP address change triggers a probe that fails. Proxy is restricted.
-  CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, true);
+  CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, true, false);
   // IP address change triggers a probe that fails. Proxy remains restricted.
-  CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, true);
+  CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, true, false);
   // IP address change triggers a probe that succeed. Proxy is unrestricted.
-  CheckProbeOnIPChange(kProbeURLWithBadResponse, "OK", true, false);
+  CheckProbeOnIPChange(kProbeURLWithBadResponse, "OK", true, false, false);
 }
 
 TEST_F(DataReductionProxySettingsTest, TestOnProxyEnabledPrefChange) {
@@ -325,9 +332,9 @@
   settings_->enabled_by_user_ = true;
   settings_->SetProxyConfigs(true, false, true);
   // The pref is disabled, so correspondingly should be the proxy.
-  CheckOnPrefChange(false, false);
+  CheckOnPrefChange(false, false, false);
   // The pref is enabled, so correspondingly should be the proxy.
-  CheckOnPrefChange(true, true);
+  CheckOnPrefChange(true, true, false);
 }
 
 TEST_F(DataReductionProxySettingsTest, TestInitDataReductionProxyOn) {
@@ -375,17 +382,19 @@
   // No call to |AddProxyToCommandLine()| was made, so the proxy feature
   // should be unavailable.
   base::MessageLoopForUI loop;
+  DataReductionProxySettings::SetAllowed(false);
   EXPECT_FALSE(DataReductionProxySettings::IsDataReductionProxyAllowed());
   MockSettings* settings = static_cast<MockSettings*>(settings_.get());
   EXPECT_CALL(*settings, RecordStartupState(PROXY_NOT_AVAILABLE));
 
   scoped_ptr<DataReductionProxyConfigurator> configurator(
       new TestDataReductionProxyConfig());
+  settings_->SetProxyConfigurator(configurator.Pass());
   scoped_refptr<net::TestURLRequestContextGetter> request_context =
       new net::TestURLRequestContextGetter(base::MessageLoopProxy::current());
-  settings_->InitDataReductionProxySettings(
-      &pref_service_, &pref_service_, request_context.get(),
-      configurator.Pass());
+  settings_->InitDataReductionProxySettings(&pref_service_,
+                                            &pref_service_,
+                                            request_context.get());
 
   base::MessageLoop::current()->RunUntilIdle();
 }
diff --git a/components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc b/components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
index 34fa1cd..6487bfc 100644
--- a/components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
+++ b/components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
@@ -17,6 +17,12 @@
 #include "net/http/http_auth_challenge_tokenizer.h"
 #include "net/http/http_request_info.h"
 
+namespace {
+
+const char kDataReductionProxyAuthScheme[] = "spdyproxy";
+
+}
+
 namespace data_reduction_proxy {
 
 using net::AuthCredentials;
@@ -29,6 +35,11 @@
 using net::HttpRequestInfo;
 using net::HttpUtil;
 
+// static
+std::string HttpAuthHandlerDataReductionProxy::Scheme() {
+  return kDataReductionProxyAuthScheme;
+}
+
 HttpAuthHandlerDataReductionProxy::Factory::Factory(
     const std::vector<GURL>& authorized_spdyproxy_origins) {
   for (unsigned int i = 0; i < authorized_spdyproxy_origins.size(); ++i) {
@@ -125,7 +136,8 @@
     HttpAuthChallengeTokenizer* challenge) {
 
   // Verify the challenge's auth-scheme.
-  if (!LowerCaseEqualsASCII(challenge->scheme(), "spdyproxy")) {
+  if (!LowerCaseEqualsASCII(challenge->scheme(),
+                            kDataReductionProxyAuthScheme)) {
     VLOG(1) << "Parsed challenge without SpdyProxy type";
     return false;
   }
diff --git a/components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.h b/components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.h
index b18cade..3db5dc2 100644
--- a/components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.h
+++ b/components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.h
@@ -17,6 +17,9 @@
 // Code for handling http SpdyProxy authentication.
 class HttpAuthHandlerDataReductionProxy : public net::HttpAuthHandler {
  public:
+  // Returns the data reduction proxy auth scheme.
+  static std::string Scheme();
+
   class Factory : public net::HttpAuthHandlerFactory {
    public:
     // Constructs a new spdyproxy handler factory which mints handlers that
diff --git a/components/data_reduction_proxy_browser.target.darwin-arm.mk b/components/data_reduction_proxy_browser.target.darwin-arm.mk
new file mode 100644
index 0000000..e654954
--- /dev/null
+++ b/components/data_reduction_proxy_browser.target.darwin-arm.mk
@@ -0,0 +1,284 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_metrics.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc \
+	components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_browser_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_browser
+data_reduction_proxy_browser: components_data_reduction_proxy_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_browser.target.darwin-arm64.mk b/components/data_reduction_proxy_browser.target.darwin-arm64.mk
new file mode 100644
index 0000000..9d3b37c
--- /dev/null
+++ b/components/data_reduction_proxy_browser.target.darwin-arm64.mk
@@ -0,0 +1,268 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_metrics.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc \
+	components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_browser_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_browser
+data_reduction_proxy_browser: components_data_reduction_proxy_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_browser.target.darwin-mips.mk b/components/data_reduction_proxy_browser.target.darwin-mips.mk
new file mode 100644
index 0000000..2b2b945
--- /dev/null
+++ b/components/data_reduction_proxy_browser.target.darwin-mips.mk
@@ -0,0 +1,280 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_metrics.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc \
+	components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_browser_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_browser
+data_reduction_proxy_browser: components_data_reduction_proxy_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_browser.target.darwin-x86.mk b/components/data_reduction_proxy_browser.target.darwin-x86.mk
new file mode 100644
index 0000000..4ef3092
--- /dev/null
+++ b/components/data_reduction_proxy_browser.target.darwin-x86.mk
@@ -0,0 +1,278 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_metrics.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc \
+	components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_browser_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_browser
+data_reduction_proxy_browser: components_data_reduction_proxy_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_browser.target.darwin-x86_64.mk b/components/data_reduction_proxy_browser.target.darwin-x86_64.mk
new file mode 100644
index 0000000..47b7492
--- /dev/null
+++ b/components/data_reduction_proxy_browser.target.darwin-x86_64.mk
@@ -0,0 +1,280 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_metrics.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc \
+	components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_browser_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_browser
+data_reduction_proxy_browser: components_data_reduction_proxy_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_browser.target.linux-arm.mk b/components/data_reduction_proxy_browser.target.linux-arm.mk
new file mode 100644
index 0000000..e654954
--- /dev/null
+++ b/components/data_reduction_proxy_browser.target.linux-arm.mk
@@ -0,0 +1,284 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_metrics.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc \
+	components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_browser_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_browser
+data_reduction_proxy_browser: components_data_reduction_proxy_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_browser.target.linux-arm64.mk b/components/data_reduction_proxy_browser.target.linux-arm64.mk
new file mode 100644
index 0000000..9d3b37c
--- /dev/null
+++ b/components/data_reduction_proxy_browser.target.linux-arm64.mk
@@ -0,0 +1,268 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_metrics.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc \
+	components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_browser_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_browser
+data_reduction_proxy_browser: components_data_reduction_proxy_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_browser.target.linux-mips.mk b/components/data_reduction_proxy_browser.target.linux-mips.mk
new file mode 100644
index 0000000..2b2b945
--- /dev/null
+++ b/components/data_reduction_proxy_browser.target.linux-mips.mk
@@ -0,0 +1,280 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_metrics.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc \
+	components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_browser_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_browser
+data_reduction_proxy_browser: components_data_reduction_proxy_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_browser.target.linux-x86.mk b/components/data_reduction_proxy_browser.target.linux-x86.mk
new file mode 100644
index 0000000..4ef3092
--- /dev/null
+++ b/components/data_reduction_proxy_browser.target.linux-x86.mk
@@ -0,0 +1,278 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_metrics.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc \
+	components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_browser_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_browser
+data_reduction_proxy_browser: components_data_reduction_proxy_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_browser.target.linux-x86_64.mk b/components/data_reduction_proxy_browser.target.linux-x86_64.mk
new file mode 100644
index 0000000..47b7492
--- /dev/null
+++ b/components/data_reduction_proxy_browser.target.linux-x86_64.mk
@@ -0,0 +1,280 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_browser_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_config_service.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_metrics.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_prefs.cc \
+	components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc \
+	components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DPOSIX_AVOID_MMAP' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_browser_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_browser
+data_reduction_proxy_browser: components_data_reduction_proxy_browser_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_common.target.darwin-arm.mk b/components/data_reduction_proxy_common.target.darwin-arm.mk
new file mode 100644
index 0000000..842dcbb
--- /dev/null
+++ b/components/data_reduction_proxy_common.target.darwin-arm.mk
@@ -0,0 +1,278 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/common/data_reduction_proxy_pref_names.cc \
+	components/data_reduction_proxy/common/data_reduction_proxy_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_common_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_common
+data_reduction_proxy_common: components_data_reduction_proxy_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_common.target.darwin-arm64.mk b/components/data_reduction_proxy_common.target.darwin-arm64.mk
new file mode 100644
index 0000000..45c829e
--- /dev/null
+++ b/components/data_reduction_proxy_common.target.darwin-arm64.mk
@@ -0,0 +1,262 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/common/data_reduction_proxy_pref_names.cc \
+	components/data_reduction_proxy/common/data_reduction_proxy_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_common_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_common
+data_reduction_proxy_common: components_data_reduction_proxy_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_common.target.darwin-mips.mk b/components/data_reduction_proxy_common.target.darwin-mips.mk
new file mode 100644
index 0000000..1aaf5fb
--- /dev/null
+++ b/components/data_reduction_proxy_common.target.darwin-mips.mk
@@ -0,0 +1,274 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/common/data_reduction_proxy_pref_names.cc \
+	components/data_reduction_proxy/common/data_reduction_proxy_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_common_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_common
+data_reduction_proxy_common: components_data_reduction_proxy_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_common.target.darwin-x86.mk b/components/data_reduction_proxy_common.target.darwin-x86.mk
new file mode 100644
index 0000000..35af02b
--- /dev/null
+++ b/components/data_reduction_proxy_common.target.darwin-x86.mk
@@ -0,0 +1,274 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/common/data_reduction_proxy_pref_names.cc \
+	components/data_reduction_proxy/common/data_reduction_proxy_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_common_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_common
+data_reduction_proxy_common: components_data_reduction_proxy_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_common.target.darwin-x86_64.mk b/components/data_reduction_proxy_common.target.darwin-x86_64.mk
new file mode 100644
index 0000000..9b0a2d8
--- /dev/null
+++ b/components/data_reduction_proxy_common.target.darwin-x86_64.mk
@@ -0,0 +1,274 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/common/data_reduction_proxy_pref_names.cc \
+	components/data_reduction_proxy/common/data_reduction_proxy_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_common_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_common
+data_reduction_proxy_common: components_data_reduction_proxy_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_common.target.linux-arm.mk b/components/data_reduction_proxy_common.target.linux-arm.mk
new file mode 100644
index 0000000..842dcbb
--- /dev/null
+++ b/components/data_reduction_proxy_common.target.linux-arm.mk
@@ -0,0 +1,278 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/common/data_reduction_proxy_pref_names.cc \
+	components/data_reduction_proxy/common/data_reduction_proxy_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-fno-tree-sra \
+	-Wno-psabi \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-abi \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-Wl,-z,relro \
+	-Wl,-z,now \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--icf=safe \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_common_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_common
+data_reduction_proxy_common: components_data_reduction_proxy_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_common.target.linux-arm64.mk b/components/data_reduction_proxy_common.target.linux-arm64.mk
new file mode 100644
index 0000000..45c829e
--- /dev/null
+++ b/components/data_reduction_proxy_common.target.linux-arm64.mk
@@ -0,0 +1,262 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/common/data_reduction_proxy_pref_names.cc \
+	components/data_reduction_proxy/common/data_reduction_proxy_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_common_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_common
+data_reduction_proxy_common: components_data_reduction_proxy_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_common.target.linux-mips.mk b/components/data_reduction_proxy_common.target.linux-mips.mk
new file mode 100644
index 0000000..1aaf5fb
--- /dev/null
+++ b/components/data_reduction_proxy_common.target.linux-mips.mk
@@ -0,0 +1,274 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/common/data_reduction_proxy_pref_names.cc \
+	components/data_reduction_proxy/common/data_reduction_proxy_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	 \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-EL \
+	-mhard-float \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-uninitialized \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-EL \
+	-Wl,--no-keep-memory \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_common_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_common
+data_reduction_proxy_common: components_data_reduction_proxy_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_common.target.linux-x86.mk b/components/data_reduction_proxy_common.target.linux-x86.mk
new file mode 100644
index 0000000..35af02b
--- /dev/null
+++ b/components/data_reduction_proxy_common.target.linux-x86.mk
@@ -0,0 +1,274 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/common/data_reduction_proxy_pref_names.cc \
+	components/data_reduction_proxy/common/data_reduction_proxy_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-msse2 \
+	-mfpmath=sse \
+	-mmmx \
+	-m32 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-fno-stack-protector \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m32 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_common_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_common
+data_reduction_proxy_common: components_data_reduction_proxy_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/data_reduction_proxy_common.target.linux-x86_64.mk b/components/data_reduction_proxy_common.target.linux-x86_64.mk
new file mode 100644
index 0000000..9b0a2d8
--- /dev/null
+++ b/components/data_reduction_proxy_common.target.linux-x86_64.mk
@@ -0,0 +1,274 @@
+# This file is generated by gyp; do not edit.
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := components_data_reduction_proxy_common_gyp
+LOCAL_MODULE_SUFFIX := .a
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
+gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
+
+# Make sure our deps are built first.
+GYP_TARGET_DEPENDENCIES :=
+
+GYP_GENERATED_OUTPUTS :=
+
+# Make sure our deps and generated files are built first.
+LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) $(GYP_GENERATED_OUTPUTS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_GENERATED_SOURCES :=
+
+GYP_COPIED_SOURCE_ORIGIN_DIRS :=
+
+LOCAL_SRC_FILES := \
+	components/data_reduction_proxy/common/data_reduction_proxy_pref_names.cc \
+	components/data_reduction_proxy/common/data_reduction_proxy_switches.cc
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Debug := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-g \
+	-fomit-frame-pointer \
+	-fdata-sections \
+	-ffunction-sections \
+	-funwind-tables
+
+MY_DEFS_Debug := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=1' \
+	'-DWTF_USE_DYNAMIC_ANNOTATIONS=1' \
+	'-D_DEBUG'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Debug := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Debug := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+# Flags passed to both C and C++ files.
+MY_CFLAGS_Release := \
+	-fstack-protector \
+	--param=ssp-buffer-size=4 \
+	-Werror \
+	-fno-exceptions \
+	-fno-strict-aliasing \
+	-Wall \
+	-Wno-unused-parameter \
+	-Wno-missing-field-initializers \
+	-fvisibility=hidden \
+	-pipe \
+	-fPIC \
+	-Wno-unused-local-typedefs \
+	-m64 \
+	-march=x86-64 \
+	-ffunction-sections \
+	-funwind-tables \
+	-g \
+	-fstack-protector \
+	-fno-short-enums \
+	-finline-limit=64 \
+	-Wa,--noexecstack \
+	-U_FORTIFY_SOURCE \
+	-Wno-extra \
+	-Wno-ignored-qualifiers \
+	-Wno-type-limits \
+	-Wno-unused-but-set-variable \
+	-Os \
+	-fno-ident \
+	-fdata-sections \
+	-ffunction-sections \
+	-fomit-frame-pointer \
+	-funwind-tables
+
+MY_DEFS_Release := \
+	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNO_TCMALLOC' \
+	'-DDISABLE_NACL' \
+	'-DCHROMIUM_BUILD' \
+	'-DUSE_LIBJPEG_TURBO=1' \
+	'-DENABLE_WEBRTC=1' \
+	'-DUSE_PROPRIETARY_CODECS' \
+	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
+	'-DENABLE_EGLIMAGE=1' \
+	'-DCLD_VERSION=1' \
+	'-DENABLE_PRINTING=1' \
+	'-DENABLE_MANAGED_USERS=1' \
+	'-DMOJO_USE_SYSTEM_IMPL' \
+	'-DUSE_OPENSSL=1' \
+	'-DUSE_OPENSSL_CERTS=1' \
+	'-D__STDC_CONSTANT_MACROS' \
+	'-D__STDC_FORMAT_MACROS' \
+	'-DANDROID' \
+	'-D__GNU_SOURCE=1' \
+	'-DUSE_STLPORT=1' \
+	'-D_STLP_USE_PTR_SPECIALIZATIONS=1' \
+	'-DCHROME_BUILD_ID=""' \
+	'-DNDEBUG' \
+	'-DNVALGRIND' \
+	'-DDYNAMIC_ANNOTATIONS_ENABLED=0' \
+	'-D_FORTIFY_SOURCE=2'
+
+
+# Include paths placed before CFLAGS/CPPFLAGS
+LOCAL_C_INCLUDES_Release := \
+	$(gyp_shared_intermediate_dir)/shim_headers/icuuc/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/icui18n/target \
+	$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/third_party/khronos \
+	$(LOCAL_PATH)/gpu \
+	$(LOCAL_PATH)/skia/config \
+	$(LOCAL_PATH)/third_party/WebKit/Source \
+	$(PWD)/frameworks/wilhelm/include \
+	$(PWD)/bionic \
+	$(PWD)/external/stlport/stlport
+
+
+# Flags passed to only C++ (and not C) files.
+LOCAL_CPPFLAGS_Release := \
+	-fno-rtti \
+	-fno-threadsafe-statics \
+	-fvisibility-inlines-hidden \
+	-Wsign-compare \
+	-Wno-non-virtual-dtor \
+	-Wno-sign-promo
+
+
+LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
+LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
+LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+### Rules for final target.
+
+LOCAL_LDFLAGS_Debug := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,--warn-shared-textrel \
+	-Wl,-O1 \
+	-Wl,--as-needed
+
+
+LOCAL_LDFLAGS_Release := \
+	-Wl,-z,now \
+	-Wl,-z,relro \
+	-Wl,--fatal-warnings \
+	-Wl,-z,noexecstack \
+	-fPIC \
+	-m64 \
+	-fuse-ld=gold \
+	-nostdlib \
+	-Wl,--no-undefined \
+	-Wl,--exclude-libs=ALL \
+	-Wl,-O1 \
+	-Wl,--as-needed \
+	-Wl,--gc-sections \
+	-Wl,--warn-shared-textrel
+
+
+LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))
+
+LOCAL_STATIC_LIBRARIES :=
+
+# Enable grouping to fix circular references
+LOCAL_GROUP_STATIC_LIBRARIES := true
+
+LOCAL_SHARED_LIBRARIES := \
+	libstlport \
+	libdl
+
+# Add target alias to "gyp_all_modules" target.
+.PHONY: gyp_all_modules
+gyp_all_modules: components_data_reduction_proxy_common_gyp
+
+# Alias gyp target name.
+.PHONY: data_reduction_proxy_common
+data_reduction_proxy_common: components_data_reduction_proxy_common_gyp
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/components/dom_distiller/DEPS b/components/dom_distiller/DEPS
index a69831c..a82b8ad 100644
--- a/components/dom_distiller/DEPS
+++ b/components/dom_distiller/DEPS
@@ -15,5 +15,4 @@
   # http://www.chromium.org/developers/design-documents/layered-components-design
   "-components/dom_distiller",
   "+components/dom_distiller/core",
-  "-content/public",
 ]
diff --git a/components/dom_distiller/core/javascript/domdistiller.js b/components/dom_distiller/core/javascript/domdistiller.js
index ce0ebd8..62f860b 100644
--- a/components/dom_distiller/core/javascript/domdistiller.js
+++ b/components/dom_distiller/core/javascript/domdistiller.js
@@ -19,6 +19,48 @@
         document.documentElement);
     // TODO(shashishekhar): Add actual previous page link here.
     result[3] = '';
+
+    /**
+     * // Properties from markup tags.
+     *
+     * var parser = new com.dom_distiller.MarkupParser(document.documentElement);
+     * if (!parser.optOut()) {
+     *   // Basic properties.
+     *   var title = parser.getTitle();  // String type.
+     *   var pageType = parser.getType();  // String type.
+     *   var pageUrl = parser.getUrl();  // String type.
+     *   var author = parser.getAuthor();  // String type.
+     *   var description = parser.getDescription();  // String type.
+     *   var publisher = parser.getPublisher();  // String type.
+     *   var copyright = parser.getCopyright();  // String type.
+     *
+     *   // Structured Image's.
+     *   var images = parser.getImages();
+     *   for (var i = 0; i < images.length; i++) {
+     *     var image = images[i];
+     *     var url = image.getUrl();  // String type.
+     *     var secureUrl = image.getSecureUrl();  // String type.
+     *     var type = image.getType();  // String type.
+     *     var caption = image.getCaption();  // String type.
+     *     var width = image.getWidth();  // int type.
+     *     var height = image.getHeight();  // int type.
+     *   }
+     *
+     *   // Structured Article.
+     *   var article = parser.getArticle();
+     *   if (article != null) {
+     *     var publishedTime = article.getPublishedTime();  // String type.
+     *     var modifiedTime = article.getModifiedTime();  // String type.
+     *     var expirationTime = article.getExpirationTime();  // String type.
+     *     var sectionName = article.getSection();  // String type.
+     *     var authors = article.getAuthors();
+     *     for (var i = 0; i < authors.length; i++) {
+     *       var author = authors[i];  // String type.
+     *     }
+     *   }
+     * }
+     */
+
   } catch (e) {
     window.console.log("Error during distillation: " + e);
   }
diff --git a/components/domain_reliability/uploader.cc b/components/domain_reliability/uploader.cc
index 7112b5f..8293bb7 100644
--- a/components/domain_reliability/uploader.cc
+++ b/components/domain_reliability/uploader.cc
@@ -18,6 +18,8 @@
 
 namespace {
 
+const char* kJsonMimeType = "application/json; charset=utf-8";
+
 class UploadUserData : public base::SupportsUserData::Data {
  public:
   static net::URLFetcher::CreateDataCallback CreateCreateDataCallback() {
@@ -61,7 +63,7 @@
     fetcher->SetRequestContext(url_request_context_getter_);
     fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
                           net::LOAD_DO_NOT_SAVE_COOKIES);
-    fetcher->SetUploadData("text/json", report_json);
+    fetcher->SetUploadData(kJsonMimeType, report_json);
     fetcher->SetAutomaticallyRetryOn5xx(false);
     fetcher->SetURLRequestUserData(
         UploadUserData::kUserDataKey,
diff --git a/components/feedback.gypi b/components/feedback.gypi
new file mode 100644
index 0000000..5cbd854
--- /dev/null
+++ b/components/feedback.gypi
@@ -0,0 +1,64 @@
+# 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.
+
+{
+  'targets': [
+    {
+      'target_name': 'feedback_component',
+      'type': 'static_library',
+      'dependencies': [
+        '../base/base.gyp:base',
+        '../content/content.gyp:content_common',
+        '../net/net.gyp:net',
+        '../third_party/zlib/google/zip.gyp:zip',
+        'components.gyp:keyed_service_core',
+        'feedback_proto',
+      ],
+      'include_dirs': [
+        '..',
+      ],
+      'defines': [
+      ],
+      'sources': [
+        'feedback/feedback_data.cc',
+        'feedback/feedback_data.h',
+        'feedback/feedback_report.cc',
+        'feedback/feedback_report.h',
+        'feedback/feedback_switches.cc',
+        'feedback/feedback_switches.h',
+        'feedback/feedback_uploader.cc',
+        'feedback/feedback_uploader.h',
+        'feedback/feedback_uploader_chrome.cc',
+        'feedback/feedback_uploader_chrome.h',
+        'feedback/feedback_uploader_delegate.cc',
+        'feedback/feedback_uploader_delegate.h',
+        'feedback/feedback_uploader_factory.cc',
+        'feedback/feedback_uploader_factory.h',
+        'feedback/feedback_util.cc',
+        'feedback/feedback_util.h',
+        'feedback/tracing_manager.cc',
+        'feedback/tracing_manager.h',
+      ],
+    },
+    {
+      # Protobuf compiler / generate rule for feedback
+      'target_name': 'feedback_proto',
+      'type': 'static_library',
+      'sources': [
+        'feedback/proto/annotations.proto',
+        'feedback/proto/chrome.proto',
+        'feedback/proto/common.proto',
+        'feedback/proto/dom.proto',
+        'feedback/proto/extension.proto',
+        'feedback/proto/math.proto',
+        'feedback/proto/web.proto',
+      ],
+      'variables': {
+        'proto_in_dir': 'feedback/proto',
+        'proto_out_dir': 'components/feedback/proto',
+      },
+      'includes': [ '../build/protoc.gypi' ]
+    },
+  ],
+}
diff --git a/components/feedback/DEPS b/components/feedback/DEPS
new file mode 100644
index 0000000..fba0249
--- /dev/null
+++ b/components/feedback/DEPS
@@ -0,0 +1,10 @@
+include_rules = [
+  "-content",
+  "+components/keyed_service",
+  "+components/user_prefs",
+  "+content/public/browser",
+  "+content/public/test",
+  "+net/base",
+  "+net/url_request",
+  "+third_party/zlib/google/zip.h",
+]
diff --git a/components/feedback/OWNERS b/components/feedback/OWNERS
new file mode 100644
index 0000000..68dad9e
--- /dev/null
+++ b/components/feedback/OWNERS
@@ -0,0 +1,3 @@
+achaulk@chromium.org
+bsimonnet@chromium.org
+zork@chromium.org
\ No newline at end of file
diff --git a/components/feedback/feedback_data.cc b/components/feedback/feedback_data.cc
new file mode 100644
index 0000000..b14ac46
--- /dev/null
+++ b/components/feedback/feedback_data.cc
@@ -0,0 +1,274 @@
+// 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.
+
+#include "components/feedback/feedback_data.h"
+
+#include "base/file_util.h"
+#include "base/json/json_string_value_serializer.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "components/feedback/feedback_util.h"
+#include "components/feedback/tracing_manager.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+namespace feedback {
+namespace {
+
+const char kMultilineIndicatorString[] = "<multiline>\n";
+const char kMultilineStartString[] = "---------- START ----------\n";
+const char kMultilineEndString[] = "---------- END ----------\n\n";
+
+const size_t kFeedbackMaxLength = 4 * 1024;
+const size_t kFeedbackMaxLineCount = 40;
+
+const char kTraceFilename[] = "tracing.zip\n";
+const char kPerformanceCategoryTag[] = "Performance";
+
+const char kZipExt[] = ".zip";
+
+const base::FilePath::CharType kLogsFilename[] =
+    FILE_PATH_LITERAL("system_logs.txt");
+const base::FilePath::CharType kHistogramsFilename[] =
+    FILE_PATH_LITERAL("histograms.txt");
+
+// Converts the system logs into a string that we can compress and send
+// with the report. This method only converts those logs that we want in
+// the compressed zip file sent with the report, hence it ignores any logs
+// below the size threshold of what we want compressed.
+std::string LogsToString(const FeedbackData::SystemLogsMap& sys_info) {
+  std::string syslogs_string;
+  for (FeedbackData::SystemLogsMap::const_iterator it = sys_info.begin();
+      it != sys_info.end(); ++it) {
+    std::string key = it->first;
+    std::string value = it->second;
+
+    if (FeedbackData::BelowCompressionThreshold(value))
+      continue;
+
+    base::TrimString(key, "\n ", &key);
+    base::TrimString(value, "\n ", &value);
+
+    if (value.find("\n") != std::string::npos) {
+      syslogs_string.append(
+          key + "=" + kMultilineIndicatorString +
+          kMultilineStartString +
+          value + "\n" +
+          kMultilineEndString);
+    } else {
+      syslogs_string.append(key + "=" + value + "\n");
+    }
+  }
+  return syslogs_string;
+}
+
+void ZipFile(const base::FilePath& filename,
+             const std::string& data, std::string* compressed_data) {
+  if (!feedback_util::ZipString(filename, data, compressed_data))
+    compressed_data->clear();
+}
+
+void ZipLogs(const FeedbackData::SystemLogsMap& sys_info,
+             std::string* compressed_logs) {
+  DCHECK(compressed_logs);
+  std::string logs_string = LogsToString(sys_info);
+  if (logs_string.empty() ||
+      !feedback_util::ZipString(
+          base::FilePath(kLogsFilename), logs_string, compressed_logs)) {
+    compressed_logs->clear();
+  }
+}
+
+void ZipHistograms(const std::string& histograms,
+                   std::string* compressed_histograms) {
+  DCHECK(compressed_histograms);
+  if (histograms.empty() ||
+      !feedback_util::ZipString(
+          base::FilePath(kHistogramsFilename),
+          histograms,
+          compressed_histograms)) {
+    compressed_histograms->clear();
+  }
+}
+
+}  // namespace
+
+// static
+bool FeedbackData::BelowCompressionThreshold(const std::string& content) {
+  if (content.length() > kFeedbackMaxLength)
+    return false;
+  const size_t line_count = std::count(content.begin(), content.end(), '\n');
+  if (line_count > kFeedbackMaxLineCount)
+    return false;
+  return true;
+}
+
+FeedbackData::FeedbackData() : context_(NULL),
+                               trace_id_(0),
+                               feedback_page_data_complete_(false),
+                               syslogs_compression_complete_(false),
+                               histograms_compression_complete_(false),
+                               attached_file_compression_complete_(false),
+                               report_sent_(false) {
+}
+
+FeedbackData::~FeedbackData() {
+}
+
+void FeedbackData::OnFeedbackPageDataComplete() {
+  feedback_page_data_complete_ = true;
+  SendReport();
+}
+
+void FeedbackData::SetAndCompressSystemInfo(
+    scoped_ptr<FeedbackData::SystemLogsMap> sys_info) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  if (trace_id_ != 0) {
+    TracingManager* manager = TracingManager::Get();
+    if (!manager ||
+        !manager->GetTraceData(
+            trace_id_,
+            base::Bind(&FeedbackData::OnGetTraceData, this, trace_id_))) {
+      trace_id_ = 0;
+    }
+  }
+
+  sys_info_ = sys_info.Pass();
+  if (sys_info_.get()) {
+    std::string* compressed_logs_ptr = new std::string;
+    scoped_ptr<std::string> compressed_logs(compressed_logs_ptr);
+    BrowserThread::PostBlockingPoolTaskAndReply(
+        FROM_HERE,
+        base::Bind(&ZipLogs,
+                   *sys_info_,
+                   compressed_logs_ptr),
+        base::Bind(&FeedbackData::OnCompressLogsComplete,
+                   this,
+                   base::Passed(&compressed_logs)));
+  }
+}
+
+void FeedbackData::SetAndCompressHistograms(
+    scoped_ptr<std::string> histograms) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  histograms_ = histograms.Pass();
+  if (histograms_.get()) {
+    std::string* compressed_histograms_ptr = new std::string;
+    scoped_ptr<std::string> compressed_histograms(compressed_histograms_ptr);
+    BrowserThread::PostBlockingPoolTaskAndReply(
+        FROM_HERE,
+        base::Bind(&ZipHistograms,
+                   *histograms_,
+                   compressed_histograms_ptr),
+        base::Bind(&FeedbackData::OnCompressHistogramsComplete,
+                   this,
+                   base::Passed(&compressed_histograms)));
+  }
+}
+
+void FeedbackData::AttachAndCompressFileData(
+    scoped_ptr<std::string> attached_filedata) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  attached_filedata_ = attached_filedata.Pass();
+
+  if (!attached_filename_.empty() && attached_filedata_.get()) {
+    std::string* compressed_file_ptr = new std::string;
+    scoped_ptr<std::string> compressed_file(compressed_file_ptr);
+#if defined(OS_WIN)
+    base::FilePath attached_file(base::UTF8ToWide(attached_filename_));
+#else
+    base::FilePath attached_file(attached_filename_);
+#endif
+    BrowserThread::PostBlockingPoolTaskAndReply(
+        FROM_HERE,
+        base::Bind(&ZipFile,
+                   attached_file,
+                   *(attached_filedata_.get()),
+                   compressed_file_ptr),
+        base::Bind(&FeedbackData::OnCompressFileComplete,
+                   this,
+                   base::Passed(&compressed_file)));
+  }
+}
+
+void FeedbackData::OnGetTraceData(
+    int trace_id,
+    scoped_refptr<base::RefCountedString> trace_data) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  TracingManager* manager = TracingManager::Get();
+  if (manager)
+    manager->DiscardTraceData(trace_id);
+
+  scoped_ptr<std::string> data(new std::string);
+  data->swap(trace_data->data());
+
+  attached_filename_ = kTraceFilename;
+  attached_filedata_ = data.Pass();
+  attached_file_compression_complete_ = true;
+  trace_id_ = 0;
+
+  set_category_tag(kPerformanceCategoryTag);
+
+  SendReport();
+}
+
+void FeedbackData::OnCompressLogsComplete(
+    scoped_ptr<std::string> compressed_logs) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  compressed_logs_ = compressed_logs.Pass();
+  syslogs_compression_complete_ = true;
+
+  SendReport();
+}
+
+void FeedbackData::OnCompressHistogramsComplete(
+    scoped_ptr<std::string> compressed_histograms) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  compressed_histograms_ = compressed_histograms.Pass();
+  histograms_compression_complete_ = true;
+
+  SendReport();
+}
+
+void FeedbackData::OnCompressFileComplete(
+    scoped_ptr<std::string> compressed_file) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  if (compressed_file.get()) {
+    attached_filedata_ = compressed_file.Pass();
+    attached_filename_.append(kZipExt);
+    attached_file_compression_complete_ = true;
+  } else {
+    attached_filename_.clear();
+    attached_filedata_.reset(NULL);
+  }
+
+  SendReport();
+}
+
+bool FeedbackData::IsDataComplete() {
+  return (!sys_info_.get() || syslogs_compression_complete_) &&
+      (!histograms_.get() || histograms_compression_complete_) &&
+      (!attached_filedata_.get() || attached_file_compression_complete_) &&
+      !trace_id_ &&
+      feedback_page_data_complete_;
+}
+
+void FeedbackData::SendReport() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  if (IsDataComplete() && !report_sent_) {
+    report_sent_ = true;
+    feedback_util::SendReport(this);
+  }
+}
+
+}  // namespace feedback
diff --git a/components/feedback/feedback_data.h b/components/feedback/feedback_data.h
new file mode 100644
index 0000000..68821d9
--- /dev/null
+++ b/components/feedback/feedback_data.h
@@ -0,0 +1,160 @@
+// 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.
+
+#ifndef COMPONENTS_FEEDBACK_FEEDBACK_DATA_H_
+#define COMPONENTS_FEEDBACK_FEEDBACK_DATA_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "url/gurl.h"
+
+namespace base {
+class FilePath;
+class RefCountedString;
+}
+namespace content {
+class BrowserContext;
+}
+
+namespace feedback {
+
+class FeedbackData : public base::RefCountedThreadSafe<FeedbackData> {
+ public:
+  typedef std::map<std::string, std::string> SystemLogsMap;
+
+  // Determine if the given feedback value is small enough to not need to
+  // be compressed.
+  static bool BelowCompressionThreshold(const std::string& content);
+
+  FeedbackData();
+
+  // Called once we've updated all the data from the feedback page.
+  void OnFeedbackPageDataComplete();
+
+  // Sets the system information for this instance and kicks off its
+  // compression.
+  void SetAndCompressSystemInfo(scoped_ptr<SystemLogsMap> sys_info);
+
+  // Sets the histograms for this instance and kicks off its
+  // compression.
+  void SetAndCompressHistograms(scoped_ptr<std::string> histograms);
+
+  // Sets the attached file data and kicks off its compression.
+  void AttachAndCompressFileData(scoped_ptr<std::string> attached_filedata);
+
+  // Called once we have compressed our system logs.
+  void OnCompressLogsComplete(scoped_ptr<std::string> compressed_logs);
+
+  // Called once we have compressed our histograms.
+  void OnCompressHistogramsComplete(
+      scoped_ptr<std::string> compressed_histograms);
+
+  // Called once we have compressed our attached file.
+  void OnCompressFileComplete(scoped_ptr<std::string> compressed_file);
+
+  // Returns true if we've completed all the tasks needed before we can send
+  // feedback - at this time this is includes getting the feedback page data
+  // and compressing the system logs.
+  bool IsDataComplete();
+
+  // Sends the feedback report if we have all our data complete.
+  void SendReport();
+
+  // Getters
+  content::BrowserContext* context() const { return context_; }
+  const std::string& category_tag() const { return category_tag_; }
+  const std::string& page_url() const { return page_url_; }
+  const std::string& description() const { return description_; }
+  const std::string& user_email() const { return user_email_; }
+  std::string* image() const { return image_.get(); }
+  const std::string attached_filename() const { return attached_filename_; }
+  const std::string attached_file_uuid() const { return attached_file_uuid_; }
+  std::string* attached_filedata() const { return attached_filedata_.get(); }
+  const std::string screenshot_uuid() const { return screenshot_uuid_; }
+  int trace_id() const { return trace_id_; }
+  SystemLogsMap* sys_info() const { return sys_info_.get(); }
+  std::string* compressed_logs() const { return compressed_logs_.get(); }
+  std::string* histograms() const { return histograms_.get(); }
+  std::string* compressed_histograms() const {
+    return compressed_histograms_.get();
+  }
+  std::string user_agent() const { return user_agent_; }
+  std::string locale() const { return locale_; }
+
+  // Setters
+  void set_context(content::BrowserContext* context) { context_ = context; }
+  void set_category_tag(const std::string& category_tag) {
+    category_tag_ = category_tag;
+  }
+  void set_page_url(const std::string& page_url) { page_url_ = page_url; }
+  void set_description(const std::string& description) {
+    description_ = description;
+  }
+  void set_user_email(const std::string& user_email) {
+    user_email_ = user_email;
+  }
+  void set_image(scoped_ptr<std::string> image) { image_ = image.Pass(); }
+  void set_attached_filename(const std::string& attached_filename) {
+    attached_filename_ = attached_filename;
+  }
+  void set_attached_file_uuid(const std::string& uuid) {
+    attached_file_uuid_ = uuid;
+  }
+  void set_screenshot_uuid(const std::string& uuid) {
+    screenshot_uuid_ = uuid;
+  }
+  void set_trace_id(int trace_id) { trace_id_ = trace_id; }
+  void set_user_agent(const std::string& user_agent) {
+    user_agent_ = user_agent;
+  }
+  void set_locale(const std::string& locale) { locale_ = locale; }
+
+ private:
+  friend class base::RefCountedThreadSafe<FeedbackData>;
+
+  virtual ~FeedbackData();
+
+  void OnGetTraceData(int trace_id,
+                      scoped_refptr<base::RefCountedString> trace_data);
+
+  content::BrowserContext* context_;
+
+  std::string category_tag_;
+  std::string page_url_;
+  std::string description_;
+  std::string user_email_;
+  scoped_ptr<std::string> image_;
+  std::string attached_filename_;
+  scoped_ptr<std::string> attached_filedata_;
+  std::string user_agent_;
+  std::string locale_;
+
+  std::string attached_file_uuid_;
+  std::string screenshot_uuid_;
+
+  int trace_id_;
+
+  scoped_ptr<SystemLogsMap> sys_info_;
+  scoped_ptr<std::string> compressed_logs_;
+
+  scoped_ptr<std::string> histograms_;
+  scoped_ptr<std::string> compressed_histograms_;
+
+  // TODO(rkc): Refactor compressing logic into a simpler common implementation.
+  bool feedback_page_data_complete_;
+  bool syslogs_compression_complete_;
+  bool histograms_compression_complete_;
+  bool attached_file_compression_complete_;
+  bool report_sent_;
+
+  DISALLOW_COPY_AND_ASSIGN(FeedbackData);
+};
+
+}  // namespace feedback
+
+#endif  // COMPONENTS_FEEDBACK_FEEDBACK_DATA_H_
diff --git a/components/feedback/feedback_report.cc b/components/feedback/feedback_report.cc
new file mode 100644
index 0000000..af48ea6
--- /dev/null
+++ b/components/feedback/feedback_report.cc
@@ -0,0 +1,84 @@
+// 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.
+
+#include "components/feedback/feedback_report.h"
+
+#include "base/file_util.h"
+#include "base/files/file.h"
+#include "base/files/file_enumerator.h"
+#include "base/files/important_file_writer.h"
+#include "base/guid.h"
+#include "base/sequenced_task_runner.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/threading/sequenced_worker_pool.h"
+
+namespace {
+
+const base::FilePath::CharType kFeedbackReportFilenameWildcard[] =
+    FILE_PATH_LITERAL("Feedback Report.*");
+
+const char kFeedbackReportFilenamePrefix[] = "Feedback Report.";
+
+void WriteReportOnBlockingPool(const base::FilePath reports_path,
+                               const base::FilePath& file,
+                               const std::string& data) {
+  DCHECK(reports_path.IsParent(file));
+  if (!base::DirectoryExists(reports_path)) {
+    base::File::Error error;
+    if (!base::CreateDirectoryAndGetError(reports_path, &error))
+      return;
+  }
+  base::ImportantFileWriter::WriteFileAtomically(file, data);
+}
+
+}  // namespace
+
+namespace feedback {
+
+FeedbackReport::FeedbackReport(
+    const base::FilePath& path,
+    const base::Time& upload_at,
+    const std::string& data,
+    scoped_refptr<base::SequencedTaskRunner> task_runner)
+    : reports_path_(path),
+      upload_at_(upload_at),
+      data_(data),
+      reports_task_runner_(task_runner) {
+  if (reports_path_.empty())
+    return;
+  file_ = reports_path_.AppendASCII(
+      kFeedbackReportFilenamePrefix + base::GenerateGUID());
+
+  reports_task_runner_->PostTask(FROM_HERE, base::Bind(
+      &WriteReportOnBlockingPool, reports_path_, file_, data_));
+}
+
+FeedbackReport::~FeedbackReport() {}
+
+void FeedbackReport::DeleteReportOnDisk() {
+  reports_task_runner_->PostTask(FROM_HERE, base::Bind(
+      base::IgnoreResult(&base::DeleteFile), file_, false));
+}
+
+// static
+void FeedbackReport::LoadReportsAndQueue(
+    const base::FilePath& user_dir, QueueCallback callback) {
+  if (user_dir.empty())
+    return;
+
+  base::FileEnumerator enumerator(user_dir,
+                                  false,
+                                  base::FileEnumerator::FILES,
+                                  kFeedbackReportFilenameWildcard);
+  for (base::FilePath name = enumerator.Next();
+       !name.empty();
+       name = enumerator.Next()) {
+    std::string data;
+    if (ReadFileToString(name, &data))
+      callback.Run(data);
+    base::DeleteFile(name, false);
+  }
+}
+
+}  // namespace feedback
diff --git a/components/feedback/feedback_report.h b/components/feedback/feedback_report.h
new file mode 100644
index 0000000..c89e543
--- /dev/null
+++ b/components/feedback/feedback_report.h
@@ -0,0 +1,64 @@
+// 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.
+
+#ifndef COMPONENTS_FEEDBACK_FEEDBACK_REPORT_H_
+#define COMPONENTS_FEEDBACK_FEEDBACK_REPORT_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/callback_forward.h"
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/time/time.h"
+
+namespace base {
+class SequencedTaskRunner;
+}
+
+namespace feedback {
+
+typedef base::Callback<void(const std::string&)> QueueCallback;
+
+// This class holds a feedback report. Once a report is created, a disk backup
+// for it is created automatically. This backup needs to explicitly be
+// deleted by calling DeleteReportOnDisk.
+class FeedbackReport : public base::RefCounted<FeedbackReport> {
+ public:
+  FeedbackReport(const base::FilePath& path,
+                 const base::Time& upload_at,
+                 const std::string& data,
+                 scoped_refptr<base::SequencedTaskRunner> task_runner);
+
+  // Stops the disk write of the report and deletes the report file if already
+  // written.
+  void DeleteReportOnDisk();
+
+  const base::Time& upload_at() const { return upload_at_; }
+  const std::string& data() const { return data_; }
+
+  // Loads the reports still on disk and queues then using the given callback.
+  // This call blocks on the file reads.
+  static void LoadReportsAndQueue(const base::FilePath& user_dir,
+                                  QueueCallback callback);
+
+ private:
+  friend class base::RefCounted<FeedbackReport>;
+  virtual ~FeedbackReport();
+
+  // Name of the file corresponding to this report.
+  base::FilePath file_;
+
+  base::FilePath reports_path_;
+  base::Time upload_at_;  // Upload this report at or after this time.
+  std::string data_;
+
+  scoped_refptr<base::SequencedTaskRunner> reports_task_runner_;
+
+  DISALLOW_COPY_AND_ASSIGN(FeedbackReport);
+};
+
+}  // namespace feedback
+
+#endif  // COMPONENTS_FEEDBACK_FEEDBACK_REPORT_H_
diff --git a/components/feedback/feedback_switches.cc b/components/feedback/feedback_switches.cc
new file mode 100644
index 0000000..74f1bec
--- /dev/null
+++ b/components/feedback/feedback_switches.cc
@@ -0,0 +1,13 @@
+// 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.
+
+#include "components/feedback/feedback_switches.h"
+
+namespace switches {
+
+// Alternative feedback server to use when submitting user feedback
+const char kFeedbackServer[]                = "feedback-server";
+
+}  // namespace switches
+
diff --git a/components/feedback/feedback_switches.h b/components/feedback/feedback_switches.h
new file mode 100644
index 0000000..046a827
--- /dev/null
+++ b/components/feedback/feedback_switches.h
@@ -0,0 +1,16 @@
+// 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.
+
+#ifndef COMPONENTS_FEEDBACK_FEEDBACK_SWITCHES_H_
+#define COMPONENTS_FEEDBACK_FEEDBACK_SWITCHES_H_
+
+namespace switches {
+
+// All switches in alphabetical order. The switches should be documented
+// alongside the definition of their values in the .cc file.
+extern const char kFeedbackServer[];
+
+}  // namespace switches
+
+#endif  // COMPONENTS_FEEDBACK_FEEDBACK_SWITCHES_H_
diff --git a/components/feedback/feedback_uploader.cc b/components/feedback/feedback_uploader.cc
new file mode 100644
index 0000000..01a0d0b
--- /dev/null
+++ b/components/feedback/feedback_uploader.cc
@@ -0,0 +1,110 @@
+// 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.
+
+#include "components/feedback/feedback_uploader.h"
+
+#include "base/callback.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/sequenced_task_runner.h"
+#include "base/task_runner_util.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "components/feedback/feedback_report.h"
+
+namespace feedback {
+namespace {
+
+const char kFeedbackPostUrl[] =
+    "https://www.google.com/tools/feedback/chrome/__submit";
+
+const int64 kRetryDelayMinutes = 60;
+
+const base::FilePath::CharType kFeedbackReportPath[] =
+    FILE_PATH_LITERAL("Feedback Reports");
+
+}  // namespace
+
+bool FeedbackUploader::ReportsUploadTimeComparator::operator()(
+    FeedbackReport* a, FeedbackReport* b) const {
+  return a->upload_at() > b->upload_at();
+}
+
+FeedbackUploader::FeedbackUploader(const base::FilePath& path,
+                                   base::SequencedWorkerPool* pool)
+    : report_path_(path.Append(kFeedbackReportPath)),
+      retry_delay_(base::TimeDelta::FromMinutes(kRetryDelayMinutes)),
+      url_(kFeedbackPostUrl),
+      pool_(pool) {
+  Init();
+}
+
+FeedbackUploader::FeedbackUploader(const base::FilePath& path,
+                                   base::SequencedWorkerPool* pool,
+                                   const std::string& url)
+    : report_path_(path.Append(kFeedbackReportPath)),
+      retry_delay_(base::TimeDelta::FromMinutes(kRetryDelayMinutes)),
+      url_(url),
+      pool_(pool) {
+  Init();
+}
+
+FeedbackUploader::~FeedbackUploader() {}
+
+void FeedbackUploader::Init() {
+  dispatch_callback_ = base::Bind(&FeedbackUploader::DispatchReport,
+                                  AsWeakPtr());
+}
+
+void FeedbackUploader::QueueReport(const std::string& data) {
+  QueueReportWithDelay(data, base::TimeDelta());
+}
+
+void FeedbackUploader::UpdateUploadTimer() {
+  if (reports_queue_.empty())
+    return;
+
+  scoped_refptr<FeedbackReport> report = reports_queue_.top();
+  base::Time now = base::Time::Now();
+  if (report->upload_at() <= now) {
+    reports_queue_.pop();
+    dispatch_callback_.Run(report->data());
+    report->DeleteReportOnDisk();
+  } else {
+    // Stop the old timer and start an updated one.
+    if (upload_timer_.IsRunning())
+      upload_timer_.Stop();
+    upload_timer_.Start(
+        FROM_HERE, report->upload_at() - now, this,
+        &FeedbackUploader::UpdateUploadTimer);
+  }
+}
+
+void FeedbackUploader::RetryReport(const std::string& data) {
+  QueueReportWithDelay(data, retry_delay_);
+}
+
+void FeedbackUploader::QueueReportWithDelay(const std::string& data,
+                                            base::TimeDelta delay) {
+  // Uses a BLOCK_SHUTDOWN file task runner because we really don't want to
+  // lose reports.
+  scoped_refptr<base::SequencedTaskRunner> task_runner =
+      pool_->GetSequencedTaskRunnerWithShutdownBehavior(
+          pool_->GetSequenceToken(),
+          base::SequencedWorkerPool::BLOCK_SHUTDOWN);
+
+  reports_queue_.push(new FeedbackReport(report_path_,
+                                         base::Time::Now() + delay,
+                                         data,
+                                         task_runner));
+  UpdateUploadTimer();
+}
+
+void FeedbackUploader::setup_for_test(
+    const ReportDataCallback& dispatch_callback,
+    const base::TimeDelta& retry_delay) {
+  dispatch_callback_ = dispatch_callback;
+  retry_delay_ = retry_delay;
+}
+
+}  // namespace feedback
diff --git a/components/feedback/feedback_uploader.h b/components/feedback/feedback_uploader.h
new file mode 100644
index 0000000..5b96610
--- /dev/null
+++ b/components/feedback/feedback_uploader.h
@@ -0,0 +1,85 @@
+// 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.
+
+#ifndef COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_H_
+#define COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_H_
+
+#include <queue>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/file_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+
+namespace feedback {
+
+typedef base::Callback<void(const std::string&)> ReportDataCallback;
+
+class FeedbackReport;
+
+// FeedbackUploader is used to add a feedback report to the queue of reports
+// being uploaded. In case uploading a report fails, it is written to disk and
+// tried again when it's turn comes up next in the queue.
+class FeedbackUploader : public base::SupportsWeakPtr<FeedbackUploader> {
+ public:
+  FeedbackUploader(const base::FilePath& path,
+                   base::SequencedWorkerPool* pool);
+  FeedbackUploader(const base::FilePath& path,
+                   base::SequencedWorkerPool* pool,
+                   const std::string& url);
+  virtual ~FeedbackUploader();
+
+  // Queues a report for uploading.
+  virtual void QueueReport(const std::string& data);
+
+  base::FilePath GetFeedbackReportsPath() { return report_path_; }
+
+  bool QueueEmpty() const { return reports_queue_.empty(); }
+
+ protected:
+  friend class FeedbackUploaderTest;
+
+  struct ReportsUploadTimeComparator {
+    bool operator()(FeedbackReport* a, FeedbackReport* b) const;
+  };
+
+  void Init();
+
+  // Dispatches the report to be uploaded.
+  virtual void DispatchReport(const std::string& data) = 0;
+
+  // Update our timer for uploading the next report.
+  void UpdateUploadTimer();
+
+  // Requeue this report with a delay.
+  void RetryReport(const std::string& data);
+
+  void QueueReportWithDelay(const std::string& data, base::TimeDelta delay);
+
+  void setup_for_test(const ReportDataCallback& dispatch_callback,
+                      const base::TimeDelta& retry_delay);
+
+  base::FilePath report_path_;
+  // Timer to upload the next report at.
+  base::OneShotTimer<FeedbackUploader> upload_timer_;
+  // Priority queue of reports prioritized by the time the report is supposed
+  // to be uploaded at.
+  std::priority_queue<scoped_refptr<FeedbackReport>,
+                      std::vector<scoped_refptr<FeedbackReport> >,
+                      ReportsUploadTimeComparator> reports_queue_;
+
+  ReportDataCallback dispatch_callback_;
+  base::TimeDelta retry_delay_;
+  std::string url_;
+  base::SequencedWorkerPool* pool_;
+
+  DISALLOW_COPY_AND_ASSIGN(FeedbackUploader);
+};
+
+}  // namespace feedback
+
+#endif  // COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_H_
diff --git a/components/feedback/feedback_uploader_chrome.cc b/components/feedback/feedback_uploader_chrome.cc
new file mode 100644
index 0000000..75d6e90
--- /dev/null
+++ b/components/feedback/feedback_uploader_chrome.cc
@@ -0,0 +1,58 @@
+// 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.
+
+#include "components/feedback/feedback_uploader_chrome.h"
+
+#include "base/callback.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/task_runner_util.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "components/feedback/feedback_report.h"
+#include "components/feedback/feedback_switches.h"
+#include "components/feedback/feedback_uploader_delegate.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/base/load_flags.h"
+#include "net/url_request/url_fetcher.h"
+#include "url/gurl.h"
+
+using content::BrowserThread;
+
+namespace feedback {
+namespace {
+
+const char kProtoBufMimeType[] = "application/x-protobuf";
+
+}  // namespace
+
+FeedbackUploaderChrome::FeedbackUploaderChrome(
+    content::BrowserContext* context)
+    : FeedbackUploader(context ? context->GetPath() : base::FilePath(),
+                       BrowserThread::GetBlockingPool()),
+      context_(context) {
+  CHECK(context_);
+  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kFeedbackServer))
+    url_ = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+        switches::kFeedbackServer);
+}
+
+void FeedbackUploaderChrome::DispatchReport(const std::string& data) {
+  GURL post_url(url_);
+
+  net::URLFetcher* fetcher = net::URLFetcher::Create(
+      post_url, net::URLFetcher::POST,
+      new FeedbackUploaderDelegate(
+          data,
+          base::Bind(&FeedbackUploaderChrome::UpdateUploadTimer, AsWeakPtr()),
+          base::Bind(&FeedbackUploaderChrome::RetryReport, AsWeakPtr())));
+
+  fetcher->SetUploadData(std::string(kProtoBufMimeType), data);
+  fetcher->SetRequestContext(context_->GetRequestContext());
+  fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
+                        net::LOAD_DO_NOT_SEND_COOKIES);
+  fetcher->Start();
+}
+
+}  // namespace feedback
diff --git a/components/feedback/feedback_uploader_chrome.h b/components/feedback/feedback_uploader_chrome.h
new file mode 100644
index 0000000..6c4381d
--- /dev/null
+++ b/components/feedback/feedback_uploader_chrome.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_CHROME_H_
+#define COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_CHROME_H_
+
+#include "components/feedback/feedback_uploader.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace feedback {
+
+class FeedbackUploaderChrome : public FeedbackUploader,
+                               public KeyedService {
+ public:
+  explicit FeedbackUploaderChrome(content::BrowserContext* context);
+
+  virtual void DispatchReport(const std::string& data) OVERRIDE;
+
+ private:
+  // Browser context this uploader was created for.
+  content::BrowserContext* context_;
+
+  DISALLOW_COPY_AND_ASSIGN(FeedbackUploaderChrome);
+};
+
+}  // namespace feedback
+
+#endif  // COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_CHROME_H_
diff --git a/components/feedback/feedback_uploader_delegate.cc b/components/feedback/feedback_uploader_delegate.cc
new file mode 100644
index 0000000..6fdca6b
--- /dev/null
+++ b/components/feedback/feedback_uploader_delegate.cc
@@ -0,0 +1,64 @@
+// 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.
+
+#include "components/feedback/feedback_uploader_delegate.h"
+
+#include <sstream>
+
+#include "base/logging.h"
+#include "net/url_request/url_fetcher.h"
+
+namespace feedback {
+namespace {
+
+const int kHttpPostSuccessNoContent = 204;
+const int kHttpPostFailNoConnection = -1;
+const int kHttpPostFailClientError = 400;
+const int kHttpPostFailServerError = 500;
+
+}  // namespace
+
+FeedbackUploaderDelegate::FeedbackUploaderDelegate(
+    const std::string& post_body,
+    const base::Closure& success_callback,
+    const ReportDataCallback& error_callback)
+        : post_body_(post_body),
+          success_callback_(success_callback),
+          error_callback_(error_callback) {
+}
+
+FeedbackUploaderDelegate::~FeedbackUploaderDelegate() {}
+
+void FeedbackUploaderDelegate::OnURLFetchComplete(
+    const net::URLFetcher* source) {
+  scoped_ptr<const net::URLFetcher> source_scoper(source);
+
+  std::stringstream error_stream;
+  int response_code = source->GetResponseCode();
+  if (response_code == kHttpPostSuccessNoContent) {
+    error_stream << "Success";
+    success_callback_.Run();
+  } else {
+    // Process the error for debug output
+    if (response_code == kHttpPostFailNoConnection) {
+      error_stream << "No connection to server.";
+    } else if ((response_code > kHttpPostFailClientError) &&
+               (response_code < kHttpPostFailServerError)) {
+      error_stream << "Client error: HTTP response code " << response_code;
+    } else if (response_code > kHttpPostFailServerError) {
+      error_stream << "Server error: HTTP response code " << response_code;
+    } else {
+      error_stream << "Unknown error: HTTP response code " << response_code;
+    }
+    error_callback_.Run(post_body_);
+  }
+
+  LOG(WARNING) << "FEEDBACK: Submission to feedback server ("
+               << source->GetURL() << ") status: " << error_stream.str();
+
+  // This instance won't be used for anything else, delete us.
+  delete this;
+}
+
+}  // namespace feedback
diff --git a/components/feedback/feedback_uploader_delegate.h b/components/feedback/feedback_uploader_delegate.h
new file mode 100644
index 0000000..2729f43
--- /dev/null
+++ b/components/feedback/feedback_uploader_delegate.h
@@ -0,0 +1,40 @@
+// 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.
+
+#ifndef COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_DELEGATE_H_
+#define COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_DELEGATE_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "components/feedback/feedback_uploader.h"
+#include "net/url_request/url_fetcher_delegate.h"
+
+namespace feedback {
+
+// FeedbackUploaderDelegate is a simple http uploader for a feedback report. On
+// succes or failure, it deletes itself, but on failure it also notifies the
+// error callback specified when constructing the class instance.
+class FeedbackUploaderDelegate : public net::URLFetcherDelegate {
+ public:
+  FeedbackUploaderDelegate(const std::string& post_body,
+                           const base::Closure& success_callback,
+                           const ReportDataCallback& error_callback);
+  virtual ~FeedbackUploaderDelegate();
+
+ private:
+  // Overridden from net::URLFetcherDelegate.
+  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
+
+  std::string post_body_;
+  base::Closure success_callback_;
+  ReportDataCallback error_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(FeedbackUploaderDelegate);
+};
+
+}  // namespace feedback
+
+#endif  // COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_DELEGATE_H_
diff --git a/components/feedback/feedback_uploader_factory.cc b/components/feedback/feedback_uploader_factory.cc
new file mode 100644
index 0000000..2e32e0f
--- /dev/null
+++ b/components/feedback/feedback_uploader_factory.cc
@@ -0,0 +1,43 @@
+// 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.
+
+#include "components/feedback/feedback_uploader_factory.h"
+
+#include "base/memory/singleton.h"
+#include "components/feedback/feedback_uploader.h"
+#include "components/feedback/feedback_uploader_chrome.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace feedback {
+
+// static
+FeedbackUploaderFactory* FeedbackUploaderFactory::GetInstance() {
+  return Singleton<FeedbackUploaderFactory>::get();
+}
+
+// static
+FeedbackUploader* FeedbackUploaderFactory::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return static_cast<FeedbackUploaderChrome*>(
+      GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+FeedbackUploaderFactory::FeedbackUploaderFactory()
+    : BrowserContextKeyedServiceFactory(
+          "feedback::FeedbackUploader",
+          BrowserContextDependencyManager::GetInstance()) {}
+
+FeedbackUploaderFactory::~FeedbackUploaderFactory() {}
+
+KeyedService* FeedbackUploaderFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  return new FeedbackUploaderChrome(context);
+}
+
+content::BrowserContext* FeedbackUploaderFactory::GetBrowserContextToUse(
+    content::BrowserContext* context) const {
+  return context;
+}
+
+}  // namespace feedback
diff --git a/components/feedback/feedback_uploader_factory.h b/components/feedback/feedback_uploader_factory.h
new file mode 100644
index 0000000..fe9957d
--- /dev/null
+++ b/components/feedback/feedback_uploader_factory.h
@@ -0,0 +1,47 @@
+// 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.
+
+#ifndef COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_FACTORY_H_
+#define COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_FACTORY_H_
+
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+template<typename T> struct DefaultSingletonTraits;
+
+namespace content {
+class BrowserContext;
+}
+
+namespace feedback {
+
+class FeedbackUploader;
+
+// Singleton that owns the FeedbackUploaders and associates them with profiles;
+class FeedbackUploaderFactory : public BrowserContextKeyedServiceFactory {
+ public:
+  // Returns singleton instance of FeedbackUploaderFactory.
+  static FeedbackUploaderFactory* GetInstance();
+
+  // Returns the Feedback Uploader associated with |context|.
+  static FeedbackUploader* GetForBrowserContext(
+      content::BrowserContext* context);
+
+ private:
+  friend struct DefaultSingletonTraits<FeedbackUploaderFactory>;
+
+  FeedbackUploaderFactory();
+  virtual ~FeedbackUploaderFactory();
+
+  // BrowserContextKeyedServiceFactory overrides:
+  virtual KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const OVERRIDE;
+  virtual content::BrowserContext* GetBrowserContextToUse(
+      content::BrowserContext* context) const OVERRIDE;
+
+  DISALLOW_COPY_AND_ASSIGN(FeedbackUploaderFactory);
+};
+
+}  // namespace feedback
+
+#endif  // COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_FACTORY_H_
diff --git a/components/feedback/feedback_uploader_unittest.cc b/components/feedback/feedback_uploader_unittest.cc
new file mode 100644
index 0000000..6d3a5e5
--- /dev/null
+++ b/components/feedback/feedback_uploader_unittest.cc
@@ -0,0 +1,162 @@
+// 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.
+
+#include "components/feedback/feedback_uploader.h"
+
+#include <set>
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/prefs/testing_pref_service.h"
+#include "base/run_loop.h"
+#include "base/stl_util.h"
+#include "components/feedback/feedback_uploader_chrome.h"
+#include "components/feedback/feedback_uploader_factory.h"
+#include "components/user_prefs/user_prefs.h"
+#include "content/public/test/test_browser_context.h"
+#include "content/public/test/test_browser_thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const char kReportOne[] = "one";
+const char kReportTwo[] = "two";
+const char kReportThree[] = "three";
+const char kReportFour[] = "four";
+const char kReportFive[] = "five";
+
+const base::TimeDelta kRetryDelayForTest =
+    base::TimeDelta::FromMilliseconds(100);
+
+KeyedService* CreateFeedbackUploaderService(content::BrowserContext* context) {
+  return new feedback::FeedbackUploaderChrome(context);
+}
+
+}  // namespace
+
+namespace feedback {
+
+class FeedbackUploaderTest : public testing::Test {
+ protected:
+  FeedbackUploaderTest()
+     : ui_thread_(content::BrowserThread::UI, &message_loop_),
+       context_(new content::TestBrowserContext()),
+       dispatched_reports_count_(0),
+       expected_reports_(0) {
+    user_prefs::UserPrefs::Set(context_.get(), new TestingPrefServiceSimple());
+    FeedbackUploaderFactory::GetInstance()->SetTestingFactory(
+        context_.get(), &CreateFeedbackUploaderService);
+
+    uploader_ = FeedbackUploaderFactory::GetForBrowserContext(context_.get());
+    uploader_->setup_for_test(
+        base::Bind(&FeedbackUploaderTest::MockDispatchReport,
+                   base::Unretained(this)),
+        kRetryDelayForTest);
+  }
+
+  virtual ~FeedbackUploaderTest() {
+    FeedbackUploaderFactory::GetInstance()->SetTestingFactory(
+        context_.get(), NULL);
+  }
+
+  void QueueReport(const std::string& data) {
+    uploader_->QueueReport(data);
+  }
+
+  void ReportFailure(const std::string& data) {
+    uploader_->RetryReport(data);
+  }
+
+  void MockDispatchReport(const std::string& report_data) {
+    if (ContainsKey(dispatched_reports_, report_data)) {
+      dispatched_reports_[report_data]++;
+    } else {
+      dispatched_reports_[report_data] = 1;
+    }
+    dispatched_reports_count_++;
+
+    // Dispatch will always update the timer, whether successful or not,
+    // simulate the same behavior.
+    uploader_->UpdateUploadTimer();
+
+    if (ProcessingComplete()) {
+      if (run_loop_.get())
+        run_loop_->Quit();
+    }
+  }
+
+  bool ProcessingComplete() {
+    return (dispatched_reports_count_ >= expected_reports_);
+  }
+
+  void RunMessageLoop() {
+    if (ProcessingComplete())
+      return;
+    run_loop_.reset(new base::RunLoop());
+    run_loop_->Run();
+  }
+
+  base::MessageLoop message_loop_;
+  scoped_ptr<base::RunLoop> run_loop_;
+  content::TestBrowserThread ui_thread_;
+  scoped_ptr<content::TestBrowserContext> context_;
+
+  FeedbackUploader* uploader_;
+
+  std::map<std::string, unsigned int> dispatched_reports_;
+  size_t dispatched_reports_count_;
+  size_t expected_reports_;
+};
+
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+#define MAYBE_QueueMultiple QueueMultiple
+#else
+// crbug.com/330547
+#define MAYBE_QueueMultiple DISABLED_QueueMultiple
+#endif
+TEST_F(FeedbackUploaderTest, MAYBE_QueueMultiple) {
+  dispatched_reports_.clear();
+  QueueReport(kReportOne);
+  QueueReport(kReportTwo);
+  QueueReport(kReportThree);
+  QueueReport(kReportFour);
+
+  EXPECT_EQ(dispatched_reports_.size(), 4u);
+  EXPECT_EQ(dispatched_reports_[kReportOne], 1u);
+  EXPECT_EQ(dispatched_reports_[kReportTwo], 1u);
+  EXPECT_EQ(dispatched_reports_[kReportThree], 1u);
+  EXPECT_EQ(dispatched_reports_[kReportFour], 1u);
+}
+
+#if defined(OS_WIN) || defined(OS_ANDROID)
+// crbug.com/330547
+#define MAYBE_QueueMultipleWithFailures DISABLED_QueueMultipleWithFailures
+#else
+#define MAYBE_QueueMultipleWithFailures QueueMultipleWithFailures
+#endif
+TEST_F(FeedbackUploaderTest, MAYBE_QueueMultipleWithFailures) {
+  dispatched_reports_.clear();
+
+  QueueReport(kReportOne);
+  QueueReport(kReportTwo);
+  QueueReport(kReportThree);
+  QueueReport(kReportFour);
+
+  ReportFailure(kReportThree);
+  ReportFailure(kReportTwo);
+  QueueReport(kReportFive);
+
+  expected_reports_ = 7;
+  RunMessageLoop();
+
+  EXPECT_EQ(dispatched_reports_.size(), 5u);
+  EXPECT_EQ(dispatched_reports_[kReportOne], 1u);
+  EXPECT_EQ(dispatched_reports_[kReportTwo], 2u);
+  EXPECT_EQ(dispatched_reports_[kReportThree], 2u);
+  EXPECT_EQ(dispatched_reports_[kReportFour], 1u);
+  EXPECT_EQ(dispatched_reports_[kReportFive], 1u);
+}
+
+}  // namespace feedback
diff --git a/components/feedback/feedback_util.cc b/components/feedback/feedback_util.cc
new file mode 100644
index 0000000..f6b4d00
--- /dev/null
+++ b/components/feedback/feedback_util.cc
@@ -0,0 +1,187 @@
+// 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.
+
+#include "components/feedback/feedback_util.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "components/feedback/feedback_data.h"
+#include "components/feedback/feedback_uploader.h"
+#include "components/feedback/feedback_uploader_factory.h"
+#include "components/feedback/proto/common.pb.h"
+#include "components/feedback/proto/dom.pb.h"
+#include "components/feedback/proto/extension.pb.h"
+#include "components/feedback/proto/math.pb.h"
+#include "third_party/zlib/google/zip.h"
+
+using feedback::FeedbackData;
+
+namespace {
+
+const char kPngMimeType[] = "image/png";
+const char kArbitraryMimeType[] = "application/octet-stream";
+const char kHistogramsAttachmentName[] = "histograms.zip";
+const char kLogsAttachmentName[] = "system_logs.zip";
+
+#if defined(OS_CHROMEOS)
+const int kChromeOSProductId = 208;
+#else
+const int kChromeBrowserProductId = 237;
+#endif
+
+void AddFeedbackData(userfeedback::ExtensionSubmit* feedback_data,
+                     const std::string& key, const std::string& value) {
+  // Don't bother with empty keys or values
+  if (key == "" || value == "") return;
+  // Create log_value object and add it to the web_data object
+  userfeedback::ProductSpecificData log_value;
+  log_value.set_key(key);
+  log_value.set_value(value);
+  userfeedback::WebData* web_data = feedback_data->mutable_web_data();
+  *(web_data->add_product_specific_data()) = log_value;
+}
+
+// Adds data as an attachment to feedback_data if the data is non-empty.
+void AddAttachment(userfeedback::ExtensionSubmit* feedback_data,
+                   const char* name,
+                   std::string* data) {
+  if (data == NULL || data->empty())
+    return;
+
+  userfeedback::ProductSpecificBinaryData* attachment =
+      feedback_data->add_product_specific_binary_data();
+  attachment->set_mime_type(kArbitraryMimeType);
+  attachment->set_name(name);
+  attachment->set_data(*data);
+}
+
+}  // namespace
+
+namespace feedback_util {
+
+void SendReport(scoped_refptr<FeedbackData> data) {
+  if (!data.get()) {
+    LOG(ERROR) << "SendReport called with NULL data!";
+    NOTREACHED();
+    return;
+  }
+
+  userfeedback::ExtensionSubmit feedback_data;
+  // Unused field, needs to be 0 though.
+  feedback_data.set_type_id(0);
+
+  userfeedback::CommonData* common_data = feedback_data.mutable_common_data();
+  // We're not using gaia ids, we're using the e-mail field instead.
+  common_data->set_gaia_id(0);
+  common_data->set_user_email(data->user_email());
+  common_data->set_description(data->description());
+  common_data->set_source_description_language(data->locale());
+
+  userfeedback::WebData* web_data = feedback_data.mutable_web_data();
+  web_data->set_url(data->page_url());
+  web_data->mutable_navigator()->set_user_agent(data->user_agent());
+
+  if (data->sys_info()) {
+    for (FeedbackData::SystemLogsMap::const_iterator i =
+        data->sys_info()->begin(); i != data->sys_info()->end(); ++i) {
+      if (FeedbackData::BelowCompressionThreshold(i->second))
+        AddFeedbackData(&feedback_data, i->first, i->second);
+    }
+
+    AddAttachment(&feedback_data, kLogsAttachmentName, data->compressed_logs());
+  }
+
+  if (data->histograms()) {
+    AddAttachment(&feedback_data,
+                  kHistogramsAttachmentName,
+                  data->compressed_histograms());
+  }
+
+  if (!data->attached_filename().empty()) {
+    // We need to use the UTF8Unsafe methods here to accomodate Windows, which
+    // uses wide strings to store filepaths.
+    std::string name = base::FilePath::FromUTF8Unsafe(
+        data->attached_filename()).BaseName().AsUTF8Unsafe();
+    AddAttachment(&feedback_data, name.c_str(), data->attached_filedata());
+  }
+
+  // NOTE: Screenshot needs to be processed after system info since we'll get
+  // the screenshot dimensions from system info.
+  if (data->image() && data->image()->size()) {
+    userfeedback::PostedScreenshot screenshot;
+    screenshot.set_mime_type(kPngMimeType);
+
+    // Set that we 'have' dimensions of the screenshot. These dimensions are
+    // ignored by the server but are a 'required' field in the protobuf.
+    userfeedback::Dimensions dimensions;
+    dimensions.set_width(0.0);
+    dimensions.set_height(0.0);
+
+    *(screenshot.mutable_dimensions()) = dimensions;
+    screenshot.set_binary_content(*data->image());
+
+    *(feedback_data.mutable_screenshot()) = screenshot;
+  }
+
+  if (data->category_tag().size())
+    feedback_data.set_bucket(data->category_tag());
+
+  // Set whether we're reporting from ChromeOS or Chrome on another platform.
+  userfeedback::ChromeData chrome_data;
+#if defined(OS_CHROMEOS)
+  chrome_data.set_chrome_platform(
+      userfeedback::ChromeData_ChromePlatform_CHROME_OS);
+  userfeedback::ChromeOsData chrome_os_data;
+  chrome_os_data.set_category(
+      userfeedback::ChromeOsData_ChromeOsCategory_OTHER);
+  *(chrome_data.mutable_chrome_os_data()) = chrome_os_data;
+  feedback_data.set_product_id(kChromeOSProductId);
+#else
+  chrome_data.set_chrome_platform(
+      userfeedback::ChromeData_ChromePlatform_CHROME_BROWSER);
+  userfeedback::ChromeBrowserData chrome_browser_data;
+  chrome_browser_data.set_category(
+      userfeedback::ChromeBrowserData_ChromeBrowserCategory_OTHER);
+  *(chrome_data.mutable_chrome_browser_data()) = chrome_browser_data;
+  feedback_data.set_product_id(kChromeBrowserProductId);
+#endif
+
+  *(feedback_data.mutable_chrome_data()) = chrome_data;
+
+  // This pointer will eventually get deleted by the PostCleanup class, after
+  // we've either managed to successfully upload the report or died trying.
+  std::string post_body;
+  feedback_data.SerializeToString(&post_body);
+
+  feedback::FeedbackUploader *uploader =
+      feedback::FeedbackUploaderFactory::GetForBrowserContext(data->context());
+  uploader->QueueReport(post_body);
+}
+
+bool ZipString(const base::FilePath& filename,
+               const std::string& data, std::string* compressed_logs) {
+  base::FilePath temp_path;
+  base::FilePath zip_file;
+
+  // Create a temporary directory, put the logs into a file in it. Create
+  // another temporary file to receive the zip file in.
+  if (!base::CreateNewTempDirectory(base::FilePath::StringType(), &temp_path))
+    return false;
+  if (base::WriteFile(temp_path.Append(filename), data.c_str(), data.size()) ==
+      -1)
+    return false;
+
+  bool succeed = base::CreateTemporaryFile(&zip_file) &&
+      zip::Zip(temp_path, zip_file, false) &&
+      base::ReadFileToString(zip_file, compressed_logs);
+
+  base::DeleteFile(temp_path, true);
+  base::DeleteFile(zip_file, false);
+
+  return succeed;
+}
+
+}  // namespace feedback_util
diff --git a/components/feedback/feedback_util.h b/components/feedback/feedback_util.h
new file mode 100644
index 0000000..0446035
--- /dev/null
+++ b/components/feedback/feedback_util.h
@@ -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.
+
+#ifndef COMPONENTS_FEEDBACK_FEEDBACK_UTIL_H_
+#define COMPONENTS_FEEDBACK_FEEDBACK_UTIL_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+
+#if defined(OS_MACOSX)
+#include "base/sys_info.h"
+#elif defined(OS_WIN)
+#include "base/win/windows_version.h"
+#endif
+
+class Profile;
+
+namespace content {
+class WebContents;
+}
+
+namespace chrome {
+extern const char kAppLauncherCategoryTag[];
+}  // namespace chrome
+
+namespace feedback {
+class FeedbackData;
+}
+
+namespace feedback_util {
+
+  void SendReport(scoped_refptr<feedback::FeedbackData> data);
+  bool ZipString(const base::FilePath& filename,
+                 const std::string& data, std::string* compressed_data);
+
+}  // namespace feedback_util
+
+#endif  // COMPONENTS_FEEDBACK_FEEDBACK_UTIL_H_
diff --git a/components/feedback/proto/annotations.proto b/components/feedback/proto/annotations.proto
new file mode 100644
index 0000000..9de845f
--- /dev/null
+++ b/components/feedback/proto/annotations.proto
@@ -0,0 +1,29 @@
+// 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.
+
+// Messages containing data about the annotations drawn on the screenshot of a 
+// web page.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package userfeedback;
+
+import "math.proto";
+import "dom.proto";
+
+// An annotation drawn by the user on the screenshot of a web page.
+message Annotation {
+  // A rectangular area covered by this annotation on annotated image.
+  // The (0, 0) coordinate is placed in the top-left corner of the image.
+  // One unit corresponds to one pixel.
+  required Rectangle rectangle = 1;
+
+  // A snippet of text displayed inside annotated portion of a web page.
+  optional string snippet = 2;
+
+  // A path from root element of the document to the annotated element.
+  optional HtmlPath annotatedElementPath = 3;
+};
diff --git a/components/feedback/proto/chrome.proto b/components/feedback/proto/chrome.proto
new file mode 100644
index 0000000..5c722f6
--- /dev/null
+++ b/components/feedback/proto/chrome.proto
@@ -0,0 +1,60 @@
+// 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package userfeedback;
+
+// Chrome Browser and Chrome OS specific data.
+message ChromeData {
+  // Encapsulates the priorities of Buganizer issues.
+  enum ChromePlatform {
+    CHROME_OS = 1;
+    CHROME_BROWSER = 2;
+  }
+
+  // What platform has a report been sent from.
+  optional ChromePlatform chrome_platform = 1 [default = CHROME_OS];
+
+  optional ChromeOsData chrome_os_data = 2;
+
+  optional ChromeBrowserData chrome_browser_data = 3;
+}
+
+message ChromeOsData {
+  enum ChromeOsCategory {
+    CONNECTIVITY = 1;
+    SYNC = 2;
+    CRASH = 3;
+    PAGE_FORMATTING_OR_LAYOUT = 4;
+    EXTENSIONS_OR_APPS = 5;
+    STANDBY_OR_RESUME = 6;
+    PHISHING_PAGE = 7;
+    OTHER = 8;
+    AUTOFILL = 9;
+  }
+
+  optional ChromeOsCategory category = 1 [default = OTHER];
+}
+
+message ChromeBrowserData{
+
+  enum ChromeBrowserCategory {
+    PAGE_FORMATTING_OR_LAYOUT = 1;
+    PAGES_NOT_LOADING = 2;
+    PLUGINS = 3;
+    TABS_OR_WINDOWS = 4;
+    SYNCED_PREFERENCES = 5;
+    CRASH = 6;
+    EXTENSIONS_OR_APPS = 7;
+    PHISHING_PAGE = 8;
+    OTHER = 9;
+    AUTOFILL = 10;
+  }
+
+  optional ChromeBrowserCategory category = 1 [default = OTHER];
+}
+
diff --git a/components/feedback/proto/common.proto b/components/feedback/proto/common.proto
new file mode 100644
index 0000000..349d173
--- /dev/null
+++ b/components/feedback/proto/common.proto
@@ -0,0 +1,31 @@
+// 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.
+
+// Basic messages used by all systems (extension, feedbackserver,
+// silver-bullet clustering, android etc).
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package userfeedback;
+
+// Data present in all kinds of feedbacks, regardless of source (Web, Android,
+// other).
+message CommonData {
+  optional fixed64 gaia_id = 1;
+
+  // Description of the problem entered by user.
+  optional string description = 2;
+  optional string description_translated = 4;
+  optional string source_description_language = 5 [ default = "en" ];
+  optional string ui_language = 6 [ default = "en_US" ];
+
+  optional string user_email = 3;
+  
+  // Unique identifier of feedback report. If set than only one report
+  // with the same identifier is stored in the system.
+  // If you are not sure how to use it leave it not set.
+  optional string unique_report_identifier = 7;
+};
diff --git a/components/feedback/proto/config.proto b/components/feedback/proto/config.proto
new file mode 100644
index 0000000..ad09505
--- /dev/null
+++ b/components/feedback/proto/config.proto
@@ -0,0 +1,142 @@
+// 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.
+
+// Messages containing configuration of Feedback Service
+// that control classification and processing of submitted feedbacks.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package userfeedback;
+
+// Product for which feedback can be sent: GMail, Writely etc.
+message Product {
+  required int32 id = 1;
+
+  required string name = 2;
+
+  repeated string owner = 3;
+};
+
+// Contains information needed to check whether particular
+// feedback type applies to the page user is browsing and forward
+// it's execution to a specific handler. It also carries information
+// about the creator.
+// TODO(morgwai): design new structure of Type with fields relevant
+// for android, web, selenium grouped into submessages.
+message FeedbackTypeData {
+  // index of feedback type as found in database
+  required int32 id = 1;
+
+  // Specifies whether this feedback type is currently enabled and
+  // feedback of this type can be submitted.
+  required bool enabled = 2;
+
+  // Problem name of this feedback type on Google Feedback pages.
+  required string problem_name = 3;
+
+  // Name of the product to which this feedback type belongs.
+  optional string product_name = 4;
+
+  // Tag 5 is used by some legacy data that is already in production db.
+
+  // matcher to execute against page
+  required MatcherData matcher = 6;
+
+  // Comma separated list of email addresses to which email notification
+  // is sent upon each new feedback of this type.
+  // No email is sent if this field is set to an empty string.
+  required string notification_email = 7;
+
+  // Do not use tag 8, 9, 10. They were used by a legacy field.
+
+  // Encapsulates different kind of feedback type.
+  enum Kind {
+    // Product feedback type.
+    PRODUCT = 1;
+    // Special feedback type (e.g. fixit).
+    SPECIAL = 2;
+  }
+
+  // Kind of feedback type.
+  optional Kind kind = 11 [default=PRODUCT];
+
+  // Prefix to be added to summary of notification email sent for feedback of this
+  // type.
+  optional string summary_prefix = 12;
+
+  // String template with which "Additional Info" field in extension
+  // should be initially filled.
+  optional string template = 13;
+
+  // ID of the product this feedback type belongs to.
+  optional int32 product_id = 14;
+
+  // Tag that is used for marking feedback types that require non-ordinary handling.
+  // E.g: This field is equal:
+  // "unclassified" for Unclassified feedback,
+  // "android" for android feedback
+  // "selenium" for selenium feedback
+  optional string tag = 15;
+
+  // Problem description visible in feedback extension.
+  optional string problem_description = 16;
+
+  // Visibilities of feedback type.
+  enum Visibility {
+    // feedback type visible in external extension only
+    EXTERNAL = 1;
+    // feedback type visible in internal extension only
+    INTERNAL = 2;
+  }
+
+  // Specifies the visibility of this feedback type.
+  optional Visibility visibility = 17 [default=INTERNAL];
+
+  // tag 18 was used by removed field
+
+  // Specifies Buganizer fields
+  // TODO(kaczmarek): enable once we migrated to new protos.
+  // optional BuganizerSettings buganizer_settings = 19;
+
+  // Channel via which notification about feedback should be send
+  enum NotifyChannel {
+    // Send email notification.
+    EMAIL = 1;
+    // File a bug in buganizer.
+    BUGANIZER = 2;
+    // File a bug in issue tracker.
+    ISSUE_TRACKER = 3;
+  }
+
+  // Specifies channel via which notification about feedback of this type should be sent.
+  optional NotifyChannel notify_channel = 20 [default=EMAIL];
+
+  // Granularity of notifications.
+  enum NotificationGranularity {
+    // Send notification per each feedback.
+    FEEDBACK = 1;
+    // Send notification per clustered group of similar feedbacks.
+    CLUSTER = 2;
+  }
+
+  // Specifies granularity of notifications send for feedbacks of this type.
+  optional NotificationGranularity notification_granularity = 21 [default=FEEDBACK];
+
+  // Threshold for number of feedbacks in a cluster at which notification is sent.
+  optional int32 clustering_threshold = 22 [default=5];
+};
+
+// Used to detect content relevant to particular type of feedback.
+message MatcherData {
+  // XPATH expression to match against page.
+  required string content_matcher = 1;
+
+  // Regexp matching page URL.
+  required string url_matcher = 2;
+
+  // Approval by feedback admins
+  optional bool url_matcher_approved = 3 [default=true];
+};
diff --git a/components/feedback/proto/dom.proto b/components/feedback/proto/dom.proto
new file mode 100644
index 0000000..0366b1b
--- /dev/null
+++ b/components/feedback/proto/dom.proto
@@ -0,0 +1,101 @@
+// 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.
+
+// Messages containing DOM data captured from the browser.
+// It includes the structure of the HTML document and Navigator data.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package userfeedback;
+
+// Data captured from HTMLDocument DOM object.
+message HtmlDocument {
+
+  // The value of document.URL property.
+  required string url = 1;
+
+  // The value of document.title property.
+  optional string title = 2;
+
+  // The value of document.documentElement property.
+  optional HtmlElement document_element = 3;
+};
+
+// Data captured from HTMLElement DOM object.
+message HtmlElement {
+
+  // The value of element.tagName property.
+  required string tag_name = 1;
+
+  // The value of element.id property.
+  optional string id = 2;
+
+  // The value of element.className property.
+  optional string class_name = 3;
+
+  // A list of child elements.
+  repeated HtmlElement child_element = 4;
+
+  // The value of frame.contentDocument property for FRAME and IFRAME elements.
+  optional HtmlDocument frame_content_document = 5;
+};
+
+// Data captured from DOM Navigator object.
+message Navigator {
+
+  // The value of 'navigator.appCodeName' property.
+  optional string app_code_name = 1;
+
+  // The value of 'navigator.appName' property.
+  optional string app_name = 2;
+
+  // The value of 'navigator.appVersion' property.
+  optional string app_version = 3;
+
+  // The value of 'navigator.appMinorVersion' property.
+  optional string app_minor_version = 4;
+
+  // The value of 'navigator.cookieEnabled' property.
+  optional bool cookie_enabled = 5;
+
+  // The value of 'navigator.cpuClass' property.
+  optional string cpu_class = 6;
+
+  // The value of 'navigator.onLine' property.
+  optional bool on_line = 7;
+
+  // The value of 'navigator.platform' property.
+  optional string platform = 8;
+
+  // The value of 'navigator.browserLanguage' property.
+  optional string browser_language = 9;
+
+  // The value of 'navigator.systemLanguage' property.
+  optional string system_language = 10;
+
+  // The value of 'navigator.userAgent' property.
+  optional string user_agent = 11;
+
+  // The return value of 'navigator.javaEnabled()' method.
+  optional bool java_enabled = 12;
+
+  // The return value of 'navigator.taintEnabled()' method.
+  optional bool taint_enabled = 13;
+
+  // Plugin names specified by 'navigator.plugins' property.
+  repeated string plugin_name = 14;
+};
+
+// A path in the HTML document between two elements, which are in the
+// ancestor-descendant relationship.
+message HtmlPath {
+
+  // Ordered list of zero-based indices.
+  // Empty path selects root element.
+  // Non-negative index N selects (N+1)-th child.
+  // Index -1 selects root element from frame content document.
+  repeated int32 index = 1;
+};
diff --git a/components/feedback/proto/extension.proto b/components/feedback/proto/extension.proto
new file mode 100644
index 0000000..2b9800f
--- /dev/null
+++ b/components/feedback/proto/extension.proto
@@ -0,0 +1,85 @@
+// 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.
+
+// Messages sent from extension to feedback server as JSON.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package userfeedback;
+
+import "common.proto";
+import "chrome.proto";
+import "dom.proto";
+import "math.proto";
+import "web.proto";
+
+// Sent along with request for extension page when user attempts to open
+// feedback tab.
+message ExtensionPageRequestParams {
+
+  required ExtensionDetails extension_details = 1;
+
+  // Url of the page (without request params) that user wants to open
+  // feedback tool for.
+  required string url = 2;
+};
+
+message PostedScreenshot {
+
+  required string mime_type = 1;
+
+  required Dimensions dimensions = 2;
+
+  optional string base64_content = 3;
+
+  optional bytes binary_content = 4;
+};
+
+// Contains data about possible errors on the client side.
+// Describes number of attempts to send feedback and possible error codes/
+// exceptions which occured.
+message ExtensionErrors {
+
+  required int32 number_of_attempts = 1;
+
+  required string errors = 2;
+};
+
+// Sent when user hits final submit button.
+message ExtensionSubmit {
+
+  required CommonData common_data = 1;
+
+  required WebData web_data = 2;
+
+  required int32 type_id = 3;
+
+  optional PostedScreenshot screenshot = 4;
+
+  optional ChromeData chrome_data = 14;
+
+  repeated ProductSpecificBinaryData product_specific_binary_data = 15;
+
+  optional string category_tag = 16;
+
+  optional int32 product_id = 17;
+
+  optional string bucket = 18;
+};
+
+// A query for suggestions, sent when the user hits the preview button.
+message SuggestQuery {
+
+  required CommonData common_data = 1;
+
+  required WebData web_data = 2;
+
+  required int32 type_id = 3;
+
+  optional HtmlDocument html_document_structure = 4;
+
+  optional ChromeData chrome_data = 5;
+};
diff --git a/components/feedback/proto/math.proto b/components/feedback/proto/math.proto
new file mode 100644
index 0000000..e523c72
--- /dev/null
+++ b/components/feedback/proto/math.proto
@@ -0,0 +1,25 @@
+// 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.
+
+// Messages containing common math data structures.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package userfeedback;
+
+// 2D Dimensions.
+message Dimensions {
+  required float width = 1;
+  required float height = 2;
+};
+
+// Axis-aligned rectangle in 2D space.
+message Rectangle {
+  required float left = 1;
+  required float top = 2;
+  required float width = 3;
+  required float height = 4;
+};
diff --git a/components/feedback/proto/web.proto b/components/feedback/proto/web.proto
new file mode 100644
index 0000000..655292f
--- /dev/null
+++ b/components/feedback/proto/web.proto
@@ -0,0 +1,87 @@
+// 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.
+
+syntax = "proto2";
+
+package userfeedback;
+
+option optimize_for = LITE_RUNTIME;
+
+// Data present in Web related feedbacks
+
+import "annotations.proto";
+import "dom.proto";
+import "math.proto";
+
+// Data present in feedbacks sent from web extension.
+message WebData {
+  // Data captured from DOM Navigator object.
+  optional Navigator navigator = 1;
+
+  // Details of the extension from which this data was sent.
+  optional ExtensionDetails extension_details = 2;
+
+  // The URL of the document.
+  // Useful when user opts out from sending html structure.
+  optional string url = 3;
+
+  // A list of annotations.
+  repeated Annotation annotation = 4;
+
+  // The ID of the suggestion selected by the user.
+  // Possible values:
+  // - Not set if no suggestions were shown, either because the version of
+  //   the client did not support suggestions, suggestions were disabled or
+  //   no matching suggestions were found.
+  // - NONE_OF_THE_ABOVE if the user has chosen "None of the above".
+  // - Empty string if suggestions were shown but the user hasn't chosen
+  //   any of them (and also she hasn't chosen "None of the above").
+  // - Actual suggestion identifier as returned from the server.
+  optional string suggestion_id = 5;
+
+  repeated ProductSpecificData product_specific_data = 6;
+
+  // Name of the binary data stored. Replicated from
+  // ProductSpecificBinaryData.name which is stored as a separate
+  // column in Feedbacks3 megastore table.
+  repeated string product_specific_binary_data_name = 7;
+};
+
+message ExtensionDetails {
+  // Indicates browser and mpm release.
+  required string extension_version = 1;
+
+  required string protocol_version = 2;
+};
+
+// Additional data sent by the internal version.
+message InternalWebData {
+  // List of user names in google.com domain to which feedback should be sent
+  // directly apart from submitting it to server.
+  repeated string email_receiver = 1;
+
+  // Subject of the problem entered by user.
+  optional string subject = 2;
+
+  // If this flag is set then product support team should be notified
+  // immediately.
+  optional bool DEPRECATED_urgent = 3 [default = false];
+};
+
+// Product specific data. Contains one key/value pair that is specific to the
+// product for which feedback is submitted.
+message ProductSpecificData {
+  required string key = 1;
+  optional string value = 2;
+};
+
+message ProductSpecificBinaryData {
+  required string name = 1;
+
+  // mime_type of data
+  optional string mime_type = 2;
+
+  // raw data
+  optional bytes data = 3;
+};
diff --git a/components/feedback/tracing_manager.cc b/components/feedback/tracing_manager.cc
new file mode 100644
index 0000000..5298c2f
--- /dev/null
+++ b/components/feedback/tracing_manager.cc
@@ -0,0 +1,142 @@
+// 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.
+
+#include "components/feedback/tracing_manager.h"
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/location.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "components/feedback/feedback_util.h"
+#include "content/public/browser/tracing_controller.h"
+
+namespace {
+// Only once trace manager can exist at a time.
+TracingManager* g_tracing_manager = NULL;
+// Trace IDs start at 1 and increase.
+int g_next_trace_id = 1;
+// Name of the file to store the tracing data as.
+const base::FilePath::CharType kTracingFilename[] =
+    FILE_PATH_LITERAL("tracing.json");
+}
+
+TracingManager::TracingManager()
+    : current_trace_id_(0),
+      weak_ptr_factory_(this) {
+  DCHECK(!g_tracing_manager);
+  g_tracing_manager = this;
+  StartTracing();
+}
+
+TracingManager::~TracingManager() {
+  DCHECK(g_tracing_manager == this);
+  g_tracing_manager = NULL;
+}
+
+int TracingManager::RequestTrace() {
+  // Return the current trace if one is being collected.
+  if (current_trace_id_)
+    return current_trace_id_;
+
+  current_trace_id_ = g_next_trace_id;
+  ++g_next_trace_id;
+  content::TracingController::GetInstance()->DisableRecording(
+      base::FilePath(),
+      base::Bind(&TracingManager::OnTraceDataCollected,
+                 weak_ptr_factory_.GetWeakPtr()));
+  return current_trace_id_;
+}
+
+bool TracingManager::GetTraceData(int id, const TraceDataCallback& callback) {
+  // If a trace is being collected currently, send it via callback when
+  // complete.
+  if (current_trace_id_) {
+    // Only allow one trace data request at a time.
+    if (trace_callback_.is_null()) {
+      trace_callback_ = callback;
+      return true;
+    } else {
+      return false;
+    }
+  } else {
+    std::map<int, scoped_refptr<base::RefCountedString> >::iterator data =
+        trace_data_.find(id);
+    if (data == trace_data_.end())
+      return false;
+
+    // Always return the data asychronously, so the behavior is consistant.
+    base::MessageLoopProxy::current()->PostTask(
+        FROM_HERE,
+        base::Bind(callback, data->second));
+    return true;
+  }
+}
+
+void TracingManager::DiscardTraceData(int id) {
+  trace_data_.erase(id);
+
+  // If the trace is discarded before it is complete, clean up the accumulators.
+  if (id == current_trace_id_) {
+    current_trace_id_ = 0;
+
+    // If the trace has already been requested, provide an empty string.
+    if (!trace_callback_.is_null()) {
+      trace_callback_.Run(scoped_refptr<base::RefCountedString>());
+      trace_callback_.Reset();
+    }
+  }
+}
+
+void TracingManager::StartTracing() {
+  content::TracingController::GetInstance()->EnableRecording(
+      "", content::TracingController::DEFAULT_OPTIONS,
+      content::TracingController::EnableRecordingDoneCallback());
+}
+
+void TracingManager::OnTraceDataCollected(const base::FilePath& path) {
+  if (!current_trace_id_)
+    return;
+
+  std::string data;
+  if (!base::ReadFileToString(path, &data)) {
+    LOG(ERROR) << "Failed to read trace data from: " << path.value();
+    return;
+  }
+  base::DeleteFile(path, false);
+
+  std::string output_val;
+  feedback_util::ZipString(
+      base::FilePath(kTracingFilename), data, &output_val);
+
+  scoped_refptr<base::RefCountedString> output(
+      base::RefCountedString::TakeString(&output_val));
+
+  trace_data_[current_trace_id_] = output;
+
+  if (!trace_callback_.is_null()) {
+    trace_callback_.Run(output);
+    trace_callback_.Reset();
+  }
+
+  current_trace_id_ = 0;
+
+  // Tracing has to be restarted asynchronous, so the TracingController can
+  // clean up.
+  base::MessageLoopProxy::current()->PostTask(
+      FROM_HERE,
+      base::Bind(&TracingManager::StartTracing,
+                 weak_ptr_factory_.GetWeakPtr()));
+}
+
+// static
+scoped_ptr<TracingManager> TracingManager::Create() {
+  if (g_tracing_manager)
+    return scoped_ptr<TracingManager>();
+  return scoped_ptr<TracingManager>(new TracingManager());
+}
+
+TracingManager* TracingManager::Get() {
+  return g_tracing_manager;
+}
diff --git a/components/feedback/tracing_manager.h b/components/feedback/tracing_manager.h
new file mode 100644
index 0000000..1148a1c
--- /dev/null
+++ b/components/feedback/tracing_manager.h
@@ -0,0 +1,78 @@
+// 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.
+
+#ifndef COMPONENTS_FEEDBACK_TRACING_MANAGER_H_
+#define COMPONENTS_FEEDBACK_TRACING_MANAGER_H_
+
+#include <map>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+
+namespace base {
+
+class RefCountedString;
+class FilePath;
+
+}
+// Callback used for getting the output of a trace.
+typedef base::Callback<void(scoped_refptr<base::RefCountedString> trace_data)>
+    TraceDataCallback;
+
+// This class is used to manage performance metrics that can be attached to
+// feedback reports.  This class is a Singleton that is owned by the preference
+// system.  It should only be created when it is enabled, and should only be
+// accessed elsewhere via Get().
+//
+// When a performance trace is desired, TracingManager::Get()->RequestTrace()
+// should be invoked.  The TracingManager will then start preparing a zipped
+// version of the performance data.  That data can then be requested via
+// GetTraceData().  When the data is no longer needed, it should be discarded
+// via DiscardTraceData().
+class TracingManager {
+ public:
+  virtual ~TracingManager();
+
+  // Create a TracingManager.  Can only be called when none exists.
+  static scoped_ptr<TracingManager> Create();
+
+  // Get the current TracingManager.  Returns NULL if one doesn't exist.
+  static TracingManager* Get();
+
+  // Request a trace ending at the current time.  If a trace is already being
+  // collected, the id for that trace is returned.
+  int RequestTrace();
+
+  // Get the trace data for |id|.  On success, true is returned, and the data is
+  // returned via |callback|.  Returns false on failure.
+  bool GetTraceData(int id, const TraceDataCallback& callback);
+
+  // Discard the data for trace |id|.
+  void DiscardTraceData(int id);
+
+ private:
+  TracingManager();
+
+  void StartTracing();
+  void OnTraceDataCollected(const base::FilePath& path);
+
+  // ID of the trace that is being collected.
+  int current_trace_id_;
+
+  // Mapping of trace ID to trace data.
+  std::map<int, scoped_refptr<base::RefCountedString> > trace_data_;
+
+  // Callback for the current trace request.
+  TraceDataCallback trace_callback_;
+
+  base::WeakPtrFactory<TracingManager> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(TracingManager);
+};
+
+#endif  // COMPONENTS_FEEDBACK_TRACING_MANAGER_H_
+
diff --git a/components/infobars/DEPS b/components/infobars/DEPS
index 4f66f6c..b1b7165 100644
--- a/components/infobars/DEPS
+++ b/components/infobars/DEPS
@@ -1,8 +1,7 @@
 include_rules = [
   # Infobars is a layered component; subdirectories must explicitly introduce
   # the ability to use the content layer as appropriate.
-  "-content",
-
+  
   "+ui",
   "+third_party/skia"
 ]
diff --git a/components/keyed_service/DEPS b/components/keyed_service/DEPS
index 6ca79ac..f2396aa 100644
--- a/components/keyed_service/DEPS
+++ b/components/keyed_service/DEPS
@@ -2,5 +2,4 @@
   # KeyedService is a layered component; subdirectories must introduce
   # allowances of //content dependencies as appropriate.
   "-components/keyed_service/content",
-  "-content",
 ]
diff --git a/components/metrics.gypi b/components/metrics.gypi
index 6036cae..e0fe848 100644
--- a/components/metrics.gypi
+++ b/components/metrics.gypi
@@ -12,11 +12,35 @@
       ],
       'dependencies': [
         '../base/base.gyp:base',
+        'component_metrics_proto',
       ],
       'sources': [
         'metrics/metrics_hashes.cc',
         'metrics/metrics_hashes.h',
+        'metrics/metrics_log_base.cc',
+        'metrics/metrics_log_base.h',
+        'metrics/metrics_log_manager.cc',
+        'metrics/metrics_log_manager.h',
       ],
     },
+    {
+      # Protobuf compiler / generator for UMA (User Metrics Analysis).
+      'target_name': 'component_metrics_proto',
+      'type': 'static_library',
+      'sources': [
+        'metrics/proto/chrome_user_metrics_extension.proto',
+        'metrics/proto/histogram_event.proto',
+        'metrics/proto/omnibox_event.proto',
+        'metrics/proto/perf_data.proto',
+        'metrics/proto/profiler_event.proto',
+        'metrics/proto/system_profile.proto',
+        'metrics/proto/user_action_event.proto',
+      ],
+      'variables': {
+        'proto_in_dir': 'metrics/proto',
+        'proto_out_dir': 'components/metrics/proto',
+      },
+      'includes': [ '../build/protoc.gypi' ],
+    },
   ],
 }
diff --git a/components/metrics/DEPS b/components/metrics/DEPS
new file mode 100644
index 0000000..1fb5bf8
--- /dev/null
+++ b/components/metrics/DEPS
@@ -0,0 +1,3 @@
+include_rules = [ 
+  "-net",
+]
diff --git a/components/metrics/README b/components/metrics/README
new file mode 100644
index 0000000..3461dea
--- /dev/null
+++ b/components/metrics/README
@@ -0,0 +1,22 @@
+This component contains the base classes for the metrics service and only
+depends on //base. It is used by ChromeOS as the base for a standalone service
+that will upload the metrics when ChromeOS is not installed (headless install).
+
+This is the first step towards the componentization of metrics that will happen
+later this spring.
+
+A proposed structure for the metrics component is:
+//components/metrics/base,
+  Depends on base only. Contains the protobuf definitions.
+//components/metrics/core
+  Depends on everything iOS depends on
+//components/metrics/content
+  Depends on content
+
+Ideally, the component would abstract the network stack and have a clean
+separation between the metrics upload logic (protbuf generation, retry, etc...),
+the chrome part (gathering histogram from all the threads, populating the
+log with hardware characteristics, plugin state, etc.).
+
+It is a plus if the component stays in a single directory as it would be easier
+for ChromeOS to pull it :).
diff --git a/components/metrics/metrics_log_base.cc b/components/metrics/metrics_log_base.cc
new file mode 100644
index 0000000..99e4edb
--- /dev/null
+++ b/components/metrics/metrics_log_base.cc
@@ -0,0 +1,142 @@
+// 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.
+
+#include "components/metrics/metrics_log_base.h"
+
+#include "base/metrics/histogram_base.h"
+#include "base/metrics/histogram_samples.h"
+#include "components/metrics/metrics_hashes.h"
+#include "components/metrics/proto/histogram_event.pb.h"
+#include "components/metrics/proto/system_profile.pb.h"
+#include "components/metrics/proto/user_action_event.pb.h"
+
+using base::Histogram;
+using base::HistogramBase;
+using base::HistogramSamples;
+using base::SampleCountIterator;
+using base::Time;
+using base::TimeDelta;
+using metrics::HistogramEventProto;
+using metrics::SystemProfileProto;
+using metrics::UserActionEventProto;
+
+namespace metrics {
+namespace {
+
+// Any id less than 16 bytes is considered to be a testing id.
+bool IsTestingID(const std::string& id) {
+  return id.size() < 16;
+}
+
+}  // namespace
+
+MetricsLogBase::MetricsLogBase(const std::string& client_id,
+                               int session_id,
+                               LogType log_type,
+                               const std::string& version_string)
+    : num_events_(0),
+      locked_(false),
+      log_type_(log_type) {
+  DCHECK_NE(NO_LOG, log_type);
+  if (IsTestingID(client_id))
+    uma_proto_.set_client_id(0);
+  else
+    uma_proto_.set_client_id(Hash(client_id));
+
+  uma_proto_.set_session_id(session_id);
+  uma_proto_.mutable_system_profile()->set_build_timestamp(GetBuildTime());
+  uma_proto_.mutable_system_profile()->set_app_version(version_string);
+}
+
+MetricsLogBase::~MetricsLogBase() {}
+
+// static
+uint64 MetricsLogBase::Hash(const std::string& value) {
+  uint64 hash = metrics::HashMetricName(value);
+
+  // The following log is VERY helpful when folks add some named histogram into
+  // the code, but forgot to update the descriptive list of histograms.  When
+  // that happens, all we get to see (server side) is a hash of the histogram
+  // name.  We can then use this logging to find out what histogram name was
+  // being hashed to a given MD5 value by just running the version of Chromium
+  // in question with --enable-logging.
+  DVLOG(1) << "Metrics: Hash numeric [" << value << "]=[" << hash << "]";
+
+  return hash;
+}
+
+// static
+int64 MetricsLogBase::GetBuildTime() {
+  static int64 integral_build_time = 0;
+  if (!integral_build_time) {
+    Time time;
+    const char* kDateTime = __DATE__ " " __TIME__ " GMT";
+    bool result = Time::FromString(kDateTime, &time);
+    DCHECK(result);
+    integral_build_time = static_cast<int64>(time.ToTimeT());
+  }
+  return integral_build_time;
+}
+
+// static
+int64 MetricsLogBase::GetCurrentTime() {
+  return (base::TimeTicks::Now() - base::TimeTicks()).InSeconds();
+}
+
+void MetricsLogBase::CloseLog() {
+  DCHECK(!locked_);
+  locked_ = true;
+}
+
+void MetricsLogBase::GetEncodedLog(std::string* encoded_log) {
+  DCHECK(locked_);
+  uma_proto_.SerializeToString(encoded_log);
+}
+
+void MetricsLogBase::RecordUserAction(const std::string& key) {
+  DCHECK(!locked_);
+
+  UserActionEventProto* user_action = uma_proto_.add_user_action_event();
+  user_action->set_name_hash(Hash(key));
+  user_action->set_time(GetCurrentTime());
+
+  ++num_events_;
+}
+
+void MetricsLogBase::RecordHistogramDelta(const std::string& histogram_name,
+                                          const HistogramSamples& snapshot) {
+  DCHECK(!locked_);
+  DCHECK_NE(0, snapshot.TotalCount());
+
+  // We will ignore the MAX_INT/infinite value in the last element of range[].
+
+  HistogramEventProto* histogram_proto = uma_proto_.add_histogram_event();
+  histogram_proto->set_name_hash(Hash(histogram_name));
+  histogram_proto->set_sum(snapshot.sum());
+
+  for (scoped_ptr<SampleCountIterator> it = snapshot.Iterator(); !it->Done();
+       it->Next()) {
+    HistogramBase::Sample min;
+    HistogramBase::Sample max;
+    HistogramBase::Count count;
+    it->Get(&min, &max, &count);
+    HistogramEventProto::Bucket* bucket = histogram_proto->add_bucket();
+    bucket->set_min(min);
+    bucket->set_max(max);
+    bucket->set_count(count);
+  }
+
+  // Omit fields to save space (see rules in histogram_event.proto comments).
+  for (int i = 0; i < histogram_proto->bucket_size(); ++i) {
+    HistogramEventProto::Bucket* bucket = histogram_proto->mutable_bucket(i);
+    if (i + 1 < histogram_proto->bucket_size() &&
+        bucket->max() == histogram_proto->bucket(i + 1).min()) {
+      bucket->clear_max();
+    } else if (bucket->max() == bucket->min() + 1) {
+      bucket->clear_min();
+    }
+  }
+}
+
+}  // namespace metrics
diff --git a/components/metrics/metrics_log_base.h b/components/metrics/metrics_log_base.h
new file mode 100644
index 0000000..25a6bd0
--- /dev/null
+++ b/components/metrics/metrics_log_base.h
@@ -0,0 +1,110 @@
+// 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.
+
+// This file defines a set of user experience metrics data recorded by
+// the MetricsService.  This is the unit of data that is sent to the server.
+
+#ifndef COMPONENTS_METRICS_METRICS_LOG_BASE_H_
+#define COMPONENTS_METRICS_METRICS_LOG_BASE_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/metrics/histogram.h"
+#include "base/time/time.h"
+#include "components/metrics/proto/chrome_user_metrics_extension.pb.h"
+
+namespace base {
+class HistogramSamples;
+}  // namespace base
+
+namespace metrics {
+
+// This class provides base functionality for logging metrics data.
+class MetricsLogBase {
+ public:
+  // TODO(asvitkine): Remove the NO_LOG value.
+  enum LogType {
+    INITIAL_STABILITY_LOG,  // The initial log containing stability stats.
+    ONGOING_LOG,            // Subsequent logs in a session.
+    NO_LOG,                 // Placeholder value for when there is no log.
+  };
+
+  // Creates a new metrics log of the specified type.
+  // client_id is the identifier for this profile on this installation
+  // session_id is an integer that's incremented on each application launch
+  MetricsLogBase(const std::string& client_id,
+                 int session_id,
+                 LogType log_type,
+                 const std::string& version_string);
+  virtual ~MetricsLogBase();
+
+  // Computes the MD5 hash of the given string, and returns the first 8 bytes of
+  // the hash.
+  static uint64 Hash(const std::string& value);
+
+  // Get the GMT buildtime for the current binary, expressed in seconds since
+  // January 1, 1970 GMT.
+  // The value is used to identify when a new build is run, so that previous
+  // reliability stats, from other builds, can be abandoned.
+  static int64 GetBuildTime();
+
+  // Convenience function to return the current time at a resolution in seconds.
+  // This wraps base::TimeTicks, and hence provides an abstract time that is
+  // always incrementing for use in measuring time durations.
+  static int64 GetCurrentTime();
+
+  // Records a user-initiated action.
+  void RecordUserAction(const std::string& key);
+
+  // Record any changes in a given histogram for transmission.
+  void RecordHistogramDelta(const std::string& histogram_name,
+                            const base::HistogramSamples& snapshot);
+
+  // Stop writing to this record and generate the encoded representation.
+  // None of the Record* methods can be called after this is called.
+  void CloseLog();
+
+  // Fills |encoded_log| with the serialized protobuf representation of the
+  // record.  Must only be called after CloseLog() has been called.
+  void GetEncodedLog(std::string* encoded_log);
+
+  int num_events() { return num_events_; }
+
+  void set_hardware_class(const std::string& hardware_class) {
+    uma_proto_.mutable_system_profile()->mutable_hardware()->set_hardware_class(
+        hardware_class);
+  }
+
+  LogType log_type() const { return log_type_; }
+
+ protected:
+  bool locked() const { return locked_; }
+
+  metrics::ChromeUserMetricsExtension* uma_proto() { return &uma_proto_; }
+  const metrics::ChromeUserMetricsExtension* uma_proto() const {
+    return &uma_proto_;
+  }
+
+  // TODO(isherman): Remove this once the XML pipeline is outta here.
+  int num_events_;  // the number of events recorded in this log
+
+ private:
+  // locked_ is true when record has been packed up for sending, and should
+  // no longer be written to.  It is only used for sanity checking and is
+  // not a real lock.
+  bool locked_;
+
+  // The type of the log, i.e. initial or ongoing.
+  const LogType log_type_;
+
+  // Stores the protocol buffer representation for this log.
+  metrics::ChromeUserMetricsExtension uma_proto_;
+
+  DISALLOW_COPY_AND_ASSIGN(MetricsLogBase);
+};
+
+}  // namespace metrics
+
+#endif  // COMPONENTS_METRICS_METRICS_LOG_BASE_H_
diff --git a/components/metrics/metrics_log_base_unittest.cc b/components/metrics/metrics_log_base_unittest.cc
new file mode 100644
index 0000000..cc7a173
--- /dev/null
+++ b/components/metrics/metrics_log_base_unittest.cc
@@ -0,0 +1,125 @@
+// 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.
+
+#include "components/metrics/metrics_log_base.h"
+
+#include <string>
+
+#include "base/base64.h"
+#include "base/metrics/bucket_ranges.h"
+#include "base/metrics/sample_vector.h"
+#include "components/metrics/proto/chrome_user_metrics_extension.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace metrics {
+
+namespace {
+
+class TestMetricsLogBase : public MetricsLogBase {
+ public:
+  TestMetricsLogBase()
+      : MetricsLogBase("client_id", 1, MetricsLogBase::ONGOING_LOG, "1.2.3.4") {
+  }
+  virtual ~TestMetricsLogBase() {}
+
+  using MetricsLogBase::uma_proto;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestMetricsLogBase);
+};
+
+}  // namespace
+
+TEST(MetricsLogBaseTest, LogType) {
+  MetricsLogBase log1("id", 0, MetricsLogBase::ONGOING_LOG, "1.2.3");
+  EXPECT_EQ(MetricsLogBase::ONGOING_LOG, log1.log_type());
+
+  MetricsLogBase log2("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "1.2.3");
+  EXPECT_EQ(MetricsLogBase::INITIAL_STABILITY_LOG, log2.log_type());
+}
+
+TEST(MetricsLogBaseTest, EmptyRecord) {
+  MetricsLogBase log("totally bogus client ID", 137,
+                     MetricsLogBase::ONGOING_LOG, "bogus version");
+  log.set_hardware_class("sample-class");
+  log.CloseLog();
+
+  std::string encoded;
+  log.GetEncodedLog(&encoded);
+
+  // A couple of fields are hard to mock, so these will be copied over directly
+  // for the expected output.
+  metrics::ChromeUserMetricsExtension parsed;
+  ASSERT_TRUE(parsed.ParseFromString(encoded));
+
+  metrics::ChromeUserMetricsExtension expected;
+  expected.set_client_id(5217101509553811875);  // Hashed bogus client ID
+  expected.set_session_id(137);
+  expected.mutable_system_profile()->set_build_timestamp(
+      parsed.system_profile().build_timestamp());
+  expected.mutable_system_profile()->set_app_version("bogus version");
+  expected.mutable_system_profile()->mutable_hardware()->set_hardware_class(
+      "sample-class");
+
+  EXPECT_EQ(expected.SerializeAsString(), encoded);
+}
+
+TEST(MetricsLogBaseTest, HistogramBucketFields) {
+  // Create buckets: 1-5, 5-7, 7-8, 8-9, 9-10, 10-11, 11-12.
+  base::BucketRanges ranges(8);
+  ranges.set_range(0, 1);
+  ranges.set_range(1, 5);
+  ranges.set_range(2, 7);
+  ranges.set_range(3, 8);
+  ranges.set_range(4, 9);
+  ranges.set_range(5, 10);
+  ranges.set_range(6, 11);
+  ranges.set_range(7, 12);
+
+  base::SampleVector samples(&ranges);
+  samples.Accumulate(3, 1);   // Bucket 1-5.
+  samples.Accumulate(6, 1);   // Bucket 5-7.
+  samples.Accumulate(8, 1);   // Bucket 8-9. (7-8 skipped)
+  samples.Accumulate(10, 1);  // Bucket 10-11. (9-10 skipped)
+  samples.Accumulate(11, 1);  // Bucket 11-12.
+
+  TestMetricsLogBase log;
+  log.RecordHistogramDelta("Test", samples);
+
+  const metrics::ChromeUserMetricsExtension* uma_proto = log.uma_proto();
+  const metrics::HistogramEventProto& histogram_proto =
+      uma_proto->histogram_event(uma_proto->histogram_event_size() - 1);
+
+  // Buckets with samples: 1-5, 5-7, 8-9, 10-11, 11-12.
+  // Should become: 1-/, 5-7, /-9, 10-/, /-12.
+  ASSERT_EQ(5, histogram_proto.bucket_size());
+
+  // 1-5 becomes 1-/ (max is same as next min).
+  EXPECT_TRUE(histogram_proto.bucket(0).has_min());
+  EXPECT_FALSE(histogram_proto.bucket(0).has_max());
+  EXPECT_EQ(1, histogram_proto.bucket(0).min());
+
+  // 5-7 stays 5-7 (no optimization possible).
+  EXPECT_TRUE(histogram_proto.bucket(1).has_min());
+  EXPECT_TRUE(histogram_proto.bucket(1).has_max());
+  EXPECT_EQ(5, histogram_proto.bucket(1).min());
+  EXPECT_EQ(7, histogram_proto.bucket(1).max());
+
+  // 8-9 becomes /-9 (min is same as max - 1).
+  EXPECT_FALSE(histogram_proto.bucket(2).has_min());
+  EXPECT_TRUE(histogram_proto.bucket(2).has_max());
+  EXPECT_EQ(9, histogram_proto.bucket(2).max());
+
+  // 10-11 becomes 10-/ (both optimizations apply, omit max is prioritized).
+  EXPECT_TRUE(histogram_proto.bucket(3).has_min());
+  EXPECT_FALSE(histogram_proto.bucket(3).has_max());
+  EXPECT_EQ(10, histogram_proto.bucket(3).min());
+
+  // 11-12 becomes /-12 (last record must keep max, min is same as max - 1).
+  EXPECT_FALSE(histogram_proto.bucket(4).has_min());
+  EXPECT_TRUE(histogram_proto.bucket(4).has_max());
+  EXPECT_EQ(12, histogram_proto.bucket(4).max());
+}
+
+}  // namespace metrics
diff --git a/components/metrics/metrics_log_manager.cc b/components/metrics/metrics_log_manager.cc
new file mode 100644
index 0000000..e537eef
--- /dev/null
+++ b/components/metrics/metrics_log_manager.cc
@@ -0,0 +1,208 @@
+// 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.
+
+#include "components/metrics/metrics_log_manager.h"
+
+#include <algorithm>
+
+#include "base/metrics/histogram.h"
+#include "base/sha1.h"
+#include "base/strings/string_util.h"
+#include "base/timer/elapsed_timer.h"
+#include "components/metrics/metrics_log_base.h"
+
+namespace metrics {
+
+MetricsLogManager::SerializedLog::SerializedLog() {}
+MetricsLogManager::SerializedLog::~SerializedLog() {}
+
+bool MetricsLogManager::SerializedLog::IsEmpty() const {
+  return log_text_.empty();
+}
+
+void MetricsLogManager::SerializedLog::SwapLogText(std::string* log_text) {
+  log_text_.swap(*log_text);
+  if (log_text_.empty())
+    log_hash_.clear();
+  else
+    log_hash_ = base::SHA1HashString(log_text_);
+}
+
+void MetricsLogManager::SerializedLog::Clear() {
+  log_text_.clear();
+  log_hash_.clear();
+}
+
+void MetricsLogManager::SerializedLog::Swap(
+    MetricsLogManager::SerializedLog* other) {
+  log_text_.swap(other->log_text_);
+  log_hash_.swap(other->log_hash_);
+}
+
+MetricsLogManager::MetricsLogManager()
+    : unsent_logs_loaded_(false),
+      staged_log_type_(MetricsLogBase::NO_LOG),
+      max_ongoing_log_store_size_(0),
+      last_provisional_store_index_(-1),
+      last_provisional_store_type_(MetricsLogBase::INITIAL_STABILITY_LOG) {}
+
+MetricsLogManager::~MetricsLogManager() {}
+
+void MetricsLogManager::BeginLoggingWithLog(MetricsLogBase* log) {
+  DCHECK(!current_log_.get());
+  current_log_.reset(log);
+}
+
+void MetricsLogManager::FinishCurrentLog() {
+  DCHECK(current_log_.get());
+  current_log_->CloseLog();
+  SerializedLog compressed_log;
+  CompressCurrentLog(&compressed_log);
+  if (!compressed_log.IsEmpty())
+    StoreLog(&compressed_log, current_log_->log_type(), NORMAL_STORE);
+  current_log_.reset();
+}
+
+void MetricsLogManager::StageNextLogForUpload() {
+  // Prioritize initial logs for uploading.
+  std::vector<SerializedLog>* source_list =
+      unsent_initial_logs_.empty() ? &unsent_ongoing_logs_
+                                   : &unsent_initial_logs_;
+  LogType source_type = (source_list == &unsent_ongoing_logs_) ?
+      MetricsLogBase::ONGOING_LOG : MetricsLogBase::INITIAL_STABILITY_LOG;
+  // CHECK, rather than DCHECK, because swap()ing with an empty list causes
+  // hard-to-identify crashes much later.
+  CHECK(!source_list->empty());
+  DCHECK(staged_log_.IsEmpty());
+  DCHECK_EQ(MetricsLogBase::NO_LOG, staged_log_type_);
+  staged_log_.Swap(&source_list->back());
+  staged_log_type_ = source_type;
+  source_list->pop_back();
+
+  // If the staged log was the last provisional store, clear that.
+  if (last_provisional_store_index_ != -1) {
+    if (source_type == last_provisional_store_type_ &&
+        static_cast<unsigned int>(last_provisional_store_index_) ==
+            source_list->size()) {
+      last_provisional_store_index_ = -1;
+    }
+  }
+}
+
+bool MetricsLogManager::has_staged_log() const {
+  return !staged_log_.IsEmpty();
+}
+
+void MetricsLogManager::DiscardStagedLog() {
+  staged_log_.Clear();
+  staged_log_type_ = MetricsLogBase::NO_LOG;
+}
+
+void MetricsLogManager::DiscardCurrentLog() {
+  current_log_->CloseLog();
+  current_log_.reset();
+}
+
+void MetricsLogManager::PauseCurrentLog() {
+  DCHECK(!paused_log_.get());
+  paused_log_.reset(current_log_.release());
+}
+
+void MetricsLogManager::ResumePausedLog() {
+  DCHECK(!current_log_.get());
+  current_log_.reset(paused_log_.release());
+}
+
+void MetricsLogManager::StoreStagedLogAsUnsent(StoreType store_type) {
+  DCHECK(has_staged_log());
+
+  // If compressing the log failed, there's nothing to store.
+  if (staged_log_.IsEmpty())
+    return;
+
+  StoreLog(&staged_log_, staged_log_type_, store_type);
+  DiscardStagedLog();
+}
+
+void MetricsLogManager::StoreLog(SerializedLog* log,
+                                 LogType log_type,
+                                 StoreType store_type) {
+  DCHECK_NE(MetricsLogBase::NO_LOG, log_type);
+  std::vector<SerializedLog>* destination_list =
+      (log_type == MetricsLogBase::INITIAL_STABILITY_LOG) ?
+      &unsent_initial_logs_ : &unsent_ongoing_logs_;
+  destination_list->push_back(SerializedLog());
+  destination_list->back().Swap(log);
+
+  if (store_type == PROVISIONAL_STORE) {
+    last_provisional_store_index_ = destination_list->size() - 1;
+    last_provisional_store_type_ = log_type;
+  }
+}
+
+void MetricsLogManager::DiscardLastProvisionalStore() {
+  if (last_provisional_store_index_ == -1)
+    return;
+  std::vector<SerializedLog>* source_list =
+      (last_provisional_store_type_ == MetricsLogBase::ONGOING_LOG)
+          ? &unsent_ongoing_logs_
+          : &unsent_initial_logs_;
+  DCHECK_LT(static_cast<unsigned int>(last_provisional_store_index_),
+            source_list->size());
+  source_list->erase(source_list->begin() + last_provisional_store_index_);
+  last_provisional_store_index_ = -1;
+}
+
+void MetricsLogManager::PersistUnsentLogs() {
+  DCHECK(log_serializer_.get());
+  if (!log_serializer_.get())
+    return;
+  DCHECK(unsent_logs_loaded_);
+  if (!unsent_logs_loaded_)
+    return;
+
+  base::ElapsedTimer timer;
+  // Remove any ongoing logs that are over the serialization size limit.
+  if (max_ongoing_log_store_size_) {
+    for (std::vector<SerializedLog>::iterator it = unsent_ongoing_logs_.begin();
+         it != unsent_ongoing_logs_.end();) {
+      size_t log_size = it->log_text().length();
+      if (log_size > max_ongoing_log_store_size_) {
+        UMA_HISTOGRAM_COUNTS("UMA.Large Accumulated Log Not Persisted",
+                             static_cast<int>(log_size));
+        it = unsent_ongoing_logs_.erase(it);
+      } else {
+        ++it;
+      }
+    }
+  }
+  log_serializer_->SerializeLogs(unsent_initial_logs_,
+                                 MetricsLogBase::INITIAL_STABILITY_LOG);
+  log_serializer_->SerializeLogs(unsent_ongoing_logs_,
+                                 MetricsLogBase::ONGOING_LOG);
+  UMA_HISTOGRAM_TIMES("UMA.StoreLogsTime", timer.Elapsed());
+}
+
+void MetricsLogManager::LoadPersistedUnsentLogs() {
+  DCHECK(log_serializer_.get());
+  if (!log_serializer_.get())
+    return;
+
+  base::ElapsedTimer timer;
+  log_serializer_->DeserializeLogs(MetricsLogBase::INITIAL_STABILITY_LOG,
+                                   &unsent_initial_logs_);
+  log_serializer_->DeserializeLogs(MetricsLogBase::ONGOING_LOG,
+                                   &unsent_ongoing_logs_);
+  UMA_HISTOGRAM_TIMES("UMA.LoadLogsTime", timer.Elapsed());
+
+  unsent_logs_loaded_ = true;
+}
+
+void MetricsLogManager::CompressCurrentLog(SerializedLog* compressed_log) {
+  std::string log_text;
+  current_log_->GetEncodedLog(&log_text);
+  compressed_log->SwapLogText(&log_text);
+}
+
+}  // namespace metrics
diff --git a/components/metrics/metrics_log_manager.h b/components/metrics/metrics_log_manager.h
new file mode 100644
index 0000000..006d4ed
--- /dev/null
+++ b/components/metrics/metrics_log_manager.h
@@ -0,0 +1,213 @@
+// 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.
+
+#ifndef COMPONENTS_METRICS_METRICS_LOG_MANAGER_H_
+#define COMPONENTS_METRICS_METRICS_LOG_MANAGER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/metrics/metrics_log_base.h"
+
+namespace metrics {
+
+// Manages all the log objects used by a MetricsService implementation. Keeps
+// track of both an in progress log and a log that is staged for uploading as
+// text, as well as saving logs to, and loading logs from, persistent storage.
+class MetricsLogManager {
+ public:
+  typedef MetricsLogBase::LogType LogType;
+
+  MetricsLogManager();
+  ~MetricsLogManager();
+
+  class SerializedLog {
+   public:
+    SerializedLog();
+    ~SerializedLog();
+
+    const std::string& log_text() const { return log_text_; }
+    const std::string& log_hash() const { return log_hash_; }
+
+    // Returns true if the log is empty.
+    bool IsEmpty() const;
+
+    // Swaps log text with |log_text| and updates the hash. This is more
+    // performant than a regular setter as it avoids doing a large string copy.
+    void SwapLogText(std::string* log_text);
+
+    // Clears the log.
+    void Clear();
+
+    // Swaps log contents with |other|.
+    void Swap(SerializedLog* other);
+
+   private:
+    // Non-human readable log text (serialized proto).
+    std::string log_text_;
+
+    // Non-human readable SHA1 of |log_text| or empty if |log_text| is empty.
+    std::string log_hash_;
+
+    // Intentionally omits DISALLOW_COPY_AND_ASSIGN() so that it can be used
+    // in std::vector<SerializedLog>.
+  };
+
+  enum StoreType {
+    NORMAL_STORE,       // A standard store operation.
+    PROVISIONAL_STORE,  // A store operation that can be easily reverted later.
+  };
+
+  // Takes ownership of |log| and makes it the current_log. This should only be
+  // called if there is not a current log.
+  void BeginLoggingWithLog(MetricsLogBase* log);
+
+  // Returns the in-progress log.
+  MetricsLogBase* current_log() { return current_log_.get(); }
+
+  // Closes current_log(), compresses it, and stores the compressed log for
+  // later, leaving current_log() NULL.
+  void FinishCurrentLog();
+
+  // Returns true if there are any logs waiting to be uploaded.
+  bool has_unsent_logs() const {
+    return !unsent_initial_logs_.empty() || !unsent_ongoing_logs_.empty();
+  }
+
+  // Populates staged_log_text() with the next stored log to send.
+  // Should only be called if has_unsent_logs() is true.
+  void StageNextLogForUpload();
+
+  // Returns true if there is a log that needs to be, or is being, uploaded.
+  bool has_staged_log() const;
+
+  // The text of the staged log, as a serialized protobuf. Empty if there is no
+  // staged log, or if compression of the staged log failed.
+  const std::string& staged_log_text() const { return staged_log_.log_text(); }
+
+  // The SHA1 hash (non-human readable) of the staged log or empty if there is
+  // no staged log.
+  const std::string& staged_log_hash() const { return staged_log_.log_hash(); }
+
+  // Discards the staged log.
+  void DiscardStagedLog();
+
+  // Closes and discards |current_log|.
+  void DiscardCurrentLog();
+
+  // Sets current_log to NULL, but saves the current log for future use with
+  // ResumePausedLog(). Only one log may be paused at a time.
+  // TODO(stuartmorgan): Pause/resume support is really a workaround for a
+  // design issue in initial log writing; that should be fixed, and pause/resume
+  // removed.
+  void PauseCurrentLog();
+
+  // Restores the previously paused log (if any) to current_log().
+  // This should only be called if there is not a current log.
+  void ResumePausedLog();
+
+  // Saves the staged log, then clears staged_log().
+  // If |store_type| is PROVISIONAL_STORE, it can be dropped from storage with
+  // a later call to DiscardLastProvisionalStore (if it hasn't already been
+  // staged again).
+  // This is intended to be used when logs are being saved while an upload is in
+  // progress, in case the upload later succeeds.
+  // This can only be called if has_staged_log() is true.
+  void StoreStagedLogAsUnsent(StoreType store_type);
+
+  // Discards the last log stored with StoreStagedLogAsUnsent with |store_type|
+  // set to PROVISIONAL_STORE, as long as it hasn't already been re-staged. If
+  // the log is no longer present, this is a no-op.
+  void DiscardLastProvisionalStore();
+
+  // Sets the threshold for how large an onging log can be and still be written
+  // to persistant storage. Ongoing logs larger than this will be discarded
+  // before persisting. 0 is interpreted as no limit.
+  void set_max_ongoing_log_store_size(size_t max_size) {
+    max_ongoing_log_store_size_ = max_size;
+  }
+
+  // Interface for a utility class to serialize and deserialize logs for
+  // persistent storage.
+  class LogSerializer {
+   public:
+    virtual ~LogSerializer() {}
+
+    // Serializes |logs| to persistent storage, replacing any previously
+    // serialized logs of the same type.
+    virtual void SerializeLogs(const std::vector<SerializedLog>& logs,
+                               LogType log_type) = 0;
+
+    // Populates |logs| with logs of type |log_type| deserialized from
+    // persistent storage.
+    virtual void DeserializeLogs(LogType log_type,
+                                 std::vector<SerializedLog>* logs) = 0;
+  };
+
+  // Sets the serializer to use for persisting and loading logs; takes ownership
+  // of |serializer|.
+  void set_log_serializer(LogSerializer* serializer) {
+    log_serializer_.reset(serializer);
+  }
+
+  // Saves any unsent logs to persistent storage using the current log
+  // serializer. Can only be called after set_log_serializer.
+  void PersistUnsentLogs();
+
+  // Loads any unsent logs from persistent storage using the current log
+  // serializer. Can only be called after set_log_serializer.
+  void LoadPersistedUnsentLogs();
+
+ private:
+  // Saves |log| as the given type (or discards it in accordance with
+  // |max_ongoing_log_store_size_|).
+  // NOTE: This clears the contents of |log| (to avoid an expensive copy),
+  // so the log should be discarded after this call.
+  void StoreLog(SerializedLog* log, LogType log_type, StoreType store_type);
+
+  // Compresses |current_log_| into |compressed_log|.
+  void CompressCurrentLog(SerializedLog* compressed_log);
+
+  // Tracks whether unsent logs (if any) have been loaded from the serializer.
+  bool unsent_logs_loaded_;
+
+  // The log that we are still appending to.
+  scoped_ptr<MetricsLogBase> current_log_;
+
+  // A paused, previously-current log.
+  scoped_ptr<MetricsLogBase> paused_log_;
+
+  // Helper class to handle serialization/deserialization of logs for persistent
+  // storage. May be NULL.
+  scoped_ptr<LogSerializer> log_serializer_;
+
+  // The current staged log, ready for upload to the server.
+  SerializedLog staged_log_;
+  LogType staged_log_type_;
+
+  // Logs from a previous session that have not yet been sent.
+  // Note that the vector has the oldest logs listed first (early in the
+  // vector), and we'll discard old logs if we have gathered too many logs.
+  std::vector<SerializedLog> unsent_initial_logs_;
+  std::vector<SerializedLog> unsent_ongoing_logs_;
+
+  size_t max_ongoing_log_store_size_;
+
+  // The index and type of the last provisional store. If nothing has been
+  // provisionally stored, or the last provisional store has already been
+  // re-staged, the index will be -1;
+  // This is necessary because during an upload there are two logs (staged
+  // and current) and a client might store them in either order, so it's
+  // not necessarily the case that the provisional store is the last store.
+  int last_provisional_store_index_;
+  LogType last_provisional_store_type_;
+
+  DISALLOW_COPY_AND_ASSIGN(MetricsLogManager);
+};
+
+}  // namespace metrics
+
+#endif  // COMPONENTS_METRICS_METRICS_LOG_MANAGER_H_
diff --git a/components/metrics/metrics_log_manager_unittest.cc b/components/metrics/metrics_log_manager_unittest.cc
new file mode 100644
index 0000000..ec0ca38
--- /dev/null
+++ b/components/metrics/metrics_log_manager_unittest.cc
@@ -0,0 +1,427 @@
+// 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.
+
+#include "components/metrics/metrics_log_manager.h"
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/sha1.h"
+#include "components/metrics/metrics_log_base.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace metrics {
+
+namespace {
+
+// Dummy serializer that just stores logs in memory.
+class DummyLogSerializer : public MetricsLogManager::LogSerializer {
+ public:
+  virtual void SerializeLogs(
+      const std::vector<MetricsLogManager::SerializedLog>& logs,
+      MetricsLogManager::LogType log_type) OVERRIDE {
+    persisted_logs_[log_type] = logs;
+  }
+
+  virtual void DeserializeLogs(
+      MetricsLogManager::LogType log_type,
+      std::vector<MetricsLogManager::SerializedLog>* logs) OVERRIDE {
+    ASSERT_NE(static_cast<void*>(NULL), logs);
+    *logs = persisted_logs_[log_type];
+  }
+
+  // Returns the number of logs of the given type.
+  size_t TypeCount(MetricsLogManager::LogType log_type) {
+    return persisted_logs_[log_type].size();
+  }
+
+  // In-memory "persitent storage".
+  std::vector<MetricsLogManager::SerializedLog> persisted_logs_[2];
+};
+
+}  // namespace
+
+TEST(MetricsLogManagerTest, StandardFlow) {
+  MetricsLogManager log_manager;
+
+  // Make sure a new manager has a clean slate.
+  EXPECT_EQ(NULL, log_manager.current_log());
+  EXPECT_FALSE(log_manager.has_staged_log());
+  EXPECT_FALSE(log_manager.has_unsent_logs());
+
+  // Check that the normal flow works.
+  MetricsLogBase* initial_log =
+      new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
+  log_manager.BeginLoggingWithLog(initial_log);
+  EXPECT_EQ(initial_log, log_manager.current_log());
+  EXPECT_FALSE(log_manager.has_staged_log());
+
+  log_manager.FinishCurrentLog();
+  EXPECT_EQ(NULL, log_manager.current_log());
+  EXPECT_TRUE(log_manager.has_unsent_logs());
+  EXPECT_FALSE(log_manager.has_staged_log());
+
+  MetricsLogBase* second_log =
+      new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
+  log_manager.BeginLoggingWithLog(second_log);
+  EXPECT_EQ(second_log, log_manager.current_log());
+
+  log_manager.StageNextLogForUpload();
+  EXPECT_TRUE(log_manager.has_staged_log());
+  EXPECT_FALSE(log_manager.staged_log_text().empty());
+
+  log_manager.DiscardStagedLog();
+  EXPECT_EQ(second_log, log_manager.current_log());
+  EXPECT_FALSE(log_manager.has_staged_log());
+  EXPECT_FALSE(log_manager.has_unsent_logs());
+  EXPECT_TRUE(log_manager.staged_log_text().empty());
+
+  EXPECT_FALSE(log_manager.has_unsent_logs());
+}
+
+TEST(MetricsLogManagerTest, AbandonedLog) {
+  MetricsLogManager log_manager;
+
+  MetricsLogBase* dummy_log =
+      new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
+  log_manager.BeginLoggingWithLog(dummy_log);
+  EXPECT_EQ(dummy_log, log_manager.current_log());
+
+  log_manager.DiscardCurrentLog();
+  EXPECT_EQ(NULL, log_manager.current_log());
+  EXPECT_FALSE(log_manager.has_staged_log());
+}
+
+TEST(MetricsLogManagerTest, InterjectedLog) {
+  MetricsLogManager log_manager;
+
+  MetricsLogBase* ongoing_log =
+      new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
+  MetricsLogBase* temp_log =
+      new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
+
+  log_manager.BeginLoggingWithLog(ongoing_log);
+  EXPECT_EQ(ongoing_log, log_manager.current_log());
+
+  log_manager.PauseCurrentLog();
+  EXPECT_EQ(NULL, log_manager.current_log());
+
+  log_manager.BeginLoggingWithLog(temp_log);
+  EXPECT_EQ(temp_log, log_manager.current_log());
+  log_manager.FinishCurrentLog();
+  EXPECT_EQ(NULL, log_manager.current_log());
+
+  log_manager.ResumePausedLog();
+  EXPECT_EQ(ongoing_log, log_manager.current_log());
+
+  EXPECT_FALSE(log_manager.has_staged_log());
+  log_manager.StageNextLogForUpload();
+  log_manager.DiscardStagedLog();
+  EXPECT_FALSE(log_manager.has_unsent_logs());
+}
+
+TEST(MetricsLogManagerTest, InterjectedLogPreservesType) {
+  MetricsLogManager log_manager;
+  DummyLogSerializer* serializer = new DummyLogSerializer;
+  log_manager.set_log_serializer(serializer);
+  log_manager.LoadPersistedUnsentLogs();
+
+  MetricsLogBase* ongoing_log =
+      new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
+  MetricsLogBase* temp_log =
+      new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
+
+  log_manager.BeginLoggingWithLog(ongoing_log);
+  log_manager.PauseCurrentLog();
+  log_manager.BeginLoggingWithLog(temp_log);
+  log_manager.FinishCurrentLog();
+  log_manager.ResumePausedLog();
+  log_manager.StageNextLogForUpload();
+  log_manager.DiscardStagedLog();
+
+  // Verify that the remaining log (which is the original ongoing log) still
+  // has the right type.
+  log_manager.FinishCurrentLog();
+  log_manager.PersistUnsentLogs();
+  EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
+  EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+}
+
+TEST(MetricsLogManagerTest, StoreAndLoad) {
+  std::vector<MetricsLogManager::SerializedLog> initial_logs;
+  std::vector<MetricsLogManager::SerializedLog> ongoing_logs;
+
+  // Set up some in-progress logging in a scoped log manager simulating the
+  // leadup to quitting, then persist as would be done on quit.
+  {
+    MetricsLogManager log_manager;
+    DummyLogSerializer* serializer = new DummyLogSerializer;
+    log_manager.set_log_serializer(serializer);
+    log_manager.LoadPersistedUnsentLogs();
+
+    // Simulate a log having already been unsent from a previous session.
+    MetricsLogManager::SerializedLog log;
+    std::string text = "proto";
+    log.SwapLogText(&text);
+    serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG].push_back(log);
+    EXPECT_FALSE(log_manager.has_unsent_logs());
+    log_manager.LoadPersistedUnsentLogs();
+    EXPECT_TRUE(log_manager.has_unsent_logs());
+
+    MetricsLogBase* log1 =
+        new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
+    MetricsLogBase* log2 =
+        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
+    log_manager.BeginLoggingWithLog(log1);
+    log_manager.FinishCurrentLog();
+    log_manager.BeginLoggingWithLog(log2);
+    log_manager.StageNextLogForUpload();
+    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
+    log_manager.FinishCurrentLog();
+
+    // Nothing should be written out until PersistUnsentLogs is called.
+    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
+    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+    log_manager.PersistUnsentLogs();
+    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
+    EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+
+    // Save the logs to transfer over to a new serializer (since log_manager
+    // owns |serializer|, so it's about to go away.
+    initial_logs =
+        serializer->persisted_logs_[MetricsLogBase::INITIAL_STABILITY_LOG];
+    ongoing_logs = serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG];
+  }
+
+  // Now simulate the relaunch, ensure that the log manager restores
+  // everything correctly, and verify that once the are handled they are not
+  // re-persisted.
+  {
+    MetricsLogManager log_manager;
+
+    DummyLogSerializer* serializer = new DummyLogSerializer;
+    serializer->persisted_logs_[MetricsLogBase::INITIAL_STABILITY_LOG] =
+        initial_logs;
+    serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG] = ongoing_logs;
+
+    log_manager.set_log_serializer(serializer);
+    log_manager.LoadPersistedUnsentLogs();
+    EXPECT_TRUE(log_manager.has_unsent_logs());
+
+    log_manager.StageNextLogForUpload();
+    log_manager.DiscardStagedLog();
+    // The initial log should be sent first; update the persisted storage to
+    // verify.
+    log_manager.PersistUnsentLogs();
+    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
+    EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+
+    // Handle the first ongoing log.
+    log_manager.StageNextLogForUpload();
+    log_manager.DiscardStagedLog();
+    EXPECT_TRUE(log_manager.has_unsent_logs());
+
+    // Handle the last log.
+    log_manager.StageNextLogForUpload();
+    log_manager.DiscardStagedLog();
+    EXPECT_FALSE(log_manager.has_unsent_logs());
+
+    // Nothing should have changed "on disk" since PersistUnsentLogs hasn't been
+    // called again.
+    EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+    // Persist, and make sure nothing is left.
+    log_manager.PersistUnsentLogs();
+    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
+    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+  }
+}
+
+TEST(MetricsLogManagerTest, StoreStagedLogTypes) {
+  // Ensure that types are preserved when storing staged logs.
+  {
+    MetricsLogManager log_manager;
+    DummyLogSerializer* serializer = new DummyLogSerializer;
+    log_manager.set_log_serializer(serializer);
+    log_manager.LoadPersistedUnsentLogs();
+
+    MetricsLogBase* log =
+        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
+    log_manager.BeginLoggingWithLog(log);
+    log_manager.FinishCurrentLog();
+    log_manager.StageNextLogForUpload();
+    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
+    log_manager.PersistUnsentLogs();
+
+    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
+    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+  }
+
+  {
+    MetricsLogManager log_manager;
+    DummyLogSerializer* serializer = new DummyLogSerializer;
+    log_manager.set_log_serializer(serializer);
+    log_manager.LoadPersistedUnsentLogs();
+
+    MetricsLogBase* log =
+        new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
+    log_manager.BeginLoggingWithLog(log);
+    log_manager.FinishCurrentLog();
+    log_manager.StageNextLogForUpload();
+    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
+    log_manager.PersistUnsentLogs();
+
+    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
+    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+  }
+}
+
+TEST(MetricsLogManagerTest, LargeLogDiscarding) {
+  MetricsLogManager log_manager;
+  DummyLogSerializer* serializer = new DummyLogSerializer;
+  log_manager.set_log_serializer(serializer);
+  log_manager.LoadPersistedUnsentLogs();
+
+  // Set the size threshold very low, to verify that it's honored.
+  log_manager.set_max_ongoing_log_store_size(1);
+
+  MetricsLogBase* log1 =
+      new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
+  MetricsLogBase* log2 =
+      new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
+  log_manager.BeginLoggingWithLog(log1);
+  log_manager.FinishCurrentLog();
+  log_manager.BeginLoggingWithLog(log2);
+  log_manager.FinishCurrentLog();
+
+  // Only the ongoing log should be written out, due to the threshold.
+  log_manager.PersistUnsentLogs();
+  EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
+  EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+}
+
+TEST(MetricsLogManagerTest, ProvisionalStoreStandardFlow) {
+  // Ensure that provisional store works, and discards the correct log.
+  {
+    MetricsLogManager log_manager;
+    DummyLogSerializer* serializer = new DummyLogSerializer;
+    log_manager.set_log_serializer(serializer);
+    log_manager.LoadPersistedUnsentLogs();
+
+    MetricsLogBase* log1 =
+        new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
+    MetricsLogBase* log2 =
+        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
+    log_manager.BeginLoggingWithLog(log1);
+    log_manager.FinishCurrentLog();
+    log_manager.BeginLoggingWithLog(log2);
+    log_manager.StageNextLogForUpload();
+    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
+    log_manager.FinishCurrentLog();
+    log_manager.DiscardLastProvisionalStore();
+
+    log_manager.PersistUnsentLogs();
+    EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
+    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+  }
+}
+
+TEST(MetricsLogManagerTest, ProvisionalStoreNoop) {
+  // Ensure that trying to drop a sent log is a no-op, even if another log has
+  // since been staged.
+  {
+    MetricsLogManager log_manager;
+    DummyLogSerializer* serializer = new DummyLogSerializer;
+    log_manager.set_log_serializer(serializer);
+    log_manager.LoadPersistedUnsentLogs();
+
+    MetricsLogBase* log1 =
+        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
+    MetricsLogBase* log2 =
+        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
+    log_manager.BeginLoggingWithLog(log1);
+    log_manager.FinishCurrentLog();
+    log_manager.StageNextLogForUpload();
+    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
+    log_manager.StageNextLogForUpload();
+    log_manager.DiscardStagedLog();
+    log_manager.BeginLoggingWithLog(log2);
+    log_manager.FinishCurrentLog();
+    log_manager.StageNextLogForUpload();
+    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
+    log_manager.DiscardLastProvisionalStore();
+
+    log_manager.PersistUnsentLogs();
+    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+  }
+
+  // Ensure that trying to drop more than once is a no-op
+  {
+    MetricsLogManager log_manager;
+    DummyLogSerializer* serializer = new DummyLogSerializer;
+    log_manager.set_log_serializer(serializer);
+    log_manager.LoadPersistedUnsentLogs();
+
+    MetricsLogBase* log1 =
+        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
+    MetricsLogBase* log2 =
+        new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
+    log_manager.BeginLoggingWithLog(log1);
+    log_manager.FinishCurrentLog();
+    log_manager.StageNextLogForUpload();
+    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
+    log_manager.BeginLoggingWithLog(log2);
+    log_manager.FinishCurrentLog();
+    log_manager.StageNextLogForUpload();
+    log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
+    log_manager.DiscardLastProvisionalStore();
+    log_manager.DiscardLastProvisionalStore();
+
+    log_manager.PersistUnsentLogs();
+    EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
+  }
+}
+
+TEST(MetricsLogManagerTest, SerializedLog) {
+  const char kFooText[] = "foo";
+  const std::string foo_hash = base::SHA1HashString(kFooText);
+  const char kBarText[] = "bar";
+  const std::string bar_hash = base::SHA1HashString(kBarText);
+
+  MetricsLogManager::SerializedLog log;
+  EXPECT_TRUE(log.log_text().empty());
+  EXPECT_TRUE(log.log_hash().empty());
+
+  std::string foo = kFooText;
+  log.SwapLogText(&foo);
+  EXPECT_TRUE(foo.empty());
+  EXPECT_FALSE(log.IsEmpty());
+  EXPECT_EQ(kFooText, log.log_text());
+  EXPECT_EQ(foo_hash, log.log_hash());
+
+  std::string bar = kBarText;
+  log.SwapLogText(&bar);
+  EXPECT_EQ(kFooText, bar);
+  EXPECT_FALSE(log.IsEmpty());
+  EXPECT_EQ(kBarText, log.log_text());
+  EXPECT_EQ(bar_hash, log.log_hash());
+
+  log.Clear();
+  EXPECT_TRUE(log.IsEmpty());
+  EXPECT_TRUE(log.log_text().empty());
+  EXPECT_TRUE(log.log_hash().empty());
+
+  MetricsLogManager::SerializedLog log2;
+  foo = kFooText;
+  log2.SwapLogText(&foo);
+  log.Swap(&log2);
+  EXPECT_FALSE(log.IsEmpty());
+  EXPECT_EQ(kFooText, log.log_text());
+  EXPECT_EQ(foo_hash, log.log_hash());
+  EXPECT_TRUE(log2.IsEmpty());
+  EXPECT_TRUE(log2.log_text().empty());
+  EXPECT_TRUE(log2.log_hash().empty());
+}
+
+}  // namespace metrics
diff --git a/components/metrics/proto/chrome_user_metrics_extension.proto b/components/metrics/proto/chrome_user_metrics_extension.proto
new file mode 100644
index 0000000..80f3499
--- /dev/null
+++ b/components/metrics/proto/chrome_user_metrics_extension.proto
@@ -0,0 +1,58 @@
+// 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.
+//
+// Protocol buffer for Chrome UMA (User Metrics Analysis).
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package metrics;
+
+import "histogram_event.proto";
+import "omnibox_event.proto";
+import "profiler_event.proto";
+import "system_profile.proto";
+import "user_action_event.proto";
+import "perf_data.proto";
+
+// Next tag: 11
+message ChromeUserMetricsExtension {
+  // The product (i.e. end user application) for a given UMA log.
+  enum Product {
+    // Google Chrome product family.
+    CHROME = 0;
+  }
+  // The product corresponding to this log. Note: The default value is Chrome,
+  // so Chrome products will not transmit this field.
+  optional Product product = 10 [default = CHROME];
+
+  // The id of the client install that generated these events.
+  //
+  // For Chrome clients, this id is unique to a top-level (one level above the
+  // "Default" directory) Chrome user data directory [1], and so is shared among
+  // all Chrome user profiles contained in this user data directory.
+  // An id of 0 is reserved for test data (monitoring and internal testing) and
+  // should normally be ignored in analysis of the data.
+  // [1] http://www.chromium.org/user-experience/user-data-directory
+  optional fixed64 client_id = 1;
+
+  // The session id for this user.
+  // Values such as tab ids are only meaningful within a particular session.
+  // The client keeps track of the session id and sends it with each event.
+  // The session id is simply an integer that is incremented each time the user
+  // relaunches Chrome.
+  optional int32 session_id = 2;
+
+  // Information about the user's browser and system configuration.
+  optional SystemProfileProto system_profile = 3;
+
+  // This message will log one or more of the following event types:
+  repeated UserActionEventProto user_action_event = 4;
+  repeated OmniboxEventProto omnibox_event = 5;
+  repeated HistogramEventProto histogram_event = 6;
+  repeated ProfilerEventProto profiler_event = 7;
+
+  repeated PerfDataProto perf_data = 8;
+}
diff --git a/components/metrics/proto/histogram_event.proto b/components/metrics/proto/histogram_event.proto
new file mode 100644
index 0000000..7cb0e8c
--- /dev/null
+++ b/components/metrics/proto/histogram_event.proto
@@ -0,0 +1,45 @@
+// 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.
+//
+// Histogram-collected metrics.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package metrics;
+
+// Next tag: 4
+message HistogramEventProto {
+  // The name of the histogram, hashed.
+  optional fixed64 name_hash = 1;
+
+  // The sum of all the sample values.
+  // Together with the total count of the sample values, this allows us to
+  // compute the average value.  The count of all sample values is just the sum
+  // of the counts of all the buckets.
+  optional int64 sum = 2;
+
+  // The per-bucket data.
+  message Bucket {
+    // Each bucket's range is bounded by min <= x < max.
+    // It is valid to omit one of these two fields in a bucket, but not both.
+    // If the min field is omitted, its value is assumed to be equal to max - 1.
+    // If the max field is omitted, its value is assumed to be equal to the next
+    // bucket's min value (possibly computed per above).  The last bucket in a
+    // histogram should always include the max field.
+    optional int64 min = 1;
+    optional int64 max = 2;
+
+    // The bucket's index in the list of buckets, sorted in ascending order.
+    // This field was intended to provide extra redundancy to detect corrupted
+    // records, but was never used.  As of M31, it is no longer sent by Chrome
+    // clients to reduce the UMA upload size.
+    optional int32 bucket_index = 3 [deprecated = true];
+
+    // The number of entries in this bucket.
+    optional int64 count = 4;
+  }
+  repeated Bucket bucket = 3;
+}
diff --git a/components/metrics/proto/omnibox_event.proto b/components/metrics/proto/omnibox_event.proto
new file mode 100644
index 0000000..cb87c8a
--- /dev/null
+++ b/components/metrics/proto/omnibox_event.proto
@@ -0,0 +1,268 @@
+// 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.
+//
+// Stores information about an omnibox interaction.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package metrics;
+
+// Next tag: 17
+message OmniboxEventProto {
+  // The timestamp for the event, in seconds since the epoch.
+  optional int64 time = 1;
+
+  // The id of the originating tab for this omnibox interaction.
+  // This is the current tab *unless* the user opened the target in a new tab.
+  // In those cases, this is unset.  Tab ids are unique for a given session_id
+  // (in the containing protocol buffer ChromeUserMetricsExtensionProto).
+  optional int32 tab_id = 2;
+
+  // The number of characters the user had typed before autocompleting.
+  optional int32 typed_length = 3;
+
+  // Whether the user deleted text immediately before selecting an omnibox
+  // suggestion.  This is usually the result of pressing backspace or delete.
+  optional bool just_deleted_text = 11;
+
+  // The number of terms that the user typed in the omnibox.
+  optional int32 num_typed_terms = 4;
+
+  // The index of the item that the user selected in the omnibox popup list.
+  // This corresponds the index of the |suggestion| below.
+  optional int32 selected_index = 5;
+
+  // Whether or not the top match was hidden in the omnibox suggestions
+  // dropdown.
+  optional bool is_top_result_hidden_in_dropdown = 14;
+
+  // Whether the omnibox popup is open.  It can be closed if, for instance,
+  // the user clicks in the omnibox and hits return to reload the same page.
+  // If the popup is closed, the suggestion list will contain only one item
+  // and selected_index will be 0 (pointing to that single item).  Because
+  // paste-and-search/paste-and-go actions ignore the current content of the
+  // omnibox dropdown (if it is open) when they happen, we pretend the
+  // dropdown is closed when logging these.
+  optional bool is_popup_open = 15;
+
+  // True if this is a paste-and-search or paste-and-go action.  (The codebase
+  // refers to both these types as paste-and-go.)
+  optional bool is_paste_and_go = 16;
+
+  // The length of the inline autocomplete text in the omnibox.
+  // The sum |typed_length| + |completed_length| gives the full length of the
+  // user-visible text in the omnibox.
+  // This field is only set for inlineable suggestions selected at position 0
+  // (|selected_index| = 0) and will be omitted otherwise.
+  optional int32 completed_length = 6;
+
+  // The amount of time, in milliseconds, since the user first began modifying
+  // the text in the omnibox.  If at some point after modifying the text, the
+  // user reverts the modifications (thus seeing the current web page's URL
+  // again), then writes in the omnibox again, this elapsed time should start
+  // from the time of the second series of modification.
+  optional int64 typing_duration_ms = 7;
+
+  // The amount of time, in milliseconds, since the last time the default
+  // (inline) match changed.  This may be longer than the time since the
+  // last keystroke.  (The last keystroke may not have changed the default
+  // match.)  It may also be shorter than the time since the last keystroke
+  // because the default match might have come from an asynchronous
+  // provider.  Regardless, it should always be less than or equal to
+  // the field |typing_duration_ms|.
+  optional int64 duration_since_last_default_match_update_ms = 13;
+
+  // The type of page currently displayed when the user used the omnibox.
+  enum PageClassification {
+    // An invalid URL; shouldn't happen.
+    INVALID_SPEC = 0;
+
+    // chrome://newtab/.  This can be either the built-in version or a
+    // replacement new tab page from an extension.  Note that when Instant
+    // Extended is enabled, the new tab page will be reported as either
+    // INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS or
+    // INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS below,
+    // unless an extension is replacing the new tab page, in which case
+    // it will still be reported as NTP.
+    NTP = 1;
+
+    // about:blank.
+    BLANK = 2;
+
+    // The user's home page.  Note that if the home page is set to any
+    // of the new tab page versions or to about:blank, then we'll
+    // classify the page into those categories, not HOME_PAGE.
+    HOME_PAGE = 3;
+
+    // The catch-all entry of everything not included somewhere else
+    // on this list.
+    OTHER = 4;
+
+    // The instant new tab page enum value was deprecated on August 2, 2013.
+    OBSOLETE_INSTANT_NTP = 5;
+
+    // The user is on a search result page that's doing search term
+    // replacement, meaning the search terms should've appeared in the omnibox
+    // before the user started editing it, not the URL of the page.
+    SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT = 6;
+
+    // The new tab page in which this omnibox interaction first started
+    // with the user having focus in the omnibox.
+    INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS = 7;
+
+    // The new tab page in which this omnibox interaction first started
+    // with the user having focus in the fakebox.
+    INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS = 8;
+
+    // The user is on a search result page that's not doing search term
+    // replacement, meaning the URL of the page should've appeared in the
+    // omnibox before the user started editing it, not the search terms.
+    SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT = 9;
+
+    // When adding new classifications, please consider adding them in
+    // chrome/browser/resources/omnibox/omnibox.html
+    // so that these new options are displayed on about:omnibox.
+  }
+  optional PageClassification current_page_classification = 10;
+
+  // What kind of input the user provided.
+  enum InputType {
+    INVALID = 0;        // Empty input (should not reach here)
+    UNKNOWN = 1;        // Valid input whose type cannot be determined
+    REQUESTED_URL = 2;  // DEPRECATED. Input autodetected as UNKNOWN, which the
+                        // user wants to treat as an URL by specifying a
+                        // desired_tld
+    URL = 3;            // Input autodetected as a URL
+    QUERY = 4;          // Input autodetected as a query
+    FORCED_QUERY = 5;   // Input forced to be a query by an initial '?'
+  }
+  optional InputType input_type = 8;
+
+  // An enum used in multiple places below.
+  enum ProviderType {
+    UNKNOWN_PROVIDER = 0;  // Unknown provider (should not reach here)
+    HISTORY_URL = 1;       // URLs in history, or user-typed URLs
+    HISTORY_CONTENTS = 2;  // Matches for page contents of pages in history
+    HISTORY_QUICK = 3;     // Matches for recently or frequently visited pages
+                           // in history
+    SEARCH = 4;            // Search suggestions for the default search engine
+    KEYWORD = 5;           // Keyword-triggered searches
+    BUILTIN = 6;           // Built-in URLs, such as chrome://version
+    SHORTCUTS = 7;         // Recently selected omnibox suggestions
+    EXTENSION_APPS = 8;    // Custom suggestions from extensions and/or apps
+    CONTACT = 9;           // DEPRECATED. The user's contacts
+    BOOKMARK = 10;         // The user's bookmarks
+    ZERO_SUGGEST = 11;     // Suggestions based on the current page
+    // This enum value is currently only used by Android GSA. It represents
+    // a suggestion from the phone.
+    ON_DEVICE = 12;
+  }
+
+  // The result set displayed on the completion popup
+  // Next tag: 6
+  message Suggestion {
+    // Where does this result come from?
+    optional ProviderType provider = 1;
+
+    // What kind of result this is.
+    // This corresponds to the AutocompleteMatch::Type enumeration in
+    // chrome/browser/autocomplete/autocomplete_match.h (except for Android
+    // GSA result types).
+    enum ResultType {
+      UNKNOWN_RESULT_TYPE = 0;    // Unknown type (should not reach here)
+      URL_WHAT_YOU_TYPED = 1;     // The input as a URL
+      HISTORY_URL = 2;            // A past page whose URL contains the input
+      HISTORY_TITLE = 3;          // A past page whose title contains the input
+      HISTORY_BODY = 4;           // A past page whose body contains the input
+      HISTORY_KEYWORD = 5;        // A past page whose keyword contains the
+                                  // input
+      NAVSUGGEST = 6;             // A suggested URL
+      SEARCH_WHAT_YOU_TYPED = 7;  // The input as a search query (with the
+                                  // default engine)
+      SEARCH_HISTORY = 8;         // A past search (with the default engine)
+                                  // containing the input
+      SEARCH_SUGGEST = 9;         // A suggested search (with the default
+                                  // engine) for a query.
+      SEARCH_OTHER_ENGINE = 10;   // A search with a non-default engine
+      EXTENSION_APP = 11;         // An Extension App with a title/url that
+                                  // contains the input
+      CONTACT = 12;               // One of the user's contacts
+      BOOKMARK_TITLE = 13;        // A bookmark whose title contains the input.
+      SEARCH_SUGGEST_ENTITY = 14; // A suggested search for an entity.
+      SEARCH_SUGGEST_INFINITE = 15; // A suggested search to complete the tail
+                                    // of the query.
+      SEARCH_SUGGEST_PERSONALIZED = 16; // A personalized suggested search.
+      SEARCH_SUGGEST_PROFILE = 17;  // A personalized suggested search for a
+                                    // Google+ profile.
+      APP_RESULT = 18;              // Result from an installed app
+                                    // (eg: a gmail email).
+                                    // Used by Android GSA for on-device
+                                    // suggestion logging.
+      APP = 19;                     // An app result (eg: the gmail app).
+                                    // Used by Android GSA for on-device
+                                    // suggestion logging.
+      LEGACY_ON_DEVICE = 20;        // An on-device result from a legacy
+                                    // provider. That is, this result is not
+                                    // from the on-device suggestion provider
+                                    // (go/icing). This field is
+                                    // used by Android GSA for on-device
+                                    // suggestion logging.
+      NAVSUGGEST_PERSONALIZED = 21; // A personalized url.
+    }
+    optional ResultType result_type = 2;
+
+    // The relevance score for this suggestion.
+    optional int32 relevance = 3;
+
+    // How many times this result was typed in / selected from the omnibox.
+    // Only set for some providers and result_types.  At the time of
+    // writing this comment, it is only set for HistoryURL and
+    // HistoryQuickProvider matches.
+    optional int32 typed_count = 5;
+
+    // Whether this item is starred (bookmarked) or not.
+    optional bool is_starred = 4;
+  }
+  repeated Suggestion suggestion = 9;
+
+  // A data structure that holds per-provider information, general information
+  // not associated with a particular result.
+  // Next tag: 6
+  message ProviderInfo {
+    // Which provider generated this ProviderInfo entry.
+    optional ProviderType provider = 1;
+
+    // The provider's done() value, i.e., whether it's completed processing
+    // the query.  Providers which don't do any asynchronous processing
+    // will always be done.
+    optional bool provider_done = 2;
+
+    // The set of field trials that have triggered in the most recent query,
+    // possibly affecting the shown suggestions.  Each element is a hash
+    // of the corresponding field trial name.
+    // See chrome/browser/autocomplete/search_provider.cc for a specific usage
+    // example.
+    repeated fixed32 field_trial_triggered = 3;
+
+    // Same as above except that the set of field trials is a union of all field
+    // trials that have triggered within the current omnibox session including
+    // the most recent query.
+    // See AutocompleteController::ResetSession() for more details on the
+    // definition of a session.
+    // See chrome/browser/autocomplete/search_provider.cc for a specific usage
+    // example.
+    repeated fixed32 field_trial_triggered_in_session = 4;
+
+    // The number of times this provider returned a non-zero number of
+    // suggestions during this omnibox session.
+    // Note that each provider may define a session differently for its
+    // purposes.
+    optional int32 times_returned_results_in_session = 5;
+  }
+  // A list of diagnostic information about each provider.  Providers
+  // will appear at most once in this list.
+  repeated ProviderInfo provider_info = 12;
+}
diff --git a/components/metrics/proto/perf_data.proto b/components/metrics/proto/perf_data.proto
new file mode 100644
index 0000000..6278649
--- /dev/null
+++ b/components/metrics/proto/perf_data.proto
@@ -0,0 +1,388 @@
+// 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package metrics;
+
+// Stores information from a perf session generated via running:
+// "perf record"
+//
+// See $kernel/tools/perf/design.txt for more details.
+
+// Please do not modify this protobuf directly, except to mirror the upstream
+// version found here:
+// https://chromium.googlesource.com/chromiumos/platform/chromiumos-wide-profiling/+/master/perf_data.proto
+// with some fields omitted for privacy reasons. Because it is a read-only copy
+// of the upstream protobuf, "Next tag:" comments are also absent.
+
+message PerfDataProto {
+
+  // Perf event attribute. Stores the event description.
+  // This data structure is defined in the linux kernel:
+  // $kernel/tools/perf/util/event.h.
+  message PerfEventAttr {
+    // Type of the event. Type is an enumeration and can be:
+    // IP: an instruction-pointer was stored in the event.
+    // MMAP: a DLL was loaded.
+    // FORK: a process was forked.
+    // etc.
+    optional uint32 type = 1;
+
+    // Size of the event data in bytes.
+    optional uint32 size = 2;
+
+    // The config stores the CPU-specific counter information.
+    optional uint64 config = 3;
+
+    // Sample period of the event. Indicates how often the event is
+    // triggered in terms of # of events. After |sample_period| events, an event
+    // will be recorded and stored.
+    optional uint64 sample_period = 4;
+
+    // Sample frequency of the event. Indicates how often the event is
+    // triggered in terms of # per second. The kernel will try to record
+    // |sample_freq| events per second.
+    optional uint64 sample_freq = 5;
+
+    // Sample type is a bitfield that records attributes of the sample. Example,
+    // whether an entire callchain was recorded, etc.
+    optional uint64 sample_type = 6;
+
+    // Bitfield that indicates whether reads on the counter will return the
+    // total time enabled and total time running.
+    optional uint64 read_format = 7;
+
+    // Indicates whether the counter starts off disabled.
+    optional bool disabled = 8;
+
+    // Indicates whether child processes inherit the counter.
+    optional bool inherit = 9;
+
+    // Indicates whether the counter is pinned to a particular CPU.
+    optional bool pinned = 10;
+
+    // Indicates whether this counter's group has exclusive access to the CPU's
+    // counters.
+    optional bool exclusive = 11;
+
+    // The following bits restrict events to be counted when the CPU is in user,
+    // kernel, hypervisor or idle modes.
+    optional bool exclude_user = 12;
+    optional bool exclude_kernel = 13;
+    optional bool exclude_hv = 14;
+    optional bool exclude_idle = 15;
+
+    // Indicates whether mmap events should be recorded.
+    optional bool mmap = 16;
+
+    // Indicates whether process comm information should be recorded upon
+    // process creation.
+    optional bool comm = 17;
+
+    // Indicates that we are in frequency mode, not period mode.
+    optional bool freq = 18;
+
+    // Indicates whether we have per-task counts.
+    optional bool inherit_stat = 19;
+
+    // Indicates whether we enable perf events after an exec() function call.
+    optional bool enable_on_exec = 20;
+
+    // Indicates whether we trace fork/exit.
+    optional bool task = 21;
+
+    // Indicates whether we are using a watermark to wake up.
+    optional bool watermark = 22;
+
+    // CPUs often "skid" when recording events. That means the instruction
+    // pointer may not be the same as the one that caused the counter overflow.
+    // Indicates the capabilities of the CPU in terms of recording precise
+    // instruction pointer.
+    optional uint32 precise_ip = 23;
+
+    // Indicates whether we have non-exec mmap data.
+    optional bool mmap_data = 24;
+
+    // If set, all the event types will have the same sample_type.
+    optional bool sample_id_all = 25;
+
+    // Indicates whether we are counting events from the host (when running a
+    // VM).
+    optional bool exclude_host = 26;
+
+    // Exclude events that happen on a guest OS.
+    optional bool exclude_guest = 27;
+
+    // Contains the number of events after which we wake up.
+    optional uint32 wakeup_events = 28;
+
+    // Contains the number of bytes after which we wake up.
+    optional uint32 wakeup_watermark = 29;
+
+    // Information about the type of the breakpoint.
+    optional uint32 bp_type = 30;
+
+    // Contains the breakpoint address.
+    optional uint64 bp_addr = 31;
+
+    // This is an extension of config (see above).
+    optional uint64 config1 = 32;
+
+    // The length of the breakpoint data in bytes.
+    optional uint64 bp_len = 33;
+
+    // This is an extension of config (see above).
+    optional uint64 config2 = 34;
+
+    // Contains the type of branch, example: user, kernel, call, return, etc.
+    optional uint64 branch_sample_type = 35;
+  }
+
+  // Describes a perf.data file attribute.
+  message PerfFileAttr {
+    optional PerfEventAttr attr = 1;
+
+    // List of perf file attribute ids. Each id describes an event.
+    repeated uint64 ids = 2;
+  }
+
+  // This message contains information about a perf sample itself, as opposed to
+  // a perf event captured by a sample.
+  message SampleInfo {
+    // Process ID / thread ID from which this sample was taken.
+    optional uint32 pid = 1;
+    optional uint32 tid = 2;
+
+    // Time this sample was taken (NOT the same as an event time).
+    // It is the number of nanoseconds since bootup.
+    optional uint64 sample_time_ns = 3;
+
+    // The ID of the sample's event type (cycles, instructions, etc).
+    // The event type IDs are defined in PerfFileAttr.
+    optional uint64 id = 4;
+
+    // The CPU on which this sample was taken.
+    optional uint32 cpu = 5;
+  }
+
+  message CommEvent {
+    // Process id.
+    optional uint32 pid = 1;
+
+    // Thread id.
+    optional uint32 tid = 2;
+
+    // Comm string's md5 prefix.
+    // The comm string was field 3 and has been intentionally left out.
+    optional uint64 comm_md5_prefix = 4;
+
+    // Time the sample was taken.
+    // Deprecated, use |sample_info| instead.
+    optional uint64 sample_time = 5 [deprecated=true];
+
+    // Info about the perf sample containing this event.
+    optional SampleInfo sample_info = 6;
+  }
+
+  message MMapEvent {
+    // Process id.
+    optional uint32 pid = 1;
+
+    // Thread id.
+    optional uint32 tid = 2;
+
+    // Start address.
+    optional uint64 start = 3;
+
+    // Length.
+    optional uint64 len = 4;
+
+    // PG Offset.
+    optional uint64 pgoff = 5;
+
+    // Filename's md5 prefix.
+    // The filename was field 6 and has been intentionally left out.
+    optional uint64 filename_md5_prefix = 7;
+
+    // Info about the perf sample containing this event.
+    optional SampleInfo sample_info = 8;
+  }
+
+  message BranchStackEntry {
+    // Branch source address.
+    optional uint64 from_ip = 1;
+
+    // Branch destination address.
+    optional uint64 to_ip = 2;
+
+    // Indicates a mispredicted branch.
+    optional bool mispredicted = 3;
+  }
+
+  message SampleEvent {
+    // Instruction pointer.
+    optional uint64 ip = 1;
+
+    // Process id.
+    optional uint32 pid = 2;
+
+    // Thread id.
+    optional uint32 tid = 3;
+
+    // The time after boot when the sample was recorded, in nanoseconds.
+    optional uint64 sample_time_ns = 4;
+
+    // The address of the sample.
+    optional uint64 addr = 5;
+
+    // The id of the sample.
+    optional uint64 id = 6;
+
+    // The stream id of the sample.
+    optional uint64 stream_id = 7;
+
+    // The period of the sample.
+    optional uint64 period = 8;
+
+    // The CPU where the event was recorded.
+    optional uint32 cpu = 9;
+
+    // The raw size of the event in bytes.
+    optional uint32 raw_size = 10;
+
+    // Sample callchain info.
+    repeated uint64 callchain = 11;
+
+    // Branch stack info.
+    repeated BranchStackEntry branch_stack = 12;
+  }
+
+  // ForkEvent is used for both FORK and EXIT events, which have the same data
+  // format.  We don't want to call this "ForkOrExitEvent", in case a separate
+  // exit event is introduced in the future.
+  message ForkEvent {
+    // Forked process ID.
+    optional uint32 pid = 1;
+
+    // Parent process ID.
+    optional uint32 ppid = 2;
+
+    // Forked process thread ID.
+    optional uint32 tid = 3;
+
+    // Parent process thread ID.
+    optional uint32 ptid = 4;
+
+    // Time of fork event in nanoseconds since bootup.
+    optional uint64 fork_time_ns = 5;
+
+    // Info about the perf sample containing this event.
+    optional SampleInfo sample_info = 11;
+  }
+
+  message EventHeader {
+    // Type of event.
+    optional uint32 type = 1;
+    optional uint32 misc = 2;
+    // Size of event.
+    optional uint32 size = 3;
+  }
+
+  message PerfEvent {
+    optional EventHeader header = 1;
+
+    optional MMapEvent mmap_event = 2;
+    optional SampleEvent sample_event = 3;
+    optional CommEvent comm_event = 4;
+    optional ForkEvent fork_event = 5;
+  }
+
+  message PerfEventStats {
+    // Total number of events read from perf data.
+    optional uint32 num_events_read = 1;
+
+    // Total number of various types of events.
+    optional uint32 num_sample_events = 2;
+    optional uint32 num_mmap_events = 3;
+    optional uint32 num_fork_events = 4;
+    optional uint32 num_exit_events = 5;
+
+    // Number of sample events that were successfully mapped by the address
+    // mapper, a quipper module that is used to obscure addresses and convert
+    // them to DSO name + offset.  Sometimes it fails to process sample events.
+    // This field allows us to track the success rate of the address mapper.
+    optional uint32 num_sample_events_mapped = 6;
+
+    // Whether address remapping was enabled.
+    optional bool did_remap = 7;
+  }
+
+  message PerfBuildID {
+    // Misc field in perf_event_header.
+    // Indicates whether the file is mapped in kernel mode or user mode.
+    optional uint32 misc = 1;
+
+    // Process ID.
+    optional uint32 pid = 2;
+
+    // Build id.  Should always contain kBuildIDArraySize bytes of data.
+    // perf_reader.h in Chrome OS defines kBuildIDArraySize = 20.
+    optional bytes build_hash = 3;
+
+    // Filename Md5sum prefix.
+    // The filename was field 4 and has been intentionally left out.
+    optional uint64 filename_md5_prefix = 5;
+  }
+
+  repeated PerfFileAttr file_attrs = 1;
+  repeated PerfEvent events = 2;
+
+  // Time when quipper generated this perf data / protobuf, given as seconds
+  // since the epoch.
+  optional uint64 timestamp_sec = 3;
+
+  // Records some stats about the serialized perf events.
+  optional PerfEventStats stats = 4;
+
+  // Not added from original: repeated uint64 metadata_mask = 5;
+
+  // Build ID metadata.
+  repeated PerfBuildID build_ids = 7;
+
+  // Not added from original: repeated PerfUint32Metadata uint32_metadata = 8;
+  // Not added from original: repeated PerfUint64Metadata uint64_metadata = 9;
+  // Not added from original:
+  //     optional PerfCPUTopologyMetadata cpu_topology = 11;
+  // Not added from original:
+  //     repeated PerfNodeTopologyMetadata numa_topology = 12;
+
+  message StringMetadata {
+    message StringAndMd5sumPrefix {
+      // The string value was field 1 and has been intentionally left out.
+
+      // The string value's md5sum prefix.
+      optional uint64 value_md5_prefix = 2;
+    }
+
+    // Not added from original: optional StringAndMd5sumPrefix hostname = 1;
+    // Not added from original:
+    //     optional StringAndMd5sumPrefix kernel_version =2;
+    // Not added from original: optional StringAndMd5sumPrefix perf_version = 3;
+    // Not added from original: optional StringAndMd5sumPrefix architecture = 4;
+    // Not added from original:
+    //     optional StringAndMd5sumPrefix cpu_description = 5;
+    // Not added from original: optional StringAndMd5sumPrefix cpu_id = 6;
+    // Not added from original:
+    //     repeated StringAndMd5sumPrefix perf_command_line_token = 7;
+
+    // The command line stored as a single string.
+    optional StringAndMd5sumPrefix perf_command_line_whole = 8;
+  }
+
+  // All the string metadata from the perf data file.
+  optional StringMetadata string_metadata = 13;
+}
diff --git a/components/metrics/proto/profiler_event.proto b/components/metrics/proto/profiler_event.proto
new file mode 100644
index 0000000..1f18b2a
--- /dev/null
+++ b/components/metrics/proto/profiler_event.proto
@@ -0,0 +1,92 @@
+// 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.
+//
+// Performance metrics collected via Chrome's built-in profiler.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package metrics;
+
+
+// Next tag: 4
+message ProfilerEventProto {
+  // The type of this profile.
+  enum ProfileType {
+    UNKNOWN_PROFILE = 0;  // Unknown type (should not reach here).
+    STARTUP_PROFILE = 1;  // Startup profile, logged approximately 60 seconds
+                          // after launch.
+  }
+  optional ProfileType profile_type = 1;
+
+  // The source based upon which "time" measurements are made.
+  // We currently only measure wall clock time; but we are exploring other
+  // measurement sources as well, such as CPU time or TCMalloc statistics.
+  enum TimeSource {
+    UNKNOWN_TIME_SOURCE = 0;  // Unknown source (should not reach here).
+    WALL_CLOCK_TIME = 1;      // Total time elapsed between the start and end of
+                              // the task's execution.
+  }
+  optional TimeSource time_source = 2;
+
+  // Data for a single tracked object (typically, a Task).
+  message TrackedObject {
+    // The name of the thread from which this task was posted, hashed.
+    optional fixed64 birth_thread_name_hash = 1;
+
+    // The name of the thread on which this task was executed, hashed.
+    optional fixed64 exec_thread_name_hash = 2;
+
+    // The source file name from which this task was posted, hashed.
+    optional fixed64 source_file_name_hash = 3;
+
+    // Function name from which this task was posted, hashed.
+    optional fixed64 source_function_name_hash = 4;
+
+    // The line number within the source file from which this task was posted.
+    optional int32 source_line_number = 5;
+
+    // The number of times this task was executed.
+    optional int32 exec_count = 6;
+
+    // The total execution time for instances this task.
+    optional int32 exec_time_total = 7;
+
+    // The execution time for a uniformly randomly sampled instance of this
+    // task.
+    optional int32 exec_time_sampled = 8;
+
+    // The total time instances this task spent waiting (e.g. in a message loop)
+    // before they were run.
+    optional int32 queue_time_total = 9;
+
+    // The time that a uniformly randomly sampled instance of this task spent
+    // waiting (e.g.  in a message loop) before it was run.
+    optional int32 queue_time_sampled = 10;
+
+    // The type of process within which this task was executed.
+    enum ProcessType {
+      UNKNOWN = 0;  // Should not reach here
+      BROWSER = 1;
+      RENDERER = 2;
+      PLUGIN = 3;
+      WORKER = 4;
+      NACL_LOADER = 5;
+      UTILITY = 6;
+      PROFILE_IMPORT = 7;
+      ZYGOTE = 8;
+      SANDBOX_HELPER = 9;
+      NACL_BROKER = 10;
+      GPU = 11;
+      PPAPI_PLUGIN = 12;
+      PPAPI_BROKER = 13;
+    }
+    optional ProcessType process_type = 11;
+
+    // The local PID for the process within which this task was executed.
+    optional uint32 process_id = 12;
+  }
+  repeated TrackedObject tracked_object = 3;
+}
diff --git a/components/metrics/proto/system_profile.proto b/components/metrics/proto/system_profile.proto
new file mode 100644
index 0000000..98a0f5d
--- /dev/null
+++ b/components/metrics/proto/system_profile.proto
@@ -0,0 +1,509 @@
+// 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.
+//
+// Stores information about the user's brower and system configuration.
+// The system configuration fields are recorded once per client session.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package metrics;
+
+// Next tag: 19
+message SystemProfileProto {
+  // The time when the client was compiled/linked, in seconds since the epoch.
+  optional int64 build_timestamp = 1;
+
+  // A version number string for the application.
+  // Most commonly this is the browser version number found in a user agent
+  // string, and is typically a 4-tuple of numbers separated by periods.  In
+  // cases where the user agent version might be ambiguous (example: Linux 64-
+  // bit build, rather than 32-bit build, or a Windows version used in some
+  // special context, such as ChromeFrame running in IE), then this may include
+  // some additional postfix to provide clarification not available in the UA
+  // string.
+  //
+  // An example of a browser version 4-tuple is "5.0.322.0".  Currently used
+  // postfixes are:
+  //
+  //   "-64": a 64-bit build
+  //   "-F": Chrome is running under control of ChromeFrame
+  //   "-devel": this is not an official build of Chrome
+  //
+  // A full version number string could look similar to:
+  // "5.0.322.0-F-devel".
+  //
+  // This value, when available, is more trustworthy than the UA string
+  // associated with the request; and including the postfix, may be more
+  // specific.
+  optional string app_version = 2;
+
+  // The brand code or distribution tag assigned to a partner, if available.
+  // Brand codes are only available on Windows.  Not every Windows install
+  // though will have a brand code.
+  optional string brand_code = 12;
+
+  // The possible channels for an installation, from least to most stable.
+  enum Channel {
+    CHANNEL_UNKNOWN = 0;  // Unknown channel -- perhaps an unofficial build?
+    CHANNEL_CANARY = 1;
+    CHANNEL_DEV = 2;
+    CHANNEL_BETA = 3;
+    CHANNEL_STABLE = 4;
+  }
+  optional Channel channel = 10;
+
+  // The date the user enabled UMA, in seconds since the epoch.
+  // If the user has toggled the UMA enabled state multiple times, this will
+  // be the most recent date on which UMA was enabled.
+  // For privacy, this is rounded to the nearest hour.
+  optional int64 uma_enabled_date = 3;
+
+  // The time when the client was installed, in seconds since the epoch.
+  // For privacy, this is rounded to the nearest hour.
+  optional int64 install_date = 16;
+
+  // The user's selected application locale, i.e. the user interface language.
+  // The locale includes a language code and, possibly, also a country code,
+  // e.g. "en-US".
+  optional string application_locale = 4;
+
+  // Information on the user's operating system.
+  message OS {
+    // The user's operating system.
+    optional string name = 1;
+
+    // The version of the OS.  The meaning of this field is OS-dependent.
+    optional string version = 2;
+
+    // The fingerprint of the build.  This field is used only on Android.
+    optional string fingerprint = 3;
+  }
+  optional OS os = 5;
+
+  // Next tag for Hardware: 16
+  // Information on the user's hardware.
+  message Hardware {
+    // The CPU architecture (x86, PowerPC, x86_64, ...)
+    optional string cpu_architecture = 1;
+
+    // The amount of RAM present on the system, in megabytes.
+    optional int64 system_ram_mb = 2;
+
+    // The base memory address that chrome.dll was loaded at.
+    // (Logged only on Windows.)
+    optional int64 dll_base = 3;
+
+    // The Chrome OS device hardware class ID is a unique string associated with
+    // each Chrome OS device product revision generally assigned at hardware
+    // qualification time.  The hardware class effectively identifies the
+    // configured system components such as CPU, WiFi adapter, etc.
+    //
+    // An example of such a hardware class is "IEC MARIO PONY 6101".  An
+    // internal database associates this hardware class with the qualified
+    // device specifications including OEM information, schematics, hardware
+    // qualification reports, test device tags, etc.
+    optional string hardware_class = 4;
+
+    // The number of physical screens.
+    optional int32 screen_count = 5;
+
+    // The screen dimensions of the primary screen, in pixels.
+    optional int32 primary_screen_width = 6;
+    optional int32 primary_screen_height = 7;
+
+    // The device scale factor of the primary screen.
+    optional float primary_screen_scale_factor = 12;
+
+    // Max DPI for any attached screen. (Windows only)
+    optional float max_dpi_x = 9;
+    optional float max_dpi_y = 10;
+
+    // Information on the CPU obtained by CPUID.
+    message CPU {
+      // A 12 character string naming the vendor, e.g. "GeniuneIntel".
+      optional string vendor_name = 1;
+
+      // The signature reported by CPUID (from EAX).
+      optional uint32 signature = 2;
+    }
+    optional CPU cpu = 13;
+
+    // Information on the GPU
+    message Graphics {
+      // The GPU manufacturer's vendor id.
+      optional uint32 vendor_id = 1;
+
+      // The GPU manufacturer's device id for the chip set.
+      optional uint32 device_id = 2;
+
+      // The driver version on the GPU.
+      optional string driver_version = 3;
+
+      // The driver date on the GPU.
+      optional string driver_date = 4;
+
+      // The GPU performance statistics.
+      // See http://src.chromium.org/viewvc/chrome/trunk/src/content/public/common/gpu_performance_stats.h?view=markup
+      // for details.  Currently logged only on Windows.
+      message PerformanceStatistics {
+        optional float graphics_score = 1;
+        optional float gaming_score = 2;
+        optional float overall_score = 3;
+      }
+      optional PerformanceStatistics performance_statistics = 5;
+
+      // The GL_VENDOR string. An example of a gl_vendor string is
+      // "Imagination Technologies". "" if we are not using OpenGL.
+      optional string gl_vendor = 6;
+
+      // The GL_RENDERER string. An example of a gl_renderer string is
+      // "PowerVR SGX 540". "" if we are not using OpenGL.
+      optional string gl_renderer = 7;
+    }
+    optional Graphics gpu = 8;
+
+    // Information about Bluetooth devices paired with the system.
+    message Bluetooth {
+      // Whether Bluetooth is present on this system.
+      optional bool is_present = 1;
+
+      // Whether Bluetooth is enabled on this system.
+      optional bool is_enabled = 2;
+
+      // Describes a paired device.
+      message PairedDevice {
+        // Assigned class of the device. This is a bitfield according to the
+        // Bluetooth specification available at the following URL:
+        // https://www.bluetooth.org/en-us/specification/assigned-numbers-overview/baseband
+        optional uint32 bluetooth_class = 1;
+
+        // Decoded device type.
+        enum Type {
+          DEVICE_UNKNOWN = 0;
+          DEVICE_COMPUTER = 1;
+          DEVICE_PHONE = 2;
+          DEVICE_MODEM = 3;
+          DEVICE_AUDIO = 4;
+          DEVICE_CAR_AUDIO = 5;
+          DEVICE_VIDEO = 6;
+          DEVICE_PERIPHERAL = 7;
+          DEVICE_JOYSTICK = 8;
+          DEVICE_GAMEPAD = 9;
+          DEVICE_KEYBOARD = 10;
+          DEVICE_MOUSE = 11;
+          DEVICE_TABLET = 12;
+          DEVICE_KEYBOARD_MOUSE_COMBO = 13;
+        }
+        optional Type type = 2;
+
+        // Vendor prefix of the Bluetooth address, these are OUI registered by
+        // the IEEE and are encoded with the first byte in bits 16-23, the
+        // second byte in bits 8-15 and the third byte in bits 0-7.
+        //
+        // ie. Google's OUI (00:1A:11) is encoded as 0x00001A11
+        optional uint32 vendor_prefix = 4;
+
+        // The Vendor ID of a device, returned in vendor_id below, can be
+        // either allocated by the Bluetooth SIG or USB IF, providing two
+        // completely overlapping namespaces for identifiers.
+        //
+        // This field should be read along with vendor_id to correctly
+        // identify the vendor. For example Google is identified by either
+        // vendor_id_source = VENDOR_ID_BLUETOOTH, vendor_id = 0x00E0 or
+        // vendor_id_source = VENDOR_ID_USB, vendor_id = 0x18D1.
+        //
+        // If the device does not support the Device ID specification the
+        // unknown value will be set.
+        enum VendorIDSource {
+          VENDOR_ID_UNKNOWN = 0;
+          VENDOR_ID_BLUETOOTH = 1;
+          VENDOR_ID_USB = 2;
+        }
+        optional VendorIDSource vendor_id_source = 8;
+
+        // Vendor ID of the device, where available.
+        optional uint32 vendor_id = 5;
+
+        // Product ID of the device, where available.
+        optional uint32 product_id = 6;
+
+        // Device ID of the device, generally the release or version number in
+        // BCD format, where available.
+        optional uint32 device_id = 7;
+      }
+      repeated PairedDevice paired_device = 3;
+    }
+    optional Bluetooth bluetooth = 11;
+
+    // Whether the internal display produces touch events. Omitted if unknown.
+    // Logged on ChromeOS only.
+    optional bool internal_display_supports_touch = 14;
+
+    // Vendor ids and product ids of external touchscreens.
+    message TouchScreen {
+      // Touch screen vendor id.
+      optional uint32 vendor_id = 1;
+      // Touch screen product id.
+      optional uint32 product_id = 2;
+    }
+    // Lists vendor and product ids of external touchscreens.
+    // Logged on ChromeOS only.
+    repeated TouchScreen external_touchscreen = 15;
+  }
+  optional Hardware hardware = 6;
+
+  // Information about the network connection.
+  message Network {
+    // Set to true if connection_type changed during the lifetime of the log.
+    optional bool connection_type_is_ambiguous = 1;
+
+    // See net::NetworkChangeNotifier::ConnectionType.
+    enum ConnectionType {
+      CONNECTION_UNKNOWN = 0;
+      CONNECTION_ETHERNET = 1;
+      CONNECTION_WIFI = 2;
+      CONNECTION_2G = 3;
+      CONNECTION_3G = 4;
+      CONNECTION_4G = 5;
+    }
+    // The connection type according to NetworkChangeNotifier.
+    optional ConnectionType connection_type = 2;
+
+    // Set to true if wifi_phy_layer_protocol changed during the lifetime of the log.
+    optional bool wifi_phy_layer_protocol_is_ambiguous = 3;
+
+    // See net::WifiPHYLayerProtocol.
+    enum WifiPHYLayerProtocol {
+      WIFI_PHY_LAYER_PROTOCOL_NONE = 0;
+      WIFI_PHY_LAYER_PROTOCOL_ANCIENT = 1;
+      WIFI_PHY_LAYER_PROTOCOL_A = 2;
+      WIFI_PHY_LAYER_PROTOCOL_B = 3;
+      WIFI_PHY_LAYER_PROTOCOL_G = 4;
+      WIFI_PHY_LAYER_PROTOCOL_N = 5;
+      WIFI_PHY_LAYER_PROTOCOL_UNKNOWN = 6;
+    }
+    // The physical layer mode of the associated wifi access point, if any.
+    optional WifiPHYLayerProtocol wifi_phy_layer_protocol = 4;
+  }
+  optional Network network = 13;
+
+  // Information on the Google Update install that is managing this client.
+  message GoogleUpdate {
+    // Whether the Google Update install is system-level or user-level.
+    optional bool is_system_install = 1;
+
+    // The date at which Google Update last started performing an automatic
+    // update check, in seconds since the Unix epoch.
+    optional int64 last_automatic_start_timestamp = 2;
+
+    // The date at which Google Update last successfully sent an update check
+    // and recieved an intact response from the server, in seconds since the
+    // Unix epoch. (The updates don't need to be successfully installed.)
+    optional int64 last_update_check_timestamp = 3;
+
+    // Describes a product being managed by Google Update. (This can also
+    // describe Google Update itself.)
+    message ProductInfo {
+      // The current version of the product that is installed.
+      optional string version = 1;
+
+      // The date at which Google Update successfully updated this product,
+      // stored in seconds since the Unix epoch.  This is updated when an update
+      // is successfully applied, or if the server reports that no update
+      // is available.
+      optional int64 last_update_success_timestamp = 2;
+
+      // The result reported by the product updater on its last run.
+      enum InstallResult {
+        INSTALL_RESULT_SUCCESS = 0;
+        INSTALL_RESULT_FAILED_CUSTOM_ERROR = 1;
+        INSTALL_RESULT_FAILED_MSI_ERROR = 2;
+        INSTALL_RESULT_FAILED_SYSTEM_ERROR = 3;
+        INSTALL_RESULT_EXIT_CODE = 4;
+      }
+      optional InstallResult last_result = 3;
+
+      // The error code reported by the product updater on its last run.  This
+      // will typically be a error code specific to the product installer.
+      optional int32 last_error = 4;
+
+      // The extra error code reported by the product updater on its last run.
+      // This will typically be a Win32 error code.
+      optional int32 last_extra_error = 5;
+    }
+    optional ProductInfo google_update_status = 4;
+    optional ProductInfo client_status = 5;
+  }
+  optional GoogleUpdate google_update = 11;
+
+  // Information on all installed plugins.
+  message Plugin {
+    // The plugin's self-reported name and filename (without path).
+    optional string name = 1;
+    optional string filename = 2;
+
+    // The plugin's version.
+    optional string version = 3;
+
+    // True if the plugin is disabled.
+    // If a client has multiple local Chrome user accounts, this is logged based
+    // on the first user account launched during the current session.
+    optional bool is_disabled = 4;
+
+    // True if the plugin is PPAPI.
+    optional bool is_pepper = 5;
+  }
+  repeated Plugin plugin = 7;
+
+  // Figures that can be used to generate application stability metrics.
+  // All values are counts of events since the last time that these
+  // values were reported.
+  // Next tag: 24
+  message Stability {
+    // Total amount of time that the program was running, in seconds,
+    // since the last time a log was recorded, as measured using a client-side
+    // clock implemented via TimeTicks, which guarantees that it is monotonic
+    // and does not jump if the user changes his/her clock.  The TimeTicks
+    // implementation also makes the clock not count time the computer is
+    // suspended.
+    optional int64 incremental_uptime_sec = 1;
+
+    // Total amount of time that the program was running, in seconds,
+    // since startup, as measured using a client-side clock implemented
+    // via TimeTicks, which guarantees that it is monotonic and does not
+    // jump if the user changes his/her clock.  The TimeTicks implementation
+    // also makes the clock not count time the computer is suspended.
+    // This field was added for M-35.
+    optional int64 uptime_sec = 23;
+
+    // Page loads along with renderer crashes and hangs, since page load count
+    // roughly corresponds to usage.
+    optional int32 page_load_count = 2;
+    optional int32 renderer_crash_count = 3;
+    optional int32 renderer_hang_count = 4;
+
+    // Number of renderer crashes that were for extensions.
+    // TODO(isherman): Figure out whether this is also counted in
+    // |renderer_crash_count|.
+    optional int32 extension_renderer_crash_count = 5;
+
+    // Number of non-renderer child process crashes.
+    optional int32 child_process_crash_count = 6;
+
+    // Number of times the browser has crashed while logged in as the "other
+    // user" (guest) account.
+    // Logged on ChromeOS only.
+    optional int32 other_user_crash_count = 7;
+
+    // Number of times the kernel has crashed.
+    // Logged on ChromeOS only.
+    optional int32 kernel_crash_count = 8;
+
+    // Number of times the system has shut down uncleanly.
+    // Logged on ChromeOS only.
+    optional int32 unclean_system_shutdown_count = 9;
+
+    //
+    // All the remaining fields in the Stability are recorded at most once per
+    // client session.
+    //
+
+    // The number of times the program was launched.
+    // This will typically be equal to 1.  However, it is possible that Chrome
+    // was unable to upload stability metrics for previous launches (e.g. due to
+    // crashing early during startup), and hence this value might be greater
+    // than 1.
+    optional int32 launch_count = 15;
+    // The number of times that it didn't exit cleanly (which we assume to be
+    // mostly crashes).
+    optional int32 crash_count = 16;
+
+    // The number of times the program began, but did not complete, the shutdown
+    // process.  (For example, this may occur when Windows is shutting down, and
+    // it only gives the process a few seconds to clean up.)
+    optional int32 incomplete_shutdown_count = 17;
+
+    // The number of times the program was able register with breakpad crash
+    // services.
+    optional int32 breakpad_registration_success_count = 18;
+
+    // The number of times the program failed to register with breakpad crash
+    // services.  If crash registration fails then when the program crashes no
+    // crash report will be generated.
+    optional int32 breakpad_registration_failure_count = 19;
+
+    // The number of times the program has run under a debugger.  This should
+    // be an exceptional condition.  Running under a debugger prevents crash
+    // dumps from being generated.
+    optional int32 debugger_present_count = 20;
+
+    // The number of times the program has run without a debugger attached.
+    // This should be most common scenario and should be very close to
+    // |launch_count|.
+    optional int32 debugger_not_present_count = 21;
+
+    // Stability information for all installed plugins.
+    message PluginStability {
+      // The relevant plugin's information (name, etc.)
+      optional Plugin plugin = 1;
+
+      // The number of times this plugin's process was launched.
+      optional int32 launch_count = 2;
+
+      // The number of times this plugin was instantiated on a web page.
+      // This will be >= |launch_count|.
+      // (A page load with multiple sections drawn by this plugin will
+      // increase this count multiple times.)
+      optional int32 instance_count = 3;
+
+      // The number of times this plugin process crashed.
+      // This value will be <= |launch_count|.
+      optional int32 crash_count = 4;
+
+      // The number of times this plugin could not be loaded.
+      optional int32 loading_error_count = 5;
+    }
+    repeated PluginStability plugin_stability = 22;
+  }
+  optional Stability stability = 8;
+
+  // Description of a field trial or experiment that the user is currently
+  // enrolled in.
+  // All metrics reported in this upload can potentially be influenced by the
+  // field trial.
+  message FieldTrial {
+    // The name of the field trial, as a 32-bit identifier.
+    // Currently, the identifier is a hash of the field trial's name.
+    optional fixed32 name_id = 1;
+
+    // The user's group within the field trial, as a 32-bit identifier.
+    // Currently, the identifier is a hash of the group's name.
+    optional fixed32 group_id = 2;
+  }
+  repeated FieldTrial field_trial = 9;
+
+  // Number of users currently signed into a multiprofile session.
+  // A zero value indicates that the user count changed while the log is open.
+  // Logged only on ChromeOS.
+  optional uint32 multi_profile_user_count = 17;
+
+  // Information about extensions that are installed, masked to provide better
+  // privacy.  Only extensions from a single profile are reported; this will
+  // generally be the profile used when the browser is started.  The profile
+  // reported on will remain consistent at least until the browser is
+  // relaunched (or the profile is deleted by the user).
+  //
+  // Each client first picks a value for client_key derived from its UMA
+  // client_id:
+  //   client_key = client_id % 4096
+  // Then, each installed extension is mapped into a hash bucket according to
+  //   bucket = CityHash64(StringPrintf("%d:%s",
+  //                                    client_key, extension_id)) % 1024
+  // The client reports the set of hash buckets occupied by all installed
+  // extensions.  If multiple extensions map to the same bucket, that bucket is
+  // still only reported once.
+  repeated int32 occupied_extension_bucket = 18;
+}
diff --git a/components/metrics/proto/user_action_event.proto b/components/metrics/proto/user_action_event.proto
new file mode 100644
index 0000000..6817dcd
--- /dev/null
+++ b/components/metrics/proto/user_action_event.proto
@@ -0,0 +1,21 @@
+// 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.
+//
+// Stores information about an event that occurs in response to a user action,
+// e.g. an interaction with a browser UI element.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package metrics;
+
+// Next tag: 3
+message UserActionEventProto {
+  // The name of the action, hashed.
+  optional fixed64 name_hash = 1;
+
+  // The timestamp for the event, in seconds since the epoch.
+  optional int64 time = 2;
+}
diff --git a/components/nacl.gyp b/components/nacl.gyp
index c52a1f7..8596924 100644
--- a/components/nacl.gyp
+++ b/components/nacl.gyp
@@ -155,8 +155,12 @@
           'sources': [
             'nacl/renderer/histogram.cc',
             'nacl/renderer/histogram.h',
+            'nacl/renderer/manifest_downloader.cc',
+            'nacl/renderer/manifest_downloader.h',
             'nacl/renderer/manifest_service_channel.cc',
             'nacl/renderer/manifest_service_channel.h',
+            'nacl/renderer/json_manifest.cc',
+            'nacl/renderer/json_manifest.h',
             'nacl/renderer/nexe_load_manager.cc',
             'nacl/renderer/nexe_load_manager.h',
             'nacl/renderer/pnacl_translation_resource_host.cc',
@@ -173,6 +177,7 @@
           ],
           'dependencies': [
             '../content/content.gyp:content_renderer',
+            '../third_party/jsoncpp/jsoncpp.gyp:jsoncpp',
             '../third_party/WebKit/public/blink.gyp:blink',
             '../webkit/common/webkit_common.gyp:webkit_common',
           ],
@@ -199,6 +204,10 @@
           'conditions': [
             ['OS=="linux"', {
               'sources': [
+                # TODO(mazda): Move this to browser_tests once we have
+                # established a way to run browser_tests on ARM Chrome OS
+                # devices (http://crbug.com/364729).
+                'nacl/loader/nonsfi/irt_icache_unittest.cc',
                 # TODO(hamaji): Currently, we build them twice. Stop building
                 # them for components_unittests. See crbug.com/364751
                 'nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc',
@@ -260,11 +269,13 @@
                 'nacl/loader/nonsfi/irt_exception_handling.cc',
                 'nacl/loader/nonsfi/irt_fdio.cc',
                 'nacl/loader/nonsfi/irt_futex.cc',
+                'nacl/loader/nonsfi/irt_icache.cc',
                 'nacl/loader/nonsfi/irt_interfaces.cc',
                 'nacl/loader/nonsfi/irt_interfaces.h',
                 'nacl/loader/nonsfi/irt_memory.cc',
                 'nacl/loader/nonsfi/irt_ppapi.cc',
                 'nacl/loader/nonsfi/irt_random.cc',
+                'nacl/loader/nonsfi/irt_resource_open.cc',
                 'nacl/loader/nonsfi/irt_thread.cc',
                 'nacl/loader/nonsfi/irt_util.h',
                 'nacl/loader/nonsfi/nonsfi_main.cc',
@@ -273,6 +284,7 @@
                 'nacl/loader/nonsfi/nonsfi_sandbox.h',
                 'nacl/loader/sandbox_linux/nacl_bpf_sandbox_linux.cc',
                 'nacl/loader/sandbox_linux/nacl_sandbox_linux.cc',
+                '../ppapi/nacl_irt/irt_manifest.h',
                 '../ppapi/nacl_irt/manifest_service.cc',
                 '../ppapi/nacl_irt/manifest_service.h',
                 '../ppapi/nacl_irt/plugin_main.cc',
@@ -300,8 +312,7 @@
                 }],
                 ['os_posix == 1 and OS != "mac"', {
                   'conditions': [
-                    # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-                    ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+                    ['use_allocator!="none"', {
                       'dependencies': [
                         '../base/allocator/allocator.gyp:allocator',
                       ],
diff --git a/components/nacl/DEPS b/components/nacl/DEPS
new file mode 100644
index 0000000..c3505fa
--- /dev/null
+++ b/components/nacl/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+  "+content/public/common",
+  "+ipc",
+]
diff --git a/components/nacl/browser/nacl_browser.cc b/components/nacl/browser/nacl_browser.cc
index f271af6..84e710f 100644
--- a/components/nacl/browser/nacl_browser.cc
+++ b/components/nacl/browser/nacl_browser.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "base/file_util.h"
+#include "base/files/file_proxy.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/histogram.h"
 #include "base/path_service.h"
@@ -140,7 +141,6 @@
 
 NaClBrowser::NaClBrowser()
     : weak_factory_(this),
-      irt_platform_file_(base::kInvalidPlatformFileValue),
       irt_filepath_(),
       irt_state_(NaClResourceUninitialized),
       validation_cache_file_path_(),
@@ -172,8 +172,6 @@
 }
 
 NaClBrowser::~NaClBrowser() {
-  if (irt_platform_file_ != base::kInvalidPlatformFileValue)
-    base::ClosePlatformFile(irt_platform_file_);
 }
 
 void NaClBrowser::InitIrtFilePath() {
@@ -224,11 +222,11 @@
   return ok_;
 }
 
-base::PlatformFile NaClBrowser::IrtFile() const {
+const base::File& NaClBrowser::IrtFile() const {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   CHECK_EQ(irt_state_, NaClResourceReady);
-  CHECK_NE(irt_platform_file_, base::kInvalidPlatformFileValue);
-  return irt_platform_file_;
+  CHECK(irt_file_.IsValid());
+  return irt_file_;
 }
 
 void NaClBrowser::EnsureAllResourcesAvailable() {
@@ -243,28 +241,27 @@
   if (IsOk() && irt_state_ == NaClResourceUninitialized) {
     irt_state_ = NaClResourceRequested;
     // TODO(ncbray) use blocking pool.
-    if (!base::FileUtilProxy::CreateOrOpen(
-            content::BrowserThread::GetMessageLoopProxyForThread(
-                content::BrowserThread::FILE)
-                .get(),
-            irt_filepath_,
-            base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
-            base::Bind(&NaClBrowser::OnIrtOpened,
-                       weak_factory_.GetWeakPtr()))) {
+    scoped_ptr<base::FileProxy> file_proxy(new base::FileProxy(
+        content::BrowserThread::GetMessageLoopProxyForThread(
+                content::BrowserThread::FILE).get()));
+    base::FileProxy* proxy = file_proxy.get();
+    if (!proxy->CreateOrOpen(irt_filepath_,
+                             base::File::FLAG_OPEN | base::File::FLAG_READ,
+                             base::Bind(&NaClBrowser::OnIrtOpened,
+                                        weak_factory_.GetWeakPtr(),
+                                        Passed(&file_proxy)))) {
       LOG(ERROR) << "Internal error, NaCl disabled.";
       MarkAsFailed();
     }
   }
 }
 
-void NaClBrowser::OnIrtOpened(base::File::Error error_code,
-                              base::PassPlatformFile file,
-                              bool created) {
+void NaClBrowser::OnIrtOpened(scoped_ptr<base::FileProxy> file_proxy,
+                              base::File::Error error_code) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   DCHECK_EQ(irt_state_, NaClResourceRequested);
-  DCHECK(!created);
-  if (error_code == base::File::FILE_OK) {
-    irt_platform_file_ = file.ReleaseValue();
+  if (file_proxy->IsValid()) {
+    irt_file_ = file_proxy->TakeFile();
   } else {
     LOG(ERROR) << "Failed to open NaCl IRT file \""
                << irt_filepath_.LossyDisplayName()
diff --git a/components/nacl/browser/nacl_browser.h b/components/nacl/browser/nacl_browser.h
index 4216733..651e2f8 100644
--- a/components/nacl/browser/nacl_browser.h
+++ b/components/nacl/browser/nacl_browser.h
@@ -10,10 +10,8 @@
 #include "base/bind.h"
 #include "base/containers/mru_cache.h"
 #include "base/files/file.h"
-#include "base/files/file_util_proxy.h"
 #include "base/memory/singleton.h"
 #include "base/memory/weak_ptr.h"
-#include "base/platform_file.h"
 #include "base/time/time.h"
 #include "components/nacl/browser/nacl_browser_delegate.h"
 #include "components/nacl/browser/nacl_validation_cache.h"
@@ -21,6 +19,10 @@
 class URLPattern;
 class GURL;
 
+namespace base {
+class FileProxy;
+}
+
 namespace nacl {
 
 // Open an immutable executable file that can be mmapped.
@@ -56,7 +58,7 @@
   const base::FilePath& GetIrtFilePath();
 
   // IRT file handle, only available when IsReady().
-  base::PlatformFile IrtFile() const;
+  const base::File& IrtFile() const;
 
   // Methods for testing GDB debug stub in browser. If test adds debug stub
   // port listener, Chrome will allocate a currently-unused TCP port number for
@@ -138,8 +140,8 @@
 
   void OpenIrtLibraryFile();
 
-  void OnIrtOpened(base::File::Error error_code,
-                   base::PassPlatformFile file, bool created);
+  void OnIrtOpened(scoped_ptr<base::FileProxy> file_proxy,
+                   base::File::Error error_code);
 
   void InitValidationCacheFilePath();
   void EnsureValidationCacheAvailable();
@@ -158,7 +160,7 @@
   // Singletons get destroyed at shutdown.
   base::WeakPtrFactory<NaClBrowser> weak_factory_;
 
-  base::PlatformFile irt_platform_file_;
+  base::File irt_file_;
   base::FilePath irt_filepath_;
   NaClResourceState irt_state_;
   NaClValidationCache validation_cache_;
diff --git a/components/nacl/browser/nacl_browser_delegate.h b/components/nacl/browser/nacl_browser_delegate.h
index 2cdff83..0e1c655 100644
--- a/components/nacl/browser/nacl_browser_delegate.h
+++ b/components/nacl/browser/nacl_browser_delegate.h
@@ -65,6 +65,7 @@
   // urls checking only the url scheme against kExtensionScheme).
   virtual bool MapUrlToLocalFilePath(const GURL& url,
                                      bool use_blocking_api,
+                                     const base::FilePath& profile_directory,
                                      base::FilePath* file_path) = 0;
   // Set match patterns which will be checked before enabling debug stub.
   virtual void SetDebugPatterns(std::string debug_patterns) = 0;
diff --git a/components/nacl/browser/nacl_file_host.cc b/components/nacl/browser/nacl_file_host.cc
index 2744b8e..0a0f10c 100644
--- a/components/nacl/browser/nacl_file_host.cc
+++ b/components/nacl/browser/nacl_file_host.cc
@@ -117,7 +117,10 @@
 
   base::FilePath file_path;
   if (!nacl::NaClBrowser::GetDelegate()->MapUrlToLocalFilePath(
-          file_url, true /* use_blocking_api */, &file_path)) {
+          file_url,
+          true /* use_blocking_api */,
+          nacl_host_message_filter->profile_directory(),
+          &file_path)) {
     NotifyRendererOfError(nacl_host_message_filter.get(), reply_msg);
     return;
   }
diff --git a/components/nacl/browser/nacl_host_message_filter.cc b/components/nacl/browser/nacl_host_message_filter.cc
index 9389b70..6ff43f5 100644
--- a/components/nacl/browser/nacl_host_message_filter.cc
+++ b/components/nacl/browser/nacl_host_message_filter.cc
@@ -90,7 +90,10 @@
   // because we're running in the I/O thread. Ideally we'd use the other path,
   // which would cover more cases.
   nacl::NaClBrowser::GetDelegate()->MapUrlToLocalFilePath(
-      manifest_url, false /* use_blocking_api */, &manifest_path);
+      manifest_url,
+      false /* use_blocking_api */,
+      profile_directory_,
+      &manifest_path);
   host->Launch(this, reply_msg, manifest_path);
 }
 
diff --git a/components/nacl/browser/nacl_host_message_filter.h b/components/nacl/browser/nacl_host_message_filter.h
index 3dc4b45..0227409 100644
--- a/components/nacl/browser/nacl_host_message_filter.h
+++ b/components/nacl/browser/nacl_host_message_filter.h
@@ -40,6 +40,7 @@
 
   int render_process_id() { return render_process_id_; }
   bool off_the_record() { return off_the_record_; }
+  const base::FilePath& profile_directory() const { return profile_directory_; }
   net::HostResolver* GetHostResolver();
 
  private:
diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc
index dda599b..6ef4986 100644
--- a/components/nacl/browser/nacl_process_host.cc
+++ b/components/nacl/browser/nacl_process_host.cc
@@ -493,7 +493,7 @@
 }
 #endif
 
-// Needed to handle sync messages in OnMessageRecieved.
+// Needed to handle sync messages in OnMessageReceived.
 bool NaClProcessHost::Send(IPC::Message* msg) {
   return process_->Send(msg);
 }
@@ -633,21 +633,33 @@
 
 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
   bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg)
-    IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate,
-                        OnQueryKnownToValidate)
-    IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate,
-                        OnSetKnownToValidate)
-    IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_ResolveFileToken,
-                                    OnResolveFileToken)
+  if (uses_nonsfi_mode_) {
+    // IPC messages relating to NaCl's validation cache must not be exposed
+    // in Non-SFI Mode, otherwise a Non-SFI nexe could use
+    // SetKnownToValidate to create a hole in the SFI sandbox.
+    IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg)
+      IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated,
+                          OnPpapiChannelsCreated)
+      IPC_MESSAGE_UNHANDLED(handled = false)
+    IPC_END_MESSAGE_MAP()
+  } else {
+    IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg)
+      IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate,
+                          OnQueryKnownToValidate)
+      IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate,
+                          OnSetKnownToValidate)
+      IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_ResolveFileToken,
+                                      OnResolveFileToken)
 #if defined(OS_WIN)
-    IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler,
-                                    OnAttachDebugExceptionHandler)
+      IPC_MESSAGE_HANDLER_DELAY_REPLY(
+          NaClProcessMsg_AttachDebugExceptionHandler,
+          OnAttachDebugExceptionHandler)
 #endif
-    IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated,
-                        OnPpapiChannelsCreated)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
+      IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated,
+                          OnPpapiChannelsCreated)
+      IPC_MESSAGE_UNHANDLED(handled = false)
+    IPC_END_MESSAGE_MAP()
+  }
   return handled;
 }
 
@@ -786,16 +798,18 @@
   NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
 
   NaClStartParams params;
-  params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled();
-  params.validation_cache_key = nacl_browser->GetValidationCacheKey();
-  params.version = NaClBrowser::GetDelegate()->GetVersionString();
-  params.enable_exception_handling = enable_exception_handling_;
-  params.enable_debug_stub = enable_debug_stub_ &&
-      NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_);
   // Enable PPAPI proxy channel creation only for renderer processes.
   params.enable_ipc_proxy = enable_ppapi_proxy();
-  params.uses_irt = uses_irt_ && !uses_nonsfi_mode_;
-  params.enable_dyncode_syscalls = enable_dyncode_syscalls_;
+  if (!uses_nonsfi_mode_) {
+    params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled();
+    params.validation_cache_key = nacl_browser->GetValidationCacheKey();
+    params.version = NaClBrowser::GetDelegate()->GetVersionString();
+    params.enable_exception_handling = enable_exception_handling_;
+    params.enable_debug_stub = enable_debug_stub_ &&
+        NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_);
+    params.uses_irt = uses_irt_;
+    params.enable_dyncode_syscalls = enable_dyncode_syscalls_;
+  }
 
   const ChildProcessData& data = process_->GetData();
   if (!ShareHandleToSelLdr(data.handle,
@@ -805,11 +819,13 @@
   }
 
   if (params.uses_irt) {
-    base::PlatformFile irt_file = nacl_browser->IrtFile();
-    CHECK_NE(irt_file, base::kInvalidPlatformFileValue);
+    const base::File& irt_file = nacl_browser->IrtFile();
+    CHECK(irt_file.IsValid());
     // Send over the IRT file handle.  We don't close our own copy!
-    if (!ShareHandleToSelLdr(data.handle, irt_file, false, &params.handles))
+    if (!ShareHandleToSelLdr(data.handle, irt_file.GetPlatformFile(), false,
+                             &params.handles)) {
       return false;
+    }
   }
 
 #if defined(OS_MACOSX)
@@ -942,11 +958,13 @@
 
 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature,
                                              bool* result) {
+  CHECK(!uses_nonsfi_mode_);
   NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
   *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_);
 }
 
 void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) {
+  CHECK(!uses_nonsfi_mode_);
   NaClBrowser::GetInstance()->SetKnownToValidate(
       signature, off_the_record_);
 }
@@ -998,6 +1016,7 @@
   //
   // TODO(ncbray): track behavior with UMA. If entries are getting evicted or
   // bogus keys are getting queried, this would be good to know.
+  CHECK(!uses_nonsfi_mode_);
   base::FilePath file_path;
   if (!NaClBrowser::GetInstance()->GetFilePath(
         file_token_lo, file_token_hi, &file_path)) {
@@ -1029,6 +1048,7 @@
 #if defined(OS_WIN)
 void NaClProcessHost::OnAttachDebugExceptionHandler(const std::string& info,
                                                     IPC::Message* reply_msg) {
+  CHECK(!uses_nonsfi_mode_);
   if (!AttachDebugExceptionHandler(info, reply_msg)) {
     // Send failure message.
     NaClProcessMsg_AttachDebugExceptionHandler::WriteReplyParams(reply_msg,
diff --git a/components/nacl/browser/test_nacl_browser_delegate.cc b/components/nacl/browser/test_nacl_browser_delegate.cc
index e89548f..3c831c2 100644
--- a/components/nacl/browser/test_nacl_browser_delegate.cc
+++ b/components/nacl/browser/test_nacl_browser_delegate.cc
@@ -40,9 +40,11 @@
   return NULL;
 }
 
-bool TestNaClBrowserDelegate::MapUrlToLocalFilePath(const GURL& url,
-                                                    bool use_blocking_api,
-                                                    base::FilePath* file_path) {
+bool TestNaClBrowserDelegate::MapUrlToLocalFilePath(
+    const GURL& url,
+    bool use_blocking_api,
+    const base::FilePath& profile_directory,
+    base::FilePath* file_path) {
   return false;
 }
 
diff --git a/components/nacl/browser/test_nacl_browser_delegate.h b/components/nacl/browser/test_nacl_browser_delegate.h
index 5c58350..8476d4f 100644
--- a/components/nacl/browser/test_nacl_browser_delegate.h
+++ b/components/nacl/browser/test_nacl_browser_delegate.h
@@ -34,6 +34,7 @@
       content::BrowserPpapiHost* ppapi_host) OVERRIDE;
   virtual bool MapUrlToLocalFilePath(const GURL& url,
                                      bool use_blocking_api,
+                                     const base::FilePath& profile_directory,
                                      base::FilePath* file_path) OVERRIDE;
   virtual void SetDebugPatterns(std::string debug_patterns) OVERRIDE;
   virtual bool URLMatchesDebugPatterns(const GURL& manifest_url) OVERRIDE;
diff --git a/components/nacl/common/nacl_types.h b/components/nacl/common/nacl_types.h
index 04a9848..a4759b1 100644
--- a/components/nacl/common/nacl_types.h
+++ b/components/nacl/common/nacl_types.h
@@ -38,9 +38,6 @@
 
 
 // Parameters sent to the NaCl process when we start it.
-//
-// If you change this, you will also need to update the IPC serialization in
-// nacl_messages.h.
 struct NaClStartParams {
   NaClStartParams();
   ~NaClStartParams();
@@ -60,6 +57,9 @@
   bool enable_ipc_proxy;
   bool uses_irt;
   bool enable_dyncode_syscalls;
+  // NOTE: Any new fields added here must also be added to the IPC
+  // serialization in nacl_messages.h and (for POD fields) the constructor
+  // in nacl_types.cc.
 };
 
 // Parameters sent to the browser process to have it launch a NaCl process.
diff --git a/components/nacl/loader/nacl_helper_linux.cc b/components/nacl/loader/nacl_helper_linux.cc
index eaf6204..e170c52 100644
--- a/components/nacl/loader/nacl_helper_linux.cc
+++ b/components/nacl/loader/nacl_helper_linux.cc
@@ -36,6 +36,7 @@
 #include "components/nacl/loader/nacl_listener.h"
 #include "components/nacl/loader/nonsfi/irt_exception_handling.h"
 #include "components/nacl/loader/sandbox_linux/nacl_sandbox_linux.h"
+#include "content/public/common/child_process_sandbox_support_linux.h"
 #include "content/public/common/content_descriptors.h"
 #include "content/public/common/zygote_fork_delegate_linux.h"
 #include "crypto/nss_util.h"
@@ -114,41 +115,24 @@
                          bool uses_nonsfi_mode,
                          nacl::NaClSandbox* nacl_sandbox,
                          const std::string& channel_id) {
-  bool validack = false;
-  base::ProcessId real_pid;
-  // Wait until the parent process has discovered our PID.  We
-  // should not fork any child processes (which the seccomp
-  // sandbox does) until then, because that can interfere with the
-  // parent's discovery of our PID.
-  const ssize_t nread = HANDLE_EINTR(
-      read(child_fds[content::ZygoteForkDelegate::kParentFDIndex]->get(),
-           &real_pid,
-           sizeof(real_pid)));
-  if (static_cast<size_t>(nread) == sizeof(real_pid)) {
-    // Make sure the parent didn't accidentally send us our real PID.
-    // We don't want it to be discoverable anywhere in our address space
-    // when we start running untrusted code.
-    CHECK(real_pid == 0);
+  DCHECK(child_fds.size() >
+         std::max(content::ZygoteForkDelegate::kPIDOracleFDIndex,
+                  content::ZygoteForkDelegate::kBrowserFDIndex));
 
-    CommandLine::ForCurrentProcess()->AppendSwitchASCII(
-        switches::kProcessChannelID, channel_id);
-    validack = true;
-  } else {
-    if (nread < 0)
-      perror("read");
-    LOG(ERROR) << "read returned " << nread;
-  }
+  // Ping the PID oracle socket.
+  CHECK(content::SendZygoteChildPing(
+      child_fds[content::ZygoteForkDelegate::kPIDOracleFDIndex]->get()));
 
+  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+      switches::kProcessChannelID, channel_id);
+
+  // Save the browser socket and close the rest.
   base::ScopedFD browser_fd(
       child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]->Pass());
   child_fds.clear();
 
-  if (validack) {
-    BecomeNaClLoader(
-        browser_fd.Pass(), system_info, uses_nonsfi_mode, nacl_sandbox);
-  } else {
-    LOG(ERROR) << "Failed to synch with zygote";
-  }
+  BecomeNaClLoader(
+      browser_fd.Pass(), system_info, uses_nonsfi_mode, nacl_sandbox);
   _exit(1);
 }
 
diff --git a/components/nacl/loader/nacl_listener.cc b/components/nacl/loader/nacl_listener.cc
index f49e3f3..e7b8f4c 100644
--- a/components/nacl/loader/nacl_listener.cc
+++ b/components/nacl/loader/nacl_listener.cc
@@ -375,10 +375,16 @@
 
 #if defined(OS_LINUX)
   if (uses_nonsfi_mode_) {
-    if (params.uses_irt) {
-      LOG(ERROR) << "IRT must not be used for non-SFI NaCl.";
-      return;
-    }
+    // Ensure that the validation cache key (used as an extra input to the
+    // validation cache's hashing) isn't exposed accidentally.
+    CHECK(!params.validation_cache_enabled);
+    CHECK(params.validation_cache_key.size() == 0);
+    CHECK(params.version.size() == 0);
+    // Ensure that a debug stub FD isn't passed through accidentally.
+    CHECK(!params.enable_debug_stub);
+    CHECK(params.debug_stub_server_bound_socket.fd == -1);
+
+    CHECK(!params.uses_irt);
     CHECK(handles.size() == 1);
     int imc_bootstrap_handle = nacl::ToNativeHandle(handles[0]);
     nacl::nonsfi::MainStart(imc_bootstrap_handle);
diff --git a/components/nacl/loader/nonsfi/irt_icache.cc b/components/nacl/loader/nonsfi/irt_icache.cc
new file mode 100644
index 0000000..49a70b3
--- /dev/null
+++ b/components/nacl/loader/nonsfi/irt_icache.cc
@@ -0,0 +1,40 @@
+// 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.
+
+#if defined(__arm__)  // nacl_irt_icache is supported only on ARM.
+
+#include <errno.h>
+#include <sys/syscall.h>
+#include <stddef.h>
+
+#include "components/nacl/loader/nonsfi/irt_interfaces.h"
+
+namespace nacl {
+namespace nonsfi {
+
+namespace {
+
+// TODO(mazda): Revisit the implementation to consider inlining the syscall
+// with assembly when Non-SFI mode's IRT implementations get moved to the
+// NaCl repository.
+int IrtClearCache(void* addr, size_t size) {
+  // The third argument of cacheflush is just ignored for now and should
+  // always be zero.
+  int result = syscall(__ARM_NR_cacheflush,
+                       addr, reinterpret_cast<intptr_t>(addr) + size, 0);
+  if (result < 0)
+    return errno;
+  return 0;
+}
+
+}  // namespace
+
+const nacl_irt_icache kIrtIcache = {
+  IrtClearCache
+};
+
+}  // namespace nonsfi
+}  // namespace nacl
+
+#endif
diff --git a/components/nacl/loader/nonsfi/irt_icache_unittest.cc b/components/nacl/loader/nonsfi/irt_icache_unittest.cc
new file mode 100644
index 0000000..5acdadf
--- /dev/null
+++ b/components/nacl/loader/nonsfi/irt_icache_unittest.cc
@@ -0,0 +1,57 @@
+// 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.
+
+#if defined(__arm__)  // nacl_irt_icache is supported only on ARM.
+
+#include <errno.h>
+#include <sys/mman.h>
+
+#include "components/nacl/loader/nonsfi/irt_interfaces.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(NaClIrtIcacheTest, ClearCache) {
+  int (*irt_clear_cache)(void*, size_t) =
+      nacl::nonsfi::kIrtIcache.clear_cache;
+  // Create code for a function to return 0x01.
+  static const uint32_t code_template[] = {
+    0xe3000001,  // movw r0, #0x1
+    0xe12fff1e,  // bx lr
+  };
+  void* start =
+      mmap(NULL, sizeof(code_template), PROT_READ | PROT_WRITE | PROT_EXEC,
+           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  EXPECT_NE(MAP_FAILED, start);
+  memcpy(start, code_template, sizeof(code_template));
+  size_t size = sizeof(code_template);
+  EXPECT_EQ(0, irt_clear_cache(start, size));
+  typedef int (*TestFunc)(void);
+  TestFunc func = reinterpret_cast<TestFunc>(start);
+  EXPECT_EQ(0x1, func());
+  // Modify the function to return 0x11.
+  *reinterpret_cast<uint32_t*>(start) = 0xe3000011;  // movw r0, #0x11
+  // In most cases 0x1 is still returned because the cached code is executed
+  // although the CPU is not obliged to do so.
+  // Uncomment the following line to see if the cached code is executed.
+  // EXPECT_EQ(0x1, func());
+  EXPECT_EQ(0, irt_clear_cache(start, size));
+  // Now it is ensured that 0x11 is returned because I-cache was invalidated
+  // and updated with the new code.
+  EXPECT_EQ(0x11, func());
+  EXPECT_EQ(0, munmap(start, sizeof(code_template)));
+}
+
+TEST(NaClIrtIcacheTest, ClearCacheInvalidArg) {
+  int (*irt_clear_cache)(void*, size_t) =
+      nacl::nonsfi::kIrtIcache.clear_cache;
+  const size_t mem_size = 256;
+  void* start =
+      mmap(NULL, mem_size, PROT_READ | PROT_WRITE | PROT_EXEC,
+           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  EXPECT_EQ(0, irt_clear_cache(start, mem_size));
+  EXPECT_EQ(EINVAL, irt_clear_cache(start, 0));
+  EXPECT_EQ(EINVAL, irt_clear_cache(NULL, mem_size));
+  EXPECT_EQ(0, munmap(start, mem_size));
+}
+
+#endif
diff --git a/components/nacl/loader/nonsfi/irt_interfaces.cc b/components/nacl/loader/nonsfi/irt_interfaces.cc
index 79bb8f5..41582d6 100644
--- a/components/nacl/loader/nonsfi/irt_interfaces.cc
+++ b/components/nacl/loader/nonsfi/irt_interfaces.cc
@@ -23,15 +23,19 @@
 #define NACL_INTERFACE_TABLE(name, value) { name, &value, sizeof(value) }
 const NaClInterfaceTable kIrtInterfaces[] = {
   NACL_INTERFACE_TABLE(NACL_IRT_BASIC_v0_1, kIrtBasic),
-  NACL_INTERFACE_TABLE(NACL_IRT_DEV_FDIO_v0_1, kIrtFdIO),
+  NACL_INTERFACE_TABLE(NACL_IRT_FDIO_v0_1, kIrtFdIO),
   NACL_INTERFACE_TABLE(NACL_IRT_MEMORY_v0_3, kIrtMemory),
   NACL_INTERFACE_TABLE(NACL_IRT_THREAD_v0_1, kIrtThread),
   NACL_INTERFACE_TABLE(NACL_IRT_FUTEX_v0_1, kIrtFutex),
   NACL_INTERFACE_TABLE(NACL_IRT_TLS_v0_1, kIrtTls),
   NACL_INTERFACE_TABLE(NACL_IRT_CLOCK_v0_1, kIrtClock),
   NACL_INTERFACE_TABLE(NACL_IRT_PPAPIHOOK_v0_1, kIrtPpapiHook),
+  NACL_INTERFACE_TABLE(NACL_IRT_RESOURCE_OPEN_v0_1, kIrtResourceOpen),
   NACL_INTERFACE_TABLE(NACL_IRT_RANDOM_v0_1, kIrtRandom),
   NACL_INTERFACE_TABLE(NACL_IRT_EXCEPTION_HANDLING_v0_1, kIrtExceptionHandling),
+#if defined(__arm__)
+  NACL_INTERFACE_TABLE(NACL_IRT_ICACHE_v0_1, kIrtIcache),
+#endif
 };
 #undef NACL_INTERFACE_TABLE
 
diff --git a/components/nacl/loader/nonsfi/irt_interfaces.h b/components/nacl/loader/nonsfi/irt_interfaces.h
index 6d723e6..1ec75d3 100644
--- a/components/nacl/loader/nonsfi/irt_interfaces.h
+++ b/components/nacl/loader/nonsfi/irt_interfaces.h
@@ -7,6 +7,7 @@
 
 #include "base/basictypes.h"
 #include "native_client/src/untrusted/irt/irt.h"
+#include "ppapi/nacl_irt/public/irt_nonsfi.h"
 #include "ppapi/nacl_irt/public/irt_ppapi.h"
 
 namespace nacl {
@@ -23,8 +24,10 @@
 extern const struct nacl_irt_tls kIrtTls;
 extern const struct nacl_irt_clock kIrtClock;
 extern const struct nacl_irt_ppapihook kIrtPpapiHook;
+extern const struct nacl_irt_resource_open kIrtResourceOpen;
 extern const struct nacl_irt_random kIrtRandom;
 extern const struct nacl_irt_exception_handling kIrtExceptionHandling;
+extern const struct nacl_irt_icache kIrtIcache;
 
 }  // namespace nonsfi
 }  // namespace nacl
diff --git a/components/nacl/loader/nonsfi/irt_resource_open.cc b/components/nacl/loader/nonsfi/irt_resource_open.cc
new file mode 100644
index 0000000..cf193c1
--- /dev/null
+++ b/components/nacl/loader/nonsfi/irt_resource_open.cc
@@ -0,0 +1,16 @@
+// 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.
+
+#include "components/nacl/loader/nonsfi/irt_interfaces.h"
+#include "ppapi/nacl_irt/irt_manifest.h"
+
+namespace nacl {
+namespace nonsfi {
+
+const nacl_irt_resource_open kIrtResourceOpen = {
+  ppapi::IrtOpenResource,
+};
+
+}  // namespace nonsfi
+}  // namespace nacl
diff --git a/components/nacl/loader/nonsfi/nonsfi_sandbox.cc b/components/nacl/loader/nonsfi/nonsfi_sandbox.cc
index 7f56ce3..0e4550c 100644
--- a/components/nacl/loader/nonsfi/nonsfi_sandbox.cc
+++ b/components/nacl/loader/nonsfi/nonsfi_sandbox.cc
@@ -203,13 +203,8 @@
 
 }  // namespace
 
-ErrorCode NaClNonSfiBPFSandboxPolicy::EvaluateSyscall(
-    SandboxBPF* sb, int sysno) const {
-  return EvaluateSyscallImpl(sb, sysno, NULL);
-}
-
-ErrorCode NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl(
-    SandboxBPF* sb, int sysno, void*) {
+ErrorCode NaClNonSfiBPFSandboxPolicy::EvaluateSyscall(SandboxBPF* sb,
+                                                      int sysno) const {
   switch (sysno) {
     // Allowed syscalls.
 #if defined(__i386__) || defined(__arm__)
diff --git a/components/nacl/loader/nonsfi/nonsfi_sandbox.h b/components/nacl/loader/nonsfi/nonsfi_sandbox.h
index 28e9cff..6ff0d41 100644
--- a/components/nacl/loader/nonsfi/nonsfi_sandbox.h
+++ b/components/nacl/loader/nonsfi/nonsfi_sandbox.h
@@ -22,9 +22,6 @@
   virtual sandbox::ErrorCode EvaluateSyscall(sandbox::SandboxBPF* sb,
                                              int sysno) const OVERRIDE;
 
-  static sandbox::ErrorCode EvaluateSyscallImpl(sandbox::SandboxBPF* sb,
-                                                int sysno, void*);
-
  private:
   DISALLOW_COPY_AND_ASSIGN(NaClNonSfiBPFSandboxPolicy);
 };
diff --git a/components/nacl/loader/nonsfi/nonsfi_sandbox_sigsys_unittest.cc b/components/nacl/loader/nonsfi/nonsfi_sandbox_sigsys_unittest.cc
index 0fe62bd..37dc599 100644
--- a/components/nacl/loader/nonsfi/nonsfi_sandbox_sigsys_unittest.cc
+++ b/components/nacl/loader/nonsfi/nonsfi_sandbox_sigsys_unittest.cc
@@ -17,12 +17,12 @@
 // are appropriately disallowed. They should raise SIGSYS regardless
 // of arguments. We always pass five zeros not to pass uninitialized
 // values to syscalls.
-#define RESTRICT_SYSCALL_DEATH_TEST_IMPL(name, sysno)                   \
-  BPF_DEATH_TEST(                                                       \
-      NaClNonSfiSandboxSIGSYSTest, name,                                \
-      DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),         \
-      nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {  \
-    syscall(sysno, 0, 0, 0, 0, 0, 0);                                   \
+#define RESTRICT_SYSCALL_DEATH_TEST_IMPL(name, sysno)                        \
+  BPF_DEATH_TEST_C(NaClNonSfiSandboxSIGSYSTest,                              \
+                   name,                                                     \
+                   DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), \
+                   nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {               \
+    syscall(sysno, 0, 0, 0, 0, 0, 0);                                        \
   }
 
 #define RESTRICT_SYSCALL_DEATH_TEST(name)               \
diff --git a/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc b/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc
index a5229ba..5e61d8f 100644
--- a/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc
+++ b/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc
@@ -64,9 +64,10 @@
   }
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, invalid_sysno,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 invalid_sysno,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   syscall(999);
 }
 
@@ -79,8 +80,9 @@
 
 // To make this test pass, we need to allow sched_getaffinity and
 // mmap. We just disable this test not to complicate the sandbox.
-BPF_TEST(NaClNonSfiSandboxTest, clone_by_pthread_create,
-         nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_TEST_C(NaClNonSfiSandboxTest,
+           clone_by_pthread_create,
+           nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   // clone call for thread creation is allowed.
   pthread_t th;
   int test_val = 42;
@@ -108,27 +110,31 @@
 }
 
 // Then, try this in the sandbox.
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, clone_for_fork,
-               DEATH_MESSAGE(sandbox::GetCloneErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 clone_for_fork,
+                 DEATH_MESSAGE(sandbox::GetCloneErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   DoFork();
 }
 
-BPF_TEST(NaClNonSfiSandboxTest, prctl_SET_NAME,
-         nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_TEST_C(NaClNonSfiSandboxTest,
+           prctl_SET_NAME,
+           nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   errno = 0;
   BPF_ASSERT_EQ(-1, syscall(__NR_prctl, PR_SET_NAME, "foo"));
   BPF_ASSERT_EQ(EPERM, errno);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, prctl_SET_DUMPABLE,
-               DEATH_MESSAGE(sandbox::GetPrctlErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 prctl_SET_DUMPABLE,
+                 DEATH_MESSAGE(sandbox::GetPrctlErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   syscall(__NR_prctl, PR_SET_DUMPABLE, 1UL);
 }
 
-BPF_TEST(NaClNonSfiSandboxTest, socketcall_allowed,
-         nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_TEST_C(NaClNonSfiSandboxTest,
+           socketcall_allowed,
+           nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   base::ScopedFD fds[2];
   struct msghdr msg = {};
   struct iovec iov;
@@ -145,112 +151,129 @@
   BPF_ASSERT_EQ(0, shutdown(fds[0].get(), SHUT_RDWR));
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, accept,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 accept,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   accept(0, NULL, NULL);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, bind,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 bind,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   bind(0, NULL, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, connect,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 connect,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   connect(0, NULL, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, getpeername,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 getpeername,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   getpeername(0, NULL, NULL);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, getsockname,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 getsockname,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   struct sockaddr addr;
   socklen_t addrlen = 0;
   getsockname(0, &addr, &addrlen);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, getsockopt,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 getsockopt,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   getsockopt(0, 0, 0, NULL, NULL);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, listen,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 listen,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   listen(0, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, recv,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 recv,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   recv(0, NULL, 0, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, recvfrom,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 recvfrom,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   recvfrom(0, NULL, 0, 0, NULL, NULL);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, send,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 send,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   send(0, NULL, 0, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, sendto,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 sendto,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   sendto(0, NULL, 0, 0, NULL, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, setsockopt,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 setsockopt,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   setsockopt(0, 0, 0, NULL, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, socket,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 socket,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   socket(0, 0, 0);
 }
 
 #if defined(__x86_64__) || defined(__arm__)
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, socketpair,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 socketpair,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   int fds[2];
   socketpair(AF_INET, SOCK_STREAM, 0, fds);
 }
 #endif
 
-BPF_TEST(NaClNonSfiSandboxTest, fcntl_SETFD_allowed,
-         nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_TEST_C(NaClNonSfiSandboxTest,
+           fcntl_SETFD_allowed,
+           nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   base::ScopedFD fds[2];
   DoSocketpair(fds);
   BPF_ASSERT_EQ(0, fcntl(fds[0].get(), F_SETFD, FD_CLOEXEC));
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, fcntl_SETFD,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 fcntl_SETFD,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   base::ScopedFD fds[2];
   DoSocketpair(fds);
   fcntl(fds[0].get(), F_SETFD, 99);
 }
 
-BPF_TEST(NaClNonSfiSandboxTest, fcntl_GETFL_SETFL_allowed,
-         nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_TEST_C(NaClNonSfiSandboxTest,
+           fcntl_GETFL_SETFL_allowed,
+           nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   base::ScopedFD fds[2];
   DoPipe(fds);
   const int fd = fds[0].get();
@@ -259,23 +282,26 @@
   BPF_ASSERT_EQ(O_NONBLOCK, fcntl(fd, F_GETFL));
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, fcntl_GETFL_SETFL,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 fcntl_GETFL_SETFL,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   base::ScopedFD fds[2];
   DoSocketpair(fds);
   fcntl(fds[0].get(), F_SETFL, O_APPEND);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, fcntl_DUPFD,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 fcntl_DUPFD,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   fcntl(0, F_DUPFD);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, fcntl_DUPFD_CLOEXEC,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 fcntl_DUPFD_CLOEXEC,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   fcntl(0, F_DUPFD_CLOEXEC);
 }
 
@@ -284,63 +310,72 @@
               MAP_ANONYMOUS | MAP_SHARED, -1, 0);
 }
 
-BPF_TEST(NaClNonSfiSandboxTest, mmap_allowed,
-         nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_TEST_C(NaClNonSfiSandboxTest,
+           mmap_allowed,
+           nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   void* ptr = DoAllowedAnonymousMmap();
   BPF_ASSERT_NE(MAP_FAILED, ptr);
   BPF_ASSERT_EQ(0, munmap(ptr, getpagesize()));
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, mmap_unallowed_flag,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 mmap_unallowed_flag,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE,
        MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, mmap_unallowed_prot,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 mmap_unallowed_prot,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   mmap(NULL, getpagesize(), PROT_READ | PROT_GROWSDOWN,
        MAP_ANONYMOUS, -1, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, mmap_exec,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 mmap_exec,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   mmap(NULL, getpagesize(), PROT_EXEC, MAP_ANONYMOUS, -1, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, mmap_read_exec,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 mmap_read_exec,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   mmap(NULL, getpagesize(), PROT_READ | PROT_EXEC, MAP_ANONYMOUS, -1, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, mmap_write_exec,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 mmap_write_exec,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   mmap(NULL, getpagesize(), PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS, -1, 0);
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, mmap_read_write_exec,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 mmap_read_write_exec,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC,
        MAP_ANONYMOUS, -1, 0);
 }
 
-BPF_TEST(NaClNonSfiSandboxTest, mprotect_allowed,
-         nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_TEST_C(NaClNonSfiSandboxTest,
+           mprotect_allowed,
+           nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   void* ptr = DoAllowedAnonymousMmap();
   BPF_ASSERT_NE(MAP_FAILED, ptr);
   BPF_ASSERT_EQ(0, mprotect(ptr, getpagesize(), PROT_READ));
   BPF_ASSERT_EQ(0, munmap(ptr, getpagesize()));
 }
 
-BPF_DEATH_TEST(NaClNonSfiSandboxTest, mprotect_unallowed_prot,
-               DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
-               nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_DEATH_TEST_C(NaClNonSfiSandboxTest,
+                 mprotect_unallowed_prot,
+                 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()),
+                 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   // We have tested DoAllowedAnonymousMmap is allowed in
   // mmap_allowed, so we can make sure the following mprotect call
   // kills the process.
@@ -349,8 +384,9 @@
   mprotect(ptr, getpagesize(), PROT_READ | PROT_GROWSDOWN);
 }
 
-BPF_TEST(NaClNonSfiSandboxTest, brk,
-         nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {
+BPF_TEST_C(NaClNonSfiSandboxTest,
+           brk,
+           nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {
   char* next_brk = static_cast<char*>(sbrk(0)) + getpagesize();
   // The kernel interface must return zero for brk.
   BPF_ASSERT_EQ(0, syscall(__NR_brk, next_brk));
@@ -362,13 +398,13 @@
 
 // The following test cases check if syscalls return EPERM regardless
 // of arguments.
-#define RESTRICT_SYSCALL_EPERM_TEST(name)                               \
-  BPF_TEST(                                                             \
-      NaClNonSfiSandboxTest, name ## _EPERM,                            \
-      nacl::nonsfi::NaClNonSfiBPFSandboxPolicy::EvaluateSyscallImpl) {  \
-    errno = 0;                                                          \
-    BPF_ASSERT_EQ(-1, syscall(__NR_ ## name, 0, 0, 0, 0, 0, 0));        \
-    BPF_ASSERT_EQ(EPERM, errno);                                        \
+#define RESTRICT_SYSCALL_EPERM_TEST(name)                      \
+  BPF_TEST_C(NaClNonSfiSandboxTest,                            \
+             name##_EPERM,                                     \
+             nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) {       \
+    errno = 0;                                                 \
+    BPF_ASSERT_EQ(-1, syscall(__NR_##name, 0, 0, 0, 0, 0, 0)); \
+    BPF_ASSERT_EQ(EPERM, errno);                               \
   }
 
 RESTRICT_SYSCALL_EPERM_TEST(epoll_create);
diff --git a/components/nacl/loader/sandbox_linux/nacl_bpf_sandbox_linux.cc b/components/nacl/loader/sandbox_linux/nacl_bpf_sandbox_linux.cc
index e123523..7626bf2 100644
--- a/components/nacl/loader/sandbox_linux/nacl_bpf_sandbox_linux.cc
+++ b/components/nacl/loader/sandbox_linux/nacl_bpf_sandbox_linux.cc
@@ -95,7 +95,7 @@
     // NaCl uses custom signal stacks.
     case __NR_sigaltstack:
     // Below is fairly similar to the policy for a Chromium renderer.
-    // TODO(jln): restrict clone(), ioctl() and prctl().
+    // TODO(jln): restrict ioctl() and prctl().
     case __NR_ioctl:
 #if defined(__i386__) || defined(__x86_64__)
     case __NR_getrlimit:
diff --git a/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc b/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc
index 1bf329d..2c92021 100644
--- a/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc
+++ b/components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc
@@ -74,13 +74,11 @@
   CHECK(!IsSandboxed()) << "Unexpectedly sandboxed!";
   scoped_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client(
       sandbox::SetuidSandboxClient::Create());
-  // Close the file descriptor that is an artefact of how the setuid sandbox
-  // works.
-  PCHECK(0 == IGNORE_EINTR(close(
-                  setuid_sandbox_client->GetUniqueToChildFileDescriptor())));
   const bool suid_sandbox_child = setuid_sandbox_client->IsSuidSandboxChild();
 
   if (suid_sandbox_child) {
+    setuid_sandbox_client->CloseDummyFile();
+
     // Make sure that no directory file descriptor is open, as it would bypass
     // the setuid sandbox model.
     CHECK(!HasOpenDirectory());
diff --git a/components/nacl/renderer/DEPS b/components/nacl/renderer/DEPS
index 4b95d5a..d7b9c93 100644
--- a/components/nacl/renderer/DEPS
+++ b/components/nacl/renderer/DEPS
@@ -11,5 +11,7 @@
   "+ppapi/thunk",
 
   "+v8/include",
+  "+third_party/jsoncpp/source/include/json",
+  "+third_party/WebKit/public/platform",
   "+third_party/WebKit/public/web",
 ]
diff --git a/components/nacl/renderer/histogram.cc b/components/nacl/renderer/histogram.cc
index 035428e..7916f00 100644
--- a/components/nacl/renderer/histogram.cc
+++ b/components/nacl/renderer/histogram.cc
@@ -88,6 +88,8 @@
 // These constants MUST match those in
 // ppapi/native_client/src/trusted/plugin/plugin.cc
 void HistogramTimeSmall(const std::string& name, int64_t sample) {
+  if (sample < 0)
+    sample = 0;
   base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
       name,
       base::TimeDelta::FromMilliseconds(1),
@@ -102,6 +104,8 @@
 // These constants MUST match those in
 // ppapi/native_client/src/trusted/plugin/plugin.cc
 void HistogramTimeMedium(const std::string& name, int64_t sample) {
+  if (sample < 0)
+    sample = 0;
   base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
       name,
       base::TimeDelta::FromMilliseconds(10),
@@ -116,6 +120,8 @@
 // These constants MUST match those in
 // ppapi/native_client/src/trusted/plugin/plugin.cc
 void HistogramTimeLarge(const std::string& name, int64_t sample) {
+  if (sample < 0)
+    sample = 0;
   base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
       name,
       base::TimeDelta::FromMilliseconds(100),
diff --git a/components/nacl/renderer/json_manifest.cc b/components/nacl/renderer/json_manifest.cc
new file mode 100644
index 0000000..8459f1f
--- /dev/null
+++ b/components/nacl/renderer/json_manifest.cc
@@ -0,0 +1,654 @@
+// 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.
+
+#include "components/nacl/renderer/json_manifest.h"
+
+#include <set>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "components/nacl/renderer/nexe_load_manager.h"
+#include "third_party/jsoncpp/source/include/json/reader.h"
+#include "third_party/jsoncpp/source/include/json/value.h"
+#include "url/gurl.h"
+
+namespace nacl {
+
+namespace {
+// Top-level section name keys
+const char* const kProgramKey =     "program";
+const char* const kInterpreterKey = "interpreter";
+const char* const kFilesKey =       "files";
+
+// ISA Dictionary keys
+const char* const kX8632Key =       "x86-32";
+const char* const kX8632NonSFIKey = "x86-32-nonsfi";
+const char* const kX8664Key =       "x86-64";
+const char* const kX8664NonSFIKey = "x86-64-nonsfi";
+const char* const kArmKey =         "arm";
+const char* const kArmNonSFIKey =   "arm-nonsfi";
+const char* const kPortableKey =    "portable";
+
+// Url Resolution keys
+const char* const kPnaclDebugKey =     "pnacl-debug";
+const char* const kPnaclTranslateKey = "pnacl-translate";
+const char* const kUrlKey =            "url";
+
+// PNaCl keys
+const char* const kOptLevelKey = "optlevel";
+
+// Sample NaCl manifest file:
+// {
+//   "program": {
+//     "x86-32": {"url": "myprogram_x86-32.nexe"},
+//     "x86-64": {"url": "myprogram_x86-64.nexe"},
+//     "arm": {"url": "myprogram_arm.nexe"}
+//   },
+//   "interpreter": {
+//     "x86-32": {"url": "interpreter_x86-32.nexe"},
+//     "x86-64": {"url": "interpreter_x86-64.nexe"},
+//     "arm": {"url": "interpreter_arm.nexe"}
+//   },
+//   "files": {
+//     "foo.txt": {
+//       "portable": {"url": "foo.txt"}
+//     },
+//     "bar.txt": {
+//       "x86-32": {"url": "x86-32/bar.txt"},
+//       "portable": {"url": "bar.txt"}
+//     },
+//     "libfoo.so": {
+//       "x86-64" : { "url": "..." }
+//     }
+//   }
+// }
+
+// Sample PNaCl manifest file:
+// {
+//   "program": {
+//     "portable": {
+//       "pnacl-translate": {
+//         "url": "myprogram.pexe"
+//       },
+//       "pnacl-debug": {
+//         "url": "myprogram.debug.pexe",
+//         "opt_level": 0
+//       }
+//     }
+//   },
+//   "files": {
+//     "foo.txt": {
+//       "portable": {"url": "foo.txt"}
+//     },
+//     "bar.txt": {
+//       "portable": {"url": "bar.txt"}
+//     }
+//   }
+// }
+
+// Returns the key for the architecture in non-SFI mode.
+std::string GetNonSFIKey(const std::string& sandbox_isa) {
+  return sandbox_isa + "-nonsfi";
+}
+
+// Looks up |property_name| in the vector |valid_names| with length
+// |valid_name_count|.  Returns true if |property_name| is found.
+bool FindMatchingProperty(const std::string& property_name,
+                          const char** valid_names,
+                          size_t valid_name_count) {
+  for (size_t i = 0; i < valid_name_count; ++i) {
+    if (property_name == valid_names[i]) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Return true if this is a valid dictionary.  Having only keys present in
+// |valid_keys| and having at least the keys in |required_keys|.
+// Error messages will be placed in |error_string|, given that the dictionary
+// was the property value of |container_key|.
+// E.g., "container_key" : dictionary
+bool IsValidDictionary(const Json::Value& dictionary,
+                       const std::string& container_key,
+                       const std::string& parent_key,
+                       const char** valid_keys,
+                       size_t valid_key_count,
+                       const char** required_keys,
+                       size_t required_key_count,
+                       std::string* error_string) {
+  if (!dictionary.isObject()) {
+    std::stringstream error_stream;
+    error_stream << parent_key << " property '" << container_key
+                 << "' is non-dictionary value '"
+                 << dictionary.toStyledString() << "'.";
+    *error_string = error_stream.str();
+    return false;
+  }
+  // Check for unknown dictionary members.
+  Json::Value::Members members = dictionary.getMemberNames();
+  for (size_t i = 0; i < members.size(); ++i) {
+    std::string property_name = members[i];
+    if (!FindMatchingProperty(property_name,
+                              valid_keys,
+                              valid_key_count)) {
+      // For forward compatibility, we do not prohibit other keys being in
+      // the dictionary.
+      VLOG(1) << "WARNING: '" << parent_key << "' property '"
+              << container_key << "' has unknown key '"
+              << property_name << "'.";
+    }
+  }
+  // Check for required members.
+  for (size_t i = 0; i < required_key_count; ++i) {
+    if (!dictionary.isMember(required_keys[i])) {
+      std::stringstream error_stream;
+      error_stream << parent_key << " property '" << container_key
+                   << "' does not have required key: '"
+                   << required_keys[i] << "'.";
+      *error_string = error_stream.str();
+      return false;
+    }
+  }
+  return true;
+}
+
+// Validate a "url" dictionary assuming it was resolved from container_key.
+// E.g., "container_key" : { "url": "foo.txt" }
+bool IsValidUrlSpec(const Json::Value& url_spec,
+                    const std::string& container_key,
+                    const std::string& parent_key,
+                    const std::string& sandbox_isa,
+                    std::string* error_string) {
+  static const char* kManifestUrlSpecRequired[] = {
+    kUrlKey
+  };
+  const char** urlSpecPlusOptional;
+  size_t urlSpecPlusOptionalLength;
+  if (sandbox_isa == kPortableKey) {
+    static const char* kPnaclUrlSpecPlusOptional[] = {
+      kUrlKey,
+      kOptLevelKey,
+    };
+    urlSpecPlusOptional = kPnaclUrlSpecPlusOptional;
+    urlSpecPlusOptionalLength = arraysize(kPnaclUrlSpecPlusOptional);
+  } else {
+    // URL specifications must not contain "pnacl-translate" keys.
+    // This prohibits NaCl clients from invoking PNaCl.
+    if (url_spec.isMember(kPnaclTranslateKey)) {
+      std::stringstream error_stream;
+      error_stream << "PNaCl-like NMF with application/x-nacl mimetype instead "
+                   << "of x-pnacl mimetype (has " << kPnaclTranslateKey << ").";
+      *error_string = error_stream.str();
+      return false;
+    }
+    urlSpecPlusOptional = kManifestUrlSpecRequired;
+    urlSpecPlusOptionalLength = arraysize(kManifestUrlSpecRequired);
+  }
+  if (!IsValidDictionary(url_spec, container_key, parent_key,
+                         urlSpecPlusOptional,
+                         urlSpecPlusOptionalLength,
+                         kManifestUrlSpecRequired,
+                         arraysize(kManifestUrlSpecRequired),
+                         error_string)) {
+    return false;
+  }
+  // Verify the correct types of the fields if they exist.
+  Json::Value url = url_spec[kUrlKey];
+  if (!url.isString()) {
+    std::stringstream error_stream;
+    error_stream << parent_key << " property '" << container_key <<
+        "' has non-string value '" << url.toStyledString() <<
+        "' for key '" << kUrlKey << "'.";
+    *error_string = error_stream.str();
+    return false;
+  }
+  Json::Value opt_level = url_spec[kOptLevelKey];
+  if (!opt_level.empty() && !opt_level.isNumeric()) {
+    std::stringstream error_stream;
+    error_stream << parent_key << " property '" << container_key <<
+        "' has non-numeric value '" << opt_level.toStyledString() <<
+        "' for key '" << kOptLevelKey << "'.";
+    *error_string = error_stream.str();
+    return false;
+  }
+  return true;
+}
+
+// Validate a "pnacl-translate" or "pnacl-debug" dictionary, assuming
+// it was resolved from container_key.
+// E.g., "container_key" : { "pnacl-translate" : URLSpec }
+bool IsValidPnaclTranslateSpec(const Json::Value& pnacl_spec,
+                               const std::string& container_key,
+                               const std::string& parent_key,
+                               const std::string& sandbox_isa,
+                               std::string* error_string) {
+  static const char* kManifestPnaclSpecValid[] = {
+    kPnaclDebugKey,
+    kPnaclTranslateKey
+  };
+  static const char* kManifestPnaclSpecRequired[] = { kPnaclTranslateKey };
+  if (!IsValidDictionary(pnacl_spec, container_key, parent_key,
+                         kManifestPnaclSpecValid,
+                         arraysize(kManifestPnaclSpecValid),
+                         kManifestPnaclSpecRequired,
+                         arraysize(kManifestPnaclSpecRequired),
+                         error_string)) {
+    return false;
+  }
+  Json::Value url_spec = pnacl_spec[kPnaclTranslateKey];
+  return IsValidUrlSpec(url_spec, kPnaclTranslateKey,
+                        container_key, sandbox_isa, error_string);
+}
+
+// Validates that |dictionary| is a valid ISA dictionary.  An ISA dictionary
+// is validated to have keys from within the set of recognized ISAs.  Unknown
+// ISAs are allowed, but ignored and warnings are produced. It is also
+// validated
+// that it must have an entry to match the ISA specified in |sandbox_isa| or
+// have a fallback 'portable' entry if there is no match. Returns true if
+// |dictionary| is an ISA to URL map.  Sets |error_info| to something
+// descriptive if it fails.
+bool IsValidISADictionary(const Json::Value& dictionary,
+                          const std::string& parent_key,
+                          const std::string& sandbox_isa,
+                          bool must_find_matching_entry,
+                          bool nonsfi_enabled,
+                          JsonManifest::ErrorInfo* error_info) {
+  // An ISA to URL dictionary has to be an object.
+  if (!dictionary.isObject()) {
+    error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE;
+    error_info->string = std::string("manifest: ") + parent_key +
+                         " property is not an ISA to URL dictionary";
+    return false;
+  }
+  // Build the set of reserved ISA dictionary keys.
+  const char** isaProperties;
+  size_t isaPropertiesLength;
+  if (sandbox_isa == kPortableKey) {
+    // The known values for PNaCl ISA dictionaries in the manifest.
+    static const char* kPnaclManifestISAProperties[] = {
+      kPortableKey
+    };
+    isaProperties = kPnaclManifestISAProperties;
+    isaPropertiesLength = arraysize(kPnaclManifestISAProperties);
+  } else {
+    // The known values for NaCl ISA dictionaries in the manifest.
+    static const char* kNaClManifestISAProperties[] = {
+      kX8632Key,
+      kX8632NonSFIKey,
+      kX8664Key,
+      kX8664NonSFIKey,
+      kArmKey,
+      kArmNonSFIKey,
+      // "portable" is here to allow checking that, if present, it can
+      // only refer to an URL, such as for a data file, and not to
+      // "pnacl-translate", which would cause the creation of a nexe.
+      kPortableKey
+    };
+    isaProperties = kNaClManifestISAProperties;
+    isaPropertiesLength = arraysize(kNaClManifestISAProperties);
+  }
+  // Check that entries in the dictionary are structurally correct.
+  Json::Value::Members members = dictionary.getMemberNames();
+  for (size_t i = 0; i < members.size(); ++i) {
+    std::string property_name = members[i];
+    Json::Value property_value = dictionary[property_name];
+    std::string error_string;
+    if (FindMatchingProperty(property_name,
+                             isaProperties,
+                             isaPropertiesLength)) {
+      // For NaCl, arch entries can only be
+      //     "arch/portable" : URLSpec
+      // For PNaCl arch in "program" dictionary entries can be
+      //     "portable" : { "pnacl-translate": URLSpec }
+      //  or "portable" : { "pnacl-debug": URLSpec }
+      // For PNaCl arch elsewhere, dictionary entries can only be
+      //     "portable" : URLSpec
+      if ((sandbox_isa != kPortableKey &&
+           !IsValidUrlSpec(property_value, property_name, parent_key,
+                           sandbox_isa, &error_string)) ||
+          (sandbox_isa == kPortableKey &&
+           parent_key == kProgramKey &&
+           !IsValidPnaclTranslateSpec(property_value, property_name, parent_key,
+                                      sandbox_isa, &error_string)) ||
+          (sandbox_isa == kPortableKey &&
+           parent_key != kProgramKey &&
+           !IsValidUrlSpec(property_value, property_name, parent_key,
+                           sandbox_isa, &error_string))) {
+        error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE;
+        error_info->string = "manifest: " + error_string;
+        return false;
+      }
+    } else {
+      // For forward compatibility, we do not prohibit other keys being in
+      // the dictionary, as they may be architectures supported in later
+      // versions.  However, the value of these entries must be an URLSpec.
+      VLOG(1) << "IsValidISADictionary: unrecognized key '"
+              << property_name << "'.";
+      if (!IsValidUrlSpec(property_value, property_name, parent_key,
+                          sandbox_isa, &error_string)) {
+        error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE;
+        error_info->string = "manifest: " + error_string;
+        return false;
+      }
+    }
+  }
+
+  if (sandbox_isa == kPortableKey) {
+    if (!dictionary.isMember(kPortableKey)) {
+      error_info->error = PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH;
+      error_info->string = "manifest: no version of " + parent_key +
+                           " given for portable.";
+      return false;
+    }
+  } else if (must_find_matching_entry) {
+    // TODO(elijahtaylor) add ISA resolver here if we expand ISAs to include
+    // micro-architectures that can resolve to multiple valid sandboxes.
+    bool has_isa = dictionary.isMember(sandbox_isa);
+    bool has_nonsfi_isa =
+        nonsfi_enabled && dictionary.isMember(GetNonSFIKey(sandbox_isa));
+    bool has_portable = dictionary.isMember(kPortableKey);
+
+    if (!has_isa && !has_nonsfi_isa && !has_portable) {
+      error_info->error = PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH;
+      error_info->string = "manifest: no version of " + parent_key +
+          " given for current arch and no portable version found.";
+      return false;
+    }
+  }
+  return true;
+}
+
+void GrabUrlAndPnaclOptions(const Json::Value& url_spec,
+                            std::string* url,
+                            PP_PNaClOptions* pnacl_options) {
+  *url = url_spec[kUrlKey].asString();
+  pnacl_options->translate = PP_TRUE;
+  if (url_spec.isMember(kOptLevelKey)) {
+    int32_t opt_raw = url_spec[kOptLevelKey].asInt();
+    // Currently only allow 0 or 2, since that is what we test.
+    if (opt_raw <= 0)
+      pnacl_options->opt_level = 0;
+    else
+      pnacl_options->opt_level = 2;
+  }
+}
+
+}  // namespace
+
+JsonManifest::JsonManifest(const std::string& manifest_base_url,
+                           const std::string& sandbox_isa,
+                           bool nonsfi_enabled,
+                           bool pnacl_debug)
+    : manifest_base_url_(manifest_base_url),
+      sandbox_isa_(sandbox_isa),
+      nonsfi_enabled_(nonsfi_enabled),
+      pnacl_debug_(pnacl_debug) { }
+
+bool JsonManifest::Init(const std::string& manifest_json,
+                        ErrorInfo* error_info) {
+  CHECK(error_info);
+
+  Json::Reader reader;
+  if (!reader.parse(manifest_json, dictionary_)) {
+    std::string json_error = reader.getFormattedErrorMessages();
+    error_info->error = PP_NACL_ERROR_MANIFEST_PARSING;
+    error_info->string = "manifest JSON parsing failed: " + json_error;
+    return false;
+  }
+  // Parse has ensured the string was valid JSON.  Check that it matches the
+  // manifest schema.
+  return MatchesSchema(error_info);
+}
+
+bool JsonManifest::GetProgramURL(std::string* full_url,
+                                 PP_PNaClOptions* pnacl_options,
+                                 bool* uses_nonsfi_mode,
+                                 ErrorInfo* error_info) const {
+  if (!full_url)
+    return false;
+  CHECK(pnacl_options);
+  CHECK(uses_nonsfi_mode);
+  CHECK(error_info);
+
+  const Json::Value& program = dictionary_[kProgramKey];
+  std::string nexe_url;
+  if (!GetURLFromISADictionary(program,
+                               kProgramKey,
+                               &nexe_url,
+                               pnacl_options,
+                               uses_nonsfi_mode,
+                               error_info)) {
+    return false;
+  }
+
+  // The contents of the manifest are resolved relative to the manifest URL.
+  GURL base_gurl(manifest_base_url_);
+  if (!base_gurl.is_valid())
+    return false;
+
+  GURL resolved_gurl = base_gurl.Resolve(nexe_url);
+  if (!resolved_gurl.is_valid()) {
+    error_info->error = PP_NACL_ERROR_MANIFEST_RESOLVE_URL;
+    error_info->string =
+        "could not resolve url '" + nexe_url +
+        "' relative to manifest base url '" + manifest_base_url_.c_str() +
+        "'.";
+    return false;
+  }
+  *full_url = resolved_gurl.possibly_invalid_spec();
+  return true;
+}
+
+bool JsonManifest::ResolveKey(const std::string& key,
+                              std::string* full_url,
+                              PP_PNaClOptions* pnacl_options) const {
+  // key must be one of kProgramKey or kFileKey '/' file-section-key
+  if (full_url == NULL || pnacl_options == NULL)
+    return false;
+
+  if (key == kProgramKey)
+    return GetKeyUrl(dictionary_, key, full_url, pnacl_options);
+
+  std::string::const_iterator p = find(key.begin(), key.end(), '/');
+  if (p == key.end()) {
+    VLOG(1) << "ResolveKey failed: invalid key, no slash: " << key;
+    return false;
+  }
+
+  // generalize to permit other sections?
+  std::string prefix(key.begin(), p);
+  if (prefix != kFilesKey) {
+    VLOG(1) << "ResolveKey failed: invalid key, no \"files\" prefix: " << key;
+    return false;
+  }
+
+  const Json::Value& files = dictionary_[kFilesKey];
+  if (!files.isObject()) {
+    VLOG(1) << "ResolveKey failed: no \"files\" dictionary";
+    return false;
+  }
+
+  std::string rest(p + 1, key.end());
+  if (!files.isMember(rest)) {
+    VLOG(1) << "ResolveKey failed: no such \"files\" entry: " << key;
+    return false;
+  }
+  return GetKeyUrl(files, rest, full_url, pnacl_options);
+}
+
+bool JsonManifest::MatchesSchema(ErrorInfo* error_info) {
+  if (!dictionary_.isObject()) {
+    error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE;
+    error_info->string = "manifest: is not a json dictionary.";
+    return false;
+  }
+  Json::Value::Members members = dictionary_.getMemberNames();
+  for (size_t i = 0; i < members.size(); ++i) {
+    // The top level dictionary entries valid in the manifest file.
+    static const char* kManifestTopLevelProperties[] = { kProgramKey,
+                                                         kInterpreterKey,
+                                                         kFilesKey };
+    std::string property_name = members[i];
+    if (!FindMatchingProperty(property_name,
+                              kManifestTopLevelProperties,
+                              arraysize(kManifestTopLevelProperties))) {
+      VLOG(1) << "JsonManifest::MatchesSchema: WARNING: unknown top-level "
+              << "section '" << property_name << "' in manifest.";
+    }
+  }
+
+  // A manifest file must have a program section.
+  if (!dictionary_.isMember(kProgramKey)) {
+    error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE;
+    error_info->string = std::string("manifest: missing '") + kProgramKey +
+                         "' section.";
+    return false;
+  }
+
+  // Validate the program section.
+  // There must be a matching (portable or sandbox_isa_) entry for program for
+  // NaCl.
+  if (!IsValidISADictionary(dictionary_[kProgramKey],
+                            kProgramKey,
+                            sandbox_isa_,
+                            true,
+                            nonsfi_enabled_,
+                            error_info)) {
+    return false;
+  }
+
+  // Validate the interpreter section (if given).
+  // There must be a matching (portable or sandbox_isa_) entry for interpreter
+  // for NaCl.
+  if (dictionary_.isMember(kInterpreterKey)) {
+    if (!IsValidISADictionary(dictionary_[kInterpreterKey],
+                              kInterpreterKey,
+                              sandbox_isa_,
+                              true,
+                              nonsfi_enabled_,
+                              error_info)) {
+      return false;
+    }
+  }
+
+  // Validate the file dictionary (if given).
+  // The "files" key does not require a matching (portable or sandbox_isa_)
+  // entry at schema validation time for NaCl.  This allows manifests to
+  // specify resources that are only loaded for a particular sandbox_isa.
+  if (dictionary_.isMember(kFilesKey)) {
+    const Json::Value& files = dictionary_[kFilesKey];
+    if (!files.isObject()) {
+      error_info->error = PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE;
+      error_info->string = std::string("manifest: '") + kFilesKey +
+                           "' is not a dictionary.";
+    }
+    Json::Value::Members members = files.getMemberNames();
+    for (size_t i = 0; i < members.size(); ++i) {
+      std::string file_name = members[i];
+      if (!IsValidISADictionary(files[file_name],
+                                file_name,
+                                sandbox_isa_,
+                                false,
+                                nonsfi_enabled_,
+                                error_info)) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+bool JsonManifest::GetKeyUrl(const Json::Value& dictionary,
+                             const std::string& key,
+                             std::string* full_url,
+                             PP_PNaClOptions* pnacl_options) const {
+  DCHECK(full_url && pnacl_options);
+  if (!dictionary.isMember(key)) {
+    VLOG(1) << "GetKeyUrl failed: file " << key << " not found in manifest.";
+    return false;
+  }
+  const Json::Value& isa_dict = dictionary[key];
+  std::string relative_url;
+  bool uses_nonsfi_mode;
+  ErrorInfo ignored_error_info;
+  if (!GetURLFromISADictionary(isa_dict, key, &relative_url,
+                               pnacl_options, &uses_nonsfi_mode,
+                               &ignored_error_info))
+    return false;
+
+  // The contents of the manifest are resolved relative to the manifest URL.
+  GURL base_gurl(manifest_base_url_);
+  if (!base_gurl.is_valid())
+    return false;
+  GURL resolved_gurl = base_gurl.Resolve(relative_url);
+  if (!resolved_gurl.is_valid())
+    return false;
+  *full_url = resolved_gurl.possibly_invalid_spec();
+  return true;
+}
+
+bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary,
+                                           const std::string& parent_key,
+                                           std::string* url,
+                                           PP_PNaClOptions* pnacl_options,
+                                           bool* uses_nonsfi_mode,
+                                           ErrorInfo* error_info) const {
+  DCHECK(url && pnacl_options && error_info);
+
+  // When the application actually requests a resolved URL, we must have
+  // a matching entry (sandbox_isa_ or portable) for NaCl.
+  ErrorInfo ignored_error_info;
+  if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa_, true,
+                            nonsfi_enabled_, &ignored_error_info)) {
+    error_info->error = PP_NACL_ERROR_MANIFEST_RESOLVE_URL;
+    error_info->string = "architecture " + sandbox_isa_ +
+                         " is not found for file " + parent_key;
+    return false;
+  }
+
+  // The call to IsValidISADictionary() above guarantees that either
+  // sandbox_isa_, its nonsfi mode, or kPortableKey is present in the
+  // dictionary.
+  *uses_nonsfi_mode = false;
+  std::string chosen_isa;
+  if (sandbox_isa_ == kPortableKey) {
+    chosen_isa = kPortableKey;
+  } else {
+    std::string nonsfi_isa = GetNonSFIKey(sandbox_isa_);
+    if (nonsfi_enabled_ && dictionary.isMember(nonsfi_isa)) {
+      chosen_isa = nonsfi_isa;
+      *uses_nonsfi_mode = true;
+    } else if (dictionary.isMember(sandbox_isa_)) {
+      chosen_isa = sandbox_isa_;
+    } else if (dictionary.isMember(kPortableKey)) {
+      chosen_isa = kPortableKey;
+    } else {
+      // Should not reach here, because the earlier IsValidISADictionary()
+      // call checked that the manifest covers the current architecture.
+      DCHECK(false);
+      return false;
+    }
+  }
+
+  const Json::Value& isa_spec = dictionary[chosen_isa];
+  // If the PNaCl debug flag is turned on, look for pnacl-debug entries first.
+  // If found, mark that it is a debug URL. Otherwise, fall back to
+  // checking for pnacl-translate URLs, etc. and don't mark it as a debug URL.
+  if (pnacl_debug_ && isa_spec.isMember(kPnaclDebugKey)) {
+    GrabUrlAndPnaclOptions(isa_spec[kPnaclDebugKey], url, pnacl_options);
+    pnacl_options->is_debug = PP_TRUE;
+  } else if (isa_spec.isMember(kPnaclTranslateKey)) {
+    GrabUrlAndPnaclOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options);
+  } else {
+    // NaCl
+    *url = isa_spec[kUrlKey].asString();
+    pnacl_options->translate = PP_FALSE;
+  }
+
+  return true;
+}
+
+}  // namespace nacl
diff --git a/components/nacl/renderer/json_manifest.h b/components/nacl/renderer/json_manifest.h
new file mode 100644
index 0000000..d8885d3
--- /dev/null
+++ b/components/nacl/renderer/json_manifest.h
@@ -0,0 +1,73 @@
+// 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.
+
+#ifndef COMPONENTS_NACL_RENDERER_JSON_MANIFEST_H
+#define COMPONENTS_NACL_RENDERER_JSON_MANIFEST_H
+
+#include <set>
+#include <string>
+
+#include "ppapi/c/pp_array_output.h"
+#include "ppapi/c/private/ppb_nacl_private.h"
+#include "third_party/jsoncpp/source/include/json/value.h"
+
+namespace nacl {
+class NexeLoadManager;
+
+class JsonManifest {
+ public:
+  struct ErrorInfo {
+    PP_NaClError error;
+    std::string string;
+  };
+
+  JsonManifest(const std::string& manifest_base_url,
+               const std::string& sandbox_isa,
+               bool nonsfi_enabled,
+               bool pnacl_debug);
+
+  // Initialize the manifest object for use by later lookups. Returns
+  // true if the manifest parses correctly and matches the schema.
+  bool Init(const std::string& json_manifest, ErrorInfo* error_info);
+
+  // Gets the full program URL for the current sandbox ISA from the
+  // manifest file.
+  bool GetProgramURL(std::string* full_url,
+                     PP_PNaClOptions* pnacl_options,
+                     bool* uses_nonsfi_mode,
+                     ErrorInfo* error_info) const;
+
+  // Resolves a key from the "files" section to a fully resolved URL,
+  // i.e., relative URL values are fully expanded relative to the
+  // manifest's URL (via ResolveURL).
+  // If there was an error, details are reported via error_info.
+  bool ResolveKey(const std::string& key,
+                  std::string* full_url,
+                  PP_PNaClOptions* pnacl_options) const;
+
+ private:
+  bool MatchesSchema(ErrorInfo* error_info);
+  bool GetKeyUrl(const Json::Value& dictionary,
+                 const std::string& key,
+                 std::string* full_url,
+                 PP_PNaClOptions* pnacl_options) const;
+  bool GetURLFromISADictionary(const Json::Value& dictionary,
+                               const std::string& parent_key,
+                               std::string* url,
+                               PP_PNaClOptions* pnacl_options,
+                               bool* uses_nonsfi_mode,
+                               ErrorInfo* error_info) const;
+
+  std::string manifest_base_url_;
+  std::string sandbox_isa_;
+  bool nonsfi_enabled_;
+  bool pnacl_debug_;
+
+  // The dictionary of manifest information parsed in Init().
+  Json::Value dictionary_;
+};
+
+}  // namespace nacl
+
+#endif  // COMPONENTS_NACL_RENDERER_JSON_MANIFEST_H
diff --git a/components/nacl/renderer/manifest_downloader.cc b/components/nacl/renderer/manifest_downloader.cc
new file mode 100644
index 0000000..fec18d7
--- /dev/null
+++ b/components/nacl/renderer/manifest_downloader.cc
@@ -0,0 +1,92 @@
+// 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.
+
+#include "components/nacl/renderer/manifest_downloader.h"
+
+#include "base/callback.h"
+#include "components/nacl/renderer/histogram.h"
+#include "components/nacl/renderer/nexe_load_manager.h"
+#include "net/base/net_errors.h"
+#include "third_party/WebKit/public/platform/WebURLError.h"
+#include "third_party/WebKit/public/platform/WebURLLoader.h"
+#include "third_party/WebKit/public/platform/WebURLResponse.h"
+
+namespace nacl {
+
+namespace {
+// This is a pretty arbitrary limit on the byte size of the NaCl manifest file.
+// Note that the resulting string object has to have at least one byte extra
+// for the null termination character.
+const size_t kNaClManifestMaxFileBytes = 1024 * 1024;
+}  // namespace
+
+ManifestDownloader::ManifestDownloader(
+    bool is_installed,
+    ManifestDownloaderCallback cb)
+    : is_installed_(is_installed),
+      cb_(cb),
+      status_code_(-1),
+      pp_nacl_error_(PP_NACL_ERROR_LOAD_SUCCESS) {
+  CHECK(!cb.is_null());
+}
+
+ManifestDownloader::~ManifestDownloader() {
+}
+
+void ManifestDownloader::didReceiveResponse(
+    blink::WebURLLoader* loader,
+    const blink::WebURLResponse& response) {
+  if (response.httpStatusCode() != 200)
+    pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_LOAD_URL;
+  status_code_ = response.httpStatusCode();
+}
+
+void ManifestDownloader::didReceiveData(
+    blink::WebURLLoader* loader,
+    const char* data,
+    int data_length,
+    int encoded_data_length) {
+  if (buffer_.size() + data_length > kNaClManifestMaxFileBytes) {
+    pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_TOO_LARGE;
+    buffer_.clear();
+  }
+
+  if (pp_nacl_error_ == PP_NACL_ERROR_LOAD_SUCCESS)
+    buffer_.append(data, data_length);
+}
+
+void ManifestDownloader::didFinishLoading(
+    blink::WebURLLoader* loader,
+    double finish_time,
+    int64_t total_encoded_data_length) {
+  // We log the status code here instead of in didReceiveResponse so that we
+  // always log a histogram value, even when we never receive a status code.
+  HistogramHTTPStatusCode(
+      is_installed_ ? "NaCl.HttpStatusCodeClass.Manifest.InstalledApp" :
+                      "NaCl.HttpStatusCodeClass.Manifest.NotInstalledApp",
+      status_code_);
+
+  cb_.Run(pp_nacl_error_, buffer_);
+  delete this;
+}
+
+void ManifestDownloader::didFail(
+    blink::WebURLLoader* loader,
+    const blink::WebURLError& error) {
+  // TODO(teravest): Find a place to share this code with PepperURLLoaderHost.
+  pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_LOAD_URL;
+  if (error.domain.equals(blink::WebString::fromUTF8(net::kErrorDomain))) {
+    switch (error.reason) {
+      case net::ERR_ACCESS_DENIED:
+      case net::ERR_NETWORK_ACCESS_DENIED:
+        pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_NOACCESS_URL;
+        break;
+    }
+  } else {
+    // It's a WebKit error.
+    pp_nacl_error_ = PP_NACL_ERROR_MANIFEST_NOACCESS_URL;
+  }
+}
+
+}  // namespace nacl
diff --git a/components/nacl/renderer/manifest_downloader.h b/components/nacl/renderer/manifest_downloader.h
new file mode 100644
index 0000000..dbdbf84
--- /dev/null
+++ b/components/nacl/renderer/manifest_downloader.h
@@ -0,0 +1,50 @@
+// 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.
+
+#include <string>
+
+#include "base/callback.h"
+#include "ppapi/c/private/ppb_nacl_private.h"
+#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
+
+namespace blink {
+struct WebURLError;
+class WebURLLoader;
+class WebURLResponse;
+}
+
+namespace nacl {
+
+// Downloads a NaCl manifest (.nmf) and returns the contents of the file to
+// caller through a callback.
+class ManifestDownloader : public blink::WebURLLoaderClient {
+ public:
+  typedef base::Callback<void(PP_NaClError, const std::string&)>
+      ManifestDownloaderCallback;
+
+  ManifestDownloader(bool is_installed, ManifestDownloaderCallback cb);
+  virtual ~ManifestDownloader();
+
+ private:
+  // WebURLLoaderClient implementation.
+  virtual void didReceiveResponse(blink::WebURLLoader* loader,
+                                  const blink::WebURLResponse& response);
+  virtual void didReceiveData(blink::WebURLLoader* loader,
+                              const char* data,
+                              int data_length,
+                              int encoded_data_length);
+  virtual void didFinishLoading(blink::WebURLLoader* loader,
+                                double finish_time,
+                                int64_t total_encoded_data_length);
+  virtual void didFail(blink::WebURLLoader* loader,
+                       const blink::WebURLError& error);
+
+  bool is_installed_;
+  ManifestDownloaderCallback cb_;
+  std::string buffer_;
+  int status_code_;
+  PP_NaClError pp_nacl_error_;
+};
+
+}  // namespace nacl
diff --git a/components/nacl/renderer/manifest_service_channel.cc b/components/nacl/renderer/manifest_service_channel.cc
index f0f4adb..606be61 100644
--- a/components/nacl/renderer/manifest_service_channel.cc
+++ b/components/nacl/renderer/manifest_service_channel.cc
@@ -4,6 +4,7 @@
 
 #include "components/nacl/renderer/manifest_service_channel.h"
 
+#include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "content/public/renderer/render_thread.h"
@@ -24,7 +25,8 @@
       channel_(new IPC::SyncChannel(
           handle, IPC::Channel::MODE_CLIENT, this,
           content::RenderThread::Get()->GetIOMessageLoopProxy(),
-          true, waitable_event)) {
+          true, waitable_event)),
+      weak_ptr_factory_(this) {
 }
 
 ManifestServiceChannel::~ManifestServiceChannel() {
@@ -32,12 +34,17 @@
     base::ResetAndReturn(&connected_callback_).Run(PP_ERROR_FAILED);
 }
 
+void ManifestServiceChannel::Send(IPC::Message* message) {
+  channel_->Send(message);
+}
+
 bool ManifestServiceChannel::OnMessageReceived(const IPC::Message& message) {
-  // TODO(hidehiko): Implement OpenResource.
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ManifestServiceChannel, message)
       IPC_MESSAGE_HANDLER(PpapiHostMsg_StartupInitializationComplete,
                           OnStartupInitializationComplete)
+      IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiHostMsg_OpenResource,
+                                      OnOpenResource)
       IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
@@ -57,4 +64,33 @@
   delegate_->StartupInitializationComplete();
 }
 
+void ManifestServiceChannel::OnOpenResource(
+    const std::string& key, IPC::Message* reply) {
+  // Currently this is used only for non-SFI mode, which is not supported on
+  // windows.
+#if !defined(OS_WIN)
+  delegate_->OpenResource(
+      key,
+      base::Bind(&ManifestServiceChannel::DidOpenResource,
+                 weak_ptr_factory_.GetWeakPtr(), reply));
+#else
+  PpapiHostMsg_OpenResource::WriteReplyParams(
+      reply, ppapi::proxy::SerializedHandle());
+  Send(reply);
+#endif
+}
+
+#if !defined(OS_WIN)
+void ManifestServiceChannel::DidOpenResource(
+    IPC::Message* reply, const base::PlatformFile& platform_file) {
+  // Here, PlatformFileForTransit is alias of base::FileDescriptor.
+  PpapiHostMsg_OpenResource::WriteReplyParams(
+      reply,
+      ppapi::proxy::SerializedHandle(
+          ppapi::proxy::SerializedHandle::FILE,
+          base::FileDescriptor(platform_file, true)));
+  Send(reply);
+}
+#endif
+
 }  // namespace nacl
diff --git a/components/nacl/renderer/manifest_service_channel.h b/components/nacl/renderer/manifest_service_channel.h
index 6dc394f..c75b35a 100644
--- a/components/nacl/renderer/manifest_service_channel.h
+++ b/components/nacl/renderer/manifest_service_channel.h
@@ -8,6 +8,10 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/platform_file.h"
+#include "base/process/process.h"
+#include "base/synchronization/lock.h"
 #include "ipc/ipc_listener.h"
 
 namespace base {
@@ -24,6 +28,8 @@
 
 class ManifestServiceChannel : public IPC::Listener {
  public:
+  typedef base::Callback<void(const base::PlatformFile&)> OpenResourceCallback;
+
   class Delegate {
    public:
     virtual ~Delegate() {}
@@ -31,7 +37,11 @@
     // Called when PPAPI initialization in the NaCl plugin is finished.
     virtual void StartupInitializationComplete() = 0;
 
-    // TODO(hidehiko): Add OpenResource() here.
+    // Called when irt_open_resource() is invoked in the NaCl plugin.
+    // Upon completion, callback is invoked with the platform file.
+    virtual void OpenResource(
+        const std::string& key,
+        const OpenResourceCallback& callback) = 0;
   };
 
   ManifestServiceChannel(
@@ -41,6 +51,8 @@
       base::WaitableEvent* waitable_event);
   virtual ~ManifestServiceChannel();
 
+  void Send(IPC::Message* message);
+
   // Listener implementation.
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
   virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
@@ -48,11 +60,20 @@
 
  private:
   void OnStartupInitializationComplete();
+  void OnOpenResource(const std::string& key, IPC::Message* reply);
+#if !defined(OS_WIN)
+  void DidOpenResource(
+      IPC::Message* reply, const base::PlatformFile& platform_file);
+#endif
 
   base::Callback<void(int32_t)> connected_callback_;
   scoped_ptr<Delegate> delegate_;
   scoped_ptr<IPC::SyncChannel> channel_;
 
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate the weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<ManifestServiceChannel> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(ManifestServiceChannel);
 };
 
diff --git a/components/nacl/renderer/ppb_nacl_private_impl.cc b/components/nacl/renderer/ppb_nacl_private_impl.cc
index 85ff322..3361f61 100644
--- a/components/nacl/renderer/ppb_nacl_private_impl.cc
+++ b/components/nacl/renderer/ppb_nacl_private_impl.cc
@@ -4,10 +4,15 @@
 
 #include "components/nacl/renderer/ppb_nacl_private_impl.h"
 
+#include <numeric>
+#include <string>
+#include <vector>
+
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/command_line.h"
 #include "base/containers/scoped_ptr_hash_map.h"
+#include "base/cpu.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/rand_util.h"
@@ -15,6 +20,9 @@
 #include "components/nacl/common/nacl_messages.h"
 #include "components/nacl/common/nacl_switches.h"
 #include "components/nacl/common/nacl_types.h"
+#include "components/nacl/renderer/histogram.h"
+#include "components/nacl/renderer/json_manifest.h"
+#include "components/nacl/renderer/manifest_downloader.h"
 #include "components/nacl/renderer/manifest_service_channel.h"
 #include "components/nacl/renderer/nexe_load_manager.h"
 #include "components/nacl/renderer/pnacl_translation_resource_host.h"
@@ -28,6 +36,7 @@
 #include "content/public/renderer/render_view.h"
 #include "content/public/renderer/renderer_ppapi_host.h"
 #include "net/base/data_url.h"
+#include "net/base/net_errors.h"
 #include "net/http/http_util.h"
 #include "ppapi/c/pp_bool.h"
 #include "ppapi/c/private/pp_file_handle.h"
@@ -37,10 +46,15 @@
 #include "ppapi/shared_impl/ppapi_preferences.h"
 #include "ppapi/shared_impl/var.h"
 #include "ppapi/thunk/enter.h"
+#include "third_party/WebKit/public/platform/WebURLLoader.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebElement.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebPluginContainer.h"
 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
+#include "third_party/WebKit/public/web/WebURLLoaderOptions.h"
+#include "third_party/jsoncpp/source/include/json/reader.h"
+#include "third_party/jsoncpp/source/include/json/value.h"
 
 namespace nacl {
 namespace {
@@ -81,7 +95,20 @@
 base::LazyInstance<NexeLoadManagerMap> g_load_manager_map =
     LAZY_INSTANCE_INITIALIZER;
 
-NexeLoadManager* GetNexeLoadManager(PP_Instance instance) {
+typedef base::ScopedPtrHashMap<int32_t, nacl::JsonManifest> JsonManifestMap;
+
+base::LazyInstance<JsonManifestMap> g_manifest_map =
+    LAZY_INSTANCE_INITIALIZER;
+
+base::LazyInstance<int32_t> g_next_manifest_id =
+    LAZY_INSTANCE_INITIALIZER;
+
+// We have to define a method here since we can't use a static initializer.
+int32_t GetPNaClManifestId() {
+  return std::numeric_limits<int32_t>::max();
+}
+
+nacl::NexeLoadManager* GetNexeLoadManager(PP_Instance instance) {
   NexeLoadManagerMap& map = g_load_manager_map.Get();
   NexeLoadManagerMap::iterator iter = map.find(instance);
   if (iter != map.end())
@@ -158,13 +185,13 @@
   DISALLOW_COPY_AND_ASSIGN(ChannelConnectedCallback);
 };
 
-// Thin adapter from PP_ManifestService to ManifestServiceChannel::Delegate.
+// Thin adapter from PPP_ManifestService to ManifestServiceChannel::Delegate.
 // Note that user_data is managed by the caller of LaunchSelLdr. Please see
 // also PP_ManifestService's comment for more details about resource
 // management.
 class ManifestServiceProxy : public ManifestServiceChannel::Delegate {
  public:
-  ManifestServiceProxy(const PP_ManifestService* manifest_service,
+  ManifestServiceProxy(const PPP_ManifestService* manifest_service,
                        void* user_data)
       : manifest_service_(*manifest_service),
         user_data_(user_data) {
@@ -184,7 +211,30 @@
     }
   }
 
+  virtual void OpenResource(
+      const std::string& key,
+      const ManifestServiceChannel::OpenResourceCallback& callback) OVERRIDE {
+    if (!user_data_)
+      return;
+
+    // The allocated callback will be freed in DidOpenResource, which is always
+    // called regardless whether OpenResource() succeeds or fails.
+    if (!PP_ToBool(manifest_service_.OpenResource(
+            user_data_,
+            key.c_str(),
+            DidOpenResource,
+            new ManifestServiceChannel::OpenResourceCallback(callback)))) {
+      user_data_ = NULL;
+    }
+  }
+
  private:
+  static void DidOpenResource(void* user_data, PP_FileHandle file_handle) {
+    scoped_ptr<ManifestServiceChannel::OpenResourceCallback> callback(
+        static_cast<ManifestServiceChannel::OpenResourceCallback*>(user_data));
+    callback->Run(file_handle);
+  }
+
   void Quit() {
     if (!user_data_)
       return;
@@ -194,7 +244,7 @@
     user_data_ = NULL;
   }
 
-  PP_ManifestService manifest_service_;
+  PPP_ManifestService manifest_service_;
   void* user_data_;
   DISALLOW_COPY_AND_ASSIGN(ManifestServiceProxy);
 };
@@ -209,7 +259,7 @@
                   PP_Bool enable_dyncode_syscalls,
                   PP_Bool enable_exception_handling,
                   PP_Bool enable_crash_throttling,
-                  const PP_ManifestService* manifest_service_interface,
+                  const PPP_ManifestService* manifest_service_interface,
                   void* manifest_service_user_data,
                   void* imc_handle,
                   struct PP_Var* error_message,
@@ -321,7 +371,14 @@
   }
 
   // Stash the manifest service handle as well.
+  // For security hardening, disable the IPCs for open_resource() when they
+  // aren't needed.  PNaCl doesn't expose open_resource(), and the new
+  // open_resource() IPCs are currently only used for Non-SFI NaCl so far,
+  // not SFI NaCl. Note that enable_dyncode_syscalls is true if and only if
+  // the plugin is a non-PNaCl plugin.
   if (load_manager &&
+      enable_dyncode_syscalls &&
+      uses_nonsfi_mode &&
       IsValidChannelHandle(
           launch_result.manifest_service_ipc_channel_handle)) {
     scoped_ptr<ManifestServiceChannel> manifest_service_channel(
@@ -851,6 +908,330 @@
   return PP_FALSE;
 }
 
+void DownloadManifestToBufferCompletion(PP_Instance instance,
+                                        struct PP_CompletionCallback callback,
+                                        struct PP_Var* out_data,
+                                        base::Time start_time,
+                                        PP_NaClError pp_nacl_error,
+                                        const std::string& data);
+
+void DownloadManifestToBuffer(PP_Instance instance,
+                              struct PP_Var* out_data,
+                              struct PP_CompletionCallback callback) {
+  nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance);
+  DCHECK(load_manager);
+  if (!load_manager) {
+    ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask(
+        FROM_HERE,
+        base::Bind(callback.func, callback.user_data,
+                   static_cast<int32_t>(PP_ERROR_FAILED)));
+  }
+
+  const GURL& gurl = load_manager->manifest_base_url();
+
+  content::PepperPluginInstance* plugin_instance =
+      content::PepperPluginInstance::Get(instance);
+  blink::WebURLLoaderOptions options;
+  options.untrustedHTTP = true;
+
+  blink::WebSecurityOrigin security_origin =
+      plugin_instance->GetContainer()->element().document().securityOrigin();
+  // Options settings here follow the original behavior in the trusted
+  // plugin and PepperURLLoaderHost.
+  if (security_origin.canRequest(gurl)) {
+    options.allowCredentials = true;
+  } else {
+    // Allow CORS.
+    options.crossOriginRequestPolicy =
+        blink::WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
+  }
+
+  blink::WebFrame* frame =
+      plugin_instance->GetContainer()->element().document().frame();
+  blink::WebURLLoader* url_loader = frame->createAssociatedURLLoader(options);
+  blink::WebURLRequest request;
+  request.initialize();
+  request.setURL(gurl);
+  request.setFirstPartyForCookies(frame->document().firstPartyForCookies());
+
+  // ManifestDownloader deletes itself after invoking the callback.
+  ManifestDownloader* client = new ManifestDownloader(
+      load_manager->is_installed(),
+      base::Bind(DownloadManifestToBufferCompletion,
+                 instance, callback, out_data, base::Time::Now()));
+  url_loader->loadAsynchronously(request, client);
+}
+
+void DownloadManifestToBufferCompletion(PP_Instance instance,
+                                        struct PP_CompletionCallback callback,
+                                        struct PP_Var* out_data,
+                                        base::Time start_time,
+                                        PP_NaClError pp_nacl_error,
+                                        const std::string& data) {
+  base::TimeDelta download_time = base::Time::Now() - start_time;
+  HistogramTimeSmall("NaCl.Perf.StartupTime.ManifestDownload",
+                     download_time.InMilliseconds());
+
+  nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance);
+  if (!load_manager) {
+    callback.func(callback.user_data, PP_ERROR_ABORTED);
+    return;
+  }
+
+  int32_t pp_error;
+  switch (pp_nacl_error) {
+    case PP_NACL_ERROR_LOAD_SUCCESS:
+      pp_error = PP_OK;
+      break;
+    case PP_NACL_ERROR_MANIFEST_LOAD_URL:
+      pp_error = PP_ERROR_FAILED;
+      load_manager->ReportLoadError(PP_NACL_ERROR_MANIFEST_LOAD_URL,
+                                    "could not load manifest url.");
+      break;
+    case PP_NACL_ERROR_MANIFEST_TOO_LARGE:
+      pp_error = PP_ERROR_FILETOOBIG;
+      load_manager->ReportLoadError(PP_NACL_ERROR_MANIFEST_TOO_LARGE,
+                                    "manifest file too large.");
+      break;
+    case PP_NACL_ERROR_MANIFEST_NOACCESS_URL:
+      pp_error = PP_ERROR_NOACCESS;
+      load_manager->ReportLoadError(PP_NACL_ERROR_MANIFEST_NOACCESS_URL,
+                                    "access to manifest url was denied.");
+      break;
+    default:
+      NOTREACHED();
+      pp_error = PP_ERROR_FAILED;
+      load_manager->ReportLoadError(PP_NACL_ERROR_MANIFEST_LOAD_URL,
+                                    "could not load manifest url.");
+  }
+
+  if (pp_error == PP_OK) {
+    std::string contents;
+    *out_data = ppapi::StringVar::StringToPPVar(data);
+  }
+  callback.func(callback.user_data, pp_error);
+}
+
+int32_t CreatePNaClManifest(PP_Instance /* instance */) {
+  return GetPNaClManifestId();
+}
+
+int32_t CreateJsonManifest(PP_Instance instance,
+                           const char* manifest_url,
+                           const char* isa_type,
+                           const char* manifest_data) {
+  int32_t manifest_id = g_next_manifest_id.Get();
+  g_next_manifest_id.Get()++;
+
+  scoped_ptr<nacl::JsonManifest> j(
+      new nacl::JsonManifest(
+          manifest_url,
+          isa_type,
+          PP_ToBool(IsNonSFIModeEnabled()),
+          PP_ToBool(NaClDebugEnabledForURL(manifest_url))));
+  JsonManifest::ErrorInfo error_info;
+  if (j->Init(manifest_data, &error_info)) {
+    g_manifest_map.Get().add(manifest_id, j.Pass());
+    return manifest_id;
+  }
+  nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance);
+  if (load_manager)
+    load_manager->ReportLoadError(error_info.error, error_info.string);
+  return -1;
+}
+
+void DestroyManifest(PP_Instance /* instance */,
+                     int32_t manifest_id) {
+  if (manifest_id == GetPNaClManifestId())
+    return;
+  g_manifest_map.Get().erase(manifest_id);
+}
+
+PP_Bool ManifestGetProgramURL(PP_Instance instance,
+                              int32_t manifest_id,
+                              PP_Var* pp_full_url,
+                              PP_PNaClOptions* pnacl_options,
+                              PP_Bool* pp_uses_nonsfi_mode) {
+  nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance);
+  if (manifest_id == GetPNaClManifestId()) {
+    if (load_manager) {
+      load_manager->ReportLoadError(
+          PP_NACL_ERROR_MANIFEST_GET_NEXE_URL,
+          "pnacl manifest does not contain a program.");
+    }
+    return PP_FALSE;
+  }
+
+  JsonManifestMap::iterator it = g_manifest_map.Get().find(manifest_id);
+  if (it == g_manifest_map.Get().end())
+    return PP_FALSE;
+
+  bool uses_nonsfi_mode;
+  std::string full_url;
+  JsonManifest::ErrorInfo error_info;
+  if (it->second->GetProgramURL(&full_url, pnacl_options, &uses_nonsfi_mode,
+                                &error_info)) {
+    *pp_full_url = ppapi::StringVar::StringToPPVar(full_url);
+    *pp_uses_nonsfi_mode = PP_FromBool(uses_nonsfi_mode);
+    return PP_TRUE;
+  }
+
+  if (load_manager)
+    load_manager->ReportLoadError(error_info.error, error_info.string);
+  return PP_FALSE;
+}
+
+PP_Bool ManifestResolveKey(PP_Instance instance,
+                           int32_t manifest_id,
+                           const char* key,
+                           PP_Var* pp_full_url,
+                           PP_PNaClOptions* pnacl_options) {
+  if (manifest_id == GetPNaClManifestId()) {
+    pnacl_options->translate = PP_FALSE;
+    // We can only resolve keys in the files/ namespace.
+    const std::string kFilesPrefix = "files/";
+    std::string key_string(key);
+    if (key_string.find(kFilesPrefix) == std::string::npos) {
+      nacl::NexeLoadManager* load_manager = GetNexeLoadManager(instance);
+      if (load_manager)
+        load_manager->ReportLoadError(PP_NACL_ERROR_MANIFEST_RESOLVE_URL,
+                                      "key did not start with files/");
+      return PP_FALSE;
+    }
+    std::string key_basename = key_string.substr(kFilesPrefix.length());
+    std::string pnacl_url =
+        std::string("chrome://pnacl-translator/") + GetSandboxArch() + "/" +
+        key_basename;
+    *pp_full_url = ppapi::StringVar::StringToPPVar(pnacl_url);
+    return PP_TRUE;
+  }
+
+  JsonManifestMap::iterator it = g_manifest_map.Get().find(manifest_id);
+  if (it == g_manifest_map.Get().end())
+    return PP_FALSE;
+
+  std::string full_url;
+  bool ok = it->second->ResolveKey(key, &full_url, pnacl_options);
+  if (ok)
+    *pp_full_url = ppapi::StringVar::StringToPPVar(full_url);
+  return PP_FromBool(ok);
+}
+
+PP_Bool GetPNaClResourceInfo(PP_Instance instance,
+                             const char* filename,
+                             PP_Var* llc_tool_name,
+                             PP_Var* ld_tool_name) {
+  NexeLoadManager* load_manager = GetNexeLoadManager(instance);
+  DCHECK(load_manager);
+  if (!load_manager)
+    return PP_FALSE;
+
+  base::PlatformFile file = GetReadonlyPnaclFD(filename);
+  if (file == base::kInvalidPlatformFileValue) {
+    load_manager->ReportLoadError(
+        PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
+        "The Portable Native Client (pnacl) component is not "
+        "installed. Please consult chrome://components for more "
+        "information.");
+    return PP_FALSE;
+  }
+
+  const int kBufferSize = 1 << 20;
+  scoped_ptr<char[]> buffer(new char[kBufferSize]);
+  if (base::ReadPlatformFile(file, 0, buffer.get(), kBufferSize) < 0) {
+    load_manager->ReportLoadError(
+        PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
+        std::string("PnaclResources::ReadResourceInfo reading failed for: ") +
+            filename);
+    return PP_FALSE;
+  }
+
+  // Expect the JSON file to contain a top-level object (dictionary).
+  Json::Reader json_reader;
+  Json::Value json_data;
+  if (!json_reader.parse(buffer.get(), json_data)) {
+    load_manager->ReportLoadError(
+        PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
+        std::string("Parsing resource info failed: JSON parse error: ") +
+            json_reader.getFormattedErrorMessages());
+    return PP_FALSE;
+  }
+
+  if (!json_data.isObject()) {
+    load_manager->ReportLoadError(
+        PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
+        "Parsing resource info failed: Malformed JSON dictionary");
+    return PP_FALSE;
+  }
+
+  if (json_data.isMember("pnacl-llc-name")) {
+    Json::Value json_name = json_data["pnacl-llc-name"];
+    if (json_name.isString()) {
+      std::string llc_tool_name_str = json_name.asString();
+      *llc_tool_name = ppapi::StringVar::StringToPPVar(llc_tool_name_str);
+    }
+  }
+
+  if (json_data.isMember("pnacl-ld-name")) {
+    Json::Value json_name = json_data["pnacl-ld-name"];
+    if (json_name.isString()) {
+      std::string ld_tool_name_str = json_name.asString();
+      *ld_tool_name = ppapi::StringVar::StringToPPVar(ld_tool_name_str);
+    }
+  }
+  return PP_TRUE;
+}
+
+// Helper to std::accumulate that creates a comma-separated list from the input.
+std::string CommaAccumulator(const std::string &lhs, const std::string &rhs) {
+  if (lhs.empty())
+    return rhs;
+  return lhs + "," + rhs;
+}
+
+PP_Var GetCpuFeatureAttrs() {
+  // PNaCl's translator from pexe to nexe can be told exactly what
+  // capabilities the user's machine has because the pexe to nexe
+  // translation is specific to the machine, and CPU information goes
+  // into the translation cache. This allows the translator to generate
+  // faster code.
+  //
+  // Care must be taken to avoid instructions which aren't supported by
+  // the NaCl sandbox. Ideally the translator would do this, but there's
+  // no point in not doing the whitelist here.
+  //
+  // TODO(jfb) Some features are missing, either because the NaCl
+  //           sandbox doesn't support them, because base::CPU doesn't
+  //           detect them, or because they don't help vector shuffles
+  //           (and we omit them because it simplifies testing). Add the
+  //           other features.
+  //
+  // TODO(jfb) The following is x86-specific. The base::CPU class
+  //           doesn't handle other architectures very well, and we
+  //           should at least detect the presence of ARM's integer
+  //           divide.
+  std::vector<std::string> attrs;
+  base::CPU cpu;
+
+  // On x86, SSE features are ordered: the most recent one implies the
+  // others. Care is taken here to only specify the latest SSE version,
+  // whereas non-SSE features don't follow this model: POPCNT is
+  // effectively always implied by SSE4.2 but has to be specified
+  // separately.
+  //
+  // TODO: AVX2, AVX, SSE 4.2.
+  if (cpu.has_sse41()) attrs.push_back("+sse4.1");
+  // TODO: SSE 4A, SSE 4.
+  else if (cpu.has_ssse3()) attrs.push_back("+ssse3");
+  // TODO: SSE 3
+  else if (cpu.has_sse2()) attrs.push_back("+sse2");
+
+  // TODO: AES, POPCNT, LZCNT, ...
+
+  return ppapi::StringVar::StringToPPVar(std::accumulate(
+      attrs.begin(), attrs.end(), std::string(), CommaAccumulator));
+}
+
 const PPB_NaCl_Private nacl_interface = {
   &LaunchSelLdr,
   &StartPpapiProxy,
@@ -889,7 +1270,15 @@
   &ProcessNaClManifest,
   &GetManifestURLArgument,
   &IsPNaCl,
-  &DevInterfacesEnabled
+  &DevInterfacesEnabled,
+  &DownloadManifestToBuffer,
+  &CreatePNaClManifest,
+  &CreateJsonManifest,
+  &DestroyManifest,
+  &ManifestGetProgramURL,
+  &ManifestResolveKey,
+  &GetPNaClResourceInfo,
+  &GetCpuFeatureAttrs
 };
 
 }  // namespace
diff --git a/components/nacl/zygote/nacl_fork_delegate_linux.cc b/components/nacl/zygote/nacl_fork_delegate_linux.cc
index ca373df..0e5f8e7 100644
--- a/components/nacl/zygote/nacl_fork_delegate_linux.cc
+++ b/components/nacl/zygote/nacl_fork_delegate_linux.cc
@@ -132,14 +132,6 @@
   fds_to_map.push_back(std::make_pair(fds[1], kNaClZygoteDescriptor));
   fds_to_map.push_back(std::make_pair(sandboxdesc, nacl_sandbox_descriptor));
 
-  // Make sure that nacl_loader is started with a dummy file descriptor. This
-  // is required because the setuid sandbox will always try to close a
-  // hard-wired file descriptor.
-  base::ScopedFD dummy_fd(socket(PF_UNIX, SOCK_DGRAM, 0));
-  CHECK(dummy_fd.is_valid());
-  fds_to_map.push_back(std::make_pair(
-      dummy_fd.get(), setuid_sandbox_client->GetUniqueToChildFileDescriptor()));
-
   // Using nacl_helper_bootstrap is not necessary on x86-64 because
   // NaCl's x86-64 sandbox is not zero-address-based.  Starting
   // nacl_helper through nacl_helper_bootstrap works on x86-64, but it
@@ -207,13 +199,16 @@
     }
 
     base::LaunchOptions options;
+
+    base::ScopedFD dummy_fd;
     if (enable_layer1_sandbox) {
-      // NaCl needs to keep tight control of the cmd_line, so
-      // pass NULL and prepend the setuid sandbox wrapper manually.
-      setuid_sandbox_client->PrependWrapper(NULL /* cmd_line */, &options);
+      // NaCl needs to keep tight control of the cmd_line, so prepend the
+      // setuid sandbox wrapper manually.
       base::FilePath sandbox_path =
           setuid_sandbox_client->GetSandboxBinaryPath();
       argv_to_launch.insert(argv_to_launch.begin(), sandbox_path.value());
+      setuid_sandbox_client->SetupLaunchOptions(
+          &options, &fds_to_map, &dummy_fd);
       setuid_sandbox_client->SetupLaunchEnvironment();
     }
 
@@ -232,6 +227,11 @@
     if (!base::LaunchProcess(argv_to_launch, options, NULL))
       status_ = kNaClHelperLaunchFailed;
     // parent and error cases are handled below
+
+    if (enable_layer1_sandbox) {
+      // Sanity check that dummy_fd was kept alive for LaunchProcess.
+      DCHECK(dummy_fd.is_valid());
+    }
   }
   if (IGNORE_EINTR(close(fds[1])) != 0)
     LOG(ERROR) << "close(fds[1]) failed";
diff --git a/components/navigation_interception.gypi b/components/navigation_interception.gypi
index f973004..97d54b7 100644
--- a/components/navigation_interception.gypi
+++ b/components/navigation_interception.gypi
@@ -4,76 +4,72 @@
 # found in the LICENSE file.
 
 {
-  'conditions': [
-    ['OS != "ios"', {
-      'targets': [
-        {
-          'target_name': 'navigation_interception',
-          'type': 'static_library',
-          'defines!': ['CONTENT_IMPLEMENTATION'],
-          'dependencies': [
-            '../base/base.gyp:base',
-            '../content/content.gyp:content_browser',
-            '../content/content.gyp:content_common',
-            '../net/net.gyp:net',
-          ],
-          'include_dirs': [
-            '..',
-            '../skia/config',
-          ],
-          'sources': [
-            'navigation_interception/intercept_navigation_resource_throttle.cc',
-            'navigation_interception/intercept_navigation_resource_throttle.h',
-            'navigation_interception/navigation_params.h',
-            'navigation_interception/navigation_params.cc',
-          ],
-          'conditions': [
-            ['OS=="android"', {
-              'dependencies': [
-                  'navigation_interception_jni_headers',
-              ],
-              'sources': [
-                'navigation_interception/component_jni_registrar.cc',
-                'navigation_interception/component_jni_registrar.h',
-                'navigation_interception/intercept_navigation_delegate.cc',
-                'navigation_interception/intercept_navigation_delegate.h',
-                'navigation_interception/navigation_params_android.h',
-                'navigation_interception/navigation_params_android.cc',
-              ],
-            }],
-          ],
-        },
+  'targets': [
+    {
+      'target_name': 'navigation_interception',
+      'type': 'static_library',
+      'defines!': ['CONTENT_IMPLEMENTATION'],
+      'dependencies': [
+        '../base/base.gyp:base',
+        '../content/content.gyp:content_browser',
+        '../content/content.gyp:content_common',
+        '../net/net.gyp:net',
+      ],
+      'include_dirs': [
+        '..',
+        '../skia/config',
+      ],
+      'sources': [
+        'navigation_interception/intercept_navigation_resource_throttle.cc',
+        'navigation_interception/intercept_navigation_resource_throttle.h',
+        'navigation_interception/navigation_params.h',
+        'navigation_interception/navigation_params.cc',
       ],
       'conditions': [
         ['OS=="android"', {
-          'targets': [
-            {
-              'target_name': 'navigation_interception_java',
-              'type': 'none',
-              'dependencies': [
-                '../base/base.gyp:base',
-              ],
-              'variables': {
-                'java_in_dir': 'navigation_interception/android/java',
-              },
-              'includes': [ '../build/java.gypi' ],
-            },
-            {
-              'target_name': 'navigation_interception_jni_headers',
-              'type': 'none',
-              'sources': [
-                'navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java',
-                'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java',
-              ],
-              'variables': {
-                'jni_gen_package': 'navigation_interception',
-                'jni_generator_ptr_type': 'long',
-              },
-              'includes': [ '../build/jni_generator.gypi' ],
-            },
+          'dependencies': [
+            'navigation_interception_jni_headers',
+          ],
+          'sources': [
+            'navigation_interception/component_jni_registrar.cc',
+            'navigation_interception/component_jni_registrar.h',
+            'navigation_interception/intercept_navigation_delegate.cc',
+            'navigation_interception/intercept_navigation_delegate.h',
+            'navigation_interception/navigation_params_android.h',
+            'navigation_interception/navigation_params_android.cc',
           ],
         }],
       ],
+    },
+  ],
+  'conditions': [
+    ['OS=="android"', {
+      'targets': [
+        {
+          'target_name': 'navigation_interception_java',
+          'type': 'none',
+          'dependencies': [
+            '../base/base.gyp:base',
+          ],
+          'variables': {
+            'java_in_dir': 'navigation_interception/android/java',
+          },
+          'includes': [ '../build/java.gypi' ],
+        },
+        {
+          'target_name': 'navigation_interception_jni_headers',
+          'type': 'none',
+          'sources': [
+            'navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java',
+            'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java',
+          ],
+          'variables': {
+            'jni_gen_package': 'navigation_interception',
+            'jni_generator_ptr_type': 'long',
+          },
+          'includes': [ '../build/jni_generator.gypi' ],
+        },
+      ],
     }],
   ],
 }
diff --git a/components/navigation_interception.target.darwin-arm.mk b/components/navigation_interception.target.darwin-arm.mk
index b58d4b8..1758994 100644
--- a/components/navigation_interception.target.darwin-arm.mk
+++ b/components/navigation_interception.target.darwin-arm.mk
@@ -47,7 +47,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -144,7 +143,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/navigation_interception.target.darwin-x86.mk b/components/navigation_interception.target.darwin-x86.mk
index 7bb7e1b..12a4257 100644
--- a/components/navigation_interception.target.darwin-x86.mk
+++ b/components/navigation_interception.target.darwin-x86.mk
@@ -49,7 +49,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -145,7 +144,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/navigation_interception.target.darwin-x86_64.mk b/components/navigation_interception.target.darwin-x86_64.mk
index 917565b..840421b 100644
--- a/components/navigation_interception.target.darwin-x86_64.mk
+++ b/components/navigation_interception.target.darwin-x86_64.mk
@@ -49,7 +49,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,7 +145,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/navigation_interception.target.linux-arm.mk b/components/navigation_interception.target.linux-arm.mk
index b58d4b8..1758994 100644
--- a/components/navigation_interception.target.linux-arm.mk
+++ b/components/navigation_interception.target.linux-arm.mk
@@ -47,7 +47,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -144,7 +143,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/navigation_interception.target.linux-x86.mk b/components/navigation_interception.target.linux-x86.mk
index 7bb7e1b..12a4257 100644
--- a/components/navigation_interception.target.linux-x86.mk
+++ b/components/navigation_interception.target.linux-x86.mk
@@ -49,7 +49,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -145,7 +144,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/navigation_interception.target.linux-x86_64.mk b/components/navigation_interception.target.linux-x86_64.mk
index 917565b..840421b 100644
--- a/components/navigation_interception.target.linux-x86_64.mk
+++ b/components/navigation_interception.target.linux-x86_64.mk
@@ -49,7 +49,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,7 +145,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/navigation_interception_jni_headers.target.darwin-arm.mk b/components/navigation_interception_jni_headers.target.darwin-arm.mk
index 6a0b17d..223d8db 100644
--- a/components/navigation_interception_jni_headers.target.darwin-arm.mk
+++ b/components/navigation_interception_jni_headers.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_navigation_interception_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/navigation_interception/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java', 'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/navigation_interception/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +66,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -148,7 +149,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/navigation_interception_jni_headers.target.darwin-arm64.mk b/components/navigation_interception_jni_headers.target.darwin-arm64.mk
index 3ade4f0..74e1184 100644
--- a/components/navigation_interception_jni_headers.target.darwin-arm64.mk
+++ b/components/navigation_interception_jni_headers.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_navigation_interception_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/navigation_interception/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java', 'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/navigation_interception/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/navigation_interception_jni_headers.target.darwin-mips.mk b/components/navigation_interception_jni_headers.target.darwin-mips.mk
index 13e60e0..26cb65f 100644
--- a/components/navigation_interception_jni_headers.target.darwin-mips.mk
+++ b/components/navigation_interception_jni_headers.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_navigation_interception_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/navigation_interception/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java', 'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/navigation_interception/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/navigation_interception_jni_headers.target.darwin-x86.mk b/components/navigation_interception_jni_headers.target.darwin-x86.mk
index 6f93d18..31b6128 100644
--- a/components/navigation_interception_jni_headers.target.darwin-x86.mk
+++ b/components/navigation_interception_jni_headers.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_navigation_interception_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/navigation_interception/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java', 'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/navigation_interception/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +68,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +151,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/navigation_interception_jni_headers.target.darwin-x86_64.mk b/components/navigation_interception_jni_headers.target.darwin-x86_64.mk
index cdb8670..f9830a6 100644
--- a/components/navigation_interception_jni_headers.target.darwin-x86_64.mk
+++ b/components/navigation_interception_jni_headers.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_navigation_interception_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/navigation_interception/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java', 'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/navigation_interception/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +68,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +151,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/navigation_interception_jni_headers.target.linux-arm.mk b/components/navigation_interception_jni_headers.target.linux-arm.mk
index 6a0b17d..223d8db 100644
--- a/components/navigation_interception_jni_headers.target.linux-arm.mk
+++ b/components/navigation_interception_jni_headers.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_navigation_interception_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/navigation_interception/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java', 'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/navigation_interception/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +66,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -148,7 +149,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/navigation_interception_jni_headers.target.linux-arm64.mk b/components/navigation_interception_jni_headers.target.linux-arm64.mk
index 3ade4f0..74e1184 100644
--- a/components/navigation_interception_jni_headers.target.linux-arm64.mk
+++ b/components/navigation_interception_jni_headers.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_navigation_interception_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/navigation_interception/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java', 'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/navigation_interception/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/navigation_interception_jni_headers.target.linux-mips.mk b/components/navigation_interception_jni_headers.target.linux-mips.mk
index 13e60e0..26cb65f 100644
--- a/components/navigation_interception_jni_headers.target.linux-mips.mk
+++ b/components/navigation_interception_jni_headers.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_navigation_interception_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/navigation_interception/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java', 'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/navigation_interception/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/navigation_interception_jni_headers.target.linux-x86.mk b/components/navigation_interception_jni_headers.target.linux-x86.mk
index 6f93d18..31b6128 100644
--- a/components/navigation_interception_jni_headers.target.linux-x86.mk
+++ b/components/navigation_interception_jni_headers.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_navigation_interception_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/navigation_interception/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java', 'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/navigation_interception/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +68,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +151,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/navigation_interception_jni_headers.target.linux-x86_64.mk b/components/navigation_interception_jni_headers.target.linux-x86_64.mk
index cdb8670..f9830a6 100644
--- a/components/navigation_interception_jni_headers.target.linux-x86_64.mk
+++ b/components/navigation_interception_jni_headers.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_navigation_interception_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/navigation_interception/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['navigation_interception/android/java/src/org/chromium/components/navigation_interception/InterceptNavigationDelegate.java', 'navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/navigation_interception/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/InterceptNavigationDelegate_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/navigation_interception/jni/NavigationParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +68,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +151,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/onc/onc_constants.cc b/components/onc/onc_constants.cc
index be564cf..260d19a 100644
--- a/components/onc/onc_constants.cc
+++ b/components/onc/onc_constants.cc
@@ -41,8 +41,9 @@
 const char kNameServers[] = "NameServers";
 const char kProxySettings[] = "ProxySettings";
 const char kSearchDomains[] = "SearchDomains";
-const char kServicePath[] = "ServicePath";
 const char kConnectionState[] = "ConnectionState";
+const char kConnectable[] = "Connectable";
+const char kErrorState[] = "ErrorState";
 const char kType[] = "Type";
 const char kVPN[] = "VPN";
 const char kWiFi[] = "WiFi";
diff --git a/components/onc/onc_constants.h b/components/onc/onc_constants.h
index e99c7f6..c68536a 100644
--- a/components/onc/onc_constants.h
+++ b/components/onc/onc_constants.h
@@ -65,8 +65,9 @@
 ONC_EXPORT extern const char kNameServers[];
 ONC_EXPORT extern const char kProxySettings[];
 ONC_EXPORT extern const char kSearchDomains[];
-ONC_EXPORT extern const char kServicePath[];
 ONC_EXPORT extern const char kConnectionState[];
+ONC_EXPORT extern const char kConnectable[];
+ONC_EXPORT extern const char kErrorState[];
 ONC_EXPORT extern const char kType[];
 ONC_EXPORT extern const char kVPN[];
 ONC_EXPORT extern const char kWiFi[];
diff --git a/components/os_crypt.target.darwin-arm.mk b/components/os_crypt.target.darwin-arm.mk
index 16ac652..b7b8aa7 100644
--- a/components/os_crypt.target.darwin-arm.mk
+++ b/components/os_crypt.target.darwin-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -128,7 +127,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/os_crypt.target.darwin-x86.mk b/components/os_crypt.target.darwin-x86.mk
index deebdd3..523f83a 100644
--- a/components/os_crypt.target.darwin-x86.mk
+++ b/components/os_crypt.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/os_crypt.target.darwin-x86_64.mk b/components/os_crypt.target.darwin-x86_64.mk
index 8fd3d88..a5066e3 100644
--- a/components/os_crypt.target.darwin-x86_64.mk
+++ b/components/os_crypt.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/os_crypt.target.linux-arm.mk b/components/os_crypt.target.linux-arm.mk
index 16ac652..b7b8aa7 100644
--- a/components/os_crypt.target.linux-arm.mk
+++ b/components/os_crypt.target.linux-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -128,7 +127,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/os_crypt.target.linux-x86.mk b/components/os_crypt.target.linux-x86.mk
index deebdd3..523f83a 100644
--- a/components/os_crypt.target.linux-x86.mk
+++ b/components/os_crypt.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/os_crypt.target.linux-x86_64.mk b/components/os_crypt.target.linux-x86_64.mk
index 8fd3d88..a5066e3 100644
--- a/components/os_crypt.target.linux-x86_64.mk
+++ b/components/os_crypt.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/os_crypt/DEPS b/components/os_crypt/DEPS
index d175bda..60ae095 100644
--- a/components/os_crypt/DEPS
+++ b/components/os_crypt/DEPS
@@ -1,4 +1,3 @@
 include_rules = [
-  "-content",
   "+crypto"
 ]
diff --git a/components/password_manager.gypi b/components/password_manager.gypi
index 82ba89e..58f7370 100644
--- a/components/password_manager.gypi
+++ b/components/password_manager.gypi
@@ -49,6 +49,8 @@
         'password_manager/core/browser/password_store_consumer.h',
         'password_manager/core/browser/password_store_default.cc',
         'password_manager/core/browser/password_store_default.h',
+        'password_manager/core/browser/password_store_sync.cc',
+        'password_manager/core/browser/password_store_sync.h',
         'password_manager/core/browser/psl_matching_helper.cc',
         'password_manager/core/browser/psl_matching_helper.h',
       ],
@@ -129,6 +131,8 @@
         'password_manager/core/common/password_manager_pref_names.h',
         'password_manager/core/common/password_manager_switches.cc',
         'password_manager/core/common/password_manager_switches.h',
+        'password_manager/core/common/password_manager_ui.cc',
+        'password_manager/core/common/password_manager_ui.h',
       ],
     },
   ],
diff --git a/components/password_manager/DEPS b/components/password_manager/DEPS
index 60c4b7c..2e79291 100644
--- a/components/password_manager/DEPS
+++ b/components/password_manager/DEPS
@@ -9,6 +9,5 @@
   "+ui",
   # PasswordManager is a layered component; subdirectories must explicitly
   # introduce the ability to use the content layer as appropriate.
-  "-content/public/common",
-  "-ipc",
+  "-components/password_manager/content",
 ]
diff --git a/components/password_manager/core/browser/mock_password_store.h b/components/password_manager/core/browser/mock_password_store.h
index b903678..8fc8794 100644
--- a/components/password_manager/core/browser/mock_password_store.h
+++ b/components/password_manager/core/browser/mock_password_store.h
@@ -47,6 +47,8 @@
   MOCK_METHOD1(FillBlacklistLogins,
       bool(std::vector<autofill::PasswordForm*>*));
 
+  PasswordStoreSync* GetSyncInterface() { return this; }
+
  protected:
   virtual ~MockPasswordStore();
 };
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index 70fc1e5..ed2981c 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -409,7 +409,7 @@
 
   // Check to see if the user told us to ignore this site in the past.
   if (preferred_match_->blacklisted_by_user) {
-    client_->PasswordAutofillWasBlocked();
+    client_->PasswordAutofillWasBlocked(best_matches_);
     manager_action_ = kManagerActionBlacklisted;
     return;
   }
@@ -633,18 +633,21 @@
 int PasswordFormManager::ScoreResult(const PasswordForm& candidate) const {
   DCHECK_EQ(state_, MATCHING_PHASE);
   // For scoring of candidate login data:
-  // The most important element that should match is the origin, followed by
-  // the action, the password name, the submit button name, and finally the
-  // username input field name.
+  // The most important element that should match is the signon_realm followed
+  // by the origin, the action, the password name, the submit button name, and
+  // finally the username input field name.
+  // If public suffix origin match was not used, it gives an addition of
+  // 128 (1 << 7).
   // Exact origin match gives an addition of 64 (1 << 6) + # of matching url
   // dirs.
   // Partial match gives an addition of 32 (1 << 5) + # matching url dirs
   // That way, a partial match cannot trump an exact match even if
   // the partial one matches all other attributes (action, elements) (and
   // regardless of the matching depth in the URL path).
-  // If public suffix origin match was not used, it gives an addition of
-  // 16 (1 << 4).
   int score = 0;
+  if (!candidate.IsPublicSuffixMatch()) {
+    score += 1 << 7;
+  }
   if (candidate.origin == observed_form_.origin) {
     // This check is here for the most common case which
     // is we have a single match in the db for the given host,
@@ -668,8 +671,6 @@
     score += (depth > 0) ? 1 << 5 : 0;
   }
   if (observed_form_.scheme == PasswordForm::SCHEME_HTML) {
-    if (!candidate.IsPublicSuffixMatch())
-      score += 1 << 4;
     if (candidate.action == observed_form_.action)
       score += 1 << 3;
     if (candidate.password_element == observed_form_.password_element)
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index 5a0b5b1..0e76081 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -687,4 +687,34 @@
   form_manager.Save();
 }
 
+TEST_F(PasswordFormManagerTest, TestScoringPublicSuffixMatch) {
+  base::MessageLoop message_loop;
+
+  TestPasswordManagerClient client(NULL);
+  MockPasswordManagerDriver driver;
+  EXPECT_CALL(driver, IsOffTheRecord()).WillRepeatedly(Return(false));
+  EXPECT_CALL(driver, AllowPasswordGenerationForForm(_));
+
+  TestPasswordManager password_manager(&client);
+  scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
+    &password_manager, &client, &driver, *observed_form(), false));
+
+  // Simulate having two matches for this form, first comes from different
+  // signon realm, but reports the same origin and action as matched form.
+  // Second candidate has the same signon realm as the form, but has a different
+  // origin and action. Public suffix match is the most important criterion so
+  // the second candidate should be selected.
+  std::vector<PasswordForm*> results;
+  results.push_back(CreateSavedMatch(false));
+  results.push_back(CreateSavedMatch(false));
+  results[0]->original_signon_realm = "http://accounts2.google.com";
+  results[1]->origin = GURL("http://accounts.google.com/a/ServiceLoginAuth2");
+  results[1]->action = GURL("http://accounts.google.com/a/ServiceLogin2");
+  SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
+  SimulateResponseFromPasswordStore(manager.get(), results);
+  EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
+  EXPECT_EQ("", password_manager.GetLatestBestMatches().begin()
+      ->second->original_signon_realm);
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h
index 9f9c368..3793865 100644
--- a/components/password_manager/core/browser/password_manager_client.h
+++ b/components/password_manager/core/browser/password_manager_client.h
@@ -36,13 +36,19 @@
   // that this form doesn't need to be saved.
   virtual void PromptUserToSavePassword(PasswordFormManager* form_to_save) = 0;
 
-  // Called when a password is autofilled. Default implementation is a no-op.
+  // Called when a password is autofilled. |best_matches| contains the
+  // PasswordForm into which a password was filled: the client may choose to
+  // save this to the PasswordStore, for example. Default implementation is a
+  // noop.
   virtual void PasswordWasAutofilled(
       const autofill::PasswordFormMap& best_matches) const {}
 
-  // Called when password autofill is blocked by the blacklist. Default
-  // implementation is a no-op.
-  virtual void PasswordAutofillWasBlocked() const {}
+  // Called when password autofill is blocked by the blacklist. |best_matches|
+  // contains the PasswordForm that flags the current site as being on the
+  // blacklist. The client may choose to remove this from the PasswordStore in
+  // order to unblacklist a site, for example. Default implementation is a noop.
+  virtual void PasswordAutofillWasBlocked(
+      const autofill::PasswordFormMap& best_matches) const {}
 
   // Called to authenticate the autofill password data.  If authentication is
   // successful, this should continue filling the form.
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.h b/components/password_manager/core/browser/password_manager_metrics_util.h
index 3ae22d4..e74b97a 100644
--- a/components/password_manager/core/browser/password_manager_metrics_util.h
+++ b/components/password_manager/core/browser/password_manager_metrics_util.h
@@ -27,6 +27,7 @@
   AUTOMATIC_WITH_PASSWORD_PENDING = 0,
   MANUAL_WITH_PASSWORD_PENDING,
   MANUAL_MANAGE_PASSWORDS,
+  MANUAL_BLACKLISTED,
   NUM_DISPLAY_DISPOSITIONS
 };
 
@@ -40,6 +41,7 @@
   CLICKED_NEVER,
   CLICKED_MANAGE,
   CLICKED_DONE,
+  CLICKED_UNBLACKLIST,
   NUM_UI_RESPONSES,
 
   // If we add the omnibox icon _without_ intending to display the bubble,
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc
index b23b3ec..0dd5684 100644
--- a/components/password_manager/core/browser/password_store.cc
+++ b/components/password_manager/core/browser/password_store.cc
@@ -163,6 +163,14 @@
   observers_->RemoveObserver(observer);
 }
 
+bool PasswordStore::ScheduleTask(const base::Closure& task) {
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner(
+      GetBackgroundTaskRunner());
+  if (task_runner.get())
+    return task_runner->PostTask(FROM_HERE, task);
+  return false;
+}
+
 void PasswordStore::Shutdown() {
 #if defined(PASSWORD_MANAGER_ENABLE_SYNC)
   ScheduleTask(base::Bind(&PasswordStore::DestroySyncableService, this));
@@ -181,14 +189,6 @@
 
 PasswordStore::~PasswordStore() { DCHECK(shutdown_called_); }
 
-bool PasswordStore::ScheduleTask(const base::Closure& task) {
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner(
-      GetBackgroundTaskRunner());
-  if (task_runner.get())
-    return task_runner->PostTask(FROM_HERE, task);
-  return false;
-}
-
 scoped_refptr<base::SingleThreadTaskRunner>
 PasswordStore::GetBackgroundTaskRunner() {
   return db_thread_runner_;
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h
index d2448d0..6bb063d 100644
--- a/components/password_manager/core/browser/password_store.h
+++ b/components/password_manager/core/browser/password_store.h
@@ -16,6 +16,7 @@
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
 #include "components/password_manager/core/browser/password_store_change.h"
+#include "components/password_manager/core/browser/password_store_sync.h"
 #include "sync/api/syncable_service.h"
 
 class Task;
@@ -56,7 +57,10 @@
 // Interface for storing form passwords in a platform-specific secure way.
 // The login request/manipulation API is not threadsafe and must be used
 // from the UI thread.
-class PasswordStore : public base::RefCountedThreadSafe<PasswordStore> {
+// PasswordStoreSync is a hidden base class because only PasswordSyncableService
+// needs to access these methods.
+class PasswordStore : protected PasswordStoreSync,
+                      public base::RefCountedThreadSafe<PasswordStore> {
  public:
   // Whether or not it's acceptable for Chrome to request access to locked
   // passwords, which requires prompting the user for permission.
@@ -169,6 +173,9 @@
   // Removes |observer| from the observer list.
   void RemoveObserver(Observer* observer);
 
+  // Schedules the given |task| to be run on the PasswordStore's TaskRunner.
+  bool ScheduleTask(const base::Closure& task);
+
   // Before you destruct the store, call Shutdown to indicate that the store
   // needs to shut itself down.
   virtual void Shutdown();
@@ -179,47 +186,31 @@
 
  protected:
   friend class base::RefCountedThreadSafe<PasswordStore>;
-  // Sync's interaction with password store needs to be synchronous.
-  // Since the synchronous methods are private these classes are made
-  // as friends. This can be fixed by moving the private impl to a new
-  // class. See http://crbug.com/307750
-  friend class browser_sync::PasswordChangeProcessor;
-  friend class browser_sync::PasswordDataTypeController;
-  friend class browser_sync::PasswordModelAssociator;
-  friend class browser_sync::PasswordModelWorker;
-  friend class PasswordSyncableService;
-  friend void passwords_helper::AddLogin(PasswordStore*,
-                                         const autofill::PasswordForm&);
-  friend void passwords_helper::RemoveLogin(PasswordStore*,
-                                            const autofill::PasswordForm&);
-  friend void passwords_helper::UpdateLogin(PasswordStore*,
-                                            const autofill::PasswordForm&);
   FRIEND_TEST_ALL_PREFIXES(PasswordStoreTest, IgnoreOldWwwGoogleLogins);
 
   typedef base::Callback<PasswordStoreChangeList(void)> ModificationTask;
 
   virtual ~PasswordStore();
 
-  // Schedules the given |task| to be run on the PasswordStore's TaskRunner.
-  bool ScheduleTask(const base::Closure& task);
-
   // Get the TaskRunner to use for PasswordStore background tasks.
   // By default, a SingleThreadTaskRunner on the DB thread is used, but
   // subclasses can override.
   virtual scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner();
 
-  // These will be run in PasswordStore's own thread.
+  // Methods below will be run in PasswordStore's own thread.
   // Synchronous implementation that reports usage metrics.
   virtual void ReportMetricsImpl() = 0;
-  // Synchronous implementation to add the given login.
+
+  // Bring PasswordStoreSync methods to the scope of PasswordStore. Otherwise,
+  // base::Bind can't be used with them because it fails to cast PasswordStore
+  // to PasswordStoreSync.
   virtual PasswordStoreChangeList AddLoginImpl(
       const autofill::PasswordForm& form) = 0;
-  // Synchronous implementation to update the given login.
   virtual PasswordStoreChangeList UpdateLoginImpl(
       const autofill::PasswordForm& form) = 0;
-  // Synchronous implementation to remove the given login.
   virtual PasswordStoreChangeList RemoveLoginImpl(
       const autofill::PasswordForm& form) = 0;
+
   // Synchronous implementation to remove the given logins.
   virtual PasswordStoreChangeList RemoveLoginsCreatedBetweenImpl(
       const base::Time& delete_begin, const base::Time& delete_end) = 0;
@@ -241,14 +232,6 @@
   // Finds all blacklist PasswordForms, and notifies the consumer.
   virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) = 0;
 
-  // Finds all non-blacklist PasswordForms, and fills the vector.
-  virtual bool FillAutofillableLogins(
-      std::vector<autofill::PasswordForm*>* forms) = 0;
-
-  // Finds all blacklist PasswordForms, and fills the vector.
-  virtual bool FillBlacklistLogins(
-      std::vector<autofill::PasswordForm*>* forms) = 0;
-
   // Dispatches the result to the PasswordStoreConsumer on the original caller's
   // thread so the callback can be executed there. This should be the UI thread.
   virtual void ForwardLoginsResult(GetLoginsRequest* request);
@@ -278,10 +261,12 @@
   // method will actually modify the password store data.
   virtual void WrapModificationTask(ModificationTask task);
 
+  // PasswordStoreSync:
   // Called by WrapModificationTask() once the underlying data-modifying
   // operation has been performed. Notifies observers that password store data
   // may have been changed.
-  void NotifyLoginsChanged(const PasswordStoreChangeList& changes);
+  virtual void NotifyLoginsChanged(
+      const PasswordStoreChangeList& changes) OVERRIDE;
 
   // Copies |matched_forms| into the request's result vector, then calls
   // |ForwardLoginsResult|. Temporarily used as an adapter between the API of
diff --git a/components/password_manager/core/browser/password_store_default.cc b/components/password_manager/core/browser/password_store_default.cc
index 5ee4968..8997c6f 100644
--- a/components/password_manager/core/browser/password_store_default.cc
+++ b/components/password_manager/core/browser/password_store_default.cc
@@ -33,6 +33,7 @@
 
 PasswordStoreChangeList PasswordStoreDefault::AddLoginImpl(
     const PasswordForm& form) {
+  DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
   PasswordStoreChangeList changes;
   if (login_db_->AddLogin(form))
     changes.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
@@ -41,6 +42,7 @@
 
 PasswordStoreChangeList PasswordStoreDefault::UpdateLoginImpl(
     const PasswordForm& form) {
+  DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
   PasswordStoreChangeList changes;
   if (login_db_->UpdateLogin(form, NULL))
     changes.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE, form));
@@ -49,6 +51,7 @@
 
 PasswordStoreChangeList PasswordStoreDefault::RemoveLoginImpl(
     const PasswordForm& form) {
+  DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
   PasswordStoreChangeList changes;
   if (login_db_->RemoveLogin(form))
     changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form));
diff --git a/components/password_manager/core/browser/password_store_sync.cc b/components/password_manager/core/browser/password_store_sync.cc
new file mode 100644
index 0000000..a1d0d49
--- /dev/null
+++ b/components/password_manager/core/browser/password_store_sync.cc
@@ -0,0 +1,11 @@
+// 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.
+
+#include "components/password_manager/core/browser/password_store_sync.h"
+
+namespace password_manager {
+
+PasswordStoreSync::~PasswordStoreSync() {}
+
+}  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_sync.h b/components/password_manager/core/browser/password_store_sync.h
new file mode 100644
index 0000000..d984bad
--- /dev/null
+++ b/components/password_manager/core/browser/password_store_sync.h
@@ -0,0 +1,49 @@
+// 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.
+
+#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_SYNC_INTERFACE_H_
+#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_SYNC_INTERFACE_H_
+
+#include <vector>
+
+#include "components/password_manager/core/browser/password_store_change.h"
+
+namespace password_manager {
+
+// PasswordStore interface for PasswordSyncableService. It provides access to
+// synchronous methods of PasswordStore which shouldn't be accessible to other
+// classes. These methods are to be called on the PasswordStore background
+// thread only.
+class PasswordStoreSync {
+ public:
+  // Finds all non-blacklist PasswordForms, and fills the vector.
+  virtual bool FillAutofillableLogins(
+      std::vector<autofill::PasswordForm*>* forms) = 0;
+
+  // Finds all blacklist PasswordForms, and fills the vector.
+  virtual bool FillBlacklistLogins(
+      std::vector<autofill::PasswordForm*>* forms) = 0;
+
+  // Synchronous implementation to add the given login.
+  virtual PasswordStoreChangeList AddLoginImpl(
+      const autofill::PasswordForm& form) = 0;
+
+  // Synchronous implementation to update the given login.
+  virtual PasswordStoreChangeList UpdateLoginImpl(
+      const autofill::PasswordForm& form) = 0;
+
+  // Synchronous implementation to remove the given login.
+  virtual PasswordStoreChangeList RemoveLoginImpl(
+      const autofill::PasswordForm& form) = 0;
+
+  // Notifies observers that password store data may have been changed.
+  virtual void NotifyLoginsChanged(const PasswordStoreChangeList& changes) = 0;
+
+ protected:
+  virtual ~PasswordStoreSync();
+};
+
+}  // namespace password_manager
+
+#endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_SYNC_INTERFACE_H_
diff --git a/components/password_manager/core/browser/password_syncable_service.cc b/components/password_manager/core/browser/password_syncable_service.cc
index 5d2f674..ae886fa 100644
--- a/components/password_manager/core/browser/password_syncable_service.cc
+++ b/components/password_manager/core/browser/password_syncable_service.cc
@@ -10,7 +10,7 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/common/password_form.h"
-#include "components/password_manager/core/browser/password_store.h"
+#include "components/password_manager/core/browser/password_store_sync.h"
 #include "net/base/escape.h"
 #include "sync/api/sync_error_factory.h"
 
@@ -109,7 +109,8 @@
 
 }  // namespace
 
-PasswordSyncableService::PasswordSyncableService(PasswordStore* password_store)
+PasswordSyncableService::PasswordSyncableService(
+    PasswordStoreSync* password_store)
     : password_store_(password_store),
       is_processing_sync_changes_(false) {
 }
diff --git a/components/password_manager/core/browser/password_syncable_service.h b/components/password_manager/core/browser/password_syncable_service.h
index a385c1c..b70ea1f 100644
--- a/components/password_manager/core/browser/password_syncable_service.h
+++ b/components/password_manager/core/browser/password_syncable_service.h
@@ -32,13 +32,13 @@
 
 namespace password_manager {
 
-class PasswordStore;
+class PasswordStoreSync;
 
 class PasswordSyncableService : public syncer::SyncableService,
                                 public base::NonThreadSafe {
  public:
   // |PasswordSyncableService| is owned by |PasswordStore|.
-  explicit PasswordSyncableService(PasswordStore* password_store);
+  explicit PasswordSyncableService(PasswordStoreSync* password_store);
   virtual ~PasswordSyncableService();
 
   // syncer::SyncableServiceImplementations
@@ -107,7 +107,7 @@
   scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
 
   // The password store that adds/updates/deletes password entries.
-  PasswordStore* const password_store_;
+  PasswordStoreSync* const password_store_;
 
   // A signal to start sync as soon as possible.
   syncer::SyncableService::StartSyncFlare flare_;
diff --git a/components/password_manager/core/browser/password_syncable_service_unittest.cc b/components/password_manager/core/browser/password_syncable_service_unittest.cc
index d39bc73..ce78669 100644
--- a/components/password_manager/core/browser/password_syncable_service_unittest.cc
+++ b/components/password_manager/core/browser/password_syncable_service_unittest.cc
@@ -86,7 +86,7 @@
 // out all interaction with the password database.
 class MockPasswordSyncableService : public PasswordSyncableService {
  public:
-  explicit MockPasswordSyncableService(PasswordStore* password_store)
+  explicit MockPasswordSyncableService(PasswordStoreSync* password_store)
       : PasswordSyncableService(password_store) {}
   virtual ~MockPasswordSyncableService() {}
 
@@ -279,7 +279,8 @@
  public:
   PasswordSyncableServiceWrapper() {
     password_store_ = new MockPasswordStore;
-    service_.reset(new MockPasswordSyncableService(password_store_));
+    service_.reset(new MockPasswordSyncableService(
+        password_store_->GetSyncInterface()));
   }
 
   ~PasswordSyncableServiceWrapper() {
diff --git a/components/password_manager/core/browser/test_password_store.cc b/components/password_manager/core/browser/test_password_store.cc
index 2ea0dc9..555eb70 100644
--- a/components/password_manager/core/browser/test_password_store.cc
+++ b/components/password_manager/core/browser/test_password_store.cc
@@ -15,7 +15,8 @@
 
 TestPasswordStore::~TestPasswordStore() {}
 
-TestPasswordStore::PasswordMap TestPasswordStore::stored_passwords() {
+const TestPasswordStore::PasswordMap& TestPasswordStore::stored_passwords()
+    const {
   return stored_passwords_;
 }
 
@@ -23,6 +24,18 @@
   stored_passwords_.clear();
 }
 
+bool TestPasswordStore::IsEmpty() const {
+  // The store is empty, if the sum of all stored passwords across all entries
+  // in |stored_passwords_| is 0.
+  size_t number_of_passwords = 0u;
+  for (PasswordMap::const_iterator it = stored_passwords_.begin();
+       !number_of_passwords && it != stored_passwords_.end();
+       ++it) {
+    number_of_passwords += it->second.size();
+  }
+  return number_of_passwords == 0u;
+}
+
 bool TestPasswordStore::FormsAreEquivalent(const autofill::PasswordForm& lhs,
                                            const autofill::PasswordForm& rhs) {
   return lhs.origin == rhs.origin &&
diff --git a/components/password_manager/core/browser/test_password_store.h b/components/password_manager/core/browser/test_password_store.h
index 498cb86..fb0b477 100644
--- a/components/password_manager/core/browser/test_password_store.h
+++ b/components/password_manager/core/browser/test_password_store.h
@@ -29,9 +29,14 @@
   typedef std::map<std::string /* signon_realm */,
                    std::vector<autofill::PasswordForm> > PasswordMap;
 
-  PasswordMap stored_passwords();
+  const PasswordMap& stored_passwords() const;
   void Clear();
 
+  // Returns true if no passwords are stored in the store. Note that this is not
+  // as simple as asking whether stored_passwords().empty(), because the map can
+  // have entries of size 0.
+  bool IsEmpty() const;
+
  protected:
   virtual ~TestPasswordStore();
 
diff --git a/components/password_manager/core/common/password_manager_ui.cc b/components/password_manager/core/common/password_manager_ui.cc
new file mode 100644
index 0000000..4b6e7d5
--- /dev/null
+++ b/components/password_manager/core/common/password_manager_ui.cc
@@ -0,0 +1,18 @@
+// 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.
+
+#include "components/password_manager/core/common/password_manager_ui.h"
+
+namespace password_manager {
+
+namespace ui {
+
+bool IsPendingState(State state) {
+  return state == PENDING_PASSWORD_AND_BUBBLE_STATE ||
+         state == PENDING_PASSWORD_STATE;
+}
+
+}  // namespace ui
+
+}  // namespace password_manager
diff --git a/components/password_manager/core/common/password_manager_ui.h b/components/password_manager/core/common/password_manager_ui.h
new file mode 100644
index 0000000..9f28a40
--- /dev/null
+++ b/components/password_manager/core/common/password_manager_ui.h
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_COMMON_PASSWORD_MANAGER_UI_H_
+#define COMPONENTS_PASSWORD_MANAGER_CORE_COMMON_PASSWORD_MANAGER_UI_H_
+
+#include "base/basictypes.h"
+
+namespace password_manager {
+
+namespace ui {
+
+// The current state of the password manager's UI.
+enum State {
+  // The password manager has nothing to do with the current site.
+  INACTIVE_STATE,
+
+  // A password has been typed in and submitted successfully. Now we need to
+  // display an Omnibox icon, and pop up a bubble asking the user whether
+  // they'd like to save the password.
+  PENDING_PASSWORD_AND_BUBBLE_STATE,
+
+  // A password is pending, but we don't need to pop up a bubble.
+  PENDING_PASSWORD_STATE,
+
+  // A password has been autofilled, or has just been saved. The icon needs
+  // to be visible, in the management state.
+  MANAGE_STATE,
+
+  // The user has blacklisted the site rendered in the current WebContents.
+  // The icon needs to be visible, in the blacklisted state.
+  BLACKLIST_STATE,
+};
+
+// Returns true if |state| represents a pending password.
+bool IsPendingState(State state);
+
+}  // namespace ui
+
+}  // namespace password_manager
+
+#endif  // COMPONENTS_PASSWORD_MANAGER_CORE_COMMON_PASSWORD_MANAGER_UI_H_
diff --git a/components/plugins.gypi b/components/plugins.gypi
index e56ed09..9775d8b 100644
--- a/components/plugins.gypi
+++ b/components/plugins.gypi
@@ -3,39 +3,34 @@
 # found in the LICENSE file.
 
 {
-  'conditions': [
-    ['OS != "ios"', {
-  
-      'targets': [
-        {
-          'target_name': 'plugins_renderer',
-          'type': 'static_library',
-          'dependencies': [
-            '../third_party/re2/re2.gyp:re2',
-            '../gin/gin.gyp:gin',
-            '../skia/skia.gyp:skia',
-            '../third_party/WebKit/public/blink.gyp:blink',
-            '../v8/tools/gyp/v8.gyp:v8',
-          ],
-          'include_dirs': [
-            '..',
-          ],
+  'targets': [
+    {
+      'target_name': 'plugins_renderer',
+      'type': 'static_library',
+      'dependencies': [
+        '../gin/gin.gyp:gin',
+        '../skia/skia.gyp:skia',
+        '../third_party/WebKit/public/blink.gyp:blink',
+        '../third_party/re2/re2.gyp:re2',
+        '../v8/tools/gyp/v8.gyp:v8',
+      ],
+      'include_dirs': [
+        '..',
+      ],
+      'sources': [
+        'plugins/renderer/plugin_placeholder.cc',
+        'plugins/renderer/plugin_placeholder.h',
+        'plugins/renderer/webview_plugin.cc',
+        'plugins/renderer/webview_plugin.h',
+      ],
+      'conditions' : [
+        ['OS=="android"', {
           'sources': [
-            'plugins/renderer/plugin_placeholder.cc',
-            'plugins/renderer/plugin_placeholder.h',
-            'plugins/renderer/webview_plugin.cc',
-            'plugins/renderer/webview_plugin.h',
-          ],
-          'conditions' : [
-            ['OS=="android"', {
-              'sources': [
-                'plugins/renderer/mobile_youtube_plugin.cc',
-                'plugins/renderer/mobile_youtube_plugin.h',
-              ]
-            }],
-          ],
-        },
-      ]
-    }]
+            'plugins/renderer/mobile_youtube_plugin.cc',
+            'plugins/renderer/mobile_youtube_plugin.h',
+          ]
+        }],
+      ],
+    },
   ]
 }
diff --git a/components/policy.gypi b/components/policy.gypi
index a47d881..d99f7af 100644
--- a/components/policy.gypi
+++ b/components/policy.gypi
@@ -128,13 +128,15 @@
         },
         {
           'target_name': 'cloud_policy_proto_generated_compile',
-          'type': 'static_library',
+          'type': '<(component)',
           'sources': [
             '<(cloud_policy_proto_path)',
           ],
           'variables': {
             'proto_in_dir': '<(policy_out_dir)/policy',
             'proto_out_dir': 'policy/proto',
+            'cc_generator_options': 'dllexport_decl=POLICY_PROTO_EXPORT:',
+            'cc_include': 'components/policy/policy_proto_export.h',
           },
           'dependencies': [
             'cloud_policy_code_generate',
@@ -142,6 +144,9 @@
           'includes': [
             '../build/protoc.gypi',
           ],
+          'defines': [
+            'POLICY_PROTO_COMPILATION',
+          ],
           # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
           'msvs_disabled_warnings': [4267, ],
         },
@@ -194,7 +199,7 @@
         },
         {
           'target_name': 'cloud_policy_proto',
-          'type': 'static_library',
+          'type': '<(component)',
           'sources': [
             'policy/proto/chrome_extension_policy.proto',
             'policy/proto/device_management_backend.proto',
@@ -204,6 +209,8 @@
           'variables': {
             'proto_in_dir': 'policy/proto',
             'proto_out_dir': 'policy/proto',
+            'cc_generator_options': 'dllexport_decl=POLICY_PROTO_EXPORT:',
+            'cc_include': 'components/policy/policy_proto_export.h',
           },
           'includes': [
             '../build/protoc.gypi',
@@ -220,6 +227,9 @@
               ],
             }],
           ],
+          'defines': [
+            'POLICY_PROTO_COMPILATION',
+          ],
         },
         {
           'target_name': 'policy_test_support',
diff --git a/components/policy/core/browser/url_blacklist_manager.cc b/components/policy/core/browser/url_blacklist_manager.cc
index 1da4adf..0706080 100644
--- a/components/policy/core/browser/url_blacklist_manager.cc
+++ b/components/policy/core/browser/url_blacklist_manager.cc
@@ -57,9 +57,9 @@
     const std::string& query,
     bool allow,
     std::set<URLQueryElementMatcherCondition>* query_conditions) {
-  url_parse::Component query_left = url_parse::MakeRange(0, query.length());
-  url_parse::Component key;
-  url_parse::Component value;
+  url::Component query_left = url::MakeRange(0, query.length());
+  url::Component key;
+  url::Component value;
   // Depending on the filter type being black-list or white-list, the matcher
   // choose any or every match. The idea is a URL should be black-listed if
   // there is any occurrence of the key value pair. It should be white-listed
@@ -201,7 +201,7 @@
                                       uint16* port,
                                       std::string* path,
                                       std::string* query) {
-  url_parse::Parsed parsed;
+  url::Parsed parsed;
 
   if (segment_url(filter, &parsed) == kFileScheme) {
     base::FilePath file_path;
@@ -241,11 +241,11 @@
     host->erase(0, 1);
     *match_subdomains = false;
   } else {
-    url_canon::RawCanonOutputT<char> output;
-    url_canon::CanonHostInfo host_info;
-    url_canon::CanonicalizeHostVerbose(filter.c_str(), parsed.host,
-                                       &output, &host_info);
-    if (host_info.family == url_canon::CanonHostInfo::NEUTRAL) {
+    url::RawCanonOutputT<char> output;
+    url::CanonHostInfo host_info;
+    url::CanonicalizeHostVerbose(filter.c_str(), parsed.host, &output,
+                                 &host_info);
+    if (host_info.family == url::CanonHostInfo::NEUTRAL) {
       // We want to match subdomains. Add a dot in front to make sure we only
       // match at domain component boundaries.
       *host = "." + *host;
diff --git a/components/policy/core/browser/url_blacklist_manager.h b/components/policy/core/browser/url_blacklist_manager.h
index 9052e95..b2bf418 100644
--- a/components/policy/core/browser/url_blacklist_manager.h
+++ b/components/policy/core/browser/url_blacklist_manager.h
@@ -43,8 +43,7 @@
  public:
   // This is meant to be bound to URLFixerUpper::SegmentURL. See that function
   // for documentation on the parameters and return value.
-  typedef std::string (*SegmentURLCallback)(const std::string&,
-                                            url_parse::Parsed*);
+  typedef std::string (*SegmentURLCallback)(const std::string&, url::Parsed*);
 
   explicit URLBlacklist(SegmentURLCallback segment_url);
   virtual ~URLBlacklist();
diff --git a/components/policy/core/common/schema_registry_unittest.cc b/components/policy/core/common/schema_registry_unittest.cc
index 94e245e..36749ea 100644
--- a/components/policy/core/common/schema_registry_unittest.cc
+++ b/components/policy/core/common/schema_registry_unittest.cc
@@ -226,7 +226,7 @@
                               schema);
   Mock::VerifyAndClearExpectations(&observer);
 
-  // Untracking |registry1| doesn't trigger an update nofitication, because it
+  // Untracking |registry1| doesn't trigger an update notification, because it
   // doesn't contain any components.
   EXPECT_CALL(observer, OnSchemaRegistryUpdated(_)).Times(0);
   combined.Untrack(&registry1);
diff --git a/components/policy/policy_proto_export.h b/components/policy/policy_proto_export.h
new file mode 100644
index 0000000..4e9fd81
--- /dev/null
+++ b/components/policy/policy_proto_export.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef COMPONENTS_POLICY_POLICY_PROTO_EXPORT_H_
+#define COMPONENTS_POLICY_POLICY_PROTO_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+
+#if defined(WIN32)
+
+#if defined(POLICY_PROTO_COMPILATION)
+#define POLICY_PROTO_EXPORT __declspec(dllexport)
+#else
+#define POLICY_PROTO_EXPORT __declspec(dllimport)
+#endif  // defined(POLICY_PROTO_COMPILATION)
+
+#else  // defined(WIN32)
+
+#if defined(POLICY_PROTO_COMPILATION)
+#define POLICY_PROTO_EXPORT __attribute__((visibility("default")))
+#else
+#define POLICY_PROTO_EXPORT
+#endif  // defined(POLICY_PROTO_COMPILATION)
+
+#endif  // defined(WIN32)
+
+#else  // defined(COMPONENT_BUILD)
+
+#define POLICY_PROTO_EXPORT
+
+#endif  // defined(COMPONENT_BUILD)
+
+#endif  // COMPONENTS_POLICY_POLICY_PROTO_EXPORT_H_
diff --git a/components/policy/resources/PRESUBMIT.py b/components/policy/resources/PRESUBMIT.py
index e34e1ac..1f16ca8 100644
--- a/components/policy/resources/PRESUBMIT.py
+++ b/components/policy/resources/PRESUBMIT.py
@@ -52,7 +52,9 @@
   policy_test_cases_file = input_api.os_path.join(
       root, 'chrome', 'test', 'data', 'policy', 'policy_test_cases.json')
   test_names = input_api.json.load(open(policy_test_cases_file)).keys()
-  tested_policies = frozenset(name for name in test_names if name[:2] != '--')
+  tested_policies = frozenset(name.partition('.')[0]
+                              for name in test_names
+                              if name[:2] != '--')
   policy_names = frozenset(policy['name'] for policy in policies)
 
   # Finally check if any policies are missing.
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 22b54d4..5bfab2f 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -118,7 +118,7 @@
 #   persistent IDs for all fields (but not for groups!) are needed. These are
 #   specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
 #   because doing so would break the deployed wire format!
-#   For your editing convenience: highest ID currently used: 264
+#   For your editing convenience: highest ID currently used: 265
 #
 # Placeholders:
 #   The following placeholder strings are automatically substituted:
@@ -1007,6 +1007,27 @@
       If you set this policy, you can configure if a user is allowed to sign in to <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> or not.''',
     },
     {
+      'name': 'EnableWebBasedSignin',
+      'type': 'main',
+      'schema': { 'type': 'boolean' },
+      'supported_on': ['chrome.*:35-'],
+      'features': {
+        'dynamic_refresh': False,
+        'per_profile': False,
+      },
+      'future': True,
+      'example_value': False,
+      'id': 265,
+      'caption': '''Enables the old web-based signin''',
+      'desc': '''Enables the old web-based signin flow.
+
+      This setting is useful for enterprise customers who are using SSO solutions that are not compatible with the new inline signin flow yet.
+      If you enable this setting, the old web-based signin flow would be used.
+      If you disable this setting or leave it not set, the new inline signin flow would be used by default. Users may still enable the old web-based signin flow through the command line flag --enable-web-based-signin.
+
+      The experimental setting will be removed in the future when the inline signin fully supports all SSO signin flows.''',
+    },
+    {
       'name': 'UserDataDir',
       'type': 'string',
       'schema': { 'type': 'string' },
@@ -1526,7 +1547,7 @@
       'name': 'Extensions',
       'type': 'group',
       'caption': '''Extensions''',
-      'desc': '''Configures extension-related policies. The user is not allowed to install blacklisted extensions unless they are whitelisted. You can also force <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> to automatically install extensions by specifying them in <ph name="EXTENSIONINSTALLFORCELIST_POLICY_NAME">ExtensionInstallForcelist</ph>. The blacklist takes precedence over the list of forced extensions.''',
+      'desc': '''Configures extension-related policies. The user is not allowed to install blacklisted extensions unless they are whitelisted. You can also force <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> to automatically install extensions by specifying them in <ph name="EXTENSIONINSTALLFORCELIST_POLICY_NAME">ExtensionInstallForcelist</ph>. Force-installed extensions are installed regardless whether they are present in the blacklist.''',
       'policies': [
         {
           'name': 'ExtensionInstallBlacklist',
diff --git a/components/policy/resources/policy_templates_am.xtb b/components/policy/resources/policy_templates_am.xtb
index 1699f6b..8ccf042 100644
--- a/components/policy/resources/policy_templates_am.xtb
+++ b/components/policy/resources/policy_templates_am.xtb
@@ -360,7 +360,7 @@
 
       ይህ መመሪያ በእሴት -1 ላይ ሲዋቀር ተጠቃሚው ያለምንም ገደብ በቋሚነት ከመስመር ውጭ ማረጋገጥ ይችላል። ይህ መመሪያ በሌላ ማንኛውም እሴት ሲዋቀር ከባለፈው ፍቃድ መስጫ በኋላ ተጠቃሚው የመስመር ላይ ማረጋገጫን እንደገና ከመጠቀሙ በፊት ምን ያክል ጊዜ ሊቆይ እንደሚችል ይገልጻል።
 
-      ይህን መመሪያ እንዳልተዋቀረ መተው <ph name="PRODUCT_OS_NAME"/> በነባሪ የተቀመጠውን የ14 ቀናት የጊዜ ገደብ እንዲጠቀም እና ከዚህ ጊዜ በኋላ ግን የመስመር ላይ ማረጋገጫን እንደገና እንዲጠቀም ያስገድደዋል።
+      ይህን መመሪያ እንዳልተዋቀረ መተው <ph name="PRODUCT_OS_NAME"/> በነባሪ የተቀመጠውን የ14 ቀኖች የጊዜ ገደብ እንዲጠቀም እና ከዚህ ጊዜ በኋላ ግን የመስመር ላይ ማረጋገጫን እንደገና እንዲጠቀም ያስገድደዋል።
 
       ይህ መመሪያ ተጽዕኖ የሚያሳርፍባቸው ኤስኤኤምኤል በመጠቀም ፈቃድ ለተሰጣቸው ተጠቃሚዎች ላይ ብቻ ነው።
 
diff --git a/components/policy/resources/policy_templates_lt.xtb b/components/policy/resources/policy_templates_lt.xtb
index f1dc1e9..d4378b9 100644
--- a/components/policy/resources/policy_templates_lt.xtb
+++ b/components/policy/resources/policy_templates_lt.xtb
@@ -1274,7 +1274,7 @@
 
       Šia politika taip pat leidžiama griežtai įtraukti papildinius į juodąjį sąrašą, kai sąraše „DisabledPlugins“ yra pakaitos simbolių įrašų, pvz., išjungti visus papildinius „*“ arba išjungti visus „Java“ papildinius „*Java*“, bet administratorius nori įgalinti konkrečią versiją, pvz., „IcedTea Java 2.3“. Šias konkrečias versijas galima nurodyti šioje politikoje.
 
-      Atminkite, kad papildinio pavadinimas ir papildinio grupės pavadinimas turi būti išskirti. Kiekviena papildinių grupė rodoma atskiroje „about:plugins“ skiltyje; kiekvienoje skiltyje gali būti vienas ar daugiau papildinių. Pavyzdžiui, „Shockwave Flash“ papildinys priklauso „Adobe Flash Player“ grupei, todėl abu pavadinimai turi atitikti sąraše nurodytas išimtis, jei tas papildinys turi būti išskirtas iš juodojo sąrašo.
+      Atminkite, kad papildinio pavadinimas ir papildinio grupės pavadinimas turi būti išskirti. Kiekviena papildinių grupė rodoma atskiroje „about:plugins“ skiltyje; kiekvienoje skiltyje gali būti vienas ar daugiau papildinių. Pavyzdžiui, „Shockwave Flash“ papildinys priklauso „Adobe Flash“ leistuvės grupei, todėl abu pavadinimai turi atitikti sąraše nurodytas išimtis, jei tas papildinys turi būti išskirtas iš juodojo sąrašo.
 
       Jei ši politika nenustatyta, bet kuris politikos „DisabledPlugins“ šablonus atitinkantis papildinys bus užrakintas, išjungtas ir naudotojas negalės jo įgalinti.</translation>
 <translation id="8951350807133946005">Nustatyti disko talpyklos katalogą</translation>
diff --git a/components/policy/resources/policy_templates_sr.xtb b/components/policy/resources/policy_templates_sr.xtb
index f416754..ba20c69 100644
--- a/components/policy/resources/policy_templates_sr.xtb
+++ b/components/policy/resources/policy_templates_sr.xtb
@@ -331,14 +331,14 @@
       Ако подесите ове смернице на Нетачно, ни корисник нити било какве апликације или додаци не могу да уђу у режим целог екрана.
 
       Када је режим целог екрана онемогућен, режим киоска је недоступан на свим платформама осим <ph name="PRODUCT_OS_NAME"/>-а.</translation>
-<translation id="8828766846428537606">Конфигурише подразумевану почетну страницу у прегледачу <ph name="PRODUCT_NAME"/> и спречава кориснике да је промене. Подешавања почетне странице корисника се потпуно закључавају само ако изаберете да почетна страница буде страница Нова картица или ако подесите да то буде URL адреса и наведете URL адресу почетне странице. Уколико не наведете URL адресу почетне странице, корисник ће и даље моћи да подеси страницу Нова картица као почетну страницу ако унесе „chrome://newtab“.</translation>
+<translation id="8828766846428537606">Конфигурише подразумевану почетну страницу у прегледачу <ph name="PRODUCT_NAME"/> и спречава кориснике да је промене. Подешавања почетне странице корисника се потпуно закључавају само ако изаберете да почетна страница буде страница Нова картица или ако подесите да то буде URL адреса и наведете URL адресу почетне странице. Ако не наведете URL адресу почетне странице, корисник ће и даље моћи да подеси страницу Нова картица као почетну страницу ако унесе „chrome://newtab“.</translation>
 <translation id="2231817271680715693">Увоз историје прегледања из подразумеваног прегледача при првом покретању</translation>
 <translation id="1353966721814789986">Странице приликом покретања</translation>
 <translation id="7173856672248996428">Привремен профил</translation>
 <translation id="1841130111523795147">Омогућавају кориснику да се пријави у <ph name="PRODUCT_NAME"/> и спречавају кориснике да промене ово подешавање.
 
       Ако подесите ове смернице, можете да конфигуришете да ли ће кориснику бити омогућено да се пријави у <ph name="PRODUCT_NAME"/> или не.</translation>
-<translation id="5564962323737505851">Конфигурише менаџера лозинке. Уколико је менаџер лозинке омогућен, можете да омогућите или онемогућите да ли ће корисник моћи да приказује сачуване лозинке у јасном тексту.</translation>
+<translation id="5564962323737505851">Конфигурише менаџера лозинке. Ако је менаџер лозинке омогућен, можете да омогућите или онемогућите да ли ће корисник моћи да приказује сачуване лозинке у јасном тексту.</translation>
 <translation id="4668325077104657568">Подразумевано подешавање слика</translation>
 <translation id="4492287494009043413">Онемогућавање прављења снимака екрана</translation>
 <translation id="6368403635025849609">Дозволи JavaScript на овим сајтовима</translation>
@@ -913,7 +913,7 @@
       Ако ове смернице нису подешене, ово подешавање ће бити омогућено, али ће корисник моћи да га промени.</translation>
 <translation id="4541530620466526913">Локални налози на уређају</translation>
 <translation id="5815129011704381141">Аутоматско поновно покретање после ажурирања</translation>
-<translation id="1757688868319862958">Омогућава да <ph name="PRODUCT_NAME"/> покреће додатне компоненте које захтевају овлашћење. Уколико омогућите ово подешавање, додатне компоненте које нису застареле увек функционишу. Уколико је ово подешавање онемогућено или није подешено, од корисника ће бити затражена дозвола да покрећу додатне компоненте које захтевају овлашћење. То су додатне компоненте који угрожавају безбедност.</translation>
+<translation id="1757688868319862958">Омогућава да <ph name="PRODUCT_NAME"/> покреће додатне компоненте које захтевају овлашћење. Ако омогућите ово подешавање, додатне компоненте које нису застареле увек функционишу. Ако је ово подешавање онемогућено или није подешено, од корисника ће бити затражена дозвола да покрећу додатне компоненте које захтевају овлашћење. То су додатне компоненте који угрожавају безбедност.</translation>
 <translation id="6392973646875039351">Омогућава функцију Аутоматско попуњавање у <ph name="PRODUCT_NAME"/>-у и омогућава корисницима да аутоматски довршавају веб-обрасце помоћу раније сачуваних података, као што је адреса или подаци о кредитној картици.
 
       Ако онемогућите ово подешавање, Аутоматско попуњавање неће бити доступно корисницима.
@@ -1222,7 +1222,7 @@
 <translation id="2223598546285729819">Подразумевано подешавање обавештења</translation>
 <translation id="6158324314836466367">Назив веб-продавнице предузећа (застарело је)</translation>
 <translation id="3984028218719007910">Одређују да ли <ph name="PRODUCT_OS_NAME"/> задржава локалне податке о налогу после одјављивања. Ако буду подешене на Тачно, <ph name="PRODUCT_OS_NAME"/> не задржава никакве сталне налоге и сви подаци из корисничке сесије ће бити одбачени након одјављивања. Ако ове смернице буду подешене на Нетачно или не буду конфигурисане, уређај може да задржи (шифроване) локалне корисничке податке.</translation>
-<translation id="3793095274466276777">Конфигурише подразумеване провере у прегледачу <ph name="PRODUCT_NAME"/> и спречава кориснике да их мењају. Уколико омогућите ово подешавање, <ph name="PRODUCT_NAME"/> ће увек при покретању проверавати да ли је подразумевани прегледач и аутоматски се регистровати ако је могуће. Уколико се ово подешавање онемогући, <ph name="PRODUCT_NAME"/> никада неће проверавати да ли је подразумевани прегледач и онемогућиће корисничке контроле за подешавање ове опције. Уколико се ово подешавање не подеси, <ph name="PRODUCT_NAME"/> ће дозволити кориснику да контролише да ли је подразумевани прегледач и да ли обавештења за кориснике треба да се прикажу када није.</translation>
+<translation id="3793095274466276777">Конфигурише подразумеване провере у прегледачу <ph name="PRODUCT_NAME"/> и спречава кориснике да их мењају. Ако омогућите ово подешавање, <ph name="PRODUCT_NAME"/> ће увек при покретању проверавати да ли је подразумевани прегледач и аутоматски се регистровати ако је могуће. Ако се ово подешавање онемогући, <ph name="PRODUCT_NAME"/> никада неће проверавати да ли је подразумевани прегледач и онемогућиће корисничке контроле за подешавање ове опције. Ако се ово подешавање не подеси, <ph name="PRODUCT_NAME"/> ће дозволити кориснику да контролише да ли је подразумевани прегледач и да ли обавештења за кориснике треба да се прикажу када није.</translation>
 <translation id="3504791027627803580">Наводе URL претраживача који се користи за претрагу слика. Захтеви за претрагу ће бити послати помоћу GET метода. Ако су смернице DefaultSearchProviderImageURLPostParams подешене, захтеви за претрагу слика ће користити POST метод.
 
           Ове смернице су опционалне. Ако нису подешене, неће се користити никаква претрага слика.
@@ -1713,7 +1713,7 @@
 <translation id="1734716591049455502">Конфигуриши опције даљинског приступа</translation>
 <translation id="7336878834592315572">Чувај колачиће током трајања сесије</translation>
 <translation id="7715711044277116530">Проценат до кога треба мењати време до замрачивања екрана у режиму презентације</translation>
-<translation id="8777120694819070607">Дозвољава прегледачу <ph name="PRODUCT_NAME"/> да покреће додатне компоненте који су застареле. Уколико омогућите ово подешавање, застареле додатне компоненте се користе као нормалне додатне компоненте. Уколико онемогућите ово подешавање, застареле додатне компоненте се неће користити и од корисника неће бити тражена дозвола за њихово покретање. Уколико ово подешавање није подешено, од корисника ће бити тражена дозвола за покретање застарелих додатних компоненти.</translation>
+<translation id="8777120694819070607">Дозвољава прегледачу <ph name="PRODUCT_NAME"/> да покреће додатне компоненте који су застареле. Ако омогућите ово подешавање, застареле додатне компоненте се користе као нормалне додатне компоненте. Ако онемогућите ово подешавање, застареле додатне компоненте се неће користити и од корисника неће бити тражена дозвола за њихово покретање. Ако ово подешавање није подешено, од корисника ће бити тражена дозвола за покретање застарелих додатних компоненти.</translation>
 <translation id="2629448496147630947">Конфигурише опције даљинског приступа у производу <ph name="PRODUCT_NAME"/>. Ове функције се занемарују, осим ако није инсталирана веб апликација Даљински приступ.</translation>
 <translation id="4001275826058808087">IT администратори уређаја за предузећа могу да користе ову ознаку да би одредили да ли ће дозволити корисницима да искоришћавају понуде преко регистрације за Chrome ОС.
 
diff --git a/components/policy/resources/policy_templates_sw.xtb b/components/policy/resources/policy_templates_sw.xtb
index 8f5b27d..3daa594 100644
--- a/components/policy/resources/policy_templates_sw.xtb
+++ b/components/policy/resources/policy_templates_sw.xtb
@@ -1482,7 +1482,7 @@
       Ikibainishwa, itaongeza kigezo cha hoja kinachoitwa 'kizuizi' kwa URL inayotumika kuleta mbegu Tofauti. Thamani ya kigezo itakuwa thamani iliyobainishwa katika sera hii.
 
       Isipobainishwa, haitarekebisha URL ya mbegu Tofauti.</translation>
-<translation id="944817693306670849">Weka ukubwa wa kache ya diski</translation>
+<translation id="944817693306670849">Weka ukubwa wa akiba ya diski</translation>
 <translation id="8544375438507658205">Kionyeshi chaguo-msngi cha HTML kwa<ph name="PRODUCT_FRAME_NAME"/></translation>
 <translation id="2371309782685318247">Inabainisha muda katika milisekunde ambapo huduma ya usimamizi wa kifaa inahojiwa kwa maelezo ya sera ya mtumiaji.
 
@@ -1553,7 +1553,7 @@
 <translation id="3891357445869647828">Wezesha JavaScript</translation>
 <translation id="6774533686631353488">Ruhusu wapangishi wa Ujumbe Asili wa ngazi ya mtumiaji (wanaosakinishwa bila idhini ya msimamizi).</translation>
 <translation id="868187325500643455">Ruhusu tovuti zote kuendesha programu jalizi moja kwa moja</translation>
-<translation id="7421483919690710988">Weka ukubwa wa kache ya diski ya media katika baiti</translation>
+<translation id="7421483919690710988">Weka ukubwa wa akiba ya diski ya media katika vipimo vya baiti</translation>
 <translation id="5226033722357981948">Bainisha iwapo kitafutaji programu jalizi kinafaa kulemazwa</translation>
 <translation id="7234280155140786597">Majina ya wapangishi waliozuiwa wa ujumbe asili (au * kwa wote)</translation>
 <translation id="4890209226533226410">Weka aina ya kikuza skrini ambacho kimewashwa.
diff --git a/components/policy/resources/policy_templates_th.xtb b/components/policy/resources/policy_templates_th.xtb
index c029d07..151a953 100644
--- a/components/policy/resources/policy_templates_th.xtb
+++ b/components/policy/resources/policy_templates_th.xtb
@@ -677,7 +677,7 @@
 
       หมายเหตุ: ในปัจจุบันนี้ นโยบายนี้ได้รับการสนับสนุนเฉพาะเมื่อทำงานในโหมดคีออสก์เท่านั้น</translation>
 <translation id="489803897780524242">พารามิเตอร์ที่ควบคุมตำแหน่งข้อความค้นหาสำหรับผู้ให้บริการค้นหาในค่าเริ่มต้น</translation>
-<translation id="316778957754360075">การตั้งค่านี้ถูกยกเลิกไปตั้งแต่ <ph name="PRODUCT_NAME"/> เวอร์ชัน 29 วิธีที่แนะนำในการตั้งค่าคอลเล็กชันส่วนขยาย/แอปที่โฮสต์โดยองค์กรคือการรวมไซต์ที่โฮสต์แพคเกจ CRX ใน ExtensionInstallSources และการวางลิงก์ดาวน์โหลดโดยตรงไปยังแพคเกจบนหน้าเว็บ ตัวเรียกใช้งานสำหรับหน้าเว็บนั้นสามารถถูกสร้างขึ้นโดยใช้นโยบาย ExtensionInstallForcelist</translation>
+<translation id="316778957754360075">การตั้งค่านี้ถูกยกเลิกไปตั้งแต่ <ph name="PRODUCT_NAME"/> เวอร์ชัน 29 วิธีที่แนะนำในการตั้งค่าคอลเล็กชันส่วนขยาย/แอปที่โฮสต์โดยองค์กรคือการรวมไซต์ที่โฮสต์แพ็กเกจ CRX ใน ExtensionInstallSources และการวางลิงก์ดาวน์โหลดโดยตรงไปยังแพ็กเกจบนหน้าเว็บ ตัวเรียกใช้งานสำหรับหน้าเว็บนั้นสามารถถูกสร้างขึ้นโดยใช้นโยบาย ExtensionInstallForcelist</translation>
 <translation id="6401669939808766804">ออกจากระบบให้ผู้ใช้</translation>
 <translation id="4826326557828204741">การกระทำที่จะดำเนินการเมื่อไม่มีการใช้งานจนถึงการหน่วงเวลาที่กำหนด ขณะที่ใช้พลังงานจากแบตเตอรี่</translation>
 <translation id="7912255076272890813">กำหนดค่าประเภทแอปพลิเคชัน/ส่วนขยายที่อนุญาต</translation>
diff --git a/components/precache/DEPS b/components/precache/DEPS
index 0caaca9..36f628b 100644
--- a/components/precache/DEPS
+++ b/components/precache/DEPS
@@ -4,5 +4,4 @@
   # http://www.chromium.org/developers/design-documents/layered-components-design
   "-components/precache",
   "+components/precache/core",
-  "-content/public",
 ]
diff --git a/components/query_parser/DEPS b/components/query_parser/DEPS
deleted file mode 100644
index 0faa0bf..0000000
--- a/components/query_parser/DEPS
+++ /dev/null
@@ -1,5 +0,0 @@
-include_rules = [
-  # query_parser is a component that is not allowed to uses content/ so that it
-  # can be shared on iOS.
-  "-content",
-]
diff --git a/components/rappor/log_uploader.cc b/components/rappor/log_uploader.cc
index ead1a97..8f1c4d6 100644
--- a/components/rappor/log_uploader.cc
+++ b/components/rappor/log_uploader.cc
@@ -7,6 +7,7 @@
 #include "base/metrics/histogram.h"
 #include "base/metrics/sparse_histogram.h"
 #include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
 #include "net/url_request/url_fetcher.h"
 
 namespace {
@@ -102,10 +103,21 @@
   DCHECK_EQ(current_fetch_.get(), source);
   scoped_ptr<net::URLFetcher> fetch(current_fetch_.Pass());
 
+  const net::URLRequestStatus& request_status = source->GetStatus();
+
   const int response_code = source->GetResponseCode();
 
-  // Log a histogram to track response success vs. failure rates.
-  UMA_HISTOGRAM_SPARSE_SLOWLY("Rappor.UploadResponseCode", response_code);
+  if (request_status.status() != net::URLRequestStatus::SUCCESS) {
+    UMA_HISTOGRAM_SPARSE_SLOWLY("Rappor.FailedUploadErrorCode",
+                                -request_status.error());
+    DVLOG(1) << "Rappor server upload failed with error: "
+             << request_status.error() << ": "
+             << net::ErrorToString(request_status.error());
+    DCHECK_EQ(-1, response_code);
+  } else {
+    // Log a histogram to track response success vs. failure rates.
+    UMA_HISTOGRAM_SPARSE_SLOWLY("Rappor.UploadResponseCode", response_code);
+  }
 
   const bool upload_succeeded = response_code == 200;
 
diff --git a/components/search_provider_logos/DEPS b/components/search_provider_logos/DEPS
index ba7b9c8..b580484 100644
--- a/components/search_provider_logos/DEPS
+++ b/components/search_provider_logos/DEPS
@@ -2,9 +2,4 @@
   "+net",
   "+third_party/skia/include/core/SkBitmap.h",
   "+ui/gfx/image",
-
-  # search_provider_logos is shared by iOS and hence cannot depend on the
-  # content layer. If //content dependencies need to be introduced, this will
-  # have to become a layered component."
-  "-content",
 ]
diff --git a/components/signin/DEPS b/components/signin/DEPS
index 6aef403..41be33e 100644
--- a/components/signin/DEPS
+++ b/components/signin/DEPS
@@ -7,9 +7,4 @@
   "+grit",  # For generated headers
   "+net",
   "+sql",
-  # Signin is a layered component; subdirectories must explicitly introduce
-  # the ability to use the content layer as appropriate.
-  "-components/signin/content",
-  "-content/public/common",
-  "-ipc",
 ]
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc
index 4388838..86b94e7 100644
--- a/components/signin/core/browser/about_signin_internals.cc
+++ b/components/signin/core/browser/about_signin_internals.cc
@@ -67,16 +67,16 @@
   switch (field) {
     case SIGNIN_TYPE:
       return "Type";
-    case CLIENT_LOGIN_STATUS:
-      return "Last OnClientLogin Status";
-    case OAUTH_LOGIN_STATUS:
-      return "Last OnOAuthLogin Status";
+    case AUTHENTICATION_RESULT_RECEIVED:
+      return "Last Authentication Result Received";
+    case REFRESH_TOKEN_RECEIVED:
+      return "Last RefreshToken Received";
     case GET_USER_INFO_STATUS:
-      return "Last OnGetUserInfo Status";
+      return "Last OnGetUserInfo Received";
     case UBER_TOKEN_STATUS:
-      return "Last OnUberToken Status";
+      return "Last OnUberToken Received";
     case MERGE_SESSION_STATUS:
-      return "Last OnMergeSession Status";
+      return "Last OnMergeSession Received";
     case TIMED_FIELDS_END:
       NOTREACHED();
       return "Error";
@@ -248,6 +248,14 @@
   NotifyObservers();
 }
 
+void AboutSigninInternals::OnRefreshTokenReceived(std::string status) {
+  NotifySigninValueChanged(REFRESH_TOKEN_RECEIVED, status);
+}
+
+void AboutSigninInternals::OnAuthenticationResultReceived(std::string status) {
+  NotifySigninValueChanged(AUTHENTICATION_RESULT_RECEIVED, status);
+}
+
 AboutSigninInternals::TokenInfo::TokenInfo(
     const std::string& consumer_id,
     const OAuth2TokenService::ScopeSet& scopes)
diff --git a/components/signin/core/browser/about_signin_internals.h b/components/signin/core/browser/about_signin_internals.h
index aa88e10..e305ce7 100644
--- a/components/signin/core/browser/about_signin_internals.h
+++ b/components/signin/core/browser/about_signin_internals.h
@@ -96,6 +96,9 @@
                               const OAuth2TokenService::ScopeSet& scopes)
       OVERRIDE;
 
+    void OnRefreshTokenReceived(std::string status);
+    void OnAuthenticationResultReceived(std::string status);
+
  private:
   // Encapsulates diagnostic information about tokens for different services.
   struct TokenInfo {
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc
index 9725b0b..accb6da 100644
--- a/components/signin/core/browser/account_reconcilor.cc
+++ b/components/signin/core/browser/account_reconcilor.cc
@@ -23,6 +23,24 @@
 #include "google_apis/gaia/gaia_urls.h"
 #include "net/cookies/canonical_cookie.h"
 
+
+namespace {
+
+class EmailEqualToFunc : public std::equal_to<std::pair<std::string, bool> > {
+ public:
+  bool operator()(const std::pair<std::string, bool>& p1,
+                  const std::pair<std::string, bool>& p2) const;
+};
+
+bool EmailEqualToFunc::operator()(
+    const std::pair<std::string, bool>& p1,
+    const std::pair<std::string, bool>& p2) const {
+  return p1.second == p2.second && gaia::AreEmailsSame(p1.first, p2.first);
+}
+
+}  // namespace
+
+
 // Fetches a refresh token from the given session in the GAIA cookie.  This is
 // a best effort only.  If it should fail, another reconcile action will occur
 // shortly anyway.
@@ -590,40 +608,45 @@
         add_to_chrome_.push_back(std::make_pair(gaia_account, i));
       }
     }
-
-    // Determine if we need to merge accounts from chrome into gaia cookie.
-    for (EmailSet::const_iterator i = valid_chrome_accounts_.begin();
-         i != valid_chrome_accounts_.end();
-         ++i) {
-      bool add_to_cookie = true;
-      for (size_t j = 0; j < gaia_accounts_.size(); ++j) {
-        if (gaia::AreEmailsSame(gaia_accounts_[j].first, *i)) {
-          add_to_cookie = !gaia_accounts_[j].second;
-          break;
-        }
-      }
-      if (add_to_cookie)
-        add_to_cookie_.push_back(*i);
-    }
   } else {
     VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie";
     // Really messed up state.  Blow away the gaia cookie completely and
     // rebuild it, making sure the primary account as specified by the
     // SigninManager is the first session in the gaia cookie.
     PerformLogoutAllAccountsAction();
-    add_to_cookie_.push_back(primary_account_);
-    for (EmailSet::const_iterator i = valid_chrome_accounts_.begin();
-         i != valid_chrome_accounts_.end();
-         ++i) {
-      if (*i != primary_account_)
-        add_to_cookie_.push_back(*i);
-    }
+    gaia_accounts_.clear();
   }
 
-  // For each account known to chrome but not in the gaia cookie,
-  // PerformMergeAction().
-  for (size_t i = 0; i < add_to_cookie_.size(); ++i)
-    PerformMergeAction(add_to_cookie_[i]);
+  // Create a list of accounts that need to be added to the gaia cookie.
+  // The primary account must be first to make sure it becomes the default
+  // account in the case where chrome is completely rebuilding the cookie.
+  add_to_cookie_.push_back(primary_account_);
+  for (EmailSet::const_iterator i = valid_chrome_accounts_.begin();
+        i != valid_chrome_accounts_.end();
+        ++i) {
+    if (*i != primary_account_)
+      add_to_cookie_.push_back(*i);
+  }
+
+  // For each account known to chrome, PerformMergeAction() if the account is
+  // not already in the cookie jar or its state is invalid, or signal merge
+  // completed otherwise.  Make a copy of |add_to_cookie_| since calls to
+  // SignalComplete() will change the array.
+  std::vector<std::string> add_to_cookie_copy = add_to_cookie_;
+  for (size_t i = 0; i < add_to_cookie_copy.size(); ++i) {
+    if (gaia_accounts_.end() !=
+            std::find_if(gaia_accounts_.begin(),
+                         gaia_accounts_.end(),
+                         std::bind1st(EmailEqualToFunc(),
+                                      std::make_pair(add_to_cookie_copy[i],
+                                                     true)))) {
+      merge_session_helper_.SignalComplete(
+          add_to_cookie_copy[i],
+          GoogleServiceAuthError::AuthErrorNone());
+    } else {
+      PerformMergeAction(add_to_cookie_copy[i]);
+    }
+  }
 
   // For each account in the gaia cookie not known to chrome,
   // PerformAddToChromeAction.
diff --git a/components/signin/core/browser/signin_internals_util.cc b/components/signin/core/browser/signin_internals_util.cc
index c16f92a..ef9e407 100644
--- a/components/signin/core/browser/signin_internals_util.cc
+++ b/components/signin/core/browser/signin_internals_util.cc
@@ -34,8 +34,8 @@
 std::string SigninStatusFieldToString(TimedSigninStatusField field) {
   switch (field) {
     ENUM_CASE(SIGNIN_TYPE);
-    ENUM_CASE(CLIENT_LOGIN_STATUS);
-    ENUM_CASE(OAUTH_LOGIN_STATUS);
+    ENUM_CASE(AUTHENTICATION_RESULT_RECEIVED);
+    ENUM_CASE(REFRESH_TOKEN_RECEIVED);
     ENUM_CASE(GET_USER_INFO_STATUS);
     ENUM_CASE(UBER_TOKEN_STATUS);
     ENUM_CASE(MERGE_SESSION_STATUS);
diff --git a/components/signin/core/browser/signin_internals_util.h b/components/signin/core/browser/signin_internals_util.h
index 8395cdb..d5856eb 100644
--- a/components/signin/core/browser/signin_internals_util.h
+++ b/components/signin/core/browser/signin_internals_util.h
@@ -38,8 +38,8 @@
 
 enum TimedSigninStatusField {
   SIGNIN_TYPE = TIMED_FIELDS_BEGIN,
-  CLIENT_LOGIN_STATUS,
-  OAUTH_LOGIN_STATUS,
+  AUTHENTICATION_RESULT_RECEIVED,
+  REFRESH_TOKEN_RECEIVED,
   GET_USER_INFO_STATUS,
   UBER_TOKEN_STATUS,
   MERGE_SESSION_STATUS,
diff --git a/components/signin/core/browser/signin_tracker.cc b/components/signin/core/browser/signin_tracker.cc
index 5dd7688..2bbd420 100644
--- a/components/signin/core/browser/signin_tracker.cc
+++ b/components/signin/core/browser/signin_tracker.cc
@@ -47,8 +47,9 @@
 }
 
 void SigninTracker::OnRefreshTokenAvailable(const std::string& account_id) {
-  // TODO: when OAuth2TokenService handles multi-login, this should check
-  // that |account_id| is the primary account before signalling success.
+  if (account_id != signin_manager_->GetAuthenticatedAccountId())
+    return;
+
   if (account_reconcilor_) {
     account_reconcilor_->AddMergeSessionObserver(this);
 #if !defined(OS_CHROMEOS)
diff --git a/components/startup_metric_utils/startup_metric_utils.cc b/components/startup_metric_utils/startup_metric_utils.cc
index beb41cd..5f60e95 100644
--- a/components/startup_metric_utils/startup_metric_utils.cc
+++ b/components/startup_metric_utils/startup_metric_utils.cc
@@ -149,7 +149,8 @@
 
 // CurrentProcessInfo::CreationTime() is currently only implemented on some
 // platforms.
-#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX)
+#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN) || \
+    defined(OS_LINUX)
   // Record timings between process creation, the main() in the executable being
   // reached and the main() in the shared library being reached.
   scoped_ptr<base::Environment> env(base::Environment::Create());
diff --git a/components/storage_monitor/portable_device_watcher_win.cc b/components/storage_monitor/portable_device_watcher_win.cc
index 003553e..3d79ece 100644
--- a/components/storage_monitor/portable_device_watcher_win.cc
+++ b/components/storage_monitor/portable_device_watcher_win.cc
@@ -59,7 +59,7 @@
   if (!dev_interface)
     return base::string16();
   base::string16 device_id(dev_interface->dbcc_name);
-  DCHECK(IsStringASCII(device_id));
+  DCHECK(base::IsStringASCII(device_id));
   return StringToLowerASCII(device_id);
 }
 
diff --git a/components/sync_driver.gypi b/components/sync_driver.gypi
index ace2857..827030f 100644
--- a/components/sync_driver.gypi
+++ b/components/sync_driver.gypi
@@ -32,6 +32,8 @@
         'sync_driver/failed_data_types_handler.h',
         'sync_driver/generic_change_processor.cc',
         'sync_driver/generic_change_processor.h',
+        'sync_driver/generic_change_processor_factory.cc',
+        'sync_driver/generic_change_processor_factory.h',
         'sync_driver/model_association_manager.cc',
         'sync_driver/model_association_manager.h',
         'sync_driver/model_associator.h',
diff --git a/components/sync_driver/DEPS b/components/sync_driver/DEPS
index 390e71b..1a20824 100644
--- a/components/sync_driver/DEPS
+++ b/components/sync_driver/DEPS
@@ -1,6 +1,4 @@
 include_rules = [
-  # SyncDriver is used by iOS, which does not use content.
-  "-content",
   "+components/os_crypt",
   "+components/user_prefs/pref_registry_syncable.h",
   "+sync",
diff --git a/components/sync_driver/backend_data_type_configurer.h b/components/sync_driver/backend_data_type_configurer.h
index ac3128d..dc91e34 100644
--- a/components/sync_driver/backend_data_type_configurer.h
+++ b/components/sync_driver/backend_data_type_configurer.h
@@ -10,9 +10,12 @@
 #include "base/callback.h"
 #include "sync/internal_api/public/base/model_type.h"
 #include "sync/internal_api/public/configure_reason.h"
+#include "sync/internal_api/public/engine/model_safe_worker.h"
 
 namespace browser_sync {
 
+class ChangeProcessor;
+
 // The DataTypeConfigurer interface abstracts out the action of
 // configuring a set of new data types and cleaning up after a set of
 // removed data types.
@@ -55,6 +58,17 @@
   static syncer::ModelTypeSet GetDataTypesInState(
       DataTypeConfigState state, const DataTypeConfigStateMap& state_map);
 
+  // Activates change processing for the given data type.  This must
+  // be called synchronously with the data type's model association so
+  // no changes are dropped between model association and change
+  // processor activation.
+  virtual void ActivateDataType(
+      syncer::ModelType type, syncer::ModelSafeGroup group,
+      ChangeProcessor* change_processor) = 0;
+
+  // Deactivates change processing for the given data type.
+  virtual void DeactivateDataType(syncer::ModelType type) = 0;
+
   // Set state of |types| in |state_map| to |state|.
   static void SetDataTypesState(DataTypeConfigState state,
                                 syncer::ModelTypeSet types,
diff --git a/components/sync_driver/data_type_controller.cc b/components/sync_driver/data_type_controller.cc
index 9e1932b..aa975d2 100644
--- a/components/sync_driver/data_type_controller.cc
+++ b/components/sync_driver/data_type_controller.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "components/sync_driver/data_type_controller.h"
+
 #include "sync/internal_api/public/base/model_type.h"
 #include "sync/util/data_type_histogram.h"
 
diff --git a/components/sync_driver/data_type_controller.h b/components/sync_driver/data_type_controller.h
index 633f433..ebc6c6f 100644
--- a/components/sync_driver/data_type_controller.h
+++ b/components/sync_driver/data_type_controller.h
@@ -25,6 +25,8 @@
 
 namespace browser_sync {
 
+class ChangeProcessor;
+
 // Data type controllers need to be refcounted threadsafe, as they may
 // need to run model associator or change processor on other threads.
 class DataTypeController
@@ -107,6 +109,10 @@
   // model.
   virtual syncer::ModelSafeGroup model_safe_group() const = 0;
 
+  // Access to the ChangeProcessor for the type being controlled by |this|.
+  // Returns NULL if the ChangeProcessor isn't created or connected.
+  virtual ChangeProcessor* GetChangeProcessor() const = 0;
+
   // Current state of the data type controller.
   virtual State state() const = 0;
 
diff --git a/components/sync_driver/fake_data_type_controller.cc b/components/sync_driver/fake_data_type_controller.cc
index d89d411..1d588c4 100644
--- a/components/sync_driver/fake_data_type_controller.cc
+++ b/components/sync_driver/fake_data_type_controller.cc
@@ -118,12 +118,14 @@
   return ModelTypeToString(type_);
 }
 
-// This isn't called by the DTM.
 syncer::ModelSafeGroup FakeDataTypeController::model_safe_group() const {
-  ADD_FAILURE();
   return syncer::GROUP_PASSIVE;
 }
 
+ChangeProcessor* FakeDataTypeController::GetChangeProcessor() const {
+  return NULL;
+}
+
 DataTypeController::State FakeDataTypeController::state() const {
   return state_;
 }
diff --git a/components/sync_driver/fake_data_type_controller.h b/components/sync_driver/fake_data_type_controller.h
index 2292c4f..643d524 100644
--- a/components/sync_driver/fake_data_type_controller.h
+++ b/components/sync_driver/fake_data_type_controller.h
@@ -39,6 +39,8 @@
 
   virtual syncer::ModelSafeGroup model_safe_group() const OVERRIDE;
 
+  virtual ChangeProcessor* GetChangeProcessor() const OVERRIDE;
+
   virtual State state() const OVERRIDE;
 
   virtual void OnSingleDatatypeUnrecoverableError(
diff --git a/components/sync_driver/fake_generic_change_processor.cc b/components/sync_driver/fake_generic_change_processor.cc
index 8f7aff2..5a85136 100644
--- a/components/sync_driver/fake_generic_change_processor.cc
+++ b/components/sync_driver/fake_generic_change_processor.cc
@@ -18,19 +18,10 @@
                              NULL,
                              syncer::FakeAttachmentService::CreateForTest()),
       sync_model_has_user_created_nodes_(true),
-      sync_model_has_user_created_nodes_success_(true),
-      crypto_ready_if_necessary_(true) {}
+      sync_model_has_user_created_nodes_success_(true) {}
 
 FakeGenericChangeProcessor::~FakeGenericChangeProcessor() {}
 
-void FakeGenericChangeProcessor::set_process_sync_changes_error(
-    const syncer::SyncError& error) {
-  process_sync_changes_error_ = error;
-}
-void FakeGenericChangeProcessor::set_get_sync_data_for_type_error(
-    const syncer::SyncError& error) {
-  get_sync_data_for_type_error_ = error;
-}
 void FakeGenericChangeProcessor::set_sync_model_has_user_created_nodes(
     bool has_nodes) {
   sync_model_has_user_created_nodes_ = has_nodes;
@@ -39,20 +30,16 @@
     bool success) {
   sync_model_has_user_created_nodes_success_ = success;
 }
-void FakeGenericChangeProcessor::set_crypto_ready_if_necessary(
-    bool crypto_ready) {
-  crypto_ready_if_necessary_ = crypto_ready;
-}
 
 syncer::SyncError FakeGenericChangeProcessor::ProcessSyncChanges(
     const tracked_objects::Location& from_here,
     const syncer::SyncChangeList& change_list) {
-  return process_sync_changes_error_;
+  return syncer::SyncError();
 }
 
 syncer::SyncError FakeGenericChangeProcessor::GetAllSyncDataReturnError(
     syncer::ModelType type, syncer::SyncDataList* current_sync_data) const {
-  return get_sync_data_for_type_error_;
+  return syncer::SyncError();
 }
 
 bool FakeGenericChangeProcessor::GetDataTypeContext(
@@ -73,7 +60,23 @@
 
 bool FakeGenericChangeProcessor::CryptoReadyIfNecessary(
     syncer::ModelType type) {
-  return crypto_ready_if_necessary_;
+  return true;
+}
+
+FakeGenericChangeProcessorFactory::FakeGenericChangeProcessorFactory(
+    scoped_ptr<FakeGenericChangeProcessor> processor)
+    : processor_(processor.Pass()) {}
+
+FakeGenericChangeProcessorFactory::~FakeGenericChangeProcessorFactory() {}
+
+scoped_ptr<GenericChangeProcessor>
+FakeGenericChangeProcessorFactory::CreateGenericChangeProcessor(
+    syncer::UserShare* user_share,
+    browser_sync::DataTypeErrorHandler* error_handler,
+    const base::WeakPtr<syncer::SyncableService>& local_service,
+    const base::WeakPtr<syncer::SyncMergeResult>& merge_result,
+    scoped_ptr<syncer::AttachmentService> attachment_service) {
+  return processor_.PassAs<GenericChangeProcessor>();
 }
 
 }  // namespace browser_sync
diff --git a/components/sync_driver/fake_generic_change_processor.h b/components/sync_driver/fake_generic_change_processor.h
index ae8117f..be9201b 100644
--- a/components/sync_driver/fake_generic_change_processor.h
+++ b/components/sync_driver/fake_generic_change_processor.h
@@ -7,6 +7,7 @@
 
 #include "components/sync_driver/generic_change_processor.h"
 
+#include "components/sync_driver/generic_change_processor_factory.h"
 #include "sync/api/sync_error.h"
 
 namespace browser_sync {
@@ -18,11 +19,8 @@
   virtual ~FakeGenericChangeProcessor();
 
   // Setters for GenericChangeProcessor implementation results.
-  void set_process_sync_changes_error(const syncer::SyncError& error);
-  void set_get_sync_data_for_type_error(const syncer::SyncError& error);
   void set_sync_model_has_user_created_nodes(bool has_nodes);
   void set_sync_model_has_user_created_nodes_success(bool success);
-  void set_crypto_ready_if_necessary(bool crypto_ready);
 
   // GenericChangeProcessor implementations.
   virtual syncer::SyncError ProcessSyncChanges(
@@ -39,11 +37,25 @@
   virtual bool CryptoReadyIfNecessary(syncer::ModelType type) OVERRIDE;
 
  private:
-  syncer::SyncError process_sync_changes_error_;
-  syncer::SyncError get_sync_data_for_type_error_;
   bool sync_model_has_user_created_nodes_;
   bool sync_model_has_user_created_nodes_success_;
-  bool crypto_ready_if_necessary_;
+};
+
+// Define a factory for FakeGenericChangeProcessor for convenience.
+class FakeGenericChangeProcessorFactory : public GenericChangeProcessorFactory {
+ public:
+  explicit FakeGenericChangeProcessorFactory(
+      scoped_ptr<FakeGenericChangeProcessor> processor);
+  virtual ~FakeGenericChangeProcessorFactory();
+  virtual scoped_ptr<GenericChangeProcessor> CreateGenericChangeProcessor(
+      syncer::UserShare* user_share,
+      browser_sync::DataTypeErrorHandler* error_handler,
+      const base::WeakPtr<syncer::SyncableService>& local_service,
+      const base::WeakPtr<syncer::SyncMergeResult>& merge_result,
+      scoped_ptr<syncer::AttachmentService> attachment_service) OVERRIDE;
+ private:
+  scoped_ptr<FakeGenericChangeProcessor> processor_;
+  DISALLOW_COPY_AND_ASSIGN(FakeGenericChangeProcessorFactory);
 };
 
 }  // namespace browser_sync
diff --git a/components/sync_driver/generic_change_processor.cc b/components/sync_driver/generic_change_processor.cc
index adc4c90..75ed373 100644
--- a/components/sync_driver/generic_change_processor.cc
+++ b/components/sync_driver/generic_change_processor.cc
@@ -36,6 +36,27 @@
   }
 }
 
+// Helper function to convert AttachmentId to AttachmentMetadataRecord.
+sync_pb::AttachmentMetadataRecord AttachmentIdToRecord(
+    const syncer::AttachmentId& attachment_id) {
+  sync_pb::AttachmentMetadataRecord record;
+  *record.mutable_id() = attachment_id.GetProto();
+  return record;
+}
+
+// Replace |write_nodes|'s attachment ids with |attachment_ids|.
+void SetAttachmentMetadata(const syncer::AttachmentIdList& attachment_ids,
+                           syncer::WriteNode* write_node) {
+  DCHECK(write_node);
+  sync_pb::AttachmentMetadata attachment_metadata;
+  std::transform(
+      attachment_ids.begin(),
+      attachment_ids.end(),
+      RepeatedFieldBackInserter(attachment_metadata.mutable_record()),
+      AttachmentIdToRecord);
+  write_node->SetAttachmentMetadata(attachment_metadata);
+}
+
 syncer::SyncData BuildRemoteSyncData(
     int64 sync_id,
     const syncer::BaseNode& read_node,
@@ -319,12 +340,11 @@
   }
 }
 
-syncer::SyncError AttemptDelete(
-    const syncer::SyncChange& change,
-    syncer::ModelType type,
-    const std::string& type_str,
-    syncer::WriteNode* node,
-    DataTypeErrorHandler* error_handler) {
+syncer::SyncError AttemptDelete(const syncer::SyncChange& change,
+                                syncer::ModelType type,
+                                const std::string& type_str,
+                                syncer::WriteNode* node,
+                                DataTypeErrorHandler* error_handler) {
   DCHECK_EQ(change.change_type(), syncer::SyncChange::ACTION_DELETE);
   if (change.sync_data().IsLocal()) {
     const std::string& tag = syncer::SyncDataLocal(change.sync_data()).GetTag();
@@ -368,12 +388,36 @@
   return syncer::SyncError();
 }
 
+// A callback invoked on completion of AttachmentService::StoreAttachment.
+void IgnoreStoreResult(const syncer::AttachmentService::StoreResult&) {
+  // TODO(maniscalco): Here is where we're going to update the in-directory
+  // entry to indicate that the attachments have been successfully stored on
+  // disk.  Why do we care?  Because we might crash after persisting the
+  // directory to disk, but before we have persisted its attachments, leaving us
+  // with danging attachment ids.  Having a flag that indicates we've stored the
+  // entry will allow us to detect and filter entries with dangling attachment
+  // ids (bug 368353).
+}
+
+void StoreAttachments(syncer::AttachmentService* attachment_service,
+                      const syncer::AttachmentList& attachments) {
+  DCHECK(attachment_service);
+  syncer::AttachmentService::StoreCallback ignore_store_result =
+      base::Bind(&IgnoreStoreResult);
+  attachment_service->StoreAttachments(attachments, ignore_store_result);
+}
+
 }  // namespace
 
 syncer::SyncError GenericChangeProcessor::ProcessSyncChanges(
     const tracked_objects::Location& from_here,
     const syncer::SyncChangeList& list_of_changes) {
   DCHECK(CalledOnValidThread());
+
+  // Keep track of brand new attachments so we can persist them on this device
+  // and upload them to the server.
+  syncer::AttachmentList new_attachments;
+
   syncer::WriteTransaction trans(from_here, share_handle());
 
   for (syncer::SyncChangeList::const_iterator iter = list_of_changes.begin();
@@ -391,20 +435,19 @@
         NOTREACHED();
         return error;
       }
-      attachment_service_->OnSyncDataDelete(change.sync_data());
       if (merge_result_.get()) {
         merge_result_->set_num_items_deleted(
             merge_result_->num_items_deleted() + 1);
       }
     } else if (change.change_type() == syncer::SyncChange::ACTION_ADD) {
-      syncer::SyncError error =
-          HandleActionAdd(change, type_str, type, trans, &sync_node);
+      syncer::SyncError error = HandleActionAdd(
+          change, type_str, type, trans, &sync_node, &new_attachments);
       if (error.IsSet()) {
         return error;
       }
     } else if (change.change_type() == syncer::SyncChange::ACTION_UPDATE) {
-      syncer::SyncError error =
-          HandleActionUpdate(change, type_str, type, trans, &sync_node);
+      syncer::SyncError error = HandleActionUpdate(
+          change, type_str, type, trans, &sync_node, &new_attachments);
       if (error.IsSet()) {
         return error;
       }
@@ -422,6 +465,11 @@
       return error;
     }
   }
+
+  if (!new_attachments.empty()) {
+    StoreAttachments(attachment_service_.get(), new_attachments);
+  }
+
   return syncer::SyncError();
 }
 
@@ -434,12 +482,14 @@
     const std::string& type_str,
     const syncer::ModelType& type,
     const syncer::WriteTransaction& trans,
-    syncer::WriteNode* sync_node) {
+    syncer::WriteNode* sync_node,
+    syncer::AttachmentList* new_attachments) {
   // TODO(sync): Handle other types of creation (custom parents, folders,
   // etc.).
   syncer::ReadNode root_node(&trans);
+  const syncer::SyncDataLocal sync_data_local(change.sync_data());
   if (root_node.InitByTagLookup(syncer::ModelTypeToRootTag(
-          change.sync_data().GetDataType())) != syncer::BaseNode::INIT_OK) {
+          sync_data_local.GetDataType())) != syncer::BaseNode::INIT_OK) {
     syncer::SyncError error(FROM_HERE,
                             syncer::SyncError::DATATYPE_ERROR,
                             "Failed to look up root node for type " + type_str,
@@ -452,9 +502,7 @@
   }
   syncer::WriteNode::InitUniqueByCreationResult result =
       sync_node->InitUniqueByCreation(
-          change.sync_data().GetDataType(),
-          root_node,
-          syncer::SyncDataLocal(change.sync_data()).GetTag());
+          sync_data_local.GetDataType(), root_node, sync_data_local.GetTag());
   if (result != syncer::WriteNode::INIT_SUCCESS) {
     std::string error_prefix = "Failed to create " + type_str + " node: " +
                                change.location().ToString() + ", ";
@@ -503,8 +551,18 @@
     }
   }
   sync_node->SetTitle(change.sync_data().GetTitle());
-  SetNodeSpecifics(change.sync_data().GetSpecifics(), sync_node);
-  attachment_service_->OnSyncDataAdd(change.sync_data());
+  SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node);
+
+  syncer::AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds();
+  SetAttachmentMetadata(attachment_ids, sync_node);
+
+  // Return any newly added attachments.
+  const syncer::AttachmentList& local_attachments_for_upload =
+      sync_data_local.GetLocalAttachmentsForUpload();
+  new_attachments->insert(new_attachments->end(),
+                          local_attachments_for_upload.begin(),
+                          local_attachments_for_upload.end());
+
   if (merge_result_.get()) {
     merge_result_->set_num_items_added(merge_result_->num_items_added() + 1);
   }
@@ -519,12 +577,14 @@
     const std::string& type_str,
     const syncer::ModelType& type,
     const syncer::WriteTransaction& trans,
-    syncer::WriteNode* sync_node) {
+    syncer::WriteNode* sync_node,
+    syncer::AttachmentList* new_attachments) {
   // TODO(zea): consider having this logic for all possible changes?
+
+  const syncer::SyncDataLocal sync_data_local(change.sync_data());
   syncer::BaseNode::InitByLookupResult result =
-      sync_node->InitByClientTagLookup(
-          change.sync_data().GetDataType(),
-          syncer::SyncDataLocal(change.sync_data()).GetTag());
+      sync_node->InitByClientTagLookup(sync_data_local.GetDataType(),
+                                       sync_data_local.GetTag());
   if (result != syncer::BaseNode::INIT_OK) {
     std::string error_prefix = "Failed to load " + type_str + " node. " +
                                change.location().ToString() + ", ";
@@ -606,9 +666,16 @@
   }
 
   sync_node->SetTitle(change.sync_data().GetTitle());
-  SetNodeSpecifics(change.sync_data().GetSpecifics(), sync_node);
-  attachment_service_->OnSyncDataUpdate(sync_node->GetAttachmentIds(),
-                                        change.sync_data());
+  SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node);
+  SetAttachmentMetadata(sync_data_local.GetAttachmentIds(), sync_node);
+
+  // Return any newly added attachments.
+  const syncer::AttachmentList& local_attachments_for_upload =
+      sync_data_local.GetLocalAttachmentsForUpload();
+  new_attachments->insert(new_attachments->end(),
+                          local_attachments_for_upload.begin(),
+                          local_attachments_for_upload.end());
+
   if (merge_result_.get()) {
     merge_result_->set_num_items_modified(merge_result_->num_items_modified() +
                                           1);
@@ -653,7 +720,6 @@
 }
 
 void GenericChangeProcessor::StartImpl() {
-  DCHECK(CalledOnValidThread());
 }
 
 syncer::UserShare* GenericChangeProcessor::share_handle() const {
diff --git a/components/sync_driver/generic_change_processor.h b/components/sync_driver/generic_change_processor.h
index a5e33cb..9f55a53 100644
--- a/components/sync_driver/generic_change_processor.h
+++ b/components/sync_driver/generic_change_processor.h
@@ -98,18 +98,27 @@
   virtual syncer::UserShare* share_handle() const OVERRIDE;
 
  private:
-  // Helper methods for acting on changes coming from the datatype. These are
-  // logically part of ProcessSyncChanges.
+  // Logically part of ProcessSyncChanges.
+  //
+  // |new_attachments| is an output parameter containing newly added attachments
+  // that need to be stored.  This method will append to it.
   syncer::SyncError HandleActionAdd(const syncer::SyncChange& change,
                                     const std::string& type_str,
                                     const syncer::ModelType& type,
                                     const syncer::WriteTransaction& trans,
-                                    syncer::WriteNode* sync_node);
+                                    syncer::WriteNode* sync_node,
+                                    syncer::AttachmentList* new_attachments);
+
+  // Logically part of ProcessSyncChanges.
+  //
+  // |new_attachments| is an output parameter containing newly added attachments
+  // that need to be stored.  This method will append to it.
   syncer::SyncError HandleActionUpdate(const syncer::SyncChange& change,
                                        const std::string& type_str,
                                        const syncer::ModelType& type,
                                        const syncer::WriteTransaction& trans,
-                                       syncer::WriteNode* sync_node);
+                                       syncer::WriteNode* sync_node,
+                                       syncer::AttachmentList* new_attachments);
 
   // The SyncableService this change processor will forward changes on to.
   const base::WeakPtr<syncer::SyncableService> local_service_;
diff --git a/components/sync_driver/generic_change_processor_factory.cc b/components/sync_driver/generic_change_processor_factory.cc
new file mode 100644
index 0000000..8d9596b
--- /dev/null
+++ b/components/sync_driver/generic_change_processor_factory.cc
@@ -0,0 +1,32 @@
+// 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.
+
+#include "components/sync_driver/generic_change_processor_factory.h"
+
+#include "components/sync_driver/generic_change_processor.h"
+
+namespace browser_sync {
+
+
+GenericChangeProcessorFactory::GenericChangeProcessorFactory() {}
+
+GenericChangeProcessorFactory::~GenericChangeProcessorFactory() {}
+
+scoped_ptr<GenericChangeProcessor>
+GenericChangeProcessorFactory::CreateGenericChangeProcessor(
+      syncer::UserShare* user_share,
+      browser_sync::DataTypeErrorHandler* error_handler,
+      const base::WeakPtr<syncer::SyncableService>& local_service,
+      const base::WeakPtr<syncer::SyncMergeResult>& merge_result,
+      scoped_ptr<syncer::AttachmentService> attachment_service) {
+    DCHECK(user_share);
+    return make_scoped_ptr(new GenericChangeProcessor(
+        error_handler,
+        local_service,
+        merge_result,
+        user_share,
+        attachment_service.Pass())).Pass();
+  }
+
+}  // namespace browser_sync
diff --git a/components/sync_driver/generic_change_processor_factory.h b/components/sync_driver/generic_change_processor_factory.h
new file mode 100644
index 0000000..978d313
--- /dev/null
+++ b/components/sync_driver/generic_change_processor_factory.h
@@ -0,0 +1,45 @@
+// 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.
+
+#ifndef COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_FACTORY_H_
+#define COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_FACTORY_H_
+
+#include "base/memory/weak_ptr.h"
+
+namespace syncer {
+class AttachmentService;
+class SyncableService;
+class SyncMergeResult;
+struct UserShare;
+}
+
+namespace browser_sync {
+
+class DataTypeErrorHandler;
+class GenericChangeProcessor;
+
+// Because GenericChangeProcessors are created and used only from the model
+// thread, their lifetime is strictly shorter than other components like
+// DataTypeController, which live before / after communication with model
+// threads begins and ends.
+// The GCP is created "on the fly" at just the right time, on just the right
+// thread. Given that, we use a factory to instantiate GenericChangeProcessors
+// so that tests can choose to use a fake processor (i.e instead of injection).
+class GenericChangeProcessorFactory {
+ public:
+  GenericChangeProcessorFactory();
+  virtual ~GenericChangeProcessorFactory();
+  virtual scoped_ptr<GenericChangeProcessor> CreateGenericChangeProcessor(
+      syncer::UserShare* user_share,
+      browser_sync::DataTypeErrorHandler* error_handler,
+      const base::WeakPtr<syncer::SyncableService>& local_service,
+      const base::WeakPtr<syncer::SyncMergeResult>& merge_result,
+      scoped_ptr<syncer::AttachmentService> attachment_service);
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GenericChangeProcessorFactory);
+};
+
+}  // namespace browser_sync
+
+#endif  // COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_FACTORY_H_
diff --git a/components/sync_driver/generic_change_processor_unittest.cc b/components/sync_driver/generic_change_processor_unittest.cc
index 0fcce29..2434e89 100644
--- a/components/sync_driver/generic_change_processor_unittest.cc
+++ b/components/sync_driver/generic_change_processor_unittest.cc
@@ -10,6 +10,8 @@
 #include "base/strings/stringprintf.h"
 #include "components/sync_driver/data_type_error_handler_mock.h"
 #include "sync/api/attachments/fake_attachment_service.h"
+#include "sync/api/attachments/fake_attachment_store.h"
+#include "sync/api/attachments/fake_attachment_uploader.h"
 #include "sync/api/fake_syncable_service.h"
 #include "sync/api/sync_change.h"
 #include "sync/api/sync_merge_result.h"
@@ -27,16 +29,53 @@
 
 namespace {
 
+const char kTestData[] = "some data";
+
+// A mock that keeps track of attachments passed to StoreAttachments.
+class MockAttachmentService : public syncer::FakeAttachmentService {
+ public:
+  MockAttachmentService();
+  virtual ~MockAttachmentService();
+  virtual void StoreAttachments(const syncer::AttachmentList& attachments,
+                                const StoreCallback& callback) OVERRIDE;
+  std::vector<syncer::AttachmentList>* attachment_lists();
+
+ private:
+  std::vector<syncer::AttachmentList> attachment_lists_;
+};
+
+MockAttachmentService::MockAttachmentService()
+    : FakeAttachmentService(
+          scoped_ptr<syncer::AttachmentStore>(new syncer::FakeAttachmentStore(
+              base::MessageLoopProxy::current())),
+          scoped_ptr<syncer::AttachmentUploader>(
+              new syncer::FakeAttachmentUploader)) {
+}
+
+MockAttachmentService::~MockAttachmentService() {
+}
+
+void MockAttachmentService::StoreAttachments(
+    const syncer::AttachmentList& attachments,
+    const StoreCallback& callback) {
+  attachment_lists_.push_back(attachments);
+  FakeAttachmentService::StoreAttachments(attachments, callback);
+}
+
+std::vector<syncer::AttachmentList>* MockAttachmentService::attachment_lists() {
+  return &attachment_lists_;
+}
+
 class SyncGenericChangeProcessorTest : public testing::Test {
  public:
   // It doesn't matter which type we use.  Just pick one.
   static const syncer::ModelType kType = syncer::PREFERENCES;
 
-  SyncGenericChangeProcessorTest() :
-      sync_merge_result_(kType),
-      merge_result_ptr_factory_(&sync_merge_result_),
-      syncable_service_ptr_factory_(&fake_syncable_service_) {
-  }
+  SyncGenericChangeProcessorTest()
+      : sync_merge_result_(kType),
+        merge_result_ptr_factory_(&sync_merge_result_),
+        syncable_service_ptr_factory_(&fake_syncable_service_),
+        mock_attachment_service_(NULL) {}
 
   virtual void SetUp() OVERRIDE {
     test_user_share_.SetUp();
@@ -47,15 +86,23 @@
                                         test_user_share_.user_share());
     }
     test_user_share_.encryption_handler()->Init();
+    scoped_ptr<MockAttachmentService> mock_attachment_service(
+        new MockAttachmentService);
+    // GenericChangeProcessor takes ownership of the AttachmentService, but we
+    // need to have a pointer to it so we can see that it was used properly.
+    // Take a pointer and trust that GenericChangeProcessor does not prematurely
+    // destroy it.
+    mock_attachment_service_ = mock_attachment_service.get();
     change_processor_.reset(new GenericChangeProcessor(
         &data_type_error_handler_,
         syncable_service_ptr_factory_.GetWeakPtr(),
         merge_result_ptr_factory_.GetWeakPtr(),
         test_user_share_.user_share(),
-        syncer::FakeAttachmentService::CreateForTest()));
+        mock_attachment_service.PassAs<syncer::AttachmentService>()));
   }
 
   virtual void TearDown() OVERRIDE {
+    mock_attachment_service_ = NULL;
     test_user_share_.TearDown();
   }
 
@@ -78,6 +125,10 @@
     return test_user_share_.user_share();
   }
 
+  MockAttachmentService* mock_attachment_service() {
+    return mock_attachment_service_;
+  }
+
  private:
   base::MessageLoopForUI loop_;
 
@@ -90,6 +141,7 @@
 
   DataTypeErrorHandlerMock data_type_error_handler_;
   syncer::TestUserShare test_user_share_;
+  MockAttachmentService* mock_attachment_service_;
 
   scoped_ptr<GenericChangeProcessor> change_processor_;
 };
@@ -239,8 +291,60 @@
   }
 }
 
-// TODO(maniscalco): Add test cases that verify GenericChangeProcessor calls the
-// right methods on its AttachmentService at the right times (bug 353303).
+// Verify that attachments on newly added or updated SyncData are passed to the
+// AttachmentService.
+TEST_F(SyncGenericChangeProcessorTest,
+       ProcessSyncChanges_AddUpdateWithAttachment) {
+  std::string tag = "client_tag";
+  std::string title = "client_title";
+  sync_pb::EntitySpecifics specifics;
+  sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference();
+  pref_specifics->set_name("test");
+  syncer::AttachmentList attachments;
+  scoped_refptr<base::RefCountedString> attachment_data =
+      new base::RefCountedString;
+  attachment_data->data() = kTestData;
+  attachments.push_back(syncer::Attachment::Create(attachment_data));
+  attachments.push_back(syncer::Attachment::Create(attachment_data));
+
+  // Add a SyncData with two attachments.
+  syncer::SyncChangeList change_list;
+  change_list.push_back(
+      syncer::SyncChange(FROM_HERE,
+                         syncer::SyncChange::ACTION_ADD,
+                         syncer::SyncData::CreateLocalDataWithAttachments(
+                             tag, title, specifics, attachments)));
+  ASSERT_FALSE(
+      change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
+
+  // Check that the AttachmentService received the new attachments.
+  ASSERT_EQ(mock_attachment_service()->attachment_lists()->size(), 1U);
+  const syncer::AttachmentList& attachments_added =
+      mock_attachment_service()->attachment_lists()->front();
+  ASSERT_EQ(attachments_added.size(), 2U);
+  ASSERT_EQ(attachments_added[0].GetId(), attachments[0].GetId());
+  ASSERT_EQ(attachments_added[1].GetId(), attachments[1].GetId());
+
+  // Update the SyncData, replacing its two attachments with one new attachment.
+  syncer::AttachmentList new_attachments;
+  new_attachments.push_back(syncer::Attachment::Create(attachment_data));
+  mock_attachment_service()->attachment_lists()->clear();
+  change_list.clear();
+  change_list.push_back(
+      syncer::SyncChange(FROM_HERE,
+                         syncer::SyncChange::ACTION_UPDATE,
+                         syncer::SyncData::CreateLocalDataWithAttachments(
+                             tag, title, specifics, new_attachments)));
+  ASSERT_FALSE(
+      change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
+
+  // Check that the AttachmentService received it.
+  ASSERT_EQ(mock_attachment_service()->attachment_lists()->size(), 1U);
+  const syncer::AttachmentList& new_attachments_added =
+      mock_attachment_service()->attachment_lists()->front();
+  ASSERT_EQ(new_attachments_added.size(), 1U);
+  ASSERT_EQ(new_attachments_added[0].GetId(), new_attachments[0].GetId());
+}
 
 }  // namespace
 
diff --git a/components/sync_driver/proxy_data_type_controller.cc b/components/sync_driver/proxy_data_type_controller.cc
index 23a78a4..918617a 100644
--- a/components/sync_driver/proxy_data_type_controller.cc
+++ b/components/sync_driver/proxy_data_type_controller.cc
@@ -48,6 +48,10 @@
   return syncer::GROUP_PASSIVE;
 }
 
+ChangeProcessor* ProxyDataTypeController::GetChangeProcessor() const {
+  return NULL;
+}
+
 std::string ProxyDataTypeController::name() const {
   // For logging only.
   return syncer::ModelTypeToString(type());
diff --git a/components/sync_driver/proxy_data_type_controller.h b/components/sync_driver/proxy_data_type_controller.h
index 98a9c15..b5e3cf2 100644
--- a/components/sync_driver/proxy_data_type_controller.h
+++ b/components/sync_driver/proxy_data_type_controller.h
@@ -27,6 +27,7 @@
   virtual void Stop() OVERRIDE;
   virtual syncer::ModelType type() const OVERRIDE;
   virtual syncer::ModelSafeGroup model_safe_group() const OVERRIDE;
+  virtual ChangeProcessor* GetChangeProcessor() const OVERRIDE;
   virtual std::string name() const OVERRIDE;
   virtual State state() const OVERRIDE;
 
diff --git a/components/sync_driver/sync_frontend.h b/components/sync_driver/sync_frontend.h
index 47d76be..0a360a8 100644
--- a/components/sync_driver/sync_frontend.h
+++ b/components/sync_driver/sync_frontend.h
@@ -16,6 +16,9 @@
 class DataTypeDebugInfoListener;
 class JsBackend;
 class ProtocolEvent;
+struct CommitCounters;
+struct StatusCounters;
+struct UpdateCounters;
 }  // namespace syncer
 
 namespace sync_pb {
@@ -62,6 +65,30 @@
   // is listening for it.
   virtual void OnProtocolEvent(const syncer::ProtocolEvent& event) = 0;
 
+  // Called when we receive an updated commit counter for a directory type.
+  //
+  // Disabled by default.  Enable by calling
+  // EnableDirectoryTypeDebugInfoForwarding() on the backend.
+  virtual void OnDirectoryTypeCommitCounterUpdated(
+      syncer::ModelType type,
+      const syncer::CommitCounters& counters) = 0;
+
+  // Called when we receive an updated update counter for a directory type.
+  //
+  // Disabled by default.  Enable by calling
+  // EnableDirectoryTypeDebugInfoForwarding() on the backend.
+  virtual void OnDirectoryTypeUpdateCounterUpdated(
+      syncer::ModelType type,
+      const syncer::UpdateCounters& counters) = 0;
+
+  // Called when we receive an updated status counter for a directory type.
+  //
+  // Disabled by default.  Enable by calling
+  // EnableDirectoryTypeDebugInfoForwarding() on the backend.
+  virtual void OnDirectoryTypeStatusCounterUpdated(
+      syncer::ModelType type,
+      const syncer::StatusCounters& counters) = 0;
+
   // The status of the connection to the sync server has changed.
   virtual void OnConnectionStatusChange(
       syncer::ConnectionStatus status) = 0;
diff --git a/components/test/data/bookmarks/meta_info_as_string.json b/components/test/data/bookmarks/meta_info_as_string.json
new file mode 100644
index 0000000..3f55d72
--- /dev/null
+++ b/components/test/data/bookmarks/meta_info_as_string.json
@@ -0,0 +1,46 @@
+{
+   "checksum": "cc00e05e4e09b3ed71eb17b8e333dc98",
+   "roots": {
+      "bookmark_bar": {
+         "children": [ {
+            "date_added": "13029639749250317",
+            "id": "4",
+            "meta_info": "{\"key\":\"value\",\"nested\":{\"key\":\"value3\"}}",
+            "name": "url1",
+            "type": "url",
+            "url": "http://www.url1.com/"
+         }, {
+            "date_added": "13029639749250417",
+            "id": "5",
+            "meta_info": "{\"key\":\"value2\",\"sync\":{\"transaction_version\":\"42\"}}",
+            "name": "url2",
+            "type": "url",
+            "url": "http://www.url2.com/"
+         } ],
+         "date_added": "13029639749250227",
+         "date_modified": "13029639749250417",
+         "id": "1",
+         "name": "Bookmarks bar",
+         "type": "folder"
+      },
+      "meta_info": "{\"sync\":{\"transaction_version\":\"1\"}}",
+      "other": {
+         "children": [  ],
+         "date_added": "13029639749250300",
+         "date_modified": "0",
+         "id": "2",
+         "name": "Other bookmarks",
+         "type": "folder"
+      },
+      "synced": {
+         "children": [  ],
+         "date_added": "13029639749250302",
+         "date_modified": "0",
+         "id": "3",
+         "name": "Mobile bookmarks",
+         "type": "folder"
+      }
+   },
+   "version": 1
+}
+
diff --git a/components/test/data/bookmarks/model_without_sync.json b/components/test/data/bookmarks/model_without_sync.json
new file mode 100644
index 0000000..517f834
--- /dev/null
+++ b/components/test/data/bookmarks/model_without_sync.json
@@ -0,0 +1,48 @@
+{
+   "checksum": "47c64556f92189712e9ba2ae0b485d62",
+   "roots": {
+      "bookmark_bar": {
+         "children": [ {
+            "children": [ {
+               "date_added": "12949698950422234",
+               "id": "5",
+               "name": "Bookmark Manager",
+               "type": "url",
+               "url": "chrome-extension://eemcgdkfndhakfknompkggombfjjjeno/main.html#3"
+            } ],
+            "date_added": "12949698938004572",
+            "date_modified": "12949698958396466",
+            "id": "3",
+            "name": "Folder A",
+            "type": "folder"
+         } ],
+         "date_added": "0",
+         "date_modified": "0",
+         "id": "1",
+         "name": "Bookmarks Bar",
+         "type": "folder"
+      },
+      "other": {
+         "children": [ {
+            "children": [ {
+               "date_added": "12949698958396466",
+               "id": "6",
+               "name": "Get started with Google Chrome",
+               "type": "url",
+               "url": "http://tools.google.com/chrome/intl/en/welcome.html"
+            } ],
+            "date_added": "12949698944107898",
+            "date_modified": "12949698961627573",
+            "id": "4",
+            "name": "Folder B",
+            "type": "folder"
+         } ],
+         "date_added": "0",
+         "date_modified": "0",
+         "id": "2",
+         "name": "Other Bookmarks",
+         "type": "folder"
+      }
+   },
+   "version": 1
+}
diff --git a/components/tracing.target.darwin-arm.mk b/components/tracing.target.darwin-arm.mk
index 0827c37..c938420 100644
--- a/components/tracing.target.darwin-arm.mk
+++ b/components/tracing.target.darwin-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -128,7 +127,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/tracing.target.darwin-x86.mk b/components/tracing.target.darwin-x86.mk
index 711274b..3fd87d8 100644
--- a/components/tracing.target.darwin-x86.mk
+++ b/components/tracing.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/tracing.target.darwin-x86_64.mk b/components/tracing.target.darwin-x86_64.mk
index d907902..f1e6c02 100644
--- a/components/tracing.target.darwin-x86_64.mk
+++ b/components/tracing.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/tracing.target.linux-arm.mk b/components/tracing.target.linux-arm.mk
index 0827c37..c938420 100644
--- a/components/tracing.target.linux-arm.mk
+++ b/components/tracing.target.linux-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -128,7 +127,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/tracing.target.linux-x86.mk b/components/tracing.target.linux-x86.mk
index 711274b..3fd87d8 100644
--- a/components/tracing.target.linux-x86.mk
+++ b/components/tracing.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/tracing.target.linux-x86_64.mk b/components/tracing.target.linux-x86_64.mk
index d907902..f1e6c02 100644
--- a/components/tracing.target.linux-x86_64.mk
+++ b/components/tracing.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/tracing/DEPS b/components/tracing/DEPS
index bd05a3e..9634ba4 100644
--- a/components/tracing/DEPS
+++ b/components/tracing/DEPS
@@ -1,8 +1,4 @@
 include_rules = [
   "+base",
   "+ipc",
-
-  # This component will be compiled into NaCl, so it shouldn't depend on
-  # anything in content.
-  "-content",
 ]
diff --git a/components/translate/BUILD.gn b/components/translate/BUILD.gn
index 0afb521..f1eab98 100644
--- a/components/translate/BUILD.gn
+++ b/components/translate/BUILD.gn
@@ -41,7 +41,10 @@
     # TODO(brettw) move thise above. This project uses net headers. This is
     # excluded for Android since net doesn't work in the GN build at the time
     # of this writing.
-    deps += [ "//net" ]
+    deps += [
+      "//net",
+      "//ui/base:ui_base",
+    ]
   }
 }
 
diff --git a/components/translate/DEPS b/components/translate/DEPS
index e0eab64..df3f959 100644
--- a/components/translate/DEPS
+++ b/components/translate/DEPS
@@ -8,6 +8,5 @@
 
   # Translate is a layered component; subdirectories must explicitly introduce
   # the ability to use the content layer as appropriate.
-  "-content",
   "-components/translate/content",
 ]
diff --git a/components/translate/content/DEPS b/components/translate/content/DEPS
index d5923ee..c3505fa 100644
--- a/components/translate/content/DEPS
+++ b/components/translate/content/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
   "+content/public/common",
+  "+ipc",
 ]
diff --git a/components/url_matcher/url_matcher.cc b/components/url_matcher/url_matcher.cc
index f40906f..3798f7e 100644
--- a/components/url_matcher/url_matcher.cc
+++ b/components/url_matcher/url_matcher.cc
@@ -386,8 +386,8 @@
   // Clear port if it is implicit from scheme.
   if (url.has_port()) {
     const std::string& port = url.scheme();
-    if (url_canon::DefaultPortForScheme(port.c_str(), port.size()) ==
-            url.EffectiveIntPort()) {
+    if (url::DefaultPortForScheme(port.c_str(), port.size()) ==
+        url.EffectiveIntPort()) {
       replacements.ClearPort();
     }
   }
@@ -407,8 +407,8 @@
   // Clear port if it is implicit from scheme.
   if (url.has_port()) {
     const std::string& port = url.scheme();
-    if (url_canon::DefaultPortForScheme(port.c_str(), port.size()) ==
-            url.EffectiveIntPort()) {
+    if (url::DefaultPortForScheme(port.c_str(), port.size()) ==
+        url.EffectiveIntPort()) {
       replacements.ClearPort();
     }
   }
diff --git a/components/url_matcher/url_matcher_unittest.cc b/components/url_matcher/url_matcher_unittest.cc
index 1278f62..b69364c 100644
--- a/components/url_matcher/url_matcher_unittest.cc
+++ b/components/url_matcher/url_matcher_unittest.cc
@@ -159,10 +159,10 @@
   // non ASCII-7 characters. We test this here, because a change to this
   // guarantee breaks this implementation horribly.
   GURL url("http://www.föö.com/föö?föö#föö");
-  EXPECT_TRUE(IsStringASCII(url.host()));
-  EXPECT_TRUE(IsStringASCII(url.path()));
-  EXPECT_TRUE(IsStringASCII(url.query()));
-  EXPECT_FALSE(IsStringASCII(url.ref()));
+  EXPECT_TRUE(base::IsStringASCII(url.host()));
+  EXPECT_TRUE(base::IsStringASCII(url.path()));
+  EXPECT_TRUE(base::IsStringASCII(url.query()));
+  EXPECT_FALSE(base::IsStringASCII(url.ref()));
 }
 
 TEST(URLMatcherConditionFactoryTest, Criteria) {
diff --git a/components/usb_service.gypi b/components/usb_service.gypi
index 97f4a61..83de742 100644
--- a/components/usb_service.gypi
+++ b/components/usb_service.gypi
@@ -22,14 +22,22 @@
     'sources': [
       'usb_service/usb_context.cc',
       'usb_service/usb_context.h',
-      'usb_service/usb_device.cc',
+      'usb_service/usb_device_impl.cc',
+      'usb_service/usb_device_impl.h',
       'usb_service/usb_device.h',
       'usb_service/usb_device_handle.cc',
       'usb_service/usb_device_handle.h',
       'usb_service/usb_interface.cc',
       'usb_service/usb_interface.h',
-      'usb_service/usb_service.cc',
       'usb_service/usb_service.h',
+      'usb_service/usb_service_impl.cc',
+    ],
+    'conditions': [
+      ['OS == "linux"', {
+        'dependencies': [
+          '../build/linux/system.gyp:udev',
+        ],
+      }]
     ]
   }],
 }
diff --git a/components/usb_service/DEPS b/components/usb_service/DEPS
index 9013632..f416680 100644
--- a/components/usb_service/DEPS
+++ b/components/usb_service/DEPS
@@ -1,7 +1,6 @@
 include_rules = [
   "+chromeos",
 
-  "-content",
   "+content/public/browser",
 
   "-net",
diff --git a/components/usb_service/usb_context.h b/components/usb_service/usb_context.h
index 432617b..73e4ee6 100644
--- a/components/usb_service/usb_context.h
+++ b/components/usb_service/usb_context.h
@@ -27,7 +27,7 @@
   PlatformUsbContext context() const { return context_; }
 
  protected:
-  friend class UsbService;
+  friend class UsbServiceImpl;
   friend class base::RefCountedThreadSafe<UsbContext>;
 
   explicit UsbContext(PlatformUsbContext context);
diff --git a/components/usb_service/usb_device.cc b/components/usb_service/usb_device.cc
deleted file mode 100644
index 301e2e3..0000000
--- a/components/usb_service/usb_device.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-// 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.
-
-#include "components/usb_service/usb_device.h"
-
-#include <algorithm>
-
-#include "base/stl_util.h"
-#include "components/usb_service/usb_context.h"
-#include "components/usb_service/usb_device_handle.h"
-#include "content/public/browser/browser_thread.h"
-#include "third_party/libusb/src/libusb/libusb.h"
-
-#if defined(OS_CHROMEOS)
-#include "base/sys_info.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/permission_broker_client.h"
-#endif  // defined(OS_CHROMEOS)
-
-using content::BrowserThread;
-
-namespace {
-
-#if defined(OS_CHROMEOS)
-void OnRequestUsbAccessReplied(
-    const base::Callback<void(bool success)>& callback,
-    bool success) {
-  BrowserThread::PostTask(
-      BrowserThread::FILE, FROM_HERE, base::Bind(callback, success));
-}
-#endif  // defined(OS_CHROMEOS)
-
-}  // namespace
-
-namespace usb_service {
-
-UsbDevice::UsbDevice(scoped_refptr<UsbContext> context,
-                     PlatformUsbDevice platform_device,
-                     uint16 vendor_id,
-                     uint16 product_id,
-                     uint32 unique_id)
-    : platform_device_(platform_device),
-      vendor_id_(vendor_id),
-      product_id_(product_id),
-      unique_id_(unique_id),
-      context_(context) {
-  CHECK(platform_device) << "platform_device cannot be NULL";
-  libusb_ref_device(platform_device);
-}
-
-UsbDevice::UsbDevice()
-    : platform_device_(NULL),
-      vendor_id_(0),
-      product_id_(0),
-      unique_id_(0),
-      context_(NULL) {
-}
-
-UsbDevice::~UsbDevice() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  for (HandlesVector::iterator it = handles_.begin(); it != handles_.end();
-       ++it) {
-    (*it)->InternalClose();
-  }
-  STLClearObject(&handles_);
-  libusb_unref_device(platform_device_);
-}
-
-#if defined(OS_CHROMEOS)
-
-void UsbDevice::RequestUsbAcess(
-    int interface_id,
-    const base::Callback<void(bool success)>& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  // ChromeOS builds on non-ChromeOS machines (dev) should not attempt to
-  // use permission broker.
-  if (base::SysInfo::IsRunningOnChromeOS()) {
-    chromeos::PermissionBrokerClient* client =
-        chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient();
-    DCHECK(client) << "Could not get permission broker client.";
-    if (!client) {
-      callback.Run(false);
-      return;
-    }
-
-    BrowserThread::PostTask(
-        BrowserThread::UI,
-        FROM_HERE,
-        base::Bind(&chromeos::PermissionBrokerClient::RequestUsbAccess,
-                   base::Unretained(client),
-                   this->vendor_id_,
-                   this->product_id_,
-                   interface_id,
-                   base::Bind(&OnRequestUsbAccessReplied, callback)));
-  }
-}
-
-#endif
-
-scoped_refptr<UsbDeviceHandle> UsbDevice::Open() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  PlatformUsbDeviceHandle handle;
-  int rv = libusb_open(platform_device_, &handle);
-  if (LIBUSB_SUCCESS == rv) {
-    scoped_refptr<UsbConfigDescriptor> interfaces = ListInterfaces();
-    if (!interfaces)
-      return NULL;
-    scoped_refptr<UsbDeviceHandle> device_handle =
-        new UsbDeviceHandle(context_, this, handle, interfaces);
-    handles_.push_back(device_handle);
-    return device_handle;
-  }
-  return NULL;
-}
-
-bool UsbDevice::Close(scoped_refptr<UsbDeviceHandle> handle) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  for (HandlesVector::iterator it = handles_.begin(); it != handles_.end();
-       ++it) {
-    if (*it == handle) {
-      (*it)->InternalClose();
-      handles_.erase(it);
-      return true;
-    }
-  }
-  return false;
-}
-
-scoped_refptr<UsbConfigDescriptor> UsbDevice::ListInterfaces() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  PlatformUsbConfigDescriptor platform_config;
-  const int list_result =
-      libusb_get_active_config_descriptor(platform_device_, &platform_config);
-  if (list_result == 0)
-    return new UsbConfigDescriptor(platform_config);
-
-  return NULL;
-}
-
-void UsbDevice::OnDisconnect() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  HandlesVector handles;
-  swap(handles, handles_);
-  for (std::vector<scoped_refptr<UsbDeviceHandle> >::iterator it =
-           handles.begin();
-       it != handles.end();
-       ++it) {
-    (*it)->InternalClose();
-  }
-}
-
-}  // namespace usb_service
diff --git a/components/usb_service/usb_device.h b/components/usb_service/usb_device.h
index 2de4193..076af18 100644
--- a/components/usb_service/usb_device.h
+++ b/components/usb_service/usb_device.h
@@ -5,23 +5,15 @@
 #ifndef COMPONENTS_USB_SERVICE_USB_DEVICE_H_
 #define COMPONENTS_USB_SERVICE_USB_DEVICE_H_
 
-#include <vector>
-
 #include "base/basictypes.h"
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
-#include "base/threading/thread_checker.h"
-#include "components/usb_service/usb_interface.h"
 #include "components/usb_service/usb_service_export.h"
 
-struct libusb_device;
-
 namespace usb_service {
 
 class UsbDeviceHandle;
-class UsbContext;
-
-typedef libusb_device* PlatformUsbDevice;
+class UsbConfigDescriptor;
 
 // A UsbDevice object represents a detected USB device, providing basic
 // information about it. For further manipulation of the device, a
@@ -30,7 +22,6 @@
     : public base::RefCountedThreadSafe<UsbDevice> {
  public:
   // Accessors to basic information.
-  PlatformUsbDevice platform_device() const { return platform_device_; }
   uint16 vendor_id() const { return vendor_id_; }
   uint16 product_id() const { return product_id_; }
   uint32 unique_id() const { return unique_id_; }
@@ -42,56 +33,36 @@
   // not be used and this method fails if the device is claimed.
   virtual void RequestUsbAcess(
       int interface_id,
-      const base::Callback<void(bool success)>& callback);
+      const base::Callback<void(bool success)>& callback) = 0;
 #endif  // OS_CHROMEOS
 
   // Creates a UsbDeviceHandle for further manipulation.
   // Blocking method. Must be called on FILE thread.
-  virtual scoped_refptr<UsbDeviceHandle> Open();
+  virtual scoped_refptr<UsbDeviceHandle> Open() = 0;
 
   // Explicitly closes a device handle. This method will be automatically called
   // by the destructor of a UsbDeviceHandle as well.
   // Closing a closed handle is a safe
   // Blocking method. Must be called on FILE thread.
-  virtual bool Close(scoped_refptr<UsbDeviceHandle> handle);
+  virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) = 0;
 
   // Lists the interfaces provided by the device and fills the given
   // UsbConfigDescriptor.
   // Blocking method. Must be called on FILE thread.
-  virtual scoped_refptr<UsbConfigDescriptor> ListInterfaces();
+  virtual scoped_refptr<UsbConfigDescriptor> ListInterfaces() = 0;
 
  protected:
-  friend class UsbService;
-  friend class base::RefCountedThreadSafe<UsbDevice>;
+  UsbDevice(uint16 vendor_id, uint16 product_id, uint32 unique_id)
+      : vendor_id_(vendor_id), product_id_(product_id), unique_id_(unique_id) {}
 
-  // Called by UsbService only;
-  UsbDevice(scoped_refptr<UsbContext> context,
-            PlatformUsbDevice platform_device,
-            uint16 vendor_id,
-            uint16 product_id,
-            uint32 unique_id);
-
-  // Constructor called in test only.
-  UsbDevice();
-  virtual ~UsbDevice();
-
-  // Called only be UsbService.
-  virtual void OnDisconnect();
+  virtual ~UsbDevice() {}
 
  private:
-  PlatformUsbDevice platform_device_;
-  uint16 vendor_id_;
-  uint16 product_id_;
-  uint32 unique_id_;
+  friend class base::RefCountedThreadSafe<UsbDevice>;
 
-  // Retain the context so that it will not be released before UsbDevice.
-  scoped_refptr<UsbContext> context_;
-
-  // Opened handles.
-  typedef std::vector<scoped_refptr<UsbDeviceHandle> > HandlesVector;
-  HandlesVector handles_;
-
-  base::ThreadChecker thread_checker_;
+  const uint16 vendor_id_;
+  const uint16 product_id_;
+  const uint32 unique_id_;
 
   DISALLOW_COPY_AND_ASSIGN(UsbDevice);
 };
diff --git a/components/usb_service/usb_device_handle.cc b/components/usb_service/usb_device_handle.cc
index b341368..f0f368e 100644
--- a/components/usb_service/usb_device_handle.cc
+++ b/components/usb_service/usb_device_handle.cc
@@ -22,6 +22,8 @@
 
 namespace usb_service {
 
+typedef libusb_device* PlatformUsbDevice;
+
 void HandleTransferCompletion(usb_service::PlatformUsbTransferHandle transfer);
 
 namespace {
diff --git a/components/usb_service/usb_device_handle.h b/components/usb_service/usb_device_handle.h
index 60b7c64..2b03a8a 100644
--- a/components/usb_service/usb_device_handle.h
+++ b/components/usb_service/usb_device_handle.h
@@ -112,7 +112,7 @@
 
  protected:
   friend class base::RefCountedThreadSafe<UsbDeviceHandle>;
-  friend class UsbDevice;
+  friend class UsbDeviceImpl;
 
   // This constructor is called by UsbDevice.
   UsbDeviceHandle(scoped_refptr<UsbContext> context,
diff --git a/components/usb_service/usb_device_impl.cc b/components/usb_service/usb_device_impl.cc
new file mode 100644
index 0000000..17c8337
--- /dev/null
+++ b/components/usb_service/usb_device_impl.cc
@@ -0,0 +1,146 @@
+// 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.
+
+#include "components/usb_service/usb_device_impl.h"
+
+#include <algorithm>
+
+#include "base/stl_util.h"
+#include "components/usb_service/usb_context.h"
+#include "components/usb_service/usb_device_handle.h"
+#include "content/public/browser/browser_thread.h"
+#include "third_party/libusb/src/libusb/libusb.h"
+
+#if defined(OS_CHROMEOS)
+#include "base/sys_info.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/permission_broker_client.h"
+#endif  // defined(OS_CHROMEOS)
+
+using content::BrowserThread;
+
+namespace {
+
+#if defined(OS_CHROMEOS)
+void OnRequestUsbAccessReplied(
+    const base::Callback<void(bool success)>& callback,
+    bool success) {
+  BrowserThread::PostTask(
+      BrowserThread::FILE, FROM_HERE, base::Bind(callback, success));
+}
+#endif  // defined(OS_CHROMEOS)
+
+}  // namespace
+
+namespace usb_service {
+
+UsbDeviceImpl::UsbDeviceImpl(scoped_refptr<UsbContext> context,
+                             PlatformUsbDevice platform_device,
+                             uint16 vendor_id,
+                             uint16 product_id,
+                             uint32 unique_id)
+    : UsbDevice(vendor_id, product_id, unique_id),
+      platform_device_(platform_device),
+      context_(context) {
+  CHECK(platform_device) << "platform_device cannot be NULL";
+  libusb_ref_device(platform_device);
+}
+
+UsbDeviceImpl::~UsbDeviceImpl() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  for (HandlesVector::iterator it = handles_.begin(); it != handles_.end();
+       ++it) {
+    (*it)->InternalClose();
+  }
+  STLClearObject(&handles_);
+  libusb_unref_device(platform_device_);
+}
+
+#if defined(OS_CHROMEOS)
+
+void UsbDeviceImpl::RequestUsbAcess(
+    int interface_id,
+    const base::Callback<void(bool success)>& callback) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  // ChromeOS builds on non-ChromeOS machines (dev) should not attempt to
+  // use permission broker.
+  if (base::SysInfo::IsRunningOnChromeOS()) {
+    chromeos::PermissionBrokerClient* client =
+        chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient();
+    DCHECK(client) << "Could not get permission broker client.";
+    if (!client) {
+      callback.Run(false);
+      return;
+    }
+
+    BrowserThread::PostTask(
+        BrowserThread::UI,
+        FROM_HERE,
+        base::Bind(&chromeos::PermissionBrokerClient::RequestUsbAccess,
+                   base::Unretained(client),
+                   vendor_id(),
+                   product_id(),
+                   interface_id,
+                   base::Bind(&OnRequestUsbAccessReplied, callback)));
+  }
+}
+
+#endif
+
+scoped_refptr<UsbDeviceHandle> UsbDeviceImpl::Open() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  PlatformUsbDeviceHandle handle;
+  int rv = libusb_open(platform_device_, &handle);
+  if (LIBUSB_SUCCESS == rv) {
+    scoped_refptr<UsbConfigDescriptor> interfaces = ListInterfaces();
+    if (!interfaces)
+      return NULL;
+    scoped_refptr<UsbDeviceHandle> device_handle =
+        new UsbDeviceHandle(context_, this, handle, interfaces);
+    handles_.push_back(device_handle);
+    return device_handle;
+  }
+  return NULL;
+}
+
+bool UsbDeviceImpl::Close(scoped_refptr<UsbDeviceHandle> handle) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  for (HandlesVector::iterator it = handles_.begin(); it != handles_.end();
+       ++it) {
+    if (*it == handle) {
+      (*it)->InternalClose();
+      handles_.erase(it);
+      return true;
+    }
+  }
+  return false;
+}
+
+scoped_refptr<UsbConfigDescriptor> UsbDeviceImpl::ListInterfaces() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  PlatformUsbConfigDescriptor platform_config;
+  const int list_result =
+      libusb_get_active_config_descriptor(platform_device_, &platform_config);
+  if (list_result == 0)
+    return new UsbConfigDescriptor(platform_config);
+
+  return NULL;
+}
+
+void UsbDeviceImpl::OnDisconnect() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  HandlesVector handles;
+  swap(handles, handles_);
+  for (std::vector<scoped_refptr<UsbDeviceHandle> >::iterator it =
+           handles.begin();
+       it != handles.end();
+       ++it) {
+    (*it)->InternalClose();
+  }
+}
+
+}  // namespace usb_service
diff --git a/components/usb_service/usb_device_impl.h b/components/usb_service/usb_device_impl.h
new file mode 100644
index 0000000..eafbe15
--- /dev/null
+++ b/components/usb_service/usb_device_impl.h
@@ -0,0 +1,67 @@
+// 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.
+
+#ifndef COMPONENTS_USB_SERVICE_USB_DEVICE_IMPL_H_
+#define COMPONENTS_USB_SERVICE_USB_DEVICE_IMPL_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/threading/thread_checker.h"
+#include "components/usb_service/usb_device.h"
+
+struct libusb_device;
+
+namespace usb_service {
+
+class UsbDeviceHandle;
+class UsbContext;
+
+typedef libusb_device* PlatformUsbDevice;
+
+class UsbDeviceImpl : public UsbDevice {
+ public:
+// UsbDevice implementation:
+#if defined(OS_CHROMEOS)
+  virtual void RequestUsbAcess(
+      int interface_id,
+      const base::Callback<void(bool success)>& callback) OVERRIDE;
+#endif  // OS_CHROMEOS
+  virtual scoped_refptr<UsbDeviceHandle> Open() OVERRIDE;
+  virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE;
+  virtual scoped_refptr<UsbConfigDescriptor> ListInterfaces() OVERRIDE;
+
+ protected:
+  friend class UsbServiceImpl;
+
+  // Called by UsbServiceImpl only;
+  UsbDeviceImpl(scoped_refptr<UsbContext> context,
+                PlatformUsbDevice platform_device,
+                uint16 vendor_id,
+                uint16 product_id,
+                uint32 unique_id);
+
+  virtual ~UsbDeviceImpl();
+
+  // Called only be UsbService.
+  void OnDisconnect();
+
+ private:
+  base::ThreadChecker thread_checker_;
+  PlatformUsbDevice platform_device_;
+
+  // Retain the context so that it will not be released before UsbDevice.
+  scoped_refptr<UsbContext> context_;
+
+  // Opened handles.
+  typedef std::vector<scoped_refptr<UsbDeviceHandle> > HandlesVector;
+  HandlesVector handles_;
+
+  DISALLOW_COPY_AND_ASSIGN(UsbDeviceImpl);
+};
+
+}  // namespace usb_service
+
+#endif  // COMPONENTS_USB_SERVICE_USB_DEVICE_IMPL_H_
diff --git a/components/usb_service/usb_interface.cc b/components/usb_service/usb_interface.cc
index 67f1a9d..3194440 100644
--- a/components/usb_service/usb_interface.cc
+++ b/components/usb_service/usb_interface.cc
@@ -149,6 +149,12 @@
     : config_(config) {
 }
 
+// TODO(zvorygin): Used for tests only. Should be removed when
+// all interfaces are extracted properly.
+UsbConfigDescriptor::UsbConfigDescriptor() {
+  config_ = NULL;
+}
+
 UsbConfigDescriptor::~UsbConfigDescriptor() {
   if (config_ != NULL) {
     libusb_free_config_descriptor(config_);
diff --git a/components/usb_service/usb_interface.h b/components/usb_service/usb_interface.h
index 31e58a2..dc5ad85 100644
--- a/components/usb_service/usb_interface.h
+++ b/components/usb_service/usb_interface.h
@@ -126,15 +126,20 @@
 class USB_SERVICE_EXPORT UsbConfigDescriptor
     : public base::RefCounted<UsbConfigDescriptor> {
  public:
-  size_t GetNumInterfaces() const;
-  scoped_refptr<const UsbInterfaceDescriptor> GetInterface(size_t index) const;
+  virtual size_t GetNumInterfaces() const;
+  virtual scoped_refptr<const UsbInterfaceDescriptor> GetInterface(
+      size_t index) const;
+
+ protected:
+  // Constructor called in test only
+  UsbConfigDescriptor();
+  virtual ~UsbConfigDescriptor();
 
  private:
   friend class base::RefCounted<UsbConfigDescriptor>;
-  friend class UsbDevice;
+  friend class UsbDeviceImpl;
 
   explicit UsbConfigDescriptor(PlatformUsbConfigDescriptor config);
-  ~UsbConfigDescriptor();
 
   PlatformUsbConfigDescriptor config_;
 
diff --git a/components/usb_service/usb_service.cc b/components/usb_service/usb_service.cc
deleted file mode 100644
index 89b884f..0000000
--- a/components/usb_service/usb_service.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-// 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.
-
-#include "components/usb_service/usb_service.h"
-
-#include <set>
-#include <vector>
-
-#include "base/lazy_instance.h"
-#include "base/stl_util.h"
-#include "components/usb_service/usb_context.h"
-#include "components/usb_service/usb_device.h"
-#include "content/public/browser/browser_thread.h"
-#include "third_party/libusb/src/libusb/libusb.h"
-
-namespace usb_service {
-
-namespace {
-
-base::LazyInstance<scoped_ptr<UsbService> >::Leaky g_usb_service_instance =
-    LAZY_INSTANCE_INITIALIZER;
-
-}  // namespace
-
-// static
-UsbService* UsbService::GetInstance() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
-  UsbService* instance = g_usb_service_instance.Get().get();
-  if (!instance) {
-    PlatformUsbContext context = NULL;
-    if (libusb_init(&context) != LIBUSB_SUCCESS)
-      return NULL;
-    if (!context)
-      return NULL;
-
-    instance = new UsbService(context);
-    g_usb_service_instance.Get().reset(instance);
-  }
-  return instance;
-}
-
-scoped_refptr<UsbDevice> UsbService::GetDeviceById(uint32 unique_id) {
-  DCHECK(CalledOnValidThread());
-  RefreshDevices();
-  for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
-    if (it->second->unique_id() == unique_id)
-      return it->second;
-  }
-  return NULL;
-}
-
-void UsbService::GetDevices(std::vector<scoped_refptr<UsbDevice> >* devices) {
-  DCHECK(CalledOnValidThread());
-  STLClearObject(devices);
-  RefreshDevices();
-
-  for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
-    devices->push_back(it->second);
-  }
-}
-
-void UsbService::WillDestroyCurrentMessageLoop() {
-  DCHECK(CalledOnValidThread());
-  g_usb_service_instance.Get().reset(NULL);
-}
-
-UsbService::UsbService(PlatformUsbContext context)
-    : context_(new UsbContext(context)), next_unique_id_(0) {
-  base::MessageLoop::current()->AddDestructionObserver(this);
-}
-
-UsbService::~UsbService() {
-  base::MessageLoop::current()->RemoveDestructionObserver(this);
-  for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
-    it->second->OnDisconnect();
-  }
-}
-
-void UsbService::RefreshDevices() {
-  DCHECK(CalledOnValidThread());
-
-  libusb_device** platform_devices = NULL;
-  const ssize_t device_count =
-      libusb_get_device_list(context_->context(), &platform_devices);
-
-  std::set<UsbDevice*> connected_devices;
-  std::vector<PlatformUsbDevice> disconnected_devices;
-
-  // Populates new devices.
-  for (ssize_t i = 0; i < device_count; ++i) {
-    if (!ContainsKey(devices_, platform_devices[i])) {
-      libusb_device_descriptor descriptor;
-      // This test is needed. A valid vendor/produce pair is required.
-      if (0 != libusb_get_device_descriptor(platform_devices[i], &descriptor))
-        continue;
-      UsbDevice* new_device = new UsbDevice(context_,
-                                            platform_devices[i],
-                                            descriptor.idVendor,
-                                            descriptor.idProduct,
-                                            ++next_unique_id_);
-      devices_[platform_devices[i]] = new_device;
-      connected_devices.insert(new_device);
-    } else {
-      connected_devices.insert(devices_[platform_devices[i]].get());
-    }
-  }
-
-  // Find disconnected devices.
-  for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
-    if (!ContainsKey(connected_devices, it->second)) {
-      disconnected_devices.push_back(it->first);
-    }
-  }
-
-  // Remove disconnected devices from devices_.
-  for (size_t i = 0; i < disconnected_devices.size(); ++i) {
-    // UsbDevice will be destroyed after this. The corresponding
-    // PlatformUsbDevice will be unref'ed during this process.
-    devices_.erase(disconnected_devices[i]);
-  }
-
-  libusb_free_device_list(platform_devices, true);
-}
-
-}  // namespace usb_service
diff --git a/components/usb_service/usb_service.h b/components/usb_service/usb_service.h
index 3bf0a40..133cacd 100644
--- a/components/usb_service/usb_service.h
+++ b/components/usb_service/usb_service.h
@@ -5,71 +5,40 @@
 #ifndef COMPONENTS_USB_SERVICE_USB_SERVICE_H_
 #define COMPONENTS_USB_SERVICE_USB_SERVICE_H_
 
-#include <map>
-#include <utility>
 #include <vector>
 
-#include "base/basictypes.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
 #include "base/threading/non_thread_safe.h"
 #include "components/usb_service/usb_service_export.h"
 
-struct libusb_device;
-struct libusb_context;
-
 namespace usb_service {
 
-typedef struct libusb_device* PlatformUsbDevice;
-typedef struct libusb_context* PlatformUsbContext;
-
-class UsbContext;
 class UsbDevice;
 
 // The USB service handles creating and managing an event handler thread that is
 // used to manage and dispatch USB events. It is also responsible for device
 // discovery on the system, which allows it to re-use device handles to prevent
 // competition for the same USB device.
-class USB_SERVICE_EXPORT UsbService
-    : public base::MessageLoop::DestructionObserver,
-      public base::NonThreadSafe {
+class USB_SERVICE_EXPORT UsbService : public base::NonThreadSafe {
  public:
-  typedef scoped_ptr<std::vector<scoped_refptr<UsbDevice> > >
-      ScopedDeviceVector;
-
   // Must be called on FILE thread.
   // Returns NULL when failed to initialized.
   static UsbService* GetInstance();
 
-  scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id);
+  static void SetInstanceForTest(UsbService* instance);
+
+  virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) = 0;
 
   // Get all of the devices attached to the system, inserting them into
   // |devices|. Clears |devices| before use. The result will be sorted by id
   // in increasing order. Must be called on FILE thread.
-  void GetDevices(std::vector<scoped_refptr<UsbDevice> >* devices);
+  virtual void GetDevices(std::vector<scoped_refptr<UsbDevice> >* devices) = 0;
 
-  // base::MessageLoop::DestructionObserver implementation.
-  virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
-
- private:
+ protected:
   friend struct base::DefaultDeleter<UsbService>;
-
-  explicit UsbService(PlatformUsbContext context);
-  virtual ~UsbService();
-
-  // Enumerate USB devices from OS and Update devices_ map.
-  void RefreshDevices();
-
-  scoped_refptr<UsbContext> context_;
-
-  // TODO(ikarienator): Figure out a better solution.
-  uint32 next_unique_id_;
-
-  // The map from PlatformUsbDevices to UsbDevices.
-  typedef std::map<PlatformUsbDevice, scoped_refptr<UsbDevice> > DeviceMap;
-  DeviceMap devices_;
-
+  UsbService() {}
+  virtual ~UsbService() {}
   DISALLOW_COPY_AND_ASSIGN(UsbService);
 };
 
diff --git a/components/usb_service/usb_service_impl.cc b/components/usb_service/usb_service_impl.cc
new file mode 100644
index 0000000..bafb51b
--- /dev/null
+++ b/components/usb_service/usb_service_impl.cc
@@ -0,0 +1,168 @@
+// 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.
+
+#include "components/usb_service/usb_service.h"
+
+#include <map>
+#include <set>
+
+#include "base/lazy_instance.h"
+#include "base/message_loop/message_loop.h"
+#include "base/stl_util.h"
+#include "components/usb_service/usb_context.h"
+#include "components/usb_service/usb_device_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "third_party/libusb/src/libusb/libusb.h"
+
+namespace usb_service {
+
+namespace {
+
+base::LazyInstance<scoped_ptr<UsbService> >::Leaky g_usb_service_instance =
+    LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
+typedef struct libusb_device* PlatformUsbDevice;
+typedef struct libusb_context* PlatformUsbContext;
+
+class UsbServiceImpl
+    : public UsbService,
+      private base::MessageLoop::DestructionObserver {
+ public:
+  explicit UsbServiceImpl(PlatformUsbContext context);
+  virtual ~UsbServiceImpl();
+
+ private:
+  // usb_service::UsbService implementation
+  virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) OVERRIDE;
+  virtual void GetDevices(
+      std::vector<scoped_refptr<UsbDevice> >* devices) OVERRIDE;
+
+  // base::MessageLoop::DestructionObserver implementation.
+  virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
+
+  // Enumerate USB devices from OS and Update devices_ map.
+  void RefreshDevices();
+
+  scoped_refptr<UsbContext> context_;
+
+  // TODO(ikarienator): Figure out a better solution.
+  uint32 next_unique_id_;
+
+  // The map from PlatformUsbDevices to UsbDevices.
+  typedef std::map<PlatformUsbDevice, scoped_refptr<UsbDeviceImpl> > DeviceMap;
+  DeviceMap devices_;
+
+  DISALLOW_COPY_AND_ASSIGN(UsbServiceImpl);
+};
+
+scoped_refptr<UsbDevice> UsbServiceImpl::GetDeviceById(uint32 unique_id) {
+  DCHECK(CalledOnValidThread());
+  RefreshDevices();
+  for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
+    if (it->second->unique_id() == unique_id)
+      return it->second;
+  }
+  return NULL;
+}
+
+void UsbServiceImpl::GetDevices(
+    std::vector<scoped_refptr<UsbDevice> >* devices) {
+  DCHECK(CalledOnValidThread());
+  STLClearObject(devices);
+  RefreshDevices();
+
+  for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
+    devices->push_back(it->second);
+  }
+}
+
+void UsbServiceImpl::WillDestroyCurrentMessageLoop() {
+  DCHECK(CalledOnValidThread());
+  g_usb_service_instance.Get().reset(NULL);
+}
+
+UsbServiceImpl::UsbServiceImpl(PlatformUsbContext context)
+    : context_(new UsbContext(context)), next_unique_id_(0) {
+  base::MessageLoop::current()->AddDestructionObserver(this);
+}
+
+UsbServiceImpl::~UsbServiceImpl() {
+  base::MessageLoop::current()->RemoveDestructionObserver(this);
+  for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
+    it->second->OnDisconnect();
+  }
+}
+
+void UsbServiceImpl::RefreshDevices() {
+  DCHECK(CalledOnValidThread());
+
+  libusb_device** platform_devices = NULL;
+  const ssize_t device_count =
+      libusb_get_device_list(context_->context(), &platform_devices);
+
+  std::set<UsbDevice*> connected_devices;
+  std::vector<PlatformUsbDevice> disconnected_devices;
+
+  // Populates new devices.
+  for (ssize_t i = 0; i < device_count; ++i) {
+    if (!ContainsKey(devices_, platform_devices[i])) {
+      libusb_device_descriptor descriptor;
+      // This test is needed. A valid vendor/produce pair is required.
+      if (0 != libusb_get_device_descriptor(platform_devices[i], &descriptor))
+        continue;
+      UsbDeviceImpl* new_device = new UsbDeviceImpl(context_,
+                                                    platform_devices[i],
+                                                    descriptor.idVendor,
+                                                    descriptor.idProduct,
+                                                    ++next_unique_id_);
+      devices_[platform_devices[i]] = new_device;
+      connected_devices.insert(new_device);
+    } else {
+      connected_devices.insert(devices_[platform_devices[i]].get());
+    }
+  }
+
+  // Find disconnected devices.
+  for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
+    if (!ContainsKey(connected_devices, it->second)) {
+      disconnected_devices.push_back(it->first);
+    }
+  }
+
+  // Remove disconnected devices from devices_.
+  for (size_t i = 0; i < disconnected_devices.size(); ++i) {
+    // UsbDevice will be destroyed after this. The corresponding
+    // PlatformUsbDevice will be unref'ed during this process.
+    devices_.erase(disconnected_devices[i]);
+  }
+
+  libusb_free_device_list(platform_devices, true);
+}
+
+// static
+UsbService* UsbService::GetInstance() {
+  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  UsbService* instance = g_usb_service_instance.Get().get();
+  if (!instance) {
+    PlatformUsbContext context = NULL;
+    if (libusb_init(&context) != LIBUSB_SUCCESS)
+      return NULL;
+    if (!context)
+      return NULL;
+
+    instance = new UsbServiceImpl(context);
+    g_usb_service_instance.Get().reset(instance);
+  }
+  return instance;
+}
+
+// static
+void UsbService::SetInstanceForTest(UsbService* instance) {
+  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
+  g_usb_service_instance.Get().reset(instance);
+}
+
+}  // namespace usb_service
diff --git a/components/user_prefs.target.darwin-arm.mk b/components/user_prefs.target.darwin-arm.mk
index 4ecaa6d..eecb245 100644
--- a/components/user_prefs.target.darwin-arm.mk
+++ b/components/user_prefs.target.darwin-arm.mk
@@ -45,7 +45,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -96,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -176,7 +170,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -227,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/user_prefs.target.darwin-arm64.mk b/components/user_prefs.target.darwin-arm64.mk
index 19c91b9..cf31dcf 100644
--- a/components/user_prefs.target.darwin-arm64.mk
+++ b/components/user_prefs.target.darwin-arm64.mk
@@ -92,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -218,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/user_prefs.target.darwin-mips.mk b/components/user_prefs.target.darwin-mips.mk
index e865c99..f1160bf 100644
--- a/components/user_prefs.target.darwin-mips.mk
+++ b/components/user_prefs.target.darwin-mips.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -225,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/user_prefs.target.darwin-x86.mk b/components/user_prefs.target.darwin-x86.mk
index e16e009..b62545e 100644
--- a/components/user_prefs.target.darwin-x86.mk
+++ b/components/user_prefs.target.darwin-x86.mk
@@ -47,7 +47,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -96,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -177,7 +171,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -226,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/user_prefs.target.darwin-x86_64.mk b/components/user_prefs.target.darwin-x86_64.mk
index e78f72d..f820002 100644
--- a/components/user_prefs.target.darwin-x86_64.mk
+++ b/components/user_prefs.target.darwin-x86_64.mk
@@ -47,7 +47,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -97,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -228,11 +221,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/user_prefs.target.linux-arm.mk b/components/user_prefs.target.linux-arm.mk
index 4ecaa6d..eecb245 100644
--- a/components/user_prefs.target.linux-arm.mk
+++ b/components/user_prefs.target.linux-arm.mk
@@ -45,7 +45,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -96,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -176,7 +170,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -227,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/user_prefs.target.linux-arm64.mk b/components/user_prefs.target.linux-arm64.mk
index 19c91b9..cf31dcf 100644
--- a/components/user_prefs.target.linux-arm64.mk
+++ b/components/user_prefs.target.linux-arm64.mk
@@ -92,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -218,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/user_prefs.target.linux-mips.mk b/components/user_prefs.target.linux-mips.mk
index e865c99..f1160bf 100644
--- a/components/user_prefs.target.linux-mips.mk
+++ b/components/user_prefs.target.linux-mips.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -225,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/user_prefs.target.linux-x86.mk b/components/user_prefs.target.linux-x86.mk
index e16e009..b62545e 100644
--- a/components/user_prefs.target.linux-x86.mk
+++ b/components/user_prefs.target.linux-x86.mk
@@ -47,7 +47,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -96,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -177,7 +171,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -226,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/user_prefs.target.linux-x86_64.mk b/components/user_prefs.target.linux-x86_64.mk
index e78f72d..f820002 100644
--- a/components/user_prefs.target.linux-x86_64.mk
+++ b/components/user_prefs.target.linux-x86_64.mk
@@ -47,7 +47,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -97,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -228,11 +221,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/variations/DEPS b/components/variations/DEPS
new file mode 100644
index 0000000..6448868
--- /dev/null
+++ b/components/variations/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+third_party/mt19937ar",
+]
diff --git a/components/variations/proto/study.proto b/components/variations/proto/study.proto
index 384c0ec..e58b8f9 100644
--- a/components/variations/proto/study.proto
+++ b/components/variations/proto/study.proto
@@ -43,7 +43,7 @@
 
   // An experiment within the study.
   //
-  // Next tag: 8
+  // Next tag: 9
   message Experiment {
     // A named parameter value for this experiment.
     //
@@ -68,6 +68,10 @@
     // properties.
     optional uint64 google_web_experiment_id = 3;
 
+    // Optional id used to allow this experiment to trigger experimental
+    // behavior on Google web properties.
+    optional uint64 google_web_trigger_experiment_id = 8;
+
     // Optional id used to uniquely identify this experiment for Google Update.
     optional uint64 google_update_experiment_id = 4;
 
@@ -146,7 +150,7 @@
   // Filtering criteria specifying whether this study is applicable to a given
   // Chrome instance.
   //
-  // Next tag: 8
+  // Next tag: 10
   message Filter {
     // The start date of the study in Unix time format. (Seconds since midnight
     // January 1, 1970 UTC). See: http://en.wikipedia.org/wiki/Unix_time
@@ -186,6 +190,22 @@
     // applies to all form factors.
     // Ex: [PHONE, TABLET]
     repeated FormFactor form_factor = 7;
+
+    // List of ChromeOS hardware classes that will receive this study. Each
+    // entry is treated as a substring of the actual device hardware_class,
+    // so "FOO" will match the client's hardware class "Device FOOBAR". If
+    // omitted, the study applies to all hardware classes unless
+    // |exclude_hardware_class| is specified. Mutually exclusive with
+    // |exclude_hardware_class|.
+    repeated string hardware_class = 8;
+
+    // List of ChromeOS hardware classes that will be excluded in this
+    // study. Each entry is treated as a substring of the actual device
+    // hardware_class, so "FOO" will match the client's hardware class
+    // "Device FOOBAR". If omitted, the study applies to all hardware classes
+    // unless |hardware_class| is specified. Mutually exclusive with
+    // |hardware_class|.
+    repeated string exclude_hardware_class = 9;
   }
 
   // Filtering criteria for this study. A study that is filtered out for a given
diff --git a/components/variations/study_filtering.cc b/components/variations/study_filtering.cc
index aeb36cc..7f35e18 100644
--- a/components/variations/study_filtering.cc
+++ b/components/variations/study_filtering.cc
@@ -64,6 +64,41 @@
   return false;
 }
 
+bool CheckStudyHardwareClass(const Study_Filter& filter,
+                             const std::string& hardware_class) {
+  // Empty hardware_class and exclude_hardware_class matches all.
+  if (filter.hardware_class_size() == 0 &&
+      filter.exclude_hardware_class_size() == 0) {
+    return true;
+  }
+
+  // Checks if we are supposed to filter for a specified set of
+  // hardware_classes. Note that this means this overrides the
+  // exclude_hardware_class in case that ever occurs (which it shouldn't).
+  if (filter.hardware_class_size() > 0) {
+    for (int i = 0; i < filter.hardware_class_size(); ++i) {
+      // Check if the entry is a substring of |hardware_class|.
+      size_t position = hardware_class.find(filter.hardware_class(i));
+      if (position != std::string::npos)
+        return true;
+    }
+    // None of the requested hardware_classes match.
+    return false;
+  }
+
+  // Omit if matches any of the exclude entries.
+  for (int i = 0; i < filter.exclude_hardware_class_size(); ++i) {
+    // Check if the entry is a substring of |hardware_class|.
+    size_t position = hardware_class.find(
+        filter.exclude_hardware_class(i));
+    if (position != std::string::npos)
+      return false;
+  }
+
+  // None of the exclusions match, so this accepts.
+  return true;
+}
+
 bool CheckStudyLocale(const Study_Filter& filter, const std::string& locale) {
   // An empty locale list matches all locales.
   if (filter.locale_size() == 0)
@@ -130,7 +165,8 @@
     const base::Time& reference_date,
     const base::Version& version,
     Study_Channel channel,
-    Study_FormFactor form_factor) {
+    Study_FormFactor form_factor,
+    const std::string& hardware_class) {
   if (study.has_filter()) {
     if (!CheckStudyChannel(study.filter(), channel)) {
       DVLOG(1) << "Filtered out study " << study.name() << " due to channel.";
@@ -163,6 +199,13 @@
                   " due to start date.";
       return false;
     }
+
+    if (!CheckStudyHardwareClass(study.filter(), hardware_class)) {
+      DVLOG(1) << "Filtered out study " << study.name() <<
+                  " due to hardware_class.";
+      return false;
+    }
+
   }
 
   DVLOG(1) << "Kept study " << study.name() << ".";
@@ -178,6 +221,7 @@
     const base::Version& version,
     Study_Channel channel,
     Study_FormFactor form_factor,
+    const std::string& hardware_class,
     std::vector<ProcessedStudy>* filtered_studies) {
   DCHECK(version.IsValid());
 
@@ -191,7 +235,7 @@
   for (int i = 0; i < seed.study_size(); ++i) {
     const Study& study = seed.study(i);
     if (!internal::ShouldAddStudy(study, locale, reference_date, version,
-                                  channel, form_factor)) {
+                                  channel, form_factor, hardware_class)) {
       continue;
     }
 
diff --git a/components/variations/study_filtering.h b/components/variations/study_filtering.h
index 1c14fc9..bb8b09d 100644
--- a/components/variations/study_filtering.h
+++ b/components/variations/study_filtering.h
@@ -28,6 +28,11 @@
 bool CheckStudyFormFactor(const Study_Filter& filter,
                           Study_FormFactor form_factor);
 
+// Checks whether a study is applicable for the given |hardware_class| per
+// |filter|.
+bool CheckStudyHardwareClass(const Study_Filter& filter,
+                             const std::string& hardware_class);
+
 // Checks whether a study is applicable for the given |locale| per |filter|.
 bool CheckStudyLocale(const Study_Filter& filter, const std::string& locale);
 
@@ -46,15 +51,14 @@
 bool IsStudyExpired(const Study& study, const base::Time& date_time);
 
 // Returns whether |study| should be disabled according to its restriction
-// parameters. Uses |version_info| for min / max version checks,
-// |reference_date| for the start date check and |channel| for channel
-// checks.
+// parameters.
 bool ShouldAddStudy(const Study& study,
                     const std::string& locale,
                     const base::Time& reference_date,
                     const base::Version& version,
                     Study_Channel channel,
-                    Study_FormFactor form_factor);
+                    Study_FormFactor form_factor,
+                    const std::string& hardware_class);
 
 }  // namespace internal
 
@@ -67,6 +71,7 @@
                               const base::Version& version,
                               Study_Channel channel,
                               Study_FormFactor form_factor,
+                              const std::string& hardware_class,
                               std::vector<ProcessedStudy>* filtered_studies);
 
 }  // namespace chrome_variations
diff --git a/components/variations/study_filtering_unittest.cc b/components/variations/study_filtering_unittest.cc
index 84c5cf7..ff39d80 100644
--- a/components/variations/study_filtering_unittest.cc
+++ b/components/variations/study_filtering_unittest.cc
@@ -313,6 +313,65 @@
   }
 }
 
+TEST(VariationsStudyFilteringTest, CheckStudyHardwareClass) {
+  struct {
+    const char* hardware_class;
+    const char* exclude_hardware_class;
+    const char* actual_hardware_class;
+    bool expected_result;
+  } test_cases[] = {
+    // Neither filtered nor excluded set:
+    // True since empty is always a match.
+    {"", "", "fancy INTEL pear device", true},
+    {"", "", "", true},
+
+    // Filtered set:
+    {"apple,pear,orange", "", "apple", true},
+    {"apple,pear,orange", "", "fancy INTEL pear device", true},
+    {"apple,pear,orange", "", "fancy INTEL GRAPE device", false},
+    // Somehow tagged as both, but still valid.
+    {"apple,pear,orange", "", "fancy INTEL pear GRAPE device", true},
+    // Substring, so still valid.
+    {"apple,pear,orange", "", "fancy INTEL SNapple device", true},
+    // No issues with doubling.
+    {"apple,pear,orange", "", "fancy orange orange device", true},
+    // Empty, which is what would happen for non ChromeOS platforms.
+    {"apple,pear,orange", "", "", false},
+
+    // Excluded set:
+    {"", "apple,pear,orange", "apple", false},
+    {"", "apple,pear,orange", "fancy INTEL pear device", false},
+    {"", "apple,pear,orange", "fancy INTEL GRAPE device", true},
+    // Somehow tagged as both. Very excluded!
+    {"", "apple,pear,orange", "fancy INTEL pear GRAPE device", false},
+    // Substring, so still invalid.
+    {"", "apple,pear,orange", "fancy INTEL SNapple device", false},
+    // Empty.
+    {"", "apple,pear,orange", "", true},
+
+    // Not testing when both are set as it should never occur and should be
+    // considered undefined.
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+    Study_Filter filter;
+    std::vector<std::string> hardware_class;
+    base::SplitString(test_cases[i].hardware_class, ',', &hardware_class);
+    for (size_t j = 0; j < hardware_class.size(); ++j)
+      filter.add_hardware_class(hardware_class[j]);
+
+    std::vector<std::string> exclude_hardware_class;
+    base::SplitString(test_cases[i].exclude_hardware_class, ',',
+                      &exclude_hardware_class);
+    for (size_t j = 0; j < exclude_hardware_class.size(); ++j)
+      filter.add_exclude_hardware_class(exclude_hardware_class[j]);
+
+    EXPECT_EQ(test_cases[i].expected_result,
+              internal::CheckStudyHardwareClass(
+                  filter, test_cases[i].actual_hardware_class));
+  }
+}
+
 TEST(VariationsStudyFilteringTest, FilterAndValidateStudies) {
   const std::string kTrial1Name = "A";
   const std::string kGroup1Name = "Group1";
@@ -339,7 +398,7 @@
   std::vector<ProcessedStudy> processed_studies;
   FilterAndValidateStudies(
       seed, "en-CA", base::Time::Now(), base::Version("20.0.0.0"),
-      Study_Channel_STABLE, Study_FormFactor_DESKTOP, &processed_studies);
+      Study_Channel_STABLE, Study_FormFactor_DESKTOP, "", &processed_studies);
 
   // Check that only the first kTrial1Name study was kept.
   ASSERT_EQ(2U, processed_studies.size());
diff --git a/components/variations/variations_associated_data.cc b/components/variations/variations_associated_data.cc
index 64a6d6e..d0f9e50 100644
--- a/components/variations/variations_associated_data.cc
+++ b/components/variations/variations_associated_data.cc
@@ -33,14 +33,24 @@
                    const VariationID id,
                    const bool force) {
 #if !defined(NDEBUG)
+    DCHECK_EQ(3, ID_COLLECTION_COUNT);
+    // Ensure that at most one of the trigger/non-trigger web property IDs are
+    // set.
+    if (key == GOOGLE_WEB_PROPERTIES || key == GOOGLE_WEB_PROPERTIES_TRIGGER) {
+      IDCollectionKey other_key = key == GOOGLE_WEB_PROPERTIES ?
+          GOOGLE_WEB_PROPERTIES_TRIGGER : GOOGLE_WEB_PROPERTIES;
+      DCHECK_EQ(EMPTY_ID, GetID(other_key, group_identifier));
+    }
+
     // Validate that all collections with this |group_identifier| have the same
     // associated ID.
-    DCHECK_EQ(2, ID_COLLECTION_COUNT);
-    IDCollectionKey other_key = GOOGLE_WEB_PROPERTIES;
-    if (key == GOOGLE_WEB_PROPERTIES)
-      other_key = GOOGLE_UPDATE_SERVICE;
-    VariationID other_id = GetID(other_key, group_identifier);
-    DCHECK(other_id == EMPTY_ID || other_id == id);
+    for (int i = 0; i < ID_COLLECTION_COUNT; ++i) {
+      IDCollectionKey other_key = static_cast<IDCollectionKey>(i);
+      if (other_key == key)
+        continue;
+      VariationID other_id = GetID(other_key, group_identifier);
+      DCHECK(other_id == EMPTY_ID || other_id == id);
+    }
 #endif
 
     base::AutoLock scoped_lock(lock_);
diff --git a/components/variations/variations_associated_data.h b/components/variations/variations_associated_data.h
index bfc4a8f..2abf5af 100644
--- a/components/variations/variations_associated_data.h
+++ b/components/variations/variations_associated_data.h
@@ -74,8 +74,12 @@
 // separate ID associations for separate parties interested in VariationIDs.
 enum IDCollectionKey {
   // This collection is used by Google web properties, transmitted through the
-  // X-Chrome-Variations header.
+  // X-Client-Data header.
   GOOGLE_WEB_PROPERTIES,
+  // This collection is used by Google web properties for IDs that trigger
+  // server side experimental behavior, transmitted through the
+  // X-Client-Data header.
+  GOOGLE_WEB_PROPERTIES_TRIGGER,
   // This collection is used by Google update services, transmitted through the
   // Google Update experiment labels.
   GOOGLE_UPDATE_SERVICE,
diff --git a/components/variations/variations_associated_data_unittest.cc b/components/variations/variations_associated_data_unittest.cc
index 6fd5f74..8cb2e3d 100644
--- a/components/variations/variations_associated_data_unittest.cc
+++ b/components/variations/variations_associated_data_unittest.cc
@@ -177,6 +177,8 @@
   EXPECT_EQ(EMPTY_ID,
             GetIDForTrial(GOOGLE_WEB_PROPERTIES, trial_true.get()));
   EXPECT_EQ(EMPTY_ID,
+            GetIDForTrial(GOOGLE_WEB_PROPERTIES_TRIGGER, trial_true.get()));
+  EXPECT_EQ(EMPTY_ID,
             GetIDForTrial(GOOGLE_UPDATE_SERVICE, trial_true.get()));
 
   AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial_true->trial_name(),
@@ -192,6 +194,25 @@
             GetIDForTrial(GOOGLE_WEB_PROPERTIES, trial_true.get()));
   EXPECT_EQ(TEST_VALUE_A,
             GetIDForTrial(GOOGLE_UPDATE_SERVICE, trial_true.get()));
+
+  trial_true = CreateFieldTrial("d2", 10, default_name, &default_group_number);
+  ASSERT_EQ(default_group_number, trial_true->group());
+  ASSERT_EQ(default_name, trial_true->group_name());
+
+  AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES_TRIGGER,
+                             trial_true->trial_name(), default_name,
+                             TEST_VALUE_A);
+  EXPECT_EQ(TEST_VALUE_A,
+            GetIDForTrial(GOOGLE_WEB_PROPERTIES_TRIGGER, trial_true.get()));
+  EXPECT_EQ(EMPTY_ID,
+            GetIDForTrial(GOOGLE_UPDATE_SERVICE, trial_true.get()));
+
+  AssociateGoogleVariationID(GOOGLE_UPDATE_SERVICE, trial_true->trial_name(),
+                             default_name, TEST_VALUE_A);
+  EXPECT_EQ(TEST_VALUE_A,
+            GetIDForTrial(GOOGLE_WEB_PROPERTIES_TRIGGER, trial_true.get()));
+  EXPECT_EQ(TEST_VALUE_A,
+            GetIDForTrial(GOOGLE_UPDATE_SERVICE, trial_true.get()));
 }
 
 TEST_F(VariationsAssociatedDataTest, AssociateVariationParams) {
diff --git a/components/variations/variations_seed_processor.cc b/components/variations/variations_seed_processor.cc
index e155100..e468e4e 100644
--- a/components/variations/variations_seed_processor.cc
+++ b/components/variations/variations_seed_processor.cc
@@ -40,6 +40,14 @@
                                     experiment.name(),
                                     variation_id);
   }
+  if (experiment.has_google_web_trigger_experiment_id()) {
+    const VariationID variation_id =
+        static_cast<VariationID>(experiment.google_web_trigger_experiment_id());
+    AssociateGoogleVariationIDForce(GOOGLE_WEB_PROPERTIES_TRIGGER,
+                                    trial_name,
+                                    experiment.name(),
+                                    variation_id);
+  }
   if (experiment.has_google_update_experiment_id()) {
     const VariationID variation_id =
         static_cast<VariationID>(experiment.google_update_experiment_id());
@@ -64,10 +72,11 @@
     const base::Time& reference_date,
     const base::Version& version,
     Study_Channel channel,
-    Study_FormFactor form_factor) {
+    Study_FormFactor form_factor,
+    const std::string& hardware_class) {
   std::vector<ProcessedStudy> filtered_studies;
   FilterAndValidateStudies(seed, locale, reference_date, version, channel,
-                           form_factor, &filtered_studies);
+                           form_factor, hardware_class, &filtered_studies);
 
   for (size_t i = 0; i < filtered_studies.size(); ++i)
     CreateTrialFromStudy(filtered_studies[i]);
diff --git a/components/variations/variations_seed_processor.h b/components/variations/variations_seed_processor.h
index f6760ac..dd4d0c8 100644
--- a/components/variations/variations_seed_processor.h
+++ b/components/variations/variations_seed_processor.h
@@ -27,13 +27,15 @@
   virtual ~VariationsSeedProcessor();
 
   // Creates field trials from the specified variations |seed|, based on the
-  // specified configuration (locale, current date, version and channel).
+  // specified configuration (locale, current date, version, channel, form
+  // factor and hardware_class).
   void CreateTrialsFromSeed(const VariationsSeed& seed,
                             const std::string& locale,
                             const base::Time& reference_date,
                             const base::Version& version,
                             Study_Channel channel,
-                            Study_FormFactor form_factor);
+                            Study_FormFactor form_factor,
+                            const std::string& hardware_class);
 
  private:
   friend class VariationsSeedProcessorTest;
diff --git a/components/variations/variations_seed_processor_unittest.cc b/components/variations/variations_seed_processor_unittest.cc
index d882aed..833b5e0 100644
--- a/components/variations/variations_seed_processor_unittest.cc
+++ b/components/variations/variations_seed_processor_unittest.cc
@@ -196,7 +196,7 @@
     study1->set_expiry_date(TimeToProtoTime(year_ago));
     seed_processor.CreateTrialsFromSeed(seed, "en-CA", base::Time::Now(),
                                         version, Study_Channel_STABLE,
-                                        Study_FormFactor_DESKTOP);
+                                        Study_FormFactor_DESKTOP, "");
     EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName));
   }
 
@@ -208,7 +208,7 @@
     study2->set_expiry_date(TimeToProtoTime(year_ago));
     seed_processor.CreateTrialsFromSeed(seed, "en-CA", base::Time::Now(),
                                         version, Study_Channel_STABLE,
-                                        Study_FormFactor_DESKTOP);
+                                        Study_FormFactor_DESKTOP, "");
     EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName));
   }
 }
@@ -323,7 +323,7 @@
   seed_processor.CreateTrialsFromSeed(seed, "en-CA", base::Time::Now(),
                                       base::Version("20.0.0.0"),
                                       Study_Channel_STABLE,
-                                      Study_FormFactor_DESKTOP);
+                                      Study_FormFactor_DESKTOP, "");
 
   // Non-specified and ACTIVATION_EXPLICIT should not start active, but
   // ACTIVATION_AUTO should.
diff --git a/components/variations/variations_seed_simulator.cc b/components/variations/variations_seed_simulator.cc
index 94e4fbb..62b9aaa 100644
--- a/components/variations/variations_seed_simulator.cc
+++ b/components/variations/variations_seed_simulator.cc
@@ -114,10 +114,11 @@
     const base::Time& reference_date,
     const base::Version& version,
     Study_Channel channel,
-    Study_FormFactor form_factor) {
+    Study_FormFactor form_factor,
+    const std::string& hardware_class) {
   std::vector<ProcessedStudy> filtered_studies;
   FilterAndValidateStudies(seed, locale, reference_date, version, channel,
-                           form_factor, &filtered_studies);
+                           form_factor, hardware_class, &filtered_studies);
 
   return ComputeDifferences(filtered_studies);
 }
diff --git a/components/variations/variations_seed_simulator.h b/components/variations/variations_seed_simulator.h
index ef9207b..36110ce 100644
--- a/components/variations/variations_seed_simulator.h
+++ b/components/variations/variations_seed_simulator.h
@@ -58,7 +58,8 @@
                              const base::Time& reference_date,
                              const base::Version& version,
                              Study_Channel channel,
-                             Study_FormFactor form_factor);
+                             Study_FormFactor form_factor,
+                             const std::string& hardware_class);
 
  private:
   friend class VariationsSeedSimulatorTest;
diff --git a/components/visitedlink/DEPS b/components/visitedlink/DEPS
new file mode 100644
index 0000000..1c40d98
--- /dev/null
+++ b/components/visitedlink/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+ipc",
+]
diff --git a/components/visitedlink_browser.target.darwin-arm.mk b/components/visitedlink_browser.target.darwin-arm.mk
index 0beac38..7e37ec0 100644
--- a/components/visitedlink_browser.target.darwin-arm.mk
+++ b/components/visitedlink_browser.target.darwin-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/visitedlink_browser.target.darwin-x86.mk b/components/visitedlink_browser.target.darwin-x86.mk
index 974197b..74a6cef 100644
--- a/components/visitedlink_browser.target.darwin-x86.mk
+++ b/components/visitedlink_browser.target.darwin-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/visitedlink_browser.target.darwin-x86_64.mk b/components/visitedlink_browser.target.darwin-x86_64.mk
index 0a40c9b..bead5de 100644
--- a/components/visitedlink_browser.target.darwin-x86_64.mk
+++ b/components/visitedlink_browser.target.darwin-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/visitedlink_browser.target.linux-arm.mk b/components/visitedlink_browser.target.linux-arm.mk
index 0beac38..7e37ec0 100644
--- a/components/visitedlink_browser.target.linux-arm.mk
+++ b/components/visitedlink_browser.target.linux-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/visitedlink_browser.target.linux-x86.mk b/components/visitedlink_browser.target.linux-x86.mk
index 974197b..74a6cef 100644
--- a/components/visitedlink_browser.target.linux-x86.mk
+++ b/components/visitedlink_browser.target.linux-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/visitedlink_browser.target.linux-x86_64.mk b/components/visitedlink_browser.target.linux-x86_64.mk
index 0a40c9b..bead5de 100644
--- a/components/visitedlink_browser.target.linux-x86_64.mk
+++ b/components/visitedlink_browser.target.linux-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/visitedlink_common.target.darwin-arm.mk b/components/visitedlink_common.target.darwin-arm.mk
index 71b3566..3e11b5b 100644
--- a/components/visitedlink_common.target.darwin-arm.mk
+++ b/components/visitedlink_common.target.darwin-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -136,7 +135,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/visitedlink_common.target.darwin-x86.mk b/components/visitedlink_common.target.darwin-x86.mk
index 53a70db..9479306 100644
--- a/components/visitedlink_common.target.darwin-x86.mk
+++ b/components/visitedlink_common.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/visitedlink_common.target.darwin-x86_64.mk b/components/visitedlink_common.target.darwin-x86_64.mk
index e188731..493de2e 100644
--- a/components/visitedlink_common.target.darwin-x86_64.mk
+++ b/components/visitedlink_common.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/visitedlink_common.target.linux-arm.mk b/components/visitedlink_common.target.linux-arm.mk
index 71b3566..3e11b5b 100644
--- a/components/visitedlink_common.target.linux-arm.mk
+++ b/components/visitedlink_common.target.linux-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -136,7 +135,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/visitedlink_common.target.linux-x86.mk b/components/visitedlink_common.target.linux-x86.mk
index 53a70db..9479306 100644
--- a/components/visitedlink_common.target.linux-x86.mk
+++ b/components/visitedlink_common.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/visitedlink_common.target.linux-x86_64.mk b/components/visitedlink_common.target.linux-x86_64.mk
index e188731..493de2e 100644
--- a/components/visitedlink_common.target.linux-x86_64.mk
+++ b/components/visitedlink_common.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/visitedlink_renderer.target.darwin-arm.mk b/components/visitedlink_renderer.target.darwin-arm.mk
index c5fca37..be11c26 100644
--- a/components/visitedlink_renderer.target.darwin-arm.mk
+++ b/components/visitedlink_renderer.target.darwin-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -187,7 +181,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -237,11 +230,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/visitedlink_renderer.target.darwin-arm64.mk b/components/visitedlink_renderer.target.darwin-arm64.mk
index 3a764b7..162d311 100644
--- a/components/visitedlink_renderer.target.darwin-arm64.mk
+++ b/components/visitedlink_renderer.target.darwin-arm64.mk
@@ -89,11 +89,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -228,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/visitedlink_renderer.target.darwin-mips.mk b/components/visitedlink_renderer.target.darwin-mips.mk
index fc757f7..fb16861 100644
--- a/components/visitedlink_renderer.target.darwin-mips.mk
+++ b/components/visitedlink_renderer.target.darwin-mips.mk
@@ -92,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -235,11 +230,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/visitedlink_renderer.target.darwin-x86.mk b/components/visitedlink_renderer.target.darwin-x86.mk
index 0efc8f4..e839c64 100644
--- a/components/visitedlink_renderer.target.darwin-x86.mk
+++ b/components/visitedlink_renderer.target.darwin-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -94,11 +93,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -189,7 +183,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -238,11 +231,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/visitedlink_renderer.target.darwin-x86_64.mk b/components/visitedlink_renderer.target.darwin-x86_64.mk
index 55e5710..3292f84 100644
--- a/components/visitedlink_renderer.target.darwin-x86_64.mk
+++ b/components/visitedlink_renderer.target.darwin-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -94,11 +93,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -189,7 +183,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -238,11 +231,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/visitedlink_renderer.target.linux-arm.mk b/components/visitedlink_renderer.target.linux-arm.mk
index c5fca37..be11c26 100644
--- a/components/visitedlink_renderer.target.linux-arm.mk
+++ b/components/visitedlink_renderer.target.linux-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -187,7 +181,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -237,11 +230,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/visitedlink_renderer.target.linux-arm64.mk b/components/visitedlink_renderer.target.linux-arm64.mk
index 3a764b7..162d311 100644
--- a/components/visitedlink_renderer.target.linux-arm64.mk
+++ b/components/visitedlink_renderer.target.linux-arm64.mk
@@ -89,11 +89,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -228,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/visitedlink_renderer.target.linux-mips.mk b/components/visitedlink_renderer.target.linux-mips.mk
index fc757f7..fb16861 100644
--- a/components/visitedlink_renderer.target.linux-mips.mk
+++ b/components/visitedlink_renderer.target.linux-mips.mk
@@ -92,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -235,11 +230,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/visitedlink_renderer.target.linux-x86.mk b/components/visitedlink_renderer.target.linux-x86.mk
index 0efc8f4..e839c64 100644
--- a/components/visitedlink_renderer.target.linux-x86.mk
+++ b/components/visitedlink_renderer.target.linux-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -94,11 +93,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -189,7 +183,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -238,11 +231,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/visitedlink_renderer.target.linux-x86_64.mk b/components/visitedlink_renderer.target.linux-x86_64.mk
index 55e5710..3292f84 100644
--- a/components/visitedlink_renderer.target.linux-x86_64.mk
+++ b/components/visitedlink_renderer.target.linux-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -94,11 +93,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -189,7 +183,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -238,11 +231,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/web_contents_delegate_android.target.darwin-arm.mk b/components/web_contents_delegate_android.target.darwin-arm.mk
index 1c64af8..c42108f 100644
--- a/components/web_contents_delegate_android.target.darwin-arm.mk
+++ b/components/web_contents_delegate_android.target.darwin-arm.mk
@@ -49,7 +49,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -180,7 +174,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/web_contents_delegate_android.target.darwin-arm64.mk b/components/web_contents_delegate_android.target.darwin-arm64.mk
index 49a382b..c43f1b6 100644
--- a/components/web_contents_delegate_android.target.darwin-arm64.mk
+++ b/components/web_contents_delegate_android.target.darwin-arm64.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -221,11 +216,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/web_contents_delegate_android.target.darwin-mips.mk b/components/web_contents_delegate_android.target.darwin-mips.mk
index 6c340c9..956c709 100644
--- a/components/web_contents_delegate_android.target.darwin-mips.mk
+++ b/components/web_contents_delegate_android.target.darwin-mips.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -228,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/web_contents_delegate_android.target.darwin-x86.mk b/components/web_contents_delegate_android.target.darwin-x86.mk
index d040725..886de2a 100644
--- a/components/web_contents_delegate_android.target.darwin-x86.mk
+++ b/components/web_contents_delegate_android.target.darwin-x86.mk
@@ -51,7 +51,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -181,7 +175,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -229,11 +222,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/web_contents_delegate_android.target.darwin-x86_64.mk b/components/web_contents_delegate_android.target.darwin-x86_64.mk
index 8a014d6..7fed6e8 100644
--- a/components/web_contents_delegate_android.target.darwin-x86_64.mk
+++ b/components/web_contents_delegate_android.target.darwin-x86_64.mk
@@ -51,7 +51,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -182,7 +176,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -231,11 +224,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/web_contents_delegate_android.target.linux-arm.mk b/components/web_contents_delegate_android.target.linux-arm.mk
index 1c64af8..c42108f 100644
--- a/components/web_contents_delegate_android.target.linux-arm.mk
+++ b/components/web_contents_delegate_android.target.linux-arm.mk
@@ -49,7 +49,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -180,7 +174,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/web_contents_delegate_android.target.linux-arm64.mk b/components/web_contents_delegate_android.target.linux-arm64.mk
index 49a382b..c43f1b6 100644
--- a/components/web_contents_delegate_android.target.linux-arm64.mk
+++ b/components/web_contents_delegate_android.target.linux-arm64.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -221,11 +216,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/web_contents_delegate_android.target.linux-mips.mk b/components/web_contents_delegate_android.target.linux-mips.mk
index 6c340c9..956c709 100644
--- a/components/web_contents_delegate_android.target.linux-mips.mk
+++ b/components/web_contents_delegate_android.target.linux-mips.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -228,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/web_contents_delegate_android.target.linux-x86.mk b/components/web_contents_delegate_android.target.linux-x86.mk
index d040725..886de2a 100644
--- a/components/web_contents_delegate_android.target.linux-x86.mk
+++ b/components/web_contents_delegate_android.target.linux-x86.mk
@@ -51,7 +51,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -181,7 +175,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -229,11 +222,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/web_contents_delegate_android.target.linux-x86_64.mk b/components/web_contents_delegate_android.target.linux-x86_64.mk
index 8a014d6..7fed6e8 100644
--- a/components/web_contents_delegate_android.target.linux-x86_64.mk
+++ b/components/web_contents_delegate_android.target.linux-x86_64.mk
@@ -51,7 +51,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -182,7 +176,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -231,11 +224,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/components/web_contents_delegate_android/DEPS b/components/web_contents_delegate_android/DEPS
index 647531f..e560a54 100644
--- a/components/web_contents_delegate_android/DEPS
+++ b/components/web_contents_delegate_android/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "+content/public/browser",
+  "+content/public/common",
   "+jni",
   "+ui/base",
   "+ui/gfx",
diff --git a/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java b/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java
index ab134f5..c276916 100644
--- a/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java
+++ b/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java
@@ -47,7 +47,7 @@
 
     @CalledByNative
     public static ColorChooserAndroid createColorChooserAndroid(
-            int nativeColorChooserAndroid,
+            long nativeColorChooserAndroid,
             ContentViewCore contentViewCore,
             int initialColor,
             ColorSuggestion[] suggestions) {
diff --git a/components/web_contents_delegate_android/color_chooser_android.cc b/components/web_contents_delegate_android/color_chooser_android.cc
index a1dcf40..d946fa9 100644
--- a/components/web_contents_delegate_android/color_chooser_android.cc
+++ b/components/web_contents_delegate_android/color_chooser_android.cc
@@ -8,7 +8,6 @@
 #include "base/android/jni_string.h"
 #include "content/public/browser/android/content_view_core.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/color_suggestion.h"
 #include "jni/ColorChooserAndroid_jni.h"
 
diff --git a/components/web_contents_delegate_android_jni_headers.target.darwin-arm.mk b/components/web_contents_delegate_android_jni_headers.target.darwin-arm.mk
index 2602254..b1f2507 100644
--- a/components/web_contents_delegate_android_jni_headers.target.darwin-arm.mk
+++ b/components/web_contents_delegate_android_jni_headers.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_web_contents_delegate_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/WebContentsDelegateAndroid.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,7 +77,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -158,7 +160,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/web_contents_delegate_android_jni_headers.target.darwin-arm64.mk b/components/web_contents_delegate_android_jni_headers.target.darwin-arm64.mk
index 499fbbe..b6e8589 100644
--- a/components/web_contents_delegate_android_jni_headers.target.darwin-arm64.mk
+++ b/components/web_contents_delegate_android_jni_headers.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_web_contents_delegate_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/WebContentsDelegateAndroid.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/web_contents_delegate_android_jni_headers.target.darwin-mips.mk b/components/web_contents_delegate_android_jni_headers.target.darwin-mips.mk
index fc1db18..afcb2fa 100644
--- a/components/web_contents_delegate_android_jni_headers.target.darwin-mips.mk
+++ b/components/web_contents_delegate_android_jni_headers.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_web_contents_delegate_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/WebContentsDelegateAndroid.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/web_contents_delegate_android_jni_headers.target.darwin-x86.mk b/components/web_contents_delegate_android_jni_headers.target.darwin-x86.mk
index 7af4b3a..b8bd435 100644
--- a/components/web_contents_delegate_android_jni_headers.target.darwin-x86.mk
+++ b/components/web_contents_delegate_android_jni_headers.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_web_contents_delegate_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/WebContentsDelegateAndroid.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,7 +79,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -160,7 +162,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/web_contents_delegate_android_jni_headers.target.darwin-x86_64.mk b/components/web_contents_delegate_android_jni_headers.target.darwin-x86_64.mk
index 824999d..b7ae0f0 100644
--- a/components/web_contents_delegate_android_jni_headers.target.darwin-x86_64.mk
+++ b/components/web_contents_delegate_android_jni_headers.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_web_contents_delegate_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/WebContentsDelegateAndroid.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,7 +79,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -160,7 +162,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/web_contents_delegate_android_jni_headers.target.linux-arm.mk b/components/web_contents_delegate_android_jni_headers.target.linux-arm.mk
index 2602254..b1f2507 100644
--- a/components/web_contents_delegate_android_jni_headers.target.linux-arm.mk
+++ b/components/web_contents_delegate_android_jni_headers.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_web_contents_delegate_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/WebContentsDelegateAndroid.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,7 +77,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -158,7 +160,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/web_contents_delegate_android_jni_headers.target.linux-arm64.mk b/components/web_contents_delegate_android_jni_headers.target.linux-arm64.mk
index 499fbbe..b6e8589 100644
--- a/components/web_contents_delegate_android_jni_headers.target.linux-arm64.mk
+++ b/components/web_contents_delegate_android_jni_headers.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_web_contents_delegate_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/WebContentsDelegateAndroid.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/web_contents_delegate_android_jni_headers.target.linux-mips.mk b/components/web_contents_delegate_android_jni_headers.target.linux-mips.mk
index fc1db18..afcb2fa 100644
--- a/components/web_contents_delegate_android_jni_headers.target.linux-mips.mk
+++ b/components/web_contents_delegate_android_jni_headers.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_web_contents_delegate_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/WebContentsDelegateAndroid.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/components/web_contents_delegate_android_jni_headers.target.linux-x86.mk b/components/web_contents_delegate_android_jni_headers.target.linux-x86.mk
index 7af4b3a..b8bd435 100644
--- a/components/web_contents_delegate_android_jni_headers.target.linux-x86.mk
+++ b/components/web_contents_delegate_android_jni_headers.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_web_contents_delegate_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/WebContentsDelegateAndroid.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,7 +79,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -160,7 +162,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/web_contents_delegate_android_jni_headers.target.linux-x86_64.mk b/components/web_contents_delegate_android_jni_headers.target.linux-x86_64.mk
index 824999d..b7ae0f0 100644
--- a/components/web_contents_delegate_android_jni_headers.target.linux-x86_64.mk
+++ b/components/web_contents_delegate_android_jni_headers.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "components_components_gyp_web_contents_delegate_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ValidationMessageBubble.java', 'web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/WebContentsDelegateAndroid.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ColorChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/ValidationMessageBubble_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/web_contents_delegate_android/jni/WebContentsDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,7 +79,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -160,7 +162,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/web_modal/web_contents_modal_dialog_manager.cc b/components/web_modal/web_contents_modal_dialog_manager.cc
index a182acb..7ae8a2d 100644
--- a/components/web_modal/web_contents_modal_dialog_manager.cc
+++ b/components/web_modal/web_contents_modal_dialog_manager.cc
@@ -9,7 +9,6 @@
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 
 using content::WebContents;
@@ -188,7 +187,7 @@
     child_dialogs_.front()->manager->Hide();
 }
 
-void WebContentsModalDialogManager::WebContentsDestroyed(WebContents* tab) {
+void WebContentsModalDialogManager::WebContentsDestroyed() {
   // First cleanly close all child dialogs.
   // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked
   // some of these to close.  CloseAllDialogs is async, so it might get called
diff --git a/components/web_modal/web_contents_modal_dialog_manager.h b/components/web_modal/web_contents_modal_dialog_manager.h
index fd2d925..326b4c1 100644
--- a/components/web_modal/web_contents_modal_dialog_manager.h
+++ b/components/web_modal/web_contents_modal_dialog_manager.h
@@ -110,7 +110,7 @@
   virtual void DidGetIgnoredUIEvent() OVERRIDE;
   virtual void WasShown() OVERRIDE;
   virtual void WasHidden() OVERRIDE;
-  virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
   virtual void DidAttachInterstitialPage() OVERRIDE;
 
   // Delegate for notifying our owner about stuff. Not owned by us.
diff --git a/components/webdata/DEPS b/components/webdata/DEPS
index 2cd12ca..7ca0452 100644
--- a/components/webdata/DEPS
+++ b/components/webdata/DEPS
@@ -1,6 +1,4 @@
 include_rules = [
-  # WebData is used by iOS, which does not use content.
-  "-content",
   "+sql",
   "+ui",
 ]
diff --git a/components/webdata_common.target.darwin-arm.mk b/components/webdata_common.target.darwin-arm.mk
index e1b3638..fbc1b88 100644
--- a/components/webdata_common.target.darwin-arm.mk
+++ b/components/webdata_common.target.darwin-arm.mk
@@ -48,7 +48,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -144,7 +143,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/webdata_common.target.darwin-x86.mk b/components/webdata_common.target.darwin-x86.mk
index d81cf0b..02dd17e 100644
--- a/components/webdata_common.target.darwin-x86.mk
+++ b/components/webdata_common.target.darwin-x86.mk
@@ -50,7 +50,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,7 +145,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/webdata_common.target.darwin-x86_64.mk b/components/webdata_common.target.darwin-x86_64.mk
index 2175b29..743a297 100644
--- a/components/webdata_common.target.darwin-x86_64.mk
+++ b/components/webdata_common.target.darwin-x86_64.mk
@@ -50,7 +50,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,7 +145,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/webdata_common.target.linux-arm.mk b/components/webdata_common.target.linux-arm.mk
index e1b3638..fbc1b88 100644
--- a/components/webdata_common.target.linux-arm.mk
+++ b/components/webdata_common.target.linux-arm.mk
@@ -48,7 +48,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -144,7 +143,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/components/webdata_common.target.linux-x86.mk b/components/webdata_common.target.linux-x86.mk
index d81cf0b..02dd17e 100644
--- a/components/webdata_common.target.linux-x86.mk
+++ b/components/webdata_common.target.linux-x86.mk
@@ -50,7 +50,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,7 +145,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/webdata_common.target.linux-x86_64.mk b/components/webdata_common.target.linux-x86_64.mk
index 2175b29..743a297 100644
--- a/components/webdata_common.target.linux-x86_64.mk
+++ b/components/webdata_common.target.linux-x86_64.mk
@@ -50,7 +50,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,7 +145,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/components/wifi.gypi b/components/wifi.gypi
index 9b6d4d1..1786758 100644
--- a/components/wifi.gypi
+++ b/components/wifi.gypi
@@ -22,7 +22,6 @@
         'wifi/wifi_export.h',
         'wifi/wifi_service.cc',
         'wifi/wifi_service.h',
-        'wifi/fake_wifi_service.cc',
         'wifi/wifi_service_mac.mm',
         'wifi/wifi_service_win.cc',
       ],
@@ -45,6 +44,22 @@
       ],
     },
     {
+      'target_name': 'wifi_test_support',
+      'type': 'static_library',
+      'dependencies': [
+        '../base/base.gyp:base',
+        'onc_component',
+        'wifi_component',
+      ],
+      'include_dirs': [
+        '..',
+      ],
+      'sources': [
+        'wifi/fake_wifi_service.cc',
+        'wifi/fake_wifi_service.h',
+      ],
+    },
+    {
       'target_name': 'wifi_test',
       'type': 'executable',
       'dependencies': [
diff --git a/components/wifi/fake_wifi_service.cc b/components/wifi/fake_wifi_service.cc
index ea0e872..86b6358 100644
--- a/components/wifi/fake_wifi_service.cc
+++ b/components/wifi/fake_wifi_service.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/wifi/wifi_service.h"
+#include "components/wifi/fake_wifi_service.h"
 
 #include "base/bind.h"
 #include "base/json/json_reader.h"
@@ -11,316 +11,224 @@
 
 namespace wifi {
 
-// Fake implementation of WiFiService used to satisfy expectations of
-// networkingPrivateApi browser test.
-class FakeWiFiService : public WiFiService {
- public:
-  FakeWiFiService() {
-    // Populate data expected by unit test.
-    {
-      WiFiService::NetworkProperties network_properties;
-      network_properties.connection_state = onc::connection_state::kConnected;
-      network_properties.guid = "stub_ethernet";
-      network_properties.name = "eth0";
-      network_properties.type = onc::network_type::kEthernet;
-      network_properties.json_extra =
-          "    {"
-          "      \"Authentication\": \"None\""
-          "    }";
-      networks_.push_back(network_properties);
-    }
-    {
-      WiFiService::NetworkProperties network_properties;
-      network_properties.connection_state = onc::connection_state::kConnected;
-      network_properties.guid = "stub_wifi1";
-      network_properties.name = "wifi1";
-      network_properties.type = onc::network_type::kWiFi;
-      network_properties.frequency = 0;
-      network_properties.ssid = "stub_wifi1";
-      network_properties.security = onc::wifi::kWEP_PSK;
-      network_properties.signal_strength = 0;
-      networks_.push_back(network_properties);
-    }
-    {
-      WiFiService::NetworkProperties network_properties;
-      network_properties.connection_state = onc::connection_state::kConnected;
-      network_properties.guid = "stub_vpn1";
-      network_properties.name = "vpn1";
-      network_properties.type = onc::network_type::kVPN;
-      networks_.push_back(network_properties);
-    }
-    {
-      WiFiService::NetworkProperties network_properties;
-      network_properties.connection_state =
-          onc::connection_state::kNotConnected;
-      network_properties.guid = "stub_wifi2";
-      network_properties.name = "wifi2_PSK";
-      network_properties.type = onc::network_type::kWiFi;
-      network_properties.frequency = 5000;
-      network_properties.frequency_set.insert(2400);
-      network_properties.frequency_set.insert(5000);
-      network_properties.ssid = "wifi2_PSK";
-      network_properties.security = onc::wifi::kWPA_PSK;
-      network_properties.signal_strength = 80;
-      networks_.push_back(network_properties);
-    }
-    {
-      WiFiService::NetworkProperties network_properties;
-      network_properties.connection_state =
-          onc::connection_state::kNotConnected;
-      network_properties.guid = "stub_cellular1";
-      network_properties.name = "cellular1";
-      network_properties.type = onc::network_type::kCellular;
-      network_properties.json_extra =
-          "    {"
-          "      \"ActivateOverNonCellularNetwork\": false,"
-          "      \"ActivationState\": \"not-activated\","
-          "      \"NetworkTechnology\": \"GSM\","
-          "      \"RoamingState\": \"home\""
-          "    }";
-      networks_.push_back(network_properties);
-    }
-  }
-
-  virtual void Initialize(
-    scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE {}
-
-  virtual void UnInitialize() OVERRIDE {}
-
-  virtual void GetProperties(const std::string& network_guid,
-                              base::DictionaryValue* properties,
-                              std::string* error) OVERRIDE {
-    NetworkList::iterator network_properties = FindNetwork(network_guid);
-    if (network_properties != networks_.end()) {
-      properties->Swap(network_properties->ToValue(false).get());
-    } else {
-      *error = "Error.DBusFailed";
-    }
-  }
-
-  virtual void GetManagedProperties(const std::string& network_guid,
-                                    base::DictionaryValue* managed_properties,
-                                    std::string* error) OVERRIDE {
-    const std::string network_properties =
-        "{"
-        "  \"ConnectionState\": {"
-        "    \"Active\": \"NotConnected\","
-        "    \"Effective\": \"Unmanaged\""
-        "  },"
-        "  \"GUID\": \"stub_wifi2\","
-        "  \"Name\": {"
-        "    \"Active\": \"wifi2_PSK\","
-        "    \"Effective\": \"UserPolicy\","
-        "    \"UserPolicy\": \"My WiFi Network\""
-        "  },"
-        "  \"Type\": {"
-        "    \"Active\": \"WiFi\","
-        "    \"Effective\": \"UserPolicy\","
-        "    \"UserPolicy\": \"WiFi\""
-        "  },"
-        "  \"WiFi\": {"
-        "    \"AutoConnect\": {"
-        "      \"Active\": false,"
-        "      \"UserEditable\": true"
-        "    },"
-        "    \"Frequency\" : {"
-        "      \"Active\": 5000,"
-        "      \"Effective\": \"Unmanaged\""
-        "    },"
-        "    \"FrequencyList\" : {"
-        "      \"Active\": [2400, 5000],"
-        "      \"Effective\": \"Unmanaged\""
-        "    },"
-        "    \"Passphrase\": {"
-        "      \"Effective\": \"UserSetting\","
-        "      \"UserEditable\": true,"
-        "      \"UserSetting\": \"FAKE_CREDENTIAL_VPaJDV9x\""
-        "    },"
-        "    \"SSID\": {"
-        "      \"Active\": \"wifi2_PSK\","
-        "      \"Effective\": \"UserPolicy\","
-        "      \"UserPolicy\": \"wifi2_PSK\""
-        "    },"
-        "    \"Security\": {"
-        "      \"Active\": \"WPA-PSK\","
-        "      \"Effective\": \"UserPolicy\","
-        "      \"UserPolicy\": \"WPA-PSK\""
-        "    },"
-        "    \"SignalStrength\": {"
-        "      \"Active\": 80,"
-        "      \"Effective\": \"Unmanaged\""
-        "    }"
-        "  }"
-        "}";
-    scoped_ptr<base::DictionaryValue> properties_value(
-        reinterpret_cast<base::DictionaryValue*>(
-            base::JSONReader::Read(network_properties)));
-    managed_properties->MergeDictionary(properties_value.get());
-  }
-
-  virtual void GetState(const std::string& network_guid,
-                        base::DictionaryValue* properties,
-                        std::string* error) OVERRIDE {
-    NetworkList::iterator network_properties = FindNetwork(network_guid);
-    if (network_properties == networks_.end()) {
-      *error = "Error.InvalidParameter";
-      return;
-    }
-
-    const std::string network_state =
-        "{"
-        "  \"ConnectionState\": \"NotConnected\","
-        "  \"GUID\": \"stub_wifi2\","
-        "  \"Name\": \"wifi2_PSK\","
-        "  \"Type\": \"WiFi\","
-        "  \"WiFi\": {"
-        "    \"Security\": \"WPA-PSK\","
-        "    \"SignalStrength\": 80"
-        "  }"
-        "}";
-    scoped_ptr<base::DictionaryValue> properties_value(
-        reinterpret_cast<base::DictionaryValue*>(
-            base::JSONReader::Read(network_state)));
-    properties->MergeDictionary(properties_value.get());
-  }
-
-  virtual void SetProperties(const std::string& network_guid,
-                             scoped_ptr<base::DictionaryValue> properties,
-                             std::string* error) OVERRIDE {
-    NetworkList::iterator network_properties = FindNetwork(network_guid);
-    if (network_properties == networks_.end() ||
-        !network_properties->UpdateFromValue(*properties)) {
-      *error = "Error.DBusFailed";
-    }
-  }
-
-  virtual void CreateNetwork(bool shared,
-                             scoped_ptr<base::DictionaryValue> properties,
-                             std::string* network_guid,
-                             std::string* error) OVERRIDE {
+FakeWiFiService::FakeWiFiService() {
+  // Populate data expected by unit test.
+  {
     WiFiService::NetworkProperties network_properties;
-    if (network_properties.UpdateFromValue(*properties)) {
-      network_properties.guid = network_properties.ssid;
-      networks_.push_back(network_properties);
-      *network_guid = network_properties.guid;
-    } else {
-      *error = "Error.DBusFailed";
+    network_properties.connection_state = onc::connection_state::kConnected;
+    network_properties.guid = "stub_wifi1";
+    network_properties.name = "wifi1";
+    network_properties.type = onc::network_type::kWiFi;
+    network_properties.frequency = 0;
+    network_properties.ssid = "wifi1";
+    network_properties.security = onc::wifi::kWEP_PSK;
+    network_properties.signal_strength = 40;
+    network_properties.json_extra =
+      "{"
+      "  \"IPConfigs\": [{"
+      "     \"Gateway\": \"0.0.0.1\","
+      "     \"IPAddress\": \"0.0.0.0\","
+      "     \"RoutingPrefix\": 0,"
+      "     \"Type\": \"IPv4\""
+      "  }],"
+      "  \"WiFi\": {"
+      "    \"Frequency\": 2400,"
+      "    \"FrequencyList\": [2400]"
+      "  }"
+      "}";
+    networks_.push_back(network_properties);
+  }
+  {
+    WiFiService::NetworkProperties network_properties;
+    network_properties.connection_state = onc::connection_state::kNotConnected;
+    network_properties.guid = "stub_wifi2";
+    network_properties.name = "wifi2_PSK";
+    network_properties.type = onc::network_type::kWiFi;
+    network_properties.frequency = 5000;
+    network_properties.frequency_set.insert(2400);
+    network_properties.frequency_set.insert(5000);
+    network_properties.ssid = "wifi2_PSK";
+    network_properties.security = onc::wifi::kWPA_PSK;
+    network_properties.signal_strength = 80;
+    networks_.push_back(network_properties);
+  }
+}
+
+FakeWiFiService::~FakeWiFiService() {
+}
+
+void FakeWiFiService::Initialize(
+    scoped_refptr<base::SequencedTaskRunner> task_runner) {
+}
+
+void FakeWiFiService::UnInitialize() {
+}
+
+void FakeWiFiService::GetProperties(const std::string& network_guid,
+                                    base::DictionaryValue* properties,
+                                    std::string* error) {
+  WiFiService::NetworkList::iterator network_properties =
+      FindNetwork(network_guid);
+  if (network_properties != networks_.end()) {
+    properties->Swap(network_properties->ToValue(false).get());
+  } else {
+    *error = "Error.DBusFailed";
+  }
+}
+
+void FakeWiFiService::GetManagedProperties(
+    const std::string& network_guid,
+    base::DictionaryValue* managed_properties,
+    std::string* error) {
+  // Not implemented
+  *error = kErrorWiFiService;
+}
+
+void FakeWiFiService::GetState(const std::string& network_guid,
+                               base::DictionaryValue* properties,
+                               std::string* error) {
+  WiFiService::NetworkList::iterator network_properties =
+      FindNetwork(network_guid);
+  if (network_properties == networks_.end()) {
+    *error = "Error.InvalidParameter";
+    return;
+  }
+  properties->Swap(network_properties->ToValue(true).get());
+}
+
+void FakeWiFiService::SetProperties(
+    const std::string& network_guid,
+    scoped_ptr<base::DictionaryValue> properties,
+    std::string* error) {
+  WiFiService::NetworkList::iterator network_properties =
+      FindNetwork(network_guid);
+  if (network_properties == networks_.end() ||
+      !network_properties->UpdateFromValue(*properties)) {
+    *error = "Error.DBusFailed";
+  }
+}
+
+void FakeWiFiService::CreateNetwork(
+    bool shared,
+    scoped_ptr<base::DictionaryValue> properties,
+    std::string* network_guid,
+    std::string* error) {
+  WiFiService::NetworkProperties network_properties;
+  if (network_properties.UpdateFromValue(*properties)) {
+    network_properties.guid = network_properties.ssid;
+    networks_.push_back(network_properties);
+    *network_guid = network_properties.guid;
+  } else {
+    *error = "Error.DBusFailed";
+  }
+}
+
+void FakeWiFiService::GetVisibleNetworks(const std::string& network_type,
+                                         base::ListValue* network_list) {
+  for (WiFiService::NetworkList::const_iterator it = networks_.begin();
+       it != networks_.end();
+       ++it) {
+    if (network_type.empty() || network_type == onc::network_type::kAllTypes ||
+        it->type == network_type) {
+      scoped_ptr<base::DictionaryValue> network(it->ToValue(true));
+      network_list->Append(network.release());
     }
   }
+}
 
-  virtual void GetVisibleNetworks(const std::string& network_type,
-                                  base::ListValue* network_list) OVERRIDE {
-    for (WiFiService::NetworkList::const_iterator it = networks_.begin();
-         it != networks_.end();
-         ++it) {
-      if (network_type.empty() ||
-          network_type == onc::network_type::kAllTypes ||
-          it->type == network_type) {
-        scoped_ptr<base::DictionaryValue> network(it->ToValue(true));
-        network_list->Append(network.release());
-      }
-    }
-  }
+void FakeWiFiService::RequestNetworkScan() {
+  NotifyNetworkListChanged(networks_);
+}
 
-  virtual void RequestNetworkScan() OVERRIDE {
+void FakeWiFiService::StartConnect(const std::string& network_guid,
+                                   std::string* error) {
+  NetworkList::iterator network_properties = FindNetwork(network_guid);
+  if (network_properties != networks_.end()) {
+    DisconnectAllNetworksOfType(network_properties->type);
+    network_properties->connection_state = onc::connection_state::kConnected;
+    SortNetworks();
     NotifyNetworkListChanged(networks_);
+    NotifyNetworkChanged(network_guid);
+  } else {
+    *error = "configure-failed";
   }
+}
 
-  virtual void StartConnect(const std::string& network_guid,
-                            std::string* error) OVERRIDE {
-    NetworkList::iterator network_properties = FindNetwork(network_guid);
-    if (network_properties != networks_.end()) {
-      DisconnectAllNetworksOfType(network_properties->type);
-      network_properties->connection_state = onc::connection_state::kConnected;
-      SortNetworks();
-      NotifyNetworkListChanged(networks_);
-      NotifyNetworkChanged(network_guid);
-    } else {
-      *error = "configure-failed";
-    }
-  }
-
-  virtual void StartDisconnect(const std::string& network_guid,
-                               std::string* error) OVERRIDE {
-    NetworkList::iterator network_properties = FindNetwork(network_guid);
-    if (network_properties != networks_.end()) {
-      network_properties->connection_state =
-          onc::connection_state::kNotConnected;
-      SortNetworks();
-      NotifyNetworkListChanged(networks_);
-      NotifyNetworkChanged(network_guid);
-    } else {
-      *error = "not-found";
-    }
-  }
-
-  virtual void GetKeyFromSystem(const std::string& network_guid,
-                                std::string* key_data,
-                                std::string* error) OVERRIDE {
+void FakeWiFiService::StartDisconnect(const std::string& network_guid,
+                                      std::string* error) {
+  WiFiService::NetworkList::iterator network_properties =
+      FindNetwork(network_guid);
+  if (network_properties != networks_.end()) {
+    network_properties->connection_state = onc::connection_state::kNotConnected;
+    SortNetworks();
+    NotifyNetworkListChanged(networks_);
+    NotifyNetworkChanged(network_guid);
+  } else {
     *error = "not-found";
   }
+}
 
-  virtual void SetEventObservers(
-      scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
-      const NetworkGuidListCallback& networks_changed_observer,
-      const NetworkGuidListCallback& network_list_changed_observer) OVERRIDE {
-    message_loop_proxy_.swap(message_loop_proxy);
-    networks_changed_observer_ = networks_changed_observer;
-    network_list_changed_observer_ = network_list_changed_observer;
+void FakeWiFiService::GetKeyFromSystem(const std::string& network_guid,
+                                       std::string* key_data,
+                                       std::string* error) {
+  *error = "not-found";
+}
+
+void FakeWiFiService::SetEventObservers(
+    scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
+    const NetworkGuidListCallback& networks_changed_observer,
+    const NetworkGuidListCallback& network_list_changed_observer) {
+  message_loop_proxy_.swap(message_loop_proxy);
+  networks_changed_observer_ = networks_changed_observer;
+  network_list_changed_observer_ = network_list_changed_observer;
+}
+
+void FakeWiFiService::RequestConnectedNetworkUpdate() {
+}
+
+WiFiService::NetworkList::iterator FakeWiFiService::FindNetwork(
+    const std::string& network_guid) {
+  for (WiFiService::NetworkList::iterator it = networks_.begin();
+       it != networks_.end();
+       ++it) {
+    if (it->guid == network_guid)
+      return it;
+  }
+  return networks_.end();
+}
+
+void FakeWiFiService::DisconnectAllNetworksOfType(const std::string& type) {
+  for (WiFiService::NetworkList::iterator it = networks_.begin();
+       it != networks_.end();
+       ++it) {
+    if (it->type == type)
+      it->connection_state = onc::connection_state::kNotConnected;
+  }
+}
+
+void FakeWiFiService::SortNetworks() {
+  // Sort networks, so connected/connecting is up front, then by type:
+  // Ethernet, WiFi, Cellular, VPN
+  networks_.sort(WiFiService::NetworkProperties::OrderByType);
+}
+
+void FakeWiFiService::NotifyNetworkListChanged(
+    const WiFiService::NetworkList& networks) {
+  WiFiService::NetworkGuidList current_networks;
+  for (WiFiService::NetworkList::const_iterator it = networks.begin();
+       it != networks.end();
+       ++it) {
+    current_networks.push_back(it->guid);
   }
 
-  virtual void RequestConnectedNetworkUpdate() OVERRIDE { }
+  message_loop_proxy_->PostTask(
+      FROM_HERE, base::Bind(network_list_changed_observer_, current_networks));
+}
 
- private:
-  NetworkList::iterator FindNetwork(const std::string& network_guid) {
-    for (NetworkList::iterator it = networks_.begin(); it != networks_.end();
-         ++it) {
-      if (it->guid == network_guid)
-        return it;
-    }
-    return networks_.end();
-  }
-
-  void DisconnectAllNetworksOfType(const std::string& type) {
-    for (NetworkList::iterator it = networks_.begin(); it != networks_.end();
-         ++it) {
-      if (it->type == type)
-        it->connection_state = onc::connection_state::kNotConnected;
-    }
-  }
-
-  void SortNetworks() {
-    // Sort networks, so connected/connecting is up front, then by type:
-    // Ethernet, WiFi, Cellular, VPN
-    networks_.sort(WiFiService::NetworkProperties::OrderByType);
-  }
-
-  void NotifyNetworkListChanged(const NetworkList& networks) {
-    WiFiService::NetworkGuidList current_networks;
-    for (WiFiService::NetworkList::const_iterator it = networks.begin();
-         it != networks.end();
-         ++it) {
-      current_networks.push_back(it->guid);
-    }
-
-    message_loop_proxy_->PostTask(
-        FROM_HERE,
-        base::Bind(network_list_changed_observer_, current_networks));
-  }
-
-  void NotifyNetworkChanged(const std::string& network_guid) {
-    WiFiService::NetworkGuidList changed_networks(1, network_guid);
-    message_loop_proxy_->PostTask(
-        FROM_HERE,
-        base::Bind(networks_changed_observer_, changed_networks));
-  }
-
-  NetworkList networks_;
-  scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
-  NetworkGuidListCallback networks_changed_observer_;
-  NetworkGuidListCallback network_list_changed_observer_;
-};
-
-WiFiService* WiFiService::CreateForTest() { return new FakeWiFiService(); }
+void FakeWiFiService::NotifyNetworkChanged(const std::string& network_guid) {
+  WiFiService::NetworkGuidList changed_networks(1, network_guid);
+  message_loop_proxy_->PostTask(
+      FROM_HERE, base::Bind(networks_changed_observer_, changed_networks));
+}
 
 }  // namespace wifi
diff --git a/components/wifi/fake_wifi_service.h b/components/wifi/fake_wifi_service.h
new file mode 100644
index 0000000..fba1f52
--- /dev/null
+++ b/components/wifi/fake_wifi_service.h
@@ -0,0 +1,77 @@
+// 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.
+
+#ifndef COMPONENTS_WIFI_FAKE_WIFI_SERVICE_H_
+#define COMPONENTS_WIFI_FAKE_WIFI_SERVICE_H_
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "components/wifi/wifi_service.h"
+
+namespace wifi {
+
+// Fake implementation of WiFiService used to satisfy expectations of
+// networkingPrivateApi browser test.
+class FakeWiFiService : public WiFiService {
+ public:
+  FakeWiFiService();
+  virtual ~FakeWiFiService();
+
+  virtual void Initialize(
+      scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE;
+  virtual void UnInitialize() OVERRIDE;
+  virtual void GetProperties(const std::string& network_guid,
+                             base::DictionaryValue* properties,
+                             std::string* error) OVERRIDE;
+  virtual void GetManagedProperties(const std::string& network_guid,
+                                    base::DictionaryValue* managed_properties,
+                                    std::string* error) OVERRIDE;
+  virtual void GetState(const std::string& network_guid,
+                        base::DictionaryValue* properties,
+                        std::string* error) OVERRIDE;
+  virtual void SetProperties(const std::string& network_guid,
+                             scoped_ptr<base::DictionaryValue> properties,
+                             std::string* error) OVERRIDE;
+  virtual void CreateNetwork(bool shared,
+                             scoped_ptr<base::DictionaryValue> properties,
+                             std::string* network_guid,
+                             std::string* error) OVERRIDE;
+  virtual void GetVisibleNetworks(const std::string& network_type,
+                                  base::ListValue* network_list) OVERRIDE;
+  virtual void RequestNetworkScan() OVERRIDE;
+  virtual void StartConnect(const std::string& network_guid,
+                            std::string* error) OVERRIDE;
+  virtual void StartDisconnect(const std::string& network_guid,
+                               std::string* error) OVERRIDE;
+  virtual void GetKeyFromSystem(const std::string& network_guid,
+                                std::string* key_data,
+                                std::string* error) OVERRIDE;
+  virtual void SetEventObservers(
+      scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
+      const NetworkGuidListCallback& networks_changed_observer,
+      const NetworkGuidListCallback& network_list_changed_observer) OVERRIDE;
+  virtual void RequestConnectedNetworkUpdate() OVERRIDE;
+
+ private:
+  NetworkList::iterator FindNetwork(const std::string& network_guid);
+
+  void DisconnectAllNetworksOfType(const std::string& type);
+
+  void SortNetworks();
+
+  void NotifyNetworkListChanged(const NetworkList& networks);
+
+  void NotifyNetworkChanged(const std::string& network_guid);
+
+  NetworkList networks_;
+  scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
+  NetworkGuidListCallback networks_changed_observer_;
+  NetworkGuidListCallback network_list_changed_observer_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeWiFiService);
+};
+
+}  // namespace wifi
+
+#endif  // COMPONENTS_WIFI_FAKE_WIFI_SERVICE_H_
diff --git a/components/wifi/wifi_service.cc b/components/wifi/wifi_service.cc
index 340a4b5..ef6b3a0 100644
--- a/components/wifi/wifi_service.cc
+++ b/components/wifi/wifi_service.cc
@@ -11,6 +11,16 @@
 
 namespace wifi {
 
+const char WiFiService::kErrorAssociateToNetwork[] = "Error.AssociateToNetwork";
+const char WiFiService::kErrorInvalidData[] = "Error.InvalidData";
+const char WiFiService::kErrorNotConfigured[] ="Error.NotConfigured";
+const char WiFiService::kErrorNotConnected[] = "Error.NotConnected";
+const char WiFiService::kErrorNotFound[] = "Error.NotFound";
+const char WiFiService::kErrorNotImplemented[] = "Error.NotImplemented";
+const char WiFiService::kErrorScanForNetworksWithName[] =
+    "Error.ScanForNetworksWithName";
+const char WiFiService::kErrorWiFiService[] = "Error.WiFiService";
+
 WiFiService::NetworkProperties::NetworkProperties()
     : connection_state(onc::connection_state::kNotConnected),
       security(onc::wifi::kNone),
@@ -27,37 +37,42 @@
   value->SetString(onc::network_config::kGUID, guid);
   value->SetString(onc::network_config::kName, name);
   value->SetString(onc::network_config::kConnectionState, connection_state);
+  DCHECK(type == onc::network_type::kWiFi);
   value->SetString(onc::network_config::kType, type);
 
-  if (type == onc::network_type::kWiFi) {
-    scoped_ptr<base::DictionaryValue> wifi(new base::DictionaryValue());
-    wifi->SetString(onc::wifi::kSecurity, security);
-    wifi->SetInteger(onc::wifi::kSignalStrength, signal_strength);
+  // For now, assume all WiFi services are connectable.
+  value->SetBoolean(onc::network_config::kConnectable, true);
 
-    // Network list expects subset of data.
-    if (!network_list) {
-      if (frequency != WiFiService::kFrequencyUnknown)
-        wifi->SetInteger(onc::wifi::kFrequency, frequency);
-      scoped_ptr<base::ListValue> frequency_list(new base::ListValue());
-      for (FrequencySet::const_iterator it = this->frequency_set.begin();
-           it != this->frequency_set.end();
-           ++it) {
-        frequency_list->AppendInteger(*it);
-      }
-      if (!frequency_list->empty())
-        wifi->Set(onc::wifi::kFrequencyList, frequency_list.release());
-      if (!bssid.empty())
-        wifi->SetString(onc::wifi::kBSSID, bssid);
-      wifi->SetString(onc::wifi::kSSID, ssid);
+  scoped_ptr<base::DictionaryValue> wifi(new base::DictionaryValue());
+  wifi->SetString(onc::wifi::kSecurity, security);
+  wifi->SetInteger(onc::wifi::kSignalStrength, signal_strength);
+
+  // Network list expects subset of data.
+  if (!network_list) {
+    if (frequency != WiFiService::kFrequencyUnknown)
+      wifi->SetInteger(onc::wifi::kFrequency, frequency);
+    scoped_ptr<base::ListValue> frequency_list(new base::ListValue());
+    for (FrequencySet::const_iterator it = this->frequency_set.begin();
+         it != this->frequency_set.end();
+         ++it) {
+      frequency_list->AppendInteger(*it);
     }
-    value->Set(onc::network_type::kWiFi, wifi.release());
-  } else {
-    // Add properites from json extra if present.
-    if (!json_extra.empty()) {
-      base::Value* value_extra = base::JSONReader::Read(json_extra);
-      value->Set(type, value_extra);
-    }
+    if (!frequency_list->empty())
+      wifi->Set(onc::wifi::kFrequencyList, frequency_list.release());
+    if (!bssid.empty())
+      wifi->SetString(onc::wifi::kBSSID, bssid);
+    wifi->SetString(onc::wifi::kSSID, ssid);
   }
+  value->Set(onc::network_type::kWiFi, wifi.release());
+
+  if (!network_list && !json_extra.empty()) {
+    base::Value* value_extra = base::JSONReader::Read(json_extra);
+    CHECK(value_extra);
+    base::DictionaryValue* value_dictionary;
+    if (value_extra->GetAsDictionary(&value_dictionary))
+      value->MergeDictionary(value_dictionary);
+  }
+
   return value.Pass();
 }
 
diff --git a/components/wifi/wifi_service.h b/components/wifi/wifi_service.h
index ce685f0..e5a8aad 100644
--- a/components/wifi/wifi_service.h
+++ b/components/wifi/wifi_service.h
@@ -41,8 +41,6 @@
 
   // Create instance of |WiFiService| for normal use.
   static WiFiService* Create();
-  // Create instance of |WiFiService| for unit test use.
-  static WiFiService* CreateForTest();
 
   // Get Properties of network identified by |network_guid|. Populates
   // |properties| on success, |error| on failure.
@@ -166,6 +164,16 @@
 
   typedef std::list<NetworkProperties> NetworkList;
 
+  // Error constants.
+  static const char kErrorAssociateToNetwork[];
+  static const char kErrorInvalidData[];
+  static const char kErrorNotConfigured[];
+  static const char kErrorNotConnected[];
+  static const char kErrorNotFound[];
+  static const char kErrorNotImplemented[];
+  static const char kErrorScanForNetworksWithName[];
+  static const char kErrorWiFiService[];
+
  private:
   DISALLOW_COPY_AND_ASSIGN(WiFiService);
 };
diff --git a/components/wifi/wifi_service_mac.mm b/components/wifi/wifi_service_mac.mm
index eb83e17..6860596 100644
--- a/components/wifi/wifi_service_mac.mm
+++ b/components/wifi/wifi_service_mac.mm
@@ -47,13 +47,6 @@
 
 namespace wifi {
 
-const char kErrorAssociateToNetwork[] = "Error.AssociateToNetwork";
-const char kErrorInvalidData[] = "Error.InvalidData";
-const char kErrorNotConnected[] = "Error.NotConnected";
-const char kErrorNotFound[] = "Error.NotFound";
-const char kErrorNotImplemented[] = "Error.NotImplemented";
-const char kErrorScanForNetworksWithName[] = "Error.ScanForNetworksWithName";
-
 // Implementation of WiFiService for Mac OS X.
 class WiFiServiceMac : public WiFiService {
  public:
diff --git a/components/wifi/wifi_service_test.cc b/components/wifi/wifi_service_test.cc
deleted file mode 100644
index d8ce8af..0000000
--- a/components/wifi/wifi_service_test.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2013 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.
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "components/onc/onc_constants.h"
-#include "components/wifi/wifi_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace wifi {
-
-class WiFiServiceTest : public testing::Test {
- public:
-  void LogError(const std::string& error_name,
-                scoped_ptr<base::DictionaryValue> error_data) {
-    LOG(ERROR) << "WiFi Error: " << error_name;
-    QuitRunLoop();
-  }
-
-  void TestError(const std::string& error_name,
-                 scoped_ptr<base::DictionaryValue> error_data) {
-    LOG(ERROR) << "WiFi Error: " << error_name;
-    FAIL();
-  }
-
-  void OnDictionaryResult(const std::string& network_guid,
-                          const base::DictionaryValue& dictionary) {}
-
-  void OnNetworkProperties(const std::string& network_guid,
-                           const WiFiService::NetworkProperties& properties) {
-    LOG(INFO) << "OnNetworkProperties" << *properties.ToValue(false).release();
-  }
-
-  void OnNetworksChangedEventWaitingForConnect(
-      const WiFiService::NetworkGuidList& network_guid_list) {
-    LOG(INFO) << "Networks Changed: " << network_guid_list.front();
-    // Check that network is now connected.
-    wifi_service_->GetProperties(
-        connected_network_guid_,
-        base::Bind(&WiFiServiceTest::WaitForConnect, base::Unretained(this)),
-        base::Bind(&WiFiServiceTest::TestError, base::Unretained(this)));
-  }
-
-  void OnNetworkConnectStarted(const std::string& network_guid) {
-    LOG(INFO) << "Started Network Connect:" << network_guid;
-    wifi_service_->SetNetworksChangedObserver(
-        base::Bind(&WiFiServiceTest::OnNetworksChangedEventWaitingForConnect,
-                   base::Unretained(this)));
-    base::MessageLoop::current()->PostDelayedTask(
-        FROM_HERE,
-        base::MessageLoop::QuitClosure(),
-        base::TimeDelta::FromSeconds(10));
-  }
-
-  void WaitForConnect(const std::string& network_guid,
-                      const WiFiService::NetworkProperties& properties) {
-    LOG(INFO) << "WaitForConnect" << *properties.ToValue(false).release();
-    if (properties.connection_state == onc::connection_state::kConnected)
-      QuitRunLoop();
-  }
-
-  void WaitForDisconnect(const std::string& network_guid,
-                         const WiFiService::NetworkProperties& properties) {
-    LOG(INFO) << "WaitForDisconnect" << *properties.ToValue(false).release();
-    EXPECT_TRUE(properties.connection_state ==
-                onc::connection_state::kNotConnected);
-  }
-
-  void OnNetworkDisconnectStarted(const std::string& network_guid) {
-    LOG(INFO) << "Started Network Disconnect:" << network_guid;
-    // Check that Network state has changed to 'Not Connected'.
-    wifi_service_->GetProperties(
-        connected_network_guid_,
-        base::Bind(&WiFiServiceTest::WaitForDisconnect, base::Unretained(this)),
-        base::Bind(&WiFiServiceTest::TestError, base::Unretained(this)));
-    // Start connect back to the same network.
-    wifi_service_->StartConnect(
-        connected_network_guid_,
-        base::Bind(&WiFiServiceTest::OnNetworkConnectStarted,
-                   base::Unretained(this)),
-        base::Bind(&WiFiServiceTest::TestError, base::Unretained(this)));
-  }
-
-  void OnVisibleNetworks(const WiFiService::NetworkList& network_list) {
-    LOG(INFO) << "Visible WiFi Networks: " << network_list.size();
-  }
-
-  void FindConnectedNetwork(const WiFiService::NetworkList& network_list) {
-    for (WiFiService::NetworkList::const_iterator net = network_list.begin();
-         net != network_list.end();
-         ++net) {
-      if (net->connection_state == onc::connection_state::kConnected) {
-        connected_network_guid_ = net->guid;
-        LOG(INFO) << "Connected Network:\n" << *(net->ToValue(false).release());
-      }
-    }
-
-    if (!connected_network_guid_.empty()) {
-      wifi_service_->StartDisconnect(
-          connected_network_guid_,
-          base::Bind(&WiFiServiceTest::OnNetworkDisconnectStarted,
-                     base::Unretained(this)),
-          base::Bind(&WiFiServiceTest::TestError, base::Unretained(this)));
-    } else {
-      LOG(INFO) << "No Connected Networks, skipping disconnect.";
-      QuitRunLoop();
-    }
-  }
-
-  void QuitRunLoop() {
-    base::MessageLoop::current()->PostTask(FROM_HERE,
-                                           base::MessageLoop::QuitClosure());
-  }
-
- protected:
-  virtual void SetUp() { wifi_service_.reset(WiFiService::CreateService()); }
-  virtual void TearDown() {}
-
-  std::string connected_network_guid_;
-  scoped_ptr<WiFiService> wifi_service_;
-  base::MessageLoop loop_;
-};
-
-// Test getting list of visible networks.
-TEST_F(WiFiServiceTest, GetVisibleNetworks) {
-  wifi_service_->GetVisibleNetworks(
-      base::Bind(&WiFiServiceTest::OnVisibleNetworks, base::Unretained(this)),
-      base::Bind(&WiFiServiceTest::LogError, base::Unretained(this)));
-}
-
-// Test that connected WiFi network can be disconnected and reconnected.
-// Disabled to avoid network connection interruption unless enabled explicitly.
-TEST_F(WiFiServiceTest, DISABLED_Reconnect) {
-  base::RunLoop run_loop;
-  wifi_service_->GetVisibleNetworks(
-      base::Bind(&WiFiServiceTest::FindConnectedNetwork,
-                 base::Unretained(this)),
-      base::Bind(&WiFiServiceTest::LogError, base::Unretained(this)));
-  run_loop.Run();
-}
-
-}  // namespace wifi
diff --git a/components/wifi/wifi_service_win.cc b/components/wifi/wifi_service_win.cc
index db1c8b9..fe9f7d0 100644
--- a/components/wifi/wifi_service_win.cc
+++ b/components/wifi/wifi_service_win.cc
@@ -24,9 +24,6 @@
 #include "third_party/libxml/chromium/libxml_utils.h"
 
 namespace {
-const char kWiFiServiceError[] = "Error.WiFiService";
-const char kWiFiServiceErrorNotImplemented[] =
-    "Error.WiFiService.NotImplemented";
 const wchar_t kNwCategoryWizardRegKey[] =
     L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Network\\"
     L"NwCategoryWizard";
@@ -266,9 +263,8 @@
   NetworkList::iterator FindNetwork(NetworkList& networks,
                                     const std::string& network_guid);
 
-  // Save currently connected network profile and return its
-  // |connected_network_guid|, so it can be re-connected later.
-  DWORD SaveCurrentConnectedNetwork(std::string* connected_network_guid);
+  // Save currently connected network profile so it can be re-connected later.
+  DWORD SaveCurrentConnectedNetwork(const NetworkProperties& properties);
 
   // Sort networks, so connected/connecting is up front, then by type:
   // Ethernet, WiFi, Cellular, VPN
@@ -511,7 +507,7 @@
                                     base::DictionaryValue* properties,
                                     std::string* error) {
   DWORD error_code = EnsureInitialized();
-  if (CheckError(error_code, kWiFiServiceError, error))
+  if (CheckError(error_code, kErrorWiFiService, error))
     return;
 
   NetworkProperties connected_properties;
@@ -535,20 +531,20 @@
     error_code = ERROR_NOT_FOUND;
   }
 
-  CheckError(error_code, kWiFiServiceError, error);
+  CheckError(error_code, kErrorWiFiService, error);
 }
 
 void WiFiServiceImpl::GetManagedProperties(
     const std::string& network_guid,
     base::DictionaryValue* managed_properties,
     std::string* error) {
-  CheckError(ERROR_CALL_NOT_IMPLEMENTED, kWiFiServiceError, error);
+  CheckError(ERROR_CALL_NOT_IMPLEMENTED, kErrorWiFiService, error);
 }
 
 void WiFiServiceImpl::GetState(const std::string& network_guid,
                                base::DictionaryValue* properties,
                                std::string* error) {
-  CheckError(ERROR_CALL_NOT_IMPLEMENTED, kWiFiServiceError, error);
+  CheckError(ERROR_CALL_NOT_IMPLEMENTED, kErrorWiFiService, error);
 }
 
 void WiFiServiceImpl::SetProperties(
@@ -560,7 +556,7 @@
   DCHECK(properties.get());
   if (!properties->HasKey(onc::network_type::kWiFi)) {
     DVLOG(0) << "Missing WiFi properties:" << *properties;
-    *error = kWiFiServiceError;
+    *error = kErrorWiFiService;
     return;
   }
 
@@ -582,24 +578,24 @@
     std::string* network_guid,
     std::string* error) {
   DWORD error_code = EnsureInitialized();
-  if (CheckError(error_code, kWiFiServiceError, error))
+  if (CheckError(error_code, kErrorWiFiService, error))
     return;
 
   WiFiService::NetworkProperties network_properties;
   if (!network_properties.UpdateFromValue(*properties)) {
-    CheckError(ERROR_INVALID_DATA, kWiFiServiceError, error);
+    CheckError(ERROR_INVALID_DATA, kErrorWiFiService, error);
     return;
   }
 
   network_properties.guid = network_properties.ssid;
   std::string profile_xml;
   if (!CreateProfile(network_properties, kEncryptionTypeAny, &profile_xml)) {
-    CheckError(ERROR_INVALID_DATA, kWiFiServiceError, error);
+    CheckError(ERROR_INVALID_DATA, kErrorWiFiService, error);
     return;
   }
 
   error_code = SetProfile(shared, profile_xml, false);
-  if (CheckError(error_code, kWiFiServiceError, error)) {
+  if (CheckError(error_code, kErrorWiFiService, error)) {
     DVLOG(0) << profile_xml;
     return;
   }
@@ -611,7 +607,7 @@
   if (!CreateProfile(network_properties,
                      kEncryptionTypeTKIP,
                      &tkip_profile_xml)) {
-    CheckError(ERROR_INVALID_DATA, kWiFiServiceError, error);
+    CheckError(ERROR_INVALID_DATA, kErrorWiFiService, error);
     return;
   }
 
@@ -661,72 +657,75 @@
                                    std::string* error) {
   DVLOG(1) << "Start Connect: " << network_guid;
   DWORD error_code = EnsureInitialized();
-  if (error_code == ERROR_SUCCESS) {
-    std::string connected_network_guid;
-    error_code = SaveCurrentConnectedNetwork(&connected_network_guid);
-    if (error_code == ERROR_SUCCESS) {
-      // Check, if the network is already connected on desired frequency.
-      bool already_connected = (network_guid == connected_network_guid);
-      Frequency frequency = GetFrequencyToConnect(network_guid);
-      if (already_connected && frequency != kFrequencyAny) {
-        NetworkProperties current_properties;
-        if (GetCurrentProperties(&current_properties) == ERROR_SUCCESS) {
-          already_connected = current_properties.connection_state ==
-                                  onc::connection_state::kConnected &&
-                              frequency == current_properties.frequency &&
-                              network_guid == current_properties.guid;
-        }
-      }
-      // Connect only if network |network_guid| is not connected already.
-      if (!already_connected)
-        error_code = Connect(network_guid, frequency);
-      if (error_code == ERROR_SUCCESS) {
-        // Notify that previously connected network has changed.
-        NotifyNetworkChanged(connected_network_guid);
-        // Start waiting for network connection state change.
-        if (!networks_changed_observer_.is_null()) {
-          DisableNwCategoryWizard();
-          // Disable automatic network change notifications as they get fired
-          // when network is just connected, but not yet accessible (doesn't
-          // have valid IP address).
-          enable_notify_network_changed_ = false;
-          WaitForNetworkConnect(network_guid, 0);
-          return;
-        }
-      }
-    }
+  if (CheckError(error_code, kErrorWiFiService, error))
+    return;
+
+  // Check, if the network is already connected on desired frequency.
+  Frequency frequency = GetFrequencyToConnect(network_guid);
+  NetworkProperties properties;
+  GetCurrentProperties(&properties);
+  bool already_connected =
+      network_guid == properties.guid &&
+      properties.connection_state == onc::connection_state::kConnected &&
+      (frequency == kFrequencyAny || frequency == properties.frequency);
+
+  // Connect only if network |network_guid| is not connected already.
+  if (!already_connected) {
+    SaveCurrentConnectedNetwork(properties);
+    error_code = Connect(network_guid, frequency);
   }
-  CheckError(error_code, kWiFiServiceError, error);
+  if (error_code == ERROR_SUCCESS) {
+    // Notify that previously connected network has changed.
+    NotifyNetworkChanged(properties.guid);
+    // Start waiting for network connection state change.
+    if (!networks_changed_observer_.is_null()) {
+      DisableNwCategoryWizard();
+      // Disable automatic network change notifications as they get fired
+      // when network is just connected, but not yet accessible (doesn't
+      // have valid IP address).
+      enable_notify_network_changed_ = false;
+      WaitForNetworkConnect(network_guid, 0);
+      return;
+    }
+  } else if (error_code == ERROR_ACCESS_DENIED) {
+    CheckError(error_code, kErrorNotConfigured, error);
+  } else {
+    CheckError(error_code, kErrorWiFiService, error);
+  }
 }
 
 void WiFiServiceImpl::StartDisconnect(const std::string& network_guid,
                                       std::string* error) {
   DVLOG(1) << "Start Disconnect: " << network_guid;
   DWORD error_code = EnsureInitialized();
-  if (error_code == ERROR_SUCCESS) {
-    std::string connected_network_guid;
-    error_code = SaveCurrentConnectedNetwork(&connected_network_guid);
-    if (error_code == ERROR_SUCCESS && network_guid == connected_network_guid) {
-      error_code = Disconnect();
-      if (error_code == ERROR_SUCCESS) {
-        NotifyNetworkChanged(network_guid);
-        return;
-      }
+  if (CheckError(error_code, kErrorWiFiService, error))
+    return;
+
+  // Check, if the network is currently connected.
+  NetworkProperties properties;
+  GetCurrentProperties(&properties);
+  if (network_guid == properties.guid) {
+    if (properties.connection_state == onc::connection_state::kConnected)
+      SaveCurrentConnectedNetwork(properties);
+    error_code = Disconnect();
+    if (error_code == ERROR_SUCCESS) {
+      NotifyNetworkChanged(network_guid);
+      return;
     }
   }
-  CheckError(error_code, kWiFiServiceError, error);
+  CheckError(error_code, kErrorWiFiService, error);
 }
 
 void WiFiServiceImpl::GetKeyFromSystem(const std::string& network_guid,
                                        std::string* key_data,
                                        std::string* error) {
   DWORD error_code = EnsureInitialized();
-  if (CheckError(error_code, kWiFiServiceError, error))
+  if (CheckError(error_code, kErrorWiFiService, error))
     return;
 
   std::string profile_xml;
   error_code = GetProfile(network_guid, true, &profile_xml);
-  if (CheckError(error_code, kWiFiServiceError, error))
+  if (CheckError(error_code, kErrorWiFiService, error))
     return;
 
   const char kSharedKeyElement[] = "sharedKey";
@@ -735,7 +734,7 @@
 
   // Quick check to verify presence of <sharedKey> element.
   if (profile_xml.find(kSharedKeyElement) == std::string::npos) {
-    *error = kWiFiServiceError;
+    *error = kErrorWiFiService;
     return;
   }
 
@@ -755,7 +754,7 @@
             // |WLAN_PROFILE_GET_PLAINTEXT_KEY| flag returns success, but has
             // protected keyMaterial. Report an error in this case.
             if (protected_data != "false") {
-              *error = kWiFiServiceError;
+              *error = kErrorWiFiService;
               break;
             }
           }
@@ -766,7 +765,7 @@
   }
 
   // Did not find passphrase in the profile.
-  *error = kWiFiServiceError;
+  *error = kErrorWiFiService;
 }
 
 void WiFiServiceImpl::SetEventObservers(
@@ -949,20 +948,13 @@
 }
 
 DWORD WiFiServiceImpl::SaveCurrentConnectedNetwork(
-    std::string* connected_network_guid) {
-  // Find currently connected network.
-  NetworkProperties current_properties;
-  DWORD error = GetCurrentProperties(&current_properties);
-  if (error == ERROR_SUCCESS && !current_properties.guid.empty() &&
+    const NetworkProperties& current_properties) {
+  DWORD error = ERROR_SUCCESS;
+  // Save currently connected network.
+  if (!current_properties.guid.empty() &&
       current_properties.connection_state ==
           onc::connection_state::kConnected) {
-    *connected_network_guid = current_properties.guid;
-    SaveTempProfile(*connected_network_guid);
-    std::string profile_xml;
-    error = GetProfile(*connected_network_guid, false, &profile_xml);
-    if (error == ERROR_SUCCESS) {
-      saved_profiles_xml_[*connected_network_guid] = profile_xml;
-    }
+    error = SaveTempProfile(current_properties.guid);
   }
   return error;
 }
@@ -1594,6 +1586,21 @@
       error = WlanConnect_function_(
           client_, &interface_guid_, &wlan_params, NULL);
     } else {
+      // If network is available, but is not open security, then it cannot be
+      // connected without profile, so return 'access denied' error.
+      scoped_ptr<base::DictionaryValue> properties (new base::DictionaryValue);
+      const base::DictionaryValue* wifi;
+      std::string wifi_security;
+      std::string error_string;
+      GetProperties(network_guid, properties.get(), &error_string);
+      if (error_string.empty() &&
+          properties->GetDictionary(onc::network_type::kWiFi, &wifi) &&
+          wifi->GetString(onc::wifi::kSecurity, &wifi_security) &&
+          wifi_security != onc::wifi::kNone) {
+        error = ERROR_ACCESS_DENIED;
+        LOG(ERROR) << error;
+        return error;
+      }
       WLAN_CONNECTION_PARAMETERS wlan_params = {
           wlan_connection_mode_discovery_unsecure,
           NULL,
diff --git a/components/wifi/wifi_test.cc b/components/wifi/wifi_test.cc
index ac7522b..f34e0c0 100644
--- a/components/wifi/wifi_test.cc
+++ b/components/wifi/wifi_test.cc
@@ -195,7 +195,8 @@
 
       wifi_service_->StartConnect(network_guid, &error);
       VLOG(0) << error;
-      base::MessageLoop::current()->Run();
+      if (error.empty())
+        base::MessageLoop::current()->Run();
       return true;
     }
   }
diff --git a/content/DEPS b/content/DEPS
index d02ee64..41a95ef 100644
--- a/content/DEPS
+++ b/content/DEPS
@@ -5,7 +5,6 @@
   # directories in content/ so we disallow all of them.
   "-content",
   "+content/common",
-  "+content/port/common",
   "+content/public/common",
   "+content/public/test",
   "+content/shell",  # for content_browsertests
diff --git a/content/browser/DEPS b/content/browser/DEPS
index f02353d..bd7a602 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -1,5 +1,4 @@
 include_rules = [
-  "+content/port/browser",
   "+content/public/browser",
   "+media/audio",  # For audio input for speech input feature.
   "+media/base",  # For Android JNI registration.
@@ -33,6 +32,7 @@
   # header-only types, and some selected common code.
   "-third_party/WebKit",
   "+third_party/WebKit/public/platform/WebCursorInfo.h",
+  "+third_party/WebKit/public/platform/WebGamepad.h",
   "+third_party/WebKit/public/platform/WebGamepads.h",
   "+third_party/WebKit/public/platform/WebGraphicsContext3D.h",
   "+third_party/WebKit/public/platform/WebIDBDatabaseException.h",
diff --git a/content/browser/accessibility/accessibility_mode_browsertest.cc b/content/browser/accessibility/accessibility_mode_browsertest.cc
index 6a0ae02..5e191bd 100644
--- a/content/browser/accessibility/accessibility_mode_browsertest.cc
+++ b/content/browser/accessibility/accessibility_mode_browsertest.cc
@@ -4,7 +4,7 @@
 
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/port/browser/render_widget_host_view_port.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host.h"
 #include "content/public/browser/render_widget_host_view.h"
@@ -23,18 +23,18 @@
 
 class AccessibilityModeTest : public ContentBrowserTest {
  protected:
-  content::WebContents* web_contents() {
+  WebContents* web_contents() {
     return shell()->web_contents();
   }
 
-  content::RenderWidgetHostImpl* rwhi() {
-    content::RenderWidgetHost* rwh =
+  RenderWidgetHostImpl* rwhi() {
+    RenderWidgetHost* rwh =
         web_contents()->GetRenderWidgetHostView()->GetRenderWidgetHost();
-    return content::RenderWidgetHostImpl::From(rwh);
+    return RenderWidgetHostImpl::From(rwh);
   }
 
-  content::RenderWidgetHostViewPort* host_view() {
-    return RenderWidgetHostViewPort::FromRWHV(
+  RenderWidgetHostViewBase* host_view() {
+    return static_cast<RenderWidgetHostViewBase*>(
         shell()->web_contents()->GetRenderWidgetHostView());
   }
 
diff --git a/content/browser/accessibility/accessibility_tree_formatter.cc b/content/browser/accessibility/accessibility_tree_formatter.cc
index 11ee7e6..cca61a5 100644
--- a/content/browser/accessibility/accessibility_tree_formatter.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter.cc
@@ -11,7 +11,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/browser/accessibility/browser_accessibility_manager.h"
-#include "content/port/browser/render_widget_host_view_port.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 
@@ -31,7 +31,7 @@
 // static
 AccessibilityTreeFormatter* AccessibilityTreeFormatter::Create(
     RenderViewHost* rvh) {
-  RenderWidgetHostViewPort* host_view = static_cast<RenderWidgetHostViewPort*>(
+  RenderWidgetHostViewBase* host_view = static_cast<RenderWidgetHostViewBase*>(
       WebContents::FromRenderViewHost(rvh)->GetRenderWidgetHostView());
 
   BrowserAccessibilityManager* manager =
diff --git a/content/browser/accessibility/accessibility_ui.cc b/content/browser/accessibility/accessibility_ui.cc
index 6f63a0e..1f4df79 100644
--- a/content/browser/accessibility/accessibility_ui.cc
+++ b/content/browser/accessibility/accessibility_ui.cc
@@ -14,8 +14,8 @@
 #include "content/browser/accessibility/browser_accessibility_manager.h"
 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/common/view_message_enums.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/favicon_status.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/render_process_host.h"
@@ -89,6 +89,44 @@
                                accessibility_mode);
 }
 
+bool HandleRequestCallback(BrowserContext* current_context,
+                           const std::string& path,
+                           const WebUIDataSource::GotDataCallback& callback) {
+  if (path != kDataFile)
+    return false;
+  scoped_ptr<base::ListValue> rvh_list(new base::ListValue());
+
+  scoped_ptr<RenderWidgetHostIterator> widgets(
+      RenderWidgetHost::GetRenderWidgetHosts());
+
+  while (RenderWidgetHost* widget = widgets->GetNextHost()) {
+    // Ignore processes that don't have a connection, such as crashed tabs.
+    if (!widget->GetProcess()->HasConnection())
+      continue;
+    if (!widget->IsRenderView())
+        continue;
+    RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
+    BrowserContext* context = rwhi->GetProcess()->GetBrowserContext();
+    if (context != current_context)
+      continue;
+
+    RenderViewHost* rvh = RenderViewHost::From(widget);
+    rvh_list->Append(BuildTargetDescriptor(rvh));
+  }
+
+  scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue());
+  data->Set("list", rvh_list.release());
+  scoped_ptr<base::FundamentalValue> a11y_mode(base::Value::CreateIntegerValue(
+      BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()));
+  data->Set("global_a11y_mode", a11y_mode.release());
+
+  std::string json_string;
+  base::JSONWriter::Write(data.get(), &json_string);
+
+  callback.Run(base::RefCountedString::TakeString(&json_string));
+  return true;
+}
+
 }  // namespace
 
 AccessibilityUI::AccessibilityUI(WebUI* web_ui) : WebUIController(web_ui) {
@@ -115,8 +153,9 @@
   html_source->AddResourcePath("accessibility.css", IDR_ACCESSIBILITY_CSS);
   html_source->AddResourcePath("accessibility.js", IDR_ACCESSIBILITY_JS);
   html_source->SetDefaultResource(IDR_ACCESSIBILITY_HTML);
-  html_source->SetRequestFilter(base::Bind(
-      &AccessibilityUI::HandleRequestCallback, base::Unretained(this)));
+  html_source->SetRequestFilter(
+      base::Bind(&HandleRequestCallback,
+                 web_ui->GetWebContents()->GetBrowserContext()));
 
   BrowserContext* browser_context =
       web_ui->GetWebContents()->GetBrowserContext();
@@ -125,51 +164,6 @@
 
 AccessibilityUI::~AccessibilityUI() {}
 
-void AccessibilityUI::SendTargetsData(
-    const WebUIDataSource::GotDataCallback& callback) {
-  scoped_ptr<base::ListValue> rvh_list(new base::ListValue());
-
-  scoped_ptr<RenderWidgetHostIterator> widgets(
-      RenderWidgetHost::GetRenderWidgetHosts());
-  BrowserContext* current_context =
-      web_ui()->GetWebContents()->GetBrowserContext();
-  while (RenderWidgetHost* widget = widgets->GetNextHost()) {
-    // Ignore processes that don't have a connection, such as crashed tabs.
-    if (!widget->GetProcess()->HasConnection())
-      continue;
-    if (!widget->IsRenderView())
-        continue;
-    RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
-    BrowserContext* context = rwhi->GetProcess()->GetBrowserContext();
-    if (context != current_context)
-      continue;
-
-    RenderViewHost* rvh = RenderViewHost::From(widget);
-    rvh_list->Append(BuildTargetDescriptor(rvh));
-  }
-
-  scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue());
-  data->Set("list", rvh_list.release());
-  scoped_ptr<base::FundamentalValue> a11y_mode(base::Value::CreateIntegerValue(
-      BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()));
-  data->Set("global_a11y_mode", a11y_mode.release());
-
-  std::string json_string;
-  base::JSONWriter::Write(data.get(), &json_string);
-
-  callback.Run(base::RefCountedString::TakeString(&json_string));
-}
-
-bool AccessibilityUI::HandleRequestCallback(
-    const std::string& path,
-    const WebUIDataSource::GotDataCallback& callback) {
-  if (path != kDataFile)
-    return false;
-
-  SendTargetsData(callback);
-  return true;
-}
-
 void AccessibilityUI::ToggleAccessibility(const base::ListValue* args) {
   std::string process_id_str;
   std::string route_id_str;
@@ -226,7 +220,7 @@
   }
 
   scoped_ptr<base::DictionaryValue> result(BuildTargetDescriptor(rvh));
-  RenderWidgetHostViewPort* host_view = static_cast<RenderWidgetHostViewPort*>(
+  RenderWidgetHostViewBase* host_view = static_cast<RenderWidgetHostViewBase*>(
       WebContents::FromRenderViewHost(rvh)->GetRenderWidgetHostView());
   if (!host_view) {
     result->Set("error",
diff --git a/content/browser/accessibility/accessibility_ui.h b/content/browser/accessibility/accessibility_ui.h
index bdf022d..4922728 100644
--- a/content/browser/accessibility/accessibility_ui.h
+++ b/content/browser/accessibility/accessibility_ui.h
@@ -20,9 +20,6 @@
   virtual ~AccessibilityUI();
 
  private:
-  void SendTargetsData(const WebUIDataSource::GotDataCallback& callback);
-  bool HandleRequestCallback(const std::string& path,
-                             const WebUIDataSource::GotDataCallback& callback);
   void ToggleAccessibility(const base::ListValue* args);
   void ToggleGlobalAccessibility(const base::ListValue* args);
   void RequestAccessibilityTree(const base::ListValue* args);
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index fb67841..ce0564f 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -222,6 +222,23 @@
   }
 }
 
+BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendantFocus(
+    BrowserAccessibility* root) {
+  BrowserAccessibility* node = BrowserAccessibilityManager::GetFocus(root);
+  if (!node)
+    return NULL;
+
+  int active_descendant_id;
+  if (node->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID,
+                            &active_descendant_id)) {
+    BrowserAccessibility* active_descendant =
+        node->manager()->GetFromID(active_descendant_id);
+    if (active_descendant)
+      return active_descendant;
+  }
+  return node;
+}
+
 BrowserAccessibility* BrowserAccessibilityManager::GetFocus(
     BrowserAccessibility* root) {
   if (focus_ && (!root || focus_->IsDescendantOf(root->node())))
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h
index 932a435..f20b651 100644
--- a/content/browser/accessibility/browser_accessibility_manager.h
+++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -158,7 +158,11 @@
 
   // Return the object that has focus, if it's a descandant of the
   // given root (inclusive). Does not make a new reference.
-  BrowserAccessibility* GetFocus(BrowserAccessibility* root);
+  virtual BrowserAccessibility* GetFocus(BrowserAccessibility* root);
+
+  // Return the descentant of the given root that has focus, or that object's
+  // active descendant if it has one.
+  BrowserAccessibility* GetActiveDescendantFocus(BrowserAccessibility* root);
 
   // True by default, but some platforms want to treat the root
   // scroll offsets separately.
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.h b/content/browser/accessibility/browser_accessibility_manager_mac.h
index c057619..4659ff5 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.h
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.h
@@ -22,6 +22,8 @@
 
   static ui::AXTreeUpdate GetEmptyDocument();
 
+  virtual BrowserAccessibility* GetFocus(BrowserAccessibility* root) OVERRIDE;
+
   // Implementation of BrowserAccessibilityManager.
   virtual void NotifyAccessibilityEvent(
       ui::AXEvent event_type, BrowserAccessibility* node) OVERRIDE;
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm
index 266f8fb..fba13be 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -40,6 +40,12 @@
   return update;
 }
 
+BrowserAccessibility* BrowserAccessibilityManagerMac::GetFocus(
+    BrowserAccessibility* root) {
+  BrowserAccessibility* node = GetActiveDescendantFocus(root);
+  return node;
+}
+
 void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent(
     ui::AXEvent event_type,
     BrowserAccessibility* node) {
@@ -50,10 +56,16 @@
   NSString* event_id = @"";
   switch (event_type) {
     case ui::AX_EVENT_ACTIVEDESCENDANTCHANGED:
-      if (node->GetRole() == ui::AX_ROLE_TREE)
+      if (node->GetRole() == ui::AX_ROLE_TREE) {
         event_id = NSAccessibilitySelectedRowsChangedNotification;
-      else
+      } else {
         event_id = NSAccessibilityFocusedUIElementChangedNotification;
+        BrowserAccessibility* active_descendant_focus =
+            GetActiveDescendantFocus(GetRoot());
+        if (active_descendant_focus)
+          node = active_descendant_focus;
+      }
+
       break;
     case ui::AX_EVENT_ALERT:
       // Not used on Mac.
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index 4e398c2..e98ae71 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -3642,6 +3642,7 @@
       ia_role_ = ROLE_SYSTEM_CLIENT;
       ia2_role_ = IA2_ROLE_SCROLL_PANE;
       ia_state_ |= STATE_SYSTEM_READONLY;
+      ia2_state_ &= ~(IA2_STATE_EDITABLE);
       break;
     case ui::AX_ROLE_SCROLL_BAR:
       ia_role_ = ROLE_SYSTEM_SCROLLBAR;
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 37f0cb0..520215a 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -18,7 +18,7 @@
 #include "content/browser/accessibility/browser_accessibility.h"
 #include "content/browser/accessibility/browser_accessibility_manager.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/port/browser/render_widget_host_view_port.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_paths.h"
 #include "content/public/common/content_switches.h"
@@ -181,7 +181,7 @@
   NavigateToURL(shell(), url);
   waiter.WaitForNotification();
 
-  RenderWidgetHostViewPort* host_view = RenderWidgetHostViewPort::FromRWHV(
+  RenderWidgetHostViewBase* host_view = static_cast<RenderWidgetHostViewBase*>(
       shell()->web_contents()->GetRenderWidgetHostView());
   AccessibilityTreeFormatter formatter(
       host_view->GetBrowserAccessibilityManager()->GetRoot());
@@ -519,4 +519,9 @@
   RunTest(FILE_PATH_LITERAL("wbr.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+                       AccessibilityAriaActivedescendant) {
+  RunTest(FILE_PATH_LITERAL("aria-activedescendant.html"));
+}
+
 }  // namespace content
diff --git a/content/browser/android/content_settings.cc b/content/browser/android/content_settings.cc
index 7c6407f..a83169c 100644
--- a/content/browser/android/content_settings.cc
+++ b/content/browser/android/content_settings.cc
@@ -42,7 +42,7 @@
   return render_view_host->GetDelegate()->GetWebkitPrefs().javascript_enabled;
 }
 
-void ContentSettings::WebContentsDestroyed(WebContents* web_contents) {
+void ContentSettings::WebContentsDestroyed() {
   delete this;
 }
 
diff --git a/content/browser/android/content_settings.h b/content/browser/android/content_settings.h
index df75727..0728a6a 100644
--- a/content/browser/android/content_settings.h
+++ b/content/browser/android/content_settings.h
@@ -26,7 +26,7 @@
   virtual ~ContentSettings();
 
   // WebContentsObserver overrides:
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // The Java counterpart to this class.
   JavaObjectWeakGlobalRef content_settings_;
diff --git a/content/browser/android/content_startup_flags.cc b/content/browser/android/content_startup_flags.cc
index ddcc86c..a771daa 100644
--- a/content/browser/android/content_startup_flags.cc
+++ b/content/browser/android/content_startup_flags.cc
@@ -62,14 +62,11 @@
   parsed_command_line->AppendSwitch(switches::kEnableAcceleratedOverflowScroll);
   parsed_command_line->AppendSwitch(switches::kEnableBeginFrameScheduling);
 
-  parsed_command_line->AppendSwitch(switches::kDisableGestureDebounce);
   parsed_command_line->AppendSwitch(switches::kEnableGestureTapHighlight);
   parsed_command_line->AppendSwitch(switches::kEnablePinch);
   parsed_command_line->AppendSwitch(switches::kEnableOverlayFullscreenVideo);
   parsed_command_line->AppendSwitch(switches::kEnableOverlayScrollbar);
   parsed_command_line->AppendSwitch(switches::kEnableOverscrollNotifications);
-  parsed_command_line->AppendSwitchASCII(switches::kTouchAckTimeoutDelayMs,
-                                         "200");
 
   // Run the GPU service as a thread in the browser instead of as a
   // standalone process.
diff --git a/content/browser/android/content_video_view.cc b/content/browser/android/content_video_view.cc
index f7e9fc8..5407032 100644
--- a/content/browser/android/content_video_view.cc
+++ b/content/browser/android/content_video_view.cc
@@ -127,7 +127,8 @@
   if (player && player->IsPlayerReady()) {
     Java_ContentVideoView_onUpdateMediaMetadata(
         env, content_video_view.obj(), player->GetVideoWidth(),
-        player->GetVideoHeight(), player->GetDuration().InMilliseconds(),
+        player->GetVideoHeight(),
+        static_cast<int>(player->GetDuration().InMilliseconds()),
         player->CanPause(),player->CanSeekForward(), player->CanSeekBackward());
   }
 }
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 30cdd6c..a091df6 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -15,6 +15,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "cc/layers/layer.h"
+#include "cc/layers/solid_color_layer.h"
 #include "cc/output/begin_frame_args.h"
 #include "content/browser/android/gesture_event_type.h"
 #include "content/browser/android/interstitial_page_delegate_android.h"
@@ -217,15 +218,23 @@
     : WebContentsObserver(web_contents),
       java_ref_(env, obj),
       web_contents_(static_cast<WebContentsImpl*>(web_contents)),
-      root_layer_(cc::Layer::Create()),
+      root_layer_(cc::SolidColorLayer::Create()),
       dpi_scale_(GetPrimaryDisplayDeviceScaleFactor()),
       view_android_(view_android),
       window_android_(window_android),
       device_orientation_(0),
-      geolocation_needs_pause_(false) {
+      geolocation_needs_pause_(false),
+      accessibility_enabled_(false) {
   CHECK(web_contents) <<
       "A ContentViewCoreImpl should be created with a valid WebContents.";
 
+  root_layer_->SetBackgroundColor(GetBackgroundColor(env, obj));
+  gfx::Size physical_size(
+      Java_ContentViewCore_getPhysicalBackingWidthPix(env, obj),
+      Java_ContentViewCore_getPhysicalBackingHeightPix(env, obj));
+  root_layer_->SetBounds(physical_size);
+  root_layer_->SetIsDrawable(true);
+
   // Currently, the only use case we have for overriding a user agent involves
   // spoofing a desktop Linux user agent for "Request desktop site".
   // Automatically set it for all WebContents so that it is available when a
@@ -275,8 +284,9 @@
       this, NOTIFICATION_WEB_CONTENTS_CONNECTED,
       Source<WebContents>(web_contents_));
 
-  static_cast<WebContentsViewAndroid*>(web_contents_->GetView())->
-      SetContentViewCore(this);
+  static_cast<WebContentsViewAndroid*>(
+      static_cast<WebContentsImpl*>(web_contents_)->GetView())->
+          SetContentViewCore(this);
   DCHECK(!web_contents_->GetUserData(kContentViewUserDataKey));
   web_contents_->SetUserData(kContentViewUserDataKey,
                              new ContentViewUserData(this));
@@ -319,6 +329,8 @@
       SetFocusInternal(HasFocus());
       if (geolocation_needs_pause_)
         PauseOrResumeGeolocation(true);
+
+      SetAccessibilityEnabledInternal(accessibility_enabled_);
       break;
     }
     case NOTIFICATION_RENDERER_PROCESS_CREATED: {
@@ -422,13 +434,6 @@
   }
 }
 
-void ContentViewCoreImpl::OnTabCrashed() {
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
-  if (obj.is_null())
-    return;
-}
-
 // All positions and sizes are in CSS pixels.
 // Note that viewport_width/height is a best effort based.
 // ContentViewCore has the actual information about the physical viewport size.
@@ -481,6 +486,8 @@
 }
 
 void ContentViewCoreImpl::OnBackgroundColorChanged(SkColor color) {
+  root_layer_->SetBackgroundColor(color);
+
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
   if (obj.is_null())
@@ -488,13 +495,15 @@
   Java_ContentViewCore_onBackgroundColorChanged(env, obj.obj(), color);
 }
 
-void ContentViewCoreImpl::ShowSelectPopupMenu(
+void ContentViewCoreImpl::ShowSelectPopupMenu(const gfx::Rect& bounds,
     const std::vector<MenuItem>& items, int selected_item, bool multiple) {
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
   if (j_obj.is_null())
     return;
 
+  ScopedJavaLocalRef<jobject> bounds_rect(CreateJavaRect(env, bounds));
+
   // For multi-select list popups we find the list of previous selections by
   // iterating through the items. But for single selection popups we take the
   // given |selected_item| as is.
@@ -532,8 +541,11 @@
   ScopedJavaLocalRef<jobjectArray> items_array(
       base::android::ToJavaArrayOfStrings(env, labels));
   Java_ContentViewCore_showSelectPopup(env, j_obj.obj(),
-                                       items_array.obj(), enabled_array.obj(),
-                                       multiple, selected_array.obj());
+                                       bounds_rect.obj(),
+                                       items_array.obj(),
+                                       enabled_array.obj(),
+                                       multiple,
+                                       selected_array.obj());
 }
 
 void ContentViewCoreImpl::HideSelectPopupMenu() {
@@ -841,10 +853,14 @@
 
 void ContentViewCoreImpl::AttachLayer(scoped_refptr<cc::Layer> layer) {
   root_layer_->AddChild(layer);
+  root_layer_->SetIsDrawable(false);
 }
 
 void ContentViewCoreImpl::RemoveLayer(scoped_refptr<cc::Layer> layer) {
   layer->RemoveFromParent();
+
+  if (!root_layer_->children().size())
+    root_layer_->SetIsDrawable(true);
 }
 
 void ContentViewCoreImpl::LoadUrl(
@@ -1301,6 +1317,11 @@
 
 void ContentViewCoreImpl::WasResized(JNIEnv* env, jobject obj) {
   RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
+  gfx::Size physical_size(
+      Java_ContentViewCore_getPhysicalBackingWidthPix(env, obj),
+      Java_ContentViewCore_getPhysicalBackingHeightPix(env, obj));
+  root_layer_->SetBounds(physical_size);
+
   if (view) {
     RenderWidgetHostImpl* host = RenderWidgetHostImpl::From(
         view->GetRenderWidgetHost());
@@ -1554,6 +1575,11 @@
 
 void ContentViewCoreImpl::SetAccessibilityEnabled(JNIEnv* env, jobject obj,
                                                   bool enabled) {
+  SetAccessibilityEnabledInternal(enabled);
+}
+
+void ContentViewCoreImpl::SetAccessibilityEnabledInternal(bool enabled) {
+  accessibility_enabled_ = enabled;
   RenderWidgetHostViewAndroid* host_view = GetRenderWidgetHostViewAndroid();
   if (!host_view)
     return;
@@ -1580,13 +1606,9 @@
   if (rwhv)
     rwhv->UpdateScreenInfo(GetViewAndroid());
 
-  RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(
-      web_contents_->GetRenderViewHost());
-  rvhi->SendOrientationChangeEvent(device_orientation_);
-
   // TODO(mlamouri): temporary plumbing for Screen Orientation, this will change
-  // in the future. It might leave ContentViewCoreImpl or simply replace the
-  // SendOrientationChangeEvent call above.
+  // in the future. The OnResize IPC message sent from UpdateScreenInfo() will
+  // propagate the information.
   blink::WebScreenOrientationType orientation =
       blink::WebScreenOrientationPortraitPrimary;
 
@@ -1650,9 +1672,9 @@
       env, obj.obj(), jresult.obj());
 }
 
-void ContentViewCoreImpl::WebContentsDestroyed(WebContents* web_contents) {
-  WebContentsViewAndroid* wcva =
-      static_cast<WebContentsViewAndroid*>(web_contents->GetView());
+void ContentViewCoreImpl::WebContentsDestroyed() {
+  WebContentsViewAndroid* wcva = static_cast<WebContentsViewAndroid*>(
+      static_cast<WebContentsImpl*>(web_contents())->GetView());
   DCHECK(wcva);
   wcva->SetContentViewCore(NULL);
 }
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index dd39522..a00b67f 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -232,14 +232,13 @@
   // |multiple| defines if it should support multi-select.
   // If not |multiple|, |selected_item| sets the initially selected item.
   // Otherwise, item's "checked" flag selects it.
-  void ShowSelectPopupMenu(const std::vector<MenuItem>& items,
+  void ShowSelectPopupMenu(const gfx::Rect& bounds,
+                           const std::vector<MenuItem>& items,
                            int selected_item,
                            bool multiple);
   // Hides a visible popup menu.
   void HideSelectPopupMenu();
 
-  void OnTabCrashed();
-
   // All sizes and offsets are in CSS pixels as cached by the renderer.
   void UpdateFrameInfo(const gfx::Vector2dF& scroll_offset,
                        float page_scale_factor,
@@ -293,6 +292,8 @@
   // Returns the viewport size after accounting for the viewport offset.
   gfx::Size GetViewSize() const;
 
+  void SetAccessibilityEnabledInternal(bool enabled);
+
   // --------------------------------------------------------------------------
   // Methods called from native code
   // --------------------------------------------------------------------------
@@ -318,7 +319,7 @@
 
   // WebContentsObserver implementation.
   virtual void RenderViewReady() OVERRIDE;
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // --------------------------------------------------------------------------
   // Other private methods and data
@@ -375,6 +376,8 @@
 
   bool geolocation_needs_pause_;
 
+  bool accessibility_enabled_;
+
   DISALLOW_COPY_AND_ASSIGN(ContentViewCoreImpl);
 };
 
diff --git a/content/browser/android/content_view_render_view.cc b/content/browser/android/content_view_render_view.cc
index 900fc99..9f5ed31 100644
--- a/content/browser/android/content_view_render_view.cc
+++ b/content/browser/android/content_view_render_view.cc
@@ -13,7 +13,6 @@
 #include "base/message_loop/message_loop.h"
 #include "cc/layers/layer.h"
 #include "content/browser/android/content_view_core_impl.h"
-#include "content/browser/android/layer_tree_build_helper_impl.h"
 #include "content/public/browser/android/compositor.h"
 #include "content/public/browser/android/content_view_layer_renderer.h"
 #include "content/public/browser/android/layer_tree_build_helper.h"
@@ -28,6 +27,24 @@
 
 namespace content {
 
+namespace {
+
+class LayerTreeBuildHelperImpl : public LayerTreeBuildHelper {
+ public:
+  LayerTreeBuildHelperImpl() {}
+  virtual ~LayerTreeBuildHelperImpl() {}
+
+  virtual scoped_refptr<cc::Layer> GetLayerTree(
+      scoped_refptr<cc::Layer> content_root_layer) OVERRIDE {
+    return content_root_layer;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(LayerTreeBuildHelperImpl);
+};
+
+}  // anonymous namespace
+
 // static
 bool ContentViewRenderView::RegisterContentViewRenderView(JNIEnv* env) {
   return RegisterNativesImpl(env);
@@ -75,8 +92,10 @@
   InitCompositor();
   ContentViewCoreImpl* content_view_core =
       reinterpret_cast<ContentViewCoreImpl*>(native_content_view_core);
-  compositor_->SetRootLayer(
-      layer_tree_build_helper_->GetLayerTree(content_view_core->GetLayer()));
+  compositor_->SetRootLayer(content_view_core
+                                ? layer_tree_build_helper_->GetLayerTree(
+                                      content_view_core->GetLayer())
+                                : scoped_refptr<cc::Layer>());
 }
 
 void ContentViewRenderView::SurfaceCreated(
diff --git a/content/browser/android/content_view_render_view.h b/content/browser/android/content_view_render_view.h
index bcfc757..8f14456 100644
--- a/content/browser/android/content_view_render_view.h
+++ b/content/browser/android/content_view_render_view.h
@@ -56,7 +56,6 @@
   bool buffers_swapped_during_composite_;
 
   base::android::ScopedJavaGlobalRef<jobject> java_obj_;
-  scoped_refptr<cc::Layer> root_layer_;
   scoped_ptr<LayerTreeBuildHelper> layer_tree_build_helper_;
 
   scoped_ptr<content::Compositor> compositor_;
diff --git a/content/browser/android/download_controller_android_impl.cc b/content/browser/android/download_controller_android_impl.cc
index 16864ab..2d04235 100644
--- a/content/browser/android/download_controller_android_impl.cc
+++ b/content/browser/android/download_controller_android_impl.cc
@@ -22,7 +22,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/download_url_parameters.h"
 #include "content/public/browser/global_request_id.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/referrer.h"
 #include "jni/DownloadController_jni.h"
 #include "net/cookies/cookie_options.h"
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.h b/content/browser/android/in_process/synchronous_compositor_impl.h
index 861afc1..885db21 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.h
+++ b/content/browser/android/in_process/synchronous_compositor_impl.h
@@ -10,7 +10,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "cc/input/layer_scroll_offset_delegate.h"
 #include "content/browser/android/in_process/synchronous_compositor_output_surface.h"
-#include "content/port/common/input_event_ack_state.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/public/browser/android/synchronous_compositor.h"
 #include "content/public/browser/web_contents_user_data.h"
 
diff --git a/content/browser/android/in_process/synchronous_input_event_filter.h b/content/browser/android/in_process/synchronous_input_event_filter.h
index ae383f4..3b81fa6 100644
--- a/content/browser/android/in_process/synchronous_input_event_filter.h
+++ b/content/browser/android/in_process/synchronous_input_event_filter.h
@@ -8,7 +8,7 @@
 #include "base/basictypes.h"
 #include "base/callback.h"
 #include "base/compiler_specific.h"
-#include "content/port/common/input_event_ack_state.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/renderer/input/input_handler_manager_client.h"
 #include "ui/gfx/vector2d_f.h"
 
diff --git a/content/browser/android/layer_tree_build_helper_impl.cc b/content/browser/android/layer_tree_build_helper_impl.cc
deleted file mode 100644
index 6849eff..0000000
--- a/content/browser/android/layer_tree_build_helper_impl.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.
-
-#include "content/browser/android/layer_tree_build_helper_impl.h"
-
-#include "cc/layers/layer.h"
-#include "cc/layers/solid_color_layer.h"
-
-namespace content {
-
-LayerTreeBuildHelperImpl::LayerTreeBuildHelperImpl() {
-  root_layer_ = cc::SolidColorLayer::Create();
-  root_layer_->SetIsDrawable(true);
-  root_layer_->SetBackgroundColor(SK_ColorWHITE);
-}
-
-LayerTreeBuildHelperImpl::~LayerTreeBuildHelperImpl() {
-}
-
-scoped_refptr<cc::Layer> LayerTreeBuildHelperImpl::GetLayerTree(
-    scoped_refptr<cc::Layer> content_root_layer) {
-  if (content_root_layer)
-    root_layer_ = content_root_layer;
-  else
-    root_layer_ = cc::Layer::Create();
-
-  return root_layer_;
-}
-}  // namespace content
diff --git a/content/browser/android/layer_tree_build_helper_impl.h b/content/browser/android/layer_tree_build_helper_impl.h
deleted file mode 100644
index b8b1a8a..0000000
--- a/content/browser/android/layer_tree_build_helper_impl.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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.
-
-#ifndef CONTENT_BROWSER_ANDROID_LAYER_TREE_BUILD_HELPER_IMPL_H_
-#define CONTENT_BROWSER_ANDROID_LAYER_TREE_BUILD_HELPER_IMPL_H_
-
-#include "base/memory/ref_counted.h"
-#include "content/public/browser/android/layer_tree_build_helper.h"
-
-namespace cc {
-class Layer;
-}
-
-namespace content {
-
-// A Helper class to build a layer tree to be composited
-// given a content root layer.
-class LayerTreeBuildHelperImpl : public LayerTreeBuildHelper {
- public:
-  LayerTreeBuildHelperImpl();
-
-  virtual ~LayerTreeBuildHelperImpl();
-
-  virtual scoped_refptr<cc::Layer> GetLayerTree(
-      scoped_refptr<cc::Layer> content_root_layer) OVERRIDE;
-
- private:
-  scoped_refptr<cc::Layer> root_layer_;
-
-  DISALLOW_COPY_AND_ASSIGN(LayerTreeBuildHelperImpl);
-};
-
-}
-
-#endif  // CONTENT_BROWSER_ANDROID_LAYER_TREE_BUILD_HELPER_IMPL_H_
diff --git a/content/browser/android/tracing_controller_android.cc b/content/browser/android/tracing_controller_android.cc
index 3c3ee75..a9c5b40 100644
--- a/content/browser/android/tracing_controller_android.cc
+++ b/content/browser/android/tracing_controller_android.cc
@@ -7,6 +7,7 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
 #include "base/debug/trace_event.h"
+#include "base/json/json_writer.h"
 #include "base/logging.h"
 #include "content/public/browser/tracing_controller.h"
 #include "jni/TracingControllerAndroid_jni.h"
@@ -76,6 +77,31 @@
     Java_TracingControllerAndroid_onTracingStopped(env, obj.obj());
 }
 
+bool TracingControllerAndroid::GetKnownCategoryGroupsAsync(JNIEnv* env,
+                                                           jobject obj) {
+  if (!TracingController::GetInstance()->GetCategories(
+          base::Bind(&TracingControllerAndroid::OnKnownCategoriesReceived,
+                     weak_factory_.GetWeakPtr()))) {
+    return false;
+  }
+  return true;
+}
+
+void TracingControllerAndroid::OnKnownCategoriesReceived(
+    const std::set<std::string>& categories_received) {
+  scoped_ptr<base::ListValue> category_list(new base::ListValue());
+  for (std::set<std::string>::const_iterator it = categories_received.begin();
+       it != categories_received.end();
+       ++it) {
+    category_list->AppendString(*it);
+  }
+  std::string received_category_list;
+  base::JSONWriter::Write(category_list.get(), &received_category_list);
+
+  // This log is required by adb_profile_chrome.py.
+  LOG(WARNING) << "{\"traceCategoriesList\": " << received_category_list << "}";
+}
+
 static jstring GetDefaultCategories(JNIEnv* env, jobject obj) {
   return base::android::ConvertUTF8ToJavaString(env,
       base::debug::CategoryFilter::kDefaultCategoryFilterString).Release();
diff --git a/content/browser/android/tracing_controller_android.h b/content/browser/android/tracing_controller_android.h
index 98455eb..ab426d7 100644
--- a/content/browser/android/tracing_controller_android.h
+++ b/content/browser/android/tracing_controller_android.h
@@ -5,6 +5,8 @@
 #ifndef CONTENT_BROWSER_ANDROID_TRACING_CONTROLLER_ANDROID_H_
 #define CONTENT_BROWSER_ANDROID_TRACING_CONTROLLER_ANDROID_H_
 
+#include <set>
+
 #include "base/android/jni_weak_ref.h"
 #include "base/files/file_path.h"
 #include "base/memory/weak_ptr.h"
@@ -22,11 +24,14 @@
                     jstring categories,
                     jboolean record_continuously);
   void StopTracing(JNIEnv* env, jobject obj, jstring jfilepath);
+  bool GetKnownCategoryGroupsAsync(JNIEnv* env, jobject obj);
   static void GenerateTracingFilePath(base::FilePath* file_path);
 
  private:
   ~TracingControllerAndroid();
   void OnTracingStopped(const base::FilePath& file_path);
+  void OnKnownCategoriesReceived(
+      const std::set<std::string>& categories_received);
 
   JavaObjectWeakGlobalRef weak_java_object_;
   base::WeakPtrFactory<TracingControllerAndroid> weak_factory_;
diff --git a/content/browser/android/web_contents_observer_android.cc b/content/browser/android/web_contents_observer_android.cc
index 9a0d56a..72b2241 100644
--- a/content/browser/android/web_contents_observer_android.cc
+++ b/content/browser/android/web_contents_observer_android.cc
@@ -48,8 +48,7 @@
   delete this;
 }
 
-void WebContentsObserverAndroid::WebContentsDestroyed(
-    WebContents* web_contents) {
+void WebContentsObserverAndroid::WebContentsDestroyed() {
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
   if (obj.is_null()) {
@@ -273,13 +272,13 @@
       jstring_error_description.obj(), jstring_url.obj());
 }
 
-void WebContentsObserverAndroid::DidFirstVisuallyNonEmptyPaint(int32 page_id) {
+void WebContentsObserverAndroid::DidFirstVisuallyNonEmptyPaint() {
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> obj(weak_java_observer_.get(env));
   if (obj.is_null())
     return;
   Java_WebContentsObserverAndroid_didFirstVisuallyNonEmptyPaint(
-      env, obj.obj(), page_id);
+      env, obj.obj());
 }
 
 bool RegisterWebContentsObserverAndroid(JNIEnv* env) {
diff --git a/content/browser/android/web_contents_observer_android.h b/content/browser/android/web_contents_observer_android.h
index 6ff1093..319436c 100644
--- a/content/browser/android/web_contents_observer_android.h
+++ b/content/browser/android/web_contents_observer_android.h
@@ -54,7 +54,7 @@
                                     const FrameNavigateParams& params) OVERRIDE;
   virtual void DidNavigateAnyFrame(const LoadCommittedDetails& details,
                                    const FrameNavigateParams& params) OVERRIDE;
-  virtual void DidFirstVisuallyNonEmptyPaint(int32 page_id) OVERRIDE;
+  virtual void DidFirstVisuallyNonEmptyPaint() OVERRIDE;
   virtual void DidStartProvisionalLoadForFrame(
       int64 frame_id,
       int64 parent_frame_id,
@@ -76,7 +76,7 @@
                              RenderViewHost* render_view_host) OVERRIDE;
   virtual void NavigationEntryCommitted(
       const LoadCommittedDetails& load_details) OVERRIDE;
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
   virtual void DidChangeVisibleSSLState() OVERRIDE;
   virtual void DidAttachInterstitialPage() OVERRIDE;
   virtual void DidDetachInterstitialPage() OVERRIDE;
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index b5db4bc..39a1de3 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -1070,7 +1070,7 @@
 
   // Env creates the compositor. Aura widgets need the compositor to be created
   // before they can be initialized by the browser.
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
 #endif  // defined(USE_AURA)
 
   if (parts_)
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.cc b/content/browser/browser_plugin/browser_plugin_embedder.cc
index cb4fcf2..3591dec 100644
--- a/content/browser/browser_plugin/browser_plugin_embedder.cc
+++ b/content/browser/browser_plugin/browser_plugin_embedder.cc
@@ -31,7 +31,8 @@
 BrowserPluginHostFactory* BrowserPluginEmbedder::factory_ = NULL;
 
 BrowserPluginEmbedder::BrowserPluginEmbedder(WebContentsImpl* web_contents)
-    : WebContentsObserver(web_contents) {
+    : WebContentsObserver(web_contents),
+      weak_ptr_factory_(this) {
 }
 
 BrowserPluginEmbedder::~BrowserPluginEmbedder() {
@@ -61,10 +62,16 @@
   guest_started_drag_ = guest->AsWeakPtr();
 }
 
-WebContentsImpl* BrowserPluginEmbedder::GetWebContents() {
+WebContentsImpl* BrowserPluginEmbedder::GetWebContents() const {
   return static_cast<WebContentsImpl*>(web_contents());
 }
 
+BrowserPluginGuestManager*
+BrowserPluginEmbedder::GetBrowserPluginGuestManager() const {
+  return BrowserPluginGuestManager::FromBrowserContext(
+      GetWebContents()->GetBrowserContext());
+}
+
 bool BrowserPluginEmbedder::DidSendScreenRectsCallback(
    BrowserPluginGuest* guest) {
   static_cast<RenderViewHostImpl*>(
@@ -74,9 +81,11 @@
 }
 
 void BrowserPluginEmbedder::DidSendScreenRects() {
-  GetBrowserPluginGuestManager()->ForEachGuest(GetWebContents(), base::Bind(
-      &BrowserPluginEmbedder::DidSendScreenRectsCallback,
-      base::Unretained(this)));
+  BrowserPluginGuestManager::FromBrowserContext(
+      GetWebContents()->GetBrowserContext())->ForEachGuest(
+          GetWebContents(), base::Bind(
+              &BrowserPluginEmbedder::DidSendScreenRectsCallback,
+              base::Unretained(this)));
 }
 
 bool BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback(
@@ -93,7 +102,8 @@
     return false;
   }
 
-  return GetBrowserPluginGuestManager()->ForEachGuest(GetWebContents(),
+  return GetBrowserPluginGuestManager()->ForEachGuest(
+      GetWebContents(),
       base::Bind(&BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback,
                  base::Unretained(this),
                  event));
@@ -108,10 +118,11 @@
 }
 
 void BrowserPluginEmbedder::SetZoomLevel(double level) {
-  GetBrowserPluginGuestManager()->ForEachGuest(GetWebContents(), base::Bind(
-      &BrowserPluginEmbedder::SetZoomLevelCallback,
-      base::Unretained(this),
-      level));
+  GetBrowserPluginGuestManager()->ForEachGuest(
+      GetWebContents(), base::Bind(
+          &BrowserPluginEmbedder::SetZoomLevelCallback,
+          base::Unretained(this),
+          level));
 }
 
 bool BrowserPluginEmbedder::OnMessageReceived(const IPC::Message& message) {
@@ -151,36 +162,18 @@
   *handled = (guest_dragging_over_.get() != NULL);
 }
 
-BrowserPluginGuestManager*
-    BrowserPluginEmbedder::GetBrowserPluginGuestManager() {
-  BrowserPluginGuestManager* guest_manager =
-      GetWebContents()->GetBrowserPluginGuestManager();
-  if (!guest_manager) {
-    guest_manager = BrowserPluginGuestManager::Create();
-    GetWebContents()->GetBrowserContext()->SetUserData(
-        browser_plugin::kBrowserPluginGuestManagerKeyName, guest_manager);
-  }
-  return guest_manager;
-}
-
 void BrowserPluginEmbedder::OnAllocateInstanceID(int request_id) {
-  int instance_id = GetBrowserPluginGuestManager()->get_next_instance_id();
+  int instance_id = GetBrowserPluginGuestManager()->GetNextInstanceID();
   Send(new BrowserPluginMsg_AllocateInstanceID_ACK(
       routing_id(), request_id, instance_id));
 }
 
-void BrowserPluginEmbedder::OnAttach(
+void BrowserPluginEmbedder::OnGuestCallback(
     int instance_id,
     const BrowserPluginHostMsg_Attach_Params& params,
-    const base::DictionaryValue& extra_params) {
-  if (!GetBrowserPluginGuestManager()->CanEmbedderAccessInstanceIDMaybeKill(
-          GetWebContents()->GetRenderProcessHost()->GetID(), instance_id))
-    return;
-
-  BrowserPluginGuest* guest =
-      GetBrowserPluginGuestManager()->GetGuestByInstanceID(
-          instance_id, GetWebContents()->GetRenderProcessHost()->GetID());
-
+    const base::DictionaryValue* extra_params,
+    BrowserPluginGuest* guest) {
+  BrowserPluginGuestManager* guest_manager = GetBrowserPluginGuestManager();
   if (guest) {
     // There is an implicit order expectation here:
     // 1. The content embedder is made aware of the attachment.
@@ -190,13 +183,13 @@
     GetContentClient()->browser()->GuestWebContentsAttached(
         guest->GetWebContents(),
         GetWebContents(),
-        extra_params);
-    guest->Attach(GetWebContents(), params, extra_params);
+        *extra_params);
+    guest->Attach(GetWebContents(), params, *extra_params);
     return;
   }
 
-  scoped_ptr<base::DictionaryValue> copy_extra_params(extra_params.DeepCopy());
-  guest = GetBrowserPluginGuestManager()->CreateGuest(
+  scoped_ptr<base::DictionaryValue> copy_extra_params(extra_params->DeepCopy());
+  guest = guest_manager->CreateGuest(
       GetWebContents()->GetSiteInstance(),
       instance_id, params,
       copy_extra_params.Pass());
@@ -204,9 +197,22 @@
     GetContentClient()->browser()->GuestWebContentsAttached(
         guest->GetWebContents(),
         GetWebContents(),
-        extra_params);
+        *extra_params);
     guest->Initialize(params, GetWebContents());
   }
 }
 
+void BrowserPluginEmbedder::OnAttach(
+    int instance_id,
+    const BrowserPluginHostMsg_Attach_Params& params,
+    const base::DictionaryValue& extra_params) {
+  GetBrowserPluginGuestManager()->MaybeGetGuestByInstanceIDOrKill(
+      instance_id, GetWebContents()->GetRenderProcessHost()->GetID(),
+      base::Bind(&BrowserPluginEmbedder::OnGuestCallback,
+                 base::Unretained(this),
+                 instance_id,
+                 params,
+                 &extra_params));
+}
+
 }  // namespace content
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.h b/content/browser/browser_plugin/browser_plugin_embedder.h
index e153a4d..4df3dc4 100644
--- a/content/browser/browser_plugin/browser_plugin_embedder.h
+++ b/content/browser/browser_plugin/browser_plugin_embedder.h
@@ -45,7 +45,7 @@
   static BrowserPluginEmbedder* Create(WebContentsImpl* web_contents);
 
   // Returns this embedder's WebContentsImpl.
-  WebContentsImpl* GetWebContents();
+  WebContentsImpl* GetWebContents() const;
 
   // Called when embedder's |rwh| has sent screen rects to renderer.
   void DidSendScreenRects();
@@ -86,9 +86,9 @@
  private:
   friend class TestBrowserPluginEmbedder;
 
-  BrowserPluginEmbedder(WebContentsImpl* web_contents);
+  explicit BrowserPluginEmbedder(WebContentsImpl* web_contents);
 
-  BrowserPluginGuestManager* GetBrowserPluginGuestManager();
+  BrowserPluginGuestManager* GetBrowserPluginGuestManager() const;
 
   bool DidSendScreenRectsCallback(BrowserPluginGuest* guest);
 
@@ -97,6 +97,13 @@
   bool UnlockMouseIfNecessaryCallback(const NativeWebKeyboardEvent& event,
                                       BrowserPluginGuest* guest);
 
+  // Called by the content embedder when a guest exists with the provided
+  // |instance_id|.
+  void OnGuestCallback(int instance_id,
+                       const BrowserPluginHostMsg_Attach_Params& params,
+                       const base::DictionaryValue* extra_params,
+                       BrowserPluginGuest* guest);
+
   // Message handlers.
 
   void OnAllocateInstanceID(int request_id);
@@ -121,6 +128,8 @@
   // status messages to the correct guest.
   base::WeakPtr<BrowserPluginGuest> guest_started_drag_;
 
+  base::WeakPtrFactory<BrowserPluginEmbedder> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(BrowserPluginEmbedder);
 };
 
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
index 7e7f97e..01060f5 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -17,8 +17,10 @@
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/frame_host/render_widget_host_view_guest.h"
 #include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/renderer_host/render_view_host_delegate_view.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/browser/web_contents/web_contents_view_guest.h"
 #include "content/common/browser_plugin/browser_plugin_constants.h"
@@ -27,15 +29,13 @@
 #include "content/common/drag_messages.h"
 #include "content/common/input_messages.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_view_host_delegate_view.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
+#include "content/public/common/context_menu_params.h"
 #include "content/public/common/drop_data.h"
 #include "content/public/common/media_stream_request.h"
 #include "content/public/common/result_codes.h"
@@ -98,9 +98,20 @@
                            const std::string& user_input) OVERRIDE {
     int embedder_render_process_id =
         guest_->embedder_web_contents()->GetRenderProcessHost()->GetID();
-    BrowserPluginGuest* guest =
-        guest_->GetWebContents()->GetBrowserPluginGuestManager()->
-            GetGuestByInstanceID(instance_id_, embedder_render_process_id);
+    guest_->GetBrowserPluginGuestManager()->
+        MaybeGetGuestByInstanceIDOrKill(
+            instance_id_,
+            embedder_render_process_id,
+            base::Bind(&BrowserPluginGuest::NewWindowRequest::RespondInternal,
+                       base::Unretained(this),
+                       should_allow));
+  }
+
+ private:
+  virtual ~NewWindowRequest() {}
+
+  void RespondInternal(bool should_allow,
+                       BrowserPluginGuest* guest) {
     if (!guest) {
       VLOG(0) << "Guest not found. Instance ID: " << instance_id_;
       return;
@@ -111,8 +122,6 @@
       guest->Destroy();
   }
 
- private:
-  virtual ~NewWindowRequest() {}
   int instance_id_;
 };
 
@@ -168,7 +177,7 @@
   }
 
   // WebContentsObserver:
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     browser_plugin_guest_->EmbedderDestroyed();
   }
 
@@ -189,8 +198,7 @@
 BrowserPluginGuest::BrowserPluginGuest(
     int instance_id,
     bool has_render_view,
-    WebContentsImpl* web_contents,
-    BrowserPluginGuest* opener)
+    WebContentsImpl* web_contents)
     : WebContentsObserver(web_contents),
       embedder_web_contents_(NULL),
       instance_id_(instance_id),
@@ -213,10 +221,7 @@
       weak_ptr_factory_(this) {
   DCHECK(web_contents);
   web_contents->SetDelegate(this);
-  if (opener)
-    opener_ = opener->AsWeakPtr();
-  GetWebContents()->GetBrowserPluginGuestManager()->AddGuest(instance_id_,
-                                                             GetWebContents());
+  GetBrowserPluginGuestManager()->AddGuest(instance_id_, GetWebContents());
 }
 
 bool BrowserPluginGuest::AddMessageToConsole(WebContents* source,
@@ -302,11 +307,10 @@
 
 BrowserPluginGuest* BrowserPluginGuest::CreateNewGuestWindow(
     const OpenURLParams& params) {
-  BrowserPluginGuestManager* guest_manager =
-      GetWebContents()->GetBrowserPluginGuestManager();
+  BrowserPluginGuestManager* guest_manager = GetBrowserPluginGuestManager();
 
   // Allocate a new instance ID for the new guest.
-  int instance_id = guest_manager->get_next_instance_id();
+  int instance_id = guest_manager->GetNextInstanceID();
 
   // Set the attach params to use the same partition as the opener.
   // We pull the partition information from the site's URL, which is of the form
@@ -322,10 +326,12 @@
   scoped_ptr<base::DictionaryValue> extra_params(
       extra_attach_params_->DeepCopy());
   BrowserPluginGuest* new_guest =
-      GetWebContents()->GetBrowserPluginGuestManager()->CreateGuest(
-          GetWebContents()->GetSiteInstance(), instance_id,
-          attach_params, extra_params.Pass());
-  new_guest->opener_ = AsWeakPtr();
+      guest_manager->CreateGuest(GetWebContents()->GetSiteInstance(),
+                                 instance_id,
+                                 attach_params,
+                                 extra_params.Pass());
+  if (new_guest->delegate_)
+    new_guest->delegate_->SetOpener(GetWebContents());
 
   // Take ownership of |new_guest|.
   pending_new_windows_.insert(
@@ -351,10 +357,10 @@
 
 void BrowserPluginGuest::Destroy() {
   is_in_destruction_ = true;
-  if (!attached() && opener())
-    opener()->pending_new_windows_.erase(this);
+  if (!attached() && GetOpener())
+    GetOpener()->pending_new_windows_.erase(this);
   DestroyUnattachedWindows();
-  GetWebContents()->GetBrowserPluginGuestManager()->RemoveGuest(instance_id_);
+  GetBrowserPluginGuestManager()->RemoveGuest(instance_id_);
   delete GetWebContents();
 }
 
@@ -509,7 +515,7 @@
   if (factory_) {
     guest = factory_->CreateBrowserPluginGuest(instance_id, web_contents);
   } else {
-    guest = new BrowserPluginGuest(instance_id, false, web_contents, NULL);
+    guest = new BrowserPluginGuest(instance_id, false, web_contents);
   }
   guest->extra_attach_params_.reset(extra_params->DeepCopy());
   web_contents->SetBrowserPluginGuest(guest);
@@ -528,7 +534,7 @@
     BrowserPluginGuest* opener) {
   BrowserPluginGuest* guest =
       new BrowserPluginGuest(
-          instance_id, has_render_view, web_contents, opener);
+          instance_id, has_render_view, web_contents);
   web_contents->SetBrowserPluginGuest(guest);
   BrowserPluginGuestDelegate* delegate = NULL;
   GetContentClient()->browser()->GuestWebContentsCreated(
@@ -545,6 +551,17 @@
   return embedder_web_contents_->GetRenderWidgetHostView();
 }
 
+BrowserPluginGuest* BrowserPluginGuest::GetOpener() const {
+  if (!delegate_)
+    return NULL;
+
+  WebContents* opener = delegate_->GetOpener();
+  if (!opener)
+    return NULL;
+
+  return static_cast<WebContentsImpl*>(opener)->GetBrowserPluginGuest();
+}
+
 void BrowserPluginGuest::UpdateVisibility() {
   OnSetVisibility(instance_id_, visible());
 }
@@ -559,6 +576,12 @@
           copy_request_id_, src_subrect, dst_size));
 }
 
+BrowserPluginGuestManager*
+BrowserPluginGuest::GetBrowserPluginGuestManager() const {
+  return BrowserPluginGuestManager::FromBrowserContext(
+      GetWebContents()->GetBrowserContext());
+}
+
 // screen.
 gfx::Rect BrowserPluginGuest::ToGuestRect(const gfx::Rect& bounds) {
   gfx::Rect guest_rect(bounds);
@@ -633,10 +656,17 @@
 }
 
 bool BrowserPluginGuest::HandleContextMenu(const ContextMenuParams& params) {
-  // TODO(fsamuel): We show the regular page context menu handler for now until
-  // we implement the Apps Context Menu API for Browser Plugin (see
-  // http://crbug.com/140315).
-  return false;  // Will be handled by WebContentsViewGuest.
+  if (delegate_) {
+    WebContentsViewGuest* view_guest =
+        static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
+    ContextMenuParams context_menu_params =
+        view_guest->ConvertContextMenuParams(params);
+
+    return delegate_->HandleContextMenu(context_menu_params);
+  }
+
+  // Will be handled by WebContentsViewGuest.
+  return false;
 }
 
 void BrowserPluginGuest::HandleKeyboardEvent(
@@ -697,8 +727,9 @@
   // Navigation also resumes resource loading which we don't want to allow
   // until attachment.
   if (!attached()) {
-    PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this);
-    if (it == opener()->pending_new_windows_.end())
+    PendingWindowMap::iterator it =
+        GetOpener()->pending_new_windows_.find(this);
+    if (it == GetOpener()->pending_new_windows_.end())
       return NULL;
     const NewWindowInfo& old_target_url = it->second;
     NewWindowInfo new_window_info(params.url, old_target_url.name);
@@ -723,7 +754,8 @@
   WebContentsImpl* new_contents_impl =
       static_cast<WebContentsImpl*>(new_contents);
   BrowserPluginGuest* guest = new_contents_impl->GetBrowserPluginGuest();
-  guest->opener_ = AsWeakPtr();
+  if (guest->delegate_)
+    guest->delegate_->SetOpener(GetWebContents());
   std::string guest_name = base::UTF16ToUTF8(frame_name);
   guest->name_ = guest_name;
   // Take ownership of the new guest until it is attached to the embedder's DOM
@@ -764,7 +796,7 @@
   return false;
 }
 
-WebContentsImpl* BrowserPluginGuest::GetWebContents() {
+WebContentsImpl* BrowserPluginGuest::GetWebContents() const {
   return static_cast<WebContentsImpl*>(web_contents());
 }
 
@@ -1020,8 +1052,8 @@
   // the time the WebContents was created and the time it was attached.
   // We also need to do an initial navigation if a RenderView was never
   // created for the new window in cases where there is no referrer.
-  PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this);
-  if (it != opener()->pending_new_windows_.end()) {
+  PendingWindowMap::iterator it = GetOpener()->pending_new_windows_.find(this);
+  if (it != GetOpener()->pending_new_windows_.end()) {
     const NewWindowInfo& new_window_info = it->second;
     if (new_window_info.changed || !has_render_view_)
       params.src = it->second.url.spec();
@@ -1031,7 +1063,7 @@
 
   // Once a new guest is attached to the DOM of the embedder page, then the
   // lifetime of the new guest is no longer managed by the opener guest.
-  opener()->pending_new_windows_.erase(this);
+  GetOpener()->pending_new_windows_.erase(this);
 
   // The guest's frame name takes precedence over the BrowserPlugin's name.
   // The guest's frame name is assigned in
@@ -1291,7 +1323,7 @@
     OnUnlockMouse();
 
   // Restore the last seen state of text input to the view.
-  RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
+  RenderWidgetHostViewBase* rwhv = static_cast<RenderWidgetHostViewBase*>(
       web_contents()->GetRenderWidgetHostView());
   if (rwhv) {
     rwhv->TextInputTypeChanged(last_text_input_type_, last_input_mode_,
@@ -1499,13 +1531,13 @@
   last_input_mode_ = input_mode;
   last_can_compose_inline_ = can_compose_inline;
 
-  RenderWidgetHostViewPort::FromRWHV(
+  static_cast<RenderWidgetHostViewBase*>(
       web_contents()->GetRenderWidgetHostView())->TextInputTypeChanged(
           type, input_mode, can_compose_inline);
 }
 
 void BrowserPluginGuest::OnImeCancelComposition() {
-  RenderWidgetHostViewPort::FromRWHV(
+  static_cast<RenderWidgetHostViewBase*>(
       web_contents()->GetRenderWidgetHostView())->ImeCancelComposition();
 }
 
@@ -1513,7 +1545,7 @@
 void BrowserPluginGuest::OnImeCompositionRangeChanged(
       const gfx::Range& range,
       const std::vector<gfx::Rect>& character_bounds) {
-  RenderWidgetHostViewPort::FromRWHV(
+  static_cast<RenderWidgetHostViewBase*>(
       web_contents()->GetRenderWidgetHostView())->ImeCompositionRangeChanged(
           range, character_bounds);
 }
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h
index 61d2d8e..7380e36 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -25,7 +25,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
 #include "content/common/edit_command.h"
-#include "content/port/common/input_event_ack_state.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/public/browser/browser_plugin_guest_delegate.h"
 #include "content/public/browser/web_contents_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
@@ -59,6 +59,7 @@
 
 namespace content {
 
+class BrowserPluginGuestManager;
 class BrowserPluginHostFactory;
 class RenderWidgetHostView;
 class SiteInstance;
@@ -136,7 +137,8 @@
   bool visible() const { return guest_visible_; }
   bool is_in_destruction() { return is_in_destruction_; }
 
-  BrowserPluginGuest* opener() const { return opener_.get(); }
+  // Returns the BrowserPluginGuest that created this guest, if any.
+  BrowserPluginGuest* GetOpener() const;
 
   // Returns whether the mouse pointer was unlocked.
   bool UnlockMouseIfNecessary(const NativeWebKeyboardEvent& event);
@@ -148,6 +150,8 @@
       gfx::Size dst_size,
       const base::Callback<void(bool, const SkBitmap&)>& callback);
 
+  BrowserPluginGuestManager* GetBrowserPluginGuestManager() const;
+
   // WebContentsObserver implementation.
   virtual void DidCommitProvisionalLoadForFrame(
       int64 frame_id,
@@ -220,7 +224,7 @@
       const blink::WebGestureEvent& event) OVERRIDE;
 
   // Exposes the protected web_contents() from WebContentsObserver.
-  WebContentsImpl* GetWebContents();
+  WebContentsImpl* GetWebContents() const;
 
   gfx::Point GetScreenCoordinates(const gfx::Point& relative_position) const;
 
@@ -297,8 +301,7 @@
   // |web_contents| has to stay valid for the lifetime of BrowserPluginGuest.
   BrowserPluginGuest(int instance_id,
                      bool has_render_view,
-                     WebContentsImpl* web_contents,
-                     BrowserPluginGuest* opener);
+                     WebContentsImpl* web_contents);
 
   // Destroy unattached new windows that have been opened by this
   // BrowserPluginGuest.
@@ -488,7 +491,6 @@
 
   typedef std::map<BrowserPluginGuest*, NewWindowInfo> PendingWindowMap;
   PendingWindowMap pending_new_windows_;
-  base::WeakPtr<BrowserPluginGuest> opener_;
   // A counter to generate a unique request id for a permission request.
   // We only need the ids to be unique for a given BrowserPluginGuest.
   int next_permission_request_id_;
diff --git a/content/browser/browser_plugin/browser_plugin_guest_manager.cc b/content/browser/browser_plugin/browser_plugin_guest_manager.cc
index 443e7c7..d36dc13 100644
--- a/content/browser/browser_plugin/browser_plugin_guest_manager.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest_manager.cc
@@ -11,8 +11,12 @@
 #include "content/common/browser_plugin/browser_plugin_constants.h"
 #include "content/common/browser_plugin/browser_plugin_messages.h"
 #include "content/common/content_export.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_plugin_guest_manager_delegate.h"
+#include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/user_metrics.h"
+#include "content/public/common/content_client.h"
 #include "content/public/common/result_codes.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/url_utils.h"
@@ -23,18 +27,44 @@
 // static
 BrowserPluginHostFactory* BrowserPluginGuestManager::factory_ = NULL;
 
-BrowserPluginGuestManager::BrowserPluginGuestManager()
-    : next_instance_id_(browser_plugin::kInstanceIDNone) {
+BrowserPluginGuestManager::BrowserPluginGuestManager(BrowserContext* context)
+    : context_(context) {}
+
+BrowserPluginGuestManagerDelegate*
+BrowserPluginGuestManager::GetDelegate() const {
+  return context_->GetGuestManagerDelegate();
 }
 
 BrowserPluginGuestManager::~BrowserPluginGuestManager() {
 }
 
+// static.
+BrowserPluginGuestManager* BrowserPluginGuestManager::FromBrowserContext(
+    BrowserContext* context) {
+  BrowserPluginGuestManager* guest_manager =
+      static_cast<BrowserPluginGuestManager*>(
+        context->GetUserData(
+            browser_plugin::kBrowserPluginGuestManagerKeyName));
+  if (!guest_manager) {
+    guest_manager = BrowserPluginGuestManager::Create(context);
+    context->SetUserData(browser_plugin::kBrowserPluginGuestManagerKeyName,
+                         guest_manager);
+  }
+  return guest_manager;
+}
+
 // static
-BrowserPluginGuestManager* BrowserPluginGuestManager::Create() {
+BrowserPluginGuestManager* BrowserPluginGuestManager::Create(
+    BrowserContext* context) {
   if (factory_)
-    return factory_->CreateBrowserPluginGuestManager();
-  return new BrowserPluginGuestManager();
+    return factory_->CreateBrowserPluginGuestManager(context);
+  return new BrowserPluginGuestManager(context);
+}
+
+int BrowserPluginGuestManager::GetNextInstanceID() {
+  if (!GetDelegate())
+    return 0;
+  return GetDelegate()->GetNextInstanceID();
 }
 
 BrowserPluginGuest* BrowserPluginGuestManager::CreateGuest(
@@ -48,7 +78,7 @@
   // since we depend on this in other parts of the code, such as FilePath
   // creation. If the validation fails, treat it as a bad message and kill the
   // renderer process.
-  if (!IsStringUTF8(params.storage_partition_id)) {
+  if (!base::IsStringUTF8(params.storage_partition_id)) {
     content::RecordAction(
         base::UserMetricsAction("BadMessageTerminate_BPGM"));
     base::KillProcess(
@@ -57,15 +87,8 @@
     return NULL;
   }
 
-  // We usually require BrowserPlugins to be hosted by a storage isolated
-  // extension. We treat WebUI pages as a special case if they host the
-  // BrowserPlugin in a component extension iframe. In that case, we use the
-  // iframe's URL to determine the extension.
   const GURL& embedder_site_url = embedder_site_instance->GetSiteURL();
-  GURL validated_frame_url(params.embedder_frame_url);
-  embedder_process_host->FilterURL(false, &validated_frame_url);
-  const std::string& host = content::HasWebUIScheme(embedder_site_url) ?
-       validated_frame_url.host() : embedder_site_url.host();
+  const std::string& host = embedder_site_url.host();
 
   std::string url_encoded_partition = net::EscapeQueryParamValue(
       params.storage_partition_id, false);
@@ -98,46 +121,51 @@
       extra_params.Pass());
 }
 
-BrowserPluginGuest* BrowserPluginGuestManager::GetGuestByInstanceID(
-    int instance_id,
-    int embedder_render_process_id) const {
-  if (!CanEmbedderAccessInstanceIDMaybeKill(embedder_render_process_id,
-                                            instance_id)) {
-    return NULL;
+static void BrowserPluginGuestByInstanceIDCallback(
+    const BrowserPluginGuestManager::GuestByInstanceIDCallback& callback,
+    WebContents* guest_web_contents) {
+  if (!guest_web_contents) {
+    callback.Run(NULL);
+    return;
   }
-  GuestInstanceMap::const_iterator it =
-      guest_web_contents_by_instance_id_.find(instance_id);
-  if (it == guest_web_contents_by_instance_id_.end())
-    return NULL;
-  return static_cast<WebContentsImpl*>(it->second)->GetBrowserPluginGuest();
+  callback.Run(static_cast<WebContentsImpl*>(guest_web_contents)->
+                   GetBrowserPluginGuest());
+}
+
+void BrowserPluginGuestManager::MaybeGetGuestByInstanceIDOrKill(
+    int instance_id,
+    int embedder_render_process_id,
+    const GuestByInstanceIDCallback& callback) const {
+  if (!GetDelegate()) {
+    callback.Run(NULL);
+    return;
+  }
+
+  GetDelegate()->MaybeGetGuestByInstanceIDOrKill(
+      instance_id,
+      embedder_render_process_id,
+      base::Bind(&BrowserPluginGuestByInstanceIDCallback,
+                 callback));
 }
 
 void BrowserPluginGuestManager::AddGuest(int instance_id,
-                                         WebContentsImpl* guest_web_contents) {
-  DCHECK(guest_web_contents_by_instance_id_.find(instance_id) ==
-         guest_web_contents_by_instance_id_.end());
-  guest_web_contents_by_instance_id_[instance_id] = guest_web_contents;
+                                         WebContents* guest_web_contents) {
+  if (!GetDelegate())
+    return;
+  GetDelegate()->AddGuest(instance_id, guest_web_contents);
 }
 
 void BrowserPluginGuestManager::RemoveGuest(int instance_id) {
-  DCHECK(guest_web_contents_by_instance_id_.find(instance_id) !=
-         guest_web_contents_by_instance_id_.end());
-  guest_web_contents_by_instance_id_.erase(instance_id);
+  if (!GetDelegate())
+    return;
+  GetDelegate()->RemoveGuest(instance_id);
 }
 
-bool BrowserPluginGuestManager::CanEmbedderAccessInstanceIDMaybeKill(
-    int embedder_render_process_id,
-    int instance_id) const {
-  if (!CanEmbedderAccessInstanceID(embedder_render_process_id, instance_id)) {
-    // The embedder process is trying to access a guest it does not own.
-    content::RecordAction(
-        base::UserMetricsAction("BadMessageTerminate_BPGM"));
-    base::KillProcess(
-        RenderProcessHost::FromID(embedder_render_process_id)->GetHandle(),
-        content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
-    return false;
-  }
-  return true;
+static void BrowserPluginGuestMessageCallback(const IPC::Message& message,
+                                              BrowserPluginGuest* guest) {
+  if (!guest)
+    return;
+  guest->OnMessageReceivedFromEmbedder(message);
 }
 
 void BrowserPluginGuestManager::OnMessageReceived(const IPC::Message& message,
@@ -148,81 +176,33 @@
   PickleIterator iter(message);
   bool success = iter.ReadInt(&instance_id);
   DCHECK(success);
-  BrowserPluginGuest* guest =
-      GetGuestByInstanceID(instance_id, render_process_id);
-  if (!guest)
-    return;
-  guest->OnMessageReceivedFromEmbedder(message);
-}
-
-// static
-bool BrowserPluginGuestManager::CanEmbedderAccessGuest(
-    int embedder_render_process_id,
-    BrowserPluginGuest* guest) {
-  // The embedder can access the guest if it has not been attached and its
-  // opener's embedder lives in the same process as the given embedder.
-  if (!guest->attached()) {
-    if (!guest->opener())
-      return false;
-
-    return embedder_render_process_id ==
-        guest->opener()->embedder_web_contents()->GetRenderProcessHost()->
-            GetID();
-  }
-
-  return embedder_render_process_id ==
-      guest->embedder_web_contents()->GetRenderProcessHost()->GetID();
-}
-
-bool BrowserPluginGuestManager::CanEmbedderAccessInstanceID(
-    int embedder_render_process_id,
-    int instance_id) const {
-  // The embedder is trying to access a guest with a negative or zero
-  // instance ID.
-  if (instance_id <= browser_plugin::kInstanceIDNone)
-    return false;
-
-  // The embedder is trying to access an instance ID that has not yet been
-  // allocated by BrowserPluginGuestManager. This could cause instance ID
-  // collisions in the future, and potentially give one embedder access to a
-  // guest it does not own.
-  if (instance_id > next_instance_id_)
-    return false;
-
-  GuestInstanceMap::const_iterator it =
-      guest_web_contents_by_instance_id_.find(instance_id);
-  if (it == guest_web_contents_by_instance_id_.end())
-    return true;
-  BrowserPluginGuest* guest =
-      static_cast<WebContentsImpl*>(it->second)->GetBrowserPluginGuest();
-
-  return CanEmbedderAccessGuest(embedder_render_process_id, guest);
+  MaybeGetGuestByInstanceIDOrKill(instance_id,
+                                  render_process_id,
+                                  base::Bind(&BrowserPluginGuestMessageCallback,
+                                             message));
 }
 
 SiteInstance* BrowserPluginGuestManager::GetGuestSiteInstance(
     const GURL& guest_site) {
-  for (GuestInstanceMap::const_iterator it =
-       guest_web_contents_by_instance_id_.begin();
-       it != guest_web_contents_by_instance_id_.end(); ++it) {
-    if (it->second->GetSiteInstance()->GetSiteURL() == guest_site)
-      return it->second->GetSiteInstance();
-  }
-  return NULL;
+  if (!GetDelegate())
+    return NULL;
+  return GetDelegate()->GetGuestSiteInstance(guest_site);
+}
+
+static bool BrowserPluginGuestCallback(
+    const BrowserPluginGuestManager::GuestCallback& callback,
+    WebContents* guest_web_contents) {
+  return callback.Run(static_cast<WebContentsImpl*>(guest_web_contents)
+                          ->GetBrowserPluginGuest());
 }
 
 bool BrowserPluginGuestManager::ForEachGuest(
-    WebContentsImpl* embedder_web_contents, const GuestCallback& callback) {
-  for (GuestInstanceMap::iterator it =
-           guest_web_contents_by_instance_id_.begin();
-       it != guest_web_contents_by_instance_id_.end(); ++it) {
-    BrowserPluginGuest* guest = it->second->GetBrowserPluginGuest();
-    if (embedder_web_contents != guest->embedder_web_contents())
-      continue;
-
-    if (callback.Run(guest))
-      return true;
-  }
-  return false;
+    WebContents* embedder_web_contents, const GuestCallback& callback) {
+  if (!GetDelegate())
+    return false;
+  return GetDelegate()->ForEachGuest(embedder_web_contents,
+                                     base::Bind(&BrowserPluginGuestCallback,
+                                                callback));
 }
 
 }  // namespace content
diff --git a/content/browser/browser_plugin/browser_plugin_guest_manager.h b/content/browser/browser_plugin/browser_plugin_guest_manager.h
index 10c6b24..31210dd 100644
--- a/content/browser/browser_plugin/browser_plugin_guest_manager.h
+++ b/content/browser/browser_plugin/browser_plugin_guest_manager.h
@@ -13,6 +13,7 @@
 #include "base/supports_user_data.h"
 #include "base/values.h"
 #include "content/common/content_export.h"
+#include "content/public/browser/browser_plugin_guest_manager_delegate.h"
 #include "ipc/ipc_message.h"
 
 struct BrowserPluginHostMsg_Attach_Params;
@@ -29,12 +30,12 @@
 
 namespace content {
 
+class BrowserContext;
 class BrowserPluginGuest;
 class BrowserPluginHostFactory;
 class RenderWidgetHostImpl;
 class SiteInstance;
 class WebContents;
-class WebContentsImpl;
 
 // WARNING: All APIs should be guarded with a process ID check like
 // CanEmbedderAccessInstanceIDMaybeKill, to prevent abuse by normal renderer
@@ -44,7 +45,11 @@
  public:
   virtual ~BrowserPluginGuestManager();
 
-  static BrowserPluginGuestManager* Create();
+  static BrowserPluginGuestManager* FromBrowserContext(BrowserContext* context);
+
+  BrowserPluginGuestManagerDelegate* GetDelegate() const;
+
+  static BrowserPluginGuestManager* Create(BrowserContext* context);
 
   // Overrides factory for testing. Default (NULL) value indicates regular
   // (non-test) environment.
@@ -52,8 +57,9 @@
     content::BrowserPluginGuestManager::factory_ = factory;
   }
 
-  // Gets the next available instance id.
-  int get_next_instance_id() { return ++next_instance_id_; }
+  // Gets the next available instance id. 0 is considered an invalid instance
+  // ID.
+  int GetNextInstanceID();
 
   // Creates a guest WebContents with the provided |instance_id| and |params|.
   // If params.src is present, the new guest will also be navigated to the
@@ -65,27 +71,21 @@
       const BrowserPluginHostMsg_Attach_Params& params,
       scoped_ptr<base::DictionaryValue> extra_params);
 
-  // Returns a BrowserPluginGuest given an |instance_id|. Returns NULL if the
-  // guest wasn't found.  If the embedder is not permitted to access the given
-  // |instance_id|, the embedder is killed, and NULL is returned.
-  BrowserPluginGuest* GetGuestByInstanceID(
-      int instance_id,
-      int embedder_render_process_id) const;
-
   // Adds a new |guest_web_contents| to the embedder (overridable in test).
-  virtual void AddGuest(int instance_id, WebContentsImpl* guest_web_contents);
+  virtual void AddGuest(int instance_id, WebContents* guest_web_contents);
 
   // Removes the guest with the given |instance_id| from this
   // BrowserPluginGuestManager.
   void RemoveGuest(int instance_id);
 
-  // Returns whether the specified embedder is permitted to access the given
-  // |instance_id|, and kills the embedder if not.
-  bool CanEmbedderAccessInstanceIDMaybeKill(int embedder_render_process_id,
-                                            int instance_id) const;
+  typedef base::Callback<void(BrowserPluginGuest*)> GuestByInstanceIDCallback;
+  void MaybeGetGuestByInstanceIDOrKill(
+       int instance_id,
+       int embedder_render_process_id,
+       const GuestByInstanceIDCallback& callback) const;
 
   typedef base::Callback<bool(BrowserPluginGuest*)> GuestCallback;
-  bool ForEachGuest(WebContentsImpl* embedder_web_contents,
+  bool ForEachGuest(WebContents* embedder_web_contents,
                     const GuestCallback& callback);
 
   void OnMessageReceived(const IPC::Message& message, int render_process_id);
@@ -93,21 +93,7 @@
  private:
   friend class TestBrowserPluginGuestManager;
 
-  BrowserPluginGuestManager();
-
-  // Returns whether the given embedder process is allowed to access the
-  // provided |guest|.
-  static bool CanEmbedderAccessGuest(int embedder_render_process_id,
-                                     BrowserPluginGuest* guest);
-
-  // Returns whether the given embedder process is allowed to use the provided
-  // |instance_id| or access the guest associated with the |instance_id|. If the
-  // embedder can, the method returns true. If the guest does not exist but the
-  // embedder can use that |instance_id|, then it returns true. If the embedder
-  // is not permitted to use that instance ID or access the associated guest,
-  // then it returns false.
-  bool CanEmbedderAccessInstanceID(int embedder_render_process_id,
-                                   int instance_id) const;
+  explicit BrowserPluginGuestManager(BrowserContext* context);
 
   // Returns an existing SiteInstance if the current profile has a guest of the
   // given |guest_site|.
@@ -116,8 +102,11 @@
   // Static factory instance (always NULL outside of tests).
   static BrowserPluginHostFactory* factory_;
 
+  // The BrowserContext in which this manager this stored.
+  BrowserContext* context_;
+
   // Contains guests' WebContents, mapping from their instance ids.
-  typedef std::map<int, WebContentsImpl*> GuestInstanceMap;
+  typedef std::map<int, WebContents*> GuestInstanceMap;
   GuestInstanceMap guest_web_contents_by_instance_id_;
   int next_instance_id_;
 
@@ -127,4 +116,3 @@
 }  // namespace content
 
 #endif  // CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_MANAGER_H_
-
diff --git a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
index b405950..c054c4a 100644
--- a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
+++ b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
@@ -15,6 +15,7 @@
 #include "content/browser/browser_plugin/test_browser_plugin_guest.h"
 #include "content/browser/browser_plugin/test_browser_plugin_guest_delegate.h"
 #include "content/browser/browser_plugin/test_browser_plugin_guest_manager.h"
+#include "content/browser/browser_plugin/test_guest_manager_delegate.h"
 #include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/frame_host/render_widget_host_view_guest.h"
@@ -35,6 +36,7 @@
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
+#include "content/shell/browser/shell_browser_context.h"
 #include "net/base/net_util.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/embedded_test_server/http_request.h"
@@ -102,11 +104,11 @@
 class TestBrowserPluginHostFactory : public BrowserPluginHostFactory {
  public:
   virtual BrowserPluginGuestManager*
-      CreateBrowserPluginGuestManager() OVERRIDE {
+      CreateBrowserPluginGuestManager(BrowserContext* context) OVERRIDE {
     guest_manager_instance_count_++;
     if (message_loop_runner_)
       message_loop_runner_->Quit();
-    return new TestBrowserPluginGuestManager();
+    return new TestBrowserPluginGuestManager(context);
   }
 
   virtual BrowserPluginGuest* CreateBrowserPluginGuest(
@@ -230,17 +232,17 @@
 
   virtual void SetUp() OVERRIDE {
     // Override factory to create tests instances of BrowserPlugin*.
-    content::BrowserPluginEmbedder::set_factory_for_testing(
+    BrowserPluginEmbedder::set_factory_for_testing(
         TestBrowserPluginHostFactory::GetInstance());
-    content::BrowserPluginGuest::set_factory_for_testing(
+    BrowserPluginGuest::set_factory_for_testing(
         TestBrowserPluginHostFactory::GetInstance());
-    content::BrowserPluginGuestManager::set_factory_for_testing(
+    BrowserPluginGuestManager::set_factory_for_testing(
         TestBrowserPluginHostFactory::GetInstance());
     ContentBrowserTest::SetUp();
   }
   virtual void TearDown() OVERRIDE {
-    content::BrowserPluginEmbedder::set_factory_for_testing(NULL);
-    content::BrowserPluginGuest::set_factory_for_testing(NULL);
+    BrowserPluginEmbedder::set_factory_for_testing(NULL);
+    BrowserPluginGuest::set_factory_for_testing(NULL);
 
     ContentBrowserTest::TearDown();
   }
@@ -285,6 +287,10 @@
 
     WebContentsImpl* embedder_web_contents = static_cast<WebContentsImpl*>(
         shell()->web_contents());
+    static_cast<ShellBrowserContext*>(
+        embedder_web_contents->GetBrowserContext())->
+            set_guest_manager_delegate_for_testing(
+                TestGuestManagerDelegate::GetInstance());
     RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
         embedder_web_contents->GetRenderViewHost());
     RenderFrameHost* rfh = embedder_web_contents->GetMainFrame();
@@ -315,18 +321,13 @@
     ASSERT_TRUE(test_embedder_);
 
     test_guest_manager_ = static_cast<TestBrowserPluginGuestManager*>(
-        embedder_web_contents->GetBrowserPluginGuestManager());
+        BrowserPluginGuestManager::FromBrowserContext(
+            test_embedder_->GetWebContents()->GetBrowserContext()));
     ASSERT_TRUE(test_guest_manager_);
 
-    test_guest_manager_->WaitForGuestAdded();
-
-    // Verify that we have exactly one guest.
-    const TestBrowserPluginGuestManager::GuestInstanceMap& instance_map =
-        test_guest_manager_->guest_web_contents_for_testing();
-    EXPECT_EQ(1u, instance_map.size());
-
     WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
-        instance_map.begin()->second);
+        test_guest_manager_->WaitForGuestAdded());
+
     test_guest_ = static_cast<TestBrowserPluginGuest*>(
         test_guest_web_contents->GetBrowserPluginGuest());
     test_guest_->WaitForLoadStop();
@@ -450,31 +451,6 @@
   ASSERT_EQ(test_embedder_after_nav, test_embedder());
 }
 
-// This test verifies that hiding the embedder also hides the guest.
-IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, BrowserPluginVisibilityChanged) {
-  const char kEmbedderURL[] = "/browser_plugin_embedder.html";
-  StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
-
-  // Hide the Browser Plugin.
-  RenderFrameHost* rfh = test_embedder()->web_contents()->GetMainFrame();
-  ExecuteSyncJSFunction(
-      rfh, "document.getElementById('plugin').style.visibility = 'hidden'");
-
-  // Make sure that the guest is hidden.
-  test_guest()->WaitUntilHidden();
-}
-
-IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderVisibilityChanged) {
-  const char kEmbedderURL[] = "/browser_plugin_embedder.html";
-  StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
-
-  // Hide the embedder.
-  test_embedder()->web_contents()->WasHidden();
-
-  // Make sure that hiding the embedder also hides the guest.
-  test_guest()->WaitUntilHidden();
-}
-
 // Verifies that installing/uninstalling touch-event handlers in the guest
 // plugin correctly updates the touch-event handling state in the embedder.
 IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AcceptTouchEvents) {
@@ -541,12 +517,9 @@
     ExecuteSyncJSFunction(
         test_embedder()->web_contents()->GetMainFrame(),
         base::StringPrintf("SetSrc('%s');", kHTMLForGuest));
-    test_guest_manager()->WaitForGuestAdded();
 
-    const TestBrowserPluginGuestManager::GuestInstanceMap& instance_map =
-        test_guest_manager()->guest_web_contents_for_testing();
     WebContentsImpl* test_guest_web_contents = static_cast<WebContentsImpl*>(
-        instance_map.begin()->second);
+        test_guest_manager()->WaitForGuestAdded());
     TestBrowserPluginGuest* new_test_guest =
         static_cast<TestBrowserPluginGuest*>(
           test_guest_web_contents->GetBrowserPluginGuest());
diff --git a/content/browser/browser_plugin/browser_plugin_host_factory.h b/content/browser/browser_plugin/browser_plugin_host_factory.h
index 9bfc1e2..b347100 100644
--- a/content/browser/browser_plugin/browser_plugin_host_factory.h
+++ b/content/browser/browser_plugin/browser_plugin_host_factory.h
@@ -23,7 +23,8 @@
 // Factory to create BrowserPlugin embedder and guest.
 class CONTENT_EXPORT BrowserPluginHostFactory {
  public:
-  virtual BrowserPluginGuestManager* CreateBrowserPluginGuestManager() = 0;
+  virtual BrowserPluginGuestManager* CreateBrowserPluginGuestManager(
+      BrowserContext* context) = 0;
 
   virtual BrowserPluginGuest* CreateBrowserPluginGuest(
       int instance_id,
diff --git a/content/browser/browser_plugin/test_browser_plugin_guest.cc b/content/browser/browser_plugin/test_browser_plugin_guest.cc
index 3bc074c..ea51e91 100644
--- a/content/browser/browser_plugin/test_browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/test_browser_plugin_guest.cc
@@ -16,13 +16,12 @@
 TestBrowserPluginGuest::TestBrowserPluginGuest(
     int instance_id,
     WebContentsImpl* web_contents)
-    : BrowserPluginGuest(instance_id, false, web_contents, NULL),
+    : BrowserPluginGuest(instance_id, false, web_contents),
       update_rect_count_(0),
       exit_observed_(false),
       focus_observed_(false),
       blur_observed_(false),
       advance_focus_observed_(false),
-      was_hidden_observed_(false),
       input_observed_(false),
       load_stop_observed_(false),
       ime_cancel_observed_(false) {
@@ -123,16 +122,6 @@
   advance_focus_message_loop_runner_->Run();
 }
 
-void TestBrowserPluginGuest::WaitUntilHidden() {
-  if (was_hidden_observed_) {
-    was_hidden_observed_ = false;
-    return;
-  }
-  was_hidden_message_loop_runner_ = new MessageLoopRunner();
-  was_hidden_message_loop_runner_->Run();
-  was_hidden_observed_ = false;
-}
-
 void TestBrowserPluginGuest::WaitForInput() {
   if (input_observed_) {
     input_observed_ = false;
@@ -239,10 +228,4 @@
   BrowserPluginGuest::OnResizeGuest(instance_id, params);
 }
 
-void TestBrowserPluginGuest::WasHidden() {
-  was_hidden_observed_ = true;
-  if (was_hidden_message_loop_runner_)
-    was_hidden_message_loop_runner_->Quit();
-}
-
 }  // namespace content
diff --git a/content/browser/browser_plugin/test_browser_plugin_guest.h b/content/browser/browser_plugin/test_browser_plugin_guest.h
index 6826fbd..9d86192 100644
--- a/content/browser/browser_plugin/test_browser_plugin_guest.h
+++ b/content/browser/browser_plugin/test_browser_plugin_guest.h
@@ -12,7 +12,6 @@
 
 namespace content {
 
-class RenderProcessHost;
 class RenderViewHost;
 class WebContentsImpl;
 
@@ -40,9 +39,6 @@
       int instance_id,
       const BrowserPluginHostMsg_ResizeGuest_Params& params) OVERRIDE;
 
-  // Overridden from WebContentsObserver.
-  virtual void WasHidden() OVERRIDE;
-
   // Test utilities to wait for a event we are interested in.
   // Waits until UpdateRect message is sent from the guest, meaning it is
   // ready/rendered.
@@ -54,8 +50,6 @@
   void WaitForBlur();
   // Waits for focus to move out of this guest.
   void WaitForAdvanceFocus();
-  // Waits until the guest is hidden.
-  void WaitUntilHidden();
   // Waits until guest exits.
   void WaitForExit();
   // Waits until input is observed.
@@ -86,7 +80,6 @@
   bool focus_observed_;
   bool blur_observed_;
   bool advance_focus_observed_;
-  bool was_hidden_observed_;
   bool input_observed_;
   bool load_stop_observed_;
   bool ime_cancel_observed_;
@@ -100,7 +93,6 @@
   scoped_refptr<MessageLoopRunner> focus_message_loop_runner_;
   scoped_refptr<MessageLoopRunner> blur_message_loop_runner_;
   scoped_refptr<MessageLoopRunner> advance_focus_message_loop_runner_;
-  scoped_refptr<MessageLoopRunner> was_hidden_message_loop_runner_;
   scoped_refptr<MessageLoopRunner> input_message_loop_runner_;
   scoped_refptr<MessageLoopRunner> load_stop_message_loop_runner_;
   scoped_refptr<MessageLoopRunner> auto_view_size_message_loop_runner_;
diff --git a/content/browser/browser_plugin/test_browser_plugin_guest_manager.cc b/content/browser/browser_plugin/test_browser_plugin_guest_manager.cc
index 2d74288..4060905 100644
--- a/content/browser/browser_plugin/test_browser_plugin_guest_manager.cc
+++ b/content/browser/browser_plugin/test_browser_plugin_guest_manager.cc
@@ -9,7 +9,10 @@
 
 namespace content {
 
-TestBrowserPluginGuestManager::TestBrowserPluginGuestManager() {
+TestBrowserPluginGuestManager::TestBrowserPluginGuestManager(
+    BrowserContext* context)
+    : BrowserPluginGuestManager(context),
+      last_guest_added_(NULL) {
 }
 
 TestBrowserPluginGuestManager::~TestBrowserPluginGuestManager() {
@@ -17,19 +20,26 @@
 
 void TestBrowserPluginGuestManager::AddGuest(
     int instance_id,
-    WebContentsImpl* guest_web_contents) {
+    WebContents* guest_web_contents) {
   BrowserPluginGuestManager::AddGuest(instance_id, guest_web_contents);
-  if (message_loop_runner_)
+  last_guest_added_ = guest_web_contents;
+  if (message_loop_runner_.get())
     message_loop_runner_->Quit();
 }
 
-void TestBrowserPluginGuestManager::WaitForGuestAdded() {
+WebContents* TestBrowserPluginGuestManager::WaitForGuestAdded() {
   // Check if guests were already created.
-  if (guest_web_contents_by_instance_id_.size() > 0)
-    return;
+  if (last_guest_added_) {
+    WebContents* last_guest_added = last_guest_added_;
+    last_guest_added_ = NULL;
+    return last_guest_added;
+  }
   // Wait otherwise.
   message_loop_runner_ = new MessageLoopRunner();
   message_loop_runner_->Run();
+  WebContents* last_guest_added = last_guest_added_;
+  last_guest_added_ = NULL;
+  return last_guest_added;
 }
 
 }  // namespace content
diff --git a/content/browser/browser_plugin/test_browser_plugin_guest_manager.h b/content/browser/browser_plugin/test_browser_plugin_guest_manager.h
index d7683cf..227eed4 100644
--- a/content/browser/browser_plugin/test_browser_plugin_guest_manager.h
+++ b/content/browser/browser_plugin/test_browser_plugin_guest_manager.h
@@ -22,17 +22,11 @@
 // BrowserPluginGuestManager to be used in tests.
 class TestBrowserPluginGuestManager : public BrowserPluginGuestManager {
  public:
-  typedef BrowserPluginGuestManager::GuestInstanceMap GuestInstanceMap;
-
-  TestBrowserPluginGuestManager();
+  explicit TestBrowserPluginGuestManager(BrowserContext* context);
   virtual ~TestBrowserPluginGuestManager();
 
-  const GuestInstanceMap& guest_web_contents_for_testing() const {
-    return guest_web_contents_by_instance_id_;
-  }
-
   // Waits until at least one guest is added to the guest manager.
-  void WaitForGuestAdded();
+  WebContents* WaitForGuestAdded();
 
  private:
   // BrowserPluginHostTest.ReloadEmbedder needs access to the GuestInstanceMap.
@@ -40,8 +34,9 @@
 
   // Overriden to intercept in test.
   virtual void AddGuest(int instance_id,
-                        WebContentsImpl* guest_web_contents) OVERRIDE;
+                        WebContents* guest_web_contents) OVERRIDE;
 
+  WebContents* last_guest_added_;
   scoped_refptr<MessageLoopRunner> message_loop_runner_;
   DISALLOW_COPY_AND_ASSIGN(TestBrowserPluginGuestManager);
 };
diff --git a/content/browser/browser_plugin/test_guest_manager_delegate.cc b/content/browser/browser_plugin/test_guest_manager_delegate.cc
new file mode 100644
index 0000000..11d3b34
--- /dev/null
+++ b/content/browser/browser_plugin/test_guest_manager_delegate.cc
@@ -0,0 +1,86 @@
+// 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.
+
+#include "content/browser/browser_plugin/test_guest_manager_delegate.h"
+
+#include "base/logging.h"
+#include "base/memory/singleton.h"
+#include "content/public/browser/site_instance.h"
+#include "content/public/browser/web_contents.h"
+
+namespace content {
+
+TestGuestManagerDelegate::TestGuestManagerDelegate()
+    : next_instance_id_(0) {
+}
+
+TestGuestManagerDelegate::~TestGuestManagerDelegate() {
+}
+
+// static.
+TestGuestManagerDelegate* TestGuestManagerDelegate::GetInstance() {
+  return Singleton<TestGuestManagerDelegate>::get();
+}
+
+int TestGuestManagerDelegate::GetNextInstanceID() {
+  return ++next_instance_id_;
+}
+
+void TestGuestManagerDelegate::AddGuest(
+    int guest_instance_id,
+    WebContents* guest_web_contents) {
+  DCHECK(guest_web_contents_by_instance_id_.find(guest_instance_id) ==
+         guest_web_contents_by_instance_id_.end());
+  guest_web_contents_by_instance_id_[guest_instance_id] = guest_web_contents;
+}
+
+void TestGuestManagerDelegate::RemoveGuest(
+    int guest_instance_id) {
+  GuestInstanceMap::iterator it =
+      guest_web_contents_by_instance_id_.find(guest_instance_id);
+  DCHECK(it != guest_web_contents_by_instance_id_.end());
+  guest_web_contents_by_instance_id_.erase(it);
+}
+
+void TestGuestManagerDelegate::MaybeGetGuestByInstanceIDOrKill(
+    int guest_instance_id,
+    int embedder_render_process_id,
+    const GuestByInstanceIDCallback& callback) {
+  GuestInstanceMap::const_iterator it =
+      guest_web_contents_by_instance_id_.find(guest_instance_id);
+  if (it == guest_web_contents_by_instance_id_.end()) {
+    callback.Run(NULL);
+    return;
+  }
+  callback.Run(it->second);
+}
+
+SiteInstance* TestGuestManagerDelegate::GetGuestSiteInstance(
+  const GURL& guest_site) {
+  for (GuestInstanceMap::const_iterator it =
+       guest_web_contents_by_instance_id_.begin();
+       it != guest_web_contents_by_instance_id_.end(); ++it) {
+    if (it->second->GetSiteInstance()->GetSiteURL() == guest_site)
+      return it->second->GetSiteInstance();
+  }
+  return NULL;
+}
+
+bool TestGuestManagerDelegate::ForEachGuest(
+    WebContents* embedder_web_contents,
+    const GuestCallback& callback) {
+  for (GuestInstanceMap::iterator it =
+           guest_web_contents_by_instance_id_.begin();
+       it != guest_web_contents_by_instance_id_.end(); ++it) {
+    WebContents* guest = it->second;
+    if (embedder_web_contents != guest->GetEmbedderWebContents())
+      continue;
+
+    if (callback.Run(guest))
+      return true;
+  }
+  return false;
+}
+
+}  // namespace content
diff --git a/content/browser/browser_plugin/test_guest_manager_delegate.h b/content/browser/browser_plugin/test_guest_manager_delegate.h
new file mode 100644
index 0000000..63f2811
--- /dev/null
+++ b/content/browser/browser_plugin/test_guest_manager_delegate.h
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef CONTENT_BROWSER_BROWSER_PLUGIN_TEST_GUEST_MANAGER_DELEGATE_H_
+#define CONTENT_BROWSER_BROWSER_PLUGIN_TEST_GUEST_MANAGER_DELEGATE_H_
+
+#include <map>
+
+#include "base/memory/singleton.h"
+#include "content/public/browser/browser_plugin_guest_manager_delegate.h"
+
+namespace content {
+
+// This class is temporary until BrowserPluginHostTest.* tests are entirely
+// moved out of content.
+class TestGuestManagerDelegate : public BrowserPluginGuestManagerDelegate {
+ public:
+  virtual ~TestGuestManagerDelegate();
+
+  static TestGuestManagerDelegate* GetInstance();
+
+  // BrowserPluginGuestManagerDelegate implementation.
+  virtual int GetNextInstanceID() OVERRIDE;
+  virtual void AddGuest(int guest_instance_id,
+                        WebContents* guest_web_contents) OVERRIDE;
+  virtual void RemoveGuest(int guest_instance_id) OVERRIDE;
+  virtual void MaybeGetGuestByInstanceIDOrKill(
+      int guest_instance_id,
+      int embedder_render_process_id,
+      const GuestByInstanceIDCallback& callback) OVERRIDE;
+  virtual SiteInstance* GetGuestSiteInstance(
+      const GURL& guest_site) OVERRIDE;
+  virtual bool ForEachGuest(WebContents* embedder_web_contents,
+                            const GuestCallback& callback) OVERRIDE;
+
+ private:
+  friend struct DefaultSingletonTraits<TestGuestManagerDelegate>;
+  TestGuestManagerDelegate();
+  // Contains guests' WebContents, mapping from their instance ids.
+  typedef std::map<int, WebContents*> GuestInstanceMap;
+  GuestInstanceMap guest_web_contents_by_instance_id_;
+
+  int next_instance_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestGuestManagerDelegate);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_BROWSER_PLUGIN_TEST_GUEST_MANAGER_DELEGATE_H_
diff --git a/content/browser/browser_url_handler_impl.cc b/content/browser/browser_url_handler_impl.cc
index bbf24e3..21793a1 100644
--- a/content/browser/browser_url_handler_impl.cc
+++ b/content/browser/browser_url_handler_impl.cc
@@ -24,13 +24,13 @@
     // Bug 26129: limit view-source to view the content and not any
     // other kind of 'active' url scheme like 'javascript' or 'data'.
     static const char* const default_allowed_sub_schemes[] = {
-      kHttpScheme,
-      kHttpsScheme,
-      kFtpScheme,
-      kChromeDevToolsScheme,
-      kChromeUIScheme,
-      kFileScheme,
-      kFileSystemScheme
+        url::kHttpScheme,
+        url::kHttpsScheme,
+        kFtpScheme,
+        kChromeDevToolsScheme,
+        kChromeUIScheme,
+        kFileScheme,
+        kFileSystemScheme
     };
 
     // Merge all the schemes for which view-source is allowed by default, with
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc
index 6a6a8b6..2dddca6 100644
--- a/content/browser/child_process_security_policy_impl.cc
+++ b/content/browser/child_process_security_policy_impl.cc
@@ -308,8 +308,8 @@
 
 ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl() {
   // We know about these schemes and believe them to be safe.
-  RegisterWebSafeScheme(kHttpScheme);
-  RegisterWebSafeScheme(kHttpsScheme);
+  RegisterWebSafeScheme(url::kHttpScheme);
+  RegisterWebSafeScheme(url::kHttpsScheme);
   RegisterWebSafeScheme(kFtpScheme);
   RegisterWebSafeScheme(kDataScheme);
   RegisterWebSafeScheme("feed");
diff --git a/content/browser/child_process_security_policy_unittest.cc b/content/browser/child_process_security_policy_unittest.cc
index 442b982..78bee5b 100644
--- a/content/browser/child_process_security_policy_unittest.cc
+++ b/content/browser/child_process_security_policy_unittest.cc
@@ -120,8 +120,8 @@
   ChildProcessSecurityPolicyImpl* p =
       ChildProcessSecurityPolicyImpl::GetInstance();
 
-  EXPECT_TRUE(p->IsWebSafeScheme(kHttpScheme));
-  EXPECT_TRUE(p->IsWebSafeScheme(kHttpsScheme));
+  EXPECT_TRUE(p->IsWebSafeScheme(url::kHttpScheme));
+  EXPECT_TRUE(p->IsWebSafeScheme(url::kHttpsScheme));
   EXPECT_TRUE(p->IsWebSafeScheme(kFtpScheme));
   EXPECT_TRUE(p->IsWebSafeScheme(kDataScheme));
   EXPECT_TRUE(p->IsWebSafeScheme("feed"));
diff --git a/content/browser/compositor/delegated_frame_host.cc b/content/browser/compositor/delegated_frame_host.cc
new file mode 100644
index 0000000..acfe613
--- /dev/null
+++ b/content/browser/compositor/delegated_frame_host.cc
@@ -0,0 +1,876 @@
+// 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.
+
+#include "content/browser/compositor/delegated_frame_host.h"
+
+#include "base/callback_helpers.h"
+#include "base/command_line.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/compositor_frame_ack.h"
+#include "cc/output/copy_output_request.h"
+#include "cc/resources/single_release_callback.h"
+#include "cc/resources/texture_mailbox.h"
+#include "content/browser/compositor/resize_lock.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
+#include "content/public/common/content_switches.h"
+#include "media/base/video_frame.h"
+#include "media/base/video_util.h"
+#include "skia/ext/image_operations.h"
+
+namespace content {
+
+////////////////////////////////////////////////////////////////////////////////
+// DelegatedFrameHostClient
+
+bool DelegatedFrameHostClient::ShouldCreateResizeLock() {
+  return GetDelegatedFrameHost()->ShouldCreateResizeLock();
+}
+
+void DelegatedFrameHostClient::RequestCopyOfOutput(
+    scoped_ptr<cc::CopyOutputRequest> request) {
+  return GetDelegatedFrameHost()->RequestCopyOfOutput(request.Pass());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DelegatedFrameHost
+
+DelegatedFrameHost::DelegatedFrameHost(DelegatedFrameHostClient* client)
+    : client_(client),
+      last_output_surface_id_(0),
+      pending_delegated_ack_count_(0),
+      skipped_frames_(false),
+      can_lock_compositor_(YES),
+      delegated_frame_evictor_(new DelegatedFrameEvictor(this)) {
+  ImageTransportFactory::GetInstance()->AddObserver(this);
+}
+
+void DelegatedFrameHost::WasShown() {
+  RenderWidgetHostImpl* host = client_->GetHost();
+  delegated_frame_evictor_->SetVisible(true);
+
+  if (host->is_accelerated_compositing_active() &&
+      !released_front_lock_.get()) {
+    ui::Compositor* compositor = client_->GetCompositor();
+    if (compositor)
+      released_front_lock_ = compositor->GetCompositorLock();
+  }
+}
+
+void DelegatedFrameHost::WasHidden() {
+  delegated_frame_evictor_->SetVisible(false);
+  released_front_lock_ = NULL;
+}
+
+void DelegatedFrameHost::MaybeCreateResizeLock() {
+  if (!client_->ShouldCreateResizeLock())
+    return;
+  DCHECK(client_->GetCompositor());
+
+  // Listen to changes in the compositor lock state.
+  ui::Compositor* compositor = client_->GetCompositor();
+  if (!compositor->HasObserver(this))
+    compositor->AddObserver(this);
+
+  bool defer_compositor_lock =
+      can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
+      can_lock_compositor_ == NO_PENDING_COMMIT;
+
+  if (can_lock_compositor_ == YES)
+    can_lock_compositor_ = YES_DID_LOCK;
+
+  resize_lock_ = client_->CreateResizeLock(defer_compositor_lock);
+}
+
+bool DelegatedFrameHost::ShouldCreateResizeLock() {
+  RenderWidgetHostImpl* host = client_->GetHost();
+
+  // On Windows while resizing, the the resize locks makes us mis-paint a white
+  // vertical strip (including the non-client area) if the content composition
+  // is lagging the UI composition. So here we disable the throttling so that
+  // the UI bits can draw ahead of the content thereby reducing the amount of
+  // whiteout. Because this causes the content to be drawn at wrong sizes while
+  // resizing we compensate by blocking the UI thread in Compositor::Draw() by
+  // issuing a FinishAllRendering() if we are resizing.
+#if defined(OS_WIN)
+  return false;
+#else
+  if (resize_lock_)
+    return false;
+
+  if (host->should_auto_resize())
+    return false;
+  if (!host->is_accelerated_compositing_active())
+    return false;
+
+  gfx::Size desired_size = client_->DesiredFrameSize();
+  if (desired_size == current_frame_size_in_dip_)
+    return false;
+
+  ui::Compositor* compositor = client_->GetCompositor();
+  if (!compositor)
+    return false;
+
+  return true;
+#endif
+}
+
+void DelegatedFrameHost::RequestCopyOfOutput(
+    scoped_ptr<cc::CopyOutputRequest> request) {
+  client_->GetLayer()->RequestCopyOfOutput(request.Pass());
+}
+
+gfx::Rect DelegatedFrameHost::GetViewBoundsWithResizeLock(
+    const gfx::Rect& bounds) const {
+  if (resize_lock_.get())
+    return gfx::Rect(bounds.origin(), resize_lock_->expected_size());
+  else
+    return bounds;
+}
+
+void DelegatedFrameHost::CopyFromCompositingSurface(
+    const gfx::Rect& src_subrect,
+    const gfx::Size& dst_size,
+    const base::Callback<void(bool, const SkBitmap&)>& callback,
+    const SkBitmap::Config config) {
+  // Only ARGB888 and RGB565 supported as of now.
+  bool format_support = ((config == SkBitmap::kRGB_565_Config) ||
+                         (config == SkBitmap::kARGB_8888_Config));
+  if (!format_support) {
+    DCHECK(format_support);
+    callback.Run(false, SkBitmap());
+    return;
+  }
+  if (!CanCopyToBitmap()) {
+    callback.Run(false, SkBitmap());
+    return;
+  }
+
+  const gfx::Size& dst_size_in_pixel = client_->ConvertViewSizeToPixel(
+      dst_size);
+  scoped_ptr<cc::CopyOutputRequest> request =
+      cc::CopyOutputRequest::CreateRequest(base::Bind(
+          &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult,
+          dst_size_in_pixel,
+          config,
+          callback));
+  gfx::Rect src_subrect_in_pixel =
+      ConvertRectToPixel(client_->CurrentDeviceScaleFactor(), src_subrect);
+  request->set_area(src_subrect_in_pixel);
+  client_->RequestCopyOfOutput(request.Pass());
+}
+
+void DelegatedFrameHost::CopyFromCompositingSurfaceToVideoFrame(
+      const gfx::Rect& src_subrect,
+      const scoped_refptr<media::VideoFrame>& target,
+      const base::Callback<void(bool)>& callback) {
+  if (!CanCopyToVideoFrame()) {
+    callback.Run(false);
+    return;
+  }
+
+  // Try get a texture to reuse.
+  scoped_refptr<OwnedMailbox> subscriber_texture;
+  if (frame_subscriber_) {
+    if (!idle_frame_subscriber_textures_.empty()) {
+      subscriber_texture = idle_frame_subscriber_textures_.back();
+      idle_frame_subscriber_textures_.pop_back();
+    } else if (GLHelper* helper =
+                   ImageTransportFactory::GetInstance()->GetGLHelper()) {
+      subscriber_texture = new OwnedMailbox(helper);
+    }
+    if (subscriber_texture.get())
+      active_frame_subscriber_textures_.insert(subscriber_texture.get());
+  }
+
+  scoped_ptr<cc::CopyOutputRequest> request =
+      cc::CopyOutputRequest::CreateRequest(base::Bind(
+          &DelegatedFrameHost::
+               CopyFromCompositingSurfaceHasResultForVideo,
+          AsWeakPtr(),  // For caching the ReadbackYUVInterface on this class.
+          subscriber_texture,
+          target,
+          callback));
+  gfx::Rect src_subrect_in_pixel =
+      ConvertRectToPixel(client_->CurrentDeviceScaleFactor(), src_subrect);
+  request->set_area(src_subrect_in_pixel);
+  if (subscriber_texture.get()) {
+    request->SetTextureMailbox(
+        cc::TextureMailbox(subscriber_texture->mailbox(),
+                           subscriber_texture->target(),
+                           subscriber_texture->sync_point()));
+  }
+  client_->RequestCopyOfOutput(request.Pass());
+}
+
+bool DelegatedFrameHost::CanCopyToBitmap() const {
+  return client_->GetCompositor() &&
+         client_->GetLayer()->has_external_content();
+}
+
+bool DelegatedFrameHost::CanCopyToVideoFrame() const {
+  RenderWidgetHostImpl* host = client_->GetHost();
+  return client_->GetCompositor() &&
+         client_->GetLayer()->has_external_content() &&
+         host->is_accelerated_compositing_active();
+}
+
+bool DelegatedFrameHost::CanSubscribeFrame() const {
+  return true;
+}
+
+void DelegatedFrameHost::BeginFrameSubscription(
+    scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
+  frame_subscriber_ = subscriber.Pass();
+}
+
+void DelegatedFrameHost::EndFrameSubscription() {
+  idle_frame_subscriber_textures_.clear();
+  frame_subscriber_.reset();
+}
+
+bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const {
+  if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
+      can_lock_compositor_ == NO_PENDING_COMMIT ||
+      !resize_lock_.get())
+    return false;
+
+  return size_in_dip != resize_lock_->expected_size();
+}
+
+void DelegatedFrameHost::WasResized() {
+  MaybeCreateResizeLock();
+}
+
+void DelegatedFrameHost::CheckResizeLock() {
+  if (!resize_lock_ ||
+      resize_lock_->expected_size() != current_frame_size_in_dip_)
+    return;
+
+  // Since we got the size we were looking for, unlock the compositor. But delay
+  // the release of the lock until we've kicked a frame with the new texture, to
+  // avoid resizing the UI before we have a chance to draw a "good" frame.
+  resize_lock_->UnlockCompositor();
+  ui::Compositor* compositor = client_->GetCompositor();
+  if (compositor) {
+    if (!compositor->HasObserver(this))
+      compositor->AddObserver(this);
+  }
+}
+
+void DelegatedFrameHost::DidReceiveFrameFromRenderer() {
+  if (frame_subscriber() && CanCopyToVideoFrame()) {
+    const base::TimeTicks present_time = base::TimeTicks::Now();
+    scoped_refptr<media::VideoFrame> frame;
+    RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback;
+    if (frame_subscriber()->ShouldCaptureFrame(present_time,
+                                               &frame, &callback)) {
+      CopyFromCompositingSurfaceToVideoFrame(
+          gfx::Rect(current_frame_size_in_dip_),
+          frame,
+          base::Bind(callback, present_time));
+    }
+  }
+}
+
+void DelegatedFrameHost::SwapDelegatedFrame(
+    uint32 output_surface_id,
+    scoped_ptr<cc::DelegatedFrameData> frame_data,
+    float frame_device_scale_factor,
+    const std::vector<ui::LatencyInfo>& latency_info) {
+  RenderWidgetHostImpl* host = client_->GetHost();
+  DCHECK_NE(0u, frame_data->render_pass_list.size());
+
+  cc::RenderPass* root_pass = frame_data->render_pass_list.back();
+
+  gfx::Size frame_size = root_pass->output_rect.size();
+  gfx::Size frame_size_in_dip =
+      ConvertSizeToDIP(frame_device_scale_factor, frame_size);
+
+  gfx::Rect damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect);
+  damage_rect.Intersect(gfx::Rect(frame_size));
+  gfx::Rect damage_rect_in_dip =
+      ConvertRectToDIP(frame_device_scale_factor, damage_rect);
+
+  if (ShouldSkipFrame(frame_size_in_dip)) {
+    cc::CompositorFrameAck ack;
+    cc::TransferableResource::ReturnResources(frame_data->resource_list,
+                                              &ack.resources);
+    RenderWidgetHostImpl::SendSwapCompositorFrameAck(
+        host->GetRoutingID(), output_surface_id,
+        host->GetProcess()->GetID(), ack);
+    skipped_frames_ = true;
+    return;
+  }
+
+  if (skipped_frames_) {
+    skipped_frames_ = false;
+    damage_rect = gfx::Rect(frame_size);
+    damage_rect_in_dip = gfx::Rect(frame_size_in_dip);
+
+    // Give the same damage rect to the compositor.
+    cc::RenderPass* root_pass = frame_data->render_pass_list.back();
+    root_pass->damage_rect = damage_rect;
+  }
+
+  if (output_surface_id != last_output_surface_id_) {
+    // Resource ids are scoped by the output surface.
+    // If the originating output surface doesn't match the last one, it
+    // indicates the renderer's output surface may have been recreated, in which
+    // case we should recreate the DelegatedRendererLayer, to avoid matching
+    // resources from the old one with resources from the new one which would
+    // have the same id. Changing the layer to showing painted content destroys
+    // the DelegatedRendererLayer.
+    EvictDelegatedFrame();
+
+    // Drop the cc::DelegatedFrameResourceCollection so that we will not return
+    // any resources from the old output surface with the new output surface id.
+    if (resource_collection_.get()) {
+      resource_collection_->SetClient(NULL);
+
+      if (resource_collection_->LoseAllResources())
+        SendReturnedDelegatedResources(last_output_surface_id_);
+
+      resource_collection_ = NULL;
+    }
+    last_output_surface_id_ = output_surface_id;
+  }
+  if (frame_size.IsEmpty()) {
+    DCHECK_EQ(0u, frame_data->resource_list.size());
+    EvictDelegatedFrame();
+  } else {
+    if (!resource_collection_) {
+      resource_collection_ = new cc::DelegatedFrameResourceCollection;
+      resource_collection_->SetClient(this);
+    }
+    // If the physical frame size changes, we need a new |frame_provider_|. If
+    // the physical frame size is the same, but the size in DIP changed, we
+    // need to adjust the scale at which the frames will be drawn, and we do
+    // this by making a new |frame_provider_| also to ensure the scale change
+    // is presented in sync with the new frame content.
+    if (!frame_provider_.get() || frame_size != frame_provider_->frame_size() ||
+        frame_size_in_dip != current_frame_size_in_dip_) {
+      frame_provider_ = new cc::DelegatedFrameProvider(
+          resource_collection_.get(), frame_data.Pass());
+      client_->GetLayer()->SetShowDelegatedContent(frame_provider_.get(),
+                                                   frame_size_in_dip);
+    } else {
+      frame_provider_->SetFrameData(frame_data.Pass());
+    }
+  }
+  released_front_lock_ = NULL;
+  current_frame_size_in_dip_ = frame_size_in_dip;
+  CheckResizeLock();
+
+  client_->SchedulePaintInRect(damage_rect_in_dip);
+
+  pending_delegated_ack_count_++;
+
+  ui::Compositor* compositor = client_->GetCompositor();
+  if (!compositor) {
+    SendDelegatedFrameAck(output_surface_id);
+  } else {
+    for (size_t i = 0; i < latency_info.size(); i++)
+      compositor->SetLatencyInfo(latency_info[i]);
+    AddOnCommitCallbackAndDisableLocks(
+        base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck,
+                   AsWeakPtr(),
+                   output_surface_id));
+  }
+  DidReceiveFrameFromRenderer();
+  if (frame_provider_.get())
+    delegated_frame_evictor_->SwappedFrame(!host->is_hidden());
+  // Note: the frame may have been evicted immediately.
+}
+
+void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) {
+  RenderWidgetHostImpl* host = client_->GetHost();
+  cc::CompositorFrameAck ack;
+  if (resource_collection_)
+    resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
+  RenderWidgetHostImpl::SendSwapCompositorFrameAck(host->GetRoutingID(),
+                                                   output_surface_id,
+                                                   host->GetProcess()->GetID(),
+                                                   ack);
+  DCHECK_GT(pending_delegated_ack_count_, 0);
+  pending_delegated_ack_count_--;
+}
+
+void DelegatedFrameHost::UnusedResourcesAreAvailable() {
+  if (pending_delegated_ack_count_)
+    return;
+
+  SendReturnedDelegatedResources(last_output_surface_id_);
+}
+
+void DelegatedFrameHost::SendReturnedDelegatedResources(
+    uint32 output_surface_id) {
+  RenderWidgetHostImpl* host = client_->GetHost();
+  DCHECK(resource_collection_);
+
+  cc::CompositorFrameAck ack;
+  resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
+  DCHECK(!ack.resources.empty());
+
+  RenderWidgetHostImpl::SendReclaimCompositorResources(
+      host->GetRoutingID(),
+      output_surface_id,
+      host->GetProcess()->GetID(),
+      ack);
+}
+
+void DelegatedFrameHost::EvictDelegatedFrame() {
+  client_->GetLayer()->SetShowPaintedContent();
+  frame_provider_ = NULL;
+  delegated_frame_evictor_->DiscardedFrame();
+}
+
+// static
+void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult(
+    const gfx::Size& dst_size_in_pixel,
+    const SkBitmap::Config config,
+    const base::Callback<void(bool, const SkBitmap&)>& callback,
+    scoped_ptr<cc::CopyOutputResult> result) {
+  if (result->IsEmpty() || result->size().IsEmpty()) {
+    callback.Run(false, SkBitmap());
+    return;
+  }
+
+  if (result->HasTexture()) {
+    PrepareTextureCopyOutputResult(dst_size_in_pixel, config,
+                                   callback,
+                                   result.Pass());
+    return;
+  }
+
+  DCHECK(result->HasBitmap());
+  PrepareBitmapCopyOutputResult(dst_size_in_pixel, config, callback,
+                                result.Pass());
+}
+
+static void CopyFromCompositingSurfaceFinished(
+    const base::Callback<void(bool, const SkBitmap&)>& callback,
+    scoped_ptr<cc::SingleReleaseCallback> release_callback,
+    scoped_ptr<SkBitmap> bitmap,
+    scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
+    bool result) {
+  bitmap_pixels_lock.reset();
+
+  uint32 sync_point = 0;
+  if (result) {
+    GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
+    sync_point = gl_helper->InsertSyncPoint();
+  }
+  bool lost_resource = sync_point == 0;
+  release_callback->Run(sync_point, lost_resource);
+
+  callback.Run(result, *bitmap);
+}
+
+// static
+void DelegatedFrameHost::PrepareTextureCopyOutputResult(
+    const gfx::Size& dst_size_in_pixel,
+    const SkBitmap::Config config,
+    const base::Callback<void(bool, const SkBitmap&)>& callback,
+    scoped_ptr<cc::CopyOutputResult> result) {
+  DCHECK(result->HasTexture());
+  base::ScopedClosureRunner scoped_callback_runner(
+      base::Bind(callback, false, SkBitmap()));
+
+  scoped_ptr<SkBitmap> bitmap(new SkBitmap);
+  bitmap->setConfig(config,
+                    dst_size_in_pixel.width(), dst_size_in_pixel.height(),
+                    0, kOpaque_SkAlphaType);
+  if (!bitmap->allocPixels())
+    return;
+
+  ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+  GLHelper* gl_helper = factory->GetGLHelper();
+  if (!gl_helper)
+    return;
+
+  scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
+      new SkAutoLockPixels(*bitmap));
+  uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
+
+  cc::TextureMailbox texture_mailbox;
+  scoped_ptr<cc::SingleReleaseCallback> release_callback;
+  result->TakeTexture(&texture_mailbox, &release_callback);
+  DCHECK(texture_mailbox.IsTexture());
+  if (!texture_mailbox.IsTexture())
+    return;
+
+  ignore_result(scoped_callback_runner.Release());
+
+  gl_helper->CropScaleReadbackAndCleanMailbox(
+      texture_mailbox.mailbox(),
+      texture_mailbox.sync_point(),
+      result->size(),
+      gfx::Rect(result->size()),
+      dst_size_in_pixel,
+      pixels,
+      config,
+      base::Bind(&CopyFromCompositingSurfaceFinished,
+                 callback,
+                 base::Passed(&release_callback),
+                 base::Passed(&bitmap),
+                 base::Passed(&bitmap_pixels_lock)));
+}
+
+// static
+void DelegatedFrameHost::PrepareBitmapCopyOutputResult(
+    const gfx::Size& dst_size_in_pixel,
+    const SkBitmap::Config config,
+    const base::Callback<void(bool, const SkBitmap&)>& callback,
+    scoped_ptr<cc::CopyOutputResult> result) {
+  if (config != SkBitmap::kARGB_8888_Config) {
+    NOTIMPLEMENTED();
+    callback.Run(false, SkBitmap());
+    return;
+  }
+  DCHECK(result->HasBitmap());
+  base::ScopedClosureRunner scoped_callback_runner(
+      base::Bind(callback, false, SkBitmap()));
+
+  scoped_ptr<SkBitmap> source = result->TakeBitmap();
+  DCHECK(source);
+  if (!source)
+    return;
+
+  ignore_result(scoped_callback_runner.Release());
+
+  SkBitmap bitmap = skia::ImageOperations::Resize(
+      *source,
+      skia::ImageOperations::RESIZE_BEST,
+      dst_size_in_pixel.width(),
+      dst_size_in_pixel.height());
+  callback.Run(true, bitmap);
+}
+
+// static
+void DelegatedFrameHost::ReturnSubscriberTexture(
+    base::WeakPtr<DelegatedFrameHost> dfh,
+    scoped_refptr<OwnedMailbox> subscriber_texture,
+    uint32 sync_point) {
+  if (!subscriber_texture.get())
+    return;
+  if (!dfh)
+    return;
+  DCHECK_NE(
+      dfh->active_frame_subscriber_textures_.count(subscriber_texture.get()),
+      0u);
+
+  subscriber_texture->UpdateSyncPoint(sync_point);
+
+  dfh->active_frame_subscriber_textures_.erase(subscriber_texture.get());
+  if (dfh->frame_subscriber_ && subscriber_texture->texture_id())
+    dfh->idle_frame_subscriber_textures_.push_back(subscriber_texture);
+}
+
+void DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo(
+    base::WeakPtr<DelegatedFrameHost> dfh,
+    const base::Callback<void(bool)>& callback,
+    scoped_refptr<OwnedMailbox> subscriber_texture,
+    scoped_ptr<cc::SingleReleaseCallback> release_callback,
+    bool result) {
+  callback.Run(result);
+
+  uint32 sync_point = 0;
+  if (result) {
+    GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
+    sync_point = gl_helper->InsertSyncPoint();
+  }
+  if (release_callback) {
+    // A release callback means the texture came from the compositor, so there
+    // should be no |subscriber_texture|.
+    DCHECK(!subscriber_texture);
+    bool lost_resource = sync_point == 0;
+    release_callback->Run(sync_point, lost_resource);
+  }
+  ReturnSubscriberTexture(dfh, subscriber_texture, sync_point);
+}
+
+// static
+void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo(
+    base::WeakPtr<DelegatedFrameHost> dfh,
+    scoped_refptr<OwnedMailbox> subscriber_texture,
+    scoped_refptr<media::VideoFrame> video_frame,
+    const base::Callback<void(bool)>& callback,
+    scoped_ptr<cc::CopyOutputResult> result) {
+  base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
+  base::ScopedClosureRunner scoped_return_subscriber_texture(
+      base::Bind(&ReturnSubscriberTexture, dfh, subscriber_texture, 0));
+
+  if (!dfh)
+    return;
+  if (result->IsEmpty())
+    return;
+  if (result->size().IsEmpty())
+    return;
+
+  // Compute the dest size we want after the letterboxing resize. Make the
+  // coordinates and sizes even because we letterbox in YUV space
+  // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
+  // line up correctly.
+  // The video frame's coded_size() and the result's size() are both physical
+  // pixels.
+  gfx::Rect region_in_frame =
+      media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()),
+                                    result->size());
+  region_in_frame = gfx::Rect(region_in_frame.x() & ~1,
+                              region_in_frame.y() & ~1,
+                              region_in_frame.width() & ~1,
+                              region_in_frame.height() & ~1);
+  if (region_in_frame.IsEmpty())
+    return;
+
+  if (!result->HasTexture()) {
+    DCHECK(result->HasBitmap());
+    scoped_ptr<SkBitmap> bitmap = result->TakeBitmap();
+    // Scale the bitmap to the required size, if necessary.
+    SkBitmap scaled_bitmap;
+    if (result->size().width() != region_in_frame.width() ||
+        result->size().height() != region_in_frame.height()) {
+      skia::ImageOperations::ResizeMethod method =
+          skia::ImageOperations::RESIZE_GOOD;
+      scaled_bitmap = skia::ImageOperations::Resize(*bitmap.get(), method,
+                                                    region_in_frame.width(),
+                                                    region_in_frame.height());
+    } else {
+      scaled_bitmap = *bitmap.get();
+    }
+
+    {
+      SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap);
+
+      media::CopyRGBToVideoFrame(
+          reinterpret_cast<uint8*>(scaled_bitmap.getPixels()),
+          scaled_bitmap.rowBytes(),
+          region_in_frame,
+          video_frame.get());
+    }
+    ignore_result(scoped_callback_runner.Release());
+    callback.Run(true);
+    return;
+  }
+
+  ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+  GLHelper* gl_helper = factory->GetGLHelper();
+  if (!gl_helper)
+    return;
+  if (subscriber_texture.get() && !subscriber_texture->texture_id())
+    return;
+
+  cc::TextureMailbox texture_mailbox;
+  scoped_ptr<cc::SingleReleaseCallback> release_callback;
+  result->TakeTexture(&texture_mailbox, &release_callback);
+  DCHECK(texture_mailbox.IsTexture());
+  if (!texture_mailbox.IsTexture())
+    return;
+
+  gfx::Rect result_rect(result->size());
+
+  content::ReadbackYUVInterface* yuv_readback_pipeline =
+      dfh->yuv_readback_pipeline_.get();
+  if (yuv_readback_pipeline == NULL ||
+      yuv_readback_pipeline->scaler()->SrcSize() != result_rect.size() ||
+      yuv_readback_pipeline->scaler()->SrcSubrect() != result_rect ||
+      yuv_readback_pipeline->scaler()->DstSize() != region_in_frame.size()) {
+    GLHelper::ScalerQuality quality = GLHelper::SCALER_QUALITY_FAST;
+    std::string quality_switch = switches::kTabCaptureDownscaleQuality;
+    // If we're scaling up, we can use the "best" quality.
+    if (result_rect.size().width() < region_in_frame.size().width() &&
+        result_rect.size().height() < region_in_frame.size().height())
+      quality_switch = switches::kTabCaptureUpscaleQuality;
+
+    std::string switch_value =
+        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(quality_switch);
+    if (switch_value == "fast")
+      quality = GLHelper::SCALER_QUALITY_FAST;
+    else if (switch_value == "good")
+      quality = GLHelper::SCALER_QUALITY_GOOD;
+    else if (switch_value == "best")
+      quality = GLHelper::SCALER_QUALITY_BEST;
+
+    dfh->yuv_readback_pipeline_.reset(
+        gl_helper->CreateReadbackPipelineYUV(quality,
+                                             result_rect.size(),
+                                             result_rect,
+                                             video_frame->coded_size(),
+                                             region_in_frame,
+                                             true,
+                                             true));
+    yuv_readback_pipeline = dfh->yuv_readback_pipeline_.get();
+  }
+
+  ignore_result(scoped_callback_runner.Release());
+  ignore_result(scoped_return_subscriber_texture.Release());
+  base::Callback<void(bool result)> finished_callback = base::Bind(
+      &DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo,
+      dfh->AsWeakPtr(),
+      callback,
+      subscriber_texture,
+      base::Passed(&release_callback));
+  yuv_readback_pipeline->ReadbackYUV(texture_mailbox.mailbox(),
+                                     texture_mailbox.sync_point(),
+                                     video_frame.get(),
+                                     finished_callback);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DelegatedFrameHost, ui::CompositorObserver implementation:
+
+void DelegatedFrameHost::OnCompositingDidCommit(
+    ui::Compositor* compositor) {
+  RenderWidgetHostImpl* host = client_->GetHost();
+  if (can_lock_compositor_ == NO_PENDING_COMMIT) {
+    can_lock_compositor_ = YES;
+    if (resize_lock_.get() && resize_lock_->GrabDeferredLock())
+      can_lock_compositor_ = YES_DID_LOCK;
+  }
+  RunOnCommitCallbacks();
+  if (resize_lock_ &&
+      resize_lock_->expected_size() == current_frame_size_in_dip_) {
+    resize_lock_.reset();
+    host->WasResized();
+    // We may have had a resize while we had the lock (e.g. if the lock expired,
+    // or if the UI still gave us some resizes), so make sure we grab a new lock
+    // if necessary.
+    MaybeCreateResizeLock();
+  }
+}
+
+void DelegatedFrameHost::OnCompositingStarted(
+    ui::Compositor* compositor, base::TimeTicks start_time) {
+  last_draw_ended_ = start_time;
+}
+
+void DelegatedFrameHost::OnCompositingEnded(
+    ui::Compositor* compositor) {
+}
+
+void DelegatedFrameHost::OnCompositingAborted(
+    ui::Compositor* compositor) {
+}
+
+void DelegatedFrameHost::OnCompositingLockStateChanged(
+    ui::Compositor* compositor) {
+  // A compositor lock that is part of a resize lock timed out. We
+  // should display a renderer frame.
+  if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) {
+    can_lock_compositor_ = NO_PENDING_RENDERER_FRAME;
+  }
+}
+
+void DelegatedFrameHost::OnUpdateVSyncParameters(
+    base::TimeTicks timebase,
+    base::TimeDelta interval) {
+  RenderWidgetHostImpl* host = client_->GetHost();
+  if (client_->IsVisible())
+    host->UpdateVSyncParameters(timebase, interval);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation:
+
+void DelegatedFrameHost::OnLostResources() {
+  RenderWidgetHostImpl* host = client_->GetHost();
+  if (frame_provider_.get())
+    EvictDelegatedFrame();
+  idle_frame_subscriber_textures_.clear();
+  yuv_readback_pipeline_.reset();
+
+  host->ScheduleComposite();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DelegatedFrameHost, private:
+
+DelegatedFrameHost::~DelegatedFrameHost() {
+  ImageTransportFactory::GetInstance()->RemoveObserver(this);
+
+  if (resource_collection_.get())
+    resource_collection_->SetClient(NULL);
+
+  // An OwnedMailbox should not refer to the GLHelper anymore once the DFH is
+  // destroyed, as it may then outlive the GLHelper.
+  for (std::set<OwnedMailbox*>::iterator it =
+           active_frame_subscriber_textures_.begin();
+       it != active_frame_subscriber_textures_.end();
+       ++it) {
+    (*it)->Destroy();
+  }
+  active_frame_subscriber_textures_.clear();
+  DCHECK(!vsync_manager_);
+}
+
+void DelegatedFrameHost::RunOnCommitCallbacks() {
+  for (std::vector<base::Closure>::const_iterator
+      it = on_compositing_did_commit_callbacks_.begin();
+      it != on_compositing_did_commit_callbacks_.end(); ++it) {
+    it->Run();
+  }
+  on_compositing_did_commit_callbacks_.clear();
+}
+
+void DelegatedFrameHost::AddOnCommitCallbackAndDisableLocks(
+    const base::Closure& callback) {
+  ui::Compositor* compositor = client_->GetCompositor();
+  DCHECK(compositor);
+
+  if (!compositor->HasObserver(this))
+    compositor->AddObserver(this);
+
+  can_lock_compositor_ = NO_PENDING_COMMIT;
+  on_compositing_did_commit_callbacks_.push_back(callback);
+}
+
+void DelegatedFrameHost::AddedToWindow() {
+  ui::Compositor* compositor = client_->GetCompositor();
+  if (compositor) {
+    DCHECK(!vsync_manager_);
+    vsync_manager_ = compositor->vsync_manager();
+    vsync_manager_->AddObserver(this);
+  }
+}
+
+void DelegatedFrameHost::RemovingFromWindow() {
+  RunOnCommitCallbacks();
+  resize_lock_.reset();
+  client_->GetHost()->WasResized();
+  ui::Compositor* compositor = client_->GetCompositor();
+  if (compositor && compositor->HasObserver(this))
+    compositor->RemoveObserver(this);
+
+  if (vsync_manager_) {
+    vsync_manager_->RemoveObserver(this);
+    vsync_manager_ = NULL;
+  }
+}
+
+void DelegatedFrameHost::LockResources() {
+  DCHECK(frame_provider_);
+  delegated_frame_evictor_->LockFrame();
+}
+
+void DelegatedFrameHost::UnlockResources() {
+  DCHECK(frame_provider_);
+  delegated_frame_evictor_->UnlockFrame();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DelegatedFrameHost, ui::LayerOwnerDelegate implementation:
+
+void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer,
+                                                ui::Layer* new_layer) {
+  // The new_layer is the one that will be used by our Window, so that's the one
+  // that should keep our frame. old_layer will be returned to the
+  // RecreateLayer caller, and should have a copy.
+  if (frame_provider_.get()) {
+    new_layer->SetShowDelegatedContent(frame_provider_.get(),
+                                       current_frame_size_in_dip_);
+  }
+}
+
+}  // namespace content
+
diff --git a/content/browser/compositor/delegated_frame_host.h b/content/browser/compositor/delegated_frame_host.h
new file mode 100644
index 0000000..5b2588d
--- /dev/null
+++ b/content/browser/compositor/delegated_frame_host.h
@@ -0,0 +1,287 @@
+// 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.
+
+#ifndef CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_
+#define CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_
+
+#include "cc/layers/delegated_frame_provider.h"
+#include "cc/layers/delegated_frame_resource_collection.h"
+#include "cc/output/copy_output_result.h"
+#include "content/browser/compositor/image_transport_factory.h"
+#include "content/browser/compositor/owned_mailbox.h"
+#include "content/browser/renderer_host/delegated_frame_evictor.h"
+#include "content/browser/renderer_host/dip_util.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/common/gpu/client/gl_helper.h"
+#include "content/public/browser/render_process_host.h"
+#include "ui/compositor/compositor.h"
+#include "ui/compositor/compositor_observer.h"
+#include "ui/compositor/compositor_vsync_manager.h"
+#include "ui/compositor/layer.h"
+#include "ui/compositor/layer_owner_delegate.h"
+#include "ui/gfx/rect_conversions.h"
+
+namespace media {
+class VideoFrame;
+}
+
+namespace content {
+
+class DelegatedFrameHost;
+class RenderWidgetHostViewFrameSubscriber;
+class RenderWidgetHostImpl;
+class ResizeLock;
+
+// The DelegatedFrameHostClient is the interface from the DelegatedFrameHost,
+// which manages delegated frames, and the ui::Compositor being used to
+// display them.
+class CONTENT_EXPORT DelegatedFrameHostClient {
+ public:
+  virtual ui::Compositor* GetCompositor() const = 0;
+  virtual ui::Layer* GetLayer() = 0;
+  virtual RenderWidgetHostImpl* GetHost() = 0;
+  virtual void SchedulePaintInRect(const gfx::Rect& damage_rect_in_dip) = 0;
+  virtual bool IsVisible() = 0;
+  virtual scoped_ptr<ResizeLock> CreateResizeLock(
+      bool defer_compositor_lock) = 0;
+  virtual gfx::Size DesiredFrameSize() = 0;
+
+  // TODO(ccameron): It is likely that at least one of these two functions is
+  // redundant. Find which one, and delete it.
+  virtual float CurrentDeviceScaleFactor() = 0;
+  virtual gfx::Size ConvertViewSizeToPixel(const gfx::Size& size) = 0;
+
+  // These are to be overridden for testing only.
+  // TODO(ccameron): This is convoluted. Make the tests that need to override
+  // these functions test DelegatedFrameHost directly (rather than do it
+  // through RenderWidgetHostViewAura).
+  virtual DelegatedFrameHost* GetDelegatedFrameHost() const = 0;
+  virtual bool ShouldCreateResizeLock();
+  virtual void RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request);
+};
+
+// The DelegatedFrameHost is used to host all of the RenderWidgetHostView state
+// and functionality that is associated with delegated frames being sent from
+// the RenderWidget. The DelegatedFrameHost will push these changes through to
+// the ui::Compositor associated with its DelegatedFrameHostClient.
+class CONTENT_EXPORT DelegatedFrameHost
+    : public ui::CompositorObserver,
+      public ui::CompositorVSyncManager::Observer,
+      public ui::LayerOwnerDelegate,
+      public ImageTransportFactoryObserver,
+      public DelegatedFrameEvictorClient,
+      public cc::DelegatedFrameResourceCollectionClient,
+      public base::SupportsWeakPtr<DelegatedFrameHost> {
+ public:
+  DelegatedFrameHost(DelegatedFrameHostClient* client);
+  virtual ~DelegatedFrameHost();
+
+  gfx::Rect GetViewBoundsWithResizeLock(const gfx::Rect& bounds) const;
+  bool CanCopyToBitmap() const;
+
+  // Public interface exposed to RenderWidgetHostView.
+  void SwapDelegatedFrame(
+      uint32 output_surface_id,
+      scoped_ptr<cc::DelegatedFrameData> frame_data,
+      float frame_device_scale_factor,
+      const std::vector<ui::LatencyInfo>& latency_info);
+  void WasHidden();
+  void WasShown();
+  void WasResized();
+  void AddedToWindow();
+  void RemovingFromWindow();
+  void CopyFromCompositingSurface(
+      const gfx::Rect& src_subrect,
+      const gfx::Size& dst_size,
+      const base::Callback<void(bool, const SkBitmap&)>& callback,
+      const SkBitmap::Config config);
+  void CopyFromCompositingSurfaceToVideoFrame(
+      const gfx::Rect& src_subrect,
+      const scoped_refptr<media::VideoFrame>& target,
+      const base::Callback<void(bool)>& callback);
+  bool CanCopyToVideoFrame() const;
+  bool CanSubscribeFrame() const;
+  void BeginFrameSubscription(
+      scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber);
+  void EndFrameSubscription();
+
+  // Exposed for tests.
+  cc::DelegatedFrameProvider* FrameProviderForTesting() const {
+    return frame_provider_.get();
+  }
+  gfx::Size CurrentFrameSizeInDIPForTesting() const {
+    return current_frame_size_in_dip_;
+  }
+  void OnCompositingDidCommitForTesting(ui::Compositor* compositor) {
+    OnCompositingDidCommit(compositor);
+  }
+
+ private:
+  friend class DelegatedFrameHostClient;
+  FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
+                           SkippedDelegatedFrames);
+  FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
+                           DiscardDelegatedFramesWithLocking);
+  FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraCopyRequestTest,
+                           DestroyedAfterCopyRequest);
+
+  RenderWidgetHostViewFrameSubscriber* frame_subscriber() const {
+    return frame_subscriber_.get();
+  }
+  bool ShouldCreateResizeLock();
+  void RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request);
+
+  void LockResources();
+  void UnlockResources();
+
+  // Overridden from ui::CompositorObserver:
+  virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE;
+  virtual void OnCompositingStarted(ui::Compositor* compositor,
+                                    base::TimeTicks start_time) OVERRIDE;
+  virtual void OnCompositingEnded(ui::Compositor* compositor) OVERRIDE;
+  virtual void OnCompositingAborted(ui::Compositor* compositor) OVERRIDE;
+  virtual void OnCompositingLockStateChanged(
+      ui::Compositor* compositor) OVERRIDE;
+
+  // Overridden from ui::CompositorVSyncManager::Observer:
+  virtual void OnUpdateVSyncParameters(base::TimeTicks timebase,
+                                       base::TimeDelta interval) OVERRIDE;
+
+  // Overridden from ui::LayerOwnerObserver:
+  virtual void OnLayerRecreated(ui::Layer* old_layer,
+                                ui::Layer* new_layer) OVERRIDE;
+
+  // Overridden from ImageTransportFactoryObserver:
+  virtual void OnLostResources() OVERRIDE;
+
+  bool ShouldSkipFrame(gfx::Size size_in_dip) const;
+
+  // Lazily grab a resize lock if the aura window size doesn't match the current
+  // frame size, to give time to the renderer.
+  void MaybeCreateResizeLock();
+
+  // Checks if the resize lock can be released because we received an new frame.
+  void CheckResizeLock();
+
+  // Run all on compositing commit callbacks.
+  void RunOnCommitCallbacks();
+
+  // Add on compositing commit callback.
+  void AddOnCommitCallbackAndDisableLocks(const base::Closure& callback);
+
+  // Called after async thumbnailer task completes.  Scales and crops the result
+  // of the copy.
+  static void CopyFromCompositingSurfaceHasResult(
+      const gfx::Size& dst_size_in_pixel,
+      const SkBitmap::Config config,
+      const base::Callback<void(bool, const SkBitmap&)>& callback,
+      scoped_ptr<cc::CopyOutputResult> result);
+  static void PrepareTextureCopyOutputResult(
+      const gfx::Size& dst_size_in_pixel,
+      const SkBitmap::Config config,
+      const base::Callback<void(bool, const SkBitmap&)>& callback,
+      scoped_ptr<cc::CopyOutputResult> result);
+  static void PrepareBitmapCopyOutputResult(
+      const gfx::Size& dst_size_in_pixel,
+      const SkBitmap::Config config,
+      const base::Callback<void(bool, const SkBitmap&)>& callback,
+      scoped_ptr<cc::CopyOutputResult> result);
+  static void CopyFromCompositingSurfaceHasResultForVideo(
+      base::WeakPtr<DelegatedFrameHost> rwhva,
+      scoped_refptr<OwnedMailbox> subscriber_texture,
+      scoped_refptr<media::VideoFrame> video_frame,
+      const base::Callback<void(bool)>& callback,
+      scoped_ptr<cc::CopyOutputResult> result);
+  static void CopyFromCompositingSurfaceFinishedForVideo(
+      base::WeakPtr<DelegatedFrameHost> rwhva,
+      const base::Callback<void(bool)>& callback,
+      scoped_refptr<OwnedMailbox> subscriber_texture,
+      scoped_ptr<cc::SingleReleaseCallback> release_callback,
+      bool result);
+  static void ReturnSubscriberTexture(
+      base::WeakPtr<DelegatedFrameHost> rwhva,
+      scoped_refptr<OwnedMailbox> subscriber_texture,
+      uint32 sync_point);
+
+  void SendDelegatedFrameAck(uint32 output_surface_id);
+  void SendReturnedDelegatedResources(uint32 output_surface_id);
+
+  // DelegatedFrameEvictorClient implementation.
+  virtual void EvictDelegatedFrame() OVERRIDE;
+
+  // cc::DelegatedFrameProviderClient implementation.
+  virtual void UnusedResourcesAreAvailable() OVERRIDE;
+
+  void DidReceiveFrameFromRenderer();
+
+  DelegatedFrameHostClient* client_;
+
+  std::vector<base::Closure> on_compositing_did_commit_callbacks_;
+
+  // The vsync manager we are observing for changes, if any.
+  scoped_refptr<ui::CompositorVSyncManager> vsync_manager_;
+
+  // With delegated renderer, this is the last output surface, used to
+  // disambiguate resources with the same id coming from different output
+  // surfaces.
+  uint32 last_output_surface_id_;
+
+  // The number of delegated frame acks that are pending, to delay resource
+  // returns until the acks are sent.
+  int pending_delegated_ack_count_;
+
+  // True after a delegated frame has been skipped, until a frame is not
+  // skipped.
+  bool skipped_frames_;
+
+  // Holds delegated resources that have been given to a DelegatedFrameProvider,
+  // and gives back resources when they are no longer in use for return to the
+  // renderer.
+  scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection_;
+
+  // Provides delegated frame updates to the cc::DelegatedRendererLayer.
+  scoped_refptr<cc::DelegatedFrameProvider> frame_provider_;
+
+  // This lock is the one waiting for a frame of the right size to come back
+  // from the renderer/GPU process. It is set from the moment the aura window
+  // got resized, to the moment we committed the renderer frame of the same
+  // size. It keeps track of the size we expect from the renderer, and locks the
+  // compositor, as well as the UI for a short time to give a chance to the
+  // renderer of producing a frame of the right size.
+  scoped_ptr<ResizeLock> resize_lock_;
+
+  // Keeps track of the current frame size.
+  gfx::Size current_frame_size_in_dip_;
+
+  // This lock is for waiting for a front surface to become available to draw.
+  scoped_refptr<ui::CompositorLock> released_front_lock_;
+
+  enum CanLockCompositorState {
+    YES,
+    // We locked, so at some point we'll need to kick a frame.
+    YES_DID_LOCK,
+    // No. A lock timed out, we need to kick a new frame before locking again.
+    NO_PENDING_RENDERER_FRAME,
+    // No. We've got a frame, but it hasn't been committed.
+    NO_PENDING_COMMIT,
+  };
+  CanLockCompositorState can_lock_compositor_;
+
+  base::TimeTicks last_draw_ended_;
+
+  // Subscriber that listens to frame presentation events.
+  scoped_ptr<RenderWidgetHostViewFrameSubscriber> frame_subscriber_;
+  std::vector<scoped_refptr<OwnedMailbox> > idle_frame_subscriber_textures_;
+  std::set<OwnedMailbox*> active_frame_subscriber_textures_;
+
+  // YUV readback pipeline.
+  scoped_ptr<content::ReadbackYUVInterface>
+      yuv_readback_pipeline_;
+
+  scoped_ptr<DelegatedFrameEvictor> delegated_frame_evictor_;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index 46f1e84..16f600a 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -27,6 +27,7 @@
 #include "content/common/gpu/client/gpu_channel_host.h"
 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
 #include "content/common/gpu/gpu_process_launch_causes.h"
+#include "content/common/host_shared_bitmap_manager.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "gpu/command_buffer/common/mailbox.h"
@@ -217,8 +218,8 @@
 
 bool GpuProcessTransportFactory::DoesCreateTestContexts() { return false; }
 
-ui::ContextFactory* GpuProcessTransportFactory::AsContextFactory() {
-  return this;
+cc::SharedBitmapManager* GpuProcessTransportFactory::GetSharedBitmapManager() {
+  return HostSharedBitmapManager::current();
 }
 
 gfx::GLSurfaceHandle GpuProcessTransportFactory::GetSharedSurfaceHandle() {
diff --git a/content/browser/compositor/gpu_process_transport_factory.h b/content/browser/compositor/gpu_process_transport_factory.h
index 77964ae..0bd5c05 100644
--- a/content/browser/compositor/gpu_process_transport_factory.h
+++ b/content/browser/compositor/gpu_process_transport_factory.h
@@ -46,9 +46,9 @@
   virtual scoped_refptr<cc::ContextProvider>
       SharedMainThreadContextProvider() OVERRIDE;
   virtual bool DoesCreateTestContexts() OVERRIDE;
+  virtual cc::SharedBitmapManager* GetSharedBitmapManager() OVERRIDE;
 
   // ImageTransportFactory implementation.
-  virtual ui::ContextFactory* AsContextFactory() OVERRIDE;
   virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() OVERRIDE;
   virtual GLHelper* GetGLHelper() OVERRIDE;
   virtual void AddObserver(ImageTransportFactoryObserver* observer) OVERRIDE;
diff --git a/content/browser/compositor/image_transport_factory.cc b/content/browser/compositor/image_transport_factory.cc
index 7f15151..aa6e532 100644
--- a/content/browser/compositor/image_transport_factory.cc
+++ b/content/browser/compositor/image_transport_factory.cc
@@ -7,7 +7,6 @@
 #include "base/command_line.h"
 #include "content/browser/compositor/gpu_process_transport_factory.h"
 #include "content/browser/compositor/no_transport_image_transport_factory.h"
-#include "content/common/host_shared_bitmap_manager.h"
 #include "ui/compositor/compositor.h"
 #include "ui/compositor/compositor_switches.h"
 #include "ui/gl/gl_implementation.h"
@@ -25,9 +24,9 @@
   DCHECK(!g_factory || g_initialized_for_unit_tests);
   if (g_initialized_for_unit_tests)
     return;
-  g_factory = new GpuProcessTransportFactory;
-  ui::ContextFactory::SetInstance(g_factory->AsContextFactory());
-  ui::Compositor::SetSharedBitmapManager(HostSharedBitmapManager::current());
+  GpuProcessTransportFactory* factory = new GpuProcessTransportFactory;
+  g_factory = factory;
+  ui::ContextFactory::SetInstance(factory);
 }
 
 void ImageTransportFactory::InitializeForUnitTests(
@@ -40,9 +39,10 @@
   if (command_line->HasSwitch(switches::kEnablePixelOutputInTests))
     g_disable_null_draw = new gfx::DisableNullDrawGLBindings;
 
-  g_factory = new NoTransportImageTransportFactory(test_factory.Pass());
-  ui::ContextFactory::SetInstance(g_factory->AsContextFactory());
-  ui::Compositor::SetSharedBitmapManager(HostSharedBitmapManager::current());
+  NoTransportImageTransportFactory* factory =
+      new NoTransportImageTransportFactory(test_factory.Pass());
+  g_factory = factory;
+  ui::ContextFactory::SetInstance(factory->context_factory());
 }
 
 // static
diff --git a/content/browser/compositor/image_transport_factory.h b/content/browser/compositor/image_transport_factory.h
index 1c6912f..5910461 100644
--- a/content/browser/compositor/image_transport_factory.h
+++ b/content/browser/compositor/image_transport_factory.h
@@ -64,9 +64,6 @@
   // Gets the factory instance.
   static ImageTransportFactory* GetInstance();
 
-  // Gets the image transport factory as a context factory for the compositor.
-  virtual ui::ContextFactory* AsContextFactory() = 0;
-
   virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() = 0;
 
   // Gets a GLHelper instance, associated with the shared context. This
diff --git a/content/browser/compositor/no_transport_image_transport_factory.cc b/content/browser/compositor/no_transport_image_transport_factory.cc
index d1c5951..db0a5ab 100644
--- a/content/browser/compositor/no_transport_image_transport_factory.cc
+++ b/content/browser/compositor/no_transport_image_transport_factory.cc
@@ -17,10 +17,6 @@
 
 NoTransportImageTransportFactory::~NoTransportImageTransportFactory() {}
 
-ui::ContextFactory* NoTransportImageTransportFactory::AsContextFactory() {
-  return context_factory_.get();
-}
-
 gfx::GLSurfaceHandle
 NoTransportImageTransportFactory::GetSharedSurfaceHandle() {
   return gfx::GLSurfaceHandle();
diff --git a/content/browser/compositor/no_transport_image_transport_factory.h b/content/browser/compositor/no_transport_image_transport_factory.h
index a0f6216..51ae292 100644
--- a/content/browser/compositor/no_transport_image_transport_factory.h
+++ b/content/browser/compositor/no_transport_image_transport_factory.h
@@ -22,12 +22,13 @@
   virtual ~NoTransportImageTransportFactory();
 
   // ImageTransportFactory implementation.
-  virtual ui::ContextFactory* AsContextFactory() OVERRIDE;
   virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() OVERRIDE;
   virtual GLHelper* GetGLHelper() OVERRIDE;
   virtual void AddObserver(ImageTransportFactoryObserver* observer) OVERRIDE;
   virtual void RemoveObserver(ImageTransportFactoryObserver* observer) OVERRIDE;
 
+  ui::ContextFactory* context_factory() { return context_factory_.get(); }
+
  private:
   scoped_ptr<ui::ContextFactory> context_factory_;
   scoped_refptr<cc::ContextProvider> context_provider_;
diff --git a/content/browser/compositor/software_output_device_x11.cc b/content/browser/compositor/software_output_device_x11.cc
index 016b4915..44267d4 100644
--- a/content/browser/compositor/software_output_device_x11.cc
+++ b/content/browser/compositor/software_output_device_x11.cc
@@ -10,6 +10,8 @@
 #include "content/public/browser/browser_thread.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkDevice.h"
+#include "ui/base/x/x11_util.h"
+#include "ui/base/x/x11_util_internal.h"
 #include "ui/compositor/compositor.h"
 #include "ui/gfx/x/x11_types.h"
 
@@ -49,6 +51,70 @@
   if (rect.IsEmpty())
     return;
 
+  int bpp = gfx::BitsPerPixelForPixmapDepth(display_, attributes_.depth);
+
+  if (bpp != 32 && bpp != 16 && ui::QueryRenderSupport(display_)) {
+    // gfx::PutARGBImage only supports 16 and 32 bpp, but Xrender can do other
+    // conversions.
+    Pixmap pixmap = XCreatePixmap(
+        display_, compositor_->widget(), rect.width(), rect.height(), 32);
+    GC gc = XCreateGC(display_, pixmap, 0, NULL);
+    XImage image;
+    memset(&image, 0, sizeof(image));
+
+    SkImageInfo info;
+    size_t rowBytes;
+    const void* addr = canvas_->peekPixels(&info, &rowBytes);
+    image.width = viewport_size_.width();
+    image.height = viewport_size_.height();
+    image.depth = 32;
+    image.bits_per_pixel = 32;
+    image.format = ZPixmap;
+    image.byte_order = LSBFirst;
+    image.bitmap_unit = 8;
+    image.bitmap_bit_order = LSBFirst;
+    image.bytes_per_line = rowBytes;
+    image.red_mask = 0xff;
+    image.green_mask = 0xff00;
+    image.blue_mask = 0xff0000;
+    image.data = const_cast<char*>(static_cast<const char*>(addr));
+
+    XPutImage(display_,
+              pixmap,
+              gc,
+              &image,
+              rect.x(),
+              rect.y() /* source x, y */,
+              0,
+              0 /* dest x, y */,
+              rect.width(),
+              rect.height());
+    XFreeGC(display_, gc);
+    Picture picture = XRenderCreatePicture(
+        display_, pixmap, ui::GetRenderARGB32Format(display_), 0, NULL);
+    XRenderPictFormat* pictformat =
+        XRenderFindVisualFormat(display_, attributes_.visual);
+    Picture dest_picture = XRenderCreatePicture(
+        display_, compositor_->widget(), pictformat, 0, NULL);
+    XRenderComposite(display_,
+                     PictOpSrc,       // op
+                     picture,         // src
+                     0,               // mask
+                     dest_picture,    // dest
+                     0,               // src_x
+                     0,               // src_y
+                     0,               // mask_x
+                     0,               // mask_y
+                     rect.x(),        // dest_x
+                     rect.y(),        // dest_y
+                     rect.width(),    // width
+                     rect.height());  // height
+    XRenderFreePicture(display_, picture);
+    XRenderFreePicture(display_, dest_picture);
+    XFreePixmap(display_, pixmap);
+    return;
+  }
+
   // TODO(jbauman): Switch to XShmPutImage since it's async.
   SkImageInfo info;
   size_t rowBytes;
diff --git a/content/browser/devtools/devtools_http_handler_impl.cc b/content/browser/devtools/devtools_http_handler_impl.cc
index 35620d4..90f5ceb 100644
--- a/content/browser/devtools/devtools_http_handler_impl.cc
+++ b/content/browser/devtools/devtools_http_handler_impl.cc
@@ -259,7 +259,7 @@
     DevToolsTarget* target = GetTarget(target_id);
     GURL page_url;
     if (target)
-      page_url = target->GetUrl();
+      page_url = target->GetURL();
     BrowserThread::PostTask(
         BrowserThread::UI,
         FROM_HERE,
@@ -753,10 +753,10 @@
                         net::EscapeForHTML(target.GetTitle()));
   dictionary->SetString(kTargetDescriptionField, target.GetDescription());
 
-  GURL url = target.GetUrl();
+  GURL url = target.GetURL();
   dictionary->SetString(kTargetUrlField, url.spec());
 
-  GURL favicon_url = target.GetFaviconUrl();
+  GURL favicon_url = target.GetFaviconURL();
   if (favicon_url.is_valid())
     dictionary->SetString(kTargetFaviconUrlField, favicon_url.spec());
 
diff --git a/content/browser/devtools/devtools_resources.target.darwin-arm.mk b/content/browser/devtools/devtools_resources.target.darwin-arm.mk
index 4006bac..6e11300 100644
--- a/content/browser/devtools/devtools_resources.target.darwin-arm.mk
+++ b/content/browser/devtools/devtools_resources.target.darwin-arm.mk
@@ -17,6 +17,7 @@
 
 ### Rules for action "devtools_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "devtools_protocol_constants":
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/devtools/devtools_resources.target.darwin-arm64.mk b/content/browser/devtools/devtools_resources.target.darwin-arm64.mk
index 4006bac..6e11300 100644
--- a/content/browser/devtools/devtools_resources.target.darwin-arm64.mk
+++ b/content/browser/devtools/devtools_resources.target.darwin-arm64.mk
@@ -17,6 +17,7 @@
 
 ### Rules for action "devtools_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "devtools_protocol_constants":
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/devtools/devtools_resources.target.darwin-mips.mk b/content/browser/devtools/devtools_resources.target.darwin-mips.mk
index 4006bac..6e11300 100644
--- a/content/browser/devtools/devtools_resources.target.darwin-mips.mk
+++ b/content/browser/devtools/devtools_resources.target.darwin-mips.mk
@@ -17,6 +17,7 @@
 
 ### Rules for action "devtools_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "devtools_protocol_constants":
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/devtools/devtools_resources.target.darwin-x86.mk b/content/browser/devtools/devtools_resources.target.darwin-x86.mk
index 4006bac..6e11300 100644
--- a/content/browser/devtools/devtools_resources.target.darwin-x86.mk
+++ b/content/browser/devtools/devtools_resources.target.darwin-x86.mk
@@ -17,6 +17,7 @@
 
 ### Rules for action "devtools_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "devtools_protocol_constants":
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/devtools/devtools_resources.target.darwin-x86_64.mk b/content/browser/devtools/devtools_resources.target.darwin-x86_64.mk
index 4006bac..6e11300 100644
--- a/content/browser/devtools/devtools_resources.target.darwin-x86_64.mk
+++ b/content/browser/devtools/devtools_resources.target.darwin-x86_64.mk
@@ -17,6 +17,7 @@
 
 ### Rules for action "devtools_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "devtools_protocol_constants":
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/devtools/devtools_resources.target.linux-arm.mk b/content/browser/devtools/devtools_resources.target.linux-arm.mk
index 4006bac..6e11300 100644
--- a/content/browser/devtools/devtools_resources.target.linux-arm.mk
+++ b/content/browser/devtools/devtools_resources.target.linux-arm.mk
@@ -17,6 +17,7 @@
 
 ### Rules for action "devtools_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "devtools_protocol_constants":
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/devtools/devtools_resources.target.linux-arm64.mk b/content/browser/devtools/devtools_resources.target.linux-arm64.mk
index 4006bac..6e11300 100644
--- a/content/browser/devtools/devtools_resources.target.linux-arm64.mk
+++ b/content/browser/devtools/devtools_resources.target.linux-arm64.mk
@@ -17,6 +17,7 @@
 
 ### Rules for action "devtools_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "devtools_protocol_constants":
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/devtools/devtools_resources.target.linux-mips.mk b/content/browser/devtools/devtools_resources.target.linux-mips.mk
index 4006bac..6e11300 100644
--- a/content/browser/devtools/devtools_resources.target.linux-mips.mk
+++ b/content/browser/devtools/devtools_resources.target.linux-mips.mk
@@ -17,6 +17,7 @@
 
 ### Rules for action "devtools_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "devtools_protocol_constants":
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/devtools/devtools_resources.target.linux-x86.mk b/content/browser/devtools/devtools_resources.target.linux-x86.mk
index 4006bac..6e11300 100644
--- a/content/browser/devtools/devtools_resources.target.linux-x86.mk
+++ b/content/browser/devtools/devtools_resources.target.linux-x86.mk
@@ -17,6 +17,7 @@
 
 ### Rules for action "devtools_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "devtools_protocol_constants":
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/devtools/devtools_resources.target.linux-x86_64.mk b/content/browser/devtools/devtools_resources.target.linux-x86_64.mk
index 4006bac..6e11300 100644
--- a/content/browser/devtools/devtools_resources.target.linux-x86_64.mk
+++ b/content/browser/devtools/devtools_resources.target.linux-x86_64.mk
@@ -17,6 +17,7 @@
 
 ### Rules for action "devtools_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/devtools_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "devtools_protocol_constants":
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/browser/devtools/devtools_protocol_constants.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/devtools/embedded_worker_devtools_manager.cc b/content/browser/devtools/embedded_worker_devtools_manager.cc
new file mode 100644
index 0000000..fb58355
--- /dev/null
+++ b/content/browser/devtools/embedded_worker_devtools_manager.cc
@@ -0,0 +1,339 @@
+// 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.
+
+#include "content/browser/devtools/embedded_worker_devtools_manager.h"
+
+#include "content/browser/devtools/devtools_manager_impl.h"
+#include "content/browser/devtools/devtools_protocol.h"
+#include "content/browser/devtools/devtools_protocol_constants.h"
+#include "content/browser/devtools/ipc_devtools_agent_host.h"
+#include "content/browser/shared_worker/shared_worker_instance.h"
+#include "content/common/devtools_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/worker_service.h"
+#include "ipc/ipc_listener.h"
+
+namespace content {
+
+namespace {
+
+bool SendMessageToWorker(
+    const EmbeddedWorkerDevToolsManager::WorkerId& worker_id,
+    IPC::Message* message) {
+  RenderProcessHost* host = RenderProcessHost::FromID(worker_id.first);
+  if (!host) {
+    delete message;
+    return false;
+  }
+  message->set_routing_id(worker_id.second);
+  host->Send(message);
+  return true;
+}
+
+}  // namespace
+
+EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo(
+    const SharedWorkerInstance& instance)
+    : shared_worker_instance_(new SharedWorkerInstance(instance)),
+      state_(WORKER_UNINSPECTED),
+      agent_host_(NULL) {
+}
+
+EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo(
+    const base::FilePath& storage_partition_path,
+    const GURL& service_worker_scope)
+    : storage_partition_path_(new base::FilePath(storage_partition_path)),
+      service_worker_scope_(new GURL(service_worker_scope)),
+      state_(WORKER_UNINSPECTED),
+      agent_host_(NULL) {
+}
+
+bool EmbeddedWorkerDevToolsManager::WorkerInfo::Matches(
+    const SharedWorkerInstance& other) {
+  if (!shared_worker_instance_)
+    return false;
+  return shared_worker_instance_->Matches(other);
+}
+
+bool EmbeddedWorkerDevToolsManager::WorkerInfo::Matches(
+    const base::FilePath& other_storage_partition_path,
+    const GURL& other_service_worker_scope) {
+  if (!storage_partition_path_ || !service_worker_scope_)
+    return false;
+  return *storage_partition_path_ == other_storage_partition_path &&
+         *service_worker_scope_ == other_service_worker_scope;
+}
+
+EmbeddedWorkerDevToolsManager::WorkerInfo::~WorkerInfo() {
+}
+
+class EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsAgentHost
+    : public IPCDevToolsAgentHost,
+      public IPC::Listener {
+ public:
+  explicit EmbeddedWorkerDevToolsAgentHost(WorkerId worker_id)
+      : worker_id_(worker_id), worker_attached_(true) {
+    AddRef();
+    if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
+      host->AddRoute(worker_id_.second, this);
+  }
+
+  // IPCDevToolsAgentHost implementation.
+  virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
+    if (worker_attached_)
+      SendMessageToWorker(worker_id_, message);
+    else
+      delete message;
+  }
+  virtual void OnClientAttached() OVERRIDE {}
+  virtual void OnClientDetached() OVERRIDE {}
+
+  // IPC::Listener implementation.
+  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
+    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+    bool handled = true;
+    IPC_BEGIN_MESSAGE_MAP(EmbeddedWorkerDevToolsAgentHost, msg)
+    IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
+                        OnDispatchOnInspectorFrontend)
+    IPC_MESSAGE_HANDLER(DevToolsHostMsg_SaveAgentRuntimeState,
+                        OnSaveAgentRuntimeState)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+    IPC_END_MESSAGE_MAP()
+    return handled;
+  }
+
+  void ReattachToWorker(WorkerId worker_id) {
+    CHECK(!worker_attached_);
+    worker_attached_ = true;
+    worker_id_ = worker_id;
+    AddRef();
+    if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
+      host->AddRoute(worker_id_.second, this);
+    Reattach(state_);
+  }
+
+  void DetachFromWorker() {
+    CHECK(worker_attached_);
+    worker_attached_ = false;
+    if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
+      host->RemoveRoute(worker_id_.second);
+    Release();
+  }
+
+  WorkerId worker_id() const { return worker_id_; }
+
+ private:
+  virtual ~EmbeddedWorkerDevToolsAgentHost() {
+    CHECK(!worker_attached_);
+    EmbeddedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(
+        this);
+  }
+
+  void OnDispatchOnInspectorFrontend(const std::string& message) {
+    DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(this,
+                                                                    message);
+  }
+
+  void OnSaveAgentRuntimeState(const std::string& state) { state_ = state; }
+
+  WorkerId worker_id_;
+  bool worker_attached_;
+  std::string state_;
+  DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsAgentHost);
+};
+
+// static
+EmbeddedWorkerDevToolsManager* EmbeddedWorkerDevToolsManager::GetInstance() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  return Singleton<EmbeddedWorkerDevToolsManager>::get();
+}
+
+DevToolsAgentHost* EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForWorker(
+    int worker_process_id,
+    int worker_route_id) {
+  WorkerId id(worker_process_id, worker_route_id);
+
+  WorkerInfoMap::iterator it = workers_.find(id);
+  if (it == workers_.end())
+    return NULL;
+
+  WorkerInfo* info = it->second;
+  if (info->state() != WORKER_UNINSPECTED)
+    return info->agent_host();
+
+  EmbeddedWorkerDevToolsAgentHost* agent_host =
+      new EmbeddedWorkerDevToolsAgentHost(id);
+  info->set_agent_host(agent_host);
+  info->set_state(WORKER_INSPECTED);
+  return agent_host;
+}
+
+DevToolsAgentHost*
+EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForServiceWorker(
+    const base::FilePath& storage_partition_path,
+    const GURL& service_worker_scope) {
+  WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(
+      storage_partition_path, service_worker_scope);
+  if (it == workers_.end())
+    return NULL;
+  return GetDevToolsAgentHostForWorker(it->first.first, it->first.second);
+}
+
+EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager() {
+}
+
+EmbeddedWorkerDevToolsManager::~EmbeddedWorkerDevToolsManager() {
+}
+
+bool EmbeddedWorkerDevToolsManager::SharedWorkerCreated(
+    int worker_process_id,
+    int worker_route_id,
+    const SharedWorkerInstance& instance) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  const WorkerId id(worker_process_id, worker_route_id);
+  WorkerInfoMap::iterator it = FindExistingSharedWorkerInfo(instance);
+  if (it == workers_.end()) {
+    scoped_ptr<WorkerInfo> info(new WorkerInfo(instance));
+    workers_.set(id, info.Pass());
+    return false;
+  }
+  MoveToPausedState(id, it);
+  return true;
+}
+
+bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated(
+    int worker_process_id,
+    int worker_route_id,
+    const base::FilePath& storage_partition_path,
+    const GURL& service_worker_scope) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  const WorkerId id(worker_process_id, worker_route_id);
+  WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(
+      storage_partition_path, service_worker_scope);
+  if (it == workers_.end()) {
+    scoped_ptr<WorkerInfo> info(
+        new WorkerInfo(storage_partition_path, service_worker_scope));
+    workers_.set(id, info.Pass());
+    return false;
+  }
+  MoveToPausedState(id, it);
+  return true;
+}
+
+void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
+                                                    int worker_route_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  const WorkerId id(worker_process_id, worker_route_id);
+  WorkerInfoMap::iterator it = workers_.find(id);
+  DCHECK(it != workers_.end());
+  WorkerInfo* info = it->second;
+  switch (info->state()) {
+    case WORKER_UNINSPECTED:
+      workers_.erase(it);
+      break;
+    case WORKER_INSPECTED: {
+      EmbeddedWorkerDevToolsAgentHost* agent_host = info->agent_host();
+      if (!agent_host->IsAttached()) {
+        scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it);
+        agent_host->DetachFromWorker();
+        return;
+      }
+      info->set_state(WORKER_TERMINATED);
+      // Client host is debugging this worker agent host.
+      std::string notification =
+          DevToolsProtocol::CreateNotification(
+              devtools::Worker::disconnectedFromWorker::kName, NULL)
+              ->Serialize();
+      DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
+          agent_host, notification);
+      agent_host->DetachFromWorker();
+      break;
+    }
+    case WORKER_TERMINATED:
+      NOTREACHED();
+      break;
+    case WORKER_PAUSED: {
+      scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it);
+      worker_info->set_state(WORKER_TERMINATED);
+      const WorkerId old_id = worker_info->agent_host()->worker_id();
+      workers_.set(old_id, worker_info.Pass());
+      break;
+    }
+  }
+}
+
+void EmbeddedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id,
+                                                         int worker_route_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  const WorkerId id(worker_process_id, worker_route_id);
+  WorkerInfoMap::iterator it = workers_.find(id);
+  DCHECK(it != workers_.end());
+  WorkerInfo* info = it->second;
+  if (info->state() != WORKER_PAUSED)
+    return;
+  info->agent_host()->ReattachToWorker(id);
+  info->set_state(WORKER_INSPECTED);
+}
+
+void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData(
+    EmbeddedWorkerDevToolsAgentHost* agent_host) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  const WorkerId id(agent_host->worker_id());
+  scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(id);
+  if (worker_info) {
+    DCHECK_EQ(WORKER_TERMINATED, worker_info->state());
+    return;
+  }
+  for (WorkerInfoMap::iterator it = workers_.begin(); it != workers_.end();
+       ++it) {
+    if (it->second->agent_host() == agent_host) {
+      DCHECK_EQ(WORKER_PAUSED, it->second->state());
+      SendMessageToWorker(
+          it->first,
+          new DevToolsAgentMsg_ResumeWorkerContext(it->first.second));
+      it->second->set_agent_host(NULL);
+      it->second->set_state(WORKER_UNINSPECTED);
+      return;
+    }
+  }
+}
+
+EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator
+EmbeddedWorkerDevToolsManager::FindExistingSharedWorkerInfo(
+    const SharedWorkerInstance& instance) {
+  WorkerInfoMap::iterator it = workers_.begin();
+  for (; it != workers_.end(); ++it) {
+    if (it->second->Matches(instance))
+      break;
+  }
+  return it;
+}
+
+EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator
+EmbeddedWorkerDevToolsManager::FindExistingServiceWorkerInfo(
+    const base::FilePath& storage_partition_path,
+    const GURL& service_worker_scope) {
+  WorkerInfoMap::iterator it = workers_.begin();
+  for (; it != workers_.end(); ++it) {
+    if (it->second->Matches(storage_partition_path, service_worker_scope))
+      break;
+  }
+  return it;
+}
+
+void EmbeddedWorkerDevToolsManager::MoveToPausedState(
+    const WorkerId& id,
+    const WorkerInfoMap::iterator& it) {
+  DCHECK_EQ(WORKER_TERMINATED, it->second->state());
+  scoped_ptr<WorkerInfo> info = workers_.take_and_erase(it);
+  info->set_state(WORKER_PAUSED);
+  workers_.set(id, info.Pass());
+}
+
+void EmbeddedWorkerDevToolsManager::ResetForTesting() {
+  workers_.clear();
+}
+
+}  // namespace content
diff --git a/content/browser/devtools/embedded_worker_devtools_manager.h b/content/browser/devtools/embedded_worker_devtools_manager.h
new file mode 100644
index 0000000..ea07574
--- /dev/null
+++ b/content/browser/devtools/embedded_worker_devtools_manager.h
@@ -0,0 +1,120 @@
+// 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.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_MANAGER_H_
+#define CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/files/file_path.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_vector.h"
+#include "base/memory/singleton.h"
+#include "base/strings/string16.h"
+#include "content/browser/shared_worker/shared_worker_instance.h"
+#include "content/common/content_export.h"
+
+class GURL;
+
+namespace content {
+class DevToolsAgentHost;
+
+// EmbeddedWorkerDevToolsManager is used instead of WorkerDevToolsManager when
+// "enable-embedded-shared-worker" flag is set.
+// This class lives on UI thread.
+class CONTENT_EXPORT EmbeddedWorkerDevToolsManager {
+ public:
+  typedef std::pair<int, int> WorkerId;
+  class EmbeddedWorkerDevToolsAgentHost;
+
+  // Returns the EmbeddedWorkerDevToolsManager singleton.
+  static EmbeddedWorkerDevToolsManager* GetInstance();
+
+  DevToolsAgentHost* GetDevToolsAgentHostForWorker(int worker_process_id,
+                                                   int worker_route_id);
+  DevToolsAgentHost* GetDevToolsAgentHostForServiceWorker(
+      const base::FilePath& storage_partition_path,
+      const GURL& service_worker_scope);
+
+  // Returns true when the worker must be paused on start.
+  bool SharedWorkerCreated(int worker_process_id,
+                           int worker_route_id,
+                           const SharedWorkerInstance& instance);
+  // Returns true when the worker must be paused on start.
+  // TODO(horo): Currently we identify ServiceWorkers with the path of storage
+  // partition and the scope of ServiceWorker. Consider having a class like
+  // SharedWorkerInstance instead of the pair.
+  bool ServiceWorkerCreated(int worker_process_id,
+                            int worker_route_id,
+                            const base::FilePath& storage_partition_path,
+                            const GURL& service_worker_scope);
+  void WorkerContextStarted(int worker_process_id, int worker_route_id);
+  void WorkerDestroyed(int worker_process_id, int worker_route_id);
+
+ private:
+  friend struct DefaultSingletonTraits<EmbeddedWorkerDevToolsManager>;
+  friend class EmbeddedWorkerDevToolsManagerTest;
+  FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerDevToolsManagerTest, BasicTest);
+  FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerDevToolsManagerTest, AttachTest);
+
+  enum WorkerState {
+    WORKER_UNINSPECTED,
+    WORKER_INSPECTED,
+    WORKER_TERMINATED,
+    WORKER_PAUSED,
+  };
+
+  class WorkerInfo {
+   public:
+    // Creates WorkerInfo for SharedWorker.
+    explicit WorkerInfo(const SharedWorkerInstance& instance);
+    // Creates WorkerInfo for ServiceWorker.
+    WorkerInfo(const base::FilePath& storage_partition_path,
+               const GURL& service_worker_scope);
+    ~WorkerInfo();
+
+    WorkerState state() { return state_; }
+    void set_state(WorkerState new_state) { state_ = new_state; }
+    EmbeddedWorkerDevToolsAgentHost* agent_host() { return agent_host_; }
+    void set_agent_host(EmbeddedWorkerDevToolsAgentHost* agent_host) {
+      agent_host_ = agent_host;
+    }
+    bool Matches(const SharedWorkerInstance& other);
+    bool Matches(const base::FilePath& other_storage_partition_path,
+                 const GURL& other_service_worker_scope);
+
+   private:
+    scoped_ptr<SharedWorkerInstance> shared_worker_instance_;
+    scoped_ptr<base::FilePath> storage_partition_path_;
+    scoped_ptr<GURL> service_worker_scope_;
+    WorkerState state_;
+    EmbeddedWorkerDevToolsAgentHost* agent_host_;
+  };
+
+  typedef base::ScopedPtrHashMap<WorkerId, WorkerInfo> WorkerInfoMap;
+
+  EmbeddedWorkerDevToolsManager();
+  virtual ~EmbeddedWorkerDevToolsManager();
+
+  void RemoveInspectedWorkerData(EmbeddedWorkerDevToolsAgentHost* agent_host);
+
+  WorkerInfoMap::iterator FindExistingSharedWorkerInfo(
+      const SharedWorkerInstance& instance);
+  WorkerInfoMap::iterator FindExistingServiceWorkerInfo(
+      const base::FilePath& storage_partition_path,
+      const GURL& service_worker_scope);
+
+  void MoveToPausedState(const WorkerId& id, const WorkerInfoMap::iterator& it);
+
+  // Resets to its initial state as if newly created.
+  void ResetForTesting();
+
+  WorkerInfoMap workers_;
+
+  DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsManager);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_MANAGER_H_
diff --git a/content/browser/devtools/embedded_worker_devtools_manager_unittest.cc b/content/browser/devtools/embedded_worker_devtools_manager_unittest.cc
new file mode 100644
index 0000000..49a6144
--- /dev/null
+++ b/content/browser/devtools/embedded_worker_devtools_manager_unittest.cc
@@ -0,0 +1,265 @@
+// 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.
+
+#include "content/browser/devtools/embedded_worker_devtools_manager.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "content/browser/browser_thread_impl.h"
+#include "content/browser/devtools/devtools_manager_impl.h"
+#include "content/browser/shared_worker/shared_worker_instance.h"
+#include "content/browser/worker_host/worker_storage_partition.h"
+#include "content/public/browser/devtools_agent_host.h"
+#include "content/public/browser/devtools_client_host.h"
+#include "content/public/test/test_browser_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+class TestDevToolsClientHost : public DevToolsClientHost {
+ public:
+  TestDevToolsClientHost() {}
+  virtual ~TestDevToolsClientHost() {}
+  virtual void DispatchOnInspectorFrontend(
+      const std::string& message) OVERRIDE {}
+  virtual void InspectedContentsClosing() OVERRIDE {}
+  virtual void ReplacedWithAnotherClient() OVERRIDE {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestDevToolsClientHost);
+};
+}
+
+class EmbeddedWorkerDevToolsManagerTest : public testing::Test {
+ public:
+  EmbeddedWorkerDevToolsManagerTest()
+      : ui_thread_(BrowserThread::UI, &message_loop_),
+        browser_context_(new TestBrowserContext()),
+        partition_(
+            new WorkerStoragePartition(browser_context_->GetRequestContext(),
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       NULL)),
+        partition_id_(*partition_.get()) {}
+
+ protected:
+  virtual void SetUp() OVERRIDE {
+    manager_ = EmbeddedWorkerDevToolsManager::GetInstance();
+  }
+  virtual void TearDown() OVERRIDE {
+    EmbeddedWorkerDevToolsManager::GetInstance()->ResetForTesting();
+  }
+
+  void CheckWorkerState(int worker_process_id,
+                        int worker_route_id,
+                        EmbeddedWorkerDevToolsManager::WorkerState state) {
+    const EmbeddedWorkerDevToolsManager::WorkerId id(worker_process_id,
+                                                     worker_route_id);
+    EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator it =
+        manager_->workers_.find(id);
+    EXPECT_TRUE(manager_->workers_.end() != it);
+    EXPECT_EQ(state, it->second->state());
+  }
+
+  void CheckWorkerNotExist(int worker_process_id, int worker_route_id) {
+    const EmbeddedWorkerDevToolsManager::WorkerId id(worker_process_id,
+                                                     worker_route_id);
+    EXPECT_TRUE(manager_->workers_.end() == manager_->workers_.find(id));
+  }
+
+  void CheckWorkerCount(size_t size) {
+    EXPECT_EQ(size, manager_->workers_.size());
+  }
+
+  void RegisterDevToolsClientHostFor(DevToolsAgentHost* agent_host,
+                                     DevToolsClientHost* client_host) {
+    DevToolsManagerImpl::GetInstance()->RegisterDevToolsClientHostFor(
+        agent_host, client_host);
+  }
+
+  void ClientHostClosing(DevToolsClientHost* client_host) {
+    DevToolsManagerImpl::GetInstance()->ClientHostClosing(client_host);
+  }
+
+  base::MessageLoopForIO message_loop_;
+  BrowserThreadImpl ui_thread_;
+  scoped_ptr<TestBrowserContext> browser_context_;
+  scoped_ptr<WorkerStoragePartition> partition_;
+  const WorkerStoragePartitionId partition_id_;
+  EmbeddedWorkerDevToolsManager* manager_;
+};
+
+TEST_F(EmbeddedWorkerDevToolsManagerTest, BasicTest) {
+  scoped_refptr<DevToolsAgentHost> agent_host;
+
+  SharedWorkerInstance instance1(GURL("http://example.com/w.js"),
+                                 base::string16(),
+                                 base::string16(),
+                                 blink::WebContentSecurityPolicyTypeReport,
+                                 browser_context_->GetResourceContext(),
+                                 partition_id_);
+
+  agent_host = manager_->GetDevToolsAgentHostForWorker(1, 1);
+  EXPECT_FALSE(agent_host.get());
+
+  // Created -> Started -> Destroyed
+  CheckWorkerNotExist(1, 1);
+  manager_->SharedWorkerCreated(1, 1, instance1);
+  CheckWorkerState(1, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+  manager_->WorkerContextStarted(1, 1);
+  CheckWorkerState(1, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+  manager_->WorkerDestroyed(1, 1);
+  CheckWorkerNotExist(1, 1);
+
+  // Created -> GetDevToolsAgentHost -> Started -> Destroyed
+  CheckWorkerNotExist(1, 2);
+  manager_->SharedWorkerCreated(1, 2, instance1);
+  CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+  agent_host = manager_->GetDevToolsAgentHostForWorker(1, 2);
+  EXPECT_TRUE(agent_host.get());
+  CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+  EXPECT_EQ(agent_host.get(), manager_->GetDevToolsAgentHostForWorker(1, 2));
+  manager_->WorkerContextStarted(1, 2);
+  CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+  manager_->WorkerDestroyed(1, 2);
+  CheckWorkerNotExist(1, 2);
+  agent_host = NULL;
+
+  // Created -> Started -> GetDevToolsAgentHost -> Destroyed
+  CheckWorkerNotExist(1, 3);
+  manager_->SharedWorkerCreated(1, 3, instance1);
+  CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+  manager_->WorkerContextStarted(1, 3);
+  CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+  agent_host = manager_->GetDevToolsAgentHostForWorker(1, 3);
+  EXPECT_TRUE(agent_host.get());
+  CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+  manager_->WorkerDestroyed(1, 3);
+  CheckWorkerNotExist(1, 3);
+  agent_host = NULL;
+
+  // Created -> Destroyed
+  CheckWorkerNotExist(1, 4);
+  manager_->SharedWorkerCreated(1, 4, instance1);
+  CheckWorkerState(1, 4, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+  manager_->WorkerDestroyed(1, 4);
+  CheckWorkerNotExist(1, 4);
+
+  // Created -> GetDevToolsAgentHost -> Destroyed
+  CheckWorkerNotExist(1, 5);
+  manager_->SharedWorkerCreated(1, 5, instance1);
+  CheckWorkerState(1, 5, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+  agent_host = manager_->GetDevToolsAgentHostForWorker(1, 5);
+  EXPECT_TRUE(agent_host.get());
+  CheckWorkerState(1, 5, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+  manager_->WorkerDestroyed(1, 5);
+  CheckWorkerNotExist(1, 5);
+  agent_host = NULL;
+
+  // Created -> GetDevToolsAgentHost -> Free agent_host -> Destroyed
+  CheckWorkerNotExist(1, 6);
+  manager_->SharedWorkerCreated(1, 6, instance1);
+  CheckWorkerState(1, 6, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+  agent_host = manager_->GetDevToolsAgentHostForWorker(1, 6);
+  EXPECT_TRUE(agent_host.get());
+  CheckWorkerState(1, 6, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+  agent_host = NULL;
+  manager_->WorkerDestroyed(1, 6);
+  CheckWorkerNotExist(1, 6);
+}
+
+TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) {
+  scoped_refptr<DevToolsAgentHost> agent_host1;
+  scoped_refptr<DevToolsAgentHost> agent_host2;
+
+  SharedWorkerInstance instance1(GURL("http://example.com/w1.js"),
+                                 base::string16(),
+                                 base::string16(),
+                                 blink::WebContentSecurityPolicyTypeReport,
+                                 browser_context_->GetResourceContext(),
+                                 partition_id_);
+  SharedWorkerInstance instance2(GURL("http://example.com/w2.js"),
+                                 base::string16(),
+                                 base::string16(),
+                                 blink::WebContentSecurityPolicyTypeReport,
+                                 browser_context_->GetResourceContext(),
+                                 partition_id_);
+
+  // Created -> GetDevToolsAgentHost -> Register -> Started -> Destroyed
+  scoped_ptr<TestDevToolsClientHost> client_host1(new TestDevToolsClientHost());
+  CheckWorkerNotExist(2, 1);
+  manager_->SharedWorkerCreated(2, 1, instance1);
+  CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+  agent_host1 = manager_->GetDevToolsAgentHostForWorker(2, 1);
+  EXPECT_TRUE(agent_host1.get());
+  CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+  EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
+  RegisterDevToolsClientHostFor(agent_host1.get(), client_host1.get());
+  CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+  manager_->WorkerContextStarted(2, 1);
+  CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+  manager_->WorkerDestroyed(2, 1);
+  CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+  EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
+
+  // Created -> Started -> GetDevToolsAgentHost -> Register -> Destroyed
+  scoped_ptr<TestDevToolsClientHost> client_host2(new TestDevToolsClientHost());
+  manager_->SharedWorkerCreated(2, 2, instance2);
+  CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+  manager_->WorkerContextStarted(2, 2);
+  CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+  agent_host2 = manager_->GetDevToolsAgentHostForWorker(2, 2);
+  EXPECT_TRUE(agent_host2.get());
+  EXPECT_NE(agent_host1.get(), agent_host2.get());
+  EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
+  CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+  RegisterDevToolsClientHostFor(agent_host2.get(), client_host2.get());
+  CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+  manager_->WorkerDestroyed(2, 2);
+  CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+  EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
+
+  // Re-created -> Started -> ClientHostClosing -> Destroyed
+  CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+  manager_->SharedWorkerCreated(2, 3, instance1);
+  CheckWorkerNotExist(2, 1);
+  CheckWorkerState(2, 3, EmbeddedWorkerDevToolsManager::WORKER_PAUSED);
+  EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 3));
+  manager_->WorkerContextStarted(2, 3);
+  CheckWorkerState(2, 3, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+  ClientHostClosing(client_host1.get());
+  manager_->WorkerDestroyed(2, 3);
+  CheckWorkerNotExist(2, 3);
+  agent_host1 = NULL;
+
+  // Re-created -> Destroyed
+  CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+  manager_->SharedWorkerCreated(2, 4, instance2);
+  CheckWorkerNotExist(2, 2);
+  CheckWorkerState(2, 4, EmbeddedWorkerDevToolsManager::WORKER_PAUSED);
+  EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 4));
+  manager_->WorkerDestroyed(2, 4);
+  CheckWorkerNotExist(2, 4);
+  CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+
+  // Re-created -> ClientHostClosing -> Destroyed
+  manager_->SharedWorkerCreated(2, 5, instance2);
+  CheckWorkerNotExist(2, 2);
+  CheckWorkerState(2, 5, EmbeddedWorkerDevToolsManager::WORKER_PAUSED);
+  EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 5));
+  ClientHostClosing(client_host2.get());
+  CheckWorkerCount(1);
+  agent_host2 = NULL;
+  CheckWorkerCount(1);
+  manager_->WorkerDestroyed(2, 5);
+  CheckWorkerCount(0);
+}
+
+}  // namespace content
diff --git a/content/browser/devtools/renderer_overrides_handler.cc b/content/browser/devtools/renderer_overrides_handler.cc
index 4951557..1fd66da 100644
--- a/content/browser/devtools/renderer_overrides_handler.cc
+++ b/content/browser/devtools/renderer_overrides_handler.cc
@@ -21,8 +21,8 @@
 #include "content/browser/renderer_host/dip_util.h"
 #include "content/browser/renderer_host/render_view_host_delegate.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/devtools_agent_host.h"
@@ -204,14 +204,14 @@
   double scale = 1;
   ParseCaptureParameters(screencast_command_.get(), &format, &quality, &scale);
 
-  RenderWidgetHostViewPort* view_port =
-      RenderWidgetHostViewPort::FromRWHV(host->GetView());
+  RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
+      host->GetView());
 
   gfx::Rect view_bounds = host->GetView()->GetViewBounds();
   gfx::Size snapshot_size = gfx::ToFlooredSize(
       gfx::ScaleSize(view_bounds.size(), scale));
 
-  view_port->CopyFromCompositingSurface(
+  view->CopyFromCompositingSurface(
       view_bounds, snapshot_size,
       base::Bind(&RendererOverridesHandler::ScreencastFrameCaptured,
                  weak_factory_.GetWeakPtr(),
diff --git a/content/browser/devtools/shared_worker_devtools_manager.cc b/content/browser/devtools/shared_worker_devtools_manager.cc
deleted file mode 100644
index 0563773..0000000
--- a/content/browser/devtools/shared_worker_devtools_manager.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// 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.
-
-#include "content/browser/devtools/shared_worker_devtools_manager.h"
-
-#include "content/browser/devtools/devtools_manager_impl.h"
-#include "content/browser/devtools/devtools_protocol.h"
-#include "content/browser/devtools/devtools_protocol_constants.h"
-#include "content/browser/devtools/ipc_devtools_agent_host.h"
-#include "content/browser/shared_worker/shared_worker_instance.h"
-#include "content/common/devtools_messages.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/worker_service.h"
-#include "ipc/ipc_listener.h"
-
-namespace content {
-
-namespace {
-
-bool SendMessageToWorker(const SharedWorkerDevToolsManager::WorkerId& worker_id,
-                         IPC::Message* message) {
-  RenderProcessHost* host = RenderProcessHost::FromID(worker_id.first);
-  if (!host) {
-    delete message;
-    return false;
-  }
-  message->set_routing_id(worker_id.second);
-  host->Send(message);
-  return true;
-}
-
-}  // namespace
-
-class SharedWorkerDevToolsManager::SharedWorkerDevToolsAgentHost
-    : public IPCDevToolsAgentHost,
-      public IPC::Listener {
- public:
-  explicit SharedWorkerDevToolsAgentHost(WorkerId worker_id)
-      : worker_id_(worker_id), worker_attached_(true) {
-    AddRef();
-    if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
-      host->AddRoute(worker_id_.second, this);
-  }
-
-  // IPCDevToolsAgentHost implementation.
-  virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
-    if (worker_attached_)
-      SendMessageToWorker(worker_id_, message);
-    else
-      delete message;
-  }
-  virtual void OnClientAttached() OVERRIDE {}
-  virtual void OnClientDetached() OVERRIDE {}
-
-  // IPC::Listener implementation.
-  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
-    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-    bool handled = true;
-    IPC_BEGIN_MESSAGE_MAP(SharedWorkerDevToolsAgentHost, msg)
-    IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
-                        OnDispatchOnInspectorFrontend)
-    IPC_MESSAGE_HANDLER(DevToolsHostMsg_SaveAgentRuntimeState,
-                        OnSaveAgentRuntimeState)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-    IPC_END_MESSAGE_MAP()
-    return handled;
-  }
-
-  void ReattachToWorker(WorkerId worker_id) {
-    CHECK(!worker_attached_);
-    worker_attached_ = true;
-    worker_id_ = worker_id;
-    AddRef();
-    if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
-      host->AddRoute(worker_id_.second, this);
-    Reattach(state_);
-  }
-
-  void DetachFromWorker() {
-    CHECK(worker_attached_);
-    worker_attached_ = false;
-    if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
-      host->RemoveRoute(worker_id_.second);
-    Release();
-  }
-
-  WorkerId worker_id() const { return worker_id_; }
-
- private:
-  virtual ~SharedWorkerDevToolsAgentHost() {
-    CHECK(!worker_attached_);
-    SharedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(this);
-  }
-
-  void OnDispatchOnInspectorFrontend(const std::string& message) {
-    DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(this,
-                                                                    message);
-  }
-
-  void OnSaveAgentRuntimeState(const std::string& state) { state_ = state; }
-
-  WorkerId worker_id_;
-  bool worker_attached_;
-  std::string state_;
-  DISALLOW_COPY_AND_ASSIGN(SharedWorkerDevToolsAgentHost);
-};
-
-// static
-SharedWorkerDevToolsManager* SharedWorkerDevToolsManager::GetInstance() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  return Singleton<SharedWorkerDevToolsManager>::get();
-}
-
-DevToolsAgentHost* SharedWorkerDevToolsManager::GetDevToolsAgentHostForWorker(
-    int worker_process_id,
-    int worker_route_id) {
-  WorkerId id(worker_process_id, worker_route_id);
-
-  WorkerInfoMap::iterator it = workers_.find(id);
-  if (it == workers_.end())
-    return NULL;
-
-  WorkerInfo* info = it->second;
-  if (info->state() != WORKER_UNINSPECTED)
-    return info->agent_host();
-
-  SharedWorkerDevToolsAgentHost* agent_host =
-      new SharedWorkerDevToolsAgentHost(id);
-  info->set_agent_host(agent_host);
-  info->set_state(WORKER_INSPECTED);
-  return agent_host;
-}
-
-SharedWorkerDevToolsManager::SharedWorkerDevToolsManager() {}
-
-SharedWorkerDevToolsManager::~SharedWorkerDevToolsManager() {}
-
-bool SharedWorkerDevToolsManager::WorkerCreated(
-    int worker_process_id,
-    int worker_route_id,
-    const SharedWorkerInstance& instance) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  const WorkerId id(worker_process_id, worker_route_id);
-  WorkerInfoMap::iterator it = FindExistingWorkerInfo(instance);
-  if (it == workers_.end()) {
-    scoped_ptr<WorkerInfo> info(new WorkerInfo(instance));
-    workers_.set(id, info.Pass());
-    return false;
-  }
-  DCHECK_EQ(WORKER_TERMINATED, it->second->state());
-  scoped_ptr<WorkerInfo> info = workers_.take_and_erase(it);
-  info->set_state(WORKER_PAUSED);
-  workers_.set(id, info.Pass());
-  return true;
-}
-
-void SharedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
-                                                  int worker_route_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  const WorkerId id(worker_process_id, worker_route_id);
-  WorkerInfoMap::iterator it = workers_.find(id);
-  DCHECK(it != workers_.end());
-  WorkerInfo* info = it->second;
-  switch (info->state()) {
-    case WORKER_UNINSPECTED:
-      workers_.erase(it);
-      break;
-    case WORKER_INSPECTED: {
-      SharedWorkerDevToolsAgentHost* agent_host = info->agent_host();
-      if (!agent_host->IsAttached()) {
-        scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it);
-        agent_host->DetachFromWorker();
-        return;
-      }
-      info->set_state(WORKER_TERMINATED);
-      // Client host is debugging this worker agent host.
-      std::string notification =
-          DevToolsProtocol::CreateNotification(
-              devtools::Worker::disconnectedFromWorker::kName, NULL)
-              ->Serialize();
-      DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
-          agent_host, notification);
-      agent_host->DetachFromWorker();
-      break;
-    }
-    case WORKER_TERMINATED:
-      NOTREACHED();
-      break;
-    case WORKER_PAUSED: {
-      scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it);
-      worker_info->set_state(WORKER_TERMINATED);
-      const WorkerId old_id = worker_info->agent_host()->worker_id();
-      workers_.set(old_id, worker_info.Pass());
-      break;
-    }
-  }
-}
-
-void SharedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id,
-                                                       int worker_route_id) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  const WorkerId id(worker_process_id, worker_route_id);
-  WorkerInfoMap::iterator it = workers_.find(id);
-  DCHECK(it != workers_.end());
-  WorkerInfo* info = it->second;
-  if (info->state() != WORKER_PAUSED)
-    return;
-  info->agent_host()->ReattachToWorker(id);
-  info->set_state(WORKER_INSPECTED);
-}
-
-void SharedWorkerDevToolsManager::RemoveInspectedWorkerData(
-    SharedWorkerDevToolsAgentHost* agent_host) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  const WorkerId id(agent_host->worker_id());
-  scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(id);
-  if (worker_info) {
-    DCHECK_EQ(WORKER_TERMINATED, worker_info->state());
-    return;
-  }
-  for (WorkerInfoMap::iterator it = workers_.begin(); it != workers_.end();
-       ++it) {
-    if (it->second->agent_host() == agent_host) {
-      DCHECK_EQ(WORKER_PAUSED, it->second->state());
-      SendMessageToWorker(
-          it->first,
-          new DevToolsAgentMsg_ResumeWorkerContext(it->first.second));
-      it->second->set_agent_host(NULL);
-      it->second->set_state(WORKER_UNINSPECTED);
-      return;
-    }
-  }
-}
-
-SharedWorkerDevToolsManager::WorkerInfoMap::iterator
-SharedWorkerDevToolsManager::FindExistingWorkerInfo(
-    const SharedWorkerInstance& instance) {
-  WorkerInfoMap::iterator it = workers_.begin();
-  for (; it != workers_.end(); ++it) {
-    if (it->second->instance().Matches(instance))
-      break;
-  }
-  return it;
-}
-
-void SharedWorkerDevToolsManager::ResetForTesting() { workers_.clear(); }
-
-}  // namespace content
diff --git a/content/browser/devtools/shared_worker_devtools_manager.h b/content/browser/devtools/shared_worker_devtools_manager.h
deleted file mode 100644
index 4b23821..0000000
--- a/content/browser/devtools/shared_worker_devtools_manager.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// 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.
-
-#ifndef CONTENT_BROWSER_DEVTOOLS_SHARED_WORKER_DEVTOOLS_MANAGER_H_
-#define CONTENT_BROWSER_DEVTOOLS_SHARED_WORKER_DEVTOOLS_MANAGER_H_
-
-#include "base/basictypes.h"
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "base/gtest_prod_util.h"
-#include "base/memory/scoped_vector.h"
-#include "base/memory/singleton.h"
-#include "base/strings/string16.h"
-#include "content/browser/shared_worker/shared_worker_instance.h"
-#include "content/common/content_export.h"
-
-class GURL;
-
-namespace content {
-class DevToolsAgentHost;
-
-// SharedWorkerDevToolsManager is used instead of WorkerDevToolsManager when
-// "enable-embedded-shared-worker" flag is set.
-// This class lives on UI thread.
-class CONTENT_EXPORT SharedWorkerDevToolsManager {
- public:
-  typedef std::pair<int, int> WorkerId;
-  class SharedWorkerDevToolsAgentHost;
-
-  // Returns the SharedWorkerDevToolsManager singleton.
-  static SharedWorkerDevToolsManager* GetInstance();
-
-  DevToolsAgentHost* GetDevToolsAgentHostForWorker(int worker_process_id,
-                                                   int worker_route_id);
-
-  // Returns true when the worker must be paused on start.
-  bool WorkerCreated(int worker_process_id,
-                     int worker_route_id,
-                     const SharedWorkerInstance& instance);
-  void WorkerDestroyed(int worker_process_id, int worker_route_id);
-  void WorkerContextStarted(int worker_process_id, int worker_route_id);
-
- private:
-  friend struct DefaultSingletonTraits<SharedWorkerDevToolsManager>;
-  friend class SharedWorkerDevToolsManagerTest;
-  FRIEND_TEST_ALL_PREFIXES(SharedWorkerDevToolsManagerTest, BasicTest);
-  FRIEND_TEST_ALL_PREFIXES(SharedWorkerDevToolsManagerTest, AttachTest);
-
-  enum WorkerState {
-    WORKER_UNINSPECTED,
-    WORKER_INSPECTED,
-    WORKER_TERMINATED,
-    WORKER_PAUSED,
-  };
-
-  class WorkerInfo {
-   public:
-    explicit WorkerInfo(const SharedWorkerInstance& instance)
-        : instance_(instance), state_(WORKER_UNINSPECTED), agent_host_(NULL) {}
-
-    const SharedWorkerInstance& instance() const { return instance_; }
-    WorkerState state() { return state_; }
-    void set_state(WorkerState new_state) { state_ = new_state; }
-    SharedWorkerDevToolsAgentHost* agent_host() { return agent_host_; }
-    void set_agent_host(SharedWorkerDevToolsAgentHost* agent_host) {
-      agent_host_ = agent_host;
-    }
-
-   private:
-    const SharedWorkerInstance instance_;
-    WorkerState state_;
-    SharedWorkerDevToolsAgentHost* agent_host_;
-  };
-
-  typedef base::ScopedPtrHashMap<WorkerId, WorkerInfo> WorkerInfoMap;
-
-  SharedWorkerDevToolsManager();
-  virtual ~SharedWorkerDevToolsManager();
-
-  void RemoveInspectedWorkerData(SharedWorkerDevToolsAgentHost* agent_host);
-
-  WorkerInfoMap::iterator FindExistingWorkerInfo(
-      const SharedWorkerInstance& instance);
-
-  // Resets to its initial state as if newly created.
-  void ResetForTesting();
-
-  WorkerInfoMap workers_;
-
-  DISALLOW_COPY_AND_ASSIGN(SharedWorkerDevToolsManager);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_DEVTOOLS_SHARED_WORKER_DEVTOOLS_MANAGER_H_
diff --git a/content/browser/devtools/shared_worker_devtools_manager_unittest.cc b/content/browser/devtools/shared_worker_devtools_manager_unittest.cc
deleted file mode 100644
index 0f987b7..0000000
--- a/content/browser/devtools/shared_worker_devtools_manager_unittest.cc
+++ /dev/null
@@ -1,265 +0,0 @@
-// 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.
-
-#include "content/browser/devtools/shared_worker_devtools_manager.h"
-
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "content/browser/browser_thread_impl.h"
-#include "content/browser/devtools/devtools_manager_impl.h"
-#include "content/browser/shared_worker/shared_worker_instance.h"
-#include "content/browser/worker_host/worker_storage_partition.h"
-#include "content/public/browser/devtools_agent_host.h"
-#include "content/public/browser/devtools_client_host.h"
-#include "content/public/test/test_browser_context.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-namespace {
-
-class TestDevToolsClientHost : public DevToolsClientHost {
- public:
-  TestDevToolsClientHost() {}
-  virtual ~TestDevToolsClientHost() {}
-  virtual void DispatchOnInspectorFrontend(const std::string& message)
-      OVERRIDE {}
-  virtual void InspectedContentsClosing() OVERRIDE {}
-  virtual void ReplacedWithAnotherClient() OVERRIDE {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestDevToolsClientHost);
-};
-}
-
-class SharedWorkerDevToolsManagerTest : public testing::Test {
- public:
-  SharedWorkerDevToolsManagerTest()
-      : ui_thread_(BrowserThread::UI, &message_loop_),
-        browser_context_(new TestBrowserContext()),
-        partition_(
-            new WorkerStoragePartition(browser_context_->GetRequestContext(),
-                                       NULL,
-                                       NULL,
-                                       NULL,
-                                       NULL,
-                                       NULL,
-                                       NULL,
-                                       NULL)),
-        partition_id_(*partition_.get()) {}
-
- protected:
-  virtual void SetUp() OVERRIDE {
-    manager_ = SharedWorkerDevToolsManager::GetInstance();
-  }
-  virtual void TearDown() OVERRIDE {
-    SharedWorkerDevToolsManager::GetInstance()->ResetForTesting();
-  }
-
-  void CheckWorkerState(int worker_process_id,
-                        int worker_route_id,
-                        SharedWorkerDevToolsManager::WorkerState state) {
-    const SharedWorkerDevToolsManager::WorkerId id(worker_process_id,
-                                                   worker_route_id);
-    SharedWorkerDevToolsManager::WorkerInfoMap::iterator it =
-        manager_->workers_.find(id);
-    EXPECT_TRUE(manager_->workers_.end() != it);
-    EXPECT_EQ(state, it->second->state());
-  }
-
-  void CheckWorkerNotExist(int worker_process_id, int worker_route_id) {
-    const SharedWorkerDevToolsManager::WorkerId id(worker_process_id,
-                                                   worker_route_id);
-    EXPECT_TRUE(manager_->workers_.end() == manager_->workers_.find(id));
-  }
-
-  void CheckWorkerCount(size_t size) {
-    EXPECT_EQ(size, manager_->workers_.size());
-  }
-
-  void RegisterDevToolsClientHostFor(DevToolsAgentHost* agent_host,
-                                     DevToolsClientHost* client_host) {
-    DevToolsManagerImpl::GetInstance()->RegisterDevToolsClientHostFor(
-        agent_host, client_host);
-  }
-
-  void ClientHostClosing(DevToolsClientHost* client_host) {
-    DevToolsManagerImpl::GetInstance()->ClientHostClosing(client_host);
-  }
-
-  base::MessageLoopForIO message_loop_;
-  BrowserThreadImpl ui_thread_;
-  scoped_ptr<TestBrowserContext> browser_context_;
-  scoped_ptr<WorkerStoragePartition> partition_;
-  const WorkerStoragePartitionId partition_id_;
-  SharedWorkerDevToolsManager* manager_;
-};
-
-TEST_F(SharedWorkerDevToolsManagerTest, BasicTest) {
-  scoped_refptr<DevToolsAgentHost> agent_host;
-
-  SharedWorkerInstance instance1(GURL("http://example.com/w.js"),
-                                 base::string16(),
-                                 base::string16(),
-                                 blink::WebContentSecurityPolicyTypeReport,
-                                 browser_context_->GetResourceContext(),
-                                 partition_id_);
-
-  agent_host = manager_->GetDevToolsAgentHostForWorker(1, 1);
-  EXPECT_FALSE(agent_host.get());
-
-  // Created -> Started -> Destroyed
-  CheckWorkerNotExist(1, 1);
-  manager_->WorkerCreated(1, 1, instance1);
-  CheckWorkerState(1, 1, SharedWorkerDevToolsManager::WORKER_UNINSPECTED);
-  manager_->WorkerContextStarted(1, 1);
-  CheckWorkerState(1, 1, SharedWorkerDevToolsManager::WORKER_UNINSPECTED);
-  manager_->WorkerDestroyed(1, 1);
-  CheckWorkerNotExist(1, 1);
-
-  // Created -> GetDevToolsAgentHost -> Started -> Destroyed
-  CheckWorkerNotExist(1, 2);
-  manager_->WorkerCreated(1, 2, instance1);
-  CheckWorkerState(1, 2, SharedWorkerDevToolsManager::WORKER_UNINSPECTED);
-  agent_host = manager_->GetDevToolsAgentHostForWorker(1, 2);
-  EXPECT_TRUE(agent_host.get());
-  CheckWorkerState(1, 2, SharedWorkerDevToolsManager::WORKER_INSPECTED);
-  EXPECT_EQ(agent_host.get(), manager_->GetDevToolsAgentHostForWorker(1, 2));
-  manager_->WorkerContextStarted(1, 2);
-  CheckWorkerState(1, 2, SharedWorkerDevToolsManager::WORKER_INSPECTED);
-  manager_->WorkerDestroyed(1, 2);
-  CheckWorkerNotExist(1, 2);
-  agent_host = NULL;
-
-  // Created -> Started -> GetDevToolsAgentHost -> Destroyed
-  CheckWorkerNotExist(1, 3);
-  manager_->WorkerCreated(1, 3, instance1);
-  CheckWorkerState(1, 3, SharedWorkerDevToolsManager::WORKER_UNINSPECTED);
-  manager_->WorkerContextStarted(1, 3);
-  CheckWorkerState(1, 3, SharedWorkerDevToolsManager::WORKER_UNINSPECTED);
-  agent_host = manager_->GetDevToolsAgentHostForWorker(1, 3);
-  EXPECT_TRUE(agent_host.get());
-  CheckWorkerState(1, 3, SharedWorkerDevToolsManager::WORKER_INSPECTED);
-  manager_->WorkerDestroyed(1, 3);
-  CheckWorkerNotExist(1, 3);
-  agent_host = NULL;
-
-  // Created -> Destroyed
-  CheckWorkerNotExist(1, 4);
-  manager_->WorkerCreated(1, 4, instance1);
-  CheckWorkerState(1, 4, SharedWorkerDevToolsManager::WORKER_UNINSPECTED);
-  manager_->WorkerDestroyed(1, 4);
-  CheckWorkerNotExist(1, 4);
-
-  // Created -> GetDevToolsAgentHost -> Destroyed
-  CheckWorkerNotExist(1, 5);
-  manager_->WorkerCreated(1, 5, instance1);
-  CheckWorkerState(1, 5, SharedWorkerDevToolsManager::WORKER_UNINSPECTED);
-  agent_host = manager_->GetDevToolsAgentHostForWorker(1, 5);
-  EXPECT_TRUE(agent_host.get());
-  CheckWorkerState(1, 5, SharedWorkerDevToolsManager::WORKER_INSPECTED);
-  manager_->WorkerDestroyed(1, 5);
-  CheckWorkerNotExist(1, 5);
-  agent_host = NULL;
-
-  // Created -> GetDevToolsAgentHost -> Free agent_host -> Destroyed
-  CheckWorkerNotExist(1, 6);
-  manager_->WorkerCreated(1, 6, instance1);
-  CheckWorkerState(1, 6, SharedWorkerDevToolsManager::WORKER_UNINSPECTED);
-  agent_host = manager_->GetDevToolsAgentHostForWorker(1, 6);
-  EXPECT_TRUE(agent_host.get());
-  CheckWorkerState(1, 6, SharedWorkerDevToolsManager::WORKER_INSPECTED);
-  agent_host = NULL;
-  manager_->WorkerDestroyed(1, 6);
-  CheckWorkerNotExist(1, 6);
-}
-
-TEST_F(SharedWorkerDevToolsManagerTest, AttachTest) {
-  scoped_refptr<DevToolsAgentHost> agent_host1;
-  scoped_refptr<DevToolsAgentHost> agent_host2;
-
-  SharedWorkerInstance instance1(GURL("http://example.com/w1.js"),
-                                 base::string16(),
-                                 base::string16(),
-                                 blink::WebContentSecurityPolicyTypeReport,
-                                 browser_context_->GetResourceContext(),
-                                 partition_id_);
-  SharedWorkerInstance instance2(GURL("http://example.com/w2.js"),
-                                 base::string16(),
-                                 base::string16(),
-                                 blink::WebContentSecurityPolicyTypeReport,
-                                 browser_context_->GetResourceContext(),
-                                 partition_id_);
-
-  // Created -> GetDevToolsAgentHost -> Register -> Started -> Destroyed
-  scoped_ptr<TestDevToolsClientHost> client_host1(new TestDevToolsClientHost());
-  CheckWorkerNotExist(2, 1);
-  manager_->WorkerCreated(2, 1, instance1);
-  CheckWorkerState(2, 1, SharedWorkerDevToolsManager::WORKER_UNINSPECTED);
-  agent_host1 = manager_->GetDevToolsAgentHostForWorker(2, 1);
-  EXPECT_TRUE(agent_host1.get());
-  CheckWorkerState(2, 1, SharedWorkerDevToolsManager::WORKER_INSPECTED);
-  EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
-  RegisterDevToolsClientHostFor(agent_host1.get(), client_host1.get());
-  CheckWorkerState(2, 1, SharedWorkerDevToolsManager::WORKER_INSPECTED);
-  manager_->WorkerContextStarted(2, 1);
-  CheckWorkerState(2, 1, SharedWorkerDevToolsManager::WORKER_INSPECTED);
-  manager_->WorkerDestroyed(2, 1);
-  CheckWorkerState(2, 1, SharedWorkerDevToolsManager::WORKER_TERMINATED);
-  EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
-
-  // Created -> Started -> GetDevToolsAgentHost -> Register -> Destroyed
-  scoped_ptr<TestDevToolsClientHost> client_host2(new TestDevToolsClientHost());
-  manager_->WorkerCreated(2, 2, instance2);
-  CheckWorkerState(2, 2, SharedWorkerDevToolsManager::WORKER_UNINSPECTED);
-  manager_->WorkerContextStarted(2, 2);
-  CheckWorkerState(2, 2, SharedWorkerDevToolsManager::WORKER_UNINSPECTED);
-  agent_host2 = manager_->GetDevToolsAgentHostForWorker(2, 2);
-  EXPECT_TRUE(agent_host2.get());
-  EXPECT_NE(agent_host1.get(), agent_host2.get());
-  EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
-  CheckWorkerState(2, 2, SharedWorkerDevToolsManager::WORKER_INSPECTED);
-  RegisterDevToolsClientHostFor(agent_host2.get(), client_host2.get());
-  CheckWorkerState(2, 2, SharedWorkerDevToolsManager::WORKER_INSPECTED);
-  manager_->WorkerDestroyed(2, 2);
-  CheckWorkerState(2, 2, SharedWorkerDevToolsManager::WORKER_TERMINATED);
-  EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
-
-  // Re-created -> Started -> ClientHostClosing -> Destroyed
-  CheckWorkerState(2, 1, SharedWorkerDevToolsManager::WORKER_TERMINATED);
-  manager_->WorkerCreated(2, 3, instance1);
-  CheckWorkerNotExist(2, 1);
-  CheckWorkerState(2, 3, SharedWorkerDevToolsManager::WORKER_PAUSED);
-  EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 3));
-  manager_->WorkerContextStarted(2, 3);
-  CheckWorkerState(2, 3, SharedWorkerDevToolsManager::WORKER_INSPECTED);
-  ClientHostClosing(client_host1.get());
-  manager_->WorkerDestroyed(2, 3);
-  CheckWorkerNotExist(2, 3);
-  agent_host1 = NULL;
-
-  // Re-created -> Destroyed
-  CheckWorkerState(2, 2, SharedWorkerDevToolsManager::WORKER_TERMINATED);
-  manager_->WorkerCreated(2, 4, instance2);
-  CheckWorkerNotExist(2, 2);
-  CheckWorkerState(2, 4, SharedWorkerDevToolsManager::WORKER_PAUSED);
-  EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 4));
-  manager_->WorkerDestroyed(2, 4);
-  CheckWorkerNotExist(2, 4);
-  CheckWorkerState(2, 2, SharedWorkerDevToolsManager::WORKER_TERMINATED);
-
-  // Re-created -> ClientHostClosing -> Destroyed
-  manager_->WorkerCreated(2, 5, instance2);
-  CheckWorkerNotExist(2, 2);
-  CheckWorkerState(2, 5, SharedWorkerDevToolsManager::WORKER_PAUSED);
-  EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 5));
-  ClientHostClosing(client_host2.get());
-  CheckWorkerCount(1);
-  agent_host2 = NULL;
-  CheckWorkerCount(1);
-  manager_->WorkerDestroyed(2, 5);
-  CheckWorkerCount(0);
-}
-
-}  // namespace content
diff --git a/content/browser/devtools/worker_devtools_manager.cc b/content/browser/devtools/worker_devtools_manager.cc
index a05a04a..0658c35 100644
--- a/content/browser/devtools/worker_devtools_manager.cc
+++ b/content/browser/devtools/worker_devtools_manager.cc
@@ -12,8 +12,8 @@
 #include "content/browser/devtools/devtools_manager_impl.h"
 #include "content/browser/devtools/devtools_protocol.h"
 #include "content/browser/devtools/devtools_protocol_constants.h"
+#include "content/browser/devtools/embedded_worker_devtools_manager.h"
 #include "content/browser/devtools/ipc_devtools_agent_host.h"
-#include "content/browser/devtools/shared_worker_devtools_manager.h"
 #include "content/browser/devtools/worker_devtools_message_filter.h"
 #include "content/browser/worker_host/worker_service_impl.h"
 #include "content/common/devtools_messages.h"
@@ -29,7 +29,7 @@
     int worker_process_id,
     int worker_route_id) {
   if (WorkerService::EmbeddedSharedWorkerEnabled()) {
-    return SharedWorkerDevToolsManager::GetInstance()
+    return EmbeddedWorkerDevToolsManager::GetInstance()
         ->GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id);
   } else {
     return WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc
index 5ab23a8..2ee130d 100644
--- a/content/browser/download/download_manager_impl_unittest.cc
+++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -432,6 +432,8 @@
   MOCK_METHOD0(GetDownloadManagerDelegate, DownloadManagerDelegate*());
   MOCK_METHOD0(GetGeolocationPermissionContext,
                GeolocationPermissionContext* ());
+  MOCK_METHOD0(GetGuestManagerDelegate,
+               BrowserPluginGuestManagerDelegate* ());
   MOCK_METHOD0(GetSpecialStoragePolicy, quota::SpecialStoragePolicy*());
 };
 
diff --git a/content/browser/fileapi/blob_storage_context_unittest.cc b/content/browser/fileapi/blob_storage_context_unittest.cc
index fd58880..823679e 100644
--- a/content/browser/fileapi/blob_storage_context_unittest.cc
+++ b/content/browser/fileapi/blob_storage_context_unittest.cc
@@ -6,6 +6,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "base/time/time.h"
 #include "content/browser/fileapi/blob_storage_host.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -41,6 +42,10 @@
   blob_data_handle = context.GetBlobDataFromUUID(kId);
   EXPECT_TRUE(blob_data_handle);
   blob_data_handle.reset();
+  {  // Clean up for ASAN
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
 
   // Make sure its still there after inc/dec.
   EXPECT_TRUE(host.IncrementBlobRefCount(kId));
@@ -48,6 +53,10 @@
   blob_data_handle = context.GetBlobDataFromUUID(kId);
   EXPECT_TRUE(blob_data_handle);
   blob_data_handle.reset();
+  {  // Clean up for ASAN
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
 
   // Make sure it goes away in the end.
   EXPECT_TRUE(host.DecrementBlobRefCount(kId));
@@ -82,6 +91,10 @@
   // Should disappear after dropping both handles.
   blob_data_handle.reset();
   another_handle.reset();
+  {  // Clean up for ASAN
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
   blob_data_handle = context.GetBlobDataFromUUID(kId);
   EXPECT_FALSE(blob_data_handle);
 }
@@ -131,6 +144,12 @@
   blob_data_handle = context.AddFinishedBlob(blob_data2.get());
   ASSERT_TRUE(blob_data_handle.get());
   EXPECT_TRUE(*(blob_data_handle->data()) == *canonicalized_blob_data2.get());
+
+  blob_data_handle.reset();
+  {  // Clean up for ASAN
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
 }
 
 TEST(BlobStorageContextTest, PublicBlobUrls) {
@@ -150,6 +169,10 @@
   ASSERT_TRUE(blob_data_handle.get());
   EXPECT_EQ(kId, blob_data_handle->data()->uuid());
   blob_data_handle.reset();
+  {  // Clean up for ASAN
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
 
   // The url registration should keep the blob alive even after
   // explicit references are dropped.
@@ -157,6 +180,10 @@
   blob_data_handle = context.GetBlobDataFromPublicURL(kUrl);
   EXPECT_TRUE(blob_data_handle);
   blob_data_handle.reset();
+  {  // Clean up for ASAN
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
 
   // Finally get rid of the url registration and the blob.
   EXPECT_TRUE(host.RevokePublicBlobURL(kUrl));
diff --git a/content/browser/fileapi/file_writer_delegate_unittest.cc b/content/browser/fileapi/file_writer_delegate_unittest.cc
index 9f1e22d..3d2814c 100644
--- a/content/browser/fileapi/file_writer_delegate_unittest.cc
+++ b/content/browser/fileapi/file_writer_delegate_unittest.cc
@@ -121,7 +121,8 @@
             *file_system_context_->GetUpdateObservers(kFileSystemType));
     writer->set_default_quota(allowed_growth);
     return new FileWriterDelegate(
-        scoped_ptr<fileapi::FileStreamWriter>(writer));
+        scoped_ptr<fileapi::FileStreamWriter>(writer),
+        FileWriterDelegate::FLUSH_ON_COMPLETION);
   }
 
   FileWriterDelegate::DelegateWriteCallback GetWriteCallback(Result* result) {
diff --git a/content/browser/fileapi/sandbox_database_test_helper.cc b/content/browser/fileapi/sandbox_database_test_helper.cc
new file mode 100644
index 0000000..3e29567
--- /dev/null
+++ b/content/browser/fileapi/sandbox_database_test_helper.cc
@@ -0,0 +1,93 @@
+// 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.
+
+#include "content/browser/fileapi/sandbox_database_test_helper.h"
+
+#include <algorithm>
+#include <functional>
+#include <vector>
+
+#include "base/file_util.h"
+#include "base/files/file.h"
+#include "base/files/file_enumerator.h"
+#include "base/stl_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/common/fileapi/file_system_util.h"
+
+using fileapi::FilePathToString;
+
+namespace content {
+
+void CorruptDatabase(const base::FilePath& db_path,
+                     leveldb::FileType type,
+                     ptrdiff_t offset,
+                     size_t size) {
+  base::FileEnumerator file_enum(db_path, false /* not recursive */,
+      base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES);
+  base::FilePath file_path;
+  base::FilePath picked_file_path;
+  uint64 picked_file_number = kuint64max;
+
+  while (!(file_path = file_enum.Next()).empty()) {
+    uint64 number = kuint64max;
+    leveldb::FileType file_type;
+    EXPECT_TRUE(leveldb::ParseFileName(FilePathToString(file_path.BaseName()),
+                                       &number, &file_type));
+    if (file_type == type &&
+        (picked_file_number == kuint64max || picked_file_number < number)) {
+      picked_file_path = file_path;
+      picked_file_number = number;
+    }
+  }
+
+  EXPECT_FALSE(picked_file_path.empty());
+  EXPECT_NE(kuint64max, picked_file_number);
+
+  base::File file(picked_file_path,
+                  base::File::FLAG_OPEN | base::File::FLAG_READ |
+                      base::File::FLAG_WRITE);
+  ASSERT_TRUE(file.IsValid());
+  EXPECT_FALSE(file.created());
+
+  base::File::Info file_info;
+  EXPECT_TRUE(file.GetInfo(&file_info));
+  if (offset < 0)
+    offset += file_info.size;
+  EXPECT_GE(offset, 0);
+  EXPECT_LE(offset, file_info.size);
+
+  size = std::min(size, static_cast<size_t>(file_info.size - offset));
+
+  std::vector<char> buf(size);
+  int read_size = file.Read(offset, vector_as_array(&buf), buf.size());
+  EXPECT_LT(0, read_size);
+  EXPECT_GE(buf.size(), static_cast<size_t>(read_size));
+  buf.resize(read_size);
+
+  std::transform(buf.begin(), buf.end(), buf.begin(),
+                 std::logical_not<char>());
+
+  int written_size = file.Write(offset, vector_as_array(&buf), buf.size());
+  EXPECT_GT(written_size, 0);
+  EXPECT_EQ(buf.size(), static_cast<size_t>(written_size));
+}
+
+void DeleteDatabaseFile(const base::FilePath& db_path,
+                        leveldb::FileType type) {
+  base::FileEnumerator file_enum(db_path, false /* not recursive */,
+      base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES);
+  base::FilePath file_path;
+  while (!(file_path = file_enum.Next()).empty()) {
+    uint64 number = kuint64max;
+    leveldb::FileType file_type;
+    EXPECT_TRUE(leveldb::ParseFileName(FilePathToString(file_path.BaseName()),
+                                       &number, &file_type));
+    if (file_type == type) {
+      base::DeleteFile(file_path, false);
+      // We may have multiple files for the same type, so don't break here.
+    }
+  }
+}
+
+}  // namespace content
diff --git a/content/browser/fileapi/sandbox_database_test_helper.h b/content/browser/fileapi/sandbox_database_test_helper.h
new file mode 100644
index 0000000..881bdff
--- /dev/null
+++ b/content/browser/fileapi/sandbox_database_test_helper.h
@@ -0,0 +1,28 @@
+// 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.
+
+#ifndef CONTENT_BROWSER_FILEAPI_SANDBOX_DATABASE_TEST_HELPER_H_
+#define CONTENT_BROWSER_FILEAPI_SANDBOX_DATABASE_TEST_HELPER_H_
+
+#include <cstddef>
+
+#include "third_party/leveldatabase/src/db/filename.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace content {
+
+void CorruptDatabase(const base::FilePath& db_path,
+                     leveldb::FileType type,
+                     ptrdiff_t offset,
+                     size_t size);
+
+void DeleteDatabaseFile(const base::FilePath& db_path,
+                        leveldb::FileType type);
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_FILEAPI_SANDBOX_DATABASE_TEST_HELPER_H_
diff --git a/content/browser/fileapi/sandbox_directory_database_unittest.cc b/content/browser/fileapi/sandbox_directory_database_unittest.cc
index fabe385..6bc3c56 100644
--- a/content/browser/fileapi/sandbox_directory_database_unittest.cc
+++ b/content/browser/fileapi/sandbox_directory_database_unittest.cc
@@ -13,15 +13,13 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "content/browser/fileapi/sandbox_database_test_helper.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/leveldatabase/src/include/leveldb/db.h"
-#include "webkit/browser/fileapi/sandbox_database_test_helper.h"
 #include "webkit/common/fileapi/file_system_util.h"
 
 #define FPL(x) FILE_PATH_LITERAL(x)
 
-using fileapi::CorruptDatabase;
-using fileapi::DeleteDatabaseFile;
 using fileapi::FilePathToString;
 using fileapi::SandboxDirectoryDatabase;
 
diff --git a/content/browser/fileapi/sandbox_origin_database_unittest.cc b/content/browser/fileapi/sandbox_origin_database_unittest.cc
index cfe5a87..cda5b77 100644
--- a/content/browser/fileapi/sandbox_origin_database_unittest.cc
+++ b/content/browser/fileapi/sandbox_origin_database_unittest.cc
@@ -13,15 +13,13 @@
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/stl_util.h"
+#include "content/browser/fileapi/sandbox_database_test_helper.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/leveldatabase/src/db/filename.h"
 #include "third_party/leveldatabase/src/include/leveldb/db.h"
-#include "webkit/browser/fileapi/sandbox_database_test_helper.h"
 #include "webkit/browser/fileapi/sandbox_origin_database.h"
 #include "webkit/common/fileapi/file_system_util.h"
 
-using fileapi::CorruptDatabase;
-using fileapi::DeleteDatabaseFile;
 using fileapi::SandboxOriginDatabase;
 
 namespace content {
diff --git a/content/browser/frame_host/interstitial_page_impl.cc b/content/browser/frame_host/interstitial_page_impl.cc
index 607ab1c..975e7d6 100644
--- a/content/browser/frame_host/interstitial_page_impl.cc
+++ b/content/browser/frame_host/interstitial_page_impl.cc
@@ -19,15 +19,15 @@
 #include "content/browser/frame_host/navigation_entry_impl.h"
 #include "content/browser/loader/resource_dispatcher_host_impl.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/browser/renderer_host/render_view_host_delegate_view.h"
 #include "content/browser/renderer_host/render_view_host_factory.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/site_instance_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/common/frame_messages.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_view_host_delegate_view.h"
-#include "content/port/browser/render_widget_host_view_port.h"
-#include "content/port/browser/web_contents_view_port.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
@@ -283,8 +283,7 @@
   if (render_view_host_->GetView() &&
       render_view_host_->GetView()->HasFocus() &&
       controller_->delegate()->GetRenderViewHost()->GetView()) {
-    RenderWidgetHostViewPort::FromRWHV(
-        controller_->delegate()->GetRenderViewHost()->GetView())->Focus();
+    controller_->delegate()->GetRenderViewHost()->GetView()->Focus();
   }
 
   // Delete this and call Shutdown on the RVH asynchronously, as we may have
@@ -357,18 +356,7 @@
   OnNavigatingAwayOrTabClosing();
 }
 
-void InterstitialPageImpl::WebContentsWillBeDestroyed() {
-  OnNavigatingAwayOrTabClosing();
-}
-
-void InterstitialPageImpl::WebContentsDestroyed(WebContents* web_contents) {
-  // WebContentsImpl will only call WebContentsWillBeDestroyed for interstitial
-  // pages that it knows about, pages that called
-  // WebContentsImpl::AttachInterstitialPage. But it's possible to have an
-  // interstitial page that never progressed that far. In that case, ensure that
-  // this interstitial page is destroyed. (And if it was attached, and
-  // OnNavigatingAwayOrTabClosing was called, it's safe to call
-  // OnNavigatingAwayOrTabClosing twice.)
+void InterstitialPageImpl::WebContentsDestroyed() {
   OnNavigatingAwayOrTabClosing();
 }
 
@@ -577,11 +565,10 @@
 WebContentsView* InterstitialPageImpl::CreateWebContentsView() {
   if (!enabled() || !create_view_)
     return NULL;
-  WebContentsView* web_contents_view = web_contents()->GetView();
-  WebContentsViewPort* web_contents_view_port =
-      static_cast<WebContentsViewPort*>(web_contents_view);
-  RenderWidgetHostView* view =
-      web_contents_view_port->CreateViewForWidget(render_view_host_);
+  WebContentsView* wcv =
+      static_cast<WebContentsImpl*>(web_contents())->GetView();
+  RenderWidgetHostViewBase* view =
+      wcv->CreateViewForWidget(render_view_host_);
   render_view_host_->SetView(view);
   render_view_host_->AllowBindings(BINDINGS_POLICY_DOM_AUTOMATION);
 
@@ -593,10 +580,10 @@
                                       false);
   controller_->delegate()->RenderFrameForInterstitialPageCreated(
       frame_tree_.root()->current_frame_host());
-  view->SetSize(web_contents_view->GetContainerSize());
+  view->SetSize(web_contents()->GetContainerBounds().size());
   // Don't show the interstitial until we have navigated to it.
   view->Hide();
-  return web_contents_view;
+  return wcv;
 }
 
 void InterstitialPageImpl::Proceed() {
@@ -704,7 +691,7 @@
   // Focus the native window.
   if (!enabled())
     return;
-  RenderWidgetHostViewPort::FromRWHV(render_view_host_->GetView())->Focus();
+  render_view_host_->GetView()->Focus();
 }
 
 void InterstitialPageImpl::FocusThroughTabTraversal(bool reverse) {
diff --git a/content/browser/frame_host/interstitial_page_impl.h b/content/browser/frame_host/interstitial_page_impl.h
index cc9dc63..fe9eee4 100644
--- a/content/browser/frame_host/interstitial_page_impl.h
+++ b/content/browser/frame_host/interstitial_page_impl.h
@@ -27,7 +27,6 @@
 class RenderViewHostImpl;
 class RenderWidgetHostView;
 class WebContentsView;
-class WebContentsImpl;
 
 enum ResourceRequestAction {
   BLOCK,
@@ -69,10 +68,6 @@
   virtual void SetSize(const gfx::Size& size) OVERRIDE;
   virtual void Focus() OVERRIDE;
 
-  // This is called by a hosting WebContents to notify this interstitial page
-  // that it is going away.
-  void WebContentsWillBeDestroyed();
-
   // Allows the user to navigate away by disabling the interstitial, canceling
   // the pending request, and unblocking the hidden renderer.  The interstitial
   // will stay visible until the navigation completes.
@@ -110,7 +105,7 @@
 
   // WebContentsObserver implementation:
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
   virtual void NavigationEntryCommitted(
       const LoadCommittedDetails& load_details) OVERRIDE;
 
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index 4fa5f08..79e2c7b 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -654,8 +654,8 @@
     case LOAD_TYPE_DEFAULT:
       break;
     case LOAD_TYPE_BROWSER_INITIATED_HTTP_POST:
-      if (!params.url.SchemeIs(kHttpScheme) &&
-          !params.url.SchemeIs(kHttpsScheme)) {
+      if (!params.url.SchemeIs(url::kHttpScheme) &&
+          !params.url.SchemeIs(url::kHttpsScheme)) {
         NOTREACHED() << "Http post load must use http(s) scheme.";
         return;
       }
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h
index b229ffb..a64edeb 100644
--- a/content/browser/frame_host/navigator.h
+++ b/content/browser/frame_host/navigator.h
@@ -37,6 +37,9 @@
   // Returns the NavigationController associated with this Navigator.
   virtual NavigationController* GetController();
 
+
+  // Notifications coming from the RenderFrameHosts ----------------------------
+
   // The RenderFrameHostImpl started a provisional load.
   virtual void DidStartProvisionalLoad(RenderFrameHostImpl* render_frame_host,
                                        int parent_routing_id,
@@ -88,6 +91,9 @@
       RenderFrameHostImpl* render_frame_host,
       NavigationController::ReloadType reload_type);
 
+
+  // Navigation requests -------------------------------------------------------
+
   virtual base::TimeTicks GetCurrentLoadStart();
 
   // The RenderFrameHostImpl has received a request to open a URL with the
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h
index db28eab..fbc4613 100644
--- a/content/browser/frame_host/render_frame_host_delegate.h
+++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -67,14 +67,14 @@
                                const ContextMenuParams& params) {}
 
   // A JavaScript message, confirmation or prompt should be shown.
-  virtual void RunJavaScriptMessage(RenderFrameHost* rfh,
+  virtual void RunJavaScriptMessage(RenderFrameHost* render_frame_host,
                                     const base::string16& message,
                                     const base::string16& default_prompt,
                                     const GURL& frame_url,
                                     JavaScriptMessageType type,
                                     IPC::Message* reply_msg) {}
 
-  virtual void RunBeforeUnloadConfirm(RenderFrameHost* rfh,
+  virtual void RunBeforeUnloadConfirm(RenderFrameHost* render_frame_host,
                                       const base::string16& message,
                                       bool is_reload,
                                       IPC::Message* reply_msg) {}
@@ -83,6 +83,14 @@
   // is no longer safe to display a pending URL without risking a URL spoof.
   virtual void DidAccessInitialDocument() {}
 
+  // The frame set its opener to null, disowning it for the lifetime of the
+  // window. Only called for the top-level frame.
+  virtual void DidDisownOpener(RenderFrameHost* render_frame_host) {}
+
+  // The onload handler in the frame has completed. Only called for the top-
+  // level frame.
+  virtual void DocumentOnLoadCompleted(RenderFrameHost* render_frame_host) {}
+
   // Return this object cast to a WebContents, if it is one. If the object is
   // not a WebContents, returns NULL.
   virtual WebContents* GetAsWebContents();
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 15e4844..f9e19e6 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -279,6 +279,8 @@
     IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading)
     IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading)
     IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL)
+    IPC_MESSAGE_HANDLER(FrameHostMsg_DocumentOnLoadCompleted,
+                        OnDocumentOnLoadCompleted)
     IPC_MESSAGE_HANDLER(FrameHostMsg_BeforeUnload_ACK, OnBeforeUnloadACK)
     IPC_MESSAGE_HANDLER(FrameHostMsg_SwapOut_ACK, OnSwapOutACK)
     IPC_MESSAGE_HANDLER(FrameHostMsg_ContextMenu, OnContextMenu)
@@ -290,6 +292,7 @@
                                     OnRunBeforeUnloadConfirm)
     IPC_MESSAGE_HANDLER(FrameHostMsg_DidAccessInitialDocument,
                         OnDidAccessInitialDocument)
+    IPC_MESSAGE_HANDLER(FrameHostMsg_DidDisownOpener, OnDidDisownOpener)
     IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_RequestPermission,
                         OnRequestDesktopNotificationPermission)
     IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_Show,
@@ -356,6 +359,12 @@
       params.should_replace_current_entry, params.user_gesture);
 }
 
+void RenderFrameHostImpl::OnDocumentOnLoadCompleted() {
+  // This message is only sent for top-level frames. TODO(avi): when frame tree
+  // mirroring works correctly, add a check here to enforce it.
+  delegate_->DocumentOnLoadCompleted(this);
+}
+
 void RenderFrameHostImpl::OnDidStartProvisionalLoadForFrame(
     int parent_routing_id,
     const GURL& url) {
@@ -680,6 +689,12 @@
   delegate_->DidAccessInitialDocument();
 }
 
+void RenderFrameHostImpl::OnDidDisownOpener() {
+  // This message is only sent for top-level frames. TODO(avi): when frame tree
+  // mirroring works correctly, add a check here to enforce it.
+  delegate_->DidDisownOpener(this);
+}
+
 void RenderFrameHostImpl::SetPendingShutdown(const base::Closure& on_swap_out) {
   render_view_host_->SetPendingShutdown(on_swap_out);
 }
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 4f40513..3acb626 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -188,6 +188,7 @@
   void OnDetach();
   void OnFrameFocused();
   void OnOpenURL(const FrameHostMsg_OpenURL_Params& params);
+  void OnDocumentOnLoadCompleted();
   void OnDidStartProvisionalLoadForFrame(int parent_routing_id,
                                          const GURL& url);
   void OnDidFailProvisionalLoadWithError(
@@ -224,6 +225,7 @@
       const ShowDesktopNotificationHostMsgParams& params);
   void OnCancelDesktopNotification(int notification_id);
   void OnDidAccessInitialDocument();
+  void OnDidDisownOpener();
 
   // Returns whether the given URL is allowed to commit in the current process.
   // This is a more conservative check than RenderProcessHost::FilterURL, since
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index e5e6d26..13a03b3 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -9,6 +9,7 @@
 #include "base/command_line.h"
 #include "base/debug/trace_event.h"
 #include "base/logging.h"
+#include "base/stl_util.h"
 #include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/devtools/render_view_devtools_agent_host.h"
 #include "content/browser/frame_host/cross_process_frame_connector.h"
@@ -24,11 +25,11 @@
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_factory.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/site_instance_impl.h"
 #include "content/browser/webui/web_ui_controller_factory_registry.h"
 #include "content/browser/webui/web_ui_impl.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
@@ -93,11 +94,7 @@
   render_frame_host_.reset();
 
   // Delete any swapped out RenderFrameHosts.
-  for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
-       iter != proxy_hosts_.end();
-       ++iter) {
-    delete iter->second;
-  }
+  STLDeleteValues(&proxy_hosts_);
 }
 
 void RenderFrameHostManager::Init(BrowserContext* browser_context,
@@ -1070,8 +1067,7 @@
     delegate_->SetFocusToLocationBar(false);
   } else if (focus_render_view &&
              render_frame_host_->render_view_host()->GetView()) {
-    RenderWidgetHostViewPort::FromRWHV(
-        render_frame_host_->render_view_host()->GetView())->Focus();
+    render_frame_host_->render_view_host()->GetView()->Focus();
   }
 
   // Notify that we've swapped RenderFrameHosts. We do this before shutting down
@@ -1360,36 +1356,6 @@
   pending_and_current_web_ui_.reset();
 }
 
-void RenderFrameHostManager::RenderViewDeleted(RenderViewHost* rvh) {
-  // We are doing this in order to work around and to track a crasher
-  // (http://crbug.com/23411) where it seems that pending_render_frame_host_ is
-  // deleted (not sure from where) but not NULLed.
-  if (pending_render_frame_host_ &&
-      rvh == pending_render_frame_host_->render_view_host()) {
-    // If you hit this NOTREACHED, please report it in the following bug
-    // http://crbug.com/23411 Make sure to include what you were doing when it
-    // happened  (navigating to a new page, closing a tab...) and if you can
-    // reproduce.
-    NOTREACHED();
-    pending_render_frame_host_.reset();
-  }
-
-  // Make sure deleted RVHs are not kept in the swapped out list while we are
-  // still alive.  (If render_frame_host_ is null, we're already being deleted.)
-  if (!render_frame_host_)
-    return;
-
-  // We can't look it up by SiteInstance ID, which may no longer be valid.
-  for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
-       iter != proxy_hosts_.end();
-       ++iter) {
-    if (iter->second->render_view_host() == rvh) {
-      proxy_hosts_.erase(iter);
-      break;
-    }
-  }
-}
-
 bool RenderFrameHostManager::IsRVHOnSwappedOutList(
     RenderViewHostImpl* rvh) const {
   RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h
index 8d5b594..f5ecf04 100644
--- a/content/browser/frame_host/render_frame_host_manager.h
+++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -260,9 +260,6 @@
                        const NotificationSource& source,
                        const NotificationDetails& details) OVERRIDE;
 
-  // Called when a RenderViewHost is about to be deleted.
-  void RenderViewDeleted(RenderViewHost* rvh);
-
   // Returns whether the given RenderFrameHost (or its associated
   // RenderViewHost) is on the list of swapped out RenderFrameHosts.
   bool IsRVHOnSwappedOutList(RenderViewHostImpl* rvh) const;
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
index c3ea519..e71ee01 100644
--- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -174,7 +174,6 @@
   }
 
   virtual void DidUpdateFaviconURL(
-      int32 page_id,
       const std::vector<FaviconURL>& candidates) OVERRIDE {
     favicon_received_ = true;
   }
@@ -399,7 +398,7 @@
     PluginFaviconMessageObserver observer(contents());
     EXPECT_TRUE(ntp_rvh->OnMessageReceived(
                     ViewHostMsg_UpdateFaviconURL(
-                        rvh()->GetRoutingID(), 0, icons)));
+                        rvh()->GetRoutingID(), icons)));
     EXPECT_TRUE(observer.favicon_received());
   }
   // Create one more view in the same SiteInstance where ntp_rvh
@@ -422,7 +421,7 @@
     PluginFaviconMessageObserver observer(contents());
     EXPECT_TRUE(
         dest_rvh->OnMessageReceived(
-            ViewHostMsg_UpdateFaviconURL(rvh()->GetRoutingID(), 101, icons)));
+            ViewHostMsg_UpdateFaviconURL(rvh()->GetRoutingID(), icons)));
     EXPECT_TRUE(observer.favicon_received());
   }
 
@@ -433,7 +432,7 @@
     PluginFaviconMessageObserver observer(contents());
     EXPECT_TRUE(
         ntp_rvh->OnMessageReceived(
-            ViewHostMsg_UpdateFaviconURL(rvh()->GetRoutingID(), 101, icons)));
+            ViewHostMsg_UpdateFaviconURL(rvh()->GetRoutingID(), icons)));
     EXPECT_FALSE(observer.favicon_received());
   }
 
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc
index 3094dff..d5228f7 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame.cc
+++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -187,9 +187,20 @@
 }
 
 #if defined(OS_ANDROID)
+void RenderWidgetHostViewChildFrame::ShowDisambiguationPopup(
+    const gfx::Rect& target_rect,
+    const SkBitmap& zoomed_bitmap) {
+}
+
 void RenderWidgetHostViewChildFrame::SelectionRootBoundsChanged(
     const gfx::Rect& bounds) {
 }
+
+void RenderWidgetHostViewChildFrame::LockCompositingSurface() {
+}
+
+void RenderWidgetHostViewChildFrame::UnlockCompositingSurface() {
+}
 #endif
 
 void RenderWidgetHostViewChildFrame::ScrollOffsetChanged() {
@@ -285,13 +296,6 @@
 }
 #endif // defined(OS_MACOSX)
 
-#if defined(OS_ANDROID)
-void RenderWidgetHostViewChildFrame::ShowDisambiguationPopup(
-    const gfx::Rect& target_rect,
-    const SkBitmap& zoomed_bitmap) {
-}
-#endif  // defined(OS_ANDROID)
-
 void RenderWidgetHostViewChildFrame::CopyFromCompositingSurface(
     const gfx::Rect& src_subrect,
     const gfx::Size& /* dst_size */,
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h
index 6f52a2c..2e5b916 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame.h
+++ b/content/browser/frame_host/render_widget_host_view_child_frame.h
@@ -53,7 +53,7 @@
   virtual void SetBackground(const SkBitmap& background) OVERRIDE;
   virtual gfx::Size GetPhysicalBackingSize() const OVERRIDE;
 
-  // RenderWidgetHostViewPort implementation.
+  // RenderWidgetHostViewBase implementation.
   virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
                            const gfx::Rect& pos) OVERRIDE;
   virtual void InitAsFullscreen(
@@ -83,9 +83,6 @@
                                 const gfx::Range& range) OVERRIDE;
   virtual void SelectionBoundsChanged(
       const ViewHostMsg_SelectionBounds_Params& params) OVERRIDE;
-#if defined(OS_ANDROID)
-  virtual void SelectionRootBoundsChanged(const gfx::Rect& bounds) OVERRIDE;
-#endif
   virtual void ScrollOffsetChanged() OVERRIDE;
   virtual void CopyFromCompositingSurface(
       const gfx::Rect& src_subrect,
@@ -137,16 +134,19 @@
   virtual bool IsSpeaking() const OVERRIDE;
   virtual void StopSpeaking() OVERRIDE;
 
-  // RenderWidgetHostViewPort implementation.
+  // RenderWidgetHostViewBase implementation.
   virtual bool PostProcessEventForPluginIme(
       const NativeWebKeyboardEvent& event) OVERRIDE;
 #endif  // defined(OS_MACOSX)
 
 #if defined(OS_ANDROID)
-  // RenderWidgetHostViewPort implementation.
+  // RenderWidgetHostViewBase implementation.
+  virtual void SelectionRootBoundsChanged(const gfx::Rect& bounds) OVERRIDE;
   virtual void ShowDisambiguationPopup(
       const gfx::Rect& target_rect,
       const SkBitmap& zoomed_bitmap) OVERRIDE;
+  virtual void LockCompositingSurface() OVERRIDE;
+  virtual void UnlockCompositingSurface() OVERRIDE;
 #endif  // defined(OS_ANDROID)
 
 #if defined(OS_WIN)
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc
index 47d8f79..2cd0ba3 100644
--- a/content/browser/frame_host/render_widget_host_view_guest.cc
+++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -47,11 +47,11 @@
 RenderWidgetHostViewGuest::RenderWidgetHostViewGuest(
     RenderWidgetHost* widget_host,
     BrowserPluginGuest* guest,
-    RenderWidgetHostView* platform_view)
+    RenderWidgetHostViewBase* platform_view)
     : RenderWidgetHostViewChildFrame(widget_host),
       // |guest| is NULL during test.
       guest_(guest ? guest->AsWeakPtr() : base::WeakPtr<BrowserPluginGuest>()),
-      platform_view_(static_cast<RenderWidgetHostViewPort*>(platform_view)) {
+      platform_view_(platform_view) {
 #if defined(USE_AURA)
   gesture_recognizer_.reset(ui::GestureRecognizer::Create());
   gesture_recognizer_->AddGestureEventHelper(this);
@@ -121,8 +121,7 @@
   if (!guest_)
     return gfx::Rect();
 
-  RenderWidgetHostViewPort* rwhv = static_cast<RenderWidgetHostViewPort*>(
-      guest_->GetEmbedderRenderWidgetHostView());
+  RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
   gfx::Rect embedder_bounds;
   if (rwhv)
     embedder_bounds = rwhv->GetViewBounds();
@@ -295,8 +294,7 @@
   if (!guest_)
     return;
 
-  RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
-      guest_->GetEmbedderRenderWidgetHostView());
+  RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
   if (!rwhv)
     return;
   // Forward the information to embedding RWHV.
@@ -307,8 +305,7 @@
   if (!guest_)
     return;
 
-  RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
-      guest_->GetEmbedderRenderWidgetHostView());
+  RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
   if (!rwhv)
     return;
   // Forward the information to embedding RWHV.
@@ -322,8 +319,7 @@
   if (!guest_)
     return;
 
-  RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
-      guest_->GetEmbedderRenderWidgetHostView());
+  RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
   if (!rwhv)
     return;
   std::vector<gfx::Rect> guest_character_bounds;
@@ -347,8 +343,7 @@
   if (!guest_)
     return;
 
-  RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
-      guest_->GetEmbedderRenderWidgetHostView());
+  RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
   if (!rwhv)
     return;
   ViewHostMsg_SelectionBounds_Params guest_params(params);
@@ -363,8 +358,7 @@
   if (!guest_)
     return;
 
-  RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
-      guest_->GetEmbedderRenderWidgetHostView());
+  RenderWidgetHostViewBase* rwhv = GetGuestRenderWidgetHostView();
   if (!rwhv)
     return;
 
@@ -402,9 +396,7 @@
 void RenderWidgetHostViewGuest::GetScreenInfo(blink::WebScreenInfo* results) {
   if (!guest_)
     return;
-  RenderWidgetHostViewPort* embedder_view =
-      RenderWidgetHostViewPort::FromRWHV(
-          guest_->GetEmbedderRenderWidgetHostView());
+  RenderWidgetHostViewBase* embedder_view = GetGuestRenderWidgetHostView();
   if (embedder_view)
     embedder_view->GetScreenInfo(results);
 }
@@ -477,6 +469,12 @@
     const gfx::Rect& target_rect,
     const SkBitmap& zoomed_bitmap) {
 }
+
+void RenderWidgetHostViewGuest::LockCompositingSurface() {
+}
+
+void RenderWidgetHostViewGuest::UnlockCompositingSurface() {
+}
 #endif  // defined(OS_ANDROID)
 
 #if defined(OS_WIN)
@@ -502,7 +500,7 @@
   return true;
 }
 
-void RenderWidgetHostViewGuest::DispatchPostponedGestureEvent(
+void RenderWidgetHostViewGuest::DispatchGestureEvent(
     ui::GestureEvent* event) {
   ForwardGestureEventToRenderer(event);
 }
@@ -572,4 +570,10 @@
   return SkBitmap::kARGB_8888_Config;
 }
 
+RenderWidgetHostViewBase*
+RenderWidgetHostViewGuest::GetGuestRenderWidgetHostView() const {
+  return static_cast<RenderWidgetHostViewBase*>(
+      guest_->GetEmbedderRenderWidgetHostView());
+}
+
 }  // namespace content
diff --git a/content/browser/frame_host/render_widget_host_view_guest.h b/content/browser/frame_host/render_widget_host_view_guest.h
index 2ac9813..2f17864 100644
--- a/content/browser/frame_host/render_widget_host_view_guest.h
+++ b/content/browser/frame_host/render_widget_host_view_guest.h
@@ -41,7 +41,7 @@
  public:
   RenderWidgetHostViewGuest(RenderWidgetHost* widget,
                             BrowserPluginGuest* guest,
-                            RenderWidgetHostView* platform_view);
+                            RenderWidgetHostViewBase* platform_view);
   virtual ~RenderWidgetHostViewGuest();
 
   // RenderWidgetHostView implementation.
@@ -57,7 +57,7 @@
   virtual gfx::Size GetPhysicalBackingSize() const OVERRIDE;
   virtual base::string16 GetSelectedText() const OVERRIDE;
 
-  // RenderWidgetHostViewPort implementation.
+  // RenderWidgetHostViewBase implementation.
   virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
                            const gfx::Rect& pos) OVERRIDE;
   virtual void InitAsFullscreen(
@@ -86,9 +86,6 @@
                                 const gfx::Range& range) OVERRIDE;
   virtual void SelectionBoundsChanged(
       const ViewHostMsg_SelectionBounds_Params& params) OVERRIDE;
-#if defined(OS_ANDROID)
-  virtual void SelectionRootBoundsChanged(const gfx::Rect& bounds) OVERRIDE;
-#endif
   virtual void CopyFromCompositingSurface(
       const gfx::Rect& src_subrect,
       const gfx::Size& dst_size,
@@ -126,15 +123,18 @@
   virtual bool IsSpeaking() const OVERRIDE;
   virtual void StopSpeaking() OVERRIDE;
 
-  // RenderWidgetHostViewPort implementation.
+  // RenderWidgetHostViewBase implementation.
   virtual bool PostProcessEventForPluginIme(
       const NativeWebKeyboardEvent& event) OVERRIDE;
 #endif  // defined(OS_MACOSX)
 
 #if defined(OS_ANDROID)
-  // RenderWidgetHostViewPort implementation.
+  // RenderWidgetHostViewBase implementation.
+  virtual void SelectionRootBoundsChanged(const gfx::Rect& bounds) OVERRIDE;
   virtual void ShowDisambiguationPopup(const gfx::Rect& target_rect,
                                        const SkBitmap& zoomed_bitmap) OVERRIDE;
+  virtual void LockCompositingSurface() OVERRIDE;
+  virtual void UnlockCompositingSurface() OVERRIDE;
 #endif  // defined(OS_ANDROID)
 
 #if defined(OS_WIN)
@@ -145,7 +145,7 @@
 
   // Overridden from ui::GestureEventHelper.
   virtual bool CanDispatchToConsumer(ui::GestureConsumer* consumer) OVERRIDE;
-  virtual void DispatchPostponedGestureEvent(ui::GestureEvent* event) OVERRIDE;
+  virtual void DispatchGestureEvent(ui::GestureEvent* event) OVERRIDE;
   virtual void DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE;
 
   virtual SkBitmap::Config PreferredReadbackFormat() OVERRIDE;
@@ -163,6 +163,8 @@
   // Process all of the given gestures (passes them on to renderer)
   void ProcessGestures(ui::GestureRecognizer::Gestures* gestures);
 
+  RenderWidgetHostViewBase* GetGuestRenderWidgetHostView() const;
+
   // BrowserPluginGuest and RenderWidgetHostViewGuest's lifetimes are not tied
   // to one another, therefore we access |guest_| through WeakPtr.
   base::WeakPtr<BrowserPluginGuest> guest_;
@@ -170,7 +172,7 @@
   // The platform view for this RenderWidgetHostView.
   // RenderWidgetHostViewGuest mostly only cares about stuff related to
   // compositing, the rest are directly forwared to this |platform_view_|.
-  RenderWidgetHostViewPort* platform_view_;
+  RenderWidgetHostViewBase* platform_view_;
 #if defined(USE_AURA)
   scoped_ptr<ui::GestureRecognizer> gesture_recognizer_;
 #endif
diff --git a/content/browser/gamepad/gamepad_consumer.h b/content/browser/gamepad/gamepad_consumer.h
new file mode 100644
index 0000000..3d07452
--- /dev/null
+++ b/content/browser/gamepad/gamepad_consumer.h
@@ -0,0 +1,29 @@
+// 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.
+
+#ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_CONSUMER_H
+#define CONTENT_BROWSER_GAMEPAD_GAMEPAD_CONSUMER_H
+
+#include "base/basictypes.h"
+#include "content/common/content_export.h"
+#include "third_party/WebKit/public/platform/WebGamepad.h"
+
+namespace content {
+
+class CONTENT_EXPORT GamepadConsumer {
+ public:
+  virtual void OnGamepadConnected(
+      unsigned index,
+      const blink::WebGamepad& gamepad) = 0;
+  virtual void OnGamepadDisconnected(
+      unsigned index,
+      const blink::WebGamepad& gamepad) = 0;
+
+ protected:
+  virtual ~GamepadConsumer() {}
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_GAMEPAD_GAMEPAD_CONSUMER_H
diff --git a/content/browser/gamepad/gamepad_provider.cc b/content/browser/gamepad/gamepad_provider.cc
index 1cc7aab..8e7644e 100644
--- a/content/browser/gamepad/gamepad_provider.cc
+++ b/content/browser/gamepad/gamepad_provider.cc
@@ -15,9 +15,14 @@
 #include "content/browser/gamepad/gamepad_data_fetcher.h"
 #include "content/browser/gamepad/gamepad_platform_data_fetcher.h"
 #include "content/browser/gamepad/gamepad_provider.h"
+#include "content/browser/gamepad/gamepad_service.h"
 #include "content/common/gamepad_hardware_buffer.h"
 #include "content/common/gamepad_messages.h"
 #include "content/common/gamepad_user_gesture.h"
+#include "content/public/browser/browser_thread.h"
+
+using blink::WebGamepad;
+using blink::WebGamepads;
 
 namespace content {
 
@@ -34,14 +39,16 @@
 GamepadProvider::GamepadProvider()
     : is_paused_(true),
       have_scheduled_do_poll_(false),
-      devices_changed_(true) {
+      devices_changed_(true),
+      ever_had_user_gesture_(false) {
   Initialize(scoped_ptr<GamepadDataFetcher>());
 }
 
 GamepadProvider::GamepadProvider(scoped_ptr<GamepadDataFetcher> fetcher)
     : is_paused_(true),
       have_scheduled_do_poll_(false),
-      devices_changed_(true) {
+      devices_changed_(true),
+      ever_had_user_gesture_(false) {
   Initialize(fetcher.Pass());
 }
 
@@ -63,6 +70,12 @@
   return renderer_handle;
 }
 
+void GamepadProvider::GetCurrentGamepadData(WebGamepads* data) {
+  const WebGamepads& pads = SharedMemoryAsHardwareBuffer()->buffer;
+  base::AutoLock lock(shared_memory_lock_);
+  *data = pads;
+}
+
 void GamepadProvider::Pause() {
   {
     base::AutoLock lock(is_paused_lock_);
@@ -111,6 +124,7 @@
   CHECK(res);
   GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer();
   memset(hwbuf, 0, sizeof(GamepadHardwareBuffer));
+  pad_states_.reset(new PadState[WebGamepads::itemsLengthCap]);
 
   polling_thread_.reset(new base::Thread("Gamepad polling thread"));
 #if defined(OS_LINUX)
@@ -148,6 +162,41 @@
     data_fetcher_->PauseHint(paused);
 }
 
+bool GamepadProvider::PadState::Match(const WebGamepad& pad) const {
+  return connected_ == pad.connected &&
+         axes_length_ == pad.axesLength &&
+         buttons_length_ == pad.buttonsLength &&
+         memcmp(id_, pad.id, arraysize(id_)) == 0 &&
+         memcmp(mapping_, pad.mapping, arraysize(mapping_)) == 0;
+}
+
+void GamepadProvider::PadState::SetPad(const WebGamepad& pad) {
+  DCHECK(pad.connected);
+  connected_ = true;
+  axes_length_ = pad.axesLength;
+  buttons_length_ = pad.buttonsLength;
+  memcpy(id_, pad.id, arraysize(id_));
+  memcpy(mapping_, pad.mapping, arraysize(mapping_));
+}
+
+void GamepadProvider::PadState::SetDisconnected() {
+  connected_ = false;
+  axes_length_ = 0;
+  buttons_length_ = 0;
+  memset(id_, 0, arraysize(id_));
+  memset(mapping_, 0, arraysize(mapping_));
+}
+
+void GamepadProvider::PadState::AsWebGamepad(WebGamepad* pad) {
+  pad->connected = connected_;
+  pad->axesLength = axes_length_;
+  pad->buttonsLength = buttons_length_;
+  memcpy(pad->id, id_, arraysize(id_));
+  memcpy(pad->mapping, mapping_, arraysize(mapping_));
+  memset(pad->axes, 0, arraysize(pad->axes));
+  memset(pad->buttons, 0, arraysize(pad->buttons));
+}
+
 void GamepadProvider::DoPoll() {
   DCHECK(base::MessageLoop::current() == polling_thread_->message_loop());
   DCHECK(have_scheduled_do_poll_);
@@ -158,7 +207,7 @@
 
   ANNOTATE_BENIGN_RACE_SIZED(
       &hwbuf->buffer,
-      sizeof(blink::WebGamepads),
+      sizeof(WebGamepads),
       "Racey reads are discarded");
 
   {
@@ -167,14 +216,35 @@
     devices_changed_ = false;
   }
 
-  // Acquire the SeqLock. There is only ever one writer to this data.
-  // See gamepad_hardware_buffer.h.
-  hwbuf->sequence.WriteBegin();
-  data_fetcher_->GetGamepadData(&hwbuf->buffer, changed);
-  hwbuf->sequence.WriteEnd();
+  {
+    base::AutoLock lock(shared_memory_lock_);
+
+    // Acquire the SeqLock. There is only ever one writer to this data.
+    // See gamepad_hardware_buffer.h.
+    hwbuf->sequence.WriteBegin();
+    data_fetcher_->GetGamepadData(&hwbuf->buffer, changed);
+    hwbuf->sequence.WriteEnd();
+  }
 
   CheckForUserGesture();
 
+  if (ever_had_user_gesture_) {
+    for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) {
+      WebGamepad& pad = hwbuf->buffer.items[i];
+      PadState& state = pad_states_.get()[i];
+      if (pad.connected && !state.connected()) {
+        OnGamepadConnectionChange(true, i, pad);
+      } else if (!pad.connected && state.connected()) {
+        OnGamepadConnectionChange(false, i, pad);
+      } else if (pad.connected && state.connected() && !state.Match(pad)) {
+        WebGamepad old_pad;
+        state.AsWebGamepad(&old_pad);
+        OnGamepadConnectionChange(false, i, old_pad);
+        OnGamepadConnectionChange(true, i, pad);
+      }
+    }
+  }
+
   // Schedule our next interval of polling.
   ScheduleDoPoll();
 }
@@ -197,6 +267,32 @@
   have_scheduled_do_poll_ = true;
 }
 
+void GamepadProvider::OnGamepadConnectionChange(
+    bool connected, int index, const WebGamepad& pad) {
+  PadState& state = pad_states_.get()[index];
+  if (connected)
+    state.SetPad(pad);
+  else
+    state.SetDisconnected();
+
+  BrowserThread::PostTask(
+      BrowserThread::IO,
+      FROM_HERE,
+      base::Bind(&GamepadProvider::DispatchGamepadConnectionChange,
+                 base::Unretained(this),
+                 connected,
+                 index,
+                 pad));
+}
+
+void GamepadProvider::DispatchGamepadConnectionChange(
+    bool connected, int index, const WebGamepad& pad) {
+  if (connected)
+    GamepadService::GetInstance()->OnGamepadConnected(index, pad);
+  else
+    GamepadService::GetInstance()->OnGamepadDisconnected(index, pad);
+}
+
 GamepadHardwareBuffer* GamepadProvider::SharedMemoryAsHardwareBuffer() {
   void* mem = gamepad_shared_memory_.memory();
   CHECK(mem);
@@ -205,10 +301,11 @@
 
 void GamepadProvider::CheckForUserGesture() {
   base::AutoLock lock(user_gesture_lock_);
-  if (user_gesture_observers_.empty())
-    return;  // Don't need to check if nobody is listening.
+  if (user_gesture_observers_.empty() && ever_had_user_gesture_)
+    return;
 
   if (GamepadsHaveUserGesture(SharedMemoryAsHardwareBuffer()->buffer)) {
+    ever_had_user_gesture_ = true;
     for (size_t i = 0; i < user_gesture_observers_.size(); i++) {
       user_gesture_observers_[i].message_loop->PostTask(FROM_HERE,
           user_gesture_observers_[i].closure);
diff --git a/content/browser/gamepad/gamepad_provider.h b/content/browser/gamepad/gamepad_provider.h
index 5f10f13..86a4b17 100644
--- a/content/browser/gamepad/gamepad_provider.h
+++ b/content/browser/gamepad/gamepad_provider.h
@@ -17,6 +17,7 @@
 #include "base/synchronization/lock.h"
 #include "base/system_monitor/system_monitor.h"
 #include "content/common/content_export.h"
+#include "third_party/WebKit/public/platform/WebGamepads.h"
 
 namespace base {
 class MessageLoopProxy;
@@ -43,6 +44,8 @@
   base::SharedMemoryHandle GetSharedMemoryHandleForProcess(
       base::ProcessHandle renderer_process);
 
+  void GetCurrentGamepadData(blink::WebGamepads* data);
+
   // Pause and resume the background polling thread. Can be called from any
   // thread.
   void Pause();
@@ -70,6 +73,13 @@
   void DoPoll();
   void ScheduleDoPoll();
 
+  void OnGamepadConnectionChange(bool connected,
+                                 int index,
+                                 const blink::WebGamepad& pad);
+  void DispatchGamepadConnectionChange(bool connected,
+                                       int index,
+                                       const blink::WebGamepad& pad);
+
   GamepadHardwareBuffer* SharedMemoryAsHardwareBuffer();
 
   // Checks the gamepad state to see if the user has interacted with it.
@@ -112,9 +122,36 @@
   base::Lock devices_changed_lock_;
   bool devices_changed_;
 
-  // When polling_thread_ is running, members below are only to be used
-  // from that thread.
+  bool ever_had_user_gesture_;
+
+  class PadState {
+   public:
+    PadState() {
+      SetDisconnected();
+    }
+
+    bool Match(const blink::WebGamepad& pad) const;
+    void SetPad(const blink::WebGamepad& pad);
+    void SetDisconnected();
+    void AsWebGamepad(blink::WebGamepad* pad);
+
+    bool connected() const { return connected_; }
+
+   private:
+    bool connected_;
+    unsigned axes_length_;
+    unsigned buttons_length_;
+    blink::WebUChar id_[blink::WebGamepad::idLengthCap];
+    blink::WebUChar mapping_[blink::WebGamepad::mappingLengthCap];
+  };
+
+  // Used to detect connections and disconnections.
+  scoped_ptr<PadState[]> pad_states_;
+
+  // Only used on the polling thread.
   scoped_ptr<GamepadDataFetcher> data_fetcher_;
+
+  base::Lock shared_memory_lock_;
   base::SharedMemory gamepad_shared_memory_;
 
   // Polling is done on this background thread.
diff --git a/content/browser/gamepad/gamepad_service.cc b/content/browser/gamepad/gamepad_service.cc
index 11a6964..a2a83b3 100644
--- a/content/browser/gamepad/gamepad_service.cc
+++ b/content/browser/gamepad/gamepad_service.cc
@@ -7,18 +7,23 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/singleton.h"
+#include "content/browser/gamepad/gamepad_consumer.h"
 #include "content/browser/gamepad/gamepad_data_fetcher.h"
 #include "content/browser/gamepad/gamepad_provider.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_process_host.h"
 
 namespace content {
 
-GamepadService::GamepadService() : num_readers_(0) {
+GamepadService::GamepadService()
+    : num_active_consumers_(0),
+      gesture_callback_pending_(false) {
 }
 
 GamepadService::GamepadService(scoped_ptr<GamepadDataFetcher> fetcher)
-    : num_readers_(0),
-      provider_(new GamepadProvider(fetcher.Pass())) {
+    : provider_(new GamepadProvider(fetcher.Pass())),
+      num_active_consumers_(0),
+      gesture_callback_pending_(false) {
   thread_checker_.DetachFromThread();
 }
 
@@ -30,28 +35,48 @@
                    LeakySingletonTraits<GamepadService> >::get();
 }
 
-void GamepadService::AddConsumer() {
+void GamepadService::ConsumerBecameActive(GamepadConsumer* consumer) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  num_readers_++;
-  DCHECK(num_readers_ > 0);
   if (!provider_)
     provider_.reset(new GamepadProvider);
-  provider_->Resume();
+
+  std::pair<ConsumerSet::iterator, bool> insert_result =
+      consumers_.insert(consumer);
+  insert_result.first->is_active = true;
+  if (!insert_result.first->did_observe_user_gesture &&
+      !gesture_callback_pending_) {
+    provider_->RegisterForUserGesture(
+          base::Bind(&GamepadService::OnUserGesture,
+                     base::Unretained(this)));
+  }
+
+  if (num_active_consumers_++ == 0)
+    provider_->Resume();
 }
 
-void GamepadService::RemoveConsumer() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+void GamepadService::ConsumerBecameInactive(GamepadConsumer* consumer) {
+  DCHECK(provider_);
+  DCHECK(num_active_consumers_ > 0);
+  DCHECK(consumers_.count(consumer) > 0);
+  DCHECK(consumers_.find(consumer)->is_active);
 
-  --num_readers_;
-  DCHECK(num_readers_ >= 0);
-
-  if (num_readers_ == 0)
+  consumers_.find(consumer)->is_active = false;
+  if (--num_active_consumers_ == 0)
     provider_->Pause();
 }
 
+void GamepadService::RemoveConsumer(GamepadConsumer* consumer) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  ConsumerSet::iterator it = consumers_.find(consumer);
+  if (it->is_active && --num_active_consumers_ == 0)
+    provider_->Pause();
+  consumers_.erase(it);
+}
+
 void GamepadService::RegisterForUserGesture(const base::Closure& closure) {
-  DCHECK(num_readers_ > 0);
+  DCHECK(consumers_.size() > 0);
   DCHECK(thread_checker_.CalledOnValidThread());
   provider_->RegisterForUserGesture(closure);
 }
@@ -60,10 +85,59 @@
   provider_.reset();
 }
 
+void GamepadService::OnGamepadConnected(
+    int index,
+    const blink::WebGamepad& pad) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  for (ConsumerSet::iterator it = consumers_.begin();
+       it != consumers_.end(); ++it) {
+    if (it->did_observe_user_gesture && it->is_active)
+      it->consumer->OnGamepadConnected(index, pad);
+  }
+}
+
+void GamepadService::OnGamepadDisconnected(
+    int index,
+    const blink::WebGamepad& pad) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  for (ConsumerSet::iterator it = consumers_.begin();
+       it != consumers_.end(); ++it) {
+    if (it->did_observe_user_gesture && it->is_active)
+      it->consumer->OnGamepadDisconnected(index, pad);
+  }
+}
+
 base::SharedMemoryHandle GamepadService::GetSharedMemoryHandleForProcess(
     base::ProcessHandle handle) {
   DCHECK(thread_checker_.CalledOnValidThread());
   return provider_->GetSharedMemoryHandleForProcess(handle);
 }
 
+void GamepadService::OnUserGesture() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  gesture_callback_pending_ = false;
+
+  if (!provider_ ||
+      num_active_consumers_ == 0)
+    return;
+
+  for (ConsumerSet::iterator it = consumers_.begin();
+       it != consumers_.end(); ++it) {
+    if (!it->did_observe_user_gesture && it->is_active) {
+      const ConsumerInfo& info = *it;
+      info.did_observe_user_gesture = true;
+      blink::WebGamepads gamepads;
+      provider_->GetCurrentGamepadData(&gamepads);
+      for (unsigned i = 0; i < blink::WebGamepads::itemsLengthCap; ++i) {
+        const blink::WebGamepad& pad = gamepads.items[i];
+        if (pad.connected)
+          info.consumer->OnGamepadConnected(i, pad);
+      }
+    }
+  }
+}
+
 }  // namespace content
diff --git a/content/browser/gamepad/gamepad_service.h b/content/browser/gamepad/gamepad_service.h
index 94620b3..6008188 100644
--- a/content/browser/gamepad/gamepad_service.h
+++ b/content/browser/gamepad/gamepad_service.h
@@ -5,6 +5,8 @@
 #ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_SERVICE_H
 #define CONTENT_BROWSER_GAMEPAD_GAMEPAD_SERVICE_H
 
+#include <set>
+
 #include "base/basictypes.h"
 #include "base/callback_forward.h"
 #include "base/memory/scoped_ptr.h"
@@ -13,8 +15,13 @@
 #include "base/threading/thread_checker.h"
 #include "content/common/content_export.h"
 
+namespace blink {
+class WebGamepad;
+}
+
 namespace content {
 
+class GamepadConsumer;
 class GamepadDataFetcher;
 class GamepadProvider;
 class GamepadServiceTestConstructor;
@@ -30,14 +37,28 @@
 
   // Increments the number of users of the provider. The Provider is running
   // when there's > 0 users, and is paused when the count drops to 0.
+  // consumer is registered to listen for gamepad connections. If this is the
+  // first time it is added to the set of consumers it will be treated
+  // specially: it will not be informed about connections before a new user
+  // gesture is observed at which point it will be notified for every connected
+  // gamepads.
   //
   // Must be called on the I/O thread.
-  void AddConsumer();
+  void ConsumerBecameActive(GamepadConsumer* consumer);
 
-  // Removes a consumer. Should be matched with an AddConsumer call.
+  // Decrements the number of users of the provider. consumer will not be
+  // informed about connections until it's added back via ConsumerBecameActive.
+  // Must be matched with a ConsumerBecameActive call.
   //
   // Must be called on the I/O thread.
-  void RemoveConsumer();
+  void ConsumerBecameInactive(GamepadConsumer* consumer);
+
+  // Decrements the number of users of the provider and removes consumer from
+  // the set of consumers. Should be matched with a a ConsumerBecameActive
+  // call.
+  //
+  // Must be called on the I/O thread.
+  void RemoveConsumer(GamepadConsumer* consumer);
 
   // Registers the given closure for calling when the user has interacted with
   // the device. This callback will only be issued once. Should only be called
@@ -52,6 +73,12 @@
   // Stop/join with the background thread in GamepadProvider |provider_|.
   void Terminate();
 
+  // Called on IO thread when a gamepad is connected.
+  void OnGamepadConnected(int index, const blink::WebGamepad& pad);
+
+  // Called on IO thread when a gamepad is disconnected.
+  void OnGamepadDisconnected(int index, const blink::WebGamepad& pad);
+
  private:
   friend struct DefaultSingletonTraits<GamepadService>;
   friend class GamepadServiceTestConstructor;
@@ -64,11 +91,34 @@
 
   virtual ~GamepadService();
 
-  int num_readers_;
+  void OnUserGesture();
+
+  struct ConsumerInfo {
+    ConsumerInfo(GamepadConsumer* consumer)
+        : consumer(consumer),
+          did_observe_user_gesture(false) {
+    }
+
+    bool operator<(const ConsumerInfo& other) const {
+      return consumer < other.consumer;
+    }
+
+    GamepadConsumer* consumer;
+    mutable bool is_active;
+    mutable bool did_observe_user_gesture;
+  };
+
   scoped_ptr<GamepadProvider> provider_;
 
   base::ThreadChecker thread_checker_;
 
+  typedef std::set<ConsumerInfo> ConsumerSet;
+  ConsumerSet consumers_;
+
+  int num_active_consumers_;
+
+  bool gesture_callback_pending_;
+
   DISALLOW_COPY_AND_ASSIGN(GamepadService);
 };
 
diff --git a/content/browser/geolocation/geolocation_dispatcher_host.cc b/content/browser/geolocation/geolocation_dispatcher_host.cc
index 9502382..5479446 100644
--- a/content/browser/geolocation/geolocation_dispatcher_host.cc
+++ b/content/browser/geolocation/geolocation_dispatcher_host.cc
@@ -4,13 +4,10 @@
 
 #include "content/browser/geolocation/geolocation_dispatcher_host.h"
 
-#include <map>
-#include <set>
 #include <utility>
 
 #include "base/bind.h"
 #include "base/metrics/histogram.h"
-#include "content/browser/geolocation/geolocation_provider_impl.h"
 #include "content/browser/renderer_host/render_message_filter.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
@@ -88,96 +85,34 @@
   }
 }
 
-class GeolocationDispatcherHostImpl : public GeolocationDispatcherHost {
- public:
-  GeolocationDispatcherHostImpl(
-      int render_process_id,
-      GeolocationPermissionContext* geolocation_permission_context);
+}  // namespace
 
-  // GeolocationDispatcherHost
-  virtual bool OnMessageReceived(const IPC::Message& msg,
-                                 bool* msg_was_ok) OVERRIDE;
-
- private:
-  virtual ~GeolocationDispatcherHostImpl();
-
-  void OnRequestPermission(int render_view_id,
-                           int bridge_id,
-                           const GURL& requesting_frame,
-                           bool user_gesture);
-  void OnCancelPermissionRequest(int render_view_id,
-                                 int bridge_id,
-                                 const GURL& requesting_frame);
-  void OnStartUpdating(int render_view_id,
-                       const GURL& requesting_frame,
-                       bool enable_high_accuracy);
-  void OnStopUpdating(int render_view_id);
-
-
-  virtual void PauseOrResume(int render_view_id, bool should_pause) OVERRIDE;
-
-  // Updates the |geolocation_provider_| with the currently required update
-  // options.
-  void RefreshGeolocationOptions();
-
-  void OnLocationUpdate(const Geoposition& position);
-
-  int render_process_id_;
-  scoped_refptr<GeolocationPermissionContext> geolocation_permission_context_;
-
-  struct RendererGeolocationOptions {
-    bool high_accuracy;
-    bool is_paused;
-  };
-
-  // Used to keep track of the renderers in this process that are using
-  // geolocation and the options associated with them. The map is iterated
-  // when a location update is available and the fan out to individual bridge
-  // IDs happens renderer side, in order to minimize context switches.
-  // Only used on the IO thread.
-  std::map<int, RendererGeolocationOptions> geolocation_renderers_;
-
-  // Used by Android WebView to support that case that a renderer is in the
-  // 'paused' state but not yet using geolocation. If the renderer does start
-  // using geolocation while paused, we move from this set into
-  // |geolocation_renderers_|. If the renderer doesn't end up wanting to use
-  // geolocation while 'paused' then we remove from this set. A renderer id
-  // can exist only in this set or |geolocation_renderers_|, never both.
-  std::set<int> pending_paused_geolocation_renderers_;
-
-  // Only set whilst we are registered with the geolocation provider.
-  GeolocationProviderImpl* geolocation_provider_;
-
-  GeolocationProviderImpl::LocationUpdateCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(GeolocationDispatcherHostImpl);
-};
-
-GeolocationDispatcherHostImpl::GeolocationDispatcherHostImpl(
+GeolocationDispatcherHost::GeolocationDispatcherHost(
     int render_process_id,
     GeolocationPermissionContext* geolocation_permission_context)
-    : render_process_id_(render_process_id),
+    : BrowserMessageFilter(GeolocationMsgStart),
+      render_process_id_(render_process_id),
       geolocation_permission_context_(geolocation_permission_context),
       geolocation_provider_(NULL) {
   callback_ = base::Bind(
-      &GeolocationDispatcherHostImpl::OnLocationUpdate, base::Unretained(this));
+      &GeolocationDispatcherHost::OnLocationUpdate, base::Unretained(this));
   // This is initialized by ResourceMessageFilter. Do not add any non-trivial
   // initialization here, defer to OnRegisterBridge which is triggered whenever
   // a javascript geolocation object is actually initialized.
 }
 
-GeolocationDispatcherHostImpl::~GeolocationDispatcherHostImpl() {
+GeolocationDispatcherHost::~GeolocationDispatcherHost() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (geolocation_provider_)
     geolocation_provider_->RemoveLocationUpdateCallback(callback_);
 }
 
-bool GeolocationDispatcherHostImpl::OnMessageReceived(
+bool GeolocationDispatcherHost::OnMessageReceived(
     const IPC::Message& msg, bool* msg_was_ok) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   *msg_was_ok = true;
   bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP_EX(GeolocationDispatcherHostImpl, msg, *msg_was_ok)
+  IPC_BEGIN_MESSAGE_MAP_EX(GeolocationDispatcherHost, msg, *msg_was_ok)
     IPC_MESSAGE_HANDLER(GeolocationHostMsg_CancelPermissionRequest,
                         OnCancelPermissionRequest)
     IPC_MESSAGE_HANDLER(GeolocationHostMsg_RequestPermission,
@@ -189,7 +124,7 @@
   return handled;
 }
 
-void GeolocationDispatcherHostImpl::OnLocationUpdate(
+void GeolocationDispatcherHost::OnLocationUpdate(
     const Geoposition& geoposition) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   RecordGeopositionErrorCode(geoposition.error_code);
@@ -201,7 +136,7 @@
   }
 }
 
-void GeolocationDispatcherHostImpl::OnRequestPermission(
+void GeolocationDispatcherHost::OnRequestPermission(
     int render_view_id,
     int bridge_id,
     const GURL& requesting_frame,
@@ -228,7 +163,7 @@
   }
 }
 
-void GeolocationDispatcherHostImpl::OnCancelPermissionRequest(
+void GeolocationDispatcherHost::OnCancelPermissionRequest(
     int render_view_id,
     int bridge_id,
     const GURL& requesting_frame) {
@@ -241,7 +176,7 @@
   }
 }
 
-void GeolocationDispatcherHostImpl::OnStartUpdating(
+void GeolocationDispatcherHost::OnStartUpdating(
     int render_view_id,
     const GURL& requesting_frame,
     bool enable_high_accuracy) {
@@ -272,7 +207,7 @@
   RefreshGeolocationOptions();
 }
 
-void GeolocationDispatcherHostImpl::OnStopUpdating(int render_view_id) {
+void GeolocationDispatcherHost::OnStopUpdating(int render_view_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":"
            << render_view_id;
@@ -281,8 +216,8 @@
   RefreshGeolocationOptions();
 }
 
-void GeolocationDispatcherHostImpl::PauseOrResume(int render_view_id,
-                                                  bool should_pause) {
+void GeolocationDispatcherHost::PauseOrResume(int render_view_id,
+                                              bool should_pause) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   std::map<int, RendererGeolocationOptions>::iterator it =
       geolocation_renderers_.find(render_view_id);
@@ -302,7 +237,7 @@
   }
 }
 
-void GeolocationDispatcherHostImpl::RefreshGeolocationOptions() {
+void GeolocationDispatcherHost::RefreshGeolocationOptions() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
   bool needs_updates = false;
@@ -328,25 +263,4 @@
   }
 }
 
-}  // namespace
-
-
-// GeolocationDispatcherHost --------------------------------------------------
-
-// static
-GeolocationDispatcherHost* GeolocationDispatcherHost::New(
-    int render_process_id,
-    GeolocationPermissionContext* geolocation_permission_context) {
-  return new GeolocationDispatcherHostImpl(
-      render_process_id,
-      geolocation_permission_context);
-}
-
-GeolocationDispatcherHost::GeolocationDispatcherHost()
-    : BrowserMessageFilter(GeolocationMsgStart) {
-}
-
-GeolocationDispatcherHost::~GeolocationDispatcherHost() {
-}
-
 }  // namespace content
diff --git a/content/browser/geolocation/geolocation_dispatcher_host.h b/content/browser/geolocation/geolocation_dispatcher_host.h
index 5620e26..28c6003 100644
--- a/content/browser/geolocation/geolocation_dispatcher_host.h
+++ b/content/browser/geolocation/geolocation_dispatcher_host.h
@@ -5,8 +5,14 @@
 #ifndef CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_
 #define CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_
 
+#include <map>
+#include <set>
+
+#include "content/browser/geolocation/geolocation_provider_impl.h"
 #include "content/public/browser/browser_message_filter.h"
 
+class GURL;
+
 namespace content {
 
 class GeolocationPermissionContext;
@@ -15,7 +21,7 @@
 // It's the complement of GeolocationDispatcher (owned by RenderView).
 class GeolocationDispatcherHost : public BrowserMessageFilter {
  public:
-  static GeolocationDispatcherHost* New(
+  GeolocationDispatcherHost(
       int render_process_id,
       GeolocationPermissionContext* geolocation_permission_context);
 
@@ -24,12 +30,62 @@
   // If a renderer is paused while not currently using geolocation but
   // then goes on to do so before being resumed, then that renderer will
   // not get geolocation updates until it is resumed.
-  virtual void PauseOrResume(int render_view_id, bool should_pause) = 0;
+  void PauseOrResume(int render_view_id, bool should_pause);
 
- protected:
-  GeolocationDispatcherHost();
+ private:
   virtual ~GeolocationDispatcherHost();
 
+  // GeolocationDispatcherHost
+  virtual bool OnMessageReceived(const IPC::Message& msg,
+                                 bool* msg_was_ok) OVERRIDE;
+
+  // Message handlers:
+  void OnRequestPermission(int render_view_id,
+                           int bridge_id,
+                           const GURL& requesting_frame,
+                           bool user_gesture);
+  void OnCancelPermissionRequest(int render_view_id,
+                                 int bridge_id,
+                                 const GURL& requesting_frame);
+  void OnStartUpdating(int render_view_id,
+                       const GURL& requesting_frame,
+                       bool enable_high_accuracy);
+  void OnStopUpdating(int render_view_id);
+
+  // Updates the |geolocation_provider_| with the currently required update
+  // options.
+  void RefreshGeolocationOptions();
+
+  void OnLocationUpdate(const Geoposition& position);
+
+  int render_process_id_;
+  scoped_refptr<GeolocationPermissionContext> geolocation_permission_context_;
+
+  struct RendererGeolocationOptions {
+    bool high_accuracy;
+    bool is_paused;
+  };
+
+  // Used to keep track of the renderers in this process that are using
+  // geolocation and the options associated with them. The map is iterated
+  // when a location update is available and the fan out to individual bridge
+  // IDs happens renderer side, in order to minimize context switches.
+  // Only used on the IO thread.
+  std::map<int, RendererGeolocationOptions> geolocation_renderers_;
+
+  // Used by Android WebView to support that case that a renderer is in the
+  // 'paused' state but not yet using geolocation. If the renderer does start
+  // using geolocation while paused, we move from this set into
+  // |geolocation_renderers_|. If the renderer doesn't end up wanting to use
+  // geolocation while 'paused' then we remove from this set. A renderer id
+  // can exist only in this set or |geolocation_renderers_|, never both.
+  std::set<int> pending_paused_geolocation_renderers_;
+
+  // Only set whilst we are registered with the geolocation provider.
+  GeolocationProviderImpl* geolocation_provider_;
+
+  GeolocationProviderImpl::LocationUpdateCallback callback_;
+
   DISALLOW_COPY_AND_ASSIGN(GeolocationDispatcherHost);
 };
 
diff --git a/content/browser/geolocation/location_arbitrator_impl.h b/content/browser/geolocation/location_arbitrator_impl.h
index e756f5e..da20e7b 100644
--- a/content/browser/geolocation/location_arbitrator_impl.h
+++ b/content/browser/geolocation/location_arbitrator_impl.h
@@ -11,8 +11,8 @@
 #include "base/time/time.h"
 #include "content/browser/geolocation/location_arbitrator.h"
 #include "content/common/content_export.h"
-#include "content/port/browser/location_provider.h"
 #include "content/public/browser/access_token_store.h"
+#include "content/public/browser/location_provider.h"
 #include "content/public/common/geoposition.h"
 #include "net/url_request/url_request_context_getter.h"
 
diff --git a/content/browser/geolocation/location_provider_base.h b/content/browser/geolocation/location_provider_base.h
index dbc4240..36d900b 100644
--- a/content/browser/geolocation/location_provider_base.h
+++ b/content/browser/geolocation/location_provider_base.h
@@ -6,7 +6,7 @@
 #define CONTENT_BROWSER_GEOLOCATION_LOCATION_PROVIDER_H_
 
 #include "content/common/content_export.h"
-#include "content/port/browser/location_provider.h"
+#include "content/public/browser/location_provider.h"
 
 namespace content {
 
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc
index a006f1e..715eb20 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -11,7 +11,7 @@
 #include "content/browser/gpu/gpu_process_host.h"
 #include "content/browser/gpu/gpu_surface_tracker.h"
 #include "content/common/child_process_host_impl.h"
-#include "content/common/gpu/client/gpu_memory_buffer_impl_shm.h"
+#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
 #include "content/common/gpu/gpu_messages.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/gpu_data_manager.h"
@@ -376,25 +376,17 @@
 }
 
 scoped_ptr<gfx::GpuMemoryBuffer>
-    BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer(
-        size_t width,
-        size_t height,
-        unsigned internalformat) {
-  if (!GpuMemoryBufferImpl::IsFormatValid(internalformat))
+BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer(size_t width,
+                                                      size_t height,
+                                                      unsigned internalformat,
+                                                      unsigned usage) {
+  if (!GpuMemoryBufferImpl::IsFormatValid(internalformat) ||
+      !GpuMemoryBufferImpl::IsUsageValid(usage))
     return scoped_ptr<gfx::GpuMemoryBuffer>();
 
-  size_t size = width * height *
-      GpuMemoryBufferImpl::BytesPerPixel(internalformat);
-  scoped_ptr<base::SharedMemory> shm(new base::SharedMemory());
-  if (!shm->CreateAnonymous(size))
-    return scoped_ptr<gfx::GpuMemoryBuffer>();
-
-  scoped_ptr<GpuMemoryBufferImplShm> buffer(
-      new GpuMemoryBufferImplShm(gfx::Size(width, height), internalformat));
-  if (!buffer->InitializeFromSharedMemory(shm.Pass()))
-    return scoped_ptr<gfx::GpuMemoryBuffer>();
-
-  return buffer.PassAs<gfx::GpuMemoryBuffer>();
+  return GpuMemoryBufferImpl::Create(gfx::Size(width, height),
+                                     internalformat,
+                                     usage).PassAs<gfx::GpuMemoryBuffer>();
 }
 
 // static
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h
index 0dc71a8..e94db42 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.h
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -42,7 +42,8 @@
   virtual scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer(
       size_t width,
       size_t height,
-      unsigned internalformat) OVERRIDE;
+      unsigned internalformat,
+      unsigned usage) OVERRIDE;
 
   // Specify a task runner and callback to be used for a set of messages. The
   // callback will be set up on the current GpuProcessHost, identified by
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc
index ef68964..c2912a3 100644
--- a/content/browser/gpu/compositor_util.cc
+++ b/content/browser/gpu/compositor_util.cc
@@ -204,7 +204,11 @@
       switches::kEnableBleedingEdgeRenderingFastPaths))
     return true;
 
+#if defined(OS_MACOSX)
+  return false;
+#else
   return IsThreadedCompositingEnabled();
+#endif
 }
 
 bool IsGpuRasterizationEnabled() {
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc
index 96c403d..2c5b91e 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -237,9 +237,12 @@
 
 #if defined(OS_ANDROID)
 void ApplyAndroidWorkarounds(const gpu::GPUInfo& gpu_info,
-                             CommandLine* command_line) {
+                             CommandLine* command_line,
+                             std::set<int>* workarounds) {
   std::string vendor(StringToLowerASCII(gpu_info.gl_vendor));
   std::string renderer(StringToLowerASCII(gpu_info.gl_renderer));
+  std::string version(StringToLowerASCII(gpu_info.gl_version));
+
   bool is_img =
       gpu_info.gl_vendor.find("Imagination") != std::string::npos;
 
@@ -516,14 +519,14 @@
   // situation where GPU process collected GL strings before this call.
   if (!gpu_info_.gl_vendor.empty() ||
       !gpu_info_.gl_renderer.empty() ||
-      !gpu_info_.gl_version_string.empty())
+      !gpu_info_.gl_version.empty())
     return;
 
   gpu::GPUInfo gpu_info = gpu_info_;
 
   gpu_info.gl_vendor = gl_vendor;
   gpu_info.gl_renderer = gl_renderer;
-  gpu_info.gl_version_string = gl_version;
+  gpu_info.gl_version = gl_version;
 
   gpu::CollectDriverInfoGL(&gpu_info);
 
@@ -539,7 +542,7 @@
 
   *gl_vendor = gpu_info_.gl_vendor;
   *gl_renderer = gpu_info_.gl_renderer;
-  *gl_version = gpu_info_.gl_version_string;
+  *gl_version = gpu_info_.gl_version;
 }
 
 void GpuDataManagerImplPrivate::Initialize() {
@@ -988,7 +991,8 @@
   UpdatePreliminaryBlacklistedFeatures();
 
 #if defined(OS_ANDROID)
-  ApplyAndroidWorkarounds(gpu_info, CommandLine::ForCurrentProcess());
+  ApplyAndroidWorkarounds(
+      gpu_info, CommandLine::ForCurrentProcess(), &gpu_driver_bugs_);
 #endif  // OS_ANDROID
 }
 
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc
index 86f4ce3..9979116 100644
--- a/content/browser/gpu/gpu_internals_ui.cc
+++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -143,14 +143,12 @@
                                              gpu_info.machine_model_name));
   basic_info->Append(NewDescriptionValuePair("Machine model version",
                                              gpu_info.machine_model_version));
-  basic_info->Append(NewDescriptionValuePair("GL version",
-                                             gpu_info.gl_version));
   basic_info->Append(NewDescriptionValuePair("GL_VENDOR",
                                              gpu_info.gl_vendor));
   basic_info->Append(NewDescriptionValuePair("GL_RENDERER",
                                              gpu_info.gl_renderer));
   basic_info->Append(NewDescriptionValuePair("GL_VERSION",
-                                             gpu_info.gl_version_string));
+                                             gpu_info.gl_version));
   basic_info->Append(NewDescriptionValuePair("GL_EXTENSIONS",
                                              gpu_info.gl_extensions));
   basic_info->Append(NewDescriptionValuePair("Window system binding vendor",
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 3af8424..008987a 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -25,11 +25,11 @@
 #include "content/common/child_process_host_impl.h"
 #include "content/common/gpu/gpu_messages.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_widget_host_view.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/result_codes.h"
@@ -917,7 +917,6 @@
   static const char* const kSwitchNames[] = {
     switches::kDisableAcceleratedVideoDecode,
     switches::kDisableBreakpad,
-    switches::kDisableGLDrawingForTests,
     switches::kDisableGpuSandbox,
     switches::kDisableGpuWatchdog,
     switches::kDisableLogging,
diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc
index 8c14648..0ef8439 100644
--- a/content/browser/gpu/gpu_process_host_ui_shim.cc
+++ b/content/browser/gpu/gpu_process_host_ui_shim.cc
@@ -17,8 +17,8 @@
 #include "content/browser/gpu/gpu_surface_tracker.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/common/gpu/gpu_messages.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/browser_thread.h"
 #include "ui/gl/gl_switches.h"
 
@@ -68,7 +68,7 @@
   bool cancelled_;
 };
 
-RenderWidgetHostViewPort* GetRenderWidgetHostViewFromSurfaceID(
+RenderWidgetHostViewBase* GetRenderWidgetHostViewFromSurfaceID(
     int surface_id) {
   int render_process_id = 0;
   int render_widget_id = 0;
@@ -78,7 +78,7 @@
 
   RenderWidgetHost* host =
       RenderWidgetHost::FromID(render_process_id, render_widget_id);
-  return host ? RenderWidgetHostViewPort::FromRWHV(host->GetView()) : NULL;
+  return host ? static_cast<RenderWidgetHostViewBase*>(host->GetView()) : NULL;
 }
 
 }  // namespace
@@ -238,7 +238,7 @@
 
 void GpuProcessHostUIShim::OnAcceleratedSurfaceInitialized(int32 surface_id,
                                                            int32 route_id) {
-  RenderWidgetHostViewPort* view =
+  RenderWidgetHostViewBase* view =
       GetRenderWidgetHostViewFromSurfaceID(surface_id);
   if (!view)
     return;
@@ -260,7 +260,7 @@
       new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
                                                 ack_params));
 
-  RenderWidgetHostViewPort* view = GetRenderWidgetHostViewFromSurfaceID(
+  RenderWidgetHostViewBase* view = GetRenderWidgetHostViewFromSurfaceID(
       params.surface_id);
   if (!view)
     return;
@@ -302,7 +302,7 @@
       new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
                                                 ack_params));
 
-  RenderWidgetHostViewPort* view =
+  RenderWidgetHostViewBase* view =
       GetRenderWidgetHostViewFromSurfaceID(params.surface_id);
   if (!view)
     return;
@@ -325,7 +325,7 @@
   TRACE_EVENT0("renderer",
       "GpuProcessHostUIShim::OnAcceleratedSurfaceSuspend");
 
-  RenderWidgetHostViewPort* view =
+  RenderWidgetHostViewBase* view =
       GetRenderWidgetHostViewFromSurfaceID(surface_id);
   if (!view)
     return;
@@ -335,7 +335,7 @@
 
 void GpuProcessHostUIShim::OnAcceleratedSurfaceRelease(
     const GpuHostMsg_AcceleratedSurfaceRelease_Params& params) {
-  RenderWidgetHostViewPort* view = GetRenderWidgetHostViewFromSurfaceID(
+  RenderWidgetHostViewBase* view = GetRenderWidgetHostViewFromSurfaceID(
       params.surface_id);
   if (!view)
     return;
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc
index dd539de..4972632 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -126,6 +126,8 @@
   GET_DATABASE_NAMES,
   DELETE_INDEX,
   CLEAR_OBJECT_STORE,
+  READ_BLOB_JOURNAL,
+  DECODE_BLOB_JOURNAL,
   INTERNAL_ERROR_MAX,
 };
 
@@ -192,6 +194,10 @@
   return leveldb::Status::InvalidArgument("Invalid database key ID");
 }
 
+static leveldb::Status IOErrorStatus() {
+  return leveldb::Status::IOError("IO Error");
+}
+
 template <typename DBOrTransaction>
 static leveldb::Status GetInt(DBOrTransaction* db,
                               const StringPiece& key,
@@ -474,6 +480,99 @@
   }
 };
 
+// TODO(ericu): Error recovery. If we persistently can't read the
+// blob journal, the safe thing to do is to clear it and leak the blobs,
+// though that may be costly. Still, database/directory deletion should always
+// clean things up, and we can write an fsck that will do a full correction if
+// need be.
+template <typename T>
+static leveldb::Status GetBlobJournal(const StringPiece& leveldb_key,
+                                      T* leveldb_transaction,
+                                      BlobJournalType* journal) {
+  std::string data;
+  bool found = false;
+  leveldb::Status s = leveldb_transaction->Get(leveldb_key, &data, &found);
+  if (!s.ok()) {
+    INTERNAL_READ_ERROR_UNTESTED(READ_BLOB_JOURNAL);
+    return s;
+  }
+  journal->clear();
+  if (!found || !data.size())
+    return leveldb::Status::OK();
+  StringPiece slice(data);
+  if (!DecodeBlobJournal(&slice, journal)) {
+    INTERNAL_READ_ERROR_UNTESTED(DECODE_BLOB_JOURNAL);
+    s = InternalInconsistencyStatus();
+  }
+  return s;
+}
+
+static void ClearBlobJournal(LevelDBTransaction* leveldb_transaction,
+                             const std::string& level_db_key) {
+  leveldb_transaction->Remove(level_db_key);
+}
+
+static void UpdatePrimaryJournalWithBlobList(
+    LevelDBTransaction* leveldb_transaction,
+    const BlobJournalType& journal) {
+  const std::string leveldb_key = BlobJournalKey::Encode();
+  std::string data;
+  EncodeBlobJournal(journal, &data);
+  leveldb_transaction->Put(leveldb_key, &data);
+}
+
+static void UpdateLiveBlobJournalWithBlobList(
+    LevelDBTransaction* leveldb_transaction,
+    const BlobJournalType& journal) {
+  const std::string leveldb_key = LiveBlobJournalKey::Encode();
+  std::string data;
+  EncodeBlobJournal(journal, &data);
+  leveldb_transaction->Put(leveldb_key, &data);
+}
+
+static leveldb::Status MergeBlobsIntoLiveBlobJournal(
+    LevelDBTransaction* leveldb_transaction,
+    const BlobJournalType& journal) {
+  BlobJournalType old_journal;
+  const std::string key = LiveBlobJournalKey::Encode();
+  leveldb::Status s = GetBlobJournal(key, leveldb_transaction, &old_journal);
+  if (!s.ok())
+    return s;
+
+  old_journal.insert(old_journal.end(), journal.begin(), journal.end());
+
+  UpdateLiveBlobJournalWithBlobList(leveldb_transaction, old_journal);
+  return leveldb::Status::OK();
+}
+
+static void UpdateBlobJournalWithDatabase(
+    LevelDBDirectTransaction* leveldb_transaction,
+    int64 database_id) {
+  BlobJournalType journal;
+  journal.push_back(
+      std::make_pair(database_id, DatabaseMetaDataKey::kAllBlobsKey));
+  const std::string key = BlobJournalKey::Encode();
+  std::string data;
+  EncodeBlobJournal(journal, &data);
+  leveldb_transaction->Put(key, &data);
+}
+
+static leveldb::Status MergeDatabaseIntoLiveBlobJournal(
+    LevelDBDirectTransaction* leveldb_transaction,
+    int64 database_id) {
+  BlobJournalType journal;
+  const std::string key = LiveBlobJournalKey::Encode();
+  leveldb::Status s = GetBlobJournal(key, leveldb_transaction, &journal);
+  if (!s.ok())
+    return s;
+  journal.push_back(
+      std::make_pair(database_id, DatabaseMetaDataKey::kAllBlobsKey));
+  std::string data;
+  EncodeBlobJournal(journal, &data);
+  leveldb_transaction->Put(key, &data);
+  return leveldb::Status::OK();
+}
+
 IndexedDBBackingStore::IndexedDBBackingStore(
     IndexedDBFactory* indexed_db_factory,
     const GURL& origin_url,
@@ -713,7 +812,7 @@
 
   scoped_ptr<LevelDBComparator> comparator(new Comparator());
 
-  if (!IsStringASCII(path_base.AsUTF8Unsafe())) {
+  if (!base::IsStringASCII(path_base.AsUTF8Unsafe())) {
     HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII,
                         origin_url);
   }
@@ -1098,6 +1197,18 @@
   const std::string key = DatabaseNameKey::Encode(origin_identifier_, name);
   transaction->Remove(key);
 
+  // TODO(ericu): Put the real calls to the blob journal code here.  For now,
+  // I've inserted fake calls so that we don't get "you didn't use this static
+  // function" compiler errors.
+  if (false) {
+    scoped_refptr<LevelDBTransaction> fake_transaction =
+        new LevelDBTransaction(NULL);
+    BlobJournalType fake_journal;
+    MergeDatabaseIntoLiveBlobJournal(transaction.get(), metadata.id);
+    UpdateBlobJournalWithDatabase(transaction.get(), metadata.id);
+    MergeBlobsIntoLiveBlobJournal(fake_transaction.get(), fake_journal);
+  }
+
   s = transaction->Commit();
   if (!s.ok()) {
     INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE);
@@ -1861,7 +1972,8 @@
             task_runner_, file_path, 0,
             fileapi::FileStreamWriter::CREATE_NEW_FILE));
     scoped_ptr<FileWriterDelegate> delegate(
-        new FileWriterDelegate(writer.Pass()));
+        new FileWriterDelegate(writer.Pass(),
+                               FileWriterDelegate::FLUSH_ON_COMPLETION));
 
     DCHECK(blob_url.is_valid());
     scoped_ptr<net::URLRequest> blob_request(request_context->CreateRequest(
@@ -1934,6 +2046,85 @@
   return true;
 }
 
+void IndexedDBBackingStore::ReportBlobUnused(int64 database_id,
+                                             int64 blob_key) {
+  DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
+  bool all_blobs = blob_key == DatabaseMetaDataKey::kAllBlobsKey;
+  DCHECK(all_blobs || DatabaseMetaDataKey::IsValidBlobKey(blob_key));
+  scoped_refptr<LevelDBTransaction> transaction =
+      new LevelDBTransaction(db_.get());
+
+  std::string live_blob_key = LiveBlobJournalKey::Encode();
+  BlobJournalType live_blob_journal;
+  if (!GetBlobJournal(live_blob_key, transaction.get(), &live_blob_journal)
+           .ok())
+    return;
+  DCHECK(live_blob_journal.size());
+
+  std::string primary_key = BlobJournalKey::Encode();
+  BlobJournalType primary_journal;
+  if (!GetBlobJournal(primary_key, transaction.get(), &primary_journal).ok())
+    return;
+
+  // There are several cases to handle.  If blob_key is kAllBlobsKey, we want to
+  // remove all entries with database_id from the live_blob journal and add only
+  // kAllBlobsKey to the primary journal.  Otherwise if IsValidBlobKey(blob_key)
+  // and we hit kAllBlobsKey for the right database_id in the journal, we leave
+  // the kAllBlobsKey entry in the live_blob journal but add the specific blob
+  // to the primary.  Otherwise if IsValidBlobKey(blob_key) and we find a
+  // matching (database_id, blob_key) tuple, we should move it to the primary
+  // journal.
+  BlobJournalType new_live_blob_journal;
+  for (BlobJournalType::iterator journal_iter = live_blob_journal.begin();
+       journal_iter != live_blob_journal.end();
+       ++journal_iter) {
+    int64 current_database_id = journal_iter->first;
+    int64 current_blob_key = journal_iter->second;
+    bool current_all_blobs =
+        current_blob_key == DatabaseMetaDataKey::kAllBlobsKey;
+    DCHECK(KeyPrefix::IsValidDatabaseId(current_database_id) ||
+           current_all_blobs);
+    if (current_database_id == database_id &&
+        (all_blobs || current_all_blobs || blob_key == current_blob_key)) {
+      if (!all_blobs) {
+        primary_journal.push_back(
+            std::make_pair(database_id, current_blob_key));
+        if (current_all_blobs)
+          new_live_blob_journal.push_back(*journal_iter);
+        new_live_blob_journal.insert(new_live_blob_journal.end(),
+                                     ++journal_iter,
+                                     live_blob_journal.end());  // All the rest.
+        break;
+      }
+    } else {
+      new_live_blob_journal.push_back(*journal_iter);
+    }
+  }
+  if (all_blobs) {
+    primary_journal.push_back(
+        std::make_pair(database_id, DatabaseMetaDataKey::kAllBlobsKey));
+  }
+  UpdatePrimaryJournalWithBlobList(transaction.get(), primary_journal);
+  UpdateLiveBlobJournalWithBlobList(transaction.get(), new_live_blob_journal);
+  transaction->Commit();
+  // We could just do the deletions/cleaning here, but if there are a lot of
+  // blobs about to be garbage collected, it'd be better to wait and do them all
+  // at once.
+  StartJournalCleaningTimer();
+}
+
+// The this reference is a raw pointer that's declared Unretained inside the
+// timer code, so this won't confuse IndexedDBFactory's check for
+// HasLastBackingStoreReference.  It's safe because if the backing store is
+// deleted, the timer will automatically be canceled on destruction.
+void IndexedDBBackingStore::StartJournalCleaningTimer() {
+  journal_cleaning_timer_.Start(
+      FROM_HERE,
+      base::TimeDelta::FromSeconds(5),
+      this,
+      &IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn);
+}
+
 // This assumes a file path of dbId/second-to-LSB-of-counter/counter.
 FilePath IndexedDBBackingStore::GetBlobFileName(int64 database_id, int64 key) {
   return GetBlobFileNameForKey(blob_path_, database_id, key);
@@ -2065,6 +2256,40 @@
   return base::DeleteFile(dirName, true);
 }
 
+leveldb::Status IndexedDBBackingStore::CleanUpBlobJournal(
+    const std::string& level_db_key) {
+  scoped_refptr<LevelDBTransaction> journal_transaction =
+      new LevelDBTransaction(db_.get());
+  BlobJournalType journal;
+  leveldb::Status s =
+      GetBlobJournal(level_db_key, journal_transaction.get(), &journal);
+  if (!s.ok())
+    return s;
+  if (!journal.size())
+    return leveldb::Status::OK();
+  BlobJournalType::iterator journal_iter;
+  for (journal_iter = journal.begin(); journal_iter != journal.end();
+       ++journal_iter) {
+    int64 database_id = journal_iter->first;
+    int64 blob_key = journal_iter->second;
+    DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
+    if (blob_key == DatabaseMetaDataKey::kAllBlobsKey) {
+      if (!RemoveBlobDirectory(database_id))
+        return IOErrorStatus();
+    } else {
+      DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key));
+      if (!RemoveBlobFile(database_id, blob_key))
+        return IOErrorStatus();
+    }
+  }
+  ClearBlobJournal(journal_transaction.get(), level_db_key);
+  return journal_transaction->Commit();
+}
+
+void IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn() {
+  CleanUpBlobJournal(BlobJournalKey::Encode());
+}
+
 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId(
     LevelDBTransaction* transaction,
     int64 database_id,
@@ -2382,11 +2607,6 @@
     return InvalidDBKeyStatus();
 }
 
-void IndexedDBBackingStore::ReportBlobUnused(int64 database_id,
-                                             int64 blob_key) {
-  // TODO(ericu)
-}
-
 IndexedDBBackingStore::Cursor::Cursor(
     const IndexedDBBackingStore::Cursor* other)
     : transaction_(other->transaction_),
diff --git a/content/browser/indexed_db/indexed_db_backing_store.h b/content/browser/indexed_db/indexed_db_backing_store.h
index efefc1f..386e296 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.h
+++ b/content/browser/indexed_db/indexed_db_backing_store.h
@@ -370,7 +370,7 @@
     }
     void PutBlobInfo(int64 database_id,
                      int64 object_store_id,
-                     const std::string& key,
+                     const std::string& object_store_data_key,
                      std::vector<IndexedDBBlobInfo>*,
                      ScopedVector<webkit_blob::BlobDataHandle>* handles);
 
@@ -471,6 +471,8 @@
       const Transaction::WriteDescriptor& descriptor,
       Transaction::ChainedBlobWriter* chained_blob_writer);
   virtual bool RemoveBlobFile(int64 database_id, int64 key);
+  virtual void StartJournalCleaningTimer();
+  void CleanPrimaryJournalIgnoreReturn();
 
  private:
   static scoped_refptr<IndexedDBBackingStore> Create(
@@ -499,6 +501,7 @@
                              IndexedDBObjectStoreMetadata::IndexMap* map)
       WARN_UNUSED_RESULT;
   bool RemoveBlobDirectory(int64 database_id);
+  leveldb::Status CleanUpBlobJournal(const std::string& level_db_key);
 
   IndexedDBFactory* indexed_db_factory_;
   const GURL origin_url_;
@@ -515,6 +518,7 @@
   net::URLRequestContext* request_context_;
   base::TaskRunner* task_runner_;
   std::set<int> child_process_ids_granted_;
+  base::OneShotTimer<IndexedDBBackingStore> journal_cleaning_timer_;
 
   scoped_ptr<LevelDBDatabase> db_;
   scoped_ptr<LevelDBComparator> comparator_;
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc
index 236158b..e69296e 100644
--- a/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -607,8 +607,7 @@
 };
 
 // Crashing on Android due to kSingleProcess flag: http://crbug.com/342525
-// Also disabled in debug due to flakiness: http://crbug.com/368134
-#if defined(OS_ANDROID) || !defined(NDEBUG)
+#if defined(OS_ANDROID)
 #define MAYBE_RenderThreadShutdownTest DISABLED_RenderThreadShutdownTest
 #else
 #define MAYBE_RenderThreadShutdownTest RenderThreadShutdownTest
diff --git a/content/browser/indexed_db/indexed_db_leveldb_coding.cc b/content/browser/indexed_db/indexed_db_leveldb_coding.cc
index 4455683..2de9b6d 100644
--- a/content/browser/indexed_db/indexed_db_leveldb_coding.cc
+++ b/content/browser/indexed_db/indexed_db_leveldb_coding.cc
@@ -375,6 +375,14 @@
   }
 }
 
+void EncodeBlobJournal(const BlobJournalType& journal, std::string* into) {
+  BlobJournalType::const_iterator iter;
+  for (iter = journal.begin(); iter != journal.end(); ++iter) {
+    EncodeVarInt(iter->first, into);
+    EncodeVarInt(iter->second, into);
+  }
+}
+
 bool DecodeByte(StringPiece* slice, unsigned char* value) {
   if (slice->empty())
     return false;
@@ -607,6 +615,27 @@
   return false;
 }
 
+bool DecodeBlobJournal(StringPiece* slice, BlobJournalType* journal) {
+  BlobJournalType output;
+  while (!slice->empty()) {
+    int64 database_id = -1;
+    int64 blob_key = -1;
+    if (!DecodeVarInt(slice, &database_id))
+      return false;
+    if (!KeyPrefix::IsValidDatabaseId(database_id))
+      return false;
+    if (!DecodeVarInt(slice, &blob_key))
+      return false;
+    if (!DatabaseMetaDataKey::IsValidBlobKey(blob_key) &&
+        (blob_key != DatabaseMetaDataKey::kAllBlobsKey)) {
+      return false;
+    }
+    output.push_back(std::make_pair(database_id, blob_key));
+  }
+  journal->swap(output);
+  return true;
+}
+
 bool ConsumeEncodedIDBKey(StringPiece* slice) {
   unsigned char type = (*slice)[0];
   slice->remove_prefix(1);
diff --git a/content/browser/indexed_db/indexed_db_leveldb_coding.h b/content/browser/indexed_db/indexed_db_leveldb_coding.h
index a86d53f..0cc882f 100644
--- a/content/browser/indexed_db/indexed_db_leveldb_coding.h
+++ b/content/browser/indexed_db/indexed_db_leveldb_coding.h
@@ -23,6 +23,10 @@
 CONTENT_EXPORT std::string MaxIDBKey();
 CONTENT_EXPORT std::string MinIDBKey();
 
+// DatabaseId, BlobKey
+typedef std::pair<int64_t, int64_t> BlobJournalEntryType;
+typedef std::vector<BlobJournalEntryType> BlobJournalType;
+
 CONTENT_EXPORT void EncodeByte(unsigned char value, std::string* into);
 CONTENT_EXPORT void EncodeBool(bool value, std::string* into);
 CONTENT_EXPORT void EncodeInt(int64 value, std::string* into);
@@ -36,6 +40,8 @@
 CONTENT_EXPORT void EncodeIDBKey(const IndexedDBKey& value, std::string* into);
 CONTENT_EXPORT void EncodeIDBKeyPath(const IndexedDBKeyPath& value,
                                      std::string* into);
+CONTENT_EXPORT void EncodeBlobJournal(const BlobJournalType& journal,
+                                      std::string* into);
 
 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeByte(base::StringPiece* slice,
                                                   unsigned char* value);
@@ -60,6 +66,9 @@
 CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeIDBKeyPath(
     base::StringPiece* slice,
     IndexedDBKeyPath* value);
+CONTENT_EXPORT WARN_UNUSED_RESULT bool DecodeBlobJournal(
+    base::StringPiece* slice,
+    BlobJournalType* journal);
 
 CONTENT_EXPORT int CompareEncodedStringsWithLength(base::StringPiece* slice1,
                                                    base::StringPiece* slice2,
@@ -229,7 +238,7 @@
     MAX_SIMPLE_METADATA_TYPE = 6
   };
 
-  static const int64 kAllBlobsKey;
+  CONTENT_EXPORT static const int64 kAllBlobsKey;
   static const int64 kBlobKeyGeneratorInitialNumber;
   // All keys <= 0 are invalid.  This one's just a convenient example.
   static const int64 kInvalidBlobKey;
diff --git a/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc b/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc
index d159a81..0bd647c 100644
--- a/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_leveldb_coding_unittest.cc
@@ -691,6 +691,76 @@
   }
 }
 
+TEST(IndexedDBLevelDBCodingTest, EncodeDecodeBlobJournal) {
+  std::vector<IndexedDBKeyPath> key_paths;
+  std::vector<std::string> encoded_paths;
+
+  std::vector<BlobJournalType> journals;
+
+  {  // Empty journal
+    BlobJournalType journal;
+    journals.push_back(journal);
+  }
+
+  {  // One item
+    BlobJournalType journal;
+    journal.push_back(std::make_pair(4, 7));
+    journals.push_back(journal);
+  }
+
+  {  // kAllBlobsKey
+    BlobJournalType journal;
+    journal.push_back(std::make_pair(5, DatabaseMetaDataKey::kAllBlobsKey));
+    journals.push_back(journal);
+  }
+
+  {  // A bunch of items
+    BlobJournalType journal;
+    journal.push_back(std::make_pair(4, 7));
+    journal.push_back(std::make_pair(5, 6));
+    journal.push_back(std::make_pair(4, 5));
+    journal.push_back(std::make_pair(4, 4));
+    journal.push_back(std::make_pair(1, 12));
+    journal.push_back(std::make_pair(4, 3));
+    journal.push_back(std::make_pair(15, 14));
+    journals.push_back(journal);
+  }
+
+  std::vector<BlobJournalType>::const_iterator journal_iter;
+  for (journal_iter = journals.begin(); journal_iter != journals.end();
+       ++journal_iter) {
+    std::string encoding;
+    EncodeBlobJournal(*journal_iter, &encoding);
+    StringPiece slice(encoding);
+    BlobJournalType journal_out;
+    EXPECT_TRUE(DecodeBlobJournal(&slice, &journal_out));
+    EXPECT_EQ(*journal_iter, journal_out);
+  }
+
+  journals.clear();
+
+  {  // Illegal database id
+    BlobJournalType journal;
+    journal.push_back(std::make_pair(0, 3));
+    journals.push_back(journal);
+  }
+
+  {  // Illegal blob id
+    BlobJournalType journal;
+    journal.push_back(std::make_pair(4, 0));
+    journals.push_back(journal);
+  }
+
+  for (journal_iter = journals.begin(); journal_iter != journals.end();
+       ++journal_iter) {
+    std::string encoding;
+    EncodeBlobJournal(*journal_iter, &encoding);
+    StringPiece slice(encoding);
+    BlobJournalType journal_out;
+    EXPECT_FALSE(DecodeBlobJournal(&slice, &journal_out));
+  }
+}
+
 TEST(IndexedDBLevelDBCodingTest, DecodeLegacyIDBKeyPath) {
   // Legacy encoding of string key paths.
   std::vector<IndexedDBKeyPath> key_paths;
diff --git a/content/browser/loader/upload_data_stream_builder_unittest.cc b/content/browser/loader/upload_data_stream_builder_unittest.cc
index dba3dff..67a57e3 100644
--- a/content/browser/loader/upload_data_stream_builder_unittest.cc
+++ b/content/browser/loader/upload_data_stream_builder_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/files/file_path.h"
 #include "base/message_loop/message_loop.h"
 #include "base/message_loop/message_loop_proxy.h"
+#include "base/run_loop.h"
 #include "base/time/time.h"
 #include "content/common/resource_request_body.h"
 #include "net/base/upload_bytes_element_reader.h"
@@ -93,170 +94,214 @@
 
 TEST(UploadDataStreamBuilderTest, ResolveBlobAndCreateUploadDataStream) {
   base::MessageLoop message_loop;
-  // Setup blob data for testing.
-  base::Time time1, time2;
-  base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1);
-  base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2);
+  {
+    // Setup blob data for testing.
+    base::Time time1, time2;
+    base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1);
+    base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2);
 
-  BlobStorageContext blob_storage_context;
+    BlobStorageContext blob_storage_context;
 
-  const std::string blob_id0("id-0");
-  scoped_refptr<BlobData> blob_data(new BlobData(blob_id0));
-  scoped_ptr<BlobDataHandle> handle1 =
-      blob_storage_context.AddFinishedBlob(blob_data);
+    const std::string blob_id0("id-0");
+    scoped_refptr<BlobData> blob_data(new BlobData(blob_id0));
+    scoped_ptr<BlobDataHandle> handle1 =
+        blob_storage_context.AddFinishedBlob(blob_data);
 
-  const std::string blob_id1("id-1");
-  blob_data = new BlobData(blob_id1);
-  blob_data->AppendData("BlobData");
-  blob_data->AppendFile(
-      base::FilePath(FILE_PATH_LITERAL("BlobFile.txt")), 0, 20, time1);
-  scoped_ptr<BlobDataHandle> handle2 =
-      blob_storage_context.AddFinishedBlob(blob_data);
+    const std::string blob_id1("id-1");
+    blob_data = new BlobData(blob_id1);
+    blob_data->AppendData("BlobData");
+    blob_data->AppendFile(
+        base::FilePath(FILE_PATH_LITERAL("BlobFile.txt")), 0, 20, time1);
+    scoped_ptr<BlobDataHandle> handle2 =
+        blob_storage_context.AddFinishedBlob(blob_data);
 
-  // Setup upload data elements for comparison.
-  ResourceRequestBody::Element blob_element1, blob_element2;
-  blob_element1.SetToBytes(
-      blob_data->items().at(0).bytes() +
-      static_cast<int>(blob_data->items().at(0).offset()),
-      static_cast<int>(blob_data->items().at(0).length()));
-  blob_element2.SetToFilePathRange(
-      blob_data->items().at(1).path(),
-      blob_data->items().at(1).offset(),
-      blob_data->items().at(1).length(),
-      blob_data->items().at(1).expected_modification_time());
+    // Setup upload data elements for comparison.
+    ResourceRequestBody::Element blob_element1, blob_element2;
+    blob_element1.SetToBytes(
+        blob_data->items().at(0).bytes() +
+        static_cast<int>(blob_data->items().at(0).offset()),
+        static_cast<int>(blob_data->items().at(0).length()));
+    blob_element2.SetToFilePathRange(
+        blob_data->items().at(1).path(),
+        blob_data->items().at(1).offset(),
+        blob_data->items().at(1).length(),
+        blob_data->items().at(1).expected_modification_time());
 
-  ResourceRequestBody::Element upload_element1, upload_element2;
-  upload_element1.SetToBytes("Hello", 5);
-  upload_element2.SetToFilePathRange(
-      base::FilePath(FILE_PATH_LITERAL("foo1.txt")), 0, 20, time2);
+    ResourceRequestBody::Element upload_element1, upload_element2;
+    upload_element1.SetToBytes("Hello", 5);
+    upload_element2.SetToFilePathRange(
+        base::FilePath(FILE_PATH_LITERAL("foo1.txt")), 0, 20, time2);
 
-  // Test no blob reference.
-  scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
-  request_body->AppendBytes(upload_element1.bytes(), upload_element1.length());
-  request_body->AppendFileRange(upload_element2.path(),
-                                upload_element2.offset(),
-                                upload_element2.length(),
-                                upload_element2.expected_modification_time());
+    // Test no blob reference.
+    scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
+    request_body->AppendBytes(
+        upload_element1.bytes(),
+        upload_element1.length());
+    request_body->AppendFileRange(
+        upload_element2.path(),
+        upload_element2.offset(),
+        upload_element2.length(),
+        upload_element2.expected_modification_time());
 
-  scoped_ptr<net::UploadDataStream> upload(
-      UploadDataStreamBuilder::Build(request_body.get(),
-                                     &blob_storage_context,
-                                     NULL,
-                                     base::MessageLoopProxy::current().get()));
+    scoped_ptr<net::UploadDataStream> upload(
+        UploadDataStreamBuilder::Build(
+            request_body.get(),
+            &blob_storage_context,
+            NULL,
+            base::MessageLoopProxy::current().get()));
 
-  ASSERT_EQ(2U, upload->element_readers().size());
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], upload_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], upload_element2));
+    ASSERT_EQ(2U, upload->element_readers().size());
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[0], upload_element1));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[1], upload_element2));
 
-  // Test having only one blob reference that refers to empty blob data.
-  request_body = new ResourceRequestBody();
-  request_body->AppendBlob(blob_id0);
+    // Test having only one blob reference that refers to empty blob data.
+    request_body = new ResourceRequestBody();
+    request_body->AppendBlob(blob_id0);
 
-  upload =
-      UploadDataStreamBuilder::Build(request_body.get(),
-                                     &blob_storage_context,
-                                     NULL,
-                                     base::MessageLoopProxy::current().get());
-  ASSERT_EQ(0U, upload->element_readers().size());
+    upload = UploadDataStreamBuilder::Build(
+        request_body.get(),
+        &blob_storage_context,
+        NULL,
+        base::MessageLoopProxy::current().get());
+    ASSERT_EQ(0U, upload->element_readers().size());
 
-  // Test having only one blob reference.
-  request_body = new ResourceRequestBody();
-  request_body->AppendBlob(blob_id1);
+    // Test having only one blob reference.
+    request_body = new ResourceRequestBody();
+    request_body->AppendBlob(blob_id1);
 
-  upload =
-      UploadDataStreamBuilder::Build(request_body.get(),
-                                     &blob_storage_context,
-                                     NULL,
-                                     base::MessageLoopProxy::current().get());
-  ASSERT_EQ(2U, upload->element_readers().size());
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], blob_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element2));
+    upload = UploadDataStreamBuilder::Build(
+        request_body.get(),
+        &blob_storage_context,
+        NULL,
+        base::MessageLoopProxy::current().get());
+    ASSERT_EQ(2U, upload->element_readers().size());
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[0], blob_element1));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[1], blob_element2));
 
-  // Test having one blob reference at the beginning.
-  request_body = new ResourceRequestBody();
-  request_body->AppendBlob(blob_id1);
-  request_body->AppendBytes(upload_element1.bytes(), upload_element1.length());
-  request_body->AppendFileRange(upload_element2.path(),
-                                upload_element2.offset(),
-                                upload_element2.length(),
-                                upload_element2.expected_modification_time());
+    // Test having one blob reference at the beginning.
+    request_body = new ResourceRequestBody();
+    request_body->AppendBlob(blob_id1);
+    request_body->AppendBytes(
+        upload_element1.bytes(),
+        upload_element1.length());
+    request_body->AppendFileRange(
+        upload_element2.path(),
+        upload_element2.offset(),
+        upload_element2.length(),
+        upload_element2.expected_modification_time());
 
-  upload =
-      UploadDataStreamBuilder::Build(request_body.get(),
-                                     &blob_storage_context,
-                                     NULL,
-                                     base::MessageLoopProxy::current().get());
-  ASSERT_EQ(4U, upload->element_readers().size());
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], blob_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element2));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], upload_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], upload_element2));
+    upload = UploadDataStreamBuilder::Build(
+        request_body.get(),
+        &blob_storage_context,
+        NULL,
+        base::MessageLoopProxy::current().get());
+    ASSERT_EQ(4U, upload->element_readers().size());
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[0], blob_element1));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[1], blob_element2));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[2], upload_element1));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[3], upload_element2));
 
-  // Test having one blob reference at the end.
-  request_body = new ResourceRequestBody();
-  request_body->AppendBytes(upload_element1.bytes(), upload_element1.length());
-  request_body->AppendFileRange(upload_element2.path(),
-                                upload_element2.offset(),
-                                upload_element2.length(),
-                                upload_element2.expected_modification_time());
-  request_body->AppendBlob(blob_id1);
+    // Test having one blob reference at the end.
+    request_body = new ResourceRequestBody();
+    request_body->AppendBytes(
+        upload_element1.bytes(),
+        upload_element1.length());
+    request_body->AppendFileRange(
+        upload_element2.path(),
+        upload_element2.offset(),
+        upload_element2.length(),
+        upload_element2.expected_modification_time());
+    request_body->AppendBlob(blob_id1);
 
-  upload =
-      UploadDataStreamBuilder::Build(request_body.get(),
-                                     &blob_storage_context,
-                                     NULL,
-                                     base::MessageLoopProxy::current().get());
-  ASSERT_EQ(4U, upload->element_readers().size());
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], upload_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], upload_element2));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], blob_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], blob_element2));
+    upload =
+        UploadDataStreamBuilder::Build(request_body.get(),
+                                       &blob_storage_context,
+                                       NULL,
+                                       base::MessageLoopProxy::current().get());
+    ASSERT_EQ(4U, upload->element_readers().size());
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[0], upload_element1));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[1], upload_element2));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[2], blob_element1));
+    EXPECT_TRUE(AreElementsEqual(
+          *upload->element_readers()[3], blob_element2));
 
-  // Test having one blob reference in the middle.
-  request_body = new ResourceRequestBody();
-  request_body->AppendBytes(upload_element1.bytes(), upload_element1.length());
-  request_body->AppendBlob(blob_id1);
-  request_body->AppendFileRange(upload_element2.path(),
-                                upload_element2.offset(),
-                                upload_element2.length(),
-                                upload_element2.expected_modification_time());
+    // Test having one blob reference in the middle.
+    request_body = new ResourceRequestBody();
+    request_body->AppendBytes(
+        upload_element1.bytes(),
+        upload_element1.length());
+    request_body->AppendBlob(blob_id1);
+    request_body->AppendFileRange(
+        upload_element2.path(),
+        upload_element2.offset(),
+        upload_element2.length(),
+        upload_element2.expected_modification_time());
 
-  upload =
-      UploadDataStreamBuilder::Build(request_body.get(),
-                                     &blob_storage_context,
-                                     NULL,
-                                     base::MessageLoopProxy::current().get());
-  ASSERT_EQ(4U, upload->element_readers().size());
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], upload_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], blob_element2));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], upload_element2));
+    upload = UploadDataStreamBuilder::Build(
+        request_body.get(),
+        &blob_storage_context,
+        NULL,
+        base::MessageLoopProxy::current().get());
+    ASSERT_EQ(4U, upload->element_readers().size());
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[0], upload_element1));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[1], blob_element1));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[2], blob_element2));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[3], upload_element2));
 
-  // Test having multiple blob references.
-  request_body = new ResourceRequestBody();
-  request_body->AppendBlob(blob_id1);
-  request_body->AppendBytes(upload_element1.bytes(), upload_element1.length());
-  request_body->AppendBlob(blob_id1);
-  request_body->AppendBlob(blob_id1);
-  request_body->AppendFileRange(upload_element2.path(),
-                                upload_element2.offset(),
-                                upload_element2.length(),
-                                upload_element2.expected_modification_time());
+    // Test having multiple blob references.
+    request_body = new ResourceRequestBody();
+    request_body->AppendBlob(blob_id1);
+    request_body->AppendBytes(
+        upload_element1.bytes(),
+        upload_element1.length());
+    request_body->AppendBlob(blob_id1);
+    request_body->AppendBlob(blob_id1);
+    request_body->AppendFileRange(
+        upload_element2.path(),
+        upload_element2.offset(),
+        upload_element2.length(),
+        upload_element2.expected_modification_time());
 
-  upload =
-      UploadDataStreamBuilder::Build(request_body.get(),
-                                     &blob_storage_context,
-                                     NULL,
-                                     base::MessageLoopProxy::current().get());
-  ASSERT_EQ(8U, upload->element_readers().size());
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], blob_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element2));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], upload_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], blob_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[4], blob_element2));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[5], blob_element1));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[6], blob_element2));
-  EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[7], upload_element2));
+    upload = UploadDataStreamBuilder::Build(
+        request_body.get(),
+        &blob_storage_context,
+        NULL,
+        base::MessageLoopProxy::current().get());
+    ASSERT_EQ(8U, upload->element_readers().size());
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[0], blob_element1));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[1], blob_element2));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[2], upload_element1));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[3], blob_element1));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[4], blob_element2));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[5], blob_element1));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[6], blob_element2));
+    EXPECT_TRUE(AreElementsEqual(
+        *upload->element_readers()[7], upload_element2));
+  }
+  // Clean up for ASAN.
+  base::RunLoop().RunUntilIdle();
 }
 
 }  // namespace content
diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc
index a2c618e..b4a71e8 100644
--- a/content/browser/media/android/browser_media_player_manager.cc
+++ b/content/browser/media/android/browser_media_player_manager.cc
@@ -318,8 +318,13 @@
     StoragePartition* partition = host->GetStoragePartition();
     fileapi::FileSystemContext* file_system_context =
         partition ? partition->GetFileSystemContext() : NULL;
+    // Eventually this needs to be fixed to pass the correct frame rather
+    // than just using the main frame.
     media_resource_getter_.reset(new MediaResourceGetterImpl(
-        context, file_system_context, host->GetID(), routing_id()));
+        context,
+        file_system_context,
+        host->GetID(),
+        web_contents()->GetMainFrame()->GetRoutingID()));
   }
   return media_resource_getter_.get();
 }
@@ -677,10 +682,13 @@
   }
 
   drm_bridge->UpdateSession(session_id, &response[0], response.size());
-  // In EME v0.1b MediaKeys lives in the media element. So the |cdm_id|
-  // is the same as the |player_id|.
-  // TODO(xhwang): Separate |cdm_id| and |player_id|.
-  MediaPlayerAndroid* player = GetPlayer(cdm_id);
+
+  DrmBridgePlayerMap::const_iterator iter = drm_bridge_player_map_.find(cdm_id);
+  if (iter == drm_bridge_player_map_.end())
+    return;
+
+  int player_id = iter->second;
+  MediaPlayerAndroid* player = GetPlayer(player_id);
   if (player)
     player->OnKeyAdded();
 }
@@ -725,6 +733,14 @@
       break;
     }
   }
+
+  for (DrmBridgePlayerMap::iterator it = drm_bridge_player_map_.begin();
+       it != drm_bridge_player_map_.end(); ++it) {
+    if (it->second == player_id) {
+      drm_bridge_player_map_.erase(it);
+      break;
+    }
+  }
 }
 
 scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer(
@@ -772,10 +788,15 @@
 }
 
 void BrowserMediaPlayerManager::RemoveDrmBridge(int cdm_id) {
+  // TODO(xhwang): Detach DrmBridge from the player it's set to. In prefixed
+  // EME implementation the current code is fine because we always destroy the
+  // player before we destroy the DrmBridge. This will not always be the case
+  // in unprefixed EME implementation.
   for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin();
       it != drm_bridges_.end(); ++it) {
     if ((*it)->cdm_id() == cdm_id) {
       drm_bridges_.erase(it);
+      drm_bridge_player_map_.erase(cdm_id);
       break;
     }
   }
@@ -792,6 +813,9 @@
   // TODO(qinmin): add the logic to decide whether we should create the
   // fullscreen surface for EME lv1.
   player->SetDrmBridge(drm_bridge);
+  // Do now support setting one CDM on multiple players.
+  DCHECK(drm_bridge_player_map_.find(cdm_id) == drm_bridge_player_map_.end());
+  drm_bridge_player_map_[cdm_id] = player_id;
 }
 
 void BrowserMediaPlayerManager::CreateSessionIfPermitted(
diff --git a/content/browser/media/android/browser_media_player_manager.h b/content/browser/media/android/browser_media_player_manager.h
index 591a445..308ed02 100644
--- a/content/browser/media/android/browser_media_player_manager.h
+++ b/content/browser/media/android/browser_media_player_manager.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_MEDIA_PLAYER_MANAGER_H_
 #define CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_MEDIA_PLAYER_MANAGER_H_
 
+#include <map>
 #include <set>
 #include <string>
 #include <vector>
@@ -218,6 +219,11 @@
   // An array of managed media DRM bridges.
   ScopedVector<media::MediaDrmBridge> drm_bridges_;
 
+  // Map from DrmBridge cdm_id to MediaPlayerAndroid player_id to indicate that
+  // the DrmBridge is set on the MediaPlayerAndroid object.
+  typedef std::map<int, int> DrmBridgePlayerMap;
+  DrmBridgePlayerMap drm_bridge_player_map_;
+
   // The fullscreen video view object or NULL if video is not played in
   // fullscreen.
   scoped_ptr<ContentVideoView> video_view_;
diff --git a/content/browser/media/android/media_resource_getter_impl.cc b/content/browser/media/android/media_resource_getter_impl.cc
index 919ee84..70f6d9b 100644
--- a/content/browser/media/android/media_resource_getter_impl.cc
+++ b/content/browser/media/android/media_resource_getter_impl.cc
@@ -58,13 +58,13 @@
 
 static void RequestPlaformPathFromFileSystemURL(
     const GURL& url,
-    int renderer_id,
+    int render_process_id,
     scoped_refptr<fileapi::FileSystemContext> file_system_context,
     const base::Callback<void(const std::string&)>& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
   base::FilePath platform_path;
   SyncGetPlatformPath(file_system_context.get(),
-                      renderer_id,
+                      render_process_id,
                       url,
                       &platform_path);
   base::FilePath data_storage_path;
@@ -111,7 +111,7 @@
      : public base::RefCountedThreadSafe<CookieGetterTask> {
  public:
   CookieGetterTask(BrowserContext* browser_context,
-                   int renderer_id, int routing_id);
+                   int render_process_id, int render_frame_id);
 
   // Called by CookieGetterImpl to start getting cookies for a URL.
   void RequestCookies(
@@ -134,20 +134,20 @@
   ResourceContext* resource_context_;
 
   // Render process id, used to check whether the process can access cookies.
-  int renderer_id_;
+  int render_process_id_;
 
-  // Routing id for the render view, used to check tab specific cookie policy.
-  int routing_id_;
+  // Render frame id, used to check tab specific cookie policy.
+  int render_frame_id_;
 
   DISALLOW_COPY_AND_ASSIGN(CookieGetterTask);
 };
 
 CookieGetterTask::CookieGetterTask(
-    BrowserContext* browser_context, int renderer_id, int routing_id)
+    BrowserContext* browser_context, int render_process_id, int render_frame_id)
     : context_getter_(browser_context->GetRequestContext()),
       resource_context_(browser_context->GetResourceContext()),
-      renderer_id_(renderer_id),
-      routing_id_(routing_id) {
+      render_process_id_(render_process_id),
+      render_frame_id_(render_frame_id) {
 }
 
 CookieGetterTask::~CookieGetterTask() {}
@@ -158,7 +158,7 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   ChildProcessSecurityPolicyImpl* policy =
       ChildProcessSecurityPolicyImpl::GetInstance();
-  if (!policy->CanAccessCookiesForOrigin(renderer_id_, url)) {
+  if (!policy->CanAccessCookiesForOrigin(render_process_id_, url)) {
     callback.Run(std::string());
     return;
   }
@@ -187,7 +187,7 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (GetContentClient()->browser()->AllowGetCookie(
       url, first_party_for_cookies, cookie_list,
-      resource_context_, renderer_id_, routing_id_)) {
+      resource_context_, render_process_id_, render_frame_id_)) {
     net::CookieStore* cookie_store =
         context_getter_->GetURLRequestContext()->cookie_store();
     cookie_store->GetCookiesWithOptionsAsync(
@@ -200,12 +200,12 @@
 MediaResourceGetterImpl::MediaResourceGetterImpl(
     BrowserContext* browser_context,
     fileapi::FileSystemContext* file_system_context,
-    int renderer_id,
-    int routing_id)
+    int render_process_id,
+    int render_frame_id)
     : browser_context_(browser_context),
       file_system_context_(file_system_context),
-      renderer_id_(renderer_id),
-      routing_id_(routing_id),
+      render_process_id_(render_process_id),
+      render_frame_id_(render_frame_id),
       weak_factory_(this) {}
 
 MediaResourceGetterImpl::~MediaResourceGetterImpl() {}
@@ -215,7 +215,7 @@
     const GetCookieCB& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   scoped_refptr<CookieGetterTask> task = new CookieGetterTask(
-      browser_context_, renderer_id_, routing_id_);
+      browser_context_, render_process_id_, render_frame_id_);
 
   GetCookieCB cb = base::Bind(&MediaResourceGetterImpl::GetCookiesCallback,
                               weak_factory_.GetWeakPtr(),
@@ -256,7 +256,7 @@
   BrowserThread::PostTask(
       BrowserThread::FILE,
       FROM_HERE,
-      base::Bind(&RequestPlaformPathFromFileSystemURL, url, renderer_id_,
+      base::Bind(&RequestPlaformPathFromFileSystemURL, url, render_process_id_,
                  context, cb));
 }
 
diff --git a/content/browser/media/android/media_resource_getter_impl.h b/content/browser/media/android/media_resource_getter_impl.h
index c0bdbe3..c1ed4b9 100644
--- a/content/browser/media/android/media_resource_getter_impl.h
+++ b/content/browser/media/android/media_resource_getter_impl.h
@@ -32,11 +32,11 @@
 class MediaResourceGetterImpl : public media::MediaResourceGetter {
  public:
   // Construct a MediaResourceGetterImpl object. |browser_context| and
-  // |renderer_id| are passed to retrieve the CookieStore.
+  // |render_process_id| are passed to retrieve the CookieStore.
   // |file_system_context| are used to get the platform path.
   MediaResourceGetterImpl(BrowserContext* browser_context,
                           fileapi::FileSystemContext* file_system_context,
-                          int renderer_id, int routing_id);
+                          int render_process_id, int render_frame_id);
   virtual ~MediaResourceGetterImpl();
 
   // media::MediaResourceGetter implementation.
@@ -70,10 +70,10 @@
   fileapi::FileSystemContext* file_system_context_;
 
   // Render process id, used to check whether the process can access cookies.
-  int renderer_id_;
+  int render_process_id_;
 
-  // Routing id for the render view, used to check tab specific cookie policy.
-  int routing_id_;
+  // Render frame id, used to check tab specific cookie policy.
+  int render_frame_id_;
 
   // NOTE: Weak pointers must be invalidated before all other member variables.
   base::WeakPtrFactory<MediaResourceGetterImpl> weak_factory_;
diff --git a/content/browser/media/capture/content_video_capture_device_core.cc b/content/browser/media/capture/content_video_capture_device_core.cc
index b8fbe8d..01a7197 100644
--- a/content/browser/media/capture/content_video_capture_device_core.cc
+++ b/content/browser/media/capture/content_video_capture_device_core.cc
@@ -48,12 +48,17 @@
       oracle_(oracle.Pass()),
       params_(params),
       capture_size_updated_(false) {
-  // Frame dimensions must each be an even integer since the client wants (or
-  // will convert to) YUV420.
-  capture_size_ = gfx::Size(
-      MakeEven(params.requested_format.frame_size.width()),
-      MakeEven(params.requested_format.frame_size.height()));
-  frame_rate_ = params.requested_format.frame_rate;
+  switch (params_.requested_format.pixel_format) {
+    case media::PIXEL_FORMAT_I420:
+      video_frame_format_ = media::VideoFrame::I420;
+      break;
+    case media::PIXEL_FORMAT_TEXTURE:
+      video_frame_format_ = media::VideoFrame::NATIVE_TEXTURE;
+      break;
+    default:
+      LOG(FATAL) << "Unexpected pixel_format "
+                 << params_.requested_format.pixel_format;
+  }
 }
 
 ThreadSafeCaptureOracle::~ThreadSafeCaptureOracle() {}
@@ -69,7 +74,8 @@
     return false;  // Capture is stopped.
 
   scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer =
-      client_->ReserveOutputBuffer(media::VideoFrame::I420, capture_size_);
+      client_->ReserveOutputBuffer(video_frame_format_,
+                                   params_.requested_format.frame_size);
   const bool should_capture =
       oracle_->ObserveEventAndDecideCapture(event, event_time);
   const bool content_is_dirty =
@@ -110,27 +116,30 @@
   TRACE_EVENT_ASYNC_BEGIN2("mirroring", "Capture", output_buffer.get(),
                            "frame_number", frame_number,
                            "trigger", event_name);
-  *storage = media::VideoFrame::WrapExternalPackedMemory(
-      media::VideoFrame::I420,
-      capture_size_,
-      gfx::Rect(capture_size_),
-      capture_size_,
-      static_cast<uint8*>(output_buffer->data()),
-      output_buffer->size(),
-      base::SharedMemory::NULLHandle(),
-      base::TimeDelta(),
-      base::Closure());
+  // NATIVE_TEXTURE frames wrap a texture mailbox, which we don't have at the
+  // moment.  We do not construct those frames.
+  if (video_frame_format_ != media::VideoFrame::NATIVE_TEXTURE) {
+    *storage = media::VideoFrame::WrapExternalPackedMemory(
+        video_frame_format_,
+        params_.requested_format.frame_size,
+        gfx::Rect(params_.requested_format.frame_size),
+        params_.requested_format.frame_size,
+        static_cast<uint8*>(output_buffer->data()),
+        output_buffer->size(),
+        base::SharedMemory::NULLHandle(),
+        base::TimeDelta(),
+        base::Closure());
+  }
   *callback = base::Bind(&ThreadSafeCaptureOracle::DidCaptureFrame,
                          this,
-                         output_buffer,
-                         *storage,
-                         frame_number);
+                         frame_number,
+                         output_buffer);
   return true;
 }
 
 gfx::Size ThreadSafeCaptureOracle::GetCaptureSize() const {
   base::AutoLock guard(lock_);
-  return capture_size_;
+  return params_.requested_format.frame_size;
 }
 
 void ThreadSafeCaptureOracle::UpdateCaptureSize(const gfx::Size& source_size) {
@@ -146,11 +155,11 @@
         source_size.height() > params_.requested_format.frame_size.height()) {
       gfx::Rect capture_rect = media::ComputeLetterboxRegion(
           gfx::Rect(params_.requested_format.frame_size), source_size);
-      capture_size_ = gfx::Size(MakeEven(capture_rect.width()),
-                                MakeEven(capture_rect.height()));
+      params_.requested_format.frame_size.SetSize(
+          MakeEven(capture_rect.width()), MakeEven(capture_rect.height()));
     } else {
-      capture_size_ = gfx::Size(MakeEven(source_size.width()),
-                                MakeEven(source_size.height()));
+      params_.requested_format.frame_size.SetSize(
+          MakeEven(source_size.width()), MakeEven(source_size.height()));
     }
     capture_size_updated_ = true;
   }
@@ -168,9 +177,9 @@
 }
 
 void ThreadSafeCaptureOracle::DidCaptureFrame(
+    int frame_number,
     const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer,
     const scoped_refptr<media::VideoFrame>& frame,
-    int frame_number,
     base::TimeTicks timestamp,
     bool success) {
   base::AutoLock guard(lock_);
@@ -183,12 +192,9 @@
 
   if (success) {
     if (oracle_->CompleteCapture(frame_number, timestamp)) {
-      client_->OnIncomingCapturedVideoFrame(
-          buffer,
-          media::VideoCaptureFormat(
-              capture_size_, frame_rate_, media::PIXEL_FORMAT_I420),
-          frame,
-          timestamp);
+      media::VideoCaptureFormat format = params_.requested_format;
+      format.frame_size = frame->coded_size();
+      client_->OnIncomingCapturedVideoFrame(buffer, format, frame, timestamp);
     }
   }
 }
@@ -211,15 +217,31 @@
     return;
   }
 
-  if (params.requested_format.frame_size.width() < kMinFrameWidth ||
-      params.requested_format.frame_size.height() < kMinFrameHeight) {
-    std::string error_msg =
-        "invalid frame size: " + params.requested_format.frame_size.ToString();
+  if (params.requested_format.pixel_format != media::PIXEL_FORMAT_I420 &&
+      params.requested_format.pixel_format != media::PIXEL_FORMAT_TEXTURE) {
+    std::string error_msg = base::StringPrintf(
+        "unsupported format: %d", params.requested_format.pixel_format);
     DVLOG(1) << error_msg;
     client->OnError(error_msg);
     return;
   }
 
+   if (params.requested_format.frame_size.width() < kMinFrameWidth ||
+       params.requested_format.frame_size.height() < kMinFrameHeight) {
+     std::string error_msg =
+         "invalid frame size: " + params.requested_format.frame_size.ToString();
+     DVLOG(1) << error_msg;
+     client->OnError(error_msg);
+     return;
+   }
+
+  media::VideoCaptureParams new_params = params;
+  // Frame dimensions must each be an even integer since the client wants (or
+  // will convert to) YUV420.
+  new_params.requested_format.frame_size.SetSize(
+      MakeEven(params.requested_format.frame_size.width()),
+      MakeEven(params.requested_format.frame_size.height()));
+
   base::TimeDelta capture_period = base::TimeDelta::FromMicroseconds(
       1000000.0 / params.requested_format.frame_rate + 0.5);
 
@@ -227,16 +249,17 @@
       new VideoCaptureOracle(capture_period,
                              kAcceleratedSubscriberIsSupported));
   oracle_proxy_ =
-      new ThreadSafeCaptureOracle(client.Pass(), oracle.Pass(), params);
+      new ThreadSafeCaptureOracle(client.Pass(), oracle.Pass(), new_params);
 
   // Starts the capture machine asynchronously.
   BrowserThread::PostTaskAndReplyWithResult(
-      BrowserThread::UI, FROM_HERE,
+      BrowserThread::UI,
+      FROM_HERE,
       base::Bind(&VideoCaptureMachine::Start,
                  base::Unretained(capture_machine_.get()),
-                 oracle_proxy_),
-      base::Bind(&ContentVideoCaptureDeviceCore::CaptureStarted,
-                 AsWeakPtr()));
+                 oracle_proxy_,
+                 new_params),
+      base::Bind(&ContentVideoCaptureDeviceCore::CaptureStarted, AsWeakPtr()));
 
   TransitionStateTo(kCapturing);
 }
diff --git a/content/browser/media/capture/content_video_capture_device_core.h b/content/browser/media/capture/content_video_capture_device_core.h
index 992caa7..3a7e697 100644
--- a/content/browser/media/capture/content_video_capture_device_core.h
+++ b/content/browser/media/capture/content_video_capture_device_core.h
@@ -13,9 +13,11 @@
 #include "base/threading/thread_checker.h"
 #include "content/browser/media/capture/video_capture_oracle.h"
 #include "content/common/content_export.h"
+#include "media/base/video_frame.h"
 #include "media/video/capture/video_capture_device.h"
 
 namespace media {
+class VideoCaptureParams;
 class VideoFrame;
 }  // namespace media
 
@@ -52,11 +54,12 @@
                           const media::VideoCaptureParams& params);
 
   // Called when a captured frame is available or an error has occurred.
-  // If |success| is true then the frame provided is valid and |timestamp|
-  // indicates when the frame was painted.
-  // If |success| is false, both the frame provided and |timestamp| are invalid.
-  typedef base::Callback<void(base::TimeTicks timestamp, bool success)>
-      CaptureFrameCallback;
+  // If |success| is true then |frame| is valid and |timestamp| indicates when
+  // the frame was painted.
+  // If |success| is false, all other parameters are invalid.
+  typedef base::Callback<void(const scoped_refptr<media::VideoFrame>& frame,
+                              base::TimeTicks timestamp,
+                              bool success)> CaptureFrameCallback;
 
   bool ObserveEventAndDecideCapture(VideoCaptureOracle::Event event,
                                     base::TimeTicks event_time,
@@ -86,9 +89,9 @@
 
   // Callback invoked on completion of all captures.
   void DidCaptureFrame(
+      int frame_number,
       const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer,
       const scoped_refptr<media::VideoFrame>& frame,
-      int frame_number,
       base::TimeTicks timestamp,
       bool success);
 
@@ -102,14 +105,13 @@
   const scoped_ptr<VideoCaptureOracle> oracle_;
 
   // The video capture parameters used to construct the oracle proxy.
-  const media::VideoCaptureParams params_;
+  media::VideoCaptureParams params_;
 
   // Indicates if capture size has been updated after construction.
   bool capture_size_updated_;
 
-  // The current capturing resolution and frame rate.
-  gfx::Size capture_size_;
-  int frame_rate_;
+  // The current capturing format, as a media::VideoFrame::Format.
+  media::VideoFrame::Format video_frame_format_;
 };
 
 // Keeps track of the video capture source frames and executes copying on the
@@ -124,8 +126,8 @@
 
   // Starts capturing. Returns true if succeeded.
   // Must be run on the UI BrowserThread.
-  virtual bool Start(
-      const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) = 0;
+  virtual bool Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
+                     const media::VideoCaptureParams& params) = 0;
 
   // Stops capturing. Must be run on the UI BrowserThread.
   // |callback| is invoked after the capturing has stopped.
diff --git a/content/browser/media/capture/desktop_capture_device_aura.cc b/content/browser/media/capture/desktop_capture_device_aura.cc
index 86bc271..1da4604 100644
--- a/content/browser/media/capture/desktop_capture_device_aura.cc
+++ b/content/browser/media/capture/desktop_capture_device_aura.cc
@@ -14,6 +14,7 @@
 #include "content/browser/media/capture/desktop_capture_device_uma_types.h"
 #include "content/common/gpu/client/gl_helper.h"
 #include "content/public/browser/browser_thread.h"
+#include "media/base/bind_to_current_loop.h"
 #include "media/base/video_util.h"
 #include "media/video/capture/video_capture_types.h"
 #include "skia/ext/image_operations.h"
@@ -97,8 +98,8 @@
   virtual ~DesktopVideoCaptureMachine();
 
   // VideoCaptureFrameSource overrides.
-  virtual bool Start(
-      const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) OVERRIDE;
+  virtual bool Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
+                     const media::VideoCaptureParams& params) OVERRIDE;
   virtual void Stop(const base::Closure& callback) OVERRIDE;
 
   // Implements aura::WindowObserver.
@@ -162,6 +163,9 @@
   // Makes all the decisions about which frames to copy, and how.
   scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_;
 
+  // The capture parameters for this capture.
+  media::VideoCaptureParams capture_params_;
+
   // YUV readback pipeline.
   scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_;
 
@@ -183,7 +187,8 @@
 DesktopVideoCaptureMachine::~DesktopVideoCaptureMachine() {}
 
 bool DesktopVideoCaptureMachine::Start(
-    const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) {
+    const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
+    const media::VideoCaptureParams& params) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   desktop_window_ = content::DesktopMediaID::GetAuraWindowById(window_id_);
@@ -197,6 +202,7 @@
 
   DCHECK(oracle_proxy.get());
   oracle_proxy_ = oracle_proxy;
+  capture_params_ = params;
 
   // Update capture size.
   UpdateCaptureSize();
@@ -294,7 +300,18 @@
   if (!cursor_bitmap.isNull())
     RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position);
   release_callback->Run(0, false);
-  capture_frame_cb.Run(start_time, result);
+  capture_frame_cb.Run(target, start_time, result);
+}
+
+void RunSingleReleaseCallback(scoped_ptr<cc::SingleReleaseCallback> cb,
+                              const std::vector<uint32>& sync_points) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
+  DCHECK(gl_helper);
+  for (unsigned i = 0; i < sync_points.size(); i++)
+    gl_helper->WaitSyncPoint(sync_points[i]);
+  uint32 new_sync_point = gl_helper->InsertSyncPoint();
+  cb->Run(new_sync_point, false);
 }
 
 void DesktopVideoCaptureMachine::DidCopyOutput(
@@ -331,9 +348,34 @@
     base::TimeTicks start_time,
     const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
     scoped_ptr<cc::CopyOutputResult> result) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_)
     return false;
 
+  if (capture_params_.requested_format.pixel_format ==
+      media::PIXEL_FORMAT_TEXTURE) {
+    DCHECK(!video_frame);
+    cc::TextureMailbox texture_mailbox;
+    scoped_ptr<cc::SingleReleaseCallback> release_callback;
+    result->TakeTexture(&texture_mailbox, &release_callback);
+    DCHECK(texture_mailbox.IsTexture());
+    if (!texture_mailbox.IsTexture())
+      return false;
+    video_frame = media::VideoFrame::WrapNativeTexture(
+        make_scoped_ptr(new gpu::MailboxHolder(texture_mailbox.mailbox(),
+                                               texture_mailbox.target(),
+                                               texture_mailbox.sync_point())),
+        media::BindToCurrentLoop(base::Bind(&RunSingleReleaseCallback,
+                                            base::Passed(&release_callback))),
+        result->size(),
+        gfx::Rect(result->size()),
+        result->size(),
+        base::TimeDelta(),
+        media::VideoFrame::ReadPixelsCB());
+    capture_frame_cb.Run(video_frame, start_time, true);
+    return true;
+  }
+
   // Compute the dest size we want after the letterboxing resize. Make the
   // coordinates and sizes even because we letterbox in YUV space
   // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
diff --git a/content/browser/media/capture/web_contents_tracker.cc b/content/browser/media/capture/web_contents_tracker.cc
index 0251c64..0765331 100644
--- a/content/browser/media/capture/web_contents_tracker.cc
+++ b/content/browser/media/capture/web_contents_tracker.cc
@@ -95,7 +95,7 @@
   OnWebContentsChangeEvent();
 }
 
-void WebContentsTracker::WebContentsDestroyed(WebContents* web_contents) {
+void WebContentsTracker::WebContentsDestroyed() {
   OnWebContentsChangeEvent();
 }
 
diff --git a/content/browser/media/capture/web_contents_tracker.h b/content/browser/media/capture/web_contents_tracker.h
index 0c77761..f8957f3 100644
--- a/content/browser/media/capture/web_contents_tracker.h
+++ b/content/browser/media/capture/web_contents_tracker.h
@@ -73,7 +73,7 @@
       OVERRIDE;
   virtual void DidNavigateMainFrame(const LoadCommittedDetails& details,
                                     const FrameNavigateParams& params) OVERRIDE;
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   scoped_refptr<base::MessageLoopProxy> message_loop_;
   ChangeCallback callback_;
diff --git a/content/browser/media/capture/web_contents_video_capture_device.cc b/content/browser/media/capture/web_contents_video_capture_device.cc
index a59dd53..0e5347c 100644
--- a/content/browser/media/capture/web_contents_video_capture_device.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -66,14 +66,14 @@
 #include "content/browser/media/capture/video_capture_oracle.h"
 #include "content/browser/media/capture/web_contents_capture_util.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/web_contents/web_contents_impl.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "media/base/video_util.h"
 #include "media/video/capture/video_capture_types.h"
@@ -100,15 +100,6 @@
   return result;
 }
 
-// Wrapper function to invoke ThreadSafeCaptureOracle::CaptureFrameCallback, is
-// compatible with RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback.
-void InvokeCaptureFrameCallback(
-    const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
-    base::TimeTicks timestamp,
-    bool frame_captured) {
-  capture_frame_cb.Run(timestamp, frame_captured);
-}
-
 void DeleteOnWorkerThread(scoped_ptr<base::Thread> render_thread,
                           const base::Closure& callback) {
   render_thread.reset();
@@ -238,8 +229,8 @@
   virtual ~WebContentsCaptureMachine();
 
   // VideoCaptureMachine overrides.
-  virtual bool Start(
-      const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) OVERRIDE;
+  virtual bool Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
+                     const media::VideoCaptureParams& params) OVERRIDE;
   virtual void Stop(const base::Closure& callback) OVERRIDE;
 
   // Starts a copy from the backing store or the composited surface. Must be run
@@ -278,7 +269,7 @@
     RenewFrameSubscription();
   }
 
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
  private:
   // Starts observing the web contents, returning false if lookup fails.
@@ -319,6 +310,9 @@
   // Makes all the decisions about which frames to copy, and how.
   scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_;
 
+  // Video capture parameters that this machine is started with.
+  media::VideoCaptureParams capture_params_;
+
   // Routing ID of any active fullscreen render widget or MSG_ROUTING_NONE
   // otherwise.
   int fullscreen_widget_id_;
@@ -348,7 +342,8 @@
   bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture(
       event_type_, present_time, storage, &capture_frame_cb);
 
-  *deliver_frame_cb = base::Bind(&InvokeCaptureFrameCallback, capture_frame_cb);
+  if (!capture_frame_cb.is_null())
+    *deliver_frame_cb = base::Bind(capture_frame_cb, *storage);
   if (oracle_decision)
     delivery_log_->ChronicleFrameDelivery(present_time);
   return oracle_decision;
@@ -369,8 +364,8 @@
       timer_(true, true) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  RenderWidgetHostViewPort* view =
-      RenderWidgetHostViewPort::FromRWHV(source.GetView());
+  RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
+      source.GetView());
 
   // Subscribe to accelerated presents. These will be serviced directly by the
   // oracle.
@@ -400,8 +395,8 @@
     RenderViewHost* source = RenderViewHost::FromID(render_process_id_,
                                                     render_view_id_);
     if (source) {
-      RenderWidgetHostViewPort* view =
-          RenderWidgetHostViewPort::FromRWHV(source->GetView());
+      RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
+          source->GetView());
       if (view)
         view->EndFrameSubscription();
     }
@@ -578,12 +573,14 @@
 }
 
 bool WebContentsCaptureMachine::Start(
-    const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) {
+    const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
+    const media::VideoCaptureParams& params) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(!started_);
 
   DCHECK(oracle_proxy.get());
   oracle_proxy_ = oracle_proxy;
+  capture_params_ = params;
 
   render_thread_.reset(new base::Thread("WebContentsVideo_RenderThread"));
   if (!render_thread_->Start()) {
@@ -632,8 +629,8 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   RenderWidgetHost* rwh = GetTarget();
-  RenderWidgetHostViewPort* view =
-      rwh ? RenderWidgetHostViewPort::FromRWHV(rwh->GetView()) : NULL;
+  RenderWidgetHostViewBase* view =
+      rwh ? static_cast<RenderWidgetHostViewBase*>(rwh->GetView()) : NULL;
   if (!view || !rwh) {
     deliver_frame_cb.Run(base::TimeTicks(), false);
     return;
@@ -705,12 +702,11 @@
   return false;
 }
 
-void WebContentsCaptureMachine::WebContentsDestroyed(
-    WebContents* web_contents) {
+void WebContentsCaptureMachine::WebContentsDestroyed() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   subscription_.reset();
-  web_contents->DecrementCapturerCount();
+  web_contents()->DecrementCapturerCount();
   oracle_proxy_->ReportError("WebContentsDestroyed()");
 }
 
diff --git a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
index aee5c44..dc1bd5a 100644
--- a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
@@ -16,9 +16,9 @@
 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
 #include "content/browser/renderer_host/render_view_host_factory.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/test/mock_render_process_host.h"
 #include "content/public/test/test_browser_context.h"
 #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/content/browser/media/media_browsertest.cc b/content/browser/media/media_browsertest.cc
index f284add..7e44a31 100644
--- a/content/browser/media/media_browsertest.cc
+++ b/content/browser/media/media_browsertest.cc
@@ -231,8 +231,7 @@
 }
 
 IN_PROC_BROWSER_TEST_F(MediaTest, MAYBE(Yuvj420pH264)) {
-  // TODO(rileya): Support YUVJ420P properly http://crbug.com/310273
-  RunColorFormatTest("yuvj420p.mp4", "FAILED");
+  RunColorFormatTest("yuvj420p.mp4", "ENDED");
 }
 
 IN_PROC_BROWSER_TEST_F(MediaTest, MAYBE(Yuv422pH264)) {
diff --git a/content/browser/media/webrtc_browsertest.cc b/content/browser/media/webrtc_browsertest.cc
index ce566ae..69fd5c0 100644
--- a/content/browser/media/webrtc_browsertest.cc
+++ b/content/browser/media/webrtc_browsertest.cc
@@ -5,6 +5,7 @@
 #include "base/command_line.h"
 #include "base/file_util.h"
 #include "base/strings/stringprintf.h"
+#include "base/threading/platform_thread.h"
 #include "base/values.h"
 #include "content/browser/media/webrtc_internals.h"
 #include "content/browser/web_contents/web_contents_impl.h"
@@ -45,6 +46,18 @@
       command_line->AppendSwitch(switches::kEnableAudioTrackProcessing);
   }
 
+  virtual void TearDownOnMainThread() OVERRIDE {
+#if defined(OS_ANDROID)
+    // TODO(phoglund): this is a ugly workaround to let the IO thread
+    // finish its work. The reason we need this on Android is that
+    // content_browsertests tearDown logic is broken with respect
+    // to threading, which causes the IO thread to compete with the
+    // teardown. See http://crbug.com/362852. I also tried with 2
+    // seconds, but that isn't enough.
+    base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(5));
+#endif
+  }
+
   // Convenience function since most peerconnection-call.html tests just load
   // the page, kick off some javascript and wait for the title to change to OK.
   void MakeTypicalPeerConnectionCall(const std::string& javascript) {
@@ -58,7 +71,7 @@
   }
 
   void DisableOpusIfOnAndroid() {
-#if defined (OS_ANDROID)
+#if defined(OS_ANDROID)
     // Always force iSAC 16K on Android for now (Opus is broken).
     EXPECT_EQ("isac-forced",
               ExecuteJavascriptAndReturnResult("forceIsac16KInSdp();"));
@@ -172,29 +185,13 @@
 
 // This test will modify the SDP offer to an unsupported codec, which should
 // cause SetLocalDescription to fail.
-#if defined(USE_OZONE)
-// Disabled for Ozone, see http://crbug.com/315392#c15
-#define MAYBE_NegotiateUnsupportedVideoCodec\
-    DISABLED_NegotiateUnsupportedVideoCodec
-#else
-#define MAYBE_NegotiateUnsupportedVideoCodec NegotiateUnsupportedVideoCodec
-#endif
-
-IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest,
-                       MAYBE_NegotiateUnsupportedVideoCodec) {
+IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, NegotiateUnsupportedVideoCodec) {
   MakeTypicalPeerConnectionCall("negotiateUnsupportedVideoCodec();");
 }
 
 // This test will modify the SDP offer to use no encryption, which should
 // cause SetLocalDescription to fail.
-#if defined(USE_OZONE)
-// Disabled for Ozone, see http://crbug.com/315392#c15
-#define MAYBE_NegotiateNonCryptoCall DISABLED_NegotiateNonCryptoCall
-#else
-#define MAYBE_NegotiateNonCryptoCall NegotiateNonCryptoCall
-#endif
-
-IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, MAYBE_NegotiateNonCryptoCall) {
+IN_PROC_BROWSER_TEST_P(WebRtcBrowserTest, NegotiateNonCryptoCall) {
   MakeTypicalPeerConnectionCall("negotiateNonCryptoCall();");
 }
 
diff --git a/content/browser/media/webrtc_internals.cc b/content/browser/media/webrtc_internals.cc
index 7a1254c..d3aaa6c 100644
--- a/content/browser/media/webrtc_internals.cc
+++ b/content/browser/media/webrtc_internals.cc
@@ -5,13 +5,15 @@
 #include "content/browser/media/webrtc_internals.h"
 
 #include "base/command_line.h"
+#include "base/path_service.h"
 #include "content/browser/media/webrtc_internals_ui_observer.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_switches.h"
 
 using base::ProcessId;
@@ -40,15 +42,18 @@
 // TODO(grunell): Shouldn't all the webrtc_internals* files be excluded from the
 // build if WebRTC is disabled?
 #if defined(ENABLE_WEBRTC)
-#if defined(OS_CHROMEOS)
+  aec_dump_file_path_ =
+      GetContentClient()->browser()->GetDefaultDownloadDirectory();
+  if (aec_dump_file_path_.empty()) {
+    // In this case the default path (|aec_dump_file_path_|) will be empty and
+    // the platform default path will be used in the file dialog (with no
+    // default file name). See SelectFileDialog::SelectFile. On Android where
+    // there's no dialog we'll fail to open the file.
+    LOG(WARNING) << "Could not get the download directory.";
+  } else {
     aec_dump_file_path_ =
-        base::FilePath(FILE_PATH_LITERAL("/tmp/audio.aecdump"));
-#elif defined(OS_ANDROID)
-    aec_dump_file_path_ =
-        base::FilePath(FILE_PATH_LITERAL("/sdcard/audio.aecdump"));
-#else
-    aec_dump_file_path_ = base::FilePath(FILE_PATH_LITERAL("audio.aecdump"));
-#endif
+        aec_dump_file_path_.Append(FILE_PATH_LITERAL("audio.aecdump"));
+  }
 #endif  // defined(ENABLE_WEBRTC)
 }
 
@@ -232,7 +237,7 @@
       NULL,
       0,
       FILE_PATH_LITERAL(""),
-      web_contents->GetView()->GetTopLevelNativeWindow(),
+      web_contents->GetTopLevelNativeWindow(),
       NULL);
 #endif
 #endif
diff --git a/content/browser/message_port_message_filter.cc b/content/browser/message_port_message_filter.cc
index 4fd8045..6de26bd 100644
--- a/content/browser/message_port_message_filter.cc
+++ b/content/browser/message_port_message_filter.cc
@@ -57,6 +57,22 @@
   return next_routing_id_.Run();
 }
 
+void MessagePortMessageFilter::UpdateMessagePortsWithNewRoutes(
+    const std::vector<int>& message_port_ids,
+    std::vector<int>* new_routing_ids) {
+  DCHECK(new_routing_ids);
+  new_routing_ids->clear();
+  new_routing_ids->resize(message_port_ids.size());
+
+  for (size_t i = 0; i < message_port_ids.size(); ++i) {
+    (*new_routing_ids)[i] = GetNextRoutingID();
+    MessagePortService::GetInstance()->UpdateMessagePort(
+        message_port_ids[i],
+        this,
+        (*new_routing_ids)[i]);
+  }
+}
+
 void MessagePortMessageFilter::OnCreateMessagePort(int *route_id,
                                                    int* message_port_id) {
   *route_id = next_routing_id_.Run();
diff --git a/content/browser/message_port_message_filter.h b/content/browser/message_port_message_filter.h
index 5cc191e..a324ad8 100644
--- a/content/browser/message_port_message_filter.h
+++ b/content/browser/message_port_message_filter.h
@@ -29,6 +29,12 @@
 
   int GetNextRoutingID();
 
+  // Updates message ports registered for |message_port_ids| and returns
+  // new routing IDs for the updated ports via |new_routing_ids|.
+  void UpdateMessagePortsWithNewRoutes(
+      const std::vector<int>& message_port_ids,
+      std::vector<int>* new_routing_ids);
+
  protected:
   // This is protected, so we can define sub classes for testing.
   virtual ~MessagePortMessageFilter();
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index da3080e..2e8e882 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -259,7 +259,8 @@
 
 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
   root_layer_->RemoveAllChildren();
-  root_layer_->AddChild(root_layer);
+  if (root_layer)
+    root_layer_->AddChild(root_layer);
 }
 
 void CompositorImpl::SetWindowSurface(ANativeWindow* window) {
@@ -326,6 +327,8 @@
     CommandLine* command_line = CommandLine::ForCurrentProcess();
     settings.initial_debug_state.SetRecordRenderingStats(
         command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
+    settings.initial_debug_state.show_fps_counter =
+        command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
 
     host_ = cc::LayerTreeHost::CreateSingleThreaded(
         this, this, HostSharedBitmapManager::current(), settings);
diff --git a/content/browser/renderer_host/event_with_latency_info.h b/content/browser/renderer_host/event_with_latency_info.h
new file mode 100644
index 0000000..483c4cf
--- /dev/null
+++ b/content/browser/renderer_host/event_with_latency_info.h
@@ -0,0 +1,59 @@
+// Copyright 2013 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.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_EVENT_WITH_LATENCY_INFO_H_
+#define CONTENT_BROWSER_RENDERER_HOST_EVENT_WITH_LATENCY_INFO_H_
+
+#include "ui/events/latency_info.h"
+
+#include "content/common/input/web_input_event_traits.h"
+
+namespace blink {
+class WebGestureEvent;
+class WebMouseEvent;
+class WebMouseWheelEvent;
+class WebTouchEvent;
+}
+
+namespace content {
+
+template <typename T>
+class EventWithLatencyInfo {
+ public:
+  T event;
+  ui::LatencyInfo latency;
+
+  EventWithLatencyInfo(const T& e, const ui::LatencyInfo& l)
+      : event(e), latency(l) {}
+
+  EventWithLatencyInfo() {}
+
+  bool CanCoalesceWith(const EventWithLatencyInfo& other)
+      const WARN_UNUSED_RESULT {
+    return WebInputEventTraits::CanCoalesce(other.event, event);
+  }
+
+  void CoalesceWith(const EventWithLatencyInfo& other) {
+    WebInputEventTraits::Coalesce(other.event, &event);
+    // When coalescing two input events, we keep the oldest LatencyInfo
+    // for Telemetry latency test since it will represent the longest
+    // latency.
+    if (other.latency.trace_id >= 0 &&
+        (latency.trace_id < 0 || other.latency.trace_id < latency.trace_id))
+      latency = other.latency;
+  }
+};
+
+typedef EventWithLatencyInfo<blink::WebGestureEvent>
+    GestureEventWithLatencyInfo;
+typedef EventWithLatencyInfo<blink::WebMouseWheelEvent>
+    MouseWheelEventWithLatencyInfo;
+typedef EventWithLatencyInfo<blink::WebMouseEvent>
+    MouseEventWithLatencyInfo;
+typedef EventWithLatencyInfo<blink::WebTouchEvent>
+    TouchEventWithLatencyInfo;
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_RENDERER_HOST_EVENT_WITH_LATENCY_INFO_H_
diff --git a/content/browser/renderer_host/gamepad_browser_message_filter.cc b/content/browser/renderer_host/gamepad_browser_message_filter.cc
index e6e05f6..f616a74 100644
--- a/content/browser/renderer_host/gamepad_browser_message_filter.cc
+++ b/content/browser/renderer_host/gamepad_browser_message_filter.cc
@@ -17,7 +17,7 @@
 GamepadBrowserMessageFilter::~GamepadBrowserMessageFilter() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (is_started_)
-    GamepadService::GetInstance()->RemoveConsumer();
+    GamepadService::GetInstance()->RemoveConsumer(this);
 }
 
 bool GamepadBrowserMessageFilter::OnMessageReceived(
@@ -34,28 +34,31 @@
   return handled;
 }
 
+void GamepadBrowserMessageFilter::OnGamepadConnected(
+    unsigned index,
+    const blink::WebGamepad& gamepad) {
+  Send(new GamepadMsg_GamepadConnected(index, gamepad));
+}
+
+void GamepadBrowserMessageFilter::OnGamepadDisconnected(
+    unsigned index,
+    const blink::WebGamepad& gamepad) {
+  Send(new GamepadMsg_GamepadDisconnected(index, gamepad));
+}
+
 void GamepadBrowserMessageFilter::OnGamepadStartPolling(
     base::SharedMemoryHandle* renderer_handle) {
   GamepadService* service = GamepadService::GetInstance();
-  if (!is_started_) {
-    is_started_ = true;
-    service->AddConsumer();
-    *renderer_handle = service->GetSharedMemoryHandleForProcess(PeerHandle());
-  } else {
-    // Currently we only expect the renderer to tell us once to start.
-    NOTREACHED();
-  }
+  CHECK(!is_started_);
+  is_started_ = true;
+  service->ConsumerBecameActive(this);
+  *renderer_handle = service->GetSharedMemoryHandleForProcess(PeerHandle());
 }
 
 void GamepadBrowserMessageFilter::OnGamepadStopPolling() {
-  // TODO(scottmg): Probably get rid of this message. We can't trust it will
-  // arrive anyway if the renderer crashes, etc.
-  if (is_started_) {
-    is_started_ = false;
-    GamepadService::GetInstance()->RemoveConsumer();
-  } else {
-    NOTREACHED();
-  }
+  CHECK(is_started_);
+  is_started_ = false;
+  GamepadService::GetInstance()->ConsumerBecameInactive(this);
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/gamepad_browser_message_filter.h b/content/browser/renderer_host/gamepad_browser_message_filter.h
index 8661e71..f328739 100644
--- a/content/browser/renderer_host/gamepad_browser_message_filter.h
+++ b/content/browser/renderer_host/gamepad_browser_message_filter.h
@@ -7,6 +7,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/memory/shared_memory.h"
+#include "content/browser/gamepad/gamepad_consumer.h"
 #include "content/public/browser/browser_message_filter.h"
 
 namespace content {
@@ -14,7 +15,9 @@
 class GamepadService;
 class RenderProcessHost;
 
-class GamepadBrowserMessageFilter : public BrowserMessageFilter {
+class GamepadBrowserMessageFilter :
+    public BrowserMessageFilter,
+    public GamepadConsumer {
  public:
   GamepadBrowserMessageFilter();
 
@@ -22,6 +25,14 @@
   virtual bool OnMessageReceived(const IPC::Message& message,
                                  bool* message_was_ok) OVERRIDE;
 
+  // GamepadConsumer implementation.
+  virtual void OnGamepadConnected(
+      unsigned index,
+      const blink::WebGamepad& gamepad) OVERRIDE;
+  virtual void OnGamepadDisconnected(
+      unsigned index,
+      const blink::WebGamepad& gamepad) OVERRIDE;
+
  private:
   virtual ~GamepadBrowserMessageFilter();
 
diff --git a/content/browser/renderer_host/gpu_message_filter.cc b/content/browser/renderer_host/gpu_message_filter.cc
index 3c8a177..856d14b 100644
--- a/content/browser/renderer_host/gpu_message_filter.cc
+++ b/content/browser/renderer_host/gpu_message_filter.cc
@@ -16,7 +16,7 @@
 #include "content/browser/gpu/gpu_surface_tracker.h"
 #include "content/browser/renderer_host/render_widget_helper.h"
 #include "content/common/gpu/gpu_messages.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/common/content_switches.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
 
diff --git a/content/browser/renderer_host/input/gesture_event_queue.cc b/content/browser/renderer_host/input/gesture_event_queue.cc
index 2fb46b6..9811e73 100644
--- a/content/browser/renderer_host/input/gesture_event_queue.cc
+++ b/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -4,7 +4,6 @@
 
 #include "content/browser/renderer_host/input/gesture_event_queue.h"
 
-#include "base/command_line.h"
 #include "base/debug/trace_event.h"
 #include "base/strings/string_number_conversions.h"
 #include "content/browser/renderer_host/input/input_router.h"
@@ -16,34 +15,27 @@
 using blink::WebInputEvent;
 
 namespace content {
-namespace {
 
-// Default debouncing interval duration: if a scroll is in progress, non-scroll
-// events during this interval are deferred to either its end or discarded on
-// receipt of another GestureScrollUpdate.
-static const int kDebouncingIntervalTimeMs = 30;
-
-}  // namespace
+GestureEventQueue::Config::Config() {
+}
 
 GestureEventQueue::GestureEventQueue(
     GestureEventQueueClient* client,
-    TouchpadTapSuppressionControllerClient* touchpad_client)
-     : client_(client),
-       fling_in_progress_(false),
-       scrolling_in_progress_(false),
-       ignore_next_ack_(false),
-       touchpad_tap_suppression_controller_(
-           new TouchpadTapSuppressionController(touchpad_client)),
-       touchscreen_tap_suppression_controller_(
-           new TouchscreenTapSuppressionController(this)),
-       debounce_interval_time_ms_(kDebouncingIntervalTimeMs),
-       debounce_enabled_(true) {
+    TouchpadTapSuppressionControllerClient* touchpad_client,
+    const Config& config)
+    : client_(client),
+      fling_in_progress_(false),
+      scrolling_in_progress_(false),
+      ignore_next_ack_(false),
+      touchpad_tap_suppression_controller_(
+          touchpad_client,
+          config.touchpad_tap_suppression_config),
+      touchscreen_tap_suppression_controller_(
+          this,
+          config.touchscreen_tap_suppression_config),
+      debounce_interval_(config.debounce_interval) {
   DCHECK(client);
-  DCHECK(touchpad_tap_suppression_controller_);
-  if (CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kDisableGestureDebounce)) {
-    debounce_enabled_ = false;
-  }
+  DCHECK(touchpad_client);
 }
 
 GestureEventQueue::~GestureEventQueue() { }
@@ -66,14 +58,14 @@
 
 bool GestureEventQueue::ShouldForwardForBounceReduction(
     const GestureEventWithLatencyInfo& gesture_event) {
-  if (!debounce_enabled_)
+  if (debounce_interval_ <= base::TimeDelta())
     return true;
   switch (gesture_event.event.type) {
     case WebInputEvent::GestureScrollUpdate:
       if (!scrolling_in_progress_) {
         debounce_deferring_timer_.Start(
             FROM_HERE,
-            base::TimeDelta::FromMilliseconds(debounce_interval_time_ms_),
+            debounce_interval_,
             this,
             &GestureEventQueue::SendScrollEndingEventsNow);
       } else {
@@ -127,9 +119,9 @@
   switch (gesture_event.event.type) {
     case WebInputEvent::GestureFlingCancel:
       if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen)
-        touchscreen_tap_suppression_controller_->GestureFlingCancel();
+        touchscreen_tap_suppression_controller_.GestureFlingCancel();
       else
-        touchpad_tap_suppression_controller_->GestureFlingCancel();
+        touchpad_tap_suppression_controller_.GestureFlingCancel();
       return true;
     case WebInputEvent::GestureTapDown:
     case WebInputEvent::GestureShowPress:
@@ -138,8 +130,8 @@
     case WebInputEvent::GestureTap:
     case WebInputEvent::GestureDoubleTap:
       if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen) {
-        return !touchscreen_tap_suppression_controller_->
-            FilterTapEvent(gesture_event);
+        return !touchscreen_tap_suppression_controller_.FilterTapEvent(
+            gesture_event);
       }
       return true;
     default:
@@ -200,9 +192,9 @@
   const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
   if (type == WebInputEvent::GestureFlingCancel) {
     if (event_with_latency.event.sourceDevice == WebGestureEvent::Touchscreen)
-      touchscreen_tap_suppression_controller_->GestureFlingCancelAck(processed);
+      touchscreen_tap_suppression_controller_.GestureFlingCancelAck(processed);
     else
-      touchpad_tap_suppression_controller_->GestureFlingCancelAck(processed);
+      touchpad_tap_suppression_controller_.GestureFlingCancelAck(processed);
   }
   DCHECK_LT(event_index, coalesced_gesture_events_.size());
   coalesced_gesture_events_.erase(coalesced_gesture_events_.begin() +
@@ -238,7 +230,7 @@
 
 TouchpadTapSuppressionController*
     GestureEventQueue::GetTouchpadTapSuppressionController() {
-  return touchpad_tap_suppression_controller_.get();
+  return &touchpad_tap_suppression_controller_;
 }
 
 bool GestureEventQueue::ExpectingGestureAck() const {
diff --git a/content/browser/renderer_host/input/gesture_event_queue.h b/content/browser/renderer_host/input/gesture_event_queue.h
index ca7f648..a0a8146 100644
--- a/content/browser/renderer_host/input/gesture_event_queue.h
+++ b/content/browser/renderer_host/input/gesture_event_queue.h
@@ -10,9 +10,12 @@
 #include "base/basictypes.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/timer/timer.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
+#include "content/browser/renderer_host/input/tap_suppression_controller.h"
+#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
+#include "content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h"
 #include "content/common/content_export.h"
-#include "content/port/browser/event_with_latency_info.h"
-#include "content/port/common/input_event_ack_state.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #include "ui/gfx/transform.h"
 
@@ -20,9 +23,6 @@
 class GestureEventQueueTest;
 class InputRouter;
 class MockRenderWidgetHost;
-class TouchpadTapSuppressionController;
-class TouchpadTapSuppressionControllerClient;
-class TouchscreenTapSuppressionController;
 
 // Interface with which the GestureEventQueue can forward gesture events, and
 // dispatch gesture event responses.
@@ -61,9 +61,25 @@
 // http://crbug.com/148443.
 class CONTENT_EXPORT GestureEventQueue {
  public:
+  struct CONTENT_EXPORT Config {
+    Config();
+
+    // Controls touchpad-related tap suppression, disabled by default.
+    TapSuppressionController::Config touchpad_tap_suppression_config;
+
+    // Controls touchscreen-related tap suppression, disabled by default.
+    TapSuppressionController::Config touchscreen_tap_suppression_config;
+
+    // Determines whether non-scroll gesture events are "debounced" during an
+    // active scroll sequence, suppressing brief scroll interruptions.
+    // Zero by default (disabled).
+    base::TimeDelta debounce_interval;
+  };
+
   // Both |client| and |touchpad_client| must outlive the GestureEventQueue.
   GestureEventQueue(GestureEventQueueClient* client,
-                     TouchpadTapSuppressionControllerClient* touchpad_client);
+                    TouchpadTapSuppressionControllerClient* touchpad_client,
+                    const Config& config);
   ~GestureEventQueue();
 
   // Returns |true| if the caller should immediately forward the provided
@@ -96,12 +112,8 @@
            debouncing_deferral_queue_.empty();
   }
 
-  void set_debounce_enabled_for_testing(bool enabled) {
-    debounce_enabled_ = enabled;
-  }
-
-  void set_debounce_interval_time_ms_for_testing(int interval_time_ms) {
-    debounce_interval_time_ms_ = interval_time_ms;
+  void set_debounce_interval_time_ms_for_testing(int interval_ms) {
+    debounce_interval_ = base::TimeDelta::FromMilliseconds(interval_ms);
   }
 
  private:
@@ -188,14 +200,12 @@
   // tap.
   // TODO(mohsen): Move touchpad tap suppression out of GestureEventQueue since
   // GEQ is meant to only be used for touchscreen gesture events.
-  scoped_ptr<TouchpadTapSuppressionController>
-      touchpad_tap_suppression_controller_;
+  TouchpadTapSuppressionController touchpad_tap_suppression_controller_;
 
   // An object tracking the state of touchscreen on the delivery of gesture tap
   // events to the renderer to filter taps immediately after a touchscreen fling
   // canceling tap.
-  scoped_ptr<TouchscreenTapSuppressionController>
-      touchscreen_tap_suppression_controller_;
+  TouchscreenTapSuppressionController touchscreen_tap_suppression_controller_;
 
   typedef std::deque<GestureEventWithLatencyInfo> GestureQueue;
 
@@ -213,13 +223,9 @@
   // Queue of events that have been deferred for debounce.
   GestureQueue debouncing_deferral_queue_;
 
-  // Time window in which to debounce scroll/fling ends.
-  // TODO(rjkroege): Make this dynamically configurable.
-  int debounce_interval_time_ms_;
-
-  // Whether scroll-ending events should be deferred when a scroll is active.
-  // Defaults to true.
-  bool debounce_enabled_;
+  // Time window in which to debounce scroll/fling ends. Note that an interval
+  // of zero effectively disables debouncing.
+  base::TimeDelta debounce_interval_;
 
   DISALLOW_COPY_AND_ASSIGN(GestureEventQueue);
 };
diff --git a/content/browser/renderer_host/input/gesture_event_queue_unittest.cc b/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
index 412dae9..2deb555 100644
--- a/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
+++ b/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
@@ -11,8 +11,8 @@
 #include "base/time/time.h"
 #include "content/browser/renderer_host/input/gesture_event_queue.h"
 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/common/input/synthetic_web_input_event_builders.h"
-#include "content/port/common/input_event_ack_state.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 
@@ -34,7 +34,7 @@
 
   // testing::Test
   virtual void SetUp() OVERRIDE {
-    queue_.reset(new GestureEventQueue(this, this));
+    queue_.reset(new GestureEventQueue(this, this, DefaultConfig()));
   }
 
   virtual void TearDown() OVERRIDE {
@@ -68,6 +68,13 @@
   }
 
  protected:
+  static GestureEventQueue::Config DefaultConfig() {
+    return GestureEventQueue::Config();
+  }
+
+  void SetUpForDebounce(int interval_ms) {
+    queue()->set_debounce_interval_time_ms_for_testing(interval_ms);
+  }
 
   // Returns the result of |GestureEventQueue::ShouldForward()|.
   bool SimulateGestureEvent(const WebGestureEvent& gesture) {
@@ -95,11 +102,8 @@
                                        float anchorX,
                                        float anchorY,
                                        int modifiers) {
-    SimulateGestureEvent(
-        SyntheticWebGestureEventBuilder::BuildPinchUpdate(scale,
-                                                          anchorX,
-                                                          anchorY,
-                                                          modifiers));
+    SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildPinchUpdate(
+        scale, anchorX, anchorY, modifiers, WebGestureEvent::Touchscreen));
   }
 
   void SimulateGestureFlingStartEvent(
@@ -137,14 +141,6 @@
     return last_acked_event_;
   }
 
-  void DisableDebounce() {
-    queue()->set_debounce_enabled_for_testing(false);
-  }
-
-  void set_debounce_interval_time_ms(int ms) {
-    queue()->set_debounce_interval_time_ms_for_testing(ms);
-  }
-
   void set_synchronous_ack(InputEventAckState ack_result) {
     sync_ack_result_.reset(new InputEventAckState(ack_result));
   }
@@ -211,9 +207,6 @@
 #endif  // GTEST_HAS_PARAM_TEST
 
 TEST_F(GestureEventQueueTest, CoalescesScrollGestureEvents) {
-  // Turn off debounce handling for test isolation.
-  DisableDebounce();
-
   // Test coalescing of only GestureScrollUpdate events.
   // Simulate gesture events.
 
@@ -289,9 +282,6 @@
 
 TEST_F(GestureEventQueueTest,
        DoesNotCoalesceScrollGestureEventsFromDifferentDevices) {
-  // Turn off debounce handling for test isolation.
-  DisableDebounce();
-
   // Test that GestureScrollUpdate events from Touchscreen and Touchpad do not
   // coalesce.
 
@@ -336,9 +326,6 @@
 }
 
 TEST_F(GestureEventQueueTest, CoalescesScrollAndPinchEvents) {
-  // Turn off debounce handling for test isolation.
-  DisableDebounce();
-
   // Test coalescing of only GestureScrollUpdate events.
   // Simulate gesture events.
 
@@ -571,9 +558,6 @@
 }
 
 TEST_F(GestureEventQueueTest, CoalescesMultiplePinchEventSequences) {
-  // Turn off debounce handling for test isolation.
-  DisableDebounce();
-
   // Simulate a pinch sequence.
   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
                        WebGestureEvent::Touchscreen);
@@ -664,9 +648,6 @@
 }
 
 TEST_F(GestureEventQueueTest, CoalescesPinchSequencesWithEarlyAck) {
-  // Turn off debounce handling for test isolation.
-  DisableDebounce();
-
   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
                        WebGestureEvent::Touchscreen);
   SendInputEventACK(WebInputEvent::GestureScrollBegin,
@@ -730,9 +711,6 @@
 
 TEST_F(GestureEventQueueTest,
        DoesNotCoalescePinchGestureEventsWithDifferentModifiers) {
-  // Turn off debounce handling for test isolation.
-  DisableDebounce();
-
   // Insert an event to force queueing of gestures.
   SimulateGestureEvent(WebInputEvent::GestureTapCancel,
                        WebGestureEvent::Touchscreen);
@@ -796,9 +774,6 @@
 }
 
 TEST_F(GestureEventQueueTest, CoalescesScrollAndPinchEventsIdentity) {
-  // Turn off debounce handling for test isolation.
-  DisableDebounce();
-
   // Insert an event to force queueing of gestures.
   SimulateGestureEvent(WebInputEvent::GestureTapCancel,
                        WebGestureEvent::Touchscreen);
@@ -913,9 +888,6 @@
 
 // Tests an event with an async ack followed by an event with a sync ack.
 TEST_F(GestureEventQueueTest, AsyncThenSyncAck) {
-  // Turn off debounce handling for test isolation.
-  DisableDebounce();
-
   SimulateGestureEvent(WebInputEvent::GestureTapDown,
                        WebGestureEvent::Touchscreen);
 
@@ -938,9 +910,6 @@
 }
 
 TEST_F(GestureEventQueueTest, CoalescesScrollAndPinchEventWithSyncAck) {
-  // Turn off debounce handling for test isolation.
-  DisableDebounce();
-
   // Simulate a pinch sequence.
   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
                        WebGestureEvent::Touchscreen);
@@ -987,8 +956,6 @@
 TEST_P(GestureEventQueueWithSourceTest, GestureFlingCancelsFiltered) {
   WebGestureEvent::SourceDevice source_device = GetParam();
 
-  // Turn off debounce handling for test isolation.
-  DisableDebounce();
   // GFC without previous GFS is dropped.
   SimulateGestureEvent(WebInputEvent::GestureFlingCancel, source_device);
   EXPECT_EQ(0U, GetAndResetSentGestureEventCount());
@@ -1084,7 +1051,7 @@
 // debounce interval, that Scrolls are not and that the deferred events are
 // sent after that timer fires.
 TEST_F(GestureEventQueueTest, DebounceDefersFollowingGestureEvents) {
-  set_debounce_interval_time_ms(3);
+  SetUpForDebounce(3);
 
   SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
                        WebGestureEvent::Touchscreen);
@@ -1147,7 +1114,8 @@
 // interval and are discarded if a GestureScrollUpdate event arrives before the
 // interval end.
 TEST_F(GestureEventQueueTest, DebounceDropsDeferredEvents) {
-  set_debounce_interval_time_ms(3);
+  SetUpForDebounce(3);
+
   EXPECT_FALSE(ScrollingInProgress());
 
   SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
diff --git a/content/browser/renderer_host/input/input_ack_handler.h b/content/browser/renderer_host/input/input_ack_handler.h
index 7917bff..0e34b82 100644
--- a/content/browser/renderer_host/input/input_ack_handler.h
+++ b/content/browser/renderer_host/input/input_ack_handler.h
@@ -6,8 +6,8 @@
 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ACK_HANDLER_H_
 
 #include "base/basictypes.h"
-#include "content/port/browser/event_with_latency_info.h"
-#include "content/port/common/input_event_ack_state.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 
diff --git a/content/browser/renderer_host/input/input_router.h b/content/browser/renderer_host/input/input_router.h
index 2dbb4ed..bb3bd03 100644
--- a/content/browser/renderer_host/input/input_router.h
+++ b/content/browser/renderer_host/input/input_router.h
@@ -6,8 +6,8 @@
 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_H_
 
 #include "base/basictypes.h"
-#include "content/port/browser/event_with_latency_info.h"
-#include "content/port/common/input_event_ack_state.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "ipc/ipc_listener.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
diff --git a/content/browser/renderer_host/input/input_router_client.h b/content/browser/renderer_host/input/input_router_client.h
index fefcb10..647c081 100644
--- a/content/browser/renderer_host/input/input_router_client.h
+++ b/content/browser/renderer_host/input/input_router_client.h
@@ -5,9 +5,9 @@
 #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_CLIENT_H_
 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_CLIENT_H_
 
+#include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/common/content_export.h"
-#include "content/port/browser/event_with_latency_info.h"
-#include "content/port/common/input_event_ack_state.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 
diff --git a/content/browser/renderer_host/input/input_router_config_helper.cc b/content/browser/renderer_host/input/input_router_config_helper.cc
new file mode 100644
index 0000000..bbd6f79
--- /dev/null
+++ b/content/browser/renderer_host/input/input_router_config_helper.cc
@@ -0,0 +1,144 @@
+// 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.
+
+#include "content/browser/renderer_host/input/input_router_config_helper.h"
+
+#include "base/command_line.h"
+#include "content/public/common/content_switches.h"
+#include "ui/events/gesture_detection/gesture_detector.h"
+
+#if defined(USE_AURA)
+#include "ui/events/gestures/gesture_configuration.h"
+#elif defined(OS_ANDROID)
+#include "ui/gfx/android/view_configuration.h"
+#include "ui/gfx/screen.h"
+#endif
+
+namespace content {
+namespace {
+
+#if defined(USE_AURA)
+
+GestureEventQueue::Config GetGestureEventQueueConfig() {
+  GestureEventQueue::Config config;
+
+#if defined(OS_CHROMEOS)
+  // Default debouncing interval duration on ChromeOS: if a scroll is in
+  // progress, non-scroll events during this interval are deferred to either its
+  // end or discarded on receipt of another GestureScrollUpdate.
+  // TODO(jdduke): Disable and remove entirely when issues with spurious
+  // scroll end detection on the Pixel are resolved, crbug.com/353702.
+  const int kDebouncingIntervalTimeMs = 30;
+  config.debounce_interval =
+      base::TimeDelta::FromMilliseconds(kDebouncingIntervalTimeMs);
+#endif
+
+  config.touchscreen_tap_suppression_config.enabled = true;
+  config.touchscreen_tap_suppression_config.max_cancel_to_down_time =
+      base::TimeDelta::FromMilliseconds(
+          ui::GestureConfiguration::fling_max_cancel_to_down_time_in_ms());
+
+  config.touchscreen_tap_suppression_config.max_tap_gap_time =
+      base::TimeDelta::FromMilliseconds(static_cast<int>(
+          ui::GestureConfiguration::semi_long_press_time_in_seconds() * 1000));
+
+  config.touchpad_tap_suppression_config.enabled = true;
+  config.touchpad_tap_suppression_config.max_cancel_to_down_time =
+      base::TimeDelta::FromMilliseconds(
+          ui::GestureConfiguration::fling_max_cancel_to_down_time_in_ms());
+
+  config.touchpad_tap_suppression_config.max_tap_gap_time =
+      base::TimeDelta::FromMilliseconds(static_cast<int>(
+          ui::GestureConfiguration::fling_max_tap_gap_time_in_ms() * 1000));
+
+  return config;
+}
+
+TouchEventQueue::Config GetTouchEventQueueConfig() {
+  TouchEventQueue::Config config;
+
+  config.touchmove_slop_suppression_length_dips =
+      ui::GestureConfiguration::max_touch_move_in_pixels_for_click();
+
+  return config;
+}
+
+#elif defined(OS_ANDROID)
+
+// Default time allowance for the touch ack delay before the touch sequence is
+// cancelled.
+const int kTouchAckTimeoutDelayMs = 200;
+
+GestureEventQueue::Config GetGestureEventQueueConfig() {
+  GestureEventQueue::Config config;
+
+  config.touchscreen_tap_suppression_config.enabled = true;
+  config.touchscreen_tap_suppression_config.max_cancel_to_down_time =
+      base::TimeDelta::FromMilliseconds(
+          gfx::ViewConfiguration::GetTapTimeoutInMs());
+  config.touchscreen_tap_suppression_config.max_tap_gap_time =
+      base::TimeDelta::FromMilliseconds(
+          gfx::ViewConfiguration::GetLongPressTimeoutInMs());
+
+  return config;
+}
+
+TouchEventQueue::Config GetTouchEventQueueConfig() {
+  TouchEventQueue::Config config;
+
+  config.touch_ack_timeout_delay =
+      base::TimeDelta::FromMilliseconds(kTouchAckTimeoutDelayMs);
+  config.touch_ack_timeout_supported = true;
+
+  const double touch_slop_length_pixels =
+      static_cast<double>(gfx::ViewConfiguration::GetTouchSlopInPixels());
+  const double device_scale_factor =
+      gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor();
+  config.touchmove_slop_suppression_length_dips =
+      touch_slop_length_pixels / device_scale_factor;
+
+  return config;
+}
+
+#else
+
+GestureEventQueue::Config GetGestureEventQueueConfig() {
+  return GestureEventQueue::Config();
+}
+
+TouchEventQueue::Config GetTouchEventQueueConfig() {
+  TouchEventQueue::Config config;
+  config.touchmove_slop_suppression_length_dips =
+      ui::GestureDetector::Config().touch_slop;
+  return config;
+}
+
+#endif
+
+TouchEventQueue::TouchScrollingMode GetTouchScrollingMode() {
+  std::string modeString =
+      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+          switches::kTouchScrollingMode);
+  if (modeString == switches::kTouchScrollingModeAsyncTouchmove)
+    return TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE;
+  if (modeString == switches::kTouchScrollingModeSyncTouchmove)
+    return TouchEventQueue::TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE;
+  if (modeString == switches::kTouchScrollingModeTouchcancel)
+    return TouchEventQueue::TOUCH_SCROLLING_MODE_TOUCHCANCEL;
+  if (modeString != "")
+    LOG(ERROR) << "Invalid --touch-scrolling-mode option: " << modeString;
+  return TouchEventQueue::TOUCH_SCROLLING_MODE_DEFAULT;
+}
+
+}  // namespace
+
+InputRouterImpl::Config GetInputRouterConfigForPlatform() {
+  InputRouterImpl::Config config;
+  config.gesture_config = GetGestureEventQueueConfig();
+  config.touch_config = GetTouchEventQueueConfig();
+  config.touch_config.touch_scrolling_mode = GetTouchScrollingMode();
+  return config;
+}
+
+}  // namespace content
diff --git a/content/browser/renderer_host/input/input_router_config_helper.h b/content/browser/renderer_host/input/input_router_config_helper.h
new file mode 100644
index 0000000..46fbbd0
--- /dev/null
+++ b/content/browser/renderer_host/input/input_router_config_helper.h
@@ -0,0 +1,18 @@
+// 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.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_CONFIG_HELPER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_CONFIG_HELPER_H_
+
+#include "content/browser/renderer_host/input/input_router_impl.h"
+
+namespace content {
+
+// Return an InputRouter configuration with parameters tailored to the current
+// platform.
+InputRouterImpl::Config GetInputRouterConfigForPlatform();
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_CONFIG_HELPER_H_
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc
index 83f6fcb..08b9e45 100644
--- a/content/browser/renderer_host/input/input_router_impl.cc
+++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -4,6 +4,8 @@
 
 #include "content/browser/renderer_host/input/input_router_impl.h"
 
+#include <math.h>
+
 #include "base/auto_reset.h"
 #include "base/command_line.h"
 #include "base/metrics/histogram.h"
@@ -16,11 +18,11 @@
 #include "content/browser/renderer_host/overscroll_controller.h"
 #include "content/common/content_constants_internal.h"
 #include "content/common/edit_command.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/common/input/touch_action.h"
 #include "content/common/input/web_touch_event_traits.h"
 #include "content/common/input_messages.h"
 #include "content/common/view_messages.h"
-#include "content/port/common/input_event_ack_state.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/user_metrics.h"
@@ -29,13 +31,6 @@
 #include "ui/events/event.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 
-#if defined(OS_ANDROID)
-#include "ui/gfx/android/view_configuration.h"
-#include "ui/gfx/screen.h"
-#else
-#include "ui/events/gestures/gesture_configuration.h"
-#endif
-
 using base::Time;
 using base::TimeDelta;
 using base::TimeTicks;
@@ -48,57 +43,6 @@
 namespace content {
 namespace {
 
-// TODO(jdduke): Instead of relying on command line flags or conditional
-// conditional compilation here, we should instead use an InputRouter::Settings
-// construct, supplied and customized by the RenderWidgetHostView. See
-// crbug.com/343917.
-bool GetTouchAckTimeoutDelay(base::TimeDelta* touch_ack_timeout_delay) {
-  CommandLine* parsed_command_line = CommandLine::ForCurrentProcess();
-  if (!parsed_command_line->HasSwitch(switches::kTouchAckTimeoutDelayMs))
-    return false;
-
-  std::string timeout_string = parsed_command_line->GetSwitchValueASCII(
-      switches::kTouchAckTimeoutDelayMs);
-  size_t timeout_ms;
-  if (!base::StringToSizeT(timeout_string, &timeout_ms))
-    return false;
-
-  *touch_ack_timeout_delay = base::TimeDelta::FromMilliseconds(timeout_ms);
-  return true;
-}
-
-#if defined(OS_ANDROID)
-double GetTouchMoveSlopSuppressionLengthDips() {
-  const double touch_slop_length_pixels =
-      static_cast<double>(gfx::ViewConfiguration::GetTouchSlopInPixels());
-  const double device_scale_factor =
-      gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor();
-  return touch_slop_length_pixels / device_scale_factor;
-}
-#elif defined(USE_AURA)
-double GetTouchMoveSlopSuppressionLengthDips() {
-  return ui::GestureConfiguration::max_touch_move_in_pixels_for_click();
-}
-#else
-double GetTouchMoveSlopSuppressionLengthDips() {
-  return 0;
-}
-#endif
-
-TouchEventQueue::TouchScrollingMode GetTouchScrollingMode() {
-  std::string modeString = CommandLine::ForCurrentProcess()->
-      GetSwitchValueASCII(switches::kTouchScrollingMode);
-  if (modeString == switches::kTouchScrollingModeAsyncTouchmove)
-    return TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE;
-  if (modeString == switches::kTouchScrollingModeSyncTouchmove)
-    return TouchEventQueue::TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE;
-  if (modeString == switches::kTouchScrollingModeTouchcancel)
-    return TouchEventQueue::TOUCH_SCROLLING_MODE_TOUCHCANCEL;
-  if (modeString != "")
-    LOG(ERROR) << "Invalid --touch-scrolling-mode option: " << modeString;
-  return TouchEventQueue::TOUCH_SCROLLING_MODE_DEFAULT;
-}
-
 const char* GetEventAckName(InputEventAckState ack_result) {
   switch(ack_result) {
     case INPUT_EVENT_ACK_STATE_UNKNOWN: return "UNKNOWN";
@@ -113,10 +57,14 @@
 
 } // namespace
 
+InputRouterImpl::Config::Config() {
+}
+
 InputRouterImpl::InputRouterImpl(IPC::Sender* sender,
                                  InputRouterClient* client,
                                  InputAckHandler* ack_handler,
-                                 int routing_id)
+                                 int routing_id,
+                                 const Config& config)
     : sender_(sender),
       client_(client),
       ack_handler_(ack_handler),
@@ -125,19 +73,14 @@
       move_caret_pending_(false),
       mouse_move_pending_(false),
       mouse_wheel_pending_(false),
-      touch_ack_timeout_supported_(false),
       current_view_flags_(0),
       current_ack_source_(ACK_SOURCE_NONE),
       flush_requested_(false),
-      touch_event_queue_(this,
-                         GetTouchScrollingMode(),
-                         GetTouchMoveSlopSuppressionLengthDips()),
-      gesture_event_queue_(this, this) {
+      touch_event_queue_(this, config.touch_config),
+      gesture_event_queue_(this, this, config.gesture_config) {
   DCHECK(sender);
   DCHECK(client);
   DCHECK(ack_handler);
-  touch_ack_timeout_supported_ =
-      GetTouchAckTimeoutDelay(&touch_ack_timeout_delay_);
   UpdateTouchAckTimeoutEnabled();
 }
 
@@ -180,26 +123,39 @@
 
 void InputRouterImpl::SendWheelEvent(
     const MouseWheelEventWithLatencyInfo& wheel_event) {
-  // If there's already a mouse wheel event waiting to be sent to the renderer,
-  // add the new deltas to that event. Not doing so (e.g., by dropping the old
-  // event, as for mouse moves) results in very slow scrolling on the Mac (on
-  // which many, very small wheel events are sent).
+  SendWheelEvent(QueuedWheelEvent(wheel_event, false));
+}
+
+void InputRouterImpl::SendWheelEvent(const QueuedWheelEvent& wheel_event) {
   if (mouse_wheel_pending_) {
+    // If there's already a mouse wheel event waiting to be sent to the
+    // renderer, add the new deltas to that event. Not doing so (e.g., by
+    // dropping the old event, as for mouse moves) results in very slow
+    // scrolling on the Mac (on which many, very small wheel events are sent).
+    // Note that we can't coalesce wheel events for pinches because the GEQ
+    // expects one ACK for each (but it's fine to coalesce non-pinch wheels
+    // into a pinch one).  Note that the GestureEventQueue ensures we only
+    // ever have a single pinch event queued here.
     if (coalesced_mouse_wheel_events_.empty() ||
-        !coalesced_mouse_wheel_events_.back().CanCoalesceWith(wheel_event)) {
+        wheel_event.synthesized_from_pinch ||
+        !coalesced_mouse_wheel_events_.back().event.CanCoalesceWith(
+            wheel_event.event)) {
       coalesced_mouse_wheel_events_.push_back(wheel_event);
     } else {
-      coalesced_mouse_wheel_events_.back().CoalesceWith(wheel_event);
+      coalesced_mouse_wheel_events_.back().event.CoalesceWith(
+          wheel_event.event);
     }
     return;
   }
+
   mouse_wheel_pending_ = true;
   current_wheel_event_ = wheel_event;
 
   HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize",
                        coalesced_mouse_wheel_events_.size());
 
-  FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false);
+  FilterAndSendWebInputEvent(
+      wheel_event.event.event, wheel_event.event.latency, false);
 }
 
 void InputRouterImpl::SendKeyboardEvent(const NativeWebKeyboardEvent& key_event,
@@ -235,7 +191,7 @@
     return;
   }
 
-  FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false);
+  SendGestureEventImmediately(gesture_event);
 }
 
 void InputRouterImpl::SendTouchEvent(
@@ -281,6 +237,12 @@
 
 void InputRouterImpl::SendGestureEventImmediately(
     const GestureEventWithLatencyInfo& gesture_event) {
+  if (gesture_event.event.type == WebInputEvent::GesturePinchUpdate &&
+      gesture_event.event.sourceDevice == WebGestureEvent::Touchpad) {
+    SendSyntheticWheelEventForPinch(gesture_event);
+    return;
+  }
+
   FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false);
 }
 
@@ -378,19 +340,6 @@
                "type",
                WebInputEventTraits::GetName(input_event.type));
 
-  // Transmit any pending wheel events on a non-wheel event. This ensures that
-  // final PhaseEnded wheel event is received, which is necessary to terminate
-  // rubber-banding, for example.
-   if (input_event.type != WebInputEvent::MouseWheel) {
-    WheelEventQueue mouse_wheel_events;
-    mouse_wheel_events.swap(coalesced_mouse_wheel_events_);
-    for (size_t i = 0; i < mouse_wheel_events.size(); ++i) {
-      OfferToHandlers(mouse_wheel_events[i].event,
-                      mouse_wheel_events[i].latency,
-                      false);
-     }
-  }
-
   // Any input event cancels a pending mouse move event.
   next_mouse_move_.reset();
 
@@ -400,18 +349,6 @@
 void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event,
                                       const ui::LatencyInfo& latency_info,
                                       bool is_keyboard_shortcut) {
-  // Trackpad pinch gestures are not yet handled by the renderer.
-  // TODO(rbyers): Send mousewheel for trackpad pinch - crbug.com/289887.
-  if (input_event.type == WebInputEvent::GesturePinchUpdate &&
-      static_cast<const WebGestureEvent&>(input_event).sourceDevice ==
-          WebGestureEvent::Touchpad) {
-    ProcessInputEventAck(input_event.type,
-                         INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
-                         latency_info,
-                         ACK_SOURCE_NONE);
-    return;
-  }
-
   if (OfferToOverscrollController(input_event, latency_info))
     return;
 
@@ -515,6 +452,43 @@
   return false;
 }
 
+void InputRouterImpl::SendSyntheticWheelEventForPinch(
+    const GestureEventWithLatencyInfo& pinch_event) {
+  // We match typical trackpad behavior on Windows by sending fake wheel events
+  // with the ctrl modifier set when we see trackpad pinch gestures.  Ideally
+  // we'd someday get a standard 'pinch' event and send that instead.
+
+  WebMouseWheelEvent wheelEvent;
+  wheelEvent.type = WebInputEvent::MouseWheel;
+  wheelEvent.timeStampSeconds = pinch_event.event.timeStampSeconds;
+  wheelEvent.windowX = wheelEvent.x = pinch_event.event.x;
+  wheelEvent.windowY = wheelEvent.y = pinch_event.event.y;
+  wheelEvent.globalX = pinch_event.event.globalX;
+  wheelEvent.globalY = pinch_event.event.globalY;
+  wheelEvent.modifiers =
+      pinch_event.event.modifiers | WebInputEvent::ControlKey;
+  wheelEvent.deltaX = 0;
+  // The function to convert scales to deltaY values is designed to be
+  // compatible with websites existing use of wheel events, and with existing
+  // Windows trackpad behavior.  In particular, we want:
+  //  - deltas should accumulate via addition: f(s1*s2)==f(s1)+f(s2)
+  //  - deltas should invert via negation: f(1/s) == -f(s)
+  //  - zoom in should be positive: f(s) > 0 iff s > 1
+  //  - magnitude roughly matches wheels: f(2) > 25 && f(2) < 100
+  //  - a formula that's relatively easy to use from JavaScript
+  // Note that 'wheel' event deltaY values have their sign inverted.  So to
+  // convert a wheel deltaY back to a scale use Math.exp(-deltaY/100).
+  DCHECK_GT(pinch_event.event.data.pinchUpdate.scale, 0);
+  wheelEvent.deltaY = 100.0f * log(pinch_event.event.data.pinchUpdate.scale);
+  wheelEvent.hasPreciseScrollingDeltas = true;
+  wheelEvent.wheelTicksX = 0;
+  wheelEvent.wheelTicksY =
+      pinch_event.event.data.pinchUpdate.scale > 1 ? 1 : -1;
+
+  SendWheelEvent(QueuedWheelEvent(
+      MouseWheelEventWithLatencyInfo(wheelEvent, pinch_event.latency), true));
+}
+
 void InputRouterImpl::OnInputEventAck(WebInputEvent::Type event_type,
                                       InputEventAckState ack_result,
                                       const ui::LatencyInfo& latency_info) {
@@ -647,20 +621,32 @@
 
 void InputRouterImpl::ProcessWheelAck(InputEventAckState ack_result,
                                       const ui::LatencyInfo& latency) {
-  ProcessAckForOverscroll(current_wheel_event_.event, ack_result);
-
   // TODO(miletus): Add renderer side latency to each uncoalesced mouse
   // wheel event and add terminal component to each of them.
-  current_wheel_event_.latency.AddNewLatencyFrom(latency);
-  // Process the unhandled wheel event here before calling SendWheelEvent()
-  // since it will mutate current_wheel_event_.
-  ack_handler_->OnWheelEventAck(current_wheel_event_, ack_result);
+  current_wheel_event_.event.latency.AddNewLatencyFrom(latency);
+
+  if (current_wheel_event_.synthesized_from_pinch) {
+    // Ack the GesturePinchUpdate event that generated this wheel event.
+    ProcessInputEventAck(WebInputEvent::GesturePinchUpdate,
+                         ack_result,
+                         current_wheel_event_.event.latency,
+                         current_ack_source_);
+  } else {
+    // Process the unhandled wheel event here before calling SendWheelEvent()
+    // since it will mutate current_wheel_event_.
+    ProcessAckForOverscroll(current_wheel_event_.event.event, ack_result);
+    ack_handler_->OnWheelEventAck(current_wheel_event_.event, ack_result);
+  }
+
+  // Mark the wheel event complete only after the ACKs have been handled above.
+  // For example, ACKing the GesturePinchUpdate could cause another
+  // GesturePinchUpdate to be sent, which should queue a wheel event rather than
+  // send it immediately.
   mouse_wheel_pending_ = false;
 
-  // Now send the next (coalesced) mouse wheel event.
+  // Send the next (coalesced or synthetic) mouse wheel event.
   if (!coalesced_mouse_wheel_events_.empty()) {
-    MouseWheelEventWithLatencyInfo next_wheel_event =
-        coalesced_mouse_wheel_events_.front();
+    QueuedWheelEvent next_wheel_event = coalesced_mouse_wheel_events_.front();
     coalesced_mouse_wheel_events_.pop_front();
     SendWheelEvent(next_wheel_event);
   }
@@ -703,11 +689,6 @@
 }
 
 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() {
-  if (!touch_ack_timeout_supported_) {
-    touch_event_queue_.SetAckTimeoutEnabled(false, base::TimeDelta());
-    return;
-  }
-
   // Mobile sites tend to be well-behaved with respect to touch handling, so
   // they have less need for the touch timeout fallback.
   const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0;
@@ -722,8 +703,7 @@
   const bool touch_ack_timeout_enabled = !fixed_page_scale &&
                                          !mobile_viewport &&
                                          !touch_action_none;
-  touch_event_queue_.SetAckTimeoutEnabled(touch_ack_timeout_enabled,
-                                          touch_ack_timeout_delay_);
+  touch_event_queue_.SetAckTimeoutEnabled(touch_ack_timeout_enabled);
 }
 
 void InputRouterImpl::SignalFlushedIfNecessary() {
@@ -752,4 +732,17 @@
   return controller && controller->overscroll_mode() != OVERSCROLL_NONE;
 }
 
+InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent()
+    : synthesized_from_pinch(false) {
+}
+
+InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent(
+    const MouseWheelEventWithLatencyInfo& event,
+    bool synthesized_from_pinch)
+    : event(event), synthesized_from_pinch(synthesized_from_pinch) {
+}
+
+InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() {
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/input/input_router_impl.h b/content/browser/renderer_host/input/input_router_impl.h
index 8c51234..76af1c4 100644
--- a/content/browser/renderer_host/input/input_router_impl.h
+++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -40,10 +40,17 @@
       public NON_EXPORTED_BASE(TouchEventQueueClient),
       public NON_EXPORTED_BASE(TouchpadTapSuppressionControllerClient) {
  public:
+  struct CONTENT_EXPORT Config {
+    Config();
+    GestureEventQueue::Config gesture_config;
+    TouchEventQueue::Config touch_config;
+  };
+
   InputRouterImpl(IPC::Sender* sender,
                   InputRouterClient* client,
                   InputAckHandler* ack_handler,
-                  int routing_id);
+                  int routing_id,
+                  const Config& config);
   virtual ~InputRouterImpl();
 
   // InputRouter
@@ -118,6 +125,26 @@
                        const ui::LatencyInfo& latency_info,
                        bool is_keyboard_shortcut);
 
+  // A data structure that attaches some metadata to a WebMouseWheelEvent
+  // and its latency info.
+  struct QueuedWheelEvent {
+    QueuedWheelEvent();
+    QueuedWheelEvent(const MouseWheelEventWithLatencyInfo& event,
+                     bool synthesized_from_pinch);
+    ~QueuedWheelEvent();
+
+    MouseWheelEventWithLatencyInfo event;
+    bool synthesized_from_pinch;
+  };
+
+  // Enqueue or send a mouse wheel event.
+  void SendWheelEvent(const QueuedWheelEvent& wheel_event);
+
+  // Given a Touchpad GesturePinchUpdate event, create and send a synthetic
+  // wheel event for it.
+  void SendSyntheticWheelEventForPinch(
+      const GestureEventWithLatencyInfo& pinch_event);
+
   // IPC message handlers
   void OnInputEventAck(blink::WebInputEvent::Type event_type,
                        InputEventAckState ack_result,
@@ -173,8 +200,9 @@
 
   // Called when a touch timeout-affecting bit has changed, in turn toggling the
   // touch ack timeout feature of the |touch_event_queue_| as appropriate. Input
-  // to that determination includes current view properties, the allowed touch
-  // action and the command-line configured |touch_ack_timeout_supported_|.
+  // to that determination includes current view properties and the allowed
+  // touch action. Note that this will only affect platforms that have a
+  // non-zero touch timeout configuration.
   void UpdateTouchAckTimeoutEnabled();
 
   // If a flush has been requested, signals a completed flush to the client if
@@ -216,7 +244,7 @@
   // (Similar to |mouse_move_pending_|.) True if a mouse wheel event was sent
   // and we are waiting for a corresponding ack.
   bool mouse_wheel_pending_;
-  MouseWheelEventWithLatencyInfo current_wheel_event_;
+  QueuedWheelEvent current_wheel_event_;
 
   // (Similar to |next_mouse_move_|.) The next mouse wheel events to send.
   // Unlike mouse moves, mouse wheel events received while one is pending are
@@ -225,7 +253,7 @@
   // high rate; not waiting for the ack results in jankiness, and using the same
   // mechanism as for mouse moves (just dropping old events when multiple ones
   // would be queued) results in very slow scrolling.
-  typedef std::deque<MouseWheelEventWithLatencyInfo> WheelEventQueue;
+  typedef std::deque<QueuedWheelEvent> WheelEventQueue;
   WheelEventQueue coalesced_mouse_wheel_events_;
 
   // A queue of keyboard events. We can't trust data from the renderer so we
@@ -237,10 +265,6 @@
   // The time when an input event was sent to the client.
   base::TimeTicks input_event_start_time_;
 
-  // Whether touch ack timeout handling has been enabled via the command line.
-  bool touch_ack_timeout_supported_;
-  base::TimeDelta touch_ack_timeout_delay_;
-
   // Cached flags from |OnViewUpdated()|, defaults to 0.
   int current_view_flags_;
 
diff --git a/content/browser/renderer_host/input/input_router_impl_perftest.cc b/content/browser/renderer_host/input/input_router_impl_perftest.cc
index 717ba4f..972fc49 100644
--- a/content/browser/renderer_host/input/input_router_impl_perftest.cc
+++ b/content/browser/renderer_host/input/input_router_impl_perftest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "base/basictypes.h"
-#include "base/command_line.h"
 #include "base/memory/scoped_ptr.h"
 #include "content/browser/renderer_host/input/input_ack_handler.h"
 #include "content/browser/renderer_host/input/input_router_client.h"
@@ -11,7 +10,6 @@
 #include "content/common/input/web_input_event_traits.h"
 #include "content/common/input_messages.h"
 #include "content/common/view_messages.h"
-#include "content/public/common/content_switches.h"
 #include "ipc/ipc_sender.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/perf/perf_test.h"
@@ -206,17 +204,14 @@
  protected:
   // testing::Test
   virtual void SetUp() OVERRIDE {
-    if (!CommandLine::ForCurrentProcess()->HasSwitch(
-            switches::kDisableGestureDebounce)) {
-      CommandLine::ForCurrentProcess()->AppendSwitch(
-          switches::kDisableGestureDebounce);
-    }
-
     sender_.reset(new NullIPCSender());
     client_.reset(new NullInputRouterClient());
     ack_handler_.reset(new NullInputAckHandler());
-    input_router_.reset(new InputRouterImpl(
-        sender_.get(), client_.get(), ack_handler_.get(), MSG_ROUTING_NONE));
+    input_router_.reset(new InputRouterImpl(sender_.get(),
+                                            client_.get(),
+                                            ack_handler_.get(),
+                                            MSG_ROUTING_NONE,
+                                            InputRouterImpl::Config()));
   }
 
   virtual void TearDown() OVERRIDE {
@@ -238,10 +233,12 @@
     input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch, latency));
   }
 
-  void SendEventAck(blink::WebInputEvent::Type type,
-                    InputEventAckState ack_result) {
+  void SendEventAckIfNecessary(const blink::WebInputEvent& event,
+                               InputEventAckState ack_result) {
+    if (WebInputEventTraits::IgnoresAckDisposition(event))
+      return;
     InputHostMsg_HandleInputEvent_ACK response(
-        0, type, ack_result, ui::LatencyInfo());
+        0, event.type, ack_result, ui::LatencyInfo());
     input_router_->OnMessageReceived(response);
   }
 
@@ -290,11 +287,11 @@
 
       for (; i < event_count; ++i, ++ack_i) {
         SendEvent(events[i], CreateLatencyInfo());
-        SendEventAck(events[ack_i].type, INPUT_EVENT_ACK_STATE_CONSUMED);
+        SendEventAckIfNecessary(events[ack_i], INPUT_EVENT_ACK_STATE_CONSUMED);
       }
 
       if (ack_delay)
-        SendEventAck(events.back().type, INPUT_EVENT_ACK_STATE_CONSUMED);
+        SendEventAckIfNecessary(events.back(), INPUT_EVENT_ACK_STATE_CONSUMED);
 
       EXPECT_EQ(event_count, GetAndResetSentEventCount());
       EXPECT_EQ(event_count, GetAndResetAckCount());
@@ -322,11 +319,12 @@
         // Touches may not be forwarded after the scroll sequence has begun, so
         // only ack if necessary.
         if (!AckCount()) {
-          SendEventAck(touches[i].type, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+          SendEventAckIfNecessary(touches[i],
+                                  INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
         }
 
         SendEvent(gestures[i], CreateLatencyInfo());
-        SendEventAck(gestures[i].type, INPUT_EVENT_ACK_STATE_CONSUMED);
+        SendEventAckIfNecessary(gestures[i], INPUT_EVENT_ACK_STATE_CONSUMED);
         EXPECT_EQ(2U, GetAndResetAckCount());
       }
     }
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc
index de00b47..1039e70 100644
--- a/content/browser/renderer_host/input/input_router_impl_unittest.cc
+++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <math.h>
+
 #include "base/basictypes.h"
 #include "base/command_line.h"
 #include "base/memory/scoped_ptr.h"
@@ -129,6 +131,11 @@
 }
 #endif  // defined(USE_AURA)
 
+// Expected function used for converting pinch scales to deltaY values.
+float PinchScaleToWheelDelta(float scale) {
+  return 100.0 * log(scale);
+}
+
 }  // namespace
 
 class InputRouterImplTest : public testing::Test {
@@ -145,10 +152,11 @@
     ack_handler_.reset(new MockInputAckHandler());
     CommandLine* command_line = CommandLine::ForCurrentProcess();
     command_line->AppendSwitch(switches::kValidateInputEventStream);
-    input_router_.reset(new InputRouterImpl(
-        process_.get(), client_.get(), ack_handler_.get(), MSG_ROUTING_NONE));
-    input_router_->gesture_event_queue_.set_debounce_enabled_for_testing(
-        false);
+    input_router_.reset(new InputRouterImpl(process_.get(),
+                                            client_.get(),
+                                            ack_handler_.get(),
+                                            MSG_ROUTING_NONE,
+                                            config_));
     client_->set_input_router(input_router());
     ack_handler_->set_input_router(input_router());
   }
@@ -163,6 +171,14 @@
     browser_context_.reset();
   }
 
+  void SetUpForTouchAckTimeoutTest(int timeout_ms) {
+    config_.touch_config.touch_ack_timeout_delay =
+        base::TimeDelta::FromMilliseconds(timeout_ms);
+    config_.touch_config.touch_ack_timeout_supported = true;
+    TearDown();
+    SetUp();
+  }
+
   void SimulateKeyboardEvent(WebInputEvent::Type type, bool is_shortcut) {
     WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
     NativeWebKeyboardEvent native_event;
@@ -206,15 +222,14 @@
         SyntheticWebGestureEventBuilder::BuildScrollUpdate(dX, dY, modifiers));
   }
 
-  void SimulateGesturePinchUpdateEvent(float scale,
-                                       float anchorX,
-                                       float anchorY,
-                                       int modifiers) {
-    SimulateGestureEvent(
-        SyntheticWebGestureEventBuilder::BuildPinchUpdate(scale,
-                                                          anchorX,
-                                                          anchorY,
-                                                          modifiers));
+  void SimulateGesturePinchUpdateEvent(
+      float scale,
+      float anchorX,
+      float anchorY,
+      int modifiers,
+      WebGestureEvent::SourceDevice sourceDevice) {
+    SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildPinchUpdate(
+        scale, anchorX, anchorY, modifiers, sourceDevice));
   }
 
   void SimulateGestureFlingStartEvent(
@@ -330,6 +345,7 @@
     base::MessageLoop::current()->Run();
   }
 
+  InputRouterImpl::Config config_;
   scoped_ptr<MockRenderProcessHost> process_;
   scoped_ptr<MockInputRouterClient> client_;
   scoped_ptr<MockInputAckHandler> ack_handler_;
@@ -509,10 +525,21 @@
   SimulateWheelEvent(0, -10, 0, false);  // enqueued
   SimulateWheelEvent(8, -6, 0, false);  // coalesced into previous event
   SimulateWheelEvent(9, -7, 1, false);  // enqueued, different modifiers
+  SimulateWheelEvent(0, -10, 0, false);  // enqueued, different modifiers
+  // Explicitly verify that PhaseEnd isn't coalesced to avoid bugs like
+  // https://crbug.com/154740.
+  SimulateWheelEventWithPhase(WebMouseWheelEvent::PhaseEnded);  // enqueued
 
   // Check that only the first event was sent.
   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
                   InputMsg_HandleInputEvent::ID));
+  const WebInputEvent* input_event =
+      GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
+  const WebMouseWheelEvent* wheel_event =
+      static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_EQ(0, wheel_event->deltaX);
+  EXPECT_EQ(-5, wheel_event->deltaY);
   EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
 
   // Check that the ACK sends the second message immediately.
@@ -525,61 +552,60 @@
   EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
           InputMsg_HandleInputEvent::ID));
+  input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
+  wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_EQ(8, wheel_event->deltaX);
+  EXPECT_EQ(-10 + -6, wheel_event->deltaY);  // coalesced
   EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
 
-  // One more time.
+  // Ack the second event (which had the third coalesced into it).
   SendInputEventACK(WebInputEvent::MouseWheel,
                     INPUT_EVENT_ACK_STATE_CONSUMED);
   base::MessageLoop::current()->RunUntilIdle();
   EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
                   InputMsg_HandleInputEvent::ID));
+  input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
+  wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_EQ(9, wheel_event->deltaX);
+  EXPECT_EQ(-7, wheel_event->deltaY);
   EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
 
-  // After the final ack, the queue should be empty.
+  // Ack the fourth event.
   SendInputEventACK(WebInputEvent::MouseWheel,
                     INPUT_EVENT_ACK_STATE_CONSUMED);
   base::MessageLoop::current()->RunUntilIdle();
   EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
-  EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
-}
-
-TEST_F(InputRouterImplTest,
-       CoalescesWheelEventsQueuedPhaseEndIsNotDropped) {
-  // Send an initial gesture begin and ACK it.
-  SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
-                       WebGestureEvent::Touchpad);
-  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_CONSUMED);
-  base::MessageLoop::current()->RunUntilIdle();
-
-  // Send a wheel event, should get sent directly.
-  SimulateWheelEvent(0, -5, 0, false);
-  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
-
-  // Send a wheel phase end event before an ACK is received for the previous
-  // wheel event, which should get queued.
-  SimulateWheelEventWithPhase(WebMouseWheelEvent::PhaseEnded);
-  EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
-
-  // A gesture event should now result in the queued phase ended event being
-  // transmitted before it.
-  SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
-                       WebGestureEvent::Touchpad);
-
-  // Verify the events that were sent.
-  const WebInputEvent* input_event =
-      GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  EXPECT_TRUE(
+      process_->sink().GetUniqueMessageMatching(InputMsg_HandleInputEvent::ID));
+  input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
   ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
-  const WebMouseWheelEvent* wheel_event =
-      static_cast<const WebMouseWheelEvent*>(input_event);
-  ASSERT_EQ(WebMouseWheelEvent::PhaseEnded, wheel_event->phase);
+  wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_EQ(0, wheel_event->deltaX);
+  EXPECT_EQ(-10, wheel_event->deltaY);
+  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
 
-  input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(1));
-  EXPECT_EQ(WebInputEvent::GestureScrollEnd, input_event->type);
+  // Ack the fifth event.
+  SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
+  base::MessageLoop::current()->RunUntilIdle();
+  EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  EXPECT_TRUE(
+      process_->sink().GetUniqueMessageMatching(InputMsg_HandleInputEvent::ID));
+  input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
+  wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_EQ(0, wheel_event->deltaX);
+  EXPECT_EQ(0, wheel_event->deltaY);
+  EXPECT_EQ(WebMouseWheelEvent::PhaseEnded, wheel_event->phase);
+  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
 
-  ASSERT_EQ(2U, GetSentMessageCountAndResetSink());
+  // After the final ack, the queue should be empty.
+  SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
+  base::MessageLoop::current()->RunUntilIdle();
+  EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
 }
 
 // Tests that touch-events are queued properly.
@@ -1011,17 +1037,11 @@
   EXPECT_EQ(3U, ack_handler_->GetAndResetAckCount());
 }
 
-// Test that touch ack timeout behavior is properly configured via the command
-// line, and toggled by view update flags and allowed touch actions.
+// Test that touch ack timeout behavior is properly toggled by view update flags
+// and allowed touch actions.
 TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
-  // Unless explicitly supported via the command-line, the touch timeout should
-  // be disabled.
-  EXPECT_FALSE(TouchEventTimeoutEnabled());
-
-  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
-      switches::kTouchAckTimeoutDelayMs, "1");
-  TearDown();
-  SetUp();
+  const int timeout_ms = 1;
+  SetUpForTouchAckTimeoutTest(timeout_ms);
   ASSERT_TRUE(TouchEventTimeoutEnabled());
 
   // Verify that the touch ack timeout fires upon the delayed ack.
@@ -1029,7 +1049,7 @@
   SendTouchEvent();
   EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
   EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
-  RunTasksAndWait(base::TimeDelta::FromMilliseconds(2));
+  RunTasksAndWait(base::TimeDelta::FromMilliseconds(timeout_ms + 1));
 
   // The timed-out event should have been ack'ed.
   EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
@@ -1095,10 +1115,8 @@
 // the touch timeout.
 TEST_F(InputRouterImplTest,
        TouchAckTimeoutDisabledForTouchSequenceAfterTouchActionNone) {
-  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
-      switches::kTouchAckTimeoutDelayMs, "1");
-  TearDown();
-  SetUp();
+  const int timeout_ms = 1;
+  SetUpForTouchAckTimeoutTest(timeout_ms);
   ASSERT_TRUE(TouchEventTimeoutEnabled());
   OnHasTouchEventHandlers(true);
 
@@ -1128,7 +1146,7 @@
   EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
 
   // Delay the ack.  The timeout should *not* fire.
-  RunTasksAndWait(base::TimeDelta::FromMilliseconds(2));
+  RunTasksAndWait(base::TimeDelta::FromMilliseconds(timeout_ms + 1));
   EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
   EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
 
@@ -1154,7 +1172,7 @@
   EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
 
   // Wait for the touch ack timeout to fire.
-  RunTasksAndWait(base::TimeDelta::FromMilliseconds(2));
+  RunTasksAndWait(base::TimeDelta::FromMilliseconds(timeout_ms + 1));
   EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
 }
 
@@ -1381,22 +1399,210 @@
 }
 
 // Test that GesturePinchUpdate is handled specially for trackpad
-TEST_F(InputRouterImplTest, TrackpadPinchUpdate) {
-  // For now Trackpad PinchUpdate events are just immediately ACKed
-  // as unconsumed without going to the renderer.
-  // TODO(rbyers): Update for wheel event behavior - crbug.com/289887.
+TEST_F(InputRouterImplTest, TouchpadPinchUpdate) {
+  // GesturePinchUpdate for trackpad sends synthetic wheel events.
   // Note that the Touchscreen case is verified as NOT doing this as
   // part of the ShowPressIsInOrder test.
-  SimulateGestureEvent(WebInputEvent::GesturePinchUpdate,
-                       WebGestureEvent::Touchpad);
-  ASSERT_EQ(0U, GetSentMessageCountAndResetSink());
+
+  SimulateGesturePinchUpdateEvent(1.5f, 20, 25, 0, WebGestureEvent::Touchpad);
+
+  // Verify we actually sent a special wheel event to the renderer.
+  const WebInputEvent* input_event =
+      GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
+  const WebMouseWheelEvent* wheel_event =
+      static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_EQ(20, wheel_event->x);
+  EXPECT_EQ(25, wheel_event->y);
+  EXPECT_EQ(20, wheel_event->globalX);
+  EXPECT_EQ(25, wheel_event->globalY);
+  EXPECT_EQ(20, wheel_event->windowX);
+  EXPECT_EQ(25, wheel_event->windowY);
+  EXPECT_EQ(PinchScaleToWheelDelta(1.5), wheel_event->deltaY);
+  EXPECT_EQ(0, wheel_event->deltaX);
+  EXPECT_EQ(1, wheel_event->hasPreciseScrollingDeltas);
+  EXPECT_EQ(1, wheel_event->wheelTicksY);
+  EXPECT_EQ(0, wheel_event->wheelTicksX);
+  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
+
+  // Indicate that the wheel event was unhandled.
+  SendInputEventACK(WebInputEvent::MouseWheel,
+                    INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+
+  // Check that the correct unhandled pinch event was received.
   EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  ASSERT_EQ(WebInputEvent::GesturePinchUpdate, ack_handler_->ack_event_type());
   EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_handler_->ack_state());
+  EXPECT_EQ(1.5f, ack_handler_->acked_gesture_event().data.pinchUpdate.scale);
   EXPECT_EQ(0, client_->in_flight_event_count());
+
+  // Second a second pinch event.
+  SimulateGesturePinchUpdateEvent(0.3f, 20, 25, 0, WebGestureEvent::Touchpad);
+  input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
+  wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_FLOAT_EQ(PinchScaleToWheelDelta(0.3f), wheel_event->deltaY);
+  EXPECT_EQ(1, wheel_event->hasPreciseScrollingDeltas);
+  EXPECT_EQ(-1, wheel_event->wheelTicksY);
+  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
+
+  // Indicate that the wheel event was handled this time.
+  SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
+
+  // Check that the correct HANDLED pinch event was received.
+  EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::GesturePinchUpdate, ack_handler_->ack_event_type());
+  EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, ack_handler_->ack_state());
+  EXPECT_FLOAT_EQ(0.3f,
+                  ack_handler_->acked_gesture_event().data.pinchUpdate.scale);
 }
 
-// Test proper handling of trackpad Gesture{Pinch,Scroll}Update sequences.
-TEST_F(InputRouterImplTest, TrackpadPinchAndScrollUpdate) {
+// Test that touchpad pinch events are coalesced property, with their synthetic
+// wheel events getting the right ACKs.
+TEST_F(InputRouterImplTest, TouchpadPinchCoalescing) {
+  // Send the first pinch.
+  SimulateGesturePinchUpdateEvent(1.5f, 20, 25, 0, WebGestureEvent::Touchpad);
+
+  // Verify we sent the wheel event to the renderer.
+  const WebInputEvent* input_event =
+      GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
+  const WebMouseWheelEvent* wheel_event =
+      static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_EQ(PinchScaleToWheelDelta(1.5f), wheel_event->deltaY);
+  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
+  EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
+  EXPECT_EQ(1, client_->in_flight_event_count());
+
+  // Send a second pinch, this should be queued in the GestureEventQueue.
+  SimulateGesturePinchUpdateEvent(1.6f, 20, 25, 0, WebGestureEvent::Touchpad);
+  EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+  EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
+
+  // Send a third pinch, this should be coalesced into the second in the
+  // GestureEventQueue.
+  SimulateGesturePinchUpdateEvent(1.7f, 20, 25, 0, WebGestureEvent::Touchpad);
+  EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+  EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
+
+  // Indicate that the first wheel event was unhandled and verify the ACK.
+  SendInputEventACK(WebInputEvent::MouseWheel,
+                    INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+  EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::GesturePinchUpdate, ack_handler_->ack_event_type());
+  EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_handler_->ack_state());
+  EXPECT_EQ(1.5f, ack_handler_->acked_gesture_event().data.pinchUpdate.scale);
+
+  // Verify a second wheel event was sent representing the 2nd and 3rd pinch
+  // events.
+  EXPECT_EQ(1, client_->in_flight_event_count());
+  input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
+  wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_FLOAT_EQ(PinchScaleToWheelDelta(1.6f * 1.7f),
+                  PinchScaleToWheelDelta(1.6f) + PinchScaleToWheelDelta(1.7f));
+  EXPECT_FLOAT_EQ(PinchScaleToWheelDelta(1.6f * 1.7f), wheel_event->deltaY);
+  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
+  EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
+
+  // Indicate that the second wheel event was handled and verify the ACK.
+  SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
+  EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::GesturePinchUpdate, ack_handler_->ack_event_type());
+  EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, ack_handler_->ack_state());
+  EXPECT_FLOAT_EQ(1.6f * 1.7f,
+                  ack_handler_->acked_gesture_event().data.pinchUpdate.scale);
+}
+
+// Test interleaving pinch and wheel events.
+TEST_F(InputRouterImplTest, TouchpadPinchAndWheel) {
+  // Simulate queued wheel and pinch events events.
+  // Note that in practice interleaving pinch and wheel events should be rare
+  // (eg. requires the use of a mouse and trackpad at the same time).
+
+  // Use the control modifier to match the synthetic wheel events so that
+  // they're elligble for coalescing.
+  int mod = WebInputEvent::ControlKey;
+
+  // Event 1: sent directly.
+  SimulateWheelEvent(0, -5, mod, true);
+  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
+
+  // Event 2: enqueued in InputRouter.
+  SimulateWheelEvent(0, -10, mod, true);
+  EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+
+  // Event 3: enqueued in InputRouter, not coalesced into #2.
+  SimulateGesturePinchUpdateEvent(1.5f, 20, 25, 0, WebGestureEvent::Touchpad);
+  EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+
+  // Event 4: enqueued in GestureEventQueue.
+  SimulateGesturePinchUpdateEvent(1.2f, 20, 25, 0, WebGestureEvent::Touchpad);
+  EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+
+  // Event 5: coalesced into wheel event for #3.
+  SimulateWheelEvent(2, 0, mod, true);
+  EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+
+  // Send ack for #1.
+  SendInputEventACK(WebInputEvent::MouseWheel,
+                    INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+  EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::MouseWheel, ack_handler_->ack_event_type());
+
+  // Verify we sent #2.
+  ASSERT_EQ(1U, process_->sink().message_count());
+  const WebInputEvent* input_event =
+      GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
+  const WebMouseWheelEvent* wheel_event =
+      static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_EQ(0, wheel_event->deltaX);
+  EXPECT_EQ(-10, wheel_event->deltaY);
+  EXPECT_EQ(mod, wheel_event->modifiers);
+  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
+
+  // Send ack for #2.
+  SendInputEventACK(WebInputEvent::MouseWheel,
+                    INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+  EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::MouseWheel, ack_handler_->ack_event_type());
+
+  // Verify we sent #3 (with #5 coalesced in).
+  ASSERT_EQ(1U, process_->sink().message_count());
+  input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
+  wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_EQ(2, wheel_event->deltaX);
+  EXPECT_EQ(PinchScaleToWheelDelta(1.5f), wheel_event->deltaY);
+  EXPECT_EQ(mod, wheel_event->modifiers);
+  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
+
+  // Send ack for #3.
+  SendInputEventACK(WebInputEvent::MouseWheel,
+                    INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+  EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::GesturePinchUpdate, ack_handler_->ack_event_type());
+
+  // Verify we sent #4.
+  ASSERT_EQ(1U, process_->sink().message_count());
+  input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
+  ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
+  wheel_event = static_cast<const WebMouseWheelEvent*>(input_event);
+  EXPECT_EQ(0, wheel_event->deltaX);
+  EXPECT_FLOAT_EQ(PinchScaleToWheelDelta(1.2f), wheel_event->deltaY);
+  EXPECT_EQ(mod, wheel_event->modifiers);
+  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
+
+  // Send ack for #4.
+  SendInputEventACK(WebInputEvent::MouseWheel,
+                    INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+  EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  EXPECT_EQ(WebInputEvent::GesturePinchUpdate, ack_handler_->ack_event_type());
+}
+
+// Test proper handling of touchpad Gesture{Pinch,Scroll}Update sequences.
+TEST_F(InputRouterImplTest, TouchpadPinchAndScrollUpdate) {
   // The first scroll should be sent immediately.
   SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
                        WebGestureEvent::Touchpad);
@@ -1426,20 +1632,24 @@
   EXPECT_EQ(1, client_->in_flight_event_count());
 
   // Ack'ing the first scroll should trigger both the coalesced scroll and the
-  // coalesced pinch events.  However, the GesturePinchUpdate should be ack'ed
-  // immediately without going to the renderer.
-  // TODO(rbyers): Update for wheel event behavior - crbug.com/289887.
+  // coalesced pinch events (which is sent to the renderer as a wheel event).
   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
                     INPUT_EVENT_ACK_STATE_CONSUMED);
-  EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
-  EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount());
-  EXPECT_EQ(1, client_->in_flight_event_count());
+  EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
+  EXPECT_EQ(2, client_->in_flight_event_count());
 
   // Ack the second scroll.
   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
                     INPUT_EVENT_ACK_STATE_CONSUMED);
   EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
   EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
+  EXPECT_EQ(1, client_->in_flight_event_count());
+
+  // Ack the wheel event.
+  SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
+  EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+  EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
   EXPECT_EQ(0, client_->in_flight_event_count());
 }
 
diff --git a/content/browser/renderer_host/input/mock_input_ack_handler.cc b/content/browser/renderer_host/input/mock_input_ack_handler.cc
index 0ab903f..3092809 100644
--- a/content/browser/renderer_host/input/mock_input_ack_handler.cc
+++ b/content/browser/renderer_host/input/mock_input_ack_handler.cc
@@ -18,10 +18,12 @@
 namespace content {
 
 MockInputAckHandler::MockInputAckHandler()
-  : input_router_(NULL),
-    ack_count_(0),
-    unexpected_event_ack_called_(false),
-    ack_state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {}
+    : input_router_(NULL),
+      ack_count_(0),
+      unexpected_event_ack_called_(false),
+      ack_event_type_(WebInputEvent::Undefined),
+      ack_state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {
+}
 
 MockInputAckHandler::~MockInputAckHandler() {}
 
@@ -30,7 +32,7 @@
     InputEventAckState ack_result)  {
   VLOG(1) << __FUNCTION__ << " called!";
   acked_key_event_ = event;
-  RecordAckCalled(ack_result);
+  RecordAckCalled(event.type, ack_result);
 }
 
 void MockInputAckHandler::OnWheelEventAck(
@@ -38,7 +40,7 @@
     InputEventAckState ack_result) {
   VLOG(1) << __FUNCTION__ << " called!";
   acked_wheel_event_ = event.event;
-  RecordAckCalled(ack_result);
+  RecordAckCalled(event.event.type, ack_result);
 }
 
 void MockInputAckHandler::OnTouchEventAck(
@@ -46,7 +48,7 @@
     InputEventAckState ack_result) {
   VLOG(1) << __FUNCTION__ << " called!";
   acked_touch_event_ = event;
-  RecordAckCalled(ack_result);
+  RecordAckCalled(event.event.type, ack_result);
   if (touch_followup_event_)
     input_router_->SendTouchEvent(*touch_followup_event_);
   if (gesture_followup_event_)
@@ -58,7 +60,7 @@
     InputEventAckState ack_result) {
   VLOG(1) << __FUNCTION__ << " called!";
   acked_gesture_event_ = event.event;
-  RecordAckCalled(ack_result);
+  RecordAckCalled(event.event.type, ack_result);
 }
 
 void MockInputAckHandler::OnUnexpectedEventAck(UnexpectedEventAckType type)  {
@@ -72,7 +74,9 @@
   return ack_count;
 }
 
-void MockInputAckHandler::RecordAckCalled(InputEventAckState ack_result) {
+void MockInputAckHandler::RecordAckCalled(blink::WebInputEvent::Type type,
+                                          InputEventAckState ack_result) {
+  ack_event_type_ = type;
   ++ack_count_;
   ack_state_ = ack_result;
 }
diff --git a/content/browser/renderer_host/input/mock_input_ack_handler.h b/content/browser/renderer_host/input/mock_input_ack_handler.h
index 88ca9e1..875964a 100644
--- a/content/browser/renderer_host/input/mock_input_ack_handler.h
+++ b/content/browser/renderer_host/input/mock_input_ack_handler.h
@@ -47,6 +47,8 @@
   }
   InputEventAckState ack_state() const { return ack_state_; }
 
+  blink::WebInputEvent::Type ack_event_type() const { return ack_event_type_; }
+
   const NativeWebKeyboardEvent& acked_keyboard_event() const {
     return acked_key_event_;
   }
@@ -61,12 +63,14 @@
   }
 
  private:
-  void RecordAckCalled(InputEventAckState ack_result);
+  void RecordAckCalled(blink::WebInputEvent::Type eventType,
+                       InputEventAckState ack_result);
 
   InputRouter* input_router_;
 
   size_t ack_count_;
   bool unexpected_event_ack_called_;
+  blink::WebInputEvent::Type ack_event_type_;
   InputEventAckState ack_state_;
   NativeWebKeyboardEvent acked_key_event_;
   blink::WebMouseWheelEvent acked_wheel_event_;
diff --git a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc
index 2866f2b..b6b2814 100644
--- a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc
+++ b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc
@@ -86,8 +86,6 @@
           current_scroll_segment_start_position_ +=
               params_.distances[current_scroll_segment_];
           ComputeNextScrollSegment();
-          // Start the next scroll immediately.
-          ForwardTouchInputEvents(timestamp, target);
         } else if (params_.prevent_fling) {
           state_ = STOPPING;
         } else {
diff --git a/content/browser/renderer_host/input/tap_suppression_controller.cc b/content/browser/renderer_host/input/tap_suppression_controller.cc
index 641af6a..c6b17e6 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller.cc
+++ b/content/browser/renderer_host/input/tap_suppression_controller.cc
@@ -10,16 +10,27 @@
 
 namespace content {
 
+TapSuppressionController::Config::Config()
+    : enabled(false),
+      max_cancel_to_down_time(base::TimeDelta::FromMilliseconds(180)),
+      max_tap_gap_time(base::TimeDelta::FromMilliseconds(500)) {
+}
+
 TapSuppressionController::TapSuppressionController(
-    TapSuppressionControllerClient* client)
+    TapSuppressionControllerClient* client,
+    const Config& config)
     : client_(client),
-      state_(TapSuppressionController::NOTHING) {
+      state_(config.enabled ? NOTHING : DISABLED),
+      max_cancel_to_down_time_(config.max_cancel_to_down_time),
+      max_tap_gap_time_(config.max_tap_gap_time) {
 }
 
 TapSuppressionController::~TapSuppressionController() {}
 
 void TapSuppressionController::GestureFlingCancel() {
   switch (state_) {
+    case DISABLED:
+      break;
     case NOTHING:
     case GFC_IN_PROGRESS:
     case LAST_CANCEL_STOPPED_FLING:
@@ -33,6 +44,7 @@
 void TapSuppressionController::GestureFlingCancelAck(bool processed) {
   base::TimeTicks event_time = Now();
   switch (state_) {
+    case DISABLED:
     case NOTHING:
       break;
     case GFC_IN_PROGRESS:
@@ -57,23 +69,21 @@
 bool TapSuppressionController::ShouldDeferTapDown() {
   base::TimeTicks event_time = Now();
   switch (state_) {
+    case DISABLED:
     case NOTHING:
       return false;
     case GFC_IN_PROGRESS:
       state_ = TAP_DOWN_STASHED;
-      StartTapDownTimer(
-          base::TimeDelta::FromMilliseconds(client_->MaxTapGapTimeInMs()));
+      StartTapDownTimer(max_tap_gap_time_);
       return true;
     case TAP_DOWN_STASHED:
       NOTREACHED() << "TapDown on TAP_DOWN_STASHED state";
       state_ = NOTHING;
       return false;
     case LAST_CANCEL_STOPPED_FLING:
-      if ((event_time - fling_cancel_time_).InMilliseconds()
-          < client_->MaxCancelToDownTimeInMs()) {
+      if ((event_time - fling_cancel_time_) < max_cancel_to_down_time_) {
         state_ = TAP_DOWN_STASHED;
-        StartTapDownTimer(
-            base::TimeDelta::FromMilliseconds(client_->MaxTapGapTimeInMs()));
+        StartTapDownTimer(max_tap_gap_time_);
         return true;
       } else {
         state_ = NOTHING;
@@ -86,6 +96,7 @@
 
 bool TapSuppressionController::ShouldSuppressTapEnd() {
   switch (state_) {
+    case DISABLED:
     case NOTHING:
     case GFC_IN_PROGRESS:
       return false;
@@ -115,7 +126,10 @@
 
 void TapSuppressionController::TapDownTimerExpired() {
   switch (state_) {
+    case DISABLED:
     case NOTHING:
+      NOTREACHED() << "Timer fired on invalid state.";
+      break;
     case GFC_IN_PROGRESS:
     case LAST_CANCEL_STOPPED_FLING:
       NOTREACHED() << "Timer fired on invalid state.";
diff --git a/content/browser/renderer_host/input/tap_suppression_controller.h b/content/browser/renderer_host/input/tap_suppression_controller.h
index ef662f3..93977f9 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller.h
+++ b/content/browser/renderer_host/input/tap_suppression_controller.h
@@ -19,7 +19,22 @@
 // GestureFlingCancel are suppressed.
 class CONTENT_EXPORT TapSuppressionController {
  public:
-  explicit TapSuppressionController(TapSuppressionControllerClient* client);
+  struct CONTENT_EXPORT Config {
+    Config();
+
+    // Defaults to false, in which case no suppression is performed.
+    bool enabled;
+
+    // The maximum time allowed between a GestureFlingCancel and its
+    // corresponding tap down.
+    base::TimeDelta max_cancel_to_down_time;
+
+    // The maximum time allowed between a single tap's down and up events.
+    base::TimeDelta max_tap_gap_time;
+  };
+
+  TapSuppressionController(TapSuppressionControllerClient* client,
+                           const Config& config);
   virtual ~TapSuppressionController();
 
   // Should be called whenever a GestureFlingCancel event is received.
@@ -49,17 +64,20 @@
   friend class MockTapSuppressionController;
 
   enum State {
+    DISABLED,
     NOTHING,
     GFC_IN_PROGRESS,
     TAP_DOWN_STASHED,
     LAST_CANCEL_STOPPED_FLING,
   };
 
-
   TapSuppressionControllerClient* client_;
   base::OneShotTimer<TapSuppressionController> tap_down_timer_;
   State state_;
 
+  base::TimeDelta max_cancel_to_down_time_;
+  base::TimeDelta max_tap_gap_time_;
+
   // TODO(rjkroege): During debugging, the event times did not prove reliable.
   // Replace the use of base::TimeTicks with an accurate event time when they
   // become available post http://crbug.com/119556.
diff --git a/content/browser/renderer_host/input/tap_suppression_controller_client.h b/content/browser/renderer_host/input/tap_suppression_controller_client.h
index fcea0e1..075fa08 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller_client.h
+++ b/content/browser/renderer_host/input/tap_suppression_controller_client.h
@@ -13,14 +13,6 @@
  public:
   virtual ~TapSuppressionControllerClient() {}
 
-  // Derived classes should implement this function to return the maximum time
-  // they allow between a GestureFlingCancel and its corresponding tap down.
-  virtual int MaxCancelToDownTimeInMs() = 0;
-
-  // Derived classes should implement this function to return the maximum time
-  // they allow between a single tap's down and up events.
-  virtual int MaxTapGapTimeInMs() = 0;
-
   // Called whenever the deferred tap down (if saved) should be dropped totally.
   virtual void DropStashedTapDown() = 0;
 
diff --git a/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc b/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc
index d436f45..702dc6f 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc
+++ b/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc
@@ -15,6 +15,7 @@
 class MockTapSuppressionController : public TapSuppressionController,
                                      public TapSuppressionControllerClient {
  public:
+  using TapSuppressionController::DISABLED;
   using TapSuppressionController::NOTHING;
   using TapSuppressionController::GFC_IN_PROGRESS;
   using TapSuppressionController::TAP_DOWN_STASHED;
@@ -32,14 +33,11 @@
     STASHED_TAP_DOWN_FORWARDED           = 1 << 7,
   };
 
-  MockTapSuppressionController()
-      : TapSuppressionController(this),
-        max_cancel_to_down_time_in_ms_(1),
-        max_tap_gap_time_in_ms_(1),
+  MockTapSuppressionController(const TapSuppressionController::Config& config)
+      : TapSuppressionController(this, config),
         last_actions_(NONE),
         time_(),
-        timer_started_(false) {
-  }
+        timer_started_(false) {}
 
   virtual ~MockTapSuppressionController() {}
 
@@ -86,14 +84,6 @@
     }
   }
 
-  void set_max_cancel_to_down_time_in_ms(int val) {
-    max_cancel_to_down_time_in_ms_ = val;
-  }
-
-  void set_max_tap_gap_time_in_ms(int val) {
-    max_tap_gap_time_in_ms_ = val;
-  }
-
   State state() { return state_; }
 
   int last_actions() { return last_actions_; }
@@ -114,14 +104,6 @@
 
  private:
   // TapSuppressionControllerClient implementation
-  virtual int MaxCancelToDownTimeInMs() OVERRIDE {
-    return max_cancel_to_down_time_in_ms_;
-  }
-
-  virtual int MaxTapGapTimeInMs() OVERRIDE {
-    return max_tap_gap_time_in_ms_;
-  }
-
   virtual void DropStashedTapDown() OVERRIDE {
     last_actions_ |= TAP_DOWN_DROPPED;
   }
@@ -136,9 +118,6 @@
   using TapSuppressionController::ShouldDeferTapDown;
   using TapSuppressionController::ShouldSuppressTapEnd;
 
-  int max_cancel_to_down_time_in_ms_;
-  int max_tap_gap_time_in_ms_;
-
   int last_actions_;
 
   base::TimeTicks time_;
@@ -158,22 +137,28 @@
  protected:
   // testing::Test
   virtual void SetUp() {
-    tap_suppression_controller_.reset(new MockTapSuppressionController());
+    tap_suppression_controller_.reset(
+        new MockTapSuppressionController(GetConfig()));
   }
 
   virtual void TearDown() {
     tap_suppression_controller_.reset();
   }
 
+  static TapSuppressionController::Config GetConfig() {
+    TapSuppressionController::Config config;
+    config.enabled = true;
+    config.max_cancel_to_down_time = base::TimeDelta::FromMilliseconds(10);
+    config.max_tap_gap_time = base::TimeDelta::FromMilliseconds(10);
+    return config;
+  }
+
   scoped_ptr<MockTapSuppressionController> tap_suppression_controller_;
 };
 
 // Test TapSuppressionController for when GestureFlingCancel Ack comes before
 // TapDown and everything happens without any delays.
 TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapFast) {
-  tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
-  tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
   // Send GestureFlingCancel.
   tap_suppression_controller_->SendGestureFlingCancel();
   EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -207,9 +192,6 @@
 // Test TapSuppressionController for when GestureFlingCancel Ack comes before
 // TapDown, but there is a small delay between TapDown and TapUp.
 TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapInsufficientlyLateTapUp) {
-  tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
-  tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
   // Send GestureFlingCancel.
   tap_suppression_controller_->SendGestureFlingCancel();
   EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -251,9 +233,6 @@
 // Test TapSuppressionController for when GestureFlingCancel Ack comes before
 // TapDown, but there is a long delay between TapDown and TapUp.
 TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapSufficientlyLateTapUp) {
-  tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
-  tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
   // Send GestureFlingCancel.
   tap_suppression_controller_->SendGestureFlingCancel();
   EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -294,9 +273,6 @@
 // Test TapSuppressionController for when GestureFlingCancel Ack comes before
 // TapDown, but there is a small delay between the Ack and TapDown.
 TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapInsufficientlyLateTapDown) {
-  tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
-  tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
   // Send GestureFlingCancel.
   tap_suppression_controller_->SendGestureFlingCancel();
   EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -338,9 +314,6 @@
 // Test TapSuppressionController for when GestureFlingCancel Ack comes before
 // TapDown, but there is a long delay between the Ack and TapDown.
 TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapSufficientlyLateTapDown) {
-  tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
-  tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
   // Send GestureFlingCancel.
   tap_suppression_controller_->SendGestureFlingCancel();
   EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -381,9 +354,6 @@
 // Test TapSuppressionController for when unprocessed GestureFlingCancel Ack
 // comes after TapDown and everything happens without any delay.
 TEST_F(TapSuppressionControllerTest, GFCAckUnprocessedAfterTapFast) {
-  tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
-  tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
   // Send GestureFlingCancel.
   tap_suppression_controller_->SendGestureFlingCancel();
   EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -417,9 +387,6 @@
 // Test TapSuppressionController for when processed GestureFlingCancel Ack comes
 // after TapDown and everything happens without any delay.
 TEST_F(TapSuppressionControllerTest, GFCAckProcessedAfterTapFast) {
-  tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
-  tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
   // Send GestureFlingCancel.
   tap_suppression_controller_->SendGestureFlingCancel();
   EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -453,9 +420,6 @@
 // Test TapSuppressionController for when GestureFlingCancel Ack comes after
 // TapDown and there is a small delay between the Ack and TapUp.
 TEST_F(TapSuppressionControllerTest, GFCAckAfterTapInsufficientlyLateTapUp) {
-  tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
-  tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
   // Send GestureFlingCancel.
   tap_suppression_controller_->SendGestureFlingCancel();
   EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -497,9 +461,6 @@
 // Test TapSuppressionController for when GestureFlingCancel Ack comes after
 // TapDown and there is a long delay between the Ack and TapUp.
 TEST_F(TapSuppressionControllerTest, GFCAckAfterTapSufficientlyLateTapUp) {
-  tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
-  tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
   // Send GestureFlingCancel.
   tap_suppression_controller_->SendGestureFlingCancel();
   EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -537,4 +498,40 @@
             tap_suppression_controller_->state());
 }
 
+// Test that no suppression occurs if the TapSuppressionController is disabled.
+TEST_F(TapSuppressionControllerTest, NoSuppressionIfDisabled) {
+  TapSuppressionController::Config disabled_config;
+  disabled_config.enabled = false;
+  tap_suppression_controller_.reset(
+      new MockTapSuppressionController(disabled_config));
+
+  // Send GestureFlingCancel.
+  tap_suppression_controller_->SendGestureFlingCancel();
+  EXPECT_EQ(MockTapSuppressionController::NONE,
+            tap_suppression_controller_->last_actions());
+  EXPECT_EQ(MockTapSuppressionController::DISABLED,
+            tap_suppression_controller_->state());
+
+  // Send GestureFlingCancel Ack.
+  tap_suppression_controller_->SendGestureFlingCancelAck(true);
+  EXPECT_EQ(MockTapSuppressionController::NONE,
+            tap_suppression_controller_->last_actions());
+  EXPECT_EQ(MockTapSuppressionController::DISABLED,
+            tap_suppression_controller_->state());
+
+  // Send TapDown. This TapDown should not be suppressed.
+  tap_suppression_controller_->SendTapDown();
+  EXPECT_EQ(MockTapSuppressionController::TAP_DOWN_FORWARDED,
+            tap_suppression_controller_->last_actions());
+  EXPECT_EQ(MockTapSuppressionController::DISABLED,
+            tap_suppression_controller_->state());
+
+  // Send TapUp. This TapUp should not be suppressed.
+  tap_suppression_controller_->SendTapUp();
+  EXPECT_EQ(MockTapSuppressionController::TAP_UP_FORWARDED,
+            tap_suppression_controller_->last_actions());
+  EXPECT_EQ(MockTapSuppressionController::DISABLED,
+            tap_suppression_controller_->state());
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/input/touch_action_browsertest.cc b/content/browser/renderer_host/input/touch_action_browsertest.cc
index 6275f47..ab6564d 100644
--- a/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -13,11 +13,11 @@
 #include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h"
 #include "content/browser/renderer_host/input/touch_event_queue.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/common/input/synthetic_gesture_params.h"
 #include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
 #include "content/common/input_messages.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/common/content_switches.h"
diff --git a/content/browser/renderer_host/input/touch_action_filter_unittest.cc b/content/browser/renderer_host/input/touch_action_filter_unittest.cc
index 3822124..e099c9b 100644
--- a/content/browser/renderer_host/input/touch_action_filter_unittest.cc
+++ b/content/browser/renderer_host/input/touch_action_filter_unittest.cc
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/browser/renderer_host/input/touch_action_filter.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/common/input/synthetic_web_input_event_builders.h"
-#include "content/port/browser/event_with_latency_info.h"
-#include "content/port/common/input_event_ack_state.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 
@@ -382,7 +382,8 @@
   WebGestureEvent pinch_begin = SyntheticWebGestureEventBuilder::Build(
           WebInputEvent::GesturePinchBegin, WebGestureEvent::Touchscreen);
   WebGestureEvent pinch_update =
-      SyntheticWebGestureEventBuilder::BuildPinchUpdate(1.2f, 5, 5, 0);
+      SyntheticWebGestureEventBuilder::BuildPinchUpdate(
+          1.2f, 5, 5, 0, WebGestureEvent::Touchscreen);
   WebGestureEvent pinch_end = SyntheticWebGestureEventBuilder::Build(
           WebInputEvent::GesturePinchEnd, WebGestureEvent::Touchscreen);
   WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
diff --git a/content/browser/renderer_host/input/touch_emulator.h b/content/browser/renderer_host/input/touch_emulator.h
index 9ee6500..af1e056 100644
--- a/content/browser/renderer_host/input/touch_emulator.h
+++ b/content/browser/renderer_host/input/touch_emulator.h
@@ -7,7 +7,7 @@
 
 #include "content/browser/renderer_host/input/touch_emulator_client.h"
 #include "content/common/cursors/webcursor.h"
-#include "content/port/common/input_event_ack_state.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #include "ui/events/gesture_detection/filtered_gesture_provider.h"
 
diff --git a/content/browser/renderer_host/input/touch_emulator_unittest.cc b/content/browser/renderer_host/input/touch_emulator_unittest.cc
index 88ba251..d04fdae 100644
--- a/content/browser/renderer_host/input/touch_emulator_unittest.cc
+++ b/content/browser/renderer_host/input/touch_emulator_unittest.cc
@@ -46,7 +46,7 @@
   // testing::Test
   virtual void SetUp() OVERRIDE {
 #if defined(USE_AURA)
-    aura::Env::CreateInstance();
+    aura::Env::CreateInstance(true);
     screen_.reset(aura::TestScreen::Create());
     gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
 #endif
diff --git a/content/browser/renderer_host/input/touch_event_queue.cc b/content/browser/renderer_host/input/touch_event_queue.cc
index 16d9e11..1877281 100644
--- a/content/browser/renderer_host/input/touch_event_queue.cc
+++ b/content/browser/renderer_host/input/touch_event_queue.cc
@@ -5,12 +5,10 @@
 #include "content/browser/renderer_host/input/touch_event_queue.h"
 
 #include "base/auto_reset.h"
-#include "base/command_line.h"
 #include "base/debug/trace_event.h"
 #include "base/stl_util.h"
 #include "content/browser/renderer_host/input/timeout_monitor.h"
 #include "content/common/input/web_touch_event_traits.h"
-#include "content/public/common/content_switches.h"
 #include "ui/gfx/geometry/point_f.h"
 
 using blink::WebInputEvent;
@@ -35,8 +33,6 @@
 // region and DPI scale are reasonably proportioned).
 const float kSlopEpsilon = .05f;
 
-typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
-
 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent(
     const TouchEventWithLatencyInfo& event_to_cancel) {
   TouchEventWithLatencyInfo event = event_to_cancel;
@@ -73,7 +69,9 @@
         timeout_delay_(timeout_delay),
         pending_ack_state_(PENDING_ACK_NONE),
         timeout_monitor_(base::Bind(&TouchTimeoutHandler::OnTimeOut,
-                                    base::Unretained(this))) {}
+                                    base::Unretained(this))) {
+    DCHECK(timeout_delay != base::TimeDelta());
+  }
 
   ~TouchTimeoutHandler() {}
 
@@ -197,42 +195,42 @@
   TouchMoveSlopSuppressor(double slop_suppression_length_dips)
       : slop_suppression_length_dips_squared_(slop_suppression_length_dips *
                                               slop_suppression_length_dips),
-        suppressing_touch_moves_(false) {}
+        suppressing_touchmoves_(false) {}
 
   bool FilterEvent(const WebTouchEvent& event) {
     if (WebTouchEventTraits::IsTouchSequenceStart(event)) {
       touch_sequence_start_position_ =
           gfx::PointF(event.touches[0].position);
-      suppressing_touch_moves_ = slop_suppression_length_dips_squared_ != 0;
+      suppressing_touchmoves_ = slop_suppression_length_dips_squared_ != 0;
     }
 
     if (event.type != WebInputEvent::TouchMove)
       return false;
 
-    if (suppressing_touch_moves_) {
+    if (suppressing_touchmoves_) {
       // Movement with a secondary pointer should terminate suppression.
       if (event.touchesLength > 1) {
-        suppressing_touch_moves_ = false;
+        suppressing_touchmoves_ = false;
       } else if (event.touchesLength == 1) {
         // Movement outside of the slop region should terminate suppression.
         gfx::PointF position(event.touches[0].position);
         if ((position - touch_sequence_start_position_).LengthSquared() >
             slop_suppression_length_dips_squared_)
-          suppressing_touch_moves_ = false;
+          suppressing_touchmoves_ = false;
       }
     }
-    return suppressing_touch_moves_;
+    return suppressing_touchmoves_;
   }
 
   void ConfirmTouchEvent(InputEventAckState ack_result) {
     if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
-      suppressing_touch_moves_ = false;
+      suppressing_touchmoves_ = false;
   }
 
  private:
   double slop_suppression_length_dips_squared_;
   gfx::PointF touch_sequence_start_position_;
-  bool suppressing_touch_moves_;
+  bool suppressing_touchmoves_;
 
   DISALLOW_COPY_AND_ASSIGN(TouchMoveSlopSuppressor);
 };
@@ -316,26 +314,37 @@
 
   // This is the list of the original events that were coalesced, each requiring
   // future ack dispatch to the client.
+  typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
   WebTouchEventWithLatencyList events_to_ack_;
 
   DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent);
 };
 
+TouchEventQueue::Config::Config()
+    : touchmove_slop_suppression_length_dips(0),
+      touch_scrolling_mode(TOUCH_SCROLLING_MODE_DEFAULT),
+      touch_ack_timeout_delay(base::TimeDelta::FromMilliseconds(200)),
+      touch_ack_timeout_supported(false) {
+}
+
 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client,
-                                 TouchScrollingMode mode,
-                                 double touchmove_suppression_length_dips)
+                                 const Config& config)
     : client_(client),
       dispatching_touch_ack_(NULL),
       dispatching_touch_(false),
       touch_filtering_state_(TOUCH_FILTERING_STATE_DEFAULT),
-      ack_timeout_enabled_(false),
+      ack_timeout_enabled_(config.touch_ack_timeout_supported),
       touchmove_slop_suppressor_(new TouchMoveSlopSuppressor(
-          touchmove_suppression_length_dips + kSlopEpsilon)),
+          config.touchmove_slop_suppression_length_dips + kSlopEpsilon)),
       send_touch_events_async_(false),
-      needs_async_touch_move_for_outer_slop_region_(false),
+      needs_async_touchmove_for_outer_slop_region_(false),
       last_sent_touch_timestamp_sec_(0),
-      touch_scrolling_mode_(mode) {
+      touch_scrolling_mode_(config.touch_scrolling_mode) {
   DCHECK(client);
+  if (ack_timeout_enabled_) {
+    timeout_handler_.reset(
+        new TouchTimeoutHandler(this, config.touch_ack_timeout_delay));
+  }
 }
 
 TouchEventQueue::~TouchEventQueue() {
@@ -447,22 +456,22 @@
     // application be sent touches at key points in the gesture stream,
     // e.g., when the application slop region is exceeded or touchmove
     // coalescing fails because of different modifiers.
-    const bool send_touch_move_now =
+    const bool send_touchmove_now =
         size() > 1 ||
         (touch.event.timeStampSeconds >=
          last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec) ||
-        (needs_async_touch_move_for_outer_slop_region_ &&
+        (needs_async_touchmove_for_outer_slop_region_ &&
          OutsideApplicationSlopRegion(touch.event,
                                       touch_sequence_start_position_)) ||
-        (pending_async_touch_move_ &&
-         !pending_async_touch_move_->CanCoalesceWith(touch));
+        (pending_async_touchmove_ &&
+         !pending_async_touchmove_->CanCoalesceWith(touch));
 
-    if (!send_touch_move_now) {
-      if (!pending_async_touch_move_) {
-        pending_async_touch_move_.reset(new TouchEventWithLatencyInfo(touch));
+    if (!send_touchmove_now) {
+      if (!pending_async_touchmove_) {
+        pending_async_touchmove_.reset(new TouchEventWithLatencyInfo(touch));
       } else {
-        DCHECK(pending_async_touch_move_->CanCoalesceWith(touch));
-        pending_async_touch_move_->CoalesceWith(touch);
+        DCHECK(pending_async_touchmove_->CanCoalesceWith(touch));
+        pending_async_touchmove_->CoalesceWith(touch);
       }
       DCHECK_EQ(1U, size());
       PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
@@ -480,14 +489,14 @@
   // Flush any pending async touch move. If it can be combined with the current
   // (touchmove) event, great, otherwise send it immediately but separately. Its
   // ack will trigger forwarding of the original |touch| event.
-  if (pending_async_touch_move_) {
-    if (pending_async_touch_move_->CanCoalesceWith(touch)) {
-      pending_async_touch_move_->CoalesceWith(touch);
-      pending_async_touch_move_->event.cancelable = !send_touch_events_async_;
-      touch = *pending_async_touch_move_.Pass();
+  if (pending_async_touchmove_) {
+    if (pending_async_touchmove_->CanCoalesceWith(touch)) {
+      pending_async_touchmove_->CoalesceWith(touch);
+      pending_async_touchmove_->event.cancelable = !send_touch_events_async_;
+      touch = *pending_async_touchmove_.Pass();
     } else {
       scoped_ptr<TouchEventWithLatencyInfo> async_move =
-          pending_async_touch_move_.Pass();
+          pending_async_touchmove_.Pass();
       async_move->event.cancelable = false;
       touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true));
       SendTouchEventImmediately(*async_move);
@@ -534,9 +543,9 @@
       }
     }
 
-    pending_async_touch_move_.reset();
+    pending_async_touchmove_.reset();
     send_touch_events_async_ = true;
-    needs_async_touch_move_for_outer_slop_region_ = true;
+    needs_async_touchmove_for_outer_slop_region_ = true;
     return;
   }
 
@@ -579,11 +588,11 @@
   // Note that there's no guarantee that this ACK is for the most recent
   // gesture event (or even part of the current sequence).  Worst case, the
   // delay in updating the absorption state will result in minor UI glitches.
-  // A valid |pending_async_touch_move_| will be flushed when the next event is
+  // A valid |pending_async_touchmove_| will be flushed when the next event is
   // forwarded.
   send_touch_events_async_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED);
   if (!send_touch_events_async_)
-    needs_async_touch_move_for_outer_slop_region_ = false;
+    needs_async_touchmove_for_outer_slop_region_ = false;
 }
 
 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) {
@@ -601,7 +610,7 @@
     // TODO(jdduke): Synthesize a TouchCancel if necessary to update Blink touch
     // state tracking (e.g., if the touch handler was removed mid-sequence).
     touch_filtering_state_ = DROP_ALL_TOUCHES;
-    pending_async_touch_move_.reset();
+    pending_async_touchmove_.reset();
     if (timeout_handler_)
       timeout_handler_->Reset();
     if (!touch_queue_.empty())
@@ -621,29 +630,30 @@
   return (event.type == WebInputEvent::TouchStart);
 }
 
-void TouchEventQueue::SetAckTimeoutEnabled(bool enabled,
-                                           base::TimeDelta ack_timeout_delay) {
-  if (!enabled) {
-    ack_timeout_enabled_ = false;
-    if (touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT)
-      touch_filtering_state_ = FORWARD_ALL_TOUCHES;
-    // Only reset the |timeout_handler_| if the timer is running and has not yet
-    // timed out. This ensures that an already timed out sequence is properly
-    // flushed by the handler.
-    if (timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning())
-      timeout_handler_->Reset();
-    return;
-  }
-
-  ack_timeout_enabled_ = true;
+void TouchEventQueue::SetAckTimeoutEnabled(bool enabled) {
+  // The timeout handler is valid only if explicitly supported in the config.
   if (!timeout_handler_)
-    timeout_handler_.reset(new TouchTimeoutHandler(this, ack_timeout_delay));
-  else
-    timeout_handler_->set_timeout_delay(ack_timeout_delay);
+    return;
+
+  if (ack_timeout_enabled_ == enabled)
+    return;
+
+  ack_timeout_enabled_ = enabled;
+
+  if (enabled)
+    return;
+
+  if (touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT)
+    touch_filtering_state_ = FORWARD_ALL_TOUCHES;
+  // Only reset the |timeout_handler_| if the timer is running and has not yet
+  // timed out. This ensures that an already timed out sequence is properly
+  // flushed by the handler.
+  if (timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning())
+    timeout_handler_->Reset();
 }
 
 bool TouchEventQueue::HasPendingAsyncTouchMoveForTesting() const {
-  return pending_async_touch_move_;
+  return pending_async_touchmove_;
 }
 
 bool TouchEventQueue::IsTimeoutRunningForTesting() const {
@@ -658,7 +668,7 @@
 void TouchEventQueue::FlushQueue() {
   DCHECK(!dispatching_touch_ack_);
   DCHECK(!dispatching_touch_);
-  pending_async_touch_move_.reset();
+  pending_async_touchmove_.reset();
   if (touch_filtering_state_ != DROP_ALL_TOUCHES)
     touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
   while (!touch_queue_.empty())
@@ -700,14 +710,14 @@
 
 void TouchEventQueue::SendTouchEventImmediately(
     const TouchEventWithLatencyInfo& touch) {
-  if (needs_async_touch_move_for_outer_slop_region_) {
+  if (needs_async_touchmove_for_outer_slop_region_) {
     // Any event other than a touchmove (e.g., touchcancel or secondary
     // touchstart) after a scroll has started will interrupt the need to send a
     // an outer slop-region exceeding touchmove.
     if (touch.event.type != WebInputEvent::TouchMove ||
         OutsideApplicationSlopRegion(touch.event,
                                      touch_sequence_start_position_))
-      needs_async_touch_move_for_outer_slop_region_ = false;
+      needs_async_touchmove_for_outer_slop_region_ = false;
   }
 
   client_->SendTouchEventImmediately(touch);
diff --git a/content/browser/renderer_host/input/touch_event_queue.h b/content/browser/renderer_host/input/touch_event_queue.h
index 9290d40..0e24073 100644
--- a/content/browser/renderer_host/input/touch_event_queue.h
+++ b/content/browser/renderer_host/input/touch_event_queue.h
@@ -10,9 +10,9 @@
 
 #include "base/basictypes.h"
 #include "base/time/time.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/common/content_export.h"
-#include "content/port/browser/event_with_latency_info.h"
-#include "content/port/common/input_event_ack_state.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #include "ui/gfx/geometry/point_f.h"
 
@@ -55,12 +55,29 @@
     TOUCH_SCROLLING_MODE_DEFAULT = TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE
   };
 
-  // The |client| must outlive the TouchEventQueue. If
-  // |touchmove_suppression_length_dips| <= 0, touch move suppression is
-  // disabled.
-  TouchEventQueue(TouchEventQueueClient* client,
-                  TouchScrollingMode mode,
-                  double touchmove_suppression_length_dips);
+  struct CONTENT_EXPORT Config {
+    Config();
+
+    // Determines the bounds of the (square) touchmove slop suppression region.
+    // Defaults to 0 (disabled).
+    double touchmove_slop_suppression_length_dips;
+
+    // Determines the type of touch scrolling.
+    // Defaults to TouchEventQueue:::TOUCH_SCROLLING_MODE_DEFAULT.
+    TouchEventQueue::TouchScrollingMode touch_scrolling_mode;
+
+    // Controls whether touch ack timeouts will trigger touch cancellation.
+    // Defaults to 200ms.
+    base::TimeDelta touch_ack_timeout_delay;
+
+    // Whether the platform supports touch ack timeout behavior.
+    // Defaults to false (disabled).
+    bool touch_ack_timeout_supported;
+  };
+
+  // The |client| must outlive the TouchEventQueue.
+  TouchEventQueue(TouchEventQueueClient* client, const Config& config);
+
   ~TouchEventQueue();
 
   // Adds an event to the queue. The event may be coalesced with previously
@@ -95,7 +112,7 @@
   // Sets whether a delayed touch ack will cancel and flush the current
   // touch sequence. Note that, if the timeout was previously disabled, enabling
   // it will take effect only for the following touch sequence.
-  void SetAckTimeoutEnabled(bool enabled, base::TimeDelta ack_timeout_delay);
+  void SetAckTimeoutEnabled(bool enabled);
 
   bool empty() const WARN_UNUSED_RESULT {
     return touch_queue_.empty();
@@ -200,7 +217,7 @@
   };
   TouchFilteringState touch_filtering_state_;
 
-  // Optional handler for timed-out touch event acks, disabled by default.
+  // Optional handler for timed-out touch event acks.
   bool ack_timeout_enabled_;
   scoped_ptr<TouchTimeoutHandler> timeout_handler_;
 
@@ -210,12 +227,12 @@
 
   // Whether touch events should remain buffered and dispatched asynchronously
   // while a scroll sequence is active.  In this mode, touchmove's are throttled
-  // and ack'ed immediately, but remain buffered in |pending_async_touch_move_|
+  // and ack'ed immediately, but remain buffered in |pending_async_touchmove_|
   // until a sufficient time period has elapsed since the last sent touch event.
   // For details see the design doc at http://goo.gl/lVyJAa.
   bool send_touch_events_async_;
-  bool needs_async_touch_move_for_outer_slop_region_;
-  scoped_ptr<TouchEventWithLatencyInfo> pending_async_touch_move_;
+  bool needs_async_touchmove_for_outer_slop_region_;
+  scoped_ptr<TouchEventWithLatencyInfo> pending_async_touchmove_;
   double last_sent_touch_timestamp_sec_;
 
   // How touch events are handled during scrolling.  For now this is a global
diff --git a/content/browser/renderer_host/input/touch_event_queue_unittest.cc b/content/browser/renderer_host/input/touch_event_queue_unittest.cc
index 779cf25..6c23e98 100644
--- a/content/browser/renderer_host/input/touch_event_queue_unittest.cc
+++ b/content/browser/renderer_host/input/touch_event_queue_unittest.cc
@@ -40,14 +40,7 @@
   virtual ~TouchEventQueueTest() {}
 
   // testing::Test
-  virtual void SetUp() OVERRIDE {
-    ResetQueueWithParameters(touch_scrolling_mode_, slop_length_dips_);
-  }
-
-  virtual void SetTouchScrollingMode(TouchEventQueue::TouchScrollingMode mode) {
-    touch_scrolling_mode_ = mode;
-    ResetQueueWithParameters(touch_scrolling_mode_, slop_length_dips_);
-  }
+  virtual void SetUp() OVERRIDE { ResetQueueWithConfig(CreateConfig()); }
 
   virtual void TearDown() OVERRIDE {
     queue_.reset();
@@ -83,14 +76,28 @@
   }
 
  protected:
+  TouchEventQueue::Config CreateConfig() {
+    TouchEventQueue::Config config;
+    config.touch_scrolling_mode = touch_scrolling_mode_;
+    config.touchmove_slop_suppression_length_dips = slop_length_dips_;
+    return config;
+  }
 
-  void SetUpForTimeoutTesting(base::TimeDelta timeout_delay) {
-    queue_->SetAckTimeoutEnabled(true, timeout_delay);
+  void SetTouchScrollingMode(TouchEventQueue::TouchScrollingMode mode) {
+    touch_scrolling_mode_ = mode;
+    ResetQueueWithConfig(CreateConfig());
   }
 
   void SetUpForTouchMoveSlopTesting(double slop_length_dips) {
     slop_length_dips_ = slop_length_dips;
-    ResetQueueWithParameters(touch_scrolling_mode_, slop_length_dips_);
+    ResetQueueWithConfig(CreateConfig());
+  }
+
+  void SetUpForTimeoutTesting(base::TimeDelta timeout_delay) {
+    TouchEventQueue::Config config = CreateConfig();
+    config.touch_ack_timeout_delay = timeout_delay;
+    config.touch_ack_timeout_supported = true;
+    ResetQueueWithConfig(config);
   }
 
   void SendTouchEvent(const WebTouchEvent& event) {
@@ -183,9 +190,7 @@
     queue_->OnHasTouchEventHandlers(has_handlers);
   }
 
-  void SetAckTimeoutDisabled() {
-    queue_->SetAckTimeoutEnabled(false, base::TimeDelta());
-  }
+  void SetAckTimeoutDisabled() { queue_->SetAckTimeoutEnabled(false); }
 
   bool IsTimeoutEnabled() const { return queue_->ack_timeout_enabled(); }
 
@@ -227,9 +232,8 @@
     touch_event_.ResetPoints();
   }
 
-  void ResetQueueWithParameters(TouchEventQueue::TouchScrollingMode mode,
-                                double slop_length_dips) {
-    queue_.reset(new TouchEventQueue(this, mode, slop_length_dips));
+  void ResetQueueWithConfig(const TouchEventQueue::Config& config) {
+    queue_.reset(new TouchEventQueue(this, config));
     queue_->OnHasTouchEventHandlers(true);
   }
 
diff --git a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc
index d920779..d309742 100644
--- a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc
+++ b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc
@@ -4,45 +4,43 @@
 
 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
 
-#include "content/browser/renderer_host/input/tap_suppression_controller.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
-
-// The default implementation of the TouchpadTapSuppressionController does not
-// suppress taps. Touchpad tap suppression is needed only on CrOS.
-
 namespace content {
 
 TouchpadTapSuppressionController::TouchpadTapSuppressionController(
-    TouchpadTapSuppressionControllerClient* /* client */)
-    : client_(NULL) {}
+    TouchpadTapSuppressionControllerClient* client,
+    const TapSuppressionController::Config& config)
+    : client_(client), controller_(this, config) {
+}
 
 TouchpadTapSuppressionController::~TouchpadTapSuppressionController() {}
 
-void TouchpadTapSuppressionController::GestureFlingCancel() {}
+void TouchpadTapSuppressionController::GestureFlingCancel() {
+  controller_.GestureFlingCancel();
+}
 
-void TouchpadTapSuppressionController::GestureFlingCancelAck(
-    bool /*processed*/) {
+void TouchpadTapSuppressionController::GestureFlingCancelAck(bool processed) {
+  controller_.GestureFlingCancelAck(processed);
 }
 
 bool TouchpadTapSuppressionController::ShouldDeferMouseDown(
-    const MouseEventWithLatencyInfo& /*event*/) {
-  return false;
+    const MouseEventWithLatencyInfo& event) {
+  bool should_defer = controller_.ShouldDeferTapDown();
+  if (should_defer)
+    stashed_mouse_down_ = event;
+  return should_defer;
 }
 
-bool TouchpadTapSuppressionController::ShouldSuppressMouseUp() { return false; }
-
-int TouchpadTapSuppressionController::MaxCancelToDownTimeInMs() {
-  return 0;
-}
-
-int TouchpadTapSuppressionController::MaxTapGapTimeInMs() {
-  return 0;
+bool TouchpadTapSuppressionController::ShouldSuppressMouseUp() {
+  return controller_.ShouldSuppressTapEnd();
 }
 
 void TouchpadTapSuppressionController::DropStashedTapDown() {
 }
 
 void TouchpadTapSuppressionController::ForwardStashedTapDown() {
+  // Mouse downs are not handled by gesture event filter; so, they are
+  // immediately forwarded to the renderer.
+  client_->SendMouseEventImmediately(stashed_mouse_down_);
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
index 64b2ed4..da74dfd 100644
--- a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
+++ b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
@@ -5,10 +5,10 @@
 #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_TAP_SUPPRESSION_CONTROLLER_H_
 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_TAP_SUPPRESSION_CONTROLLER_H_
 
-#include "base/memory/scoped_ptr.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
+#include "content/browser/renderer_host/input/tap_suppression_controller.h"
 #include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
 #include "content/common/content_export.h"
-#include "content/port/browser/event_with_latency_info.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 
 namespace content {
@@ -27,8 +27,9 @@
 class TouchpadTapSuppressionController : public TapSuppressionControllerClient {
  public:
   // The |client| must outlive the TouchpadTapSupressionController.
-  explicit TouchpadTapSuppressionController(
-      TouchpadTapSuppressionControllerClient* client);
+  TouchpadTapSuppressionController(
+      TouchpadTapSuppressionControllerClient* client,
+      const TapSuppressionController::Config& config);
   virtual ~TouchpadTapSuppressionController();
 
   // Should be called on arrival of GestureFlingCancel events.
@@ -51,8 +52,6 @@
   friend class MockRenderWidgetHost;
 
   // TapSuppressionControllerClient implementation.
-  virtual int MaxCancelToDownTimeInMs() OVERRIDE;
-  virtual int MaxTapGapTimeInMs() OVERRIDE;
   virtual void DropStashedTapDown() OVERRIDE;
   virtual void ForwardStashedTapDown() OVERRIDE;
 
@@ -60,7 +59,7 @@
   MouseEventWithLatencyInfo stashed_mouse_down_;
 
   // The core controller of tap suppression.
-  scoped_ptr<TapSuppressionController> controller_;
+  TapSuppressionController controller_;
 
   DISALLOW_COPY_AND_ASSIGN(TouchpadTapSuppressionController);
 };
diff --git a/content/browser/renderer_host/input/touchpad_tap_suppression_controller_aura.cc b/content/browser/renderer_host/input/touchpad_tap_suppression_controller_aura.cc
deleted file mode 100644
index 991097d..0000000
--- a/content/browser/renderer_host/input/touchpad_tap_suppression_controller_aura.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2013 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.
-
-#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
-
-#include "content/browser/renderer_host/input/tap_suppression_controller.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
-#include "ui/events/gestures/gesture_configuration.h"
-
-namespace content {
-
-TouchpadTapSuppressionController::TouchpadTapSuppressionController(
-    TouchpadTapSuppressionControllerClient* client)
-    : client_(client),
-      controller_(new TapSuppressionController(this)) {
-}
-
-TouchpadTapSuppressionController::~TouchpadTapSuppressionController() {}
-
-void TouchpadTapSuppressionController::GestureFlingCancel() {
-  controller_->GestureFlingCancel();
-}
-
-void TouchpadTapSuppressionController::GestureFlingCancelAck(bool processed) {
-  controller_->GestureFlingCancelAck(processed);
-}
-
-bool TouchpadTapSuppressionController::ShouldDeferMouseDown(
-    const MouseEventWithLatencyInfo& event) {
-  bool should_defer = controller_->ShouldDeferTapDown();
-  if (should_defer)
-    stashed_mouse_down_ = event;
-  return should_defer;
-}
-
-bool TouchpadTapSuppressionController::ShouldSuppressMouseUp() {
-  return controller_->ShouldSuppressTapEnd();
-}
-
-int TouchpadTapSuppressionController::MaxCancelToDownTimeInMs() {
-  return ui::GestureConfiguration::fling_max_cancel_to_down_time_in_ms();
-}
-
-int TouchpadTapSuppressionController::MaxTapGapTimeInMs() {
-  return ui::GestureConfiguration::fling_max_tap_gap_time_in_ms();
-}
-
-void TouchpadTapSuppressionController::DropStashedTapDown() {
-}
-
-void TouchpadTapSuppressionController::ForwardStashedTapDown() {
-  // Mouse downs are not handled by gesture event filter; so, they are
-  // immediately forwarded to the renderer.
-  client_->SendMouseEventImmediately(stashed_mouse_down_);
-}
-
-}  // namespace content
diff --git a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
index 7f024b3..872cfb0 100644
--- a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
+++ b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
@@ -5,39 +5,33 @@
 #include "content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h"
 
 #include "content/browser/renderer_host/input/gesture_event_queue.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller.h"
-#include "ui/events/gestures/gesture_configuration.h"
-
-#if defined(OS_ANDROID)
-#include "ui/gfx/android/view_configuration.h"
-#endif
 
 using blink::WebInputEvent;
 
 namespace content {
 
 TouchscreenTapSuppressionController::TouchscreenTapSuppressionController(
-    GestureEventQueue* geq)
-    : gesture_event_queue_(geq),
-      controller_(new TapSuppressionController(this)) {
+    GestureEventQueue* geq,
+    const TapSuppressionController::Config& config)
+    : gesture_event_queue_(geq), controller_(this, config) {
 }
 
 TouchscreenTapSuppressionController::~TouchscreenTapSuppressionController() {}
 
 void TouchscreenTapSuppressionController::GestureFlingCancel() {
-  controller_->GestureFlingCancel();
+  controller_.GestureFlingCancel();
 }
 
 void TouchscreenTapSuppressionController::GestureFlingCancelAck(
     bool processed) {
-  controller_->GestureFlingCancelAck(processed);
+  controller_.GestureFlingCancelAck(processed);
 }
 
 bool TouchscreenTapSuppressionController::FilterTapEvent(
     const GestureEventWithLatencyInfo& event) {
   switch (event.event.type) {
     case WebInputEvent::GestureTapDown:
-      if (!controller_->ShouldDeferTapDown())
+      if (!controller_.ShouldDeferTapDown())
         return false;
       stashed_tap_down_.reset(new GestureEventWithLatencyInfo(event));
       return true;
@@ -54,7 +48,7 @@
     case WebInputEvent::GestureTapCancel:
     case WebInputEvent::GestureTap:
     case WebInputEvent::GestureDoubleTap:
-      return controller_->ShouldSuppressTapEnd();
+      return controller_.ShouldSuppressTapEnd();
 
     default:
       break;
@@ -62,27 +56,6 @@
   return false;
 }
 
-#if defined(OS_ANDROID)
-// TODO(jdduke): Enable ui::GestureConfiguration on Android and initialize
-//               with parameters from ViewConfiguration.
-int TouchscreenTapSuppressionController::MaxCancelToDownTimeInMs() {
-  return gfx::ViewConfiguration::GetTapTimeoutInMs();
-}
-
-int TouchscreenTapSuppressionController::MaxTapGapTimeInMs() {
-  return gfx::ViewConfiguration::GetLongPressTimeoutInMs();
-}
-#else
-int TouchscreenTapSuppressionController::MaxCancelToDownTimeInMs() {
-  return ui::GestureConfiguration::fling_max_cancel_to_down_time_in_ms();
-}
-
-int TouchscreenTapSuppressionController::MaxTapGapTimeInMs() {
-  return static_cast<int>(
-      ui::GestureConfiguration::semi_long_press_time_in_seconds() * 1000);
-}
-#endif
-
 void TouchscreenTapSuppressionController::DropStashedTapDown() {
   stashed_tap_down_.reset();
   stashed_show_press_.reset();
diff --git a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
index 02b5b06..706e9d8 100644
--- a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
+++ b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
@@ -6,20 +6,22 @@
 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHSCREEN_TAP_SUPPRESSION_CONTROLLER_H_
 
 #include "base/memory/scoped_ptr.h"
-#include "content/browser/renderer_host/input/gesture_event_queue.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
+#include "content/browser/renderer_host/input/tap_suppression_controller.h"
 #include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
 
 namespace content {
 
 class GestureEventQueue;
-class TapSuppressionController;
 
 // Controls the suppression of touchscreen taps immediately following the
 // dispatch of a GestureFlingCancel event.
 class TouchscreenTapSuppressionController
     : public TapSuppressionControllerClient {
  public:
-  explicit TouchscreenTapSuppressionController(GestureEventQueue* geq);
+  TouchscreenTapSuppressionController(
+      GestureEventQueue* geq,
+      const TapSuppressionController::Config& config);
   virtual ~TouchscreenTapSuppressionController();
 
   // Should be called on arrival of GestureFlingCancel events.
@@ -35,8 +37,6 @@
 
  private:
   // TapSuppressionControllerClient implementation.
-  virtual int MaxCancelToDownTimeInMs() OVERRIDE;
-  virtual int MaxTapGapTimeInMs() OVERRIDE;
   virtual void DropStashedTapDown() OVERRIDE;
   virtual void ForwardStashedTapDown() OVERRIDE;
 
@@ -47,7 +47,7 @@
   ScopedGestureEvent stashed_show_press_;
 
   // The core controller of tap suppression.
-  scoped_ptr<TapSuppressionController> controller_;
+  TapSuppressionController controller_;
 
   DISALLOW_COPY_AND_ASSIGN(TouchscreenTapSuppressionController);
 };
diff --git a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller_stub.cc b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller_stub.cc
deleted file mode 100644
index 243907e..0000000
--- a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller_stub.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2013 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.
-
-#include "content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h"
-
-#include "content/browser/renderer_host/input/tap_suppression_controller.h"
-
-// This is the stub implementation of TouchscreenTapSuppressionController which
-// is used on platforms that do not need tap suppression for touchscreen.
-
-namespace content {
-
-TouchscreenTapSuppressionController::TouchscreenTapSuppressionController(
-    GestureEventQueue* /*geq*/)
-    : gesture_event_queue_(NULL) {}
-
-TouchscreenTapSuppressionController::~TouchscreenTapSuppressionController() {}
-
-void TouchscreenTapSuppressionController::GestureFlingCancel() {}
-
-void TouchscreenTapSuppressionController::GestureFlingCancelAck(
-    bool /*processed*/) {
-}
-
-bool TouchscreenTapSuppressionController::FilterTapEvent(
-    const GestureEventWithLatencyInfo& /*event*/) {
-  return false;
-}
-
-int TouchscreenTapSuppressionController::MaxCancelToDownTimeInMs() {
-  return 0;
-}
-
-int TouchscreenTapSuppressionController::MaxTapGapTimeInMs() {
-  return 0;
-}
-
-void TouchscreenTapSuppressionController::DropStashedTapDown() {}
-
-void TouchscreenTapSuppressionController::ForwardStashedTapDown() {}
-
-}  // namespace content
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.cc b/content/browser/renderer_host/media/audio_input_renderer_host.cc
index 3e683fb..b536cf3 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -65,6 +65,7 @@
           media::AudioLogFactory::AUDIO_INPUT_CONTROLLER)) {}
 
 AudioInputRendererHost::~AudioInputRendererHost() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   DCHECK(audio_entries_.empty());
 }
 
@@ -131,8 +132,8 @@
     return;
   }
 
-  if (!entry->controller->LowLatencyMode()) {
-    NOTREACHED() << "Only low-latency mode is supported.";
+  if (!entry->controller->SharedMemoryAndSyncSocketMode()) {
+    NOTREACHED() << "Only shared-memory/sync-socket mode is supported.";
     DeleteEntryOnError(entry, INVALID_LATENCY_MODE);
     return;
   }
diff --git a/content/browser/renderer_host/media/midi_host.cc b/content/browser/renderer_host/media/midi_host.cc
index 39520b0..9c85b73 100644
--- a/content/browser/renderer_host/media/midi_host.cc
+++ b/content/browser/renderer_host/media/midi_host.cc
@@ -122,9 +122,7 @@
   MidiPortInfoList input_ports;
   MidiPortInfoList output_ports;
 
-  // TODO(toyoshim): Report what error happens back to blink.
-  bool success = result == media::MIDI_OK;
-  if (success) {
+  if (result == media::MIDI_OK) {
     input_ports = midi_manager_->input_ports();
     output_ports = midi_manager_->output_ports();
     received_messages_queues_.clear();
@@ -136,7 +134,7 @@
   }
 
   Send(new MidiMsg_SessionStarted(client_id,
-                                  success,
+                                  result,
                                   input_ports,
                                   output_ports));
 }
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index 98721c5..deb5e19 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -296,25 +296,20 @@
   if (!frame_format.IsValid())
     return;
 
-  // Padded pixels in width/height in case video capture device has odd
-  // numbers for width/height. When the width/height is odd, the last pixel of
-  // each row will have a Y/U/V sample. It's still considered odd width/height,
-  // not duplicated. Converting back to ARGB it will still be odd width/height.
-  // The destination buffer should be rounded up. Pass in a stride that reflects
-  // the byte per line with rounding to libyuv::ConvertToI420, but pass in the
-  // original width/height.
-  int padded_width = 0;
-  int padded_height = 0;
+  // Chopped pixels in width/height in case video capture device has odd
+  // numbers for width/height.
+  int chopped_width = 0;
+  int chopped_height = 0;
   int new_unrotated_width = frame_format.frame_size.width();
   int new_unrotated_height = frame_format.frame_size.height();
 
   if (new_unrotated_width & 1) {
-    ++new_unrotated_width;
-    padded_width = 1;
+    --new_unrotated_width;
+    chopped_width = 1;
   }
   if (new_unrotated_height & 1) {
-    ++new_unrotated_height;
-    padded_height = 1;
+    --new_unrotated_height;
+    chopped_height = 1;
   }
 
   int destination_width = new_unrotated_width;
@@ -365,23 +360,23 @@
     case media::PIXEL_FORMAT_UNKNOWN:  // Color format not set.
       break;
     case media::PIXEL_FORMAT_I420:
-      DCHECK(!padded_width && !padded_height);
+      DCHECK(!chopped_width && !chopped_height);
       origin_colorspace = libyuv::FOURCC_I420;
       break;
     case media::PIXEL_FORMAT_YV12:
-      DCHECK(!padded_width && !padded_height);
+      DCHECK(!chopped_width && !chopped_height);
       origin_colorspace = libyuv::FOURCC_YV12;
       break;
     case media::PIXEL_FORMAT_NV21:
-      DCHECK(!padded_width && !padded_height);
+      DCHECK(!chopped_width && !chopped_height);
       origin_colorspace = libyuv::FOURCC_NV21;
       break;
     case media::PIXEL_FORMAT_YUY2:
-      DCHECK(!padded_width && !padded_height);
+      DCHECK(!chopped_width && !chopped_height);
       origin_colorspace = libyuv::FOURCC_YUY2;
       break;
     case media::PIXEL_FORMAT_UYVY:
-      DCHECK(!padded_width && !padded_height);
+      DCHECK(!chopped_width && !chopped_height);
       origin_colorspace = libyuv::FOURCC_UYVY;
       break;
     case media::PIXEL_FORMAT_RGB24:
@@ -415,10 +410,10 @@
                         crop_x,
                         crop_y,
                         frame_format.frame_size.width(),
-                        (flip ? -frame_format.frame_size.height()
-                              : frame_format.frame_size.height()),
-                        frame_format.frame_size.width(),
-                        frame_format.frame_size.height(),
+                        (flip ? -frame_format.frame_size.height() :
+                                frame_format.frame_size.height()),
+                        new_unrotated_width,
+                        new_unrotated_height,
                         rotation_mode,
                         origin_colorspace);
   scoped_refptr<media::VideoFrame> frame =
diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
index 2387b15..f650397 100644
--- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -615,32 +615,4 @@
   Mock::VerifyAndClearExpectations(client_b_.get());
 }
 
-// This test verifies that a 1x1 frame is passed down to the client.
-TEST_F(VideoCaptureControllerTest, CaptureOddWidthHeightFrames) {
-  media::VideoCaptureParams session_100;
-  session_100.requested_format = media::VideoCaptureFormat(
-      gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);
-  const VideoCaptureControllerID client_a_route_1(0xa1a1a1a1);
-  controller_->AddClient(client_a_route_1,
-                         client_a_.get(),
-                         base::kNullProcessHandle,
-                         100,
-                         session_100);
-  {
-    InSequence s;
-    EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1)).Times(1);
-    EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_1)).Times(1);
-  }
-
-  media::VideoCaptureFormat frame_format(
-      gfx::Size(1, 1), 30, media::PIXEL_FORMAT_ARGB);
-  size_t length =
-      frame_format.frame_size.width() * frame_format.frame_size.height() * 4;
-  scoped_ptr<uint8[]> buffer(new uint8[length]);
-
-  device_->OnIncomingCapturedData(
-      buffer.get(), length, frame_format, 0, base::TimeTicks());
-  base::RunLoop().RunUntilIdle();
-}
-
 }  // namespace content
diff --git a/content/browser/renderer_host/p2p/socket_host_udp.cc b/content/browser/renderer_host/p2p/socket_host_udp.cc
index c864728..77c817e 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp.cc
+++ b/content/browser/renderer_host/p2p/socket_host_udp.cc
@@ -41,7 +41,8 @@
          error == net::ERR_ADDRESS_INVALID ||
          error == net::ERR_ACCESS_DENIED ||
          error == net::ERR_CONNECTION_RESET ||
-         error == net::ERR_OUT_OF_MEMORY;
+         error == net::ERR_OUT_OF_MEMORY ||
+         error == net::ERR_INTERNET_DISCONNECTED;
 }
 
 }  // namespace
@@ -287,7 +288,7 @@
       return;
     }
     VLOG(0) << "sendto() has failed twice returning a "
-                 " transient error. Dropping the packet.";
+               " transient error. Dropping the packet.";
   }
   message_sender_->Send(new P2PMsg_OnSendComplete(id_));
 }
diff --git a/content/browser/renderer_host/pepper/pepper_gamepad_host.cc b/content/browser/renderer_host/pepper/pepper_gamepad_host.cc
index 8783e81..bbb72b8 100644
--- a/content/browser/renderer_host/pepper/pepper_gamepad_host.cc
+++ b/content/browser/renderer_host/pepper/pepper_gamepad_host.cc
@@ -37,7 +37,7 @@
 
 PepperGamepadHost::~PepperGamepadHost() {
   if (is_started_)
-    gamepad_service_->RemoveConsumer();
+    gamepad_service_->RemoveConsumer(this);
 }
 
 int32_t PepperGamepadHost::OnResourceMessageReceived(
@@ -55,7 +55,7 @@
   if (is_started_)
     return PP_ERROR_FAILED;
 
-  gamepad_service_->AddConsumer();
+  gamepad_service_->ConsumerBecameActive(this);
   is_started_ = true;
 
   // Don't send the shared memory back until the user has interacted with the
diff --git a/content/browser/renderer_host/pepper/pepper_gamepad_host.h b/content/browser/renderer_host/pepper/pepper_gamepad_host.h
index 1db73aa..c9f2c18 100644
--- a/content/browser/renderer_host/pepper/pepper_gamepad_host.h
+++ b/content/browser/renderer_host/pepper/pepper_gamepad_host.h
@@ -7,6 +7,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
+#include "content/browser/gamepad/gamepad_consumer.h"
 #include "content/common/content_export.h"
 #include "ppapi/host/resource_host.h"
 
@@ -21,7 +22,9 @@
 class BrowserPpapiHost;
 class GamepadService;
 
-class CONTENT_EXPORT PepperGamepadHost : public ppapi::host::ResourceHost {
+class CONTENT_EXPORT PepperGamepadHost :
+    public ppapi::host::ResourceHost,
+    public GamepadConsumer {
  public:
   PepperGamepadHost(BrowserPpapiHost* host,
                     PP_Instance instance,
@@ -40,6 +43,14 @@
       const IPC::Message& msg,
       ppapi::host::HostMessageContext* context) OVERRIDE;
 
+  // GamepadConsumer implementation.
+  virtual void OnGamepadConnected(
+      unsigned index,
+      const blink::WebGamepad& gamepad) OVERRIDE {}
+  virtual void OnGamepadDisconnected(
+      unsigned index,
+      const blink::WebGamepad& gamepad) OVERRIDE {}
+
  private:
   int32_t OnRequestMemory(ppapi::host::HostMessageContext* context);
 
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index c5eed71..e686ce8 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -10,6 +10,7 @@
 #include "base/bind_helpers.h"
 #include "base/command_line.h"
 #include "base/debug/alias.h"
+#include "base/numerics/safe_math.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread.h"
@@ -35,6 +36,7 @@
 #include "content/common/desktop_notification_messages.h"
 #include "content/common/frame_messages.h"
 #include "content/common/gpu/client/gpu_memory_buffer_impl.h"
+#include "content/common/gpu/client/gpu_memory_buffer_impl_shm.h"
 #include "content/common/host_shared_bitmap_manager.h"
 #include "content/common/media/media_param_traits.h"
 #include "content/common/view_messages.h"
@@ -876,15 +878,6 @@
 #if defined(OS_WIN)
 void RenderMessageFilter::OnGetMonitorColorProfile(std::vector<char>* profile) {
   DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
-  static bool enabled = false;
-  static bool checked = false;
-  if (!checked) {
-    checked = true;
-    const CommandLine& command = *CommandLine::ForCurrentProcess();
-    enabled = command.HasSwitch(switches::kEnableMonitorProfile);
-  }
-  if (enabled)
-    return;
   *profile = g_color_profile.Get().profile();
 }
 #endif
@@ -892,9 +885,11 @@
 void RenderMessageFilter::OnDownloadUrl(const IPC::Message& message,
                                         const GURL& url,
                                         const Referrer& referrer,
-                                        const base::string16& suggested_name) {
+                                        const base::string16& suggested_name,
+                                        const bool use_prompt) {
   scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
   save_info->suggested_name = suggested_name;
+  save_info->prompt_for_save_location = use_prompt;
 
   // There may be a special cookie store that we could use for this download,
   // rather than the default one. Since this feature is generally only used for
@@ -1254,14 +1249,26 @@
     uint32 width,
     uint32 height,
     uint32 internalformat,
+    uint32 usage,
     gfx::GpuMemoryBufferHandle* handle) {
-  if (!GpuMemoryBufferImpl::IsFormatValid(internalformat)) {
+  if (!GpuMemoryBufferImpl::IsFormatValid(internalformat) ||
+      !GpuMemoryBufferImpl::IsUsageValid(usage)) {
+    handle->type = gfx::EMPTY_BUFFER;
+    return;
+  }
+  base::CheckedNumeric<int> size = width;
+  size *= height;
+  if (!size.IsValid()) {
     handle->type = gfx::EMPTY_BUFFER;
     return;
   }
 
 #if defined(OS_MACOSX)
-  if (GpuMemoryBufferImplIOSurface::IsFormatSupported(internalformat)) {
+  // TODO(reveman): This should be moved to
+  // GpuMemoryBufferImpl::AllocateForChildProcess and
+  // GpuMemoryBufferImplIOSurface. crbug.com/325045, crbug.com/323304
+  if (GpuMemoryBufferImplIOSurface::IsConfigurationSupported(internalformat,
+                                                             usage)) {
     IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
     if (io_surface_support) {
       base::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
@@ -1306,7 +1313,12 @@
 #endif
 
 #if defined(OS_ANDROID)
-  if (GpuMemoryBufferImplSurfaceTexture::IsFormatSupported(internalformat)) {
+  // TODO(reveman): This should be moved to
+  // GpuMemoryBufferImpl::AllocateForChildProcess and
+  // GpuMemoryBufferImplSurfaceTexture when adding support for out-of-process
+  // GPU service. crbug.com/368716
+  if (GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported(
+          internalformat, usage)) {
     // Each surface texture is associated with a render process id. This allows
     // the GPU service and Java Binder IPC to verify that a renderer is not
     // trying to use a surface texture it doesn't own.
@@ -1321,24 +1333,8 @@
   }
 #endif
 
-  uint64 stride = static_cast<uint64>(width) *
-      GpuMemoryBufferImpl::BytesPerPixel(internalformat);
-  if (stride > std::numeric_limits<uint32>::max()) {
-    handle->type = gfx::EMPTY_BUFFER;
-    return;
-  }
-
-  uint64 buffer_size = stride * static_cast<uint64>(height);
-  if (buffer_size > std::numeric_limits<size_t>::max()) {
-    handle->type = gfx::EMPTY_BUFFER;
-    return;
-  }
-
-  // Fallback to fake GpuMemoryBuffer that is backed by shared memory and
-  // requires an upload before it can be used as a texture.
-  handle->type = gfx::SHARED_MEMORY_BUFFER;
-  ChildProcessHostImpl::AllocateSharedMemory(
-      static_cast<size_t>(buffer_size), PeerHandle(), &handle->handle);
+  GpuMemoryBufferImpl::AllocateForChildProcess(
+      gfx::Size(width, height), internalformat, usage, PeerHandle(), handle);
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h
index 3c42f53..2fa211c 100644
--- a/content/browser/renderer_host/render_message_filter.h
+++ b/content/browser/renderer_host/render_message_filter.h
@@ -196,7 +196,8 @@
   void OnDownloadUrl(const IPC::Message& message,
                      const GURL& url,
                      const Referrer& referrer,
-                     const base::string16& suggested_name);
+                     const base::string16& suggested_name,
+                     const bool use_prompt);
   void OnCheckNotificationPermission(const GURL& source_origin,
                                      int* permission_level);
 
@@ -277,6 +278,7 @@
   void OnAllocateGpuMemoryBuffer(uint32 width,
                                  uint32 height,
                                  uint32 internalformat,
+                                 uint32 usage,
                                  gfx::GpuMemoryBufferHandle* handle);
 
   // Cached resource request dispatcher host and plugin service, guaranteed to
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 04368dd..4cf4cdc 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -99,7 +99,6 @@
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/browser/service_worker/service_worker_dispatcher_host.h"
 #include "content/browser/shared_worker/shared_worker_message_filter.h"
-#include "content/browser/speech/input_tag_speech_dispatcher_host.h"
 #include "content/browser/speech/speech_recognition_dispatcher_host.h"
 #include "content/browser/storage_partition_impl.h"
 #include "content/browser/streams/stream_context.h"
@@ -115,7 +114,6 @@
 #include "content/common/mojo/mojo_messages.h"
 #include "content/common/resource_messages.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/notification_service.h"
@@ -124,6 +122,7 @@
 #include "content/public/browser/render_process_host_observer.h"
 #include "content/public/browser/render_widget_host.h"
 #include "content/public/browser/render_widget_host_iterator.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/browser/resource_context.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/worker_service.h"
@@ -703,7 +702,7 @@
       storage_partition_impl_->GetIndexedDBContext(),
       ChromeBlobStorageContext::GetFor(browser_context)));
 
-  geolocation_dispatcher_host_ = GeolocationDispatcherHost::New(
+  geolocation_dispatcher_host_ = new GeolocationDispatcherHost(
       GetID(), browser_context->GetGeolocationPermissionContext());
   AddFilter(geolocation_dispatcher_host_);
   gpu_message_filter_ = new GpuMessageFilter(GetID(), widget_helper_.get());
@@ -724,10 +723,6 @@
 #if defined(ENABLE_PLUGINS)
   AddFilter(new PepperRendererConnection(GetID()));
 #endif
-#if defined(ENABLE_INPUT_SPEECH)
-  AddFilter(new InputTagSpeechDispatcherHost(
-      IsGuest(), GetID(), storage_partition_impl_->GetURLRequestContext()));
-#endif
   AddFilter(new SpeechRecognitionDispatcherHost(
       IsGuest(), GetID(), storage_partition_impl_->GetURLRequestContext()));
   AddFilter(new FileAPIMessageFilter(
@@ -1038,6 +1033,7 @@
     switches::kDisableDatabases,
     switches::kDisableDesktopNotifications,
     switches::kDisableDirectNPAPIRequests,
+    switches::kDisableDistanceFieldText,
     switches::kDisableFastTextAutosizing,
     switches::kDisableFileSystem,
     switches::kDisableFiltersOverIPC,
@@ -1057,7 +1053,6 @@
     switches::kDisableSeccompFilterSandbox,
     switches::kDisableSessionStorage,
     switches::kDisableSharedWorkers,
-    switches::kDisableSpeechInput,
     switches::kDisableTouchAdjustment,
     switches::kDisableTouchDragDrop,
     switches::kDisableTouchEditing,
@@ -1073,6 +1068,7 @@
     switches::kEnableCompositingForFixedPosition,
     switches::kEnableCompositingForTransition,
     switches::kEnableDeferredImageDecoding,
+    switches::kEnableDistanceFieldText,
     switches::kEnableEncryptedMedia,
     switches::kEnableExperimentalCanvasFeatures,
     switches::kEnableExperimentalWebPlatformFeatures,
@@ -1092,6 +1088,7 @@
     switches::kEnableOverlayScrollbar,
     switches::kEnableOverscrollNotifications,
     switches::kEnablePinch,
+    switches::kEnablePreciseMemoryInfo,
     switches::kEnablePreparsedJsCaching,
     switches::kEnableRepaintAfterLayout,
     switches::kEnableSeccompFilterSandbox,
diff --git a/content/browser/renderer_host/render_view_host_browsertest.cc b/content/browser/renderer_host/render_view_host_browsertest.cc
index 5c5da74..31ecee9 100644
--- a/content/browser/renderer_host/render_view_host_browsertest.cc
+++ b/content/browser/renderer_host/render_view_host_browsertest.cc
@@ -117,4 +117,16 @@
             new_root->current_frame_host()->routing_id());
 }
 
+IN_PROC_BROWSER_TEST_F(RenderViewHostTest, IsFocusedElementEditable) {
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+
+  GURL test_url = embedded_test_server()->GetURL("/touch_selection.html");
+  NavigateToURL(shell(), test_url);
+
+  RenderViewHost* rvh = shell()->web_contents()->GetRenderViewHost();
+  EXPECT_FALSE(rvh->IsFocusedElementEditable());
+  EXPECT_TRUE(ExecuteScript(shell()->web_contents(), "focus_textfield();"));
+  EXPECT_TRUE(rvh->IsFocusedElementEditable());
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h
index 3cdd78f..bfa45e8 100644
--- a/content/browser/renderer_host/render_view_host_delegate.h
+++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -140,19 +140,10 @@
   // entirely loaded).
   virtual void DidChangeLoadProgress(double progress) {}
 
-  // The RenderView set its opener to null, disowning it for the lifetime of
-  // the window.
-  virtual void DidDisownOpener(RenderViewHost* rvh) {}
-
   // The RenderView's main frame document element is ready. This happens when
   // the document has finished parsing.
   virtual void DocumentAvailableInMainFrame(RenderViewHost* render_view_host) {}
 
-  // The onload handler in the RenderView's main frame has completed.
-  virtual void DocumentOnLoadCompletedInMainFrame(
-      RenderViewHost* render_view_host,
-      int32 page_id) {}
-
   // The page wants to close the active view in this tab.
   virtual void RouteCloseEvent(RenderViewHost* rvh) {}
 
diff --git a/content/browser/renderer_host/render_view_host_delegate_view.h b/content/browser/renderer_host/render_view_host_delegate_view.h
new file mode 100644
index 0000000..fb2babd
--- /dev/null
+++ b/content/browser/renderer_host/render_view_host_delegate_view.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2012 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.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_DELEGATE_VIEW_H_
+#define CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_DELEGATE_VIEW_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "content/common/content_export.h"
+#include "content/common/drag_event_source_info.h"
+#include "third_party/WebKit/public/web/WebDragOperation.h"
+
+class SkBitmap;
+
+namespace gfx {
+class ImageSkia;
+class Rect;
+class Vector2d;
+}
+
+namespace content {
+class RenderFrameHost;
+struct ContextMenuParams;
+struct DropData;
+struct MenuItem;
+
+// This class provides a way for the RenderViewHost to reach out to its
+// delegate's view. It only needs to be implemented by embedders if they don't
+// use the default WebContentsView implementations.
+class CONTENT_EXPORT RenderViewHostDelegateView {
+ public:
+  // A context menu should be shown, to be built using the context information
+  // provided in the supplied params.
+  virtual void ShowContextMenu(RenderFrameHost* render_frame_host,
+                               const ContextMenuParams& params) {}
+
+  // Shows a popup menu with the specified items.
+  // This method should call RenderViewHost::DidSelectPopupMenuItem[s]() or
+  // RenderViewHost::DidCancelPopupMenu() based on the user action.
+  virtual void ShowPopupMenu(const gfx::Rect& bounds,
+                             int item_height,
+                             double item_font_size,
+                             int selected_item,
+                             const std::vector<MenuItem>& items,
+                             bool right_aligned,
+                             bool allow_multiple_selection) {};
+
+  // Hides a popup menu opened by ShowPopupMenu().
+  virtual void HidePopupMenu() {};
+
+  // The user started dragging content of the specified type within the
+  // RenderView. Contextual information about the dragged content is supplied
+  // by DropData. If the delegate's view cannot start the drag for /any/
+  // reason, it must inform the renderer that the drag has ended; otherwise,
+  // this results in bugs like http://crbug.com/157134.
+  virtual void StartDragging(const DropData& drop_data,
+                             blink::WebDragOperationsMask allowed_ops,
+                             const gfx::ImageSkia& image,
+                             const gfx::Vector2d& image_offset,
+                             const DragEventSourceInfo& event_info) {}
+
+  // The page wants to update the mouse cursor during a drag & drop operation.
+  // |operation| describes the current operation (none, move, copy, link.)
+  virtual void UpdateDragCursor(blink::WebDragOperation operation) {}
+
+  // Notification that view for this delegate got the focus.
+  virtual void GotFocus() {}
+
+  // Callback to inform the browser that the page is returning the focus to
+  // the browser's chrome. If reverse is true, it means the focus was
+  // retrieved by doing a Shift-Tab.
+  virtual void TakeFocus(bool reverse) {}
+
+ protected:
+  virtual ~RenderViewHostDelegateView() {}
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_DELEGATE_VIEW_H_
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 878ae78..c173bb9 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -39,6 +39,8 @@
 #include "content/browser/renderer_host/media/audio_renderer_host.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_delegate.h"
+#include "content/browser/renderer_host/render_view_host_delegate_view.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/common/accessibility_messages.h"
 #include "content/common/browser_plugin/browser_plugin_messages.h"
 #include "content/common/content_switches_internal.h"
@@ -51,8 +53,6 @@
 #include "content/common/swapped_out_messages.h"
 #include "content/common/view_messages.h"
 #include "content/common/web_ui_setup.mojom.h"
-#include "content/port/browser/render_view_host_delegate_view.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/ax_event_notification_details.h"
 #include "content/public/browser/browser_accessibility_state.h"
 #include "content/public/browser/browser_context.h"
@@ -215,7 +215,8 @@
       sudden_termination_allowed_(false),
       render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING),
       virtual_keyboard_requested_(false),
-      weak_factory_(this) {
+      weak_factory_(this),
+      is_focused_element_editable_(false) {
   DCHECK(instance_.get());
   CHECK(delegate_);  // http://crbug.com/82827
 
@@ -420,7 +421,7 @@
       atoi(command_line.GetSwitchValueASCII(
       switches::kAcceleratedCanvas2dMSAASampleCount).c_str());
   prefs.deferred_filters_enabled =
-      command_line.HasSwitch(switches::kEnableDeferredFilters);
+      !command_line.HasSwitch(switches::kDisableDeferredFilters);
   prefs.container_culling_enabled =
       command_line.HasSwitch(switches::kEnableContainerCulling);
   prefs.lazy_layout_enabled =
@@ -1002,11 +1003,8 @@
     IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnRequestMove)
     IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeLoadProgress,
                         OnDidChangeLoadProgress)
-    IPC_MESSAGE_HANDLER(ViewHostMsg_DidDisownOpener, OnDidDisownOpener)
     IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentAvailableInMainFrame,
                         OnDocumentAvailableInMainFrame)
-    IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentOnLoadCompletedInMainFrame,
-                        OnDocumentOnLoadCompletedInMainFrame)
     IPC_MESSAGE_HANDLER(ViewHostMsg_ToggleFullscreen, OnToggleFullscreen)
     IPC_MESSAGE_HANDLER(ViewHostMsg_DidContentsPreferredSizeChange,
                         OnDidContentsPreferredSizeChange)
@@ -1235,19 +1233,10 @@
   delegate_->DidChangeLoadProgress(load_progress);
 }
 
-void RenderViewHostImpl::OnDidDisownOpener() {
-  delegate_->DidDisownOpener(this);
-}
-
 void RenderViewHostImpl::OnDocumentAvailableInMainFrame() {
   delegate_->DocumentAvailableInMainFrame(this);
 }
 
-void RenderViewHostImpl::OnDocumentOnLoadCompletedInMainFrame(
-    int32 page_id) {
-  delegate_->DocumentOnLoadCompletedInMainFrame(this, page_id);
-}
-
 void RenderViewHostImpl::OnToggleFullscreen(bool enter_fullscreen) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   delegate_->ToggleFullscreenMode(enter_fullscreen);
@@ -1373,6 +1362,7 @@
 }
 
 void RenderViewHostImpl::OnFocusedNodeChanged(bool is_editable_node) {
+  is_focused_element_editable_ = is_editable_node;
   if (view_)
     view_->FocusedNodeChanged(is_editable_node);
 #if defined(OS_WIN)
@@ -1498,14 +1488,6 @@
 }
 #endif
 
-void RenderViewHostImpl::SendOrientationChangeEvent(int orientation) {
-  Send(new ViewMsg_OrientationChangeEvent(GetRoutingID(), orientation));
-}
-
-void RenderViewHostImpl::ToggleSpeechInput() {
-  Send(new InputTagSpeechMsg_ToggleSpeechInput(GetRoutingID()));
-}
-
 bool RenderViewHostImpl::IsWaitingForUnloadACK() const {
   return rvh_state_ == STATE_WAITING_FOR_UNLOAD_ACK ||
          rvh_state_ == STATE_WAITING_FOR_CLOSE ||
@@ -1547,9 +1529,14 @@
 }
 
 void RenderViewHostImpl::ClearFocusedElement() {
+  is_focused_element_editable_ = false;
   Send(new ViewMsg_ClearFocusedElement(GetRoutingID()));
 }
 
+bool RenderViewHostImpl::IsFocusedElementEditable() {
+  return is_focused_element_editable_;
+}
+
 void RenderViewHostImpl::Zoom(PageZoom zoom) {
   Send(new ViewMsg_Zoom(GetRoutingID(), zoom));
 }
@@ -1577,6 +1564,10 @@
   Send(new ViewMsg_CopyImageAt(GetRoutingID(), x, y));
 }
 
+void RenderViewHostImpl::SaveImageAt(int x, int y) {
+  Send(new ViewMsg_SaveImageAt(GetRoutingID(), x, y));
+}
+
 void RenderViewHostImpl::ExecuteMediaPlayerActionAtLocation(
   const gfx::Point& location, const blink::WebMediaPlayerAction& action) {
   Send(new ViewMsg_MediaPlayerActionAt(GetRoutingID(), location, action));
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index 061da82..e08d18c 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -155,8 +155,10 @@
   virtual RenderFrameHost* GetMainFrame() OVERRIDE;
   virtual void AllowBindings(int binding_flags) OVERRIDE;
   virtual void ClearFocusedElement() OVERRIDE;
+  virtual bool IsFocusedElementEditable() OVERRIDE;
   virtual void ClosePage() OVERRIDE;
   virtual void CopyImageAt(int x, int y) OVERRIDE;
+  virtual void SaveImageAt(int x, int y) OVERRIDE;
   virtual void DirectoryEnumerationFinished(
       int request_id,
       const std::vector<base::FilePath>& files) OVERRIDE;
@@ -203,7 +205,6 @@
                                 const std::string& value) OVERRIDE;
   virtual void Zoom(PageZoom zoom) OVERRIDE;
   virtual void SyncRendererPrefs() OVERRIDE;
-  virtual void ToggleSpeechInput() OVERRIDE;
   virtual WebPreferences GetWebkitPreferences() OVERRIDE;
   virtual void UpdateWebkitPreferences(
       const WebPreferences& prefs) OVERRIDE;
@@ -396,9 +397,6 @@
   void DidCancelPopupMenu();
 #endif
 
-  // User rotated the screen. Calls the "onorientationchange" Javascript hook.
-  void SendOrientationChangeEvent(int orientation);
-
   int main_frame_routing_id() const {
     return main_frame_routing_id_;
   }
@@ -492,9 +490,7 @@
   void OnClose();
   void OnRequestMove(const gfx::Rect& pos);
   void OnDidChangeLoadProgress(double load_progress);
-  void OnDidDisownOpener();
   void OnDocumentAvailableInMainFrame();
-  void OnDocumentOnLoadCompletedInMainFrame(int32 page_id);
   void OnToggleFullscreen(bool enter_fullscreen);
   void OnDidContentsPreferredSizeChange(const gfx::Size& new_size);
   void OnDidChangeScrollOffset();
@@ -648,6 +644,9 @@
 
   base::WeakPtrFactory<RenderViewHostImpl> weak_factory_;
 
+  // True if the current focused element is editable.
+  bool is_focused_element_editable_;
+
   DISALLOW_COPY_AND_ASSIGN(RenderViewHostImpl);
 };
 
diff --git a/content/browser/renderer_host/render_view_host_unittest.cc b/content/browser/renderer_host/render_view_host_unittest.cc
index cb5e52b..836540c 100644
--- a/content/browser/renderer_host/render_view_host_unittest.cc
+++ b/content/browser/renderer_host/render_view_host_unittest.cc
@@ -6,9 +6,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/renderer_host/render_view_host_delegate_view.h"
 #include "content/common/input_messages.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_view_host_delegate_view.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/common/bindings_policy.h"
 #include "content/public/common/drop_data.h"
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 5172633..f01a2e7 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -31,6 +31,7 @@
 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
 #include "content/browser/gpu/gpu_surface_tracker.h"
 #include "content/browser/renderer_host/dip_util.h"
+#include "content/browser/renderer_host/input/input_router_config_helper.h"
 #include "content/browser/renderer_host/input/input_router_impl.h"
 #include "content/browser/renderer_host/input/synthetic_gesture.h"
 #include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
@@ -42,6 +43,7 @@
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/renderer_host/render_widget_helper.h"
 #include "content/browser/renderer_host/render_widget_host_delegate.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/common/accessibility_messages.h"
 #include "content/common/content_constants_internal.h"
 #include "content/common/cursors/webcursor.h"
@@ -49,7 +51,6 @@
 #include "content/common/host_shared_bitmap_manager.h"
 #include "content/common/input_messages.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
@@ -229,7 +230,8 @@
   accessibility_mode_ =
       BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode();
 
-  input_router_.reset(new InputRouterImpl(process_, this, this, routing_id_));
+  input_router_.reset(new InputRouterImpl(
+      process_, this, this, routing_id_, GetInputRouterConfigForPlatform()));
 
   touch_emulator_.reset();
 
@@ -322,8 +324,8 @@
   return rwh->AsRenderWidgetHostImpl();
 }
 
-void RenderWidgetHostImpl::SetView(RenderWidgetHostView* view) {
-  view_ = RenderWidgetHostViewPort::FromRWHV(view);
+void RenderWidgetHostImpl::SetView(RenderWidgetHostViewBase* view) {
+  view_ = view;
 
   GpuSurfaceTracker::Get()->SetSurfaceHandle(
       surface_id_, GetCompositingSurface());
@@ -1165,10 +1167,10 @@
 
 void RenderWidgetHostImpl::GetWebScreenInfo(blink::WebScreenInfo* result) {
   TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::GetWebScreenInfo");
-  if (GetView())
-    static_cast<RenderWidgetHostViewPort*>(GetView())->GetScreenInfo(result);
+  if (view_)
+    view_->GetScreenInfo(result);
   else
-    RenderWidgetHostViewPort::GetDefaultScreenInfo(result);
+    RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
   screen_info_out_of_date_ = false;
 }
 
@@ -1218,7 +1220,8 @@
   waiting_for_screen_rects_ack_ = false;
 
   // Reset to ensure that input routing works with a new renderer.
-  input_router_.reset(new InputRouterImpl(process_, this, this, routing_id_));
+  input_router_.reset(new InputRouterImpl(
+      process_, this, this, routing_id_, GetInputRouterConfigForPlatform()));
 
   if (overscroll_controller_)
     overscroll_controller_->Reset();
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 65a2767..139ea3b 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -25,14 +25,14 @@
 #include "build/build_config.h"
 #include "cc/resources/shared_bitmap.h"
 #include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/browser/renderer_host/input/input_ack_handler.h"
 #include "content/browser/renderer_host/input/input_router_client.h"
 #include "content/browser/renderer_host/input/synthetic_gesture.h"
 #include "content/browser/renderer_host/input/touch_emulator_client.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/common/input/synthetic_gesture_packet.h"
 #include "content/common/view_message_enums.h"
-#include "content/port/browser/event_with_latency_info.h"
-#include "content/port/common/input_event_ack_state.h"
 #include "content/public/browser/render_widget_host.h"
 #include "content/public/common/page_zoom.h"
 #include "ipc/ipc_listener.h"
@@ -83,7 +83,7 @@
 class MockRenderWidgetHost;
 class OverscrollController;
 class RenderWidgetHostDelegate;
-class RenderWidgetHostViewPort;
+class RenderWidgetHostViewBase;
 class SyntheticGestureController;
 class TimeoutMonitor;
 class TouchEmulator;
@@ -203,7 +203,7 @@
   void InvalidateScreenInfo();
 
   // Sets the View of this RenderWidgetHost.
-  void SetView(RenderWidgetHostView* view);
+  void SetView(RenderWidgetHostViewBase* view);
 
   int surface_id() const { return surface_id_; }
 
@@ -598,7 +598,7 @@
   // crashes, its View is destroyed and this pointer becomes NULL, even though
   // render_view_host_ lives on to load another URL (creating a new View while
   // doing so).
-  RenderWidgetHostViewPort* view_;
+  RenderWidgetHostViewBase* view_;
 
   // true if a renderer has once been valid. We use this flag to display a sad
   // tab only when we lose our renderer and not if a paint occurs during
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index db75239..78505f1 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -11,16 +11,14 @@
 #include "content/browser/browser_thread_impl.h"
 #include "content/browser/renderer_host/input/gesture_event_queue.h"
 #include "content/browser/renderer_host/input/input_router_impl.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
 #include "content/browser/renderer_host/input/touch_event_queue.h"
 #include "content/browser/renderer_host/overscroll_controller.h"
 #include "content/browser/renderer_host/overscroll_controller_delegate.h"
 #include "content/browser/renderer_host/render_widget_host_delegate.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/common/input/synthetic_web_input_event_builders.h"
 #include "content/common/input_messages.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/mock_render_process_host.h"
 #include "content/public/test/test_browser_context.h"
@@ -30,16 +28,17 @@
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/screen.h"
 
-#if defined(USE_AURA)
-#include "content/browser/compositor/image_transport_factory.h"
-#include "content/browser/renderer_host/render_widget_host_view_aura.h"
-#include "ui/aura/env.h"
-#include "ui/aura/test/test_screen.h"
-#include "ui/compositor/test/in_process_context_factory.h"
+#if defined(OS_ANDROID)
+#include "content/browser/renderer_host/render_widget_host_view_android.h"
 #endif
 
 #if defined(USE_AURA)
+#include "content/browser/compositor/image_transport_factory.h"
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
 #include "content/browser/renderer_host/ui_events_helper.h"
+#include "ui/aura/env.h"
+#include "ui/aura/test/test_screen.h"
+#include "ui/compositor/test/in_process_context_factory.h"
 #include "ui/events/event.h"
 #endif
 
@@ -198,7 +197,6 @@
       int routing_id)
       : RenderWidgetHostImpl(delegate, process, routing_id, false),
         unresponsive_timer_fired_(false) {
-    input_router_impl_ = static_cast<InputRouterImpl*>(input_router_.get());
     acked_touch_event_type_ = blink::WebInputEvent::Undefined;
   }
 
@@ -249,13 +247,10 @@
     overscroll_controller_->set_delegate(overscroll_delegate_.get());
   }
 
-  void DisableGestureDebounce() {
-    gesture_event_queue().set_debounce_enabled_for_testing(false);
-  }
+  void DisableGestureDebounce() { set_debounce_interval_time_ms(0); }
 
   void set_debounce_interval_time_ms(int delay_ms) {
-    gesture_event_queue().
-        set_debounce_interval_time_ms_for_testing(delay_ms);
+    gesture_event_queue().set_debounce_interval_time_ms_for_testing(delay_ms);
   }
 
   bool TouchEventQueueEmpty() const {
@@ -307,12 +302,11 @@
   }
 
   void SetupForInputRouterTest() {
-    mock_input_router_ = new MockInputRouter(this);
-    input_router_.reset(mock_input_router_);
+    input_router_.reset(new MockInputRouter(this));
   }
 
   MockInputRouter* mock_input_router() {
-    return mock_input_router_;
+    return static_cast<MockInputRouter*>(input_router_.get());
   }
 
  protected:
@@ -321,27 +315,29 @@
   }
 
   const TouchEventQueue& touch_event_queue() const {
-    return input_router_impl_->touch_event_queue_;
+    return input_router_impl()->touch_event_queue_;
   }
 
   const GestureEventQueue& gesture_event_queue() const {
-    return input_router_impl_->gesture_event_queue_;
+    return input_router_impl()->gesture_event_queue_;
   }
 
   GestureEventQueue& gesture_event_queue() {
-    return input_router_impl_->gesture_event_queue_;
+    return input_router_impl()->gesture_event_queue_;
   }
 
  private:
+  const InputRouterImpl* input_router_impl() const {
+    return static_cast<InputRouterImpl*>(input_router_.get());
+  }
+
+  InputRouterImpl* input_router_impl() {
+    return static_cast<InputRouterImpl*>(input_router_.get());
+  }
+
   bool unresponsive_timer_fired_;
   WebInputEvent::Type acked_touch_event_type_;
 
-  // |input_router_impl_| and |mock_input_router_| are owned by
-  // RenderWidgetHostImpl.  The handles below are provided for convenience so
-  // that we don't have to reinterpret_cast it all the time.
-  InputRouterImpl* input_router_impl_;
-  MockInputRouter* mock_input_router_;
-
   scoped_ptr<TestOverscrollDelegate> overscroll_delegate_;
 
   DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
@@ -606,7 +602,7 @@
 #if defined(USE_AURA)
     ImageTransportFactory::InitializeForUnitTests(
         scoped_ptr<ui::ContextFactory>(new ui::InProcessContextFactory));
-    aura::Env::CreateInstance();
+    aura::Env::CreateInstance(true);
     screen_.reset(aura::TestScreen::Create());
     gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
 #endif
@@ -615,6 +611,9 @@
     view_.reset(new TestView(host_.get()));
     host_->SetView(view_.get());
     host_->Init();
+
+    // Tests for debounce-related behavior will explicitly enable debouncing.
+    host_->DisableGestureDebounce();
   }
   virtual void TearDown() {
     view_.reset();
@@ -742,11 +741,8 @@
                                        float anchorX,
                                        float anchorY,
                                        int modifiers) {
-    SimulateGestureEventCore(
-        SyntheticWebGestureEventBuilder::BuildPinchUpdate(scale,
-                                                          anchorX,
-                                                          anchorY,
-                                                          modifiers));
+    SimulateGestureEventCore(SyntheticWebGestureEventBuilder::BuildPinchUpdate(
+        scale, anchorX, anchorY, modifiers, WebGestureEvent::Touchscreen));
   }
 
   // Inject synthetic GestureFlingStart events.
@@ -960,15 +956,13 @@
 // Tests setting custom background
 TEST_F(RenderWidgetHostTest, Background) {
 #if !defined(OS_MACOSX)
-  scoped_ptr<RenderWidgetHostView> view(
-      RenderWidgetHostView::CreateViewForWidget(host_.get()));
-#if defined(OS_LINUX) || defined(USE_AURA)
+  scoped_ptr<RenderWidgetHostViewBase> view;
+#if defined(USE_AURA)
+  view.reset(new RenderWidgetHostViewAura(host_.get()));
   // TODO(derat): Call this on all platforms: http://crbug.com/102450.
-  // InitAsChild doesn't seem to work if NULL parent is passed on Windows,
-  // which leads to DCHECK failure in RenderWidgetHostView::Destroy.
-  // When you enable this for OS_WIN, enable |view.release()->Destroy()|
-  // below.
   view->InitAsChild(NULL);
+#elif defined(OS_ANDROID)
+  view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL));
 #endif
   host_->SetView(view.get());
 
@@ -1008,10 +1002,10 @@
   sent_background.a.unlockPixels();
   background.unlockPixels();
 
-#if defined(OS_LINUX) || defined(USE_AURA)
+#if defined(USE_AURA)
   // See the comment above |InitAsChild(NULL)|.
   host_->SetView(NULL);
-  static_cast<RenderWidgetHostViewPort*>(view.release())->Destroy();
+  static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy();
 #endif
 
 #else
@@ -1522,7 +1516,6 @@
 // overscroll nav instead of completing it.
 TEST_F(RenderWidgetHostTest, ReverseFlingCancelsOverscroll) {
   host_->SetupForOverscrollControllerTest();
-  host_->DisableGestureDebounce();
   process_->sink().ClearMessages();
   view_->set_bounds(gfx::Rect(0, 0, 400, 200));
   view_->Show();
@@ -1575,7 +1568,6 @@
 TEST_F(RenderWidgetHostTest, GestureScrollOverscrolls) {
   // Turn off debounce handling for test isolation.
   host_->SetupForOverscrollControllerTest();
-  host_->DisableGestureDebounce();
   process_->sink().ClearMessages();
 
   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
@@ -1629,7 +1621,6 @@
 TEST_F(RenderWidgetHostTest, GestureScrollConsumedHorizontal) {
   // Turn off debounce handling for test isolation.
   host_->SetupForOverscrollControllerTest();
-  host_->DisableGestureDebounce();
   process_->sink().ClearMessages();
 
   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
@@ -2084,7 +2075,6 @@
 // move events do reach the renderer.
 TEST_F(RenderWidgetHostTest, OverscrollMouseMoveCompletion) {
   host_->SetupForOverscrollControllerTest();
-  host_->DisableGestureDebounce();
   process_->sink().ClearMessages();
   view_->set_bounds(gfx::Rect(0, 0, 400, 200));
   view_->Show();
@@ -2175,7 +2165,6 @@
 // reset after the end of the scroll.
 TEST_F(RenderWidgetHostTest, OverscrollStateResetsAfterScroll) {
   host_->SetupForOverscrollControllerTest();
-  host_->DisableGestureDebounce();
   process_->sink().ClearMessages();
   view_->set_bounds(gfx::Rect(0, 0, 400, 200));
   view_->Show();
@@ -2250,6 +2239,7 @@
                     INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
   EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_mode());
   EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_delegate()->current_mode());
+  EXPECT_EQ(2U, process_->sink().message_count());
 
   host_->Blur();
   EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode());
@@ -2261,7 +2251,8 @@
 
   SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
                        WebGestureEvent::Touchscreen);
-  EXPECT_EQ(0U, process_->sink().message_count());
+  EXPECT_EQ(1U, process_->sink().message_count());
+  process_->sink().ClearMessages();
 
   // Start a scroll gesture again. This should correctly start the overscroll
   // after the threshold.
@@ -2278,7 +2269,7 @@
                        WebGestureEvent::Touchscreen);
   EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode());
   EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_delegate()->completed_mode());
-  process_->sink().ClearMessages();
+  EXPECT_EQ(3U, process_->sink().message_count());
 }
 
 std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
@@ -2301,7 +2292,6 @@
 
 TEST_F(RenderWidgetHostTest, TouchEmulator) {
   simulated_event_time_delta_seconds_ = 0.1;
-  host_->DisableGestureDebounce();
   // Immediately ack all touches instead of sending them to the renderer.
   host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
   host_->OnMessageReceived(
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index b2f6e1c..b3aad6a 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1447,7 +1447,7 @@
 }
 
 // static
-void RenderWidgetHostViewPort::GetDefaultScreenInfo(
+void RenderWidgetHostViewBase::GetDefaultScreenInfo(
     blink::WebScreenInfo* results) {
   const gfx::Display& display =
       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
@@ -1462,14 +1462,4 @@
   results->isMonochrome = (results->depthPerComponent == 0);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostView, public:
-
-// static
-RenderWidgetHostView*
-RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) {
-  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
-  return new RenderWidgetHostViewAndroid(rwhi, NULL);
-}
-
 } // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index 914a020..1c3d443 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -21,6 +21,7 @@
 #include "content/browser/renderer_host/image_transport_factory_android.h"
 #include "content/browser/renderer_host/ime_adapter_android.h"
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
+#include "content/common/content_export.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
@@ -58,7 +59,7 @@
 // -----------------------------------------------------------------------------
 // See comments in render_widget_host_view.h about this class and its members.
 // -----------------------------------------------------------------------------
-class RenderWidgetHostViewAndroid
+class CONTENT_EXPORT RenderWidgetHostViewAndroid
     : public RenderWidgetHostViewBase,
       public cc::DelegatedFrameResourceCollectionClient,
       public ImageTransportFactoryAndroidObserver,
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 491e64c..116a6f4 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -8,14 +8,10 @@
 #include "base/basictypes.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/command_line.h"
 #include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/string_number_conversions.h"
-#include "cc/layers/delegated_frame_provider.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/compositor_frame_ack.h"
 #include "cc/output/copy_output_request.h"
 #include "cc/output/copy_output_result.h"
 #include "cc/resources/texture_mailbox.h"
@@ -38,15 +34,10 @@
 #include "content/common/gpu/client/gl_helper.h"
 #include "content/common/gpu/gpu_messages.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/browser/user_metrics.h"
-#include "content/public/common/content_switches.h"
-#include "media/base/video_util.h"
-#include "skia/ext/image_operations.h"
 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
@@ -67,7 +58,6 @@
 #include "ui/base/ime/input_method.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/compositor/compositor_vsync_manager.h"
-#include "ui/compositor/layer.h"
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
 #include "ui/events/gestures/gesture_recognizer.h"
@@ -418,6 +408,7 @@
 RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
     : host_(RenderWidgetHostImpl::From(host)),
       window_(new aura::Window(this)),
+      delegated_frame_host_(new DelegatedFrameHost(this)),
       in_shutdown_(false),
       in_bounds_changed_(false),
       is_fullscreen_(false),
@@ -429,16 +420,11 @@
       can_compose_inline_(true),
       has_composition_text_(false),
       accept_return_character_(false),
-      last_output_surface_id_(0),
-      pending_delegated_ack_count_(0),
-      skipped_frames_(false),
       last_swapped_software_frame_scale_factor_(1.f),
       paint_canvas_(NULL),
       synthetic_move_sent_(false),
-      can_lock_compositor_(YES),
       cursor_visibility_state_in_renderer_(UNKNOWN),
       touch_editing_client_(NULL),
-      delegated_frame_evictor_(new DelegatedFrameEvictor(this)),
       weak_ptr_factory_(this) {
   host_->SetView(this);
   window_observer_.reset(new WindowObserver(this));
@@ -446,9 +432,8 @@
   aura::client::SetActivationDelegate(window_, this);
   aura::client::SetActivationChangeObserver(window_, this);
   aura::client::SetFocusChangeObserver(window_, this);
-  window_->set_layer_owner_delegate(this);
+  window_->set_layer_owner_delegate(delegated_frame_host_.get());
   gfx::Screen::GetScreenFor(window_)->AddObserver(this);
-  ImageTransportFactory::GetInstance()->AddObserver(this);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -558,7 +543,6 @@
   if (!host_->is_hidden())
     return;
   host_->WasShown();
-  delegated_frame_evictor_->SetVisible(true);
 
   aura::Window* root = window_->GetRootWindow();
   if (root) {
@@ -568,12 +552,7 @@
       NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
   }
 
-  if (host_->is_accelerated_compositing_active() &&
-      !released_front_lock_.get()) {
-    ui::Compositor* compositor = GetCompositor();
-    if (compositor)
-      released_front_lock_ = compositor->GetCompositorLock();
-  }
+  delegated_frame_host_->WasShown();
 
 #if defined(OS_WIN)
   if (legacy_render_widget_host_HWND_) {
@@ -595,8 +574,7 @@
   if (!host_ || host_->is_hidden())
     return;
   host_->WasHidden();
-  delegated_frame_evictor_->SetVisible(false);
-  released_front_lock_ = NULL;
+  delegated_frame_host_->WasHidden();
 
 #if defined(OS_WIN)
   constrained_rects_.clear();
@@ -638,77 +616,6 @@
   InternalSetBounds(gfx::Rect(relative_origin, rect.size()));
 }
 
-void RenderWidgetHostViewAura::MaybeCreateResizeLock() {
-  if (!ShouldCreateResizeLock())
-    return;
-  DCHECK(window_->GetHost());
-  DCHECK(window_->GetHost()->compositor());
-
-  // Listen to changes in the compositor lock state.
-  ui::Compositor* compositor = window_->GetHost()->compositor();
-  if (!compositor->HasObserver(this))
-    compositor->AddObserver(this);
-
-  bool defer_compositor_lock =
-      can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
-      can_lock_compositor_ == NO_PENDING_COMMIT;
-
-  if (can_lock_compositor_ == YES)
-    can_lock_compositor_ = YES_DID_LOCK;
-
-  resize_lock_ = CreateResizeLock(defer_compositor_lock);
-}
-
-bool RenderWidgetHostViewAura::ShouldCreateResizeLock() {
-  // On Windows while resizing, the the resize locks makes us mis-paint a white
-  // vertical strip (including the non-client area) if the content composition
-  // is lagging the UI composition. So here we disable the throttling so that
-  // the UI bits can draw ahead of the content thereby reducing the amount of
-  // whiteout. Because this causes the content to be drawn at wrong sizes while
-  // resizing we compensate by blocking the UI thread in Compositor::Draw() by
-  // issuing a FinishAllRendering() if we are resizing.
-#if defined(OS_WIN)
-  return false;
-#else
-  if (resize_lock_)
-    return false;
-
-  if (host_->should_auto_resize())
-    return false;
-  if (!host_->is_accelerated_compositing_active())
-    return false;
-
-  gfx::Size desired_size = window_->bounds().size();
-  if (desired_size == current_frame_size_in_dip_)
-    return false;
-
-  aura::WindowTreeHost* host = window_->GetHost();
-  if (!host)
-    return false;
-
-  ui::Compositor* compositor = host->compositor();
-  if (!compositor)
-    return false;
-
-  return true;
-#endif
-}
-
-scoped_ptr<ResizeLock> RenderWidgetHostViewAura::CreateResizeLock(
-    bool defer_compositor_lock) {
-  gfx::Size desired_size = window_->bounds().size();
-  return scoped_ptr<ResizeLock>(new CompositorResizeLock(
-      window_->GetHost(),
-      desired_size,
-      defer_compositor_lock,
-      base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs)));
-}
-
-void RenderWidgetHostViewAura::RequestCopyOfOutput(
-    scoped_ptr<cc::CopyOutputRequest> request) {
-  window_->layer()->RequestCopyOfOutput(request.Pass());
-}
-
 gfx::NativeView RenderWidgetHostViewAura::GetNativeView() const {
   return window_;
 }
@@ -739,6 +646,10 @@
   return static_cast<gfx::NativeViewAccessible>(NULL);
 }
 
+ui::TextInputClient* RenderWidgetHostViewAura::GetTextInputClient() {
+  return this;
+}
+
 void RenderWidgetHostViewAura::SetKeyboardFocus() {
 #if defined(OS_WIN)
   if (CanFocus()) {
@@ -831,7 +742,7 @@
 }
 
 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const {
-  return CanCopyToBitmap();
+  return delegated_frame_host_->CanCopyToBitmap();
 }
 
 void RenderWidgetHostViewAura::Show() {
@@ -861,10 +772,7 @@
   // for the correct frame (i.e. during a resize), don't change the size so that
   // we don't pipeline more resizes than we can handle.
   gfx::Rect bounds(window_->GetBoundsInScreen());
-  if (resize_lock_.get())
-    return gfx::Rect(bounds.origin(), resize_lock_->expected_size());
-  else
-    return bounds;
+  return delegated_frame_host_->GetViewBoundsWithResizeLock(bounds);
 }
 
 void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) {
@@ -1024,97 +932,33 @@
     const gfx::Size& dst_size,
     const base::Callback<void(bool, const SkBitmap&)>& callback,
     const SkBitmap::Config config) {
-  // Only ARGB888 and RGB565 supported as of now.
-  bool format_support = ((config == SkBitmap::kRGB_565_Config) ||
-                         (config == SkBitmap::kARGB_8888_Config));
-  if (!format_support) {
-    DCHECK(format_support);
-    callback.Run(false, SkBitmap());
-    return;
-  }
-  if (!CanCopyToBitmap()) {
-    callback.Run(false, SkBitmap());
-    return;
-  }
-
-  const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size);
-  scoped_ptr<cc::CopyOutputRequest> request =
-      cc::CopyOutputRequest::CreateRequest(base::Bind(
-          &RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResult,
-          dst_size_in_pixel,
-          config,
-          callback));
-  gfx::Rect src_subrect_in_pixel =
-      ConvertRectToPixel(current_device_scale_factor_, src_subrect);
-  request->set_area(src_subrect_in_pixel);
-  RequestCopyOfOutput(request.Pass());
+  delegated_frame_host_->CopyFromCompositingSurface(
+      src_subrect, dst_size, callback, config);
 }
 
 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame(
       const gfx::Rect& src_subrect,
       const scoped_refptr<media::VideoFrame>& target,
       const base::Callback<void(bool)>& callback) {
-  if (!CanCopyToVideoFrame()) {
-    callback.Run(false);
-    return;
-  }
-
-  // Try get a texture to reuse.
-  scoped_refptr<OwnedMailbox> subscriber_texture;
-  if (frame_subscriber_) {
-    if (!idle_frame_subscriber_textures_.empty()) {
-      subscriber_texture = idle_frame_subscriber_textures_.back();
-      idle_frame_subscriber_textures_.pop_back();
-    } else if (GLHelper* helper =
-                   ImageTransportFactory::GetInstance()->GetGLHelper()) {
-      subscriber_texture = new OwnedMailbox(helper);
-    }
-    if (subscriber_texture.get())
-      active_frame_subscriber_textures_.insert(subscriber_texture.get());
-  }
-
-  scoped_ptr<cc::CopyOutputRequest> request =
-      cc::CopyOutputRequest::CreateRequest(base::Bind(
-          &RenderWidgetHostViewAura::
-               CopyFromCompositingSurfaceHasResultForVideo,
-          AsWeakPtr(),  // For caching the ReadbackYUVInterface on this class.
-          subscriber_texture,
-          target,
-          callback));
-  gfx::Rect src_subrect_in_pixel =
-      ConvertRectToPixel(current_device_scale_factor_, src_subrect);
-  request->set_area(src_subrect_in_pixel);
-  if (subscriber_texture.get()) {
-    request->SetTextureMailbox(
-        cc::TextureMailbox(subscriber_texture->mailbox(),
-                           subscriber_texture->target(),
-                           subscriber_texture->sync_point()));
-  }
-  RequestCopyOfOutput(request.Pass());
-}
-
-bool RenderWidgetHostViewAura::CanCopyToBitmap() const {
-  return GetCompositor() && window_->layer()->has_external_content();
+  delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame(
+      src_subrect, target, callback);
 }
 
 bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const {
-  return GetCompositor() &&
-         window_->layer()->has_external_content() &&
-         host_->is_accelerated_compositing_active();
+  return delegated_frame_host_->CanCopyToVideoFrame();
 }
 
 bool RenderWidgetHostViewAura::CanSubscribeFrame() const {
-  return true;
+  return delegated_frame_host_->CanSubscribeFrame();
 }
 
 void RenderWidgetHostViewAura::BeginFrameSubscription(
     scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
-  frame_subscriber_ = subscriber.Pass();
+  delegated_frame_host_->BeginFrameSubscription(subscriber.Pass());
 }
 
 void RenderWidgetHostViewAura::EndFrameSubscription() {
-  idle_frame_subscriber_textures_.clear();
-  frame_subscriber_.reset();
+  delegated_frame_host_->EndFrameSubscription();
 }
 
 void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
@@ -1124,15 +968,6 @@
                                                              int route_id) {
 }
 
-bool RenderWidgetHostViewAura::ShouldSkipFrame(gfx::Size size_in_dip) const {
-  if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
-      can_lock_compositor_ == NO_PENDING_COMMIT ||
-      !resize_lock_.get())
-    return false;
-
-  return size_in_dip != resize_lock_->expected_size();
-}
-
 void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) {
   if (HasDisplayPropertyChanged(window_))
     host_->InvalidateScreenInfo();
@@ -1142,7 +977,7 @@
   if (!in_bounds_changed_)
     window_->SetBounds(rect);
   host_->WasResized();
-  MaybeCreateResizeLock();
+  delegated_frame_host_->WasResized();
   if (touch_editing_client_) {
     touch_editing_client_->OnSelectionOrCursorChanged(selection_anchor_rect_,
       selection_focus_rect_);
@@ -1174,38 +1009,11 @@
 #endif
 }
 
-void RenderWidgetHostViewAura::CheckResizeLock() {
-  if (!resize_lock_ ||
-      resize_lock_->expected_size() != current_frame_size_in_dip_)
-    return;
-
-  // Since we got the size we were looking for, unlock the compositor. But delay
-  // the release of the lock until we've kicked a frame with the new texture, to
-  // avoid resizing the UI before we have a chance to draw a "good" frame.
-  resize_lock_->UnlockCompositor();
-  ui::Compositor* compositor = GetCompositor();
-  if (compositor) {
-    if (!compositor->HasObserver(this))
-      compositor->AddObserver(this);
-  }
-}
-
-void RenderWidgetHostViewAura::DidReceiveFrameFromRenderer() {
-  if (frame_subscriber() && CanCopyToVideoFrame()) {
-    const base::TimeTicks present_time = base::TimeTicks::Now();
-    scoped_refptr<media::VideoFrame> frame;
-    RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback;
-    if (frame_subscriber()->ShouldCaptureFrame(present_time,
-                                               &frame, &callback)) {
-      CopyFromCompositingSurfaceToVideoFrame(
-          gfx::Rect(current_frame_size_in_dip_),
-          frame,
-          base::Bind(callback, present_time));
-    }
-  }
-}
-
 #if defined(OS_WIN)
+bool RenderWidgetHostViewAura::UsesNativeWindowFrame() const {
+  return (legacy_render_widget_host_HWND_ != NULL);
+}
+
 void RenderWidgetHostViewAura::UpdateConstrainedWindowRects(
     const std::vector<gfx::Rect>& rects) {
   // Check this before setting constrained_rects_, so that next time they're set
@@ -1242,164 +1050,16 @@
   // Oldschool composited mode is no longer supported.
 }
 
-void RenderWidgetHostViewAura::SwapDelegatedFrame(
-    uint32 output_surface_id,
-    scoped_ptr<cc::DelegatedFrameData> frame_data,
-    float frame_device_scale_factor,
-    const std::vector<ui::LatencyInfo>& latency_info) {
-  DCHECK_NE(0u, frame_data->render_pass_list.size());
-
-  cc::RenderPass* root_pass = frame_data->render_pass_list.back();
-
-  gfx::Size frame_size = root_pass->output_rect.size();
-  gfx::Size frame_size_in_dip =
-      ConvertSizeToDIP(frame_device_scale_factor, frame_size);
-
-  gfx::Rect damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect);
-  damage_rect.Intersect(gfx::Rect(frame_size));
-  gfx::Rect damage_rect_in_dip =
-      ConvertRectToDIP(frame_device_scale_factor, damage_rect);
-
-  if (ShouldSkipFrame(frame_size_in_dip)) {
-    cc::CompositorFrameAck ack;
-    cc::TransferableResource::ReturnResources(frame_data->resource_list,
-                                              &ack.resources);
-    RenderWidgetHostImpl::SendSwapCompositorFrameAck(
-        host_->GetRoutingID(), output_surface_id,
-        host_->GetProcess()->GetID(), ack);
-    skipped_frames_ = true;
-    return;
-  }
-
-  if (skipped_frames_) {
-    skipped_frames_ = false;
-    damage_rect = gfx::Rect(frame_size);
-    damage_rect_in_dip = gfx::Rect(frame_size_in_dip);
-
-    // Give the same damage rect to the compositor.
-    cc::RenderPass* root_pass = frame_data->render_pass_list.back();
-    root_pass->damage_rect = damage_rect;
-  }
-
-  if (output_surface_id != last_output_surface_id_) {
-    // Resource ids are scoped by the output surface.
-    // If the originating output surface doesn't match the last one, it
-    // indicates the renderer's output surface may have been recreated, in which
-    // case we should recreate the DelegatedRendererLayer, to avoid matching
-    // resources from the old one with resources from the new one which would
-    // have the same id. Changing the layer to showing painted content destroys
-    // the DelegatedRendererLayer.
-    EvictDelegatedFrame();
-
-    // Drop the cc::DelegatedFrameResourceCollection so that we will not return
-    // any resources from the old output surface with the new output surface id.
-    if (resource_collection_.get()) {
-      resource_collection_->SetClient(NULL);
-
-      if (resource_collection_->LoseAllResources())
-        SendReturnedDelegatedResources(last_output_surface_id_);
-
-      resource_collection_ = NULL;
-    }
-    last_output_surface_id_ = output_surface_id;
-  }
-  if (frame_size.IsEmpty()) {
-    DCHECK_EQ(0u, frame_data->resource_list.size());
-    EvictDelegatedFrame();
-  } else {
-    if (!resource_collection_) {
-      resource_collection_ = new cc::DelegatedFrameResourceCollection;
-      resource_collection_->SetClient(this);
-    }
-    // If the physical frame size changes, we need a new |frame_provider_|. If
-    // the physical frame size is the same, but the size in DIP changed, we
-    // need to adjust the scale at which the frames will be drawn, and we do
-    // this by making a new |frame_provider_| also to ensure the scale change
-    // is presented in sync with the new frame content.
-    if (!frame_provider_.get() || frame_size != frame_provider_->frame_size() ||
-        frame_size_in_dip != current_frame_size_in_dip_) {
-      frame_provider_ = new cc::DelegatedFrameProvider(
-          resource_collection_.get(), frame_data.Pass());
-      window_->layer()->SetShowDelegatedContent(frame_provider_.get(),
-                                                frame_size_in_dip);
-    } else {
-      frame_provider_->SetFrameData(frame_data.Pass());
-    }
-  }
-  released_front_lock_ = NULL;
-  current_frame_size_in_dip_ = frame_size_in_dip;
-  CheckResizeLock();
-
-  window_->SchedulePaintInRect(damage_rect_in_dip);
-
-  pending_delegated_ack_count_++;
-
-  ui::Compositor* compositor = GetCompositor();
-  if (!compositor) {
-    SendDelegatedFrameAck(output_surface_id);
-  } else {
-    for (size_t i = 0; i < latency_info.size(); i++)
-      compositor->SetLatencyInfo(latency_info[i]);
-    AddOnCommitCallbackAndDisableLocks(
-        base::Bind(&RenderWidgetHostViewAura::SendDelegatedFrameAck,
-                   AsWeakPtr(),
-                   output_surface_id));
-  }
-  DidReceiveFrameFromRenderer();
-  if (frame_provider_.get())
-    delegated_frame_evictor_->SwappedFrame(!host_->is_hidden());
-  // Note: the frame may have been evicted immediately.
-}
-
-void RenderWidgetHostViewAura::SendDelegatedFrameAck(uint32 output_surface_id) {
-  cc::CompositorFrameAck ack;
-  if (resource_collection_)
-    resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
-  RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
-                                                   output_surface_id,
-                                                   host_->GetProcess()->GetID(),
-                                                   ack);
-  DCHECK_GT(pending_delegated_ack_count_, 0);
-  pending_delegated_ack_count_--;
-}
-
-void RenderWidgetHostViewAura::UnusedResourcesAreAvailable() {
-  if (pending_delegated_ack_count_)
-    return;
-
-  SendReturnedDelegatedResources(last_output_surface_id_);
-}
-
-void RenderWidgetHostViewAura::SendReturnedDelegatedResources(
-    uint32 output_surface_id) {
-  DCHECK(resource_collection_);
-
-  cc::CompositorFrameAck ack;
-  resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
-  DCHECK(!ack.resources.empty());
-
-  RenderWidgetHostImpl::SendReclaimCompositorResources(
-      host_->GetRoutingID(),
-      output_surface_id,
-      host_->GetProcess()->GetID(),
-      ack);
-}
-
-void RenderWidgetHostViewAura::EvictDelegatedFrame() {
-  window_->layer()->SetShowPaintedContent();
-  frame_provider_ = NULL;
-  delegated_frame_evictor_->DiscardedFrame();
-}
-
 void RenderWidgetHostViewAura::OnSwapCompositorFrame(
     uint32 output_surface_id,
     scoped_ptr<cc::CompositorFrame> frame) {
   TRACE_EVENT0("content", "RenderWidgetHostViewAura::OnSwapCompositorFrame");
   if (frame->delegated_frame_data) {
-    SwapDelegatedFrame(output_surface_id,
-                       frame->delegated_frame_data.Pass(),
-                       frame->metadata.device_scale_factor,
-                       frame->metadata.latency_info);
+    delegated_frame_host_->SwapDelegatedFrame(
+        output_surface_id,
+        frame->delegated_frame_data.Pass(),
+        frame->metadata.device_scale_factor,
+        frame->metadata.latency_info);
     return;
   }
 
@@ -1451,310 +1111,46 @@
   return false;
 }
 
-// static
-void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResult(
-    const gfx::Size& dst_size_in_pixel,
-    const SkBitmap::Config config,
-    const base::Callback<void(bool, const SkBitmap&)>& callback,
-    scoped_ptr<cc::CopyOutputResult> result) {
-  if (result->IsEmpty() || result->size().IsEmpty()) {
-    callback.Run(false, SkBitmap());
-    return;
-  }
-
-  if (result->HasTexture()) {
-    PrepareTextureCopyOutputResult(dst_size_in_pixel, config,
-                                   callback,
-                                   result.Pass());
-    return;
-  }
-
-  DCHECK(result->HasBitmap());
-  PrepareBitmapCopyOutputResult(dst_size_in_pixel, config, callback,
-                                result.Pass());
-}
-
-static void CopyFromCompositingSurfaceFinished(
-    const base::Callback<void(bool, const SkBitmap&)>& callback,
-    scoped_ptr<cc::SingleReleaseCallback> release_callback,
-    scoped_ptr<SkBitmap> bitmap,
-    scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
-    bool result) {
-  bitmap_pixels_lock.reset();
-
-  uint32 sync_point = 0;
-  if (result) {
-    GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
-    sync_point = gl_helper->InsertSyncPoint();
-  }
-  bool lost_resource = sync_point == 0;
-  release_callback->Run(sync_point, lost_resource);
-
-  callback.Run(result, *bitmap);
-}
-
-// static
-void RenderWidgetHostViewAura::PrepareTextureCopyOutputResult(
-    const gfx::Size& dst_size_in_pixel,
-    const SkBitmap::Config config,
-    const base::Callback<void(bool, const SkBitmap&)>& callback,
-    scoped_ptr<cc::CopyOutputResult> result) {
-  DCHECK(result->HasTexture());
-  base::ScopedClosureRunner scoped_callback_runner(
-      base::Bind(callback, false, SkBitmap()));
-
-  scoped_ptr<SkBitmap> bitmap(new SkBitmap);
-  bitmap->setConfig(config,
-                    dst_size_in_pixel.width(), dst_size_in_pixel.height(),
-                    0, kOpaque_SkAlphaType);
-  if (!bitmap->allocPixels())
-    return;
-
-  ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
-  GLHelper* gl_helper = factory->GetGLHelper();
-  if (!gl_helper)
-    return;
-
-  scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
-      new SkAutoLockPixels(*bitmap));
-  uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
-
-  cc::TextureMailbox texture_mailbox;
-  scoped_ptr<cc::SingleReleaseCallback> release_callback;
-  result->TakeTexture(&texture_mailbox, &release_callback);
-  DCHECK(texture_mailbox.IsTexture());
-  if (!texture_mailbox.IsTexture())
-    return;
-
-  ignore_result(scoped_callback_runner.Release());
-
-  gl_helper->CropScaleReadbackAndCleanMailbox(
-      texture_mailbox.mailbox(),
-      texture_mailbox.sync_point(),
-      result->size(),
-      gfx::Rect(result->size()),
-      dst_size_in_pixel,
-      pixels,
-      config,
-      base::Bind(&CopyFromCompositingSurfaceFinished,
-                 callback,
-                 base::Passed(&release_callback),
-                 base::Passed(&bitmap),
-                 base::Passed(&bitmap_pixels_lock)));
-}
-
-// static
-void RenderWidgetHostViewAura::PrepareBitmapCopyOutputResult(
-    const gfx::Size& dst_size_in_pixel,
-    const SkBitmap::Config config,
-    const base::Callback<void(bool, const SkBitmap&)>& callback,
-    scoped_ptr<cc::CopyOutputResult> result) {
-  if (config != SkBitmap::kARGB_8888_Config) {
-    NOTIMPLEMENTED();
-    callback.Run(false, SkBitmap());
-    return;
-  }
-  DCHECK(result->HasBitmap());
-  base::ScopedClosureRunner scoped_callback_runner(
-      base::Bind(callback, false, SkBitmap()));
-
-  scoped_ptr<SkBitmap> source = result->TakeBitmap();
-  DCHECK(source);
-  if (!source)
-    return;
-
-  ignore_result(scoped_callback_runner.Release());
-
-  SkBitmap bitmap = skia::ImageOperations::Resize(
-      *source,
-      skia::ImageOperations::RESIZE_BEST,
-      dst_size_in_pixel.width(),
-      dst_size_in_pixel.height());
-  callback.Run(true, bitmap);
-}
-
-// static
-void RenderWidgetHostViewAura::ReturnSubscriberTexture(
-    base::WeakPtr<RenderWidgetHostViewAura> rwhva,
-    scoped_refptr<OwnedMailbox> subscriber_texture,
-    uint32 sync_point) {
-  if (!subscriber_texture.get())
-    return;
-  if (!rwhva)
-    return;
-  DCHECK_NE(
-      rwhva->active_frame_subscriber_textures_.count(subscriber_texture.get()),
-      0u);
-
-  subscriber_texture->UpdateSyncPoint(sync_point);
-
-  rwhva->active_frame_subscriber_textures_.erase(subscriber_texture.get());
-  if (rwhva->frame_subscriber_ && subscriber_texture->texture_id())
-    rwhva->idle_frame_subscriber_textures_.push_back(subscriber_texture);
-}
-
-void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinishedForVideo(
-    base::WeakPtr<RenderWidgetHostViewAura> rwhva,
-    const base::Callback<void(bool)>& callback,
-    scoped_refptr<OwnedMailbox> subscriber_texture,
-    scoped_ptr<cc::SingleReleaseCallback> release_callback,
-    bool result) {
-  callback.Run(result);
-
-  uint32 sync_point = 0;
-  if (result) {
-    GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
-    sync_point = gl_helper->InsertSyncPoint();
-  }
-  if (release_callback) {
-    // A release callback means the texture came from the compositor, so there
-    // should be no |subscriber_texture|.
-    DCHECK(!subscriber_texture);
-    bool lost_resource = sync_point == 0;
-    release_callback->Run(sync_point, lost_resource);
-  }
-  ReturnSubscriberTexture(rwhva, subscriber_texture, sync_point);
-}
-
-// static
-void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResultForVideo(
-    base::WeakPtr<RenderWidgetHostViewAura> rwhva,
-    scoped_refptr<OwnedMailbox> subscriber_texture,
-    scoped_refptr<media::VideoFrame> video_frame,
-    const base::Callback<void(bool)>& callback,
-    scoped_ptr<cc::CopyOutputResult> result) {
-  base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
-  base::ScopedClosureRunner scoped_return_subscriber_texture(
-      base::Bind(&ReturnSubscriberTexture, rwhva, subscriber_texture, 0));
-
-  if (!rwhva)
-    return;
-  if (result->IsEmpty())
-    return;
-  if (result->size().IsEmpty())
-    return;
-
-  // Compute the dest size we want after the letterboxing resize. Make the
-  // coordinates and sizes even because we letterbox in YUV space
-  // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
-  // line up correctly.
-  // The video frame's coded_size() and the result's size() are both physical
-  // pixels.
-  gfx::Rect region_in_frame =
-      media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()),
-                                    result->size());
-  region_in_frame = gfx::Rect(region_in_frame.x() & ~1,
-                              region_in_frame.y() & ~1,
-                              region_in_frame.width() & ~1,
-                              region_in_frame.height() & ~1);
-  if (region_in_frame.IsEmpty())
-    return;
-
-  if (!result->HasTexture()) {
-    DCHECK(result->HasBitmap());
-    scoped_ptr<SkBitmap> bitmap = result->TakeBitmap();
-    // Scale the bitmap to the required size, if necessary.
-    SkBitmap scaled_bitmap;
-    if (result->size().width() != region_in_frame.width() ||
-        result->size().height() != region_in_frame.height()) {
-      skia::ImageOperations::ResizeMethod method =
-          skia::ImageOperations::RESIZE_GOOD;
-      scaled_bitmap = skia::ImageOperations::Resize(*bitmap.get(), method,
-                                                    region_in_frame.width(),
-                                                    region_in_frame.height());
-    } else {
-      scaled_bitmap = *bitmap.get();
-    }
-
-    {
-      SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap);
-
-      media::CopyRGBToVideoFrame(
-          reinterpret_cast<uint8*>(scaled_bitmap.getPixels()),
-          scaled_bitmap.rowBytes(),
-          region_in_frame,
-          video_frame.get());
-    }
-    ignore_result(scoped_callback_runner.Release());
-    callback.Run(true);
-    return;
-  }
-
-  ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
-  GLHelper* gl_helper = factory->GetGLHelper();
-  if (!gl_helper)
-    return;
-  if (subscriber_texture.get() && !subscriber_texture->texture_id())
-    return;
-
-  cc::TextureMailbox texture_mailbox;
-  scoped_ptr<cc::SingleReleaseCallback> release_callback;
-  result->TakeTexture(&texture_mailbox, &release_callback);
-  DCHECK(texture_mailbox.IsTexture());
-  if (!texture_mailbox.IsTexture())
-    return;
-
-  gfx::Rect result_rect(result->size());
-
-  content::ReadbackYUVInterface* yuv_readback_pipeline =
-      rwhva->yuv_readback_pipeline_.get();
-  if (yuv_readback_pipeline == NULL ||
-      yuv_readback_pipeline->scaler()->SrcSize() != result_rect.size() ||
-      yuv_readback_pipeline->scaler()->SrcSubrect() != result_rect ||
-      yuv_readback_pipeline->scaler()->DstSize() != region_in_frame.size()) {
-    GLHelper::ScalerQuality quality = GLHelper::SCALER_QUALITY_FAST;
-    std::string quality_switch = switches::kTabCaptureDownscaleQuality;
-    // If we're scaling up, we can use the "best" quality.
-    if (result_rect.size().width() < region_in_frame.size().width() &&
-        result_rect.size().height() < region_in_frame.size().height())
-      quality_switch = switches::kTabCaptureUpscaleQuality;
-
-    std::string switch_value =
-        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(quality_switch);
-    if (switch_value == "fast")
-      quality = GLHelper::SCALER_QUALITY_FAST;
-    else if (switch_value == "good")
-      quality = GLHelper::SCALER_QUALITY_GOOD;
-    else if (switch_value == "best")
-      quality = GLHelper::SCALER_QUALITY_BEST;
-
-    rwhva->yuv_readback_pipeline_.reset(
-        gl_helper->CreateReadbackPipelineYUV(quality,
-                                             result_rect.size(),
-                                             result_rect,
-                                             video_frame->coded_size(),
-                                             region_in_frame,
-                                             true,
-                                             true));
-    yuv_readback_pipeline = rwhva->yuv_readback_pipeline_.get();
-  }
-
-  ignore_result(scoped_callback_runner.Release());
-  ignore_result(scoped_return_subscriber_texture.Release());
-  base::Callback<void(bool result)> finished_callback = base::Bind(
-      &RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinishedForVideo,
-      rwhva->AsWeakPtr(),
-      callback,
-      subscriber_texture,
-      base::Passed(&release_callback));
-  yuv_readback_pipeline->ReadbackYUV(texture_mailbox.mailbox(),
-                                     texture_mailbox.sync_point(),
-                                     video_frame.get(),
-                                     finished_callback);
-}
-
 void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo* results) {
   GetScreenInfoForWindow(results, window_->GetRootWindow() ? window_ : NULL);
 }
 
 gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() {
-  gfx::Rect rect = window_->GetToplevelWindow()->GetBoundsInScreen();
+  aura::Window* top_level = window_->GetToplevelWindow();
+  gfx::Rect bounds(top_level->GetBoundsInScreen());
 
 #if defined(OS_WIN)
-  rect = gfx::win::ScreenToDIPRect(rect);
+  // TODO(zturner,iyengar): This will break when we remove support for NPAPI and
+  // remove the legacy hwnd, so a better fix will need to be decided when that
+  // happens.
+  if (UsesNativeWindowFrame()) {
+    // aura::Window doesn't take into account non-client area of native windows
+    // (e.g. HWNDs), so for that case ask Windows directly what the bounds are.
+    aura::WindowTreeHost* host = top_level->GetHost();
+    if (!host)
+      return top_level->GetBoundsInScreen();
+    RECT window_rect = {0};
+    HWND hwnd = host->GetAcceleratedWidget();
+    ::GetWindowRect(hwnd, &window_rect);
+    bounds = gfx::Rect(window_rect);
+
+    // Maximized windows are outdented from the work area by the frame thickness
+    // even though this "frame" is not painted.  This confuses code (and people)
+    // that think of a maximized window as corresponding exactly to the work
+    // area.  Correct for this by subtracting the frame thickness back off.
+    if (::IsZoomed(hwnd)) {
+      bounds.Inset(GetSystemMetrics(SM_CXSIZEFRAME),
+                   GetSystemMetrics(SM_CYSIZEFRAME));
+
+      bounds.Inset(GetSystemMetrics(SM_CXPADDEDBORDER),
+                   GetSystemMetrics(SM_CXPADDEDBORDER));
+    }
+  }
+
+  bounds = gfx::win::ScreenToDIPRect(bounds);
 #endif
 
-  return rect;
+  return bounds;
 }
 
 void RenderWidgetHostViewAura::GestureEventAck(
@@ -2690,77 +2086,13 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostViewAura, ui::CompositorObserver implementation:
-
-void RenderWidgetHostViewAura::OnCompositingDidCommit(
-    ui::Compositor* compositor) {
-  if (can_lock_compositor_ == NO_PENDING_COMMIT) {
-    can_lock_compositor_ = YES;
-    if (resize_lock_.get() && resize_lock_->GrabDeferredLock())
-      can_lock_compositor_ = YES_DID_LOCK;
-  }
-  RunOnCommitCallbacks();
-  if (resize_lock_ &&
-      resize_lock_->expected_size() == current_frame_size_in_dip_) {
-    resize_lock_.reset();
-    host_->WasResized();
-    // We may have had a resize while we had the lock (e.g. if the lock expired,
-    // or if the UI still gave us some resizes), so make sure we grab a new lock
-    // if necessary.
-    MaybeCreateResizeLock();
-  }
-}
-
-void RenderWidgetHostViewAura::OnCompositingStarted(
-    ui::Compositor* compositor, base::TimeTicks start_time) {
-  last_draw_ended_ = start_time;
-}
-
-void RenderWidgetHostViewAura::OnCompositingEnded(
-    ui::Compositor* compositor) {
-}
-
-void RenderWidgetHostViewAura::OnCompositingAborted(
-    ui::Compositor* compositor) {
-}
-
-void RenderWidgetHostViewAura::OnCompositingLockStateChanged(
-    ui::Compositor* compositor) {
-  // A compositor lock that is part of a resize lock timed out. We
-  // should display a renderer frame.
-  if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) {
-    can_lock_compositor_ = NO_PENDING_RENDERER_FRAME;
-  }
-}
-
-void RenderWidgetHostViewAura::OnUpdateVSyncParameters(
-    base::TimeTicks timebase,
-    base::TimeDelta interval) {
-  if (IsShowing())
-    host_->UpdateVSyncParameters(timebase, interval);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation:
-
-void RenderWidgetHostViewAura::OnLostResources() {
-  if (frame_provider_.get())
-    EvictDelegatedFrame();
-  idle_frame_subscriber_textures_.clear();
-  yuv_readback_pipeline_.reset();
-
-  host_->ScheduleComposite();
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // RenderWidgetHostViewAura, private:
 
 RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
   if (touch_editing_client_)
     touch_editing_client_->OnViewDestroyed();
 
-  ImageTransportFactory::GetInstance()->RemoveObserver(this);
-
+  delegated_frame_host_.reset();
   window_observer_.reset();
   if (window_->GetHost())
     window_->GetHost()->RemoveObserver(this);
@@ -2784,24 +2116,9 @@
   // associated with the window, but just in case.
   DetachFromInputMethod();
 
-  if (resource_collection_.get())
-    resource_collection_->SetClient(NULL);
-
-  // An OwnedMailbox should not refer to the GLHelper anymore once the RWHVA is
-  // destroyed, as it may then outlive the GLHelper.
-  for (std::set<OwnedMailbox*>::iterator it =
-           active_frame_subscriber_textures_.begin();
-       it != active_frame_subscriber_textures_.end();
-       ++it) {
-    (*it)->Destroy();
-  }
-  active_frame_subscriber_textures_.clear();
-
 #if defined(OS_WIN)
   legacy_render_widget_host_HWND_.reset(NULL);
 #endif
-
-  DCHECK(!vsync_manager_);
 }
 
 void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
@@ -2924,27 +2241,6 @@
       global_mouse_position_.y() > rect.bottom() - border_y;
 }
 
-void RenderWidgetHostViewAura::RunOnCommitCallbacks() {
-  for (std::vector<base::Closure>::const_iterator
-      it = on_compositing_did_commit_callbacks_.begin();
-      it != on_compositing_did_commit_callbacks_.end(); ++it) {
-    it->Run();
-  }
-  on_compositing_did_commit_callbacks_.clear();
-}
-
-void RenderWidgetHostViewAura::AddOnCommitCallbackAndDisableLocks(
-    const base::Closure& callback) {
-  ui::Compositor* compositor = GetCompositor();
-  DCHECK(compositor);
-
-  if (!compositor->HasObserver(this))
-    compositor->AddObserver(this);
-
-  can_lock_compositor_ = NO_PENDING_COMMIT;
-  on_compositing_did_commit_callbacks_.push_back(callback);
-}
-
 void RenderWidgetHostViewAura::AddedToRootWindow() {
   window_->GetHost()->AddObserver(this);
   UpdateScreenInfo(window_);
@@ -2969,12 +2265,7 @@
         reinterpret_cast<HWND>(GetNativeViewId()));
 #endif
 
-  ui::Compositor* compositor = GetCompositor();
-  if (compositor) {
-    DCHECK(!vsync_manager_);
-    vsync_manager_ = compositor->vsync_manager();
-    vsync_manager_->AddObserver(this);
-  }
+  delegated_frame_host_->AddedToWindow();
 }
 
 void RenderWidgetHostViewAura::RemovingFromRootWindow() {
@@ -2986,12 +2277,7 @@
   DetachFromInputMethod();
 
   window_->GetHost()->RemoveObserver(this);
-  RunOnCommitCallbacks();
-  resize_lock_.reset();
-  host_->WasResized();
-  ui::Compositor* compositor = GetCompositor();
-  if (compositor && compositor->HasObserver(this))
-    compositor->RemoveObserver(this);
+  delegated_frame_host_->RemovingFromWindow();
 
 #if defined(OS_WIN)
   // Update the legacy window's parent temporarily to the desktop window. It
@@ -2999,16 +2285,6 @@
   if (legacy_render_widget_host_HWND_)
     legacy_render_widget_host_HWND_->UpdateParent(::GetDesktopWindow());
 #endif
-
-  if (vsync_manager_) {
-    vsync_manager_->RemoveObserver(this);
-    vsync_manager_ = NULL;
-  }
-}
-
-ui::Compositor* RenderWidgetHostViewAura::GetCompositor() const {
-  aura::WindowTreeHost* host = window_->GetHost();
-  return host ? host->compositor() : NULL;
 }
 
 void RenderWidgetHostViewAura::DetachFromInputMethod() {
@@ -3046,45 +2322,69 @@
   host_->ForwardKeyboardEvent(event);
 }
 
-void RenderWidgetHostViewAura::LockResources() {
-  DCHECK(frame_provider_);
-  delegated_frame_evictor_->LockFrame();
-}
-
-void RenderWidgetHostViewAura::UnlockResources() {
-  DCHECK(frame_provider_);
-  delegated_frame_evictor_->UnlockFrame();
-}
-
 SkBitmap::Config RenderWidgetHostViewAura::PreferredReadbackFormat() {
   return SkBitmap::kARGB_8888_Config;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostViewAura, ui::LayerOwnerDelegate implementation:
+// DelegatedFrameHost, public:
 
-void RenderWidgetHostViewAura::OnLayerRecreated(ui::Layer* old_layer,
-                                                ui::Layer* new_layer) {
-  // The new_layer is the one that will be used by our Window, so that's the one
-  // that should keep our frame. old_layer will be returned to the
-  // RecreateLayer caller, and should have a copy.
-  if (frame_provider_.get()) {
-    new_layer->SetShowDelegatedContent(frame_provider_.get(),
-                                       current_frame_size_in_dip_);
-  }
+ui::Compositor* RenderWidgetHostViewAura::GetCompositor() const {
+  aura::WindowTreeHost* host = window_->GetHost();
+  return host ? host->compositor() : NULL;
+}
+
+ui::Layer* RenderWidgetHostViewAura::GetLayer() {
+  return window_->layer();
+}
+
+RenderWidgetHostImpl* RenderWidgetHostViewAura::GetHost() {
+  return host_;
+}
+
+void RenderWidgetHostViewAura::SchedulePaintInRect(
+    const gfx::Rect& damage_rect_in_dip) {
+  window_->SchedulePaintInRect(damage_rect_in_dip);
+}
+
+bool RenderWidgetHostViewAura::IsVisible() {
+  return IsShowing();
+}
+
+gfx::Size RenderWidgetHostViewAura::DesiredFrameSize() {
+  return window_->bounds().size();
+}
+
+float RenderWidgetHostViewAura::CurrentDeviceScaleFactor() {
+  return current_device_scale_factor_;
+}
+
+gfx::Size RenderWidgetHostViewAura::ConvertViewSizeToPixel(
+    const gfx::Size& size) {
+  return content::ConvertViewSizeToPixel(this, size);
+}
+
+scoped_ptr<ResizeLock> RenderWidgetHostViewAura::CreateResizeLock(
+    bool defer_compositor_lock) {
+  gfx::Size desired_size = window_->bounds().size();
+  return scoped_ptr<ResizeLock>(new CompositorResizeLock(
+      window_->GetHost(),
+      desired_size,
+      defer_compositor_lock,
+      base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs)));
+  ResizeLock* lock = NULL;
+  return scoped_ptr<ResizeLock>(lock);
+}
+
+DelegatedFrameHost* RenderWidgetHostViewAura::GetDelegatedFrameHost() const {
+  return delegated_frame_host_.get();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostView, public:
+// RenderWidgetHostViewBase, public:
 
 // static
-RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
-    RenderWidgetHost* widget) {
-  return new RenderWidgetHostViewAura(widget);
-}
-
-// static
-void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) {
+void RenderWidgetHostViewBase::GetDefaultScreenInfo(WebScreenInfo* results) {
   GetScreenInfoForWindow(results, NULL);
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index e9fd837..fa3c0e7 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -16,28 +16,19 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "cc/layers/delegated_frame_provider.h"
-#include "cc/layers/delegated_frame_resource_collection.h"
-#include "cc/resources/single_release_callback.h"
-#include "cc/resources/texture_mailbox.h"
 #include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/compositor/delegated_frame_host.h"
 #include "content/browser/compositor/image_transport_factory.h"
 #include "content/browser/compositor/owned_mailbox.h"
-#include "content/browser/renderer_host/delegated_frame_evictor.h"
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/common/content_export.h"
 #include "content/common/cursors/webcursor.h"
-#include "content/common/gpu/client/gl_helper.h"
 #include "third_party/skia/include/core/SkRegion.h"
 #include "ui/aura/client/cursor_client_observer.h"
 #include "ui/aura/client/focus_change_observer.h"
 #include "ui/aura/window_delegate.h"
 #include "ui/aura/window_tree_host_observer.h"
 #include "ui/base/ime/text_input_client.h"
-#include "ui/compositor/compositor.h"
-#include "ui/compositor/compositor_observer.h"
-#include "ui/compositor/compositor_vsync_manager.h"
-#include "ui/compositor/layer_owner_delegate.h"
 #include "ui/gfx/display_observer.h"
 #include "ui/gfx/insets.h"
 #include "ui/gfx/rect.h"
@@ -68,7 +59,6 @@
 
 namespace ui {
 class CompositorLock;
-class CompositorVSyncManager;
 class InputMethod;
 class LocatedEvent;
 class Texture;
@@ -82,14 +72,11 @@
 class RenderFrameHostImpl;
 class RenderWidgetHostImpl;
 class RenderWidgetHostView;
-class ResizeLock;
 
 // RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
 class CONTENT_EXPORT RenderWidgetHostViewAura
     : public RenderWidgetHostViewBase,
-      public ui::CompositorObserver,
-      public ui::CompositorVSyncManager::Observer,
-      public ui::LayerOwnerDelegate,
+      public DelegatedFrameHostClient,
       public ui::TextInputClient,
       public gfx::DisplayObserver,
       public aura::WindowTreeHostObserver,
@@ -98,10 +85,7 @@
       public aura::client::ActivationChangeObserver,
       public aura::client::FocusChangeObserver,
       public aura::client::CursorClientObserver,
-      public ImageTransportFactoryObserver,
-      public DelegatedFrameEvictorClient,
-      public base::SupportsWeakPtr<RenderWidgetHostViewAura>,
-      public cc::DelegatedFrameResourceCollectionClient {
+      public base::SupportsWeakPtr<RenderWidgetHostViewAura> {
  public:
   // Displays and controls touch editing elements such as selection handles.
   class TouchEditingClient {
@@ -141,6 +125,8 @@
     touch_editing_client_ = client;
   }
 
+  explicit RenderWidgetHostViewAura(RenderWidgetHost* host);
+
   // RenderWidgetHostView implementation.
   virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
   virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE;
@@ -150,6 +136,7 @@
   virtual gfx::NativeView GetNativeView() const OVERRIDE;
   virtual gfx::NativeViewId GetNativeViewId() const OVERRIDE;
   virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE;
+  virtual ui::TextInputClient* GetTextInputClient() OVERRIDE;
   virtual bool HasFocus() const OVERRIDE;
   virtual bool IsSurfaceAvailableForCopy() const OVERRIDE;
   virtual void Show() OVERRIDE;
@@ -160,7 +147,7 @@
   virtual gfx::Size GetVisibleViewportSize() const OVERRIDE;
   virtual void SetInsets(const gfx::Insets& insets) OVERRIDE;
 
-  // Overridden from RenderWidgetHostViewPort:
+  // Overridden from RenderWidgetHostViewBase:
   virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
                            const gfx::Rect& pos) OVERRIDE;
   virtual void InitAsFullscreen(
@@ -322,8 +309,6 @@
   virtual void OnHostMoved(const aura::WindowTreeHost* host,
                            const gfx::Point& new_origin) OVERRIDE;
 
-  bool CanCopyToBitmap() const;
-
   void OnTextInputStateChanged(const ViewHostMsg_TextInputState_Params& params);
 
 #if defined(OS_WIN)
@@ -342,46 +327,12 @@
   bool IsClosing() const { return in_shutdown_; }
 
  protected:
-  friend class RenderWidgetHostView;
   virtual ~RenderWidgetHostViewAura();
 
-  // Should be constructed via RenderWidgetHostView::CreateViewForWidget.
-  explicit RenderWidgetHostViewAura(RenderWidgetHost* host);
-
-  RenderWidgetHostViewFrameSubscriber* frame_subscriber() const {
-    return frame_subscriber_.get();
-  }
-
-  virtual bool ShouldCreateResizeLock();
-  virtual scoped_ptr<ResizeLock> CreateResizeLock(bool defer_compositor_lock);
-
-  virtual void RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request);
-
   // Exposed for tests.
   aura::Window* window() { return window_; }
-  gfx::Size current_frame_size_in_dip() const {
-    return current_frame_size_in_dip_;
-  }
-  void LockResources();
-  void UnlockResources();
-
-  // Overridden from ui::CompositorObserver:
-  virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE;
-  virtual void OnCompositingStarted(ui::Compositor* compositor,
-                                    base::TimeTicks start_time) OVERRIDE;
-  virtual void OnCompositingEnded(ui::Compositor* compositor) OVERRIDE;
-  virtual void OnCompositingAborted(ui::Compositor* compositor) OVERRIDE;
-  virtual void OnCompositingLockStateChanged(
-      ui::Compositor* compositor) OVERRIDE;
-
-  // Overridden from ui::CompositorVSyncManager::Observer:
-  virtual void OnUpdateVSyncParameters(base::TimeTicks timebase,
-                                       base::TimeDelta interval) OVERRIDE;
   virtual SkBitmap::Config PreferredReadbackFormat() OVERRIDE;
-
-  // Overridden from ui::LayerOwnerObserver:
-  virtual void OnLayerRecreated(ui::Layer* old_layer,
-                                ui::Layer* new_layer) OVERRIDE;
+  virtual DelegatedFrameHost* GetDelegatedFrameHost() const OVERRIDE;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, SetCompositionText);
@@ -406,23 +357,16 @@
   class WindowObserver;
   friend class WindowObserver;
 
-  // Overridden from ImageTransportFactoryObserver:
-  virtual void OnLostResources() OVERRIDE;
-
   void UpdateCursorIfOverSelf();
-  bool ShouldSkipFrame(gfx::Size size_in_dip) const;
 
   // Set the bounds of the window and handle size changes.  Assumes the caller
   // has already adjusted the origin of |rect| to conform to whatever coordinate
   // space is required by the aura::Window.
   void InternalSetBounds(const gfx::Rect& rect);
 
-  // Lazily grab a resize lock if the aura window size doesn't match the current
-  // frame size, to give time to the renderer.
-  void MaybeCreateResizeLock();
-
-  // Checks if the resize lock can be released because we received an new frame.
-  void CheckResizeLock();
+#if defined(OS_WIN)
+  bool UsesNativeWindowFrame() const;
+#endif
 
   ui::InputMethod* GetInputMethod() const;
 
@@ -449,53 +393,24 @@
   // moved to center.
   bool ShouldMoveToCenter();
 
-  // Run all on compositing commit callbacks.
-  void RunOnCommitCallbacks();
-
-  // Add on compositing commit callback.
-  void AddOnCommitCallbackAndDisableLocks(const base::Closure& callback);
-
   // Called after |window_| is parented to a WindowEventDispatcher.
   void AddedToRootWindow();
 
   // Called prior to removing |window_| from a WindowEventDispatcher.
   void RemovingFromRootWindow();
 
-  // Called after async thumbnailer task completes.  Scales and crops the result
-  // of the copy.
-  static void CopyFromCompositingSurfaceHasResult(
-      const gfx::Size& dst_size_in_pixel,
-      const SkBitmap::Config config,
-      const base::Callback<void(bool, const SkBitmap&)>& callback,
-      scoped_ptr<cc::CopyOutputResult> result);
-  static void PrepareTextureCopyOutputResult(
-      const gfx::Size& dst_size_in_pixel,
-      const SkBitmap::Config config,
-      const base::Callback<void(bool, const SkBitmap&)>& callback,
-      scoped_ptr<cc::CopyOutputResult> result);
-  static void PrepareBitmapCopyOutputResult(
-      const gfx::Size& dst_size_in_pixel,
-      const SkBitmap::Config config,
-      const base::Callback<void(bool, const SkBitmap&)>& callback,
-      scoped_ptr<cc::CopyOutputResult> result);
-  static void CopyFromCompositingSurfaceHasResultForVideo(
-      base::WeakPtr<RenderWidgetHostViewAura> rwhva,
-      scoped_refptr<OwnedMailbox> subscriber_texture,
-      scoped_refptr<media::VideoFrame> video_frame,
-      const base::Callback<void(bool)>& callback,
-      scoped_ptr<cc::CopyOutputResult> result);
-  static void CopyFromCompositingSurfaceFinishedForVideo(
-      base::WeakPtr<RenderWidgetHostViewAura> rwhva,
-      const base::Callback<void(bool)>& callback,
-      scoped_refptr<OwnedMailbox> subscriber_texture,
-      scoped_ptr<cc::SingleReleaseCallback> release_callback,
-      bool result);
-  static void ReturnSubscriberTexture(
-      base::WeakPtr<RenderWidgetHostViewAura> rwhva,
-      scoped_refptr<OwnedMailbox> subscriber_texture,
-      uint32 sync_point);
-
-  ui::Compositor* GetCompositor() const;
+  // DelegatedFrameHostClient implementation.
+  virtual ui::Compositor* GetCompositor() const OVERRIDE;
+  virtual ui::Layer* GetLayer() OVERRIDE;
+  virtual RenderWidgetHostImpl* GetHost() OVERRIDE;
+  virtual void SchedulePaintInRect(
+      const gfx::Rect& damage_rect_in_dip) OVERRIDE;
+  virtual bool IsVisible() OVERRIDE;
+  virtual scoped_ptr<ResizeLock> CreateResizeLock(
+      bool defer_compositor_lock) OVERRIDE;
+  virtual gfx::Size DesiredFrameSize() OVERRIDE;
+  virtual float CurrentDeviceScaleFactor() OVERRIDE;
+  virtual gfx::Size ConvertViewSizeToPixel(const gfx::Size& size) OVERRIDE;
 
   // Detaches |this| from the input method object.
   void DetachFromInputMethod();
@@ -515,22 +430,6 @@
   // Converts |rect| from screen coordinate to window coordinate.
   gfx::Rect ConvertRectFromScreen(const gfx::Rect& rect) const;
 
-  void SwapDelegatedFrame(
-      uint32 output_surface_id,
-      scoped_ptr<cc::DelegatedFrameData> frame_data,
-      float frame_device_scale_factor,
-      const std::vector<ui::LatencyInfo>& latency_info);
-  void SendDelegatedFrameAck(uint32 output_surface_id);
-  void SendReturnedDelegatedResources(uint32 output_surface_id);
-
-  // DelegatedFrameEvictorClient implementation.
-  virtual void EvictDelegatedFrame() OVERRIDE;
-
-  // cc::DelegatedFrameProviderClient implementation.
-  virtual void UnusedResourcesAreAvailable() OVERRIDE;
-
-  void DidReceiveFrameFromRenderer();
-
   // Helper function to set keyboard focus to the main window.
   void SetKeyboardFocus();
 
@@ -541,6 +440,8 @@
 
   aura::Window* window_;
 
+  scoped_ptr<DelegatedFrameHost> delegated_frame_host_;
+
   scoped_ptr<WindowObserver> window_observer_;
 
   // Are we in the process of closing?  Tracked so fullscreen views can avoid
@@ -597,32 +498,6 @@
   // Current tooltip text.
   base::string16 tooltip_;
 
-  std::vector<base::Closure> on_compositing_did_commit_callbacks_;
-
-  // The vsync manager we are observing for changes, if any.
-  scoped_refptr<ui::CompositorVSyncManager> vsync_manager_;
-
-  // With delegated renderer, this is the last output surface, used to
-  // disambiguate resources with the same id coming from different output
-  // surfaces.
-  uint32 last_output_surface_id_;
-
-  // The number of delegated frame acks that are pending, to delay resource
-  // returns until the acks are sent.
-  int pending_delegated_ack_count_;
-
-  // True after a delegated frame has been skipped, until a frame is not
-  // skipped.
-  bool skipped_frames_;
-
-  // Holds delegated resources that have been given to a DelegatedFrameProvider,
-  // and gives back resources when they are no longer in use for return to the
-  // renderer.
-  scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection_;
-
-  // Provides delegated frame updates to the cc::DelegatedRendererLayer.
-  scoped_refptr<cc::DelegatedFrameProvider> frame_provider_;
-
   // The size and scale of the last software compositing frame that was swapped.
   gfx::Size last_swapped_software_frame_size_;
   float last_swapped_software_frame_scale_factor_;
@@ -645,35 +520,10 @@
   // events vs. normal mouse move events.
   bool synthetic_move_sent_;
 
-  // This lock is the one waiting for a frame of the right size to come back
-  // from the renderer/GPU process. It is set from the moment the aura window
-  // got resized, to the moment we committed the renderer frame of the same
-  // size. It keeps track of the size we expect from the renderer, and locks the
-  // compositor, as well as the UI for a short time to give a chance to the
-  // renderer of producing a frame of the right size.
-  scoped_ptr<ResizeLock> resize_lock_;
-
-  // Keeps track of the current frame size.
-  gfx::Size current_frame_size_in_dip_;
-
-  // This lock is for waiting for a front surface to become available to draw.
-  scoped_refptr<ui::CompositorLock> released_front_lock_;
-
   // Used to track the state of the window we're created from. Only used when
   // created fullscreen.
   scoped_ptr<aura::WindowTracker> host_tracker_;
 
-  enum CanLockCompositorState {
-    YES,
-    // We locked, so at some point we'll need to kick a frame.
-    YES_DID_LOCK,
-    // No. A lock timed out, we need to kick a new frame before locking again.
-    NO_PENDING_RENDERER_FRAME,
-    // No. We've got a frame, but it hasn't been committed.
-    NO_PENDING_COMMIT,
-  };
-  CanLockCompositorState can_lock_compositor_;
-
   // Used to track the last cursor visibility update that was sent to the
   // renderer via NotifyRendererOfCursorVisibilityState().
   enum CursorVisibilityState {
@@ -696,22 +546,11 @@
   PluginWindowMoves plugin_window_moves_;
 #endif
 
-  base::TimeTicks last_draw_ended_;
-
-  // Subscriber that listens to frame presentation events.
-  scoped_ptr<RenderWidgetHostViewFrameSubscriber> frame_subscriber_;
-  std::vector<scoped_refptr<OwnedMailbox> > idle_frame_subscriber_textures_;
-  std::set<OwnedMailbox*> active_frame_subscriber_textures_;
-
-  // YUV readback pipeline.
-  scoped_ptr<content::ReadbackYUVInterface>
-      yuv_readback_pipeline_;
-
   TouchEditingClient* touch_editing_client_;
 
   gfx::Insets insets_;
 
-  scoped_ptr<DelegatedFrameEvictor> delegated_frame_evictor_;
+  std::vector<ui::LatencyInfo> software_latency_info_;
 
   scoped_ptr<aura::client::ScopedTooltipDisabler> tooltip_disabler_;
 
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index 591c725..581ebc8 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -21,8 +21,8 @@
 #include "content/common/host_shared_bitmap_manager.h"
 #include "content/common/input_messages.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/browser/render_widget_host_view.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/test/mock_render_process_host.h"
 #include "content/public/test/test_browser_context.h"
 #include "ipc/ipc_test_sink.h"
@@ -155,18 +155,24 @@
 
   virtual ~FakeRenderWidgetHostViewAura() {}
 
-  virtual bool ShouldCreateResizeLock() OVERRIDE {
-    gfx::Size desired_size = window()->bounds().size();
-    return desired_size != current_frame_size_in_dip();
-  }
-
-  virtual scoped_ptr<ResizeLock> CreateResizeLock(bool defer_compositor_lock)
-      OVERRIDE {
+  virtual scoped_ptr<ResizeLock> CreateResizeLock(
+      bool defer_compositor_lock) OVERRIDE {
     gfx::Size desired_size = window()->bounds().size();
     return scoped_ptr<ResizeLock>(
         new FakeResizeLock(desired_size, defer_compositor_lock));
   }
 
+  void RunOnCompositingDidCommit() {
+    GetDelegatedFrameHost()->OnCompositingDidCommitForTesting(
+        window()->GetHost()->compositor());
+  }
+
+  virtual bool ShouldCreateResizeLock() OVERRIDE {
+    gfx::Size desired_size = window()->bounds().size();
+    return desired_size !=
+           GetDelegatedFrameHost()->CurrentFrameSizeInDIPForTesting();
+  }
+
   virtual void RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request)
       OVERRIDE {
     last_copy_request_ = request.Pass();
@@ -181,8 +187,8 @@
     }
   }
 
-  void RunOnCompositingDidCommit() {
-    OnCompositingDidCommit(window()->GetHost()->compositor());
+  cc::DelegatedFrameProvider* frame_provider() const {
+    return GetDelegatedFrameHost()->FrameProviderForTesting();
   }
 
   // A lock that doesn't actually do anything to the compositor, and does not
@@ -217,8 +223,7 @@
 
     parent_host_ = new RenderWidgetHostImpl(
         &delegate_, process_host_, MSG_ROUTING_NONE, false);
-    parent_view_ = static_cast<RenderWidgetHostViewAura*>(
-        RenderWidgetHostView::CreateViewForWidget(parent_host_));
+    parent_view_ = new RenderWidgetHostViewAura(parent_host_);
     parent_view_->InitAsChild(NULL);
     aura::client::ParentWindowWithContext(parent_view_->GetNativeView(),
                                           aura_test_helper_->root_window(),
@@ -984,7 +989,7 @@
   // Lock the compositor. Now we should drop frames.
   view_rect = gfx::Rect(150, 150);
   view_->SetSize(view_rect.size());
-  view_->MaybeCreateResizeLock();
+  view_->GetDelegatedFrameHost()->MaybeCreateResizeLock();
 
   // This frame is dropped.
   gfx::Rect dropped_damage_rect_1(10, 20, 30, 40);
@@ -1103,37 +1108,37 @@
     views[i]->WasShown();
     views[i]->OnSwapCompositorFrame(
         1, MakeDelegatedFrame(1.f, frame_size, view_rect));
-    EXPECT_TRUE(views[i]->frame_provider_);
+    EXPECT_TRUE(views[i]->frame_provider());
     views[i]->WasHidden();
   }
 
   // There should be max_renderer_frames with a frame in it, and one without it.
   // Since the logic is LRU eviction, the first one should be without.
-  EXPECT_FALSE(views[0]->frame_provider_);
+  EXPECT_FALSE(views[0]->frame_provider());
   for (size_t i = 1; i < renderer_count; ++i)
-    EXPECT_TRUE(views[i]->frame_provider_);
+    EXPECT_TRUE(views[i]->frame_provider());
 
   // LRU renderer is [0], make it visible, it shouldn't evict anything yet.
   views[0]->WasShown();
-  EXPECT_FALSE(views[0]->frame_provider_);
-  EXPECT_TRUE(views[1]->frame_provider_);
+  EXPECT_FALSE(views[0]->frame_provider());
+  EXPECT_TRUE(views[1]->frame_provider());
 
   // Swap a frame on it, it should evict the next LRU [1].
   views[0]->OnSwapCompositorFrame(
       1, MakeDelegatedFrame(1.f, frame_size, view_rect));
-  EXPECT_TRUE(views[0]->frame_provider_);
-  EXPECT_FALSE(views[1]->frame_provider_);
+  EXPECT_TRUE(views[0]->frame_provider());
+  EXPECT_FALSE(views[1]->frame_provider());
   views[0]->WasHidden();
 
   // LRU renderer is [1], still hidden. Swap a frame on it, it should evict
   // the next LRU [2].
   views[1]->OnSwapCompositorFrame(
       1, MakeDelegatedFrame(1.f, frame_size, view_rect));
-  EXPECT_TRUE(views[0]->frame_provider_);
-  EXPECT_TRUE(views[1]->frame_provider_);
-  EXPECT_FALSE(views[2]->frame_provider_);
+  EXPECT_TRUE(views[0]->frame_provider());
+  EXPECT_TRUE(views[1]->frame_provider());
+  EXPECT_FALSE(views[2]->frame_provider());
   for (size_t i = 3; i < renderer_count; ++i)
-    EXPECT_TRUE(views[i]->frame_provider_);
+    EXPECT_TRUE(views[i]->frame_provider());
 
   // Make all renderers but [0] visible and swap a frame on them, keep [0]
   // hidden, it becomes the LRU.
@@ -1141,14 +1146,14 @@
     views[i]->WasShown();
     views[i]->OnSwapCompositorFrame(
         1, MakeDelegatedFrame(1.f, frame_size, view_rect));
-    EXPECT_TRUE(views[i]->frame_provider_);
+    EXPECT_TRUE(views[i]->frame_provider());
   }
-  EXPECT_FALSE(views[0]->frame_provider_);
+  EXPECT_FALSE(views[0]->frame_provider());
 
   // Swap a frame on [0], it should be evicted immediately.
   views[0]->OnSwapCompositorFrame(
       1, MakeDelegatedFrame(1.f, frame_size, view_rect));
-  EXPECT_FALSE(views[0]->frame_provider_);
+  EXPECT_FALSE(views[0]->frame_provider());
 
   // Make [0] visible, and swap a frame on it. Nothing should be evicted
   // although we're above the limit.
@@ -1156,11 +1161,11 @@
   views[0]->OnSwapCompositorFrame(
       1, MakeDelegatedFrame(1.f, frame_size, view_rect));
   for (size_t i = 0; i < renderer_count; ++i)
-    EXPECT_TRUE(views[i]->frame_provider_);
+    EXPECT_TRUE(views[i]->frame_provider());
 
   // Make [0] hidden, it should evict its frame.
   views[0]->WasHidden();
-  EXPECT_FALSE(views[0]->frame_provider_);
+  EXPECT_FALSE(views[0]->frame_provider());
 
   for (size_t i = 0; i < renderer_count - 1; ++i)
     views[i]->WasHidden();
@@ -1182,9 +1187,9 @@
   views[renderer_count - 1]->WasHidden();
   for (size_t i = 0; i < renderer_count; ++i) {
     if (i + 2 < renderer_count)
-      EXPECT_FALSE(views[i]->frame_provider_);
+      EXPECT_FALSE(views[i]->frame_provider());
     else
-      EXPECT_TRUE(views[i]->frame_provider_);
+      EXPECT_TRUE(views[i]->frame_provider());
   }
   HostSharedBitmapManager::current()->ProcessRemoved(
       base::GetCurrentProcessHandle());
@@ -1233,25 +1238,25 @@
     views[i]->WasShown();
     views[i]->OnSwapCompositorFrame(
         1, MakeDelegatedFrame(1.f, frame_size, view_rect));
-    EXPECT_TRUE(views[i]->frame_provider_);
+    EXPECT_TRUE(views[i]->frame_provider());
   }
 
   // If we hide [0], then [0] should be evicted.
   views[0]->WasHidden();
-  EXPECT_FALSE(views[0]->frame_provider_);
+  EXPECT_FALSE(views[0]->frame_provider());
 
   // If we lock [0] before hiding it, then [0] should not be evicted.
   views[0]->WasShown();
   views[0]->OnSwapCompositorFrame(
         1, MakeDelegatedFrame(1.f, frame_size, view_rect));
-  EXPECT_TRUE(views[0]->frame_provider_);
-  views[0]->LockResources();
+  EXPECT_TRUE(views[0]->frame_provider());
+  views[0]->GetDelegatedFrameHost()->LockResources();
   views[0]->WasHidden();
-  EXPECT_TRUE(views[0]->frame_provider_);
+  EXPECT_TRUE(views[0]->frame_provider());
 
   // If we unlock [0] now, then [0] should be evicted.
-  views[0]->UnlockResources();
-  EXPECT_FALSE(views[0]->frame_provider_);
+  views[0]->GetDelegatedFrameHost()->UnlockResources();
+  EXPECT_FALSE(views[0]->frame_provider());
 
   for (size_t i = 0; i < renderer_count; ++i) {
     views[i]->Destroy();
@@ -1277,7 +1282,7 @@
 
   // Save the frame provider.
   scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
-      view_->frame_provider_;
+      view_->frame_provider();
 
   // This frame will have the same number of physical pixels, but has a new
   // scale on it.
@@ -1287,7 +1292,7 @@
   // When we get a new frame with the same frame size in physical pixels, but a
   // different scale, we should generate a new frame provider, as the final
   // result will need to be scaled differently to the screen.
-  EXPECT_NE(frame_provider.get(), view_->frame_provider_.get());
+  EXPECT_NE(frame_provider.get(), view_->frame_provider());
 }
 
 class RenderWidgetHostViewAuraCopyRequestTest
@@ -1343,7 +1348,9 @@
   request = view_->last_copy_request_.Pass();
 
   // There should be one subscriber texture in flight.
-  EXPECT_EQ(1u, view_->active_frame_subscriber_textures_.size());
+  EXPECT_EQ(1u,
+            view_->GetDelegatedFrameHost()->
+                active_frame_subscriber_textures_.size());
 
   // Send back the mailbox included in the request. There's no release callback
   // since the mailbox came from the RWHVA originally.
@@ -1355,7 +1362,9 @@
   run_loop.Run();
 
   // The callback should succeed.
-  EXPECT_EQ(0u, view_->active_frame_subscriber_textures_.size());
+  EXPECT_EQ(0u,
+            view_->GetDelegatedFrameHost()->
+                active_frame_subscriber_textures_.size());
   EXPECT_EQ(1, callback_count_);
   EXPECT_TRUE(result_);
 
@@ -1366,7 +1375,9 @@
   request = view_->last_copy_request_.Pass();
 
   // There should be one subscriber texture in flight again.
-  EXPECT_EQ(1u, view_->active_frame_subscriber_textures_.size());
+  EXPECT_EQ(1u,
+            view_->GetDelegatedFrameHost()->
+                active_frame_subscriber_textures_.size());
 
   // Destroy the RenderWidgetHostViewAura and ImageTransportFactory.
   TearDownEnvironment();
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index 8c37e81..c7eafc2 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -11,7 +11,7 @@
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/common/content_switches_internal.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
 #include "ui/gfx/display.h"
 #include "ui/gfx/screen.h"
@@ -36,18 +36,6 @@
 
 namespace content {
 
-// static
-RenderWidgetHostViewPort* RenderWidgetHostViewPort::FromRWHV(
-    RenderWidgetHostView* rwhv) {
-  return static_cast<RenderWidgetHostViewPort*>(rwhv);
-}
-
-// static
-RenderWidgetHostViewPort* RenderWidgetHostViewPort::CreateViewForWidget(
-    RenderWidgetHost* widget) {
-  return FromRWHV(RenderWidgetHostView::CreateViewForWidget(widget));
-}
-
 #if defined(OS_WIN)
 
 namespace {
@@ -384,6 +372,7 @@
       selection_text_offset_(0),
       selection_range_(gfx::Range::InvalidRange()),
       current_device_scale_factor_(0),
+      current_display_rotation_(gfx::Display::ROTATE_0),
       pinch_zoom_enabled_(content::IsPinchToZoomEnabled()),
       renderer_frame_number_(0) {
 }
@@ -425,6 +414,11 @@
   selection_range_.set_end(range.end());
 }
 
+ui::TextInputClient* RenderWidgetHostViewBase::GetTextInputClient() {
+  NOTREACHED();
+  return NULL;
+}
+
 bool RenderWidgetHostViewBase::IsShowingContextMenu() const {
   return showing_context_menu_;
 }
@@ -525,18 +519,17 @@
   gfx::Display display =
       gfx::Screen::GetScreenFor(view)->GetDisplayNearestWindow(view);
   if (current_display_area_ == display.work_area() &&
-      current_device_scale_factor_ == display.device_scale_factor()) {
+      current_device_scale_factor_ == display.device_scale_factor() &&
+      current_display_rotation_ == display.rotation()) {
     return false;
   }
+
   current_display_area_ = display.work_area();
   current_device_scale_factor_ = display.device_scale_factor();
+  current_display_rotation_ = display.rotation();
   return true;
 }
 
-void RenderWidgetHostViewBase::ProcessAckedTouchEvent(
-    const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
-}
-
 scoped_ptr<SyntheticGestureTarget>
 RenderWidgetHostViewBase::CreateSyntheticGestureTarget() {
   RenderWidgetHostImpl* host =
@@ -545,9 +538,6 @@
       new SyntheticGestureTargetBase(host));
 }
 
-void RenderWidgetHostViewBase::FocusedNodeChanged(bool is_editable_node) {
-}
-
 // Platform implementation should override this method to allow frame
 // subscription. Frame subscriber is set to RenderProcessHost, which is
 // platform independent. It should be set to the specific presenter on each
@@ -592,14 +582,6 @@
   ++renderer_frame_number_;
 }
 
-void RenderWidgetHostViewBase::LockCompositingSurface() {
-  NOTIMPLEMENTED();
-}
-
-void RenderWidgetHostViewBase::UnlockCompositingSurface() {
-  NOTIMPLEMENTED();
-}
-
 void RenderWidgetHostViewBase::FlushInput() {
   RenderWidgetHostImpl* impl = NULL;
   if (GetRenderWidgetHost())
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index 59d6f00..42f021f 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -14,87 +14,94 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "base/callback_forward.h"
+#include "base/process/kill.h"
 #include "base/timer/timer.h"
+#include "cc/output/compositor_frame.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/common/content_export.h"
-#include "content/port/browser/render_widget_host_view_port.h"
+#include "content/common/input/input_event_ack_state.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "ipc/ipc_listener.h"
+#include "third_party/WebKit/public/web/WebPopupType.h"
+#include "third_party/WebKit/public/web/WebTextDirection.h"
+#include "ui/base/ime/text_input_mode.h"
+#include "ui/base/ime/text_input_type.h"
+#include "ui/gfx/display.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/range/range.h"
 #include "ui/gfx/rect.h"
+#include "ui/surface/transport_dib.h"
+
+class SkBitmap;
+
+struct AccessibilityHostMsg_EventParams;
+struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params;
+struct GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params;
+struct ViewHostMsg_TextInputState_Params;
+struct ViewHostMsg_SelectionBounds_Params;
+
+namespace media {
+class VideoFrame;
+}
+
+namespace blink {
+struct WebScreenInfo;
+}
 
 namespace content {
+class BrowserAccessibilityManager;
+class SyntheticGesture;
+class SyntheticGestureTarget;
+class WebCursor;
+struct WebPluginGeometry;
+struct NativeWebKeyboardEvent;
 
-class RenderWidgetHostImpl;
-
-// Basic implementation shared by concrete RenderWidgetHostView
-// subclasses.
-//
-// Note that nothing should use this class, except concrete subclasses
-// that are deriving from it, and code that is written specifically to
-// use one of these concrete subclasses (i.e. platform-specific code).
-//
-// To enable embedders that add ports, everything else in content/
-// should use the RenderWidgetHostViewPort interface.
-//
-// RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
-class CONTENT_EXPORT RenderWidgetHostViewBase
-    : public RenderWidgetHostViewPort {
+// Basic implementation shared by concrete RenderWidgetHostView subclasses.
+class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
+                                                public IPC::Listener {
  public:
   virtual ~RenderWidgetHostViewBase();
 
-  // RenderWidgetHostViewPort implementation.
-  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
-  virtual void SelectionChanged(const base::string16& text,
-                                size_t offset,
-                                const gfx::Range& range) OVERRIDE;
+  // RenderWidgetHostView implementation.
   virtual void SetBackground(const SkBitmap& background) OVERRIDE;
   virtual const SkBitmap& GetBackground() OVERRIDE;
-  virtual gfx::Size GetPhysicalBackingSize() const OVERRIDE;
-  virtual float GetOverdrawBottomHeight() const OVERRIDE;
+  virtual ui::TextInputClient* GetTextInputClient() OVERRIDE;
   virtual bool IsShowingContextMenu() const OVERRIDE;
   virtual void SetShowingContextMenu(bool showing_menu) OVERRIDE;
   virtual base::string16 GetSelectedText() const OVERRIDE;
   virtual bool IsMouseLocked() OVERRIDE;
-  virtual void UnhandledWheelEvent(
-      const blink::WebMouseWheelEvent& event) OVERRIDE;
-  virtual InputEventAckState FilterInputEvent(
-      const blink::WebInputEvent& input_event) OVERRIDE;
-  virtual void OnSetNeedsFlushInput() OVERRIDE;
-  virtual void OnDidFlushInput() OVERRIDE;
-  virtual void GestureEventAck(const blink::WebGestureEvent& event,
-                               InputEventAckState ack_result) OVERRIDE;
-  virtual void SetPopupType(blink::WebPopupType popup_type) OVERRIDE;
-  virtual blink::WebPopupType GetPopupType() OVERRIDE;
-  virtual BrowserAccessibilityManager*
-      GetBrowserAccessibilityManager() const OVERRIDE;
-  virtual void SetBrowserAccessibilityManager(
-      BrowserAccessibilityManager* manager) OVERRIDE;
-  virtual void CreateBrowserAccessibilityManagerIfNeeded() OVERRIDE;
-  virtual void OnAccessibilitySetFocus(int acc_obj_id) OVERRIDE;
-  virtual void AccessibilityShowMenu(int acc_obj_id) OVERRIDE;
-  virtual gfx::Point AccessibilityOriginInScreen(const gfx::Rect& bounds)
-      OVERRIDE;
-  virtual void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
-                                      InputEventAckState ack_result) OVERRIDE;
-  virtual scoped_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget()
-      OVERRIDE;
-  virtual void FocusedNodeChanged(bool is_editable_node) OVERRIDE;
-  virtual bool CanSubscribeFrame() const OVERRIDE;
+  virtual gfx::Size GetVisibleViewportSize() const OVERRIDE;
+  virtual void SetInsets(const gfx::Insets& insets) OVERRIDE;
   virtual void BeginFrameSubscription(
       scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) OVERRIDE;
   virtual void EndFrameSubscription() OVERRIDE;
-  virtual void OnSwapCompositorFrame(
-      uint32 output_surface_id,
-      scoped_ptr<cc::CompositorFrame> frame) OVERRIDE {}
-  virtual void DidStopFlinging() OVERRIDE {}
-  virtual uint32 RendererFrameNumber() OVERRIDE;
-  virtual void DidReceiveRendererFrame() OVERRIDE;
-  virtual void LockCompositingSurface() OVERRIDE;
-  virtual void UnlockCompositingSurface() OVERRIDE;
 
-  virtual SkBitmap::Config PreferredReadbackFormat() OVERRIDE;
+  // IPC::Listener implementation:
+  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
 
-  virtual gfx::Size GetVisibleViewportSize() const OVERRIDE;
-  virtual void SetInsets(const gfx::Insets& insets) OVERRIDE;
+  // Called when a mousewheel event was not processed by the renderer.
+  // virtual for testing.
+  virtual void UnhandledWheelEvent(const blink::WebMouseWheelEvent& event);
+
+  // Called by the host when the input flush has completed.
+  void OnDidFlushInput();
+
+  void SetPopupType(blink::WebPopupType popup_type);
+
+  blink::WebPopupType GetPopupType();
+
+  // Get the BrowserAccessibilityManager if it exists, may return NULL.
+  BrowserAccessibilityManager* GetBrowserAccessibilityManager() const;
+
+  void SetBrowserAccessibilityManager(BrowserAccessibilityManager* manager);
+
+  // Return a value that is incremented each time the renderer swaps a new frame
+  // to the view.
+  uint32 RendererFrameNumber();
+
+  // Called each time the RenderWidgetHost receives a new frame for display from
+  // the renderer.
+  void DidReceiveRendererFrame();
 
   // Notification that a resize or move session ended on the native widget.
   void UpdateScreenInfo(gfx::NativeView view);
@@ -103,7 +110,247 @@
   // changed since the last time.
   bool HasDisplayPropertyChanged(gfx::NativeView view);
 
+  //----------------------------------------------------------------------------
+  // The following methods can be overridden by derived classes.
+
+  // Notifies the View that the renderer text selection has changed.
+  virtual void SelectionChanged(const base::string16& text,
+                                size_t offset,
+                                const gfx::Range& range);
+
+  // The size of the view's backing surface in non-DPI-adjusted pixels.
+  virtual gfx::Size GetPhysicalBackingSize() const;
+
+  // The height of the physical backing surface that is overdrawn opaquely in
+  // the browser, for example by an on-screen-keyboard (in DPI-adjusted pixels).
+  virtual float GetOverdrawBottomHeight() const;
+
+  // Called prior to forwarding input event messages to the renderer, giving
+  // the view a chance to perform in-process event filtering or processing.
+  // Return values of |NOT_CONSUMED| or |UNKNOWN| will result in |input_event|
+  // being forwarded.
+  virtual InputEventAckState FilterInputEvent(
+      const blink::WebInputEvent& input_event);
+
+  // Called by the host when it requires an input flush; the flush call should
+  // by synchronized with BeginFrame.
+  virtual void OnSetNeedsFlushInput();
+
+  virtual void GestureEventAck(const blink::WebGestureEvent& event,
+                               InputEventAckState ack_result);
+
+  // Create a platform specific SyntheticGestureTarget implementation that will
+  // be used to inject synthetic input events.
+  virtual scoped_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget();
+
+  // Return true if frame subscription is supported on this platform.
+  virtual bool CanSubscribeFrame() const;
+
+  // Create a BrowserAccessibilityManager for this view if it's possible to
+  // create one and if one doesn't exist already. Some ports may not create
+  // one depending on the current state.
+  virtual void CreateBrowserAccessibilityManagerIfNeeded();
+
+  virtual void OnAccessibilitySetFocus(int acc_obj_id);
+  virtual void AccessibilityShowMenu(int acc_obj_id);
+  virtual gfx::Point AccessibilityOriginInScreen(const gfx::Rect& bounds);
+
+  virtual SkBitmap::Config PreferredReadbackFormat();
+
+  // Informs that the focused DOM node has changed.
+  virtual void FocusedNodeChanged(bool is_editable_node) {}
+
+  virtual void OnSwapCompositorFrame(uint32 output_surface_id,
+                                     scoped_ptr<cc::CompositorFrame> frame) {}
+
+  // Because the associated remote WebKit instance can asynchronously
+  // prevent-default on a dispatched touch event, the touch events are queued in
+  // the GestureRecognizer until invocation of ProcessAckedTouchEvent releases
+  // it to be consumed (when |ack_result| is NOT_CONSUMED OR NO_CONSUMER_EXISTS)
+  // or ignored (when |ack_result| is CONSUMED).
+  virtual void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
+                                      InputEventAckState ack_result) {}
+
+  virtual void DidStopFlinging() {}
+
+  //----------------------------------------------------------------------------
+  // The following static methods are implemented by each platform.
+
+  static void GetDefaultScreenInfo(blink::WebScreenInfo* results);
+
+  //----------------------------------------------------------------------------
+  // The following pure virtual methods are implemented by derived classes.
+
+  // Perform all the initialization steps necessary for this object to represent
+  // a popup (such as a <select> dropdown), then shows the popup at |pos|.
+  virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
+                           const gfx::Rect& pos) = 0;
+
+  // Perform all the initialization steps necessary for this object to represent
+  // a full screen window.
+  // |reference_host_view| is the view associated with the creating page that
+  // helps to position the full screen widget on the correct monitor.
+  virtual void InitAsFullscreen(RenderWidgetHostView* reference_host_view) = 0;
+
+  // Notifies the View that it has become visible.
+  virtual void WasShown() = 0;
+
+  // Notifies the View that it has been hidden.
+  virtual void WasHidden() = 0;
+
+  // Moves all plugin windows as described in the given list.
+  // |scroll_offset| is the scroll offset of the render view.
+  virtual void MovePluginWindows(
+      const std::vector<WebPluginGeometry>& moves) = 0;
+
+  // Take focus from the associated View component.
+  virtual void Blur() = 0;
+
+  // Sets the cursor to the one associated with the specified cursor_type
+  virtual void UpdateCursor(const WebCursor& cursor) = 0;
+
+  // Indicates whether the page has finished loading.
+  virtual void SetIsLoading(bool is_loading) = 0;
+
+  // Updates the type of the input method attached to the view.
+  virtual void TextInputTypeChanged(ui::TextInputType type,
+                                    ui::TextInputMode mode,
+                                    bool can_compose_inline) = 0;
+
+  // Cancel the ongoing composition of the input method attached to the view.
+  virtual void ImeCancelComposition() = 0;
+
+  // Notifies the View that the renderer has ceased to exist.
+  virtual void RenderProcessGone(base::TerminationStatus status,
+                                 int error_code) = 0;
+
+  // Tells the View to destroy itself.
+  virtual void Destroy() = 0;
+
+  // Tells the View that the tooltip text for the current mouse position over
+  // the page has changed.
+  virtual void SetTooltipText(const base::string16& tooltip_text) = 0;
+
+  // Notifies the View that the renderer selection bounds has changed.
+  // |start_rect| and |end_rect| are the bounds end of the selection in the
+  // coordinate system of the render view. |start_direction| and |end_direction|
+  // indicates the direction at which the selection was made on touch devices.
+  virtual void SelectionBoundsChanged(
+      const ViewHostMsg_SelectionBounds_Params& params) = 0;
+
+  // Notifies the view that the scroll offset has changed.
+  virtual void ScrollOffsetChanged() = 0;
+
+  // Copies the contents of the compositing surface into the given
+  // (uninitialized) PlatformCanvas if any.
+  // The rectangle region specified with |src_subrect| is copied from the
+  // contents, scaled to |dst_size|, and written to |output|.
+  // |callback| is invoked with true on success, false otherwise. |output| can
+  // be initialized even on failure.
+  // A smaller region than |src_subrect| may be copied if the underlying surface
+  // is smaller than |src_subrect|.
+  // NOTE: |callback| is called asynchronously.
+  virtual void CopyFromCompositingSurface(
+      const gfx::Rect& src_subrect,
+      const gfx::Size& dst_size,
+      const base::Callback<void(bool, const SkBitmap&)>& callback,
+      const SkBitmap::Config config) = 0;
+
+  // Copies a given subset of the compositing surface's content into a YV12
+  // VideoFrame, and invokes a callback with a success/fail parameter. |target|
+  // must contain an allocated, YV12 video frame of the intended size. If the
+  // copy rectangle does not match |target|'s size, the copied content will be
+  // scaled and letterboxed with black borders. The copy will happen
+  // asynchronously. This operation will fail if there is no available
+  // compositing surface.
+  virtual void CopyFromCompositingSurfaceToVideoFrame(
+      const gfx::Rect& src_subrect,
+      const scoped_refptr<media::VideoFrame>& target,
+      const base::Callback<void(bool)>& callback) = 0;
+
+  // Returns true if CopyFromCompositingSurfaceToVideoFrame() is likely to
+  // succeed.
+  //
+  // TODO(nick): When VideoFrame copies are broadly implemented, this method
+  // should be renamed to HasCompositingSurface(), or unified with
+  // IsSurfaceAvailableForCopy() and HasAcceleratedSurface().
+  virtual bool CanCopyToVideoFrame() const = 0;
+
+  // Called when accelerated compositing state changes.
+  virtual void OnAcceleratedCompositingStateChange() = 0;
+  // Called when an accelerated compositing surface is initialized.
+  virtual void AcceleratedSurfaceInitialized(int host_id, int route_id) = 0;
+  // |params.window| and |params.surface_id| indicate which accelerated
+  // surface's buffers swapped. |params.renderer_id| and |params.route_id|
+  // are used to formulate a reply to the GPU process to prevent it from getting
+  // too far ahead. They may all be zero, in which case no flow control is
+  // enforced; this case is currently used for accelerated plugins.
+  virtual void AcceleratedSurfaceBuffersSwapped(
+      const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
+      int gpu_host_id) = 0;
+  // Similar to above, except |params.(x|y|width|height)| define the region
+  // of the surface that changed.
+  virtual void AcceleratedSurfacePostSubBuffer(
+      const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel,
+      int gpu_host_id) = 0;
+
+  // Release the accelerated surface temporarily. It will be recreated on the
+  // next swap buffers or post sub buffer.
+  virtual void AcceleratedSurfaceSuspend() = 0;
+
+  virtual void AcceleratedSurfaceRelease() = 0;
+
+  // Return true if the view has an accelerated surface that contains the last
+  // presented frame for the view. If |desired_size| is non-empty, true is
+  // returned only if the accelerated surface size matches.
+  virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) = 0;
+
+  virtual void GetScreenInfo(blink::WebScreenInfo* results) = 0;
+
+  // Gets the bounds of the window, in screen coordinates.
+  virtual gfx::Rect GetBoundsInRootWindow() = 0;
+
+  virtual gfx::GLSurfaceHandle GetCompositingSurface() = 0;
+
+  virtual void SetScrollOffsetPinning(
+      bool is_pinned_to_left, bool is_pinned_to_right) = 0;
+
+#if defined(OS_ANDROID)
+  virtual void ShowDisambiguationPopup(const gfx::Rect& target_rect,
+                                       const SkBitmap& zoomed_bitmap) = 0;
+
+  // Notifies the View that the renderer selection root bounds has changed.
+  virtual void SelectionRootBoundsChanged(const gfx::Rect& bounds) = 0;
+
+  // Instructs the view to not drop the surface even when the view is hidden.
+  virtual void LockCompositingSurface() = 0;
+  virtual void UnlockCompositingSurface() = 0;
+#endif
+
+#if defined(OS_MACOSX)
+  // Does any event handling necessary for plugin IME; should be called after
+  // the plugin has already had a chance to process the event. If plugin IME is
+  // not enabled, this is a no-op, so it is always safe to call.
+  // Returns true if the event was handled by IME.
+  virtual bool PostProcessEventForPluginIme(
+      const NativeWebKeyboardEvent& event) = 0;
+#endif
+
+#if defined(OS_MACOSX) || defined(USE_AURA)
+  // Updates the range of the marked text in an IME composition.
+  virtual void ImeCompositionRangeChanged(
+      const gfx::Range& range,
+      const std::vector<gfx::Rect>& character_bounds) = 0;
+#endif
+
 #if defined(OS_WIN)
+  virtual void SetParentNativeViewAccessible(
+      gfx::NativeViewAccessible accessible_parent) = 0;
+
+  // Returns an HWND that's given as the parent window for windowless Flash to
+  // workaround crbug.com/301548.
+  virtual gfx::NativeViewId GetParentForWindowlessPlugin() const = 0;
+
   // The callback that DetachPluginsHelper calls for each child window. Call
   // this directly if you want to do custom filtering on plugin windows first.
   static void DetachPluginWindowsCallback(HWND window);
@@ -160,6 +407,9 @@
   // The scale factor of the display the renderer is currently on.
   float current_device_scale_factor_;
 
+  // The orientation of the display the renderer is currently on.
+  gfx::Display::Rotation current_display_rotation_;
+
   // Whether pinch-to-zoom should be enabled and pinch events forwarded to the
   // renderer.
   bool pinch_zoom_enabled_;
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
index 4721e54c..3c2de99 100644
--- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -10,10 +10,10 @@
 #include "content/browser/gpu/gpu_data_manager_impl.h"
 #include "content/browser/renderer_host/dip_util.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
-#include "content/port/browser/render_widget_host_view_port.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/public/browser/gpu_data_manager.h"
 #include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_paths.h"
 #include "content/public/common/content_switches.h"
@@ -58,7 +58,7 @@
 // high-DPI fails.
 #define PASS_TEST_IF_SCALE_FACTOR_NOT_SUPPORTED(factor) \
   if (ui::GetScaleForScaleFactor( \
-          GetScaleFactorForView(GetRenderWidgetHostViewPort())) != factor) {  \
+          GetScaleFactorForView(GetRenderWidgetHostView())) != factor) {  \
     LOG(WARNING) << "Blindly passing this test: failed to set up "  \
                     "scale factor: " << factor;  \
     return false;  \
@@ -112,11 +112,9 @@
     return rwh;
   }
 
-  RenderWidgetHostViewPort* GetRenderWidgetHostViewPort() const {
-    RenderWidgetHostViewPort* const view =
-        RenderWidgetHostViewPort::FromRWHV(GetRenderViewHost()->GetView());
-    CHECK(view);
-    return view;
+  RenderWidgetHostViewBase* GetRenderWidgetHostView() const {
+    return static_cast<RenderWidgetHostViewBase*>(
+        GetRenderViewHost()->GetView());
   }
 
   // Callback when using CopyFromBackingStore() API.
@@ -188,7 +186,7 @@
  protected:
   // Waits until the source is available for copying.
   void WaitForCopySourceReady() {
-    while (!GetRenderWidgetHostViewPort()->IsSurfaceAvailableForCopy())
+    while (!GetRenderWidgetHostView()->IsSurfaceAvailableForCopy())
       GiveItSomeTime();
   }
 
@@ -318,7 +316,7 @@
                  run_loop.QuitClosure()),
       SkBitmap::kARGB_8888_Config);
   // Delete the surface before the callback is run.
-  GetRenderWidgetHostViewPort()->AcceleratedSurfaceRelease();
+  GetRenderWidgetHostView()->AcceleratedSurfaceRelease();
   run_loop.Run();
 
   EXPECT_EQ(1, callback_invoke_count());
@@ -339,7 +337,7 @@
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
                        MAYBE_CopyFromCompositingSurface_CallbackDespiteDelete) {
   SET_UP_SURFACE_OR_PASS_TEST(NULL);
-  RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
+  RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
   if (!view->CanCopyToVideoFrame()) {
     LOG(WARNING) <<
         ("Blindly passing this test: CopyFromCompositingSurfaceToVideoFrame() "
@@ -366,7 +364,7 @@
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
                        FrameSubscriberTest) {
   SET_UP_SURFACE_OR_PASS_TEST(NULL);
-  RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
+  RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
   if (!view->CanSubscribeFrame()) {
     LOG(WARNING) << ("Blindly passing this test: Frame subscription not "
                      "supported on this platform.");
@@ -391,7 +389,7 @@
 // Test that we can copy twice from an accelerated composited page.
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest, CopyTwice) {
   SET_UP_SURFACE_OR_PASS_TEST(NULL);
-  RenderWidgetHostViewPort* const view = GetRenderWidgetHostViewPort();
+  RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
   if (!view->CanCopyToVideoFrame()) {
     LOG(WARNING) << ("Blindly passing this test: "
                      "CopyFromCompositingSurfaceToVideoFrame() not supported "
@@ -593,7 +591,7 @@
     if (!ShouldContinueAfterTestURLLoad())
       return;
 
-    RenderWidgetHostViewPort* rwhvp = GetRenderWidgetHostViewPort();
+    RenderWidgetHostViewBase* rwhvp = GetRenderWidgetHostView();
     if (video_frame && !rwhvp->CanCopyToVideoFrame()) {
       // This should only happen on Mac when using the software compositor.
       // Otherwise, raise an error. This can be removed when Mac is moved to a
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h
index a7bc1bd..9626259 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -19,6 +19,7 @@
 #include "content/browser/renderer_host/display_link_mac.h"
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/renderer_host/software_frame_manager.h"
+#include "content/common/content_export.h"
 #include "content/common/cursors/webcursor.h"
 #include "content/common/edit_command.h"
 #import "content/public/browser/render_widget_host_view_mac_base.h"
@@ -211,10 +212,15 @@
 //     references to it must become NULL."
 //
 // RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
-class RenderWidgetHostViewMac : public RenderWidgetHostViewBase,
-                                public IPC::Sender,
-                                public SoftwareFrameManagerClient {
+class CONTENT_EXPORT RenderWidgetHostViewMac
+    : public RenderWidgetHostViewBase,
+      public IPC::Sender,
+      public SoftwareFrameManagerClient {
  public:
+  // The view will associate itself with the given widget. The native view must
+  // be hooked up immediately to the view hierarchy, or else when it is
+  // deleted it will delete this out from under the caller.
+  explicit RenderWidgetHostViewMac(RenderWidgetHost* widget);
   virtual ~RenderWidgetHostViewMac();
 
   RenderWidgetHostViewCocoa* cocoa_view() const { return cocoa_view_; }
@@ -253,7 +259,7 @@
   virtual void StopSpeaking() OVERRIDE;
   virtual void SetBackground(const SkBitmap& background) OVERRIDE;
 
-  // Implementation of RenderWidgetHostViewPort.
+  // Implementation of RenderWidgetHostViewBase.
   virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
                            const gfx::Rect& pos) OVERRIDE;
   virtual void InitAsFullscreen(
@@ -509,7 +515,6 @@
   bool HasPendingSwapAck() const { return pending_swap_ack_; }
 
  private:
-  friend class RenderWidgetHostView;
   friend class RenderWidgetHostViewMacTest;
 
   struct PendingSwapAck {
@@ -524,11 +529,6 @@
   scoped_ptr<PendingSwapAck> pending_swap_ack_;
   void AddPendingSwapAck(int32 route_id, int gpu_host_id, int32 renderer_id);
 
-  // The view will associate itself with the given widget. The native view must
-  // be hooked up immediately to the view hierarchy, or else when it is
-  // deleted it will delete this out from under the caller.
-  explicit RenderWidgetHostViewMac(RenderWidgetHost* widget);
-
   // Returns whether this render view is a popup (autocomplete window).
   bool IsPopup() const;
 
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index 8e1d695..2e89069 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -43,11 +43,11 @@
 #include "content/common/input_messages.h"
 #include "content/common/view_messages.h"
 #include "content/common/webplugin_geometry.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
 #import "content/public/browser/render_widget_host_view_mac_delegate.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
@@ -393,16 +393,10 @@
 namespace content {
 
 ///////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostView, public:
+// RenderWidgetHostViewBase, public:
 
 // static
-RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
-    RenderWidgetHost* widget) {
-  return new RenderWidgetHostViewMac(widget);
-}
-
-// static
-void RenderWidgetHostViewPort::GetDefaultScreenInfo(
+void RenderWidgetHostViewBase::GetDefaultScreenInfo(
     blink::WebScreenInfo* results) {
   *results = GetWebScreenInfo(NULL);
 }
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h b/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h
index 79ccc4d..a14d312 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h
+++ b/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.h
@@ -12,7 +12,6 @@
 
 class RenderWidgetHostView;
 class RenderWidgetHostViewMac;
-class RenderWidgetHostViewPort;
 
 // A helper class to bring up definition of word for a RWHV.
 //
@@ -21,8 +20,7 @@
 // system settings.
 class RenderWidgetHostViewMacDictionaryHelper {
  public:
-  explicit RenderWidgetHostViewMacDictionaryHelper(
-      RenderWidgetHostViewPort* view);
+  explicit RenderWidgetHostViewMacDictionaryHelper(RenderWidgetHostView* view);
 
   // Overrides the view to use to bring up dictionary panel.
   // This |target_view| can be different from |view_|, |view_| is used to get
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.mm b/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.mm
index 8402a43..bcae7ec 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_dictionary_helper.mm
@@ -9,7 +9,7 @@
 namespace content {
 
 RenderWidgetHostViewMacDictionaryHelper::
-    RenderWidgetHostViewMacDictionaryHelper(RenderWidgetHostViewPort* view)
+    RenderWidgetHostViewMacDictionaryHelper(RenderWidgetHostView* view)
     : view_(static_cast<RenderWidgetHostViewMac*>(view)),
       target_view_(static_cast<RenderWidgetHostViewMac*>(view)) {
 }
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
index 3af547f..94f499e 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
@@ -118,8 +118,8 @@
   base::mac::ScopedNSAutoreleasePool pool;
 
   // Owned by its |cocoa_view()|, i.e. |rwhv_cocoa|.
-  RenderWidgetHostViewMac* rwhv_mac = static_cast<RenderWidgetHostViewMac*>(
-      RenderWidgetHostView::CreateViewForWidget(render_widget));
+  RenderWidgetHostViewMac* rwhv_mac = new RenderWidgetHostViewMac(
+      render_widget);
   base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa(
       [rwhv_mac->cocoa_view() retain]);
 
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index dfdc127..c875c22 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -189,8 +189,7 @@
     old_rwhv_ = rvh()->GetView();
 
     // Owned by its |cocoa_view()|, i.e. |rwhv_cocoa_|.
-    rwhv_mac_ = static_cast<RenderWidgetHostViewMac*>(
-        RenderWidgetHostView::CreateViewForWidget(rvh()));
+    rwhv_mac_ = new RenderWidgetHostViewMac(rvh());
     rwhv_cocoa_.reset([rwhv_mac_->cocoa_view() retain]);
   }
   virtual void TearDown() {
@@ -201,7 +200,7 @@
     pool_.Recycle();
 
     // See comment in SetUp().
-    test_rvh()->SetView(old_rwhv_);
+    test_rvh()->SetView(static_cast<RenderWidgetHostViewBase*>(old_rwhv_));
 
     RenderViewHostImplTestHarness::TearDown();
   }
@@ -277,8 +276,7 @@
   // Owned by its |cocoa_view()|.
   RenderWidgetHostImpl* rwh = new RenderWidgetHostImpl(
       &delegate, process_host, MSG_ROUTING_NONE, false);
-  RenderWidgetHostViewMac* view = static_cast<RenderWidgetHostViewMac*>(
-      RenderWidgetHostView::CreateViewForWidget(rwh));
+  RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh);
 
   view->InitAsFullscreen(rwhv_mac_);
 
@@ -311,8 +309,7 @@
   // Owned by its |cocoa_view()|.
   RenderWidgetHostImpl* rwh = new RenderWidgetHostImpl(
       &delegate, process_host, MSG_ROUTING_NONE, false);
-  RenderWidgetHostViewMac* view = static_cast<RenderWidgetHostViewMac*>(
-      RenderWidgetHostView::CreateViewForWidget(rwh));
+  RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh);
 
   view->InitAsFullscreen(rwhv_mac_);
 
@@ -666,8 +663,7 @@
   // Owned by its |cocoa_view()|.
   MockRenderWidgetHostImpl* rwh = new MockRenderWidgetHostImpl(
       &delegate, process_host, MSG_ROUTING_NONE);
-  RenderWidgetHostViewMac* view = static_cast<RenderWidgetHostViewMac*>(
-      RenderWidgetHostView::CreateViewForWidget(rwh));
+  RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh);
 
   base::scoped_nsobject<CocoaTestHelperWindow> window(
       [[CocoaTestHelperWindow alloc] init]);
@@ -713,8 +709,7 @@
   MockRenderWidgetHostDelegate delegate;
   MockRenderWidgetHostImpl* host = new MockRenderWidgetHostImpl(
       &delegate, process_host, MSG_ROUTING_NONE);
-  RenderWidgetHostViewMac* view = static_cast<RenderWidgetHostViewMac*>(
-      RenderWidgetHostView::CreateViewForWidget(host));
+  RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host);
 
   // Send an initial wheel event with NSEventPhaseBegan to the view.
   NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 0);
@@ -752,8 +747,7 @@
   MockRenderWidgetHostDelegate delegate;
   MockRenderWidgetHostImpl* host = new MockRenderWidgetHostImpl(
       &delegate, process_host, MSG_ROUTING_NONE);
-  RenderWidgetHostViewMac* view = static_cast<RenderWidgetHostViewMac*>(
-      RenderWidgetHostView::CreateViewForWidget(host));
+  RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host);
 
   // Add a delegate to the view.
   base::scoped_nsobject<MockRenderWidgetHostViewMacDelegate> view_delegate(
diff --git a/content/browser/renderer_host/ui_events_helper.h b/content/browser/renderer_host/ui_events_helper.h
index a7f2eaa..883ba48 100644
--- a/content/browser/renderer_host/ui_events_helper.h
+++ b/content/browser/renderer_host/ui_events_helper.h
@@ -6,8 +6,8 @@
 #define CONTENT_BROWSER_RENDERER_HOST_UI_EVENTS_HELPER_H_
 
 #include "base/memory/scoped_vector.h"
+#include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/common/content_export.h"
-#include "content/port/browser/event_with_latency_info.h"
 
 namespace blink {
 class WebGestureEvent;
diff --git a/content/browser/service_worker/database_proto.target.darwin-arm.mk b/content/browser/service_worker/database_proto.target.darwin-arm.mk
index 24604b3..c3e221e 100644
--- a/content/browser/service_worker/database_proto.target.darwin-arm.mk
+++ b/content/browser/service_worker/database_proto.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_service_worker_service_worker_proto_gyp_database_proto_target_genproto":
 # "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['service_worker_database.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -63,7 +64,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -156,7 +156,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/browser/service_worker/database_proto.target.darwin-arm64.mk b/content/browser/service_worker/database_proto.target.darwin-arm64.mk
index b4377f3..14d103c 100644
--- a/content/browser/service_worker/database_proto.target.darwin-arm64.mk
+++ b/content/browser/service_worker/database_proto.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_service_worker_service_worker_proto_gyp_database_proto_target_genproto":
 # "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['service_worker_database.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/service_worker/database_proto.target.darwin-mips.mk b/content/browser/service_worker/database_proto.target.darwin-mips.mk
index 0d606ab..f7ec6bb 100644
--- a/content/browser/service_worker/database_proto.target.darwin-mips.mk
+++ b/content/browser/service_worker/database_proto.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_service_worker_service_worker_proto_gyp_database_proto_target_genproto":
 # "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['service_worker_database.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/service_worker/database_proto.target.darwin-x86.mk b/content/browser/service_worker/database_proto.target.darwin-x86.mk
index edb4a07..359a96e 100644
--- a/content/browser/service_worker/database_proto.target.darwin-x86.mk
+++ b/content/browser/service_worker/database_proto.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_service_worker_service_worker_proto_gyp_database_proto_target_genproto":
 # "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['service_worker_database.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,7 +66,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +158,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/browser/service_worker/database_proto.target.darwin-x86_64.mk b/content/browser/service_worker/database_proto.target.darwin-x86_64.mk
index b2c335b..238a569 100644
--- a/content/browser/service_worker/database_proto.target.darwin-x86_64.mk
+++ b/content/browser/service_worker/database_proto.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_service_worker_service_worker_proto_gyp_database_proto_target_genproto":
 # "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['service_worker_database.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,7 +66,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +158,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/browser/service_worker/database_proto.target.linux-arm.mk b/content/browser/service_worker/database_proto.target.linux-arm.mk
index 24604b3..c3e221e 100644
--- a/content/browser/service_worker/database_proto.target.linux-arm.mk
+++ b/content/browser/service_worker/database_proto.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_service_worker_service_worker_proto_gyp_database_proto_target_genproto":
 # "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['service_worker_database.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -63,7 +64,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -156,7 +156,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/browser/service_worker/database_proto.target.linux-arm64.mk b/content/browser/service_worker/database_proto.target.linux-arm64.mk
index b4377f3..14d103c 100644
--- a/content/browser/service_worker/database_proto.target.linux-arm64.mk
+++ b/content/browser/service_worker/database_proto.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_service_worker_service_worker_proto_gyp_database_proto_target_genproto":
 # "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['service_worker_database.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/service_worker/database_proto.target.linux-mips.mk b/content/browser/service_worker/database_proto.target.linux-mips.mk
index 0d606ab..f7ec6bb 100644
--- a/content/browser/service_worker/database_proto.target.linux-mips.mk
+++ b/content/browser/service_worker/database_proto.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_service_worker_service_worker_proto_gyp_database_proto_target_genproto":
 # "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['service_worker_database.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/service_worker/database_proto.target.linux-x86.mk b/content/browser/service_worker/database_proto.target.linux-x86.mk
index edb4a07..359a96e 100644
--- a/content/browser/service_worker/database_proto.target.linux-x86.mk
+++ b/content/browser/service_worker/database_proto.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_service_worker_service_worker_proto_gyp_database_proto_target_genproto":
 # "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['service_worker_database.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,7 +66,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +158,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/browser/service_worker/database_proto.target.linux-x86_64.mk b/content/browser/service_worker/database_proto.target.linux-x86_64.mk
index b2c335b..238a569 100644
--- a/content/browser/service_worker/database_proto.target.linux-x86_64.mk
+++ b/content/browser/service_worker/database_proto.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_service_worker_service_worker_proto_gyp_database_proto_target_genproto":
 # "{'inputs': ['../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['service_worker_database.proto'], 'action': ['python', '../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/service_worker', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/service_worker/service_worker_database_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,7 +66,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +158,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index b56df25..24d2a95 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -99,6 +99,13 @@
   }
 }
 
+void EmbeddedWorkerInstance::OnScriptLoaded() {
+  // TODO(horo): Implement this.
+}
+
+void EmbeddedWorkerInstance::OnScriptLoadFailed() {
+}
+
 void EmbeddedWorkerInstance::OnStarted(int thread_id) {
   // Stop is requested before OnStarted is sent back from the worker.
   if (status_ == STOPPING)
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h
index a56a594..f9d382c 100644
--- a/content/browser/service_worker/embedded_worker_instance.h
+++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -121,7 +121,15 @@
                        int worker_devtools_agent_route_id);
 
   // Called back from Registry when the worker instance has ack'ed that
-  // its WorkerGlobalScope is actually started on |thread_id| in the
+  // it finished loading the script.
+  void OnScriptLoaded();
+
+  // Called back from Registry when the worker instance has ack'ed that
+  // it failed to load the script.
+  void OnScriptLoadFailed();
+
+  // Called back from Registry when the worker instance has ack'ed that
+  // its WorkerGlobalScope is actually started and parsed on |thread_id| in the
   // child process.
   // This will change the internal status from STARTING to RUNNING.
   void OnStarted(int thread_id);
diff --git a/content/browser/service_worker/embedded_worker_registry.cc b/content/browser/service_worker/embedded_worker_registry.cc
index 82b9bb0..a859268 100644
--- a/content/browser/service_worker/embedded_worker_registry.cc
+++ b/content/browser/service_worker/embedded_worker_registry.cc
@@ -84,6 +84,34 @@
   }
 }
 
+void EmbeddedWorkerRegistry::OnWorkerScriptLoaded(int process_id,
+                                                  int embedded_worker_id) {
+  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
+  if (found == worker_map_.end()) {
+    LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
+    return;
+  }
+  if (found->second->process_id() != process_id) {
+    LOG(ERROR) << "Incorrect embedded_worker_id";
+    return;
+  }
+  found->second->OnScriptLoaded();
+}
+
+void EmbeddedWorkerRegistry::OnWorkerScriptLoadFailed(int process_id,
+                                                      int embedded_worker_id) {
+  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
+  if (found == worker_map_.end()) {
+    LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
+    return;
+  }
+  if (found->second->process_id() != process_id) {
+    LOG(ERROR) << "Incorrect embedded_worker_id";
+    return;
+  }
+  found->second->OnScriptLoadFailed();
+}
+
 void EmbeddedWorkerRegistry::OnWorkerStarted(
     int process_id, int thread_id, int embedded_worker_id) {
   DCHECK(!ContainsKey(worker_process_map_, process_id) ||
@@ -93,8 +121,11 @@
     LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
     return;
   }
+  if (found->second->process_id() != process_id) {
+    LOG(ERROR) << "Incorrect embedded_worker_id";
+    return;
+  }
   worker_process_map_[process_id].insert(embedded_worker_id);
-  DCHECK_EQ(found->second->process_id(), process_id);
   found->second->OnStarted(thread_id);
 }
 
@@ -105,7 +136,10 @@
     LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
     return;
   }
-  DCHECK_EQ(found->second->process_id(), process_id);
+  if (found->second->process_id() != process_id) {
+    LOG(ERROR) << "Incorrect embedded_worker_id";
+    return;
+  }
   worker_process_map_[process_id].erase(embedded_worker_id);
   found->second->OnStopped();
 }
diff --git a/content/browser/service_worker/embedded_worker_registry.h b/content/browser/service_worker/embedded_worker_registry.h
index a79b258..24b5b69 100644
--- a/content/browser/service_worker/embedded_worker_registry.h
+++ b/content/browser/service_worker/embedded_worker_registry.h
@@ -64,6 +64,8 @@
 
   // Called back from EmbeddedWorker in the child process, relayed via
   // ServiceWorkerDispatcherHost.
+  void OnWorkerScriptLoaded(int process_id, int embedded_worker_id);
+  void OnWorkerScriptLoadFailed(int process_id, int embedded_worker_id);
   void OnWorkerStarted(int process_id, int thread_id, int embedded_worker_id);
   void OnWorkerStopped(int process_id, int embedded_worker_id);
   void OnReportException(int embedded_worker_id,
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc
index 698e260..e6f8ce5 100644
--- a/content/browser/service_worker/embedded_worker_test_helper.cc
+++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -23,7 +23,9 @@
     : wrapper_(new ServiceWorkerContextWrapper(NULL)),
       next_thread_id_(0),
       weak_factory_(this) {
-  wrapper_->Init(base::FilePath(), NULL);
+  wrapper_->InitForTesting(base::FilePath(),
+                           base::MessageLoopProxy::current(),
+                           NULL);
   scoped_ptr<ServiceWorkerProcessManager> process_manager(
       new ServiceWorkerProcessManager(wrapper_));
   process_manager->SetProcessRefcountOpsForTest(base::Bind(AlwaysTrue),
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc
index d654661..7a8e386 100644
--- a/content/browser/service_worker/service_worker_context_core.cc
+++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -77,11 +77,12 @@
 
 ServiceWorkerContextCore::ServiceWorkerContextCore(
     const base::FilePath& path,
+    base::SequencedTaskRunner* database_task_runner,
     quota::QuotaManagerProxy* quota_manager_proxy,
     ObserverListThreadSafe<ServiceWorkerContextObserver>* observer_list,
     scoped_ptr<ServiceWorkerProcessManager> process_manager)
-    : storage_(
-          new ServiceWorkerStorage(path, AsWeakPtr(), quota_manager_proxy)),
+    : storage_(new ServiceWorkerStorage(
+          path, AsWeakPtr(), database_task_runner, quota_manager_proxy)),
       embedded_worker_registry_(new EmbeddedWorkerRegistry(AsWeakPtr())),
       job_coordinator_(new ServiceWorkerJobCoordinator(AsWeakPtr())),
       process_manager_(process_manager.Pass()),
diff --git a/content/browser/service_worker/service_worker_context_core.h b/content/browser/service_worker/service_worker_context_core.h
index 55d64ae..54dcc9d 100644
--- a/content/browser/service_worker/service_worker_context_core.h
+++ b/content/browser/service_worker/service_worker_context_core.h
@@ -25,6 +25,7 @@
 
 namespace base {
 class FilePath;
+class SequencedTaskRunner;
 }
 
 namespace quota {
@@ -86,6 +87,7 @@
   // be called on the thread which called AddObserver() of |observer_list|.
   ServiceWorkerContextCore(
       const base::FilePath& user_data_directory,
+      base::SequencedTaskRunner* database_task_runner,
       quota::QuotaManagerProxy* quota_manager_proxy,
       ObserverListThreadSafe<ServiceWorkerContextObserver>* observer_list,
       scoped_ptr<ServiceWorkerProcessManager> process_manager);
diff --git a/content/browser/service_worker/service_worker_context_request_handler.cc b/content/browser/service_worker/service_worker_context_request_handler.cc
index 2e7c655..cd6c200 100644
--- a/content/browser/service_worker/service_worker_context_request_handler.cc
+++ b/content/browser/service_worker/service_worker_context_request_handler.cc
@@ -4,13 +4,20 @@
 
 #include "content/browser/service_worker/service_worker_context_request_handler.h"
 
+#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_read_from_cache_job.h"
+#include "content/browser/service_worker/service_worker_version.h"
+#include "net/url_request/url_request.h"
+
 namespace content {
 
 ServiceWorkerContextRequestHandler::ServiceWorkerContextRequestHandler(
     base::WeakPtr<ServiceWorkerContextCore> context,
     base::WeakPtr<ServiceWorkerProviderHost> provider_host,
     ResourceType::Type resource_type)
-    : ServiceWorkerRequestHandler(context, provider_host, resource_type) {
+    : ServiceWorkerRequestHandler(context, provider_host, resource_type),
+      version_(provider_host_->running_hosted_version()) {
+  DCHECK(provider_host_->IsHostToRunningServiceWorker());
 }
 
 ServiceWorkerContextRequestHandler::~ServiceWorkerContextRequestHandler() {
@@ -19,8 +26,51 @@
 net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
     net::URLRequest* request,
     net::NetworkDelegate* network_delegate) {
-  // TODO(michaeln): write me
+  if (!provider_host_ || !version_)
+    return NULL;
+
+  // We only use the script cache for main script loading and
+  // importScripts(), even if a cached script is xhr'd, we don't
+  // retrieve it from the script cache.
+  // TODO(michaeln): Get the desired behavior clarified in the spec,
+  // and make tweak the behavior here to match.
+  if (resource_type_ != ResourceType::SERVICE_WORKER &&
+      resource_type_ != ResourceType::SCRIPT) {
+    return NULL;
+  }
+
+  if (ShouldAddToScriptCache(request->url())) {
+    return NULL;
+    // TODO(michaeln): return new ServiceWorkerWriteToCacheJob();
+  }
+
+  int64 response_id = kInvalidServiceWorkerResponseId;
+  if (ShouldReadFromScriptCache(request->url(), &response_id)) {
+    return new ServiceWorkerReadFromCacheJob(
+        request, network_delegate, context_, response_id);
+  }
+
+  // NULL means use the network.
   return NULL;
 }
 
+bool ServiceWorkerContextRequestHandler::ShouldAddToScriptCache(
+    const GURL& url) {
+  // TODO(michaeln): Ensure the transition to INSTALLING can't
+  // happen prior to the initial eval completion.
+  if (version_->status() != ServiceWorkerVersion::NEW)
+    return false;
+  return version_->LookupInScriptCache(url) == kInvalidServiceWorkerResponseId;
+}
+
+bool ServiceWorkerContextRequestHandler::ShouldReadFromScriptCache(
+    const GURL& url, int64* response_id_out) {
+  // We don't read from the script cache until the version is INSTALLED.
+  if (version_->status() == ServiceWorkerVersion::NEW ||
+      version_->status() == ServiceWorkerVersion::INSTALLING)
+    return false;
+  *response_id_out = version_->LookupInScriptCache(url);
+  return *response_id_out != kInvalidServiceWorkerResponseId;
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_context_request_handler.h b/content/browser/service_worker/service_worker_context_request_handler.h
index ee24f45..d2e6adb 100644
--- a/content/browser/service_worker/service_worker_context_request_handler.h
+++ b/content/browser/service_worker/service_worker_context_request_handler.h
@@ -9,6 +9,8 @@
 
 namespace content {
 
+class ServiceWorkerVersion;
+
 // A request handler derivative used to handle requests from
 // service workers.
 class CONTENT_EXPORT ServiceWorkerContextRequestHandler
@@ -26,6 +28,11 @@
       net::NetworkDelegate* network_delegate) OVERRIDE;
 
  private:
+  bool ShouldAddToScriptCache(const GURL& url);
+  bool ShouldReadFromScriptCache(const GURL& url, int64* response_id_out);
+
+  scoped_refptr<ServiceWorkerVersion> version_;
+
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContextRequestHandler);
 };
 
diff --git a/content/browser/service_worker/service_worker_context_unittest.cc b/content/browser/service_worker/service_worker_context_unittest.cc
index dc174bd..6a8088b 100644
--- a/content/browser/service_worker/service_worker_context_unittest.cc
+++ b/content/browser/service_worker/service_worker_context_unittest.cc
@@ -160,6 +160,7 @@
 
   context()->storage()->FindRegistrationForId(
       registration_id,
+      GURL("http://www.example.com"),
       base::Bind(&ExpectRegisteredWorkers,
                  SERVICE_WORKER_OK,
                  version_id,
@@ -198,6 +199,7 @@
 
   context()->storage()->FindRegistrationForId(
       registration_id,
+      GURL("http://www.example.com"),
       base::Bind(&ExpectRegisteredWorkers,
                  SERVICE_WORKER_ERROR_NOT_FOUND,
                  kInvalidServiceWorkerVersionId,
@@ -236,6 +238,7 @@
 
   context()->storage()->FindRegistrationForId(
       registration_id,
+      GURL("http://www.example.com"),
       base::Bind(&ExpectRegisteredWorkers,
                  SERVICE_WORKER_ERROR_NOT_FOUND,
                  kInvalidServiceWorkerVersionId,
@@ -274,6 +277,7 @@
 
   context()->storage()->FindRegistrationForId(
       registration_id,
+      pattern.GetOrigin(),
       base::Bind(&ExpectRegisteredWorkers,
                  SERVICE_WORKER_ERROR_NOT_FOUND,
                  kInvalidServiceWorkerVersionId,
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index e6a9004..fd808be 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -5,6 +5,7 @@
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 
 #include "base/files/file_path.h"
+#include "base/threading/sequenced_worker_pool.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/browser/service_worker/service_worker_context_observer.h"
 #include "content/browser/service_worker/service_worker_process_manager.h"
@@ -26,22 +27,12 @@
 void ServiceWorkerContextWrapper::Init(
     const base::FilePath& user_data_directory,
     quota::QuotaManagerProxy* quota_manager_proxy) {
-  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
-    BrowserThread::PostTask(
-        BrowserThread::IO,
-        FROM_HERE,
-        base::Bind(&ServiceWorkerContextWrapper::Init,
-                   this,
-                   user_data_directory,
-                   make_scoped_refptr(quota_manager_proxy)));
-    return;
-  }
-  DCHECK(!context_core_);
-  context_core_.reset(new ServiceWorkerContextCore(
-      user_data_directory,
-      quota_manager_proxy,
-      observer_list_,
-      make_scoped_ptr(new ServiceWorkerProcessManager(this))));
+  scoped_refptr<base::SequencedTaskRunner> database_task_runner =
+      BrowserThread::GetBlockingPool()->
+          GetSequencedTaskRunnerWithShutdownBehavior(
+              BrowserThread::GetBlockingPool()->GetSequenceToken(),
+              base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+  InitInternal(user_data_directory, database_task_runner, quota_manager_proxy);
 }
 
 void ServiceWorkerContextWrapper::Shutdown() {
@@ -137,4 +128,35 @@
   observer_list_->RemoveObserver(observer);
 }
 
+void ServiceWorkerContextWrapper::InitForTesting(
+    const base::FilePath& user_data_directory,
+    base::SequencedTaskRunner* database_task_runner,
+    quota::QuotaManagerProxy* quota_manager_proxy) {
+  InitInternal(user_data_directory, database_task_runner, quota_manager_proxy);
+}
+
+void ServiceWorkerContextWrapper::InitInternal(
+    const base::FilePath& user_data_directory,
+    base::SequencedTaskRunner* database_task_runner,
+    quota::QuotaManagerProxy* quota_manager_proxy) {
+  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
+    BrowserThread::PostTask(
+        BrowserThread::IO,
+        FROM_HERE,
+        base::Bind(&ServiceWorkerContextWrapper::InitInternal,
+                   this,
+                   user_data_directory,
+                   make_scoped_refptr(database_task_runner),
+                   make_scoped_refptr(quota_manager_proxy)));
+    return;
+  }
+  DCHECK(!context_core_);
+  context_core_.reset(new ServiceWorkerContextCore(
+      user_data_directory,
+      database_task_runner,
+      quota_manager_proxy,
+      observer_list_,
+      make_scoped_ptr(new ServiceWorkerProcessManager(this))));
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h
index 6d53549..6b5b841 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -16,6 +16,7 @@
 
 namespace base {
 class FilePath;
+class SequencedTaskRunner;
 }
 
 namespace quota {
@@ -61,9 +62,17 @@
 
  private:
   friend class base::RefCountedThreadSafe<ServiceWorkerContextWrapper>;
+  friend class EmbeddedWorkerTestHelper;
   friend class ServiceWorkerProcessManager;
   virtual ~ServiceWorkerContextWrapper();
 
+  void InitForTesting(const base::FilePath& user_data_directory,
+                      base::SequencedTaskRunner* database_task_runner,
+                      quota::QuotaManagerProxy* quota_manager_proxy);
+  void InitInternal(const base::FilePath& user_data_directory,
+                    base::SequencedTaskRunner* database_task_runner,
+                    quota::QuotaManagerProxy* quota_manager_proxy);
+
   const scoped_refptr<ObserverListThreadSafe<ServiceWorkerContextObserver> >
       observer_list_;
   // Cleared in Shutdown():
diff --git a/content/browser/service_worker/service_worker_database.cc b/content/browser/service_worker/service_worker_database.cc
index 1c94235..37558b2 100644
--- a/content/browser/service_worker/service_worker_database.cc
+++ b/content/browser/service_worker/service_worker_database.cc
@@ -49,6 +49,10 @@
 //     (ex. "REG:http://example.com\x00123456")
 //   value: <ServiceWorkerRegistrationData serialized as a string>
 //
+//   key: "RES:" + <int64 'version_id'> + '\x00' + <int64 'resource_id'>
+//     (ex. "RES:123456\x00654321")
+//   value: <ServiceWorkerResourceRecord serialized as a string>
+//
 //   key: "URES:" + <int64 'uncommitted_resource_id'>
 //   value: <empty>
 
@@ -63,6 +67,7 @@
 const char kUniqueOriginKey[] = "INITDATA_UNIQUE_ORIGIN:";
 
 const char kRegKeyPrefix[] = "REG:";
+const char kResKeyPrefix[] = "RES:";
 const char kKeySeparator = '\x00';
 
 const char kUncommittedResIdKeyPrefix[] = "URES:";
@@ -89,6 +94,19 @@
                             base::Int64ToString(registration_id).c_str());
 }
 
+std::string CreateResourceRecordKeyPrefix(int64 version_id) {
+  return base::StringPrintf("%s%s%c",
+                            kResKeyPrefix,
+                            base::Int64ToString(version_id).c_str(),
+                            kKeySeparator);
+}
+
+std::string CreateResourceRecordKey(int64 version_id,
+                                    int64 resource_id) {
+  return CreateResourceRecordKeyPrefix(version_id).append(
+      base::Int64ToString(resource_id));
+}
+
 std::string CreateUniqueOriginKey(const GURL& origin) {
   return base::StringPrintf("%s%s", kUniqueOriginKey, origin.spec().c_str());
 }
@@ -120,15 +138,37 @@
   batch->Put(CreateRegistrationKey(data.registration_id(), origin), value);
 }
 
+void PutResourceRecordToBatch(
+    const ServiceWorkerDatabase::ResourceRecord& input,
+    int64 version_id,
+    leveldb::WriteBatch* batch) {
+  DCHECK(batch);
+
+  // Convert ResourceRecord to ServiceWorkerResourceRecord.
+  ServiceWorkerResourceRecord record;
+  record.set_resource_id(input.resource_id);
+  record.set_url(input.url.spec());
+
+  std::string value;
+  bool success = record.SerializeToString(&value);
+  DCHECK(success);
+  batch->Put(CreateResourceRecordKey(version_id, input.resource_id), value);
+}
+
 void PutUniqueOriginToBatch(const GURL& origin,
                             leveldb::WriteBatch* batch) {
   // Value should be empty.
   batch->Put(CreateUniqueOriginKey(origin), "");
 }
 
-bool ParseRegistrationData(
-    const std::string& serialized,
-    ServiceWorkerDatabase::RegistrationData* out) {
+void PutPurgeableResourceIdToBatch(int64 resource_id,
+                                   leveldb::WriteBatch* batch) {
+  // Value should be empty.
+  batch->Put(CreateResourceIdKey(kPurgeableResIdKeyPrefix, resource_id), "");
+}
+
+bool ParseRegistrationData(const std::string& serialized,
+                           ServiceWorkerDatabase::RegistrationData* out) {
   DCHECK(out);
   ServiceWorkerRegistrationData data;
   if (!data.ParseFromString(serialized))
@@ -136,8 +176,11 @@
 
   GURL scope_url(data.scope_url());
   GURL script_url(data.script_url());
-  if (scope_url.GetOrigin() != script_url.GetOrigin())
+  if (!scope_url.is_valid() ||
+      !script_url.is_valid() ||
+      scope_url.GetOrigin() != script_url.GetOrigin()) {
     return false;
+  }
 
   // Convert ServiceWorkerRegistrationData to RegistrationData.
   out->registration_id = data.registration_id();
@@ -151,6 +194,23 @@
   return true;
 }
 
+bool ParseResourceRecord(const std::string& serialized,
+                         ServiceWorkerDatabase::ResourceRecord* out) {
+  DCHECK(out);
+  ServiceWorkerResourceRecord record;
+  if (!record.ParseFromString(serialized))
+    return false;
+
+  GURL url(record.url());
+  if (!url.is_valid())
+    return false;
+
+  // Convert ServiceWorkerResourceRecord to ResourceRecord.
+  out->resource_id = record.resource_id();
+  out->url = url;
+  return true;
+}
+
 }  // namespace
 
 ServiceWorkerDatabase::RegistrationData::RegistrationData()
@@ -171,6 +231,7 @@
       is_disabled_(false),
       was_corruption_detected_(false),
       is_initialized_(false) {
+  sequence_checker_.DetachFromSequence();
 }
 
 ServiceWorkerDatabase::~ServiceWorkerDatabase() {
@@ -187,8 +248,15 @@
   DCHECK(next_avail_version_id);
   DCHECK(next_avail_resource_id);
 
-  if (!LazyOpen(false) || is_disabled_)
-    return false;
+  if (!LazyOpen(false)) {
+    if (is_disabled_)
+      return false;
+    // Database has never been used.
+    *next_avail_registration_id = 0;
+    *next_avail_version_id = 0;
+    *next_avail_resource_id = 0;
+    return true;
+  }
 
   if (!ReadNextAvailableId(kNextRegIdKey, &next_avail_registration_id_) ||
       !ReadNextAvailableId(kNextVerIdKey, &next_avail_version_id_) ||
@@ -207,8 +275,13 @@
   DCHECK(sequence_checker_.CalledOnValidSequencedThread());
   DCHECK(origins);
 
-  if (!LazyOpen(false) || is_disabled_)
-    return false;
+  if (!LazyOpen(false)) {
+    if (is_disabled_)
+      return false;
+    // Database has never been used.
+    origins->clear();
+    return true;
+  }
 
   scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
   for (itr->Seek(kUniqueOriginKey); itr->Valid(); itr->Next()) {
@@ -232,8 +305,13 @@
   DCHECK(sequence_checker_.CalledOnValidSequencedThread());
   DCHECK(registrations);
 
-  if (!LazyOpen(false) || is_disabled_)
-    return false;
+  if (!LazyOpen(false)) {
+    if (is_disabled_)
+      return false;
+    // Database has never been used.
+    registrations->clear();
+    return true;
+  }
 
   // Create a key prefix for registrations.
   std::string prefix = base::StringPrintf(
@@ -261,6 +339,41 @@
   return true;
 }
 
+bool ServiceWorkerDatabase::GetAllRegistrations(
+    std::vector<RegistrationData>* registrations) {
+  DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+  DCHECK(registrations);
+
+  if (!LazyOpen(false)) {
+    if (is_disabled_)
+      return false;
+    // Database has never been used.
+    registrations->clear();
+    return true;
+  }
+
+  scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
+  for (itr->Seek(kRegKeyPrefix); itr->Valid(); itr->Next()) {
+    if (!itr->status().ok()) {
+      HandleError(FROM_HERE, itr->status());
+      registrations->clear();
+      return false;
+    }
+
+    if (!RemovePrefix(itr->key().ToString(), kRegKeyPrefix, NULL))
+      break;
+
+    RegistrationData registration;
+    if (!ParseRegistrationData(itr->value().ToString(), &registration)) {
+      HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse"));
+      registrations->clear();
+      return false;
+    }
+    registrations->push_back(registration);
+  }
+  return true;
+}
+
 bool ServiceWorkerDatabase::ReadRegistration(
     int64 registration_id,
     const GURL& origin,
@@ -277,7 +390,8 @@
   if (!ReadRegistrationData(registration_id, origin, &value))
     return false;
 
-  // TODO(nhiroki): Read ResourceRecords tied with this registration.
+  if (!ReadResourceRecords(value.version_id, resources))
+    return false;
 
   *registration = value;
   return true;
@@ -300,7 +414,43 @@
 
   PutRegistrationDataToBatch(registration, &batch);
 
-  // TODO(nhiroki): Write |resources| into the database.
+  // Retrieve a previous version to sweep purgeable resources.
+  RegistrationData old_registration;
+  if (!ReadRegistrationData(registration.registration_id,
+                            registration.scope.GetOrigin(),
+                            &old_registration)) {
+    if (is_disabled_)
+      return false;
+    // Just not found.
+  } else {
+    DCHECK_LT(old_registration.version_id, registration.version_id);
+    // Currently resource sharing across versions and registrations is not
+    // suppported, so resource ids should not be overlapped between
+    // |registration| and |old_registration|.
+    // TODO(nhiroki): Add DCHECK to make sure the overlap does not exist.
+    if (!DeleteResourceRecords(old_registration.version_id, &batch))
+      return false;
+  }
+
+  // Used for avoiding multiple writes for the same resource id or url.
+  std::set<int64> pushed_resources;
+  std::set<GURL> pushed_urls;
+  for (std::vector<ResourceRecord>::const_iterator itr = resources.begin();
+       itr != resources.end(); ++itr) {
+    if (!itr->url.is_valid())
+      return false;
+
+    // Duplicated resource id or url should not exist.
+    DCHECK(pushed_resources.insert(itr->resource_id).second);
+    DCHECK(pushed_urls.insert(itr->url).second);
+
+    PutResourceRecordToBatch(*itr, registration.version_id, &batch);
+
+    // Delete a resource from the uncommitted list.
+    batch.Delete(CreateResourceIdKey(
+        kUncommittedResIdKeyPrefix, itr->resource_id));
+  }
+
   return WriteBatch(&batch);
 }
 
@@ -358,9 +508,19 @@
     batch.Delete(CreateUniqueOriginKey(origin));
   }
 
+  // Delete a registration specified by |registration_id|.
   batch.Delete(CreateRegistrationKey(registration_id, origin));
 
-  // TODO(nhiroki): Delete ResourceRecords tied with this registration.
+  // Delete resource records associated with the registration.
+  for (std::vector<RegistrationData>::const_iterator itr =
+           registrations.begin(); itr != registrations.end(); ++itr) {
+    if (itr->registration_id == registration_id) {
+      if (!DeleteResourceRecords(itr->version_id, &batch))
+        return false;
+      break;
+    }
+  }
+
   return WriteBatch(&batch);
 }
 
@@ -392,6 +552,31 @@
   return DeleteResourceIds(kPurgeableResIdKeyPrefix, ids);
 }
 
+bool ServiceWorkerDatabase::DeleteAllDataForOrigin(const GURL& origin) {
+  DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+  if (!LazyOpen(true) || is_disabled_ || !origin.is_valid())
+    return false;
+
+  leveldb::WriteBatch batch;
+
+  // Delete from the unique origin list.
+  batch.Delete(CreateUniqueOriginKey(origin));
+
+  std::vector<RegistrationData> registrations;
+  if (!GetRegistrationsForOrigin(origin, &registrations))
+    return false;
+
+  // Delete registrations and resource records.
+  for (std::vector<RegistrationData>::const_iterator itr =
+           registrations.begin(); itr != registrations.end(); ++itr) {
+    batch.Delete(CreateRegistrationKey(itr->registration_id, origin));
+    if (!DeleteResourceRecords(itr->version_id, &batch))
+      return false;
+  }
+
+  return WriteBatch(&batch);
+}
+
 bool ServiceWorkerDatabase::LazyOpen(bool create_if_needed) {
   DCHECK(sequence_checker_.CalledOnValidSequencedThread());
   if (IsOpen())
@@ -493,6 +678,68 @@
   return true;
 }
 
+bool ServiceWorkerDatabase::ReadResourceRecords(
+    int64 version_id,
+    std::vector<ResourceRecord>* resources) {
+  DCHECK(resources);
+
+  std::string prefix = CreateResourceRecordKeyPrefix(version_id);
+  scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
+  for (itr->Seek(prefix); itr->Valid(); itr->Next()) {
+    if (!itr->status().ok()) {
+      HandleError(FROM_HERE, itr->status());
+      resources->clear();
+      return false;
+    }
+
+    if (!RemovePrefix(itr->key().ToString(), prefix, NULL))
+      break;
+
+    ResourceRecord resource;
+    if (!ParseResourceRecord(itr->value().ToString(), &resource)) {
+      HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse"));
+      resources->clear();
+      return false;
+    }
+    resources->push_back(resource);
+  }
+  return true;
+}
+
+bool ServiceWorkerDatabase::DeleteResourceRecords(
+    int64 version_id,
+    leveldb::WriteBatch* batch) {
+  DCHECK(batch);
+
+  std::string prefix = CreateResourceRecordKeyPrefix(version_id);
+  scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
+  for (itr->Seek(prefix); itr->Valid(); itr->Next()) {
+    if (!itr->status().ok()) {
+      HandleError(FROM_HERE, itr->status());
+      return false;
+    }
+
+    std::string key = itr->key().ToString();
+    std::string unprefixed;
+    if (!RemovePrefix(key, prefix, &unprefixed))
+      break;
+
+    int64 resource_id;
+    if (!base::StringToInt64(unprefixed, &resource_id)) {
+      HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse"));
+      return false;
+    }
+
+    // Remove a resource record.
+    batch->Delete(key);
+
+    // Currently resource sharing across versions and registrations is not
+    // supported, so we can purge this without caring about it.
+    PutPurgeableResourceIdToBatch(resource_id, batch);
+  }
+  return true;
+}
+
 bool ServiceWorkerDatabase::ReadResourceIds(const char* id_key_prefix,
                                             std::set<int64>* ids) {
   DCHECK(sequence_checker_.CalledOnValidSequencedThread());
diff --git a/content/browser/service_worker/service_worker_database.h b/content/browser/service_worker/service_worker_database.h
index 9b52daa..23d3ffd 100644
--- a/content/browser/service_worker/service_worker_database.h
+++ b/content/browser/service_worker/service_worker_database.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATABASE_H_
 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DATABASE_H_
 
+#include <map>
 #include <set>
 #include <vector>
 
@@ -76,6 +77,8 @@
   bool GetRegistrationsForOrigin(const GURL& origin,
                                  std::vector<RegistrationData>* registrations);
 
+  bool GetAllRegistrations(std::vector<RegistrationData>* registrations);
+
   // Saving, retrieving, and updating registration data.
   // (will bump next_avail_xxxx_ids as needed)
   // (resource ids will be added/removed from the uncommitted/purgeable
@@ -127,6 +130,10 @@
   // Returns true on success. Otherwise deletes nothing and returns false.
   bool ClearPurgeableResourceIds(const std::set<int64>& ids);
 
+  // Delete all data for |origin|, namely, unique origin, registrations and
+  // resource records. Resources are moved to the purgeable list.
+  bool DeleteAllDataForOrigin(const GURL& origin);
+
   bool is_disabled() const { return is_disabled_; }
   bool was_corruption_detected() const { return was_corruption_detected_; }
 
@@ -142,12 +149,19 @@
   bool ReadRegistrationData(int64 registration_id,
                             const GURL& origin,
                             RegistrationData* registration);
+  bool ReadResourceRecords(int64 version_id,
+                           std::vector<ResourceRecord>* resources);
+  bool DeleteResourceRecords(int64 version_id,
+                             leveldb::WriteBatch* batch);
   bool ReadResourceIds(const char* id_key_prefix,
                        std::set<int64>* ids);
   bool WriteResourceIds(const char* id_key_prefix,
                         const std::set<int64>& ids);
   bool DeleteResourceIds(const char* id_key_prefix,
                          const std::set<int64>& ids);
+
+  // Reads the current schema version from the database. If the database hasn't
+  // been written anything yet, sets |db_version| to 0 and returns true.
   bool ReadDatabaseVersion(int64* db_version);
 
   // Write a batch into the database.
@@ -190,7 +204,11 @@
 
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, OpenDatabase);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, OpenDatabase_InMemory);
+  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, DatabaseVersion);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, GetNextAvailableIds);
+  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, Registration_Basic);
+  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, Registration_Overwrite);
+  FRIEND_TEST_ALL_PREFIXES(ServiceWorkerDatabaseTest, Registration_Multiple);
 
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDatabase);
 };
diff --git a/content/browser/service_worker/service_worker_database_unittest.cc b/content/browser/service_worker/service_worker_database_unittest.cc
index bcf2eae..cbacfcc 100644
--- a/content/browser/service_worker/service_worker_database_unittest.cc
+++ b/content/browser/service_worker/service_worker_database_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "content/browser/service_worker/service_worker_database.h"
 
+#include <string>
+
 #include "base/files/scoped_temp_dir.h"
 #include "base/stl_util.h"
 #include "content/browser/service_worker/service_worker_database.pb.h"
@@ -13,6 +15,9 @@
 
 namespace {
 
+typedef ServiceWorkerDatabase::RegistrationData RegistrationData;
+typedef ServiceWorkerDatabase::ResourceRecord Resource;
+
 struct AvailableIds {
   int64 reg_id;
   int64 res_id;
@@ -22,6 +27,31 @@
   ~AvailableIds() {}
 };
 
+// TODO(nhiroki): Refactor tests using this helper.
+GURL URL(const GURL& origin, const std::string& path) {
+  EXPECT_TRUE(origin.is_valid());
+  GURL out(origin.GetOrigin().spec() + path);
+  EXPECT_TRUE(out.is_valid());
+  return out;
+}
+
+// TODO(nhiroki): Remove this.
+Resource CreateResource(int64 resource_id, const std::string& url) {
+  Resource resource;
+  resource.resource_id = resource_id;
+  resource.url = GURL(url);
+  EXPECT_TRUE(resource.url.is_valid());
+  return resource;
+}
+
+Resource CreateResource(int64 resource_id, const GURL& url) {
+  Resource resource;
+  resource.resource_id = resource_id;
+  resource.url = url;
+  EXPECT_TRUE(resource.url.is_valid());
+  return resource;
+}
+
 ServiceWorkerDatabase* CreateDatabase(const base::FilePath& path) {
   return new ServiceWorkerDatabase(path);
 }
@@ -30,9 +60,8 @@
   return new ServiceWorkerDatabase(base::FilePath());
 }
 
-void VerifyRegistrationData(
-    const ServiceWorkerDatabase::RegistrationData& expected,
-    const ServiceWorkerDatabase::RegistrationData& actual) {
+void VerifyRegistrationData(const RegistrationData& expected,
+                            const RegistrationData& actual) {
   EXPECT_EQ(expected.registration_id, actual.registration_id);
   EXPECT_EQ(expected.scope, actual.scope);
   EXPECT_EQ(expected.script, actual.script);
@@ -42,6 +71,17 @@
   EXPECT_EQ(expected.last_update_check, actual.last_update_check);
 }
 
+void VerifyResourceRecords(const std::vector<Resource>& expected,
+                           const std::vector<Resource>& actual) {
+  EXPECT_EQ(expected.size(), actual.size());
+  if (expected.size() != actual.size())
+    return;
+  for (size_t i = 0; i < expected.size(); ++i) {
+    EXPECT_EQ(expected[i].resource_id, actual[i].resource_id);
+    EXPECT_EQ(expected[i].url, actual[i].url);
+  }
+}
+
 }  // namespace
 
 TEST(ServiceWorkerDatabaseTest, OpenDatabase) {
@@ -72,6 +112,26 @@
   EXPECT_FALSE(database->LazyOpen(false));
 }
 
+TEST(ServiceWorkerDatabaseTest, DatabaseVersion) {
+  scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
+  EXPECT_TRUE(database->LazyOpen(true));
+
+  // Opening a new database does not write anything, so its schema version
+  // should be 0.
+  int64 db_version = -1;
+  EXPECT_TRUE(database->ReadDatabaseVersion(&db_version));
+  EXPECT_EQ(0u, db_version);
+
+  // First writing triggers database initialization and bumps the schema
+  // version.
+  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
+  ServiceWorkerDatabase::RegistrationData data;
+  ASSERT_TRUE(database->WriteRegistration(data, resources));
+
+  EXPECT_TRUE(database->ReadDatabaseVersion(&db_version));
+  EXPECT_LT(0, db_version);
+}
+
 TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
   base::ScopedTempDir database_dir;
   ASSERT_TRUE(database_dir.CreateUniqueTempDir());
@@ -79,9 +139,12 @@
       CreateDatabase(database_dir.path()));
   AvailableIds ids;
 
-  // Should be false because the database hasn't been opened.
-  EXPECT_FALSE(database->GetNextAvailableIds(
+  // The database has never been used, so returns initial values.
+  EXPECT_TRUE(database->GetNextAvailableIds(
       &ids.reg_id, &ids.ver_id, &ids.res_id));
+  EXPECT_EQ(0, ids.reg_id);
+  EXPECT_EQ(0, ids.ver_id);
+  EXPECT_EQ(0, ids.res_id);
 
   ASSERT_TRUE(database->LazyOpen(true));
   EXPECT_TRUE(database->GetNextAvailableIds(
@@ -91,8 +154,8 @@
   EXPECT_EQ(0, ids.res_id);
 
   // Writing a registration bumps the next available ids.
-  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
-  ServiceWorkerDatabase::RegistrationData data1;
+  std::vector<Resource> resources;
+  RegistrationData data1;
   data1.registration_id = 100;
   data1.scope = GURL("http://example.com/foo");
   data1.script = GURL("http://example.com/script1.js");
@@ -107,7 +170,7 @@
 
   // Writing a registration whose ids are lower than the stored ones should not
   // bump the next available ids.
-  ServiceWorkerDatabase::RegistrationData data2;
+  RegistrationData data2;
   data2.registration_id = 10;
   data2.scope = GURL("http://example.com/bar");
   data2.script = GURL("http://example.com/script2.js");
@@ -128,12 +191,12 @@
   scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
 
   std::set<GURL> origins;
-  EXPECT_FALSE(database->GetOriginsWithRegistrations(&origins));
+  EXPECT_TRUE(database->GetOriginsWithRegistrations(&origins));
   EXPECT_TRUE(origins.empty());
 
-  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
+  std::vector<Resource> resources;
 
-  ServiceWorkerDatabase::RegistrationData data1;
+  RegistrationData data1;
   data1.registration_id = 123;
   data1.scope = GURL("http://example.com/foo");
   data1.script = GURL("http://example.com/script1.js");
@@ -141,7 +204,7 @@
   GURL origin1 = data1.script.GetOrigin();
   ASSERT_TRUE(database->WriteRegistration(data1, resources));
 
-  ServiceWorkerDatabase::RegistrationData data2;
+  RegistrationData data2;
   data2.registration_id = 234;
   data2.scope = GURL("https://www.example.com/bar");
   data2.script = GURL("https://www.example.com/script2.js");
@@ -149,7 +212,7 @@
   GURL origin2 = data2.script.GetOrigin();
   ASSERT_TRUE(database->WriteRegistration(data2, resources));
 
-  ServiceWorkerDatabase::RegistrationData data3;
+  RegistrationData data3;
   data3.registration_id = 345;
   data3.scope = GURL("https://example.org/hoge");
   data3.script = GURL("https://example.org/script3.js");
@@ -158,7 +221,7 @@
   ASSERT_TRUE(database->WriteRegistration(data3, resources));
 
   // |origin3| has two registrations.
-  ServiceWorkerDatabase::RegistrationData data4;
+  RegistrationData data4;
   data4.registration_id = 456;
   data4.scope = GURL("https://example.org/fuga");
   data4.script = GURL("https://example.org/script4.js");
@@ -198,26 +261,27 @@
   scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
 
   GURL origin("https://example.org");
-  std::vector<ServiceWorkerDatabase::RegistrationData> registrations;
-  EXPECT_FALSE(database->GetRegistrationsForOrigin(origin, &registrations));
+  std::vector<RegistrationData> registrations;
+  EXPECT_TRUE(database->GetRegistrationsForOrigin(origin, &registrations));
+  EXPECT_TRUE(registrations.empty());
 
-  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
+  std::vector<Resource> resources;
 
-  ServiceWorkerDatabase::RegistrationData data1;
+  RegistrationData data1;
   data1.registration_id = 100;
   data1.scope = GURL("http://example.com/foo");
   data1.script = GURL("http://example.com/script1.js");
   data1.version_id = 1000;
   ASSERT_TRUE(database->WriteRegistration(data1, resources));
 
-  ServiceWorkerDatabase::RegistrationData data2;
+  RegistrationData data2;
   data2.registration_id = 200;
   data2.scope = GURL("https://www.example.com/bar");
   data2.script = GURL("https://www.example.com/script2.js");
   data2.version_id = 2000;
   ASSERT_TRUE(database->WriteRegistration(data2, resources));
 
-  ServiceWorkerDatabase::RegistrationData data3;
+  RegistrationData data3;
   data3.registration_id = 300;
   data3.scope = GURL("https://example.org/hoge");
   data3.script = GURL("https://example.org/script3.js");
@@ -225,45 +289,258 @@
   ASSERT_TRUE(database->WriteRegistration(data3, resources));
 
   // Same origin with |data3|.
-  ServiceWorkerDatabase::RegistrationData data4;
+  RegistrationData data4;
   data4.registration_id = 400;
   data4.scope = GURL("https://example.org/fuga");
   data4.script = GURL("https://example.org/script4.js");
   data4.version_id = 4000;
   ASSERT_TRUE(database->WriteRegistration(data4, resources));
 
+  registrations.clear();
   EXPECT_TRUE(database->GetRegistrationsForOrigin(origin, &registrations));
   EXPECT_EQ(2U, registrations.size());
   VerifyRegistrationData(data3, registrations[0]);
   VerifyRegistrationData(data4, registrations[1]);
 }
 
-TEST(ServiceWorkerDatabaseTest, Registration) {
+TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) {
   scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
 
-  ServiceWorkerDatabase::RegistrationData data;
+  std::vector<RegistrationData> registrations;
+  EXPECT_TRUE(database->GetAllRegistrations(&registrations));
+  EXPECT_TRUE(registrations.empty());
+
+  std::vector<Resource> resources;
+
+  RegistrationData data1;
+  data1.registration_id = 100;
+  data1.scope = GURL("http://www1.example.com/foo");
+  data1.script = GURL("http://www1.example.com/script1.js");
+  data1.version_id = 1000;
+  ASSERT_TRUE(database->WriteRegistration(data1, resources));
+
+  RegistrationData data2;
+  data2.registration_id = 200;
+  data2.scope = GURL("http://www2.example.com/bar");
+  data2.script = GURL("http://www2.example.com/script2.js");
+  data2.version_id = 2000;
+  ASSERT_TRUE(database->WriteRegistration(data2, resources));
+
+  RegistrationData data3;
+  data3.registration_id = 300;
+  data3.scope = GURL("http://www3.example.com/hoge");
+  data3.script = GURL("http://www3.example.com/script3.js");
+  data3.version_id = 3000;
+  ASSERT_TRUE(database->WriteRegistration(data3, resources));
+
+  // Same origin with |data3|.
+  RegistrationData data4;
+  data4.registration_id = 400;
+  data4.scope = GURL("http://www4.example.com/fuga");
+  data4.script = GURL("http://www4.example.com/script4.js");
+  data4.version_id = 4000;
+  ASSERT_TRUE(database->WriteRegistration(data4, resources));
+
+  registrations.clear();
+  EXPECT_TRUE(database->GetAllRegistrations(&registrations));
+  EXPECT_EQ(4U, registrations.size());
+  VerifyRegistrationData(data1, registrations[0]);
+  VerifyRegistrationData(data2, registrations[1]);
+  VerifyRegistrationData(data3, registrations[2]);
+  VerifyRegistrationData(data4, registrations[3]);
+}
+
+// TODO(nhiroki): Record read/write operations using gtest fixture to avoid
+// building expectations by hand. For example, expected purgeable resource ids
+// should be calculated automatically.
+TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
+  scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
+
+  RegistrationData data;
   data.registration_id = 100;
   data.scope = GURL("http://example.com/foo");
   data.script = GURL("http://example.com/script.js");
   data.version_id = 200;
   GURL origin = data.scope.GetOrigin();
 
-  // TODO(nhiroki): Test ResourceRecord manipulation.
-  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
+  Resource resource1 = CreateResource(1, "http://example.com/resource1");
+  Resource resource2 = CreateResource(2, "http://example.com/resource2");
+
+  std::vector<Resource> resources;
+  resources.push_back(resource1);
+  resources.push_back(resource2);
+
+  // Write |resource1| to the uncommitted list to make sure that writing
+  // registration removes resource ids associated with the registration from
+  // the uncommitted list.
+  std::set<int64> uncommitted_ids;
+  uncommitted_ids.insert(resource1.resource_id);
+  EXPECT_TRUE(database->WriteUncommittedResourceIds(uncommitted_ids));
+  std::set<int64> uncommitted_ids_out;
+  EXPECT_TRUE(database->GetUncommittedResourceIds(&uncommitted_ids_out));
+  EXPECT_EQ(1u, uncommitted_ids_out.size());
+  EXPECT_TRUE(ContainsKey(uncommitted_ids_out, resource1.resource_id));
 
   EXPECT_TRUE(database->WriteRegistration(data, resources));
 
-  ServiceWorkerDatabase::RegistrationData data_out;
-  std::vector<ServiceWorkerDatabase::ResourceRecord> resources_out;
+  // Make sure that the registration and resource records are stored.
+  RegistrationData data_out;
+  std::vector<Resource> resources_out;
   EXPECT_TRUE(database->ReadRegistration(
       data.registration_id, origin, &data_out, &resources_out));
   VerifyRegistrationData(data, data_out);
+  VerifyResourceRecords(resources, resources_out);
 
-  EXPECT_TRUE(database->DeleteRegistration(data.registration_id,
-                                           data.scope.GetOrigin()));
+  // Make sure that |resource1| is removed from the uncommitted list.
+  uncommitted_ids_out.clear();
+  EXPECT_TRUE(database->GetUncommittedResourceIds(&uncommitted_ids_out));
+  EXPECT_TRUE(uncommitted_ids_out.empty());
 
+  EXPECT_TRUE(database->DeleteRegistration(
+      data.registration_id, data.scope.GetOrigin()));
+
+  // Make sure that the registration and resource records are gone.
+  resources_out.clear();
   EXPECT_FALSE(database->ReadRegistration(
       data.registration_id, origin, &data_out, &resources_out));
+  EXPECT_TRUE(resources_out.empty());
+
+  // Resources should be purgeable because these are no longer referred.
+  std::set<int64> purgeable_resource_ids;
+  EXPECT_TRUE(database->GetPurgeableResourceIds(&purgeable_resource_ids));
+  EXPECT_EQ(2u, purgeable_resource_ids.size());
+  EXPECT_TRUE(ContainsKey(purgeable_resource_ids, resource1.resource_id));
+  EXPECT_TRUE(ContainsKey(purgeable_resource_ids, resource2.resource_id));
+}
+
+TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
+  scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
+
+  RegistrationData data;
+  data.registration_id = 100;
+  data.scope = GURL("http://example.com/foo");
+  data.script = GURL("http://example.com/script.js");
+  data.version_id = 200;
+  GURL origin = data.scope.GetOrigin();
+
+  Resource resource1 = CreateResource(1, "http://example.com/resource1");
+  Resource resource2 = CreateResource(2, "http://example.com/resource2");
+
+  std::vector<Resource> resources1;
+  resources1.push_back(resource1);
+  resources1.push_back(resource2);
+
+  EXPECT_TRUE(database->WriteRegistration(data, resources1));
+
+  // Make sure that the registration and resource records are stored.
+  RegistrationData data_out;
+  std::vector<Resource> resources_out;
+  EXPECT_TRUE(database->ReadRegistration(
+      data.registration_id, origin, &data_out, &resources_out));
+  VerifyRegistrationData(data, data_out);
+  VerifyResourceRecords(resources1, resources_out);
+
+  // Update the registration.
+  RegistrationData updated_data = data;
+  updated_data.version_id = data.version_id + 1;
+  Resource resource3 = CreateResource(3, "http://example.com/resource3");
+  Resource resource4 = CreateResource(4, "http://example.com/resource4");
+  std::vector<Resource> resources2;
+  resources2.push_back(resource3);
+  resources2.push_back(resource4);
+
+  EXPECT_TRUE(database->WriteRegistration(updated_data, resources2));
+
+  // Make sure that |updated_data| is stored and resources referred from |data|
+  // is moved to the purgeable list.
+  resources_out.clear();
+  EXPECT_TRUE(database->ReadRegistration(
+      updated_data.registration_id, origin, &data_out, &resources_out));
+  VerifyRegistrationData(updated_data, data_out);
+  VerifyResourceRecords(resources2, resources_out);
+
+  std::set<int64> purgeable_resource_ids;
+  EXPECT_TRUE(database->GetPurgeableResourceIds(&purgeable_resource_ids));
+  EXPECT_EQ(2u, purgeable_resource_ids.size());
+  EXPECT_TRUE(ContainsKey(purgeable_resource_ids, resource1.resource_id));
+  EXPECT_TRUE(ContainsKey(purgeable_resource_ids, resource2.resource_id));
+}
+
+TEST(ServiceWorkerDatabaseTest, Registration_Multiple) {
+  scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
+
+  // Add registration1.
+  RegistrationData data1;
+  data1.registration_id = 100;
+  data1.scope = GURL("http://example.com/foo");
+  data1.script = GURL("http://example.com/script1.js");
+  data1.version_id = 200;
+  GURL origin1 = data1.scope.GetOrigin();
+
+  Resource resource1 = CreateResource(1, "http://example.com/resource1");
+  Resource resource2 = CreateResource(2, "http://example.com/resource2");
+
+  std::vector<Resource> resources1;
+  resources1.push_back(resource1);
+  resources1.push_back(resource2);
+  EXPECT_TRUE(database->WriteRegistration(data1, resources1));
+
+  // Add registration2.
+  RegistrationData data2;
+  data2.registration_id = 101;
+  data2.scope = GURL("http://example.com/bar");
+  data2.script = GURL("http://example.com/script2.js");
+  data2.version_id = 201;
+  GURL origin2 = data2.scope.GetOrigin();
+
+  Resource resource3 = CreateResource(3, "http://example.com/resource3");
+  Resource resource4 = CreateResource(4, "http://example.com/resource4");
+
+  std::vector<Resource> resources2;
+  resources2.push_back(resource3);
+  resources2.push_back(resource4);
+  EXPECT_TRUE(database->WriteRegistration(data2, resources2));
+
+  // Make sure that registration1 is stored.
+  RegistrationData data_out;
+  std::vector<Resource> resources_out;
+  EXPECT_TRUE(database->ReadRegistration(
+      data1.registration_id, origin1, &data_out, &resources_out));
+  VerifyRegistrationData(data1, data_out);
+  VerifyResourceRecords(resources1, resources_out);
+
+  // Make sure that registration2 is also stored.
+  resources_out.clear();
+  EXPECT_TRUE(database->ReadRegistration(
+      data2.registration_id, origin2, &data_out, &resources_out));
+  VerifyRegistrationData(data2, data_out);
+  VerifyResourceRecords(resources2, resources_out);
+
+  std::set<int64> purgeable_resource_ids;
+  EXPECT_TRUE(database->GetPurgeableResourceIds(&purgeable_resource_ids));
+  EXPECT_TRUE(purgeable_resource_ids.empty());
+
+  // Delete registration1.
+  EXPECT_TRUE(database->DeleteRegistration(data1.registration_id, origin1));
+
+  // Make sure that registration1 is gone.
+  resources_out.clear();
+  EXPECT_FALSE(database->ReadRegistration(
+      data1.registration_id, origin1, &data_out, &resources_out));
+  EXPECT_TRUE(resources_out.empty());
+
+  purgeable_resource_ids.clear();
+  EXPECT_TRUE(database->GetPurgeableResourceIds(&purgeable_resource_ids));
+  EXPECT_EQ(2u, purgeable_resource_ids.size());
+  EXPECT_TRUE(ContainsKey(purgeable_resource_ids, resource1.resource_id));
+  EXPECT_TRUE(ContainsKey(purgeable_resource_ids, resource2.resource_id));
+
+  // Make sure that registration2 is still alive.
+  resources_out.clear();
+  EXPECT_TRUE(database->ReadRegistration(
+      data2.registration_id, origin2, &data_out, &resources_out));
+  VerifyRegistrationData(data2, data_out);
+  VerifyResourceRecords(resources2, resources_out);
 }
 
 TEST(ServiceWorkerDatabaseTest, UncommittedResourceIds) {
@@ -350,4 +627,77 @@
   EXPECT_TRUE(ContainsKey(ids_out, 4));
 }
 
+TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
+  scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
+
+  // Data associated with |origin1| will be removed.
+  GURL origin1("http://example.com");
+  GURL origin2("http://example.org");
+
+  // |origin1| has two registrations.
+  RegistrationData data1;
+  data1.registration_id = 10;
+  data1.scope = URL(origin1, "/foo");
+  data1.script = URL(origin1, "/script1.js");
+  data1.version_id = 100;
+
+  std::vector<Resource> resources1;
+  resources1.push_back(CreateResource(1, URL(origin1, "/resource1")));
+  resources1.push_back(CreateResource(2, URL(origin1, "/resource2")));
+  ASSERT_TRUE(database->WriteRegistration(data1, resources1));
+
+  RegistrationData data2;
+  data2.registration_id = 11;
+  data2.scope = URL(origin1, "/bar");
+  data2.script = URL(origin1, "/script2.js");
+  data2.version_id = 101;
+
+  std::vector<Resource> resources2;
+  resources2.push_back(CreateResource(3, URL(origin1, "/resource3")));
+  resources2.push_back(CreateResource(4, URL(origin1, "/resource4")));
+  ASSERT_TRUE(database->WriteRegistration(data2, resources2));
+
+  // |origin2| has one registration.
+  RegistrationData data3;
+  data3.registration_id = 12;
+  data3.scope = URL(origin2, "/hoge");
+  data3.script = URL(origin2, "/script3.js");
+  data3.version_id = 102;
+
+  std::vector<Resource> resources3;
+  resources3.push_back(CreateResource(5, URL(origin2, "/resource5")));
+  resources3.push_back(CreateResource(6, URL(origin2, "/resource6")));
+  ASSERT_TRUE(database->WriteRegistration(data3, resources3));
+
+  EXPECT_TRUE(database->DeleteAllDataForOrigin(origin1));
+
+  // |origin1| should be removed from the unique origin list.
+  std::set<GURL> unique_origins;
+  EXPECT_TRUE(database->GetOriginsWithRegistrations(&unique_origins));
+  EXPECT_EQ(1u, unique_origins.size());
+  EXPECT_TRUE(ContainsKey(unique_origins, origin2));
+
+  // The registrations for |origin1| should be removed.
+  std::vector<RegistrationData> registrations;
+  EXPECT_TRUE(database->GetRegistrationsForOrigin(origin1, &registrations));
+  EXPECT_TRUE(registrations.empty());
+
+  // The registration for |origin2| should not be removed.
+  RegistrationData data_out;
+  std::vector<Resource> resources_out;
+  EXPECT_TRUE(database->ReadRegistration(
+      data3.registration_id, origin2, &data_out, &resources_out));
+  VerifyRegistrationData(data3, data_out);
+  VerifyResourceRecords(resources3, resources_out);
+
+  // The resources associated with |origin1| should be purgeable.
+  std::set<int64> purgeable_ids_out;
+  EXPECT_TRUE(database->GetPurgeableResourceIds(&purgeable_ids_out));
+  EXPECT_EQ(4u, purgeable_ids_out.size());
+  EXPECT_TRUE(ContainsKey(purgeable_ids_out, 1));
+  EXPECT_TRUE(ContainsKey(purgeable_ids_out, 2));
+  EXPECT_TRUE(ContainsKey(purgeable_ids_out, 3));
+  EXPECT_TRUE(ContainsKey(purgeable_ids_out, 4));
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_disk_cache.cc b/content/browser/service_worker/service_worker_disk_cache.cc
new file mode 100644
index 0000000..a8ca52a
--- /dev/null
+++ b/content/browser/service_worker/service_worker_disk_cache.cc
@@ -0,0 +1,22 @@
+// 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.
+
+#include "content/browser/service_worker/service_worker_disk_cache.h"
+
+namespace content {
+
+ServiceWorkerResponseReader::ServiceWorkerResponseReader(
+    int64 response_id, ServiceWorkerDiskCache* disk_cache)
+    : appcache::AppCacheResponseReader(response_id, 0, disk_cache) {
+}
+
+ServiceWorkerResponseWriter::ServiceWorkerResponseWriter(
+    int64 response_id, ServiceWorkerDiskCache* disk_cache)
+    : appcache::AppCacheResponseWriter(response_id, 0, disk_cache) {
+}
+
+HttpResponseInfoIOBuffer::~HttpResponseInfoIOBuffer() {
+}
+
+}  // namespace content
diff --git a/content/browser/service_worker/service_worker_disk_cache.h b/content/browser/service_worker/service_worker_disk_cache.h
new file mode 100644
index 0000000..c0446c9
--- /dev/null
+++ b/content/browser/service_worker/service_worker_disk_cache.h
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_
+
+#include "content/common/content_export.h"
+#include "webkit/browser/appcache/appcache_disk_cache.h"
+
+namespace content {
+
+// Wholesale reusage of the appcache code for response reading,
+// writing, and storage. See the corresponding class in that
+// library for doc comments and other details.
+// TODO(michaeln): If this reuse sticks, refactor/move the
+// resused classes to a more common location.
+
+class ServiceWorkerDiskCache
+    : public appcache::AppCacheDiskCache {
+};
+
+class ServiceWorkerResponseReader
+    : public appcache::AppCacheResponseReader {
+ protected:
+  // Should only be constructed by the storage class.
+  friend class ServiceWorkerStorage;
+  ServiceWorkerResponseReader(
+      int64 response_id,
+      ServiceWorkerDiskCache* disk_cache);
+};
+
+class ServiceWorkerResponseWriter
+    : public appcache::AppCacheResponseWriter {
+ protected:
+  // Should only be constructed by the storage class.
+  friend class ServiceWorkerStorage;
+  ServiceWorkerResponseWriter(
+      int64 response_id,
+      ServiceWorkerDiskCache* disk_cache);
+};
+
+struct HttpResponseInfoIOBuffer
+    : public appcache::HttpResponseInfoIOBuffer {
+ protected:
+  virtual ~HttpResponseInfoIOBuffer();
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_DISK_CACHE_
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index f36af07..ded0a37 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -98,14 +98,14 @@
                         OnProviderCreated)
     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed,
                         OnProviderDestroyed)
-    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_AddScriptClient,
-                        OnAddScriptClient)
-    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_RemoveScriptClient,
-                        OnRemoveScriptClient)
     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetVersionId,
                         OnSetHostedVersionId)
-    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessage,
-                        OnPostMessage)
+    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker,
+                        OnPostMessageToWorker)
+    IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoaded,
+                        OnWorkerScriptLoaded)
+    IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoadFailed,
+                        OnWorkerScriptLoadFailed)
     IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted,
                         OnWorkerStarted)
     IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped,
@@ -114,8 +114,10 @@
                         OnReportException)
     IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportConsoleMessage,
                         OnReportConsoleMessage)
-    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ServiceWorkerObjectDestroyed,
-                        OnServiceWorkerObjectDestroyed)
+    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount,
+                        OnIncrementServiceWorkerRefCount)
+    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount,
+                        OnDecrementServiceWorkerRefCount)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
@@ -222,30 +224,26 @@
                  request_id));
 }
 
-void ServiceWorkerDispatcherHost::OnPostMessage(
+void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
     int handle_id,
     const base::string16& message,
     const std::vector<int>& sent_message_port_ids) {
   if (!context_ || !ServiceWorkerUtils::IsFeatureEnabled())
     return;
 
-  std::vector<int> new_routing_ids(sent_message_port_ids.size());
-  for (size_t i = 0; i < sent_message_port_ids.size(); ++i) {
-    new_routing_ids[i] = message_port_message_filter_->GetNextRoutingID();
-    MessagePortService::GetInstance()->UpdateMessagePort(
-        sent_message_port_ids[i],
-        message_port_message_filter_,
-        new_routing_ids[i]);
-  }
-
   ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
   if (!handle) {
     BadMessageReceived();
     return;
   }
 
+  std::vector<int> new_routing_ids;
+  message_port_message_filter_->UpdateMessagePortsWithNewRoutes(
+      sent_message_port_ids, &new_routing_ids);
   handle->version()->SendMessage(
-      ServiceWorkerMsg_Message(message, sent_message_port_ids, new_routing_ids),
+      ServiceWorkerMsg_MessageToWorker(message,
+                                       sent_message_port_ids,
+                                       new_routing_ids),
       base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
 }
 
@@ -272,28 +270,6 @@
   context_->RemoveProviderHost(render_process_id_, provider_id);
 }
 
-void ServiceWorkerDispatcherHost::OnAddScriptClient(
-    int thread_id, int provider_id) {
-  if (!context_)
-    return;
-  ServiceWorkerProviderHost* provider_host =
-      context_->GetProviderHost(render_process_id_, provider_id);
-  if (!provider_host)
-    return;
-  provider_host->AddScriptClient(thread_id);
-}
-
-void ServiceWorkerDispatcherHost::OnRemoveScriptClient(
-    int thread_id, int provider_id) {
-  if (!context_)
-    return;
-  ServiceWorkerProviderHost* provider_host =
-      context_->GetProviderHost(render_process_id_, provider_id);
-  if (!provider_host)
-    return;
-  provider_host->RemoveScriptClient(thread_id);
-}
-
 void ServiceWorkerDispatcherHost::OnSetHostedVersionId(
     int provider_id, int64 version_id) {
   if (!context_)
@@ -330,6 +306,21 @@
   RegisterServiceWorkerHandle(handle.Pass());
 }
 
+void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(int embedded_worker_id) {
+  if (!context_)
+    return;
+  context_->embedded_worker_registry()->OnWorkerScriptLoaded(
+      render_process_id_, embedded_worker_id);
+}
+
+void ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed(
+    int embedded_worker_id) {
+  if (!context_)
+    return;
+  context_->embedded_worker_registry()->OnWorkerScriptLoadFailed(
+      render_process_id_, embedded_worker_id);
+}
+
 void ServiceWorkerDispatcherHost::OnWorkerStarted(
     int thread_id, int embedded_worker_id) {
   if (!context_)
@@ -374,9 +365,26 @@
       params.source_url);
 }
 
-void ServiceWorkerDispatcherHost::OnServiceWorkerObjectDestroyed(
+void ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount(
     int handle_id) {
-  handles_.Remove(handle_id);
+  ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
+  if (!handle) {
+    BadMessageReceived();
+    return;
+  }
+  handle->IncrementRefCount();
+}
+
+void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount(
+    int handle_id) {
+  ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
+  if (!handle) {
+    BadMessageReceived();
+    return;
+  }
+  handle->DecrementRefCount();
+  if (handle->HasNoRefCount())
+    handles_.Remove(handle_id);
 }
 
 void ServiceWorkerDispatcherHost::UnregistrationComplete(
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.h b/content/browser/service_worker/service_worker_dispatcher_host.h
index 97b50bd..7301eee 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.h
+++ b/content/browser/service_worker/service_worker_dispatcher_host.h
@@ -47,6 +47,10 @@
 
   void RegisterServiceWorkerHandle(scoped_ptr<ServiceWorkerHandle> handle);
 
+  MessagePortMessageFilter* message_port_message_filter() {
+    return message_port_message_filter_;
+  }
+
  protected:
   virtual ~ServiceWorkerDispatcherHost();
 
@@ -67,9 +71,9 @@
                                  const GURL& pattern);
   void OnProviderCreated(int provider_id);
   void OnProviderDestroyed(int provider_id);
-  void OnAddScriptClient(int thread_id, int provider_id);
-  void OnRemoveScriptClient(int thread_id, int provider_id);
   void OnSetHostedVersionId(int provider_id, int64 version_id);
+  void OnWorkerScriptLoaded(int embedded_worker_id);
+  void OnWorkerScriptLoadFailed(int embedded_worker_id);
   void OnWorkerStarted(int thread_id,
                        int embedded_worker_id);
   void OnWorkerStopped(int embedded_worker_id);
@@ -84,6 +88,11 @@
   void OnPostMessage(int handle_id,
                      const base::string16& message,
                      const std::vector<int>& sent_message_port_ids);
+  void OnIncrementServiceWorkerRefCount(int handle_id);
+  void OnDecrementServiceWorkerRefCount(int handle_id);
+  void OnPostMessageToWorker(int handle_id,
+                             const base::string16& message,
+                             const std::vector<int>& sent_message_port_ids);
   void OnServiceWorkerObjectDestroyed(int handle_id);
 
   // Callbacks from ServiceWorkerContextCore
diff --git a/content/browser/service_worker/service_worker_handle.cc b/content/browser/service_worker/service_worker_handle.cc
index cc57b6f..a07ab9e 100644
--- a/content/browser/service_worker/service_worker_handle.cc
+++ b/content/browser/service_worker/service_worker_handle.cc
@@ -63,6 +63,7 @@
       sender_(sender),
       thread_id_(thread_id),
       handle_id_(context.get() ? context->GetNewServiceWorkerHandleId() : -1),
+      ref_count_(1),
       registration_(registration),
       version_(version) {
   version_->AddListener(this);
@@ -112,4 +113,14 @@
   return info;
 }
 
+void ServiceWorkerHandle::IncrementRefCount() {
+  DCHECK_GT(ref_count_, 0);
+  ++ref_count_;
+}
+
+void ServiceWorkerHandle::DecrementRefCount() {
+  DCHECK_GE(ref_count_, 0);
+  --ref_count_;
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_handle.h b/content/browser/service_worker/service_worker_handle.h
index 2aa7cc0..81d5b35 100644
--- a/content/browser/service_worker/service_worker_handle.h
+++ b/content/browser/service_worker/service_worker_handle.h
@@ -71,11 +71,16 @@
   ServiceWorkerVersion* version() { return version_.get(); }
   int handle_id() const { return handle_id_; }
 
+  bool HasNoRefCount() const { return ref_count_ <= 0; }
+  void IncrementRefCount();
+  void DecrementRefCount();
+
  private:
   base::WeakPtr<ServiceWorkerContextCore> context_;
   IPC::Sender* sender_;  // Not owned, it should always outlive this.
   const int thread_id_;
   const int handle_id_;
+  int ref_count_;  // Created with 1.
   scoped_refptr<ServiceWorkerRegistration> registration_;
   scoped_refptr<ServiceWorkerVersion> version_;
 
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc
index aa874ae..2da7d3e 100644
--- a/content/browser/service_worker/service_worker_provider_host.cc
+++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -5,6 +5,7 @@
 #include "content/browser/service_worker/service_worker_provider_host.h"
 
 #include "base/stl_util.h"
+#include "content/browser/message_port_message_filter.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/browser/service_worker/service_worker_context_request_handler.h"
 #include "content/browser/service_worker/service_worker_controllee_request_handler.h"
@@ -16,6 +17,8 @@
 
 namespace content {
 
+static const int kDocumentMainThreadId = 0;
+
 ServiceWorkerProviderHost::ServiceWorkerProviderHost(
     int process_id, int provider_id,
     base::WeakPtr<ServiceWorkerContextCore> context,
@@ -33,16 +36,6 @@
     pending_version_->RemovePendingControllee(this);
 }
 
-void ServiceWorkerProviderHost::AddScriptClient(int thread_id) {
-  DCHECK(!ContainsKey(script_client_thread_ids_, thread_id));
-  script_client_thread_ids_.insert(thread_id);
-}
-
-void ServiceWorkerProviderHost::RemoveScriptClient(int thread_id) {
-  DCHECK(ContainsKey(script_client_thread_ids_, thread_id));
-  script_client_thread_ids_.erase(thread_id);
-}
-
 void ServiceWorkerProviderHost::SetActiveVersion(
     ServiceWorkerVersion* version) {
   if (version == active_version_)
@@ -57,19 +50,17 @@
   if (!dispatcher_host_)
     return;  // Could be NULL in some tests.
 
-  for (std::set<int>::iterator it = script_client_thread_ids_.begin();
-       it != script_client_thread_ids_.end();
-       ++it) {
-    ServiceWorkerObjectInfo info;
-    if (context_ && version) {
-      scoped_ptr<ServiceWorkerHandle> handle =
-          ServiceWorkerHandle::Create(context_, dispatcher_host_, *it, version);
-      info = handle->GetObjectInfo();
-      dispatcher_host_->RegisterServiceWorkerHandle(handle.Pass());
-    }
-    dispatcher_host_->Send(
-        new ServiceWorkerMsg_SetCurrentServiceWorker(*it, provider_id(), info));
+  ServiceWorkerObjectInfo info;
+  if (context_ && version) {
+    scoped_ptr<ServiceWorkerHandle> handle =
+        ServiceWorkerHandle::Create(context_, dispatcher_host_,
+                                    kDocumentMainThreadId, version);
+    info = handle->GetObjectInfo();
+    dispatcher_host_->RegisterServiceWorkerHandle(handle.Pass());
   }
+  dispatcher_host_->Send(
+      new ServiceWorkerMsg_SetCurrentServiceWorker(
+          kDocumentMainThreadId, provider_id(), info));
 }
 
 void ServiceWorkerProviderHost::SetPendingVersion(
@@ -86,11 +77,7 @@
   if (!dispatcher_host_)
     return;  // Could be NULL in some tests.
 
-  for (std::set<int>::iterator it = script_client_thread_ids_.begin();
-       it != script_client_thread_ids_.end();
-       ++it) {
-    // TODO(kinuko): dispatch pendingchange event to the script clients.
-  }
+  // TODO(kinuko): dispatch pendingchange event to the document.
 }
 
 bool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id) {
@@ -132,4 +119,23 @@
   return scoped_ptr<ServiceWorkerRequestHandler>();
 }
 
+void ServiceWorkerProviderHost::PostMessage(
+    const base::string16& message,
+    const std::vector<int>& sent_message_port_ids) {
+  if (!dispatcher_host_)
+    return;  // Could be NULL in some tests.
+
+  std::vector<int> new_routing_ids;
+  dispatcher_host_->message_port_message_filter()->
+      UpdateMessagePortsWithNewRoutes(sent_message_port_ids,
+                                      &new_routing_ids);
+
+  dispatcher_host_->Send(
+      new ServiceWorkerMsg_MessageToDocument(
+          kDocumentMainThreadId, provider_id(),
+          message,
+          sent_message_port_ids,
+          new_routing_ids));
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h
index 65a8807..5aceebf 100644
--- a/content/browser/service_worker/service_worker_provider_host.h
+++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -6,6 +6,7 @@
 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_
 
 #include <set>
+#include <vector>
 
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
@@ -42,9 +43,6 @@
 
   int process_id() const { return process_id_; }
   int provider_id() const { return provider_id_; }
-  const std::set<int>& script_client_thread_ids() const {
-    return script_client_thread_ids_;
-  }
 
   bool IsHostToRunningServiceWorker() {
     return running_hosted_version_ != NULL;
@@ -71,12 +69,6 @@
   void set_document_url(const GURL& url) { document_url_ = url; }
   const GURL& document_url() const { return document_url_; }
 
-  // Adds and removes script client thread ID, who is listening events
-  // dispatched from ServiceWorker to the document (and any of its dedicated
-  // workers) corresponding to this provider.
-  void AddScriptClient(int thread_id);
-  void RemoveScriptClient(int thread_id);
-
   // Associate |version| to this provider as its '.active' or '.pending'
   // version.
   // Giving NULL to this method will unset the corresponding field.
@@ -92,11 +84,14 @@
   scoped_ptr<ServiceWorkerRequestHandler> CreateRequestHandler(
       ResourceType::Type resource_type);
 
+  // Dispatches message event to the document.
+  void PostMessage(const base::string16& message,
+                   const std::vector<int>& sent_message_port_ids);
+
  private:
   const int process_id_;
   const int provider_id_;
   GURL document_url_;
-  std::set<int> script_client_thread_ids_;
   scoped_refptr<ServiceWorkerVersion> active_version_;
   scoped_refptr<ServiceWorkerVersion> pending_version_;
   scoped_refptr<ServiceWorkerVersion> running_hosted_version_;
diff --git a/content/browser/service_worker/service_worker_provider_host_unittest.cc b/content/browser/service_worker/service_worker_provider_host_unittest.cc
index 03c513a..5da54fb 100644
--- a/content/browser/service_worker/service_worker_provider_host_unittest.cc
+++ b/content/browser/service_worker/service_worker_provider_host_unittest.cc
@@ -25,6 +25,7 @@
   virtual void SetUp() OVERRIDE {
     context_.reset(new ServiceWorkerContextCore(
         base::FilePath(),
+        base::MessageLoopProxy::current(),
         NULL,
         NULL,
         scoped_ptr<ServiceWorkerProcessManager>()));
diff --git a/content/browser/service_worker/service_worker_read_from_cache_job.cc b/content/browser/service_worker/service_worker_read_from_cache_job.cc
new file mode 100644
index 0000000..bb2a39f
--- /dev/null
+++ b/content/browser/service_worker/service_worker_read_from_cache_job.cc
@@ -0,0 +1,181 @@
+// 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.
+
+#include "content/browser/service_worker/service_worker_read_from_cache_job.h"
+
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_disk_cache.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_util.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_status.h"
+
+namespace content {
+
+ServiceWorkerReadFromCacheJob::ServiceWorkerReadFromCacheJob(
+    net::URLRequest* request,
+    net::NetworkDelegate* network_delegate,
+    base::WeakPtr<ServiceWorkerContextCore> context,
+    int64 response_id)
+    : net::URLRequestJob(request, network_delegate),
+      context_(context),
+      response_id_(response_id),
+      has_been_killed_(false),
+      weak_factory_(this) {
+}
+
+ServiceWorkerReadFromCacheJob::~ServiceWorkerReadFromCacheJob() {
+}
+
+void ServiceWorkerReadFromCacheJob::Start() {
+  if (!context_) {
+    NotifyStartError(net::URLRequestStatus(
+        net::URLRequestStatus::FAILED, net::ERR_FAILED));
+    return;
+  }
+
+  // Create a response reader and start reading the headers,
+  // we'll continue when thats done.
+  reader_ = context_->storage()->CreateResponseReader(response_id_);
+  http_info_io_buffer_ = new HttpResponseInfoIOBuffer;
+  reader_->ReadInfo(
+      http_info_io_buffer_,
+      base::Bind(&ServiceWorkerReadFromCacheJob::OnReadInfoComplete,
+                 weak_factory_.GetWeakPtr()));
+  SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
+}
+
+void ServiceWorkerReadFromCacheJob::Kill() {
+  if (has_been_killed_)
+    return;
+  weak_factory_.InvalidateWeakPtrs();
+  has_been_killed_ = true;
+  reader_.reset();
+  context_.reset();
+  http_info_io_buffer_ = NULL;
+  http_info_.reset();
+  range_response_info_.reset();
+  net::URLRequestJob::Kill();
+}
+
+net::LoadState ServiceWorkerReadFromCacheJob::GetLoadState() const {
+  NOTIMPLEMENTED();
+  return net::LOAD_STATE_WAITING_FOR_APPCACHE;
+}
+
+bool ServiceWorkerReadFromCacheJob::GetCharset(std::string* charset) {
+  if (!http_info())
+    return false;
+  return http_info()->headers->GetCharset(charset);
+}
+
+bool ServiceWorkerReadFromCacheJob::GetMimeType(std::string* mime_type) const {
+  if (!http_info())
+    return false;
+  return http_info()->headers->GetMimeType(mime_type);
+}
+
+void ServiceWorkerReadFromCacheJob::GetResponseInfo(
+    net::HttpResponseInfo* info) {
+  if (!http_info())
+    return;
+  *info = *http_info();
+}
+
+int ServiceWorkerReadFromCacheJob::GetResponseCode() const {
+  if (!http_info())
+    return -1;
+  return http_info()->headers->response_code();
+}
+
+void ServiceWorkerReadFromCacheJob::SetExtraRequestHeaders(
+      const net::HttpRequestHeaders& headers) {
+  std::string value;
+  std::vector<net::HttpByteRange> ranges;
+  if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &value) ||
+      !net::HttpUtil::ParseRangeHeader(value, &ranges)) {
+    return;
+  }
+
+  // If multiple ranges are requested, we play dumb and
+  // return the entire response with 200 OK.
+  if (ranges.size() == 1U)
+    range_requested_ = ranges[0];
+}
+
+bool ServiceWorkerReadFromCacheJob::ReadRawData(
+    net::IOBuffer* buf,
+    int buf_size,
+    int *bytes_read) {
+  DCHECK_NE(buf_size, 0);
+  DCHECK(bytes_read);
+  DCHECK(!reader_->IsReadPending());
+  reader_->ReadData(
+      buf, buf_size, base::Bind(&ServiceWorkerReadFromCacheJob::OnReadComplete,
+                                weak_factory_.GetWeakPtr()));
+  SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
+  return false;
+}
+
+const net::HttpResponseInfo* ServiceWorkerReadFromCacheJob::http_info() const {
+  if (!http_info_)
+    return NULL;
+  if (range_response_info_)
+    return range_response_info_.get();
+  return http_info_.get();
+}
+
+void ServiceWorkerReadFromCacheJob::OnReadInfoComplete(int result) {
+  scoped_refptr<ServiceWorkerReadFromCacheJob> protect(this);
+  if (!http_info_io_buffer_->http_info) {
+    DCHECK(result < 0);
+    NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
+    return;
+  }
+  DCHECK(result >= 0);
+  SetStatus(net::URLRequestStatus());  // Clear the IO_PENDING status
+  http_info_.reset(http_info_io_buffer_->http_info.release());
+  if (is_range_request())
+    SetupRangeResponse(http_info_io_buffer_->response_data_size);
+  http_info_io_buffer_ = NULL;
+  NotifyHeadersComplete();
+}
+
+void ServiceWorkerReadFromCacheJob::SetupRangeResponse(int resource_size) {
+  DCHECK(is_range_request() && http_info_.get() && reader_.get());
+  if (resource_size < 0 || !range_requested_.ComputeBounds(resource_size)) {
+    range_requested_ = net::HttpByteRange();
+    return;
+  }
+
+  DCHECK(range_requested_.IsValid());
+  int offset = static_cast<int>(range_requested_.first_byte_position());
+  int length = static_cast<int>(range_requested_.last_byte_position() -
+                                range_requested_.first_byte_position() + 1);
+
+  // Tell the reader about the range to read.
+  reader_->SetReadRange(offset, length);
+
+  // Make a copy of the full response headers and fix them up
+  // for the range we'll be returning.
+  range_response_info_.reset(new net::HttpResponseInfo(*http_info_));
+  net::HttpResponseHeaders* headers = range_response_info_->headers.get();
+  headers->UpdateWithNewRange(
+      range_requested_, resource_size, true /* replace status line */);
+}
+
+void ServiceWorkerReadFromCacheJob::OnReadComplete(int result) {
+  if (result == 0)
+    NotifyDone(net::URLRequestStatus());
+  else if (result < 0)
+    NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
+  else
+    SetStatus(net::URLRequestStatus());  // Clear the IO_PENDING status
+  NotifyReadComplete(result);
+}
+
+}  // namespace content
diff --git a/content/browser/service_worker/service_worker_read_from_cache_job.h b/content/browser/service_worker/service_worker_read_from_cache_job.h
new file mode 100644
index 0000000..6d61c3b
--- /dev/null
+++ b/content/browser/service_worker/service_worker_read_from_cache_job.h
@@ -0,0 +1,73 @@
+// 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.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_READ_FROM_CACHE_JOB_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_READ_FROM_CACHE_JOB_
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "content/browser/service_worker/service_worker_disk_cache.h"
+#include "content/common/content_export.h"
+#include "net/http/http_byte_range.h"
+#include "net/url_request/url_request_job.h"
+
+namespace content {
+
+class ServiceWorkerContextCore;
+class ServiceWorkerResponseReader;
+
+// A URLRequestJob derivative used to retrieve script resources
+// from the service workers script cache. It uses a response reader
+// and pipes the response to the consumer of this url request job.
+class CONTENT_EXPORT ServiceWorkerReadFromCacheJob
+    : public net::URLRequestJob {
+ public:
+  ServiceWorkerReadFromCacheJob(
+      net::URLRequest* request,
+      net::NetworkDelegate* network_delegate,
+      base::WeakPtr<ServiceWorkerContextCore> context,
+      int64 response_id);
+
+ private:
+  virtual ~ServiceWorkerReadFromCacheJob();
+
+  // net::URLRequestJob overrides
+  virtual void Start() OVERRIDE;
+  virtual void Kill() OVERRIDE;
+  virtual net::LoadState GetLoadState() const OVERRIDE;
+  virtual bool GetCharset(std::string* charset) OVERRIDE;
+  virtual bool GetMimeType(std::string* mime_type) const OVERRIDE;
+  virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE;
+  virtual int GetResponseCode() const OVERRIDE;
+  virtual void SetExtraRequestHeaders(
+      const net::HttpRequestHeaders& headers) OVERRIDE;
+  virtual bool ReadRawData(net::IOBuffer* buf,
+                           int buf_size,
+                           int *bytes_read) OVERRIDE;
+
+  // Reader completion callbacks.
+  void OnReadInfoComplete(int result);
+  void OnReadComplete(int result);
+
+  // Helpers
+  const net::HttpResponseInfo* http_info() const;
+  bool is_range_request() const { return range_requested_.IsValid(); }
+  void SetupRangeResponse(int response_data_size);
+
+  base::WeakPtr<ServiceWorkerContextCore> context_;
+  int64 response_id_;
+  scoped_ptr<ServiceWorkerResponseReader> reader_;
+  scoped_refptr<HttpResponseInfoIOBuffer> http_info_io_buffer_;
+  scoped_ptr<net::HttpResponseInfo> http_info_;
+  net::HttpByteRange range_requested_;
+  scoped_ptr<net::HttpResponseInfo> range_response_info_;
+  bool has_been_killed_;
+  base::WeakPtrFactory<ServiceWorkerReadFromCacheJob> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerReadFromCacheJob);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_READ_FROM_CACHE_JOB_
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc
index 6819305..4cb4c91 100644
--- a/content/browser/service_worker/service_worker_register_job.cc
+++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -183,6 +183,7 @@
   // when it no longer has any controllees.
   context_->storage()->DeleteRegistration(
       existing_registration->id(),
+      existing_registration->script_url().GetOrigin(),
       base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue,
                  weak_factory_.GetWeakPtr()));
 }
@@ -367,6 +368,7 @@
     if (registration() && !registration()->active_version()) {
       context_->storage()->DeleteRegistration(
           registration()->id(),
+          registration()->script_url().GetOrigin(),
           base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
     }
     if (!is_promise_resolved_)
diff --git a/content/browser/service_worker/service_worker_registration_unittest.cc b/content/browser/service_worker/service_worker_registration_unittest.cc
index d1015b2..311e114 100644
--- a/content/browser/service_worker/service_worker_registration_unittest.cc
+++ b/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "content/browser/browser_thread_impl.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -23,12 +24,18 @@
   virtual void SetUp() OVERRIDE {
     context_.reset(new ServiceWorkerContextCore(
         base::FilePath(),
+        base::MessageLoopProxy::current(),
         NULL,
         NULL,
         scoped_ptr<ServiceWorkerProcessManager>()));
     context_ptr_ = context_->AsWeakPtr();
   }
 
+  virtual void TearDown() OVERRIDE {
+    context_.reset();
+    base::RunLoop().RunUntilIdle();
+  }
+
  protected:
   scoped_ptr<ServiceWorkerContextCore> context_;
   base::WeakPtr<ServiceWorkerContextCore> context_ptr_;
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc
index 7d1712f..1a3dd36 100644
--- a/content/browser/service_worker/service_worker_storage.cc
+++ b/content/browser/service_worker/service_worker_storage.cc
@@ -5,19 +5,37 @@
 #include "content/browser/service_worker/service_worker_storage.h"
 
 #include <string>
+
+#include "base/bind_helpers.h"
 #include "base/message_loop/message_loop.h"
+#include "base/sequenced_task_runner.h"
+#include "base/task_runner_util.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_disk_cache.h"
 #include "content/browser/service_worker/service_worker_info.h"
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_utils.h"
 #include "content/browser/service_worker/service_worker_version.h"
+#include "content/common/service_worker/service_worker_types.h"
 #include "content/public/browser/browser_thread.h"
+#include "net/base/net_errors.h"
 #include "webkit/browser/quota/quota_manager_proxy.h"
 
 namespace content {
 
 namespace {
 
+typedef base::Callback<void(
+    ServiceWorkerStorage::InitialData* data,
+    bool success)> InitializeCallback;
+typedef base::Callback<void(
+    const ServiceWorkerDatabase::RegistrationData& data,
+    const std::vector<ServiceWorkerDatabase::ResourceRecord>& resources,
+    ServiceWorkerStatusCode status)> ReadRegistrationCallback;
+typedef base::Callback<void(
+    bool origin_is_deletable,
+    ServiceWorkerStatusCode status)> DeleteRegistrationCallback;
+
 void RunSoon(const tracked_objects::Location& from_here,
              const base::Closure& closure) {
   base::MessageLoop::current()->PostTask(from_here, closure);
@@ -39,91 +57,191 @@
 }
 
 const base::FilePath::CharType kServiceWorkerDirectory[] =
-    FILE_PATH_LITERAL("ServiceWorker");
+    FILE_PATH_LITERAL("Service Worker");
+const base::FilePath::CharType kDatabaseName[] =
+    FILE_PATH_LITERAL("Database");
+
+const int kMaxMemDiskCacheSize = 10 * 1024 * 1024;
+
+void EmptyCompletionCallback(int) {}
+
+void ReadInitialDataFromDB(
+    ServiceWorkerDatabase* database,
+    scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+    const InitializeCallback& callback) {
+  DCHECK(database);
+  ServiceWorkerStorage::InitialData* data =
+      new ServiceWorkerStorage::InitialData();
+  bool success =
+      database->GetNextAvailableIds(&data->next_registration_id,
+                                    &data->next_version_id,
+                                    &data->next_resource_id) &&
+      database->GetOriginsWithRegistrations(&data->origins);
+  original_task_runner->PostTask(
+      FROM_HERE, base::Bind(callback, base::Owned(data), success));
+}
+
+void ReadRegistrationFromDB(
+    ServiceWorkerDatabase* database,
+    scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+    int64 registration_id,
+    const GURL& origin,
+    const ReadRegistrationCallback& callback) {
+  DCHECK(database);
+  ServiceWorkerDatabase::RegistrationData data;
+  std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
+
+  // TODO(nhiroki): The database should return more detailed status like
+  // ServiceWorkerStatusCode instead of bool value.
+  ServiceWorkerStatusCode status = SERVICE_WORKER_OK;
+  if (!database->ReadRegistration(registration_id, origin, &data, &resources)) {
+    status = database->is_disabled() ? SERVICE_WORKER_ERROR_FAILED
+                                     : SERVICE_WORKER_ERROR_NOT_FOUND;
+  }
+  original_task_runner->PostTask(
+      FROM_HERE, base::Bind(callback, data, resources, status));
+}
+
+void DeleteRegistrationFromDB(
+    ServiceWorkerDatabase* database,
+    scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+    int64 registration_id,
+    const GURL& origin,
+    const DeleteRegistrationCallback& callback) {
+  DCHECK(database);
+  if (!database->DeleteRegistration(registration_id, origin)) {
+    original_task_runner->PostTask(
+        FROM_HERE, base::Bind(callback, false, SERVICE_WORKER_ERROR_FAILED));
+    return;
+  }
+
+  // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the
+  // unique origin list.
+  std::vector<ServiceWorkerDatabase::RegistrationData> registrations;
+  if (!database->GetRegistrationsForOrigin(origin, &registrations)) {
+    original_task_runner->PostTask(
+        FROM_HERE, base::Bind(callback, false, SERVICE_WORKER_ERROR_FAILED));
+    return;
+  }
+
+  bool deletable = registrations.empty();
+  original_task_runner->PostTask(
+      FROM_HERE, base::Bind(callback, deletable, SERVICE_WORKER_OK));
+}
+
+void UpdateToActiveStateInDB(
+    ServiceWorkerDatabase* database,
+    scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+    int64 registration_id,
+    const GURL& origin,
+    const ServiceWorkerStorage::StatusCallback& callback) {
+  DCHECK(database);
+
+  // TODO(nhiroki): The database should return more detailed status like
+  // ServiceWorkerStatusCode instead of bool value.
+  ServiceWorkerStatusCode status = SERVICE_WORKER_OK;
+  if (!database->UpdateVersionToActive(registration_id, origin)) {
+    status = database->is_disabled() ? SERVICE_WORKER_ERROR_FAILED
+                                     : SERVICE_WORKER_ERROR_NOT_FOUND;
+  }
+  original_task_runner->PostTask(FROM_HERE, base::Bind(callback, status));
+}
 
 }  // namespace
 
+ServiceWorkerStorage::InitialData::InitialData()
+    : next_registration_id(kInvalidServiceWorkerRegistrationId),
+      next_version_id(kInvalidServiceWorkerVersionId),
+      next_resource_id(kInvalidServiceWorkerResourceId) {
+}
+
+ServiceWorkerStorage::InitialData::~InitialData() {
+}
+
 ServiceWorkerStorage::ServiceWorkerStorage(
     const base::FilePath& path,
     base::WeakPtr<ServiceWorkerContextCore> context,
+    base::SequencedTaskRunner* database_task_runner,
     quota::QuotaManagerProxy* quota_manager_proxy)
-    : last_registration_id_(0),
-      last_version_id_(0),
-      last_resource_id_(0),
-      simulated_lazy_initted_(false),
+    : next_registration_id_(kInvalidServiceWorkerRegistrationId),
+      next_version_id_(kInvalidServiceWorkerVersionId),
+      next_resource_id_(kInvalidServiceWorkerResourceId),
+      state_(UNINITIALIZED),
       context_(context),
-      quota_manager_proxy_(quota_manager_proxy) {
-  if (!path.empty())
+      database_task_runner_(database_task_runner),
+      quota_manager_proxy_(quota_manager_proxy),
+      weak_factory_(this) {
+  if (!path.empty()) {
     path_ = path.Append(kServiceWorkerDirectory);
+    database_.reset(new ServiceWorkerDatabase(path_.Append(kDatabaseName)));
+  } else {
+    // Create an in-memory database.
+    database_.reset(new ServiceWorkerDatabase(base::FilePath()));
+  }
 }
 
 ServiceWorkerStorage::~ServiceWorkerStorage() {
+  weak_factory_.InvalidateWeakPtrs();
+  database_task_runner_->DeleteSoon(FROM_HERE, database_.release());
 }
 
 void ServiceWorkerStorage::FindRegistrationForPattern(
     const GURL& scope,
     const FindRegistrationCallback& callback) {
-  simulated_lazy_initted_ = true;
   scoped_refptr<ServiceWorkerRegistration> null_registration;
-  if (!context_) {
-    CompleteFindSoon(
-        FROM_HERE, null_registration, SERVICE_WORKER_ERROR_FAILED, callback);
+  if (!LazyInitialize(base::Bind(
+          &ServiceWorkerStorage::FindRegistrationForPattern,
+          weak_factory_.GetWeakPtr(), scope, callback))) {
+    if (state_ != INITIALIZING || !context_) {
+      CompleteFindSoon(FROM_HERE, null_registration,
+                       SERVICE_WORKER_ERROR_FAILED, callback);
+    }
     return;
   }
+  DCHECK_EQ(INITIALIZED, state_);
 
-  scoped_refptr<ServiceWorkerRegistration> installing_registration =
-      FindInstallingRegistrationForPattern(scope);
-  if (installing_registration) {
-    CompleteFindSoon(
-        FROM_HERE, installing_registration, SERVICE_WORKER_OK, callback);
-    return;
-  }
-
-  // See if there are any registrations for the origin.
-  OriginRegistrationsMap::const_iterator
-      found = stored_registrations_.find(scope.GetOrigin());
-  if (found == stored_registrations_.end()) {
+  // See if there are any stored registrations for the origin.
+  if (!ContainsKey(registered_origins_, scope.GetOrigin())) {
+    // Look for something currently being installed.
+    scoped_refptr<ServiceWorkerRegistration> installing_registration =
+        FindInstallingRegistrationForPattern(scope);
+    if (installing_registration) {
+      CompleteFindSoon(
+          FROM_HERE, installing_registration, SERVICE_WORKER_OK, callback);
+      return;
+    }
     CompleteFindSoon(
         FROM_HERE, null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
     return;
   }
 
-  // Find one with a matching scope.
-  for (RegistrationsMap::const_iterator it = found->second.begin();
-       it != found->second.end(); ++it) {
-    if (scope == it->second.scope) {
-      const ServiceWorkerDatabase::RegistrationData* data = &(it->second);
-      scoped_refptr<ServiceWorkerRegistration> registration =
-          context_->GetLiveRegistration(data->registration_id);
-      if (registration) {
-        CompleteFindSoon(FROM_HERE, registration, SERVICE_WORKER_OK, callback);
-        return;
-      }
-
-      registration = CreateRegistration(data);
-      CompleteFindSoon(FROM_HERE, registration, SERVICE_WORKER_OK, callback);
-      return;
-    }
-  }
-
-  CompleteFindSoon(
-      FROM_HERE, null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
+  RegistrationList* registrations = new RegistrationList();
+  PostTaskAndReplyWithResult(
+      database_task_runner_,
+      FROM_HERE,
+      base::Bind(&ServiceWorkerDatabase::GetRegistrationsForOrigin,
+                 base::Unretained(database_.get()),
+                 scope.GetOrigin(), base::Unretained(registrations)),
+      base::Bind(&ServiceWorkerStorage::DidGetRegistrationsForPattern,
+                 weak_factory_.GetWeakPtr(), scope, callback,
+                 base::Owned(registrations)));
 }
 
 void ServiceWorkerStorage::FindRegistrationForDocument(
     const GURL& document_url,
     const FindRegistrationCallback& callback) {
-  simulated_lazy_initted_ = true;
   scoped_refptr<ServiceWorkerRegistration> null_registration;
-  if (!context_) {
-    CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback);
+  if (!LazyInitialize(base::Bind(
+          &ServiceWorkerStorage::FindRegistrationForDocument,
+          weak_factory_.GetWeakPtr(), document_url, callback))) {
+    if (state_ != INITIALIZING || !context_)
+      CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback);
     return;
   }
+  DCHECK_EQ(INITIALIZED, state_);
 
-  // See if there are any registrations for the origin.
-  OriginRegistrationsMap::const_iterator
-      found = stored_registrations_.find(document_url.GetOrigin());
-  if (found == stored_registrations_.end()) {
+  // See if there are any stored registrations for the origin.
+  if (!ContainsKey(registered_origins_, document_url.GetOrigin())) {
     // Look for something currently being installed.
     scoped_refptr<ServiceWorkerRegistration> installing_registration =
         FindInstallingRegistrationForDocument(document_url);
@@ -131,126 +249,92 @@
       CompleteFindNow(installing_registration, SERVICE_WORKER_OK, callback);
       return;
     }
-
-    // Return syncly to simulate this class having an in memory map of
-    // origins with registrations.
-    CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_NOT_FOUND,
-                    callback);
+    CompleteFindNow(
+        null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
     return;
   }
 
-  // Find one with a pattern match.
-  for (RegistrationsMap::const_iterator it = found->second.begin();
-       it != found->second.end(); ++it) {
-    // TODO(michaeln): if there are multiple matches the one with
-    // the longest scope should win.
-    if (ServiceWorkerUtils::ScopeMatches(it->second.scope, document_url)) {
-      const ServiceWorkerDatabase::RegistrationData* data = &(it->second);
-
-      // If its in the live map, return syncly to simulate this class having
-      // iterated over the values in that map instead of reading the db.
-      scoped_refptr<ServiceWorkerRegistration> registration =
-          context_->GetLiveRegistration(data->registration_id);
-      if (registration) {
-        CompleteFindNow(registration, SERVICE_WORKER_OK, callback);
-        return;
-      }
-
-      // If we have to create a new instance, return it asyncly to simulate
-      // having had to retreive the RegistrationData from the db.
-      registration = CreateRegistration(data);
-      CompleteFindSoon(FROM_HERE, registration, SERVICE_WORKER_OK, callback);
-      return;
-    }
-  }
-
-  // Look for something currently being installed.
-  // TODO(michaeln): Should be mixed in with the stored registrations
-  // for this test.
-  scoped_refptr<ServiceWorkerRegistration> installing_registration =
-      FindInstallingRegistrationForDocument(document_url);
-  if (installing_registration) {
-    CompleteFindSoon(
-        FROM_HERE, installing_registration, SERVICE_WORKER_OK, callback);
-    return;
-  }
-
-  // Return asyncly to simulate having had to look in the db since this
-  // origin does have some registations.
-  CompleteFindSoon(
-      FROM_HERE, null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
+  RegistrationList* registrations = new RegistrationList();
+  PostTaskAndReplyWithResult(
+      database_task_runner_,
+      FROM_HERE,
+      base::Bind(&ServiceWorkerDatabase::GetRegistrationsForOrigin,
+                 base::Unretained(database_.get()),
+                 document_url.GetOrigin(), base::Unretained(registrations)),
+      base::Bind(&ServiceWorkerStorage::DidGetRegistrationsForDocument,
+                 weak_factory_.GetWeakPtr(), document_url, callback,
+                 base::Owned(registrations)));
 }
 
 void ServiceWorkerStorage::FindRegistrationForId(
     int64 registration_id,
+    const GURL& origin,
     const FindRegistrationCallback& callback) {
-  simulated_lazy_initted_ = true;
   scoped_refptr<ServiceWorkerRegistration> null_registration;
-  if (!context_) {
-    CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback);
+  if (!LazyInitialize(base::Bind(
+          &ServiceWorkerStorage::FindRegistrationForId,
+          weak_factory_.GetWeakPtr(), registration_id, origin, callback))) {
+    if (state_ != INITIALIZING || !context_)
+      CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback);
     return;
   }
-  scoped_refptr<ServiceWorkerRegistration> installing_registration =
-      FindInstallingRegistrationForId(registration_id);
-  if (installing_registration) {
-    CompleteFindNow(installing_registration, SERVICE_WORKER_OK, callback);
+  DCHECK_EQ(INITIALIZED, state_);
+
+  // See if there are any stored registrations for the origin.
+  if (!ContainsKey(registered_origins_, origin)) {
+    // Look for somthing currently being installed.
+    scoped_refptr<ServiceWorkerRegistration> installing_registration =
+        FindInstallingRegistrationForId(registration_id);
+    if (installing_registration) {
+      CompleteFindNow(installing_registration, SERVICE_WORKER_OK, callback);
+      return;
+    }
+    CompleteFindNow(
+        null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback);
     return;
   }
-  RegistrationPtrMap::const_iterator found =
-      registrations_by_id_.find(registration_id);
-  if (found == registrations_by_id_.end()) {
-    CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_NOT_FOUND,
-                    callback);
-    return;
-  }
+
   scoped_refptr<ServiceWorkerRegistration> registration =
       context_->GetLiveRegistration(registration_id);
   if (registration) {
     CompleteFindNow(registration, SERVICE_WORKER_OK, callback);
     return;
   }
-  registration = CreateRegistration(found->second);
-  CompleteFindSoon(FROM_HERE, registration, SERVICE_WORKER_OK, callback);
+
+  database_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&ReadRegistrationFromDB,
+                 database_.get(),
+                 base::MessageLoopProxy::current(),
+                 registration_id, origin,
+                 base::Bind(&ServiceWorkerStorage::DidReadRegistrationForId,
+                            weak_factory_.GetWeakPtr(), callback)));
 }
 
 void ServiceWorkerStorage::GetAllRegistrations(
     const GetAllRegistrationInfosCallback& callback) {
-  simulated_lazy_initted_ = true;
-  std::vector<ServiceWorkerRegistrationInfo> registrations;
-  if (!context_) {
-    RunSoon(FROM_HERE, base::Bind(callback, registrations));
+  if (!LazyInitialize(base::Bind(
+          &ServiceWorkerStorage::GetAllRegistrations,
+          weak_factory_.GetWeakPtr(), callback))) {
+    if (state_ != INITIALIZING || !context_) {
+      RunSoon(FROM_HERE, base::Bind(
+          callback, std::vector<ServiceWorkerRegistrationInfo>()));
+    }
     return;
   }
+  DCHECK_EQ(INITIALIZED, state_);
 
-  // Add all stored registrations.
-  for (RegistrationPtrMap::const_iterator it = registrations_by_id_.begin();
-       it != registrations_by_id_.end(); ++it) {
-    ServiceWorkerRegistration* registration =
-        context_->GetLiveRegistration(it->first);
-    if (registration) {
-      registrations.push_back(registration->GetInfo());
-      continue;
-    }
-    ServiceWorkerRegistrationInfo info;
-    info.pattern = it->second->scope;
-    info.script_url = it->second->script;
-    info.active_version.is_null = false;
-    if (it->second->is_active)
-      info.active_version.status = ServiceWorkerVersion::ACTIVE;
-    else
-      info.active_version.status = ServiceWorkerVersion::INSTALLED;
-    registrations.push_back(info);
-  }
-
-  // Add unstored registrations that are being installed.
-  for (RegistrationRefsById::const_iterator it =
-           installing_registrations_.begin();
-       it != installing_registrations_.end(); ++it) {
-    if (registrations_by_id_.find(it->first) == registrations_by_id_.end())
-      registrations.push_back(it->second->GetInfo());
-  }
-
-  RunSoon(FROM_HERE, base::Bind(callback, registrations));
+  RegistrationList* registrations = new RegistrationList;
+  PostTaskAndReplyWithResult(
+      database_task_runner_,
+      FROM_HERE,
+      base::Bind(&ServiceWorkerDatabase::GetAllRegistrations,
+                 base::Unretained(database_.get()),
+                 base::Unretained(registrations)),
+      base::Bind(&ServiceWorkerStorage::DidGetAllRegistrations,
+                 weak_factory_.GetWeakPtr(),
+                 callback,
+                 base::Owned(registrations)));
 }
 
 void ServiceWorkerStorage::StoreRegistration(
@@ -259,17 +343,14 @@
     const StatusCallback& callback) {
   DCHECK(registration);
   DCHECK(version);
-  DCHECK(simulated_lazy_initted_);
-  if (!context_) {
+
+  DCHECK(state_ == INITIALIZED || state_ == DISABLED);
+  if (state_ != INITIALIZED || !context_) {
     RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
     return;
   }
 
-  // Keep a database struct in the storage map.
-  RegistrationsMap& storage_map =
-      stored_registrations_[registration->script_url().GetOrigin()];
-  ServiceWorkerDatabase::RegistrationData& data =
-      storage_map[registration->id()];
+  ServiceWorkerDatabase::RegistrationData data;
   data.registration_id = registration->id();
   data.scope = registration->pattern();
   data.script = registration->script_url();
@@ -278,70 +359,95 @@
   data.last_update_check = base::Time::Now();
   data.is_active = false;  // initially stored in the waiting state
 
-  // Keep a seperate map of ptrs keyed by id only.
-  registrations_by_id_[registration->id()] = &storage_map[registration->id()];
-
-  RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_OK));
+  ResourceList resources;
+  PostTaskAndReplyWithResult(
+      database_task_runner_,
+      FROM_HERE,
+      base::Bind(&ServiceWorkerDatabase::WriteRegistration,
+                 base::Unretained(database_.get()), data, resources),
+      base::Bind(&ServiceWorkerStorage::DidStoreRegistration,
+                 weak_factory_.GetWeakPtr(),
+                 registration->script_url().GetOrigin(),
+                 callback));
 }
 
- void ServiceWorkerStorage::UpdateToActiveState(
-      ServiceWorkerRegistration* registration,
-      const StatusCallback& callback) {
-  DCHECK(simulated_lazy_initted_);
-  if (!context_) {
+void ServiceWorkerStorage::UpdateToActiveState(
+    ServiceWorkerRegistration* registration,
+    const StatusCallback& callback) {
+  DCHECK(registration);
+
+  DCHECK(state_ == INITIALIZED || state_ == DISABLED);
+  if (state_ != INITIALIZED || !context_) {
     RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
     return;
   }
 
-  RegistrationPtrMap::const_iterator
-       found = registrations_by_id_.find(registration->id());
-  if (found == registrations_by_id_.end()) {
-    RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND));
-    return;
-  }
-  DCHECK(!found->second->is_active);
-  found->second->is_active = true;
-  RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_OK));
+  database_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&UpdateToActiveStateInDB,
+                 database_.get(),
+                 base::MessageLoopProxy::current(),
+                 registration->id(),
+                 registration->script_url().GetOrigin(),
+                 callback));
 }
 
 void ServiceWorkerStorage::DeleteRegistration(
     int64 registration_id,
+    const GURL& origin,
     const StatusCallback& callback) {
-  DCHECK(simulated_lazy_initted_);
-  RegistrationPtrMap::iterator
-      found = registrations_by_id_.find(registration_id);
-  if (found == registrations_by_id_.end()) {
-    RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND));
+  DCHECK(state_ == INITIALIZED || state_ == DISABLED);
+  if (state_ != INITIALIZED || !context_) {
+    RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
     return;
   }
 
-  GURL origin = found->second->script.GetOrigin();
-  stored_registrations_[origin].erase(registration_id);
-  if (stored_registrations_[origin].empty())
-    stored_registrations_.erase(origin);
+  database_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&DeleteRegistrationFromDB,
+                 database_.get(),
+                 base::MessageLoopProxy::current(),
+                 registration_id, origin,
+                 base::Bind(&ServiceWorkerStorage::DidDeleteRegistration,
+                            weak_factory_.GetWeakPtr(), origin, callback)));
 
-  registrations_by_id_.erase(found);
-
-  RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_OK));
   // TODO(michaeln): Either its instance should also be
   // removed from liveregistrations map or the live object
   // should marked as deleted in some way and not 'findable'
   // thereafter.
 }
 
+scoped_ptr<ServiceWorkerResponseReader>
+ServiceWorkerStorage::CreateResponseReader(int64 response_id) {
+  return make_scoped_ptr(
+      new ServiceWorkerResponseReader(response_id, disk_cache()));
+}
+
+scoped_ptr<ServiceWorkerResponseWriter>
+ServiceWorkerStorage::CreateResponseWriter(int64 response_id) {
+  return make_scoped_ptr(
+      new ServiceWorkerResponseWriter(response_id, disk_cache()));
+}
+
 int64 ServiceWorkerStorage::NewRegistrationId() {
-  DCHECK(simulated_lazy_initted_);
-  return ++last_registration_id_;
+  if (state_ == DISABLED)
+    return kInvalidServiceWorkerRegistrationId;
+  DCHECK_EQ(INITIALIZED, state_);
+  return next_registration_id_++;
 }
 
 int64 ServiceWorkerStorage::NewVersionId() {
-  DCHECK(simulated_lazy_initted_);
-  return ++last_version_id_;
+  if (state_ == DISABLED)
+    return kInvalidServiceWorkerVersionId;
+  DCHECK_EQ(INITIALIZED, state_);
+  return next_version_id_++;
 }
 
 int64 ServiceWorkerStorage::NewResourceId() {
-  DCHECK(simulated_lazy_initted_);
-  return ++last_resource_id_;
+  if (state_ == DISABLED)
+    return kInvalidServiceWorkerResourceId;
+  DCHECK_EQ(INITIALIZED, state_);
+  return next_resource_id_++;
 }
 
 void ServiceWorkerStorage::NotifyInstallingRegistration(
@@ -354,19 +460,244 @@
   installing_registrations_.erase(registration->id());
 }
 
+bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) {
+  if (!context_)
+    return false;
+
+  switch (state_) {
+    case INITIALIZED:
+      return true;
+    case DISABLED:
+      return false;
+    case INITIALIZING:
+      pending_tasks_.push_back(callback);
+      return false;
+    case UNINITIALIZED:
+      pending_tasks_.push_back(callback);
+      // Fall-through.
+  }
+
+  state_ = INITIALIZING;
+  database_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&ReadInitialDataFromDB,
+                 database_.get(),
+                 base::MessageLoopProxy::current(),
+                 base::Bind(&ServiceWorkerStorage::DidReadInitialData,
+                            weak_factory_.GetWeakPtr())));
+  return false;
+}
+
+void ServiceWorkerStorage::DidReadInitialData(
+    InitialData* data,
+    bool success) {
+  DCHECK(data);
+  DCHECK_EQ(INITIALIZING, state_);
+
+  if (success) {
+    next_registration_id_ = data->next_registration_id;
+    next_version_id_ = data->next_version_id;
+    next_resource_id_ = data->next_resource_id;
+    registered_origins_.swap(data->origins);
+    state_ = INITIALIZED;
+  } else {
+    DLOG(WARNING) << "Failed to initialize.";
+    state_ = DISABLED;
+  }
+
+  for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin();
+       it != pending_tasks_.end(); ++it) {
+    RunSoon(FROM_HERE, *it);
+  }
+  pending_tasks_.clear();
+}
+
+void ServiceWorkerStorage::DidGetRegistrationsForPattern(
+    const GURL& scope,
+    const FindRegistrationCallback& callback,
+    RegistrationList* registrations,
+    bool success) {
+  DCHECK(registrations);
+  if (!success) {
+    callback.Run(SERVICE_WORKER_ERROR_FAILED,
+                 scoped_refptr<ServiceWorkerRegistration>());
+    return;
+  }
+
+  // Find one with a matching scope.
+  for (RegistrationList::const_iterator it = registrations->begin();
+       it != registrations->end(); ++it) {
+    if (scope == it->scope) {
+      scoped_refptr<ServiceWorkerRegistration> registration =
+          context_->GetLiveRegistration(it->registration_id);
+      if (!registration)
+        registration = CreateRegistration(*it);
+      callback.Run(SERVICE_WORKER_OK, registration);
+      return;
+    }
+  }
+
+  // Look for something currently being installed.
+  scoped_refptr<ServiceWorkerRegistration> installing_registration =
+      FindInstallingRegistrationForPattern(scope);
+  if (installing_registration) {
+    callback.Run(SERVICE_WORKER_OK, installing_registration);
+    return;
+  }
+
+  callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND,
+               scoped_refptr<ServiceWorkerRegistration>());
+}
+
+void ServiceWorkerStorage::DidGetRegistrationsForDocument(
+    const GURL& document_url,
+    const FindRegistrationCallback& callback,
+    RegistrationList* registrations,
+    bool success) {
+  DCHECK(registrations);
+  if (!success) {
+    callback.Run(SERVICE_WORKER_ERROR_FAILED,
+                 scoped_refptr<ServiceWorkerRegistration>());
+    return;
+  }
+
+  // Find one with a pattern match.
+  for (RegistrationList::const_iterator it = registrations->begin();
+       it != registrations->end(); ++it) {
+    // TODO(michaeln): if there are multiple matches the one with
+    // the longest scope should win.
+    if (ServiceWorkerUtils::ScopeMatches(it->scope, document_url)) {
+      scoped_refptr<ServiceWorkerRegistration> registration =
+          context_->GetLiveRegistration(it->registration_id);
+      if (registration) {
+        callback.Run(SERVICE_WORKER_OK, registration);
+        return;
+      }
+      callback.Run(SERVICE_WORKER_OK, CreateRegistration(*it));
+      return;
+    }
+  }
+
+  // Look for something currently being installed.
+  // TODO(michaeln): Should be mixed in with the stored registrations
+  // for this test.
+  scoped_refptr<ServiceWorkerRegistration> installing_registration =
+      FindInstallingRegistrationForDocument(document_url);
+  if (installing_registration) {
+    callback.Run(SERVICE_WORKER_OK, installing_registration);
+    return;
+  }
+
+  callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND,
+               scoped_refptr<ServiceWorkerRegistration>());
+}
+
+void ServiceWorkerStorage::DidReadRegistrationForId(
+    const FindRegistrationCallback& callback,
+    const ServiceWorkerDatabase::RegistrationData& registration,
+    const ResourceList& resources,
+    ServiceWorkerStatusCode status) {
+  if (status == SERVICE_WORKER_OK) {
+    callback.Run(status, CreateRegistration(registration));
+    return;
+  }
+
+  if (status == SERVICE_WORKER_ERROR_NOT_FOUND) {
+    // Look for somthing currently being installed.
+    scoped_refptr<ServiceWorkerRegistration> installing_registration =
+        FindInstallingRegistrationForId(registration.registration_id);
+    if (installing_registration) {
+      callback.Run(SERVICE_WORKER_OK, installing_registration);
+      return;
+    }
+    callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND,
+                 scoped_refptr<ServiceWorkerRegistration>());
+    return;
+  }
+
+  callback.Run(status, scoped_refptr<ServiceWorkerRegistration>());
+  return;
+}
+
+void ServiceWorkerStorage::DidGetAllRegistrations(
+    const GetAllRegistrationInfosCallback& callback,
+    RegistrationList* registrations,
+    bool success) {
+  DCHECK(registrations);
+  if (!success) {
+    callback.Run(std::vector<ServiceWorkerRegistrationInfo>());
+    return;
+  }
+
+  // Add all stored registrations.
+  std::set<int64> pushed_registrations;
+  std::vector<ServiceWorkerRegistrationInfo> infos;
+  for (RegistrationList::const_iterator it = registrations->begin();
+       it != registrations->end(); ++it) {
+    DCHECK(pushed_registrations.insert(it->registration_id).second);
+    ServiceWorkerRegistration* registration =
+        context_->GetLiveRegistration(it->registration_id);
+    if (registration) {
+      infos.push_back(registration->GetInfo());
+      continue;
+    }
+    ServiceWorkerRegistrationInfo info;
+    info.pattern = it->scope;
+    info.script_url = it->script;
+    info.active_version.is_null = false;
+    if (it->is_active)
+      info.active_version.status = ServiceWorkerVersion::ACTIVE;
+    else
+      info.active_version.status = ServiceWorkerVersion::INSTALLED;
+    info.active_version.version_id = it->version_id;
+    infos.push_back(info);
+  }
+
+  // Add unstored registrations that are being installed.
+  for (RegistrationRefsById::const_iterator it =
+           installing_registrations_.begin();
+       it != installing_registrations_.end(); ++it) {
+    if (pushed_registrations.insert(it->first).second)
+      infos.push_back(it->second->GetInfo());
+  }
+
+  callback.Run(infos);
+}
+
+void ServiceWorkerStorage::DidStoreRegistration(
+    const GURL& origin,
+    const StatusCallback& callback,
+    bool success) {
+  if (!success) {
+    callback.Run(SERVICE_WORKER_ERROR_FAILED);
+    return;
+  }
+  registered_origins_.insert(origin);
+  callback.Run(SERVICE_WORKER_OK);
+}
+
+void ServiceWorkerStorage::DidDeleteRegistration(
+    const GURL& origin,
+    const StatusCallback& callback,
+    bool origin_is_deletable,
+    ServiceWorkerStatusCode status) {
+  if (origin_is_deletable)
+    registered_origins_.erase(origin);
+  callback.Run(status);
+}
+
 scoped_refptr<ServiceWorkerRegistration>
 ServiceWorkerStorage::CreateRegistration(
-    const ServiceWorkerDatabase::RegistrationData* data) {
+    const ServiceWorkerDatabase::RegistrationData& data) {
   scoped_refptr<ServiceWorkerRegistration> registration(
       new ServiceWorkerRegistration(
-          data->scope, data->script, data->registration_id, context_));
+          data.scope, data.script, data.registration_id, context_));
 
   scoped_refptr<ServiceWorkerVersion> version =
-      context_->GetLiveVersion(data->version_id);
+      context_->GetLiveVersion(data.version_id);
   if (!version) {
-    version = new ServiceWorkerVersion(
-        registration, data->version_id, context_);
-    version->SetStatus(data->GetVersionStatus());
+    version = new ServiceWorkerVersion(registration, data.version_id, context_);
+    version->SetStatus(data.GetVersionStatus());
   }
 
   if (version->status() == ServiceWorkerVersion::ACTIVE)
@@ -420,4 +751,17 @@
   return found->second;
 }
 
+ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() {
+  if (disk_cache_)
+    return disk_cache_.get();
+
+  // TODO(michaeln): Store data on disk and do error checking.
+  disk_cache_.reset(new ServiceWorkerDiskCache);
+  int rv = disk_cache_->InitWithMemBackend(
+      kMaxMemDiskCacheSize,
+      base::Bind(&EmptyCompletionCallback));
+  DCHECK_EQ(net::OK, rv);
+  return disk_cache_.get();
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_storage.h b/content/browser/service_worker/service_worker_storage.h
index 3932a72..6780d4c 100644
--- a/content/browser/service_worker/service_worker_storage.h
+++ b/content/browser/service_worker/service_worker_storage.h
@@ -6,6 +6,7 @@
 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_
 
 #include <map>
+#include <set>
 #include <vector>
 
 #include "base/bind.h"
@@ -18,6 +19,10 @@
 #include "content/common/service_worker/service_worker_status_code.h"
 #include "url/gurl.h"
 
+namespace base {
+class SequencedTaskRunner;
+}
+
 namespace quota {
 class QuotaManagerProxy;
 }
@@ -25,8 +30,11 @@
 namespace content {
 
 class ServiceWorkerContextCore;
+class ServiceWorkerDiskCache;
 class ServiceWorkerRegistration;
 class ServiceWorkerRegistrationInfo;
+class ServiceWorkerResponseReader;
+class ServiceWorkerResponseWriter;
 class ServiceWorkerVersion;
 
 // This class provides an interface to store and retrieve ServiceWorker
@@ -44,8 +52,19 @@
       void(ServiceWorkerStatusCode status, int result)>
           CompareCallback;
 
+  struct InitialData {
+    int64 next_registration_id;
+    int64 next_version_id;
+    int64 next_resource_id;
+    std::set<GURL> origins;
+
+    InitialData();
+    ~InitialData();
+  };
+
   ServiceWorkerStorage(const base::FilePath& path,
                        base::WeakPtr<ServiceWorkerContextCore> context,
+                       base::SequencedTaskRunner* database_task_runner,
                        quota::QuotaManagerProxy* quota_manager_proxy);
   ~ServiceWorkerStorage();
 
@@ -63,6 +82,7 @@
   void FindRegistrationForPattern(const GURL& scope,
                                   const FindRegistrationCallback& callback);
   void FindRegistrationForId(int64 registration_id,
+                             const GURL& origin,
                              const FindRegistrationCallback& callback);
 
   // Returns info about all stored and initially installing registrations.
@@ -87,8 +107,14 @@
   // will remain available until either a browser restart or
   // DeleteVersionResources is called.
   void DeleteRegistration(int64 registration_id,
+                          const GURL& origin,
                           const StatusCallback& callback);
 
+  scoped_ptr<ServiceWorkerResponseReader> CreateResponseReader(
+      int64 response_id);
+  scoped_ptr<ServiceWorkerResponseWriter> CreateResponseWriter(
+      int64 response_id);
+
   // Returns new IDs which are guaranteed to be unique in the storage.
   int64 NewRegistrationId();
   int64 NewVersionId();
@@ -103,8 +129,45 @@
  private:
   friend class ServiceWorkerStorageTest;
 
+  typedef std::vector<ServiceWorkerDatabase::RegistrationData> RegistrationList;
+  typedef std::vector<ServiceWorkerDatabase::ResourceRecord> ResourceList;
+
+  bool LazyInitialize(
+      const base::Closure& callback);
+  void DidReadInitialData(
+      InitialData* data,
+      bool success);
+  void DidGetRegistrationsForPattern(
+      const GURL& scope,
+      const FindRegistrationCallback& callback,
+      RegistrationList* registrations,
+      bool succcess);
+  void DidGetRegistrationsForDocument(
+      const GURL& scope,
+      const FindRegistrationCallback& callback,
+      RegistrationList* registrations,
+      bool succcess);
+  void DidReadRegistrationForId(
+      const FindRegistrationCallback& callback,
+      const ServiceWorkerDatabase::RegistrationData& registration,
+      const ResourceList& resources,
+      ServiceWorkerStatusCode status);
+  void DidGetAllRegistrations(
+      const GetAllRegistrationInfosCallback& callback,
+      RegistrationList* registrations,
+      bool success);
+  void DidStoreRegistration(
+      const GURL& origin,
+      const StatusCallback& callback,
+      bool success);
+  void DidDeleteRegistration(
+      const GURL& origin,
+      const StatusCallback& callback,
+      bool origin_is_deletable,
+      ServiceWorkerStatusCode status);
+
   scoped_refptr<ServiceWorkerRegistration> CreateRegistration(
-      const ServiceWorkerDatabase::RegistrationData* data);
+      const ServiceWorkerDatabase::RegistrationData& data);
   ServiceWorkerRegistration* FindInstallingRegistrationForDocument(
       const GURL& document_url);
   ServiceWorkerRegistration* FindInstallingRegistrationForPattern(
@@ -112,32 +175,43 @@
   ServiceWorkerRegistration* FindInstallingRegistrationForId(
       int64 registration_id);
 
-  // TODO(michaeln): Store these structs in a database.
-  typedef std::map<int64, ServiceWorkerDatabase::RegistrationData>
-      RegistrationsMap;
-  typedef std::map<GURL, RegistrationsMap>
-      OriginRegistrationsMap;
-  OriginRegistrationsMap stored_registrations_;
-
-  // For iterating and lookup based on id only, this map holds
-  // pointers to the values stored in the OriginRegistrationsMap.
-  typedef std::map<int64, ServiceWorkerDatabase::RegistrationData*>
-      RegistrationPtrMap;
-  RegistrationPtrMap registrations_by_id_;
-
   // For finding registrations being installed.
   typedef std::map<int64, scoped_refptr<ServiceWorkerRegistration> >
       RegistrationRefsById;
   RegistrationRefsById installing_registrations_;
 
-  int64 last_registration_id_;
-  int64 last_version_id_;
-  int64 last_resource_id_;
-  bool simulated_lazy_initted_;
+  // Lazy disk_cache getter.
+  ServiceWorkerDiskCache* disk_cache();
+
+  // Origins having registations.
+  std::set<GURL> registered_origins_;
+
+  // Pending database tasks waiting for initialization.
+  std::vector<base::Closure> pending_tasks_;
+
+  int64 next_registration_id_;
+  int64 next_version_id_;
+  int64 next_resource_id_;
+
+  enum State {
+    UNINITIALIZED,
+    INITIALIZING,
+    INITIALIZED,
+    DISABLED,
+  };
+  State state_;
 
   base::FilePath path_;
   base::WeakPtr<ServiceWorkerContextCore> context_;
+
+  // Only accessed on |database_task_runner_|.
+  scoped_ptr<ServiceWorkerDatabase> database_;
+
+  scoped_refptr<base::SequencedTaskRunner> database_task_runner_;
   scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_;
+  scoped_ptr<ServiceWorkerDiskCache> disk_cache_;
+
+  base::WeakPtrFactory<ServiceWorkerStorage> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage);
 };
diff --git a/content/browser/service_worker/service_worker_storage_unittest.cc b/content/browser/service_worker/service_worker_storage_unittest.cc
index 80ee8af..2265e9c 100644
--- a/content/browser/service_worker/service_worker_storage_unittest.cc
+++ b/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -74,11 +74,11 @@
   virtual void SetUp() OVERRIDE {
     context_.reset(new ServiceWorkerContextCore(
         base::FilePath(),
+        base::MessageLoopProxy::current(),
         NULL,
         NULL,
         scoped_ptr<ServiceWorkerProcessManager>()));
     context_ptr_ = context_->AsWeakPtr();
-    storage()->simulated_lazy_initted_ = true;
   }
 
   virtual void TearDown() OVERRIDE {
@@ -97,8 +97,8 @@
   const GURL kScope("http://www.test.com/scope/*");
   const GURL kScript("http://www.test.com/script.js");
   const GURL kDocumentUrl("http://www.test.com/scope/document.html");
-  const int64 kRegistrationId = storage()->NewRegistrationId();
-  const int64 kVersionId = storage()->NewVersionId();
+  const int64 kRegistrationId = 0;
+  const int64 kVersionId = 0;
 
   bool was_called = false;
   ServiceWorkerStatusCode result = SERVICE_WORKER_OK;
@@ -123,6 +123,7 @@
   was_called = false;
   storage()->FindRegistrationForId(
       kRegistrationId,
+      kScope.GetOrigin(),
       MakeFindCallback(&was_called, &result, &found_registration));
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
@@ -151,6 +152,7 @@
   storage()->FindRegistrationForDocument(
       kDocumentUrl,
       MakeFindCallback(&was_called, &result, &found_registration));
+  base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
   EXPECT_EQ(SERVICE_WORKER_OK, result);
   EXPECT_EQ(live_registration, found_registration);
@@ -172,6 +174,7 @@
   // Can be found by id too.
   storage()->FindRegistrationForId(
       kRegistrationId,
+      kScope.GetOrigin(),
       MakeFindCallback(&was_called, &result, &found_registration));
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
@@ -273,6 +276,7 @@
   EXPECT_TRUE(context_->GetLiveVersion(kRegistrationId));
   storage()->DeleteRegistration(
       kRegistrationId,
+      kScope.GetOrigin(),
       MakeStatusCallback(&was_called, &result));
   EXPECT_FALSE(was_called);
   base::RunLoop().RunUntilIdle();
@@ -284,6 +288,7 @@
   // Should no longer be found.
   storage()->FindRegistrationForId(
       kRegistrationId,
+      kScope.GetOrigin(),
       MakeFindCallback(&was_called, &result, &found_registration));
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
@@ -291,14 +296,15 @@
   EXPECT_FALSE(found_registration);
   was_called = false;
 
-  // Deleting an unstored registration should fail.
+  // Deleting an unstored registration should succeed.
   storage()->DeleteRegistration(
       kRegistrationId + 1,
+      kScope.GetOrigin(),
       MakeStatusCallback(&was_called, &result));
   EXPECT_FALSE(was_called);
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(was_called);
-  EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND, result);
+  EXPECT_EQ(SERVICE_WORKER_OK, result);
   was_called = false;
 }
 
@@ -306,8 +312,8 @@
   const GURL kScope("http://www.test.com/scope/*");
   const GURL kScript("http://www.test.com/script.js");
   const GURL kDocumentUrl("http://www.test.com/scope/document.html");
-  const int64 kRegistrationId = storage()->NewRegistrationId();
-  const int64 kVersionId = storage()->NewVersionId();
+  const int64 kRegistrationId = 0;
+  const int64 kVersionId = 0;
 
   bool was_called = false;
   ServiceWorkerStatusCode result = SERVICE_WORKER_OK;
@@ -326,6 +332,7 @@
   // Should not be findable, including by GetAllRegistrations.
   storage()->FindRegistrationForId(
       kRegistrationId,
+      kScope.GetOrigin(),
       MakeFindCallback(&was_called, &result, &found_registration));
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
@@ -362,6 +369,7 @@
   // Now should be findable.
   storage()->FindRegistrationForId(
       kRegistrationId,
+      kScope.GetOrigin(),
       MakeFindCallback(&was_called, &result, &found_registration));
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
@@ -401,6 +409,7 @@
   // Once again, should not be findable.
   storage()->FindRegistrationForId(
       kRegistrationId,
+      kScope.GetOrigin(),
       MakeFindCallback(&was_called, &result, &found_registration));
   base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(was_called);
diff --git a/content/browser/service_worker/service_worker_unregister_job.cc b/content/browser/service_worker/service_worker_unregister_job.cc
index 5866c78..a66f32f 100644
--- a/content/browser/service_worker/service_worker_unregister_job.cc
+++ b/content/browser/service_worker/service_worker_unregister_job.cc
@@ -54,6 +54,7 @@
     // when the version no longer has any controllees.
     context_->storage()->DeleteRegistration(
         registration->id(),
+        registration->script_url().GetOrigin(),
         base::Bind(&ServiceWorkerUnregisterJob::Complete,
                    weak_factory_.GetWeakPtr()));
     return;
diff --git a/content/browser/service_worker/service_worker_url_request_job.cc b/content/browser/service_worker/service_worker_url_request_job.cc
index 46439b6..37d22d0 100644
--- a/content/browser/service_worker/service_worker_url_request_job.cc
+++ b/content/browser/service_worker/service_worker_url_request_job.cc
@@ -172,6 +172,7 @@
     // TODO(kinuko): Would be nice to log the error case.
     response_type_ = FALLBACK_TO_NETWORK;
     NotifyRestartRequired();
+    return;
   }
 
   if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) {
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 592f88b..66ca883 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "base/stl_util.h"
+#include "base/strings/string16.h"
 #include "content/browser/service_worker/embedded_worker_instance.h"
 #include "content/browser/service_worker/embedded_worker_registry.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
@@ -429,6 +430,8 @@
                         OnFetchEventFinished)
     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SyncEventFinished,
                         OnSyncEventFinished)
+    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument,
+                        OnPostMessageToDocument)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
@@ -547,4 +550,31 @@
   sync_callbacks_.Remove(request_id);
 }
 
+void ServiceWorkerVersion::AddToScriptCache(
+    const GURL& url, int64 resource_id) {
+  DCHECK_EQ(kInvalidServiceWorkerResponseId, LookupInScriptCache(url));
+  DCHECK_EQ(NEW, status_);
+  script_cache_map_[url] = resource_id;
+}
+
+int64 ServiceWorkerVersion::LookupInScriptCache(const GURL& url) {
+  ResourceIDMap::const_iterator found = script_cache_map_.find(url);
+  if (found == script_cache_map_.end())
+    return kInvalidServiceWorkerResponseId;
+  return found->second;
+}
+
+void ServiceWorkerVersion::OnPostMessageToDocument(
+    int client_id,
+    const base::string16& message,
+    const std::vector<int>& sent_message_port_ids) {
+  ServiceWorkerProviderHost* provider_host =
+      controllee_by_id_.Lookup(client_id);
+  if (!provider_host) {
+    // The client may already have been closed, just ignore.
+    return;
+  }
+  provider_host->PostMessage(message, sent_message_port_ids);
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index e0db0ff..84ecc01 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -212,10 +212,14 @@
                                       const GURL& source_url) OVERRIDE;
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
 
+  void AddToScriptCache(const GURL& url, int64 resource_id);
+  int64 LookupInScriptCache(const GURL& url);
+
  private:
   typedef ServiceWorkerVersion self;
   typedef std::map<ServiceWorkerProviderHost*, int> ControlleeMap;
   typedef IDMap<ServiceWorkerProviderHost> ControlleeByIDMap;
+  typedef std::map<GURL, int64> ResourceIDMap;
   friend class base::RefCounted<ServiceWorkerVersion>;
 
   virtual ~ServiceWorkerVersion();
@@ -236,6 +240,9 @@
                             ServiceWorkerFetchEventResult result,
                             const ServiceWorkerResponse& response);
   void OnSyncEventFinished(int request_id);
+  void OnPostMessageToDocument(int client_id,
+                               const base::string16& message,
+                               const std::vector<int>& sent_message_port_ids);
 
   const int64 version_id_;
   int64 registration_id_;
@@ -258,6 +265,8 @@
   base::WeakPtr<ServiceWorkerContextCore> context_;
   ObserverList<Listener> listeners_;
 
+  ResourceIDMap script_cache_map_;
+
   base::WeakPtrFactory<ServiceWorkerVersion> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersion);
diff --git a/content/browser/shared_worker/shared_worker_host.cc b/content/browser/shared_worker/shared_worker_host.cc
index 18936f3..6f6e420 100644
--- a/content/browser/shared_worker/shared_worker_host.cc
+++ b/content/browser/shared_worker/shared_worker_host.cc
@@ -5,7 +5,7 @@
 #include "content/browser/shared_worker/shared_worker_host.h"
 
 #include "base/metrics/histogram.h"
-#include "content/browser/devtools/shared_worker_devtools_manager.h"
+#include "content/browser/devtools/embedded_worker_devtools_manager.h"
 #include "content/browser/frame_host/render_frame_host_delegate.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/message_port_service.h"
@@ -33,14 +33,14 @@
 
 void NotifyWorkerScriptLoadedOnUI(int worker_process_id, int worker_route_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  SharedWorkerDevToolsManager::GetInstance()->WorkerContextStarted(
+  EmbeddedWorkerDevToolsManager::GetInstance()->WorkerContextStarted(
       worker_process_id, worker_route_id);
 }
 
 void NotifyWorkerDestroyedOnUI(int worker_process_id, int worker_route_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  SharedWorkerDevToolsManager::GetInstance()->WorkerDestroyed(worker_process_id,
-                                                              worker_route_id);
+  EmbeddedWorkerDevToolsManager::GetInstance()->WorkerDestroyed(
+      worker_process_id, worker_route_id);
 }
 
 }  // namespace
diff --git a/content/browser/shared_worker/shared_worker_instance.h b/content/browser/shared_worker/shared_worker_instance.h
index e68c9a4..2785c40 100644
--- a/content/browser/shared_worker/shared_worker_instance.h
+++ b/content/browser/shared_worker/shared_worker_instance.h
@@ -17,7 +17,7 @@
 class ResourceContext;
 
 // SharedWorkerInstance is copyable value-type data type. It could be passed to
-// the UI thread and be used for comparison in SharedWorkerDevToolsManager.
+// the UI thread and be used for comparison in EmbeddedWorkerDevToolsManager.
 class CONTENT_EXPORT SharedWorkerInstance {
  public:
   SharedWorkerInstance(const GURL& url,
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc
index aa97e44..4a689fa 100644
--- a/content/browser/shared_worker/shared_worker_service_impl.cc
+++ b/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -11,7 +11,7 @@
 
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
-#include "content/browser/devtools/shared_worker_devtools_manager.h"
+#include "content/browser/devtools/embedded_worker_devtools_manager.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/shared_worker/shared_worker_host.h"
 #include "content/browser/shared_worker/shared_worker_instance.h"
@@ -193,7 +193,7 @@
     bool pause_on_start = false;
     if (is_new_worker_) {
       pause_on_start =
-          SharedWorkerDevToolsManager::GetInstance()->WorkerCreated(
+          EmbeddedWorkerDevToolsManager::GetInstance()->SharedWorkerCreated(
               worker_process_id_, worker_route_id_, instance_);
     }
     BrowserThread::PostTask(
diff --git a/content/browser/speech/endpointer/energy_endpointer.cc b/content/browser/speech/endpointer/energy_endpointer.cc
index d8d1274..30f3770 100644
--- a/content/browser/speech/endpointer/energy_endpointer.cc
+++ b/content/browser/speech/endpointer/energy_endpointer.cc
@@ -238,7 +238,7 @@
 
   // Check that this is user input audio vs. pre-input adaptation audio.
   // Input audio starts when the user indicates start of input, by e.g.
-  // pressing push-to-talk. Audio recieved prior to that is used to update
+  // pressing push-to-talk. Audio received prior to that is used to update
   // noise and speech level estimates.
   if (!estimating_environment_) {
     bool decision = false;
diff --git a/content/browser/speech/input_tag_speech_browsertest.cc b/content/browser/speech/input_tag_speech_browsertest.cc
deleted file mode 100644
index cc3bc11..0000000
--- a/content/browser/speech/input_tag_speech_browsertest.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2013 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.
-
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/public/browser/notification_types.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/common/speech_recognition_error.h"
-#include "content/public/common/speech_recognition_result.h"
-#include "content/public/common/url_constants.h"
-#include "content/public/test/content_browser_test.h"
-#include "content/public/test/content_browser_test_utils.h"
-#include "content/public/test/fake_speech_recognition_manager.h"
-#include "content/public/test/test_utils.h"
-#include "content/shell/browser/shell.h"
-#include "third_party/WebKit/public/web/WebInputEvent.h"
-
-namespace content {
-
-class InputTagSpeechBrowserTest : public ContentBrowserTest {
- public:
-  // ContentBrowserTest methods
-  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
-    EXPECT_TRUE(!command_line->HasSwitch(switches::kDisableSpeechInput));
-  }
-
- protected:
-  void LoadAndStartSpeechRecognitionTest(const char* filename) {
-    // The test page calculates the speech button's coordinate in the page on
-    // load & sets that coordinate in the URL fragment. We send mouse down & up
-    // events at that coordinate to trigger speech recognition.
-    GURL test_url = GetTestUrl("speech", filename);
-    NavigateToURL(shell(), test_url);
-
-    blink::WebMouseEvent mouse_event;
-    mouse_event.type = blink::WebInputEvent::MouseDown;
-    mouse_event.button = blink::WebMouseEvent::ButtonLeft;
-    mouse_event.x = 0;
-    mouse_event.y = 0;
-    mouse_event.clickCount = 1;
-    WebContents* web_contents = shell()->web_contents();
-
-    WindowedNotificationObserver observer(
-        NOTIFICATION_LOAD_STOP,
-        Source<NavigationController>(&web_contents->GetController()));
-    web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
-    mouse_event.type = blink::WebInputEvent::MouseUp;
-    web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
-    fake_speech_recognition_manager_.WaitForRecognitionStarted();
-
-    // We should wait for a navigation event, raised by the test page JS code
-    // upon the onwebkitspeechchange event, in all cases except when the
-    // speech response is inhibited.
-    if (fake_speech_recognition_manager_.should_send_fake_response())
-      observer.Wait();
-  }
-
-  void RunSpeechRecognitionTest(const char* filename) {
-    // The fake speech input manager would receive the speech input
-    // request and return the test string as recognition result. The test page
-    // then sets the URL fragment as 'pass' if it received the expected string.
-    LoadAndStartSpeechRecognitionTest(filename);
-
-    EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
-  }
-
-  // ContentBrowserTest methods.
-  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
-    fake_speech_recognition_manager_.set_should_send_fake_response(true);
-    speech_recognition_manager_ = &fake_speech_recognition_manager_;
-
-    // Inject the fake manager factory so that the test result is returned to
-    // the web page.
-    SpeechRecognitionManager::SetManagerForTesting(speech_recognition_manager_);
-  }
-
-  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
-    speech_recognition_manager_ = NULL;
-  }
-
-  FakeSpeechRecognitionManager fake_speech_recognition_manager_;
-
-  // This is used by the static |fakeManager|, and it is a pointer rather than a
-  // direct instance per the style guide.
-  static SpeechRecognitionManager* speech_recognition_manager_;
-};
-
-SpeechRecognitionManager*
-    InputTagSpeechBrowserTest::speech_recognition_manager_ = NULL;
-
-// TODO(satish): Once this flakiness has been fixed, add a second test here to
-// check for sending many clicks in succession to the speech button and verify
-// that it doesn't cause any crash but works as expected. This should act as the
-// test for http://crbug.com/59173
-//
-// TODO(satish): Similar to above, once this flakiness has been fixed add
-// another test here to check that when speech recognition is in progress and
-// a renderer crashes, we get a call to
-// SpeechRecognitionManager::CancelAllRequestsWithDelegate.
-// crbug/360448
-IN_PROC_BROWSER_TEST_F(InputTagSpeechBrowserTest,
-    DISABLED_TestBasicRecognition) {
-  RunSpeechRecognitionTest("basic_recognition.html");
-  EXPECT_TRUE(fake_speech_recognition_manager_.grammar().empty());
-}
-
-// crbug/360448
-IN_PROC_BROWSER_TEST_F(InputTagSpeechBrowserTest, DISABLED_GrammarAttribute) {
-  RunSpeechRecognitionTest("grammar_attribute.html");
-  EXPECT_EQ("http://example.com/grammar.xml",
-            fake_speech_recognition_manager_.grammar());
-}
-
-// Flaky on Linux, Windows and Mac http://crbug.com/140765.
-IN_PROC_BROWSER_TEST_F(InputTagSpeechBrowserTest, DISABLED_TestCancelAll) {
-  // The test checks that the cancel-all callback gets issued when a session
-  // is pending, so don't send a fake response.
-  // We are not expecting a navigation event being raised from the JS of the
-  // test page JavaScript in this case.
-  fake_speech_recognition_manager_.set_should_send_fake_response(false);
-
-  LoadAndStartSpeechRecognitionTest("basic_recognition.html");
-
-  // Make the renderer crash. This should trigger
-  // InputTagSpeechDispatcherHost to cancel all pending sessions.
-  NavigateToURL(shell(), GURL(kChromeUICrashURL));
-
-  EXPECT_TRUE(fake_speech_recognition_manager_.did_cancel_all());
-}
-
-}  // namespace content
diff --git a/content/browser/speech/input_tag_speech_dispatcher_host.cc b/content/browser/speech/input_tag_speech_dispatcher_host.cc
deleted file mode 100644
index dd6a4b2..0000000
--- a/content/browser/speech/input_tag_speech_dispatcher_host.cc
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "content/browser/speech/input_tag_speech_dispatcher_host.h"
-
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "content/browser/browser_plugin/browser_plugin_guest.h"
-#include "content/browser/child_process_security_policy_impl.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/speech/speech_recognition_manager_impl.h"
-#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/common/speech_recognition_messages.h"
-#include "content/public/browser/speech_recognition_manager_delegate.h"
-#include "content/public/browser/speech_recognition_session_config.h"
-#include "content/public/browser/speech_recognition_session_context.h"
-
-namespace {
-const uint32 kMaxHypothesesForSpeechInputTag = 6;
-}
-
-namespace content {
-
-InputTagSpeechDispatcherHost::InputTagSpeechDispatcherHost(
-    bool is_guest,
-    int render_process_id,
-    net::URLRequestContextGetter* url_request_context_getter)
-    : BrowserMessageFilter(SpeechRecognitionMsgStart),
-      is_guest_(is_guest),
-      render_process_id_(render_process_id),
-      url_request_context_getter_(url_request_context_getter),
-      weak_factory_(this) {
-  // Do not add any non-trivial initialization here, instead do it lazily when
-  // required (e.g. see the method |SpeechRecognitionManager::GetInstance()|) or
-  // add an Init() method.
-}
-
-InputTagSpeechDispatcherHost::~InputTagSpeechDispatcherHost() {
-  SpeechRecognitionManager::GetInstance()->AbortAllSessionsForRenderProcess(
-      render_process_id_);
-}
-
-base::WeakPtr<InputTagSpeechDispatcherHost>
-InputTagSpeechDispatcherHost::AsWeakPtr() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  return weak_factory_.GetWeakPtr();
-}
-
-bool InputTagSpeechDispatcherHost::OnMessageReceived(
-    const IPC::Message& message, bool* message_was_ok) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP_EX(InputTagSpeechDispatcherHost, message,
-                           *message_was_ok)
-    IPC_MESSAGE_HANDLER(InputTagSpeechHostMsg_StartRecognition,
-                        OnStartRecognition)
-    IPC_MESSAGE_HANDLER(InputTagSpeechHostMsg_CancelRecognition,
-                        OnCancelRecognition)
-    IPC_MESSAGE_HANDLER(InputTagSpeechHostMsg_StopRecording,
-                        OnStopRecording)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-void InputTagSpeechDispatcherHost::OverrideThreadForMessage(
-    const IPC::Message& message,
-    BrowserThread::ID* thread) {
-  if (message.type() == InputTagSpeechHostMsg_StartRecognition::ID)
-    *thread = BrowserThread::UI;
-}
-
-void InputTagSpeechDispatcherHost::OnChannelClosing() {
-  weak_factory_.InvalidateWeakPtrs();
-}
-
-void InputTagSpeechDispatcherHost::OnStartRecognition(
-    const InputTagSpeechHostMsg_StartRecognition_Params& params) {
-  InputTagSpeechHostMsg_StartRecognition_Params input_params(params);
-  int render_process_id = render_process_id_;
-
-  // Check that the origin specified by the renderer process is one
-  // that it is allowed to access.
-  if (params.origin_url != "null" &&
-      !ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL(
-          render_process_id, GURL(params.origin_url))) {
-    LOG(ERROR) << "ITSDH::OnStartRecognition, disallowed origin: "
-               << params.origin_url;
-    return;
-  }
-
-  // The chrome layer is mostly oblivious to BrowserPlugin guests and so it
-  // cannot correctly place the speech bubble relative to a guest. Thus, we
-  // set up the speech recognition context relative to the embedder.
-  int guest_render_view_id = MSG_ROUTING_NONE;
-  if (is_guest_) {
-    RenderViewHostImpl* render_view_host =
-        RenderViewHostImpl::FromID(render_process_id_, params.render_view_id);
-    WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
-        WebContents::FromRenderViewHost(render_view_host));
-    BrowserPluginGuest* guest = web_contents->GetBrowserPluginGuest();
-    input_params.element_rect.set_origin(
-        guest->GetScreenCoordinates(input_params.element_rect.origin()));
-    guest_render_view_id = params.render_view_id;
-    render_process_id =
-        guest->embedder_web_contents()->GetRenderProcessHost()->GetID();
-    input_params.render_view_id =
-        guest->embedder_web_contents()->GetRoutingID();
-  }
-  bool filter_profanities =
-      SpeechRecognitionManagerImpl::GetInstance() &&
-      SpeechRecognitionManagerImpl::GetInstance()->delegate() &&
-      SpeechRecognitionManagerImpl::GetInstance()->delegate()->
-          FilterProfanities(render_process_id_);
-
- BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::Bind(
-          &InputTagSpeechDispatcherHost::StartRecognitionOnIO,
-          this,
-          render_process_id,
-          guest_render_view_id,
-          input_params,
-          filter_profanities));
-}
-
-void InputTagSpeechDispatcherHost::StartRecognitionOnIO(
-    int render_process_id,
-    int guest_render_view_id,
-    const InputTagSpeechHostMsg_StartRecognition_Params& params,
-    bool filter_profanities) {
-  SpeechRecognitionSessionContext context;
-  context.render_process_id = render_process_id;
-  context.render_view_id = params.render_view_id;
-  context.guest_render_view_id = guest_render_view_id;
-  // Keep context.embedder_render_process_id and context.embedder_render_view_id
-  // unset.
-  context.request_id = params.request_id;
-  context.element_rect = params.element_rect;
-
-  SpeechRecognitionSessionConfig config;
-  config.language = params.language;
-  if (!params.grammar.empty()) {
-    config.grammars.push_back(SpeechRecognitionGrammar(params.grammar));
-  }
-  config.max_hypotheses = kMaxHypothesesForSpeechInputTag;
-  config.origin_url = params.origin_url;
-  config.initial_context = context;
-  config.url_request_context_getter = url_request_context_getter_.get();
-  config.filter_profanities = filter_profanities;
-  config.event_listener = AsWeakPtr();
-
-  int session_id = SpeechRecognitionManager::GetInstance()->CreateSession(
-      config);
-  DCHECK_NE(session_id, SpeechRecognitionManager::kSessionIDInvalid);
-  SpeechRecognitionManager::GetInstance()->StartSession(session_id);
-}
-
-void InputTagSpeechDispatcherHost::OnCancelRecognition(int render_view_id,
-                                                       int request_id) {
-  int session_id = SpeechRecognitionManager::GetInstance()->GetSession(
-      render_process_id_, render_view_id, request_id);
-
-  // The renderer might provide an invalid |request_id| if the session was not
-  // started as expected, e.g., due to unsatisfied security requirements.
-  if (session_id != SpeechRecognitionManager::kSessionIDInvalid)
-    SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
-}
-
-void InputTagSpeechDispatcherHost::OnStopRecording(int render_view_id,
-                                                   int request_id) {
-  int session_id = SpeechRecognitionManager::GetInstance()->GetSession(
-      render_process_id_, render_view_id, request_id);
-
-  // The renderer might provide an invalid |request_id| if the session was not
-  // started as expected, e.g., due to unsatisfied security requirements.
-  if (session_id != SpeechRecognitionManager::kSessionIDInvalid) {
-    SpeechRecognitionManager::GetInstance()->StopAudioCaptureForSession(
-        session_id);
-  }
-}
-
-// -------- SpeechRecognitionEventListener interface implementation -----------
-void InputTagSpeechDispatcherHost::OnRecognitionResults(
-    int session_id,
-    const SpeechRecognitionResults& results) {
-  DVLOG(1) << "InputTagSpeechDispatcherHost::OnRecognitionResults enter";
-
-  const SpeechRecognitionSessionContext& context =
-      SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
-
-  int render_view_id =
-      context.guest_render_view_id == MSG_ROUTING_NONE ?
-          context.render_view_id : context.guest_render_view_id;
-  Send(new InputTagSpeechMsg_SetRecognitionResults(
-      render_view_id,
-      context.request_id,
-      results));
-  DVLOG(1) << "InputTagSpeechDispatcherHost::OnRecognitionResults exit";
-}
-
-void InputTagSpeechDispatcherHost::OnAudioEnd(int session_id) {
-  DVLOG(1) << "InputTagSpeechDispatcherHost::OnAudioEnd enter";
-
-  const SpeechRecognitionSessionContext& context =
-      SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
-  int render_view_id =
-      context.guest_render_view_id == MSG_ROUTING_NONE ?
-          context.render_view_id : context.guest_render_view_id;
-  Send(new InputTagSpeechMsg_RecordingComplete(render_view_id,
-                                               context.request_id));
-  DVLOG(1) << "InputTagSpeechDispatcherHost::OnAudioEnd exit";
-}
-
-void InputTagSpeechDispatcherHost::OnRecognitionEnd(int session_id) {
-  DVLOG(1) << "InputTagSpeechDispatcherHost::OnRecognitionEnd enter";
-  const SpeechRecognitionSessionContext& context =
-      SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
-  int render_view_id =
-      context.guest_render_view_id == MSG_ROUTING_NONE ?
-          context.render_view_id : context.guest_render_view_id;
-  Send(new InputTagSpeechMsg_RecognitionComplete(render_view_id,
-                                                 context.request_id));
-  DVLOG(1) << "InputTagSpeechDispatcherHost::OnRecognitionEnd exit";
-}
-
-// The events below are currently not used by x-webkit-speech implementation.
-void InputTagSpeechDispatcherHost::OnRecognitionStart(int session_id) {}
-void InputTagSpeechDispatcherHost::OnAudioStart(int session_id) {}
-void InputTagSpeechDispatcherHost::OnSoundStart(int session_id) {}
-void InputTagSpeechDispatcherHost::OnSoundEnd(int session_id) {}
-void InputTagSpeechDispatcherHost::OnRecognitionError(
-    int session_id,
-    const SpeechRecognitionError& error) {}
-void InputTagSpeechDispatcherHost::OnAudioLevelsChange(
-    int session_id, float volume, float noise_volume) {}
-void InputTagSpeechDispatcherHost::OnEnvironmentEstimationComplete(
-    int session_id) {}
-
-}  // namespace content
diff --git a/content/browser/speech/input_tag_speech_dispatcher_host.h b/content/browser/speech/input_tag_speech_dispatcher_host.h
deleted file mode 100644
index 4d5eb60..0000000
--- a/content/browser/speech/input_tag_speech_dispatcher_host.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CONTENT_BROWSER_SPEECH_INPUT_TAG_SPEECH_DISPATCHER_HOST_H_
-#define CONTENT_BROWSER_SPEECH_INPUT_TAG_SPEECH_DISPATCHER_HOST_H_
-
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "content/common/content_export.h"
-#include "content/public/browser/browser_message_filter.h"
-#include "content/public/browser/speech_recognition_event_listener.h"
-#include "content/public/common/speech_recognition_result.h"
-#include "net/url_request/url_request_context_getter.h"
-
-struct InputTagSpeechHostMsg_StartRecognition_Params;
-
-namespace content {
-
-class SpeechRecognitionManager;
-
-// InputTagSpeechDispatcherHost is a delegate for Speech API messages used by
-// RenderMessageFilter. Basically it acts as a proxy, relaying the events coming
-// from the SpeechRecognitionManager to IPC messages (and vice versa).
-// It's the complement of SpeechRecognitionDispatcher (owned by RenderView).
-class CONTENT_EXPORT InputTagSpeechDispatcherHost
-    : public BrowserMessageFilter,
-      public SpeechRecognitionEventListener {
- public:
-  InputTagSpeechDispatcherHost(
-      bool guest,
-      int render_process_id,
-      net::URLRequestContextGetter* url_request_context_getter);
-
-  base::WeakPtr<InputTagSpeechDispatcherHost> AsWeakPtr();
-
-  // SpeechRecognitionEventListener methods.
-  virtual void OnRecognitionStart(int session_id) OVERRIDE;
-  virtual void OnAudioStart(int session_id) OVERRIDE;
-  virtual void OnEnvironmentEstimationComplete(int session_id) OVERRIDE;
-  virtual void OnSoundStart(int session_id) OVERRIDE;
-  virtual void OnSoundEnd(int session_id) OVERRIDE;
-  virtual void OnAudioEnd(int session_id) OVERRIDE;
-  virtual void OnRecognitionEnd(int session_id) OVERRIDE;
-  virtual void OnRecognitionResults(
-      int session_id,
-      const SpeechRecognitionResults& results) OVERRIDE;
-  virtual void OnRecognitionError(
-      int session_id,
-      const SpeechRecognitionError& error) OVERRIDE;
-  virtual void OnAudioLevelsChange(int session_id,
-                                   float volume,
-                                   float noise_volume) OVERRIDE;
-
-  // BrowserMessageFilter implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message,
-                                 bool* message_was_ok) OVERRIDE;
-  virtual void OverrideThreadForMessage(
-      const IPC::Message& message,
-      BrowserThread::ID* thread) OVERRIDE;
-
-  virtual void OnChannelClosing() OVERRIDE;
-
- private:
-  virtual ~InputTagSpeechDispatcherHost();
-
-  void OnStartRecognition(
-      const InputTagSpeechHostMsg_StartRecognition_Params& params);
-  void OnCancelRecognition(int render_view_id, int request_id);
-  void OnStopRecording(int render_view_id, int request_id);
-
-  void StartRecognitionOnIO(
-      int embedder_render_process_id,
-      int embedder_render_view_id,
-      const InputTagSpeechHostMsg_StartRecognition_Params& params,
-      bool filter_profanities);
-
-  bool is_guest_;
-  int render_process_id_;
-  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
-
-  // Used for posting asynchronous tasks (on the IO thread) without worrying
-  // about this class being destroyed in the meanwhile (due to browser shutdown)
-  // since tasks pending on a destroyed WeakPtr are automatically discarded.
-  base::WeakPtrFactory<InputTagSpeechDispatcherHost> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(InputTagSpeechDispatcherHost);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_SPEECH_INPUT_TAG_SPEECH_DISPATCHER_HOST_H_
diff --git a/content/browser/speech/proto/speech_proto.target.darwin-arm.mk b/content/browser/speech/proto/speech_proto.target.darwin-arm.mk
index 041a249..3efb7da 100644
--- a/content/browser/speech/proto/speech_proto.target.darwin-arm.mk
+++ b/content/browser/speech/proto/speech_proto.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
 # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -63,7 +64,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -156,7 +156,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/browser/speech/proto/speech_proto.target.darwin-arm64.mk b/content/browser/speech/proto/speech_proto.target.darwin-arm64.mk
index 2f1cfb7..3d2b88f 100644
--- a/content/browser/speech/proto/speech_proto.target.darwin-arm64.mk
+++ b/content/browser/speech/proto/speech_proto.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
 # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/speech/proto/speech_proto.target.darwin-mips.mk b/content/browser/speech/proto/speech_proto.target.darwin-mips.mk
index 4e14901..bd168a8 100644
--- a/content/browser/speech/proto/speech_proto.target.darwin-mips.mk
+++ b/content/browser/speech/proto/speech_proto.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
 # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/speech/proto/speech_proto.target.darwin-x86.mk b/content/browser/speech/proto/speech_proto.target.darwin-x86.mk
index 2b96537..034dad0 100644
--- a/content/browser/speech/proto/speech_proto.target.darwin-x86.mk
+++ b/content/browser/speech/proto/speech_proto.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
 # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,7 +66,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +158,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/browser/speech/proto/speech_proto.target.darwin-x86_64.mk b/content/browser/speech/proto/speech_proto.target.darwin-x86_64.mk
index 909d011..01c2092 100644
--- a/content/browser/speech/proto/speech_proto.target.darwin-x86_64.mk
+++ b/content/browser/speech/proto/speech_proto.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
 # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,7 +66,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +158,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/browser/speech/proto/speech_proto.target.linux-arm.mk b/content/browser/speech/proto/speech_proto.target.linux-arm.mk
index 041a249..3efb7da 100644
--- a/content/browser/speech/proto/speech_proto.target.linux-arm.mk
+++ b/content/browser/speech/proto/speech_proto.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
 # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -63,7 +64,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -156,7 +156,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/browser/speech/proto/speech_proto.target.linux-arm64.mk b/content/browser/speech/proto/speech_proto.target.linux-arm64.mk
index 2f1cfb7..3d2b88f 100644
--- a/content/browser/speech/proto/speech_proto.target.linux-arm64.mk
+++ b/content/browser/speech/proto/speech_proto.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
 # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/speech/proto/speech_proto.target.linux-mips.mk b/content/browser/speech/proto/speech_proto.target.linux-mips.mk
index 4e14901..bd168a8 100644
--- a/content/browser/speech/proto/speech_proto.target.linux-mips.mk
+++ b/content/browser/speech/proto/speech_proto.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
 # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/browser/speech/proto/speech_proto.target.linux-x86.mk b/content/browser/speech/proto/speech_proto.target.linux-x86.mk
index 2b96537..034dad0 100644
--- a/content/browser/speech/proto/speech_proto.target.linux-x86.mk
+++ b/content/browser/speech/proto/speech_proto.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
 # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,7 +66,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +158,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/browser/speech/proto/speech_proto.target.linux-x86_64.mk b/content/browser/speech/proto/speech_proto.target.linux-x86_64.mk
index 909d011..01c2092 100644
--- a/content/browser/speech/proto/speech_proto.target.linux-x86_64.mk
+++ b/content/browser/speech/proto/speech_proto.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_browser_speech_proto_speech_proto_gyp_speech_proto_target_genproto":
 # "{'inputs': ['../../../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['google_streaming_api.proto'], 'action': ['python', '../../../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', '.', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/content/browser/speech/proto', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/content/browser/speech/proto/google_streaming_api_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,7 +66,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +158,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/browser/speech/speech_recognition_dispatcher_host.cc b/content/browser/speech/speech_recognition_dispatcher_host.cc
index 57b3bc6c..1c97a4f 100644
--- a/content/browser/speech/speech_recognition_dispatcher_host.cc
+++ b/content/browser/speech/speech_recognition_dispatcher_host.cc
@@ -105,8 +105,7 @@
   }
 
   // TODO(lazyboy): Check if filter_profanities should use |render_process_id|
-  // instead of |render_process_id_|. We are also using the same value in
-  // input_tag_dispatcher_host.cc
+  // instead of |render_process_id_|.
   bool filter_profanities =
       SpeechRecognitionManagerImpl::GetInstance() &&
       SpeechRecognitionManagerImpl::GetInstance()->delegate() &&
@@ -138,7 +137,6 @@
   if (embedder_render_process_id)
     context.guest_render_view_id = params.render_view_id;
   context.request_id = params.request_id;
-  context.requested_by_page_element = false;
 
   SpeechRecognitionSessionConfig config;
   config.is_legacy_api = false;
diff --git a/content/browser/speech/speech_recognition_manager_impl.cc b/content/browser/speech/speech_recognition_manager_impl.cc
index a9d3de5..4b0827a 100644
--- a/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/content/browser/speech/speech_recognition_manager_impl.cc
@@ -290,8 +290,8 @@
 
 // Here begins the SpeechRecognitionEventListener interface implementation,
 // which will simply relay the events to the proper listener registered for the
-// particular session (most likely InputTagSpeechDispatcherHost) and to the
-// catch-all listener provided by the delegate (if any).
+// particular session and to the catch-all listener provided by the delegate
+// (if any).
 
 void SpeechRecognitionManagerImpl::OnRecognitionStart(int session_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
diff --git a/content/browser/speech/speech_recognizer_impl.cc b/content/browser/speech/speech_recognizer_impl.cc
index b296cc0..3ba1f08 100644
--- a/content/browser/speech/speech_recognizer_impl.cc
+++ b/content/browser/speech/speech_recognizer_impl.cc
@@ -254,6 +254,7 @@
 }
 
 SpeechRecognizerImpl::~SpeechRecognizerImpl() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   endpointer_.EndSession();
   if (audio_controller_.get()) {
     audio_controller_->Close(
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc
index 03fb312..7fe7934 100644
--- a/content/browser/storage_partition_impl_map.cc
+++ b/content/browser/storage_partition_impl_map.cc
@@ -159,7 +159,7 @@
 
 base::FilePath GetStoragePartitionDomainPath(
     const std::string& partition_domain) {
-  CHECK(IsStringUTF8(partition_domain));
+  CHECK(base::IsStringUTF8(partition_domain));
 
   return base::FilePath(kStoragePartitionDirname).Append(kExtensionsDirname)
       .Append(base::FilePath::FromUTF8Unsafe(partition_domain));
diff --git a/content/browser/vibration/vibration_message_filter.cc b/content/browser/vibration/vibration_message_filter.cc
index b404748..8f35075 100644
--- a/content/browser/vibration/vibration_message_filter.cc
+++ b/content/browser/vibration/vibration_message_filter.cc
@@ -8,8 +8,8 @@
 
 #include "base/numerics/safe_conversions.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/vibration_provider.h"
 #include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/vibration_provider.h"
 #include "content/public/common/content_client.h"
 #include "third_party/WebKit/public/platform/WebVibration.h"
 
diff --git a/content/browser/vibration/vibration_provider_android.h b/content/browser/vibration/vibration_provider_android.h
index 58ada97..4d39c74 100644
--- a/content/browser/vibration/vibration_provider_android.h
+++ b/content/browser/vibration/vibration_provider_android.h
@@ -6,7 +6,7 @@
 #define CONTENT_BROWSER_VIBRATION_VIBRATION_PROVIDER_ANDROID_H_
 
 #include "base/android/jni_android.h"
-#include "content/port/browser/vibration_provider.h"
+#include "content/public/browser/vibration_provider.h"
 
 namespace content {
 
diff --git a/content/browser/web_contents/aura/gesture_nav_simple.cc b/content/browser/web_contents/aura/gesture_nav_simple.cc
index 7ae0557..44f16bc 100644
--- a/content/browser/web_contents/aura/gesture_nav_simple.cc
+++ b/content/browser/web_contents/aura/gesture_nav_simple.cc
@@ -8,8 +8,8 @@
 #include "content/browser/frame_host/navigation_controller_impl.h"
 #include "content/browser/renderer_host/overscroll_controller.h"
 #include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/public/browser/overscroll_configuration.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_client.h"
 #include "grit/ui_resources.h"
 #include "ui/aura/window.h"
@@ -159,7 +159,7 @@
 }
 
 gfx::Rect GestureNavSimple::GetVisibleBounds() const {
-  return web_contents_->GetView()->GetNativeView()->bounds();
+  return web_contents_->GetNativeView()->bounds();
 }
 
 void GestureNavSimple::OnOverscrollUpdate(float delta_x, float delta_y) {
@@ -199,7 +199,7 @@
   arrow_->set_delegate(arrow_delegate_.get());
   arrow_->SetFillsBoundsOpaquely(false);
 
-  aura::Window* window = web_contents_->GetView()->GetNativeView();
+  aura::Window* window = web_contents_->GetNativeView();
   const gfx::Rect& window_bounds = window->bounds();
   completion_threshold_ = window_bounds.width() *
       GetOverscrollConfig(OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE);
diff --git a/content/browser/web_contents/aura/overscroll_navigation_overlay.cc b/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
index 28ae712..1a17d90 100644
--- a/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
+++ b/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
@@ -301,8 +301,7 @@
   }
 }
 
-void OverscrollNavigationOverlay::DocumentOnLoadCompletedInMainFrame(
-    int32 page_id) {
+void OverscrollNavigationOverlay::DocumentOnLoadCompletedInMainFrame() {
   // Use the last committed entry rather than the active one, in case a
   // pending entry has been created.
   int committed_entry_id =
@@ -314,7 +313,7 @@
   }
 }
 
-void OverscrollNavigationOverlay::DidFirstVisuallyNonEmptyPaint(int32 page_id) {
+void OverscrollNavigationOverlay::DidFirstVisuallyNonEmptyPaint() {
   int visible_entry_id =
       web_contents_->GetController().GetVisibleEntry()->GetUniqueID();
   if (visible_entry_id == pending_entry_id_ || !pending_entry_id_) {
diff --git a/content/browser/web_contents/aura/overscroll_navigation_overlay.h b/content/browser/web_contents/aura/overscroll_navigation_overlay.h
index 18adf05..e401e17 100644
--- a/content/browser/web_contents/aura/overscroll_navigation_overlay.h
+++ b/content/browser/web_contents/aura/overscroll_navigation_overlay.h
@@ -91,8 +91,8 @@
   virtual void OnWindowSliderDestroyed() OVERRIDE;
 
   // Overridden from WebContentsObserver:
-  virtual void DocumentOnLoadCompletedInMainFrame(int32 page_id) OVERRIDE;
-  virtual void DidFirstVisuallyNonEmptyPaint(int32 page_id) OVERRIDE;
+  virtual void DocumentOnLoadCompletedInMainFrame() OVERRIDE;
+  virtual void DidFirstVisuallyNonEmptyPaint() OVERRIDE;
   virtual void DidStopLoading(RenderViewHost* host) OVERRIDE;
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
 
diff --git a/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc b/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
index 1e24364..a9419b3 100644
--- a/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
+++ b/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc
@@ -6,8 +6,8 @@
 
 #include "content/browser/frame_host/navigation_entry_impl.h"
 #include "content/browser/web_contents/aura/image_window_delegate.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/common/view_messages.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/mock_render_process_host.h"
 #include "content/test/test_render_view_host.h"
 #include "content/test/test_web_contents.h"
@@ -45,8 +45,7 @@
   }
 
   void ReceivePaintUpdate() {
-    ViewHostMsg_DidFirstVisuallyNonEmptyPaint msg(
-        test_rvh()->GetRoutingID(), 0);
+    ViewHostMsg_DidFirstVisuallyNonEmptyPaint msg(test_rvh()->GetRoutingID());
     RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg);
   }
 
diff --git a/content/browser/web_contents/touch_editable_impl_aura.cc b/content/browser/web_contents/touch_editable_impl_aura.cc
index be0addf..b161773 100644
--- a/content/browser/web_contents/touch_editable_impl_aura.cc
+++ b/content/browser/web_contents/touch_editable_impl_aura.cc
@@ -353,6 +353,10 @@
   EndTouchEditing(false);
 }
 
+void TouchEditableImplAura::DestroyTouchSelection() {
+  EndTouchEditing(false);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // TouchEditableImplAura, private:
 
diff --git a/content/browser/web_contents/touch_editable_impl_aura.h b/content/browser/web_contents/touch_editable_impl_aura.h
index 1d4a56d..dd19e8e 100644
--- a/content/browser/web_contents/touch_editable_impl_aura.h
+++ b/content/browser/web_contents/touch_editable_impl_aura.h
@@ -68,6 +68,7 @@
       int command_id,
       ui::Accelerator* accelerator) OVERRIDE;
   virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
+  virtual void DestroyTouchSelection() OVERRIDE;
 
  protected:
   TouchEditableImplAura();
diff --git a/content/browser/web_contents/touch_editable_impl_aura_browsertest.cc b/content/browser/web_contents/touch_editable_impl_aura_browsertest.cc
index c1641dc..0479984 100644
--- a/content/browser/web_contents/touch_editable_impl_aura_browsertest.cc
+++ b/content/browser/web_contents/touch_editable_impl_aura_browsertest.cc
@@ -12,7 +12,6 @@
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/browser/web_contents/web_contents_view_aura.h"
 #include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
@@ -140,8 +139,7 @@
     ASSERT_TRUE(test_server()->Start());
     GURL test_url(test_server()->GetURL(url));
     NavigateToURL(shell(), test_url);
-    aura::Window* content =
-        shell()->web_contents()->GetView()->GetContentNativeView();
+    aura::Window* content = shell()->web_contents()->GetContentNativeView();
     content->GetHost()->SetBounds(gfx::Rect(800, 600));
   }
 
@@ -176,7 +174,7 @@
   view_aura->SetTouchEditableForTest(touch_editable);
   RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
       web_contents->GetRenderWidgetHostView());
-  aura::Window* content = web_contents->GetView()->GetContentNativeView();
+  aura::Window* content = web_contents->GetContentNativeView();
   aura::test::EventGenerator generator(content->GetRootWindow(), content);
   gfx::Rect bounds = content->GetBoundsInRootWindow();
 
@@ -362,7 +360,7 @@
   view_aura->SetTouchEditableForTest(touch_editable);
   RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
       web_contents->GetRenderWidgetHostView());
-  aura::Window* content = web_contents->GetView()->GetContentNativeView();
+  aura::Window* content = web_contents->GetContentNativeView();
   aura::test::EventGenerator generator(content->GetRootWindow(), content);
   gfx::Rect bounds = content->GetBoundsInRootWindow();
   EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index b27d4c1..0f3ea7a 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -40,8 +40,10 @@
 #include "content/browser/message_port_service.h"
 #include "content/browser/power_save_blocker_impl.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/browser/renderer_host/render_view_host_delegate_view.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/site_instance_impl.h"
 #include "content/browser/web_contents/web_contents_view_guest.h"
 #include "content/browser/webui/generic_handler.h"
@@ -54,8 +56,6 @@
 #include "content/common/input_messages.h"
 #include "content/common/ssl_status_serialization.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_view_host_delegate_view.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/ax_event_notification_details.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/content_browser_client.h"
@@ -74,7 +74,6 @@
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/bindings_policy.h"
 #include "content/public/common/content_constants.h"
 #include "content/public/common/content_switches.h"
@@ -96,6 +95,7 @@
 
 #if defined(OS_ANDROID)
 #include "content/browser/android/date_time_chooser_android.h"
+#include "content/browser/media/android/browser_media_player_manager.h"
 #include "content/browser/renderer_host/java/java_bridge_dispatcher_host_manager.h"
 #include "content/browser/web_contents/web_contents_android.h"
 #include "content/common/java_bridge_messages.h"
@@ -289,8 +289,9 @@
   }
 
   // WebContentsObserver:
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
-    owner_->OnWebContentsDestroyed(static_cast<WebContentsImpl*>(web_contents));
+  virtual void WebContentsDestroyed() OVERRIDE {
+    owner_->OnWebContentsDestroyed(
+        static_cast<WebContentsImpl*>(web_contents()));
   }
 
  private:
@@ -363,14 +364,6 @@
 WebContentsImpl::~WebContentsImpl() {
   is_being_destroyed_ = true;
 
-  // If there is an interstitial page being shown, tell it to close down early
-  // so that this contents will be alive enough to handle all the UI triggered
-  // by that. <http://crbug.com/363564>
-  InterstitialPageImpl* interstitial_page =
-      static_cast<InterstitialPageImpl*>(GetInterstitialPage());
-  if (interstitial_page)
-    interstitial_page->WebContentsWillBeDestroyed();
-
   // Delete all RFH pending shutdown, which will lead the corresponding RVH to
   // shutdown and be deleted as well.
   frame_tree_.ForEach(
@@ -419,7 +412,11 @@
 
   FOR_EACH_OBSERVER(WebContentsObserver,
                     observers_,
-                    WebContentsImplDestroyed());
+                    WebContentsDestroyed());
+
+  FOR_EACH_OBSERVER(WebContentsObserver,
+                    observers_,
+                    ResetWebContents());
 
   SetDelegate(NULL);
 
@@ -514,6 +511,10 @@
     IPC_MESSAGE_HANDLER(FrameHostMsg_EndColorChooser, OnEndColorChooser)
     IPC_MESSAGE_HANDLER(FrameHostMsg_SetSelectedColorInColorChooser,
                         OnSetSelectedColorInColorChooser)
+    IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPlayingNotification,
+                        OnMediaPlayingNotification)
+    IPC_MESSAGE_HANDLER(FrameHostMsg_MediaPausedNotification,
+                        OnMediaPausedNotification)
     IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache,
                         OnDidLoadResourceFromMemoryCache)
     IPC_MESSAGE_HANDLER(ViewHostMsg_DidDisplayInsecureContent,
@@ -536,10 +537,6 @@
                                 OnBrowserPluginMessage(message))
     IPC_MESSAGE_HANDLER(ImageHostMsg_DidDownloadImage, OnDidDownloadImage)
     IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFaviconURL, OnUpdateFaviconURL)
-    IPC_MESSAGE_HANDLER(ViewHostMsg_MediaPlayingNotification,
-                        OnMediaPlayingNotification)
-    IPC_MESSAGE_HANDLER(ViewHostMsg_MediaPausedNotification,
-                        OnMediaPausedNotification)
     IPC_MESSAGE_HANDLER(ViewHostMsg_DidFirstVisuallyNonEmptyPaint,
                         OnFirstVisuallyNonEmptyPaint)
     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowValidationMessage,
@@ -683,14 +680,6 @@
   return GetRenderManager()->GetRenderWidgetHostView();
 }
 
-RenderWidgetHostViewPort* WebContentsImpl::GetRenderWidgetHostViewPort() const {
-  BrowserPluginGuest* guest = GetBrowserPluginGuest();
-  if (guest && guest->embedder_web_contents()) {
-    return guest->embedder_web_contents()->GetRenderWidgetHostViewPort();
-  }
-  return RenderWidgetHostViewPort::FromRWHV(GetRenderWidgetHostView());
-}
-
 RenderWidgetHostView* WebContentsImpl::GetFullscreenRenderWidgetHostView()
     const {
   RenderWidgetHost* const widget_host =
@@ -967,8 +956,7 @@
 
 void WebContentsImpl::WasShown() {
   controller_.SetActive(true);
-  RenderWidgetHostViewPort* rwhv =
-      RenderWidgetHostViewPort::FromRWHV(GetRenderWidgetHostView());
+  RenderWidgetHostView* rwhv = GetRenderWidgetHostView();
   if (rwhv) {
     rwhv->Show();
 #if defined(OS_MACOSX)
@@ -1001,8 +989,7 @@
     // removes the |GetRenderViewHost()|; then when we actually destroy the
     // window, OnWindowPosChanged() notices and calls WasHidden() (which
     // calls us).
-    RenderWidgetHostViewPort* rwhv =
-        RenderWidgetHostViewPort::FromRWHV(GetRenderWidgetHostView());
+    RenderWidgetHostView* rwhv = GetRenderWidgetHostView();
     if (rwhv)
       rwhv->Hide();
   }
@@ -1035,7 +1022,7 @@
   // We pass our own opener so that the cloned page can access it if it was
   // before.
   CreateParams create_params(GetBrowserContext(), GetSiteInstance());
-  create_params.initial_size = view_->GetContainerSize();
+  create_params.initial_size = GetContainerBounds().size();
   WebContentsImpl* tc = CreateWithOpener(create_params, opener_);
   tc->GetController().CopyStateFrom(controller_);
   FOR_EACH_OBSERVER(WebContentsObserver,
@@ -1078,30 +1065,24 @@
       params.browser_context, params.site_instance, params.routing_id,
       params.main_frame_routing_id);
 
-  view_.reset(GetContentClient()->browser()->
-      OverrideCreateWebContentsView(this, &render_view_host_delegate_view_));
-  if (view_) {
-    CHECK(render_view_host_delegate_view_);
+  WebContentsViewDelegate* delegate =
+      GetContentClient()->browser()->GetWebContentsViewDelegate(this);
+
+  if (browser_plugin_guest_) {
+    scoped_ptr<WebContentsView> platform_view(CreateWebContentsView(
+        this, delegate, &render_view_host_delegate_view_));
+
+    WebContentsViewGuest* rv = new WebContentsViewGuest(
+        this, browser_plugin_guest_.get(), platform_view.Pass(),
+        render_view_host_delegate_view_);
+    render_view_host_delegate_view_ = rv;
+    view_.reset(rv);
   } else {
-    WebContentsViewDelegate* delegate =
-        GetContentClient()->browser()->GetWebContentsViewDelegate(this);
-
-    if (browser_plugin_guest_) {
-      scoped_ptr<WebContentsViewPort> platform_view(CreateWebContentsView(
-          this, delegate, &render_view_host_delegate_view_));
-
-      WebContentsViewGuest* rv = new WebContentsViewGuest(
-          this, browser_plugin_guest_.get(), platform_view.Pass(),
-          render_view_host_delegate_view_);
-      render_view_host_delegate_view_ = rv;
-      view_.reset(rv);
-    } else {
-      // Regular WebContentsView.
-      view_.reset(CreateWebContentsView(
-          this, delegate, &render_view_host_delegate_view_));
-    }
-    CHECK(render_view_host_delegate_view_);
+    // Regular WebContentsView.
+    view_.reset(CreateWebContentsView(
+        this, delegate, &render_view_host_delegate_view_));
   }
+  CHECK(render_view_host_delegate_view_);
   CHECK(view_.get());
 
   gfx::Size initial_size = params.initial_size;
@@ -1438,11 +1419,13 @@
   create_params.main_frame_routing_id = main_frame_route_id;
   if (!is_guest) {
     create_params.context = view_->GetNativeView();
-    create_params.initial_size = view_->GetContainerSize();
+    create_params.initial_size = GetContainerBounds().size();
   } else {
     // This makes |new_contents| act as a guest.
     // For more info, see comment above class BrowserPluginGuest.
-    int instance_id = GetBrowserPluginGuestManager()->get_next_instance_id();
+    int instance_id =
+        BrowserPluginGuestManager::FromBrowserContext(GetBrowserContext())->
+            GetNextInstanceID();
     WebContentsImpl* new_contents_impl =
         static_cast<WebContentsImpl*>(new_contents);
     BrowserPluginGuest::CreateWithOpener(instance_id,
@@ -1458,7 +1441,7 @@
   // will be shown immediately).
   if (!params.opener_suppressed) {
     if (!is_guest) {
-      WebContentsViewPort* new_view = new_contents->view_.get();
+      WebContentsView* new_view = new_contents->view_.get();
 
       // TODO(brettw): It seems bogus that we have to call this function on the
       // newly created object and give it one of its own member variables.
@@ -1533,8 +1516,9 @@
       new RenderWidgetHostImpl(this, process, route_id, IsHidden());
   created_widgets_.insert(widget_host);
 
-  RenderWidgetHostViewPort* widget_view = RenderWidgetHostViewPort::FromRWHV(
-      view_->CreateViewForPopupWidget(widget_host));
+  RenderWidgetHostViewBase* widget_view =
+      static_cast<RenderWidgetHostViewBase*>(
+          view_->CreateViewForPopupWidget(widget_host));
   if (!widget_view)
     return;
   if (!is_fullscreen) {
@@ -1577,10 +1561,19 @@
 void WebContentsImpl::ShowCreatedWidget(int route_id,
                                         bool is_fullscreen,
                                         const gfx::Rect& initial_pos) {
-  RenderWidgetHostViewPort* widget_host_view =
-      RenderWidgetHostViewPort::FromRWHV(GetCreatedWidget(route_id));
+  RenderWidgetHostViewBase* widget_host_view =
+      static_cast<RenderWidgetHostViewBase*>(GetCreatedWidget(route_id));
   if (!widget_host_view)
     return;
+
+  RenderWidgetHostView* view = NULL;
+  BrowserPluginGuest* guest = GetBrowserPluginGuest();
+  if (guest && guest->embedder_web_contents()) {
+    view = guest->embedder_web_contents()->GetRenderWidgetHostView();
+  } else {
+    view = GetRenderWidgetHostView();
+  }
+
   if (is_fullscreen) {
     DCHECK_EQ(MSG_ROUTING_NONE, fullscreen_widget_routing_id_);
     fullscreen_widget_routing_id_ = route_id;
@@ -1588,7 +1581,7 @@
       widget_host_view->InitAsChild(GetRenderWidgetHostView()->GetNativeView());
       delegate_->ToggleFullscreenModeForTab(this, true);
     } else {
-      widget_host_view->InitAsFullscreen(GetRenderWidgetHostViewPort());
+      widget_host_view->InitAsFullscreen(view);
     }
     FOR_EACH_OBSERVER(WebContentsObserver,
                       observers_,
@@ -1596,7 +1589,7 @@
     if (!widget_host_view->HasFocus())
       widget_host_view->Focus();
   } else {
-    widget_host_view->InitAsPopup(GetRenderWidgetHostViewPort(), initial_pos);
+    widget_host_view->InitAsPopup(view, initial_pos);
   }
 
   RenderWidgetHostImpl* render_widget_host_impl =
@@ -1948,6 +1941,48 @@
       focused_frame->GetRoutingID(), context, action));
 }
 
+gfx::NativeView WebContentsImpl::GetNativeView() {
+  return view_->GetNativeView();
+}
+
+gfx::NativeView WebContentsImpl::GetContentNativeView() {
+  return view_->GetContentNativeView();
+}
+
+gfx::NativeWindow WebContentsImpl::GetTopLevelNativeWindow() {
+  return view_->GetTopLevelNativeWindow();
+}
+
+gfx::Rect WebContentsImpl::GetViewBounds() {
+  return view_->GetViewBounds();
+}
+
+gfx::Rect WebContentsImpl::GetContainerBounds() {
+  gfx::Rect rv;
+  view_->GetContainerBounds(&rv);
+  return rv;
+}
+
+DropData* WebContentsImpl::GetDropData() {
+  return view_->GetDropData();
+}
+
+void WebContentsImpl::Focus() {
+  view_->Focus();
+}
+
+void WebContentsImpl::SetInitialFocus() {
+  view_->SetInitialFocus();
+}
+
+void WebContentsImpl::StoreFocus() {
+  view_->StoreFocus();
+}
+
+void WebContentsImpl::RestoreFocus() {
+  view_->RestoreFocus();
+}
+
 void WebContentsImpl::FocusThroughTabTraversal(bool reverse) {
   if (ShowingInterstitialPage()) {
     GetRenderManager()->interstitial_page()->FocusThroughTabTraversal(reverse);
@@ -2803,10 +2838,9 @@
 }
 
 void WebContentsImpl::OnUpdateFaviconURL(
-    int32 page_id,
     const std::vector<FaviconURL>& candidates) {
   FOR_EACH_OBSERVER(WebContentsObserver, observers_,
-                    DidUpdateFaviconURL(page_id, candidates));
+                    DidUpdateFaviconURL(candidates));
 }
 
 void WebContentsImpl::OnMediaPlayingNotification(int64 player_cookie,
@@ -2828,7 +2862,7 @@
   }
 
   if (blocker) {
-    power_save_blockers_[render_view_message_source_][player_cookie] =
+    power_save_blockers_[render_frame_message_source_][player_cookie] =
         blocker.release();
   }
 #endif  // !defined(OS_CHROMEOS)
@@ -2837,14 +2871,14 @@
 void WebContentsImpl::OnMediaPausedNotification(int64 player_cookie) {
   // Chrome OS does its own detection of audio and video.
 #if !defined(OS_CHROMEOS)
-  delete power_save_blockers_[render_view_message_source_][player_cookie];
-  power_save_blockers_[render_view_message_source_].erase(player_cookie);
+  delete power_save_blockers_[render_frame_message_source_][player_cookie];
+  power_save_blockers_[render_frame_message_source_].erase(player_cookie);
 #endif  // !defined(OS_CHROMEOS)
 }
 
-void WebContentsImpl::OnFirstVisuallyNonEmptyPaint(int32 page_id) {
+void WebContentsImpl::OnFirstVisuallyNonEmptyPaint() {
   FOR_EACH_OBSERVER(WebContentsObserver, observers_,
-                    DidFirstVisuallyNonEmptyPaint(page_id));
+                    DidFirstVisuallyNonEmptyPaint());
 }
 
 void WebContentsImpl::DidChangeVisibleSSLState() {
@@ -3047,6 +3081,7 @@
 }
 
 void WebContentsImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
+  ClearPowerSaveBlockers(render_frame_host);
   FOR_EACH_OBSERVER(WebContentsObserver,
                     observers_,
                     RenderFrameDeleted(render_frame_host));
@@ -3067,7 +3102,7 @@
 }
 
 void WebContentsImpl::RunJavaScriptMessage(
-    RenderFrameHost* rfh,
+    RenderFrameHost* render_frame_host,
     const base::string16& message,
     const base::string16& default_prompt,
     const GURL& frame_url,
@@ -3077,7 +3112,7 @@
   // showing an interstitial as it's shown over the previous page and we don't
   // want the hidden page's dialogs to interfere with the interstitial.
   bool suppress_this_message =
-      static_cast<RenderViewHostImpl*>(rfh->GetRenderViewHost())->
+      static_cast<RenderViewHostImpl*>(render_frame_host->GetRenderViewHost())->
           IsSwappedOut() ||
       ShowingInterstitialPage() ||
       !delegate_ ||
@@ -3097,8 +3132,8 @@
         default_prompt,
         base::Bind(&WebContentsImpl::OnDialogClosed,
                    base::Unretained(this),
-                   rfh->GetProcess()->GetID(),
-                   rfh->GetRoutingID(),
+                   render_frame_host->GetProcess()->GetID(),
+                   render_frame_host->GetRoutingID(),
                    reply_msg,
                    false),
         &suppress_this_message);
@@ -3107,7 +3142,8 @@
   if (suppress_this_message) {
     // If we are suppressing messages, just reply as if the user immediately
     // pressed "Cancel", passing true to |dialog_was_suppressed|.
-    OnDialogClosed(rfh->GetProcess()->GetID(), rfh->GetRoutingID(), reply_msg,
+    OnDialogClosed(render_frame_host->GetProcess()->GetID(),
+                   render_frame_host->GetRoutingID(), reply_msg,
                    true, false, base::string16());
   }
 
@@ -3116,13 +3152,14 @@
 }
 
 void WebContentsImpl::RunBeforeUnloadConfirm(
-    RenderFrameHost* rfh,
+    RenderFrameHost* render_frame_host,
     const base::string16& message,
     bool is_reload,
     IPC::Message* reply_msg) {
-  RenderFrameHostImpl* rfhi = static_cast<RenderFrameHostImpl*>(rfh);
+  RenderFrameHostImpl* rfhi =
+      static_cast<RenderFrameHostImpl*>(render_frame_host);
   RenderViewHostImpl* rvhi =
-      static_cast<RenderViewHostImpl*>(rfh->GetRenderViewHost());
+      static_cast<RenderViewHostImpl*>(render_frame_host->GetRenderViewHost());
   if (delegate_)
     delegate_->WillRunBeforeUnloadConfirm();
 
@@ -3141,7 +3178,8 @@
   dialog_manager_->RunBeforeUnloadDialog(
       this, message, is_reload,
       base::Bind(&WebContentsImpl::OnDialogClosed, base::Unretained(this),
-                 rfh->GetProcess()->GetID(), rfh->GetRoutingID(), reply_msg,
+                 render_frame_host->GetProcess()->GetID(),
+                 render_frame_host->GetRoutingID(), reply_msg,
                  false));
 }
 
@@ -3259,11 +3297,14 @@
   if (dialog_manager_)
     dialog_manager_->CancelActiveAndPendingDialogs(this);
 
-  ClearPowerSaveBlockers(rvh);
   SetIsLoading(rvh, false, true, NULL);
   NotifyDisconnected();
   SetIsCrashed(status, error_code);
-  GetView()->OnTabCrashed(GetCrashedStatus(), crashed_error_code_);
+
+#if defined(OS_ANDROID)
+  if (GetRenderViewHostImpl()->media_player_manager())
+    GetRenderViewHostImpl()->media_player_manager()->DestroyAllMediaPlayers();
+#endif
 
   FOR_EACH_OBSERVER(WebContentsObserver,
                     observers_,
@@ -3271,8 +3312,6 @@
 }
 
 void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) {
-  ClearPowerSaveBlockers(rvh);
-  GetRenderManager()->RenderViewDeleted(rvh);
   FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewDeleted(rvh));
 }
 
@@ -3419,20 +3458,6 @@
     delegate_->LoadProgressChanged(this, progress);
 }
 
-void WebContentsImpl::DidDisownOpener(RenderViewHost* rvh) {
-  if (opener_) {
-    // Clear our opener so that future cross-process navigations don't have an
-    // opener assigned.
-    RemoveDestructionObserver(opener_);
-    opener_ = NULL;
-  }
-
-  // Notify all swapped out RenderViewHosts for this tab.  This is important
-  // in case we go back to them, or if another window in those processes tries
-  // to access window.opener.
-  GetRenderManager()->DidDisownOpener(rvh);
-}
-
 void WebContentsImpl::DidAccessInitialDocument() {
   has_accessed_initial_document_ = true;
 
@@ -3446,25 +3471,37 @@
   NotifyNavigationStateChanged(content::INVALIDATE_TYPE_URL);
 }
 
-void WebContentsImpl::DocumentAvailableInMainFrame(
-    RenderViewHost* render_view_host) {
-  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
-                    DocumentAvailableInMainFrame());
+void WebContentsImpl::DidDisownOpener(RenderFrameHost* render_frame_host) {
+  if (opener_) {
+    // Clear our opener so that future cross-process navigations don't have an
+    // opener assigned.
+    RemoveDestructionObserver(opener_);
+    opener_ = NULL;
+  }
+
+  // Notify all swapped out RenderViewHosts for this tab.  This is important
+  // in case we go back to them, or if another window in those processes tries
+  // to access window.opener.
+  GetRenderManager()->DidDisownOpener(render_frame_host->GetRenderViewHost());
 }
 
-void WebContentsImpl::DocumentOnLoadCompletedInMainFrame(
-    RenderViewHost* render_view_host,
-    int32 page_id) {
+void WebContentsImpl::DocumentOnLoadCompleted(
+    RenderFrameHost* render_frame_host) {
   FOR_EACH_OBSERVER(WebContentsObserver, observers_,
-                    DocumentOnLoadCompletedInMainFrame(page_id));
+                    DocumentOnLoadCompletedInMainFrame());
 
   // TODO(avi): Remove. http://crbug.com/170921
   NotificationService::current()->Notify(
       NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
       Source<WebContents>(this),
-      Details<int>(&page_id));
+      NotificationService::NoDetails());
 }
 
+void WebContentsImpl::DocumentAvailableInMainFrame(
+    RenderViewHost* render_view_host) {
+  FOR_EACH_OBSERVER(WebContentsObserver, observers_,
+                    DocumentAvailableInMainFrame());
+}
 void WebContentsImpl::RouteCloseEvent(RenderViewHost* rvh) {
   // Tell the active RenderViewHost to run unload handlers and close, as long
   // as the request came from a RenderViewHost in the same BrowsingInstance.
@@ -3495,15 +3532,9 @@
     MessagePortMessageFilter* message_port_message_filter =
         static_cast<RenderProcessHostImpl*>(GetRenderProcessHost())
             ->message_port_message_filter();
-    std::vector<int> new_routing_ids(params.message_port_ids.size());
-    for (size_t i = 0; i < params.message_port_ids.size(); ++i) {
-      new_routing_ids[i] = message_port_message_filter->GetNextRoutingID();
-      MessagePortService::GetInstance()->UpdateMessagePort(
-          params.message_port_ids[i],
-          message_port_message_filter,
-          new_routing_ids[i]);
-    }
-    new_params.new_routing_ids = new_routing_ids;
+    message_port_message_filter->UpdateMessagePortsWithNewRoutes(
+        params.message_port_ids,
+        &new_params.new_routing_ids);
   }
 
   // If there is a source_routing_id, translate it to the routing ID for
@@ -3754,7 +3785,7 @@
     CrossProcessFrameConnector* frame_connector) {
   TRACE_EVENT0("browser", "WebContentsImpl::CreateRenderViewForRenderManager");
   // Can be NULL during tests.
-  RenderWidgetHostView* rwh_view;
+  RenderWidgetHostViewBase* rwh_view;
   // TODO(kenrb): RenderWidgetHostViewChildFrame special casing is temporary
   // until RenderWidgetHost is attached to RenderFrameHost. We need to special
   // case this because RWH is still a base class of RenderViewHost, and child
@@ -3798,6 +3829,7 @@
 }
 
 #if defined(OS_ANDROID)
+
 base::android::ScopedJavaLocalRef<jobject>
 WebContentsImpl::GetJavaWebContents() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -3816,6 +3848,27 @@
                                           MSG_ROUTING_NONE,
                                           NULL);
 }
+
+#elif defined(OS_MACOSX)
+
+void WebContentsImpl::SetAllowOverlappingViews(bool overlapping) {
+  view_->SetAllowOverlappingViews(overlapping);
+}
+
+bool WebContentsImpl::GetAllowOverlappingViews() {
+  return view_->GetAllowOverlappingViews();
+}
+
+void WebContentsImpl::SetOverlayView(WebContents* overlay,
+                                     const gfx::Point& offset) {
+  view_->SetOverlayView(static_cast<WebContentsImpl*>(overlay)->GetView(),
+                        offset);
+}
+
+void WebContentsImpl::RemoveOverlayView() {
+  view_->RemoveOverlayView();
+}
+
 #endif
 
 void WebContentsImpl::OnDialogClosed(int render_process_id,
@@ -3855,10 +3908,10 @@
 }
 
 void WebContentsImpl::CreateViewAndSetSizeForRVH(RenderViewHost* rvh) {
-  RenderWidgetHostView* rwh_view = view_->CreateViewForWidget(rvh);
+  RenderWidgetHostViewBase* rwh_view = view_->CreateViewForWidget(rvh);
   // Can be NULL during tests.
   if (rwh_view)
-    rwh_view->SetSize(GetView()->GetContainerSize());
+    rwh_view->SetSize(GetContainerBounds().size());
 }
 
 bool WebContentsImpl::IsHidden() {
@@ -3886,17 +3939,10 @@
   return browser_plugin_embedder_.get();
 }
 
-BrowserPluginGuestManager*
-    WebContentsImpl::GetBrowserPluginGuestManager() const {
-  return static_cast<BrowserPluginGuestManager*>(
-      GetBrowserContext()->GetUserData(
-          browser_plugin::kBrowserPluginGuestManagerKeyName));
-}
-
 void WebContentsImpl::ClearPowerSaveBlockers(
-    RenderViewHost* render_view_host) {
-  STLDeleteValues(&power_save_blockers_[render_view_host]);
-  power_save_blockers_.erase(render_view_host);
+    RenderFrameHost* render_frame_host) {
+  STLDeleteValues(&power_save_blockers_[render_frame_host]);
+  power_save_blockers_.erase(render_frame_host);
 }
 
 void WebContentsImpl::ClearAllPowerSaveBlockers() {
@@ -3906,12 +3952,12 @@
   power_save_blockers_.clear();
 }
 
-gfx::Size WebContentsImpl::GetSizeForNewRenderView() const {
+gfx::Size WebContentsImpl::GetSizeForNewRenderView() {
   gfx::Size size;
   if (delegate_)
     size = delegate_->GetSizeForNewRenderView(this);
   if (size.IsEmpty())
-    size = view_->GetContainerSize();
+    size = GetContainerBounds().size();
   return size;
 }
 
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index d275e5c..92c8fea 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -56,7 +56,6 @@
 class RenderViewHostDelegateView;
 class RenderViewHostImpl;
 class RenderWidgetHostImpl;
-class RenderWidgetHostViewPort;
 class SavePackage;
 class SessionStorageNamespaceImpl;
 class SiteInstance;
@@ -64,7 +63,7 @@
 class WebContentsDelegate;
 class WebContentsImpl;
 class WebContentsObserver;
-class WebContentsViewPort;
+class WebContentsView;
 class WebContentsViewDelegate;
 struct AXEventNotificationDetails;
 struct ColorSuggestion;
@@ -75,7 +74,7 @@
 
 // Factory function for the implementations that content knows about. Takes
 // ownership of |delegate|.
-WebContentsViewPort* CreateWebContentsView(
+WebContentsView* CreateWebContentsView(
     WebContentsImpl* web_contents,
     WebContentsViewDelegate* delegate,
     RenderViewHostDelegateView** render_view_host_delegate_view);
@@ -150,10 +149,6 @@
   // an embedder.
   BrowserPluginEmbedder* GetBrowserPluginEmbedder() const;
 
-  // Returns the BrowserPluginGuestManager object, or NULL if this web contents
-  // does not have a BrowserPluginGuestManager.
-  BrowserPluginGuestManager* GetBrowserPluginGuestManager() const;
-
   // Gets the current fullscreen render widget's routing ID. Returns
   // MSG_ROUTING_NONE when there is no fullscreen render widget.
   int GetFullscreenWidgetRoutingID() const;
@@ -175,6 +170,8 @@
       RenderViewHost* render_view_host,
       const ResourceRedirectDetails& details);
 
+  WebContentsView* GetView() const;
+
   // WebContents ------------------------------------------------------
   virtual WebContentsDelegate* GetDelegate() OVERRIDE;
   virtual void SetDelegate(WebContentsDelegate* delegate) OVERRIDE;
@@ -197,7 +194,6 @@
   virtual RenderWidgetHostView* GetRenderWidgetHostView() const OVERRIDE;
   virtual RenderWidgetHostView* GetFullscreenRenderWidgetHostView() const
       OVERRIDE;
-  virtual WebContentsView* GetView() const OVERRIDE;
   virtual WebUI* CreateWebUI(const GURL& url) OVERRIDE;
   virtual WebUI* GetWebUI() const OVERRIDE;
   virtual WebUI* GetCommittedWebUI() const OVERRIDE;
@@ -255,6 +251,16 @@
       const CustomContextMenuContext& context) OVERRIDE;
   virtual void ExecuteCustomContextMenuCommand(
       int action, const CustomContextMenuContext& context) OVERRIDE;
+  virtual gfx::NativeView GetNativeView() OVERRIDE;
+  virtual gfx::NativeView GetContentNativeView() OVERRIDE;
+  virtual gfx::NativeWindow GetTopLevelNativeWindow() OVERRIDE;
+  virtual gfx::Rect GetContainerBounds() OVERRIDE;
+  virtual gfx::Rect GetViewBounds() OVERRIDE;
+  virtual DropData* GetDropData() OVERRIDE;
+  virtual void Focus() OVERRIDE;
+  virtual void SetInitialFocus() OVERRIDE;
+  virtual void StoreFocus() OVERRIDE;
+  virtual void RestoreFocus() OVERRIDE;
   virtual void FocusThroughTabTraversal(bool reverse) OVERRIDE;
   virtual bool ShowingInterstitialPage() const OVERRIDE;
   virtual InterstitialPage* GetInterstitialPage() const OVERRIDE;
@@ -308,6 +314,12 @@
 #if defined(OS_ANDROID)
   virtual base::android::ScopedJavaLocalRef<jobject> GetJavaWebContents()
       OVERRIDE;
+#elif defined(OS_MACOSX)
+  virtual void SetAllowOverlappingViews(bool overlapping) OVERRIDE;
+  virtual bool GetAllowOverlappingViews() OVERRIDE;
+  virtual void SetOverlayView(WebContents* overlay,
+                              const gfx::Point& offset) OVERRIDE;
+  virtual void RemoveOverlayView() OVERRIDE;
 #endif
 
   // Implementation of PageNavigator.
@@ -329,17 +341,20 @@
   virtual void WorkerCrashed(RenderFrameHost* render_frame_host) OVERRIDE;
   virtual void ShowContextMenu(RenderFrameHost* render_frame_host,
                                const ContextMenuParams& params) OVERRIDE;
-  virtual void RunJavaScriptMessage(RenderFrameHost* rfh,
+  virtual void RunJavaScriptMessage(RenderFrameHost* render_frame_host,
                                     const base::string16& message,
                                     const base::string16& default_prompt,
                                     const GURL& frame_url,
                                     JavaScriptMessageType type,
                                     IPC::Message* reply_msg) OVERRIDE;
-  virtual void RunBeforeUnloadConfirm(RenderFrameHost* rfh,
+  virtual void RunBeforeUnloadConfirm(RenderFrameHost* render_frame_host,
                                       const base::string16& message,
                                       bool is_reload,
                                       IPC::Message* reply_msg) OVERRIDE;
   virtual void DidAccessInitialDocument() OVERRIDE;
+  virtual void DidDisownOpener(RenderFrameHost* render_frame_host) OVERRIDE;
+  virtual void DocumentOnLoadCompleted(
+      RenderFrameHost* render_frame_host) OVERRIDE;
   virtual WebContents* GetAsWebContents() OVERRIDE;
   virtual bool IsNeverVisible() OVERRIDE;
 
@@ -371,12 +386,8 @@
   virtual void RequestMove(const gfx::Rect& new_bounds) OVERRIDE;
   virtual void DidCancelLoading() OVERRIDE;
   virtual void DidChangeLoadProgress(double progress) OVERRIDE;
-  virtual void DidDisownOpener(RenderViewHost* rvh) OVERRIDE;
   virtual void DocumentAvailableInMainFrame(
       RenderViewHost* render_view_host) OVERRIDE;
-  virtual void DocumentOnLoadCompletedInMainFrame(
-      RenderViewHost* render_view_host,
-      int32 page_id) OVERRIDE;
   virtual void RouteCloseEvent(RenderViewHost* rvh) OVERRIDE;
   virtual void RouteMessageEvent(
       RenderViewHost* rvh,
@@ -748,9 +759,8 @@
                           const GURL& image_url,
                           const std::vector<SkBitmap>& bitmaps,
                           const std::vector<gfx::Size>& original_bitmap_sizes);
-  void OnUpdateFaviconURL(int32 page_id,
-                          const std::vector<FaviconURL>& candidates);
-  void OnFirstVisuallyNonEmptyPaint(int32 page_id);
+  void OnUpdateFaviconURL(const std::vector<FaviconURL>& candidates);
+  void OnFirstVisuallyNonEmptyPaint();
   void OnMediaPlayingNotification(int64 player_cookie,
                                   bool has_video,
                                   bool has_audio);
@@ -819,13 +829,6 @@
   // called once as this call also removes it from the internal map.
   WebContentsImpl* GetCreatedWindow(int route_id);
 
-  // Returns the RenderWidgetHostView that is associated with a native window
-  // and can be used in showing created widgets.
-  // If this WebContents belongs to a browser plugin guest, there is no native
-  // window 'view' associated with this WebContents. This method returns the
-  // 'view' of the embedder instead.
-  RenderWidgetHostViewPort* GetRenderWidgetHostViewPort() const;
-
   // Misc non-view stuff -------------------------------------------------------
 
   // Helper functions for sending notifications.
@@ -843,14 +846,14 @@
   // Removes browser plugin embedder if there is one.
   void RemoveBrowserPluginEmbedder();
 
-  // Clear |render_view_host|'s PowerSaveBlockers.
-  void ClearPowerSaveBlockers(RenderViewHost* render_view_host);
+  // Clear |render_frame_host|'s PowerSaveBlockers.
+  void ClearPowerSaveBlockers(RenderFrameHost* render_frame_host);
 
   // Clear all PowerSaveBlockers, leave power_save_blocker_ empty.
   void ClearAllPowerSaveBlockers();
 
   // Helper function to invoke WebContentsDelegate::GetSizeForNewRenderView().
-  gfx::Size GetSizeForNewRenderView() const;
+  gfx::Size GetSizeForNewRenderView();
 
   void OnFrameRemoved(RenderViewHostImpl* render_view_host,
                       int frame_routing_id);
@@ -874,7 +877,7 @@
   NavigationControllerImpl controller_;
 
   // The corresponding view.
-  scoped_ptr<WebContentsViewPort> view_;
+  scoped_ptr<WebContentsView> view_;
 
   // The view of the RVHD. Usually this is our WebContentsView implementation,
   // but if an embedder uses a different WebContentsView, they'll need to
@@ -914,10 +917,10 @@
 
   // Helper classes ------------------------------------------------------------
 
-  // Maps the RenderViewHost to its media_player_cookie and PowerSaveBlocker
-  // pairs. Key is the RenderViewHost, value is the map which maps player_cookie
-  // on to PowerSaveBlocker.
-  typedef std::map<RenderViewHost*, std::map<int64, PowerSaveBlocker*> >
+  // Maps the RenderFrameHost to its media_player_cookie and PowerSaveBlocker
+  // pairs. Key is the RenderFrameHost, value is the map which maps
+  // player_cookie on to PowerSaveBlocker.
+  typedef std::map<RenderFrameHost*, std::map<int64, PowerSaveBlocker*> >
       PowerSaveBlockerMap;
   PowerSaveBlockerMap power_save_blockers_;
 
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc
index b414ccd..a8ada8f 100644
--- a/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -6,6 +6,7 @@
 #include "base/values.h"
 #include "content/browser/frame_host/navigation_entry_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/public/browser/load_notification_details.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/notification_details.h"
@@ -14,7 +15,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_paths.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
@@ -40,7 +40,8 @@
   if (set_start_page)
     NavigateToURL(shell, GURL("about://blank"));
 #else
-  shell->web_contents()->GetView()->SizeContents(size);
+  static_cast<WebContentsImpl*>(shell->web_contents())->GetView()->
+      SizeContents(size);
 #endif  // defined(OS_MACOSX)
 }
 
@@ -113,8 +114,8 @@
 
   // WebContentsDelegate:
   virtual gfx::Size GetSizeForNewRenderView(
-      const WebContents* web_contents) const OVERRIDE {
-    gfx::Size size(web_contents->GetView()->GetContainerSize());
+      WebContents* web_contents) const OVERRIDE {
+    gfx::Size size(web_contents->GetContainerBounds().size());
     size.Enlarge(size_insets_.width(), size_insets_.height());
     return size;
   }
@@ -284,7 +285,7 @@
   // When no size is set, RenderWidgetHostView adopts the size of
   // WebContentsView.
   NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html"));
-  EXPECT_EQ(shell()->web_contents()->GetView()->GetContainerSize(),
+  EXPECT_EQ(shell()->web_contents()->GetContainerBounds().size(),
             shell()->web_contents()->GetRenderWidgetHostView()->GetViewBounds().
                 size());
 
@@ -308,7 +309,7 @@
 #endif
 
   EXPECT_EQ(exp_wcv_size,
-            shell()->web_contents()->GetView()->GetContainerSize());
+            shell()->web_contents()->GetContainerBounds().size());
 
   // If WebContentsView is resized after RenderWidgetHostView is created but
   // before pending navigation entry is committed, both RenderWidgetHostView and
@@ -334,7 +335,7 @@
       GetViewBounds().size();
 
   EXPECT_EQ(new_size, actual_size);
-  EXPECT_EQ(new_size, shell()->web_contents()->GetView()->GetContainerSize());
+  EXPECT_EQ(new_size, shell()->web_contents()->GetContainerBounds().size());
 }
 
 IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, OpenURLSubframe) {
diff --git a/content/browser/web_contents/web_contents_view.h b/content/browser/web_contents/web_contents_view.h
new file mode 100644
index 0000000..b2eb509
--- /dev/null
+++ b/content/browser/web_contents/web_contents_view.h
@@ -0,0 +1,137 @@
+// Copyright (c) 2012 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.
+
+#ifndef CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/strings/string16.h"
+#include "content/common/content_export.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/size.h"
+
+namespace content {
+class RenderViewHost;
+class RenderWidgetHost;
+class RenderWidgetHostViewBase;
+struct DropData;
+
+// The WebContentsView is an interface that is implemented by the platform-
+// dependent web contents views. The WebContents uses this interface to talk to
+// them.
+class WebContentsView {
+ public:
+  virtual ~WebContentsView() {}
+
+  // Returns the native widget that contains the contents of the tab.
+  virtual gfx::NativeView GetNativeView() const = 0;
+
+  // Returns the native widget with the main content of the tab (i.e. the main
+  // render view host, though there may be many popups in the tab as children of
+  // the container).
+  virtual gfx::NativeView GetContentNativeView() const = 0;
+
+  // Returns the outermost native view. This will be used as the parent for
+  // dialog boxes.
+  virtual gfx::NativeWindow GetTopLevelNativeWindow() const = 0;
+
+  // Computes the rectangle for the native widget that contains the contents of
+  // the tab in the screen coordinate system.
+  virtual void GetContainerBounds(gfx::Rect* out) const = 0;
+
+  // TODO(brettw) this is a hack. It's used in two places at the time of this
+  // writing: (1) when render view hosts switch, we need to size the replaced
+  // one to be correct, since it wouldn't have known about sizes that happened
+  // while it was hidden; (2) in constrained windows.
+  //
+  // (1) will be fixed once interstitials are cleaned up. (2) seems like it
+  // should be cleaned up or done some other way, since this works for normal
+  // WebContents without the special code.
+  virtual void SizeContents(const gfx::Size& size) = 0;
+
+  // Sets focus to the native widget for this tab.
+  virtual void Focus() = 0;
+
+  // Sets focus to the appropriate element when the WebContents is shown the
+  // first time.
+  virtual void SetInitialFocus() = 0;
+
+  // Stores the currently focused view.
+  virtual void StoreFocus() = 0;
+
+  // Restores focus to the last focus view. If StoreFocus has not yet been
+  // invoked, SetInitialFocus is invoked.
+  virtual void RestoreFocus() = 0;
+
+  // Returns the current drop data, if any.
+  virtual DropData* GetDropData() const = 0;
+
+  // Get the bounds of the View, relative to the parent.
+  virtual gfx::Rect GetViewBounds() const = 0;
+
+  virtual void CreateView(
+      const gfx::Size& initial_size, gfx::NativeView context) = 0;
+
+  // Sets up the View that holds the rendered web page, receives messages for
+  // it and contains page plugins. The host view should be sized to the current
+  // size of the WebContents.
+  virtual RenderWidgetHostViewBase* CreateViewForWidget(
+      RenderWidgetHost* render_widget_host) = 0;
+
+  // Creates a new View that holds a popup and receives messages for it.
+  virtual RenderWidgetHostViewBase* CreateViewForPopupWidget(
+      RenderWidgetHost* render_widget_host) = 0;
+
+  // Sets the page title for the native widgets corresponding to the view. This
+  // is not strictly necessary and isn't expected to be displayed anywhere, but
+  // can aid certain debugging tools such as Spy++ on Windows where you are
+  // trying to find a specific window.
+  virtual void SetPageTitle(const base::string16& title) = 0;
+
+  // Invoked when the WebContents is notified that the RenderView has been
+  // fully created.
+  virtual void RenderViewCreated(RenderViewHost* host) = 0;
+
+  // Invoked when the WebContents is notified that the RenderView has been
+  // swapped in.
+  virtual void RenderViewSwappedIn(RenderViewHost* host) = 0;
+
+  // Invoked to enable/disable overscroll gesture navigation.
+  virtual void SetOverscrollControllerEnabled(bool enabled) = 0;
+
+#if defined(OS_MACOSX)
+  // The web contents view assumes that its view will never be overlapped by
+  // another view (either partially or fully). This allows it to perform
+  // optimizations. If the view is in a view hierarchy where it might be
+  // overlapped by another view, notify the view by calling this with |true|.
+  virtual void SetAllowOverlappingViews(bool overlapping) = 0;
+
+  // Returns true if overlapping views are allowed, false otherwise.
+  virtual bool GetAllowOverlappingViews() const = 0;
+
+  // To draw two overlapping web contents view, the underlaying one should
+  // know about the overlaying one. Caller must ensure that |overlay| exists
+  // until |RemoveOverlayView| is called.
+  virtual void SetOverlayView(WebContentsView* overlay,
+                              const gfx::Point& offset) = 0;
+
+  // Removes the previously set overlay view.
+  virtual void RemoveOverlayView() = 0;
+
+  // If we close the tab while a UI control is in an event-tracking
+  // loop, the control may message freed objects and crash.
+  // WebContents::Close() calls IsEventTracking(), and if it returns
+  // true CloseTabAfterEventTracking() is called and the close is not
+  // completed.
+  virtual bool IsEventTracking() const = 0;
+  virtual void CloseTabAfterEventTracking() = 0;
+#endif
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_H_
diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc
index 2c177a8..3378595 100644
--- a/content/browser/web_contents/web_contents_view_android.cc
+++ b/content/browser/web_contents/web_contents_view_android.cc
@@ -7,7 +7,6 @@
 #include "base/logging.h"
 #include "content/browser/android/content_view_core_impl.h"
 #include "content/browser/frame_host/interstitial_page_impl.h"
-#include "content/browser/media/android/browser_media_player_manager.h"
 #include "content/browser/renderer_host/render_widget_host_view_android.h"
 #include "content/browser/renderer_host/render_view_host_factory.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
@@ -15,7 +14,7 @@
 #include "content/public/browser/web_contents_delegate.h"
 
 namespace content {
-WebContentsViewPort* CreateWebContentsView(
+WebContentsView* CreateWebContentsView(
     WebContentsImpl* web_contents,
     WebContentsViewDelegate* delegate,
     RenderViewHostDelegateView** render_view_host_delegate_view) {
@@ -76,16 +75,6 @@
     content_view_core_->SetTitle(title);
 }
 
-void WebContentsViewAndroid::OnTabCrashed(base::TerminationStatus status,
-                                          int error_code) {
-  RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
-      web_contents_->GetRenderViewHost());
-  if (rvh->media_player_manager())
-    rvh->media_player_manager()->DestroyAllMediaPlayers();
-  if (content_view_core_)
-    content_view_core_->OnTabCrashed();
-}
-
 void WebContentsViewAndroid::SizeContents(const gfx::Size& size) {
   // TODO(klobag): Do we need to do anything else?
   RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
@@ -131,7 +120,7 @@
     const gfx::Size& initial_size, gfx::NativeView context) {
 }
 
-RenderWidgetHostView* WebContentsViewAndroid::CreateViewForWidget(
+RenderWidgetHostViewBase* WebContentsViewAndroid::CreateViewForWidget(
     RenderWidgetHost* render_widget_host) {
   if (render_widget_host->GetView()) {
     // During testing, the view will already be set up in most cases to the
@@ -140,7 +129,8 @@
     // view twice), we check for the RVH Factory, which will be set when we're
     // making special ones (which go along with the special views).
     DCHECK(RenderViewHostFactory::has_factory());
-    return render_widget_host->GetView();
+    return static_cast<RenderWidgetHostViewBase*>(
+        render_widget_host->GetView());
   }
   // Note that while this instructs the render widget host to reference
   // |native_view_|, this has no effect without also instructing the
@@ -148,14 +138,13 @@
   // order to paint it. See ContentView::GetRenderWidgetHostViewAndroid for an
   // example of how this is achieved for InterstitialPages.
   RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(render_widget_host);
-  RenderWidgetHostView* view = new RenderWidgetHostViewAndroid(
-      rwhi, content_view_core_);
-  return view;
+  return new RenderWidgetHostViewAndroid(rwhi, content_view_core_);
 }
 
-RenderWidgetHostView* WebContentsViewAndroid::CreateViewForPopupWidget(
+RenderWidgetHostViewBase* WebContentsViewAndroid::CreateViewForPopupWidget(
     RenderWidgetHost* render_widget_host) {
-  return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
+  RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(render_widget_host);
+  return new RenderWidgetHostViewAndroid(rwhi, NULL);
 }
 
 void WebContentsViewAndroid::RenderViewCreated(RenderViewHost* host) {
@@ -183,7 +172,7 @@
     bool allow_multiple_selection) {
   if (content_view_core_) {
     content_view_core_->ShowSelectPopupMenu(
-        items, selected_item, allow_multiple_selection);
+        bounds, items, selected_item, allow_multiple_selection);
   }
 }
 
diff --git a/content/browser/web_contents/web_contents_view_android.h b/content/browser/web_contents/web_contents_view_android.h
index a5fb44c..2503595 100644
--- a/content/browser/web_contents/web_contents_view_android.h
+++ b/content/browser/web_contents/web_contents_view_android.h
@@ -6,18 +6,18 @@
 #define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_VIEW_ANDROID_H_
 
 #include "base/memory/scoped_ptr.h"
-#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/port/browser/render_view_host_delegate_view.h"
-#include "content/port/browser/web_contents_view_port.h"
+#include "content/browser/renderer_host/render_view_host_delegate_view.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/public/browser/web_contents_view_delegate.h"
 #include "content/public/common/context_menu_params.h"
 #include "ui/gfx/rect_f.h"
 
 namespace content {
 class ContentViewCoreImpl;
+class WebContentsImpl;
 
 // Android-specific implementation of the WebContentsView.
-class WebContentsViewAndroid : public WebContentsViewPort,
+class WebContentsViewAndroid : public WebContentsView,
                                public RenderViewHostDelegateView {
  public:
   WebContentsViewAndroid(WebContentsImpl* web_contents,
@@ -34,8 +34,6 @@
   virtual gfx::NativeView GetContentNativeView() const OVERRIDE;
   virtual gfx::NativeWindow GetTopLevelNativeWindow() const OVERRIDE;
   virtual void GetContainerBounds(gfx::Rect* out) const OVERRIDE;
-  virtual void OnTabCrashed(base::TerminationStatus status,
-                            int error_code) OVERRIDE;
   virtual void SizeContents(const gfx::Size& size) OVERRIDE;
   virtual void Focus() OVERRIDE;
   virtual void SetInitialFocus() OVERRIDE;
@@ -43,13 +41,11 @@
   virtual void RestoreFocus() OVERRIDE;
   virtual DropData* GetDropData() const OVERRIDE;
   virtual gfx::Rect GetViewBounds() const OVERRIDE;
-
-  // WebContentsViewPort implementation ----------------------------------------
   virtual void CreateView(
       const gfx::Size& initial_size, gfx::NativeView context) OVERRIDE;
-  virtual RenderWidgetHostView* CreateViewForWidget(
+  virtual RenderWidgetHostViewBase* CreateViewForWidget(
       RenderWidgetHost* render_widget_host) OVERRIDE;
-  virtual RenderWidgetHostView* CreateViewForPopupWidget(
+  virtual RenderWidgetHostViewBase* CreateViewForPopupWidget(
       RenderWidgetHost* render_widget_host) OVERRIDE;
   virtual void SetPageTitle(const base::string16& title) OVERRIDE;
   virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index 2d77af7..c818fa1 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -70,7 +70,7 @@
 #include "ui/wm/public/drag_drop_delegate.h"
 
 namespace content {
-WebContentsViewPort* CreateWebContentsView(
+WebContentsView* CreateWebContentsView(
     WebContentsImpl* web_contents,
     WebContentsViewDelegate* delegate,
     RenderViewHostDelegateView** render_view_host_delegate_view) {
@@ -159,7 +159,7 @@
       web_contents_window()->delegate()->OnGestureEvent(event);
   }
 
-  WebContents* web_contents_;
+  WebContentsImpl* web_contents_;
 
   // The window is displayed both during the gesture, and after the gesture
   // while the navigation is in progress. During the gesture, it is necessary to
@@ -979,10 +979,6 @@
   *out = window_->GetBoundsInScreen();
 }
 
-void WebContentsViewAura::OnTabCrashed(base::TerminationStatus status,
-                                       int error_code) {
-}
-
 void WebContentsViewAura::SizeContents(const gfx::Size& size) {
   gfx::Rect bounds = window_->bounds();
   if (bounds.size() != size) {
@@ -1035,7 +1031,7 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// WebContentsViewAura, WebContentsViewPort implementation:
+// WebContentsViewAura, WebContentsView implementation:
 
 void WebContentsViewAura::CreateView(
     const gfx::Size& initial_size, gfx::NativeView context) {
@@ -1043,7 +1039,7 @@
   // if the bookmark bar is not shown and you create a new tab). The right
   // value is set shortly after this, so its safe to ignore.
 
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
   window_.reset(new aura::Window(this));
   window_->set_owned_by_parent(false);
   window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
@@ -1082,7 +1078,7 @@
     drag_dest_delegate_ = delegate_->GetDragDestDelegate();
 }
 
-RenderWidgetHostView* WebContentsViewAura::CreateViewForWidget(
+RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget(
     RenderWidgetHost* render_widget_host) {
   if (render_widget_host->GetView()) {
     // During testing, the view will already be set up in most cases to the
@@ -1091,11 +1087,12 @@
     // view twice), we check for the RVH Factory, which will be set when we're
     // making special ones (which go along with the special views).
     DCHECK(RenderViewHostFactory::has_factory());
-    return render_widget_host->GetView();
+    return static_cast<RenderWidgetHostViewBase*>(
+        render_widget_host->GetView());
   }
 
-  RenderWidgetHostView* view =
-      RenderWidgetHostView::CreateViewForWidget(render_widget_host);
+  RenderWidgetHostViewBase* view = new RenderWidgetHostViewAura(
+      render_widget_host);
   view->InitAsChild(NULL);
   GetNativeView()->AddChild(view->GetNativeView());
 
@@ -1122,9 +1119,9 @@
   return view;
 }
 
-RenderWidgetHostView* WebContentsViewAura::CreateViewForPopupWidget(
+RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForPopupWidget(
     RenderWidgetHost* render_widget_host) {
-  return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
+  return new RenderWidgetHostViewAura(render_widget_host);
 }
 
 void WebContentsViewAura::SetPageTitle(const base::string16& title) {
diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h
index e472a36..9cf4182 100644
--- a/content/browser/web_contents/web_contents_view_aura.h
+++ b/content/browser/web_contents/web_contents_view_aura.h
@@ -10,9 +10,9 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "content/browser/renderer_host/overscroll_controller_delegate.h"
+#include "content/browser/renderer_host/render_view_host_delegate_view.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/common/content_export.h"
-#include "content/port/browser/render_view_host_delegate_view.h"
-#include "content/port/browser/web_contents_view_port.h"
 #include "ui/aura/window_delegate.h"
 #include "ui/compositor/layer_animation_observer.h"
 #include "ui/wm/public/drag_drop_delegate.h"
@@ -35,10 +35,10 @@
 class WebContentsImpl;
 class WebDragDestDelegate;
 
-class CONTENT_EXPORT WebContentsViewAura
-    : public WebContentsViewPort,
+class WebContentsViewAura
+    : public WebContentsView,
       public RenderViewHostDelegateView,
-      NON_EXPORTED_BASE(public OverscrollControllerDelegate),
+      public OverscrollControllerDelegate,
       public ui::ImplicitAnimationObserver,
       public aura::WindowDelegate,
       public aura::client::DragDropDelegate {
@@ -46,9 +46,10 @@
   WebContentsViewAura(WebContentsImpl* web_contents,
                       WebContentsViewDelegate* delegate);
 
-  void SetupOverlayWindowForTesting();
+  CONTENT_EXPORT void SetupOverlayWindowForTesting();
 
-  void SetTouchEditableForTest(TouchEditableImplAura* touch_editable);
+  CONTENT_EXPORT void SetTouchEditableForTest(
+      TouchEditableImplAura* touch_editable);
 
  private:
   class WindowObserver;
@@ -105,8 +106,6 @@
   virtual gfx::NativeView GetContentNativeView() const OVERRIDE;
   virtual gfx::NativeWindow GetTopLevelNativeWindow() const OVERRIDE;
   virtual void GetContainerBounds(gfx::Rect *out) const OVERRIDE;
-  virtual void OnTabCrashed(base::TerminationStatus status,
-                            int error_code) OVERRIDE;
   virtual void SizeContents(const gfx::Size& size) OVERRIDE;
   virtual void Focus() OVERRIDE;
   virtual void SetInitialFocus() OVERRIDE;
@@ -114,13 +113,11 @@
   virtual void RestoreFocus() OVERRIDE;
   virtual DropData* GetDropData() const OVERRIDE;
   virtual gfx::Rect GetViewBounds() const OVERRIDE;
-
-  // Overridden from WebContentsViewPort:
   virtual void CreateView(
       const gfx::Size& initial_size, gfx::NativeView context) OVERRIDE;
-  virtual RenderWidgetHostView* CreateViewForWidget(
+  virtual RenderWidgetHostViewBase* CreateViewForWidget(
       RenderWidgetHost* render_widget_host) OVERRIDE;
-  virtual RenderWidgetHostView* CreateViewForPopupWidget(
+  virtual RenderWidgetHostViewBase* CreateViewForPopupWidget(
       RenderWidgetHost* render_widget_host) OVERRIDE;
   virtual void SetPageTitle(const base::string16& title) OVERRIDE;
   virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
diff --git a/content/browser/web_contents/web_contents_view_aura_browsertest.cc b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
index adfebd1..c20a888 100644
--- a/content/browser/web_contents/web_contents_view_aura_browsertest.cc
+++ b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
@@ -16,9 +16,9 @@
 #include "content/browser/frame_host/navigation_entry_impl.h"
 #include "content/browser/frame_host/navigation_entry_screenshot_manager.h"
 #include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
@@ -182,7 +182,7 @@
     EXPECT_TRUE(controller.CanGoBack());
     EXPECT_FALSE(controller.CanGoForward());
 
-    aura::Window* content = web_contents->GetView()->GetContentNativeView();
+    aura::Window* content = web_contents->GetContentNativeView();
     gfx::Rect bounds = content->GetBoundsInRootWindow();
     aura::test::EventGenerator generator(content->GetRootWindow(), content);
     const int kScrollDurationMs = 20;
@@ -319,7 +319,7 @@
   web_contents->GetController().GoBack();
   EXPECT_EQ(1, GetCurrentIndex());
 
-  aura::Window* content = web_contents->GetView()->GetContentNativeView();
+  aura::Window* content = web_contents->GetContentNativeView();
   ui::EventProcessor* dispatcher = content->GetHost()->event_processor();
   gfx::Rect bounds = content->GetBoundsInRootWindow();
 
@@ -442,7 +442,7 @@
     // index 3 to index 2, and index 3 should have a screenshot.
     base::string16 expected_title = base::ASCIIToUTF16("Title: #2");
     content::TitleWatcher title_watcher(web_contents, expected_title);
-    aura::Window* content = web_contents->GetView()->GetContentNativeView();
+    aura::Window* content = web_contents->GetContentNativeView();
     gfx::Rect bounds = content->GetBoundsInRootWindow();
     aura::test::EventGenerator generator(content->GetRootWindow(), content);
     generator.GestureScrollSequence(
@@ -582,7 +582,7 @@
   ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
   EXPECT_EQ(1, GetCurrentIndex());
 
-  aura::Window* content = web_contents->GetView()->GetContentNativeView();
+  aura::Window* content = web_contents->GetContentNativeView();
   gfx::Rect bounds = content->GetBoundsInRootWindow();
   aura::test::EventGenerator generator(content->GetRootWindow(), content);
   generator.GestureScrollSequence(
@@ -591,7 +591,7 @@
       base::TimeDelta::FromMilliseconds(20),
       1);
 
-  window->AddChild(shell()->web_contents()->GetView()->GetContentNativeView());
+  window->AddChild(shell()->web_contents()->GetContentNativeView());
 }
 
 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
@@ -604,7 +604,7 @@
   ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
   EXPECT_EQ(1, GetCurrentIndex());
 
-  aura::Window* content = web_contents->GetView()->GetContentNativeView();
+  aura::Window* content = web_contents->GetContentNativeView();
   gfx::Rect bounds = content->GetBoundsInRootWindow();
   aura::test::EventGenerator generator(content->GetRootWindow(), content);
   generator.GestureScrollSequence(
@@ -613,11 +613,12 @@
       base::TimeDelta::FromMilliseconds(20),
       1);
 
-  delete web_contents->GetView()->GetContentNativeView();
+  delete web_contents->GetContentNativeView();
 }
 
+// TODO(dalecurtis): Test disabled due to flakiness.  http://crbug.com/369871.
 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
-                       RepeatedQuickOverscrollGestures) {
+                       DISABLED_RepeatedQuickOverscrollGestures) {
   ASSERT_NO_FATAL_FAILURE(
       StartTestWithPage("files/overscroll_navigation.html"));
 
@@ -644,7 +645,7 @@
   EXPECT_TRUE(controller.CanGoBack());
   EXPECT_TRUE(controller.CanGoForward());
 
-  aura::Window* content = web_contents->GetView()->GetContentNativeView();
+  aura::Window* content = web_contents->GetContentNativeView();
   gfx::Rect bounds = content->GetBoundsInRootWindow();
   aura::test::EventGenerator generator(content->GetRootWindow(), content);
 
diff --git a/content/browser/web_contents/web_contents_view_guest.cc b/content/browser/web_contents/web_contents_view_guest.cc
index 873aaab..9ebb060 100644
--- a/content/browser/web_contents/web_contents_view_guest.cc
+++ b/content/browser/web_contents/web_contents_view_guest.cc
@@ -34,7 +34,7 @@
 WebContentsViewGuest::WebContentsViewGuest(
     WebContentsImpl* web_contents,
     BrowserPluginGuest* guest,
-    scoped_ptr<WebContentsViewPort> platform_view,
+    scoped_ptr<WebContentsView> platform_view,
     RenderViewHostDelegateView* platform_view_delegate_view)
     : web_contents_(web_contents),
       guest_(guest),
@@ -57,7 +57,7 @@
 }
 
 gfx::NativeWindow WebContentsViewGuest::GetTopLevelNativeWindow() const {
-  return guest_->embedder_web_contents()->GetView()->GetTopLevelNativeWindow();
+  return guest_->embedder_web_contents()->GetTopLevelNativeWindow();
 }
 
 void WebContentsViewGuest::OnGuestInitialized(WebContentsView* parent_view) {
@@ -71,6 +71,30 @@
 #endif  // defined(USE_AURA)
 }
 
+ContextMenuParams WebContentsViewGuest::ConvertContextMenuParams(
+    const ContextMenuParams& params) const {
+#if defined(USE_AURA)
+  // Context menu uses ScreenPositionClient::ConvertPointToScreen() in aura
+  // to calculate popup position. Guest's native view
+  // (platform_view_->GetNativeView()) is part of the embedder's view hierarchy,
+  // but is placed at (0, 0) w.r.t. the embedder's position. Therefore, |offset|
+  // is added to |params|.
+  gfx::Rect embedder_bounds;
+  guest_->embedder_web_contents()->GetView()->GetContainerBounds(
+      &embedder_bounds);
+  gfx::Rect guest_bounds;
+  GetContainerBounds(&guest_bounds);
+
+  gfx::Vector2d offset = guest_bounds.origin() - embedder_bounds.origin();
+  ContextMenuParams params_in_embedder = params;
+  params_in_embedder.x += offset.x();
+  params_in_embedder.y += offset.y();
+  return params_in_embedder;
+#else
+  return params;
+#endif
+}
+
 void WebContentsViewGuest::GetContainerBounds(gfx::Rect* out) const {
   // We need embedder container's bounds to calculate our bounds.
   guest_->embedder_web_contents()->GetView()->GetContainerBounds(out);
@@ -119,7 +143,7 @@
   size_ = initial_size;
 }
 
-RenderWidgetHostView* WebContentsViewGuest::CreateViewForWidget(
+RenderWidgetHostViewBase* WebContentsViewGuest::CreateViewForWidget(
     RenderWidgetHost* render_widget_host) {
   if (render_widget_host->GetView()) {
     // During testing, the view will already be set up in most cases to the
@@ -128,13 +152,14 @@
     // view twice), we check for the RVH Factory, which will be set when we're
     // making special ones (which go along with the special views).
     DCHECK(RenderViewHostFactory::has_factory());
-    return render_widget_host->GetView();
+    return static_cast<RenderWidgetHostViewBase*>(
+        render_widget_host->GetView());
   }
 
-  RenderWidgetHostView* platform_widget = NULL;
-  platform_widget = platform_view_->CreateViewForWidget(render_widget_host);
+  RenderWidgetHostViewBase* platform_widget =
+      platform_view_->CreateViewForWidget(render_widget_host);
 
-  RenderWidgetHostView* view = new RenderWidgetHostViewGuest(
+  RenderWidgetHostViewBase* view = new RenderWidgetHostViewGuest(
       render_widget_host,
       guest_,
       platform_widget);
@@ -142,9 +167,9 @@
   return view;
 }
 
-RenderWidgetHostView* WebContentsViewGuest::CreateViewForPopupWidget(
+RenderWidgetHostViewBase* WebContentsViewGuest::CreateViewForPopupWidget(
     RenderWidgetHost* render_widget_host) {
-  return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
+  return platform_view_->CreateViewForWidget(render_widget_host);
 }
 
 void WebContentsViewGuest::SetPageTitle(const base::string16& title) {
@@ -179,10 +204,6 @@
   platform_view_->RestoreFocus();
 }
 
-void WebContentsViewGuest::OnTabCrashed(base::TerminationStatus status,
-                                        int error_code) {
-}
-
 void WebContentsViewGuest::Focus() {
   platform_view_->Focus();
 }
@@ -215,27 +236,8 @@
 
 void WebContentsViewGuest::ShowContextMenu(RenderFrameHost* render_frame_host,
                                            const ContextMenuParams& params) {
-#if defined(USE_AURA)
-  // Context menu uses ScreenPositionClient::ConvertPointToScreen() in aura
-  // to calculate popup position. Guest's native view
-  // (platform_view_->GetNativeView()) is part of the embedder's view hierarchy,
-  // but is placed at (0, 0) w.r.t. the embedder's position. Therefore, |offset|
-  // is added to |params|.
-  gfx::Rect embedder_bounds;
-  guest_->embedder_web_contents()->GetView()->GetContainerBounds(
-      &embedder_bounds);
-  gfx::Rect guest_bounds;
-  GetContainerBounds(&guest_bounds);
-
-  gfx::Vector2d offset = guest_bounds.origin() - embedder_bounds.origin();
-  ContextMenuParams params_in_embedder = params;
-  params_in_embedder.x += offset.x();
-  params_in_embedder.y += offset.y();
   platform_view_delegate_view_->ShowContextMenu(
-      render_frame_host, params_in_embedder);
-#else
-  platform_view_delegate_view_->ShowContextMenu(render_frame_host, params);
-#endif  // defined(USE_AURA)
+      render_frame_host, ConvertContextMenuParams(params));
 }
 
 void WebContentsViewGuest::StartDragging(
diff --git a/content/browser/web_contents/web_contents_view_guest.h b/content/browser/web_contents/web_contents_view_guest.h
index aaa35c3..53edd64 100644
--- a/content/browser/web_contents/web_contents_view_guest.h
+++ b/content/browser/web_contents/web_contents_view_guest.h
@@ -8,10 +8,10 @@
 #include <vector>
 
 #include "base/memory/scoped_ptr.h"
+#include "content/browser/renderer_host/render_view_host_delegate_view.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/common/content_export.h"
 #include "content/common/drag_event_source_info.h"
-#include "content/port/browser/render_view_host_delegate_view.h"
-#include "content/port/browser/web_contents_view_port.h"
 
 namespace content {
 
@@ -19,9 +19,8 @@
 class WebContentsImpl;
 class BrowserPluginGuest;
 
-class CONTENT_EXPORT WebContentsViewGuest
-    : public WebContentsViewPort,
-      public RenderViewHostDelegateView {
+class WebContentsViewGuest : public WebContentsView,
+                             public RenderViewHostDelegateView {
  public:
   // The corresponding WebContentsImpl is passed in the constructor, and manages
   // our lifetime. This doesn't need to be the case, but is this way currently
@@ -30,7 +29,7 @@
   // |platform_view|.
   WebContentsViewGuest(WebContentsImpl* web_contents,
                        BrowserPluginGuest* guest,
-                       scoped_ptr<WebContentsViewPort> platform_view,
+                       scoped_ptr<WebContentsView> platform_view,
                        RenderViewHostDelegateView* platform_view_delegate_view);
   virtual ~WebContentsViewGuest();
 
@@ -38,14 +37,16 @@
 
   void OnGuestInitialized(WebContentsView* parent_view);
 
-  // WebContentsView implementation --------------------------------------------
+  // Converts the guest specific coordinates in |params| to embedder specific
+  // ones.
+  ContextMenuParams ConvertContextMenuParams(
+      const ContextMenuParams& params) const;
 
+  // WebContentsView implementation --------------------------------------------
   virtual gfx::NativeView GetNativeView() const OVERRIDE;
   virtual gfx::NativeView GetContentNativeView() const OVERRIDE;
   virtual gfx::NativeWindow GetTopLevelNativeWindow() const OVERRIDE;
   virtual void GetContainerBounds(gfx::Rect* out) const OVERRIDE;
-  virtual void OnTabCrashed(base::TerminationStatus status,
-                            int error_code) OVERRIDE;
   virtual void SizeContents(const gfx::Size& size) OVERRIDE;
   virtual void Focus() OVERRIDE;
   virtual void SetInitialFocus() OVERRIDE;
@@ -53,26 +54,22 @@
   virtual void RestoreFocus() OVERRIDE;
   virtual DropData* GetDropData() const OVERRIDE;
   virtual gfx::Rect GetViewBounds() const OVERRIDE;
-#if defined(OS_MACOSX)
-  virtual void SetAllowOverlappingViews(bool overlapping) OVERRIDE;
-  virtual bool GetAllowOverlappingViews() const OVERRIDE;
-  virtual void SetOverlayView(WebContentsView* overlay,
-                              const gfx::Point& offset) OVERRIDE;
-  virtual void RemoveOverlayView() OVERRIDE;
-#endif
-
-  // WebContentsViewPort implementation ----------------------------------------
   virtual void CreateView(const gfx::Size& initial_size,
                           gfx::NativeView context) OVERRIDE;
-  virtual RenderWidgetHostView* CreateViewForWidget(
+  virtual RenderWidgetHostViewBase* CreateViewForWidget(
       RenderWidgetHost* render_widget_host) OVERRIDE;
-  virtual RenderWidgetHostView* CreateViewForPopupWidget(
+  virtual RenderWidgetHostViewBase* CreateViewForPopupWidget(
       RenderWidgetHost* render_widget_host) OVERRIDE;
   virtual void SetPageTitle(const base::string16& title) OVERRIDE;
   virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
   virtual void RenderViewSwappedIn(RenderViewHost* host) OVERRIDE;
   virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
 #if defined(OS_MACOSX)
+  virtual void SetAllowOverlappingViews(bool overlapping) OVERRIDE;
+  virtual bool GetAllowOverlappingViews() const OVERRIDE;
+  virtual void SetOverlayView(WebContentsView* overlay,
+                              const gfx::Point& offset) OVERRIDE;
+  virtual void RemoveOverlayView() OVERRIDE;
   virtual bool IsEventTracking() const OVERRIDE;
   virtual void CloseTabAfterEventTracking() OVERRIDE;
 #endif
@@ -95,7 +92,7 @@
   BrowserPluginGuest* guest_;
   // The platform dependent view backing this WebContentsView.
   // Calls to this WebContentsViewGuest are forwarded to |platform_view_|.
-  scoped_ptr<WebContentsViewPort> platform_view_;
+  scoped_ptr<WebContentsView> platform_view_;
   gfx::Size size_;
 
   // Delegate view for guest's platform view.
diff --git a/content/browser/web_contents/web_contents_view_mac.h b/content/browser/web_contents/web_contents_view_mac.h
index c738c74..c6bc9da 100644
--- a/content/browser/web_contents/web_contents_view_mac.h
+++ b/content/browser/web_contents/web_contents_view_mac.h
@@ -12,10 +12,10 @@
 
 #include "base/mac/scoped_nsobject.h"
 #include "base/memory/scoped_ptr.h"
+#include "content/browser/renderer_host/render_view_host_delegate_view.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/common/content_export.h"
 #include "content/common/drag_event_source_info.h"
-#include "content/port/browser/render_view_host_delegate_view.h"
-#include "content/port/browser/web_contents_view_port.h"
 #include "ui/base/cocoa/base_view.h"
 #include "ui/gfx/size.h"
 
@@ -55,7 +55,7 @@
 
 // Mac-specific implementation of the WebContentsView. It owns an NSView that
 // contains all of the contents of the tab and associated child views.
-class WebContentsViewMac : public WebContentsViewPort,
+class WebContentsViewMac : public WebContentsView,
                            public RenderViewHostDelegateView {
  public:
   // The corresponding WebContentsImpl is passed in the constructor, and manages
@@ -70,8 +70,6 @@
   virtual gfx::NativeView GetContentNativeView() const OVERRIDE;
   virtual gfx::NativeWindow GetTopLevelNativeWindow() const OVERRIDE;
   virtual void GetContainerBounds(gfx::Rect* out) const OVERRIDE;
-  virtual void OnTabCrashed(base::TerminationStatus status,
-                            int error_code) OVERRIDE;
   virtual void SizeContents(const gfx::Size& size) OVERRIDE;
   virtual void Focus() OVERRIDE;
   virtual void SetInitialFocus() OVERRIDE;
@@ -84,13 +82,11 @@
   virtual void SetOverlayView(WebContentsView* overlay,
                               const gfx::Point& offset) OVERRIDE;
   virtual void RemoveOverlayView() OVERRIDE;
-
-  // WebContentsViewPort implementation ----------------------------------------
   virtual void CreateView(
       const gfx::Size& initial_size, gfx::NativeView context) OVERRIDE;
-  virtual RenderWidgetHostView* CreateViewForWidget(
+  virtual RenderWidgetHostViewBase* CreateViewForWidget(
       RenderWidgetHost* render_widget_host) OVERRIDE;
-  virtual RenderWidgetHostView* CreateViewForPopupWidget(
+  virtual RenderWidgetHostViewBase* CreateViewForPopupWidget(
       RenderWidgetHost* render_widget_host) OVERRIDE;
   virtual void SetPageTitle(const base::string16& title) OVERRIDE;
   virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm
index 1bb3ffb..39e579b 100644
--- a/content/browser/web_contents/web_contents_view_mac.mm
+++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -68,7 +68,7 @@
 @end
 
 namespace content {
-WebContentsViewPort* CreateWebContentsView(
+WebContentsView* CreateWebContentsView(
     WebContentsImpl* web_contents,
     WebContentsViewDelegate* delegate,
     RenderViewHostDelegateView** render_view_host_delegate_view) {
@@ -152,10 +152,6 @@
                               offset:offset];
 }
 
-void WebContentsViewMac::OnTabCrashed(base::TerminationStatus /* status */,
-                                      int /* error_code */) {
-}
-
 void WebContentsViewMac::SizeContents(const gfx::Size& size) {
   // TODO(brettw | japhet) This is a hack and should be removed.
   // See web_contents_view.h.
@@ -337,7 +333,7 @@
   cocoa_view_.reset(view);
 }
 
-RenderWidgetHostView* WebContentsViewMac::CreateViewForWidget(
+RenderWidgetHostViewBase* WebContentsViewMac::CreateViewForWidget(
     RenderWidgetHost* render_widget_host) {
   if (render_widget_host->GetView()) {
     // During testing, the view will already be set up in most cases to the
@@ -346,11 +342,12 @@
     // view twice), we check for the RVH Factory, which will be set when we're
     // making special ones (which go along with the special views).
     DCHECK(RenderViewHostFactory::has_factory());
-    return render_widget_host->GetView();
+    return static_cast<RenderWidgetHostViewBase*>(
+        render_widget_host->GetView());
   }
 
-  RenderWidgetHostViewMac* view = static_cast<RenderWidgetHostViewMac*>(
-      RenderWidgetHostView::CreateViewForWidget(render_widget_host));
+  RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(
+      render_widget_host);
   if (delegate()) {
     base::scoped_nsobject<NSObject<RenderWidgetHostViewMacDelegate> >
         rw_delegate(
@@ -382,9 +379,9 @@
   return view;
 }
 
-RenderWidgetHostView* WebContentsViewMac::CreateViewForPopupWidget(
+RenderWidgetHostViewBase* WebContentsViewMac::CreateViewForPopupWidget(
     RenderWidgetHost* render_widget_host) {
-  return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
+  return new RenderWidgetHostViewMac(render_widget_host);
 }
 
 void WebContentsViewMac::SetPageTitle(const base::string16& title) {
diff --git a/content/browser/webui/web_ui_impl.cc b/content/browser/webui/web_ui_impl.cc
index 8641919..72261c3 100644
--- a/content/browser/webui/web_ui_impl.cc
+++ b/content/browser/webui/web_ui_impl.cc
@@ -11,12 +11,12 @@
 #include "content/browser/renderer_host/dip_util.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/browser/webui/web_ui_controller_factory_registry.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_view_host.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui_controller.h"
 #include "content/public/browser/web_ui_message_handler.h"
 #include "content/public/common/bindings_policy.h"
@@ -139,14 +139,14 @@
 }
 
 void WebUIImpl::CallJavascriptFunction(const std::string& function_name) {
-  DCHECK(IsStringASCII(function_name));
+  DCHECK(base::IsStringASCII(function_name));
   base::string16 javascript = base::ASCIIToUTF16(function_name + "();");
   ExecuteJavascript(javascript);
 }
 
 void WebUIImpl::CallJavascriptFunction(const std::string& function_name,
                                        const base::Value& arg) {
-  DCHECK(IsStringASCII(function_name));
+  DCHECK(base::IsStringASCII(function_name));
   std::vector<const base::Value*> args;
   args.push_back(&arg);
   ExecuteJavascript(GetJavascriptCall(function_name, args));
@@ -155,7 +155,7 @@
 void WebUIImpl::CallJavascriptFunction(
     const std::string& function_name,
     const base::Value& arg1, const base::Value& arg2) {
-  DCHECK(IsStringASCII(function_name));
+  DCHECK(base::IsStringASCII(function_name));
   std::vector<const base::Value*> args;
   args.push_back(&arg1);
   args.push_back(&arg2);
@@ -165,7 +165,7 @@
 void WebUIImpl::CallJavascriptFunction(
     const std::string& function_name,
     const base::Value& arg1, const base::Value& arg2, const base::Value& arg3) {
-  DCHECK(IsStringASCII(function_name));
+  DCHECK(base::IsStringASCII(function_name));
   std::vector<const base::Value*> args;
   args.push_back(&arg1);
   args.push_back(&arg2);
@@ -179,7 +179,7 @@
     const base::Value& arg2,
     const base::Value& arg3,
     const base::Value& arg4) {
-  DCHECK(IsStringASCII(function_name));
+  DCHECK(base::IsStringASCII(function_name));
   std::vector<const base::Value*> args;
   args.push_back(&arg1);
   args.push_back(&arg2);
@@ -191,7 +191,7 @@
 void WebUIImpl::CallJavascriptFunction(
     const std::string& function_name,
     const std::vector<const base::Value*>& args) {
-  DCHECK(IsStringASCII(function_name));
+  DCHECK(base::IsStringASCII(function_name));
   ExecuteJavascript(GetJavascriptCall(function_name, args));
 }
 
diff --git a/content/browser/webui/web_ui_mojo_browsertest.cc b/content/browser/webui/web_ui_mojo_browsertest.cc
index 1ab433c..598dbe1 100644
--- a/content/browser/webui/web_ui_mojo_browsertest.cc
+++ b/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -32,34 +32,6 @@
 namespace {
 
 bool got_message = false;
-int message_count = 0;
-
-const int kExpectedMessageCount = 100;
-
-// Negative numbers with different values in each byte, the last of
-// which can survive promotion to double and back.
-const int8  kExpectedInt8Value = -65;
-const int16 kExpectedInt16Value = -16961;
-const int32 kExpectedInt32Value = -1145258561;
-const int64 kExpectedInt64Value = -77263311946305LL;
-
-// Positive numbers with different values in each byte, the last of
-// which can survive promotion to double and back.
-const uint8  kExpectedUInt8Value = 65;
-const uint16 kExpectedUInt16Value = 16961;
-const uint32 kExpectedUInt32Value = 1145258561;
-const uint64 kExpectedUInt64Value = 77263311946305LL;
-
-// Double/float values, including special case constants.
-const double kExpectedDoubleVal = 3.14159265358979323846;
-const double kExpectedDoubleInf = std::numeric_limits<double>::infinity();
-const double kExpectedDoubleNan = std::numeric_limits<double>::quiet_NaN();
-const float kExpectedFloatVal = static_cast<float>(kExpectedDoubleVal);
-const float kExpectedFloatInf = std::numeric_limits<float>::infinity();
-const float kExpectedFloatNan = std::numeric_limits<float>::quiet_NaN();
-
-// NaN has the property that it is not equal to itself.
-#define EXPECT_NAN(x) EXPECT_NE(x, x)
 
 // The bindings for the page are generated from a .mojom file. This code looks
 // up the generated file from disk and returns it.
@@ -97,11 +69,6 @@
     NOTREACHED();
   }
 
-  virtual void EchoResponse(const mojo::EchoArgs& arg1,
-                            const mojo::EchoArgs& arg2) OVERRIDE {
-    NOTREACHED();
-  }
-
  protected:
   mojo::RemotePtr<mojo::RendererTarget> client_;
   base::RunLoop* run_loop_;
@@ -131,76 +98,6 @@
   DISALLOW_COPY_AND_ASSIGN(PingBrowserTargetImpl);
 };
 
-class EchoBrowserTargetImpl : public BrowserTargetImpl {
- public:
-  EchoBrowserTargetImpl(mojo::ScopedRendererTargetHandle handle,
-                        base::RunLoop* run_loop)
-      : BrowserTargetImpl(handle, run_loop) {
-    mojo::AllocationScope scope;
-    mojo::EchoArgs::Builder builder;
-    builder.set_si64(kExpectedInt64Value);
-    builder.set_si32(kExpectedInt32Value);
-    builder.set_si16(kExpectedInt16Value);
-    builder.set_si8(kExpectedInt8Value);
-    builder.set_ui64(kExpectedUInt64Value);
-    builder.set_ui32(kExpectedUInt32Value);
-    builder.set_ui16(kExpectedUInt16Value);
-    builder.set_ui8(kExpectedUInt8Value);
-    builder.set_float_val(kExpectedFloatVal);
-    builder.set_float_inf(kExpectedFloatInf);
-    builder.set_float_nan(kExpectedFloatNan);
-    builder.set_double_val(kExpectedDoubleVal);
-    builder.set_double_inf(kExpectedDoubleInf);
-    builder.set_double_nan(kExpectedDoubleNan);
-    builder.set_name("coming");
-    mojo::Array<mojo::String>::Builder string_array(3);
-    string_array[0] = "one";
-    string_array[1] = "two";
-    string_array[2] = "three";
-    builder.set_string_array(string_array.Finish());
-    client_->Echo(builder.Finish());
-  }
-
-  virtual ~EchoBrowserTargetImpl() {}
-
-  // mojo::BrowserTarget overrides:
-  // Check the response, and quit the RunLoop after N calls.
-  virtual void EchoResponse(const mojo::EchoArgs& arg1,
-                            const mojo::EchoArgs& arg2) OVERRIDE {
-    EXPECT_EQ(kExpectedInt64Value, arg1.si64());
-    EXPECT_EQ(kExpectedInt32Value, arg1.si32());
-    EXPECT_EQ(kExpectedInt16Value, arg1.si16());
-    EXPECT_EQ(kExpectedInt8Value, arg1.si8());
-    EXPECT_EQ(kExpectedUInt64Value, arg1.ui64());
-    EXPECT_EQ(kExpectedUInt32Value, arg1.ui32());
-    EXPECT_EQ(kExpectedUInt16Value, arg1.ui16());
-    EXPECT_EQ(kExpectedUInt8Value, arg1.ui8());
-    EXPECT_EQ(kExpectedFloatVal, arg1.float_val());
-    EXPECT_EQ(kExpectedFloatInf, arg1.float_inf());
-    EXPECT_NAN(arg1.float_nan());
-    EXPECT_EQ(kExpectedDoubleVal, arg1.double_val());
-    EXPECT_EQ(kExpectedDoubleInf, arg1.double_inf());
-    EXPECT_NAN(arg1.double_nan());
-    EXPECT_EQ(std::string("coming"), arg1.name().To<std::string>());
-    EXPECT_EQ(std::string("one"), arg1.string_array()[0].To<std::string>());
-    EXPECT_EQ(std::string("two"), arg1.string_array()[1].To<std::string>());
-    EXPECT_EQ(std::string("three"), arg1.string_array()[2].To<std::string>());
-
-    EXPECT_EQ(-1, arg2.si64());
-    EXPECT_EQ(-1, arg2.si32());
-    EXPECT_EQ(-1, arg2.si16());
-    EXPECT_EQ(-1, arg2.si8());
-    EXPECT_EQ(std::string("going"), arg2.name().To<std::string>());
-
-    message_count += 1;
-    if (message_count == kExpectedMessageCount)
-      run_loop_->Quit();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(EchoBrowserTargetImpl);
-};
-
 // WebUIController that sets up mojo bindings.
 class TestWebUIController : public WebUIController {
  public:
@@ -242,27 +139,6 @@
   DISALLOW_COPY_AND_ASSIGN(PingTestWebUIController);
 };
 
-// TestWebUIController that additionally creates the echo test BrowserTarget
-// implementation at the right time.
-class EchoTestWebUIController : public TestWebUIController {
- public:
-   EchoTestWebUIController(WebUI* web_ui, base::RunLoop* run_loop)
-      : TestWebUIController(web_ui, run_loop) {
-  }
-
-  // WebUIController overrides:
-  virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE {
-    mojo::InterfacePipe<mojo::BrowserTarget, mojo::RendererTarget> pipe;
-    browser_target_.reset(new EchoBrowserTargetImpl(
-        pipe.handle_to_peer.Pass(), run_loop_));
-    render_view_host->SetWebUIHandle(
-        mojo::ScopedMessagePipeHandle(pipe.handle_to_self.release()));
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(EchoTestWebUIController);
-};
-
 // WebUIControllerFactory that creates TestWebUIController.
 class TestWebUIControllerFactory : public WebUIControllerFactory {
  public:
@@ -274,8 +150,6 @@
       WebUI* web_ui, const GURL& url) const OVERRIDE {
     if (url.query() == "ping")
       return new PingTestWebUIController(web_ui, run_loop_);
-    if (url.query() == "echo")
-      return new EchoTestWebUIController(web_ui, run_loop_);
     return NULL;
   }
   virtual WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
@@ -341,31 +215,5 @@
   EXPECT_TRUE(got_message);
 }
 
-// Loads a webui page that contains mojo bindings and verifies that
-// parameters are passed back correctly from JavaScript.
-IN_PROC_BROWSER_TEST_F(WebUIMojoTest, EndToEndEcho) {
-  // Currently there is no way to have a generated file included in the isolate
-  // files. If the bindings file doesn't exist assume we're on such a bot and
-  // pass.
-  // TODO(sky): remove this conditional when isolates support copying from gen.
-  const base::FilePath test_file_path(
-      mojo::test::GetFilePathForJSResource(
-          "content/test/data/web_ui_test_mojo_bindings.mojom"));
-  if (!base::PathExists(test_file_path)) {
-    LOG(WARNING) << " mojom binding file doesn't exist, assuming on isolate";
-    return;
-  }
-
-  message_count = 0;
-  ASSERT_TRUE(test_server()->Start());
-  base::RunLoop run_loop;
-  factory()->set_run_loop(&run_loop);
-  GURL test_url(test_server()->GetURL("files/web_ui_mojo.html?echo"));
-  NavigateToURL(shell(), test_url);
-  // RunLoop is quit when response received from page.
-  run_loop.Run();
-  EXPECT_EQ(kExpectedMessageCount, message_count);
-}
-
 }  // namespace
 }  // namespace content
diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc
index 88bd70a..ee9548e 100644
--- a/content/browser/worker_host/worker_process_host.cc
+++ b/content/browser/worker_host/worker_process_host.cc
@@ -204,7 +204,7 @@
     switches::kDisableFileSystem,
     switches::kDisableSeccompFilterSandbox,
     switches::kEnableExperimentalWebPlatformFeatures,
-    switches::kEnableSharedWorkerMemoryInfo,
+    switches::kEnablePreciseMemoryInfo,
     switches::kEnableServiceWorker,
 #if defined(OS_MACOSX)
     switches::kEnableSandboxLogging,
diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc
index 8e6cf89..9d63ad9 100644
--- a/content/browser/zygote_host/zygote_host_impl_linux.cc
+++ b/content/browser/zygote_host/zygote_host_impl_linux.cc
@@ -153,16 +153,9 @@
   if (using_suid_sandbox_) {
     scoped_ptr<sandbox::SetuidSandboxClient>
         sandbox_client(sandbox::SetuidSandboxClient::Create());
-    sandbox_client->PrependWrapper(&cmd_line, &options);
+    sandbox_client->PrependWrapper(&cmd_line);
+    sandbox_client->SetupLaunchOptions(&options, &fds_to_map, &dummy_fd);
     sandbox_client->SetupLaunchEnvironment();
-
-    // We no longer need this dummy socket for discovering the zygote's PID,
-    // but the sandbox is still hard-coded to expect a file descriptor at
-    // kZygoteIdFd. Fixing this requires a sandbox API change. :(
-    CHECK_EQ(kZygoteIdFd, sandbox_client->GetUniqueToChildFileDescriptor());
-    dummy_fd.reset(socket(AF_UNIX, SOCK_DGRAM, 0));
-    CHECK_GE(dummy_fd.get(), 0);
-    fds_to_map.push_back(std::make_pair(dummy_fd.get(), kZygoteIdFd));
   }
 
   base::ProcessHandle process = -1;
@@ -301,6 +294,12 @@
   DCHECK(init_);
   Pickle pickle;
 
+  int raw_socks[2];
+  PCHECK(0 == socketpair(AF_UNIX, SOCK_SEQPACKET, 0, raw_socks));
+  base::ScopedFD my_sock(raw_socks[0]);
+  base::ScopedFD peer_sock(raw_socks[1]);
+  CHECK(UnixDomainSocket::EnableReceiveProcessId(my_sock.get()));
+
   pickle.WriteInt(kZygoteCommandFork);
   pickle.WriteString(process_type);
   pickle.WriteInt(argv.size());
@@ -308,12 +307,19 @@
        i = argv.begin(); i != argv.end(); ++i)
     pickle.WriteString(*i);
 
-  pickle.WriteInt(mapping.size());
+  // Fork requests contain one file descriptor for the PID oracle, and one
+  // more for each file descriptor mapping for the child process.
+  const size_t num_fds_to_send = 1 + mapping.size();
+  pickle.WriteInt(num_fds_to_send);
 
   std::vector<int> fds;
-  // Scoped pointers cannot be stored in containers, so we have to use a
-  // linked_ptr.
-  std::vector<linked_ptr<base::ScopedFD> > autodelete_fds;
+  ScopedVector<base::ScopedFD> autoclose_fds;
+
+  // First FD to send is peer_sock.
+  fds.push_back(peer_sock.get());
+  autoclose_fds.push_back(new base::ScopedFD(peer_sock.Pass()));
+
+  // The rest come from mapping.
   for (std::vector<FileDescriptorInfo>::const_iterator
        i = mapping.begin(); i != mapping.end(); ++i) {
     pickle.WriteUInt32(i->id);
@@ -321,16 +327,46 @@
     if (i->fd.auto_close) {
       // Auto-close means we need to close the FDs after they have been passed
       // to the other process.
-      linked_ptr<base::ScopedFD> ptr(new base::ScopedFD(fds.back()));
-      autodelete_fds.push_back(ptr);
+      autoclose_fds.push_back(new base::ScopedFD(i->fd.fd));
     }
   }
 
+  // Sanity check that we've populated |fds| correctly.
+  DCHECK_EQ(num_fds_to_send, fds.size());
+
   pid_t pid;
   {
     base::AutoLock lock(control_lock_);
     if (!SendMessage(pickle, &fds))
       return base::kNullProcessHandle;
+    autoclose_fds.clear();
+
+    {
+      char buf[sizeof(kZygoteChildPingMessage) + 1];
+      ScopedVector<base::ScopedFD> recv_fds;
+      base::ProcessId real_pid;
+
+      ssize_t n = UnixDomainSocket::RecvMsgWithPid(
+          my_sock.get(), buf, sizeof(buf), &recv_fds, &real_pid);
+      if (n != sizeof(kZygoteChildPingMessage) ||
+          0 != memcmp(buf,
+                      kZygoteChildPingMessage,
+                      sizeof(kZygoteChildPingMessage))) {
+        // Zygote children should still be trustworthy when they're supposed to
+        // ping us, so something's broken if we don't receive a valid ping.
+        LOG(ERROR) << "Did not receive ping from zygote child";
+        NOTREACHED();
+        real_pid = -1;
+      }
+      my_sock.reset();
+
+      // Always send PID back to zygote.
+      Pickle pid_pickle;
+      pid_pickle.WriteInt(kZygoteCommandForkRealPID);
+      pid_pickle.WriteInt(real_pid);
+      if (!SendMessage(pid_pickle, NULL))
+        return base::kNullProcessHandle;
+    }
 
     // Read the reply, which pickles the PID and an optional UMA enumeration.
     static const unsigned kMaxReplyLength = 2048;
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 33d3790..78f648e 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -748,9 +748,6 @@
     IDR_SEARCH_MAGNIFIER_RESULTS, ui::SCALE_FACTOR_100P },
   { "textAreaResizeCorner", IDR_TEXTAREA_RESIZER, ui::SCALE_FACTOR_100P },
   { "textAreaResizeCorner@2x", IDR_TEXTAREA_RESIZER, ui::SCALE_FACTOR_200P },
-  { "inputSpeech", IDR_INPUT_SPEECH, ui::SCALE_FACTOR_100P },
-  { "inputSpeechRecording", IDR_INPUT_SPEECH_RECORDING, ui::SCALE_FACTOR_100P },
-  { "inputSpeechWaiting", IDR_INPUT_SPEECH_WAITING, ui::SCALE_FACTOR_100P },
   { "generatePassword", IDR_PASSWORD_GENERATION_ICON, ui::SCALE_FACTOR_100P },
   { "generatePasswordHover",
     IDR_PASSWORD_GENERATION_ICON_HOVER, ui::SCALE_FACTOR_100P },
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h
index 863d9f7..156c773 100644
--- a/content/child/blink_platform_impl.h
+++ b/content/child/blink_platform_impl.h
@@ -15,7 +15,6 @@
 #include "third_party/WebKit/public/platform/Platform.h"
 #include "third_party/WebKit/public/platform/WebURLError.h"
 #include "ui/base/layout.h"
-#include "webkit/child/resource_loader_bridge.h"
 
 #if defined(USE_DEFAULT_RENDER_THEME)
 #include "content/child/webthemeengine_impl_default.h"
diff --git a/content/child/child_thread.cc b/content/child/child_thread.cc
index 2c9c59e..e39ef4c 100644
--- a/content/child/child_thread.cc
+++ b/content/child/child_thread.cc
@@ -45,7 +45,6 @@
 #include "ipc/ipc_switches.h"
 #include "ipc/ipc_sync_channel.h"
 #include "ipc/ipc_sync_message_filter.h"
-#include "webkit/child/resource_loader_bridge.h"
 
 #if defined(OS_WIN)
 #include "content/common/handle_enumerator_win.h"
@@ -374,11 +373,6 @@
   return &router_;
 }
 
-webkit_glue::ResourceLoaderBridge* ChildThread::CreateBridge(
-    const RequestInfo& request_info) {
-  return resource_dispatcher()->CreateBridge(request_info);
-}
-
 base::SharedMemory* ChildThread::AllocateSharedMemory(size_t buf_size) {
   return AllocateSharedMemory(buf_size, this);
 }
diff --git a/content/child/child_thread.h b/content/child/child_thread.h
index 6af7016..8887e7a 100644
--- a/content/child/child_thread.h
+++ b/content/child/child_thread.h
@@ -79,11 +79,6 @@
 
   MessageRouter* GetRouter();
 
-  // Creates a ResourceLoaderBridge.
-  // Tests can override this method if they want a custom loading behavior.
-  virtual webkit_glue::ResourceLoaderBridge* CreateBridge(
-      const RequestInfo& request_info);
-
   // Allocates a block of shared memory of the given size and
   // maps in into the address space. Returns NULL of failure.
   // Note: On posix, this requires a sync IPC to the browser process,
diff --git a/content/child/ftp_directory_listing_response_delegate.cc b/content/child/ftp_directory_listing_response_delegate.cc
index cc700ae..e6e7feb 100644
--- a/content/child/ftp_directory_listing_response_delegate.cc
+++ b/content/child/ftp_directory_listing_response_delegate.cc
@@ -34,7 +34,7 @@
 base::string16 ConvertPathToUTF16(const std::string& path) {
   // Per RFC 2640, FTP servers should use UTF-8 or its proper subset ASCII,
   // but many old FTP servers use legacy encodings. Try UTF-8 first.
-  if (IsStringUTF8(path))
+  if (base::IsStringUTF8(path))
     return base::UTF8ToUTF16(path);
 
   // Try detecting the encoding. The sample is rather small though, so it may
diff --git a/content/child/indexed_db/indexed_db_dispatcher.cc b/content/child/indexed_db/indexed_db_dispatcher.cc
index 9f56e9f..3a66188 100644
--- a/content/child/indexed_db/indexed_db_dispatcher.cc
+++ b/content/child/indexed_db/indexed_db_dispatcher.cc
@@ -645,8 +645,8 @@
   const IndexedDBKey& primary_key = p.primary_key;
   const std::string& value = p.value;
 
-  WebIDBCursorImpl* cursor = cursors_[ipc_cursor_id];
-  DCHECK(cursor);
+  if (cursors_.find(ipc_cursor_id) == cursors_.end())
+    return;
 
   WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id);
   if (!callbacks)
@@ -678,13 +678,16 @@
     PrepareWebValueAndBlobInfo(
         p.values[i], p.blob_or_file_infos[i], &values[i], &blob_infos[i]);
   }
-  WebIDBCursorImpl* cursor = cursors_[ipc_cursor_id];
-  DCHECK(cursor);
-  cursor->SetPrefetchData(keys, primary_keys, values, blob_infos);
+  std::map<int32, WebIDBCursorImpl*>::const_iterator cur_iter =
+      cursors_.find(ipc_cursor_id);
+  if (cur_iter == cursors_.end())
+    return;
+
+  cur_iter->second->SetPrefetchData(keys, primary_keys, values, blob_infos);
 
   WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id);
   DCHECK(callbacks);
-  cursor->CachedContinue(callbacks);
+  cur_iter->second->CachedContinue(callbacks);
   pending_callbacks_.Remove(ipc_callbacks_id);
 }
 
diff --git a/content/child/npapi/plugin_host.cc b/content/child/npapi/plugin_host.cc
index c48819d..a5eb536 100644
--- a/content/child/npapi/plugin_host.cc
+++ b/content/child/npapi/plugin_host.cc
@@ -623,7 +623,7 @@
   // Before a windowless plugin can refresh part of its drawing area, it must
   // first invalidate it.  This function causes the NPP_HandleEvent method to
   // pass an update event or a paint message to the plug-in.  After calling
-  // this method, the plug-in recieves a paint message asynchronously.
+  // this method, the plug-in receives a paint message asynchronously.
 
   // The browser redraws invalid areas of the document and any windowless
   // plug-ins at regularly timed intervals. To force a paint message, the
diff --git a/content/child/npapi/webplugin_delegate_impl_mac.mm b/content/child/npapi/webplugin_delegate_impl_mac.mm
index e399cc9..9b1d503 100644
--- a/content/child/npapi/webplugin_delegate_impl_mac.mm
+++ b/content/child/npapi/webplugin_delegate_impl_mac.mm
@@ -354,7 +354,7 @@
   }
   NPCocoaEvent* plugin_event = event_converter->plugin_event();
 
-  // The plugin host recieves events related to drags starting outside the
+  // The plugin host receives events related to drags starting outside the
   // plugin, but the NPAPI Cocoa event model spec says plugins shouldn't receive
   // them, so filter them out.
   // If WebKit adds a page capture mode (like the plugin capture mode that
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc
index e8778c8..b6a877f 100644
--- a/content/child/resource_dispatcher.cc
+++ b/content/child/resource_dispatcher.cc
@@ -297,18 +297,6 @@
     return true;
   }
 
-  // If the request has been canceled, only dispatch
-  // ResourceMsg_RequestComplete (otherwise resource leaks) and drop other
-  // messages.
-  if (request_info->is_canceled) {
-    if (message.type() == ResourceMsg_RequestComplete::ID) {
-      DispatchMessage(message);
-    } else {
-      ReleaseResourcesInDataMessage(message);
-    }
-    return true;
-  }
-
   if (request_info->is_deferred) {
     request_info->deferred_message_queue.push_back(new IPC::Message(message));
     return true;
@@ -600,23 +588,6 @@
     return;
   }
 
-  PendingRequestInfo& request_info = it->second;
-  request_info.is_canceled = true;
-
-  // Removes pending requests. If ResourceMsg_RequestComplete was queued,
-  // dispatch it.
-  MessageQueue& queue = request_info.deferred_message_queue;
-  while (!queue.empty()) {
-    IPC::Message* message = queue.front();
-    if (message->type() == ResourceMsg_RequestComplete::ID) {
-      DispatchMessage(*message);
-    } else {
-      ReleaseResourcesInDataMessage(*message);
-    }
-    queue.pop_front();
-    delete message;
-  }
-
   // |request_id| will be removed from |pending_requests_| when
   // OnRequestComplete returns with ERR_ABORTED.
   message_sender()->Send(new ResourceHostMsg_CancelRequest(request_id));
@@ -656,7 +627,6 @@
     : peer(NULL),
       resource_type(ResourceType::SUB_RESOURCE),
       is_deferred(false),
-      is_canceled(false),
       blocked_response(false),
       buffer_size(0) {
 }
@@ -671,7 +641,6 @@
       resource_type(resource_type),
       origin_pid(origin_pid),
       is_deferred(false),
-      is_canceled(false),
       url(request_url),
       frame_origin(frame_origin),
       response_url(request_url),
diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h
index 93e8580..5aabbd4 100644
--- a/content/child/resource_dispatcher.h
+++ b/content/child/resource_dispatcher.h
@@ -113,7 +113,6 @@
     int origin_pid;
     MessageQueue deferred_message_queue;
     bool is_deferred;
-    bool is_canceled;
     // Original requested url.
     GURL url;
     // The security origin of the frame that initiates this request.
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index fa6346c..8792cda 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -117,9 +117,6 @@
   if (command_line.HasSwitch(switches::kEnableWebMIDI))
     WebRuntimeFeatures::enableWebMIDI(true);
 
-  if (command_line.HasSwitch(switches::kDisableSpeechInput))
-    WebRuntimeFeatures::enableSpeechInput(false);
-
   if (command_line.HasSwitch(switches::kDisableFileSystem))
     WebRuntimeFeatures::enableFileSystem(false);
 
@@ -153,6 +150,9 @@
 
   if (command_line.HasSwitch(switches::kEnableBleedingEdgeRenderingFastPaths))
     WebRuntimeFeatures::enableBleedingEdgeFastPaths(true);
+
+  if (command_line.HasSwitch(switches::kEnablePreciseMemoryInfo))
+    WebRuntimeFeatures::enablePreciseMemoryInfo(true);
 }
 
 }  // namespace content
diff --git a/content/child/service_worker/service_worker_dispatcher.cc b/content/child/service_worker/service_worker_dispatcher.cc
index d8ac46e..123f983 100644
--- a/content/child/service_worker/service_worker_dispatcher.cc
+++ b/content/child/service_worker/service_worker_dispatcher.cc
@@ -7,9 +7,14 @@
 #include "base/lazy_instance.h"
 #include "base/stl_util.h"
 #include "base/threading/thread_local.h"
+#include "content/child/child_thread.h"
+#include "content/child/service_worker/service_worker_handle_reference.h"
+#include "content/child/service_worker/service_worker_provider_context.h"
 #include "content/child/service_worker/web_service_worker_impl.h"
 #include "content/child/thread_safe_sender.h"
+#include "content/child/webmessageportchannel_impl.h"
 #include "content/common/service_worker/service_worker_messages.h"
+#include "third_party/WebKit/public/platform/WebServiceWorkerProviderClient.h"
 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
 
 using blink::WebServiceWorkerError;
@@ -39,13 +44,6 @@
 }
 
 ServiceWorkerDispatcher::~ServiceWorkerDispatcher() {
-  for (ScriptClientMap::iterator it = script_clients_.begin();
-       it != script_clients_.end();
-       ++it) {
-    Send(new ServiceWorkerHostMsg_RemoveScriptClient(
-        CurrentWorkerId(), it->first));
-  }
-
   g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted);
 }
 
@@ -61,6 +59,8 @@
                         OnServiceWorkerStateChanged)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetCurrentServiceWorker,
                         OnSetCurrentServiceWorker)
+    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
+                        OnPostMessage)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   DCHECK(handled) << "Unhandled message:" << msg.type();
@@ -91,23 +91,34 @@
       CurrentWorkerId(), request_id, provider_id, pattern));
 }
 
+void ServiceWorkerDispatcher::AddProviderContext(
+    ServiceWorkerProviderContext* provider_context) {
+  DCHECK(provider_context);
+  int provider_id = provider_context->provider_id();
+  DCHECK(!ContainsKey(provider_contexts_, provider_id));
+  provider_contexts_[provider_id] = provider_context;
+}
+
+void ServiceWorkerDispatcher::RemoveProviderContext(
+    ServiceWorkerProviderContext* provider_context) {
+  DCHECK(provider_context);
+  DCHECK(ContainsKey(provider_contexts_, provider_context->provider_id()));
+  provider_contexts_.erase(provider_context->provider_id());
+  worker_to_provider_.erase(provider_context->current_handle_id());
+}
+
 void ServiceWorkerDispatcher::AddScriptClient(
     int provider_id,
     blink::WebServiceWorkerProviderClient* client) {
   DCHECK(client);
   DCHECK(!ContainsKey(script_clients_, provider_id));
   script_clients_[provider_id] = client;
-  thread_safe_sender_->Send(new ServiceWorkerHostMsg_AddScriptClient(
-      CurrentWorkerId(), provider_id));
 }
 
 void ServiceWorkerDispatcher::RemoveScriptClient(int provider_id) {
   // This could be possibly called multiple times to ensure termination.
-  if (ContainsKey(script_clients_, provider_id)) {
+  if (ContainsKey(script_clients_, provider_id))
     script_clients_.erase(provider_id);
-    thread_safe_sender_->Send(new ServiceWorkerHostMsg_RemoveScriptClient(
-        CurrentWorkerId(), provider_id));
-  }
 }
 
 ServiceWorkerDispatcher*
@@ -195,27 +206,63 @@
     int thread_id,
     int handle_id,
     blink::WebServiceWorkerState state) {
-  ServiceWorkerMap::iterator found = service_workers_.find(handle_id);
-  if (found == service_workers_.end())
-    return;
-  found->second->OnStateChanged(state);
+  WorkerObjectMap::iterator worker = service_workers_.find(handle_id);
+  if (worker != service_workers_.end())
+    worker->second->OnStateChanged(state);
+
+  WorkerToProviderMap::iterator provider = worker_to_provider_.find(handle_id);
+  if (provider != worker_to_provider_.end())
+    provider->second->OnServiceWorkerStateChanged(handle_id, state);
 }
 
 void ServiceWorkerDispatcher::OnSetCurrentServiceWorker(
     int thread_id,
     int provider_id,
     const ServiceWorkerObjectInfo& info) {
-  scoped_ptr<WebServiceWorkerImpl> worker(
-      new WebServiceWorkerImpl(info, thread_safe_sender_));
+  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
+  if (provider != provider_contexts_.end()) {
+    provider->second->OnSetCurrentServiceWorker(provider_id, info);
+    worker_to_provider_[info.handle_id] = provider->second;
+  }
+
+  ScriptClientMap::iterator found = script_clients_.find(provider_id);
+  if (found != script_clients_.end()) {
+    // Populate the .current field with the new worker object.
+    scoped_ptr<ServiceWorkerHandleReference> handle_ref(
+        ServiceWorkerHandleReference::Create(info, thread_safe_sender_));
+    found->second->setCurrentServiceWorker(
+        new WebServiceWorkerImpl(handle_ref.Pass(), thread_safe_sender_));
+  }
+}
+
+void ServiceWorkerDispatcher::OnPostMessage(
+    int thread_id,
+    int provider_id,
+    const base::string16& message,
+    const std::vector<int>& sent_message_port_ids,
+    const std::vector<int>& new_routing_ids) {
+  // Make sure we're on the main document thread. (That must be the only
+  // thread we get this message)
+  DCHECK(ChildThread::current());
+
   ScriptClientMap::iterator found = script_clients_.find(provider_id);
   if (found == script_clients_.end()) {
-    // Note that |worker|'s destructor sends a ServiceWorkerObjectDestroyed
-    // message so the browser-side can clean up the ServiceWorkerHandle it
-    // created when sending us this message.
+    // For now we do no queueing for messages sent to nonexistent / unattached
+    // client.
     return;
   }
-  // TODO(falken): Call client->setCurrentServiceWorker(worker) when the Blink
-  // change to add that function rolls in.
+
+  std::vector<WebMessagePortChannelImpl*> ports;
+  if (!sent_message_port_ids.empty()) {
+    ports.resize(sent_message_port_ids.size());
+    for (size_t i = 0; i < sent_message_port_ids.size(); ++i) {
+      ports[i] = new WebMessagePortChannelImpl(
+          new_routing_ids[i], sent_message_port_ids[i],
+          base::MessageLoopProxy::current());
+    }
+  }
+
+  found->second->dispatchMessageEvent(message, ports);
 }
 
 void ServiceWorkerDispatcher::AddServiceWorker(
diff --git a/content/child/service_worker/service_worker_dispatcher.h b/content/child/service_worker/service_worker_dispatcher.h
index c1d8a75..b596b37 100644
--- a/content/child/service_worker/service_worker_dispatcher.h
+++ b/content/child/service_worker/service_worker_dispatcher.h
@@ -6,6 +6,7 @@
 #define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
 
 #include <map>
+#include <vector>
 
 #include "base/id_map.h"
 #include "base/memory/ref_counted.h"
@@ -29,6 +30,7 @@
 
 class ServiceWorkerMessageFilter;
 struct ServiceWorkerObjectInfo;
+class ServiceWorkerProviderContext;
 class ThreadSafeSender;
 class WebServiceWorkerImpl;
 
@@ -55,6 +57,13 @@
       const GURL& pattern,
       blink::WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks);
 
+  // Called when a new provider context for a document is created. Usually
+  // this happens when a new document is being loaded, and is called much
+  // earlier than AddScriptClient.
+  // (This is attached only to the document thread's ServiceWorkerDispatcher)
+  void AddProviderContext(ServiceWorkerProviderContext* provider_context);
+  void RemoveProviderContext(ServiceWorkerProviderContext* provider_context);
+
   // Called when navigator.serviceWorker is instantiated or detached
   // for a document whose provider can be identified by |provider_id|.
   void AddScriptClient(int provider_id,
@@ -74,7 +83,9 @@
   typedef IDMap<blink::WebServiceWorkerProvider::WebServiceWorkerCallbacks,
       IDMapOwnPointer> CallbackMap;
   typedef std::map<int, blink::WebServiceWorkerProviderClient*> ScriptClientMap;
-  typedef std::map<int, WebServiceWorkerImpl*> ServiceWorkerMap;
+  typedef std::map<int, ServiceWorkerProviderContext*> ProviderContextMap;
+  typedef std::map<int, WebServiceWorkerImpl*> WorkerObjectMap;
+  typedef std::map<int, ServiceWorkerProviderContext*> WorkerToProviderMap;
 
   friend class WebServiceWorkerImpl;
 
@@ -96,6 +107,11 @@
   void OnSetCurrentServiceWorker(int thread_id,
                                  int provider_id,
                                  const ServiceWorkerObjectInfo& info);
+  void OnPostMessage(int thread_id,
+                     int provider_id,
+                     const base::string16& message,
+                     const std::vector<int>& sent_message_port_ids,
+                     const std::vector<int>& new_routing_ids);
 
   // Keeps map from handle_id to ServiceWorker object.
   void AddServiceWorker(int handle_id, WebServiceWorkerImpl* worker);
@@ -103,7 +119,12 @@
 
   CallbackMap pending_callbacks_;
   ScriptClientMap script_clients_;
-  ServiceWorkerMap service_workers_;
+  ProviderContextMap provider_contexts_;
+  WorkerObjectMap service_workers_;
+
+  // A map for ServiceWorkers that are associated to a particular document
+  // (e.g. as .current).
+  WorkerToProviderMap worker_to_provider_;
 
   scoped_refptr<ThreadSafeSender> thread_safe_sender_;
 
diff --git a/content/child/service_worker/service_worker_handle_reference.cc b/content/child/service_worker/service_worker_handle_reference.cc
new file mode 100644
index 0000000..1053cfb
--- /dev/null
+++ b/content/child/service_worker/service_worker_handle_reference.cc
@@ -0,0 +1,50 @@
+// 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.
+
+#include "content/child/service_worker/service_worker_handle_reference.h"
+
+#include "content/child/thread_safe_sender.h"
+#include "content/common/service_worker/service_worker_messages.h"
+
+namespace content {
+
+scoped_ptr<ServiceWorkerHandleReference>
+ServiceWorkerHandleReference::Create(
+    const ServiceWorkerObjectInfo& info,
+    ThreadSafeSender* sender) {
+  DCHECK(sender);
+  return make_scoped_ptr(new ServiceWorkerHandleReference(info, sender, true));
+}
+
+scoped_ptr<ServiceWorkerHandleReference>
+ServiceWorkerHandleReference::CreateForDeleter(
+    const ServiceWorkerObjectInfo& info,
+    ThreadSafeSender* sender) {
+  DCHECK(sender);
+  return make_scoped_ptr(new ServiceWorkerHandleReference(info, sender, false));
+}
+
+ServiceWorkerHandleReference::ServiceWorkerHandleReference(
+    const ServiceWorkerObjectInfo& info,
+    ThreadSafeSender* sender,
+    bool increment_ref_in_ctor)
+    : info_(info),
+      sender_(sender) {
+  if (increment_ref_in_ctor &&
+      info_.handle_id != kInvalidServiceWorkerHandleId) {
+    sender_->Send(
+        new ServiceWorkerHostMsg_IncrementServiceWorkerRefCount(
+            info_.handle_id));
+  }
+}
+
+ServiceWorkerHandleReference::~ServiceWorkerHandleReference() {
+  if (info_.handle_id != kInvalidServiceWorkerHandleId) {
+    sender_->Send(
+        new ServiceWorkerHostMsg_DecrementServiceWorkerRefCount(
+            info_.handle_id));
+  }
+}
+
+}  // namespace content
diff --git a/content/child/service_worker/service_worker_handle_reference.h b/content/child/service_worker/service_worker_handle_reference.h
new file mode 100644
index 0000000..48f969f
--- /dev/null
+++ b/content/child/service_worker/service_worker_handle_reference.h
@@ -0,0 +1,49 @@
+// 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.
+
+#ifndef CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_
+#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/common/service_worker/service_worker_types.h"
+
+namespace content {
+
+class ThreadSafeSender;
+
+// Automatically increments and decrements ServiceWorkerHandle's ref-count
+// (in the browser side) in ctor and dtor.
+class ServiceWorkerHandleReference {
+ public:
+  // Creates a new ServiceWorkerHandleReference (and increments ref-count).
+  static scoped_ptr<ServiceWorkerHandleReference> Create(
+      const ServiceWorkerObjectInfo& info,
+      ThreadSafeSender* sender);
+  // This doesn't increment ref-count in ctor.
+  static scoped_ptr<ServiceWorkerHandleReference> CreateForDeleter(
+      const ServiceWorkerObjectInfo& info,
+      ThreadSafeSender* sender);
+
+  ~ServiceWorkerHandleReference();
+
+  const ServiceWorkerObjectInfo& info() const { return info_; }
+  int handle_id() const { return info_.handle_id; }
+  const GURL& scope() const { return info_.scope; }
+  const GURL& url() const { return info_.url; }
+  blink::WebServiceWorkerState state() const { return info_.state; }
+  void set_state(blink::WebServiceWorkerState state) { info_.state = state; }
+
+ private:
+  ServiceWorkerHandleReference(const ServiceWorkerObjectInfo& info,
+                               ThreadSafeSender* sender,
+                               bool increment_ref_in_ctor);
+  ServiceWorkerObjectInfo info_;
+  scoped_refptr<ThreadSafeSender> sender_;
+  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandleReference);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_
diff --git a/content/child/service_worker/service_worker_message_filter.cc b/content/child/service_worker/service_worker_message_filter.cc
index 8ba89df..ad3f4fb 100644
--- a/content/child/service_worker/service_worker_message_filter.cc
+++ b/content/child/service_worker/service_worker_message_filter.cc
@@ -23,7 +23,7 @@
   if (handle_id == kInvalidServiceWorkerHandleId)
     return;
   sender->Send(
-      new ServiceWorkerHostMsg_ServiceWorkerObjectDestroyed(handle_id));
+      new ServiceWorkerHostMsg_DecrementServiceWorkerRefCount(handle_id));
 }
 
 }  // namespace
diff --git a/content/child/service_worker/service_worker_network_provider.cc b/content/child/service_worker/service_worker_network_provider.cc
index 8a0eb6a..2f2ede6 100644
--- a/content/child/service_worker/service_worker_network_provider.cc
+++ b/content/child/service_worker/service_worker_network_provider.cc
@@ -6,6 +6,7 @@
 
 #include "base/atomic_sequence_num.h"
 #include "content/child/child_thread.h"
+#include "content/child/service_worker/service_worker_provider_context.h"
 #include "content/common/service_worker/service_worker_messages.h"
 
 namespace content {
@@ -35,7 +36,8 @@
 }
 
 ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider()
-    : provider_id_(GetNextProviderId()) {
+    : provider_id_(GetNextProviderId()),
+      context_(new ServiceWorkerProviderContext(provider_id_)) {
   if (!ChildThread::current())
     return;  // May be null in some tests.
   ChildThread::current()->Send(
diff --git a/content/child/service_worker/service_worker_network_provider.h b/content/child/service_worker/service_worker_network_provider.h
index 400918f..0d6f494 100644
--- a/content/child/service_worker/service_worker_network_provider.h
+++ b/content/child/service_worker/service_worker_network_provider.h
@@ -6,12 +6,15 @@
 #define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_NETWORK_PROVIDER_IMPL_H_
 
 #include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/supports_user_data.h"
 #include "content/common/content_export.h"
 
 namespace content {
 
+class ServiceWorkerProviderContext;
+
 // A unique provider_id is generated for each instance.
 // Instantiated prior to the main resource load being started and remains
 // allocated until after the last subresource load has occurred.
@@ -37,6 +40,7 @@
   virtual ~ServiceWorkerNetworkProvider();
 
   int provider_id() const { return provider_id_; }
+  ServiceWorkerProviderContext* context() { return context_.get(); }
 
   // This method is called for a provider that's associated with a
   // running service worker script. The version_id indicates which
@@ -45,6 +49,7 @@
 
  private:
   const int provider_id_;
+  scoped_refptr<ServiceWorkerProviderContext> context_;
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNetworkProvider);
 };
 
diff --git a/content/child/service_worker/service_worker_provider_context.cc b/content/child/service_worker/service_worker_provider_context.cc
new file mode 100644
index 0000000..9426881
--- /dev/null
+++ b/content/child/service_worker/service_worker_provider_context.cc
@@ -0,0 +1,78 @@
+// 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.
+
+#include "content/child/service_worker/service_worker_provider_context.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/stl_util.h"
+#include "content/child/child_thread.h"
+#include "content/child/service_worker/service_worker_dispatcher.h"
+#include "content/child/service_worker/service_worker_handle_reference.h"
+#include "content/child/thread_safe_sender.h"
+#include "content/child/worker_task_runner.h"
+#include "content/common/service_worker/service_worker_messages.h"
+
+namespace content {
+
+ServiceWorkerProviderContext::ServiceWorkerProviderContext(int provider_id)
+    : provider_id_(provider_id),
+      main_thread_loop_proxy_(base::MessageLoopProxy::current()) {
+  if (!ChildThread::current())
+    return;  // May be null in some tests.
+  thread_safe_sender_ = ChildThread::current()->thread_safe_sender();
+  ServiceWorkerDispatcher* dispatcher =
+      ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
+          thread_safe_sender_);
+  DCHECK(dispatcher);
+  dispatcher->AddProviderContext(this);
+}
+
+ServiceWorkerProviderContext::~ServiceWorkerProviderContext() {
+  if (ServiceWorkerDispatcher* dispatcher =
+          ServiceWorkerDispatcher::GetThreadSpecificInstance()) {
+    dispatcher->RemoveProviderContext(this);
+  }
+}
+
+scoped_ptr<ServiceWorkerHandleReference>
+ServiceWorkerProviderContext::GetCurrentServiceWorkerHandle() {
+  DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
+  if (!current_)
+    return scoped_ptr<ServiceWorkerHandleReference>();
+  return ServiceWorkerHandleReference::Create(
+      current_->info(), thread_safe_sender_);
+}
+
+void ServiceWorkerProviderContext::OnServiceWorkerStateChanged(
+    int handle_id,
+    blink::WebServiceWorkerState state) {
+  // Currently .current is the only ServiceWorker associated to this provider.
+  DCHECK_EQ(current_handle_id(), handle_id);
+  current_->set_state(state);
+
+  // TODO(kinuko): We can forward the message to other threads here
+  // when we support navigator.serviceWorker in dedicated workers.
+}
+
+void ServiceWorkerProviderContext::OnSetCurrentServiceWorker(
+    int provider_id,
+    const ServiceWorkerObjectInfo& info) {
+  DCHECK_EQ(provider_id_, provider_id);
+
+  // This context is is the primary owner of this handle, keeps the
+  // initial reference until it goes away.
+  current_ = ServiceWorkerHandleReference::CreateForDeleter(
+      info, thread_safe_sender_);
+
+  // TODO(kinuko): We can forward the message to other threads here
+  // when we support navigator.serviceWorker in dedicated workers.
+}
+
+int ServiceWorkerProviderContext::current_handle_id() const {
+  DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
+  return current_ ? current_->info().handle_id : kInvalidServiceWorkerHandleId;
+}
+
+}  // namespace content
diff --git a/content/child/service_worker/service_worker_provider_context.h b/content/child/service_worker/service_worker_provider_context.h
new file mode 100644
index 0000000..23b1114
--- /dev/null
+++ b/content/child/service_worker/service_worker_provider_context.h
@@ -0,0 +1,66 @@
+// 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.
+
+#ifndef CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_CONTEXT_H_
+#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_CONTEXT_H_
+
+#include <set>
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner_helpers.h"
+#include "base/synchronization/lock.h"
+#include "content/common/service_worker/service_worker_types.h"
+
+namespace base {
+class MessageLoopProxy;
+}
+
+namespace IPC {
+class Message;
+}
+
+namespace content {
+
+class ServiceWorkerHandleReference;
+struct ServiceWorkerProviderContextDeleter;
+class ThreadSafeSender;
+
+// An instance of this class holds document-related information (e.g.
+// .current). Created and destructed on the main thread.
+// TODO(kinuko): To support navigator.serviceWorker in dedicated workers
+// this needs to be RefCountedThreadSafe and .current info needs to be
+// handled in a thread-safe manner (e.g. by a lock etc).
+class ServiceWorkerProviderContext
+    : public base::RefCounted<ServiceWorkerProviderContext> {
+ public:
+  explicit ServiceWorkerProviderContext(int provider_id);
+
+  // Returns a new handle reference for .current.
+  scoped_ptr<ServiceWorkerHandleReference> GetCurrentServiceWorkerHandle();
+
+  // Called from ServiceWorkerDispatcher.
+  void OnServiceWorkerStateChanged(int handle_id,
+                                   blink::WebServiceWorkerState state);
+  void OnSetCurrentServiceWorker(int provider_id,
+                                 const ServiceWorkerObjectInfo& info);
+
+  int provider_id() const { return provider_id_; }
+  int current_handle_id() const;
+
+ private:
+  friend class base::RefCounted<ServiceWorkerProviderContext>;
+  ~ServiceWorkerProviderContext();
+
+  const int provider_id_;
+  scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_;
+  scoped_refptr<ThreadSafeSender> thread_safe_sender_;
+  scoped_ptr<ServiceWorkerHandleReference> current_;
+
+  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderContext);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_CONTEXT_H_
diff --git a/content/child/service_worker/web_service_worker_impl.cc b/content/child/service_worker/web_service_worker_impl.cc
index 02f8779..d996dd6 100644
--- a/content/child/service_worker/web_service_worker_impl.cc
+++ b/content/child/service_worker/web_service_worker_impl.cc
@@ -5,6 +5,7 @@
 #include "content/child/service_worker/web_service_worker_impl.h"
 
 #include "content/child/service_worker/service_worker_dispatcher.h"
+#include "content/child/service_worker/service_worker_handle_reference.h"
 #include "content/child/thread_safe_sender.h"
 #include "content/child/webmessageportchannel_impl.h"
 #include "content/common/service_worker/service_worker_messages.h"
@@ -21,27 +22,38 @@
 WebServiceWorkerImpl::WebServiceWorkerImpl(
     const ServiceWorkerObjectInfo& info,
     ThreadSafeSender* thread_safe_sender)
-    : handle_id_(info.handle_id),
-      scope_(info.scope),
-      url_(info.url),
-      state_(info.state),
+    : handle_ref_(
+          ServiceWorkerHandleReference::CreateForDeleter(info,
+                                                         thread_safe_sender)),
+      state_(handle_ref_->state()),
       thread_safe_sender_(thread_safe_sender),
       proxy_(NULL) {
   ServiceWorkerDispatcher* dispatcher =
       ServiceWorkerDispatcher::GetThreadSpecificInstance();
   DCHECK(dispatcher);
-  dispatcher->AddServiceWorker(handle_id_, this);
+  dispatcher->AddServiceWorker(handle_ref_->handle_id(), this);
+}
+
+WebServiceWorkerImpl::WebServiceWorkerImpl(
+    scoped_ptr<ServiceWorkerHandleReference> handle_ref,
+    ThreadSafeSender* thread_safe_sender)
+    : handle_ref_(handle_ref.Pass()),
+      state_(handle_ref_->state()),
+      thread_safe_sender_(thread_safe_sender),
+      proxy_(NULL) {
+  ServiceWorkerDispatcher* dispatcher =
+      ServiceWorkerDispatcher::GetThreadSpecificInstance();
+  DCHECK(dispatcher);
+  dispatcher->AddServiceWorker(handle_ref_->handle_id(), this);
 }
 
 WebServiceWorkerImpl::~WebServiceWorkerImpl() {
-  if (handle_id_ == kInvalidServiceWorkerHandleId)
+  if (handle_ref_->handle_id() == kInvalidServiceWorkerHandleId)
     return;
-  thread_safe_sender_->Send(
-      new ServiceWorkerHostMsg_ServiceWorkerObjectDestroyed(handle_id_));
   ServiceWorkerDispatcher* dispatcher =
       ServiceWorkerDispatcher::GetThreadSpecificInstance();
   if (dispatcher)
-    dispatcher->RemoveServiceWorker(handle_id_);
+    dispatcher->RemoveServiceWorker(handle_ref_->handle_id());
 }
 
 void WebServiceWorkerImpl::OnStateChanged(
@@ -70,11 +82,11 @@
 }
 
 blink::WebURL WebServiceWorkerImpl::scope() const {
-  return scope_;
+  return handle_ref_->scope();
 }
 
 blink::WebURL WebServiceWorkerImpl::url() const {
-  return url_;
+  return handle_ref_->url();
 }
 
 blink::WebServiceWorkerState WebServiceWorkerImpl::state() const {
@@ -83,8 +95,8 @@
 
 void WebServiceWorkerImpl::postMessage(const WebString& message,
                                        WebMessagePortChannelArray* channels) {
-  thread_safe_sender_->Send(new ServiceWorkerHostMsg_PostMessage(
-      handle_id_,
+  thread_safe_sender_->Send(new ServiceWorkerHostMsg_PostMessageToWorker(
+      handle_ref_->handle_id(),
       message,
       WebMessagePortChannelImpl::ExtractMessagePortIDs(channels)));
 }
diff --git a/content/child/service_worker/web_service_worker_impl.h b/content/child/service_worker/web_service_worker_impl.h
index cf9728e..0558b23 100644
--- a/content/child/service_worker/web_service_worker_impl.h
+++ b/content/child/service_worker/web_service_worker_impl.h
@@ -20,14 +20,25 @@
 
 namespace content {
 
-class ThreadSafeSender;
+class ServiceWorkerHandleReference;
 struct ServiceWorkerObjectInfo;
+class ThreadSafeSender;
 
+// Each instance corresponds to one ServiceWorker object in JS context, and
+// is held by ServiceWorker object in blink's c++ layer, e.g. created one
+// per navigator.serviceWorker.current or per successful
+// navigator.serviceWorker.register call.
+//
+// Each instance holds one ServiceWorkerHandleReference so that
+// corresponding ServiceWorkerHandle doesn't go away in the browser process
+// while the ServiceWorker object is alive.
 class WebServiceWorkerImpl
     : NON_EXPORTED_BASE(public blink::WebServiceWorker) {
  public:
   WebServiceWorkerImpl(const ServiceWorkerObjectInfo& info,
                        ThreadSafeSender* thread_safe_sender);
+  WebServiceWorkerImpl(scoped_ptr<ServiceWorkerHandleReference> handle_ref,
+                       ThreadSafeSender* thread_safe_sender);
   virtual ~WebServiceWorkerImpl();
 
   // Notifies that the service worker's state changed. This function may queue
@@ -47,9 +58,7 @@
   // Commits the new state internally and notifies the proxy of the change.
   void ChangeState(blink::WebServiceWorkerState new_state);
 
-  const int handle_id_;
-  const GURL scope_;
-  const GURL url_;
+  scoped_ptr<ServiceWorkerHandleReference> handle_ref_;
   blink::WebServiceWorkerState state_;
   scoped_refptr<ThreadSafeSender> thread_safe_sender_;
   blink::WebServiceWorkerProxy* proxy_;
diff --git a/content/child/service_worker/web_service_worker_provider_impl.cc b/content/child/service_worker/web_service_worker_provider_impl.cc
index 99f9738..407552d 100644
--- a/content/child/service_worker/web_service_worker_provider_impl.cc
+++ b/content/child/service_worker/web_service_worker_provider_impl.cc
@@ -8,7 +8,12 @@
 #include "base/logging.h"
 #include "content/child/child_thread.h"
 #include "content/child/service_worker/service_worker_dispatcher.h"
+#include "content/child/service_worker/service_worker_handle_reference.h"
+#include "content/child/service_worker/service_worker_provider_context.h"
+#include "content/child/service_worker/web_service_worker_impl.h"
 #include "content/child/thread_safe_sender.h"
+#include "content/common/service_worker/service_worker_messages.h"
+#include "third_party/WebKit/public/platform/WebServiceWorkerProviderClient.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
 
 using blink::WebURL;
@@ -17,9 +22,10 @@
 
 WebServiceWorkerProviderImpl::WebServiceWorkerProviderImpl(
     ThreadSafeSender* thread_safe_sender,
-    int provider_id)
+    ServiceWorkerProviderContext* context)
     : thread_safe_sender_(thread_safe_sender),
-      provider_id_(provider_id) {
+      context_(context),
+      provider_id_(context->provider_id()) {
 }
 
 WebServiceWorkerProviderImpl::~WebServiceWorkerProviderImpl() {
@@ -29,10 +35,28 @@
 
 void WebServiceWorkerProviderImpl::setClient(
     blink::WebServiceWorkerProviderClient* client) {
-  if (client)
-    GetDispatcher()->AddScriptClient(provider_id_, client);
-  else
+  if (!client) {
     RemoveScriptClient();
+    return;
+  }
+
+  // TODO(kinuko): Here we could also register the current thread ID
+  // on the provider context so that multiple WebServiceWorkerProviderImpl
+  // (e.g. on document and on dedicated workers) can properly share
+  // the single provider context across threads. (http://crbug.com/366538
+  // for more context)
+  scoped_ptr<ServiceWorkerHandleReference> current =
+      context_->GetCurrentServiceWorkerHandle();
+  GetDispatcher()->AddScriptClient(provider_id_, client);
+  if (!current)
+    return;
+
+  int handle_id = current->info().handle_id;
+  if (handle_id != kInvalidServiceWorkerHandleId) {
+    scoped_ptr<WebServiceWorkerImpl> worker(
+        new WebServiceWorkerImpl(current.Pass(), thread_safe_sender_));
+    client->setCurrentServiceWorker(worker.release());
+  }
 }
 
 void WebServiceWorkerProviderImpl::registerServiceWorker(
diff --git a/content/child/service_worker/web_service_worker_provider_impl.h b/content/child/service_worker/web_service_worker_provider_impl.h
index 69aeed6..912d2f4 100644
--- a/content/child/service_worker/web_service_worker_provider_impl.h
+++ b/content/child/service_worker/web_service_worker_provider_impl.h
@@ -18,13 +18,16 @@
 namespace content {
 
 class ServiceWorkerDispatcher;
+class ServiceWorkerProviderContext;
 class ThreadSafeSender;
 
+// This class corresponds to one ServiceWorkerContainer interface in
+// JS context (i.e. navigator.serviceWorker).
 class WebServiceWorkerProviderImpl
     : NON_EXPORTED_BASE(public blink::WebServiceWorkerProvider) {
  public:
   WebServiceWorkerProviderImpl(ThreadSafeSender* thread_safe_sender,
-                               int provider_id);
+                               ServiceWorkerProviderContext* context);
   virtual ~WebServiceWorkerProviderImpl();
 
   virtual void setClient(blink::WebServiceWorkerProviderClient* client);
@@ -36,11 +39,14 @@
   virtual void unregisterServiceWorker(const blink::WebURL& pattern,
                                        WebServiceWorkerCallbacks*);
 
+  ServiceWorkerProviderContext* context() { return context_.get(); }
+
  private:
   void RemoveScriptClient();
   ServiceWorkerDispatcher* GetDispatcher();
 
   scoped_refptr<ThreadSafeSender> thread_safe_sender_;
+  scoped_refptr<ServiceWorkerProviderContext> context_;
   const int provider_id_;
 
   DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerProviderImpl);
diff --git a/content/child/simple_webmimeregistry_impl.cc b/content/child/simple_webmimeregistry_impl.cc
index 3b3ebd6..e7416d9 100644
--- a/content/child/simple_webmimeregistry_impl.cc
+++ b/content/child/simple_webmimeregistry_impl.cc
@@ -18,7 +18,8 @@
 
 //static
 std::string SimpleWebMimeRegistryImpl::ToASCIIOrEmpty(const WebString& string) {
-  return IsStringASCII(string) ? base::UTF16ToASCII(string) : std::string();
+  return base::IsStringASCII(string) ? base::UTF16ToASCII(string)
+                                     : std::string();
 }
 
 WebMimeRegistry::SupportsType SimpleWebMimeRegistryImpl::supportsMIMEType(
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc
index 7724a50..ca8fa82 100644
--- a/content/child/web_url_loader_impl.cc
+++ b/content/child/web_url_loader_impl.cc
@@ -16,6 +16,7 @@
 #include "content/child/ftp_directory_listing_response_delegate.h"
 #include "content/child/request_extra_data.h"
 #include "content/child/request_info.h"
+#include "content/child/resource_dispatcher.h"
 #include "content/child/sync_load_response.h"
 #include "content/common/resource_request_body.h"
 #include "content/public/child/request_peer.h"
@@ -400,7 +401,8 @@
   request_info.extra_data = request.extraData();
   referrer_policy_ = request.referrerPolicy();
   request_info.referrer_policy = request.referrerPolicy();
-  bridge_.reset(ChildThread::current()->CreateBridge(request_info));
+  bridge_.reset(ChildThread::current()->resource_dispatcher()->CreateBridge(
+      request_info));
 
   if (!request.httpBody().isNull()) {
     // GET and HEAD requests shouldn't have http bodies.
diff --git a/content/child/webcrypto/platform_crypto_nss.cc b/content/child/webcrypto/platform_crypto_nss.cc
index ffa62a5..65dbb2f 100644
--- a/content/child/webcrypto/platform_crypto_nss.cc
+++ b/content/child/webcrypto/platform_crypto_nss.cc
@@ -560,13 +560,16 @@
   PORT_SetError(0);
 #endif
 
-  crypto::ScopedPK11SymKey new_key(PK11_UnwrapSymKey(wrapping_key->key(),
-                                                     CKM_NSS_AES_KEY_WRAP,
-                                                     param_item.get(),
-                                                     &cipher_text,
-                                                     mechanism,
-                                                     flags,
-                                                     plaintext_length));
+  crypto::ScopedPK11SymKey new_key(
+      PK11_UnwrapSymKeyWithFlags(wrapping_key->key(),
+                                 CKM_NSS_AES_KEY_WRAP,
+                                 param_item.get(),
+                                 &cipher_text,
+                                 mechanism,
+                                 CKA_FLAGS_ONLY,
+                                 plaintext_length,
+                                 flags));
+
   // TODO(padolph): Use NSS PORT_GetError() and friends to report a more
   // accurate error, providing if doesn't leak any information to web pages
   // about other web crypto users, key details, etc.
@@ -1575,7 +1578,7 @@
   // temporarily viewed as a symmetric key to be unwrapped (decrypted).
   crypto::ScopedPK11SymKey decrypted;
   Status status = DoUnwrapSymKeyAesKw(
-      data, wrapping_key, CKK_GENERIC_SECRET, CKA_ENCRYPT, &decrypted);
+      data, wrapping_key, CKK_GENERIC_SECRET, 0, &decrypted);
   if (status.IsError())
     return status;
 
diff --git a/content/child/webcrypto/shared_crypto_unittest.cc b/content/child/webcrypto/shared_crypto_unittest.cc
index 3beadc4..20f1ad5 100644
--- a/content/child/webcrypto/shared_crypto_unittest.cc
+++ b/content/child/webcrypto/shared_crypto_unittest.cc
@@ -2785,9 +2785,7 @@
     EXPECT_FALSE(key.isNull());
     EXPECT_TRUE(key.handle());
     EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
-    EXPECT_EQ(
-        webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc).id(),
-        key.algorithm().id());
+    EXPECT_EQ(blink::WebCryptoAlgorithmIdAesCbc, key.algorithm().id());
     EXPECT_EQ(true, key.extractable());
     EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages());
 
@@ -2799,6 +2797,64 @@
   }
 }
 
+// Unwrap a HMAC key using AES-KW, and then try doing a sign/verify with the
+// unwrapped key
+TEST_F(SharedCryptoTest, MAYBE(AesKwRawSymkeyUnwrapSignVerifyHmac)) {
+  scoped_ptr<base::ListValue> tests;
+  ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
+
+  base::DictionaryValue* test;
+  ASSERT_TRUE(tests->GetDictionary(0, &test));
+  const std::vector<uint8> test_kek = GetBytesFromHexString(test, "kek");
+  const std::vector<uint8> test_ciphertext =
+      GetBytesFromHexString(test, "ciphertext");
+  const blink::WebCryptoAlgorithm wrapping_algorithm =
+      CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
+
+  // Import the wrapping key.
+  blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
+      test_kek, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey);
+
+  // Unwrap the known ciphertext.
+  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  ASSERT_EQ(
+      Status::Success(),
+      UnwrapKey(blink::WebCryptoKeyFormatRaw,
+                CryptoData(test_ciphertext),
+                wrapping_key,
+                wrapping_algorithm,
+                CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1),
+                false,
+                blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify,
+                &key));
+
+  EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+  EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id());
+  EXPECT_FALSE(key.extractable());
+  EXPECT_EQ(blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify,
+            key.usages());
+
+  // Sign an empty message and ensure it is verified.
+  std::vector<uint8> test_message;
+  std::vector<uint8> signature;
+
+  ASSERT_EQ(Status::Success(),
+            Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac),
+                 key,
+                 CryptoData(test_message),
+                 &signature));
+
+  EXPECT_GT(signature.size(), 0u);
+
+  bool verify_result;
+  ASSERT_EQ(Status::Success(),
+            VerifySignature(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac),
+                            key,
+                            CryptoData(signature),
+                            CryptoData(test_message),
+                            &verify_result));
+}
+
 TEST_F(SharedCryptoTest, MAYBE(AesKwRawSymkeyWrapUnwrapErrors)) {
   scoped_ptr<base::ListValue> tests;
   ASSERT_TRUE(ReadJsonTestFileToList("aes_kw.json", &tests));
diff --git a/content/common/DEPS b/content/common/DEPS
index 2e419da..645304d 100644
--- a/content/common/DEPS
+++ b/content/common/DEPS
@@ -13,6 +13,7 @@
   "+third_party/WebKit/public/platform/WebDeviceOrientationData.h",
   "+third_party/WebKit/public/platform/WebFloatPoint.h",
   "+third_party/WebKit/public/platform/WebFloatRect.h",
+  "+third_party/WebKit/public/platform/WebGamepad.h",
   "+third_party/WebKit/public/platform/WebGamepads.h",
   "+third_party/WebKit/public/platform/WebGraphicsContext3D.h",
   "+third_party/WebKit/public/platform/WebHTTPBody.h",
diff --git a/content/common/cc_messages.cc b/content/common/cc_messages.cc
index 079cb2a..87201c4 100644
--- a/content/common/cc_messages.cc
+++ b/content/common/cc_messages.cc
@@ -504,10 +504,9 @@
 
     // If the quad has a new shared quad state, read it in.
     if (last_shared_quad_state_index != shared_quad_state_index) {
-      scoped_ptr<cc::SharedQuadState> state(cc::SharedQuadState::Create());
-      if (!ReadParam(m, iter, state.get()))
+      cc::SharedQuadState* state = p->CreateAndAppendSharedQuadState();
+      if (!ReadParam(m, iter, state))
         return false;
-      p->shared_quad_state_list.push_back(state.Pass());
       last_shared_quad_state_index = shared_quad_state_index;
     }
 
diff --git a/content/common/cc_messages.h b/content/common/cc_messages.h
index b388bbb..3ad133c 100644
--- a/content/common/cc_messages.h
+++ b/content/common/cc_messages.h
@@ -131,6 +131,8 @@
                           cc::FilterOperation::FILTER_TYPE_LAST )
 IPC_ENUM_TRAITS_MAX_VALUE(cc::ResourceFormat, cc::RESOURCE_FORMAT_MAX)
 IPC_ENUM_TRAITS_MAX_VALUE(SkXfermode::Mode, SkXfermode::kLastMode)
+IPC_ENUM_TRAITS_MAX_VALUE(cc::YUVVideoDrawQuad::ColorSpace,
+                          cc::YUVVideoDrawQuad::COLOR_SPACE_LAST)
 
 IPC_STRUCT_TRAITS_BEGIN(cc::RenderPass::Id)
   IPC_STRUCT_TRAITS_MEMBER(layer_id)
@@ -220,6 +222,7 @@
   IPC_STRUCT_TRAITS_MEMBER(u_plane_resource_id)
   IPC_STRUCT_TRAITS_MEMBER(v_plane_resource_id)
   IPC_STRUCT_TRAITS_MEMBER(a_plane_resource_id)
+  IPC_STRUCT_TRAITS_MEMBER(color_space)
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(cc::SharedQuadState)
diff --git a/content/common/cc_messages_perftest.cc b/content/common/cc_messages_perftest.cc
index 87aa2e8..7589128 100644
--- a/content/common/cc_messages_perftest.cc
+++ b/content/common/cc_messages_perftest.cc
@@ -65,7 +65,7 @@
   scoped_ptr<CompositorFrame> frame(new CompositorFrame);
 
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
-  render_pass->shared_quad_state_list.push_back(SharedQuadState::Create());
+  render_pass->CreateAndAppendSharedQuadState();
   for (int i = 0; i < 4000; ++i) {
     render_pass->quad_list.push_back(
         PictureDrawQuad::Create().PassAs<DrawQuad>());
@@ -83,7 +83,7 @@
   scoped_ptr<CompositorFrame> frame(new CompositorFrame);
 
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
-  render_pass->shared_quad_state_list.push_back(SharedQuadState::Create());
+  render_pass->CreateAndAppendSharedQuadState();
   for (int i = 0; i < 100000; ++i) {
     render_pass->quad_list.push_back(
         PictureDrawQuad::Create().PassAs<DrawQuad>());
@@ -102,7 +102,7 @@
 
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
   for (int i = 0; i < 4000; ++i) {
-    render_pass->shared_quad_state_list.push_back(SharedQuadState::Create());
+    render_pass->CreateAndAppendSharedQuadState();
     render_pass->quad_list.push_back(
         PictureDrawQuad::Create().PassAs<DrawQuad>());
     render_pass->quad_list.back()->shared_quad_state =
@@ -120,7 +120,7 @@
 
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
   for (int i = 0; i < 100000; ++i) {
-    render_pass->shared_quad_state_list.push_back(SharedQuadState::Create());
+    render_pass->CreateAndAppendSharedQuadState();
     render_pass->quad_list.push_back(
         PictureDrawQuad::Create().PassAs<DrawQuad>());
     render_pass->quad_list.back()->shared_quad_state =
@@ -141,7 +141,7 @@
   for (int i = 0; i < 1000; ++i) {
     scoped_ptr<RenderPass> render_pass = RenderPass::Create();
     for (int j = 0; j < 100; ++j) {
-      render_pass->shared_quad_state_list.push_back(SharedQuadState::Create());
+      render_pass->CreateAndAppendSharedQuadState();
       render_pass->quad_list.push_back(
           PictureDrawQuad::Create().PassAs<DrawQuad>());
       render_pass->quad_list.back()->shared_quad_state =
diff --git a/content/common/cc_messages_unittest.cc b/content/common/cc_messages_unittest.cc
index 09ad85c..ee65629 100644
--- a/content/common/cc_messages_unittest.cc
+++ b/content/common/cc_messages_unittest.cc
@@ -200,6 +200,7 @@
     EXPECT_EQ(a->u_plane_resource_id, b->u_plane_resource_id);
     EXPECT_EQ(a->v_plane_resource_id, b->v_plane_resource_id);
     EXPECT_EQ(a->a_plane_resource_id, b->a_plane_resource_id);
+    EXPECT_EQ(a->color_space, b->color_space);
   }
 
   void Compare(const TransferableResource& a, const TransferableResource& b) {
@@ -259,6 +260,8 @@
   ResourceProvider::ResourceId arbitrary_resourceid3 = 23;
   ResourceProvider::ResourceId arbitrary_resourceid4 = 16;
   SkScalar arbitrary_sigma = SkFloatToScalar(2.0f);
+  YUVVideoDrawQuad::ColorSpace arbitrary_color_space =
+      YUVVideoDrawQuad::REC_601;
 
   FilterOperations arbitrary_filters1;
   arbitrary_filters1.Append(FilterOperation::CreateGrayscaleFilter(
@@ -272,7 +275,14 @@
   arbitrary_filters2.Append(FilterOperation::CreateBrightnessFilter(
       arbitrary_float2));
 
-  scoped_ptr<SharedQuadState> shared_state1_in = SharedQuadState::Create();
+  scoped_ptr<RenderPass> pass_in = RenderPass::Create();
+  pass_in->SetAll(arbitrary_id,
+                  arbitrary_rect1,
+                  arbitrary_rect2,
+                  arbitrary_matrix,
+                  arbitrary_bool1);
+
+  SharedQuadState* shared_state1_in = pass_in->CreateAndAppendSharedQuadState();
   shared_state1_in->SetAll(arbitrary_matrix,
                            arbitrary_size1,
                            arbitrary_rect1,
@@ -280,11 +290,21 @@
                            arbitrary_bool1,
                            arbitrary_float1,
                            arbitrary_blend_mode1);
-  scoped_ptr<SharedQuadState> shared_state1_cmp = shared_state1_in->Copy();
+
+  scoped_ptr<RenderPass> pass_cmp = RenderPass::Create();
+  pass_cmp->SetAll(arbitrary_id,
+                   arbitrary_rect1,
+                   arbitrary_rect2,
+                   arbitrary_matrix,
+                   arbitrary_bool1);
+
+  SharedQuadState* shared_state1_cmp =
+      pass_cmp->CreateAndAppendSharedQuadState();
+  shared_state1_cmp->CopyFrom(shared_state1_in);
 
   scoped_ptr<CheckerboardDrawQuad> checkerboard_in =
       CheckerboardDrawQuad::Create();
-  checkerboard_in->SetAll(shared_state1_in.get(),
+  checkerboard_in->SetAll(shared_state1_in,
                           arbitrary_rect1,
                           arbitrary_rect2_inside_rect1,
                           arbitrary_rect1_inside_rect1,
@@ -295,7 +315,7 @@
 
   scoped_ptr<DebugBorderDrawQuad> debugborder_in =
       DebugBorderDrawQuad::Create();
-  debugborder_in->SetAll(shared_state1_in.get(),
+  debugborder_in->SetAll(shared_state1_in,
                          arbitrary_rect3,
                          arbitrary_rect1_inside_rect3,
                          arbitrary_rect2_inside_rect3,
@@ -307,7 +327,7 @@
 
   scoped_ptr<IOSurfaceDrawQuad> iosurface_in =
       IOSurfaceDrawQuad::Create();
-  iosurface_in->SetAll(shared_state1_in.get(),
+  iosurface_in->SetAll(shared_state1_in,
                        arbitrary_rect2,
                        arbitrary_rect2_inside_rect2,
                        arbitrary_rect1_inside_rect2,
@@ -318,7 +338,7 @@
   scoped_ptr<DrawQuad> iosurface_cmp = iosurface_in->Copy(
       iosurface_in->shared_quad_state);
 
-  scoped_ptr<SharedQuadState> shared_state2_in = SharedQuadState::Create();
+  SharedQuadState* shared_state2_in = pass_in->CreateAndAppendSharedQuadState();
   shared_state2_in->SetAll(arbitrary_matrix,
                            arbitrary_size2,
                            arbitrary_rect2,
@@ -326,11 +346,13 @@
                            arbitrary_bool1,
                            arbitrary_float2,
                            arbitrary_blend_mode2);
-  scoped_ptr<SharedQuadState> shared_state2_cmp = shared_state2_in->Copy();
+  SharedQuadState* shared_state2_cmp =
+      pass_cmp->CreateAndAppendSharedQuadState();
+  shared_state2_cmp->CopyFrom(shared_state2_in);
 
   scoped_ptr<RenderPassDrawQuad> renderpass_in =
       RenderPassDrawQuad::Create();
-  renderpass_in->SetAll(shared_state2_in.get(),
+  renderpass_in->SetAll(shared_state2_in,
                         arbitrary_rect1,
                         arbitrary_rect2_inside_rect1,
                         arbitrary_rect1_inside_rect1,
@@ -345,7 +367,7 @@
   scoped_ptr<RenderPassDrawQuad> renderpass_cmp = renderpass_in->Copy(
       renderpass_in->shared_quad_state, renderpass_in->render_pass_id);
 
-  scoped_ptr<SharedQuadState> shared_state3_in = SharedQuadState::Create();
+  SharedQuadState* shared_state3_in = pass_in->CreateAndAppendSharedQuadState();
   shared_state3_in->SetAll(arbitrary_matrix,
                            arbitrary_size3,
                            arbitrary_rect3,
@@ -353,11 +375,13 @@
                            arbitrary_bool1,
                            arbitrary_float3,
                            arbitrary_blend_mode3);
-  scoped_ptr<SharedQuadState> shared_state3_cmp = shared_state3_in->Copy();
+  SharedQuadState* shared_state3_cmp =
+      pass_cmp->CreateAndAppendSharedQuadState();
+  shared_state3_cmp->CopyFrom(shared_state3_in);
 
   scoped_ptr<SolidColorDrawQuad> solidcolor_in =
       SolidColorDrawQuad::Create();
-  solidcolor_in->SetAll(shared_state3_in.get(),
+  solidcolor_in->SetAll(shared_state3_in,
                         arbitrary_rect3,
                         arbitrary_rect1_inside_rect3,
                         arbitrary_rect2_inside_rect3,
@@ -369,7 +393,7 @@
 
   scoped_ptr<StreamVideoDrawQuad> streamvideo_in =
       StreamVideoDrawQuad::Create();
-  streamvideo_in->SetAll(shared_state3_in.get(),
+  streamvideo_in->SetAll(shared_state3_in,
                          arbitrary_rect2,
                          arbitrary_rect2_inside_rect2,
                          arbitrary_rect1_inside_rect2,
@@ -381,17 +405,17 @@
 
   int arbitrary_surface_id = 3;
   scoped_ptr<SurfaceDrawQuad> surface_in = SurfaceDrawQuad::Create();
-  surface_in->SetAll(shared_state3_in.get(),
-                         arbitrary_rect2,
-                         arbitrary_rect2_inside_rect2,
-                         arbitrary_rect1_inside_rect2,
-                         arbitrary_bool1,
-                         arbitrary_surface_id);
+  surface_in->SetAll(shared_state3_in,
+                     arbitrary_rect2,
+                     arbitrary_rect2_inside_rect2,
+                     arbitrary_rect1_inside_rect2,
+                     arbitrary_bool1,
+                     arbitrary_surface_id);
   scoped_ptr<DrawQuad> surface_cmp = surface_in->Copy(
       surface_in->shared_quad_state);
 
   scoped_ptr<TextureDrawQuad> texture_in = TextureDrawQuad::Create();
-  texture_in->SetAll(shared_state3_in.get(),
+  texture_in->SetAll(shared_state3_in,
                      arbitrary_rect2,
                      arbitrary_rect2_inside_rect2,
                      arbitrary_rect1_inside_rect2,
@@ -407,7 +431,7 @@
       texture_in->shared_quad_state);
 
   scoped_ptr<TileDrawQuad> tile_in = TileDrawQuad::Create();
-  tile_in->SetAll(shared_state3_in.get(),
+  tile_in->SetAll(shared_state3_in,
                   arbitrary_rect2,
                   arbitrary_rect2_inside_rect2,
                   arbitrary_rect1_inside_rect2,
@@ -421,7 +445,7 @@
 
   scoped_ptr<YUVVideoDrawQuad> yuvvideo_in =
       YUVVideoDrawQuad::Create();
-  yuvvideo_in->SetAll(shared_state3_in.get(),
+  yuvvideo_in->SetAll(shared_state3_in,
                       arbitrary_rect1,
                       arbitrary_rect2_inside_rect1,
                       arbitrary_rect1_inside_rect1,
@@ -430,24 +454,15 @@
                       arbitrary_resourceid1,
                       arbitrary_resourceid2,
                       arbitrary_resourceid3,
-                      arbitrary_resourceid4);
+                      arbitrary_resourceid4,
+                      arbitrary_color_space);
   scoped_ptr<DrawQuad> yuvvideo_cmp = yuvvideo_in->Copy(
       yuvvideo_in->shared_quad_state);
 
-  scoped_ptr<RenderPass> pass_in = RenderPass::Create();
-  pass_in->SetAll(arbitrary_id,
-                  arbitrary_rect1,
-                  arbitrary_rect2,
-                  arbitrary_matrix,
-                  arbitrary_bool1);
-
-  pass_in->shared_quad_state_list.push_back(shared_state1_in.Pass());
   pass_in->quad_list.push_back(checkerboard_in.PassAs<DrawQuad>());
   pass_in->quad_list.push_back(debugborder_in.PassAs<DrawQuad>());
   pass_in->quad_list.push_back(iosurface_in.PassAs<DrawQuad>());
   pass_in->quad_list.push_back(renderpass_in.PassAs<DrawQuad>());
-  pass_in->shared_quad_state_list.push_back(shared_state2_in.Pass());
-  pass_in->shared_quad_state_list.push_back(shared_state3_in.Pass());
   pass_in->quad_list.push_back(solidcolor_in.PassAs<DrawQuad>());
   pass_in->quad_list.push_back(streamvideo_in.PassAs<DrawQuad>());
   pass_in->quad_list.push_back(surface_in.PassAs<DrawQuad>());
@@ -455,20 +470,11 @@
   pass_in->quad_list.push_back(tile_in.PassAs<DrawQuad>());
   pass_in->quad_list.push_back(yuvvideo_in.PassAs<DrawQuad>());
 
-  scoped_ptr<RenderPass> pass_cmp = RenderPass::Create();
-  pass_cmp->SetAll(arbitrary_id,
-                   arbitrary_rect1,
-                   arbitrary_rect2,
-                   arbitrary_matrix,
-                   arbitrary_bool1);
 
-  pass_cmp->shared_quad_state_list.push_back(shared_state1_cmp.Pass());
   pass_cmp->quad_list.push_back(checkerboard_cmp.PassAs<DrawQuad>());
   pass_cmp->quad_list.push_back(debugborder_cmp.PassAs<DrawQuad>());
   pass_cmp->quad_list.push_back(iosurface_cmp.PassAs<DrawQuad>());
   pass_cmp->quad_list.push_back(renderpass_cmp.PassAs<DrawQuad>());
-  pass_cmp->shared_quad_state_list.push_back(shared_state2_cmp.Pass());
-  pass_cmp->shared_quad_state_list.push_back(shared_state3_cmp.Pass());
   pass_cmp->quad_list.push_back(solidcolor_cmp.PassAs<DrawQuad>());
   pass_cmp->quad_list.push_back(streamvideo_cmp.PassAs<DrawQuad>());
   pass_cmp->quad_list.push_back(surface_cmp.PassAs<DrawQuad>());
@@ -540,7 +546,7 @@
                   false);
 
   // The first SharedQuadState is used.
-  scoped_ptr<SharedQuadState> shared_state1_in = SharedQuadState::Create();
+  SharedQuadState* shared_state1_in = pass_in->CreateAndAppendSharedQuadState();
   shared_state1_in->SetAll(gfx::Transform(),
                            gfx::Size(1, 1),
                            gfx::Rect(),
@@ -550,7 +556,7 @@
                            SkXfermode::kSrcOver_Mode);
 
   quad = CheckerboardDrawQuad::Create();
-  quad->SetAll(shared_state1_in.get(),
+  quad->SetAll(shared_state1_in,
                gfx::Rect(10, 10),
                gfx::Rect(10, 10),
                gfx::Rect(10, 10),
@@ -559,7 +565,7 @@
   pass_in->quad_list.push_back(quad.PassAs<DrawQuad>());
 
   // The second and third SharedQuadStates are not used.
-  scoped_ptr<SharedQuadState> shared_state2_in = SharedQuadState::Create();
+  SharedQuadState* shared_state2_in = pass_in->CreateAndAppendSharedQuadState();
   shared_state2_in->SetAll(gfx::Transform(),
                            gfx::Size(2, 2),
                            gfx::Rect(),
@@ -568,7 +574,7 @@
                            1.f,
                            SkXfermode::kSrcOver_Mode);
 
-  scoped_ptr<SharedQuadState> shared_state3_in = SharedQuadState::Create();
+  SharedQuadState* shared_state3_in = pass_in->CreateAndAppendSharedQuadState();
   shared_state3_in->SetAll(gfx::Transform(),
                            gfx::Size(3, 3),
                            gfx::Rect(),
@@ -578,7 +584,7 @@
                            SkXfermode::kSrcOver_Mode);
 
   // The fourth SharedQuadState is used.
-  scoped_ptr<SharedQuadState> shared_state4_in = SharedQuadState::Create();
+  SharedQuadState* shared_state4_in = pass_in->CreateAndAppendSharedQuadState();
   shared_state4_in->SetAll(gfx::Transform(),
                            gfx::Size(4, 4),
                            gfx::Rect(),
@@ -588,7 +594,7 @@
                            SkXfermode::kSrcOver_Mode);
 
   quad = CheckerboardDrawQuad::Create();
-  quad->SetAll(shared_state4_in.get(),
+  quad->SetAll(shared_state4_in,
                gfx::Rect(10, 10),
                gfx::Rect(10, 10),
                gfx::Rect(10, 10),
@@ -597,7 +603,7 @@
   pass_in->quad_list.push_back(quad.PassAs<DrawQuad>());
 
   // The fifth is not used again.
-  scoped_ptr<SharedQuadState> shared_state5_in = SharedQuadState::Create();
+  SharedQuadState* shared_state5_in = pass_in->CreateAndAppendSharedQuadState();
   shared_state5_in->SetAll(gfx::Transform(),
                            gfx::Size(5, 5),
                            gfx::Rect(),
@@ -606,12 +612,6 @@
                            1.f,
                            SkXfermode::kSrcOver_Mode);
 
-  pass_in->shared_quad_state_list.push_back(shared_state1_in.Pass());
-  pass_in->shared_quad_state_list.push_back(shared_state2_in.Pass());
-  pass_in->shared_quad_state_list.push_back(shared_state3_in.Pass());
-  pass_in->shared_quad_state_list.push_back(shared_state4_in.Pass());
-  pass_in->shared_quad_state_list.push_back(shared_state5_in.Pass());
-
   // 5 SharedQuadStates go in.
   ASSERT_EQ(5u, pass_in->shared_quad_state_list.size());
   ASSERT_EQ(2u, pass_in->quad_list.size());
diff --git a/content/common/child_process_host_impl.cc b/content/common/child_process_host_impl.cc
index 6d6060e..488cdb0 100644
--- a/content/common/child_process_host_impl.cc
+++ b/content/common/child_process_host_impl.cc
@@ -308,6 +308,7 @@
     uint32 width,
     uint32 height,
     uint32 internalformat,
+    uint32 usage,
     gfx::GpuMemoryBufferHandle* handle) {
   handle->type = gfx::SHARED_MEMORY_BUFFER;
   AllocateSharedMemory(
diff --git a/content/common/child_process_host_impl.h b/content/common/child_process_host_impl.h
index 1daa5d5..4ac660d 100644
--- a/content/common/child_process_host_impl.h
+++ b/content/common/child_process_host_impl.h
@@ -84,6 +84,7 @@
   void OnAllocateGpuMemoryBuffer(uint32 width,
                                  uint32 height,
                                  uint32 internalformat,
+                                 uint32 usage,
                                  gfx::GpuMemoryBufferHandle* handle);
 
   ChildProcessHostDelegate* delegate_;
diff --git a/content/common/child_process_messages.h b/content/common/child_process_messages.h
index 8587f98..ecbd201 100644
--- a/content/common/child_process_messages.h
+++ b/content/common/child_process_messages.h
@@ -181,8 +181,9 @@
 #endif
 
 // Asks the browser to create a gpu memory buffer.
-IPC_SYNC_MESSAGE_CONTROL3_1(ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer,
+IPC_SYNC_MESSAGE_CONTROL4_1(ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer,
                             uint32 /* width */,
                             uint32 /* height */,
                             uint32 /* internalformat */,
+                            uint32 /* usage */,
                             gfx::GpuMemoryBufferHandle)
diff --git a/content/common/child_process_sandbox_support_impl_linux.cc b/content/common/child_process_sandbox_support_impl_linux.cc
index a810e5c..c0edcfc 100644
--- a/content/common/child_process_sandbox_support_impl_linux.cc
+++ b/content/common/child_process_sandbox_support_impl_linux.cc
@@ -14,6 +14,7 @@
 #include "base/posix/unix_domain_socket_linux.h"
 #include "base/sys_byteorder.h"
 #include "content/common/sandbox_linux/sandbox_linux.h"
+#include "content/common/zygote_commands_linux.h"
 #include "third_party/WebKit/public/platform/linux/WebFontFamily.h"
 #include "third_party/WebKit/public/platform/linux/WebFontRenderStyle.h"
 
@@ -181,4 +182,11 @@
   return true;
 }
 
+bool SendZygoteChildPing(int fd) {
+  return UnixDomainSocket::SendMsg(fd,
+                                   kZygoteChildPingMessage,
+                                   sizeof(kZygoteChildPingMessage),
+                                   std::vector<int>());
+}
+
 }  // namespace content
diff --git a/content/common/content_message_generator.h b/content/common/content_message_generator.h
index ca2dda1..07943e8 100644
--- a/content/common/content_message_generator.h
+++ b/content/common/content_message_generator.h
@@ -60,6 +60,7 @@
 #include "content/common/worker_messages.h"
 
 #if defined(OS_ANDROID)
+#include "content/common/gin_java_bridge_messages.h"
 #include "content/common/media/cdm_messages.h"
 #include "content/common/media/media_player_messages_android.h"
 #endif  // defined(OS_ANDROID)
diff --git a/content/common/cursors/webcursor_win.cc b/content/common/cursors/webcursor_win.cc
deleted file mode 100644
index d034c57..0000000
--- a/content/common/cursors/webcursor_win.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/logging.h"
-#include "base/pickle.h"
-#include "content/common/cursors/webcursor.h"
-#include "grit/ui_unscaled_resources.h"
-#include "third_party/WebKit/public/platform/WebCursorInfo.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/icon_util.h"
-
-using blink::WebCursorInfo;
-
-static LPCWSTR ToCursorID(WebCursorInfo::Type type) {
-  switch (type) {
-    case WebCursorInfo::TypePointer:
-      return IDC_ARROW;
-    case WebCursorInfo::TypeCross:
-      return IDC_CROSS;
-    case WebCursorInfo::TypeHand:
-      return IDC_HAND;
-    case WebCursorInfo::TypeIBeam:
-      return IDC_IBEAM;
-    case WebCursorInfo::TypeWait:
-      return IDC_WAIT;
-    case WebCursorInfo::TypeHelp:
-      return IDC_HELP;
-    case WebCursorInfo::TypeEastResize:
-      return IDC_SIZEWE;
-    case WebCursorInfo::TypeNorthResize:
-      return IDC_SIZENS;
-    case WebCursorInfo::TypeNorthEastResize:
-      return IDC_SIZENESW;
-    case WebCursorInfo::TypeNorthWestResize:
-      return IDC_SIZENWSE;
-    case WebCursorInfo::TypeSouthResize:
-      return IDC_SIZENS;
-    case WebCursorInfo::TypeSouthEastResize:
-      return IDC_SIZENWSE;
-    case WebCursorInfo::TypeSouthWestResize:
-      return IDC_SIZENESW;
-    case WebCursorInfo::TypeWestResize:
-      return IDC_SIZEWE;
-    case WebCursorInfo::TypeNorthSouthResize:
-      return IDC_SIZENS;
-    case WebCursorInfo::TypeEastWestResize:
-      return IDC_SIZEWE;
-    case WebCursorInfo::TypeNorthEastSouthWestResize:
-      return IDC_SIZENESW;
-    case WebCursorInfo::TypeNorthWestSouthEastResize:
-      return IDC_SIZENWSE;
-    case WebCursorInfo::TypeColumnResize:
-      return MAKEINTRESOURCE(IDC_COLRESIZE);
-    case WebCursorInfo::TypeRowResize:
-      return MAKEINTRESOURCE(IDC_ROWRESIZE);
-    case WebCursorInfo::TypeMiddlePanning:
-      return MAKEINTRESOURCE(IDC_PAN_MIDDLE);
-    case WebCursorInfo::TypeEastPanning:
-      return MAKEINTRESOURCE(IDC_PAN_EAST);
-    case WebCursorInfo::TypeNorthPanning:
-      return MAKEINTRESOURCE(IDC_PAN_NORTH);
-    case WebCursorInfo::TypeNorthEastPanning:
-      return MAKEINTRESOURCE(IDC_PAN_NORTH_EAST);
-    case WebCursorInfo::TypeNorthWestPanning:
-      return MAKEINTRESOURCE(IDC_PAN_NORTH_WEST);
-    case WebCursorInfo::TypeSouthPanning:
-      return MAKEINTRESOURCE(IDC_PAN_SOUTH);
-    case WebCursorInfo::TypeSouthEastPanning:
-      return MAKEINTRESOURCE(IDC_PAN_SOUTH_EAST);
-    case WebCursorInfo::TypeSouthWestPanning:
-      return MAKEINTRESOURCE(IDC_PAN_SOUTH_WEST);
-    case WebCursorInfo::TypeWestPanning:
-      return MAKEINTRESOURCE(IDC_PAN_WEST);
-    case WebCursorInfo::TypeMove:
-      return IDC_SIZEALL;
-    case WebCursorInfo::TypeVerticalText:
-      return MAKEINTRESOURCE(IDC_VERTICALTEXT);
-    case WebCursorInfo::TypeCell:
-      return MAKEINTRESOURCE(IDC_CELL);
-    case WebCursorInfo::TypeContextMenu:
-      return MAKEINTRESOURCE(IDC_ARROW);
-    case WebCursorInfo::TypeAlias:
-      return MAKEINTRESOURCE(IDC_ALIAS);
-    case WebCursorInfo::TypeProgress:
-      return IDC_APPSTARTING;
-    case WebCursorInfo::TypeNoDrop:
-      return IDC_NO;
-    case WebCursorInfo::TypeCopy:
-      return MAKEINTRESOURCE(IDC_COPYCUR);
-    case WebCursorInfo::TypeNone:
-      return MAKEINTRESOURCE(IDC_CURSOR_NONE);
-    case WebCursorInfo::TypeNotAllowed:
-      return IDC_NO;
-    case WebCursorInfo::TypeZoomIn:
-      return MAKEINTRESOURCE(IDC_ZOOMIN);
-    case WebCursorInfo::TypeZoomOut:
-      return MAKEINTRESOURCE(IDC_ZOOMOUT);
-    case WebCursorInfo::TypeGrab:
-      return MAKEINTRESOURCE(IDC_HAND_GRAB);
-    case WebCursorInfo::TypeGrabbing:
-      return MAKEINTRESOURCE(IDC_HAND_GRABBING);
-  }
-  NOTREACHED();
-  return NULL;
-}
-
-static bool IsSystemCursorID(LPCWSTR cursor_id) {
-  return cursor_id >= IDC_ARROW;  // See WinUser.h
-}
-
-namespace content {
-
-HCURSOR WebCursor::GetCursor(HINSTANCE module_handle){
-  if (!IsCustom()) {
-    const wchar_t* cursor_id =
-        ToCursorID(static_cast<WebCursorInfo::Type>(type_));
-
-    if (IsSystemCursorID(cursor_id))
-      module_handle = NULL;
-
-    return LoadCursor(module_handle, cursor_id);
-  }
-
-  if (custom_cursor_) {
-    DCHECK(external_cursor_ == NULL);
-    return custom_cursor_;
-  }
-
-  if (external_cursor_)
-    return external_cursor_;
-
-  custom_cursor_ =
-      IconUtil::CreateCursorFromDIB(
-          custom_size_,
-          hotspot_,
-          !custom_data_.empty() ? &custom_data_[0] : NULL,
-          custom_data_.size());
-  return custom_cursor_;
-}
-
-gfx::NativeCursor WebCursor::GetNativeCursor() {
-  return GetCursor(NULL);
-}
-
-void WebCursor::InitPlatformData() {
-  custom_cursor_ = NULL;
-}
-
-bool WebCursor::SerializePlatformData(Pickle* pickle) const {
-  // There are some issues with converting certain HCURSORS to bitmaps. The
-  // HCURSOR being a user object can be marshaled as is.
-  // HCURSORs are always 32 bits on Windows, even on 64 bit systems.
-  return pickle->WriteUInt32(reinterpret_cast<uint32>(external_cursor_));
-}
-
-bool WebCursor::DeserializePlatformData(PickleIterator* iter) {
-  return iter->ReadUInt32(reinterpret_cast<uint32*>(&external_cursor_));
-}
-
-bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
-  if (!IsCustom())
-    return true;
-
-  return (external_cursor_ == other.external_cursor_);
-}
-
-void WebCursor::CopyPlatformData(const WebCursor& other) {
-  external_cursor_ = other.external_cursor_;
-  // The custom_cursor_ member will be initialized to a HCURSOR the next time
-  // the GetCursor member function is invoked on this WebCursor instance. The
-  // cursor is created using the data in the custom_data_ vector.
-  custom_cursor_ = NULL;
-}
-
-void WebCursor::CleanupPlatformData() {
-  external_cursor_ = NULL;
-
-  if (custom_cursor_) {
-    DestroyIcon(custom_cursor_);
-    custom_cursor_ = NULL;
-  }
-}
-
-}  // namespace content
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index c56553a..38f4e19 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -56,7 +56,6 @@
   IPC_STRUCT_TRAITS_MEMBER(misspelled_word)
   IPC_STRUCT_TRAITS_MEMBER(misspelling_hash)
   IPC_STRUCT_TRAITS_MEMBER(dictionary_suggestions)
-  IPC_STRUCT_TRAITS_MEMBER(speech_input_enabled)
   IPC_STRUCT_TRAITS_MEMBER(spellcheck_enabled)
   IPC_STRUCT_TRAITS_MEMBER(is_editable)
   IPC_STRUCT_TRAITS_MEMBER(writing_direction_default)
@@ -429,11 +428,19 @@
 IPC_MESSAGE_ROUTED1(FrameHostMsg_DidFinishLoad,
                     GURL /* validated_url */)
 
+// Sent when after the onload handler has been invoked for the document
+// in this frame. Sent for top-level frames.
+IPC_MESSAGE_ROUTED0(FrameHostMsg_DocumentOnLoadCompleted)
+
 // Notifies that the initial empty document of a view has been accessed.
 // After this, it is no longer safe to show a pending navigation's URL without
 // making a URL spoof possible.
 IPC_MESSAGE_ROUTED0(FrameHostMsg_DidAccessInitialDocument)
 
+// Sent when the frame sets its opener to null, disowning it for the lifetime of
+// the window. Sent for top-level frames.
+IPC_MESSAGE_ROUTED0(FrameHostMsg_DidDisownOpener)
+
 // Following message is used to communicate the values received by the
 // callback binding the JS to Cpp.
 // An instance of browser that has an automation host listening to it can
@@ -573,3 +580,12 @@
 IPC_MESSAGE_ROUTED2(FrameHostMsg_SetSelectedColorInColorChooser,
                     int /* id */,
                     SkColor /* color */)
+
+// Notifies the browser that media has started/stopped playing.
+IPC_MESSAGE_ROUTED3(FrameHostMsg_MediaPlayingNotification,
+                    int64 /* player_cookie, distinguishes instances */,
+                    bool /* has_video */,
+                    bool /* has_audio */)
+
+IPC_MESSAGE_ROUTED1(FrameHostMsg_MediaPausedNotification,
+                    int64 /* player_cookie, distinguishes instances */)
diff --git a/content/common/gamepad_messages.h b/content/common/gamepad_messages.h
index 0532b9c..63d6556 100644
--- a/content/common/gamepad_messages.h
+++ b/content/common/gamepad_messages.h
@@ -1,16 +1,26 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 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.
 
 // Multiply-included message file, no include guard.
 
 #include "base/memory/shared_memory.h"
+#include "content/common/gamepad_param_traits.h"
 #include "ipc/ipc_message_macros.h"
 #include "ipc/ipc_param_traits.h"
 #include "ipc/ipc_platform_file.h"
+#include "third_party/WebKit/public/platform/WebGamepad.h"
 
 #define IPC_MESSAGE_START GamepadMsgStart
 
+IPC_MESSAGE_CONTROL2(GamepadMsg_GamepadConnected,
+                     int /* index */,
+                     blink::WebGamepad)
+
+IPC_MESSAGE_CONTROL2(GamepadMsg_GamepadDisconnected,
+                     int /* index */,
+                     blink::WebGamepad)
+
 // Messages sent from the renderer to the browser.
 
 // Asks the browser process to start polling, and return a shared memory
diff --git a/content/common/gamepad_param_traits.cc b/content/common/gamepad_param_traits.cc
new file mode 100644
index 0000000..356d875
--- /dev/null
+++ b/content/common/gamepad_param_traits.cc
@@ -0,0 +1,79 @@
+// 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.
+
+#include "content/common/gamepad_param_traits.h"
+
+#include "base/pickle.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "ipc/ipc_message_utils.h"
+#include "third_party/WebKit/public/platform/WebGamepad.h"
+
+using blink::WebGamepad;
+
+namespace {
+
+void LogWebUCharString(
+    const blink::WebUChar web_string[],
+    const size_t array_size,
+    std::string* log) {
+  base::string16 utf16;
+  utf16.reserve(array_size);
+  for (size_t i = 0; i < array_size && web_string[i]; ++i) {
+    utf16[i] = web_string[i];
+  }
+  log->append(base::UTF16ToUTF8(utf16));
+}
+
+}
+
+namespace IPC {
+
+void ParamTraits<WebGamepad>::Write(
+    Message* m,
+    const WebGamepad& p) {
+  m->WriteData(reinterpret_cast<const char*>(&p), sizeof(WebGamepad));
+}
+
+bool ParamTraits<WebGamepad>::Read(
+    const Message* m,
+    PickleIterator* iter,
+    WebGamepad* p) {
+  int length;
+  const char* data;
+  if (!m->ReadData(iter, &data, &length) || length != sizeof(WebGamepad))
+    return false;
+  memcpy(p, data, sizeof(WebGamepad));
+
+  return true;
+}
+
+void ParamTraits<WebGamepad>::Log(
+    const WebGamepad& p,
+    std::string* l) {
+  l->append("WebGamepad(");
+  LogParam(p.connected, l);
+  LogWebUCharString(p.id, WebGamepad::idLengthCap, l);
+  l->append(",");
+  LogWebUCharString(p.mapping, WebGamepad::mappingLengthCap, l);
+  l->append(",");
+  LogParam(p.timestamp, l);
+  l->append(",");
+  LogParam(p.axesLength, l);
+  l->append(", [");
+  for (size_t i = 0; i < arraysize(p.axes); ++i) {
+    l->append(base::StringPrintf("%f%s", p.axes[i],
+        i < (arraysize(p.axes) - 1) ? ", " : "], "));
+  }
+  LogParam(p.buttonsLength, l);
+  l->append(", [");
+  for (size_t i = 0; i < arraysize(p.buttons); ++i) {
+    l->append(base::StringPrintf("(%u, %f)%s",
+        p.buttons[i].pressed, p.buttons[i].value,
+        i < (arraysize(p.buttons) - 1) ? ", " : "], "));
+  }
+  l->append(")");
+}
+
+} // namespace IPC
diff --git a/content/common/gamepad_param_traits.h b/content/common/gamepad_param_traits.h
new file mode 100644
index 0000000..aa9e440
--- /dev/null
+++ b/content/common/gamepad_param_traits.h
@@ -0,0 +1,32 @@
+// 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.
+
+#ifndef CONTENT_COMMON_GAMEPAD_PARAM_TRAITS_H_
+#define CONTENT_COMMON_GAMEPAD_PARAM_TRAITS_H_
+
+#include <string>
+
+#include "ipc/ipc_param_traits.h"
+
+class PickleIterator;
+
+namespace blink { class WebGamepad; }
+
+namespace IPC {
+
+class Message;
+
+template <>
+struct ParamTraits<blink::WebGamepad> {
+  typedef blink::WebGamepad param_type;
+  static void Write(Message* m, const blink::WebGamepad& p);
+  static bool Read(const Message* m,
+                   PickleIterator* iter,
+                   blink::WebGamepad* p);
+  static void Log(const blink::WebGamepad& p, std::string* l);
+};
+
+} // namespace IPC
+
+#endif
diff --git a/content/common/gin_java_bridge_messages.h b/content/common/gin_java_bridge_messages.h
new file mode 100644
index 0000000..f9525b1
--- /dev/null
+++ b/content/common/gin_java_bridge_messages.h
@@ -0,0 +1,68 @@
+// 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.
+
+// IPC messages for injected Java objects (Gin-based implementation).
+
+// Multiply-included message file, hence no include guard.
+
+#include "base/basictypes.h"
+#include "content/common/content_export.h"
+#include "ipc/ipc_message_macros.h"
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
+#define IPC_MESSAGE_START GinJavaBridgeMsgStart
+
+// Messages for handling Java objects injected into JavaScript -----------------
+
+// Sent from browser to renderer to add a Java object with the given name.
+// Object IDs are generated on the browser side.
+IPC_MESSAGE_ROUTED2(GinJavaBridgeMsg_AddNamedObject,
+                    std::string /* name */,
+                    int32 /* object_id */)
+
+// Sent from browser to renderer to remove a Java object with the given name.
+IPC_MESSAGE_ROUTED1(GinJavaBridgeMsg_RemoveNamedObject,
+                    std::string /* name */)
+
+// Sent from renderer to browser to get information about methods of
+// the given object. The query will only succeed if inspection of injected
+// objects is enabled on the browser side.
+IPC_SYNC_MESSAGE_ROUTED1_1(GinJavaBridgeHostMsg_GetMethods,
+                           int32 /* object_id */,
+                           std::set<std::string> /* returned_method_names */)
+
+// Sent from renderer to browser to find out, if an object has a method with
+// the given name.
+IPC_SYNC_MESSAGE_ROUTED2_1(GinJavaBridgeHostMsg_HasMethod,
+                           int32 /* object_id */,
+                           std::string /* method_name */,
+                           bool /* result */)
+
+// Sent from renderer to browser to invoke a method. Method arguments
+// are chained into |arguments| list. base::ListValue is used for |result| as
+// a container to work around immutability of base::Value.
+// Empty result list indicates that an error has happened on the Java side
+// (either bridge-induced error or an unhandled Java exception) and an exception
+// must be thrown into JavaScript.
+// Some special value types that are not supported by base::Value are encoded
+// as BinaryValues via GinJavaBridgeValue.
+IPC_SYNC_MESSAGE_ROUTED3_1(GinJavaBridgeHostMsg_InvokeMethod,
+                           int32 /* object_id */,
+                           std::string /* method_name */,
+                           base::ListValue /* arguments */,
+                           base::ListValue /* result */)
+
+// Sent from renderer to browser in two cases:
+//
+//  1. (Main usage) To inform that the JS wrapper of the object has
+//     been completely dereferenced and garbage-collected.
+//
+//  2. To notify the browser that wrapper creation has failed.  The browser side
+//     assumes optimistically that every time an object is returned from a
+//     method, the corresponding wrapper object will be successfully created on
+//     the renderer side. Sending of this message informs the browser whether
+//     this expectation has failed.
+IPC_MESSAGE_ROUTED1(GinJavaBridgeHostMsg_ObjectWrapperDeleted,
+                    int32 /* object_id */)
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc
index b24e7c6..59153d6 100644
--- a/content/common/gpu/client/command_buffer_proxy_impl.cc
+++ b/content/common/gpu/client/command_buffer_proxy_impl.cc
@@ -299,6 +299,7 @@
     size_t width,
     size_t height,
     unsigned internalformat,
+    unsigned usage,
     int32* id) {
   *id = -1;
 
@@ -309,9 +310,8 @@
   DCHECK(gpu_memory_buffers_.find(new_id) == gpu_memory_buffers_.end());
 
   scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer(
-      channel_->factory()->AllocateGpuMemoryBuffer(width,
-                                                   height,
-                                                   internalformat));
+      channel_->factory()->AllocateGpuMemoryBuffer(
+          width, height, internalformat, usage));
   if (!gpu_memory_buffer)
     return NULL;
 
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.h b/content/common/gpu/client/command_buffer_proxy_impl.h
index c1227ae..9f2ff4f 100644
--- a/content/common/gpu/client/command_buffer_proxy_impl.h
+++ b/content/common/gpu/client/command_buffer_proxy_impl.h
@@ -15,9 +15,9 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
+#include "gpu/command_buffer/client/gpu_control.h"
 #include "gpu/command_buffer/common/command_buffer.h"
 #include "gpu/command_buffer/common/command_buffer_shared.h"
-#include "gpu/command_buffer/common/gpu_control.h"
 #include "gpu/command_buffer/common/gpu_memory_allocation.h"
 #include "ipc/ipc_listener.h"
 #include "ui/events/latency_info.h"
@@ -101,11 +101,11 @@
 
   // gpu::GpuControl implementation:
   virtual gpu::Capabilities GetCapabilities() OVERRIDE;
-  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(
-      size_t width,
-      size_t height,
-      unsigned internalformat,
-      int32* id) OVERRIDE;
+  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(size_t width,
+                                                      size_t height,
+                                                      unsigned internalformat,
+                                                      unsigned usage,
+                                                      int32* id) OVERRIDE;
   virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
   virtual uint32 InsertSyncPoint() OVERRIDE;
   virtual void SignalSyncPoint(uint32 sync_point,
diff --git a/content/common/gpu/client/gl_helper_unittest.cc b/content/common/gpu/client/gl_helper_unittest.cc
index 9e7af8c..acb1f59 100644
--- a/content/common/gpu/client/gl_helper_unittest.cc
+++ b/content/common/gpu/client/gl_helper_unittest.cc
@@ -27,7 +27,6 @@
 #include "content/common/gpu/client/gl_helper_scaling.h"
 #include "content/public/test/unittest_test_suite.h"
 #include "content/test/content_test_suite.h"
-#include "gpu/config/gpu_util.h"
 #include "media/base/video_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -1667,7 +1666,6 @@
 #if defined(OS_MACOSX)
   base::mac::ScopedNSAutoreleasePool pool;
 #endif
-  gpu::ApplyGpuDriverBugWorkarounds(CommandLine::ForCurrentProcess());
 
   content::UnitTestTestSuite runner(suite);
   base::MessageLoop message_loop;
diff --git a/content/common/gpu/client/gpu_channel_host.h b/content/common/gpu/client/gpu_channel_host.h
index 7b95879..4f5b74f 100644
--- a/content/common/gpu/client/gpu_channel_host.h
+++ b/content/common/gpu/client/gpu_channel_host.h
@@ -80,7 +80,8 @@
   virtual scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer(
       size_t width,
       size_t height,
-      unsigned internalformat) = 0;
+      unsigned internalformat,
+      unsigned usage) = 0;
 };
 
 // Encapsulates an IPC channel between the client and one GPU process.
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl.cc b/content/common/gpu/client/gpu_memory_buffer_impl.cc
index 77a846f..b3cd983 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl.cc
@@ -8,7 +8,7 @@
 
 namespace content {
 
-GpuMemoryBufferImpl::GpuMemoryBufferImpl(gfx::Size size,
+GpuMemoryBufferImpl::GpuMemoryBufferImpl(const gfx::Size& size,
                                          unsigned internalformat)
     : size_(size), internalformat_(internalformat), mapped_(false) {
   DCHECK(IsFormatValid(internalformat));
@@ -28,6 +28,17 @@
 }
 
 // static
+bool GpuMemoryBufferImpl::IsUsageValid(unsigned usage) {
+  switch (usage) {
+    case GL_IMAGE_MAP_CHROMIUM:
+    case GL_IMAGE_SCANOUT_CHROMIUM:
+      return true;
+    default:
+      return false;
+  }
+}
+
+// static
 size_t GpuMemoryBufferImpl::BytesPerPixel(unsigned internalformat) {
   switch (internalformat) {
     case GL_BGRA8_EXT:
@@ -41,8 +52,4 @@
 
 bool GpuMemoryBufferImpl::IsMapped() const { return mapped_; }
 
-uint32 GpuMemoryBufferImpl::GetStride() const {
-  return size_.width() * BytesPerPixel(internalformat_);
-}
-
 }  // namespace content
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl.h b/content/common/gpu/client/gpu_memory_buffer_impl.h
index ee85f0f..af72599 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl.h
+++ b/content/common/gpu/client/gpu_memory_buffer_impl.h
@@ -14,25 +14,48 @@
 // Provides common implementation of a GPU memory buffer.
 class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
  public:
-  static scoped_ptr<GpuMemoryBufferImpl> Create(
-      gfx::GpuMemoryBufferHandle handle,
-      gfx::Size size,
-      unsigned internalformat);
-
   virtual ~GpuMemoryBufferImpl();
 
+  // Creates a GPU memory buffer instance with |size| and |internalformat| for
+  // |usage|.
+  static scoped_ptr<GpuMemoryBufferImpl> Create(const gfx::Size& size,
+                                                unsigned internalformat,
+                                                unsigned usage);
+
+  // Allocates a GPU memory buffer with |size| and |internalformat| for |usage|
+  // by |child_process|. The |handle| returned can be used by the
+  // |child_process| to create an instance of this class.
+  static void AllocateForChildProcess(const gfx::Size& size,
+                                      unsigned internalformat,
+                                      unsigned usage,
+                                      base::ProcessHandle child_process,
+                                      gfx::GpuMemoryBufferHandle* handle);
+
+  // Creates an instance from the given |handle|. |size| and |internalformat|
+  // should match what was used to allocate the |handle|.
+  static scoped_ptr<GpuMemoryBufferImpl> CreateFromHandle(
+      gfx::GpuMemoryBufferHandle handle,
+      const gfx::Size& size,
+      unsigned internalformat);
+
+  // Returns true if |internalformat| is a format recognized by this base class.
   static bool IsFormatValid(unsigned internalformat);
+
+  // Returns true if |usage| is recognized by this base class.
+  static bool IsUsageValid(unsigned usage);
+
+  // Returns the number of bytes per pixel that must be used by an
+  // implementation when using |internalformat|.
   static size_t BytesPerPixel(unsigned internalformat);
 
   // Overridden from gfx::GpuMemoryBuffer:
   virtual bool IsMapped() const OVERRIDE;
-  virtual uint32 GetStride() const OVERRIDE;
 
  protected:
-  GpuMemoryBufferImpl(gfx::Size size, unsigned internalformat);
+  GpuMemoryBufferImpl(const gfx::Size& size, unsigned internalformat);
 
   const gfx::Size size_;
-  unsigned internalformat_;
+  const unsigned internalformat_;
   bool mapped_;
 
   DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImpl);
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_android.cc b/content/common/gpu/client/gpu_memory_buffer_impl_android.cc
index a7f694f..0e31dc9 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_android.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_android.cc
@@ -9,15 +9,51 @@
 
 namespace content {
 
+// static
 scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::Create(
+    const gfx::Size& size,
+    unsigned internalformat,
+    unsigned usage) {
+  if (GpuMemoryBufferImplShm::IsConfigurationSupported(
+          size, internalformat, usage)) {
+    scoped_ptr<GpuMemoryBufferImplShm> buffer(
+        new GpuMemoryBufferImplShm(size, internalformat));
+    if (!buffer->Initialize())
+      return scoped_ptr<GpuMemoryBufferImpl>();
+
+    return buffer.PassAs<GpuMemoryBufferImpl>();
+  }
+
+  return scoped_ptr<GpuMemoryBufferImpl>();
+}
+
+// static
+void GpuMemoryBufferImpl::AllocateForChildProcess(
+    const gfx::Size& size,
+    unsigned internalformat,
+    unsigned usage,
+    base::ProcessHandle child_process,
+    gfx::GpuMemoryBufferHandle* handle) {
+  if (GpuMemoryBufferImplShm::IsConfigurationSupported(
+          size, internalformat, usage)) {
+    GpuMemoryBufferImplShm::AllocateSharedMemoryForChildProcess(
+        size, internalformat, child_process, handle);
+    return;
+  }
+
+  handle->type = gfx::EMPTY_BUFFER;
+}
+
+// static
+scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::CreateFromHandle(
     gfx::GpuMemoryBufferHandle handle,
-    gfx::Size size,
+    const gfx::Size& size,
     unsigned internalformat) {
   switch (handle.type) {
     case gfx::SHARED_MEMORY_BUFFER: {
       scoped_ptr<GpuMemoryBufferImplShm> buffer(
           new GpuMemoryBufferImplShm(size, internalformat));
-      if (!buffer->Initialize(handle))
+      if (!buffer->InitializeFromHandle(handle))
         return scoped_ptr<GpuMemoryBufferImpl>();
 
       return buffer.PassAs<GpuMemoryBufferImpl>();
@@ -25,7 +61,7 @@
     case gfx::SURFACE_TEXTURE_BUFFER: {
       scoped_ptr<GpuMemoryBufferImplSurfaceTexture> buffer(
           new GpuMemoryBufferImplSurfaceTexture(size, internalformat));
-      if (!buffer->Initialize(handle))
+      if (!buffer->InitializeFromHandle(handle))
         return scoped_ptr<GpuMemoryBufferImpl>();
 
       return buffer.PassAs<GpuMemoryBufferImpl>();
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc
index 299bd56..62732a1 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.cc
@@ -11,7 +11,7 @@
 namespace content {
 
 GpuMemoryBufferImplIOSurface::GpuMemoryBufferImplIOSurface(
-    gfx::Size size,
+    const gfx::Size& size,
     unsigned internalformat)
     : GpuMemoryBufferImpl(size, internalformat),
       io_surface_support_(IOSurfaceSupport::Initialize()) {
@@ -31,6 +31,23 @@
 }
 
 // static
+bool GpuMemoryBufferImplIOSurface::IsUsageSupported(unsigned usage) {
+  switch (usage) {
+    case GL_IMAGE_MAP_CHROMIUM:
+      return true;
+    default:
+      return false;
+  }
+}
+
+// static
+bool GpuMemoryBufferImplIOSurface::IsConfigurationSupported(
+    unsigned internalformat,
+    unsigned usage) {
+  return IsFormatSupported(internalformat) && IsUsageSupported(usage);
+}
+
+// static
 uint32 GpuMemoryBufferImplIOSurface::PixelFormat(unsigned internalformat) {
   switch (internalformat) {
     case GL_BGRA8_EXT:
@@ -41,8 +58,9 @@
   }
 }
 
-bool GpuMemoryBufferImplIOSurface::Initialize(
+bool GpuMemoryBufferImplIOSurface::InitializeFromHandle(
     gfx::GpuMemoryBufferHandle handle) {
+  DCHECK(IsFormatSupported(internalformat_));
   io_surface_.reset(io_surface_support_->IOSurfaceLookup(handle.io_surface_id));
   if (!io_surface_) {
     VLOG(1) << "IOSurface lookup failed";
@@ -52,7 +70,7 @@
   return true;
 }
 
-void* GpuMemoryBufferImplIOSurface::Map(AccessMode mode) {
+void* GpuMemoryBufferImplIOSurface::Map() {
   DCHECK(!mapped_);
   io_surface_support_->IOSurfaceLock(io_surface_, 0, NULL);
   mapped_ = true;
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h
index de5c1fd..9f552bc 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h
@@ -12,20 +12,21 @@
 
 namespace content {
 
-// Provides implementation of a GPU memory buffer based
-// on an IO surface handle.
+// Implementation of GPU memory buffer based on IO surfaces.
 class GpuMemoryBufferImplIOSurface : public GpuMemoryBufferImpl {
  public:
-  GpuMemoryBufferImplIOSurface(gfx::Size size, unsigned internalformat);
+  GpuMemoryBufferImplIOSurface(const gfx::Size& size, unsigned internalformat);
   virtual ~GpuMemoryBufferImplIOSurface();
 
   static bool IsFormatSupported(unsigned internalformat);
+  static bool IsUsageSupported(unsigned usage);
+  static bool IsConfigurationSupported(unsigned internalformat, unsigned usage);
   static uint32 PixelFormat(unsigned internalformat);
 
-  bool Initialize(gfx::GpuMemoryBufferHandle handle);
+  bool InitializeFromHandle(gfx::GpuMemoryBufferHandle handle);
 
   // Overridden from gfx::GpuMemoryBuffer:
-  virtual void* Map(AccessMode mode) OVERRIDE;
+  virtual void* Map() OVERRIDE;
   virtual void Unmap() OVERRIDE;
   virtual uint32 GetStride() const OVERRIDE;
   virtual gfx::GpuMemoryBufferHandle GetHandle() const OVERRIDE;
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_linux.cc b/content/common/gpu/client/gpu_memory_buffer_impl_linux.cc
index ffd4e38..8da027b 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_linux.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_linux.cc
@@ -8,15 +8,51 @@
 
 namespace content {
 
+// static
 scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::Create(
+    const gfx::Size& size,
+    unsigned internalformat,
+    unsigned usage) {
+  if (GpuMemoryBufferImplShm::IsConfigurationSupported(
+          size, internalformat, usage)) {
+    scoped_ptr<GpuMemoryBufferImplShm> buffer(
+        new GpuMemoryBufferImplShm(size, internalformat));
+    if (!buffer->Initialize())
+      return scoped_ptr<GpuMemoryBufferImpl>();
+
+    return buffer.PassAs<GpuMemoryBufferImpl>();
+  }
+
+  return scoped_ptr<GpuMemoryBufferImpl>();
+}
+
+// static
+void GpuMemoryBufferImpl::AllocateForChildProcess(
+    const gfx::Size& size,
+    unsigned internalformat,
+    unsigned usage,
+    base::ProcessHandle child_process,
+    gfx::GpuMemoryBufferHandle* handle) {
+  if (GpuMemoryBufferImplShm::IsConfigurationSupported(
+          size, internalformat, usage)) {
+    GpuMemoryBufferImplShm::AllocateSharedMemoryForChildProcess(
+        size, internalformat, child_process, handle);
+    return;
+  }
+
+  handle->type = gfx::EMPTY_BUFFER;
+}
+
+// static
+scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::CreateFromHandle(
     gfx::GpuMemoryBufferHandle handle,
-    gfx::Size size,
+    const gfx::Size& size,
     unsigned internalformat) {
   switch (handle.type) {
     case gfx::SHARED_MEMORY_BUFFER: {
       scoped_ptr<GpuMemoryBufferImplShm> buffer(
           new GpuMemoryBufferImplShm(size, internalformat));
-      if (!buffer->Initialize(handle))
+      if (!buffer->InitializeFromHandle(handle))
         return scoped_ptr<GpuMemoryBufferImpl>();
 
       return buffer.PassAs<GpuMemoryBufferImpl>();
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_mac.cc b/content/common/gpu/client/gpu_memory_buffer_impl_mac.cc
index 1c8e552..35831b5 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_mac.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_mac.cc
@@ -9,15 +9,51 @@
 
 namespace content {
 
+// static
 scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::Create(
+    const gfx::Size& size,
+    unsigned internalformat,
+    unsigned usage) {
+  if (GpuMemoryBufferImplShm::IsConfigurationSupported(
+          size, internalformat, usage)) {
+    scoped_ptr<GpuMemoryBufferImplShm> buffer(
+        new GpuMemoryBufferImplShm(size, internalformat));
+    if (!buffer->Initialize())
+      return scoped_ptr<GpuMemoryBufferImpl>();
+
+    return buffer.PassAs<GpuMemoryBufferImpl>();
+  }
+
+  return scoped_ptr<GpuMemoryBufferImpl>();
+}
+
+// static
+void GpuMemoryBufferImpl::AllocateForChildProcess(
+    const gfx::Size& size,
+    unsigned internalformat,
+    unsigned usage,
+    base::ProcessHandle child_process,
+    gfx::GpuMemoryBufferHandle* handle) {
+  if (GpuMemoryBufferImplShm::IsConfigurationSupported(
+          size, internalformat, usage)) {
+    GpuMemoryBufferImplShm::AllocateSharedMemoryForChildProcess(
+        size, internalformat, child_process, handle);
+    return;
+  }
+
+  handle->type = gfx::EMPTY_BUFFER;
+}
+
+// static
+scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::CreateFromHandle(
     gfx::GpuMemoryBufferHandle handle,
-    gfx::Size size,
+    const gfx::Size& size,
     unsigned internalformat) {
   switch (handle.type) {
     case gfx::SHARED_MEMORY_BUFFER: {
       scoped_ptr<GpuMemoryBufferImplShm> buffer(
           new GpuMemoryBufferImplShm(size, internalformat));
-      if (!buffer->Initialize(handle))
+      if (!buffer->InitializeFromHandle(handle))
         return scoped_ptr<GpuMemoryBufferImpl>();
 
       return buffer.PassAs<GpuMemoryBufferImpl>();
@@ -25,7 +61,7 @@
     case gfx::IO_SURFACE_BUFFER: {
       scoped_ptr<GpuMemoryBufferImplIOSurface> buffer(
           new GpuMemoryBufferImplIOSurface(size, internalformat));
-      if (!buffer->Initialize(handle))
+      if (!buffer->InitializeFromHandle(handle))
         return scoped_ptr<GpuMemoryBufferImpl>();
 
       return buffer.PassAs<GpuMemoryBufferImpl>();
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_shm.cc b/content/common/gpu/client/gpu_memory_buffer_impl_shm.cc
index c550bf6..a978c66 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_shm.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_shm.cc
@@ -4,17 +4,74 @@
 
 #include "content/common/gpu/client/gpu_memory_buffer_impl_shm.h"
 
-#include "base/logging.h"
+#include "base/numerics/safe_math.h"
+#include "ui/gl/gl_bindings.h"
 
 namespace content {
 
-GpuMemoryBufferImplShm::GpuMemoryBufferImplShm(gfx::Size size,
+GpuMemoryBufferImplShm::GpuMemoryBufferImplShm(const gfx::Size& size,
                                                unsigned internalformat)
     : GpuMemoryBufferImpl(size, internalformat) {}
 
 GpuMemoryBufferImplShm::~GpuMemoryBufferImplShm() {}
 
-bool GpuMemoryBufferImplShm::Initialize(gfx::GpuMemoryBufferHandle handle) {
+// static
+void GpuMemoryBufferImplShm::AllocateSharedMemoryForChildProcess(
+    const gfx::Size& size,
+    unsigned internalformat,
+    base::ProcessHandle child_process,
+    gfx::GpuMemoryBufferHandle* handle) {
+  DCHECK(IsLayoutSupported(size, internalformat));
+  base::SharedMemory shared_memory;
+  if (!shared_memory.CreateAnonymous(size.GetArea() *
+                                     BytesPerPixel(internalformat))) {
+    handle->type = gfx::EMPTY_BUFFER;
+    return;
+  }
+  handle->type = gfx::SHARED_MEMORY_BUFFER;
+  shared_memory.GiveToProcess(child_process, &handle->handle);
+}
+
+// static
+bool GpuMemoryBufferImplShm::IsLayoutSupported(const gfx::Size& size,
+                                               unsigned internalformat) {
+  base::CheckedNumeric<int> buffer_size = size.width();
+  buffer_size *= size.height();
+  buffer_size *= BytesPerPixel(internalformat);
+  return buffer_size.IsValid();
+}
+
+// static
+bool GpuMemoryBufferImplShm::IsUsageSupported(unsigned usage) {
+  switch (usage) {
+    case GL_IMAGE_MAP_CHROMIUM:
+      return true;
+    default:
+      return false;
+  }
+}
+
+// static
+bool GpuMemoryBufferImplShm::IsConfigurationSupported(const gfx::Size& size,
+                                                      unsigned internalformat,
+                                                      unsigned usage) {
+  return IsLayoutSupported(size, internalformat) && IsUsageSupported(usage);
+}
+
+bool GpuMemoryBufferImplShm::Initialize() {
+  DCHECK(IsLayoutSupported(size_, internalformat_));
+  scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
+  if (!shared_memory->CreateAnonymous(size_.GetArea() *
+                                      BytesPerPixel(internalformat_)))
+    return false;
+  shared_memory_ = shared_memory.Pass();
+  DCHECK(!shared_memory_->memory());
+  return true;
+}
+
+bool GpuMemoryBufferImplShm::InitializeFromHandle(
+    gfx::GpuMemoryBufferHandle handle) {
+  DCHECK(IsLayoutSupported(size_, internalformat_));
   if (!base::SharedMemory::IsHandleValid(handle.handle))
     return false;
   shared_memory_.reset(new base::SharedMemory(handle.handle, false));
@@ -22,14 +79,7 @@
   return true;
 }
 
-bool GpuMemoryBufferImplShm::InitializeFromSharedMemory(
-    scoped_ptr<base::SharedMemory> shared_memory) {
-  shared_memory_ = shared_memory.Pass();
-  DCHECK(!shared_memory_->memory());
-  return true;
-}
-
-void* GpuMemoryBufferImplShm::Map(AccessMode mode) {
+void* GpuMemoryBufferImplShm::Map() {
   DCHECK(!mapped_);
   if (!shared_memory_->Map(size_.GetArea() * BytesPerPixel(internalformat_)))
     return NULL;
@@ -43,6 +93,10 @@
   mapped_ = false;
 }
 
+uint32 GpuMemoryBufferImplShm::GetStride() const {
+  return size_.width() * BytesPerPixel(internalformat_);
+}
+
 gfx::GpuMemoryBufferHandle GpuMemoryBufferImplShm::GetHandle() const {
   gfx::GpuMemoryBufferHandle handle;
   handle.type = gfx::SHARED_MEMORY_BUFFER;
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_shm.h b/content/common/gpu/client/gpu_memory_buffer_impl_shm.h
index 6e08563..961ab52 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_shm.h
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_shm.h
@@ -9,19 +9,33 @@
 
 namespace content {
 
-// Provides implementation of a GPU memory buffer based
-// on a shared memory handle.
+// Implementation of GPU memory buffer based on shared memory.
 class GpuMemoryBufferImplShm : public GpuMemoryBufferImpl {
  public:
-  GpuMemoryBufferImplShm(gfx::Size size, unsigned internalformat);
+  GpuMemoryBufferImplShm(const gfx::Size& size, unsigned internalformat);
   virtual ~GpuMemoryBufferImplShm();
 
-  bool Initialize(gfx::GpuMemoryBufferHandle handle);
-  bool InitializeFromSharedMemory(scoped_ptr<base::SharedMemory> shared_memory);
+  // Allocates a shared memory backed GPU memory buffer with |size| and
+  // |internalformat| for use by |child_process|.
+  static void AllocateSharedMemoryForChildProcess(
+      const gfx::Size& size,
+      unsigned internalformat,
+      base::ProcessHandle child_process,
+      gfx::GpuMemoryBufferHandle* handle);
+
+  static bool IsLayoutSupported(const gfx::Size& size, unsigned internalformat);
+  static bool IsUsageSupported(unsigned usage);
+  static bool IsConfigurationSupported(const gfx::Size& size,
+                                       unsigned internalformat,
+                                       unsigned usage);
+
+  bool Initialize();
+  bool InitializeFromHandle(gfx::GpuMemoryBufferHandle handle);
 
   // Overridden from gfx::GpuMemoryBuffer:
-  virtual void* Map(AccessMode mode) OVERRIDE;
+  virtual void* Map() OVERRIDE;
   virtual void Unmap() OVERRIDE;
+  virtual uint32 GetStride() const OVERRIDE;
   virtual gfx::GpuMemoryBufferHandle GetHandle() const OVERRIDE;
 
  private:
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc
index 25b51b6..f608050 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc
@@ -11,6 +11,18 @@
 
 namespace content {
 
+GpuMemoryBufferImplSurfaceTexture::GpuMemoryBufferImplSurfaceTexture(
+    const gfx::Size& size,
+    unsigned internalformat)
+    : GpuMemoryBufferImpl(size, internalformat),
+      native_window_(NULL),
+      stride_(0u) {}
+
+GpuMemoryBufferImplSurfaceTexture::~GpuMemoryBufferImplSurfaceTexture() {
+  if (native_window_)
+    ANativeWindow_release(native_window_);
+}
+
 // static
 bool GpuMemoryBufferImplSurfaceTexture::IsFormatSupported(
     unsigned internalformat) {
@@ -23,6 +35,23 @@
 }
 
 // static
+bool GpuMemoryBufferImplSurfaceTexture::IsUsageSupported(unsigned usage) {
+  switch (usage) {
+    case GL_IMAGE_MAP_CHROMIUM:
+      return true;
+    default:
+      return false;
+  }
+}
+
+// static
+bool GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported(
+    unsigned internalformat,
+    unsigned usage) {
+  return IsFormatSupported(internalformat) && IsUsageSupported(usage);
+}
+
+// static
 int GpuMemoryBufferImplSurfaceTexture::WindowFormat(unsigned internalformat) {
   switch (internalformat) {
     case GL_RGBA8_OES:
@@ -33,22 +62,12 @@
   }
 }
 
-GpuMemoryBufferImplSurfaceTexture::GpuMemoryBufferImplSurfaceTexture(
-    gfx::Size size,
-    unsigned internalformat)
-    : GpuMemoryBufferImpl(size, internalformat),
-      native_window_(NULL),
-      stride_(0u) {}
-
-GpuMemoryBufferImplSurfaceTexture::~GpuMemoryBufferImplSurfaceTexture() {
-  if (native_window_)
-    ANativeWindow_release(native_window_);
-}
-
-bool GpuMemoryBufferImplSurfaceTexture::Initialize(
+bool GpuMemoryBufferImplSurfaceTexture::InitializeFromHandle(
     gfx::GpuMemoryBufferHandle handle) {
-  TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Initialize");
+  TRACE_EVENT0("gpu",
+               "GpuMemoryBufferImplSurfaceTexture::InitializeFromHandle");
 
+  DCHECK(IsFormatSupported(internalformat_));
   DCHECK(!native_window_);
   native_window_ = SurfaceTextureLookup::GetInstance()->AcquireNativeWidget(
       handle.surface_texture_id.primary_id,
@@ -65,7 +84,7 @@
   return true;
 }
 
-void* GpuMemoryBufferImplSurfaceTexture::Map(AccessMode mode) {
+void* GpuMemoryBufferImplSurfaceTexture::Map() {
   TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Map");
 
   DCHECK(!mapped_);
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h
index 01628f2..c1cbfc3 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h
@@ -11,19 +11,22 @@
 
 namespace content {
 
-// Provides implementation of a GPU memory buffer based on a surface texture id.
+// Implementation of GPU memory buffer based on SurfaceTextures.
 class GpuMemoryBufferImplSurfaceTexture : public GpuMemoryBufferImpl {
  public:
-  GpuMemoryBufferImplSurfaceTexture(gfx::Size size, unsigned internalformat);
+  GpuMemoryBufferImplSurfaceTexture(const gfx::Size& size,
+                                    unsigned internalformat);
   virtual ~GpuMemoryBufferImplSurfaceTexture();
 
-  bool Initialize(gfx::GpuMemoryBufferHandle handle);
-
   static bool IsFormatSupported(unsigned internalformat);
+  static bool IsUsageSupported(unsigned usage);
+  static bool IsConfigurationSupported(unsigned internalformat, unsigned usage);
   static int WindowFormat(unsigned internalformat);
 
+  bool InitializeFromHandle(gfx::GpuMemoryBufferHandle handle);
+
   // Overridden from gfx::GpuMemoryBuffer:
-  virtual void* Map(AccessMode mode) OVERRIDE;
+  virtual void* Map() OVERRIDE;
   virtual void Unmap() OVERRIDE;
   virtual gfx::GpuMemoryBufferHandle GetHandle() const OVERRIDE;
   virtual uint32 GetStride() const OVERRIDE;
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_win.cc b/content/common/gpu/client/gpu_memory_buffer_impl_win.cc
index ffd4e38..8da027b 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_win.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_win.cc
@@ -8,15 +8,51 @@
 
 namespace content {
 
+// static
 scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::Create(
+    const gfx::Size& size,
+    unsigned internalformat,
+    unsigned usage) {
+  if (GpuMemoryBufferImplShm::IsConfigurationSupported(
+          size, internalformat, usage)) {
+    scoped_ptr<GpuMemoryBufferImplShm> buffer(
+        new GpuMemoryBufferImplShm(size, internalformat));
+    if (!buffer->Initialize())
+      return scoped_ptr<GpuMemoryBufferImpl>();
+
+    return buffer.PassAs<GpuMemoryBufferImpl>();
+  }
+
+  return scoped_ptr<GpuMemoryBufferImpl>();
+}
+
+// static
+void GpuMemoryBufferImpl::AllocateForChildProcess(
+    const gfx::Size& size,
+    unsigned internalformat,
+    unsigned usage,
+    base::ProcessHandle child_process,
+    gfx::GpuMemoryBufferHandle* handle) {
+  if (GpuMemoryBufferImplShm::IsConfigurationSupported(
+          size, internalformat, usage)) {
+    GpuMemoryBufferImplShm::AllocateSharedMemoryForChildProcess(
+        size, internalformat, child_process, handle);
+    return;
+  }
+
+  handle->type = gfx::EMPTY_BUFFER;
+}
+
+// static
+scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::CreateFromHandle(
     gfx::GpuMemoryBufferHandle handle,
-    gfx::Size size,
+    const gfx::Size& size,
     unsigned internalformat) {
   switch (handle.type) {
     case gfx::SHARED_MEMORY_BUFFER: {
       scoped_ptr<GpuMemoryBufferImplShm> buffer(
           new GpuMemoryBufferImplShm(size, internalformat));
-      if (!buffer->Initialize(handle))
+      if (!buffer->InitializeFromHandle(handle))
         return scoped_ptr<GpuMemoryBufferImpl>();
 
       return buffer.PassAs<GpuMemoryBufferImpl>();
diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
index 0ece341..01917ff 100644
--- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
+++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
@@ -1336,17 +1336,34 @@
 DELEGATE_TO_GL_2(vertexAttribDivisorANGLE, VertexAttribDivisorANGLE, WGC3Duint,
                  WGC3Duint)
 
-DELEGATE_TO_GL_3R(createImageCHROMIUM, CreateImageCHROMIUM,
-                  WGC3Dsizei, WGC3Dsizei, WGC3Denum,
+DELEGATE_TO_GL_4R(createImageCHROMIUM,
+                  CreateImageCHROMIUM,
+                  WGC3Dsizei,
+                  WGC3Dsizei,
+                  WGC3Denum,
+                  WGC3Denum,
                   WGC3Duint);
 
+WGC3Duint WebGraphicsContext3DCommandBufferImpl::createImageCHROMIUM(
+    WGC3Dsizei width,
+    WGC3Dsizei height,
+    WGC3Denum internalformat) {
+  return gl_->CreateImageCHROMIUM(
+      width, height, internalformat, GL_IMAGE_MAP_CHROMIUM);
+}
+
 DELEGATE_TO_GL_1(destroyImageCHROMIUM, DestroyImageCHROMIUM, WGC3Duint);
 
 DELEGATE_TO_GL_3(getImageParameterivCHROMIUM, GetImageParameterivCHROMIUM,
                  WGC3Duint, WGC3Denum, GLint*);
 
-DELEGATE_TO_GL_2R(mapImageCHROMIUM, MapImageCHROMIUM,
-                  WGC3Duint, WGC3Denum, void*);
+DELEGATE_TO_GL_1R(mapImageCHROMIUM, MapImageCHROMIUM, WGC3Duint, void*);
+
+void* WebGraphicsContext3DCommandBufferImpl::mapImageCHROMIUM(
+    WGC3Duint image_id,
+    WGC3Denum access) {
+  return gl_->MapImageCHROMIUM(image_id);
+}
 
 DELEGATE_TO_GL_1(unmapImageCHROMIUM, UnmapImageCHROMIUM, WGC3Duint);
 
diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
index a167c64..6a41e47 100644
--- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
+++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
@@ -652,12 +652,19 @@
   virtual void vertexAttribDivisorANGLE(WGC3Duint index, WGC3Duint divisor);
 
   // GL_CHROMIUM_map_image
+  // TODO(alexst): remove this old function after blink cleanup.
   virtual WGC3Duint createImageCHROMIUM(
       WGC3Dsizei width, WGC3Dsizei height, WGC3Denum internalformat);
+  virtual WGC3Duint createImageCHROMIUM(WGC3Dsizei width,
+                                        WGC3Dsizei height,
+                                        WGC3Denum internalformat,
+                                        WGC3Denum usage);
   virtual void destroyImageCHROMIUM(WGC3Duint image_id);
   virtual void getImageParameterivCHROMIUM(
       WGC3Duint image_id, WGC3Denum pname, WGC3Dint* params);
+  // TODO(alexst): remove this old function after blink cleanup.
   virtual void* mapImageCHROMIUM(WGC3Duint image_id, WGC3Denum access);
+  virtual void* mapImageCHROMIUM(WGC3Duint image_id);
   virtual void unmapImageCHROMIUM(WGC3Duint image_id);
 
   // GL_EXT_multisampled_render_to_texture
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index 6f72157..3795fa7 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -186,6 +186,7 @@
   devtools_gpu_instrumentation::ScopedGpuTask task(channel());
   FastSetActiveURL(active_url_, active_url_hash_);
 
+  bool have_context = false;
   // Ensure the appropriate GL context is current before handling any IPC
   // messages directed at the command buffer. This ensures that the message
   // handler can assume that the context is current (not necessary for
@@ -197,6 +198,7 @@
       message.type() != GpuCommandBufferMsg_SetLatencyInfo::ID) {
     if (!MakeCurrent())
       return false;
+    have_context = true;
   }
 
   // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers
@@ -249,8 +251,10 @@
 
   CheckCompleteWaits();
 
-  // Ensure that any delayed work that was created will be handled.
-  ScheduleDelayedWork(kHandleMoreWorkPeriodMs);
+  if (have_context) {
+    // Ensure that any delayed work that was created will be handled.
+    ScheduleDelayedWork(kHandleMoreWorkPeriodMs);
+  }
 
   DCHECK(handled);
   return handled;
@@ -538,12 +542,8 @@
     return;
   }
 
-  gpu_control_.reset(
-      new gpu::GpuControlService(context_group_->image_manager(),
-                                 NULL,
-                                 context_group_->mailbox_manager(),
-                                 NULL,
-                                 decoder_->GetCapabilities()));
+  gpu_control_service_.reset(
+      new gpu::GpuControlService(context_group_->image_manager(), NULL));
 
   if (CommandLine::ForCurrentProcess()->HasSwitch(
       switches::kEnableGPUServiceLogging)) {
@@ -587,7 +587,7 @@
       shared_state_shm.Pass(), kSharedStateSize));
 
   GpuCommandBufferMsg_Initialize::WriteReplyParams(
-      reply_message, true, gpu_control_->GetCapabilities());
+      reply_message, true, decoder_->GetCapabilities());
   Send(reply_message);
 
   if (handle_.is_null() && !active_url_.is_empty()) {
@@ -942,19 +942,16 @@
     return;
   }
 #endif
-  if (gpu_control_) {
-    gpu_control_->RegisterGpuMemoryBuffer(id,
-                                          gpu_memory_buffer,
-                                          width,
-                                          height,
-                                          internalformat);
+  if (gpu_control_service_) {
+    gpu_control_service_->RegisterGpuMemoryBuffer(
+        id, gpu_memory_buffer, width, height, internalformat);
   }
 }
 
 void GpuCommandBufferStub::OnDestroyGpuMemoryBuffer(int32 id) {
   TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyGpuMemoryBuffer");
-  if (gpu_control_)
-    gpu_control_->DestroyGpuMemoryBuffer(id);
+  if (gpu_control_service_)
+    gpu_control_service_->UnregisterGpuMemoryBuffer(id);
 }
 
 void GpuCommandBufferStub::SendConsoleMessage(
diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h
index 6e4cd88..214cb97 100644
--- a/content/common/gpu/gpu_command_buffer_stub.h
+++ b/content/common/gpu/gpu_command_buffer_stub.h
@@ -252,7 +252,7 @@
   scoped_ptr<gpu::gles2::GLES2Decoder> decoder_;
   scoped_ptr<gpu::GpuScheduler> scheduler_;
   scoped_refptr<gfx::GLSurface> surface_;
-  scoped_ptr<gpu::GpuControlService> gpu_control_;
+  scoped_ptr<gpu::GpuControlService> gpu_control_service_;
 
   scoped_ptr<GpuMemoryManagerClientState> memory_manager_client_state_;
   // The last memory allocation received from the GpuMemoryManager (used to
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index b283e9a..9e320e0 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -168,7 +168,6 @@
   IPC_STRUCT_TRAITS_MEMBER(machine_model_name)
   IPC_STRUCT_TRAITS_MEMBER(machine_model_version)
   IPC_STRUCT_TRAITS_MEMBER(gl_version)
-  IPC_STRUCT_TRAITS_MEMBER(gl_version_string)
   IPC_STRUCT_TRAITS_MEMBER(gl_vendor)
   IPC_STRUCT_TRAITS_MEMBER(gl_renderer)
   IPC_STRUCT_TRAITS_MEMBER(gl_extensions)
@@ -197,6 +196,7 @@
   IPC_STRUCT_TRAITS_MEMBER(texture_usage)
   IPC_STRUCT_TRAITS_MEMBER(texture_storage)
   IPC_STRUCT_TRAITS_MEMBER(discard_framebuffer)
+  IPC_STRUCT_TRAITS_MEMBER(sync_query)
   IPC_STRUCT_TRAITS_MEMBER(map_image)
 IPC_STRUCT_TRAITS_END()
 
diff --git a/content/common/gpu/media/exynos_v4l2_video_device.cc b/content/common/gpu/media/exynos_v4l2_video_device.cc
index 1ee7557..2410da0 100644
--- a/content/common/gpu/media/exynos_v4l2_video_device.cc
+++ b/content/common/gpu/media/exynos_v4l2_video_device.cc
@@ -20,11 +20,15 @@
 namespace content {
 
 namespace {
-const char kDevice[] = "/dev/mfc-dec";
+const char kDecoderDevice[] = "/dev/mfc-dec";
+const char kEncoderDevice[] = "/dev/mfc-enc";
+const char kImageProcessorDevice[] = "/dev/gsc1";
 }
 
-ExynosV4L2Device::ExynosV4L2Device()
-    : device_fd_(-1), device_poll_interrupt_fd_(-1) {}
+ExynosV4L2Device::ExynosV4L2Device(Type type)
+    : type_(type),
+      device_fd_(-1),
+      device_poll_interrupt_fd_(-1) {}
 
 ExynosV4L2Device::~ExynosV4L2Device() {
   if (device_poll_interrupt_fd_ != -1) {
@@ -38,7 +42,7 @@
 }
 
 int ExynosV4L2Device::Ioctl(int request, void* arg) {
-  return ioctl(device_fd_, request, arg);
+  return HANDLE_EINTR(ioctl(device_fd_, request, arg));
 }
 
 bool ExynosV4L2Device::Poll(bool poll_device, bool* event_pending) {
@@ -83,6 +87,7 @@
 
   const uint64 buf = 1;
   if (HANDLE_EINTR(write(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) {
+    DPLOG(ERROR) << "SetDevicePollInterrupt(): write() failed";
     return false;
   }
   return true;
@@ -105,9 +110,22 @@
 }
 
 bool ExynosV4L2Device::Initialize() {
-  DVLOG(2) << "Initialize(): opening device: " << kDevice;
+  const char* device_path = NULL;
+  switch (type_) {
+    case kDecoder:
+      device_path = kDecoderDevice;
+      break;
+    case kEncoder:
+      device_path = kEncoderDevice;
+      break;
+    case kImageProcessor:
+      device_path = kImageProcessorDevice;
+      break;
+  }
+
+  DVLOG(2) << "Initialize(): opening device: " << device_path;
   // Open the video device.
-  device_fd_ = HANDLE_EINTR(open(kDevice, O_RDWR | O_NONBLOCK | O_CLOEXEC));
+  device_fd_ = HANDLE_EINTR(open(device_path, O_RDWR | O_NONBLOCK | O_CLOEXEC));
   if (device_fd_ == -1) {
     return false;
   }
@@ -120,6 +138,7 @@
 }
 
 EGLImageKHR ExynosV4L2Device::CreateEGLImage(EGLDisplay egl_display,
+                                             EGLContext /* egl_context */,
                                              GLuint texture_id,
                                              gfx::Size frame_buffer_size,
                                              unsigned int buffer_index,
@@ -135,7 +154,7 @@
     expbuf.index = buffer_index;
     expbuf.plane = i;
     expbuf.flags = O_CLOEXEC;
-    if (HANDLE_EINTR(Ioctl(VIDIOC_EXPBUF, &expbuf) != 0)) {
+    if (Ioctl(VIDIOC_EXPBUF, &expbuf) != 0) {
       return EGL_NO_IMAGE_KHR;
     }
     dmabuf_fds[i].reset(expbuf.fd);
@@ -175,6 +194,18 @@
 
 GLenum ExynosV4L2Device::GetTextureTarget() { return GL_TEXTURE_EXTERNAL_OES; }
 
-uint32 ExynosV4L2Device::PreferredOutputFormat() { return V4L2_PIX_FMT_NV12M; }
+uint32 ExynosV4L2Device::PreferredInputFormat() {
+  // TODO(posciak): We should support "dontcare" returns here once we
+  // implement proper handling (fallback, negotiation) for this in users.
+  CHECK_EQ(type_, kEncoder);
+  return V4L2_PIX_FMT_NV12M;
+}
+
+uint32 ExynosV4L2Device::PreferredOutputFormat() {
+  // TODO(posciak): We should support "dontcare" returns here once we
+  // implement proper handling (fallback, negotiation) for this in users.
+  CHECK_EQ(type_, kDecoder);
+  return V4L2_PIX_FMT_NV12M;
+}
 
 }  //  namespace content
diff --git a/content/common/gpu/media/exynos_v4l2_video_device.h b/content/common/gpu/media/exynos_v4l2_video_device.h
index fc9e62a..3745cbe 100644
--- a/content/common/gpu/media/exynos_v4l2_video_device.h
+++ b/content/common/gpu/media/exynos_v4l2_video_device.h
@@ -14,7 +14,7 @@
 
 class ExynosV4L2Device : public V4L2Device {
  public:
-  ExynosV4L2Device();
+  explicit ExynosV4L2Device(Type type);
   virtual ~ExynosV4L2Device();
 
   // V4L2Device implementation.
@@ -30,6 +30,7 @@
   virtual void Munmap(void* addr, unsigned int len) OVERRIDE;
   virtual bool Initialize() OVERRIDE;
   virtual EGLImageKHR CreateEGLImage(EGLDisplay egl_display,
+                                     EGLContext egl_context,
                                      GLuint texture_id,
                                      gfx::Size frame_buffer_size,
                                      unsigned int buffer_index,
@@ -37,9 +38,12 @@
   virtual EGLBoolean DestroyEGLImage(EGLDisplay egl_display,
                                      EGLImageKHR egl_image) OVERRIDE;
   virtual GLenum GetTextureTarget() OVERRIDE;
+  virtual uint32 PreferredInputFormat() OVERRIDE;
   virtual uint32 PreferredOutputFormat() OVERRIDE;
 
  private:
+  const Type type_;
+
   // The actual device fd.
   int device_fd_;
 
diff --git a/content/common/gpu/media/exynos_video_encode_accelerator.cc b/content/common/gpu/media/exynos_video_encode_accelerator.cc
deleted file mode 100644
index c8bddd0..0000000
--- a/content/common/gpu/media/exynos_video_encode_accelerator.cc
+++ /dev/null
@@ -1,1540 +0,0 @@
-// Copyright 2013 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.
-
-#include "content/common/gpu/media/exynos_video_encode_accelerator.h"
-
-#include <fcntl.h>
-#include <linux/videodev2.h>
-#include <poll.h>
-#include <sys/eventfd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-
-#include "base/callback.h"
-#include "base/command_line.h"
-#include "base/debug/trace_event.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "base/posix/eintr_wrapper.h"
-#include "content/public/common/content_switches.h"
-#include "media/base/bitstream_buffer.h"
-
-#define NOTIFY_ERROR(x)                                            \
-  do {                                                             \
-    SetEncoderState(kError);                                       \
-    DLOG(ERROR) << "calling NotifyError(): " << x;                 \
-    NotifyError(x);                                                \
-  } while (0)
-
-#define IOCTL_OR_ERROR_RETURN_VALUE(fd, type, arg, value)          \
-  do {                                                             \
-    if (HANDLE_EINTR(ioctl(fd, type, arg) != 0)) {                 \
-      DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
-      NOTIFY_ERROR(kPlatformFailureError);                         \
-      return value;                                                \
-    }                                                              \
-  } while (0)
-
-#define IOCTL_OR_ERROR_RETURN(fd, type, arg) \
-  IOCTL_OR_ERROR_RETURN_VALUE(fd, type, arg, ((void)0))
-
-#define IOCTL_OR_ERROR_RETURN_FALSE(fd, type, arg) \
-  IOCTL_OR_ERROR_RETURN_VALUE(fd, type, arg, false)
-
-namespace content {
-
-namespace {
-
-const char kExynosGscDevice[] = "/dev/gsc1";
-const char kExynosMfcDevice[] = "/dev/mfc-enc";
-
-// File descriptors we need to poll, one-bit flag for each.
-enum PollFds {
-  kPollGsc = (1 << 0),
-  kPollMfc = (1 << 1),
-};
-
-}  // anonymous namespace
-
-struct ExynosVideoEncodeAccelerator::BitstreamBufferRef {
-  BitstreamBufferRef(int32 id, scoped_ptr<base::SharedMemory> shm, size_t size)
-      : id(id), shm(shm.Pass()), size(size) {}
-  const int32 id;
-  const scoped_ptr<base::SharedMemory> shm;
-  const size_t size;
-};
-
-
-ExynosVideoEncodeAccelerator::GscInputRecord::GscInputRecord()
-    : at_device(false) {}
-
-ExynosVideoEncodeAccelerator::GscOutputRecord::GscOutputRecord()
-    : at_device(false), mfc_input(-1) {}
-
-ExynosVideoEncodeAccelerator::MfcInputRecord::MfcInputRecord()
-    : at_device(false) {
-  fd[0] = fd[1] = -1;
-}
-
-ExynosVideoEncodeAccelerator::MfcOutputRecord::MfcOutputRecord()
-    : at_device(false), address(NULL), length(0) {}
-
-ExynosVideoEncodeAccelerator::ExynosVideoEncodeAccelerator()
-    : child_message_loop_proxy_(base::MessageLoopProxy::current()),
-      weak_this_ptr_factory_(this),
-      weak_this_(weak_this_ptr_factory_.GetWeakPtr()),
-      encoder_thread_("ExynosEncoderThread"),
-      encoder_state_(kUninitialized),
-      output_buffer_byte_size_(0),
-      stream_header_size_(0),
-      input_format_fourcc_(0),
-      output_format_fourcc_(0),
-      gsc_fd_(-1),
-      gsc_input_streamon_(false),
-      gsc_input_buffer_queued_count_(0),
-      gsc_output_streamon_(false),
-      gsc_output_buffer_queued_count_(0),
-      mfc_fd_(-1),
-      mfc_input_streamon_(false),
-      mfc_input_buffer_queued_count_(0),
-      mfc_output_streamon_(false),
-      mfc_output_buffer_queued_count_(0),
-      device_poll_thread_("ExynosEncoderDevicePollThread"),
-      device_poll_interrupt_fd_(-1) {}
-
-ExynosVideoEncodeAccelerator::~ExynosVideoEncodeAccelerator() {
-  DCHECK(!encoder_thread_.IsRunning());
-  DCHECK(!device_poll_thread_.IsRunning());
-
-  if (device_poll_interrupt_fd_ != -1) {
-    close(device_poll_interrupt_fd_);
-    device_poll_interrupt_fd_ = -1;
-  }
-  if (gsc_fd_ != -1) {
-    DestroyGscInputBuffers();
-    DestroyGscOutputBuffers();
-    close(gsc_fd_);
-    gsc_fd_ = -1;
-  }
-  if (mfc_fd_ != -1) {
-    DestroyMfcInputBuffers();
-    DestroyMfcOutputBuffers();
-    close(mfc_fd_);
-    mfc_fd_ = -1;
-  }
-}
-
-bool ExynosVideoEncodeAccelerator::Initialize(
-    media::VideoFrame::Format input_format,
-    const gfx::Size& input_visible_size,
-    media::VideoCodecProfile output_profile,
-    uint32 initial_bitrate,
-    Client* client) {
-  DVLOG(3) << "Initialize(): input_format=" << input_format
-           << ", input_visible_size=" << input_visible_size.ToString()
-           << ", output_profile=" << output_profile
-           << ", initial_bitrate=" << initial_bitrate;
-
-  client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
-  client_ = client_ptr_factory_->GetWeakPtr();
-
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-  DCHECK_EQ(encoder_state_, kUninitialized);
-
-  input_visible_size_ = input_visible_size;
-  input_allocated_size_.SetSize((input_visible_size_.width() + 0xF) & ~0xF,
-                                (input_visible_size_.height() + 0xF) & ~0xF);
-  converted_visible_size_.SetSize((input_visible_size_.width() + 0x1) & ~0x1,
-                                  (input_visible_size_.height() + 0x1) & ~0x1);
-  converted_allocated_size_.SetSize(
-      (converted_visible_size_.width() + 0xF) & ~0xF,
-      (converted_visible_size_.height() + 0xF) & ~0xF);
-  output_visible_size_ = converted_visible_size_;
-
-  switch (input_format) {
-    case media::VideoFrame::I420:
-      input_format_fourcc_ = V4L2_PIX_FMT_YUV420M;
-      break;
-    default:
-      DLOG(ERROR) << "Initialize(): invalid input_format=" << input_format;
-      return false;
-  }
-
-  if (output_profile >= media::H264PROFILE_MIN &&
-      output_profile <= media::H264PROFILE_MAX) {
-    output_format_fourcc_ = V4L2_PIX_FMT_H264;
-  } else if (output_profile >= media::VP8PROFILE_MIN &&
-             output_profile <= media::VP8PROFILE_MAX) {
-    output_format_fourcc_ = V4L2_PIX_FMT_VP8;
-  } else {
-    DLOG(ERROR) << "Initialize(): invalid output_profile=" << output_profile;
-    return false;
-  }
-
-  // Open the color conversion device.
-  DVLOG(2) << "Initialize(): opening GSC device: " << kExynosGscDevice;
-  gsc_fd_ =
-      HANDLE_EINTR(open(kExynosGscDevice, O_RDWR | O_NONBLOCK | O_CLOEXEC));
-  if (gsc_fd_ == -1) {
-    DPLOG(ERROR) << "Initialize(): could not open GSC device: "
-                 << kExynosGscDevice;
-    return false;
-  }
-
-  // Capabilities check.
-  struct v4l2_capability caps;
-  memset(&caps, 0, sizeof(caps));
-  const __u32 kCapsRequired = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
-                              V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING;
-  if (HANDLE_EINTR(ioctl(gsc_fd_, VIDIOC_QUERYCAP, &caps))) {
-    DPLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP";
-    return false;
-  }
-  if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
-    DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
-                   "caps check failed: 0x" << std::hex << caps.capabilities;
-    return false;
-  }
-
-  // Open the video encoder device.
-  DVLOG(2) << "Initialize(): opening MFC device: " << kExynosMfcDevice;
-  mfc_fd_ =
-      HANDLE_EINTR(open(kExynosMfcDevice, O_RDWR | O_NONBLOCK | O_CLOEXEC));
-  if (mfc_fd_ == -1) {
-    DPLOG(ERROR) << "Initialize(): could not open MFC device: "
-                 << kExynosMfcDevice;
-    return false;
-  }
-
-  memset(&caps, 0, sizeof(caps));
-  if (HANDLE_EINTR(ioctl(mfc_fd_, VIDIOC_QUERYCAP, &caps))) {
-    DPLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP";
-    return false;
-  }
-  if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
-    DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
-                   "caps check failed: 0x" << std::hex << caps.capabilities;
-    return false;
-  }
-
-  // Create the interrupt fd.
-  DCHECK_EQ(device_poll_interrupt_fd_, -1);
-  device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-  if (device_poll_interrupt_fd_ == -1) {
-    DPLOG(ERROR) << "Initialize(): eventfd() failed";
-    return false;
-  }
-
-  DVLOG(3)
-      << "Initialize(): input_visible_size_=" << input_visible_size_.ToString()
-      << ", input_allocated_size_=" << input_allocated_size_.ToString()
-      << ", converted_visible_size_=" << converted_visible_size_.ToString()
-      << ", converted_allocated_size_=" << converted_allocated_size_.ToString()
-      << ", output_visible_size_=" << output_visible_size_.ToString();
-
-  if (!CreateGscInputBuffers() || !CreateGscOutputBuffers())
-    return false;
-
-  // MFC setup for encoding is rather particular in ordering:
-  //
-  // 1. Format (VIDIOC_S_FMT) set first on OUTPUT and CAPTURE queues.
-  // 2. VIDIOC_REQBUFS, VIDIOC_QBUF, and VIDIOC_STREAMON on CAPTURE queue.
-  // 3. VIDIOC_REQBUFS (and later VIDIOC_QBUF and VIDIOC_STREAMON) on OUTPUT
-  //    queue.
-  //
-  // Unfortunately, we cannot do (3) in Initialize() here since we have no
-  // buffers to QBUF in step (2) until the client has provided output buffers
-  // through UseOutputBitstreamBuffer().  So, we just do (1), and the
-  // VIDIOC_REQBUFS part of (2) here.  The rest is done the first time we get
-  // a UseOutputBitstreamBuffer() callback.
-
-  if (!SetMfcFormats())
-    return false;
-
-  if (!InitMfcControls())
-    return false;
-
-  // VIDIOC_REQBUFS on CAPTURE queue.
-  if (!CreateMfcOutputBuffers())
-    return false;
-
-  if (!encoder_thread_.Start()) {
-    DLOG(ERROR) << "Initialize(): encoder thread failed to start";
-    return false;
-  }
-
-  RequestEncodingParametersChange(initial_bitrate, kInitialFramerate);
-
-  SetEncoderState(kInitialized);
-
-  child_message_loop_proxy_->PostTask(
-      FROM_HERE,
-      base::Bind(&Client::RequireBitstreamBuffers,
-                 client_,
-                 gsc_input_buffer_map_.size(),
-                 input_allocated_size_,
-                 output_buffer_byte_size_));
-  return true;
-}
-
-void ExynosVideoEncodeAccelerator::Encode(
-    const scoped_refptr<media::VideoFrame>& frame,
-    bool force_keyframe) {
-  DVLOG(3) << "Encode(): force_keyframe=" << force_keyframe;
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-
-  encoder_thread_.message_loop()->PostTask(
-      FROM_HERE,
-      base::Bind(&ExynosVideoEncodeAccelerator::EncodeTask,
-                 base::Unretained(this),
-                 frame,
-                 force_keyframe));
-}
-
-void ExynosVideoEncodeAccelerator::UseOutputBitstreamBuffer(
-    const media::BitstreamBuffer& buffer) {
-  DVLOG(3) << "UseOutputBitstreamBuffer(): id=" << buffer.id();
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-
-  if (buffer.size() < output_buffer_byte_size_) {
-    NOTIFY_ERROR(kInvalidArgumentError);
-    return;
-  }
-
-  scoped_ptr<base::SharedMemory> shm(
-      new base::SharedMemory(buffer.handle(), false));
-  if (!shm->Map(buffer.size())) {
-    NOTIFY_ERROR(kPlatformFailureError);
-    return;
-  }
-
-  scoped_ptr<BitstreamBufferRef> buffer_ref(
-      new BitstreamBufferRef(buffer.id(), shm.Pass(), buffer.size()));
-  encoder_thread_.message_loop()->PostTask(
-      FROM_HERE,
-      base::Bind(&ExynosVideoEncodeAccelerator::UseOutputBitstreamBufferTask,
-                 base::Unretained(this),
-                 base::Passed(&buffer_ref)));
-}
-
-void ExynosVideoEncodeAccelerator::RequestEncodingParametersChange(
-    uint32 bitrate,
-    uint32 framerate) {
-  DVLOG(3) << "RequestEncodingParametersChange(): bitrate=" << bitrate
-           << ", framerate=" << framerate;
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-
-  encoder_thread_.message_loop()->PostTask(
-      FROM_HERE,
-      base::Bind(
-          &ExynosVideoEncodeAccelerator::RequestEncodingParametersChangeTask,
-          base::Unretained(this),
-          bitrate,
-          framerate));
-}
-
-void ExynosVideoEncodeAccelerator::Destroy() {
-  DVLOG(3) << "Destroy()";
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-
-  // We're destroying; cancel all callbacks.
-  client_ptr_factory_.reset();
-
-  // If the encoder thread is running, destroy using posted task.
-  if (encoder_thread_.IsRunning()) {
-    encoder_thread_.message_loop()->PostTask(
-        FROM_HERE,
-        base::Bind(&ExynosVideoEncodeAccelerator::DestroyTask,
-                   base::Unretained(this)));
-    // DestroyTask() will put the encoder into kError state and cause all tasks
-    // to no-op.
-    encoder_thread_.Stop();
-  } else {
-    // Otherwise, call the destroy task directly.
-    DestroyTask();
-  }
-
-  // Set to kError state just in case.
-  SetEncoderState(kError);
-
-  delete this;
-}
-
-// static
-std::vector<media::VideoEncodeAccelerator::SupportedProfile>
-ExynosVideoEncodeAccelerator::GetSupportedProfiles() {
-  std::vector<SupportedProfile> profiles;
-
-  SupportedProfile profile;
-
-  const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
-  if (cmd_line->HasSwitch(switches::kEnableWebRtcHWVp8Encoding)) {
-    profile.profile = media::VP8PROFILE_MAIN;
-    profile.max_resolution.SetSize(1920, 1088);
-    profile.max_framerate.numerator = 30;
-    profile.max_framerate.denominator = 1;
-    profiles.push_back(profile);
-  } else {
-    profile.profile = media::H264PROFILE_MAIN;
-    profile.max_resolution.SetSize(1920, 1088);
-    profile.max_framerate.numerator = 30;
-    profile.max_framerate.denominator = 1;
-    profiles.push_back(profile);
-  }
-
-  return profiles;
-}
-
-void ExynosVideoEncodeAccelerator::EncodeTask(
-    const scoped_refptr<media::VideoFrame>& frame, bool force_keyframe) {
-  DVLOG(3) << "EncodeTask(): force_keyframe=" << force_keyframe;
-  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
-  DCHECK_NE(encoder_state_, kUninitialized);
-
-  if (encoder_state_ == kError) {
-    DVLOG(2) << "EncodeTask(): early out: kError state";
-    return;
-  }
-
-  encoder_input_queue_.push_back(frame);
-  EnqueueGsc();
-
-  if (force_keyframe) {
-    // TODO(sheu): this presently makes for slightly imprecise encoding
-    // parameters updates.  To precisely align the parameter updates with the
-    // incoming input frame, we should track the parameters through the GSC
-    // pipeline and only apply them when the MFC input is about to be queued.
-    struct v4l2_ext_control ctrls[1];
-    struct v4l2_ext_controls control;
-    memset(&ctrls, 0, sizeof(ctrls));
-    memset(&control, 0, sizeof(control));
-    ctrls[0].id    = V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE;
-    ctrls[0].value = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME;
-    control.ctrl_class = V4L2_CTRL_CLASS_MPEG;
-    control.count = 1;
-    control.controls = ctrls;
-    IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_S_EXT_CTRLS, &control);
-  }
-}
-
-void ExynosVideoEncodeAccelerator::UseOutputBitstreamBufferTask(
-    scoped_ptr<BitstreamBufferRef> buffer_ref) {
-  DVLOG(3) << "UseOutputBitstreamBufferTask(): id=" << buffer_ref->id;
-  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
-
-  encoder_output_queue_.push_back(
-      linked_ptr<BitstreamBufferRef>(buffer_ref.release()));
-  EnqueueMfc();
-
-  if (encoder_state_ == kInitialized) {
-    // Finish setting up our MFC OUTPUT queue.  See: Initialize().
-    // VIDIOC_REQBUFS on OUTPUT queue.
-    if (!CreateMfcInputBuffers())
-      return;
-    if (!StartDevicePoll())
-      return;
-    encoder_state_ = kEncoding;
-  }
-}
-
-void ExynosVideoEncodeAccelerator::DestroyTask() {
-  DVLOG(3) << "DestroyTask()";
-
-  // DestroyTask() should run regardless of encoder_state_.
-
-  // Stop streaming and the device_poll_thread_.
-  StopDevicePoll();
-
-  // Set our state to kError, and early-out all tasks.
-  encoder_state_ = kError;
-}
-
-void ExynosVideoEncodeAccelerator::ServiceDeviceTask() {
-  DVLOG(3) << "ServiceDeviceTask()";
-  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
-  DCHECK_NE(encoder_state_, kUninitialized);
-  DCHECK_NE(encoder_state_, kInitialized);
-
-  if (encoder_state_ == kError) {
-    DVLOG(2) << "ServiceDeviceTask(): early out: kError state";
-    return;
-  }
-
-  DequeueGsc();
-  DequeueMfc();
-  EnqueueGsc();
-  EnqueueMfc();
-
-  // Clear the interrupt fd.
-  if (!ClearDevicePollInterrupt())
-    return;
-
-  unsigned int poll_fds = 0;
-  // Add GSC fd, if we should poll on it.
-  // GSC has to wait until both input and output buffers are queued.
-  if (gsc_input_buffer_queued_count_ > 0 && gsc_output_buffer_queued_count_ > 0)
-    poll_fds |= kPollGsc;
-  // Add MFC fd, if we should poll on it.
-  // MFC can be polled as soon as either input or output buffers are queued.
-  if (mfc_input_buffer_queued_count_ + mfc_output_buffer_queued_count_ > 0)
-    poll_fds |= kPollMfc;
-
-  // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
-  // so either:
-  // * device_poll_thread_ is running normally
-  // * device_poll_thread_ scheduled us, but then a DestroyTask() shut it down,
-  //   in which case we're in kError state, and we should have early-outed
-  //   already.
-  DCHECK(device_poll_thread_.message_loop());
-  // Queue the DevicePollTask() now.
-  device_poll_thread_.message_loop()->PostTask(
-      FROM_HERE,
-      base::Bind(&ExynosVideoEncodeAccelerator::DevicePollTask,
-                 base::Unretained(this),
-                 poll_fds));
-
-  DVLOG(2) << "ServiceDeviceTask(): buffer counts: ENC["
-           << encoder_input_queue_.size() << "] => GSC["
-           << gsc_free_input_buffers_.size() << "+"
-           << gsc_input_buffer_queued_count_ << "/"
-           << gsc_input_buffer_map_.size() << "->"
-           << gsc_free_output_buffers_.size() << "+"
-           << gsc_output_buffer_queued_count_ << "/"
-           << gsc_output_buffer_map_.size() << "] => "
-           << mfc_ready_input_buffers_.size() << " => MFC["
-           << mfc_free_input_buffers_.size() << "+"
-           << mfc_input_buffer_queued_count_ << "/"
-           << mfc_input_buffer_map_.size() << "->"
-           << mfc_free_output_buffers_.size() << "+"
-           << mfc_output_buffer_queued_count_ << "/"
-           << mfc_output_buffer_map_.size() << "] => OUT["
-           << encoder_output_queue_.size() << "]";
-}
-
-void ExynosVideoEncodeAccelerator::EnqueueGsc() {
-  DVLOG(3) << "EnqueueGsc()";
-  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
-
-  const int old_gsc_inputs_queued = gsc_input_buffer_queued_count_;
-  while (!encoder_input_queue_.empty() && !gsc_free_input_buffers_.empty()) {
-    if (!EnqueueGscInputRecord())
-      return;
-  }
-  if (old_gsc_inputs_queued == 0 && gsc_input_buffer_queued_count_ != 0) {
-    // We started up a previously empty queue.
-    // Queue state changed; signal interrupt.
-    if (!SetDevicePollInterrupt())
-      return;
-    // Start VIDIOC_STREAMON if we haven't yet.
-    if (!gsc_input_streamon_) {
-      __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-      IOCTL_OR_ERROR_RETURN(gsc_fd_, VIDIOC_STREAMON, &type);
-      gsc_input_streamon_ = true;
-    }
-  }
-
-  // Enqueue a GSC output, only if we need one.  GSC output buffers write
-  // directly to MFC input buffers, so we'll have to check for free MFC input
-  // buffers as well.
-  // GSC is liable to race conditions if more than one output buffer is
-  // simultaneously enqueued, so enqueue just one.
-  if (gsc_input_buffer_queued_count_ != 0 &&
-      gsc_output_buffer_queued_count_ == 0 &&
-      !gsc_free_output_buffers_.empty() && !mfc_free_input_buffers_.empty()) {
-    const int old_gsc_outputs_queued = gsc_output_buffer_queued_count_;
-    if (!EnqueueGscOutputRecord())
-      return;
-    if (old_gsc_outputs_queued == 0 && gsc_output_buffer_queued_count_ != 0) {
-      // We just started up a previously empty queue.
-      // Queue state changed; signal interrupt.
-      if (!SetDevicePollInterrupt())
-        return;
-      // Start VIDIOC_STREAMON if we haven't yet.
-      if (!gsc_output_streamon_) {
-        __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-        IOCTL_OR_ERROR_RETURN(gsc_fd_, VIDIOC_STREAMON, &type);
-        gsc_output_streamon_ = true;
-      }
-    }
-  }
-  DCHECK_LE(gsc_output_buffer_queued_count_, 1);
-}
-
-void ExynosVideoEncodeAccelerator::DequeueGsc() {
-  DVLOG(3) << "DequeueGsc()";
-  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
-
-  // Dequeue completed GSC input (VIDEO_OUTPUT) buffers, and recycle to the free
-  // list.
-  struct v4l2_buffer dqbuf;
-  struct v4l2_plane planes[3];
-  while (gsc_input_buffer_queued_count_ > 0) {
-    DCHECK(gsc_input_streamon_);
-    memset(&dqbuf, 0, sizeof(dqbuf));
-    memset(&planes, 0, sizeof(planes));
-    dqbuf.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-    dqbuf.memory   = V4L2_MEMORY_USERPTR;
-    dqbuf.m.planes = planes;
-    dqbuf.length   = arraysize(planes);
-    if (HANDLE_EINTR(ioctl(gsc_fd_, VIDIOC_DQBUF, &dqbuf)) != 0) {
-      if (errno == EAGAIN) {
-        // EAGAIN if we're just out of buffers to dequeue.
-        break;
-      }
-      DPLOG(ERROR) << "DequeueGsc(): ioctl() failed: VIDIOC_DQBUF";
-      NOTIFY_ERROR(kPlatformFailureError);
-      return;
-    }
-    GscInputRecord& input_record = gsc_input_buffer_map_[dqbuf.index];
-    DCHECK(input_record.at_device);
-    DCHECK(input_record.frame.get());
-    input_record.at_device = false;
-    input_record.frame = NULL;
-    gsc_free_input_buffers_.push_back(dqbuf.index);
-    gsc_input_buffer_queued_count_--;
-  }
-
-  // Dequeue completed GSC output (VIDEO_CAPTURE) buffers, and recycle to the
-  // free list.  Queue the corresponding MFC buffer to the GSC->MFC holding
-  // queue.
-  while (gsc_output_buffer_queued_count_ > 0) {
-    DCHECK(gsc_output_streamon_);
-    memset(&dqbuf, 0, sizeof(dqbuf));
-    memset(&planes, 0, sizeof(planes));
-    dqbuf.type     = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-    dqbuf.memory   = V4L2_MEMORY_DMABUF;
-    dqbuf.m.planes = planes;
-    dqbuf.length   = 2;
-    if (HANDLE_EINTR(ioctl(gsc_fd_, VIDIOC_DQBUF, &dqbuf)) != 0) {
-      if (errno == EAGAIN) {
-        // EAGAIN if we're just out of buffers to dequeue.
-        break;
-      }
-      DPLOG(ERROR) << "DequeueGsc(): ioctl() failed: VIDIOC_DQBUF";
-      NOTIFY_ERROR(kPlatformFailureError);
-      return;
-    }
-    GscOutputRecord& output_record = gsc_output_buffer_map_[dqbuf.index];
-    DCHECK(output_record.at_device);
-    DCHECK(output_record.mfc_input != -1);
-    mfc_ready_input_buffers_.push_back(output_record.mfc_input);
-    output_record.at_device = false;
-    output_record.mfc_input = -1;
-    gsc_free_output_buffers_.push_back(dqbuf.index);
-    gsc_output_buffer_queued_count_--;
-  }
-}
-void ExynosVideoEncodeAccelerator::EnqueueMfc() {
-  DVLOG(3) << "EnqueueMfc()";
-  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
-
-  // Enqueue all the MFC inputs we can.
-  const int old_mfc_inputs_queued = mfc_input_buffer_queued_count_;
-  while (!mfc_ready_input_buffers_.empty()) {
-    if (!EnqueueMfcInputRecord())
-      return;
-  }
-  if (old_mfc_inputs_queued == 0 && mfc_input_buffer_queued_count_ != 0) {
-    // We just started up a previously empty queue.
-    // Queue state changed; signal interrupt.
-    if (!SetDevicePollInterrupt())
-      return;
-    // Start VIDIOC_STREAMON if we haven't yet.
-    if (!mfc_input_streamon_) {
-      __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-      IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_STREAMON, &type);
-      mfc_input_streamon_ = true;
-    }
-  }
-
-  // Enqueue all the MFC outputs we can.
-  const int old_mfc_outputs_queued = mfc_output_buffer_queued_count_;
-  while (!mfc_free_output_buffers_.empty() && !encoder_output_queue_.empty()) {
-    if (!EnqueueMfcOutputRecord())
-      return;
-  }
-  if (old_mfc_outputs_queued == 0 && mfc_output_buffer_queued_count_ != 0) {
-    // We just started up a previously empty queue.
-    // Queue state changed; signal interrupt.
-    if (!SetDevicePollInterrupt())
-      return;
-    // Start VIDIOC_STREAMON if we haven't yet.
-    if (!mfc_output_streamon_) {
-      __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-      IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_STREAMON, &type);
-      mfc_output_streamon_ = true;
-    }
-  }
-}
-
-void ExynosVideoEncodeAccelerator::DequeueMfc() {
-  DVLOG(3) << "DequeueMfc()";
-  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
-
-  // Dequeue completed MFC input (VIDEO_OUTPUT) buffers, and recycle to the free
-  // list.
-  struct v4l2_buffer dqbuf;
-  struct v4l2_plane planes[2];
-  while (mfc_input_buffer_queued_count_ > 0) {
-    DCHECK(mfc_input_streamon_);
-    memset(&dqbuf, 0, sizeof(dqbuf));
-    memset(&planes, 0, sizeof(planes));
-    dqbuf.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-    dqbuf.memory   = V4L2_MEMORY_MMAP;
-    dqbuf.m.planes = planes;
-    dqbuf.length   = 2;
-    if (HANDLE_EINTR(ioctl(mfc_fd_, VIDIOC_DQBUF, &dqbuf)) != 0) {
-      if (errno == EAGAIN) {
-        // EAGAIN if we're just out of buffers to dequeue.
-        break;
-      }
-      DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF";
-      NOTIFY_ERROR(kPlatformFailureError);
-      return;
-    }
-    MfcInputRecord& input_record = mfc_input_buffer_map_[dqbuf.index];
-    DCHECK(input_record.at_device);
-    input_record.at_device = false;
-    mfc_free_input_buffers_.push_back(dqbuf.index);
-    mfc_input_buffer_queued_count_--;
-  }
-
-  // Dequeue completed MFC output (VIDEO_CAPTURE) buffers, and recycle to the
-  // free list.  Notify the client that an output buffer is complete.
-  while (mfc_output_buffer_queued_count_ > 0) {
-    DCHECK(mfc_output_streamon_);
-    memset(&dqbuf, 0, sizeof(dqbuf));
-    memset(planes, 0, sizeof(planes));
-    dqbuf.type     = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-    dqbuf.memory   = V4L2_MEMORY_MMAP;
-    dqbuf.m.planes = planes;
-    dqbuf.length   = 1;
-    if (HANDLE_EINTR(ioctl(mfc_fd_, VIDIOC_DQBUF, &dqbuf)) != 0) {
-      if (errno == EAGAIN) {
-        // EAGAIN if we're just out of buffers to dequeue.
-        break;
-      }
-      DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF";
-      NOTIFY_ERROR(kPlatformFailureError);
-      return;
-    }
-    const bool key_frame = ((dqbuf.flags & V4L2_BUF_FLAG_KEYFRAME) != 0);
-    MfcOutputRecord& output_record = mfc_output_buffer_map_[dqbuf.index];
-    DCHECK(output_record.at_device);
-    DCHECK(output_record.buffer_ref.get());
-
-    void* output_data = output_record.address;
-    size_t output_size = dqbuf.m.planes[0].bytesused;
-    // This shouldn't happen, but just in case. We should be able to recover
-    // after next keyframe after showing some corruption.
-    DCHECK_LE(output_size, output_buffer_byte_size_);
-    if (output_size > output_buffer_byte_size_)
-      output_size = output_buffer_byte_size_;
-    uint8* target_data =
-        reinterpret_cast<uint8*>(output_record.buffer_ref->shm->memory());
-    if (output_format_fourcc_ == V4L2_PIX_FMT_H264) {
-      if (stream_header_size_ == 0) {
-        // Assume that the first buffer dequeued is the stream header.
-        stream_header_size_ = output_size;
-        stream_header_.reset(new uint8[stream_header_size_]);
-        memcpy(stream_header_.get(), output_data, stream_header_size_);
-      }
-      if (key_frame &&
-          output_buffer_byte_size_ - stream_header_size_ >= output_size) {
-        // Insert stream header before every keyframe.
-        memcpy(target_data, stream_header_.get(), stream_header_size_);
-        memcpy(target_data + stream_header_size_, output_data, output_size);
-        output_size += stream_header_size_;
-      } else {
-        memcpy(target_data, output_data, output_size);
-      }
-    } else {
-      memcpy(target_data, output_data, output_size);
-    }
-
-    DVLOG(3) << "DequeueMfc(): returning "
-                "bitstream_buffer_id=" << output_record.buffer_ref->id
-             << ", key_frame=" << key_frame;
-    child_message_loop_proxy_->PostTask(
-        FROM_HERE,
-        base::Bind(&Client::BitstreamBufferReady,
-                   client_,
-                   output_record.buffer_ref->id,
-                   output_size,
-                   key_frame));
-    output_record.at_device = false;
-    output_record.buffer_ref.reset();
-    mfc_free_output_buffers_.push_back(dqbuf.index);
-    mfc_output_buffer_queued_count_--;
-  }
-}
-
-bool ExynosVideoEncodeAccelerator::EnqueueGscInputRecord() {
-  DVLOG(3) << "EnqueueGscInputRecord()";
-  DCHECK(!encoder_input_queue_.empty());
-  DCHECK(!gsc_free_input_buffers_.empty());
-
-  // Enqueue a GSC input (VIDEO_OUTPUT) buffer for an input video frame
-  scoped_refptr<media::VideoFrame> frame = encoder_input_queue_.front();
-  const int gsc_buffer = gsc_free_input_buffers_.back();
-  GscInputRecord& input_record = gsc_input_buffer_map_[gsc_buffer];
-  DCHECK(!input_record.at_device);
-  DCHECK(!input_record.frame.get());
-  struct v4l2_buffer qbuf;
-  struct v4l2_plane qbuf_planes[3];
-  memset(&qbuf, 0, sizeof(qbuf));
-  memset(qbuf_planes, 0, sizeof(qbuf_planes));
-  qbuf.index    = gsc_buffer;
-  qbuf.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-  qbuf.memory   = V4L2_MEMORY_USERPTR;
-  qbuf.m.planes = qbuf_planes;
-  switch (input_format_fourcc_) {
-    case V4L2_PIX_FMT_YUV420M: {
-      qbuf.m.planes[0].bytesused = input_allocated_size_.GetArea();
-      qbuf.m.planes[0].length    = input_allocated_size_.GetArea();
-      qbuf.m.planes[0].m.userptr = reinterpret_cast<unsigned long>(
-          frame->data(media::VideoFrame::kYPlane));
-      qbuf.m.planes[1].bytesused = input_allocated_size_.GetArea() / 4;
-      qbuf.m.planes[1].length    = input_allocated_size_.GetArea() / 4;
-      qbuf.m.planes[1].m.userptr = reinterpret_cast<unsigned long>(
-          frame->data(media::VideoFrame::kUPlane));
-      qbuf.m.planes[2].bytesused = input_allocated_size_.GetArea() / 4;
-      qbuf.m.planes[2].length    = input_allocated_size_.GetArea() / 4;
-      qbuf.m.planes[2].m.userptr = reinterpret_cast<unsigned long>(
-          frame->data(media::VideoFrame::kVPlane));
-      qbuf.length = 3;
-      break;
-    }
-    default:
-      NOTREACHED();
-      NOTIFY_ERROR(kIllegalStateError);
-      return false;
-  }
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_QBUF, &qbuf);
-  input_record.at_device = true;
-  input_record.frame = frame;
-  encoder_input_queue_.pop_front();
-  gsc_free_input_buffers_.pop_back();
-  gsc_input_buffer_queued_count_++;
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::EnqueueGscOutputRecord() {
-  DVLOG(3) << "EnqueueGscOutputRecord()";
-  DCHECK(!gsc_free_output_buffers_.empty());
-  DCHECK(!mfc_free_input_buffers_.empty());
-
-  // Enqueue a GSC output (VIDEO_CAPTURE) buffer.
-  const int gsc_buffer = gsc_free_output_buffers_.back();
-  const int mfc_buffer = mfc_free_input_buffers_.back();
-  GscOutputRecord& output_record = gsc_output_buffer_map_[gsc_buffer];
-  MfcInputRecord& input_record = mfc_input_buffer_map_[mfc_buffer];
-  DCHECK(!output_record.at_device);
-  DCHECK_EQ(output_record.mfc_input, -1);
-  DCHECK(!input_record.at_device);
-  struct v4l2_buffer qbuf;
-  struct v4l2_plane qbuf_planes[2];
-  memset(&qbuf, 0, sizeof(qbuf));
-  memset(qbuf_planes, 0, sizeof(qbuf_planes));
-  qbuf.index            = gsc_buffer;
-  qbuf.type             = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  qbuf.memory           = V4L2_MEMORY_DMABUF;
-  qbuf.m.planes         = qbuf_planes;
-  qbuf.m.planes[0].m.fd = input_record.fd[0];
-  qbuf.m.planes[1].m.fd = input_record.fd[1];
-  qbuf.length           = 2;
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_QBUF, &qbuf);
-  output_record.at_device = true;
-  output_record.mfc_input = mfc_buffer;
-  mfc_free_input_buffers_.pop_back();
-  gsc_free_output_buffers_.pop_back();
-  gsc_output_buffer_queued_count_++;
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::EnqueueMfcInputRecord() {
-  DVLOG(3) << "EnqueueMfcInputRecord()";
-  DCHECK(!mfc_ready_input_buffers_.empty());
-
-  // Enqueue a MFC input (VIDEO_OUTPUT) buffer.
-  const int mfc_buffer = mfc_ready_input_buffers_.front();
-  MfcInputRecord& input_record = mfc_input_buffer_map_[mfc_buffer];
-  DCHECK(!input_record.at_device);
-  struct v4l2_buffer qbuf;
-  struct v4l2_plane qbuf_planes[2];
-  memset(&qbuf, 0, sizeof(qbuf));
-  memset(qbuf_planes, 0, sizeof(qbuf_planes));
-  qbuf.index     = mfc_buffer;
-  qbuf.type      = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-  qbuf.memory    = V4L2_MEMORY_MMAP;
-  qbuf.m.planes  = qbuf_planes;
-  qbuf.length    = 2;
-  IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf);
-  input_record.at_device = true;
-  mfc_ready_input_buffers_.pop_front();
-  mfc_input_buffer_queued_count_++;
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::EnqueueMfcOutputRecord() {
-  DVLOG(3) << "EnqueueMfcOutputRecord()";
-  DCHECK(!mfc_free_output_buffers_.empty());
-  DCHECK(!encoder_output_queue_.empty());
-
-  // Enqueue a MFC output (VIDEO_CAPTURE) buffer.
-  linked_ptr<BitstreamBufferRef> output_buffer = encoder_output_queue_.back();
-  const int mfc_buffer = mfc_free_output_buffers_.back();
-  MfcOutputRecord& output_record = mfc_output_buffer_map_[mfc_buffer];
-  DCHECK(!output_record.at_device);
-  DCHECK(!output_record.buffer_ref.get());
-  struct v4l2_buffer qbuf;
-  struct v4l2_plane qbuf_planes[1];
-  memset(&qbuf, 0, sizeof(qbuf));
-  memset(qbuf_planes, 0, sizeof(qbuf_planes));
-  qbuf.index                 = mfc_buffer;
-  qbuf.type                  = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  qbuf.memory                = V4L2_MEMORY_MMAP;
-  qbuf.m.planes              = qbuf_planes;
-  qbuf.length                = 1;
-  IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf);
-  output_record.at_device = true;
-  output_record.buffer_ref = output_buffer;
-  encoder_output_queue_.pop_back();
-  mfc_free_output_buffers_.pop_back();
-  mfc_output_buffer_queued_count_++;
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::StartDevicePoll() {
-  DVLOG(3) << "StartDevicePoll()";
-  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
-  DCHECK(!device_poll_thread_.IsRunning());
-
-  // Start up the device poll thread and schedule its first DevicePollTask().
-  if (!device_poll_thread_.Start()) {
-    DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
-    NOTIFY_ERROR(kPlatformFailureError);
-    return false;
-  }
-  // Enqueue a poll task with no devices to poll on -- it will wait only on the
-  // interrupt fd.
-  device_poll_thread_.message_loop()->PostTask(
-      FROM_HERE,
-      base::Bind(&ExynosVideoEncodeAccelerator::DevicePollTask,
-                 base::Unretained(this),
-                 0));
-
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::StopDevicePoll() {
-  DVLOG(3) << "StopDevicePoll()";
-
-  // Signal the DevicePollTask() to stop, and stop the device poll thread.
-  if (!SetDevicePollInterrupt())
-    return false;
-  device_poll_thread_.Stop();
-  // Clear the interrupt now, to be sure.
-  if (!ClearDevicePollInterrupt())
-    return false;
-
-  // Stop streaming.
-  if (gsc_input_streamon_) {
-    __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-    IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_STREAMOFF, &type);
-  }
-  gsc_input_streamon_ = false;
-  if (gsc_output_streamon_) {
-    __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-    IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_STREAMOFF, &type);
-  }
-  gsc_output_streamon_ = false;
-  if (mfc_input_streamon_) {
-    __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-    IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type);
-  }
-  mfc_input_streamon_ = false;
-  if (mfc_output_streamon_) {
-    __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-    IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type);
-  }
-  mfc_output_streamon_ = false;
-
-  // Reset all our accounting info.
-  encoder_input_queue_.clear();
-  gsc_free_input_buffers_.clear();
-  for (size_t i = 0; i < gsc_input_buffer_map_.size(); ++i) {
-    GscInputRecord& input_record = gsc_input_buffer_map_[i];
-    input_record.at_device = false;
-    input_record.frame = NULL;
-    gsc_free_input_buffers_.push_back(i);
-  }
-  gsc_input_buffer_queued_count_ = 0;
-  gsc_free_output_buffers_.clear();
-  for (size_t i = 0; i < gsc_output_buffer_map_.size(); ++i) {
-    GscOutputRecord& output_record = gsc_output_buffer_map_[i];
-    output_record.at_device = false;
-    output_record.mfc_input = -1;
-    gsc_free_output_buffers_.push_back(i);
-  }
-  gsc_output_buffer_queued_count_ = 0;
-  mfc_ready_input_buffers_.clear();
-  mfc_free_input_buffers_.clear();
-  for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
-    MfcInputRecord& input_record = mfc_input_buffer_map_[i];
-    input_record.at_device = false;
-    mfc_free_input_buffers_.push_back(i);
-  }
-  mfc_input_buffer_queued_count_ = 0;
-  mfc_free_output_buffers_.clear();
-  for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
-    MfcOutputRecord& output_record = mfc_output_buffer_map_[i];
-    output_record.at_device = false;
-    output_record.buffer_ref.reset();
-    mfc_free_output_buffers_.push_back(i);
-  }
-  mfc_output_buffer_queued_count_ = 0;
-  encoder_output_queue_.clear();
-
-  DVLOG(3) << "StopDevicePoll(): device poll stopped";
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::SetDevicePollInterrupt() {
-  DVLOG(3) << "SetDevicePollInterrupt()";
-
-  // We might get called here if we fail during initialization, in which case we
-  // don't have a file descriptor.
-  if (device_poll_interrupt_fd_ == -1)
-    return true;
-
-  const uint64 buf = 1;
-  if (HANDLE_EINTR((write(device_poll_interrupt_fd_, &buf, sizeof(buf)))) <
-      static_cast<ssize_t>(sizeof(buf))) {
-    DPLOG(ERROR) << "SetDevicePollInterrupt(): write() failed";
-    NOTIFY_ERROR(kPlatformFailureError);
-    return false;
-  }
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::ClearDevicePollInterrupt() {
-  DVLOG(3) << "ClearDevicePollInterrupt()";
-
-  // We might get called here if we fail during initialization, in which case we
-  // don't have a file descriptor.
-  if (device_poll_interrupt_fd_ == -1)
-    return true;
-
-  uint64 buf;
-  if (HANDLE_EINTR(read(device_poll_interrupt_fd_, &buf, sizeof(buf))) <
-      static_cast<ssize_t>(sizeof(buf))) {
-    if (errno == EAGAIN) {
-      // No interrupt flag set, and we're reading nonblocking.  Not an error.
-      return true;
-    } else {
-      DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed";
-      NOTIFY_ERROR(kPlatformFailureError);
-      return false;
-    }
-  }
-  return true;
-}
-
-void ExynosVideoEncodeAccelerator::DevicePollTask(unsigned int poll_fds) {
-  DVLOG(3) << "DevicePollTask()";
-  DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current());
-  DCHECK_NE(device_poll_interrupt_fd_, -1);
-
-  // This routine just polls the set of device fds, and schedules a
-  // ServiceDeviceTask() on encoder_thread_ when processing needs to occur.
-  // Other threads may notify this task to return early by writing to
-  // device_poll_interrupt_fd_.
-  struct pollfd pollfds[3];
-  nfds_t nfds;
-
-  // Add device_poll_interrupt_fd_;
-  pollfds[0].fd = device_poll_interrupt_fd_;
-  pollfds[0].events = POLLIN | POLLERR;
-  nfds = 1;
-
-  // Add GSC fd, if we should poll on it.
-  // GSC has to wait until both input and output buffers are queued.
-  if (poll_fds & kPollGsc) {
-    DVLOG(3) << "DevicePollTask(): adding GSC to poll() set";
-    pollfds[nfds].fd = gsc_fd_;
-    pollfds[nfds].events = POLLIN | POLLOUT | POLLERR;
-    nfds++;
-  }
-  if (poll_fds & kPollMfc) {
-    DVLOG(3) << "DevicePollTask(): adding MFC to poll() set";
-    pollfds[nfds].fd = mfc_fd_;
-    pollfds[nfds].events = POLLIN | POLLOUT | POLLERR;
-    nfds++;
-  }
-
-  // Poll it!
-  if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) {
-    DPLOG(ERROR) << "DevicePollTask(): poll() failed";
-    NOTIFY_ERROR(kPlatformFailureError);
-    return;
-  }
-
-  // All processing should happen on ServiceDeviceTask(), since we shouldn't
-  // touch encoder state from this thread.
-  encoder_thread_.message_loop()->PostTask(
-      FROM_HERE,
-      base::Bind(&ExynosVideoEncodeAccelerator::ServiceDeviceTask,
-                 base::Unretained(this)));
-}
-
-void ExynosVideoEncodeAccelerator::NotifyError(Error error) {
-  DVLOG(1) << "NotifyError(): error=" << error;
-
-  if (!child_message_loop_proxy_->BelongsToCurrentThread()) {
-    child_message_loop_proxy_->PostTask(
-        FROM_HERE,
-        base::Bind(
-            &ExynosVideoEncodeAccelerator::NotifyError, weak_this_, error));
-    return;
-  }
-
-  if (client_) {
-    client_->NotifyError(error);
-    client_ptr_factory_.reset();
-  }
-}
-
-void ExynosVideoEncodeAccelerator::SetEncoderState(State state) {
-  DVLOG(3) << "SetEncoderState(): state=" << state;
-
-  // We can touch encoder_state_ only if this is the encoder thread or the
-  // encoder thread isn't running.
-  if (encoder_thread_.message_loop() != NULL &&
-      encoder_thread_.message_loop() != base::MessageLoop::current()) {
-    encoder_thread_.message_loop()->PostTask(
-        FROM_HERE,
-        base::Bind(&ExynosVideoEncodeAccelerator::SetEncoderState,
-                   base::Unretained(this),
-                   state));
-  } else {
-    encoder_state_ = state;
-  }
-}
-
-void ExynosVideoEncodeAccelerator::RequestEncodingParametersChangeTask(
-    uint32 bitrate,
-    uint32 framerate) {
-  DVLOG(3) << "RequestEncodingParametersChangeTask(): bitrate=" << bitrate
-           << ", framerate=" << framerate;
-  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
-
-  if (bitrate < 1)
-    bitrate = 1;
-  if (framerate < 1)
-    framerate = 1;
-
-  struct v4l2_ext_control ctrls[1];
-  struct v4l2_ext_controls control;
-  memset(&ctrls, 0, sizeof(ctrls));
-  memset(&control, 0, sizeof(control));
-  ctrls[0].id    = V4L2_CID_MPEG_VIDEO_BITRATE;
-  ctrls[0].value = bitrate;
-  control.ctrl_class = V4L2_CTRL_CLASS_MPEG;
-  control.count = arraysize(ctrls);
-  control.controls = ctrls;
-  IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_S_EXT_CTRLS, &control);
-
-  struct v4l2_streamparm parms;
-  memset(&parms, 0, sizeof(parms));
-  parms.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-  // Note that we are provided "frames per second" but V4L2 expects "time per
-  // frame"; hence we provide the reciprocal of the framerate here.
-  parms.parm.output.timeperframe.numerator = 1;
-  parms.parm.output.timeperframe.denominator = framerate;
-  IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_S_PARM, &parms);
-}
-
-bool ExynosVideoEncodeAccelerator::CreateGscInputBuffers() {
-  DVLOG(3) << "CreateGscInputBuffers()";
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-  DCHECK_EQ(encoder_state_, kUninitialized);
-  DCHECK(!gsc_input_streamon_);
-
-  struct v4l2_control control;
-  memset(&control, 0, sizeof(control));
-  control.id    = V4L2_CID_ROTATE;
-  control.value = 0;
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
-
-  // HFLIP actually seems to control vertical mirroring for GSC, and vice-versa.
-  memset(&control, 0, sizeof(control));
-  control.id    = V4L2_CID_HFLIP;
-  control.value = 0;
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
-
-  memset(&control, 0, sizeof(control));
-  control.id    = V4L2_CID_VFLIP;
-  control.value = 0;
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
-
-  memset(&control, 0, sizeof(control));
-  control.id    = V4L2_CID_ALPHA_COMPONENT;
-  control.value = 255;
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CTRL, &control);
-
-  struct v4l2_format format;
-  memset(&format, 0, sizeof(format));
-  format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-  format.fmt.pix_mp.width  = input_allocated_size_.width();
-  format.fmt.pix_mp.height = input_allocated_size_.height();
-  format.fmt.pix_mp.pixelformat = input_format_fourcc_;
-  switch (input_format_fourcc_) {
-    case V4L2_PIX_FMT_RGB32:
-      format.fmt.pix_mp.plane_fmt[0].sizeimage =
-          input_allocated_size_.GetArea() * 4;
-      format.fmt.pix_mp.plane_fmt[0].bytesperline =
-          input_allocated_size_.width() * 4;
-      format.fmt.pix_mp.num_planes = 1;
-      break;
-    case V4L2_PIX_FMT_YUV420M:
-      format.fmt.pix_mp.plane_fmt[0].sizeimage =
-          input_allocated_size_.GetArea();
-      format.fmt.pix_mp.plane_fmt[0].bytesperline =
-          input_allocated_size_.width();
-      format.fmt.pix_mp.plane_fmt[1].sizeimage =
-          input_allocated_size_.GetArea() / 4;
-      format.fmt.pix_mp.plane_fmt[1].bytesperline =
-          input_allocated_size_.width() / 2;
-      format.fmt.pix_mp.plane_fmt[2].sizeimage =
-          input_allocated_size_.GetArea() / 4;
-      format.fmt.pix_mp.plane_fmt[2].bytesperline =
-          input_allocated_size_.width() / 2;
-      format.fmt.pix_mp.num_planes = 3;
-      break;
-    default:
-      NOTREACHED();
-      NOTIFY_ERROR(kIllegalStateError);
-      return false;
-  }
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_FMT, &format);
-
-  struct v4l2_crop crop;
-  memset(&crop, 0, sizeof(crop));
-  crop.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-  crop.c.left   = 0;
-  crop.c.top    = 0;
-  crop.c.width  = input_visible_size_.width();
-  crop.c.height = input_visible_size_.height();
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CROP, &crop);
-
-  struct v4l2_requestbuffers reqbufs;
-  memset(&reqbufs, 0, sizeof(reqbufs));
-  reqbufs.count  = kGscInputBufferCount;
-  reqbufs.type   = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-  reqbufs.memory = V4L2_MEMORY_USERPTR;
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_REQBUFS, &reqbufs);
-
-  DCHECK(gsc_input_buffer_map_.empty());
-  gsc_input_buffer_map_.resize(reqbufs.count);
-  for (size_t i = 0; i < gsc_input_buffer_map_.size(); ++i)
-    gsc_free_input_buffers_.push_back(i);
-
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::CreateGscOutputBuffers() {
-  DVLOG(3) << "CreateGscOutputBuffers()";
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-  DCHECK_EQ(encoder_state_, kUninitialized);
-  DCHECK(!gsc_output_streamon_);
-
-  struct v4l2_format format;
-  memset(&format, 0, sizeof(format));
-  format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  format.fmt.pix_mp.width = converted_allocated_size_.width();
-  format.fmt.pix_mp.height = converted_allocated_size_.height();
-  format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
-  format.fmt.pix_mp.plane_fmt[0].sizeimage =
-      converted_allocated_size_.GetArea();
-  format.fmt.pix_mp.plane_fmt[1].sizeimage =
-      converted_allocated_size_.GetArea() / 2;
-  format.fmt.pix_mp.plane_fmt[0].bytesperline =
-      converted_allocated_size_.width();
-  format.fmt.pix_mp.plane_fmt[1].bytesperline =
-      converted_allocated_size_.width();
-  format.fmt.pix_mp.num_planes = 2;
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_FMT, &format);
-
-  struct v4l2_crop crop;
-  memset(&crop, 0, sizeof(crop));
-  crop.type     = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  crop.c.left   = 0;
-  crop.c.top    = 0;
-  crop.c.width  = converted_visible_size_.width();
-  crop.c.height = converted_visible_size_.height();
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_S_CROP, &crop);
-
-  struct v4l2_requestbuffers reqbufs;
-  memset(&reqbufs, 0, sizeof(reqbufs));
-  reqbufs.count  = kGscOutputBufferCount;
-  reqbufs.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  reqbufs.memory = V4L2_MEMORY_DMABUF;
-  IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_REQBUFS, &reqbufs);
-
-  DCHECK(gsc_output_buffer_map_.empty());
-  gsc_output_buffer_map_.resize(reqbufs.count);
-  for (size_t i = 0; i < gsc_output_buffer_map_.size(); ++i)
-    gsc_free_output_buffers_.push_back(i);
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::SetMfcFormats() {
-  DVLOG(3) << "SetMfcFormats()";
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-  DCHECK(!mfc_input_streamon_);
-  DCHECK(!mfc_output_streamon_);
-
-  // VIDIOC_S_FMT on OUTPUT queue.
-  struct v4l2_format format;
-  memset(&format, 0, sizeof(format));
-  format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-  format.fmt.pix_mp.width = input_allocated_size_.width();
-  format.fmt.pix_mp.height = input_allocated_size_.height();
-  format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
-  format.fmt.pix_mp.num_planes = 2;
-  IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format);
-  // We read direct from GSC, so we rely on the HW not changing our set
-  // size/stride.
-  DCHECK_GT(format.fmt.pix_mp.plane_fmt[0].sizeimage,
-            static_cast<__u32>(input_allocated_size_.GetArea()));
-  DCHECK_EQ(format.fmt.pix_mp.plane_fmt[0].bytesperline,
-            static_cast<__u32>(input_allocated_size_.width()));
-  DCHECK_GT(format.fmt.pix_mp.plane_fmt[1].sizeimage,
-            static_cast<__u32>(input_allocated_size_.GetArea() / 2));
-  DCHECK_EQ(format.fmt.pix_mp.plane_fmt[1].bytesperline,
-            static_cast<__u32>(input_allocated_size_.width()));
-
-  struct v4l2_crop crop;
-  memset(&crop, 0, sizeof(crop));
-  crop.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-  crop.c.left   = 0;
-  crop.c.top    = 0;
-  crop.c.width  = input_visible_size_.width();
-  crop.c.height = input_visible_size_.height();
-  IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_CROP, &crop);
-
-  // VIDIOC_S_FMT on CAPTURE queue.
-  output_buffer_byte_size_ = kMfcOutputBufferSize;
-  memset(&format, 0, sizeof(format));
-  format.type                   = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  format.fmt.pix_mp.width       = output_visible_size_.width();
-  format.fmt.pix_mp.height      = output_visible_size_.height();
-  format.fmt.pix_mp.pixelformat = output_format_fourcc_;
-  format.fmt.pix_mp.plane_fmt[0].sizeimage = output_buffer_byte_size_;
-  format.fmt.pix_mp.num_planes  = 1;
-  IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format);
-
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::InitMfcControls() {
-  struct v4l2_ext_control ctrls[9];
-  struct v4l2_ext_controls control;
-  memset(&ctrls, 0, sizeof(ctrls));
-  memset(&control, 0, sizeof(control));
-  // No B-frames, for lowest decoding latency.
-  ctrls[0].id    = V4L2_CID_MPEG_VIDEO_B_FRAMES;
-  ctrls[0].value = 0;
-  // Enable frame-level bitrate control.
-  ctrls[1].id    = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
-  ctrls[1].value = 1;
-  // Enable "tight" bitrate mode. For this to work properly, frame- and mb-level
-  // bitrate controls have to be enabled as well.
-  ctrls[2].id    = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
-  ctrls[2].value = 1;
-  // Force bitrate control to average over a GOP (for tight bitrate
-  // tolerance).
-  ctrls[3].id    = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
-  ctrls[3].value = 1;
-  // Quantization parameter maximum value (for variable bitrate control).
-  ctrls[4].id    = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
-  ctrls[4].value = 51;
-  // Separate stream header so we can cache it and insert into the stream.
-  ctrls[5].id    = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
-  ctrls[5].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
-  // Enable macroblock-level bitrate control.
-  ctrls[6].id    = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE;
-  ctrls[6].value = 1;
-  // Use H.264 level 4.0 to match the supported max resolution.
-  ctrls[7].id    = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
-  ctrls[7].value = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
-  // Disable periodic key frames.
-  ctrls[8].id    = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
-  ctrls[8].value = 0;
-  control.ctrl_class = V4L2_CTRL_CLASS_MPEG;
-  control.count = arraysize(ctrls);
-  control.controls = ctrls;
-  IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_EXT_CTRLS, &control);
-
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::CreateMfcInputBuffers() {
-  DVLOG(3) << "CreateMfcInputBuffers()";
-  // This function runs on encoder_thread_ after output buffers have been
-  // provided by the client.
-  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
-  DCHECK(!mfc_input_streamon_);
-
-  struct v4l2_requestbuffers reqbufs;
-  memset(&reqbufs, 0, sizeof(reqbufs));
-  reqbufs.count = 1;  // Driver will allocate the appropriate number of buffers.
-  reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-  reqbufs.memory = V4L2_MEMORY_MMAP;
-  IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs);
-
-  DCHECK(mfc_input_buffer_map_.empty());
-  mfc_input_buffer_map_.resize(reqbufs.count);
-  for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
-    MfcInputRecord& input_record = mfc_input_buffer_map_[i];
-    for (int j = 0; j < 2; ++j) {
-      // Export the DMABUF fd so GSC can write to it.
-      struct v4l2_exportbuffer expbuf;
-      memset(&expbuf, 0, sizeof(expbuf));
-      expbuf.type  = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-      expbuf.index = i;
-      expbuf.plane = j;
-      expbuf.flags = O_CLOEXEC;
-      IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_EXPBUF, &expbuf);
-      input_record.fd[j] = expbuf.fd;
-    }
-    mfc_free_input_buffers_.push_back(i);
-  }
-
-  return true;
-}
-
-bool ExynosVideoEncodeAccelerator::CreateMfcOutputBuffers() {
-  DVLOG(3) << "CreateMfcOutputBuffers()";
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-  DCHECK(!mfc_output_streamon_);
-
-  struct v4l2_requestbuffers reqbufs;
-  memset(&reqbufs, 0, sizeof(reqbufs));
-  reqbufs.count = kMfcOutputBufferCount;
-  reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  reqbufs.memory = V4L2_MEMORY_MMAP;
-  IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs);
-
-  DCHECK(mfc_output_buffer_map_.empty());
-  mfc_output_buffer_map_.resize(reqbufs.count);
-  for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
-    struct v4l2_plane planes[1];
-    struct v4l2_buffer buffer;
-    memset(&buffer, 0, sizeof(buffer));
-    memset(planes, 0, sizeof(planes));
-    buffer.index    = i;
-    buffer.type     = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-    buffer.memory   = V4L2_MEMORY_MMAP;
-    buffer.m.planes = planes;
-    buffer.length   = arraysize(planes);
-    IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYBUF, &buffer);
-    void* address = mmap(NULL, buffer.m.planes[0].length,
-        PROT_READ | PROT_WRITE, MAP_SHARED, mfc_fd_,
-        buffer.m.planes[0].m.mem_offset);
-    if (address == MAP_FAILED) {
-      DPLOG(ERROR) << "CreateMfcOutputBuffers(): mmap() failed";
-      return false;
-    }
-    mfc_output_buffer_map_[i].address = address;
-    mfc_output_buffer_map_[i].length = buffer.m.planes[0].length;
-    mfc_free_output_buffers_.push_back(i);
-  }
-
-  return true;
-}
-
-void ExynosVideoEncodeAccelerator::DestroyGscInputBuffers() {
-  DVLOG(3) << "DestroyGscInputBuffers()";
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-  DCHECK(!gsc_input_streamon_);
-
-  struct v4l2_requestbuffers reqbufs;
-  memset(&reqbufs, 0, sizeof(reqbufs));
-  reqbufs.count = 0;
-  reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-  reqbufs.memory = V4L2_MEMORY_USERPTR;
-  if (HANDLE_EINTR(ioctl(gsc_fd_, VIDIOC_REQBUFS, &reqbufs)) != 0)
-    DPLOG(ERROR) << "DestroyGscInputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
-
-  gsc_input_buffer_map_.clear();
-  gsc_free_input_buffers_.clear();
-}
-
-void ExynosVideoEncodeAccelerator::DestroyGscOutputBuffers() {
-  DVLOG(3) << "DestroyGscOutputBuffers()";
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-  DCHECK(!gsc_output_streamon_);
-
-  struct v4l2_requestbuffers reqbufs;
-  memset(&reqbufs, 0, sizeof(reqbufs));
-  reqbufs.count = 0;
-  reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  reqbufs.memory = V4L2_MEMORY_DMABUF;
-  if (HANDLE_EINTR(ioctl(gsc_fd_, VIDIOC_REQBUFS, &reqbufs)) != 0)
-    DPLOG(ERROR) << "DestroyGscOutputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
-
-  gsc_output_buffer_map_.clear();
-  gsc_free_output_buffers_.clear();
-}
-
-void ExynosVideoEncodeAccelerator::DestroyMfcInputBuffers() {
-  DVLOG(3) << "DestroyMfcInputBuffers()";
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-  DCHECK(!mfc_input_streamon_);
-
-  for (size_t buf = 0; buf < mfc_input_buffer_map_.size(); ++buf) {
-    MfcInputRecord& input_record = mfc_input_buffer_map_[buf];
-
-    for (size_t plane = 0; plane < arraysize(input_record.fd); ++plane)
-      close(mfc_input_buffer_map_[buf].fd[plane]);
-  }
-
-  struct v4l2_requestbuffers reqbufs;
-  memset(&reqbufs, 0, sizeof(reqbufs));
-  reqbufs.count = 0;
-  reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-  reqbufs.memory = V4L2_MEMORY_MMAP;
-  if (HANDLE_EINTR(ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs)) != 0)
-    DPLOG(ERROR) << "DestroyMfcInputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
-
-  mfc_input_buffer_map_.clear();
-  mfc_free_input_buffers_.clear();
-}
-
-void ExynosVideoEncodeAccelerator::DestroyMfcOutputBuffers() {
-  DVLOG(3) << "DestroyMfcOutputBuffers()";
-  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
-  DCHECK(!mfc_output_streamon_);
-
-  for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
-    if (mfc_output_buffer_map_[i].address != NULL) {
-      munmap(mfc_output_buffer_map_[i].address,
-             mfc_output_buffer_map_[i].length);
-    }
-  }
-
-  struct v4l2_requestbuffers reqbufs;
-  memset(&reqbufs, 0, sizeof(reqbufs));
-  reqbufs.count = 0;
-  reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  reqbufs.memory = V4L2_MEMORY_MMAP;
-  if (HANDLE_EINTR(ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs)) != 0)
-    DPLOG(ERROR) << "DestroyMfcOutputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
-
-  mfc_output_buffer_map_.clear();
-  mfc_free_output_buffers_.clear();
-}
-
-}  // namespace content
diff --git a/content/common/gpu/media/exynos_video_encode_accelerator.h b/content/common/gpu/media/exynos_video_encode_accelerator.h
deleted file mode 100644
index 89bcd8e..0000000
--- a/content/common/gpu/media/exynos_video_encode_accelerator.h
+++ /dev/null
@@ -1,308 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_
-#define CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_
-
-#include <list>
-#include <vector>
-
-#include "base/memory/linked_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread.h"
-#include "content/common/content_export.h"
-#include "media/video/video_encode_accelerator.h"
-#include "ui/gfx/size.h"
-
-namespace base {
-
-class MessageLoopProxy;
-
-}  // namespace base
-
-namespace media {
-
-class BitstreamBuffer;
-
-}  // namespace media
-
-namespace content {
-
-// This class handles Exynos video encode acceleration by interfacing with the
-// V4L2 devices exported by the Multi Format Codec and GScaler hardware blocks
-// on the Exynos platform.  The threading model of this class is the same as the
-// ExynosVideoDecodeAccelerator (from which class this was designed).
-class CONTENT_EXPORT ExynosVideoEncodeAccelerator
-    : public media::VideoEncodeAccelerator {
- public:
-  ExynosVideoEncodeAccelerator();
-  virtual ~ExynosVideoEncodeAccelerator();
-
-  // media::VideoEncodeAccelerator implementation.
-  virtual bool Initialize(media::VideoFrame::Format format,
-                          const gfx::Size& input_visible_size,
-                          media::VideoCodecProfile output_profile,
-                          uint32 initial_bitrate,
-                          Client* client) OVERRIDE;
-  virtual void Encode(const scoped_refptr<media::VideoFrame>& frame,
-                      bool force_keyframe) OVERRIDE;
-  virtual void UseOutputBitstreamBuffer(
-      const media::BitstreamBuffer& buffer) OVERRIDE;
-  virtual void RequestEncodingParametersChange(uint32 bitrate,
-                                               uint32 framerate) OVERRIDE;
-  virtual void Destroy() OVERRIDE;
-
-  static std::vector<media::VideoEncodeAccelerator::SupportedProfile>
-      GetSupportedProfiles();
-
- private:
-  // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to
-  // this instance.
-  struct BitstreamBufferRef;
-
-  // Record for GSC input buffers.
-  struct GscInputRecord {
-    GscInputRecord();
-    bool at_device;
-    scoped_refptr<media::VideoFrame> frame;
-  };
-
-  // Record for GSC output buffers.
-  struct GscOutputRecord {
-    GscOutputRecord();
-    bool at_device;
-    int mfc_input;
-  };
-
-  // Record for MFC input buffers.
-  struct MfcInputRecord {
-    MfcInputRecord();
-    bool at_device;
-    int fd[2];
-  };
-
-  // Record for MFC output buffers.
-  struct MfcOutputRecord {
-    MfcOutputRecord();
-    bool at_device;
-    linked_ptr<BitstreamBufferRef> buffer_ref;
-    void* address;
-    size_t length;
-  };
-
-  enum {
-    kInitialFramerate = 30,
-    // These are rather subjectively tuned.
-    kGscInputBufferCount = 2,
-    kGscOutputBufferCount = 2,
-    kMfcOutputBufferCount = 2,
-    // MFC hardware does not report required output buffer size correctly.
-    // Use maximum theoretical size to avoid hanging the hardware.
-    kMfcOutputBufferSize = (2 * 1024 * 1024),
-  };
-
-  // Internal state of the encoder.
-  enum State {
-    kUninitialized,  // Initialize() not yet called.
-    kInitialized,    // Initialize() returned true; ready to start encoding.
-    kEncoding,       // Encoding frames.
-    kError,          // Error in encoder state.
-  };
-
-  //
-  // Encoding tasks, to be run on encode_thread_.
-  //
-
-  // Encode a GSC input buffer.
-  void EncodeTask(const scoped_refptr<media::VideoFrame>& frame,
-                  bool force_keyframe);
-
-  // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder
-  // output.
-  void UseOutputBitstreamBufferTask(scoped_ptr<BitstreamBufferRef> buffer_ref);
-
-  // Device destruction task.
-  void DestroyTask();
-
-  // Service I/O on the V4L2 devices.  This task should only be scheduled from
-  // DevicePollTask().
-  void ServiceDeviceTask();
-
-  // Handle the various device queues.
-  void EnqueueGsc();
-  void DequeueGsc();
-  void EnqueueMfc();
-  void DequeueMfc();
-  // Enqueue a buffer on the corresponding queue.  Returns false on fatal error.
-  bool EnqueueGscInputRecord();
-  bool EnqueueGscOutputRecord();
-  bool EnqueueMfcInputRecord();
-  bool EnqueueMfcOutputRecord();
-
-  // Attempt to start/stop device_poll_thread_.
-  bool StartDevicePoll();
-  bool StopDevicePoll();
-  // Set/clear the device poll interrupt (using device_poll_interrupt_fd_).
-  bool SetDevicePollInterrupt();
-  bool ClearDevicePollInterrupt();
-
-  //
-  // Device tasks, to be run on device_poll_thread_.
-  //
-
-  // The device task.
-  void DevicePollTask(unsigned int poll_fds);
-
-  //
-  // Safe from any thread.
-  //
-
-  // Error notification (using PostTask() to child thread, if necessary).
-  void NotifyError(Error error);
-
-  // Set the encoder_thread_ state (using PostTask to encoder thread, if
-  // necessary).
-  void SetEncoderState(State state);
-
-  //
-  // Other utility functions.  Called on encoder_thread_, unless
-  // encoder_thread_ is not yet started, in which case the child thread can call
-  // these (e.g. in Initialize() or Destroy()).
-  //
-
-  // Change the parameters of encoding.
-  void RequestEncodingParametersChangeTask(uint32 bitrate, uint32 framerate);
-
-  // Create the buffers we need.
-  bool CreateGscInputBuffers();
-  bool CreateGscOutputBuffers();
-  bool SetMfcFormats();
-  bool InitMfcControls();
-  bool CreateMfcInputBuffers();
-  bool CreateMfcOutputBuffers();
-
-  // Destroy these buffers.
-  void DestroyGscInputBuffers();
-  void DestroyGscOutputBuffers();
-  void DestroyMfcInputBuffers();
-  void DestroyMfcOutputBuffers();
-
-  // Our original calling message loop for the child thread.
-  const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_;
-
-  // WeakPtr<> pointing to |this| for use in posting tasks from the encoder or
-  // device worker threads back to the child thread.  Because the worker threads
-  // are members of this class, any task running on those threads is guaranteed
-  // that this object is still alive.  As a result, tasks posted from the child
-  // thread to the encoder or device thread should use base::Unretained(this),
-  // and tasks posted the other way should use |weak_this_|.
-  base::WeakPtrFactory<ExynosVideoEncodeAccelerator> weak_this_ptr_factory_;
-  base::WeakPtr<ExynosVideoEncodeAccelerator> weak_this_;
-
-  // To expose client callbacks from VideoEncodeAccelerator.
-  // NOTE: all calls to these objects *MUST* be executed on
-  // child_message_loop_proxy_.
-  scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_;
-  base::WeakPtr<Client> client_;
-
-  //
-  // Encoder state, owned and operated by encoder_thread_.
-  // Before encoder_thread_ has started, the encoder state is managed by
-  // the child (main) thread.  After encoder_thread_ has started, the encoder
-  // thread should be the only one managing these.
-  //
-
-  // This thread services tasks posted from the VEA API entry points by the
-  // child thread and device service callbacks posted from the device thread.
-  base::Thread encoder_thread_;
-  // Encoder state.
-  State encoder_state_;
-  // The visible/allocated sizes of the input frame.
-  gfx::Size input_visible_size_;
-  gfx::Size input_allocated_size_;
-  // The visible/allocated sizes of the color-converted intermediate frame.
-  gfx::Size converted_visible_size_;
-  gfx::Size converted_allocated_size_;
-  // The logical visible size of the output frame.
-  gfx::Size output_visible_size_;
-  // The required byte size of output BitstreamBuffers.
-  size_t output_buffer_byte_size_;
-
-  // We need to provide the stream header with every keyframe, to allow
-  // midstream decoding restarts.  Store it here.
-  scoped_ptr<uint8[]> stream_header_;
-  size_t stream_header_size_;
-
-  // V4L2 formats for input frames and the output stream.
-  uint32 input_format_fourcc_;
-  uint32 output_format_fourcc_;
-
-  // Video frames ready to be encoded.
-  std::list<scoped_refptr<media::VideoFrame> > encoder_input_queue_;
-
-  // GSC color conversion device.
-  int gsc_fd_;
-  // GSC input queue state.
-  bool gsc_input_streamon_;
-  // GSC input buffers enqueued to device.
-  int gsc_input_buffer_queued_count_;
-  // GSC input buffers ready to use; LIFO since we don't care about ordering.
-  std::vector<int> gsc_free_input_buffers_;
-  // Mapping of int index to GSC input buffer record.
-  std::vector<GscInputRecord> gsc_input_buffer_map_;
-
-  // GSC output queue state.
-  bool gsc_output_streamon_;
-  // GSC output buffers enqueued to device.
-  int gsc_output_buffer_queued_count_;
-  // GSC output buffers ready to use; LIFO since we don't care about ordering.
-  std::vector<int> gsc_free_output_buffers_;
-  // Mapping of int index to GSC output buffer record.
-  std::vector<GscOutputRecord> gsc_output_buffer_map_;
-
-  // MFC input buffers filled by GSC, waiting to be queued to MFC.
-  std::list<int> mfc_ready_input_buffers_;
-
-  // MFC video encoding device.
-  int mfc_fd_;
-
-  // MFC input queue state.
-  bool mfc_input_streamon_;
-  // MFC input buffers enqueued to device.
-  int mfc_input_buffer_queued_count_;
-  // MFC input buffers ready to use; LIFO since we don't care about ordering.
-  std::vector<int> mfc_free_input_buffers_;
-  // Mapping of int index to MFC input buffer record.
-  std::vector<MfcInputRecord> mfc_input_buffer_map_;
-
-  // MFC output queue state.
-  bool mfc_output_streamon_;
-  // MFC output buffers enqueued to device.
-  int mfc_output_buffer_queued_count_;
-  // MFC output buffers ready to use; LIFO since we don't care about ordering.
-  std::vector<int> mfc_free_output_buffers_;
-  // Mapping of int index to MFC output buffer record.
-  std::vector<MfcOutputRecord> mfc_output_buffer_map_;
-
-  // Bitstream buffers ready to be used to return encoded output, as a LIFO
-  // since we don't care about ordering.
-  std::vector<linked_ptr<BitstreamBufferRef> > encoder_output_queue_;
-
-  //
-  // The device polling thread handles notifications of V4L2 device changes.
-  // TODO(sheu): replace this thread with an TYPE_IO encoder_thread_.
-  //
-
-  // The thread.
-  base::Thread device_poll_thread_;
-  // eventfd fd to signal device poll thread when its poll() should be
-  // interrupted.
-  int device_poll_interrupt_fd_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExynosVideoEncodeAccelerator);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_COMMON_GPU_MEDIA_EXYNOS_VIDEO_ENCODE_ACCELERATOR_H_
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc
index 69f8313..1e1b15c 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.cc
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -252,18 +252,18 @@
   video_decode_accelerator_.reset(
       new DXVAVideoDecodeAccelerator(make_context_current_));
 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
-  scoped_ptr<V4L2Device> device =
-      V4L2Device::Create(stub_->decoder()->GetGLContext()->GetHandle());
+  scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
   if (!device.get()) {
     SendCreateDecoderReply(init_done_msg, false);
     return;
   }
-  video_decode_accelerator_.reset(
-      new V4L2VideoDecodeAccelerator(gfx::GLSurfaceEGL::GetHardwareDisplay(),
-                                     weak_factory_for_io_.GetWeakPtr(),
-                                     make_context_current_,
-                                     device.Pass(),
-                                     io_message_loop_));
+  video_decode_accelerator_.reset(new V4L2VideoDecodeAccelerator(
+      gfx::GLSurfaceEGL::GetHardwareDisplay(),
+      stub_->decoder()->GetGLContext()->GetHandle(),
+      weak_factory_for_io_.GetWeakPtr(),
+      make_context_current_,
+      device.Pass(),
+      io_message_loop_));
 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11)
   if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
     VLOG(1) << "HW video decode acceleration not available without "
diff --git a/content/common/gpu/media/gpu_video_encode_accelerator.cc b/content/common/gpu/media/gpu_video_encode_accelerator.cc
index c47ef0f..3a6deec 100644
--- a/content/common/gpu/media/gpu_video_encode_accelerator.cc
+++ b/content/common/gpu/media/gpu_video_encode_accelerator.cc
@@ -16,7 +16,7 @@
 #include "media/base/video_frame.h"
 
 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
-#include "content/common/gpu/media/exynos_video_encode_accelerator.h"
+#include "content/common/gpu/media/v4l2_video_encode_accelerator.h"
 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
 #include "content/common/gpu/media/android_video_encode_accelerator.h"
 #endif
@@ -162,7 +162,7 @@
   std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles;
 
 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
-  profiles = ExynosVideoEncodeAccelerator::GetSupportedProfiles();
+  profiles = V4L2VideoEncodeAccelerator::GetSupportedProfiles();
 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
   profiles = AndroidVideoEncodeAccelerator::GetSupportedProfiles();
 #endif
@@ -174,7 +174,11 @@
 void GpuVideoEncodeAccelerator::CreateEncoder() {
   DCHECK(!encoder_);
 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
-  encoder_.reset(new ExynosVideoEncodeAccelerator());
+  scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder);
+  if (!device.get())
+    return;
+
+  encoder_.reset(new V4L2VideoEncodeAccelerator(device.Pass()));
 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
   encoder_.reset(new AndroidVideoEncodeAccelerator());
 #endif
diff --git a/content/common/gpu/media/tegra_v4l2_video_device.cc b/content/common/gpu/media/tegra_v4l2_video_device.cc
index c844337..43c3401 100644
--- a/content/common/gpu/media/tegra_v4l2_video_device.cc
+++ b/content/common/gpu/media/tegra_v4l2_video_device.cc
@@ -15,7 +15,8 @@
 namespace content {
 
 namespace {
-const char kDevice[] = "/dev/tegra_avpchannel";
+const char kDecoderDevice[] = "/dev/tegra_avpchannel";
+const char kEncoderDevice[] = "/dev/nvhost-msenc";
 }
 
 typedef int32 (*TegraV4L2Open)(const char* name, int32 flags);
@@ -89,8 +90,10 @@
 base::LazyInstance<TegraFunctionSymbolFinder> g_tegra_function_symbol_finder_ =
     LAZY_INSTANCE_INITIALIZER;
 
-TegraV4L2Device::TegraV4L2Device(EGLContext egl_context)
-    : device_fd_(-1), egl_context_(egl_context) {}
+TegraV4L2Device::TegraV4L2Device(Type type)
+    : type_(type),
+      device_fd_(-1) {
+}
 
 TegraV4L2Device::~TegraV4L2Device() {
   if (device_fd_ != -1) {
@@ -100,7 +103,7 @@
 }
 
 int TegraV4L2Device::Ioctl(int flags, void* arg) {
-  return TegraV4L2_Ioctl(device_fd_, flags, arg);
+  return HANDLE_EINTR(TegraV4L2_Ioctl(device_fd_, flags, arg));
 }
 
 bool TegraV4L2Device::Poll(bool poll_device, bool* event_pending) {
@@ -141,20 +144,34 @@
 }
 
 bool TegraV4L2Device::Initialize() {
+  const char* device_path = NULL;
+  switch (type_) {
+    case kDecoder:
+      device_path = kDecoderDevice;
+      break;
+    case kEncoder:
+      device_path = kEncoderDevice;
+      break;
+    case kImageProcessor:
+      DVLOG(1) << "Device type " << type_ << " not supported on this platform";
+      return false;
+  }
+
   if (!g_tegra_function_symbol_finder_.Get().initialized()) {
     DLOG(ERROR) << "Unable to initialize functions ";
     return false;
   }
-  device_fd_ =
-      HANDLE_EINTR(TegraV4L2_Open(kDevice, O_RDWR | O_NONBLOCK | O_CLOEXEC));
+  device_fd_ = HANDLE_EINTR(
+      TegraV4L2_Open(device_path, O_RDWR | O_NONBLOCK | O_CLOEXEC));
   if (device_fd_ == -1) {
-    DLOG(ERROR) << "Unable to open tegra_v4l2_open ";
+    DLOG(ERROR) << "Unable to open device " << device_path;
     return false;
   }
   return true;
 }
 
 EGLImageKHR TegraV4L2Device::CreateEGLImage(EGLDisplay egl_display,
+                                            EGLContext egl_context,
                                             GLuint texture_id,
                                             gfx::Size /* frame_buffer_size */,
                                             unsigned int buffer_index,
@@ -163,7 +180,7 @@
   EGLint attr = EGL_NONE;
   EGLImageKHR egl_image =
       eglCreateImageKHR(egl_display,
-                        egl_context_,
+                        egl_context,
                         EGL_GL_TEXTURE_2D_KHR,
                         reinterpret_cast<EGLClientBuffer>(texture_id),
                         &attr);
@@ -184,6 +201,18 @@
 
 GLenum TegraV4L2Device::GetTextureTarget() { return GL_TEXTURE_2D; }
 
-uint32 TegraV4L2Device::PreferredOutputFormat() { return V4L2_PIX_FMT_NV12M; }
+uint32 TegraV4L2Device::PreferredInputFormat() {
+  // TODO(posciak): We should support "dontcare" returns here once we
+  // implement proper handling (fallback, negotiation) for this in users.
+  CHECK_EQ(type_, kEncoder);
+  return V4L2_PIX_FMT_YUV420M;
+}
+
+uint32 TegraV4L2Device::PreferredOutputFormat() {
+  // TODO(posciak): We should support "dontcare" returns here once we
+  // implement proper handling (fallback, negotiation) for this in users.
+  CHECK_EQ(type_, kDecoder);
+  return V4L2_PIX_FMT_NV12M;
+}
 
 }  //  namespace content
diff --git a/content/common/gpu/media/tegra_v4l2_video_device.h b/content/common/gpu/media/tegra_v4l2_video_device.h
index 62ade4d..e588951 100644
--- a/content/common/gpu/media/tegra_v4l2_video_device.h
+++ b/content/common/gpu/media/tegra_v4l2_video_device.h
@@ -18,7 +18,7 @@
 // V4L2 specification via the library API instead of system calls.
 class TegraV4L2Device : public V4L2Device {
  public:
-  explicit TegraV4L2Device(EGLContext egl_context);
+  explicit TegraV4L2Device(Type type);
   virtual ~TegraV4L2Device();
 
   virtual int Ioctl(int flags, void* arg) OVERRIDE;
@@ -33,6 +33,7 @@
   virtual void Munmap(void* addr, unsigned int len) OVERRIDE;
   virtual bool Initialize() OVERRIDE;
   virtual EGLImageKHR CreateEGLImage(EGLDisplay egl_display,
+                                     EGLContext egl_context,
                                      GLuint texture_id,
                                      gfx::Size frame_buffer_size,
                                      unsigned int buffer_index,
@@ -40,15 +41,15 @@
   virtual EGLBoolean DestroyEGLImage(EGLDisplay egl_display,
                                      EGLImageKHR egl_image) OVERRIDE;
   virtual GLenum GetTextureTarget() OVERRIDE;
+  virtual uint32 PreferredInputFormat() OVERRIDE;
   virtual uint32 PreferredOutputFormat() OVERRIDE;
 
  private:
+  const Type type_;
+
   // The actual device fd.
   int device_fd_;
 
-  // The EGLContext associated with this device.
-  EGLContext egl_context_;
-
   DISALLOW_COPY_AND_ASSIGN(TegraV4L2Device);
 };
 
diff --git a/content/common/gpu/media/v4l2_image_processor.cc b/content/common/gpu/media/v4l2_image_processor.cc
new file mode 100644
index 0000000..67303da
--- /dev/null
+++ b/content/common/gpu/media/v4l2_image_processor.cc
@@ -0,0 +1,717 @@
+// 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.
+
+#include <fcntl.h>
+#include <linux/videodev2.h>
+#include <poll.h>
+#include <sys/eventfd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/numerics/safe_conversions.h"
+#include "content/common/gpu/media/v4l2_image_processor.h"
+#include "media/base/bind_to_current_loop.h"
+
+#define NOTIFY_ERROR()                      \
+  do {                                      \
+    DLOG(ERROR) << "calling NotifyError()"; \
+    NotifyError();                          \
+  } while (0)
+
+#define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value)              \
+  do {                                                             \
+    if (device_->Ioctl(type, arg) != 0) {                          \
+      DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
+      return value;                                                \
+    }                                                              \
+  } while (0)
+
+#define IOCTL_OR_ERROR_RETURN(type, arg) \
+  IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0))
+
+#define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
+  IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false)
+
+#define IOCTL_OR_LOG_ERROR(type, arg)                              \
+  do {                                                             \
+    if (device_->Ioctl(type, arg) != 0)                            \
+      DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
+  } while (0)
+
+namespace content {
+
+V4L2ImageProcessor::InputRecord::InputRecord() : at_device(false) {
+}
+
+V4L2ImageProcessor::OutputRecord::OutputRecord()
+    : at_device(false), at_client(false) {
+}
+
+V4L2ImageProcessor::JobRecord::JobRecord() {
+}
+
+V4L2ImageProcessor::V4L2ImageProcessor(scoped_ptr<V4L2Device> device)
+    : input_format_(media::VideoFrame::UNKNOWN),
+      output_format_(media::VideoFrame::UNKNOWN),
+      input_format_fourcc_(0),
+      output_format_fourcc_(0),
+      input_planes_count_(0),
+      output_planes_count_(0),
+      child_message_loop_proxy_(base::MessageLoopProxy::current()),
+      device_(device.Pass()),
+      device_thread_("V4L2ImageProcessorThread"),
+      device_poll_thread_("V4L2ImageProcessorDevicePollThread"),
+      input_streamon_(false),
+      input_buffer_queued_count_(0),
+      output_streamon_(false),
+      output_buffer_queued_count_(0),
+      device_weak_factory_(this) {
+}
+
+V4L2ImageProcessor::~V4L2ImageProcessor() {
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(!device_thread_.IsRunning());
+  DCHECK(!device_poll_thread_.IsRunning());
+
+  DestroyInputBuffers();
+  DestroyOutputBuffers();
+}
+
+void V4L2ImageProcessor::NotifyError() {
+  if (!child_message_loop_proxy_->BelongsToCurrentThread())
+    child_message_loop_proxy_->PostTask(FROM_HERE, error_cb_);
+  else
+    error_cb_.Run();
+}
+
+bool V4L2ImageProcessor::Initialize(media::VideoFrame::Format input_format,
+                                    media::VideoFrame::Format output_format,
+                                    gfx::Size input_visible_size,
+                                    gfx::Size output_visible_size,
+                                    gfx::Size output_allocated_size,
+                                    const base::Closure& error_cb) {
+  DCHECK(!error_cb.is_null());
+  error_cb_ = error_cb;
+
+  // TODO(posciak): Replace Exynos-specific format/parameter hardcoding in this
+  // class with proper capability enumeration.
+  DCHECK_EQ(input_format, media::VideoFrame::I420);
+  DCHECK_EQ(output_format, media::VideoFrame::NV12);
+
+  input_format_ = input_format;
+  output_format_ = output_format;
+  input_format_fourcc_ = V4L2Device::VideoFrameFormatToV4L2PixFmt(input_format);
+  output_format_fourcc_ =
+      V4L2Device::VideoFrameFormatToV4L2PixFmt(output_format);
+
+  if (!input_format_fourcc_ || !output_format_fourcc_) {
+    DLOG(ERROR) << "Unrecognized format(s)";
+    return false;
+  }
+
+  input_visible_size_ = input_visible_size;
+  output_visible_size_ = output_visible_size;
+  output_allocated_size_ = output_allocated_size;
+
+  input_planes_count_ = media::VideoFrame::NumPlanes(input_format);
+  DCHECK_LE(input_planes_count_, VIDEO_MAX_PLANES);
+  output_planes_count_ = media::VideoFrame::NumPlanes(output_format);
+  DCHECK_LE(output_planes_count_, VIDEO_MAX_PLANES);
+
+  // Capabilities check.
+  struct v4l2_capability caps;
+  memset(&caps, 0, sizeof(caps));
+  const __u32 kCapsRequired = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+                              V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
+  if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
+    DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
+                   "caps check failed: 0x" << std::hex << caps.capabilities;
+    return false;
+  }
+
+  if (!CreateInputBuffers() || !CreateOutputBuffers())
+    return false;
+
+  if (!device_thread_.Start()) {
+    DLOG(ERROR) << "Initialize(): encoder thread failed to start";
+    return false;
+  }
+
+  // StartDevicePoll will NOTIFY_ERROR on failure, so IgnoreResult is fine here.
+  device_thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(base::IgnoreResult(&V4L2ImageProcessor::StartDevicePoll),
+                 base::Unretained(this)));
+
+  DVLOG(1) << "V4L2ImageProcessor initialized for "
+           << " input_format:"
+           << media::VideoFrame::FormatToString(input_format)
+           << ", output_format:"
+           << media::VideoFrame::FormatToString(output_format)
+           << ", input_visible_size: " << input_visible_size.ToString()
+           << ", input_allocated_size: " << input_allocated_size_.ToString()
+           << ", output_visible_size: " << output_visible_size.ToString()
+           << ", output_allocated_size: " << output_allocated_size.ToString();
+
+  return true;
+}
+
+void V4L2ImageProcessor::Process(const scoped_refptr<media::VideoFrame>& frame,
+                                 const FrameReadyCB& cb) {
+  DVLOG(3) << __func__ << ": ts=" << frame->timestamp().InMilliseconds();
+
+  scoped_ptr<JobRecord> job_record(new JobRecord());
+  job_record->frame = frame;
+  job_record->ready_cb = cb;
+
+  device_thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&V4L2ImageProcessor::ProcessTask,
+                 base::Unretained(this),
+                 base::Passed(&job_record)));
+}
+
+void V4L2ImageProcessor::ProcessTask(scoped_ptr<JobRecord> job_record) {
+  DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current());
+
+  input_queue_.push(make_linked_ptr(job_record.release()));
+  Enqueue();
+}
+
+void V4L2ImageProcessor::Destroy() {
+  DVLOG(3) << __func__;
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+
+  // If the device thread is running, destroy using posted task.
+  if (device_thread_.IsRunning()) {
+    device_thread_.message_loop()->PostTask(
+        FROM_HERE,
+        base::Bind(&V4L2ImageProcessor::DestroyTask, base::Unretained(this)));
+    // Wait for tasks to finish/early-exit.
+    device_thread_.Stop();
+  } else {
+    // Otherwise DestroyTask() is not needed.
+    DCHECK(!device_poll_thread_.IsRunning());
+    DCHECK(!device_weak_factory_.HasWeakPtrs());
+  }
+
+  delete this;
+}
+
+void V4L2ImageProcessor::DestroyTask() {
+  DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current());
+
+  device_weak_factory_.InvalidateWeakPtrs();
+
+  // Stop streaming and the device_poll_thread_.
+  StopDevicePoll();
+}
+
+bool V4L2ImageProcessor::CreateInputBuffers() {
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(!input_streamon_);
+
+  struct v4l2_control control;
+  memset(&control, 0, sizeof(control));
+  control.id = V4L2_CID_ROTATE;
+  control.value = 0;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CTRL, &control);
+
+  memset(&control, 0, sizeof(control));
+  control.id = V4L2_CID_HFLIP;
+  control.value = 0;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CTRL, &control);
+
+  memset(&control, 0, sizeof(control));
+  control.id = V4L2_CID_VFLIP;
+  control.value = 0;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CTRL, &control);
+
+  memset(&control, 0, sizeof(control));
+  control.id = V4L2_CID_ALPHA_COMPONENT;
+  control.value = 255;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CTRL, &control);
+
+  struct v4l2_format format;
+  memset(&format, 0, sizeof(format));
+  format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  format.fmt.pix_mp.width = input_visible_size_.width();
+  format.fmt.pix_mp.height = input_visible_size_.height();
+  format.fmt.pix_mp.pixelformat = input_format_fourcc_;
+  format.fmt.pix_mp.num_planes = input_planes_count_;
+  for (size_t i = 0; i < input_planes_count_; ++i) {
+    format.fmt.pix_mp.plane_fmt[i].sizeimage =
+        media::VideoFrame::PlaneAllocationSize(
+            input_format_, i, input_allocated_size_);
+    format.fmt.pix_mp.plane_fmt[i].bytesperline =
+        base::checked_cast<__u32>(input_allocated_size_.width());
+  }
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format);
+
+  input_allocated_size_ = V4L2Device::CodedSizeFromV4L2Format(format);
+  DCHECK(gfx::Rect(input_allocated_size_).Contains(
+      gfx::Rect(input_visible_size_)));
+
+  struct v4l2_crop crop;
+  memset(&crop, 0, sizeof(crop));
+  crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  crop.c.left = 0;
+  crop.c.top = 0;
+  crop.c.width = base::checked_cast<__u32>(input_visible_size_.width());
+  crop.c.height = base::checked_cast<__u32>(input_visible_size_.height());
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CROP, &crop);
+
+  struct v4l2_requestbuffers reqbufs;
+  memset(&reqbufs, 0, sizeof(reqbufs));
+  reqbufs.count = kInputBufferCount;
+  reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  reqbufs.memory = V4L2_MEMORY_USERPTR;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs);
+
+  DCHECK(input_buffer_map_.empty());
+  input_buffer_map_.resize(reqbufs.count);
+
+  for (size_t i = 0; i < input_buffer_map_.size(); ++i)
+    free_input_buffers_.push_back(i);
+
+  return true;
+}
+
+bool V4L2ImageProcessor::CreateOutputBuffers() {
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(!output_streamon_);
+
+  struct v4l2_format format;
+  memset(&format, 0, sizeof(format));
+  format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  format.fmt.pix_mp.width = output_allocated_size_.width();
+  format.fmt.pix_mp.height = output_allocated_size_.height();
+  format.fmt.pix_mp.pixelformat = output_format_fourcc_;
+  format.fmt.pix_mp.num_planes = output_planes_count_;
+  for (size_t i = 0; i < output_planes_count_; ++i) {
+    format.fmt.pix_mp.plane_fmt[i].sizeimage =
+        media::VideoFrame::PlaneAllocationSize(
+            output_format_, i, output_allocated_size_);
+    format.fmt.pix_mp.plane_fmt[i].bytesperline =
+        base::checked_cast<__u32>(output_allocated_size_.width());
+  }
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format);
+
+  gfx::Size adjusted_allocated_size =
+      V4L2Device::CodedSizeFromV4L2Format(format);
+  DCHECK(gfx::Rect(adjusted_allocated_size).Contains(
+      gfx::Rect(output_allocated_size_)));
+  output_allocated_size_ = adjusted_allocated_size;
+
+  struct v4l2_crop crop;
+  memset(&crop, 0, sizeof(crop));
+  crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  crop.c.left = 0;
+  crop.c.top = 0;
+  crop.c.width = base::checked_cast<__u32>(output_visible_size_.width());
+  crop.c.height = base::checked_cast<__u32>(output_visible_size_.height());
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CROP, &crop);
+
+  struct v4l2_requestbuffers reqbufs;
+  memset(&reqbufs, 0, sizeof(reqbufs));
+  reqbufs.count = kOutputBufferCount;
+  reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  reqbufs.memory = V4L2_MEMORY_MMAP;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs);
+
+  DCHECK(output_buffer_map_.empty());
+  output_buffer_map_.resize(reqbufs.count);
+  for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
+    OutputRecord& output_record = output_buffer_map_[i];
+    output_record.fds.resize(output_planes_count_);
+    for (size_t j = 0; j < output_planes_count_; ++j) {
+      struct v4l2_exportbuffer expbuf;
+      memset(&expbuf, 0, sizeof(expbuf));
+      expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+      expbuf.index = i;
+      expbuf.plane = j;
+      expbuf.flags = O_CLOEXEC;
+      IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_EXPBUF, &expbuf);
+      output_record.fds[j] = expbuf.fd;
+    }
+    free_output_buffers_.push_back(i);
+  }
+
+  return true;
+}
+
+void V4L2ImageProcessor::DestroyInputBuffers() {
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(!input_streamon_);
+
+  struct v4l2_requestbuffers reqbufs;
+  memset(&reqbufs, 0, sizeof(reqbufs));
+  reqbufs.count = 0;
+  reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  reqbufs.memory = V4L2_MEMORY_USERPTR;
+  IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
+
+  input_buffer_map_.clear();
+  free_input_buffers_.clear();
+}
+
+void V4L2ImageProcessor::DestroyOutputBuffers() {
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(!output_streamon_);
+
+  for (size_t buf = 0; buf < output_buffer_map_.size(); ++buf) {
+    OutputRecord& output_record = output_buffer_map_[buf];
+    for (size_t plane = 0; plane < output_record.fds.size(); ++plane)
+      close(output_record.fds[plane]);
+    output_record.fds.clear();
+  }
+
+  struct v4l2_requestbuffers reqbufs;
+  memset(&reqbufs, 0, sizeof(reqbufs));
+  reqbufs.count = 0;
+  reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  reqbufs.memory = V4L2_MEMORY_MMAP;
+  IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
+
+  output_buffer_map_.clear();
+  free_output_buffers_.clear();
+}
+
+void V4L2ImageProcessor::DevicePollTask(bool poll_device) {
+  DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current());
+
+  bool event_pending;
+  if (!device_->Poll(poll_device, &event_pending)) {
+    NOTIFY_ERROR();
+    return;
+  }
+
+  // All processing should happen on ServiceDeviceTask(), since we shouldn't
+  // touch encoder state from this thread.
+  device_thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&V4L2ImageProcessor::ServiceDeviceTask,
+                 base::Unretained(this)));
+}
+
+void V4L2ImageProcessor::ServiceDeviceTask() {
+  DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current());
+  // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
+  // so either:
+  // * device_poll_thread_ is running normally
+  // * device_poll_thread_ scheduled us, but then a DestroyTask() shut it down,
+  //   in which case we should early-out.
+  if (!device_poll_thread_.message_loop())
+    return;
+
+  Dequeue();
+  Enqueue();
+
+  if (!device_->ClearDevicePollInterrupt())
+    return;
+
+  bool poll_device =
+      (input_buffer_queued_count_ > 0 && output_buffer_queued_count_ > 0);
+
+  device_poll_thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&V4L2ImageProcessor::DevicePollTask,
+                 base::Unretained(this),
+                 poll_device));
+
+  DVLOG(2) << __func__ << ": buffer counts: INPUT["
+           << input_queue_.size() << "] => DEVICE["
+           << free_input_buffers_.size() << "+"
+           << input_buffer_queued_count_ << "/"
+           << input_buffer_map_.size() << "->"
+           << free_output_buffers_.size() << "+"
+           << output_buffer_queued_count_ << "/"
+           << output_buffer_map_.size() << "] => CLIENT["
+           << output_buffer_map_.size() - output_buffer_queued_count_ -
+              free_output_buffers_.size() << "]";
+}
+
+void V4L2ImageProcessor::Enqueue() {
+  DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current());
+
+  const int old_inputs_queued = input_buffer_queued_count_;
+  while (!input_queue_.empty() && !free_input_buffers_.empty()) {
+    if (!EnqueueInputRecord())
+      return;
+  }
+  if (old_inputs_queued == 0 && input_buffer_queued_count_ != 0) {
+    // We started up a previously empty queue.
+    // Queue state changed; signal interrupt.
+    if (!device_->SetDevicePollInterrupt())
+      return;
+    // VIDIOC_STREAMON if we haven't yet.
+    if (!input_streamon_) {
+      __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+      IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
+      input_streamon_ = true;
+    }
+  }
+
+  // TODO(posciak): Fix this to be non-Exynos specific.
+  // Exynos GSC is liable to race conditions if more than one output buffer is
+  // simultaneously enqueued, so enqueue just one.
+  if (output_buffer_queued_count_ == 0 && !free_output_buffers_.empty()) {
+    const int old_outputs_queued = output_buffer_queued_count_;
+    if (!EnqueueOutputRecord())
+      return;
+    if (old_outputs_queued == 0 && output_buffer_queued_count_ != 0) {
+      // We just started up a previously empty queue.
+      // Queue state changed; signal interrupt.
+      if (!device_->SetDevicePollInterrupt())
+        return;
+      // Start VIDIOC_STREAMON if we haven't yet.
+      if (!output_streamon_) {
+        __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+        IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
+        output_streamon_ = true;
+      }
+    }
+  }
+  DCHECK_LE(output_buffer_queued_count_, 1);
+}
+
+void V4L2ImageProcessor::Dequeue() {
+  DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current());
+
+  // Dequeue completed input (VIDEO_OUTPUT) buffers,
+  // and recycle to the free list.
+  struct v4l2_buffer dqbuf;
+  struct v4l2_plane planes[VIDEO_MAX_PLANES];
+  while (input_buffer_queued_count_ > 0) {
+    DCHECK(input_streamon_);
+    memset(&dqbuf, 0, sizeof(dqbuf));
+    memset(&planes, 0, sizeof(planes));
+    dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    dqbuf.memory = V4L2_MEMORY_USERPTR;
+    dqbuf.m.planes = planes;
+    dqbuf.length = input_planes_count_;
+    if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) {
+      if (errno == EAGAIN) {
+        // EAGAIN if we're just out of buffers to dequeue.
+        break;
+      }
+      DPLOG(ERROR) << "ioctl() failed: VIDIOC_DQBUF";
+      NOTIFY_ERROR();
+      return;
+    }
+    InputRecord& input_record = input_buffer_map_[dqbuf.index];
+    DCHECK(input_record.at_device);
+    input_record.at_device = false;
+    input_record.frame = NULL;
+    free_input_buffers_.push_back(dqbuf.index);
+    input_buffer_queued_count_--;
+  }
+
+  // Dequeue completed output (VIDEO_CAPTURE) buffers, recycle to the free list.
+  // Return the finished buffer to the client via the job ready callback.
+  while (output_buffer_queued_count_ > 0) {
+    DCHECK(output_streamon_);
+    memset(&dqbuf, 0, sizeof(dqbuf));
+    memset(&planes, 0, sizeof(planes));
+    dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    dqbuf.memory = V4L2_MEMORY_DMABUF;
+    dqbuf.m.planes = planes;
+    dqbuf.length = output_planes_count_;
+    if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) {
+      if (errno == EAGAIN) {
+        // EAGAIN if we're just out of buffers to dequeue.
+        break;
+      }
+      DPLOG(ERROR) << "ioctl() failed: VIDIOC_DQBUF";
+      NOTIFY_ERROR();
+      return;
+    }
+    OutputRecord& output_record = output_buffer_map_[dqbuf.index];
+    DCHECK(output_record.at_device);
+    output_record.at_device = false;
+    output_record.at_client = true;
+    output_buffer_queued_count_--;
+
+    // Jobs are always processed in FIFO order.
+    DCHECK(!running_jobs_.empty());
+    linked_ptr<JobRecord> job_record = running_jobs_.front();
+    running_jobs_.pop();
+
+    scoped_refptr<media::VideoFrame> output_frame =
+        media::VideoFrame::WrapExternalDmabufs(
+            output_format_,
+            output_allocated_size_,
+            gfx::Rect(output_visible_size_),
+            output_visible_size_,
+            output_record.fds,
+            job_record->frame->timestamp(),
+            media::BindToCurrentLoop(
+                base::Bind(&V4L2ImageProcessor::ReuseOutputBuffer,
+                           device_weak_factory_.GetWeakPtr(),
+                           dqbuf.index)));
+
+    DVLOG(3) << "Processing finished, returning frame, ts="
+             << output_frame->timestamp().InMilliseconds();
+
+    child_message_loop_proxy_->PostTask(
+        FROM_HERE, base::Bind(job_record->ready_cb, output_frame));
+  }
+}
+
+void V4L2ImageProcessor::ReuseOutputBuffer(int index) {
+  DVLOG(3) << "Reusing output buffer, index=" << index;
+  DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current());
+
+  OutputRecord& output_record = output_buffer_map_[index];
+  DCHECK(output_record.at_client);
+  DCHECK(!output_record.at_device);
+  output_record.at_client = false;
+  free_output_buffers_.push_back(index);
+
+  Enqueue();
+}
+
+bool V4L2ImageProcessor::EnqueueInputRecord() {
+  DCHECK(!input_queue_.empty());
+  DCHECK(!free_input_buffers_.empty());
+
+  // Enqueue an input (VIDEO_OUTPUT) buffer for an input video frame.
+  linked_ptr<JobRecord> job_record = input_queue_.front();
+  input_queue_.pop();
+  const int index = free_input_buffers_.back();
+  InputRecord& input_record = input_buffer_map_[index];
+  DCHECK(!input_record.at_device);
+  input_record.frame = job_record->frame;
+  struct v4l2_buffer qbuf;
+  struct v4l2_plane qbuf_planes[VIDEO_MAX_PLANES];
+  memset(&qbuf, 0, sizeof(qbuf));
+  memset(qbuf_planes, 0, sizeof(qbuf_planes));
+  qbuf.index = index;
+  qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  qbuf.memory = V4L2_MEMORY_USERPTR;
+  qbuf.m.planes = qbuf_planes;
+  qbuf.length = input_planes_count_;
+  for (size_t i = 0; i < input_planes_count_; ++i) {
+    qbuf.m.planes[i].bytesused = media::VideoFrame::PlaneAllocationSize(
+        input_record.frame->format(), i, input_allocated_size_);
+    qbuf.m.planes[i].length = qbuf.m.planes[i].bytesused;
+    qbuf.m.planes[i].m.userptr =
+        reinterpret_cast<unsigned long>(input_record.frame->data(i));
+  }
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
+  input_record.at_device = true;
+  running_jobs_.push(job_record);
+  free_input_buffers_.pop_back();
+  input_buffer_queued_count_++;
+
+  DVLOG(3) << __func__ << ": enqueued frame ts="
+           << job_record->frame->timestamp().InMilliseconds() << " to device.";
+
+  return true;
+}
+
+bool V4L2ImageProcessor::EnqueueOutputRecord() {
+  DCHECK(!free_output_buffers_.empty());
+
+  // Enqueue an output (VIDEO_CAPTURE) buffer.
+  const int index = free_output_buffers_.back();
+  OutputRecord& output_record = output_buffer_map_[index];
+  DCHECK(!output_record.at_device);
+  struct v4l2_buffer qbuf;
+  struct v4l2_plane qbuf_planes[VIDEO_MAX_PLANES];
+  memset(&qbuf, 0, sizeof(qbuf));
+  memset(qbuf_planes, 0, sizeof(qbuf_planes));
+  qbuf.index = index;
+  qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  qbuf.memory = V4L2_MEMORY_MMAP;
+  qbuf.m.planes = qbuf_planes;
+  qbuf.length = output_planes_count_;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
+  output_record.at_device = true;
+  free_output_buffers_.pop_back();
+  output_buffer_queued_count_++;
+  return true;
+}
+
+bool V4L2ImageProcessor::StartDevicePoll() {
+  DVLOG(3) << __func__ << ": starting device poll";
+  DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current());
+  DCHECK(!device_poll_thread_.IsRunning());
+
+  // Start up the device poll thread and schedule its first DevicePollTask().
+  if (!device_poll_thread_.Start()) {
+    DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
+    NOTIFY_ERROR();
+    return false;
+  }
+  // Enqueue a poll task with no devices to poll on - will wait only for the
+  // poll interrupt
+  device_poll_thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &V4L2ImageProcessor::DevicePollTask, base::Unretained(this), false));
+
+  return true;
+}
+
+bool V4L2ImageProcessor::StopDevicePoll() {
+  DVLOG(3) << __func__ << ": stopping device poll";
+  if (device_thread_.IsRunning())
+    DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current());
+
+  // Signal the DevicePollTask() to stop, and stop the device poll thread.
+  if (!device_->SetDevicePollInterrupt())
+    return false;
+  device_poll_thread_.Stop();
+
+  // Clear the interrupt now, to be sure.
+  if (!device_->ClearDevicePollInterrupt())
+    return false;
+
+  if (input_streamon_) {
+    __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type);
+  }
+  input_streamon_ = false;
+
+  if (output_streamon_) {
+    __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type);
+  }
+  output_streamon_ = false;
+
+  // Reset all our accounting info.
+  while (!input_queue_.empty())
+    input_queue_.pop();
+
+  while (!running_jobs_.empty())
+    running_jobs_.pop();
+
+  free_input_buffers_.clear();
+  for (size_t i = 0; i < input_buffer_map_.size(); ++i) {
+    InputRecord& input_record = input_buffer_map_[i];
+    input_record.at_device = false;
+    input_record.frame = NULL;
+    free_input_buffers_.push_back(i);
+  }
+  input_buffer_queued_count_ = 0;
+
+  free_output_buffers_.clear();
+  for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
+    OutputRecord& output_record = output_buffer_map_[i];
+    output_record.at_device = false;
+    if (!output_record.at_client)
+      free_output_buffers_.push_back(i);
+  }
+  output_buffer_queued_count_ = 0;
+
+  return true;
+}
+
+}  // namespace content
diff --git a/content/common/gpu/media/v4l2_image_processor.h b/content/common/gpu/media/v4l2_image_processor.h
new file mode 100644
index 0000000..24c52c4
--- /dev/null
+++ b/content/common/gpu/media/v4l2_image_processor.h
@@ -0,0 +1,177 @@
+// 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.
+
+#ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_PROCESSOR_H_
+#define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_PROCESSOR_H_
+
+#include <queue>
+#include <vector>
+
+#include "base/memory/linked_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread.h"
+#include "content/common/content_export.h"
+#include "content/common/gpu/media/v4l2_video_device.h"
+#include "media/base/video_frame.h"
+
+namespace content {
+
+// Handles image processing accelerators that expose a V4L2 memory-to-memory
+// interface. The threading model of this class is the same as for other V4L2
+// hardware accelerators (see V4L2VideoDecodeAccelerator) for more details.
+class CONTENT_EXPORT V4L2ImageProcessor {
+ public:
+  explicit V4L2ImageProcessor(scoped_ptr<V4L2Device> device);
+  virtual ~V4L2ImageProcessor();
+
+  // Initializes the processor to convert from |input_format| to |output_format|
+  // and/or scale from |input_visible_size| to |output_visible_size|.
+  // Request the output buffers to be of at least |output_allocated_size|.
+  // Provided |error_cb| will be called if an error occurs.
+  // Return true if the requested configuration is supported.
+  bool Initialize(media::VideoFrame::Format input_format,
+                  media::VideoFrame::Format output_format,
+                  gfx::Size input_visible_size,
+                  gfx::Size output_visible_size,
+                  gfx::Size output_allocated_size,
+                  const base::Closure& error_cb);
+
+  // Returns allocated size required by the processor to be fed with.
+  gfx::Size input_allocated_size() { return input_allocated_size_; }
+
+  // Callback to be used to return a processed image to the client. The client
+  // should drop references to |frame| once it's done with it.
+  typedef base::Callback<void(const scoped_refptr<media::VideoFrame>& frame)>
+      FrameReadyCB;
+
+  // Called by client to process |frame|. The resulting processed frame will
+  // be returned via |cb|. The processor will drop all its references to |frame|
+  // after it finishes accessing it.
+  void Process(const scoped_refptr<media::VideoFrame>& frame,
+               const FrameReadyCB& cb);
+
+  // Stop all processing and clean up.
+  void Destroy();
+
+ private:
+  // Record for input buffers.
+  struct InputRecord {
+    InputRecord();
+    scoped_refptr<media::VideoFrame> frame;
+    bool at_device;
+  };
+
+  // Record for output buffers.
+  struct OutputRecord {
+    OutputRecord();
+    bool at_device;
+    bool at_client;
+    std::vector<int> fds;
+  };
+
+  // Job record. Jobs are processed in a FIFO order. This is separate from
+  // InputRecord, because an InputRecord may be returned before we dequeue
+  // the corresponding output buffer. It can't always be associated with
+  // an OutputRecord immediately either, because at the time of submission we
+  // may not have one available (and don't need one to submit input to the
+  // device).
+  struct JobRecord {
+    JobRecord();
+    scoped_refptr<media::VideoFrame> frame;
+    FrameReadyCB ready_cb;
+  };
+
+  enum {
+    // Arbitrarily tuned.
+    kInputBufferCount = 2,
+    kOutputBufferCount = 2,
+  };
+
+  void ReuseOutputBuffer(int index);
+
+  void Enqueue();
+  void Dequeue();
+  bool EnqueueInputRecord();
+  bool EnqueueOutputRecord();
+  bool CreateInputBuffers();
+  bool CreateOutputBuffers();
+  void DestroyInputBuffers();
+  void DestroyOutputBuffers();
+
+  void NotifyError();
+  void DestroyTask();
+
+  void ProcessTask(scoped_ptr<JobRecord> job_record);
+  void ServiceDeviceTask();
+
+  // Attempt to start/stop device_poll_thread_.
+  bool StartDevicePoll();
+  bool StopDevicePoll();
+
+  // Ran on device_poll_thread_ to wait for device events.
+  void DevicePollTask(bool poll_device);
+
+  // Size and format-related members remain constant after initialization.
+  // The visible/allocated sizes of the input frame.
+  gfx::Size input_visible_size_;
+  gfx::Size input_allocated_size_;
+
+  // The visible/allocated sizes of the destination frame.
+  gfx::Size output_visible_size_;
+  gfx::Size output_allocated_size_;
+
+  media::VideoFrame::Format input_format_;
+  media::VideoFrame::Format output_format_;
+  uint32 input_format_fourcc_;
+  uint32 output_format_fourcc_;
+
+  size_t input_planes_count_;
+  size_t output_planes_count_;
+
+  // Our original calling message loop for the child thread.
+  const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_;
+
+  // V4L2 device in use.
+  scoped_ptr<V4L2Device> device_;
+
+  // Thread to communicate with the device on.
+  base::Thread device_thread_;
+  // Thread used to poll the V4L2 for events only.
+  base::Thread device_poll_thread_;
+
+  // All the below members are to be accessed from device_thread_ only
+  // (if it's running).
+  std::queue<linked_ptr<JobRecord> > input_queue_;
+  std::queue<linked_ptr<JobRecord> > running_jobs_;
+
+  // Input queue state.
+  bool input_streamon_;
+  // Number of input buffers enqueued to the device.
+  int input_buffer_queued_count_;
+  // Input buffers ready to use; LIFO since we don't care about ordering.
+  std::vector<int> free_input_buffers_;
+  // Mapping of int index to an input buffer record.
+  std::vector<InputRecord> input_buffer_map_;
+
+  // Output queue state.
+  bool output_streamon_;
+  // Number of output buffers enqueued to the device.
+  int output_buffer_queued_count_;
+  // Output buffers ready to use; LIFO since we don't care about ordering.
+  std::vector<int> free_output_buffers_;
+  // Mapping of int index to an output buffer record.
+  std::vector<OutputRecord> output_buffer_map_;
+
+  // Error callback to the client.
+  base::Closure error_cb_;
+
+  // Weak factory for producing weak pointers on the device_thread_
+  base::WeakPtrFactory<V4L2ImageProcessor> device_weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(V4L2ImageProcessor);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_PROCESSOR_H_
diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_video_decode_accelerator.cc
index 2f2e880..185d7ce 100644
--- a/content/common/gpu/media/v4l2_video_decode_accelerator.cc
+++ b/content/common/gpu/media/v4l2_video_decode_accelerator.cc
@@ -17,38 +17,40 @@
 #include "base/message_loop/message_loop.h"
 #include "base/message_loop/message_loop_proxy.h"
 #include "base/numerics/safe_conversions.h"
-#include "base/posix/eintr_wrapper.h"
 #include "content/common/gpu/media/v4l2_video_decode_accelerator.h"
 #include "media/filters/h264_parser.h"
 #include "ui/gl/scoped_binders.h"
 
+#define NOTIFY_ERROR(x)                            \
+  do {                                             \
+    SetDecoderState(kError);                       \
+    DLOG(ERROR) << "calling NotifyError(): " << x; \
+    NotifyError(x);                                \
+  } while (0)
+
+#define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value)              \
+  do {                                                             \
+    if (device_->Ioctl(type, arg) != 0) {                          \
+      DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
+      NOTIFY_ERROR(PLATFORM_FAILURE);                              \
+      return value;                                                \
+    }                                                              \
+  } while (0)
+
+#define IOCTL_OR_ERROR_RETURN(type, arg) \
+  IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0))
+
+#define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
+  IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false)
+
+#define IOCTL_OR_LOG_ERROR(type, arg)                              \
+  do {                                                             \
+    if (device_->Ioctl(type, arg) != 0)                            \
+      DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
+  } while (0)
+
 namespace content {
 
-#define NOTIFY_ERROR(x)                                               \
-  do {                                                                \
-    SetDecoderState(kError);                                          \
-    DLOG(ERROR) << "calling NotifyError(): " << x;                    \
-    NotifyError(x);                                                   \
-  } while (0)
-
-#define IOCTL_OR_ERROR_RETURN(type, arg)                           \
-  do {                                                             \
-    if (HANDLE_EINTR(device_->Ioctl(type, arg) != 0)) {            \
-      DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
-      NOTIFY_ERROR(PLATFORM_FAILURE);                              \
-      return;                                                      \
-    }                                                              \
-  } while (0)
-
-#define IOCTL_OR_ERROR_RETURN_FALSE(type, arg)                     \
-  do {                                                             \
-    if (HANDLE_EINTR(device_->Ioctl(type, arg) != 0)) {            \
-      DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
-      NOTIFY_ERROR(PLATFORM_FAILURE);                              \
-      return false;                                                \
-    }                                                              \
-  } while (0)
-
 namespace {
 
 // TODO(posciak): remove once we update linux-headers.
@@ -152,6 +154,7 @@
 
 V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator(
     EGLDisplay egl_display,
+    EGLContext egl_context,
     const base::WeakPtr<Client>& io_client,
     const base::Callback<bool(void)>& make_context_current,
     scoped_ptr<V4L2Device> device,
@@ -174,7 +177,6 @@
       input_buffer_queued_count_(0),
       output_streamon_(false),
       output_buffer_queued_count_(0),
-      output_buffer_pixelformat_(0),
       output_dpb_size_(0),
       output_planes_count_(0),
       picture_clearing_count_(0),
@@ -182,6 +184,7 @@
       device_poll_thread_("V4L2DevicePollThread"),
       make_context_current_(make_context_current),
       egl_display_(egl_display),
+      egl_context_(egl_context),
       video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN),
       weak_this_factory_(this) {
   weak_this_ = weak_this_factory_.GetWeakPtr();
@@ -268,7 +271,13 @@
   struct v4l2_format format;
   memset(&format, 0, sizeof(format));
   format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  format.fmt.pix_mp.pixelformat = device_->PreferredOutputFormat();
+  uint32 output_format_fourcc = device_->PreferredOutputFormat();
+  if (output_format_fourcc == 0) {
+    // TODO(posciak): We should enumerate available output formats, as well as
+    // take into account formats that the client is ready to accept.
+    return false;
+  }
+  format.fmt.pix_mp.pixelformat = output_format_fourcc;
   IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format);
 
   // Subscribe to the resolution change event.
@@ -348,6 +357,7 @@
     DCHECK_EQ(output_record.cleared, false);
 
     EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_,
+                                                    egl_context_,
                                                     buffers[i].texture_id(),
                                                     frame_buffer_size_,
                                                     i,
@@ -1605,7 +1615,7 @@
   *again = false;
   memset(format, 0, sizeof(*format));
   format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  if (HANDLE_EINTR(device_->Ioctl(VIDIOC_G_FMT, format)) != 0) {
+  if (device_->Ioctl(VIDIOC_G_FMT, format) != 0) {
     if (errno == EINVAL) {
       // EINVAL means we haven't seen sufficient stream to decode the format.
       *again = true;
@@ -1626,8 +1636,6 @@
   output_planes_count_ = format.fmt.pix_mp.num_planes;
   frame_buffer_size_.SetSize(
       format.fmt.pix_mp.width, format.fmt.pix_mp.height);
-  output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat;
-  DCHECK_EQ(output_buffer_pixelformat_, device_->PreferredOutputFormat());
   DVLOG(3) << "CreateBuffersForFormat(): new resolution: "
            << frame_buffer_size_.ToString();
 
@@ -1644,15 +1652,10 @@
   DCHECK(!input_streamon_);
   DCHECK(input_buffer_map_.empty());
 
-  __u32 pixelformat = 0;
-  if (video_profile_ >= media::H264PROFILE_MIN &&
-      video_profile_ <= media::H264PROFILE_MAX) {
-    pixelformat = V4L2_PIX_FMT_H264;
-  } else if (video_profile_ >= media::VP8PROFILE_MIN &&
-             video_profile_ <= media::VP8PROFILE_MAX) {
-    pixelformat = V4L2_PIX_FMT_VP8;
-  } else {
+  __u32 pixelformat = V4L2Device::VideoCodecProfileToV4L2PixFmt(video_profile_);
+  if (!pixelformat) {
     NOTREACHED();
+    return false;
   }
 
   struct v4l2_format format;
@@ -1773,8 +1776,7 @@
   reqbufs.count = 0;
   reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   reqbufs.memory = V4L2_MEMORY_MMAP;
-  if (device_->Ioctl(VIDIOC_REQBUFS, &reqbufs) != 0)
-    DPLOG(ERROR) << "DestroyInputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
+  IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
 
   input_buffer_map_.clear();
   free_input_buffers_.clear();
diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.h b/content/common/gpu/media/v4l2_video_decode_accelerator.h
index 33b5dbe..9aec936 100644
--- a/content/common/gpu/media/v4l2_video_decode_accelerator.h
+++ b/content/common/gpu/media/v4l2_video_decode_accelerator.h
@@ -77,6 +77,7 @@
  public:
   V4L2VideoDecodeAccelerator(
       EGLDisplay egl_display,
+      EGLContext egl_context,
       const base::WeakPtr<Client>& io_client_,
       const base::Callback<bool(void)>& make_context_current,
       scoped_ptr<V4L2Device> device,
@@ -394,8 +395,6 @@
   std::queue<int> free_output_buffers_;
   // Mapping of int index to output buffer record.
   std::vector<OutputRecord> output_buffer_map_;
-  // Output pixel format.
-  uint32 output_buffer_pixelformat_;
   // Required size of DPB for decoding.
   int output_dpb_size_;
   // Stores the number of planes (i.e. separate memory buffers) for output.
@@ -430,6 +429,7 @@
 
   // EGL state
   EGLDisplay egl_display_;
+  EGLContext egl_context_;
 
   // The codec we'll be decoding for.
   media::VideoCodecProfile video_profile_;
diff --git a/content/common/gpu/media/v4l2_video_device.cc b/content/common/gpu/media/v4l2_video_device.cc
index d63cd4e..e9c5422 100644
--- a/content/common/gpu/media/v4l2_video_device.cc
+++ b/content/common/gpu/media/v4l2_video_device.cc
@@ -2,29 +2,138 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/debug/trace_event.h"
+#include <linux/videodev2.h>
+
+#include "base/numerics/safe_conversions.h"
 #include "content/common/gpu/media/exynos_v4l2_video_device.h"
 #include "content/common/gpu/media/tegra_v4l2_video_device.h"
 
 namespace content {
 
-V4L2Device::V4L2Device() {}
-
 V4L2Device::~V4L2Device() {}
 
 // static
-scoped_ptr<V4L2Device> V4L2Device::Create(EGLContext egl_context) {
+scoped_ptr<V4L2Device> V4L2Device::Create(Type type) {
   DVLOG(3) << __PRETTY_FUNCTION__;
 
-  scoped_ptr<ExynosV4L2Device> exynos_device(new ExynosV4L2Device());
+  scoped_ptr<ExynosV4L2Device> exynos_device(new ExynosV4L2Device(type));
   if (exynos_device->Initialize())
     return exynos_device.PassAs<V4L2Device>();
 
-  scoped_ptr<TegraV4L2Device> tegra_device(new TegraV4L2Device(egl_context));
+  scoped_ptr<TegraV4L2Device> tegra_device(new TegraV4L2Device(type));
   if (tegra_device->Initialize())
     return tegra_device.PassAs<V4L2Device>();
 
   DLOG(ERROR) << "Failed to create V4L2Device";
   return scoped_ptr<V4L2Device>();
 }
+
+// static
+media::VideoFrame::Format V4L2Device::V4L2PixFmtToVideoFrameFormat(
+    uint32 pix_fmt) {
+  switch (pix_fmt) {
+    case V4L2_PIX_FMT_NV12:
+    case V4L2_PIX_FMT_NV12M:
+      return media::VideoFrame::NV12;
+
+    case V4L2_PIX_FMT_YUV420:
+    case V4L2_PIX_FMT_YUV420M:
+      return media::VideoFrame::I420;
+
+    default:
+      LOG(FATAL) << "Add more cases as needed";
+      return media::VideoFrame::UNKNOWN;
+  }
+}
+
+// static
+uint32 V4L2Device::VideoFrameFormatToV4L2PixFmt(
+    media::VideoFrame::Format format) {
+  switch (format) {
+    case media::VideoFrame::NV12:
+      return V4L2_PIX_FMT_NV12M;
+
+    case media::VideoFrame::I420:
+      return V4L2_PIX_FMT_YUV420M;
+
+    default:
+      LOG(FATAL) << "Add more cases as needed";
+      return 0;
+  }
+}
+
+// static
+uint32 V4L2Device::VideoCodecProfileToV4L2PixFmt(
+    media::VideoCodecProfile profile) {
+  if (profile >= media::H264PROFILE_MIN &&
+      profile <= media::H264PROFILE_MAX) {
+    return V4L2_PIX_FMT_H264;
+  } else if (profile >= media::VP8PROFILE_MIN &&
+             profile <= media::VP8PROFILE_MAX) {
+    return V4L2_PIX_FMT_VP8;
+  } else {
+    LOG(FATAL) << "Add more cases as needed";
+    return 0;
+  }
+}
+
+// static
+gfx::Size V4L2Device::CodedSizeFromV4L2Format(struct v4l2_format format) {
+  gfx::Size coded_size;
+  gfx::Size visible_size;
+  media::VideoFrame::Format frame_format = media::VideoFrame::UNKNOWN;
+  int bytesperline = 0;
+  int sizeimage = 0;
+
+  if (V4L2_TYPE_IS_MULTIPLANAR(format.type) &&
+      format.fmt.pix_mp.num_planes > 0) {
+    bytesperline =
+        base::checked_cast<int>(format.fmt.pix_mp.plane_fmt[0].bytesperline);
+    sizeimage =
+        base::checked_cast<int>(format.fmt.pix_mp.plane_fmt[0].sizeimage);
+    visible_size.SetSize(base::checked_cast<int>(format.fmt.pix_mp.width),
+                         base::checked_cast<int>(format.fmt.pix_mp.height));
+    frame_format =
+        V4L2Device::V4L2PixFmtToVideoFrameFormat(format.fmt.pix_mp.pixelformat);
+  } else {
+    bytesperline = base::checked_cast<int>(format.fmt.pix.bytesperline);
+    sizeimage = base::checked_cast<int>(format.fmt.pix.sizeimage);
+    visible_size.SetSize(base::checked_cast<int>(format.fmt.pix.width),
+                         base::checked_cast<int>(format.fmt.pix.height));
+    frame_format =
+        V4L2Device::V4L2PixFmtToVideoFrameFormat(format.fmt.pix.pixelformat);
+  }
+
+  int horiz_bpp =
+      media::VideoFrame::PlaneHorizontalBitsPerPixel(frame_format, 0);
+  if (sizeimage == 0 || bytesperline == 0 || horiz_bpp == 0 ||
+      (bytesperline * 8) % horiz_bpp != 0) {
+    DLOG(ERROR) << "Invalid format provided";
+    return coded_size;
+  }
+
+  // Round up sizeimage to full bytesperlines. sizeimage does not have to be
+  // a multiple of bytesperline, as in V4L2 terms it's just a byte size of
+  // the buffer, unrelated to its payload.
+  sizeimage = ((sizeimage + bytesperline - 1) / bytesperline) * bytesperline;
+
+  coded_size.SetSize(bytesperline * 8 / horiz_bpp, sizeimage / bytesperline);
+
+  // Sanity checks. Calculated coded size has to contain given visible size
+  // and fulfill buffer byte size requirements for each plane.
+  DCHECK(gfx::Rect(coded_size).Contains(gfx::Rect(visible_size)));
+
+  if (V4L2_TYPE_IS_MULTIPLANAR(format.type)) {
+    for (size_t i = 0; i < format.fmt.pix_mp.num_planes; ++i) {
+      DCHECK_LE(
+          format.fmt.pix_mp.plane_fmt[i].sizeimage,
+          media::VideoFrame::PlaneAllocationSize(frame_format, i, coded_size));
+      DCHECK_LE(format.fmt.pix_mp.plane_fmt[i].bytesperline,
+                base::checked_cast<__u32>(coded_size.width()));
+    }
+  }
+
+  return coded_size;
+}
+
 }  //  namespace content
diff --git a/content/common/gpu/media/v4l2_video_device.h b/content/common/gpu/media/v4l2_video_device.h
index a982ef2..f4b368f 100644
--- a/content/common/gpu/media/v4l2_video_device.h
+++ b/content/common/gpu/media/v4l2_video_device.h
@@ -9,6 +9,8 @@
 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DEVICE_H_
 #define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DEVICE_H_
 
+#include "media/base/video_decoder_config.h"
+#include "media/base/video_frame.h"
 #include "ui/gfx/size.h"
 #include "ui/gl/gl_bindings.h"
 
@@ -16,13 +18,24 @@
 
 class V4L2Device {
  public:
-  V4L2Device();
+  // Utility format conversion functions
+  static media::VideoFrame::Format V4L2PixFmtToVideoFrameFormat(uint32 format);
+  static uint32 VideoFrameFormatToV4L2PixFmt(media::VideoFrame::Format format);
+  static uint32 VideoCodecProfileToV4L2PixFmt(media::VideoCodecProfile profile);
+  // Convert format requirements requested by a V4L2 device to gfx::Size.
+  static gfx::Size CodedSizeFromV4L2Format(struct v4l2_format format);
+
   virtual ~V4L2Device();
 
-  // Creates and initializes an appropriate V4L2Device object for the
-  // current platform and returns a scoped_ptr<V4L2Device> on success else
-  // returns NULL.
-  static scoped_ptr<V4L2Device> Create(EGLContext egl_context);
+  enum Type {
+    kDecoder,
+    kEncoder,
+    kImageProcessor,
+  };
+
+  // Creates and initializes an appropriate V4L2Device of |type| for the
+  // current platform and returns a scoped_ptr<V4L2Device> on success, or NULL.
+  static scoped_ptr<V4L2Device> Create(Type type);
 
   // Parameters and return value are the same as for the standard ioctl() system
   // call.
@@ -54,7 +67,8 @@
                      unsigned int offset) = 0;
   virtual void Munmap(void* addr, unsigned int len) = 0;
 
-  // Does all the initialization of V4L2Device, returns true on success.
+  // Initializes the V4L2Device to operate as a device of |type|.
+  // Returns true on success.
   virtual bool Initialize() = 0;
 
   // Creates an EGLImageKHR since each V4L2Device may use a different method of
@@ -63,6 +77,7 @@
   // used to associate the returned EGLImageKHR by the underlying V4L2Device
   // implementation.
   virtual EGLImageKHR CreateEGLImage(EGLDisplay egl_display,
+                                     EGLContext egl_context,
                                      GLuint texture_id,
                                      gfx::Size frame_buffer_size,
                                      unsigned int buffer_index,
@@ -75,7 +90,10 @@
   // Returns the supported texture target for the V4L2Device.
   virtual GLenum GetTextureTarget() = 0;
 
-  // Returns the preferred pixel format supported by this V4L2Device.
+  // Returns the preferred V4L2 input format or 0 if don't care.
+  virtual uint32 PreferredInputFormat() = 0;
+
+  // Returns the preferred V4L2 output format or 0 if don't care.
   virtual uint32 PreferredOutputFormat() = 0;
 };
 
diff --git a/content/common/gpu/media/v4l2_video_encode_accelerator.cc b/content/common/gpu/media/v4l2_video_encode_accelerator.cc
new file mode 100644
index 0000000..0dd33a0
--- /dev/null
+++ b/content/common/gpu/media/v4l2_video_encode_accelerator.cc
@@ -0,0 +1,1096 @@
+// 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.
+
+#include <fcntl.h>
+#include <linux/videodev2.h>
+#include <poll.h>
+#include <sys/eventfd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include "base/callback.h"
+#include "base/command_line.h"
+#include "base/debug/trace_event.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/numerics/safe_conversions.h"
+#include "content/common/gpu/media/v4l2_video_encode_accelerator.h"
+#include "content/public/common/content_switches.h"
+#include "media/base/bitstream_buffer.h"
+
+#define NOTIFY_ERROR(x)                            \
+  do {                                             \
+    SetEncoderState(kError);                       \
+    DLOG(ERROR) << "calling NotifyError(): " << x; \
+    NotifyError(x);                                \
+  } while (0)
+
+#define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value)              \
+  do {                                                             \
+    if (device_->Ioctl(type, arg) != 0) {                          \
+      DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
+      NOTIFY_ERROR(kPlatformFailureError);                         \
+      return value;                                                \
+    }                                                              \
+  } while (0)
+
+#define IOCTL_OR_ERROR_RETURN(type, arg) \
+  IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0))
+
+#define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
+  IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false)
+
+#define IOCTL_OR_LOG_ERROR(type, arg)                              \
+  do {                                                             \
+    if (device_->Ioctl(type, arg) != 0)                            \
+      DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
+  } while (0)
+
+namespace content {
+
+struct V4L2VideoEncodeAccelerator::BitstreamBufferRef {
+  BitstreamBufferRef(int32 id, scoped_ptr<base::SharedMemory> shm, size_t size)
+      : id(id), shm(shm.Pass()), size(size) {}
+  const int32 id;
+  const scoped_ptr<base::SharedMemory> shm;
+  const size_t size;
+};
+
+V4L2VideoEncodeAccelerator::InputRecord::InputRecord() : at_device(false) {
+}
+
+V4L2VideoEncodeAccelerator::OutputRecord::OutputRecord()
+    : at_device(false), address(NULL), length(0) {
+}
+
+V4L2VideoEncodeAccelerator::V4L2VideoEncodeAccelerator(
+    scoped_ptr<V4L2Device> device)
+    : child_message_loop_proxy_(base::MessageLoopProxy::current()),
+      weak_this_ptr_factory_(this),
+      weak_this_(weak_this_ptr_factory_.GetWeakPtr()),
+      output_buffer_byte_size_(0),
+      device_input_format_(media::VideoFrame::UNKNOWN),
+      input_planes_count_(0),
+      output_format_fourcc_(0),
+      encoder_thread_("V4L2EncoderThread"),
+      encoder_state_(kUninitialized),
+      stream_header_size_(0),
+      device_(device.Pass()),
+      input_streamon_(false),
+      input_buffer_queued_count_(0),
+      input_memory_type_(V4L2_MEMORY_USERPTR),
+      output_streamon_(false),
+      output_buffer_queued_count_(0),
+      device_poll_thread_("V4L2EncoderDevicePollThread") {
+}
+
+V4L2VideoEncodeAccelerator::~V4L2VideoEncodeAccelerator() {
+  DCHECK(!encoder_thread_.IsRunning());
+  DCHECK(!device_poll_thread_.IsRunning());
+  DVLOG(4) << __func__;
+
+  DestroyInputBuffers();
+  DestroyOutputBuffers();
+}
+
+bool V4L2VideoEncodeAccelerator::Initialize(
+    media::VideoFrame::Format input_format,
+    const gfx::Size& input_visible_size,
+    media::VideoCodecProfile output_profile,
+    uint32 initial_bitrate,
+    Client* client) {
+  DVLOG(3) << __func__ << ": input_format="
+           << media::VideoFrame::FormatToString(input_format)
+           << ", input_visible_size=" << input_visible_size.ToString()
+           << ", output_profile=" << output_profile
+           << ", initial_bitrate=" << initial_bitrate;
+
+  visible_size_ = input_visible_size;
+
+  client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
+  client_ = client_ptr_factory_->GetWeakPtr();
+
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK_EQ(encoder_state_, kUninitialized);
+
+  struct v4l2_capability caps;
+  memset(&caps, 0, sizeof(caps));
+  const __u32 kCapsRequired = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+                              V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
+  if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
+    DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
+                   "caps check failed: 0x" << std::hex << caps.capabilities;
+    return false;
+  }
+
+  if (!SetFormats(input_format, output_profile)) {
+    DLOG(ERROR) << "Failed setting up formats";
+    return false;
+  }
+
+  if (input_format != device_input_format_) {
+    DVLOG(1) << "Input format not supported by the HW, will convert to "
+             << media::VideoFrame::FormatToString(device_input_format_);
+
+    scoped_ptr<V4L2Device> device =
+        V4L2Device::Create(V4L2Device::kImageProcessor);
+    image_processor_.reset(new V4L2ImageProcessor(device.Pass()));
+
+    // Convert from input_format to device_input_format_, keeping the size
+    // at visible_size_ and requiring the output buffers to be of at least
+    // input_allocated_size_.
+    if (!image_processor_->Initialize(
+            input_format,
+            device_input_format_,
+            visible_size_,
+            visible_size_,
+            input_allocated_size_,
+            base::Bind(&V4L2VideoEncodeAccelerator::ImageProcessorError,
+                       weak_this_))) {
+      DLOG(ERROR) << "Failed initializing image processor";
+      return false;
+    }
+  }
+
+  if (!InitControls())
+    return false;
+
+  if (!CreateOutputBuffers())
+    return false;
+
+  if (!encoder_thread_.Start()) {
+    DLOG(ERROR) << "Initialize(): encoder thread failed to start";
+    return false;
+  }
+
+  RequestEncodingParametersChange(initial_bitrate, kInitialFramerate);
+
+  SetEncoderState(kInitialized);
+
+  child_message_loop_proxy_->PostTask(
+      FROM_HERE,
+      base::Bind(&Client::RequireBitstreamBuffers,
+                 client_,
+                 kInputBufferCount,
+                 image_processor_.get() ?
+                     image_processor_->input_allocated_size() :
+                     input_allocated_size_,
+                 output_buffer_byte_size_));
+  return true;
+}
+
+void V4L2VideoEncodeAccelerator::ImageProcessorError() {
+  DVLOG(1) << "Image processor error";
+  NOTIFY_ERROR(kPlatformFailureError);
+}
+
+void V4L2VideoEncodeAccelerator::Encode(
+    const scoped_refptr<media::VideoFrame>& frame,
+    bool force_keyframe) {
+  DVLOG(3) << "Encode(): force_keyframe=" << force_keyframe;
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+
+  if (image_processor_) {
+    image_processor_->Process(
+        frame,
+        base::Bind(&V4L2VideoEncodeAccelerator::FrameProcessed,
+                   weak_this_,
+                   force_keyframe));
+  } else {
+    encoder_thread_.message_loop()->PostTask(
+        FROM_HERE,
+        base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask,
+                   base::Unretained(this),
+                   frame,
+                   force_keyframe));
+  }
+}
+
+void V4L2VideoEncodeAccelerator::UseOutputBitstreamBuffer(
+    const media::BitstreamBuffer& buffer) {
+  DVLOG(3) << "UseOutputBitstreamBuffer(): id=" << buffer.id();
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+
+  if (buffer.size() < output_buffer_byte_size_) {
+    NOTIFY_ERROR(kInvalidArgumentError);
+    return;
+  }
+
+  scoped_ptr<base::SharedMemory> shm(
+      new base::SharedMemory(buffer.handle(), false));
+  if (!shm->Map(buffer.size())) {
+    NOTIFY_ERROR(kPlatformFailureError);
+    return;
+  }
+
+  scoped_ptr<BitstreamBufferRef> buffer_ref(
+      new BitstreamBufferRef(buffer.id(), shm.Pass(), buffer.size()));
+  encoder_thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask,
+                 base::Unretained(this),
+                 base::Passed(&buffer_ref)));
+}
+
+void V4L2VideoEncodeAccelerator::RequestEncodingParametersChange(
+    uint32 bitrate,
+    uint32 framerate) {
+  DVLOG(3) << "RequestEncodingParametersChange(): bitrate=" << bitrate
+           << ", framerate=" << framerate;
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+
+  encoder_thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask,
+          base::Unretained(this),
+          bitrate,
+          framerate));
+}
+
+void V4L2VideoEncodeAccelerator::Destroy() {
+  DVLOG(3) << "Destroy()";
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+
+  // We're destroying; cancel all callbacks.
+  client_ptr_factory_.reset();
+
+  if (image_processor_.get())
+    image_processor_.release()->Destroy();
+
+  // If the encoder thread is running, destroy using posted task.
+  if (encoder_thread_.IsRunning()) {
+    encoder_thread_.message_loop()->PostTask(
+        FROM_HERE,
+        base::Bind(&V4L2VideoEncodeAccelerator::DestroyTask,
+                   base::Unretained(this)));
+    // DestroyTask() will put the encoder into kError state and cause all tasks
+    // to no-op.
+    encoder_thread_.Stop();
+  } else {
+    // Otherwise, call the destroy task directly.
+    DestroyTask();
+  }
+
+  // Set to kError state just in case.
+  SetEncoderState(kError);
+
+  delete this;
+}
+
+// static
+std::vector<media::VideoEncodeAccelerator::SupportedProfile>
+V4L2VideoEncodeAccelerator::GetSupportedProfiles() {
+  std::vector<SupportedProfile> profiles;
+  SupportedProfile profile;
+
+  const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+  if (cmd_line->HasSwitch(switches::kEnableWebRtcHWVp8Encoding)) {
+    profile.profile = media::VP8PROFILE_MAIN;
+    profile.max_resolution.SetSize(1920, 1088);
+    profile.max_framerate.numerator = 30;
+    profile.max_framerate.denominator = 1;
+    profiles.push_back(profile);
+  } else {
+    profile.profile = media::H264PROFILE_MAIN;
+    profile.max_resolution.SetSize(1920, 1088);
+    profile.max_framerate.numerator = 30;
+    profile.max_framerate.denominator = 1;
+    profiles.push_back(profile);
+  }
+
+  return profiles;
+}
+
+void V4L2VideoEncodeAccelerator::FrameProcessed(
+    bool force_keyframe,
+    const scoped_refptr<media::VideoFrame>& frame) {
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DVLOG(3) << "FrameProcessed(): force_keyframe=" << force_keyframe;
+
+  encoder_thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&V4L2VideoEncodeAccelerator::EncodeTask,
+                 base::Unretained(this),
+                 frame,
+                 force_keyframe));
+}
+
+void V4L2VideoEncodeAccelerator::EncodeTask(
+    const scoped_refptr<media::VideoFrame>& frame,
+    bool force_keyframe) {
+  DVLOG(3) << "EncodeTask(): force_keyframe=" << force_keyframe;
+  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
+  DCHECK_NE(encoder_state_, kUninitialized);
+
+  if (encoder_state_ == kError) {
+    DVLOG(2) << "EncodeTask(): early out: kError state";
+    return;
+  }
+
+  encoder_input_queue_.push_back(frame);
+  Enqueue();
+
+  if (force_keyframe) {
+    // TODO(posciak): this presently makes for slightly imprecise encoding
+    // parameters updates.  To precisely align the parameter updates with the
+    // incoming input frame, we should queue the parameters together with the
+    // frame onto encoder_input_queue_ and apply them when the input is about
+    // to be queued to the codec.
+    struct v4l2_ext_control ctrls[1];
+    struct v4l2_ext_controls control;
+    memset(&ctrls, 0, sizeof(ctrls));
+    memset(&control, 0, sizeof(control));
+    ctrls[0].id = V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE;
+    ctrls[0].value = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME;
+    control.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+    control.count = 1;
+    control.controls = ctrls;
+    IOCTL_OR_ERROR_RETURN(VIDIOC_S_EXT_CTRLS, &control);
+  }
+}
+
+void V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask(
+    scoped_ptr<BitstreamBufferRef> buffer_ref) {
+  DVLOG(3) << "UseOutputBitstreamBufferTask(): id=" << buffer_ref->id;
+  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
+
+  encoder_output_queue_.push_back(
+      linked_ptr<BitstreamBufferRef>(buffer_ref.release()));
+  Enqueue();
+
+  if (encoder_state_ == kInitialized) {
+    // Finish setting up our OUTPUT queue.  See: Initialize().
+    // VIDIOC_REQBUFS on OUTPUT queue.
+    if (!CreateInputBuffers())
+      return;
+    if (!StartDevicePoll())
+      return;
+    encoder_state_ = kEncoding;
+  }
+}
+
+void V4L2VideoEncodeAccelerator::DestroyTask() {
+  DVLOG(3) << "DestroyTask()";
+
+  // DestroyTask() should run regardless of encoder_state_.
+
+  // Stop streaming and the device_poll_thread_.
+  StopDevicePoll();
+
+  // Set our state to kError, and early-out all tasks.
+  encoder_state_ = kError;
+}
+
+void V4L2VideoEncodeAccelerator::ServiceDeviceTask() {
+  DVLOG(3) << "ServiceDeviceTask()";
+  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
+  DCHECK_NE(encoder_state_, kUninitialized);
+  DCHECK_NE(encoder_state_, kInitialized);
+
+  if (encoder_state_ == kError) {
+    DVLOG(2) << "ServiceDeviceTask(): early out: kError state";
+    return;
+  }
+
+  Dequeue();
+  Enqueue();
+
+  // Clear the interrupt fd.
+  if (!device_->ClearDevicePollInterrupt())
+    return;
+
+  // Device can be polled as soon as either input or output buffers are queued.
+  bool poll_device =
+      (input_buffer_queued_count_ + output_buffer_queued_count_ > 0);
+
+  // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
+  // so either:
+  // * device_poll_thread_ is running normally
+  // * device_poll_thread_ scheduled us, but then a DestroyTask() shut it down,
+  //   in which case we're in kError state, and we should have early-outed
+  //   already.
+  DCHECK(device_poll_thread_.message_loop());
+  // Queue the DevicePollTask() now.
+  device_poll_thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask,
+                 base::Unretained(this),
+                 poll_device));
+
+  DVLOG(2) << __func__ << ": buffer counts: ENC["
+           << encoder_input_queue_.size() << "] => DEVICE["
+           << free_input_buffers_.size() << "+"
+           << input_buffer_queued_count_ << "/"
+           << input_buffer_map_.size() << "->"
+           << free_output_buffers_.size() << "+"
+           << output_buffer_queued_count_ << "/"
+           << output_buffer_map_.size() << "] => OUT["
+           << encoder_output_queue_.size() << "]";
+}
+
+void V4L2VideoEncodeAccelerator::Enqueue() {
+  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
+
+  DVLOG(3) << "Enqueue() "
+           << "free_input_buffers: " << free_input_buffers_.size()
+           << "input_queue: " << encoder_input_queue_.size();
+
+  // Enqueue all the inputs we can.
+  const int old_inputs_queued = input_buffer_queued_count_;
+  // while (!ready_input_buffers_.empty()) {
+  while (!encoder_input_queue_.empty() && !free_input_buffers_.empty()) {
+    if (!EnqueueInputRecord())
+      return;
+  }
+  if (old_inputs_queued == 0 && input_buffer_queued_count_ != 0) {
+    // We just started up a previously empty queue.
+    // Queue state changed; signal interrupt.
+    if (!device_->SetDevicePollInterrupt())
+      return;
+    // Start VIDIOC_STREAMON if we haven't yet.
+    if (!input_streamon_) {
+      __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+      IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
+      input_streamon_ = true;
+    }
+  }
+
+  // Enqueue all the outputs we can.
+  const int old_outputs_queued = output_buffer_queued_count_;
+  while (!free_output_buffers_.empty() && !encoder_output_queue_.empty()) {
+    if (!EnqueueOutputRecord())
+      return;
+  }
+  if (old_outputs_queued == 0 && output_buffer_queued_count_ != 0) {
+    // We just started up a previously empty queue.
+    // Queue state changed; signal interrupt.
+    if (!device_->SetDevicePollInterrupt())
+      return;
+    // Start VIDIOC_STREAMON if we haven't yet.
+    if (!output_streamon_) {
+      __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+      IOCTL_OR_ERROR_RETURN(VIDIOC_STREAMON, &type);
+      output_streamon_ = true;
+    }
+  }
+}
+
+void V4L2VideoEncodeAccelerator::Dequeue() {
+  DVLOG(3) << "Dequeue()";
+  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
+
+  // Dequeue completed input (VIDEO_OUTPUT) buffers, and recycle to the free
+  // list.
+  struct v4l2_buffer dqbuf;
+  struct v4l2_plane planes[VIDEO_MAX_PLANES];
+  while (input_buffer_queued_count_ > 0) {
+    DVLOG(4) << "inputs queued: " << input_buffer_queued_count_;
+    DCHECK(input_streamon_);
+    memset(&dqbuf, 0, sizeof(dqbuf));
+    memset(&planes, 0, sizeof(planes));
+    dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    dqbuf.memory = V4L2_MEMORY_MMAP;
+    dqbuf.m.planes = planes;
+    dqbuf.length = input_planes_count_;
+    if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) {
+      if (errno == EAGAIN) {
+        // EAGAIN if we're just out of buffers to dequeue.
+        break;
+      }
+      DPLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF";
+      NOTIFY_ERROR(kPlatformFailureError);
+      return;
+    }
+    InputRecord& input_record = input_buffer_map_[dqbuf.index];
+    DCHECK(input_record.at_device);
+    input_record.at_device = false;
+
+    input_record.frame = NULL;
+    free_input_buffers_.push_back(dqbuf.index);
+    input_buffer_queued_count_--;
+  }
+
+  // Dequeue completed output (VIDEO_CAPTURE) buffers, and recycle to the
+  // free list.  Notify the client that an output buffer is complete.
+  while (output_buffer_queued_count_ > 0) {
+    DCHECK(output_streamon_);
+    memset(&dqbuf, 0, sizeof(dqbuf));
+    memset(planes, 0, sizeof(planes));
+    dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    dqbuf.memory = V4L2_MEMORY_MMAP;
+    dqbuf.m.planes = planes;
+    dqbuf.length = 1;
+    if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) {
+      if (errno == EAGAIN) {
+        // EAGAIN if we're just out of buffers to dequeue.
+        break;
+      }
+      DPLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF";
+      NOTIFY_ERROR(kPlatformFailureError);
+      return;
+    }
+    const bool key_frame = ((dqbuf.flags & V4L2_BUF_FLAG_KEYFRAME) != 0);
+    OutputRecord& output_record = output_buffer_map_[dqbuf.index];
+    DCHECK(output_record.at_device);
+    DCHECK(output_record.buffer_ref.get());
+
+    void* output_data = output_record.address;
+    size_t output_size = dqbuf.m.planes[0].bytesused;
+    // This shouldn't happen, but just in case. We should be able to recover
+    // after next keyframe after showing some corruption.
+    DCHECK_LE(output_size, output_buffer_byte_size_);
+    if (output_size > output_buffer_byte_size_)
+      output_size = output_buffer_byte_size_;
+    uint8* target_data =
+        reinterpret_cast<uint8*>(output_record.buffer_ref->shm->memory());
+    if (output_format_fourcc_ == V4L2_PIX_FMT_H264) {
+      if (stream_header_size_ == 0) {
+        // Assume that the first buffer dequeued is the stream header.
+        stream_header_size_ = output_size;
+        stream_header_.reset(new uint8[stream_header_size_]);
+        memcpy(stream_header_.get(), output_data, stream_header_size_);
+      }
+      if (key_frame &&
+          output_buffer_byte_size_ - stream_header_size_ >= output_size) {
+        // Insert stream header before every keyframe.
+        memcpy(target_data, stream_header_.get(), stream_header_size_);
+        memcpy(target_data + stream_header_size_, output_data, output_size);
+        output_size += stream_header_size_;
+      } else {
+        memcpy(target_data, output_data, output_size);
+      }
+    } else {
+      memcpy(target_data, output_data, output_size);
+    }
+
+    DVLOG(3) << "Dequeue(): returning "
+                "bitstream_buffer_id=" << output_record.buffer_ref->id
+             << ", size=" << output_size << ", key_frame=" << key_frame;
+    child_message_loop_proxy_->PostTask(
+        FROM_HERE,
+        base::Bind(&Client::BitstreamBufferReady,
+                   client_,
+                   output_record.buffer_ref->id,
+                   output_size,
+                   key_frame));
+    output_record.at_device = false;
+    output_record.buffer_ref.reset();
+    free_output_buffers_.push_back(dqbuf.index);
+    output_buffer_queued_count_--;
+  }
+}
+
+bool V4L2VideoEncodeAccelerator::EnqueueInputRecord() {
+  DVLOG(3) << "EnqueueInputRecord()";
+  DCHECK(!free_input_buffers_.empty());
+  DCHECK(!encoder_input_queue_.empty());
+
+  // Enqueue an input (VIDEO_OUTPUT) buffer.
+  scoped_refptr<media::VideoFrame> frame = encoder_input_queue_.front();
+  const int index = free_input_buffers_.back();
+  InputRecord& input_record = input_buffer_map_[index];
+  DCHECK(!input_record.at_device);
+  struct v4l2_buffer qbuf;
+  struct v4l2_plane qbuf_planes[VIDEO_MAX_PLANES];
+  memset(&qbuf, 0, sizeof(qbuf));
+  memset(qbuf_planes, 0, sizeof(qbuf_planes));
+  qbuf.index = index;
+  qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  qbuf.m.planes = qbuf_planes;
+
+  DCHECK_EQ(device_input_format_, frame->format());
+  for (size_t i = 0; i < input_planes_count_; ++i) {
+    qbuf.m.planes[i].bytesused =
+        base::checked_cast<__u32>(media::VideoFrame::PlaneAllocationSize(
+            frame->format(), i, input_allocated_size_));
+
+    switch (input_memory_type_) {
+      case V4L2_MEMORY_USERPTR:
+        qbuf.m.planes[i].m.userptr =
+            reinterpret_cast<unsigned long>(frame->data(i));
+        DCHECK(qbuf.m.planes[i].m.userptr);
+        break;
+
+      case V4L2_MEMORY_DMABUF:
+        qbuf.m.planes[i].m.fd = frame->dmabuf_fd(i);
+        DCHECK_NE(qbuf.m.planes[i].m.fd, -1);
+        break;
+
+      default:
+        NOTREACHED();
+        return false;
+    }
+  }
+
+  qbuf.memory = input_memory_type_;
+  qbuf.length = input_planes_count_;
+
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
+  input_record.at_device = true;
+  input_record.frame = frame;
+  encoder_input_queue_.pop_front();
+  free_input_buffers_.pop_back();
+  input_buffer_queued_count_++;
+  return true;
+}
+
+bool V4L2VideoEncodeAccelerator::EnqueueOutputRecord() {
+  DVLOG(3) << "EnqueueOutputRecord()";
+  DCHECK(!free_output_buffers_.empty());
+  DCHECK(!encoder_output_queue_.empty());
+
+  // Enqueue an output (VIDEO_CAPTURE) buffer.
+  linked_ptr<BitstreamBufferRef> output_buffer = encoder_output_queue_.back();
+  const int index = free_output_buffers_.back();
+  OutputRecord& output_record = output_buffer_map_[index];
+  DCHECK(!output_record.at_device);
+  DCHECK(!output_record.buffer_ref.get());
+  struct v4l2_buffer qbuf;
+  struct v4l2_plane qbuf_planes[1];
+  memset(&qbuf, 0, sizeof(qbuf));
+  memset(qbuf_planes, 0, sizeof(qbuf_planes));
+  qbuf.index = index;
+  qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  qbuf.memory = V4L2_MEMORY_MMAP;
+  qbuf.m.planes = qbuf_planes;
+  qbuf.length = 1;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
+  output_record.at_device = true;
+  output_record.buffer_ref = output_buffer;
+  encoder_output_queue_.pop_back();
+  free_output_buffers_.pop_back();
+  output_buffer_queued_count_++;
+  return true;
+}
+
+bool V4L2VideoEncodeAccelerator::StartDevicePoll() {
+  DVLOG(3) << "StartDevicePoll()";
+  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
+  DCHECK(!device_poll_thread_.IsRunning());
+
+  // Start up the device poll thread and schedule its first DevicePollTask().
+  if (!device_poll_thread_.Start()) {
+    DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
+    NOTIFY_ERROR(kPlatformFailureError);
+    return false;
+  }
+  // Enqueue a poll task with no devices to poll on -- it will wait only on the
+  // interrupt fd.
+  device_poll_thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&V4L2VideoEncodeAccelerator::DevicePollTask,
+                 base::Unretained(this),
+                 false));
+
+  return true;
+}
+
+bool V4L2VideoEncodeAccelerator::StopDevicePoll() {
+  DVLOG(3) << "StopDevicePoll()";
+
+  // Signal the DevicePollTask() to stop, and stop the device poll thread.
+  if (!device_->SetDevicePollInterrupt())
+    return false;
+  device_poll_thread_.Stop();
+  // Clear the interrupt now, to be sure.
+  if (!device_->ClearDevicePollInterrupt())
+    return false;
+
+  if (input_streamon_) {
+    __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type);
+  }
+  input_streamon_ = false;
+
+  if (output_streamon_) {
+    __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_STREAMOFF, &type);
+  }
+  output_streamon_ = false;
+
+  // Reset all our accounting info.
+  encoder_input_queue_.clear();
+  free_input_buffers_.clear();
+  for (size_t i = 0; i < input_buffer_map_.size(); ++i) {
+    InputRecord& input_record = input_buffer_map_[i];
+    input_record.at_device = false;
+    input_record.frame = NULL;
+    free_input_buffers_.push_back(i);
+  }
+  input_buffer_queued_count_ = 0;
+
+  free_output_buffers_.clear();
+  for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
+    OutputRecord& output_record = output_buffer_map_[i];
+    output_record.at_device = false;
+    output_record.buffer_ref.reset();
+    free_output_buffers_.push_back(i);
+  }
+  output_buffer_queued_count_ = 0;
+
+  encoder_output_queue_.clear();
+
+  DVLOG(3) << "StopDevicePoll(): device poll stopped";
+  return true;
+}
+
+void V4L2VideoEncodeAccelerator::DevicePollTask(bool poll_device) {
+  DVLOG(3) << "DevicePollTask()";
+  DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current());
+
+  bool event_pending;
+  if (!device_->Poll(poll_device, &event_pending)) {
+    NOTIFY_ERROR(kPlatformFailureError);
+    return;
+  }
+
+  // All processing should happen on ServiceDeviceTask(), since we shouldn't
+  // touch encoder state from this thread.
+  encoder_thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&V4L2VideoEncodeAccelerator::ServiceDeviceTask,
+                 base::Unretained(this)));
+}
+
+void V4L2VideoEncodeAccelerator::NotifyError(Error error) {
+  DVLOG(1) << "NotifyError(): error=" << error;
+
+  if (!child_message_loop_proxy_->BelongsToCurrentThread()) {
+    child_message_loop_proxy_->PostTask(
+        FROM_HERE,
+        base::Bind(
+            &V4L2VideoEncodeAccelerator::NotifyError, weak_this_, error));
+    return;
+  }
+
+  if (client_) {
+    client_->NotifyError(error);
+    client_ptr_factory_.reset();
+  }
+}
+
+void V4L2VideoEncodeAccelerator::SetEncoderState(State state) {
+  DVLOG(3) << "SetEncoderState(): state=" << state;
+
+  // We can touch encoder_state_ only if this is the encoder thread or the
+  // encoder thread isn't running.
+  if (encoder_thread_.message_loop() != NULL &&
+      encoder_thread_.message_loop() != base::MessageLoop::current()) {
+    encoder_thread_.message_loop()->PostTask(
+        FROM_HERE,
+        base::Bind(&V4L2VideoEncodeAccelerator::SetEncoderState,
+                   base::Unretained(this),
+                   state));
+  } else {
+    encoder_state_ = state;
+  }
+}
+
+void V4L2VideoEncodeAccelerator::RequestEncodingParametersChangeTask(
+    uint32 bitrate,
+    uint32 framerate) {
+  DVLOG(3) << "RequestEncodingParametersChangeTask(): bitrate=" << bitrate
+           << ", framerate=" << framerate;
+  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
+
+  if (bitrate < 1)
+    bitrate = 1;
+  if (framerate < 1)
+    framerate = 1;
+
+  struct v4l2_ext_control ctrls[1];
+  struct v4l2_ext_controls control;
+  memset(&ctrls, 0, sizeof(ctrls));
+  memset(&control, 0, sizeof(control));
+  ctrls[0].id = V4L2_CID_MPEG_VIDEO_BITRATE;
+  ctrls[0].value = bitrate;
+  control.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+  control.count = arraysize(ctrls);
+  control.controls = ctrls;
+  IOCTL_OR_ERROR_RETURN(VIDIOC_S_EXT_CTRLS, &control);
+
+  struct v4l2_streamparm parms;
+  memset(&parms, 0, sizeof(parms));
+  parms.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  // Note that we are provided "frames per second" but V4L2 expects "time per
+  // frame"; hence we provide the reciprocal of the framerate here.
+  parms.parm.output.timeperframe.numerator = 1;
+  parms.parm.output.timeperframe.denominator = framerate;
+  IOCTL_OR_ERROR_RETURN(VIDIOC_S_PARM, &parms);
+}
+
+bool V4L2VideoEncodeAccelerator::SetOutputFormat(
+    media::VideoCodecProfile output_profile) {
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(!input_streamon_);
+  DCHECK(!output_streamon_);
+
+  output_format_fourcc_ =
+      V4L2Device::VideoCodecProfileToV4L2PixFmt(output_profile);
+  if (!output_format_fourcc_) {
+    DLOG(ERROR) << "Initialize(): invalid output_profile=" << output_profile;
+    return false;
+  }
+
+  output_buffer_byte_size_ = kOutputBufferSize;
+
+  struct v4l2_format format;
+  memset(&format, 0, sizeof(format));
+  format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  format.fmt.pix_mp.width = visible_size_.width();
+  format.fmt.pix_mp.height = visible_size_.height();
+  format.fmt.pix_mp.pixelformat = output_format_fourcc_;
+  format.fmt.pix_mp.plane_fmt[0].sizeimage =
+      base::checked_cast<__u32>(output_buffer_byte_size_);
+  format.fmt.pix_mp.num_planes = 1;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format);
+
+  // Device might have adjusted the required output size.
+  size_t adjusted_output_buffer_size =
+      base::checked_cast<size_t>(format.fmt.pix_mp.plane_fmt[0].sizeimage);
+  DCHECK_GE(adjusted_output_buffer_size, output_buffer_byte_size_);
+  output_buffer_byte_size_ = adjusted_output_buffer_size;
+
+  return true;
+}
+
+bool V4L2VideoEncodeAccelerator::NegotiateInputFormat(
+    media::VideoFrame::Format input_format) {
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(!input_streamon_);
+  DCHECK(!output_streamon_);
+
+  device_input_format_ = media::VideoFrame::UNKNOWN;
+  input_planes_count_ = 0;
+
+  uint32 input_format_fourcc =
+      V4L2Device::VideoFrameFormatToV4L2PixFmt(input_format);
+  if (!input_format_fourcc) {
+    DVLOG(1) << "Unsupported input format";
+    return false;
+  }
+
+  size_t input_planes_count = media::VideoFrame::NumPlanes(input_format);
+  DCHECK_LE(input_planes_count, VIDEO_MAX_PLANES);
+
+  // First see if we the device can use the provided input_format directly.
+  struct v4l2_format format;
+  memset(&format, 0, sizeof(format));
+  format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  format.fmt.pix_mp.width = visible_size_.width();
+  format.fmt.pix_mp.height = visible_size_.height();
+  format.fmt.pix_mp.pixelformat = input_format_fourcc;
+  format.fmt.pix_mp.num_planes = input_planes_count;
+  if (device_->Ioctl(VIDIOC_S_FMT, &format) != 0) {
+    // Error or format unsupported by device, try to negotiate a fallback.
+    input_format_fourcc = device_->PreferredInputFormat();
+    input_format =
+        V4L2Device::V4L2PixFmtToVideoFrameFormat(input_format_fourcc);
+    if (input_format == media::VideoFrame::UNKNOWN)
+      return false;
+
+    input_planes_count = media::VideoFrame::NumPlanes(input_format);
+    DCHECK_LE(input_planes_count, VIDEO_MAX_PLANES);
+
+    // Device might have adjusted parameters, reset them along with the format.
+    memset(&format, 0, sizeof(format));
+    format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    format.fmt.pix_mp.width = visible_size_.width();
+    format.fmt.pix_mp.height = visible_size_.height();
+    format.fmt.pix_mp.pixelformat = input_format_fourcc;
+    format.fmt.pix_mp.num_planes = input_planes_count;
+    IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format);
+    DCHECK_EQ(format.fmt.pix_mp.num_planes, input_planes_count);
+  }
+
+  // Take device-adjusted sizes for allocated size.
+  input_allocated_size_ = V4L2Device::CodedSizeFromV4L2Format(format);
+  DCHECK(gfx::Rect(input_allocated_size_).Contains(gfx::Rect(visible_size_)));
+
+  device_input_format_ = input_format;
+  input_planes_count_ = input_planes_count;
+  return true;
+}
+
+bool V4L2VideoEncodeAccelerator::SetFormats(
+    media::VideoFrame::Format input_format,
+    media::VideoCodecProfile output_profile) {
+  DVLOG(3) << "SetFormats()";
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(!input_streamon_);
+  DCHECK(!output_streamon_);
+
+  if (!SetOutputFormat(output_profile))
+    return false;
+
+  if (!NegotiateInputFormat(input_format))
+    return false;
+
+  struct v4l2_crop crop;
+  memset(&crop, 0, sizeof(crop));
+  crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+  crop.c.left = 0;
+  crop.c.top = 0;
+  crop.c.width = visible_size_.width();
+  crop.c.height = visible_size_.height();
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CROP, &crop);
+
+  return true;
+}
+
+bool V4L2VideoEncodeAccelerator::InitControls() {
+  struct v4l2_ext_control ctrls[9];
+  struct v4l2_ext_controls control;
+  memset(&ctrls, 0, sizeof(ctrls));
+  memset(&control, 0, sizeof(control));
+  // No B-frames, for lowest decoding latency.
+  ctrls[0].id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
+  ctrls[0].value = 0;
+  // Enable frame-level bitrate control.
+  ctrls[1].id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
+  ctrls[1].value = 1;
+  // Enable "tight" bitrate mode. For this to work properly, frame- and mb-level
+  // bitrate controls have to be enabled as well.
+  ctrls[2].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF;
+  ctrls[2].value = 1;
+  // Force bitrate control to average over a GOP (for tight bitrate
+  // tolerance).
+  ctrls[3].id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT;
+  ctrls[3].value = 1;
+  // Quantization parameter maximum value (for variable bitrate control).
+  ctrls[4].id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
+  ctrls[4].value = 51;
+  // Separate stream header so we can cache it and insert into the stream.
+  ctrls[5].id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
+  ctrls[5].value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
+  // Enable macroblock-level bitrate control.
+  ctrls[6].id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE;
+  ctrls[6].value = 1;
+  // Use H.264 level 4.0 to match the supported max resolution.
+  ctrls[7].id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
+  ctrls[7].value = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
+  // Disable periodic key frames.
+  ctrls[8].id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
+  ctrls[8].value = 0;
+  control.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+  control.count = arraysize(ctrls);
+  control.controls = ctrls;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_EXT_CTRLS, &control);
+
+  return true;
+}
+
+bool V4L2VideoEncodeAccelerator::CreateInputBuffers() {
+  DVLOG(3) << "CreateInputBuffers()";
+  // This function runs on encoder_thread_ after output buffers have been
+  // provided by the client.
+  DCHECK_EQ(encoder_thread_.message_loop(), base::MessageLoop::current());
+  DCHECK(!input_streamon_);
+
+  struct v4l2_requestbuffers reqbufs;
+  memset(&reqbufs, 0, sizeof(reqbufs));
+  // Driver will modify to the appropriate number of buffers.
+  reqbufs.count = 1;
+  reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  // TODO(posciak): Once we start doing zero-copy, we should decide based on
+  // the current pipeline setup which memory type to use. This should probably
+  // be decided based on an argument to Initialize().
+  if (image_processor_.get())
+    input_memory_type_ = V4L2_MEMORY_DMABUF;
+  else
+    input_memory_type_ = V4L2_MEMORY_USERPTR;
+
+  reqbufs.memory = input_memory_type_;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs);
+
+  DCHECK(input_buffer_map_.empty());
+  input_buffer_map_.resize(reqbufs.count);
+  for (size_t i = 0; i < input_buffer_map_.size(); ++i)
+    free_input_buffers_.push_back(i);
+
+  return true;
+}
+
+bool V4L2VideoEncodeAccelerator::CreateOutputBuffers() {
+  DVLOG(3) << "CreateOutputBuffers()";
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(!output_streamon_);
+
+  struct v4l2_requestbuffers reqbufs;
+  memset(&reqbufs, 0, sizeof(reqbufs));
+  reqbufs.count = kOutputBufferCount;
+  reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  reqbufs.memory = V4L2_MEMORY_MMAP;
+  IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs);
+
+  DCHECK(output_buffer_map_.empty());
+  output_buffer_map_.resize(reqbufs.count);
+  for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
+    struct v4l2_plane planes[1];
+    struct v4l2_buffer buffer;
+    memset(&buffer, 0, sizeof(buffer));
+    memset(planes, 0, sizeof(planes));
+    buffer.index = i;
+    buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    buffer.memory = V4L2_MEMORY_MMAP;
+    buffer.m.planes = planes;
+    buffer.length = arraysize(planes);
+    IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYBUF, &buffer);
+    void* address = device_->Mmap(NULL,
+                                  buffer.m.planes[0].length,
+                                  PROT_READ | PROT_WRITE,
+                                  MAP_SHARED,
+                                  buffer.m.planes[0].m.mem_offset);
+    if (address == MAP_FAILED) {
+      DPLOG(ERROR) << "CreateOutputBuffers(): mmap() failed";
+      return false;
+    }
+    output_buffer_map_[i].address = address;
+    output_buffer_map_[i].length = buffer.m.planes[0].length;
+    free_output_buffers_.push_back(i);
+  }
+
+  return true;
+}
+
+void V4L2VideoEncodeAccelerator::DestroyInputBuffers() {
+  DVLOG(3) << "DestroyInputBuffers()";
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(!input_streamon_);
+
+  struct v4l2_requestbuffers reqbufs;
+  memset(&reqbufs, 0, sizeof(reqbufs));
+  reqbufs.count = 0;
+  reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  reqbufs.memory = input_memory_type_;
+  IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
+
+  input_buffer_map_.clear();
+  free_input_buffers_.clear();
+}
+
+void V4L2VideoEncodeAccelerator::DestroyOutputBuffers() {
+  DVLOG(3) << "DestroyOutputBuffers()";
+  DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(!output_streamon_);
+
+  for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
+    if (output_buffer_map_[i].address != NULL)
+      device_->Munmap(output_buffer_map_[i].address,
+                      output_buffer_map_[i].length);
+  }
+
+  struct v4l2_requestbuffers reqbufs;
+  memset(&reqbufs, 0, sizeof(reqbufs));
+  reqbufs.count = 0;
+  reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  reqbufs.memory = V4L2_MEMORY_MMAP;
+  IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs);
+
+  output_buffer_map_.clear();
+  free_output_buffers_.clear();
+}
+
+}  // namespace content
diff --git a/content/common/gpu/media/v4l2_video_encode_accelerator.h b/content/common/gpu/media/v4l2_video_encode_accelerator.h
new file mode 100644
index 0000000..15f580d
--- /dev/null
+++ b/content/common/gpu/media/v4l2_video_encode_accelerator.h
@@ -0,0 +1,283 @@
+// 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.
+
+#ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_
+#define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_
+
+#include <list>
+#include <linux/videodev2.h>
+#include <vector>
+
+#include "base/memory/linked_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread.h"
+#include "content/common/content_export.h"
+#include "content/common/gpu/media/v4l2_image_processor.h"
+#include "content/common/gpu/media/v4l2_video_device.h"
+#include "media/video/video_encode_accelerator.h"
+#include "ui/gfx/size.h"
+
+namespace base {
+
+class MessageLoopProxy;
+
+}  // namespace base
+
+namespace media {
+
+class BitstreamBuffer;
+
+}  // namespace media
+
+namespace content {
+
+// This class handles video encode acceleration by interfacing with a V4L2
+// device exposed by the codec hardware driver. The threading model of this
+// class is the same as in the V4L2VideoDecodeAccelerator (from which class this
+// was designed).
+// This class may try to instantiate and use a V4L2ImageProcessor for input
+// format conversion, if the input format requested via Initialize() is not
+// accepted by the hardware codec.
+class CONTENT_EXPORT V4L2VideoEncodeAccelerator
+    : public media::VideoEncodeAccelerator {
+ public:
+  explicit V4L2VideoEncodeAccelerator(scoped_ptr<V4L2Device> device);
+  virtual ~V4L2VideoEncodeAccelerator();
+
+  // media::VideoEncodeAccelerator implementation.
+  virtual bool Initialize(media::VideoFrame::Format format,
+                          const gfx::Size& input_visible_size,
+                          media::VideoCodecProfile output_profile,
+                          uint32 initial_bitrate,
+                          Client* client) OVERRIDE;
+  virtual void Encode(const scoped_refptr<media::VideoFrame>& frame,
+                      bool force_keyframe) OVERRIDE;
+  virtual void UseOutputBitstreamBuffer(const media::BitstreamBuffer& buffer)
+      OVERRIDE;
+  virtual void RequestEncodingParametersChange(uint32 bitrate,
+                                               uint32 framerate) OVERRIDE;
+  virtual void Destroy() OVERRIDE;
+
+  static std::vector<media::VideoEncodeAccelerator::SupportedProfile>
+      GetSupportedProfiles();
+
+ private:
+  // Auto-destroy reference for BitstreamBuffer, for tracking buffers passed to
+  // this instance.
+  struct BitstreamBufferRef;
+
+  // Record for codec input buffers.
+  struct InputRecord {
+    InputRecord();
+    bool at_device;
+    scoped_refptr<media::VideoFrame> frame;
+  };
+
+  // Record for output buffers.
+  struct OutputRecord {
+    OutputRecord();
+    bool at_device;
+    linked_ptr<BitstreamBufferRef> buffer_ref;
+    void* address;
+    size_t length;
+  };
+
+  enum {
+    kInitialFramerate = 30,
+    // These are rather subjectively tuned.
+    kInputBufferCount = 2,
+    kOutputBufferCount = 2,
+    kOutputBufferSize = (2 * 1024 * 1024),
+  };
+
+  // Internal state of the encoder.
+  enum State {
+    kUninitialized,  // Initialize() not yet called.
+    kInitialized,    // Initialize() returned true; ready to start encoding.
+    kEncoding,       // Encoding frames.
+    kError,          // Error in encoder state.
+  };
+
+  //
+  // Callbacks for the image processor, if one is used.
+  //
+
+  // Callback run by the image processor when a frame is ready for us to encode.
+  void FrameProcessed(bool force_keyframe,
+                      const scoped_refptr<media::VideoFrame>& frame);
+
+  // Error callback for handling image processor errors.
+  void ImageProcessorError();
+
+  //
+  // Encoding tasks, to be run on encode_thread_.
+  //
+
+  void EncodeTask(const scoped_refptr<media::VideoFrame>& frame,
+                  bool force_keyframe);
+
+  // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder
+  // output.
+  void UseOutputBitstreamBufferTask(scoped_ptr<BitstreamBufferRef> buffer_ref);
+
+  // Device destruction task.
+  void DestroyTask();
+
+  // Service I/O on the V4L2 devices.  This task should only be scheduled from
+  // DevicePollTask().
+  void ServiceDeviceTask();
+
+  // Handle the device queues.
+  void Enqueue();
+  void Dequeue();
+  // Enqueue a buffer on the corresponding queue.  Returns false on fatal error.
+  bool EnqueueInputRecord();
+  bool EnqueueOutputRecord();
+
+  // Attempt to start/stop device_poll_thread_.
+  bool StartDevicePoll();
+  bool StopDevicePoll();
+
+  //
+  // Device tasks, to be run on device_poll_thread_.
+  //
+
+  // The device task.
+  void DevicePollTask(bool poll_device);
+
+  //
+  // Safe from any thread.
+  //
+
+  // Error notification (using PostTask() to child thread, if necessary).
+  void NotifyError(Error error);
+
+  // Set the encoder_thread_ state (using PostTask to encoder thread, if
+  // necessary).
+  void SetEncoderState(State state);
+
+  //
+  // Other utility functions.  Called on encoder_thread_, unless
+  // encoder_thread_ is not yet started, in which case the child thread can call
+  // these (e.g. in Initialize() or Destroy()).
+  //
+
+  // Change encoding parameters.
+  void RequestEncodingParametersChangeTask(uint32 bitrate, uint32 framerate);
+
+  // Set up formats and initialize the device for them.
+  bool SetFormats(media::VideoFrame::Format input_format,
+                  media::VideoCodecProfile output_profile);
+
+  // Try to set up the device to the input format we were Initialized() with,
+  // or if the device doesn't support it, use one it can support, so that we
+  // can later instantiate a V4L2ImageProcessor to convert to it.
+  bool NegotiateInputFormat(media::VideoFrame::Format input_format);
+
+  // Set up the device to the output format requested in Initialize().
+  bool SetOutputFormat(media::VideoCodecProfile output_profile);
+
+  // Initialize device controls with default values.
+  bool InitControls();
+
+  // Create the buffers we need.
+  bool CreateInputBuffers();
+  bool CreateOutputBuffers();
+
+  // Destroy these buffers.
+  void DestroyInputBuffers();
+  void DestroyOutputBuffers();
+
+  // Our original calling message loop for the child thread.
+  const scoped_refptr<base::MessageLoopProxy> child_message_loop_proxy_;
+
+  // WeakPtr<> pointing to |this| for use in posting tasks from the encoder or
+  // device worker threads back to the child thread.  Because the worker threads
+  // are members of this class, any task running on those threads is guaranteed
+  // that this object is still alive.  As a result, tasks posted from the child
+  // thread to the encoder or device thread should use base::Unretained(this),
+  // and tasks posted the other way should use |weak_this_|.
+  base::WeakPtrFactory<V4L2VideoEncodeAccelerator> weak_this_ptr_factory_;
+  base::WeakPtr<V4L2VideoEncodeAccelerator> weak_this_;
+
+  // To expose client callbacks from VideoEncodeAccelerator.
+  // NOTE: all calls to these objects *MUST* be executed on
+  // child_message_loop_proxy_.
+  scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_;
+  base::WeakPtr<Client> client_;
+
+  gfx::Size visible_size_;
+  // Input allocated size required by the device.
+  gfx::Size input_allocated_size_;
+  size_t output_buffer_byte_size_;
+
+  // Formats for input frames and the output stream.
+  media::VideoFrame::Format device_input_format_;
+  size_t input_planes_count_;
+  uint32 output_format_fourcc_;
+
+  //
+  // Encoder state, owned and operated by encoder_thread_.
+  // Before encoder_thread_ has started, the encoder state is managed by
+  // the child (main) thread.  After encoder_thread_ has started, the encoder
+  // thread should be the only one managing these.
+  //
+
+  // This thread services tasks posted from the VEA API entry points by the
+  // child thread and device service callbacks posted from the device thread.
+  base::Thread encoder_thread_;
+  // Encoder state.
+  State encoder_state_;
+
+  // We need to provide the stream header with every keyframe, to allow
+  // midstream decoding restarts.  Store it here.
+  scoped_ptr<uint8[]> stream_header_;
+  size_t stream_header_size_;
+
+  // Video frames ready to be encoded.
+  std::list<scoped_refptr<media::VideoFrame> > encoder_input_queue_;
+
+  // Encoder device.
+  scoped_ptr<V4L2Device> device_;
+
+  // Input queue state.
+  bool input_streamon_;
+  // Input buffers enqueued to device.
+  int input_buffer_queued_count_;
+  // Input buffers ready to use; LIFO since we don't care about ordering.
+  std::vector<int> free_input_buffers_;
+  // Mapping of int index to input buffer record.
+  std::vector<InputRecord> input_buffer_map_;
+  enum v4l2_memory input_memory_type_;
+
+  // Output queue state.
+  bool output_streamon_;
+  // Output buffers enqueued to device.
+  int output_buffer_queued_count_;
+  // Output buffers ready to use; LIFO since we don't care about ordering.
+  std::vector<int> free_output_buffers_;
+  // Mapping of int index to output buffer record.
+  std::vector<OutputRecord> output_buffer_map_;
+
+  // Bitstream buffers ready to be used to return encoded output, as a LIFO
+  // since we don't care about ordering.
+  std::vector<linked_ptr<BitstreamBufferRef> > encoder_output_queue_;
+
+  //
+  // The device polling thread handles notifications of V4L2 device changes.
+  // TODO(sheu): replace this thread with an TYPE_IO encoder_thread_.
+  //
+
+  // The thread.
+  base::Thread device_poll_thread_;
+
+  // Image processor, if one is in use.
+  scoped_ptr<V4L2ImageProcessor> image_processor_;
+
+  DISALLOW_COPY_AND_ASSIGN(V4L2VideoEncodeAccelerator);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_ENCODE_ACCELERATOR_H_
diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc
index 87a899f..f758373 100644
--- a/content/common/gpu/media/video_decode_accelerator_unittest.cc
+++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc
@@ -553,14 +553,14 @@
       new DXVAVideoDecodeAccelerator(base::Bind(&DoNothingReturnTrue)));
 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL)
 
-  scoped_ptr<V4L2Device> device = V4L2Device::Create(
-      static_cast<EGLContext>(rendering_helper_->GetGLContext()));
+  scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder);
   if (!device.get()) {
     NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
     return;
   }
   decoder_.reset(new V4L2VideoDecodeAccelerator(
       static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()),
+      static_cast<EGLContext>(rendering_helper_->GetGLContext()),
       weak_client,
       base::Bind(&DoNothingReturnTrue),
       device.Pass(),
diff --git a/content/common/gpu/media/video_encode_accelerator_unittest.cc b/content/common/gpu/media/video_encode_accelerator_unittest.cc
index d8c8eef..56d40a2 100644
--- a/content/common/gpu/media/video_encode_accelerator_unittest.cc
+++ b/content/common/gpu/media/video_encode_accelerator_unittest.cc
@@ -13,7 +13,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/time/time.h"
-#include "content/common/gpu/media/exynos_video_encode_accelerator.h"
+#include "content/common/gpu/media/v4l2_video_encode_accelerator.h"
 #include "content/common/gpu/media/video_accelerator_unittest_helpers.h"
 #include "media/base/bind_to_current_loop.h"
 #include "media/base/bitstream_buffer.h"
@@ -53,6 +53,8 @@
 // Minimum required FPS throughput for the basic performance test.
 const uint32 kMinPerfFPS = 30;
 
+// The syntax of multiple test streams is:
+//  test-stream1;test-stream2;test-stream3
 // The syntax of each test stream is:
 // "in_filename:width:height:out_filename:requested_bitrate:requested_framerate
 //  :requested_subsequent_bitrate:requested_subsequent_framerate"
@@ -93,46 +95,102 @@
   unsigned int requested_subsequent_framerate;
 };
 
+// Parse |data| into its constituent parts, set the various output fields
+// accordingly, read in video stream, and store them to |test_streams|.
 static void ParseAndReadTestStreamData(const base::FilePath::StringType& data,
-                                       TestStream* test_stream) {
-  std::vector<base::FilePath::StringType> fields;
-  base::SplitString(data, ':', &fields);
-  CHECK_GE(fields.size(), 4U) << data;
-  CHECK_LE(fields.size(), 9U) << data;
+                                       ScopedVector<TestStream>* test_streams) {
+  // Split the string to individual test stream data.
+  std::vector<base::FilePath::StringType> test_streams_data;
+  base::SplitString(data, ';', &test_streams_data);
+  CHECK_GE(test_streams_data.size(), 1U) << data;
 
-  base::FilePath::StringType filename = fields[0];
-  int width, height;
-  CHECK(base::StringToInt(fields[1], &width));
-  CHECK(base::StringToInt(fields[2], &height));
-  test_stream->size = gfx::Size(width, height);
-  CHECK(!test_stream->size.IsEmpty());
-  int profile;
-  CHECK(base::StringToInt(fields[3], &profile));
-  CHECK_GT(profile, media::VIDEO_CODEC_PROFILE_UNKNOWN);
-  CHECK_LE(profile, media::VIDEO_CODEC_PROFILE_MAX);
-  test_stream->requested_profile =
-      static_cast<media::VideoCodecProfile>(profile);
+  // Parse each test stream data and read the input file.
+  for (size_t index = 0; index < test_streams_data.size(); ++index) {
+    std::vector<base::FilePath::StringType> fields;
+    base::SplitString(test_streams_data[index], ':', &fields);
+    CHECK_GE(fields.size(), 4U) << data;
+    CHECK_LE(fields.size(), 9U) << data;
+    TestStream* test_stream = new TestStream();
 
-  if (fields.size() >= 5 && !fields[4].empty())
-    test_stream->out_filename = fields[4];
+    base::FilePath::StringType filename = fields[0];
+    int width, height;
+    CHECK(base::StringToInt(fields[1], &width));
+    CHECK(base::StringToInt(fields[2], &height));
+    test_stream->size = gfx::Size(width, height);
+    CHECK(!test_stream->size.IsEmpty());
+    int profile;
+    CHECK(base::StringToInt(fields[3], &profile));
+    CHECK_GT(profile, media::VIDEO_CODEC_PROFILE_UNKNOWN);
+    CHECK_LE(profile, media::VIDEO_CODEC_PROFILE_MAX);
+    test_stream->requested_profile =
+        static_cast<media::VideoCodecProfile>(profile);
 
-  if (fields.size() >= 6 && !fields[5].empty())
-    CHECK(base::StringToUint(fields[5], &test_stream->requested_bitrate));
+    if (fields.size() >= 5 && !fields[4].empty())
+      test_stream->out_filename = fields[4];
 
-  if (fields.size() >= 7 && !fields[6].empty())
-    CHECK(base::StringToUint(fields[6], &test_stream->requested_framerate));
+    if (fields.size() >= 6 && !fields[5].empty())
+      CHECK(base::StringToUint(fields[5], &test_stream->requested_bitrate));
 
-  if (fields.size() >= 8 && !fields[7].empty()) {
-    CHECK(base::StringToUint(fields[7],
-                             &test_stream->requested_subsequent_bitrate));
+    if (fields.size() >= 7 && !fields[6].empty())
+      CHECK(base::StringToUint(fields[6], &test_stream->requested_framerate));
+
+    if (fields.size() >= 8 && !fields[7].empty()) {
+      CHECK(base::StringToUint(fields[7],
+                               &test_stream->requested_subsequent_bitrate));
+    }
+
+    if (fields.size() >= 9 && !fields[8].empty()) {
+      CHECK(base::StringToUint(fields[8],
+                               &test_stream->requested_subsequent_framerate));
+    }
+
+    CHECK(test_stream->input_file.Initialize(base::FilePath(filename)));
+    test_streams->push_back(test_stream);
   }
+}
 
-  if (fields.size() >= 9 && !fields[8].empty()) {
-    CHECK(base::StringToUint(fields[8],
-                             &test_stream->requested_subsequent_framerate));
+// Set default parameters of |test_streams| and update the parameters according
+// to |mid_stream_bitrate_switch| and |mid_stream_framerate_switch|.
+static void UpdateTestStreamData(bool mid_stream_bitrate_switch,
+                                 bool mid_stream_framerate_switch,
+                                 ScopedVector<TestStream>* test_streams) {
+  for (size_t i = 0; i < test_streams->size(); i++) {
+    TestStream* test_stream = (*test_streams)[i];
+    // Use defaults for bitrate/framerate if they are not provided.
+    if (test_stream->requested_bitrate == 0)
+      test_stream->requested_bitrate = kDefaultBitrate;
+
+    if (test_stream->requested_framerate == 0)
+      test_stream->requested_framerate = kDefaultFramerate;
+
+    // If bitrate/framerate switch is requested, use the subsequent values if
+    // provided, or, if not, calculate them from their initial values using
+    // the default ratios.
+    // Otherwise, if a switch is not requested, keep the initial values.
+    if (mid_stream_bitrate_switch) {
+      if (test_stream->requested_subsequent_bitrate == 0) {
+        test_stream->requested_subsequent_bitrate =
+            test_stream->requested_bitrate * kDefaultSubsequentBitrateRatio;
+      }
+    } else {
+      test_stream->requested_subsequent_bitrate =
+          test_stream->requested_bitrate;
+    }
+    if (test_stream->requested_subsequent_bitrate == 0)
+      test_stream->requested_subsequent_bitrate = 1;
+
+    if (mid_stream_framerate_switch) {
+      if (test_stream->requested_subsequent_framerate == 0) {
+        test_stream->requested_subsequent_framerate =
+            test_stream->requested_framerate * kDefaultSubsequentFramerateRatio;
+      }
+    } else {
+      test_stream->requested_subsequent_framerate =
+          test_stream->requested_framerate;
+    }
+    if (test_stream->requested_subsequent_framerate == 0)
+      test_stream->requested_subsequent_framerate = 1;
   }
-
-  CHECK(test_stream->input_file.Initialize(base::FilePath(filename)));
 }
 
 enum ClientState {
@@ -348,6 +406,7 @@
   scoped_ptr<VideoEncodeAccelerator> encoder_;
 
   const TestStream& test_stream_;
+  // Used to notify another thread about the state. VEAClient does not own this.
   ClientStateNotification<ClientState>* note_;
 
   // Ids assigned to VideoFrames (start at 1 for easy comparison with
@@ -472,7 +531,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   CHECK(!has_encoder());
 
-  encoder_.reset(new ExynosVideoEncodeAccelerator());
+  scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder);
+  encoder_.reset(new V4L2VideoEncodeAccelerator(device.Pass()));
   SetState(CS_ENCODER_SET);
 
   DVLOG(1) << "Profile: " << test_stream_.requested_profile
@@ -602,6 +662,7 @@
 }
 
 void VEAClient::SetState(ClientState new_state) {
+  DVLOG(4) << "Changing state " << state_ << "->" << new_state;
   note_->Notify(new_state);
   state_ = new_state;
 }
@@ -631,6 +692,7 @@
   uint8* frame_data =
       const_cast<uint8*>(test_stream_.input_file.data() + position);
 
+  CHECK_GT(current_framerate_, 0);
   scoped_refptr<media::VideoFrame> frame =
       media::VideoFrame::WrapExternalYuvData(
           kInputFormat,
@@ -643,7 +705,9 @@
           frame_data,
           frame_data + input_coded_size_.GetArea(),
           frame_data + (input_coded_size_.GetArea() * 5 / 4),
-          base::TimeDelta(),
+          base::TimeDelta().FromMilliseconds(
+              next_input_id_ * base::Time::kMillisecondsPerSecond /
+              current_framerate_),
           media::BindToCurrentLoop(
               base::Bind(&VEAClient::InputNoLongerNeededCallback,
                          base::Unretained(this),
@@ -789,6 +853,7 @@
 }
 
 // Test parameters:
+// - Number of concurrent encoders.
 // - If true, save output to file (provided an output filename was supplied).
 // - Force a keyframe every n frames.
 // - Force bitrate; the actual required value is provided as a property
@@ -798,122 +863,114 @@
 // - If true, switch framerate mid-stream.
 class VideoEncodeAcceleratorTest
     : public ::testing::TestWithParam<
-         Tuple6<bool, int, bool, bool, bool, bool> > {};
+          Tuple7<int, bool, int, bool, bool, bool, bool> > {};
 
 TEST_P(VideoEncodeAcceleratorTest, TestSimpleEncode) {
-  const unsigned int keyframe_period = GetParam().b;
-  const bool force_bitrate = GetParam().c;
-  const bool test_perf = GetParam().d;
-  const bool mid_stream_bitrate_switch = GetParam().e;
-  const bool mid_stream_framerate_switch = GetParam().f;
+  const int num_concurrent_encoders = GetParam().a;
+  const bool save_to_file = GetParam().b;
+  const unsigned int keyframe_period = GetParam().c;
+  const bool force_bitrate = GetParam().d;
+  const bool test_perf = GetParam().e;
+  const bool mid_stream_bitrate_switch = GetParam().f;
+  const bool mid_stream_framerate_switch = GetParam().g;
 
-  TestStream test_stream;
-  ParseAndReadTestStreamData(*g_test_stream_data, &test_stream);
+  // Initialize the test streams.
+  ScopedVector<TestStream> test_streams;
+  ParseAndReadTestStreamData(*g_test_stream_data, &test_streams);
+  UpdateTestStreamData(
+      mid_stream_bitrate_switch, mid_stream_framerate_switch, &test_streams);
 
-  // Disregard save_to_file if we didn't get an output filename.
-  const bool save_to_file = GetParam().a && !test_stream.out_filename.empty();
+  ScopedVector<ClientStateNotification<ClientState> > notes;
+  // The clients can only be deleted after the encoder threads are stopped.
+  ScopedVector<VEAClient> clients;
+  ScopedVector<base::Thread> encoder_threads;
 
-  // Use defaults for bitrate/framerate if they are not provided.
-  if (test_stream.requested_bitrate == 0)
-    test_stream.requested_bitrate = kDefaultBitrate;
+  // Create all the encoders.
+  for (int i = 0; i < num_concurrent_encoders; i++) {
+    int test_stream_index = i % test_streams.size();
+    // Disregard save_to_file if we didn't get an output filename.
+    bool encoder_save_to_file =
+        (save_to_file &&
+         !test_streams[test_stream_index]->out_filename.empty());
 
-  if (test_stream.requested_framerate == 0)
-    test_stream.requested_framerate = kDefaultFramerate;
+    notes.push_back(new ClientStateNotification<ClientState>());
+    clients.push_back(new VEAClient(*test_streams[test_stream_index],
+                                    notes.back(),
+                                    encoder_save_to_file,
+                                    keyframe_period,
+                                    force_bitrate,
+                                    test_perf));
 
-  // If bitrate/framerate switch is requested, use the subsequent values if
-  // provided, or, if not, calculate them from their initial values using
-  // the default ratios.
-  // Otherwise, if a switch is not requested, keep the initial values.
-  if (mid_stream_bitrate_switch) {
-    if (test_stream.requested_subsequent_bitrate == 0) {
-      test_stream.requested_subsequent_bitrate =
-          test_stream.requested_bitrate * kDefaultSubsequentBitrateRatio;
-    }
-  } else {
-    test_stream.requested_subsequent_bitrate = test_stream.requested_bitrate;
+    // Initialize the encoder thread.
+    char thread_name[32];
+    sprintf(thread_name, "EncoderThread%d", i);
+    base::Thread* encoder_thread = new base::Thread(thread_name);
+    encoder_thread->Start();
+    encoder_thread->message_loop()->PostTask(
+        FROM_HERE,
+        base::Bind(&VEAClient::CreateEncoder,
+                   base::Unretained(clients.back())));
+    encoder_threads.push_back(encoder_thread);
   }
-  if (test_stream.requested_subsequent_bitrate == 0)
-    test_stream.requested_subsequent_bitrate = 1;
 
-  if (mid_stream_framerate_switch) {
-    if (test_stream.requested_subsequent_framerate == 0) {
-      test_stream.requested_subsequent_framerate =
-          test_stream.requested_framerate * kDefaultSubsequentFramerateRatio;
-    }
-  } else {
-    test_stream.requested_subsequent_framerate =
-        test_stream.requested_framerate;
+  // Wait all the encoders to finish.
+  for (int i = 0; i < num_concurrent_encoders; i++) {
+    ASSERT_EQ(notes[i]->Wait(), CS_ENCODER_SET);
+    ASSERT_EQ(notes[i]->Wait(), CS_INITIALIZED);
+    ASSERT_EQ(notes[i]->Wait(), CS_ENCODING);
+    ASSERT_EQ(notes[i]->Wait(), CS_FINISHING);
+    ASSERT_EQ(notes[i]->Wait(), CS_FINISHED);
+    encoder_threads[i]->message_loop()->PostTask(
+        FROM_HERE,
+        base::Bind(&VEAClient::DestroyEncoder, base::Unretained(clients[i])));
+    encoder_threads[i]->Stop();
   }
-  if (test_stream.requested_subsequent_framerate == 0)
-    test_stream.requested_subsequent_framerate = 1;
-
-  base::Thread encoder_thread("EncoderThread");
-  encoder_thread.Start();
-
-  ClientStateNotification<ClientState> note;
-  scoped_ptr<VEAClient> client(new VEAClient(test_stream,
-                                             &note,
-                                             save_to_file,
-                                             keyframe_period,
-                                             force_bitrate,
-                                             test_perf));
-
-  encoder_thread.message_loop()->PostTask(
-      FROM_HERE,
-      base::Bind(&VEAClient::CreateEncoder, base::Unretained(client.get())));
-
-  ASSERT_EQ(note.Wait(), CS_ENCODER_SET);
-  ASSERT_EQ(note.Wait(), CS_INITIALIZED);
-  ASSERT_EQ(note.Wait(), CS_ENCODING);
-  ASSERT_EQ(note.Wait(), CS_FINISHING);
-  ASSERT_EQ(note.Wait(), CS_FINISHED);
-
-  encoder_thread.message_loop()->PostTask(
-      FROM_HERE,
-      base::Bind(&VEAClient::DestroyEncoder, base::Unretained(client.get())));
-
-  encoder_thread.Stop();
 }
 
-INSTANTIATE_TEST_CASE_P(SimpleEncode,
-                        VideoEncodeAcceleratorTest,
-                        ::testing::Values(MakeTuple(
-                            true, 0, false, false, false, false)));
+INSTANTIATE_TEST_CASE_P(
+    SimpleEncode,
+    VideoEncodeAcceleratorTest,
+    ::testing::Values(MakeTuple(1, true, 0, false, false, false, false)));
 
-INSTANTIATE_TEST_CASE_P(EncoderPerf,
-                        VideoEncodeAcceleratorTest,
-                        ::testing::Values(MakeTuple(
-                            false, 0, false, true, false, false)));
+INSTANTIATE_TEST_CASE_P(
+    EncoderPerf,
+    VideoEncodeAcceleratorTest,
+    ::testing::Values(MakeTuple(1, false, 0, false, true, false, false)));
 
-INSTANTIATE_TEST_CASE_P(ForceKeyframes,
-                        VideoEncodeAcceleratorTest,
-                        ::testing::Values(MakeTuple(
-                            false, 10, false, false, false, false)));
+INSTANTIATE_TEST_CASE_P(
+    ForceKeyframes,
+    VideoEncodeAcceleratorTest,
+    ::testing::Values(MakeTuple(1, false, 10, false, false, false, false)));
 
-INSTANTIATE_TEST_CASE_P(ForceBitrate,
-                        VideoEncodeAcceleratorTest,
-                        ::testing::Values(MakeTuple(
-                            false, 0, true, false, false, false)));
+INSTANTIATE_TEST_CASE_P(
+    ForceBitrate,
+    VideoEncodeAcceleratorTest,
+    ::testing::Values(MakeTuple(1, false, 0, true, false, false, false)));
 
-INSTANTIATE_TEST_CASE_P(MidStreamParamSwitchBitrate,
-                        VideoEncodeAcceleratorTest,
-                        ::testing::Values(MakeTuple(
-                            false, 0, true, false, true, false)));
+INSTANTIATE_TEST_CASE_P(
+    MidStreamParamSwitchBitrate,
+    VideoEncodeAcceleratorTest,
+    ::testing::Values(MakeTuple(1, false, 0, true, false, true, false)));
 
-INSTANTIATE_TEST_CASE_P(MidStreamParamSwitchFPS,
-                        VideoEncodeAcceleratorTest,
-                        ::testing::Values(MakeTuple(
-                            false, 0, true, false, false, true)));
+INSTANTIATE_TEST_CASE_P(
+    MidStreamParamSwitchFPS,
+    VideoEncodeAcceleratorTest,
+    ::testing::Values(MakeTuple(1, false, 0, true, false, false, true)));
 
-INSTANTIATE_TEST_CASE_P(MidStreamParamSwitchBitrateAndFPS,
-                        VideoEncodeAcceleratorTest,
-                        ::testing::Values(MakeTuple(
-                            false, 0, true, false, true, true)));
+INSTANTIATE_TEST_CASE_P(
+    MidStreamParamSwitchBitrateAndFPS,
+    VideoEncodeAcceleratorTest,
+    ::testing::Values(MakeTuple(1, false, 0, true, false, true, true)));
+
+INSTANTIATE_TEST_CASE_P(
+    MultipleEncoders,
+    VideoEncodeAcceleratorTest,
+    ::testing::Values(MakeTuple(3, false, 0, false, false, false, false),
+                      MakeTuple(3, false, 0, true, false, true, true)));
 
 // TODO(posciak): more tests:
 // - async FeedEncoderWithOutput
 // - out-of-order return of outputs to encoder
-// - multiple encoders
 // - multiple encoders + decoders
 // - mid-stream encoder_->Destroy()
 
diff --git a/content/common/input/input_event_ack_state.h b/content/common/input/input_event_ack_state.h
new file mode 100644
index 0000000..5b9c706
--- /dev/null
+++ b/content/common/input/input_event_ack_state.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2012 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.
+
+#ifndef CONTENT_COMMON_INPUT_INPUT_EVENT_ACK_STATE_H_
+#define CONTENT_COMMON_INPUT_INPUT_EVENT_ACK_STATE_H_
+
+namespace content {
+
+// Describes the state of the input event ACK coming back to the browser side.
+enum InputEventAckState {
+  INPUT_EVENT_ACK_STATE_UNKNOWN,
+  INPUT_EVENT_ACK_STATE_CONSUMED,
+  INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
+  INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
+  INPUT_EVENT_ACK_STATE_IGNORED,
+  INPUT_EVENT_ACK_STATE_MAX = INPUT_EVENT_ACK_STATE_IGNORED
+};
+
+}  // namespace content
+
+#endif  // CONTENT_COMMON_INPUT_INPUT_EVENT_ACK_STATE_H_
diff --git a/content/common/input/synthetic_web_input_event_builders.cc b/content/common/input/synthetic_web_input_event_builders.cc
index 1bdea99..2fcca34 100644
--- a/content/common/input/synthetic_web_input_event_builders.cc
+++ b/content/common/input/synthetic_web_input_event_builders.cc
@@ -123,12 +123,15 @@
     float scale,
     float anchor_x,
     float anchor_y,
-    int modifiers) {
-  WebGestureEvent result = Build(WebInputEvent::GesturePinchUpdate,
-                                 WebGestureEvent::Touchscreen);
+    int modifiers,
+    WebGestureEvent::SourceDevice source_device) {
+  WebGestureEvent result =
+      Build(WebInputEvent::GesturePinchUpdate, source_device);
   result.data.pinchUpdate.scale = scale;
   result.x = anchor_x;
   result.y = anchor_y;
+  result.globalX = anchor_x;
+  result.globalY = anchor_y;
   result.modifiers = modifiers;
   return result;
 }
diff --git a/content/common/input/synthetic_web_input_event_builders.h b/content/common/input/synthetic_web_input_event_builders.h
index 5df4cd6..3344251 100644
--- a/content/common/input/synthetic_web_input_event_builders.h
+++ b/content/common/input/synthetic_web_input_event_builders.h
@@ -41,16 +41,18 @@
  public:
   static blink::WebGestureEvent Build(
       blink::WebInputEvent::Type type,
-      blink::WebGestureEvent::SourceDevice sourceDevice);
+      blink::WebGestureEvent::SourceDevice source_device);
   static blink::WebGestureEvent BuildScrollBegin(float dx_hint,
                                                  float dy_hint);
   static blink::WebGestureEvent BuildScrollUpdate(float dx,
                                                   float dy,
                                                   int modifiers);
-  static blink::WebGestureEvent BuildPinchUpdate(float scale,
-                                                 float anchor_x,
-                                                 float anchor_y,
-                                                 int modifiers);
+  static blink::WebGestureEvent BuildPinchUpdate(
+      float scale,
+      float anchor_x,
+      float anchor_y,
+      int modifiers,
+      blink::WebGestureEvent::SourceDevice source_device);
   static blink::WebGestureEvent BuildFling(
       float velocity_x,
       float velocity_y,
diff --git a/content/common/input/web_input_event_traits.cc b/content/common/input/web_input_event_traits.cc
index 4dcd4ba..fa9f433 100644
--- a/content/common/input/web_input_event_traits.cc
+++ b/content/common/input/web_input_event_traits.cc
@@ -5,6 +5,7 @@
 #include "content/common/input/web_input_event_traits.h"
 
 #include <bitset>
+#include <limits>
 
 #include "base/logging.h"
 
@@ -14,6 +15,7 @@
 using blink::WebMouseEvent;
 using blink::WebMouseWheelEvent;
 using blink::WebTouchEvent;
+using std::numeric_limits;
 
 namespace content {
 namespace {
@@ -173,6 +175,12 @@
         event_to_coalesce.data.scrollUpdate.deltaY;
   } else if (event->type == WebInputEvent::GesturePinchUpdate) {
     event->data.pinchUpdate.scale *= event_to_coalesce.data.pinchUpdate.scale;
+    // Ensure the scale remains bounded above 0 and below Infinity so that
+    // we can reliably perform operations like log on the values.
+    if (event->data.pinchUpdate.scale < numeric_limits<float>::min())
+      event->data.pinchUpdate.scale = numeric_limits<float>::min();
+    else if (event->data.pinchUpdate.scale > numeric_limits<float>::max())
+      event->data.pinchUpdate.scale = numeric_limits<float>::max();
   }
 }
 
diff --git a/content/common/input/web_input_event_traits_unittest.cc b/content/common/input/web_input_event_traits_unittest.cc
index 7a18f2a..6eafb0f 100644
--- a/content/common/input/web_input_event_traits_unittest.cc
+++ b/content/common/input/web_input_event_traits_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "content/common/input/web_input_event_traits.h"
 
+#include <limits>
+
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 
@@ -11,6 +13,7 @@
 using blink::WebInputEvent;
 using blink::WebTouchEvent;
 using blink::WebTouchPoint;
+using std::numeric_limits;
 
 namespace content {
 namespace {
@@ -135,6 +138,25 @@
   EXPECT_TRUE(WebInputEventTraits::CanCoalesce(pinch0, pinch0));
   WebInputEventTraits::Coalesce(pinch0, &pinch1);
   EXPECT_EQ(2.f * 3.f, pinch1.data.pinchUpdate.scale);
+
+  // Scales have a minimum value and can never reach 0.
+  ASSERT_GT(numeric_limits<float>::min(), 0);
+  pinch0 = CreateGesture(WebInputEvent::GesturePinchUpdate, 1, 1);
+  pinch0.data.pinchUpdate.scale = numeric_limits<float>::min() * 2.0f;
+  pinch1 = CreateGesture(WebInputEvent::GesturePinchUpdate, 1, 1);
+  pinch1.data.pinchUpdate.scale = numeric_limits<float>::min() * 5.0f;
+  EXPECT_TRUE(WebInputEventTraits::CanCoalesce(pinch0, pinch1));
+  WebInputEventTraits::Coalesce(pinch0, &pinch1);
+  EXPECT_EQ(numeric_limits<float>::min(), pinch1.data.pinchUpdate.scale);
+
+  // Scales have a maximum value and can never reach Infinity.
+  pinch0 = CreateGesture(WebInputEvent::GesturePinchUpdate, 1, 1);
+  pinch0.data.pinchUpdate.scale = numeric_limits<float>::max() / 2.0f;
+  pinch1 = CreateGesture(WebInputEvent::GesturePinchUpdate, 1, 1);
+  pinch1.data.pinchUpdate.scale = 10.0f;
+  EXPECT_TRUE(WebInputEventTraits::CanCoalesce(pinch0, pinch1));
+  WebInputEventTraits::Coalesce(pinch0, &pinch1);
+  EXPECT_EQ(numeric_limits<float>::max(), pinch1.data.pinchUpdate.scale);
 }
 
 }  // namespace
diff --git a/content/common/input_messages.h b/content/common/input_messages.h
index 7f42435..df67c71 100644
--- a/content/common/input_messages.h
+++ b/content/common/input_messages.h
@@ -11,13 +11,13 @@
 #include "content/common/content_param_traits.h"
 #include "content/common/edit_command.h"
 #include "content/common/input/input_event.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/common/input/input_param_traits.h"
 #include "content/common/input/synthetic_gesture_packet.h"
 #include "content/common/input/synthetic_gesture_params.h"
 #include "content/common/input/synthetic_pinch_gesture_params.h"
 #include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
 #include "content/common/input/synthetic_tap_gesture_params.h"
-#include "content/port/common/input_event_ack_state.h"
 #include "content/public/common/common_param_traits.h"
 #include "content/common/input/touch_action.h"
 #include "ipc/ipc_message_macros.h"
diff --git a/content/common/media/midi_messages.h b/content/common/media/midi_messages.h
index c907a98..f46f201 100644
--- a/content/common/media/midi_messages.h
+++ b/content/common/media/midi_messages.h
@@ -8,7 +8,9 @@
 #include "base/basictypes.h"
 #include "content/common/content_export.h"
 #include "ipc/ipc_message_macros.h"
+#include "ipc/param_traits_macros.h"
 #include "media/midi/midi_port_info.h"
+#include "media/midi/midi_result.h"
 #include "url/gurl.h"
 
 #undef IPC_MESSAGE_EXPORT
@@ -22,6 +24,8 @@
   IPC_STRUCT_TRAITS_MEMBER(version)
 IPC_STRUCT_TRAITS_END()
 
+IPC_ENUM_TRAITS_MAX_VALUE(media::MidiResult, media::MIDI_RESULT_LAST)
+
 // Messages for IPC between MidiDispatcher and MidiDispatcherHost.
 
 // Renderer request to browser for using system exclusive messages.
@@ -58,7 +62,7 @@
 
 IPC_MESSAGE_CONTROL4(MidiMsg_SessionStarted,
                      int /* client id */,
-                     bool /* success */,
+                     media::MidiResult /* result */,
                      media::MidiPortInfoList /* input ports */,
                      media::MidiPortInfoList /* output ports */)
 
diff --git a/content/common/p2p_messages.h b/content/common/p2p_messages.h
index 9f64778..c227b0a 100644
--- a/content/common/p2p_messages.h
+++ b/content/common/p2p_messages.h
@@ -23,9 +23,14 @@
 IPC_ENUM_TRAITS_MIN_MAX_VALUE(talk_base::DiffServCodePoint,
                               talk_base::DSCP_NO_CHANGE,
                               talk_base::DSCP_CS7)
+IPC_ENUM_TRAITS_MIN_MAX_VALUE(net::NetworkChangeNotifier::ConnectionType,
+                              net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
+                              net::NetworkChangeNotifier::CONNECTION_NONE)
+
 
 IPC_STRUCT_TRAITS_BEGIN(net::NetworkInterface)
   IPC_STRUCT_TRAITS_MEMBER(name)
+  IPC_STRUCT_TRAITS_MEMBER(type)
   IPC_STRUCT_TRAITS_MEMBER(address)
 IPC_STRUCT_TRAITS_END()
 
diff --git a/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc b/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc
index 6335dfc..b7bd3fa 100644
--- a/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc
+++ b/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc
@@ -21,6 +21,8 @@
   bool override_and_allow = false;
 
   switch (sysno) {
+    // TODO(rsesek): restrict clone parameters.
+    case __NR_clone:
     case __NR_epoll_pwait:
     case __NR_flock:
     case __NR_getpriority:
diff --git a/content/common/sandbox_linux/bpf_gpu_policy_linux.cc b/content/common/sandbox_linux/bpf_gpu_policy_linux.cc
index 1570114..8ea2600 100644
--- a/content/common/sandbox_linux/bpf_gpu_policy_linux.cc
+++ b/content/common/sandbox_linux/bpf_gpu_policy_linux.cc
@@ -185,10 +185,6 @@
       DCHECK(broker_process_);
       return sandbox->Trap(GpuSIGSYS_Handler, broker_process_);
     default:
-      // Allow *kill from the GPU process temporarily until fork()
-      // is denied here.
-      if (SyscallSets::IsKill(sysno))
-        return ErrorCode(ErrorCode::ERR_ALLOWED);
       if (SyscallSets::IsEventFd(sysno))
         return ErrorCode(ErrorCode::ERR_ALLOWED);
 
diff --git a/content/common/sandbox_linux/bpf_ppapi_policy_linux.cc b/content/common/sandbox_linux/bpf_ppapi_policy_linux.cc
index 3a59bfc..4c80622 100644
--- a/content/common/sandbox_linux/bpf_ppapi_policy_linux.cc
+++ b/content/common/sandbox_linux/bpf_ppapi_policy_linux.cc
@@ -24,8 +24,6 @@
 ErrorCode PpapiProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
                                               int sysno) const {
   switch (sysno) {
-    case __NR_clone:
-      return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox);
     case __NR_pread64:
     case __NR_pwrite64:
     case __NR_sched_get_priority_max:
diff --git a/content/common/sandbox_linux/bpf_renderer_policy_linux.cc b/content/common/sandbox_linux/bpf_renderer_policy_linux.cc
index eba2eca..2679778 100644
--- a/content/common/sandbox_linux/bpf_renderer_policy_linux.cc
+++ b/content/common/sandbox_linux/bpf_renderer_policy_linux.cc
@@ -24,8 +24,6 @@
 ErrorCode RendererProcessPolicy::EvaluateSyscall(SandboxBPF* sandbox,
                                                  int sysno) const {
   switch (sysno) {
-    case __NR_clone:
-      return sandbox::RestrictCloneToThreadsAndEPERMFork(sandbox);
     case __NR_ioctl:
       return sandbox::RestrictIoctl(sandbox);
     case __NR_prctl:
diff --git a/content/common/sandbox_linux/sandbox_linux.cc b/content/common/sandbox_linux/sandbox_linux.cc
index f3a1b2f..237cc89 100644
--- a/content/common/sandbox_linux/sandbox_linux.cc
+++ b/content/common/sandbox_linux/sandbox_linux.cc
@@ -60,6 +60,7 @@
 #endif
 }
 
+#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER)
 bool AddResourceLimit(int resource, rlim_t limit) {
   struct rlimit old_rlimit;
   if (getrlimit(resource, &old_rlimit))
@@ -72,6 +73,7 @@
   int rc = setrlimit(resource, &new_rlimit);
   return rc == 0;
 }
+#endif
 
 bool IsRunningTSAN() {
 #if defined(THREAD_SANITIZER)
@@ -122,16 +124,18 @@
   return instance;
 }
 
-#if defined(ADDRESS_SANITIZER) && defined(OS_LINUX)
-// ASan API call to notify the tool the sandbox is going to be turned on.
+#if (defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
+     defined(LEAK_SANITIZER))  && defined(OS_LINUX)
+// Sanitizer API call to notify the tool the sandbox is going to be turned on.
 extern "C" void __sanitizer_sandbox_on_notify(void *reserved);
 #endif
 
 void LinuxSandbox::PreinitializeSandbox() {
   CHECK(!pre_initialized_);
   seccomp_bpf_supported_ = false;
-#if defined(ADDRESS_SANITIZER) && defined(OS_LINUX)
-  // ASan needs to open some resources before the sandbox is enabled.
+#if (defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
+     defined(LEAK_SANITIZER))  && defined(OS_LINUX)
+  // Sanitizers need to open some resources before the sandbox is enabled.
   // This should not fork, not launch threads, not open a directory.
   __sanitizer_sandbox_on_notify(/*reserved*/ NULL);
 #endif
@@ -328,7 +332,7 @@
 
 bool LinuxSandbox::LimitAddressSpace(const std::string& process_type) {
   (void) process_type;
-#if !defined(ADDRESS_SANITIZER)
+#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER)
   CommandLine* command_line = CommandLine::ForCurrentProcess();
   if (command_line->HasSwitch(switches::kNoSandbox)) {
     return false;
@@ -368,7 +372,7 @@
 #else
   base::SysInfo::AmountOfVirtualMemory();
   return false;
-#endif  // !defined(ADDRESS_SANITIZER)
+#endif  // !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER)
 }
 
 bool LinuxSandbox::HasOpenDirectories() const {
diff --git a/content/common/savable_url_schemes.cc b/content/common/savable_url_schemes.cc
index e49fceb..290d78f 100644
--- a/content/common/savable_url_schemes.cc
+++ b/content/common/savable_url_schemes.cc
@@ -13,8 +13,8 @@
 namespace {
 
 const char* const kDefaultSavableSchemes[] = {
-  kHttpScheme,
-  kHttpsScheme,
+  url::kHttpScheme,
+  url::kHttpsScheme,
   kFileScheme,
   kFileSystemScheme,
   kFtpScheme,
diff --git a/content/common/service_worker/embedded_worker_messages.h b/content/common/service_worker/embedded_worker_messages.h
index c130285..b31e63b 100644
--- a/content/common/service_worker/embedded_worker_messages.h
+++ b/content/common/service_worker/embedded_worker_messages.h
@@ -44,6 +44,16 @@
 IPC_MESSAGE_CONTROL1(EmbeddedWorkerMsg_StopWorker,
                      int /* embedded_worker_id */)
 
+// Renderer -> Browser message to indicate that the worker has loadedd the
+// script.
+IPC_MESSAGE_CONTROL1(EmbeddedWorkerHostMsg_WorkerScriptLoaded,
+                     int /* embedded_worker_id */)
+
+// Renderer -> Browser message to indicate that the worker has failed to load
+// the script.
+IPC_MESSAGE_CONTROL1(EmbeddedWorkerHostMsg_WorkerScriptLoadFailed,
+                     int /* embedded_worker_id */)
+
 // Renderer -> Browser message to indicate that the worker is started.
 IPC_MESSAGE_CONTROL2(EmbeddedWorkerHostMsg_WorkerStarted,
                      int /* thread_id */,
diff --git a/content/common/service_worker/service_worker_messages.h b/content/common/service_worker/service_worker_messages.h
index 8af1825..e3f2e38 100644
--- a/content/common/service_worker/service_worker_messages.h
+++ b/content/common/service_worker/service_worker_messages.h
@@ -67,8 +67,8 @@
                      GURL /* scope (url pattern) */)
 
 // Sends a 'message' event to a service worker (renderer->browser).
-IPC_MESSAGE_CONTROL3(ServiceWorkerHostMsg_PostMessage,
-                     int64 /* version_id */,
+IPC_MESSAGE_CONTROL3(ServiceWorkerHostMsg_PostMessageToWorker,
+                     int /* handle_id */,
                      base::string16 /* message */,
                      std::vector<int> /* sent_message_port_ids */)
 
@@ -81,8 +81,12 @@
 IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_ProviderDestroyed,
                      int /* provider_id */)
 
-// Informs the browser of a ServiceWorker object being destroyed.
-IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_ServiceWorkerObjectDestroyed,
+// Increments and decrements the ServiceWorker object's reference
+// counting in the browser side. The ServiceWorker object is created
+// with ref-count==1 initially.
+IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount,
+                     int /* handle_id */)
+IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount,
                      int /* handle_id */)
 
 // Informs the browser that |provider_id| is associated
@@ -92,16 +96,6 @@
                      int /* provider_id */,
                      int64 /* version_id */)
 
-// Informs the browser of a new scriptable API client in the child process.
-IPC_MESSAGE_CONTROL2(ServiceWorkerHostMsg_AddScriptClient,
-                     int /* thread_id */,
-                     int /* provider_id */)
-
-// Informs the browser that the scriptable API client is unregistered.
-IPC_MESSAGE_CONTROL2(ServiceWorkerHostMsg_RemoveScriptClient,
-                     int /* thread_id */,
-                     int /* provider_id */)
-
 // Informs the browser that event handling has finished.
 // Routed to the target ServiceWorkerVersion.
 IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_InstallEventFinished,
@@ -122,6 +116,12 @@
 IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_GetClientDocuments,
                     int /* request_id */)
 
+// Sends a 'message' event to a client document (renderer->browser).
+IPC_MESSAGE_ROUTED3(ServiceWorkerHostMsg_PostMessageToDocument,
+                    int /* client_id */,
+                    base::string16 /* message */,
+                    std::vector<int> /* sent_message_port_ids */)
+
 //---------------------------------------------------------------------------
 // Messages sent from the browser to the child process.
 //
@@ -162,6 +162,14 @@
                      int /* provider_id */,
                      content::ServiceWorkerObjectInfo)
 
+// Sends a 'message' event to a client document (browser->renderer).
+IPC_MESSAGE_CONTROL5(ServiceWorkerMsg_MessageToDocument,
+                     int /* thread_id */,
+                     int /* provider_id */,
+                     base::string16 /* message */,
+                     std::vector<int> /* sent_message_port_ids */,
+                     std::vector<int> /* new_routing_ids */)
+
 // Sent via EmbeddedWorker to dispatch events.
 IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_InstallEvent,
                      int /* request_id */,
@@ -173,7 +181,7 @@
                      content::ServiceWorkerFetchRequest)
 IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_SyncEvent,
                      int /* request_id */)
-IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_Message,
+IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_MessageToWorker,
                      base::string16 /* message */,
                      std::vector<int> /* sent_message_port_ids */,
                      std::vector<int> /* new_routing_ids */)
diff --git a/content/common/service_worker/service_worker_types.h b/content/common/service_worker/service_worker_types.h
index b69c6e4..319e272 100644
--- a/content/common/service_worker/service_worker_types.h
+++ b/content/common/service_worker/service_worker_types.h
@@ -28,6 +28,8 @@
 const static int kInvalidServiceWorkerProviderId = -1;
 const static int64 kInvalidServiceWorkerRegistrationId = -1;
 const static int64 kInvalidServiceWorkerVersionId = -1;
+const static int64 kInvalidServiceWorkerResourceId = -1;
+const static int64 kInvalidServiceWorkerResponseId = -1;
 
 // To dispatch fetch request from browser to child process.
 // TODO(kinuko): This struct will definitely need more fields and
diff --git a/content/common/speech_recognition_messages.h b/content/common/speech_recognition_messages.h
index 0af0d39..4840abd 100644
--- a/content/common/speech_recognition_messages.h
+++ b/content/common/speech_recognition_messages.h
@@ -40,67 +40,6 @@
   IPC_STRUCT_TRAITS_MEMBER(weight)
 IPC_STRUCT_TRAITS_END()
 
-// Used to start a speech recognition session.
-IPC_STRUCT_BEGIN(InputTagSpeechHostMsg_StartRecognition_Params)
-  // The render view requesting speech recognition.
-  IPC_STRUCT_MEMBER(int, render_view_id)
-  // Request ID used within the render view.
-  IPC_STRUCT_MEMBER(int, request_id)
-  // Position of the UI element in page coordinates.
-  IPC_STRUCT_MEMBER(gfx::Rect, element_rect)
-  // Language to use for speech recognition.
-  IPC_STRUCT_MEMBER(std::string, language)
-  // Speech grammar given by the speech recognition element.
-  IPC_STRUCT_MEMBER(std::string, grammar)
-  // URL of the page (or iframe if applicable).
-  IPC_STRUCT_MEMBER(std::string, origin_url)
-IPC_STRUCT_END()
-
-// Renderer -> Browser messages.
-
-// Requests the speech recognition service to start speech recognition on behalf
-// of the given |render_view_id|.
-IPC_MESSAGE_CONTROL1(InputTagSpeechHostMsg_StartRecognition,
-                     InputTagSpeechHostMsg_StartRecognition_Params)
-
-// Requests the speech recognition service to cancel speech recognition on
-// behalf of the given |render_view_id|. If speech recognition is not happening
-// or is happening on behalf of some other render view, this call does nothing.
-IPC_MESSAGE_CONTROL2(InputTagSpeechHostMsg_CancelRecognition,
-                     int /* render_view_id */,
-                     int /* request_id */)
-
-// Requests the speech recognition service to stop audio recording on behalf of
-// the given |render_view_id|. Any audio recorded so far will be fed to the
-// speech recognizer. If speech recognition is not happening nor or is
-// happening on behalf of some other render view, this call does nothing.
-IPC_MESSAGE_CONTROL2(InputTagSpeechHostMsg_StopRecording,
-                     int /* render_view_id */,
-                     int /* request_id */)
-
-// Browser -> Renderer messages.
-
-// Relays a speech recognition result, either partial or final.
-IPC_MESSAGE_ROUTED2(InputTagSpeechMsg_SetRecognitionResults,
-                    int /* request_id */,
-                    content::SpeechRecognitionResults /* results */)
-
-// Indicates that speech recognizer has stopped recording and started
-// recognition.
-IPC_MESSAGE_ROUTED1(InputTagSpeechMsg_RecordingComplete,
-                    int /* request_id */)
-
-// Indicates that speech recognizer has completed recognition. This will be the
-// last message sent in response to a InputTagSpeechHostMsg_StartRecognition.
-IPC_MESSAGE_ROUTED1(InputTagSpeechMsg_RecognitionComplete,
-                    int /* request_id */)
-
-// Toggles speech recognition on or off on the speech input control for the
-// current focused element. Has no effect if the current element doesn't
-// support speech recognition.
-IPC_MESSAGE_ROUTED0(InputTagSpeechMsg_ToggleSpeechInput)
-
-
 // ------- Messages for Speech JS APIs (SpeechRecognitionDispatcher) ----------
 
 // Renderer -> Browser messages.
diff --git a/content/common/swapped_out_messages.cc b/content/common/swapped_out_messages.cc
index e835966..be0fe8a 100644
--- a/content/common/swapped_out_messages.cc
+++ b/content/common/swapped_out_messages.cc
@@ -93,9 +93,7 @@
       break;
   }
 
-  // Check with the embedder as well.
-  ContentClient* client = GetContentClient();
-  return client->CanHandleWhileSwappedOut(msg);
+  return false;
 }
 
 }  // namespace content
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index c7e64ee..8a2d3dd 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -15,11 +15,11 @@
 #include "content/common/content_param_traits.h"
 #include "content/common/cookie_data.h"
 #include "content/common/input/did_overscroll_params.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/common/navigation_gesture.h"
 #include "content/common/pepper_renderer_instance_data.h"
 #include "content/common/view_message_enums.h"
 #include "content/common/webplugin_geometry.h"
-#include "content/port/common/input_event_ack_state.h"
 #include "content/public/common/common_param_traits.h"
 #include "content/public/common/favicon_url.h"
 #include "content/public/common/file_chooser_params.h"
@@ -528,10 +528,6 @@
 // Tells the render side that the mouse has been unlocked.
 IPC_MESSAGE_ROUTED0(ViewMsg_MouseLockLost)
 
-// Screen was rotated. Dispatched to the onorientationchange javascript API.
-IPC_MESSAGE_ROUTED1(ViewMsg_OrientationChangeEvent,
-                    int /* orientation */)
-
 // Sent by the browser when the parameters for vsync alignment have changed.
 IPC_MESSAGE_ROUTED2(ViewMsg_UpdateVSyncParameters,
                     base::TimeTicks /* timebase */,
@@ -650,6 +646,12 @@
                     int /* x */,
                     int /* y */)
 
+// Saves the image at location x, y to the disk (if there indeed is an
+// image at that location).
+IPC_MESSAGE_ROUTED2(ViewMsg_SaveImageAt,
+                    int /* x */,
+                    int /* y */)
+
 // Tells the renderer to perform the given action on the media player
 // located at the given point.
 IPC_MESSAGE_ROUTED2(ViewMsg_MediaPlayerActionAt,
@@ -1118,14 +1120,6 @@
 // message.
 IPC_MESSAGE_ROUTED0(ViewHostMsg_ClosePage_ACK)
 
-// Notifies the browser that media has started/stopped playing.
-IPC_MESSAGE_ROUTED3(ViewHostMsg_MediaPlayingNotification,
-                    int64 /* player_cookie, distinguishes instances */,
-                    bool /* has_video */,
-                    bool /* has_audio */)
-IPC_MESSAGE_ROUTED1(ViewHostMsg_MediaPausedNotification,
-                    int64 /* player_cookie, distinguishes instances */)
-
 // Notifies the browser that we have session history information.
 // page_id: unique ID that allows us to distinguish between history entries.
 IPC_MESSAGE_ROUTED2(ViewHostMsg_UpdateState,
@@ -1154,20 +1148,11 @@
 IPC_MESSAGE_ROUTED1(ViewHostMsg_DidChangeLoadProgress,
                     double /* load_progress */)
 
-// Sent when the renderer main frame sets its opener to null, disowning it for
-// the lifetime of the window.
-IPC_MESSAGE_ROUTED0(ViewHostMsg_DidDisownOpener)
-
 // Sent when the document element is available for the top-level frame.  This
 // happens after the page starts loading, but before all resources are
 // finished.
 IPC_MESSAGE_ROUTED0(ViewHostMsg_DocumentAvailableInMainFrame)
 
-// Sent when after the onload handler has been invoked for the document
-// in the top-level frame.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_DocumentOnLoadCompletedInMainFrame,
-                    int32 /* page_id */)
-
 // Sent when the renderer loads a resource from its memory cache.
 // The security info is non empty if the resource was originally loaded over
 // a secure connection.
@@ -1304,10 +1289,11 @@
                     bool /* blocked by policy */)
 
 // Initiates a download based on user actions like 'ALT+click'.
-IPC_MESSAGE_ROUTED3(ViewHostMsg_DownloadUrl,
+IPC_MESSAGE_ROUTED4(ViewHostMsg_DownloadUrl,
                     GURL     /* url */,
                     content::Referrer /* referrer */,
-                    base::string16 /* suggested_name */)
+                    base::string16 /* suggested_name */,
+                    bool /* use prompt for save location */)
 
 // Used to go to the session history entry at the given offset (ie, -1 will
 // return the "back" item).
@@ -1652,14 +1638,12 @@
 IPC_MESSAGE_ROUTED0(ViewHostMsg_WillInsertBody)
 
 // Notification that the urls for the favicon of a site has been determined.
-IPC_MESSAGE_ROUTED2(ViewHostMsg_UpdateFaviconURL,
-                    int32 /* page_id */,
+IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateFaviconURL,
                     std::vector<content::FaviconURL> /* candidates */)
 
 // Sent once a paint happens after the first non empty layout. In other words
 // after the page has painted something.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_DidFirstVisuallyNonEmptyPaint,
-                    int /* page_id */)
+IPC_MESSAGE_ROUTED0(ViewHostMsg_DidFirstVisuallyNonEmptyPaint)
 
 // Sent by the renderer to the browser to start a vibration with the given
 // duration.
diff --git a/content/common/zygote_commands_linux.h b/content/common/zygote_commands_linux.h
index 4c932ff..ca5a1d5 100644
--- a/content/common/zygote_commands_linux.h
+++ b/content/common/zygote_commands_linux.h
@@ -18,20 +18,16 @@
 // is ready to go.
 static const char kZygoteHelloMessage[] = "ZYGOTE_OK";
 
+// Message sent by zygote children to the browser so the browser can discover
+// the sending child's process ID.
+static const char kZygoteChildPingMessage[] = "CHILD_PING";
+
 // Maximum allowable length for messages sent to the zygote.
 const size_t kZygoteMaxMessageLength = 8192;
 
 // File descriptors initialized by the Zygote Host
 const int kZygoteSocketPairFd =
     kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor;
-// This file descriptor is special. It is passed to the Zygote and a setuid
-// helper will be called to locate the process of the Zygote on the system.
-// This mechanism is used when multiple PID namespaces exist because of the
-// setuid sandbox.
-// It is very important that this file descriptor does not exist in multiple
-// processes.
-// This number must be kept in sync in sandbox/linux/suid/sandbox.c
-const int kZygoteIdFd = 7;
 
 // These are the command codes used on the wire between the browser and the
 // zygote.
@@ -46,7 +42,11 @@
   kZygoteCommandGetTerminationStatus = 2,
 
   // Read a bitmask of kSandboxLinux*
-  kZygoteCommandGetSandboxStatus = 3
+  kZygoteCommandGetSandboxStatus = 3,
+
+  // Not a real zygote command, but a subcommand used during the zygote fork
+  // protocol.  Sends the child's PID as seen from the browser process.
+  kZygoteCommandForkRealPID = 4
 };
 
 }  // namespace content
diff --git a/content/common_aidl.target.darwin-arm.mk b/content/common_aidl.target.darwin-arm.mk
index ec700aa..ca3b197 100644
--- a/content/common_aidl.target.darwin-arm.mk
+++ b/content/common_aidl.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
 # "{'inputs': ['$(PWD)/prebuilts/sdk/18/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(PWD)/prebuilts/sdk/tools/darwin/aidl', '-p$(PWD)/prebuilts/sdk/18/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -62,7 +64,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -147,7 +148,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/common_aidl.target.darwin-arm64.mk b/content/common_aidl.target.darwin-arm64.mk
index bde744d..583fb72 100644
--- a/content/common_aidl.target.darwin-arm64.mk
+++ b/content/common_aidl.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
 # "{'inputs': ['$(PWD)/prebuilts/sdk/18/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(PWD)/prebuilts/sdk/tools/darwin/aidl', '-p$(PWD)/prebuilts/sdk/18/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/common_aidl.target.darwin-mips.mk b/content/common_aidl.target.darwin-mips.mk
index a820777..ec3e714 100644
--- a/content/common_aidl.target.darwin-mips.mk
+++ b/content/common_aidl.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
 # "{'inputs': ['$(PWD)/prebuilts/sdk/18/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(PWD)/prebuilts/sdk/tools/darwin/aidl', '-p$(PWD)/prebuilts/sdk/18/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/common_aidl.target.darwin-x86.mk b/content/common_aidl.target.darwin-x86.mk
index f615738..82f4ade 100644
--- a/content/common_aidl.target.darwin-x86.mk
+++ b/content/common_aidl.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
 # "{'inputs': ['$(PWD)/prebuilts/sdk/18/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(PWD)/prebuilts/sdk/tools/darwin/aidl', '-p$(PWD)/prebuilts/sdk/18/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +66,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -149,7 +150,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/common_aidl.target.darwin-x86_64.mk b/content/common_aidl.target.darwin-x86_64.mk
index 98add68..9df41b3 100644
--- a/content/common_aidl.target.darwin-x86_64.mk
+++ b/content/common_aidl.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
 # "{'inputs': ['$(PWD)/prebuilts/sdk/18/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(PWD)/prebuilts/sdk/tools/darwin/aidl', '-p$(PWD)/prebuilts/sdk/18/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +66,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -149,7 +150,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/common_aidl.target.linux-arm.mk b/content/common_aidl.target.linux-arm.mk
index bc49c73..dcf9384 100644
--- a/content/common_aidl.target.linux-arm.mk
+++ b/content/common_aidl.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
 # "{'inputs': ['$(PWD)/prebuilts/sdk/18/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(PWD)/prebuilts/sdk/tools/linux/aidl', '-p$(PWD)/prebuilts/sdk/18/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -62,7 +64,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -147,7 +148,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/common_aidl.target.linux-arm64.mk b/content/common_aidl.target.linux-arm64.mk
index 693ce72..d3e5a26 100644
--- a/content/common_aidl.target.linux-arm64.mk
+++ b/content/common_aidl.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
 # "{'inputs': ['$(PWD)/prebuilts/sdk/18/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(PWD)/prebuilts/sdk/tools/linux/aidl', '-p$(PWD)/prebuilts/sdk/18/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/common_aidl.target.linux-mips.mk b/content/common_aidl.target.linux-mips.mk
index ae017dd..94142f3 100644
--- a/content/common_aidl.target.linux-mips.mk
+++ b/content/common_aidl.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
 # "{'inputs': ['$(PWD)/prebuilts/sdk/18/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(PWD)/prebuilts/sdk/tools/linux/aidl', '-p$(PWD)/prebuilts/sdk/18/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/common_aidl.target.linux-x86.mk b/content/common_aidl.target.linux-x86.mk
index fd0a3da..2b27b09 100644
--- a/content/common_aidl.target.linux-x86.mk
+++ b/content/common_aidl.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
 # "{'inputs': ['$(PWD)/prebuilts/sdk/18/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(PWD)/prebuilts/sdk/tools/linux/aidl', '-p$(PWD)/prebuilts/sdk/18/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +66,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -149,7 +150,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/common_aidl.target.linux-x86_64.mk b/content/common_aidl.target.linux-x86_64.mk
index bbfbce2..00d980e 100644
--- a/content/common_aidl.target.linux-x86_64.mk
+++ b/content/common_aidl.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_common_aidl_target_compile_aidl":
 # "{'inputs': ['$(PWD)/prebuilts/sdk/18/framework.aidl', 'public/android/java/src/org/chromium/content/common/common.aidl'], 'extension': 'aidl', 'rule_sources': ['public/android/java/src/org/chromium/content/common/IChildProcessCallback.aidl', 'public/android/java/src/org/chromium/content/common/IChildProcessService.aidl'], 'rule_name': 'compile_aidl', 'outputs': ['$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java'], 'action': ['$(PWD)/prebuilts/sdk/tools/linux/aidl', '-p$(PWD)/prebuilts/sdk/18/framework.aidl', '-ppublic/android/java/src/org/chromium/content/common/common.aidl', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/common_aidl/aidl/%(INPUT_ROOT)s.java']}":
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessCallback.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/common_aidl/aidl/IChildProcessService.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +66,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -149,7 +150,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_app.gypi b/content/content_app.gypi
index 4d10317..0a873a4 100644
--- a/content/content_app.gypi
+++ b/content/content_app.gypi
@@ -35,8 +35,7 @@
     'public/app/startup_helper_win.h',
   ],
   'conditions': [
-    # TODO(dmikurube): Kill {linux|android}_use_tcmalloc. http://crbug.com/345554
-    ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and ((OS=="linux" and os_posix==1 and use_aura==1 and linux_use_tcmalloc==1) or (OS=="android" and android_use_tcmalloc==1)))', {
+    ['((OS=="linux" and os_posix==1 and use_aura==1) or OS=="android") and use_allocator!="none"', {
       'dependencies': [
         # This is needed by app/content_main_runner.cc
         '../base/allocator/allocator.gyp:allocator',
diff --git a/content/content_app_both.target.darwin-arm.mk b/content/content_app_both.target.darwin-arm.mk
index 8db3e9b..98be9b7 100644
--- a/content/content_app_both.target.darwin-arm.mk
+++ b/content/content_app_both.target.darwin-arm.mk
@@ -52,7 +52,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -104,11 +103,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -184,7 +178,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -236,11 +229,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_app_both.target.darwin-arm64.mk b/content/content_app_both.target.darwin-arm64.mk
index 8861d64..9ea3856 100644
--- a/content/content_app_both.target.darwin-arm64.mk
+++ b/content/content_app_both.target.darwin-arm64.mk
@@ -100,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -227,11 +222,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_app_both.target.darwin-mips.mk b/content/content_app_both.target.darwin-mips.mk
index ab62522..76e991e 100644
--- a/content/content_app_both.target.darwin-mips.mk
+++ b/content/content_app_both.target.darwin-mips.mk
@@ -103,11 +103,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -234,11 +229,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_app_both.target.darwin-x86.mk b/content/content_app_both.target.darwin-x86.mk
index c966625..bc4148c 100644
--- a/content/content_app_both.target.darwin-x86.mk
+++ b/content/content_app_both.target.darwin-x86.mk
@@ -54,7 +54,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -104,11 +103,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -185,7 +179,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -235,11 +228,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_app_both.target.darwin-x86_64.mk b/content/content_app_both.target.darwin-x86_64.mk
index 6bda3ae..1f07488 100644
--- a/content/content_app_both.target.darwin-x86_64.mk
+++ b/content/content_app_both.target.darwin-x86_64.mk
@@ -54,7 +54,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -105,11 +104,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -186,7 +180,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -237,11 +230,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_app_both.target.linux-arm.mk b/content/content_app_both.target.linux-arm.mk
index 8db3e9b..98be9b7 100644
--- a/content/content_app_both.target.linux-arm.mk
+++ b/content/content_app_both.target.linux-arm.mk
@@ -52,7 +52,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -104,11 +103,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -184,7 +178,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -236,11 +229,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_app_both.target.linux-arm64.mk b/content/content_app_both.target.linux-arm64.mk
index 8861d64..9ea3856 100644
--- a/content/content_app_both.target.linux-arm64.mk
+++ b/content/content_app_both.target.linux-arm64.mk
@@ -100,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -227,11 +222,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_app_both.target.linux-mips.mk b/content/content_app_both.target.linux-mips.mk
index ab62522..76e991e 100644
--- a/content/content_app_both.target.linux-mips.mk
+++ b/content/content_app_both.target.linux-mips.mk
@@ -103,11 +103,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -234,11 +229,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_app_both.target.linux-x86.mk b/content/content_app_both.target.linux-x86.mk
index c966625..bc4148c 100644
--- a/content/content_app_both.target.linux-x86.mk
+++ b/content/content_app_both.target.linux-x86.mk
@@ -54,7 +54,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -104,11 +103,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -185,7 +179,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -235,11 +228,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_app_both.target.linux-x86_64.mk b/content/content_app_both.target.linux-x86_64.mk
index 6bda3ae..1f07488 100644
--- a/content/content_app_both.target.linux-x86_64.mk
+++ b/content/content_app_both.target.linux-x86_64.mk
@@ -54,7 +54,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -105,11 +104,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -186,7 +180,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -237,11 +230,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index cbe667f..25ac91b 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -38,12 +38,6 @@
     '<(INTERMEDIATE_DIR)',
   ],
   'sources': [
-    'port/browser/event_with_latency_info.h',
-    'port/browser/location_provider.h',
-    'port/browser/render_view_host_delegate_view.h',
-    'port/browser/render_widget_host_view_port.h',
-    'port/browser/vibration_provider.h',
-    'port/browser/web_contents_view_port.h',
     'public/browser/access_token_store.h',
     'public/browser/android/compositor.h',
     'public/browser/android/compositor_client.h',
@@ -75,6 +69,8 @@
     'public/browser/browser_message_filter.h',
     'public/browser/browser_plugin_guest_delegate.cc',
     'public/browser/browser_plugin_guest_delegate.h',
+    'public/browser/browser_plugin_guest_manager_delegate.cc',
+    'public/browser/browser_plugin_guest_manager_delegate.h',
     'public/browser/browser_ppapi_host.h',
     'public/browser/browser_shutdown.h',
     'public/browser/browser_url_handler.h',
@@ -137,6 +133,7 @@
     'public/browser/load_notification_details.h',
     'public/browser/local_storage_usage_info.cc',
     'public/browser/local_storage_usage_info.h',
+    'public/browser/location_provider.h',
     'public/browser/media_capture_devices.h',
     'public/browser/media_device_id.cc',
     'public/browser/media_device_id.h',
@@ -172,6 +169,7 @@
     'public/browser/render_view_host.h',
     'public/browser/render_widget_host.h',
     'public/browser/render_widget_host_view.h',
+    'public/browser/render_widget_host_view_frame_subscriber.h',
     'public/browser/render_widget_host_view_mac_delegate.h',
     'public/browser/resource_context.h',
     'public/browser/resource_controller.h',
@@ -201,6 +199,7 @@
     'public/browser/tracing_controller.h',
     'public/browser/user_metrics.h',
     'public/browser/utility_process_host.h',
+    'public/browser/vibration_provider.h',
     'public/browser/web_contents.cc',
     'public/browser/web_contents.h',
     'public/browser/web_contents_delegate.cc',
@@ -208,7 +207,6 @@
     'public/browser/web_contents_observer.cc',
     'public/browser/web_contents_observer.h',
     'public/browser/web_contents_user_data.h',
-    'public/browser/web_contents_view.h',
     'public/browser/web_contents_view_delegate.h',
     'public/browser/web_drag_dest_delegate.h',
     'public/browser/web_ui.h',
@@ -290,8 +288,6 @@
     'browser/android/in_process/synchronous_input_event_filter.h',
     'browser/android/interstitial_page_delegate_android.cc',
     'browser/android/interstitial_page_delegate_android.h',
-    'browser/android/layer_tree_build_helper_impl.cc',
-    'browser/android/layer_tree_build_helper_impl.h',
     'browser/android/load_url_params.cc',
     'browser/android/load_url_params.h',
     'browser/android/overscroll_glow.h',
@@ -357,6 +353,8 @@
     'browser/compositor/browser_compositor_output_surface.h',
     'browser/compositor/browser_compositor_output_surface_proxy.cc',
     'browser/compositor/browser_compositor_output_surface_proxy.h',
+    'browser/compositor/delegated_frame_host.cc',
+    'browser/compositor/delegated_frame_host.h',
     'browser/compositor/gpu_process_transport_factory.cc',
     'browser/compositor/gpu_process_transport_factory.h',
     'browser/compositor/image_transport_factory.cc',
@@ -407,12 +405,12 @@
     'browser/devtools/devtools_tracing_handler.cc',
     'browser/devtools/ipc_devtools_agent_host.cc',
     'browser/devtools/ipc_devtools_agent_host.h',
+    'browser/devtools/embedded_worker_devtools_manager.cc',
+    'browser/devtools/embedded_worker_devtools_manager.h',
     'browser/devtools/render_view_devtools_agent_host.cc',
     'browser/devtools/render_view_devtools_agent_host.h',
     'browser/devtools/renderer_overrides_handler.cc',
     'browser/devtools/renderer_overrides_handler.h',
-    'browser/devtools/shared_worker_devtools_manager.cc',
-    'browser/devtools/shared_worker_devtools_manager.h',
     'browser/devtools/tethering_handler.h',
     'browser/devtools/tethering_handler.cc',
     'browser/devtools/worker_devtools_manager.cc',
@@ -576,6 +574,7 @@
     'browser/frame_host/render_widget_host_view_child_frame.h',
     'browser/frame_host/render_widget_host_view_guest.cc',
     'browser/frame_host/render_widget_host_view_guest.h',
+    'browser/gamepad/gamepad_consumer.h',
     'browser/gamepad/gamepad_data_fetcher.h',
     'browser/gamepad/gamepad_platform_data_fetcher.h',
     'browser/gamepad/gamepad_platform_data_fetcher_linux.cc',
@@ -887,6 +886,7 @@
     'browser/renderer_host/dip_util.h',
     'browser/renderer_host/display_link_mac.h',
     'browser/renderer_host/display_link_mac.cc',
+    'browser/renderer_host/event_with_latency_info.h',
     'browser/renderer_host/file_utilities_message_filter.cc',
     'browser/renderer_host/file_utilities_message_filter.h',
     'browser/renderer_host/gamepad_browser_message_filter.cc',
@@ -904,6 +904,8 @@
     'browser/renderer_host/input/input_router_client.h',
     'browser/renderer_host/input/input_router_impl.cc',
     'browser/renderer_host/input/input_router_impl.h',
+    'browser/renderer_host/input/input_router_config_helper.cc',
+    'browser/renderer_host/input/input_router_config_helper.h',
     'browser/renderer_host/input/motion_event_android.cc',
     'browser/renderer_host/input/motion_event_android.h',
     'browser/renderer_host/input/motion_event_web.cc',
@@ -937,12 +939,10 @@
     'browser/renderer_host/input/touch_event_queue.h',
     'browser/renderer_host/input/touch_action_filter.cc',
     'browser/renderer_host/input/touch_action_filter.h',
-    'browser/renderer_host/input/touchpad_tap_suppression_controller_aura.cc',
     'browser/renderer_host/input/touchpad_tap_suppression_controller.cc',
     'browser/renderer_host/input/touchpad_tap_suppression_controller.h',
     'browser/renderer_host/input/touchscreen_tap_suppression_controller.cc',
     'browser/renderer_host/input/touchscreen_tap_suppression_controller.h',
-    'browser/renderer_host/input/touchscreen_tap_suppression_controller_stub.cc',
     'browser/renderer_host/input/web_input_event_builders_android.cc',
     'browser/renderer_host/input/web_input_event_builders_android.h',
     'browser/renderer_host/input/web_input_event_builders_win.cc',
@@ -1083,6 +1083,7 @@
     'browser/renderer_host/render_process_host_impl.h',
     'browser/renderer_host/render_view_host_delegate.cc',
     'browser/renderer_host/render_view_host_delegate.h',
+    'browser/renderer_host/render_view_host_delegate_view.h',
     'browser/renderer_host/render_view_host_factory.cc',
     'browser/renderer_host/render_view_host_factory.h',
     'browser/renderer_host/render_view_host_impl.cc',
@@ -1157,6 +1158,8 @@
     'browser/service_worker/service_worker_controllee_request_handler.h',
     'browser/service_worker/service_worker_database.cc',
     'browser/service_worker/service_worker_database.h',
+    'browser/service_worker/service_worker_disk_cache.cc',
+    'browser/service_worker/service_worker_disk_cache.h',
     'browser/service_worker/service_worker_dispatcher_host.cc',
     'browser/service_worker/service_worker_dispatcher_host.h',
     'browser/service_worker/service_worker_fetch_dispatcher.cc',
@@ -1173,6 +1176,8 @@
     'browser/service_worker/service_worker_process_manager.h',
     'browser/service_worker/service_worker_provider_host.cc',
     'browser/service_worker/service_worker_provider_host.h',
+    'browser/service_worker/service_worker_read_from_cache_job.cc',
+    'browser/service_worker/service_worker_read_from_cache_job.h',
     'browser/service_worker/service_worker_register_job_base.h',
     'browser/service_worker/service_worker_register_job.cc',
     'browser/service_worker/service_worker_register_job.h',
@@ -1220,8 +1225,6 @@
     'browser/speech/google_one_shot_remote_engine.h',
     'browser/speech/google_streaming_remote_engine.cc',
     'browser/speech/google_streaming_remote_engine.h',
-    'browser/speech/input_tag_speech_dispatcher_host.cc',
-    'browser/speech/input_tag_speech_dispatcher_host.h',
     'browser/speech/speech_recognition_dispatcher_host.cc',
     'browser/speech/speech_recognition_dispatcher_host.h',
     'browser/speech/speech_recognition_engine.cc',
@@ -1314,6 +1317,7 @@
     'browser/web_contents/web_contents_android.h',
     'browser/web_contents/web_contents_impl.cc',
     'browser/web_contents/web_contents_impl.h',
+    'browser/web_contents/web_contents_view.h',
     'browser/web_contents/web_contents_view_android.cc',
     'browser/web_contents/web_contents_view_android.h',
     'browser/web_contents/web_contents_view_aura.cc',
@@ -1648,27 +1652,13 @@
         ['exclude', '^browser/gamepad/gamepad_platform_data_fetcher_linux\\.cc$'],
       ],
     }],
-    ['use_aura!=1 and OS!="android"', {
-      'sources!': [
-        'browser/renderer_host/input/touchscreen_tap_suppression_controller.cc',
-        'browser/renderer_host/tap_suppression_controller.cc',
-      ],
-    }, {
-      'sources!': [
-        'browser/renderer_host/input/touchscreen_tap_suppression_controller_stub.cc',
-      ],
-    }],
     ['use_aura==1', {
       'dependencies': [
         '../ui/aura/aura.gyp:aura',
         '../ui/base/strings/ui_strings.gyp:ui_strings',
       ],
-      'sources/': [
-        ['exclude', '^browser/renderer_host/input/touchpad_tap_suppression_controller.cc'],
-      ],
     }, {
       'sources/': [
-        ['exclude', '^browser/renderer_host/input/touchpad_tap_suppression_controller_aura.cc'],
         ['exclude', '^browser/renderer_host/render_widget_host_view_aura.cc'],
         ['exclude', '^browser/renderer_host/render_widget_host_view_aura.h'],
         ['exclude', '^browser/web_contents/touch_editable_impl_aura.cc'],
@@ -1710,11 +1700,7 @@
         ['exclude', '^browser/renderer_host/pepper/'],
       ],
     }],
-    ['input_speech==0', {
-      'sources/': [
-        ['exclude', '^browser/speech/input_tag_speech_dispatcher_host\\.(cc|h)$'],
-      ],
-    }, {  # input_speech==1
+    ['input_speech==1', {
       'dependencies': [
         '../third_party/flac/flac.gyp:libflac',
         '../third_party/speex/speex.gyp:libspeex',
diff --git a/content/content_browser.target.darwin-arm.mk b/content/content_browser.target.darwin-arm.mk
index 72c8b0d..f1155a9 100644
--- a/content/content_browser.target.darwin-arm.mk
+++ b/content/content_browser.target.darwin-arm.mk
@@ -63,6 +63,7 @@
 	content/public/browser/browser_main_parts.cc \
 	content/public/browser/browser_message_filter.cc \
 	content/public/browser/browser_plugin_guest_delegate.cc \
+	content/public/browser/browser_plugin_guest_manager_delegate.cc \
 	content/public/browser/content_browser_client.cc \
 	content/public/browser/desktop_media_id.cc \
 	content/public/browser/download_manager_delegate.cc \
@@ -114,7 +115,6 @@
 	content/browser/android/in_process/synchronous_compositor_output_surface.cc \
 	content/browser/android/in_process/synchronous_input_event_filter.cc \
 	content/browser/android/interstitial_page_delegate_android.cc \
-	content/browser/android/layer_tree_build_helper_impl.cc \
 	content/browser/android/load_url_params.cc \
 	content/browser/android/overscroll_glow.cc \
 	content/browser/android/surface_texture_peer_browser_impl.cc \
@@ -157,9 +157,9 @@
 	content/browser/devtools/devtools_system_info_handler.cc \
 	content/browser/devtools/devtools_tracing_handler.cc \
 	content/browser/devtools/ipc_devtools_agent_host.cc \
+	content/browser/devtools/embedded_worker_devtools_manager.cc \
 	content/browser/devtools/render_view_devtools_agent_host.cc \
 	content/browser/devtools/renderer_overrides_handler.cc \
-	content/browser/devtools/shared_worker_devtools_manager.cc \
 	content/browser/devtools/tethering_handler.cc \
 	content/browser/devtools/worker_devtools_manager.cc \
 	content/browser/devtools/worker_devtools_message_filter.cc \
@@ -354,6 +354,7 @@
 	content/browser/renderer_host/ime_adapter_android.cc \
 	content/browser/renderer_host/input/gesture_event_queue.cc \
 	content/browser/renderer_host/input/input_router_impl.cc \
+	content/browser/renderer_host/input/input_router_config_helper.cc \
 	content/browser/renderer_host/input/motion_event_android.cc \
 	content/browser/renderer_host/input/motion_event_web.cc \
 	content/browser/renderer_host/input/synthetic_gesture.cc \
@@ -429,6 +430,7 @@
 	content/browser/service_worker/service_worker_context_wrapper.cc \
 	content/browser/service_worker/service_worker_controllee_request_handler.cc \
 	content/browser/service_worker/service_worker_database.cc \
+	content/browser/service_worker/service_worker_disk_cache.cc \
 	content/browser/service_worker/service_worker_dispatcher_host.cc \
 	content/browser/service_worker/service_worker_fetch_dispatcher.cc \
 	content/browser/service_worker/service_worker_handle.cc \
@@ -437,6 +439,7 @@
 	content/browser/service_worker/service_worker_job_coordinator.cc \
 	content/browser/service_worker/service_worker_process_manager.cc \
 	content/browser/service_worker/service_worker_provider_host.cc \
+	content/browser/service_worker/service_worker_read_from_cache_job.cc \
 	content/browser/service_worker/service_worker_register_job.cc \
 	content/browser/service_worker/service_worker_registration.cc \
 	content/browser/service_worker/service_worker_registration_status.cc \
@@ -525,7 +528,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -576,11 +578,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -702,7 +699,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -753,11 +749,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_browser.target.darwin-arm64.mk b/content/content_browser.target.darwin-arm64.mk
index 702e359..9f915cb 100644
--- a/content/content_browser.target.darwin-arm64.mk
+++ b/content/content_browser.target.darwin-arm64.mk
@@ -63,6 +63,7 @@
 	content/public/browser/browser_main_parts.cc \
 	content/public/browser/browser_message_filter.cc \
 	content/public/browser/browser_plugin_guest_delegate.cc \
+	content/public/browser/browser_plugin_guest_manager_delegate.cc \
 	content/public/browser/content_browser_client.cc \
 	content/public/browser/desktop_media_id.cc \
 	content/public/browser/download_manager_delegate.cc \
@@ -114,7 +115,6 @@
 	content/browser/android/in_process/synchronous_compositor_output_surface.cc \
 	content/browser/android/in_process/synchronous_input_event_filter.cc \
 	content/browser/android/interstitial_page_delegate_android.cc \
-	content/browser/android/layer_tree_build_helper_impl.cc \
 	content/browser/android/load_url_params.cc \
 	content/browser/android/overscroll_glow.cc \
 	content/browser/android/surface_texture_peer_browser_impl.cc \
@@ -157,9 +157,9 @@
 	content/browser/devtools/devtools_system_info_handler.cc \
 	content/browser/devtools/devtools_tracing_handler.cc \
 	content/browser/devtools/ipc_devtools_agent_host.cc \
+	content/browser/devtools/embedded_worker_devtools_manager.cc \
 	content/browser/devtools/render_view_devtools_agent_host.cc \
 	content/browser/devtools/renderer_overrides_handler.cc \
-	content/browser/devtools/shared_worker_devtools_manager.cc \
 	content/browser/devtools/tethering_handler.cc \
 	content/browser/devtools/worker_devtools_manager.cc \
 	content/browser/devtools/worker_devtools_message_filter.cc \
@@ -354,6 +354,7 @@
 	content/browser/renderer_host/ime_adapter_android.cc \
 	content/browser/renderer_host/input/gesture_event_queue.cc \
 	content/browser/renderer_host/input/input_router_impl.cc \
+	content/browser/renderer_host/input/input_router_config_helper.cc \
 	content/browser/renderer_host/input/motion_event_android.cc \
 	content/browser/renderer_host/input/motion_event_web.cc \
 	content/browser/renderer_host/input/synthetic_gesture.cc \
@@ -429,6 +430,7 @@
 	content/browser/service_worker/service_worker_context_wrapper.cc \
 	content/browser/service_worker/service_worker_controllee_request_handler.cc \
 	content/browser/service_worker/service_worker_database.cc \
+	content/browser/service_worker/service_worker_disk_cache.cc \
 	content/browser/service_worker/service_worker_dispatcher_host.cc \
 	content/browser/service_worker/service_worker_fetch_dispatcher.cc \
 	content/browser/service_worker/service_worker_handle.cc \
@@ -437,6 +439,7 @@
 	content/browser/service_worker/service_worker_job_coordinator.cc \
 	content/browser/service_worker/service_worker_process_manager.cc \
 	content/browser/service_worker/service_worker_provider_host.cc \
+	content/browser/service_worker/service_worker_read_from_cache_job.cc \
 	content/browser/service_worker/service_worker_register_job.cc \
 	content/browser/service_worker/service_worker_registration.cc \
 	content/browser/service_worker/service_worker_registration_status.cc \
@@ -572,11 +575,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -744,11 +742,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_browser.target.darwin-mips.mk b/content/content_browser.target.darwin-mips.mk
index 126847d..8a2c57a 100644
--- a/content/content_browser.target.darwin-mips.mk
+++ b/content/content_browser.target.darwin-mips.mk
@@ -63,6 +63,7 @@
 	content/public/browser/browser_main_parts.cc \
 	content/public/browser/browser_message_filter.cc \
 	content/public/browser/browser_plugin_guest_delegate.cc \
+	content/public/browser/browser_plugin_guest_manager_delegate.cc \
 	content/public/browser/content_browser_client.cc \
 	content/public/browser/desktop_media_id.cc \
 	content/public/browser/download_manager_delegate.cc \
@@ -114,7 +115,6 @@
 	content/browser/android/in_process/synchronous_compositor_output_surface.cc \
 	content/browser/android/in_process/synchronous_input_event_filter.cc \
 	content/browser/android/interstitial_page_delegate_android.cc \
-	content/browser/android/layer_tree_build_helper_impl.cc \
 	content/browser/android/load_url_params.cc \
 	content/browser/android/overscroll_glow.cc \
 	content/browser/android/surface_texture_peer_browser_impl.cc \
@@ -157,9 +157,9 @@
 	content/browser/devtools/devtools_system_info_handler.cc \
 	content/browser/devtools/devtools_tracing_handler.cc \
 	content/browser/devtools/ipc_devtools_agent_host.cc \
+	content/browser/devtools/embedded_worker_devtools_manager.cc \
 	content/browser/devtools/render_view_devtools_agent_host.cc \
 	content/browser/devtools/renderer_overrides_handler.cc \
-	content/browser/devtools/shared_worker_devtools_manager.cc \
 	content/browser/devtools/tethering_handler.cc \
 	content/browser/devtools/worker_devtools_manager.cc \
 	content/browser/devtools/worker_devtools_message_filter.cc \
@@ -354,6 +354,7 @@
 	content/browser/renderer_host/ime_adapter_android.cc \
 	content/browser/renderer_host/input/gesture_event_queue.cc \
 	content/browser/renderer_host/input/input_router_impl.cc \
+	content/browser/renderer_host/input/input_router_config_helper.cc \
 	content/browser/renderer_host/input/motion_event_android.cc \
 	content/browser/renderer_host/input/motion_event_web.cc \
 	content/browser/renderer_host/input/synthetic_gesture.cc \
@@ -429,6 +430,7 @@
 	content/browser/service_worker/service_worker_context_wrapper.cc \
 	content/browser/service_worker/service_worker_controllee_request_handler.cc \
 	content/browser/service_worker/service_worker_database.cc \
+	content/browser/service_worker/service_worker_disk_cache.cc \
 	content/browser/service_worker/service_worker_dispatcher_host.cc \
 	content/browser/service_worker/service_worker_fetch_dispatcher.cc \
 	content/browser/service_worker/service_worker_handle.cc \
@@ -437,6 +439,7 @@
 	content/browser/service_worker/service_worker_job_coordinator.cc \
 	content/browser/service_worker/service_worker_process_manager.cc \
 	content/browser/service_worker/service_worker_provider_host.cc \
+	content/browser/service_worker/service_worker_read_from_cache_job.cc \
 	content/browser/service_worker/service_worker_register_job.cc \
 	content/browser/service_worker/service_worker_registration.cc \
 	content/browser/service_worker/service_worker_registration_status.cc \
@@ -575,11 +578,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -751,11 +749,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_browser.target.darwin-x86.mk b/content/content_browser.target.darwin-x86.mk
index c322196..d8bd77f 100644
--- a/content/content_browser.target.darwin-x86.mk
+++ b/content/content_browser.target.darwin-x86.mk
@@ -63,6 +63,7 @@
 	content/public/browser/browser_main_parts.cc \
 	content/public/browser/browser_message_filter.cc \
 	content/public/browser/browser_plugin_guest_delegate.cc \
+	content/public/browser/browser_plugin_guest_manager_delegate.cc \
 	content/public/browser/content_browser_client.cc \
 	content/public/browser/desktop_media_id.cc \
 	content/public/browser/download_manager_delegate.cc \
@@ -114,7 +115,6 @@
 	content/browser/android/in_process/synchronous_compositor_output_surface.cc \
 	content/browser/android/in_process/synchronous_input_event_filter.cc \
 	content/browser/android/interstitial_page_delegate_android.cc \
-	content/browser/android/layer_tree_build_helper_impl.cc \
 	content/browser/android/load_url_params.cc \
 	content/browser/android/overscroll_glow.cc \
 	content/browser/android/surface_texture_peer_browser_impl.cc \
@@ -157,9 +157,9 @@
 	content/browser/devtools/devtools_system_info_handler.cc \
 	content/browser/devtools/devtools_tracing_handler.cc \
 	content/browser/devtools/ipc_devtools_agent_host.cc \
+	content/browser/devtools/embedded_worker_devtools_manager.cc \
 	content/browser/devtools/render_view_devtools_agent_host.cc \
 	content/browser/devtools/renderer_overrides_handler.cc \
-	content/browser/devtools/shared_worker_devtools_manager.cc \
 	content/browser/devtools/tethering_handler.cc \
 	content/browser/devtools/worker_devtools_manager.cc \
 	content/browser/devtools/worker_devtools_message_filter.cc \
@@ -354,6 +354,7 @@
 	content/browser/renderer_host/ime_adapter_android.cc \
 	content/browser/renderer_host/input/gesture_event_queue.cc \
 	content/browser/renderer_host/input/input_router_impl.cc \
+	content/browser/renderer_host/input/input_router_config_helper.cc \
 	content/browser/renderer_host/input/motion_event_android.cc \
 	content/browser/renderer_host/input/motion_event_web.cc \
 	content/browser/renderer_host/input/synthetic_gesture.cc \
@@ -429,6 +430,7 @@
 	content/browser/service_worker/service_worker_context_wrapper.cc \
 	content/browser/service_worker/service_worker_controllee_request_handler.cc \
 	content/browser/service_worker/service_worker_database.cc \
+	content/browser/service_worker/service_worker_disk_cache.cc \
 	content/browser/service_worker/service_worker_dispatcher_host.cc \
 	content/browser/service_worker/service_worker_fetch_dispatcher.cc \
 	content/browser/service_worker/service_worker_handle.cc \
@@ -437,6 +439,7 @@
 	content/browser/service_worker/service_worker_job_coordinator.cc \
 	content/browser/service_worker/service_worker_process_manager.cc \
 	content/browser/service_worker/service_worker_provider_host.cc \
+	content/browser/service_worker/service_worker_read_from_cache_job.cc \
 	content/browser/service_worker/service_worker_register_job.cc \
 	content/browser/service_worker/service_worker_registration.cc \
 	content/browser/service_worker/service_worker_registration_status.cc \
@@ -527,7 +530,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -576,11 +578,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -703,7 +700,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -752,11 +748,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_browser.target.darwin-x86_64.mk b/content/content_browser.target.darwin-x86_64.mk
index fde7931..5110287 100644
--- a/content/content_browser.target.darwin-x86_64.mk
+++ b/content/content_browser.target.darwin-x86_64.mk
@@ -63,6 +63,7 @@
 	content/public/browser/browser_main_parts.cc \
 	content/public/browser/browser_message_filter.cc \
 	content/public/browser/browser_plugin_guest_delegate.cc \
+	content/public/browser/browser_plugin_guest_manager_delegate.cc \
 	content/public/browser/content_browser_client.cc \
 	content/public/browser/desktop_media_id.cc \
 	content/public/browser/download_manager_delegate.cc \
@@ -114,7 +115,6 @@
 	content/browser/android/in_process/synchronous_compositor_output_surface.cc \
 	content/browser/android/in_process/synchronous_input_event_filter.cc \
 	content/browser/android/interstitial_page_delegate_android.cc \
-	content/browser/android/layer_tree_build_helper_impl.cc \
 	content/browser/android/load_url_params.cc \
 	content/browser/android/overscroll_glow.cc \
 	content/browser/android/surface_texture_peer_browser_impl.cc \
@@ -157,9 +157,9 @@
 	content/browser/devtools/devtools_system_info_handler.cc \
 	content/browser/devtools/devtools_tracing_handler.cc \
 	content/browser/devtools/ipc_devtools_agent_host.cc \
+	content/browser/devtools/embedded_worker_devtools_manager.cc \
 	content/browser/devtools/render_view_devtools_agent_host.cc \
 	content/browser/devtools/renderer_overrides_handler.cc \
-	content/browser/devtools/shared_worker_devtools_manager.cc \
 	content/browser/devtools/tethering_handler.cc \
 	content/browser/devtools/worker_devtools_manager.cc \
 	content/browser/devtools/worker_devtools_message_filter.cc \
@@ -354,6 +354,7 @@
 	content/browser/renderer_host/ime_adapter_android.cc \
 	content/browser/renderer_host/input/gesture_event_queue.cc \
 	content/browser/renderer_host/input/input_router_impl.cc \
+	content/browser/renderer_host/input/input_router_config_helper.cc \
 	content/browser/renderer_host/input/motion_event_android.cc \
 	content/browser/renderer_host/input/motion_event_web.cc \
 	content/browser/renderer_host/input/synthetic_gesture.cc \
@@ -429,6 +430,7 @@
 	content/browser/service_worker/service_worker_context_wrapper.cc \
 	content/browser/service_worker/service_worker_controllee_request_handler.cc \
 	content/browser/service_worker/service_worker_database.cc \
+	content/browser/service_worker/service_worker_disk_cache.cc \
 	content/browser/service_worker/service_worker_dispatcher_host.cc \
 	content/browser/service_worker/service_worker_fetch_dispatcher.cc \
 	content/browser/service_worker/service_worker_handle.cc \
@@ -437,6 +439,7 @@
 	content/browser/service_worker/service_worker_job_coordinator.cc \
 	content/browser/service_worker/service_worker_process_manager.cc \
 	content/browser/service_worker/service_worker_provider_host.cc \
+	content/browser/service_worker/service_worker_read_from_cache_job.cc \
 	content/browser/service_worker/service_worker_register_job.cc \
 	content/browser/service_worker/service_worker_registration.cc \
 	content/browser/service_worker/service_worker_registration_status.cc \
@@ -527,7 +530,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -577,11 +579,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -704,7 +701,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -754,11 +750,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_browser.target.linux-arm.mk b/content/content_browser.target.linux-arm.mk
index 72c8b0d..f1155a9 100644
--- a/content/content_browser.target.linux-arm.mk
+++ b/content/content_browser.target.linux-arm.mk
@@ -63,6 +63,7 @@
 	content/public/browser/browser_main_parts.cc \
 	content/public/browser/browser_message_filter.cc \
 	content/public/browser/browser_plugin_guest_delegate.cc \
+	content/public/browser/browser_plugin_guest_manager_delegate.cc \
 	content/public/browser/content_browser_client.cc \
 	content/public/browser/desktop_media_id.cc \
 	content/public/browser/download_manager_delegate.cc \
@@ -114,7 +115,6 @@
 	content/browser/android/in_process/synchronous_compositor_output_surface.cc \
 	content/browser/android/in_process/synchronous_input_event_filter.cc \
 	content/browser/android/interstitial_page_delegate_android.cc \
-	content/browser/android/layer_tree_build_helper_impl.cc \
 	content/browser/android/load_url_params.cc \
 	content/browser/android/overscroll_glow.cc \
 	content/browser/android/surface_texture_peer_browser_impl.cc \
@@ -157,9 +157,9 @@
 	content/browser/devtools/devtools_system_info_handler.cc \
 	content/browser/devtools/devtools_tracing_handler.cc \
 	content/browser/devtools/ipc_devtools_agent_host.cc \
+	content/browser/devtools/embedded_worker_devtools_manager.cc \
 	content/browser/devtools/render_view_devtools_agent_host.cc \
 	content/browser/devtools/renderer_overrides_handler.cc \
-	content/browser/devtools/shared_worker_devtools_manager.cc \
 	content/browser/devtools/tethering_handler.cc \
 	content/browser/devtools/worker_devtools_manager.cc \
 	content/browser/devtools/worker_devtools_message_filter.cc \
@@ -354,6 +354,7 @@
 	content/browser/renderer_host/ime_adapter_android.cc \
 	content/browser/renderer_host/input/gesture_event_queue.cc \
 	content/browser/renderer_host/input/input_router_impl.cc \
+	content/browser/renderer_host/input/input_router_config_helper.cc \
 	content/browser/renderer_host/input/motion_event_android.cc \
 	content/browser/renderer_host/input/motion_event_web.cc \
 	content/browser/renderer_host/input/synthetic_gesture.cc \
@@ -429,6 +430,7 @@
 	content/browser/service_worker/service_worker_context_wrapper.cc \
 	content/browser/service_worker/service_worker_controllee_request_handler.cc \
 	content/browser/service_worker/service_worker_database.cc \
+	content/browser/service_worker/service_worker_disk_cache.cc \
 	content/browser/service_worker/service_worker_dispatcher_host.cc \
 	content/browser/service_worker/service_worker_fetch_dispatcher.cc \
 	content/browser/service_worker/service_worker_handle.cc \
@@ -437,6 +439,7 @@
 	content/browser/service_worker/service_worker_job_coordinator.cc \
 	content/browser/service_worker/service_worker_process_manager.cc \
 	content/browser/service_worker/service_worker_provider_host.cc \
+	content/browser/service_worker/service_worker_read_from_cache_job.cc \
 	content/browser/service_worker/service_worker_register_job.cc \
 	content/browser/service_worker/service_worker_registration.cc \
 	content/browser/service_worker/service_worker_registration_status.cc \
@@ -525,7 +528,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -576,11 +578,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -702,7 +699,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -753,11 +749,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_browser.target.linux-arm64.mk b/content/content_browser.target.linux-arm64.mk
index 702e359..9f915cb 100644
--- a/content/content_browser.target.linux-arm64.mk
+++ b/content/content_browser.target.linux-arm64.mk
@@ -63,6 +63,7 @@
 	content/public/browser/browser_main_parts.cc \
 	content/public/browser/browser_message_filter.cc \
 	content/public/browser/browser_plugin_guest_delegate.cc \
+	content/public/browser/browser_plugin_guest_manager_delegate.cc \
 	content/public/browser/content_browser_client.cc \
 	content/public/browser/desktop_media_id.cc \
 	content/public/browser/download_manager_delegate.cc \
@@ -114,7 +115,6 @@
 	content/browser/android/in_process/synchronous_compositor_output_surface.cc \
 	content/browser/android/in_process/synchronous_input_event_filter.cc \
 	content/browser/android/interstitial_page_delegate_android.cc \
-	content/browser/android/layer_tree_build_helper_impl.cc \
 	content/browser/android/load_url_params.cc \
 	content/browser/android/overscroll_glow.cc \
 	content/browser/android/surface_texture_peer_browser_impl.cc \
@@ -157,9 +157,9 @@
 	content/browser/devtools/devtools_system_info_handler.cc \
 	content/browser/devtools/devtools_tracing_handler.cc \
 	content/browser/devtools/ipc_devtools_agent_host.cc \
+	content/browser/devtools/embedded_worker_devtools_manager.cc \
 	content/browser/devtools/render_view_devtools_agent_host.cc \
 	content/browser/devtools/renderer_overrides_handler.cc \
-	content/browser/devtools/shared_worker_devtools_manager.cc \
 	content/browser/devtools/tethering_handler.cc \
 	content/browser/devtools/worker_devtools_manager.cc \
 	content/browser/devtools/worker_devtools_message_filter.cc \
@@ -354,6 +354,7 @@
 	content/browser/renderer_host/ime_adapter_android.cc \
 	content/browser/renderer_host/input/gesture_event_queue.cc \
 	content/browser/renderer_host/input/input_router_impl.cc \
+	content/browser/renderer_host/input/input_router_config_helper.cc \
 	content/browser/renderer_host/input/motion_event_android.cc \
 	content/browser/renderer_host/input/motion_event_web.cc \
 	content/browser/renderer_host/input/synthetic_gesture.cc \
@@ -429,6 +430,7 @@
 	content/browser/service_worker/service_worker_context_wrapper.cc \
 	content/browser/service_worker/service_worker_controllee_request_handler.cc \
 	content/browser/service_worker/service_worker_database.cc \
+	content/browser/service_worker/service_worker_disk_cache.cc \
 	content/browser/service_worker/service_worker_dispatcher_host.cc \
 	content/browser/service_worker/service_worker_fetch_dispatcher.cc \
 	content/browser/service_worker/service_worker_handle.cc \
@@ -437,6 +439,7 @@
 	content/browser/service_worker/service_worker_job_coordinator.cc \
 	content/browser/service_worker/service_worker_process_manager.cc \
 	content/browser/service_worker/service_worker_provider_host.cc \
+	content/browser/service_worker/service_worker_read_from_cache_job.cc \
 	content/browser/service_worker/service_worker_register_job.cc \
 	content/browser/service_worker/service_worker_registration.cc \
 	content/browser/service_worker/service_worker_registration_status.cc \
@@ -572,11 +575,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -744,11 +742,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_browser.target.linux-mips.mk b/content/content_browser.target.linux-mips.mk
index 126847d..8a2c57a 100644
--- a/content/content_browser.target.linux-mips.mk
+++ b/content/content_browser.target.linux-mips.mk
@@ -63,6 +63,7 @@
 	content/public/browser/browser_main_parts.cc \
 	content/public/browser/browser_message_filter.cc \
 	content/public/browser/browser_plugin_guest_delegate.cc \
+	content/public/browser/browser_plugin_guest_manager_delegate.cc \
 	content/public/browser/content_browser_client.cc \
 	content/public/browser/desktop_media_id.cc \
 	content/public/browser/download_manager_delegate.cc \
@@ -114,7 +115,6 @@
 	content/browser/android/in_process/synchronous_compositor_output_surface.cc \
 	content/browser/android/in_process/synchronous_input_event_filter.cc \
 	content/browser/android/interstitial_page_delegate_android.cc \
-	content/browser/android/layer_tree_build_helper_impl.cc \
 	content/browser/android/load_url_params.cc \
 	content/browser/android/overscroll_glow.cc \
 	content/browser/android/surface_texture_peer_browser_impl.cc \
@@ -157,9 +157,9 @@
 	content/browser/devtools/devtools_system_info_handler.cc \
 	content/browser/devtools/devtools_tracing_handler.cc \
 	content/browser/devtools/ipc_devtools_agent_host.cc \
+	content/browser/devtools/embedded_worker_devtools_manager.cc \
 	content/browser/devtools/render_view_devtools_agent_host.cc \
 	content/browser/devtools/renderer_overrides_handler.cc \
-	content/browser/devtools/shared_worker_devtools_manager.cc \
 	content/browser/devtools/tethering_handler.cc \
 	content/browser/devtools/worker_devtools_manager.cc \
 	content/browser/devtools/worker_devtools_message_filter.cc \
@@ -354,6 +354,7 @@
 	content/browser/renderer_host/ime_adapter_android.cc \
 	content/browser/renderer_host/input/gesture_event_queue.cc \
 	content/browser/renderer_host/input/input_router_impl.cc \
+	content/browser/renderer_host/input/input_router_config_helper.cc \
 	content/browser/renderer_host/input/motion_event_android.cc \
 	content/browser/renderer_host/input/motion_event_web.cc \
 	content/browser/renderer_host/input/synthetic_gesture.cc \
@@ -429,6 +430,7 @@
 	content/browser/service_worker/service_worker_context_wrapper.cc \
 	content/browser/service_worker/service_worker_controllee_request_handler.cc \
 	content/browser/service_worker/service_worker_database.cc \
+	content/browser/service_worker/service_worker_disk_cache.cc \
 	content/browser/service_worker/service_worker_dispatcher_host.cc \
 	content/browser/service_worker/service_worker_fetch_dispatcher.cc \
 	content/browser/service_worker/service_worker_handle.cc \
@@ -437,6 +439,7 @@
 	content/browser/service_worker/service_worker_job_coordinator.cc \
 	content/browser/service_worker/service_worker_process_manager.cc \
 	content/browser/service_worker/service_worker_provider_host.cc \
+	content/browser/service_worker/service_worker_read_from_cache_job.cc \
 	content/browser/service_worker/service_worker_register_job.cc \
 	content/browser/service_worker/service_worker_registration.cc \
 	content/browser/service_worker/service_worker_registration_status.cc \
@@ -575,11 +578,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -751,11 +749,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_browser.target.linux-x86.mk b/content/content_browser.target.linux-x86.mk
index c322196..d8bd77f 100644
--- a/content/content_browser.target.linux-x86.mk
+++ b/content/content_browser.target.linux-x86.mk
@@ -63,6 +63,7 @@
 	content/public/browser/browser_main_parts.cc \
 	content/public/browser/browser_message_filter.cc \
 	content/public/browser/browser_plugin_guest_delegate.cc \
+	content/public/browser/browser_plugin_guest_manager_delegate.cc \
 	content/public/browser/content_browser_client.cc \
 	content/public/browser/desktop_media_id.cc \
 	content/public/browser/download_manager_delegate.cc \
@@ -114,7 +115,6 @@
 	content/browser/android/in_process/synchronous_compositor_output_surface.cc \
 	content/browser/android/in_process/synchronous_input_event_filter.cc \
 	content/browser/android/interstitial_page_delegate_android.cc \
-	content/browser/android/layer_tree_build_helper_impl.cc \
 	content/browser/android/load_url_params.cc \
 	content/browser/android/overscroll_glow.cc \
 	content/browser/android/surface_texture_peer_browser_impl.cc \
@@ -157,9 +157,9 @@
 	content/browser/devtools/devtools_system_info_handler.cc \
 	content/browser/devtools/devtools_tracing_handler.cc \
 	content/browser/devtools/ipc_devtools_agent_host.cc \
+	content/browser/devtools/embedded_worker_devtools_manager.cc \
 	content/browser/devtools/render_view_devtools_agent_host.cc \
 	content/browser/devtools/renderer_overrides_handler.cc \
-	content/browser/devtools/shared_worker_devtools_manager.cc \
 	content/browser/devtools/tethering_handler.cc \
 	content/browser/devtools/worker_devtools_manager.cc \
 	content/browser/devtools/worker_devtools_message_filter.cc \
@@ -354,6 +354,7 @@
 	content/browser/renderer_host/ime_adapter_android.cc \
 	content/browser/renderer_host/input/gesture_event_queue.cc \
 	content/browser/renderer_host/input/input_router_impl.cc \
+	content/browser/renderer_host/input/input_router_config_helper.cc \
 	content/browser/renderer_host/input/motion_event_android.cc \
 	content/browser/renderer_host/input/motion_event_web.cc \
 	content/browser/renderer_host/input/synthetic_gesture.cc \
@@ -429,6 +430,7 @@
 	content/browser/service_worker/service_worker_context_wrapper.cc \
 	content/browser/service_worker/service_worker_controllee_request_handler.cc \
 	content/browser/service_worker/service_worker_database.cc \
+	content/browser/service_worker/service_worker_disk_cache.cc \
 	content/browser/service_worker/service_worker_dispatcher_host.cc \
 	content/browser/service_worker/service_worker_fetch_dispatcher.cc \
 	content/browser/service_worker/service_worker_handle.cc \
@@ -437,6 +439,7 @@
 	content/browser/service_worker/service_worker_job_coordinator.cc \
 	content/browser/service_worker/service_worker_process_manager.cc \
 	content/browser/service_worker/service_worker_provider_host.cc \
+	content/browser/service_worker/service_worker_read_from_cache_job.cc \
 	content/browser/service_worker/service_worker_register_job.cc \
 	content/browser/service_worker/service_worker_registration.cc \
 	content/browser/service_worker/service_worker_registration_status.cc \
@@ -527,7 +530,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -576,11 +578,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -703,7 +700,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -752,11 +748,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_browser.target.linux-x86_64.mk b/content/content_browser.target.linux-x86_64.mk
index fde7931..5110287 100644
--- a/content/content_browser.target.linux-x86_64.mk
+++ b/content/content_browser.target.linux-x86_64.mk
@@ -63,6 +63,7 @@
 	content/public/browser/browser_main_parts.cc \
 	content/public/browser/browser_message_filter.cc \
 	content/public/browser/browser_plugin_guest_delegate.cc \
+	content/public/browser/browser_plugin_guest_manager_delegate.cc \
 	content/public/browser/content_browser_client.cc \
 	content/public/browser/desktop_media_id.cc \
 	content/public/browser/download_manager_delegate.cc \
@@ -114,7 +115,6 @@
 	content/browser/android/in_process/synchronous_compositor_output_surface.cc \
 	content/browser/android/in_process/synchronous_input_event_filter.cc \
 	content/browser/android/interstitial_page_delegate_android.cc \
-	content/browser/android/layer_tree_build_helper_impl.cc \
 	content/browser/android/load_url_params.cc \
 	content/browser/android/overscroll_glow.cc \
 	content/browser/android/surface_texture_peer_browser_impl.cc \
@@ -157,9 +157,9 @@
 	content/browser/devtools/devtools_system_info_handler.cc \
 	content/browser/devtools/devtools_tracing_handler.cc \
 	content/browser/devtools/ipc_devtools_agent_host.cc \
+	content/browser/devtools/embedded_worker_devtools_manager.cc \
 	content/browser/devtools/render_view_devtools_agent_host.cc \
 	content/browser/devtools/renderer_overrides_handler.cc \
-	content/browser/devtools/shared_worker_devtools_manager.cc \
 	content/browser/devtools/tethering_handler.cc \
 	content/browser/devtools/worker_devtools_manager.cc \
 	content/browser/devtools/worker_devtools_message_filter.cc \
@@ -354,6 +354,7 @@
 	content/browser/renderer_host/ime_adapter_android.cc \
 	content/browser/renderer_host/input/gesture_event_queue.cc \
 	content/browser/renderer_host/input/input_router_impl.cc \
+	content/browser/renderer_host/input/input_router_config_helper.cc \
 	content/browser/renderer_host/input/motion_event_android.cc \
 	content/browser/renderer_host/input/motion_event_web.cc \
 	content/browser/renderer_host/input/synthetic_gesture.cc \
@@ -429,6 +430,7 @@
 	content/browser/service_worker/service_worker_context_wrapper.cc \
 	content/browser/service_worker/service_worker_controllee_request_handler.cc \
 	content/browser/service_worker/service_worker_database.cc \
+	content/browser/service_worker/service_worker_disk_cache.cc \
 	content/browser/service_worker/service_worker_dispatcher_host.cc \
 	content/browser/service_worker/service_worker_fetch_dispatcher.cc \
 	content/browser/service_worker/service_worker_handle.cc \
@@ -437,6 +439,7 @@
 	content/browser/service_worker/service_worker_job_coordinator.cc \
 	content/browser/service_worker/service_worker_process_manager.cc \
 	content/browser/service_worker/service_worker_provider_host.cc \
+	content/browser/service_worker/service_worker_read_from_cache_job.cc \
 	content/browser/service_worker/service_worker_register_job.cc \
 	content/browser/service_worker/service_worker_registration.cc \
 	content/browser/service_worker/service_worker_registration_status.cc \
@@ -527,7 +530,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -577,11 +579,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -704,7 +701,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -754,11 +750,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_child.gypi b/content/content_child.gypi
index c46451c..e695981 100644
--- a/content/content_child.gypi
+++ b/content/content_child.gypi
@@ -146,12 +146,16 @@
     'child/runtime_features.h',
     'child/scoped_child_process_reference.cc',
     'child/scoped_child_process_reference.h',
+    'child/service_worker/service_worker_handle_reference.cc',
+    'child/service_worker/service_worker_handle_reference.h',
     'child/service_worker/service_worker_dispatcher.cc',
     'child/service_worker/service_worker_dispatcher.h',
     'child/service_worker/service_worker_message_filter.cc',
     'child/service_worker/service_worker_message_filter.h',
     'child/service_worker/service_worker_network_provider.cc',
     'child/service_worker/service_worker_network_provider.h',
+    'child/service_worker/service_worker_provider_context.cc',
+    'child/service_worker/service_worker_provider_context.h',
     'child/service_worker/web_service_worker_impl.cc',
     'child/service_worker/web_service_worker_impl.h',
     'child/service_worker/web_service_worker_provider_impl.cc',
diff --git a/content/content_child.target.darwin-arm.mk b/content/content_child.target.darwin-arm.mk
index 7d72f9b..7b86b37 100644
--- a/content/content_child.target.darwin-arm.mk
+++ b/content/content_child.target.darwin-arm.mk
@@ -78,9 +78,11 @@
 	content/child/resource_dispatcher.cc \
 	content/child/runtime_features.cc \
 	content/child/scoped_child_process_reference.cc \
+	content/child/service_worker/service_worker_handle_reference.cc \
 	content/child/service_worker/service_worker_dispatcher.cc \
 	content/child/service_worker/service_worker_message_filter.cc \
 	content/child/service_worker/service_worker_network_provider.cc \
+	content/child/service_worker/service_worker_provider_context.cc \
 	content/child/service_worker/web_service_worker_impl.cc \
 	content/child/service_worker/web_service_worker_provider_impl.cc \
 	content/child/shared_worker_devtools_agent.cc \
@@ -127,7 +129,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -177,11 +178,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -276,7 +272,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -326,11 +321,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_child.target.darwin-arm64.mk b/content/content_child.target.darwin-arm64.mk
index cfbb0a9..cc05b03 100644
--- a/content/content_child.target.darwin-arm64.mk
+++ b/content/content_child.target.darwin-arm64.mk
@@ -78,9 +78,11 @@
 	content/child/resource_dispatcher.cc \
 	content/child/runtime_features.cc \
 	content/child/scoped_child_process_reference.cc \
+	content/child/service_worker/service_worker_handle_reference.cc \
 	content/child/service_worker/service_worker_dispatcher.cc \
 	content/child/service_worker/service_worker_message_filter.cc \
 	content/child/service_worker/service_worker_network_provider.cc \
+	content/child/service_worker/service_worker_provider_context.cc \
 	content/child/service_worker/web_service_worker_impl.cc \
 	content/child/service_worker/web_service_worker_provider_impl.cc \
 	content/child/shared_worker_devtools_agent.cc \
@@ -173,11 +175,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -317,11 +314,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_child.target.darwin-mips.mk b/content/content_child.target.darwin-mips.mk
index a241d92..b35db36 100644
--- a/content/content_child.target.darwin-mips.mk
+++ b/content/content_child.target.darwin-mips.mk
@@ -78,9 +78,11 @@
 	content/child/resource_dispatcher.cc \
 	content/child/runtime_features.cc \
 	content/child/scoped_child_process_reference.cc \
+	content/child/service_worker/service_worker_handle_reference.cc \
 	content/child/service_worker/service_worker_dispatcher.cc \
 	content/child/service_worker/service_worker_message_filter.cc \
 	content/child/service_worker/service_worker_network_provider.cc \
+	content/child/service_worker/service_worker_provider_context.cc \
 	content/child/service_worker/web_service_worker_impl.cc \
 	content/child/service_worker/web_service_worker_provider_impl.cc \
 	content/child/shared_worker_devtools_agent.cc \
@@ -176,11 +178,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -324,11 +321,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_child.target.darwin-x86.mk b/content/content_child.target.darwin-x86.mk
index c28ad02..b21b62c 100644
--- a/content/content_child.target.darwin-x86.mk
+++ b/content/content_child.target.darwin-x86.mk
@@ -78,9 +78,11 @@
 	content/child/resource_dispatcher.cc \
 	content/child/runtime_features.cc \
 	content/child/scoped_child_process_reference.cc \
+	content/child/service_worker/service_worker_handle_reference.cc \
 	content/child/service_worker/service_worker_dispatcher.cc \
 	content/child/service_worker/service_worker_message_filter.cc \
 	content/child/service_worker/service_worker_network_provider.cc \
+	content/child/service_worker/service_worker_provider_context.cc \
 	content/child/service_worker/web_service_worker_impl.cc \
 	content/child/service_worker/web_service_worker_provider_impl.cc \
 	content/child/shared_worker_devtools_agent.cc \
@@ -129,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -178,11 +179,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -277,7 +273,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -326,11 +321,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_child.target.darwin-x86_64.mk b/content/content_child.target.darwin-x86_64.mk
index d539dc1..b7d7290 100644
--- a/content/content_child.target.darwin-x86_64.mk
+++ b/content/content_child.target.darwin-x86_64.mk
@@ -78,9 +78,11 @@
 	content/child/resource_dispatcher.cc \
 	content/child/runtime_features.cc \
 	content/child/scoped_child_process_reference.cc \
+	content/child/service_worker/service_worker_handle_reference.cc \
 	content/child/service_worker/service_worker_dispatcher.cc \
 	content/child/service_worker/service_worker_message_filter.cc \
 	content/child/service_worker/service_worker_network_provider.cc \
+	content/child/service_worker/service_worker_provider_context.cc \
 	content/child/service_worker/web_service_worker_impl.cc \
 	content/child/service_worker/web_service_worker_provider_impl.cc \
 	content/child/shared_worker_devtools_agent.cc \
@@ -129,7 +131,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -178,11 +179,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -279,7 +275,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -328,11 +323,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_child.target.linux-arm.mk b/content/content_child.target.linux-arm.mk
index 7d72f9b..7b86b37 100644
--- a/content/content_child.target.linux-arm.mk
+++ b/content/content_child.target.linux-arm.mk
@@ -78,9 +78,11 @@
 	content/child/resource_dispatcher.cc \
 	content/child/runtime_features.cc \
 	content/child/scoped_child_process_reference.cc \
+	content/child/service_worker/service_worker_handle_reference.cc \
 	content/child/service_worker/service_worker_dispatcher.cc \
 	content/child/service_worker/service_worker_message_filter.cc \
 	content/child/service_worker/service_worker_network_provider.cc \
+	content/child/service_worker/service_worker_provider_context.cc \
 	content/child/service_worker/web_service_worker_impl.cc \
 	content/child/service_worker/web_service_worker_provider_impl.cc \
 	content/child/shared_worker_devtools_agent.cc \
@@ -127,7 +129,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -177,11 +178,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -276,7 +272,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -326,11 +321,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_child.target.linux-arm64.mk b/content/content_child.target.linux-arm64.mk
index cfbb0a9..cc05b03 100644
--- a/content/content_child.target.linux-arm64.mk
+++ b/content/content_child.target.linux-arm64.mk
@@ -78,9 +78,11 @@
 	content/child/resource_dispatcher.cc \
 	content/child/runtime_features.cc \
 	content/child/scoped_child_process_reference.cc \
+	content/child/service_worker/service_worker_handle_reference.cc \
 	content/child/service_worker/service_worker_dispatcher.cc \
 	content/child/service_worker/service_worker_message_filter.cc \
 	content/child/service_worker/service_worker_network_provider.cc \
+	content/child/service_worker/service_worker_provider_context.cc \
 	content/child/service_worker/web_service_worker_impl.cc \
 	content/child/service_worker/web_service_worker_provider_impl.cc \
 	content/child/shared_worker_devtools_agent.cc \
@@ -173,11 +175,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -317,11 +314,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_child.target.linux-mips.mk b/content/content_child.target.linux-mips.mk
index a241d92..b35db36 100644
--- a/content/content_child.target.linux-mips.mk
+++ b/content/content_child.target.linux-mips.mk
@@ -78,9 +78,11 @@
 	content/child/resource_dispatcher.cc \
 	content/child/runtime_features.cc \
 	content/child/scoped_child_process_reference.cc \
+	content/child/service_worker/service_worker_handle_reference.cc \
 	content/child/service_worker/service_worker_dispatcher.cc \
 	content/child/service_worker/service_worker_message_filter.cc \
 	content/child/service_worker/service_worker_network_provider.cc \
+	content/child/service_worker/service_worker_provider_context.cc \
 	content/child/service_worker/web_service_worker_impl.cc \
 	content/child/service_worker/web_service_worker_provider_impl.cc \
 	content/child/shared_worker_devtools_agent.cc \
@@ -176,11 +178,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -324,11 +321,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_child.target.linux-x86.mk b/content/content_child.target.linux-x86.mk
index c28ad02..b21b62c 100644
--- a/content/content_child.target.linux-x86.mk
+++ b/content/content_child.target.linux-x86.mk
@@ -78,9 +78,11 @@
 	content/child/resource_dispatcher.cc \
 	content/child/runtime_features.cc \
 	content/child/scoped_child_process_reference.cc \
+	content/child/service_worker/service_worker_handle_reference.cc \
 	content/child/service_worker/service_worker_dispatcher.cc \
 	content/child/service_worker/service_worker_message_filter.cc \
 	content/child/service_worker/service_worker_network_provider.cc \
+	content/child/service_worker/service_worker_provider_context.cc \
 	content/child/service_worker/web_service_worker_impl.cc \
 	content/child/service_worker/web_service_worker_provider_impl.cc \
 	content/child/shared_worker_devtools_agent.cc \
@@ -129,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -178,11 +179,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -277,7 +273,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -326,11 +321,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_child.target.linux-x86_64.mk b/content/content_child.target.linux-x86_64.mk
index d539dc1..b7d7290 100644
--- a/content/content_child.target.linux-x86_64.mk
+++ b/content/content_child.target.linux-x86_64.mk
@@ -78,9 +78,11 @@
 	content/child/resource_dispatcher.cc \
 	content/child/runtime_features.cc \
 	content/child/scoped_child_process_reference.cc \
+	content/child/service_worker/service_worker_handle_reference.cc \
 	content/child/service_worker/service_worker_dispatcher.cc \
 	content/child/service_worker/service_worker_message_filter.cc \
 	content/child/service_worker/service_worker_network_provider.cc \
+	content/child/service_worker/service_worker_provider_context.cc \
 	content/child/service_worker/web_service_worker_impl.cc \
 	content/child/service_worker/web_service_worker_provider_impl.cc \
 	content/child/shared_worker_devtools_agent.cc \
@@ -129,7 +131,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -178,11 +179,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -279,7 +275,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -328,11 +323,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_common.gypi b/content/content_common.gypi
index 8c330f5..61cc59b 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -175,7 +175,6 @@
     'common/cursors/webcursor_aurax11.cc',
     'common/cursors/webcursor_mac.mm',
     'common/cursors/webcursor_ozone.cc',
-    'common/cursors/webcursor_win.cc',
     'common/database_messages.h',
     'common/date_time_suggestion.h',
     'common/desktop_notification_messages.h',
@@ -212,9 +211,12 @@
     'common/frame_param_macros.h',
     'common/gamepad_hardware_buffer.h',
     'common/gamepad_messages.h',
+    'common/gamepad_param_traits.cc',
+    'common/gamepad_param_traits.h',
     'common/gamepad_user_gesture.cc',
     'common/gamepad_user_gesture.h',
     'common/geolocation_messages.h',
+    'common/gin_java_bridge_messages.h',
     'common/gpu/client/command_buffer_proxy_impl.cc',
     'common/gpu/client/command_buffer_proxy_impl.h',
     'common/gpu/client/context_provider_command_buffer.cc',
@@ -302,6 +304,7 @@
     'common/input/gesture_event_stream_validator.h',
     'common/input/input_event.cc',
     'common/input/input_event.h',
+    'common/input/input_event_ack_state.h',
     'common/input/input_event_stream_validator.cc',
     'common/input/input_event_stream_validator.h',
     'common/input/input_param_traits.cc',
@@ -452,7 +455,6 @@
     'common/websocket_messages.h',
     'common/worker_messages.h',
     'common/zygote_commands_linux.h',
-    'port/common/input_event_ack_state.h',
   ],
   'target_conditions': [
     ['OS=="android" and <(use_seccomp_bpf)==1', {
@@ -466,7 +468,6 @@
     ['use_aura==1', {
       'sources!': [
         'common/cursors/webcursor_mac.mm',
-        'common/cursors/webcursor_win.cc',
       ],
     }],
     ['OS=="ios"', {
@@ -616,14 +617,16 @@
       'sources': [
         'common/gpu/media/exynos_v4l2_video_device.cc',
         'common/gpu/media/exynos_v4l2_video_device.h',
-        'common/gpu/media/exynos_video_encode_accelerator.cc',
-        'common/gpu/media/exynos_video_encode_accelerator.h',
         'common/gpu/media/tegra_v4l2_video_device.cc',
         'common/gpu/media/tegra_v4l2_video_device.h',
+        'common/gpu/media/v4l2_image_processor.cc',
+        'common/gpu/media/v4l2_image_processor.h',
         'common/gpu/media/v4l2_video_decode_accelerator.cc',
         'common/gpu/media/v4l2_video_decode_accelerator.h',
         'common/gpu/media/v4l2_video_device.cc',
         'common/gpu/media/v4l2_video_device.h',
+        'common/gpu/media/v4l2_video_encode_accelerator.cc',
+        'common/gpu/media/v4l2_video_encode_accelerator.h',
       ],
       'include_dirs': [
         '<(DEPTH)/third_party/khronos',
diff --git a/content/content_common.target.darwin-arm.mk b/content/content_common.target.darwin-arm.mk
index 17869dc..dd34bfe 100644
--- a/content/content_common.target.darwin-arm.mk
+++ b/content/content_common.target.darwin-arm.mk
@@ -89,6 +89,7 @@
 	content/common/font_list.cc \
 	content/common/font_list_android.cc \
 	content/common/frame_param.cc \
+	content/common/gamepad_param_traits.cc \
 	content/common/gamepad_user_gesture.cc \
 	content/common/gpu/client/command_buffer_proxy_impl.cc \
 	content/common/gpu/client/context_provider_command_buffer.cc \
@@ -184,7 +185,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -236,11 +236,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -352,7 +347,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -404,11 +398,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_common.target.darwin-arm64.mk b/content/content_common.target.darwin-arm64.mk
index adb76c3..2a2d123 100644
--- a/content/content_common.target.darwin-arm64.mk
+++ b/content/content_common.target.darwin-arm64.mk
@@ -89,6 +89,7 @@
 	content/common/font_list.cc \
 	content/common/font_list_android.cc \
 	content/common/frame_param.cc \
+	content/common/gamepad_param_traits.cc \
 	content/common/gamepad_user_gesture.cc \
 	content/common/gpu/client/command_buffer_proxy_impl.cc \
 	content/common/gpu/client/context_provider_command_buffer.cc \
@@ -229,11 +230,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -391,11 +387,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_common.target.darwin-mips.mk b/content/content_common.target.darwin-mips.mk
index 9be18e4..6d54cb7 100644
--- a/content/content_common.target.darwin-mips.mk
+++ b/content/content_common.target.darwin-mips.mk
@@ -89,6 +89,7 @@
 	content/common/font_list.cc \
 	content/common/font_list_android.cc \
 	content/common/frame_param.cc \
+	content/common/gamepad_param_traits.cc \
 	content/common/gamepad_user_gesture.cc \
 	content/common/gpu/client/command_buffer_proxy_impl.cc \
 	content/common/gpu/client/context_provider_command_buffer.cc \
@@ -232,11 +233,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -398,11 +394,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_common.target.darwin-x86.mk b/content/content_common.target.darwin-x86.mk
index 26b44c0..c695a83 100644
--- a/content/content_common.target.darwin-x86.mk
+++ b/content/content_common.target.darwin-x86.mk
@@ -89,6 +89,7 @@
 	content/common/font_list.cc \
 	content/common/font_list_android.cc \
 	content/common/frame_param.cc \
+	content/common/gamepad_param_traits.cc \
 	content/common/gamepad_user_gesture.cc \
 	content/common/gpu/client/command_buffer_proxy_impl.cc \
 	content/common/gpu/client/context_provider_command_buffer.cc \
@@ -186,7 +187,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -236,11 +236,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -353,7 +348,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -403,11 +397,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_common.target.darwin-x86_64.mk b/content/content_common.target.darwin-x86_64.mk
index f4d9674..f5a3222 100644
--- a/content/content_common.target.darwin-x86_64.mk
+++ b/content/content_common.target.darwin-x86_64.mk
@@ -89,6 +89,7 @@
 	content/common/font_list.cc \
 	content/common/font_list_android.cc \
 	content/common/frame_param.cc \
+	content/common/gamepad_param_traits.cc \
 	content/common/gamepad_user_gesture.cc \
 	content/common/gpu/client/command_buffer_proxy_impl.cc \
 	content/common/gpu/client/context_provider_command_buffer.cc \
@@ -186,7 +187,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -237,11 +237,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -354,7 +349,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -405,11 +399,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_common.target.linux-arm.mk b/content/content_common.target.linux-arm.mk
index 17869dc..dd34bfe 100644
--- a/content/content_common.target.linux-arm.mk
+++ b/content/content_common.target.linux-arm.mk
@@ -89,6 +89,7 @@
 	content/common/font_list.cc \
 	content/common/font_list_android.cc \
 	content/common/frame_param.cc \
+	content/common/gamepad_param_traits.cc \
 	content/common/gamepad_user_gesture.cc \
 	content/common/gpu/client/command_buffer_proxy_impl.cc \
 	content/common/gpu/client/context_provider_command_buffer.cc \
@@ -184,7 +185,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -236,11 +236,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -352,7 +347,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -404,11 +398,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_common.target.linux-arm64.mk b/content/content_common.target.linux-arm64.mk
index adb76c3..2a2d123 100644
--- a/content/content_common.target.linux-arm64.mk
+++ b/content/content_common.target.linux-arm64.mk
@@ -89,6 +89,7 @@
 	content/common/font_list.cc \
 	content/common/font_list_android.cc \
 	content/common/frame_param.cc \
+	content/common/gamepad_param_traits.cc \
 	content/common/gamepad_user_gesture.cc \
 	content/common/gpu/client/command_buffer_proxy_impl.cc \
 	content/common/gpu/client/context_provider_command_buffer.cc \
@@ -229,11 +230,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -391,11 +387,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_common.target.linux-mips.mk b/content/content_common.target.linux-mips.mk
index 9be18e4..6d54cb7 100644
--- a/content/content_common.target.linux-mips.mk
+++ b/content/content_common.target.linux-mips.mk
@@ -89,6 +89,7 @@
 	content/common/font_list.cc \
 	content/common/font_list_android.cc \
 	content/common/frame_param.cc \
+	content/common/gamepad_param_traits.cc \
 	content/common/gamepad_user_gesture.cc \
 	content/common/gpu/client/command_buffer_proxy_impl.cc \
 	content/common/gpu/client/context_provider_command_buffer.cc \
@@ -232,11 +233,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -398,11 +394,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_common.target.linux-x86.mk b/content/content_common.target.linux-x86.mk
index 26b44c0..c695a83 100644
--- a/content/content_common.target.linux-x86.mk
+++ b/content/content_common.target.linux-x86.mk
@@ -89,6 +89,7 @@
 	content/common/font_list.cc \
 	content/common/font_list_android.cc \
 	content/common/frame_param.cc \
+	content/common/gamepad_param_traits.cc \
 	content/common/gamepad_user_gesture.cc \
 	content/common/gpu/client/command_buffer_proxy_impl.cc \
 	content/common/gpu/client/context_provider_command_buffer.cc \
@@ -186,7 +187,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -236,11 +236,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -353,7 +348,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -403,11 +397,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_common.target.linux-x86_64.mk b/content/content_common.target.linux-x86_64.mk
index f4d9674..f5a3222 100644
--- a/content/content_common.target.linux-x86_64.mk
+++ b/content/content_common.target.linux-x86_64.mk
@@ -89,6 +89,7 @@
 	content/common/font_list.cc \
 	content/common/font_list_android.cc \
 	content/common/frame_param.cc \
+	content/common/gamepad_param_traits.cc \
 	content/common/gamepad_user_gesture.cc \
 	content/common/gpu/client/command_buffer_proxy_impl.cc \
 	content/common/gpu/client/context_provider_command_buffer.cc \
@@ -186,7 +187,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -237,11 +237,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -354,7 +349,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -405,11 +399,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_common_mojo_bindings.target.darwin-arm.mk b/content/content_common_mojo_bindings.target.darwin-arm.mk
index d0d6f84..3d3fecd 100644
--- a/content/content_common_mojo_bindings.target.darwin-arm.mk
+++ b/content/content_common_mojo_bindings.target.darwin-arm.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "content_content_gyp_content_common_mojo_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -155,7 +155,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/content_common_mojo_bindings.target.darwin-arm64.mk b/content/content_common_mojo_bindings.target.darwin-arm64.mk
index 136cc20..4cd9159 100644
--- a/content/content_common_mojo_bindings.target.darwin-arm64.mk
+++ b/content/content_common_mojo_bindings.target.darwin-arm64.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "content_content_gyp_content_common_mojo_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_common_mojo_bindings.target.darwin-mips.mk b/content/content_common_mojo_bindings.target.darwin-mips.mk
index 4b94bc2..5a6c439 100644
--- a/content/content_common_mojo_bindings.target.darwin-mips.mk
+++ b/content/content_common_mojo_bindings.target.darwin-mips.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "content_content_gyp_content_common_mojo_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_common_mojo_bindings.target.darwin-x86.mk b/content/content_common_mojo_bindings.target.darwin-x86.mk
index 2b187a2..559cb90 100644
--- a/content/content_common_mojo_bindings.target.darwin-x86.mk
+++ b/content/content_common_mojo_bindings.target.darwin-x86.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "content_content_gyp_content_common_mojo_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,7 +69,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_common_mojo_bindings.target.darwin-x86_64.mk b/content/content_common_mojo_bindings.target.darwin-x86_64.mk
index 5c27181..d07587f 100644
--- a/content/content_common_mojo_bindings.target.darwin-x86_64.mk
+++ b/content/content_common_mojo_bindings.target.darwin-x86_64.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "content_content_gyp_content_common_mojo_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,7 +69,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_common_mojo_bindings.target.linux-arm.mk b/content/content_common_mojo_bindings.target.linux-arm.mk
index d0d6f84..3d3fecd 100644
--- a/content/content_common_mojo_bindings.target.linux-arm.mk
+++ b/content/content_common_mojo_bindings.target.linux-arm.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "content_content_gyp_content_common_mojo_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -155,7 +155,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/content_common_mojo_bindings.target.linux-arm64.mk b/content/content_common_mojo_bindings.target.linux-arm64.mk
index 136cc20..4cd9159 100644
--- a/content/content_common_mojo_bindings.target.linux-arm64.mk
+++ b/content/content_common_mojo_bindings.target.linux-arm64.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "content_content_gyp_content_common_mojo_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_common_mojo_bindings.target.linux-mips.mk b/content/content_common_mojo_bindings.target.linux-mips.mk
index 4b94bc2..5a6c439 100644
--- a/content/content_common_mojo_bindings.target.linux-mips.mk
+++ b/content/content_common_mojo_bindings.target.linux-mips.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "content_content_gyp_content_common_mojo_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_common_mojo_bindings.target.linux-x86.mk b/content/content_common_mojo_bindings.target.linux-x86.mk
index 2b187a2..559cb90 100644
--- a/content/content_common_mojo_bindings.target.linux-x86.mk
+++ b/content/content_common_mojo_bindings.target.linux-x86.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "content_content_gyp_content_common_mojo_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,7 +69,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_common_mojo_bindings.target.linux-x86_64.mk b/content/content_common_mojo_bindings.target.linux-x86_64.mk
index 5c27181..d07587f 100644
--- a/content/content_common_mojo_bindings.target.linux-x86_64.mk
+++ b/content/content_common_mojo_bindings.target.linux-x86_64.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "content_content_gyp_content_common_mojo_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['common/web_ui_setup.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/content/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/common/web_ui_setup.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,7 +69,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_gpu.target.darwin-arm.mk b/content/content_gpu.target.darwin-arm.mk
index 2a2c7c8..253ae53 100644
--- a/content/content_gpu.target.darwin-arm.mk
+++ b/content/content_gpu.target.darwin-arm.mk
@@ -49,7 +49,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -179,7 +173,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -229,11 +222,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_gpu.target.darwin-arm64.mk b/content/content_gpu.target.darwin-arm64.mk
index 626c02d..a8b4a2d 100644
--- a/content/content_gpu.target.darwin-arm64.mk
+++ b/content/content_gpu.target.darwin-arm64.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -220,11 +215,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_gpu.target.darwin-mips.mk b/content/content_gpu.target.darwin-mips.mk
index f953a6d..da86a58 100644
--- a/content/content_gpu.target.darwin-mips.mk
+++ b/content/content_gpu.target.darwin-mips.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -227,11 +222,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_gpu.target.darwin-x86.mk b/content/content_gpu.target.darwin-x86.mk
index e364ed6..9f9bb07 100644
--- a/content/content_gpu.target.darwin-x86.mk
+++ b/content/content_gpu.target.darwin-x86.mk
@@ -51,7 +51,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -181,7 +175,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_gpu.target.darwin-x86_64.mk b/content/content_gpu.target.darwin-x86_64.mk
index 72b4e84..9adf2ba 100644
--- a/content/content_gpu.target.darwin-x86_64.mk
+++ b/content/content_gpu.target.darwin-x86_64.mk
@@ -51,7 +51,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -181,7 +175,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_gpu.target.linux-arm.mk b/content/content_gpu.target.linux-arm.mk
index 2a2c7c8..253ae53 100644
--- a/content/content_gpu.target.linux-arm.mk
+++ b/content/content_gpu.target.linux-arm.mk
@@ -49,7 +49,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -179,7 +173,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -229,11 +222,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_gpu.target.linux-arm64.mk b/content/content_gpu.target.linux-arm64.mk
index 626c02d..a8b4a2d 100644
--- a/content/content_gpu.target.linux-arm64.mk
+++ b/content/content_gpu.target.linux-arm64.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -220,11 +215,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_gpu.target.linux-mips.mk b/content/content_gpu.target.linux-mips.mk
index f953a6d..da86a58 100644
--- a/content/content_gpu.target.linux-mips.mk
+++ b/content/content_gpu.target.linux-mips.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -227,11 +222,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_gpu.target.linux-x86.mk b/content/content_gpu.target.linux-x86.mk
index e364ed6..9f9bb07 100644
--- a/content/content_gpu.target.linux-x86.mk
+++ b/content/content_gpu.target.linux-x86.mk
@@ -51,7 +51,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -181,7 +175,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_gpu.target.linux-x86_64.mk b/content/content_gpu.target.linux-x86_64.mk
index 72b4e84..9adf2ba 100644
--- a/content/content_gpu.target.linux-x86_64.mk
+++ b/content/content_gpu.target.linux-x86_64.mk
@@ -51,7 +51,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -181,7 +175,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_jni_headers.target.darwin-arm.mk b/content/content_jni_headers.target.darwin-arm.mk
index fdce0ae..c37449f 100644
--- a/content/content_jni_headers.target.darwin-arm.mk
+++ b/content/content_jni_headers.target.darwin-arm.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java', 'public/android/java/src/org/chromium/content/browser/BatteryStatusManager.java', 'public/android/java/src/org/chromium/content/browser/BrowserStartupController.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceSensors.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java', 'public/android/java/src/org/chromium/content/browser/MediaDrmCredentialManager.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java', 'public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java', 'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java', 'public/android/java/src/org/chromium/content/browser/TimeZoneMonitor.java', 'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java', 'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java', 'public/android/java/src/org/chromium/content/browser/VibrationProvider.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java', 'public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -60,6 +65,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +74,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -164,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -172,6 +191,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -180,6 +200,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -188,6 +209,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -196,6 +218,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,6 +227,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -212,6 +236,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -220,6 +245,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -228,6 +254,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -236,6 +263,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -244,6 +272,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -252,6 +281,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -346,7 +376,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -431,7 +460,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/content_jni_headers.target.darwin-arm64.mk b/content/content_jni_headers.target.darwin-arm64.mk
index 27e2191..bf40706 100644
--- a/content/content_jni_headers.target.darwin-arm64.mk
+++ b/content/content_jni_headers.target.darwin-arm64.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java', 'public/android/java/src/org/chromium/content/browser/BatteryStatusManager.java', 'public/android/java/src/org/chromium/content/browser/BrowserStartupController.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceSensors.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java', 'public/android/java/src/org/chromium/content/browser/MediaDrmCredentialManager.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java', 'public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java', 'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java', 'public/android/java/src/org/chromium/content/browser/TimeZoneMonitor.java', 'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java', 'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java', 'public/android/java/src/org/chromium/content/browser/VibrationProvider.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java', 'public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -60,6 +65,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +74,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -164,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -172,6 +191,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -180,6 +200,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -188,6 +209,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -196,6 +218,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,6 +227,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -212,6 +236,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -220,6 +245,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -228,6 +254,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -236,6 +263,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -244,6 +272,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -252,6 +281,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_jni_headers.target.darwin-mips.mk b/content/content_jni_headers.target.darwin-mips.mk
index 01f4404..857e7d5 100644
--- a/content/content_jni_headers.target.darwin-mips.mk
+++ b/content/content_jni_headers.target.darwin-mips.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java', 'public/android/java/src/org/chromium/content/browser/BatteryStatusManager.java', 'public/android/java/src/org/chromium/content/browser/BrowserStartupController.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceSensors.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java', 'public/android/java/src/org/chromium/content/browser/MediaDrmCredentialManager.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java', 'public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java', 'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java', 'public/android/java/src/org/chromium/content/browser/TimeZoneMonitor.java', 'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java', 'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java', 'public/android/java/src/org/chromium/content/browser/VibrationProvider.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java', 'public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -60,6 +65,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +74,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -164,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -172,6 +191,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -180,6 +200,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -188,6 +209,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -196,6 +218,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,6 +227,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -212,6 +236,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -220,6 +245,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -228,6 +254,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -236,6 +263,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -244,6 +272,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -252,6 +281,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_jni_headers.target.darwin-x86.mk b/content/content_jni_headers.target.darwin-x86.mk
index d38a8a8..4c400cd 100644
--- a/content/content_jni_headers.target.darwin-x86.mk
+++ b/content/content_jni_headers.target.darwin-x86.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java', 'public/android/java/src/org/chromium/content/browser/BatteryStatusManager.java', 'public/android/java/src/org/chromium/content/browser/BrowserStartupController.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceSensors.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java', 'public/android/java/src/org/chromium/content/browser/MediaDrmCredentialManager.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java', 'public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java', 'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java', 'public/android/java/src/org/chromium/content/browser/TimeZoneMonitor.java', 'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java', 'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java', 'public/android/java/src/org/chromium/content/browser/VibrationProvider.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java', 'public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -60,6 +65,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +74,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -164,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -172,6 +191,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -180,6 +200,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -188,6 +209,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -196,6 +218,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,6 +227,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -212,6 +236,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -220,6 +245,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -228,6 +254,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -236,6 +263,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -244,6 +272,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -252,6 +281,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -348,7 +378,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -433,7 +462,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_jni_headers.target.darwin-x86_64.mk b/content/content_jni_headers.target.darwin-x86_64.mk
index a4c782d..af6f959 100644
--- a/content/content_jni_headers.target.darwin-x86_64.mk
+++ b/content/content_jni_headers.target.darwin-x86_64.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java', 'public/android/java/src/org/chromium/content/browser/BatteryStatusManager.java', 'public/android/java/src/org/chromium/content/browser/BrowserStartupController.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceSensors.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java', 'public/android/java/src/org/chromium/content/browser/MediaDrmCredentialManager.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java', 'public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java', 'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java', 'public/android/java/src/org/chromium/content/browser/TimeZoneMonitor.java', 'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java', 'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java', 'public/android/java/src/org/chromium/content/browser/VibrationProvider.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java', 'public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -60,6 +65,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +74,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -164,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -172,6 +191,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -180,6 +200,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -188,6 +209,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -196,6 +218,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,6 +227,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -212,6 +236,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -220,6 +245,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -228,6 +254,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -236,6 +263,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -244,6 +272,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -252,6 +281,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -348,7 +378,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -433,7 +462,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_jni_headers.target.linux-arm.mk b/content/content_jni_headers.target.linux-arm.mk
index fdce0ae..c37449f 100644
--- a/content/content_jni_headers.target.linux-arm.mk
+++ b/content/content_jni_headers.target.linux-arm.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java', 'public/android/java/src/org/chromium/content/browser/BatteryStatusManager.java', 'public/android/java/src/org/chromium/content/browser/BrowserStartupController.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceSensors.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java', 'public/android/java/src/org/chromium/content/browser/MediaDrmCredentialManager.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java', 'public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java', 'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java', 'public/android/java/src/org/chromium/content/browser/TimeZoneMonitor.java', 'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java', 'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java', 'public/android/java/src/org/chromium/content/browser/VibrationProvider.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java', 'public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -60,6 +65,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +74,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -164,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -172,6 +191,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -180,6 +200,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -188,6 +209,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -196,6 +218,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,6 +227,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -212,6 +236,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -220,6 +245,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -228,6 +254,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -236,6 +263,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -244,6 +272,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -252,6 +281,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -346,7 +376,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -431,7 +460,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/content_jni_headers.target.linux-arm64.mk b/content/content_jni_headers.target.linux-arm64.mk
index 27e2191..bf40706 100644
--- a/content/content_jni_headers.target.linux-arm64.mk
+++ b/content/content_jni_headers.target.linux-arm64.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java', 'public/android/java/src/org/chromium/content/browser/BatteryStatusManager.java', 'public/android/java/src/org/chromium/content/browser/BrowserStartupController.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceSensors.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java', 'public/android/java/src/org/chromium/content/browser/MediaDrmCredentialManager.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java', 'public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java', 'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java', 'public/android/java/src/org/chromium/content/browser/TimeZoneMonitor.java', 'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java', 'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java', 'public/android/java/src/org/chromium/content/browser/VibrationProvider.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java', 'public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -60,6 +65,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +74,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -164,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -172,6 +191,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -180,6 +200,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -188,6 +209,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -196,6 +218,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,6 +227,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -212,6 +236,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -220,6 +245,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -228,6 +254,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -236,6 +263,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -244,6 +272,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -252,6 +281,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_jni_headers.target.linux-mips.mk b/content/content_jni_headers.target.linux-mips.mk
index 01f4404..857e7d5 100644
--- a/content/content_jni_headers.target.linux-mips.mk
+++ b/content/content_jni_headers.target.linux-mips.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java', 'public/android/java/src/org/chromium/content/browser/BatteryStatusManager.java', 'public/android/java/src/org/chromium/content/browser/BrowserStartupController.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceSensors.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java', 'public/android/java/src/org/chromium/content/browser/MediaDrmCredentialManager.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java', 'public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java', 'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java', 'public/android/java/src/org/chromium/content/browser/TimeZoneMonitor.java', 'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java', 'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java', 'public/android/java/src/org/chromium/content/browser/VibrationProvider.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java', 'public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -60,6 +65,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +74,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -164,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -172,6 +191,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -180,6 +200,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -188,6 +209,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -196,6 +218,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,6 +227,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -212,6 +236,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -220,6 +245,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -228,6 +254,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -236,6 +263,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -244,6 +272,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -252,6 +281,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_jni_headers.target.linux-x86.mk b/content/content_jni_headers.target.linux-x86.mk
index d38a8a8..4c400cd 100644
--- a/content/content_jni_headers.target.linux-x86.mk
+++ b/content/content_jni_headers.target.linux-x86.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java', 'public/android/java/src/org/chromium/content/browser/BatteryStatusManager.java', 'public/android/java/src/org/chromium/content/browser/BrowserStartupController.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceSensors.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java', 'public/android/java/src/org/chromium/content/browser/MediaDrmCredentialManager.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java', 'public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java', 'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java', 'public/android/java/src/org/chromium/content/browser/TimeZoneMonitor.java', 'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java', 'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java', 'public/android/java/src/org/chromium/content/browser/VibrationProvider.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java', 'public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -60,6 +65,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +74,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -164,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -172,6 +191,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -180,6 +200,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -188,6 +209,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -196,6 +218,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,6 +227,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -212,6 +236,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -220,6 +245,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -228,6 +254,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -236,6 +263,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -244,6 +272,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -252,6 +281,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -348,7 +378,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -433,7 +462,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_jni_headers.target.linux-x86_64.mk b/content/content_jni_headers.target.linux-x86_64.mk
index a4c782d..af6f959 100644
--- a/content/content_jni_headers.target.linux-x86_64.mk
+++ b/content/content_jni_headers.target.linux-x86_64.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "content_content_gyp_content_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/content/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['public/android/java/src/org/chromium/content/app/ChildProcessService.java', 'public/android/java/src/org/chromium/content/app/ContentMain.java', 'public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java', 'public/android/java/src/org/chromium/content/browser/BatteryStatusManager.java', 'public/android/java/src/org/chromium/content/browser/BrowserStartupController.java', 'public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java', 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceSensors.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', 'public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java', 'public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java', 'public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java', 'public/android/java/src/org/chromium/content/browser/LoadUrlParams.java', 'public/android/java/src/org/chromium/content/browser/LocationProviderAdapter.java', 'public/android/java/src/org/chromium/content/browser/MediaDrmCredentialManager.java', 'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java', 'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java', 'public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java', 'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java', 'public/android/java/src/org/chromium/content/browser/TimeZoneMonitor.java', 'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java', 'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java', 'public/android/java/src/org/chromium/content/browser/VibrationProvider.java', 'public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java', 'public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java', 'public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/content/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessService_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -28,6 +29,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentMain_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -36,6 +38,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserAccessibilityManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +47,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BatteryStatusManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +56,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/BrowserStartupController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -60,6 +65,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ChildProcessLauncher_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,6 +74,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentSettings_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,6 +83,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentVideoView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -84,6 +92,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewCore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -92,6 +101,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewRenderView_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -100,6 +110,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ContentViewStatics_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -108,6 +119,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DeviceSensors_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,6 +128,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DownloadController_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,6 +137,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ImeAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -132,6 +146,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/DateTimeChooserAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,6 +155,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/InterstitialPageDelegateAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -148,6 +164,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LoadUrlParams_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,6 +173,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/LocationProviderAdapter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -164,6 +182,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaDrmCredentialManager_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -172,6 +191,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MediaResourceGetter_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -180,6 +200,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/PowerSaveBlocker_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -188,6 +209,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/ScreenOrientationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -196,6 +218,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/SpeechRecognition_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -204,6 +227,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TimeZoneMonitor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -212,6 +236,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TouchEventSynthesizer_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -220,6 +245,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/TracingControllerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -228,6 +254,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/VibrationProvider_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -236,6 +263,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsObserverAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -244,6 +272,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/NavigationControllerImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -252,6 +281,7 @@
 
 
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/WebContentsImpl_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -348,7 +378,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -433,7 +462,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index a962029..80fd4ec 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -184,8 +184,6 @@
     'renderer/input/input_handler_proxy.h',
     'renderer/input/input_handler_wrapper.cc',
     'renderer/input/input_handler_wrapper.h',
-    'renderer/input_tag_speech_dispatcher.cc',
-    'renderer/input_tag_speech_dispatcher.h',
     'renderer/internal_document_state_data.cc',
     'renderer/internal_document_state_data.h',
     'renderer/java/java_bridge_channel.cc',
@@ -377,8 +375,6 @@
     'renderer/pepper/pepper_platform_audio_input.h',
     'renderer/pepper/pepper_platform_audio_output.cc',
     'renderer/pepper/pepper_platform_audio_output.h',
-    'renderer/pepper/pepper_platform_context_3d.cc',
-    'renderer/pepper/pepper_platform_context_3d.h',
     'renderer/pepper/pepper_platform_video_capture.cc',
     'renderer/pepper/pepper_platform_video_capture.h',
     'renderer/pepper/pepper_plugin_instance_impl.cc',
@@ -558,12 +554,6 @@
         'renderer/active_notification_tracker.cc',
       ],
     }],
-    ['input_speech==0', {
-      'sources!': [
-        'renderer/input_tag_speech_dispatcher.cc',
-        'renderer/input_tag_speech_dispatcher.h',
-      ]
-    }],
     ['OS=="mac"', {
       'sources!': [
         'common/process_watcher_posix.cc',
@@ -686,6 +676,8 @@
         'renderer/media/rtc_video_encoder_factory.h',
         'renderer/media/rtc_video_renderer.cc',
         'renderer/media/rtc_video_renderer.h',
+        'renderer/media/video_frame_deliverer.cc',
+        'renderer/media/video_frame_deliverer.h',
         'renderer/media/video_source_handler.cc',
         'renderer/media/video_source_handler.h',
         'renderer/media/webaudio_capturer_source.cc',
diff --git a/content/content_renderer.target.darwin-arm.mk b/content/content_renderer.target.darwin-arm.mk
index 951d2ea..e39cc03 100644
--- a/content/content_renderer.target.darwin-arm.mk
+++ b/content/content_renderer.target.darwin-arm.mk
@@ -239,6 +239,7 @@
 	content/renderer/media/rtc_video_encoder.cc \
 	content/renderer/media/rtc_video_encoder_factory.cc \
 	content/renderer/media/rtc_video_renderer.cc \
+	content/renderer/media/video_frame_deliverer.cc \
 	content/renderer/media/video_source_handler.cc \
 	content/renderer/media/webaudio_capturer_source.cc \
 	content/renderer/media/webrtc/webrtc_video_track_adapter.cc \
@@ -280,7 +281,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -333,11 +333,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -459,7 +454,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -512,11 +506,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_renderer.target.darwin-arm64.mk b/content/content_renderer.target.darwin-arm64.mk
index d821615..f569491 100644
--- a/content/content_renderer.target.darwin-arm64.mk
+++ b/content/content_renderer.target.darwin-arm64.mk
@@ -239,6 +239,7 @@
 	content/renderer/media/rtc_video_encoder.cc \
 	content/renderer/media/rtc_video_encoder_factory.cc \
 	content/renderer/media/rtc_video_renderer.cc \
+	content/renderer/media/video_frame_deliverer.cc \
 	content/renderer/media/video_source_handler.cc \
 	content/renderer/media/webaudio_capturer_source.cc \
 	content/renderer/media/webrtc/webrtc_video_track_adapter.cc \
@@ -329,11 +330,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -503,11 +499,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_renderer.target.darwin-mips.mk b/content/content_renderer.target.darwin-mips.mk
index c4aff5f..6570800 100644
--- a/content/content_renderer.target.darwin-mips.mk
+++ b/content/content_renderer.target.darwin-mips.mk
@@ -239,6 +239,7 @@
 	content/renderer/media/rtc_video_encoder.cc \
 	content/renderer/media/rtc_video_encoder_factory.cc \
 	content/renderer/media/rtc_video_renderer.cc \
+	content/renderer/media/video_frame_deliverer.cc \
 	content/renderer/media/video_source_handler.cc \
 	content/renderer/media/webaudio_capturer_source.cc \
 	content/renderer/media/webrtc/webrtc_video_track_adapter.cc \
@@ -332,11 +333,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -510,11 +506,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_renderer.target.darwin-x86.mk b/content/content_renderer.target.darwin-x86.mk
index d27b5dd..c79504b 100644
--- a/content/content_renderer.target.darwin-x86.mk
+++ b/content/content_renderer.target.darwin-x86.mk
@@ -239,6 +239,7 @@
 	content/renderer/media/rtc_video_encoder.cc \
 	content/renderer/media/rtc_video_encoder_factory.cc \
 	content/renderer/media/rtc_video_renderer.cc \
+	content/renderer/media/video_frame_deliverer.cc \
 	content/renderer/media/video_source_handler.cc \
 	content/renderer/media/webaudio_capturer_source.cc \
 	content/renderer/media/webrtc/webrtc_video_track_adapter.cc \
@@ -282,7 +283,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -333,11 +333,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -460,7 +455,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -511,11 +505,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_renderer.target.darwin-x86_64.mk b/content/content_renderer.target.darwin-x86_64.mk
index b0bad04..2038b97 100644
--- a/content/content_renderer.target.darwin-x86_64.mk
+++ b/content/content_renderer.target.darwin-x86_64.mk
@@ -239,6 +239,7 @@
 	content/renderer/media/rtc_video_encoder.cc \
 	content/renderer/media/rtc_video_encoder_factory.cc \
 	content/renderer/media/rtc_video_renderer.cc \
+	content/renderer/media/video_frame_deliverer.cc \
 	content/renderer/media/video_source_handler.cc \
 	content/renderer/media/webaudio_capturer_source.cc \
 	content/renderer/media/webrtc/webrtc_video_track_adapter.cc \
@@ -282,7 +283,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -334,11 +334,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -461,7 +456,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -513,11 +507,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_renderer.target.linux-arm.mk b/content/content_renderer.target.linux-arm.mk
index 951d2ea..e39cc03 100644
--- a/content/content_renderer.target.linux-arm.mk
+++ b/content/content_renderer.target.linux-arm.mk
@@ -239,6 +239,7 @@
 	content/renderer/media/rtc_video_encoder.cc \
 	content/renderer/media/rtc_video_encoder_factory.cc \
 	content/renderer/media/rtc_video_renderer.cc \
+	content/renderer/media/video_frame_deliverer.cc \
 	content/renderer/media/video_source_handler.cc \
 	content/renderer/media/webaudio_capturer_source.cc \
 	content/renderer/media/webrtc/webrtc_video_track_adapter.cc \
@@ -280,7 +281,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -333,11 +333,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -459,7 +454,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -512,11 +506,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_renderer.target.linux-arm64.mk b/content/content_renderer.target.linux-arm64.mk
index d821615..f569491 100644
--- a/content/content_renderer.target.linux-arm64.mk
+++ b/content/content_renderer.target.linux-arm64.mk
@@ -239,6 +239,7 @@
 	content/renderer/media/rtc_video_encoder.cc \
 	content/renderer/media/rtc_video_encoder_factory.cc \
 	content/renderer/media/rtc_video_renderer.cc \
+	content/renderer/media/video_frame_deliverer.cc \
 	content/renderer/media/video_source_handler.cc \
 	content/renderer/media/webaudio_capturer_source.cc \
 	content/renderer/media/webrtc/webrtc_video_track_adapter.cc \
@@ -329,11 +330,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -503,11 +499,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_renderer.target.linux-mips.mk b/content/content_renderer.target.linux-mips.mk
index c4aff5f..6570800 100644
--- a/content/content_renderer.target.linux-mips.mk
+++ b/content/content_renderer.target.linux-mips.mk
@@ -239,6 +239,7 @@
 	content/renderer/media/rtc_video_encoder.cc \
 	content/renderer/media/rtc_video_encoder_factory.cc \
 	content/renderer/media/rtc_video_renderer.cc \
+	content/renderer/media/video_frame_deliverer.cc \
 	content/renderer/media/video_source_handler.cc \
 	content/renderer/media/webaudio_capturer_source.cc \
 	content/renderer/media/webrtc/webrtc_video_track_adapter.cc \
@@ -332,11 +333,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -510,11 +506,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_renderer.target.linux-x86.mk b/content/content_renderer.target.linux-x86.mk
index d27b5dd..c79504b 100644
--- a/content/content_renderer.target.linux-x86.mk
+++ b/content/content_renderer.target.linux-x86.mk
@@ -239,6 +239,7 @@
 	content/renderer/media/rtc_video_encoder.cc \
 	content/renderer/media/rtc_video_encoder_factory.cc \
 	content/renderer/media/rtc_video_renderer.cc \
+	content/renderer/media/video_frame_deliverer.cc \
 	content/renderer/media/video_source_handler.cc \
 	content/renderer/media/webaudio_capturer_source.cc \
 	content/renderer/media/webrtc/webrtc_video_track_adapter.cc \
@@ -282,7 +283,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -333,11 +333,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -460,7 +455,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -511,11 +505,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_renderer.target.linux-x86_64.mk b/content/content_renderer.target.linux-x86_64.mk
index b0bad04..2038b97 100644
--- a/content/content_renderer.target.linux-x86_64.mk
+++ b/content/content_renderer.target.linux-x86_64.mk
@@ -239,6 +239,7 @@
 	content/renderer/media/rtc_video_encoder.cc \
 	content/renderer/media/rtc_video_encoder_factory.cc \
 	content/renderer/media/rtc_video_renderer.cc \
+	content/renderer/media/video_frame_deliverer.cc \
 	content/renderer/media/video_source_handler.cc \
 	content/renderer/media/webaudio_capturer_source.cc \
 	content/renderer/media/webrtc/webrtc_video_track_adapter.cc \
@@ -282,7 +283,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -334,11 +334,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -461,7 +456,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -513,11 +507,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/content/content_resources.target.darwin-arm.mk b/content/content_resources.target.darwin-arm.mk
index 6a55087..3161d81 100644
--- a/content/content_resources.target.darwin-arm.mk
+++ b/content/content_resources.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_content_resources":
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_resources.target.darwin-arm64.mk b/content/content_resources.target.darwin-arm64.mk
index 6a55087..3161d81 100644
--- a/content/content_resources.target.darwin-arm64.mk
+++ b/content/content_resources.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_content_resources":
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_resources.target.darwin-mips.mk b/content/content_resources.target.darwin-mips.mk
index 6a55087..3161d81 100644
--- a/content/content_resources.target.darwin-mips.mk
+++ b/content/content_resources.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_content_resources":
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_resources.target.darwin-x86.mk b/content/content_resources.target.darwin-x86.mk
index 6a55087..3161d81 100644
--- a/content/content_resources.target.darwin-x86.mk
+++ b/content/content_resources.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_content_resources":
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_resources.target.darwin-x86_64.mk b/content/content_resources.target.darwin-x86_64.mk
index 6a55087..3161d81 100644
--- a/content/content_resources.target.darwin-x86_64.mk
+++ b/content/content_resources.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_content_resources":
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_resources.target.linux-arm.mk b/content/content_resources.target.linux-arm.mk
index 6a55087..3161d81 100644
--- a/content/content_resources.target.linux-arm.mk
+++ b/content/content_resources.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_content_resources":
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_resources.target.linux-arm64.mk b/content/content_resources.target.linux-arm64.mk
index 6a55087..3161d81 100644
--- a/content/content_resources.target.linux-arm64.mk
+++ b/content/content_resources.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_content_resources":
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_resources.target.linux-mips.mk b/content/content_resources.target.linux-mips.mk
index 6a55087..3161d81 100644
--- a/content/content_resources.target.linux-mips.mk
+++ b/content/content_resources.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_content_resources":
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_resources.target.linux-x86.mk b/content/content_resources.target.linux-x86.mk
index 6a55087..3161d81 100644
--- a/content/content_resources.target.linux-x86.mk
+++ b/content/content_resources.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_content_resources":
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_resources.target.linux-x86_64.mk b/content/content_resources.target.linux-x86_64.mk
index 6a55087..3161d81 100644
--- a/content/content_resources.target.linux-x86_64.mk
+++ b/content/content_resources.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_content_resources":
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/grit/content_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/content_shell.gypi b/content/content_shell.gypi
index 2d53996..3b14649 100644
--- a/content/content_shell.gypi
+++ b/content/content_shell.gypi
@@ -193,8 +193,6 @@
         'shell/renderer/test_runner/MockWebRTCDataChannelHandler.h',
         'shell/renderer/test_runner/MockWebRTCPeerConnectionHandler.cpp',
         'shell/renderer/test_runner/MockWebRTCPeerConnectionHandler.h',
-        'shell/renderer/test_runner/MockWebSpeechInputController.cpp',
-        'shell/renderer/test_runner/MockWebSpeechInputController.h',
         'shell/renderer/test_runner/MockWebSpeechRecognizer.cpp',
         'shell/renderer/test_runner/MockWebSpeechRecognizer.h',
         'shell/renderer/test_runner/SpellCheckClient.cpp',
@@ -301,8 +299,7 @@
             '../components/components.gyp:breakpad_host',
           ],
         }],
-        # TODO(dmikurube): Kill {linux|android}_use_tcmalloc. http://crbug.com/345554
-        ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and ((OS=="linux" and linux_use_tcmalloc==1) or (OS=="android" and android_use_tcmalloc==1)))', {
+        ['(OS=="linux" or OS=="android") and use_allocator!="none"', {
           'dependencies': [
             # This is needed by content/app/content_main_runner.cc
             '../base/allocator/allocator.gyp:allocator',
@@ -639,23 +636,7 @@
         'content_shell',
       ],
     },
-    {
-      'target_name': 'layout_test_helper',
-      'type': 'executable',
-      'sources': [
-        'shell/renderer/test_runner/helper/layout_test_helper_mac.mm',
-        'shell/renderer/test_runner/helper/layout_test_helper_win.cc',
-      ],
-      'conditions': [
-        ['OS=="mac"', {
-          'link_settings': {
-            'libraries': [
-              '$(SDKROOT)/System/Library/Frameworks/AppKit.framework',
-            ],
-          },
-        }],
-      ],
-    },
+
     {
       'target_name': 'test_netscape_plugin',
       'type': 'loadable_module',
@@ -761,6 +742,27 @@
     }
   ],
   'conditions': [
+    ['OS=="mac" or OS=="win"', {
+      'targets': [
+        {
+          'target_name': 'layout_test_helper',
+          'type': 'executable',
+          'sources': [
+            'shell/renderer/test_runner/helper/layout_test_helper_mac.mm',
+            'shell/renderer/test_runner/helper/layout_test_helper_win.cc',
+          ],
+          'conditions': [
+            ['OS=="mac"', {
+              'link_settings': {
+                'libraries': [
+                  '$(SDKROOT)/System/Library/Frameworks/AppKit.framework',
+                ],
+              },
+            }],
+          ],
+        },
+      ],
+    }],  # OS=="mac" or OS=="win"
     ['OS=="mac"', {
       'targets': [
         {
@@ -1073,7 +1075,7 @@
         },
       ],
     }],  # OS=="win"
-    ['OS=="win" and fastbuild==0 and target_arch=="ia32"', {
+    ['OS=="win" and fastbuild==0 and target_arch=="ia32" and syzyasan==1', {
       'variables': {
         'dest_dir': '<(PRODUCT_DIR)/syzygy',
       },
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index e9972dd..ccf43f0 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -50,9 +50,11 @@
         '../testing/gtest.gyp:gtest',
         '../ui/accessibility/accessibility.gyp:ax_gen',
         '../ui/base/ui_base.gyp:ui_base',
+        '../ui/base/ui_base.gyp:ui_base_test_support',
         '../ui/events/events.gyp:dom4_keycode_converter',
         '../ui/events/events.gyp:events_base',
         '../ui/events/events.gyp:events_test_support',
+        '../ui/events/events.gyp:gesture_detection',
         '../ui/gfx/gfx.gyp:gfx',
         '../ui/gfx/gfx.gyp:gfx_geometry',
         '../ui/gfx/gfx.gyp:gfx_test_support',
@@ -161,6 +163,8 @@
         'test/content_browser_test_utils_internal.h',
         'test/content_test_suite.cc',
         'test/content_test_suite.h',
+        'test/frame_load_waiter.cc',
+        'test/frame_load_waiter.h',
         'test/mock_google_streaming_server.cc',
         'test/mock_google_streaming_server.h',
         'test/mock_keyboard.cc',
@@ -200,8 +204,6 @@
         'test/test_render_view_host_factory.h',
         'test/test_web_contents.cc',
         'test/test_web_contents.h',
-        'test/test_web_contents_view.cc',
-        'test/test_web_contents_view.h',
         'test/web_gesture_curve_mock.cc',
         'test/web_gesture_curve_mock.h',
         'test/weburl_loader_mock.cc',
@@ -396,9 +398,9 @@
         'browser/database_tracker_unittest.cc',
         'browser/device_sensors/data_fetcher_shared_memory_base_unittest.cc',
         'browser/device_sensors/sensor_manager_android_unittest.cc',
+        'browser/devtools/embedded_worker_devtools_manager_unittest.cc',
         'browser/devtools/devtools_http_handler_unittest.cc',
         'browser/devtools/devtools_manager_unittest.cc',
-        'browser/devtools/shared_worker_devtools_manager_unittest.cc',
         'browser/dom_storage/dom_storage_area_unittest.cc',
         'browser/dom_storage/dom_storage_context_impl_unittest.cc',
         'browser/dom_storage/dom_storage_database_unittest.cc',
@@ -437,6 +439,8 @@
         'browser/fileapi/obfuscated_file_util_unittest.cc',
         'browser/fileapi/plugin_private_file_system_backend_unittest.cc',
         'browser/fileapi/recursive_operation_delegate_unittest.cc',
+        'browser/fileapi/sandbox_database_test_helper.cc',
+        'browser/fileapi/sandbox_database_test_helper.h',
         'browser/fileapi/sandbox_directory_database_unittest.cc',
         'browser/fileapi/sandbox_file_system_backend_delegate_unittest.cc',
         'browser/fileapi/sandbox_file_system_backend_unittest.cc',
@@ -680,8 +684,6 @@
         '../webkit/browser/database/database_quota_client_unittest.cc',
         '../webkit/browser/database/database_util_unittest.cc',
         '../webkit/browser/database/databases_table_unittest.cc',
-        '../webkit/browser/fileapi/sandbox_database_test_helper.cc',
-        '../webkit/browser/fileapi/sandbox_database_test_helper.h',
         '../webkit/child/multipart_response_delegate_unittest.cc',
       ],
       'conditions': [
@@ -1066,6 +1068,8 @@
             'browser/browser_plugin/test_browser_plugin_guest_delegate.h',
             'browser/browser_plugin/test_browser_plugin_guest_manager.cc',
             'browser/browser_plugin/test_browser_plugin_guest_manager.h',
+            'browser/browser_plugin/test_guest_manager_delegate.cc',
+            'browser/browser_plugin/test_guest_manager_delegate.h',
             'browser/child_process_security_policy_browsertest.cc',
             'browser/cross_site_transfer_browsertest.cc',
             'browser/database_browsertest.cc',
@@ -1103,7 +1107,6 @@
             'browser/service_worker/service_worker_browsertest.cc',
             'browser/session_history_browsertest.cc',
             'browser/site_per_process_browsertest.cc',
-            'browser/speech/input_tag_speech_browsertest.cc',
             'browser/speech/speech_recognition_browsertest.cc',
             'browser/tracing/tracing_controller_browsertest.cc',
             'browser/web_contents/opened_by_dom_browsertest.cc',
@@ -1410,10 +1413,9 @@
                   '<(angle_path)/src/build_angle.gyp:libGLESv2',
                 ],
               }],
-              # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
               ['(OS=="win" and win_use_allocator_shim==1) or '
                '(os_posix == 1 and OS != "android" and '
-               ' ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)))', {
+               ' use_allocator!="none")', {
                 'dependencies': [
                   '../base/allocator/allocator.gyp:allocator',
                 ],
diff --git a/content/content_utility.target.darwin-arm.mk b/content/content_utility.target.darwin-arm.mk
index c27157b..4e731e8 100644
--- a/content/content_utility.target.darwin-arm.mk
+++ b/content/content_utility.target.darwin-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -142,7 +141,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/content_utility.target.darwin-x86.mk b/content/content_utility.target.darwin-x86.mk
index 636cc50..ff69d87 100644
--- a/content/content_utility.target.darwin-x86.mk
+++ b/content/content_utility.target.darwin-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_utility.target.darwin-x86_64.mk b/content/content_utility.target.darwin-x86_64.mk
index 892a3c3..5cabe8d 100644
--- a/content/content_utility.target.darwin-x86_64.mk
+++ b/content/content_utility.target.darwin-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_utility.target.linux-arm.mk b/content/content_utility.target.linux-arm.mk
index c27157b..4e731e8 100644
--- a/content/content_utility.target.linux-arm.mk
+++ b/content/content_utility.target.linux-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -142,7 +141,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/content_utility.target.linux-x86.mk b/content/content_utility.target.linux-x86.mk
index 636cc50..ff69d87 100644
--- a/content/content_utility.target.linux-x86.mk
+++ b/content/content_utility.target.linux-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/content_utility.target.linux-x86_64.mk b/content/content_utility.target.linux-x86_64.mk
index 892a3c3..5cabe8d 100644
--- a/content/content_utility.target.linux-x86_64.mk
+++ b/content/content_utility.target.linux-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/gesture_event_type_java.target.darwin-arm.mk b/content/gesture_event_type_java.target.darwin-arm.mk
index e76964d..b581a7e 100644
--- a/content/gesture_event_type_java.target.darwin-arm.mk
+++ b/content/gesture_event_type_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_gesture_event_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/gesture_event_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/GestureEventType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/gesture_event_type_java.target.darwin-arm64.mk b/content/gesture_event_type_java.target.darwin-arm64.mk
index 65cad10..2c2735e 100644
--- a/content/gesture_event_type_java.target.darwin-arm64.mk
+++ b/content/gesture_event_type_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_gesture_event_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/gesture_event_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/GestureEventType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/gesture_event_type_java.target.darwin-mips.mk b/content/gesture_event_type_java.target.darwin-mips.mk
index 3c5db35..71b5c82 100644
--- a/content/gesture_event_type_java.target.darwin-mips.mk
+++ b/content/gesture_event_type_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_gesture_event_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/gesture_event_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/GestureEventType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/gesture_event_type_java.target.darwin-x86.mk b/content/gesture_event_type_java.target.darwin-x86.mk
index 147c35e..384b329 100644
--- a/content/gesture_event_type_java.target.darwin-x86.mk
+++ b/content/gesture_event_type_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_gesture_event_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/gesture_event_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/GestureEventType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/gesture_event_type_java.target.darwin-x86_64.mk b/content/gesture_event_type_java.target.darwin-x86_64.mk
index 29c613e..566c63a 100644
--- a/content/gesture_event_type_java.target.darwin-x86_64.mk
+++ b/content/gesture_event_type_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_gesture_event_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/gesture_event_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/GestureEventType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/gesture_event_type_java.target.linux-arm.mk b/content/gesture_event_type_java.target.linux-arm.mk
index e76964d..b581a7e 100644
--- a/content/gesture_event_type_java.target.linux-arm.mk
+++ b/content/gesture_event_type_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_gesture_event_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/gesture_event_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/GestureEventType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/gesture_event_type_java.target.linux-arm64.mk b/content/gesture_event_type_java.target.linux-arm64.mk
index 65cad10..2c2735e 100644
--- a/content/gesture_event_type_java.target.linux-arm64.mk
+++ b/content/gesture_event_type_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_gesture_event_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/gesture_event_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/GestureEventType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/gesture_event_type_java.target.linux-mips.mk b/content/gesture_event_type_java.target.linux-mips.mk
index 3c5db35..71b5c82 100644
--- a/content/gesture_event_type_java.target.linux-mips.mk
+++ b/content/gesture_event_type_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_gesture_event_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/gesture_event_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/GestureEventType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/gesture_event_type_java.target.linux-x86.mk b/content/gesture_event_type_java.target.linux-x86.mk
index 147c35e..384b329 100644
--- a/content/gesture_event_type_java.target.linux-x86.mk
+++ b/content/gesture_event_type_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_gesture_event_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/gesture_event_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/GestureEventType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/gesture_event_type_java.target.linux-x86_64.mk b/content/gesture_event_type_java.target.linux-x86_64.mk
index 29c613e..566c63a 100644
--- a/content/gesture_event_type_java.target.linux-x86_64.mk
+++ b/content/gesture_event_type_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_gesture_event_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/gesture_event_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/GestureEventType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/GestureEventType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/java_set_jni_headers.target.darwin-arm.mk b/content/java_set_jni_headers.target.darwin-arm.mk
index 8c6a0b2..72bd9b9 100644
--- a/content/java_set_jni_headers.target.darwin-arm.mk
+++ b/content/java_set_jni_headers.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/java_set_jni_headers.target.darwin-arm64.mk b/content/java_set_jni_headers.target.darwin-arm64.mk
index 3cf247b..9fb9092 100644
--- a/content/java_set_jni_headers.target.darwin-arm64.mk
+++ b/content/java_set_jni_headers.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/java_set_jni_headers.target.darwin-mips.mk b/content/java_set_jni_headers.target.darwin-mips.mk
index ad36454..fd8bdd2 100644
--- a/content/java_set_jni_headers.target.darwin-mips.mk
+++ b/content/java_set_jni_headers.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/java_set_jni_headers.target.darwin-x86.mk b/content/java_set_jni_headers.target.darwin-x86.mk
index 9c5560d..705d954 100644
--- a/content/java_set_jni_headers.target.darwin-x86.mk
+++ b/content/java_set_jni_headers.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/java_set_jni_headers.target.darwin-x86_64.mk b/content/java_set_jni_headers.target.darwin-x86_64.mk
index db76835..01ed935 100644
--- a/content/java_set_jni_headers.target.darwin-x86_64.mk
+++ b/content/java_set_jni_headers.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/java_set_jni_headers.target.linux-arm.mk b/content/java_set_jni_headers.target.linux-arm.mk
index 8c6a0b2..72bd9b9 100644
--- a/content/java_set_jni_headers.target.linux-arm.mk
+++ b/content/java_set_jni_headers.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/java_set_jni_headers.target.linux-arm64.mk b/content/java_set_jni_headers.target.linux-arm64.mk
index 3cf247b..9fb9092 100644
--- a/content/java_set_jni_headers.target.linux-arm64.mk
+++ b/content/java_set_jni_headers.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/java_set_jni_headers.target.linux-mips.mk b/content/java_set_jni_headers.target.linux-mips.mk
index ad36454..fd8bdd2 100644
--- a/content/java_set_jni_headers.target.linux-mips.mk
+++ b/content/java_set_jni_headers.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/java_set_jni_headers.target.linux-x86.mk b/content/java_set_jni_headers.target.linux-x86.mk
index 9c5560d..705d954 100644
--- a/content/java_set_jni_headers.target.linux-x86.mk
+++ b/content/java_set_jni_headers.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/java_set_jni_headers.target.linux-x86_64.mk b/content/java_set_jni_headers.target.linux-x86_64.mk
index db76835..01ed935 100644
--- a/content/java_set_jni_headers.target.linux-x86_64.mk
+++ b/content/java_set_jni_headers.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/HashSet_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/motionevent_jni_headers.target.darwin-arm.mk b/content/motionevent_jni_headers.target.darwin-arm.mk
index 29051ba..c81f198 100644
--- a/content/motionevent_jni_headers.target.darwin-arm.mk
+++ b/content/motionevent_jni_headers.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/motionevent_jni_headers.target.darwin-arm64.mk b/content/motionevent_jni_headers.target.darwin-arm64.mk
index 1c56a76..0059f2b 100644
--- a/content/motionevent_jni_headers.target.darwin-arm64.mk
+++ b/content/motionevent_jni_headers.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/motionevent_jni_headers.target.darwin-mips.mk b/content/motionevent_jni_headers.target.darwin-mips.mk
index 835de29..7590a89 100644
--- a/content/motionevent_jni_headers.target.darwin-mips.mk
+++ b/content/motionevent_jni_headers.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/motionevent_jni_headers.target.darwin-x86.mk b/content/motionevent_jni_headers.target.darwin-x86.mk
index 53a3740..05bd214 100644
--- a/content/motionevent_jni_headers.target.darwin-x86.mk
+++ b/content/motionevent_jni_headers.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/motionevent_jni_headers.target.darwin-x86_64.mk b/content/motionevent_jni_headers.target.darwin-x86_64.mk
index dc66874..5612f29 100644
--- a/content/motionevent_jni_headers.target.darwin-x86_64.mk
+++ b/content/motionevent_jni_headers.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/motionevent_jni_headers.target.linux-arm.mk b/content/motionevent_jni_headers.target.linux-arm.mk
index 29051ba..c81f198 100644
--- a/content/motionevent_jni_headers.target.linux-arm.mk
+++ b/content/motionevent_jni_headers.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/motionevent_jni_headers.target.linux-arm64.mk b/content/motionevent_jni_headers.target.linux-arm64.mk
index 1c56a76..0059f2b 100644
--- a/content/motionevent_jni_headers.target.linux-arm64.mk
+++ b/content/motionevent_jni_headers.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/motionevent_jni_headers.target.linux-mips.mk b/content/motionevent_jni_headers.target.linux-mips.mk
index 835de29..7590a89 100644
--- a/content/motionevent_jni_headers.target.linux-mips.mk
+++ b/content/motionevent_jni_headers.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/motionevent_jni_headers.target.linux-x86.mk b/content/motionevent_jni_headers.target.linux-x86.mk
index 53a3740..05bd214 100644
--- a/content/motionevent_jni_headers.target.linux-x86.mk
+++ b/content/motionevent_jni_headers.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/motionevent_jni_headers.target.linux-x86_64.mk b/content/motionevent_jni_headers.target.linux-x86_64.mk
index dc66874..5612f29 100644
--- a/content/motionevent_jni_headers.target.linux-x86_64.mk
+++ b/content/motionevent_jni_headers.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/content/jni/MotionEvent_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/page_transition_types_java.target.darwin-arm.mk b/content/page_transition_types_java.target.darwin-arm.mk
index 0517679..71a35ee 100644
--- a/content/page_transition_types_java.target.darwin-arm.mk
+++ b/content/page_transition_types_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/page_transition_types_java.target.darwin-arm64.mk b/content/page_transition_types_java.target.darwin-arm64.mk
index 46de31c..6a1d741 100644
--- a/content/page_transition_types_java.target.darwin-arm64.mk
+++ b/content/page_transition_types_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/page_transition_types_java.target.darwin-mips.mk b/content/page_transition_types_java.target.darwin-mips.mk
index a6a78ae..17090de 100644
--- a/content/page_transition_types_java.target.darwin-mips.mk
+++ b/content/page_transition_types_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/page_transition_types_java.target.darwin-x86.mk b/content/page_transition_types_java.target.darwin-x86.mk
index 6107ab6..f754f8a 100644
--- a/content/page_transition_types_java.target.darwin-x86.mk
+++ b/content/page_transition_types_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/page_transition_types_java.target.darwin-x86_64.mk b/content/page_transition_types_java.target.darwin-x86_64.mk
index 23d4704..199a32e 100644
--- a/content/page_transition_types_java.target.darwin-x86_64.mk
+++ b/content/page_transition_types_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/page_transition_types_java.target.linux-arm.mk b/content/page_transition_types_java.target.linux-arm.mk
index 0517679..71a35ee 100644
--- a/content/page_transition_types_java.target.linux-arm.mk
+++ b/content/page_transition_types_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/page_transition_types_java.target.linux-arm64.mk b/content/page_transition_types_java.target.linux-arm64.mk
index 46de31c..6a1d741 100644
--- a/content/page_transition_types_java.target.linux-arm64.mk
+++ b/content/page_transition_types_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/page_transition_types_java.target.linux-mips.mk b/content/page_transition_types_java.target.linux-mips.mk
index a6a78ae..17090de 100644
--- a/content/page_transition_types_java.target.linux-mips.mk
+++ b/content/page_transition_types_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/page_transition_types_java.target.linux-x86.mk b/content/page_transition_types_java.target.linux-x86.mk
index 6107ab6..f754f8a 100644
--- a/content/page_transition_types_java.target.linux-x86.mk
+++ b/content/page_transition_types_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/page_transition_types_java.target.linux-x86_64.mk b/content/page_transition_types_java.target.linux-x86_64.mk
index 23d4704..199a32e 100644
--- a/content/page_transition_types_java.target.linux-x86_64.mk
+++ b/content/page_transition_types_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_page_transition_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/page_transition_types_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/PageTransitionTypes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/PageTransitionTypes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/plugin/webplugin_proxy.cc b/content/plugin/webplugin_proxy.cc
index 73d527b..8a035d5 100644
--- a/content/plugin/webplugin_proxy.cc
+++ b/content/plugin/webplugin_proxy.cc
@@ -288,8 +288,8 @@
     if (delegate_->GetQuirks() &
         WebPluginDelegateImpl::PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS) {
       GURL request_url(url);
-      if (!request_url.SchemeIs(kHttpScheme) &&
-          !request_url.SchemeIs(kHttpsScheme) &&
+      if (!request_url.SchemeIs(url::kHttpScheme) &&
+          !request_url.SchemeIs(url::kHttpsScheme) &&
           !request_url.SchemeIs(kFtpScheme)) {
         return;
       }
diff --git a/content/popup_item_type_java.target.darwin-arm.mk b/content/popup_item_type_java.target.darwin-arm.mk
index 7f1ba8b..860c193 100644
--- a/content/popup_item_type_java.target.darwin-arm.mk
+++ b/content/popup_item_type_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_popup_item_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/popup_item_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/input/PopupItemType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/popup_item_type_java.target.darwin-arm64.mk b/content/popup_item_type_java.target.darwin-arm64.mk
index a6b7f20..98d7ec7 100644
--- a/content/popup_item_type_java.target.darwin-arm64.mk
+++ b/content/popup_item_type_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_popup_item_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/popup_item_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/input/PopupItemType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/popup_item_type_java.target.darwin-mips.mk b/content/popup_item_type_java.target.darwin-mips.mk
index 4bf782e..f901d1a 100644
--- a/content/popup_item_type_java.target.darwin-mips.mk
+++ b/content/popup_item_type_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_popup_item_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/popup_item_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/input/PopupItemType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/popup_item_type_java.target.darwin-x86.mk b/content/popup_item_type_java.target.darwin-x86.mk
index 1e03de5..a8556f5 100644
--- a/content/popup_item_type_java.target.darwin-x86.mk
+++ b/content/popup_item_type_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_popup_item_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/popup_item_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/input/PopupItemType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/popup_item_type_java.target.darwin-x86_64.mk b/content/popup_item_type_java.target.darwin-x86_64.mk
index 03e0a9c..17d1cfb 100644
--- a/content/popup_item_type_java.target.darwin-x86_64.mk
+++ b/content/popup_item_type_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_popup_item_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/popup_item_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/input/PopupItemType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/popup_item_type_java.target.linux-arm.mk b/content/popup_item_type_java.target.linux-arm.mk
index 7f1ba8b..860c193 100644
--- a/content/popup_item_type_java.target.linux-arm.mk
+++ b/content/popup_item_type_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_popup_item_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/popup_item_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/input/PopupItemType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/popup_item_type_java.target.linux-arm64.mk b/content/popup_item_type_java.target.linux-arm64.mk
index a6b7f20..98d7ec7 100644
--- a/content/popup_item_type_java.target.linux-arm64.mk
+++ b/content/popup_item_type_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_popup_item_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/popup_item_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/input/PopupItemType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/popup_item_type_java.target.linux-mips.mk b/content/popup_item_type_java.target.linux-mips.mk
index 4bf782e..f901d1a 100644
--- a/content/popup_item_type_java.target.linux-mips.mk
+++ b/content/popup_item_type_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_popup_item_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/popup_item_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/input/PopupItemType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/popup_item_type_java.target.linux-x86.mk b/content/popup_item_type_java.target.linux-x86.mk
index 1e03de5..a8556f5 100644
--- a/content/popup_item_type_java.target.linux-x86.mk
+++ b/content/popup_item_type_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_popup_item_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/popup_item_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/input/PopupItemType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/popup_item_type_java.target.linux-x86_64.mk b/content/popup_item_type_java.target.linux-x86_64.mk
index 03e0a9c..17d1cfb 100644
--- a/content/popup_item_type_java.target.linux-x86_64.mk
+++ b/content/popup_item_type_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_popup_item_type_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'browser/android/popup_item_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/input/PopupItemType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/input/PopupItemType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/port/browser/DEPS b/content/port/browser/DEPS
deleted file mode 100644
index 9db1804..0000000
--- a/content/port/browser/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-  "+content/public/browser"
-]
diff --git a/content/port/browser/event_with_latency_info.h b/content/port/browser/event_with_latency_info.h
deleted file mode 100644
index c0da186..0000000
--- a/content/port/browser/event_with_latency_info.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CONTENT_PORT_BROWSER_EVENT_WITH_LATENCY_INFO_H_
-#define CONTENT_PORT_BROWSER_EVENT_WITH_LATENCY_INFO_H_
-
-#include "ui/events/latency_info.h"
-
-#include "content/common/input/web_input_event_traits.h"
-
-namespace blink {
-class WebGestureEvent;
-class WebMouseEvent;
-class WebMouseWheelEvent;
-class WebTouchEvent;
-}
-
-namespace content {
-
-template <typename T>
-class EventWithLatencyInfo {
- public:
-  T event;
-  ui::LatencyInfo latency;
-
-  EventWithLatencyInfo(const T& e, const ui::LatencyInfo& l)
-      : event(e), latency(l) {}
-
-  EventWithLatencyInfo() {}
-
-  bool CanCoalesceWith(const EventWithLatencyInfo& other)
-      const WARN_UNUSED_RESULT {
-    return WebInputEventTraits::CanCoalesce(other.event, event);
-  }
-
-  void CoalesceWith(const EventWithLatencyInfo& other) {
-    WebInputEventTraits::Coalesce(other.event, &event);
-    // When coalescing two input events, we keep the oldest LatencyInfo
-    // for Telemetry latency test since it will represent the longest
-    // latency.
-    if (other.latency.trace_id >= 0 &&
-        (latency.trace_id < 0 || other.latency.trace_id < latency.trace_id))
-      latency = other.latency;
-  }
-};
-
-typedef EventWithLatencyInfo<blink::WebGestureEvent>
-    GestureEventWithLatencyInfo;
-typedef EventWithLatencyInfo<blink::WebMouseWheelEvent>
-    MouseWheelEventWithLatencyInfo;
-typedef EventWithLatencyInfo<blink::WebMouseEvent>
-    MouseEventWithLatencyInfo;
-typedef EventWithLatencyInfo<blink::WebTouchEvent>
-    TouchEventWithLatencyInfo;
-
-}  // namespace content
-
-#endif  // CONTENT_PORT_BROWSER_EVENT_WITH_LATENCY_INFO_H_
diff --git a/content/port/browser/location_provider.h b/content/port/browser/location_provider.h
deleted file mode 100644
index 0dc61ef..0000000
--- a/content/port/browser/location_provider.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2013 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.
-
-#ifndef CONTENT_PORT_BROWSER_LOCATION_PROVIDER_H_
-#define CONTENT_PORT_BROWSER_LOCATION_PROVIDER_H_
-
-#include "base/callback.h"
-#include "base/compiler_specific.h"
-#include "content/public/common/geoposition.h"
-
-namespace content {
-
-class LocationProvider;
-
-// The interface for providing location information.
-class LocationProvider {
- public:
-  virtual ~LocationProvider() {}
-
-  typedef base::Callback<void(const LocationProvider*, const Geoposition&)>
-      LocationProviderUpdateCallback;
-
-  // This callback will be used to notify when a new Geoposition becomes
-  // available.
-  virtual void SetUpdateCallback(
-      const LocationProviderUpdateCallback& callback) = 0;
-
-  // StartProvider maybe called multiple times, e.g. to alter the
-  // |high_accuracy| setting. Returns false if a fatal error was encountered
-  // which prevented the provider from starting.
-  virtual bool StartProvider(bool high_accuracy) = 0;
-
-  // Stops the provider from sending more requests.
-  // Important: a LocationProvider may be instantiated and StartProvider() may
-  // be called before the user has granted permission via OnPermissionGranted().
-  // This is to allow underlying providers to warm up, load their internal
-  // libraries, etc. No |LocationProviderUpdateCallback| can be run and no
-  // network requests can be done until OnPermissionGranted() has been called.
-  virtual void StopProvider() = 0;
-
-  // Gets the current best position estimate.
-  virtual void GetPosition(Geoposition* position) = 0;
-
-  // Provides a hint to the provider that new location data is needed as soon
-  // as possible.
-  virtual void RequestRefresh() = 0;
-
-  // Called everytime permission is granted to a page for using geolocation.
-  // This may either be through explicit user action (e.g. responding to the
-  // infobar prompt) or inferred from a persisted site permission.
-  // Note: See |StartProvider()| for more information.
-  virtual void OnPermissionGranted() = 0;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PORT_BROWSER_LOCATION_PROVIDER_H_
diff --git a/content/port/browser/render_view_host_delegate_view.h b/content/port/browser/render_view_host_delegate_view.h
deleted file mode 100644
index e7af7c9..0000000
--- a/content/port/browser/render_view_host_delegate_view.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CONTENT_PORT_BROWSER_RENDER_VIEW_HOST_DELEGATE_VIEW_H_
-#define CONTENT_PORT_BROWSER_RENDER_VIEW_HOST_DELEGATE_VIEW_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "content/common/content_export.h"
-#include "content/common/drag_event_source_info.h"
-#include "third_party/WebKit/public/web/WebDragOperation.h"
-
-class SkBitmap;
-
-namespace gfx {
-class ImageSkia;
-class Rect;
-class Vector2d;
-}
-
-namespace content {
-class RenderFrameHost;
-struct ContextMenuParams;
-struct DropData;
-struct MenuItem;
-
-// This class provides a way for the RenderViewHost to reach out to its
-// delegate's view. It only needs to be implemented by embedders if they don't
-// use the default WebContentsView implementations.
-class CONTENT_EXPORT RenderViewHostDelegateView {
- public:
-  // A context menu should be shown, to be built using the context information
-  // provided in the supplied params.
-  virtual void ShowContextMenu(RenderFrameHost* render_frame_host,
-                               const ContextMenuParams& params) {}
-
-  // Shows a popup menu with the specified items.
-  // This method should call RenderViewHost::DidSelectPopupMenuItem[s]() or
-  // RenderViewHost::DidCancelPopupMenu() based on the user action.
-  virtual void ShowPopupMenu(const gfx::Rect& bounds,
-                             int item_height,
-                             double item_font_size,
-                             int selected_item,
-                             const std::vector<MenuItem>& items,
-                             bool right_aligned,
-                             bool allow_multiple_selection) {};
-
-  // Hides a popup menu opened by ShowPopupMenu().
-  virtual void HidePopupMenu() {};
-
-  // The user started dragging content of the specified type within the
-  // RenderView. Contextual information about the dragged content is supplied
-  // by DropData. If the delegate's view cannot start the drag for /any/
-  // reason, it must inform the renderer that the drag has ended; otherwise,
-  // this results in bugs like http://crbug.com/157134.
-  virtual void StartDragging(const DropData& drop_data,
-                             blink::WebDragOperationsMask allowed_ops,
-                             const gfx::ImageSkia& image,
-                             const gfx::Vector2d& image_offset,
-                             const DragEventSourceInfo& event_info) {}
-
-  // The page wants to update the mouse cursor during a drag & drop operation.
-  // |operation| describes the current operation (none, move, copy, link.)
-  virtual void UpdateDragCursor(blink::WebDragOperation operation) {}
-
-  // Notification that view for this delegate got the focus.
-  virtual void GotFocus() {}
-
-  // Callback to inform the browser that the page is returning the focus to
-  // the browser's chrome. If reverse is true, it means the focus was
-  // retrieved by doing a Shift-Tab.
-  virtual void TakeFocus(bool reverse) {}
-
- protected:
-  virtual ~RenderViewHostDelegateView() {}
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PORT_BROWSER_RENDER_VIEW_HOST_DELEGATE_VIEW_H_
diff --git a/content/port/browser/render_widget_host_view_frame_subscriber.h b/content/port/browser/render_widget_host_view_frame_subscriber.h
deleted file mode 100644
index 76fd4b1..0000000
--- a/content/port/browser/render_widget_host_view_frame_subscriber.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CONTENT_PORT_BROWSER_RENDER_WIDGET_HOST_VIEW_FRAME_SUBSCRIBER_H_
-#define CONTENT_PORT_BROWSER_RENDER_WIDGET_HOST_VIEW_FRAME_SUBSCRIBER_H_
-
-#include "base/callback.h"
-#include "base/time/time.h"
-
-namespace gfx {
-class Rect;
-class Size;
-}  // namespace gfx
-
-namespace media {
-class VideoFrame;
-}  // namespace media
-
-namespace content {
-
-// Defines an interface for listening to events of frame presentation and to
-// instruct the platform layer (i.e. RenderWidgetHostViewPort) to copy a frame.
-//
-// Further processing is possible (e.g. scale and color space conversion)
-// through this interface. See ShouldCaptureFrame() for details.
-//
-// It is platform dependent which thread this object lives on, but it is
-// guaranteed to be used on a single thread.
-class RenderWidgetHostViewFrameSubscriber {
- public:
-  virtual ~RenderWidgetHostViewFrameSubscriber() {}
-
-  // Called when a captured frame is available or the frame is no longer
-  // needed by the platform layer.
-  //
-  // If |frame_captured| is true then frame provided contains valid content and
-  // |timestamp| is the time when the frame was painted.
-  //
-  // If |frame_captured| is false then the content in frame provided is
-  // invalid. There was an error during the process of frame capture or the
-  // platform layer is shutting down. |timestamp| is also invalid in this case.
-  typedef base::Callback<void(base::TimeTicks /* timestamp */,
-                              bool /* frame_captured */)> DeliverFrameCallback;
-
-  // Called when a new frame is going to be presented at time
-  // |present_time|. Implementation can decide whether the current frame should
-  // be captured or not.
-  //
-  // Return true if the current frame should be captured. If so, |storage|
-  // should will be set to hold an appropriately sized and allocated buffer
-  // into which to copy the frame. The platform presenter will perform scaling
-  // and color space conversion to fit into the output frame.
-  //
-  // Destination format is determined by |storage|, currently only
-  // media::VideoFrame::YV12 is supported. Platform layer will perform color
-  // space conversion if needed.
-  //
-  // When the frame is available |callback| will be called. It is up to the
-  // platform layer to decide when to deliver a captured frame.
-  //
-  // Return false if the current frame should not be captured.
-  virtual bool ShouldCaptureFrame(base::TimeTicks present_time,
-                                  scoped_refptr<media::VideoFrame>* storage,
-                                  DeliverFrameCallback* callback) = 0;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PORT_BROWSER_RENDER_WIDGET_HOST_VIEW_FRAME_SUBSCRIBER_H_
diff --git a/content/port/browser/render_widget_host_view_port.h b/content/port/browser/render_widget_host_view_port.h
deleted file mode 100644
index c35777b..0000000
--- a/content/port/browser/render_widget_host_view_port.h
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CONTENT_PORT_BROWSER_RENDER_WIDGET_HOST_VIEW_PORT_H_
-#define CONTENT_PORT_BROWSER_RENDER_WIDGET_HOST_VIEW_PORT_H_
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/process/kill.h"
-#include "base/strings/string16.h"
-#include "cc/output/compositor_frame.h"
-#include "content/common/content_export.h"
-#include "content/port/browser/event_with_latency_info.h"
-#include "content/port/common/input_event_ack_state.h"
-#include "content/public/browser/render_widget_host_view.h"
-#include "ipc/ipc_listener.h"
-#include "third_party/WebKit/public/web/WebPopupType.h"
-#include "third_party/WebKit/public/web/WebTextDirection.h"
-#include "ui/base/ime/text_input_mode.h"
-#include "ui/base/ime/text_input_type.h"
-#include "ui/gfx/range/range.h"
-#include "ui/surface/transport_dib.h"
-
-class SkBitmap;
-
-struct AccessibilityHostMsg_EventParams;
-struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params;
-struct GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params;
-struct ViewHostMsg_TextInputState_Params;
-struct ViewHostMsg_SelectionBounds_Params;
-
-namespace media {
-class VideoFrame;
-}
-
-namespace blink {
-struct WebScreenInfo;
-}
-
-namespace content {
-class RenderWidgetHostViewFrameSubscriber;
-class SyntheticGesture;
-class SyntheticGestureTarget;
-class WebCursor;
-struct WebPluginGeometry;
-struct NativeWebKeyboardEvent;
-
-// This is the larger RenderWidgetHostView interface exposed only
-// within content/ and to embedders looking to port to new platforms.
-// RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
-class CONTENT_EXPORT RenderWidgetHostViewPort : public RenderWidgetHostView,
-                                                public IPC::Listener {
- public:
-  virtual ~RenderWidgetHostViewPort() {}
-
-  // Does the cast for you.
-  static RenderWidgetHostViewPort* FromRWHV(RenderWidgetHostView* rwhv);
-
-  // Like RenderWidgetHostView::CreateViewForWidget, with cast.
-  static RenderWidgetHostViewPort* CreateViewForWidget(
-      RenderWidgetHost* widget);
-
-  static void GetDefaultScreenInfo(blink::WebScreenInfo* results);
-
-  // Perform all the initialization steps necessary for this object to represent
-  // a popup (such as a <select> dropdown), then shows the popup at |pos|.
-  virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
-                           const gfx::Rect& pos) = 0;
-
-  // Perform all the initialization steps necessary for this object to represent
-  // a full screen window.
-  // |reference_host_view| is the view associated with the creating page that
-  // helps to position the full screen widget on the correct monitor.
-  virtual void InitAsFullscreen(
-      RenderWidgetHostView* reference_host_view) = 0;
-
-  // Notifies the View that it has become visible.
-  virtual void WasShown() = 0;
-
-  // Notifies the View that it has been hidden.
-  virtual void WasHidden() = 0;
-
-  // Moves all plugin windows as described in the given list.
-  // |scroll_offset| is the scroll offset of the render view.
-  virtual void MovePluginWindows(
-      const std::vector<WebPluginGeometry>& moves) = 0;
-
-  // Take focus from the associated View component.
-  virtual void Blur() = 0;
-
-  // Sets the cursor to the one associated with the specified cursor_type
-  virtual void UpdateCursor(const WebCursor& cursor) = 0;
-
-  // Indicates whether the page has finished loading.
-  virtual void SetIsLoading(bool is_loading) = 0;
-
-  // Updates the type of the input method attached to the view.
-  virtual void TextInputTypeChanged(ui::TextInputType type,
-                                    ui::TextInputMode mode,
-                                    bool can_compose_inline) = 0;
-
-  // Cancel the ongoing composition of the input method attached to the view.
-  virtual void ImeCancelComposition() = 0;
-
-  // Informs that the focused DOM node has changed.
-  virtual void FocusedNodeChanged(bool is_editable_node) = 0;
-
-#if defined(OS_MACOSX) || defined(USE_AURA)
-  // Updates the range of the marked text in an IME composition.
-  virtual void ImeCompositionRangeChanged(
-      const gfx::Range& range,
-      const std::vector<gfx::Rect>& character_bounds) = 0;
-#endif
-
-  // Notifies the View that the renderer has ceased to exist.
-  virtual void RenderProcessGone(base::TerminationStatus status,
-                                 int error_code) = 0;
-
-  // Tells the View to destroy itself.
-  virtual void Destroy() = 0;
-
-  // Tells the View that the tooltip text for the current mouse position over
-  // the page has changed.
-  virtual void SetTooltipText(const base::string16& tooltip_text) = 0;
-
-  // Notifies the View that the renderer text selection has changed.
-  virtual void SelectionChanged(const base::string16& text,
-                                size_t offset,
-                                const gfx::Range& range) = 0;
-
-  // Notifies the View that the renderer selection bounds has changed.
-  // |start_rect| and |end_rect| are the bounds end of the selection in the
-  // coordinate system of the render view. |start_direction| and |end_direction|
-  // indicates the direction at which the selection was made on touch devices.
-  virtual void SelectionBoundsChanged(
-      const ViewHostMsg_SelectionBounds_Params& params) = 0;
-
-#if defined(OS_ANDROID)
-  // Notifies the View that the renderer selection root bounds has changed.
-  virtual void SelectionRootBoundsChanged(const gfx::Rect& bounds) = 0;
-#endif
-
-  // Notifies the view that the scroll offset has changed.
-  virtual void ScrollOffsetChanged() = 0;
-
-  // Copies the contents of the compositing surface into the given
-  // (uninitialized) PlatformCanvas if any.
-  // The rectangle region specified with |src_subrect| is copied from the
-  // contents, scaled to |dst_size|, and written to |output|.
-  // |callback| is invoked with true on success, false otherwise. |output| can
-  // be initialized even on failure.
-  // A smaller region than |src_subrect| may be copied if the underlying surface
-  // is smaller than |src_subrect|.
-  // NOTE: |callback| is called asynchronously.
-  virtual void CopyFromCompositingSurface(
-      const gfx::Rect& src_subrect,
-      const gfx::Size& dst_size,
-      const base::Callback<void(bool, const SkBitmap&)>& callback,
-      const SkBitmap::Config config) = 0;
-
-  // Instructs the view to not drop the surface even when the view is hidden.
-  virtual void LockCompositingSurface() = 0;
-  virtual void UnlockCompositingSurface() = 0;
-
-  // Copies a given subset of the compositing surface's content into a YV12
-  // VideoFrame, and invokes a callback with a success/fail parameter. |target|
-  // must contain an allocated, YV12 video frame of the intended size. If the
-  // copy rectangle does not match |target|'s size, the copied content will be
-  // scaled and letterboxed with black borders. The copy will happen
-  // asynchronously. This operation will fail if there is no available
-  // compositing surface.
-  virtual void CopyFromCompositingSurfaceToVideoFrame(
-      const gfx::Rect& src_subrect,
-      const scoped_refptr<media::VideoFrame>& target,
-      const base::Callback<void(bool)>& callback) = 0;
-
-  // Returns true if CopyFromCompositingSurfaceToVideoFrame() is likely to
-  // succeed.
-  //
-  // TODO(nick): When VideoFrame copies are broadly implemented, this method
-  // should be renamed to HasCompositingSurface(), or unified with
-  // IsSurfaceAvailableForCopy() and HasAcceleratedSurface().
-  virtual bool CanCopyToVideoFrame() const = 0;
-
-  // Return true if frame subscription is supported on this platform.
-  virtual bool CanSubscribeFrame() const = 0;
-
-  // Begin subscribing for presentation events and captured frames.
-  // |subscriber| is now owned by this object, it will be called only on the
-  // UI thread.
-  virtual void BeginFrameSubscription(
-      scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) = 0;
-
-  // End subscribing for frame presentation events. FrameSubscriber will be
-  // deleted after this call.
-  virtual void EndFrameSubscription() = 0;
-
-  // Called when accelerated compositing state changes.
-  virtual void OnAcceleratedCompositingStateChange() = 0;
-  // Called when an accelerated compositing surface is initialized.
-  virtual void AcceleratedSurfaceInitialized(int host_id, int route_id) = 0;
-  // |params.window| and |params.surface_id| indicate which accelerated
-  // surface's buffers swapped. |params.renderer_id| and |params.route_id|
-  // are used to formulate a reply to the GPU process to prevent it from getting
-  // too far ahead. They may all be zero, in which case no flow control is
-  // enforced; this case is currently used for accelerated plugins.
-  virtual void AcceleratedSurfaceBuffersSwapped(
-      const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
-      int gpu_host_id) = 0;
-  // Similar to above, except |params.(x|y|width|height)| define the region
-  // of the surface that changed.
-  virtual void AcceleratedSurfacePostSubBuffer(
-      const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel,
-      int gpu_host_id) = 0;
-
-  // Release the accelerated surface temporarily. It will be recreated on the
-  // next swap buffers or post sub buffer.
-  virtual void AcceleratedSurfaceSuspend() = 0;
-
-  virtual void AcceleratedSurfaceRelease() = 0;
-
-  // Return true if the view has an accelerated surface that contains the last
-  // presented frame for the view. If |desired_size| is non-empty, true is
-  // returned only if the accelerated surface size matches.
-  virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) = 0;
-
-  virtual void OnSwapCompositorFrame(
-      uint32 output_surface_id,
-      scoped_ptr<cc::CompositorFrame> frame) = 0;
-
-  virtual void GetScreenInfo(blink::WebScreenInfo* results) = 0;
-
-  // The size of the view's backing surface in non-DPI-adjusted pixels.
-  virtual gfx::Size GetPhysicalBackingSize() const = 0;
-
-  // The height of the physical backing surface that is overdrawn opaquely in
-  // the browser, for example by an on-screen-keyboard (in DPI-adjusted pixels).
-  virtual float GetOverdrawBottomHeight() const = 0;
-
-  // Gets the bounds of the window, in screen coordinates.
-  virtual gfx::Rect GetBoundsInRootWindow() = 0;
-
-  virtual gfx::GLSurfaceHandle GetCompositingSurface() = 0;
-
-  // Because the associated remote WebKit instance can asynchronously
-  // prevent-default on a dispatched touch event, the touch events are queued in
-  // the GestureRecognizer until invocation of ProcessAckedTouchEvent releases
-  // it to be consumed (when |ack_result| is NOT_CONSUMED OR NO_CONSUMER_EXISTS)
-  // or ignored (when |ack_result| is CONSUMED).
-  virtual void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
-                                      InputEventAckState ack_result) = 0;
-
-  virtual void SetScrollOffsetPinning(
-      bool is_pinned_to_left, bool is_pinned_to_right) = 0;
-
-  // Called when a mousewheel event was not processed by the renderer.
-  virtual void UnhandledWheelEvent(const blink::WebMouseWheelEvent& event) = 0;
-
-  // Called prior to forwarding input event messages to the renderer, giving
-  // the view a chance to perform in-process event filtering or processing.
-  // Return values of |NOT_CONSUMED| or |UNKNOWN| will result in |input_event|
-  // being forwarded.
-  virtual InputEventAckState FilterInputEvent(
-      const blink::WebInputEvent& input_event) = 0;
-
-  // Called by the host when it requires an input flush; the flush call should
-  // by synchronized with BeginFrame.
-  virtual void OnSetNeedsFlushInput() = 0;
-
-  // Called by the host when the input flush has completed.
-  virtual void OnDidFlushInput() = 0;
-
-  // Create a platform specific SyntheticGestureTarget implementation that will
-  // be used to inject synthetic input events.
-  virtual scoped_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget() = 0;
-
-  virtual void GestureEventAck(const blink::WebGestureEvent& event,
-                               InputEventAckState ack_result) = 0;
-
-  virtual void DidStopFlinging() = 0;
-
-  virtual void SetPopupType(blink::WebPopupType popup_type) = 0;
-  virtual blink::WebPopupType GetPopupType() = 0;
-
-  // Get the BrowserAccessibilityManager if it exists, may return NULL.
-  virtual BrowserAccessibilityManager*
-      GetBrowserAccessibilityManager() const = 0;
-  // Create a BrowserAccessibilityManager for this view if it's possible to
-  // create one and if one doesn't exist already. Some ports may not create
-  // one depending on the current state.
-  virtual void CreateBrowserAccessibilityManagerIfNeeded() = 0;
-  virtual void SetBrowserAccessibilityManager(
-      BrowserAccessibilityManager* manager) = 0;
-  virtual void OnAccessibilitySetFocus(int acc_obj_id) = 0;
-  virtual void AccessibilityShowMenu(int acc_obj_id) = 0;
-  virtual gfx::Point AccessibilityOriginInScreen(const gfx::Rect& bounds) = 0;
-  // Return a value that is incremented each time the renderer swaps a new frame
-  // to the view.
-  virtual uint32 RendererFrameNumber() = 0;
-  // Called each time the RenderWidgetHost receives a new frame for display from
-  // the renderer.
-  virtual void DidReceiveRendererFrame() = 0;
-
-  virtual SkBitmap::Config PreferredReadbackFormat() = 0;
-
-#if defined(OS_MACOSX)
-  // Does any event handling necessary for plugin IME; should be called after
-  // the plugin has already had a chance to process the event. If plugin IME is
-  // not enabled, this is a no-op, so it is always safe to call.
-  // Returns true if the event was handled by IME.
-  virtual bool PostProcessEventForPluginIme(
-      const NativeWebKeyboardEvent& event) = 0;
-#endif
-
-#if defined(OS_ANDROID)
-  virtual void ShowDisambiguationPopup(const gfx::Rect& target_rect,
-                                       const SkBitmap& zoomed_bitmap) = 0;
-#endif
-
-#if defined(OS_WIN)
-  virtual void SetParentNativeViewAccessible(
-      gfx::NativeViewAccessible accessible_parent) = 0;
-
-  // Returns an HWND that's given as the parent window for windowless Flash to
-  // workaround crbug.com/301548.
-  virtual gfx::NativeViewId GetParentForWindowlessPlugin() const = 0;
-#endif
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PORT_BROWSER_RENDER_WIDGET_HOST_VIEW_PORT_H_
diff --git a/content/port/browser/vibration_provider.h b/content/port/browser/vibration_provider.h
deleted file mode 100644
index df2587f..0000000
--- a/content/port/browser/vibration_provider.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CONTENT_PORT_BROWSER_VIBRATION_PROVIDER_H_
-#define CONTENT_PORT_BROWSER_VIBRATION_PROVIDER_H_
-
-namespace content {
-
-class VibrationProvider {
- public:
-  // Device should start vibrating for N milliseconds.
-  virtual void Vibrate(int64 milliseconds) = 0;
-
-  // Cancels vibration of the device.
-  virtual void CancelVibration() = 0;
-
-  virtual ~VibrationProvider() {}
-};
-
-}  // namespace content
-
-#endif // CONTENT_PORT_BROWSER_VIBRATION_PROVIDER_H_
diff --git a/content/port/browser/web_contents_view_port.h b/content/port/browser/web_contents_view_port.h
deleted file mode 100644
index fef0b3c..0000000
--- a/content/port/browser/web_contents_view_port.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2013 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.
-
-#ifndef CONTENT_PORT_BROWSER_WEB_CONTENTS_VIEW_PORT_H_
-#define CONTENT_PORT_BROWSER_WEB_CONTENTS_VIEW_PORT_H_
-
-#include "content/public/browser/web_contents_view.h"
-
-namespace content {
-class RenderViewHost;
-class RenderWidgetHost;
-class RenderWidgetHostView;
-
-// This is the larger WebContentsView interface exposed only within content/ and
-// to embedders looking to port to new platforms.
-class CONTENT_EXPORT WebContentsViewPort : public WebContentsView {
- public:
-  virtual ~WebContentsViewPort() {}
-
-  virtual void CreateView(
-      const gfx::Size& initial_size, gfx::NativeView context) = 0;
-
-  // Sets up the View that holds the rendered web page, receives messages for
-  // it and contains page plugins. The host view should be sized to the current
-  // size of the WebContents.
-  virtual RenderWidgetHostView* CreateViewForWidget(
-      RenderWidgetHost* render_widget_host) = 0;
-
-  // Creates a new View that holds a popup and receives messages for it.
-  virtual RenderWidgetHostView* CreateViewForPopupWidget(
-      RenderWidgetHost* render_widget_host) = 0;
-
-  // Sets the page title for the native widgets corresponding to the view. This
-  // is not strictly necessary and isn't expected to be displayed anywhere, but
-  // can aid certain debugging tools such as Spy++ on Windows where you are
-  // trying to find a specific window.
-  virtual void SetPageTitle(const base::string16& title) = 0;
-
-  // Invoked when the WebContents is notified that the RenderView has been
-  // fully created.
-  virtual void RenderViewCreated(RenderViewHost* host) = 0;
-
-  // Invoked when the WebContents is notified that the RenderView has been
-  // swapped in.
-  virtual void RenderViewSwappedIn(RenderViewHost* host) = 0;
-
-  // Invoked to enable/disable overscroll gesture navigation.
-  virtual void SetOverscrollControllerEnabled(bool enabled) = 0;
-
-#if defined(OS_MACOSX)
-  // If we close the tab while a UI control is in an event-tracking
-  // loop, the control may message freed objects and crash.
-  // WebContents::Close() calls IsEventTracking(), and if it returns
-  // true CloseTabAfterEventTracking() is called and the close is not
-  // completed.
-  virtual bool IsEventTracking() const = 0;
-  virtual void CloseTabAfterEventTracking() = 0;
-#endif
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PORT_BROWSER_WEB_CONTENTS_VIEW_PORT_H_
diff --git a/content/port/common/input_event_ack_state.h b/content/port/common/input_event_ack_state.h
deleted file mode 100644
index a482ab0..0000000
--- a/content/port/common/input_event_ack_state.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CONTENT_PORT_COMMON_INPUT_EVENT_ACK_STATE_H_
-#define CONTENT_PORT_COMMON_INPUT_EVENT_ACK_STATE_H_
-
-namespace content {
-
-// Describes the state of the input event ACK coming back to the browser side.
-enum InputEventAckState {
-  INPUT_EVENT_ACK_STATE_UNKNOWN,
-  INPUT_EVENT_ACK_STATE_CONSUMED,
-  INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
-  INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
-  INPUT_EVENT_ACK_STATE_IGNORED,
-  INPUT_EVENT_ACK_STATE_MAX = INPUT_EVENT_ACK_STATE_IGNORED
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PORT_COMMON_INPUT_EVENT_ACK_STATE_H_
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 40661f1..e8ad655 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -64,7 +64,9 @@
 import org.chromium.content.browser.input.ImeAdapter.AdapterInputConnectionFactory;
 import org.chromium.content.browser.input.InputMethodManagerWrapper;
 import org.chromium.content.browser.input.InsertionHandleController;
+import org.chromium.content.browser.input.SelectPopup;
 import org.chromium.content.browser.input.SelectPopupDialog;
+import org.chromium.content.browser.input.SelectPopupDropdown;
 import org.chromium.content.browser.input.SelectPopupItem;
 import org.chromium.content.browser.input.SelectionHandleController;
 import org.chromium.content.common.ContentSwitches;
@@ -227,7 +229,7 @@
     private ZoomControlsDelegate mZoomControlsDelegate;
 
     private PopupZoomer mPopupZoomer;
-    private SelectPopupDialog mSelectPopupDialog;
+    private SelectPopup mSelectPopup;
 
     private Runnable mFakeMouseMoveRunnable = null;
 
@@ -627,14 +629,14 @@
             public void didNavigateMainFrame(String url, String baseUrl,
                     boolean isNavigationToDifferentPage, boolean isNavigationInPage) {
                 if (!isNavigationToDifferentPage) return;
-                hidePopupDialog();
+                hidePopups();
                 resetScrollInProgress();
                 resetGestureDetection();
             }
 
             @Override
             public void renderProcessGone(boolean wasOomProtected) {
-                hidePopupDialog();
+                hidePopups();
                 resetScrollInProgress();
                 // No need to reset gesture detection as the detector will have
                 // been destroyed in the RenderWidgetHostView.
@@ -1081,36 +1083,48 @@
      * @see View#onTouchEvent(MotionEvent)
      */
     public boolean onTouchEvent(MotionEvent event) {
-        MotionEvent offset = createOffsetMotionEvent(event);
+        TraceEvent.begin("onTouchEvent");
+        try {
+            cancelRequestToScrollFocusedEditableNodeIntoView();
 
-        cancelRequestToScrollFocusedEditableNodeIntoView();
+            final int eventAction = event.getActionMasked();
 
-        final int eventAction = offset.getActionMasked();
+            // Only these actions have any effect on gesture detection.  Other
+            // actions have no corresponding WebTouchEvent type and may confuse the
+            // touch pipline, so we ignore them entirely.
+            if (eventAction != MotionEvent.ACTION_DOWN
+                    && eventAction != MotionEvent.ACTION_UP
+                    && eventAction != MotionEvent.ACTION_CANCEL
+                    && eventAction != MotionEvent.ACTION_MOVE
+                    && eventAction != MotionEvent.ACTION_POINTER_DOWN
+                    && eventAction != MotionEvent.ACTION_POINTER_UP) {
+                return false;
+            }
 
-        // Only these actions have any effect on gesture detection.  Other
-        // actions have no corresponding WebTouchEvent type and may confuse the
-        // touch pipline, so we ignore them entirely.
-        if (eventAction != MotionEvent.ACTION_DOWN
-                && eventAction != MotionEvent.ACTION_UP
-                && eventAction != MotionEvent.ACTION_CANCEL
-                && eventAction != MotionEvent.ACTION_MOVE
-                && eventAction != MotionEvent.ACTION_POINTER_DOWN
-                && eventAction != MotionEvent.ACTION_POINTER_UP) {
-            return false;
+            if (mNativeContentViewCore == 0) return false;
+
+            // A zero offset is quite common, in which case the unnecessary copy should be avoided.
+            MotionEvent offset = null;
+            if (mCurrentTouchOffsetX != 0 || mCurrentTouchOffsetY != 0) {
+                offset = createOffsetMotionEvent(event);
+                event = offset;
+            }
+
+            final int pointerCount = event.getPointerCount();
+            final boolean consumed = nativeOnTouchEvent(mNativeContentViewCore, event,
+                    event.getEventTime(), eventAction,
+                    pointerCount, event.getHistorySize(), event.getActionIndex(),
+                    event.getX(), event.getY(),
+                    pointerCount > 1 ? event.getX(1) : 0,
+                    pointerCount > 1 ? event.getY(1) : 0,
+                    event.getPointerId(0), pointerCount > 1 ? event.getPointerId(1) : -1,
+                    event.getTouchMajor(), pointerCount > 1 ? event.getTouchMajor(1) : 0);
+
+            if (offset != null) offset.recycle();
+            return consumed;
+        } finally {
+            TraceEvent.end("onTouchEvent");
         }
-
-        if (mNativeContentViewCore == 0) return false;
-        final int pointerCount = offset.getPointerCount();
-        boolean consumed = nativeOnTouchEvent(mNativeContentViewCore, offset,
-                offset.getEventTime(), eventAction,
-                pointerCount, offset.getHistorySize(), offset.getActionIndex(),
-                offset.getX(), offset.getY(),
-                pointerCount > 1 ? offset.getX(1) : 0,
-                pointerCount > 1 ? offset.getY(1) : 0,
-                offset.getPointerId(0), pointerCount > 1 ? offset.getPointerId(1) : -1,
-                offset.getTouchMajor(), pointerCount > 1 ? offset.getTouchMajor(1) : 0);
-        offset.recycle();
-        return consumed;
     }
 
     public void setIgnoreRemainingTouchEvents() {
@@ -1346,7 +1360,7 @@
      */
     public void onHide() {
         assert mNativeContentViewCore != 0;
-        hidePopupDialog();
+        hidePopups();
         setInjectedAccessibility(false);
         nativeOnHide(mNativeContentViewCore);
     }
@@ -1361,7 +1375,7 @@
         return mContentSettings;
     }
 
-    private void hidePopupDialog() {
+    private void hidePopups() {
         hideSelectPopup();
         hideHandles();
         hideSelectActionBar();
@@ -1400,7 +1414,7 @@
     @SuppressLint("MissingSuperCall")
     public void onDetachedFromWindow() {
         setInjectedAccessibility(false);
-        hidePopupDialog();
+        hidePopups();
         mZoomControlsDelegate.dismissZoomPicker();
         unregisterAccessibilityContentObserver();
 
@@ -1456,8 +1470,10 @@
         TraceEvent.begin();
 
         if (newConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
-            mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore),
-                    ImeAdapter.getTextInputTypeNone());
+            if (mNativeContentViewCore != 0) {
+                mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore),
+                        ImeAdapter.getTextInputTypeNone());
+            }
             mInputMethodManagerWrapper.restartInput(mContainerView);
         }
         mContainerViewInternals.super_onConfigurationChanged(newConfig);
@@ -1613,25 +1629,27 @@
     public boolean onHoverEvent(MotionEvent event) {
         TraceEvent.begin("onHoverEvent");
         MotionEvent offset = createOffsetMotionEvent(event);
+        try {
+            if (mBrowserAccessibilityManager != null) {
+                return mBrowserAccessibilityManager.onHoverEvent(offset);
+            }
 
-        if (mBrowserAccessibilityManager != null) {
-            return mBrowserAccessibilityManager.onHoverEvent(offset);
-        }
+            // Work around Android bug where the x, y coordinates of a hover exit
+            // event are incorrect when touch exploration is on.
+            if (mTouchExplorationEnabled && offset.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
+                return true;
+            }
 
-        // Work around Android bug where the x, y coordinates of a hover exit
-        // event are incorrect when touch exploration is on.
-        if (mTouchExplorationEnabled && offset.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
+            mContainerView.removeCallbacks(mFakeMouseMoveRunnable);
+            if (mNativeContentViewCore != 0) {
+                nativeSendMouseMoveEvent(mNativeContentViewCore, offset.getEventTime(),
+                        offset.getX(), offset.getY());
+            }
             return true;
+        } finally {
+            offset.recycle();
+            TraceEvent.end("onHoverEvent");
         }
-
-        mContainerView.removeCallbacks(mFakeMouseMoveRunnable);
-        if (mNativeContentViewCore != 0) {
-            nativeSendMouseMoveEvent(mNativeContentViewCore, offset.getEventTime(),
-                    offset.getX(), offset.getY());
-        }
-        TraceEvent.end("onHoverEvent");
-        offset.recycle();
-        return true;
     }
 
     /**
@@ -1641,6 +1659,8 @@
         if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
             switch (event.getAction()) {
                 case MotionEvent.ACTION_SCROLL:
+                    if (mNativeContentViewCore == 0) return false;
+
                     nativeSendMouseWheelEvent(mNativeContentViewCore, event.getEventTime(),
                             event.getX(), event.getY(),
                             event.getAxisValue(MotionEvent.AXIS_VSCROLL));
@@ -1653,6 +1673,7 @@
                         @Override
                         public void run() {
                             onHoverEvent(eventFakeMouseMove);
+                            eventFakeMouseMove.recycle();
                         }
                     };
                     mContainerView.postDelayed(mFakeMouseMoveRunnable, 250);
@@ -1851,7 +1872,7 @@
         if (mNativeContentViewCore != 0) {
             nativeSelectPopupMenuItems(mNativeContentViewCore, indices);
         }
-        mSelectPopupDialog = null;
+        mSelectPopup = null;
     }
 
     /**
@@ -2116,7 +2137,7 @@
     }
 
     public void clearSslPreferences() {
-        nativeClearSslPreferences(mNativeContentViewCore);
+        if (mNativeContentViewCore != 0) nativeClearSslPreferences(mNativeContentViewCore);
     }
 
     private boolean isSelectionHandleShowing() {
@@ -2314,20 +2335,25 @@
      */
     @SuppressWarnings("unused")
     @CalledByNative
-    private void showSelectPopup(String[] items, int[] enabled, boolean multiple,
+    private void showSelectPopup(Rect bounds, String[] items, int[] enabled, boolean multiple,
             int[] selectedIndices) {
         if (mContainerView.getParent() == null || mContainerView.getVisibility() != View.VISIBLE) {
             selectPopupMenuItems(null);
             return;
         }
 
-        hideSelectPopup();
         assert items.length == enabled.length;
         List<SelectPopupItem> popupItems = new ArrayList<SelectPopupItem>();
         for (int i = 0; i < items.length; i++) {
             popupItems.add(new SelectPopupItem(items[i], enabled[i]));
         }
-        mSelectPopupDialog = SelectPopupDialog.show(this, popupItems, multiple, selectedIndices);
+        hidePopups();
+        if (DeviceUtils.isTablet(mContext) && !multiple) {
+            mSelectPopup = new SelectPopupDropdown(this, popupItems, bounds, selectedIndices);
+        } else {
+            mSelectPopup = new SelectPopupDialog(this, popupItems, multiple, selectedIndices);
+        }
+        mSelectPopup.show();
     }
 
     /**
@@ -2335,17 +2361,14 @@
      */
     @CalledByNative
     private void hideSelectPopup() {
-        if (mSelectPopupDialog != null) {
-            mSelectPopupDialog.hide();
-            mSelectPopupDialog = null;
-        }
+        if (mSelectPopup != null) mSelectPopup.hide();
     }
 
     /**
-     * @return The visible select popup dialog being shown.
+     * @return The visible select popup being shown.
      */
-    public SelectPopupDialog getSelectPopupForTest() {
-        return mSelectPopupDialog;
+    public SelectPopup getSelectPopupForTest() {
+        return mSelectPopup;
     }
 
     @SuppressWarnings("unused")
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java
index ea90582..6759697 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java
@@ -244,12 +244,6 @@
     protected void render() {
         if (mPendingRenders > 0) mPendingRenders--;
 
-        // Waiting for the content view contents to be ready avoids compositing
-        // when the surface texture is still empty.
-        if (mContentViewCore == null || !mContentViewCore.isReady()) {
-            return;
-        }
-
         boolean didDraw = nativeComposite(mNativeContentViewRenderView);
         if (didDraw) {
             mPendingSwapBuffers++;
diff --git a/content/public/android/java/src/org/chromium/content/browser/LoadUrlParams.java b/content/public/android/java/src/org/chromium/content/browser/LoadUrlParams.java
index 6cd412c..12a2260 100644
--- a/content/public/android/java/src/org/chromium/content/browser/LoadUrlParams.java
+++ b/content/public/android/java/src/org/chromium/content/browser/LoadUrlParams.java
@@ -19,17 +19,18 @@
 @JNINamespace("content")
 public class LoadUrlParams {
     // Should match NavigationController::LoadUrlType exactly. See comments
-    // there for proper usage. Values are initialized in initializeConstants.
-    public static int LOAD_TYPE_DEFAULT;
-    public static int LOAD_TYPE_BROWSER_INITIATED_HTTP_POST;
-    public static int LOAD_TYPE_DATA;
+    // there for proper usage. initializeConstants() checks that the values
+    // are correct.
+    public static final int LOAD_TYPE_DEFAULT = 0;
+    public static final int LOAD_TYPE_BROWSER_INITIATED_HTTP_POST = 1;
+    public static final int LOAD_TYPE_DATA = 2;
 
     // Should match NavigationController::UserAgentOverrideOption exactly.
-    // See comments there for proper usage. Values are initialized in
-    // initializeConstants.
-    public static int UA_OVERRIDE_INHERIT;
-    public static int UA_OVERRIDE_FALSE;
-    public static int UA_OVERRIDE_TRUE;
+    // See comments there for proper usage. initializeConstants() checks that
+    // the values are correct.
+    public static final int UA_OVERRIDE_INHERIT = 0;
+    public static final int UA_OVERRIDE_FALSE = 1;
+    public static final int UA_OVERRIDE_TRUE = 2;
 
     // Fields with counterparts in NavigationController::LoadURLParams.
     // Package private so that ContentViewCore.loadUrl can pass them down to
@@ -61,9 +62,6 @@
      * @param transitionType the PageTransitionType constant corresponding to the load
      */
     public LoadUrlParams(String url, int transitionType) {
-        // Check initializeConstants was called.
-        assert LOAD_TYPE_DEFAULT != LOAD_TYPE_BROWSER_INITIATED_HTTP_POST;
-
         mUrl = url;
         mTransitionType = transitionType;
 
@@ -379,12 +377,12 @@
             int ua_override_inherit,
             int ua_override_false,
             int ua_override_true) {
-        LOAD_TYPE_DEFAULT = load_type_default;
-        LOAD_TYPE_BROWSER_INITIATED_HTTP_POST = load_type_browser_initiated_http_post;
-        LOAD_TYPE_DATA = load_type_data;
-        UA_OVERRIDE_INHERIT = ua_override_inherit;
-        UA_OVERRIDE_FALSE = ua_override_false;
-        UA_OVERRIDE_TRUE = ua_override_true;
+        assert LOAD_TYPE_DEFAULT == load_type_default;
+        assert LOAD_TYPE_BROWSER_INITIATED_HTTP_POST == load_type_browser_initiated_http_post;
+        assert LOAD_TYPE_DATA == load_type_data;
+        assert UA_OVERRIDE_INHERIT == ua_override_inherit;
+        assert UA_OVERRIDE_FALSE == ua_override_false;
+        assert UA_OVERRIDE_TRUE == ua_override_true;
     }
 
     /**
diff --git a/content/public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java b/content/public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java
index f26b274..172a016 100644
--- a/content/public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java
+++ b/content/public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java
@@ -46,6 +46,7 @@
 
     private static final String ACTION_START = "GPU_PROFILER_START";
     private static final String ACTION_STOP = "GPU_PROFILER_STOP";
+    private static final String ACTION_LIST_CATEGORIES = "GPU_PROFILER_LIST_CATEGORIES";
     private static final String FILE_EXTRA = "file";
     private static final String CATEGORIES_EXTRA = "categories";
     private static final String RECORD_CONTINUOUSLY_EXTRA = "continuous";
@@ -152,6 +153,12 @@
         return startTracing(filePath, showToasts, categories, recordContinuously);
     }
 
+    private void initializeNativeControllerIfNeeded() {
+        if (mNativeTracingControllerAndroid == 0) {
+            mNativeTracingControllerAndroid = nativeInit();
+        }
+    }
+
     /**
      * Start profiling to the specified file. Returns true on success.
      *
@@ -177,9 +184,7 @@
             return false;
         }
         // Lazy initialize the native side, to allow construction before the library is loaded.
-        if (mNativeTracingControllerAndroid == 0) {
-            mNativeTracingControllerAndroid = nativeInit();
-        }
+        initializeNativeControllerIfNeeded();
         if (!nativeStartTracing(mNativeTracingControllerAndroid, categories,
                 recordContinuously)) {
             logAndToastError(mContext.getString(R.string.profiler_error_toast));
@@ -218,6 +223,17 @@
         mFilename = null;
     }
 
+    /**
+     * Get known category groups.
+     */
+    public void getCategoryGroups() {
+        // Lazy initialize the native side, to allow construction before the library is loaded.
+        initializeNativeControllerIfNeeded();
+        if (!nativeGetKnownCategoryGroupsAsync(mNativeTracingControllerAndroid)) {
+            Log.e(TAG, "Unable to fetch tracing record groups list.");
+        }
+    }
+
     @Override
     protected void finalize() {
         if (mNativeTracingControllerAndroid != 0) {
@@ -240,6 +256,7 @@
         TracingIntentFilter(Context context) {
             addAction(context.getPackageName() + "." + ACTION_START);
             addAction(context.getPackageName() + "." + ACTION_STOP);
+            addAction(context.getPackageName() + "." + ACTION_LIST_CATEGORIES);
         }
     }
 
@@ -264,6 +281,8 @@
                 }
             } else if (intent.getAction().endsWith(ACTION_STOP)) {
                 stopTracing();
+            } else if (intent.getAction().endsWith(ACTION_LIST_CATEGORIES)) {
+                getCategoryGroups();
             } else {
                 Log.e(TAG, "Unexpected intent: " + intent);
             }
@@ -276,5 +295,6 @@
     private native boolean nativeStartTracing(
             long nativeTracingControllerAndroid, String categories, boolean recordContinuously);
     private native void nativeStopTracing(long nativeTracingControllerAndroid, String filename);
+    private native boolean nativeGetKnownCategoryGroupsAsync(long nativeTracingControllerAndroid);
     private native String nativeGetDefaultCategories();
 }
diff --git a/content/public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java b/content/public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java
index e406907..17081e5 100644
--- a/content/public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java
+++ b/content/public/android/java/src/org/chromium/content/browser/WebContentsObserverAndroid.java
@@ -65,10 +65,9 @@
 
     /**
      * Called when the page had painted something non-empty.
-     * @param pageId unique ID of the page in history entries.
      */
     @CalledByNative
-    public void didFirstVisuallyNonEmptyPaint(int pageId) {
+    public void didFirstVisuallyNonEmptyPaint() {
     }
 
     /**
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopup.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopup.java
new file mode 100644
index 0000000..bd5abef
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopup.java
@@ -0,0 +1,19 @@
+// 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.content.browser.input;
+
+/**
+ * Handles the popup UI for the <select> HTML tag support.
+ */
+public interface SelectPopup {
+    /**
+     * Shows the popup.
+     */
+    public void show();
+    /**
+     * Hides the popup.
+     */
+    public void hide();
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java
index 3313d88..1ebbbf7 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java
@@ -22,7 +22,7 @@
 /**
  * Handles the popup dialog for the <select> HTML tag support.
  */
-public class SelectPopupDialog {
+public class SelectPopupDialog implements SelectPopup {
     private static final int[] SELECT_DIALOG_ATTRS = {
         R.attr.select_dialog_multichoice,
         R.attr.select_dialog_singlechoice
@@ -34,7 +34,7 @@
     private final ContentViewCore mContentViewCore;
     private final Context mContext;
 
-    private SelectPopupDialog(ContentViewCore contentViewCore, List<SelectPopupItem> items,
+    public SelectPopupDialog(ContentViewCore contentViewCore, List<SelectPopupItem> items,
             boolean multiple, int[] selected) {
         mContentViewCore = contentViewCore;
         mContext = mContentViewCore.getContext();
@@ -121,27 +121,13 @@
         return indices;
     }
 
-    /**
-     * Hides the select dialog.
-     */
-    public void hide() {
-        mListBoxPopup.cancel();
+    @Override
+    public void show() {
+        mListBoxPopup.show();
     }
 
-    /**
-     * Shows the popup menu triggered by the passed ContentView.
-     * Hides any currently shown popup.
-     * @param items           Items to show.
-     * @param multiple        Whether the popup menu should support multi-select.
-     * @param selectedIndices Indices of selected items.
-     * @return                The select dialog created.
-     */
-    public static SelectPopupDialog show(
-            ContentViewCore contentViewCore, List<SelectPopupItem> items,
-            boolean multiple, int[] selectedIndices) {
-        SelectPopupDialog dialog = new SelectPopupDialog(
-                contentViewCore, items, multiple, selectedIndices);
-        dialog.mListBoxPopup.show();
-        return dialog;
+    @Override
+    public void hide() {
+        mListBoxPopup.cancel();
     }
 }
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDropdown.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDropdown.java
new file mode 100644
index 0000000..97458f3
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDropdown.java
@@ -0,0 +1,74 @@
+// 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.content.browser.input;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.view.View;
+import android.widget.AdapterView;
+
+import org.chromium.content.browser.ContentViewCore;
+import org.chromium.content.browser.RenderCoordinates;
+import org.chromium.ui.DropdownAdapter;
+import org.chromium.ui.DropdownItem;
+import org.chromium.ui.DropdownPopupWindow;
+
+import java.util.List;
+
+/**
+ * Handles the dropdown popup for the <select> HTML tag support.
+ */
+public class SelectPopupDropdown implements SelectPopup {
+
+    private final ContentViewCore mContentViewCore;
+    private final Context mContext;
+
+    private DropdownPopupWindow mDropdownPopupWindow;
+    private int mInitialSelection = -1;
+
+    public SelectPopupDropdown(ContentViewCore contentViewCore, List<SelectPopupItem> items,
+            Rect bounds, int[] selected) {
+        mContentViewCore = contentViewCore;
+        mContext = mContentViewCore.getContext();
+        mDropdownPopupWindow = new DropdownPopupWindow(mContext,
+                mContentViewCore.getViewAndroidDelegate());
+        mDropdownPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                int[] selectedIndices = {position};
+                mContentViewCore.selectPopupMenuItems(selectedIndices);
+                hide();
+            }
+        });
+        if (selected.length > 0) {
+            mInitialSelection = selected[0];
+        }
+        DropdownItem[] dropdownItems = items.toArray(new DropdownItem[items.size()]);
+        mDropdownPopupWindow.setAdapter(new DropdownAdapter(mContext, dropdownItems, null));
+        RenderCoordinates renderCoordinates = mContentViewCore.getRenderCoordinates();
+        float anchorX = renderCoordinates.fromPixToDip(
+                renderCoordinates.fromLocalCssToPix(bounds.left));
+        float anchorY = renderCoordinates.fromPixToDip(
+                renderCoordinates.fromLocalCssToPix(bounds.top));
+        float anchorWidth = renderCoordinates.fromPixToDip(
+                renderCoordinates.fromLocalCssToPix(bounds.right)) - anchorX;
+        float anchorHeight = renderCoordinates.fromPixToDip(
+                renderCoordinates.fromLocalCssToPix(bounds.bottom)) - anchorY;
+        mDropdownPopupWindow.setAnchorRect(anchorX, anchorY, anchorWidth, anchorHeight);
+    }
+
+    @Override
+    public void show() {
+        mDropdownPopupWindow.show();
+        if (mInitialSelection >= 0) {
+            mDropdownPopupWindow.getListView().setSelection(mInitialSelection);
+        }
+    }
+
+    @Override
+    public void hide() {
+        mDropdownPopupWindow.dismiss();
+    }
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupItem.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupItem.java
index 2b3a60e..b517098 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupItem.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupItem.java
@@ -4,11 +4,13 @@
 
 package org.chromium.content.browser.input;
 
+import org.chromium.ui.DropdownItem;
+
 /**
  * Select popup item containing the label, the type and the enabled state
  * of an item belonging to a select popup dialog.
  */
-public class SelectPopupItem {
+public class SelectPopupItem implements DropdownItem {
     private final String mLabel;
     private final int mType;
 
@@ -17,10 +19,26 @@
         mType = type;
     }
 
+    @Override
     public String getLabel() {
         return mLabel;
     }
 
+    @Override
+    public String getSublabel() {
+        return null;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return mType == PopupItemType.ENABLED || mType == PopupItemType.GROUP;
+    }
+
+    @Override
+    public boolean isGroupHeader() {
+        return mType == PopupItemType.GROUP;
+    }
+
     public int getType() {
         return mType;
     }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationIntegrationTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationIntegrationTest.java
index 36f089d..4350725 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationIntegrationTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationIntegrationTest.java
@@ -4,8 +4,7 @@
 
 package org.chromium.content.browser;
 
-import android.test.suitebuilder.annotation.SmallTest;
-
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.content.browser.test.util.JavaScriptUtils;
@@ -66,13 +65,23 @@
         mContentViewCore = activity.getActiveContentViewCore();
     }
 
-    @SmallTest
+    /*
+     * Broken by http://src.chromium.org/viewvc/blink?revision=173532&view=revision
+     * crbug.com/371144
+     * @SmallTest
+     */
+    @DisabledTest
     @Feature({"ScreenOrientation"})
     public void testNoOp() throws Throwable {
         assertEquals(0, getWindowOrientationChangeCount());
     }
 
-    @SmallTest
+    /*
+     * Broken by http://src.chromium.org/viewvc/blink?revision=173532&view=revision
+     * crbug.com/371144
+     * @SmallTest
+     */
+    @DisabledTest
     @Feature({"ScreenOrientation"})
     public void testExpectedValues() throws Throwable {
         int[] values = { 90, -90, 180, 0, 90 };
@@ -89,7 +98,12 @@
 
     // We can't test unexpected value because it is branching to a NOTREACHED().
 
-    @SmallTest
+    /*
+     * Broken by http://src.chromium.org/viewvc/blink?revision=173532&view=revision
+     * crbug.com/371144
+     * @SmallTest
+     */
+    @DisabledTest
     @Feature({"ScreenOrientation"})
     public void testNoChange() throws Throwable {
         // The target angle for that test should depend on the current orientation.
diff --git a/content/public/browser/browser_context.h b/content/public/browser/browser_context.h
index 0cb1b5b..d4e80b2 100644
--- a/content/public/browser/browser_context.h
+++ b/content/public/browser/browser_context.h
@@ -31,6 +31,7 @@
 
 namespace content {
 
+class BrowserPluginGuestManagerDelegate;
 class DownloadManager;
 class DownloadManagerDelegate;
 class GeolocationPermissionContext;
@@ -169,6 +170,10 @@
   // return NULL, in which case geolocation requests will always be allowed.
   virtual GeolocationPermissionContext* GetGeolocationPermissionContext() = 0;
 
+  // Returns the guest manager delegate for this context.
+  virtual content::BrowserPluginGuestManagerDelegate*
+      GetGuestManagerDelegate() = 0;
+
   // Returns a special storage policy implementation, or NULL.
   virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() = 0;
 };
diff --git a/content/public/browser/browser_plugin_guest_delegate.cc b/content/public/browser/browser_plugin_guest_delegate.cc
index d1b821d..b3d0fb4 100644
--- a/content/public/browser/browser_plugin_guest_delegate.cc
+++ b/content/public/browser/browser_plugin_guest_delegate.cc
@@ -8,6 +8,10 @@
 
 namespace content {
 
+WebContents* BrowserPluginGuestDelegate::GetOpener() const {
+  return NULL;
+}
+
 bool BrowserPluginGuestDelegate::HandleKeyboardEvent(
     const NativeWebKeyboardEvent& event) {
   return false;
@@ -45,4 +49,9 @@
   return NULL;
 }
 
+bool BrowserPluginGuestDelegate::HandleContextMenu(
+    const ContextMenuParams& params) {
+  return false;
+}
+
 }  // namespace content
diff --git a/content/public/browser/browser_plugin_guest_delegate.h b/content/public/browser/browser_plugin_guest_delegate.h
index efb036c..6df0ef1 100644
--- a/content/public/browser/browser_plugin_guest_delegate.h
+++ b/content/public/browser/browser_plugin_guest_delegate.h
@@ -19,7 +19,9 @@
 namespace content {
 
 class JavaScriptDialogManager;
+struct ContextMenuParams;
 struct NativeWebKeyboardEvent;
+class WebContents;
 
 // Objects implement this interface to get notified about changes in the guest
 // WebContents and to provide necessary functionality.
@@ -40,6 +42,11 @@
   // Notification that the embedder has completed attachment.
   virtual void DidAttach() {}
 
+  // Returns the opener for this guest.
+  // TODO(fsamuel): Remove this once the New Window API is migrated outside of
+  // the content layer.
+  virtual WebContents* GetOpener() const;
+
   // Informs the delegate that the guest render process is gone. |status|
   // indicates whether the guest was killed, crashed, or was terminated
   // gracefully.
@@ -98,6 +105,12 @@
   // Requests resolution of a potentially relative URL.
   virtual GURL ResolveURL(const std::string& src);
 
+  // Informs the delegate of the WebContents that created delegate's associated
+  // WebContents.
+  // TODO(fsamuel): Remove this once the New Window API is migrated outside of
+  // the content layer.
+  virtual void SetOpener(WebContents* opener) {}
+
   // Notifies that the content size of the guest has changed in autosize mode.
   virtual void SizeChanged(const gfx::Size& old_size,
                            const gfx::Size& new_size) {}
@@ -127,6 +140,9 @@
   // Returns a pointer to a service to manage JavaScript dialogs. May return
   // NULL in which case dialogs aren't shown.
   virtual JavaScriptDialogManager* GetJavaScriptDialogManager();
+
+  // Returns true if the context menu operation was handled by the delegate.
+  virtual bool HandleContextMenu(const ContextMenuParams& params);
 };
 
 }  // namespace content
diff --git a/content/public/browser/browser_plugin_guest_manager_delegate.cc b/content/public/browser/browser_plugin_guest_manager_delegate.cc
new file mode 100644
index 0000000..43012be
--- /dev/null
+++ b/content/public/browser/browser_plugin_guest_manager_delegate.cc
@@ -0,0 +1,25 @@
+// 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.
+
+#include "content/public/browser/browser_plugin_guest_manager_delegate.h"
+
+namespace content {
+
+int BrowserPluginGuestManagerDelegate::GetNextInstanceID() {
+  return 0;
+}
+
+content::SiteInstance* BrowserPluginGuestManagerDelegate::GetGuestSiteInstance(
+    const GURL& guest_site) {
+  return NULL;
+}
+
+bool BrowserPluginGuestManagerDelegate::ForEachGuest(
+    WebContents* embedder_web_contents,
+    const GuestCallback& callback) {
+  return false;
+}
+
+}  // content
+
diff --git a/content/public/browser/browser_plugin_guest_manager_delegate.h b/content/public/browser/browser_plugin_guest_manager_delegate.h
new file mode 100644
index 0000000..484b09c
--- /dev/null
+++ b/content/public/browser/browser_plugin_guest_manager_delegate.h
@@ -0,0 +1,68 @@
+// 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.
+
+#ifndef CONTENT_PUBLIC_BROWSER_BROWSER_PLUGIN_GUEST_MANAGER_DELEGATE_H_
+#define CONTENT_PUBLIC_BROWSER_BROWSER_PLUGIN_GUEST_MANAGER_DELEGATE_H_
+
+#include "base/callback.h"
+#include "content/common/content_export.h"
+
+class GURL;
+
+namespace content {
+
+class SiteInstance;
+class WebContents;
+
+// A BrowserPluginGuestManagerDelegate offloads guest management and routing
+// operations outside of the content layer.
+class CONTENT_EXPORT BrowserPluginGuestManagerDelegate {
+ public:
+  virtual ~BrowserPluginGuestManagerDelegate() {}
+
+  // Return a new instance ID.
+  // TODO(fsamuel): Remove this. Once the instance ID concept is moved
+  // entirely out of content and into chrome, this API will be unnecessary.
+  virtual int GetNextInstanceID();
+
+  // Adds a new WebContents |guest_web_contents| as a guest.
+  // TODO(fsamuel): Remove this. Once guest WebContents allocation
+  // moves outside of content, this API will be unnecessary.
+  virtual void AddGuest(int guest_instance_id,
+                        WebContents* guest_web_contents) {}
+
+  // Removes a |guest_instance_id| as a valid guest.
+  // TODO(fsamuel): Remove this. Once guest WebContents allocation
+  // moves outside of content, this API will be unnecessary.
+  virtual void RemoveGuest(int guest_instance_id) {}
+
+  typedef base::Callback<void(WebContents*)> GuestByInstanceIDCallback;
+  // Requests a guest WebContents associated with the provided
+  // |guest_instance_id|. If a guest associated with the provided ID
+  // does not exist, then the |callback| will be called with a NULL
+  // WebContents. If the provided |embedder_render_process_id| does
+  // not own the requested guest, then the embedder will be killed,
+  // and the |callback| will not be called.
+  virtual void MaybeGetGuestByInstanceIDOrKill(
+      int guest_instance_id,
+      int embedder_render_process_id,
+      const GuestByInstanceIDCallback& callback) {}
+
+  // Returns an existing SiteInstance if the current profile has a guest of the
+  // given |guest_site|.
+  // TODO(fsamuel): Remove this. Once guest WebContents allocation
+  // moves outside of content, this API will be unnecessary.
+  virtual content::SiteInstance* GetGuestSiteInstance(const GURL& guest_site);
+
+  // Iterates over all WebContents belonging to a given |embedder_web_contents|,
+  // calling |callback| for each. If one of the callbacks returns true, then
+  // the iteration exits early.
+  typedef base::Callback<bool(WebContents*)> GuestCallback;
+  virtual bool ForEachGuest(WebContents* embedder_web_contents,
+                            const GuestCallback& callback);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_PUBLIC_BROWSER_BROWSER_PLUGIN_GUEST_MANAGER_DELEGATE_H_
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index ba80b8f..fb8279b 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -15,12 +15,6 @@
   return NULL;
 }
 
-WebContentsViewPort* ContentBrowserClient::OverrideCreateWebContentsView(
-    WebContents* web_contents,
-    RenderViewHostDelegateView** render_view_host_delegate_view) {
-  return NULL;
-}
-
 WebContentsViewDelegate* ContentBrowserClient::GetWebContentsViewDelegate(
     WebContents* web_contents) {
   return NULL;
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index ac40ae2..5f0473b 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -95,14 +95,12 @@
 class RenderFrameHost;
 class RenderProcessHost;
 class RenderViewHost;
-class RenderViewHostDelegateView;
 class ResourceContext;
 class SiteInstance;
 class SpeechRecognitionManagerDelegate;
 class VibrationProvider;
 class WebContents;
 class WebContentsViewDelegate;
-class WebContentsViewPort;
 struct MainFunctionParams;
 struct Referrer;
 struct ShowDesktopNotificationHostMsgParams;
@@ -135,14 +133,6 @@
   virtual BrowserMainParts* CreateBrowserMainParts(
       const MainFunctionParams& parameters);
 
-  // Allows an embedder to return their own WebContentsViewPort implementation.
-  // Return NULL to let the default one for the platform be created. Otherwise
-  // |render_view_host_delegate_view| also needs to be provided, and it is
-  // owned by the embedder.
-  virtual WebContentsViewPort* OverrideCreateWebContentsView(
-      WebContents* web_contents,
-      RenderViewHostDelegateView** render_view_host_delegate_view);
-
   // If content creates the WebContentsView implementation, it will ask the
   // embedder to return an (optional) delegate to customize it. The view will
   // own the delegate.
diff --git a/content/public/browser/devtools_target.h b/content/public/browser/devtools_target.h
index 3fcac05..ae4ab8b 100644
--- a/content/public/browser/devtools_target.h
+++ b/content/public/browser/devtools_target.h
@@ -38,10 +38,10 @@
   virtual std::string GetDescription() const = 0;
 
   // Returns the url associated with this target.
-  virtual GURL GetUrl() const = 0;
+  virtual GURL GetURL() const = 0;
 
   // Returns the favicon url for this target.
-  virtual GURL GetFaviconUrl() const = 0;
+  virtual GURL GetFaviconURL() const = 0;
 
   // Returns the time when the target was last active.
   virtual base::TimeTicks GetLastActivityTime() const = 0;
diff --git a/content/public/browser/location_provider.h b/content/public/browser/location_provider.h
new file mode 100644
index 0000000..8752a90
--- /dev/null
+++ b/content/public/browser/location_provider.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2013 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.
+
+#ifndef CONTENT_PUBLIC_BROWSER_LOCATION_PROVIDER_H_
+#define CONTENT_PUBLIC_BROWSER_LOCATION_PROVIDER_H_
+
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "content/public/common/geoposition.h"
+
+namespace content {
+
+class LocationProvider;
+
+// The interface for providing location information.
+class LocationProvider {
+ public:
+  virtual ~LocationProvider() {}
+
+  typedef base::Callback<void(const LocationProvider*, const Geoposition&)>
+      LocationProviderUpdateCallback;
+
+  // This callback will be used to notify when a new Geoposition becomes
+  // available.
+  virtual void SetUpdateCallback(
+      const LocationProviderUpdateCallback& callback) = 0;
+
+  // StartProvider maybe called multiple times, e.g. to alter the
+  // |high_accuracy| setting. Returns false if a fatal error was encountered
+  // which prevented the provider from starting.
+  virtual bool StartProvider(bool high_accuracy) = 0;
+
+  // Stops the provider from sending more requests.
+  // Important: a LocationProvider may be instantiated and StartProvider() may
+  // be called before the user has granted permission via OnPermissionGranted().
+  // This is to allow underlying providers to warm up, load their internal
+  // libraries, etc. No |LocationProviderUpdateCallback| can be run and no
+  // network requests can be done until OnPermissionGranted() has been called.
+  virtual void StopProvider() = 0;
+
+  // Gets the current best position estimate.
+  virtual void GetPosition(Geoposition* position) = 0;
+
+  // Provides a hint to the provider that new location data is needed as soon
+  // as possible.
+  virtual void RequestRefresh() = 0;
+
+  // Called everytime permission is granted to a page for using geolocation.
+  // This may either be through explicit user action (e.g. responding to the
+  // infobar prompt) or inferred from a persisted site permission.
+  // Note: See |StartProvider()| for more information.
+  virtual void OnPermissionGranted() = 0;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_PUBLIC_BROWSER_LOCATION_PROVIDER_H_
diff --git a/content/public/browser/notification_types.h b/content/public/browser/notification_types.h
index a284989..08ffd33 100644
--- a/content/public/browser/notification_types.h
+++ b/content/public/browser/notification_types.h
@@ -72,7 +72,7 @@
   // Other load-related (not from NavigationController) ----------------------
 
   // Corresponds to ViewHostMsg_DocumentOnLoadCompletedInMainFrame. The source
-  // is the WebContents and the details the page_id.
+  // is the WebContents.
   // DEPRECATED: Use WebContentsObserver::DocumentOnLoadCompletedInMainFrame()
   NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
 
diff --git a/content/public/browser/render_view_host.h b/content/public/browser/render_view_host.h
index 6a6b349..629cdbd 100644
--- a/content/public/browser/render_view_host.h
+++ b/content/public/browser/render_view_host.h
@@ -82,6 +82,9 @@
   // Tells the renderer to clear the focused element (if any).
   virtual void ClearFocusedElement() = 0;
 
+  // Returns true if the current focused element is editable.
+  virtual bool IsFocusedElementEditable() = 0;
+
   // Causes the renderer to close the current page, including running its
   // onunload event handler.  A ClosePage_ACK message will be sent to the
   // ResourceDispatcherHost when it is finished.
@@ -91,6 +94,10 @@
   // image at that location).
   virtual void CopyImageAt(int x, int y) = 0;
 
+  // Saves the image at location x, y to the disk (if there indeed is an
+  // image at that location).
+  virtual void SaveImageAt(int x, int y) = 0;
+
   // Notifies the listener that a directory enumeration is complete.
   virtual void DirectoryEnumerationFinished(
       int request_id,
@@ -187,8 +194,6 @@
   // RenderViewHostDelegate.
   virtual void SyncRendererPrefs() = 0;
 
-  virtual void ToggleSpeechInput() = 0;
-
   // Returns the current WebKit preferences.
   virtual WebPreferences GetWebkitPreferences() = 0;
 
diff --git a/content/public/browser/render_widget_host_view.h b/content/public/browser/render_widget_host_view.h
index 4c0df76..1620e24 100644
--- a/content/public/browser/render_widget_host_view.h
+++ b/content/public/browser/render_widget_host_view.h
@@ -6,6 +6,7 @@
 #define CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_VIEW_H_
 
 #include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/strings/string16.h"
 #include "content/common/content_export.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -20,10 +21,14 @@
 class Size;
 }
 
+namespace ui {
+class TextInputClient;
+}
+
 namespace content {
 
-class BrowserAccessibilityManager;
 class RenderWidgetHost;
+class RenderWidgetHostViewFrameSubscriber;
 
 // RenderWidgetHostView is an interface implemented by an object that acts as
 // the "View" portion of a RenderWidgetHost. The RenderWidgetHost and its
@@ -35,26 +40,12 @@
 //
 // RenderWidgetHostView Class Hierarchy:
 //   RenderWidgetHostView - Public interface.
-//   RenderWidgetHostViewPort - Private interface for content/ and ports.
 //   RenderWidgetHostViewBase - Common implementation between platforms.
-//   RenderWidgetHostViewWin, ... - Platform specific implementations.
+//   RenderWidgetHostViewAura, ... - Platform specific implementations.
 class CONTENT_EXPORT RenderWidgetHostView {
  public:
   virtual ~RenderWidgetHostView() {}
 
-  // Platform-specific creator. Use this to construct new RenderWidgetHostViews
-  // rather than using RenderWidgetHostViewWin & friends.
-  //
-  // This function must NOT size it, because the RenderView in the renderer
-  // wouldn't have been created yet. The widget would set its "waiting for
-  // resize ack" flag, and the ack would never come becasue no RenderView
-  // received it.
-  //
-  // The RenderWidgetHost must already be created (because we can't know if it's
-  // going to be a regular RenderWidgetHost or a RenderViewHost (a subclass).
-  static RenderWidgetHostView* CreateViewForWidget(
-      RenderWidgetHost* widget);
-
   // Initialize this object for use as a drawing area.  |parent_view| may be
   // left as NULL on platforms where a parent view is not required to initialize
   // a child window.
@@ -76,6 +67,13 @@
   virtual gfx::NativeViewId GetNativeViewId() const = 0;
   virtual gfx::NativeViewAccessible GetNativeViewAccessible() = 0;
 
+  // Returns a ui::TextInputClient to support text input or NULL if this RWHV
+  // doesn't support text input.
+  // Note: Not all the platforms use ui::InputMethod and ui::TextInputClient for
+  // text input.  Some platforms (Mac and Android for example) use their own
+  // text input system.
+  virtual ui::TextInputClient* GetTextInputClient() = 0;
+
   // Set focus to the associated View component.
   virtual void Focus() = 0;
   // Returns true if the View currently has the focus.
@@ -123,6 +121,16 @@
   // visible viewport.
   virtual void SetInsets(const gfx::Insets& insets) = 0;
 
+  // Begin subscribing for presentation events and captured frames.
+  // |subscriber| is now owned by this object, it will be called only on the
+  // UI thread.
+  virtual void BeginFrameSubscription(
+      scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) = 0;
+
+  // End subscribing for frame presentation events. FrameSubscriber will be
+  // deleted after this call.
+  virtual void EndFrameSubscription() = 0;
+
 #if defined(OS_MACOSX)
   // Set the view's active state (i.e., tint state of controls).
   virtual void SetActive(bool active) = 0;
diff --git a/content/public/browser/render_widget_host_view_frame_subscriber.h b/content/public/browser/render_widget_host_view_frame_subscriber.h
new file mode 100644
index 0000000..0b65859
--- /dev/null
+++ b/content/public/browser/render_widget_host_view_frame_subscriber.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2012 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.
+
+#ifndef CONTENT_PORT_BROWSER_RENDER_WIDGET_HOST_VIEW_FRAME_SUBSCRIBER_H_
+#define CONTENT_PORT_BROWSER_RENDER_WIDGET_HOST_VIEW_FRAME_SUBSCRIBER_H_
+
+#include "base/callback.h"
+#include "base/time/time.h"
+
+namespace gfx {
+class Rect;
+class Size;
+}  // namespace gfx
+
+namespace media {
+class VideoFrame;
+}  // namespace media
+
+namespace content {
+
+// Defines an interface for listening to events of frame presentation and to
+// instruct the platform layer (i.e. RenderWidgetHostView) to copy a frame.
+//
+// Further processing is possible (e.g. scale and color space conversion)
+// through this interface. See ShouldCaptureFrame() for details.
+//
+// It is platform dependent which thread this object lives on, but it is
+// guaranteed to be used on a single thread.
+class RenderWidgetHostViewFrameSubscriber {
+ public:
+  virtual ~RenderWidgetHostViewFrameSubscriber() {}
+
+  // Called when a captured frame is available or the frame is no longer
+  // needed by the platform layer.
+  //
+  // If |frame_captured| is true then frame provided contains valid content and
+  // |timestamp| is the time when the frame was painted.
+  //
+  // If |frame_captured| is false then the content in frame provided is
+  // invalid. There was an error during the process of frame capture or the
+  // platform layer is shutting down. |timestamp| is also invalid in this case.
+  typedef base::Callback<void(base::TimeTicks /* timestamp */,
+                              bool /* frame_captured */)> DeliverFrameCallback;
+
+  // Called when a new frame is going to be presented at time
+  // |present_time|. Implementation can decide whether the current frame should
+  // be captured or not.
+  //
+  // Return true if the current frame should be captured. If so, |storage|
+  // should will be set to hold an appropriately sized and allocated buffer
+  // into which to copy the frame. The platform presenter will perform scaling
+  // and color space conversion to fit into the output frame.
+  //
+  // Destination format is determined by |storage|, currently only
+  // media::VideoFrame::YV12 is supported. Platform layer will perform color
+  // space conversion if needed.
+  //
+  // When the frame is available |callback| will be called. It is up to the
+  // platform layer to decide when to deliver a captured frame.
+  //
+  // Return false if the current frame should not be captured.
+  virtual bool ShouldCaptureFrame(base::TimeTicks present_time,
+                                  scoped_refptr<media::VideoFrame>* storage,
+                                  DeliverFrameCallback* callback) = 0;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_PORT_BROWSER_RENDER_WIDGET_HOST_VIEW_FRAME_SUBSCRIBER_H_
diff --git a/content/public/browser/speech_recognition_session_config.h b/content/public/browser/speech_recognition_session_config.h
index 813fbd1..1cde643 100644
--- a/content/public/browser/speech_recognition_session_config.h
+++ b/content/public/browser/speech_recognition_session_config.h
@@ -22,7 +22,9 @@
   SpeechRecognitionSessionConfig();
   ~SpeechRecognitionSessionConfig();
 
+  // TODO(hans): The legacy API is dead; remove this flag (crbug.com/223198).
   bool is_legacy_api;
+
   std::string language;
   SpeechRecognitionGrammarArray grammars;
   std::string origin_url;
diff --git a/content/public/browser/speech_recognition_session_context.cc b/content/public/browser/speech_recognition_session_context.cc
index f362ef3..9b6575b 100644
--- a/content/public/browser/speech_recognition_session_context.cc
+++ b/content/public/browser/speech_recognition_session_context.cc
@@ -14,8 +14,7 @@
       guest_render_view_id(MSG_ROUTING_NONE),
       embedder_render_process_id(0),
       embedder_render_view_id(MSG_ROUTING_NONE),
-      request_id(0),
-      requested_by_page_element(true) {
+      request_id(0) {
 }
 
 SpeechRecognitionSessionContext::~SpeechRecognitionSessionContext() {
diff --git a/content/public/browser/speech_recognition_session_context.h b/content/public/browser/speech_recognition_session_context.h
index 5606b78..d092a5d 100644
--- a/content/public/browser/speech_recognition_session_context.h
+++ b/content/public/browser/speech_recognition_session_context.h
@@ -46,14 +46,6 @@
 
   int request_id;
 
-  // Determines whether recognition was requested by a page element (in which
-  // case its coordinates are passed in |element_rect|).
-  bool requested_by_page_element;
-
-  // The coordinates of the page element for placing the bubble (valid only when
-  // |requested_by_page_element| = true).
-  gfx::Rect element_rect;
-
   // A texual description of the context (website, extension name) that is
   // requesting recognition, for prompting security notifications to the user.
   std::string context_name;
diff --git a/content/public/browser/vibration_provider.h b/content/public/browser/vibration_provider.h
new file mode 100644
index 0000000..71eba76
--- /dev/null
+++ b/content/public/browser/vibration_provider.h
@@ -0,0 +1,23 @@
+// Copyright 2013 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.
+
+#ifndef CONTENT_PUBLIC_BROWSER_VIBRATION_PROVIDER_H_
+#define CONTENT_PUBLIC_BROWSER_VIBRATION_PROVIDER_H_
+
+namespace content {
+
+class VibrationProvider {
+ public:
+  // Device should start vibrating for N milliseconds.
+  virtual void Vibrate(int64 milliseconds) = 0;
+
+  // Cancels vibration of the device.
+  virtual void CancelVibration() = 0;
+
+  virtual ~VibrationProvider() {}
+};
+
+}  // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_VIBRATION_PROVIDER_H_
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index 0e0ed9b..fd31c1a 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -23,7 +23,7 @@
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/window_open_disposition.h"
 #include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/rect.h"
 
 #if defined(OS_ANDROID)
 #include "base/android/scoped_java_ref.h"
@@ -37,11 +37,6 @@
 struct WebFindOptions;
 }
 
-namespace gfx {
-class Rect;
-class Size;
-}
-
 namespace net {
 struct LoadStateWithParam;
 }
@@ -57,8 +52,8 @@
 class RenderWidgetHostView;
 class SiteInstance;
 class WebContentsDelegate;
-class WebContentsView;
 struct CustomContextMenuContext;
+struct DropData;
 struct RendererPreferences;
 
 // WebContents is the core class in content/. A WebContents renders web content
@@ -68,7 +63,7 @@
 //   scoped_ptr<content::WebContents> web_contents(
 //       content::WebContents::Create(
 //           content::WebContents::CreateParams(browser_context)));
-//   gfx::NativeView view = web_contents->GetView()->GetNativeView();
+//   gfx::NativeView view = web_contents->GetNativeView();
 //   // |view| is an HWND, NSView*, GtkWidget*, etc.; insert it into the view
 //   // hierarchy wherever it needs to go.
 //
@@ -210,9 +205,6 @@
   // NULL.
   virtual RenderWidgetHostView* GetFullscreenRenderWidgetHostView() const = 0;
 
-  // The WebContentsView will never change and is guaranteed non-NULL.
-  virtual WebContentsView* GetView() const = 0;
-
   // Create a WebUI page for the given url. In most cases, this doesn't need to
   // be called by embedders since content will create its own WebUI objects as
   // necessary. However if the embedder wants to create its own WebUI object and
@@ -372,6 +364,42 @@
 
   // Views and focus -----------------------------------------------------------
 
+  // Returns the native widget that contains the contents of the tab.
+  virtual gfx::NativeView GetNativeView() = 0;
+
+  // Returns the native widget with the main content of the tab (i.e. the main
+  // render view host, though there may be many popups in the tab as children of
+  // the container).
+  virtual gfx::NativeView GetContentNativeView() = 0;
+
+  // Returns the outermost native view. This will be used as the parent for
+  // dialog boxes.
+  virtual gfx::NativeWindow GetTopLevelNativeWindow() = 0;
+
+  // Computes the rectangle for the native widget that contains the contents of
+  // the tab in the screen coordinate system.
+  virtual gfx::Rect GetContainerBounds() = 0;
+
+  // Get the bounds of the View, relative to the parent.
+  virtual gfx::Rect GetViewBounds() = 0;
+
+  // Returns the current drop data, if any.
+  virtual DropData* GetDropData() = 0;
+
+  // Sets focus to the native widget for this tab.
+  virtual void Focus() = 0;
+
+  // Sets focus to the appropriate element when the WebContents is shown the
+  // first time.
+  virtual void SetInitialFocus() = 0;
+
+  // Stores the currently focused view.
+  virtual void StoreFocus() = 0;
+
+  // Restores focus to the last focus view. If StoreFocus has not yet been
+  // invoked, SetInitialFocus is invoked.
+  virtual void RestoreFocus() = 0;
+
   // Focuses the first (last if |reverse| is true) element in the page.
   // Invoked when this tab is getting the focus through tab traversal (|reverse|
   // is true when using Shift-Tab).
@@ -545,6 +573,24 @@
   CONTENT_EXPORT static WebContents* FromJavaWebContents(
       jobject jweb_contents_android);
   virtual base::android::ScopedJavaLocalRef<jobject> GetJavaWebContents() = 0;
+#elif defined(OS_MACOSX)
+  // The web contents view assumes that its view will never be overlapped by
+  // another view (either partially or fully). This allows it to perform
+  // optimizations. If the view is in a view hierarchy where it might be
+  // overlapped by another view, notify the view by calling this with |true|.
+  virtual void SetAllowOverlappingViews(bool overlapping) = 0;
+
+  // Returns true if overlapping views are allowed, false otherwise.
+  virtual bool GetAllowOverlappingViews() = 0;
+
+  // To draw two overlapping web contents view, the underlaying one should
+  // know about the overlaying one. Caller must ensure that |overlay| exists
+  // until |RemoveOverlayView| is called.
+  virtual void SetOverlayView(WebContents* overlay,
+                              const gfx::Point& offset) = 0;
+
+  // Removes the previously set overlay view.
+  virtual void RemoveOverlayView() = 0;
 #endif  // OS_ANDROID
 
  private:
diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc
index 5346c2a..9a26e0f 100644
--- a/content/public/browser/web_contents_delegate.cc
+++ b/content/public/browser/web_contents_delegate.cc
@@ -196,7 +196,7 @@
 }
 
 gfx::Size WebContentsDelegate::GetSizeForNewRenderView(
-    const WebContents* web_contents) const {
+   WebContents* web_contents) const {
   return gfx::Size();
 }
 
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
index d22d7c7..0edb3bd 100644
--- a/content/public/browser/web_contents_delegate.h
+++ b/content/public/browser/web_contents_delegate.h
@@ -447,8 +447,7 @@
   // This is optional for implementations of WebContentsDelegate; if the
   // delegate doesn't provide a size, the current WebContentsView's size will be
   // used.
-  virtual gfx::Size GetSizeForNewRenderView(
-      const WebContents* web_contents) const;
+  virtual gfx::Size GetSizeForNewRenderView(WebContents* web_contents) const;
 
   // Notification that validation of a form displayed by the |web_contents|
   // has failed. There can only be one message per |web_contents| at a time.
diff --git a/content/public/browser/web_contents_observer.cc b/content/public/browser/web_contents_observer.cc
index fc0fcf2..a5700a7 100644
--- a/content/public/browser/web_contents_observer.cc
+++ b/content/public/browser/web_contents_observer.cc
@@ -61,12 +61,9 @@
   return web_contents_->GetRoutingID();
 }
 
-void WebContentsObserver::WebContentsImplDestroyed() {
-  // Do cleanup so that 'this' can safely be deleted from WebContentsDestroyed.
+void WebContentsObserver::ResetWebContents() {
   web_contents_->RemoveObserver(this);
-  WebContentsImpl* contents = web_contents_;
   web_contents_ = NULL;
-  WebContentsDestroyed(contents);
 }
 
 }  // namespace content
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h
index 9fae539..23fe1b9 100644
--- a/content/public/browser/web_contents_observer.h
+++ b/content/public/browser/web_contents_observer.h
@@ -173,7 +173,7 @@
 
   // This method is invoked once the onload handler of the main frame has
   // completed.
-  virtual void DocumentOnLoadCompletedInMainFrame(int32 page_id) {}
+  virtual void DocumentOnLoadCompletedInMainFrame() {}
 
   // This method is invoked when the document in the given frame finished
   // loading. At this point, scripts marked as defer were executed, and
@@ -239,7 +239,7 @@
 
   // This method is invoked when the renderer has completed its first paint
   // after a non-empty layout.
-  virtual void DidFirstVisuallyNonEmptyPaint(int32 page_id) {}
+  virtual void DidFirstVisuallyNonEmptyPaint() {}
 
   // These two methods correspond to the points in time when the spinner of the
   // tab starts and stops spinning.
@@ -293,16 +293,15 @@
                                         WebContents* new_web_contents) {}
 
   // Invoked when the WebContents is being destroyed. Gives subclasses a chance
-  // to cleanup. At the time this is invoked |web_contents()| returns NULL.
-  // It is safe to delete 'this' from here.
-  virtual void WebContentsDestroyed(WebContents* web_contents) {}
+  // to cleanup. After the whole loop over all WebContentsObservers has been
+  // finished, web_contents() returns NULL.
+  virtual void WebContentsDestroyed() {}
 
   // Called when the user agent override for a WebContents has been changed.
   virtual void UserAgentOverrideSet(const std::string& user_agent) {}
 
   // Invoked when new FaviconURL candidates are received from the renderer.
-  virtual void DidUpdateFaviconURL(int32 page_id,
-                                   const std::vector<FaviconURL>& candidates) {}
+  virtual void DidUpdateFaviconURL(const std::vector<FaviconURL>& candidates) {}
 
   // Invoked when a pepper plugin creates and shows or destroys a fullscreen
   // render widget.
@@ -359,9 +358,7 @@
  private:
   friend class WebContentsImpl;
 
-  // Invoked from WebContentsImpl. Invokes WebContentsDestroyed and NULL out
-  // |web_contents_|.
-  void WebContentsImplDestroyed();
+  void ResetWebContents();
 
   WebContentsImpl* web_contents_;
 
diff --git a/content/public/browser/web_contents_view.h b/content/public/browser/web_contents_view.h
deleted file mode 100644
index 8405945..0000000
--- a/content/public/browser/web_contents_view.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_VIEW_H_
-#define CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_VIEW_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/process/kill.h"
-#include "content/common/content_export.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/size.h"
-
-namespace content {
-struct DropData;
-
-// The WebContentsView is an interface that is implemented by the platform-
-// dependent web contents views. The WebContents uses this interface to talk to
-// them.
-class CONTENT_EXPORT WebContentsView {
- public:
-  virtual ~WebContentsView() {}
-
-  // Returns the native widget that contains the contents of the tab.
-  virtual gfx::NativeView GetNativeView() const = 0;
-
-  // Returns the native widget with the main content of the tab (i.e. the main
-  // render view host, though there may be many popups in the tab as children of
-  // the container).
-  virtual gfx::NativeView GetContentNativeView() const = 0;
-
-  // Returns the outermost native view. This will be used as the parent for
-  // dialog boxes.
-  virtual gfx::NativeWindow GetTopLevelNativeWindow() const = 0;
-
-  // Computes the rectangle for the native widget that contains the contents of
-  // the tab in the screen coordinate system.
-  virtual void GetContainerBounds(gfx::Rect* out) const = 0;
-
-  // Helper function for GetContainerBounds. Most callers just want to know the
-  // size, and this makes it more clear.
-  gfx::Size GetContainerSize() const {
-    gfx::Rect rc;
-    GetContainerBounds(&rc);
-    return gfx::Size(rc.width(), rc.height());
-  }
-
-  // Used to notify the view that a tab has crashed.
-  virtual void OnTabCrashed(base::TerminationStatus status, int error_code) = 0;
-
-  // TODO(brettw) this is a hack. It's used in two places at the time of this
-  // writing: (1) when render view hosts switch, we need to size the replaced
-  // one to be correct, since it wouldn't have known about sizes that happened
-  // while it was hidden; (2) in constrained windows.
-  //
-  // (1) will be fixed once interstitials are cleaned up. (2) seems like it
-  // should be cleaned up or done some other way, since this works for normal
-  // WebContents without the special code.
-  virtual void SizeContents(const gfx::Size& size) = 0;
-
-  // Sets focus to the native widget for this tab.
-  virtual void Focus() = 0;
-
-  // Sets focus to the appropriate element when the WebContents is shown the
-  // first time.
-  virtual void SetInitialFocus() = 0;
-
-  // Stores the currently focused view.
-  virtual void StoreFocus() = 0;
-
-  // Restores focus to the last focus view. If StoreFocus has not yet been
-  // invoked, SetInitialFocus is invoked.
-  virtual void RestoreFocus() = 0;
-
-  // Returns the current drop data, if any.
-  virtual DropData* GetDropData() const = 0;
-
-  // Get the bounds of the View, relative to the parent.
-  virtual gfx::Rect GetViewBounds() const = 0;
-
-#if defined(OS_MACOSX)
-  // The web contents view assumes that its view will never be overlapped by
-  // another view (either partially or fully). This allows it to perform
-  // optimizations. If the view is in a view hierarchy where it might be
-  // overlapped by another view, notify the view by calling this with |true|.
-  virtual void SetAllowOverlappingViews(bool overlapping) = 0;
-
-  // Returns true if overlapping views are allowed, false otherwise.
-  virtual bool GetAllowOverlappingViews() const = 0;
-
-  // To draw two overlapping web contents view, the underlaying one should
-  // know about the overlaying one. Caller must ensure that |overlay| exists
-  // until |RemoveOverlayView| is called.
-  virtual void SetOverlayView(WebContentsView* overlay,
-                              const gfx::Point& offset) = 0;
-
-  // Removes the previously set overlay view.
-  virtual void RemoveOverlayView() = 0;
-#endif
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_VIEW_H_
diff --git a/content/public/common/child_process_sandbox_support_linux.h b/content/public/common/child_process_sandbox_support_linux.h
index 9e1cde2..58dc3ea 100644
--- a/content/public/common/child_process_sandbox_support_linux.h
+++ b/content/public/common/child_process_sandbox_support_linux.h
@@ -50,6 +50,10 @@
 CONTENT_EXPORT bool GetFontTable(int fd, uint32_t table_tag, off_t offset,
                                  uint8_t* output, size_t* output_length);
 
+// Sends a zygote child "ping" message to browser process via socket |fd|.
+// Returns true on success.
+CONTENT_EXPORT bool SendZygoteChildPing(int fd);
+
 };  // namespace content
 
 #endif  // CONTENT_PUBLIC_COMMON_CHILD_PROCESS_SANDBOX_SUPPORT_LINUX_H_
diff --git a/content/public/common/content_client.cc b/content/public/common/content_client.cc
index b1b0f9b..3a9769c 100644
--- a/content/public/common/content_client.cc
+++ b/content/public/common/content_client.cc
@@ -70,10 +70,6 @@
   return false;
 }
 
-bool ContentClient::CanHandleWhileSwappedOut(const IPC::Message& message) {
-  return false;
-}
-
 std::string ContentClient::GetProduct() const {
   return std::string();
 }
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h
index add53dd..ec52600 100644
--- a/content/public/common/content_client.h
+++ b/content/public/common/content_client.h
@@ -94,10 +94,6 @@
   // Returns whether the given message should be sent in a swapped out renderer.
   virtual bool CanSendWhileSwappedOut(const IPC::Message* message);
 
-  // Returns whether the given message should be processed in the browser on
-  // behalf of a swapped out renderer.
-  virtual bool CanHandleWhileSwappedOut(const IPC::Message& message);
-
   // Returns a string describing the embedder product name and version,
   // of the form "productname/version", with no other slashes.
   // Used as part of the user agent string.
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index f42b07f..589f694 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -161,9 +161,6 @@
 // Disable Stage3D inside of flapper.
 const char kDisableFlashStage3d[]           = "disable-flash-stage3d";
 
-// Disable deferral of scroll-ending gesture events when a scroll is active.
-const char kDisableGestureDebounce[]        = "disable-gesture-debounce";
-
 const char kDisableGestureTapHighlight[]    = "disable-gesture-tap-highlight";
 
 // Disable GL multisampling.
@@ -227,6 +224,9 @@
 // Disables LCD text.
 const char kDisableLCDText[]                = "disable-lcd-text";
 
+// Disables distance field text.
+const char kDisableDistanceFieldText[]      = "disable-distance-field-text";
+
 // Disable LocalStorage.
 const char kDisableLocalStorage[]           = "disable-local-storage";
 
@@ -282,9 +282,6 @@
 // Disables the use of a 3D software rasterizer.
 const char kDisableSoftwareRasterizer[]     = "disable-software-rasterizer";
 
-// Disables speech input.
-const char kDisableSpeechInput[]            = "disable-speech-input";
-
 // Disable False Start in SSL and TLS connections.
 const char kDisableSSLFalseStart[]          = "disable-ssl-false-start";
 
@@ -321,8 +318,8 @@
 const char kEnableBleedingEdgeRenderingFastPaths[] =
     "enable-bleeding-edge-rendering-fast-paths";
 
-// Disable gpu-accelerated 2d canvas.
-const char kEnableDeferredFilters[]         = "enable-deferred-filters";
+// Disable deferred image filters.
+const char kDisableDeferredFilters[]         = "disable-deferred-filters";
 
 // Enables accelerated compositing for backgrounds of root layers with
 // background-attachment: fixed.
@@ -337,6 +334,10 @@
 // Enables LCD text.
 const char kEnableLCDText[]                 = "enable-lcd-text";
 
+// Enables using signed distance fields when rendering text.
+// Only valid if GPU rasterization is enabled as well.
+const char kEnableDistanceFieldText[]       = "enable-distance-field-text";
+
 // Enables experimental feature that maps multiple RenderLayers to
 // one composited layer to avoid pathological layer counts.
 const char kEnableLayerSquashing[] =
@@ -447,17 +448,6 @@
 // Enables the memory benchmarking extension
 const char kEnableMemoryBenchmarking[]      = "enable-memory-benchmarking";
 
-// Make the values returned to window.performance.memory more granular and more
-// up to date in shared worker. Without this flag, the memory information is
-// still available, but it is bucketized and updated less frequently.
-const char kEnableSharedWorkerMemoryInfo[] =
-    "enable-shared-worker-memory-info";
-
-// On Windows, converts the page to the currently-installed monitor profile.
-// This does NOT enable color management for images. The source is still
-// assumed to be sRGB.
-const char kEnableMonitorProfile[]          = "enable-monitor-profile";
-
 // Enables use of cache if offline, even if it's stale
 const char kEnableOfflineCacheAccess[]      = "enable-offline-cache-access";
 
@@ -477,6 +467,12 @@
 // Enables compositor-accelerated touch-screen pinch gestures.
 const char kEnablePinch[]                   = "enable-pinch";
 
+// Make the values returned to window.performance.memory more granular and more
+// up to date in shared worker. Without this flag, the memory information is
+// still available, but it is bucketized and updated less frequently. This flag
+// also applys to workers.
+const char kEnablePreciseMemoryInfo[] = "enable-precise-memory-info";
+
 // Enable caching of pre-parsed JS script data.  See http://crbug.com/32407.
 const char kEnablePreparsedJsCaching[]      = "enable-preparsed-js-caching";
 
@@ -839,10 +835,6 @@
 // Type of the current test harness ("browser" or "ui").
 const char kTestType[]                      = "test-type";
 
-// Enable timeout-based touch event cancellation if a touch ack is delayed.
-// If unspecified, touch timeout behavior will be disabled.
-const char kTouchAckTimeoutDelayMs[]        = "touch-ack-timeout-delay-ms";
-
 const char kTouchScrollingMode[]            = "touch-scrolling-mode";
 const char kTouchScrollingModeAsyncTouchmove[] = "async-touchmove";
 const char kTouchScrollingModeSyncTouchmove[] = "sync-touchmove";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 53a4004..c8c97bca 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -46,6 +46,7 @@
 CONTENT_EXPORT extern const char kDisableDelegatedRenderer[];
 extern const char kDisableDesktopNotifications[];
 extern const char kDisableDirectNPAPIRequests[];
+CONTENT_EXPORT extern const char kDisableDistanceFieldText[];
 extern const char kDisableDomainBlockingFor3DAPIs[];
 CONTENT_EXPORT extern const char kDisableEmbeddedSharedWorker[];
 CONTENT_EXPORT extern const char kDisableExperimentalWebGL[];
@@ -55,7 +56,6 @@
 CONTENT_EXPORT extern const char kDisableFixedPositionCreatesStackingContext[];
 CONTENT_EXPORT extern const char kDisableFlash3d[];
 CONTENT_EXPORT extern const char kDisableFlashStage3d[];
-CONTENT_EXPORT extern const char kDisableGestureDebounce[];
 CONTENT_EXPORT extern const char kDisableGestureTapHighlight[];
 CONTENT_EXPORT extern const char kDisableGLMultisampling[];
 CONTENT_EXPORT extern const char kDisableGpu[];
@@ -91,7 +91,6 @@
 extern const char kDisableSiteSpecificQuirks[];
 CONTENT_EXPORT extern const char kDisableSmoothScrolling[];
 CONTENT_EXPORT extern const char kDisableSoftwareRasterizer[];
-CONTENT_EXPORT extern const char kDisableSpeechInput[];
 CONTENT_EXPORT extern const char kDisableSSLFalseStart[];
 CONTENT_EXPORT extern const char kDisableThreadedCompositing[];
 CONTENT_EXPORT extern const char kDisableUniversalAcceleratedOverflowScroll[];
@@ -101,7 +100,7 @@
 CONTENT_EXPORT extern const char kDisableZeroCopy[];
 CONTENT_EXPORT extern const char kDomAutomationController[];
 CONTENT_EXPORT extern const char kEnableBleedingEdgeRenderingFastPaths[];
-CONTENT_EXPORT extern const char kEnableDeferredFilters[];
+CONTENT_EXPORT extern const char kDisableDeferredFilters[];
 CONTENT_EXPORT extern const char kEnableAcceleratedFixedRootBackground[];
 CONTENT_EXPORT extern const char kEnableAcceleratedOverflowScroll[];
 CONTENT_EXPORT extern const char kEnableLayerSquashing[];
@@ -112,6 +111,7 @@
 CONTENT_EXPORT extern const char kEnableCompositingForTransition[];
 CONTENT_EXPORT extern const char kEnableDeferredImageDecoding[];
 CONTENT_EXPORT extern const char kEnableDelegatedRenderer[];
+CONTENT_EXPORT extern const char kEnableDistanceFieldText[];
 CONTENT_EXPORT extern const char kEnableDownloadResumption[];
 CONTENT_EXPORT extern const char kEnableEncryptedMedia[];
 CONTENT_EXPORT extern const char kEnableExperimentalCanvasFeatures[];
@@ -134,20 +134,19 @@
 CONTENT_EXPORT extern const char kEnableLCDText[];
 CONTENT_EXPORT extern const char kEnableLogging[];
 extern const char kEnableMemoryBenchmarking[];
-extern const char kEnableMonitorProfile[];
 CONTENT_EXPORT extern const char kEnableOfflineCacheAccess[];
 CONTENT_EXPORT extern const char kEnableOneCopy[];
 CONTENT_EXPORT extern const char kEnableOverlayFullscreenVideo[];
 CONTENT_EXPORT extern const char kDisableOverlayFullscreenVideoSubtitle[];
 CONTENT_EXPORT extern const char kEnableOverscrollNotifications[];
 CONTENT_EXPORT extern const char kEnablePinch[];
+CONTENT_EXPORT extern const char kEnablePreciseMemoryInfo[];
 extern const char kEnablePreparsedJsCaching[];
 CONTENT_EXPORT extern const char kEnablePrivilegedWebGLExtensions[];
 CONTENT_EXPORT extern const char kEnableRegionBasedColumns[];
 CONTENT_EXPORT extern const char kEnableRepaintAfterLayout[];
 CONTENT_EXPORT extern const char kEnableSandboxLogging[];
 extern const char kEnableSeccompFilterSandbox[];
-extern const char kEnableSharedWorkerMemoryInfo[];
 extern const char kEnableSkiaBenchmarking[];
 CONTENT_EXPORT extern const char kEnableSmoothScrolling[];
 CONTENT_EXPORT extern const char kEnableSpatialNavigation[];
@@ -237,7 +236,6 @@
 CONTENT_EXPORT extern const char kTestingFixedHttpsPort[];
 CONTENT_EXPORT extern const char kTestSandbox[];
 CONTENT_EXPORT extern const char kTestType[];
-CONTENT_EXPORT extern const char kTouchAckTimeoutDelayMs[];
 CONTENT_EXPORT extern const char kTouchScrollingMode[];
 CONTENT_EXPORT extern const char kTouchScrollingModeAsyncTouchmove[];
 CONTENT_EXPORT extern const char kTouchScrollingModeSyncTouchmove[];
diff --git a/content/public/common/context_menu_params.cc b/content/public/common/context_menu_params.cc
index 8289be0..54b48c2 100644
--- a/content/public/common/context_menu_params.cc
+++ b/content/public/common/context_menu_params.cc
@@ -21,7 +21,6 @@
       has_image_contents(true),
       media_flags(0),
       misspelling_hash(0),
-      speech_input_enabled(false),
       spellcheck_enabled(false),
       is_editable(false),
       writing_direction_default(
diff --git a/content/public/common/context_menu_params.h b/content/public/common/context_menu_params.h
index ccdb473..ccef48e 100644
--- a/content/public/common/context_menu_params.h
+++ b/content/public/common/context_menu_params.h
@@ -112,9 +112,6 @@
   // and the misspelled_word is not empty.
   std::vector<base::string16> dictionary_suggestions;
 
-  // If editable, flag for whether node is speech-input enabled.
-  bool speech_input_enabled;
-
   // If editable, flag for whether spell check is enabled or not.
   bool spellcheck_enabled;
 
diff --git a/content/public/common/media_stream_request.cc b/content/public/common/media_stream_request.cc
index 4a4bf72..fa12fc8 100644
--- a/content/public/common/media_stream_request.cc
+++ b/content/public/common/media_stream_request.cc
@@ -67,6 +67,22 @@
       input.channel_layout == input_second.channel_layout;
 }
 
+MediaStreamDevices::MediaStreamDevices() {}
+
+MediaStreamDevices::MediaStreamDevices(size_t count,
+                                       const MediaStreamDevice& value)
+    : std::vector<MediaStreamDevice>(count, value) {
+}
+
+const MediaStreamDevice* MediaStreamDevices::FindById(
+    const std::string& device_id) const {
+  for (const_iterator iter = begin(); iter != end(); ++iter) {
+    if (iter->id == device_id)
+      return &(*iter);
+  }
+  return NULL;
+}
+
 MediaStreamRequest::MediaStreamRequest(
     int render_process_id,
     int render_view_id,
diff --git a/content/public/common/media_stream_request.h b/content/public/common/media_stream_request.h
index 7a58061..37172c0 100644
--- a/content/public/common/media_stream_request.h
+++ b/content/public/common/media_stream_request.h
@@ -46,7 +46,7 @@
   MEDIA_DEVICE_ACCESS = 0,
   MEDIA_GENERATE_STREAM,
   MEDIA_ENUMERATE_DEVICES,
-  MEDIA_OPEN_DEVICE
+  MEDIA_OPEN_DEVICE  // Only used in requests made by Pepper.
 };
 
 // Facing mode for video capture.
@@ -164,7 +164,16 @@
   AudioDeviceParameters matched_output;
 };
 
-typedef std::vector<MediaStreamDevice> MediaStreamDevices;
+class CONTENT_EXPORT MediaStreamDevices
+    : public std::vector<MediaStreamDevice> {
+ public:
+  MediaStreamDevices();
+  MediaStreamDevices(size_t count, const MediaStreamDevice& value);
+
+  // Looks for a MediaStreamDevice based on its ID.
+  // Returns NULL if not found.
+  const MediaStreamDevice* FindById(const std::string& device_id) const;
+};
 
 typedef std::map<MediaStreamType, MediaStreamDevices> MediaStreamDeviceMap;
 
diff --git a/content/public/common/page_state.h b/content/public/common/page_state.h
index c05e65e..c38f961 100644
--- a/content/public/common/page_state.h
+++ b/content/public/common/page_state.h
@@ -23,9 +23,7 @@
 // example the URLs of the documents and the values of any form fields.  This
 // information is used when navigating back & forward through session history.
 //
-// The browser process only sees the encoded form of the data, which is
-// designed as an archival format.  The renderer process can decode the data
-// using methods found in public/renderer/history_item_serialization.h.
+// The format of the encoded data is not exposed by the content API.
 class CONTENT_EXPORT PageState {
  public:
   static PageState CreateFromEncodedData(const std::string& data);
diff --git a/content/public/common/url_constants.cc b/content/public/common/url_constants.cc
index 389e022..278cb7b 100644
--- a/content/public/common/url_constants.cc
+++ b/content/public/common/url_constants.cc
@@ -18,8 +18,6 @@
 const char kFileSystemScheme[] = "filesystem";
 const char kFtpScheme[] = "ftp";
 const char kGuestScheme[] = "chrome-guest";
-const char kHttpScheme[] = "http";
-const char kHttpsScheme[] = "https";
 const char kJavaScriptScheme[] = "javascript";
 const char kMailToScheme[] = "mailto";
 const char kMetadataScheme[] = "metadata";
diff --git a/content/public/common/url_constants.h b/content/public/common/url_constants.h
index 194bb3a..f2f7078 100644
--- a/content/public/common/url_constants.h
+++ b/content/public/common/url_constants.h
@@ -6,6 +6,7 @@
 #define CONTENT_PUBLIC_COMMON_URL_CONSTANTS_H_
 
 #include "content/common/content_export.h"
+#include "url/url_constants.h"
 
 // Contains constants for known URLs and portions thereof.
 
@@ -23,8 +24,6 @@
 CONTENT_EXPORT extern const char kFileSystemScheme[];
 CONTENT_EXPORT extern const char kFtpScheme[];
 CONTENT_EXPORT extern const char kGuestScheme[];
-CONTENT_EXPORT extern const char kHttpScheme[];
-CONTENT_EXPORT extern const char kHttpsScheme[];
 CONTENT_EXPORT extern const char kJavaScriptScheme[];
 CONTENT_EXPORT extern const char kMailToScheme[];
 CONTENT_EXPORT extern const char kMetadataScheme[];
diff --git a/content/public/common/zygote_fork_delegate_linux.h b/content/public/common/zygote_fork_delegate_linux.h
index 39833c5..66f99cd 100644
--- a/content/public/common/zygote_fork_delegate_linux.h
+++ b/content/public/common/zygote_fork_delegate_linux.h
@@ -49,11 +49,11 @@
   enum {
     // Used to pass in the descriptor for talking to the Browser
     kBrowserFDIndex,
-    // The next two are used in the protocol for discovering the
-    // child processes real PID from within the SUID sandbox. See
-    // http://code.google.com/p/chromium/wiki/LinuxZygote
-    kDummyFDIndex,
-    kParentFDIndex,
+    // The PID oracle is used in the protocol for discovering the
+    // child process's real PID from within the SUID sandbox.
+    // The child process is required to write to the socket after
+    // successfully forking.
+    kPIDOracleFDIndex,
     kNumPassedFDs  // Number of FDs in the vector passed to Fork().
   };
 
diff --git a/content/public/renderer/render_view_observer.h b/content/public/renderer/render_view_observer.h
index 0f09571..69ae18c 100644
--- a/content/public/renderer/render_view_observer.h
+++ b/content/public/renderer/render_view_observer.h
@@ -27,7 +27,6 @@
 class WebFormElement;
 class WebGestureEvent;
 class WebLocalFrame;
-class WebMediaPlayerClient;
 class WebMouseEvent;
 class WebNode;
 class WebTouchEvent;
@@ -81,8 +80,6 @@
                                    blink::WebDataSource* ds) {}
   virtual void PrintPage(blink::WebLocalFrame* frame, bool user_initiated) {}
   virtual void FocusedNodeChanged(const blink::WebNode& node) {}
-  virtual void WillCreateMediaPlayer(blink::WebLocalFrame* frame,
-                                     blink::WebMediaPlayerClient* client) {}
   virtual void ZoomLevelChanged() {};
   virtual void DidChangeScrollOffset(blink::WebLocalFrame* frame) {}
   virtual void DraggableRegionsChanged(blink::WebFrame* frame) {}
@@ -108,7 +105,7 @@
   // These match incoming IPCs.
   virtual void Navigate(const GURL& url) {}
   virtual void ClosePage() {}
-  virtual void OrientationChangeEvent(int orientation) {}
+  virtual void OrientationChangeEvent() {}
 
   virtual void OnStop() {}
 
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java
index f8b5cf1..299e3de 100644
--- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java
+++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/DOMUtils.java
@@ -30,15 +30,15 @@
         sb.append("(function() {");
         sb.append("  var node = document.getElementById('" + nodeId + "');");
         sb.append("  if (!node) return null;");
-        sb.append("  var width = node.offsetWidth;");
-        sb.append("  var height = node.offsetHeight;");
+        sb.append("  var width = Math.round(node.offsetWidth);");
+        sb.append("  var height = Math.round(node.offsetHeight);");
         sb.append("  var x = -window.scrollX;");
         sb.append("  var y = -window.scrollY;");
         sb.append("  do {");
         sb.append("    x += node.offsetLeft;");
         sb.append("    y += node.offsetTop;");
         sb.append("  } while (node = node.offsetParent);");
-        sb.append("  return [ x, y, width, height ];");
+        sb.append("  return [ Math.round(x), Math.round(y), width, height ];");
         sb.append("})();");
 
         String jsonText = JavaScriptUtils.executeJavaScriptAndWaitForResult(
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index d0a33f0..c6216d4 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -217,15 +217,8 @@
     use_osmesa = false;
 #endif
 
-  if (command_line->HasSwitch(switches::kUseGL)) {
-    NOTREACHED() <<
-        "kUseGL should not be used with tests. Try kUseGpuInTests instead.";
-  }
-
-  if (use_osmesa && !use_software_compositing_) {
-    command_line->AppendSwitchASCII(
-        switches::kUseGL, gfx::kGLImplementationOSMesaName);
-  }
+  if (use_osmesa && !use_software_compositing_)
+    command_line->AppendSwitch(switches::kOverrideUseGLWithOSMesaForTests);
 
   scoped_refptr<net::HostResolverProc> local_resolver =
       new LocalHostResolverProc();
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index d81f391..60b2b0e 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -14,6 +14,7 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/test/test_timeouts.h"
 #include "base/values.h"
+#include "content/browser/web_contents/web_contents_view.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/dom_operation_notification_details.h"
 #include "content/public/browser/notification_service.h"
@@ -23,7 +24,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/test/test_utils.h"
 #include "grit/webui_resources.h"
 #include "net/base/filename_util.h"
@@ -221,8 +221,8 @@
 void SimulateMouseClick(WebContents* web_contents,
                         int modifiers,
                         blink::WebMouseEvent::Button button) {
-  int x = web_contents->GetView()->GetContainerSize().width() / 2;
-  int y = web_contents->GetView()->GetContainerSize().height() / 2;
+  int x = web_contents->GetContainerBounds().width() / 2;
+  int y = web_contents->GetContainerBounds().height() / 2;
   SimulateMouseClickAt(web_contents, modifiers, button, gfx::Point(x, y));
 }
 
@@ -237,8 +237,7 @@
   mouse_event.y = point.y();
   mouse_event.modifiers = modifiers;
   // Mac needs globalX/globalY for events to plugins.
-  gfx::Rect offset;
-  web_contents->GetView()->GetContainerBounds(&offset);
+  gfx::Rect offset = web_contents->GetContainerBounds();
   mouse_event.globalX = point.x() + offset.x();
   mouse_event.globalY = point.y() + offset.y();
   mouse_event.clickCount = 1;
@@ -599,8 +598,7 @@
   message_loop_runner_->Run();
 }
 
-void WebContentsDestroyedWatcher::WebContentsDestroyed(
-    WebContents* web_contents) {
+void WebContentsDestroyedWatcher::WebContentsDestroyed() {
   message_loop_runner_->Quit();
 }
 
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index 63d68bd..85a81e3 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -223,7 +223,7 @@
 
  private:
   // Overridden WebContentsObserver methods.
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   scoped_refptr<MessageLoopRunner> message_loop_runner_;
 
diff --git a/content/public/test/layouttest_support.h b/content/public/test/layouttest_support.h
index a96b0a7..9833988 100644
--- a/content/public/test/layouttest_support.h
+++ b/content/public/test/layouttest_support.h
@@ -22,6 +22,7 @@
 namespace content {
 
 class PageState;
+class RenderFrame;
 class RenderView;
 class WebTestProxyBase;
 
@@ -80,6 +81,9 @@
 // Set the device scale factor and force the compositor to resize.
 void SetDeviceScaleFactor(RenderView* render_view, float factor);
 
+// Set the device color profile associated with the profile |name|.
+void SetDeviceColorProfile(RenderView* render_view, const std::string& name);
+
 // Enables or disables synchronous resize mode. When enabled, all window-sizing
 // machinery is short-circuited inside the renderer. This mode is necessary for
 // some tests that were written before browsers had multi-process architecture
@@ -94,8 +98,8 @@
 void DisableAutoResizeMode(RenderView* render_view,
                            const blink::WebSize& new_size);
 
-// Forces the |render_view| to use mock media streams.
-void UseMockMediaStreams(RenderView* render_view);
+// Forces the |render_frame| to use mock media streams.
+void UseMockMediaStreams(RenderFrame* render_frame);
 
 // Provides a text dump of the contents of the given page state.
 std::string DumpBackForwardList(std::vector<PageState>& page_state,
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
index 994c7be..43b1e16 100644
--- a/content/public/test/render_view_test.cc
+++ b/content/public/test/render_view_test.cc
@@ -20,6 +20,7 @@
 #include "content/renderer/render_view_impl.h"
 #include "content/renderer/renderer_main_platform_delegate.h"
 #include "content/renderer/renderer_webkitplatformsupport_impl.h"
+#include "content/test/frame_load_waiter.h"
 #include "content/test/mock_render_process.h"
 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
 #include "third_party/WebKit/public/platform/WebURLRequest.h"
@@ -117,12 +118,10 @@
   std::string url_str = "data:text/html;charset=utf-8,";
   url_str.append(html);
   GURL url(url_str);
-
   GetMainFrame()->loadRequest(WebURLRequest(url));
-
   // The load actually happens asynchronously, so we pump messages to process
   // the pending continuation.
-  ProcessPendingMessages();
+  FrameLoadWaiter(view_->GetMainRenderFrame()).Wait();
 }
 
 void RenderViewTest::GoBack(const PageState& state) {
@@ -268,14 +267,15 @@
     "    var parent_coordinates = GetCoordinates(elem.offsetParent);"
     "    coordinates[0] += parent_coordinates[0];"
     "    coordinates[1] += parent_coordinates[1];"
-    "    return coordinates;"
+    "    return [ Math.round(coordinates[0]),"
+    "             Math.round(coordinates[1])];"
     "  };"
     "  var elem = document.getElementById('$1');"
     "  if (!elem)"
     "    return null;"
     "  var bounds = GetCoordinates(elem);"
-    "  bounds[2] = elem.offsetWidth;"
-    "  bounds[3] = elem.offsetHeight;"
+    "  bounds[2] = Math.round(elem.offsetWidth);"
+    "  bounds[3] = Math.round(elem.offsetHeight);"
     "  return bounds;"
     "})();";
 gfx::Rect RenderViewTest::GetElementBounds(const std::string& element_id) {
@@ -341,6 +341,7 @@
   params.navigation_type = FrameMsg_Navigate_Type::RELOAD;
   RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
   impl->main_render_frame()->OnNavigate(params);
+  FrameLoadWaiter(impl->main_render_frame()).Wait();
 }
 
 uint32 RenderViewTest::GetNavigationIPCType() {
@@ -424,7 +425,7 @@
 
   // The load actually happens asynchronously, so we pump messages to process
   // the pending continuation.
-  ProcessPendingMessages();
+  FrameLoadWaiter(view_->GetMainRenderFrame()).Wait();
 }
 
 }  // namespace content
diff --git a/content/public/test/render_widget_test.cc b/content/public/test/render_widget_test.cc
index 66c4aba..b86753b 100644
--- a/content/public/test/render_widget_test.cc
+++ b/content/public/test/render_widget_test.cc
@@ -13,6 +13,7 @@
 #include "content/renderer/render_view_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/WebKit/public/platform/WebScreenOrientationType.h"
 #include "third_party/WebKit/public/platform/WebSize.h"
 #include "third_party/WebKit/public/web/WebView.h"
 #include "ui/gfx/codec/jpeg_codec.h"
@@ -74,6 +75,16 @@
   resize_params.physical_backing_size = gfx::Size();
   widget->OnResize(resize_params);
   EXPECT_FALSE(widget->next_paint_is_resize_ack());
+
+  // Changing the screen info should not send the ack.
+  resize_params.screen_info.orientationAngle = 90;
+  widget->OnResize(resize_params);
+  EXPECT_FALSE(widget->next_paint_is_resize_ack());
+
+  resize_params.screen_info.orientationType =
+      blink::WebScreenOrientationPortraitPrimary;
+  widget->OnResize(resize_params);
+  EXPECT_FALSE(widget->next_paint_is_resize_ack());
 }
 
 }  // namespace content
diff --git a/content/public/test/test_browser_context.cc b/content/public/test/test_browser_context.cc
index 20b7b88..bfbeb80 100644
--- a/content/public/test/test_browser_context.cc
+++ b/content/public/test/test_browser_context.cc
@@ -143,6 +143,11 @@
   return NULL;
 }
 
+BrowserPluginGuestManagerDelegate*
+    TestBrowserContext::GetGuestManagerDelegate() {
+  return NULL;
+}
+
 quota::SpecialStoragePolicy* TestBrowserContext::GetSpecialStoragePolicy() {
   return special_storage_policy_.get();
 }
diff --git a/content/public/test/test_browser_context.h b/content/public/test/test_browser_context.h
index 9019330..ea2f5f2 100644
--- a/content/public/test/test_browser_context.h
+++ b/content/public/test/test_browser_context.h
@@ -64,6 +64,8 @@
   virtual ResourceContext* GetResourceContext() OVERRIDE;
   virtual GeolocationPermissionContext*
       GetGeolocationPermissionContext() OVERRIDE;
+  virtual content::BrowserPluginGuestManagerDelegate*
+      GetGuestManagerDelegate() OVERRIDE;
   virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
 
  private:
diff --git a/content/public/test/test_navigation_observer.cc b/content/public/test/test_navigation_observer.cc
index cad43a8..bfe74f6 100644
--- a/content/public/test/test_navigation_observer.cc
+++ b/content/public/test/test_navigation_observer.cc
@@ -34,8 +34,8 @@
     parent_->OnDidAttachInterstitialPage(web_contents());
   }
 
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
-    parent_->OnWebContentsDestroyed(this, web_contents);
+  virtual void WebContentsDestroyed() OVERRIDE {
+    parent_->OnWebContentsDestroyed(this, web_contents());
   }
 
   virtual void DidStartLoading(RenderViewHost* render_view_host) OVERRIDE {
diff --git a/content/renderer/accessibility/blink_ax_enum_conversion.cc b/content/renderer/accessibility/blink_ax_enum_conversion.cc
index 63c8f30..724b145 100644
--- a/content/renderer/accessibility/blink_ax_enum_conversion.cc
+++ b/content/renderer/accessibility/blink_ax_enum_conversion.cc
@@ -138,6 +138,8 @@
       return ui::AX_ROLE_DRAWER;
     case blink::WebAXRoleEditableText:
       return ui::AX_ROLE_EDITABLE_TEXT;
+    case blink::WebAXRoleEmbeddedObject:
+      return ui::AX_ROLE_EMBEDDED_OBJECT;
     case blink::WebAXRoleFooter:
       return ui::AX_ROLE_FOOTER;
     case blink::WebAXRoleForm:
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc
index cf04584..3f7ef26 100644
--- a/content/renderer/browser_plugin/browser_plugin.cc
+++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -981,20 +981,44 @@
 
   const blink::WebInputEvent* modified_event = &event;
   scoped_ptr<blink::WebTouchEvent> touch_event;
-  // WebKit gives BrowserPlugin a list of touches that are down, but the browser
-  // process expects a list of all touches. We modify the TouchEnd event here to
-  // match these expectations.
-  if (event.type == blink::WebInputEvent::TouchEnd) {
+  if (blink::WebInputEvent::isTouchEventType(event.type)) {
     const blink::WebTouchEvent* orig_touch_event =
         static_cast<const blink::WebTouchEvent*>(&event);
+
     touch_event.reset(new blink::WebTouchEvent());
     memcpy(touch_event.get(), orig_touch_event, sizeof(blink::WebTouchEvent));
-    if (touch_event->changedTouchesLength > 0) {
-      memcpy(&touch_event->touches[touch_event->touchesLength],
-             &touch_event->changedTouches,
-            touch_event->changedTouchesLength * sizeof(blink::WebTouchPoint));
+
+    // TODO(bokan): Blink passes back a WebGestureEvent with a touches,
+    // changedTouches, and targetTouches lists; however, it doesn't set
+    // the state field on the touches which is what the RenderWidget uses
+    // to create a WebCore::TouchEvent. crbug.com/358132 tracks removing
+    // these multiple lists from WebTouchEvent since they lead to misuse
+    // like this and are functionally unused. In the mean time we'll setup
+    // the state field here manually to fix multi-touch BrowserPlugins.
+    for (size_t i = 0; i < touch_event->touchesLength; ++i) {
+      blink::WebTouchPoint& touch = touch_event->touches[i];
+      touch.state = blink::WebTouchPoint::StateStationary;
+      for (size_t j = 0; j < touch_event->changedTouchesLength; ++j) {
+        blink::WebTouchPoint& changed_touch = touch_event->changedTouches[j];
+        if (touch.id == changed_touch.id) {
+          touch.state = changed_touch.state;
+          break;
+        }
+      }
     }
-    touch_event->touchesLength += touch_event->changedTouchesLength;
+
+    // For End and Cancel, Blink gives BrowserPlugin a list of touches that
+    // are down, but the browser process expects a list of all touches. We
+    // modify these events here to match these expectations.
+    if (event.type == blink::WebInputEvent::TouchEnd ||
+        event.type == blink::WebInputEvent::TouchCancel) {
+      if (touch_event->changedTouchesLength > 0) {
+        memcpy(&touch_event->touches[touch_event->touchesLength],
+               &touch_event->changedTouches,
+              touch_event->changedTouchesLength * sizeof(blink::WebTouchPoint));
+        touch_event->touchesLength += touch_event->changedTouchesLength;
+      }
+    }
     modified_event = touch_event.get();
   }
 
diff --git a/content/renderer/context_menu_params_builder.cc b/content/renderer/context_menu_params_builder.cc
index d56c6ea..48355e8 100644
--- a/content/renderer/context_menu_params_builder.cc
+++ b/content/renderer/context_menu_params_builder.cc
@@ -32,7 +32,6 @@
   params.selection_text = data.selectedText;
   params.misspelled_word = data.misspelledWord;
   params.misspelling_hash = data.misspellingHash;
-  params.speech_input_enabled = data.isSpeechInputEnabled;
   params.spellcheck_enabled = data.isSpellCheckingEnabled;
   params.is_editable = data.isEditable;
   params.writing_direction_default = data.writingDirectionDefault;
diff --git a/content/renderer/gamepad_shared_memory_reader.cc b/content/renderer/gamepad_shared_memory_reader.cc
index 23edeb3..f1b1e83 100644
--- a/content/renderer/gamepad_shared_memory_reader.cc
+++ b/content/renderer/gamepad_shared_memory_reader.cc
@@ -6,19 +6,28 @@
 
 #include "base/debug/trace_event.h"
 #include "base/metrics/histogram.h"
-#include "content/common/gamepad_messages.h"
 #include "content/common/gamepad_user_gesture.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/common/gamepad_hardware_buffer.h"
 #include "ipc/ipc_sync_message_filter.h"
+#include "third_party/WebKit/public/platform/WebGamepadListener.h"
 
 namespace content {
 
 GamepadSharedMemoryReader::GamepadSharedMemoryReader()
     : gamepad_hardware_buffer_(NULL),
+      gamepad_listener_(NULL),
+      is_polling_(false),
       ever_interacted_with_(false) {
+}
+
+void GamepadSharedMemoryReader::StartPollingIfNecessary() {
+  if (is_polling_)
+    return;
+
   CHECK(RenderThread::Get()->Send(new GamepadHostMsg_StartPolling(
       &renderer_shared_memory_handle_)));
+
   // If we don't get a valid handle from the browser, don't try to Map (we're
   // probably out of memory or file handles).
   bool valid_handle = base::SharedMemory::IsHandleValid(
@@ -26,6 +35,7 @@
   UMA_HISTOGRAM_BOOLEAN("Gamepad.ValidSharedMemoryHandle", valid_handle);
   if (!valid_handle)
     return;
+
   renderer_shared_memory_.reset(
       new base::SharedMemory(renderer_shared_memory_handle_, true));
   CHECK(renderer_shared_memory_->Map(sizeof(GamepadHardwareBuffer)));
@@ -33,9 +43,25 @@
   CHECK(memory);
   gamepad_hardware_buffer_ =
       static_cast<GamepadHardwareBuffer*>(memory);
+
+  is_polling_ = true;
+}
+
+void GamepadSharedMemoryReader::StopPollingIfNecessary() {
+  if (is_polling_) {
+    RenderThread::Get()->Send(new GamepadHostMsg_StopPolling());
+    is_polling_ = false;
+  }
 }
 
 void GamepadSharedMemoryReader::SampleGamepads(blink::WebGamepads& gamepads) {
+  // Blink should set the listener before start sampling.
+  CHECK(gamepad_listener_);
+
+  StartPollingIfNecessary();
+  if (!is_polling_)
+    return;
+
   // ==========
   //   DANGER
   // ==========
@@ -88,8 +114,45 @@
   }
 }
 
+void GamepadSharedMemoryReader::SetGamepadListener(
+    blink::WebGamepadListener* listener) {
+  gamepad_listener_ = listener;
+  if (gamepad_listener_) {
+    // Polling has to be started rigth now and not just on the first sampling
+    // because want to get connection events from now.
+    StartPollingIfNecessary();
+  } else {
+    StopPollingIfNecessary();
+  }
+}
+
 GamepadSharedMemoryReader::~GamepadSharedMemoryReader() {
-  RenderThread::Get()->Send(new GamepadHostMsg_StopPolling());
+  StopPollingIfNecessary();
+}
+
+bool GamepadSharedMemoryReader::OnControlMessageReceived(
+    const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(GamepadSharedMemoryReader, message)
+    IPC_MESSAGE_HANDLER(GamepadMsg_GamepadConnected, OnGamepadConnected)
+    IPC_MESSAGE_HANDLER(GamepadMsg_GamepadDisconnected, OnGamepadDisconnected)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+void GamepadSharedMemoryReader::OnGamepadConnected(
+    int index,
+    const blink::WebGamepad& gamepad) {
+  if (gamepad_listener_)
+    gamepad_listener_->didConnectGamepad(index, gamepad);
+}
+
+void GamepadSharedMemoryReader::OnGamepadDisconnected(
+    int index,
+    const blink::WebGamepad& gamepad) {
+  if (gamepad_listener_)
+    gamepad_listener_->didDisconnectGamepad(index, gamepad);
 }
 
 } // namespace content
diff --git a/content/renderer/gamepad_shared_memory_reader.h b/content/renderer/gamepad_shared_memory_reader.h
index 08dc41a..3846176 100644
--- a/content/renderer/gamepad_shared_memory_reader.h
+++ b/content/renderer/gamepad_shared_memory_reader.h
@@ -7,23 +7,40 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/shared_memory.h"
+#include "content/common/gamepad_messages.h"
+#include "content/public/renderer/render_process_observer.h"
 #include "third_party/WebKit/public/platform/WebGamepads.h"
 
+namespace blink { class WebGamepadListener; }
+
 namespace content {
 
 struct GamepadHardwareBuffer;
 
-class GamepadSharedMemoryReader {
+class GamepadSharedMemoryReader : public RenderProcessObserver {
  public:
   GamepadSharedMemoryReader();
   virtual ~GamepadSharedMemoryReader();
-  void SampleGamepads(blink::WebGamepads&);
+
+  void SampleGamepads(blink::WebGamepads& gamepads);
+  void SetGamepadListener(blink::WebGamepadListener* listener);
+
+  // RenderProcessObserver implementation.
+  virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE;
 
  private:
+  void OnGamepadConnected(int index, const blink::WebGamepad& gamepad);
+  void OnGamepadDisconnected(int index, const blink::WebGamepad& gamepad);
+
+  void StartPollingIfNecessary();
+  void StopPollingIfNecessary();
+
   base::SharedMemoryHandle renderer_shared_memory_handle_;
   scoped_ptr<base::SharedMemory> renderer_shared_memory_;
   GamepadHardwareBuffer* gamepad_hardware_buffer_;
+  blink::WebGamepadListener* gamepad_listener_;
 
+  bool is_polling_;
   bool ever_interacted_with_;
 };
 
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index 6d58b51..9ea0cda 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -23,6 +23,9 @@
 #include "cc/debug/layer_tree_debug_state.h"
 #include "cc/debug/micro_benchmark.h"
 #include "cc/layers/layer.h"
+#include "cc/output/copy_output_request.h"
+#include "cc/output/copy_output_result.h"
+#include "cc/resources/single_release_callback.h"
 #include "cc/trees/layer_tree_host.h"
 #include "content/child/child_shared_bitmap_manager.h"
 #include "content/common/content_switches_internal.h"
@@ -31,8 +34,10 @@
 #include "content/renderer/input/input_handler_manager.h"
 #include "content/renderer/render_thread_impl.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
+#include "third_party/WebKit/public/platform/WebCompositeAndReadbackAsyncCallback.h"
 #include "third_party/WebKit/public/platform/WebSize.h"
 #include "third_party/WebKit/public/web/WebWidget.h"
+#include "ui/gfx/frame_time.h"
 #include "ui/gl/gl_switches.h"
 #include "ui/native_theme/native_theme_switches.h"
 #include "webkit/renderer/compositor_bindings/web_layer_impl.h"
@@ -140,18 +145,22 @@
   if (render_thread) {
     settings.impl_side_painting =
         render_thread->is_impl_side_painting_enabled();
-    if (render_thread->is_gpu_rasterization_forced())
-      settings.rasterization_site = cc::LayerTreeSettings::GpuRasterization;
-    else if (render_thread->is_gpu_rasterization_enabled())
-      settings.rasterization_site = cc::LayerTreeSettings::HybridRasterization;
-    else
-      settings.rasterization_site = cc::LayerTreeSettings::CpuRasterization;
+    settings.gpu_rasterization_forced =
+        render_thread->is_gpu_rasterization_forced();
+    settings.gpu_rasterization_enabled =
+        render_thread->is_gpu_rasterization_enabled();
     settings.create_low_res_tiling = render_thread->is_low_res_tiling_enabled();
     settings.can_use_lcd_text = render_thread->is_lcd_text_enabled();
+    settings.use_distance_field_text =
+        render_thread->is_distance_field_text_enabled();
     settings.use_zero_copy = render_thread->is_zero_copy_enabled();
     settings.use_one_copy = render_thread->is_one_copy_enabled();
   }
 
+  if (cmd->HasSwitch(switches::kEnableBleedingEdgeRenderingFastPaths)) {
+    settings.recording_mode = cc::LayerTreeSettings::RecordWithSkRecord;
+  }
+
   settings.calculate_top_controls_position =
       cmd->HasSwitch(cc::switches::kEnableTopControlsPositionCalculation);
   if (cmd->HasSwitch(cc::switches::kTopControlsHeight)) {
@@ -255,11 +264,16 @@
 
 #if defined(OS_ANDROID)
   settings.max_partial_texture_updates = 0;
-  settings.scrollbar_animator = cc::LayerTreeSettings::LinearFade;
-  settings.solid_color_scrollbar_color =
-      (widget->UsingSynchronousRendererCompositor())  // It is Android Webview.
-          ? SK_ColorTRANSPARENT
-          : SkColorSetARGB(128, 128, 128, 128);
+  if (widget->UsingSynchronousRendererCompositor()) {
+    // Android WebView uses system scrollbars, so make ours invisible.
+    settings.scrollbar_animator = cc::LayerTreeSettings::NoAnimator;
+    settings.solid_color_scrollbar_color = SK_ColorTRANSPARENT;
+  } else {
+    settings.scrollbar_animator = cc::LayerTreeSettings::LinearFade;
+    settings.scrollbar_fade_delay_ms = 300;
+    settings.scrollbar_fade_duration_ms = 300;
+    settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
+  }
   settings.highp_threshold_min = 2048;
   // Android WebView handles root layer flings itself.
   settings.ignore_root_layer_flings =
@@ -297,6 +311,8 @@
     settings.scrollbar_animator = cc::LayerTreeSettings::LinearFade;
     settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
   }
+  settings.scrollbar_fade_delay_ms = 500;
+  settings.scrollbar_fade_duration_ms = 300;
 #endif
 
   compositor->Initialize(settings);
@@ -549,6 +565,31 @@
                                                 rect_in_device_viewport);
 }
 
+void CompositeAndReadbackAsyncCallback(
+    blink::WebCompositeAndReadbackAsyncCallback* callback,
+    scoped_ptr<cc::CopyOutputResult> result) {
+  if (result->HasBitmap()) {
+    scoped_ptr<SkBitmap> result_bitmap = result->TakeBitmap();
+    callback->didCompositeAndReadback(*result_bitmap);
+  } else {
+    callback->didCompositeAndReadback(SkBitmap());
+  }
+}
+
+void RenderWidgetCompositor::compositeAndReadbackAsync(
+    blink::WebCompositeAndReadbackAsyncCallback* callback) {
+  DCHECK(layer_tree_host_->root_layer());
+  scoped_ptr<cc::CopyOutputRequest> request =
+      cc::CopyOutputRequest::CreateBitmapRequest(
+          base::Bind(&CompositeAndReadbackAsyncCallback, callback));
+  layer_tree_host_->root_layer()->RequestCopyOfOutput(request.Pass());
+  if (!threaded_) {
+    widget_->webwidget()->animate(0.0);
+    widget_->webwidget()->layout();
+    layer_tree_host_->Composite(gfx::FrameTime::Now());
+  }
+}
+
 void RenderWidgetCompositor::finishAllRendering() {
   layer_tree_host_->FinishAllRendering();
 }
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h
index c1578d5..6c493ea 100644
--- a/content/renderer/gpu/render_widget_compositor.h
+++ b/content/renderer/gpu/render_widget_compositor.h
@@ -101,6 +101,8 @@
   virtual bool commitRequested() const;
   virtual void didStopFlinging();
   virtual bool compositeAndReadback(void *pixels, const blink::WebRect& rect);
+  virtual void compositeAndReadbackAsync(
+      blink::WebCompositeAndReadbackAsyncCallback* callback);
   virtual void finishAllRendering();
   virtual void setDeferCommits(bool defer_commits);
   virtual void registerForAnimations(blink::WebLayer* layer);
diff --git a/content/renderer/ico_image_decoder_unittest.cc b/content/renderer/ico_image_decoder_unittest.cc
index b59cfe3..1cfb6fe 100644
--- a/content/renderer/ico_image_decoder_unittest.cc
+++ b/content/renderer/ico_image_decoder_unittest.cc
@@ -18,7 +18,8 @@
   }
 };
 
-TEST_F(ICOImageDecoderTest, Decoding) {
+// crbug.com/371332
+TEST_F(ICOImageDecoderTest, DISABLED_Decoding) {
   TestDecoding();
 }
 
diff --git a/content/renderer/input/input_event_filter.h b/content/renderer/input/input_event_filter.h
index e79f5a7..88a8518 100644
--- a/content/renderer/input/input_event_filter.h
+++ b/content/renderer/input/input_event_filter.h
@@ -11,7 +11,7 @@
 #include "base/callback_forward.h"
 #include "base/synchronization/lock.h"
 #include "content/common/content_export.h"
-#include "content/port/common/input_event_ack_state.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/renderer/input/input_handler_manager_client.h"
 #include "ipc/message_filter.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
diff --git a/content/renderer/input/input_handler_manager.h b/content/renderer/input/input_handler_manager.h
index b5a0ae5..b6c7070 100644
--- a/content/renderer/input/input_handler_manager.h
+++ b/content/renderer/input/input_handler_manager.h
@@ -8,7 +8,7 @@
 #include "base/containers/scoped_ptr_hash_map.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
-#include "content/port/common/input_event_ack_state.h"
+#include "content/common/input/input_event_ack_state.h"
 #include "content/renderer/render_view_impl.h"
 
 namespace base {
diff --git a/content/renderer/input/input_handler_proxy.cc b/content/renderer/input/input_handler_proxy.cc
index dd54185..e1d6dd3 100644
--- a/content/renderer/input/input_handler_proxy.cc
+++ b/content/renderer/input/input_handler_proxy.cc
@@ -38,10 +38,80 @@
 // client to scroll.
 const float kScrollEpsilon = 0.1f;
 
+// Minimum fling velocity required for the active fling and new fling for the
+// two to accumulate.
+const double kMinBoostFlingSpeedSquare = 350. * 350.;
+
+// Minimum velocity for the active touch scroll to preserve (boost) an active
+// fling for which cancellation has been deferred.
+const double kMinBoostTouchScrollSpeedSquare = 150 * 150.;
+
+// Timeout window after which the active fling will be cancelled if no scrolls
+// or flings of sufficient velocity relative to the current fling are received.
+// The default value on Android native views is 40ms, but we use a slightly
+// increased value to accomodate small IPC message delays.
+const double kFlingBoostTimeoutDelaySeconds = 0.045;
+
+gfx::Vector2dF ToClientScrollIncrement(const WebFloatSize& increment) {
+  return gfx::Vector2dF(-increment.width, -increment.height);
+}
+
 double InSecondsF(const base::TimeTicks& time) {
   return (time - base::TimeTicks()).InSecondsF();
 }
 
+bool ShouldSuppressScrollForFlingBoosting(
+    const gfx::Vector2dF& current_fling_velocity,
+    const WebGestureEvent& scroll_update_event,
+    double time_since_last_boost_event) {
+  DCHECK_EQ(WebInputEvent::GestureScrollUpdate, scroll_update_event.type);
+
+  gfx::Vector2dF dx(scroll_update_event.data.scrollUpdate.deltaX,
+                    scroll_update_event.data.scrollUpdate.deltaY);
+  if (gfx::DotProduct(current_fling_velocity, dx) < 0)
+    return false;
+
+  if (time_since_last_boost_event < 0.001)
+    return true;
+
+  // TODO(jdduke): Use |scroll_update_event.data.scrollUpdate.velocity{X,Y}|.
+  // The scroll must be of sufficient velocity to maintain the active fling.
+  const gfx::Vector2dF scroll_velocity =
+      gfx::ScaleVector2d(dx, 1. / time_since_last_boost_event);
+  if (scroll_velocity.LengthSquared() < kMinBoostTouchScrollSpeedSquare)
+    return false;
+
+  return true;
+}
+
+bool ShouldBoostFling(const gfx::Vector2dF& current_fling_velocity,
+                      const WebGestureEvent& fling_start_event) {
+  DCHECK_EQ(WebInputEvent::GestureFlingStart, fling_start_event.type);
+
+  gfx::Vector2dF new_fling_velocity(
+      fling_start_event.data.flingStart.velocityX,
+      fling_start_event.data.flingStart.velocityY);
+
+  if (gfx::DotProduct(current_fling_velocity, new_fling_velocity) < 0)
+    return false;
+
+  if (current_fling_velocity.LengthSquared() < kMinBoostFlingSpeedSquare)
+    return false;
+
+  if (new_fling_velocity.LengthSquared() < kMinBoostFlingSpeedSquare)
+    return false;
+
+  return true;
+}
+
+WebGestureEvent ObtainGestureScrollBegin(const WebGestureEvent& event) {
+  WebGestureEvent scroll_begin_event = event;
+  scroll_begin_event.type = WebInputEvent::GestureScrollBegin;
+  scroll_begin_event.data.scrollBegin.deltaXHint = 0;
+  scroll_begin_event.data.scrollBegin.deltaYHint = 0;
+  return scroll_begin_event;
+}
+
 void SendScrollLatencyUma(const WebInputEvent& event,
                           const ui::LatencyInfo& latency_info) {
   if (!(event.type == WebInputEvent::GestureScrollBegin ||
@@ -71,9 +141,11 @@
 
 namespace content {
 
-InputHandlerProxy::InputHandlerProxy(cc::InputHandler* input_handler)
-    : client_(NULL),
+InputHandlerProxy::InputHandlerProxy(cc::InputHandler* input_handler,
+                                     InputHandlerProxyClient* client)
+    : client_(client),
       input_handler_(input_handler),
+      deferred_fling_cancel_time_seconds_(0),
 #ifndef NDEBUG
       expect_scroll_update_end_(false),
 #endif
@@ -83,6 +155,7 @@
       disallow_horizontal_fling_scroll_(false),
       disallow_vertical_fling_scroll_(false),
       has_fling_animation_started_(false) {
+  DCHECK(client);
   input_handler_->BindToClient(this);
 }
 
@@ -90,15 +163,9 @@
 
 void InputHandlerProxy::WillShutdown() {
   input_handler_ = NULL;
-  DCHECK(client_);
   client_->WillShutdown();
 }
 
-void InputHandlerProxy::SetClient(InputHandlerProxyClient* client) {
-  DCHECK(!client_ || !client);
-  client_ = client;
-}
-
 InputHandlerProxy::EventDisposition
 InputHandlerProxy::HandleInputEventWithLatencyInfo(
     const WebInputEvent& event,
@@ -121,11 +188,13 @@
 
 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent(
     const WebInputEvent& event) {
-  DCHECK(client_);
   DCHECK(input_handler_);
   TRACE_EVENT1("input", "InputHandlerProxy::HandleInputEvent",
                "type", WebInputEventTraits::GetName(event.type));
 
+  if (FilterInputEventForFlingBoosting(event))
+    return DID_HANDLE;
+
   if (event.type == WebInputEvent::MouseWheel) {
     const WebMouseWheelEvent& wheel_event =
         *static_cast<const WebMouseWheelEvent*>(&event);
@@ -310,30 +379,25 @@
       if (gesture_event.sourceDevice == WebGestureEvent::Touchpad)
         input_handler_->ScrollEnd();
 
+      const float vx = gesture_event.data.flingStart.velocityX;
+      const float vy = gesture_event.data.flingStart.velocityY;
+      current_fling_velocity_ = gfx::Vector2dF(vx, vy);
       fling_curve_.reset(client_->CreateFlingAnimationCurve(
-          gesture_event.sourceDevice,
-          WebFloatPoint(gesture_event.data.flingStart.velocityX,
-                        gesture_event.data.flingStart.velocityY),
-          blink::WebSize()));
-      disallow_horizontal_fling_scroll_ =
-          !gesture_event.data.flingStart.velocityX;
-      disallow_vertical_fling_scroll_ =
-          !gesture_event.data.flingStart.velocityY;
-      TRACE_EVENT_ASYNC_BEGIN2(
-          "input",
-          "InputHandlerProxy::HandleGestureFling::started",
-          this,
-          "vx",
-          gesture_event.data.flingStart.velocityX,
-          "vy",
-          gesture_event.data.flingStart.velocityY);
+          gesture_event.sourceDevice, WebFloatPoint(vx, vy), blink::WebSize()));
+      disallow_horizontal_fling_scroll_ = !vx;
+      disallow_vertical_fling_scroll_ = !vy;
+      TRACE_EVENT_ASYNC_BEGIN2("input",
+                               "InputHandlerProxy::HandleGestureFling::started",
+                               this,
+                               "vx",
+                               vx,
+                               "vy",
+                               vy);
       // Note that the timestamp will only be used to kickstart the animation if
       // its sufficiently close to the timestamp of the first call |Animate()|.
       has_fling_animation_started_ = false;
-        fling_parameters_.startTime = gesture_event.timeStampSeconds;
-      fling_parameters_.delta =
-          WebFloatPoint(gesture_event.data.flingStart.velocityX,
-                        gesture_event.data.flingStart.velocityY);
+      fling_parameters_.startTime = gesture_event.timeStampSeconds;
+      fling_parameters_.delta = WebFloatPoint(vx, vy);
       fling_parameters_.point = WebPoint(gesture_event.x, gesture_event.y);
       fling_parameters_.globalPoint =
           WebPoint(gesture_event.globalX, gesture_event.globalY);
@@ -371,23 +435,180 @@
   return DID_NOT_HANDLE;
 }
 
+bool InputHandlerProxy::FilterInputEventForFlingBoosting(
+    const WebInputEvent& event) {
+  if (!WebInputEvent::isGestureEventType(event.type))
+    return false;
+
+  if (!fling_curve_) {
+    DCHECK(!deferred_fling_cancel_time_seconds_);
+    return false;
+  }
+
+  const WebGestureEvent& gesture_event =
+      static_cast<const WebGestureEvent&>(event);
+  if (gesture_event.type == WebInputEvent::GestureFlingCancel) {
+    if (current_fling_velocity_.LengthSquared() < kMinBoostFlingSpeedSquare)
+      return false;
+
+    TRACE_EVENT_INSTANT0("input",
+                         "InputHandlerProxy::FlingBoostStart",
+                         TRACE_EVENT_SCOPE_THREAD);
+    deferred_fling_cancel_time_seconds_ =
+        event.timeStampSeconds + kFlingBoostTimeoutDelaySeconds;
+    return true;
+  }
+
+  // A fling is either inactive or is "free spinning", i.e., has yet to be
+  // interrupted by a touch gesture, in which case there is nothing to filter.
+  if (!deferred_fling_cancel_time_seconds_)
+    return false;
+
+  // Gestures from a different source should immediately interrupt the fling.
+  if (gesture_event.sourceDevice != fling_parameters_.sourceDevice) {
+    FlingBoostCancelAndResumeScrollingIfNecessary();
+    return false;
+  }
+
+  switch (gesture_event.type) {
+    case WebInputEvent::GestureTapCancel:
+    case WebInputEvent::GestureTapDown:
+      return false;
+
+    case WebInputEvent::GestureScrollBegin:
+      if (!input_handler_->IsCurrentlyScrollingLayerAt(
+              gfx::Point(gesture_event.x, gesture_event.y),
+              fling_parameters_.sourceDevice == WebGestureEvent::Touchpad
+                  ? cc::InputHandler::NonBubblingGesture
+                  : cc::InputHandler::Gesture)) {
+        CancelCurrentFling(true);
+        return false;
+      }
+
+      // TODO(jdduke): Use |gesture_event.data.scrollBegin.delta{X,Y}Hint| to
+      // determine if the ScrollBegin should immediately cancel the fling.
+      FlingBoostExtend(gesture_event);
+      return true;
+
+    case WebInputEvent::GestureScrollUpdate: {
+      const double time_since_last_boost_event =
+          event.timeStampSeconds - last_fling_boost_event_.timeStampSeconds;
+      if (ShouldSuppressScrollForFlingBoosting(current_fling_velocity_,
+                                               gesture_event,
+                                               time_since_last_boost_event)) {
+        FlingBoostExtend(gesture_event);
+        return true;
+      }
+
+      FlingBoostCancelAndResumeScrollingIfNecessary();
+      return false;
+    }
+
+    case WebInputEvent::GestureScrollEnd:
+      CancelCurrentFling(true);
+      return true;
+
+    case WebInputEvent::GestureFlingStart: {
+      DCHECK_EQ(fling_parameters_.sourceDevice, gesture_event.sourceDevice);
+
+      bool fling_boosted =
+          fling_parameters_.modifiers == gesture_event.modifiers &&
+          ShouldBoostFling(current_fling_velocity_, gesture_event);
+
+      gfx::Vector2dF new_fling_velocity(
+          gesture_event.data.flingStart.velocityX,
+          gesture_event.data.flingStart.velocityY);
+
+      if (fling_boosted)
+        current_fling_velocity_ += new_fling_velocity;
+      else
+        current_fling_velocity_ = new_fling_velocity;
+
+      WebFloatPoint velocity(current_fling_velocity_.x(),
+                             current_fling_velocity_.y());
+      deferred_fling_cancel_time_seconds_ = 0;
+      last_fling_boost_event_ = WebGestureEvent();
+      fling_curve_.reset(client_->CreateFlingAnimationCurve(
+          gesture_event.sourceDevice, velocity, blink::WebSize()));
+      fling_parameters_.startTime = gesture_event.timeStampSeconds;
+      fling_parameters_.delta = velocity;
+      fling_parameters_.point = WebPoint(gesture_event.x, gesture_event.y);
+      fling_parameters_.globalPoint =
+          WebPoint(gesture_event.globalX, gesture_event.globalY);
+
+      TRACE_EVENT_INSTANT2("input",
+                           fling_boosted ? "InputHandlerProxy::FlingBoosted"
+                                         : "InputHandlerProxy::FlingReplaced",
+                           TRACE_EVENT_SCOPE_THREAD,
+                           "vx",
+                           current_fling_velocity_.x(),
+                           "vy",
+                           current_fling_velocity_.y());
+
+      // The client expects balanced calls between a consumed GestureFlingStart
+      // and |DidStopFlinging()|. TODO(jdduke): Provide a count parameter to
+      // |DidStopFlinging()| and only send after the accumulated fling ends.
+      client_->DidStopFlinging();
+      return true;
+    }
+
+    default:
+      // All other types of gestures (taps, presses, etc...) will complete the
+      // deferred fling cancellation.
+      FlingBoostCancelAndResumeScrollingIfNecessary();
+      return false;
+  }
+}
+
+void InputHandlerProxy::FlingBoostExtend(const blink::WebGestureEvent& event) {
+  TRACE_EVENT_INSTANT0(
+      "input", "InputHandlerProxy::FlingBoostExtend", TRACE_EVENT_SCOPE_THREAD);
+  deferred_fling_cancel_time_seconds_ =
+      event.timeStampSeconds + kFlingBoostTimeoutDelaySeconds;
+  last_fling_boost_event_ = event;
+}
+
+void InputHandlerProxy::FlingBoostCancelAndResumeScrollingIfNecessary() {
+  TRACE_EVENT_INSTANT0(
+      "input", "InputHandlerProxy::FlingBoostCancel", TRACE_EVENT_SCOPE_THREAD);
+  DCHECK(deferred_fling_cancel_time_seconds_);
+
+  // Note: |last_fling_boost_event_| is cleared by |CancelCurrentFling()|.
+  WebGestureEvent last_fling_boost_event = last_fling_boost_event_;
+
+  CancelCurrentFling(true);
+
+  if (last_fling_boost_event.type == WebInputEvent::GestureScrollBegin ||
+      last_fling_boost_event.type == WebInputEvent::GestureScrollUpdate) {
+    // Synthesize a GestureScrollBegin, as the original was suppressed.
+    HandleInputEvent(ObtainGestureScrollBegin(last_fling_boost_event));
+  }
+}
+
 void InputHandlerProxy::Animate(base::TimeTicks time) {
   if (!fling_curve_)
     return;
 
   double monotonic_time_sec = InSecondsF(time);
+
+  if (deferred_fling_cancel_time_seconds_ &&
+      monotonic_time_sec > deferred_fling_cancel_time_seconds_) {
+    FlingBoostCancelAndResumeScrollingIfNecessary();
+    return;
+  }
+
   if (!has_fling_animation_started_) {
     has_fling_animation_started_ = true;
     // Guard against invalid, future or sufficiently stale start times, as there
     // are no guarantees fling event and animation timestamps are compatible.
-  if (!fling_parameters_.startTime ||
+    if (!fling_parameters_.startTime ||
         monotonic_time_sec <= fling_parameters_.startTime ||
         monotonic_time_sec >= fling_parameters_.startTime +
                                   kMaxSecondsFromFlingTimestampToFirstAnimate) {
-    fling_parameters_.startTime = monotonic_time_sec;
-    input_handler_->SetNeedsAnimate();
-    return;
-  }
+      fling_parameters_.startTime = monotonic_time_sec;
+      input_handler_->SetNeedsAnimate();
+      return;
+    }
   }
 
   bool fling_is_active =
@@ -427,7 +648,8 @@
   DidOverscrollParams params;
   params.accumulated_overscroll = accumulated_overscroll;
   params.latest_overscroll_delta = latest_overscroll_delta;
-  params.current_fling_velocity = current_fling_velocity_;
+  params.current_fling_velocity =
+      ToClientScrollIncrement(current_fling_velocity_);
 
   if (fling_curve_) {
     static const int kFlingOverscrollThreshold = 1;
@@ -464,6 +686,8 @@
   gesture_scroll_on_impl_thread_ = false;
   current_fling_velocity_ = gfx::Vector2dF();
   fling_parameters_ = blink::WebActiveWheelFlingParameters();
+  deferred_fling_cancel_time_seconds_ = 0;
+  last_fling_boost_event_ = WebGestureEvent();
   if (send_fling_stopped_notification && had_fling_animation)
     client_->DidStopFlinging();
   return had_fling_animation;
@@ -508,10 +732,6 @@
   return false;
 }
 
-static gfx::Vector2dF ToClientScrollIncrement(const WebFloatSize& increment) {
-  return gfx::Vector2dF(-increment.width, -increment.height);
-}
-
 bool InputHandlerProxy::scrollBy(const WebFloatSize& increment,
                                  const WebFloatSize& velocity) {
   WebFloatSize clipped_increment;
@@ -525,7 +745,7 @@
     clipped_velocity.height = velocity.height;
   }
 
-  current_fling_velocity_ = ToClientScrollIncrement(clipped_velocity);
+  current_fling_velocity_ = clipped_velocity;
 
   // Early out if the increment is zero, but avoid early terimination if the
   // velocity is still non-zero.
diff --git a/content/renderer/input/input_handler_proxy.h b/content/renderer/input/input_handler_proxy.h
index d9147a5..de54fa2 100644
--- a/content/renderer/input/input_handler_proxy.h
+++ b/content/renderer/input/input_handler_proxy.h
@@ -27,11 +27,10 @@
     : public cc::InputHandlerClient,
       public NON_EXPORTED_BASE(blink::WebGestureCurveTarget) {
  public:
-  explicit InputHandlerProxy(cc::InputHandler* input_handler);
+  InputHandlerProxy(cc::InputHandler* input_handler,
+                    InputHandlerProxyClient* client);
   virtual ~InputHandlerProxy();
 
-  void SetClient(InputHandlerProxyClient* client);
-
   enum EventDisposition {
     DID_HANDLE,
     DID_NOT_HANDLE,
@@ -61,6 +60,17 @@
  private:
   EventDisposition HandleGestureFling(const blink::WebGestureEvent& event);
 
+  // Returns true if the event should be suppressed due to to an active,
+  // boost-enabled fling, in which case further processing should cease.
+  bool FilterInputEventForFlingBoosting(const blink::WebInputEvent& event);
+
+  // Schedule a time in the future after which a boost-enabled fling will
+  // terminate without further momentum from the user (see |Animate()|).
+  void FlingBoostExtend(const blink::WebGestureEvent& event);
+
+  // Cancel the current fling and insert a GestureScrollBegin if necessary.
+  void FlingBoostCancelAndResumeScrollingIfNecessary();
+
   // Returns true if we scrolled by the increment.
   bool TouchpadFlingScroll(const blink::WebFloatSize& increment);
 
@@ -75,6 +85,15 @@
   InputHandlerProxyClient* client_;
   cc::InputHandler* input_handler_;
 
+  // Time at which an active fling should expire due to a deferred cancellation
+  // event. A call to |Animate()| after this time will end the fling.
+  double deferred_fling_cancel_time_seconds_;
+
+  // The last event that extended the lifetime of the boosted fling. If the
+  // event was a scroll gesture, a GestureScrollBegin will be inserted if the
+  // fling terminates (via |FlingBoostCancelAndResumeScrollingIfNecessary()|).
+  blink::WebGestureEvent last_fling_boost_event_;
+
 #ifndef NDEBUG
   bool expect_scroll_update_end_;
 #endif
diff --git a/content/renderer/input/input_handler_proxy_unittest.cc b/content/renderer/input/input_handler_proxy_unittest.cc
index 48e67d2..e4b19d0 100644
--- a/content/renderer/input/input_handler_proxy_unittest.cc
+++ b/content/renderer/input/input_handler_proxy_unittest.cc
@@ -33,6 +33,43 @@
 namespace content {
 namespace {
 
+double InSecondsF(const base::TimeTicks& time) {
+  return (time - base::TimeTicks()).InSecondsF();
+}
+
+WebGestureEvent CreateFling(base::TimeTicks timestamp,
+                            WebGestureEvent::SourceDevice source_device,
+                            WebFloatPoint velocity,
+                            WebPoint point,
+                            WebPoint global_point,
+                            int modifiers) {
+  WebGestureEvent fling;
+  fling.type = WebInputEvent::GestureFlingStart;
+  fling.sourceDevice = source_device;
+  fling.timeStampSeconds = (timestamp - base::TimeTicks()).InSecondsF();
+  fling.data.flingStart.velocityX = velocity.x;
+  fling.data.flingStart.velocityY = velocity.y;
+  fling.x = point.x;
+  fling.y = point.y;
+  fling.globalX = global_point.x;
+  fling.globalY = global_point.y;
+  fling.modifiers = modifiers;
+  return fling;
+}
+
+WebGestureEvent CreateFling(WebGestureEvent::SourceDevice source_device,
+                            WebFloatPoint velocity,
+                            WebPoint point,
+                            WebPoint global_point,
+                            int modifiers) {
+  return CreateFling(base::TimeTicks(),
+                     source_device,
+                     velocity,
+                     point,
+                     global_point,
+                     modifiers);
+}
+
 class MockInputHandler : public cc::InputHandler {
  public:
   MockInputHandler() {}
@@ -71,6 +108,10 @@
 
   virtual void MouseMoveAt(const gfx::Point& mouse_position) OVERRIDE {}
 
+  MOCK_METHOD2(IsCurrentlyScrollingLayerAt,
+               bool(const gfx::Point& point,
+                    cc::InputHandler::ScrollInputType type));
+
   MOCK_METHOD1(HaveTouchEventHandlersAt, bool(const gfx::Point& point));
 
   virtual void SetRootLayerScrollOffsetDelegate(
@@ -153,8 +194,7 @@
   InputHandlerProxyTest()
       : expected_disposition_(InputHandlerProxy::DID_HANDLE) {
     input_handler_.reset(
-        new content::InputHandlerProxy(&mock_input_handler_));
-    input_handler_->SetClient(&mock_client_);
+        new content::InputHandlerProxy(&mock_input_handler_, &mock_client_));
   }
 
   ~InputHandlerProxyTest() {
@@ -170,6 +210,43 @@
     testing::Mock::VerifyAndClearExpectations(&mock_client_);                 \
   } while (false)
 
+  void StartFling(base::TimeTicks timestamp,
+                  WebGestureEvent::SourceDevice source_device,
+                  WebFloatPoint velocity,
+                  WebPoint position) {
+    expected_disposition_ = InputHandlerProxy::DID_HANDLE;
+    VERIFY_AND_RESET_MOCKS();
+
+    EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
+        .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
+    gesture_.type = WebInputEvent::GestureScrollBegin;
+    gesture_.sourceDevice = source_device;
+    EXPECT_EQ(expected_disposition_,
+              input_handler_->HandleInputEvent(gesture_));
+
+    VERIFY_AND_RESET_MOCKS();
+
+    EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
+        .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
+    EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
+
+    gesture_ =
+        CreateFling(timestamp, source_device, velocity, position, position, 0);
+    EXPECT_EQ(expected_disposition_,
+              input_handler_->HandleInputEvent(gesture_));
+
+    VERIFY_AND_RESET_MOCKS();
+  }
+
+  void CancelFling(base::TimeTicks timestamp) {
+    gesture_.timeStampSeconds = InSecondsF(timestamp);
+    gesture_.type = WebInputEvent::GestureFlingCancel;
+    EXPECT_EQ(expected_disposition_,
+              input_handler_->HandleInputEvent(gesture_));
+
+    VERIFY_AND_RESET_MOCKS();
+  }
+
  protected:
   testing::StrictMock<MockInputHandler> mock_input_handler_;
   scoped_ptr<content::InputHandlerProxy> input_handler_;
@@ -480,14 +557,11 @@
   // Note that for trackpad, wheel events with the Control modifier are
   // special (reserved for zoom), so don't set that here.
   int modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey;
-  gesture_.data.flingStart.velocityX = fling_delta.x;
-  gesture_.data.flingStart.velocityY = fling_delta.y;
-  gesture_.sourceDevice = WebGestureEvent::Touchpad;
-  gesture_.x = fling_point.x;
-  gesture_.y = fling_point.y;
-  gesture_.globalX = fling_global_point.x;
-  gesture_.globalY = fling_global_point.y;
-  gesture_.modifiers = modifiers;
+  gesture_ = CreateFling(WebGestureEvent::Touchpad,
+                         fling_delta,
+                         fling_point,
+                         fling_global_point,
+                         modifiers);
   EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
@@ -582,21 +656,17 @@
   VERIFY_AND_RESET_MOCKS();
 
   // Start a gesture fling in the -X direction with zero Y movement.
-  gesture_.type = WebInputEvent::GestureFlingStart;
   WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
   WebPoint fling_point = WebPoint(7, 13);
   WebPoint fling_global_point = WebPoint(17, 23);
   // Note that for trackpad, wheel events with the Control modifier are
   // special (reserved for zoom), so don't set that here.
   int modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey;
-  gesture_.data.flingStart.velocityX = fling_delta.x;
-  gesture_.data.flingStart.velocityY = fling_delta.y;
-  gesture_.sourceDevice = WebGestureEvent::Touchpad;
-  gesture_.x = fling_point.x;
-  gesture_.y = fling_point.y;
-  gesture_.globalX = fling_global_point.x;
-  gesture_.globalY = fling_global_point.y;
-  gesture_.modifiers = modifiers;
+  gesture_ = CreateFling(WebGestureEvent::Touchpad,
+                         fling_delta,
+                         fling_point,
+                         fling_global_point,
+                         modifiers);
   EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
@@ -689,19 +759,15 @@
   input_handler_->MainThreadHasStoppedFlinging();
 
   // Start a second gesture fling, this time in the +Y direction with no X.
-  gesture_.type = WebInputEvent::GestureFlingStart;
   fling_delta = WebFloatPoint(0, -1000);
   fling_point = WebPoint(95, 87);
   fling_global_point = WebPoint(32, 71);
   modifiers = WebInputEvent::AltKey;
-  gesture_.data.flingStart.velocityX = fling_delta.x;
-  gesture_.data.flingStart.velocityY = fling_delta.y;
-  gesture_.sourceDevice = WebGestureEvent::Touchpad;
-  gesture_.x = fling_point.x;
-  gesture_.y = fling_point.y;
-  gesture_.globalX = fling_global_point.x;
-  gesture_.globalY = fling_global_point.y;
-  gesture_.modifiers = modifiers;
+  gesture_ = CreateFling(WebGestureEvent::Touchpad,
+                         fling_delta,
+                         fling_point,
+                         fling_global_point,
+                         modifiers);
   EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
@@ -867,20 +933,16 @@
 
   // On the fling start, we should schedule an animation but not actually start
   // scrolling.
-  gesture_.type = WebInputEvent::GestureFlingStart;
-  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
   WebPoint fling_point = WebPoint(7, 13);
   WebPoint fling_global_point = WebPoint(17, 23);
   // Note that for touchscreen the control modifier is not special.
   int modifiers = WebInputEvent::ControlKey;
-  gesture_.data.flingStart.velocityX = fling_delta.x;
-  gesture_.data.flingStart.velocityY = fling_delta.y;
-  gesture_.sourceDevice = WebGestureEvent::Touchscreen;
-  gesture_.x = fling_point.x;
-  gesture_.y = fling_point.y;
-  gesture_.globalX = fling_global_point.x;
-  gesture_.globalY = fling_global_point.y;
-  gesture_.modifiers = modifiers;
+  gesture_ = CreateFling(WebGestureEvent::Touchscreen,
+                         fling_delta,
+                         fling_point,
+                         fling_global_point,
+                         modifiers);
   EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
@@ -930,21 +992,18 @@
 
   // On the fling start, we should schedule an animation but not actually start
   // scrolling.
-  base::TimeDelta startTimeOffset = base::TimeDelta::FromMilliseconds(10);
-  gesture_.type = WebInputEvent::GestureFlingStart;
-  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
+  base::TimeTicks time = base::TimeTicks() + dt;
+  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
   WebPoint fling_point = WebPoint(7, 13);
   WebPoint fling_global_point = WebPoint(17, 23);
   int modifiers = WebInputEvent::ControlKey;
-  gesture_.timeStampSeconds = startTimeOffset.InSecondsF();
-  gesture_.data.flingStart.velocityX = fling_delta.x;
-  gesture_.data.flingStart.velocityY = fling_delta.y;
-  gesture_.sourceDevice = WebGestureEvent::Touchscreen;
-  gesture_.x = fling_point.x;
-  gesture_.y = fling_point.y;
-  gesture_.globalX = fling_global_point.x;
-  gesture_.globalY = fling_global_point.y;
-  gesture_.modifiers = modifiers;
+  gesture_ = CreateFling(time,
+                         WebGestureEvent::Touchscreen,
+                         fling_delta,
+                         fling_point,
+                         fling_global_point,
+                         modifiers);
   EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
@@ -961,7 +1020,7 @@
               ScrollBy(testing::_,
                        testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
       .WillOnce(testing::Return(true));
-  base::TimeTicks time = base::TimeTicks() + 2 * startTimeOffset;
+  time += dt;
   input_handler_->Animate(time);
 
   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
@@ -989,7 +1048,7 @@
   // scrolling.
   base::TimeDelta start_time_offset = base::TimeDelta::FromMilliseconds(10);
   gesture_.type = WebInputEvent::GestureFlingStart;
-  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
   WebPoint fling_point = WebPoint(7, 13);
   WebPoint fling_global_point = WebPoint(17, 23);
   int modifiers = WebInputEvent::ControlKey;
@@ -1055,19 +1114,15 @@
 
   // On the fling start, we should schedule an animation but not actually start
   // scrolling.
-  gesture_.type = WebInputEvent::GestureFlingStart;
-  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
   WebPoint fling_point = WebPoint(7, 13);
   WebPoint fling_global_point = WebPoint(17, 23);
   int modifiers = WebInputEvent::ControlKey | WebInputEvent::AltKey;
-  gesture_.data.flingStart.velocityX = fling_delta.x;
-  gesture_.data.flingStart.velocityY = fling_delta.y;
-  gesture_.sourceDevice = WebGestureEvent::Touchscreen;
-  gesture_.x = fling_point.x;
-  gesture_.y = fling_point.y;
-  gesture_.globalX = fling_global_point.x;
-  gesture_.globalY = fling_global_point.y;
-  gesture_.modifiers = modifiers;
+  gesture_ = CreateFling(WebGestureEvent::Touchscreen,
+                         fling_delta,
+                         fling_point,
+                         fling_global_point,
+                         modifiers);
   EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
@@ -1117,7 +1172,7 @@
   // On the fling start, we should schedule an animation but not actually start
   // scrolling.
   gesture_.type = WebInputEvent::GestureFlingStart;
-  WebFloatPoint fling_delta = WebFloatPoint(1000, 1000);
+  WebFloatPoint fling_delta = WebFloatPoint(100, 100);
   gesture_.data.flingStart.velocityX = fling_delta.x;
   gesture_.data.flingStart.velocityY = fling_delta.y;
   EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
@@ -1191,22 +1246,18 @@
 
   // On the fling start, we should schedule an animation but not actually start
   // scrolling.
-  base::TimeDelta time_offset = base::TimeDelta::FromMilliseconds(10);
-  base::TimeTicks time = base::TimeTicks() + time_offset;
-  gesture_.type = WebInputEvent::GestureFlingStart;
-  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
+  base::TimeTicks time = base::TimeTicks() + dt;
+  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
   WebPoint fling_point = WebPoint(7, 13);
   WebPoint fling_global_point = WebPoint(17, 23);
   int modifiers = WebInputEvent::ControlKey;
-  gesture_.timeStampSeconds = time_offset.InSecondsF();
-  gesture_.data.flingStart.velocityX = fling_delta.x;
-  gesture_.data.flingStart.velocityY = fling_delta.y;
-  gesture_.sourceDevice = WebGestureEvent::Touchscreen;
-  gesture_.x = fling_point.x;
-  gesture_.y = fling_point.y;
-  gesture_.globalX = fling_global_point.x;
-  gesture_.globalY = fling_global_point.y;
-  gesture_.modifiers = modifiers;
+  gesture_ = CreateFling(time,
+                         WebGestureEvent::Touchscreen,
+                         fling_delta,
+                         fling_point,
+                         fling_global_point,
+                         modifiers);
   EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
@@ -1271,7 +1322,7 @@
   // On the fling start, we should schedule an animation but not actually start
   // scrolling.
   gesture_.type = WebInputEvent::GestureFlingStart;
-  WebFloatPoint fling_delta = WebFloatPoint(1000, 1000);
+  WebFloatPoint fling_delta = WebFloatPoint(100, 100);
   gesture_.data.flingStart.velocityX = fling_delta.x;
   gesture_.data.flingStart.velocityY = fling_delta.y;
   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
@@ -1421,7 +1472,7 @@
 
   // On the fling start, animation should be scheduled, but no scrolling occurs.
   gesture_.type = WebInputEvent::GestureFlingStart;
-  WebFloatPoint fling_delta = WebFloatPoint(1000, 1000);
+  WebFloatPoint fling_delta = WebFloatPoint(100, 100);
   gesture_.data.flingStart.velocityX = fling_delta.x;
   gesture_.data.flingStart.velocityY = fling_delta.y;
   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
@@ -1466,21 +1517,18 @@
 
   // On the fling start, we should schedule an animation but not actually start
   // scrolling.
-  base::TimeDelta startTimeOffset = base::TimeDelta::FromMilliseconds(10);
-  gesture_.type = WebInputEvent::GestureFlingStart;
-  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
+  base::TimeTicks time = base::TimeTicks() + dt;
+  WebFloatPoint fling_delta = WebFloatPoint(100, 0);
   WebPoint fling_point = WebPoint(7, 13);
   WebPoint fling_global_point = WebPoint(17, 23);
   int modifiers = WebInputEvent::ControlKey;
-  gesture_.timeStampSeconds = startTimeOffset.InSecondsF();
-  gesture_.data.flingStart.velocityX = fling_delta.x;
-  gesture_.data.flingStart.velocityY = fling_delta.y;
-  gesture_.sourceDevice = WebGestureEvent::Touchscreen;
-  gesture_.x = fling_point.x;
-  gesture_.y = fling_point.y;
-  gesture_.globalX = fling_global_point.x;
-  gesture_.globalY = fling_global_point.y;
-  gesture_.modifiers = modifiers;
+  gesture_ = CreateFling(time,
+                         WebGestureEvent::Touchscreen,
+                         fling_delta,
+                         fling_point,
+                         fling_global_point,
+                         modifiers);
   EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
   EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
       .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
@@ -1495,8 +1543,7 @@
   EXPECT_CALL(mock_input_handler_,
               ScrollBy(testing::_,
                        testing::_)).Times(0);
-  base::TimeTicks time =
-      base::TimeTicks() + base::TimeDelta::FromMilliseconds(8);
+  time -= base::TimeDelta::FromMilliseconds(5);
   input_handler_->Animate(time);
 
   testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
@@ -1518,5 +1565,287 @@
   EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
 }
 
+TEST_F(InputHandlerProxyTest, FlingBoost) {
+  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
+  base::TimeTicks time = base::TimeTicks() + dt;
+  base::TimeTicks last_animate_time = time;
+  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+  WebPoint fling_point = WebPoint(7, 13);
+  StartFling(time, WebGestureEvent::Touchscreen, fling_delta, fling_point);
+
+  // Now cancel the fling.  The fling cancellation should be deferred to allow
+  // fling boosting events to arrive.
+  time += dt;
+  CancelFling(time);
+
+  // The GestureScrollBegin should be swallowed by the fling if it hits the same
+  // scrolling layer.
+  EXPECT_CALL(mock_input_handler_,
+              IsCurrentlyScrollingLayerAt(testing::_, testing::_))
+      .WillOnce(testing::Return(true));
+
+  time += dt;
+  gesture_.timeStampSeconds = InSecondsF(time);
+  gesture_.type = WebInputEvent::GestureScrollBegin;
+  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+
+  VERIFY_AND_RESET_MOCKS();
+
+  // Animate calls within the deferred cancellation window should continue.
+  time += dt;
+  float expected_delta =
+      (time - last_animate_time).InSecondsF() * -fling_delta.x;
+  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
+  EXPECT_CALL(mock_input_handler_,
+              ScrollBy(testing::_,
+                       testing::Property(&gfx::Vector2dF::x,
+                                         testing::Eq(expected_delta))))
+      .WillOnce(testing::Return(true));
+  input_handler_->Animate(time);
+  last_animate_time = time;
+
+  VERIFY_AND_RESET_MOCKS();
+
+  // GestureScrollUpdates in the same direction and at sufficient speed should
+  // be swallowed by the fling.
+  time += dt;
+  gesture_.timeStampSeconds = InSecondsF(time);
+  gesture_.type = WebInputEvent::GestureScrollUpdate;
+  gesture_.data.scrollUpdate.deltaX = fling_delta.x;
+  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+
+  VERIFY_AND_RESET_MOCKS();
+
+  // Animate calls within the deferred cancellation window should continue.
+  time += dt;
+  expected_delta = (time - last_animate_time).InSecondsF() * -fling_delta.x;
+  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
+  EXPECT_CALL(mock_input_handler_,
+              ScrollBy(testing::_,
+                       testing::Property(&gfx::Vector2dF::x,
+                                         testing::Eq(expected_delta))))
+      .WillOnce(testing::Return(true));
+  input_handler_->Animate(time);
+  last_animate_time = time;
+
+  VERIFY_AND_RESET_MOCKS();
+
+  // GestureFlingStart in the same direction and at sufficient speed should
+  // boost the active fling.
+
+  gesture_ = CreateFling(time,
+                         WebGestureEvent::Touchscreen,
+                         fling_delta,
+                         fling_point,
+                         fling_point,
+                         0);
+  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+  VERIFY_AND_RESET_MOCKS();
+
+  time += dt;
+  // Note we get *2x* as much delta because 2 flings have combined.
+  expected_delta = 2 * (time - last_animate_time).InSecondsF() * -fling_delta.x;
+  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
+  EXPECT_CALL(mock_input_handler_,
+              ScrollBy(testing::_,
+                       testing::Property(&gfx::Vector2dF::x,
+                                         testing::Eq(expected_delta))))
+      .WillOnce(testing::Return(true));
+  input_handler_->Animate(time);
+  last_animate_time = time;
+
+  VERIFY_AND_RESET_MOCKS();
+
+  // Repeated GestureFlingStarts should accumulate.
+
+  CancelFling(time);
+  gesture_ = CreateFling(time,
+                         WebGestureEvent::Touchscreen,
+                         fling_delta,
+                         fling_point,
+                         fling_point,
+                         0);
+  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+  VERIFY_AND_RESET_MOCKS();
+
+  time += dt;
+  // Note we get *3x* as much delta because 3 flings have combined.
+  expected_delta = 3 * (time - last_animate_time).InSecondsF() * -fling_delta.x;
+  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
+  EXPECT_CALL(mock_input_handler_,
+              ScrollBy(testing::_,
+                       testing::Property(&gfx::Vector2dF::x,
+                                         testing::Eq(expected_delta))))
+      .WillOnce(testing::Return(true));
+  input_handler_->Animate(time);
+  last_animate_time = time;
+
+  VERIFY_AND_RESET_MOCKS();
+
+  // GestureFlingCancel should terminate the fling if no boosting gestures are
+  // received within the timeout window.
+
+  time += dt;
+  gesture_.timeStampSeconds = InSecondsF(time);
+  gesture_.type = WebInputEvent::GestureFlingCancel;
+  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+
+  VERIFY_AND_RESET_MOCKS();
+
+  time += base::TimeDelta::FromMilliseconds(100);
+  EXPECT_CALL(mock_input_handler_, ScrollEnd());
+  input_handler_->Animate(time);
+
+  VERIFY_AND_RESET_MOCKS();
+}
+
+TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollTargetsDifferentLayer) {
+  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
+  base::TimeTicks time = base::TimeTicks() + dt;
+  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+  WebPoint fling_point = WebPoint(7, 13);
+  StartFling(time, WebGestureEvent::Touchscreen, fling_delta, fling_point);
+
+  // Cancel the fling.  The fling cancellation should be deferred to allow
+  // fling boosting events to arrive.
+  time += dt;
+  CancelFling(time);
+
+  // If the GestureScrollBegin targets a different layer, the fling should be
+  // cancelled and the scroll should be handled as usual.
+  EXPECT_CALL(mock_input_handler_,
+              IsCurrentlyScrollingLayerAt(testing::_, testing::_))
+      .WillOnce(testing::Return(false));
+  EXPECT_CALL(mock_input_handler_, ScrollEnd());
+  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
+      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
+
+  time += dt;
+  gesture_.timeStampSeconds = InSecondsF(time);
+  gesture_.type = WebInputEvent::GestureScrollBegin;
+  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+
+  VERIFY_AND_RESET_MOCKS();
+}
+
+TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollDelayed) {
+  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
+  base::TimeTicks time = base::TimeTicks() + dt;
+  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+  WebPoint fling_point = WebPoint(7, 13);
+  StartFling(time, WebGestureEvent::Touchscreen, fling_delta, fling_point);
+
+  // Cancel the fling.  The fling cancellation should be deferred to allow
+  // fling boosting events to arrive.
+  time += dt;
+  CancelFling(time);
+
+  // The GestureScrollBegin should be swallowed by the fling if it hits the same
+  // scrolling layer.
+  EXPECT_CALL(mock_input_handler_,
+              IsCurrentlyScrollingLayerAt(testing::_, testing::_))
+      .WillOnce(testing::Return(true));
+
+  time += dt;
+  gesture_.timeStampSeconds = InSecondsF(time);
+  gesture_.type = WebInputEvent::GestureScrollBegin;
+  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+
+  VERIFY_AND_RESET_MOCKS();
+
+  // If no GestureScrollUpdate or GestureFlingStart is received within the
+  // timeout window, the fling should be cancelled and scrolling should resume.
+  time += base::TimeDelta::FromMilliseconds(100);
+  EXPECT_CALL(mock_input_handler_, ScrollEnd());
+  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
+      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
+  input_handler_->Animate(time);
+
+  VERIFY_AND_RESET_MOCKS();
+}
+
+TEST_F(InputHandlerProxyTest, NoFlingBoostIfScrollInDifferentDirection) {
+  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
+  base::TimeTicks time = base::TimeTicks() + dt;
+  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+  WebPoint fling_point = WebPoint(7, 13);
+  StartFling(time, WebGestureEvent::Touchscreen, fling_delta, fling_point);
+
+  // Cancel the fling.  The fling cancellation should be deferred to allow
+  // fling boosting events to arrive.
+  time += dt;
+  CancelFling(time);
+
+  // The GestureScrollBegin should be swallowed by the fling if it hits the same
+  // scrolling layer.
+  EXPECT_CALL(mock_input_handler_,
+              IsCurrentlyScrollingLayerAt(testing::_, testing::_))
+      .WillOnce(testing::Return(true));
+
+  time += dt;
+  gesture_.timeStampSeconds = InSecondsF(time);
+  gesture_.type = WebInputEvent::GestureScrollBegin;
+  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+
+  VERIFY_AND_RESET_MOCKS();
+
+  // If the GestureScrollUpdate is in a different direction than the fling,
+  // the fling should be cancelled and scrolling should resume.
+  time += dt;
+  gesture_.timeStampSeconds = InSecondsF(time);
+  gesture_.type = WebInputEvent::GestureScrollUpdate;
+  gesture_.data.scrollUpdate.deltaX = -fling_delta.x;
+  EXPECT_CALL(mock_input_handler_, ScrollEnd());
+  EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
+      .WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
+  EXPECT_CALL(mock_input_handler_,
+              ScrollBy(testing::_,
+                       testing::Property(&gfx::Vector2dF::x,
+                                         testing::Eq(fling_delta.x))))
+      .WillOnce(testing::Return(true));
+  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+
+  VERIFY_AND_RESET_MOCKS();
+}
+
+TEST_F(InputHandlerProxyTest, NoFlingBoostIfFlingTooSlow) {
+  base::TimeDelta dt = base::TimeDelta::FromMilliseconds(10);
+  base::TimeTicks time = base::TimeTicks() + dt;
+  WebFloatPoint fling_delta = WebFloatPoint(1000, 0);
+  WebPoint fling_point = WebPoint(7, 13);
+  StartFling(time, WebGestureEvent::Touchscreen, fling_delta, fling_point);
+
+  // Cancel the fling.  The fling cancellation should be deferred to allow
+  // fling boosting events to arrive.
+  time += dt;
+  CancelFling(time);
+
+  // If the new fling is too slow, no boosting should take place, with the new
+  // fling replacing the old.
+  WebFloatPoint small_fling_delta = WebFloatPoint(100, 0);
+  gesture_ = CreateFling(time,
+                         WebGestureEvent::Touchscreen,
+                         small_fling_delta,
+                         fling_point,
+                         fling_point,
+                         0);
+  EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
+
+  VERIFY_AND_RESET_MOCKS();
+
+  // Note that the new fling delta uses the *slow*, unboosted fling velocity.
+  time += dt;
+  float expected_delta = dt.InSecondsF() * -small_fling_delta.x;
+  EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
+  EXPECT_CALL(mock_input_handler_,
+              ScrollBy(testing::_,
+                       testing::Property(&gfx::Vector2dF::x,
+                                         testing::Eq(expected_delta))))
+      .WillOnce(testing::Return(true));
+  input_handler_->Animate(time);
+
+  VERIFY_AND_RESET_MOCKS();
+}
+
 } // namespace
 } // namespace content
diff --git a/content/renderer/input/input_handler_wrapper.cc b/content/renderer/input/input_handler_wrapper.cc
index fd04f3b..d80686d 100644
--- a/content/renderer/input/input_handler_wrapper.cc
+++ b/content/renderer/input/input_handler_wrapper.cc
@@ -19,15 +19,13 @@
     const base::WeakPtr<RenderViewImpl>& render_view_impl)
     : input_handler_manager_(input_handler_manager),
       routing_id_(routing_id),
-      input_handler_proxy_(input_handler.get()),
+      input_handler_proxy_(input_handler.get(), this),
       main_loop_(main_loop),
       render_view_impl_(render_view_impl) {
   DCHECK(input_handler);
-  input_handler_proxy_.SetClient(this);
 }
 
 InputHandlerWrapper::~InputHandlerWrapper() {
-  input_handler_proxy_.SetClient(NULL);
 }
 
 void InputHandlerWrapper::TransferActiveWheelFlingAnimation(
diff --git a/content/renderer/input_tag_speech_dispatcher.cc b/content/renderer/input_tag_speech_dispatcher.cc
deleted file mode 100644
index 092eb2e..0000000
--- a/content/renderer/input_tag_speech_dispatcher.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "content/renderer/input_tag_speech_dispatcher.h"
-
-#include "base/strings/utf_string_conversions.h"
-#include "content/common/speech_recognition_messages.h"
-#include "content/renderer/render_view_impl.h"
-#include "third_party/WebKit/public/platform/WebSize.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebElement.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebInputElement.h"
-#include "third_party/WebKit/public/web/WebNode.h"
-#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
-#include "third_party/WebKit/public/web/WebSpeechInputListener.h"
-#include "third_party/WebKit/public/web/WebView.h"
-
-using blink::WebDocument;
-using blink::WebElement;
-using blink::WebFrame;
-using blink::WebInputElement;
-using blink::WebNode;
-using blink::WebView;
-
-namespace content {
-
-InputTagSpeechDispatcher::InputTagSpeechDispatcher(
-    RenderViewImpl* render_view,
-    blink::WebSpeechInputListener* listener)
-    : RenderViewObserver(render_view),
-      listener_(listener) {
-}
-
-bool InputTagSpeechDispatcher::OnMessageReceived(
-    const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(InputTagSpeechDispatcher, message)
-    IPC_MESSAGE_HANDLER(InputTagSpeechMsg_SetRecognitionResults,
-                        OnSpeechRecognitionResults)
-    IPC_MESSAGE_HANDLER(InputTagSpeechMsg_RecordingComplete,
-                        OnSpeechRecordingComplete)
-    IPC_MESSAGE_HANDLER(InputTagSpeechMsg_RecognitionComplete,
-                        OnSpeechRecognitionComplete)
-    IPC_MESSAGE_HANDLER(InputTagSpeechMsg_ToggleSpeechInput,
-                        OnSpeechRecognitionToggleSpeechInput)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-bool InputTagSpeechDispatcher::startRecognition(
-    int request_id,
-    const blink::WebRect& element_rect,
-    const blink::WebString& language,
-    const blink::WebString& grammar,
-    const blink::WebSecurityOrigin& origin) {
-  DVLOG(1) << "InputTagSpeechDispatcher::startRecognition enter";
-
-  InputTagSpeechHostMsg_StartRecognition_Params params;
-  params.grammar = base::UTF16ToUTF8(grammar);
-  params.language = base::UTF16ToUTF8(language);
-  params.origin_url = base::UTF16ToUTF8(origin.toString());
-  params.render_view_id = routing_id();
-  params.request_id = request_id;
-  params.element_rect = element_rect;
-
-  Send(new InputTagSpeechHostMsg_StartRecognition(params));
-  DVLOG(1) << "InputTagSpeechDispatcher::startRecognition exit";
-  return true;
-}
-
-void InputTagSpeechDispatcher::cancelRecognition(int request_id) {
-  DVLOG(1) << "InputTagSpeechDispatcher::cancelRecognition enter";
-  Send(new InputTagSpeechHostMsg_CancelRecognition(routing_id(), request_id));
-  DVLOG(1) << "InputTagSpeechDispatcher::cancelRecognition exit";
-}
-
-void InputTagSpeechDispatcher::stopRecording(int request_id) {
-  DVLOG(1) << "InputTagSpeechDispatcher::stopRecording enter";
-  Send(new InputTagSpeechHostMsg_StopRecording(routing_id(),
-                                               request_id));
-  DVLOG(1) << "InputTagSpeechDispatcher::stopRecording exit";
-}
-
-void InputTagSpeechDispatcher::OnSpeechRecognitionResults(
-    int request_id,
-    const SpeechRecognitionResults& results) {
-  DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecognitionResults enter";
-  DCHECK_EQ(results.size(), 1U);
-
-  const SpeechRecognitionResult& result = results[0];
-  blink::WebSpeechInputResultArray webkit_result(result.hypotheses.size());
-  for (size_t i = 0; i < result.hypotheses.size(); ++i) {
-    webkit_result[i].assign(result.hypotheses[i].utterance,
-        result.hypotheses[i].confidence);
-  }
-  listener_->setRecognitionResult(request_id, webkit_result);
-
-  DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecognitionResults exit";
-}
-
-void InputTagSpeechDispatcher::OnSpeechRecordingComplete(int request_id) {
-  DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecordingComplete enter";
-  listener_->didCompleteRecording(request_id);
-  DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecordingComplete exit";
-}
-
-void InputTagSpeechDispatcher::OnSpeechRecognitionComplete(int request_id) {
-  DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecognitionComplete enter";
-  listener_->didCompleteRecognition(request_id);
-  DVLOG(1) << "InputTagSpeechDispatcher::OnSpeechRecognitionComplete exit";
-}
-
-void InputTagSpeechDispatcher::OnSpeechRecognitionToggleSpeechInput() {
-  DVLOG(1) <<"InputTagSpeechDispatcher::OnSpeechRecognitionToggleSpeechInput";
-
-  WebView* web_view = render_view()->GetWebView();
-
-  WebFrame* frame = web_view->mainFrame();
-  if (!frame)
-    return;
-
-  WebDocument document = frame->document();
-  if (document.isNull())
-    return;
-
-  blink::WebElement element = document.focusedElement();
-  if (element.isNull())
-    return;
-
-  blink::WebInputElement* input_element = blink::toWebInputElement(&element);
-  if (!input_element)
-    return;
-  if (!input_element->isSpeechInputEnabled())
-    return;
-
-  if (input_element->getSpeechInputState() == WebInputElement::Idle) {
-    input_element->startSpeechInput();
-  } else {
-    input_element->stopSpeechInput();
-  }
-}
-
-}  // namespace content
diff --git a/content/renderer/input_tag_speech_dispatcher.h b/content/renderer/input_tag_speech_dispatcher.h
deleted file mode 100644
index ee9dda9..0000000
--- a/content/renderer/input_tag_speech_dispatcher.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CONTENT_RENDERER_INPUT_TAG_SPEECH_DISPATCHER_H_
-#define CONTENT_RENDERER_INPUT_TAG_SPEECH_DISPATCHER_H_
-
-#include "base/basictypes.h"
-#include "content/public/common/speech_recognition_result.h"
-#include "content/public/renderer/render_view_observer.h"
-#include "third_party/WebKit/public/web/WebSpeechInputController.h"
-
-namespace blink {
-class WebSpeechInputListener;
-}
-
-namespace content {
-class RenderViewImpl;
-struct SpeechRecognitionResult;
-
-// InputTagSpeechDispatcher is a delegate for messages used by WebKit. It's
-// the complement of InputTagSpeechDispatcherHost (owned by RenderViewHost).
-class InputTagSpeechDispatcher : public RenderViewObserver,
-                                 public blink::WebSpeechInputController {
- public:
-  InputTagSpeechDispatcher(RenderViewImpl* render_view,
-                           blink::WebSpeechInputListener* listener);
-
- private:
-  // RenderView::Observer implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-
-  // blink::WebSpeechInputController.
-  virtual bool startRecognition(int request_id,
-                                const blink::WebRect& element_rect,
-                                const blink::WebString& language,
-                                const blink::WebString& grammar,
-                                const blink::WebSecurityOrigin& origin);
-
-  virtual void cancelRecognition(int request_id);
-  virtual void stopRecording(int request_id);
-
-  void OnSpeechRecognitionResults(
-      int request_id, const SpeechRecognitionResults& results);
-  void OnSpeechRecordingComplete(int request_id);
-  void OnSpeechRecognitionComplete(int request_id);
-  void OnSpeechRecognitionToggleSpeechInput();
-
-  blink::WebSpeechInputListener* listener_;
-
-  DISALLOW_COPY_AND_ASSIGN(InputTagSpeechDispatcher);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_INPUT_TAG_SPEECH_DISPATCHER_H_
diff --git a/content/renderer/media/android/audio_decoder_android.cc b/content/renderer/media/android/audio_decoder_android.cc
index 21c978e..72e25ab 100644
--- a/content/renderer/media/android/audio_decoder_android.cc
+++ b/content/renderer/media/android/audio_decoder_android.cc
@@ -165,6 +165,9 @@
   // The number of bytes in the data portion of the chunk.
   size_t chunk_size_;
 
+  // The total number of bytes in the encoded data.
+  size_t data_size_;
+
   // The current position within the WAVE file.
   const uint8_t* buffer_;
 
@@ -183,7 +186,8 @@
 };
 
 WAVEDecoder::WAVEDecoder(const uint8_t* encoded_data, size_t data_size)
-    : buffer_(encoded_data),
+    : data_size_(data_size),
+      buffer_(encoded_data),
       buffer_end_(encoded_data + 1),
       bytes_per_sample_(0),
       number_of_channels_(0),
@@ -247,6 +251,10 @@
   if (chunk_size_ % 2)
     ++chunk_size_;
 
+  // Check for completely bogus chunk size.
+  if (chunk_size_ > data_size_)
+    return false;
+
   return true;
 }
 
diff --git a/content/renderer/media/android/media_source_delegate.cc b/content/renderer/media/android/media_source_delegate.cc
index 324ee80..eb4f5c3 100644
--- a/content/renderer/media/android/media_source_delegate.cc
+++ b/content/renderer/media/android/media_source_delegate.cc
@@ -114,6 +114,14 @@
   return is_video_encrypted_;
 }
 
+base::Time MediaSourceDelegate::GetTimelineOffset() const {
+  DCHECK(main_loop_->BelongsToCurrentThread());
+  if (!chunk_demuxer_)
+    return base::Time();
+
+  return chunk_demuxer_->GetTimelineOffset();
+}
+
 void MediaSourceDelegate::StopDemuxer() {
   DCHECK(media_loop_->BelongsToCurrentThread());
   DCHECK(chunk_demuxer_);
diff --git a/content/renderer/media/android/media_source_delegate.h b/content/renderer/media/android/media_source_delegate.h
index d7e6ddc..4ac8ed8 100644
--- a/content/renderer/media/android/media_source_delegate.h
+++ b/content/renderer/media/android/media_source_delegate.h
@@ -106,6 +106,9 @@
   // Called on the main thread to check whether the video stream is encrypted.
   bool IsVideoEncrypted();
 
+  // Gets the ChunkDemuxer timeline offset.
+  base::Time GetTimelineOffset() const;
+
  private:
   // This is private to enforce use of the Destroyer.
   virtual ~MediaSourceDelegate();
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
index c8c8ae4..9c230c1 100644
--- a/content/renderer/media/android/webmediaplayer_android.cc
+++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -128,9 +128,11 @@
   player_id_ = manager_->RegisterMediaPlayer(this);
 
 #if defined(VIDEO_HOLE)
-  // Defer stream texture creation until we are sure it's necessary.
-  needs_establish_peer_ = false;
-  current_frame_ = VideoFrame::CreateBlackFrame(gfx::Size(1, 1));
+  if (manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo()) {
+    // Defer stream texture creation until we are sure it's necessary.
+    needs_establish_peer_ = false;
+    current_frame_ = VideoFrame::CreateBlackFrame(gfx::Size(1, 1));
+  }
   force_use_overlay_embedded_video_ = CommandLine::ForCurrentProcess()->
       HasSwitch(switches::kForceUseOverlayEmbeddedVideo);
 #endif  // defined(VIDEO_HOLE)
@@ -397,6 +399,17 @@
   return duration_.InSecondsF();
 }
 
+double WebMediaPlayerAndroid::timelineOffset() const {
+  base::Time timeline_offset;
+  if (media_source_delegate_)
+    timeline_offset = media_source_delegate_->GetTimelineOffset();
+
+  if (timeline_offset.is_null())
+    return std::numeric_limits<double>::quiet_NaN();
+
+  return timeline_offset.ToJsTime();
+}
+
 double WebMediaPlayerAndroid::currentTime() const {
   // If the player is processing a seek, return the seek time.
   // Blink may still query us if updatePlaybackState() occurs while seeking.
@@ -690,13 +703,9 @@
   } else if (stream_texture_proxy_ && !stream_id_) {
     // Do deferred stream texture creation finally.
     DoCreateStreamTexture();
-    if (paused()) {
-      SetNeedsEstablishPeer(true);
-    } else {
-      EstablishSurfaceTexturePeer();
-    }
+    SetNeedsEstablishPeer(true);
   }
-#else
+#endif  // defined(VIDEO_HOLE)
   // When play() gets called, |natural_size_| may still be empty and
   // EstablishSurfaceTexturePeer() will not get called. As a result, the video
   // may play without a surface texture. When we finally get the valid video
@@ -704,7 +713,6 @@
   // previously called.
   if (!paused() && needs_establish_peer_)
     EstablishSurfaceTexturePeer();
-#endif  // defined(VIDEO_HOLE)
 
   natural_size_.width = width;
   natural_size_.height = height;
@@ -1183,7 +1191,8 @@
 // Convert a WebString to ASCII, falling back on an empty string in the case
 // of a non-ASCII string.
 static std::string ToASCIIOrEmpty(const blink::WebString& string) {
-  return IsStringASCII(string) ? base::UTF16ToASCII(string) : std::string();
+  return base::IsStringASCII(string) ? base::UTF16ToASCII(string)
+                                     : std::string();
 }
 
 // Helper functions to report media EME related stats to UMA. They follow the
diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h
index 1dcadb4..9a6468a 100644
--- a/content/renderer/media/android/webmediaplayer_android.h
+++ b/content/renderer/media/android/webmediaplayer_android.h
@@ -129,6 +129,7 @@
   virtual bool paused() const;
   virtual bool seeking() const;
   virtual double duration() const;
+  virtual double timelineOffset() const;
   virtual double currentTime() const;
 
   virtual bool didLoadingProgress() const;
diff --git a/content/renderer/media/audio_message_filter.h b/content/renderer/media/audio_message_filter.h
index 2892bb9..71bf012 100644
--- a/content/renderer/media/audio_message_filter.h
+++ b/content/renderer/media/audio_message_filter.h
@@ -45,7 +45,7 @@
                                                          int render_frame_id);
 
   // When set, AudioMessageFilter will update the AudioHardwareConfig with new
-  // configuration values as recieved by OnOutputDeviceChanged().  The provided
+  // configuration values as received by OnOutputDeviceChanged().  The provided
   // |config| must outlive AudioMessageFilter.
   void SetAudioHardwareConfig(media::AudioHardwareConfig* config);
 
diff --git a/content/renderer/media/buffered_data_source.cc b/content/renderer/media/buffered_data_source.cc
index 8b2fc3a..d046178 100644
--- a/content/renderer/media/buffered_data_source.cc
+++ b/content/renderer/media/buffered_data_source.cc
@@ -140,7 +140,7 @@
 
   init_cb_ = init_cb;
 
-  if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) {
+  if (url_.SchemeIs(url::kHttpScheme) || url_.SchemeIs(url::kHttpsScheme)) {
     // Do an unbounded range request starting at the beginning.  If the server
     // responds with 200 instead of 206 we'll fall back into a streaming mode.
     loader_.reset(CreateResourceLoader(0, kPositionNotSpecified));
diff --git a/content/renderer/media/buffered_data_source_unittest.cc b/content/renderer/media/buffered_data_source_unittest.cc
index 0f67898..6cf7ef4 100644
--- a/content/renderer/media/buffered_data_source_unittest.cc
+++ b/content/renderer/media/buffered_data_source_unittest.cc
@@ -132,7 +132,8 @@
             &BufferedDataSourceTest::OnInitialize, base::Unretained(this)));
     message_loop_.RunUntilIdle();
 
-    bool is_http = gurl.SchemeIs(kHttpScheme) || gurl.SchemeIs(kHttpsScheme);
+    bool is_http =
+        gurl.SchemeIs(url::kHttpScheme) || gurl.SchemeIs(url::kHttpsScheme);
     EXPECT_EQ(data_source_->downloading(), is_http);
   }
 
diff --git a/content/renderer/media/buffered_resource_loader.cc b/content/renderer/media/buffered_resource_loader.cc
index 1351298..128340d 100644
--- a/content/renderer/media/buffered_resource_loader.cc
+++ b/content/renderer/media/buffered_resource_loader.cc
@@ -389,7 +389,7 @@
   // received a response from HTTP/HTTPS protocol or the request was
   // successful (in particular range request). So we only verify the partial
   // response for HTTP and HTTPS protocol.
-  if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) {
+  if (url_.SchemeIs(url::kHttpScheme) || url_.SchemeIs(url::kHttpsScheme)) {
     bool partial_response = (response.httpStatusCode() == kHttpPartialContent);
     bool ok_response = (response.httpStatusCode() == kHttpOK);
 
diff --git a/content/renderer/media/media_stream_audio_processor.cc b/content/renderer/media/media_stream_audio_processor.cc
index c82a1b6..27a35bb 100644
--- a/content/renderer/media/media_stream_audio_processor.cc
+++ b/content/renderer/media/media_stream_audio_processor.cc
@@ -252,11 +252,8 @@
                                               int sample_rate,
                                               int audio_delay_milliseconds) {
   DCHECK(render_thread_checker_.CalledOnValidThread());
-#if defined(OS_ANDROID) || defined(OS_IOS)
-  DCHECK(audio_processing_->echo_control_mobile()->is_enabled());
-#else
-  DCHECK(audio_processing_->echo_cancellation()->is_enabled());
-#endif
+  DCHECK(audio_processing_->echo_control_mobile()->is_enabled() ^
+         audio_processing_->echo_cancellation()->is_enabled());
 
   TRACE_EVENT0("audio", "MediaStreamAudioProcessor::OnPlayoutData");
   DCHECK_LT(audio_delay_milliseconds,
diff --git a/content/renderer/media/media_stream_audio_processor_options.cc b/content/renderer/media/media_stream_audio_processor_options.cc
index 320d1a6b..e1474c0 100644
--- a/content/renderer/media/media_stream_audio_processor_options.cc
+++ b/content/renderer/media/media_stream_audio_processor_options.cc
@@ -6,6 +6,7 @@
 
 #include "base/files/file_path.h"
 #include "base/logging.h"
+#include "base/metrics/field_trial.h"
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/common/media/media_stream_options.h"
@@ -94,13 +95,18 @@
 }
 
 void EnableEchoCancellation(AudioProcessing* audio_processing) {
-#if defined(OS_ANDROID)
-  // Mobile devices are using AECM.
-  int err = audio_processing->echo_control_mobile()->set_routing_mode(
-      webrtc::EchoControlMobile::kSpeakerphone);
-  err |= audio_processing->echo_control_mobile()->Enable(true);
-  CHECK_EQ(err, 0);
-#else
+#if defined(OS_ANDROID) || defined(OS_IOS)
+  const std::string group_name =
+      base::FieldTrialList::FindFullName("ReplaceAECMWithAEC");
+  if (group_name.empty() || (group_name != "Enabled")) {
+    // Mobile devices are using AECM.
+    int err = audio_processing->echo_control_mobile()->set_routing_mode(
+        webrtc::EchoControlMobile::kSpeakerphone);
+    err |= audio_processing->echo_control_mobile()->Enable(true);
+    CHECK_EQ(err, 0);
+    return;
+  }
+#endif
   int err = audio_processing->echo_cancellation()->set_suppression_level(
       webrtc::EchoCancellation::kHighSuppression);
 
@@ -109,7 +115,6 @@
   err |= audio_processing->echo_cancellation()->enable_delay_logging(true);
   err |= audio_processing->echo_cancellation()->Enable(true);
   CHECK_EQ(err, 0);
-#endif
 }
 
 void EnableNoiseSuppression(AudioProcessing* audio_processing) {
diff --git a/content/renderer/media/media_stream_impl_unittest.cc b/content/renderer/media/media_stream_impl_unittest.cc
index bc0fbaf..2d15fb1 100644
--- a/content/renderer/media/media_stream_impl_unittest.cc
+++ b/content/renderer/media/media_stream_impl_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/child/child_process.h"
 #include "content/renderer/media/media_stream.h"
 #include "content/renderer/media/media_stream_impl.h"
 #include "content/renderer/media/media_stream_track.h"
@@ -106,6 +107,7 @@
  public:
   virtual void SetUp() {
     // Create our test object.
+    child_process_.reset(new ChildProcess());
     ms_dispatcher_.reset(new MockMediaStreamDispatcher());
     dependency_factory_.reset(new MockMediaStreamDependencyFactory());
     ms_impl_.reset(new MediaStreamImplUnderTest(ms_dispatcher_.get(),
@@ -165,6 +167,7 @@
   }
 
  protected:
+  scoped_ptr<ChildProcess> child_process_;
   scoped_ptr<MockMediaStreamDispatcher> ms_dispatcher_;
   scoped_ptr<MediaStreamImplUnderTest> ms_impl_;
   scoped_ptr<MockMediaStreamDependencyFactory> dependency_factory_;
diff --git a/content/renderer/media/media_stream_video_capture_source_unittest.cc b/content/renderer/media/media_stream_video_capture_source_unittest.cc
index f721070..a204f1e 100644
--- a/content/renderer/media/media_stream_video_capture_source_unittest.cc
+++ b/content/renderer/media/media_stream_video_capture_source_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "base/bind.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/child/child_process.h"
 #include "content/renderer/media/media_stream_video_capturer_source.h"
 #include "content/renderer/media/media_stream_video_track.h"
 #include "content/renderer/media/mock_media_constraint_factory.h"
@@ -29,6 +30,11 @@
 
 class MediaStreamVideoCapturerSourceTest : public testing::Test {
  public:
+  MediaStreamVideoCapturerSourceTest()
+     : child_process_(new ChildProcess()),
+       source_(NULL) {
+  }
+
   void InitWithDeviceInfo(const StreamDeviceInfo& device_info) {
     delegate_ = new MockVideoCapturerDelegate(device_info);
     source_ = new MediaStreamVideoCapturerSource(
@@ -58,6 +64,7 @@
   void OnConstraintsApplied(MediaStreamSource* source, bool success) {
   }
 
+  scoped_ptr<ChildProcess> child_process_;
   blink::WebMediaStreamSource webkit_source_;
   MediaStreamVideoCapturerSource* source_;  // owned by webkit_source.
   scoped_refptr<MockVideoCapturerDelegate> delegate_;
diff --git a/content/renderer/media/media_stream_video_capturer_source.cc b/content/renderer/media/media_stream_video_capturer_source.cc
index 0eb3104..4bcab47 100644
--- a/content/renderer/media/media_stream_video_capturer_source.cc
+++ b/content/renderer/media/media_stream_video_capturer_source.cc
@@ -52,7 +52,6 @@
 
 VideoCapturerDelegate::~VideoCapturerDelegate() {
   DVLOG(3) << "VideoCapturerDelegate::dtor";
-  DCHECK(new_frame_callback_.is_null());
   if (!release_device_cb_.is_null())
     release_device_cb_.Run();
 }
@@ -102,7 +101,6 @@
     const StartedCallback& started_callback) {
   DCHECK(params.requested_format.IsValid());
   DCHECK(thread_checker_.CalledOnValidThread());
-  new_frame_callback_ = new_frame_callback;
   started_callback_ = started_callback;
   got_first_frame_ = false;
 
@@ -119,8 +117,7 @@
           params,
           media::BindToCurrentLoop(base::Bind(
               &VideoCapturerDelegate::OnStateUpdateOnRenderThread, this)),
-          media::BindToCurrentLoop(base::Bind(
-              &VideoCapturerDelegate::OnFrameReadyOnRenderThread, this)));
+          new_frame_callback);
 }
 
 void VideoCapturerDelegate::StopCapture() {
@@ -130,29 +127,17 @@
   if (!stop_capture_cb_.is_null()) {
     base::ResetAndReturn(&stop_capture_cb_).Run();
   }
-  new_frame_callback_.Reset();
   started_callback_.Reset();
   source_formats_callback_.Reset();
 }
 
-void VideoCapturerDelegate::OnFrameReadyOnRenderThread(
-    const scoped_refptr<media::VideoFrame>& frame,
-    const media::VideoCaptureFormat& format) {
-  if (!got_first_frame_) {
-    got_first_frame_ = true;
-    if (!started_callback_.is_null())
-      started_callback_.Run(true);
-  }
-
-  if (!new_frame_callback_.is_null()) {
-    new_frame_callback_.Run(frame, format);
-  }
-}
-
 void VideoCapturerDelegate::OnStateUpdateOnRenderThread(
     VideoCaptureState state) {
-  if (state == VIDEO_CAPTURE_STATE_ERROR && !started_callback_.is_null()) {
-    started_callback_.Run(false);
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DVLOG(3) << "OnStateUpdateOnRenderThread state = " << state;
+  if (state > VIDEO_CAPTURE_STATE_STARTING && !started_callback_.is_null()) {
+    base::ResetAndReturn(&started_callback_).Run(
+        state == VIDEO_CAPTURE_STATE_STARTED);
   }
 }
 
@@ -217,8 +202,7 @@
     const StreamDeviceInfo& device_info,
     const SourceStoppedCallback& stop_callback,
     const scoped_refptr<VideoCapturerDelegate>& delegate)
-    : MediaStreamVideoSource(),
-      delegate_(delegate) {
+    : delegate_(delegate) {
   SetDeviceInfo(device_info);
   SetStopCallback(stop_callback);
 }
@@ -228,16 +212,17 @@
 
 void MediaStreamVideoCapturerSource::GetCurrentSupportedFormats(
     int max_requested_width,
-    int max_requested_height) {
+    int max_requested_height,
+    const VideoCaptureDeviceFormatsCB& callback) {
   delegate_->GetCurrentSupportedFormats(
       max_requested_width,
       max_requested_height,
-      base::Bind(&MediaStreamVideoCapturerSource::OnSupportedFormats,
-                 base::Unretained(this)));
+      callback);
 }
 
 void MediaStreamVideoCapturerSource::StartSourceImpl(
-    const media::VideoCaptureParams& params) {
+    const media::VideoCaptureParams& params,
+    const VideoCaptureDeliverFrameCB& frame_callback) {
   media::VideoCaptureParams new_params(params);
   if (device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE ||
       device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
@@ -245,8 +230,7 @@
   }
   delegate_->StartCapture(
       new_params,
-      base::Bind(&MediaStreamVideoCapturerSource::DeliverVideoFrame,
-                 base::Unretained(this)),
+      frame_callback,
       base::Bind(&MediaStreamVideoCapturerSource::OnStartDone,
                  base::Unretained(this)));
 }
diff --git a/content/renderer/media/media_stream_video_capturer_source.h b/content/renderer/media/media_stream_video_capturer_source.h
index 0fbef5d..dcae91a 100644
--- a/content/renderer/media/media_stream_video_capturer_source.h
+++ b/content/renderer/media/media_stream_video_capturer_source.h
@@ -54,9 +54,6 @@
 
   virtual ~VideoCapturerDelegate();
 
-  void OnFrameReadyOnRenderThread(
-      const scoped_refptr<media::VideoFrame>& frame,
-      const media::VideoCaptureFormat& format);
   void OnStateUpdateOnRenderThread(VideoCaptureState state);
   void OnDeviceFormatsInUseReceived(const media::VideoCaptureFormats& formats);
   void OnDeviceSupportedFormatsEnumerated(
@@ -71,11 +68,8 @@
   bool is_screen_cast_;
   bool got_first_frame_;
 
-  // |new_frame_callback_| is provided to this class in StartToDeliver and must
-  // be valid until StopDeliver is called.
-  VideoCaptureDeliverFrameCB new_frame_callback_;
-  // |started_callback| is provided to this class in StartToDeliver and must be
-  // valid until StopDeliver is called.
+  // |started_callback| is provided to this class in StartCapture and must be
+  // valid until StopCapture is called.
   StartedCallback started_callback_;
 
   VideoCaptureDeviceFormatsCB source_formats_callback_;
@@ -104,10 +98,12 @@
   // Implements MediaStreamVideoSource.
   virtual void GetCurrentSupportedFormats(
       int max_requested_width,
-      int max_requested_height) OVERRIDE;
+      int max_requested_height,
+      const VideoCaptureDeviceFormatsCB& callback) OVERRIDE;
 
   virtual void StartSourceImpl(
-      const media::VideoCaptureParams& params) OVERRIDE;
+      const media::VideoCaptureParams& params,
+      const VideoCaptureDeliverFrameCB& frame_callback) OVERRIDE;
 
   virtual void StopSourceImpl() OVERRIDE;
 
diff --git a/content/renderer/media/media_stream_video_source.cc b/content/renderer/media/media_stream_video_source.cc
index 491f6f8..2db0ef0 100644
--- a/content/renderer/media/media_stream_video_source.cc
+++ b/content/renderer/media/media_stream_video_source.cc
@@ -8,10 +8,13 @@
 #include <limits>
 #include <string>
 
+#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
+#include "content/child/child_process.h"
 #include "content/renderer/media/media_stream_dependency_factory.h"
 #include "content/renderer/media/media_stream_video_track.h"
+#include "content/renderer/media/video_frame_deliverer.h"
 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
 
 namespace content {
@@ -215,6 +218,13 @@
   return ret;
 }
 
+// Returns true if |constraint| has mandatory constraints.
+bool HasMandatoryConstraints(const blink::WebMediaConstraints& constraints) {
+  blink::WebVector<blink::WebMediaConstraint> mandatory_constraints;
+  constraints.getMandatoryConstraints(mandatory_constraints);
+  return !mandatory_constraints.isEmpty();
+}
+
 // Retrieve the desired max width and height from |constraints|.
 void GetDesiredMaxWidthAndHeight(const blink::WebMediaConstraints& constraints,
                                  int* desired_width, int* desired_height) {
@@ -277,14 +287,90 @@
 }
 
 // Empty method used for keeping a reference to the original media::VideoFrame
-// in MediaStreamVideoSource::DeliverVideoFrame if cropping is needed.
-// The reference to |frame| is kept in the closure that calls this method.
+// in MediaStreamVideoSource::FrameDeliverer::DeliverFrameOnIO if cropping is
+// needed. The reference to |frame| is kept in the closure that calls this
+// method.
 void ReleaseOriginalFrame(
     const scoped_refptr<media::VideoFrame>& frame) {
 }
 
 }  // anonymous namespace
 
+// Helper class used for delivering video frames to all registered tracks
+// on the IO-thread.
+class MediaStreamVideoSource::FrameDeliverer : public VideoFrameDeliverer {
+ public:
+  FrameDeliverer(
+      const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
+      : VideoFrameDeliverer(io_message_loop)  {
+  }
+
+  // Register |callback| to receive video frames of max size
+  // |max_frame_output_size| on the IO thread.
+  // TODO(perkj): Currently |max_frame_output_size| must be the same for all
+  // |callbacks|.
+  void AddCallback(void* id,
+                   const VideoCaptureDeliverFrameCB& callback,
+                   const gfx::Size& max_frame_output_size) {
+    DCHECK(thread_checker().CalledOnValidThread());
+    io_message_loop()->PostTask(
+        FROM_HERE,
+        base::Bind(
+            &FrameDeliverer::AddCallbackWithResolutionOnIO,
+            this, id, callback, max_frame_output_size));
+  }
+
+  virtual void DeliverFrameOnIO(
+      const scoped_refptr<media::VideoFrame>& frame,
+      const media::VideoCaptureFormat& format) OVERRIDE {
+    DCHECK(io_message_loop()->BelongsToCurrentThread());
+    TRACE_EVENT0("video", "MediaStreamVideoSource::DeliverFrameOnIO");
+    if (max_output_size_.IsEmpty())
+      return;  // Frame received before the output has been decided.
+
+    scoped_refptr<media::VideoFrame> video_frame(frame);
+    const gfx::Size& visible_size = frame->visible_rect().size();
+    if (visible_size.width() > max_output_size_.width() ||
+        visible_size.height() > max_output_size_.height()) {
+      // If |frame| is not the size that is expected, we need to crop it by
+      // providing a new |visible_rect|. The new visible rect must be within the
+      // original |visible_rect|.
+      gfx::Rect output_rect = frame->visible_rect();
+      output_rect.ClampToCenteredSize(max_output_size_);
+      // TODO(perkj): Allow cropping of textures once http://crbug/362521 is
+      // fixed.
+      if (frame->format() != media::VideoFrame::NATIVE_TEXTURE) {
+        video_frame = media::VideoFrame::WrapVideoFrame(
+            frame,
+            output_rect,
+            output_rect.size(),
+            base::Bind(&ReleaseOriginalFrame, frame));
+      }
+    }
+    VideoFrameDeliverer::DeliverFrameOnIO(video_frame, format);
+  }
+
+ protected:
+  virtual ~FrameDeliverer() {
+  }
+
+  void AddCallbackWithResolutionOnIO(
+      void* id,
+     const VideoCaptureDeliverFrameCB& callback,
+      const gfx::Size& max_frame_output_size) {
+    DCHECK(io_message_loop()->BelongsToCurrentThread());
+    // Currently we only support one frame output size.
+    DCHECK(!max_frame_output_size.IsEmpty() &&
+           (max_output_size_.IsEmpty() ||
+            max_output_size_ == max_frame_output_size));
+    max_output_size_ = max_frame_output_size;
+    VideoFrameDeliverer::AddCallbackOnIO(id, callback);
+  }
+
+ private:
+  gfx::Size max_output_size_;
+};
+
 // static
 MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource(
     const blink::WebMediaStreamSource& source) {
@@ -301,14 +387,20 @@
 }
 
 MediaStreamVideoSource::MediaStreamVideoSource()
-    : state_(NEW) {
+    : state_(NEW),
+      frame_deliverer_(
+          new MediaStreamVideoSource::FrameDeliverer(
+              ChildProcess::current()->io_message_loop_proxy())),
+      weak_factory_(this) {
 }
 
 MediaStreamVideoSource::~MediaStreamVideoSource() {
+  DVLOG(3) << "~MediaStreamVideoSource()";
 }
 
 void MediaStreamVideoSource::AddTrack(
     MediaStreamVideoTrack* track,
+    const VideoCaptureDeliverFrameCB& frame_callback,
     const blink::WebMediaConstraints& constraints,
     const ConstraintsCallback& callback) {
   DCHECK(CalledOnValidThread());
@@ -317,7 +409,7 @@
   tracks_.push_back(track);
 
   requested_constraints_.push_back(
-      RequestedConstraints(constraints, callback));
+      RequestedConstraints(track, frame_callback, constraints, callback));
 
   switch (state_) {
     case NEW: {
@@ -330,8 +422,11 @@
       GetConstraintValue(constraints, true, kMaxHeight, &max_requested_height);
 
       state_ = RETRIEVING_CAPABILITIES;
-      GetCurrentSupportedFormats(max_requested_width,
-                                 max_requested_height);
+      GetCurrentSupportedFormats(
+          max_requested_width,
+          max_requested_height,
+          base::Bind(&MediaStreamVideoSource::OnSupportedFormats,
+                     weak_factory_.GetWeakPtr()));
 
       break;
     }
@@ -355,10 +450,19 @@
       std::find(tracks_.begin(), tracks_.end(), video_track);
   DCHECK(it != tracks_.end());
   tracks_.erase(it);
+  // Call |RemoveCallback| here even if adding the track has failed and
+  // frame_deliverer_->AddCallback has not been called.
+  frame_deliverer_->RemoveCallback(video_track);
+
   if (tracks_.empty())
     StopSource();
 }
 
+const scoped_refptr<base::MessageLoopProxy>&
+MediaStreamVideoSource::io_message_loop() const {
+  return frame_deliverer_->io_message_loop();
+}
+
 void MediaStreamVideoSource::DoStopSource() {
   DCHECK(CalledOnValidThread());
   DVLOG(3) << "DoStopSource()";
@@ -369,36 +473,6 @@
   SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded);
 }
 
-void MediaStreamVideoSource::DeliverVideoFrame(
-    const scoped_refptr<media::VideoFrame>& frame,
-    const media::VideoCaptureFormat& format) {
-  DCHECK(CalledOnValidThread());
-  scoped_refptr<media::VideoFrame> video_frame(frame);
-
-  if (frame->visible_rect().size().width() > max_frame_output_size_.width() ||
-      frame->visible_rect().size().height() > max_frame_output_size_.height()) {
-    // If |frame| is not the size that is expected, we need to crop it by
-    // providing a new |visible_rect|. The new visible rect must be within the
-    // original |visible_rect|.
-    gfx::Rect output_rect = frame->visible_rect();
-    output_rect.ClampToCenteredSize(max_frame_output_size_);
-    // TODO(perkj): Allow cropping of textures once http://crbug/362521 is
-    // fixed.
-    if (frame->format() != media::VideoFrame::NATIVE_TEXTURE) {
-      video_frame = media::VideoFrame::WrapVideoFrame(
-          frame,
-          output_rect,
-          output_rect.size(),
-          base::Bind(&ReleaseOriginalFrame, frame));
-    }
-  }
-
-  for (std::vector<MediaStreamVideoTrack*>::iterator it = tracks_.begin();
-       it != tracks_.end(); ++it) {
-    (*it)->OnVideoFrame(video_frame);
-  }
-}
-
 void MediaStreamVideoSource::OnSupportedFormats(
     const media::VideoCaptureFormats& formats) {
   DCHECK(CalledOnValidThread());
@@ -424,7 +498,10 @@
 
   media::VideoCaptureParams params;
   params.requested_format = current_format_;
-  StartSourceImpl(params);
+  StartSourceImpl(
+      params,
+      base::Bind(&MediaStreamVideoSource::FrameDeliverer::DeliverFrameOnIO,
+                 frame_deliverer_));
 }
 
 bool MediaStreamVideoSource::FindBestFormatWithConstraints(
@@ -439,6 +516,16 @@
     const blink::WebMediaConstraints& requested_constraints =
         request_it->constraints;
 
+    // If the source doesn't support capability enumeration it is still ok if
+    // no mandatory constraints have been specified. That just means that
+    // we will start with whatever format is native to the source.
+    if (formats.empty() && !HasMandatoryConstraints(requested_constraints)) {
+      *best_format = media::VideoCaptureFormat();
+      *resulting_constraints = requested_constraints;
+      *max_frame_output_size = gfx::Size(std::numeric_limits<int>::max(),
+                                         std::numeric_limits<int>::max());
+      return true;
+    }
     media::VideoCaptureFormats filtered_formats =
         FilterFormats(requested_constraints, formats);
     if (filtered_formats.size() > 0) {
@@ -480,8 +567,19 @@
   callbacks.swap(requested_constraints_);
   for (std::vector<RequestedConstraints>::iterator it = callbacks.begin();
        it != callbacks.end(); ++it) {
-    bool success = state_ == STARTED &&
-        !FilterFormats(it->constraints, formats).empty();
+    // The track has been added successfully if the source has started and
+    // there are either no mandatory constraints and the source doesn't expose
+    // its format capabilities, or the constraints and the format match.
+    // For example, a remote source doesn't expose its format capabilities.
+    bool success =
+        state_ == STARTED &&
+        ((!current_format_.IsValid() && !HasMandatoryConstraints(
+            it->constraints)) ||
+         !FilterFormats(it->constraints, formats).empty());
+    if (success) {
+      frame_deliverer_->AddCallback(it->track, it->frame_callback,
+                                    max_frame_output_size_);
+    }
     DVLOG(3) << "FinalizeAddTrack() success " << success;
     if (!it->callback.is_null())
       it->callback.Run(this, success);
@@ -500,9 +598,14 @@
 }
 
 MediaStreamVideoSource::RequestedConstraints::RequestedConstraints(
+    MediaStreamVideoTrack* track,
+    const VideoCaptureDeliverFrameCB& frame_callback,
     const blink::WebMediaConstraints& constraints,
     const ConstraintsCallback& callback)
-    : constraints(constraints), callback(callback) {
+    : track(track),
+      frame_callback(frame_callback),
+      constraints(constraints),
+      callback(callback) {
 }
 
 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() {
diff --git a/content/renderer/media/media_stream_video_source.h b/content/renderer/media/media_stream_video_source.h
index 933017c..34b9170 100644
--- a/content/renderer/media/media_stream_video_source.h
+++ b/content/renderer/media/media_stream_video_source.h
@@ -5,12 +5,16 @@
 #ifndef CONTENT_RENDERER_MEDIA_MEDIA_STREAM_VIDEO_SOURCE_H_
 #define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_VIDEO_SOURCE_H_
 
+#include <string>
 #include <vector>
 
 #include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
 #include "base/threading/non_thread_safe.h"
 #include "content/common/content_export.h"
+#include "content/common/media/video_capture.h"
 #include "content/renderer/media/media_stream_source.h"
+#include "content/renderer/media/video_frame_deliverer.h"
 #include "media/base/video_frame.h"
 #include "media/video/capture/video_capture_types.h"
 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
@@ -49,6 +53,7 @@
 
   // Puts |track| in the registered tracks list.
   void AddTrack(MediaStreamVideoTrack* track,
+                const VideoCaptureDeliverFrameCB& frame_callback,
                 const blink::WebMediaConstraints& constraints,
                 const ConstraintsCallback& callback);
   void RemoveTrack(MediaStreamVideoTrack* track);
@@ -56,6 +61,9 @@
   // Return true if |name| is a constraint supported by MediaStreamVideoSource.
   static bool IsConstraintSupported(const std::string& name);
 
+  // Returns the MessageLoopProxy where video frames will be delivered on.
+  const scoped_refptr<base::MessageLoopProxy>& io_message_loop() const;
+
   // Constraint keys used by a video source.
   // Specified by draft-alvestrand-constraints-resolution-00b
   static const char kMinAspectRatio[];  // minAspectRatio
@@ -79,30 +87,26 @@
   // Sets ready state and notifies the ready state to all registered tracks.
   virtual void SetReadyState(blink::WebMediaStreamSource::ReadyState state);
 
-  // Delivers |frame| to registered tracks according to their constraints.
-  // Note: current implementation assumes |frame| be contiguous layout of image
-  // planes and I420.
-  // |format| contains extra information like the frame rate of this source.
-  virtual void DeliverVideoFrame(const scoped_refptr<media::VideoFrame>& frame,
-                                 const media::VideoCaptureFormat& format);
-
   // An implementation must fetch the formats that can currently be used by
   // the source and call OnSupportedFormats when done.
   // |max_requested_height| and |max_requested_width| is the max height and
   // width set as a mandatory constraint if set when calling
   // MediaStreamVideoSource::AddTrack. If max height and max width is not set
   // |max_requested_height| and |max_requested_width| are 0.
-  virtual void GetCurrentSupportedFormats(int max_requested_width,
-                                          int max_requested_height) = 0;
-  void OnSupportedFormats(const media::VideoCaptureFormats& formats);
+  virtual void GetCurrentSupportedFormats(
+      int max_requested_width,
+      int max_requested_height,
+      const VideoCaptureDeviceFormatsCB& callback) = 0;
 
   // An implementation must start capture frames using the resolution in
   // |params|. When the source has started or the source failed to start
   // OnStartDone must be called. An implementation must call
-  // DeliverVideoFrame with the captured frames.
+  // invoke |frame_callback| on the IO thread with the captured frames.
   // TODO(perkj): pass a VideoCaptureFormats instead of VideoCaptureParams for
   // subclasses to customize.
-  virtual void StartSourceImpl(const media::VideoCaptureParams& params) = 0;
+  virtual void StartSourceImpl(
+      const media::VideoCaptureParams& params,
+      const VideoCaptureDeliverFrameCB& frame_callback) = 0;
   void OnStartDone(bool success);
 
   // An implementation must immediately stop capture video frames and must not
@@ -120,8 +124,7 @@
   State state() const { return state_; }
 
  private:
-  // Creates a webrtc::VideoSourceInterface used by libjingle.
-  void InitAdapter();
+  void OnSupportedFormats(const media::VideoCaptureFormats& formats);
 
   // Finds the first constraints in |requested_constraints_| that can be
   // fulfilled. |best_format| is set to the video resolution that can be
@@ -152,10 +155,14 @@
   gfx::Size max_frame_output_size_;
 
   struct RequestedConstraints {
-    RequestedConstraints(const blink::WebMediaConstraints& constraints,
+    RequestedConstraints(MediaStreamVideoTrack* track,
+                         const VideoCaptureDeliverFrameCB& frame_callback,
+                         const blink::WebMediaConstraints& constraints,
                          const ConstraintsCallback& callback);
     ~RequestedConstraints();
 
+    MediaStreamVideoTrack* track;
+    VideoCaptureDeliverFrameCB frame_callback;
     blink::WebMediaConstraints constraints;
     ConstraintsCallback callback;
   };
@@ -163,9 +170,17 @@
 
   media::VideoCaptureFormats supported_formats_;
 
+  // |FrameDeliverer| is an internal helper object used for delivering video
+  // frames using callbacks to all registered tracks on the IO thread.
+  class FrameDeliverer;
+  scoped_refptr<FrameDeliverer> frame_deliverer_;
+
   // Tracks that currently are receiving video frames.
   std::vector<MediaStreamVideoTrack*> tracks_;
 
+  // NOTE: Weak pointers must be invalidated before all other member variables.
+  base::WeakPtrFactory<MediaStreamVideoSource> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoSource);
 };
 
diff --git a/content/renderer/media/media_stream_video_source_unittest.cc b/content/renderer/media/media_stream_video_source_unittest.cc
index 1274cc5..1b1f204 100644
--- a/content/renderer/media/media_stream_video_source_unittest.cc
+++ b/content/renderer/media/media_stream_video_source_unittest.cc
@@ -6,24 +6,31 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/child/child_process.h"
 #include "content/renderer/media/media_stream_video_source.h"
 #include "content/renderer/media/media_stream_video_track.h"
 #include "content/renderer/media/mock_media_constraint_factory.h"
 #include "content/renderer/media/mock_media_stream_video_sink.h"
-#include "content/renderer/media/mock_media_stream_video_sink.h"
 #include "content/renderer/media/mock_media_stream_video_source.h"
 #include "media/base/video_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
 
+ACTION_P(RunClosure, closure) {
+  closure.Run();
+}
+
 class MediaStreamVideoSourceTest
     : public ::testing::Test {
  public:
   MediaStreamVideoSourceTest()
-      : number_of_successful_constraints_applied_(0),
+      : child_process_(new ChildProcess()),
+        number_of_successful_constraints_applied_(0),
         number_of_failed_constraints_applied_(0),
         mock_source_(new MockMediaStreamVideoSource(true)) {
     media::VideoCaptureFormats formats;
@@ -96,17 +103,13 @@
                            int expected_height) {
     // Expect the source to start capture with the supported resolution.
     blink::WebMediaStreamTrack track =
-        CreateTrackAndStartSource(constraints, capture_width, capture_height ,
+        CreateTrackAndStartSource(constraints, capture_width, capture_height,
                                   30);
 
     MockMediaStreamVideoSink sink;
     MediaStreamVideoSink::AddToVideoTrack(&sink, track);
-    EXPECT_EQ(0, sink.number_of_frames());
 
-    scoped_refptr<media::VideoFrame> frame =
-        media::VideoFrame::CreateBlackFrame(gfx::Size(capture_width,
-                                                      capture_height));
-    mock_source()->DeliverVideoFrame(frame, media::VideoCaptureFormat());
+    DeliverVideoFrameAndWaitForRenderer(capture_width, capture_height, &sink);
     EXPECT_EQ(1, sink.number_of_frames());
 
     // Expect the delivered frame to be cropped.
@@ -115,6 +118,19 @@
     MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
   }
 
+  void DeliverVideoFrameAndWaitForRenderer(int width, int height,
+                                           MockMediaStreamVideoSink* sink) {
+    base::RunLoop run_loop;
+    base::Closure quit_closure = run_loop.QuitClosure();
+    EXPECT_CALL(*sink, OnVideoFrame()).WillOnce(
+        RunClosure(quit_closure));
+    scoped_refptr<media::VideoFrame> frame =
+              media::VideoFrame::CreateBlackFrame(gfx::Size(width, height));
+    mock_source()->DeliverVideoFrame(frame);
+    run_loop.Run();
+  }
+
+
   void ReleaseTrackAndSourceOnAddTrackCallback(
       const blink::WebMediaStreamTrack& track_to_release) {
     track_to_release_ = track_to_release;
@@ -135,7 +151,8 @@
       track_to_release_.reset();
     }
   }
-
+  scoped_ptr<ChildProcess> child_process_;
+  base::MessageLoopForUI message_loop_;
   blink::WebMediaStreamTrack track_to_release_;
   int number_of_successful_constraints_applied_;
   int number_of_failed_constraints_applied_;
@@ -414,37 +431,22 @@
   MockMediaStreamVideoSink sink;
   MediaStreamVideoSink::AddToVideoTrack(&sink, track);
   EXPECT_EQ(0, sink.number_of_frames());
-
-  {
-    scoped_refptr<media::VideoFrame> frame1 =
-        media::VideoFrame::CreateBlackFrame(gfx::Size(320, 240));
-    mock_source()->DeliverVideoFrame(frame1,
-                                     media::VideoCaptureFormat());
-  }
+  DeliverVideoFrameAndWaitForRenderer(320, 240, &sink);
   EXPECT_EQ(1, sink.number_of_frames());
   // Expect the delivered frame to be passed unchanged since its smaller than
   // max requested.
   EXPECT_EQ(320, sink.frame_size().width());
   EXPECT_EQ(240, sink.frame_size().height());
 
-  {
-    scoped_refptr<media::VideoFrame> frame2 =
-          media::VideoFrame::CreateBlackFrame(gfx::Size(640, 480));
-    mock_source()->DeliverVideoFrame(frame2,
-                                     media::VideoCaptureFormat());
-  }
+  DeliverVideoFrameAndWaitForRenderer(640, 480, &sink);
   EXPECT_EQ(2, sink.number_of_frames());
   // Expect the delivered frame to be passed unchanged since its smaller than
   // max requested.
   EXPECT_EQ(640, sink.frame_size().width());
   EXPECT_EQ(480, sink.frame_size().height());
 
-  {
-    scoped_refptr<media::VideoFrame> frame3 =
-          media::VideoFrame::CreateBlackFrame(gfx::Size(1280, 720));
-    mock_source()->DeliverVideoFrame(frame3,
-                                     media::VideoCaptureFormat());
-  }
+  DeliverVideoFrameAndWaitForRenderer(1280, 720, &sink);
+
   EXPECT_EQ(3, sink.number_of_frames());
   // Expect a frame to be cropped since its larger than max requested.
   EXPECT_EQ(800, sink.frame_size().width());
diff --git a/content/renderer/media/media_stream_video_track.cc b/content/renderer/media/media_stream_video_track.cc
index f5cea67..577c7dc 100644
--- a/content/renderer/media/media_stream_video_track.cc
+++ b/content/renderer/media/media_stream_video_track.cc
@@ -4,9 +4,104 @@
 
 #include "content/renderer/media/media_stream_video_track.h"
 
+#include "base/bind.h"
+#include "content/renderer/media/video_frame_deliverer.h"
+#include "media/base/bind_to_current_loop.h"
+
 namespace content {
 
-//static
+// Helper class used for delivering video frames to MediaStreamSinks on the
+// IO-thread and MediaStreamVideoSinks on the main render thread.
+// Frames are delivered to an instance of this class from a
+// MediaStreamVideoSource on the IO-thread to the method DeliverFrameOnIO.
+// Frames are only delivered to the sinks if the track is enabled.
+class MediaStreamVideoTrack::FrameDeliverer : public VideoFrameDeliverer {
+ public:
+  FrameDeliverer(
+      const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
+      bool enabled)
+      : VideoFrameDeliverer(io_message_loop_proxy),
+        enabled_(enabled) {
+  }
+
+  // Add |sink| to receive frames and state changes on the main render thread.
+  void AddSink(MediaStreamVideoSink* sink) {
+    DCHECK(thread_checker().CalledOnValidThread());
+    DCHECK(std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end());
+    if (sinks_.empty()) {
+      VideoCaptureDeliverFrameCB frame_callback = media::BindToCurrentLoop(
+          base::Bind(
+              &MediaStreamVideoTrack::FrameDeliverer::OnVideoFrameOnMainThread,
+              this));
+      AddCallback(this, frame_callback);
+    }
+
+    sinks_.push_back(sink);
+  }
+
+  void RemoveSink(MediaStreamVideoSink* sink) {
+    DCHECK(thread_checker().CalledOnValidThread());
+    std::vector<MediaStreamVideoSink*>::iterator it =
+        std::find(sinks_.begin(), sinks_.end(), sink);
+    DCHECK(it != sinks_.end());
+    sinks_.erase(it);
+    if (sinks_.empty()) {
+      RemoveCallback(this);
+    }
+  }
+
+  // Called when a video frame is received on the main render thread.
+  // It delivers the received frames to the registered MediaStreamVideo sinks.
+  void OnVideoFrameOnMainThread(
+      const scoped_refptr<media::VideoFrame>& frame,
+      const media::VideoCaptureFormat& format) {
+    DCHECK(thread_checker().CalledOnValidThread());
+    for (std::vector<MediaStreamVideoSink*>::iterator it = sinks_.begin();
+         it != sinks_.end(); ++it) {
+      (*it)->OnVideoFrame(frame);
+    }
+  }
+
+  void SetEnabled(bool enabled) {
+    DCHECK(thread_checker().CalledOnValidThread());
+    io_message_loop()->PostTask(
+        FROM_HERE,
+        base::Bind(&MediaStreamVideoTrack::FrameDeliverer::SetEnabledOnIO,
+                   this, enabled));
+  }
+
+  virtual void DeliverFrameOnIO(
+      const scoped_refptr<media::VideoFrame>& frame,
+      const media::VideoCaptureFormat& format) OVERRIDE {
+    DCHECK(io_message_loop()->BelongsToCurrentThread());
+    if (!enabled_)
+      return;
+    VideoFrameDeliverer::DeliverFrameOnIO(frame, format);
+  }
+
+  const std::vector<MediaStreamVideoSink*>& sinks() const { return sinks_; }
+
+ protected:
+  virtual ~FrameDeliverer() {
+    DCHECK(sinks_.empty());
+  }
+
+  void SetEnabledOnIO(bool enabled) {
+    DCHECK(io_message_loop()->BelongsToCurrentThread());
+    enabled_ = enabled;
+  }
+
+ private:
+  // The below members are used on the main render thread.
+  std::vector<MediaStreamVideoSink*> sinks_;
+
+  // The below parameters are used on the IO-thread.
+  bool enabled_;
+
+  DISALLOW_COPY_AND_ASSIGN(FrameDeliverer);
+};
+
+// static
 blink::WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
     MediaStreamVideoSource* source,
     const blink::WebMediaConstraints& constraints,
@@ -33,37 +128,52 @@
     const MediaStreamVideoSource::ConstraintsCallback& callback,
     bool enabled)
     : MediaStreamTrack(NULL, true),
-      enabled_(enabled),
+      frame_deliverer_(
+          new MediaStreamVideoTrack::FrameDeliverer(source->io_message_loop(),
+                                                    enabled)),
       constraints_(constraints),
       source_(source) {
-  source->AddTrack(this, constraints, callback);
+  source->AddTrack(this,
+                   base::Bind(
+                       &MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO,
+                       frame_deliverer_),
+                   constraints, callback);
 }
 
 MediaStreamVideoTrack::~MediaStreamVideoTrack() {
-  DCHECK(sinks_.empty());
   Stop();
+  DVLOG(3) << "~MediaStreamVideoTrack()";
 }
 
 void MediaStreamVideoTrack::AddSink(MediaStreamVideoSink* sink) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end());
-  sinks_.push_back(sink);
+  frame_deliverer_->AddSink(sink);
 }
 
 void MediaStreamVideoTrack::RemoveSink(MediaStreamVideoSink* sink) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  std::vector<MediaStreamVideoSink*>::iterator it =
-      std::find(sinks_.begin(), sinks_.end(), sink);
-  DCHECK(it != sinks_.end());
-  sinks_.erase(it);
+  frame_deliverer_->RemoveSink(sink);
+}
+
+void MediaStreamVideoTrack::AddSink(
+    MediaStreamSink* sink, const VideoCaptureDeliverFrameCB& callback) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  frame_deliverer_->AddCallback(sink, callback);
+}
+
+void MediaStreamVideoTrack::RemoveSink(MediaStreamSink* sink) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  frame_deliverer_->RemoveCallback(sink);
 }
 
 void MediaStreamVideoTrack::SetEnabled(bool enabled) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  enabled_ = enabled;
   MediaStreamTrack::SetEnabled(enabled);
-  for (std::vector<MediaStreamVideoSink*>::iterator it = sinks_.begin();
-       it != sinks_.end(); ++it) {
+
+  frame_deliverer_->SetEnabled(enabled);
+  const std::vector<MediaStreamVideoSink*>& sinks = frame_deliverer_->sinks();
+  for (std::vector<MediaStreamVideoSink*>::const_iterator it = sinks.begin();
+       it != sinks.end(); ++it) {
     (*it)->OnEnabledChanged(enabled);
   }
 }
@@ -77,23 +187,12 @@
   OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded);
 }
 
-void MediaStreamVideoTrack::OnVideoFrame(
-    const scoped_refptr<media::VideoFrame>& frame) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (!enabled_)
-    return;
-
-  for (std::vector<MediaStreamVideoSink*>::iterator it = sinks_.begin();
-       it != sinks_.end(); ++it) {
-    (*it)->OnVideoFrame(frame);
-  }
-}
-
 void MediaStreamVideoTrack::OnReadyStateChanged(
     blink::WebMediaStreamSource::ReadyState state) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  for (std::vector<MediaStreamVideoSink*>::iterator it = sinks_.begin();
-       it != sinks_.end(); ++it) {
+  const std::vector<MediaStreamVideoSink*>& sinks = frame_deliverer_->sinks();
+  for (std::vector<MediaStreamVideoSink*>::const_iterator it = sinks.begin();
+       it != sinks.end(); ++it) {
     (*it)->OnReadyStateChanged(state);
   }
 }
diff --git a/content/renderer/media/media_stream_video_track.h b/content/renderer/media/media_stream_video_track.h
index c28ebb1..9fa8125 100644
--- a/content/renderer/media/media_stream_video_track.h
+++ b/content/renderer/media/media_stream_video_track.h
@@ -47,13 +47,21 @@
        const MediaStreamVideoSource::ConstraintsCallback& callback,
        bool enabled);
   virtual ~MediaStreamVideoTrack();
+
+  // Add |sink| to receive state changes and video frames on the main render
+  // thread.
   virtual void AddSink(MediaStreamVideoSink* sink);
   virtual void RemoveSink(MediaStreamVideoSink* sink);
 
+  // Add |sink| to receive state changes on the main render thread and video
+  // frames in the |callback| method on the IO-thread.
+  virtual void AddSink(MediaStreamSink* sink,
+                       const VideoCaptureDeliverFrameCB& callback);
+  virtual void RemoveSink(MediaStreamSink* sink);
+
   virtual void SetEnabled(bool enabled) OVERRIDE;
   virtual void Stop() OVERRIDE;
 
-  void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame);
   void OnReadyStateChanged(blink::WebMediaStreamSource::ReadyState state);
 
   const blink::WebMediaConstraints& constraints() const {
@@ -65,8 +73,11 @@
   base::ThreadChecker thread_checker_;
 
  private:
-  bool enabled_;
-  std::vector<MediaStreamVideoSink*> sinks_;
+  // |FrameDeliverer| is an internal helper object used for delivering video
+  // frames on the IO-thread using callbacks to all registered tracks.
+  class FrameDeliverer;
+  scoped_refptr<FrameDeliverer> frame_deliverer_;
+
   blink::WebMediaConstraints constraints_;
 
   // Weak ref to the source this tracks is connected to.  |source_| is owned
diff --git a/content/renderer/media/media_stream_video_track_unittest.cc b/content/renderer/media/media_stream_video_track_unittest.cc
index c10fba2..758c568 100644
--- a/content/renderer/media/media_stream_video_track_unittest.cc
+++ b/content/renderer/media/media_stream_video_track_unittest.cc
@@ -2,7 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/child/child_process.h"
 #include "content/renderer/media/media_stream_video_track.h"
 #include "content/renderer/media/mock_media_stream_video_sink.h"
 #include "content/renderer/media/mock_media_stream_video_source.h"
@@ -11,10 +14,15 @@
 
 namespace content {
 
+ACTION_P(RunClosure, closure) {
+  closure.Run();
+}
+
 class MediaStreamVideoTrackTest : public ::testing::Test {
  public:
   MediaStreamVideoTrackTest()
-      : mock_source_(new MockMediaStreamVideoSource(false)),
+      : child_process_(new ChildProcess()),
+        mock_source_(new MockMediaStreamVideoSource(false)),
         source_started_(false) {
     blink_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
                               blink::WebMediaStreamSource::TypeVideo,
@@ -22,7 +30,27 @@
     blink_source_.setExtraData(mock_source_);
   }
 
+  virtual ~MediaStreamVideoTrackTest() {
+  }
+
+  void DeliverVideoFrameAndWaitForRenderer(MockMediaStreamVideoSink* sink) {
+    base::RunLoop run_loop;
+    base::Closure quit_closure = run_loop.QuitClosure();
+    EXPECT_CALL(*sink, OnVideoFrame()).WillOnce(
+        RunClosure(quit_closure));
+    scoped_refptr<media::VideoFrame> frame =
+        media::VideoFrame::CreateBlackFrame(
+            gfx::Size(MediaStreamVideoSource::kDefaultWidth,
+                      MediaStreamVideoSource::kDefaultHeight));
+    mock_source()->DeliverVideoFrame(frame);
+    run_loop.Run();
+  }
+
  protected:
+  base::MessageLoop* io_message_loop() const {
+    return child_process_->io_message_loop();
+  }
+
   // Create a track that's associated with |mock_source_|.
   blink::WebMediaStreamTrack CreateTrack() {
     blink::WebMediaConstraints constraints;
@@ -45,6 +73,8 @@
   }
 
  private:
+  scoped_ptr<ChildProcess> child_process_;
+  base::MessageLoopForUI message_loop_;
   blink::WebMediaStreamSource blink_source_;
   // |mock_source_| is owned by |webkit_source_|.
   MockMediaStreamVideoSource* mock_source_;
@@ -56,19 +86,20 @@
   blink::WebMediaStreamTrack track = CreateTrack();
   MediaStreamVideoSink::AddToVideoTrack(&sink, track);
 
-  MediaStreamVideoTrack* video_track =
-        MediaStreamVideoTrack::GetVideoTrack(track);
+  DeliverVideoFrameAndWaitForRenderer(&sink);
+  EXPECT_EQ(1, sink.number_of_frames());
+
+  DeliverVideoFrameAndWaitForRenderer(&sink);
+
+  MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
+
   scoped_refptr<media::VideoFrame> frame =
       media::VideoFrame::CreateBlackFrame(
           gfx::Size(MediaStreamVideoSource::kDefaultWidth,
                     MediaStreamVideoSource::kDefaultHeight));
-  video_track->OnVideoFrame(frame);
-  EXPECT_EQ(1, sink.number_of_frames());
-  video_track->OnVideoFrame(frame);
-  EXPECT_EQ(2, sink.number_of_frames());
-
-  MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
-  video_track->OnVideoFrame(frame);
+  mock_source()->DeliverVideoFrame(frame);
+  // Wait for the IO thread to complete delivering frames.
+  io_message_loop()->RunUntilIdle();
   EXPECT_EQ(2, sink.number_of_frames());
 }
 
@@ -79,21 +110,26 @@
 
   MediaStreamVideoTrack* video_track =
       MediaStreamVideoTrack::GetVideoTrack(track);
-  scoped_refptr<media::VideoFrame> frame =
-      media::VideoFrame::CreateBlackFrame(
-          gfx::Size(MediaStreamVideoSource::kDefaultWidth,
-                    MediaStreamVideoSource::kDefaultHeight));
-  video_track->OnVideoFrame(frame);
+
+  DeliverVideoFrameAndWaitForRenderer(&sink);
   EXPECT_EQ(1, sink.number_of_frames());
 
   video_track->SetEnabled(false);
   EXPECT_FALSE(sink.enabled());
-  video_track->OnVideoFrame(frame);
+
+  scoped_refptr<media::VideoFrame> frame =
+      media::VideoFrame::CreateBlackFrame(
+          gfx::Size(MediaStreamVideoSource::kDefaultWidth,
+                    MediaStreamVideoSource::kDefaultHeight));
+  mock_source()->DeliverVideoFrame(frame);
+  // Wait for the IO thread to complete delivering frames.
+  io_message_loop()->RunUntilIdle();
   EXPECT_EQ(1, sink.number_of_frames());
 
   video_track->SetEnabled(true);
   EXPECT_TRUE(sink.enabled());
-  video_track->OnVideoFrame(frame);
+  mock_source()->DeliverVideoFrame(frame);
+  DeliverVideoFrameAndWaitForRenderer(&sink);
   EXPECT_EQ(2, sink.number_of_frames());
   MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track);
 }
diff --git a/content/renderer/media/midi_message_filter.cc b/content/renderer/media/midi_message_filter.cc
index f349c6e..cf950f7 100644
--- a/content/renderer/media/midi_message_filter.cc
+++ b/content/renderer/media/midi_message_filter.cc
@@ -100,26 +100,26 @@
 
 void MidiMessageFilter::OnSessionStarted(
     int client_id,
-    bool success,
+    media::MidiResult result,
     MidiPortInfoList inputs,
     MidiPortInfoList outputs) {
   // Handle on the main JS thread.
   main_message_loop_->PostTask(
       FROM_HERE,
       base::Bind(&MidiMessageFilter::HandleSessionStarted, this,
-                 client_id, success, inputs, outputs));
+                 client_id, result, inputs, outputs));
 }
 
 void MidiMessageFilter::HandleSessionStarted(
     int client_id,
-    bool success,
+    media::MidiResult result,
     MidiPortInfoList inputs,
     MidiPortInfoList outputs) {
   blink::WebMIDIAccessorClient* client = GetClientFromId(client_id);
   if (!client)
     return;
 
-  if (success) {
+  if (result == media::MIDI_OK) {
     // Add the client's input and output ports.
     for (size_t i = 0; i < inputs.size(); ++i) {
       client->didAddInputPort(
@@ -137,7 +137,26 @@
           base::UTF8ToUTF16(outputs[i].version));
     }
   }
-  client->didStartSession(success);
+  std::string error;
+  std::string message;
+  switch (result) {
+    case media::MIDI_OK:
+      break;
+    case media::MIDI_NOT_SUPPORTED:
+      error = "NotSupportedError";
+      break;
+    case media::MIDI_INITIALIZATION_ERROR:
+      error = "InvalidStateError";
+      message = "Platform dependent initialization failed.";
+      break;
+    default:
+      NOTREACHED();
+      error = "InvalidStateError";
+      message = "Unknown internal error occurred.";
+      break;
+  }
+  client->didStartSession(result == media::MIDI_OK, base::UTF8ToUTF16(error),
+                          base::UTF8ToUTF16(message));
 }
 
 blink::WebMIDIAccessorClient*
diff --git a/content/renderer/media/midi_message_filter.h b/content/renderer/media/midi_message_filter.h
index 8e1a7b6..017585c 100644
--- a/content/renderer/media/midi_message_filter.h
+++ b/content/renderer/media/midi_message_filter.h
@@ -12,6 +12,7 @@
 #include "content/common/content_export.h"
 #include "ipc/message_filter.h"
 #include "media/midi/midi_port_info.h"
+#include "media/midi/midi_result.h"
 #include "third_party/WebKit/public/platform/WebMIDIAccessorClient.h"
 
 namespace base {
@@ -61,7 +62,7 @@
   // Called when the browser process has approved (or denied) access to
   // MIDI hardware.
   void OnSessionStarted(int client_id,
-                        bool success,
+                        media::MidiResult result,
                         media::MidiPortInfoList inputs,
                         media::MidiPortInfoList outputs);
 
@@ -77,7 +78,7 @@
   void OnAcknowledgeSentData(size_t bytes_sent);
 
   void HandleSessionStarted(int client_id,
-                            bool success,
+                            media::MidiResult result,
                             media::MidiPortInfoList inputs,
                             media::MidiPortInfoList outputs);
 
diff --git a/content/renderer/media/mock_media_stream_video_sink.cc b/content/renderer/media/mock_media_stream_video_sink.cc
index ce9222f..4246a39 100644
--- a/content/renderer/media/mock_media_stream_video_sink.cc
+++ b/content/renderer/media/mock_media_stream_video_sink.cc
@@ -13,11 +13,15 @@
       state_(blink::WebMediaStreamSource::ReadyStateLive) {
 }
 
+MockMediaStreamVideoSink::~MockMediaStreamVideoSink() {
+}
+
 void MockMediaStreamVideoSink::OnVideoFrame(
     const scoped_refptr<media::VideoFrame>& frame) {
   ++number_of_frames_;
   format_ = frame->format();
   frame_size_ = frame->natural_size();
+  OnVideoFrame();
 }
 
 void MockMediaStreamVideoSink::OnReadyStateChanged(
diff --git a/content/renderer/media/mock_media_stream_video_sink.h b/content/renderer/media/mock_media_stream_video_sink.h
index 9511a0a..07ec43f 100644
--- a/content/renderer/media/mock_media_stream_video_sink.h
+++ b/content/renderer/media/mock_media_stream_video_sink.h
@@ -8,12 +8,14 @@
 #include "content/public/renderer/media_stream_video_sink.h"
 
 #include "media/base/video_frame.h"
+#include "testing/gmock/include/gmock/gmock.h"
 
 namespace content {
 
 class MockMediaStreamVideoSink : public MediaStreamVideoSink {
  public:
   MockMediaStreamVideoSink();
+  virtual ~MockMediaStreamVideoSink();
 
   virtual void OnVideoFrame(
       const scoped_refptr<media::VideoFrame>& frame) OVERRIDE;
@@ -21,6 +23,10 @@
         blink::WebMediaStreamSource::ReadyState state) OVERRIDE;
   virtual void OnEnabledChanged(bool enabled) OVERRIDE;
 
+  // Triggered when OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame)
+  // is called.
+  MOCK_METHOD0(OnVideoFrame,  void());
+
   int number_of_frames() const { return number_of_frames_; }
   media::VideoFrame::Format format() const { return format_; }
   gfx::Size frame_size() const { return frame_size_; }
diff --git a/content/renderer/media/mock_media_stream_video_source.cc b/content/renderer/media/mock_media_stream_video_source.cc
index 84a4479..12bddb4 100644
--- a/content/renderer/media/mock_media_stream_video_source.cc
+++ b/content/renderer/media/mock_media_stream_video_source.cc
@@ -4,21 +4,24 @@
 
 #include "content/renderer/media/mock_media_stream_video_source.h"
 
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/location.h"
+
 namespace content {
 
 MockMediaStreamVideoSource::MockMediaStreamVideoSource(
     bool manual_get_supported_formats)
-    : MediaStreamVideoSource(),
-      manual_get_supported_formats_(manual_get_supported_formats),
+    : manual_get_supported_formats_(manual_get_supported_formats),
       max_requested_height_(0),
       max_requested_width_(0),
       attempted_to_start_(false) {
   supported_formats_.push_back(
-          media::VideoCaptureFormat(
-              gfx::Size(MediaStreamVideoSource::kDefaultWidth,
-                        MediaStreamVideoSource::kDefaultHeight),
-              MediaStreamVideoSource::kDefaultFrameRate,
-              media::PIXEL_FORMAT_I420));
+      media::VideoCaptureFormat(
+          gfx::Size(MediaStreamVideoSource::kDefaultWidth,
+                    MediaStreamVideoSource::kDefaultHeight),
+          MediaStreamVideoSource::kDefaultFrameRate,
+          media::PIXEL_FORMAT_I420));
 }
 
 MockMediaStreamVideoSource::~MockMediaStreamVideoSource() {}
@@ -36,30 +39,53 @@
 }
 
 void MockMediaStreamVideoSource::CompleteGetSupportedFormats() {
-  OnSupportedFormats(supported_formats_);
+  DCHECK(!formats_callback_.is_null());
+  base::ResetAndReturn(&formats_callback_).Run(supported_formats_);
 }
 
 void MockMediaStreamVideoSource::GetCurrentSupportedFormats(
     int max_requested_height,
-    int max_requested_width) {
+    int max_requested_width,
+    const VideoCaptureDeviceFormatsCB& callback) {
+  DCHECK(formats_callback_.is_null());
   max_requested_height_ = max_requested_height;
   max_requested_width_ = max_requested_width;
 
-  if (!manual_get_supported_formats_)
-    OnSupportedFormats(supported_formats_);
+  if (manual_get_supported_formats_) {
+    formats_callback_ = callback;
+    return;
+  }
+  callback.Run(supported_formats_);
 }
 
 void MockMediaStreamVideoSource::StartSourceImpl(
-    const media::VideoCaptureParams& params) {
+    const media::VideoCaptureParams& params,
+    const VideoCaptureDeliverFrameCB& frame_callback) {
+  DCHECK(frame_callback_.is_null());
   params_ = params;
   attempted_to_start_ = true;
+  frame_callback_ = frame_callback;
 }
 
 void MockMediaStreamVideoSource::StopSourceImpl() {
 }
 
+void MockMediaStreamVideoSource::DeliverVideoFrame(
+    const scoped_refptr<media::VideoFrame>& frame) {
+  DCHECK(!frame_callback_.is_null());
+  io_message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&MockMediaStreamVideoSource::DeliverVideoFrameOnIO,
+                 base::Unretained(this), frame, params_.requested_format,
+                 frame_callback_));
+}
+
+void MockMediaStreamVideoSource::DeliverVideoFrameOnIO(
+    const scoped_refptr<media::VideoFrame>& frame,
+    media::VideoCaptureFormat format,
+    const VideoCaptureDeliverFrameCB& frame_callback) {
+  DCHECK(io_message_loop()->BelongsToCurrentThread());
+  frame_callback.Run(frame, format);
+}
+
 }  // namespace content
-
-
-
-
diff --git a/content/renderer/media/mock_media_stream_video_source.h b/content/renderer/media/mock_media_stream_video_source.h
index 33d3f70..d0d82e6 100644
--- a/content/renderer/media/mock_media_stream_video_source.h
+++ b/content/renderer/media/mock_media_stream_video_source.h
@@ -9,10 +9,9 @@
 
 namespace content {
 
-class MockMediaStreamVideoSource
-    : public MediaStreamVideoSource {
+class MockMediaStreamVideoSource : public MediaStreamVideoSource {
  public:
-  MockMediaStreamVideoSource(bool manual_get_supported_formats);
+  explicit MockMediaStreamVideoSource(bool manual_get_supported_formats);
   virtual ~MockMediaStreamVideoSource();
 
   // Simulate that the underlying source start successfully.
@@ -29,21 +28,30 @@
     supported_formats_ = formats;
   }
 
+  // Delivers |frame| to all registered tracks on the IO thread. Its up to the
+  // call to make sure MockMediaStreamVideoSource is not destroyed before the
+  // frame has been delivered.
+  void DeliverVideoFrame(const scoped_refptr<media::VideoFrame>& frame);
+
   void CompleteGetSupportedFormats();
 
   const media::VideoCaptureParams& start_params() const { return params_; }
   int max_requested_height() const { return max_requested_height_; }
   int max_requested_width() const { return max_requested_width_; }
 
-  using MediaStreamVideoSource::DeliverVideoFrame;
-
  protected:
+  void DeliverVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame,
+                             media::VideoCaptureFormat format,
+                             const VideoCaptureDeliverFrameCB& frame_callback);
+
   // Implements MediaStreamVideoSource.
   virtual void GetCurrentSupportedFormats(
       int max_requested_height,
-      int max_requested_width) OVERRIDE;
+      int max_requested_width,
+      const VideoCaptureDeviceFormatsCB& callback) OVERRIDE;
   virtual void StartSourceImpl(
-      const media::VideoCaptureParams& params) OVERRIDE;
+      const media::VideoCaptureParams& params,
+      const VideoCaptureDeliverFrameCB& frame_callback) OVERRIDE;
   virtual void StopSourceImpl() OVERRIDE;
 
  private:
@@ -53,6 +61,10 @@
   int max_requested_height_;
   int max_requested_width_;
   bool attempted_to_start_;
+  VideoCaptureDeviceFormatsCB formats_callback_;
+  VideoCaptureDeliverFrameCB frame_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockMediaStreamVideoSource);
 };
 
 }  // namespace content
diff --git a/content/renderer/media/mock_peer_connection_impl.cc b/content/renderer/media/mock_peer_connection_impl.cc
index 4dc55f3..c00c023 100644
--- a/content/renderer/media/mock_peer_connection_impl.cc
+++ b/content/renderer/media/mock_peer_connection_impl.cc
@@ -269,8 +269,8 @@
     return false;
 
   DCHECK_EQ(kStatsOutputLevelStandard, level);
-  std::vector<webrtc::StatsReport> reports;
-  webrtc::StatsReport report;
+  std::vector<webrtc::StatsReport> reports(track ? 1 : 2);
+  webrtc::StatsReport& report = reports[0];
   report.id = "1234";
   report.type = "ssrc";
   report.timestamp = 42;
@@ -278,17 +278,17 @@
   value.name = "trackname";
   value.value = "trackvalue";
   report.values.push_back(value);
-  reports.push_back(report);
   // If selector is given, we pass back one report.
   // If selector is not given, we pass back two.
   if (!track) {
-    report.id = "nontrack";
-    report.type = "generic";
-    report.timestamp = 44;
+    webrtc::StatsReport& report2 = reports[1];
+    report2.id = "nontrack";
+    report2.type = "generic";
+    report2.timestamp = 44;
+    report2.values.push_back(value);
     value.name = "somename";
     value.value = "somevalue";
-    report.values.push_back(value);
-    reports.push_back(report);
+    report2.values.push_back(value);
   }
   // Note that the callback is synchronous, not asynchronous; it will
   // happen before the request call completes.
@@ -355,4 +355,9 @@
   return candidate->ToString(&ice_sdp_);
 }
 
+void MockPeerConnectionImpl::RegisterUMAObserver(
+    webrtc::UMAObserver* observer) {
+  NOTIMPLEMENTED();
+}
+
 }  // namespace content
diff --git a/content/renderer/media/mock_peer_connection_impl.h b/content/renderer/media/mock_peer_connection_impl.h
index 20bf9af..ca23116 100644
--- a/content/renderer/media/mock_peer_connection_impl.h
+++ b/content/renderer/media/mock_peer_connection_impl.h
@@ -98,6 +98,7 @@
       const webrtc::MediaConstraintsInterface* constraints) OVERRIDE;
   virtual bool AddIceCandidate(
       const webrtc::IceCandidateInterface* candidate) OVERRIDE;
+  virtual void RegisterUMAObserver(webrtc::UMAObserver* observer) OVERRIDE;
 
   void AddRemoteStream(webrtc::MediaStreamInterface* stream);
 
diff --git a/content/renderer/media/rtc_data_channel_handler.cc b/content/renderer/media/rtc_data_channel_handler.cc
index 9d2b56c..1fe4de1 100644
--- a/content/renderer/media/rtc_data_channel_handler.cc
+++ b/content/renderer/media/rtc_data_channel_handler.cc
@@ -4,6 +4,7 @@
 
 #include "content/renderer/media/rtc_data_channel_handler.h"
 
+#include <limits>
 #include <string>
 
 #include "base/logging.h"
@@ -45,6 +46,13 @@
     IncrementCounter(CHANNEL_ORDERED);
   if (negotiated())
     IncrementCounter(CHANNEL_NEGOTIATED);
+
+  UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.DataChannelMaxRetransmits",
+                              maxRetransmits(), 0,
+                              std::numeric_limits<unsigned short>::max(), 50);
+  UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.DataChannelMaxRetransmitTime",
+                              maxRetransmitTime(), 0,
+                              std::numeric_limits<unsigned short>::max(), 50);
 }
 
 RtcDataChannelHandler::~RtcDataChannelHandler() {
diff --git a/content/renderer/media/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
index 1544020..93e5b23 100644
--- a/content/renderer/media/rtc_peer_connection_handler_unittest.cc
+++ b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
@@ -6,8 +6,10 @@
 #include <vector>
 
 #include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "content/child/child_process.h"
 #include "content/renderer/media/media_stream.h"
 #include "content/renderer/media/media_stream_audio_source.h"
 #include "content/renderer/media/media_stream_source.h"
@@ -198,6 +200,7 @@
 class RTCPeerConnectionHandlerTest : public ::testing::Test {
  public:
   RTCPeerConnectionHandlerTest() : mock_peer_connection_(NULL) {
+    child_process_.reset(new ChildProcess());
   }
 
   virtual void SetUp() {
@@ -284,7 +287,7 @@
     return stream;
   }
 
-  base::MessageLoop message_loop_;
+  scoped_ptr<ChildProcess> child_process_;
   scoped_ptr<MockWebRTCPeerConnectionHandlerClient> mock_client_;
   scoped_ptr<MockMediaStreamDependencyFactory> mock_dependency_factory_;
   scoped_ptr<NiceMock<MockPeerConnectionTracker> > mock_tracker_;
diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc
index 465c9fe..122fc06 100644
--- a/content/renderer/media/video_capture_impl.cc
+++ b/content/renderer/media/video_capture_impl.cc
@@ -136,8 +136,7 @@
   // that client list and don't have to run the other following RemoveClient().
   if (!RemoveClient(client_id, &clients_pending_on_filter_)) {
     if (!RemoveClient(client_id, &clients_pending_on_restart_)) {
-      bool removed = RemoveClient(client_id, &clients_);
-      DCHECK(removed) << "Removing a non-existent client.";
+      RemoveClient(client_id, &clients_);
     }
   }
 
diff --git a/content/renderer/media/video_capture_impl_unittest.cc b/content/renderer/media/video_capture_impl_unittest.cc
index 1f54b76..37dc014 100644
--- a/content/renderer/media/video_capture_impl_unittest.cc
+++ b/content/renderer/media/video_capture_impl_unittest.cc
@@ -95,6 +95,10 @@
       OnDeviceFormatsInUseReceived(media::VideoCaptureFormats());
     }
 
+    void ReceiveStateChangeMessage(VideoCaptureState state) {
+      OnStateChanged(state);
+    }
+
     const media::VideoCaptureParams& capture_params() const {
       return capture_params_;
     }
@@ -277,4 +281,32 @@
          params_small_.requested_format.frame_size);
 }
 
+TEST_F(VideoCaptureImplTest, EndedBeforeStop) {
+   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED));
+   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED));
+
+   Init();
+   StartCapture(0, params_small_);
+
+   // Receive state change message from browser.
+   video_capture_impl_->ReceiveStateChangeMessage(VIDEO_CAPTURE_STATE_ENDED);
+
+   StopCapture(0);
+   DeInit();
+}
+
+TEST_F(VideoCaptureImplTest, ErrorBeforeStop) {
+   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED));
+   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_ERROR));
+
+   Init();
+   StartCapture(0, params_small_);
+
+   // Receive state change message from browser.
+   video_capture_impl_->ReceiveStateChangeMessage(VIDEO_CAPTURE_STATE_ERROR);
+
+   StopCapture(0);
+   DeInit();
+}
+
 }  // namespace content
diff --git a/content/renderer/media/video_frame_compositor.cc b/content/renderer/media/video_frame_compositor.cc
index e991357..2d3bfd4 100644
--- a/content/renderer/media/video_frame_compositor.cc
+++ b/content/renderer/media/video_frame_compositor.cc
@@ -4,11 +4,6 @@
 
 #include "content/renderer/media/video_frame_compositor.h"
 
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "cc/layers/video_frame_provider.h"
-#include "content/renderer/render_thread_impl.h"
 #include "media/base/video_frame.h"
 
 namespace content {
@@ -20,6 +15,7 @@
     case media::VideoFrame::YV12J:
     case media::VideoFrame::YV16:
     case media::VideoFrame::I420:
+    case media::VideoFrame::NV12:
       return true;
 
     case media::VideoFrame::YV12A:
@@ -32,141 +28,49 @@
   return false;
 }
 
-class VideoFrameCompositor::Internal : public cc::VideoFrameProvider {
- public:
-  Internal(
-      const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner,
-      const base::Callback<void(gfx::Size)>& natural_size_changed_cb,
-      const base::Callback<void(bool)>& opacity_changed_cb)
-      : compositor_task_runner_(compositor_task_runner),
-        natural_size_changed_cb_(natural_size_changed_cb),
-        opacity_changed_cb_(opacity_changed_cb),
-        client_(NULL),
-        compositor_notification_pending_(false),
-        frames_dropped_before_compositor_was_notified_(0) {}
-
-  virtual ~Internal() {
-    if (client_)
-      client_->StopUsingProvider();
-  }
-
-  void DeleteSoon() {
-    compositor_task_runner_->DeleteSoon(FROM_HERE, this);
-  }
-
-  void UpdateCurrentFrame(const scoped_refptr<media::VideoFrame>& frame) {
-    base::AutoLock auto_lock(lock_);
-
-    if (current_frame_ &&
-        current_frame_->natural_size() != frame->natural_size()) {
-      natural_size_changed_cb_.Run(frame->natural_size());
-    }
-
-    if (!current_frame_ || IsOpaque(current_frame_) != IsOpaque(frame)) {
-      opacity_changed_cb_.Run(IsOpaque(frame));
-    }
-
-    current_frame_ = frame;
-
-    // Count frames as dropped if and only if we updated the frame but didn't
-    // finish notifying the compositor for the previous frame.
-    if (compositor_notification_pending_) {
-      if (frames_dropped_before_compositor_was_notified_ < kuint32max)
-        ++frames_dropped_before_compositor_was_notified_;
-      return;
-    }
-
-    compositor_notification_pending_ = true;
-    compositor_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&Internal::NotifyCompositorOfNewFrame,
-                   base::Unretained(this)));
-  }
-
-  uint32 GetFramesDroppedBeforeCompositorWasNotified() {
-    base::AutoLock auto_lock(lock_);
-    return frames_dropped_before_compositor_was_notified_;
-  }
-
-  void SetFramesDroppedBeforeCompositorWasNotifiedForTesting(
-      uint32 dropped_frames) {
-    base::AutoLock auto_lock(lock_);
-    frames_dropped_before_compositor_was_notified_ = dropped_frames;
-  }
-
-  // cc::VideoFrameProvider implementation.
-  virtual void SetVideoFrameProviderClient(
-      cc::VideoFrameProvider::Client* client) OVERRIDE {
-    if (client_)
-      client_->StopUsingProvider();
-    client_ = client;
-  }
-
-  virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() OVERRIDE {
-    base::AutoLock auto_lock(lock_);
-    return current_frame_;
-  }
-
-  virtual void PutCurrentFrame(const scoped_refptr<media::VideoFrame>& frame)
-      OVERRIDE {}
-
- private:
-  void NotifyCompositorOfNewFrame() {
-    base::AutoLock auto_lock(lock_);
-    compositor_notification_pending_ = false;
-    if (client_)
-      client_->DidReceiveFrame();
-  }
-
-  scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
-  base::Callback<void(gfx::Size)> natural_size_changed_cb_;
-  base::Callback<void(bool)> opacity_changed_cb_;
-
-  cc::VideoFrameProvider::Client* client_;
-
-  base::Lock lock_;
-  scoped_refptr<media::VideoFrame> current_frame_;
-  bool compositor_notification_pending_;
-  uint32 frames_dropped_before_compositor_was_notified_;
-
-  DISALLOW_COPY_AND_ASSIGN(Internal);
-};
-
 VideoFrameCompositor::VideoFrameCompositor(
-    const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner,
     const base::Callback<void(gfx::Size)>& natural_size_changed_cb,
     const base::Callback<void(bool)>& opacity_changed_cb)
-    : internal_(new Internal(compositor_task_runner,
-                             natural_size_changed_cb,
-                             opacity_changed_cb)) {
+    : natural_size_changed_cb_(natural_size_changed_cb),
+      opacity_changed_cb_(opacity_changed_cb),
+      client_(NULL) {
 }
 
 VideoFrameCompositor::~VideoFrameCompositor() {
-  internal_->DeleteSoon();
+  if (client_)
+    client_->StopUsingProvider();
 }
 
-cc::VideoFrameProvider* VideoFrameCompositor::GetVideoFrameProvider() {
-  return internal_;
+void VideoFrameCompositor::SetVideoFrameProviderClient(
+    cc::VideoFrameProvider::Client* client) {
+  if (client_)
+    client_->StopUsingProvider();
+  client_ = client;
+}
+
+scoped_refptr<media::VideoFrame> VideoFrameCompositor::GetCurrentFrame() {
+  return current_frame_;
+}
+
+void VideoFrameCompositor::PutCurrentFrame(
+    const scoped_refptr<media::VideoFrame>& frame) {
 }
 
 void VideoFrameCompositor::UpdateCurrentFrame(
     const scoped_refptr<media::VideoFrame>& frame) {
-  internal_->UpdateCurrentFrame(frame);
-}
+  if (current_frame_ &&
+      current_frame_->natural_size() != frame->natural_size()) {
+    natural_size_changed_cb_.Run(frame->natural_size());
+  }
 
-scoped_refptr<media::VideoFrame> VideoFrameCompositor::GetCurrentFrame() {
-  return internal_->GetCurrentFrame();
-}
+  if (!current_frame_ || IsOpaque(current_frame_) != IsOpaque(frame)) {
+    opacity_changed_cb_.Run(IsOpaque(frame));
+  }
 
-uint32 VideoFrameCompositor::GetFramesDroppedBeforeCompositorWasNotified() {
-  return internal_->GetFramesDroppedBeforeCompositorWasNotified();
-}
+  current_frame_ = frame;
 
-void
-VideoFrameCompositor::SetFramesDroppedBeforeCompositorWasNotifiedForTesting(
-    uint32 dropped_frames) {
-  internal_->SetFramesDroppedBeforeCompositorWasNotifiedForTesting(
-      dropped_frames);
+  if (client_)
+    client_->DidReceiveFrame();
 }
 
 }  // namespace content
diff --git a/content/renderer/media/video_frame_compositor.h b/content/renderer/media/video_frame_compositor.h
index 21654bd..91e5d0c 100644
--- a/content/renderer/media/video_frame_compositor.h
+++ b/content/renderer/media/video_frame_compositor.h
@@ -7,36 +7,27 @@
 
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
-#include "base/synchronization/lock.h"
+#include "cc/layers/video_frame_provider.h"
 #include "content/common/content_export.h"
 #include "ui/gfx/size.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace cc {
-class VideoFrameProvider;
-}
-
 namespace media {
 class VideoFrame;
 }
 
 namespace content {
 
-// VideoFrameCompositor handles incoming frames by notifying the compositor in a
-// thread-safe manner.
+// VideoFrameCompositor handles incoming frames by notifying the compositor and
+// dispatching callbacks when detecting changes in video frames.
 //
-// Typical usage is to deliver the output of VideoRendererImpl to
+// Typical usage is to deliver ready-to-be-displayed video frames to
 // UpdateCurrentFrame() so that VideoFrameCompositor can take care of tracking
-// dropped frames and firing callbacks as needed.
+// changes in video frames and firing callbacks as needed.
 //
-// All APIs are callable from any thread.
-class CONTENT_EXPORT VideoFrameCompositor {
+// VideoFrameCompositor must live on the same thread as the compositor.
+class CONTENT_EXPORT VideoFrameCompositor
+    : NON_EXPORTED_BASE(public cc::VideoFrameProvider) {
  public:
-  // |compositor_task_runner| is the task runner of the compositor.
-  //
   // |natural_size_changed_cb| is run with the new natural size of the video
   // frame whenever a change in natural size is detected. It is not called the
   // first time UpdateCurrentFrame() is called. Run on the same thread as the
@@ -50,33 +41,27 @@
   // respect to why we don't call |natural_size_changed_cb| on the first frame.
   // I suspect it was for historical reasons that no longer make sense.
   VideoFrameCompositor(
-      const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner,
       const base::Callback<void(gfx::Size)>& natural_size_changed_cb,
       const base::Callback<void(bool)>& opacity_changed_cb);
-  ~VideoFrameCompositor();
+  virtual ~VideoFrameCompositor();
 
-  cc::VideoFrameProvider* GetVideoFrameProvider();
+  // cc::VideoFrameProvider implementation.
+  virtual void SetVideoFrameProviderClient(
+      cc::VideoFrameProvider::Client* client) OVERRIDE;
+  virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() OVERRIDE;
+  virtual void PutCurrentFrame(
+      const scoped_refptr<media::VideoFrame>& frame) OVERRIDE;
 
   // Updates the current frame and notifies the compositor.
   void UpdateCurrentFrame(const scoped_refptr<media::VideoFrame>& frame);
 
-  // Retrieves the last frame set via UpdateCurrentFrame() for non-compositing
-  // purposes (e.g., painting to a canvas).
-  //
-  // Note that the compositor retrieves frames via the cc::VideoFrameProvider
-  // interface instead of using this method.
-  scoped_refptr<media::VideoFrame> GetCurrentFrame();
-
-  // Returns the number of frames dropped before the compositor was notified
-  // of a new frame.
-  uint32 GetFramesDroppedBeforeCompositorWasNotified();
-
-  void SetFramesDroppedBeforeCompositorWasNotifiedForTesting(
-      uint32 dropped_frames);
-
  private:
-  class Internal;
-  Internal* internal_;
+  base::Callback<void(gfx::Size)> natural_size_changed_cb_;
+  base::Callback<void(bool)> opacity_changed_cb_;
+
+  cc::VideoFrameProvider::Client* client_;
+
+  scoped_refptr<media::VideoFrame> current_frame_;
 
   DISALLOW_COPY_AND_ASSIGN(VideoFrameCompositor);
 };
diff --git a/content/renderer/media/video_frame_compositor_unittest.cc b/content/renderer/media/video_frame_compositor_unittest.cc
index 7aecad0..6669825 100644
--- a/content/renderer/media/video_frame_compositor_unittest.cc
+++ b/content/renderer/media/video_frame_compositor_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "base/bind.h"
-#include "base/message_loop/message_loop.h"
 #include "cc/layers/video_frame_provider.h"
 #include "content/renderer/media/video_frame_compositor.h"
 #include "media/base/video_frame.h"
@@ -18,7 +17,6 @@
  public:
   VideoFrameCompositorTest()
       : compositor_(new VideoFrameCompositor(
-            message_loop_.message_loop_proxy(),
             base::Bind(&VideoFrameCompositorTest::NaturalSizeChanged,
                        base::Unretained(this)),
             base::Bind(&VideoFrameCompositorTest::OpacityChanged,
@@ -27,20 +25,14 @@
         natural_size_changed_count_(0),
         opacity_changed_count_(0),
         opaque_(false) {
-    provider()->SetVideoFrameProviderClient(this);
+    compositor_->SetVideoFrameProviderClient(this);
   }
 
   virtual ~VideoFrameCompositorTest() {
-    provider()->SetVideoFrameProviderClient(NULL);
-    compositor_.reset();
-    message_loop_.RunUntilIdle();
+    compositor_->SetVideoFrameProviderClient(NULL);
   }
 
-  base::MessageLoop* message_loop() { return &message_loop_; }
   VideoFrameCompositor* compositor() { return compositor_.get(); }
-  cc::VideoFrameProvider* provider() {
-    return compositor_->GetVideoFrameProvider();
-  }
   int did_receive_frame_count() { return did_receive_frame_count_; }
   int natural_size_changed_count() { return natural_size_changed_count_; }
   gfx::Size natural_size() { return natural_size_; }
@@ -66,7 +58,6 @@
     opaque_ = opaque;
   }
 
-  base::MessageLoop message_loop_;
   scoped_ptr<VideoFrameCompositor> compositor_;
   int did_receive_frame_count_;
   int natural_size_changed_count_;
@@ -78,21 +69,17 @@
 };
 
 TEST_F(VideoFrameCompositorTest, InitialValues) {
-  EXPECT_TRUE(compositor()->GetVideoFrameProvider());
   EXPECT_FALSE(compositor()->GetCurrentFrame());
-  EXPECT_EQ(0u, compositor()->GetFramesDroppedBeforeCompositorWasNotified());
 }
 
 TEST_F(VideoFrameCompositorTest, UpdateCurrentFrame) {
   scoped_refptr<VideoFrame> expected = VideoFrame::CreateEOSFrame();
 
+  // Should notify compositor synchronously.
+  EXPECT_EQ(0, did_receive_frame_count());
   compositor()->UpdateCurrentFrame(expected);
   scoped_refptr<VideoFrame> actual = compositor()->GetCurrentFrame();
   EXPECT_EQ(expected, actual);
-
-  // Should notify compositor asynchronously.
-  EXPECT_EQ(0, did_receive_frame_count());
-  message_loop()->RunUntilIdle();
   EXPECT_EQ(1, did_receive_frame_count());
 }
 
@@ -172,38 +159,4 @@
   EXPECT_EQ(2, opacity_changed_count());
 }
 
-TEST_F(VideoFrameCompositorTest, GetFramesDroppedBeforeCompositorWasNotified) {
-  scoped_refptr<VideoFrame> frame = VideoFrame::CreateEOSFrame();
-
-  compositor()->UpdateCurrentFrame(frame);
-  EXPECT_EQ(0, did_receive_frame_count());
-  EXPECT_EQ(0u, compositor()->GetFramesDroppedBeforeCompositorWasNotified());
-
-  // Should not increment if we finished notifying the compositor.
-  //
-  // This covers the normal scenario where the compositor is getting
-  // notifications in a timely manner.
-  message_loop()->RunUntilIdle();
-  compositor()->UpdateCurrentFrame(frame);
-  EXPECT_EQ(1, did_receive_frame_count());
-  EXPECT_EQ(0u, compositor()->GetFramesDroppedBeforeCompositorWasNotified());
-
-  // Should increment if we didn't notify the compositor.
-  //
-  // This covers the scenario where the compositor is falling behind.
-  // Consider it dropped.
-  message_loop()->RunUntilIdle();
-  compositor()->UpdateCurrentFrame(frame);
-  compositor()->UpdateCurrentFrame(frame);
-  EXPECT_EQ(2, did_receive_frame_count());
-  EXPECT_EQ(1u, compositor()->GetFramesDroppedBeforeCompositorWasNotified());
-
-  // Shouldn't overflow.
-  compositor()->SetFramesDroppedBeforeCompositorWasNotifiedForTesting(
-      kuint32max);
-  compositor()->UpdateCurrentFrame(frame);
-  EXPECT_EQ(kuint32max,
-            compositor()->GetFramesDroppedBeforeCompositorWasNotified());
-}
-
 }  // namespace content
diff --git a/content/renderer/media/video_frame_deliverer.cc b/content/renderer/media/video_frame_deliverer.cc
new file mode 100644
index 0000000..67b11c4
--- /dev/null
+++ b/content/renderer/media/video_frame_deliverer.cc
@@ -0,0 +1,68 @@
+// 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.
+
+#include "content/renderer/media/video_frame_deliverer.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+
+namespace content {
+
+VideoFrameDeliverer::VideoFrameDeliverer(
+    const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
+    : io_message_loop_(io_message_loop) {
+  DCHECK(io_message_loop_);
+}
+
+VideoFrameDeliverer::~VideoFrameDeliverer() {
+  DCHECK(callbacks_.empty());
+}
+
+void VideoFrameDeliverer::AddCallback(
+    void* id,
+    const VideoCaptureDeliverFrameCB& callback) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  io_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&VideoFrameDeliverer::AddCallbackOnIO,
+                 this, id, callback));
+}
+
+void VideoFrameDeliverer::AddCallbackOnIO(
+    void* id,
+    const VideoCaptureDeliverFrameCB& callback) {
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  callbacks_.push_back(std::make_pair(id, callback));
+}
+
+void VideoFrameDeliverer::RemoveCallback(void* id) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  io_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&VideoFrameDeliverer::RemoveCallbackOnIO,
+                 this, id));
+}
+
+void VideoFrameDeliverer::RemoveCallbackOnIO(void* id) {
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  std::vector<VideoIdCallbackPair>::iterator it = callbacks_.begin();
+  for (; it != callbacks_.end(); ++it) {
+    if (it->first == id) {
+      callbacks_.erase(it);
+      return;
+    }
+  }
+}
+
+void VideoFrameDeliverer::DeliverFrameOnIO(
+    const scoped_refptr<media::VideoFrame>& frame,
+    const media::VideoCaptureFormat& format) {
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  for (std::vector<VideoIdCallbackPair>::iterator it = callbacks_.begin();
+       it != callbacks_.end(); ++it) {
+    it->second.Run(frame, format);
+  }
+}
+
+}  // namespace content
diff --git a/content/renderer/media/video_frame_deliverer.h b/content/renderer/media/video_frame_deliverer.h
new file mode 100644
index 0000000..f17c588
--- /dev/null
+++ b/content/renderer/media/video_frame_deliverer.h
@@ -0,0 +1,76 @@
+// 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.
+
+#ifndef CONTENT_RENDERER_MEDIA_VIDEO_FRAME_DELIVERER_H_
+#define CONTENT_RENDERER_MEDIA_VIDEO_FRAME_DELIVERER_H_
+
+#include <utility>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/threading/thread_checker.h"
+#include "content/common/media/video_capture.h"
+#include "media/base/video_frame.h"
+
+namespace content {
+
+// VideoFrameDeliverer is a helper class used for registering
+// VideoCaptureDeliverFrameCB on the main render thread to receive video frames
+// on the IO-thread.
+// Its used by MediaStreamVideoTrack and MediaStreamVideoSource.
+class VideoFrameDeliverer
+    : public base::RefCountedThreadSafe<VideoFrameDeliverer> {
+ public:
+  explicit VideoFrameDeliverer(
+      const scoped_refptr<base::MessageLoopProxy>& io_message_loop);
+
+  // Add |callback| to receive video frames on the IO-thread.
+  // Must be called on the main render thread.
+  void AddCallback(void* id, const VideoCaptureDeliverFrameCB& callback);
+  // Removes |callback| associated with |id| from receiving video frames if |id|
+  // has been added. It is ok to call RemoveCallback even if the |id| has not
+  // been added.
+  // Must be called on the main render thread.
+  void RemoveCallback(void* id);
+
+  // Triggers all registered callbacks with |frame| and |format| as parameters.
+  // Must be called on the IO-thread.
+  virtual void DeliverFrameOnIO(
+      const scoped_refptr<media::VideoFrame>& frame,
+      const media::VideoCaptureFormat& format);
+
+  const scoped_refptr<base::MessageLoopProxy>& io_message_loop() const {
+    return io_message_loop_;
+  }
+
+ protected:
+  void AddCallbackOnIO(void* id, const VideoCaptureDeliverFrameCB& callback);
+  // It is ok to call RemoveCallback even if |id| has not been added.
+  void RemoveCallbackOnIO(void* id);
+
+ protected:
+  virtual ~VideoFrameDeliverer();
+  const base::ThreadChecker& thread_checker() const {
+    return thread_checker_;
+  }
+
+ private:
+  friend class base::RefCountedThreadSafe<VideoFrameDeliverer>;
+
+  // Used to DCHECK that AddCallback and RemoveCallback are called on the main
+  // render thread.
+  base::ThreadChecker thread_checker_;
+  scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+
+  typedef std::pair<void*, VideoCaptureDeliverFrameCB> VideoIdCallbackPair;
+  std::vector<VideoIdCallbackPair> callbacks_;
+
+  DISALLOW_COPY_AND_ASSIGN(VideoFrameDeliverer);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_RENDERER_MEDIA_VIDEO_FRAME_DELIVERER_H_
diff --git a/content/renderer/media/video_source_handler_unittest.cc b/content/renderer/media/video_source_handler_unittest.cc
index 59b803d..1d66ca0 100644
--- a/content/renderer/media/video_source_handler_unittest.cc
+++ b/content/renderer/media/video_source_handler_unittest.cc
@@ -5,6 +5,7 @@
 #include <string>
 
 #include "base/strings/utf_string_conversions.h"
+#include "content/child/child_process.h"
 #include "content/public/renderer/media_stream_video_sink.h"
 #include "content/renderer/media/media_stream.h"
 #include "content/renderer/media/media_stream_registry_interface.h"
@@ -15,7 +16,6 @@
 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 
-
 namespace content {
 
 static const std::string kTestStreamUrl = "stream_url";
@@ -40,13 +40,16 @@
 
 class VideoSourceHandlerTest : public ::testing::Test {
  public:
-  VideoSourceHandlerTest() : registry_() {
+  VideoSourceHandlerTest()
+       : child_process_(new ChildProcess()),
+         registry_() {
     handler_.reset(new VideoSourceHandler(&registry_));
     registry_.Init(kTestStreamUrl);
     registry_.AddVideoTrack(kTestVideoTrackId);
   }
 
  protected:
+  scoped_ptr<ChildProcess> child_process_;
   scoped_ptr<VideoSourceHandler> handler_;
   MockMediaStreamRegistry registry_;
 };
diff --git a/content/renderer/media/webaudiosourceprovider_impl.cc b/content/renderer/media/webaudiosourceprovider_impl.cc
index 48bcf1c..4d878ce 100644
--- a/content/renderer/media/webaudiosourceprovider_impl.cc
+++ b/content/renderer/media/webaudiosourceprovider_impl.cc
@@ -114,7 +114,9 @@
   DCHECK(renderer_);
   DCHECK(client_);
   DCHECK_EQ(channels_, bus_wrapper_->channels());
-  renderer_->Render(bus_wrapper_.get(), 0);
+  const size_t frames = renderer_->Render(bus_wrapper_.get(), 0);
+  if (frames < number_of_frames)
+    bus_wrapper_->ZeroFramesPartial(frames, number_of_frames - frames);
   bus_wrapper_->Scale(volume_);
 }
 
diff --git a/content/renderer/media/webaudiosourceprovider_impl_unittest.cc b/content/renderer/media/webaudiosourceprovider_impl_unittest.cc
index e4786a5..8a59822 100644
--- a/content/renderer/media/webaudiosourceprovider_impl_unittest.cc
+++ b/content/renderer/media/webaudiosourceprovider_impl_unittest.cc
@@ -212,15 +212,27 @@
   wasp_impl_->provideInput(audio_data, params_.frames_per_buffer());
   ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get()));
 
+  // Ensure if a renderer properly fill silence for partial Render() calls by
+  // configuring the fake callback to return half the data.  After these calls
+  // bus1 is full of junk data, and bus2 is partially filled.
+  wasp_impl_->SetVolume(1);
+  fake_callback_.Render(bus1.get(), 0);
+  fake_callback_.reset();
+  fake_callback_.Render(bus2.get(), 0);
+  bus2->ZeroFramesPartial(bus2->frames() / 2,
+                          bus2->frames() - bus2->frames() / 2);
+  fake_callback_.reset();
+  fake_callback_.set_half_fill(true);
   wasp_impl_->Play();
 
-  // Play should return real audio data again...
+  // Play should return real audio data again, but the last half should be zero.
   wasp_impl_->provideInput(audio_data, params_.frames_per_buffer());
-  ASSERT_FALSE(CompareBusses(bus1.get(), bus2.get()));
+  ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get()));
 
   // Stop() should return silence.
   wasp_impl_->Stop();
   bus1->channel(0)[0] = 1;
+  bus2->Zero();
   wasp_impl_->provideInput(audio_data, params_.frames_per_buffer());
   ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get()));
 }
diff --git a/content/renderer/media/webcontentdecryptionmodule_impl.cc b/content/renderer/media/webcontentdecryptionmodule_impl.cc
index 38fe7a0..fa64ee7 100644
--- a/content/renderer/media/webcontentdecryptionmodule_impl.cc
+++ b/content/renderer/media/webcontentdecryptionmodule_impl.cc
@@ -40,7 +40,7 @@
 
   // TODO(ddorwin): Guard against this in supported types check and remove this.
   // Chromium only supports ASCII key systems.
-  if (!IsStringASCII(key_system)) {
+  if (!base::IsStringASCII(key_system)) {
     NOTREACHED();
     return NULL;
   }
diff --git a/content/renderer/media/webcontentdecryptionmodulesession_impl.cc b/content/renderer/media/webcontentdecryptionmodulesession_impl.cc
index 14fa798..76935ae 100644
--- a/content/renderer/media/webcontentdecryptionmodulesession_impl.cc
+++ b/content/renderer/media/webcontentdecryptionmodulesession_impl.cc
@@ -36,7 +36,7 @@
     const uint8* init_data, size_t init_data_length) {
   // TODO(ddorwin): Guard against this in supported types check and remove this.
   // Chromium only supports ASCII MIME types.
-  if (!IsStringASCII(mime_type)) {
+  if (!base::IsStringASCII(mime_type)) {
     NOTREACHED();
     OnSessionError(media::MediaKeys::kUnknownError, 0);
     return;
diff --git a/content/renderer/media/webmediaplayer_impl.cc b/content/renderer/media/webmediaplayer_impl.cc
index 75c1e7a..1f11498 100644
--- a/content/renderer/media/webmediaplayer_impl.cc
+++ b/content/renderer/media/webmediaplayer_impl.cc
@@ -171,12 +171,14 @@
       supports_save_(true),
       starting_(false),
       chunk_demuxer_(NULL),
-      compositor_(  // Threaded compositing isn't enabled universally yet.
-          (RenderThreadImpl::current()->compositor_message_loop_proxy()
-               ? RenderThreadImpl::current()->compositor_message_loop_proxy()
-               : base::MessageLoopProxy::current()),
+      // Threaded compositing isn't enabled universally yet.
+      compositor_task_runner_(
+          RenderThreadImpl::current()->compositor_message_loop_proxy()
+              ? RenderThreadImpl::current()->compositor_message_loop_proxy()
+              : base::MessageLoopProxy::current()),
+      compositor_(new VideoFrameCompositor(
           BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged),
-          BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged)),
+          BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged))),
       text_track_index_(0),
       web_cdm_(NULL) {
   media_log_->AddEvent(
@@ -232,6 +234,8 @@
       base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waiter)));
   waiter.Wait();
 
+  compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_);
+
   // Let V8 know we are not using extra resources anymore.
   if (incremented_externally_allocated_memory_) {
     v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
@@ -544,6 +548,7 @@
                                const WebRect& rect,
                                unsigned char alpha) {
   DCHECK(main_loop_->BelongsToCurrentThread());
+  TRACE_EVENT0("media", "WebMediaPlayerImpl:paint");
 
   if (!accelerated_compositing_reported_) {
     accelerated_compositing_reported_ = true;
@@ -560,9 +565,9 @@
   //   - We haven't reached HAVE_CURRENT_DATA and need to paint black
   //   - We're painting to a canvas
   // See http://crbug.com/341225 http://crbug.com/342621 for details.
-  scoped_refptr<media::VideoFrame> video_frame = compositor_.GetCurrentFrame();
+  scoped_refptr<media::VideoFrame> video_frame =
+      GetCurrentFrameFromCompositor();
 
-  TRACE_EVENT0("media", "WebMediaPlayerImpl:paint");
   gfx::Rect gfx_rect(rect);
   skcanvas_video_renderer_.Paint(video_frame.get(), canvas, gfx_rect, alpha);
 }
@@ -594,14 +599,7 @@
   DCHECK(main_loop_->BelongsToCurrentThread());
 
   media::PipelineStatistics stats = pipeline_.GetStatistics();
-
-  unsigned frames_dropped = stats.video_frames_dropped;
-
-  frames_dropped += const_cast<VideoFrameCompositor&>(compositor_)
-                        .GetFramesDroppedBeforeCompositorWasNotified();
-
-  DCHECK_LE(frames_dropped, stats.video_frames_decoded);
-  return frames_dropped;
+  return stats.video_frames_dropped;
 }
 
 unsigned WebMediaPlayerImpl::audioDecodedByteCount() const {
@@ -626,10 +624,11 @@
     unsigned int type,
     bool premultiply_alpha,
     bool flip_y) {
-  scoped_refptr<media::VideoFrame> video_frame = compositor_.GetCurrentFrame();
-
   TRACE_EVENT0("media", "WebMediaPlayerImpl:copyVideoTextureToPlatformTexture");
 
+  scoped_refptr<media::VideoFrame> video_frame =
+      GetCurrentFrameFromCompositor();
+
   if (!video_frame)
     return false;
   if (video_frame->format() != media::VideoFrame::NATIVE_TEXTURE)
@@ -747,7 +746,8 @@
 // Convert a WebString to ASCII, falling back on an empty string in the case
 // of a non-ASCII string.
 static std::string ToASCIIOrEmpty(const blink::WebString& string) {
-  return IsStringASCII(string) ? base::UTF16ToASCII(string) : std::string();
+  return base::IsStringASCII(string) ? base::UTF16ToASCII(string)
+                                     : std::string();
 }
 
 WebMediaPlayer::MediaKeyException
@@ -992,8 +992,8 @@
 
   if (hasVideo()) {
     DCHECK(!video_weblayer_);
-    video_weblayer_.reset(new webkit::WebLayerImpl(
-        cc::VideoLayer::Create(compositor_.GetVideoFrameProvider())));
+    video_weblayer_.reset(
+        new webkit::WebLayerImpl(cc::VideoLayer::Create(compositor_)));
     video_weblayer_->setOpaque(opaque_);
     client_->setWebLayer(video_weblayer_.get());
   }
@@ -1151,6 +1151,8 @@
   UMA_HISTOGRAM_BOOLEAN("Media.MSE.Playback",
                         (load_type_ == LoadTypeMediaSource));
 
+  media::LogCB mse_log_cb;
+
   // Figure out which demuxer to use.
   if (load_type_ != LoadTypeMediaSource) {
     DCHECK(!chunk_demuxer_);
@@ -1164,10 +1166,12 @@
     DCHECK(!chunk_demuxer_);
     DCHECK(!data_source_);
 
+    mse_log_cb = base::Bind(&LogMediaSourceError, media_log_);
+
     chunk_demuxer_ = new media::ChunkDemuxer(
         BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened),
         BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNeedKey),
-        base::Bind(&LogMediaSourceError, media_log_),
+        mse_log_cb,
         true);
     demuxer_.reset(chunk_demuxer_);
   }
@@ -1181,7 +1185,8 @@
 
   // Create our audio decoders and renderer.
   ScopedVector<media::AudioDecoder> audio_decoders;
-  audio_decoders.push_back(new media::FFmpegAudioDecoder(media_loop_));
+  audio_decoders.push_back(new media::FFmpegAudioDecoder(media_loop_,
+                                                         mse_log_cb));
   audio_decoders.push_back(new media::OpusAudioDecoder(media_loop_));
 
   scoped_ptr<media::AudioRenderer> audio_renderer(new media::AudioRendererImpl(
@@ -1310,7 +1315,11 @@
 
 void WebMediaPlayerImpl::FrameReady(
     const scoped_refptr<media::VideoFrame>& frame) {
-  compositor_.UpdateCurrentFrame(frame);
+  compositor_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&VideoFrameCompositor::UpdateCurrentFrame,
+                 base::Unretained(compositor_),
+                 frame));
 }
 
 void WebMediaPlayerImpl::SetDecryptorReadyCB(
@@ -1347,4 +1356,32 @@
   decryptor_ready_cb_ = decryptor_ready_cb;
 }
 
+static void GetCurrentFrameAndSignal(
+    VideoFrameCompositor* compositor,
+    scoped_refptr<media::VideoFrame>* video_frame_out,
+    base::WaitableEvent* event) {
+  TRACE_EVENT0("media", "GetCurrentFrameAndSignal");
+  *video_frame_out = compositor->GetCurrentFrame();
+  event->Signal();
+}
+
+scoped_refptr<media::VideoFrame>
+WebMediaPlayerImpl::GetCurrentFrameFromCompositor() {
+  TRACE_EVENT0("media", "WebMediaPlayerImpl::GetCurrentFrameFromCompositor");
+  if (compositor_task_runner_->BelongsToCurrentThread())
+    return compositor_->GetCurrentFrame();
+
+  // Use a posted task and waitable event instead of a lock otherwise
+  // WebGL/Canvas can see different content than what the compositor is seeing.
+  scoped_refptr<media::VideoFrame> video_frame;
+  base::WaitableEvent event(false, false);
+  compositor_task_runner_->PostTask(FROM_HERE,
+                                    base::Bind(&GetCurrentFrameAndSignal,
+                                               base::Unretained(compositor_),
+                                               &video_frame,
+                                               &event));
+  event.Wait();
+  return video_frame;
+}
+
 }  // namespace content
diff --git a/content/renderer/media/webmediaplayer_impl.h b/content/renderer/media/webmediaplayer_impl.h
index 1c3cb51..4bf0f6e 100644
--- a/content/renderer/media/webmediaplayer_impl.h
+++ b/content/renderer/media/webmediaplayer_impl.h
@@ -241,6 +241,10 @@
   // NULL immediately and reset.
   void SetDecryptorReadyCB(const media::DecryptorReadyCB& decryptor_ready_cb);
 
+  // Returns the current video frame from |compositor_|. Blocks until the
+  // compositor can return the frame.
+  scoped_refptr<media::VideoFrame> GetCurrentFrameFromCompositor();
+
   blink::WebLocalFrame* frame_;
 
   // TODO(hclam): get rid of these members and read from the pipeline directly.
@@ -332,7 +336,8 @@
   std::string init_data_type_;
 
   // Video rendering members.
-  VideoFrameCompositor compositor_;
+  scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
+  VideoFrameCompositor* compositor_;  // Deleted on |compositor_task_runner_|.
   media::SkCanvasVideoRenderer skcanvas_video_renderer_;
 
   // The compositor layer for displaying the video content when using composited
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source.cc b/content/renderer/media/webrtc/media_stream_remote_video_source.cc
index 97c810a..d2984f5 100644
--- a/content/renderer/media/webrtc/media_stream_remote_video_source.cc
+++ b/content/renderer/media/webrtc/media_stream_remote_video_source.cc
@@ -5,59 +5,71 @@
 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h"
 
 #include "base/bind.h"
+#include "base/callback_helpers.h"
 #include "base/location.h"
 #include "base/message_loop/message_loop_proxy.h"
 #include "content/renderer/media/native_handle_impl.h"
+#include "media/base/bind_to_current_loop.h"
 #include "media/base/video_frame.h"
+#include "media/base/video_frame_pool.h"
 #include "media/base/video_util.h"
 #include "third_party/libjingle/source/talk/media/base/videoframe.h"
 
 namespace content {
 
-MediaStreamRemoteVideoSource::MediaStreamRemoteVideoSource(
-    webrtc::VideoTrackInterface* remote_track)
-    : MediaStreamVideoSource(),
-      message_loop_proxy_(base::MessageLoopProxy::current()),
-      remote_track_(remote_track),
-      last_state_(remote_track_->state()),
-      first_frame_received_(false) {
-  remote_track_->AddRenderer(this);
-  remote_track_->RegisterObserver(this);
+// Internal class used for receiving frames from the webrtc track on a
+// libjingle thread and forward it to the IO-thread.
+class MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate
+    : public base::RefCountedThreadSafe<RemoteVideoSourceDelegate>,
+      public webrtc::VideoRendererInterface {
+ public:
+  RemoteVideoSourceDelegate(
+      const scoped_refptr<base::MessageLoopProxy>& io_message_loop,
+      const VideoCaptureDeliverFrameCB& new_frame_callback);
+
+ protected:
+  friend class base::RefCountedThreadSafe<RemoteVideoSourceDelegate>;
+  virtual ~RemoteVideoSourceDelegate();
+
+  // Implements webrtc::VideoRendererInterface used for receiving video frames
+  // from the PeerConnection video track. May be called on a libjingle internal
+  // thread.
+  virtual void SetSize(int width, int height) OVERRIDE;
+  virtual void RenderFrame(const cricket::VideoFrame* frame) OVERRIDE;
+
+  void DoRenderFrameOnIOThread(scoped_refptr<media::VideoFrame> video_frame,
+                               const media::VideoCaptureFormat& format);
+ private:
+  // Bound to the render thread.
+  base::ThreadChecker thread_checker_;
+
+  scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+  // |frame_pool_| is only accessed on whatever
+  // thread webrtc::VideoRendererInterface::RenderFrame is called on.
+  media::VideoFramePool frame_pool_;
+
+  // |frame_callback_| is accessed on the IO thread.
+  VideoCaptureDeliverFrameCB frame_callback_;
+};
+
+MediaStreamRemoteVideoSource::
+RemoteVideoSourceDelegate::RemoteVideoSourceDelegate(
+    const scoped_refptr<base::MessageLoopProxy>& io_message_loop,
+    const VideoCaptureDeliverFrameCB& new_frame_callback)
+    : io_message_loop_(io_message_loop),
+      frame_callback_(new_frame_callback) {
 }
 
-MediaStreamRemoteVideoSource::~MediaStreamRemoteVideoSource() {
-  StopSourceImpl();
+MediaStreamRemoteVideoSource::
+RemoteVideoSourceDelegate::~RemoteVideoSourceDelegate() {
 }
 
-void MediaStreamRemoteVideoSource::GetCurrentSupportedFormats(
-    int max_requested_width,
-    int max_requested_height) {
-  DCHECK(message_loop_proxy_->BelongsToCurrentThread());
-  if (format_.IsValid()) {
-    media::VideoCaptureFormats formats;
-    formats.push_back(format_);
-    OnSupportedFormats(formats);
-  }
+void MediaStreamRemoteVideoSource::
+RemoteVideoSourceDelegate::SetSize(int width, int height) {
 }
 
-void MediaStreamRemoteVideoSource::StartSourceImpl(
-    const media::VideoCaptureParams& params) {
-  DCHECK(message_loop_proxy_->BelongsToCurrentThread());
-  OnStartDone(true);
-}
-
-void MediaStreamRemoteVideoSource::StopSourceImpl() {
-  DCHECK(message_loop_proxy_->BelongsToCurrentThread());
-  if (state() != MediaStreamVideoSource::ENDED) {
-    remote_track_->RemoveRenderer(this);
-    remote_track_->UnregisterObserver(this);
-  }
-}
-
-void MediaStreamRemoteVideoSource::SetSize(int width, int height) {
-}
-
-void MediaStreamRemoteVideoSource::RenderFrame(
+void MediaStreamRemoteVideoSource::
+RemoteVideoSourceDelegate::RenderFrame(
     const cricket::VideoFrame* frame) {
   base::TimeDelta timestamp = base::TimeDelta::FromMilliseconds(
       frame->GetTimeStamp() / talk_base::kNumNanosecsPerMillisec);
@@ -87,32 +99,75 @@
         frame->GetVPlane(), frame->GetVPitch(), uv_rows, video_frame.get());
   }
 
-  if (!first_frame_received_) {
-    first_frame_received_ = true;
-    media::VideoPixelFormat pixel_format = (
-        video_frame->format() == media::VideoFrame::YV12) ?
-            media::PIXEL_FORMAT_YV12 : media::PIXEL_FORMAT_TEXTURE;
-    media::VideoCaptureFormat format(
-        gfx::Size(video_frame->natural_size().width(),
-                  video_frame->natural_size().height()),
-        MediaStreamVideoSource::kDefaultFrameRate,
-        pixel_format);
-    message_loop_proxy_->PostTask(
-        FROM_HERE,
-        base::Bind(&MediaStreamRemoteVideoSource::FrameFormatOnMainThread,
-                   AsWeakPtr(), format));
-  }
+  media::VideoPixelFormat pixel_format =
+      (video_frame->format() == media::VideoFrame::YV12) ?
+          media::PIXEL_FORMAT_YV12 : media::PIXEL_FORMAT_TEXTURE;
 
-  // TODO(perkj): Consider delivering the frame on whatever thread the frame is
-  // delivered on once crbug/335327 is fixed.
-  message_loop_proxy_->PostTask(
+  media::VideoCaptureFormat format(
+      gfx::Size(video_frame->natural_size().width(),
+                video_frame->natural_size().height()),
+                MediaStreamVideoSource::kDefaultFrameRate,
+                pixel_format);
+
+  io_message_loop_->PostTask(
       FROM_HERE,
-      base::Bind(&MediaStreamRemoteVideoSource::DoRenderFrameOnMainThread,
-                 AsWeakPtr(), video_frame));
+      base::Bind(&RemoteVideoSourceDelegate::DoRenderFrameOnIOThread,
+                 this, video_frame, format));
+}
+
+void MediaStreamRemoteVideoSource::
+RemoteVideoSourceDelegate::DoRenderFrameOnIOThread(
+    scoped_refptr<media::VideoFrame> video_frame,
+    const media::VideoCaptureFormat& format) {
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  frame_callback_.Run(video_frame, format);
+}
+
+MediaStreamRemoteVideoSource::MediaStreamRemoteVideoSource(
+    webrtc::VideoTrackInterface* remote_track)
+    : remote_track_(remote_track),
+      last_state_(remote_track->state()) {
+  remote_track_->RegisterObserver(this);
+}
+
+MediaStreamRemoteVideoSource::~MediaStreamRemoteVideoSource() {
+  remote_track_->UnregisterObserver(this);
+}
+
+void MediaStreamRemoteVideoSource::GetCurrentSupportedFormats(
+    int max_requested_width,
+    int max_requested_height,
+    const VideoCaptureDeviceFormatsCB& callback) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  media::VideoCaptureFormats formats;
+  // Since the remote end is free to change the resolution at any point in time
+  // the supported formats are unknown.
+  callback.Run(formats);
+}
+
+void MediaStreamRemoteVideoSource::StartSourceImpl(
+    const media::VideoCaptureParams& params,
+    const VideoCaptureDeliverFrameCB& frame_callback) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(!delegate_);
+  delegate_ = new RemoteVideoSourceDelegate(io_message_loop(), frame_callback);
+  remote_track_->AddRenderer(delegate_);
+  OnStartDone(true);
+}
+
+void MediaStreamRemoteVideoSource::StopSourceImpl() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(state() != MediaStreamVideoSource::ENDED);
+  remote_track_->RemoveRenderer(delegate_);
+}
+
+webrtc::VideoRendererInterface*
+MediaStreamRemoteVideoSource::RenderInterfaceForTest() {
+  return delegate_;
 }
 
 void MediaStreamRemoteVideoSource::OnChanged() {
-  DCHECK(message_loop_proxy_->BelongsToCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
   webrtc::MediaStreamTrackInterface::TrackState state = remote_track_->state();
   if (state != last_state_) {
     last_state_ = state;
@@ -134,22 +189,4 @@
   }
 }
 
-void MediaStreamRemoteVideoSource::FrameFormatOnMainThread(
-    const media::VideoCaptureFormat& format) {
-  DCHECK(message_loop_proxy_->BelongsToCurrentThread());
-  format_ = format;
-  if (state() == RETRIEVING_CAPABILITIES) {
-    media::VideoCaptureFormats formats;
-    formats.push_back(format);
-    OnSupportedFormats(formats);
-  }
-}
-
-void MediaStreamRemoteVideoSource::DoRenderFrameOnMainThread(
-    scoped_refptr<media::VideoFrame> video_frame) {
-  DCHECK(message_loop_proxy_->BelongsToCurrentThread());
-  if (state() == STARTED)
-    DeliverVideoFrame(video_frame, format_);
-}
-
 }  // namespace content
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source.h b/content/renderer/media/webrtc/media_stream_remote_video_source.h
index a409271..e7d65dd 100644
--- a/content/renderer/media/webrtc/media_stream_remote_video_source.h
+++ b/content/renderer/media/webrtc/media_stream_remote_video_source.h
@@ -5,10 +5,8 @@
 #ifndef CONTENT_RENDERER_MEDIA_WEBRTC_MEDIA_STREAM_REMOTE_VIDEO_SOURCE_H_
 #define CONTENT_RENDERER_MEDIA_WEBRTC_MEDIA_STREAM_REMOTE_VIDEO_SOURCE_H_
 
-#include "base/memory/weak_ptr.h"
 #include "content/common/content_export.h"
 #include "content/renderer/media/media_stream_video_source.h"
-#include "media/base/video_frame_pool.h"
 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
 
@@ -20,9 +18,7 @@
 // a local source and a video track where the source is a remote video track.
 class CONTENT_EXPORT MediaStreamRemoteVideoSource
      : public MediaStreamVideoSource,
-       NON_EXPORTED_BASE(public webrtc::VideoRendererInterface),
-       NON_EXPORTED_BASE(public webrtc::ObserverInterface),
-       public base::SupportsWeakPtr<MediaStreamRemoteVideoSource> {
+       NON_EXPORTED_BASE(public webrtc::ObserverInterface) {
  public:
   explicit MediaStreamRemoteVideoSource(
       webrtc::VideoTrackInterface* remote_track);
@@ -32,37 +28,33 @@
   // Implements MediaStreamVideoSource.
   virtual void GetCurrentSupportedFormats(
       int max_requested_width,
-      int max_requested_height) OVERRIDE;
+      int max_requested_height,
+      const VideoCaptureDeviceFormatsCB& callback) OVERRIDE;
 
   virtual void StartSourceImpl(
-      const media::VideoCaptureParams& params) OVERRIDE;
+      const media::VideoCaptureParams& params,
+      const VideoCaptureDeliverFrameCB& frame_callback) OVERRIDE;
 
   virtual void StopSourceImpl() OVERRIDE;
 
-  // Implements webrtc::VideoRendererInterface used for receiving video frames
-  // from the PeerConnection video track. May be called on
-  // a different thread.
-  virtual void SetSize(int width, int height) OVERRIDE;
-  virtual void RenderFrame(const cricket::VideoFrame* frame) OVERRIDE;
+  // Used by tests to test that a frame can be received and that the
+  // MediaStreamRemoteVideoSource behaves as expected.
+  webrtc::VideoRendererInterface* RenderInterfaceForTest();
 
+ private:
   // webrtc::ObserverInterface implementation.
   virtual void OnChanged() OVERRIDE;
 
- private:
-  void FrameFormatOnMainThread(const media::VideoCaptureFormat& format);
-  void DoRenderFrameOnMainThread(scoped_refptr<media::VideoFrame> video_frame);
-
-  scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
   scoped_refptr<webrtc::VideoTrackInterface> remote_track_;
   webrtc::MediaStreamTrackInterface::TrackState last_state_;
 
-  // |first_frame_received_| and |frame_pool_| are only accessed on whatever
-  // thread webrtc::VideoRendererInterface::RenderFrame is called on.
-  bool first_frame_received_;
-  media::VideoFramePool frame_pool_;
+  // Internal class used for receiving frames from the webrtc track on a
+  // libjingle thread and forward it to the IO-thread.
+  class RemoteVideoSourceDelegate;
+  scoped_refptr<RemoteVideoSourceDelegate> delegate_;
 
-  // |format_| is the format currently received by this source.
-  media::VideoCaptureFormat format_;
+  // Bound to the render thread.
+  base::ThreadChecker thread_checker_;
 
   DISALLOW_COPY_AND_ASSIGN(MediaStreamRemoteVideoSource);
 };
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc b/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
index 0b6b327..16c3687 100644
--- a/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
+++ b/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "content/public/renderer/media_stream_video_sink.h"
+#include "content/child/child_process.h"
 #include "content/renderer/media/media_stream_video_track.h"
 #include "content/renderer/media/mock_media_stream_dependency_factory.h"
+#include "content/renderer/media/mock_media_stream_video_sink.h"
 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h"
 #include "media/base/video_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -13,30 +16,9 @@
 
 namespace content {
 
-class MockVideoSink : public MediaStreamVideoSink {
- public:
-  MockVideoSink()
-      : number_of_frames_(0),
-        state_(blink::WebMediaStreamSource::ReadyStateLive) {
-  }
-
-  virtual void OnVideoFrame(
-      const scoped_refptr<media::VideoFrame>& frame) OVERRIDE {
-    ++number_of_frames_;
-  }
-
-  virtual void OnReadyStateChanged(
-      blink::WebMediaStreamSource::ReadyState state) OVERRIDE {
-    state_ = state;
-  }
-
-  int number_of_frames() const { return number_of_frames_; }
-  blink::WebMediaStreamSource::ReadyState state() const { return state_; }
-
- private:
-  int number_of_frames_;
-  blink::WebMediaStreamSource::ReadyState state_;
-};
+ACTION_P(RunClosure, closure) {
+  closure.Run();
+}
 
 class MediaStreamRemoteVideoSourceUnderTest
     : public MediaStreamRemoteVideoSource {
@@ -44,14 +26,15 @@
   MediaStreamRemoteVideoSourceUnderTest(webrtc::VideoTrackInterface* track)
       : MediaStreamRemoteVideoSource(track) {
   }
-  using MediaStreamRemoteVideoSource::RenderFrame;
+ using MediaStreamRemoteVideoSource::RenderInterfaceForTest;
 };
 
 class MediaStreamRemoteVideoSourceTest
     : public ::testing::Test {
  public:
   MediaStreamRemoteVideoSourceTest()
-      : mock_factory_(new MockMediaStreamDependencyFactory()),
+      : child_process_(new ChildProcess()),
+        mock_factory_(new MockMediaStreamDependencyFactory()),
         webrtc_video_track_(
             mock_factory_->CreateLocalVideoTrack(
                 "test",
@@ -65,7 +48,6 @@
                               base::UTF8ToUTF16("dummy_source_name"));
     webkit_source_.setExtraData(remote_source_);
   }
-  virtual ~MediaStreamRemoteVideoSourceTest() {}
 
   MediaStreamRemoteVideoSourceUnderTest* source() {
     return remote_source_;
@@ -97,8 +79,6 @@
         webrtc::MediaStreamTrackInterface::kEnded);
   }
 
-  base::MessageLoop* message_loop() { return &message_loop_; }
-
   const blink::WebMediaStreamSource& webkit_source() const {
     return  webkit_source_;
   }
@@ -112,7 +92,8 @@
       ++number_of_failed_constraints_applied_;
   }
 
-  base::MessageLoop message_loop_;
+  scoped_ptr<ChildProcess> child_process_;
+  base::MessageLoopForUI message_loop_;
   scoped_ptr<MockMediaStreamDependencyFactory> mock_factory_;
   scoped_refptr<webrtc::VideoTrackInterface> webrtc_video_track_;
   // |remote_source_| is owned by |webkit_source_|.
@@ -124,17 +105,22 @@
 
 TEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) {
   scoped_ptr<MediaStreamVideoTrack> track(CreateTrack());
-  EXPECT_EQ(0, NumberOfSuccessConstraintsCallbacks());
+  EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
 
-  MockVideoSink sink;
+  MockMediaStreamVideoSink sink;
   track->AddSink(&sink);
 
+
+
+  base::RunLoop run_loop;
+  base::Closure quit_closure = run_loop.QuitClosure();
+  EXPECT_CALL(sink, OnVideoFrame()).WillOnce(
+      RunClosure(quit_closure));
   cricket::WebRtcVideoFrame webrtc_frame;
   webrtc_frame.InitToBlack(320, 240, 1, 1, 0, 1);
-  source()->RenderFrame(&webrtc_frame);
-  message_loop()->RunUntilIdle();
+  source()->RenderInterfaceForTest()->RenderFrame(&webrtc_frame);
+  run_loop.Run();
 
-  EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
   EXPECT_EQ(1, sink.number_of_frames());
   track->RemoveSink(&sink);
 }
@@ -142,7 +128,7 @@
 TEST_F(MediaStreamRemoteVideoSourceTest, RemoteTrackStop) {
   scoped_ptr<MediaStreamVideoTrack> track(CreateTrack());
 
-  MockVideoSink sink;
+  MockMediaStreamVideoSink sink;
   track->AddSink(&sink);
 
   EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink.state());
diff --git a/content/renderer/media/webrtc/video_destination_handler.cc b/content/renderer/media/webrtc/video_destination_handler.cc
index 3335293..c8eff87 100644
--- a/content/renderer/media/webrtc/video_destination_handler.cc
+++ b/content/renderer/media/webrtc/video_destination_handler.cc
@@ -24,8 +24,53 @@
 
 namespace content {
 
-PpFrameWriter::PpFrameWriter()
-    : MediaStreamVideoSource(), first_frame_received_(false) {
+class PpFrameWriter::FrameWriterDelegate
+    : public base::RefCountedThreadSafe<FrameWriterDelegate> {
+ public:
+  FrameWriterDelegate(
+      const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
+      const VideoCaptureDeliverFrameCB& new_frame_callback);
+
+  void DeliverFrame(const scoped_refptr<media::VideoFrame>& frame,
+                    const media::VideoCaptureFormat& format);
+ private:
+  friend class base::RefCountedThreadSafe<FrameWriterDelegate>;
+  virtual ~FrameWriterDelegate();
+
+  void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame,
+                        const media::VideoCaptureFormat& format);
+
+  scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+  VideoCaptureDeliverFrameCB new_frame_callback_;
+};
+
+PpFrameWriter::FrameWriterDelegate::FrameWriterDelegate(
+    const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
+    const VideoCaptureDeliverFrameCB& new_frame_callback)
+    : io_message_loop_(io_message_loop_proxy),
+      new_frame_callback_(new_frame_callback) {
+}
+
+PpFrameWriter::FrameWriterDelegate::~FrameWriterDelegate() {
+}
+
+void PpFrameWriter::FrameWriterDelegate::DeliverFrame(
+    const scoped_refptr<media::VideoFrame>& frame,
+    const media::VideoCaptureFormat& format) {
+  io_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&FrameWriterDelegate::DeliverFrameOnIO,
+                 this, frame, format));
+}
+
+void PpFrameWriter::FrameWriterDelegate::DeliverFrameOnIO(
+     const scoped_refptr<media::VideoFrame>& frame,
+     const media::VideoCaptureFormat& format) {
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  new_frame_callback_.Run(frame, format);
+}
+
+PpFrameWriter::PpFrameWriter() {
   DVLOG(3) << "PpFrameWriter ctor";
 }
 
@@ -33,21 +78,25 @@
   DVLOG(3) << "PpFrameWriter dtor";
 }
 
-void PpFrameWriter::GetCurrentSupportedFormats(int max_requested_width,
-                                               int max_requested_height) {
+void PpFrameWriter::GetCurrentSupportedFormats(
+    int max_requested_width,
+    int max_requested_height,
+    const VideoCaptureDeviceFormatsCB& callback) {
   DCHECK(CalledOnValidThread());
   DVLOG(3) << "PpFrameWriter::GetCurrentSupportedFormats()";
-  if (format_.IsValid()) {
-    media::VideoCaptureFormats formats;
-    formats.push_back(format_);
-    OnSupportedFormats(formats);
-  }
+  // Since the input is free to change the resolution at any point in time
+  // the supported formats are unknown.
+  media::VideoCaptureFormats formats;
+  callback.Run(formats);
 }
 
 void PpFrameWriter::StartSourceImpl(
-    const media::VideoCaptureParams& params) {
+    const media::VideoCaptureParams& params,
+    const VideoCaptureDeliverFrameCB& frame_callback) {
   DCHECK(CalledOnValidThread());
+  DCHECK(!delegate_);
   DVLOG(3) << "PpFrameWriter::StartSourceImpl()";
+  delegate_ = new FrameWriterDelegate(io_message_loop(), frame_callback);
   OnStartDone(true);
 }
 
@@ -79,19 +128,6 @@
 
   const gfx::Size frame_size(bitmap->width(), bitmap->height());
 
-  if (!first_frame_received_) {
-    first_frame_received_ = true;
-    format_ = media::VideoCaptureFormat(
-        frame_size,
-        MediaStreamVideoSource::kDefaultFrameRate,
-        media::PIXEL_FORMAT_YV12);
-    if (state() == MediaStreamVideoSource::RETRIEVING_CAPABILITIES) {
-      media::VideoCaptureFormats formats;
-      formats.push_back(format_);
-      OnSupportedFormats(formats);
-    }
-  }
-
   if (state() != MediaStreamVideoSource::STARTED)
     return;
 
@@ -105,6 +141,10 @@
   scoped_refptr<media::VideoFrame> new_frame =
       frame_pool_.CreateFrame(media::VideoFrame::YV12, frame_size,
                               gfx::Rect(frame_size), frame_size, timestamp);
+  media::VideoCaptureFormat format(
+      frame_size,
+      MediaStreamVideoSource::kDefaultFrameRate,
+      media::PIXEL_FORMAT_YV12);
 
   libyuv::BGRAToI420(reinterpret_cast<uint8*>(bitmap->getPixels()),
                      bitmap->rowBytes(),
@@ -116,7 +156,7 @@
                      new_frame->stride(media::VideoFrame::kVPlane),
                      frame_size.width(), frame_size.height());
 
-  DeliverVideoFrame(new_frame, format_);
+  delegate_->DeliverFrame(new_frame, format);
 }
 
 // PpFrameWriterProxy is a helper class to make sure the user won't use
@@ -167,6 +207,7 @@
   // theoretically it's possible we can get an id that's duplicated with the
   // existing sources.
   base::Base64Encode(base::RandBytesAsString(64), &track_id);
+
   PpFrameWriter* writer = new PpFrameWriter();
 
   // Create a new webkit video track.
diff --git a/content/renderer/media/webrtc/video_destination_handler.h b/content/renderer/media/webrtc/video_destination_handler.h
index b13d26d..0b6641c 100644
--- a/content/renderer/media/webrtc/video_destination_handler.h
+++ b/content/renderer/media/webrtc/video_destination_handler.h
@@ -49,18 +49,21 @@
                         int64 time_stamp_ns) OVERRIDE;
  protected:
   // MediaStreamVideoSource implementation.
-  virtual void GetCurrentSupportedFormats(int max_requested_width,
-                                          int max_requested_height) OVERRIDE;
+  virtual void GetCurrentSupportedFormats(
+      int max_requested_width,
+      int max_requested_height,
+      const VideoCaptureDeviceFormatsCB& callback) OVERRIDE;
   virtual void StartSourceImpl(
-      const media::VideoCaptureParams& params) OVERRIDE;
+      const media::VideoCaptureParams& params,
+      const VideoCaptureDeliverFrameCB& frame_callback) OVERRIDE;
   virtual void StopSourceImpl() OVERRIDE;
 
  private:
-  // |format_| is the format currently received by this source.
-  media::VideoCaptureFormat format_;
-  bool first_frame_received_;
   media::VideoFramePool frame_pool_;
 
+  class FrameWriterDelegate;
+  scoped_refptr<FrameWriterDelegate> delegate_;
+
   DISALLOW_COPY_AND_ASSIGN(PpFrameWriter);
 };
 
diff --git a/content/renderer/media/webrtc/video_destination_handler_unittest.cc b/content/renderer/media/webrtc/video_destination_handler_unittest.cc
index fb3d863..062c277 100644
--- a/content/renderer/media/webrtc/video_destination_handler_unittest.cc
+++ b/content/renderer/media/webrtc/video_destination_handler_unittest.cc
@@ -4,7 +4,10 @@
 
 #include <string>
 
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/child/child_process.h"
 #include "content/renderer/media/media_stream.h"
 #include "content/renderer/media/media_stream_video_track.h"
 #include "content/renderer/media/mock_media_stream_registry.h"
@@ -13,22 +16,36 @@
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
 #include "content/renderer/pepper/ppb_image_data_impl.h"
 #include "content/test/ppapi_unittest.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 
+using ::testing::_;
+
 namespace content {
 
+ACTION_P(RunClosure, closure) {
+  closure.Run();
+}
+
 static const std::string kTestStreamUrl = "stream_url";
 static const std::string kUnknownStreamUrl = "unknown_stream_url";
 
 class VideoDestinationHandlerTest : public PpapiUnittest {
  public:
-  VideoDestinationHandlerTest() : registry_() {
+  VideoDestinationHandlerTest()
+     : child_process_(new ChildProcess()),
+       registry_(MockMediaStreamRegistry()) {
     registry_.Init(kTestStreamUrl);
   }
 
+  base::MessageLoop* io_message_loop() const {
+    return child_process_->io_message_loop();
+  }
+
  protected:
+  scoped_ptr<ChildProcess> child_process_;
   MockMediaStreamRegistry registry_;
 };
 
@@ -39,7 +56,7 @@
                                              kUnknownStreamUrl, &frame_writer));
   EXPECT_TRUE(VideoDestinationHandler::Open(&registry_,
                                             kTestStreamUrl, &frame_writer));
-  // The |frame_writer| is a proxy and is owned by who call Open.
+  // The |frame_writer| is a proxy and is owned by whoever call Open.
   delete frame_writer;
 }
 
@@ -67,14 +84,21 @@
       new PPB_ImageData_Impl(instance()->pp_instance(),
                              PPB_ImageData_Impl::ForTest()));
   image->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, 640, 360, true);
-  frame_writer->PutFrame(image, 10);
-  EXPECT_EQ(1, sink.number_of_frames());
+  {
+    base::RunLoop run_loop;
+    base::Closure quit_closure = run_loop.QuitClosure();
+
+    EXPECT_CALL(sink, OnVideoFrame()).WillOnce(
+        RunClosure(quit_closure));
+    frame_writer->PutFrame(image, 10);
+    run_loop.Run();
+  }
   // TODO(perkj): Verify that the track output I420 when
   // https://codereview.chromium.org/213423006/ is landed.
-
+  EXPECT_EQ(1, sink.number_of_frames());
   native_track->RemoveSink(&sink);
 
-  // The |frame_writer| is a proxy and is owned by who call Open.
+  // The |frame_writer| is a proxy and is owned by whoever call Open.
   delete frame_writer;
 }
 
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc b/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc
index 8cbceff..5a5b9bf 100644
--- a/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc
+++ b/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/memory/scoped_ptr.h"
+#include "content/child/child_process.h"
 #include "content/renderer/media/media_stream.h"
 #include "content/renderer/media/media_stream_audio_source.h"
 #include "content/renderer/media/media_stream_video_source.h"
@@ -22,6 +23,7 @@
 class WebRtcMediaStreamAdapterTest : public ::testing::Test {
  public:
   virtual void SetUp() {
+    child_process_.reset(new ChildProcess());
     dependency_factory_.reset(new MockMediaStreamDependencyFactory());
   }
 
@@ -89,6 +91,7 @@
   }
 
  protected:
+  scoped_ptr<ChildProcess> child_process_;
   scoped_ptr<MockMediaStreamDependencyFactory> dependency_factory_;
   scoped_ptr<WebRtcMediaStreamAdapter> adapter_;
 };
diff --git a/content/renderer/media/webrtc/webrtc_video_track_adapter.cc b/content/renderer/media/webrtc/webrtc_video_track_adapter.cc
index 023aba1..0fdef64 100644
--- a/content/renderer/media/webrtc/webrtc_video_track_adapter.cc
+++ b/content/renderer/media/webrtc/webrtc_video_track_adapter.cc
@@ -22,27 +22,77 @@
 
 namespace content {
 
+// Simple help class used for receiving video frames on the IO-thread from
+// a MediaStreamVideoTrack and forward the frames to a
+// WebRtcVideoCapturerAdapter that implements a video capturer for libjingle.
+class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter
+    : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> {
+ public:
+  WebRtcVideoSourceAdapter(
+      const scoped_refptr<webrtc::VideoSourceInterface>& source,
+      WebRtcVideoCapturerAdapter* capture_adapter);
+
+  void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame,
+                        const media::VideoCaptureFormat& format);
+
+ private:
+  friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>;
+  virtual ~WebRtcVideoSourceAdapter();
+
+  // Used to DCHECK that frames are called on the IO-thread.
+  base::ThreadChecker io_thread_checker_;
+  scoped_refptr<webrtc::VideoSourceInterface> video_source_;
+  // |capture_adapter_| is owned by |video_source_|
+  WebRtcVideoCapturerAdapter* capture_adapter_;
+};
+
+WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter(
+    const scoped_refptr<webrtc::VideoSourceInterface>& source,
+    WebRtcVideoCapturerAdapter* capture_adapter)
+    : video_source_(source),
+      capture_adapter_(capture_adapter) {
+  io_thread_checker_.DetachFromThread();
+}
+
+WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() {
+}
+
+void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO(
+    const scoped_refptr<media::VideoFrame>& frame,
+    const media::VideoCaptureFormat& format) {
+  DCHECK(io_thread_checker_.CalledOnValidThread());
+  capture_adapter_->OnFrameCaptured(frame);
+}
+
 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter(
     const blink::WebMediaStreamTrack& track,
     MediaStreamDependencyFactory* factory)
     : web_track_(track) {
-  MediaStreamVideoSink::AddToVideoTrack(this, web_track_);
-
   const blink::WebMediaConstraints& constraints =
       MediaStreamVideoTrack::GetVideoTrack(track)->constraints();
 
   bool is_screencast = ConstraintKeyExists(
       constraints, base::UTF8ToUTF16(kMediaStreamSource));
-  capture_adapter_ = factory->CreateVideoCapturer(is_screencast);
+  WebRtcVideoCapturerAdapter* capture_adapter =
+      factory->CreateVideoCapturer(is_screencast);
 
   // |video_source| owns |capture_adapter|
-  video_source_ = factory->CreateVideoSource(capture_adapter_,
-                                             track.source().constraints());
+  scoped_refptr<webrtc::VideoSourceInterface> video_source(
+      factory->CreateVideoSource(capture_adapter,
+                                 track.source().constraints()));
 
   video_track_ = factory->CreateLocalVideoTrack(web_track_.id().utf8(),
-                                                video_source_);
+                                                video_source.get());
+
   video_track_->set_enabled(web_track_.isEnabled());
 
+  source_adapter_ = new WebRtcVideoSourceAdapter(video_source,
+                                                 capture_adapter);
+
+  MediaStreamVideoTrack::GetVideoTrack(track)->AddSink(
+      this, base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO,
+                       source_adapter_));
+
   DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast "
            << is_screencast;
 }
@@ -50,7 +100,7 @@
 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() {
   DCHECK(thread_checker_.CalledOnValidThread());
   DVLOG(3) << "WebRtcVideoTrackAdapter dtor().";
-  MediaStreamVideoSink::RemoveFromVideoTrack(this, web_track_);
+  MediaStreamVideoTrack::GetVideoTrack(web_track_)->RemoveSink(this);
 }
 
 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled) {
@@ -58,11 +108,5 @@
   video_track_->set_enabled(enabled);
 }
 
-void WebRtcVideoTrackAdapter::OnVideoFrame(
-    const scoped_refptr<media::VideoFrame>& frame) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  capture_adapter_->OnFrameCaptured(frame);
-}
-
 }  // namespace content
 
diff --git a/content/renderer/media/webrtc/webrtc_video_track_adapter.h b/content/renderer/media/webrtc/webrtc_video_track_adapter.h
index b2cff0a..6b649ba 100644
--- a/content/renderer/media/webrtc/webrtc_video_track_adapter.h
+++ b/content/renderer/media/webrtc/webrtc_video_track_adapter.h
@@ -7,7 +7,7 @@
 
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
-#include "content/public/renderer/media_stream_video_sink.h"
+#include "content/public/renderer/media_stream_sink.h"
 #include "content/renderer/media/media_stream_dependency_factory.h"
 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
@@ -16,6 +16,8 @@
 
 namespace content {
 
+class MediaStreamVideoTrack;
+
 // WebRtcVideoTrackAdapter is an adapter between a
 // content::MediaStreamVideoTrack object and a webrtc VideoTrack that is
 // currently sent on a PeerConnection.
@@ -25,7 +27,7 @@
 // added to an RTCPeerConnection object.
 // Instances of this class is owned by the WebRtcMediaStreamAdapter object that
 // created it.
-class WebRtcVideoTrackAdapter : public MediaStreamVideoSink {
+class WebRtcVideoTrackAdapter : public MediaStreamSink {
  public:
   WebRtcVideoTrackAdapter(const blink::WebMediaStreamTrack& track,
                           MediaStreamDependencyFactory* factory);
@@ -36,24 +38,20 @@
   }
 
  protected:
-  // Implements MediaStreamVideoSink
-  virtual void OnVideoFrame(
-      const scoped_refptr<media::VideoFrame>& frame) OVERRIDE;
+  // Implementation of MediaStreamSink.
   virtual void OnEnabledChanged(bool enabled) OVERRIDE;
 
  private:
   // Used to DCHECK that we are called on the correct thread.
   base::ThreadChecker thread_checker_;
 
-  scoped_refptr<webrtc::VideoSourceInterface> video_source_;
   scoped_refptr<webrtc::VideoTrackInterface> video_track_;
-
   blink::WebMediaStreamTrack web_track_;
 
-  // |capture_adapter_| is owned by |video_source_|
-  WebRtcVideoCapturerAdapter* capture_adapter_;
+  class WebRtcVideoSourceAdapter;
+  scoped_refptr<WebRtcVideoSourceAdapter> source_adapter_;
 
-  DISALLOW_COPY_AND_ASSIGN (WebRtcVideoTrackAdapter);
+  DISALLOW_COPY_AND_ASSIGN(WebRtcVideoTrackAdapter);
 };
 
 }  // namespace content
diff --git a/content/renderer/media/webrtc_audio_device_impl.cc b/content/renderer/media/webrtc_audio_device_impl.cc
index 97d5d09..517b3e7 100644
--- a/content/renderer/media/webrtc_audio_device_impl.cc
+++ b/content/renderer/media/webrtc_audio_device_impl.cc
@@ -8,6 +8,7 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/string_util.h"
 #include "base/win/windows_version.h"
+#include "content/renderer/media/media_stream_audio_processor.h"
 #include "content/renderer/media/webrtc_audio_capturer.h"
 #include "content/renderer/media/webrtc_audio_renderer.h"
 #include "content/renderer/render_thread_impl.h"
@@ -27,7 +28,9 @@
       initialized_(false),
       playing_(false),
       recording_(false),
-      microphone_volume_(0) {
+      microphone_volume_(0),
+      is_audio_track_processing_enabled_(
+          MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled()) {
   DVLOG(1) << "WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()";
 }
 
@@ -73,13 +76,13 @@
     DVLOG(2) << "total delay: " << input_delay_ms_ + output_delay_ms_;
   }
 
-  // Write audio samples in blocks of 10 milliseconds to the registered
+  // Write audio frames in blocks of 10 milliseconds to the registered
   // webrtc::AudioTransport sink. Keep writing until our internal byte
   // buffer is empty.
   const int16* audio_buffer = audio_data;
-  const int samples_per_10_msec = (sample_rate / 100);
-  CHECK_EQ(number_of_frames % samples_per_10_msec, 0);
-  int accumulated_audio_samples = 0;
+  const int frames_per_10_ms = (sample_rate / 100);
+  CHECK_EQ(number_of_frames % frames_per_10_ms, 0);
+  int accumulated_audio_frames = 0;
   uint32_t new_volume = 0;
 
   // The lock here is to protect a race in the resampler inside webrtc when
@@ -91,7 +94,7 @@
   // webrtc::AudioProcessing module to Chrome. See http://crbug/264611 for
   // details.
   base::AutoLock auto_lock(capture_callback_lock_);
-  while (accumulated_audio_samples < number_of_frames) {
+  while (accumulated_audio_frames < number_of_frames) {
     // Deliver 10ms of recorded 16-bit linear PCM audio.
     int new_mic_level = audio_transport_callback_->OnDataAvailable(
         &channels[0],
@@ -99,14 +102,14 @@
         audio_buffer,
         sample_rate,
         number_of_channels,
-        samples_per_10_msec,
+        frames_per_10_ms,
         total_delay_ms,
         current_volume,
         key_pressed,
         need_audio_processing);
 
-    accumulated_audio_samples += samples_per_10_msec;
-    audio_buffer += samples_per_10_msec * number_of_channels;
+    accumulated_audio_frames += frames_per_10_ms;
+    audio_buffer += frames_per_10_ms * number_of_channels;
 
     // The latest non-zero new microphone level will be returned.
     if (new_mic_level)
@@ -133,28 +136,45 @@
     output_delay_ms_ = audio_delay_milliseconds;
   }
 
-  int samples_per_10_msec = (sample_rate / 100);
+  int frames_per_10_ms = (sample_rate / 100);
   int bytes_per_sample = sizeof(render_buffer_[0]);
-  const int bytes_per_10_msec =
-      audio_bus->channels() * samples_per_10_msec * bytes_per_sample;
-  DCHECK_EQ(audio_bus->frames() % samples_per_10_msec, 0);
+  const int bytes_per_10_ms =
+      audio_bus->channels() * frames_per_10_ms * bytes_per_sample;
+  DCHECK_EQ(audio_bus->frames() % frames_per_10_ms, 0);
 
-  // Get audio samples in blocks of 10 milliseconds from the registered
+  // Get audio frames in blocks of 10 milliseconds from the registered
   // webrtc::AudioTransport source. Keep reading until our internal buffer
   // is full.
-  uint32_t num_audio_samples = 0;
-  int accumulated_audio_samples = 0;
+  uint32_t num_audio_frames = 0;
+  int accumulated_audio_frames = 0;
   int16* audio_data = &render_buffer_[0];
-  while (accumulated_audio_samples < audio_bus->frames()) {
+  while (accumulated_audio_frames < audio_bus->frames()) {
     // Get 10ms and append output to temporary byte buffer.
-    audio_transport_callback_->NeedMorePlayData(samples_per_10_msec,
-                                                bytes_per_sample,
-                                                audio_bus->channels(),
+    if (is_audio_track_processing_enabled_) {
+      // When audio processing is enabled in the audio track, we use
+      // PullRenderData() instead of NeedMorePlayData() to avoid passing the
+      // render data to the APM in WebRTC as reference signal for echo
+      // cancellation.
+      static const int kBitsPerByte = 8;
+      audio_transport_callback_->PullRenderData(bytes_per_sample * kBitsPerByte,
                                                 sample_rate,
-                                                audio_data,
-                                                num_audio_samples);
-    accumulated_audio_samples += num_audio_samples;
-    audio_data += bytes_per_10_msec;
+                                                audio_bus->channels(),
+                                                frames_per_10_ms,
+                                                audio_data);
+      accumulated_audio_frames += frames_per_10_ms;
+    } else {
+      // TODO(xians): Remove the following code after the APM in WebRTC is
+      // deprecated.
+      audio_transport_callback_->NeedMorePlayData(frames_per_10_ms,
+                                                  bytes_per_sample,
+                                                  audio_bus->channels(),
+                                                  sample_rate,
+                                                  audio_data,
+                                                  num_audio_frames);
+      accumulated_audio_frames += num_audio_frames;
+    }
+
+    audio_data += bytes_per_10_ms;
   }
 
   // De-interleave each channel and convert to 32-bit floating-point
@@ -395,20 +415,20 @@
 }
 
 int32_t WebRtcAudioDeviceImpl::RecordingSampleRate(
-    uint32_t* samples_per_sec) const {
+    uint32_t* sample_rate) const {
   // We use the default capturer as the recording sample rate.
   scoped_refptr<WebRtcAudioCapturer> capturer(GetDefaultCapturer());
   if (!capturer.get())
     return -1;
 
-  *samples_per_sec = static_cast<uint32_t>(
+  *sample_rate = static_cast<uint32_t>(
       capturer->source_audio_parameters().sample_rate());
   return 0;
 }
 
 int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate(
-    uint32_t* samples_per_sec) const {
-  *samples_per_sec = renderer_ ? renderer_->sample_rate() : 0;
+    uint32_t* sample_rate) const {
+  *sample_rate = renderer_ ? renderer_->sample_rate() : 0;
   return 0;
 }
 
diff --git a/content/renderer/media/webrtc_audio_device_impl.h b/content/renderer/media/webrtc_audio_device_impl.h
index 4cf36d4..b8e6741 100644
--- a/content/renderer/media/webrtc_audio_device_impl.h
+++ b/content/renderer/media/webrtc_audio_device_impl.h
@@ -321,8 +321,8 @@
   virtual int32_t StereoRecordingIsAvailable(bool* available) const OVERRIDE;
   virtual int32_t PlayoutDelay(uint16_t* delay_ms) const OVERRIDE;
   virtual int32_t RecordingDelay(uint16_t* delay_ms) const OVERRIDE;
-  virtual int32_t RecordingSampleRate(uint32_t* samples_per_sec) const OVERRIDE;
-  virtual int32_t PlayoutSampleRate(uint32_t* samples_per_sec) const OVERRIDE;
+  virtual int32_t RecordingSampleRate(uint32_t* sample_rate) const OVERRIDE;
+  virtual int32_t PlayoutSampleRate(uint32_t* sample_rate) const OVERRIDE;
 
   // Sets the |renderer_|, returns false if |renderer_| already exists.
   // Called on the main renderer thread.
@@ -387,7 +387,7 @@
 
   // WebRtcAudioRendererSource implementation.
 
-  // Called on the AudioInputDevice worker thread.
+  // Called on the AudioOutputDevice worker thread.
   virtual void RenderData(media::AudioBus* audio_bus,
                           int sample_rate,
                           int audio_delay_milliseconds) OVERRIDE;
@@ -453,6 +453,9 @@
   // Used for start the Aec dump on the default capturer.
   base::File aec_dump_file_;
 
+  // Flag to tell if audio processing is enabled in MediaStreamAudioProcessor.
+  const bool is_audio_track_processing_enabled_;
+
   DISALLOW_COPY_AND_ASSIGN(WebRtcAudioDeviceImpl);
 };
 
diff --git a/content/renderer/media/websourcebuffer_impl.cc b/content/renderer/media/websourcebuffer_impl.cc
index ff3ac5b..93a996b 100644
--- a/content/renderer/media/websourcebuffer_impl.cc
+++ b/content/renderer/media/websourcebuffer_impl.cc
@@ -88,7 +88,13 @@
 }
 
 void WebSourceBufferImpl::abort() {
-  demuxer_->Abort(id_);
+  demuxer_->Abort(id_,
+                  append_window_start_, append_window_end_,
+                  &timestamp_offset_);
+
+  // TODO(wolenetz): abort should be able to modify the caller timestamp offset
+  // (just like WebSourceBufferImpl::append).
+  // See http://crbug.com/370229 for further details.
 }
 
 void WebSourceBufferImpl::remove(double start, double end) {
diff --git a/content/renderer/p2p/ipc_network_manager.cc b/content/renderer/p2p/ipc_network_manager.cc
index ee88831..a11e03c 100644
--- a/content/renderer/p2p/ipc_network_manager.cc
+++ b/content/renderer/p2p/ipc_network_manager.cc
@@ -12,6 +12,29 @@
 
 namespace content {
 
+namespace {
+
+talk_base::AdapterType ConvertConnectionTypeToAdapterType(
+    net::NetworkChangeNotifier::ConnectionType type) {
+  switch (type) {
+    case net::NetworkChangeNotifier::CONNECTION_UNKNOWN:
+        return talk_base::ADAPTER_TYPE_UNKNOWN;
+    case net::NetworkChangeNotifier::CONNECTION_ETHERNET:
+        return talk_base::ADAPTER_TYPE_ETHERNET;
+    case net::NetworkChangeNotifier::CONNECTION_WIFI:
+        return talk_base::ADAPTER_TYPE_WIFI;
+    case net::NetworkChangeNotifier::CONNECTION_2G:
+    case net::NetworkChangeNotifier::CONNECTION_3G:
+    case net::NetworkChangeNotifier::CONNECTION_4G:
+        return talk_base::ADAPTER_TYPE_CELLULAR;
+    default:
+        return talk_base::ADAPTER_TYPE_UNKNOWN;
+  }
+  return talk_base::ADAPTER_TYPE_UNKNOWN;
+}
+
+}  // namespace
+
 IpcNetworkManager::IpcNetworkManager(P2PSocketDispatcher* socket_dispatcher)
     : socket_dispatcher_(socket_dispatcher),
       start_count_(0),
@@ -60,7 +83,8 @@
       memcpy(&address, &it->address[0], sizeof(uint32));
       address = talk_base::NetworkToHost32(address);
       talk_base::Network* network = new talk_base::Network(
-          it->name, it->name, talk_base::IPAddress(address), 32);
+          it->name, it->name, talk_base::IPAddress(address), 32,
+          ConvertConnectionTypeToAdapterType(it->type));
       network->AddIP(talk_base::IPAddress(address));
       networks.push_back(network);
     } else if (it->address.size() == net::kIPv6AddressSize) {
@@ -69,7 +93,8 @@
       talk_base::IPAddress ip6_addr(address);
       if (!talk_base::IPIsPrivate(ip6_addr)) {
         talk_base::Network* network = new talk_base::Network(
-            it->name, it->name, ip6_addr, 64);
+            it->name, it->name, ip6_addr, 64,
+            ConvertConnectionTypeToAdapterType(it->type));
         network->AddIP(ip6_addr);
         networks.push_back(network);
       }
@@ -81,14 +106,14 @@
     std::string name_v4("loopback_ipv4");
     talk_base::IPAddress ip_address_v4(INADDR_LOOPBACK);
     talk_base::Network* network_v4 = new talk_base::Network(
-        name_v4, name_v4, ip_address_v4, 32);
+        name_v4, name_v4, ip_address_v4, 32, talk_base::ADAPTER_TYPE_UNKNOWN);
     network_v4->AddIP(ip_address_v4);
     networks.push_back(network_v4);
 
     std::string name_v6("loopback_ipv6");
     talk_base::IPAddress ip_address_v6(in6addr_loopback);
     talk_base::Network* network_v6 = new talk_base::Network(
-        name_v6, name_v6, ip_address_v6, 64);
+        name_v6, name_v6, ip_address_v6, 64, talk_base::ADAPTER_TYPE_UNKNOWN);
     network_v6->AddIP(ip_address_v6);
     networks.push_back(network_v6);
   }
diff --git a/content/renderer/pepper/audio_helper.cc b/content/renderer/pepper/audio_helper.cc
index 6adfab4..2ce1ae4 100644
--- a/content/renderer/pepper/audio_helper.cc
+++ b/content/renderer/pepper/audio_helper.cc
@@ -53,7 +53,7 @@
                                 size_t shared_memory_size,
                                 base::SyncSocket::Handle socket_handle) {
   if (TrackedCallback::IsPending(create_callback_)) {
-    // Trusted side of proxy can specify a callback to recieve handles. In
+    // Trusted side of proxy can specify a callback to receive handles. In
     // this case we don't need to map any data or start the thread since it
     // will be handled by the proxy.
     shared_memory_for_create_callback_.reset(
diff --git a/content/renderer/pepper/content_decryptor_delegate.cc b/content/renderer/pepper/content_decryptor_delegate.cc
index a10b741..a36cf6f 100644
--- a/content/renderer/pepper/content_decryptor_delegate.cc
+++ b/content/renderer/pepper/content_decryptor_delegate.cc
@@ -1026,9 +1026,7 @@
         audio_samples_per_second_,
         frame_count,
         &channel_ptrs[0],
-        base::TimeDelta::FromMicroseconds(timestamp),
-        base::TimeDelta::FromMicroseconds(audio_samples_per_second_ /
-                                          frame_count));
+        base::TimeDelta::FromMicroseconds(timestamp));
     frames->push_back(frame);
 
     cur += frame_size;
diff --git a/content/renderer/pepper/content_renderer_pepper_host_factory.cc b/content/renderer/pepper/content_renderer_pepper_host_factory.cc
index 87ade57..3a9c6fe 100644
--- a/content/renderer/pepper/content_renderer_pepper_host_factory.cc
+++ b/content/renderer/pepper/content_renderer_pepper_host_factory.cc
@@ -13,6 +13,7 @@
 #include "content/renderer/pepper/pepper_file_ref_renderer_host.h"
 #include "content/renderer/pepper/pepper_file_system_host.h"
 #include "content/renderer/pepper/pepper_graphics_2d_host.h"
+#include "content/renderer/pepper/pepper_media_stream_video_track_host.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
 #include "content/renderer/pepper/pepper_truetype_font_host.h"
 #include "content/renderer/pepper/pepper_url_loader_host.h"
@@ -126,6 +127,9 @@
       return scoped_ptr<ResourceHost>(
           new PepperWebSocketHost(host_, instance, params.pp_resource()));
 #if defined(ENABLE_WEBRTC)
+    case PpapiHostMsg_MediaStreamVideoTrack_Create::ID:
+      return scoped_ptr<ResourceHost>(new PepperMediaStreamVideoTrackHost(
+          host_, instance, params.pp_resource()));
     // These private MediaStream interfaces are exposed as if they were public
     // so they can be used by NaCl plugins. However, they are available only
     // for whitelisted apps.
@@ -157,7 +161,7 @@
         }
         // Check that the family name is valid UTF-8 before passing it to the
         // host OS.
-        if (IsStringUTF8(desc.family)) {
+        if (base::IsStringUTF8(desc.family)) {
           return scoped_ptr<ResourceHost>(new PepperTrueTypeFontHost(
               host_, instance, params.pp_resource(), desc));
         }
diff --git a/content/renderer/pepper/pepper_media_stream_audio_track_host.cc b/content/renderer/pepper/pepper_media_stream_audio_track_host.cc
index f7ca253..f45f601 100644
--- a/content/renderer/pepper/pepper_media_stream_audio_track_host.cc
+++ b/content/renderer/pepper/pepper_media_stream_audio_track_host.cc
@@ -75,7 +75,7 @@
     int32_t number_of_buffers,
     int32_t buffer_size) {
   DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current());
-  bool result = host_->InitBuffers(number_of_buffers, buffer_size);
+  bool result = host_->InitBuffers(number_of_buffers, buffer_size, kRead);
   // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin.
   CHECK(result);
   base::AutoLock lock(lock_);
diff --git a/content/renderer/pepper/pepper_media_stream_track_host_base.cc b/content/renderer/pepper/pepper_media_stream_track_host_base.cc
index f21790a..4a22c49 100644
--- a/content/renderer/pepper/pepper_media_stream_track_host_base.cc
+++ b/content/renderer/pepper/pepper_media_stream_track_host_base.cc
@@ -30,7 +30,8 @@
 PepperMediaStreamTrackHostBase::~PepperMediaStreamTrackHostBase() {}
 
 bool PepperMediaStreamTrackHostBase::InitBuffers(int32_t number_of_buffers,
-                                                 int32_t buffer_size) {
+                                                 int32_t buffer_size,
+                                                 TrackType track_type) {
   DCHECK_GT(number_of_buffers, 0);
   DCHECK_GT(buffer_size,
             static_cast<int32_t>(sizeof(ppapi::MediaStreamBuffer::Header)));
@@ -62,10 +63,12 @@
 #endif
   SerializedHandle handle(host_->ShareHandleWithRemote(platform_file, false),
                           size);
+  bool readonly = (track_type == kRead);
   host()->SendUnsolicitedReplyWithHandles(
       pp_resource(),
       PpapiPluginMsg_MediaStreamTrack_InitBuffers(number_of_buffers,
-                                                  buffer_size),
+                                                  buffer_size,
+                                                  readonly),
       std::vector<SerializedHandle>(1, handle));
   return true;
 }
@@ -78,6 +81,13 @@
       pp_resource(), PpapiPluginMsg_MediaStreamTrack_EnqueueBuffer(index));
 }
 
+void PepperMediaStreamTrackHostBase::SendEnqueueBuffersMessageToPlugin(
+    const std::vector<int32_t>& indices) {
+  DCHECK_GE(indices.size(), 0U);
+  host()->SendUnsolicitedReply(pp_resource(),
+      PpapiPluginMsg_MediaStreamTrack_EnqueueBuffers(indices));
+}
+
 int32_t PepperMediaStreamTrackHostBase::OnResourceMessageReceived(
     const IPC::Message& msg,
     HostMessageContext* context) {
diff --git a/content/renderer/pepper/pepper_media_stream_track_host_base.h b/content/renderer/pepper/pepper_media_stream_track_host_base.h
index 76eb41a..37ebd61 100644
--- a/content/renderer/pepper/pepper_media_stream_track_host_base.h
+++ b/content/renderer/pepper/pepper_media_stream_track_host_base.h
@@ -23,7 +23,13 @@
                                  PP_Resource resource);
   virtual ~PepperMediaStreamTrackHostBase();
 
-  bool InitBuffers(int32_t number_of_buffers, int32_t buffer_size);
+  enum TrackType {
+    kRead,
+    kWrite
+  };
+  bool InitBuffers(int32_t number_of_buffers,
+                   int32_t buffer_size,
+                   TrackType track_type);
 
   ppapi::MediaStreamBufferManager* buffer_manager() { return &buffer_manager_; }
 
@@ -33,18 +39,26 @@
   // Also see |MediaStreamBufferManager|.
   void SendEnqueueBufferMessageToPlugin(int32_t index);
 
+  // Sends a set of buffer indices to the corresponding
+  // MediaStreamTrackResourceBase via an IPC message.
+  // The resource adds the buffer indices into its
+  // |frame_buffer_| for reading or writing. Also see |MediaStreamFrameBuffer|.
+  void SendEnqueueBuffersMessageToPlugin(const std::vector<int32_t>& indices);
+
   // ResourceMessageHandler overrides:
   virtual int32_t OnResourceMessageReceived(
       const IPC::Message& msg,
       ppapi::host::HostMessageContext* context) OVERRIDE;
 
+  // Message handlers:
+  virtual int32_t OnHostMsgEnqueueBuffer(
+      ppapi::host::HostMessageContext* context, int32_t index);
+
  private:
   // Subclasses must implement this method to clean up when the track is closed.
   virtual void OnClose() = 0;
 
   // Message handlers:
-  int32_t OnHostMsgEnqueueBuffer(ppapi::host::HostMessageContext* context,
-                                 int32_t index);
   int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context);
 
   RendererPpapiHost* host_;
diff --git a/content/renderer/pepper/pepper_media_stream_video_track_host.cc b/content/renderer/pepper/pepper_media_stream_video_track_host.cc
index 1238566..7d98e71 100644
--- a/content/renderer/pepper/pepper_media_stream_video_track_host.cc
+++ b/content/renderer/pepper/pepper_media_stream_video_track_host.cc
@@ -4,14 +4,24 @@
 
 #include "content/renderer/pepper/pepper_media_stream_video_track_host.h"
 
+#include "base/base64.h"
 #include "base/logging.h"
+#include "base/rand_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/renderer/media/media_stream_video_track.h"
 #include "media/base/yuv_convert.h"
 #include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_media_stream_video_track.h"
 #include "ppapi/c/ppb_video_frame.h"
 #include "ppapi/host/dispatch_host_message.h"
 #include "ppapi/host/host_message_context.h"
 #include "ppapi/proxy/ppapi_messages.h"
 #include "ppapi/shared_impl/media_stream_buffer.h"
+
+// IS_ALIGNED is also defined in
+// third_party/libjingle/overrides/talk/base/basictypes.h
+// TODO(ronghuawu): Avoid undef.
+#undef IS_ALIGNED
 #include "third_party/libyuv/include/libyuv.h"
 
 using media::VideoFrame;
@@ -25,6 +35,23 @@
 // Filter mode for scaling frames.
 const libyuv::FilterMode kFilterMode = libyuv::kFilterBox;
 
+const char kPepperVideoSourceName[] = "PepperVideoSourceName";
+
+// Default config for output mode.
+const int kDefaultOutputFrameRate = 30;
+
+media::VideoPixelFormat ToPixelFormat(PP_VideoFrame_Format format) {
+  switch (format) {
+    case PP_VIDEOFRAME_FORMAT_YV12:
+      return media::PIXEL_FORMAT_YV12;
+    case PP_VIDEOFRAME_FORMAT_I420:
+      return media::PIXEL_FORMAT_I420;
+    default:
+      DVLOG(1) << "Unsupported pixel format " << format;
+      return media::PIXEL_FORMAT_UNKNOWN;
+  }
+}
+
 PP_VideoFrame_Format ToPpapiFormat(VideoFrame::Format format) {
   switch (format) {
     case VideoFrame::YV12:
@@ -149,6 +176,57 @@
 
 namespace content {
 
+// Internal class used for delivering video frames on the IO-thread to
+// the MediaStreamVideoSource implementation.
+class PepperMediaStreamVideoTrackHost::FrameDeliverer
+    : public base::RefCountedThreadSafe<FrameDeliverer> {
+ public:
+  FrameDeliverer(
+      const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
+      const VideoCaptureDeliverFrameCB& new_frame_callback);
+
+  void DeliverVideoFrame(const scoped_refptr<media::VideoFrame>& frame,
+                         const media::VideoCaptureFormat& format);
+
+ private:
+  friend class base::RefCountedThreadSafe<FrameDeliverer>;
+  virtual ~FrameDeliverer();
+
+  void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame,
+                        const media::VideoCaptureFormat& format);
+
+  scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+  VideoCaptureDeliverFrameCB new_frame_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(FrameDeliverer);
+};
+
+PepperMediaStreamVideoTrackHost::FrameDeliverer::FrameDeliverer(
+    const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
+    const VideoCaptureDeliverFrameCB& new_frame_callback)
+    : io_message_loop_(io_message_loop_proxy),
+      new_frame_callback_(new_frame_callback) {
+}
+
+PepperMediaStreamVideoTrackHost::FrameDeliverer::~FrameDeliverer() {
+}
+
+void PepperMediaStreamVideoTrackHost::FrameDeliverer::DeliverVideoFrame(
+    const scoped_refptr<media::VideoFrame>& frame,
+    const media::VideoCaptureFormat& format) {
+  io_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&FrameDeliverer::DeliverFrameOnIO,
+                 this, frame, format));
+}
+
+void PepperMediaStreamVideoTrackHost::FrameDeliverer::DeliverFrameOnIO(
+     const scoped_refptr<media::VideoFrame>& frame,
+     const media::VideoCaptureFormat& format) {
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  new_frame_callback_.Run(frame, format);
+}
+
 PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost(
     RendererPpapiHost* host,
     PP_Instance instance,
@@ -160,10 +238,32 @@
       number_of_buffers_(kDefaultNumberOfBuffers),
       source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN),
       plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN),
-      frame_data_size_(0) {
+      frame_data_size_(0),
+      type_(kRead),
+      output_started_(false) {
   DCHECK(!track_.isNull());
 }
 
+PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost(
+    RendererPpapiHost* host,
+    PP_Instance instance,
+    PP_Resource resource)
+    : PepperMediaStreamTrackHostBase(host, instance, resource),
+      connected_(false),
+      number_of_buffers_(kDefaultNumberOfBuffers),
+      source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN),
+      plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN),
+      frame_data_size_(0),
+      type_(kWrite),
+      output_started_(false) {
+  InitBlinkTrack();
+  DCHECK(!track_.isNull());
+}
+
+bool PepperMediaStreamVideoTrackHost::IsMediaStreamVideoTrackHost() {
+  return true;
+}
+
 PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() {
   OnClose();
 }
@@ -187,8 +287,26 @@
   int32_t buffer_size =
       sizeof(ppapi::MediaStreamBuffer::Video) + frame_data_size_;
   bool result = PepperMediaStreamTrackHostBase::InitBuffers(number_of_buffers_,
-                                                            buffer_size);
+                                                            buffer_size,
+                                                            type_);
   CHECK(result);
+
+  if (type_ == kWrite) {
+    for (int32_t i = 0; i < buffer_manager()->number_of_buffers(); ++i) {
+      ppapi::MediaStreamBuffer::Video* buffer =
+          &(buffer_manager()->GetBufferPointer(i)->video);
+      buffer->header.size = buffer_manager()->buffer_size();
+      buffer->header.type = ppapi::MediaStreamBuffer::TYPE_VIDEO;
+      buffer->format = format;
+      buffer->size.width = size.width();
+      buffer->size.height = size.height();
+      buffer->data_size = frame_data_size_;
+    }
+
+    // Make all the frames avaiable to the plugin.
+    std::vector<int32_t> indices = buffer_manager()->DequeueBuffers();
+    SendEnqueueBuffersMessageToPlugin(indices);
+  }
 }
 
 void PepperMediaStreamVideoTrackHost::OnClose() {
@@ -198,6 +316,65 @@
   }
 }
 
+int32_t PepperMediaStreamVideoTrackHost::OnHostMsgEnqueueBuffer(
+    ppapi::host::HostMessageContext* context, int32_t index) {
+  if (type_ == kRead) {
+    return PepperMediaStreamTrackHostBase::OnHostMsgEnqueueBuffer(context,
+                                                                  index);
+  } else {
+    return SendFrameToTrack(index);
+  }
+}
+
+int32_t PepperMediaStreamVideoTrackHost::SendFrameToTrack(int32_t index) {
+  DCHECK_EQ(type_, kWrite);
+
+  if (output_started_) {
+    // Sends the frame to blink video track.
+    ppapi::MediaStreamBuffer::Video* pp_frame =
+        &(buffer_manager()->GetBufferPointer(index)->video);
+
+    int32 y_stride = plugin_frame_size_.width();
+    int32 uv_stride = (plugin_frame_size_.width() + 1) / 2;
+    uint8* y_data = static_cast<uint8*>(pp_frame->data);
+    // Default to I420
+    uint8* u_data = y_data + plugin_frame_size_.GetArea();
+    uint8* v_data = y_data + (plugin_frame_size_.GetArea() * 5 / 4);
+    if (plugin_frame_format_ == PP_VIDEOFRAME_FORMAT_YV12) {
+      // Swap u and v for YV12.
+      uint8* tmp = u_data;
+      u_data = v_data;
+      v_data = tmp;
+    }
+
+    int64 ts_ms = static_cast<int64>(pp_frame->timestamp *
+                                     base::Time::kMillisecondsPerSecond);
+    scoped_refptr<VideoFrame> frame = media::VideoFrame::WrapExternalYuvData(
+        FromPpapiFormat(plugin_frame_format_),
+        plugin_frame_size_,
+        gfx::Rect(plugin_frame_size_),
+        plugin_frame_size_,
+        y_stride,
+        uv_stride,
+        uv_stride,
+        y_data,
+        u_data,
+        v_data,
+        base::TimeDelta::FromMilliseconds(ts_ms),
+        base::Closure());
+
+    frame_deliverer_->DeliverVideoFrame(
+        frame,
+        media::VideoCaptureFormat(plugin_frame_size_,
+                                  kDefaultOutputFrameRate,
+                                  ToPixelFormat(plugin_frame_format_)));
+  }
+
+  // Makes the frame available again for plugin.
+  SendEnqueueBufferMessageToPlugin(index);
+  return PP_OK;
+}
+
 void PepperMediaStreamVideoTrackHost::OnVideoFrame(
     const scoped_refptr<VideoFrame>& frame) {
   DCHECK(frame);
@@ -235,9 +412,39 @@
   buffer->size.height = size.height();
   buffer->data_size = frame_data_size_;
   ConvertFromMediaVideoFrame(frame, format, size, buffer->data);
+
   SendEnqueueBufferMessageToPlugin(index);
 }
 
+void PepperMediaStreamVideoTrackHost::GetCurrentSupportedFormats(
+    int max_requested_width, int max_requested_height,
+    const VideoCaptureDeviceFormatsCB& callback) {
+  if (type_ != kWrite) {
+    DVLOG(1) << "GetCurrentSupportedFormats is only supported in output mode.";
+    callback.Run(media::VideoCaptureFormats());
+    return;
+  }
+
+  media::VideoCaptureFormats formats;
+  formats.push_back(
+      media::VideoCaptureFormat(plugin_frame_size_,
+                                kDefaultOutputFrameRate,
+                                ToPixelFormat(plugin_frame_format_)));
+  callback.Run(formats);
+}
+
+void PepperMediaStreamVideoTrackHost::StartSourceImpl(
+    const media::VideoCaptureParams& params,
+    const VideoCaptureDeliverFrameCB& frame_callback) {
+  output_started_ = true;
+  frame_deliverer_ = new FrameDeliverer(io_message_loop(), frame_callback);
+}
+
+void PepperMediaStreamVideoTrackHost::StopSourceImpl() {
+  output_started_ = false;
+  frame_deliverer_ = NULL;
+}
+
 void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() {
   if (!connected_) {
     MediaStreamVideoSink::AddToVideoTrack(this, track_);
@@ -286,11 +493,39 @@
   // new settings. Otherwise, we will initialize buffer when we receive
   // the first frame, because plugin can only provide part of attributes
   // which are not enough to initialize buffers.
-  if (changed && !source_frame_size_.IsEmpty())
+  if (changed && (type_ == kWrite || !source_frame_size_.IsEmpty()))
     InitBuffers();
 
-  context->reply_msg = PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply();
+  // TODO(ronghuawu): Ask the owner of DOMMediaStreamTrackToResource why
+  // source id instead of track id is used there.
+  const std::string id = track_.source().id().utf8();
+  context->reply_msg = PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply(id);
   return PP_OK;
 }
 
+void PepperMediaStreamVideoTrackHost::InitBlinkTrack() {
+  std::string source_id;
+  base::Base64Encode(base::RandBytesAsString(64), &source_id);
+  blink::WebMediaStreamSource webkit_source;
+  webkit_source.initialize(base::UTF8ToUTF16(source_id),
+                           blink::WebMediaStreamSource::TypeVideo,
+                           base::UTF8ToUTF16(kPepperVideoSourceName));
+  webkit_source.setExtraData(this);
+
+  const bool enabled = true;
+  blink::WebMediaConstraints constraints;
+  constraints.initialize();
+  track_ = MediaStreamVideoTrack::CreateVideoTrack(
+       this, constraints,
+       base::Bind(
+           &PepperMediaStreamVideoTrackHost::OnTrackStarted,
+           base::Unretained(this)),
+       enabled);
+}
+
+void PepperMediaStreamVideoTrackHost::OnTrackStarted(
+    MediaStreamSource* source, bool success) {
+  DVLOG(3) << "OnTrackStarted result: " << success;
+}
+
 }  // namespace content
diff --git a/content/renderer/pepper/pepper_media_stream_video_track_host.h b/content/renderer/pepper/pepper_media_stream_video_track_host.h
index 521b7ab..3658706 100644
--- a/content/renderer/pepper/pepper_media_stream_video_track_host.h
+++ b/content/renderer/pepper/pepper_media_stream_video_track_host.h
@@ -7,6 +7,7 @@
 
 #include "base/compiler_specific.h"
 #include "content/public/renderer/media_stream_video_sink.h"
+#include "content/renderer/media/media_stream_video_source.h"
 #include "content/renderer/pepper/pepper_media_stream_track_host_base.h"
 #include "media/base/video_frame.h"
 #include "ppapi/c/ppb_video_frame.h"
@@ -17,25 +18,58 @@
 namespace content {
 
 class PepperMediaStreamVideoTrackHost : public PepperMediaStreamTrackHostBase,
-                                        public MediaStreamVideoSink {
+                                        public MediaStreamVideoSink,
+                                        public MediaStreamVideoSource {
  public:
+  // Input mode constructor.
+  // In input mode, this class passes video frames from |track| to the
+  // associated pepper plugin.
   PepperMediaStreamVideoTrackHost(RendererPpapiHost* host,
                                   PP_Instance instance,
                                   PP_Resource resource,
                                   const blink::WebMediaStreamTrack& track);
 
+  // Output mode constructor.
+  // In output mode, this class passes video frames from the associated
+  // pepper plugin to a newly created blink::WebMediaStreamTrack.
+  PepperMediaStreamVideoTrackHost(RendererPpapiHost* host,
+                                  PP_Instance instance,
+                                  PP_Resource resource);
+
+  virtual bool IsMediaStreamVideoTrackHost() OVERRIDE;
+
+  blink::WebMediaStreamTrack track() { return track_; }
+
  private:
+
   virtual ~PepperMediaStreamVideoTrackHost();
 
   void InitBuffers();
 
   // PepperMediaStreamTrackHostBase overrides:
   virtual void OnClose() OVERRIDE;
+  virtual int32_t OnHostMsgEnqueueBuffer(
+      ppapi::host::HostMessageContext* context, int32_t index) OVERRIDE;
+
+  // Sends frame with |index| to |track_|.
+  int32_t SendFrameToTrack(int32_t index);
 
   // MediaStreamVideoSink overrides:
   virtual void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame)
       OVERRIDE;
 
+  // MediaStreamVideoSource overrides:
+  virtual void GetCurrentSupportedFormats(
+      int max_requested_width,
+      int max_requested_height,
+      const VideoCaptureDeviceFormatsCB& callback) OVERRIDE;
+
+  virtual void StartSourceImpl(
+      const media::VideoCaptureParams& params,
+      const VideoCaptureDeliverFrameCB& frame_callback) OVERRIDE;
+
+  virtual void StopSourceImpl() OVERRIDE;
+
   // ResourceHost overrides:
   virtual void DidConnectPendingHostToResource() OVERRIDE;
 
@@ -49,6 +83,9 @@
       ppapi::host::HostMessageContext* context,
       const ppapi::MediaStreamVideoTrackShared::Attributes& attributes);
 
+  void InitBlinkTrack();
+  void OnTrackStarted(MediaStreamSource* source, bool success);
+
   blink::WebMediaStreamTrack track_;
 
   // True if it has been added to |blink::WebMediaStreamTrack| as a sink.
@@ -72,6 +109,16 @@
   // The size of frame pixels in bytes.
   uint32_t frame_data_size_;
 
+  // TODO(ronghuawu): Remove |type_| and split PepperMediaStreamVideoTrackHost
+  // into 2 classes for read and write.
+  TrackType type_;
+  bool output_started_;
+
+  // Internal class used for delivering video frames on the IO-thread to
+  // the MediaStreamVideoSource implementation.
+  class FrameDeliverer;
+  scoped_refptr<FrameDeliverer> frame_deliverer_;
+
   DISALLOW_COPY_AND_ASSIGN(PepperMediaStreamVideoTrackHost);
 };
 
diff --git a/content/renderer/pepper/pepper_platform_context_3d.cc b/content/renderer/pepper/pepper_platform_context_3d.cc
deleted file mode 100644
index 239c67d..0000000
--- a/content/renderer/pepper/pepper_platform_context_3d.cc
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "content/renderer/pepper/pepper_platform_context_3d.h"
-
-#include "base/bind.h"
-#include "content/common/gpu/client/context_provider_command_buffer.h"
-#include "content/common/gpu/client/gpu_channel_host.h"
-#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
-#include "content/renderer/render_thread_impl.h"
-#include "gpu/command_buffer/client/gles2_cmd_helper.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "ppapi/c/pp_graphics_3d.h"
-#include "ui/gl/gpu_preference.h"
-#include "url/gurl.h"
-
-namespace content {
-
-PlatformContext3D::PlatformContext3D()
-    : has_alpha_(false), command_buffer_(NULL), weak_ptr_factory_(this) {}
-
-PlatformContext3D::~PlatformContext3D() {
-  if (command_buffer_) {
-    DCHECK(channel_.get());
-    channel_->DestroyCommandBuffer(command_buffer_);
-    command_buffer_ = NULL;
-  }
-
-  channel_ = NULL;
-}
-
-bool PlatformContext3D::Init(const int32* attrib_list,
-                             PlatformContext3D* share_context) {
-  // Ignore initializing more than once.
-  if (command_buffer_)
-    return true;
-
-  RenderThreadImpl* render_thread = RenderThreadImpl::current();
-  if (!render_thread)
-    return false;
-
-  gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
-
-  channel_ = render_thread->EstablishGpuChannelSync(
-      CAUSE_FOR_GPU_LAUNCH_PEPPERPLATFORMCONTEXT3DIMPL_INITIALIZE);
-  if (!channel_.get())
-    return false;
-
-  gfx::Size surface_size;
-  std::vector<int32> attribs;
-  // TODO(alokp): Change GpuChannelHost::CreateOffscreenCommandBuffer()
-  // interface to accept width and height in the attrib_list so that
-  // we do not need to filter for width and height here.
-  if (attrib_list) {
-    for (const int32_t* attr = attrib_list; attr[0] != PP_GRAPHICS3DATTRIB_NONE;
-         attr += 2) {
-      switch (attr[0]) {
-        case PP_GRAPHICS3DATTRIB_WIDTH:
-          surface_size.set_width(attr[1]);
-          break;
-        case PP_GRAPHICS3DATTRIB_HEIGHT:
-          surface_size.set_height(attr[1]);
-          break;
-        case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE:
-          gpu_preference =
-              (attr[1] == PP_GRAPHICS3DATTRIB_GPU_PREFERENCE_LOW_POWER)
-                  ? gfx::PreferIntegratedGpu
-                  : gfx::PreferDiscreteGpu;
-          break;
-        case PP_GRAPHICS3DATTRIB_ALPHA_SIZE:
-          has_alpha_ = attr[1] > 0;
-        // fall-through
-        default:
-          attribs.push_back(attr[0]);
-          attribs.push_back(attr[1]);
-          break;
-      }
-    }
-    attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
-  }
-
-  CommandBufferProxyImpl* share_buffer = NULL;
-  if (share_context) {
-    PlatformContext3D* share_impl =
-        static_cast<PlatformContext3D*>(share_context);
-    share_buffer = share_impl->command_buffer_;
-  }
-
-  command_buffer_ = channel_->CreateOffscreenCommandBuffer(
-      surface_size, share_buffer, attribs, GURL::EmptyGURL(), gpu_preference);
-  if (!command_buffer_)
-    return false;
-  if (!command_buffer_->Initialize())
-    return false;
-  gpu::Mailbox mailbox = gpu::Mailbox::Generate();
-  if (!command_buffer_->ProduceFrontBuffer(mailbox))
-    return false;
-  mailbox_ = mailbox;
-  sync_point_ = command_buffer_->InsertSyncPoint();
-
-  command_buffer_->SetChannelErrorCallback(base::Bind(
-      &PlatformContext3D::OnContextLost, weak_ptr_factory_.GetWeakPtr()));
-  command_buffer_->SetOnConsoleMessageCallback(base::Bind(
-      &PlatformContext3D::OnConsoleMessage, weak_ptr_factory_.GetWeakPtr()));
-
-  return true;
-}
-
-void PlatformContext3D::GetBackingMailbox(gpu::Mailbox* mailbox,
-                                          uint32* sync_point) {
-  *mailbox = mailbox_;
-  *sync_point = sync_point_;
-}
-
-void PlatformContext3D::InsertSyncPointForBackingMailbox() {
-  DCHECK(command_buffer_);
-  sync_point_ = command_buffer_->InsertSyncPoint();
-}
-
-bool PlatformContext3D::IsOpaque() {
-  DCHECK(command_buffer_);
-  return !has_alpha_;
-}
-
-gpu::CommandBuffer* PlatformContext3D::GetCommandBuffer() {
-  return command_buffer_;
-}
-
-gpu::GpuControl* PlatformContext3D::GetGpuControl() { return command_buffer_; }
-
-int PlatformContext3D::GetCommandBufferRouteId() {
-  DCHECK(command_buffer_);
-  return command_buffer_->GetRouteID();
-}
-
-void PlatformContext3D::SetContextLostCallback(const base::Closure& task) {
-  context_lost_callback_ = task;
-}
-
-void PlatformContext3D::SetOnConsoleMessageCallback(
-    const ConsoleMessageCallback& task) {
-  console_message_callback_ = task;
-}
-
-void PlatformContext3D::Echo(const base::Closure& task) {
-  command_buffer_->Echo(task);
-}
-
-void PlatformContext3D::OnContextLost() {
-  DCHECK(command_buffer_);
-
-  if (!context_lost_callback_.is_null())
-    context_lost_callback_.Run();
-}
-
-void PlatformContext3D::OnConsoleMessage(const std::string& msg, int id) {
-  DCHECK(command_buffer_);
-
-  if (!console_message_callback_.is_null())
-    console_message_callback_.Run(msg, id);
-}
-
-}  // namespace content
diff --git a/content/renderer/pepper/pepper_platform_context_3d.h b/content/renderer/pepper/pepper_platform_context_3d.h
deleted file mode 100644
index 8112ea9..0000000
--- a/content/renderer/pepper/pepper_platform_context_3d.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_CONTEXT_3D_H_
-#define CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_CONTEXT_3D_H_
-
-#include "base/callback.h"
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
-#include "gpu/command_buffer/common/mailbox.h"
-
-class CommandBufferProxy;
-namespace gpu {
-class CommandBuffer;
-struct Mailbox;
-}  // namespace gpu
-
-namespace content {
-class ContextProviderCommandBuffer;
-class GpuChannelHost;
-
-class PlatformContext3D {
- public:
-  explicit PlatformContext3D();
-  ~PlatformContext3D();
-
-  // Initialize the context.
-  bool Init(const int32* attrib_list, PlatformContext3D* share_context);
-
-  // Retrieves the mailbox name for the front buffer backing the context.
-  void GetBackingMailbox(gpu::Mailbox* mailbox, uint32* sync_point);
-
-  // Inserts a new sync point to associate with the backing mailbox, that should
-  // be waited on before using the mailbox.
-  void InsertSyncPointForBackingMailbox();
-
-  // Returns true if the backing texture is always opaque.
-  bool IsOpaque();
-
-  // This call will return the address of the command buffer for this context
-  // that is constructed in Initialize() and is valid until this context is
-  // destroyed.
-  gpu::CommandBuffer* GetCommandBuffer();
-
-  // Returns the GpuControl class that services out-of-band messages.
-  gpu::GpuControl* GetGpuControl();
-
-  // If the command buffer is routed in the GPU channel, return the route id.
-  // Otherwise return 0.
-  int GetCommandBufferRouteId();
-
-  // Set an optional callback that will be invoked when the context is lost
-  // (e.g. gpu process crash). Takes ownership of the callback.
-  typedef base::Callback<void(const std::string&, int)> ConsoleMessageCallback;
-  void SetContextLostCallback(const base::Closure& callback);
-
-  // Set an optional callback that will be invoked when the GPU process
-  // sends a console message.
-  void SetOnConsoleMessageCallback(const ConsoleMessageCallback& callback);
-
-  // Run the callback once the channel has been flushed.
-  void Echo(const base::Closure& task);
-
- private:
-  bool InitRaw();
-  void OnContextLost();
-  void OnConsoleMessage(const std::string& msg, int id);
-
-  scoped_refptr<GpuChannelHost> channel_;
-  gpu::Mailbox mailbox_;
-  uint32 sync_point_;
-  bool has_alpha_;
-  CommandBufferProxyImpl* command_buffer_;
-  base::Closure context_lost_callback_;
-  ConsoleMessageCallback console_message_callback_;
-  base::WeakPtrFactory<PlatformContext3D> weak_ptr_factory_;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_CONTEXT_3D_H_
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index a951355..283db70 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -34,7 +34,6 @@
 #include "content/renderer/pepper/pepper_file_ref_renderer_host.h"
 #include "content/renderer/pepper/pepper_graphics_2d_host.h"
 #include "content/renderer/pepper/pepper_in_process_router.h"
-#include "content/renderer/pepper/pepper_platform_context_3d.h"
 #include "content/renderer/pepper/pepper_url_loader_host.h"
 #include "content/renderer/pepper/plugin_module.h"
 #include "content/renderer/pepper/plugin_object.h"
@@ -69,6 +68,7 @@
 #include "ppapi/c/private/ppp_pdf.h"
 #include "ppapi/host/ppapi_host.h"
 #include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/serialized_var.h"
 #include "ppapi/proxy/uma_private_resource.h"
 #include "ppapi/proxy/url_loader_resource.h"
 #include "ppapi/shared_impl/ppapi_permissions.h"
@@ -505,7 +505,6 @@
       find_identifier_(-1),
       plugin_find_interface_(NULL),
       plugin_input_event_interface_(NULL),
-      plugin_messaging_interface_(NULL),
       plugin_mouse_lock_interface_(NULL),
       plugin_pdf_interface_(NULL),
       plugin_private_interface_(NULL),
@@ -513,7 +512,6 @@
       plugin_textinput_interface_(NULL),
       plugin_zoom_interface_(NULL),
       checked_for_plugin_input_event_interface_(false),
-      checked_for_plugin_messaging_interface_(false),
       checked_for_plugin_pdf_interface_(false),
       gamepad_impl_(new GamepadImpl()),
       uma_private_impl_(NULL),
@@ -738,10 +736,9 @@
 void PepperPluginInstanceImpl::CommitBackingTexture() {
   if (!texture_layer_.get())
     return;
-  PlatformContext3D* context = bound_graphics_3d_->platform_context();
   gpu::Mailbox mailbox;
   uint32 sync_point = 0;
-  context->GetBackingMailbox(&mailbox, &sync_point);
+  bound_graphics_3d_->GetBackingMailbox(&mailbox, &sync_point);
   DCHECK(!mailbox.IsZero());
   DCHECK_NE(sync_point, 0u);
   texture_layer_->SetTextureMailboxWithoutReleaseCallback(
@@ -1117,11 +1114,19 @@
 
 void PepperPluginInstanceImpl::HandleMessage(PP_Var message) {
   TRACE_EVENT0("ppapi", "PepperPluginInstanceImpl::HandleMessage");
-  // Keep a reference on the stack. See NOTE above.
-  scoped_refptr<PepperPluginInstanceImpl> ref(this);
-  if (!LoadMessagingInterface())
+  ppapi::proxy::HostDispatcher* dispatcher =
+      ppapi::proxy::HostDispatcher::GetForInstance(pp_instance());
+  if (!dispatcher || (message.type == PP_VARTYPE_OBJECT)) {
+    // The dispatcher should always be valid, and the browser should never send
+    // an 'object' var over PPP_Messaging.
+    NOTREACHED();
     return;
-  plugin_messaging_interface_->HandleMessage(pp_instance(), message);
+  }
+  dispatcher->Send(new PpapiMsg_PPPMessaging_HandleMessage(
+      ppapi::API_ID_PPP_MESSAGING,
+      pp_instance(),
+      ppapi::proxy::SerializedVarSendInputShmem(dispatcher, message,
+                                                pp_instance())));
 }
 
 PP_Var PepperPluginInstanceImpl::GetInstanceObject() {
@@ -1367,15 +1372,6 @@
   return !!plugin_input_event_interface_;
 }
 
-bool PepperPluginInstanceImpl::LoadMessagingInterface() {
-  if (!checked_for_plugin_messaging_interface_) {
-    checked_for_plugin_messaging_interface_ = true;
-    plugin_messaging_interface_ = static_cast<const PPP_Messaging*>(
-        module_->GetPluginInterface(PPP_MESSAGING_INTERFACE));
-  }
-  return !!plugin_messaging_interface_;
-}
-
 bool PepperPluginInstanceImpl::LoadMouseLockInterface() {
   if (!plugin_mouse_lock_interface_) {
     plugin_mouse_lock_interface_ = static_cast<const PPP_MouseLock*>(
@@ -1921,8 +1917,7 @@
   gpu::Mailbox mailbox;
   uint32 sync_point = 0;
   if (bound_graphics_3d_.get()) {
-    PlatformContext3D* context = bound_graphics_3d_->platform_context();
-    context->GetBackingMailbox(&mailbox, &sync_point);
+    bound_graphics_3d_->GetBackingMailbox(&mailbox, &sync_point);
     DCHECK_EQ(mailbox.IsZero(), sync_point == 0);
   }
   bool want_3d_layer = !mailbox.IsZero();
@@ -2761,8 +2756,6 @@
   plugin_find_interface_ = NULL;
   plugin_input_event_interface_ = NULL;
   checked_for_plugin_input_event_interface_ = false;
-  plugin_messaging_interface_ = NULL;
-  checked_for_plugin_messaging_interface_ = false;
   plugin_mouse_lock_interface_ = NULL;
   plugin_pdf_interface_ = NULL;
   checked_for_plugin_pdf_interface_ = false;
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h
index ec0a452..b018b14 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.h
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -36,7 +36,6 @@
 #include "ppapi/c/ppb_input_event.h"
 #include "ppapi/c/ppp_graphics_3d.h"
 #include "ppapi/c/ppp_input_event.h"
-#include "ppapi/c/ppp_messaging.h"
 #include "ppapi/c/ppp_mouse_lock.h"
 #include "ppapi/c/private/ppb_content_decryptor_private.h"
 #include "ppapi/c/private/ppp_find_private.h"
@@ -566,7 +565,6 @@
 
   bool LoadFindInterface();
   bool LoadInputEventInterface();
-  bool LoadMessagingInterface();
   bool LoadMouseLockInterface();
   bool LoadPdfInterface();
   bool LoadPrintInterface();
@@ -713,7 +711,6 @@
   // When adding PPP interfaces, make sure to reset them in ResetAsProxied.
   const PPP_Find_Private* plugin_find_interface_;
   const PPP_InputEvent* plugin_input_event_interface_;
-  const PPP_Messaging* plugin_messaging_interface_;
   const PPP_MouseLock* plugin_mouse_lock_interface_;
   const PPP_Pdf* plugin_pdf_interface_;
   const PPP_Instance_Private* plugin_private_interface_;
@@ -725,7 +722,6 @@
   // corresponding interfaces, so that we can ask only once.
   // When adding flags, make sure to reset them in ResetAsProxied.
   bool checked_for_plugin_input_event_interface_;
-  bool checked_for_plugin_messaging_interface_;
   bool checked_for_plugin_pdf_interface_;
 
   // This is only valid between a successful PrintBegin call and a PrintEnd
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.cc b/content/renderer/pepper/ppb_graphics_3d_impl.cc
index fa5d6c8..d40f220 100644
--- a/content/renderer/pepper/ppb_graphics_3d_impl.cc
+++ b/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -8,11 +8,13 @@
 #include "base/command_line.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/common/gpu/client/command_buffer_proxy_impl.h"
+#include "content/common/gpu/client/gpu_channel_host.h"
 #include "content/public/common/content_switches.h"
 #include "content/renderer/pepper/host_globals.h"
-#include "content/renderer/pepper/pepper_platform_context_3d.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
 #include "content/renderer/pepper/plugin_module.h"
+#include "content/renderer/render_thread_impl.h"
 #include "content/renderer/render_view_impl.h"
 #include "gpu/command_buffer/client/gles2_implementation.h"
 #include "ppapi/c/ppp_graphics_3d.h"
@@ -44,9 +46,21 @@
     : PPB_Graphics3D_Shared(instance),
       bound_to_instance_(false),
       commit_pending_(false),
+      sync_point_(0),
+      has_alpha_(false),
+      command_buffer_(NULL),
       weak_ptr_factory_(this) {}
 
-PPB_Graphics3D_Impl::~PPB_Graphics3D_Impl() { DestroyGLES2Impl(); }
+PPB_Graphics3D_Impl::~PPB_Graphics3D_Impl() {
+  DestroyGLES2Impl();
+  if (command_buffer_) {
+    DCHECK(channel_.get());
+    channel_->DestroyCommandBuffer(command_buffer_);
+    command_buffer_ = NULL;
+  }
+
+  channel_ = NULL;
+}
 
 // static
 PP_Resource PPB_Graphics3D_Impl::Create(PP_Instance instance,
@@ -120,7 +134,7 @@
 }
 
 uint32_t PPB_Graphics3D_Impl::InsertSyncPoint() {
-  return platform_context_->GetGpuControl()->InsertSyncPoint();
+  return command_buffer_->InsertSyncPoint();
 }
 
 bool PPB_Graphics3D_Impl::BindToInstance(bool bind) {
@@ -128,7 +142,7 @@
   return true;
 }
 
-bool PPB_Graphics3D_Impl::IsOpaque() { return platform_context_->IsOpaque(); }
+bool PPB_Graphics3D_Impl::IsOpaque() { return !has_alpha_; }
 
 void PPB_Graphics3D_Impl::ViewInitiatedPaint() {
   commit_pending_ = false;
@@ -139,15 +153,21 @@
 
 void PPB_Graphics3D_Impl::ViewFlushedPaint() {}
 
+int PPB_Graphics3D_Impl::GetCommandBufferRouteId() {
+  DCHECK(command_buffer_);
+  return command_buffer_->GetRouteID();
+}
+
 gpu::CommandBuffer* PPB_Graphics3D_Impl::GetCommandBuffer() {
-  return platform_context_->GetCommandBuffer();
+  return command_buffer_;
 }
 
 gpu::GpuControl* PPB_Graphics3D_Impl::GetGpuControl() {
-  return platform_context_->GetGpuControl();
+  return command_buffer_;
 }
 
 int32 PPB_Graphics3D_Impl::DoSwapBuffers() {
+  DCHECK(command_buffer_);
   // We do not have a GLES2 implementation when using an OOP proxy.
   // The plugin-side proxy is responsible for adding the SwapBuffers command
   // to the command buffer in that case.
@@ -156,7 +176,7 @@
 
   // Since the backing texture has been updated, a new sync point should be
   // inserted.
-  platform_context_->InsertSyncPointForBackingMailbox();
+  sync_point_ = command_buffer_->InsertSyncPoint();
 
   if (bound_to_instance_) {
     // If we are bound to the instance, we need to ask the compositor
@@ -170,8 +190,8 @@
     commit_pending_ = true;
   } else {
     // Wait for the command to complete on the GPU to allow for throttling.
-    platform_context_->Echo(base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers,
-                                       weak_ptr_factory_.GetWeakPtr()));
+    command_buffer_->Echo(base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers,
+                                     weak_ptr_factory_.GetWeakPtr()));
   }
 
   return PP_OK_COMPLETIONPENDING;
@@ -182,10 +202,6 @@
   if (!InitRaw(share_context, attrib_list))
     return false;
 
-  gpu::CommandBuffer* command_buffer = GetCommandBuffer();
-  if (!command_buffer->Initialize())
-    return false;
-
   gpu::gles2::GLES2Implementation* share_gles2 = NULL;
   if (share_context) {
     share_gles2 =
@@ -209,24 +225,71 @@
   if (!prefs.pepper_3d_enabled)
     return false;
 
-  platform_context_.reset(new PlatformContext3D);
-  if (!platform_context_)
+  RenderThreadImpl* render_thread = RenderThreadImpl::current();
+  if (!render_thread)
     return false;
 
-  PlatformContext3D* share_platform_context = NULL;
+  channel_ = render_thread->EstablishGpuChannelSync(
+      CAUSE_FOR_GPU_LAUNCH_PEPPERPLATFORMCONTEXT3DIMPL_INITIALIZE);
+  if (!channel_.get())
+    return false;
+
+  gfx::Size surface_size;
+  std::vector<int32> attribs;
+  gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
+  // TODO(alokp): Change GpuChannelHost::CreateOffscreenCommandBuffer()
+  // interface to accept width and height in the attrib_list so that
+  // we do not need to filter for width and height here.
+  if (attrib_list) {
+    for (const int32_t* attr = attrib_list; attr[0] != PP_GRAPHICS3DATTRIB_NONE;
+         attr += 2) {
+      switch (attr[0]) {
+        case PP_GRAPHICS3DATTRIB_WIDTH:
+          surface_size.set_width(attr[1]);
+          break;
+        case PP_GRAPHICS3DATTRIB_HEIGHT:
+          surface_size.set_height(attr[1]);
+          break;
+        case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE:
+          gpu_preference =
+              (attr[1] == PP_GRAPHICS3DATTRIB_GPU_PREFERENCE_LOW_POWER)
+                  ? gfx::PreferIntegratedGpu
+                  : gfx::PreferDiscreteGpu;
+          break;
+        case PP_GRAPHICS3DATTRIB_ALPHA_SIZE:
+          has_alpha_ = attr[1] > 0;
+        // fall-through
+        default:
+          attribs.push_back(attr[0]);
+          attribs.push_back(attr[1]);
+          break;
+      }
+    }
+    attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
+  }
+
+  CommandBufferProxyImpl* share_buffer = NULL;
   if (share_context) {
     PPB_Graphics3D_Impl* share_graphics =
         static_cast<PPB_Graphics3D_Impl*>(share_context);
-    share_platform_context = share_graphics->platform_context();
+    share_buffer = share_graphics->command_buffer_;
   }
 
-  if (!platform_context_->Init(attrib_list, share_platform_context))
+  command_buffer_ = channel_->CreateOffscreenCommandBuffer(
+      surface_size, share_buffer, attribs, GURL::EmptyGURL(), gpu_preference);
+  if (!command_buffer_)
     return false;
+  if (!command_buffer_->Initialize())
+    return false;
+  mailbox_ = gpu::Mailbox::Generate();
+  if (!command_buffer_->ProduceFrontBuffer(mailbox_))
+    return false;
+  sync_point_ = command_buffer_->InsertSyncPoint();
 
-  platform_context_->SetContextLostCallback(base::Bind(
+  command_buffer_->SetChannelErrorCallback(base::Bind(
       &PPB_Graphics3D_Impl::OnContextLost, weak_ptr_factory_.GetWeakPtr()));
 
-  platform_context_->SetOnConsoleMessageCallback(base::Bind(
+  command_buffer_->SetOnConsoleMessageCallback(base::Bind(
       &PPB_Graphics3D_Impl::OnConsoleMessage, weak_ptr_factory_.GetWeakPtr()));
   return true;
 }
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.h b/content/renderer/pepper/ppb_graphics_3d_impl.h
index e721be6..c3520c0 100644
--- a/content/renderer/pepper/ppb_graphics_3d_impl.h
+++ b/content/renderer/pepper/ppb_graphics_3d_impl.h
@@ -6,11 +6,13 @@
 #define CONTENT_RENDERER_PEPPER_PPB_GRAPHICS_3D_IMPL_H_
 
 #include "base/memory/weak_ptr.h"
+#include "gpu/command_buffer/common/mailbox.h"
 #include "ppapi/shared_impl/ppb_graphics_3d_shared.h"
 #include "ppapi/shared_impl/resource.h"
 
 namespace content {
-class PlatformContext3D;
+class CommandBufferProxyImpl;
+class GpuChannelHost;
 
 class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared {
  public:
@@ -46,7 +48,14 @@
   void ViewInitiatedPaint();
   void ViewFlushedPaint();
 
-  PlatformContext3D* platform_context() { return platform_context_.get(); }
+  void GetBackingMailbox(gpu::Mailbox* mailbox, uint32* sync_point) {
+    *mailbox = mailbox_;
+    *sync_point = sync_point_;
+  }
+
+  int GetCommandBufferRouteId();
+
+  GpuChannelHost* channel() { return channel_; }
 
  protected:
   virtual ~PPB_Graphics3D_Impl();
@@ -72,8 +81,13 @@
   bool bound_to_instance_;
   // True when waiting for compositor to commit our backing texture.
   bool commit_pending_;
-  // The 3D Context. Responsible for providing the command buffer.
-  scoped_ptr<PlatformContext3D> platform_context_;
+
+  gpu::Mailbox mailbox_;
+  uint32 sync_point_;
+  bool has_alpha_;
+  scoped_refptr<GpuChannelHost> channel_;
+  CommandBufferProxyImpl* command_buffer_;
+
   base::WeakPtrFactory<PPB_Graphics3D_Impl> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(PPB_Graphics3D_Impl);
diff --git a/content/renderer/pepper/ppb_video_decoder_impl.cc b/content/renderer/pepper/ppb_video_decoder_impl.cc
index 7a7d61a..9844c36 100644
--- a/content/renderer/pepper/ppb_video_decoder_impl.cc
+++ b/content/renderer/pepper/ppb_video_decoder_impl.cc
@@ -12,7 +12,6 @@
 #include "content/common/gpu/client/gpu_channel_host.h"
 #include "content/renderer/pepper/common.h"
 #include "content/renderer/pepper/host_globals.h"
-#include "content/renderer/pepper/pepper_platform_context_3d.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
 #include "content/renderer/pepper/plugin_module.h"
 #include "content/renderer/pepper/ppb_buffer_impl.h"
@@ -33,7 +32,6 @@
 using ppapi::thunk::EnterResourceNoLock;
 using ppapi::thunk::PPB_Buffer_API;
 using ppapi::thunk::PPB_Graphics3D_API;
-using ppapi::thunk::PPB_VideoDecoder_API;
 
 namespace {
 
@@ -112,45 +110,33 @@
 PP_Resource PPB_VideoDecoder_Impl::Create(PP_Instance instance,
                                           PP_Resource graphics_context,
                                           PP_VideoDecoder_Profile profile) {
-  EnterResourceNoLock<PPB_Graphics3D_API> enter_context(graphics_context, true);
-  if (enter_context.failed())
-    return 0;
-  PPB_Graphics3D_Impl* graphics3d_impl =
-      static_cast<PPB_Graphics3D_Impl*>(enter_context.object());
-
   scoped_refptr<PPB_VideoDecoder_Impl> decoder(
       new PPB_VideoDecoder_Impl(instance));
-  if (decoder->Init(graphics_context,
-                    graphics3d_impl->platform_context(),
-                    graphics3d_impl->gles2_impl(),
-                    profile))
+  if (decoder->Init(graphics_context, profile))
     return decoder->GetReference();
   return 0;
 }
 
 bool PPB_VideoDecoder_Impl::Init(PP_Resource graphics_context,
-                                 PlatformContext3D* context,
-                                 gpu::gles2::GLES2Implementation* gles2_impl,
                                  PP_VideoDecoder_Profile profile) {
-  InitCommon(graphics_context, gles2_impl);
+  EnterResourceNoLock<PPB_Graphics3D_API> enter_context(graphics_context, true);
+  if (enter_context.failed())
+    return false;
 
-  int command_buffer_route_id = context->GetCommandBufferRouteId();
+  PPB_Graphics3D_Impl* graphics_3d =
+      static_cast<PPB_Graphics3D_Impl*>(enter_context.object());
+
+  int command_buffer_route_id = graphics_3d->GetCommandBufferRouteId();
   if (command_buffer_route_id == 0)
     return false;
 
+  InitCommon(graphics_context, graphics_3d->gles2_impl());
   FlushCommandBuffer();
 
-  RenderThreadImpl* render_thread = RenderThreadImpl::current();
-
   // This is not synchronous, but subsequent IPC messages will be buffered, so
   // it is okay to immediately send IPC messages through the returned channel.
-  GpuChannelHost* channel =
-      render_thread->EstablishGpuChannelSync(
-          CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE);
-
-  if (!channel)
-    return false;
-
+  GpuChannelHost* channel = graphics_3d->channel();
+  DCHECK(channel);
   decoder_ = channel->CreateVideoDecoder(command_buffer_route_id);
   return (decoder_ && decoder_->Initialize(PPToMediaProfile(profile), this));
 }
diff --git a/content/renderer/pepper/ppb_video_decoder_impl.h b/content/renderer/pepper/ppb_video_decoder_impl.h
index 8cbaedb..c099950 100644
--- a/content/renderer/pepper/ppb_video_decoder_impl.h
+++ b/content/renderer/pepper/ppb_video_decoder_impl.h
@@ -14,20 +14,13 @@
 #include "ppapi/c/pp_var.h"
 #include "ppapi/shared_impl/ppb_video_decoder_shared.h"
 #include "ppapi/shared_impl/resource.h"
-#include "ppapi/thunk/ppb_video_decoder_api.h"
+#include "ppapi/thunk/ppb_video_decoder_dev_api.h"
 
 struct PP_PictureBuffer_Dev;
 struct PP_VideoBitstreamBuffer_Dev;
 
-namespace gpu {
-namespace gles2 {
-class GLES2Implementation;
-}  // namespace gles2
-}  // namespace gpu
-
 namespace content {
-class PlatformContext3D;
-class PlatformVideoDecoder;
+class PPB_Graphics3D_Impl;
 
 class PPB_VideoDecoder_Impl : public ppapi::PPB_VideoDecoder_Shared,
                               public media::VideoDecodeAccelerator::Client {
@@ -38,7 +31,7 @@
                             PP_Resource graphics_context,
                             PP_VideoDecoder_Profile profile);
 
-  // PPB_VideoDecoder_API implementation.
+  // PPB_VideoDecoder_Dev_API implementation.
   virtual int32_t Decode(const PP_VideoBitstreamBuffer_Dev* bitstream_buffer,
                          scoped_refptr<ppapi::TrackedCallback> callback)
       OVERRIDE;
@@ -68,8 +61,6 @@
 
   explicit PPB_VideoDecoder_Impl(PP_Instance instance);
   bool Init(PP_Resource graphics_context,
-            PlatformContext3D* context,
-            gpu::gles2::GLES2Implementation* gles2_impl,
             PP_VideoDecoder_Profile profile);
 
   // This is NULL before initialization, and after destruction.
diff --git a/content/renderer/pepper/resource_converter.cc b/content/renderer/pepper/resource_converter.cc
index 5fef938..62164cf 100644
--- a/content/renderer/pepper/resource_converter.cc
+++ b/content/renderer/pepper/resource_converter.cc
@@ -18,6 +18,7 @@
 #include "ppapi/shared_impl/scoped_pp_var.h"
 #include "third_party/WebKit/public/platform/WebFileSystem.h"
 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
+#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
 #include "third_party/WebKit/public/web/WebDOMFileSystem.h"
 #include "third_party/WebKit/public/web/WebDOMMediaStreamTrack.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
@@ -144,6 +145,16 @@
   return true;
 }
 
+bool ResourceHostToDOMMediaStreamVideoTrack(
+    content::PepperMediaStreamVideoTrackHost* host,
+    v8::Handle<v8::Context> context,
+    v8::Handle<v8::Value>* dom_video_track) {
+  // TODO(ronghuawu): Implement this once crbug/352219 is resolved.
+  // blink::WebMediaStreamTrack track = host->track();
+  // *dom_video_track = track.toV8Value();
+  return false;
+}
+
 bool DOMMediaStreamTrackToResource(
     PP_Instance instance,
     RendererPpapiHost* host,
@@ -299,6 +310,11 @@
         static_cast<content::PepperFileSystemHost*>(resource_host),
         context,
         result);
+  } else if (resource_host->IsMediaStreamVideoTrackHost()) {
+    return ResourceHostToDOMMediaStreamVideoTrack(
+        static_cast<content::PepperMediaStreamVideoTrackHost*>(resource_host),
+        context,
+        result);
   } else {
     LOG(ERROR) << "The type of resource #" << resource_id
                << " cannot be converted to a JavaScript object.";
diff --git a/content/renderer/pepper/resource_creation_impl.cc b/content/renderer/pepper/resource_creation_impl.cc
index 1a698b1..404a7e6 100644
--- a/content/renderer/pepper/resource_creation_impl.cc
+++ b/content/renderer/pepper/resource_creation_impl.cc
@@ -195,6 +195,11 @@
                                                          code);
 }
 
+PP_Resource ResourceCreationImpl::CreateMediaStreamVideoTrack(
+    PP_Instance instance) {
+  return 0;  // Not supported in-process.
+}
+
 PP_Resource ResourceCreationImpl::CreateMouseInputEvent(
     PP_Instance instance,
     PP_InputEvent_Type type,
@@ -233,14 +238,6 @@
   return 0;  // Not supported in-process.
 }
 
-PP_Resource ResourceCreationImpl::CreateTouchInputEvent(PP_Instance instance,
-                                                        PP_InputEvent_Type type,
-                                                        PP_TimeTicks time_stamp,
-                                                        uint32_t modifiers) {
-  return PPB_InputEvent_Shared::CreateTouchInputEvent(
-      ppapi::OBJECT_IS_IMPL, instance, type, time_stamp, modifiers);
-}
-
 PP_Resource ResourceCreationImpl::CreateNetworkMonitor(PP_Instance instance) {
   return 0;  // Not supported in-process.
 }
@@ -281,6 +278,14 @@
   return 0;  // Not supported in-process.
 }
 
+PP_Resource ResourceCreationImpl::CreateTouchInputEvent(PP_Instance instance,
+                                                        PP_InputEvent_Type type,
+                                                        PP_TimeTicks time_stamp,
+                                                        uint32_t modifiers) {
+  return PPB_InputEvent_Shared::CreateTouchInputEvent(
+      ppapi::OBJECT_IS_IMPL, instance, type, time_stamp, modifiers);
+}
+
 PP_Resource ResourceCreationImpl::CreateUDPSocket(PP_Instance instance) {
   return 0;  // Not supported in-process.
 }
@@ -293,7 +298,7 @@
   return 0;  // VideoCapture is not supported in process now.
 }
 
-PP_Resource ResourceCreationImpl::CreateVideoDecoder(
+PP_Resource ResourceCreationImpl::CreateVideoDecoderDev(
     PP_Instance instance,
     PP_Resource graphics3d_id,
     PP_VideoDecoder_Profile profile) {
diff --git a/content/renderer/pepper/resource_creation_impl.h b/content/renderer/pepper/resource_creation_impl.h
index 55a0d7c..4a301f4 100644
--- a/content/renderer/pepper/resource_creation_impl.h
+++ b/content/renderer/pepper/resource_creation_impl.h
@@ -86,6 +86,8 @@
                                                    uint32_t key_code,
                                                    PP_Var character_text,
                                                    PP_Var code) OVERRIDE;
+  virtual PP_Resource CreateMediaStreamVideoTrack(
+      PP_Instance instance) OVERRIDE;
   virtual PP_Resource CreateMouseInputEvent(
       PP_Instance instance,
       PP_InputEvent_Type type,
@@ -104,10 +106,6 @@
   virtual PP_Resource CreateNetAddressFromNetAddressPrivate(
       PP_Instance instance,
       const PP_NetAddress_Private& private_addr) OVERRIDE;
-  virtual PP_Resource CreateTouchInputEvent(PP_Instance instance,
-                                            PP_InputEvent_Type type,
-                                            PP_TimeTicks time_stamp,
-                                            uint32_t modifiers) OVERRIDE;
   virtual PP_Resource CreateNetworkMonitor(PP_Instance instance) OVERRIDE;
   virtual PP_Resource CreatePlatformVerificationPrivate(PP_Instance instance)
       OVERRIDE;
@@ -121,12 +119,16 @@
   virtual PP_Resource CreateTCPSocket1_0(PP_Instance instance) OVERRIDE;
   virtual PP_Resource CreateTCPSocket(PP_Instance instance) OVERRIDE;
   virtual PP_Resource CreateTCPSocketPrivate(PP_Instance instance) OVERRIDE;
+  virtual PP_Resource CreateTouchInputEvent(PP_Instance instance,
+                                            PP_InputEvent_Type type,
+                                            PP_TimeTicks time_stamp,
+                                            uint32_t modifiers) OVERRIDE;
   virtual PP_Resource CreateUDPSocket(PP_Instance instance) OVERRIDE;
   virtual PP_Resource CreateUDPSocketPrivate(PP_Instance instance) OVERRIDE;
   virtual PP_Resource CreateVideoCapture(PP_Instance instance) OVERRIDE;
-  virtual PP_Resource CreateVideoDecoder(PP_Instance instance,
-                                         PP_Resource graphics3d_id,
-                                         PP_VideoDecoder_Profile profile)
+  virtual PP_Resource CreateVideoDecoderDev(PP_Instance instance,
+                                            PP_Resource graphics3d_id,
+                                            PP_VideoDecoder_Profile profile)
       OVERRIDE;
   virtual PP_Resource CreateVideoDestination(PP_Instance instance) OVERRIDE;
   virtual PP_Resource CreateVideoSource(PP_Instance instance) OVERRIDE;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 3c86654..b93c8ed 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -25,6 +25,7 @@
 #include "content/child/service_worker/service_worker_network_provider.h"
 #include "content/child/service_worker/web_service_worker_provider_impl.h"
 #include "content/child/web_socket_stream_handle_impl.h"
+#include "content/child/webmessageportchannel_impl.h"
 #include "content/common/clipboard_messages.h"
 #include "content/common/frame_messages.h"
 #include "content/common/input_messages.h"
@@ -56,7 +57,14 @@
 #include "content/renderer/ime_event_guard.h"
 #include "content/renderer/internal_document_state_data.h"
 #include "content/renderer/java/java_bridge_dispatcher.h"
+#include "content/renderer/media/audio_renderer_mixer_manager.h"
+#include "content/renderer/media/media_stream_dispatcher.h"
+#include "content/renderer/media/media_stream_impl.h"
+#include "content/renderer/media/render_media_log.h"
 #include "content/renderer/media/webcontentdecryptionmodule_impl.h"
+#include "content/renderer/media/webmediaplayer_impl.h"
+#include "content/renderer/media/webmediaplayer_ms.h"
+#include "content/renderer/media/webmediaplayer_params.h"
 #include "content/renderer/notification_provider.h"
 #include "content/renderer/npapi/plugin_channel_host.h"
 #include "content/renderer/render_process.h"
@@ -68,6 +76,7 @@
 #include "content/renderer/shared_worker_repository.h"
 #include "content/renderer/v8_value_converter_impl.h"
 #include "content/renderer/websharedworker_proxy.h"
+#include "media/base/audio_renderer_mixer_input.h"
 #include "net/base/data_url.h"
 #include "net/base/net_errors.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
@@ -106,6 +115,15 @@
 #include "content/renderer/media/rtc_peer_connection_handler.h"
 #endif
 
+#if defined(OS_ANDROID)
+#include <cpu-features.h>
+
+#include "content/common/gpu/client/context_provider_command_buffer.h"
+#include "content/renderer/android/synchronous_compositor_factory.h"
+#include "content/renderer/media/android/stream_texture_factory_impl.h"
+#include "content/renderer/media/android/webmediaplayer_android.h"
+#endif
+
 using blink::WebContextMenuData;
 using blink::WebData;
 using blink::WebDataSource;
@@ -115,6 +133,8 @@
 using blink::WebHistoryItem;
 using blink::WebHTTPBody;
 using blink::WebLocalFrame;
+using blink::WebMediaPlayer;
+using blink::WebMediaPlayerClient;
 using blink::WebNavigationPolicy;
 using blink::WebNavigationType;
 using blink::WebNode;
@@ -203,6 +223,25 @@
   *zero = 0;
 }
 
+#if defined(SYZYASAN)
+NOINLINE static void CorruptMemoryBlock() {
+  // NOTE(sebmarchand): We intentionally corrupt a memory block here in order to
+  //     trigger an Address Sanitizer (ASAN) error report.
+  static const int kArraySize = 5;
+  int* array = new int[kArraySize];
+  // Encapsulate the invalid memory access into a try-catch statement to prevent
+  // this function from being instrumented. This way the underflow won't be
+  // detected but the corruption will (as the allocator will still be hooked).
+  __try {
+    int dummy = array[-1]--;
+    // Make sure the assignments to the dummy value aren't optimized away.
+    base::debug::Alias(&array);
+  } __except (EXCEPTION_EXECUTE_HANDLER) {
+  }
+  delete[] array;
+}
+#endif
+
 #if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
 NOINLINE static void MaybeTriggerAsanError(const GURL& url) {
   // NOTE(rogerm): We intentionally perform an invalid heap access here in
@@ -211,6 +250,9 @@
   static const char kHeapOverflow[] = "/heap-overflow";
   static const char kHeapUnderflow[] = "/heap-underflow";
   static const char kUseAfterFree[] = "/use-after-free";
+#if defined(SYZYASAN)
+  static const char kCorruptHeapBlock[] = "/corrupt-heap-block";
+#endif
   static const int kArraySize = 5;
 
   if (!url.DomainIs(kCrashDomain, sizeof(kCrashDomain) - 1))
@@ -230,6 +272,10 @@
     int* dangling = array.get();
     array.reset();
     dummy = dangling[kArraySize / 2];
+#if defined(SYZYASAN)
+  } else if (crash_type == kCorruptHeapBlock) {
+    CorruptMemoryBlock();
+#endif
   }
 
   // Make sure the assignments to the dummy value aren't optimized away.
@@ -276,7 +322,7 @@
   // 2. The origin of the url and the opener is the same in which case the
   //    opener relationship is maintained.
   // 3. Reloads/form submits/back forward navigations
-  if (!url.SchemeIs(kHttpScheme) && !url.SchemeIs(kHttpsScheme))
+  if (!url.SchemeIs(url::kHttpScheme) && !url.SchemeIs(url::kHttpsScheme))
     return false;
 
   if (type != blink::WebNavigationTypeReload &&
@@ -341,7 +387,10 @@
       selection_text_offset_(0),
       selection_range_(gfx::Range::InvalidRange()),
       handling_select_range_(false),
-      notification_provider_(NULL) {
+      notification_provider_(NULL),
+      media_stream_client_(NULL),
+      web_user_media_client_(NULL),
+      weak_factory_(this) {
   RenderThread::Get()->AddRoute(routing_id_, this);
 
 #if defined(OS_ANDROID)
@@ -567,6 +616,13 @@
 
 #endif  // ENABLE_PLUGINS
 
+void RenderFrameImpl::SetMediaStreamClientForTesting(
+    MediaStreamClient* media_stream_client) {
+  DCHECK(!media_stream_client_);
+  DCHECK(!web_user_media_client_);
+  media_stream_client_ = media_stream_client;
+}
+
 bool RenderFrameImpl::Send(IPC::Message* message) {
   if (is_detaching_ ||
       ((is_swapped_out_ || render_view_->is_swapped_out()) &&
@@ -579,6 +635,8 @@
 }
 
 bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
+  GetContentClient()->SetActiveURL(frame_->document().url());
+
   ObserverListBase<RenderFrameObserver>::Iterator it(observers_);
   RenderFrameObserver* observer;
   while ((observer = it.GetNext()) != NULL) {
@@ -629,7 +687,8 @@
   if (!msg_is_ok) {
     // The message had a handler, but its deserialization failed.
     // Kill the renderer to avoid potential spoofing attacks.
-    CHECK(false) << "Unable to deserialize message in RenderFrameImpl.";
+    int id = msg.type();
+    CHECK(false) << "Unable to deserialize " << id << " in RenderFrameImpl.";
   }
 
   return handled;
@@ -1286,11 +1345,22 @@
     blink::WebLocalFrame* frame,
     const blink::WebURL& url,
     blink::WebMediaPlayerClient* client) {
-  DCHECK(!frame_ || frame_ == frame);
-  // TODO(nasko): Moving the implementation here involves moving a few media
-  // related client objects here or referencing them in the RenderView. Needs
-  // more work to understand where the proper place for those objects is.
-  return render_view_->CreateMediaPlayer(this, frame, url, client);
+  WebMediaPlayer* player = CreateWebMediaPlayerForMediaStream(url, client);
+  if (player)
+    return player;
+
+#if defined(OS_ANDROID)
+  return CreateAndroidWebMediaPlayer(url, client);
+#else
+  WebMediaPlayerParams params(
+      base::Bind(&ContentRendererClient::DeferMediaLoad,
+                 base::Unretained(GetContentClient()->renderer()),
+                 static_cast<RenderFrame*>(this)),
+      RenderThreadImpl::current()->GetAudioRendererMixerManager()->CreateInput(
+          render_view_->routing_id_, routing_id_));
+  return new WebMediaPlayerImpl(frame, client, weak_factory_.GetWeakPtr(),
+                                params);
+#endif  // defined(OS_ANDROID)
 }
 
 blink::WebContentDecryptionModule*
@@ -1334,14 +1404,14 @@
   DCHECK(!frame_ || frame_ == frame);
   // At this point we should have non-null data source.
   DCHECK(frame->dataSource());
+  if (!ChildThread::current())
+    return NULL;  // May be null in some tests.
   ServiceWorkerNetworkProvider* provider =
       ServiceWorkerNetworkProvider::FromDocumentState(
           DocumentState::FromDataSource(frame->dataSource()));
-  int provider_id = provider ?
-      provider->provider_id() :
-      kInvalidServiceWorkerProviderId;
   return new WebServiceWorkerProviderImpl(
-      ChildThread::current()->thread_safe_sender(), provider_id);
+      ChildThread::current()->thread_safe_sender(),
+      provider ? provider->context() : NULL);
 }
 
 void RenderFrameImpl::didAccessInitialDocument(blink::WebLocalFrame* frame) {
@@ -1395,7 +1465,15 @@
 
 void RenderFrameImpl::didDisownOpener(blink::WebLocalFrame* frame) {
   DCHECK(!frame_ || frame_ == frame);
-  render_view_->didDisownOpener(frame);
+  // We only need to notify the browser if the active, top-level frame clears
+  // its opener.  We can ignore cases where a swapped out frame clears its
+  // opener after hearing about it from the browser, and the browser does not
+  // (yet) care about subframe openers.
+  if (render_view_->is_swapped_out_ || frame->parent())
+    return;
+
+  // Notify WebContents and all its swapped out RenderViews.
+  Send(new FrameHostMsg_DidDisownOpener(routing_id_));
 }
 
 void RenderFrameImpl::frameDetached(blink::WebFrame* frame) {
@@ -1541,7 +1619,11 @@
   if (policy == blink::WebNavigationPolicyDownload) {
     render_view_->Send(new ViewHostMsg_DownloadUrl(render_view_->GetRoutingID(),
                                                    request.url(), referrer,
-                                                   suggested_name));
+                                                   suggested_name, false));
+  } else if (policy == blink::WebNavigationPolicyDownloadTo) {
+    render_view_->Send(new ViewHostMsg_DownloadUrl(render_view_->GetRoutingID(),
+                                                   request.url(), referrer,
+                                                   suggested_name, true));
   } else {
     OpenURL(frame, request.url(), referrer, policy);
   }
@@ -1966,9 +2048,8 @@
 
 void RenderFrameImpl::didHandleOnloadEvents(blink::WebLocalFrame* frame) {
   DCHECK(!frame_ || frame_ == frame);
-  // TODO(nasko): Move implementation here. Needed state:
-  // * page_id_
-  render_view_->didHandleOnloadEvents(frame);
+  if (!frame->parent())
+    Send(new FrameHostMsg_DocumentOnLoadCompleted(routing_id_));
 }
 
 void RenderFrameImpl::didFailLoad(blink::WebLocalFrame* frame,
@@ -2513,7 +2594,17 @@
 void RenderFrameImpl::didFirstVisuallyNonEmptyLayout(
     blink::WebLocalFrame* frame) {
   DCHECK(!frame_ || frame_ == frame);
-  render_view_->didFirstVisuallyNonEmptyLayout(frame);
+  if (frame->parent())
+    return;
+
+  InternalDocumentStateData* data =
+      InternalDocumentStateData::FromDataSource(frame->dataSource());
+  data->set_did_first_visually_non_empty_layout(true);
+
+#if defined(OS_ANDROID)
+  GetRenderWidget()->DidChangeBodyBackgroundColor(
+      render_view_->webwidget_->backgroundColor());
+#endif
 }
 
 void RenderFrameImpl::didChangeContentsSize(blink::WebLocalFrame* frame,
@@ -2608,7 +2699,11 @@
 }
 
 blink::WebUserMediaClient* RenderFrameImpl::userMediaClient() {
-  return render_view_->userMediaClient();
+  // This can happen in tests, in which case it's OK to return NULL.
+  if (!InitializeMediaStreamClient())
+    return NULL;
+
+  return web_user_media_client_;
 }
 
 blink::WebMIDIClient* RenderFrameImpl::webMIDIClient() {
@@ -2616,15 +2711,48 @@
 }
 
 bool RenderFrameImpl::willCheckAndDispatchMessageEvent(
-    blink::WebLocalFrame* sourceFrame,
-    blink::WebFrame* targetFrame,
-    blink::WebSecurityOrigin targetOrigin,
+    blink::WebLocalFrame* source_frame,
+    blink::WebFrame* target_frame,
+    blink::WebSecurityOrigin target_origin,
     blink::WebDOMMessageEvent event) {
-  DCHECK(!frame_ || frame_ == targetFrame);
-  // TODO(nasko): Move implementation here. Needed state:
-  // * is_swapped_out_
-  return render_view_->willCheckAndDispatchMessageEvent(
-      sourceFrame, targetFrame, targetOrigin, event);
+  DCHECK(!frame_ || frame_ == target_frame);
+
+  if (!render_view_->is_swapped_out_)
+    return false;
+
+  ViewMsg_PostMessage_Params params;
+  params.data = event.data().toString();
+  params.source_origin = event.origin();
+  if (!target_origin.isNull())
+    params.target_origin = target_origin.toString();
+
+  blink::WebMessagePortChannelArray channels = event.releaseChannels();
+  if (!channels.isEmpty()) {
+    std::vector<int> message_port_ids(channels.size());
+     // Extract the port IDs from the channel array.
+     for (size_t i = 0; i < channels.size(); ++i) {
+       WebMessagePortChannelImpl* webchannel =
+           static_cast<WebMessagePortChannelImpl*>(channels[i]);
+       message_port_ids[i] = webchannel->message_port_id();
+       webchannel->QueueMessages();
+       DCHECK_NE(message_port_ids[i], MSG_ROUTING_NONE);
+     }
+     params.message_port_ids = message_port_ids;
+  }
+
+  // Include the routing ID for the source frame (if one exists), which the
+  // browser process will translate into the routing ID for the equivalent
+  // frame in the target process.
+  params.source_routing_id = MSG_ROUTING_NONE;
+  if (source_frame) {
+    RenderViewImpl* source_view =
+        RenderViewImpl::FromWebView(source_frame->view());
+    if (source_view)
+      params.source_routing_id = source_view->routing_id();
+  }
+
+  Send(new ViewHostMsg_RouteMessageEvent(render_view_->routing_id_, params));
+  return true;
 }
 
 blink::WebString RenderFrameImpl::userAgentOverride(blink::WebLocalFrame* frame,
@@ -2693,6 +2821,21 @@
       routing_id_, frame_rect, scale_factor));
 }
 
+void RenderFrameImpl::DidPlay(blink::WebMediaPlayer* player) {
+  Send(new FrameHostMsg_MediaPlayingNotification(
+      routing_id_, reinterpret_cast<int64>(player), player->hasVideo(),
+      player->hasAudio()));
+}
+
+void RenderFrameImpl::DidPause(blink::WebMediaPlayer* player) {
+  Send(new FrameHostMsg_MediaPausedNotification(
+      routing_id_, reinterpret_cast<int64>(player)));
+}
+
+void RenderFrameImpl::PlayerGone(blink::WebMediaPlayer* player) {
+  DidPause(player);
+}
+
 void RenderFrameImpl::AddObserver(RenderFrameObserver* observer) {
   observers_.AddObserver(observer);
 }
@@ -3225,4 +3368,99 @@
   GetRenderWidget()->UpdateSelectionBounds();
 }
 
+bool RenderFrameImpl::InitializeMediaStreamClient() {
+  if (media_stream_client_)
+    return true;
+
+  if (!RenderThreadImpl::current())  // Will be NULL during unit tests.
+    return false;
+
+#if defined(OS_ANDROID)
+  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebRTC))
+    return false;
+#endif
+
+#if defined(ENABLE_WEBRTC)
+  if (!render_view_->media_stream_dispatcher_) {
+    render_view_->media_stream_dispatcher_ =
+        new MediaStreamDispatcher(render_view_.get());
+  }
+
+  MediaStreamImpl* media_stream_impl = new MediaStreamImpl(
+      render_view_.get(),
+      render_view_->media_stream_dispatcher_,
+      RenderThreadImpl::current()->GetMediaStreamDependencyFactory());
+  media_stream_client_ = media_stream_impl;
+  web_user_media_client_ = media_stream_impl;
+  return true;
+#else
+  return false;
+#endif
+}
+
+WebMediaPlayer* RenderFrameImpl::CreateWebMediaPlayerForMediaStream(
+    const blink::WebURL& url,
+    WebMediaPlayerClient* client) {
+#if defined(ENABLE_WEBRTC)
+  if (!InitializeMediaStreamClient()) {
+    LOG(ERROR) << "Failed to initialize MediaStreamClient";
+    return NULL;
+  }
+  if (media_stream_client_->IsMediaStream(url)) {
+#if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
+    bool found_neon =
+        (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
+    UMA_HISTOGRAM_BOOLEAN("Platform.WebRtcNEONFound", found_neon);
+#endif  // defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
+    return new WebMediaPlayerMS(frame_, client, weak_factory_.GetWeakPtr(),
+                                media_stream_client_, new RenderMediaLog());
+  }
+#endif  // defined(ENABLE_WEBRTC)
+  return NULL;
+}
+
+#if defined(OS_ANDROID)
+
+WebMediaPlayer* RenderFrameImpl::CreateAndroidWebMediaPlayer(
+      const blink::WebURL& url,
+      WebMediaPlayerClient* client) {
+  GpuChannelHost* gpu_channel_host =
+      RenderThreadImpl::current()->EstablishGpuChannelSync(
+          CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE);
+  if (!gpu_channel_host) {
+    LOG(ERROR) << "Failed to establish GPU channel for media player";
+    return NULL;
+  }
+
+  scoped_refptr<StreamTextureFactory> stream_texture_factory;
+  if (GetRenderWidget()->UsingSynchronousRendererCompositor()) {
+    SynchronousCompositorFactory* factory =
+        SynchronousCompositorFactory::GetInstance();
+    stream_texture_factory = factory->CreateStreamTextureFactory(
+        render_view_->routing_id_);
+  } else {
+    scoped_refptr<webkit::gpu::ContextProviderWebContext> context_provider =
+        RenderThreadImpl::current()->SharedMainThreadContextProvider();
+
+    if (!context_provider.get()) {
+      LOG(ERROR) << "Failed to get context3d for media player";
+      return NULL;
+    }
+
+    stream_texture_factory = StreamTextureFactoryImpl::Create(
+        context_provider, gpu_channel_host, render_view_->routing_id_);
+  }
+
+  return new WebMediaPlayerAndroid(
+      frame_,
+      client,
+      weak_factory_.GetWeakPtr(),
+      render_view_->media_player_manager_,
+      stream_texture_factory,
+      RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy(),
+      new RenderMediaLog());
+}
+
+#endif
+
 }  // namespace content
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index fcd8e52..a13caa6 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -17,6 +17,7 @@
 #include "content/public/common/javascript_message_type.h"
 #include "content/public/common/referrer.h"
 #include "content/public/renderer/render_frame.h"
+#include "content/renderer/media/webmediaplayer_delegate.h"
 #include "content/renderer/renderer_webcookiejar_impl.h"
 #include "ipc/ipc_message.h"
 #include "third_party/WebKit/public/web/WebDataSource.h"
@@ -35,9 +36,9 @@
 class WebMouseEvent;
 class WebContentDecryptionModule;
 class WebMIDIClient;
+class WebMediaPlayer;
 class WebNotificationPresenter;
 class WebSecurityOrigin;
-class WebUserMediaClient;
 struct WebCompositionUnderline;
 struct WebContextMenuData;
 struct WebCursorInfo;
@@ -52,6 +53,7 @@
 namespace content {
 
 class ChildFrameCompositingHelper;
+class MediaStreamClient;
 class NotificationProvider;
 class PepperPluginInstanceImpl;
 class RendererPpapiHost;
@@ -63,7 +65,8 @@
 
 class CONTENT_EXPORT RenderFrameImpl
     : public RenderFrame,
-      NON_EXPORTED_BASE(public blink::WebFrameClient) {
+      NON_EXPORTED_BASE(public blink::WebFrameClient),
+      NON_EXPORTED_BASE(public WebMediaPlayerDelegate) {
  public:
   // Creates a new RenderFrame. |render_view| is the RenderView object that this
   // frame belongs to.
@@ -175,6 +178,10 @@
     bool keep_selection);
 #endif  // ENABLE_PLUGINS
 
+  // Overrides the MediaStreamClient used when creating MediaStream players.
+  // Must be called before any players are created.
+  void SetMediaStreamClientForTesting(MediaStreamClient* media_stream_client);
+
   // IPC::Sender
   virtual bool Send(IPC::Message* msg) OVERRIDE;
 
@@ -199,7 +206,7 @@
                                  blink::WebNavigationPolicy policy) OVERRIDE;
   virtual void ExecuteJavaScript(const base::string16& javascript) OVERRIDE;
 
-  // blink::WebFrameClient implementation -------------------------------------
+  // blink::WebFrameClient implementation:
   virtual blink::WebPlugin* createPlugin(blink::WebLocalFrame* frame,
                                          const blink::WebPluginParams& params);
   virtual blink::WebMediaPlayer* createMediaPlayer(
@@ -349,9 +356,9 @@
   virtual blink::WebUserMediaClient* userMediaClient();
   virtual blink::WebMIDIClient* webMIDIClient();
   virtual bool willCheckAndDispatchMessageEvent(
-      blink::WebLocalFrame* sourceFrame,
-      blink::WebFrame* targetFrame,
-      blink::WebSecurityOrigin targetOrigin,
+      blink::WebLocalFrame* source_frame,
+      blink::WebFrame* target_frame,
+      blink::WebSecurityOrigin target_origin,
       blink::WebDOMMessageEvent event);
   virtual blink::WebString userAgentOverride(blink::WebLocalFrame* frame,
                                              const blink::WebURL& url);
@@ -363,6 +370,11 @@
   virtual void initializeChildFrame(const blink::WebRect& frame_rect,
                                     float scale_factor);
 
+  // WebMediaPlayerDelegate implementation:
+  virtual void DidPlay(blink::WebMediaPlayer* player) OVERRIDE;
+  virtual void DidPause(blink::WebMediaPlayer* player) OVERRIDE;
+  virtual void PlayerGone(blink::WebMediaPlayer* player) OVERRIDE;
+
   // TODO(nasko): Make all tests in RenderViewImplTest friends and then move
   // this back to private member.
   void OnNavigate(const FrameMsg_Navigate_Params& params);
@@ -473,6 +485,21 @@
                                const blink::WebURLError& error,
                                bool replace);
 
+  // Initializes |media_stream_client_|, returning true if successful. Returns
+  // false if it wasn't possible to create a MediaStreamClient (e.g., WebRTC is
+  // disabled) in which case |media_stream_client_| is NULL.
+  bool InitializeMediaStreamClient();
+
+  blink::WebMediaPlayer* CreateWebMediaPlayerForMediaStream(
+      const blink::WebURL& url,
+      blink::WebMediaPlayerClient* client);
+
+#if defined(OS_ANDROID)
+ blink::WebMediaPlayer* CreateAndroidWebMediaPlayer(
+      const blink::WebURL& url,
+      blink::WebMediaPlayerClient* client);
+#endif
+
   // Stores the WebLocalFrame we are associated with.
   blink::WebLocalFrame* frame_;
 
@@ -532,6 +559,12 @@
   // Holds a reference to the service which provides desktop notifications.
   NotificationProvider* notification_provider_;
 
+  // MediaStreamClient attached to this frame; lazily initialized.
+  MediaStreamClient* media_stream_client_;
+  blink::WebUserMediaClient* web_user_media_client_;
+
+  base::WeakPtrFactory<RenderFrameImpl> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(RenderFrameImpl);
 };
 
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 08016d7..e4ea63f 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -396,6 +396,9 @@
 
   AddFilter((new EmbeddedWorkerContextMessageFilter())->GetFilter());
 
+  gamepad_shared_memory_reader_.reset(new GamepadSharedMemoryReader());
+  AddObserver(gamepad_shared_memory_reader_.get());
+
   GetContentClient()->renderer()->RenderThreadStarted();
 
   InitSkiaEventTracer();
@@ -431,6 +434,14 @@
   is_gpu_rasterization_forced_ =
       command_line.HasSwitch(switches::kForceGpuRasterization);
 
+  if (command_line.HasSwitch(switches::kDisableDistanceFieldText)) {
+    is_distance_field_text_enabled_ = false;
+  } else if (command_line.HasSwitch(switches::kEnableDistanceFieldText)) {
+    is_distance_field_text_enabled_ = true;
+  } else {
+    is_distance_field_text_enabled_ = false;
+  }
+
   is_low_res_tiling_enabled_ = true;
   if (command_line.HasSwitch(switches::kDisableLowResTiling) &&
       !command_line.HasSwitch(switches::kEnableLowResTiling)) {
@@ -1135,7 +1146,8 @@
 scoped_ptr<gfx::GpuMemoryBuffer> RenderThreadImpl::AllocateGpuMemoryBuffer(
     size_t width,
     size_t height,
-    unsigned internalformat) {
+    unsigned internalformat,
+    unsigned usage) {
   DCHECK(allocate_gpu_memory_buffer_thread_checker_.CalledOnValidThread());
 
   if (!GpuMemoryBufferImpl::IsFormatValid(internalformat))
@@ -1143,11 +1155,8 @@
 
   gfx::GpuMemoryBufferHandle handle;
   bool success;
-  IPC::Message* message =
-      new ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer(width,
-                                                          height,
-                                                          internalformat,
-                                                          &handle);
+  IPC::Message* message = new ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer(
+      width, height, internalformat, usage, &handle);
 
   // Allow calling this from the compositor thread.
   if (base::MessageLoop::current() == message_loop())
@@ -1158,10 +1167,9 @@
   if (!success)
     return scoped_ptr<gfx::GpuMemoryBuffer>();
 
-  return GpuMemoryBufferImpl::Create(
-      handle,
-      gfx::Size(width, height),
-      internalformat).PassAs<gfx::GpuMemoryBuffer>();
+  return GpuMemoryBufferImpl::CreateFromHandle(
+             handle, gfx::Size(width, height), internalformat)
+      .PassAs<gfx::GpuMemoryBuffer>();
 }
 
 void RenderThreadImpl::AcceptConnection(
@@ -1458,11 +1466,13 @@
 }
 
 void RenderThreadImpl::SampleGamepads(blink::WebGamepads* data) {
-  if (!gamepad_shared_memory_reader_)
-    gamepad_shared_memory_reader_.reset(new GamepadSharedMemoryReader);
   gamepad_shared_memory_reader_->SampleGamepads(*data);
 }
 
+void RenderThreadImpl::SetGamepadListener(blink::WebGamepadListener* listener) {
+  gamepad_shared_memory_reader_->SetGamepadListener(listener);
+}
+
 void RenderThreadImpl::WidgetCreated() {
   widget_count_++;
 }
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index 5695270..f221bd4 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -33,6 +33,7 @@
 
 namespace blink {
 class WebGamepads;
+class WebGamepadListener;
 class WebGraphicsContext3D;
 class WebMediaStreamCenter;
 class WebMediaStreamCenterClient;
@@ -216,6 +217,10 @@
 
   bool is_lcd_text_enabled() const { return is_lcd_text_enabled_; }
 
+  bool is_distance_field_text_enabled() const {
+    return is_distance_field_text_enabled_;
+  }
+
   bool is_zero_copy_enabled() const { return is_zero_copy_enabled_; }
 
   bool is_one_copy_enabled() const { return is_one_copy_enabled_; }
@@ -271,6 +276,10 @@
     return vc_manager_.get();
   }
 
+  GamepadSharedMemoryReader* gamepad_shared_memory_reader() const {
+    return gamepad_shared_memory_reader_.get();
+  }
+
   // Get the GPU channel. Returns NULL if the channel is not established or
   // has been lost.
   GpuChannelHost* GetGpuChannel();
@@ -368,6 +377,10 @@
   // Retrieve current gamepad data.
   void SampleGamepads(blink::WebGamepads* data);
 
+  // Set a listener for gamepad connected/disconnected events.
+  // A non-null listener must be set first before calling SampleGamepads.
+  void SetGamepadListener(blink::WebGamepadListener* listener);
+
   // Called by a RenderWidget when it is created or destroyed. This
   // allows the process to know when there are no visible widgets.
   void WidgetCreated();
@@ -400,7 +413,8 @@
   virtual scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer(
       size_t width,
       size_t height,
-      unsigned internalformat) OVERRIDE;
+      unsigned internalformat,
+      unsigned usage) OVERRIDE;
 
   // mojo::ShellClient implementation:
   virtual void AcceptConnection(
@@ -545,6 +559,7 @@
   bool is_impl_side_painting_enabled_;
   bool is_low_res_tiling_enabled_;
   bool is_lcd_text_enabled_;
+  bool is_distance_field_text_enabled_;
   bool is_zero_copy_enabled_;
   bool is_one_copy_enabled_;
 
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index f0a8802..b06151b 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -35,6 +35,7 @@
 #include "content/renderer/render_view_impl.h"
 #include "content/shell/browser/shell.h"
 #include "content/shell/browser/shell_browser_context.h"
+#include "content/test/frame_load_waiter.h"
 #include "content/test/mock_keyboard.h"
 #include "net/base/net_errors.h"
 #include "net/cert/cert_status_flags.h"
@@ -2014,7 +2015,8 @@
   nav_params.page_id = -1;
   nav_params.frame_to_navigate = "frame";
   frame()->OnNavigate(nav_params);
-  ProcessPendingMessages();
+  FrameLoadWaiter(
+      RenderFrame::FromWebFrame(frame()->GetWebFrame()->firstChild())).Wait();
 
   // Copy the document content to std::wstring and compare with the
   // expected result.
@@ -2164,7 +2166,8 @@
 
   // An error occurred.
   view()->main_render_frame()->didFailProvisionalLoad(web_frame, error);
-  ProcessPendingMessages();
+  // The error page itself is loaded asynchronously.
+  FrameLoadWaiter(frame()).Wait();
   const int kMaxOutputCharacters = 22;
   EXPECT_EQ("A suffusion of yellow.",
             base::UTF16ToASCII(web_frame->contentAsText(kMaxOutputCharacters)));
@@ -2249,7 +2252,7 @@
   EXPECT_EQ(0.1, progress_value.a);
   render_thread_->sink().ClearMessages();
 
-  ProcessPendingMessages();
+  FrameLoadWaiter(frame()).Wait();
 
   // The data url has loaded, so we should see a progress change to 1.0 (done)
   // and a stop notification.
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 306b8ce..17b69a0 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -85,20 +85,13 @@
 #include "content/renderer/idle_user_detector.h"
 #include "content/renderer/ime_event_guard.h"
 #include "content/renderer/input/input_handler_manager.h"
-#include "content/renderer/input_tag_speech_dispatcher.h"
 #include "content/renderer/internal_document_state_data.h"
 #include "content/renderer/load_progress_tracker.h"
 #include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/audio_renderer_mixer_manager.h"
 #include "content/renderer/media/media_stream_dependency_factory.h"
 #include "content/renderer/media/media_stream_dispatcher.h"
-#include "content/renderer/media/media_stream_impl.h"
 #include "content/renderer/media/midi_dispatcher.h"
-#include "content/renderer/media/render_media_log.h"
 #include "content/renderer/media/video_capture_impl_manager.h"
-#include "content/renderer/media/webmediaplayer_impl.h"
-#include "content/renderer/media/webmediaplayer_ms.h"
-#include "content/renderer/media/webmediaplayer_params.h"
 #include "content/renderer/memory_benchmarking_extension.h"
 #include "content/renderer/mhtml_generator.h"
 #include "content/renderer/push_messaging_dispatcher.h"
@@ -122,7 +115,6 @@
 #include "content/renderer/web_ui_mojo.h"
 #include "content/renderer/websharedworker_proxy.h"
 #include "media/audio/audio_output_device.h"
-#include "media/base/audio_renderer_mixer_input.h"
 #include "media/base/filter_collection.h"
 #include "media/base/media_switches.h"
 #include "media/filters/audio_renderer_impl.h"
@@ -185,7 +177,6 @@
 #include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
 #include "third_party/WebKit/public/web/WebSettings.h"
 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
-#include "third_party/WebKit/public/web/WebUserMediaClient.h"
 #include "third_party/WebKit/public/web/WebView.h"
 #include "third_party/WebKit/public/web/WebWindowFeatures.h"
 #include "third_party/WebKit/public/web/default/WebRenderTheme.h"
@@ -204,15 +195,11 @@
 #if defined(OS_ANDROID)
 #include <cpu-features.h>
 
-#include "content/common/gpu/client/context_provider_command_buffer.h"
 #include "content/renderer/android/address_detector.h"
 #include "content/renderer/android/content_detector.h"
 #include "content/renderer/android/email_detector.h"
 #include "content/renderer/android/phone_number_detector.h"
-#include "content/renderer/android/synchronous_compositor_factory.h"
 #include "content/renderer/media/android/renderer_media_player_manager.h"
-#include "content/renderer/media/android/stream_texture_factory_impl.h"
-#include "content/renderer/media/android/webmediaplayer_android.h"
 #include "net/android/network_library.h"
 #include "skia/ext/platform_canvas.h"
 #include "third_party/WebKit/public/platform/WebFloatPoint.h"
@@ -271,9 +258,7 @@
 using blink::WebInputElement;
 using blink::WebInputEvent;
 using blink::WebLocalFrame;
-using blink::WebMediaPlayer;
 using blink::WebMediaPlayerAction;
-using blink::WebMediaPlayerClient;
 using blink::WebMouseEvent;
 using blink::WebNavigationPolicy;
 using blink::WebNavigationType;
@@ -488,11 +473,6 @@
   return DeviceScaleEnsuresTextQuality(device_scale_factor);
 }
 
-static bool ShouldUseCompositingForGpuRasterizationHint() {
-  return RenderThreadImpl::current() &&
-         RenderThreadImpl::current()->is_gpu_rasterization_enabled();
-}
-
 static FaviconURL::IconType ToFaviconType(blink::WebIconURL::Type type) {
   switch (type) {
     case blink::WebIconURL::TypeFavicon:
@@ -671,19 +651,15 @@
       has_scrolled_focused_editable_node_into_rect_(false),
       push_messaging_dispatcher_(NULL),
       geolocation_dispatcher_(NULL),
-      input_tag_speech_dispatcher_(NULL),
       speech_recognition_dispatcher_(NULL),
       media_stream_dispatcher_(NULL),
       browser_plugin_manager_(NULL),
-      media_stream_client_(NULL),
-      web_user_media_client_(NULL),
       midi_dispatcher_(NULL),
       devtools_agent_(NULL),
       accessibility_mode_(AccessibilityModeOff),
       renderer_accessibility_(NULL),
       mouse_lock_dispatcher_(NULL),
 #if defined(OS_ANDROID)
-      body_background_color_(SK_ColorWHITE),
       expected_content_intent_id_(0),
       media_player_manager_(NULL),
 #endif
@@ -770,9 +746,6 @@
       ShouldUseAcceleratedFixedRootBackground(device_scale_factor_));
   webview()->settings()->setCompositedScrollingForFramesEnabled(
       ShouldUseCompositedScrollingForFrames(device_scale_factor_));
-  webview()->settings()
-      ->setAcceleratedCompositingForGpuRasterizationHintEnabled(
-          ShouldUseCompositingForGpuRasterizationHint());
 
   ApplyWebPreferences(webkit_preferences_, webview());
 
@@ -1094,6 +1067,7 @@
     IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
     IPC_MESSAGE_HANDLER(ViewMsg_SetName, OnSetName)
     IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt)
+    IPC_MESSAGE_HANDLER(ViewMsg_SaveImageAt, OnSaveImageAt)
     IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind)
     IPC_MESSAGE_HANDLER(ViewMsg_StopFinding, OnStopFinding)
     IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom)
@@ -1133,8 +1107,6 @@
                         OnDisableScrollbarsForSmallWindows)
     IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
     IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt)
-    IPC_MESSAGE_HANDLER(ViewMsg_OrientationChangeEvent,
-                        OnOrientationChangeEvent)
     IPC_MESSAGE_HANDLER(ViewMsg_PluginActionAt, OnPluginActionAt)
     IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
     IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
@@ -1239,6 +1211,10 @@
   webview()->copyImageAt(WebPoint(x, y));
 }
 
+void RenderViewImpl::OnSaveImageAt(int x, int y) {
+  webview()->saveImageAt(WebPoint(x, y));
+}
+
 void RenderViewImpl::OnUpdateTargetURLAck() {
   // Check if there is a targeturl waiting to be sent.
   if (target_url_status_ == TARGET_PENDING) {
@@ -2017,44 +1993,6 @@
 
 // blink::WebFrameClient -----------------------------------------------------
 
-blink::WebMediaPlayer* RenderViewImpl::CreateMediaPlayer(
-    RenderFrame* render_frame,
-    blink::WebLocalFrame* frame,
-    const blink::WebURL& url,
-    blink::WebMediaPlayerClient* client) {
-  FOR_EACH_OBSERVER(
-      RenderViewObserver, observers_, WillCreateMediaPlayer(frame, client));
-
-  WebMediaPlayer* player = CreateWebMediaPlayerForMediaStream(frame, url,
-                                                              client);
-  if (player)
-    return player;
-
-#if defined(OS_ANDROID)
-  return CreateAndroidWebMediaPlayer(frame, url, client);
-#else
-  WebMediaPlayerParams params(
-      base::Bind(&ContentRendererClient::DeferMediaLoad,
-                 base::Unretained(GetContentClient()->renderer()),
-                 static_cast<RenderFrame*>(render_frame)),
-      RenderThreadImpl::current()->GetAudioRendererMixerManager()->CreateInput(
-          routing_id_, render_frame->GetRoutingID()));
-  return new WebMediaPlayerImpl(frame, client, AsWeakPtr(), params);
-#endif  // defined(OS_ANDROID)
-}
-
-void RenderViewImpl::didDisownOpener(blink::WebLocalFrame* frame) {
-  // We only need to notify the browser if the active, top-level frame clears
-  // its opener.  We can ignore cases where a swapped out frame clears its
-  // opener after hearing about it from the browser, and the browser does not
-  // (yet) care about subframe openers.
-  if (is_swapped_out_ || frame->parent())
-    return;
-
-  // Notify WebContents and all its swapped out RenderViews.
-  Send(new ViewHostMsg_DidDisownOpener(routing_id_));
-}
-
 void RenderViewImpl::Repaint(const gfx::Size& size) {
   OnRepaint(size);
 }
@@ -2335,13 +2273,6 @@
   SendUpdateFaviconURL(urls);
 }
 
-void RenderViewImpl::didHandleOnloadEvents(WebLocalFrame* frame) {
-  if (webview()->mainFrame() == frame) {
-    Send(new ViewHostMsg_DocumentOnLoadCompletedInMainFrame(routing_id_,
-                                                            page_id_));
-  }
-}
-
 void RenderViewImpl::didUpdateCurrentHistoryItem(WebLocalFrame* frame) {
   StartNavStateSyncTimerIfNecessary();
 }
@@ -2375,34 +2306,6 @@
   return browser_plugin_manager_.get();
 }
 
-bool RenderViewImpl::InitializeMediaStreamClient() {
-  if (media_stream_client_)
-    return true;
-
-  if (!RenderThreadImpl::current())  // Will be NULL during unit tests.
-    return false;
-
-#if defined(OS_ANDROID)
-  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebRTC))
-    return false;
-#endif
-
-#if defined(ENABLE_WEBRTC)
-  if (!media_stream_dispatcher_)
-    media_stream_dispatcher_ = new MediaStreamDispatcher(this);
-
-  MediaStreamImpl* media_stream_impl = new MediaStreamImpl(
-      this,
-      media_stream_dispatcher_,
-      RenderThreadImpl::current()->GetMediaStreamDependencyFactory());
-  media_stream_client_ = media_stream_impl;
-  web_user_media_client_ = media_stream_impl;
-  return true;
-#else
-  return false;
-#endif
-}
-
 void RenderViewImpl::UpdateScrollState(WebFrame* frame) {
   WebSize offset = frame->scrollOffset();
   WebSize minimum_offset = frame->minimumScrollOffset();
@@ -2433,31 +2336,6 @@
       RenderViewObserver, observers_, DidChangeScrollOffset(frame));
 }
 
-void RenderViewImpl::didFirstVisuallyNonEmptyLayout(WebLocalFrame* frame) {
-  if (frame != webview()->mainFrame())
-    return;
-
-  InternalDocumentStateData* data =
-      InternalDocumentStateData::FromDataSource(frame->dataSource());
-  data->set_did_first_visually_non_empty_layout(true);
-
-#if defined(OS_ANDROID)
-  // Update body background color if necessary.
-  SkColor bg_color = webwidget_->backgroundColor();
-
-  // If not initialized, default to white. Note that 0 is different from black
-  // as black still has alpha 0xFF.
-  if (!bg_color)
-    bg_color = SK_ColorWHITE;
-
-  if (bg_color != body_background_color_) {
-    body_background_color_ = bg_color;
-    Send(new ViewHostMsg_DidChangeBodyBackgroundColor(
-        GetRoutingID(), bg_color));
-  }
-#endif
-}
-
 void RenderViewImpl::SendFindReply(int request_id,
                                    int match_count,
                                    int ordinal,
@@ -2471,48 +2349,6 @@
                                   final_status_update));
 }
 
-bool RenderViewImpl::willCheckAndDispatchMessageEvent(
-    blink::WebLocalFrame* sourceFrame,
-    blink::WebFrame* targetFrame,
-    blink::WebSecurityOrigin target_origin,
-    blink::WebDOMMessageEvent event) {
-  if (!is_swapped_out_)
-    return false;
-
-  ViewMsg_PostMessage_Params params;
-  params.data = event.data().toString();
-  params.source_origin = event.origin();
-  if (!target_origin.isNull())
-    params.target_origin = target_origin.toString();
-
-  blink::WebMessagePortChannelArray channels = event.releaseChannels();
-  if (!channels.isEmpty()) {
-    std::vector<int> message_port_ids(channels.size());
-     // Extract the port IDs from the channel array.
-     for (size_t i = 0; i < channels.size(); ++i) {
-       WebMessagePortChannelImpl* webchannel =
-           static_cast<WebMessagePortChannelImpl*>(channels[i]);
-       message_port_ids[i] = webchannel->message_port_id();
-       webchannel->QueueMessages();
-       DCHECK_NE(message_port_ids[i], MSG_ROUTING_NONE);
-     }
-     params.message_port_ids = message_port_ids;
-  }
-
-  // Include the routing ID for the source frame (if one exists), which the
-  // browser process will translate into the routing ID for the equivalent
-  // frame in the target process.
-  params.source_routing_id = MSG_ROUTING_NONE;
-  if (sourceFrame) {
-    RenderViewImpl* source_view = FromWebView(sourceFrame->view());
-    if (source_view)
-      params.source_routing_id = source_view->routing_id();
-  }
-
-  Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params));
-  return true;
-}
-
 blink::WebString RenderViewImpl::acceptLanguages() {
   return WebString::fromUTF8(renderer_preferences_.accept_languages);
 }
@@ -2632,22 +2468,6 @@
   main_render_frame_->didStopLoading();
 }
 
-void RenderViewImpl::DidPlay(blink::WebMediaPlayer* player) {
-  Send(new ViewHostMsg_MediaPlayingNotification(routing_id_,
-                                                reinterpret_cast<int64>(player),
-                                                player->hasVideo(),
-                                                player->hasAudio()));
-}
-
-void RenderViewImpl::DidPause(blink::WebMediaPlayer* player) {
-  Send(new ViewHostMsg_MediaPausedNotification(
-      routing_id_, reinterpret_cast<int64>(player)));
-}
-
-void RenderViewImpl::PlayerGone(blink::WebMediaPlayer* player) {
-  DidPause(player);
-}
-
 void RenderViewImpl::SyncNavigationState() {
   if (!webview())
     return;
@@ -3184,12 +3004,13 @@
     webview()->performMediaPlayerAction(action, location);
 }
 
-void RenderViewImpl::OnOrientationChangeEvent(int orientation) {
-  // Screen has rotated. 0 = default (portrait), 90 = one turn right, and so on.
+void RenderViewImpl::OnOrientationChange() {
+  // TODO(mlamouri): consumers of that event should be using DisplayObserver.
   FOR_EACH_OBSERVER(RenderViewObserver,
                     observers_,
-                    OrientationChangeEvent(orientation));
-  webview()->mainFrame()->sendOrientationChangeEvent(orientation);
+                    OrientationChangeEvent());
+
+  webview()->mainFrame()->sendOrientationChangeEvent();
 }
 
 void RenderViewImpl::OnPluginActionAt(const gfx::Point& location,
@@ -3383,8 +3204,7 @@
     if (data->did_first_visually_non_empty_layout() &&
         !data->did_first_visually_non_empty_paint()) {
       data->set_did_first_visually_non_empty_paint(true);
-      Send(new ViewHostMsg_DidFirstVisuallyNonEmptyPaint(routing_id_,
-                                                         page_id_));
+      Send(new ViewHostMsg_DidFirstVisuallyNonEmptyPaint(routing_id_));
     }
 
     // TODO(jar): The following code should all be inside a method, probably in
@@ -3900,16 +3720,6 @@
   return geolocation_dispatcher_;
 }
 
-blink::WebSpeechInputController* RenderViewImpl::speechInputController(
-    blink::WebSpeechInputListener* listener) {
-#if defined(ENABLE_INPUT_SPEECH)
-  if (!input_tag_speech_dispatcher_)
-    input_tag_speech_dispatcher_ =
-        new InputTagSpeechDispatcher(this, listener);
-#endif
-  return input_tag_speech_dispatcher_;
-}
-
 blink::WebSpeechRecognizer* RenderViewImpl::speechRecognizer() {
   if (!speech_recognition_dispatcher_)
     speech_recognition_dispatcher_ = new SpeechRecognitionDispatcher(this);
@@ -3934,15 +3744,19 @@
 
 void RenderViewImpl::zoomLevelChanged() {
   bool remember = !webview()->mainFrame()->document().isPluginDocument();
-  float zoom_level = webview()->zoomLevel();
+  double zoom_level = webview()->zoomLevel();
 
   FOR_EACH_OBSERVER(RenderViewObserver, observers_, ZoomLevelChanged());
 
-  // Tell the browser which url got zoomed so it can update the menu and the
-  // saved values if necessary
-  Send(new ViewHostMsg_DidZoomURL(
-      routing_id_, zoom_level, remember,
-      GURL(webview()->mainFrame()->document().url())));
+  // Do not send empty URLs to the browser when we are just setting the default
+  // zoom level (from RendererPreferences) before the first navigation.
+  if (!webview()->mainFrame()->document().url().isEmpty()) {
+    // Tell the browser which url got zoomed so it can update the menu and the
+    // saved values if necessary
+    Send(new ViewHostMsg_DidZoomURL(
+        routing_id_, zoom_level, remember,
+        GURL(webview()->mainFrame()->document().url())));
+  }
 }
 
 double RenderViewImpl::zoomLevelToZoomFactor(double zoom_level) const {
@@ -3983,14 +3797,6 @@
   return current_state;
 }
 
-blink::WebUserMediaClient* RenderViewImpl::userMediaClient() {
-  // This can happen in tests, in which case it's OK to return NULL.
-  if (!InitializeMediaStreamClient())
-    return NULL;
-
-  return web_user_media_client_;
-}
-
 blink::WebMIDIClient* RenderViewImpl::webMIDIClient() {
   if (!midi_dispatcher_)
     midi_dispatcher_ = new MidiDispatcher(this);
@@ -4010,28 +3816,6 @@
       DraggableRegionsChanged(webview()->mainFrame()));
 }
 
-WebMediaPlayer* RenderViewImpl::CreateWebMediaPlayerForMediaStream(
-    WebFrame* frame,
-    const blink::WebURL& url,
-    WebMediaPlayerClient* client) {
-#if defined(ENABLE_WEBRTC)
-  if (!InitializeMediaStreamClient()) {
-    LOG(ERROR) << "Failed to initialize MediaStreamClient";
-    return NULL;
-  }
-  if (media_stream_client_->IsMediaStream(url)) {
-#if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
-    bool found_neon =
-        (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
-    UMA_HISTOGRAM_BOOLEAN("Platform.WebRtcNEONFound", found_neon);
-#endif  // defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
-    return new WebMediaPlayerMS(frame, client, AsWeakPtr(),
-                                media_stream_client_, new RenderMediaLog());
-  }
-#endif  // defined(ENABLE_WEBRTC)
-  return NULL;
-}
-
 #if defined(OS_ANDROID)
 WebContentDetectionResult RenderViewImpl::detectContentAround(
     const WebHitTestResult& touch_hit) {
@@ -4095,46 +3879,6 @@
   date_time_picker_client_.reset(NULL);
 }
 
-WebMediaPlayer* RenderViewImpl::CreateAndroidWebMediaPlayer(
-      WebFrame* frame,
-      const blink::WebURL& url,
-      WebMediaPlayerClient* client) {
-  GpuChannelHost* gpu_channel_host =
-      RenderThreadImpl::current()->EstablishGpuChannelSync(
-          CAUSE_FOR_GPU_LAUNCH_VIDEODECODEACCELERATOR_INITIALIZE);
-  if (!gpu_channel_host) {
-    LOG(ERROR) << "Failed to establish GPU channel for media player";
-    return NULL;
-  }
-
-  scoped_refptr<StreamTextureFactory> stream_texture_factory;
-  if (UsingSynchronousRendererCompositor()) {
-    SynchronousCompositorFactory* factory =
-        SynchronousCompositorFactory::GetInstance();
-    stream_texture_factory = factory->CreateStreamTextureFactory(routing_id_);
-  } else {
-    scoped_refptr<webkit::gpu::ContextProviderWebContext> context_provider =
-        RenderThreadImpl::current()->SharedMainThreadContextProvider();
-
-    if (!context_provider.get()) {
-      LOG(ERROR) << "Failed to get context3d for media player";
-      return NULL;
-    }
-
-    stream_texture_factory = StreamTextureFactoryImpl::Create(
-        context_provider, gpu_channel_host, routing_id_);
-  }
-
-  return new WebMediaPlayerAndroid(
-      frame,
-      client,
-      AsWeakPtr(),
-      media_player_manager_,
-      stream_texture_factory,
-      RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy(),
-      new RenderMediaLog());
-}
-
 #endif  // defined(OS_ANDROID)
 
 #if defined(OS_MACOSX)
@@ -4247,10 +3991,10 @@
         canvas.translate(-zoom_rect.x() * device_scale_factor_,
                          -zoom_rect.y() * device_scale_factor_);
 
-        webwidget_->paint(
-            &canvas,
-            zoom_rect,
-            WebWidget::ForceSoftwareRenderingAndIgnoreGPUResidentContent);
+        DCHECK(webwidget_->isAcceleratedCompositingActive());
+        // TODO(aelias): The disambiguation popup should be composited so we
+        // don't have to call this method.
+        webwidget_->paintCompositedDeprecated(&canvas, zoom_rect);
       }
 
       gfx::Rect physical_window_zoom_rect = gfx::ToEnclosingRect(
@@ -4304,6 +4048,11 @@
   OnResize(params);
 }
 
+void RenderViewImpl::SetDeviceColorProfileForTesting(
+    const std::vector<char>& color_profile) {
+  // TODO(noel): Add RenderViewImpl::SetDeviceColorProfile(color_profile).
+}
+
 void RenderViewImpl::ForceResizeForTesting(const gfx::Size& new_size) {
   gfx::Rect new_position(rootWindowRect().x,
                          rootWindowRect().y,
@@ -4325,13 +4074,6 @@
   OnDisableAutoResize(new_size);
 }
 
-void RenderViewImpl::SetMediaStreamClientForTesting(
-    MediaStreamClient* media_stream_client) {
-  DCHECK(!media_stream_client_);
-  DCHECK(!web_user_media_client_);
-  media_stream_client_ = media_stream_client;
-}
-
 void RenderViewImpl::OnReleaseDisambiguationPopupBitmap(
     const cc::SharedBitmapId& id) {
   BitmapMap::iterator it = disambiguation_bitmaps_.find(id);
@@ -4347,7 +4089,7 @@
 
 void RenderViewImpl::SendUpdateFaviconURL(const std::vector<FaviconURL>& urls) {
   if (!urls.empty())
-    Send(new ViewHostMsg_UpdateFaviconURL(routing_id_, page_id_, urls));
+    Send(new ViewHostMsg_UpdateFaviconURL(routing_id_, urls));
 }
 
 void RenderViewImpl::DidStopLoadingIcons() {
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index f1abfbd..8ef97ae 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -35,7 +35,6 @@
 #include "content/public/common/stop_find_action.h"
 #include "content/public/common/top_controls_state.h"
 #include "content/public/renderer/render_view.h"
-#include "content/renderer/media/webmediaplayer_delegate.h"
 #include "content/renderer/mouse_lock_dispatcher.h"
 #include "content/renderer/render_frame_impl.h"
 #include "content/renderer/render_widget.h"
@@ -100,19 +99,14 @@
 class WebImage;
 class WebPeerConnection00Handler;
 class WebPeerConnection00HandlerClient;
-class WebMediaPlayer;
-class WebMediaPlayerClient;
 class WebMouseEvent;
 class WebPeerConnectionHandler;
 class WebPeerConnectionHandlerClient;
 class WebSocketStreamHandle;
-class WebSpeechInputController;
-class WebSpeechInputListener;
 class WebSpeechRecognizer;
 class WebStorageNamespace;
 class WebTouchEvent;
 class WebURLRequest;
-class WebUserMediaClient;
 struct WebActiveWheelFlingParameters;
 struct WebDateTimeChooserParams;
 struct WebFileChooserParams;
@@ -142,10 +136,8 @@
 class HistoryController;
 class HistoryEntry;
 class ImageResourceFetcher;
-class InputTagSpeechDispatcher;
 class LoadProgressTracker;
 class MidiDispatcher;
-class MediaStreamClient;
 class MediaStreamDispatcher;
 class MouseLockDispatcher;
 class NavigationState;
@@ -177,7 +169,6 @@
       NON_EXPORTED_BASE(public blink::WebViewClient),
       NON_EXPORTED_BASE(public blink::WebPageSerializerClient),
       public RenderView,
-      NON_EXPORTED_BASE(public WebMediaPlayerDelegate),
       public base::SupportsWeakPtr<RenderViewImpl> {
  public:
   // Creates a new RenderView. |opener_id| is the routing ID of the RenderView
@@ -231,6 +222,7 @@
 
   RenderFrameImpl* main_render_frame() { return main_render_frame_.get(); }
 
+  // TODO(jam): move to RenderFrameImpl
   MediaStreamDispatcher* media_stream_dispatcher() {
     return media_stream_dispatcher_;
   }
@@ -355,12 +347,6 @@
   // periodic timer so we don't send too many messages.
   void SyncNavigationState();
 
-  // Temporary call until all this media code moves to RenderFrame.
-  // TODO(jam): remove me
-  blink::WebMediaPlayer* CreateMediaPlayer(RenderFrame* render_frame,
-                                           blink::WebLocalFrame* frame,
-                                           const blink::WebURL& url,
-                                           blink::WebMediaPlayerClient* client);
   // Returns the length of the session history of this RenderView. Note that
   // this only coincides with the actual length of the session history if this
   // RenderView is the currently active RenderView of a WebContents.
@@ -374,6 +360,9 @@
   // Change the device scale factor and force the compositor to resize.
   void SetDeviceScaleFactorForTesting(float factor);
 
+  // Change the device ICC color profile while running a layout test.
+  void SetDeviceColorProfileForTesting(const std::vector<char>& color_profile);
+
   // Used to force the size of a window when running layout tests.
   void ForceResizeForTesting(const gfx::Size& new_size);
 
@@ -384,10 +373,6 @@
                                   const gfx::Size& max_size);
   void DisableAutoResizeForTesting(const gfx::Size& new_size);
 
-  // Overrides the MediaStreamClient used when creating MediaStream players.
-  // Must be called before any players are created.
-  void SetMediaStreamClientForTesting(MediaStreamClient* media_stream_client);
-
   // IPC::Listener implementation ----------------------------------------------
 
   virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
@@ -467,8 +452,6 @@
   virtual void didUpdateInspectorSetting(const blink::WebString& key,
                                          const blink::WebString& value);
   virtual blink::WebGeolocationClient* geolocationClient();
-  virtual blink::WebSpeechInputController* speechInputController(
-      blink::WebSpeechInputListener* listener);
   virtual blink::WebSpeechRecognizer* speechRecognizer();
   virtual void zoomLimitsChanged(double minimum_level, double maximum_level);
   virtual void zoomLevelChanged();
@@ -479,7 +462,6 @@
                                        const blink::WebURL& url,
                                        const blink::WebString& title);
   virtual blink::WebPageVisibilityState visibilityState() const;
-  virtual blink::WebUserMediaClient* userMediaClient();
   virtual blink::WebMIDIClient* webMIDIClient();
   virtual blink::WebPushClient* webPushClient();
   virtual void draggableRegionsChanged();
@@ -535,12 +517,6 @@
                                       bool animate) OVERRIDE;
 #endif
 
-  // WebMediaPlayerDelegate implementation -----------------------
-
-  virtual void DidPlay(blink::WebMediaPlayer* player) OVERRIDE;
-  virtual void DidPause(blink::WebMediaPlayer* player) OVERRIDE;
-  virtual void PlayerGone(blink::WebMediaPlayer* player) OVERRIDE;
-
   // Please do not add your stuff randomly to the end here. If there is an
   // appropriate section, add it there. If not, there are some random functions
   // nearer to the top you can add it to.
@@ -579,6 +555,7 @@
                                        const gfx::Range& replacement_range,
                                        bool keep_selection) OVERRIDE;
   virtual void SetDeviceScaleFactor(float device_scale_factor) OVERRIDE;
+  virtual void OnOrientationChange() OVERRIDE;
   virtual ui::TextInputType GetTextInputType() OVERRIDE;
   virtual void GetSelectionBounds(gfx::Rect* start, gfx::Rect* end) OVERRIDE;
 #if defined(OS_MACOSX) || defined(USE_AURA)
@@ -678,7 +655,6 @@
   // still live here and are called from RenderFrameImpl. These implementations
   // are to be moved to RenderFrameImpl <http://crbug.com/361761>.
 
-  void didDisownOpener(blink::WebLocalFrame* frame);
   void didCreateDataSource(blink::WebLocalFrame* frame,
                            blink::WebDataSource* datasource);
   void didClearWindowObject(blink::WebLocalFrame* frame, int world_id);
@@ -686,15 +662,8 @@
                        const blink::WebString& title,
                        blink::WebTextDirection direction);
   void didChangeIcon(blink::WebLocalFrame*, blink::WebIconURL::Type);
-  void didHandleOnloadEvents(blink::WebLocalFrame* frame);
   void didUpdateCurrentHistoryItem(blink::WebLocalFrame* frame);
   void didChangeScrollOffset(blink::WebLocalFrame* frame);
-  void didFirstVisuallyNonEmptyLayout(blink::WebLocalFrame*);
-  bool willCheckAndDispatchMessageEvent(
-      blink::WebLocalFrame* sourceFrame,
-      blink::WebFrame* targetFrame,
-      blink::WebSecurityOrigin targetOrigin,
-      blink::WebDOMMessageEvent event);
 
   static bool IsReload(const FrameMsg_Navigate_Params& params);
 
@@ -747,6 +716,7 @@
   void OnClosePage();
   void OnShowContextMenu(const gfx::Point& location);
   void OnCopyImageAt(int x, int y);
+  void OnSaveImageAt(int x, int y);
   void OnSetName(const std::string& name);
   void OnDeterminePageLanguage();
   void OnDisableScrollbarsForSmallWindows(
@@ -785,7 +755,6 @@
       const base::FilePath& local_directory_name);
   void OnMediaPlayerActionAt(const gfx::Point& location,
                              const blink::WebMediaPlayerAction& action);
-  void OnOrientationChangeEvent(int orientation);
   void OnPluginActionAt(const gfx::Point& location,
                         const blink::WebPluginAction& action);
   void OnMoveOrResizeStarted();
@@ -843,11 +812,6 @@
   // Check whether the preferred size has changed.
   void CheckPreferredSize();
 
-  // Initializes |media_stream_client_|, returning true if successful. Returns
-  // false if it wasn't possible to create a MediaStreamClient (e.g., WebRTC is
-  // disabled) in which case |media_stream_client_| is NULL.
-  bool InitializeMediaStreamClient();
-
   // This callback is triggered when DownloadFavicon completes, either
   // succesfully or with a failure. See DownloadFavicon for more
   // details.
@@ -897,18 +861,8 @@
 #if defined(OS_ANDROID)
   // Launch an Android content intent with the given URL.
   void LaunchAndroidContentIntent(const GURL& intent_url, size_t request_id);
-
-  blink::WebMediaPlayer* CreateAndroidWebMediaPlayer(
-      blink::WebFrame* frame,
-      const blink::WebURL& url,
-      blink::WebMediaPlayerClient* client);
 #endif
 
-  blink::WebMediaPlayer* CreateWebMediaPlayerForMediaStream(
-      blink::WebFrame* frame,
-      const blink::WebURL& url,
-      blink::WebMediaPlayerClient* client);
-
   // Sends a reply to the current find operation handling if it was a
   // synchronous find request.
   void SendFindReply(int request_id,
@@ -1140,9 +1094,6 @@
   // The geolocation dispatcher attached to this view, lazily initialized.
   GeolocationDispatcher* geolocation_dispatcher_;
 
-  // The speech dispatcher attached to this view, lazily initialized.
-  InputTagSpeechDispatcher* input_tag_speech_dispatcher_;
-
   // The speech recognition dispatcher attached to this view, lazily
   // initialized.
   SpeechRecognitionDispatcher* speech_recognition_dispatcher_;
@@ -1156,10 +1107,6 @@
   // BrowserPluginManager attached to this view; lazily initialized.
   scoped_refptr<BrowserPluginManager> browser_plugin_manager_;
 
-  // MediaStreamClient attached to this view; lazily initialized.
-  MediaStreamClient* media_stream_client_;
-  blink::WebUserMediaClient* web_user_media_client_;
-
   // MidiClient attached to this view; lazily initialized.
   MidiDispatcher* midi_dispatcher_;
 
@@ -1180,11 +1127,6 @@
 #if defined(OS_ANDROID)
   // Android Specific ---------------------------------------------------------
 
-  // The background color of the document body element. This is used as the
-  // default background color for filling the screen areas for which we don't
-  // have the actual content.
-  SkColor body_background_color_;
-
   // Expected id of the next content intent launched. Used to prevent scheduled
   // intents to be launched if aborted.
   size_t expected_content_intent_id_;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 5b4a19d..6f3af32 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -254,8 +254,11 @@
     const gfx::Size& visible_viewport_size,
     gfx::Rect resizer_rect,
     bool is_fullscreen) {
-  applied_widget_rect_.set_size(params_.viewSize.isEmpty() ?
-      original_size_ : gfx::Size(params_.viewSize));
+  applied_widget_rect_.set_size(gfx::Size(params_.viewSize));
+  if (!applied_widget_rect_.width())
+    applied_widget_rect_.set_width(original_size_.width());
+  if (!applied_widget_rect_.height())
+    applied_widget_rect_.set_height(original_size_.height());
 
   if (params_.fitToView) {
     DCHECK(!original_size_.IsEmpty());
@@ -383,7 +386,6 @@
       pending_window_rect_count_(0),
       suppress_next_char_events_(false),
       is_accelerated_compositing_active_(false),
-      was_accelerated_compositing_ever_active_(false),
       animation_update_pending_(false),
       invalidation_task_posted_(false),
       screen_info_(screen_info),
@@ -393,6 +395,7 @@
 #if defined(OS_ANDROID)
       text_field_is_dirty_(false),
       outstanding_ime_acks_(0),
+      body_background_color_(SK_ColorWHITE),
 #endif
 #if defined(OS_MACOSX)
       cached_has_main_frame_horizontal_scrollbar_(false),
@@ -499,7 +502,6 @@
   }
   if (compositor_)
     StartCompositor();
-  DoDeferredUpdate();
 
   Send(new ViewHostMsg_RenderViewReady(routing_id_));
 }
@@ -750,11 +752,17 @@
     return;
   }
 
+  bool orientation_changed =
+      screen_info_.orientationAngle != params.screen_info.orientationAngle;
+
   screen_info_ = params.screen_info;
   SetDeviceScaleFactor(screen_info_.deviceScaleFactor);
   Resize(params.new_size, params.physical_backing_size,
          params.overdraw_bottom_height, params.visible_viewport_size,
          params.resizer_rect, params.is_fullscreen, SEND_RESIZE_ACK);
+
+  if (orientation_changed)
+    OnOrientationChange();
 }
 
 void RenderWidget::OnChangeResizeRect(const gfx::Rect& resizer_rect) {
@@ -1059,6 +1067,8 @@
           kInputHandlingTimeThrottlingThresholdMicroseconds;
   }
 
+  TRACE_EVENT_SYNTHETIC_DELAY_END("blink.HandleInputEvent");
+
   if (!WebInputEventTraits::IgnoresAckDisposition(*input_event)) {
     scoped_ptr<IPC::Message> response(
         new InputHostMsg_HandleInputEvent_ACK(routing_id_,
@@ -1099,7 +1109,6 @@
     UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_IME);
 #endif
 
-  TRACE_EVENT_SYNTHETIC_DELAY_END("blink.HandleInputEvent");
   handling_input_event_ = false;
 
   if (!prevent_default) {
@@ -1141,13 +1150,13 @@
     TRACE_EVENT0("renderer", "EarlyOut_NoAnimationUpdatePending");
     return;
   }
-  DoDeferredUpdateAndSendInputAck();
+  FlushPendingInputEventAck();
 }
 
 void RenderWidget::InvalidationCallback() {
   TRACE_EVENT0("renderer", "RenderWidget::InvalidationCallback");
   invalidation_task_posted_ = false;
-  DoDeferredUpdateAndSendInputAck();
+  FlushPendingInputEventAck();
 }
 
 void RenderWidget::FlushPendingInputEventAck() {
@@ -1156,15 +1165,6 @@
   total_input_handling_time_this_frame_ = base::TimeDelta();
 }
 
-void RenderWidget::DoDeferredUpdateAndSendInputAck() {
-  DoDeferredUpdate();
-  FlushPendingInputEventAck();
-}
-
-// TODO(danakj): Remove this when everything is ForceCompositingMode.
-void RenderWidget::DoDeferredUpdate() {
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // WebWidgetClient
 
@@ -1278,11 +1278,7 @@
   is_accelerated_compositing_active_ = true;
   Send(new ViewHostMsg_DidActivateAcceleratedCompositing(
       routing_id_, is_accelerated_compositing_active_));
-
-  if (!was_accelerated_compositing_ever_active_) {
-    was_accelerated_compositing_ever_active_ = true;
-    webwidget_->enterForceCompositingMode(true);
-  }
+  webwidget_->enterForceCompositingMode(true);
 }
 
 void RenderWidget::didDeactivateCompositor() {
@@ -1291,13 +1287,6 @@
   is_accelerated_compositing_active_ = false;
   Send(new ViewHostMsg_DidActivateAcceleratedCompositing(
       routing_id_, is_accelerated_compositing_active_));
-
-  // In single-threaded mode, we exit force compositing mode and re-enter in
-  // DoDeferredUpdate() if appropriate. In threaded compositing mode,
-  // DoDeferredUpdate() is bypassed and WebKit is responsible for exiting and
-  // entering force compositing mode at the appropriate times.
-  if (!is_threaded_compositing_enabled_ && !ForceCompositingModeEnabled())
-    webwidget_->enterForceCompositingMode(false);
 }
 
 void RenderWidget::initializeLayerTreeView() {
@@ -1689,6 +1678,9 @@
   }
 }
 
+void RenderWidget::OnOrientationChange() {
+}
+
 gfx::Vector2d RenderWidget::GetScrollOffset() {
   // Bare RenderWidgets don't support scroll offset.
   return gfx::Vector2d();
@@ -2000,6 +1992,20 @@
 }
 #endif
 
+#if defined(OS_ANDROID)
+void RenderWidget::DidChangeBodyBackgroundColor(SkColor bg_color) {
+  // If not initialized, default to white. Note that 0 is different from black
+  // as black still has alpha 0xFF.
+  if (!bg_color)
+    bg_color = SK_ColorWHITE;
+
+  if (bg_color != body_background_color_) {
+    body_background_color_ = bg_color;
+    Send(new ViewHostMsg_DidChangeBodyBackgroundColor(routing_id(), bg_color));
+  }
+}
+#endif
+
 bool RenderWidget::CanComposeInline() {
   return true;
 }
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index fdcf8ed..97a3b29 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -261,6 +261,10 @@
                                        bool has_vertical_scrollbar);
 #endif  // defined(OS_MACOSX)
 
+#if defined(OS_ANDROID)
+  void DidChangeBodyBackgroundColor(SkColor bg_color);
+#endif
+
  protected:
   // Friend RefCounted so that the dtor can be non-public. Using this class
   // without ref-counting is an error.
@@ -302,8 +306,6 @@
   void AnimationCallback();
   void InvalidationCallback();
   void FlushPendingInputEventAck();
-  void DoDeferredUpdateAndSendInputAck();
-  void DoDeferredUpdate();
   void DoDeferredClose();
   void DoDeferredSetWindowRect(const blink::WebRect& pos);
 
@@ -386,6 +388,8 @@
 
   virtual void SetDeviceScaleFactor(float device_scale_factor);
 
+  virtual void OnOrientationChange();
+
   // Override points to notify derived classes that a paint has happened.
   // DidInitiatePaint happens when that has completed, and subsequent rendering
   // won't affect the painted content. DidFlushPaint happens once we've received
@@ -655,11 +659,6 @@
   // compositor.
   bool is_accelerated_compositing_active_;
 
-  // Set to true if compositing has ever been active for this widget. Once a
-  // widget has used compositing, it will act as though force compositing mode
-  // is on for the remainder of the widget's lifetime.
-  bool was_accelerated_compositing_ever_active_;
-
   base::OneShotTimer<RenderWidget> animation_timer_;
   bool animation_update_pending_;
   bool invalidation_task_posted_;
@@ -694,6 +693,11 @@
   // browser regarding IME-type events that have not been acknowledged by the
   // browser. If this value is not 0 IME events will be dropped.
   int outstanding_ime_acks_;
+
+  // The background color of the document body element. This is used as the
+  // default background color for filling the screen areas for which we don't
+  // have the actual content.
+  SkColor body_background_color_;
 #endif
 
 #if defined(OS_MACOSX)
diff --git a/content/renderer/render_widget_fullscreen_pepper.cc b/content/renderer/render_widget_fullscreen_pepper.cc
index af8fd83..bf85de2 100644
--- a/content/renderer/render_widget_fullscreen_pepper.cc
+++ b/content/renderer/render_widget_fullscreen_pepper.cc
@@ -13,7 +13,6 @@
 #include "content/common/view_messages.h"
 #include "content/public/common/content_switches.h"
 #include "content/renderer/gpu/render_widget_compositor.h"
-#include "content/renderer/pepper/pepper_platform_context_3d.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
 #include "content/renderer/render_thread_impl.h"
 #include "gpu/command_buffer/client/gles2_implementation.h"
@@ -131,6 +130,8 @@
 }
 
 // WebWidget that simply wraps the pepper plugin.
+// TODO(piman): figure out IME and implement setComposition and friends if
+// necessary.
 class PepperWidget : public WebWidget {
  public:
   explicit PepperWidget(RenderWidgetFullscreenPepper* widget)
@@ -148,9 +149,6 @@
     return size_;
   }
 
-  virtual void willStartLiveResize() {
-  }
-
   virtual void resize(const WebSize& size) {
     if (!widget_->plugin())
       return;
@@ -162,33 +160,6 @@
     widget_->Invalidate();
   }
 
-  virtual void willEndLiveResize() {
-  }
-
-  virtual void animate(double frameBeginTime) {
-  }
-
-  virtual void layout() {
-  }
-
-  virtual void paint(WebCanvas* canvas, const WebRect& rect, PaintOptions) {
-    if (!widget_->plugin())
-      return;
-
-    SkAutoCanvasRestore auto_restore(canvas, true);
-    float canvas_scale = widget_->deviceScaleFactor();
-    canvas->scale(canvas_scale, canvas_scale);
-
-    WebRect plugin_rect(0, 0, size_.width, size_.height);
-    widget_->plugin()->Paint(canvas, plugin_rect, rect);
-  }
-
-  virtual void setCompositorSurfaceReady() {
-  }
-
-  virtual void composite(bool finish) {
-  }
-
   virtual void themeChanged() {
     NOTIMPLEMENTED();
   }
@@ -281,56 +252,6 @@
     return result;
   }
 
-  virtual void mouseCaptureLost() {
-  }
-
-  virtual void setFocus(bool focus) {
-  }
-
-  // TODO(piman): figure out IME and implement these if necessary.
-  virtual bool setComposition(
-      const WebString& text,
-      const WebVector<WebCompositionUnderline>& underlines,
-      int selectionStart,
-      int selectionEnd) {
-    return false;
-  }
-
-  virtual bool confirmComposition() {
-    return false;
-  }
-
-  virtual bool compositionRange(size_t* location, size_t* length) {
-    return false;
-  }
-
-  virtual bool confirmComposition(const WebString& text) {
-    return false;
-  }
-
-  virtual WebTextInputType textInputType() {
-    return blink::WebTextInputTypeNone;
-  }
-
-  virtual WebRect caretOrSelectionBounds() {
-    return WebRect();
-  }
-
-  virtual bool selectionRange(WebPoint& start, WebPoint& end) const {
-    return false;
-  }
-
-  virtual bool caretOrSelectionRange(size_t* location, size_t* length) {
-    return false;
-  }
-
-  virtual void setTextDirection(WebTextDirection) {
-  }
-
-  virtual bool isAcceleratedCompositingActive() const {
-    return widget_->plugin() && widget_->is_compositing();
-  }
-
  private:
   RenderWidgetFullscreenPepper* widget_;
   WebSize size_;
diff --git a/content/renderer/render_widget_fullscreen_pepper.h b/content/renderer/render_widget_fullscreen_pepper.h
index 0b97c9e..5fdb0e0 100644
--- a/content/renderer/render_widget_fullscreen_pepper.h
+++ b/content/renderer/render_widget_fullscreen_pepper.h
@@ -49,8 +49,6 @@
     return mouse_lock_dispatcher_.get();
   }
 
-  bool is_compositing() const { return !!layer_; }
-
  protected:
   RenderWidgetFullscreenPepper(PepperPluginInstanceImpl* plugin,
                                const GURL& active_url,
diff --git a/content/renderer/renderer_main_platform_delegate_win.cc b/content/renderer/renderer_main_platform_delegate_win.cc
index 3503fdd..77d5a34 100644
--- a/content/renderer/renderer_main_platform_delegate_win.cc
+++ b/content/renderer/renderer_main_platform_delegate_win.cc
@@ -19,6 +19,7 @@
 #include "content/renderer/render_thread_impl.h"
 #include "sandbox/win/src/sandbox.h"
 #include "skia/ext/vector_platform_device_emf_win.h"
+#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
 #include "third_party/WebKit/public/web/win/WebFontRendering.h"
 #include "third_party/icu/source/i18n/unicode/timezone.h"
 #include "third_party/skia/include/ports/SkFontMgr.h"
@@ -103,7 +104,9 @@
     }
   }
   blink::WebFontRendering::setUseDirectWrite(use_direct_write);
-  blink::WebFontRendering::setUseSubpixelPositioning(use_direct_write);
+  if (use_direct_write) {
+    blink::WebRuntimeFeatures::enableSubpixelFontScaling(true);
+  }
 }
 
 void RendererMainPlatformDelegate::PlatformUninitialize() {
diff --git a/content/renderer/renderer_webkitplatformsupport_impl.cc b/content/renderer/renderer_webkitplatformsupport_impl.cc
index b507a73..91906df 100644
--- a/content/renderer/renderer_webkitplatformsupport_impl.cc
+++ b/content/renderer/renderer_webkitplatformsupport_impl.cc
@@ -413,7 +413,7 @@
     // Check whether the key system is supported with the mime_type and codecs.
 
     // Chromium only supports ASCII parameters.
-    if (!IsStringASCII(key_system))
+    if (!base::IsStringASCII(key_system))
       return IsNotSupported;
 
     std::string key_system_ascii =
@@ -474,8 +474,8 @@
     const WebString& mime_type,
     const WebString& codecs) {
   // Chromium only supports ASCII parameters.
-  if (!IsStringASCII(key_system) || !IsStringASCII(mime_type) ||
-      !IsStringASCII(codecs)) {
+  if (!base::IsStringASCII(key_system) || !base::IsStringASCII(mime_type) ||
+      !base::IsStringASCII(codecs)) {
     return false;
   }
 
@@ -884,7 +884,8 @@
 
 void RendererWebKitPlatformSupportImpl::sampleGamepads(WebGamepads& gamepads) {
   if (g_test_gamepads == 0) {
-    RenderThreadImpl::current()->SampleGamepads(&gamepads);
+    RenderThreadImpl::current()->gamepad_shared_memory_reader()->
+        SampleGamepads(gamepads);
   } else {
     gamepads = g_test_gamepads.Get();
   }
@@ -893,6 +894,8 @@
 void RendererWebKitPlatformSupportImpl::setGamepadListener(
       blink::WebGamepadListener* listener) {
   web_gamepad_listener = listener;
+  RenderThreadImpl::current()->gamepad_shared_memory_reader()->
+      SetGamepadListener(listener);
 }
 
 //------------------------------------------------------------------------------
diff --git a/content/renderer/service_worker/embedded_worker_context_client.cc b/content/renderer/service_worker/embedded_worker_context_client.cc
index 688dd85..4bd0635 100644
--- a/content/renderer/service_worker/embedded_worker_context_client.cc
+++ b/content/renderer/service_worker/embedded_worker_context_client.cc
@@ -11,6 +11,7 @@
 #include "content/child/request_extra_data.h"
 #include "content/child/service_worker/service_worker_network_provider.h"
 #include "content/child/thread_safe_sender.h"
+#include "content/child/webmessageportchannel_impl.h"
 #include "content/child/worker_task_runner.h"
 #include "content/child/worker_thread_task_runner.h"
 #include "content/common/devtools_messages.h"
@@ -131,6 +132,8 @@
   DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread());
   DCHECK(!script_context_);
 
+  Send(new EmbeddedWorkerHostMsg_WorkerScriptLoadFailed(embedded_worker_id_));
+
   RenderThreadImpl::current()->embedded_worker_dispatcher()->
       WorkerContextDestroyed(embedded_worker_id_);
 }
@@ -146,6 +149,8 @@
   g_worker_client_tls.Pointer()->Set(this);
   script_context_.reset(new ServiceWorkerScriptContext(this, proxy));
 
+  Send(new EmbeddedWorkerHostMsg_WorkerScriptLoaded(embedded_worker_id_));
+
   // Schedule a task to send back WorkerStarted asynchronously,
   // so that at the time we send it we can be sure that the worker
   // script has been evaluated and worker run loop has been started.
@@ -160,10 +165,26 @@
   // worker_task_runner_->RunsTasksOnCurrentThread() returns false
   // (while we're still on the worker thread).
   script_context_.reset();
+
+#if !defined(HAS_SERVICE_WORKER_CONTEXT_DESTROYED)
+  // TODO(kinuko): Remove this after blink side is landed.
   main_thread_proxy_->PostTask(
       FROM_HERE,
       base::Bind(&CallWorkerContextDestroyedOnMainThread,
                  embedded_worker_id_));
+#endif
+}
+
+void EmbeddedWorkerContextClient::workerContextDestroyed() {
+  // TODO(kinuko): Remove this ifdef after blink side is landed.
+#ifdef HAS_SERVICE_WORKER_CONTEXT_DESTROYED
+  // Now we should be able to free the WebEmbeddedWorker container on the
+  // main thread.
+  main_thread_proxy_->PostTask(
+      FROM_HERE,
+      base::Bind(&CallWorkerContextDestroyedOnMainThread,
+                 embedded_worker_id_));
+#endif
 }
 
 void EmbeddedWorkerContextClient::reportException(
@@ -266,6 +287,16 @@
   return new WebServiceWorkerNetworkProviderImpl();
 }
 
+void EmbeddedWorkerContextClient::postMessageToClient(
+    int client_id,
+    const blink::WebString& message,
+    blink::WebMessagePortChannelArray* channels) {
+  DCHECK(script_context_);
+  script_context_->PostMessageToDocument(
+      client_id, message,
+      WebMessagePortChannelImpl::ExtractMessagePortIDs(channels));
+}
+
 void EmbeddedWorkerContextClient::OnMessageToWorker(
     int thread_id,
     int embedded_worker_id,
diff --git a/content/renderer/service_worker/embedded_worker_context_client.h b/content/renderer/service_worker/embedded_worker_context_client.h
index 4312af2..7d18ec5 100644
--- a/content/renderer/service_worker/embedded_worker_context_client.h
+++ b/content/renderer/service_worker/embedded_worker_context_client.h
@@ -70,6 +70,7 @@
   virtual void workerContextFailedToStart();
   virtual void workerContextStarted(blink::WebServiceWorkerContextProxy* proxy);
   virtual void willDestroyWorkerContext();
+  virtual void workerContextDestroyed();
   virtual void reportException(const blink::WebString& error_message,
                                int line_number,
                                int column_number,
@@ -92,6 +93,10 @@
   virtual void didHandleSyncEvent(int request_id);
   virtual blink::WebServiceWorkerNetworkProvider*
       createServiceWorkerNetworkProvider(blink::WebDataSource* data_source);
+  virtual void postMessageToClient(
+      int client_id,
+      const blink::WebString& message,
+      blink::WebMessagePortChannelArray* channels);
 
   // TODO: Implement DevTools related method overrides.
 
@@ -99,6 +104,7 @@
   base::MessageLoopProxy* main_thread_proxy() const {
     return main_thread_proxy_;
   }
+  ThreadSafeSender* thread_safe_sender() { return sender_; }
 
  private:
   void OnMessageToWorker(int thread_id,
diff --git a/content/renderer/service_worker/service_worker_script_context.cc b/content/renderer/service_worker/service_worker_script_context.cc
index c97cd86..7df0808 100644
--- a/content/renderer/service_worker/service_worker_script_context.cc
+++ b/content/renderer/service_worker/service_worker_script_context.cc
@@ -5,6 +5,7 @@
 #include "content/renderer/service_worker/service_worker_script_context.h"
 
 #include "base/logging.h"
+#include "content/child/thread_safe_sender.h"
 #include "content/child/webmessageportchannel_impl.h"
 #include "content/common/service_worker/service_worker_messages.h"
 #include "content/renderer/service_worker/embedded_worker_context_client.h"
@@ -14,6 +15,20 @@
 
 namespace content {
 
+namespace {
+
+void SendPostMessageToDocumentOnMainThread(
+    ThreadSafeSender* sender,
+    int routing_id,
+    int client_id,
+    const base::string16& message,
+    const std::vector<int>& message_port_ids) {
+  sender->Send(new ServiceWorkerHostMsg_PostMessageToDocument(
+      routing_id, client_id, message, message_port_ids));
+}
+
+}  // namespace
+
 ServiceWorkerScriptContext::ServiceWorkerScriptContext(
     EmbeddedWorkerContextClient* embedded_context,
     blink::WebServiceWorkerContextProxy* proxy)
@@ -31,7 +46,7 @@
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_FetchEvent, OnFetchEvent)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_InstallEvent, OnInstallEvent)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SyncEvent, OnSyncEvent)
-    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_Message, OnPostMessage)
+    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToWorker, OnPostMessage)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetClientDocuments,
                         OnDidGetClientDocuments)
     IPC_MESSAGE_UNHANDLED(handled = false)
@@ -74,6 +89,21 @@
       GetRoutingID(), request_id));
 }
 
+void ServiceWorkerScriptContext::PostMessageToDocument(
+    int client_id,
+    const base::string16& message,
+    const std::vector<int>& message_port_ids) {
+  // This may send IDs for MessagePorts, and all internal book-keeping
+  // messages for MessagePort (e.g. QueueMessages) are sent from main thread
+  // (with thread hopping), so we need to do the same thread hopping here not
+  // to overtake those messages.
+  embedded_context_->main_thread_proxy()->PostTask(
+      FROM_HERE,
+      base::Bind(&SendPostMessageToDocumentOnMainThread,
+                 make_scoped_refptr(embedded_context_->thread_safe_sender()),
+                 GetRoutingID(), client_id, message, message_port_ids));
+}
+
 void ServiceWorkerScriptContext::Send(IPC::Message* message) {
   embedded_context_->Send(message);
 }
diff --git a/content/renderer/service_worker/service_worker_script_context.h b/content/renderer/service_worker/service_worker_script_context.h
index 03a9e27..a528d34 100644
--- a/content/renderer/service_worker/service_worker_script_context.h
+++ b/content/renderer/service_worker/service_worker_script_context.h
@@ -10,6 +10,7 @@
 #include "base/basictypes.h"
 #include "base/id_map.h"
 #include "base/strings/string16.h"
+#include "content/child/webmessageportchannel_impl.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "third_party/WebKit/public/platform/WebServiceWorkerClientsInfo.h"
 #include "third_party/WebKit/public/platform/WebServiceWorkerEventResult.h"
@@ -49,6 +50,9 @@
   void DidHandleSyncEvent(int request_id);
   void GetClientDocuments(
       blink::WebServiceWorkerClientsCallbacks* callbacks);
+  void PostMessageToDocument(int client_id,
+                             const base::string16& message,
+                             const std::vector<int>& message_port_ids);
 
  private:
   typedef IDMap<blink::WebServiceWorkerClientsCallbacks, IDMapOwnPointer>
diff --git a/content/renderer/web_preferences.cc b/content/renderer/web_preferences.cc
index 2c4e41b..a2d4e5e 100644
--- a/content/renderer/web_preferences.cc
+++ b/content/renderer/web_preferences.cc
@@ -342,6 +342,8 @@
       prefs.pinch_overlay_scrollbar_thickness);
   settings->setUseSolidColorScrollbars(prefs.use_solid_color_scrollbars);
   settings->setCompositorTouchHitTesting(prefs.compositor_touch_hit_testing);
+
+  settings->setUseThreadedHTMLParserForDataURLs(true);
 }
 
 }  // namespace content
diff --git a/content/result_codes_java.target.darwin-arm.mk b/content/result_codes_java.target.darwin-arm.mk
index 90f7759..8e52139 100644
--- a/content/result_codes_java.target.darwin-arm.mk
+++ b/content/result_codes_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/result_codes_java.target.darwin-arm64.mk b/content/result_codes_java.target.darwin-arm64.mk
index babd565..a57ad6e 100644
--- a/content/result_codes_java.target.darwin-arm64.mk
+++ b/content/result_codes_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/result_codes_java.target.darwin-mips.mk b/content/result_codes_java.target.darwin-mips.mk
index fff7fb7..773c4cd 100644
--- a/content/result_codes_java.target.darwin-mips.mk
+++ b/content/result_codes_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/result_codes_java.target.darwin-x86.mk b/content/result_codes_java.target.darwin-x86.mk
index 3a2bed7..ed345b9 100644
--- a/content/result_codes_java.target.darwin-x86.mk
+++ b/content/result_codes_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/result_codes_java.target.darwin-x86_64.mk b/content/result_codes_java.target.darwin-x86_64.mk
index 4eb98f9..c37fc9c 100644
--- a/content/result_codes_java.target.darwin-x86_64.mk
+++ b/content/result_codes_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/result_codes_java.target.linux-arm.mk b/content/result_codes_java.target.linux-arm.mk
index 90f7759..8e52139 100644
--- a/content/result_codes_java.target.linux-arm.mk
+++ b/content/result_codes_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/result_codes_java.target.linux-arm64.mk b/content/result_codes_java.target.linux-arm64.mk
index babd565..a57ad6e 100644
--- a/content/result_codes_java.target.linux-arm64.mk
+++ b/content/result_codes_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/result_codes_java.target.linux-mips.mk b/content/result_codes_java.target.linux-mips.mk
index fff7fb7..773c4cd 100644
--- a/content/result_codes_java.target.linux-mips.mk
+++ b/content/result_codes_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/result_codes_java.target.linux-x86.mk b/content/result_codes_java.target.linux-x86.mk
index 3a2bed7..ed345b9 100644
--- a/content/result_codes_java.target.linux-x86.mk
+++ b/content/result_codes_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/result_codes_java.target.linux-x86_64.mk b/content/result_codes_java.target.linux-x86_64.mk
index 4eb98f9..c37fc9c 100644
--- a/content/result_codes_java.target.linux-x86_64.mk
+++ b/content/result_codes_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_result_codes_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/result_codes_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ResultCodes.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ResultCodes.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/screen_orientation_values_java.target.darwin-arm.mk b/content/screen_orientation_values_java.target.darwin-arm.mk
index cce8004..fc61918 100644
--- a/content/screen_orientation_values_java.target.darwin-arm.mk
+++ b/content/screen_orientation_values_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_screen_orientation_values_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/screen_orientation_values_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/screen_orientation_values_java.target.darwin-arm64.mk b/content/screen_orientation_values_java.target.darwin-arm64.mk
index f3ed27c..5b24642 100644
--- a/content/screen_orientation_values_java.target.darwin-arm64.mk
+++ b/content/screen_orientation_values_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_screen_orientation_values_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/screen_orientation_values_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/screen_orientation_values_java.target.darwin-mips.mk b/content/screen_orientation_values_java.target.darwin-mips.mk
index 61dcfdd..a37a815 100644
--- a/content/screen_orientation_values_java.target.darwin-mips.mk
+++ b/content/screen_orientation_values_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_screen_orientation_values_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/screen_orientation_values_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/screen_orientation_values_java.target.darwin-x86.mk b/content/screen_orientation_values_java.target.darwin-x86.mk
index 14c4bd9..673b0ef 100644
--- a/content/screen_orientation_values_java.target.darwin-x86.mk
+++ b/content/screen_orientation_values_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_screen_orientation_values_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/screen_orientation_values_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/screen_orientation_values_java.target.darwin-x86_64.mk b/content/screen_orientation_values_java.target.darwin-x86_64.mk
index f685f10..377f27b 100644
--- a/content/screen_orientation_values_java.target.darwin-x86_64.mk
+++ b/content/screen_orientation_values_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_screen_orientation_values_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/screen_orientation_values_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/screen_orientation_values_java.target.linux-arm.mk b/content/screen_orientation_values_java.target.linux-arm.mk
index cce8004..fc61918 100644
--- a/content/screen_orientation_values_java.target.linux-arm.mk
+++ b/content/screen_orientation_values_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_screen_orientation_values_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/screen_orientation_values_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/screen_orientation_values_java.target.linux-arm64.mk b/content/screen_orientation_values_java.target.linux-arm64.mk
index f3ed27c..5b24642 100644
--- a/content/screen_orientation_values_java.target.linux-arm64.mk
+++ b/content/screen_orientation_values_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_screen_orientation_values_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/screen_orientation_values_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/screen_orientation_values_java.target.linux-mips.mk b/content/screen_orientation_values_java.target.linux-mips.mk
index 61dcfdd..a37a815 100644
--- a/content/screen_orientation_values_java.target.linux-mips.mk
+++ b/content/screen_orientation_values_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_screen_orientation_values_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/screen_orientation_values_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/screen_orientation_values_java.target.linux-x86.mk b/content/screen_orientation_values_java.target.linux-x86.mk
index 14c4bd9..673b0ef 100644
--- a/content/screen_orientation_values_java.target.linux-x86.mk
+++ b/content/screen_orientation_values_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_screen_orientation_values_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/screen_orientation_values_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/screen_orientation_values_java.target.linux-x86_64.mk b/content/screen_orientation_values_java.target.linux-x86_64.mk
index f685f10..377f27b 100644
--- a/content/screen_orientation_values_java.target.linux-x86_64.mk
+++ b/content/screen_orientation_values_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_screen_orientation_values_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/screen_orientation_values_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/common/ScreenOrientationValues.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc
index 3eecb83..b7aeb6b 100644
--- a/content/shell/app/shell_main_delegate.cc
+++ b/content/shell/app/shell_main_delegate.cc
@@ -170,6 +170,8 @@
 
     command_line.AppendSwitch(switches::kEnableFileCookies);
 
+    command_line.AppendSwitch(switches::kEnablePreciseMemoryInfo);
+
     // Unless/until WebM files are added to the media layout tests, we need to
     // avoid removing MP4/H264/AAC so that layout tests can run on Android.
 #if !defined(OS_ANDROID)
diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc
index e55fb85..c63ff15 100644
--- a/content/shell/browser/shell.cc
+++ b/content/shell/browser/shell.cc
@@ -18,7 +18,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/renderer_preferences.h"
 #include "content/shell/browser/notify_done_forwarder.h"
 #include "content/shell/browser/shell_browser_main_parts.h"
@@ -47,7 +46,7 @@
   }
 
   // WebContentsObserver
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     shell_->OnDevToolsWebContentsDestroyed();
   }
 
@@ -176,7 +175,7 @@
       PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR);
   params.frame_name = frame_name;
   web_contents_->GetController().LoadURLWithParams(params);
-  web_contents_->GetView()->Focus();
+  web_contents_->Focus();
 }
 
 void Shell::LoadDataWithBaseURL(const GURL& url, const std::string& data,
@@ -188,7 +187,7 @@
   params.virtual_url_for_data_url = url;
   params.override_user_agent = NavigationController::UA_OVERRIDE_FALSE;
   web_contents_->GetController().LoadURLWithParams(params);
-  web_contents_->GetView()->Focus();
+  web_contents_->Focus();
 }
 
 void Shell::AddNewContents(WebContents* source,
@@ -204,17 +203,17 @@
 
 void Shell::GoBackOrForward(int offset) {
   web_contents_->GetController().GoToOffset(offset);
-  web_contents_->GetView()->Focus();
+  web_contents_->Focus();
 }
 
 void Shell::Reload() {
   web_contents_->GetController().Reload(false);
-  web_contents_->GetView()->Focus();
+  web_contents_->Focus();
 }
 
 void Shell::Stop() {
   web_contents_->Stop();
-  web_contents_->GetView()->Focus();
+  web_contents_->Focus();
 }
 
 void Shell::UpdateNavigationControls(bool to_different_document) {
@@ -252,7 +251,7 @@
 gfx::NativeView Shell::GetContentView() {
   if (!web_contents_)
     return NULL;
-  return web_contents_->GetView()->GetNativeView();
+  return web_contents_->GetNativeView();
 }
 
 WebContents* Shell::OpenURLFromTab(WebContents* source,
diff --git a/content/shell/browser/shell_aura.cc b/content/shell/browser/shell_aura.cc
index ccfa1f6..33ee197 100644
--- a/content/shell/browser/shell_aura.cc
+++ b/content/shell/browser/shell_aura.cc
@@ -5,7 +5,6 @@
 #include "content/shell/browser/shell.h"
 
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/shell/browser/shell_platform_data_aura.h"
 #include "ui/aura/env.h"
 #include "ui/aura/test/test_screen.h"
@@ -50,7 +49,7 @@
 
 void Shell::PlatformSetContents() {
   CHECK(platform_);
-  aura::Window* content = web_contents_->GetView()->GetNativeView();
+  aura::Window* content = web_contents_->GetNativeView();
   aura::Window* parent = platform_->host()->window();
   if (parent->Contains(content))
     return;
diff --git a/content/shell/browser/shell_browser_context.cc b/content/shell/browser/shell_browser_context.cc
index b37521e..7778ff6 100644
--- a/content/shell/browser/shell_browser_context.cc
+++ b/content/shell/browser/shell_browser_context.cc
@@ -65,6 +65,7 @@
     : off_the_record_(off_the_record),
       net_log_(net_log),
       ignore_certificate_errors_(false),
+      guest_manager_delegate_(NULL),
       resource_context_(new ShellResourceContext) {
   InitWhileIOAllowed();
 }
@@ -234,6 +235,11 @@
   return NULL;
 }
 
+BrowserPluginGuestManagerDelegate*
+    ShellBrowserContext::GetGuestManagerDelegate() {
+  return guest_manager_delegate_;
+}
+
 quota::SpecialStoragePolicy* ShellBrowserContext::GetSpecialStoragePolicy() {
   return NULL;
 }
diff --git a/content/shell/browser/shell_browser_context.h b/content/shell/browser/shell_browser_context.h
index 3bd5192..63bbf34 100644
--- a/content/shell/browser/shell_browser_context.h
+++ b/content/shell/browser/shell_browser_context.h
@@ -29,6 +29,11 @@
   ShellBrowserContext(bool off_the_record, net::NetLog* net_log);
   virtual ~ShellBrowserContext();
 
+  void set_guest_manager_delegate_for_testing(
+      BrowserPluginGuestManagerDelegate* guest_manager_delegate) {
+    guest_manager_delegate_ = guest_manager_delegate;
+  }
+
   // BrowserContext implementation.
   virtual base::FilePath GetPath() const OVERRIDE;
   virtual bool IsOffTheRecord() const OVERRIDE;
@@ -67,6 +72,8 @@
   virtual ResourceContext* GetResourceContext() OVERRIDE;
   virtual GeolocationPermissionContext*
       GetGeolocationPermissionContext() OVERRIDE;
+  virtual content::BrowserPluginGuestManagerDelegate*
+      GetGuestManagerDelegate() OVERRIDE;
   virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
 
   net::URLRequestContextGetter* CreateRequestContext(
@@ -89,6 +96,7 @@
   net::NetLog* net_log_;
   bool ignore_certificate_errors_;
   base::FilePath path_;
+  BrowserPluginGuestManagerDelegate* guest_manager_delegate_;
   scoped_ptr<ShellResourceContext> resource_context_;
   scoped_ptr<ShellDownloadManagerDelegate> download_manager_delegate_;
   scoped_refptr<ShellURLRequestContextGetter> url_request_getter_;
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index d4394f3..21423d2 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -211,8 +211,8 @@
   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
     command_line->AppendSwitch(switches::kDumpRenderTree);
   if (CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kEnableFontSmoothing))
-    command_line->AppendSwitch(switches::kEnableFontSmoothing);
+      switches::kEnableFontAntialiasing))
+    command_line->AppendSwitch(switches::kEnableFontAntialiasing);
   if (CommandLine::ForCurrentProcess()->HasSwitch(
       switches::kExposeInternalsForTesting))
     command_line->AppendSwitch(switches::kExposeInternalsForTesting);
diff --git a/content/shell/browser/shell_devtools_delegate.cc b/content/shell/browser/shell_devtools_delegate.cc
index 01dca2b..d6f3b62 100644
--- a/content/shell/browser/shell_devtools_delegate.cc
+++ b/content/shell/browser/shell_devtools_delegate.cc
@@ -80,8 +80,8 @@
   virtual std::string GetType() const OVERRIDE { return kTargetTypePage; }
   virtual std::string GetTitle() const OVERRIDE { return title_; }
   virtual std::string GetDescription() const OVERRIDE { return std::string(); }
-  virtual GURL GetUrl() const OVERRIDE { return url_; }
-  virtual GURL GetFaviconUrl() const OVERRIDE { return favicon_url_; }
+  virtual GURL GetURL() const OVERRIDE { return url_; }
+  virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; }
   virtual base::TimeTicks GetLastActivityTime() const OVERRIDE {
     return last_activity_time_;
   }
diff --git a/content/shell/browser/shell_devtools_frontend.cc b/content/shell/browser/shell_devtools_frontend.cc
index a25df91..21973f4 100644
--- a/content/shell/browser/shell_devtools_frontend.cc
+++ b/content/shell/browser/shell_devtools_frontend.cc
@@ -13,7 +13,6 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_client.h"
 #include "content/shell/browser/shell.h"
 #include "content/shell/browser/shell_browser_context.h"
@@ -90,7 +89,7 @@
 }
 
 void ShellDevToolsFrontend::Focus() {
-  web_contents()->GetView()->Focus();
+  web_contents()->Focus();
 }
 
 void ShellDevToolsFrontend::InspectElementAt(int x, int y) {
@@ -122,12 +121,12 @@
                                          frontend_host_.get());
 }
 
-void ShellDevToolsFrontend::DocumentOnLoadCompletedInMainFrame(int32 page_id) {
+void ShellDevToolsFrontend::DocumentOnLoadCompletedInMainFrame() {
   web_contents()->GetMainFrame()->ExecuteJavaScript(
       base::ASCIIToUTF16("InspectorFrontendAPI.setUseSoftMenu(true);"));
 }
 
-void ShellDevToolsFrontend::WebContentsDestroyed(WebContents* web_contents) {
+void ShellDevToolsFrontend::WebContentsDestroyed() {
   DevToolsManager::GetInstance()->ClientHostClosing(frontend_host_.get());
   delete this;
 }
diff --git a/content/shell/browser/shell_devtools_frontend.h b/content/shell/browser/shell_devtools_frontend.h
index 6244380..d9591c7 100644
--- a/content/shell/browser/shell_devtools_frontend.h
+++ b/content/shell/browser/shell_devtools_frontend.h
@@ -43,8 +43,8 @@
 
   // WebContentsObserver overrides
   virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE;
-  virtual void DocumentOnLoadCompletedInMainFrame(int32 page_id) OVERRIDE;
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void DocumentOnLoadCompletedInMainFrame() OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // DevToolsFrontendHostDelegate implementation
   virtual void DispatchOnEmbedder(const std::string& message) OVERRIDE {}
diff --git a/content/shell/browser/shell_download_manager_delegate.cc b/content/shell/browser/shell_download_manager_delegate.cc
index 45f86f3..9f37d82 100644
--- a/content/shell/browser/shell_download_manager_delegate.cc
+++ b/content/shell/browser/shell_download_manager_delegate.cc
@@ -19,7 +19,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/download_manager.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/shell/browser/webkit_test_controller.h"
 #include "content/shell/common/shell_switches.h"
 #include "net/base/filename_util.h"
@@ -171,7 +170,7 @@
   OPENFILENAME save_as;
   ZeroMemory(&save_as, sizeof(save_as));
   save_as.lStructSize = sizeof(OPENFILENAME);
-  save_as.hwndOwner = item->GetWebContents()->GetView()->GetNativeView()->
+  save_as.hwndOwner = item->GetWebContents()->GetNativeView()->
       GetHost()->GetAcceleratedWidget();
   save_as.lpstrFile = file_name;
   save_as.nMaxFile = arraysize(file_name);
diff --git a/content/shell/browser/shell_javascript_dialog_manager.cc b/content/shell/browser/shell_javascript_dialog_manager.cc
index ef284e2..ae08633 100644
--- a/content/shell/browser/shell_javascript_dialog_manager.cc
+++ b/content/shell/browser/shell_javascript_dialog_manager.cc
@@ -8,7 +8,6 @@
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/shell/browser/shell_javascript_dialog.h"
 #include "content/shell/browser/webkit_test_controller.h"
 #include "content/shell/common/shell_switches.h"
@@ -55,8 +54,7 @@
   base::string16 new_message_text = net::FormatUrl(origin_url, accept_lang) +
                               base::ASCIIToUTF16("\n\n") +
                               message_text;
-  gfx::NativeWindow parent_window =
-      web_contents->GetView()->GetTopLevelNativeWindow();
+  gfx::NativeWindow parent_window = web_contents->GetTopLevelNativeWindow();
 
   dialog_.reset(new ShellJavaScriptDialog(this,
                                           parent_window,
@@ -99,8 +97,7 @@
       message_text +
       base::ASCIIToUTF16("\n\nIs it OK to leave/reload this page?");
 
-  gfx::NativeWindow parent_window =
-      web_contents->GetView()->GetTopLevelNativeWindow();
+  gfx::NativeWindow parent_window = web_contents->GetTopLevelNativeWindow();
 
   dialog_.reset(new ShellJavaScriptDialog(this,
                                           parent_window,
diff --git a/content/shell/browser/shell_mac.mm b/content/shell/browser/shell_mac.mm
index a51c852..f332064 100644
--- a/content/shell/browser/shell_mac.mm
+++ b/content/shell/browser/shell_mac.mm
@@ -12,7 +12,6 @@
 #include "base/strings/sys_string_conversions.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/shell/app/resource.h"
 #import "ui/base/cocoa/underlay_opengl_hosting_window.h"
 #include "url/gurl.h"
@@ -243,7 +242,7 @@
 }
 
 void Shell::PlatformSetContents() {
-  NSView* web_view = web_contents_->GetView()->GetNativeView();
+  NSView* web_view = web_contents_->GetNativeView();
   [web_view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
 
   if (headless_) {
@@ -267,7 +266,7 @@
     [window().contentView setFrame:frame];
     return;
   }
-  NSView* web_view = web_contents_->GetView()->GetNativeView();
+  NSView* web_view = web_contents_->GetNativeView();
   NSRect frame = NSMakeRect(0, 0, content_size.width(), content_size.height());
   [web_view setFrame:frame];
 }
diff --git a/content/shell/browser/shell_views.cc b/content/shell/browser/shell_views.cc
index 6bc61b1..fda7fbc 100644
--- a/content/shell/browser/shell_views.cc
+++ b/content/shell/browser/shell_views.cc
@@ -8,7 +8,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/context_menu_params.h"
 #include "content/shell/browser/shell_platform_data_aura.h"
 #include "ui/aura/client/screen_position_client.h"
@@ -138,7 +137,7 @@
     web_view_ = new views::WebView(web_contents->GetBrowserContext());
     web_view_->SetWebContents(web_contents);
     web_view_->SetPreferredSize(size);
-    web_contents->GetView()->Focus();
+    web_contents->Focus();
     contents_view_->AddChildView(web_view_);
     Layout();
 
@@ -174,7 +173,7 @@
     // Convert from content coordinates to window coordinates.
     // This code copied from chrome_web_contents_view_delegate_views.cc
     aura::Window* web_contents_window =
-        shell_->web_contents()->GetView()->GetNativeView();
+        shell_->web_contents()->GetNativeView();
     aura::Window* root_window = web_contents_window->GetRootWindow();
     aura::client::ScreenPositionClient* screen_position_client =
         aura::client::GetScreenPositionClient(root_window);
@@ -514,7 +513,7 @@
 void Shell::PlatformSetContents() {
   if (headless_) {
     CHECK(platform_);
-    aura::Window* content = web_contents_->GetView()->GetNativeView();
+    aura::Window* content = web_contents_->GetNativeView();
     aura::Window* parent = platform_->host()->window();
     if (!parent->Contains(content)) {
       parent->AddChild(content);
diff --git a/content/shell/browser/shell_web_contents_view_delegate_android.cc b/content/shell/browser/shell_web_contents_view_delegate_android.cc
index fb4a3dc..bd2d186 100644
--- a/content/shell/browser/shell_web_contents_view_delegate_android.cc
+++ b/content/shell/browser/shell_web_contents_view_delegate_android.cc
@@ -7,7 +7,6 @@
 #include "base/command_line.h"
 #include "content/public/browser/android/content_view_core.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/context_menu_params.h"
 #include "content/shell/browser/shell_web_contents_view_delegate_creator.h"
 
diff --git a/content/shell/browser/shell_web_contents_view_delegate_mac.mm b/content/shell/browser/shell_web_contents_view_delegate_mac.mm
index cd825d5..375112f 100644
--- a/content/shell/browser/shell_web_contents_view_delegate_mac.mm
+++ b/content/shell/browser/shell_web_contents_view_delegate_mac.mm
@@ -12,7 +12,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/context_menu_params.h"
 #include "content/shell/browser/shell.h"
 #include "content/shell/browser/shell_browser_context.h"
@@ -202,7 +201,7 @@
                       YES,
                       delegate);
 
-  NSView* parent_view = web_contents_->GetView()->GetContentNativeView();
+  NSView* parent_view = web_contents_->GetContentNativeView();
   NSEvent* currentEvent = [NSApp currentEvent];
   NSWindow* window = [parent_view window];
   NSPoint position = [window mouseLocationOutsideOfEventStream];
@@ -248,15 +247,15 @@
     }
     case ShellContextMenuItemBackTag:
       web_contents_->GetController().GoToOffset(-1);
-      web_contents_->GetView()->Focus();
+      web_contents_->Focus();
       break;
     case ShellContextMenuItemForwardTag:
       web_contents_->GetController().GoToOffset(1);
-      web_contents_->GetView()->Focus();
+      web_contents_->Focus();
       break;
     case ShellContextMenuItemReloadTag: {
       web_contents_->GetController().Reload(false);
-      web_contents_->GetView()->Focus();
+      web_contents_->Focus();
       break;
     }
     case ShellContextMenuItemInspectTag: {
diff --git a/content/shell/browser/shell_web_contents_view_delegate_win.cc b/content/shell/browser/shell_web_contents_view_delegate_win.cc
index 81d9b0d..9eb834d 100644
--- a/content/shell/browser/shell_web_contents_view_delegate_win.cc
+++ b/content/shell/browser/shell_web_contents_view_delegate_win.cc
@@ -10,7 +10,6 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/context_menu_params.h"
 #include "content/shell/browser/shell.h"
 #include "content/shell/browser/shell_browser_context.h"
@@ -175,14 +174,14 @@
 #else
   gfx::Point screen_point(params.x, params.y);
   POINT point = screen_point.ToPOINT();
-  ClientToScreen(web_contents_->GetView()->GetNativeView(), &point);
+  ClientToScreen(web_contents_->GetNativeView(), &point);
 
   int selection =
       TrackPopupMenu(sub_menu,
                      TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
                      point.x, point.y,
                      0,
-                     web_contents_->GetView()->GetContentNativeView(),
+                     web_contents_->GetContentNativeView(),
                      NULL);
 
   MenuItemSelected(selection);
@@ -216,15 +215,15 @@
     }
     case ShellContextMenuItemBackId:
       web_contents_->GetController().GoToOffset(-1);
-      web_contents_->GetView()->Focus();
+      web_contents_->Focus();
       break;
     case ShellContextMenuItemForwardId:
       web_contents_->GetController().GoToOffset(1);
-      web_contents_->GetView()->Focus();
+      web_contents_->Focus();
       break;
     case ShellContextMenuItemReloadId:
       web_contents_->GetController().Reload(false);
-      web_contents_->GetView()->Focus();
+      web_contents_->Focus();
       break;
     case ShellContextMenuItemInspectId: {
       ShellDevToolsFrontend::Show(web_contents_);
diff --git a/content/shell/browser/webkit_test_controller.cc b/content/shell/browser/webkit_test_controller.cc
index d16986b..fa56d01 100644
--- a/content/shell/browser/webkit_test_controller.cc
+++ b/content/shell/browser/webkit_test_controller.cc
@@ -24,7 +24,6 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/url_constants.h"
 #include "content/shell/browser/shell.h"
@@ -277,7 +276,7 @@
         PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR);
     params.should_clear_history_list = true;
     main_window_->web_contents()->GetController().LoadURLWithParams(params);
-    main_window_->web_contents()->GetView()->Focus();
+    main_window_->web_contents()->Focus();
   }
   main_window_->web_contents()->GetRenderViewHost()->SetActive(true);
   main_window_->web_contents()->GetRenderViewHost()->Focus();
@@ -422,7 +421,7 @@
   DiscardMainWindow();
 }
 
-void WebKitTestController::WebContentsDestroyed(WebContents* web_contents) {
+void WebKitTestController::WebContentsDestroyed() {
   DCHECK(CalledOnValidThread());
   printer_->AddErrorMessage("FAIL: main window was destroyed");
   DiscardMainWindow();
diff --git a/content/shell/browser/webkit_test_controller.h b/content/shell/browser/webkit_test_controller.h
index f9a7dbd..2e5cf58 100644
--- a/content/shell/browser/webkit_test_controller.h
+++ b/content/shell/browser/webkit_test_controller.h
@@ -135,7 +135,7 @@
                              base::ProcessId plugin_pid) OVERRIDE;
   virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE;
   virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
-  virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
+  virtual void WebContentsDestroyed() OVERRIDE;
 
   // NotificationObserver implementation.
   virtual void Observe(int type,
diff --git a/content/shell/common/shell_switches.cc b/content/shell/common/shell_switches.cc
index 997981e..e267cc5 100644
--- a/content/shell/common/shell_switches.cc
+++ b/content/shell/common/shell_switches.cc
@@ -27,8 +27,8 @@
 // Enable accelerated 2D canvas.
 const char kEnableAccelerated2DCanvas[] = "enable-accelerated-2d-canvas";
 
-// Enable font smoothing for pixel tests.
-const char kEnableFontSmoothing[] = "enable-font-smoothing";
+// Enable font antialiasing for pixel tests.
+const char kEnableFontAntialiasing[] = "enable-font-antialiasing";
 
 // Enables the leak detection of loading webpages. This allows us to check
 // whether or not reloading a webpage releases web-related objects correctly.
diff --git a/content/shell/common/shell_switches.h b/content/shell/common/shell_switches.h
index fb830f2..8f62d6a 100644
--- a/content/shell/common/shell_switches.h
+++ b/content/shell/common/shell_switches.h
@@ -16,7 +16,7 @@
 extern const char kCrashDumpsDir[];
 extern const char kDumpRenderTree[];
 extern const char kEnableAccelerated2DCanvas[];
-extern const char kEnableFontSmoothing[];
+extern const char kEnableFontAntialiasing[];
 extern const char kEnableLeakDetection[];
 extern const char kEncodeBinary[];
 extern const char kExposeInternalsForTesting[];
diff --git a/content/shell/common/webkit_test_helpers.h b/content/shell/common/webkit_test_helpers.h
index ffdbb2d..08f3e69 100644
--- a/content/shell/common/webkit_test_helpers.h
+++ b/content/shell/common/webkit_test_helpers.h
@@ -20,12 +20,11 @@
 
 struct TestPreferences;
 
-// The TestRunner library keeps its settings in a WebTestRunner::WebPreferenes
-// object. The content_shell, however, uses WebPreferences. This
-// method exports the settings from the WebTestRunner library which are relevant
-// for layout tests.
-void ExportLayoutTestSpecificPreferences(
-    const TestPreferences& from, WebPreferences* to);
+// The TestRunner library keeps its settings in a WebPreferenes object.
+// The content_shell, however, uses WebPreferences. This method exports the
+// settings from the WebTestRunner library which are relevant for layout tests.
+void ExportLayoutTestSpecificPreferences(const TestPreferences& from,
+                                         WebPreferences* to);
 
 // Applies settings that differ between layout tests and regular mode.
 void ApplyLayoutTestDefaultPreferences(WebPreferences* prefs);
diff --git a/content/shell/geolocation/shell_access_token_store.cc b/content/shell/geolocation/shell_access_token_store.cc
index cec481d..bdcf699 100644
--- a/content/shell/geolocation/shell_access_token_store.cc
+++ b/content/shell/geolocation/shell_access_token_store.cc
@@ -45,7 +45,8 @@
   // we provide a dummy access_token set to avoid hitting the server.
   AccessTokenSet access_token_set;
   access_token_set[GURL()] = base::ASCIIToUTF16("chromium_content_shell");
-  callback.Run(access_token_set, system_request_context_);
+  callback.Run(access_token_set, system_request_context_.get());
+  system_request_context_ = NULL;
 }
 
 void ShellAccessTokenStore::SaveAccessToken(
diff --git a/content/shell/geolocation/shell_access_token_store.h b/content/shell/geolocation/shell_access_token_store.h
index 0345b8c..e97ce36 100644
--- a/content/shell/geolocation/shell_access_token_store.h
+++ b/content/shell/geolocation/shell_access_token_store.h
@@ -5,7 +5,9 @@
 #ifndef CONTENT_SHELL_GEOLOCATION_SHELL_ACCESS_TOKEN_STORE_H_
 #define CONTENT_SHELL_GEOLOCATION_SHELL_ACCESS_TOKEN_STORE_H_
 
+#include "base/memory/ref_counted.h"
 #include "content/public/browser/access_token_store.h"
+#include "net/url_request/url_request_context_getter.h"
 
 namespace content {
 class ShellBrowserContext;
@@ -31,7 +33,7 @@
       const GURL& server_url, const base::string16& access_token) OVERRIDE;
 
   content::ShellBrowserContext* shell_browser_context_;
-  net::URLRequestContextGetter* system_request_context_;
+  scoped_refptr<net::URLRequestContextGetter> system_request_context_;
 
   DISALLOW_COPY_AND_ASSIGN(ShellAccessTokenStore);
 };
diff --git a/content/shell/renderer/shell_content_renderer_client.cc b/content/shell/renderer/shell_content_renderer_client.cc
index e0585cc..fdb0bc2 100644
--- a/content/shell/renderer/shell_content_renderer_client.cc
+++ b/content/shell/renderer/shell_content_renderer_client.cc
@@ -45,8 +45,6 @@
 using blink::WebRTCPeerConnectionHandler;
 using blink::WebRTCPeerConnectionHandlerClient;
 using blink::WebThemeEngine;
-using WebTestRunner::WebTestDelegate;
-using WebTestRunner::WebTestInterfaces;
 
 namespace content {
 
diff --git a/content/shell/renderer/shell_render_process_observer.cc b/content/shell/renderer/shell_render_process_observer.cc
index 9760c64..6b32d7a 100644
--- a/content/shell/renderer/shell_render_process_observer.cc
+++ b/content/shell/renderer/shell_render_process_observer.cc
@@ -20,8 +20,6 @@
 
 using blink::WebFrame;
 using blink::WebRuntimeFeatures;
-using WebTestRunner::WebTestDelegate;
-using WebTestRunner::WebTestInterfaces;
 
 namespace content {
 
diff --git a/content/shell/renderer/shell_render_process_observer.h b/content/shell/renderer/shell_render_process_observer.h
index ffe59e2..1a42e8a 100644
--- a/content/shell/renderer/shell_render_process_observer.h
+++ b/content/shell/renderer/shell_render_process_observer.h
@@ -16,15 +16,12 @@
 class WebFrame;
 }
 
-namespace WebTestRunner {
-class WebTestDelegate;
-class WebTestInterfaces;
-}
-
 namespace content {
 
 class RenderView;
 class WebKitTestRunner;
+class WebTestDelegate;
+class WebTestInterfaces;
 
 class ShellRenderProcessObserver : public RenderProcessObserver {
  public:
@@ -33,7 +30,7 @@
   ShellRenderProcessObserver();
   virtual ~ShellRenderProcessObserver();
 
-  void SetTestDelegate(WebTestRunner::WebTestDelegate* delegate);
+  void SetTestDelegate(WebTestDelegate* delegate);
   void SetMainWindow(RenderView* view);
 
   // RenderProcessObserver implementation.
@@ -41,10 +38,10 @@
   virtual void OnRenderProcessShutdown() OVERRIDE;
   virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE;
 
-  WebTestRunner::WebTestDelegate* test_delegate() const {
+  WebTestDelegate* test_delegate() const {
     return test_delegate_;
   }
-  WebTestRunner::WebTestInterfaces* test_interfaces() const {
+  WebTestInterfaces* test_interfaces() const {
     return test_interfaces_.get();
   }
   WebKitTestRunner* main_test_runner() const { return main_test_runner_; }
@@ -56,8 +53,8 @@
   void OnSetWebKitSourceDir(const base::FilePath& webkit_source_dir);
 
   WebKitTestRunner* main_test_runner_;
-  WebTestRunner::WebTestDelegate* test_delegate_;
-  scoped_ptr<WebTestRunner::WebTestInterfaces> test_interfaces_;
+  WebTestDelegate* test_delegate_;
+  scoped_ptr<WebTestInterfaces> test_interfaces_;
 
   base::FilePath webkit_source_dir_;
 
diff --git a/content/shell/renderer/test_runner/MockColorChooser.cpp b/content/shell/renderer/test_runner/MockColorChooser.cpp
index c9321fc..cd7609b 100644
--- a/content/shell/renderer/test_runner/MockColorChooser.cpp
+++ b/content/shell/renderer/test_runner/MockColorChooser.cpp
@@ -7,7 +7,6 @@
 #include "content/shell/renderer/test_runner/WebTestDelegate.h"
 #include "content/shell/renderer/test_runner/WebTestProxy.h"
 
-using namespace WebTestRunner;
 using namespace blink;
 using namespace std;
 
diff --git a/content/shell/renderer/test_runner/MockColorChooser.h b/content/shell/renderer/test_runner/MockColorChooser.h
index 5a71f92..a4a269a 100644
--- a/content/shell/renderer/test_runner/MockColorChooser.h
+++ b/content/shell/renderer/test_runner/MockColorChooser.h
@@ -11,17 +11,14 @@
 #include "third_party/WebKit/public/web/WebColorChooser.h"
 #include "third_party/WebKit/public/web/WebColorChooserClient.h"
 
-namespace WebTestRunner {
-class WebTestDelegate;
-}
-
 namespace content {
 
+class WebTestDelegate;
 class WebTestProxyBase;
 
 class MockColorChooser : public blink::WebColorChooser {
 public:
-    MockColorChooser(blink::WebColorChooserClient*, WebTestRunner::WebTestDelegate*, content::WebTestProxyBase*);
+    MockColorChooser(blink::WebColorChooserClient*, WebTestDelegate*, WebTestProxyBase*);
     virtual ~MockColorChooser();
 
     // blink::WebColorChooser implementation.
@@ -29,13 +26,13 @@
     virtual void endChooser() OVERRIDE;
 
     void invokeDidEndChooser();
-    WebTestRunner::WebTaskList* taskList() { return &m_taskList; }
+    WebTaskList* taskList() { return &m_taskList; }
 
 private:
     blink::WebColorChooserClient* m_client;
-    WebTestRunner::WebTestDelegate* m_delegate;
-    content::WebTestProxyBase* m_proxy;
-    WebTestRunner::WebTaskList m_taskList;
+    WebTestDelegate* m_delegate;
+    WebTestProxyBase* m_proxy;
+    WebTaskList m_taskList;
 
     DISALLOW_COPY_AND_ASSIGN(MockColorChooser);
 };
diff --git a/content/shell/renderer/test_runner/MockGrammarCheck.cpp b/content/shell/renderer/test_runner/MockGrammarCheck.cpp
index 960129a..9bf1e32 100644
--- a/content/shell/renderer/test_runner/MockGrammarCheck.cpp
+++ b/content/shell/renderer/test_runner/MockGrammarCheck.cpp
@@ -21,7 +21,7 @@
 {
     DCHECK(results);
     base::string16 stringText = text;
-    if (find_if(stringText.begin(), stringText.end(), WebTestRunner::isASCIIAlpha) == stringText.end())
+    if (find_if(stringText.begin(), stringText.end(), isASCIIAlpha) == stringText.end())
         return true;
 
     // Find matching grammatical errors from known ones. This function has to
diff --git a/content/shell/renderer/test_runner/MockSpellCheck.cpp b/content/shell/renderer/test_runner/MockSpellCheck.cpp
index 033fd6b..6342c6c 100644
--- a/content/shell/renderer/test_runner/MockSpellCheck.cpp
+++ b/content/shell/renderer/test_runner/MockSpellCheck.cpp
@@ -11,7 +11,7 @@
 using namespace blink;
 using namespace std;
 
-namespace WebTestRunner {
+namespace content {
 
 namespace {
 
@@ -182,4 +182,4 @@
     return false;
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/MockSpellCheck.h b/content/shell/renderer/test_runner/MockSpellCheck.h
index 86918da..46f4a05 100644
--- a/content/shell/renderer/test_runner/MockSpellCheck.h
+++ b/content/shell/renderer/test_runner/MockSpellCheck.h
@@ -12,7 +12,7 @@
 #include "third_party/WebKit/public/platform/WebVector.h"
 #include "third_party/WebKit/public/web/WebTextCheckingResult.h"
 
-namespace WebTestRunner {
+namespace content {
 
 // A mock implementation of a spell-checker used for WebKit tests.
 // This class only implements the minimal functionarities required by WebKit
@@ -64,6 +64,6 @@
     DISALLOW_COPY_AND_ASSIGN(MockSpellCheck);
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_MOCKSPELLCHECK_H_
diff --git a/content/shell/renderer/test_runner/MockWebAudioDevice.cpp b/content/shell/renderer/test_runner/MockWebAudioDevice.cpp
index b3bc688..4ca2cd5 100644
--- a/content/shell/renderer/test_runner/MockWebAudioDevice.cpp
+++ b/content/shell/renderer/test_runner/MockWebAudioDevice.cpp
@@ -4,9 +4,7 @@
 
 #include "content/shell/renderer/test_runner/MockWebAudioDevice.h"
 
-using namespace blink;
-
-namespace WebTestRunner {
+namespace content {
 
 MockWebAudioDevice::MockWebAudioDevice(double sampleRate)
     : m_sampleRate(sampleRate)
@@ -30,4 +28,4 @@
     return m_sampleRate;
 }
 
-} // namespace WebTestRunner
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/MockWebAudioDevice.h b/content/shell/renderer/test_runner/MockWebAudioDevice.h
index 54cd345..a18fa6d 100644
--- a/content/shell/renderer/test_runner/MockWebAudioDevice.h
+++ b/content/shell/renderer/test_runner/MockWebAudioDevice.h
@@ -9,7 +9,7 @@
 #include "content/shell/renderer/test_runner/TestCommon.h"
 #include "third_party/WebKit/public/platform/WebAudioDevice.h"
 
-namespace WebTestRunner {
+namespace content {
 
 class MockWebAudioDevice : public blink::WebAudioDevice {
 public:
@@ -26,6 +26,6 @@
     DISALLOW_COPY_AND_ASSIGN(MockWebAudioDevice);
 };
 
-} // namespace WebTestRunner
+} // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_MOCKWEBAUDIODEVICE_H_
diff --git a/content/shell/renderer/test_runner/MockWebMIDIAccessor.cpp b/content/shell/renderer/test_runner/MockWebMIDIAccessor.cpp
index 383f6a4..940c806 100644
--- a/content/shell/renderer/test_runner/MockWebMIDIAccessor.cpp
+++ b/content/shell/renderer/test_runner/MockWebMIDIAccessor.cpp
@@ -12,12 +12,14 @@
 
 using namespace blink;
 
+namespace content {
+
 namespace {
 
-class DidStartSessionTask : public WebTestRunner::WebMethodTask<WebTestRunner::MockWebMIDIAccessor> {
+class DidStartSessionTask : public WebMethodTask<MockWebMIDIAccessor> {
 public:
-    DidStartSessionTask(WebTestRunner::MockWebMIDIAccessor* object, blink::WebMIDIAccessorClient* client, bool result)
-        : WebMethodTask<WebTestRunner::MockWebMIDIAccessor>(object)
+    DidStartSessionTask(MockWebMIDIAccessor* object, blink::WebMIDIAccessorClient* client, bool result)
+        : WebMethodTask<MockWebMIDIAccessor>(object)
         , m_client(client)
         , m_result(result)
     {
@@ -25,7 +27,7 @@
 
     virtual void runIfValid() OVERRIDE
     {
-        m_client->didStartSession(m_result);
+        m_client->didStartSession(m_result, "InvalidStateError", "");
     }
 
 private:
@@ -33,9 +35,7 @@
     bool m_result;
 };
 
-} // namespace
-
-namespace WebTestRunner {
+}  // namespace
 
 MockWebMIDIAccessor::MockWebMIDIAccessor(blink::WebMIDIAccessorClient* client, TestInterfaces* interfaces)
     : m_client(client)
@@ -55,4 +55,4 @@
     m_interfaces->delegate()->postTask(new DidStartSessionTask(this, m_client, m_interfaces->testRunner()->midiAccessorResult()));
 }
 
-} // namespace WebTestRunner
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/MockWebMIDIAccessor.h b/content/shell/renderer/test_runner/MockWebMIDIAccessor.h
index 6298d35..302c5bf 100644
--- a/content/shell/renderer/test_runner/MockWebMIDIAccessor.h
+++ b/content/shell/renderer/test_runner/MockWebMIDIAccessor.h
@@ -14,7 +14,7 @@
 class WebMIDIAccessorClient;
 }
 
-namespace WebTestRunner {
+namespace content {
 
 class TestInterfaces;
 
@@ -25,11 +25,10 @@
 
     // blink::WebMIDIAccessor implementation.
     virtual void startSession() OVERRIDE;
-    virtual void sendMIDIData(
-        unsigned portIndex,
-        const unsigned char* data,
-        size_t length,
-        double timestamp) OVERRIDE { }
+    virtual void sendMIDIData(unsigned portIndex,
+                              const unsigned char* data,
+                              size_t length,
+                              double timestamp) OVERRIDE {}
 
     // WebTask related methods
     WebTaskList* taskList() { return &m_taskList; }
@@ -42,6 +41,6 @@
     DISALLOW_COPY_AND_ASSIGN(MockWebMIDIAccessor);
 };
 
-} // namespace WebTestRunner
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_MOCKWEBMIDIACCESSOR_H_
diff --git a/content/shell/renderer/test_runner/MockWebMediaStreamCenter.cpp b/content/shell/renderer/test_runner/MockWebMediaStreamCenter.cpp
index a937b1a..e5d0d39 100644
--- a/content/shell/renderer/test_runner/MockWebMediaStreamCenter.cpp
+++ b/content/shell/renderer/test_runner/MockWebMediaStreamCenter.cpp
@@ -19,7 +19,7 @@
 
 using namespace blink;
 
-namespace WebTestRunner {
+namespace content {
 
 class NewTrackTask : public WebMethodTask<MockWebMediaStreamCenter> {
 public:
@@ -123,4 +123,4 @@
     return NULL;
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/MockWebMediaStreamCenter.h b/content/shell/renderer/test_runner/MockWebMediaStreamCenter.h
index fbc67a7..2aee2b8 100644
--- a/content/shell/renderer/test_runner/MockWebMediaStreamCenter.h
+++ b/content/shell/renderer/test_runner/MockWebMediaStreamCenter.h
@@ -16,7 +16,7 @@
 class WebMediaStreamCenterClient;
 };
 
-namespace WebTestRunner {
+namespace content {
 
 class TestInterfaces;
 
@@ -45,6 +45,6 @@
     DISALLOW_COPY_AND_ASSIGN(MockWebMediaStreamCenter);
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_MOCKWEBMEDIASTREAMCENTER_H_
diff --git a/content/shell/renderer/test_runner/MockWebRTCDTMFSenderHandler.cpp b/content/shell/renderer/test_runner/MockWebRTCDTMFSenderHandler.cpp
index 223c16d..4ab7159 100644
--- a/content/shell/renderer/test_runner/MockWebRTCDTMFSenderHandler.cpp
+++ b/content/shell/renderer/test_runner/MockWebRTCDTMFSenderHandler.cpp
@@ -12,7 +12,7 @@
 
 using namespace blink;
 
-namespace WebTestRunner {
+namespace content {
 
 class DTMFSenderToneTask : public WebMethodTask<MockWebRTCDTMFSenderHandler> {
 public:
@@ -70,4 +70,4 @@
     return true;
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/MockWebRTCDTMFSenderHandler.h b/content/shell/renderer/test_runner/MockWebRTCDTMFSenderHandler.h
index 7062f57..82425ff 100644
--- a/content/shell/renderer/test_runner/MockWebRTCDTMFSenderHandler.h
+++ b/content/shell/renderer/test_runner/MockWebRTCDTMFSenderHandler.h
@@ -12,7 +12,7 @@
 #include "third_party/WebKit/public/platform/WebRTCDTMFSenderHandler.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 
-namespace WebTestRunner {
+namespace content {
 
 class WebTestDelegate;
 
@@ -43,6 +43,6 @@
     DISALLOW_COPY_AND_ASSIGN(MockWebRTCDTMFSenderHandler);
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_MOCKWEBRTCDTMFSENDERHANDLER_H_
diff --git a/content/shell/renderer/test_runner/MockWebRTCDataChannelHandler.cpp b/content/shell/renderer/test_runner/MockWebRTCDataChannelHandler.cpp
index f70fa00..9308557 100644
--- a/content/shell/renderer/test_runner/MockWebRTCDataChannelHandler.cpp
+++ b/content/shell/renderer/test_runner/MockWebRTCDataChannelHandler.cpp
@@ -11,7 +11,7 @@
 
 using namespace blink;
 
-namespace WebTestRunner {
+namespace content {
 
 class DataChannelReadyStateTask : public WebMethodTask<MockWebRTCDataChannelHandler> {
 public:
@@ -115,4 +115,4 @@
     m_delegate->postTask(new DataChannelReadyStateTask(this, m_client, WebRTCDataChannelHandlerClient::ReadyStateClosed));
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/MockWebRTCDataChannelHandler.h b/content/shell/renderer/test_runner/MockWebRTCDataChannelHandler.h
index db1e6c4..6d2d604 100644
--- a/content/shell/renderer/test_runner/MockWebRTCDataChannelHandler.h
+++ b/content/shell/renderer/test_runner/MockWebRTCDataChannelHandler.h
@@ -12,7 +12,7 @@
 #include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 
-namespace WebTestRunner {
+namespace content {
 
 class WebTestDelegate;
 
@@ -50,6 +50,6 @@
     DISALLOW_COPY_AND_ASSIGN(MockWebRTCDataChannelHandler);
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_MOCKWEBRTCDATACHANNELHANDLER_H_
diff --git a/content/shell/renderer/test_runner/MockWebRTCPeerConnectionHandler.cpp b/content/shell/renderer/test_runner/MockWebRTCPeerConnectionHandler.cpp
index cfdbe54..831d2fb 100644
--- a/content/shell/renderer/test_runner/MockWebRTCPeerConnectionHandler.cpp
+++ b/content/shell/renderer/test_runner/MockWebRTCPeerConnectionHandler.cpp
@@ -20,9 +20,8 @@
 #include "third_party/WebKit/public/platform/WebVector.h"
 
 using namespace blink;
-using namespace content;
 
-namespace WebTestRunner {
+namespace content {
 
 class RTCSessionDescriptionRequestSuccededTask : public WebMethodTask<MockWebRTCPeerConnectionHandler> {
 public:
@@ -283,4 +282,4 @@
     m_stopped = true;
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/MockWebRTCPeerConnectionHandler.h b/content/shell/renderer/test_runner/MockWebRTCPeerConnectionHandler.h
index cff8864..18ccf87 100644
--- a/content/shell/renderer/test_runner/MockWebRTCPeerConnectionHandler.h
+++ b/content/shell/renderer/test_runner/MockWebRTCPeerConnectionHandler.h
@@ -17,7 +17,7 @@
 class WebRTCPeerConnectionHandlerClient;
 };
 
-namespace WebTestRunner {
+namespace content {
 
 class TestInterfaces;
 
@@ -60,6 +60,6 @@
     DISALLOW_COPY_AND_ASSIGN(MockWebRTCPeerConnectionHandler);
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_MOCKWEBRTCPEERCONNECTIONHANDLER_H_
diff --git a/content/shell/renderer/test_runner/MockWebSpeechInputController.cpp b/content/shell/renderer/test_runner/MockWebSpeechInputController.cpp
deleted file mode 100644
index 07526b0..0000000
--- a/content/shell/renderer/test_runner/MockWebSpeechInputController.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2013 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.
-
-#include "content/shell/renderer/test_runner/MockWebSpeechInputController.h"
-
-#include "base/logging.h"
-#include "content/shell/renderer/test_runner/WebTestDelegate.h"
-#include "third_party/WebKit/public/platform/WebCString.h"
-#include "third_party/WebKit/public/platform/WebVector.h"
-#include "third_party/WebKit/public/web/WebSpeechInputListener.h"
-
-#if ENABLE_INPUT_SPEECH
-
-using namespace blink;
-using namespace std;
-
-namespace WebTestRunner {
-
-namespace {
-
-WebSpeechInputResultArray makeRectResult(const WebRect& rect)
-{
-    char buffer[100];
-    snprintf(buffer, sizeof(buffer), "%d,%d,%d,%d", rect.x, rect.y, rect.width, rect.height);
-
-    WebSpeechInputResult res;
-    res.assign(WebString::fromUTF8(static_cast<const char*>(buffer)), 1.0);
-
-    WebSpeechInputResultArray results;
-    results.assign(&res, 1);
-    return results;
-}
-
-}
-
-MockWebSpeechInputController::MockWebSpeechInputController(WebSpeechInputListener* listener)
-    : m_listener(listener)
-    , m_speechTask(0)
-    , m_recording(false)
-    , m_requestId(-1)
-    , m_dumpRect(false)
-    , m_delegate(0)
-{
-}
-
-MockWebSpeechInputController::~MockWebSpeechInputController()
-{
-}
-
-void MockWebSpeechInputController::setDelegate(WebTestDelegate* delegate)
-{
-    m_delegate = delegate;
-}
-
-void MockWebSpeechInputController::addMockRecognitionResult(const WebString& result, double confidence, const WebString& language)
-{
-    WebSpeechInputResult res;
-    res.assign(result, confidence);
-
-    if (language.isEmpty())
-        m_resultsForEmptyLanguage.push_back(res);
-    else {
-        string langString = language.utf8();
-        if (m_recognitionResults.find(langString) == m_recognitionResults.end())
-            m_recognitionResults[langString] = vector<WebSpeechInputResult>();
-        m_recognitionResults[langString].push_back(res);
-    }
-}
-
-void MockWebSpeechInputController::setDumpRect(bool dumpRect)
-{
-    m_dumpRect = dumpRect;
-}
-
-void MockWebSpeechInputController::clearResults()
-{
-    m_resultsForEmptyLanguage.clear();
-    m_recognitionResults.clear();
-    m_dumpRect = false;
-}
-
-bool MockWebSpeechInputController::startRecognition(int requestId, const WebRect& elementRect, const WebString& language, const WebString& grammar, const WebSecurityOrigin& origin)
-{
-    if (m_speechTask)
-        return false;
-
-    m_requestId = requestId;
-    m_requestRect = elementRect;
-    m_recording = true;
-    m_language = language.utf8();
-
-    m_speechTask = new SpeechTask(this);
-    m_delegate->postTask(m_speechTask);
-
-    return true;
-}
-
-void MockWebSpeechInputController::cancelRecognition(int requestId)
-{
-    if (m_speechTask) {
-        DCHECK_EQ(requestId, m_requestId);
-
-        m_speechTask->stop();
-        m_recording = false;
-        m_listener->didCompleteRecognition(m_requestId);
-        m_requestId = 0;
-    }
-}
-
-void MockWebSpeechInputController::stopRecording(int requestId)
-{
-    DCHECK_EQ(requestId, m_requestId);
-    if (m_speechTask && m_recording) {
-        m_speechTask->stop();
-        speechTaskFired();
-    }
-}
-
-void MockWebSpeechInputController::speechTaskFired()
-{
-    if (m_recording) {
-        m_recording = false;
-        m_listener->didCompleteRecording(m_requestId);
-
-        m_speechTask = new SpeechTask(this);
-        m_delegate->postTask(m_speechTask);
-    } else {
-        bool noResultsFound = false;
-        // We take a copy of the requestId here so that if scripts destroyed the input element
-        // inside one of the callbacks below, we'll still know what this session's requestId was.
-        int requestId = m_requestId;
-        m_requestId = 0;
-
-        if (m_dumpRect) {
-            m_listener->setRecognitionResult(requestId, makeRectResult(m_requestRect));
-        } else if (m_language.empty()) {
-            // Empty language case must be handled separately to avoid problems with HashMap and empty keys.
-            if (!m_resultsForEmptyLanguage.empty())
-                m_listener->setRecognitionResult(requestId, m_resultsForEmptyLanguage);
-            else
-                noResultsFound = true;
-        } else {
-            if (m_recognitionResults.find(m_language) != m_recognitionResults.end())
-                m_listener->setRecognitionResult(requestId, m_recognitionResults[m_language]);
-            else
-                noResultsFound = true;
-        }
-
-        if (noResultsFound) {
-            // Can't avoid setting a result even if no result was set for the given language.
-            // This would avoid generating the events used to check the results and the test would timeout.
-            string error("error: no result found for language '");
-            error.append(m_language);
-            error.append("'");
-
-            WebSpeechInputResult res;
-            res.assign(WebString::fromUTF8(error), 1.0);
-
-            vector<WebSpeechInputResult> results;
-            results.push_back(res);
-
-            m_listener->setRecognitionResult(requestId, results);
-        }
-    }
-}
-
-MockWebSpeechInputController::SpeechTask::SpeechTask(MockWebSpeechInputController* mock)
-    : WebMethodTask<MockWebSpeechInputController>::WebMethodTask(mock)
-{
-}
-
-void MockWebSpeechInputController::SpeechTask::stop()
-{
-    m_object->m_speechTask = 0;
-    cancel();
-}
-
-void MockWebSpeechInputController::SpeechTask::runIfValid()
-{
-    m_object->m_speechTask = 0;
-    m_object->speechTaskFired();
-}
-
-}
-
-#endif
diff --git a/content/shell/renderer/test_runner/MockWebSpeechInputController.h b/content/shell/renderer/test_runner/MockWebSpeechInputController.h
deleted file mode 100644
index eb62d12..0000000
--- a/content/shell/renderer/test_runner/MockWebSpeechInputController.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CONTENT_SHELL_RENDERER_TEST_RUNNER_MOCKWEBSPEECHINPUTCONTROLLER_H_
-#define CONTENT_SHELL_RENDERER_TEST_RUNNER_MOCKWEBSPEECHINPUTCONTROLLER_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "content/shell/renderer/test_runner/TestCommon.h"
-#include "content/shell/renderer/test_runner/WebTask.h"
-#include "third_party/WebKit/public/platform/WebRect.h"
-#include "third_party/WebKit/public/web/WebSpeechInputController.h"
-#include "third_party/WebKit/public/web/WebSpeechInputResult.h"
-
-namespace blink {
-class WebSecurityOrigin;
-class WebSpeechInputListener;
-class WebString;
-}
-
-namespace WebTestRunner {
-
-class WebTestDelegate;
-
-class MockWebSpeechInputController : public blink::WebSpeechInputController {
-public:
-    explicit MockWebSpeechInputController(blink::WebSpeechInputListener*);
-    virtual ~MockWebSpeechInputController();
-
-    void addMockRecognitionResult(const blink::WebString& result, double confidence, const blink::WebString& language);
-    void setDumpRect(bool);
-    void clearResults();
-    void setDelegate(WebTestDelegate*);
-
-    // WebSpeechInputController implementation:
-    virtual bool startRecognition(int requestId, const blink::WebRect& elementRect, const blink::WebString& language, const blink::WebString& grammar, const blink::WebSecurityOrigin&) OVERRIDE;
-    virtual void cancelRecognition(int requestId) OVERRIDE;
-    virtual void stopRecording(int requestId) OVERRIDE;
-
-    WebTaskList* taskList() { return &m_taskList; }
-
-private:
-    void speechTaskFired();
-
-    class SpeechTask : public WebMethodTask<MockWebSpeechInputController> {
-    public:
-        SpeechTask(MockWebSpeechInputController*);
-        void stop();
-
-    private:
-        virtual void runIfValid() OVERRIDE;
-    };
-
-    blink::WebSpeechInputListener* m_listener;
-
-    WebTaskList m_taskList;
-    SpeechTask* m_speechTask;
-
-    bool m_recording;
-    int m_requestId;
-    blink::WebRect m_requestRect;
-    std::string m_language;
-
-    std::map<std::string, std::vector<blink::WebSpeechInputResult> > m_recognitionResults;
-    std::vector<blink::WebSpeechInputResult> m_resultsForEmptyLanguage;
-    bool m_dumpRect;
-
-    WebTestDelegate* m_delegate;
-
-    DISALLOW_COPY_AND_ASSIGN(MockWebSpeechInputController);
-};
-
-}
-
-#endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_MOCKWEBSPEECHINPUTCONTROLLER_H_
diff --git a/content/shell/renderer/test_runner/MockWebSpeechRecognizer.cpp b/content/shell/renderer/test_runner/MockWebSpeechRecognizer.cpp
index 8aa232d..1d44c9d 100644
--- a/content/shell/renderer/test_runner/MockWebSpeechRecognizer.cpp
+++ b/content/shell/renderer/test_runner/MockWebSpeechRecognizer.cpp
@@ -12,7 +12,7 @@
 using namespace blink;
 using namespace std;
 
-namespace WebTestRunner {
+namespace content {
 
 namespace {
 
@@ -224,4 +224,4 @@
     m_object->m_delegate->postTask(new StepTask(m_object));
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/MockWebSpeechRecognizer.h b/content/shell/renderer/test_runner/MockWebSpeechRecognizer.h
index fd6e138..fa1a606 100644
--- a/content/shell/renderer/test_runner/MockWebSpeechRecognizer.h
+++ b/content/shell/renderer/test_runner/MockWebSpeechRecognizer.h
@@ -19,7 +19,7 @@
 class WebSpeechRecognizerClient;
 }
 
-namespace WebTestRunner {
+namespace content {
 
 class WebTestDelegate;
 
@@ -81,6 +81,6 @@
     DISALLOW_COPY_AND_ASSIGN(MockWebSpeechRecognizer);
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_MOCKWEBSPEECHRECOGNIZER_H_
diff --git a/content/shell/renderer/test_runner/SpellCheckClient.cpp b/content/shell/renderer/test_runner/SpellCheckClient.cpp
index 3be3d0e..3e8d47d 100644
--- a/content/shell/renderer/test_runner/SpellCheckClient.cpp
+++ b/content/shell/renderer/test_runner/SpellCheckClient.cpp
@@ -11,10 +11,9 @@
 #include "third_party/WebKit/public/web/WebTextCheckingResult.h"
 
 using namespace blink;
-using namespace content;
 using namespace std;
 
-namespace WebTestRunner {
+namespace content {
 
 namespace {
 
@@ -32,7 +31,7 @@
     CallbackMethodType m_callback;
 };
 
-}
+}  // namespace
 
 SpellCheckClient::SpellCheckClient(WebTestProxyBase* webTestProxy)
     : m_lastRequestedTextCheckingCompletion(0)
@@ -141,4 +140,4 @@
     return WebString();
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/SpellCheckClient.h b/content/shell/renderer/test_runner/SpellCheckClient.h
index a2b26a7..d7efa92 100644
--- a/content/shell/renderer/test_runner/SpellCheckClient.h
+++ b/content/shell/renderer/test_runner/SpellCheckClient.h
@@ -11,16 +11,13 @@
 #include "third_party/WebKit/public/web/WebSpellCheckClient.h"
 
 namespace content {
-class WebTestProxyBase;
-}
-
-namespace WebTestRunner {
 
 class WebTestDelegate;
+class WebTestProxyBase;
 
 class SpellCheckClient : public blink::WebSpellCheckClient {
 public:
-    explicit SpellCheckClient(content::WebTestProxyBase*);
+    explicit SpellCheckClient(WebTestProxyBase*);
     virtual ~SpellCheckClient();
 
     void setDelegate(WebTestDelegate*);
@@ -50,11 +47,11 @@
 
     WebTestDelegate* m_delegate;
 
-    content::WebTestProxyBase* m_webTestProxy;
+    WebTestProxyBase* m_webTestProxy;
 
     DISALLOW_COPY_AND_ASSIGN(SpellCheckClient);
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_SPELLCHECKCLIENT_H_
diff --git a/content/shell/renderer/test_runner/TestCommon.cpp b/content/shell/renderer/test_runner/TestCommon.cpp
index 691ecdd..24e642d 100644
--- a/content/shell/renderer/test_runner/TestCommon.cpp
+++ b/content/shell/renderer/test_runner/TestCommon.cpp
@@ -6,7 +6,7 @@
 
 using namespace std;
 
-namespace WebTestRunner {
+namespace content {
 
 namespace {
 
@@ -17,7 +17,7 @@
 const char dataUrlPattern[] = "data:";
 const string::size_type dataUrlPatternSize = sizeof(dataUrlPattern) - 1;
 
-}
+}  // namespace
 
 string normalizeLayoutTestURL(const string& url)
 {
@@ -34,4 +34,4 @@
     return result;
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/TestCommon.h b/content/shell/renderer/test_runner/TestCommon.h
index bdf3ea7..7144158 100644
--- a/content/shell/renderer/test_runner/TestCommon.h
+++ b/content/shell/renderer/test_runner/TestCommon.h
@@ -14,7 +14,7 @@
 #define snprintf(str, size, ...) _snprintf_s(str, size, size, __VA_ARGS__)
 #endif
 
-namespace WebTestRunner {
+namespace content {
 
 inline bool isASCIIAlpha(char ch) { return (ch | 0x20) >= 'a' && (ch | 0x20) <= 'z'; }
 
@@ -22,6 +22,6 @@
 
 std::string normalizeLayoutTestURL(const std::string& url);
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_TESTCOMMON_H_
diff --git a/content/shell/renderer/test_runner/TestInterfaces.cpp b/content/shell/renderer/test_runner/TestInterfaces.cpp
index dca5d75..4c2e00d 100644
--- a/content/shell/renderer/test_runner/TestInterfaces.cpp
+++ b/content/shell/renderer/test_runner/TestInterfaces.cpp
@@ -24,22 +24,21 @@
 #include "third_party/WebKit/public/web/WebView.h"
 
 using namespace blink;
-using namespace content;
 using namespace std;
 
-namespace WebTestRunner {
+namespace content {
 
 TestInterfaces::TestInterfaces()
-    : m_accessibilityController(new content::AccessibilityController())
-    , m_eventSender(new content::EventSender(this))
-    , m_gamepadController(new content::GamepadController())
-    , m_textInputController(new content::TextInputController())
-    , m_testRunner(new content::TestRunner(this))
+    : m_accessibilityController(new AccessibilityController())
+    , m_eventSender(new EventSender(this))
+    , m_gamepadController(new GamepadController())
+    , m_textInputController(new TextInputController())
+    , m_testRunner(new TestRunner(this))
     , m_delegate(0)
 {
     blink::setLayoutTestMode(true);
-    if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableFontSmoothing))
-        blink::setFontSmoothingEnabledForTest(true);
+    if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableFontAntialiasing))
+        blink::setFontAntialiasingEnabledForTest(true);
 
     // NOTE: please don't put feature specific enable flags here,
     // instead add them to RuntimeEnabledFeatures.in
@@ -158,17 +157,17 @@
     m_windowList.erase(pos);
 }
 
-content::AccessibilityController* TestInterfaces::accessibilityController()
+AccessibilityController* TestInterfaces::accessibilityController()
 {
     return m_accessibilityController.get();
 }
 
-content::EventSender* TestInterfaces::eventSender()
+EventSender* TestInterfaces::eventSender()
 {
     return m_eventSender.get();
 }
 
-content::TestRunner* TestInterfaces::testRunner()
+TestRunner* TestInterfaces::testRunner()
 {
     return m_testRunner.get();
 }
@@ -202,4 +201,4 @@
     return m_themeEngine.get();
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/TestInterfaces.h b/content/shell/renderer/test_runner/TestInterfaces.h
index a287e27..0a6639a 100644
--- a/content/shell/renderer/test_runner/TestInterfaces.h
+++ b/content/shell/renderer/test_runner/TestInterfaces.h
@@ -25,24 +25,21 @@
 }
 
 namespace content {
+
 class AccessibilityController;
 class EventSender;
 class GamepadController;
 class TestRunner;
 class TextInputController;
-class WebTestProxyBase;
-}
-
-namespace WebTestRunner {
-
 class WebTestDelegate;
+class WebTestProxyBase;
 
 class TestInterfaces {
 public:
     TestInterfaces();
     ~TestInterfaces();
 
-    void setWebView(blink::WebView*, content::WebTestProxyBase*);
+    void setWebView(blink::WebView*, WebTestProxyBase*);
     void setDelegate(WebTestDelegate*);
     void bindTo(blink::WebFrame*);
     void resetTestHelperControllers();
@@ -50,27 +47,27 @@
     void setTestIsRunning(bool);
     void configureForTestWithURL(const blink::WebURL&, bool generatePixels);
 
-    void windowOpened(content::WebTestProxyBase*);
-    void windowClosed(content::WebTestProxyBase*);
+    void windowOpened(WebTestProxyBase*);
+    void windowClosed(WebTestProxyBase*);
 
-    content::AccessibilityController* accessibilityController();
-    content::EventSender* eventSender();
-    content::TestRunner* testRunner();
+    AccessibilityController* accessibilityController();
+    EventSender* eventSender();
+    TestRunner* testRunner();
     WebTestDelegate* delegate();
-    content::WebTestProxyBase* proxy();
-    const std::vector<content::WebTestProxyBase*>& windowList();
+    WebTestProxyBase* proxy();
+    const std::vector<WebTestProxyBase*>& windowList();
     blink::WebThemeEngine* themeEngine();
 
 private:
-    scoped_ptr<content::AccessibilityController> m_accessibilityController;
-    scoped_ptr<content::EventSender> m_eventSender;
-    scoped_ptr<content::GamepadController> m_gamepadController;
-    scoped_ptr<content::TextInputController> m_textInputController;
-    scoped_ptr<content::TestRunner> m_testRunner;
+    scoped_ptr<AccessibilityController> m_accessibilityController;
+    scoped_ptr<EventSender> m_eventSender;
+    scoped_ptr<GamepadController> m_gamepadController;
+    scoped_ptr<TextInputController> m_textInputController;
+    scoped_ptr<TestRunner> m_testRunner;
     WebTestDelegate* m_delegate;
-    content::WebTestProxyBase* m_proxy;
+    WebTestProxyBase* m_proxy;
 
-    std::vector<content::WebTestProxyBase*> m_windowList;
+    std::vector<WebTestProxyBase*> m_windowList;
 #if defined(__APPLE__)
     scoped_ptr<WebTestThemeEngineMac> m_themeEngine;
 #else
@@ -80,6 +77,6 @@
     DISALLOW_COPY_AND_ASSIGN(TestInterfaces);
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_TESTINTERFACES_H_
diff --git a/content/shell/renderer/test_runner/TestPlugin.cpp b/content/shell/renderer/test_runner/TestPlugin.cpp
index 2606207..db9edc5 100644
--- a/content/shell/renderer/test_runner/TestPlugin.cpp
+++ b/content/shell/renderer/test_runner/TestPlugin.cpp
@@ -27,7 +27,7 @@
 using namespace blink;
 using namespace std;
 
-namespace WebTestRunner {
+namespace content {
 
 namespace {
 
@@ -296,7 +296,7 @@
     } else {
         size_t bytes = 4 * m_rect.width * m_rect.height;
         scoped_ptr<base::SharedMemory> bitmap =
-                content::RenderThread::Get()->HostAllocateSharedMemoryBuffer(bytes);
+            RenderThread::Get()->HostAllocateSharedMemoryBuffer(bytes);
         if (!bitmap->Map(bytes)) {
             m_textureMailbox = cc::TextureMailbox();
         } else {
@@ -690,4 +690,4 @@
            || mimeType == canCreateWithoutRendererMimeType();
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/TestPlugin.h b/content/shell/renderer/test_runner/TestPlugin.h
index d9cd7c6..8c1f06b 100644
--- a/content/shell/renderer/test_runner/TestPlugin.h
+++ b/content/shell/renderer/test_runner/TestPlugin.h
@@ -20,9 +20,9 @@
 
 namespace blink {
 class WebFrame;
-}  // namespace blink
+}
 
-namespace WebTestRunner {
+namespace content {
 
 class WebTestDelegate;
 
@@ -153,6 +153,6 @@
     DISALLOW_COPY_AND_ASSIGN(TestPlugin);
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_TESTPLUGIN_H_
diff --git a/content/shell/renderer/test_runner/WebFrameTestProxy.h b/content/shell/renderer/test_runner/WebFrameTestProxy.h
index 6002389..b9fa40a 100644
--- a/content/shell/renderer/test_runner/WebFrameTestProxy.h
+++ b/content/shell/renderer/test_runner/WebFrameTestProxy.h
@@ -202,6 +202,10 @@
         // RenderFrameImpl::willStartUsingPeerConnectionHandler can not be mocked.
         // See http://crbug/363285.
     }
+    virtual blink::WebUserMediaClient* userMediaClient()
+    {
+        return m_baseProxy->userMediaClient();
+    }
     virtual bool willCheckAndDispatchMessageEvent(blink::WebLocalFrame* sourceFrame, blink::WebFrame* targetFrame, blink::WebSecurityOrigin target, blink::WebDOMMessageEvent event)
     {
         if (m_baseProxy->willCheckAndDispatchMessageEvent(sourceFrame, targetFrame, target, event))
diff --git a/content/shell/renderer/test_runner/WebPermissions.cpp b/content/shell/renderer/test_runner/WebPermissions.cpp
index 77d2f1e..b2cfd74 100644
--- a/content/shell/renderer/test_runner/WebPermissions.cpp
+++ b/content/shell/renderer/test_runner/WebPermissions.cpp
@@ -9,7 +9,6 @@
 #include "third_party/WebKit/public/platform/WebCString.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
 
-using namespace WebTestRunner;
 using namespace std;
 
 namespace content {
diff --git a/content/shell/renderer/test_runner/WebPermissions.h b/content/shell/renderer/test_runner/WebPermissions.h
index f942d40..85330b6 100644
--- a/content/shell/renderer/test_runner/WebPermissions.h
+++ b/content/shell/renderer/test_runner/WebPermissions.h
@@ -9,12 +9,10 @@
 #include "third_party/WebKit/public/web/WebFrame.h"
 #include "third_party/WebKit/public/web/WebPermissionClient.h"
 
-namespace WebTestRunner {
-class WebTestDelegate;
-}
-
 namespace content {
 
+class WebTestDelegate;
+
 class WebPermissions : public blink::WebPermissionClient {
 public:
     WebPermissions();
@@ -39,11 +37,11 @@
     // Resets the policy to allow everything, except for running insecure content.
     void reset();
 
-    void setDelegate(WebTestRunner::WebTestDelegate*);
+    void setDelegate(WebTestDelegate*);
     void setDumpCallbacks(bool);
 
 private:
-    WebTestRunner::WebTestDelegate* m_delegate;
+    WebTestDelegate* m_delegate;
     bool m_dumpCallbacks;
 
     bool m_imagesAllowed;
diff --git a/content/shell/renderer/test_runner/WebTask.cpp b/content/shell/renderer/test_runner/WebTask.cpp
index 0a21971..43302e6 100644
--- a/content/shell/renderer/test_runner/WebTask.cpp
+++ b/content/shell/renderer/test_runner/WebTask.cpp
@@ -9,7 +9,7 @@
 
 using namespace std;
 
-namespace WebTestRunner {
+namespace content {
 
 WebTask::WebTask(WebTaskList* list)
     : m_taskList(list)
@@ -50,4 +50,4 @@
         m_tasks[0]->cancel();
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/WebTask.h b/content/shell/renderer/test_runner/WebTask.h
index 548cf82..6c7548b 100644
--- a/content/shell/renderer/test_runner/WebTask.h
+++ b/content/shell/renderer/test_runner/WebTask.h
@@ -7,7 +7,7 @@
 
 #include <vector>
 
-namespace WebTestRunner {
+namespace content {
 
 class WebTaskList;
 
@@ -72,6 +72,6 @@
     T* m_object;
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_WEBTASK_H_
diff --git a/content/shell/renderer/test_runner/WebTestDelegate.h b/content/shell/renderer/test_runner/WebTestDelegate.h
index fa4ef33..f63e31b 100644
--- a/content/shell/renderer/test_runner/WebTestDelegate.h
+++ b/content/shell/renderer/test_runner/WebTestDelegate.h
@@ -27,13 +27,10 @@
 }
 
 namespace content {
-class WebTestProxyBase;
-struct TestPreferences;
-}
-
-namespace WebTestRunner {
 
 class WebTask;
+class WebTestProxyBase;
+struct TestPreferences;
 
 class WebTestDelegate {
 public:
@@ -85,7 +82,7 @@
     virtual blink::WebURL rewriteLayoutTestsURL(const std::string& utf8URL) = 0;
 
     // Manages the settings to used for layout tests.
-    virtual content::TestPreferences* preferences() = 0;
+    virtual TestPreferences* preferences() = 0;
     virtual void applyPreferences() = 0;
 
     // Enables or disables synchronous resize mode. When enabled, all window-sizing machinery is
@@ -117,8 +114,11 @@
     // Controls the device scale factor of the main WebView for hidpi tests.
     virtual void setDeviceScaleFactor(float) = 0;
 
+    // Change the device color profile while running a layout test.
+    virtual void setDeviceColorProfile(const std::string& name) = 0;
+
     // Controls which WebView should be focused.
-    virtual void setFocus(content::WebTestProxyBase*, bool) = 0;
+    virtual void setFocus(WebTestProxyBase*, bool) = 0;
 
     // Controls whether all cookies should be accepted or writing cookies in a
     // third-party context is blocked.
@@ -152,9 +152,9 @@
 
     // Returns a text dump the back/forward history for the WebView associated
     // with the given WebTestProxyBase.
-    virtual std::string dumpHistoryForWindow(content::WebTestProxyBase*) = 0;
+    virtual std::string dumpHistoryForWindow(WebTestProxyBase*) = 0;
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_WEBTESTDELEGATE_H_
diff --git a/content/shell/renderer/test_runner/WebTestInterfaces.cpp b/content/shell/renderer/test_runner/WebTestInterfaces.cpp
index 38a359f..2178aef 100644
--- a/content/shell/renderer/test_runner/WebTestInterfaces.cpp
+++ b/content/shell/renderer/test_runner/WebTestInterfaces.cpp
@@ -12,9 +12,8 @@
 #include "content/shell/renderer/test_runner/test_runner.h"
 
 using namespace blink;
-using namespace content;
 
-namespace WebTestRunner {
+namespace content {
 
 WebTestInterfaces::WebTestInterfaces()
     : m_interfaces(new TestInterfaces())
@@ -90,4 +89,4 @@
     return new MockWebAudioDevice(sampleRate);
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/WebTestInterfaces.h b/content/shell/renderer/test_runner/WebTestInterfaces.h
index cfcc146..83764d4 100644
--- a/content/shell/renderer/test_runner/WebTestInterfaces.h
+++ b/content/shell/renderer/test_runner/WebTestInterfaces.h
@@ -22,13 +22,10 @@
 }
 
 namespace content {
-class WebTestProxyBase;
-}
-
-namespace WebTestRunner {
 
 class TestInterfaces;
 class WebTestDelegate;
+class WebTestProxyBase;
 class WebTestRunner;
 
 class WebTestInterfaces {
@@ -36,7 +33,7 @@
     WebTestInterfaces();
     ~WebTestInterfaces();
 
-    void setWebView(blink::WebView*, content::WebTestProxyBase*);
+    void setWebView(blink::WebView*, WebTestProxyBase*);
     void setDelegate(WebTestDelegate*);
     void bindTo(blink::WebFrame*);
     void resetAll();
@@ -59,6 +56,6 @@
     scoped_ptr<TestInterfaces> m_interfaces;
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_WEBTESTINTERFACES_H_
diff --git a/content/shell/renderer/test_runner/WebTestProxy.cpp b/content/shell/renderer/test_runner/WebTestProxy.cpp
index 7cc74a4..4295806 100644
--- a/content/shell/renderer/test_runner/WebTestProxy.cpp
+++ b/content/shell/renderer/test_runner/WebTestProxy.cpp
@@ -6,10 +6,11 @@
 
 #include <cctype>
 
+#include "base/callback_helpers.h"
+#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "content/shell/renderer/test_runner/event_sender.h"
 #include "content/shell/renderer/test_runner/MockColorChooser.h"
-#include "content/shell/renderer/test_runner/MockWebSpeechInputController.h"
 #include "content/shell/renderer/test_runner/MockWebSpeechRecognizer.h"
 #include "content/shell/renderer/test_runner/SpellCheckClient.h"
 #include "content/shell/renderer/test_runner/TestCommon.h"
@@ -44,7 +45,6 @@
 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
 #include "third_party/WebKit/public/web/WebView.h"
 
-using namespace WebTestRunner;
 using namespace blink;
 using namespace std;
 
@@ -340,10 +340,6 @@
 {
     m_delegate = delegate;
     m_spellcheck->setDelegate(delegate);
-#if ENABLE_INPUT_SPEECH
-    if (m_speechInputController.get())
-        m_speechInputController->setDelegate(delegate);
-#endif
     if (m_speechRecognizer.get())
         m_speechRecognizer->setDelegate(delegate);
 }
@@ -381,10 +377,6 @@
     m_logConsoleOutput = true;
     if (m_midiClient.get())
         m_midiClient->resetMock();
-#if ENABLE_INPUT_SPEECH
-    if (m_speechInputController.get())
-        m_speechInputController->clearResults();
-#endif
 }
 
 WebSpellCheckClient* WebTestProxyBase::spellCheckClient() const
@@ -420,12 +412,16 @@
 
 string WebTestProxyBase::captureTree(bool debugRenderTree)
 {
+    bool shouldDumpCustomText = m_testInterfaces->testRunner()->shouldDumpAsCustomText();
     bool shouldDumpAsText = m_testInterfaces->testRunner()->shouldDumpAsText();
     bool shouldDumpAsMarkup = m_testInterfaces->testRunner()->shouldDumpAsMarkup();
     bool shouldDumpAsPrinted = m_testInterfaces->testRunner()->isPrinting();
     WebFrame* frame = webView()->mainFrame();
     string dataUtf8;
-    if (shouldDumpAsText) {
+    if (shouldDumpCustomText) {
+        // Append a newline for the test driver.
+        dataUtf8 = m_testInterfaces->testRunner()->customDumpText() + "\n";
+    } else if (shouldDumpAsText) {
         bool recursive = m_testInterfaces->testRunner()->shouldDumpChildFramesAsText();
         dataUtf8 = shouldDumpAsPrinted ? dumpFramesAsPrintedText(frame, recursive) : dumpFramesAsText(frame, recursive);
     } else if (shouldDumpAsMarkup) {
@@ -450,34 +446,63 @@
 
 SkCanvas* WebTestProxyBase::capturePixels()
 {
+    TRACE_EVENT0("shell", "WebTestProxyBase::capturePixels");
     webWidget()->layout();
     if (m_testInterfaces->testRunner()->isPrinting())
         paintPagesWithBoundaries();
     else
         paintInvalidatedRegion();
 
-    // See if we need to draw the selection bounds rect. Selection bounds
-    // rect is the rect enclosing the (possibly transformed) selection.
-    // The rect should be drawn after everything is laid out and painted.
-    if (m_testInterfaces->testRunner()->shouldDumpSelectionRect()) {
-        // If there is a selection rect - draw a red 1px border enclosing rect
-        WebRect wr = webView()->mainFrame()->selectionBoundsRect();
-        if (!wr.isEmpty()) {
-            // Render a red rectangle bounding selection rect
-            SkPaint paint;
-            paint.setColor(0xFFFF0000); // Fully opaque red
-            paint.setStyle(SkPaint::kStroke_Style);
-            paint.setFlags(SkPaint::kAntiAlias_Flag);
-            paint.setStrokeWidth(1.0f);
-            SkIRect rect; // Bounding rect
-            rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height);
-            canvas()->drawIRect(rect, paint);
-        }
-    }
+    DrawSelectionRect(canvas());
 
     return canvas();
 }
 
+void WebTestProxyBase::DrawSelectionRect(SkCanvas* canvas) {
+  // See if we need to draw the selection bounds rect. Selection bounds
+  // rect is the rect enclosing the (possibly transformed) selection.
+  // The rect should be drawn after everything is laid out and painted.
+  if (!m_testInterfaces->testRunner()->shouldDumpSelectionRect())
+    return;
+  // If there is a selection rect - draw a red 1px border enclosing rect
+  WebRect wr = webView()->mainFrame()->selectionBoundsRect();
+  if (wr.isEmpty())
+    return;
+  // Render a red rectangle bounding selection rect
+  SkPaint paint;
+  paint.setColor(0xFFFF0000);  // Fully opaque red
+  paint.setStyle(SkPaint::kStroke_Style);
+  paint.setFlags(SkPaint::kAntiAlias_Flag);
+  paint.setStrokeWidth(1.0f);
+  SkIRect rect;  // Bounding rect
+  rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height);
+  canvas->drawIRect(rect, paint);
+}
+
+void WebTestProxyBase::didCompositeAndReadback(const SkBitmap& bitmap) {
+  TRACE_EVENT2("shell",
+               "WebTestProxyBase::didCompositeAndReadback",
+               "x",
+               bitmap.info().fWidth,
+               "y",
+               bitmap.info().fHeight);
+  SkCanvas canvas(bitmap);
+  DrawSelectionRect(&canvas);
+  DCHECK(!m_compositeAndReadbackCallback.is_null());
+  base::ResetAndReturn(&m_compositeAndReadbackCallback).Run(bitmap);
+}
+
+void WebTestProxyBase::CapturePixelsAsync(
+    base::Callback<void(const SkBitmap&)> callback) {
+  TRACE_EVENT0("shell", "WebTestProxyBase::CapturePixelsAsync");
+
+  DCHECK(webWidget()->isAcceleratedCompositingActive());
+  DCHECK(!callback.is_null());
+  DCHECK(m_compositeAndReadbackCallback.is_null());
+  m_compositeAndReadbackCallback = callback;
+  webWidget()->compositeAndReadbackAsync(this);
+}
+
 void WebTestProxyBase::setLogConsoleOutput(bool enabled)
 {
     m_logConsoleOutput = enabled;
@@ -605,14 +630,6 @@
     return m_midiClient.get();
 }
 
-#if ENABLE_INPUT_SPEECH
-MockWebSpeechInputController* WebTestProxyBase::speechInputControllerMock()
-{
-    DCHECK(m_speechInputController.get());
-    return m_speechInputController.get();
-}
-#endif
-
 MockWebSpeechRecognizer* WebTestProxyBase::speechRecognizerMock()
 {
     if (!m_speechRecognizer.get()) {
@@ -900,20 +917,6 @@
     return midiClientMock();
 }
 
-WebSpeechInputController* WebTestProxyBase::speechInputController(WebSpeechInputListener* listener)
-{
-#if ENABLE_INPUT_SPEECH
-    if (!m_speechInputController.get()) {
-        m_speechInputController.reset(new MockWebSpeechInputController(listener));
-        m_speechInputController->setDelegate(m_delegate);
-    }
-    return m_speechInputController.get();
-#else
-    DCHECK(listener);
-    return 0;
-#endif
-}
-
 WebSpeechRecognizer* WebTestProxyBase::speechRecognizer()
 {
     return speechRecognizerMock();
diff --git a/content/shell/renderer/test_runner/WebTestProxy.h b/content/shell/renderer/test_runner/WebTestProxy.h
index d87518e..7ecb38a 100644
--- a/content/shell/renderer/test_runner/WebTestProxy.h
+++ b/content/shell/renderer/test_runner/WebTestProxy.h
@@ -12,6 +12,7 @@
 #include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "content/shell/renderer/test_runner/WebTask.h"
+#include "third_party/WebKit/public/platform/WebCompositeAndReadbackAsyncCallback.h"
 #include "third_party/WebKit/public/platform/WebRect.h"
 #include "third_party/WebKit/public/platform/WebURLError.h"
 #include "third_party/WebKit/public/platform/WebURLRequest.h"
@@ -51,8 +52,6 @@
 class WebPlugin;
 class WebRange;
 class WebSerializedScriptValue;
-class WebSpeechInputController;
-class WebSpeechInputListener;
 class WebSpeechRecognizer;
 class WebSpellCheckClient;
 class WebString;
@@ -72,24 +71,20 @@
 typedef unsigned WebColor;
 }
 
-namespace WebTestRunner {
-class MockWebSpeechInputController;
+namespace content {
+
 class MockWebSpeechRecognizer;
+class RenderFrame;
 class SpellCheckClient;
 class TestInterfaces;
 class WebTestDelegate;
 class WebTestInterfaces;
 class WebUserMediaClientMock;
-}
 
-namespace content {
-
-class RenderFrame;
-
-class WebTestProxyBase {
+class WebTestProxyBase : public blink::WebCompositeAndReadbackAsyncCallback {
 public:
-    void setInterfaces(WebTestRunner::WebTestInterfaces*);
-    void setDelegate(WebTestRunner::WebTestDelegate*);
+    void setInterfaces(WebTestInterfaces*);
+    void setDelegate(WebTestDelegate*);
     void setWidget(blink::WebWidget*);
 
     void reset();
@@ -103,6 +98,7 @@
 
     std::string captureTree(bool debugRenderTree);
     SkCanvas* capturePixels();
+    void CapturePixelsAsync(base::Callback<void(const SkBitmap&)> callback);
 
     void setLogConsoleOutput(bool enabled);
 
@@ -119,10 +115,9 @@
     void discardBackingStore();
 
     blink::WebMIDIClientMock* midiClientMock();
-    WebTestRunner::MockWebSpeechInputController* speechInputControllerMock();
-    WebTestRunner::MockWebSpeechRecognizer* speechRecognizerMock();
+    MockWebSpeechRecognizer* speechRecognizerMock();
 
-    WebTestRunner::WebTaskList* taskList() { return &m_taskList; }
+    WebTaskList* taskList() { return &m_taskList; }
 
     blink::WebView* webView();
 
@@ -130,6 +125,9 @@
 
     void postSpellCheckEvent(const blink::WebString& eventName);
 
+    // WebCompositeAndReadbackAsyncCallback implementation.
+    virtual void didCompositeAndReadback(const SkBitmap& bitmap);
+
 protected:
     WebTestProxyBase();
     ~WebTestProxyBase();
@@ -156,7 +154,6 @@
     void printPage(blink::WebLocalFrame*);
     blink::WebNotificationPresenter* notificationPresenter();
     blink::WebMIDIClient* webMIDIClient();
-    blink::WebSpeechInputController* speechInputController(blink::WebSpeechInputListener*);
     blink::WebSpeechRecognizer* speechRecognizer();
     bool requestPointerLock();
     void requestPointerUnlock();
@@ -197,17 +194,18 @@
     SkCanvas* canvas();
     void invalidateAll();
     void animateNow();
+    void DrawSelectionRect(SkCanvas* canvas);
 
     blink::WebWidget* webWidget();
 
-    WebTestRunner::TestInterfaces* m_testInterfaces;
-    ::WebTestRunner::WebTestDelegate* m_delegate;
+    TestInterfaces* m_testInterfaces;
+    WebTestDelegate* m_delegate;
     blink::WebWidget* m_webWidget;
 
-    WebTestRunner::WebTaskList m_taskList;
+    WebTaskList m_taskList;
 
-    scoped_ptr<WebTestRunner::SpellCheckClient> m_spellcheck;
-    scoped_ptr<WebTestRunner::WebUserMediaClientMock> m_userMediaClient;
+    scoped_ptr<SpellCheckClient> m_spellcheck;
+    scoped_ptr<WebUserMediaClientMock> m_userMediaClient;
 
     // Painting.
     scoped_ptr<SkCanvas> m_canvas;
@@ -216,14 +214,13 @@
     bool m_animateScheduled;
     std::map<unsigned, std::string> m_resourceIdentifierMap;
     std::map<unsigned, blink::WebURLRequest> m_requestMap;
+    base::Callback<void(const SkBitmap&)> m_compositeAndReadbackCallback;
 
     bool m_logConsoleOutput;
     int m_chooserCount;
 
     scoped_ptr<blink::WebMIDIClientMock> m_midiClient;
-    scoped_ptr<WebTestRunner::MockWebSpeechRecognizer> m_speechRecognizer;
-    scoped_ptr<WebTestRunner::MockWebSpeechInputController>
-        m_speechInputController;
+    scoped_ptr<MockWebSpeechRecognizer> m_speechRecognizer;
 
 private:
     DISALLOW_COPY_AND_ASSIGN(WebTestProxyBase);
@@ -315,10 +312,6 @@
     {
         return WebTestProxyBase::webMIDIClient();
     }
-    virtual blink::WebSpeechInputController* speechInputController(blink::WebSpeechInputListener* listener)
-    {
-        return WebTestProxyBase::speechInputController(listener);
-    }
     virtual blink::WebSpeechRecognizer* speechRecognizer()
     {
         return WebTestProxyBase::speechRecognizer();
diff --git a/content/shell/renderer/test_runner/WebTestRunner.h b/content/shell/renderer/test_runner/WebTestRunner.h
index e8305c9..1693946 100644
--- a/content/shell/renderer/test_runner/WebTestRunner.h
+++ b/content/shell/renderer/test_runner/WebTestRunner.h
@@ -11,7 +11,7 @@
 class WebPermissionClient;
 }
 
-namespace WebTestRunner {
+namespace content {
 
 class WebTestRunner {
 public:
@@ -37,6 +37,6 @@
     virtual bool shouldGeneratePixelResults() = 0;
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_WEBTESTRUNNER_H_
diff --git a/content/shell/renderer/test_runner/WebTestThemeEngineMac.h b/content/shell/renderer/test_runner/WebTestThemeEngineMac.h
index 2583e81..5b78917 100644
--- a/content/shell/renderer/test_runner/WebTestThemeEngineMac.h
+++ b/content/shell/renderer/test_runner/WebTestThemeEngineMac.h
@@ -12,7 +12,7 @@
 #include "base/basictypes.h"
 #include "third_party/WebKit/public/platform/WebThemeEngine.h"
 
-namespace WebTestRunner {
+namespace content {
 
 class WebTestThemeEngineMac : public blink::WebThemeEngine {
 public:
@@ -43,6 +43,6 @@
     DISALLOW_COPY_AND_ASSIGN(WebTestThemeEngineMac);
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_WEBTESTTHEMEENGINEMAC_H_
diff --git a/content/shell/renderer/test_runner/WebTestThemeEngineMac.mm b/content/shell/renderer/test_runner/WebTestThemeEngineMac.mm
index 6a3cb70..3ec0555 100644
--- a/content/shell/renderer/test_runner/WebTestThemeEngineMac.mm
+++ b/content/shell/renderer/test_runner/WebTestThemeEngineMac.mm
@@ -67,7 +67,7 @@
 
 @end
 
-namespace WebTestRunner {
+namespace content {
 
 namespace {
 
@@ -83,7 +83,7 @@
     }
 }
 
-}
+}  // namespace
 
 void WebTestThemeEngineMac::paintScrollbarThumb(
     WebCanvas* canvas,
@@ -174,4 +174,4 @@
     [NSGraphicsContext restoreGraphicsState];
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/WebTestThemeEngineMock.cpp b/content/shell/renderer/test_runner/WebTestThemeEngineMock.cpp
index 654371f..15f6c1c 100644
--- a/content/shell/renderer/test_runner/WebTestThemeEngineMock.cpp
+++ b/content/shell/renderer/test_runner/WebTestThemeEngineMock.cpp
@@ -15,7 +15,7 @@
 using blink::WebRect;
 using blink::WebThemeEngine;
 
-namespace WebTestRunner {
+namespace content {
 
 static const SkColor edgeColor     = SK_ColorBLACK;
 static const SkColor readOnlyColor = SkColorSetRGB(0xe9, 0xc2, 0xa6);
@@ -645,4 +645,4 @@
     }
 }
 
-} // namespace WebTestRunner
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/WebTestThemeEngineMock.h b/content/shell/renderer/test_runner/WebTestThemeEngineMock.h
index 45c7961..5ea721d 100644
--- a/content/shell/renderer/test_runner/WebTestThemeEngineMock.h
+++ b/content/shell/renderer/test_runner/WebTestThemeEngineMock.h
@@ -8,25 +8,22 @@
 #include "third_party/WebKit/public/platform/WebRect.h"
 #include "third_party/WebKit/public/platform/WebThemeEngine.h"
 
-using blink::WebRect;
-using blink::WebThemeEngine;
-
-namespace WebTestRunner {
+namespace content {
 
 class WebTestThemeEngineMock : public blink::WebThemeEngine {
 public:
     virtual ~WebTestThemeEngineMock() { }
 
     // WebThemeEngine methods:
-    virtual blink::WebSize getSize(WebThemeEngine::Part);
+    virtual blink::WebSize getSize(blink::WebThemeEngine::Part);
 
     virtual void paint(blink::WebCanvas*,
-        WebThemeEngine::Part,
-        WebThemeEngine::State,
+        blink::WebThemeEngine::Part,
+        blink::WebThemeEngine::State,
         const blink::WebRect&,
-        const WebThemeEngine::ExtraParams*);
+        const blink::WebThemeEngine::ExtraParams*);
 };
 
-} // namespace WebTestRunner
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_WEBTESTTHEMEENGINEMOCK_H_
diff --git a/content/shell/renderer/test_runner/WebUserMediaClientMock.cpp b/content/shell/renderer/test_runner/WebUserMediaClientMock.cpp
index fe1701d..03d3abe 100644
--- a/content/shell/renderer/test_runner/WebUserMediaClientMock.cpp
+++ b/content/shell/renderer/test_runner/WebUserMediaClientMock.cpp
@@ -20,9 +20,7 @@
 
 using namespace blink;
 
-using content::MockConstraints;
-
-namespace WebTestRunner {
+namespace content {
 
 class UserMediaRequestTask : public WebMethodTask<WebUserMediaClientMock> {
 public:
@@ -178,4 +176,4 @@
 {
 }
 
-}
+}  // namespace content
diff --git a/content/shell/renderer/test_runner/WebUserMediaClientMock.h b/content/shell/renderer/test_runner/WebUserMediaClientMock.h
index e8f2e83..8124e8c 100644
--- a/content/shell/renderer/test_runner/WebUserMediaClientMock.h
+++ b/content/shell/renderer/test_runner/WebUserMediaClientMock.h
@@ -12,7 +12,7 @@
 #include "third_party/WebKit/public/platform/WebURL.h"
 #include "third_party/WebKit/public/web/WebUserMediaClient.h"
 
-namespace WebTestRunner {
+namespace content {
 
 class WebTestDelegate;
 
@@ -36,6 +36,6 @@
     DISALLOW_COPY_AND_ASSIGN(WebUserMediaClientMock);
 };
 
-}
+}  // namespace content
 
 #endif  // CONTENT_SHELL_RENDERER_TEST_RUNNER_WEBUSERMEDIACLIENTMOCK_H_
diff --git a/content/shell/renderer/test_runner/accessibility_controller.cc b/content/shell/renderer/test_runner/accessibility_controller.cc
index 430e00c..c937a69 100644
--- a/content/shell/renderer/test_runner/accessibility_controller.cc
+++ b/content/shell/renderer/test_runner/accessibility_controller.cc
@@ -202,8 +202,7 @@
       argv);
 }
 
-void AccessibilityController::SetDelegate(
-    WebTestRunner::WebTestDelegate* delegate) {
+void AccessibilityController::SetDelegate(WebTestDelegate* delegate) {
   delegate_ = delegate;
 }
 
diff --git a/content/shell/renderer/test_runner/accessibility_controller.h b/content/shell/renderer/test_runner/accessibility_controller.h
index 30e0131..5ea475f 100644
--- a/content/shell/renderer/test_runner/accessibility_controller.h
+++ b/content/shell/renderer/test_runner/accessibility_controller.h
@@ -18,12 +18,10 @@
 class WebView;
 }
 
-namespace WebTestRunner {
-class WebTestDelegate;
-}
-
 namespace content {
 
+class WebTestDelegate;
+
 class AccessibilityController :
       public base::SupportsWeakPtr<AccessibilityController> {
  public:
@@ -37,7 +35,7 @@
   void NotificationReceived(const blink::WebAXObject& target,
                             const std::string& notification_name);
 
-  void SetDelegate(WebTestRunner::WebTestDelegate* delegate);
+  void SetDelegate(WebTestDelegate* delegate);
   void SetWebView(blink::WebView* web_view);
 
  private:
@@ -64,7 +62,7 @@
 
   v8::Persistent<v8::Function> notification_callback_;
 
-  WebTestRunner::WebTestDelegate* delegate_;
+  WebTestDelegate* delegate_;
   blink::WebView* web_view_;
 
   base::WeakPtrFactory<AccessibilityController> weak_factory_;
diff --git a/content/shell/renderer/test_runner/event_sender.cc b/content/shell/renderer/test_runner/event_sender.cc
index 5285d03..ed5b2a6 100644
--- a/content/shell/renderer/test_runner/event_sender.cc
+++ b/content/shell/renderer/test_runner/event_sender.cc
@@ -138,7 +138,7 @@
 // helpful.
 std::vector<std::string> MakeMenuItemStringsFor(
     WebContextMenuData* context_menu,
-    WebTestRunner::WebTestDelegate* delegate) {
+    WebTestDelegate* delegate) {
   // These constants are based on Safari's context menu because tests are made
   // for it.
   static const char* kNonEditableMenuStrings[] = {
@@ -177,7 +177,7 @@
       strings.push_back(*item);
     }
     WebVector<WebString> suggestions;
-    WebTestRunner::MockSpellCheck::fillSuggestionList(
+    MockSpellCheck::fillSuggestionList(
         context_menu->misspelledWord, &suggestions);
     for (size_t i = 0; i < suggestions.size(); ++i) {
       strings.push_back(suggestions[i].utf8());
@@ -203,7 +203,7 @@
   return WebMouseEvent::ButtonMiddle;
 }
 
-class MouseDownTask : public WebTestRunner::WebMethodTask<EventSender> {
+class MouseDownTask : public WebMethodTask<EventSender> {
  public:
   MouseDownTask(EventSender* obj, int button_number, int modifiers)
       : WebMethodTask<EventSender>(obj),
@@ -219,7 +219,7 @@
   int modifiers_;
 };
 
-class MouseUpTask : public WebTestRunner::WebMethodTask<EventSender> {
+class MouseUpTask : public WebMethodTask<EventSender> {
  public:
   MouseUpTask(EventSender* obj, int button_number, int modifiers)
       : WebMethodTask<EventSender>(obj),
@@ -235,7 +235,7 @@
   int modifiers_;
 };
 
-class KeyDownTask : public WebTestRunner::WebMethodTask<EventSender> {
+class KeyDownTask : public WebMethodTask<EventSender> {
  public:
   KeyDownTask(EventSender* obj,
               const std::string code_str,
@@ -336,7 +336,7 @@
   void TextZoomOut();
   void ZoomPageIn();
   void ZoomPageOut();
-  void SetPageZoomFactor(gin::Arguments* args);
+  void SetPageZoomFactor(double factor);
   void SetPageScaleFactor(gin::Arguments* args);
   void ClearTouchPoints();
   void ReleaseTouchPoint(unsigned index);
@@ -586,14 +586,9 @@
     sender_->ZoomPageOut();
 }
 
-void EventSenderBindings::SetPageZoomFactor(gin::Arguments* args) {
-  if (!sender_)
-    return;
-  double zoom_factor;
-  if (args->PeekNext().IsEmpty())
-    return;
-  args->GetNext(&zoom_factor);
-  sender_->SetPageZoomFactor(zoom_factor);
+void EventSenderBindings::SetPageZoomFactor(double factor) {
+  if (sender_)
+    sender_->SetPageZoomFactor(factor);
 }
 
 void EventSenderBindings::SetPageScaleFactor(gin::Arguments* args) {
@@ -1007,7 +1002,7 @@
       milliseconds(0),
       modifiers(0) {}
 
-EventSender::EventSender(WebTestRunner::TestInterfaces* interfaces)
+EventSender::EventSender(TestInterfaces* interfaces)
     : interfaces_(interfaces),
       delegate_(NULL),
       view_(NULL),
@@ -1079,7 +1074,7 @@
   EventSenderBindings::Install(weak_factory_.GetWeakPtr(), frame);
 }
 
-void EventSender::SetDelegate(WebTestRunner::WebTestDelegate* delegate) {
+void EventSender::SetDelegate(WebTestDelegate* delegate) {
   delegate_ = delegate;
 }
 
@@ -1402,7 +1397,7 @@
 
   for (size_t i = 0; i < window_list.size(); ++i) {
     window_list.at(i)->webView()->setZoomLevel(
-        content::ZoomFactorToZoomLevel(zoom_factor));
+        ZoomFactorToZoomLevel(zoom_factor));
   }
 }
 
diff --git a/content/shell/renderer/test_runner/event_sender.h b/content/shell/renderer/test_runner/event_sender.h
index b9f2922..3b2c7ef 100644
--- a/content/shell/renderer/test_runner/event_sender.h
+++ b/content/shell/renderer/test_runner/event_sender.h
@@ -30,12 +30,10 @@
 class Arguments;
 }
 
-namespace WebTestRunner {
+namespace content {
+
 class TestInterfaces;
 class WebTestDelegate;
-}
-
-namespace content {
 
 // Key event location code introduced in DOM Level 3.
 // See also: http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboardevents
@@ -48,12 +46,12 @@
 
 class EventSender : public base::SupportsWeakPtr<EventSender> {
  public:
-  explicit EventSender(WebTestRunner::TestInterfaces*);
+  explicit EventSender(TestInterfaces*);
   virtual ~EventSender();
 
   void Reset();
   void Install(blink::WebFrame*);
-  void SetDelegate(WebTestRunner::WebTestDelegate*);
+  void SetDelegate(WebTestDelegate*);
   void SetWebView(blink::WebView*);
 
   void SetContextMenuData(const blink::WebContextMenuData&);
@@ -66,7 +64,7 @@
                int modifiers,
                KeyLocationCode location);
 
-  WebTestRunner::WebTaskList* taskList() { return &task_list_; }
+  WebTaskList* taskList() { return &task_list_; }
 
  private:
   friend class EventSenderBindings;
@@ -221,10 +219,10 @@
   int wm_sys_dead_char_;
 #endif
 
-  WebTestRunner::WebTaskList task_list_;
+  WebTaskList task_list_;
 
-  WebTestRunner::TestInterfaces* interfaces_;
-  WebTestRunner::WebTestDelegate* delegate_;
+  TestInterfaces* interfaces_;
+  WebTestDelegate* delegate_;
   blink::WebView* view_;
 
   bool force_layout_on_events_;
diff --git a/content/shell/renderer/test_runner/gamepad_controller.cc b/content/shell/renderer/test_runner/gamepad_controller.cc
index f03651b..7efe712 100644
--- a/content/shell/renderer/test_runner/gamepad_controller.cc
+++ b/content/shell/renderer/test_runner/gamepad_controller.cc
@@ -150,7 +150,7 @@
   GamepadControllerBindings::Install(weak_factory_.GetWeakPtr(), frame);
 }
 
-void GamepadController::SetDelegate(WebTestRunner::WebTestDelegate* delegate) {
+void GamepadController::SetDelegate(WebTestDelegate* delegate) {
   delegate_ = delegate;
 }
 
diff --git a/content/shell/renderer/test_runner/gamepad_controller.h b/content/shell/renderer/test_runner/gamepad_controller.h
index f38fc32..b648fd0 100644
--- a/content/shell/renderer/test_runner/gamepad_controller.h
+++ b/content/shell/renderer/test_runner/gamepad_controller.h
@@ -12,12 +12,10 @@
 class WebFrame;
 }
 
-namespace WebTestRunner {
-class WebTestDelegate;
-}
-
 namespace content {
 
+class WebTestDelegate;
+
 class GamepadController : public base::SupportsWeakPtr<GamepadController> {
  public:
   GamepadController();
@@ -25,7 +23,7 @@
 
   void Reset();
   void Install(blink::WebFrame* frame);
-  void SetDelegate(WebTestRunner::WebTestDelegate* delegate);
+  void SetDelegate(WebTestDelegate* delegate);
 
  private:
   friend class GamepadControllerBindings;
@@ -48,7 +46,7 @@
 
   blink::WebGamepads gamepads_;
 
-  WebTestRunner::WebTestDelegate* delegate_;
+  WebTestDelegate* delegate_;
 
   base::WeakPtrFactory<GamepadController> weak_factory_;
 
diff --git a/content/shell/renderer/test_runner/notification_presenter.h b/content/shell/renderer/test_runner/notification_presenter.h
index b0934cd..083223a 100644
--- a/content/shell/renderer/test_runner/notification_presenter.h
+++ b/content/shell/renderer/test_runner/notification_presenter.h
@@ -12,12 +12,10 @@
 #include "third_party/WebKit/public/web/WebNotification.h"
 #include "third_party/WebKit/public/web/WebNotificationPresenter.h"
 
-namespace WebTestRunner {
-class WebTestDelegate;
-}
-
 namespace content {
 
+class WebTestDelegate;
+
 // A class that implements WebNotificationPresenter for the TestRunner library.
 class NotificationPresenter : public blink::WebNotificationPresenter {
  public:
@@ -33,9 +31,7 @@
   // Called by the TestRunner to reset the presenter to an default state.
   void Reset();
 
-  void set_delegate(WebTestRunner::WebTestDelegate* delegate) {
-    delegate_ = delegate;
-  }
+  void set_delegate(WebTestDelegate* delegate) { delegate_ = delegate; }
 
   // blink::WebNotificationPresenter interface
   virtual bool show(const blink::WebNotification& notification);
@@ -48,7 +44,7 @@
       blink::WebNotificationPermissionCallback* callback);
 
  private:
-  WebTestRunner::WebTestDelegate* delegate_;
+  WebTestDelegate* delegate_;
 
   // Map of known origins and whether they are allowed to show notifications.
   typedef std::map<std::string, bool> KnownOriginMap;
diff --git a/content/shell/renderer/test_runner/test_runner.cc b/content/shell/renderer/test_runner/test_runner.cc
index 2a53e2f..6b0e681 100644
--- a/content/shell/renderer/test_runner/test_runner.cc
+++ b/content/shell/renderer/test_runner/test_runner.cc
@@ -8,7 +8,6 @@
 
 #include "base/logging.h"
 #include "content/shell/common/test_runner/test_preferences.h"
-#include "content/shell/renderer/test_runner/MockWebSpeechInputController.h"
 #include "content/shell/renderer/test_runner/MockWebSpeechRecognizer.h"
 #include "content/shell/renderer/test_runner/TestInterfaces.h"
 #include "content/shell/renderer/test_runner/WebPermissions.h"
@@ -48,7 +47,8 @@
 #endif
 
 using namespace blink;
-using namespace WebTestRunner;
+
+namespace content {
 
 namespace {
 
@@ -59,12 +59,11 @@
   return WebString::fromUTF8(chars.get());
 }
 
-class HostMethodTask :
-      public ::WebTestRunner::WebMethodTask<content::TestRunner> {
+class HostMethodTask : public WebMethodTask<TestRunner> {
  public:
-  typedef void (content::TestRunner::*CallbackMethodType)();
-  HostMethodTask(content::TestRunner* object, CallbackMethodType callback)
-      : WebMethodTask<content::TestRunner>(object), callback_(callback) {}
+  typedef void (TestRunner::*CallbackMethodType)();
+  HostMethodTask(TestRunner* object, CallbackMethodType callback)
+      : WebMethodTask<TestRunner>(object), callback_(callback) {}
 
   virtual void runIfValid() OVERRIDE {
     (m_object->*callback_)();
@@ -76,13 +75,10 @@
 
 }  // namespace
 
-namespace content {
-
-class InvokeCallbackTask : public WebMethodTask<content::TestRunner> {
+class InvokeCallbackTask : public WebMethodTask<TestRunner> {
  public:
-  InvokeCallbackTask(content::TestRunner* object,
-                     v8::Handle<v8::Function> callback)
-      : WebMethodTask<content::TestRunner>(object),
+  InvokeCallbackTask(TestRunner* object, v8::Handle<v8::Function> callback)
+      : WebMethodTask<TestRunner>(object),
         callback_(blink::mainThreadIsolate(), callback) {}
 
   virtual void runIfValid() OVERRIDE {
@@ -232,15 +228,13 @@
   void SetWindowIsKey(bool value);
   std::string PathToLocalResource(const std::string& path);
   void SetBackingScaleFactor(double value, v8::Handle<v8::Function> callback);
+  void SetColorProfile(const std::string& name,
+                       v8::Handle<v8::Function> callback);
   void SetPOSIXLocale(const std::string& locale);
   void SetMIDIAccessorResult(bool result);
   void SetMIDISysexPermission(bool value);
   void GrantWebNotificationPermission(gin::Arguments* args);
   bool SimulateWebNotificationClick(const std::string& value);
-  void AddMockSpeechInputResult(const std::string& result,
-                                double confidence,
-                                const std::string& language);
-  void SetMockSpeechInputDumpRect(bool value);
   void AddMockSpeechRecognitionResult(const std::string& transcript,
                                       double confidence);
   void SetMockSpeechRecognitionError(const std::string& error,
@@ -250,6 +244,7 @@
   void RemoveWebPageOverlay();
   void DisplayAsync();
   void DisplayAsyncThen(v8::Handle<v8::Function> callback);
+  void SetCustomTextOutput(std::string output);
 
   bool GlobalFlag();
   void SetGlobalFlag(bool value);
@@ -298,8 +293,7 @@
 
 gin::ObjectTemplateBuilder TestRunnerBindings::GetObjectTemplateBuilder(
     v8::Isolate* isolate) {
-  return gin::Wrappable<TestRunnerBindings>::GetObjectTemplateBuilder(
-      isolate)
+  return gin::Wrappable<TestRunnerBindings>::GetObjectTemplateBuilder(isolate)
       // Methods controlling test execution.
       .SetMethod("notifyDone", &TestRunnerBindings::NotifyDone)
       .SetMethod("waitUntilDone", &TestRunnerBindings::WaitUntilDone)
@@ -331,9 +325,9 @@
                  &TestRunnerBindings::CallShouldCloseOnWebView)
       .SetMethod("setDomainRelaxationForbiddenForURLScheme",
                  &TestRunnerBindings::SetDomainRelaxationForbiddenForURLScheme)
-      .SetMethod("evaluateScriptInIsolatedWorldAndReturnValue",
-                 &TestRunnerBindings::
-                     EvaluateScriptInIsolatedWorldAndReturnValue)
+      .SetMethod(
+           "evaluateScriptInIsolatedWorldAndReturnValue",
+           &TestRunnerBindings::EvaluateScriptInIsolatedWorldAndReturnValue)
       .SetMethod("evaluateScriptInIsolatedWorld",
                  &TestRunnerBindings::EvaluateScriptInIsolatedWorld)
       .SetMethod("setIsolatedWorldSecurityOrigin",
@@ -434,9 +428,9 @@
                  &TestRunnerBindings::DumpBackForwardList)
       .SetMethod("dumpSelectionRect", &TestRunnerBindings::DumpSelectionRect)
       .SetMethod("setPrinting", &TestRunnerBindings::SetPrinting)
-      .SetMethod("setShouldStayOnPageAfterHandlingBeforeUnload",
-                 &TestRunnerBindings::
-                     SetShouldStayOnPageAfterHandlingBeforeUnload)
+      .SetMethod(
+           "setShouldStayOnPageAfterHandlingBeforeUnload",
+           &TestRunnerBindings::SetShouldStayOnPageAfterHandlingBeforeUnload)
       .SetMethod("setWillSendRequestClearHeader",
                  &TestRunnerBindings::SetWillSendRequestClearHeader)
       .SetMethod("dumpResourceRequestPriorities",
@@ -458,6 +452,8 @@
                  &TestRunnerBindings::PathToLocalResource)
       .SetMethod("setBackingScaleFactor",
                  &TestRunnerBindings::SetBackingScaleFactor)
+      .SetMethod("setColorProfile",
+                 &TestRunnerBindings::SetColorProfile)
       .SetMethod("setPOSIXLocale", &TestRunnerBindings::SetPOSIXLocale)
       .SetMethod("setMIDIAccessorResult",
                  &TestRunnerBindings::SetMIDIAccessorResult)
@@ -467,10 +463,6 @@
                  &TestRunnerBindings::GrantWebNotificationPermission)
       .SetMethod("simulateWebNotificationClick",
                  &TestRunnerBindings::SimulateWebNotificationClick)
-      .SetMethod("addMockSpeechInputResult",
-                 &TestRunnerBindings::AddMockSpeechInputResult)
-      .SetMethod("setMockSpeechInputDumpRect",
-                 &TestRunnerBindings::SetMockSpeechInputDumpRect)
       .SetMethod("addMockSpeechRecognitionResult",
                  &TestRunnerBindings::AddMockSpeechRecognitionResult)
       .SetMethod("setMockSpeechRecognitionError",
@@ -482,9 +474,12 @@
                  &TestRunnerBindings::RemoveWebPageOverlay)
       .SetMethod("displayAsync", &TestRunnerBindings::DisplayAsync)
       .SetMethod("displayAsyncThen", &TestRunnerBindings::DisplayAsyncThen)
+      .SetMethod("setCustomTextOutput",
+                 &TestRunnerBindings::SetCustomTextOutput)
 
       // Properties.
-      .SetProperty("globalFlag", &TestRunnerBindings::GlobalFlag,
+      .SetProperty("globalFlag",
+                   &TestRunnerBindings::GlobalFlag,
                    &TestRunnerBindings::SetGlobalFlag)
       .SetProperty("platformName", &TestRunnerBindings::PlatformName)
       .SetProperty("tooltipText", &TestRunnerBindings::TooltipText)
@@ -531,7 +526,6 @@
       // Used at fast/dom/assign-to-window-status.html
       .SetMethod("dumpStatusCallbacks",
                  &TestRunnerBindings::DumpWindowStatusChanges);
-
 }
 
 void TestRunnerBindings::NotifyDone() {
@@ -1156,6 +1150,12 @@
     runner_->SetBackingScaleFactor(value, callback);
 }
 
+void TestRunnerBindings::SetColorProfile(
+    const std::string& name, v8::Handle<v8::Function> callback) {
+  if (runner_)
+    runner_->SetColorProfile(name, callback);
+}
+
 void TestRunnerBindings::SetPOSIXLocale(const std::string& locale) {
   if (runner_)
     runner_->SetPOSIXLocale(locale);
@@ -1188,18 +1188,6 @@
   return false;
 }
 
-void TestRunnerBindings::AddMockSpeechInputResult(const std::string& result,
-                                                  double confidence,
-                                                  const std::string& language) {
-  if (runner_)
-    runner_->AddMockSpeechInputResult(result, confidence, language);
-}
-
-void TestRunnerBindings::SetMockSpeechInputDumpRect(bool value) {
-  if (runner_)
-    runner_->SetMockSpeechInputDumpRect(value);
-}
-
 void TestRunnerBindings::AddMockSpeechRecognitionResult(
     const std::string& transcript, double confidence) {
   if (runner_)
@@ -1238,6 +1226,10 @@
     runner_->DisplayAsyncThen(callback);
 }
 
+void TestRunnerBindings::SetCustomTextOutput(std::string output) {
+  runner_->setCustomTextOutput(output);
+}
+
 bool TestRunnerBindings::GlobalFlag() {
   if (runner_)
     return runner_->global_flag_;
@@ -1374,7 +1366,7 @@
       web_view_(NULL),
       page_overlay_(NULL),
       web_permissions_(new WebPermissions()),
-      notification_presenter_(new content::NotificationPresenter()),
+      notification_presenter_(new NotificationPresenter()),
       weak_factory_(this) {}
 
 TestRunner::~TestRunner() {}
@@ -1431,6 +1423,7 @@
   if (delegate_) {
     // Reset the default quota for each origin to 5MB
     delegate_->setDatabaseQuota(5 * 1024 * 1024);
+    delegate_->setDeviceColorProfile("sRGB");
     delegate_->setDeviceScaleFactor(1);
     delegate_->setAcceptAllCookies(false);
     delegate_->setLocale("");
@@ -1467,6 +1460,8 @@
   midi_accessor_result_ = true;
   should_stay_on_page_after_handling_before_unload_ = false;
   should_dump_resource_priorities_ = false;
+  has_custom_text_output_ = false;
+  custom_text_output_.clear();
 
   http_headers_to_clear_.clear();
 
@@ -1522,6 +1517,19 @@
   dump_as_markup_ = value;
 }
 
+bool TestRunner::shouldDumpAsCustomText() const {
+  return has_custom_text_output_;
+}
+
+std::string TestRunner::customDumpText() const {
+  return custom_text_output_;
+}
+
+void TestRunner::setCustomTextOutput(std::string text) {
+  custom_text_output_ = text;
+  has_custom_text_output_ = true;
+}
+
 bool TestRunner::shouldGeneratePixelResults() {
   CheckResponseMimeType();
   return generate_pixel_results_;
@@ -2499,6 +2507,12 @@
   delegate_->postTask(new InvokeCallbackTask(this, callback));
 }
 
+void TestRunner::SetColorProfile(const std::string& name,
+                                 v8::Handle<v8::Function> callback) {
+  delegate_->setDeviceColorProfile(name);
+  delegate_->postTask(new InvokeCallbackTask(this, callback));
+}
+
 void TestRunner::SetPOSIXLocale(const std::string& locale) {
   delegate_->setLocale(locale);
 }
@@ -2523,21 +2537,6 @@
   return notification_presenter_->SimulateClick(value);
 }
 
-void TestRunner::AddMockSpeechInputResult(const std::string& result,
-                                          double confidence,
-                                          const std::string& language) {
-#if ENABLE_INPUT_SPEECH
-  proxy_->speechInputControllerMock()->addMockRecognitionResult(
-      WebString::fromUTF8(result), confidence, WebString::fromUTF8(language));
-#endif
-}
-
-void TestRunner::SetMockSpeechInputDumpRect(bool value) {
-#if ENABLE_INPUT_SPEECH
-  proxy_->speechInputControllerMock()->setDumpRect(value);
-#endif
-}
-
 void TestRunner::AddMockSpeechRecognitionResult(const std::string& transcript,
                                                 double confidence) {
   proxy_->speechRecognizerMock()->addMockResult(
diff --git a/content/shell/renderer/test_runner/test_runner.h b/content/shell/renderer/test_runner/test_runner.h
index 424f575..93f83f9 100644
--- a/content/shell/renderer/test_runner/test_runner.h
+++ b/content/shell/renderer/test_runner/test_runner.h
@@ -28,33 +28,30 @@
 class Arguments;
 }
 
-namespace WebTestRunner {
-class TestInterfaces;
-class WebTestDelegate;
-}
-
 namespace content {
 
 class InvokeCallbackTask;
 class NotificationPresenter;
+class TestInterfaces;
 class TestPageOverlay;
 class WebPermissions;
+class WebTestDelegate;
 class WebTestProxyBase;
 
-class TestRunner : public ::WebTestRunner::WebTestRunner,
+class TestRunner : public WebTestRunner,
                    public base::SupportsWeakPtr<TestRunner> {
  public:
-  explicit TestRunner(::WebTestRunner::TestInterfaces*);
+  explicit TestRunner(TestInterfaces*);
   virtual ~TestRunner();
 
   void Install(blink::WebFrame* frame);
 
-  void SetDelegate(::WebTestRunner::WebTestDelegate*);
+  void SetDelegate(WebTestDelegate*);
   void SetWebView(blink::WebView*, WebTestProxyBase*);
 
   void Reset();
 
-  ::WebTestRunner::WebTaskList* taskList() { return &task_list_; }
+  WebTaskList* taskList() { return &task_list_; }
 
   void SetTestIsRunning(bool);
   bool TestIsRunning() const { return test_is_running_; }
@@ -76,6 +73,8 @@
   bool isPrinting() const;
   bool shouldDumpAsText();
   bool shouldDumpAsTextWithPixelResults();
+  bool shouldDumpAsCustomText() const;
+  std:: string customDumpText() const;
   bool shouldDumpAsMarkup();
   bool shouldDumpChildFrameScrollPositions() const;
   bool shouldDumpChildFramesAsText() const;
@@ -84,6 +83,7 @@
   void clearDevToolsLocalStorage();
   void setShouldDumpAsText(bool);
   void setShouldDumpAsMarkup(bool);
+  void setCustomTextOutput(std::string text);
   void setShouldGeneratePixelResults(bool);
   void setShouldDumpFrameLoadCallbacks(bool);
   void setShouldDumpPingLoaderCallbacks(bool);
@@ -127,7 +127,7 @@
     virtual ~WorkItem() {}
 
     // Returns true if this started a load.
-    virtual bool Run(::WebTestRunner::WebTestDelegate*, blink::WebView*) = 0;
+    virtual bool Run(WebTestDelegate*, blink::WebView*) = 0;
   };
 
  private:
@@ -150,20 +150,19 @@
 
     void set_frozen(bool frozen) { frozen_ = frozen; }
     bool is_empty() { return queue_.empty(); }
-    ::WebTestRunner::WebTaskList* taskList() { return &task_list_; }
+    WebTaskList* taskList() { return &task_list_; }
 
    private:
     void ProcessWork();
 
-    class WorkQueueTask : public ::WebTestRunner::WebMethodTask<WorkQueue> {
+    class WorkQueueTask : public WebMethodTask<WorkQueue> {
      public:
-      WorkQueueTask(WorkQueue* object) :
-          ::WebTestRunner::WebMethodTask<WorkQueue>(object) { }
+      WorkQueueTask(WorkQueue* object) : WebMethodTask<WorkQueue>(object) {}
 
       virtual void runIfValid() OVERRIDE;
     };
 
-    ::WebTestRunner::WebTaskList task_list_;
+    WebTaskList task_list_;
     std::deque<WorkItem*> queue_;
     bool frozen_;
     TestRunner* controller_;
@@ -478,6 +477,10 @@
   // Used to set the device scale factor.
   void SetBackingScaleFactor(double value, v8::Handle<v8::Function> callback);
 
+  // Change the device color profile while running a layout test.
+  void SetColorProfile(const std::string& name,
+                       v8::Handle<v8::Function> callback);
+
   // Calls setlocale(LC_ALL, ...) for a specified locale.
   // Resets between tests.
   void SetPOSIXLocale(const std::string& locale);
@@ -492,11 +495,7 @@
   // Simulates a click on a desktop notification.
   bool SimulateWebNotificationClick(const std::string& value);
 
-  // Speech input related functions.
-  void AddMockSpeechInputResult(const std::string& result,
-                                double confidence,
-                                const std::string& language);
-  void SetMockSpeechInputDumpRect(bool value);
+  // Speech recognition related functions.
   void AddMockSpeechRecognitionResult(const std::string& transcript,
                                       double confidence);
   void SetMockSpeechRecognitionError(const std::string& error,
@@ -676,16 +675,19 @@
 
   bool should_dump_resource_priorities_;
 
+  bool has_custom_text_output_;
+  std::string custom_text_output_;
+
   std::set<std::string> http_headers_to_clear_;
 
   // WAV audio data is stored here.
   std::vector<unsigned char> audio_data_;
 
   // Used for test timeouts.
-  ::WebTestRunner::WebTaskList task_list_;
+  WebTaskList task_list_;
 
-  ::WebTestRunner::TestInterfaces* test_interfaces_;
-  ::WebTestRunner::WebTestDelegate* delegate_;
+  TestInterfaces* test_interfaces_;
+  WebTestDelegate* delegate_;
   blink::WebView* web_view_;
   TestPageOverlay* page_overlay_;
   WebTestProxyBase* proxy_;
diff --git a/content/shell/renderer/webkit_test_runner.cc b/content/shell/renderer/webkit_test_runner.cc
index f0454e1..e82c423 100644
--- a/content/shell/renderer/webkit_test_runner.cc
+++ b/content/shell/renderer/webkit_test_runner.cc
@@ -87,8 +87,6 @@
 using blink::WebTestingSupport;
 using blink::WebVector;
 using blink::WebView;
-using WebTestRunner::WebTask;
-using WebTestRunner::WebTestInterfaces;
 
 namespace content {
 
@@ -212,9 +210,7 @@
       focused_view_(NULL),
       is_main_window_(false),
       focus_on_next_commit_(false),
-      leak_detector_(new LeakDetector(this))
-{
-  UseMockMediaStreams(render_view);
+      leak_detector_(new LeakDetector(this)) {
 }
 
 WebKitTestRunner::~WebKitTestRunner() {
@@ -436,6 +432,10 @@
   SetDeviceScaleFactor(render_view(), factor);
 }
 
+void WebKitTestRunner::setDeviceColorProfile(const std::string& name) {
+  SetDeviceColorProfile(render_view(), name);
+}
+
 void WebKitTestRunner::setFocus(WebTestProxyBase* proxy, bool focus) {
   ProxyToRenderViewVisitor visitor(proxy);
   RenderView::ForEach(&visitor);
@@ -640,6 +640,7 @@
 void WebKitTestRunner::CaptureDump() {
   WebTestInterfaces* interfaces =
       ShellRenderProcessObserver::GetInstance()->test_interfaces();
+  TRACE_EVENT0("shell", "WebKitTestRunner::CaptureDump");
 
   if (interfaces->testRunner()->shouldDumpAsAudio()) {
     std::vector<unsigned char> vector_data;
@@ -651,25 +652,44 @@
 
     if (test_config_.enable_pixel_dumping &&
         interfaces->testRunner()->shouldGeneratePixelResults()) {
-      SkBitmap snapshot;
-      CopyCanvasToBitmap(proxy()->capturePixels(), &snapshot);
-
-      SkAutoLockPixels snapshot_lock(snapshot);
-      base::MD5Digest digest;
-      base::MD5Sum(snapshot.getPixels(), snapshot.getSize(), &digest);
-      std::string actual_pixel_hash = base::MD5DigestToBase16(digest);
-
-      if (actual_pixel_hash == test_config_.expected_pixel_hash) {
-        SkBitmap empty_image;
-        Send(new ShellViewHostMsg_ImageDump(
-            routing_id(), actual_pixel_hash, empty_image));
+      // TODO(danakj): Remove when kForceCompositingMode is everywhere.
+      if (!render_view()->GetWebView()->isAcceleratedCompositingActive()) {
+        SkBitmap snapshot;
+        CopyCanvasToBitmap(proxy()->capturePixels(), &snapshot);
+        CaptureDumpPixels(snapshot);
       } else {
-        Send(new ShellViewHostMsg_ImageDump(
-            routing_id(), actual_pixel_hash, snapshot));
+        proxy()->CapturePixelsAsync(base::Bind(
+            &WebKitTestRunner::CaptureDumpPixels, base::Unretained(this)));
       }
+      return;
     }
   }
 
+  CaptureDumpComplete();
+}
+
+void WebKitTestRunner::CaptureDumpPixels(const SkBitmap& snapshot) {
+  DCHECK_NE(0, snapshot.info().fWidth);
+  DCHECK_NE(0, snapshot.info().fHeight);
+
+  SkAutoLockPixels snapshot_lock(snapshot);
+  base::MD5Digest digest;
+  base::MD5Sum(snapshot.getPixels(), snapshot.getSize(), &digest);
+  std::string actual_pixel_hash = base::MD5DigestToBase16(digest);
+
+  if (actual_pixel_hash == test_config_.expected_pixel_hash) {
+    SkBitmap empty_image;
+    Send(new ShellViewHostMsg_ImageDump(
+        routing_id(), actual_pixel_hash, empty_image));
+  } else {
+    Send(new ShellViewHostMsg_ImageDump(
+        routing_id(), actual_pixel_hash, snapshot));
+  }
+
+  CaptureDumpComplete();
+}
+
+void WebKitTestRunner::CaptureDumpComplete() {
   render_view()->GetWebView()->mainFrame()->stopLoading();
 
   base::MessageLoop::current()->PostTask(
diff --git a/content/shell/renderer/webkit_test_runner.h b/content/shell/renderer/webkit_test_runner.h
index a5ef240..55471bc 100644
--- a/content/shell/renderer/webkit_test_runner.h
+++ b/content/shell/renderer/webkit_test_runner.h
@@ -18,6 +18,7 @@
 #include "third_party/WebKit/public/platform/WebScreenOrientationType.h"
 #include "v8/include/v8.h"
 
+class SkBitmap;
 class SkCanvas;
 
 namespace blink {
@@ -35,7 +36,7 @@
 // This is the renderer side of the webkit test runner.
 class WebKitTestRunner : public RenderViewObserver,
                          public RenderViewObserverTracker<WebKitTestRunner>,
-                         public WebTestRunner::WebTestDelegate {
+                         public WebTestDelegate {
  public:
   explicit WebKitTestRunner(RenderView* render_view);
   virtual ~WebKitTestRunner();
@@ -66,9 +67,8 @@
   virtual void setScreenOrientation(
       const blink::WebScreenOrientationType& orientation) OVERRIDE;
   virtual void printMessage(const std::string& message) OVERRIDE;
-  virtual void postTask(::WebTestRunner::WebTask* task) OVERRIDE;
-  virtual void postDelayedTask(::WebTestRunner::WebTask* task,
-                               long long ms) OVERRIDE;
+  virtual void postTask(WebTask* task) OVERRIDE;
+  virtual void postDelayedTask(WebTask* task, long long ms) OVERRIDE;
   virtual blink::WebString registerIsolatedFileSystem(
       const blink::WebVector<blink::WebString>& absolute_filenames) OVERRIDE;
   virtual long long getCurrentTimeInMillisecond() OVERRIDE;
@@ -94,6 +94,7 @@
   virtual void clearAllDatabases() OVERRIDE;
   virtual void setDatabaseQuota(int quota) OVERRIDE;
   virtual void setDeviceScaleFactor(float factor) OVERRIDE;
+  virtual void setDeviceColorProfile(const std::string& name) OVERRIDE;
   virtual void setFocus(WebTestProxyBase* proxy, bool focus) OVERRIDE;
   virtual void setAcceptAllCookies(bool accept) OVERRIDE;
   virtual std::string pathToLocalResource(const std::string& resource) OVERRIDE;
@@ -130,6 +131,8 @@
   // After finishing the test, retrieves the audio, text, and pixel dumps from
   // the TestRunner library and sends them to the browser process.
   void CaptureDump();
+  void CaptureDumpPixels(const SkBitmap& snapshot);
+  void CaptureDumpComplete();
 
   WebTestProxyBase* proxy_;
 
diff --git a/content/speech_recognition_error_java.target.darwin-arm.mk b/content/speech_recognition_error_java.target.darwin-arm.mk
index df7cd89..27c7402 100644
--- a/content/speech_recognition_error_java.target.darwin-arm.mk
+++ b/content/speech_recognition_error_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_speech_recognition_error_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/speech_recognition_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/SpeechRecognitionError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/speech_recognition_error_java.target.darwin-arm64.mk b/content/speech_recognition_error_java.target.darwin-arm64.mk
index e4b6f58..5a40b49 100644
--- a/content/speech_recognition_error_java.target.darwin-arm64.mk
+++ b/content/speech_recognition_error_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_speech_recognition_error_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/speech_recognition_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/SpeechRecognitionError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/speech_recognition_error_java.target.darwin-mips.mk b/content/speech_recognition_error_java.target.darwin-mips.mk
index 81a41ec..c65f047 100644
--- a/content/speech_recognition_error_java.target.darwin-mips.mk
+++ b/content/speech_recognition_error_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_speech_recognition_error_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/speech_recognition_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/SpeechRecognitionError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/speech_recognition_error_java.target.darwin-x86.mk b/content/speech_recognition_error_java.target.darwin-x86.mk
index 9bb4c80..4b15130 100644
--- a/content/speech_recognition_error_java.target.darwin-x86.mk
+++ b/content/speech_recognition_error_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_speech_recognition_error_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/speech_recognition_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/SpeechRecognitionError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/speech_recognition_error_java.target.darwin-x86_64.mk b/content/speech_recognition_error_java.target.darwin-x86_64.mk
index 3c35fa4..b21a358 100644
--- a/content/speech_recognition_error_java.target.darwin-x86_64.mk
+++ b/content/speech_recognition_error_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_speech_recognition_error_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/speech_recognition_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/SpeechRecognitionError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/speech_recognition_error_java.target.linux-arm.mk b/content/speech_recognition_error_java.target.linux-arm.mk
index df7cd89..27c7402 100644
--- a/content/speech_recognition_error_java.target.linux-arm.mk
+++ b/content/speech_recognition_error_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_speech_recognition_error_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/speech_recognition_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/SpeechRecognitionError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/content/speech_recognition_error_java.target.linux-arm64.mk b/content/speech_recognition_error_java.target.linux-arm64.mk
index e4b6f58..5a40b49 100644
--- a/content/speech_recognition_error_java.target.linux-arm64.mk
+++ b/content/speech_recognition_error_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_speech_recognition_error_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/speech_recognition_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/SpeechRecognitionError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/speech_recognition_error_java.target.linux-mips.mk b/content/speech_recognition_error_java.target.linux-mips.mk
index 81a41ec..c65f047 100644
--- a/content/speech_recognition_error_java.target.linux-mips.mk
+++ b/content/speech_recognition_error_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_speech_recognition_error_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/speech_recognition_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/SpeechRecognitionError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/speech_recognition_error_java.target.linux-x86.mk b/content/speech_recognition_error_java.target.linux-x86.mk
index 9bb4c80..4b15130 100644
--- a/content/speech_recognition_error_java.target.linux-x86.mk
+++ b/content/speech_recognition_error_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_speech_recognition_error_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/speech_recognition_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/SpeechRecognitionError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/speech_recognition_error_java.target.linux-x86_64.mk b/content/speech_recognition_error_java.target.linux-x86_64.mk
index 3c35fa4..b21a358 100644
--- a/content/speech_recognition_error_java.target.linux-x86_64.mk
+++ b/content/speech_recognition_error_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "content_content_gyp_speech_recognition_error_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'public/common/speech_recognition_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['public/android/java/src/org/chromium/content/browser/SpeechRecognitionError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/content/browser/SpeechRecognitionError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/content/test/accessibility_browser_test_utils.cc b/content/test/accessibility_browser_test_utils.cc
index 8cb74ec..e8ba40f 100644
--- a/content/test/accessibility_browser_test_utils.cc
+++ b/content/test/accessibility_browser_test_utils.cc
@@ -9,8 +9,8 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/common/view_message_enums.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/test_utils.h"
diff --git a/content/test/content_test_suite.cc b/content/test/content_test_suite.cc
index ef1bfe9..9aef770 100644
--- a/content/test/content_test_suite.cc
+++ b/content/test/content_test_suite.cc
@@ -10,6 +10,7 @@
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_paths.h"
 #include "content/public/test/test_content_client_initializer.h"
+#include "gpu/config/gpu_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/resource/resource_bundle.h"
 
@@ -81,8 +82,11 @@
   media::InitializeMediaLibraryForTesting();
   // When running in a child process for Mac sandbox tests, the sandbox exists
   // to initialize GL, so don't do it here.
-  if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestChildProcess))
+  if (!CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kTestChildProcess)) {
     gfx::GLSurface::InitializeOneOffForTests();
+    gpu::ApplyGpuDriverBugWorkarounds(CommandLine::ForCurrentProcess());
+  }
 #endif
   testing::TestEventListeners& listeners =
       testing::UnitTest::GetInstance()->listeners();
diff --git a/content/test/data/accessibility/aria-activedescendant-expected-android.txt b/content/test/data/accessibility/aria-activedescendant-expected-android.txt
new file mode 100644
index 0000000..8620d59
--- /dev/null
+++ b/content/test/data/accessibility/aria-activedescendant-expected-android.txt
@@ -0,0 +1 @@
+#<skip - need to generate expectation>
diff --git a/content/test/data/accessibility/aria-activedescendant-expected-mac.txt b/content/test/data/accessibility/aria-activedescendant-expected-mac.txt
new file mode 100644
index 0000000..14b25a3
--- /dev/null
+++ b/content/test/data/accessibility/aria-activedescendant-expected-mac.txt
@@ -0,0 +1,8 @@
+AXWebArea
+    AXGroup AXTitle='Inactive descendantActive descendantInactive descendant #2'
+        AXGroup
+            AXStaticText AXValue='Inactive descendant'
+        AXGroup AXFocused='1'
+            AXStaticText AXValue='Active descendant'
+        AXGroup
+            AXStaticText AXValue='Inactive descendant #2'
diff --git a/content/test/data/accessibility/aria-activedescendant-expected-win.txt b/content/test/data/accessibility/aria-activedescendant-expected-win.txt
new file mode 100644
index 0000000..8620d59
--- /dev/null
+++ b/content/test/data/accessibility/aria-activedescendant-expected-win.txt
@@ -0,0 +1 @@
+#<skip - need to generate expectation>
diff --git a/content/test/data/accessibility/aria-activedescendant.html b/content/test/data/accessibility/aria-activedescendant.html
new file mode 100644
index 0000000..dbf2d28
--- /dev/null
+++ b/content/test/data/accessibility/aria-activedescendant.html
@@ -0,0 +1,15 @@
+<!--
+@MAC-ALLOW:AXFocused='1'
+-->
+<html>
+<body>
+  <div id="parent" aria-label="parent node" aria-activedescendant="active" tabindex="0">
+    <div id="inactive">Inactive descendant</div>
+    <div id="active">Active descendant</div>
+    <div id="alsoinactive">Inactive descendant #2</div>
+  </div>
+  <script>
+    document.querySelector('#parent').focus();
+  </script>
+</body>
+</html>
diff --git a/content/test/data/accessibility/iframe-coordinates.html b/content/test/data/accessibility/iframe-coordinates.html
index c5cd3d0..6052153 100644
--- a/content/test/data/accessibility/iframe-coordinates.html
+++ b/content/test/data/accessibility/iframe-coordinates.html
@@ -11,6 +11,7 @@
 @WIN-ALLOW:size=(300, 100)
 @WIN-ALLOW:size=(250, 50)
 @WIN-ALLOW:size=(150, 50)
+@WIN-ALLOW:IA2_STATE_EDITABLE
 -->
 <html>
 <head>
diff --git a/content/test/data/gpu/webgl.html b/content/test/data/gpu/webgl.html
index 001c569..faa445d 100644
--- a/content/test/data/gpu/webgl.html
+++ b/content/test/data/gpu/webgl.html
@@ -59,6 +59,47 @@
     window.domAutomationController.send("FAILED");
 }
 
+function testQuantityLoss() {
+  var count = 0;
+  var iterations = 128;
+  var garbageCanvases = [];
+
+  function createAndDiscardContext() {
+    count++;
+
+    var c = document.createElement("canvas");
+    c.width = 1;
+    c.height = 1;
+    garbageCanvases.push(c);
+
+    var ctx = c.getContext("experimental-webgl");
+    if (!ctx) {
+      return false;
+    }
+    ctx.clear(gl.COLOR_BUFFER_BIT);
+
+    if (count < iterations) {
+      window.requestAnimationFrame(createAndDiscardContext);
+    } else {
+      // Remove the references to the garbage canvases, then attempt to trigger
+      // a garbage collect.
+      garbageCanvases = null;
+
+      window.domAutomationController.setAutomationId(1);
+      alreadySetAutomationId = true;
+      window.domAutomationController.send("LOADED");
+
+      // Trying to provoke garbage collection through excessive allocations.
+      setInterval(function() {
+        var garbageArray = new Uint8Array(1024 * 1024);
+        garbageArray[0] = 255;
+      }, 10);
+    }
+  };
+
+  createAndDiscardContext();
+}
+
 function contextLostTest(kind)
 {
   switch (kind) {
@@ -79,6 +120,12 @@
       alreadySetAutomationId = true;
       window.domAutomationController.send("LOADED");
       break;
+    case "forced_quantity_loss":
+      // Test creates many new contexts, forcing the original context to be
+      // lost. Then a garbage collect is triggered and the original context is
+      // watched to ensure it restores properly.
+      testQuantityLoss();
+      break;
   }
 }
 
diff --git a/content/test/data/speech/basic_recognition.html b/content/test/data/speech/basic_recognition.html
deleted file mode 100644
index 3ef7f74..0000000
--- a/content/test/data/speech/basic_recognition.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<html>
-  <head>
-    <title>Speech input test</title>
-    <script type="text/javascript">
-      function onspeechresult(value) {
-        if (value == "Pictures of the moon") {
-          document.getElementById('status').innerHTML = 'PASS';
-          document.location = '#pass';
-        } else {
-          document.location = '#fail';
-        }
-      }
-    </script>
-  </head>
-  <body style="padding:0; margin:0;">
-    <input id='inputField' x-webkit-speech
-           onwebkitspeechchange="onspeechresult(this.value);"
-           onchange="onspeechresult(this.value);"
-           style="position:absolute; margin:0; padding:0; border:0; width:10px;">
-    <br>
-    <div id="status">FAIL</div>
-    <script>document.getElementById('inputField').focus();</script>
-  </body>
-</html>
diff --git a/content/test/data/speech/grammar_attribute.html b/content/test/data/speech/grammar_attribute.html
deleted file mode 100644
index 393d68a..0000000
--- a/content/test/data/speech/grammar_attribute.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<html>
-  <head>
-    <title>Speech input with grammar attribute test</title>
-    <script type="text/javascript">
-      function onspeechresult(value) {
-        if (value == "Pictures of the moon") {
-          document.getElementById('status').innerHTML = 'PASS';
-          document.location = '#pass';
-        } else {
-          document.location = '#fail';
-        }
-      }
-    </script>
-  </head>
-  <body style="padding:0; margin:0;">
-    <input id='inputField' x-webkit-speech
-           x-webkit-grammar="http://example.com/grammar.xml"
-           onwebkitspeechchange="onspeechresult(this.value);"
-           onchange="onspeechresult(this.value);"
-           style="position:absolute; margin:0; padding:0; border:0; width:10px;">
-    <br>
-    <div id="status">FAIL</div>
-    <script>document.getElementById('inputField').focus();</script>
-  </body>
-</html>
diff --git a/content/test/data/web_ui_mojo.js b/content/test/data/web_ui_mojo.js
index 3dc3229..086dc00 100644
--- a/content/test/data/web_ui_mojo.js
+++ b/content/test/data/web_ui_mojo.js
@@ -6,7 +6,7 @@
     'mojo/public/js/bindings/connection',
     'content/test/data/web_ui_test_mojo_bindings.mojom',
 ], function (connection, bindings) {
-  var retainedConnection, kIterations = 100, kBadValue = 13;
+  var retainedConnection;
 
   function RendererTargetTest(bindings) {
     this.bindings_ = bindings;
@@ -23,33 +23,6 @@
     this.bindings_.pingResponse();
   };
 
-  RendererTargetTest.prototype.echo = function (arg) {
-    var i;
-
-    // Ensure negative values are negative.
-    if (arg.si64 > 0)
-      arg.si64 = kBadValue;
-
-    if (arg.si32 > 0)
-      arg.si32 = kBadValue;
-
-    if (arg.si16 > 0)
-      arg.si16 = kBadValue;
-
-    if (arg.si8 > 0)
-      arg.si8 = kBadValue;
-
-    for (i = 0; i < kIterations; ++i) {
-      arg2 = new bindings.EchoArgs();
-      arg2.si64 = -1;
-      arg2.si32 = -1;
-      arg2.si16 = -1;
-      arg2.si8 = -1;
-      arg2.name = "going";
-      this.bindings_.echoResponse(arg, arg2);
-    }
-  };
-
   return function(handle) {
     retainedConnection = new connection.Connection(
         handle, RendererTargetTest, bindings.BrowserTargetProxy);
diff --git a/content/test/data/web_ui_test_mojo_bindings.mojom b/content/test/data/web_ui_test_mojo_bindings.mojom
index 9ffd385..67d5983 100644
--- a/content/test/data/web_ui_test_mojo_bindings.mojom
+++ b/content/test/data/web_ui_test_mojo_bindings.mojom
@@ -1,36 +1,13 @@
 module mojo {
 
-// This struct encompasses all of the basic types, so that they
-// may be sent from C++ to JS and back for validation.
-struct EchoArgs {
-  int64 si64;
-  int32 si32;
-  int16 si16;
-  int8  si8;
-  uint64 ui64;
-  uint32 ui32;
-  uint16 ui16;
-  uint8  ui8;
-  float float_val;
-  float float_inf;
-  float float_nan;
-  double double_val;
-  double double_inf;
-  double double_nan;
-  string name;
-  string[] string_array;
-};
-
 [Peer=RendererTarget]
 interface BrowserTarget {
   PingResponse();
-  EchoResponse(EchoArgs arg1, EchoArgs arg2);
 };
 
 [Peer=BrowserTarget]
 interface RendererTarget {
   Ping();
-  Echo(EchoArgs arg);
 };
 
 }
diff --git a/content/test/frame_load_waiter.cc b/content/test/frame_load_waiter.cc
new file mode 100644
index 0000000..6343f85
--- /dev/null
+++ b/content/test/frame_load_waiter.cc
@@ -0,0 +1,27 @@
+// 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.
+
+#include "content/test/frame_load_waiter.h"
+
+#include "base/location.h"
+#include "base/message_loop/message_loop.h"
+
+namespace content {
+
+FrameLoadWaiter::FrameLoadWaiter(RenderFrame* frame)
+    : RenderFrameObserver(frame) {
+}
+
+void FrameLoadWaiter::Wait() {
+  // Pump messages until Blink's threaded HTML parser finishes.
+  run_loop_.Run();
+}
+
+void FrameLoadWaiter::DidFinishLoad() {
+  // Post a task to quit instead of quitting directly, since the load completion
+  // may trigger other IPCs that tests are expecting.
+  base::MessageLoop::current()->PostTask(FROM_HERE, run_loop_.QuitClosure());
+}
+
+}  // namespace content
diff --git a/content/test/frame_load_waiter.h b/content/test/frame_load_waiter.h
new file mode 100644
index 0000000..81b0baa
--- /dev/null
+++ b/content/test/frame_load_waiter.h
@@ -0,0 +1,32 @@
+// 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.
+
+#ifndef CONTENT_TEST_FRAME_LOAD_WAITER_H_
+#define CONTENT_TEST_FRAME_LOAD_WAITER_H_
+
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "content/public/renderer/render_frame_observer.h"
+
+namespace content {
+
+// Helper class to spin the run loop when waiting for a frame load to complete.
+// Blink uses a threaded HTML parser, so it's no longer sufficient to just spin
+// the run loop once to process all pending messages.
+class FrameLoadWaiter : public RenderFrameObserver {
+ public:
+  explicit FrameLoadWaiter(RenderFrame* frame);
+  void Wait();
+
+ private:
+  virtual void DidFinishLoad() OVERRIDE;
+
+  base::RunLoop run_loop_;
+
+  DISALLOW_COPY_AND_ASSIGN(FrameLoadWaiter);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_TEST_FRAME_LOAD_WAITER_H_
diff --git a/content/test/gpu/gpu_tests/cloud_storage_test_base.py b/content/test/gpu/gpu_tests/cloud_storage_test_base.py
index e16454a..f6e5234 100644
--- a/content/test/gpu/gpu_tests/cloud_storage_test_base.py
+++ b/content/test/gpu/gpu_tests/cloud_storage_test_base.py
@@ -46,8 +46,8 @@
           str(actual_color.b) + "]")
 
 class ValidatorBase(page_test.PageTest):
-  def __init__(self, test_method_name):
-    super(ValidatorBase, self).__init__(test_method_name)
+  def __init__(self):
+    super(ValidatorBase, self).__init__()
     # Parameters for cloud storage reference images.
     self.vendor_id = None
     self.device_id = None
diff --git a/content/test/gpu/gpu_tests/context_lost.py b/content/test/gpu/gpu_tests/context_lost.py
index 0acab35..3e5840d 100644
--- a/content/test/gpu/gpu_tests/context_lost.py
+++ b/content/test/gpu/gpu_tests/context_lost.py
@@ -49,7 +49,7 @@
     # after each run, but if more tests are added which crash the GPU
     # process, then it will.
     super(_ContextLostValidator, self).__init__(
-      'ValidatePage', needs_browser_restart_after_each_page=True)
+      needs_browser_restart_after_each_page=True)
 
   def CustomizeBrowserOptions(self, options):
     options.AppendExtraBrowserArgs(
@@ -102,17 +102,39 @@
           'window.domAutomationController._succeeded'):
           raise page_test.Failure(
             'Test failed (context not restored properly?)')
+    elif page.force_garbage_collection:
+      # Try to corce GC to clean up any contexts not attached to the page.
+      # This method seem unreliable, so the page will also attempt to force
+      # GC through excessive allocations.
+      tab.CollectGarbage()
+      completed = False
+      try:
+        print "Waiting for page to finish."
+        util.WaitFor(lambda: tab.EvaluateJavaScript(
+            'window.domAutomationController._finished'), wait_timeout)
+        completed = True
+      except util.TimeoutException:
+        pass
+
+      if not completed:
+        raise page_test.Failure(
+            'Test didn\'t complete (no context restored event?)')
+      if not tab.EvaluateJavaScript(
+        'window.domAutomationController._succeeded'):
+        raise page_test.Failure(
+          'Test failed (context not restored properly?)')
 
 class WebGLContextLostFromGPUProcessExitPage(page.Page):
   def __init__(self, page_set, base_dir):
     super(WebGLContextLostFromGPUProcessExitPage, self).__init__(
       url='file://webgl.html?query=kill_after_notification',
       page_set=page_set,
-      base_dir=base_dir)
-    self.name = 'ContextLost.WebGLContextLostFromGPUProcessExit'
+      base_dir=base_dir,
+      name='ContextLost.WebGLContextLostFromGPUProcessExit')
     self.script_to_evaluate_on_commit = harness_script
     self.kill_gpu_process = True
     self.number_of_gpu_process_kills = 1
+    self.force_garbage_collection = False
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
@@ -125,16 +147,32 @@
     super(WebGLContextLostFromLoseContextExtensionPage, self).__init__(
       url='file://webgl.html?query=WEBGL_lose_context',
       page_set=page_set,
-      base_dir=base_dir)
-    self.name = 'ContextLost.WebGLContextLostFromLoseContextExtension',
+      base_dir=base_dir,
+      name='ContextLost.WebGLContextLostFromLoseContextExtension')
     self.script_to_evaluate_on_commit = harness_script
     self.kill_gpu_process = False
+    self.force_garbage_collection = False
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
     action_runner.RunAction(WaitAction(
       {'javascript': 'window.domAutomationController._finished'}))
 
+class WebGLContextLostFromQuantityPage(page.Page):
+  def __init__(self, page_set, base_dir):
+    super(WebGLContextLostFromQuantityPage, self).__init__(
+      url='file://webgl.html?query=forced_quantity_loss',
+      page_set=page_set,
+      base_dir=base_dir,
+      name='ContextLost.WebGLContextLostFromQuantity')
+    self.script_to_evaluate_on_commit = harness_script
+    self.kill_gpu_process = False
+    self.force_garbage_collection = True
+
+  def RunNavigateSteps(self, action_runner):
+    action_runner.RunAction(NavigateAction())
+    action_runner.RunAction(WaitAction(
+      {'javascript': 'window.domAutomationController._loaded'}))
 
 class ContextLost(test_module.Test):
   enabled = True
@@ -150,4 +188,7 @@
       serving_dirs=set(['']))
     ps.AddPage(WebGLContextLostFromGPUProcessExitPage(ps, ps.base_dir))
     ps.AddPage(WebGLContextLostFromLoseContextExtensionPage(ps, ps.base_dir))
+    ps.AddPage(WebGLContextLostFromQuantityPage(ps, ps.base_dir))
     return ps
+
+
diff --git a/content/test/gpu/gpu_tests/gpu_process.py b/content/test/gpu/gpu_tests/gpu_process.py
index 9b3c12d..33114dc 100644
--- a/content/test/gpu/gpu_tests/gpu_process.py
+++ b/content/test/gpu/gpu_tests/gpu_process.py
@@ -20,7 +20,7 @@
 
 class _GpuProcessValidator(page_test.PageTest):
   def __init__(self):
-    super(_GpuProcessValidator, self).__init__('ValidatePage',
+    super(_GpuProcessValidator, self).__init__(
         needs_browser_restart_after_each_page=True)
 
   def CustomizeBrowserOptions(self, options):
diff --git a/content/test/gpu/gpu_tests/gpu_rasterization.py b/content/test/gpu/gpu_tests/gpu_rasterization.py
index 700261d..4bcef4b 100644
--- a/content/test/gpu/gpu_tests/gpu_rasterization.py
+++ b/content/test/gpu/gpu_tests/gpu_rasterization.py
@@ -26,9 +26,6 @@
   return tab.EvaluateJavaScript('domAutomationController._succeeded')
 
 class _GpuRasterizationValidator(cloud_storage_test_base.ValidatorBase):
-  def __init__(self):
-    super(_GpuRasterizationValidator, self).__init__('ValidatePage')
-
   def CustomizeBrowserOptions(self, options):
     options.AppendExtraBrowserArgs(['--force-compositing-mode',
                                     '--enable-threaded-compositing',
diff --git a/content/test/gpu/gpu_tests/hardware_accelerated_feature.py b/content/test/gpu/gpu_tests/hardware_accelerated_feature.py
index 5476458..b2386c1 100644
--- a/content/test/gpu/gpu_tests/hardware_accelerated_feature.py
+++ b/content/test/gpu/gpu_tests/hardware_accelerated_feature.py
@@ -26,9 +26,6 @@
 """;
 
 class _HardwareAcceleratedFeatureValidator(page_test.PageTest):
-  def __init__(self):
-    super(_HardwareAcceleratedFeatureValidator, self).__init__('ValidatePage')
-
   def ValidatePage(self, page, tab, results):
     feature = page.feature
     if not tab.EvaluateJavaScript('VerifyHardwareAccelerated("%s")' % feature):
@@ -37,12 +34,12 @@
 def safe_feature_name(feature):
   return feature.lower().replace(' ', '_')
 
-class ChromeGpuPage(page_module.PageWithDefaultRunNavigate):
+class ChromeGpuPage(page_module.Page):
   def __init__(self, page_set, feature):
     super(ChromeGpuPage, self).__init__(
-      url='chrome://gpu', page_set=page_set, base_dir=page_set.base_dir)
-    self.name = ('HardwareAcceleratedFeature.%s_accelerated' %
-                 safe_feature_name(feature))
+      url='chrome://gpu', page_set=page_set, base_dir=page_set.base_dir,
+      name=('HardwareAcceleratedFeature.%s_accelerated' %
+            safe_feature_name(feature)))
     self.feature = feature
     self.script_to_evaluate_on_commit = test_harness_script
 
diff --git a/content/test/gpu/gpu_tests/maps.py b/content/test/gpu/gpu_tests/maps.py
index 4184ff8..bb431fb 100644
--- a/content/test/gpu/gpu_tests/maps.py
+++ b/content/test/gpu/gpu_tests/maps.py
@@ -23,9 +23,6 @@
 from telemetry.page.actions.all_page_actions import *
 
 class _MapsValidator(cloud_storage_test_base.ValidatorBase):
-  def __init__(self):
-    super(_MapsValidator, self).__init__('ValidatePage')
-
   def CustomizeBrowserOptions(self, options):
     options.AppendExtraBrowserArgs('--enable-gpu-benchmarking')
 
@@ -81,10 +78,9 @@
     super(MapsPage, self).__init__(
       url='http://localhost:10020/tracker.html',
       page_set=page_set,
-      base_dir=base_dir)
-    self.name = 'Maps.maps_001'
-    self.script_to_evaluate_on_commit = 'window.screen = null;'
-    self.pixel_expectations = 'data/maps_001_expectations.json'
+      base_dir=base_dir,
+      name='Maps.maps_002')
+    self.pixel_expectations = 'data/maps_002_expectations.json'
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
diff --git a/content/test/gpu/gpu_tests/maps_expectations.py b/content/test/gpu/gpu_tests/maps_expectations.py
index b7147ae..a3ad0fe 100644
--- a/content/test/gpu/gpu_tests/maps_expectations.py
+++ b/content/test/gpu/gpu_tests/maps_expectations.py
@@ -24,4 +24,4 @@
     # self.Fail('Maps.maps_001',
     #     ['mac', 'amd', ('nvidia', 0x1234)], bug=123)
 
-    self.Fail('Maps.maps_001', bug=367173)
+    pass
diff --git a/content/test/gpu/gpu_tests/memory.py b/content/test/gpu/gpu_tests/memory.py
index f45d9bb..b56f737 100644
--- a/content/test/gpu/gpu_tests/memory.py
+++ b/content/test/gpu/gpu_tests/memory.py
@@ -54,9 +54,6 @@
 """ % MEMORY_LIMIT_MB
 
 class _MemoryValidator(page_test.PageTest):
-  def __init__(self):
-    super(_MemoryValidator, self).__init__('ValidatePage')
-
   def ValidatePage(self, page, tab, results):
     timeline_data = tab.browser.StopTracing()
     timeline_model = model.TimelineModel(timeline_data)
diff --git a/content/test/gpu/gpu_tests/pixel.py b/content/test/gpu/gpu_tests/pixel.py
index 7b0e85f..7a1e33f 100644
--- a/content/test/gpu/gpu_tests/pixel.py
+++ b/content/test/gpu/gpu_tests/pixel.py
@@ -47,9 +47,6 @@
   return tab.EvaluateJavaScript('domAutomationController._succeeded')
 
 class _PixelValidator(cloud_storage_test_base.ValidatorBase):
-  def __init__(self):
-    super(_PixelValidator, self).__init__('ValidatePage')
-
   def CustomizeBrowserOptions(self, options):
     options.AppendExtraBrowserArgs('--enable-gpu-benchmarking')
 
diff --git a/content/test/gpu/gpu_tests/screenshot_sync.py b/content/test/gpu/gpu_tests/screenshot_sync.py
index cc62029..03ca595 100644
--- a/content/test/gpu/gpu_tests/screenshot_sync.py
+++ b/content/test/gpu/gpu_tests/screenshot_sync.py
@@ -17,9 +17,6 @@
     util.GetChromiumSrcDir(), 'content', 'test', 'data', 'gpu')
 
 class _ScreenshotSyncValidator(page_test.PageTest):
-  def __init__(self):
-    super(_ScreenshotSyncValidator, self).__init__('ValidatePage')
-
   def CustomizeBrowserOptions(self, options):
     options.AppendExtraBrowserArgs('--enable-gpu-benchmarking')
 
@@ -35,8 +32,8 @@
     super(ScreenshotSyncPage, self).__init__(
       url='file://screenshot_sync.html',
       page_set=page_set,
-      base_dir=base_dir)
-    self.name = 'ScreenshotSync'
+      base_dir=base_dir,
+      name='ScreenshotSync')
     self.user_agent_type = 'desktop'
 
   def RunNavigateSteps(self, action_runner):
diff --git a/content/test/gpu/gpu_tests/webgl_conformance.py b/content/test/gpu/gpu_tests/webgl_conformance.py
index 48c943f..2aa8ab4 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance.py
@@ -64,9 +64,7 @@
 
 class WebglConformanceValidator(page_test.PageTest):
   def __init__(self):
-    super(WebglConformanceValidator, self).__init__('ValidatePage',
-        attempts=1,
-        max_errors=10)
+    super(WebglConformanceValidator, self).__init__(attempts=1, max_errors=10)
 
   def ValidatePage(self, page, tab, results):
     if not _DidWebGLTestSucceed(tab):
@@ -83,10 +81,10 @@
 class WebglConformancePage(page_module.Page):
   def __init__(self, page_set, test):
     super(WebglConformancePage, self).__init__(
-      url='file://' + test, page_set=page_set, base_dir=page_set.base_dir)
-    self.name = ('WebglConformance.%s' %
-                 test.replace('/', '_').replace('-', '_').
-                 replace('\\', '_').rpartition('.')[0].replace('.', '_'))
+      url='file://' + test, page_set=page_set, base_dir=page_set.base_dir,
+      name=('WebglConformance.%s' %
+              test.replace('/', '_').replace('-', '_').
+                 replace('\\', '_').rpartition('.')[0].replace('.', '_')))
     self.script_to_evaluate_on_commit = conformance_harness_script
 
   def RunNavigateSteps(self, action_runner):
@@ -103,7 +101,7 @@
   def AddTestCommandLineArgs(cls, group):
     group.add_option('--webgl-conformance-version',
         help='Version of the WebGL conformance tests to run.',
-        default='1.0.2')
+        default='1.0.3')
 
   def CreatePageSet(self, options):
     tests = self._ParseTests('00_test_list.txt',
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index affa210..ceb5606 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -27,12 +27,14 @@
     # Fails on all platforms
     self.Fail('conformance/glsl/misc/shaders-with-mis-matching-uniforms.html',
         bug=351396)
+    self.Fail('conformance/glsl/misc/boolean_precision.html',
+        bug=368874)
+    self.Fail('conformance/glsl/bugs/nested-structs-with-same-name.html',
+        bug=368910)
 
-    # Temporary suppressions of failures until bugs are fixed.
-    self.Fail('conformance/context/constants-and-properties.html',
-        bug=363842)
-    self.Fail('conformance/rendering/draw-elements-out-of-bounds.html',
-        bug=363869)
+    # Flaky on Win
+    self.Fail('conformance/extensions/webgl-draw-buffers.html',
+        ['win'], bug=369349)
 
     # Win7 / Intel failures
     self.Fail('conformance/rendering/gl-scissor-test.html',
@@ -56,6 +58,8 @@
     # Radar 13499677
     self.Fail('conformance/glsl/functions/glsl-function-smoothstep-gentype.html',
         ['mac', ('intel', 0x116)], bug=225642)
+    self.Fail('conformance/extensions/webgl-draw-buffers.html',
+        ['mac', ('intel', 0x116)], bug=369349)
 
     # Mac 10.8 / Intel HD 3000 failures
     self.Fail('conformance/rendering/gl-scissor-test.html',
@@ -63,6 +67,16 @@
     self.Fail('conformance/ogles/GL/operators/operators_009_to_016.html',
         ['mountainlion', ('intel', 0x116)], bug=322795)
 
+    # Mac Retina failures
+    self.Fail(
+        'conformance/glsl/bugs/array-of-struct-with-int-first-position.html',
+        ['mac', ('nvidia', 0xfd5), ('nvidia', 0xfe9)], bug=368912)
+
+    # Mac 10.8 / ATI failures
+    self.Fail(
+        'conformance/rendering/point-with-gl-pointcoord-in-fragment-shader.html',
+        ['mountainlion', 'amd'])
+
     # Mac 10.7 / Intel failures
     self.Skip('conformance/glsl/functions/glsl-function-asin.html',
         ['lion', 'intel'])
@@ -99,6 +113,9 @@
     # The following test is very slow and therefore times out on Android bot.
     self.Skip('conformance/rendering/multisample-corruption.html',
         ['android'])
+    # The following test times out on Android bot.
+    self.Fail('conformance/uniforms/gl-uniform-arrays.html',
+        ['android'], bug=369300)
     self.Fail('conformance/glsl/misc/empty_main.vert.html',
         ['android'], bug=315976)
     self.Fail('conformance/glsl/misc/gl_position_unset.vert.html',
diff --git a/content/test/gpu/page_sets/PRESUBMIT.py b/content/test/gpu/page_sets/PRESUBMIT.py
index 62bc2b4..d8e3842 100644
--- a/content/test/gpu/page_sets/PRESUBMIT.py
+++ b/content/test/gpu/page_sets/PRESUBMIT.py
@@ -1,4 +1,4 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
+# Copyright (c) 2013 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.
 
@@ -6,69 +6,85 @@
 import re
 import sys
 
+def _GetTelemetryPath(input_api):
+  return os.path.join(
+      os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(
+      input_api.PresubmitLocalPath())))), 'tools', 'telemetry')
 
-# Avoid leaking changes to global sys.path.
-_old_sys_path = sys.path
-try:
-  telemetry_dir = os.path.abspath(os.path.join(
-      os.pardir, os.pardir, os.pardir, os.pardir, 'tools', 'telemetry'))
-  sys.path.append(telemetry_dir)
-  from telemetry.page import cloud_storage
-finally:
-  sys.path = _old_sys_path
+def LoadSupport(input_api):
+  if 'cloud_storage' not in globals():
+    # Avoid leaking changes to global sys.path.
+    _old_sys_path = sys.path
+    try:
+      telemetry_path = _GetTelemetryPath(input_api)
+      sys.path = [telemetry_path] + sys.path
+      from telemetry.page import cloud_storage
+      globals()['cloud_storage'] = cloud_storage
+    finally:
+      sys.path = _old_sys_path
+
+  return globals()['cloud_storage']
 
 
-def _SyncFilesToCloud(input_api, output_api):
-  """Searches for .sha1 files and uploads them to Cloud Storage.
-
-  It validates all the hashes and skips upload if not necessary.
+def _GetFilesNotInCloud(input_api):
+  """Searches for .sha1 files and checks to see if they have already
+  been uploaded Cloud Storage. Returns a list of those that have not.
   """
-  # Look in both buckets, in case the user uploaded the file manually. But this
-  # script focuses on WPR archives, so it only uploads to the internal bucket.
-  hashes_in_cloud_storage = cloud_storage.List(cloud_storage.INTERNAL_BUCKET)
-  hashes_in_cloud_storage += cloud_storage.List(cloud_storage.PUBLIC_BUCKET)
-
-  results = []
+  hash_paths = []
   for affected_file in input_api.AffectedFiles(include_deletes=False):
     hash_path = affected_file.AbsoluteLocalPath()
-    file_path, extension = os.path.splitext(hash_path)
-    if extension != '.sha1':
-      continue
+    _, extension = os.path.splitext(hash_path)
+    if extension == '.sha1':
+      hash_paths.append(hash_path)
+  if not hash_paths:
+    return []
 
-    with open(hash_path, 'rb') as f:
-      file_hash = f.read(1024).rstrip()
-    if file_hash in hashes_in_cloud_storage:
-      results.append(output_api.PresubmitNotifyResult(
-          'File already in Cloud Storage, skipping upload: %s' % hash_path))
-      continue
+  cloud_storage = LoadSupport(input_api)
 
-    if not re.match('^([A-Za-z0-9]{40})$', file_hash):
-      results.append(output_api.PresubmitError(
-          'Hash file does not contain a valid SHA-1 hash: %s' % hash_path))
-      continue
-    if not os.path.exists(file_path):
-      results.append(output_api.PresubmitError(
-          'Hash file exists, but file not found: %s' % hash_path))
-      continue
-    if cloud_storage.GetHash(file_path) != file_hash:
-      results.append(output_api.PresubmitError(
-          'Hash file does not match file\'s actual hash: %s' % hash_path))
-      continue
+  # Look in both buckets, in case the user uploaded the file manually.
+  hashes_in_cloud_storage = cloud_storage.List(cloud_storage.PUBLIC_BUCKET)
+  try:
+    hashes_in_cloud_storage += cloud_storage.List(cloud_storage.INTERNAL_BUCKET)
+  except (cloud_storage.PermissionError, cloud_storage.CredentialsError):
+    pass
 
-    try:
-      cloud_storage.Insert(cloud_storage.INTERNAL_BUCKET, file_hash, file_path)
-      results.append(output_api.PresubmitNotifyResult(
-          'Uploaded file to Cloud Storage: %s' % hash_path))
-    except cloud_storage.CloudStorageError, e:
-      results.append(output_api.PresubmitError(
-          'Unable to upload to Cloud Storage: %s\n\n%s' % (hash_path, e)))
+  files = []
+  for hash_path in hash_paths:
+    file_hash = cloud_storage.ReadHash(hash_path)
+    if file_hash not in hashes_in_cloud_storage:
+      files.append((hash_path, file_hash))
 
+  return files
+
+
+def _VerifyFilesInCloud(input_api, output_api):
+  """Fails presubmit if any .sha1 files have not been previously uploaded to
+  Cloud storage.
+  """
+  results = []
+  hash_paths = _GetFilesNotInCloud(input_api)
+  file_paths = []
+  for hash_path, _ in hash_paths:
+    results.append(output_api.PresubmitError(
+        'Attemping to commit hash file, but corresponding '
+        'data file is not in Cloud Storage: %s' % hash_path))
+    file_paths.append(os.path.splitext(hash_path)[0])
+
+  if len(file_paths) > 0:
+    upload_script_path = os.path.join(
+        _GetTelemetryPath(input_api), 'cloud_storage')
+    results.append(output_api.PresubmitError(
+          'To upload missing files, Run: \n'
+          '%s upload %s google-only' %
+          (upload_script_path, ' '.join(file_paths))))
   return results
 
 
 def CheckChangeOnUpload(input_api, output_api):
-  return _SyncFilesToCloud(input_api, output_api)
+  results = _VerifyFilesInCloud(input_api, output_api)
+  return results
 
 
 def CheckChangeOnCommit(input_api, output_api):
-  return _SyncFilesToCloud(input_api, output_api)
+  results = _VerifyFilesInCloud(input_api, output_api)
+  return results
diff --git a/content/test/gpu/page_sets/data/maps.json b/content/test/gpu/page_sets/data/maps.json
index 60866bd..f0adb1b 100644
--- a/content/test/gpu/page_sets/data/maps.json
+++ b/content/test/gpu/page_sets/data/maps.json
@@ -1,7 +1,7 @@
 {
     "description": "Describes the Web Page Replay archives for a page set. Don't edit by hand! Use record_wpr for updating.",
     "archives": {
-        "maps_001.wpr": [
+        "maps_002.wpr": [
             "http://localhost:10020/tracker.html"
         ]
     }
diff --git a/content/test/gpu/page_sets/data/maps_001.wpr.sha1 b/content/test/gpu/page_sets/data/maps_001.wpr.sha1
deleted file mode 100644
index 50b1bbc..0000000
--- a/content/test/gpu/page_sets/data/maps_001.wpr.sha1
+++ /dev/null
@@ -1 +0,0 @@
-4cb9c238b57522547df5814e7df468bb2e667484
\ No newline at end of file
diff --git a/content/test/gpu/page_sets/data/maps_002.wpr.sha1 b/content/test/gpu/page_sets/data/maps_002.wpr.sha1
new file mode 100644
index 0000000..8c0753b
--- /dev/null
+++ b/content/test/gpu/page_sets/data/maps_002.wpr.sha1
@@ -0,0 +1 @@
+7c703b05d45cadba0499050f425b3bc58df8585a
\ No newline at end of file
diff --git a/content/test/gpu/page_sets/data/maps_001_expectations.json b/content/test/gpu/page_sets/data/maps_002_expectations.json
similarity index 100%
rename from content/test/gpu/page_sets/data/maps_001_expectations.json
rename to content/test/gpu/page_sets/data/maps_002_expectations.json
diff --git a/content/test/gpu/page_sets/gpu_process_tests.py b/content/test/gpu/page_sets/gpu_process_tests.py
index 61ef42c..0089743 100644
--- a/content/test/gpu/page_sets/gpu_process_tests.py
+++ b/content/test/gpu/page_sets/gpu_process_tests.py
@@ -7,12 +7,12 @@
 from telemetry.page import page_set as page_set_module
 
 
-class GpuProcessTestsPage(page_module.PageWithDefaultRunNavigate):
+class GpuProcessTestsPage(page_module.Page):
 
   def __init__(self, url, name, page_set):
-    super(GpuProcessTestsPage, self).__init__(url=url, page_set=page_set)
+    super(GpuProcessTestsPage, self).__init__(url=url, page_set=page_set,
+                                              name=name)
     self.user_agent_type = 'desktop'
-    self.name = name
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
diff --git a/content/test/gpu/page_sets/gpu_rasterization_tests.py b/content/test/gpu/page_sets/gpu_rasterization_tests.py
index 886e1a4..c908a88 100644
--- a/content/test/gpu/page_sets/gpu_rasterization_tests.py
+++ b/content/test/gpu/page_sets/gpu_rasterization_tests.py
@@ -7,15 +7,15 @@
 from telemetry.page import page_set as page_set_module
 
 
-class GpuRasterizationTestsPage(page_module.PageWithDefaultRunNavigate):
+class GpuRasterizationTestsPage(page_module.Page):
 
   def __init__(self, page_set):
     super(GpuRasterizationTestsPage, self).__init__(
       url='file://../../data/gpu/pixel_css3d.html',
-      page_set=page_set)
+      page_set=page_set,
+      name='GpuRasterization.CSS3DBlueBox')
 
     self.user_agent_type = 'desktop'
-    self.name = 'GpuRasterization.CSS3DBlueBox'
     self.expectations = [
       {'comment': 'body-t',
        'color': [255, 255, 255],
diff --git a/content/test/gpu/page_sets/memory_tests.py b/content/test/gpu/page_sets/memory_tests.py
index 6ecf722..2492d22 100644
--- a/content/test/gpu/page_sets/memory_tests.py
+++ b/content/test/gpu/page_sets/memory_tests.py
@@ -7,13 +7,13 @@
 from telemetry.page import page_set as page_set_module
 
 
-class MemoryTestsPage(page_module.PageWithDefaultRunNavigate):
+class MemoryTestsPage(page_module.Page):
 
   def __init__(self, page_set):
     super(MemoryTestsPage, self).__init__(
-      url='file://../../data/gpu/mem_css3d.html', page_set=page_set)
+      url='file://../../data/gpu/mem_css3d.html', page_set=page_set,
+      name='Memory.CSS3D')
     self.user_agent_type = 'desktop'
-    self.name = 'Memory.CSS3D'
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
diff --git a/content/test/gpu/page_sets/page_set_unittest.py b/content/test/gpu/page_sets/page_set_unittest.py
new file mode 100644
index 0000000..8f57972
--- /dev/null
+++ b/content/test/gpu/page_sets/page_set_unittest.py
@@ -0,0 +1,16 @@
+# 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.
+
+import os
+
+from telemetry.core import discover
+from telemetry.page import page_set as page_set_module
+from telemetry.page import page_set_archive_info
+from telemetry.test_util import page_set_smoke_test
+
+
+class PageSetUnitTest(page_set_smoke_test.PageSetSmokeTest):
+
+  def testSmoke(self):
+    self.RunSmokeTest(os.path.dirname(__file__))
diff --git a/content/test/gpu/page_sets/pixel_tests.py b/content/test/gpu/page_sets/pixel_tests.py
index 041ec30..ea75ee0 100644
--- a/content/test/gpu/page_sets/pixel_tests.py
+++ b/content/test/gpu/page_sets/pixel_tests.py
@@ -7,12 +7,11 @@
 from telemetry.page import page_set as page_set_module
 
 
-class PixelTestsPage(page_module.PageWithDefaultRunNavigate):
+class PixelTestsPage(page_module.Page):
 
   def __init__(self, url, name, test_rect, revision, page_set):
-    super(PixelTestsPage, self).__init__(url=url, page_set=page_set)
+    super(PixelTestsPage, self).__init__(url=url, page_set=page_set, name=name)
     self.user_agent_type = 'desktop'
-    self.name = name
     self.test_rect = test_rect
     self.revision = revision
 
diff --git a/content/test/gpu/run_unittests b/content/test/gpu/run_unittests
new file mode 100755
index 0000000..ad8abfc
--- /dev/null
+++ b/content/test/gpu/run_unittests
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+# 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.
+
+import os
+import sys
+
+"""This script runs unit tests for code in gpu_tests/ that does telemetry
+performance measurement.
+
+This script DOES NOT run benchmarks. run_gpu_tests does that.
+"""
+
+sys.path.append(os.path.join(os.path.dirname(__file__),
+    os.pardir, os.pardir, os.pardir, 'tools', 'telemetry'))
+
+from telemetry.unittest import gtest_testrunner
+from telemetry.unittest import run_tests
+
+
+if __name__ == '__main__':
+  top_level_dir = os.path.abspath(os.path.dirname(__file__))
+  runner = gtest_testrunner.GTestTestRunner(print_result_after_run=False)
+  ret = run_tests.Main(sys.argv[1:], top_level_dir, top_level_dir, runner)
+
+  if runner.result:
+    runner.result.PrintSummary()
+    sys.exit(min(ret + runner.result.num_errors, 255))
+  else:
+    sys.exit(ret)
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc
index eb218ab..8f57dee 100644
--- a/content/test/layouttest_support.cc
+++ b/content/test/layouttest_support.cc
@@ -11,6 +11,7 @@
 #include "content/public/common/page_state.h"
 #include "content/renderer/history_entry.h"
 #include "content/renderer/history_serialization.h"
+#include "content/renderer/render_frame_impl.h"
 #include "content/renderer/render_thread_impl.h"
 #include "content/renderer/render_view_impl.h"
 #include "content/renderer/renderer_webkitplatformsupport_impl.h"
@@ -65,6 +66,8 @@
   FrameProxy* render_frame_proxy = new FrameProxy(render_view, routing_id);
   render_frame_proxy->setBaseProxy(GetWebTestProxyBase(render_view));
 
+  UseMockMediaStreams(render_frame_proxy);
+
   return render_frame_proxy;
 }
 
@@ -143,6 +146,75 @@
       SetDeviceScaleFactorForTesting(factor);
 }
 
+void SetDeviceColorProfile(RenderView* render_view, const std::string& name) {
+  std::vector<char> color_profile;
+
+  struct TestColorProfile {
+    char* data() {
+      static unsigned char color_profile_data[] = {
+        0x00,0x00,0x01,0xea,0x54,0x45,0x53,0x54,0x00,0x00,0x00,0x00,
+        0x6d,0x6e,0x74,0x72,0x52,0x47,0x42,0x20,0x58,0x59,0x5a,0x20,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x61,0x63,0x73,0x70,0x74,0x65,0x73,0x74,0x00,0x00,0x00,0x00,
+        0x74,0x65,0x73,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf6,0xd6,
+        0x00,0x01,0x00,0x00,0x00,0x00,0xd3,0x2d,0x74,0x65,0x73,0x74,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,
+        0x63,0x70,0x72,0x74,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x0d,
+        0x64,0x65,0x73,0x63,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x8c,
+        0x77,0x74,0x70,0x74,0x00,0x00,0x01,0x8c,0x00,0x00,0x00,0x14,
+        0x72,0x58,0x59,0x5a,0x00,0x00,0x01,0xa0,0x00,0x00,0x00,0x14,
+        0x67,0x58,0x59,0x5a,0x00,0x00,0x01,0xb4,0x00,0x00,0x00,0x14,
+        0x62,0x58,0x59,0x5a,0x00,0x00,0x01,0xc8,0x00,0x00,0x00,0x14,
+        0x72,0x54,0x52,0x43,0x00,0x00,0x01,0xdc,0x00,0x00,0x00,0x0e,
+        0x67,0x54,0x52,0x43,0x00,0x00,0x01,0xdc,0x00,0x00,0x00,0x0e,
+        0x62,0x54,0x52,0x43,0x00,0x00,0x01,0xdc,0x00,0x00,0x00,0x0e,
+        0x74,0x65,0x78,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x64,0x65,0x73,0x63,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x10,0x77,0x68,0x61,0x63,0x6b,0x65,0x64,0x2e,
+        0x69,0x63,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+        0x58,0x59,0x5a,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xf3,0x52,
+        0x00,0x01,0x00,0x00,0x00,0x01,0x16,0xcc,0x58,0x59,0x5a,0x20,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x8d,0x00,0x00,0xa0,0x2c,
+        0x00,0x00,0x0f,0x95,0x58,0x59,0x5a,0x20,0x00,0x00,0x00,0x00,
+        0x00,0x00,0x26,0x31,0x00,0x00,0x10,0x2f,0x00,0x00,0xbe,0x9b,
+        0x58,0x59,0x5a,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x18,
+        0x00,0x00,0x4f,0xa5,0x00,0x00,0x04,0xfc,0x63,0x75,0x72,0x76,
+        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x33
+      };
+
+      return reinterpret_cast<char*>(color_profile_data);
+    }
+
+    size_t size() {
+      const size_t kColorProfileSizeInBytes = 490u;
+      return kColorProfileSizeInBytes;
+    }
+  };
+
+  if (name == "sRGB") {
+    color_profile.assign(name.data(), name.data() + name.size());
+  } else if (name == "test") {
+    TestColorProfile test;
+    color_profile.assign(test.data(), test.data() + test.size());
+  }
+
+  static_cast<RenderViewImpl*>(render_view)->
+      SetDeviceColorProfileForTesting(color_profile);
+}
+
 void UseSynchronousResizeMode(RenderView* render_view, bool enable) {
   static_cast<RenderViewImpl*>(render_view)->
       UseSynchronousResizeModeForTesting(enable);
@@ -160,10 +232,11 @@
       DisableAutoResizeForTesting(new_size);
 }
 
-void UseMockMediaStreams(RenderView* render_view) {
-  RenderViewImpl* render_view_impl = static_cast<RenderViewImpl*>(render_view);
-  render_view_impl->SetMediaStreamClientForTesting(
-      new TestMediaStreamClient(render_view_impl));
+void UseMockMediaStreams(RenderFrame* render_frame) {
+  RenderFrameImpl* render_frame_impl = static_cast<RenderFrameImpl*>(
+      render_frame);
+  render_frame_impl->SetMediaStreamClientForTesting(
+      new TestMediaStreamClient(render_frame_impl));
 }
 
 struct ToLower {
@@ -193,8 +266,7 @@
     result.append(indent, ' ');
   }
 
-  std::string url =
-      WebTestRunner::normalizeLayoutTestURL(item.urlString().utf8());
+  std::string url = normalizeLayoutTestURL(item.urlString().utf8());
   result.append(url);
   if (!item.target().isEmpty()) {
     result.append(" (in frame \"");
diff --git a/content/test/plugin/plugin_windowed_test.cc b/content/test/plugin/plugin_windowed_test.cc
index c0d6630..546ad21 100644
--- a/content/test/plugin/plugin_windowed_test.cc
+++ b/content/test/plugin/plugin_windowed_test.cc
@@ -130,10 +130,11 @@
     PAINTSTRUCT ps;
     HDC hdc = BeginPaint(window, &ps);
     HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));
-    SelectObject(hdc, brush);
+    HGDIOBJ orig = SelectObject(hdc, brush);
     RECT r;
     GetClientRect(window, &r);
     Rectangle(hdc, 0, 0, r.right, r.bottom);
+    SelectObject(hdc, orig); // restore
     DeleteObject(brush);
     EndPaint(window, &ps);
   }
diff --git a/content/test/test_content_browser_client.cc b/content/test/test_content_browser_client.cc
index 7b9d368..c917f25 100644
--- a/content/test/test_content_browser_client.cc
+++ b/content/test/test_content_browser_client.cc
@@ -4,11 +4,8 @@
 
 #include "content/test/test_content_browser_client.h"
 
-#include <string>
-
 #include "base/files/file_path.h"
 #include "base/logging.h"
-#include "content/test/test_web_contents_view.h"
 
 namespace content {
 
@@ -18,18 +15,6 @@
 TestContentBrowserClient::~TestContentBrowserClient() {
 }
 
-WebContentsViewPort* TestContentBrowserClient::OverrideCreateWebContentsView(
-    WebContents* web_contents,
-    RenderViewHostDelegateView** render_view_host_delegate_view) {
-#if defined(OS_IOS)
-  return NULL;
-#else
-  TestWebContentsView* rv = new TestWebContentsView;
-  *render_view_host_delegate_view = rv;
-  return rv;
-#endif
-}
-
 base::FilePath TestContentBrowserClient::GetDefaultDownloadDirectory() {
   if (!download_dir_.IsValid()) {
     bool result = download_dir_.CreateUniqueTempDir();
diff --git a/content/test/test_content_browser_client.h b/content/test/test_content_browser_client.h
index f0d58bb..b4ff3f9 100644
--- a/content/test/test_content_browser_client.h
+++ b/content/test/test_content_browser_client.h
@@ -19,10 +19,6 @@
  public:
   TestContentBrowserClient();
   virtual ~TestContentBrowserClient();
-
-  virtual WebContentsViewPort* OverrideCreateWebContentsView(
-      WebContents* web_contents,
-      RenderViewHostDelegateView** render_view_host_delegate_view) OVERRIDE;
   virtual base::FilePath GetDefaultDownloadDirectory() OVERRIDE;
 
  private:
diff --git a/content/test/test_media_stream_client.cc b/content/test/test_media_stream_client.cc
index 39fe80a..b0bab2b 100644
--- a/content/test/test_media_stream_client.cc
+++ b/content/test/test_media_stream_client.cc
@@ -37,8 +37,8 @@
 
 namespace content {
 
-TestMediaStreamClient::TestMediaStreamClient(RenderView* render_view)
-    : RenderViewObserver(render_view) {}
+TestMediaStreamClient::TestMediaStreamClient(RenderFrame* render_frame)
+    : RenderFrameObserver(render_frame) {}
 
 TestMediaStreamClient::~TestMediaStreamClient() {}
 
diff --git a/content/test/test_media_stream_client.h b/content/test/test_media_stream_client.h
index 60053a4..9f1e6d5 100644
--- a/content/test/test_media_stream_client.h
+++ b/content/test/test_media_stream_client.h
@@ -6,7 +6,7 @@
 #define CONTENT_TEST_TEST_MEDIA_STREAM_CLIENT_H_
 
 #include "base/callback_forward.h"
-#include "content/public/renderer/render_view_observer.h"
+#include "content/public/renderer/render_frame_observer.h"
 #include "content/renderer/media/media_stream_client.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
 
@@ -14,10 +14,10 @@
 
 // TestMediaStreamClient is a mock implementation of MediaStreamClient used when
 // running layout tests.
-class TestMediaStreamClient : public RenderViewObserver,
+class TestMediaStreamClient : public RenderFrameObserver,
                               public MediaStreamClient {
  public:
-  explicit TestMediaStreamClient(RenderView* render_view);
+  explicit TestMediaStreamClient(RenderFrame* render_frame);
   virtual ~TestMediaStreamClient();
 
   // MediaStreamClient implementation.
diff --git a/content/test/test_render_view_host.cc b/content/test/test_render_view_host.cc
index 2c8fad9..63ca1bb 100644
--- a/content/test/test_render_view_host.cc
+++ b/content/test/test_render_view_host.cc
@@ -68,6 +68,10 @@
   return NULL;
 }
 
+ui::TextInputClient* TestRenderWidgetHostView::GetTextInputClient() {
+  return &text_input_client_;
+}
+
 bool TestRenderWidgetHostView::HasFocus() const {
   return true;
 }
diff --git a/content/test/test_render_view_host.h b/content/test/test_render_view_host.h
index 551c142..3b82382 100644
--- a/content/test/test_render_view_host.h
+++ b/content/test/test_render_view_host.h
@@ -16,6 +16,7 @@
 #include "content/public/common/page_transition_types.h"
 #include "content/public/test/test_renderer_host.h"
 #include "content/test/test_render_frame_host.h"
+#include "ui/base/ime/dummy_text_input_client.h"
 #include "ui/base/layout.h"
 #include "ui/gfx/vector2d_f.h"
 
@@ -62,6 +63,7 @@
   virtual gfx::NativeView GetNativeView() const OVERRIDE;
   virtual gfx::NativeViewId GetNativeViewId() const OVERRIDE;
   virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE;
+  virtual ui::TextInputClient* GetTextInputClient() OVERRIDE;
   virtual bool HasFocus() const OVERRIDE;
   virtual bool IsSurfaceAvailableForCopy() const OVERRIDE;
   virtual void Show() OVERRIDE;
@@ -83,7 +85,7 @@
       uint32 output_surface_id,
       scoped_ptr<cc::CompositorFrame> frame) OVERRIDE;
 
-  // RenderWidgetHostViewPort implementation.
+  // RenderWidgetHostViewBase implementation.
   virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
                            const gfx::Rect& pos) OVERRIDE {}
   virtual void InitAsFullscreen(
@@ -112,9 +114,6 @@
   virtual void SetTooltipText(const base::string16& tooltip_text) OVERRIDE {}
   virtual void SelectionBoundsChanged(
       const ViewHostMsg_SelectionBounds_Params& params) OVERRIDE {}
-#if defined(OS_ANDROID)
-  virtual void SelectionRootBoundsChanged(const gfx::Rect&) OVERRIDE {}
-#endif
   virtual void ScrollOffsetChanged() OVERRIDE {}
   virtual void CopyFromCompositingSurface(
       const gfx::Rect& src_subrect,
@@ -142,9 +141,12 @@
   virtual bool PostProcessEventForPluginIme(
       const NativeWebKeyboardEvent& event) OVERRIDE;
 #elif defined(OS_ANDROID)
+  virtual void SelectionRootBoundsChanged(const gfx::Rect&) OVERRIDE {}
   virtual void ShowDisambiguationPopup(
       const gfx::Rect& target_rect,
       const SkBitmap& zoomed_bitmap) OVERRIDE {}
+  virtual void LockCompositingSurface() OVERRIDE {}
+  virtual void UnlockCompositingSurface() OVERRIDE {}
 #endif
   virtual void GetScreenInfo(blink::WebScreenInfo* results) OVERRIDE {}
   virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE;
@@ -168,6 +170,7 @@
  private:
   bool is_showing_;
   bool did_swap_compositor_frame_;
+  ui::DummyTextInputClient text_input_client_;
 };
 
 #if defined(COMPILER_MSVC)
diff --git a/content/test/test_web_contents_view.cc b/content/test/test_web_contents_view.cc
deleted file mode 100644
index 41a1f30..0000000
--- a/content/test/test_web_contents_view.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "content/test/test_web_contents_view.h"
-
-namespace content {
-
-TestWebContentsView::TestWebContentsView() {
-}
-
-TestWebContentsView::~TestWebContentsView() {
-}
-
-void TestWebContentsView::StartDragging(
-    const DropData& drop_data,
-    blink::WebDragOperationsMask allowed_ops,
-    const gfx::ImageSkia& image,
-    const gfx::Vector2d& image_offset,
-    const DragEventSourceInfo& event_info) {
-}
-
-void TestWebContentsView::UpdateDragCursor(blink::WebDragOperation operation) {
-}
-
-void TestWebContentsView::GotFocus() {
-}
-
-void TestWebContentsView::TakeFocus(bool reverse) {
-}
-
-gfx::NativeView TestWebContentsView::GetNativeView() const {
-  return gfx::NativeView();
-}
-
-gfx::NativeView TestWebContentsView::GetContentNativeView() const {
-  return gfx::NativeView();
-}
-
-gfx::NativeWindow TestWebContentsView::GetTopLevelNativeWindow() const {
-  return gfx::NativeWindow();
-}
-
-void TestWebContentsView::GetContainerBounds(gfx::Rect *out) const {
-}
-
-void TestWebContentsView::OnTabCrashed(base::TerminationStatus status,
-                                       int error_code) {
-}
-
-void TestWebContentsView::SizeContents(const gfx::Size& size) {
-}
-
-void TestWebContentsView::Focus() {
-}
-
-void TestWebContentsView::SetInitialFocus() {
-}
-
-void TestWebContentsView::StoreFocus() {
-}
-
-void TestWebContentsView::RestoreFocus() {
-}
-
-DropData* TestWebContentsView::GetDropData() const {
-  return NULL;
-}
-
-gfx::Rect TestWebContentsView::GetViewBounds() const {
-  return gfx::Rect();
-}
-
-#if defined(OS_MACOSX)
-void TestWebContentsView::SetAllowOverlappingViews(bool overlapping) {
-}
-
-bool TestWebContentsView::GetAllowOverlappingViews() const {
-  return false;
-}
-
-void TestWebContentsView::SetOverlayView(
-    WebContentsView* overlay, const gfx::Point& offset) {
-}
-
-void TestWebContentsView::RemoveOverlayView() {
-}
-#endif
-
-void TestWebContentsView::CreateView(const gfx::Size& initial_size,
-                                     gfx::NativeView context) {
-}
-
-RenderWidgetHostView* TestWebContentsView::CreateViewForWidget(
-    RenderWidgetHost* render_widget_host) {
-  return NULL;
-}
-
-RenderWidgetHostView* TestWebContentsView::CreateViewForPopupWidget(
-    RenderWidgetHost* render_widget_host) {
-  return NULL;
-}
-
-void TestWebContentsView::SetPageTitle(const base::string16& title) {
-}
-
-void TestWebContentsView::RenderViewCreated(RenderViewHost* host) {
-}
-
-void TestWebContentsView::RenderViewSwappedIn(RenderViewHost* host) {
-}
-
-void TestWebContentsView::SetOverscrollControllerEnabled(bool enabled) {
-}
-
-#if defined(OS_MACOSX)
-bool TestWebContentsView::IsEventTracking() const {
-  return false;
-}
-
-void TestWebContentsView::CloseTabAfterEventTracking() {
-}
-#endif
-
-}  // namespace content
diff --git a/content/test/test_web_contents_view.h b/content/test/test_web_contents_view.h
deleted file mode 100644
index 053582e..0000000
--- a/content/test/test_web_contents_view.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CONTENT_TEST_TEST_WEB_CONTENTS_VIEW_H_
-#define CONTENT_TEST_TEST_WEB_CONTENTS_VIEW_H_
-
-#include "base/compiler_specific.h"
-#include "content/port/browser/render_view_host_delegate_view.h"
-#include "content/port/browser/web_contents_view_port.h"
-
-namespace content {
-
-class TestWebContentsView : public WebContentsViewPort,
-                            public RenderViewHostDelegateView {
- public:
-  TestWebContentsView();
-  virtual ~TestWebContentsView();
-
-  // RenderViewHostDelegateView:
-  virtual void StartDragging(const DropData& drop_data,
-                             blink::WebDragOperationsMask allowed_ops,
-                             const gfx::ImageSkia& image,
-                             const gfx::Vector2d& image_offset,
-                             const DragEventSourceInfo& event_info) OVERRIDE;
-  virtual void UpdateDragCursor(blink::WebDragOperation operation) OVERRIDE;
-  virtual void GotFocus() OVERRIDE;
-  virtual void TakeFocus(bool reverse) OVERRIDE;
-
-  // WebContentsView:
-  virtual gfx::NativeView GetNativeView() const OVERRIDE;
-  virtual gfx::NativeView GetContentNativeView() const OVERRIDE;
-  virtual gfx::NativeWindow GetTopLevelNativeWindow() const OVERRIDE;
-  virtual void GetContainerBounds(gfx::Rect *out) const OVERRIDE;
-  virtual void OnTabCrashed(base::TerminationStatus status,
-                            int error_code) OVERRIDE;
-  virtual void SizeContents(const gfx::Size& size) OVERRIDE;
-  virtual void Focus() OVERRIDE;
-  virtual void SetInitialFocus() OVERRIDE;
-  virtual void StoreFocus() OVERRIDE;
-  virtual void RestoreFocus() OVERRIDE;
-  virtual DropData* GetDropData() const OVERRIDE;
-  virtual gfx::Rect GetViewBounds() const OVERRIDE;
-#if defined(OS_MACOSX)
-  virtual void SetAllowOverlappingViews(bool overlapping) OVERRIDE;
-  virtual bool GetAllowOverlappingViews() const OVERRIDE;
-  virtual void SetOverlayView(WebContentsView* overlay,
-                              const gfx::Point& offset) OVERRIDE;
-  virtual void RemoveOverlayView() OVERRIDE;
-#endif
-
-  // WebContentsViewPort:
-  virtual void CreateView(const gfx::Size& initial_size,
-                          gfx::NativeView context) OVERRIDE;
-  virtual RenderWidgetHostView* CreateViewForWidget(
-      RenderWidgetHost* render_widget_host) OVERRIDE;
-  virtual RenderWidgetHostView* CreateViewForPopupWidget(
-      RenderWidgetHost* render_widget_host) OVERRIDE;
-  virtual void SetPageTitle(const base::string16& title) OVERRIDE;
-  virtual void RenderViewCreated(RenderViewHost* host) OVERRIDE;
-  virtual void RenderViewSwappedIn(RenderViewHost* host) OVERRIDE;
-  virtual void SetOverscrollControllerEnabled(bool enabled) OVERRIDE;
-#if defined(OS_MACOSX)
-  virtual bool IsEventTracking() const OVERRIDE;
-  virtual void CloseTabAfterEventTracking() OVERRIDE;
-#endif
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestWebContentsView);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_TEST_TEST_WEB_CONTENTS_VIEW_H_
diff --git a/content/webkit_version.target.darwin-arm.mk b/content/webkit_version.target.darwin-arm.mk
index fb843d7..d516472 100644
--- a/content/webkit_version.target.darwin-arm.mk
+++ b/content/webkit_version.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_webkit_version":
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit_version.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/webkit_version.target.darwin-arm64.mk b/content/webkit_version.target.darwin-arm64.mk
index fb843d7..d516472 100644
--- a/content/webkit_version.target.darwin-arm64.mk
+++ b/content/webkit_version.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_webkit_version":
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit_version.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/webkit_version.target.darwin-mips.mk b/content/webkit_version.target.darwin-mips.mk
index fb843d7..d516472 100644
--- a/content/webkit_version.target.darwin-mips.mk
+++ b/content/webkit_version.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_webkit_version":
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit_version.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/webkit_version.target.darwin-x86.mk b/content/webkit_version.target.darwin-x86.mk
index fb843d7..d516472 100644
--- a/content/webkit_version.target.darwin-x86.mk
+++ b/content/webkit_version.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_webkit_version":
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit_version.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/webkit_version.target.darwin-x86_64.mk b/content/webkit_version.target.darwin-x86_64.mk
index fb843d7..d516472 100644
--- a/content/webkit_version.target.darwin-x86_64.mk
+++ b/content/webkit_version.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_webkit_version":
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit_version.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/webkit_version.target.linux-arm.mk b/content/webkit_version.target.linux-arm.mk
index fb843d7..d516472 100644
--- a/content/webkit_version.target.linux-arm.mk
+++ b/content/webkit_version.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_webkit_version":
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit_version.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/webkit_version.target.linux-arm64.mk b/content/webkit_version.target.linux-arm64.mk
index fb843d7..d516472 100644
--- a/content/webkit_version.target.linux-arm64.mk
+++ b/content/webkit_version.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_webkit_version":
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit_version.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/webkit_version.target.linux-mips.mk b/content/webkit_version.target.linux-mips.mk
index fb843d7..d516472 100644
--- a/content/webkit_version.target.linux-mips.mk
+++ b/content/webkit_version.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_webkit_version":
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit_version.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/webkit_version.target.linux-x86.mk b/content/webkit_version.target.linux-x86.mk
index fb843d7..d516472 100644
--- a/content/webkit_version.target.linux-x86.mk
+++ b/content/webkit_version.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_webkit_version":
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit_version.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/webkit_version.target.linux-x86_64.mk b/content/webkit_version.target.linux-x86_64.mk
index fb843d7..d516472 100644
--- a/content/webkit_version.target.linux-x86_64.mk
+++ b/content/webkit_version.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_webkit_version":
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit_version.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit_version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/content/worker/websharedworker_stub.cc b/content/worker/websharedworker_stub.cc
index a047469..b33e707 100644
--- a/content/worker/websharedworker_stub.cc
+++ b/content/worker/websharedworker_stub.cc
@@ -16,7 +16,6 @@
 #include "content/worker/worker_thread.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
-#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
 #include "third_party/WebKit/public/web/WebSharedWorker.h"
 
 namespace content {
@@ -46,9 +45,6 @@
     // is attached or explicit resume notification is received.
     impl_->pauseWorkerContextOnStart();
   }
-  blink::WebRuntimeFeatures::enablePreciseMemoryInfo(
-      CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableSharedWorkerMemoryInfo));
 
   worker_devtools_agent_.reset(new SharedWorkerDevToolsAgent(route_id, impl_));
   client()->set_devtools_agent(worker_devtools_agent_.get());
diff --git a/content/zygote/zygote_linux.cc b/content/zygote/zygote_linux.cc
index 67b071c..5f922a4 100644
--- a/content/zygote/zygote_linux.cc
+++ b/content/zygote/zygote_linux.cc
@@ -50,6 +50,30 @@
   return -1;
 }
 
+void CreatePipe(base::ScopedFD* read_pipe, base::ScopedFD* write_pipe) {
+  int raw_pipe[2];
+  PCHECK(0 == pipe(raw_pipe));
+  read_pipe->reset(raw_pipe[0]);
+  write_pipe->reset(raw_pipe[1]);
+}
+
+void KillAndReap(pid_t pid, bool use_helper) {
+  if (use_helper) {
+    // Helper children may be forked in another PID namespace, so |pid| might
+    // be meaningless to us; or we just might not be able to directly send it
+    // signals.  So we can't kill it.
+    // Additionally, we're not its parent, so we can't reap it anyway.
+    // TODO(mdempsky): Extend the ZygoteForkDelegate API to handle this.
+    LOG(WARNING) << "Unable to kill or reap helper children";
+    return;
+  }
+
+  // Kill the child process in case it's not already dead, so we can safely
+  // perform a blocking wait.
+  PCHECK(0 == kill(pid, SIGKILL));
+  PCHECK(pid == HANDLE_EINTR(waitpid(pid, NULL, 0)));
+}
+
 }  // namespace
 
 Zygote::Zygote(int sandbox_flags,
@@ -161,6 +185,13 @@
       case kZygoteCommandGetSandboxStatus:
         HandleGetSandboxStatus(fd, pickle, iter);
         return false;
+      case kZygoteCommandForkRealPID:
+        // This shouldn't happen in practice, but some failure paths in
+        // HandleForkRequest (e.g., if ReadArgsAndFork fails during depickling)
+        // could leave this command pending on the socket.
+        LOG(ERROR) << "Unexpected real PID message from browser";
+        NOTREACHED();
+        return false;
       default:
         NOTREACHED();
         break;
@@ -295,6 +326,7 @@
 int Zygote::ForkWithRealPid(const std::string& process_type,
                             const base::GlobalDescriptors::Mapping& fd_mapping,
                             const std::string& channel_id,
+                            base::ScopedFD pid_oracle,
                             std::string* uma_name,
                             int* uma_sample,
                             int* uma_boundary_value) {
@@ -302,50 +334,38 @@
                                                        uma_name,
                                                        uma_sample,
                                                        uma_boundary_value));
-  int dummy_fd;
-  ino_t dummy_inode;
-  int pipe_fds[2] = { -1, -1 };
+
+  base::ScopedFD read_pipe, write_pipe;
   base::ProcessId pid = 0;
-
-  dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0);
-  if (dummy_fd < 0) {
-    LOG(ERROR) << "Failed to create dummy FD";
-    goto error;
-  }
-  if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) {
-    LOG(ERROR) << "Failed to get inode for dummy FD";
-    goto error;
-  }
-  if (pipe(pipe_fds) != 0) {
-    LOG(ERROR) << "Failed to create pipe";
-    goto error;
-  }
-
   if (use_helper) {
-    std::vector<int> fds;
     int ipc_channel_fd = LookUpFd(fd_mapping, kPrimaryIPCChannel);
     if (ipc_channel_fd < 0) {
       DLOG(ERROR) << "Failed to find kPrimaryIPCChannel in FD mapping";
-      goto error;
+      return -1;
     }
+    std::vector<int> fds;
     fds.push_back(ipc_channel_fd);  // kBrowserFDIndex
-    fds.push_back(dummy_fd);  // kDummyFDIndex
-    fds.push_back(pipe_fds[0]);  // kParentFDIndex
+    fds.push_back(pid_oracle.get());  // kPIDOracleFDIndex
     pid = helper_->Fork(process_type, fds, channel_id);
+
+    // Helpers should never return in the child process.
+    CHECK_NE(pid, 0);
   } else {
+    CreatePipe(&read_pipe, &write_pipe);
     pid = fork();
   }
-  if (pid < 0) {
-    goto error;
-  } else if (pid == 0) {
+
+  if (pid == 0) {
     // In the child process.
-    close(pipe_fds[1]);
+    write_pipe.reset();
+
+    // Ping the PID oracle socket so the browser can find our PID.
+    CHECK(SendZygoteChildPing(pid_oracle.get()));
+
+    // Now read back our real PID from the zygote.
     base::ProcessId real_pid;
-    // Wait until the parent process has discovered our PID.  We
-    // should not fork any child processes (which the seccomp
-    // sandbox does) until then, because that can interfere with the
-    // parent's discovery of our PID.
-    if (!base::ReadFromFD(pipe_fds[0], reinterpret_cast<char*>(&real_pid),
+    if (!base::ReadFromFD(read_pipe.get(),
+                          reinterpret_cast<char*>(&real_pid),
                           sizeof(real_pid))) {
       LOG(FATAL) << "Failed to synchronise with parent zygote process";
     }
@@ -361,78 +381,64 @@
     base::debug::TraceLog::GetInstance()->SetProcessID(
         static_cast<int>(real_pid));
 #endif
-    close(pipe_fds[0]);
-    close(dummy_fd);
     return 0;
-  } else {
-    // In the parent process.
-    close(dummy_fd);
-    dummy_fd = -1;
-    close(pipe_fds[0]);
-    pipe_fds[0] = -1;
-    base::ProcessId real_pid;
-    if (UsingSUIDSandbox()) {
-      uint8_t reply_buf[512];
-      Pickle request;
-      request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE);
-      request.WriteUInt64(dummy_inode);
+  }
 
-      const ssize_t r = UnixDomainSocket::SendRecvMsg(
-          GetSandboxFD(), reply_buf, sizeof(reply_buf), NULL,
-          request);
-      if (r == -1) {
-        LOG(ERROR) << "Failed to get child process's real PID";
-        goto error;
-      }
+  // In the parent process.
+  read_pipe.reset();
+  pid_oracle.reset();
 
-      Pickle reply(reinterpret_cast<char*>(reply_buf), r);
-      PickleIterator iter(reply);
-      if (!reply.ReadInt(&iter, &real_pid))
-        goto error;
-      if (real_pid <= 0) {
-        // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already?
-        LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed";
-        goto error;
-      }
-    } else {
-      // If no SUID sandbox is involved then no pid translation is
-      // necessary.
-      real_pid = pid;
-    }
+  // Always receive a real PID from the zygote host, though it might
+  // be invalid (see below).
+  base::ProcessId real_pid;
+  {
+    ScopedVector<base::ScopedFD> recv_fds;
+    char buf[kZygoteMaxMessageLength];
+    const ssize_t len = UnixDomainSocket::RecvMsg(
+        kZygoteSocketPairFd, buf, sizeof(buf), &recv_fds);
+    CHECK_GT(len, 0);
+    CHECK(recv_fds.empty());
 
-    // Now set-up this process to be tracked by the Zygote.
-    if (process_info_map_.find(real_pid) != process_info_map_.end()) {
-      LOG(ERROR) << "Already tracking PID " << real_pid;
-      NOTREACHED();
-    }
-    process_info_map_[real_pid].internal_pid = pid;
-    process_info_map_[real_pid].started_from_helper = use_helper;
+    Pickle pickle(buf, len);
+    PickleIterator iter(pickle);
 
-    // If we're using a helper, we still need to let the child process know
-    // we've discovered its real PID, but we don't actually reveal the PID.
-    const base::ProcessId pid_for_child = use_helper ? 0 : real_pid;
+    int kind;
+    CHECK(pickle.ReadInt(&iter, &kind));
+    CHECK(kind == kZygoteCommandForkRealPID);
+    CHECK(pickle.ReadInt(&iter, &real_pid));
+  }
+
+  // Fork failed.
+  if (pid < 0) {
+    return -1;
+  }
+
+  // If we successfully forked a child, but it crashed without sending
+  // a message to the browser, the browser won't have found its PID.
+  if (real_pid < 0) {
+    KillAndReap(pid, use_helper);
+    return -1;
+  }
+
+  // If we're not using a helper, send the PID back to the child process.
+  if (!use_helper) {
     ssize_t written =
-        HANDLE_EINTR(write(pipe_fds[1], &pid_for_child, sizeof(pid_for_child)));
-    if (written != sizeof(pid_for_child)) {
-      LOG(ERROR) << "Failed to synchronise with child process";
-      goto error;
+        HANDLE_EINTR(write(write_pipe.get(), &real_pid, sizeof(real_pid)));
+    if (written != sizeof(real_pid)) {
+      KillAndReap(pid, use_helper);
+      return -1;
     }
-    close(pipe_fds[1]);
-    return real_pid;
   }
 
- error:
-  if (pid > 0) {
-    if (waitpid(pid, NULL, WNOHANG) == -1)
-      LOG(ERROR) << "Failed to wait for process";
+  // Now set-up this process to be tracked by the Zygote.
+  if (process_info_map_.find(real_pid) != process_info_map_.end()) {
+    LOG(ERROR) << "Already tracking PID " << real_pid;
+    NOTREACHED();
   }
-  if (dummy_fd >= 0)
-    close(dummy_fd);
-  if (pipe_fds[0] >= 0)
-    close(pipe_fds[0]);
-  if (pipe_fds[1] >= 0)
-    close(pipe_fds[1]);
-  return -1;
+  process_info_map_[real_pid].internal_pid = pid;
+  process_info_map_[real_pid].started_from_helper = use_helper;
+
+  return real_pid;
 }
 
 base::ProcessId Zygote::ReadArgsAndFork(const Pickle& pickle,
@@ -469,7 +475,13 @@
   if (numfds != static_cast<int>(fds.size()))
     return -1;
 
-  for (int i = 0; i < numfds; ++i) {
+  // First FD is the PID oracle socket.
+  if (fds.size() < 1)
+    return -1;
+  base::ScopedFD pid_oracle(fds[0]->Pass());
+
+  // Remaining FDs are for the global descriptor mapping.
+  for (int i = 1; i < numfds; ++i) {
     base::GlobalDescriptors::Key key;
     if (!pickle.ReadUInt32(&iter, &key))
       return -1;
@@ -480,8 +492,12 @@
       static_cast<uint32_t>(kSandboxIPCChannel), GetSandboxFD()));
 
   // Returns twice, once per process.
-  base::ProcessId child_pid = ForkWithRealPid(process_type, mapping, channel_id,
-                                              uma_name, uma_sample,
+  base::ProcessId child_pid = ForkWithRealPid(process_type,
+                                              mapping,
+                                              channel_id,
+                                              pid_oracle.Pass(),
+                                              uma_name,
+                                              uma_sample,
                                               uma_boundary_value);
   if (!child_pid) {
     // This is the child process.
diff --git a/content/zygote/zygote_linux.h b/content/zygote/zygote_linux.h
index 4aa2f03..8e1996c 100644
--- a/content/zygote/zygote_linux.h
+++ b/content/zygote/zygote_linux.h
@@ -75,12 +75,16 @@
 
   // This is equivalent to fork(), except that, when using the SUID sandbox, it
   // returns the real PID of the child process as it appears outside the
-  // sandbox, rather than returning the PID inside the sandbox. Optionally, it
-  // fills in uma_name et al with a report the helper wants to make via
-  // UMA_HISTOGRAM_ENUMERATION.
+  // sandbox, rather than returning the PID inside the sandbox.  The child's
+  // real PID is determined by having it call content::SendZygoteChildPing(int)
+  // using the |pid_oracle| descriptor.
+  // Finally, when using a ZygoteForkDelegate helper, |uma_name|, |uma_sample|,
+  // and |uma_boundary_value| may be set if the helper wants to make a UMA
+  // report via UMA_HISTOGRAM_ENUMERATION.
   int ForkWithRealPid(const std::string& process_type,
                       const base::GlobalDescriptors::Mapping& fd_mapping,
                       const std::string& channel_id,
+                      base::ScopedFD pid_oracle,
                       std::string* uma_name,
                       int* uma_sample,
                       int* uma_boundary_value);
diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc
index f94683a..11f0602 100644
--- a/content/zygote/zygote_main_linux.cc
+++ b/content/zygote/zygote_main_linux.cc
@@ -453,11 +453,7 @@
   const bool must_enable_setuid_sandbox =
       linux_sandbox->setuid_sandbox_client()->IsSuidSandboxChild();
   if (must_enable_setuid_sandbox) {
-    // When we're launched through the setuid sandbox, ZygoteHostImpl::Init
-    // arranges for kZygoteIdFd to be a dummy file descriptor to satisfy an
-    // ancient setuid sandbox ABI requirement. However, the descriptor is no
-    // longer needed, so we can simply close it right away now.
-    CHECK_EQ(0, IGNORE_EINTR(close(kZygoteIdFd)));
+    linux_sandbox->setuid_sandbox_client()->CloseDummyFile();
 
     // Let the ZygoteHost know we're booting up.
     CHECK(UnixDomainSocket::SendMsg(kZygoteSocketPairFd,
diff --git a/courgette/courgette.gyp b/courgette/courgette.gyp
index 00c2088..52db0fb 100644
--- a/courgette/courgette.gyp
+++ b/courgette/courgette.gyp
@@ -121,8 +121,7 @@
       'conditions': [
         [ 'os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
diff --git a/courgette/courgette_lib.target.darwin-arm.mk b/courgette/courgette_lib.target.darwin-arm.mk
index d08dcd4..ca8fd6f 100644
--- a/courgette/courgette_lib.target.darwin-arm.mk
+++ b/courgette/courgette_lib.target.darwin-arm.mk
@@ -60,7 +60,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -147,7 +146,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/courgette/courgette_lib.target.darwin-x86.mk b/courgette/courgette_lib.target.darwin-x86.mk
index 15d5c23..c763b9a 100644
--- a/courgette/courgette_lib.target.darwin-x86.mk
+++ b/courgette/courgette_lib.target.darwin-x86.mk
@@ -62,7 +62,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -149,7 +148,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/courgette/courgette_lib.target.darwin-x86_64.mk b/courgette/courgette_lib.target.darwin-x86_64.mk
index 12fe550..989ab73 100644
--- a/courgette/courgette_lib.target.darwin-x86_64.mk
+++ b/courgette/courgette_lib.target.darwin-x86_64.mk
@@ -62,7 +62,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -149,7 +148,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/courgette/courgette_lib.target.linux-arm.mk b/courgette/courgette_lib.target.linux-arm.mk
index d08dcd4..ca8fd6f 100644
--- a/courgette/courgette_lib.target.linux-arm.mk
+++ b/courgette/courgette_lib.target.linux-arm.mk
@@ -60,7 +60,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -147,7 +146,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/courgette/courgette_lib.target.linux-x86.mk b/courgette/courgette_lib.target.linux-x86.mk
index 15d5c23..c763b9a 100644
--- a/courgette/courgette_lib.target.linux-x86.mk
+++ b/courgette/courgette_lib.target.linux-x86.mk
@@ -62,7 +62,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -149,7 +148,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/courgette/courgette_lib.target.linux-x86_64.mk b/courgette/courgette_lib.target.linux-x86_64.mk
index 12fe550..989ab73 100644
--- a/courgette/courgette_lib.target.linux-x86_64.mk
+++ b/courgette/courgette_lib.target.linux-x86_64.mk
@@ -62,7 +62,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -149,7 +148,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/crypto/crypto.gyp b/crypto/crypto.gyp
index e43f976..ec1e278 100644
--- a/crypto/crypto.gyp
+++ b/crypto/crypto.gyp
@@ -180,8 +180,7 @@
       'conditions': [
         [ 'os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            [ '(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            [ 'use_allocator!="none"', {
                 'dependencies': [
                   '../base/allocator/allocator.gyp:allocator',
                 ],
diff --git a/crypto/crypto.target.darwin-arm.mk b/crypto/crypto.target.darwin-arm.mk
index 3631a95..508066c 100644
--- a/crypto/crypto.target.darwin-arm.mk
+++ b/crypto/crypto.target.darwin-arm.mk
@@ -63,7 +63,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -151,7 +150,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/crypto/crypto.target.darwin-x86.mk b/crypto/crypto.target.darwin-x86.mk
index 3a9cc82..f79dd58 100644
--- a/crypto/crypto.target.darwin-x86.mk
+++ b/crypto/crypto.target.darwin-x86.mk
@@ -65,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -153,7 +152,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/crypto/crypto.target.darwin-x86_64.mk b/crypto/crypto.target.darwin-x86_64.mk
index aab3216..285e966 100644
--- a/crypto/crypto.target.darwin-x86_64.mk
+++ b/crypto/crypto.target.darwin-x86_64.mk
@@ -65,7 +65,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +153,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/crypto/crypto.target.linux-arm.mk b/crypto/crypto.target.linux-arm.mk
index 3631a95..508066c 100644
--- a/crypto/crypto.target.linux-arm.mk
+++ b/crypto/crypto.target.linux-arm.mk
@@ -63,7 +63,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -151,7 +150,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/crypto/crypto.target.linux-x86.mk b/crypto/crypto.target.linux-x86.mk
index 3a9cc82..f79dd58 100644
--- a/crypto/crypto.target.linux-x86.mk
+++ b/crypto/crypto.target.linux-x86.mk
@@ -65,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -153,7 +152,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/crypto/crypto.target.linux-x86_64.mk b/crypto/crypto.target.linux-x86_64.mk
index aab3216..285e966 100644
--- a/crypto/crypto.target.linux-x86_64.mk
+++ b/crypto/crypto.target.linux-x86_64.mk
@@ -65,7 +65,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +153,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/dbus/message.cc b/dbus/message.cc
index eaf3c9b..c9219b7 100644
--- a/dbus/message.cc
+++ b/dbus/message.cc
@@ -507,7 +507,7 @@
 
 void MessageWriter::AppendString(const std::string& value) {
   // D-Bus Specification (0.19) says a string "must be valid UTF-8".
-  CHECK(IsStringUTF8(value));
+  CHECK(base::IsStringUTF8(value));
   const char* pointer = value.c_str();
   AppendBasic(DBUS_TYPE_STRING, &pointer);
   // TODO(satorux): It may make sense to return an error here, as the
diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp
index 2b4fed5..ec06dec 100644
--- a/device/bluetooth/bluetooth.gyp
+++ b/device/bluetooth/bluetooth.gyp
@@ -78,8 +78,10 @@
         'bluetooth_socket_chromeos.h',
         'bluetooth_socket_mac.h',
         'bluetooth_socket_mac.mm',
-        'bluetooth_socket_thread_win.cc',
-        'bluetooth_socket_thread_win.h',
+        'bluetooth_socket_net.cc',
+        'bluetooth_socket_net.h',
+        'bluetooth_socket_thread.cc',
+        'bluetooth_socket_thread.h',
         'bluetooth_socket_win.cc',
         'bluetooth_socket_win.h',
         'bluetooth_task_manager_win.cc',
@@ -134,6 +136,8 @@
         'test/mock_bluetooth_device.h',
         'test/mock_bluetooth_discovery_session.cc',
         'test/mock_bluetooth_discovery_session.h',
+        'test/mock_bluetooth_gatt_characteristic.cc',
+        'test/mock_bluetooth_gatt_characteristic.h',
         'test/mock_bluetooth_gatt_service.cc',
         'test/mock_bluetooth_gatt_service.h',
         'test/mock_bluetooth_profile.cc',
diff --git a/device/bluetooth/bluetooth_adapter.cc b/device/bluetooth/bluetooth_adapter.cc
index 58ffcac..3aa39ea 100644
--- a/device/bluetooth/bluetooth_adapter.cc
+++ b/device/bluetooth/bluetooth_adapter.cc
@@ -28,6 +28,10 @@
   STLDeleteValues(&devices_);
 }
 
+base::WeakPtr<BluetoothAdapter> BluetoothAdapter::GetWeakPtrForTesting() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 void BluetoothAdapter::StartDiscoverySession(
     const DiscoverySessionCallback& callback,
     const ErrorCallback& error_callback) {
diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h
index c2f513c..6c9780e 100644
--- a/device/bluetooth/bluetooth_adapter.h
+++ b/device/bluetooth/bluetooth_adapter.h
@@ -101,6 +101,9 @@
   static base::WeakPtr<BluetoothAdapter> CreateAdapter(
       const InitCallback& init_callback);
 
+  // Returns a weak pointer to an existing adapter for testing purposes only.
+  base::WeakPtr<BluetoothAdapter> GetWeakPtrForTesting();
+
   // Adds and removes observers for events on this bluetooth adapter. If
   // monitoring multiple adapters, check the |adapter| parameter of observer
   // methods to determine which adapter is issuing the event.
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_chromeos.cc
index 6ae91e8..c7e8d9a 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.cc
+++ b/device/bluetooth/bluetooth_adapter_chromeos.cc
@@ -9,7 +9,10 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
+#include "base/sequenced_task_runner.h"
+#include "base/single_thread_task_runner.h"
 #include "base/sys_info.h"
+#include "base/thread_task_runner_handle.h"
 #include "chromeos/dbus/bluetooth_adapter_client.h"
 #include "chromeos/dbus/bluetooth_agent_manager_client.h"
 #include "chromeos/dbus/bluetooth_agent_service_provider.h"
@@ -19,6 +22,7 @@
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/bluetooth_device_chromeos.h"
 #include "device/bluetooth/bluetooth_pairing_chromeos.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 using device::BluetoothAdapter;
@@ -64,6 +68,9 @@
     : num_discovery_sessions_(0),
       discovery_request_pending_(false),
       weak_ptr_factory_(this) {
+  ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
+  socket_thread_ = device::BluetoothSocketThread::Get();
+
   DBusThreadManager::Get()->GetBluetoothAdapterClient()->AddObserver(this);
   DBusThreadManager::Get()->GetBluetoothDeviceClient()->AddObserver(this);
   DBusThreadManager::Get()->GetBluetoothInputClient()->AddObserver(this);
@@ -282,7 +289,10 @@
     return;
 
   BluetoothDeviceChromeOS* device_chromeos =
-      new BluetoothDeviceChromeOS(this, object_path);
+      new BluetoothDeviceChromeOS(this,
+                                  object_path,
+                                  ui_task_runner_,
+                                  socket_thread_);
   DCHECK(devices_.find(device_chromeos->GetAddress()) == devices_.end());
 
   devices_[device_chromeos->GetAddress()] = device_chromeos;
@@ -592,13 +602,7 @@
 
   for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin();
        iter != device_paths.end(); ++iter) {
-    BluetoothDeviceChromeOS* device_chromeos =
-        new BluetoothDeviceChromeOS(this, *iter);
-
-    devices_[device_chromeos->GetAddress()] = device_chromeos;
-
-    FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
-                      DeviceAdded(this, device_chromeos));
+    DeviceAdded(*iter);
   }
 }
 
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.h b/device/bluetooth/bluetooth_adapter_chromeos.h
index 905cbc3..024dce8 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.h
+++ b/device/bluetooth/bluetooth_adapter_chromeos.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner.h"
 #include "chromeos/dbus/bluetooth_adapter_client.h"
 #include "chromeos/dbus/bluetooth_agent_service_provider.h"
 #include "chromeos/dbus/bluetooth_device_client.h"
@@ -17,6 +18,10 @@
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_device.h"
 
+namespace device {
+class BluetoothSocketThread;
+}  // namespace device
+
 namespace chromeos {
 
 class BluetoothChromeOSTest;
@@ -230,6 +235,10 @@
   // our own class as its delegate.
   scoped_ptr<BluetoothAgentServiceProvider> agent_;
 
+  // UI thread task runner and socket thread object used to create sockets.
+  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
+  scoped_refptr<device::BluetoothSocketThread> socket_thread_;
+
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothAdapterChromeOS> weak_ptr_factory_;
diff --git a/device/bluetooth/bluetooth_adapter_factory.cc b/device/bluetooth/bluetooth_adapter_factory.cc
index 471ce2f..3395053 100644
--- a/device/bluetooth/bluetooth_adapter_factory.cc
+++ b/device/bluetooth/bluetooth_adapter_factory.cc
@@ -54,6 +54,10 @@
 
 // static
 bool BluetoothAdapterFactory::IsBluetoothAdapterAvailable() {
+  // SetAdapterForTesting() may be used to provide a test or mock adapter
+  // instance even on platforms that would otherwise not support it.
+  if (default_adapter.Get())
+    return true;
 #if defined(OS_CHROMEOS) || defined(OS_WIN)
   return true;
 #elif defined(OS_MACOSX)
@@ -71,10 +75,11 @@
   if (!default_adapter.Get()) {
     default_adapter.Get() =
         BluetoothAdapter::CreateAdapter(base::Bind(&RunAdapterCallbacks));
+    DCHECK(!default_adapter.Get()->IsInitialized());
   }
 
-  DCHECK(!default_adapter.Get()->IsInitialized());
-  adapter_callbacks.Get().push_back(callback);
+  if (!default_adapter.Get()->IsInitialized())
+    adapter_callbacks.Get().push_back(callback);
 #else  // !defined(OS_WIN)
   if (!default_adapter.Get()) {
     default_adapter.Get() =
@@ -82,8 +87,17 @@
   }
 
   DCHECK(default_adapter.Get()->IsInitialized());
-  callback.Run(scoped_refptr<BluetoothAdapter>(default_adapter.Get().get()));
 #endif  // defined(OS_WIN)
+
+  if (default_adapter.Get()->IsInitialized())
+    callback.Run(scoped_refptr<BluetoothAdapter>(default_adapter.Get().get()));
+
+}
+
+// static
+void BluetoothAdapterFactory::SetAdapterForTesting(
+    scoped_refptr<BluetoothAdapter> adapter) {
+  default_adapter.Get() = adapter->GetWeakPtrForTesting();
 }
 
 // static
diff --git a/device/bluetooth/bluetooth_adapter_factory.h b/device/bluetooth/bluetooth_adapter_factory.h
index e9dcee4..0e61a2c 100644
--- a/device/bluetooth/bluetooth_adapter_factory.h
+++ b/device/bluetooth/bluetooth_adapter_factory.h
@@ -28,6 +28,11 @@
   // use.
   static void GetAdapter(const AdapterCallback& callback);
 
+  // Sets the shared instance of the default adapter for testing purposes only,
+  // no reference is retained after completion of the call, removing the last
+  // reference will reset the factory.
+  static void SetAdapterForTesting(scoped_refptr<BluetoothAdapter> adapter);
+
   // Returns true iff the implementation has a (non-NULL) shared instance of the
   // adapter. Exposed for testing.
   static bool HasSharedInstanceForTesting();
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm
index 5fb53a3..fe5f888 100644
--- a/device/bluetooth/bluetooth_adapter_mac.mm
+++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -31,10 +31,6 @@
 - (BluetoothHCIPowerState)powerState;
 @end
 
-@interface IOBluetoothDevice (LionSDKDeclarations)
-- (NSString*)addressString;
-@end
-
 @protocol IOBluetoothDeviceInquiryDelegate
 - (void)deviceInquiryStarted:(IOBluetoothDeviceInquiry*)sender;
 - (void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender
@@ -232,9 +228,8 @@
 
   if (controller != nil) {
     name = base::SysNSStringToUTF8([controller nameAsString]);
-    // TODO(isherman): Convert the address format to XX:XX:XX:XX:XX:XX rather
-    // than xx-xx-xx-xx-xx-xx.
-    address = base::SysNSStringToUTF8([controller addressAsString]);
+    address = BluetoothDeviceMac::NormalizeAddress(
+        base::SysNSStringToUTF8([controller addressAsString]));
     powered = ([controller powerState] == kBluetoothHCIPowerStateON);
   }
 
@@ -273,8 +268,7 @@
 void BluetoothAdapterMac::UpdateDevices(NSArray* devices) {
   STLDeleteValues(&devices_);
   for (IOBluetoothDevice* device in devices) {
-    std::string device_address =
-        base::SysNSStringToUTF8([device addressString]);
+    std::string device_address = BluetoothDeviceMac::GetDeviceAddress(device);
     devices_[device_address] = new BluetoothDeviceMac(device);
   }
 }
@@ -298,7 +292,7 @@
 void BluetoothAdapterMac::DeviceFound(IOBluetoothDeviceInquiry* inquiry,
                                       IOBluetoothDevice* device) {
   DCHECK_EQ(device_inquiry_, inquiry);
-  std::string device_address = base::SysNSStringToUTF8([device addressString]);
+  std::string device_address = BluetoothDeviceMac::GetDeviceAddress(device);
   if (discovered_devices_.find(device_address) == discovered_devices_.end()) {
     BluetoothDeviceMac device_mac(device);
     FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
diff --git a/device/bluetooth/bluetooth_adapter_win.cc b/device/bluetooth/bluetooth_adapter_win.cc
index 06877e2..8b594e6 100644
--- a/device/bluetooth/bluetooth_adapter_win.cc
+++ b/device/bluetooth/bluetooth_adapter_win.cc
@@ -14,7 +14,7 @@
 #include "base/stl_util.h"
 #include "base/thread_task_runner_handle.h"
 #include "device/bluetooth/bluetooth_device_win.h"
-#include "device/bluetooth/bluetooth_socket_thread_win.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
 #include "device/bluetooth/bluetooth_task_manager_win.h"
 
 namespace device {
@@ -249,7 +249,7 @@
 
 void BluetoothAdapterWin::Init() {
   ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
-  socket_thread_ = BluetoothSocketThreadWin::Get();
+  socket_thread_ = BluetoothSocketThread::Get();
   task_manager_ =
       new BluetoothTaskManagerWin(ui_task_runner_);
   task_manager_->AddObserver(this);
diff --git a/device/bluetooth/bluetooth_adapter_win.h b/device/bluetooth/bluetooth_adapter_win.h
index 7aecb49..7af58ad 100644
--- a/device/bluetooth/bluetooth_adapter_win.h
+++ b/device/bluetooth/bluetooth_adapter_win.h
@@ -26,7 +26,7 @@
 
 class BluetoothAdapterWinTest;
 class BluetoothDevice;
-class BluetoothSocketThreadWin;
+class BluetoothSocketThread;
 
 class BluetoothAdapterWin : public BluetoothAdapter,
                             public BluetoothTaskManagerWin::Observer {
@@ -75,7 +75,7 @@
   const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner() const {
     return ui_task_runner_;
   }
-  const scoped_refptr<BluetoothSocketThreadWin>& socket_thread() const {
+  const scoped_refptr<BluetoothSocketThread>& socket_thread() const {
     return socket_thread_;
   }
 
@@ -127,7 +127,7 @@
   size_t num_discovery_listeners_;
 
   scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
-  scoped_refptr<BluetoothSocketThreadWin> socket_thread_;
+  scoped_refptr<BluetoothSocketThread> socket_thread_;
   scoped_refptr<BluetoothTaskManagerWin> task_manager_;
 
   base::ThreadChecker thread_checker_;
diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h
index 220066c..7dce44f 100644
--- a/device/bluetooth/bluetooth_device.h
+++ b/device/bluetooth/bluetooth_device.h
@@ -21,6 +21,7 @@
 class BluetoothGattService;
 class BluetoothProfile;
 class BluetoothSocket;
+class BluetoothUUID;
 
 struct BluetoothOutOfBandPairingData;
 
@@ -304,12 +305,6 @@
   // confirmation of a displayed passkey.
   virtual bool ExpectingConfirmation() const = 0;
 
-  // SocketCallback is used by ConnectToService to return a BluetoothSocket to
-  // the caller, or NULL if there was an error.  The socket will remain open
-  // until the last reference to the returned BluetoothSocket is released.
-  typedef base::Callback<void(scoped_refptr<BluetoothSocket>)>
-      SocketCallback;
-
   // Initiates a connection to the device, pairing first if necessary.
   //
   // Method calls will be made on the supplied object |pairing_delegate|
@@ -380,6 +375,22 @@
       const base::Closure& callback,
       const ConnectToProfileErrorCallback& error_callback) = 0;
 
+  // Attempts to initiate an outgoing L2CAP or RFCOMM connection to the
+  // advertised service on this device matching |uuid|, performing an SDP lookup
+  // if necessary to determine the correct protocol and channel for the
+  // connection. |callback| will be called on a successful connection with a
+  // BluetoothSocket instance that is to be owned by the receiver.
+  // |error_callback| will be called on failure with a message indicating the
+  // cause.
+  typedef base::Callback<void(scoped_refptr<BluetoothSocket>)>
+      ConnectToServiceCallback;
+  typedef base::Callback<void(const std::string& message)>
+      ConnectToServiceErrorCallback;
+  virtual void ConnectToService(
+      const BluetoothUUID& uuid,
+      const ConnectToServiceCallback& callback,
+      const ConnectToServiceErrorCallback& error_callback) = 0;
+
   // Sets the Out Of Band pairing data for this device to |data|.  Exactly one
   // of |callback| or |error_callback| will be run.
   virtual void SetOutOfBandPairingData(
diff --git a/device/bluetooth/bluetooth_device_chromeos.cc b/device/bluetooth/bluetooth_device_chromeos.cc
index e894136..0535927 100644
--- a/device/bluetooth/bluetooth_device_chromeos.cc
+++ b/device/bluetooth/bluetooth_device_chromeos.cc
@@ -7,6 +7,7 @@
 #include <stdio.h>
 
 #include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/metrics/histogram.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -21,9 +22,14 @@
 #include "device/bluetooth/bluetooth_profile_chromeos.h"
 #include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
 #include "device/bluetooth/bluetooth_socket.h"
+#include "device/bluetooth/bluetooth_socket_chromeos.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
+#include "device/bluetooth/bluetooth_uuid.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 using device::BluetoothDevice;
+using device::BluetoothSocket;
+using device::BluetoothUUID;
 
 namespace {
 
@@ -116,10 +122,14 @@
 
 BluetoothDeviceChromeOS::BluetoothDeviceChromeOS(
     BluetoothAdapterChromeOS* adapter,
-    const dbus::ObjectPath& object_path)
+    const dbus::ObjectPath& object_path,
+    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+    scoped_refptr<device::BluetoothSocketThread> socket_thread)
     : adapter_(adapter),
       object_path_(object_path),
       num_connecting_calls_(0),
+      ui_task_runner_(ui_task_runner),
+      socket_thread_(socket_thread),
       weak_ptr_factory_(this) {
   DBusThreadManager::Get()->GetBluetoothGattServiceClient()->AddObserver(this);
 
@@ -426,6 +436,14 @@
               error_callback));
 }
 
+void BluetoothDeviceChromeOS::ConnectToService(
+    const BluetoothUUID& uuid,
+    const ConnectToServiceCallback& callback,
+    const ConnectToServiceErrorCallback& error_callback) {
+  // TODO(keybuk): implement
+  NOTIMPLEMENTED();
+}
+
 void BluetoothDeviceChromeOS::SetOutOfBandPairingData(
     const device::BluetoothOutOfBandPairingData& data,
     const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_device_chromeos.h b/device/bluetooth/bluetooth_device_chromeos.h
index 96265ae..4132789 100644
--- a/device/bluetooth/bluetooth_device_chromeos.h
+++ b/device/bluetooth/bluetooth_device_chromeos.h
@@ -7,14 +7,20 @@
 
 #include <string>
 
+#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
+#include "base/sequenced_task_runner.h"
 #include "chromeos/dbus/bluetooth_device_client.h"
 #include "chromeos/dbus/bluetooth_gatt_service_client.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_device.h"
 
+namespace device {
+class BluetoothSocketThread;
+}  // namespace device
+
 namespace chromeos {
 
 class BluetoothAdapterChromeOS;
@@ -65,6 +71,10 @@
       device::BluetoothProfile* profile,
       const base::Closure& callback,
       const ConnectToProfileErrorCallback& error_callback) OVERRIDE;
+  virtual void ConnectToService(
+      const device::BluetoothUUID& uuid,
+      const ConnectToServiceCallback& callback,
+      const ConnectToServiceErrorCallback& error_callback) OVERRIDE;
   virtual void SetOutOfBandPairingData(
       const device::BluetoothOutOfBandPairingData& data,
       const base::Closure& callback,
@@ -93,8 +103,11 @@
  private:
   friend class BluetoothAdapterChromeOS;
 
-  BluetoothDeviceChromeOS(BluetoothAdapterChromeOS* adapter,
-                          const dbus::ObjectPath& object_path);
+  BluetoothDeviceChromeOS(
+      BluetoothAdapterChromeOS* adapter,
+      const dbus::ObjectPath& object_path,
+      scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+      scoped_refptr<device::BluetoothSocketThread> socket_thread);
   virtual ~BluetoothDeviceChromeOS();
 
   // BluetoothGattServiceClient::Observer overrides.
@@ -172,6 +185,10 @@
   // Number of ongoing calls to Connect().
   int num_connecting_calls_;
 
+  // UI thread task runner and socket thread object used to create sockets.
+  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
+  scoped_refptr<device::BluetoothSocketThread> socket_thread_;
+
   // During pairing this is set to an object that we don't own, but on which
   // we can make method calls to request, display or confirm PIN Codes and
   // Passkeys. Generally it is the object that owns this one.
diff --git a/device/bluetooth/bluetooth_device_mac.h b/device/bluetooth/bluetooth_device_mac.h
index 1503f1d..757f769 100644
--- a/device/bluetooth/bluetooth_device_mac.h
+++ b/device/bluetooth/bluetooth_device_mac.h
@@ -62,6 +62,10 @@
       BluetoothProfile* profile,
       const base::Closure& callback,
       const ConnectToProfileErrorCallback& error_callback) OVERRIDE;
+  virtual void ConnectToService(
+      const BluetoothUUID& uuid,
+      const ConnectToServiceCallback& callback,
+      const ConnectToServiceErrorCallback& error_callback) OVERRIDE;
   virtual void SetOutOfBandPairingData(
       const BluetoothOutOfBandPairingData& data,
       const base::Closure& callback,
@@ -70,6 +74,16 @@
       const base::Closure& callback,
       const ErrorCallback& error_callback) OVERRIDE;
 
+  // Returns the Bluetooth address for the |device|. The returned address has a
+  // normalized format (see below).
+  static std::string GetDeviceAddress(IOBluetoothDevice* device);
+
+  // Returns the address formatted according to Chrome's expectations rather
+  // than per the system convention: octets are separated by colons rather than
+  // by dashes. That is, the returned format is XX:XX:XX:XX:XX:XX rather than
+  // xx-xx-xx-xx-xx-xx.
+  static std::string NormalizeAddress(const std::string& address);
+
  protected:
   // BluetoothDevice override
   virtual std::string GetDeviceName() const OVERRIDE;
diff --git a/device/bluetooth/bluetooth_device_mac.mm b/device/bluetooth/bluetooth_device_mac.mm
index aaeffb8..38134cf 100644
--- a/device/bluetooth/bluetooth_device_mac.mm
+++ b/device/bluetooth/bluetooth_device_mac.mm
@@ -10,12 +10,14 @@
 #include "base/hash.h"
 #include "base/sequenced_task_runner.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #include "device/bluetooth/bluetooth_out_of_band_pairing_data.h"
 #include "device/bluetooth/bluetooth_profile_mac.h"
 #include "device/bluetooth/bluetooth_service_record_mac.h"
 #include "device/bluetooth/bluetooth_socket_mac.h"
+#include "device/bluetooth/bluetooth_uuid.h"
 
 // Replicate specific 10.7 SDK declarations for building with prior SDKs.
 #if !defined(MAC_OS_X_VERSION_10_7) || \
@@ -70,7 +72,7 @@
 }
 
 std::string BluetoothDeviceMac::GetAddress() const {
-  return base::SysNSStringToUTF8([device_ addressString]);
+  return GetDeviceAddress(device_);
 }
 
 BluetoothDevice::VendorIDSource BluetoothDeviceMac::GetVendorIDSource() const {
@@ -199,6 +201,14 @@
       ->Connect(device_, callback, error_callback);
 }
 
+void BluetoothDeviceMac::ConnectToService(
+    const BluetoothUUID& uuid,
+    const ConnectToServiceCallback& callback,
+    const ConnectToServiceErrorCallback& error_callback) {
+  // TODO(keybuk): implement
+  NOTIMPLEMENTED();
+}
+
 void BluetoothDeviceMac::SetOutOfBandPairingData(
     const BluetoothOutOfBandPairingData& data,
     const base::Closure& callback,
@@ -234,4 +244,17 @@
   return power_level;
 }
 
+// static
+std::string BluetoothDeviceMac::GetDeviceAddress(IOBluetoothDevice* device) {
+  return NormalizeAddress(base::SysNSStringToUTF8([device addressString]));
+}
+
+// static
+std::string BluetoothDeviceMac::NormalizeAddress(const std::string& address) {
+  std::string normalized;
+  base::ReplaceChars(address, "-", ":", &normalized);
+  StringToUpperASCII(&normalized);
+  return normalized;
+}
+
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_device_win.cc b/device/bluetooth/bluetooth_device_win.cc
index 53995ff..a06f947 100644
--- a/device/bluetooth/bluetooth_device_win.cc
+++ b/device/bluetooth/bluetooth_device_win.cc
@@ -14,9 +14,10 @@
 #include "device/bluetooth/bluetooth_out_of_band_pairing_data.h"
 #include "device/bluetooth/bluetooth_profile_win.h"
 #include "device/bluetooth/bluetooth_service_record_win.h"
-#include "device/bluetooth/bluetooth_socket_thread_win.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
 #include "device/bluetooth/bluetooth_socket_win.h"
 #include "device/bluetooth/bluetooth_task_manager_win.h"
+#include "device/bluetooth/bluetooth_uuid.h"
 
 namespace {
 
@@ -29,7 +30,7 @@
 BluetoothDeviceWin::BluetoothDeviceWin(
     const BluetoothTaskManagerWin::DeviceState& state,
     scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
-    scoped_refptr<BluetoothSocketThreadWin> socket_thread,
+    scoped_refptr<BluetoothSocketThread> socket_thread,
     net::NetLog* net_log,
     const net::NetLog::Source& net_log_source)
     : BluetoothDevice(),
@@ -212,6 +213,14 @@
                                                       error_callback);
 }
 
+void BluetoothDeviceWin::ConnectToService(
+    const BluetoothUUID& uuid,
+    const ConnectToServiceCallback& callback,
+    const ConnectToServiceErrorCallback& error_callback) {
+  // TODO(keybuk): implement
+  NOTIMPLEMENTED();
+}
+
 void BluetoothDeviceWin::SetOutOfBandPairingData(
     const BluetoothOutOfBandPairingData& data,
     const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_device_win.h b/device/bluetooth/bluetooth_device_win.h
index 128a87c..fa0c752 100644
--- a/device/bluetooth/bluetooth_device_win.h
+++ b/device/bluetooth/bluetooth_device_win.h
@@ -17,14 +17,14 @@
 
 class BluetoothAdapterWin;
 class BluetoothServiceRecord;
-class BluetoothSocketThreadWin;
+class BluetoothSocketThread;
 
 class BluetoothDeviceWin : public BluetoothDevice {
  public:
   explicit BluetoothDeviceWin(
       const BluetoothTaskManagerWin::DeviceState& state,
       scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
-      scoped_refptr<BluetoothSocketThreadWin> socket_thread,
+      scoped_refptr<BluetoothSocketThread> socket_thread,
       net::NetLog* net_log,
       const net::NetLog::Source& net_log_source);
   virtual ~BluetoothDeviceWin();
@@ -68,6 +68,10 @@
       device::BluetoothProfile* profile,
       const base::Closure& callback,
       const ConnectToProfileErrorCallback& error_callback) OVERRIDE;
+  virtual void ConnectToService(
+      const BluetoothUUID& uuid,
+      const ConnectToServiceCallback& callback,
+      const ConnectToServiceErrorCallback& error_callback) OVERRIDE;
   virtual void SetOutOfBandPairingData(
       const BluetoothOutOfBandPairingData& data,
       const base::Closure& callback,
@@ -93,7 +97,7 @@
   void SetVisible(bool visible);
 
   scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
-  scoped_refptr<BluetoothSocketThreadWin> socket_thread_;
+  scoped_refptr<BluetoothSocketThread> socket_thread_;
   net::NetLog* net_log_;
   net::NetLog::Source net_log_source_;
 
diff --git a/device/bluetooth/bluetooth_device_win_unittest.cc b/device/bluetooth/bluetooth_device_win_unittest.cc
index e784863..086f96e2 100644
--- a/device/bluetooth/bluetooth_device_win_unittest.cc
+++ b/device/bluetooth/bluetooth_device_win_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/test/test_simple_task_runner.h"
 #include "device/bluetooth/bluetooth_device_win.h"
 #include "device/bluetooth/bluetooth_service_record.h"
-#include "device/bluetooth/bluetooth_socket_thread_win.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
 #include "device/bluetooth/bluetooth_task_manager_win.h"
 #include "device/bluetooth/bluetooth_uuid.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -65,8 +65,8 @@
 
     scoped_refptr<base::SequencedTaskRunner> ui_task_runner(
         new base::TestSimpleTaskRunner());
-    scoped_refptr<BluetoothSocketThreadWin> socket_thread(
-        BluetoothSocketThreadWin::Get());
+    scoped_refptr<BluetoothSocketThread> socket_thread(
+        BluetoothSocketThread::Get());
     device_.reset(new BluetoothDeviceWin(device_state,
                                          ui_task_runner,
                                          socket_thread,
diff --git a/device/bluetooth/bluetooth_gatt_characteristic.h b/device/bluetooth/bluetooth_gatt_characteristic.h
index 947d8ff..881511c 100644
--- a/device/bluetooth/bluetooth_gatt_characteristic.h
+++ b/device/bluetooth/bluetooth_gatt_characteristic.h
@@ -138,6 +138,11 @@
   virtual std::vector<BluetoothGattDescriptor*>
       GetDescriptors() const = 0;
 
+  // Returns the GATT characteristic descriptor with identifier |identifier| if
+  // it belongs to this GATT characteristic.
+  virtual BluetoothGattDescriptor* GetDescriptor(
+      const std::string& identifier) const = 0;
+
   // Adds a characteristic descriptor to the locally hosted characteristic
   // represented by this instance. This method only makes sense for local
   // characteristics and won't have an effect if this instance represents a
diff --git a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc
index 032ed8c..91a4446 100644
--- a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc
@@ -132,6 +132,9 @@
         gatt_characteristic_added_count_(0),
         gatt_characteristic_removed_count_(0),
         gatt_characteristic_value_changed_count_(0),
+        gatt_descriptor_added_count_(0),
+        gatt_descriptor_removed_count_(0),
+        gatt_descriptor_value_changed_count_(0),
         device_address_(device->GetAddress()),
         gatt_service_id_(service->GetIdentifier()),
         adapter_(adapter) {
@@ -200,10 +203,61 @@
     ++gatt_characteristic_value_changed_count_;
     last_gatt_characteristic_id_ = characteristic->GetIdentifier();
     last_gatt_characteristic_uuid_ = characteristic->GetUUID();
-    last_changed_characteristic_value_ = characteristic->GetValue();
+    last_changed_characteristic_value_ = value;
 
     EXPECT_EQ(service->GetCharacteristic(last_gatt_characteristic_id_),
               characteristic);
+    EXPECT_EQ(service, characteristic->GetService());
+
+    QuitMessageLoop();
+  }
+
+  virtual void GattDescriptorAdded(
+      BluetoothGattCharacteristic* characteristic,
+      BluetoothGattDescriptor* descriptor) OVERRIDE {
+    ASSERT_EQ(gatt_service_id_, characteristic->GetService()->GetIdentifier());
+
+    ++gatt_descriptor_added_count_;
+    last_gatt_descriptor_id_ = descriptor->GetIdentifier();
+    last_gatt_descriptor_uuid_ = descriptor->GetUUID();
+
+    EXPECT_EQ(characteristic->GetDescriptor(last_gatt_descriptor_id_),
+              descriptor);
+    EXPECT_EQ(characteristic, descriptor->GetCharacteristic());
+
+    QuitMessageLoop();
+  }
+
+  virtual void GattDescriptorRemoved(
+      BluetoothGattCharacteristic* characteristic,
+      BluetoothGattDescriptor* descriptor) OVERRIDE {
+    ASSERT_EQ(gatt_service_id_, characteristic->GetService()->GetIdentifier());
+
+    ++gatt_descriptor_removed_count_;
+    last_gatt_descriptor_id_ = descriptor->GetIdentifier();
+    last_gatt_descriptor_uuid_ = descriptor->GetUUID();
+
+    // The characteristic should return NULL for this descriptor..
+    EXPECT_FALSE(characteristic->GetDescriptor(last_gatt_descriptor_id_));
+    EXPECT_EQ(characteristic, descriptor->GetCharacteristic());
+
+    QuitMessageLoop();
+  }
+
+  virtual void GattDescriptorValueChanged(
+      BluetoothGattCharacteristic* characteristic,
+      BluetoothGattDescriptor* descriptor,
+      const std::vector<uint8>& value) OVERRIDE {
+    ASSERT_EQ(gatt_service_id_, characteristic->GetService()->GetIdentifier());
+
+    ++gatt_descriptor_value_changed_count_;
+    last_gatt_descriptor_id_ = descriptor->GetIdentifier();
+    last_gatt_descriptor_uuid_ = descriptor->GetUUID();
+    last_changed_descriptor_value_ = value;
+
+    EXPECT_EQ(characteristic->GetDescriptor(last_gatt_descriptor_id_),
+              descriptor);
+    EXPECT_EQ(characteristic, descriptor->GetCharacteristic());
 
     QuitMessageLoop();
   }
@@ -212,9 +266,15 @@
   int gatt_characteristic_added_count_;
   int gatt_characteristic_removed_count_;
   int gatt_characteristic_value_changed_count_;
+  int gatt_descriptor_added_count_;
+  int gatt_descriptor_removed_count_;
+  int gatt_descriptor_value_changed_count_;
   std::string last_gatt_characteristic_id_;
   BluetoothUUID last_gatt_characteristic_uuid_;
   std::vector<uint8> last_changed_characteristic_value_;
+  std::string last_gatt_descriptor_id_;
+  BluetoothUUID last_gatt_descriptor_uuid_;
+  std::vector<uint8> last_changed_descriptor_value_;
 
  private:
   // Some tests use a message loop since background processing is simulated;
@@ -501,6 +561,10 @@
 
   TestGattServiceObserver service_observer(adapter_, device, service);
   EXPECT_EQ(0, service_observer.gatt_service_changed_count_);
+  EXPECT_EQ(0, service_observer.gatt_descriptor_added_count_);
+  EXPECT_EQ(0, service_observer.gatt_descriptor_removed_count_);
+  EXPECT_EQ(0, service_observer.gatt_descriptor_value_changed_count_);
+
   EXPECT_TRUE(service->GetCharacteristics().empty());
 
   // Run the message loop so that the characteristics appear.
@@ -508,6 +572,10 @@
   EXPECT_EQ(4, service_observer.gatt_service_changed_count_);
 
   // Only the Heart Rate Measurement characteristic has a descriptor.
+  EXPECT_EQ(1, service_observer.gatt_descriptor_added_count_);
+  EXPECT_EQ(0, service_observer.gatt_descriptor_removed_count_);
+  EXPECT_EQ(0, service_observer.gatt_descriptor_value_changed_count_);
+
   BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
       fake_bluetooth_gatt_characteristic_client_->
           GetBodySensorLocationPath().value());
@@ -530,25 +598,40 @@
   EXPECT_FALSE(descriptor->IsLocal());
   EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
             descriptor->GetUUID());
+  EXPECT_EQ(descriptor->GetUUID(),
+            service_observer.last_gatt_descriptor_uuid_);
+  EXPECT_EQ(descriptor->GetIdentifier(),
+            service_observer.last_gatt_descriptor_id_);
 
   // Hide the descriptor.
   fake_bluetooth_gatt_descriptor_client_->HideDescriptor(
       dbus::ObjectPath(descriptor->GetIdentifier()));
   EXPECT_TRUE(characteristic->GetDescriptors().empty());
   EXPECT_EQ(5, service_observer.gatt_service_changed_count_);
+  EXPECT_EQ(1, service_observer.gatt_descriptor_added_count_);
+  EXPECT_EQ(1, service_observer.gatt_descriptor_removed_count_);
+  EXPECT_EQ(0, service_observer.gatt_descriptor_value_changed_count_);
 
   // Expose the descriptor again.
+  service_observer.last_gatt_descriptor_id_.clear();
+  service_observer.last_gatt_descriptor_uuid_ = BluetoothUUID();
   fake_bluetooth_gatt_descriptor_client_->ExposeDescriptor(
       dbus::ObjectPath(characteristic->GetIdentifier()),
       FakeBluetoothGattDescriptorClient::
           kClientCharacteristicConfigurationUUID);
   EXPECT_EQ(6, service_observer.gatt_service_changed_count_);
   EXPECT_EQ(1U, characteristic->GetDescriptors().size());
+  EXPECT_EQ(2, service_observer.gatt_descriptor_added_count_);
+  EXPECT_EQ(1, service_observer.gatt_descriptor_removed_count_);
+  EXPECT_EQ(0, service_observer.gatt_descriptor_value_changed_count_);
 
   descriptor = characteristic->GetDescriptors()[0];
   EXPECT_FALSE(descriptor->IsLocal());
   EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
             descriptor->GetUUID());
+  EXPECT_EQ(descriptor->GetUUID(), service_observer.last_gatt_descriptor_uuid_);
+  EXPECT_EQ(descriptor->GetIdentifier(),
+            service_observer.last_gatt_descriptor_id_);
 }
 
 TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) {
@@ -798,6 +881,7 @@
 
   TestGattServiceObserver service_observer(adapter_, device, service);
   EXPECT_EQ(0, service_observer.gatt_service_changed_count_);
+  EXPECT_EQ(0, service_observer.gatt_descriptor_value_changed_count_);
   EXPECT_TRUE(service->GetCharacteristics().empty());
 
   // Run the message loop so that the characteristics appear.
@@ -834,6 +918,8 @@
   EXPECT_EQ(1, success_callback_count_);
   EXPECT_EQ(0, error_callback_count_);
   EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
+  EXPECT_EQ(4, service_observer.gatt_service_changed_count_);
+  EXPECT_EQ(0, service_observer.gatt_descriptor_value_changed_count_);
 
   // Write value.
   desc_value[0] = 0x03;
@@ -847,6 +933,8 @@
   EXPECT_EQ(0, error_callback_count_);
   EXPECT_FALSE(ValuesEqual(last_read_value_, descriptor->GetValue()));
   EXPECT_TRUE(ValuesEqual(desc_value, descriptor->GetValue()));
+  EXPECT_EQ(4, service_observer.gatt_service_changed_count_);
+  EXPECT_EQ(1, service_observer.gatt_descriptor_value_changed_count_);
 
   // Read new value.
   descriptor->ReadRemoteDescriptor(
@@ -858,6 +946,8 @@
   EXPECT_EQ(0, error_callback_count_);
   EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
   EXPECT_TRUE(ValuesEqual(desc_value, descriptor->GetValue()));
+  EXPECT_EQ(4, service_observer.gatt_service_changed_count_);
+  EXPECT_EQ(1, service_observer.gatt_descriptor_value_changed_count_);
 }
 
 }  // namespace chromeos
diff --git a/device/bluetooth/bluetooth_gatt_service.h b/device/bluetooth/bluetooth_gatt_service.h
index 346772e..16f4ae5 100644
--- a/device/bluetooth/bluetooth_gatt_service.h
+++ b/device/bluetooth/bluetooth_gatt_service.h
@@ -173,6 +173,28 @@
         BluetoothGattService* service,
         BluetoothGattCharacteristic* characteristic) {}
 
+    // Called when the remote GATT characteristic descriptor |descriptor|
+    // belonging to characteristic |characteristic| has been discovered. Don't
+    // cache the arguments as the pointers may become invalid. Instead, use the
+    // specially assigned identifier to obtain a descriptor and cache that
+    // identifier as necessary.
+    //
+    // This method will always be followed by a call to GattServiceChanged,
+    // which can be used by observers to get all the characteristics of a
+    // service and perform the necessary updates. GattDescriptorAdded exists
+    // mostly for convenience.
+    virtual void GattDescriptorAdded(
+        BluetoothGattCharacteristic* characteristic,
+        BluetoothGattDescriptor* descriptor) {}
+
+    // Called when a GATT characteristic descriptor |descriptor| belonging to
+    // characteristic |characteristic| has been removed. This method is for
+    // convenience and will be followed by a call to GattServiceChanged (except
+    // when called after the service gets removed).
+    virtual void GattDescriptorRemoved(
+        BluetoothGattCharacteristic* characteristic,
+        BluetoothGattDescriptor* descriptor) {}
+
     // Called when the value of a characteristic has changed. This might be a
     // result of a read/write request to, or a notification/indication from, a
     // remote GATT characteristic.
@@ -180,6 +202,12 @@
         BluetoothGattService* service,
         BluetoothGattCharacteristic* characteristic,
         const std::vector<uint8>& value) {}
+
+    // Called when the value of a characteristic descriptor has been updated.
+    virtual void GattDescriptorValueChanged(
+        BluetoothGattCharacteristic* characteristic,
+        BluetoothGattDescriptor* descriptor,
+        const std::vector<uint8>& value) {}
   };
 
   // The ErrorCallback is used by methods to asynchronously report errors.
diff --git a/device/bluetooth/bluetooth_profile.cc b/device/bluetooth/bluetooth_profile.cc
index 5cf421c..3454eb2 100644
--- a/device/bluetooth/bluetooth_profile.cc
+++ b/device/bluetooth/bluetooth_profile.cc
@@ -5,7 +5,11 @@
 #include "device/bluetooth/bluetooth_profile.h"
 
 #if defined(OS_CHROMEOS)
+#include "base/sequenced_task_runner.h"
+#include "base/single_thread_task_runner.h"
+#include "base/thread_task_runner_handle.h"
 #include "device/bluetooth/bluetooth_profile_chromeos.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
 #elif defined(OS_MACOSX)
 #include "base/mac/mac_util.h"
 #elif defined(OS_WIN)
@@ -49,7 +53,9 @@
                                 const ProfileCallback& callback) {
 #if defined(OS_CHROMEOS)
   chromeos::BluetoothProfileChromeOS* profile = NULL;
-  profile = new chromeos::BluetoothProfileChromeOS();
+  profile = new chromeos::BluetoothProfileChromeOS(
+      base::ThreadTaskRunnerHandle::Get(),
+      device::BluetoothSocketThread::Get());
   profile->Init(uuid, options, callback);
 #elif defined(OS_MACOSX)
   BluetoothProfile* profile = NULL;
diff --git a/device/bluetooth/bluetooth_profile_chromeos.cc b/device/bluetooth/bluetooth_profile_chromeos.cc
index 2b6e91f..878f51a 100644
--- a/device/bluetooth/bluetooth_profile_chromeos.cc
+++ b/device/bluetooth/bluetooth_profile_chromeos.cc
@@ -30,6 +30,7 @@
 #include "device/bluetooth/bluetooth_profile.h"
 #include "device/bluetooth/bluetooth_socket.h"
 #include "device/bluetooth/bluetooth_socket_chromeos.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 using device::BluetoothAdapter;
@@ -54,8 +55,12 @@
 
 namespace chromeos {
 
-BluetoothProfileChromeOS::BluetoothProfileChromeOS()
-    : weak_ptr_factory_(this) {
+BluetoothProfileChromeOS::BluetoothProfileChromeOS(
+    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+    scoped_refptr<device::BluetoothSocketThread> socket_thread)
+    : ui_task_runner_(ui_task_runner),
+      socket_thread_(socket_thread),
+      weak_ptr_factory_(this) {
 }
 
 BluetoothProfileChromeOS::~BluetoothProfileChromeOS() {
@@ -281,16 +286,45 @@
     return;
   }
 
-  callback.Run(SUCCESS);
+  scoped_refptr<BluetoothSocketChromeOS> socket =
+      BluetoothSocketChromeOS::CreateBluetoothSocket(
+          ui_task_runner_,
+          socket_thread_,
+          NULL,
+          net::NetLog::Source());
+  socket->Connect(fd.Pass(),
+                  base::Bind(&BluetoothProfileChromeOS::OnConnect,
+                             weak_ptr_factory_.GetWeakPtr(),
+                             device_path,
+                             socket,
+                             callback),
+                  base::Bind(&BluetoothProfileChromeOS::OnConnectError,
+                             weak_ptr_factory_.GetWeakPtr(),
+                             callback));
+}
+
+void BluetoothProfileChromeOS::OnConnect(
+    const dbus::ObjectPath& device_path,
+    scoped_refptr<BluetoothSocketChromeOS> socket,
+    const ConfirmationCallback& callback) {
+  VLOG(1) << object_path_.value() << ": Profile connection complete";
 
   BluetoothDeviceChromeOS* device =
       static_cast<BluetoothAdapterChromeOS*>(adapter_.get())->
           GetDeviceWithPath(device_path);
   DCHECK(device);
 
-  scoped_refptr<BluetoothSocket> socket((
-      BluetoothSocketChromeOS::Create(fd.get())));
   connection_callback_.Run(device, socket);
+  callback.Run(SUCCESS);
+}
+
+void BluetoothProfileChromeOS::OnConnectError(
+    const ConfirmationCallback& callback,
+    const std::string& error_message) {
+  VLOG(1) << object_path_.value() << ": Profile connection failed: "
+          << error_message;
+
+  callback.Run(REJECTED);
 }
 
 }  // namespace chromeos
diff --git a/device/bluetooth/bluetooth_profile_chromeos.h b/device/bluetooth/bluetooth_profile_chromeos.h
index fd3ad19..93af714 100644
--- a/device/bluetooth/bluetooth_profile_chromeos.h
+++ b/device/bluetooth/bluetooth_profile_chromeos.h
@@ -11,6 +11,7 @@
 #include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner.h"
 #include "chromeos/chromeos_export.h"
 #include "chromeos/dbus/bluetooth_profile_manager_client.h"
 #include "chromeos/dbus/bluetooth_profile_service_provider.h"
@@ -25,8 +26,14 @@
 
 }  // namespace dbus
 
+namespace device {
+class BluetoothSocketThread;
+}  // namespace device
+
 namespace chromeos {
 
+class BluetoothSocketChromeOS;
+
 // The BluetoothProfileChromeOS class implements BluetoothProfile for the
 // Chrome OS platform.
 class CHROMEOS_EXPORT BluetoothProfileChromeOS
@@ -45,7 +52,9 @@
  private:
   friend class BluetoothProfile;
 
-  BluetoothProfileChromeOS();
+  BluetoothProfileChromeOS(
+      scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+      scoped_refptr<device::BluetoothSocketThread> socket_thread);
   virtual ~BluetoothProfileChromeOS();
 
   // Called by BluetoothProfile::Register to initialize the profile object
@@ -105,6 +114,17 @@
       const ConfirmationCallback& callback,
       scoped_ptr<dbus::FileDescriptor> fd);
 
+  // Methods run after the socket has been connected to a
+  // BluetoothSocketChromeOS instance on the I/O thread, these methods complete
+  // the incoming connection calling both the Bluetooth daemon callback
+  // |callback| to indicate success or failure and calling this object's
+  // new connection callback method.
+  void OnConnect(const dbus::ObjectPath& device_path,
+                 scoped_refptr<BluetoothSocketChromeOS> socket,
+                 const ConfirmationCallback& callback);
+  void OnConnectError(const ConfirmationCallback& callback,
+                      const std::string& error_message);
+
   // UUID of the profile passed during initialization.
   device::BluetoothUUID uuid_;
 
@@ -126,6 +146,10 @@
   // connected socket to profile object owner.
   ConnectionCallback connection_callback_;
 
+  // UI thread task runner and socket thread object used to create sockets.
+  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
+  scoped_refptr<device::BluetoothSocketThread> socket_thread_;
+
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothProfileChromeOS> weak_ptr_factory_;
diff --git a/device/bluetooth/bluetooth_profile_mac.h b/device/bluetooth/bluetooth_profile_mac.h
index 4fef256..a49d7c0 100644
--- a/device/bluetooth/bluetooth_profile_mac.h
+++ b/device/bluetooth/bluetooth_profile_mac.h
@@ -12,12 +12,13 @@
 #include "base/basictypes.h"
 #include "base/callback.h"
 #include "base/mac/scoped_nsobject.h"
+#include "base/memory/weak_ptr.h"
 #include "base/sequenced_task_runner.h"
 #include "device/bluetooth/bluetooth_profile.h"
 #include "device/bluetooth/bluetooth_socket.h"
 #include "device/bluetooth/bluetooth_uuid.h"
 
-@class BluetoothProfileMacHelper;
+@class RFCOMMConnectionListener;
 @class IOBluetoothDevice;
 @class IOBluetoothRFCOMMChannel;
 
@@ -37,6 +38,16 @@
                const base::Closure& success_callback,
                const BluetoothSocket::ErrorCompletionCallback& error_callback);
 
+  // Callback that is invoked when the OS completes an SDP query.
+  // |status| is the returned status from the SDP query. The remaining
+  // parameters are those from |Connect()|.
+  void OnSDPQueryComplete(
+      IOReturn status,
+      IOBluetoothDevice* device,
+      const ConnectionCallback& connection_callback,
+      const base::Closure& success_callback,
+      const BluetoothSocket::ErrorCompletionCallback& error_callback);
+
   // Callback that is invoked when the OS detects a new incoming RFCOMM channel
   // connection. |rfcomm_channel| is the newly opened channel.
   void OnRFCOMMChannelOpened(IOBluetoothRFCOMMChannel* rfcomm_channel);
@@ -54,11 +65,17 @@
 
   // A simple helper that registers for OS notifications and forwards them to
   // |this| profile.
-  base::scoped_nsobject<BluetoothProfileMacHelper> helper_;
+  base::scoped_nsobject<RFCOMMConnectionListener> rfcomm_connection_listener_;
 
   // A handle to the service record registered in the system SDP server.
   // Used to eventually unregister the service.
   const BluetoothSDPServiceRecordHandle service_record_handle_;
+
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate its weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<BluetoothProfileMac> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothProfileMac);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_profile_mac.mm b/device/bluetooth/bluetooth_profile_mac.mm
index 6ef1601..5ac6414 100644
--- a/device/bluetooth/bluetooth_profile_mac.mm
+++ b/device/bluetooth/bluetooth_profile_mac.mm
@@ -23,7 +23,7 @@
     MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
 
 @interface IOBluetoothDevice (LionSDKDeclarations)
-- (NSString*)addressString;
+- (IOReturn)performSDPQuery:(id)target uuids:(NSArray*)uuids;
 @end
 
 #endif  // MAC_OS_X_VERSION_10_7
@@ -32,6 +32,7 @@
 namespace {
 
 const char kNoConnectionCallback[] = "Connection callback not set";
+const char kSDPQueryFailed[] = "SDP query failed";
 const char kProfileNotFound[] = "Profile not found";
 
 // It's safe to use 0 to represent an unregistered service, as implied by the
@@ -39,22 +40,22 @@
 const BluetoothSDPServiceRecordHandle kInvalidServiceRecordHandle = 0;
 
 // Converts |uuid| to a IOBluetoothSDPUUID instance.
-//
-// |uuid| must be in the format of XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
-IOBluetoothSDPUUID* GetIOBluetoothSDPUUID(const std::string& uuid) {
-  DCHECK(uuid.size() == 36);
-  DCHECK(uuid[8] == '-');
-  DCHECK(uuid[13] == '-');
-  DCHECK(uuid[18] == '-');
-  DCHECK(uuid[23] == '-');
-  std::string numbers_only = uuid;
+IOBluetoothSDPUUID* GetIOBluetoothSDPUUID(const BluetoothUUID& uuid) {
+  // The canonical UUID format is XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
+  const std::string uuid_str = uuid.canonical_value();
+  DCHECK_EQ(uuid_str.size(), 36U);
+  DCHECK_EQ(uuid_str[8], '-');
+  DCHECK_EQ(uuid_str[13], '-');
+  DCHECK_EQ(uuid_str[18], '-');
+  DCHECK_EQ(uuid_str[23], '-');
+  std::string numbers_only = uuid_str;
   numbers_only.erase(23, 1);
   numbers_only.erase(18, 1);
   numbers_only.erase(13, 1);
   numbers_only.erase(8, 1);
   std::vector<uint8> uuid_bytes_vector;
   base::HexStringToBytes(numbers_only, &uuid_bytes_vector);
-  DCHECK(uuid_bytes_vector.size() == 16);
+  DCHECK_EQ(uuid_bytes_vector.size(), 16U);
 
   return [IOBluetoothSDPUUID uuidWithBytes:&uuid_bytes_vector.front()
                                     length:uuid_bytes_vector.size()];
@@ -110,7 +111,7 @@
                          forKey:IntToNSString(kServiceNameKey)];
 
   const int kUUIDsKey = kBluetoothSDPAttributeIdentifierServiceClassIDList;
-  NSArray* uuids = @[GetIOBluetoothSDPUUID(uuid.canonical_value())];
+  NSArray* uuids = @[GetIOBluetoothSDPUUID(uuid)];
   [service_definition setObject:uuids forKey:IntToNSString(kUUIDsKey)];
 
   const int kProtocolDefinitionsKey =
@@ -169,9 +170,67 @@
 }  // namespace
 }  // namespace device
 
-// A simple helper class that forwards system notifications to its wrapped
-// |profile_|.
-@interface BluetoothProfileMacHelper : NSObject {
+using device::BluetoothProfile;
+using device::BluetoothProfileMac;
+using device::BluetoothSocket;
+
+// A simple helper class that forwards SDP query completed notifications to its
+// wrapped |profile_|.
+@interface SDPQueryListener : NSObject {
+ @private
+  // The profile that registered for notifications.
+  base::WeakPtr<BluetoothProfileMac> profile_;
+
+  // Callbacks associated with the connect request that triggered this SDP
+  // query.
+  BluetoothProfile::ConnectionCallback connection_callback_;
+  base::Closure success_callback_;
+  BluetoothSocket::ErrorCompletionCallback error_callback_;
+
+  // The device being queried.
+  IOBluetoothDevice* device_;  // weak
+}
+
+- (id)initWithProfile:(base::WeakPtr<BluetoothProfileMac>)profile
+               device:(IOBluetoothDevice*)device
+  connection_callback:(BluetoothProfile::ConnectionCallback)connection_callback
+     success_callback:(base::Closure)success_callback
+       error_callback:(BluetoothSocket::ErrorCompletionCallback)error_callback;
+- (void)sdpQueryComplete:(IOBluetoothDevice*)device status:(IOReturn)status;
+
+@end
+
+@implementation SDPQueryListener
+
+- (id)initWithProfile:(base::WeakPtr<BluetoothProfileMac>)profile
+               device:(IOBluetoothDevice*)device
+  connection_callback:(BluetoothProfile::ConnectionCallback)connection_callback
+     success_callback:(base::Closure)success_callback
+       error_callback:(BluetoothSocket::ErrorCompletionCallback)error_callback {
+  if ((self = [super init])) {
+    profile_ = profile;
+    device_ = device;
+    connection_callback_ = connection_callback;
+    success_callback_ = success_callback;
+    error_callback_ = error_callback;
+  }
+
+  return self;
+}
+
+- (void)sdpQueryComplete:(IOBluetoothDevice*)device status:(IOReturn)status {
+  DCHECK_EQ(device, device_);
+  if (profile_) {
+    profile_->OnSDPQueryComplete(status, device, connection_callback_,
+                                 success_callback_, error_callback_);
+  }
+}
+
+@end
+
+// A simple helper class that forwards RFCOMM channel opened notifications to
+// its wrapped |profile_|.
+@interface RFCOMMConnectionListener : NSObject {
  @private
   // The profile that owns |self|.
   device::BluetoothProfileMac* profile_;  // weak
@@ -188,7 +247,7 @@
 
 @end
 
-@implementation BluetoothProfileMacHelper
+@implementation RFCOMMConnectionListener
 
 - (id)initWithProfile:(device::BluetoothProfileMac*)profile
             channelID:(BluetoothRFCOMMChannelID)channelID {
@@ -218,10 +277,10 @@
                     channel:(IOBluetoothRFCOMMChannel*)rfcommChannel {
   if (notification != rfcommNewChannelNotification_) {
     // This case is reachable if there are pre-existing RFCOMM channels open at
-    // the time that the helper is created. In that case, each existing channel
-    // calls into this method with a different notification than the one this
-    // class registered with. Ignore those; this class is only interested in
-    // channels that have opened since it registered for notifications.
+    // the time that the listener is created. In that case, each existing
+    // channel calls into this method with a different notification than the one
+    // this class registered with. Ignore those; this class is only interested
+    // in channels that have opened since it registered for notifications.
     return;
   }
 
@@ -242,10 +301,11 @@
                                          const Options& options)
     : uuid_(uuid),
       rfcomm_channel_id_(options.channel),
-      helper_([[BluetoothProfileMacHelper alloc]
-                initWithProfile:this
-                      channelID:rfcomm_channel_id_]),
-      service_record_handle_(RegisterService(uuid, options)) {
+      rfcomm_connection_listener_([[RFCOMMConnectionListener alloc]
+                                    initWithProfile:this
+                                          channelID:rfcomm_channel_id_]),
+      service_record_handle_(RegisterService(uuid, options)),
+      weak_ptr_factory_(this) {
   // TODO(isherman): What should happen if there was an error registering the
   // service, i.e. if |service_record_handle_| is |kInvalidServiceRecordHandle|?
   // http://crbug.com/367290
@@ -274,19 +334,43 @@
     return;
   }
 
+  // Perform an SDP query on the |device| to refresh the cache, in case the
+  // services that the |device| advertises have changed since the previous
+  // query.
+  SDPQueryListener* listener =
+      [[SDPQueryListener alloc] initWithProfile:weak_ptr_factory_.GetWeakPtr()
+                                         device:device
+                            connection_callback:connection_callback_
+                               success_callback:success_callback
+                                 error_callback:error_callback];
+  [device performSDPQuery:[listener autorelease]
+                    uuids:@[GetIOBluetoothSDPUUID(uuid_)]];
+}
+
+void BluetoothProfileMac::OnSDPQueryComplete(
+    IOReturn status,
+    IOBluetoothDevice* device,
+    const ConnectionCallback& connection_callback,
+    const base::Closure& success_callback,
+    const BluetoothSocket::ErrorCompletionCallback& error_callback) {
+  if (status != kIOReturnSuccess) {
+    error_callback.Run(kSDPQueryFailed);
+    return;
+  }
+
   IOBluetoothSDPServiceRecord* record = [device
-      getServiceRecordForUUID:GetIOBluetoothSDPUUID(uuid_.canonical_value())];
+      getServiceRecordForUUID:GetIOBluetoothSDPUUID(uuid_)];
   if (record == nil) {
     error_callback.Run(kProfileNotFound);
     return;
   }
 
-  std::string device_address = base::SysNSStringToUTF8([device addressString]);
+  std::string device_address = BluetoothDeviceMac::GetDeviceAddress(device);
   BluetoothSocketMac::Connect(
       record,
       base::Bind(OnConnectSuccess,
                  success_callback,
-                 connection_callback_,
+                 connection_callback,
                  device_address),
       error_callback);
 }
@@ -295,7 +379,7 @@
     IOBluetoothRFCOMMChannel* rfcomm_channel) {
   DCHECK_EQ([rfcomm_channel getChannelID], rfcomm_channel_id_);
   std::string device_address =
-      base::SysNSStringToUTF8([[rfcomm_channel getDevice] addressString]);
+      BluetoothDeviceMac::GetDeviceAddress([rfcomm_channel getDevice]);
   BluetoothSocketMac::AcceptConnection(
       rfcomm_channel,
       base::Bind(OnConnectSuccess,
diff --git a/device/bluetooth/bluetooth_profile_win.cc b/device/bluetooth/bluetooth_profile_win.cc
index 8495224..5bc3a2c 100644
--- a/device/bluetooth/bluetooth_profile_win.cc
+++ b/device/bluetooth/bluetooth_profile_win.cc
@@ -13,7 +13,7 @@
 #include "device/bluetooth/bluetooth_adapter_win.h"
 #include "device/bluetooth/bluetooth_device_win.h"
 #include "device/bluetooth/bluetooth_service_record.h"
-#include "device/bluetooth/bluetooth_socket_thread_win.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
 #include "device/bluetooth/bluetooth_socket_win.h"
 
 namespace {
@@ -119,7 +119,7 @@
 void BluetoothProfileWin::Connect(
     const BluetoothDeviceWin* device,
     scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
-    scoped_refptr<BluetoothSocketThreadWin> socket_thread,
+    scoped_refptr<BluetoothSocketThread> socket_thread,
     net::NetLog* net_log,
     const net::NetLog::Source& source,
     const base::Closure& success_callback,
diff --git a/device/bluetooth/bluetooth_profile_win.h b/device/bluetooth/bluetooth_profile_win.h
index 5e0e914..0222bfd 100644
--- a/device/bluetooth/bluetooth_profile_win.h
+++ b/device/bluetooth/bluetooth_profile_win.h
@@ -23,7 +23,7 @@
 class BluetoothAdapter;
 class BluetoothAdapterWin;
 class BluetoothDeviceWin;
-class BluetoothSocketThreadWin;
+class BluetoothSocketThread;
 class BluetoothSocketWin;
 
 class BluetoothProfileWin : public BluetoothProfile {
@@ -43,7 +43,7 @@
 
   void Connect(const BluetoothDeviceWin* device,
                scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
-               scoped_refptr<BluetoothSocketThreadWin> socket_thread,
+               scoped_refptr<BluetoothSocketThread> socket_thread,
                net::NetLog* net_log,
                const net::NetLog::Source& source,
                const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc
index a2b28a1..bb175e3 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc
@@ -114,6 +114,16 @@
   return descriptors;
 }
 
+device::BluetoothGattDescriptor*
+BluetoothRemoteGattCharacteristicChromeOS::GetDescriptor(
+    const std::string& identifier) const {
+  DescriptorMap::const_iterator iter =
+      descriptors_.find(dbus::ObjectPath(identifier));
+  if (iter == descriptors_.end())
+    return NULL;
+  return iter->second;
+}
+
 bool BluetoothRemoteGattCharacteristicChromeOS::AddDescriptor(
     device::BluetoothGattDescriptor* descriptor) {
   VLOG(1) << "Descriptors cannot be added to a remote GATT characteristic.";
@@ -194,6 +204,8 @@
   DCHECK(descriptor->GetIdentifier() == object_path.value());
   DCHECK(descriptor->GetUUID().IsValid());
   DCHECK(service_);
+
+  service_->NotifyDescriptorAddedOrRemoved(this, descriptor, true /* added */);
   service_->NotifyServiceChanged();
 }
 
@@ -211,9 +223,12 @@
   BluetoothRemoteGattDescriptorChromeOS* descriptor = iter->second;
   DCHECK(descriptor->object_path() == object_path);
   descriptors_.erase(iter);
+
+  service_->NotifyDescriptorAddedOrRemoved(this, descriptor, false /* added */);
   delete descriptor;
 
   DCHECK(service_);
+
   service_->NotifyServiceChanged();
 }
 
@@ -224,8 +239,21 @@
   if (iter == descriptors_.end())
     return;
 
+  // Ignore all property changes except for "Value".
+  BluetoothGattDescriptorClient::Properties* properties =
+      DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
+          GetProperties(object_path);
+  DCHECK(properties);
+  if (property_name != properties->value.name())
+    return;
+
   VLOG(1) << "GATT descriptor property changed: " << object_path.value()
           << ", property: " << property_name;
+
+  DCHECK(service_);
+
+  service_->NotifyDescriptorValueChanged(
+      this, iter->second, properties->value.value());
 }
 
 void BluetoothRemoteGattCharacteristicChromeOS::OnGetValue(
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
index 1a4f045..849655a 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h
@@ -44,6 +44,8 @@
   virtual Permissions GetPermissions() const OVERRIDE;
   virtual std::vector<device::BluetoothGattDescriptor*>
       GetDescriptors() const OVERRIDE;
+  virtual device::BluetoothGattDescriptor* GetDescriptor(
+      const std::string& identifier) const OVERRIDE;
   virtual bool AddDescriptor(
       device::BluetoothGattDescriptor* descriptor) OVERRIDE;
   virtual bool UpdateValue(const std::vector<uint8>& value) OVERRIDE;
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc
index c2a5dbf..f2ec861 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc
@@ -10,6 +10,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "device/bluetooth/bluetooth_device_chromeos.h"
 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
+#include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h"
 
 namespace chromeos {
 
@@ -164,6 +165,32 @@
                     GattServiceChanged(this));
 }
 
+void BluetoothRemoteGattServiceChromeOS::NotifyDescriptorAddedOrRemoved(
+    BluetoothRemoteGattCharacteristicChromeOS* characteristic,
+    BluetoothRemoteGattDescriptorChromeOS* descriptor,
+    bool added) {
+  DCHECK(characteristic->GetService() == this);
+  DCHECK(descriptor->GetCharacteristic() == characteristic);
+  if (added) {
+    FOR_EACH_OBSERVER(device::BluetoothGattService::Observer, observers_,
+                      GattDescriptorAdded(characteristic, descriptor));
+    return;
+  }
+  FOR_EACH_OBSERVER(device::BluetoothGattService::Observer, observers_,
+                    GattDescriptorRemoved(characteristic, descriptor));
+}
+
+void BluetoothRemoteGattServiceChromeOS::NotifyDescriptorValueChanged(
+    BluetoothRemoteGattCharacteristicChromeOS* characteristic,
+    BluetoothRemoteGattDescriptorChromeOS* descriptor,
+    const std::vector<uint8>& value) {
+  DCHECK(characteristic->GetService() == this);
+  DCHECK(descriptor->GetCharacteristic() == characteristic);
+  FOR_EACH_OBSERVER(
+      device::BluetoothGattService::Observer, observers_,
+      GattDescriptorValueChanged(characteristic, descriptor, value));
+}
+
 void BluetoothRemoteGattServiceChromeOS::GattServicePropertyChanged(
     const dbus::ObjectPath& object_path,
     const std::string& property_name){
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
index b781ff2..f86c2ac 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
+++ b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h
@@ -27,6 +27,7 @@
 
 class BluetoothDeviceChromeOS;
 class BluetoothRemoteGattCharacteristicChromeOS;
+class BluetoothRemoteGattDescriptorChromeOS;
 
 // The BluetoothRemoteGattServiceChromeOS class implements BluetootGattService
 // for remote GATT services on the the Chrome OS platform.
@@ -68,6 +69,25 @@
   // service observers when characteristic descriptors get added and removed.
   void NotifyServiceChanged();
 
+  // Notifies its observers that a descriptor |descriptor| belonging to
+  // characteristic |characteristic| has been added or removed. This is used
+  // by BluetoothRemoteGattCharacteristicChromeOS instances to notify service
+  // observers when characteristic descriptors get added and removed. If |added|
+  // is true, an "Added" event will be sent. Otherwise, a "Removed" event will
+  // be sent.
+  void NotifyDescriptorAddedOrRemoved(
+      BluetoothRemoteGattCharacteristicChromeOS* characteristic,
+      BluetoothRemoteGattDescriptorChromeOS* descriptor,
+      bool added);
+
+  // Notifies its observers that the value of a descriptor has changed. Called
+  // by BluetoothRemoteGattCharacteristicChromeOS instances to notify service
+  // observers when the value of one of their descriptors gets updated.
+  void NotifyDescriptorValueChanged(
+      BluetoothRemoteGattCharacteristicChromeOS* characteristic,
+      BluetoothRemoteGattDescriptorChromeOS* descriptor,
+      const std::vector<uint8>& value);
+
  private:
   friend class BluetoothDeviceChromeOS;
 
diff --git a/device/bluetooth/bluetooth_socket.h b/device/bluetooth/bluetooth_socket.h
index a23efa3..7a41a2f 100644
--- a/device/bluetooth/bluetooth_socket.h
+++ b/device/bluetooth/bluetooth_socket.h
@@ -43,7 +43,7 @@
 
   // Gracefully disconnects the socket and calls |callback| upon completion.
   // There is no failure case, as this is a best effort operation.
-  virtual void Disconnect(const base::Closure& callback) = 0;
+  virtual void Disconnect(const base::Closure& success_callback) = 0;
 
   // Receives data from the socket and calls |success_callback| when data is
   // available. |buffer_size| specifies the maximum number of bytes that can be
diff --git a/device/bluetooth/bluetooth_socket_chromeos.cc b/device/bluetooth/bluetooth_socket_chromeos.cc
index 60f8888..86cdc48 100644
--- a/device/bluetooth/bluetooth_socket_chromeos.cc
+++ b/device/bluetooth/bluetooth_socket_chromeos.cc
@@ -4,187 +4,99 @@
 
 #include "device/bluetooth/bluetooth_socket_chromeos.h"
 
-#include <errno.h>
-#include <poll.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
 #include <string>
 
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/safe_strerror_posix.h"
+#include "base/sequenced_task_runner.h"
 #include "base/threading/thread_restrictions.h"
 #include "dbus/file_descriptor.h"
 #include "device/bluetooth/bluetooth_socket.h"
-#include "net/base/io_buffer.h"
+#include "device/bluetooth/bluetooth_socket_net.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+
+namespace {
+
+const char kSocketAlreadyConnected[] = "Socket is already connected.";
+
+}  // namespace
 
 namespace chromeos {
 
-BluetoothSocketChromeOS::BluetoothSocketChromeOS(int fd)
-    : fd_(fd) {
-  // Fetch the socket type so we read from it correctly.
-  int optval;
-  socklen_t opt_len = sizeof optval;
-  if (getsockopt(fd_, SOL_SOCKET, SO_TYPE, &optval, &opt_len) < 0) {
-    // Sequenced packet is the safest assumption since it won't result in
-    // truncated packets.
-    LOG(WARNING) << "Unable to get socket type: " << safe_strerror(errno);
-    optval = SOCK_SEQPACKET;
-  }
+// static
+scoped_refptr<BluetoothSocketChromeOS>
+BluetoothSocketChromeOS::CreateBluetoothSocket(
+    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+    scoped_refptr<device::BluetoothSocketThread> socket_thread,
+    net::NetLog* net_log,
+    const net::NetLog::Source& source) {
+  DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
 
-  if (optval == SOCK_DGRAM || optval == SOCK_SEQPACKET) {
-    socket_type_ = L2CAP;
-  } else {
-    socket_type_ = RFCOMM;
-  }
+  return make_scoped_refptr(
+      new BluetoothSocketChromeOS(
+          ui_task_runner, socket_thread, net_log, source));
+}
+
+BluetoothSocketChromeOS::BluetoothSocketChromeOS(
+    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+    scoped_refptr<device::BluetoothSocketThread> socket_thread,
+    net::NetLog* net_log,
+    const net::NetLog::Source& source)
+    : BluetoothSocketNet(ui_task_runner, socket_thread, net_log, source) {
 }
 
 BluetoothSocketChromeOS::~BluetoothSocketChromeOS() {
-  close(fd_);
 }
 
-void BluetoothSocketChromeOS::Close() { NOTIMPLEMENTED(); }
-
-void BluetoothSocketChromeOS::Disconnect(const base::Closure& callback) {
-  NOTIMPLEMENTED();
-}
-
-void BluetoothSocketChromeOS::Receive(
-    int buffer_size,
-    const ReceiveCompletionCallback& success_callback,
-    const ReceiveErrorCompletionCallback& error_callback) {
-  NOTIMPLEMENTED();
-}
-
-void BluetoothSocketChromeOS::Send(
-    scoped_refptr<net::IOBuffer> buffer,
-    int buffer_size,
-    const SendCompletionCallback& success_callback,
+void BluetoothSocketChromeOS::Connect(
+    scoped_ptr<dbus::FileDescriptor> fd,
+    const base::Closure& success_callback,
     const ErrorCompletionCallback& error_callback) {
-  NOTIMPLEMENTED();
+  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
+
+  socket_thread()->task_runner()->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &BluetoothSocketChromeOS::DoConnect,
+          this,
+          base::Passed(&fd),
+          base::Bind(&BluetoothSocketChromeOS::PostSuccess,
+                     this,
+                     success_callback),
+          base::Bind(&BluetoothSocketChromeOS::PostErrorCompletion,
+                     this,
+                     error_callback)));
 }
 
-#if 0
-bool BluetoothSocketChromeOS::Receive(net::GrowableIOBuffer *buffer) {
+void BluetoothSocketChromeOS::DoConnect(
+    scoped_ptr<dbus::FileDescriptor> fd,
+    const base::Closure& success_callback,
+    const ErrorCompletionCallback& error_callback) {
+  DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread());
   base::ThreadRestrictions::AssertIOAllowed();
-
-  if (socket_type_ == L2CAP) {
-    int count;
-    if (ioctl(fd_, FIONREAD, &count) < 0) {
-      error_message_ = safe_strerror(errno);
-      LOG(WARNING) << "Unable to get waiting data size: " << error_message_;
-      return true;
-    }
-
-    // No bytes waiting can mean either nothing to read, or the other end has
-    // been closed, and reading zero bytes always returns zero.
-    //
-    // We can't do a short read for fear of a race where data arrives between
-    // calls and we trunctate it. So use poll() to check for the POLLHUP flag.
-    if (count == 0) {
-      struct pollfd pollfd;
-
-      pollfd.fd = fd_;
-      pollfd.events = 0;
-      pollfd.revents = 0;
-
-      // Timeout parameter set to 0 so this call will not block.
-      if (HANDLE_EINTR(poll(&pollfd, 1, 0)) < 0) {
-        error_message_ = safe_strerror(errno);
-        LOG(WARNING) << "Unable to check whether socket is closed: "
-                     << error_message_;
-        return false;
-      }
-
-      if (pollfd.revents & POLLHUP) {
-        // TODO(keybuk, youngki): Agree a common way to flag disconnected.
-        error_message_ = "Disconnected";
-        return false;
-      }
-    }
-
-    buffer->SetCapacity(count);
-  } else {
-    buffer->SetCapacity(1024);
-  }
-
-  ssize_t bytes_read;
-  do {
-    if (buffer->RemainingCapacity() == 0)
-      buffer->SetCapacity(buffer->capacity() * 2);
-    bytes_read =
-        HANDLE_EINTR(read(fd_, buffer->data(), buffer->RemainingCapacity()));
-    if (bytes_read > 0)
-      buffer->set_offset(buffer->offset() + bytes_read);
-  } while (socket_type_ == RFCOMM && bytes_read > 0);
-
-  // Ignore an error if at least one read() call succeeded; it'll be returned
-  // the next read() call.
-  if (buffer->offset() > 0)
-    return true;
-
-  if (bytes_read < 0) {
-    if (errno == ECONNRESET || errno == ENOTCONN) {
-      // TODO(keybuk, youngki): Agree a common way to flag disconnected.
-      error_message_ = "Disconnected";
-      return false;
-    } else if (errno != EAGAIN && errno != EWOULDBLOCK) {
-      error_message_ = safe_strerror(errno);
-      return false;
-    }
-  }
-
-  if (bytes_read == 0 && socket_type_ == RFCOMM) {
-    // TODO(keybuk, youngki): Agree a common way to flag disconnected.
-    error_message_ = "Disconnected";
-    return false;
-  }
-
-  return true;
-}
-
-bool BluetoothSocketChromeOS::Send(net::DrainableIOBuffer *buffer) {
-  base::ThreadRestrictions::AssertIOAllowed();
-
-  ssize_t bytes_written;
-  do {
-    bytes_written =
-        HANDLE_EINTR(write(fd_, buffer->data(), buffer->BytesRemaining()));
-    if (bytes_written > 0)
-      buffer->DidConsume(bytes_written);
-  } while (buffer->BytesRemaining() > 0 && bytes_written > 0);
-
-  if (bytes_written < 0) {
-    if (errno == EPIPE || errno == ECONNRESET || errno == ENOTCONN) {
-      // TODO(keybuk, youngki): Agree a common way to flag disconnected.
-      error_message_ = "Disconnected";
-      return false;
-    } else if (errno != EAGAIN && errno != EWOULDBLOCK) {
-      error_message_ = safe_strerror(errno);
-      return false;
-    }
-  }
-
-  return true;
-}
-
-std::string BluetoothSocketChromeOS::GetLastErrorMessage() const {
-  return error_message_;
-}
-#endif
-
-// static
-scoped_refptr<device::BluetoothSocket> BluetoothSocketChromeOS::Create(
-    dbus::FileDescriptor* fd) {
   DCHECK(fd->is_valid());
 
-  BluetoothSocketChromeOS* bluetooth_socket =
-      new BluetoothSocketChromeOS(fd->TakeValue());
-  return scoped_refptr<BluetoothSocketChromeOS>(bluetooth_socket);
+  if (tcp_socket()) {
+    error_callback.Run(kSocketAlreadyConnected);
+    return;
+  }
+
+  ResetTCPSocket();
+
+  // Note: We don't have a meaningful |IPEndPoint|, but that is ok since the
+  // TCPSocket implementation does not actually require one.
+  int net_result = tcp_socket()->AdoptConnectedSocket(fd->value(),
+                                                      net::IPEndPoint());
+  if (net_result != net::OK) {
+    error_callback.Run("Error connecting to socket: " +
+                       std::string(net::ErrorToString(net_result)));
+    return;
+  }
+
+  fd->TakeValue();
+  success_callback.Run();
 }
 
 }  // namespace chromeos
diff --git a/device/bluetooth/bluetooth_socket_chromeos.h b/device/bluetooth/bluetooth_socket_chromeos.h
index 58141b8..8301d5c 100644
--- a/device/bluetooth/bluetooth_socket_chromeos.h
+++ b/device/bluetooth/bluetooth_socket_chromeos.h
@@ -5,67 +5,46 @@
 #ifndef DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_
 #define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_
 
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
 #include "chromeos/chromeos_export.h"
 #include "device/bluetooth/bluetooth_socket.h"
+#include "device/bluetooth/bluetooth_socket_net.h"
 
 namespace dbus {
 class FileDescriptor;
 }  // namespace dbus
 
-namespace net {
-class IOBuffer;
-}  // namespace net
 
 namespace chromeos {
 
 // The BluetoothSocketChromeOS class implements BluetoothSocket for the
 // Chrome OS platform.
 class CHROMEOS_EXPORT BluetoothSocketChromeOS
-    : public device::BluetoothSocket {
+    : public device::BluetoothSocketNet {
  public:
-  // Overriden from BluetoothSocket:
-  virtual void Close() OVERRIDE;
-  virtual void Disconnect(const base::Closure& callback) OVERRIDE;
-  virtual void Receive(int buffer_size,
-                       const ReceiveCompletionCallback& success_callback,
-                       const ReceiveErrorCompletionCallback& error_callback)
-      OVERRIDE;
-  virtual void Send(scoped_refptr<net::IOBuffer> buffer,
-                    int buffer_size,
-                    const SendCompletionCallback& success_callback,
-                    const ErrorCompletionCallback& error_callback) OVERRIDE;
+  static scoped_refptr<BluetoothSocketChromeOS> CreateBluetoothSocket(
+      scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+      scoped_refptr<device::BluetoothSocketThread> socket_thread,
+      net::NetLog* net_log,
+      const net::NetLog::Source& source);
 
-  // Create an instance of a BluetoothSocket from the passed file descriptor
-  // received over D-Bus in |fd|, the descriptor will be taken from that object
-  // and ownership passed to the returned object.
-  static scoped_refptr<device::BluetoothSocket> Create(
-      dbus::FileDescriptor* fd);
+  virtual void Connect(scoped_ptr<dbus::FileDescriptor> fd,
+                       const base::Closure& success_callback,
+                       const ErrorCompletionCallback& error_callback);
 
  protected:
   virtual ~BluetoothSocketChromeOS();
 
  private:
-  BluetoothSocketChromeOS(int fd);
+  BluetoothSocketChromeOS(
+      scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+      scoped_refptr<device::BluetoothSocketThread> socket_thread,
+      net::NetLog* net_log,
+      const net::NetLog::Source& source);
 
-  // The different socket types have different reading patterns; l2cap sockets
-  // have to be read with boundaries between datagrams preserved while rfcomm
-  // sockets do not.
-  enum SocketType {
-    L2CAP,
-    RFCOMM
-  };
+  void DoConnect(scoped_ptr<dbus::FileDescriptor> fd,
+                 const base::Closure& success_callback,
+                 const ErrorCompletionCallback& error_callback);
 
-  // File descriptor and socket type of the socket.
-  const int fd_;
-  SocketType socket_type_;
-
-  // Last error message, set during Receive() and Send() and retrieved using
-  // GetLastErrorMessage().
-  std::string error_message_;
 
   DISALLOW_COPY_AND_ASSIGN(BluetoothSocketChromeOS);
 };
diff --git a/device/bluetooth/bluetooth_socket_mac.mm b/device/bluetooth/bluetooth_socket_mac.mm
index c332430..cdbc8dd 100644
--- a/device/bluetooth/bluetooth_socket_mac.mm
+++ b/device/bluetooth/bluetooth_socket_mac.mm
@@ -18,20 +18,11 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
+#include "device/bluetooth/bluetooth_device_mac.h"
 #include "device/bluetooth/bluetooth_service_record.h"
 #include "device/bluetooth/bluetooth_service_record_mac.h"
 #include "net/base/io_buffer.h"
 
-// Replicate specific 10.7 SDK declarations for building with prior SDKs.
-#if !defined(MAC_OS_X_VERSION_10_7) || \
-    MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
-
-@interface IOBluetoothDevice (LionSDKDeclarations)
-- (NSString*)addressString;
-@end
-
-#endif  // MAC_OS_X_VERSION_10_7
-
 @interface BluetoothRFCOMMChannelDelegate
     : NSObject <IOBluetoothRFCOMMChannelDelegate> {
  @private
@@ -181,7 +172,7 @@
   if (status != kIOReturnSuccess) {
     std::stringstream error;
     error << "Failed to connect bluetooth socket ("
-          << base::SysNSStringToUTF8([device addressString]) << "): (" << status
+          << BluetoothDeviceMac::GetDeviceAddress(device) << "): (" << status
           << ")";
     error_callback.Run(error.str());
     return;
@@ -218,9 +209,8 @@
     ReleaseChannel();
     std::stringstream error;
     error << "Failed to connect bluetooth socket ("
-          << base::SysNSStringToUTF8(
-                 [[rfcomm_channel_ getDevice] addressString]) << "): ("
-          << status << ")";
+          << BluetoothDeviceMac::GetDeviceAddress([rfcomm_channel_ getDevice])
+          << "): (" << status << ")";
     temp->error_callback.Run(error.str());
     return;
   }
@@ -339,8 +329,7 @@
     if (status != kIOReturnSuccess) {
       std::stringstream error;
       error << "Failed to connect bluetooth socket ("
-            << base::SysNSStringToUTF8(
-                   [[rfcomm_channel_ getDevice] addressString])
+            << BluetoothDeviceMac::GetDeviceAddress([rfcomm_channel_ getDevice])
             << "): (" << status << ")";
       // Remember the first error only
       if (request->status == kIOReturnSuccess)
@@ -395,8 +384,7 @@
     if (!request->error_signaled) {
       std::stringstream error;
       error << "Failed to connect bluetooth socket ("
-            << base::SysNSStringToUTF8(
-                   [[rfcomm_channel_ getDevice] addressString])
+            << BluetoothDeviceMac::GetDeviceAddress([rfcomm_channel_ getDevice])
             << "): (" << status << ")";
       request->error_signaled = true;
       request->error_callback.Run(error.str());
diff --git a/device/bluetooth/bluetooth_socket_net.cc b/device/bluetooth/bluetooth_socket_net.cc
new file mode 100644
index 0000000..8360578
--- /dev/null
+++ b/device/bluetooth/bluetooth_socket_net.cc
@@ -0,0 +1,333 @@
+// 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.
+
+#include "device/bluetooth/bluetooth_socket_net.h"
+
+#include <queue>
+#include <string>
+
+#include "base/logging.h"
+#include "base/memory/linked_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/sequenced_task_runner.h"
+#include "base/threading/thread_restrictions.h"
+#include "device/bluetooth/bluetooth_socket.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+
+namespace {
+
+const char kSocketNotConnected[] = "Socket is not connected.";
+
+static void DeactivateSocket(
+    const scoped_refptr<device::BluetoothSocketThread>& socket_thread) {
+  socket_thread->OnSocketDeactivate();
+}
+
+}  // namespace
+
+namespace device {
+
+// static
+scoped_refptr<BluetoothSocketNet>
+BluetoothSocketNet::CreateBluetoothSocket(
+    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+    scoped_refptr<BluetoothSocketThread> socket_thread,
+    net::NetLog* net_log,
+    const net::NetLog::Source& source) {
+  DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
+
+  return make_scoped_refptr(
+      new BluetoothSocketNet(ui_task_runner, socket_thread, net_log, source));
+}
+
+BluetoothSocketNet::WriteRequest::WriteRequest()
+    : buffer_size(0) {}
+
+BluetoothSocketNet::WriteRequest::~WriteRequest() {}
+
+BluetoothSocketNet::BluetoothSocketNet(
+    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+    scoped_refptr<BluetoothSocketThread> socket_thread,
+    net::NetLog* net_log,
+    const net::NetLog::Source& source)
+    : ui_task_runner_(ui_task_runner),
+      socket_thread_(socket_thread),
+      net_log_(net_log),
+      source_(source) {
+  DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
+  socket_thread_->OnSocketActivate();
+}
+
+BluetoothSocketNet::~BluetoothSocketNet() {
+  DCHECK(tcp_socket_.get() == NULL);
+  ui_task_runner_->PostTask(FROM_HERE,
+                            base::Bind(&DeactivateSocket, socket_thread_));
+}
+
+void BluetoothSocketNet::Close() {
+  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+  socket_thread_->task_runner()->PostTask(
+      FROM_HERE, base::Bind(&BluetoothSocketNet::DoClose, this));
+}
+
+void BluetoothSocketNet::Disconnect(
+    const base::Closure& success_callback) {
+  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+  socket_thread_->task_runner()->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &BluetoothSocketNet::DoDisconnect,
+          this,
+          base::Bind(&BluetoothSocketNet::PostSuccess,
+                     this,
+                     success_callback)));
+}
+
+void BluetoothSocketNet::Receive(
+    int buffer_size,
+    const ReceiveCompletionCallback& success_callback,
+    const ReceiveErrorCompletionCallback& error_callback) {
+  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+  socket_thread_->task_runner()->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &BluetoothSocketNet::DoReceive,
+          this,
+          buffer_size,
+          base::Bind(&BluetoothSocketNet::PostReceiveCompletion,
+                     this,
+                     success_callback),
+          base::Bind(&BluetoothSocketNet::PostReceiveErrorCompletion,
+                     this,
+                     error_callback)));
+}
+
+void BluetoothSocketNet::Send(
+    scoped_refptr<net::IOBuffer> buffer,
+    int buffer_size,
+    const SendCompletionCallback& success_callback,
+    const ErrorCompletionCallback& error_callback) {
+  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+  socket_thread_->task_runner()->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &BluetoothSocketNet::DoSend,
+          this,
+          buffer,
+          buffer_size,
+          base::Bind(&BluetoothSocketNet::PostSendCompletion,
+                     this,
+                     success_callback),
+          base::Bind(&BluetoothSocketNet::PostErrorCompletion,
+                     this,
+                     error_callback)));
+}
+
+void BluetoothSocketNet::ResetData() {
+}
+
+void BluetoothSocketNet::ResetTCPSocket() {
+  tcp_socket_.reset(new net::TCPSocket(net_log_, source_));
+}
+
+void BluetoothSocketNet::SetTCPSocket(scoped_ptr<net::TCPSocket> tcp_socket) {
+  tcp_socket_ = tcp_socket.Pass();
+}
+
+void BluetoothSocketNet::PostSuccess(const base::Closure& callback) {
+  ui_task_runner_->PostTask(FROM_HERE, callback);
+}
+
+void BluetoothSocketNet::PostErrorCompletion(
+    const ErrorCompletionCallback& callback,
+    const std::string& error) {
+  ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, error));
+}
+
+void BluetoothSocketNet::DoClose() {
+  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
+  base::ThreadRestrictions::AssertIOAllowed();
+
+  if (tcp_socket_) {
+    tcp_socket_->Close();
+    tcp_socket_.reset(NULL);
+  }
+
+  // Note: Closing |tcp_socket_| above released all potential pending
+  // Send/Receive operations, so we can no safely release the state associated
+  // to those pending operations.
+  read_buffer_ = NULL;
+  std::queue<linked_ptr<WriteRequest> > empty;
+  std::swap(write_queue_, empty);
+
+  ResetData();
+}
+
+void BluetoothSocketNet::DoDisconnect(const base::Closure& callback) {
+  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
+  base::ThreadRestrictions::AssertIOAllowed();
+
+  DoClose();
+  callback.Run();
+}
+
+void BluetoothSocketNet::DoReceive(
+    int buffer_size,
+    const ReceiveCompletionCallback& success_callback,
+    const ReceiveErrorCompletionCallback& error_callback) {
+  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
+  base::ThreadRestrictions::AssertIOAllowed();
+
+  if (!tcp_socket_) {
+    error_callback.Run(BluetoothSocket::kDisconnected, kSocketNotConnected);
+    return;
+  }
+
+  // Only one pending read at a time
+  if (read_buffer_.get()) {
+    error_callback.Run(BluetoothSocket::kIOPending,
+                       net::ErrorToString(net::ERR_IO_PENDING));
+    return;
+  }
+
+  scoped_refptr<net::IOBufferWithSize> buffer(
+      new net::IOBufferWithSize(buffer_size));
+  int read_result =
+      tcp_socket_->Read(buffer.get(),
+                        buffer->size(),
+                        base::Bind(&BluetoothSocketNet::OnSocketReadComplete,
+                                   this,
+                                   success_callback,
+                                   error_callback));
+
+  if (read_result > 0) {
+    success_callback.Run(read_result, buffer);
+  } else if (read_result == net::OK ||
+             read_result == net::ERR_CONNECTION_CLOSED) {
+    error_callback.Run(BluetoothSocket::kDisconnected,
+                       net::ErrorToString(net::ERR_CONNECTION_CLOSED));
+  } else if (read_result == net::ERR_IO_PENDING) {
+    read_buffer_ = buffer;
+  } else {
+    error_callback.Run(BluetoothSocket::kSystemError,
+                       net::ErrorToString(read_result));
+  }
+}
+
+void BluetoothSocketNet::OnSocketReadComplete(
+    const ReceiveCompletionCallback& success_callback,
+    const ReceiveErrorCompletionCallback& error_callback,
+    int read_result) {
+  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
+  base::ThreadRestrictions::AssertIOAllowed();
+
+  scoped_refptr<net::IOBufferWithSize> buffer;
+  buffer.swap(read_buffer_);
+  if (read_result > 0) {
+    success_callback.Run(read_result, buffer);
+  } else if (read_result == net::OK ||
+             read_result == net::ERR_CONNECTION_CLOSED) {
+    error_callback.Run(BluetoothSocket::kDisconnected,
+                       net::ErrorToString(net::ERR_CONNECTION_CLOSED));
+  } else {
+    error_callback.Run(BluetoothSocket::kSystemError,
+                       net::ErrorToString(read_result));
+  }
+}
+
+void BluetoothSocketNet::DoSend(
+    scoped_refptr<net::IOBuffer> buffer,
+    int buffer_size,
+    const SendCompletionCallback& success_callback,
+    const ErrorCompletionCallback& error_callback) {
+  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
+  base::ThreadRestrictions::AssertIOAllowed();
+
+  if (!tcp_socket_) {
+    error_callback.Run(kSocketNotConnected);
+    return;
+  }
+
+  linked_ptr<WriteRequest> request(new WriteRequest());
+  request->buffer = buffer;
+  request->buffer_size = buffer_size;
+  request->success_callback = success_callback;
+  request->error_callback = error_callback;
+
+  write_queue_.push(request);
+  if (write_queue_.size() == 1) {
+    SendFrontWriteRequest();
+  }
+}
+
+void BluetoothSocketNet::SendFrontWriteRequest() {
+  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
+  base::ThreadRestrictions::AssertIOAllowed();
+
+  if (!tcp_socket_)
+    return;
+
+  if (write_queue_.size() == 0)
+    return;
+
+  linked_ptr<WriteRequest> request = write_queue_.front();
+  net::CompletionCallback callback =
+      base::Bind(&BluetoothSocketNet::OnSocketWriteComplete,
+                 this,
+                 request->success_callback,
+                 request->error_callback);
+  int send_result =
+      tcp_socket_->Write(request->buffer, request->buffer_size, callback);
+  if (send_result != net::ERR_IO_PENDING) {
+    callback.Run(send_result);
+  }
+}
+
+void BluetoothSocketNet::OnSocketWriteComplete(
+    const SendCompletionCallback& success_callback,
+    const ErrorCompletionCallback& error_callback,
+    int send_result) {
+  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
+  base::ThreadRestrictions::AssertIOAllowed();
+
+  write_queue_.pop();
+
+  if (send_result >= net::OK) {
+    success_callback.Run(send_result);
+  } else {
+    error_callback.Run(net::ErrorToString(send_result));
+  }
+
+  // Don't call directly to avoid potentail large recursion.
+  socket_thread_->task_runner()->PostNonNestableTask(
+      FROM_HERE,
+      base::Bind(&BluetoothSocketNet::SendFrontWriteRequest, this));
+}
+
+void BluetoothSocketNet::PostReceiveCompletion(
+    const ReceiveCompletionCallback& callback,
+    int io_buffer_size,
+    scoped_refptr<net::IOBuffer> io_buffer) {
+  ui_task_runner_->PostTask(FROM_HERE,
+                            base::Bind(callback, io_buffer_size, io_buffer));
+}
+
+void BluetoothSocketNet::PostReceiveErrorCompletion(
+    const ReceiveErrorCompletionCallback& callback,
+    ErrorReason reason,
+    const std::string& error_message) {
+  ui_task_runner_->PostTask(FROM_HERE,
+                            base::Bind(callback, reason, error_message));
+}
+
+void BluetoothSocketNet::PostSendCompletion(
+    const SendCompletionCallback& callback,
+    int bytes_written) {
+  ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, bytes_written));
+}
+
+}  // namespace device
diff --git a/device/bluetooth/bluetooth_socket_net.h b/device/bluetooth/bluetooth_socket_net.h
new file mode 100644
index 0000000..2a8425c
--- /dev/null
+++ b/device/bluetooth/bluetooth_socket_net.h
@@ -0,0 +1,137 @@
+// 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.
+
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_NET_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_NET_H_
+
+#include <queue>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/linked_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/sequenced_task_runner.h"
+#include "device/bluetooth/bluetooth_socket.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
+#include "net/base/net_log.h"
+#include "net/socket/tcp_socket.h"
+
+namespace net {
+class IOBuffer;
+class IOBufferWithSize;
+}  // namespace net
+
+namespace device {
+
+// This class is a base-class for implementations of BluetoothSocket that can
+// use net::TCPSocket. All public methods (including the factory method) must
+// be called on the UI thread, while underlying socket operations are
+// performed on a separate thread.
+class BluetoothSocketNet : public BluetoothSocket {
+ public:
+  static scoped_refptr<BluetoothSocketNet> CreateBluetoothSocket(
+      scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+      scoped_refptr<BluetoothSocketThread> socket_thread,
+      net::NetLog* net_log,
+      const net::NetLog::Source& source);
+
+  // BluetoothSocket:
+  virtual void Close() OVERRIDE;
+  virtual void Disconnect(const base::Closure& callback) OVERRIDE;
+  virtual void Receive(int buffer_size,
+                       const ReceiveCompletionCallback& success_callback,
+                       const ReceiveErrorCompletionCallback& error_callback)
+      OVERRIDE;
+  virtual void Send(scoped_refptr<net::IOBuffer> buffer,
+                    int buffer_size,
+                    const SendCompletionCallback& success_callback,
+                    const ErrorCompletionCallback& error_callback) OVERRIDE;
+
+ protected:
+  BluetoothSocketNet(scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+                     scoped_refptr<BluetoothSocketThread> socket_thread,
+                     net::NetLog* net_log,
+                     const net::NetLog::Source& source);
+  virtual ~BluetoothSocketNet();
+
+  // Resets locally held data after a socket is closed. Default implementation
+  // does nothing, subclasses may override.
+  virtual void ResetData();
+
+  // Methods for subclasses to obtain the members.
+  scoped_refptr<base::SequencedTaskRunner> ui_task_runner() const {
+    return ui_task_runner_;
+  }
+
+  scoped_refptr<BluetoothSocketThread> socket_thread() const {
+    return socket_thread_;
+  }
+
+  net::NetLog* net_log() const { return net_log_; }
+  const net::NetLog::Source& source() const { return source_; }
+
+  net::TCPSocket* tcp_socket() { return tcp_socket_.get(); }
+
+  void ResetTCPSocket();
+  void SetTCPSocket(scoped_ptr<net::TCPSocket> tcp_socket);
+
+  void PostSuccess(const base::Closure& callback);
+  void PostErrorCompletion(const ErrorCompletionCallback& callback,
+                           const std::string& error);
+
+ private:
+  struct WriteRequest {
+    WriteRequest();
+    ~WriteRequest();
+
+    scoped_refptr<net::IOBuffer> buffer;
+    int buffer_size;
+    SendCompletionCallback success_callback;
+    ErrorCompletionCallback error_callback;
+  };
+
+  void DoClose();
+  void DoDisconnect(const base::Closure& callback);
+  void DoReceive(int buffer_size,
+                 const ReceiveCompletionCallback& success_callback,
+                 const ReceiveErrorCompletionCallback& error_callback);
+  void OnSocketReadComplete(
+      const ReceiveCompletionCallback& success_callback,
+      const ReceiveErrorCompletionCallback& error_callback,
+      int read_result);
+  void DoSend(scoped_refptr<net::IOBuffer> buffer,
+              int buffer_size,
+              const SendCompletionCallback& success_callback,
+              const ErrorCompletionCallback& error_callback);
+  void SendFrontWriteRequest();
+  void OnSocketWriteComplete(const SendCompletionCallback& success_callback,
+                             const ErrorCompletionCallback& error_callback,
+                             int send_result);
+
+  void PostReceiveCompletion(const ReceiveCompletionCallback& callback,
+                             int io_buffer_size,
+                             scoped_refptr<net::IOBuffer> io_buffer);
+  void PostReceiveErrorCompletion(
+      const ReceiveErrorCompletionCallback& callback,
+      ErrorReason reason,
+      const std::string& error_message);
+  void PostSendCompletion(const SendCompletionCallback& callback,
+                          int bytes_written);
+
+  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
+  scoped_refptr<BluetoothSocketThread> socket_thread_;
+  net::NetLog* net_log_;
+  const net::NetLog::Source source_;
+
+  scoped_ptr<net::TCPSocket> tcp_socket_;
+  scoped_refptr<net::IOBufferWithSize> read_buffer_;
+  std::queue<linked_ptr<WriteRequest> > write_queue_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothSocketNet);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_NET_H_
diff --git a/device/bluetooth/bluetooth_socket_thread.cc b/device/bluetooth/bluetooth_socket_thread.cc
new file mode 100644
index 0000000..3f49d41
--- /dev/null
+++ b/device/bluetooth/bluetooth_socket_thread.cc
@@ -0,0 +1,66 @@
+// 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.
+
+#include "device/bluetooth/bluetooth_socket_thread.h"
+
+#include "base/lazy_instance.h"
+#include "base/sequenced_task_runner.h"
+#include "base/threading/thread.h"
+
+namespace device {
+
+base::LazyInstance<scoped_refptr<BluetoothSocketThread> > g_instance =
+    LAZY_INSTANCE_INITIALIZER;
+
+// static
+scoped_refptr<BluetoothSocketThread> BluetoothSocketThread::Get() {
+  if (!g_instance.Get().get()) {
+    g_instance.Get() = new BluetoothSocketThread();
+  }
+  return g_instance.Get();
+}
+
+BluetoothSocketThread::BluetoothSocketThread()
+    : active_socket_count_(0) {}
+
+BluetoothSocketThread::~BluetoothSocketThread() {}
+
+void BluetoothSocketThread::OnSocketActivate() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  active_socket_count_++;
+  EnsureStarted();
+}
+
+void BluetoothSocketThread::OnSocketDeactivate() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  active_socket_count_--;
+  if (active_socket_count_ == 0 && thread_) {
+    thread_->Stop();
+    thread_.reset(NULL);
+    task_runner_ = NULL;
+  }
+}
+
+void BluetoothSocketThread::EnsureStarted() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (thread_)
+    return;
+
+  base::Thread::Options thread_options;
+  thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
+  thread_.reset(new base::Thread("BluetoothSocketThread"));
+  thread_->StartWithOptions(thread_options);
+  task_runner_ = thread_->message_loop_proxy();
+}
+
+scoped_refptr<base::SequencedTaskRunner> BluetoothSocketThread::task_runner()
+    const {
+  DCHECK(active_socket_count_ > 0);
+  DCHECK(thread_);
+  DCHECK(task_runner_);
+
+  return task_runner_;
+}
+
+}  // namespace device
diff --git a/device/bluetooth/bluetooth_socket_thread.h b/device/bluetooth/bluetooth_socket_thread.h
new file mode 100644
index 0000000..7be6b3a
--- /dev/null
+++ b/device/bluetooth/bluetooth_socket_thread.h
@@ -0,0 +1,48 @@
+// 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.
+
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_THREAD_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_THREAD_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread_checker.h"
+
+namespace base {
+class SequencedTaskRunner;
+class Thread;
+}  // namespace base
+
+namespace device {
+
+// Thread abstraction used by |BluetoothSocketChromeOS| and |BluetoothSocketWin|
+// to perform IO operations on the underlying platform sockets. An instance of
+// this class can be shared by many active sockets.
+class BluetoothSocketThread
+    : public base::RefCountedThreadSafe<BluetoothSocketThread> {
+ public:
+  static scoped_refptr<BluetoothSocketThread> Get();
+  void OnSocketActivate();
+  void OnSocketDeactivate();
+
+  scoped_refptr<base::SequencedTaskRunner> task_runner() const;
+
+ private:
+  friend class base::RefCountedThreadSafe<BluetoothSocketThread>;
+  BluetoothSocketThread();
+  virtual ~BluetoothSocketThread();
+
+  void EnsureStarted();
+
+  base::ThreadChecker thread_checker_;
+  int active_socket_count_;
+  scoped_ptr<base::Thread> thread_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothSocketThread);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_THREAD_H_
diff --git a/device/bluetooth/bluetooth_socket_thread_win.cc b/device/bluetooth/bluetooth_socket_thread_win.cc
deleted file mode 100644
index 04ce799..0000000
--- a/device/bluetooth/bluetooth_socket_thread_win.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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.
-
-#include "device/bluetooth/bluetooth_socket_thread_win.h"
-
-#include "base/lazy_instance.h"
-#include "base/sequenced_task_runner.h"
-#include "base/threading/thread.h"
-
-namespace device {
-
-base::LazyInstance<scoped_refptr<BluetoothSocketThreadWin> > g_instance =
-    LAZY_INSTANCE_INITIALIZER;
-
-// static
-scoped_refptr<BluetoothSocketThreadWin> BluetoothSocketThreadWin::Get() {
-  if (!g_instance.Get().get()) {
-    g_instance.Get() = new BluetoothSocketThreadWin();
-  }
-  return g_instance.Get();
-}
-
-BluetoothSocketThreadWin::BluetoothSocketThreadWin()
-    : active_socket_count_(0) {}
-
-BluetoothSocketThreadWin::~BluetoothSocketThreadWin() {}
-
-void BluetoothSocketThreadWin::OnSocketActivate() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  active_socket_count_++;
-  EnsureStarted();
-}
-
-void BluetoothSocketThreadWin::OnSocketDeactivate() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  active_socket_count_--;
-  if (active_socket_count_ == 0 && thread_) {
-    thread_->Stop();
-    thread_.reset(NULL);
-    task_runner_ = NULL;
-  }
-}
-
-void BluetoothSocketThreadWin::EnsureStarted() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (thread_)
-    return;
-
-  base::Thread::Options thread_options;
-  thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
-  thread_.reset(new base::Thread("BluetoothSocketThreadWin"));
-  thread_->StartWithOptions(thread_options);
-  task_runner_ = thread_->message_loop_proxy();
-}
-
-scoped_refptr<base::SequencedTaskRunner> BluetoothSocketThreadWin::task_runner()
-    const {
-  DCHECK(active_socket_count_ > 0);
-  DCHECK(thread_);
-  DCHECK(task_runner_);
-
-  return task_runner_;
-}
-
-}  // namespace device
diff --git a/device/bluetooth/bluetooth_socket_thread_win.h b/device/bluetooth/bluetooth_socket_thread_win.h
deleted file mode 100644
index 063ebbb..0000000
--- a/device/bluetooth/bluetooth_socket_thread_win.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.
-
-#ifndef DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_THREAD_WIN_H_
-#define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_THREAD_WIN_H_
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/threading/thread_checker.h"
-
-namespace base {
-class SequencedTaskRunner;
-class Thread;
-}  // namespace base
-
-namespace device {
-
-// Thread abstraction used by |BluetoothSocketWWin| to perform IO operations on
-// the underlying platform sockets. An instance of this class can be shared by
-// many active sockets.
-class BluetoothSocketThreadWin
-    : public base::RefCountedThreadSafe<BluetoothSocketThreadWin> {
- public:
-  static scoped_refptr<BluetoothSocketThreadWin> Get();
-  void OnSocketActivate();
-  void OnSocketDeactivate();
-
-  scoped_refptr<base::SequencedTaskRunner> task_runner() const;
-
- private:
-  friend class base::RefCountedThreadSafe<BluetoothSocketThreadWin>;
-  BluetoothSocketThreadWin();
-  virtual ~BluetoothSocketThreadWin();
-
-  void EnsureStarted();
-
-  base::ThreadChecker thread_checker_;
-  int active_socket_count_;
-  scoped_ptr<base::Thread> thread_;
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothSocketThreadWin);
-};
-
-}  // namespace device
-
-#endif  // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_THREAD_WIN_H_
diff --git a/device/bluetooth/bluetooth_socket_win.cc b/device/bluetooth/bluetooth_socket_win.cc
index 2371d21..5f672c4 100644
--- a/device/bluetooth/bluetooth_socket_win.cc
+++ b/device/bluetooth/bluetooth_socket_win.cc
@@ -16,7 +16,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "device/bluetooth/bluetooth_init_win.h"
 #include "device/bluetooth/bluetooth_service_record_win.h"
-#include "device/bluetooth/bluetooth_socket_thread_win.h"
+#include "device/bluetooth/bluetooth_socket_thread.h"
 #include "net/base/io_buffer.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
@@ -26,7 +26,6 @@
 
 const char kL2CAPNotSupported[] = "Bluetooth L2CAP protocal is not supported";
 const char kSocketAlreadyConnected[] = "Socket is already connected.";
-const char kSocketNotConnected[] = "Socket is not connected.";
 const char kInvalidRfcommPort[] = "Invalid RFCCOMM port.";
 const char kFailedToCreateSocket[] = "Failed to create socket.";
 const char kFailedToBindSocket[] = "Failed to bind socket.";
@@ -35,13 +34,6 @@
 const char kBadUuid[] = "Bad uuid.";
 const char kWsaSetServiceError[] = "WSASetService error.";
 
-using device::BluetoothSocketWin;
-
-static void DeactivateSocket(
-    const scoped_refptr<device::BluetoothSocketThreadWin>& socket_thread) {
-  socket_thread->OnSocketDeactivate();
-}
-
 }  // namespace
 
 namespace device {
@@ -62,9 +54,10 @@
 };
 
 // static
-scoped_refptr<BluetoothSocketWin> BluetoothSocketWin::CreateBluetoothSocket(
+scoped_refptr<BluetoothSocketWin>
+BluetoothSocketWin::CreateBluetoothSocket(
     scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
-    scoped_refptr<BluetoothSocketThreadWin> socket_thread,
+    scoped_refptr<device::BluetoothSocketThread> socket_thread,
     net::NetLog* net_log,
     const net::NetLog::Source& source) {
   DCHECK(ui_task_runner->RunsTasksOnCurrentThread());
@@ -75,23 +68,16 @@
 
 BluetoothSocketWin::BluetoothSocketWin(
     scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
-    scoped_refptr<BluetoothSocketThreadWin> socket_thread,
+    scoped_refptr<BluetoothSocketThread> socket_thread,
     net::NetLog* net_log,
     const net::NetLog::Source& source)
-    : ui_task_runner_(ui_task_runner),
-      socket_thread_(socket_thread),
-      net_log_(net_log),
-      source_(source),
+    : BluetoothSocketNet(ui_task_runner, socket_thread, net_log, source),
       supports_rfcomm_(false),
       rfcomm_channel_(-1),
       bth_addr_(BTH_ADDR_NULL) {
-  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
-  socket_thread->OnSocketActivate();
 }
 
 BluetoothSocketWin::~BluetoothSocketWin() {
-  ui_task_runner_->PostTask(FROM_HERE,
-                            base::Bind(&DeactivateSocket, socket_thread_));
 }
 
 void BluetoothSocketWin::StartService(
@@ -101,9 +87,9 @@
     const base::Closure& success_callback,
     const ErrorCompletionCallback& error_callback,
     const OnNewConnectionCallback& new_connection_callback) {
-  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
 
-  socket_thread_->task_runner()->PostTask(
+  socket_thread()->task_runner()->PostTask(
       FROM_HERE,
       base::Bind(&BluetoothSocketWin::DoStartService,
                  this,
@@ -115,17 +101,11 @@
                  new_connection_callback));
 }
 
-void BluetoothSocketWin::Close() {
-  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
-  socket_thread_->task_runner()->PostTask(
-      FROM_HERE, base::Bind(&BluetoothSocketWin::DoClose, this));
-}
-
 void BluetoothSocketWin::Connect(
     const BluetoothServiceRecord& service_record,
     const base::Closure& success_callback,
     const ErrorCompletionCallback& error_callback) {
-  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
 
   const BluetoothServiceRecordWin* service_record_win =
       static_cast<const BluetoothServiceRecordWin*>(&service_record);
@@ -136,7 +116,7 @@
     bth_addr_ = service_record_win->bth_addr();
   }
 
-  socket_thread_->task_runner()->PostTask(
+  socket_thread()->task_runner()->PostTask(
       FROM_HERE,
       base::Bind(
           &BluetoothSocketWin::DoConnect,
@@ -146,69 +126,8 @@
               &BluetoothSocketWin::PostErrorCompletion, this, error_callback)));
 }
 
-void BluetoothSocketWin::Disconnect(const base::Closure& success_callback) {
-  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
-  socket_thread_->task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(
-          &BluetoothSocketWin::DoDisconnect,
-          this,
-          base::Bind(
-              &BluetoothSocketWin::PostSuccess, this, success_callback)));
-}
 
-void BluetoothSocketWin::Receive(
-    int buffer_size,
-    const ReceiveCompletionCallback& success_callback,
-    const ReceiveErrorCompletionCallback& error_callback) {
-  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
-  socket_thread_->task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(&BluetoothSocketWin::DoReceive,
-                 this,
-                 buffer_size,
-                 base::Bind(&BluetoothSocketWin::PostReceiveCompletion,
-                            this,
-                            success_callback),
-                 base::Bind(&BluetoothSocketWin::PostReceiveErrorCompletion,
-                            this,
-                            error_callback)));
-}
-
-void BluetoothSocketWin::Send(scoped_refptr<net::IOBuffer> buffer,
-                              int buffer_size,
-                              const SendCompletionCallback& success_callback,
-                              const ErrorCompletionCallback& error_callback) {
-  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
-  socket_thread_->task_runner()->PostTask(
-      FROM_HERE,
-      base::Bind(
-          &BluetoothSocketWin::DoSend,
-          this,
-          buffer,
-          buffer_size,
-          base::Bind(
-              &BluetoothSocketWin::PostSendCompletion, this, success_callback),
-          base::Bind(
-              &BluetoothSocketWin::PostErrorCompletion, this, error_callback)));
-}
-
-void BluetoothSocketWin::DoClose() {
-  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
-  base::ThreadRestrictions::AssertIOAllowed();
-
-  if (tcp_socket_) {
-    tcp_socket_->Close();
-    tcp_socket_.reset(NULL);
-  }
-
-  // Note: Closing |tcp_socket_| above released all potential pending
-  // Send/Receive operations, so we can no safely release the state associated
-  // to those pending operations.
-  read_buffer_ = NULL;
-  std::queue<linked_ptr<WriteRequest> > empty;
-  write_queue_.swap(empty);
-
+void BluetoothSocketWin::ResetData() {
   if (service_reg_data_) {
     if (WSASetService(&service_reg_data_->service,RNRSERVICE_DELETE, 0) ==
         SOCKET_ERROR) {
@@ -221,10 +140,10 @@
 void BluetoothSocketWin::DoConnect(
     const base::Closure& success_callback,
     const ErrorCompletionCallback& error_callback) {
-  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
+  DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread());
   base::ThreadRestrictions::AssertIOAllowed();
 
-  if (tcp_socket_) {
+  if (tcp_socket()) {
     error_callback.Run(kSocketAlreadyConnected);
     return;
   }
@@ -235,7 +154,7 @@
     return;
   }
 
-  tcp_socket_.reset(new net::TCPSocket(net_log_, source_));
+  ResetTCPSocket();
   net::EnsureWinsockInit();
   SOCKET socket_fd = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
   SOCKADDR_BTH sa;
@@ -260,7 +179,7 @@
   // Note: We don't have a meaningful |IPEndPoint|, but that is ok since the
   // TCPSocket implementation does not actually require one.
   int net_result =
-      tcp_socket_->AdoptConnectedSocket(socket_fd, net::IPEndPoint());
+      tcp_socket()->AdoptConnectedSocket(socket_fd, net::IPEndPoint());
   if (net_result != net::OK) {
     error_callback.Run("Error connecting to socket: " +
                        std::string(net::ErrorToString(net_result)));
@@ -271,177 +190,6 @@
   success_callback.Run();
 }
 
-void BluetoothSocketWin::DoDisconnect(const base::Closure& success_callback) {
-  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
-  base::ThreadRestrictions::AssertIOAllowed();
-
-  DoClose();
-  success_callback.Run();
-}
-
-void BluetoothSocketWin::DoReceive(
-    int buffer_size,
-    const ReceiveCompletionCallback& success_callback,
-    const ReceiveErrorCompletionCallback& error_callback) {
-  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
-  base::ThreadRestrictions::AssertIOAllowed();
-
-  if (!tcp_socket_) {
-    error_callback.Run(BluetoothSocketWin::kDisconnected, kSocketNotConnected);
-    return;
-  }
-
-  // Only one pending read at a time
-  if (read_buffer_.get()) {
-    error_callback.Run(BluetoothSocketWin::kIOPending,
-                       net::ErrorToString(net::ERR_IO_PENDING));
-    return;
-  }
-
-  scoped_refptr<net::IOBufferWithSize> buffer(
-      new net::IOBufferWithSize(buffer_size));
-  int read_result =
-      tcp_socket_->Read(buffer.get(),
-                        buffer->size(),
-                        base::Bind(&BluetoothSocketWin::OnSocketReadComplete,
-                                   this,
-                                   success_callback,
-                                   error_callback));
-
-  if (read_result > 0) {
-    success_callback.Run(read_result, buffer);
-  } else if (read_result == net::OK ||
-             read_result == net::ERR_CONNECTION_CLOSED) {
-    error_callback.Run(BluetoothSocketWin::kDisconnected,
-                       net::ErrorToString(net::ERR_CONNECTION_CLOSED));
-  } else if (read_result == net::ERR_IO_PENDING) {
-    read_buffer_ = buffer;
-  } else {
-    error_callback.Run(BluetoothSocketWin::kSystemError,
-                       net::ErrorToString(read_result));
-  }
-}
-
-void BluetoothSocketWin::OnSocketReadComplete(
-    const ReceiveCompletionCallback& success_callback,
-    const ReceiveErrorCompletionCallback& error_callback,
-    int read_result) {
-  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
-  base::ThreadRestrictions::AssertIOAllowed();
-
-  scoped_refptr<net::IOBufferWithSize> buffer;
-  buffer.swap(read_buffer_);
-  if (read_result > 0) {
-    success_callback.Run(read_result, buffer);
-  } else if (read_result == net::OK ||
-             read_result == net::ERR_CONNECTION_CLOSED) {
-    error_callback.Run(BluetoothSocketWin::kDisconnected,
-                       net::ErrorToString(net::ERR_CONNECTION_CLOSED));
-  } else {
-    error_callback.Run(BluetoothSocketWin::kSystemError,
-                       net::ErrorToString(read_result));
-  }
-}
-
-void BluetoothSocketWin::DoSend(scoped_refptr<net::IOBuffer> buffer,
-                                int buffer_size,
-                                const SendCompletionCallback& success_callback,
-                                const ErrorCompletionCallback& error_callback) {
-  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
-  base::ThreadRestrictions::AssertIOAllowed();
-
-  if (!tcp_socket_) {
-    error_callback.Run(kSocketNotConnected);
-    return;
-  }
-
-  linked_ptr<WriteRequest> request(new WriteRequest());
-  request->buffer = buffer;
-  request->buffer_size = buffer_size;
-  request->success_callback = success_callback;
-  request->error_callback = error_callback;
-
-  write_queue_.push(request);
-  if (write_queue_.size() == 1) {
-    SendFrontWriteRequest();
-  }
-}
-
-void BluetoothSocketWin::SendFrontWriteRequest() {
-  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
-  base::ThreadRestrictions::AssertIOAllowed();
-
-  if (!tcp_socket_)
-    return;
-
-  if (write_queue_.size() == 0)
-    return;
-
-  linked_ptr<WriteRequest> request = write_queue_.front();
-  net::CompletionCallback callback =
-      base::Bind(&BluetoothSocketWin::OnSocketWriteComplete,
-                 this,
-                 request->success_callback,
-                 request->error_callback);
-  int send_result =
-      tcp_socket_->Write(request->buffer, request->buffer_size, callback);
-  if (send_result != net::ERR_IO_PENDING) {
-    callback.Run(send_result);
-  }
-}
-
-void BluetoothSocketWin::OnSocketWriteComplete(
-    const SendCompletionCallback& success_callback,
-    const ErrorCompletionCallback& error_callback,
-    int send_result) {
-  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
-  base::ThreadRestrictions::AssertIOAllowed();
-
-  write_queue_.pop();
-
-  if (send_result >= net::OK) {
-    success_callback.Run(send_result);
-  } else {
-    error_callback.Run(net::ErrorToString(send_result));
-  }
-
-  // Don't call directly to avoid potentail large recursion.
-  socket_thread_->task_runner()->PostNonNestableTask(
-      FROM_HERE, base::Bind(&BluetoothSocketWin::SendFrontWriteRequest, this));
-}
-
-void BluetoothSocketWin::PostSuccess(const base::Closure& callback) {
-  ui_task_runner_->PostTask(FROM_HERE, callback);
-}
-
-void BluetoothSocketWin::PostErrorCompletion(
-    const ErrorCompletionCallback& callback,
-    const std::string& error) {
-  ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, error));
-}
-
-void BluetoothSocketWin::PostReceiveCompletion(
-    const ReceiveCompletionCallback& callback,
-    int io_buffer_size,
-    scoped_refptr<net::IOBuffer> io_buffer) {
-  ui_task_runner_->PostTask(FROM_HERE,
-                            base::Bind(callback, io_buffer_size, io_buffer));
-}
-
-void BluetoothSocketWin::PostReceiveErrorCompletion(
-    const ReceiveErrorCompletionCallback& callback,
-    ErrorReason reason,
-    const std::string& error_message) {
-  ui_task_runner_->PostTask(FROM_HERE,
-                            base::Bind(callback, reason, error_message));
-}
-
-void BluetoothSocketWin::PostSendCompletion(
-    const SendCompletionCallback& callback,
-    int bytes_written) {
-  ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, bytes_written));
-}
-
 void BluetoothSocketWin::DoStartService(
     const BluetoothUUID& uuid,
     const std::string& name,
@@ -449,8 +197,8 @@
     const base::Closure& success_callback,
     const ErrorCompletionCallback& error_callback,
     const OnNewConnectionCallback& new_connection_callback) {
-  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
-  DCHECK(!tcp_socket_ &&
+  DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread());
+  DCHECK(!tcp_socket() &&
          !service_reg_data_ &&
          on_new_connection_callback_.is_null());
 
@@ -542,7 +290,7 @@
     return;
   }
 
-  tcp_socket_ = scoped_socket.Pass();
+  SetTCPSocket(scoped_socket.Pass());
   service_reg_data_ = reg_data.Pass();
   on_new_connection_callback_ = new_connection_callback;
   DoAccept();
@@ -551,8 +299,8 @@
 }
 
 void BluetoothSocketWin::DoAccept() {
-  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
-  int result = tcp_socket_->Accept(
+  DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread());
+  int result = tcp_socket()->Accept(
       &accept_socket_,
       &accept_address_,
       base::Bind(&BluetoothSocketWin::OnAcceptOnSocketThread, this));
@@ -561,13 +309,13 @@
 }
 
 void BluetoothSocketWin::OnAcceptOnSocketThread(int accept_result) {
-  DCHECK(socket_thread_->task_runner()->RunsTasksOnCurrentThread());
+  DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread());
   if (accept_result != net::OK) {
     LOG(WARNING) << "OnAccept error, net err=" << accept_result;
     return;
   }
 
-  ui_task_runner_->PostTask(
+  ui_task_runner()->PostTask(
     FROM_HERE,
     base::Bind(&BluetoothSocketWin::OnAcceptOnUI,
                this,
@@ -579,14 +327,14 @@
 void BluetoothSocketWin::OnAcceptOnUI(
     scoped_ptr<net::TCPSocket> accept_socket,
     const net::IPEndPoint& peer_address) {
-  DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
 
   scoped_refptr<BluetoothSocketWin> peer = CreateBluetoothSocket(
-          ui_task_runner_,
-          socket_thread_,
-          net_log_,
-          source_);
-  peer->tcp_socket_ = accept_socket.Pass();
+          ui_task_runner(),
+          socket_thread(),
+          net_log(),
+          source());
+  peer->SetTCPSocket(accept_socket.Pass());
 
   on_new_connection_callback_.Run(peer, peer_address);
 }
diff --git a/device/bluetooth/bluetooth_socket_win.h b/device/bluetooth/bluetooth_socket_win.h
index 0b4ac90..195e870 100644
--- a/device/bluetooth/bluetooth_socket_win.h
+++ b/device/bluetooth/bluetooth_socket_win.h
@@ -7,40 +7,29 @@
 
 #include <WinSock2.h>
 
-#include <queue>
 #include <string>
 
-#include "base/memory/linked_ptr.h"
 #include "base/memory/ref_counted.h"
-#include "base/threading/thread_checker.h"
 #include "device/bluetooth/bluetooth_service_record_win.h"
 #include "device/bluetooth/bluetooth_socket.h"
+#include "device/bluetooth/bluetooth_socket_net.h"
 #include "net/base/ip_endpoint.h"
-#include "net/base/net_log.h"
 #include "net/socket/tcp_socket.h"
 
-namespace net {
-class IOBuffer;
-class IOBufferWithSize;
-}  // namespace net
-
 namespace device {
 
 class BluetoothServiceRecord;
-class BluetoothSocketThreadWin;
 
-// This class is an implementation of BluetoothSocket class for the Windows
-// platform.  All public methods (including the factory method) must be called
-// on the UI thread, while underlying socket operations are performed on a
-// separated thread.
-class BluetoothSocketWin : public BluetoothSocket {
+// The BluetoothSocketWin class implements BluetoothSocket for the Microsoft
+// Windows platform.
+class BluetoothSocketWin : public BluetoothSocketNet {
  public:
   typedef base::Callback<void(scoped_refptr<BluetoothSocketWin>,
                               const net::IPEndPoint&)> OnNewConnectionCallback;
 
   static scoped_refptr<BluetoothSocketWin> CreateBluetoothSocket(
       scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
-      scoped_refptr<BluetoothSocketThreadWin> socket_thread,
+      scoped_refptr<BluetoothSocketThread> socket_thread,
       net::NetLog* net_log,
       const net::NetLog::Source& source);
 
@@ -63,19 +52,8 @@
                const base::Closure& success_callback,
                const ErrorCompletionCallback& error_callback);
 
-  // Overriden from BluetoothSocket:
-  virtual void Close() OVERRIDE;
-
-  virtual void Disconnect(const base::Closure& callback) OVERRIDE;
-
-  virtual void Receive(int buffer_size,
-                       const ReceiveCompletionCallback& success_callback,
-                       const ReceiveErrorCompletionCallback& error_callback)
-      OVERRIDE;
-  virtual void Send(scoped_refptr<net::IOBuffer> buffer,
-                    int buffer_size,
-                    const SendCompletionCallback& success_callback,
-                    const ErrorCompletionCallback& error_callback) OVERRIDE;
+  // BluetoothSocketNet:
+  void ResetData();
 
  protected:
   virtual ~BluetoothSocketWin();
@@ -83,52 +61,14 @@
  private:
   struct ServiceRegData;
 
-  struct WriteRequest {
-    scoped_refptr<net::IOBuffer> buffer;
-    int buffer_size;
-    SendCompletionCallback success_callback;
-    ErrorCompletionCallback error_callback;
-  };
-
   BluetoothSocketWin(scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
-                     scoped_refptr<BluetoothSocketThreadWin> socket_thread,
+                     scoped_refptr<BluetoothSocketThread> socket_thread,
                      net::NetLog* net_log,
                      const net::NetLog::Source& source);
 
-  void DoClose();
+
   void DoConnect(const base::Closure& success_callback,
                  const ErrorCompletionCallback& error_callback);
-  void DoDisconnect(const base::Closure& callback);
-  void DoReceive(int buffer_size,
-                 const ReceiveCompletionCallback& success_callback,
-                 const ReceiveErrorCompletionCallback& error_callback);
-  void DoSend(scoped_refptr<net::IOBuffer> buffer,
-              int buffer_size,
-              const SendCompletionCallback& success_callback,
-              const ErrorCompletionCallback& error_callback);
-
-  void PostSuccess(const base::Closure& callback);
-  void PostErrorCompletion(const ErrorCompletionCallback& callback,
-                           const std::string& error);
-  void PostReceiveCompletion(const ReceiveCompletionCallback& callback,
-                             int io_buffer_size,
-                             scoped_refptr<net::IOBuffer> io_buffer);
-  void PostReceiveErrorCompletion(
-      const ReceiveErrorCompletionCallback& callback,
-      ErrorReason reason,
-      const std::string& error_message);
-  void PostSendCompletion(const SendCompletionCallback& callback,
-                          int bytes_written);
-
-  void SendFrontWriteRequest();
-  void OnSocketWriteComplete(const SendCompletionCallback& success_callback,
-                             const ErrorCompletionCallback& error_callback,
-                             int net_status);
-  void OnSocketReadComplete(
-      const ReceiveCompletionCallback& success_callback,
-      const ReceiveErrorCompletionCallback& error_callback,
-      int send_result);
-
   void DoStartService(const BluetoothUUID& uuid,
       const std::string& name,
       int rfcomm_channel,
@@ -140,19 +80,10 @@
   void OnAcceptOnUI(scoped_ptr<net::TCPSocket> accept_socket,
                     const net::IPEndPoint& peer_address);
 
-  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
-  scoped_refptr<BluetoothSocketThreadWin> socket_thread_;
-  net::NetLog* net_log_;
-  const net::NetLog::Source source_;
   std::string device_address_;
   bool supports_rfcomm_;
   uint8 rfcomm_channel_;
   BTH_ADDR bth_addr_;
-  scoped_ptr<net::TCPSocket> tcp_socket_;
-  // Queue of pending writes. The buffer at the front of the queue is the one
-  // being written.
-  std::queue<linked_ptr<WriteRequest> > write_queue_;
-  scoped_refptr<net::IOBufferWithSize> read_buffer_;
 
   scoped_ptr<ServiceRegData> service_reg_data_;
   scoped_ptr<net::TCPSocket> accept_socket_;
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.h b/device/bluetooth/test/mock_bluetooth_adapter.h
index 32f40d1..ee03353 100644
--- a/device/bluetooth/test/mock_bluetooth_adapter.h
+++ b/device/bluetooth/test/mock_bluetooth_adapter.h
@@ -31,6 +31,8 @@
 
   MockBluetoothAdapter();
 
+  virtual bool IsInitialized() const { return true; }
+
   MOCK_METHOD1(AddObserver, void(BluetoothAdapter::Observer*));
   MOCK_METHOD1(RemoveObserver, void(BluetoothAdapter::Observer*));
   MOCK_CONST_METHOD0(GetAddress, std::string());
@@ -39,7 +41,6 @@
                void(const std::string& name,
                     const base::Closure& callback,
                     const ErrorCallback& error_callback));
-  MOCK_CONST_METHOD0(IsInitialized, bool());
   MOCK_CONST_METHOD0(IsPresent, bool());
   MOCK_CONST_METHOD0(IsPowered, bool());
   MOCK_METHOD3(SetPowered,
diff --git a/device/bluetooth/test/mock_bluetooth_device.h b/device/bluetooth/test/mock_bluetooth_device.h
index 9291e9b..5a6af5c 100644
--- a/device/bluetooth/test/mock_bluetooth_device.h
+++ b/device/bluetooth/test/mock_bluetooth_device.h
@@ -67,6 +67,10 @@
                void(BluetoothProfile* profile,
                     const base::Closure& callback,
                     const ConnectToProfileErrorCallback& error_callback));
+  MOCK_METHOD3(ConnectToService,
+               void(const BluetoothUUID& uuid,
+                    const ConnectToServiceCallback& callback,
+                    const ConnectToServiceErrorCallback& error_callback));
 
   MOCK_METHOD3(SetOutOfBandPairingData,
       void(const BluetoothOutOfBandPairingData& data,
diff --git a/device/bluetooth/test/mock_bluetooth_gatt_characteristic.cc b/device/bluetooth/test/mock_bluetooth_gatt_characteristic.cc
new file mode 100644
index 0000000..5cc4da3
--- /dev/null
+++ b/device/bluetooth/test/mock_bluetooth_gatt_characteristic.cc
@@ -0,0 +1,37 @@
+// 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.
+
+#include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h"
+
+#include "device/bluetooth/test/mock_bluetooth_gatt_service.h"
+
+using testing::Return;
+using testing::ReturnRefOfCopy;
+using testing::_;
+
+namespace device {
+
+MockBluetoothGattCharacteristic::MockBluetoothGattCharacteristic(
+    MockBluetoothGattService* service,
+    const std::string& identifier,
+    const BluetoothUUID& uuid,
+    bool is_local,
+    Properties properties,
+    Permissions permissions) {
+  ON_CALL(*this, GetIdentifier()).WillByDefault(Return(identifier));
+  ON_CALL(*this, GetUUID()).WillByDefault(Return(uuid));
+  ON_CALL(*this, IsLocal()).WillByDefault(Return(is_local));
+  ON_CALL(*this, GetValue())
+      .WillByDefault(ReturnRefOfCopy(std::vector<uint8>()));
+  ON_CALL(*this, GetService()).WillByDefault(Return(service));
+  ON_CALL(*this, GetProperties()).WillByDefault(Return(properties));
+  ON_CALL(*this, GetPermissions()).WillByDefault(Return(permissions));
+  ON_CALL(*this, GetDescriptors())
+      .WillByDefault(Return(std::vector<BluetoothGattDescriptor*>()));
+}
+
+MockBluetoothGattCharacteristic::~MockBluetoothGattCharacteristic() {
+}
+
+}  // namespace device
diff --git a/device/bluetooth/test/mock_bluetooth_gatt_characteristic.h b/device/bluetooth/test/mock_bluetooth_gatt_characteristic.h
new file mode 100644
index 0000000..85323f4
--- /dev/null
+++ b/device/bluetooth/test/mock_bluetooth_gatt_characteristic.h
@@ -0,0 +1,58 @@
+// 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.
+
+#ifndef DEVICE_BLUETOOTH_TEST_MOCK_BLUETOOTH_GATT_CHARACTERISTIC_H_
+#define DEVICE_BLUETOOTH_TEST_MOCK_BLUETOOTH_GATT_CHARACTERISTIC_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "device/bluetooth/bluetooth_gatt_characteristic.h"
+#include "device/bluetooth/bluetooth_uuid.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace device {
+
+class BluetoothGattDescriptor;
+class BluetoothGattService;
+class MockBluetoothGattService;
+
+class MockBluetoothGattCharacteristic : public BluetoothGattCharacteristic {
+ public:
+  MockBluetoothGattCharacteristic(MockBluetoothGattService* service,
+                                  const std::string& identifier,
+                                  const BluetoothUUID& uuid,
+                                  bool is_local,
+                                  Properties properties,
+                                  Permissions permissions);
+  virtual ~MockBluetoothGattCharacteristic();
+
+  MOCK_CONST_METHOD0(GetIdentifier, std::string());
+  MOCK_CONST_METHOD0(GetUUID, BluetoothUUID());
+  MOCK_CONST_METHOD0(IsLocal, bool());
+  MOCK_CONST_METHOD0(GetValue, const std::vector<uint8>&());
+  MOCK_CONST_METHOD0(GetService, BluetoothGattService*());
+  MOCK_CONST_METHOD0(GetProperties, Properties());
+  MOCK_CONST_METHOD0(GetPermissions, Permissions());
+  MOCK_CONST_METHOD0(GetDescriptors, std::vector<BluetoothGattDescriptor*>());
+  MOCK_CONST_METHOD1(GetDescriptor,
+                     BluetoothGattDescriptor*(const std::string&));
+  MOCK_METHOD1(AddDescriptor, bool(BluetoothGattDescriptor*));
+  MOCK_METHOD1(UpdateValue, bool(const std::vector<uint8>&));
+  MOCK_METHOD2(ReadRemoteCharacteristic,
+               void(const ValueCallback&, const ErrorCallback&));
+  MOCK_METHOD3(WriteRemoteCharacteristic,
+               void(const std::vector<uint8>&,
+                    const base::Closure&,
+                    const ErrorCallback&));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockBluetoothGattCharacteristic);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_BLUETOOTH_TEST_MOCK_BLUETOOTH_GATT_CHARACTERISTIC_H_
diff --git a/device/bluetooth/test/mock_bluetooth_socket.h b/device/bluetooth/test/mock_bluetooth_socket.h
index 09e7e26..f990478 100644
--- a/device/bluetooth/test/mock_bluetooth_socket.h
+++ b/device/bluetooth/test/mock_bluetooth_socket.h
@@ -17,7 +17,7 @@
  public:
   MockBluetoothSocket();
   MOCK_METHOD0(Close, void());
-  MOCK_METHOD1(Disconnect, void(const base::Closure& callback));
+  MOCK_METHOD1(Disconnect, void(const base::Closure& success_callback));
   MOCK_METHOD3(Receive,
                void(int count,
                     const ReceiveCompletionCallback& success_callback,
diff --git a/device/device_tests.gyp b/device/device_tests.gyp
index b28f475..46c8f3d 100644
--- a/device/device_tests.gyp
+++ b/device/device_tests.gyp
@@ -59,8 +59,7 @@
         }],
         ['os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
diff --git a/device/hid/hid_connection_win.cc b/device/hid/hid_connection_win.cc
index ca28251..17448f0 100644
--- a/device/hid/hid_connection_win.cc
+++ b/device/hid/hid_connection_win.cc
@@ -142,18 +142,22 @@
     return;
   }
 
-  if (buffer->size() < device_info().input_report_size) {
+  // This fairly awkward logic is correct: If Windows does not expect a device
+  // to supply a report ID in its input reports, it requires the buffer to be
+  // 1 byte larger than what the device actually sends.
+  int receive_buffer_size = device_info().input_report_size;
+  int expected_buffer_size = receive_buffer_size;
+  if (!device_info().has_report_id)
+    expected_buffer_size -= 1;
+
+  if (buffer->size() < expected_buffer_size) {
     callback.Run(false, 0);
     return;
   }
 
-  // If the device doesn't support report IDs, the caller should not be
-  // expecting one; however, Windows will always expect enough space for one,
-  // so we need to use a buffer with one extra byte of space in this case.
   scoped_refptr<net::IOBufferWithSize> receive_buffer(buffer);
-  if (!device_info().has_report_id)
-    receive_buffer = new net::IOBufferWithSize(buffer->size() + 1);
-
+  if (receive_buffer_size != expected_buffer_size)
+    receive_buffer = new net::IOBufferWithSize(receive_buffer_size);
   scoped_refptr<PendingHidTransfer> transfer(
       new PendingHidTransfer(this, buffer, receive_buffer, callback));
   transfers_.insert(transfer);
@@ -183,7 +187,7 @@
   memcpy(output_buffer->data() + 1, buffer->data(), buffer->size());
 
   scoped_refptr<PendingHidTransfer> transfer(
-      new PendingHidTransfer(this, buffer, NULL, callback));
+      new PendingHidTransfer(this, output_buffer, NULL, callback));
   transfers_.insert(transfer);
   transfer->TakeResultFromWindowsAPI(
       WriteFile(file_.Get(),
@@ -204,14 +208,18 @@
     return;
   }
 
-  if (buffer->size() < device_info().feature_report_size) {
+  int receive_buffer_size = device_info().feature_report_size;
+  int expected_buffer_size = receive_buffer_size;
+  if (!device_info().has_report_id)
+    expected_buffer_size -= 1;
+  if (buffer->size() < expected_buffer_size) {
     callback.Run(false, 0);
     return;
   }
 
   scoped_refptr<net::IOBufferWithSize> receive_buffer(buffer);
-  if (!device_info().has_report_id)
-    receive_buffer = new net::IOBufferWithSize(buffer->size() + 1);
+  if (receive_buffer_size != expected_buffer_size)
+    receive_buffer = new net::IOBufferWithSize(receive_buffer_size);
 
   // The first byte of the destination buffer is the report ID being requested.
   receive_buffer->data()[0] = report_id;
@@ -240,11 +248,6 @@
     return;
   }
 
-  if (buffer->size() < device_info().feature_report_size) {
-    callback.Run(false, 0);
-    return;
-  }
-
   // The Windows API always wants either a report ID (if supported) or
   // zero at the front of every output report.
   scoped_refptr<net::IOBufferWithSize> output_buffer(buffer);
@@ -253,7 +256,7 @@
   memcpy(output_buffer->data() + 1, buffer->data(), buffer->size());
 
   scoped_refptr<PendingHidTransfer> transfer(
-      new PendingHidTransfer(this, buffer, NULL, callback));
+      new PendingHidTransfer(this, output_buffer, NULL, callback));
   transfer->TakeResultFromWindowsAPI(
       DeviceIoControl(file_.Get(),
                       IOCTL_HID_SET_FEATURE,
diff --git a/device/hid/hid_service_win.cc b/device/hid/hid_service_win.cc
index dade5d2..42c9a3a 100644
--- a/device/hid/hid_service_win.cc
+++ b/device/hid/hid_service_win.cc
@@ -204,34 +204,10 @@
         device_info.has_report_id = (button_caps[0].ReportID != 0);
       }
     }
-    // If report IDs are supported, adjust all the expected report sizes
-    // down by one byte. This is because Windows will always provide sizes
-    // which assume the presence of a report ID.
-    if (device_info.has_report_id) {
-      if (device_info.input_report_size > 0)
-        device_info.input_report_size -= 1;
-      if (device_info.output_report_size > 0)
-        device_info.output_report_size -= 1;
-      if (device_info.feature_report_size > 0)
-        device_info.feature_report_size -= 1;
-    }
+
     HidD_FreePreparsedData(preparsed_data);
   }
 
-  // Get the serial number
-  wchar_t str_property[512] = { 0 };
-  if (HidD_GetSerialNumberString(device_handle.Get(),
-                                 str_property,
-                                 sizeof(str_property))) {
-    device_info.serial_number = base::SysWideToUTF8(str_property);
-  }
-
-  if (HidD_GetProductString(device_handle.Get(),
-                            str_property,
-                            sizeof(str_property))) {
-    device_info.product_name = base::SysWideToUTF8(str_property);
-  }
-
   AddDevice(device_info);
 }
 
diff --git a/extensions/DEPS b/extensions/DEPS
index 5d3a4d5..9d6a6a0 100644
--- a/extensions/DEPS
+++ b/extensions/DEPS
@@ -2,6 +2,7 @@
   "+components/url_matcher",
   "+content/public/common",
   "+crypto",
+  "+grit/extensions_resources.h",
   "+testing",
   "+ui",
 
@@ -12,10 +13,11 @@
   #
   # TODO(jamescook): Remove these. http://crbug.com/162530
   "!chrome/browser/chrome_notification_types.h",
-  "!chrome/renderer/extensions/dispatcher.h",
-  "!chrome/renderer/extensions/extension_helper.h",
   "!grit/common_resources.h",
-  "!grit/extensions_api_resources.h",
+  '!grit/extensions_api_resources.h',
+  # This is needed for renderer JS sources which should eventually move to
+  # the extensions_resources target.
+  "!grit/renderer_resources.h",
 ]
 
 specific_include_rules = {
@@ -24,16 +26,24 @@
 
     # Temporarily allowed testing includes.  See above.
     # TODO(jamescook): Remove these. http://crbug.com/162530
+    "+chrome/browser/apps/app_browsertest_util.h",
+    "+chrome/browser/extensions/api/management/management_api.h",
+    "+chrome/browser/extensions/api/permissions/permissions_api.h",
     "+chrome/browser/extensions/extension_api_unittest.h",
+    "+chrome/browser/extensions/extension_apitest.h",
+    "+chrome/browser/extensions/extension_function_test_utils.h",
     "+chrome/browser/extensions/extension_service_unittest.h",
+    "+chrome/browser/extensions/test_extension_dir.h",
     "+chrome/browser/extensions/test_extension_system.h",
+    "+chrome/browser/ui/browser.h",
     "+chrome/common/chrome_paths.h",
+    "+chrome/common/extensions/features/feature_channel.h",
     "+chrome/common/extensions/manifest_tests/extension_manifest_test.h",
     "+chrome/test/base/testing_profile.h",
+    "+chrome/test/base/ui_test_utils.h",
   ],
   "(simple|complex)_feature_unittest\.cc|base_feature_provider_unittest\.cc": [
     "+chrome/common/extensions/features/chrome_channel_feature_filter.h",
-    "+chrome/common/extensions/features/feature_channel.h",
   ],
   "permissions_data_unittest\.cc": [
     "+chrome/common/chrome_version_info.h",
diff --git a/extensions/browser/DEPS b/extensions/browser/DEPS
index dfc7fe1..af6e02a 100644
--- a/extensions/browser/DEPS
+++ b/extensions/browser/DEPS
@@ -7,4 +7,5 @@
   "+sync",
   "+third_party/leveldatabase",
   "+third_party/skia/include",
+  "+webkit/browser/fileapi",
 ]
diff --git a/extensions/browser/api/async_api_function.cc b/extensions/browser/api/async_api_function.cc
index 1152f20..a4e40f6 100644
--- a/extensions/browser/api/async_api_function.cc
+++ b/extensions/browser/api/async_api_function.cc
@@ -16,7 +16,7 @@
 
 AsyncApiFunction::~AsyncApiFunction() {}
 
-bool AsyncApiFunction::RunImpl() {
+bool AsyncApiFunction::RunAsync() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   if (!PrePrepare() || !Prepare()) {
diff --git a/extensions/browser/api/async_api_function.h b/extensions/browser/api/async_api_function.h
index b18ec4d..dd586f1 100644
--- a/extensions/browser/api/async_api_function.h
+++ b/extensions/browser/api/async_api_function.h
@@ -12,7 +12,7 @@
 
 // AsyncApiFunction provides convenient thread management for APIs that need to
 // do essentially all their work on a thread other than the UI thread.
-class AsyncApiFunction : public UIThreadExtensionFunction {
+class AsyncApiFunction : public AsyncExtensionFunction {
  protected:
   AsyncApiFunction();
   virtual ~AsyncApiFunction();
@@ -38,8 +38,8 @@
   // Respond. Guaranteed to happen on UI thread.
   virtual bool Respond() = 0;
 
-  // ExtensionFunction::RunImpl()
-  virtual bool RunImpl() OVERRIDE;
+  // ExtensionFunction::RunAsync()
+  virtual bool RunAsync() OVERRIDE;
 
  protected:
   content::BrowserThread::ID work_thread_id() const { return work_thread_id_; }
diff --git a/extensions/browser/api/dns/dns_api.cc b/extensions/browser/api/dns/dns_api.cc
index a3a7eb1..ef270c7 100644
--- a/extensions/browser/api/dns/dns_api.cc
+++ b/extensions/browser/api/dns/dns_api.cc
@@ -30,7 +30,7 @@
 
 DnsResolveFunction::~DnsResolveFunction() {}
 
-bool DnsResolveFunction::RunImpl() {
+bool DnsResolveFunction::RunAsync() {
   scoped_ptr<Resolve::Params> params(Resolve::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
 
diff --git a/extensions/browser/api/dns/dns_api.h b/extensions/browser/api/dns/dns_api.h
index f14769b..8261564 100644
--- a/extensions/browser/api/dns/dns_api.h
+++ b/extensions/browser/api/dns/dns_api.h
@@ -28,7 +28,7 @@
   virtual ~DnsResolveFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
   void WorkOnIOThread();
   void RespondOnUIThread();
diff --git a/extensions/browser/api/runtime/runtime_api.cc b/extensions/browser/api/runtime/runtime_api.cc
new file mode 100644
index 0000000..9dc3feb
--- /dev/null
+++ b/extensions/browser/api/runtime/runtime_api.cc
@@ -0,0 +1,517 @@
+// 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.
+
+#include "extensions/browser/api/runtime/runtime_api.h"
+
+#include <utility>
+
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
+#include "base/values.h"
+#include "base/version.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/child_process_security_policy.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "extensions/browser/api/runtime/runtime_api_delegate.h"
+#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_host.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/extensions_browser_client.h"
+#include "extensions/browser/lazy_background_task_queue.h"
+#include "extensions/browser/process_manager.h"
+#include "extensions/common/api/runtime.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/manifest_handlers/background_info.h"
+#include "url/gurl.h"
+#include "webkit/browser/fileapi/isolated_context.h"
+
+using content::BrowserContext;
+
+namespace extensions {
+
+namespace runtime = core_api::runtime;
+
+namespace {
+
+const char kNoBackgroundPageError[] = "You do not have a background page.";
+const char kPageLoadError[] = "Background page failed to load.";
+const char kInstallReason[] = "reason";
+const char kInstallReasonChromeUpdate[] = "chrome_update";
+const char kInstallReasonUpdate[] = "update";
+const char kInstallReasonInstall[] = "install";
+const char kInstallPreviousVersion[] = "previousVersion";
+const char kInvalidUrlError[] = "Invalid URL.";
+const char kPlatformInfoUnavailable[] = "Platform information unavailable.";
+
+const char kUpdatesDisabledError[] = "Autoupdate is not enabled.";
+
+// A preference key storing the url loaded when an extension is uninstalled.
+const char kUninstallUrl[] = "uninstall_url";
+
+// The name of the directory to be returned by getPackageDirectoryEntry. This
+// particular value does not matter to user code, but is chosen for consistency
+// with the equivalent Pepper API.
+const char kPackageDirectoryPath[] = "crxfs";
+
+void DispatchOnStartupEventImpl(BrowserContext* browser_context,
+                                const std::string& extension_id,
+                                bool first_call,
+                                ExtensionHost* host) {
+  // A NULL host from the LazyBackgroundTaskQueue means the page failed to
+  // load. Give up.
+  if (!host && !first_call)
+    return;
+
+  // Don't send onStartup events to incognito browser contexts.
+  if (browser_context->IsOffTheRecord())
+    return;
+
+  if (ExtensionsBrowserClient::Get()->IsShuttingDown() ||
+      !ExtensionsBrowserClient::Get()->IsValidContext(browser_context))
+    return;
+  ExtensionSystem* system = ExtensionSystem::Get(browser_context);
+  if (!system)
+    return;
+
+  // If this is a persistent background page, we want to wait for it to load
+  // (it might not be ready, since this is startup). But only enqueue once.
+  // If it fails to load the first time, don't bother trying again.
+  const Extension* extension =
+      ExtensionRegistry::Get(browser_context)->enabled_extensions().GetByID(
+          extension_id);
+  if (extension && BackgroundInfo::HasPersistentBackgroundPage(extension) &&
+      first_call &&
+      system->lazy_background_task_queue()->ShouldEnqueueTask(browser_context,
+                                                              extension)) {
+    system->lazy_background_task_queue()->AddPendingTask(
+        browser_context,
+        extension_id,
+        base::Bind(
+            &DispatchOnStartupEventImpl, browser_context, extension_id, false));
+    return;
+  }
+
+  scoped_ptr<base::ListValue> event_args(new base::ListValue());
+  scoped_ptr<Event> event(
+      new Event(runtime::OnStartup::kEventName, event_args.Pass()));
+  system->event_router()->DispatchEventToExtension(extension_id, event.Pass());
+}
+
+void SetUninstallURL(ExtensionPrefs* prefs,
+                     const std::string& extension_id,
+                     const std::string& url_string) {
+  prefs->UpdateExtensionPref(
+      extension_id, kUninstallUrl, new base::StringValue(url_string));
+}
+
+#if defined(ENABLE_EXTENSIONS)
+std::string GetUninstallURL(ExtensionPrefs* prefs,
+                            const std::string& extension_id) {
+  std::string url_string;
+  prefs->ReadPrefAsString(extension_id, kUninstallUrl, &url_string);
+  return url_string;
+}
+#endif  // defined(ENABLE_EXTENSIONS)
+
+}  // namespace
+
+///////////////////////////////////////////////////////////////////////////////
+
+static base::LazyInstance<BrowserContextKeyedAPIFactory<RuntimeAPI> >
+    g_factory = LAZY_INSTANCE_INITIALIZER;
+
+// static
+BrowserContextKeyedAPIFactory<RuntimeAPI>* RuntimeAPI::GetFactoryInstance() {
+  return g_factory.Pointer();
+}
+
+RuntimeAPI::RuntimeAPI(content::BrowserContext* context)
+    : browser_context_(context), dispatch_chrome_updated_event_(false) {
+  registrar_.Add(this,
+                 chrome::NOTIFICATION_EXTENSIONS_READY,
+                 content::Source<BrowserContext>(context));
+  registrar_.Add(this,
+                 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
+                 content::Source<BrowserContext>(context));
+  registrar_.Add(this,
+                 chrome::NOTIFICATION_EXTENSION_INSTALLED,
+                 content::Source<BrowserContext>(context));
+  registrar_.Add(this,
+                 chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
+                 content::Source<BrowserContext>(context));
+
+  delegate_ = ExtensionsBrowserClient::Get()->CreateRuntimeAPIDelegate(
+      browser_context_);
+
+  // Check if registered events are up-to-date. We can only do this once
+  // per browser context, since it updates internal state when called.
+  dispatch_chrome_updated_event_ =
+      ExtensionsBrowserClient::Get()->DidVersionUpdate(browser_context_);
+}
+
+RuntimeAPI::~RuntimeAPI() {
+  delegate_->RemoveUpdateObserver(this);
+}
+
+void RuntimeAPI::Observe(int type,
+                         const content::NotificationSource& source,
+                         const content::NotificationDetails& details) {
+  switch (type) {
+    case chrome::NOTIFICATION_EXTENSIONS_READY: {
+      OnExtensionsReady();
+      break;
+    }
+    case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
+      const Extension* extension =
+          content::Details<const Extension>(details).ptr();
+      OnExtensionLoaded(extension);
+      break;
+    }
+    case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
+      const Extension* extension =
+          content::Details<const InstalledExtensionInfo>(details)->extension;
+      OnExtensionInstalled(extension);
+      break;
+    }
+    case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
+      const Extension* extension =
+          content::Details<const Extension>(details).ptr();
+      OnExtensionUninstalled(extension);
+      break;
+    }
+    default:
+      NOTREACHED();
+      break;
+  }
+}
+
+void RuntimeAPI::OnExtensionsReady() {
+  // We're done restarting Chrome after an update.
+  dispatch_chrome_updated_event_ = false;
+
+  delegate_->AddUpdateObserver(this);
+
+  // RuntimeAPI is redirected in incognito, so |browser_context_| is never
+  // incognito. We don't observe incognito ProcessManagers but that is OK
+  // because we don't send onStartup events to incognito browser contexts.
+  DCHECK(!browser_context_->IsOffTheRecord());
+  // Some tests use partially constructed Profiles without a process manager.
+  ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_);
+  if (extension_system->process_manager())
+    extension_system->process_manager()->AddObserver(this);
+}
+
+void RuntimeAPI::OnExtensionLoaded(const Extension* extension) {
+  if (!dispatch_chrome_updated_event_)
+    return;
+
+  // Dispatch the onInstalled event with reason "chrome_update".
+  base::MessageLoop::current()->PostTask(
+      FROM_HERE,
+      base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent,
+                 browser_context_,
+                 extension->id(),
+                 Version(),
+                 true));
+}
+
+void RuntimeAPI::OnExtensionInstalled(const Extension* extension) {
+  // Ephemeral apps are not considered to be installed and do not receive
+  // the onInstalled() event.
+  if (extension->is_ephemeral())
+    return;
+
+  Version old_version = delegate_->GetPreviousExtensionVersion(extension);
+
+  // Dispatch the onInstalled event.
+  base::MessageLoop::current()->PostTask(
+      FROM_HERE,
+      base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent,
+                 browser_context_,
+                 extension->id(),
+                 old_version,
+                 false));
+}
+
+void RuntimeAPI::OnExtensionUninstalled(const Extension* extension) {
+  // Ephemeral apps are not considered to be installed, so the uninstall URL
+  // is not invoked when they are removed.
+  if (extension->is_ephemeral())
+    return;
+
+  RuntimeEventRouter::OnExtensionUninstalled(browser_context_, extension->id());
+}
+
+void RuntimeAPI::Shutdown() {
+  // ExtensionSystem deletes its ProcessManager during the Shutdown() phase, so
+  // the observer must be removed here and not in the RuntimeAPI destructor.
+  ProcessManager* process_manager =
+      ExtensionSystem::Get(browser_context_)->process_manager();
+  // Some tests use partially constructed Profiles without a process manager.
+  if (process_manager)
+    process_manager->RemoveObserver(this);
+}
+
+void RuntimeAPI::OnAppUpdateAvailable(const Extension* extension) {
+  RuntimeEventRouter::DispatchOnUpdateAvailableEvent(
+      browser_context_, extension->id(), extension->manifest()->value());
+}
+
+void RuntimeAPI::OnChromeUpdateAvailable() {
+  RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(browser_context_);
+}
+
+void RuntimeAPI::OnBackgroundHostStartup(const Extension* extension) {
+  RuntimeEventRouter::DispatchOnStartupEvent(browser_context_, extension->id());
+}
+
+void RuntimeAPI::ReloadExtension(const std::string& extension_id) {
+  delegate_->ReloadExtension(extension_id);
+}
+
+bool RuntimeAPI::CheckForUpdates(
+    const std::string& extension_id,
+    const RuntimeAPIDelegate::UpdateCheckCallback& callback) {
+  return delegate_->CheckForUpdates(extension_id, callback);
+}
+
+void RuntimeAPI::OpenURL(const GURL& update_url) {
+  delegate_->OpenURL(update_url);
+}
+
+bool RuntimeAPI::GetPlatformInfo(runtime::PlatformInfo* info) {
+  return delegate_->GetPlatformInfo(info);
+}
+
+bool RuntimeAPI::RestartDevice(std::string* error_message) {
+  return delegate_->RestartDevice(error_message);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// static
+void RuntimeEventRouter::DispatchOnStartupEvent(
+    content::BrowserContext* context,
+    const std::string& extension_id) {
+  DispatchOnStartupEventImpl(context, extension_id, true, NULL);
+}
+
+// static
+void RuntimeEventRouter::DispatchOnInstalledEvent(
+    content::BrowserContext* context,
+    const std::string& extension_id,
+    const Version& old_version,
+    bool chrome_updated) {
+  if (!ExtensionsBrowserClient::Get()->IsValidContext(context))
+    return;
+  ExtensionSystem* system = ExtensionSystem::Get(context);
+  if (!system)
+    return;
+
+  scoped_ptr<base::ListValue> event_args(new base::ListValue());
+  base::DictionaryValue* info = new base::DictionaryValue();
+  event_args->Append(info);
+  if (old_version.IsValid()) {
+    info->SetString(kInstallReason, kInstallReasonUpdate);
+    info->SetString(kInstallPreviousVersion, old_version.GetString());
+  } else if (chrome_updated) {
+    info->SetString(kInstallReason, kInstallReasonChromeUpdate);
+  } else {
+    info->SetString(kInstallReason, kInstallReasonInstall);
+  }
+  DCHECK(system->event_router());
+  scoped_ptr<Event> event(
+      new Event(runtime::OnInstalled::kEventName, event_args.Pass()));
+  system->event_router()->DispatchEventWithLazyListener(extension_id,
+                                                        event.Pass());
+}
+
+// static
+void RuntimeEventRouter::DispatchOnUpdateAvailableEvent(
+    content::BrowserContext* context,
+    const std::string& extension_id,
+    const base::DictionaryValue* manifest) {
+  ExtensionSystem* system = ExtensionSystem::Get(context);
+  if (!system)
+    return;
+
+  scoped_ptr<base::ListValue> args(new base::ListValue);
+  args->Append(manifest->DeepCopy());
+  DCHECK(system->event_router());
+  scoped_ptr<Event> event(
+      new Event(runtime::OnUpdateAvailable::kEventName, args.Pass()));
+  system->event_router()->DispatchEventToExtension(extension_id, event.Pass());
+}
+
+// static
+void RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(
+    content::BrowserContext* context) {
+  ExtensionSystem* system = ExtensionSystem::Get(context);
+  if (!system)
+    return;
+
+  scoped_ptr<base::ListValue> args(new base::ListValue);
+  DCHECK(system->event_router());
+  scoped_ptr<Event> event(
+      new Event(runtime::OnBrowserUpdateAvailable::kEventName, args.Pass()));
+  system->event_router()->BroadcastEvent(event.Pass());
+}
+
+// static
+void RuntimeEventRouter::DispatchOnRestartRequiredEvent(
+    content::BrowserContext* context,
+    const std::string& app_id,
+    core_api::runtime::OnRestartRequired::Reason reason) {
+  ExtensionSystem* system = ExtensionSystem::Get(context);
+  if (!system)
+    return;
+
+  scoped_ptr<Event> event(
+      new Event(runtime::OnRestartRequired::kEventName,
+                core_api::runtime::OnRestartRequired::Create(reason)));
+
+  DCHECK(system->event_router());
+  system->event_router()->DispatchEventToExtension(app_id, event.Pass());
+}
+
+// static
+void RuntimeEventRouter::OnExtensionUninstalled(
+    content::BrowserContext* context,
+    const std::string& extension_id) {
+#if defined(ENABLE_EXTENSIONS)
+  GURL uninstall_url(
+      GetUninstallURL(ExtensionPrefs::Get(context), extension_id));
+
+  if (uninstall_url.is_empty())
+    return;
+
+  RuntimeAPI::GetFactoryInstance()->Get(context)->OpenURL(uninstall_url);
+#endif  // defined(ENABLE_EXTENSIONS)
+}
+
+ExtensionFunction::ResponseAction RuntimeGetBackgroundPageFunction::Run() {
+  ExtensionSystem* system = ExtensionSystem::Get(browser_context());
+  ExtensionHost* host =
+      system->process_manager()->GetBackgroundHostForExtension(extension_id());
+  if (system->lazy_background_task_queue()->ShouldEnqueueTask(browser_context(),
+                                                              GetExtension())) {
+    system->lazy_background_task_queue()->AddPendingTask(
+        browser_context(),
+        extension_id(),
+        base::Bind(&RuntimeGetBackgroundPageFunction::OnPageLoaded, this));
+  } else if (host) {
+    OnPageLoaded(host);
+  } else {
+    return RespondNow(Error(kNoBackgroundPageError));
+  }
+
+  return RespondLater();
+}
+
+void RuntimeGetBackgroundPageFunction::OnPageLoaded(ExtensionHost* host) {
+  if (host) {
+    Respond(NoArguments());
+  } else {
+    Respond(Error(kPageLoadError));
+  }
+}
+
+ExtensionFunction::ResponseAction RuntimeSetUninstallURLFunction::Run() {
+  std::string url_string;
+  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url_string));
+
+  GURL url(url_string);
+  if (!url.is_valid()) {
+    return RespondNow(
+        Error(ErrorUtils::FormatErrorMessage(kInvalidUrlError, url_string)));
+  }
+  SetUninstallURL(
+      ExtensionPrefs::Get(browser_context()), extension_id(), url_string);
+  return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction RuntimeReloadFunction::Run() {
+  RuntimeAPI::GetFactoryInstance()->Get(browser_context())->ReloadExtension(
+      extension_id());
+  return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction RuntimeRequestUpdateCheckFunction::Run() {
+  if (!RuntimeAPI::GetFactoryInstance()
+           ->Get(browser_context())
+           ->CheckForUpdates(
+               extension_id(),
+               base::Bind(&RuntimeRequestUpdateCheckFunction::CheckComplete,
+                          this))) {
+    return RespondNow(Error(kUpdatesDisabledError));
+  }
+  return RespondLater();
+}
+
+void RuntimeRequestUpdateCheckFunction::CheckComplete(
+    const RuntimeAPIDelegate::UpdateCheckResult& result) {
+  if (result.success) {
+    base::ListValue* results = new base::ListValue;
+    results->AppendString(result.response);
+    base::DictionaryValue* details = new base::DictionaryValue;
+    results->Append(details);
+    details->SetString("version", result.version);
+    Respond(MultipleArguments(results));
+  } else {
+    Respond(SingleArgument(new base::StringValue(result.response)));
+  }
+}
+
+ExtensionFunction::ResponseAction RuntimeRestartFunction::Run() {
+  std::string message;
+  bool result =
+      RuntimeAPI::GetFactoryInstance()->Get(browser_context())->RestartDevice(
+          &message);
+  if (!result) {
+    return RespondNow(Error(message));
+  }
+  return RespondNow(NoArguments());
+}
+
+ExtensionFunction::ResponseAction RuntimeGetPlatformInfoFunction::Run() {
+  runtime::PlatformInfo info;
+  if (!RuntimeAPI::GetFactoryInstance()
+           ->Get(browser_context())
+           ->GetPlatformInfo(&info)) {
+    return RespondNow(Error(kPlatformInfoUnavailable));
+  }
+  return RespondNow(MultipleArguments(
+      runtime::GetPlatformInfo::Results::Create(info).release()));
+}
+
+ExtensionFunction::ResponseAction
+RuntimeGetPackageDirectoryEntryFunction::Run() {
+  fileapi::IsolatedContext* isolated_context =
+      fileapi::IsolatedContext::GetInstance();
+  DCHECK(isolated_context);
+
+  std::string relative_path = kPackageDirectoryPath;
+  base::FilePath path = extension_->path();
+  std::string filesystem_id = isolated_context->RegisterFileSystemForPath(
+      fileapi::kFileSystemTypeNativeLocal, path, &relative_path);
+
+  int renderer_id = render_view_host_->GetProcess()->GetID();
+  content::ChildProcessSecurityPolicy* policy =
+      content::ChildProcessSecurityPolicy::GetInstance();
+  policy->GrantReadFileSystem(renderer_id, filesystem_id);
+  base::DictionaryValue* dict = new base::DictionaryValue();
+  dict->SetString("fileSystemId", filesystem_id);
+  dict->SetString("baseName", relative_path);
+  return RespondNow(SingleArgument(dict));
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/api/runtime/runtime_api.h b/extensions/browser/api/runtime/runtime_api.h
new file mode 100644
index 0000000..e341398
--- /dev/null
+++ b/extensions/browser/api/runtime/runtime_api.h
@@ -0,0 +1,206 @@
+// 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.
+
+#ifndef EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_
+#define EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_
+
+#include <string>
+
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "extensions/browser/api/runtime/runtime_api_delegate.h"
+#include "extensions/browser/browser_context_keyed_api_factory.h"
+#include "extensions/browser/extension_function.h"
+#include "extensions/browser/process_manager_observer.h"
+#include "extensions/browser/update_observer.h"
+#include "extensions/common/api/runtime.h"
+
+namespace base {
+class Version;
+}
+
+namespace content {
+class BrowserContext;
+}
+
+namespace extensions {
+
+namespace core_api {
+namespace runtime {
+struct PlatformInfo;
+}
+}
+
+class Extension;
+class ExtensionHost;
+
+// Runtime API dispatches onStartup, onInstalled, and similar events to
+// extensions. There is one instance shared between a browser context and
+// its related incognito instance.
+class RuntimeAPI : public BrowserContextKeyedAPI,
+                   public content::NotificationObserver,
+                   public UpdateObserver,
+                   public ProcessManagerObserver {
+ public:
+  static BrowserContextKeyedAPIFactory<RuntimeAPI>* GetFactoryInstance();
+
+  explicit RuntimeAPI(content::BrowserContext* context);
+  virtual ~RuntimeAPI();
+
+  // content::NotificationObserver overrides:
+  virtual void Observe(int type,
+                       const content::NotificationSource& source,
+                       const content::NotificationDetails& details) OVERRIDE;
+
+  void ReloadExtension(const std::string& extension_id);
+  bool CheckForUpdates(const std::string& extension_id,
+                       const RuntimeAPIDelegate::UpdateCheckCallback& callback);
+  void OpenURL(const GURL& uninstall_url);
+  bool GetPlatformInfo(core_api::runtime::PlatformInfo* info);
+  bool RestartDevice(std::string* error_message);
+
+ private:
+  friend class BrowserContextKeyedAPIFactory<RuntimeAPI>;
+
+  void OnExtensionsReady();
+  void OnExtensionLoaded(const Extension* extension);
+  void OnExtensionInstalled(const Extension* extension);
+  void OnExtensionUninstalled(const Extension* extension);
+
+  // BrowserContextKeyedAPI implementation:
+  static const char* service_name() { return "RuntimeAPI"; }
+  static const bool kServiceRedirectedInIncognito = true;
+  static const bool kServiceIsNULLWhileTesting = true;
+  virtual void Shutdown() OVERRIDE;
+
+  // extensions::UpdateObserver overrides:
+  virtual void OnAppUpdateAvailable(const Extension* extension) OVERRIDE;
+  virtual void OnChromeUpdateAvailable() OVERRIDE;
+
+  // ProcessManagerObserver implementation:
+  virtual void OnBackgroundHostStartup(const Extension* extension) OVERRIDE;
+
+  scoped_ptr<RuntimeAPIDelegate> delegate_;
+
+  content::BrowserContext* browser_context_;
+
+  // True if we should dispatch the chrome.runtime.onInstalled event with
+  // reason "chrome_update" upon loading each extension.
+  bool dispatch_chrome_updated_event_;
+
+  content::NotificationRegistrar registrar_;
+
+  DISALLOW_COPY_AND_ASSIGN(RuntimeAPI);
+};
+
+class RuntimeEventRouter {
+ public:
+  // Dispatches the onStartup event to all currently-loaded extensions.
+  static void DispatchOnStartupEvent(content::BrowserContext* context,
+                                     const std::string& extension_id);
+
+  // Dispatches the onInstalled event to the given extension.
+  static void DispatchOnInstalledEvent(content::BrowserContext* context,
+                                       const std::string& extension_id,
+                                       const base::Version& old_version,
+                                       bool chrome_updated);
+
+  // Dispatches the onUpdateAvailable event to the given extension.
+  static void DispatchOnUpdateAvailableEvent(
+      content::BrowserContext* context,
+      const std::string& extension_id,
+      const base::DictionaryValue* manifest);
+
+  // Dispatches the onBrowserUpdateAvailable event to all extensions.
+  static void DispatchOnBrowserUpdateAvailableEvent(
+      content::BrowserContext* context);
+
+  // Dispatches the onRestartRequired event to the given app.
+  static void DispatchOnRestartRequiredEvent(
+      content::BrowserContext* context,
+      const std::string& app_id,
+      core_api::runtime::OnRestartRequired::Reason reason);
+
+  // Does any work needed at extension uninstall (e.g. load uninstall url).
+  static void OnExtensionUninstalled(content::BrowserContext* context,
+                                     const std::string& extension_id);
+};
+
+class RuntimeGetBackgroundPageFunction : public UIThreadExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("runtime.getBackgroundPage",
+                             RUNTIME_GETBACKGROUNDPAGE)
+
+ protected:
+  virtual ~RuntimeGetBackgroundPageFunction() {}
+  virtual ResponseAction Run() OVERRIDE;
+
+ private:
+  void OnPageLoaded(ExtensionHost*);
+};
+
+class RuntimeSetUninstallURLFunction : public UIThreadExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("runtime.setUninstallURL", RUNTIME_SETUNINSTALLURL)
+
+ protected:
+  virtual ~RuntimeSetUninstallURLFunction() {}
+  virtual ResponseAction Run() OVERRIDE;
+};
+
+class RuntimeReloadFunction : public UIThreadExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("runtime.reload", RUNTIME_RELOAD)
+
+ protected:
+  virtual ~RuntimeReloadFunction() {}
+  virtual ResponseAction Run() OVERRIDE;
+};
+
+class RuntimeRequestUpdateCheckFunction : public UIThreadExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("runtime.requestUpdateCheck",
+                             RUNTIME_REQUESTUPDATECHECK)
+
+ protected:
+  virtual ~RuntimeRequestUpdateCheckFunction() {}
+  virtual ResponseAction Run() OVERRIDE;
+
+ private:
+  void CheckComplete(const RuntimeAPIDelegate::UpdateCheckResult& result);
+};
+
+class RuntimeRestartFunction : public UIThreadExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("runtime.restart", RUNTIME_RESTART)
+
+ protected:
+  virtual ~RuntimeRestartFunction() {}
+  virtual ResponseAction Run() OVERRIDE;
+};
+
+class RuntimeGetPlatformInfoFunction : public UIThreadExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("runtime.getPlatformInfo",
+                             RUNTIME_GETPLATFORMINFO);
+
+ protected:
+  virtual ~RuntimeGetPlatformInfoFunction() {}
+  virtual ResponseAction Run() OVERRIDE;
+};
+
+class RuntimeGetPackageDirectoryEntryFunction
+    : public UIThreadExtensionFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("runtime.getPackageDirectoryEntry",
+                             RUNTIME_GETPACKAGEDIRECTORYENTRY)
+
+ protected:
+  virtual ~RuntimeGetPackageDirectoryEntryFunction() {}
+  virtual ResponseAction Run() OVERRIDE;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_
diff --git a/extensions/browser/api/runtime/runtime_api_delegate.cc b/extensions/browser/api/runtime/runtime_api_delegate.cc
new file mode 100644
index 0000000..3ead8b6
--- /dev/null
+++ b/extensions/browser/api/runtime/runtime_api_delegate.cc
@@ -0,0 +1,16 @@
+// 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.
+
+#include "extensions/browser/api/runtime/runtime_api_delegate.h"
+
+namespace extensions {
+
+RuntimeAPIDelegate::UpdateCheckResult::UpdateCheckResult(
+    bool success,
+    const std::string& response,
+    const std::string& version)
+    : success(success), response(response), version(version) {
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/api/runtime/runtime_api_delegate.h b/extensions/browser/api/runtime/runtime_api_delegate.h
new file mode 100644
index 0000000..98b4963
--- /dev/null
+++ b/extensions/browser/api/runtime/runtime_api_delegate.h
@@ -0,0 +1,77 @@
+// 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.
+
+#ifndef EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H
+#define EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H
+
+#include "base/callback.h"
+#include "base/version.h"
+
+class GURL;
+
+namespace extensions {
+
+namespace core_api {
+namespace runtime {
+struct PlatformInfo;
+}
+}
+
+class Extension;
+class UpdateObserver;
+
+// This is a delegate interface for chrome.runtime API behavior. Clients must
+// vend some implementation of this interface through
+// ExtensionsBrowserClient::CreateRuntimeAPIDelegate.
+class RuntimeAPIDelegate {
+ public:
+  struct UpdateCheckResult {
+    bool success;
+    std::string response;
+    std::string version;
+
+    UpdateCheckResult(bool success,
+                      const std::string& response,
+                      const std::string& version);
+  };
+
+  virtual ~RuntimeAPIDelegate() {}
+
+  // The callback given to RequestUpdateCheck.
+  typedef base::Callback<void(const UpdateCheckResult&)> UpdateCheckCallback;
+
+  // Registers an UpdateObserver on behalf of the runtime API.
+  virtual void AddUpdateObserver(UpdateObserver* observer) = 0;
+
+  // Unregisters an UpdateObserver on behalf of the runtime API.
+  virtual void RemoveUpdateObserver(UpdateObserver* observer) = 0;
+
+  // Determines an extension's previously installed version if applicable.
+  virtual base::Version GetPreviousExtensionVersion(
+      const Extension* extension) = 0;
+
+  // Reloads an extension.
+  virtual void ReloadExtension(const std::string& extension_id) = 0;
+
+  // Requests an extensions update update check. Returns |false| if updates
+  // are disabled. Otherwise |callback| is called with the result of the
+  // update check.
+  virtual bool CheckForUpdates(const std::string& extension_id,
+                               const UpdateCheckCallback& callback) = 0;
+
+  // Navigates the browser to a URL on behalf of the runtime API.
+  virtual void OpenURL(const GURL& uninstall_url) = 0;
+
+  // Populates platform info to be provided by the getPlatformInfo function.
+  // Returns false iff no info is provided.
+  virtual bool GetPlatformInfo(core_api::runtime::PlatformInfo* info) = 0;
+
+  // Request a restart of the host device. Returns false iff the device
+  // will not be restarted.
+  virtual bool RestartDevice(std::string* error_message) = 0;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H
diff --git a/extensions/browser/api/runtime/runtime_apitest.cc b/extensions/browser/api/runtime/runtime_apitest.cc
new file mode 100644
index 0000000..6fd81f1
--- /dev/null
+++ b/extensions/browser/api/runtime/runtime_apitest.cc
@@ -0,0 +1,127 @@
+// 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.
+
+#include "chrome/browser/apps/app_browsertest_util.h"
+#include "chrome/browser/extensions/api/management/management_api.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/extensions/extension_function_test_utils.h"
+#include "chrome/browser/extensions/test_extension_dir.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/notification_service.h"
+#include "extensions/browser/api/runtime/runtime_api.h"
+#include "extensions/browser/extension_registry.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+// Tests the privileged components of chrome.runtime.
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimePrivileged) {
+  ASSERT_TRUE(RunExtensionTest("runtime/privileged")) << message_;
+}
+
+// Tests the unprivileged components of chrome.runtime.
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeUnprivileged) {
+  ASSERT_TRUE(StartEmbeddedTestServer());
+  ASSERT_TRUE(
+      LoadExtension(test_data_dir_.AppendASCII("runtime/content_script")));
+
+  // The content script runs on webpage.html.
+  ResultCatcher catcher;
+  ui_test_utils::NavigateToURL(browser(),
+                               embedded_test_server()->GetURL("/webpage.html"));
+  EXPECT_TRUE(catcher.GetNextResult()) << message_;
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeUninstallURL) {
+  // Auto-confirm the uninstall dialog.
+  extensions::ManagementUninstallFunction::SetAutoConfirmForTest(true);
+  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("runtime")
+                                .AppendASCII("uninstall_url")
+                                .AppendASCII("sets_uninstall_url")));
+  ASSERT_TRUE(RunExtensionTest("runtime/uninstall_url")) << message_;
+}
+
+namespace extensions {
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeGetPlatformInfo) {
+  scoped_ptr<base::Value> result(
+      extension_function_test_utils::RunFunctionAndReturnSingleResult(
+          new RuntimeGetPlatformInfoFunction(), "[]", browser()));
+  ASSERT_TRUE(result.get() != NULL);
+  base::DictionaryValue* dict =
+      extension_function_test_utils::ToDictionary(result.get());
+  ASSERT_TRUE(dict != NULL);
+  EXPECT_TRUE(dict->HasKey("os"));
+  EXPECT_TRUE(dict->HasKey("arch"));
+  EXPECT_TRUE(dict->HasKey("nacl_arch"));
+}
+
+// Tests chrome.runtime.getPackageDirectory with an app.
+IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
+                       ChromeRuntimeGetPackageDirectoryEntryApp) {
+  ClearCommandLineArgs();
+  ASSERT_TRUE(RunPlatformAppTest("api_test/runtime/get_package_directory/app"))
+      << message_;
+}
+
+// Tests chrome.runtime.getPackageDirectory with an extension.
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest,
+                       ChromeRuntimeGetPackageDirectoryEntryExtension) {
+  ASSERT_TRUE(RunExtensionTest("runtime/get_package_directory/extension"))
+      << message_;
+}
+
+// Tests chrome.runtime.reload
+// This test is flaky on Linux: crbug.com/366181
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#define MAYBE_ChromeRuntimeReload DISABLED_ChromeRuntimeReload
+#else
+#define MAYBE_ChromeRuntimeReload ChromeRuntimeReload
+#endif
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_ChromeRuntimeReload) {
+  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
+  const char kManifest[] =
+      "{"
+      "  \"name\": \"reload\","
+      "  \"version\": \"1.0\","
+      "  \"background\": {"
+      "    \"scripts\": [\"background.js\"]"
+      "  },"
+      "  \"manifest_version\": 2"
+      "}";
+
+  TestExtensionDir dir;
+  dir.WriteManifest(kManifest);
+  dir.WriteFile(FILE_PATH_LITERAL("background.js"), "console.log('loaded');");
+
+  const Extension* extension = LoadExtension(dir.unpacked_path());
+  ASSERT_TRUE(extension);
+  const std::string extension_id = extension->id();
+
+  // Somewhat arbitrary upper limit of 30 iterations. If the extension manages
+  // to reload itself that often without being terminated, the test fails
+  // anyway.
+  for (int i = 0; i < 30; i++) {
+    content::WindowedNotificationObserver unload_observer(
+        chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
+        content::NotificationService::AllSources());
+    content::WindowedNotificationObserver load_observer(
+        chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
+        content::NotificationService::AllSources());
+
+    ASSERT_TRUE(ExecuteScriptInBackgroundPageNoWait(
+        extension_id, "chrome.runtime.reload();"));
+    unload_observer.Wait();
+
+    if (registry->GetExtensionById(extension_id,
+                                   ExtensionRegistry::TERMINATED)) {
+      break;
+    } else {
+      load_observer.Wait();
+      WaitForExtensionViewsToLoad();
+    }
+  }
+  ASSERT_TRUE(
+      registry->GetExtensionById(extension_id, ExtensionRegistry::TERMINATED));
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc
index 5d40b84..229cfdd 100644
--- a/extensions/browser/api/socket/socket_api.cc
+++ b/extensions/browser/api/socket/socket_api.cc
@@ -638,7 +638,7 @@
   SetResult(info.ToValue().release());
 }
 
-bool SocketGetNetworkListFunction::RunImpl() {
+bool SocketGetNetworkListFunction::RunAsync() {
   content::BrowserThread::PostTask(
       content::BrowserThread::FILE,
       FROM_HERE,
diff --git a/extensions/browser/api/socket/socket_api.h b/extensions/browser/api/socket/socket_api.h
index 60bd765..cd93f7a 100644
--- a/extensions/browser/api/socket/socket_api.h
+++ b/extensions/browser/api/socket/socket_api.h
@@ -407,7 +407,7 @@
 
  protected:
   virtual ~SocketGetNetworkListFunction() {}
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 
  private:
   void GetNetworkListOnFileThread();
diff --git a/extensions/browser/api/storage/storage_api.cc b/extensions/browser/api/storage/storage_api.cc
index 3f1882d..1023236 100644
--- a/extensions/browser/api/storage/storage_api.cc
+++ b/extensions/browser/api/storage/storage_api.cc
@@ -32,22 +32,20 @@
   std::string settings_namespace_string;
   if (!args_->GetString(0, &settings_namespace_string)) {
     // This should be EXTENSION_FUNCTION_VALIDATE(false) but there is no way
-    // to signify that from this function. It will be caught in
-    // RunImplTypesafe().
+    // to signify that from this function. It will be caught in Run().
     return false;
   }
   return settings_namespace_string != "sync";
 }
 
-ExtensionFunction::ResponseAction SettingsFunction::RunImplTypesafe() {
+ExtensionFunction::ResponseAction SettingsFunction::Run() {
   std::string settings_namespace_string;
-  EXTENSION_FUNCTION_VALIDATE_TYPESAFE(
-      args_->GetString(0, &settings_namespace_string));
+  EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &settings_namespace_string));
   args_->Remove(0, NULL);
   settings_namespace_ =
       settings_namespace::FromString(settings_namespace_string);
-  EXTENSION_FUNCTION_VALIDATE_TYPESAFE(settings_namespace_ !=
-                                       settings_namespace::INVALID);
+  EXTENSION_FUNCTION_VALIDATE(settings_namespace_ !=
+                              settings_namespace::INVALID);
 
   StorageFrontend* frontend = StorageFrontend::Get(browser_context());
   if (!frontend->IsStorageEnabled(settings_namespace_)) {
@@ -66,11 +64,10 @@
 
 void SettingsFunction::AsyncRunWithStorage(ValueStore* storage) {
   ResponseValue response = RunWithStorage(storage);
-  BrowserThread::PostTask(BrowserThread::UI,
-                          FROM_HERE,
-                          base::Bind(&SettingsFunction::SendResponseTypesafe,
-                                     this,
-                                     base::Passed(&response)));
+  BrowserThread::PostTask(
+      BrowserThread::UI,
+      FROM_HERE,
+      base::Bind(&SettingsFunction::Respond, this, base::Passed(&response)));
 }
 
 ExtensionFunction::ResponseValue SettingsFunction::UseReadResult(
diff --git a/extensions/browser/api/storage/storage_api.h b/extensions/browser/api/storage/storage_api.h
index 9f1091c..b4b97da 100644
--- a/extensions/browser/api/storage/storage_api.h
+++ b/extensions/browser/api/storage/storage_api.h
@@ -22,7 +22,7 @@
 
   // ExtensionFunction:
   virtual bool ShouldSkipQuotaLimiting() const OVERRIDE;
-  virtual ResponseAction RunImplTypesafe() OVERRIDE;
+  virtual ResponseAction Run() OVERRIDE;
 
   // Extension settings function implementations should do their work here.
   // The StorageFrontend makes sure this is posted to the appropriate thread.
@@ -48,7 +48,7 @@
                                ValueStore* storage);
 
  private:
-  // Called via PostTask from RunImplTypesafe. Calls RunWithStorage and then
+  // Called via PostTask from Run. Calls RunWithStorage and then
   // SendResponse with its success value.
   void AsyncRunWithStorage(ValueStore* storage);
 
diff --git a/extensions/browser/api/test/test_api.cc b/extensions/browser/api/test/test_api.cc
index b052946..87252b7 100644
--- a/extensions/browser/api/test/test_api.cc
+++ b/extensions/browser/api/test/test_api.cc
@@ -87,7 +87,7 @@
   return true;
 }
 
-bool TestSendMessageFunction::RunImpl() {
+bool TestSendMessageFunction::RunAsync() {
   scoped_ptr<PassMessage::Params> params(PassMessage::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
   content::NotificationService::current()->Notify(
diff --git a/extensions/browser/api/test/test_api.h b/extensions/browser/api/test/test_api.h
index 9511abf..ea5a639 100644
--- a/extensions/browser/api/test/test_api.h
+++ b/extensions/browser/api/test/test_api.h
@@ -81,7 +81,7 @@
   virtual ~TestSendMessageFunction();
 
   // ExtensionFunction:
-  virtual bool RunImpl() OVERRIDE;
+  virtual bool RunAsync() OVERRIDE;
 };
 
 class TestGetConfigFunction : public TestExtensionFunction {
diff --git a/chrome/browser/extensions/api/usb/DEPS b/extensions/browser/api/usb/DEPS
similarity index 100%
rename from chrome/browser/extensions/api/usb/DEPS
rename to extensions/browser/api/usb/DEPS
diff --git a/chrome/browser/extensions/api/usb/OWNERS b/extensions/browser/api/usb/OWNERS
similarity index 100%
rename from chrome/browser/extensions/api/usb/OWNERS
rename to extensions/browser/api/usb/OWNERS
diff --git a/extensions/browser/api/usb/usb_api.cc b/extensions/browser/api/usb/usb_api.cc
new file mode 100644
index 0000000..93ac6c1
--- /dev/null
+++ b/extensions/browser/api/usb/usb_api.cc
@@ -0,0 +1,1208 @@
+// 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.
+
+#include "extensions/browser/api/usb/usb_api.h"
+
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "components/usb_service/usb_device_handle.h"
+#include "components/usb_service/usb_service.h"
+#include "extensions/browser/api/usb/usb_device_resource.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/common/api/usb.h"
+#include "extensions/common/permissions/permissions_data.h"
+#include "extensions/common/permissions/usb_device_permission.h"
+
+namespace usb = extensions::core_api::usb;
+namespace BulkTransfer = usb::BulkTransfer;
+namespace ClaimInterface = usb::ClaimInterface;
+namespace CloseDevice = usb::CloseDevice;
+namespace ControlTransfer = usb::ControlTransfer;
+namespace FindDevices = usb::FindDevices;
+namespace GetDevices = usb::GetDevices;
+namespace InterruptTransfer = usb::InterruptTransfer;
+namespace IsochronousTransfer = usb::IsochronousTransfer;
+namespace ListInterfaces = usb::ListInterfaces;
+namespace OpenDevice = usb::OpenDevice;
+namespace ReleaseInterface = usb::ReleaseInterface;
+namespace RequestAccess = usb::RequestAccess;
+namespace ResetDevice = usb::ResetDevice;
+namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting;
+
+using content::BrowserThread;
+using std::string;
+using std::vector;
+using usb::ControlTransferInfo;
+using usb::ConnectionHandle;
+using usb::Device;
+using usb::Direction;
+using usb::EndpointDescriptor;
+using usb::GenericTransferInfo;
+using usb::InterfaceDescriptor;
+using usb::IsochronousTransferInfo;
+using usb::Recipient;
+using usb::RequestType;
+using usb::SynchronizationType;
+using usb::TransferType;
+using usb::UsageType;
+using usb_service::UsbConfigDescriptor;
+using usb_service::UsbDevice;
+using usb_service::UsbDeviceHandle;
+using usb_service::UsbEndpointDescriptor;
+using usb_service::UsbEndpointDirection;
+using usb_service::UsbInterfaceAltSettingDescriptor;
+using usb_service::UsbInterfaceDescriptor;
+using usb_service::UsbService;
+using usb_service::UsbSynchronizationType;
+using usb_service::UsbTransferStatus;
+using usb_service::UsbTransferType;
+using usb_service::UsbUsageType;
+
+typedef std::vector<scoped_refptr<UsbDevice> > DeviceVector;
+typedef scoped_ptr<DeviceVector> ScopedDeviceVector;
+
+namespace {
+
+const char kDataKey[] = "data";
+const char kResultCodeKey[] = "resultCode";
+
+const char kErrorInitService[] = "Failed to initialize USB service.";
+
+const char kErrorOpen[] = "Failed to open device.";
+const char kErrorCancelled[] = "Transfer was cancelled.";
+const char kErrorDisconnect[] = "Device disconnected.";
+const char kErrorGeneric[] = "Transfer failed.";
+#if !defined(OS_CHROMEOS)
+const char kErrorNotSupported[] = "Not supported on this platform.";
+#endif
+const char kErrorOverflow[] = "Inbound transfer overflow.";
+const char kErrorStalled[] = "Transfer stalled.";
+const char kErrorTimeout[] = "Transfer timed out.";
+const char kErrorTransferLength[] = "Transfer length is insufficient.";
+
+const char kErrorCannotListInterfaces[] = "Error listing interfaces.";
+const char kErrorCannotClaimInterface[] = "Error claiming interface.";
+const char kErrorCannotReleaseInterface[] = "Error releasing interface.";
+const char kErrorCannotSetInterfaceAlternateSetting[] =
+    "Error setting alternate interface setting.";
+const char kErrorConvertDirection[] = "Invalid transfer direction.";
+const char kErrorConvertRecipient[] = "Invalid transfer recipient.";
+const char kErrorConvertRequestType[] = "Invalid request type.";
+const char kErrorConvertSynchronizationType[] = "Invalid synchronization type";
+const char kErrorConvertTransferType[] = "Invalid endpoint type.";
+const char kErrorConvertUsageType[] = "Invalid usage type.";
+const char kErrorMalformedParameters[] = "Error parsing parameters.";
+const char kErrorNoDevice[] = "No such device.";
+const char kErrorPermissionDenied[] = "Permission to access device was denied";
+const char kErrorInvalidTransferLength[] =
+    "Transfer length must be a positive number less than 104,857,600.";
+const char kErrorInvalidNumberOfPackets[] =
+    "Number of packets must be a positive number less than 4,194,304.";
+const char kErrorInvalidPacketLength[] =
+    "Packet length must be a positive number less than 65,536.";
+const char kErrorResetDevice[] =
+    "Error resetting the device. The device has been closed.";
+
+const size_t kMaxTransferLength = 100 * 1024 * 1024;
+const int kMaxPackets = 4 * 1024 * 1024;
+const int kMaxPacketLength = 64 * 1024;
+
+bool ConvertDirectionToApi(const UsbEndpointDirection& input,
+                           Direction* output) {
+  switch (input) {
+    case usb_service::USB_DIRECTION_INBOUND:
+      *output = usb::DIRECTION_IN;
+      return true;
+    case usb_service::USB_DIRECTION_OUTBOUND:
+      *output = usb::DIRECTION_OUT;
+      return true;
+    default:
+      NOTREACHED();
+      return false;
+  }
+}
+
+bool ConvertSynchronizationTypeToApi(const UsbSynchronizationType& input,
+                                     usb::SynchronizationType* output) {
+  switch (input) {
+    case usb_service::USB_SYNCHRONIZATION_NONE:
+      *output = usb::SYNCHRONIZATION_TYPE_NONE;
+      return true;
+    case usb_service::USB_SYNCHRONIZATION_ASYNCHRONOUS:
+      *output = usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS;
+      return true;
+    case usb_service::USB_SYNCHRONIZATION_ADAPTIVE:
+      *output = usb::SYNCHRONIZATION_TYPE_ADAPTIVE;
+      return true;
+    case usb_service::USB_SYNCHRONIZATION_SYNCHRONOUS:
+      *output = usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS;
+      return true;
+    default:
+      NOTREACHED();
+      return false;
+  }
+}
+
+bool ConvertTransferTypeToApi(const UsbTransferType& input,
+                              usb::TransferType* output) {
+  switch (input) {
+    case usb_service::USB_TRANSFER_CONTROL:
+      *output = usb::TRANSFER_TYPE_CONTROL;
+      return true;
+    case usb_service::USB_TRANSFER_INTERRUPT:
+      *output = usb::TRANSFER_TYPE_INTERRUPT;
+      return true;
+    case usb_service::USB_TRANSFER_ISOCHRONOUS:
+      *output = usb::TRANSFER_TYPE_ISOCHRONOUS;
+      return true;
+    case usb_service::USB_TRANSFER_BULK:
+      *output = usb::TRANSFER_TYPE_BULK;
+      return true;
+    default:
+      NOTREACHED();
+      return false;
+  }
+}
+
+bool ConvertUsageTypeToApi(const UsbUsageType& input, usb::UsageType* output) {
+  switch (input) {
+    case usb_service::USB_USAGE_DATA:
+      *output = usb::USAGE_TYPE_DATA;
+      return true;
+    case usb_service::USB_USAGE_FEEDBACK:
+      *output = usb::USAGE_TYPE_FEEDBACK;
+      return true;
+    case usb_service::USB_USAGE_EXPLICIT_FEEDBACK:
+      *output = usb::USAGE_TYPE_EXPLICITFEEDBACK;
+      return true;
+    default:
+      NOTREACHED();
+      return false;
+  }
+}
+
+bool ConvertDirection(const Direction& input, UsbEndpointDirection* output) {
+  switch (input) {
+    case usb::DIRECTION_IN:
+      *output = usb_service::USB_DIRECTION_INBOUND;
+      return true;
+    case usb::DIRECTION_OUT:
+      *output = usb_service::USB_DIRECTION_OUTBOUND;
+      return true;
+    default:
+      NOTREACHED();
+      return false;
+  }
+}
+
+bool ConvertRequestType(const RequestType& input,
+                        UsbDeviceHandle::TransferRequestType* output) {
+  switch (input) {
+    case usb::REQUEST_TYPE_STANDARD:
+      *output = UsbDeviceHandle::STANDARD;
+      return true;
+    case usb::REQUEST_TYPE_CLASS:
+      *output = UsbDeviceHandle::CLASS;
+      return true;
+    case usb::REQUEST_TYPE_VENDOR:
+      *output = UsbDeviceHandle::VENDOR;
+      return true;
+    case usb::REQUEST_TYPE_RESERVED:
+      *output = UsbDeviceHandle::RESERVED;
+      return true;
+    default:
+      NOTREACHED();
+      return false;
+  }
+}
+
+bool ConvertRecipient(const Recipient& input,
+                      UsbDeviceHandle::TransferRecipient* output) {
+  switch (input) {
+    case usb::RECIPIENT_DEVICE:
+      *output = UsbDeviceHandle::DEVICE;
+      return true;
+    case usb::RECIPIENT_INTERFACE:
+      *output = UsbDeviceHandle::INTERFACE;
+      return true;
+    case usb::RECIPIENT_ENDPOINT:
+      *output = UsbDeviceHandle::ENDPOINT;
+      return true;
+    case usb::RECIPIENT_OTHER:
+      *output = UsbDeviceHandle::OTHER;
+      return true;
+    default:
+      NOTREACHED();
+      return false;
+  }
+}
+
+template <class T>
+bool GetTransferSize(const T& input, size_t* output) {
+  if (input.direction == usb::DIRECTION_IN) {
+    const int* length = input.length.get();
+    if (length && *length >= 0 &&
+        static_cast<size_t>(*length) < kMaxTransferLength) {
+      *output = *length;
+      return true;
+    }
+  } else if (input.direction == usb::DIRECTION_OUT) {
+    if (input.data.get()) {
+      *output = input.data->size();
+      return true;
+    }
+  }
+  return false;
+}
+
+template <class T>
+scoped_refptr<net::IOBuffer> CreateBufferForTransfer(
+    const T& input,
+    UsbEndpointDirection direction,
+    size_t size) {
+  if (size >= kMaxTransferLength)
+    return NULL;
+
+  // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This
+  // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer
+  // cannot represent a zero-length buffer, while an URB can.
+  scoped_refptr<net::IOBuffer> buffer =
+      new net::IOBuffer(std::max(static_cast<size_t>(1), size));
+
+  if (direction == usb_service::USB_DIRECTION_INBOUND) {
+    return buffer;
+  } else if (direction == usb_service::USB_DIRECTION_OUTBOUND) {
+    if (input.data.get() && size <= input.data->size()) {
+      memcpy(buffer->data(), input.data->data(), size);
+      return buffer;
+    }
+  }
+  NOTREACHED();
+  return NULL;
+}
+
+const char* ConvertTransferStatusToErrorString(const UsbTransferStatus status) {
+  switch (status) {
+    case usb_service::USB_TRANSFER_COMPLETED:
+      return "";
+    case usb_service::USB_TRANSFER_ERROR:
+      return kErrorGeneric;
+    case usb_service::USB_TRANSFER_TIMEOUT:
+      return kErrorTimeout;
+    case usb_service::USB_TRANSFER_CANCELLED:
+      return kErrorCancelled;
+    case usb_service::USB_TRANSFER_STALLED:
+      return kErrorStalled;
+    case usb_service::USB_TRANSFER_DISCONNECT:
+      return kErrorDisconnect;
+    case usb_service::USB_TRANSFER_OVERFLOW:
+      return kErrorOverflow;
+    case usb_service::USB_TRANSFER_LENGTH_SHORT:
+      return kErrorTransferLength;
+    default:
+      NOTREACHED();
+      return "";
+  }
+}
+
+#if defined(OS_CHROMEOS)
+void RequestUsbDevicesAccessHelper(
+    ScopedDeviceVector devices,
+    std::vector<scoped_refptr<UsbDevice> >::iterator i,
+    int interface_id,
+    const base::Callback<void(ScopedDeviceVector result)>& callback,
+    bool success) {
+  if (success) {
+    ++i;
+  } else {
+    i = devices->erase(i);
+  }
+  if (i == devices->end()) {
+    callback.Run(devices.Pass());
+    return;
+  }
+  (*i)->RequestUsbAcess(interface_id,
+                        base::Bind(RequestUsbDevicesAccessHelper,
+                                   base::Passed(devices.Pass()),
+                                   i,
+                                   interface_id,
+                                   callback));
+}
+
+void RequestUsbDevicesAccess(
+    ScopedDeviceVector devices,
+    int interface_id,
+    const base::Callback<void(ScopedDeviceVector result)>& callback) {
+  if (devices->empty()) {
+    callback.Run(devices.Pass());
+    return;
+  }
+  std::vector<scoped_refptr<UsbDevice> >::iterator i = devices->begin();
+  (*i)->RequestUsbAcess(interface_id,
+                        base::Bind(RequestUsbDevicesAccessHelper,
+                                   base::Passed(devices.Pass()),
+                                   i,
+                                   interface_id,
+                                   callback));
+}
+#endif  // OS_CHROMEOS
+
+base::DictionaryValue* CreateTransferInfo(UsbTransferStatus status,
+                                          scoped_refptr<net::IOBuffer> data,
+                                          size_t length) {
+  base::DictionaryValue* result = new base::DictionaryValue();
+  result->SetInteger(kResultCodeKey, status);
+  result->Set(kDataKey,
+              base::BinaryValue::CreateWithCopiedBuffer(data->data(), length));
+  return result;
+}
+
+base::Value* PopulateConnectionHandle(int handle,
+                                      int vendor_id,
+                                      int product_id) {
+  ConnectionHandle result;
+  result.handle = handle;
+  result.vendor_id = vendor_id;
+  result.product_id = product_id;
+  return result.ToValue().release();
+}
+
+base::Value* PopulateDevice(UsbDevice* device) {
+  Device result;
+  result.device = device->unique_id();
+  result.vendor_id = device->vendor_id();
+  result.product_id = device->product_id();
+  return result.ToValue().release();
+}
+
+base::Value* PopulateInterfaceDescriptor(
+    int interface_number,
+    int alternate_setting,
+    int interface_class,
+    int interface_subclass,
+    int interface_protocol,
+    std::vector<linked_ptr<EndpointDescriptor> >* endpoints) {
+  InterfaceDescriptor descriptor;
+  descriptor.interface_number = interface_number;
+  descriptor.alternate_setting = alternate_setting;
+  descriptor.interface_class = interface_class;
+  descriptor.interface_subclass = interface_subclass;
+  descriptor.interface_protocol = interface_protocol;
+  descriptor.endpoints = *endpoints;
+  return descriptor.ToValue().release();
+}
+
+}  // namespace
+
+namespace extensions {
+
+UsbAsyncApiFunction::UsbAsyncApiFunction() : manager_(NULL) {
+}
+
+UsbAsyncApiFunction::~UsbAsyncApiFunction() {
+}
+
+bool UsbAsyncApiFunction::PrePrepare() {
+  manager_ = ApiResourceManager<UsbDeviceResource>::Get(browser_context());
+  set_work_thread_id(BrowserThread::FILE);
+  return manager_ != NULL;
+}
+
+bool UsbAsyncApiFunction::Respond() {
+  return error_.empty();
+}
+
+scoped_refptr<UsbDevice> UsbAsyncApiFunction::GetDeviceOrOrCompleteWithError(
+    const Device& input_device) {
+  const uint16_t vendor_id = input_device.vendor_id;
+  const uint16_t product_id = input_device.product_id;
+  UsbDevicePermission::CheckParam param(
+      vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
+  if (!PermissionsData::CheckAPIPermissionWithParam(
+          GetExtension(), APIPermission::kUsbDevice, &param)) {
+    LOG(WARNING) << "Insufficient permissions to access device.";
+    CompleteWithError(kErrorPermissionDenied);
+    return NULL;
+  }
+
+  UsbService* service = UsbService::GetInstance();
+  if (!service) {
+    CompleteWithError(kErrorInitService);
+    return NULL;
+  }
+  scoped_refptr<UsbDevice> device;
+
+  device = service->GetDeviceById(input_device.device);
+
+  if (!device) {
+    CompleteWithError(kErrorNoDevice);
+    return NULL;
+  }
+
+  if (device->vendor_id() != input_device.vendor_id ||
+      device->product_id() != input_device.product_id) {
+    // Must act as if there is no such a device.
+    // Otherwise can be used to finger print unauthorized devices.
+    CompleteWithError(kErrorNoDevice);
+    return NULL;
+  }
+
+  return device;
+}
+
+scoped_refptr<UsbDeviceHandle>
+UsbAsyncApiFunction::GetDeviceHandleOrCompleteWithError(
+    const ConnectionHandle& input_device_handle) {
+  UsbDeviceResource* resource =
+      manager_->Get(extension_->id(), input_device_handle.handle);
+  if (!resource) {
+    CompleteWithError(kErrorNoDevice);
+    return NULL;
+  }
+
+  if (!resource->device() || !resource->device()->device()) {
+    CompleteWithError(kErrorDisconnect);
+    manager_->Remove(extension_->id(), input_device_handle.handle);
+    return NULL;
+  }
+
+  if (resource->device()->device()->vendor_id() !=
+          input_device_handle.vendor_id ||
+      resource->device()->device()->product_id() !=
+          input_device_handle.product_id) {
+    CompleteWithError(kErrorNoDevice);
+    return NULL;
+  }
+
+  return resource->device();
+}
+
+void UsbAsyncApiFunction::RemoveUsbDeviceResource(int api_resource_id) {
+  manager_->Remove(extension_->id(), api_resource_id);
+}
+
+void UsbAsyncApiFunction::CompleteWithError(const std::string& error) {
+  SetError(error);
+  AsyncWorkCompleted();
+}
+
+UsbAsyncApiTransferFunction::UsbAsyncApiTransferFunction() {
+}
+
+UsbAsyncApiTransferFunction::~UsbAsyncApiTransferFunction() {
+}
+
+void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status,
+                                              scoped_refptr<net::IOBuffer> data,
+                                              size_t length) {
+  if (status != usb_service::USB_TRANSFER_COMPLETED)
+    SetError(ConvertTransferStatusToErrorString(status));
+
+  SetResult(CreateTransferInfo(status, data, length));
+  AsyncWorkCompleted();
+}
+
+bool UsbAsyncApiTransferFunction::ConvertDirectionSafely(
+    const Direction& input,
+    UsbEndpointDirection* output) {
+  const bool converted = ConvertDirection(input, output);
+  if (!converted)
+    SetError(kErrorConvertDirection);
+  return converted;
+}
+
+bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely(
+    const RequestType& input,
+    UsbDeviceHandle::TransferRequestType* output) {
+  const bool converted = ConvertRequestType(input, output);
+  if (!converted)
+    SetError(kErrorConvertRequestType);
+  return converted;
+}
+
+bool UsbAsyncApiTransferFunction::ConvertRecipientSafely(
+    const Recipient& input,
+    UsbDeviceHandle::TransferRecipient* output) {
+  const bool converted = ConvertRecipient(input, output);
+  if (!converted)
+    SetError(kErrorConvertRecipient);
+  return converted;
+}
+
+UsbFindDevicesFunction::UsbFindDevicesFunction() {
+}
+
+UsbFindDevicesFunction::~UsbFindDevicesFunction() {
+}
+
+bool UsbFindDevicesFunction::Prepare() {
+  parameters_ = FindDevices::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbFindDevicesFunction::AsyncWorkStart() {
+  scoped_ptr<base::ListValue> result(new base::ListValue());
+  const uint16_t vendor_id = parameters_->options.vendor_id;
+  const uint16_t product_id = parameters_->options.product_id;
+  int interface_id = parameters_->options.interface_id.get()
+                         ? *parameters_->options.interface_id.get()
+                         : UsbDevicePermissionData::ANY_INTERFACE;
+  UsbDevicePermission::CheckParam param(vendor_id, product_id, interface_id);
+  if (!PermissionsData::CheckAPIPermissionWithParam(
+          GetExtension(), APIPermission::kUsbDevice, &param)) {
+    LOG(WARNING) << "Insufficient permissions to access device.";
+    CompleteWithError(kErrorPermissionDenied);
+    return;
+  }
+
+  UsbService* service = UsbService::GetInstance();
+  if (!service) {
+    CompleteWithError(kErrorInitService);
+    return;
+  }
+
+  ScopedDeviceVector devices(new DeviceVector());
+  service->GetDevices(devices.get());
+
+  for (DeviceVector::iterator it = devices->begin(); it != devices->end();) {
+    if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) {
+      it = devices->erase(it);
+    } else {
+      ++it;
+    }
+  }
+
+#if defined(OS_CHROMEOS)
+  RequestUsbDevicesAccess(
+      devices.Pass(),
+      interface_id,
+      base::Bind(&UsbFindDevicesFunction::OpenDevices, this));
+#else
+  OpenDevices(devices.Pass());
+#endif  // OS_CHROMEOS
+}
+
+void UsbFindDevicesFunction::OpenDevices(ScopedDeviceVector devices) {
+  base::ListValue* result = new base::ListValue();
+
+  for (size_t i = 0; i < devices->size(); ++i) {
+    scoped_refptr<UsbDeviceHandle> device_handle = devices->at(i)->Open();
+    if (device_handle)
+      device_handles_.push_back(device_handle);
+  }
+
+  for (size_t i = 0; i < device_handles_.size(); ++i) {
+    UsbDeviceHandle* const device_handle = device_handles_[i].get();
+    UsbDeviceResource* const resource =
+        new UsbDeviceResource(extension_->id(), device_handle);
+
+    result->Append(PopulateConnectionHandle(manager_->Add(resource),
+                                            parameters_->options.vendor_id,
+                                            parameters_->options.product_id));
+  }
+
+  SetResult(result);
+  AsyncWorkCompleted();
+}
+
+UsbGetDevicesFunction::UsbGetDevicesFunction() {
+}
+
+UsbGetDevicesFunction::~UsbGetDevicesFunction() {
+}
+
+bool UsbGetDevicesFunction::Prepare() {
+  parameters_ = GetDevices::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbGetDevicesFunction::AsyncWorkStart() {
+  scoped_ptr<base::ListValue> result(new base::ListValue());
+
+  const uint16_t vendor_id = parameters_->options.vendor_id;
+  const uint16_t product_id = parameters_->options.product_id;
+  UsbDevicePermission::CheckParam param(
+      vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
+  if (!PermissionsData::CheckAPIPermissionWithParam(
+          GetExtension(), APIPermission::kUsbDevice, &param)) {
+    LOG(WARNING) << "Insufficient permissions to access device.";
+    CompleteWithError(kErrorPermissionDenied);
+    return;
+  }
+
+  UsbService* service = UsbService::GetInstance();
+  if (!service) {
+    CompleteWithError(kErrorInitService);
+    return;
+  }
+
+  DeviceVector devices;
+  service->GetDevices(&devices);
+
+  for (DeviceVector::iterator it = devices.begin(); it != devices.end();) {
+    if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) {
+      it = devices.erase(it);
+    } else {
+      ++it;
+    }
+  }
+
+  for (size_t i = 0; i < devices.size(); ++i) {
+    result->Append(PopulateDevice(devices[i].get()));
+  }
+
+  SetResult(result.release());
+  AsyncWorkCompleted();
+}
+
+UsbRequestAccessFunction::UsbRequestAccessFunction() {
+}
+
+UsbRequestAccessFunction::~UsbRequestAccessFunction() {
+}
+
+bool UsbRequestAccessFunction::Prepare() {
+  parameters_ = RequestAccess::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbRequestAccessFunction::AsyncWorkStart() {
+#if defined(OS_CHROMEOS)
+  scoped_refptr<UsbDevice> device =
+      GetDeviceOrOrCompleteWithError(parameters_->device);
+  if (!device)
+    return;
+
+  device->RequestUsbAcess(
+      parameters_->interface_id,
+      base::Bind(&UsbRequestAccessFunction::OnCompleted, this));
+#else
+  SetResult(new base::FundamentalValue(false));
+  CompleteWithError(kErrorNotSupported);
+#endif  // OS_CHROMEOS
+}
+
+void UsbRequestAccessFunction::OnCompleted(bool success) {
+  SetResult(new base::FundamentalValue(success));
+  AsyncWorkCompleted();
+}
+
+UsbOpenDeviceFunction::UsbOpenDeviceFunction() {
+}
+
+UsbOpenDeviceFunction::~UsbOpenDeviceFunction() {
+}
+
+bool UsbOpenDeviceFunction::Prepare() {
+  parameters_ = OpenDevice::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbOpenDeviceFunction::AsyncWorkStart() {
+  scoped_refptr<UsbDevice> device =
+      GetDeviceOrOrCompleteWithError(parameters_->device);
+  if (!device)
+    return;
+
+  handle_ = device->Open();
+  if (!handle_) {
+    SetError(kErrorOpen);
+    AsyncWorkCompleted();
+    return;
+  }
+
+  SetResult(PopulateConnectionHandle(
+      manager_->Add(new UsbDeviceResource(extension_->id(), handle_)),
+      handle_->device()->vendor_id(),
+      handle_->device()->product_id()));
+  AsyncWorkCompleted();
+}
+
+UsbListInterfacesFunction::UsbListInterfacesFunction() {
+}
+
+UsbListInterfacesFunction::~UsbListInterfacesFunction() {
+}
+
+bool UsbListInterfacesFunction::Prepare() {
+  parameters_ = ListInterfaces::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbListInterfacesFunction::AsyncWorkStart() {
+  scoped_refptr<UsbDeviceHandle> device_handle =
+      GetDeviceHandleOrCompleteWithError(parameters_->handle);
+  if (!device_handle)
+    return;
+
+  scoped_refptr<UsbConfigDescriptor> config =
+      device_handle->device()->ListInterfaces();
+
+  if (!config) {
+    SetError(kErrorCannotListInterfaces);
+    AsyncWorkCompleted();
+    return;
+  }
+
+  result_.reset(new base::ListValue());
+
+  for (size_t i = 0, num_interfaces = config->GetNumInterfaces();
+       i < num_interfaces;
+       ++i) {
+    scoped_refptr<const UsbInterfaceDescriptor> usb_interface(
+        config->GetInterface(i));
+    for (size_t j = 0, num_descriptors = usb_interface->GetNumAltSettings();
+         j < num_descriptors;
+         ++j) {
+      scoped_refptr<const UsbInterfaceAltSettingDescriptor> descriptor =
+          usb_interface->GetAltSetting(j);
+      std::vector<linked_ptr<EndpointDescriptor> > endpoints;
+      for (size_t k = 0, num_endpoints = descriptor->GetNumEndpoints();
+           k < num_endpoints;
+           k++) {
+        scoped_refptr<const UsbEndpointDescriptor> endpoint =
+            descriptor->GetEndpoint(k);
+        linked_ptr<EndpointDescriptor> endpoint_desc(new EndpointDescriptor());
+
+        TransferType type;
+        Direction direction;
+        SynchronizationType synchronization;
+        UsageType usage;
+
+        if (!ConvertTransferTypeSafely(endpoint->GetTransferType(), &type) ||
+            !ConvertDirectionSafely(endpoint->GetDirection(), &direction) ||
+            !ConvertSynchronizationTypeSafely(
+                endpoint->GetSynchronizationType(), &synchronization) ||
+            !ConvertUsageTypeSafely(endpoint->GetUsageType(), &usage)) {
+          SetError(kErrorCannotListInterfaces);
+          AsyncWorkCompleted();
+          return;
+        }
+
+        endpoint_desc->address = endpoint->GetAddress();
+        endpoint_desc->type = type;
+        endpoint_desc->direction = direction;
+        endpoint_desc->maximum_packet_size = endpoint->GetMaximumPacketSize();
+        endpoint_desc->synchronization = synchronization;
+        endpoint_desc->usage = usage;
+
+        int* polling_interval = new int;
+        endpoint_desc->polling_interval.reset(polling_interval);
+        *polling_interval = endpoint->GetPollingInterval();
+
+        endpoints.push_back(endpoint_desc);
+      }
+
+      result_->Append(
+          PopulateInterfaceDescriptor(descriptor->GetInterfaceNumber(),
+                                      descriptor->GetAlternateSetting(),
+                                      descriptor->GetInterfaceClass(),
+                                      descriptor->GetInterfaceSubclass(),
+                                      descriptor->GetInterfaceProtocol(),
+                                      &endpoints));
+    }
+  }
+
+  SetResult(result_.release());
+  AsyncWorkCompleted();
+}
+
+bool UsbListInterfacesFunction::ConvertDirectionSafely(
+    const UsbEndpointDirection& input,
+    usb::Direction* output) {
+  const bool converted = ConvertDirectionToApi(input, output);
+  if (!converted)
+    SetError(kErrorConvertDirection);
+  return converted;
+}
+
+bool UsbListInterfacesFunction::ConvertSynchronizationTypeSafely(
+    const UsbSynchronizationType& input,
+    usb::SynchronizationType* output) {
+  const bool converted = ConvertSynchronizationTypeToApi(input, output);
+  if (!converted)
+    SetError(kErrorConvertSynchronizationType);
+  return converted;
+}
+
+bool UsbListInterfacesFunction::ConvertTransferTypeSafely(
+    const UsbTransferType& input,
+    usb::TransferType* output) {
+  const bool converted = ConvertTransferTypeToApi(input, output);
+  if (!converted)
+    SetError(kErrorConvertTransferType);
+  return converted;
+}
+
+bool UsbListInterfacesFunction::ConvertUsageTypeSafely(
+    const UsbUsageType& input,
+    usb::UsageType* output) {
+  const bool converted = ConvertUsageTypeToApi(input, output);
+  if (!converted)
+    SetError(kErrorConvertUsageType);
+  return converted;
+}
+
+UsbCloseDeviceFunction::UsbCloseDeviceFunction() {
+}
+
+UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {
+}
+
+bool UsbCloseDeviceFunction::Prepare() {
+  parameters_ = CloseDevice::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbCloseDeviceFunction::AsyncWorkStart() {
+  scoped_refptr<UsbDeviceHandle> device_handle =
+      GetDeviceHandleOrCompleteWithError(parameters_->handle);
+  if (!device_handle)
+    return;
+
+  device_handle->Close();
+  RemoveUsbDeviceResource(parameters_->handle.handle);
+  AsyncWorkCompleted();
+}
+
+UsbClaimInterfaceFunction::UsbClaimInterfaceFunction() {
+}
+
+UsbClaimInterfaceFunction::~UsbClaimInterfaceFunction() {
+}
+
+bool UsbClaimInterfaceFunction::Prepare() {
+  parameters_ = ClaimInterface::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbClaimInterfaceFunction::AsyncWorkStart() {
+  scoped_refptr<UsbDeviceHandle> device_handle =
+      GetDeviceHandleOrCompleteWithError(parameters_->handle);
+  if (!device_handle)
+    return;
+
+  bool success = device_handle->ClaimInterface(parameters_->interface_number);
+
+  if (!success)
+    SetError(kErrorCannotClaimInterface);
+  AsyncWorkCompleted();
+}
+
+UsbReleaseInterfaceFunction::UsbReleaseInterfaceFunction() {
+}
+
+UsbReleaseInterfaceFunction::~UsbReleaseInterfaceFunction() {
+}
+
+bool UsbReleaseInterfaceFunction::Prepare() {
+  parameters_ = ReleaseInterface::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbReleaseInterfaceFunction::AsyncWorkStart() {
+  scoped_refptr<UsbDeviceHandle> device_handle =
+      GetDeviceHandleOrCompleteWithError(parameters_->handle);
+  if (!device_handle)
+    return;
+
+  bool success = device_handle->ReleaseInterface(parameters_->interface_number);
+  if (!success)
+    SetError(kErrorCannotReleaseInterface);
+  AsyncWorkCompleted();
+}
+
+UsbSetInterfaceAlternateSettingFunction::
+    UsbSetInterfaceAlternateSettingFunction() {
+}
+
+UsbSetInterfaceAlternateSettingFunction::
+    ~UsbSetInterfaceAlternateSettingFunction() {
+}
+
+bool UsbSetInterfaceAlternateSettingFunction::Prepare() {
+  parameters_ = SetInterfaceAlternateSetting::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbSetInterfaceAlternateSettingFunction::AsyncWorkStart() {
+  scoped_refptr<UsbDeviceHandle> device_handle =
+      GetDeviceHandleOrCompleteWithError(parameters_->handle);
+  if (!device_handle)
+    return;
+
+  bool success = device_handle->SetInterfaceAlternateSetting(
+      parameters_->interface_number, parameters_->alternate_setting);
+  if (!success)
+    SetError(kErrorCannotSetInterfaceAlternateSetting);
+
+  AsyncWorkCompleted();
+}
+
+UsbControlTransferFunction::UsbControlTransferFunction() {
+}
+
+UsbControlTransferFunction::~UsbControlTransferFunction() {
+}
+
+bool UsbControlTransferFunction::Prepare() {
+  parameters_ = ControlTransfer::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbControlTransferFunction::AsyncWorkStart() {
+  scoped_refptr<UsbDeviceHandle> device_handle =
+      GetDeviceHandleOrCompleteWithError(parameters_->handle);
+  if (!device_handle)
+    return;
+
+  const ControlTransferInfo& transfer = parameters_->transfer_info;
+
+  UsbEndpointDirection direction;
+  UsbDeviceHandle::TransferRequestType request_type;
+  UsbDeviceHandle::TransferRecipient recipient;
+  size_t size = 0;
+
+  if (!ConvertDirectionSafely(transfer.direction, &direction) ||
+      !ConvertRequestTypeSafely(transfer.request_type, &request_type) ||
+      !ConvertRecipientSafely(transfer.recipient, &recipient)) {
+    AsyncWorkCompleted();
+    return;
+  }
+
+  if (!GetTransferSize(transfer, &size)) {
+    CompleteWithError(kErrorInvalidTransferLength);
+    return;
+  }
+
+  scoped_refptr<net::IOBuffer> buffer =
+      CreateBufferForTransfer(transfer, direction, size);
+  if (!buffer.get()) {
+    CompleteWithError(kErrorMalformedParameters);
+    return;
+  }
+
+  device_handle->ControlTransfer(
+      direction,
+      request_type,
+      recipient,
+      transfer.request,
+      transfer.value,
+      transfer.index,
+      buffer.get(),
+      size,
+      0,
+      base::Bind(&UsbControlTransferFunction::OnCompleted, this));
+}
+
+UsbBulkTransferFunction::UsbBulkTransferFunction() {
+}
+
+UsbBulkTransferFunction::~UsbBulkTransferFunction() {
+}
+
+bool UsbBulkTransferFunction::Prepare() {
+  parameters_ = BulkTransfer::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbBulkTransferFunction::AsyncWorkStart() {
+  scoped_refptr<UsbDeviceHandle> device_handle =
+      GetDeviceHandleOrCompleteWithError(parameters_->handle);
+  if (!device_handle)
+    return;
+
+  const GenericTransferInfo& transfer = parameters_->transfer_info;
+
+  UsbEndpointDirection direction;
+  size_t size = 0;
+
+  if (!ConvertDirectionSafely(transfer.direction, &direction)) {
+    AsyncWorkCompleted();
+    return;
+  }
+
+  if (!GetTransferSize(transfer, &size)) {
+    CompleteWithError(kErrorInvalidTransferLength);
+    return;
+  }
+
+  scoped_refptr<net::IOBuffer> buffer =
+      CreateBufferForTransfer(transfer, direction, size);
+  if (!buffer.get()) {
+    CompleteWithError(kErrorMalformedParameters);
+    return;
+  }
+
+  device_handle->BulkTransfer(
+      direction,
+      transfer.endpoint,
+      buffer.get(),
+      size,
+      0,
+      base::Bind(&UsbBulkTransferFunction::OnCompleted, this));
+}
+
+UsbInterruptTransferFunction::UsbInterruptTransferFunction() {
+}
+
+UsbInterruptTransferFunction::~UsbInterruptTransferFunction() {
+}
+
+bool UsbInterruptTransferFunction::Prepare() {
+  parameters_ = InterruptTransfer::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbInterruptTransferFunction::AsyncWorkStart() {
+  scoped_refptr<UsbDeviceHandle> device_handle =
+      GetDeviceHandleOrCompleteWithError(parameters_->handle);
+  if (!device_handle)
+    return;
+
+  const GenericTransferInfo& transfer = parameters_->transfer_info;
+
+  UsbEndpointDirection direction;
+  size_t size = 0;
+
+  if (!ConvertDirectionSafely(transfer.direction, &direction)) {
+    AsyncWorkCompleted();
+    return;
+  }
+
+  if (!GetTransferSize(transfer, &size)) {
+    CompleteWithError(kErrorInvalidTransferLength);
+    return;
+  }
+
+  scoped_refptr<net::IOBuffer> buffer =
+      CreateBufferForTransfer(transfer, direction, size);
+  if (!buffer.get()) {
+    CompleteWithError(kErrorMalformedParameters);
+    return;
+  }
+
+  device_handle->InterruptTransfer(
+      direction,
+      transfer.endpoint,
+      buffer.get(),
+      size,
+      0,
+      base::Bind(&UsbInterruptTransferFunction::OnCompleted, this));
+}
+
+UsbIsochronousTransferFunction::UsbIsochronousTransferFunction() {
+}
+
+UsbIsochronousTransferFunction::~UsbIsochronousTransferFunction() {
+}
+
+bool UsbIsochronousTransferFunction::Prepare() {
+  parameters_ = IsochronousTransfer::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbIsochronousTransferFunction::AsyncWorkStart() {
+  scoped_refptr<UsbDeviceHandle> device_handle =
+      GetDeviceHandleOrCompleteWithError(parameters_->handle);
+  if (!device_handle)
+    return;
+
+  const IsochronousTransferInfo& transfer = parameters_->transfer_info;
+  const GenericTransferInfo& generic_transfer = transfer.transfer_info;
+
+  size_t size = 0;
+  UsbEndpointDirection direction;
+
+  if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) {
+    AsyncWorkCompleted();
+    return;
+  }
+  if (!GetTransferSize(generic_transfer, &size)) {
+    CompleteWithError(kErrorInvalidTransferLength);
+    return;
+  }
+  if (transfer.packets < 0 || transfer.packets >= kMaxPackets) {
+    CompleteWithError(kErrorInvalidNumberOfPackets);
+    return;
+  }
+  unsigned int packets = transfer.packets;
+  if (transfer.packet_length < 0 ||
+      transfer.packet_length >= kMaxPacketLength) {
+    CompleteWithError(kErrorInvalidPacketLength);
+    return;
+  }
+  unsigned int packet_length = transfer.packet_length;
+  const uint64 total_length = packets * packet_length;
+  if (packets > size || total_length > size) {
+    CompleteWithError(kErrorTransferLength);
+    return;
+  }
+
+  scoped_refptr<net::IOBuffer> buffer =
+      CreateBufferForTransfer(generic_transfer, direction, size);
+  if (!buffer.get()) {
+    CompleteWithError(kErrorMalformedParameters);
+    return;
+  }
+
+  device_handle->IsochronousTransfer(
+      direction,
+      generic_transfer.endpoint,
+      buffer.get(),
+      size,
+      packets,
+      packet_length,
+      0,
+      base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this));
+}
+
+UsbResetDeviceFunction::UsbResetDeviceFunction() {
+}
+
+UsbResetDeviceFunction::~UsbResetDeviceFunction() {
+}
+
+bool UsbResetDeviceFunction::Prepare() {
+  parameters_ = ResetDevice::Params::Create(*args_);
+  EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+  return true;
+}
+
+void UsbResetDeviceFunction::AsyncWorkStart() {
+  scoped_refptr<UsbDeviceHandle> device_handle =
+      GetDeviceHandleOrCompleteWithError(parameters_->handle);
+  if (!device_handle)
+    return;
+
+  bool success = device_handle->ResetDevice();
+  if (!success) {
+    device_handle->Close();
+    RemoveUsbDeviceResource(parameters_->handle.handle);
+    SetResult(new base::FundamentalValue(false));
+    CompleteWithError(kErrorResetDevice);
+    return;
+  }
+
+  SetResult(new base::FundamentalValue(true));
+  AsyncWorkCompleted();
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/api/usb/usb_api.h b/extensions/browser/api/usb/usb_api.h
new file mode 100644
index 0000000..3dd0d2b
--- /dev/null
+++ b/extensions/browser/api/usb/usb_api.h
@@ -0,0 +1,317 @@
+// 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.
+
+#ifndef EXTENSIONS_BROWSER_API_USB_USB_API_H_
+#define EXTENSIONS_BROWSER_API_USB_USB_API_H_
+
+#include <string>
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/usb_service/usb_device.h"
+#include "components/usb_service/usb_device_handle.h"
+#include "extensions/browser/api/api_resource_manager.h"
+#include "extensions/browser/api/async_api_function.h"
+#include "extensions/common/api/usb.h"
+#include "net/base/io_buffer.h"
+
+namespace extensions {
+
+class UsbDeviceResource;
+
+class UsbAsyncApiFunction : public AsyncApiFunction {
+ public:
+  UsbAsyncApiFunction();
+
+ protected:
+  virtual ~UsbAsyncApiFunction();
+
+  virtual bool PrePrepare() OVERRIDE;
+  virtual bool Respond() OVERRIDE;
+
+  scoped_refptr<usb_service::UsbDevice> GetDeviceOrOrCompleteWithError(
+      const extensions::core_api::usb::Device& input_device);
+
+  scoped_refptr<usb_service::UsbDeviceHandle>
+      GetDeviceHandleOrCompleteWithError(
+          const extensions::core_api::usb::ConnectionHandle&
+              input_device_handle);
+
+  void RemoveUsbDeviceResource(int api_resource_id);
+
+  void CompleteWithError(const std::string& error);
+
+  ApiResourceManager<UsbDeviceResource>* manager_;
+};
+
+class UsbAsyncApiTransferFunction : public UsbAsyncApiFunction {
+ protected:
+  UsbAsyncApiTransferFunction();
+  virtual ~UsbAsyncApiTransferFunction();
+
+  bool ConvertDirectionSafely(const extensions::core_api::usb::Direction& input,
+                              usb_service::UsbEndpointDirection* output);
+  bool ConvertRequestTypeSafely(
+      const extensions::core_api::usb::RequestType& input,
+      usb_service::UsbDeviceHandle::TransferRequestType* output);
+  bool ConvertRecipientSafely(
+      const extensions::core_api::usb::Recipient& input,
+      usb_service::UsbDeviceHandle::TransferRecipient* output);
+
+  void OnCompleted(usb_service::UsbTransferStatus status,
+                   scoped_refptr<net::IOBuffer> data,
+                   size_t length);
+};
+
+class UsbFindDevicesFunction : public UsbAsyncApiFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.findDevices", USB_FINDDEVICES)
+
+  UsbFindDevicesFunction();
+
+ protected:
+  virtual ~UsbFindDevicesFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+  void OpenDevices(
+      scoped_ptr<std::vector<scoped_refptr<usb_service::UsbDevice> > > devices);
+
+  std::vector<scoped_refptr<usb_service::UsbDeviceHandle> > device_handles_;
+  scoped_ptr<extensions::core_api::usb::FindDevices::Params> parameters_;
+};
+
+class UsbGetDevicesFunction : public UsbAsyncApiFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.getDevices", USB_GETDEVICES)
+
+  UsbGetDevicesFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ protected:
+  virtual ~UsbGetDevicesFunction();
+
+ private:
+  void EnumerationCompletedFileThread(
+      scoped_ptr<std::vector<scoped_refptr<usb_service::UsbDevice> > > devices);
+
+  scoped_ptr<extensions::core_api::usb::GetDevices::Params> parameters_;
+};
+
+class UsbRequestAccessFunction : public UsbAsyncApiFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.requestAccess", USB_REQUESTACCESS)
+
+  UsbRequestAccessFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ protected:
+  virtual ~UsbRequestAccessFunction();
+
+  void OnCompleted(bool success);
+
+ private:
+  scoped_ptr<extensions::core_api::usb::RequestAccess::Params> parameters_;
+};
+
+class UsbOpenDeviceFunction : public UsbAsyncApiFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.openDevice", USB_OPENDEVICE)
+
+  UsbOpenDeviceFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ protected:
+  virtual ~UsbOpenDeviceFunction();
+
+ private:
+  scoped_refptr<usb_service::UsbDeviceHandle> handle_;
+  scoped_ptr<extensions::core_api::usb::OpenDevice::Params> parameters_;
+};
+
+class UsbListInterfacesFunction : public UsbAsyncApiFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.listInterfaces", USB_LISTINTERFACES)
+
+  UsbListInterfacesFunction();
+
+ protected:
+  virtual ~UsbListInterfacesFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+  bool ConvertDirectionSafely(const usb_service::UsbEndpointDirection& input,
+                              extensions::core_api::usb::Direction* output);
+  bool ConvertSynchronizationTypeSafely(
+      const usb_service::UsbSynchronizationType& input,
+      extensions::core_api::usb::SynchronizationType* output);
+  bool ConvertTransferTypeSafely(
+      const usb_service::UsbTransferType& input,
+      extensions::core_api::usb::TransferType* output);
+  bool ConvertUsageTypeSafely(const usb_service::UsbUsageType& input,
+                              extensions::core_api::usb::UsageType* output);
+
+  scoped_ptr<base::ListValue> result_;
+  scoped_ptr<extensions::core_api::usb::ListInterfaces::Params> parameters_;
+};
+
+class UsbCloseDeviceFunction : public UsbAsyncApiFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.closeDevice", USB_CLOSEDEVICE)
+
+  UsbCloseDeviceFunction();
+
+ protected:
+  virtual ~UsbCloseDeviceFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+  scoped_ptr<extensions::core_api::usb::CloseDevice::Params> parameters_;
+};
+
+class UsbClaimInterfaceFunction : public UsbAsyncApiFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.claimInterface", USB_CLAIMINTERFACE)
+
+  UsbClaimInterfaceFunction();
+
+ protected:
+  virtual ~UsbClaimInterfaceFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+  scoped_ptr<extensions::core_api::usb::ClaimInterface::Params> parameters_;
+};
+
+class UsbReleaseInterfaceFunction : public UsbAsyncApiFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.releaseInterface", USB_RELEASEINTERFACE)
+
+  UsbReleaseInterfaceFunction();
+
+ protected:
+  virtual ~UsbReleaseInterfaceFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+  scoped_ptr<extensions::core_api::usb::ReleaseInterface::Params> parameters_;
+};
+
+class UsbSetInterfaceAlternateSettingFunction : public UsbAsyncApiFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.setInterfaceAlternateSetting",
+                             USB_SETINTERFACEALTERNATESETTING)
+
+  UsbSetInterfaceAlternateSettingFunction();
+
+ private:
+  virtual ~UsbSetInterfaceAlternateSettingFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+  scoped_ptr<extensions::core_api::usb::SetInterfaceAlternateSetting::Params>
+      parameters_;
+};
+
+class UsbControlTransferFunction : public UsbAsyncApiTransferFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.controlTransfer", USB_CONTROLTRANSFER)
+
+  UsbControlTransferFunction();
+
+ protected:
+  virtual ~UsbControlTransferFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+  scoped_ptr<extensions::core_api::usb::ControlTransfer::Params> parameters_;
+};
+
+class UsbBulkTransferFunction : public UsbAsyncApiTransferFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.bulkTransfer", USB_BULKTRANSFER)
+
+  UsbBulkTransferFunction();
+
+ protected:
+  virtual ~UsbBulkTransferFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+  scoped_ptr<extensions::core_api::usb::BulkTransfer::Params> parameters_;
+};
+
+class UsbInterruptTransferFunction : public UsbAsyncApiTransferFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.interruptTransfer", USB_INTERRUPTTRANSFER)
+
+  UsbInterruptTransferFunction();
+
+ protected:
+  virtual ~UsbInterruptTransferFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+  scoped_ptr<extensions::core_api::usb::InterruptTransfer::Params> parameters_;
+};
+
+class UsbIsochronousTransferFunction : public UsbAsyncApiTransferFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.isochronousTransfer", USB_ISOCHRONOUSTRANSFER)
+
+  UsbIsochronousTransferFunction();
+
+ protected:
+  virtual ~UsbIsochronousTransferFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+  scoped_ptr<extensions::core_api::usb::IsochronousTransfer::Params>
+      parameters_;
+};
+
+class UsbResetDeviceFunction : public UsbAsyncApiFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION("usb.resetDevice", USB_RESETDEVICE)
+
+  UsbResetDeviceFunction();
+
+ protected:
+  virtual ~UsbResetDeviceFunction();
+
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+ private:
+  scoped_ptr<extensions::core_api::usb::ResetDevice::Params> parameters_;
+};
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_API_USB_USB_API_H_
diff --git a/extensions/browser/api/usb/usb_apitest.cc b/extensions/browser/api/usb/usb_apitest.cc
new file mode 100644
index 0000000..335258d
--- /dev/null
+++ b/extensions/browser/api/usb/usb_apitest.cc
@@ -0,0 +1,275 @@
+// 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.
+
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/ui/browser.h"
+#include "components/usb_service/usb_service.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/test/test_utils.h"
+#include "extensions/browser/api/usb/usb_api.h"
+#include "net/base/io_buffer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::AnyNumber;
+using testing::_;
+using testing::Return;
+using content::BrowserThread;
+using usb_service::UsbConfigDescriptor;
+using usb_service::UsbDevice;
+using usb_service::UsbDeviceHandle;
+using usb_service::UsbEndpointDirection;
+using usb_service::UsbService;
+using usb_service::UsbTransferCallback;
+
+namespace {
+
+ACTION_TEMPLATE(InvokeUsbTransferCallback,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_1_VALUE_PARAMS(p1)) {
+  ::std::tr1::get<k>(args).Run(p1, new net::IOBuffer(1), 1);
+}
+
+// MSVC erroneously thinks that at least one of the arguments for the transfer
+// methods differ by const or volatility and emits a warning about the old
+// standards-noncompliant behaviour of their compiler.
+#if defined(OS_WIN)
+#pragma warning(push)
+#pragma warning(disable : 4373)
+#endif
+
+class MockUsbDeviceHandle : public UsbDeviceHandle {
+ public:
+  MockUsbDeviceHandle() : UsbDeviceHandle() {}
+
+  MOCK_METHOD0(Close, void());
+
+  MOCK_METHOD10(ControlTransfer,
+                void(const UsbEndpointDirection direction,
+                     const TransferRequestType request_type,
+                     const TransferRecipient recipient,
+                     const uint8 request,
+                     const uint16 value,
+                     const uint16 index,
+                     net::IOBuffer* buffer,
+                     const size_t length,
+                     const unsigned int timeout,
+                     const UsbTransferCallback& callback));
+
+  MOCK_METHOD6(BulkTransfer,
+               void(const UsbEndpointDirection direction,
+                    const uint8 endpoint,
+                    net::IOBuffer* buffer,
+                    const size_t length,
+                    const unsigned int timeout,
+                    const UsbTransferCallback& callback));
+
+  MOCK_METHOD6(InterruptTransfer,
+               void(const UsbEndpointDirection direction,
+                    const uint8 endpoint,
+                    net::IOBuffer* buffer,
+                    const size_t length,
+                    const unsigned int timeout,
+                    const UsbTransferCallback& callback));
+
+  MOCK_METHOD8(IsochronousTransfer,
+               void(const UsbEndpointDirection direction,
+                    const uint8 endpoint,
+                    net::IOBuffer* buffer,
+                    const size_t length,
+                    const unsigned int packets,
+                    const unsigned int packet_length,
+                    const unsigned int timeout,
+                    const UsbTransferCallback& callback));
+
+  MOCK_METHOD0(ResetDevice, bool());
+
+  void set_device(UsbDevice* device) { device_ = device; }
+
+ protected:
+  virtual ~MockUsbDeviceHandle() {}
+};
+
+class MockUsbConfigDescriptor : public UsbConfigDescriptor {
+ public:
+  MOCK_CONST_METHOD0(GetNumInterfaces, size_t());
+
+ protected:
+  virtual ~MockUsbConfigDescriptor() {}
+};
+
+class MockUsbDevice : public UsbDevice {
+ public:
+  explicit MockUsbDevice(MockUsbDeviceHandle* mock_handle)
+      : UsbDevice(0, 0, 0), mock_handle_(mock_handle) {
+    mock_handle->set_device(this);
+  }
+
+  virtual scoped_refptr<UsbDeviceHandle> Open() OVERRIDE {
+    return mock_handle_;
+  }
+
+  virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) OVERRIDE {
+    EXPECT_TRUE(false) << "Should not be reached";
+    return false;
+  }
+
+#if defined(OS_CHROMEOS)
+  virtual void RequestUsbAcess(
+      int interface_id,
+      const base::Callback<void(bool success)>& callback) OVERRIDE {
+    BrowserThread::PostTask(
+          BrowserThread::FILE, FROM_HERE, base::Bind(callback, true));
+  }
+#endif  // OS_CHROMEOS
+
+  MOCK_METHOD0(ListInterfaces, scoped_refptr<UsbConfigDescriptor>());
+
+ private:
+  MockUsbDeviceHandle* mock_handle_;
+  virtual ~MockUsbDevice() {}
+};
+
+class MockUsbService : public UsbService {
+ public:
+  explicit MockUsbService(scoped_refptr<UsbDevice> device) : device_(device) {}
+
+ protected:
+  virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) OVERRIDE {
+    EXPECT_EQ(unique_id, 0U);
+    return device_;
+  }
+
+  virtual void GetDevices(
+      std::vector<scoped_refptr<UsbDevice> >* devices) OVERRIDE {
+    STLClearObject(devices);
+    devices->push_back(device_);
+  }
+
+  scoped_refptr<UsbDevice> device_;
+};
+
+#if defined(OS_WIN)
+#pragma warning(pop)
+#endif
+
+class UsbApiTest : public ExtensionApiTest {
+ public:
+  virtual void SetUpOnMainThread() OVERRIDE {
+    mock_device_handle_ = new MockUsbDeviceHandle();
+    mock_device_ = new MockUsbDevice(mock_device_handle_.get());
+    scoped_refptr<content::MessageLoopRunner> runner =
+        new content::MessageLoopRunner;
+    BrowserThread::PostTaskAndReply(BrowserThread::FILE,
+                                    FROM_HERE,
+                                    base::Bind(&UsbApiTest::SetUpService, this),
+                                    runner->QuitClosure());
+    runner->Run();
+  }
+
+  void SetUpService() {
+    UsbService::SetInstanceForTest(new MockUsbService(mock_device_));
+  }
+
+  virtual void CleanUpOnMainThread() OVERRIDE {
+    scoped_refptr<content::MessageLoopRunner> runner =
+        new content::MessageLoopRunner;
+    UsbService* service = NULL;
+    BrowserThread::PostTaskAndReply(
+        BrowserThread::FILE,
+        FROM_HERE,
+        base::Bind(&UsbService::SetInstanceForTest, service),
+        runner->QuitClosure());
+    runner->Run();
+  }
+
+ protected:
+  scoped_refptr<MockUsbDeviceHandle> mock_device_handle_;
+  scoped_refptr<MockUsbDevice> mock_device_;
+};
+
+}  // namespace
+
+IN_PROC_BROWSER_TEST_F(UsbApiTest, DeviceHandling) {
+  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(4);
+  ASSERT_TRUE(RunExtensionTest("usb/device_handling"));
+}
+
+IN_PROC_BROWSER_TEST_F(UsbApiTest, ResetDevice) {
+  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(2);
+  EXPECT_CALL(*mock_device_handle_.get(), ResetDevice())
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  EXPECT_CALL(
+      *mock_device_handle_.get(),
+      InterruptTransfer(usb_service::USB_DIRECTION_OUTBOUND, 2, _, 1, _, _))
+      .WillOnce(
+          InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_COMPLETED));
+  ASSERT_TRUE(RunExtensionTest("usb/reset_device"));
+}
+
+IN_PROC_BROWSER_TEST_F(UsbApiTest, ListInterfaces) {
+  scoped_refptr<MockUsbConfigDescriptor> mock_descriptor =
+      new MockUsbConfigDescriptor();
+  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
+  EXPECT_CALL(*mock_descriptor.get(), GetNumInterfaces()).WillOnce(Return(0));
+  EXPECT_CALL(*mock_device_.get(), ListInterfaces())
+      .WillOnce(Return(mock_descriptor));
+  ASSERT_TRUE(RunExtensionTest("usb/list_interfaces"));
+}
+
+IN_PROC_BROWSER_TEST_F(UsbApiTest, TransferEvent) {
+  EXPECT_CALL(*mock_device_handle_.get(),
+              ControlTransfer(usb_service::USB_DIRECTION_OUTBOUND,
+                              UsbDeviceHandle::STANDARD,
+                              UsbDeviceHandle::DEVICE,
+                              1,
+                              2,
+                              3,
+                              _,
+                              1,
+                              _,
+                              _))
+      .WillOnce(
+          InvokeUsbTransferCallback<9>(usb_service::USB_TRANSFER_COMPLETED));
+  EXPECT_CALL(*mock_device_handle_.get(),
+              BulkTransfer(usb_service::USB_DIRECTION_OUTBOUND, 1, _, 1, _, _))
+      .WillOnce(
+          InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_COMPLETED));
+  EXPECT_CALL(
+      *mock_device_handle_.get(),
+      InterruptTransfer(usb_service::USB_DIRECTION_OUTBOUND, 2, _, 1, _, _))
+      .WillOnce(
+          InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_COMPLETED));
+  EXPECT_CALL(*mock_device_handle_.get(),
+              IsochronousTransfer(
+                  usb_service::USB_DIRECTION_OUTBOUND, 3, _, 1, 1, 1, _, _))
+      .WillOnce(
+          InvokeUsbTransferCallback<7>(usb_service::USB_TRANSFER_COMPLETED));
+  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
+  ASSERT_TRUE(RunExtensionTest("usb/transfer_event"));
+}
+
+IN_PROC_BROWSER_TEST_F(UsbApiTest, ZeroLengthTransfer) {
+  EXPECT_CALL(*mock_device_handle_.get(), BulkTransfer(_, _, _, 0, _, _))
+      .WillOnce(
+          InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_COMPLETED));
+  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
+  ASSERT_TRUE(RunExtensionTest("usb/zero_length_transfer"));
+}
+
+IN_PROC_BROWSER_TEST_F(UsbApiTest, TransferFailure) {
+  EXPECT_CALL(*mock_device_handle_.get(), BulkTransfer(_, _, _, _, _, _))
+      .WillOnce(
+           InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_COMPLETED))
+      .WillOnce(InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_ERROR))
+      .WillOnce(
+          InvokeUsbTransferCallback<5>(usb_service::USB_TRANSFER_TIMEOUT));
+  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
+  ASSERT_TRUE(RunExtensionTest("usb/transfer_failure"));
+}
+
+IN_PROC_BROWSER_TEST_F(UsbApiTest, InvalidLengthTransfer) {
+  EXPECT_CALL(*mock_device_handle_.get(), Close()).Times(AnyNumber());
+  ASSERT_TRUE(RunExtensionTest("usb/invalid_length_transfer"));
+}
diff --git a/extensions/browser/api/usb/usb_device_resource.cc b/extensions/browser/api/usb/usb_device_resource.cc
new file mode 100644
index 0000000..030de7b
--- /dev/null
+++ b/extensions/browser/api/usb/usb_device_resource.cc
@@ -0,0 +1,45 @@
+// 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.
+
+#include "extensions/browser/api/usb/usb_device_resource.h"
+
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/synchronization/lock.h"
+#include "components/usb_service/usb_device_handle.h"
+#include "content/public/browser/browser_thread.h"
+#include "extensions/browser/api/api_resource.h"
+#include "extensions/common/api/usb.h"
+
+using content::BrowserThread;
+using usb_service::UsbDeviceHandle;
+
+namespace extensions {
+
+static base::LazyInstance<
+    BrowserContextKeyedAPIFactory<ApiResourceManager<UsbDeviceResource> > >
+    g_factory = LAZY_INSTANCE_INITIALIZER;
+
+// static
+template <>
+BrowserContextKeyedAPIFactory<ApiResourceManager<UsbDeviceResource> >*
+ApiResourceManager<UsbDeviceResource>::GetFactoryInstance() {
+  return g_factory.Pointer();
+}
+
+UsbDeviceResource::UsbDeviceResource(const std::string& owner_extension_id,
+                                     scoped_refptr<UsbDeviceHandle> device)
+    : ApiResource(owner_extension_id), device_(device) {
+}
+
+UsbDeviceResource::~UsbDeviceResource() {
+  BrowserThread::PostTask(BrowserThread::FILE,
+                          FROM_HERE,
+                          base::Bind(&UsbDeviceHandle::Close, device_));
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/api/usb/usb_device_resource.h b/extensions/browser/api/usb/usb_device_resource.h
new file mode 100644
index 0000000..cb6cbbe
--- /dev/null
+++ b/extensions/browser/api/usb/usb_device_resource.h
@@ -0,0 +1,50 @@
+// 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.
+
+#ifndef EXTENSIONS_BROWSER_API_USB_USB_DEVICE_RESOURCE_H_
+#define EXTENSIONS_BROWSER_API_USB_USB_DEVICE_RESOURCE_H_
+
+#include <set>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/linked_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/lock.h"
+#include "components/usb_service/usb_device_handle.h"
+#include "content/public/browser/browser_thread.h"
+#include "extensions/browser/api/api_resource.h"
+#include "extensions/browser/api/api_resource_manager.h"
+#include "extensions/common/api/usb.h"
+
+namespace net {
+class IOBuffer;
+}  // namespace net
+
+namespace extensions {
+
+// A UsbDeviceResource is an ApiResource wrapper for a UsbDevice.
+class UsbDeviceResource : public ApiResource {
+ public:
+  UsbDeviceResource(const std::string& owner_extension_id,
+                    scoped_refptr<usb_service::UsbDeviceHandle> device);
+  virtual ~UsbDeviceResource();
+
+  scoped_refptr<usb_service::UsbDeviceHandle> device() { return device_; }
+
+  static const content::BrowserThread::ID kThreadId =
+      content::BrowserThread::FILE;
+
+ private:
+  friend class ApiResourceManager<UsbDeviceResource>;
+  static const char* service_name() { return "UsbDeviceResourceManager"; }
+
+  scoped_refptr<usb_service::UsbDeviceHandle> device_;
+
+  DISALLOW_COPY_AND_ASSIGN(UsbDeviceResource);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_API_USB_USB_DEVICE_RESOURCE_H_
diff --git a/extensions/browser/api/usb/usb_manual_apitest.cc b/extensions/browser/api/usb/usb_manual_apitest.cc
new file mode 100644
index 0000000..d28be9d
--- /dev/null
+++ b/extensions/browser/api/usb/usb_manual_apitest.cc
@@ -0,0 +1,18 @@
+// 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.
+
+#include "chrome/browser/extensions/api/permissions/permissions_api.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+
+namespace {
+
+class UsbManualApiTest : public ExtensionApiTest {};
+
+}  // namespace
+
+IN_PROC_BROWSER_TEST_F(UsbManualApiTest, MANUAL_ListInterfaces) {
+  extensions::PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
+  extensions::PermissionsRequestFunction::SetAutoConfirmForTests(true);
+  ASSERT_TRUE(RunExtensionTest("usb_manual/list_interfaces"));
+}
diff --git a/extensions/browser/browser_context_keyed_service_factories.cc b/extensions/browser/browser_context_keyed_service_factories.cc
index 38ee253..6091a0f 100644
--- a/extensions/browser/browser_context_keyed_service_factories.cc
+++ b/extensions/browser/browser_context_keyed_service_factories.cc
@@ -5,6 +5,7 @@
 #include "extensions/browser/browser_context_keyed_service_factories.h"
 
 #include "extensions/browser/api/api_resource_manager.h"
+#include "extensions/browser/api/runtime/runtime_api.h"
 #include "extensions/browser/api/socket/socket.h"
 #include "extensions/browser/api/socket/tcp_socket.h"
 #include "extensions/browser/api/socket/udp_socket.h"
@@ -26,9 +27,10 @@
   core_api::TCPServerSocketEventDispatcher::GetFactoryInstance();
   core_api::TCPSocketEventDispatcher::GetFactoryInstance();
   core_api::UDPSocketEventDispatcher::GetFactoryInstance();
-  extensions::ExtensionPrefsFactory::GetInstance();
-  extensions::RendererStartupHelperFactory::GetInstance();
-  extensions::StorageFrontend::GetFactoryInstance();
+  ExtensionPrefsFactory::GetInstance();
+  RendererStartupHelperFactory::GetInstance();
+  RuntimeAPI::GetFactoryInstance();
+  StorageFrontend::GetFactoryInstance();
 }
 
 }  // namespace extensions
diff --git a/extensions/browser/content_verifier.cc b/extensions/browser/content_verifier.cc
new file mode 100644
index 0000000..879ee25
--- /dev/null
+++ b/extensions/browser/content_verifier.cc
@@ -0,0 +1,125 @@
+// 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.
+
+#include "extensions/browser/content_verifier.h"
+
+#include <algorithm>
+
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/metrics/field_trial.h"
+#include "content/public/browser/browser_thread.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/common/switches.h"
+
+namespace {
+
+const char kExperimentName[] = "ExtensionContentVerification";
+
+}  // namespace
+
+namespace extensions {
+
+ContentVerifier::ContentVerifier(content::BrowserContext* context,
+                                 const ContentVerifierFilter& filter)
+    : mode_(GetMode()),
+      filter_(filter),
+      context_(context),
+      observers_(new ObserverListThreadSafe<ContentVerifierObserver>) {
+}
+
+ContentVerifier::~ContentVerifier() {
+}
+
+void ContentVerifier::Start() {
+}
+
+void ContentVerifier::Shutdown() {
+  filter_.Reset();
+}
+
+ContentVerifyJob* ContentVerifier::CreateJobFor(
+    const std::string& extension_id,
+    const base::FilePath& extension_root,
+    const base::FilePath& relative_path) {
+  if (filter_.is_null())
+    return NULL;
+
+  ExtensionRegistry* registry = ExtensionRegistry::Get(context_);
+  const Extension* extension =
+      registry->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
+
+  if (!extension || !filter_.Run(extension))
+    return NULL;
+
+  return new ContentVerifyJob(
+      extension_id,
+      base::Bind(&ContentVerifier::VerifyFailed, this, extension->id()));
+}
+
+void ContentVerifier::VerifyFailed(const std::string& extension_id,
+                                   ContentVerifyJob::FailureReason reason) {
+  if (mode_ < ENFORCE)
+    return;
+
+  if (reason == ContentVerifyJob::NO_HASHES && mode_ < ENFORCE_STRICT) {
+    content::BrowserThread::PostTask(
+        content::BrowserThread::UI,
+        FROM_HERE,
+        base::Bind(&ContentVerifier::RequestFetch, this, extension_id));
+    return;
+  }
+
+  // The magic of ObserverListThreadSafe will make sure that observers get
+  // called on the same threads that they called AddObserver on.
+  observers_->Notify(&ContentVerifierObserver::ContentVerifyFailed,
+                     extension_id);
+}
+
+void ContentVerifier::AddObserver(ContentVerifierObserver* observer) {
+  observers_->AddObserver(observer);
+}
+
+void ContentVerifier::RemoveObserver(ContentVerifierObserver* observer) {
+  observers_->RemoveObserver(observer);
+}
+
+void ContentVerifier::RequestFetch(const std::string& extension_id) {
+}
+
+// static
+ContentVerifier::Mode ContentVerifier::GetMode() {
+  Mode experiment_value = NONE;
+  const std::string group = base::FieldTrialList::FindFullName(kExperimentName);
+  if (group == "EnforceStrict")
+    experiment_value = ENFORCE_STRICT;
+  else if (group == "Enforce")
+    experiment_value = ENFORCE;
+  else if (group == "Bootstrap")
+    experiment_value = BOOTSTRAP;
+
+  Mode cmdline_value = NONE;
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kExtensionContentVerification)) {
+    std::string switch_value = command_line->GetSwitchValueASCII(
+        switches::kExtensionContentVerification);
+    if (switch_value == switches::kExtensionContentVerificationBootstrap)
+      cmdline_value = BOOTSTRAP;
+    else if (switch_value == switches::kExtensionContentVerificationEnforce)
+      cmdline_value = ENFORCE;
+    else if (switch_value ==
+             switches::kExtensionContentVerificationEnforceStrict)
+      cmdline_value = ENFORCE_STRICT;
+    else
+      // If no value was provided (or the wrong one), just default to enforce.
+      cmdline_value = ENFORCE;
+  }
+
+  // We don't want to allow the command-line flags to eg disable enforcement if
+  // the experiment group says it should be on, or malware may just modify the
+  // command line flags. So return the more restrictive of the 2 values.
+  return std::max(experiment_value, cmdline_value);
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/content_verifier.h b/extensions/browser/content_verifier.h
new file mode 100644
index 0000000..edce70a
--- /dev/null
+++ b/extensions/browser/content_verifier.h
@@ -0,0 +1,103 @@
+// 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.
+
+#ifndef EXTENSIONS_BROWSER_CONTENT_VERIFIER_H_
+#define EXTENSIONS_BROWSER_CONTENT_VERIFIER_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/observer_list_threadsafe.h"
+#include "extensions/browser/content_verifier_filter.h"
+#include "extensions/browser/content_verify_job.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace content {
+class BrowserContext;
+}
+
+namespace extensions {
+
+// Interface for clients of ContentVerifier.
+class ContentVerifierObserver {
+ public:
+  // Called when the content verifier detects that a read of a file inside
+  // an extension did not match its expected hash.
+  virtual void ContentVerifyFailed(const std::string& extension_id) = 0;
+};
+
+// Used for managing overall content verification - both fetching content
+// hashes as needed, and supplying job objects to verify file contents as they
+// are read.
+class ContentVerifier : public base::RefCountedThreadSafe<ContentVerifier> {
+ public:
+  ContentVerifier(content::BrowserContext* context,
+                  const ContentVerifierFilter& filter);
+  void Start();
+  void Shutdown();
+
+  // Call this before reading a file within an extension. The caller owns the
+  // returned job.
+  ContentVerifyJob* CreateJobFor(const std::string& extension_id,
+                                 const base::FilePath& extension_root,
+                                 const base::FilePath& relative_path);
+
+  // Called (typically by a verification job) to indicate that verification
+  // failed while reading some file in |extension_id|.
+  void VerifyFailed(const std::string& extension_id,
+                    ContentVerifyJob::FailureReason reason);
+
+  // Observers will be called back on the same thread that they call
+  // AddObserver on.
+  void AddObserver(ContentVerifierObserver* observer);
+  void RemoveObserver(ContentVerifierObserver* observer);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ContentVerifier);
+
+  friend class base::RefCountedThreadSafe<ContentVerifier>;
+  virtual ~ContentVerifier();
+
+  // Attempts to fetch content hashes for |extension_id|.
+  void RequestFetch(const std::string& extension_id);
+
+  // Note that it is important for these to appear in increasing "severity"
+  // order, because we use this to let command line flags increase, but not
+  // decrease, the mode you're running in compared to the experiment group.
+  enum Mode {
+    // Do not try to fetch content hashes if they are missing, and do not
+    // enforce them if they are present.
+    NONE = 0,
+
+    // If content hashes are missing, try to fetch them, but do not enforce.
+    BOOTSTRAP,
+
+    // If hashes are present, enforce them. If they are missing, try to fetch
+    // them.
+    ENFORCE,
+
+    // Treat the absence of hashes the same as a verification failure.
+    ENFORCE_STRICT
+  };
+
+  static Mode GetMode();
+
+  // The mode we're running in - set once at creation.
+  const Mode mode_;
+
+  // The filter we use to decide whether to return a ContentVerifyJob.
+  ContentVerifierFilter filter_;
+
+  // The associated BrowserContext.
+  content::BrowserContext* context_;
+
+  // The set of objects interested in verification failures.
+  scoped_refptr<ObserverListThreadSafe<ContentVerifierObserver> > observers_;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_CONTENT_VERIFIER_H_
diff --git a/extensions/browser/content_verifier_filter.h b/extensions/browser/content_verifier_filter.h
new file mode 100644
index 0000000..6327d1f
--- /dev/null
+++ b/extensions/browser/content_verifier_filter.h
@@ -0,0 +1,23 @@
+// 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.
+
+#ifndef EXTENSIONS_BROWSER_CONTENT_VERIFIER_FILTER_H_
+#define EXTENSIONS_BROWSER_CONTENT_VERIFIER_FILTER_H_
+
+#include "base/bind.h"
+#include "base/callback.h"
+
+namespace extensions {
+
+class Extension;
+
+// A callback function for deciding if a given extension should have it's
+// content verified or not. Returning true means "yes, it should be verified".
+//
+// This function should be prepared to be called on any thread.
+typedef base::Callback<bool(const Extension*)> ContentVerifierFilter;
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_CONTENT_VERIFIER_FILTER_H_
diff --git a/extensions/browser/content_verify_job.cc b/extensions/browser/content_verify_job.cc
new file mode 100644
index 0000000..399f363
--- /dev/null
+++ b/extensions/browser/content_verify_job.cc
@@ -0,0 +1,69 @@
+// 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.
+
+#include "extensions/browser/content_verify_job.h"
+
+#include <algorithm>
+
+#include "base/stl_util.h"
+#include "base/task_runner_util.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace extensions {
+
+namespace {
+
+ContentVerifyJob::TestDelegate* g_test_delegate = NULL;
+
+}  // namespace
+
+ContentVerifyJob::ContentVerifyJob(const std::string& extension_id,
+                                   const FailureCallback& failure_callback)
+    : extension_id_(extension_id), failure_callback_(failure_callback) {
+  // It's ok for this object to be constructed on a different thread from where
+  // it's used.
+  thread_checker_.DetachFromThread();
+}
+
+ContentVerifyJob::~ContentVerifyJob() {
+}
+
+void ContentVerifyJob::Start() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+}
+
+void ContentVerifyJob::BytesRead(int count, const char* data) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (g_test_delegate) {
+    FailureReason reason =
+        g_test_delegate->BytesRead(extension_id_, count, data);
+    if (reason != NONE)
+      return DispatchFailureCallback(reason);
+  }
+}
+
+void ContentVerifyJob::DoneReading() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (g_test_delegate) {
+    FailureReason reason = g_test_delegate->DoneReading(extension_id_);
+    if (reason != NONE) {
+      DispatchFailureCallback(reason);
+      return;
+    }
+  }
+}
+
+// static
+void ContentVerifyJob::SetDelegateForTests(TestDelegate* delegate) {
+  g_test_delegate = delegate;
+}
+
+void ContentVerifyJob::DispatchFailureCallback(FailureReason reason) {
+  if (!failure_callback_.is_null()) {
+    failure_callback_.Run(reason);
+    failure_callback_.Reset();
+  }
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/content_verify_job.h b/extensions/browser/content_verify_job.h
new file mode 100644
index 0000000..ff75b8c
--- /dev/null
+++ b/extensions/browser/content_verify_job.h
@@ -0,0 +1,97 @@
+// 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.
+
+#ifndef EXTENSIONS_BROWSER_CONTENT_VERIFY_JOB_H_
+#define EXTENSIONS_BROWSER_CONTENT_VERIFY_JOB_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread_checker.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace extensions {
+
+class ContentHashReader;
+
+// Objects of this class are responsible for verifying that the actual content
+// read from an extension file matches an expected set of hashes. This class
+// can be created on any thread but the rest of the methods should be called
+// from only one thread.
+class ContentVerifyJob : public base::RefCountedThreadSafe<ContentVerifyJob> {
+ public:
+  enum FailureReason {
+    // No failure.
+    NONE,
+
+    // Failed because there were no expected hashes.
+    NO_HASHES,
+
+    // Some of the content read did not match the expected hash.
+    HASH_MISMATCH
+  };
+  typedef base::Callback<void(FailureReason)> FailureCallback;
+
+  // The |failure_callback| will be called at most once if there was a failure.
+  //
+  // IMPORTANT NOTE: this class is still a stub right now - in the future this
+  // constructor will also be passed information to let it lookup expected
+  // block hashes for the file being read.
+  ContentVerifyJob(const std::string& extension_id,
+                   const FailureCallback& failure_callback);
+
+  // This begins the process of getting expected hashes, so it should be called
+  // as early as possible.
+  void Start();
+
+  // Call this to add more bytes to verify. If at any point the read bytes
+  // don't match the expected hashes, this will dispatch the failure
+  // callback. The failure callback will only be run once even if more bytes
+  // are read. Make sure to call DoneReading so that any final bytes that were
+  // read that didn't align exactly on a block size boundary get their hash
+  // checked as well.
+  void BytesRead(int count, const char* data);
+
+  // Call once when finished adding bytes via BytesRead.
+  void DoneReading();
+
+  class TestDelegate {
+   public:
+    // These methods will be called inside BytesRead/DoneReading respectively.
+    // If either return something other than NONE, then the failure callback
+    // will be dispatched with that reason.
+    virtual FailureReason BytesRead(const std::string& extension_id,
+                                    int count,
+                                    const char* data) = 0;
+    virtual FailureReason DoneReading(const std::string& extension_id) = 0;
+  };
+
+  static void SetDelegateForTests(TestDelegate* delegate);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ContentVerifyJob);
+
+  virtual ~ContentVerifyJob();
+  friend class base::RefCountedThreadSafe<ContentVerifyJob>;
+
+  void DispatchFailureCallback(FailureReason reason);
+
+  // The id of the extension for the file being verified.
+  std::string extension_id_;
+
+  // Called once if verification fails.
+  FailureCallback failure_callback_;
+
+  // For ensuring methods on called on the right thread.
+  base::ThreadChecker thread_checker_;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_CONTENT_VERIFY_JOB_H_
diff --git a/extensions/browser/event_listener_map.cc b/extensions/browser/event_listener_map.cc
index 1c9fba4..5d90e98 100644
--- a/extensions/browser/event_listener_map.cc
+++ b/extensions/browser/event_listener_map.cc
@@ -5,6 +5,7 @@
 #include "extensions/browser/event_listener_map.h"
 
 #include "base/values.h"
+#include "content/public/browser/render_process_host.h"
 #include "extensions/browser/event_router.h"
 #include "ipc/ipc_message.h"
 
@@ -18,11 +19,12 @@
                              const std::string& extension_id,
                              content::RenderProcessHost* process,
                              scoped_ptr<DictionaryValue> filter)
-    : event_name(event_name),
-      extension_id(extension_id),
-      process(process),
-      filter(filter.Pass()),
-      matcher_id(-1) {}
+    : event_name_(event_name),
+      extension_id_(extension_id),
+      process_(process),
+      filter_(filter.Pass()),
+      matcher_id_(-1) {
+}
 
 EventListener::~EventListener() {}
 
@@ -30,20 +32,30 @@
   // We don't check matcher_id equality because we want a listener with a
   // filter that hasn't been added to EventFilter to match one that is
   // equivalent but has.
-  return event_name == other->event_name &&
-      extension_id == other->extension_id &&
-      process == other->process &&
-      ((!!filter.get()) == (!!other->filter.get())) &&
-      (!filter.get() || filter->Equals(other->filter.get()));
+  return event_name_ == other->event_name_ &&
+         extension_id_ == other->extension_id_ && process_ == other->process_ &&
+         ((!!filter_.get()) == (!!other->filter_.get())) &&
+         (!filter_.get() || filter_->Equals(other->filter_.get()));
 }
 
 scoped_ptr<EventListener> EventListener::Copy() const {
   scoped_ptr<DictionaryValue> filter_copy;
-  if (filter)
-    filter_copy.reset(filter->DeepCopy());
-  return scoped_ptr<EventListener>(new EventListener(event_name, extension_id,
-                                                     process,
-                                                     filter_copy.Pass()));
+  if (filter_)
+    filter_copy.reset(filter_->DeepCopy());
+  return scoped_ptr<EventListener>(new EventListener(
+      event_name_, extension_id_, process_, filter_copy.Pass()));
+}
+
+bool EventListener::IsLazy() const {
+  return !process_;
+}
+
+void EventListener::MakeLazy() {
+  process_ = NULL;
+}
+
+content::BrowserContext* EventListener::GetBrowserContext() const {
+  return process_ ? process_->GetBrowserContext() : NULL;
 }
 
 EventListenerMap::EventListenerMap(Delegate* delegate)
@@ -55,16 +67,16 @@
 bool EventListenerMap::AddListener(scoped_ptr<EventListener> listener) {
   if (HasListener(listener.get()))
     return false;
-  if (listener->filter) {
-    scoped_ptr<EventMatcher> matcher(ParseEventMatcher(listener->filter.get()));
-    MatcherID id = event_filter_.AddEventMatcher(listener->event_name,
-                                                 matcher.Pass());
-    listener->matcher_id = id;
+  if (listener->filter()) {
+    scoped_ptr<EventMatcher> matcher(ParseEventMatcher(listener->filter()));
+    MatcherID id =
+        event_filter_.AddEventMatcher(listener->event_name(), matcher.Pass());
+    listener->set_matcher_id(id);
     listeners_by_matcher_id_[id] = listener.get();
-    filtered_events_.insert(listener->event_name);
+    filtered_events_.insert(listener->event_name());
   }
   linked_ptr<EventListener> listener_ptr(listener.release());
-  listeners_[listener_ptr->event_name].push_back(listener_ptr);
+  listeners_[listener_ptr->event_name()].push_back(listener_ptr);
 
   delegate_->OnListenerAdded(listener_ptr.get());
 
@@ -78,7 +90,7 @@
 }
 
 bool EventListenerMap::RemoveListener(const EventListener* listener) {
-  ListenerList& listeners = listeners_[listener->event_name];
+  ListenerList& listeners = listeners_[listener->event_name()];
   for (ListenerList::iterator it = listeners.begin(); it != listeners.end();
        it++) {
     if ((*it)->Equals(listener)) {
@@ -107,14 +119,14 @@
 
   for (ListenerList::iterator it2 = it->second.begin();
        it2 != it->second.end(); it2++) {
-    if ((*it2)->extension_id == extension_id)
+    if ((*it2)->extension_id() == extension_id)
       return true;
   }
   return false;
 }
 
 bool EventListenerMap::HasListener(const EventListener* listener) {
-  ListenerMap::iterator it = listeners_.find(listener->event_name);
+  ListenerMap::iterator it = listeners_.find(listener->event_name());
   if (it == listeners_.end())
     return false;
   for (ListenerList::iterator it2 = it->second.begin();
@@ -132,7 +144,8 @@
        it++) {
     for (ListenerList::iterator it2 = it->second.begin();
          it2 != it->second.end(); it2++) {
-      if ((*it2)->process == process && (*it2)->extension_id == extension_id)
+      if ((*it2)->process() == process &&
+          (*it2)->extension_id() == extension_id)
         return true;
     }
   }
@@ -145,7 +158,7 @@
        it++) {
     for (ListenerList::iterator it2 = it->second.begin();
          it2 != it->second.end();) {
-      if (!(*it2)->process && (*it2)->extension_id == extension_id) {
+      if ((*it2)->IsLazy() && (*it2)->extension_id() == extension_id) {
         CleanupListener(it2->get());
         it2 = it->second.erase(it2);
       } else {
@@ -216,7 +229,7 @@
        it++) {
     for (ListenerList::iterator it2 = it->second.begin();
          it2 != it->second.end();) {
-      if ((*it2)->process == process) {
+      if ((*it2)->process() == process) {
         linked_ptr<EventListener> listener(*it2);
         CleanupListener(it2->get());
         it2 = it->second.erase(it2);
@@ -230,10 +243,10 @@
 
 void EventListenerMap::CleanupListener(EventListener* listener) {
   // If the listener doesn't have a filter then we have nothing to clean up.
-  if (listener->matcher_id == -1)
+  if (listener->matcher_id() == -1)
     return;
-  event_filter_.RemoveEventMatcher(listener->matcher_id);
-  CHECK_EQ(1u, listeners_by_matcher_id_.erase(listener->matcher_id));
+  event_filter_.RemoveEventMatcher(listener->matcher_id());
+  CHECK_EQ(1u, listeners_by_matcher_id_.erase(listener->matcher_id()));
 }
 
 bool EventListenerMap::IsFilteredEvent(const Event& event) const {
diff --git a/extensions/browser/event_listener_map.h b/extensions/browser/event_listener_map.h
index 71aa192..163fc8f 100644
--- a/extensions/browser/event_listener_map.h
+++ b/extensions/browser/event_listener_map.h
@@ -18,6 +18,7 @@
 }
 
 namespace content {
+class BrowserContext;
 class RenderProcessHost;
 }
 
@@ -27,15 +28,18 @@
 struct Event;
 
 // A listener for an extension event. A listener is essentially an endpoint
-// that an event can be dispatched to. This is a lazy listener if |process| is
-// NULL and a filtered listener if |filter| is defined.
+// that an event can be dispatched to.
+//
+// This is a lazy listener if |IsLazy| is returns true, and a filtered listener
+// if |filter| is defined.
 //
 // A lazy listener is added to an event to indicate that a lazy background page
 // is listening to the event. It is associated with no process, so to dispatch
 // an event to a lazy listener one must start a process running the associated
 // extension and dispatch the event to that.
 //
-struct EventListener {
+class EventListener {
+ public:
   // |filter| represents a generic filter structure that EventFilter knows how
   // to filter events with. A typical filter instance will look like
   //
@@ -53,13 +57,30 @@
 
   scoped_ptr<EventListener> Copy() const;
 
-  const std::string event_name;
-  const std::string extension_id;
-  content::RenderProcessHost* process;
-  scoped_ptr<base::DictionaryValue> filter;
-  EventFilter::MatcherID matcher_id;
+  // Returns true in the case of a lazy background page, and thus no process.
+  bool IsLazy() const;
+
+  // Modifies this listener to be a lazy listener, clearing process references.
+  void MakeLazy();
+
+  // Returns the browser context associated with the listener, or NULL if
+  // IsLazy.
+  content::BrowserContext* GetBrowserContext() const;
+
+  const std::string event_name() const { return event_name_; }
+  const std::string extension_id() const { return extension_id_; }
+  content::RenderProcessHost* process() const { return process_; }
+  base::DictionaryValue* filter() const { return filter_.get(); }
+  EventFilter::MatcherID matcher_id() const { return matcher_id_; }
+  void set_matcher_id(EventFilter::MatcherID id) { matcher_id_ = id; }
 
  private:
+  const std::string event_name_;
+  const std::string extension_id_;
+  content::RenderProcessHost* process_;
+  scoped_ptr<base::DictionaryValue> filter_;
+  EventFilter::MatcherID matcher_id_;  // -1 if unset.
+
   DISALLOW_COPY_AND_ASSIGN(EventListener);
 };
 
diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc
index 8a6a0a3..0ff308d 100644
--- a/extensions/browser/event_router.cc
+++ b/extensions/browser/event_router.cc
@@ -216,22 +216,20 @@
 }
 
 void EventRouter::OnListenerAdded(const EventListener* listener) {
-  const EventListenerInfo details(
-      listener->event_name,
-      listener->extension_id,
-      listener->process ? listener->process->GetBrowserContext() : NULL);
-  std::string base_event_name = GetBaseEventName(listener->event_name);
+  const EventListenerInfo details(listener->event_name(),
+                                  listener->extension_id(),
+                                  listener->GetBrowserContext());
+  std::string base_event_name = GetBaseEventName(listener->event_name());
   ObserverMap::iterator observer = observers_.find(base_event_name);
   if (observer != observers_.end())
     observer->second->OnListenerAdded(details);
 }
 
 void EventRouter::OnListenerRemoved(const EventListener* listener) {
-  const EventListenerInfo details(
-      listener->event_name,
-      listener->extension_id,
-      listener->process ? listener->process->GetBrowserContext() : NULL);
-  std::string base_event_name = GetBaseEventName(listener->event_name);
+  const EventListenerInfo details(listener->event_name(),
+                                  listener->extension_id(),
+                                  listener->GetBrowserContext());
+  std::string base_event_name = GetBaseEventName(listener->event_name());
   ObserverMap::iterator observer = observers_.find(base_event_name);
   if (observer != observers_.end())
     observer->second->OnListenerRemoved(details);
@@ -296,7 +294,7 @@
   listeners_.RemoveListener(&listener);
 
   if (remove_lazy_listener) {
-    listener.process = NULL;
+    listener.MakeLazy();
     bool removed = listeners_.RemoveListener(&listener);
 
     if (removed)
@@ -454,9 +452,9 @@
        it != listeners.end(); it++) {
     const EventListener* listener = *it;
     if (restrict_to_extension_id.empty() ||
-        restrict_to_extension_id == listener->extension_id) {
-      if (!listener->process) {
-        DispatchLazyEvent(listener->extension_id, event, &already_dispatched);
+        restrict_to_extension_id == listener->extension_id()) {
+      if (listener->IsLazy()) {
+        DispatchLazyEvent(listener->extension_id(), event, &already_dispatched);
       }
     }
   }
@@ -465,13 +463,13 @@
        it != listeners.end(); it++) {
     const EventListener* listener = *it;
     if (restrict_to_extension_id.empty() ||
-        restrict_to_extension_id == listener->extension_id) {
-      if (listener->process) {
-        EventDispatchIdentifier dispatch_id(
-            listener->process->GetBrowserContext(), listener->extension_id);
+        restrict_to_extension_id == listener->extension_id()) {
+      if (listener->process()) {
+        EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(),
+                                            listener->extension_id());
         if (!ContainsKey(already_dispatched, dispatch_id)) {
-          DispatchEventToProcess(listener->extension_id, listener->process,
-              event);
+          DispatchEventToProcess(
+              listener->extension_id(), listener->process(), event);
         }
       }
     }
diff --git a/extensions/browser/extension_function.cc b/extensions/browser/extension_function.cc
index 7e9a194..ff7d544 100644
--- a/extensions/browser/extension_function.cc
+++ b/extensions/browser/extension_function.cc
@@ -34,7 +34,9 @@
     } else {
       function->SetResultList(make_scoped_ptr(result));
     }
-    DCHECK_EQ("", function->GetError());
+    // It would be nice to DCHECK(error.empty()) but some legacy extension
+    // function implementations... I'm looking at chrome.input.ime... do this
+    // for some reason.
   }
 
   virtual ~MultipleArgumentsResponseValue() {}
@@ -45,7 +47,8 @@
 class ErrorResponseValue : public ExtensionFunction::ResponseValueObject {
  public:
   ErrorResponseValue(ExtensionFunction* function, const std::string& error) {
-    DCHECK_NE("", error);
+    // It would be nice to DCHECK(!error.empty()) but too many legacy extension
+    // function implementations don't set error but signal failure.
     function->SetError(error);
   }
 
@@ -224,32 +227,22 @@
 
 ExtensionFunction::ResponseAction ExtensionFunction::RespondNow(
     ResponseValue result) {
-  return scoped_ptr<ResponseActionObject>(new RespondNowAction(
+  return ResponseAction(new RespondNowAction(
       result.Pass(), base::Bind(&ExtensionFunction::SendResponse, this)));
 }
 
 ExtensionFunction::ResponseAction ExtensionFunction::RespondLater() {
-  return scoped_ptr<ResponseActionObject>(new RespondLaterAction());
+  return ResponseAction(new RespondLaterAction());
 }
 
-void ExtensionFunction::Run() {
-  if (!RunImpl())
-    SendResponse(false);
+// static
+ExtensionFunction::ResponseAction ExtensionFunction::ValidationFailure(
+    ExtensionFunction* function) {
+  return function->RespondNow(function->BadMessage());
 }
 
-bool ExtensionFunction::RunImpl() {
-  RunImplTypesafe()->Execute();
-  return true;
-}
-
-ExtensionFunction::ResponseAction ExtensionFunction::RunImplTypesafe() {
-  NOTREACHED()
-      << "ExtensionFunctions must override either RunImpl or RunImplTypesafe";
-  return RespondNow(NoArguments());
-}
-
-void ExtensionFunction::SendResponseTypesafe(ResponseValue response) {
-  SendResponse(response->Apply());
+void ExtensionFunction::Respond(ResponseValue result) {
+  SendResponse(result->Apply());
 }
 
 bool ExtensionFunction::ShouldSkipQuotaLimiting() const {
@@ -277,6 +270,10 @@
   response_callback_.Run(type, *results_, GetError());
 }
 
+void ExtensionFunction::OnRespondingLater(ResponseValue value) {
+  SendResponse(value->Apply());
+}
+
 UIThreadExtensionFunction::UIThreadExtensionFunction()
     : render_view_host_(NULL),
       render_frame_host_(NULL),
@@ -369,15 +366,30 @@
 AsyncExtensionFunction::~AsyncExtensionFunction() {
 }
 
+ExtensionFunction::ResponseAction AsyncExtensionFunction::Run() {
+  return RunAsync() ? RespondLater() : RespondNow(Error(error_));
+}
+
+// static
+bool AsyncExtensionFunction::ValidationFailure(
+    AsyncExtensionFunction* function) {
+  return false;
+}
+
 SyncExtensionFunction::SyncExtensionFunction() {
 }
 
 SyncExtensionFunction::~SyncExtensionFunction() {
 }
 
-bool SyncExtensionFunction::RunImpl() {
-  SendResponse(RunSync());
-  return true;
+ExtensionFunction::ResponseAction SyncExtensionFunction::Run() {
+  return RespondNow(RunSync() ? MultipleArguments(results_.get())
+                              : Error(error_));
+}
+
+// static
+bool SyncExtensionFunction::ValidationFailure(SyncExtensionFunction* function) {
+  return false;
 }
 
 SyncIOThreadExtensionFunction::SyncIOThreadExtensionFunction() {
@@ -386,7 +398,13 @@
 SyncIOThreadExtensionFunction::~SyncIOThreadExtensionFunction() {
 }
 
-bool SyncIOThreadExtensionFunction::RunImpl() {
-  SendResponse(RunSync());
-  return true;
+ExtensionFunction::ResponseAction SyncIOThreadExtensionFunction::Run() {
+  return RespondNow(RunSync() ? MultipleArguments(results_.get())
+                              : Error(error_));
+}
+
+// static
+bool SyncIOThreadExtensionFunction::ValidationFailure(
+    SyncIOThreadExtensionFunction* function) {
+  return false;
 }
diff --git a/extensions/browser/extension_function.h b/extensions/browser/extension_function.h
index ee5f97a..9f8cb71 100644
--- a/extensions/browser/extension_function.h
+++ b/extensions/browser/extension_function.h
@@ -44,28 +44,23 @@
 class QuotaLimitHeuristic;
 }
 
-#define EXTENSION_FUNCTION_VALIDATE(test) \
-  EXTENSION_FUNCTION_VALIDATE_INTERNAL(test, false)
-
-#define EXTENSION_FUNCTION_VALIDATE_TYPESAFE(test) \
-  EXTENSION_FUNCTION_VALIDATE_INTERNAL(test, RespondNow(BadMessage()))
-
 #ifdef NDEBUG
-#define EXTENSION_FUNCTION_VALIDATE_INTERNAL(test, failure) \
-  do {                                                      \
-    if (!(test)) {                                          \
-      bad_message_ = true;                                  \
-      return (failure);                                     \
-    }                                                       \
+#define EXTENSION_FUNCTION_VALIDATE(test) \
+  do {                                    \
+    if (!(test)) {                        \
+      bad_message_ = true;                \
+      return ValidationFailure(this);     \
+    }                                     \
   } while (0)
 #else   // NDEBUG
-#define EXTENSION_FUNCTION_VALIDATE_INTERNAL(test, failure) CHECK(test)
+#define EXTENSION_FUNCTION_VALIDATE(test) CHECK(test)
 #endif  // NDEBUG
 
-#define EXTENSION_FUNCTION_ERROR(error) do { \
-    error_ = error; \
-    bad_message_ = true; \
-    return false; \
+#define EXTENSION_FUNCTION_ERROR(error) \
+  do {                                  \
+    error_ = error;                     \
+    bad_message_ = true;                \
+    return ValidationFailure(this);     \
   } while (0)
 
 // Declares a callable extension function with the given |name|. You must also
@@ -118,13 +113,41 @@
   // This will be run after the function has been set up but before Run().
   virtual bool HasPermission();
 
-  // Execute the API. Clients should initialize the ExtensionFunction using
-  // SetArgs(), set_request_id(), and the other setters before calling this
-  // method.
+  // The result of a function call.
   //
-  // Note that once Run() returns, dispatcher() can be NULL, so be sure to
-  // NULL-check.
-  void Run();
+  // Use NoArguments(), SingleArgument(), MultipleArguments(), or Error()
+  // rather than this class directly.
+  class ResponseValueObject {
+   public:
+    virtual ~ResponseValueObject() {}
+
+    // Returns true for success, false for failure.
+    virtual bool Apply() = 0;
+  };
+  typedef scoped_ptr<ResponseValueObject> ResponseValue;
+
+  // The action to use when returning from RunAsync.
+  //
+  // Use RespondNow() or RespondLater() rather than this class directly.
+  class ResponseActionObject {
+   public:
+    virtual ~ResponseActionObject() {}
+
+    virtual void Execute() = 0;
+  };
+  typedef scoped_ptr<ResponseActionObject> ResponseAction;
+
+  // Runs the function and returns the action to take when the caller is ready
+  // to respond.
+  //
+  // Callers must call Execute() on the return ResponseAction at some point,
+  // exactly once.
+  //
+  // SyncExtensionFunction and AsyncExtensionFunction implement this in terms
+  // of SyncExtensionFunction::RunSync and AsyncExtensionFunction::RunAsync,
+  // but this is deprecated. ExtensionFunction implementations are encouraged
+  // to just implement Run.
+  virtual ResponseAction Run() WARN_UNUSED_RESULT = 0;
 
   // Gets whether quota should be applied to this individual function
   // invocation. This is different to GetQuotaLimitHeuristics which is only
@@ -208,30 +231,6 @@
   void set_source_tab_id(int source_tab_id) { source_tab_id_ = source_tab_id; }
   int source_tab_id() const { return source_tab_id_; }
 
-  // The result of a function call.
-  //
-  // Use NoArguments(), SingleArgument(), MultipleArguments(), or Error()
-  // rather than this class directly.
-  class ResponseValueObject {
-   public:
-    virtual ~ResponseValueObject() {}
-
-    // Returns true for success, false for failure.
-    virtual bool Apply() = 0;
-  };
-  typedef scoped_ptr<ResponseValueObject> ResponseValue;
-
-  // The action to use when returning from RunImpl.
-  //
-  // Use RespondNow() or RespondLater() rather than this class directly.
-  class ResponseActionObject {
-   public:
-    virtual ~ResponseActionObject() {}
-
-    virtual void Execute() = 0;
-  };
-  typedef scoped_ptr<ResponseActionObject> ResponseAction;
-
  protected:
   friend struct ExtensionFunctionDeleteTraits;
 
@@ -252,28 +251,28 @@
   //
   // Respond to the extension immediately with |result|.
   ResponseAction RespondNow(ResponseValue result);
-  // Don't respond now, but promise to call SendResponse later.
+  // Don't respond now, but promise to call Respond() later.
   ResponseAction RespondLater();
 
+  // This is the return value of the EXTENSION_FUNCTION_VALIDATE macro, which
+  // needs to work from Run(), RunAsync(), and RunSync(). The former of those
+  // has a different return type (ResponseAction) than the latter two (bool).
+  static ResponseAction ValidationFailure(ExtensionFunction* function);
+
+  // If RespondLater() was used, functions must at some point call Respond()
+  // with |result| as their result.
+  void Respond(ResponseValue result);
+
   virtual ~ExtensionFunction();
 
   // Helper method for ExtensionFunctionDeleteTraits. Deletes this object.
   virtual void Destruct() const = 0;
 
-  // Derived classes should implement one of these methods to do their work.
+  // Do not call this function directly, return the appropriate ResponseAction
+  // from Run() instead. If using RespondLater then call Respond().
   //
-  // Returns the action to take. DO NOT USE WITH SyncExtensionFunction.
-  virtual ResponseAction RunImplTypesafe();
-  // Deprecated. Returns true on success. SendResponse() must be called later.
-  // Return false to indicate an error and respond immediately.
-  virtual bool RunImpl();
-
-  // Sends the result back to the extension.
-  //
-  // Responds with |response|.
-  void SendResponseTypesafe(ResponseValue response);
-  // Deprecated. Call with true to indicate success, false to indicate failure,
-  // in which case please set |error_|.
+  // Call with true to indicate success, false to indicate failure, in which
+  // case please set |error_|.
   virtual void SendResponse(bool success) = 0;
 
   // Common implementation for SendResponse.
@@ -337,6 +336,8 @@
   int source_tab_id_;
 
  private:
+  void OnRespondingLater(ResponseValue response);
+
   DISALLOW_COPY_AND_ASSIGN(ExtensionFunction);
 };
 
@@ -489,6 +490,19 @@
 
  protected:
   virtual ~AsyncExtensionFunction();
+
+  // Deprecated: Override UIThreadExtensionFunction and implement Run() instead.
+  //
+  // AsyncExtensionFunctions implement this method. Return true to indicate that
+  // nothing has gone wrong yet; SendResponse must be called later. Return true
+  // to respond immediately with an error.
+  virtual bool RunAsync() = 0;
+
+  // ValidationFailure override to match RunAsync().
+  static bool ValidationFailure(AsyncExtensionFunction* function);
+
+ private:
+  virtual ResponseAction Run() OVERRIDE;
 };
 
 // A SyncExtensionFunction is an ExtensionFunction that runs synchronously
@@ -502,24 +516,41 @@
  public:
   SyncExtensionFunction();
 
-  virtual bool RunImpl() OVERRIDE;
-
  protected:
+  virtual ~SyncExtensionFunction();
+
+  // Deprecated: Override UIThreadExtensionFunction and implement Run() instead.
+  //
+  // SyncExtensionFunctions implement this method. Return true to respond
+  // immediately with success, false to respond immediately with an error.
   virtual bool RunSync() = 0;
 
-  virtual ~SyncExtensionFunction();
+  // ValidationFailure override to match RunSync().
+  static bool ValidationFailure(SyncExtensionFunction* function);
+
+ private:
+  virtual ResponseAction Run() OVERRIDE;
 };
 
 class SyncIOThreadExtensionFunction : public IOThreadExtensionFunction {
  public:
   SyncIOThreadExtensionFunction();
 
-  virtual bool RunImpl() OVERRIDE;
-
  protected:
+  virtual ~SyncIOThreadExtensionFunction();
+
+  // Deprecated: Override IOThreadExtensionFunction and implement Run() instead.
+  //
+  // SyncIOThreadExtensionFunctions implement this method. Return true to
+  // respond immediately with success, false to respond immediately with an
+  // error.
   virtual bool RunSync() = 0;
 
-  virtual ~SyncIOThreadExtensionFunction();
+  // ValidationFailure override to match RunSync().
+  static bool ValidationFailure(SyncIOThreadExtensionFunction* function);
+
+ private:
+  virtual ResponseAction Run() OVERRIDE;
 };
 
 #endif  // EXTENSIONS_BROWSER_EXTENSION_FUNCTION_H_
diff --git a/extensions/browser/extension_function_dispatcher.cc b/extensions/browser/extension_function_dispatcher.cc
index dd5f30a..fb3b50d 100644
--- a/extensions/browser/extension_function_dispatcher.cc
+++ b/extensions/browser/extension_function_dispatcher.cc
@@ -274,7 +274,7 @@
                             static_cast<content::BrowserContext*>(profile_id));
     UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.FunctionCalls",
                                 function->histogram_value());
-    function->Run();
+    function->Run()->Execute();
   } else {
     function->OnQuotaExceeded(violation_error);
   }
@@ -382,7 +382,7 @@
         extension->id(), params.name, args.Pass(), browser_context_);
     UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.FunctionCalls",
                                 function->histogram_value());
-    function->Run();
+    function->Run()->Execute();
   } else {
     function->OnQuotaExceeded(violation_error);
   }
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 5486d77..3403afb 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -808,6 +808,18 @@
   BLUETOOTHSOCKET_GETSOCKETS,
   WEBSTOREPRIVATE_SIGNINFUNCTION,
   SHELL_CREATEWINDOW,
+  FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDSUCCESS,
+  FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDERROR,
+  BROWSER_OPENTAB,
+  MANAGEMENT_CREATEAPPSHORTCUT,
+  WEBVIEW_SHOWCONTEXTMENU,
+  WEBRTCLOGGINGPRIVATE_STARTRTPDUMP,
+  WEBRTCLOGGINGPRIVATE_STOPRTPDUMP,
+  AUTOMATIONINTERNAL_ENABLEDESKTOP,
+  HOTWORDPRIVATE_SETHOTWORDSESSIONSTATE,
+  HOTWORDPRIVATE_NOTIFYHOTWORDRECOGNITION,
+  FILESYSTEMPROVIDERINTERNAL_READDIRECTORYREQUESTEDSUCCESS,
+  FILESYSTEMPROVIDERINTERNAL_READDIRECTORYREQUESTEDERROR,
   // Last entry: Add new entries above and ensure to update
   // tools/metrics/histograms/histograms/histograms.xml.
   ENUM_BOUNDARY
diff --git a/extensions/browser/extension_protocols.cc b/extensions/browser/extension_protocols.cc
index 32b6bc0..71cefcc 100644
--- a/extensions/browser/extension_protocols.cc
+++ b/extensions/browser/extension_protocols.cc
@@ -33,6 +33,8 @@
 #include "content/public/browser/resource_request_info.h"
 #include "crypto/secure_hash.h"
 #include "crypto/sha2.h"
+#include "extensions/browser/content_verifier.h"
+#include "extensions/browser/content_verify_job.h"
 #include "extensions/browser/extensions_browser_client.h"
 #include "extensions/browser/info_map.h"
 #include "extensions/common/constants.h"
@@ -165,13 +167,15 @@
                          const base::FilePath& relative_path,
                          const std::string& content_security_policy,
                          bool send_cors_header,
-                         bool follow_symlinks_anywhere)
+                         bool follow_symlinks_anywhere,
+                         ContentVerifyJob* verify_job)
       : net::URLRequestFileJob(
             request,
             network_delegate,
             base::FilePath(),
             BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
                 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
+        verify_job_(verify_job),
         seek_position_(0),
         bytes_read_(0),
         directory_path_(directory_path),
@@ -184,13 +188,6 @@
     if (follow_symlinks_anywhere) {
       resource_.set_follow_symlinks_anywhere();
     }
-    const std::string& group =
-        base::FieldTrialList::FindFullName("ExtensionContentHashMeasurement");
-    if (group == "Yes") {
-      base::ElapsedTimer timer;
-      hash_.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256));
-      hashing_time_ = timer.Elapsed();
-    }
   }
 
   virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE {
@@ -214,9 +211,25 @@
     DCHECK(posted);
   }
 
+  virtual void SetExtraRequestHeaders(
+      const net::HttpRequestHeaders& headers) OVERRIDE {
+    // TODO(asargent) - we'll need to add proper support for range headers.
+    // crbug.com/369895.
+    std::string range_header;
+    if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) {
+      if (verify_job_)
+        verify_job_ = NULL;
+    }
+    URLRequestFileJob::SetExtraRequestHeaders(headers);
+  }
+
   virtual void OnSeekComplete(int64 result) OVERRIDE {
     DCHECK_EQ(seek_position_, 0);
     seek_position_ = result;
+    // TODO(asargent) - we'll need to add proper support for range headers.
+    // crbug.com/369895.
+    if (result > 0 && verify_job_)
+      verify_job_ = NULL;
   }
 
   virtual void OnReadComplete(net::IOBuffer* buffer, int result) OVERRIDE {
@@ -227,23 +240,16 @@
                                   -result);
     if (result > 0) {
       bytes_read_ += result;
-      if (hash_.get()) {
-        base::ElapsedTimer timer;
-        hash_->Update(buffer->data(), result);
-        hashing_time_ += timer.Elapsed();
+      if (verify_job_) {
+        verify_job_->BytesRead(result, buffer->data());
+        if (!remaining_bytes())
+          verify_job_->DoneReading();
       }
     }
   }
 
  private:
   virtual ~URLRequestExtensionJob() {
-    if (hash_.get()) {
-      base::ElapsedTimer timer;
-      std::string hash_bytes(crypto::kSHA256Length, 0);
-      hash_->Finish(string_as_array(&hash_bytes), hash_bytes.size());
-      hashing_time_ += timer.Elapsed();
-      UMA_HISTOGRAM_TIMES("ExtensionUrlRequest.HashTimeMs", hashing_time_);
-    }
     UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.TotalKbRead", bytes_read_ / 1024);
     UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.SeekPosition", seek_position_);
   }
@@ -258,8 +264,7 @@
     URLRequestFileJob::Start();
   }
 
-  // A hash of the contents we've read from the file.
-  scoped_ptr<crypto::SecureHash> hash_;
+  scoped_refptr<ContentVerifyJob> verify_job_;
 
   // The position we seeked to in the file.
   int64 seek_position_;
@@ -267,9 +272,6 @@
   // The number of bytes of content we read from the file.
   int bytes_read_;
 
-  // Used to count the total time it takes to do hashing operations.
-  base::TimeDelta hashing_time_;
-
   net::HttpResponseInfo response_info_;
   base::FilePath directory_path_;
   extensions::ExtensionResource resource_;
@@ -499,6 +501,14 @@
       return NULL;
     }
   }
+  ContentVerifyJob* verify_job = NULL;
+  ContentVerifier* verifier = extension_info_map_->content_verifier();
+  if (verifier) {
+    verify_job =
+        verifier->CreateJobFor(extension_id, directory_path, relative_path);
+    if (verify_job)
+      verify_job->Start();
+  }
 
   return new URLRequestExtensionJob(request,
                                     network_delegate,
@@ -507,7 +517,8 @@
                                     relative_path,
                                     content_security_policy,
                                     send_cors_header,
-                                    follow_symlinks_anywhere);
+                                    follow_symlinks_anywhere,
+                                    verify_job);
 }
 
 }  // namespace
diff --git a/extensions/browser/extension_protocols.h b/extensions/browser/extension_protocols.h
index 2260374..51db6e2 100644
--- a/extensions/browser/extension_protocols.h
+++ b/extensions/browser/extension_protocols.h
@@ -33,7 +33,7 @@
 // profiles.
 net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler(
     bool is_incognito,
-    extensions::InfoMap* extension_info_map);
+    InfoMap* extension_info_map);
 
 }  // namespace extensions
 
diff --git a/extensions/browser/extension_system.h b/extensions/browser/extension_system.h
index 1ccccdd..e658138 100644
--- a/extensions/browser/extension_system.h
+++ b/extensions/browser/extension_system.h
@@ -26,6 +26,7 @@
 namespace extensions {
 
 class Blacklist;
+class ContentVerifier;
 class ErrorConsole;
 class EventRouter;
 class Extension;
@@ -124,6 +125,9 @@
 
   // Signaled when the extension system has completed its startup tasks.
   virtual const OneShotEvent& ready() const = 0;
+
+  // Returns the content verifier, if any.
+  virtual ContentVerifier* content_verifier() = 0;
 };
 
 }  // namespace extensions
diff --git a/extensions/browser/extensions_browser_client.h b/extensions/browser/extensions_browser_client.h
index e3b91b2..9356aa6 100644
--- a/extensions/browser/extensions_browser_client.h
+++ b/extensions/browser/extensions_browser_client.h
@@ -40,6 +40,7 @@
 class ExtensionSystem;
 class ExtensionSystemProvider;
 class InfoMap;
+class RuntimeAPIDelegate;
 
 // Interface to allow the extensions module to make browser-process-specific
 // queries of the embedder. Should be Set() once in the browser process.
@@ -166,6 +167,12 @@
   virtual void RegisterExtensionFunctions(
       ExtensionFunctionRegistry* registry) const = 0;
 
+  // Creates a RuntimeAPIDelegate responsible for handling extensions
+  // management-related events such as update and installation on behalf of the
+  // core runtime API implementation.
+  virtual scoped_ptr<RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
+      content::BrowserContext* context) const = 0;
+
   // Returns the single instance of |this|.
   static ExtensionsBrowserClient* Get();
 
diff --git a/extensions/browser/info_map.cc b/extensions/browser/info_map.cc
index 408b4f1..42b85c5 100644
--- a/extensions/browser/info_map.cc
+++ b/extensions/browser/info_map.cc
@@ -5,6 +5,7 @@
 #include "extensions/browser/info_map.h"
 
 #include "content/public/browser/browser_thread.h"
+#include "extensions/browser/content_verifier.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_set.h"
@@ -207,6 +208,10 @@
   return false;
 }
 
+void InfoMap::SetContentVerifier(ContentVerifier* verifier) {
+  content_verifier_ = verifier;
+}
+
 InfoMap::~InfoMap() {
   if (quota_service_) {
     BrowserThread::DeleteSoon(
diff --git a/extensions/browser/info_map.h b/extensions/browser/info_map.h
index ad47506..5dfc9c2 100644
--- a/extensions/browser/info_map.h
+++ b/extensions/browser/info_map.h
@@ -16,6 +16,7 @@
 #include "extensions/common/extension_set.h"
 
 namespace extensions {
+class ContentVerifier;
 class Extension;
 
 // Contains extension data that needs to be accessed on the IO thread. It can
@@ -103,6 +104,9 @@
                                 bool notifications_disabled);
   bool AreNotificationsDisabled(const std::string& extension_id) const;
 
+  void SetContentVerifier(ContentVerifier* verifier);
+  ContentVerifier* content_verifier() { return content_verifier_; }
+
  private:
   friend class base::RefCountedThreadSafe<InfoMap>;
 
@@ -131,6 +135,8 @@
   extensions::ProcessMap worker_process_map_;
 
   int signin_process_id_;
+
+  scoped_refptr<ContentVerifier> content_verifier_;
 };
 
 }  // namespace extensions
diff --git a/extensions/browser/quota_service_unittest.cc b/extensions/browser/quota_service_unittest.cc
index d9501ba..8a684c7 100644
--- a/extensions/browser/quota_service_unittest.cc
+++ b/extensions/browser/quota_service_unittest.cc
@@ -67,7 +67,7 @@
   virtual std::string GetError() const OVERRIDE { return std::string(); }
   virtual void SetError(const std::string& error) OVERRIDE {}
   virtual void Destruct() const OVERRIDE { delete this; }
-  virtual bool RunImpl() OVERRIDE { return true; }
+  virtual ResponseAction Run() OVERRIDE { return RespondLater(); }
   virtual void SendResponse(bool) OVERRIDE {}
 
  protected:
diff --git a/extensions/browser/test_extensions_browser_client.cc b/extensions/browser/test_extensions_browser_client.cc
index 6e919ea..7708ca7 100644
--- a/extensions/browser/test_extensions_browser_client.cc
+++ b/extensions/browser/test_extensions_browser_client.cc
@@ -7,6 +7,7 @@
 #include "content/public/browser/browser_context.h"
 #include "extensions/browser/app_sorting.h"
 #include "extensions/browser/extension_host_delegate.h"
+#include "extensions/browser/test_runtime_api_delegate.h"
 
 using content::BrowserContext;
 
@@ -155,4 +156,10 @@
 void TestExtensionsBrowserClient::RegisterExtensionFunctions(
     ExtensionFunctionRegistry* registry) const {}
 
+scoped_ptr<RuntimeAPIDelegate>
+TestExtensionsBrowserClient::CreateRuntimeAPIDelegate(
+    content::BrowserContext* context) const {
+  return scoped_ptr<RuntimeAPIDelegate>(new TestRuntimeAPIDelegate());
+}
+
 }  // namespace extensions
diff --git a/extensions/browser/test_extensions_browser_client.h b/extensions/browser/test_extensions_browser_client.h
index f7401fe..ff09ae3 100644
--- a/extensions/browser/test_extensions_browser_client.h
+++ b/extensions/browser/test_extensions_browser_client.h
@@ -73,6 +73,8 @@
   virtual ExtensionSystemProvider* GetExtensionSystemFactory() OVERRIDE;
   virtual void RegisterExtensionFunctions(
       ExtensionFunctionRegistry* registry) const OVERRIDE;
+  virtual scoped_ptr<RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
+      content::BrowserContext* context) const OVERRIDE;
 
  private:
   content::BrowserContext* main_context_;       // Not owned.
diff --git a/extensions/browser/test_runtime_api_delegate.cc b/extensions/browser/test_runtime_api_delegate.cc
new file mode 100644
index 0000000..9394050
--- /dev/null
+++ b/extensions/browser/test_runtime_api_delegate.cc
@@ -0,0 +1,53 @@
+// 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.
+
+#include "extensions/browser/test_runtime_api_delegate.h"
+
+#include "extensions/common/api/runtime.h"
+
+namespace extensions {
+
+using core_api::runtime::PlatformInfo;
+
+TestRuntimeAPIDelegate::TestRuntimeAPIDelegate() {
+}
+
+TestRuntimeAPIDelegate::~TestRuntimeAPIDelegate() {
+}
+
+void TestRuntimeAPIDelegate::AddUpdateObserver(UpdateObserver* observer) {
+}
+
+void TestRuntimeAPIDelegate::RemoveUpdateObserver(UpdateObserver* observer) {
+}
+
+base::Version TestRuntimeAPIDelegate::GetPreviousExtensionVersion(
+    const Extension* extension) {
+  return base::Version();
+}
+
+void TestRuntimeAPIDelegate::ReloadExtension(const std::string& extension_id) {
+}
+
+bool TestRuntimeAPIDelegate::CheckForUpdates(
+    const std::string& extension_id,
+    const UpdateCheckCallback& callback) {
+  return false;
+}
+
+void TestRuntimeAPIDelegate::OpenURL(const GURL& uninstall_url) {
+}
+
+bool TestRuntimeAPIDelegate::GetPlatformInfo(PlatformInfo* info) {
+  // TODO(rockot): This probably isn't right. Maybe this delegate should just
+  // support manual PlatformInfo override for tests if necessary.
+  info->os = PlatformInfo::OS_CROS_;
+  return true;
+}
+
+bool TestRuntimeAPIDelegate::RestartDevice(std::string* error_message) {
+  return false;
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/test_runtime_api_delegate.h b/extensions/browser/test_runtime_api_delegate.h
new file mode 100644
index 0000000..8922bd5
--- /dev/null
+++ b/extensions/browser/test_runtime_api_delegate.h
@@ -0,0 +1,36 @@
+// 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.
+
+#ifndef EXENSIONS_BROWSER_TEST_RUNTIME_API_DELEGATE_H_
+#define EXENSIONS_BROWSER_TEST_RUNTIME_API_DELEGATE_H_
+
+#include "base/macros.h"
+#include "extensions/browser/api/runtime/runtime_api_delegate.h"
+
+namespace extensions {
+
+class TestRuntimeAPIDelegate : public RuntimeAPIDelegate {
+ public:
+  TestRuntimeAPIDelegate();
+  virtual ~TestRuntimeAPIDelegate();
+
+  // RuntimeAPIDelegate implementation.
+  virtual void AddUpdateObserver(UpdateObserver* observer) OVERRIDE;
+  virtual void RemoveUpdateObserver(UpdateObserver* observer) OVERRIDE;
+  virtual base::Version GetPreviousExtensionVersion(
+      const Extension* extension) OVERRIDE;
+  virtual void ReloadExtension(const std::string& extension_id) OVERRIDE;
+  virtual bool CheckForUpdates(const std::string& extension_id,
+                               const UpdateCheckCallback& callback) OVERRIDE;
+  virtual void OpenURL(const GURL& uninstall_url) OVERRIDE;
+  virtual bool GetPlatformInfo(core_api::runtime::PlatformInfo* info) OVERRIDE;
+  virtual bool RestartDevice(std::string* error_message) OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestRuntimeAPIDelegate);
+};
+
+}  // namespace extensions
+
+#endif  // EXENSIONS_BROWSER_TEST_RUNTIME_API_DELEGATE_H_
diff --git a/extensions/browser/verified_contents.cc b/extensions/browser/verified_contents.cc
new file mode 100644
index 0000000..964291b
--- /dev/null
+++ b/extensions/browser/verified_contents.cc
@@ -0,0 +1,312 @@
+// 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.
+
+#include "extensions/browser/verified_contents.h"
+
+#include "base/base64.h"
+#include "base/file_util.h"
+#include "base/json/json_reader.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "crypto/signature_verifier.h"
+#include "extensions/common/extension.h"
+
+using base::DictionaryValue;
+using base::ListValue;
+using base::Value;
+
+namespace {
+
+// Note: this structure is an ASN.1 which encodes the algorithm used with its
+// parameters.  The signature algorithm is "RSA256" aka "RSASSA-PKCS-v1_5 using
+// SHA-256 hash algorithm". This is defined in PKCS #1 (RFC 3447).
+// It is encoding: { OID sha256WithRSAEncryption      PARAMETERS NULL }
+const uint8 kSignatureAlgorithm[15] = {0x30, 0x0d, 0x06, 0x09, 0x2a,
+                                       0x86, 0x48, 0x86, 0xf7, 0x0d,
+                                       0x01, 0x01, 0x0b, 0x05, 0x00};
+
+const char kBlockSizeKey[] = "block_size";
+const char kContentHashesKey[] = "content_hashes";
+const char kFilesKey[] = "files";
+const char kFormatKey[] = "format";
+const char kHashBlockSizeKey[] = "hash_block_size";
+const char kHeaderKidKey[] = "header.kid";
+const char kItemIdKey[] = "item_id";
+const char kItemVersionKey[] = "item_version";
+const char kPathKey[] = "path";
+const char kPayloadKey[] = "payload";
+const char kProtectedKey[] = "protected";
+const char kRootHashKey[] = "root_hash";
+const char kSignatureKey[] = "signature";
+const char kSignaturesKey[] = "signatures";
+const char kTreeHash[] = "treehash";
+const char kWebstoreKId[] = "webstore";
+
+// This function fixes up a string in base64url encoding to be in standard
+// base64.
+//
+// The JSON signing spec we're following uses "base64url" encoding (RFC 4648
+// section 5 without padding). The slight differences from regular base64
+// encoding are:
+//   1. uses '_' instead of '/'
+//   2. uses '-' instead of '+'
+//   3. omits trailing '=' padding
+bool FixupBase64Encoding(std::string* input) {
+  for (std::string::iterator i = input->begin(); i != input->end(); ++i) {
+    if (*i == '-')
+      *i = '+';
+    else if (*i == '_')
+      *i = '/';
+  }
+  switch (input->size() % 4) {
+    case 0:
+      break;
+    case 2:
+      input->append("==");
+      break;
+    case 3:
+      input->append("=");
+      break;
+    default:
+      return false;
+  }
+  return true;
+}
+
+}  // namespace
+
+namespace extensions {
+
+VerifiedContents::VerifiedContents(const uint8* public_key, int public_key_size)
+    : public_key_(public_key),
+      public_key_size_(public_key_size),
+      valid_signature_(false),  // Guilty until proven innocent.
+      block_size_(0) {
+}
+
+VerifiedContents::~VerifiedContents() {
+}
+
+// The format of the payload json is:
+// {
+//   "content_hashes": [
+//     {
+//       "block_size": 4096,
+//       "hash_block_size": 4096,
+//       "format": "treehash",
+//       "files": [
+//         {
+//           "path": "foo/bar",
+//           "root_hash": "<hex encoded bytes>"
+//         },
+//         ...
+//       ]
+//     }
+//   ]
+// }
+bool VerifiedContents::InitFrom(const base::FilePath& path,
+                                bool ignore_invalid_signature) {
+  std::string payload;
+  if (!GetPayload(path, &payload, ignore_invalid_signature))
+    return false;
+
+  scoped_ptr<base::Value> value(base::JSONReader::Read(payload));
+  if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY))
+    return false;
+  DictionaryValue* dictionary = static_cast<DictionaryValue*>(value.get());
+
+  std::string item_id;
+  if (!dictionary->GetString(kItemIdKey, &item_id) ||
+      !Extension::IdIsValid(item_id))
+    return false;
+  extension_id_ = item_id;
+
+  std::string version_string;
+  if (!dictionary->GetString(kItemVersionKey, &version_string))
+    return false;
+  version_ = base::Version(version_string);
+  if (!version_.IsValid())
+    return false;
+
+  ListValue* hashes_list = NULL;
+  if (!dictionary->GetList(kContentHashesKey, &hashes_list))
+    return false;
+
+  for (size_t i = 0; i < hashes_list->GetSize(); i++) {
+    DictionaryValue* hashes = NULL;
+    if (!hashes_list->GetDictionary(i, &hashes))
+      return false;
+    std::string format;
+    if (!hashes->GetString(kFormatKey, &format) || format != kTreeHash)
+      continue;
+
+    int block_size = 0;
+    int hash_block_size = 0;
+    if (!hashes->GetInteger(kBlockSizeKey, &block_size) ||
+        !hashes->GetInteger(kHashBlockSizeKey, &hash_block_size))
+      return false;
+    block_size_ = block_size;
+
+    // We don't support using a different block_size and hash_block_size at
+    // the moment.
+    if (block_size_ != hash_block_size)
+      return false;
+
+    ListValue* files = NULL;
+    if (!hashes->GetList(kFilesKey, &files))
+      return false;
+
+    for (size_t j = 0; j < files->GetSize(); j++) {
+      DictionaryValue* data = NULL;
+      if (!files->GetDictionary(j, &data))
+        return false;
+      std::string file_path_string;
+      std::string encoded_root_hash;
+      std::vector<uint8> root_hash;
+      if (!data->GetString(kPathKey, &file_path_string) ||
+          !base::IsStringUTF8(file_path_string) ||
+          !data->GetString(kRootHashKey, &encoded_root_hash) ||
+          !base::HexStringToBytes(encoded_root_hash, &root_hash))
+        return false;
+      base::FilePath file_path =
+          base::FilePath::FromUTF8Unsafe(file_path_string);
+      root_hashes_[file_path] = std::string();
+      root_hashes_[file_path].append(root_hash.begin(), root_hash.end());
+    }
+
+    break;
+  }
+  return true;
+}
+
+const std::string* VerifiedContents::GetTreeHashRoot(
+    const base::FilePath& relative_path) {
+  std::map<base::FilePath, std::string>::const_iterator i =
+      root_hashes_.find(relative_path);
+  if (i == root_hashes_.end())
+    return NULL;
+  return &i->second;
+}
+
+// We're loosely following the "JSON Web Signature" draft spec for signing
+// a JSON payload:
+//
+//   http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-26
+//
+// The idea is that you have some JSON that you want to sign, so you
+// base64-encode that and put it as the "payload" field in a containing
+// dictionary. There might be signatures of it done with multiple
+// alrogirhtms/parameters, so the payload is followed by a list of one or more
+// signature sections. Each signature section specifies the
+// algorithm/parameters in a JSON object which is base64url encoded into one
+// string and put into a "protected" field in the signature. Then the encoded
+// "payload" and "protected" strings are concatenated with a "." in between
+// them and those bytes are signed and the resulting signature is base64url
+// encoded and placed in the "signature" field. E.g.
+// {
+//   "payload": "<base64url encoded JSON to sign>",
+//   "signatures": [
+//     {
+//       "protected": "<base64url encoded JSON with algorithm/parameters>",
+//       "header": {
+//         <object with metadata about this signature, eg a key identifier>
+//       }
+//       "signature":
+//          "<base64url encoded signature done over payload || . || protected>"
+//     },
+//     ... <zero or more additional signatures> ...
+//   ]
+// }
+//
+// There might be both a signature generated with a webstore private key and a
+// signature generated with the extension's private key - for now we only
+// verify the webstore one (since the id is in the payload, so we can trust
+// that it is for a given extension), but in the future we may validate using
+// the extension's key too (eg for non-webstore hosted extensions such as
+// enterprise installs).
+bool VerifiedContents::GetPayload(const base::FilePath& path,
+                                  std::string* payload,
+                                  bool ignore_invalid_signature) {
+  std::string contents;
+  if (!base::ReadFileToString(path, &contents))
+    return false;
+  scoped_ptr<base::Value> value(base::JSONReader::Read(contents));
+  if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY))
+    return false;
+  DictionaryValue* dictionary = static_cast<DictionaryValue*>(value.get());
+
+  ListValue* signatures = NULL;
+  if (!dictionary->GetList(kSignaturesKey, &signatures))
+    return false;
+
+  std::string protected_value;
+  std::string decoded_signature;
+  for (size_t i = 0; i < signatures->GetSize(); i++) {
+    DictionaryValue* signature_dict = NULL;
+    if (!signatures->GetDictionary(i, &signature_dict))
+      return false;
+    std::string kid;
+    if (!signature_dict->GetString(kHeaderKidKey, &kid))
+      continue;
+    if (kid == std::string(kWebstoreKId)) {
+      std::string encoded_signature;
+      if (!signature_dict->GetString(kProtectedKey, &protected_value) ||
+          !signature_dict->GetString(kSignatureKey, &encoded_signature) ||
+          !FixupBase64Encoding(&encoded_signature) ||
+          !base::Base64Decode(encoded_signature, &decoded_signature))
+        return false;
+      break;
+    }
+  }
+  std::string encoded_payload;
+  if (!dictionary->GetString(kPayloadKey, &encoded_payload))
+    return false;
+
+  valid_signature_ =
+      VerifySignature(protected_value, encoded_payload, decoded_signature);
+  if (!valid_signature_ && !ignore_invalid_signature)
+    return false;
+
+  if (!FixupBase64Encoding(&encoded_payload) ||
+      !base::Base64Decode(encoded_payload, payload))
+    return false;
+
+  return true;
+}
+
+bool VerifiedContents::VerifySignature(const std::string& protected_value,
+                                       const std::string& payload,
+                                       const std::string& signature_bytes) {
+  crypto::SignatureVerifier signature_verifier;
+  if (!signature_verifier.VerifyInit(
+          kSignatureAlgorithm,
+          sizeof(kSignatureAlgorithm),
+          reinterpret_cast<const uint8*>(signature_bytes.data()),
+          signature_bytes.size(),
+          public_key_,
+          public_key_size_)) {
+    VLOG(1) << "Could not verify signature - VerifyInit failure";
+    return false;
+  }
+
+  signature_verifier.VerifyUpdate(
+      reinterpret_cast<const uint8*>(protected_value.data()),
+      protected_value.size());
+
+  std::string dot(".");
+  signature_verifier.VerifyUpdate(reinterpret_cast<const uint8*>(dot.data()),
+                                  dot.size());
+
+  signature_verifier.VerifyUpdate(
+      reinterpret_cast<const uint8*>(payload.data()), payload.size());
+
+  if (!signature_verifier.VerifyFinal()) {
+    VLOG(1) << "Could not verify signature - VerifyFinal failure";
+    return false;
+  }
+  return true;
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/verified_contents.h b/extensions/browser/verified_contents.h
new file mode 100644
index 0000000..9a24062
--- /dev/null
+++ b/extensions/browser/verified_contents.h
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef EXTENSIONS_BROWSER_VERIFIED_CONTENTS_H_
+#define EXTENSIONS_BROWSER_VERIFIED_CONTENTS_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/version.h"
+
+namespace extensions {
+
+// This class encapsulates the data in a "verified_contents.json" file
+// generated by the webstore for a .crx file. That data includes a set of
+// signed expected hashes of file content which can be used to check for
+// corruption of extension files on local disk.
+class VerifiedContents {
+ public:
+  // Note: the public_key must remain valid for the lifetime of this object.
+  VerifiedContents(const uint8* public_key, int public_key_size);
+  ~VerifiedContents();
+
+  // Returns true if we successfully parsed the verified_contents.json file at
+  // |path| and validated the enclosed signature. The
+  // |ignore_invalid_signature| argument can be set to make this still succeed
+  // if the contents of the file were parsed successfully but the signature did
+  // not validate. (Use with caution!)
+  bool InitFrom(const base::FilePath& path, bool ignore_invalid_signature);
+
+  int block_size() const { return block_size_; }
+  const std::string& extension_id() const { return extension_id_; }
+  const base::Version& version() const { return version_; }
+
+  // This returns a pointer to the binary form of an expected sha256 root hash
+  // for |relative_path| computing using a tree hash algorithm.
+  const std::string* GetTreeHashRoot(const base::FilePath& relative_path);
+
+  // If InitFrom has not been called yet, or was used in "ignore invalid
+  // signature" mode, this can return false.
+  bool valid_signature() { return valid_signature_; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(VerifiedContents);
+
+  // Returns the base64url-decoded "payload" field from the json at |path|, if
+  // the signature was valid (or ignore_invalid_signature was set to true).
+  bool GetPayload(const base::FilePath& path,
+                  std::string* payload,
+                  bool ignore_invalid_signature);
+
+  // The |protected_value| and |payload| arguments should be base64url encoded
+  // strings, and |signature_bytes| should be a byte array. See comments in the
+  // .cc file on GetPayload for where these come from in the overall input
+  // file.
+  bool VerifySignature(const std::string& protected_value,
+                       const std::string& payload,
+                       const std::string& signature_bytes);
+
+  // The public key we should use for signature verification.
+  const uint8* public_key_;
+  const int public_key_size_;
+
+  // Indicates whether the signature was successfully validated or not.
+  bool valid_signature_;
+
+  // The block size used for computing the treehash root hashes.
+  int block_size_;
+
+  // Information about which extension these signed hashes are for.
+  std::string extension_id_;
+  base::Version version_;
+
+  // The expected treehash root hashes for each file.
+  std::map<base::FilePath, std::string> root_hashes_;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_VERIFIED_CONTENTS_H_
diff --git a/extensions/browser/verified_contents_unittest.cc b/extensions/browser/verified_contents_unittest.cc
new file mode 100644
index 0000000..50e2655
--- /dev/null
+++ b/extensions/browser/verified_contents_unittest.cc
@@ -0,0 +1,86 @@
+// 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.
+
+#include <string>
+#include <vector>
+
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "extensions/browser/verified_contents.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_paths.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+namespace {
+
+bool HexStringEquals(std::string hex_string, const std::string* bytes) {
+  if (!bytes)
+    return false;
+  std::vector<uint8> decoded;
+  if (!base::HexStringToBytes(hex_string, &decoded))
+    return false;
+  if (decoded.size() != bytes->size())
+    return false;
+
+  if (bytes->empty())
+    return true;
+
+  return memcmp(vector_as_array(&decoded), bytes->data(), bytes->size()) == 0;
+}
+
+bool GetPublicKey(const base::FilePath& path, std::string* public_key) {
+  std::string public_key_pem;
+  if (!base::ReadFileToString(path, &public_key_pem))
+    return false;
+  if (!Extension::ParsePEMKeyBytes(public_key_pem, public_key))
+    return false;
+  return true;
+}
+
+}  // namespace
+
+TEST(VerifiedContents, Simple) {
+  // Figure out our test data directory.
+  base::FilePath path;
+  PathService::Get(DIR_TEST_DATA, &path);
+  path = path.AppendASCII("content_verifier/");
+
+  // Initialize the VerifiedContents object.
+  std::string public_key;
+  ASSERT_TRUE(GetPublicKey(path.AppendASCII("public_key.pem"), &public_key));
+  VerifiedContents contents(reinterpret_cast<const uint8*>(public_key.data()),
+                            public_key.size());
+  base::FilePath verified_contents_path =
+      path.AppendASCII("verified_contents.json");
+
+  ASSERT_TRUE(contents.InitFrom(verified_contents_path, false));
+
+  // Make sure we get expected values.
+  EXPECT_EQ(contents.block_size(), 4096);
+  EXPECT_EQ(contents.extension_id(), "abcdefghijklmnopabcdefghijklmnop");
+  EXPECT_EQ("1.2.3", contents.version().GetString());
+
+  EXPECT_TRUE(HexStringEquals(
+      "fafcb22089fb8920b383b5f7202508e7065aded1bbc3bbf2882724c5974919fb",
+      contents.GetTreeHashRoot(
+          base::FilePath::FromUTF8Unsafe("manifest.json"))));
+  EXPECT_TRUE(HexStringEquals(
+      "b711e21b9290bcda0f3921f915b428f596f9809db78f7a0507446ef433a7ce2c",
+      contents.GetTreeHashRoot(
+          base::FilePath::FromUTF8Unsafe("background.js"))));
+  EXPECT_TRUE(HexStringEquals(
+      "2f7ecb15b4ff866b7144bec07c664df584e95baca8cff662435a292c99f53595",
+      contents.GetTreeHashRoot(
+          base::FilePath::FromUTF8Unsafe("foo/bar.html"))));
+
+  base::FilePath nonexistent = base::FilePath::FromUTF8Unsafe("nonexistent");
+  EXPECT_TRUE(contents.GetTreeHashRoot(nonexistent) == NULL);
+}
+
+}  // namespace extensions
diff --git a/extensions/common/ad_injection_constants.cc b/extensions/common/ad_injection_constants.cc
index 584f6a8..68ce280 100644
--- a/extensions/common/ad_injection_constants.cc
+++ b/extensions/common/ad_injection_constants.cc
@@ -29,7 +29,7 @@
 // The maximum depth to check when we examine a newly-added element.
 extern const size_t kMaximumDepthToCheck = 5u;
 
-bool ApiCanInjectAds(const char* api) {
+bool ApiCanInjectAds(const std::string& api) {
   return api == kHtmlIframeSrcApiName ||
          api == kHtmlEmbedSrcApiName ||
          EndsWith(api, kAppendChildApiSuffix, true /* case sensitive */);
diff --git a/extensions/common/ad_injection_constants.h b/extensions/common/ad_injection_constants.h
index fe695c7..01dd86b 100644
--- a/extensions/common/ad_injection_constants.h
+++ b/extensions/common/ad_injection_constants.h
@@ -5,6 +5,8 @@
 #ifndef EXTENSIONS_COMMON_AD_INJECTION_CONSTANTS_H_
 #define EXTENSIONS_COMMON_AD_INJECTION_CONSTANTS_H_
 
+#include <string>
+
 #include "base/basictypes.h"
 
 namespace extensions {
@@ -29,7 +31,7 @@
 
 // Returns true if the given |api| can potentially inject ads, and should
 // therefore be examined.
-bool ApiCanInjectAds(const char* api);
+bool ApiCanInjectAds(const std::string& api);
 
 }  // namespace ad_injection_constants
 }  // namespace extensions
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json
index 8dbeb14..c415da8 100644
--- a/extensions/common/api/_api_features.json
+++ b/extensions/common/api/_api_features.json
@@ -9,17 +9,62 @@
 // Note that specifying "web_page", "blessed_web_page", or "all" as a context
 // type will require manually updating chrome/renderer/resources/dispatcher.cc.
 
+// To add a new whitelisted ID, SHA-1 it and force it to uppercase. In Bash:
+//
+// $ echo -n "aaaabbbbccccddddeeeeffffgggghhhh" | \
+// sha1sum | tr '[:lower:]' '[:upper:]'
+// 9A0417016F345C934A1A88F55CA17C05014EEEBA  -
+//
+// Google employees: please update http://go/chrome-api-whitelist to map
+// hashes back to ids.
+
 {
   "dns": {
     "dependencies": ["permission:dns"],
     "contexts": ["blessed_extension"]
   },
-  // TODO(jamescook): Move this to app_shell _api_features.json once that file
-  // exists.
-  "shell": {
+  "runtime": {
+    "channel": "stable",
+    "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
+    "contexts": ["blessed_extension"]
+  },
+  "runtime.getManifest": {
+    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+  },
+  "runtime.connect": {
+    "contexts": "all",
+    "matches": ["<all_urls>"]
+  },
+  "runtime.getURL": {
+    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+  },
+  "runtime.id": {
+    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+  },
+  "runtime.lastError": {
+    "contexts": "all",
+    "extension_types": "all",
+    "matches": ["<all_urls>"]
+  },
+  "runtime.onConnect": {
+    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+  },
+  "runtime.onMessage": {
+    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+  },
+  "runtime.reload": {
+    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+  },
+  "runtime.requestUpdateCheck": {
+    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+  },
+  "runtime.sendMessage": {
+    "contexts": "all",
+    "matches": ["<all_urls>"]
+  },
+  "runtime.setUninstallURL": {
     "channel": "dev",
-    "contexts": ["blessed_extension"],
-    "extension_types": ["platform_app"]
+    "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
   },
   "socket": {
     "dependencies": ["permission:socket"],
@@ -46,5 +91,19 @@
     "channel": "stable",
     "extension_types": "all",
     "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+  },
+  "types": {
+    "channel": "stable",
+    "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
+    "contexts": ["blessed_extension"]
+  },
+  "types.private": {
+    "channel": "dev",
+    "extension_types": ["extension"],
+    "location": "component"
+  },
+  "usb": {
+    "dependencies": ["permission:usb"],
+    "contexts": ["blessed_extension"]
   }
 }
diff --git a/extensions/common/api/_manifest_features.json b/extensions/common/api/_manifest_features.json
index 60d0a2d..271eea7 100644
--- a/extensions/common/api/_manifest_features.json
+++ b/extensions/common/api/_manifest_features.json
@@ -6,6 +6,15 @@
 // See extensions/common/features/* to understand this file, in particular
 // feature.h, simple_feature.h, and base_feature_provider.h.
 
+// To add a new whitelisted ID, SHA-1 it and force it to uppercase. In Bash:
+//
+// $ echo -n "aaaabbbbccccddddeeeeffffgggghhhh" | \
+// sha1sum | tr '[:lower:]' '[:upper:]'
+// 9A0417016F345C934A1A88F55CA17C05014EEEBA  -
+//
+// Google employees: please update http://go/chrome-api-whitelist to map
+// hashes back to ids.
+
 {
   // The default platform app CSP can only be overridden by whitelisted apps.
   // This is a separate key from the top-level content_security_policy one since
diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json
index a1e975b..4a24afe 100644
--- a/extensions/common/api/_permission_features.json
+++ b/extensions/common/api/_permission_features.json
@@ -33,6 +33,12 @@
       ]
     }
   ],
+  // Note: runtime is not actually a permission, but some systems check these
+  // values to verify restrictions.
+  "runtime": {
+    "channel": "stable",
+    "extension_types": ["extension", "legacy_packaged_app", "platform_app"]
+  },
   "socket": [
     {
       "channel": "stable",
@@ -53,5 +59,33 @@
     "channel": "stable",
     "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
     "min_manifest_version": 2
-  }
+  },
+  "usb": [
+    {
+      "channel": "stable",
+      "extension_types": ["platform_app"]
+    },
+    {
+      "channel": "stable",
+      "extension_types": ["extension"],
+      "whitelist": [
+        "496B6890097EB6E19809ADEADD095A8721FBB2E0",  // FIDO U2F APIs
+        "E24F1786D842E91E74C27929B0B3715A4689A473"   // CryptoToken
+      ]
+    }
+  ],
+  "usbDevices": [
+    {
+      "channel": "stable",
+      "extension_types": ["platform_app"]
+    },
+    {
+      "channel": "stable",
+      "extension_types": ["extension"],
+      "whitelist": [
+        "496B6890097EB6E19809ADEADD095A8721FBB2E0",  // FIDO U2F APIs
+        "E24F1786D842E91E74C27929B0B3715A4689A473"   // CryptoToken
+      ]
+    }
+  ]
 }
diff --git a/extensions/common/api/api.gyp b/extensions/common/api/api.gyp
index 4e3c2b0..400701d 100644
--- a/extensions/common/api/api.gyp
+++ b/extensions/common/api/api.gyp
@@ -24,12 +24,14 @@
         'schema_files': [
           'dns.idl',
           'extensions_manifest_types.json',
+          'runtime.json',
           'socket.idl',
           'sockets_tcp.idl',
           'sockets_tcp_server.idl',
           'sockets_udp.idl',
           'storage.json',
           'test.json',
+          'usb.idl',
         ],
         'cc_dir': 'extensions/common/api',
         'root_namespace': 'extensions::core_api',
diff --git a/extensions/common/api/extensions_manifest_types.json b/extensions/common/api/extensions_manifest_types.json
index 24c2df5..0026269 100644
--- a/extensions/common/api/extensions_manifest_types.json
+++ b/extensions/common/api/extensions_manifest_types.json
@@ -13,6 +13,32 @@
     },
     "types": [
       {
+        "id": "ExternallyConnectable",
+        "type": "object",
+        // Note: description commented out because externally_connectable.html
+        // already describes it, and the repetition looks odd.
+        // "description": "The <code>externally_connectable</code> manifest property declares which extensions, apps, and web pages can connect to your extension via $(ref:runtime.connect) and $(ref:runtime.sendMessage).",
+        "properties": {
+          "ids": {
+            "description": "<p>The IDs of extensions or apps that are allowed to connect. If left empty or unspecified, no extensions or apps can connect.</p><p>The wildcard <code>\"*\"</code> will allow all extensions and apps to connect.</p>",
+            "optional": true,
+            "type": "array",
+            "items": {"type": "string"}
+          },
+          "matches": {
+            "description": "<p>The URL patterns for <em>web pages</em> that are allowed to connect. <em>This does not affect content scripts.</em> If left empty or unspecified, no web pages can connect.</p><p>Patterns cannot include wildcard domains nor subdomains of <a href=\"http://publicsuffix.org/list/\">(effective) top level domains</a>; <code>*://google.com/*</code> and <code>http://*.chromium.org/*</code> are valid, while <code>&lt;all_urls&gt;</code>, <code>http://*/*</code>, <code>*://*.com/*</code>, and even <code>http://*.appspot.com/*</code> are not.</p>",
+            "optional": true,
+            "type": "array",
+            "items": {"type": "string"}
+          },
+          "accepts_tls_channel_id": {
+            "description": "If <code>true</code>, messages sent via $(ref:runtime.connect) or $(ref:runtime.sendMessage) will set $(ref:runtime.MessageSender.tlsChannelId) if those methods request it to be. If <code>false</code>, $(ref:runtime.MessageSender.tlsChannelId) will never be set under any circumstance.",
+            "optional": true,
+            "type": "boolean"
+          }
+        }
+      },
+      {
         "id": "SocketHostPatterns",
         "description": "<p>A single string or a list of strings representing host:port patterns.</p>",
         "choices": [
diff --git a/extensions/common/api/runtime.json b/extensions/common/api/runtime.json
new file mode 100644
index 0000000..6009576
--- /dev/null
+++ b/extensions/common/api/runtime.json
@@ -0,0 +1,482 @@
+// 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.
+
+// Note: Many of these functions and events are implemented by hand and should
+// not elicit any code generation from the schema compiler. These items are
+// marked "nocompile."
+[
+  {
+    "namespace": "runtime",
+    "description": "Use the <code>chrome.runtime</code> API to retrieve the background page, return details about the manifest, and listen for and respond to events in the app or extension lifecycle. You can also use this API to convert the relative path of URLs to fully-qualified URLs.",
+    "types": [
+      {
+        "id": "Port",
+        "type": "object",
+        "nocompile": true,
+        "description": "An object which allows two way communication with other pages.",
+        "properties": {
+          "name": {"type": "string"},
+          "disconnect": { "type": "function" },
+          "onDisconnect": { "$ref": "events.Event" },
+          "onMessage": { "$ref": "events.Event" },
+          "postMessage": {"type": "function"},
+          "sender": {
+            "$ref": "MessageSender",
+            "optional": true,
+            "description": "This property will <b>only</b> be present on ports passed to onConnect/onConnectExternal listeners."
+          }
+        },
+        "additionalProperties": { "type": "any"}
+      },
+      {
+        "id": "MessageSender",
+        "type": "object",
+        "nocompile": true,
+        "description": "An object containing information about the script context that sent a message or request.",
+        "properties": {
+          "tab": {"$ref": "tabs.Tab", "optional": true, "description": "The $(ref:tabs.Tab) which opened the connection, if any. This property will <strong>only</strong> be present when the connection was opened from a tab (including content scripts), and <strong>only</strong> if the receiver is an extension, not an app."},
+          "id": {"type": "string", "optional": true, "description": "The ID of the extension or app that opened the connection, if any."},
+          "url": {"type": "string", "optional": true, "description": "The URL of the page or frame that opened the connection, if any. This property will <strong>only</strong> be present when the connection was opened from a tab or content script."},
+          "tlsChannelId": {"type": "string", "optional": true, "description": "The TLS channel ID of the web page that opened the connection, if requested by the extension or app, and if available."}
+        }
+      },
+      {
+        "id": "PlatformInfo",
+        "type": "object",
+        "description": "An object containing information about the current platform.",
+        "properties": {
+          "os": {
+            "type": "string",
+            "description": "The operating system chrome is running on.",
+            "enum": ["mac", "win", "android", "cros", "linux", "openbsd"]
+          },
+          "arch": {
+            "type": "string",
+            "enum": ["arm", "x86-32", "x86-64"],
+            "description": "The machine's processor architecture."
+          },
+          "nacl_arch" : {
+            "description": "The native client architecture. This may be different from arch on some platforms.",
+            "type": "string",
+            "enum": ["arm", "x86-32", "x86-64"]
+          }
+        }
+      }
+    ],
+    "properties": {
+      "lastError": {
+        "type": "object",
+        "optional": true,
+        "description": "This will be defined during an API method callback if there was an error",
+        "properties": {
+          "message": {
+            "optional": true,
+            "type": "string",
+            "description": "Details about the error which occurred."
+          }
+        }
+      },
+      "id": {
+        "type": "string",
+        "description": "The ID of the extension/app."
+      }
+    },
+    "functions": [
+      {
+        "name": "getBackgroundPage",
+        "type": "function",
+        "description": "Retrieves the JavaScript 'window' object for the background page running inside the current extension/app. If the background page is an event page, the system will ensure it is loaded before calling the callback. If there is no background page, an error is set.",
+        "parameters": [
+          {
+            "type": "function",
+            "name": "callback",
+            "parameters": [
+              {
+                "name": "backgroundPage",
+                // Note: Only optional because we don't support validation
+                // for custom callbacks.
+                "optional": true,
+                "type": "object",
+                "isInstanceOf": "Window",
+                "additionalProperties": { "type": "any" },
+                "description": "The JavaScript 'window' object for the background page."
+              }
+            ]
+          }
+        ]
+      },
+      {
+        "name": "getManifest",
+        "description": "Returns details about the app or extension from the manifest. The object returned is a serialization of the full <a href=\"manifest.html\">manifest file</a>.",
+        "type": "function",
+        "nocompile": true,
+        "parameters": [],
+        "returns": {
+          "type": "object",
+          "properties": {},
+          "additionalProperties": { "type": "any" },
+          "description": "The manifest details."
+        }
+      },
+      {
+        "name": "getURL",
+        "type": "function",
+        "nocompile": true,
+        "description": "Converts a relative path within an app/extension install directory to a fully-qualified URL.",
+        "parameters": [
+          {
+            "type": "string",
+            "name": "path",
+            "description": "A path to a resource within an app/extension expressed relative to its install directory."
+          }
+        ],
+        "returns": {
+          "type": "string",
+          "description": "The fully-qualified URL to the resource."
+        }
+      },
+      {
+        "name": "setUninstallURL",
+        "type": "function",
+        "description": "Sets the URL to be visited upon uninstallation. This may be used to clean up server-side data, do analytics, and implement surveys. Maximum 255 characters.",
+        "parameters": [
+          {
+            "type": "string",
+            "name": "url",
+            "maxLength": 255
+          }
+        ]
+      },
+      {
+        "name": "reload",
+        "description": "Reloads the app or extension.",
+        "type": "function",
+        "parameters": []
+      },
+      {
+        "name": "requestUpdateCheck",
+        "type": "function",
+        "description": "Requests an update check for this app/extension.",
+        "parameters": [
+          {
+            "type": "function",
+            "name": "callback",
+            "parameters": [
+              {
+                "name": "status",
+                "type": "string",
+                "enum": ["throttled", "no_update", "update_available"],
+                "description": "Result of the update check."
+              },
+              {
+                "name": "details",
+                "type": "object",
+                "optional": true,
+                "properties": {
+                  "version": {
+                    "type": "string",
+                    "description": "The version of the available update."
+                  }
+                },
+                "description": "If an update is available, this contains more information about the available update."
+              }
+            ]
+          }
+        ]
+      },
+      {
+        "name": "restart",
+        "description": "Restart the ChromeOS device when the app runs in kiosk mode. Otherwise, it's no-op.",
+        "type": "function",
+        "parameters": []
+      },
+      {
+        "name": "connect",
+        "type": "function",
+        "nocompile": true,
+        "description": "Attempts to connect to connect listeners within an extension/app (such as the background page), or other extensions/apps. This is useful for content scripts connecting to their extension processes, inter-app/extension communication, and <a href=\"manifest/externally_connectable.html\">web messaging</a>. Note that this does not connect to any listeners in a content script. Extensions may connect to content scripts embedded in tabs via $(ref:tabs.connect).",
+        "parameters": [
+          {"type": "string", "name": "extensionId", "optional": true, "description": "The ID of the extension or app to connect to. If omitted, a connection will be attempted with your own extension. Required if sending messages from a web page for <a href=\"manifest/externally_connectable.html\">web messaging</a>."},
+          {
+            "type": "object",
+            "name": "connectInfo",
+            "properties": {
+              "name": { "type": "string", "optional": true, "description": "Will be passed into onConnect for processes that are listening for the connection event." },
+              "includeTlsChannelId": { "type": "boolean", "optional": true, "description": "Whether the TLS channel ID will be passed into onConnectExternal for processes that are listening for the connection event." }
+            },
+            "optional": true
+          }
+        ],
+        "returns": {
+          "$ref": "Port",
+          "description": "Port through which messages can be sent and received. The port's $(ref:runtime.Port onDisconnect) event is fired if the extension/app does not exist. "
+        }
+      },
+      {
+        "name": "connectNative",
+        "type": "function",
+        "nocompile": true,
+        "description": "Connects to a native application in the host machine.",
+        "parameters": [
+          {
+            "type": "string",
+            "name": "application",
+            "description": "The name of the registered application to connect to."
+          }
+        ],
+        "returns": {
+          "$ref": "Port",
+          "description": "Port through which messages can be sent and received with the application"
+        }
+      },
+      {
+        "name": "sendMessage",
+        "type": "function",
+        "nocompile": true,
+        "allowAmbiguousOptionalArguments": true,
+        "description": "Sends a single message to event listeners within your extension/app or a different extension/app. Similar to $(ref:runtime.connect) but only sends a single message, with an optional response. If sending to your extension, the $(ref:runtime.onMessage) event will be fired in each page, or $(ref:runtime.onMessageExternal), if a different extension. Note that extensions cannot send messages to content scripts using this method. To send messages to content scripts, use $(ref:tabs.sendMessage).",
+        "parameters": [
+          {"type": "string", "name": "extensionId", "optional": true, "description": "The ID of the extension/app to send the message to. If omitted, the message will be sent to your own extension/app. Required if sending messages from a web page for <a href=\"manifest/externally_connectable.html\">web messaging</a>."},
+          { "type": "any", "name": "message" },
+          {
+            "type": "object",
+            "name": "options",
+            "properties": {
+              "includeTlsChannelId": { "type": "boolean", "optional": true, "description": "Whether the TLS channel ID will be passed into onMessageExternal for processes that are listening for the connection event." }
+            },
+            "optional": true
+          },
+          {
+            "type": "function",
+            "name": "responseCallback",
+            "optional": true,
+            "parameters": [
+              {
+                "name": "response",
+                "type": "any",
+                "description": "The JSON response object sent by the handler of the message. If an error occurs while connecting to the extension, the callback will be called with no arguments and $(ref:runtime.lastError) will be set to the error message."
+              }
+            ]
+          }
+        ]
+      },
+      {
+        "name": "sendNativeMessage",
+        "type": "function",
+        "nocompile": true,
+        "description": "Send a single message to a native application.",
+        "parameters": [
+          {
+            "name": "application",
+            "description": "The name of the native messaging host.",
+            "type": "string"
+          },
+          {
+            "name": "message",
+            "description": "The message that will be passed to the native messaging host.",
+            "type": "object",
+            "additionalProperties": {
+              "type": "any"
+            }
+          },
+          {
+            "type": "function",
+            "name": "responseCallback",
+            "optional": true,
+            "parameters": [
+              {
+                "name": "response",
+                "type": "any",
+                "description": "The response message sent by the native messaging host. If an error occurs while connecting to the native messaging host, the callback will be called with no arguments and $(ref:runtime.lastError) will be set to the error message.",
+                "additionalProperties": {
+                  "type": "any"
+                }
+              }
+            ]
+          }
+        ]
+      },
+      {
+        "name": "getPlatformInfo",
+        "type": "function",
+        "description": "Returns information about the current platform.",
+        "parameters": [
+          {
+            "type": "function",
+            "name": "callback",
+            "description": "Called with results",
+            "parameters": [
+              {
+                "name": "platformInfo",
+                "$ref": "PlatformInfo"
+              }
+            ]
+          }
+        ]
+      },
+      {
+        "name": "getPackageDirectoryEntry",
+        "type": "function",
+        "description": "Returns a DirectoryEntry for the package directory.",
+        "parameters": [
+          {
+            "type": "function",
+            "name": "callback",
+            "parameters": [
+              {
+                "name": "directoryEntry",
+                "type": "object",
+                "additionalProperties": { "type": "any" },
+                "isInstanceOf": "DirectoryEntry"
+              }
+            ]
+          }
+        ]
+      }
+    ],
+    "events": [
+      {
+        "name": "onStartup",
+        "type": "function",
+        "description": "Fired when a profile that has this extension installed first starts up. This event is not fired when an incognito profile is started, even if this extension is operating in 'split' incognito mode."
+      },
+      {
+        "name": "onInstalled",
+        "type": "function",
+        "description": "Fired when the extension is first installed, when the extension is updated to a new version, and when Chrome is updated to a new version.",
+        "parameters": [
+          {
+            "type": "object",
+            "name": "details",
+            "properties": {
+              "reason": {
+                "type": "string",
+                "enum": ["install", "update", "chrome_update"],
+                "description": "The reason that this event is being dispatched."
+              },
+              "previousVersion": {
+                "type": "string",
+                "optional": true,
+                "description": "Indicates the previous version of the extension, which has just been updated. This is present only if 'reason' is 'update'."
+              }
+            }
+          }
+        ]
+      },
+      {
+        "name": "onSuspend",
+        "type": "function",
+        "description": "Sent to the event page just before it is unloaded. This gives the extension opportunity to do some clean up. Note that since the page is unloading, any asynchronous operations started while handling this event are not guaranteed to complete. If more activity for the event page occurs before it gets unloaded the onSuspendCanceled event will be sent and the page won't be unloaded. "
+      },
+      {
+        "name": "onSuspendCanceled",
+        "type": "function",
+        "description": "Sent after onSuspend to indicate that the app won't be unloaded after all."
+      },
+      {
+        "name": "onUpdateAvailable",
+        "type": "function",
+        "description": "Fired when an update is available, but isn't installed immediately because the app is currently running. If you do nothing, the update will be installed the next time the background page gets unloaded, if you want it to be installed sooner you can explicitly call chrome.runtime.reload().",
+        "parameters": [
+          {
+            "type": "object",
+            "name": "details",
+            "properties": {
+              "version": {
+                "type": "string",
+                "description": "The version number of the available update."
+              }
+            },
+            "additionalProperties": { "type": "any" },
+            "description": "The manifest details of the available update."
+          }
+        ]
+      },
+      {
+        // TODO(xiyuan): onBrowserUpdateAvailable is deprecated in favor of
+        // onRestartRequired. We should remove it when we are sure it is unused.
+        "name": "onBrowserUpdateAvailable",
+        "type": "function",
+        "description": "Fired when a Chrome update is available, but isn't installed immediately because a browser restart is required.",
+        "deprecated": "Please use $(ref:runtime.onRestartRequired).",
+        "parameters": []
+      },
+      {
+        "name": "onConnect",
+        "type": "function",
+        "nocompile": true,
+        "options": {
+          "unmanaged": true
+        },
+        "description": "Fired when a connection is made from either an extension process or a content script.",
+        "parameters": [
+          {"$ref": "Port", "name": "port"}
+        ]
+      },
+      {
+        "name": "onConnectExternal",
+        "type": "function",
+        "nocompile": true,
+        "options": {
+          "unmanaged": true
+        },
+        "description": "Fired when a connection is made from another extension.",
+        "parameters": [
+          {"$ref": "Port", "name": "port"}
+        ]
+      },
+      {
+        "name": "onMessage",
+        "type": "function",
+        "options": {
+          "unmanaged": true
+        },
+        "nocompile": true,
+        "description": "Fired when a message is sent from either an extension process or a content script.",
+        "parameters": [
+          {"name": "message", "type": "any", "optional": true, "description": "The message sent by the calling script."},
+          {"name": "sender", "$ref": "MessageSender" },
+          {"name": "sendResponse", "type": "function", "description": "Function to call (at most once) when you have a response. The argument should be any JSON-ifiable object. If you have more than one <code>onMessage</code> listener in the same document, then only one may send a response. This function becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until <code>sendResponse</code> is called)." }
+        ],
+        "returns": {
+          "type": "boolean",
+          "optional": true,
+          "description": "Return true from the event listener if you wish to call <code>sendResponse</code> after the event listener returns."
+        }
+      },
+      {
+        "name": "onMessageExternal",
+        "type": "function",
+        "options": {
+          "unmanaged": true
+        },
+        "nocompile": true,
+        "description": "Fired when a message is sent from another extension/app. Cannot be used in a content script.",
+        "parameters": [
+          {"name": "message", "type": "any", "optional": true, "description": "The message sent by the calling script."},
+          {"name": "sender", "$ref": "MessageSender" },
+          {"name": "sendResponse", "type": "function", "description": "Function to call (at most once) when you have a response. The argument should be any JSON-ifiable object. If you have more than one <code>onMessage</code> listener in the same document, then only one may send a response. This function becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until <code>sendResponse</code> is called)." }
+        ],
+        "returns": {
+          "type": "boolean",
+          "optional": true,
+          "description": "Return true from the event listener if you wish to call <code>sendResponse</code> after the event listener returns."
+        }
+      },
+      {
+        "name": "onRestartRequired",
+        "type": "function",
+        "description": "Fired when an app or the device that it runs on needs to be restarted. The app should close all its windows at its earliest convenient time to let the restart to happen. If the app does nothing, a restart will be enforced after a 24-hour grace period has passed. Currently, this event is only fired for Chrome OS kiosk apps.",
+        "parameters": [
+          {
+            "type": "string",
+            "name": "reason",
+            "description": "The reason that the event is being dispatched. 'app_update' is used when the restart is needed because the application is updated to a newer version. 'os_update' is used when the restart is needed because the browser/OS is updated to a newer version. 'periodic' is used when the system runs for more than the permitted uptime set in the enterprise policy.",
+            "enum": ["app_update", "os_update", "periodic"]
+          }
+        ]
+      }
+    ]
+  }
+]
diff --git a/extensions/common/api/test.json b/extensions/common/api/test.json
index 4e09054..4ede098 100644
--- a/extensions/common/api/test.json
+++ b/extensions/common/api/test.json
@@ -373,6 +373,22 @@
             ]
           }
         ]
+      },
+      {
+        "name": "setExceptionHandler",
+        "type": "function",
+        "description": "Sets the function to be called when an exception occurs. By default this is a function which fails the test. This is reset for every test run through $ref:test.runTests.",
+        "nocompile": true,
+        "parameters": [
+          {
+            "type": "function",
+            "name": "callback",
+            "parameters": [
+              {"type": "string", "name": "message"},
+              {"type": "any", "name": "exception"}
+            ]
+          }
+        ]
       }
     ],
     "events": [
diff --git a/extensions/common/api/usb.idl b/extensions/common/api/usb.idl
new file mode 100644
index 0000000..278171e
--- /dev/null
+++ b/extensions/common/api/usb.idl
@@ -0,0 +1,307 @@
+// 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.
+
+// Use the <code>chrome.usb</code> API to interact with connected USB
+// devices. This API provides access to USB operations from within the context
+// of an app. Using this API, apps can function as drivers for hardware devices.
+namespace usb {
+
+  // Direction, Recipient, RequestType, and TransferType all map to their
+  // namesakes within the USB specification.
+  enum Direction {in, out};
+  enum Recipient {device, _interface, endpoint, other};
+  enum RequestType {standard, class, vendor, reserved};
+  enum TransferType {control, interrupt, isochronous, bulk};
+
+  // For isochronous mode, SynchronizationType and UsageType map to their
+  // namesakes within the USB specification.
+  enum SynchronizationType {asynchronous, adaptive, synchronous};
+  enum UsageType {data, feedback, explicitFeedback};
+
+  // Returned by |getDevices| to identify a connected USB device.
+  dictionary Device {
+    // The id of the USB device. It remains unchanged until the device is
+    // unplugged.
+    long device;
+    long vendorId;
+    long productId;
+  };
+
+  // Returned by |openDevice| to be used for USB communication.
+  // Every time a device is opened, a new connection handle is created.
+  //
+  // A connection handle represents the underlying data structure that contains
+  // all the data we need to communicate with a USB device, including the status
+  // of interfaces, the pending transfers, the descriptors, and etc. A connectin
+  // handle id is different from a USB device id.
+  //
+  // All connection handles can work together if the device allows it.
+  // The connection handle will be automatically closed when the app is reloaded
+  // or suspended.
+  //
+  // When a connection handle is closed, all the interfaces it claimed will be
+  // released and all the transfers in progress will be canceled immediately.
+  dictionary ConnectionHandle {
+    // The id of the USB connection handle.
+    long handle;
+    long vendorId;
+    long productId;
+  };
+
+  dictionary EndpointDescriptor {
+    long address;
+    TransferType type;
+    Direction direction;
+    long maximumPacketSize;
+
+    // Used for isochronous mode.
+    SynchronizationType? synchronization;
+    UsageType? usage;
+
+    // If this is an interrupt endpoint, this will be 1-255.
+    long? pollingInterval;
+  };
+
+  dictionary InterfaceDescriptor {
+    long interfaceNumber;
+    long alternateSetting;
+    long interfaceClass;
+    long interfaceSubclass;
+    long interfaceProtocol;
+    DOMString? description;
+    EndpointDescriptor[] endpoints;
+  };
+
+  // ControlTransferInfo represents that parameters to a single USB control
+  // transfer.
+  dictionary ControlTransferInfo {
+    // The direction of this transfer.
+    Direction direction;
+
+    // The intended recipient for this transfer.
+    Recipient recipient;
+
+    // The type of this request.
+    RequestType requestType;
+
+    long request;
+    long value;
+    long index;
+
+    // If this transfer is an input transfer, then this field must be set to
+    // indicate the expected data length. If this is an output transfer, then
+    // this field is ignored.
+    long? length;
+
+    // The data payload carried by this transfer. If this is an output transfer
+    // then this field must be set.
+    ArrayBuffer? data;
+  };
+
+  // GenericTransferInfo is used by both bulk and interrupt transfers to
+  // specify the parameters of the transfer.
+  dictionary GenericTransferInfo {
+    // The direction of this transfer.
+    Direction direction;
+
+    long endpoint;
+
+    // If this is an input transfer then this field indicates the size of the
+    // input buffer. If this is an output transfer then this field is ignored.
+    long? length;
+
+    // If this is an output transfer then this field must be populated.
+    // Otherwise, it will be ignored.
+    ArrayBuffer? data;
+  };
+
+  // IsochronousTransferInfo describes a single multi-packet isochronous
+  // transfer.
+  dictionary IsochronousTransferInfo {
+    // All of the normal transfer parameters are encapsulated in the
+    // transferInfo parameters. Note that the data specified in this parameter
+    // block is split along packetLength boundaries to form the individual
+    // packets of the transfer.
+    GenericTransferInfo transferInfo;
+
+    // The total number of packets in this transfer.
+    long packets;
+
+    // The length of each of the packets in this transfer.
+    long packetLength;
+  };
+
+  dictionary TransferResultInfo {
+    // A value of 0 indicates that the transfer was a success. Other values
+    // indicate failure.
+    long? resultCode;
+
+    // If the transfer was an input transfer then this field will contain all
+    // of the input data requested.
+    ArrayBuffer? data;
+  };
+
+  // Describes the properties of devices which are found via |getDevices|.
+  dictionary EnumerateDevicesOptions {
+    long vendorId;
+    long productId;
+  };
+  
+  // Describes the properties of devices which are found via |findDevices|.
+  dictionary EnumerateDevicesAndRequestAccessOptions {
+    long vendorId;
+    long productId;
+    // The interface id to request access against.
+    // Only available on ChromeOS. It has no effect on other platforms.
+    long? interfaceId;
+  };
+
+  callback VoidCallback = void ();
+  callback GetDevicesCallback = void (Device[] devices);
+  callback RequestAccessCallback = void (boolean sucess);
+  callback OpenDeviceCallback = void (ConnectionHandle handle);
+  callback FindDevicesCallback = void (ConnectionHandle[] handles);
+  callback ListInterfacesCallback = void (InterfaceDescriptor[] descriptors);
+  callback CloseDeviceCallback = void ();
+  callback TransferCallback = void (TransferResultInfo info);
+  callback ResetDeviceCallback = void(boolean result);
+
+  interface Functions {
+    // Lists USB devices specified by vendorId/productId/interfaceId tuple.
+    // |options|: The properties to search for on target devices.
+    // |callback|: Invoked with a list of |Device|s on complete.
+    static void getDevices(EnumerateDevicesOptions options,
+                           GetDevicesCallback callback);
+
+    // This method is ChromeOS specific. Calling this method on other platforms
+    // will fail.
+    // Requests access from the permission broker to an OS claimed device if the
+    // given interface on the device is not claimed.
+    //
+    // |device|: The device to request access to.
+    // |interfaceId|: 
+    static void requestAccess(Device device,
+                              long interfaceId,
+                              RequestAccessCallback callback);
+
+    // Opens a USB device returned by |getDevices|.
+    // |device|: The device to open.
+    // |callback|: Invoked with the created ConnectionHandle on complete.
+    static void openDevice(Device device, OpenDeviceCallback callback);
+
+    // Finds USB devices specified by the vendorId/productId/interfaceId tuple
+    // and, if permissions allow, opens them for use.
+    //
+    // On Chrome OS, you can specify the interfaceId. In that case the method
+    // will request access from permission broker in the same way as in
+    // |requestUsbAcess|.
+    //
+    // If the access request is rejected, or the device is failed to be opened,
+    // its connection handle will not be created or returned.
+    //
+    // Calling this method is equivalent to calling |getDevices| followed by
+    // a series of |requestAccess| (if it is on ChromeOs) and |openDevice|
+    // calls, and returning all the successfully opened connection handles.
+    //
+    // |options|: The properties to search for on target devices.
+    // |callback|: Invoked with the opened ConnectionHandle on complete.
+    static void findDevices(EnumerateDevicesAndRequestAccessOptions options,
+                            FindDevicesCallback callback);
+
+    // Closes a connection handle. Invoking operations on a device after it
+    // has been closed is a safe operation, but causes no action to be taken.
+    // |handle|: The connection handle to close.
+    // |callback|: The callback to invoke once the device is closed.
+    static void closeDevice(ConnectionHandle handle,
+                            optional CloseDeviceCallback callback);
+
+    // Lists all the interfaces on the USB device.
+    // |handle|: The device from which the interfaces should be listed.
+    // |callback|: The callback to invoke when the interfaces are enumerated.
+    static void listInterfaces(ConnectionHandle handle,
+                               ListInterfacesCallback callback);
+
+    // Claims an interface on the specified USB device.
+    // Before you can transfer data with endpoints, you must claim their parent
+    // interfaces. Only one connection handle on the same host can claim each
+    // interface. If the interface is already claimed, this call will fail.
+    //
+    // You shall call releaseInterface when the interface is not needed anymore.
+    //
+    // |handle|: The device on which the interface is to be claimed.
+    // |interface|: The interface number to be claimed.
+    // |callback|: The callback to invoke once the interface is claimed.
+    static void claimInterface(ConnectionHandle handle, long interfaceNumber,
+                               VoidCallback callback);
+
+    // Releases a claim to an interface on the provided device.
+    // |handle|: The device on which the interface is to be released.
+    // |interface|: The interface number to be released.
+    // |callback|: The callback to invoke once the interface is released.
+    static void releaseInterface(ConnectionHandle handle, long interfaceNumber,
+                                 VoidCallback callback);
+
+    // Selects an alternate setting on a previously claimed interface on a
+    // device.
+    // |handle|: The device on which the interface settings are to be set.
+    // |interface|: The interface number to be set.
+    // |alternateSetting|: The alternate setting to set.
+    // |callback|: The callback to invoke once the interface setting is set.
+    static void setInterfaceAlternateSetting(ConnectionHandle handle,
+                                             long interfaceNumber,
+                                             long alternateSetting,
+                                             VoidCallback callback);
+
+    // Performs a control transfer on the specified device. See the
+    // ControlTransferInfo structure for the parameters required to make a
+    // transfer.
+    //
+    // Conceptually control transfer talks to the device itself. You do not need
+    // to claim interface 0 to perform a control transfer.
+    //
+    // |handle|: A connection handle to make the transfer on.
+    // |transferInfo|: The parameters to the transfer. See ControlTransferInfo.
+    // |callback|: Invoked once the transfer has completed.
+    static void controlTransfer(ConnectionHandle handle,
+                                ControlTransferInfo transferInfo,
+                                TransferCallback callback);
+
+    // Performs a bulk transfer on the specified device.
+    // |handle|: A connection handle to make the transfer on.
+    // |transferInfo|: The parameters to the transfer. See GenericTransferInfo.
+    // |callback|: Invoked once the transfer has completed.
+    static void bulkTransfer(ConnectionHandle handle,
+                             GenericTransferInfo transferInfo,
+                             TransferCallback callback);
+
+    // Performs an interrupt transfer on the specified device.
+    // |handle|: A connection handle to make the transfer on.
+    // |transferInfo|: The parameters to the transfer. See GenericTransferInfo.
+    // |callback|: Invoked once the transfer has completed.
+    static void interruptTransfer(ConnectionHandle handle,
+                                  GenericTransferInfo transferInfo,
+                                  TransferCallback callback);
+
+    // Performs an isochronous transfer on the specific device.
+    // |handle|: A connection handle to make the transfer on.
+    // |transferInfo|: The parameters to the transfer. See
+    // IsochronousTransferInfo.
+    // |callback|: Invoked once the transfer has been completed.
+    static void isochronousTransfer(ConnectionHandle handle,
+                                    IsochronousTransferInfo transferInfo,
+                                    TransferCallback callback);
+
+    // Tries to reset the USB device and restores it to the previous status.
+    // If the reset fails, the given connection handle will be closed and the 
+    // USB device will appear to be disconnected then reconnected. 
+    // In that case you must call |getDevices| or |findDevices| again to acquire
+    // the device.
+    //
+    // |handle|: A connection handle to reset.
+    // |callback|: Invoked once the device is reset with a boolean indicating
+    // whether the reset is completed successfully.
+    static void resetDevice(ConnectionHandle handle,
+                            ResetDeviceCallback callback);
+  };
+};
diff --git a/extensions/common/extension.h b/extensions/common/extension.h
index 3354fa6..10df63c 100644
--- a/extensions/common/extension.h
+++ b/extensions/common/extension.h
@@ -99,7 +99,8 @@
     DISABLE_KNOWN_DISABLED = 1 << 7,
     DISABLE_NOT_VERIFIED = 1 << 8,  // Disabled because we could not verify
                                     // the install.
-    DISABLE_GREYLIST = 1 << 9
+    DISABLE_GREYLIST = 1 << 9,
+    DISABLE_CORRUPTED = 1 << 10,
   };
 
   enum InstallType {
diff --git a/extensions/common/extension_api.cc b/extensions/common/extension_api.cc
index 39e37ff..f2483b9 100644
--- a/extensions/common/extension_api.cc
+++ b/extensions/common/extension_api.cc
@@ -230,6 +230,8 @@
 
   // Schemas to be loaded from resources.
   CHECK(unloaded_schemas_.empty());
+  RegisterSchemaResource("accessibilityPrivate",
+                         IDR_EXTENSION_API_JSON_ACCESSIBILITYPRIVATE);
   RegisterSchemaResource("app", IDR_EXTENSION_API_JSON_APP);
   RegisterSchemaResource("browserAction", IDR_EXTENSION_API_JSON_BROWSERACTION);
   RegisterSchemaResource("commands", IDR_EXTENSION_API_JSON_COMMANDS);
diff --git a/extensions/common/extensions_client.h b/extensions/common/extensions_client.h
index 8207895..6b9c534 100644
--- a/extensions/common/extensions_client.h
+++ b/extensions/common/extensions_client.h
@@ -39,9 +39,6 @@
   // in-process.
   virtual void Initialize() = 0;
 
-  // Returns a PermissionsProvider to initialize the permissions system.
-  virtual const PermissionsProvider& GetPermissionsProvider() const = 0;
-
   // Returns the global PermissionMessageProvider to use to provide permission
   // warning strings.
   virtual const PermissionMessageProvider& GetPermissionMessageProvider()
diff --git a/extensions/common/features/complex_feature.cc b/extensions/common/features/complex_feature.cc
index ae7327c..eeb4f77 100644
--- a/extensions/common/features/complex_feature.cc
+++ b/extensions/common/features/complex_feature.cc
@@ -9,6 +9,7 @@
 ComplexFeature::ComplexFeature(scoped_ptr<FeatureList> features) {
   DCHECK_GT(features->size(), 0UL);
   features_.swap(*features);
+  no_parent_ = features_[0]->no_parent();
 
 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
   // Verify GetContexts, IsInternal, & IsBlockedInServiceWorker are consistent
@@ -29,6 +30,9 @@
     DCHECK(first_blocked_in_service_worker == (*it)->IsBlockedInServiceWorker())
         << "Complex feature must have consistent values of "
            "blocked_in_service_worker across all sub features.";
+    DCHECK(no_parent_ == (*it)->no_parent())
+        << "Complex feature must have consistent values of "
+           "no_parent across all sub features.";
   }
 #endif
 }
@@ -82,6 +86,16 @@
   return first_availability;
 }
 
+bool ComplexFeature::IsIdInBlacklist(const std::string& extension_id) const {
+  for (FeatureList::const_iterator it = features_.begin();
+       it != features_.end();
+       ++it) {
+    if ((*it)->IsIdInBlacklist(extension_id))
+      return true;
+  }
+  return false;
+}
+
 bool ComplexFeature::IsIdInWhitelist(const std::string& extension_id) const {
   for (FeatureList::const_iterator it = features_.begin();
        it != features_.end();
diff --git a/extensions/common/features/complex_feature.h b/extensions/common/features/complex_feature.h
index 25f4907..5d12644 100644
--- a/extensions/common/features/complex_feature.h
+++ b/extensions/common/features/complex_feature.h
@@ -36,6 +36,7 @@
                                             const GURL& url,
                                             Platform platform) const OVERRIDE;
 
+  virtual bool IsIdInBlacklist(const std::string& extension_id) const OVERRIDE;
   virtual bool IsIdInWhitelist(const std::string& extension_id) const OVERRIDE;
   virtual bool IsBlockedInServiceWorker() const OVERRIDE;
 
diff --git a/extensions/common/features/feature.h b/extensions/common/features/feature.h
index 595f22f..0f0f35a 100644
--- a/extensions/common/features/feature.h
+++ b/extensions/common/features/feature.h
@@ -69,6 +69,7 @@
     INVALID_MAX_MANIFEST_VERSION,
     NOT_PRESENT,
     UNSUPPORTED_CHANNEL,
+    FOUND_IN_BLACKLIST,
   };
 
   // Container for AvailabiltyResult that also exposes a user-visible error
@@ -151,6 +152,7 @@
                                              const GURL& url,
                                              Context context) const = 0;
 
+  virtual bool IsIdInBlacklist(const std::string& extension_id) const = 0;
   virtual bool IsIdInWhitelist(const std::string& extension_id) const = 0;
 
  protected:
diff --git a/extensions/common/features/simple_feature.cc b/extensions/common/features/simple_feature.cc
index 8ef18f8..eab3ae9 100644
--- a/extensions/common/features/simple_feature.cc
+++ b/extensions/common/features/simple_feature.cc
@@ -227,7 +227,8 @@
     : location_(UNSPECIFIED_LOCATION),
       min_manifest_version_(0),
       max_manifest_version_(0),
-      has_parent_(false) {}
+      has_parent_(false),
+      component_extensions_auto_granted_(true) {}
 
 SimpleFeature::~SimpleFeature() {}
 
@@ -237,6 +238,7 @@
 
 std::string SimpleFeature::Parse(const base::DictionaryValue* value) {
   ParseURLPatterns(value, "matches", &matches_);
+  ParseSet(value, "blacklist", &blacklist_);
   ParseSet(value, "whitelist", &whitelist_);
   ParseSet(value, "dependencies", &dependencies_);
   ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_,
@@ -253,6 +255,10 @@
   no_parent_ = false;
   value->GetBoolean("noparent", &no_parent_);
 
+  component_extensions_auto_granted_ = true;
+  value->GetBoolean("component_extensions_auto_granted",
+                    &component_extensions_auto_granted_);
+
   if (matches_.is_empty() && contexts_.count(WEB_PAGE_CONTEXT) != 0) {
     return name() + ": Allowing web_page contexts requires supplying a value " +
         "for matches.";
@@ -287,9 +293,14 @@
     return CreateAvailability(INVALID_TYPE, type);
   }
 
+  if (IsIdInBlacklist(extension_id))
+    return CreateAvailability(FOUND_IN_BLACKLIST, type);
+
+  // TODO(benwells): don't grant all component extensions.
+  // See http://crbug.com/370375 for more details.
   // Component extensions can access any feature.
-  // TODO(kalman/asargent): Should this match EXTERNAL_COMPONENT too?
-  if (location == Manifest::COMPONENT)
+  // NOTE: Deliberately does not match EXTERNAL_COMPONENT.
+  if (component_extensions_auto_granted_ && location == Manifest::COMPONENT)
     return CreateAvailability(IS_AVAILABLE, type);
 
   if (!whitelist_.empty()) {
@@ -375,6 +386,7 @@
     case IS_AVAILABLE:
       return std::string();
     case NOT_FOUND_IN_WHITELIST:
+    case FOUND_IN_BLACKLIST:
       return base::StringPrintf(
           "'%s' is not allowed for specified extension ID.",
           name().c_str());
@@ -466,13 +478,17 @@
 
 bool SimpleFeature::IsBlockedInServiceWorker() const { return false; }
 
+bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const {
+  return IsIdInList(extension_id, blacklist_);
+}
+
 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const {
-  return IsIdInWhitelist(extension_id, whitelist_);
+  return IsIdInList(extension_id, whitelist_);
 }
 
 // static
-bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id,
-                                    const std::set<std::string>& whitelist) {
+bool SimpleFeature::IsIdInList(const std::string& extension_id,
+                               const std::set<std::string>& list) {
   // Belt-and-suspenders philosophy here. We should be pretty confident by this
   // point that we've validated the extension ID format, but in case something
   // slips through, we avoid a class of attack where creative ID manipulation
@@ -480,8 +496,8 @@
   if (extension_id.length() != 32)  // 128 bits / 4 = 32 mpdecimal characters
     return false;
 
-  if (whitelist.find(extension_id) != whitelist.end() ||
-      whitelist.find(HashExtensionId(extension_id)) != whitelist.end()) {
+  if (list.find(extension_id) != list.end() ||
+      list.find(HashExtensionId(extension_id)) != list.end()) {
     return true;
   }
 
diff --git a/extensions/common/features/simple_feature.h b/extensions/common/features/simple_feature.h
index 0eb1d4e..f81d62b4 100644
--- a/extensions/common/features/simple_feature.h
+++ b/extensions/common/features/simple_feature.h
@@ -53,6 +53,7 @@
     max_manifest_version_ = max_manifest_version;
   }
 
+  std::set<std::string>* blacklist() { return &blacklist_; }
   std::set<std::string>* whitelist() { return &whitelist_; }
   std::set<Manifest::Type>* extension_types() { return &extension_types_; }
 
@@ -104,9 +105,10 @@
   virtual bool IsInternal() const OVERRIDE;
   virtual bool IsBlockedInServiceWorker() const OVERRIDE;
 
+  virtual bool IsIdInBlacklist(const std::string& extension_id) const OVERRIDE;
   virtual bool IsIdInWhitelist(const std::string& extension_id) const OVERRIDE;
-  static bool IsIdInWhitelist(const std::string& extension_id,
-                              const std::set<std::string>& whitelist);
+  static bool IsIdInList(const std::string& extension_id,
+                         const std::set<std::string>& list);
 
  protected:
   Availability CreateAvailability(AvailabilityResult result) const;
@@ -124,6 +126,7 @@
   // members the same way: it matches everything. It is up to the higher level
   // code that reads Features out of static data to validate that data and set
   // sensible defaults.
+  std::set<std::string> blacklist_;
   std::set<std::string> whitelist_;
   std::set<Manifest::Type> extension_types_;
   std::set<Context> contexts_;
@@ -133,6 +136,7 @@
   int min_manifest_version_;
   int max_manifest_version_;
   bool has_parent_;
+  bool component_extensions_auto_granted_;
 
   typedef std::vector<linked_ptr<SimpleFeatureFilter> > FilterList;
   FilterList filters_;
diff --git a/extensions/common/features/simple_feature_unittest.cc b/extensions/common/features/simple_feature_unittest.cc
index ddcac9a..8ba5dfa 100644
--- a/extensions/common/features/simple_feature_unittest.cc
+++ b/extensions/common/features/simple_feature_unittest.cc
@@ -172,6 +172,84 @@
                                     Feature::UNSPECIFIED_PLATFORM).result());
 }
 
+TEST_F(ExtensionSimpleFeatureTest, Blacklist) {
+  const std::string kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
+  const std::string kIdBar("barabbbbccccddddeeeeffffgggghhhh");
+  const std::string kIdBaz("bazabbbbccccddddeeeeffffgggghhhh");
+  SimpleFeature feature;
+  feature.blacklist()->insert(kIdFoo);
+  feature.blacklist()->insert(kIdBar);
+
+  EXPECT_EQ(
+      Feature::FOUND_IN_BLACKLIST,
+      feature.IsAvailableToManifest(kIdFoo,
+                                    Manifest::TYPE_UNKNOWN,
+                                    Manifest::INVALID_LOCATION,
+                                    -1,
+                                    Feature::UNSPECIFIED_PLATFORM).result());
+  EXPECT_EQ(
+      Feature::FOUND_IN_BLACKLIST,
+      feature.IsAvailableToManifest(kIdBar,
+                                    Manifest::TYPE_UNKNOWN,
+                                    Manifest::INVALID_LOCATION,
+                                    -1,
+                                    Feature::UNSPECIFIED_PLATFORM).result());
+
+  EXPECT_EQ(
+      Feature::IS_AVAILABLE,
+      feature.IsAvailableToManifest(kIdBaz,
+                                    Manifest::TYPE_UNKNOWN,
+                                    Manifest::INVALID_LOCATION,
+                                    -1,
+                                    Feature::UNSPECIFIED_PLATFORM).result());
+  EXPECT_EQ(
+      Feature::IS_AVAILABLE,
+      feature.IsAvailableToManifest(std::string(),
+                                    Manifest::TYPE_UNKNOWN,
+                                    Manifest::INVALID_LOCATION,
+                                    -1,
+                                    Feature::UNSPECIFIED_PLATFORM).result());
+}
+
+TEST_F(ExtensionSimpleFeatureTest, HashedIdBlacklist) {
+  // echo -n "fooabbbbccccddddeeeeffffgggghhhh" |
+  //   sha1sum | tr '[:lower:]' '[:upper:]'
+  const std::string kIdFoo("fooabbbbccccddddeeeeffffgggghhhh");
+  const std::string kIdFooHashed("55BC7228A0D502A2A48C9BB16B07062A01E62897");
+  SimpleFeature feature;
+
+  feature.blacklist()->insert(kIdFooHashed);
+
+  EXPECT_EQ(
+      Feature::FOUND_IN_BLACKLIST,
+      feature.IsAvailableToManifest(kIdFoo,
+                                    Manifest::TYPE_UNKNOWN,
+                                    Manifest::INVALID_LOCATION,
+                                    -1,
+                                    Feature::UNSPECIFIED_PLATFORM).result());
+  EXPECT_NE(
+      Feature::FOUND_IN_BLACKLIST,
+      feature.IsAvailableToManifest(kIdFooHashed,
+                                    Manifest::TYPE_UNKNOWN,
+                                    Manifest::INVALID_LOCATION,
+                                    -1,
+                                    Feature::UNSPECIFIED_PLATFORM).result());
+  EXPECT_EQ(
+      Feature::IS_AVAILABLE,
+      feature.IsAvailableToManifest("slightlytoooolongforanextensionid",
+                                    Manifest::TYPE_UNKNOWN,
+                                    Manifest::INVALID_LOCATION,
+                                    -1,
+                                    Feature::UNSPECIFIED_PLATFORM).result());
+  EXPECT_EQ(
+      Feature::IS_AVAILABLE,
+      feature.IsAvailableToManifest("tooshortforanextensionid",
+                                    Manifest::TYPE_UNKNOWN,
+                                    Manifest::INVALID_LOCATION,
+                                    -1,
+                                    Feature::UNSPECIFIED_PLATFORM).result());
+}
+
 TEST_F(ExtensionSimpleFeatureTest, PackageType) {
   SimpleFeature feature;
   feature.extension_types()->insert(Manifest::TYPE_EXTENSION);
diff --git a/extensions/common/manifest_constants.cc b/extensions/common/manifest_constants.cc
index e0433b3..cc574d9 100644
--- a/extensions/common/manifest_constants.cc
+++ b/extensions/common/manifest_constants.cc
@@ -11,6 +11,7 @@
 const char kAllFrames[] = "all_frames";
 const char kAltKey[] = "altKey";
 const char kApp[] = "app";
+const char kAutomation[] = "automation";
 const char kBackgroundAllowJsAccess[] = "background.allow_js_access";
 const char kBackgroundPage[] = "background.page";
 const char kBackgroundPageLegacy[] = "background_page";
@@ -171,6 +172,7 @@
 const char kWebviewAccessibleResources[] = "accessible_resources";
 const char kWebviewName[] = "name";
 const char kWebviewPartitions[] = "partitions";
+const char kWhitelist[] = "whitelist";
 
 }  // namespace manifest_keys
 
@@ -330,6 +332,10 @@
     "Invalid value for 'export.resources'.";
 const char kInvalidExportResourcesString[] =
     "Invalid value for 'export.resources[*]'.";
+const char kInvalidExportWhitelist[] =
+    "Invalid value for 'export.whitelist'.";
+const char kInvalidExportWhitelistString[] =
+    "Invalid value for 'export.whitelist[*]'.";
 const char kInvalidFileAccessList[] =
     "Invalid value for 'file_access'.";
 const char kInvalidFileAccessValue[] =
diff --git a/extensions/common/manifest_constants.h b/extensions/common/manifest_constants.h
index 398b082..4579852 100644
--- a/extensions/common/manifest_constants.h
+++ b/extensions/common/manifest_constants.h
@@ -13,6 +13,7 @@
 extern const char kAllFrames[];
 extern const char kAltKey[];
 extern const char kApp[];
+extern const char kAutomation[];
 extern const char kBackgroundAllowJsAccess[];
 extern const char kBackgroundPage[];
 extern const char kBackgroundPageLegacy[];
@@ -178,6 +179,7 @@
 extern const char kWebviewName[];
 extern const char kWebviewAccessibleResources[];
 extern const char kWebviewPartitions[];
+extern const char kWhitelist[];
 
 }  // namespace manifest_keys
 
@@ -286,6 +288,8 @@
 extern const char kInvalidExportPermissions[];
 extern const char kInvalidExportResources[];
 extern const char kInvalidExportResourcesString[];
+extern const char kInvalidExportWhitelist[];
+extern const char kInvalidExportWhitelistString[];
 extern const char kInvalidFileAccessList[];
 extern const char kInvalidFileAccessValue[];
 extern const char kInvalidFileBrowserHandler[];
diff --git a/extensions/common/manifest_handlers/externally_connectable.cc b/extensions/common/manifest_handlers/externally_connectable.cc
new file mode 100644
index 0000000..859e520
--- /dev/null
+++ b/extensions/common/manifest_handlers/externally_connectable.cc
@@ -0,0 +1,218 @@
+// 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.
+
+#include "extensions/common/manifest_handlers/externally_connectable.h"
+
+#include <algorithm>
+
+#include "base/stl_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "extensions/common/api/extensions_manifest_types.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/manifest_constants.h"
+#include "extensions/common/permissions/api_permission_set.h"
+#include "extensions/common/permissions/permissions_data.h"
+#include "extensions/common/url_pattern.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "url/gurl.h"
+
+namespace rcd = net::registry_controlled_domains;
+
+namespace extensions {
+
+namespace externally_connectable_errors {
+const char kErrorInvalidMatchPattern[] = "Invalid match pattern '*'";
+const char kErrorInvalidId[] = "Invalid ID '*'";
+const char kErrorNothingSpecified[] =
+    "'externally_connectable' specifies neither 'matches' nor 'ids'; "
+    "nothing will be able to connect";
+const char kErrorTopLevelDomainsNotAllowed[] =
+    "\"*\" is an effective top level domain for which wildcard subdomains such "
+    "as \"*\" are not allowed";
+const char kErrorWildcardHostsNotAllowed[] =
+    "Wildcard domain patterns such as \"*\" are not allowed";
+}  // namespace externally_connectable_errors
+
+namespace keys = extensions::manifest_keys;
+namespace errors = externally_connectable_errors;
+using core_api::extensions_manifest_types::ExternallyConnectable;
+
+namespace {
+
+const char kAllIds[] = "*";
+
+template <typename T>
+std::vector<T> Sorted(const std::vector<T>& in) {
+  std::vector<T> out = in;
+  std::sort(out.begin(), out.end());
+  return out;
+}
+
+}  // namespace
+
+ExternallyConnectableHandler::ExternallyConnectableHandler() {
+}
+
+ExternallyConnectableHandler::~ExternallyConnectableHandler() {
+}
+
+bool ExternallyConnectableHandler::Parse(Extension* extension,
+                                         base::string16* error) {
+  const base::Value* externally_connectable = NULL;
+  CHECK(extension->manifest()->Get(keys::kExternallyConnectable,
+                                   &externally_connectable));
+  std::vector<InstallWarning> install_warnings;
+  scoped_ptr<ExternallyConnectableInfo> info =
+      ExternallyConnectableInfo::FromValue(*externally_connectable,
+                                           &install_warnings,
+                                           error);
+  if (!info)
+    return false;
+  if (!info->matches.is_empty()) {
+    PermissionsData::GetInitialAPIPermissions(extension)
+        ->insert(APIPermission::kWebConnectable);
+  }
+  extension->AddInstallWarnings(install_warnings);
+  extension->SetManifestData(keys::kExternallyConnectable, info.release());
+  return true;
+}
+
+const std::vector<std::string> ExternallyConnectableHandler::Keys() const {
+  return SingleKey(keys::kExternallyConnectable);
+}
+
+// static
+ExternallyConnectableInfo* ExternallyConnectableInfo::Get(
+    const Extension* extension) {
+  return static_cast<ExternallyConnectableInfo*>(
+      extension->GetManifestData(keys::kExternallyConnectable));
+}
+
+// static
+scoped_ptr<ExternallyConnectableInfo> ExternallyConnectableInfo::FromValue(
+    const base::Value& value,
+    std::vector<InstallWarning>* install_warnings,
+    base::string16* error) {
+  scoped_ptr<ExternallyConnectable> externally_connectable =
+      ExternallyConnectable::FromValue(value, error);
+  if (!externally_connectable)
+    return scoped_ptr<ExternallyConnectableInfo>();
+
+  URLPatternSet matches;
+
+  if (externally_connectable->matches) {
+    for (std::vector<std::string>::iterator it =
+             externally_connectable->matches->begin();
+         it != externally_connectable->matches->end();
+         ++it) {
+      // Safe to use SCHEME_ALL here; externally_connectable gives a page ->
+      // extension communication path, not the other way.
+      URLPattern pattern(URLPattern::SCHEME_ALL);
+      if (pattern.Parse(*it) != URLPattern::PARSE_SUCCESS) {
+        *error = ErrorUtils::FormatErrorMessageUTF16(
+            errors::kErrorInvalidMatchPattern, *it);
+        return scoped_ptr<ExternallyConnectableInfo>();
+      }
+
+      // Wildcard hosts are not allowed.
+      if (pattern.host().empty()) {
+        // Warning not error for forwards compatibility.
+        install_warnings->push_back(
+            InstallWarning(ErrorUtils::FormatErrorMessage(
+                               errors::kErrorWildcardHostsNotAllowed, *it),
+                           keys::kExternallyConnectable,
+                           *it));
+        continue;
+      }
+
+      // Wildcards on subdomains of a TLD are not allowed.
+      size_t registry_length = rcd::GetRegistryLength(
+          pattern.host(),
+          // This means that things that look like TLDs - the foobar in
+          // http://google.foobar - count as TLDs.
+          rcd::INCLUDE_UNKNOWN_REGISTRIES,
+          // This means that effective TLDs like appspot.com count as TLDs;
+          // codereview.appspot.com and evil.appspot.com are different.
+          rcd::INCLUDE_PRIVATE_REGISTRIES);
+
+      if (registry_length == std::string::npos) {
+        // The URL parsing combined with host().empty() should have caught this.
+        NOTREACHED() << *it;
+        *error = ErrorUtils::FormatErrorMessageUTF16(
+            errors::kErrorInvalidMatchPattern, *it);
+        return scoped_ptr<ExternallyConnectableInfo>();
+      }
+
+      // Broad match patterns like "*.com", "*.co.uk", and even "*.appspot.com"
+      // are not allowed. However just "appspot.com" is ok.
+      if (registry_length == 0 && pattern.match_subdomains()) {
+        // Warning not error for forwards compatibility.
+        install_warnings->push_back(
+            InstallWarning(ErrorUtils::FormatErrorMessage(
+                               errors::kErrorTopLevelDomainsNotAllowed,
+                               pattern.host().c_str(),
+                               *it),
+                           keys::kExternallyConnectable,
+                           *it));
+        continue;
+      }
+
+      matches.AddPattern(pattern);
+    }
+  }
+
+  std::vector<std::string> ids;
+  bool all_ids = false;
+
+  if (externally_connectable->ids) {
+    for (std::vector<std::string>::iterator it =
+             externally_connectable->ids->begin();
+         it != externally_connectable->ids->end();
+         ++it) {
+      if (*it == kAllIds) {
+        all_ids = true;
+      } else if (Extension::IdIsValid(*it)) {
+        ids.push_back(*it);
+      } else {
+        *error =
+            ErrorUtils::FormatErrorMessageUTF16(errors::kErrorInvalidId, *it);
+        return scoped_ptr<ExternallyConnectableInfo>();
+      }
+    }
+  }
+
+  if (!externally_connectable->matches && !externally_connectable->ids) {
+    install_warnings->push_back(InstallWarning(errors::kErrorNothingSpecified,
+                                               keys::kExternallyConnectable));
+  }
+
+  bool accepts_tls_channel_id =
+      externally_connectable->accepts_tls_channel_id.get() &&
+      *externally_connectable->accepts_tls_channel_id;
+  return make_scoped_ptr(new ExternallyConnectableInfo(
+      matches, ids, all_ids, accepts_tls_channel_id));
+}
+
+ExternallyConnectableInfo::~ExternallyConnectableInfo() {
+}
+
+ExternallyConnectableInfo::ExternallyConnectableInfo(
+    const URLPatternSet& matches,
+    const std::vector<std::string>& ids,
+    bool all_ids,
+    bool accepts_tls_channel_id)
+    : matches(matches),
+      ids(Sorted(ids)),
+      all_ids(all_ids),
+      accepts_tls_channel_id(accepts_tls_channel_id) {
+}
+
+bool ExternallyConnectableInfo::IdCanConnect(const std::string& id) {
+  if (all_ids)
+    return true;
+  DCHECK(base::STLIsSorted(ids));
+  return std::binary_search(ids.begin(), ids.end(), id);
+}
+
+}  // namespace extensions
diff --git a/extensions/common/manifest_handlers/externally_connectable.h b/extensions/common/manifest_handlers/externally_connectable.h
new file mode 100644
index 0000000..960904e
--- /dev/null
+++ b/extensions/common/manifest_handlers/externally_connectable.h
@@ -0,0 +1,97 @@
+// 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.
+
+#ifndef EXTENSIONS_COMMON_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_
+#define EXTENSIONS_COMMON_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/install_warning.h"
+#include "extensions/common/manifest_handler.h"
+#include "extensions/common/url_pattern_set.h"
+
+class GURL;
+
+namespace base {
+class Value;
+}
+
+namespace extensions {
+
+// Error constants used when parsing the externally_connectable manifest entry.
+namespace externally_connectable_errors {
+extern const char kErrorInvalid[];
+extern const char kErrorInvalidMatchPattern[];
+extern const char kErrorInvalidId[];
+extern const char kErrorNothingSpecified[];
+extern const char kErrorTopLevelDomainsNotAllowed[];
+extern const char kErrorWildcardHostsNotAllowed[];
+}  // namespace externally_connectable_errors
+
+// Parses the externally_connectable manifest entry.
+class ExternallyConnectableHandler : public ManifestHandler {
+ public:
+  ExternallyConnectableHandler();
+  virtual ~ExternallyConnectableHandler();
+
+  virtual bool Parse(Extension* extension, base::string16* error) OVERRIDE;
+
+ private:
+  virtual const std::vector<std::string> Keys() const OVERRIDE;
+
+  DISALLOW_COPY_AND_ASSIGN(ExternallyConnectableHandler);
+};
+
+// The parsed form of the externally_connectable manifest entry.
+struct ExternallyConnectableInfo : public Extension::ManifestData {
+ public:
+  // Gets the ExternallyConnectableInfo for |extension|, or NULL if none was
+  // specified.
+  static ExternallyConnectableInfo* Get(const Extension* extension);
+
+  // Tries to construct the info based on |value|, as it would have appeared in
+  // the manifest. Sets |error| and returns an empty scoped_ptr on failure.
+  static scoped_ptr<ExternallyConnectableInfo> FromValue(
+      const base::Value& value,
+      std::vector<InstallWarning>* install_warnings,
+      base::string16* error);
+
+  virtual ~ExternallyConnectableInfo();
+
+  // The URL patterns that are allowed to connect/sendMessage.
+  const URLPatternSet matches;
+
+  // The extension IDs that are allowed to connect/sendMessage. Sorted.
+  const std::vector<std::string> ids;
+
+  // True if any extension is allowed to connect. This would have corresponded
+  // to an ID of "*" in |ids|.
+  const bool all_ids;
+
+  // True if extension accepts the TLS channel ID, when requested by the
+  // connecting origin.
+  const bool accepts_tls_channel_id;
+
+  // Returns true if |ids| contains |id| or if |all_ids| is true.
+  //
+  // More convenient for callers than checking each individually, and it makes
+  // use of the sortedness of |ids|.
+  bool IdCanConnect(const std::string& id);
+
+  // Public only for testing. Use FromValue in production.
+  ExternallyConnectableInfo(const URLPatternSet& matches,
+                            const std::vector<std::string>& ids,
+                            bool all_ids,
+                            bool accepts_tls_channel_id);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ExternallyConnectableInfo);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_COMMON_MANIFEST_HANDLERS_EXTERNALLY_CONNECTABLE_H_
diff --git a/extensions/common/manifest_handlers/externally_connectable_unittest.cc b/extensions/common/manifest_handlers/externally_connectable_unittest.cc
new file mode 100644
index 0000000..41b2d32
--- /dev/null
+++ b/extensions/common/manifest_handlers/externally_connectable_unittest.cc
@@ -0,0 +1,315 @@
+// 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.
+
+#include <algorithm>
+
+#include "chrome/common/extensions/features/feature_channel.h"
+#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/manifest_constants.h"
+#include "extensions/common/manifest_handlers/externally_connectable.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::ElementsAre;
+
+namespace extensions {
+
+namespace errors = externally_connectable_errors;
+
+class ExternallyConnectableTest : public ExtensionManifestTest {
+ public:
+  ExternallyConnectableTest() : channel_(chrome::VersionInfo::CHANNEL_DEV) {}
+
+ protected:
+  ExternallyConnectableInfo* GetExternallyConnectableInfo(
+      scoped_refptr<Extension> extension) {
+    return static_cast<ExternallyConnectableInfo*>(
+        extension->GetManifestData(manifest_keys::kExternallyConnectable));
+  }
+
+ private:
+  ScopedCurrentChannel channel_;
+};
+
+TEST_F(ExternallyConnectableTest, IDsAndMatches) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectSuccess("externally_connectable_ids_and_matches.json");
+  ASSERT_TRUE(extension.get());
+
+  EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kWebConnectable));
+
+  ExternallyConnectableInfo* info =
+      ExternallyConnectableInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_THAT(info->ids,
+              ElementsAre("abcdefghijklmnopabcdefghijklmnop",
+                          "ponmlkjihgfedcbaponmlkjihgfedcba"));
+
+  EXPECT_FALSE(info->all_ids);
+
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com/")));
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://example.com/index.html")));
+
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/index.html")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com/")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com/")));
+
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org/")));
+  EXPECT_TRUE(
+      info->matches.MatchesURL(GURL("http://build.chromium.org/index.html")));
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org")));
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org/")));
+  EXPECT_FALSE(
+      info->matches.MatchesURL(GURL("http://foo.chromium.org/index.html")));
+
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com")));
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com/")));
+
+  // TLD-style patterns should match just the TLD.
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://appspot.com/foo.html")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://go/here")));
+
+  // TLD-style patterns should *not* match any subdomains of the TLD.
+  EXPECT_FALSE(
+      info->matches.MatchesURL(GURL("http://codereview.appspot.com/foo.html")));
+  EXPECT_FALSE(
+      info->matches.MatchesURL(GURL("http://chromium.com/index.html")));
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://here.go/somewhere")));
+
+  // Paths that don't have any wildcards should match the exact domain, but
+  // ignore the trailing slash. This is kind of a corner case, so let's test it.
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://no.wildcard.path")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://no.wildcard.path/")));
+  EXPECT_FALSE(
+      info->matches.MatchesURL(GURL("http://no.wildcard.path/index.html")));
+}
+
+TEST_F(ExternallyConnectableTest, IDs) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectSuccess("externally_connectable_ids.json");
+  ASSERT_TRUE(extension.get());
+
+  EXPECT_FALSE(extension->HasAPIPermission(APIPermission::kWebConnectable));
+
+  ExternallyConnectableInfo* info =
+      ExternallyConnectableInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_THAT(info->ids,
+              ElementsAre("abcdefghijklmnopabcdefghijklmnop",
+                          "ponmlkjihgfedcbaponmlkjihgfedcba"));
+
+  EXPECT_FALSE(info->all_ids);
+
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://google.com/index.html")));
+}
+
+TEST_F(ExternallyConnectableTest, Matches) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectSuccess("externally_connectable_matches.json");
+  ASSERT_TRUE(extension.get());
+
+  EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kWebConnectable));
+
+  ExternallyConnectableInfo* info =
+      ExternallyConnectableInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_THAT(info->ids, ElementsAre());
+
+  EXPECT_FALSE(info->all_ids);
+
+  EXPECT_FALSE(info->accepts_tls_channel_id);
+
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com/")));
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://example.com/index.html")));
+
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://google.com/index.html")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com/")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://google.com/")));
+
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org/")));
+  EXPECT_TRUE(
+      info->matches.MatchesURL(GURL("http://build.chromium.org/index.html")));
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org")));
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("https://build.chromium.org/")));
+  EXPECT_FALSE(
+      info->matches.MatchesURL(GURL("http://foo.chromium.org/index.html")));
+
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com")));
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://yahoo.com/")));
+}
+
+TEST_F(ExternallyConnectableTest, MatchesWithTlsChannelId) {
+  scoped_refptr<Extension> extension = LoadAndExpectSuccess(
+      "externally_connectable_matches_tls_channel_id.json");
+  ASSERT_TRUE(extension.get());
+
+  EXPECT_TRUE(extension->HasAPIPermission(APIPermission::kWebConnectable));
+
+  ExternallyConnectableInfo* info =
+      ExternallyConnectableInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_THAT(info->ids, ElementsAre());
+
+  EXPECT_FALSE(info->all_ids);
+
+  EXPECT_TRUE(info->accepts_tls_channel_id);
+
+  // The matches portion of the manifest is identical to those in
+  // externally_connectable_matches, so only a subset of the Matches tests is
+  // repeated here.
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://example.com")));
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://example.com/index.html")));
+}
+
+TEST_F(ExternallyConnectableTest, AllIDs) {
+  scoped_refptr<Extension> extension =
+      LoadAndExpectSuccess("externally_connectable_all_ids.json");
+  ASSERT_TRUE(extension.get());
+
+  EXPECT_FALSE(extension->HasAPIPermission(APIPermission::kWebConnectable));
+
+  ExternallyConnectableInfo* info =
+      ExternallyConnectableInfo::Get(extension.get());
+  ASSERT_TRUE(info);
+
+  EXPECT_THAT(info->ids,
+              ElementsAre("abcdefghijklmnopabcdefghijklmnop",
+                          "ponmlkjihgfedcbaponmlkjihgfedcba"));
+
+  EXPECT_TRUE(info->all_ids);
+
+  EXPECT_FALSE(info->matches.MatchesURL(GURL("http://google.com/index.html")));
+}
+
+TEST_F(ExternallyConnectableTest, IdCanConnect) {
+  // Not in order to test that ExternallyConnectableInfo sorts it.
+  std::string matches_ids_array[] = {"g", "h", "c", "i", "a", "z", "b"};
+  std::vector<std::string> matches_ids(
+      matches_ids_array, matches_ids_array + arraysize(matches_ids_array));
+
+  std::string nomatches_ids_array[] = {"2", "3", "1"};
+
+  // all_ids = false.
+  {
+    ExternallyConnectableInfo info(URLPatternSet(), matches_ids, false, false);
+    for (size_t i = 0; i < matches_ids.size(); ++i)
+      EXPECT_TRUE(info.IdCanConnect(matches_ids[i]));
+    for (size_t i = 0; i < arraysize(nomatches_ids_array); ++i)
+      EXPECT_FALSE(info.IdCanConnect(nomatches_ids_array[i]));
+  }
+
+  // all_ids = true.
+  {
+    ExternallyConnectableInfo info(URLPatternSet(), matches_ids, true, false);
+    for (size_t i = 0; i < matches_ids.size(); ++i)
+      EXPECT_TRUE(info.IdCanConnect(matches_ids[i]));
+    for (size_t i = 0; i < arraysize(nomatches_ids_array); ++i)
+      EXPECT_TRUE(info.IdCanConnect(nomatches_ids_array[i]));
+  }
+}
+
+TEST_F(ExternallyConnectableTest, ErrorWrongFormat) {
+  LoadAndExpectError("externally_connectable_error_wrong_format.json",
+                     "expected dictionary, got string");
+}
+
+TEST_F(ExternallyConnectableTest, ErrorBadID) {
+  LoadAndExpectError(
+      "externally_connectable_bad_id.json",
+      ErrorUtils::FormatErrorMessage(errors::kErrorInvalidId, "badid"));
+}
+
+TEST_F(ExternallyConnectableTest, ErrorBadMatches) {
+  LoadAndExpectError("externally_connectable_error_bad_matches.json",
+                     ErrorUtils::FormatErrorMessage(
+                         errors::kErrorInvalidMatchPattern, "www.yahoo.com"));
+}
+
+TEST_F(ExternallyConnectableTest, WarningNoAllURLs) {
+  scoped_refptr<Extension> extension = LoadAndExpectWarning(
+      "externally_connectable_error_all_urls.json",
+      ErrorUtils::FormatErrorMessage(errors::kErrorWildcardHostsNotAllowed,
+                                     "<all_urls>"));
+  ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
+  EXPECT_FALSE(info->matches.ContainsPattern(
+      URLPattern(URLPattern::SCHEME_ALL, "<all_urls>")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
+}
+
+TEST_F(ExternallyConnectableTest, WarningWildcardHost) {
+  scoped_refptr<Extension> extension = LoadAndExpectWarning(
+      "externally_connectable_error_wildcard_host.json",
+      ErrorUtils::FormatErrorMessage(errors::kErrorWildcardHostsNotAllowed,
+                                     "http://*/*"));
+  ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
+  EXPECT_FALSE(info->matches.ContainsPattern(
+      URLPattern(URLPattern::SCHEME_ALL, "http://*/*")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
+}
+
+TEST_F(ExternallyConnectableTest, WarningNoTLD) {
+  scoped_refptr<Extension> extension = LoadAndExpectWarning(
+      "externally_connectable_error_tld.json",
+      ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed,
+                                     "co.uk",
+                                     "http://*.co.uk/*"));
+  ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
+  EXPECT_FALSE(info->matches.ContainsPattern(
+      URLPattern(URLPattern::SCHEME_ALL, "http://*.co.uk/*")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
+}
+
+TEST_F(ExternallyConnectableTest, WarningNoEffectiveTLD) {
+  scoped_refptr<Extension> extension = LoadAndExpectWarning(
+      "externally_connectable_error_effective_tld.json",
+      ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed,
+                                     "appspot.com",
+                                     "http://*.appspot.com/*"));
+  ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
+  EXPECT_FALSE(info->matches.ContainsPattern(
+      URLPattern(URLPattern::SCHEME_ALL, "http://*.appspot.com/*")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
+}
+
+TEST_F(ExternallyConnectableTest, WarningUnknownTLD) {
+  scoped_refptr<Extension> extension = LoadAndExpectWarning(
+      "externally_connectable_error_unknown_tld.json",
+      ErrorUtils::FormatErrorMessage(errors::kErrorTopLevelDomainsNotAllowed,
+                                     "notatld",
+                                     "http://*.notatld/*"));
+  ExternallyConnectableInfo* info = GetExternallyConnectableInfo(extension);
+  EXPECT_FALSE(info->matches.ContainsPattern(
+      URLPattern(URLPattern::SCHEME_ALL, "http://*.notatld/*")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("https://example.com")));
+  EXPECT_TRUE(info->matches.MatchesURL(GURL("http://build.chromium.org")));
+}
+
+TEST_F(ExternallyConnectableTest, WarningNothingSpecified) {
+  LoadAndExpectWarning("externally_connectable_nothing_specified.json",
+                       errors::kErrorNothingSpecified);
+}
+
+}  // namespace extensions
diff --git a/extensions/common/manifest_handlers/shared_module_info.cc b/extensions/common/manifest_handlers/shared_module_info.cc
index 5f44160..ac95ee5 100644
--- a/extensions/common/manifest_handlers/shared_module_info.cc
+++ b/extensions/common/manifest_handlers/shared_module_info.cc
@@ -84,6 +84,17 @@
 }
 
 // static
+bool SharedModuleInfo::IsExportAllowedByWhitelist(const Extension* extension,
+                                                  const std::string& other_id) {
+  const SharedModuleInfo& info = GetSharedModuleInfo(extension);
+  if (info.export_whitelist_.empty())
+    return true;
+  if (info.export_whitelist_.find(other_id) != info.export_whitelist_.end())
+    return true;
+  return false;
+}
+
+// static
 bool SharedModuleInfo::ImportsExtensionById(const Extension* extension,
                                             const std::string& other_id) {
   const SharedModuleInfo& info = GetSharedModuleInfo(extension);
@@ -128,6 +139,23 @@
       *error = base::ASCIIToUTF16(errors::kInvalidExportResources);
       return false;
     }
+    if (export_value->HasKey(keys::kWhitelist)) {
+      const base::ListValue* whitelist = NULL;
+      if (!export_value->GetList(keys::kWhitelist, &whitelist)) {
+        *error = base::ASCIIToUTF16(errors::kInvalidExportWhitelist);
+        return false;
+      }
+      for (size_t i = 0; i < whitelist->GetSize(); ++i) {
+        std::string extension_id;
+        if (!whitelist->GetString(i, &extension_id) ||
+            !Extension::IdIsValid(extension_id)) {
+          *error = ErrorUtils::FormatErrorMessageUTF16(
+              errors::kInvalidExportWhitelistString, base::IntToString(i));
+          return false;
+        }
+        export_whitelist_.insert(extension_id);
+      }
+    }
     for (size_t i = 0; i < resources_list->GetSize(); ++i) {
       std::string resource_path;
       if (!resources_list->GetString(i, &resource_path)) {
diff --git a/extensions/common/manifest_handlers/shared_module_info.h b/extensions/common/manifest_handlers/shared_module_info.h
index 4240ed7..72fd506 100644
--- a/extensions/common/manifest_handlers/shared_module_info.h
+++ b/extensions/common/manifest_handlers/shared_module_info.h
@@ -36,6 +36,11 @@
   static bool IsSharedModule(const Extension* extension);
   static bool IsExportAllowed(const Extension* extension,
                               const std::string& relative_path);
+  // Check against the shared module's whitelist to see if |other_id| can import
+  // its resources. If no whitelist is specified, all extensions can import this
+  // extension.
+  static bool IsExportAllowedByWhitelist(const Extension* extension,
+                                         const std::string& other_id);
 
   // Functions relating to importing resources.
   static bool ImportsExtensionById(const Extension* extension,
@@ -47,6 +52,9 @@
   // This extension exports the following resources to other extensions.
   URLPatternSet exported_set_;
 
+  // Optional list of extensions from which importing is allowed.
+  std::set<std::string> export_whitelist_;
+
   // Optional list of module imports of other extensions.
   std::vector<ImportInfo> imports_;
 };
diff --git a/extensions/common/manifest_handlers/shared_module_manifest_unittest.cc b/extensions/common/manifest_handlers/shared_module_manifest_unittest.cc
index fa1e387..9fad618 100644
--- a/extensions/common/manifest_handlers/shared_module_manifest_unittest.cc
+++ b/extensions/common/manifest_handlers/shared_module_manifest_unittest.cc
@@ -39,6 +39,26 @@
       << manifest.name();
   EXPECT_TRUE(SharedModuleInfo::IsExportAllowed(extension.get(), "foo/bar"))
       << manifest.name();
+
+  EXPECT_TRUE(SharedModuleInfo::IsExportAllowedByWhitelist(extension.get(),
+                  kImportId1)) << manifest.name();
+  EXPECT_TRUE(SharedModuleInfo::IsExportAllowedByWhitelist(extension.get(),
+                  kImportId2)) << manifest.name();
+  EXPECT_FALSE(SharedModuleInfo::IsExportAllowedByWhitelist(extension.get(),
+                  kNoImport)) << manifest.name();
+}
+
+TEST_F(SharedModuleManifestTest, ExportWhitelistAll) {
+  Manifest manifest("shared_module_export_no_whitelist.json");
+
+  scoped_refptr<Extension> extension = LoadAndExpectSuccess(manifest);
+
+  EXPECT_TRUE(SharedModuleInfo::IsExportAllowedByWhitelist(extension.get(),
+                  kImportId1)) << manifest.name();
+  EXPECT_TRUE(SharedModuleInfo::IsExportAllowedByWhitelist(extension.get(),
+                  kImportId2)) << manifest.name();
+  EXPECT_TRUE(SharedModuleInfo::IsExportAllowedByWhitelist(extension.get(),
+                  kNoImport)) << manifest.name();
 }
 
 TEST_F(SharedModuleManifestTest, ExportFoo) {
@@ -66,6 +86,12 @@
              "Invalid value for 'export.resources'."),
     Testcase("shared_module_export_resource_not_string.json",
              "Invalid value for 'export.resources[1]'."),
+    Testcase("shared_module_export_whitelist_item_not_id.json",
+             "Invalid value for 'export.whitelist[0]'."),
+    Testcase("shared_module_export_whitelist_item_not_string.json",
+             "Invalid value for 'export.whitelist[0]'."),
+    Testcase("shared_module_export_whitelist_not_list.json",
+             "Invalid value for 'export.whitelist'."),
   };
   RunTestcases(testcases, arraysize(testcases), EXPECT_TYPE_ERROR);
 }
diff --git a/extensions/common/permissions/api_permission.cc b/extensions/common/permissions/api_permission.cc
index b757cf2..de0dd98 100644
--- a/extensions/common/permissions/api_permission.cc
+++ b/extensions/common/permissions/api_permission.cc
@@ -113,20 +113,14 @@
 // APIPermissionInfo
 //
 
-APIPermissionInfo::APIPermissionInfo(
-    APIPermission::ID id,
-    const char* name,
-    int l10n_message_id,
-    PermissionMessage::ID message_id,
-    int flags,
-    APIPermissionConstructor api_permission_constructor)
-    : id_(id),
-      name_(name),
-      flags_(flags),
-      l10n_message_id_(l10n_message_id),
-      message_id_(message_id),
-      api_permission_constructor_(api_permission_constructor) { }
-
+APIPermissionInfo::APIPermissionInfo(const APIPermissionInfo::InitInfo& info)
+    : id_(info.id),
+      name_(info.name),
+      flags_(info.flags),
+      l10n_message_id_(info.l10n_message_id),
+      message_id_(info.message_id ? info.message_id : PermissionMessage::kNone),
+      api_permission_constructor_(info.constructor) {
+}
 
 APIPermissionInfo::~APIPermissionInfo() { }
 
diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h
index a660f79..15e44ec 100644
--- a/extensions/common/permissions/api_permission.h
+++ b/extensions/common/permissions/api_permission.h
@@ -37,6 +37,7 @@
     // Real permissions.
     kAccessibilityFeaturesModify,
     kAccessibilityFeaturesRead,
+    kAccessibilityPrivate,
     kActiveTab,
     kActivityLogPrivate,
     kAdView,
@@ -140,7 +141,6 @@
     kStreamsPrivate,
     kSyncFileSystem,
     kSystemPrivate,
-    kSystemIndicator,
     kSystemDisplay,
     kSystemStorage,
     kTab,
@@ -174,6 +174,7 @@
     kSystemInfoCpu,
     kSystemInfoMemory,
     kFirstRunPrivate,
+    kBrowser,
     kEnumBoundary
   };
 
@@ -322,17 +323,25 @@
  private:
   // Instances should only be constructed from within a PermissionsProvider.
   friend class ChromeAPIPermissions;
+  friend class ExtensionsAPIPermissions;
   // Implementations of APIPermission will want to get the permission message,
   // but this class's implementation should be hidden from everyone else.
   friend class APIPermission;
 
-  explicit APIPermissionInfo(
-      APIPermission::ID id,
-      const char* name,
-      int l10n_message_id,
-      PermissionMessage::ID message_id,
-      int flags,
-      APIPermissionConstructor api_permission_constructor);
+  // This exists to allow aggregate initialization, so that default values
+  // for flags, etc. can be omitted.
+  // TODO(yoz): Simplify the way initialization is done. APIPermissionInfo
+  // should be the simple data struct.
+  struct InitInfo {
+    APIPermission::ID id;
+    const char* name;
+    int flags;
+    int l10n_message_id;
+    PermissionMessage::ID message_id;
+    APIPermissionInfo::APIPermissionConstructor constructor;
+  };
+
+  explicit APIPermissionInfo(const InitInfo& info);
 
   // Returns the localized permission message associated with this api.
   // Use GetMessage_ to avoid name conflict with macro GetMessage on Windows.
diff --git a/extensions/common/permissions/extensions_api_permissions.cc b/extensions/common/permissions/extensions_api_permissions.cc
new file mode 100644
index 0000000..c1e00f5
--- /dev/null
+++ b/extensions/common/permissions/extensions_api_permissions.cc
@@ -0,0 +1,50 @@
+// 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.
+
+#include "extensions/common/permissions/extensions_api_permissions.h"
+
+#include "extensions/common/permissions/api_permission.h"
+#include "extensions/common/permissions/permission_message.h"
+#include "extensions/common/permissions/socket_permission.h"
+#include "grit/extensions_strings.h"
+
+namespace extensions {
+
+namespace {
+
+template <typename T>
+APIPermission* CreateAPIPermission(const APIPermissionInfo* permission) {
+  return new T(permission);
+}
+
+}  // namespace
+
+std::vector<APIPermissionInfo*> ExtensionsAPIPermissions::GetAllPermissions()
+    const {
+  APIPermissionInfo::InitInfo permissions_to_register[] = {
+      {APIPermission::kDns, "dns"},
+      // Because warning messages for the "socket" permission vary based
+      // on the permissions parameters, no message ID or message text is
+      // specified here.  The message ID and text used will be
+      // determined at run-time in the |SocketPermission| class.
+      {APIPermission::kSocket, "socket",
+       APIPermissionInfo::kFlagCannotBeOptional, 0, PermissionMessage::kNone,
+       &CreateAPIPermission<SocketPermission>},
+      {APIPermission::kStorage, "storage"},
+      {APIPermission::kUsb, "usb", APIPermissionInfo::kFlagNone,
+       IDS_EXTENSION_PROMPT_WARNING_USB, PermissionMessage::kUsb},
+  };
+
+  std::vector<APIPermissionInfo*> permissions;
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(permissions_to_register); ++i)
+    permissions.push_back(new APIPermissionInfo(permissions_to_register[i]));
+  return permissions;
+}
+
+std::vector<PermissionsProvider::AliasInfo>
+ExtensionsAPIPermissions::GetAllAliases() const {
+  return std::vector<PermissionsProvider::AliasInfo>();
+}
+
+}  // namespace extensions
diff --git a/extensions/common/permissions/extensions_api_permissions.h b/extensions/common/permissions/extensions_api_permissions.h
new file mode 100644
index 0000000..9ba9277
--- /dev/null
+++ b/extensions/common/permissions/extensions_api_permissions.h
@@ -0,0 +1,22 @@
+// 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.
+
+#ifndef EXTENSIONS_COMMON_PERMISSIONS_EXTENSIONS_API_PERMISSIONS_H_
+#define EXTENSIONS_COMMON_PERMISSIONS_EXTENSIONS_API_PERMISSIONS_H_
+
+#include "base/compiler_specific.h"
+#include "extensions/common/permissions/permissions_provider.h"
+
+namespace extensions {
+
+class ExtensionsAPIPermissions : public PermissionsProvider {
+ public:
+  virtual std::vector<APIPermissionInfo*> GetAllPermissions() const OVERRIDE;
+  virtual std::vector<PermissionsProvider::AliasInfo> GetAllAliases()
+      const OVERRIDE;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_COMMON_PERMISSIONS_EXTENSIONS_API_PERMISSIONS_H_
diff --git a/extensions/common/permissions/permissions_info.cc b/extensions/common/permissions/permissions_info.cc
index e4684aa..9592fa5 100644
--- a/extensions/common/permissions/permissions_info.cc
+++ b/extensions/common/permissions/permissions_info.cc
@@ -8,7 +8,6 @@
 #include "base/logging.h"
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
-#include "extensions/common/extensions_client.h"
 
 namespace extensions {
 
@@ -20,8 +19,15 @@
   return g_permissions_info.Pointer();
 }
 
-PermissionsInfo::~PermissionsInfo() {
-  STLDeleteContainerPairSecondPointers(id_map_.begin(), id_map_.end());
+void PermissionsInfo::AddProvider(const PermissionsProvider& provider) {
+  std::vector<APIPermissionInfo*> permissions = provider.GetAllPermissions();
+  std::vector<PermissionsProvider::AliasInfo> aliases =
+      provider.GetAllAliases();
+
+  for (size_t i = 0; i < permissions.size(); ++i)
+    RegisterPermission(permissions[i]);
+  for (size_t i = 0; i < aliases.size(); ++i)
+    RegisterAlias(aliases[i].name, aliases[i].alias);
 }
 
 const APIPermissionInfo* PermissionsInfo::GetByID(
@@ -64,19 +70,10 @@
 PermissionsInfo::PermissionsInfo()
     : hosted_app_permission_count_(0),
       permission_count_(0) {
-  InitializeWithProvider(ExtensionsClient::Get()->GetPermissionsProvider());
 }
 
-void PermissionsInfo::InitializeWithProvider(
-    const PermissionsProvider& provider) {
-  std::vector<APIPermissionInfo*> permissions = provider.GetAllPermissions();
-  std::vector<PermissionsProvider::AliasInfo> aliases =
-      provider.GetAllAliases();
-
-  for (size_t i = 0; i < permissions.size(); ++i)
-    RegisterPermission(permissions[i]);
-  for (size_t i = 0; i < aliases.size(); ++i)
-    RegisterAlias(aliases[i].name, aliases[i].alias);
+PermissionsInfo::~PermissionsInfo() {
+  STLDeleteContainerPairSecondPointers(id_map_.begin(), id_map_.end());
 }
 
 void PermissionsInfo::RegisterAlias(
diff --git a/extensions/common/permissions/permissions_info.h b/extensions/common/permissions/permissions_info.h
index 9be7e6d..e1d0afd 100644
--- a/extensions/common/permissions/permissions_info.h
+++ b/extensions/common/permissions/permissions_info.h
@@ -24,7 +24,8 @@
  public:
   static PermissionsInfo* GetInstance();
 
-  virtual ~PermissionsInfo();
+  // Initializes the permissions from the provider.
+  void AddProvider(const PermissionsProvider& provider);
 
   // Returns the permission with the given |id|, and NULL if it doesn't exist.
   const APIPermissionInfo* GetByID(APIPermission::ID id) const;
@@ -52,8 +53,7 @@
 
   PermissionsInfo();
 
-  // Initializes the permissions from the provider.
-  void InitializeWithProvider(const PermissionsProvider& provider);
+  virtual ~PermissionsInfo();
 
   // Registers an |alias| for a given permission |name|.
   void RegisterAlias(const char* name, const char* alias);
diff --git a/extensions/common/permissions/permissions_provider.h b/extensions/common/permissions/permissions_provider.h
index 5a27a86..4417995 100644
--- a/extensions/common/permissions/permissions_provider.h
+++ b/extensions/common/permissions/permissions_provider.h
@@ -11,8 +11,9 @@
 
 class APIPermissionInfo;
 
-// The PermissionsProvider creates the APIPermissions instances. It is only
-// needed at startup time.
+// The PermissionsProvider creates APIPermissions instances. It is only
+// needed at startup time. Typically, ExtensionsClient will register
+// its PermissionsProviders with the global PermissionsInfo at startup.
 class PermissionsProvider {
  public:
   // An alias for a given permission |name|.
diff --git a/extensions/common/permissions/socket_permission_entry.cc b/extensions/common/permissions/socket_permission_entry.cc
index 8c21edc..ddadf22 100644
--- a/extensions/common/permissions/socket_permission_entry.cc
+++ b/extensions/common/permissions/socket_permission_entry.cc
@@ -85,10 +85,10 @@
 
     if (!pattern_.host.empty()) {
       // Do not wildcard part of IP address.
-      url_parse::Component component(0, lhost.length());
-      url_canon::RawCanonOutputT<char, 128> ignored_output;
-      url_canon::CanonHostInfo host_info;
-      url_canon::CanonicalizeIPAddress(
+      url::Component component(0, lhost.length());
+      url::RawCanonOutputT<char, 128> ignored_output;
+      url::CanonHostInfo host_info;
+      url::CanonicalizeIPAddress(
           lhost.c_str(), component, &ignored_output, &host_info);
       if (host_info.IsIPAddress())
         return false;
diff --git a/extensions/common/switches.cc b/extensions/common/switches.cc
index 41c3469..57ea960 100644
--- a/extensions/common/switches.cc
+++ b/extensions/common/switches.cc
@@ -35,6 +35,16 @@
 // notified of its impending unload and that unload happening.
 const char kEventPageSuspendingTime[] = "event-page-unloading-time";
 
+// Values for the kExtensionContentVerification flag. See ContentVerifier::Mode
+// for more explanation.
+const char kExtensionContentVerificationBootstrap[] = "bootstrap";
+const char kExtensionContentVerificationEnforceStrict[] = "enforce_strict";
+const char kExtensionContentVerificationEnforce[] = "enforce";
+
+// Name of the command line flag to force content verification to be on in one
+// of various modes.
+const char kExtensionContentVerification[] = "extension-content-verification";
+
 // Marks a renderer as extension process.
 const char kExtensionProcess[] = "extension-process";
 
diff --git a/extensions/common/switches.h b/extensions/common/switches.h
index f79e32f..b758403 100644
--- a/extensions/common/switches.h
+++ b/extensions/common/switches.h
@@ -18,6 +18,10 @@
 extern const char kErrorConsole[];
 extern const char kEventPageIdleTime[];
 extern const char kEventPageSuspendingTime[];
+extern const char kExtensionContentVerificationBootstrap[];
+extern const char kExtensionContentVerificationEnforceStrict[];
+extern const char kExtensionContentVerificationEnforce[];
+extern const char kExtensionContentVerification[];
 extern const char kExtensionProcess[];
 extern const char kExtensionsOnChromeURLs[];
 extern const char kForceDevModeHighlighting[];
diff --git a/extensions/common/url_pattern.cc b/extensions/common/url_pattern.cc
index 477d3dd..020be3c 100644
--- a/extensions/common/url_pattern.cc
+++ b/extensions/common/url_pattern.cc
@@ -20,13 +20,13 @@
 // TODO(aa): What about more obscure schemes like data: and javascript: ?
 // Note: keep this array in sync with kValidSchemeMasks.
 const char* kValidSchemes[] = {
-  content::kHttpScheme,
-  content::kHttpsScheme,
-  content::kFileScheme,
-  content::kFtpScheme,
-  content::kChromeUIScheme,
-  extensions::kExtensionScheme,
-  content::kFileSystemScheme,
+    url::kHttpScheme,
+    url::kHttpsScheme,
+    content::kFileScheme,
+    content::kFtpScheme,
+    content::kChromeUIScheme,
+    extensions::kExtensionScheme,
+    content::kFileSystemScheme,
 };
 
 const int kValidSchemeMasks[] = {
@@ -73,8 +73,8 @@
   if (scheme == "*")
     return true;
 
-  return url_util::IsStandard(scheme.c_str(),
-      url_parse::Component(0, static_cast<int>(scheme.length())));
+  return url::IsStandard(scheme.c_str(),
+                         url::Component(0, static_cast<int>(scheme.length())));
 }
 
 bool IsValidPortForScheme(const std::string& scheme, const std::string& port) {
@@ -82,12 +82,12 @@
     return true;
 
   // Only accept non-wildcard ports if the scheme uses ports.
-  if (url_canon::DefaultPortForScheme(scheme.c_str(), scheme.length()) ==
-      url_parse::PORT_UNSPECIFIED) {
+  if (url::DefaultPortForScheme(scheme.c_str(), scheme.length()) ==
+      url::PORT_UNSPECIFIED) {
     return false;
   }
 
-  int parsed_port = url_parse::PORT_UNSPECIFIED;
+  int parsed_port = url::PORT_UNSPECIFIED;
   if (!base::StringToInt(port, &parsed_port))
     return false;
   return (parsed_port >= 0) && (parsed_port < 65536);
@@ -365,7 +365,7 @@
 }
 
 bool URLPattern::MatchesHost(const std::string& host) const {
-  std::string test(content::kHttpScheme);
+  std::string test(url::kHttpScheme);
   test += content::kStandardSchemeSeparator;
   test += host;
   test += "/";
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp
index 1664e87..61de6ad 100644
--- a/extensions/extensions.gyp
+++ b/extensions/extensions.gyp
@@ -15,9 +15,6 @@
         # api resources compiled into the chrome resource bundle.
         # http://crbug.com/162530
         '../chrome/chrome_resources.gyp:chrome_resources',
-        # TODO(tfarina): This dep here is for extensions/common/constants.*
-        # We should find a way to compile this module within extensions_common.
-        '../chrome/common_constants.gyp:common_constants',
         '../components/components.gyp:url_matcher',
         '../content/content.gyp:content_common',
         '../crypto/crypto.gyp:crypto',
@@ -46,6 +43,8 @@
         'common/api/sockets/sockets_manifest_permission.h',
         'common/common_manifest_handlers.cc',
         'common/common_manifest_handlers.h',
+        'common/constants.cc',
+        'common/constants.h',
         'common/crx_file.cc',
         'common/crx_file.h',
         'common/csp_validator.cc',
@@ -124,6 +123,8 @@
         'common/manifest_handlers/background_info.h',
         'common/manifest_handlers/csp_info.cc',
         'common/manifest_handlers/csp_info.h',
+        'common/manifest_handlers/externally_connectable.cc',
+        'common/manifest_handlers/externally_connectable.h',
         'common/manifest_handlers/icons_handler.cc',
         'common/manifest_handlers/icons_handler.h',
         'common/manifest_handlers/incognito_info.cc',
@@ -151,6 +152,8 @@
         'common/permissions/api_permission_set.cc',
         'common/permissions/api_permission_set.h',
         'common/permissions/base_set_operators.h',
+        'common/permissions/extensions_api_permissions.cc',
+        'common/permissions/extensions_api_permissions.h',
         'common/permissions/manifest_permission.cc',
         'common/permissions/manifest_permission.h',
         'common/permissions/manifest_permission_set.cc',
@@ -204,6 +207,9 @@
       'msvs_disabled_warnings': [ 4267, ],
       'conditions': [
         ['enable_extensions==1', {
+          'dependencies': [
+            '../device/usb/usb.gyp:device_usb',
+          ],
           'sources!': [
             'common/extension_api_stub.cc',
           ],
@@ -219,6 +225,8 @@
       'type': 'static_library',
       'dependencies': [
         '../components/components.gyp:keyed_service_content',
+        '../components/components.gyp:usb_service',
+        '../components/components.gyp:user_prefs',
         '../content/content.gyp:content_browser',
         '../skia/skia.gyp:skia',
         '../third_party/leveldatabase/leveldatabase.gyp:leveldatabase',
@@ -250,6 +258,10 @@
         'browser/api/dns/host_resolver_wrapper.h',
         'browser/api/extensions_api_client.cc',
         'browser/api/extensions_api_client.h',
+        'browser/api/runtime/runtime_api.cc',
+        'browser/api/runtime/runtime_api.h',
+        'browser/api/runtime/runtime_api_delegate.cc',
+        'browser/api/runtime/runtime_api_delegate.h',
         'browser/api/socket/socket.cc',
         'browser/api/socket/socket.h',
         'browser/api/socket/socket_api.cc',
@@ -290,12 +302,21 @@
         'browser/api/storage/weak_unlimited_settings_storage.h',
         'browser/api/test/test_api.cc',
         'browser/api/test/test_api.h',
+        'browser/api/usb/usb_api.cc',
+        'browser/api/usb/usb_api.h',
+        'browser/api/usb/usb_device_resource.cc',
+        'browser/api/usb/usb_device_resource.h',
         'browser/api_activity_monitor.h',
         'browser/app_sorting.h',
         'browser/blacklist_state.h',
         'browser/browser_context_keyed_api_factory.h',
         'browser/browser_context_keyed_service_factories.cc',
         'browser/browser_context_keyed_service_factories.h',
+        'browser/content_verifier.cc',
+        'browser/content_verifier.h',
+        'browser/content_verifier_filter.h',
+        'browser/content_verify_job.cc',
+        'browser/content_verify_job.h',
         'browser/error_map.cc',
         'browser/error_map.h',
         'browser/event_listener_map.cc',
@@ -386,6 +407,8 @@
         'browser/value_store/value_store_frontend.h',
         'browser/value_store/value_store_util.cc',
         'browser/value_store/value_store_util.h',
+        'browser/verified_contents.cc',
+        'browser/verified_contents.h',
         'browser/view_type_utils.cc',
         'browser/view_type_utils.h',
       ],
@@ -398,11 +421,16 @@
           # when enable_extensions==0.
           'sources/': [
             ['exclude', '^browser/api/'],
+            ['include', '^browser/api/runtime/runtime_api.cc'],
+            ['include', '^browser/api/runtime/runtime_api_delegate.cc'],
           ],
           'sources!': [
             'browser/browser_context_keyed_service_factories.cc',
             'browser/browser_context_keyed_service_factories.h',
           ],
+          'dependencies!': [
+            '../components/components.gyp:usb_service',
+          ],
         }],
       ],
       # Disable c4267 warnings until we fix size_t to int truncations.
@@ -411,14 +439,23 @@
     {
       'target_name': 'extensions_renderer',
       'type': 'static_library',
+      'dependencies': [
+        'extensions_resources.gyp:extensions_resources',
+        '../chrome/chrome_resources.gyp:chrome_resources',
+        '../third_party/WebKit/public/blink.gyp:blink',
+      ],
       'include_dirs': [
         '..',
       ],
       'sources': [
         'renderer/activity_log_converter_strategy.cc',
         'renderer/activity_log_converter_strategy.h',
+        'renderer/api_activity_logger.cc',
+        'renderer/api_activity_logger.h',
         'renderer/api_definitions_natives.cc',
         'renderer/api_definitions_natives.h',
+        'renderer/app_runtime_custom_bindings.cc',
+        'renderer/app_runtime_custom_bindings.h',
         'renderer/binding_generating_native_handler.cc',
         'renderer/binding_generating_native_handler.h',
         'renderer/blob_native_handler.cc',
@@ -431,12 +468,19 @@
         'renderer/context_menus_custom_bindings.h',
         'renderer/css_native_handler.cc',
         'renderer/css_native_handler.h',
+        'renderer/default_dispatcher_delegate.cc',
+        'renderer/default_dispatcher_delegate.h',
+        'renderer/dispatcher.cc',
+        'renderer/dispatcher.h',
+        'renderer/dispatcher_delegate.h',
         'renderer/document_custom_bindings.cc',
         'renderer/document_custom_bindings.h',
         'renderer/dom_activity_logger.cc',
         'renderer/dom_activity_logger.h',
         'renderer/event_bindings.cc',
         'renderer/event_bindings.h',
+        'renderer/extension_helper.cc',
+        'renderer/extension_helper.h',
         'renderer/extensions_renderer_client.cc',
         'renderer/extensions_renderer_client.h',
         'renderer/extension_groups.h',
@@ -446,18 +490,30 @@
         'renderer/i18n_custom_bindings.h',
         'renderer/id_generator_custom_bindings.cc',
         'renderer/id_generator_custom_bindings.h',
+        'renderer/lazy_background_page_native_handler.cc',
+        'renderer/lazy_background_page_native_handler.h',
         'renderer/logging_native_handler.cc',
         'renderer/logging_native_handler.h',
+        'renderer/messaging_bindings.cc',
+        'renderer/messaging_bindings.h',
         'renderer/module_system.cc',
         'renderer/module_system.h',
         'renderer/native_handler.cc',
         'renderer/native_handler.h',
         'renderer/object_backed_native_handler.cc',
         'renderer/object_backed_native_handler.h',
+        'renderer/print_native_handler.cc',
+        'renderer/print_native_handler.h',
+        'renderer/process_info_native_handler.cc',
+        'renderer/process_info_native_handler.h',
         'renderer/render_view_observer_natives.cc',
         'renderer/render_view_observer_natives.h',
         'renderer/request_sender.cc',
         'renderer/request_sender.h',
+        'renderer/resource_bundle_source_map.cc',
+        'renderer/resource_bundle_source_map.h',
+        'renderer/runtime_custom_bindings.cc',
+        'renderer/runtime_custom_bindings.h',
         'renderer/safe_builtins.cc',
         'renderer/safe_builtins.h',
         'renderer/send_request_natives.cc',
@@ -469,14 +525,23 @@
         'renderer/script_context.h',
         'renderer/script_context_set.cc',
         'renderer/script_context_set.h',
+        'renderer/static_v8_external_ascii_string_resource.cc',
+        'renderer/static_v8_external_ascii_string_resource.h',
+        'renderer/test_features_native_handler.cc',
+        'renderer/test_features_native_handler.h',
+        'renderer/user_gestures_native_handler.cc',
+        'renderer/user_gestures_native_handler.h',
+        'renderer/user_script_scheduler.cc',
+        'renderer/user_script_scheduler.h',
+        'renderer/user_script_slave.cc',
+        'renderer/user_script_slave.h',
         'renderer/utils_native_handler.cc',
         'renderer/utils_native_handler.h',
+        'renderer/v8_context_native_handler.cc',
+        'renderer/v8_context_native_handler.h',
         'renderer/v8_schema_registry.cc',
         'renderer/v8_schema_registry.h',
       ],
-      'dependencies': [
-        '../third_party/WebKit/public/blink.gyp:blink',
-      ],
       # Disable c4267 warnings until we fix size_t to int truncations.
       'msvs_disabled_warnings': [ 4267, ],
       'conditions': [
@@ -500,17 +565,21 @@
       'dependencies': [
         '../base/base.gyp:base',
         '../testing/gtest.gyp:gtest',
+        'common/api/api.gyp:extensions_api',
         'extensions_browser',
         'extensions_common',
       ],
       'include_dirs': [
         '..',
+        '<(SHARED_INTERMEDIATE_DIR)',
       ],
       'sources': [
         'browser/test_extensions_browser_client.cc',
         'browser/test_extensions_browser_client.h',
         'browser/test_management_policy.cc',
         'browser/test_management_policy.h',
+        'browser/test_runtime_api_delegate.cc',
+        'browser/test_runtime_api_delegate.h',
         'common/extension_builder.cc',
         'common/extension_builder.h',
         'common/test_util.cc',
diff --git a/extensions/extensions_resources.gyp b/extensions/extensions_resources.gyp
index dcbf26f..856def8 100644
--- a/extensions/extensions_resources.gyp
+++ b/extensions/extensions_resources.gyp
@@ -3,15 +3,14 @@
 # found in the LICENSE file.
 
 {
-  'variables': {
-    'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/extensions',
-  },
   'targets': [
     {
       'target_name': 'extensions_resources',
       'type': 'none',
+      'variables': {
+        'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/extensions',
+      },
       'actions': [
-        # Data resources.
         {
           'action_name': 'extensions_resources',
           'variables': {
@@ -20,11 +19,7 @@
           'includes': [ '../build/grit_action.gypi' ],
         },
       ],
-      'direct_dependent_settings': {
-        'include_dirs': [
-          '<(SHARED_INTERMEDIATE_DIR)/extensions',
-        ],
-      },
+      'includes': [ '../build/grit_target.gypi' ],
       'hard_dependency': 1,
     }
   ]
diff --git a/extensions/extensions_strings.grd b/extensions/extensions_strings.grd
index 2971356..8b05719 100644
--- a/extensions/extensions_strings.grd
+++ b/extensions/extensions_strings.grd
@@ -265,9 +265,6 @@
         NA
       </message>
       </if>
-      <message name="IDS_EXTENSION_PROMPT_WARNING_HOST_LIST" desc="Permission string (heading) for a list of websites.">
-        Access your data on the following websites:
-      </message>
       <message name="IDS_EXTENSION_PROMPT_WARNING_HOST_LIST_ENTRY" desc="Single entry in a list of websites.">
         - <ph name="WEBSITE_1">$1<ex>www.google.com</ex></ph>
       </message>
@@ -317,6 +314,9 @@
       </message>
       
       <!-- USB API strings. Please keep alphabetized. -->
+      <message name="IDS_EXTENSION_PROMPT_WARNING_USB" desc="Permission string for access to USB devices.">
+        Access USB devices
+      </message>
       <message name="IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE" desc="Permission string for access to a specific USB device.">
         Access the USB device <ph name="PRODUCT_NAME">$1<ex>SoundKnob</ex></ph> from <ph name="VENDOR_NAME">$2<ex>Griffin Technology</ex></ph>
       </message>
diff --git a/extensions/generated_extensions_api.gni b/extensions/generated_extensions_api.gni
index d4da603..c8817a6 100644
--- a/extensions/generated_extensions_api.gni
+++ b/extensions/generated_extensions_api.gni
@@ -70,18 +70,9 @@
     "$compiler_root/util_cc_helper.py",
   ]
 
-  # This list mirrors the outputs that will be generated by the following
-  # action_foreach. It's used by the static_library target.
-  compiled_schema_outputs = process_file_template(
-    schemas,
-    [ "$target_gen_dir/{{source_name_part}}.cc",
-      "$target_gen_dir/{{source_name_part}}.h",
-    ])
-
   schema_generator_name = target_name + "_schema_generator"
   action_foreach(schema_generator_name) {
     script = compiler_script
-    hard_dep = true
     source_prereqs = compiler_sources
     sources = schemas
     outputs = [
@@ -98,17 +89,15 @@
   }
 
   bundle_generator_name = target_name + "_bundle_generator"
-  bundle_outputs = [
-    "$target_gen_dir/generated_api.cc",
-    "$target_gen_dir/generated_api.h",
-    "$target_gen_dir/generated_schemas.cc",
-    "$target_gen_dir/generated_schemas.h",
-  ]
   action(bundle_generator_name) {
     script = compiler_script
-    hard_dep = true
     source_prereqs = compiler_sources + schemas + uncompiled_schemas
-    outputs = bundle_outputs
+    outputs = [
+      "$target_gen_dir/generated_api.cc",
+      "$target_gen_dir/generated_api.h",
+      "$target_gen_dir/generated_schemas.cc",
+      "$target_gen_dir/generated_schemas.h",
+    ]
     args = [
       "--root=" + rebase_path("//", root_build_dir),
       "--destdir=" + rebase_path(root_gen_dir, root_build_dir),
@@ -121,8 +110,10 @@
   }
 
   source_set(target_name) {
-    hard_dep = true
-    sources = compiled_schema_outputs + bundle_outputs
+    sources =
+      get_target_outputs(":$schema_generator_name") +
+      get_target_outputs(":$bundle_generator_name")
+
     deps = [
       ":$schema_generator_name",
       ":$bundle_generator_name",
diff --git a/extensions/renderer/api_activity_logger.cc b/extensions/renderer/api_activity_logger.cc
new file mode 100644
index 0000000..c1c5aef
--- /dev/null
+++ b/extensions/renderer/api_activity_logger.cc
@@ -0,0 +1,80 @@
+// 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.
+
+#include <string>
+
+#include "base/bind.h"
+#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/v8_value_converter.h"
+#include "extensions/common/extension_messages.h"
+#include "extensions/renderer/activity_log_converter_strategy.h"
+#include "extensions/renderer/api_activity_logger.h"
+#include "extensions/renderer/script_context.h"
+
+using content::V8ValueConverter;
+
+namespace extensions {
+
+APIActivityLogger::APIActivityLogger(ScriptContext* context)
+    : ObjectBackedNativeHandler(context) {
+  RouteFunction("LogEvent", base::Bind(&APIActivityLogger::LogEvent));
+  RouteFunction("LogAPICall", base::Bind(&APIActivityLogger::LogAPICall));
+}
+
+// static
+void APIActivityLogger::LogAPICall(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  LogInternal(APICALL, args);
+}
+
+// static
+void APIActivityLogger::LogEvent(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  LogInternal(EVENT, args);
+}
+
+// static
+void APIActivityLogger::LogInternal(
+    const CallType call_type,
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  DCHECK_GT(args.Length(), 2);
+  DCHECK(args[0]->IsString());
+  DCHECK(args[1]->IsString());
+  DCHECK(args[2]->IsArray());
+
+  std::string ext_id = *v8::String::Utf8Value(args[0]);
+  ExtensionHostMsg_APIActionOrEvent_Params params;
+  params.api_call = *v8::String::Utf8Value(args[1]);
+  if (args.Length() == 4)  // Extras are optional.
+    params.extra = *v8::String::Utf8Value(args[3]);
+  else
+    params.extra = "";
+
+  // Get the array of api call arguments.
+  v8::Local<v8::Array> arg_array = v8::Local<v8::Array>::Cast(args[2]);
+  if (arg_array->Length() > 0) {
+    scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
+    ActivityLogConverterStrategy strategy;
+    converter->SetFunctionAllowed(true);
+    converter->SetStrategy(&strategy);
+    scoped_ptr<base::ListValue> arg_list(new base::ListValue());
+    for (size_t i = 0; i < arg_array->Length(); ++i) {
+      arg_list->Set(
+          i,
+          converter->FromV8Value(arg_array->Get(i),
+                                 args.GetIsolate()->GetCurrentContext()));
+    }
+    params.arguments.Swap(arg_list.get());
+  }
+
+  if (call_type == APICALL) {
+    content::RenderThread::Get()->Send(
+        new ExtensionHostMsg_AddAPIActionToActivityLog(ext_id, params));
+  } else if (call_type == EVENT) {
+    content::RenderThread::Get()->Send(
+        new ExtensionHostMsg_AddEventToActivityLog(ext_id, params));
+  }
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/api_activity_logger.h b/extensions/renderer/api_activity_logger.h
new file mode 100644
index 0000000..13f23f9
--- /dev/null
+++ b/extensions/renderer/api_activity_logger.h
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_API_ACTIVITY_LOGGER_H_
+#define EXTENSIONS_RENDERER_API_ACTIVITY_LOGGER_H_
+
+#include <string>
+
+#include "extensions/common/features/feature.h"
+#include "extensions/renderer/object_backed_native_handler.h"
+#include "v8/include/v8.h"
+
+namespace extensions {
+
+// Used to log extension API calls and events that are implemented with custom
+// bindings.The actions are sent via IPC to extensions::ActivityLog for
+// recording and display.
+class APIActivityLogger : public ObjectBackedNativeHandler {
+ public:
+  explicit APIActivityLogger(ScriptContext* context);
+
+ private:
+  // Used to distinguish API calls & events from each other in LogInternal.
+  enum CallType { APICALL, EVENT };
+
+  // This is ultimately invoked in bindings.js with JavaScript arguments.
+  //    arg0 - extension ID as a string
+  //    arg1 - API call name as a string
+  //    arg2 - arguments to the API call
+  //    arg3 - any extra logging info as a string (optional)
+  static void LogAPICall(const v8::FunctionCallbackInfo<v8::Value>& args);
+
+  // This is ultimately invoked in bindings.js with JavaScript arguments.
+  //    arg0 - extension ID as a string
+  //    arg1 - Event name as a string
+  //    arg2 - Event arguments
+  //    arg3 - any extra logging info as a string (optional)
+  static void LogEvent(const v8::FunctionCallbackInfo<v8::Value>& args);
+
+  // LogAPICall and LogEvent are really the same underneath except for
+  // how they are ultimately dispatched to the log.
+  static void LogInternal(const CallType call_type,
+                          const v8::FunctionCallbackInfo<v8::Value>& args);
+
+  DISALLOW_COPY_AND_ASSIGN(APIActivityLogger);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_API_ACTIVITY_LOGGER_H_
diff --git a/extensions/renderer/api_definitions_natives.cc b/extensions/renderer/api_definitions_natives.cc
index a7970b2..c0dc699 100644
--- a/extensions/renderer/api_definitions_natives.cc
+++ b/extensions/renderer/api_definitions_natives.cc
@@ -4,9 +4,9 @@
 
 #include "extensions/renderer/api_definitions_natives.h"
 
-#include "chrome/renderer/extensions/dispatcher.h"
 #include "extensions/common/features/feature.h"
 #include "extensions/common/features/feature_provider.h"
+#include "extensions/renderer/dispatcher.h"
 #include "extensions/renderer/script_context.h"
 
 namespace extensions {
diff --git a/extensions/renderer/app_runtime_custom_bindings.cc b/extensions/renderer/app_runtime_custom_bindings.cc
new file mode 100644
index 0000000..3a1f169
--- /dev/null
+++ b/extensions/renderer/app_runtime_custom_bindings.cc
@@ -0,0 +1,66 @@
+// 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.
+
+#include "extensions/renderer/app_runtime_custom_bindings.h"
+
+#include "base/bind.h"
+#include "base/strings/string_number_conversions.h"
+#include "third_party/WebKit/public/platform/WebCString.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/web/WebBlob.h"
+#include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
+
+using blink::WebBlob;
+using blink::WebSerializedScriptValue;
+using blink::WebString;
+
+namespace {
+
+void DeserializeString(const v8::FunctionCallbackInfo<v8::Value>& args) {
+  DCHECK(args.Length() == 1);
+  DCHECK(args[0]->IsString());
+
+  std::string data_v8(*v8::String::Utf8Value(args[0]));
+  WebString data_webstring = WebString::fromUTF8(data_v8);
+  WebSerializedScriptValue serialized =
+      WebSerializedScriptValue::fromString(data_webstring);
+  args.GetReturnValue().Set(serialized.deserialize());
+}
+
+void SerializeToString(const v8::FunctionCallbackInfo<v8::Value>& args) {
+  DCHECK(args.Length() == 1);
+  WebSerializedScriptValue data = WebSerializedScriptValue::serialize(args[0]);
+  WebString data_webstring = data.toString();
+
+  std::string v = std::string(data_webstring.utf8());
+  args.GetReturnValue().Set(
+      v8::String::NewFromUtf8(args.GetIsolate(), v.c_str()));
+}
+
+void CreateBlob(const v8::FunctionCallbackInfo<v8::Value>& args) {
+  DCHECK(args.Length() == 2);
+  DCHECK(args[0]->IsString());
+  DCHECK(args[1]->IsNumber());
+
+  std::string blob_file_path(*v8::String::Utf8Value(args[0]));
+  std::string blob_length_string(*v8::String::Utf8Value(args[1]));
+  int64 blob_length = 0;
+  DCHECK(base::StringToInt64(blob_length_string, &blob_length));
+  blink::WebBlob web_blob =
+      WebBlob::createFromFile(WebString::fromUTF8(blob_file_path), blob_length);
+  args.GetReturnValue().Set(web_blob.toV8Value());
+}
+
+}  // namespace
+
+namespace extensions {
+
+AppRuntimeCustomBindings::AppRuntimeCustomBindings(ScriptContext* context)
+    : ObjectBackedNativeHandler(context) {
+  RouteFunction("DeserializeString", base::Bind(&DeserializeString));
+  RouteFunction("SerializeToString", base::Bind(&SerializeToString));
+  RouteFunction("CreateBlob", base::Bind(&CreateBlob));
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/app_runtime_custom_bindings.h b/extensions/renderer/app_runtime_custom_bindings.h
new file mode 100644
index 0000000..f4ff906
--- /dev/null
+++ b/extensions/renderer/app_runtime_custom_bindings.h
@@ -0,0 +1,23 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_APP_RUNTIME_CUSTOM_BINDINGS_H_
+#define EXTENSIONS_RENDERER_APP_RUNTIME_CUSTOM_BINDINGS_H_
+
+#include "extensions/renderer/object_backed_native_handler.h"
+
+namespace extensions {
+
+// The native component of custom bindings for the chrome.app.runtime API.
+class AppRuntimeCustomBindings : public ObjectBackedNativeHandler {
+ public:
+  explicit AppRuntimeCustomBindings(ScriptContext* context);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AppRuntimeCustomBindings);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_APP_RUNTIME_CUSTOM_BINDINGS_H_
diff --git a/extensions/renderer/console.cc b/extensions/renderer/console.cc
index 303de44..7429104 100644
--- a/extensions/renderer/console.cc
+++ b/extensions/renderer/console.cc
@@ -10,10 +10,10 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/renderer/extensions/dispatcher.h"
-#include "chrome/renderer/extensions/extension_helper.h"
 #include "content/public/renderer/render_view.h"
 #include "content/public/renderer/render_view_visitor.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/extension_helper.h"
 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
 #include "third_party/WebKit/public/web/WebView.h"
diff --git a/extensions/renderer/default_dispatcher_delegate.cc b/extensions/renderer/default_dispatcher_delegate.cc
new file mode 100644
index 0000000..326ee70
--- /dev/null
+++ b/extensions/renderer/default_dispatcher_delegate.cc
@@ -0,0 +1,27 @@
+// 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.
+
+#include "extensions/renderer/default_dispatcher_delegate.h"
+
+#include "extensions/renderer/script_context.h"
+
+namespace extensions {
+
+DefaultDispatcherDelegate::DefaultDispatcherDelegate() {
+}
+
+DefaultDispatcherDelegate::~DefaultDispatcherDelegate() {
+}
+
+// DispatcherDelegate implementation.
+scoped_ptr<ScriptContext> DefaultDispatcherDelegate::CreateScriptContext(
+    const v8::Handle<v8::Context>& v8_context,
+    blink::WebFrame* frame,
+    const Extension* extension,
+    Feature::Context context_type) {
+  return make_scoped_ptr(
+      new ScriptContext(v8_context, frame, extension, context_type));
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/default_dispatcher_delegate.h b/extensions/renderer/default_dispatcher_delegate.h
new file mode 100644
index 0000000..1ee92ab
--- /dev/null
+++ b/extensions/renderer/default_dispatcher_delegate.h
@@ -0,0 +1,27 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_DEFAULT_DISPATCHER_DELEGATE_H
+#define EXTENSIONS_RENDERER_DEFAULT_DISPATCHER_DELEGATE_H
+
+#include "extensions/renderer/dispatcher_delegate.h"
+
+namespace extensions {
+
+class DefaultDispatcherDelegate : public DispatcherDelegate {
+ public:
+  DefaultDispatcherDelegate();
+  virtual ~DefaultDispatcherDelegate();
+
+  // DispatcherDelegate implementation.
+  virtual scoped_ptr<ScriptContext> CreateScriptContext(
+      const v8::Handle<v8::Context>& v8_context,
+      blink::WebFrame* frame,
+      const Extension* extension,
+      Feature::Context context_type) OVERRIDE;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_DEFAULT_DISPATCHER_DELEGATE_H
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
new file mode 100644
index 0000000..a3014ed
--- /dev/null
+++ b/extensions/renderer/dispatcher.cc
@@ -0,0 +1,1221 @@
+// 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.
+
+#include "extensions/renderer/dispatcher.h"
+
+#include "base/callback.h"
+#include "base/command_line.h"
+#include "base/debug/alias.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/user_metrics_action.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/url_constants.h"
+#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/render_view.h"
+#include "content/public/renderer/v8_value_converter.h"
+#include "extensions/common/api/messaging/message.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_api.h"
+#include "extensions/common/extension_messages.h"
+#include "extensions/common/extension_urls.h"
+#include "extensions/common/features/feature.h"
+#include "extensions/common/features/feature_provider.h"
+#include "extensions/common/manifest.h"
+#include "extensions/common/manifest_constants.h"
+#include "extensions/common/manifest_handlers/background_info.h"
+#include "extensions/common/manifest_handlers/externally_connectable.h"
+#include "extensions/common/manifest_handlers/sandboxed_page_info.h"
+#include "extensions/common/message_bundle.h"
+#include "extensions/common/permissions/permission_set.h"
+#include "extensions/common/permissions/permissions_data.h"
+#include "extensions/common/switches.h"
+#include "extensions/common/view_type.h"
+#include "extensions/renderer/api_activity_logger.h"
+#include "extensions/renderer/api_definitions_natives.h"
+#include "extensions/renderer/app_runtime_custom_bindings.h"
+#include "extensions/renderer/binding_generating_native_handler.h"
+#include "extensions/renderer/blob_native_handler.h"
+#include "extensions/renderer/content_watcher.h"
+#include "extensions/renderer/context_menus_custom_bindings.h"
+#include "extensions/renderer/css_native_handler.h"
+#include "extensions/renderer/dispatcher_delegate.h"
+#include "extensions/renderer/document_custom_bindings.h"
+#include "extensions/renderer/dom_activity_logger.h"
+#include "extensions/renderer/event_bindings.h"
+#include "extensions/renderer/extension_groups.h"
+#include "extensions/renderer/extension_helper.h"
+#include "extensions/renderer/extensions_renderer_client.h"
+#include "extensions/renderer/file_system_natives.h"
+#include "extensions/renderer/i18n_custom_bindings.h"
+#include "extensions/renderer/id_generator_custom_bindings.h"
+#include "extensions/renderer/lazy_background_page_native_handler.h"
+#include "extensions/renderer/logging_native_handler.h"
+#include "extensions/renderer/messaging_bindings.h"
+#include "extensions/renderer/module_system.h"
+#include "extensions/renderer/print_native_handler.h"
+#include "extensions/renderer/process_info_native_handler.h"
+#include "extensions/renderer/render_view_observer_natives.h"
+#include "extensions/renderer/request_sender.h"
+#include "extensions/renderer/runtime_custom_bindings.h"
+#include "extensions/renderer/safe_builtins.h"
+#include "extensions/renderer/script_context.h"
+#include "extensions/renderer/script_context_set.h"
+#include "extensions/renderer/send_request_natives.h"
+#include "extensions/renderer/set_icon_natives.h"
+#include "extensions/renderer/test_features_native_handler.h"
+#include "extensions/renderer/user_gestures_native_handler.h"
+#include "extensions/renderer/user_script_slave.h"
+#include "extensions/renderer/utils_native_handler.h"
+#include "extensions/renderer/v8_context_native_handler.h"
+#include "grit/common_resources.h"
+#include "grit/renderer_resources.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/platform/WebURLRequest.h"
+#include "third_party/WebKit/public/web/WebCustomElement.h"
+#include "third_party/WebKit/public/web/WebDataSource.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebFrame.h"
+#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
+#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
+#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
+#include "third_party/WebKit/public/web/WebView.h"
+#include "ui/base/layout.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "v8/include/v8.h"
+
+using base::UserMetricsAction;
+using blink::WebDataSource;
+using blink::WebDocument;
+using blink::WebFrame;
+using blink::WebScopedUserGesture;
+using blink::WebSecurityPolicy;
+using blink::WebString;
+using blink::WebVector;
+using blink::WebView;
+using content::RenderThread;
+using content::RenderView;
+
+namespace extensions {
+
+namespace {
+
+static const int64 kInitialExtensionIdleHandlerDelayMs = 5 * 1000;
+static const int64 kMaxExtensionIdleHandlerDelayMs = 5 * 60 * 1000;
+static const char kEventDispatchFunction[] = "dispatchEvent";
+static const char kOnSuspendEvent[] = "runtime.onSuspend";
+static const char kOnSuspendCanceledEvent[] = "runtime.onSuspendCanceled";
+
+// Returns the global value for "chrome" from |context|. If one doesn't exist
+// creates a new object for it.
+//
+// Note that this isn't necessarily an object, since webpages can write, for
+// example, "window.chrome = true".
+v8::Handle<v8::Value> GetOrCreateChrome(ScriptContext* context) {
+  v8::Handle<v8::String> chrome_string(
+      v8::String::NewFromUtf8(context->isolate(), "chrome"));
+  v8::Handle<v8::Object> global(context->v8_context()->Global());
+  v8::Handle<v8::Value> chrome(global->Get(chrome_string));
+  if (chrome->IsUndefined()) {
+    chrome = v8::Object::New(context->isolate());
+    global->Set(chrome_string, chrome);
+  }
+  return chrome;
+}
+
+// Returns |value| cast to an object if possible, else an empty handle.
+v8::Handle<v8::Object> AsObjectOrEmpty(v8::Handle<v8::Value> value) {
+  return value->IsObject() ? value.As<v8::Object>() : v8::Handle<v8::Object>();
+}
+
+// Calls a method |method_name| in a module |module_name| belonging to the
+// module system from |context|. Intended as a callback target from
+// ScriptContextSet::ForEach.
+void CallModuleMethod(const std::string& module_name,
+                      const std::string& method_name,
+                      const base::ListValue* args,
+                      ScriptContext* context) {
+  v8::HandleScope handle_scope(context->isolate());
+  v8::Context::Scope context_scope(context->v8_context());
+
+  scoped_ptr<content::V8ValueConverter> converter(
+      content::V8ValueConverter::create());
+
+  std::vector<v8::Handle<v8::Value> > arguments;
+  for (base::ListValue::const_iterator it = args->begin(); it != args->end();
+       ++it) {
+    arguments.push_back(converter->ToV8Value(*it, context->v8_context()));
+  }
+
+  context->module_system()->CallModuleMethod(
+      module_name, method_name, &arguments);
+}
+
+// This handles the "chrome." root API object in script contexts.
+class ChromeNativeHandler : public ObjectBackedNativeHandler {
+ public:
+  explicit ChromeNativeHandler(ScriptContext* context)
+      : ObjectBackedNativeHandler(context) {
+    RouteFunction(
+        "GetChrome",
+        base::Bind(&ChromeNativeHandler::GetChrome, base::Unretained(this)));
+  }
+
+  void GetChrome(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    args.GetReturnValue().Set(GetOrCreateChrome(context()));
+  }
+};
+
+}  // namespace
+
+Dispatcher::Dispatcher(DispatcherDelegate* delegate)
+    : delegate_(delegate),
+      content_watcher_(new ContentWatcher()),
+      source_map_(&ResourceBundle::GetSharedInstance()),
+      v8_schema_registry_(new V8SchemaRegistry),
+      is_webkit_initialized_(false) {
+  const CommandLine& command_line = *(CommandLine::ForCurrentProcess());
+  is_extension_process_ =
+      command_line.HasSwitch(extensions::switches::kExtensionProcess) ||
+      command_line.HasSwitch(::switches::kSingleProcess);
+
+  if (is_extension_process_) {
+    RenderThread::Get()->SetIdleNotificationDelayInMs(
+        kInitialExtensionIdleHandlerDelayMs);
+  }
+
+  RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension());
+
+  user_script_slave_.reset(new UserScriptSlave(&extensions_));
+  request_sender_.reset(new RequestSender(this));
+  PopulateSourceMap();
+}
+
+Dispatcher::~Dispatcher() {
+}
+
+bool Dispatcher::IsExtensionActive(const std::string& extension_id) const {
+  bool is_active =
+      active_extension_ids_.find(extension_id) != active_extension_ids_.end();
+  if (is_active)
+    CHECK(extensions_.Contains(extension_id));
+  return is_active;
+}
+
+std::string Dispatcher::GetExtensionID(const WebFrame* frame, int world_id) {
+  if (world_id != 0) {
+    // Isolated worlds (content script).
+    return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id);
+  }
+
+  // TODO(kalman): Delete this check.
+  if (frame->document().securityOrigin().isUnique())
+    return std::string();
+
+  // Extension pages (chrome-extension:// URLs).
+  GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame);
+  return extensions_.GetExtensionOrAppIDByURL(frame_url);
+}
+
+void Dispatcher::DidCreateScriptContext(
+    WebFrame* frame,
+    const v8::Handle<v8::Context>& v8_context,
+    int extension_group,
+    int world_id) {
+#if !defined(ENABLE_EXTENSIONS)
+  return;
+#endif
+
+  std::string extension_id = GetExtensionID(frame, world_id);
+
+  const Extension* extension = extensions_.GetByID(extension_id);
+  if (!extension && !extension_id.empty()) {
+    // There are conditions where despite a context being associated with an
+    // extension, no extension actually gets found.  Ignore "invalid" because
+    // CSP blocks extension page loading by switching the extension ID to
+    // "invalid". This isn't interesting.
+    if (extension_id != "invalid") {
+      LOG(ERROR) << "Extension \"" << extension_id << "\" not found";
+      RenderThread::Get()->RecordAction(
+          UserMetricsAction("ExtensionNotFound_ED"));
+    }
+
+    extension_id = "";
+  }
+
+  Feature::Context context_type =
+      ClassifyJavaScriptContext(extension,
+                                extension_group,
+                                ScriptContext::GetDataSourceURLForFrame(frame),
+                                frame->document().securityOrigin());
+
+  ScriptContext* context =
+      delegate_->CreateScriptContext(v8_context, frame, extension, context_type)
+          .release();
+  script_context_set_.Add(context);
+
+  if (extension) {
+    InitOriginPermissions(extension, context_type);
+  }
+
+  {
+    scoped_ptr<ModuleSystem> module_system(
+        new ModuleSystem(context, &source_map_));
+    context->set_module_system(module_system.Pass());
+  }
+  ModuleSystem* module_system = context->module_system();
+
+  // Enable natives in startup.
+  ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system);
+
+  RegisterNativeHandlers(module_system, context);
+
+  // chrome.Event is part of the public API (although undocumented). Make it
+  // lazily evalulate to Event from event_bindings.js. For extensions only
+  // though, not all webpages!
+  if (context->extension()) {
+    v8::Handle<v8::Object> chrome = AsObjectOrEmpty(GetOrCreateChrome(context));
+    if (!chrome.IsEmpty())
+      module_system->SetLazyField(chrome, "Event", kEventBindings, "Event");
+  }
+
+  UpdateBindingsForContext(context);
+
+  bool is_within_platform_app = IsWithinPlatformApp();
+  // Inject custom JS into the platform app context.
+  if (is_within_platform_app) {
+    module_system->Require("platformApp");
+  }
+
+  delegate_->RequireAdditionalModules(
+      module_system, extension, context_type, is_within_platform_app);
+
+  VLOG(1) << "Num tracked contexts: " << script_context_set_.size();
+}
+
+void Dispatcher::WillReleaseScriptContext(
+    WebFrame* frame,
+    const v8::Handle<v8::Context>& v8_context,
+    int world_id) {
+  ScriptContext* context = script_context_set_.GetByV8Context(v8_context);
+  if (!context)
+    return;
+
+  context->DispatchOnUnloadEvent();
+  // TODO(kalman): add an invalidation observer interface to ScriptContext.
+  request_sender_->InvalidateSource(context);
+
+  script_context_set_.Remove(context);
+  VLOG(1) << "Num tracked contexts: " << script_context_set_.size();
+}
+
+void Dispatcher::DidCreateDocumentElement(blink::WebFrame* frame) {
+  if (IsWithinPlatformApp()) {
+    // WebKit doesn't let us define an additional user agent stylesheet, so we
+    // insert the default platform app stylesheet into all documents that are
+    // loaded in each app.
+    std::string stylesheet = ResourceBundle::GetSharedInstance()
+                                 .GetRawDataResource(IDR_PLATFORM_APP_CSS)
+                                 .as_string();
+    ReplaceFirstSubstringAfterOffset(
+        &stylesheet, 0, "$FONTFAMILY", system_font_family_);
+    ReplaceFirstSubstringAfterOffset(
+        &stylesheet, 0, "$FONTSIZE", system_font_size_);
+    frame->document().insertStyleSheet(WebString::fromUTF8(stylesheet));
+  }
+
+  content_watcher_->DidCreateDocumentElement(frame);
+}
+
+void Dispatcher::DidMatchCSS(
+    blink::WebFrame* frame,
+    const blink::WebVector<blink::WebString>& newly_matching_selectors,
+    const blink::WebVector<blink::WebString>& stopped_matching_selectors) {
+  content_watcher_->DidMatchCSS(
+      frame, newly_matching_selectors, stopped_matching_selectors);
+}
+
+void Dispatcher::OnExtensionResponse(int request_id,
+                                     bool success,
+                                     const base::ListValue& response,
+                                     const std::string& error) {
+  request_sender_->HandleResponse(request_id, success, response, error);
+}
+
+bool Dispatcher::CheckContextAccessToExtensionAPI(
+    const std::string& function_name,
+    ScriptContext* context) const {
+  if (!context) {
+    DLOG(ERROR) << "Not in a v8::Context";
+    return false;
+  }
+
+  if (!context->extension()) {
+    context->isolate()->ThrowException(v8::Exception::Error(
+        v8::String::NewFromUtf8(context->isolate(), "Not in an extension.")));
+    return false;
+  }
+
+  // Theoretically we could end up with bindings being injected into sandboxed
+  // frames, for example content scripts. Don't let them execute API functions.
+  blink::WebFrame* frame = context->web_frame();
+  if (IsSandboxedPage(ScriptContext::GetDataSourceURLForFrame(frame))) {
+    static const char kMessage[] =
+        "%s cannot be used within a sandboxed frame.";
+    std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
+    context->isolate()->ThrowException(v8::Exception::Error(
+        v8::String::NewFromUtf8(context->isolate(), error_msg.c_str())));
+    return false;
+  }
+
+  Feature::Availability availability = context->GetAvailability(function_name);
+  if (!availability.is_available()) {
+    context->isolate()->ThrowException(
+        v8::Exception::Error(v8::String::NewFromUtf8(
+            context->isolate(), availability.message().c_str())));
+  }
+
+  return availability.is_available();
+}
+
+void Dispatcher::DispatchEvent(const std::string& extension_id,
+                               const std::string& event_name) const {
+  base::ListValue args;
+  args.Set(0, new base::StringValue(event_name));
+  args.Set(1, new base::ListValue());
+
+  // Needed for Windows compilation, since kEventBindings is declared extern.
+  const char* local_event_bindings = kEventBindings;
+  script_context_set_.ForEach(extension_id,
+                              NULL,  // all render views
+                              base::Bind(&CallModuleMethod,
+                                         local_event_bindings,
+                                         kEventDispatchFunction,
+                                         &args));
+}
+
+void Dispatcher::InvokeModuleSystemMethod(content::RenderView* render_view,
+                                          const std::string& extension_id,
+                                          const std::string& module_name,
+                                          const std::string& function_name,
+                                          const base::ListValue& args,
+                                          bool user_gesture) {
+  scoped_ptr<WebScopedUserGesture> web_user_gesture;
+  if (user_gesture)
+    web_user_gesture.reset(new WebScopedUserGesture);
+
+  script_context_set_.ForEach(
+      extension_id,
+      render_view,
+      base::Bind(&CallModuleMethod, module_name, function_name, &args));
+
+  // Reset the idle handler each time there's any activity like event or message
+  // dispatch, for which Invoke is the chokepoint.
+  if (is_extension_process_) {
+    RenderThread::Get()->ScheduleIdleHandler(
+        kInitialExtensionIdleHandlerDelayMs);
+  }
+
+  // Tell the browser process when an event has been dispatched with a lazy
+  // background page active.
+  const Extension* extension = extensions_.GetByID(extension_id);
+  if (extension && BackgroundInfo::HasLazyBackgroundPage(extension) &&
+      module_name == kEventBindings &&
+      function_name == kEventDispatchFunction) {
+    RenderView* background_view =
+        ExtensionHelper::GetBackgroundPage(extension_id);
+    if (background_view) {
+      background_view->Send(
+          new ExtensionHostMsg_EventAck(background_view->GetRoutingID()));
+    }
+  }
+}
+
+void Dispatcher::ClearPortData(int port_id) {
+  // Only the target port side has entries in |port_to_tab_id_map_|. If
+  // |port_id| is a source port, std::map::erase() will just silently fail
+  // here as a no-op.
+  port_to_tab_id_map_.erase(port_id);
+}
+
+bool Dispatcher::OnControlMessageReceived(const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(Dispatcher, message)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_ActivateExtension, OnActivateExtension)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_CancelSuspend, OnCancelSuspend)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_ClearTabSpecificPermissions,
+                      OnClearTabSpecificPermissions)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnDeliverMessage)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect, OnDispatchOnConnect)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect, OnDispatchOnDisconnect)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_SetChannel, OnSetChannel)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_SetFunctionNames, OnSetFunctionNames)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingWhitelist,
+                      OnSetScriptingWhitelist)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_SetSystemFont, OnSetSystemFont)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_ShouldSuspend, OnShouldSuspend)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_Suspend, OnSuspend)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnUnloaded)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_UpdatePermissions, OnUpdatePermissions)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateTabSpecificPermissions,
+                      OnUpdateTabSpecificPermissions)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts, OnUpdateUserScripts)
+  IPC_MESSAGE_HANDLER(ExtensionMsg_UsingWebRequestAPI, OnUsingWebRequestAPI)
+  IPC_MESSAGE_FORWARD(ExtensionMsg_WatchPages,
+                      content_watcher_.get(),
+                      ContentWatcher::OnWatchPages)
+  IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+
+  return handled;
+}
+
+void Dispatcher::WebKitInitialized() {
+  // For extensions, we want to ensure we call the IdleHandler every so often,
+  // even if the extension keeps up activity.
+  if (is_extension_process_) {
+    forced_idle_timer_.reset(new base::RepeatingTimer<content::RenderThread>);
+    forced_idle_timer_->Start(
+        FROM_HERE,
+        base::TimeDelta::FromMilliseconds(kMaxExtensionIdleHandlerDelayMs),
+        RenderThread::Get(),
+        &RenderThread::IdleHandler);
+  }
+
+  // Initialize host permissions for any extensions that were activated before
+  // WebKit was initialized.
+  for (std::set<std::string>::iterator iter = active_extension_ids_.begin();
+       iter != active_extension_ids_.end();
+       ++iter) {
+    const Extension* extension = extensions_.GetByID(*iter);
+    CHECK(extension);
+  }
+
+  EnableCustomElementWhiteList();
+
+  is_webkit_initialized_ = true;
+}
+
+void Dispatcher::IdleNotification() {
+  if (is_extension_process_) {
+    // Dampen the forced delay as well if the extension stays idle for long
+    // periods of time.
+    int64 forced_delay_ms =
+        std::max(RenderThread::Get()->GetIdleNotificationDelayInMs(),
+                 kMaxExtensionIdleHandlerDelayMs);
+    forced_idle_timer_->Stop();
+    forced_idle_timer_->Start(
+        FROM_HERE,
+        base::TimeDelta::FromMilliseconds(forced_delay_ms),
+        RenderThread::Get(),
+        &RenderThread::IdleHandler);
+  }
+}
+
+void Dispatcher::OnRenderProcessShutdown() {
+  v8_schema_registry_.reset();
+  forced_idle_timer_.reset();
+}
+
+void Dispatcher::OnActivateExtension(const std::string& extension_id) {
+  const Extension* extension = extensions_.GetByID(extension_id);
+  if (!extension) {
+    // Extension was activated but was never loaded. This probably means that
+    // the renderer failed to load it (or the browser failed to tell us when it
+    // did). Failures shouldn't happen, but instead of crashing there (which
+    // executes on all renderers) be conservative and only crash in the renderer
+    // of the extension which failed to load; this one.
+    std::string& error = extension_load_errors_[extension_id];
+    char minidump[256];
+    base::debug::Alias(&minidump);
+    base::snprintf(minidump,
+                   arraysize(minidump),
+                   "e::dispatcher:%s:%s",
+                   extension_id.c_str(),
+                   error.c_str());
+    CHECK(extension) << extension_id << " was never loaded: " << error;
+  }
+
+  active_extension_ids_.insert(extension_id);
+
+  // This is called when starting a new extension page, so start the idle
+  // handler ticking.
+  RenderThread::Get()->ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayMs);
+
+  if (is_webkit_initialized_) {
+    extensions::DOMActivityLogger::AttachToWorld(
+        extensions::DOMActivityLogger::kMainWorldId, extension_id);
+  }
+
+  UpdateActiveExtensions();
+}
+
+void Dispatcher::OnCancelSuspend(const std::string& extension_id) {
+  DispatchEvent(extension_id, kOnSuspendCanceledEvent);
+}
+
+void Dispatcher::OnClearTabSpecificPermissions(
+    int tab_id,
+    const std::vector<std::string>& extension_ids) {
+  delegate_->ClearTabSpecificPermissions(this, tab_id, extension_ids);
+}
+
+void Dispatcher::OnDeliverMessage(int target_port_id, const Message& message) {
+  scoped_ptr<RequestSender::ScopedTabID> scoped_tab_id;
+  std::map<int, int>::const_iterator it =
+      port_to_tab_id_map_.find(target_port_id);
+  if (it != port_to_tab_id_map_.end()) {
+    scoped_tab_id.reset(
+        new RequestSender::ScopedTabID(request_sender(), it->second));
+  }
+
+  MessagingBindings::DeliverMessage(script_context_set_.GetAll(),
+                                    target_port_id,
+                                    message,
+                                    NULL);  // All render views.
+}
+
+void Dispatcher::OnDispatchOnConnect(
+    int target_port_id,
+    const std::string& channel_name,
+    const base::DictionaryValue& source_tab,
+    const ExtensionMsg_ExternalConnectionInfo& info,
+    const std::string& tls_channel_id) {
+  DCHECK(!ContainsKey(port_to_tab_id_map_, target_port_id));
+  DCHECK_EQ(1, target_port_id % 2);  // target renderer ports have odd IDs.
+  int sender_tab_id = -1;
+  source_tab.GetInteger("id", &sender_tab_id);
+  port_to_tab_id_map_[target_port_id] = sender_tab_id;
+
+  MessagingBindings::DispatchOnConnect(script_context_set_.GetAll(),
+                                       target_port_id,
+                                       channel_name,
+                                       source_tab,
+                                       info.source_id,
+                                       info.target_id,
+                                       info.source_url,
+                                       tls_channel_id,
+                                       NULL);  // All render views.
+}
+
+void Dispatcher::OnDispatchOnDisconnect(int port_id,
+                                        const std::string& error_message) {
+  MessagingBindings::DispatchOnDisconnect(script_context_set_.GetAll(),
+                                          port_id,
+                                          error_message,
+                                          NULL);  // All render views.
+}
+
+void Dispatcher::OnLoaded(
+    const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions) {
+  std::vector<ExtensionMsg_Loaded_Params>::const_iterator i;
+  for (i = loaded_extensions.begin(); i != loaded_extensions.end(); ++i) {
+    std::string error;
+    scoped_refptr<const Extension> extension = i->ConvertToExtension(&error);
+    if (!extension.get()) {
+      extension_load_errors_[i->id] = error;
+      continue;
+    }
+    OnLoadedInternal(extension);
+  }
+  // Update the available bindings for all contexts. These may have changed if
+  // an externally_connectable extension was loaded that can connect to an
+  // open webpage.
+  UpdateBindings("");
+}
+
+void Dispatcher::OnLoadedInternal(scoped_refptr<const Extension> extension) {
+  extensions_.Insert(extension);
+}
+
+void Dispatcher::OnMessageInvoke(const std::string& extension_id,
+                                 const std::string& module_name,
+                                 const std::string& function_name,
+                                 const base::ListValue& args,
+                                 bool user_gesture) {
+  InvokeModuleSystemMethod(
+      NULL, extension_id, module_name, function_name, args, user_gesture);
+}
+
+void Dispatcher::OnSetChannel(int channel) {
+  delegate_->SetChannel(channel);
+}
+
+void Dispatcher::OnSetFunctionNames(const std::vector<std::string>& names) {
+  function_names_.clear();
+  for (size_t i = 0; i < names.size(); ++i)
+    function_names_.insert(names[i]);
+}
+
+void Dispatcher::OnSetScriptingWhitelist(
+    const ExtensionsClient::ScriptingWhitelist& extension_ids) {
+  ExtensionsClient::Get()->SetScriptingWhitelist(extension_ids);
+}
+
+void Dispatcher::OnSetSystemFont(const std::string& font_family,
+                                 const std::string& font_size) {
+  system_font_family_ = font_family;
+  system_font_size_ = font_size;
+}
+
+void Dispatcher::OnShouldSuspend(const std::string& extension_id,
+                                 int sequence_id) {
+  RenderThread::Get()->Send(
+      new ExtensionHostMsg_ShouldSuspendAck(extension_id, sequence_id));
+}
+
+void Dispatcher::OnSuspend(const std::string& extension_id) {
+  // Dispatch the suspend event. This doesn't go through the standard event
+  // dispatch machinery because it requires special handling. We need to let
+  // the browser know when we are starting and stopping the event dispatch, so
+  // that it still considers the extension idle despite any activity the suspend
+  // event creates.
+  DispatchEvent(extension_id, kOnSuspendEvent);
+  RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id));
+}
+
+void Dispatcher::OnUnloaded(const std::string& id) {
+  extensions_.Remove(id);
+  active_extension_ids_.erase(id);
+
+  // If the extension is later reloaded with a different set of permissions,
+  // we'd like it to get a new isolated world ID, so that it can pick up the
+  // changed origin whitelist.
+  user_script_slave_->RemoveIsolatedWorld(id);
+
+  // Invalidate all of the contexts that were removed.
+  // TODO(kalman): add an invalidation observer interface to ScriptContext.
+  ScriptContextSet::ContextSet removed_contexts =
+      script_context_set_.OnExtensionUnloaded(id);
+  for (ScriptContextSet::ContextSet::iterator it = removed_contexts.begin();
+       it != removed_contexts.end();
+       ++it) {
+    request_sender_->InvalidateSource(*it);
+  }
+
+  // Update the available bindings for the remaining contexts. These may have
+  // changed if an externally_connectable extension is unloaded and a webpage
+  // is no longer accessible.
+  UpdateBindings("");
+
+  // Invalidates the messages map for the extension in case the extension is
+  // reloaded with a new messages map.
+  EraseL10nMessagesMap(id);
+
+  // We don't do anything with existing platform-app stylesheets. They will
+  // stay resident, but the URL pattern corresponding to the unloaded
+  // extension's URL just won't match anything anymore.
+}
+
+void Dispatcher::OnUpdatePermissions(
+    const ExtensionMsg_UpdatePermissions_Params& params) {
+  int reason_id = params.reason_id;
+  const std::string& extension_id = params.extension_id;
+  const APIPermissionSet& apis = params.apis;
+  const ManifestPermissionSet& manifest_permissions =
+      params.manifest_permissions;
+  const URLPatternSet& explicit_hosts = params.explicit_hosts;
+  const URLPatternSet& scriptable_hosts = params.scriptable_hosts;
+
+  const Extension* extension = extensions_.GetByID(extension_id);
+  if (!extension)
+    return;
+
+  scoped_refptr<const PermissionSet> delta = new PermissionSet(
+      apis, manifest_permissions, explicit_hosts, scriptable_hosts);
+  scoped_refptr<const PermissionSet> old_active =
+      extension->GetActivePermissions();
+  UpdatedExtensionPermissionsInfo::Reason reason =
+      static_cast<UpdatedExtensionPermissionsInfo::Reason>(reason_id);
+
+  const PermissionSet* new_active = NULL;
+  switch (reason) {
+    case UpdatedExtensionPermissionsInfo::ADDED:
+      new_active = PermissionSet::CreateUnion(old_active.get(), delta.get());
+      break;
+    case UpdatedExtensionPermissionsInfo::REMOVED:
+      new_active =
+          PermissionSet::CreateDifference(old_active.get(), delta.get());
+      break;
+  }
+
+  PermissionsData::SetActivePermissions(extension, new_active);
+  UpdateOriginPermissions(reason, extension, explicit_hosts);
+  UpdateBindings(extension->id());
+}
+
+void Dispatcher::OnUpdateTabSpecificPermissions(
+    int page_id,
+    int tab_id,
+    const std::string& extension_id,
+    const URLPatternSet& origin_set) {
+  delegate_->UpdateTabSpecificPermissions(
+      this, page_id, tab_id, extension_id, origin_set);
+}
+
+void Dispatcher::OnUpdateUserScripts(base::SharedMemoryHandle scripts) {
+  DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle";
+  user_script_slave_->UpdateScripts(scripts);
+  UpdateActiveExtensions();
+}
+
+void Dispatcher::OnUsingWebRequestAPI(bool adblock,
+                                      bool adblock_plus,
+                                      bool other_webrequest) {
+  delegate_->HandleWebRequestAPIUsage(adblock, adblock_plus, other_webrequest);
+}
+
+void Dispatcher::UpdateActiveExtensions() {
+  std::set<std::string> active_extensions = active_extension_ids_;
+  user_script_slave_->GetActiveExtensions(&active_extensions);
+  delegate_->OnActiveExtensionsUpdated(active_extensions);
+}
+
+void Dispatcher::InitOriginPermissions(const Extension* extension,
+                                       Feature::Context context_type) {
+  delegate_->InitOriginPermissions(extension, context_type);
+  UpdateOriginPermissions(
+      UpdatedExtensionPermissionsInfo::ADDED,
+      extension,
+      PermissionsData::GetEffectiveHostPermissions(extension));
+}
+
+void Dispatcher::UpdateOriginPermissions(
+    UpdatedExtensionPermissionsInfo::Reason reason,
+    const Extension* extension,
+    const URLPatternSet& origins) {
+  for (URLPatternSet::const_iterator i = origins.begin(); i != origins.end();
+       ++i) {
+    const char* schemes[] = {
+        url::kHttpScheme,
+        url::kHttpsScheme,
+        content::kFileScheme,
+        content::kChromeUIScheme,
+        content::kFtpScheme,
+    };
+    for (size_t j = 0; j < arraysize(schemes); ++j) {
+      if (i->MatchesScheme(schemes[j])) {
+        ((reason == UpdatedExtensionPermissionsInfo::REMOVED)
+             ? WebSecurityPolicy::removeOriginAccessWhitelistEntry
+             : WebSecurityPolicy::addOriginAccessWhitelistEntry)(
+            extension->url(),
+            WebString::fromUTF8(schemes[j]),
+            WebString::fromUTF8(i->host()),
+            i->match_subdomains());
+      }
+    }
+  }
+}
+
+void Dispatcher::EnableCustomElementWhiteList() {
+  blink::WebCustomElement::addEmbedderCustomElementName("webview");
+  // TODO(fsamuel): Add <adview> to the whitelist once it has been converted
+  // into a custom element.
+  blink::WebCustomElement::addEmbedderCustomElementName("browser-plugin");
+}
+
+void Dispatcher::UpdateBindings(const std::string& extension_id) {
+  script_context_set().ForEach(extension_id,
+                               NULL,  // all render views
+                               base::Bind(&Dispatcher::UpdateBindingsForContext,
+                                          base::Unretained(this)));
+}
+
+void Dispatcher::UpdateBindingsForContext(ScriptContext* context) {
+  v8::HandleScope handle_scope(context->isolate());
+  v8::Context::Scope context_scope(context->v8_context());
+
+  // TODO(kalman): Make the bindings registration have zero overhead then run
+  // the same code regardless of context type.
+  switch (context->context_type()) {
+    case Feature::UNSPECIFIED_CONTEXT:
+    case Feature::WEB_PAGE_CONTEXT:
+    case Feature::BLESSED_WEB_PAGE_CONTEXT: {
+      // Web page context; it's too expensive to run the full bindings code.
+      // Hard-code that the app and webstore APIs are available...
+      RegisterBinding("app", context);
+      RegisterBinding("webstore", context);
+
+      // ... and that the runtime API might be available if any extension can
+      // connect to it.
+      bool runtime_is_available = false;
+      for (ExtensionSet::const_iterator it = extensions_.begin();
+           it != extensions_.end();
+           ++it) {
+        ExternallyConnectableInfo* info =
+            static_cast<ExternallyConnectableInfo*>(
+                (*it)->GetManifestData(manifest_keys::kExternallyConnectable));
+        if (info && info->matches.MatchesURL(context->GetURL())) {
+          runtime_is_available = true;
+          break;
+        }
+      }
+      if (runtime_is_available)
+        RegisterBinding("runtime", context);
+      break;
+    }
+
+    case Feature::BLESSED_EXTENSION_CONTEXT:
+    case Feature::UNBLESSED_EXTENSION_CONTEXT:
+    case Feature::CONTENT_SCRIPT_CONTEXT: {
+      // Extension context; iterate through all the APIs and bind the available
+      // ones.
+      FeatureProvider* api_feature_provider = FeatureProvider::GetAPIFeatures();
+      const std::vector<std::string>& apis =
+          api_feature_provider->GetAllFeatureNames();
+      for (std::vector<std::string>::const_iterator it = apis.begin();
+           it != apis.end();
+           ++it) {
+        const std::string& api_name = *it;
+        Feature* feature = api_feature_provider->GetFeature(api_name);
+        DCHECK(feature);
+
+        // Internal APIs are included via require(api_name) from internal code
+        // rather than chrome[api_name].
+        if (feature->IsInternal())
+          continue;
+
+        // If this API has a parent feature (and isn't marked 'noparent'),
+        // then this must be a function or event, so we should not register.
+        if (api_feature_provider->GetParent(feature) != NULL)
+          continue;
+
+        if (context->IsAnyFeatureAvailableToContext(*feature))
+          RegisterBinding(api_name, context);
+      }
+      if (CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType)) {
+        RegisterBinding("test", context);
+      }
+      break;
+    }
+  }
+}
+
+void Dispatcher::RegisterBinding(const std::string& api_name,
+                                 ScriptContext* context) {
+  std::string bind_name;
+  v8::Handle<v8::Object> bind_object =
+      GetOrCreateBindObjectIfAvailable(api_name, &bind_name, context);
+
+  // Empty if the bind object failed to be created, probably because the
+  // extension overrode chrome with a non-object, e.g. window.chrome = true.
+  if (bind_object.IsEmpty())
+    return;
+
+  v8::Local<v8::String> v8_api_name =
+      v8::String::NewFromUtf8(context->isolate(), api_name.c_str());
+  if (bind_object->HasRealNamedProperty(v8_api_name)) {
+    // The bind object may already have the property if the API has been
+    // registered before (or if the extension has put something there already,
+    // but, whatevs).
+    //
+    // In the former case, we need to re-register the bindings for the APIs
+    // which the extension now has permissions for (if any), but not touch any
+    // others so that we don't destroy state such as event listeners.
+    //
+    // TODO(kalman): Only register available APIs to make this all moot.
+    if (bind_object->HasRealNamedCallbackProperty(v8_api_name))
+      return;  // lazy binding still there, nothing to do
+    if (bind_object->Get(v8_api_name)->IsObject())
+      return;  // binding has already been fully installed
+  }
+
+  ModuleSystem* module_system = context->module_system();
+  if (!source_map_.Contains(api_name)) {
+    module_system->RegisterNativeHandler(
+        api_name,
+        scoped_ptr<NativeHandler>(new BindingGeneratingNativeHandler(
+            module_system, api_name, "binding")));
+    module_system->SetNativeLazyField(
+        bind_object, bind_name, api_name, "binding");
+  } else {
+    module_system->SetLazyField(bind_object, bind_name, api_name, "binding");
+  }
+}
+
+// NOTE: please use the naming convention "foo_natives" for these.
+void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system,
+                                        ScriptContext* context) {
+  module_system->RegisterNativeHandler(
+      "chrome", scoped_ptr<NativeHandler>(new ChromeNativeHandler(context)));
+  module_system->RegisterNativeHandler(
+      "lazy_background_page",
+      scoped_ptr<NativeHandler>(new LazyBackgroundPageNativeHandler(context)));
+  module_system->RegisterNativeHandler(
+      "logging", scoped_ptr<NativeHandler>(new LoggingNativeHandler(context)));
+  module_system->RegisterNativeHandler("schema_registry",
+                                       v8_schema_registry_->AsNativeHandler());
+  module_system->RegisterNativeHandler(
+      "print", scoped_ptr<NativeHandler>(new PrintNativeHandler(context)));
+  module_system->RegisterNativeHandler(
+      "test_features",
+      scoped_ptr<NativeHandler>(new TestFeaturesNativeHandler(context)));
+  module_system->RegisterNativeHandler(
+      "user_gestures",
+      scoped_ptr<NativeHandler>(new UserGesturesNativeHandler(context)));
+  module_system->RegisterNativeHandler(
+      "utils", scoped_ptr<NativeHandler>(new UtilsNativeHandler(context)));
+  module_system->RegisterNativeHandler(
+      "v8_context",
+      scoped_ptr<NativeHandler>(new V8ContextNativeHandler(context, this)));
+
+  const Extension* extension = context->extension();
+  int manifest_version = extension ? extension->manifest_version() : 1;
+  bool send_request_disabled =
+      (extension && Manifest::IsUnpackedLocation(extension->location()) &&
+       BackgroundInfo::HasLazyBackgroundPage(extension));
+  module_system->RegisterNativeHandler(
+      "process",
+      scoped_ptr<NativeHandler>(new ProcessInfoNativeHandler(
+          context,
+          context->GetExtensionID(),
+          context->GetContextTypeDescription(),
+          ExtensionsRendererClient::Get()->IsIncognitoProcess(),
+          manifest_version,
+          send_request_disabled)));
+
+  module_system->RegisterNativeHandler(
+      "event_natives",
+      scoped_ptr<NativeHandler>(new EventBindings(this, context)));
+  module_system->RegisterNativeHandler(
+      "messaging_natives",
+      scoped_ptr<NativeHandler>(MessagingBindings::Get(this, context)));
+  module_system->RegisterNativeHandler(
+      "apiDefinitions",
+      scoped_ptr<NativeHandler>(new ApiDefinitionsNatives(this, context)));
+  module_system->RegisterNativeHandler(
+      "sendRequest",
+      scoped_ptr<NativeHandler>(
+          new SendRequestNatives(request_sender_.get(), context)));
+  module_system->RegisterNativeHandler(
+      "setIcon",
+      scoped_ptr<NativeHandler>(
+          new SetIconNatives(request_sender_.get(), context)));
+  module_system->RegisterNativeHandler(
+      "activityLogger",
+      scoped_ptr<NativeHandler>(new APIActivityLogger(context)));
+  module_system->RegisterNativeHandler(
+      "renderViewObserverNatives",
+      scoped_ptr<NativeHandler>(new RenderViewObserverNatives(context)));
+
+  // Natives used by multiple APIs.
+  module_system->RegisterNativeHandler(
+      "file_system_natives",
+      scoped_ptr<NativeHandler>(new FileSystemNatives(context)));
+
+  // Custom bindings.
+  module_system->RegisterNativeHandler(
+      "app_runtime",
+      scoped_ptr<NativeHandler>(new AppRuntimeCustomBindings(context)));
+  module_system->RegisterNativeHandler(
+      "blob_natives",
+      scoped_ptr<NativeHandler>(new BlobNativeHandler(context)));
+  module_system->RegisterNativeHandler(
+      "context_menus",
+      scoped_ptr<NativeHandler>(new ContextMenusCustomBindings(context)));
+  module_system->RegisterNativeHandler(
+      "css_natives", scoped_ptr<NativeHandler>(new CssNativeHandler(context)));
+  module_system->RegisterNativeHandler(
+      "document_natives",
+      scoped_ptr<NativeHandler>(new DocumentCustomBindings(context)));
+  module_system->RegisterNativeHandler(
+      "i18n", scoped_ptr<NativeHandler>(new I18NCustomBindings(context)));
+  module_system->RegisterNativeHandler(
+      "id_generator",
+      scoped_ptr<NativeHandler>(new IdGeneratorCustomBindings(context)));
+  module_system->RegisterNativeHandler(
+      "runtime", scoped_ptr<NativeHandler>(new RuntimeCustomBindings(context)));
+
+  delegate_->RegisterNativeHandlers(this, module_system, context);
+}
+
+void Dispatcher::PopulateSourceMap() {
+  // Libraries.
+  source_map_.RegisterSource("entryIdManager", IDR_ENTRY_ID_MANAGER);
+  source_map_.RegisterSource(kEventBindings, IDR_EVENT_BINDINGS_JS);
+  source_map_.RegisterSource("imageUtil", IDR_IMAGE_UTIL_JS);
+  source_map_.RegisterSource("json_schema", IDR_JSON_SCHEMA_JS);
+  source_map_.RegisterSource("lastError", IDR_LAST_ERROR_JS);
+  source_map_.RegisterSource("messaging", IDR_MESSAGING_JS);
+  source_map_.RegisterSource("messaging_utils", IDR_MESSAGING_UTILS_JS);
+  source_map_.RegisterSource(kSchemaUtils, IDR_SCHEMA_UTILS_JS);
+  source_map_.RegisterSource("sendRequest", IDR_SEND_REQUEST_JS);
+  source_map_.RegisterSource("setIcon", IDR_SET_ICON_JS);
+  source_map_.RegisterSource("test", IDR_TEST_CUSTOM_BINDINGS_JS);
+  source_map_.RegisterSource("uncaught_exception_handler",
+                             IDR_UNCAUGHT_EXCEPTION_HANDLER_JS);
+  source_map_.RegisterSource("unload_event", IDR_UNLOAD_EVENT_JS);
+  source_map_.RegisterSource("utils", IDR_UTILS_JS);
+
+  // Custom bindings.
+  source_map_.RegisterSource("app.runtime", IDR_APP_RUNTIME_CUSTOM_BINDINGS_JS);
+  source_map_.RegisterSource("contextMenus",
+                             IDR_CONTEXT_MENUS_CUSTOM_BINDINGS_JS);
+  source_map_.RegisterSource("extension", IDR_EXTENSION_CUSTOM_BINDINGS_JS);
+  source_map_.RegisterSource("i18n", IDR_I18N_CUSTOM_BINDINGS_JS);
+  source_map_.RegisterSource("permissions", IDR_PERMISSIONS_CUSTOM_BINDINGS_JS);
+  source_map_.RegisterSource("runtime", IDR_RUNTIME_CUSTOM_BINDINGS_JS);
+  source_map_.RegisterSource("binding", IDR_BINDING_JS);
+
+  // Custom types sources.
+  source_map_.RegisterSource("StorageArea", IDR_STORAGE_AREA_JS);
+
+  // Platform app sources that are not API-specific..
+  source_map_.RegisterSource("platformApp", IDR_PLATFORM_APP_JS);
+
+  delegate_->PopulateSourceMap(&source_map_);
+}
+
+bool Dispatcher::IsWithinPlatformApp() {
+  for (std::set<std::string>::iterator iter = active_extension_ids_.begin();
+       iter != active_extension_ids_.end();
+       ++iter) {
+    const Extension* extension = extensions_.GetByID(*iter);
+    if (extension && extension->is_platform_app())
+      return true;
+  }
+  return false;
+}
+
+// TODO(kalman): This is checking for the wrong thing, it should be checking if
+// the frame's security origin is unique. The extension sandbox directive is
+// checked for in extensions/common/manifest_handlers/csp_info.cc.
+bool Dispatcher::IsSandboxedPage(const GURL& url) const {
+  if (url.SchemeIs(kExtensionScheme)) {
+    const Extension* extension = extensions_.GetByID(url.host());
+    if (extension) {
+      return SandboxedPageInfo::IsSandboxedPage(extension, url.path());
+    }
+  }
+  return false;
+}
+
+Feature::Context Dispatcher::ClassifyJavaScriptContext(
+    const Extension* extension,
+    int extension_group,
+    const GURL& url,
+    const blink::WebSecurityOrigin& origin) {
+  DCHECK_GE(extension_group, 0);
+  if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) {
+    return extension ?  // TODO(kalman): when does this happen?
+               Feature::CONTENT_SCRIPT_CONTEXT
+                     : Feature::UNSPECIFIED_CONTEXT;
+  }
+
+  // We have an explicit check for sandboxed pages before checking whether the
+  // extension is active in this process because:
+  // 1. Sandboxed pages run in the same process as regular extension pages, so
+  //    the extension is considered active.
+  // 2. ScriptContext creation (which triggers bindings injection) happens
+  //    before the SecurityContext is updated with the sandbox flags (after
+  //    reading the CSP header), so the caller can't check if the context's
+  //    security origin is unique yet.
+  if (IsSandboxedPage(url))
+    return Feature::WEB_PAGE_CONTEXT;
+
+  if (extension && IsExtensionActive(extension->id())) {
+    // |extension| is active in this process, but it could be either a true
+    // extension process or within the extent of a hosted app. In the latter
+    // case this would usually be considered a (blessed) web page context,
+    // unless the extension in question is a component extension, in which case
+    // we cheat and call it blessed.
+    return (extension->is_hosted_app() &&
+            extension->location() != Manifest::COMPONENT)
+               ? Feature::BLESSED_WEB_PAGE_CONTEXT
+               : Feature::BLESSED_EXTENSION_CONTEXT;
+  }
+
+  // TODO(kalman): This isUnique() check is wrong, it should be performed as
+  // part of IsSandboxedPage().
+  if (!origin.isUnique() && extensions_.ExtensionBindingsAllowed(url)) {
+    if (!extension)  // TODO(kalman): when does this happen?
+      return Feature::UNSPECIFIED_CONTEXT;
+    return extension->is_hosted_app() ? Feature::BLESSED_WEB_PAGE_CONTEXT
+                                      : Feature::UNBLESSED_EXTENSION_CONTEXT;
+  }
+
+  if (url.is_valid())
+    return Feature::WEB_PAGE_CONTEXT;
+
+  return Feature::UNSPECIFIED_CONTEXT;
+}
+
+v8::Handle<v8::Object> Dispatcher::GetOrCreateObject(
+    const v8::Handle<v8::Object>& object,
+    const std::string& field,
+    v8::Isolate* isolate) {
+  v8::Handle<v8::String> key = v8::String::NewFromUtf8(isolate, field.c_str());
+  // If the object has a callback property, it is assumed it is an unavailable
+  // API, so it is safe to delete. This is checked before GetOrCreateObject is
+  // called.
+  if (object->HasRealNamedCallbackProperty(key)) {
+    object->Delete(key);
+  } else if (object->HasRealNamedProperty(key)) {
+    v8::Handle<v8::Value> value = object->Get(key);
+    CHECK(value->IsObject());
+    return v8::Handle<v8::Object>::Cast(value);
+  }
+
+  v8::Handle<v8::Object> new_object = v8::Object::New(isolate);
+  object->Set(key, new_object);
+  return new_object;
+}
+
+v8::Handle<v8::Object> Dispatcher::GetOrCreateBindObjectIfAvailable(
+    const std::string& api_name,
+    std::string* bind_name,
+    ScriptContext* context) {
+  std::vector<std::string> split;
+  base::SplitString(api_name, '.', &split);
+
+  v8::Handle<v8::Object> bind_object;
+
+  // Check if this API has an ancestor. If the API's ancestor is available and
+  // the API is not available, don't install the bindings for this API. If
+  // the API is available and its ancestor is not, delete the ancestor and
+  // install the bindings for the API. This is to prevent loading the ancestor
+  // API schema if it will not be needed.
+  //
+  // For example:
+  //  If app is available and app.window is not, just install app.
+  //  If app.window is available and app is not, delete app and install
+  //  app.window on a new object so app does not have to be loaded.
+  FeatureProvider* api_feature_provider = FeatureProvider::GetAPIFeatures();
+  std::string ancestor_name;
+  bool only_ancestor_available = false;
+
+  for (size_t i = 0; i < split.size() - 1; ++i) {
+    ancestor_name += (i ? "." : "") + split[i];
+    if (api_feature_provider->GetFeature(ancestor_name) &&
+        context->GetAvailability(ancestor_name).is_available() &&
+        !context->GetAvailability(api_name).is_available()) {
+      only_ancestor_available = true;
+      break;
+    }
+
+    if (bind_object.IsEmpty()) {
+      bind_object = AsObjectOrEmpty(GetOrCreateChrome(context));
+      if (bind_object.IsEmpty())
+        return v8::Handle<v8::Object>();
+    }
+    bind_object = GetOrCreateObject(bind_object, split[i], context->isolate());
+  }
+
+  if (only_ancestor_available)
+    return v8::Handle<v8::Object>();
+
+  if (bind_name)
+    *bind_name = split.back();
+
+  return bind_object.IsEmpty() ? AsObjectOrEmpty(GetOrCreateChrome(context))
+                               : bind_object;
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/dispatcher.h b/extensions/renderer/dispatcher.h
new file mode 100644
index 0000000..e4d7aed
--- /dev/null
+++ b/extensions/renderer/dispatcher.h
@@ -0,0 +1,293 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_DISPATCHER_H_
+#define EXTENSIONS_RENDERER_DISPATCHER_H_
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/memory/shared_memory.h"
+#include "base/timer/timer.h"
+#include "content/public/renderer/render_process_observer.h"
+#include "extensions/common/event_filter.h"
+#include "extensions/common/extension_set.h"
+#include "extensions/common/extensions_client.h"
+#include "extensions/common/features/feature.h"
+#include "extensions/renderer/resource_bundle_source_map.h"
+#include "extensions/renderer/script_context.h"
+#include "extensions/renderer/script_context_set.h"
+#include "extensions/renderer/v8_schema_registry.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/platform/WebVector.h"
+#include "v8/include/v8.h"
+
+class ChromeRenderViewTest;
+class GURL;
+class ModuleSystem;
+class URLPattern;
+struct ExtensionMsg_ExternalConnectionInfo;
+struct ExtensionMsg_Loaded_Params;
+struct ExtensionMsg_UpdatePermissions_Params;
+
+namespace blink {
+class WebFrame;
+class WebSecurityOrigin;
+}
+
+namespace base {
+class DictionaryValue;
+class ListValue;
+}
+
+namespace content {
+class RenderThread;
+}
+
+namespace extensions {
+class ContentWatcher;
+class DispatcherDelegate;
+class Extension;
+class FilteredEventRouter;
+class ManifestPermissionSet;
+class RequestSender;
+class ScriptContext;
+class UserScriptSlave;
+struct Message;
+
+// Dispatches extension control messages sent to the renderer and stores
+// renderer extension related state.
+class Dispatcher : public content::RenderProcessObserver {
+ public:
+  explicit Dispatcher(DispatcherDelegate* delegate);
+  virtual ~Dispatcher();
+
+  const std::set<std::string>& function_names() const {
+    return function_names_;
+  }
+
+  bool is_extension_process() const { return is_extension_process_; }
+
+  const ExtensionSet* extensions() const { return &extensions_; }
+
+  const ScriptContextSet& script_context_set() const {
+    return script_context_set_;
+  }
+
+  V8SchemaRegistry* v8_schema_registry() { return v8_schema_registry_.get(); }
+
+  ContentWatcher* content_watcher() { return content_watcher_.get(); }
+
+  UserScriptSlave* user_script_slave() { return user_script_slave_.get(); }
+
+  RequestSender* request_sender() { return request_sender_.get(); }
+
+  bool IsExtensionActive(const std::string& extension_id) const;
+
+  // Finds the extension ID for the JavaScript context associated with the
+  // specified |frame| and isolated world. If |world_id| is zero, finds the
+  // extension ID associated with the main world's JavaScript context. If the
+  // JavaScript context isn't from an extension, returns empty string.
+  std::string GetExtensionID(const blink::WebFrame* frame, int world_id);
+
+  void DidCreateScriptContext(blink::WebFrame* frame,
+                              const v8::Handle<v8::Context>& context,
+                              int extension_group,
+                              int world_id);
+
+  void WillReleaseScriptContext(blink::WebFrame* frame,
+                                const v8::Handle<v8::Context>& context,
+                                int world_id);
+
+  void DidCreateDocumentElement(blink::WebFrame* frame);
+
+  void DidMatchCSS(
+      blink::WebFrame* frame,
+      const blink::WebVector<blink::WebString>& newly_matching_selectors,
+      const blink::WebVector<blink::WebString>& stopped_matching_selectors);
+
+  void OnExtensionResponse(int request_id,
+                           bool success,
+                           const base::ListValue& response,
+                           const std::string& error);
+
+  // Checks that the current context contains an extension that has permission
+  // to execute the specified function. If it does not, a v8 exception is thrown
+  // and the method returns false. Otherwise returns true.
+  bool CheckContextAccessToExtensionAPI(const std::string& function_name,
+                                        ScriptContext* context) const;
+
+  // Dispatches the event named |event_name| to all render views.
+  void DispatchEvent(const std::string& extension_id,
+                     const std::string& event_name) const;
+
+  // Shared implementation of the various MessageInvoke IPCs.
+  void InvokeModuleSystemMethod(content::RenderView* render_view,
+                                const std::string& extension_id,
+                                const std::string& module_name,
+                                const std::string& function_name,
+                                const base::ListValue& args,
+                                bool user_gesture);
+
+  void ClearPortData(int port_id);
+
+ private:
+  friend class ::ChromeRenderViewTest;
+  FRIEND_TEST_ALL_PREFIXES(RendererPermissionsPolicyDelegateTest,
+                           CannotScriptWebstore);
+
+  // RenderProcessObserver implementation:
+  virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE;
+  virtual void WebKitInitialized() OVERRIDE;
+  virtual void IdleNotification() OVERRIDE;
+  virtual void OnRenderProcessShutdown() OVERRIDE;
+
+  void OnActivateExtension(const std::string& extension_id);
+  void OnCancelSuspend(const std::string& extension_id);
+  void OnClearTabSpecificPermissions(
+      int tab_id,
+      const std::vector<std::string>& extension_ids);
+  void OnDeliverMessage(int target_port_id, const Message& message);
+  void OnDispatchOnConnect(int target_port_id,
+                           const std::string& channel_name,
+                           const base::DictionaryValue& source_tab,
+                           const ExtensionMsg_ExternalConnectionInfo& info,
+                           const std::string& tls_channel_id);
+  void OnDispatchOnDisconnect(int port_id, const std::string& error_message);
+  void OnLoaded(
+      const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions);
+  void OnLoadedInternal(scoped_refptr<const Extension> extension);
+  void OnMessageInvoke(const std::string& extension_id,
+                       const std::string& module_name,
+                       const std::string& function_name,
+                       const base::ListValue& args,
+                       bool user_gesture);
+  void OnSetChannel(int channel);
+  void OnSetFunctionNames(const std::vector<std::string>& names);
+  void OnSetScriptingWhitelist(
+      const ExtensionsClient::ScriptingWhitelist& extension_ids);
+  void OnSetSystemFont(const std::string& font_family,
+                       const std::string& font_size);
+  void OnShouldSuspend(const std::string& extension_id, int sequence_id);
+  void OnSuspend(const std::string& extension_id);
+  void OnUnloaded(const std::string& id);
+  void OnUpdatePermissions(const ExtensionMsg_UpdatePermissions_Params& params);
+  void OnUpdateTabSpecificPermissions(int page_id,
+                                      int tab_id,
+                                      const std::string& extension_id,
+                                      const URLPatternSet& origin_set);
+  void OnUpdateUserScripts(base::SharedMemoryHandle scripts);
+  void OnUsingWebRequestAPI(bool adblock,
+                            bool adblock_plus,
+                            bool other_webrequest);
+
+  void UpdateActiveExtensions();
+
+  // Sets up the host permissions for |extension|.
+  void InitOriginPermissions(const Extension* extension,
+                             Feature::Context context_type);
+  void UpdateOriginPermissions(UpdatedExtensionPermissionsInfo::Reason reason,
+                               const Extension* extension,
+                               const URLPatternSet& origins);
+
+  // Enable custom element whitelist in Apps.
+  void EnableCustomElementWhiteList();
+
+  // Adds or removes bindings for every context belonging to |extension_id|, or
+  // or all contexts if |extension_id| is empty.
+  void UpdateBindings(const std::string& extension_id);
+
+  void UpdateBindingsForContext(ScriptContext* context);
+
+  void RegisterBinding(const std::string& api_name, ScriptContext* context);
+
+  void RegisterNativeHandlers(ModuleSystem* module_system,
+                              ScriptContext* context);
+
+  // Inserts static source code into |source_map_|.
+  void PopulateSourceMap();
+
+  // Returns whether the current renderer hosts a platform app.
+  bool IsWithinPlatformApp();
+
+  bool IsSandboxedPage(const GURL& url) const;
+
+  // Returns the Feature::Context type of context for a JavaScript context.
+  Feature::Context ClassifyJavaScriptContext(
+      const Extension* extension,
+      int extension_group,
+      const GURL& url,
+      const blink::WebSecurityOrigin& origin);
+
+  // Gets |field| from |object| or creates it as an empty object if it doesn't
+  // exist.
+  v8::Handle<v8::Object> GetOrCreateObject(const v8::Handle<v8::Object>& object,
+                                           const std::string& field,
+                                           v8::Isolate* isolate);
+
+  v8::Handle<v8::Object> GetOrCreateBindObjectIfAvailable(
+      const std::string& api_name,
+      std::string* bind_name,
+      ScriptContext* context);
+
+  // The delegate for this dispatcher. Not owned, but must extend beyond the
+  // Dispatcher's own lifetime.
+  DispatcherDelegate* delegate_;
+
+  // True if this renderer is running extensions.
+  bool is_extension_process_;
+
+  // Contains all loaded extensions.  This is essentially the renderer
+  // counterpart to ExtensionService in the browser. It contains information
+  // about all extensions currently loaded by the browser.
+  ExtensionSet extensions_;
+
+  // The IDs of extensions that failed to load, mapped to the error message
+  // generated on failure.
+  std::map<std::string, std::string> extension_load_errors_;
+
+  // All the bindings contexts that are currently loaded for this renderer.
+  // There is zero or one for each v8 context.
+  ScriptContextSet script_context_set_;
+
+  scoped_ptr<ContentWatcher> content_watcher_;
+
+  scoped_ptr<UserScriptSlave> user_script_slave_;
+
+  // Same as above, but on a longer timer and will run even if the process is
+  // not idle, to ensure that IdleHandle gets called eventually.
+  scoped_ptr<base::RepeatingTimer<content::RenderThread> > forced_idle_timer_;
+
+  // All declared function names.
+  std::set<std::string> function_names_;
+
+  // The extensions and apps that are active in this process.
+  std::set<std::string> active_extension_ids_;
+
+  ResourceBundleSourceMap source_map_;
+
+  // Cache for the v8 representation of extension API schemas.
+  scoped_ptr<V8SchemaRegistry> v8_schema_registry_;
+
+  // Sends API requests to the extension host.
+  scoped_ptr<RequestSender> request_sender_;
+
+  // The platforms system font family and size;
+  std::string system_font_family_;
+  std::string system_font_size_;
+
+  // Mapping of port IDs to tabs. If there is no tab, the value would be -1.
+  std::map<int, int> port_to_tab_id_map_;
+
+  // True once WebKit has been initialized (and it is therefore safe to poke).
+  bool is_webkit_initialized_;
+
+  DISALLOW_COPY_AND_ASSIGN(Dispatcher);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_DISPATCHER_H_
diff --git a/extensions/renderer/dispatcher_delegate.h b/extensions/renderer/dispatcher_delegate.h
new file mode 100644
index 0000000..13d557f
--- /dev/null
+++ b/extensions/renderer/dispatcher_delegate.h
@@ -0,0 +1,96 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_DISPATCHER_DELEGATE_H
+#define EXTENSIONS_RENDERER_DISPATCHER_DELEGATE_H
+
+#include <set>
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "extensions/common/features/feature.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+class WebFrame;
+}
+
+namespace extensions {
+class Dispatcher;
+class Extension;
+class ModuleSystem;
+class ResourceBundleSourceMap;
+class ScriptContext;
+class URLPatternSet;
+
+// Base class and default implementation for an extensions::Dispacher delegate.
+// DispatcherDelegate can be used to override and extend the behavior of the
+// extensions system's renderer side.
+class DispatcherDelegate {
+ public:
+  virtual ~DispatcherDelegate() {}
+
+  // Creates a new ScriptContext for a given v8 context.
+  virtual scoped_ptr<ScriptContext> CreateScriptContext(
+      const v8::Handle<v8::Context>& v8_context,
+      blink::WebFrame* frame,
+      const Extension* extension,
+      Feature::Context context_type) = 0;
+
+  // Initializes origin permissions for a newly created extension context.
+  virtual void InitOriginPermissions(const Extension* extension,
+                                     Feature::Context context_type) {}
+
+  // Includes additional native handlers in a given ModuleSystem.
+  virtual void RegisterNativeHandlers(Dispatcher* dispatcher,
+                                      ModuleSystem* module_system,
+                                      ScriptContext* context) {}
+
+  // Includes additional source resources into the resource map.
+  virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) {}
+
+  // Requires additional modules within an extension context's module system.
+  virtual void RequireAdditionalModules(ModuleSystem* module_system,
+                                        const Extension* extension,
+                                        Feature::Context context_type,
+                                        bool is_within_platform_app) {}
+
+  // Allows the delegate to respond to an updated set of active extensions in
+  // the Dispatcher.
+  virtual void OnActiveExtensionsUpdated(
+      const std::set<std::string>& extension_ids) {}
+
+  // Sets the current Chrome channel.
+  // TODO(rockot): This doesn't belong in a generic extensions system interface.
+  // See http://crbug.com/368431.
+  virtual void SetChannel(int channel) {}
+
+  // Clears extension permissions specific to a given tab.
+  // TODO(rockot): This doesn't belong in a generic extensions system interface.
+  // See http://crbug.com/368431.
+  virtual void ClearTabSpecificPermissions(
+      const extensions::Dispatcher* dispatcher,
+      int tab_id,
+      const std::vector<std::string>& extension_ids) {}
+
+  // Updates extension permissions specific to a given tab.
+  // TODO(rockot): This doesn't belong in a generic extensions system interface.
+  // See http://crbug.com/368431.
+  virtual void UpdateTabSpecificPermissions(
+      const extensions::Dispatcher* dispatcher,
+      int page_id,
+      int tab_id,
+      const std::string& extension_id,
+      const extensions::URLPatternSet& origin_set) {}
+
+  // Allows the delegate to respond to reports from the browser about WebRequest
+  // API usage from within this process.
+  virtual void HandleWebRequestAPIUsage(bool adblock,
+                                        bool adblock_plus,
+                                        bool other_webrequest) {}
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_DISPATCHER_DELEGATE_H
diff --git a/extensions/renderer/dom_activity_logger.cc b/extensions/renderer/dom_activity_logger.cc
index 6e74e9e..1d71ead 100644
--- a/extensions/renderer/dom_activity_logger.cc
+++ b/extensions/renderer/dom_activity_logger.cc
@@ -12,8 +12,6 @@
 #include "extensions/renderer/activity_log_converter_strategy.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
-#include "third_party/WebKit/public/web/WebDOMActivityLogger.h"
-#include "v8/include/v8.h"
 
 using content::V8ValueConverter;
 using blink::WebString;
@@ -21,50 +19,35 @@
 
 namespace extensions {
 
+namespace {
+
+// Converts the given |v8_value| and appends it to the given |list|, if the
+// conversion succeeds.
+void AppendV8Value(const std::string& api_name,
+                   const v8::Handle<v8::Value>& v8_value,
+                   base::ListValue* list) {
+  DCHECK(list);
+  scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
+  ActivityLogConverterStrategy strategy;
+  strategy.set_enable_detailed_parsing(
+      ad_injection_constants::ApiCanInjectAds(api_name));
+  converter->SetFunctionAllowed(true);
+  converter->SetStrategy(&strategy);
+  scoped_ptr<base::Value> value(converter->FromV8Value(
+      v8_value, v8::Isolate::GetCurrent()->GetCurrentContext()));
+
+  if (value.get())
+    list->Append(value.release());
+}
+
+}  // namespace
+
 DOMActivityLogger::DOMActivityLogger(const std::string& extension_id)
     : extension_id_(extension_id) {
 }
 
 DOMActivityLogger::~DOMActivityLogger() {}
 
-void DOMActivityLogger::log(
-    const WebString& api_name,
-    int argc,
-    const v8::Handle<v8::Value> argv[],
-    const WebString& call_type,
-    const WebURL& url,
-    const WebString& title) {
-  scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
-  ActivityLogConverterStrategy strategy;
-  strategy.set_enable_detailed_parsing(
-      ad_injection_constants::ApiCanInjectAds(api_name.utf8().c_str()));
-  converter->SetFunctionAllowed(true);
-  converter->SetStrategy(&strategy);
-  scoped_ptr<base::ListValue> argv_list_value(new base::ListValue());
-  for (int i = 0; i < argc; i++) {
-    argv_list_value->Set(
-        i,
-        converter->FromV8Value(argv[i],
-                               v8::Isolate::GetCurrent()->GetCurrentContext()));
-  }
-
-  ExtensionHostMsg_DOMAction_Params params;
-  params.url = url;
-  params.url_title = title;
-  params.api_call = api_name.utf8();
-  params.arguments.Swap(argv_list_value.get());
-  const std::string type = call_type.utf8();
-  if (type == "Getter")
-    params.call_type = DomActionType::GETTER;
-  else if (type == "Setter")
-    params.call_type = DomActionType::SETTER;
-  else
-    params.call_type = DomActionType::METHOD;
-
-  content::RenderThread::Get()->Send(
-      new ExtensionHostMsg_AddDOMActionToActivityLog(extension_id_, params));
-}
-
 void DOMActivityLogger::AttachToWorld(int world_id,
                                       const std::string& extension_id) {
 #if defined(ENABLE_EXTENSIONS)
@@ -77,4 +60,63 @@
 #endif
 }
 
+void DOMActivityLogger::logGetter(const WebString& api_name,
+                                  const WebURL& url,
+                                  const WebString& title) {
+  SendDomActionMessage(api_name.utf8(),
+                       url,
+                       title,
+                       DomActionType::GETTER,
+                       scoped_ptr<base::ListValue>(new base::ListValue()));
+}
+
+void DOMActivityLogger::logSetter(const WebString& api_name,
+                                  const v8::Handle<v8::Value>& new_value,
+                                  const WebURL& url,
+                                  const WebString& title) {
+  logSetter(api_name, new_value, v8::Handle<v8::Value>(), url, title);
+}
+
+void DOMActivityLogger::logSetter(const WebString& api_name,
+                                  const v8::Handle<v8::Value>& new_value,
+                                  const v8::Handle<v8::Value>& old_value,
+                                  const WebURL& url,
+                                  const WebString& title) {
+  scoped_ptr<base::ListValue> args(new base::ListValue);
+  std::string api_name_utf8 = api_name.utf8();
+  AppendV8Value(api_name_utf8, new_value, args.get());
+  if (!old_value.IsEmpty())
+    AppendV8Value(api_name_utf8, old_value, args.get());
+  SendDomActionMessage(
+      api_name_utf8, url, title, DomActionType::SETTER, args.Pass());
+}
+
+void DOMActivityLogger::logMethod(const WebString& api_name,
+                                  int argc,
+                                  const v8::Handle<v8::Value>* argv,
+                                  const WebURL& url,
+                                  const WebString& title) {
+  scoped_ptr<base::ListValue> args(new base::ListValue);
+  std::string api_name_utf8 = api_name.utf8();
+  for (int i = 0; i < argc; ++i)
+    AppendV8Value(api_name_utf8, argv[i], args.get());
+  SendDomActionMessage(
+      api_name_utf8, url, title, DomActionType::METHOD, args.Pass());
+}
+
+void DOMActivityLogger::SendDomActionMessage(const std::string& api_call,
+                                             const GURL& url,
+                                             const base::string16& url_title,
+                                             DomActionType::Type call_type,
+                                             scoped_ptr<base::ListValue> args) {
+  ExtensionHostMsg_DOMAction_Params params;
+  params.api_call = api_call;
+  params.url = url;
+  params.url_title = url_title;
+  params.call_type = call_type;
+  params.arguments.Swap(args.get());
+  content::RenderThread::Get()->Send(
+      new ExtensionHostMsg_AddDOMActionToActivityLog(extension_id_, params));
+}
+
 }  // namespace extensions
diff --git a/extensions/renderer/dom_activity_logger.h b/extensions/renderer/dom_activity_logger.h
index e4b1c2b..4095146 100644
--- a/extensions/renderer/dom_activity_logger.h
+++ b/extensions/renderer/dom_activity_logger.h
@@ -8,7 +8,18 @@
 #include <string>
 
 #include "base/macros.h"
+#include "extensions/common/dom_action_types.h"
 #include "third_party/WebKit/public/web/WebDOMActivityLogger.h"
+#include "v8/include/v8.h"
+
+namespace base {
+class ListValue;
+}
+
+namespace blink {
+class WebString;
+class WebURL;
+}
 
 namespace content {
 class V8ValueConverter;
@@ -16,8 +27,6 @@
 
 namespace extensions {
 
-class ActivityLogConverterStrategy;
-
 // Used to log DOM API calls from within WebKit. The events are sent via IPC to
 // extensions::ActivityLog for recording and display.
 class DOMActivityLogger: public blink::WebDOMActivityLogger {
@@ -26,17 +35,6 @@
   explicit DOMActivityLogger(const std::string& extension_id);
   virtual ~DOMActivityLogger();
 
-  // Marshalls the arguments into an ExtensionHostMsg_DOMAction_Params
-  // and sends it over to the browser (via IPC) for appending it to the
-  // extension activity log.
-  // (Overrides the log method in blink::WebDOMActivityLogger)
-  virtual void log(const blink::WebString& api_name,
-                   int argc,
-                   const v8::Handle<v8::Value> argv[],
-                   const blink::WebString& call_type,
-                   const blink::WebURL& url,
-                   const blink::WebString& title) OVERRIDE;
-
   // Check (using the WebKit API) if there is no logger attached to the world
   // corresponding to world_id, and if so, construct a new logger and attach it.
   // world_id = 0 indicates the main world.
@@ -44,6 +42,38 @@
                             const std::string& extension_id);
 
  private:
+  // blink::WebDOMActivityLogger implementation.
+  // Marshals the arguments into an ExtensionHostMsg_DOMAction_Params and sends
+  // it over to the browser (via IPC) for appending it to the extension activity
+  // log.
+  // These methods don't have the OVERRIDE keyword due to the complexities it
+  // introduces when changes blink apis.
+  virtual void logGetter(const blink::WebString& api_name,
+                         const blink::WebURL& url,
+                         const blink::WebString& title);
+  virtual void logSetter(const blink::WebString& api_name,
+                         const v8::Handle<v8::Value>& new_value,
+                         const blink::WebURL& url,
+                         const blink::WebString& title);
+  virtual void logSetter(const blink::WebString& api_name,
+                         const v8::Handle<v8::Value>& new_value,
+                         const v8::Handle<v8::Value>& old_value,
+                         const blink::WebURL& url,
+                         const blink::WebString& title);
+  virtual void logMethod(const blink::WebString& api_name,
+                         int argc,
+                         const v8::Handle<v8::Value>* argv,
+                         const blink::WebURL& url,
+                         const blink::WebString& title);
+
+  // Helper function to actually send the message across IPC.
+  void SendDomActionMessage(const std::string& api_call,
+                            const GURL& url,
+                            const base::string16& url_title,
+                            DomActionType::Type call_type,
+                            scoped_ptr<base::ListValue> args);
+
+  // The id of the extension with which this logger is associated.
   std::string extension_id_;
 
   DISALLOW_COPY_AND_ASSIGN(DOMActivityLogger);
diff --git a/extensions/renderer/event_bindings.cc b/extensions/renderer/event_bindings.cc
index 9446595..331e651 100644
--- a/extensions/renderer/event_bindings.cc
+++ b/extensions/renderer/event_bindings.cc
@@ -13,8 +13,6 @@
 #include "base/bind.h"
 #include "base/lazy_instance.h"
 #include "base/memory/scoped_ptr.h"
-#include "chrome/renderer/extensions/dispatcher.h"
-#include "chrome/renderer/extensions/extension_helper.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/render_view.h"
 #include "content/public/renderer/v8_value_converter.h"
@@ -23,6 +21,8 @@
 #include "extensions/common/extension_messages.h"
 #include "extensions/common/manifest_handlers/background_info.h"
 #include "extensions/common/value_counter.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/extension_helper.h"
 #include "extensions/renderer/object_backed_native_handler.h"
 #include "url/gurl.h"
 #include "v8/include/v8.h"
diff --git a/extensions/renderer/extension_helper.cc b/extensions/renderer/extension_helper.cc
new file mode 100644
index 0000000..915097b
--- /dev/null
+++ b/extensions/renderer/extension_helper.cc
@@ -0,0 +1,349 @@
+// 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.
+
+#include "extensions/renderer/extension_helper.h"
+
+#include "base/lazy_instance.h"
+#include "content/public/renderer/render_view.h"
+#include "content/public/renderer/render_view_visitor.h"
+#include "extensions/common/api/messaging/message.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/extension_messages.h"
+#include "extensions/renderer/console.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/messaging_bindings.h"
+#include "extensions/renderer/user_script_scheduler.h"
+#include "extensions/renderer/user_script_slave.h"
+#include "third_party/WebKit/public/platform/WebURLRequest.h"
+#include "third_party/WebKit/public/web/WebConsoleMessage.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
+#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
+#include "third_party/WebKit/public/web/WebView.h"
+
+using content::ConsoleMessageLevel;
+using blink::WebConsoleMessage;
+using blink::WebDataSource;
+using blink::WebFrame;
+using blink::WebLocalFrame;
+using blink::WebURLRequest;
+using blink::WebScopedUserGesture;
+using blink::WebView;
+
+namespace extensions {
+
+namespace {
+// Keeps a mapping from the frame pointer to a UserScriptScheduler object.
+// We store this mapping per process, because a frame can jump from one
+// document to another with adoptNode, and so having the object be a
+// RenderViewObserver means it might miss some notifications after it moves.
+typedef std::map<WebFrame*, UserScriptScheduler*> SchedulerMap;
+static base::LazyInstance<SchedulerMap> g_schedulers =
+    LAZY_INSTANCE_INITIALIZER;
+
+// A RenderViewVisitor class that iterates through the set of available
+// views, looking for a view of the given type, in the given browser window
+// and within the given extension.
+// Used to accumulate the list of views associated with an extension.
+class ViewAccumulator : public content::RenderViewVisitor {
+ public:
+  ViewAccumulator(const std::string& extension_id,
+                  int browser_window_id,
+                  ViewType view_type)
+      : extension_id_(extension_id),
+        browser_window_id_(browser_window_id),
+        view_type_(view_type) {
+  }
+
+  std::vector<content::RenderView*> views() { return views_; }
+
+  // Returns false to terminate the iteration.
+  virtual bool Visit(content::RenderView* render_view) OVERRIDE {
+    ExtensionHelper* helper = ExtensionHelper::Get(render_view);
+    if (!ViewTypeMatches(helper->view_type(), view_type_))
+      return true;
+
+    GURL url = render_view->GetWebView()->mainFrame()->document().url();
+    if (!url.SchemeIs(kExtensionScheme))
+      return true;
+    const std::string& extension_id = url.host();
+    if (extension_id != extension_id_)
+      return true;
+
+    if (browser_window_id_ != extension_misc::kUnknownWindowId &&
+        helper->browser_window_id() != browser_window_id_) {
+      return true;
+    }
+
+    views_.push_back(render_view);
+
+    if (view_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE)
+      return false;  // There can be only one...
+    return true;
+  }
+
+ private:
+  // Returns true if |type| "isa" |match|.
+  static bool ViewTypeMatches(ViewType type, ViewType match) {
+    if (type == match)
+      return true;
+
+    // INVALID means match all.
+    if (match == VIEW_TYPE_INVALID)
+      return true;
+
+    return false;
+  }
+
+  std::string extension_id_;
+  int browser_window_id_;
+  ViewType view_type_;
+  std::vector<content::RenderView*> views_;
+};
+
+}  // namespace
+
+// static
+std::vector<content::RenderView*> ExtensionHelper::GetExtensionViews(
+    const std::string& extension_id,
+    int browser_window_id,
+    ViewType view_type) {
+  ViewAccumulator accumulator(extension_id, browser_window_id, view_type);
+  content::RenderView::ForEach(&accumulator);
+  return accumulator.views();
+}
+
+// static
+content::RenderView* ExtensionHelper::GetBackgroundPage(
+    const std::string& extension_id) {
+  ViewAccumulator accumulator(extension_id, extension_misc::kUnknownWindowId,
+                              VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
+  content::RenderView::ForEach(&accumulator);
+  CHECK_LE(accumulator.views().size(), 1u);
+  if (accumulator.views().size() == 0)
+    return NULL;
+  return accumulator.views()[0];
+}
+
+ExtensionHelper::ExtensionHelper(content::RenderView* render_view,
+                                 Dispatcher* dispatcher)
+    : content::RenderViewObserver(render_view),
+      content::RenderViewObserverTracker<ExtensionHelper>(render_view),
+      dispatcher_(dispatcher),
+      view_type_(VIEW_TYPE_INVALID),
+      tab_id_(-1),
+      browser_window_id_(-1) {
+}
+
+ExtensionHelper::~ExtensionHelper() {
+}
+
+bool ExtensionHelper::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(ExtensionHelper, message)
+    IPC_MESSAGE_HANDLER(ExtensionMsg_Response, OnExtensionResponse)
+    IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnExtensionMessageInvoke)
+    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect,
+                        OnExtensionDispatchOnConnect)
+    IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnExtensionDeliverMessage)
+    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect,
+                        OnExtensionDispatchOnDisconnect)
+    IPC_MESSAGE_HANDLER(ExtensionMsg_ExecuteCode, OnExecuteCode)
+    IPC_MESSAGE_HANDLER(ExtensionMsg_SetTabId, OnSetTabId)
+    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateBrowserWindowId,
+                        OnUpdateBrowserWindowId)
+    IPC_MESSAGE_HANDLER(ExtensionMsg_NotifyRenderViewType,
+                        OnNotifyRendererViewType)
+    IPC_MESSAGE_HANDLER(ExtensionMsg_AddMessageToConsole,
+                        OnAddMessageToConsole)
+    IPC_MESSAGE_HANDLER(ExtensionMsg_AppWindowClosed,
+                        OnAppWindowClosed);
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+void ExtensionHelper::DidFinishDocumentLoad(WebLocalFrame* frame) {
+  dispatcher_->user_script_slave()->InjectScripts(
+      frame, UserScript::DOCUMENT_END);
+
+  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
+  if (i != g_schedulers.Get().end())
+    i->second->DidFinishDocumentLoad();
+}
+
+void ExtensionHelper::DidFinishLoad(blink::WebLocalFrame* frame) {
+  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
+  if (i != g_schedulers.Get().end())
+    i->second->DidFinishLoad();
+}
+
+void ExtensionHelper::DidCreateDocumentElement(WebLocalFrame* frame) {
+  dispatcher_->user_script_slave()->InjectScripts(
+      frame, UserScript::DOCUMENT_START);
+  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
+  if (i != g_schedulers.Get().end())
+    i->second->DidCreateDocumentElement();
+
+  dispatcher_->DidCreateDocumentElement(frame);
+}
+
+void ExtensionHelper::DidStartProvisionalLoad(blink::WebLocalFrame* frame) {
+  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
+  if (i != g_schedulers.Get().end())
+    i->second->DidStartProvisionalLoad();
+}
+
+void ExtensionHelper::DraggableRegionsChanged(blink::WebFrame* frame) {
+  blink::WebVector<blink::WebDraggableRegion> webregions =
+      frame->document().draggableRegions();
+  std::vector<DraggableRegion> regions;
+  for (size_t i = 0; i < webregions.size(); ++i) {
+    DraggableRegion region;
+    region.bounds = webregions[i].bounds;
+    region.draggable = webregions[i].draggable;
+    regions.push_back(region);
+  }
+  Send(new ExtensionHostMsg_UpdateDraggableRegions(routing_id(), regions));
+}
+
+void ExtensionHelper::FrameDetached(WebFrame* frame) {
+  // This could be called before DidCreateDataSource, in which case the frame
+  // won't be in the map.
+  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
+  if (i == g_schedulers.Get().end())
+    return;
+
+  delete i->second;
+  g_schedulers.Get().erase(i);
+}
+
+void ExtensionHelper::DidMatchCSS(
+    blink::WebLocalFrame* frame,
+    const blink::WebVector<blink::WebString>& newly_matching_selectors,
+    const blink::WebVector<blink::WebString>& stopped_matching_selectors) {
+  dispatcher_->DidMatchCSS(
+      frame, newly_matching_selectors, stopped_matching_selectors);
+}
+
+void ExtensionHelper::DidCreateDataSource(WebLocalFrame* frame,
+                                          WebDataSource* ds) {
+  // Check first if we created a scheduler for the frame, since this function
+  // gets called for navigations within the document.
+  if (g_schedulers.Get().count(frame))
+    return;
+
+  g_schedulers.Get()[frame] = new UserScriptScheduler(frame, dispatcher_);
+}
+
+void ExtensionHelper::OnExtensionResponse(int request_id,
+                                          bool success,
+                                          const base::ListValue& response,
+                                          const std::string& error) {
+  dispatcher_->OnExtensionResponse(request_id,
+                                   success,
+                                   response,
+                                   error);
+}
+
+void ExtensionHelper::OnExtensionMessageInvoke(const std::string& extension_id,
+                                               const std::string& module_name,
+                                               const std::string& function_name,
+                                               const base::ListValue& args,
+                                               bool user_gesture) {
+  dispatcher_->InvokeModuleSystemMethod(
+      render_view(), extension_id, module_name, function_name, args,
+      user_gesture);
+}
+
+void ExtensionHelper::OnExtensionDispatchOnConnect(
+    int target_port_id,
+    const std::string& channel_name,
+    const base::DictionaryValue& source_tab,
+    const ExtensionMsg_ExternalConnectionInfo& info,
+    const std::string& tls_channel_id) {
+  MessagingBindings::DispatchOnConnect(
+      dispatcher_->script_context_set().GetAll(),
+      target_port_id,
+      channel_name,
+      source_tab,
+      info.source_id,
+      info.target_id,
+      info.source_url,
+      tls_channel_id,
+      render_view());
+}
+
+void ExtensionHelper::OnExtensionDeliverMessage(int target_id,
+                                                const Message& message) {
+  MessagingBindings::DeliverMessage(dispatcher_->script_context_set().GetAll(),
+                                    target_id,
+                                    message,
+                                    render_view());
+}
+
+void ExtensionHelper::OnExtensionDispatchOnDisconnect(
+    int port_id,
+    const std::string& error_message) {
+  MessagingBindings::DispatchOnDisconnect(
+      dispatcher_->script_context_set().GetAll(),
+      port_id,
+      error_message,
+      render_view());
+}
+
+void ExtensionHelper::OnExecuteCode(
+    const ExtensionMsg_ExecuteCode_Params& params) {
+  WebView* webview = render_view()->GetWebView();
+  WebFrame* main_frame = webview->mainFrame();
+  if (!main_frame) {
+    base::ListValue val;
+    Send(new ExtensionHostMsg_ExecuteCodeFinished(routing_id(),
+                                                  params.request_id,
+                                                  "No main frame",
+                                                  -1,
+                                                  GURL(std::string()),
+                                                  val));
+    return;
+  }
+
+  // chrome.tabs.executeScript() only supports execution in either the top frame
+  // or all frames.  We handle both cases in the top frame.
+  SchedulerMap::iterator i = g_schedulers.Get().find(main_frame);
+  if (i != g_schedulers.Get().end())
+    i->second->ExecuteCode(params);
+}
+
+void ExtensionHelper::OnNotifyRendererViewType(ViewType type) {
+  view_type_ = type;
+}
+
+void ExtensionHelper::OnSetTabId(int init_tab_id) {
+  CHECK_EQ(tab_id_, -1);
+  CHECK_GE(init_tab_id, 0);
+  tab_id_ = init_tab_id;
+}
+
+void ExtensionHelper::OnUpdateBrowserWindowId(int window_id) {
+  browser_window_id_ = window_id;
+}
+
+void ExtensionHelper::OnAddMessageToConsole(ConsoleMessageLevel level,
+                                            const std::string& message) {
+  console::AddMessage(render_view(), level, message);
+}
+
+void ExtensionHelper::OnAppWindowClosed() {
+  v8::HandleScope scope(v8::Isolate::GetCurrent());
+  v8::Handle<v8::Context> v8_context =
+      render_view()->GetWebView()->mainFrame()->mainWorldScriptContext();
+  ScriptContext* script_context =
+      dispatcher_->script_context_set().GetByV8Context(v8_context);
+  if (!script_context)
+    return;
+  script_context->module_system()->CallModuleMethod("app.window",
+                                                    "onAppWindowClosed");
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/extension_helper.h b/extensions/renderer/extension_helper.h
new file mode 100644
index 0000000..486db54
--- /dev/null
+++ b/extensions/renderer/extension_helper.h
@@ -0,0 +1,113 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_EXTENSION_HELPER_H_
+#define EXTENSIONS_RENDERER_EXTENSION_HELPER_H_
+
+#include <vector>
+
+#include "content/public/common/console_message_level.h"
+#include "content/public/renderer/render_view_observer.h"
+#include "content/public/renderer/render_view_observer_tracker.h"
+#include "extensions/common/view_type.h"
+
+class GURL;
+class SkBitmap;
+struct ExtensionMsg_ExecuteCode_Params;
+struct ExtensionMsg_ExternalConnectionInfo;
+
+namespace base {
+class DictionaryValue;
+class ListValue;
+}
+
+namespace extensions {
+class Dispatcher;
+struct Message;
+
+// RenderView-level plumbing for extension features.
+class ExtensionHelper
+    : public content::RenderViewObserver,
+      public content::RenderViewObserverTracker<ExtensionHelper> {
+ public:
+  // Returns a list of extension RenderViews that match the given filter
+  // criteria. If |browser_window_id| is not extension_misc::kUnknownWindowId,
+  // the list is restricted to views in that browser window.
+  static std::vector<content::RenderView*> GetExtensionViews(
+      const std::string& extension_id,
+      int browser_window_id,
+      ViewType view_type);
+
+  // Returns the given extension's background page, or NULL if none.
+  static content::RenderView* GetBackgroundPage(
+      const std::string& extension_id);
+
+  ExtensionHelper(content::RenderView* render_view, Dispatcher* dispatcher);
+  virtual ~ExtensionHelper();
+
+  int tab_id() const { return tab_id_; }
+  int browser_window_id() const { return browser_window_id_; }
+  ViewType view_type() const { return view_type_; }
+  Dispatcher* dispatcher() const { return dispatcher_; }
+
+ private:
+  // RenderViewObserver implementation.
+  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+  virtual void DidFinishDocumentLoad(blink::WebLocalFrame* frame) OVERRIDE;
+  virtual void DidFinishLoad(blink::WebLocalFrame* frame) OVERRIDE;
+  virtual void DidCreateDocumentElement(blink::WebLocalFrame* frame) OVERRIDE;
+  virtual void DidStartProvisionalLoad(blink::WebLocalFrame* frame) OVERRIDE;
+  virtual void FrameDetached(blink::WebFrame* frame) OVERRIDE;
+  virtual void DidMatchCSS(
+      blink::WebLocalFrame* frame,
+      const blink::WebVector<blink::WebString>& newly_matching_selectors,
+      const blink::WebVector<blink::WebString>& stopped_matching_selectors)
+      OVERRIDE;
+  virtual void DidCreateDataSource(blink::WebLocalFrame* frame,
+                                   blink::WebDataSource* ds) OVERRIDE;
+  virtual void DraggableRegionsChanged(blink::WebFrame* frame) OVERRIDE;
+
+  void OnExtensionResponse(int request_id, bool success,
+                           const base::ListValue& response,
+                           const std::string& error);
+  void OnExtensionMessageInvoke(const std::string& extension_id,
+                                const std::string& module_name,
+                                const std::string& function_name,
+                                const base::ListValue& args,
+                                bool user_gesture);
+  void OnExtensionDispatchOnConnect(
+      int target_port_id,
+      const std::string& channel_name,
+      const base::DictionaryValue& source_tab,
+      const ExtensionMsg_ExternalConnectionInfo& info,
+      const std::string& tls_channel_id);
+  void OnExtensionDeliverMessage(int target_port_id,
+                                 const Message& message);
+  void OnExtensionDispatchOnDisconnect(int port_id,
+                                       const std::string& error_message);
+  void OnExecuteCode(const ExtensionMsg_ExecuteCode_Params& params);
+  void OnNotifyRendererViewType(ViewType view_type);
+  void OnSetTabId(int tab_id);
+  void OnUpdateBrowserWindowId(int window_id);
+  void OnAddMessageToConsole(content::ConsoleMessageLevel level,
+                             const std::string& message);
+  void OnAppWindowClosed();
+
+  Dispatcher* dispatcher_;
+
+  // Type of view attached with RenderView.
+  ViewType view_type_;
+
+  // Id of the tab which the RenderView is attached to.
+  int tab_id_;
+
+  // Id number of browser window which RenderView is attached to.
+  int browser_window_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExtensionHelper);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_EXTENSION_HELPER_H_
diff --git a/extensions/renderer/extensions_renderer_client.h b/extensions/renderer/extensions_renderer_client.h
index 6b06b6c..ae4a31b 100644
--- a/extensions/renderer/extensions_renderer_client.h
+++ b/extensions/renderer/extensions_renderer_client.h
@@ -9,9 +9,6 @@
 
 namespace extensions {
 
-class ModuleSystem;
-class ScriptContext;
-
 // Interface to allow the extensions module to make render-process-specific
 // queries of the embedder. Should be Set() once in the render process.
 //
@@ -30,13 +27,6 @@
   // (third_party/WebKit/public/web/WebFrame.h) for additional context.
   virtual int GetLowestIsolatedWorldId() const = 0;
 
-  // Registers additional native C++ code handlers for JS API functions.
-  virtual void RegisterNativeHandlers(ModuleSystem* module_system,
-                                      ScriptContext* context) = 0;
-
-  // Registers additional JS source code resources for API implementations.
-  virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) = 0;
-
   // Returns the single instance of |this|.
   static ExtensionsRendererClient* Get();
 
diff --git a/extensions/renderer/lazy_background_page_native_handler.cc b/extensions/renderer/lazy_background_page_native_handler.cc
new file mode 100644
index 0000000..c8a31fe
--- /dev/null
+++ b/extensions/renderer/lazy_background_page_native_handler.cc
@@ -0,0 +1,62 @@
+// 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.
+
+#include "extensions/renderer/lazy_background_page_native_handler.h"
+
+#include "base/bind.h"
+#include "content/public/renderer/render_view.h"
+#include "extensions/common/extension_messages.h"
+#include "extensions/common/manifest_handlers/background_info.h"
+#include "extensions/renderer/extension_helper.h"
+#include "extensions/renderer/script_context.h"
+
+namespace extensions {
+
+LazyBackgroundPageNativeHandler::LazyBackgroundPageNativeHandler(
+    ScriptContext* context)
+    : ObjectBackedNativeHandler(context) {
+  RouteFunction(
+      "IncrementKeepaliveCount",
+      base::Bind(&LazyBackgroundPageNativeHandler::IncrementKeepaliveCount,
+                 base::Unretained(this)));
+  RouteFunction(
+      "DecrementKeepaliveCount",
+      base::Bind(&LazyBackgroundPageNativeHandler::DecrementKeepaliveCount,
+                 base::Unretained(this)));
+}
+
+void LazyBackgroundPageNativeHandler::IncrementKeepaliveCount(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  if (!context())
+    return;
+  content::RenderView* render_view = context()->GetRenderView();
+  if (IsContextLazyBackgroundPage(render_view, context()->extension())) {
+    render_view->Send(new ExtensionHostMsg_IncrementLazyKeepaliveCount(
+        render_view->GetRoutingID()));
+  }
+}
+
+void LazyBackgroundPageNativeHandler::DecrementKeepaliveCount(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  if (!context())
+    return;
+  content::RenderView* render_view = context()->GetRenderView();
+  if (IsContextLazyBackgroundPage(render_view, context()->extension())) {
+    render_view->Send(new ExtensionHostMsg_DecrementLazyKeepaliveCount(
+        render_view->GetRoutingID()));
+  }
+}
+
+bool LazyBackgroundPageNativeHandler::IsContextLazyBackgroundPage(
+    content::RenderView* render_view,
+    const Extension* extension) {
+  if (!render_view)
+    return false;
+
+  ExtensionHelper* helper = ExtensionHelper::Get(render_view);
+  return (extension && BackgroundInfo::HasLazyBackgroundPage(extension) &&
+          helper->view_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/lazy_background_page_native_handler.h b/extensions/renderer/lazy_background_page_native_handler.h
new file mode 100644
index 0000000..5ee43b2
--- /dev/null
+++ b/extensions/renderer/lazy_background_page_native_handler.h
@@ -0,0 +1,31 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_LAZY_BACKGROUND_PAGE_NATIVE_HANDLER_H_
+#define EXTENSIONS_RENDERER_LAZY_BACKGROUND_PAGE_NATIVE_HANDLER_H_
+
+#include "extensions/renderer/object_backed_native_handler.h"
+
+namespace content {
+class RenderView;
+}
+
+namespace extensions {
+
+class Extension;
+
+class LazyBackgroundPageNativeHandler : public ObjectBackedNativeHandler {
+ public:
+  explicit LazyBackgroundPageNativeHandler(ScriptContext* context);
+  void IncrementKeepaliveCount(const v8::FunctionCallbackInfo<v8::Value>& args);
+  void DecrementKeepaliveCount(const v8::FunctionCallbackInfo<v8::Value>& args);
+
+ private:
+  bool IsContextLazyBackgroundPage(content::RenderView* render_view,
+                                   const Extension* extension);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_LAZY_BACKGROUND_PAGE_NATIVE_HANDLER_H_
diff --git a/extensions/renderer/messaging_bindings.cc b/extensions/renderer/messaging_bindings.cc
new file mode 100644
index 0000000..d442681
--- /dev/null
+++ b/extensions/renderer/messaging_bindings.cc
@@ -0,0 +1,433 @@
+// 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.
+
+#include "extensions/renderer/messaging_bindings.h"
+
+#include <map>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/lazy_instance.h"
+#include "base/message_loop/message_loop.h"
+#include "base/values.h"
+#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/render_view.h"
+#include "content/public/renderer/v8_value_converter.h"
+#include "extensions/common/api/messaging/message.h"
+#include "extensions/common/extension_messages.h"
+#include "extensions/common/manifest_handlers/externally_connectable.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/event_bindings.h"
+#include "extensions/renderer/object_backed_native_handler.h"
+#include "extensions/renderer/scoped_persistent.h"
+#include "extensions/renderer/script_context.h"
+#include "extensions/renderer/script_context_set.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
+#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
+#include "third_party/WebKit/public/web/WebScopedWindowFocusAllowedIndicator.h"
+#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
+#include "v8/include/v8.h"
+
+// Message passing API example (in a content script):
+// var extension =
+//    new chrome.Extension('00123456789abcdef0123456789abcdef0123456');
+// var port = runtime.connect();
+// port.postMessage('Can you hear me now?');
+// port.onmessage.addListener(function(msg, port) {
+//   alert('response=' + msg);
+//   port.postMessage('I got your reponse');
+// });
+
+using content::RenderThread;
+using content::V8ValueConverter;
+
+namespace extensions {
+
+namespace {
+
+struct ExtensionData {
+  struct PortData {
+    int ref_count;  // how many contexts have a handle to this port
+    PortData() : ref_count(0) {}
+  };
+  std::map<int, PortData> ports;  // port ID -> data
+};
+
+base::LazyInstance<ExtensionData> g_extension_data = LAZY_INSTANCE_INITIALIZER;
+
+bool HasPortData(int port_id) {
+  return g_extension_data.Get().ports.find(port_id) !=
+         g_extension_data.Get().ports.end();
+}
+
+ExtensionData::PortData& GetPortData(int port_id) {
+  return g_extension_data.Get().ports[port_id];
+}
+
+void ClearPortData(int port_id) {
+  g_extension_data.Get().ports.erase(port_id);
+}
+
+const char kPortClosedError[] = "Attempting to use a disconnected port object";
+const char kReceivingEndDoesntExistError[] =
+    "Could not establish connection. Receiving end does not exist.";
+
+class ExtensionImpl : public ObjectBackedNativeHandler {
+ public:
+  ExtensionImpl(Dispatcher* dispatcher, ScriptContext* context)
+      : ObjectBackedNativeHandler(context), dispatcher_(dispatcher) {
+    RouteFunction(
+        "CloseChannel",
+        base::Bind(&ExtensionImpl::CloseChannel, base::Unretained(this)));
+    RouteFunction(
+        "PortAddRef",
+        base::Bind(&ExtensionImpl::PortAddRef, base::Unretained(this)));
+    RouteFunction(
+        "PortRelease",
+        base::Bind(&ExtensionImpl::PortRelease, base::Unretained(this)));
+    RouteFunction(
+        "PostMessage",
+        base::Bind(&ExtensionImpl::PostMessage, base::Unretained(this)));
+    // TODO(fsamuel, kalman): Move BindToGC out of messaging natives.
+    RouteFunction("BindToGC",
+                  base::Bind(&ExtensionImpl::BindToGC, base::Unretained(this)));
+  }
+
+  virtual ~ExtensionImpl() {}
+
+ private:
+  void ClearPortDataAndNotifyDispatcher(int port_id) {
+    ClearPortData(port_id);
+    dispatcher_->ClearPortData(port_id);
+  }
+
+  // Sends a message along the given channel.
+  void PostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    content::RenderView* renderview = context()->GetRenderView();
+    if (!renderview)
+      return;
+
+    // Arguments are (int32 port_id, string message).
+    CHECK(args.Length() == 2 && args[0]->IsInt32() && args[1]->IsString());
+
+    int port_id = args[0]->Int32Value();
+    if (!HasPortData(port_id)) {
+      args.GetIsolate()->ThrowException(v8::Exception::Error(
+          v8::String::NewFromUtf8(args.GetIsolate(), kPortClosedError)));
+      return;
+    }
+
+    renderview->Send(new ExtensionHostMsg_PostMessage(
+        renderview->GetRoutingID(), port_id,
+        Message(*v8::String::Utf8Value(args[1]),
+                blink::WebUserGestureIndicator::isProcessingUserGesture())));
+  }
+
+  // Forcefully disconnects a port.
+  void CloseChannel(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    // Arguments are (int32 port_id, boolean notify_browser).
+    CHECK_EQ(2, args.Length());
+    CHECK(args[0]->IsInt32());
+    CHECK(args[1]->IsBoolean());
+
+    int port_id = args[0]->Int32Value();
+    if (!HasPortData(port_id))
+      return;
+
+    // Send via the RenderThread because the RenderView might be closing.
+    bool notify_browser = args[1]->BooleanValue();
+    if (notify_browser) {
+      content::RenderThread::Get()->Send(
+          new ExtensionHostMsg_CloseChannel(port_id, std::string()));
+    }
+
+    ClearPortDataAndNotifyDispatcher(port_id);
+  }
+
+  // A new port has been created for a context.  This occurs both when script
+  // opens a connection, and when a connection is opened to this script.
+  void PortAddRef(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    // Arguments are (int32 port_id).
+    CHECK_EQ(1, args.Length());
+    CHECK(args[0]->IsInt32());
+
+    int port_id = args[0]->Int32Value();
+    ++GetPortData(port_id).ref_count;
+  }
+
+  // The frame a port lived in has been destroyed.  When there are no more
+  // frames with a reference to a given port, we will disconnect it and notify
+  // the other end of the channel.
+  void PortRelease(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    // Arguments are (int32 port_id).
+    CHECK_EQ(1, args.Length());
+    CHECK(args[0]->IsInt32());
+
+    int port_id = args[0]->Int32Value();
+    if (HasPortData(port_id) && --GetPortData(port_id).ref_count == 0) {
+      // Send via the RenderThread because the RenderView might be closing.
+      content::RenderThread::Get()->Send(
+          new ExtensionHostMsg_CloseChannel(port_id, std::string()));
+      ClearPortDataAndNotifyDispatcher(port_id);
+    }
+  }
+
+  // Holds a |callback| to run sometime after |object| is GC'ed. |callback| will
+  // not be executed re-entrantly to avoid running JS in an unexpected state.
+  class GCCallback {
+   public:
+    static void Bind(v8::Handle<v8::Object> object,
+                     v8::Handle<v8::Function> callback,
+                     v8::Isolate* isolate) {
+      GCCallback* cb = new GCCallback(object, callback, isolate);
+      cb->object_.SetWeak(cb, NearDeathCallback);
+    }
+
+   private:
+    static void NearDeathCallback(
+        const v8::WeakCallbackData<v8::Object, GCCallback>& data) {
+      // v8 says we need to explicitly reset weak handles from their callbacks.
+      // It's not implicit as one might expect.
+      data.GetParameter()->object_.reset();
+      base::MessageLoop::current()->PostTask(
+          FROM_HERE,
+          base::Bind(&GCCallback::RunCallback,
+                     base::Owned(data.GetParameter())));
+    }
+
+    GCCallback(v8::Handle<v8::Object> object,
+               v8::Handle<v8::Function> callback,
+               v8::Isolate* isolate)
+        : object_(object), callback_(callback), isolate_(isolate) {}
+
+    void RunCallback() {
+      v8::HandleScope handle_scope(isolate_);
+      v8::Handle<v8::Function> callback = callback_.NewHandle(isolate_);
+      v8::Handle<v8::Context> context = callback->CreationContext();
+      if (context.IsEmpty())
+        return;
+      v8::Context::Scope context_scope(context);
+      blink::WebScopedMicrotaskSuppression suppression;
+      callback->Call(context->Global(), 0, NULL);
+    }
+
+    ScopedPersistent<v8::Object> object_;
+    ScopedPersistent<v8::Function> callback_;
+    v8::Isolate* isolate_;
+
+    DISALLOW_COPY_AND_ASSIGN(GCCallback);
+  };
+
+  // void BindToGC(object, callback)
+  //
+  // Binds |callback| to be invoked *sometime after* |object| is garbage
+  // collected. We don't call the method re-entrantly so as to avoid executing
+  // JS in some bizarro undefined mid-GC state.
+  void BindToGC(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    CHECK(args.Length() == 2 && args[0]->IsObject() && args[1]->IsFunction());
+    GCCallback::Bind(args[0].As<v8::Object>(),
+                     args[1].As<v8::Function>(),
+                     args.GetIsolate());
+  }
+
+  // Dispatcher handle. Not owned.
+  Dispatcher* dispatcher_;
+};
+
+}  // namespace
+
+ObjectBackedNativeHandler* MessagingBindings::Get(Dispatcher* dispatcher,
+                                                  ScriptContext* context) {
+  return new ExtensionImpl(dispatcher, context);
+}
+
+// static
+void MessagingBindings::DispatchOnConnect(
+    const ScriptContextSet::ContextSet& contexts,
+    int target_port_id,
+    const std::string& channel_name,
+    const base::DictionaryValue& source_tab,
+    const std::string& source_extension_id,
+    const std::string& target_extension_id,
+    const GURL& source_url,
+    const std::string& tls_channel_id,
+    content::RenderView* restrict_to_render_view) {
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  v8::HandleScope handle_scope(isolate);
+
+  scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
+
+  bool port_created = false;
+  std::string source_url_spec = source_url.spec();
+
+  // TODO(kalman): pass in the full ScriptContextSet; call ForEach.
+  for (ScriptContextSet::ContextSet::const_iterator it = contexts.begin();
+       it != contexts.end();
+       ++it) {
+    if (restrict_to_render_view &&
+        restrict_to_render_view != (*it)->GetRenderView()) {
+      continue;
+    }
+
+    // TODO(kalman): remove when ContextSet::ForEach is available.
+    if ((*it)->v8_context().IsEmpty())
+      continue;
+
+    v8::Handle<v8::Value> tab = v8::Null(isolate);
+    v8::Handle<v8::Value> tls_channel_id_value = v8::Undefined(isolate);
+    const Extension* extension = (*it)->extension();
+    if (extension) {
+      if (!source_tab.empty() && !extension->is_platform_app())
+        tab = converter->ToV8Value(&source_tab, (*it)->v8_context());
+
+      ExternallyConnectableInfo* externally_connectable =
+          ExternallyConnectableInfo::Get(extension);
+      if (externally_connectable &&
+          externally_connectable->accepts_tls_channel_id) {
+        tls_channel_id_value =
+            v8::String::NewFromUtf8(isolate,
+                                    tls_channel_id.c_str(),
+                                    v8::String::kNormalString,
+                                    tls_channel_id.size());
+      }
+    }
+
+    v8::Handle<v8::Value> arguments[] = {
+        // portId
+        v8::Integer::New(isolate, target_port_id),
+        // channelName
+        v8::String::NewFromUtf8(isolate,
+                                channel_name.c_str(),
+                                v8::String::kNormalString,
+                                channel_name.size()),
+        // sourceTab
+        tab,
+        // sourceExtensionId
+        v8::String::NewFromUtf8(isolate,
+                                source_extension_id.c_str(),
+                                v8::String::kNormalString,
+                                source_extension_id.size()),
+        // targetExtensionId
+        v8::String::NewFromUtf8(isolate,
+                                target_extension_id.c_str(),
+                                v8::String::kNormalString,
+                                target_extension_id.size()),
+        // sourceUrl
+        v8::String::NewFromUtf8(isolate,
+                                source_url_spec.c_str(),
+                                v8::String::kNormalString,
+                                source_url_spec.size()),
+        // tlsChannelId
+        tls_channel_id_value,
+    };
+
+    v8::Handle<v8::Value> retval = (*it)->module_system()->CallModuleMethod(
+        "messaging", "dispatchOnConnect", arraysize(arguments), arguments);
+
+    if (retval.IsEmpty()) {
+      LOG(ERROR) << "Empty return value from dispatchOnConnect.";
+      continue;
+    }
+
+    CHECK(retval->IsBoolean());
+    port_created |= retval->BooleanValue();
+  }
+
+  // If we didn't create a port, notify the other end of the channel (treat it
+  // as a disconnect).
+  if (!port_created) {
+    content::RenderThread::Get()->Send(new ExtensionHostMsg_CloseChannel(
+        target_port_id, kReceivingEndDoesntExistError));
+  }
+}
+
+// static
+void MessagingBindings::DeliverMessage(
+    const ScriptContextSet::ContextSet& contexts,
+    int target_port_id,
+    const Message& message,
+    content::RenderView* restrict_to_render_view) {
+  scoped_ptr<blink::WebScopedUserGesture> web_user_gesture;
+  scoped_ptr<blink::WebScopedWindowFocusAllowedIndicator> allow_window_focus;
+  if (message.user_gesture) {
+    web_user_gesture.reset(new blink::WebScopedUserGesture);
+    allow_window_focus.reset(new blink::WebScopedWindowFocusAllowedIndicator);
+  }
+
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  v8::HandleScope handle_scope(isolate);
+
+  // TODO(kalman): pass in the full ScriptContextSet; call ForEach.
+  for (ScriptContextSet::ContextSet::const_iterator it = contexts.begin();
+       it != contexts.end();
+       ++it) {
+    if (restrict_to_render_view &&
+        restrict_to_render_view != (*it)->GetRenderView()) {
+      continue;
+    }
+
+    // TODO(kalman): remove when ContextSet::ForEach is available.
+    if ((*it)->v8_context().IsEmpty())
+      continue;
+
+    // Check to see whether the context has this port before bothering to create
+    // the message.
+    v8::Handle<v8::Value> port_id_handle =
+        v8::Integer::New(isolate, target_port_id);
+    v8::Handle<v8::Value> has_port = (*it)->module_system()->CallModuleMethod(
+        "messaging", "hasPort", 1, &port_id_handle);
+
+    CHECK(!has_port.IsEmpty());
+    if (!has_port->BooleanValue())
+      continue;
+
+    std::vector<v8::Handle<v8::Value> > arguments;
+    arguments.push_back(v8::String::NewFromUtf8(isolate,
+                                                message.data.c_str(),
+                                                v8::String::kNormalString,
+                                                message.data.size()));
+    arguments.push_back(port_id_handle);
+    (*it)->module_system()->CallModuleMethod(
+        "messaging", "dispatchOnMessage", &arguments);
+  }
+}
+
+// static
+void MessagingBindings::DispatchOnDisconnect(
+    const ScriptContextSet::ContextSet& contexts,
+    int port_id,
+    const std::string& error_message,
+    content::RenderView* restrict_to_render_view) {
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  v8::HandleScope handle_scope(isolate);
+
+  // TODO(kalman): pass in the full ScriptContextSet; call ForEach.
+  for (ScriptContextSet::ContextSet::const_iterator it = contexts.begin();
+       it != contexts.end();
+       ++it) {
+    if (restrict_to_render_view &&
+        restrict_to_render_view != (*it)->GetRenderView()) {
+      continue;
+    }
+
+    // TODO(kalman): remove when ContextSet::ForEach is available.
+    if ((*it)->v8_context().IsEmpty())
+      continue;
+
+    std::vector<v8::Handle<v8::Value> > arguments;
+    arguments.push_back(v8::Integer::New(isolate, port_id));
+    if (!error_message.empty()) {
+      arguments.push_back(
+          v8::String::NewFromUtf8(isolate, error_message.c_str()));
+    } else {
+      arguments.push_back(v8::Null(isolate));
+    }
+    (*it)->module_system()->CallModuleMethod(
+        "messaging", "dispatchOnDisconnect", &arguments);
+  }
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/messaging_bindings.h b/extensions/renderer/messaging_bindings.h
new file mode 100644
index 0000000..721b434
--- /dev/null
+++ b/extensions/renderer/messaging_bindings.h
@@ -0,0 +1,71 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_MESSAGING_BINDINGS_H_
+#define EXTENSIONS_RENDERER_MESSAGING_BINDINGS_H_
+
+#include <string>
+
+#include "extensions/renderer/script_context_set.h"
+
+namespace base {
+class DictionaryValue;
+}
+
+namespace content {
+class RenderView;
+}
+
+namespace v8 {
+class Extension;
+}
+
+namespace extensions {
+class Dispatcher;
+struct Message;
+class ObjectBackedNativeHandler;
+
+// Manually implements JavaScript bindings for extension messaging.
+//
+// TODO(aa): This should all get re-implemented using SchemaGeneratedBindings.
+// If anything needs to be manual for some reason, it should be implemented in
+// its own class.
+class MessagingBindings {
+ public:
+  // Creates an instance of the extension.
+  static ObjectBackedNativeHandler* Get(Dispatcher* dispatcher,
+                                        ScriptContext* context);
+
+  // Dispatches the onConnect content script messaging event to some contexts
+  // in |contexts|. If |restrict_to_render_view| is specified, only contexts in
+  // that render view will receive the message.
+  static void DispatchOnConnect(const ScriptContextSet::ContextSet& contexts,
+                                int target_port_id,
+                                const std::string& channel_name,
+                                const base::DictionaryValue& source_tab,
+                                const std::string& source_extension_id,
+                                const std::string& target_extension_id,
+                                const GURL& source_url,
+                                const std::string& tls_channel_id,
+                                content::RenderView* restrict_to_render_view);
+
+  // Delivers a message sent using content script messaging to some of the
+  // contexts in |bindings_context_set|. If |restrict_to_render_view| is
+  // specified, only contexts in that render view will receive the message.
+  static void DeliverMessage(const ScriptContextSet::ContextSet& context_set,
+                             int target_port_id,
+                             const Message& message,
+                             content::RenderView* restrict_to_render_view);
+
+  // Dispatches the onDisconnect event in response to the channel being closed.
+  static void DispatchOnDisconnect(
+      const ScriptContextSet::ContextSet& context_set,
+      int port_id,
+      const std::string& error_message,
+      content::RenderView* restrict_to_render_view);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_MESSAGING_BINDINGS_H_
diff --git a/extensions/renderer/print_native_handler.cc b/extensions/renderer/print_native_handler.cc
new file mode 100644
index 0000000..1e83b0e
--- /dev/null
+++ b/extensions/renderer/print_native_handler.cc
@@ -0,0 +1,32 @@
+// 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.
+
+#include "extensions/renderer/print_native_handler.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/strings/string_util.h"
+
+namespace extensions {
+
+PrintNativeHandler::PrintNativeHandler(ScriptContext* context)
+    : ObjectBackedNativeHandler(context) {
+  RouteFunction("Print",
+                base::Bind(&PrintNativeHandler::Print, base::Unretained(this)));
+}
+
+void PrintNativeHandler::Print(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  if (args.Length() < 1)
+    return;
+
+  std::vector<std::string> components;
+  for (int i = 0; i < args.Length(); ++i)
+    components.push_back(*v8::String::Utf8Value(args[i]->ToString()));
+
+  LOG(ERROR) << JoinString(components, ',');
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/print_native_handler.h b/extensions/renderer/print_native_handler.h
new file mode 100644
index 0000000..b2e5d37
--- /dev/null
+++ b/extensions/renderer/print_native_handler.h
@@ -0,0 +1,21 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_PRINT_NATIVE_HANDLER_H_
+#define EXTENSIONS_RENDERER_PRINT_NATIVE_HANDLER_H_
+
+#include "extensions/renderer/object_backed_native_handler.h"
+
+namespace extensions {
+
+class PrintNativeHandler : public ObjectBackedNativeHandler {
+ public:
+  explicit PrintNativeHandler(ScriptContext* context);
+
+  void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_PRINT_NATIVE_HANDLER_H_
diff --git a/extensions/renderer/process_info_native_handler.cc b/extensions/renderer/process_info_native_handler.cc
new file mode 100644
index 0000000..3c7ba78
--- /dev/null
+++ b/extensions/renderer/process_info_native_handler.cc
@@ -0,0 +1,86 @@
+// 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.
+
+#include "extensions/renderer/process_info_native_handler.h"
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "extensions/renderer/script_context.h"
+
+namespace extensions {
+
+ProcessInfoNativeHandler::ProcessInfoNativeHandler(
+    ScriptContext* context,
+    const std::string& extension_id,
+    const std::string& context_type,
+    bool is_incognito_context,
+    int manifest_version,
+    bool send_request_disabled)
+    : ObjectBackedNativeHandler(context),
+      extension_id_(extension_id),
+      context_type_(context_type),
+      is_incognito_context_(is_incognito_context),
+      manifest_version_(manifest_version),
+      send_request_disabled_(send_request_disabled) {
+  RouteFunction("GetExtensionId",
+                base::Bind(&ProcessInfoNativeHandler::GetExtensionId,
+                           base::Unretained(this)));
+  RouteFunction("GetContextType",
+                base::Bind(&ProcessInfoNativeHandler::GetContextType,
+                           base::Unretained(this)));
+  RouteFunction("InIncognitoContext",
+                base::Bind(&ProcessInfoNativeHandler::InIncognitoContext,
+                           base::Unretained(this)));
+  RouteFunction("GetManifestVersion",
+                base::Bind(&ProcessInfoNativeHandler::GetManifestVersion,
+                           base::Unretained(this)));
+  RouteFunction("IsSendRequestDisabled",
+                base::Bind(&ProcessInfoNativeHandler::IsSendRequestDisabled,
+                           base::Unretained(this)));
+  RouteFunction(
+      "HasSwitch",
+      base::Bind(&ProcessInfoNativeHandler::HasSwitch, base::Unretained(this)));
+}
+
+void ProcessInfoNativeHandler::GetExtensionId(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  args.GetReturnValue().Set(
+      v8::String::NewFromUtf8(args.GetIsolate(), extension_id_.c_str()));
+}
+
+void ProcessInfoNativeHandler::GetContextType(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  args.GetReturnValue().Set(
+      v8::String::NewFromUtf8(args.GetIsolate(), context_type_.c_str()));
+}
+
+void ProcessInfoNativeHandler::InIncognitoContext(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  args.GetReturnValue().Set(is_incognito_context_);
+}
+
+void ProcessInfoNativeHandler::GetManifestVersion(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  args.GetReturnValue().Set(static_cast<int32_t>(manifest_version_));
+}
+
+void ProcessInfoNativeHandler::IsSendRequestDisabled(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  if (send_request_disabled_) {
+    args.GetReturnValue().Set(v8::String::NewFromUtf8(
+        args.GetIsolate(),
+        "sendRequest and onRequest are obsolete."
+        " Please use sendMessage and onMessage instead."));
+  }
+}
+
+void ProcessInfoNativeHandler::HasSwitch(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  CHECK(args.Length() == 1 && args[0]->IsString());
+  bool has_switch = CommandLine::ForCurrentProcess()->HasSwitch(
+      *v8::String::Utf8Value(args[0]));
+  args.GetReturnValue().Set(v8::Boolean::New(args.GetIsolate(), has_switch));
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/process_info_native_handler.h b/extensions/renderer/process_info_native_handler.h
new file mode 100644
index 0000000..1f25269
--- /dev/null
+++ b/extensions/renderer/process_info_native_handler.h
@@ -0,0 +1,40 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_PROCESS_INFO_NATIVE_HANDLER_H_
+#define EXTENSIONS_RENDERER_PROCESS_INFO_NATIVE_HANDLER_H_
+
+#include <string>
+
+#include "extensions/renderer/object_backed_native_handler.h"
+
+namespace extensions {
+
+class ProcessInfoNativeHandler : public ObjectBackedNativeHandler {
+ public:
+  ProcessInfoNativeHandler(ScriptContext* context,
+                           const std::string& extension_id,
+                           const std::string& context_type,
+                           bool is_incognito_context,
+                           int manifest_version,
+                           bool send_request_disabled);
+
+ private:
+  void GetExtensionId(const v8::FunctionCallbackInfo<v8::Value>& args);
+  void GetContextType(const v8::FunctionCallbackInfo<v8::Value>& args);
+  void InIncognitoContext(const v8::FunctionCallbackInfo<v8::Value>& args);
+  void GetManifestVersion(const v8::FunctionCallbackInfo<v8::Value>& args);
+  void IsSendRequestDisabled(const v8::FunctionCallbackInfo<v8::Value>& args);
+  void HasSwitch(const v8::FunctionCallbackInfo<v8::Value>& args);
+
+  std::string extension_id_;
+  std::string context_type_;
+  bool is_incognito_context_;
+  int manifest_version_;
+  bool send_request_disabled_;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_PROCESS_INFO_NATIVE_HANDLER_H_
diff --git a/extensions/renderer/request_sender.cc b/extensions/renderer/request_sender.cc
index 09ffa8f..60c77c6 100644
--- a/extensions/renderer/request_sender.cc
+++ b/extensions/renderer/request_sender.cc
@@ -5,9 +5,9 @@
 #include "extensions/renderer/request_sender.h"
 
 #include "base/values.h"
-#include "chrome/renderer/extensions/dispatcher.h"
 #include "content/public/renderer/render_view.h"
 #include "extensions/common/extension_messages.h"
+#include "extensions/renderer/dispatcher.h"
 #include "extensions/renderer/script_context.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
diff --git a/extensions/renderer/resource_bundle_source_map.cc b/extensions/renderer/resource_bundle_source_map.cc
new file mode 100644
index 0000000..954a6d7
--- /dev/null
+++ b/extensions/renderer/resource_bundle_source_map.cc
@@ -0,0 +1,47 @@
+// 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.
+
+#include "extensions/renderer/resource_bundle_source_map.h"
+
+#include "ui/base/resource/resource_bundle.h"
+
+namespace extensions {
+
+ResourceBundleSourceMap::ResourceBundleSourceMap(
+    const ui::ResourceBundle* resource_bundle)
+    : resource_bundle_(resource_bundle) {
+}
+
+ResourceBundleSourceMap::~ResourceBundleSourceMap() {
+}
+
+void ResourceBundleSourceMap::RegisterSource(const std::string& name,
+                                             int resource_id) {
+  resource_id_map_[name] = resource_id;
+}
+
+v8::Handle<v8::Value> ResourceBundleSourceMap::GetSource(
+    v8::Isolate* isolate,
+    const std::string& name) {
+  if (!Contains(name))
+    return v8::Undefined(isolate);
+  int resource_id = resource_id_map_[name];
+  return ConvertString(isolate,
+                       resource_bundle_->GetRawDataResource(resource_id));
+}
+
+bool ResourceBundleSourceMap::Contains(const std::string& name) {
+  return !!resource_id_map_.count(name);
+}
+
+v8::Handle<v8::String> ResourceBundleSourceMap::ConvertString(
+    v8::Isolate* isolate,
+    const base::StringPiece& string) {
+  // v8 takes ownership of the StaticV8ExternalAsciiStringResource (see
+  // v8::String::NewExternal()).
+  return v8::String::NewExternal(
+      isolate, new StaticV8ExternalAsciiStringResource(string));
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/resource_bundle_source_map.h b/extensions/renderer/resource_bundle_source_map.h
new file mode 100644
index 0000000..89e8b1d
--- /dev/null
+++ b/extensions/renderer/resource_bundle_source_map.h
@@ -0,0 +1,45 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_
+#define EXTENSIONS_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_
+
+#include <map>
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/memory/linked_ptr.h"
+#include "base/strings/string_piece.h"
+#include "extensions/renderer/module_system.h"
+#include "extensions/renderer/static_v8_external_ascii_string_resource.h"
+#include "v8/include/v8.h"
+
+namespace ui {
+class ResourceBundle;
+}
+
+namespace extensions {
+
+class ResourceBundleSourceMap : public extensions::ModuleSystem::SourceMap {
+ public:
+  explicit ResourceBundleSourceMap(const ui::ResourceBundle* resource_bundle);
+  virtual ~ResourceBundleSourceMap();
+
+  virtual v8::Handle<v8::Value> GetSource(v8::Isolate* isolate,
+                                          const std::string& name) OVERRIDE;
+  virtual bool Contains(const std::string& name) OVERRIDE;
+
+  void RegisterSource(const std::string& name, int resource_id);
+
+ private:
+  v8::Handle<v8::String> ConvertString(v8::Isolate* isolate,
+                                       const base::StringPiece& string);
+
+  const ui::ResourceBundle* resource_bundle_;
+  std::map<std::string, int> resource_id_map_;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_
diff --git a/extensions/renderer/runtime_custom_bindings.cc b/extensions/renderer/runtime_custom_bindings.cc
new file mode 100644
index 0000000..3815abc
--- /dev/null
+++ b/extensions/renderer/runtime_custom_bindings.cc
@@ -0,0 +1,177 @@
+// 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.
+
+#include "extensions/renderer/runtime_custom_bindings.h"
+
+#include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "content/public/renderer/render_view.h"
+#include "content/public/renderer/v8_value_converter.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_messages.h"
+#include "extensions/common/features/feature.h"
+#include "extensions/common/features/feature_provider.h"
+#include "extensions/common/manifest.h"
+#include "extensions/renderer/api_activity_logger.h"
+#include "extensions/renderer/extension_helper.h"
+#include "extensions/renderer/script_context.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebFrame.h"
+#include "third_party/WebKit/public/web/WebView.h"
+
+using content::V8ValueConverter;
+
+namespace extensions {
+
+RuntimeCustomBindings::RuntimeCustomBindings(ScriptContext* context)
+    : ObjectBackedNativeHandler(context) {
+  RouteFunction(
+      "GetManifest",
+      base::Bind(&RuntimeCustomBindings::GetManifest, base::Unretained(this)));
+  RouteFunction("OpenChannelToExtension",
+                base::Bind(&RuntimeCustomBindings::OpenChannelToExtension,
+                           base::Unretained(this)));
+  RouteFunction("OpenChannelToNativeApp",
+                base::Bind(&RuntimeCustomBindings::OpenChannelToNativeApp,
+                           base::Unretained(this)));
+  RouteFunction("GetExtensionViews",
+                base::Bind(&RuntimeCustomBindings::GetExtensionViews,
+                           base::Unretained(this)));
+}
+
+RuntimeCustomBindings::~RuntimeCustomBindings() {
+}
+
+void RuntimeCustomBindings::OpenChannelToExtension(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  // Get the current RenderView so that we can send a routed IPC message from
+  // the correct source.
+  content::RenderView* renderview = context()->GetRenderView();
+  if (!renderview)
+    return;
+
+  // The Javascript code should validate/fill the arguments.
+  CHECK_EQ(args.Length(), 3);
+  CHECK(args[0]->IsString() && args[1]->IsString() && args[2]->IsBoolean());
+
+  ExtensionMsg_ExternalConnectionInfo info;
+
+  // For messaging APIs, hosted apps should be considered a web page so hide
+  // its extension ID.
+  const Extension* extension = context()->extension();
+  if (extension && !extension->is_hosted_app())
+    info.source_id = extension->id();
+
+  info.target_id = *v8::String::Utf8Value(args[0]->ToString());
+  info.source_url = context()->GetURL();
+  std::string channel_name = *v8::String::Utf8Value(args[1]->ToString());
+  bool include_tls_channel_id =
+      args.Length() > 2 ? args[2]->BooleanValue() : false;
+  int port_id = -1;
+  renderview->Send(
+      new ExtensionHostMsg_OpenChannelToExtension(renderview->GetRoutingID(),
+                                                  info,
+                                                  channel_name,
+                                                  include_tls_channel_id,
+                                                  &port_id));
+  args.GetReturnValue().Set(static_cast<int32_t>(port_id));
+}
+
+void RuntimeCustomBindings::OpenChannelToNativeApp(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  // Verify that the extension has permission to use native messaging.
+  Feature::Availability availability =
+      FeatureProvider::GetPermissionFeatures()
+          ->GetFeature("nativeMessaging")
+          ->IsAvailableToContext(context()->extension(),
+                                 context()->context_type(),
+                                 context()->GetURL());
+  if (!availability.is_available())
+    return;
+
+  // Get the current RenderView so that we can send a routed IPC message from
+  // the correct source.
+  content::RenderView* renderview = context()->GetRenderView();
+  if (!renderview)
+    return;
+
+  // The Javascript code should validate/fill the arguments.
+  CHECK(args.Length() >= 2 && args[0]->IsString() && args[1]->IsString());
+
+  std::string extension_id = *v8::String::Utf8Value(args[0]->ToString());
+  std::string native_app_name = *v8::String::Utf8Value(args[1]->ToString());
+
+  int port_id = -1;
+  renderview->Send(new ExtensionHostMsg_OpenChannelToNativeApp(
+      renderview->GetRoutingID(), extension_id, native_app_name, &port_id));
+  args.GetReturnValue().Set(static_cast<int32_t>(port_id));
+}
+
+void RuntimeCustomBindings::GetManifest(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  CHECK(context()->extension());
+
+  scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
+  args.GetReturnValue().Set(converter->ToV8Value(
+      context()->extension()->manifest()->value(), context()->v8_context()));
+}
+
+void RuntimeCustomBindings::GetExtensionViews(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  if (args.Length() != 2)
+    return;
+
+  if (!args[0]->IsInt32() || !args[1]->IsString())
+    return;
+
+  // |browser_window_id| == extension_misc::kUnknownWindowId means getting
+  // all views for the current extension.
+  int browser_window_id = args[0]->Int32Value();
+
+  std::string view_type_string = *v8::String::Utf8Value(args[1]->ToString());
+  StringToUpperASCII(&view_type_string);
+  // |view_type| == VIEW_TYPE_INVALID means getting any type of
+  // views.
+  ViewType view_type = VIEW_TYPE_INVALID;
+  if (view_type_string == kViewTypeBackgroundPage) {
+    view_type = VIEW_TYPE_EXTENSION_BACKGROUND_PAGE;
+  } else if (view_type_string == kViewTypeInfobar) {
+    view_type = VIEW_TYPE_EXTENSION_INFOBAR;
+  } else if (view_type_string == kViewTypeTabContents) {
+    view_type = VIEW_TYPE_TAB_CONTENTS;
+  } else if (view_type_string == kViewTypePopup) {
+    view_type = VIEW_TYPE_EXTENSION_POPUP;
+  } else if (view_type_string == kViewTypeExtensionDialog) {
+    view_type = VIEW_TYPE_EXTENSION_DIALOG;
+  } else if (view_type_string == kViewTypeAppWindow) {
+    view_type = VIEW_TYPE_APP_WINDOW;
+  } else if (view_type_string == kViewTypePanel) {
+    view_type = VIEW_TYPE_PANEL;
+  } else if (view_type_string != kViewTypeAll) {
+    return;
+  }
+
+  std::string extension_id = context()->GetExtensionID();
+  if (extension_id.empty())
+    return;
+
+  std::vector<content::RenderView*> views = ExtensionHelper::GetExtensionViews(
+      extension_id, browser_window_id, view_type);
+  v8::Local<v8::Array> v8_views = v8::Array::New(args.GetIsolate());
+  int v8_index = 0;
+  for (size_t i = 0; i < views.size(); ++i) {
+    v8::Local<v8::Context> context =
+        views[i]->GetWebView()->mainFrame()->mainWorldScriptContext();
+    if (!context.IsEmpty()) {
+      v8::Local<v8::Value> window = context->Global();
+      DCHECK(!window.IsEmpty());
+      v8_views->Set(v8::Integer::New(args.GetIsolate(), v8_index++), window);
+    }
+  }
+
+  args.GetReturnValue().Set(v8_views);
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/runtime_custom_bindings.h b/extensions/renderer/runtime_custom_bindings.h
new file mode 100644
index 0000000..70f4d03
--- /dev/null
+++ b/extensions/renderer/runtime_custom_bindings.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_RUNTIME_CUSTOM_BINDINGS_H_
+#define EXTENSIONS_RENDERER_RUNTIME_CUSTOM_BINDINGS_H_
+
+#include "base/compiler_specific.h"
+#include "extensions/renderer/object_backed_native_handler.h"
+#include "v8/include/v8.h"
+
+namespace extensions {
+
+// The native component of custom bindings for the chrome.runtime API.
+class RuntimeCustomBindings : public ObjectBackedNativeHandler {
+ public:
+  explicit RuntimeCustomBindings(ScriptContext* context);
+
+  virtual ~RuntimeCustomBindings();
+
+  // Creates a new messaging channel to the given extension.
+  void OpenChannelToExtension(const v8::FunctionCallbackInfo<v8::Value>& args);
+
+  // Creates a new messaging channels for the specified native application.
+  void OpenChannelToNativeApp(const v8::FunctionCallbackInfo<v8::Value>& args);
+
+ private:
+  void GetManifest(const v8::FunctionCallbackInfo<v8::Value>& args);
+  void GetExtensionViews(const v8::FunctionCallbackInfo<v8::Value>& args);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_RUNTIME_CUSTOM_BINDINGS_H_
diff --git a/extensions/renderer/script_context.cc b/extensions/renderer/script_context.cc
index 77f72aa..33a9413 100644
--- a/extensions/renderer/script_context.cc
+++ b/extensions/renderer/script_context.cc
@@ -24,7 +24,7 @@
 
 namespace extensions {
 
-ScriptContext::ScriptContext(v8::Handle<v8::Context> v8_context,
+ScriptContext::ScriptContext(const v8::Handle<v8::Context>& v8_context,
                              blink::WebFrame* web_frame,
                              const Extension* extension,
                              Feature::Context context_type)
diff --git a/extensions/renderer/script_context.h b/extensions/renderer/script_context.h
index c2cbb04..5cc137e 100644
--- a/extensions/renderer/script_context.h
+++ b/extensions/renderer/script_context.h
@@ -30,7 +30,7 @@
 // Extensions wrapper for a v8 context.
 class ScriptContext : public RequestSender::Source {
  public:
-  ScriptContext(v8::Handle<v8::Context> context,
+  ScriptContext(const v8::Handle<v8::Context>& context,
                 blink::WebFrame* frame,
                 const Extension* extension,
                 Feature::Context context_type);
diff --git a/extensions/renderer/static_v8_external_ascii_string_resource.cc b/extensions/renderer/static_v8_external_ascii_string_resource.cc
new file mode 100644
index 0000000..5d64d2e
--- /dev/null
+++ b/extensions/renderer/static_v8_external_ascii_string_resource.cc
@@ -0,0 +1,25 @@
+// 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.
+
+#include "extensions/renderer/static_v8_external_ascii_string_resource.h"
+
+namespace extensions {
+
+StaticV8ExternalAsciiStringResource::StaticV8ExternalAsciiStringResource(
+    const base::StringPiece& buffer)
+    : buffer_(buffer) {
+}
+
+StaticV8ExternalAsciiStringResource::~StaticV8ExternalAsciiStringResource() {
+}
+
+const char* StaticV8ExternalAsciiStringResource::data() const {
+  return buffer_.data();
+}
+
+size_t StaticV8ExternalAsciiStringResource::length() const {
+  return buffer_.length();
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/static_v8_external_ascii_string_resource.h b/extensions/renderer/static_v8_external_ascii_string_resource.h
new file mode 100644
index 0000000..da02650
--- /dev/null
+++ b/extensions/renderer/static_v8_external_ascii_string_resource.h
@@ -0,0 +1,32 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_STATIC_V8_EXTERNAL_ASCII_STRING_RESOURCE_H_
+#define EXTENSIONS_RENDERER_STATIC_V8_EXTERNAL_ASCII_STRING_RESOURCE_H_
+
+#include "base/compiler_specific.h"
+#include "base/strings/string_piece.h"
+#include "v8/include/v8.h"
+
+namespace extensions {
+
+// A very simple implementation of v8::ExternalAsciiStringResource that just
+// wraps a buffer. The buffer must outlive the v8 runtime instance this resource
+// is used in.
+class StaticV8ExternalAsciiStringResource
+    : public v8::String::ExternalAsciiStringResource {
+ public:
+  explicit StaticV8ExternalAsciiStringResource(const base::StringPiece& buffer);
+  virtual ~StaticV8ExternalAsciiStringResource();
+
+  virtual const char* data() const OVERRIDE;
+  virtual size_t length() const OVERRIDE;
+
+ private:
+  base::StringPiece buffer_;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_STATIC_V8_EXTERNAL_ASCII_STRING_RESOURCE_H_
diff --git a/extensions/renderer/test_extensions_renderer_client.cc b/extensions/renderer/test_extensions_renderer_client.cc
index 4d1c021..5299878 100644
--- a/extensions/renderer/test_extensions_renderer_client.cc
+++ b/extensions/renderer/test_extensions_renderer_client.cc
@@ -19,13 +19,4 @@
   return 1;
 }
 
-void TestExtensionsRendererClient::RegisterNativeHandlers(
-    extensions::ModuleSystem* module_system,
-    extensions::ScriptContext* context) {
-}
-
-void TestExtensionsRendererClient::PopulateSourceMap(
-    ResourceBundleSourceMap* source_map) {
-}
-
 }  // namespace extensions
diff --git a/extensions/renderer/test_extensions_renderer_client.h b/extensions/renderer/test_extensions_renderer_client.h
index a71d1bb..72550a9 100644
--- a/extensions/renderer/test_extensions_renderer_client.h
+++ b/extensions/renderer/test_extensions_renderer_client.h
@@ -18,9 +18,6 @@
   // ExtensionsRendererClient implementation.
   virtual bool IsIncognitoProcess() const OVERRIDE;
   virtual int GetLowestIsolatedWorldId() const OVERRIDE;
-  virtual void RegisterNativeHandlers(ModuleSystem* module_system,
-                                      ScriptContext* context) OVERRIDE;
-  virtual void PopulateSourceMap(ResourceBundleSourceMap* source_map) OVERRIDE;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TestExtensionsRendererClient);
diff --git a/extensions/renderer/test_features_native_handler.cc b/extensions/renderer/test_features_native_handler.cc
new file mode 100644
index 0000000..6e0423d
--- /dev/null
+++ b/extensions/renderer/test_features_native_handler.cc
@@ -0,0 +1,36 @@
+// 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.
+
+#include "extensions/renderer/test_features_native_handler.h"
+
+#include "base/bind.h"
+#include "content/public/renderer/v8_value_converter.h"
+#include "extensions/common/features/json_feature_provider_source.h"
+#include "extensions/renderer/script_context.h"
+#include "grit/common_resources.h"
+#include "grit/extensions_resources.h"
+
+namespace extensions {
+
+TestFeaturesNativeHandler::TestFeaturesNativeHandler(ScriptContext* context)
+    : ObjectBackedNativeHandler(context) {
+  RouteFunction("GetAPIFeatures",
+                base::Bind(&TestFeaturesNativeHandler::GetAPIFeatures,
+                           base::Unretained(this)));
+}
+
+void TestFeaturesNativeHandler::GetAPIFeatures(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  JSONFeatureProviderSource source("api");
+  // TODO(rockot): Only inlcude extensions features here. Chrome should add
+  // its own native handler for Chrome features.
+  source.LoadJSON(IDR_CHROME_EXTENSION_API_FEATURES);
+  source.LoadJSON(IDR_EXTENSION_API_FEATURES);
+  scoped_ptr<content::V8ValueConverter> converter(
+      content::V8ValueConverter::create());
+  args.GetReturnValue().Set(
+      converter->ToV8Value(&source.dictionary(), context()->v8_context()));
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/test_features_native_handler.h b/extensions/renderer/test_features_native_handler.h
new file mode 100644
index 0000000..2422178
--- /dev/null
+++ b/extensions/renderer/test_features_native_handler.h
@@ -0,0 +1,22 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_TEST_FEATURES_NATIVE_HANDLER_H_
+#define EXTENSIONS_RENDERER_TEST_FEATURES_NATIVE_HANDLER_H_
+
+#include "extensions/renderer/object_backed_native_handler.h"
+
+namespace extensions {
+
+class TestFeaturesNativeHandler : public ObjectBackedNativeHandler {
+ public:
+  explicit TestFeaturesNativeHandler(ScriptContext* context);
+
+ private:
+  void GetAPIFeatures(const v8::FunctionCallbackInfo<v8::Value>& args);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_TEST_FEATURES_NATIVE_HANDLER_H_
diff --git a/extensions/renderer/user_gestures_native_handler.cc b/extensions/renderer/user_gestures_native_handler.cc
new file mode 100644
index 0000000..9875ac0
--- /dev/null
+++ b/extensions/renderer/user_gestures_native_handler.cc
@@ -0,0 +1,52 @@
+// 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.
+
+#include "extensions/renderer/user_gestures_native_handler.h"
+
+#include "base/bind.h"
+#include "extensions/renderer/script_context.h"
+#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
+#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
+
+namespace extensions {
+
+UserGesturesNativeHandler::UserGesturesNativeHandler(ScriptContext* context)
+    : ObjectBackedNativeHandler(context) {
+  RouteFunction("IsProcessingUserGesture",
+                base::Bind(&UserGesturesNativeHandler::IsProcessingUserGesture,
+                           base::Unretained(this)));
+  RouteFunction("RunWithUserGesture",
+                base::Bind(&UserGesturesNativeHandler::RunWithUserGesture,
+                           base::Unretained(this)));
+  RouteFunction("RunWithoutUserGesture",
+                base::Bind(&UserGesturesNativeHandler::RunWithoutUserGesture,
+                           base::Unretained(this)));
+}
+
+void UserGesturesNativeHandler::IsProcessingUserGesture(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  args.GetReturnValue().Set(v8::Boolean::New(
+      args.GetIsolate(),
+      blink::WebUserGestureIndicator::isProcessingUserGesture()));
+}
+
+void UserGesturesNativeHandler::RunWithUserGesture(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  blink::WebScopedUserGesture user_gesture;
+  CHECK_EQ(args.Length(), 1);
+  CHECK(args[0]->IsFunction());
+  v8::Handle<v8::Value> no_args;
+  context()->CallFunction(v8::Handle<v8::Function>::Cast(args[0]), 0, &no_args);
+}
+
+void UserGesturesNativeHandler::RunWithoutUserGesture(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  blink::WebUserGestureIndicator::consumeUserGesture();
+  CHECK_EQ(args.Length(), 1);
+  CHECK(args[0]->IsFunction());
+  v8::Handle<v8::Value> no_args;
+  context()->CallFunction(v8::Handle<v8::Function>::Cast(args[0]), 0, &no_args);
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/user_gestures_native_handler.h b/extensions/renderer/user_gestures_native_handler.h
new file mode 100644
index 0000000..fbe15fb
--- /dev/null
+++ b/extensions/renderer/user_gestures_native_handler.h
@@ -0,0 +1,24 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_USER_GESTURES_NATIVE_HANDLER_H_
+#define EXTENSIONS_RENDERER_USER_GESTURES_NATIVE_HANDLER_H_
+
+#include "extensions/renderer/object_backed_native_handler.h"
+
+namespace extensions {
+
+class UserGesturesNativeHandler : public ObjectBackedNativeHandler {
+ public:
+  explicit UserGesturesNativeHandler(ScriptContext* context);
+
+ private:
+  void IsProcessingUserGesture(const v8::FunctionCallbackInfo<v8::Value>& args);
+  void RunWithUserGesture(const v8::FunctionCallbackInfo<v8::Value>& args);
+  void RunWithoutUserGesture(const v8::FunctionCallbackInfo<v8::Value>& args);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_USER_GESTURES_NATIVE_HANDLER_H_
diff --git a/extensions/renderer/user_script_scheduler.cc b/extensions/renderer/user_script_scheduler.cc
new file mode 100644
index 0000000..9c82fb7a
--- /dev/null
+++ b/extensions/renderer/user_script_scheduler.cc
@@ -0,0 +1,280 @@
+// 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.
+
+#include "extensions/renderer/user_script_scheduler.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "content/public/renderer/render_view.h"
+#include "content/public/renderer/v8_value_converter.h"
+#include "extensions/common/error_utils.h"
+#include "extensions/common/extension_messages.h"
+#include "extensions/common/manifest_constants.h"
+#include "extensions/common/permissions/permissions_data.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/dom_activity_logger.h"
+#include "extensions/renderer/extension_groups.h"
+#include "extensions/renderer/extension_helper.h"
+#include "extensions/renderer/script_context.h"
+#include "extensions/renderer/user_script_slave.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/platform/WebVector.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebFrame.h"
+#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
+#include "third_party/WebKit/public/web/WebView.h"
+#include "v8/include/v8.h"
+
+namespace {
+// The length of time to wait after the DOM is complete to try and run user
+// scripts.
+const int kUserScriptIdleTimeoutMs = 200;
+}
+
+using blink::WebDocument;
+using blink::WebFrame;
+using blink::WebString;
+using blink::WebVector;
+using blink::WebView;
+
+namespace extensions {
+
+UserScriptScheduler::UserScriptScheduler(WebFrame* frame,
+                                         Dispatcher* dispatcher)
+    : weak_factory_(this),
+      frame_(frame),
+      current_location_(UserScript::UNDEFINED),
+      has_run_idle_(false),
+      dispatcher_(dispatcher) {
+  for (int i = UserScript::UNDEFINED; i < UserScript::RUN_LOCATION_LAST; ++i) {
+    pending_execution_map_[static_cast<UserScript::RunLocation>(i)] =
+      std::queue<linked_ptr<ExtensionMsg_ExecuteCode_Params> >();
+  }
+}
+
+UserScriptScheduler::~UserScriptScheduler() {
+}
+
+void UserScriptScheduler::ExecuteCode(
+    const ExtensionMsg_ExecuteCode_Params& params) {
+  UserScript::RunLocation run_at =
+    static_cast<UserScript::RunLocation>(params.run_at);
+  if (current_location_ < run_at) {
+    pending_execution_map_[run_at].push(
+        linked_ptr<ExtensionMsg_ExecuteCode_Params>(
+            new ExtensionMsg_ExecuteCode_Params(params)));
+    return;
+  }
+
+  ExecuteCodeImpl(params);
+}
+
+void UserScriptScheduler::DidCreateDocumentElement() {
+  current_location_ = UserScript::DOCUMENT_START;
+  MaybeRun();
+}
+
+void UserScriptScheduler::DidFinishDocumentLoad() {
+  current_location_ = UserScript::DOCUMENT_END;
+  MaybeRun();
+  // Schedule a run for DOCUMENT_IDLE
+  base::MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&UserScriptScheduler::IdleTimeout, weak_factory_.GetWeakPtr()),
+      base::TimeDelta::FromMilliseconds(kUserScriptIdleTimeoutMs));
+}
+
+void UserScriptScheduler::DidFinishLoad() {
+  current_location_ = UserScript::DOCUMENT_IDLE;
+  // Ensure that running scripts does not keep any progress UI running.
+  base::MessageLoop::current()->PostTask(
+      FROM_HERE,
+      base::Bind(&UserScriptScheduler::MaybeRun, weak_factory_.GetWeakPtr()));
+}
+
+void UserScriptScheduler::DidStartProvisionalLoad() {
+  // The frame is navigating, so reset the state since we'll want to inject
+  // scripts once the load finishes.
+  current_location_ = UserScript::UNDEFINED;
+  has_run_idle_ = false;
+  weak_factory_.InvalidateWeakPtrs();
+  std::map<UserScript::RunLocation, ExecutionQueue>::iterator itr =
+    pending_execution_map_.begin();
+  for (itr = pending_execution_map_.begin();
+       itr != pending_execution_map_.end(); ++itr) {
+    while (!itr->second.empty())
+      itr->second.pop();
+  }
+}
+
+void UserScriptScheduler::IdleTimeout() {
+  current_location_ = UserScript::DOCUMENT_IDLE;
+  MaybeRun();
+}
+
+void UserScriptScheduler::MaybeRun() {
+  if (current_location_ == UserScript::UNDEFINED)
+    return;
+
+  if (!has_run_idle_ && current_location_ == UserScript::DOCUMENT_IDLE) {
+    has_run_idle_ = true;
+    dispatcher_->user_script_slave()->InjectScripts(
+        frame_, UserScript::DOCUMENT_IDLE);
+  }
+
+  // Run all tasks from the current time and earlier.
+  for (int i = UserScript::DOCUMENT_START;
+       i <= current_location_; ++i) {
+    UserScript::RunLocation run_time = static_cast<UserScript::RunLocation>(i);
+    while (!pending_execution_map_[run_time].empty()) {
+      linked_ptr<ExtensionMsg_ExecuteCode_Params>& params =
+        pending_execution_map_[run_time].front();
+      ExecuteCodeImpl(*params);
+      pending_execution_map_[run_time].pop();
+    }
+  }
+}
+
+void UserScriptScheduler::ExecuteCodeImpl(
+    const ExtensionMsg_ExecuteCode_Params& params) {
+  const Extension* extension = dispatcher_->extensions()->GetByID(
+      params.extension_id);
+  content::RenderView* render_view =
+      content::RenderView::FromWebView(frame_->view());
+  ExtensionHelper* extension_helper = ExtensionHelper::Get(render_view);
+  base::ListValue execution_results;
+
+  // Since extension info is sent separately from user script info, they can
+  // be out of sync. We just ignore this situation.
+  if (!extension) {
+    render_view->Send(
+        new ExtensionHostMsg_ExecuteCodeFinished(render_view->GetRoutingID(),
+                                                 params.request_id,
+                                                 std::string(),  // no error
+                                                 -1,
+                                                 GURL(std::string()),
+                                                 execution_results));
+    return;
+  }
+
+  std::vector<WebFrame*> frame_vector;
+  frame_vector.push_back(frame_);
+  if (params.all_frames)
+    GetAllChildFrames(frame_, &frame_vector);
+
+  std::string error;
+
+  scoped_ptr<blink::WebScopedUserGesture> gesture;
+  if (params.user_gesture)
+    gesture.reset(new blink::WebScopedUserGesture);
+
+  GURL top_url = frame_->document().url();
+
+  for (std::vector<WebFrame*>::iterator frame_it = frame_vector.begin();
+       frame_it != frame_vector.end(); ++frame_it) {
+    WebFrame* child_frame = *frame_it;
+    CHECK(child_frame) << top_url;
+
+    // We recheck access here in the renderer for extra safety against races
+    // with navigation.
+    //
+    // But different frames can have different URLs, and the extension might
+    // only have access to a subset of them. For the top frame, we can
+    // immediately send an error and stop because the browser process
+    // considers that an error too.
+    //
+    // For child frames, we just skip ones the extension doesn't have access
+    // to and carry on.
+
+    bool can_execute_script =
+        PermissionsData::CanExecuteScriptOnPage(extension,
+                                                child_frame->document().url(),
+                                                top_url,
+                                                extension_helper->tab_id(),
+                                                NULL,
+                                                -1,
+                                                NULL);
+    if ((!params.is_web_view && !can_execute_script) ||
+        (params.is_web_view &&
+         child_frame->document().url() != params.webview_src)) {
+      if (child_frame->parent()) {
+        continue;
+      } else {
+        error = ErrorUtils::FormatErrorMessage(
+            manifest_errors::kCannotAccessPage,
+            child_frame->document().url().spec());
+        break;
+      }
+    }
+
+    if (params.is_javascript) {
+      WebScriptSource source(WebString::fromUTF8(params.code), params.file_url);
+      v8::HandleScope scope(v8::Isolate::GetCurrent());
+
+      scoped_ptr<content::V8ValueConverter> v8_converter(
+          content::V8ValueConverter::create());
+      v8::Local<v8::Value> script_value;
+
+      if (params.in_main_world) {
+        DOMActivityLogger::AttachToWorld(DOMActivityLogger::kMainWorldId,
+                                         extension->id());
+        script_value = child_frame->executeScriptAndReturnValue(source);
+      } else {
+        blink::WebVector<v8::Local<v8::Value> > results;
+        std::vector<WebScriptSource> sources;
+        sources.push_back(source);
+        int isolated_world_id =
+            dispatcher_->user_script_slave()->GetIsolatedWorldIdForExtension(
+                extension, child_frame);
+        DOMActivityLogger::AttachToWorld(isolated_world_id, extension->id());
+        child_frame->executeScriptInIsolatedWorld(
+            isolated_world_id, &sources.front(),
+            sources.size(), EXTENSION_GROUP_CONTENT_SCRIPTS, &results);
+        // We only expect one value back since we only pushed one source
+        if (results.size() == 1 && !results[0].IsEmpty())
+          script_value = results[0];
+      }
+
+      if (params.wants_result && !script_value.IsEmpty()) {
+        // It's safe to always use the main world context when converting here.
+        // V8ValueConverterImpl shouldn't actually care about the context scope,
+        // and it switches to v8::Object's creation context when encountered.
+        v8::Local<v8::Context> context = child_frame->mainWorldScriptContext();
+        base::Value* result = v8_converter->FromV8Value(script_value, context);
+        // Always append an execution result (i.e. no result == null result) so
+        // that |execution_results| lines up with the frames.
+        execution_results.Append(
+            result ? result : base::Value::CreateNullValue());
+      }
+    } else {
+      child_frame->document().insertStyleSheet(
+          WebString::fromUTF8(params.code));
+    }
+  }
+
+  render_view->Send(new ExtensionHostMsg_ExecuteCodeFinished(
+      render_view->GetRoutingID(),
+      params.request_id,
+      error,
+      render_view->GetPageId(),
+      ScriptContext::GetDataSourceURLForFrame(frame_),
+      execution_results));
+}
+
+bool UserScriptScheduler::GetAllChildFrames(
+    WebFrame* parent_frame,
+    std::vector<WebFrame*>* frames_vector) const {
+  if (!parent_frame)
+    return false;
+
+  for (WebFrame* child_frame = parent_frame->firstChild(); child_frame;
+       child_frame = child_frame->nextSibling()) {
+    frames_vector->push_back(child_frame);
+    GetAllChildFrames(child_frame, frames_vector);
+  }
+  return true;
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/user_script_scheduler.h b/extensions/renderer/user_script_scheduler.h
new file mode 100644
index 0000000..4e8a45b
--- /dev/null
+++ b/extensions/renderer/user_script_scheduler.h
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_USER_SCRIPT_SCHEDULER_H_
+#define EXTENSIONS_RENDERER_USER_SCRIPT_SCHEDULER_H_
+
+#include <map>
+#include <queue>
+
+#include "base/memory/linked_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "extensions/common/user_script.h"
+
+class RenderView;
+struct ExtensionMsg_ExecuteCode_Params;
+
+namespace blink {
+class WebFrame;
+}
+
+namespace extensions {
+class Dispatcher;
+
+// Implements support for injecting scripts at different times in the document
+// loading process. The different possible time are described in
+// UserScript::RunLocation.
+//
+// Currently, determining idleness is simple: it is whichever of the following
+// happens first:
+//
+// a) When the initial DOM for a page is complete + kUserScriptIdleTimeout,
+// b) or when the page has completely loaded including all subresources.
+//
+// The intent of this mechanism is to prevent user scripts from slowing down
+// fast pages (run after load), while still allowing them to run relatively
+// timely for pages with lots of slow subresources.
+//
+// NOTE: this class does not inherit from RenderViewObserver on purpose.  The
+// reason is that this object is per frame, and a frame can move across
+// RenderViews thanks to adoptNode.  So we have each RenderView's
+// ExtensionHelper proxy these calls to the renderer process' Dispatcher,
+// which contains the mapping from WebFrame to us.
+class UserScriptScheduler {
+ public:
+  UserScriptScheduler(blink::WebFrame* frame, Dispatcher* dispatcher);
+  ~UserScriptScheduler();
+
+  void ExecuteCode(const ExtensionMsg_ExecuteCode_Params& params);
+  void DidCreateDocumentElement();
+  void DidFinishDocumentLoad();
+  void DidFinishLoad();
+  void DidStartProvisionalLoad();
+
+ private:
+  typedef
+    std::queue<linked_ptr<ExtensionMsg_ExecuteCode_Params> >
+    ExecutionQueue;
+
+  // Run user scripts, except if they've already run for this frame, or the
+  // frame has been destroyed.
+  void MaybeRun();
+
+  // Backend for the IPC Message ExecuteCode in addition to being used
+  // internally.
+  void ExecuteCodeImpl(const ExtensionMsg_ExecuteCode_Params& params);
+
+  // Get all child frames of parent_frame, returned by frames_vector.
+  bool GetAllChildFrames(blink::WebFrame* parent_frame,
+                         std::vector<blink::WebFrame*>* frames_vector) const;
+
+  // Call to signify thet the idle timeout has expired.
+  void IdleTimeout();
+
+  base::WeakPtrFactory<UserScriptScheduler> weak_factory_;
+
+  // The Frame we will run scripts in.
+  blink::WebFrame* frame_;
+
+  // The current location in the document loading process.
+  // Will be UserScript::UNDEFINED if it is before any scripts should be run.
+  UserScript::RunLocation current_location_;
+
+  // Whether we have already run the idle scripts.
+  bool has_run_idle_;
+
+  // This is only used if we're for the main frame.
+  std::map<UserScript::RunLocation, ExecutionQueue> pending_execution_map_;
+
+  Dispatcher* dispatcher_;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_USER_SCRIPT_SCHEDULER_H_
diff --git a/extensions/renderer/user_script_slave.cc b/extensions/renderer/user_script_slave.cc
new file mode 100644
index 0000000..64cd3f6
--- /dev/null
+++ b/extensions/renderer/user_script_slave.cc
@@ -0,0 +1,314 @@
+// 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.
+
+#include "extensions/renderer/user_script_slave.h"
+
+#include <map>
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/memory/shared_memory.h"
+#include "base/metrics/histogram.h"
+#include "base/pickle.h"
+#include "base/strings/stringprintf.h"
+#include "base/timer/elapsed_timer.h"
+#include "content/public/common/url_constants.h"
+#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/render_view.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_messages.h"
+#include "extensions/common/extension_set.h"
+#include "extensions/common/manifest_handlers/csp_info.h"
+#include "extensions/common/permissions/permissions_data.h"
+#include "extensions/renderer/dom_activity_logger.h"
+#include "extensions/renderer/extension_groups.h"
+#include "extensions/renderer/extensions_renderer_client.h"
+#include "extensions/renderer/script_context.h"
+#include "grit/renderer_resources.h"
+#include "third_party/WebKit/public/platform/WebURLRequest.h"
+#include "third_party/WebKit/public/platform/WebVector.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebFrame.h"
+#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
+#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
+#include "third_party/WebKit/public/web/WebView.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "url/gurl.h"
+
+using blink::WebFrame;
+using blink::WebSecurityOrigin;
+using blink::WebSecurityPolicy;
+using blink::WebString;
+using blink::WebVector;
+using blink::WebView;
+using content::RenderThread;
+
+namespace extensions {
+
+// These two strings are injected before and after the Greasemonkey API and
+// user script to wrap it in an anonymous scope.
+static const char kUserScriptHead[] = "(function (unsafeWindow) {\n";
+static const char kUserScriptTail[] = "\n})(window);";
+
+int UserScriptSlave::GetIsolatedWorldIdForExtension(const Extension* extension,
+                                                    WebFrame* frame) {
+  static int g_next_isolated_world_id =
+      ExtensionsRendererClient::Get()->GetLowestIsolatedWorldId();
+
+  IsolatedWorldMap::iterator iter = isolated_world_ids_.find(extension->id());
+  if (iter != isolated_world_ids_.end()) {
+    // We need to set the isolated world origin and CSP even if it's not a new
+    // world since these are stored per frame, and we might not have used this
+    // isolated world in this frame before.
+    frame->setIsolatedWorldSecurityOrigin(
+        iter->second, WebSecurityOrigin::create(extension->url()));
+    frame->setIsolatedWorldContentSecurityPolicy(
+        iter->second,
+        WebString::fromUTF8(CSPInfo::GetContentSecurityPolicy(extension)));
+    return iter->second;
+  }
+
+  int new_id = g_next_isolated_world_id;
+  ++g_next_isolated_world_id;
+
+  // This map will tend to pile up over time, but realistically, you're never
+  // going to have enough extensions for it to matter.
+  isolated_world_ids_[extension->id()] = new_id;
+  frame->setIsolatedWorldSecurityOrigin(
+      new_id, WebSecurityOrigin::create(extension->url()));
+  frame->setIsolatedWorldContentSecurityPolicy(
+      new_id,
+      WebString::fromUTF8(CSPInfo::GetContentSecurityPolicy(extension)));
+  return new_id;
+}
+
+std::string UserScriptSlave::GetExtensionIdForIsolatedWorld(
+    int isolated_world_id) {
+  for (IsolatedWorldMap::iterator iter = isolated_world_ids_.begin();
+       iter != isolated_world_ids_.end();
+       ++iter) {
+    if (iter->second == isolated_world_id)
+      return iter->first;
+  }
+  return std::string();
+}
+
+void UserScriptSlave::RemoveIsolatedWorld(const std::string& extension_id) {
+  isolated_world_ids_.erase(extension_id);
+}
+
+UserScriptSlave::UserScriptSlave(const ExtensionSet* extensions)
+    : script_deleter_(&scripts_), extensions_(extensions) {
+  api_js_ = ResourceBundle::GetSharedInstance().GetRawDataResource(
+      IDR_GREASEMONKEY_API_JS);
+}
+
+UserScriptSlave::~UserScriptSlave() {
+}
+
+void UserScriptSlave::GetActiveExtensions(
+    std::set<std::string>* extension_ids) {
+  for (size_t i = 0; i < scripts_.size(); ++i) {
+    DCHECK(!scripts_[i]->extension_id().empty());
+    extension_ids->insert(scripts_[i]->extension_id());
+  }
+}
+
+bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) {
+  scripts_.clear();
+
+  bool only_inject_incognito =
+      ExtensionsRendererClient::Get()->IsIncognitoProcess();
+
+  // Create the shared memory object (read only).
+  shared_memory_.reset(new base::SharedMemory(shared_memory, true));
+  if (!shared_memory_.get())
+    return false;
+
+  // First get the size of the memory block.
+  if (!shared_memory_->Map(sizeof(Pickle::Header)))
+    return false;
+  Pickle::Header* pickle_header =
+      reinterpret_cast<Pickle::Header*>(shared_memory_->memory());
+
+  // Now map in the rest of the block.
+  int pickle_size = sizeof(Pickle::Header) + pickle_header->payload_size;
+  shared_memory_->Unmap();
+  if (!shared_memory_->Map(pickle_size))
+    return false;
+
+  // Unpickle scripts.
+  uint64 num_scripts = 0;
+  Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()), pickle_size);
+  PickleIterator iter(pickle);
+  CHECK(pickle.ReadUInt64(&iter, &num_scripts));
+
+  scripts_.reserve(num_scripts);
+  for (uint64 i = 0; i < num_scripts; ++i) {
+    scripts_.push_back(new UserScript());
+    UserScript* script = scripts_.back();
+    script->Unpickle(pickle, &iter);
+
+    // Note that this is a pointer into shared memory. We don't own it. It gets
+    // cleared up when the last renderer or browser process drops their
+    // reference to the shared memory.
+    for (size_t j = 0; j < script->js_scripts().size(); ++j) {
+      const char* body = NULL;
+      int body_length = 0;
+      CHECK(pickle.ReadData(&iter, &body, &body_length));
+      script->js_scripts()[j].set_external_content(
+          base::StringPiece(body, body_length));
+    }
+    for (size_t j = 0; j < script->css_scripts().size(); ++j) {
+      const char* body = NULL;
+      int body_length = 0;
+      CHECK(pickle.ReadData(&iter, &body, &body_length));
+      script->css_scripts()[j].set_external_content(
+          base::StringPiece(body, body_length));
+    }
+
+    if (only_inject_incognito && !script->is_incognito_enabled()) {
+      // This script shouldn't run in an incognito tab.
+      delete script;
+      scripts_.pop_back();
+    }
+  }
+
+  return true;
+}
+
+void UserScriptSlave::InjectScripts(WebFrame* frame,
+                                    UserScript::RunLocation location) {
+  GURL data_source_url = ScriptContext::GetDataSourceURLForFrame(frame);
+  if (data_source_url.is_empty())
+    return;
+
+  if (frame->isViewSourceModeEnabled())
+    data_source_url = GURL(content::kViewSourceScheme + std::string(":") +
+                           data_source_url.spec());
+
+  base::ElapsedTimer timer;
+  int num_css = 0;
+  int num_scripts = 0;
+
+  ExecutingScriptsMap extensions_executing_scripts;
+
+  for (size_t i = 0; i < scripts_.size(); ++i) {
+    std::vector<WebScriptSource> sources;
+    UserScript* script = scripts_[i];
+
+    if (frame->parent() && !script->match_all_frames())
+      continue;  // Only match subframes if the script declared it wanted to.
+
+    const Extension* extension = extensions_->GetByID(script->extension_id());
+
+    // Since extension info is sent separately from user script info, they can
+    // be out of sync. We just ignore this situation.
+    if (!extension)
+      continue;
+
+    // Content scripts are not tab-specific.
+    const int kNoTabId = -1;
+    // We don't have a process id in this context.
+    const int kNoProcessId = -1;
+    if (!PermissionsData::CanExecuteScriptOnPage(extension,
+                                                 data_source_url,
+                                                 frame->top()->document().url(),
+                                                 kNoTabId,
+                                                 script,
+                                                 kNoProcessId,
+                                                 NULL)) {
+      continue;
+    }
+
+    if (location == UserScript::DOCUMENT_START) {
+      num_css += script->css_scripts().size();
+      for (UserScript::FileList::const_iterator iter =
+               script->css_scripts().begin();
+           iter != script->css_scripts().end();
+           ++iter) {
+        frame->document().insertStyleSheet(
+            WebString::fromUTF8(iter->GetContent().as_string()));
+      }
+    }
+
+    if (script->run_location() == location) {
+      num_scripts += script->js_scripts().size();
+      for (size_t j = 0; j < script->js_scripts().size(); ++j) {
+        UserScript::File& file = script->js_scripts()[j];
+        std::string content = file.GetContent().as_string();
+
+        // We add this dumb function wrapper for standalone user script to
+        // emulate what Greasemonkey does.
+        // TODO(aa): I think that maybe "is_standalone" scripts don't exist
+        // anymore. Investigate.
+        if (script->is_standalone() || script->emulate_greasemonkey()) {
+          content.insert(0, kUserScriptHead);
+          content += kUserScriptTail;
+        }
+        sources.push_back(
+            WebScriptSource(WebString::fromUTF8(content), file.url()));
+      }
+    }
+
+    if (!sources.empty()) {
+      // Emulate Greasemonkey API for scripts that were converted to extensions
+      // and "standalone" user scripts.
+      if (script->is_standalone() || script->emulate_greasemonkey()) {
+        sources.insert(
+            sources.begin(),
+            WebScriptSource(WebString::fromUTF8(api_js_.as_string())));
+      }
+
+      int isolated_world_id = GetIsolatedWorldIdForExtension(extension, frame);
+
+      base::ElapsedTimer exec_timer;
+      DOMActivityLogger::AttachToWorld(isolated_world_id, extension->id());
+      frame->executeScriptInIsolatedWorld(isolated_world_id,
+                                          &sources.front(),
+                                          sources.size(),
+                                          EXTENSION_GROUP_CONTENT_SCRIPTS);
+      UMA_HISTOGRAM_TIMES("Extensions.InjectScriptTime", exec_timer.Elapsed());
+
+      for (std::vector<WebScriptSource>::const_iterator iter = sources.begin();
+           iter != sources.end();
+           ++iter) {
+        extensions_executing_scripts[extension->id()].insert(
+            GURL(iter->url).path());
+      }
+    }
+  }
+
+  // Notify the browser if any extensions are now executing scripts.
+  if (!extensions_executing_scripts.empty()) {
+    blink::WebFrame* top_frame = frame->top();
+    content::RenderView* render_view =
+        content::RenderView::FromWebView(top_frame->view());
+    render_view->Send(new ExtensionHostMsg_ContentScriptsExecuting(
+        render_view->GetRoutingID(),
+        extensions_executing_scripts,
+        render_view->GetPageId(),
+        ScriptContext::GetDataSourceURLForFrame(top_frame)));
+  }
+
+  // Log debug info.
+  if (location == UserScript::DOCUMENT_START) {
+    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_CssCount", num_css);
+    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_ScriptCount", num_scripts);
+    if (num_css || num_scripts)
+      UMA_HISTOGRAM_TIMES("Extensions.InjectStart_Time", timer.Elapsed());
+  } else if (location == UserScript::DOCUMENT_END) {
+    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectEnd_ScriptCount", num_scripts);
+    if (num_scripts)
+      UMA_HISTOGRAM_TIMES("Extensions.InjectEnd_Time", timer.Elapsed());
+  } else if (location == UserScript::DOCUMENT_IDLE) {
+    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectIdle_ScriptCount", num_scripts);
+    if (num_scripts)
+      UMA_HISTOGRAM_TIMES("Extensions.InjectIdle_Time", timer.Elapsed());
+  } else {
+    NOTREACHED();
+  }
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/user_script_slave.h b/extensions/renderer/user_script_slave.h
new file mode 100644
index 0000000..fc3da79
--- /dev/null
+++ b/extensions/renderer/user_script_slave.h
@@ -0,0 +1,84 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_USER_SCRIPT_SLAVE_H_
+#define EXTENSIONS_RENDERER_USER_SCRIPT_SLAVE_H_
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/shared_memory.h"
+#include "base/stl_util.h"
+#include "base/strings/string_piece.h"
+#include "extensions/common/user_script.h"
+#include "third_party/WebKit/public/web/WebScriptSource.h"
+
+class GURL;
+
+namespace blink {
+class WebFrame;
+}
+
+using blink::WebScriptSource;
+
+namespace extensions {
+class Extension;
+class ExtensionSet;
+
+// Manages installed UserScripts for a render process.
+class UserScriptSlave {
+ public:
+  explicit UserScriptSlave(const ExtensionSet* extensions);
+  ~UserScriptSlave();
+
+  // Returns the unique set of extension IDs this UserScriptSlave knows about.
+  void GetActiveExtensions(std::set<std::string>* extension_ids);
+
+  // Update the parsed scripts from shared memory.
+  bool UpdateScripts(base::SharedMemoryHandle shared_memory);
+
+  // Inject the appropriate scripts into a frame based on its URL.
+  // TODO(aa): Extract a UserScriptFrame interface out of this to improve
+  // testability.
+  void InjectScripts(blink::WebFrame* frame, UserScript::RunLocation location);
+
+  // Gets the isolated world ID to use for the given |extension| in the given
+  // |frame|. If no isolated world has been created for that extension,
+  // one will be created and initialized.
+  int GetIsolatedWorldIdForExtension(const Extension* extension,
+                                     blink::WebFrame* frame);
+
+  // Gets the id of the extension running in a given isolated world. If no such
+  // isolated world exists, or no extension is running in it, returns empty
+  // string.
+  std::string GetExtensionIdForIsolatedWorld(int isolated_world_id);
+
+  void RemoveIsolatedWorld(const std::string& extension_id);
+
+ private:
+  // Shared memory containing raw script data.
+  scoped_ptr<base::SharedMemory> shared_memory_;
+
+  // Parsed script data.
+  std::vector<UserScript*> scripts_;
+  STLElementDeleter<std::vector<UserScript*> > script_deleter_;
+
+  // Greasemonkey API source that is injected with the scripts.
+  base::StringPiece api_js_;
+
+  // Extension metadata.
+  const ExtensionSet* extensions_;
+
+  typedef std::map<std::string, int> IsolatedWorldMap;
+  IsolatedWorldMap isolated_world_ids_;
+
+  DISALLOW_COPY_AND_ASSIGN(UserScriptSlave);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_USER_SCRIPT_SLAVE_H_
diff --git a/extensions/renderer/v8_context_native_handler.cc b/extensions/renderer/v8_context_native_handler.cc
new file mode 100644
index 0000000..56cd973
--- /dev/null
+++ b/extensions/renderer/v8_context_native_handler.cc
@@ -0,0 +1,55 @@
+// 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.
+
+#include "extensions/renderer/v8_context_native_handler.h"
+
+#include "base/bind.h"
+#include "extensions/common/features/feature.h"
+#include "extensions/renderer/dispatcher.h"
+#include "extensions/renderer/script_context.h"
+
+namespace extensions {
+
+V8ContextNativeHandler::V8ContextNativeHandler(ScriptContext* context,
+                                               Dispatcher* dispatcher)
+    : ObjectBackedNativeHandler(context),
+      context_(context),
+      dispatcher_(dispatcher) {
+  RouteFunction("GetAvailability",
+                base::Bind(&V8ContextNativeHandler::GetAvailability,
+                           base::Unretained(this)));
+  RouteFunction("GetModuleSystem",
+                base::Bind(&V8ContextNativeHandler::GetModuleSystem,
+                           base::Unretained(this)));
+}
+
+void V8ContextNativeHandler::GetAvailability(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  CHECK_EQ(args.Length(), 1);
+  v8::Isolate* isolate = args.GetIsolate();
+  std::string api_name = *v8::String::Utf8Value(args[0]->ToString());
+  Feature::Availability availability = context_->GetAvailability(api_name);
+
+  v8::Handle<v8::Object> ret = v8::Object::New(isolate);
+  ret->Set(v8::String::NewFromUtf8(isolate, "is_available"),
+           v8::Boolean::New(isolate, availability.is_available()));
+  ret->Set(v8::String::NewFromUtf8(isolate, "message"),
+           v8::String::NewFromUtf8(isolate, availability.message().c_str()));
+  ret->Set(v8::String::NewFromUtf8(isolate, "result"),
+           v8::Integer::New(isolate, availability.result()));
+  args.GetReturnValue().Set(ret);
+}
+
+void V8ContextNativeHandler::GetModuleSystem(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  CHECK_EQ(args.Length(), 1);
+  CHECK(args[0]->IsObject());
+  v8::Handle<v8::Context> v8_context =
+      v8::Handle<v8::Object>::Cast(args[0])->CreationContext();
+  ScriptContext* context =
+      dispatcher_->script_context_set().GetByV8Context(v8_context);
+  args.GetReturnValue().Set(context->module_system()->NewInstance());
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/v8_context_native_handler.h b/extensions/renderer/v8_context_native_handler.h
new file mode 100644
index 0000000..a3a6163
--- /dev/null
+++ b/extensions/renderer/v8_context_native_handler.h
@@ -0,0 +1,28 @@
+// 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.
+
+#ifndef EXTENSIONS_RENDERER_V8_CONTEXT_NATIVE_HANDLER_H_
+#define EXTENSIONS_RENDERER_V8_CONTEXT_NATIVE_HANDLER_H_
+
+#include "extensions/renderer/object_backed_native_handler.h"
+
+namespace extensions {
+
+class Dispatcher;
+
+class V8ContextNativeHandler : public ObjectBackedNativeHandler {
+ public:
+  V8ContextNativeHandler(ScriptContext* context, Dispatcher* dispatcher);
+
+ private:
+  void GetAvailability(const v8::FunctionCallbackInfo<v8::Value>& args);
+  void GetModuleSystem(const v8::FunctionCallbackInfo<v8::Value>& args);
+
+  ScriptContext* context_;
+  Dispatcher* dispatcher_;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_RENDERER_V8_CONTEXT_NATIVE_HANDLER_H_
diff --git a/extensions/test/data/content_verifier/README b/extensions/test/data/content_verifier/README
new file mode 100644
index 0000000..b950a21
--- /dev/null
+++ b/extensions/test/data/content_verifier/README
@@ -0,0 +1,28 @@
+
+The public/private key pairs were generated with the following commands:
+
+openssl genrsa -out private_key.pem 2048
+openssl rsa -in private_key.pem -pubout -out public_key.pem
+
+
+The signature was generated by:
+
+1) Take the contents of payload.json and base64url encode them:
+cat payload.json | tr -d \\n | base64 -w0 | tr _ / | tr \- + | tr -d '=' > payload_encoded.txt
+
+2) Put the contents of payload_encoded.txt into the "payload" field of
+verified_contents.json.
+
+3) Copy the contents of the "protected" field from verified_contents.json into
+protected.txt.
+
+4) Concatenate the "protected" and "payload" fields with a '.' separator.
+
+echo -n '.' | cat protected.txt - payload_encoded.txt > signature_input.txt
+
+5) Sign it
+
+tr -d \\n < signature_input.txt | openssl dgst -sha256 -sign private_key.pem -binary | base64 -w0  | tr _ / | tr \- + | tr -d '=' > signature.txt
+
+6) Put the contents of signature.txt into the "signature" field in
+verified_contents.json.
diff --git a/extensions/test/data/content_verifier/payload.json b/extensions/test/data/content_verifier/payload.json
new file mode 100644
index 0000000..9995069
--- /dev/null
+++ b/extensions/test/data/content_verifier/payload.json
@@ -0,0 +1,25 @@
+{
+  "content_hashes": [
+    {
+      "block_size": 4096,
+      "hash_block_size": 4096,
+      "format": "treehash",
+      "files": [
+        {
+          "path": "manifest.json",
+          "root_hash": "fafcb22089fb8920b383b5f7202508e7065aded1bbc3bbf2882724c5974919fb"
+        },
+        {
+          "path": "background.js",
+          "root_hash": "b711e21b9290bcda0f3921f915b428f596f9809db78f7a0507446ef433a7ce2c"
+        },
+        {
+          "path": "foo/bar.html",
+          "root_hash": "2f7ecb15b4ff866b7144bec07c664df584e95baca8cff662435a292c99f53595"
+        }
+      ]
+    }
+  ],
+  "item_id": "abcdefghijklmnopabcdefghijklmnop",
+  "item_version": "1.2.3"
+}
diff --git a/extensions/test/data/content_verifier/private_key.pem b/extensions/test/data/content_verifier/private_key.pem
new file mode 100644
index 0000000..f88b394
--- /dev/null
+++ b/extensions/test/data/content_verifier/private_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAxlOasjnVYBOB3oiaJpsmOC9aUX+TbOva/y3w4gm/j7w4p2S3
+ytrCHhglLBRMqDHd0KdN1DiA7Eld8357naDx2hRv3/TBqbUsKmpwQV3Dlidoc7YT
+lQrjmuR3gPNtIqpF3MtTWCdTvBdJd+rs5pXcuhcJPbS56JW1XuQ3MHr8GahtNG0c
+GBDv01L9P1jwiufPa5CJYYI0XmcD73YNvGM7gv0Zh34odbxIw/T3Lv8YXLb46I0M
+yhzkYAUBUt7nOsMrvPjczI3Jez6AhF4EorlLi3vC2kKp6hnSmGLHJ6+/Ehc8A56Q
+P1DT2/ljPyo2Wre6sanLm2ALyU86Id42mMaXGQIDAQABAoIBAGhzl8HOG8bh/0AI
+icdTZymoJtVNb4OqJEjJFVi28aDt7Jicvv+jfyECbnFsr4LV4JEHzEG9EIlhio23
+S7uVDEtjABjfey+6L2yXak/C5kOqtaRbfKy+c2kccqQDkLL1Ip5Kp7aB3+PsD9GM
+dQBsZTfM8h0BlfgdAMzdPQPXgfawhAcwisLn+6oRmtJUvcsKoK/6UWblbB8L3NwN
+Z1o8ufgI23N+RRCZHAhrvl0xnVO6SzYIaB1lhIbeSyxGDEcIpMValSPOYyWasAO+
+JiHmSajSlT2fRO58jOJTjNuDmPzXbTsEDsELnusvrjbwU4vo8DFmd3cGUwY249f5
+otbg3dECgYEA8ZhypG4BEwZB3auyGsZdSJ9NUgR2Gt7dlJxiIJhzedIgaSGj6J0N
+Y/pTBUayHZZeeo1+3YXA/wtikIDyNxZtjzH74tTTW4I1lvyu1L5QpU141cUujwkJ
+vJ7HKuda45oYbmuTnFi/vwy3+cwHDePPlXIDbgvSFmNkD4Q4mdPJsrsCgYEA0ia6
+hQxjmDHeB4vxAKsc7+t65EkmLz2s41q3GfhxjMnKmINURGxwvF6I8cCL6kUO1ljG
+G0mZFd0Vapm5tyKqjPt95HiEl0yu60Mqj1T2utaHnPL8phhhrQUlLyQ7qnwOgu7A
+REqHO2LU4M/b2U9i4PdzCNHRd2WMZL4fKyO30jsCgYAdiCADX3r8I1iryxATW8oN
+VYOzEd6J/FIjl1YbW+dJrdjOYRFTHteDMBcz3udo3HeiDWfDllT4GCEtPsXc2/36
+cgazPIa1ed4pHawVT0o2Wpj5sIe3bkhlaRc5dFxU1AJGhRnfE64koV5fx4PZO86l
+GvG2YvWETRPvHZ95ljzifwKBgE16XdXjpWxdJkCeBXJ7o6WIqbw0g9Fy6aTAszTt
+9d80Hm9wK8c2O7IXIGIQ3QS4BSpdfFxfHAOFiPnORzwPmdV0ewuaqzek2/B8yNoj
+NvvXUBQ7OY56+rfxZ64jq6PFLQx0vYnv+D+axmVD/Qf3TrsmP9EGmjVsyP/zYEZl
+WsY1AoGBAMQpZGUjdxeSYbxZnmFkf4TXYE/QjW/bpOE35hsaUG5X4GEoAhXguxwA
+PsQXrHQa4t9vevW8OnVLKNbm11WDHyEWnuzrGyUHrvIHSqSng6Z9mvjbr6HM3nwg
+xafypreMHnRrx5DnbpkALERceG17toO9+N9l0KELMxdOXIqAiVQC
+-----END RSA PRIVATE KEY-----
diff --git a/extensions/test/data/content_verifier/public_key.pem b/extensions/test/data/content_verifier/public_key.pem
new file mode 100644
index 0000000..2a568a1
--- /dev/null
+++ b/extensions/test/data/content_verifier/public_key.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxlOasjnVYBOB3oiaJpsm
+OC9aUX+TbOva/y3w4gm/j7w4p2S3ytrCHhglLBRMqDHd0KdN1DiA7Eld8357naDx
+2hRv3/TBqbUsKmpwQV3Dlidoc7YTlQrjmuR3gPNtIqpF3MtTWCdTvBdJd+rs5pXc
+uhcJPbS56JW1XuQ3MHr8GahtNG0cGBDv01L9P1jwiufPa5CJYYI0XmcD73YNvGM7
+gv0Zh34odbxIw/T3Lv8YXLb46I0MyhzkYAUBUt7nOsMrvPjczI3Jez6AhF4EorlL
+i3vC2kKp6hnSmGLHJ6+/Ehc8A56QP1DT2/ljPyo2Wre6sanLm2ALyU86Id42mMaX
+GQIDAQAB
+-----END PUBLIC KEY-----
diff --git a/extensions/test/data/content_verifier/verified_contents.json b/extensions/test/data/content_verifier/verified_contents.json
new file mode 100644
index 0000000..ba86f3b
--- /dev/null
+++ b/extensions/test/data/content_verifier/verified_contents.json
@@ -0,0 +1,15 @@
+{
+  "payload": "eyAgImNvbnRlbnRfaGFzaGVzIjogWyAgICB7ICAgICAgImJsb2NrX3NpemUiOiA0MDk2LCAgICAgICJoYXNoX2Jsb2NrX3NpemUiOiA0MDk2LCAgICAgICJmb3JtYXQiOiAidHJlZWhhc2giLCAgICAgICJmaWxlcyI6IFsgICAgICAgIHsgICAgICAgICAgInBhdGgiOiAibWFuaWZlc3QuanNvbiIsICAgICAgICAgICJyb290X2hhc2giOiAiZmFmY2IyMjA4OWZiODkyMGIzODNiNWY3MjAyNTA4ZTcwNjVhZGVkMWJiYzNiYmYyODgyNzI0YzU5NzQ5MTlmYiIgICAgICAgIH0sICAgICAgICB7ICAgICAgICAgICJwYXRoIjogImJhY2tncm91bmQuanMiLCAgICAgICAgICAicm9vdF9oYXNoIjogImI3MTFlMjFiOTI5MGJjZGEwZjM5MjFmOTE1YjQyOGY1OTZmOTgwOWRiNzhmN2EwNTA3NDQ2ZWY0MzNhN2NlMmMiICAgICAgICB9LCAgICAgICAgeyAgICAgICAgICAicGF0aCI6ICJmb28vYmFyLmh0bWwiLCAgICAgICAgICAicm9vdF9oYXNoIjogIjJmN2VjYjE1YjRmZjg2NmI3MTQ0YmVjMDdjNjY0ZGY1ODRlOTViYWNhOGNmZjY2MjQzNWEyOTJjOTlmNTM1OTUiICAgICAgICB9ICAgICAgXSAgICB9ICBdLCAgIml0ZW1faWQiOiAiYWJjZGVmZ2hpamtsbW5vcGFiY2RlZmdoaWprbG1ub3AiLCAgIml0ZW1fdmVyc2lvbiI6ICIxLjIuMyJ9",
+  "signatures": [
+    {
+      "header": {"kid": "publisher"},
+      "protected": "eyJhbGciOiJSUzI1NiJ9",
+      "signature": "whatever"
+    },
+    {
+      "header": {"kid": "webstore"},
+      "protected": "eyJhbGciOiJSUzI1NiJ9",
+      "signature": "cLCoy+XfCahsNbF0xT6WBk2hvGwPut8D9mdkkKIDc6+wQVQryLSP2dGFqgS1XDP54vY8OqM8/7GrdTfVPim6aG80fAPd0YY3Q8nnn9zG2Lhr7rkYMMTdXFzE1bYamxoc3N9WNFkeisvXPZC26QX/D3JOlEisVhXym6DZRk3sibaVGh+mDgZej6YCzPQjnboquQsOsImL9Br7f3HxiH41kjMlsqX+PHrcgzeTVW5VOyiJVIEhOE1QDtgRPOW+MopaDPVvXxTsO8/LDeYE306CxVzemMJcKKaC39c2uOIn55cQqjOtPq1aqss7qFCSqGtvuMwmjSYEgV/q3VX/nc7npA"
+    }
+  ]
+}
diff --git a/gin/gin.target.darwin-arm.mk b/gin/gin.target.darwin-arm.mk
index 3ee5cc7..85bf38e 100644
--- a/gin/gin.target.darwin-arm.mk
+++ b/gin/gin.target.darwin-arm.mk
@@ -63,7 +63,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -153,7 +152,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gin/gin.target.darwin-x86.mk b/gin/gin.target.darwin-x86.mk
index 431dc21..a0398a8 100644
--- a/gin/gin.target.darwin-x86.mk
+++ b/gin/gin.target.darwin-x86.mk
@@ -65,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +154,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gin/gin.target.darwin-x86_64.mk b/gin/gin.target.darwin-x86_64.mk
index 043e2e5..5bb76cc 100644
--- a/gin/gin.target.darwin-x86_64.mk
+++ b/gin/gin.target.darwin-x86_64.mk
@@ -65,7 +65,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +154,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gin/gin.target.linux-arm.mk b/gin/gin.target.linux-arm.mk
index 3ee5cc7..85bf38e 100644
--- a/gin/gin.target.linux-arm.mk
+++ b/gin/gin.target.linux-arm.mk
@@ -63,7 +63,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -153,7 +152,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gin/gin.target.linux-x86.mk b/gin/gin.target.linux-x86.mk
index 431dc21..a0398a8 100644
--- a/gin/gin.target.linux-x86.mk
+++ b/gin/gin.target.linux-x86.mk
@@ -65,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +154,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gin/gin.target.linux-x86_64.mk b/gin/gin.target.linux-x86_64.mk
index 043e2e5..5bb76cc 100644
--- a/gin/gin.target.linux-x86_64.mk
+++ b/gin/gin.target.linux-x86_64.mk
@@ -65,7 +65,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +154,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h
index f82a53a..ee696f6 100644
--- a/gin/public/isolate_holder.h
+++ b/gin/public/isolate_holder.h
@@ -16,12 +16,12 @@
 
 // To embed Gin, first create an instance of IsolateHolder to hold the
 // v8::Isolate in which you will execute JavaScript. You might wish to subclass
-// IsolateHolder if you want to tie more state to the lifetime of the
+// IsolateHolder if you want to tie more state to the lifetime of the isolate.
 //
 // You can use gin in two modes: either gin manages V8, or the gin-embedder
-// manages gin. If gin manages V8, use the IsolateHolder constructor without
-// parameters, otherwise, the gin-embedder needs to create v8::Isolates and
-// pass them to IsolateHolder.
+// manages gin. If gin manages V8, use the IsolateHolder constructor that does
+// not take an v8::Isolate parameter, otherwise, the gin-embedder needs to
+// create v8::Isolates and pass them to IsolateHolder.
 //
 // It is not possible to mix the two.
 class GIN_EXPORT IsolateHolder {
diff --git a/google_apis/drive/gdata_wapi_url_generator_unittest.cc b/google_apis/drive/gdata_wapi_url_generator_unittest.cc
index 7699732..0ac8508 100644
--- a/google_apis/drive/gdata_wapi_url_generator_unittest.cc
+++ b/google_apis/drive/gdata_wapi_url_generator_unittest.cc
@@ -41,7 +41,7 @@
 }
 
 TEST_F(GDataWapiUrlGeneratorTest, GenerateEditUrlWithEmbedOrigin) {
-  url_util::AddStandardScheme("chrome-extension");
+  url::AddStandardScheme("chrome-extension");
 
   EXPECT_EQ(
       "https://docs.google.com/feeds/default/private/full/XXX?v=3&alt=json"
diff --git a/google_apis/gaia/gaia_switches.cc b/google_apis/gaia/gaia_switches.cc
index a5c4399..a1879d1 100644
--- a/google_apis/gaia/gaia_switches.cc
+++ b/google_apis/gaia/gaia_switches.cc
@@ -6,7 +6,6 @@
 
 namespace switches {
 
-const char kClientLoginToOAuth2Url[]        = "client-login-to-oauth2-url";
 const char kGaiaUrl[]                       = "gaia-url";
 const char kGoogleApisUrl[]                 = "google-apis-url";
 const char kLsoUrl[]                        = "lso-url";
diff --git a/google_apis/gaia/gaia_switches.h b/google_apis/gaia/gaia_switches.h
index 15917c4..bc69ebe 100644
--- a/google_apis/gaia/gaia_switches.h
+++ b/google_apis/gaia/gaia_switches.h
@@ -7,9 +7,6 @@
 
 namespace switches {
 
-// Supplies custom client login to OAuth2 URL for testing purposes.
-extern const char kClientLoginToOAuth2Url[];
-
 // Specifies the path for GAIA authentication URL. The default value is
 // "https://accounts.google.com".
 extern const char kGaiaUrl[];
diff --git a/google_apis/gaia/merge_session_helper.cc b/google_apis/gaia/merge_session_helper.cc
index 187860f..c3c8a2e 100644
--- a/google_apis/gaia/merge_session_helper.cc
+++ b/google_apis/gaia/merge_session_helper.cc
@@ -96,6 +96,16 @@
   LogOutInternal("", std::vector<std::string>());
 }
 
+void MergeSessionHelper::SignalComplete(
+    const std::string& account_id,
+    const GoogleServiceAuthError& error) {
+  // Its possible for the observer to delete |this| object.  Don't access
+  // access any members after this calling the observer.  This method should
+  // be the last call in any other method.
+  FOR_EACH_OBSERVER(Observer, observer_list_,
+                    MergeSessionCompleted(account_id, error));
+}
+
 void MergeSessionHelper::StartLogOutUrlFetch() {
   DCHECK(accounts_.front().empty());
   GURL logout_url(GaiaUrls::GetInstance()->service_logout_url());
@@ -153,16 +163,6 @@
   HandleNextAccount();
 }
 
-void MergeSessionHelper::SignalComplete(
-    const std::string& account_id,
-    const GoogleServiceAuthError& error) {
-  // Its possible for the observer to delete |this| object.  Don't access
-  // access any members after this calling the observer.  This method should
-  // be the last call in any other method.
-  FOR_EACH_OBSERVER(Observer, observer_list_,
-                    MergeSessionCompleted(account_id, error));
-}
-
 void MergeSessionHelper::HandleNextAccount() {
   accounts_.pop_front();
   gaia_auth_fetcher_.reset();
diff --git a/google_apis/gaia/merge_session_helper.h b/google_apis/gaia/merge_session_helper.h
index 76bad63..f4af8f0 100644
--- a/google_apis/gaia/merge_session_helper.h
+++ b/google_apis/gaia/merge_session_helper.h
@@ -65,6 +65,12 @@
   // Signout all accounts.
   void LogOutAllAccounts();
 
+  // Call observers when merge session completes.  This public so that callers
+  // that know that a given account is already in the cookie jar can simply
+  // inform the observers.
+  void SignalComplete(const std::string& account_id,
+                      const GoogleServiceAuthError& error);
+
  private:
   // Overridden from UbertokenConsumer.
   virtual void OnUbertokenSuccess(const std::string& token) OVERRIDE;
@@ -85,10 +91,6 @@
   // Virtual for testing purpose.
   virtual void StartLogOutUrlFetch();
 
-  // Call observer when merge session completes.
-  void SignalComplete(const std::string& account_id,
-                      const GoogleServiceAuthError& error);
-
   // Start the next merge session, if needed.
   void HandleNextAccount();
 
diff --git a/google_apis/gcm/engine/checkin_request.cc b/google_apis/gcm/engine/checkin_request.cc
index 7addbeb..aa46655 100644
--- a/google_apis/gcm/engine/checkin_request.cc
+++ b/google_apis/gcm/engine/checkin_request.cc
@@ -7,16 +7,15 @@
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/histogram.h"
+#include "google_apis/gcm/monitoring/gcm_stats_recorder.h"
 #include "google_apis/gcm/protocol/checkin.pb.h"
 #include "net/http/http_status_code.h"
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_request_status.h"
-#include "url/gurl.h"
 
 namespace gcm {
 
 namespace {
-const char kCheckinURL[] = "https://android.clients.google.com/checkin";
 const char kRequestContentType[] = "application/x-protobuf";
 const int kRequestVersionValue = 2;
 const int kDefaultUserSerialNumber = 0;
@@ -24,7 +23,7 @@
 // This enum is also used in an UMA histogram (GCMCheckinRequestStatus
 // enum defined in tools/metrics/histograms/histogram.xml). Hence the entries
 // here shouldn't be deleted or re-ordered and new ones should be added to
-// the end.
+// the end, and update the GetCheckinRequestStatusString(...) below.
 enum CheckinRequestStatus {
   SUCCESS,                    // Checkin completed successfully.
   URL_FETCHING_FAILED,        // URL fetching failed.
@@ -40,8 +39,40 @@
   STATUS_COUNT
 };
 
-void RecordCheckinStatusToUMA(CheckinRequestStatus status) {
+// Returns string representation of enum CheckinRequestStatus.
+std::string GetCheckinRequestStatusString(CheckinRequestStatus status) {
+  switch (status) {
+    case SUCCESS:
+      return "SUCCESS";
+    case URL_FETCHING_FAILED:
+      return "URL_FETCHING_FAILED";
+    case HTTP_BAD_REQUEST:
+      return "HTTP_BAD_REQUEST";
+    case HTTP_UNAUTHORIZED:
+      return "HTTP_UNAUTHORIZED";
+    case HTTP_NOT_OK:
+      return "HTTP_NOT_OK";
+    case RESPONSE_PARSING_FAILED:
+      return "RESPONSE_PARSING_FAILED";
+    case ZERO_ID_OR_TOKEN:
+      return "ZERO_ID_OR_TOKEN";
+    default:
+      NOTREACHED();
+      return "UNKNOWN_STATUS";
+  }
+}
+
+// Records checkin status to both stats recorder and reports to UMA.
+void RecordCheckinStatusAndReportUMA(CheckinRequestStatus status,
+                                     GCMStatsRecorder* recorder,
+                                     bool will_retry) {
   UMA_HISTOGRAM_ENUMERATION("GCM.CheckinRequestStatus", status, STATUS_COUNT);
+  if (status == SUCCESS)
+    recorder->RecordCheckinSuccess();
+  else {
+    recorder->RecordCheckinFailure(GetCheckinRequestStatusString(status),
+                                   will_retry);
+  }
 }
 
 }  // namespace
@@ -62,14 +93,18 @@
 CheckinRequest::RequestInfo::~RequestInfo() {}
 
 CheckinRequest::CheckinRequest(
+    const GURL& checkin_url,
     const RequestInfo& request_info,
     const net::BackoffEntry::Policy& backoff_policy,
     const CheckinRequestCallback& callback,
-    net::URLRequestContextGetter* request_context_getter)
+    net::URLRequestContextGetter* request_context_getter,
+    GCMStatsRecorder* recorder)
     : request_context_getter_(request_context_getter),
       callback_(callback),
       backoff_entry_(&backoff_policy),
+      checkin_url_(checkin_url),
       request_info_(request_info),
+      recorder_(recorder),
       weak_ptr_factory_(this) {
 }
 
@@ -105,9 +140,10 @@
   CHECK(request.SerializeToString(&upload_data));
 
   url_fetcher_.reset(
-      net::URLFetcher::Create(GURL(kCheckinURL), net::URLFetcher::POST, this));
+      net::URLFetcher::Create(checkin_url_, net::URLFetcher::POST, this));
   url_fetcher_->SetRequestContext(request_context_getter_);
   url_fetcher_->SetUploadData(kRequestContentType, upload_data);
+  recorder_->RecordCheckinInitiated(request_info_.android_id);
   url_fetcher_->Start();
 }
 
@@ -121,6 +157,8 @@
     DVLOG(1) << "Delay GCM checkin for: "
              << backoff_entry_.GetTimeUntilRelease().InMilliseconds()
              << " milliseconds.";
+    recorder_->RecordCheckinDelayedDueToBackoff(
+        backoff_entry_.GetTimeUntilRelease().InMilliseconds());
     base::MessageLoop::current()->PostDelayedTask(
         FROM_HERE,
         base::Bind(&CheckinRequest::RetryWithBackoff,
@@ -138,7 +176,7 @@
   checkin_proto::AndroidCheckinResponse response_proto;
   if (!source->GetStatus().is_success()) {
     LOG(ERROR) << "Failed to get checkin response. Fetcher failed. Retrying.";
-    RecordCheckinStatusToUMA(URL_FETCHING_FAILED);
+    RecordCheckinStatusAndReportUMA(URL_FETCHING_FAILED, recorder_, true);
     RetryWithBackoff(true);
     return;
   }
@@ -151,8 +189,9 @@
     // UNAUTHORIZED indicates that security token didn't match the android id.
     LOG(ERROR) << "No point retrying the checkin with status: "
                << response_status << ". Checkin failed.";
-    RecordCheckinStatusToUMA(response_status == net::HTTP_BAD_REQUEST ?
-        HTTP_BAD_REQUEST : HTTP_UNAUTHORIZED);
+    CheckinRequestStatus status = response_status == net::HTTP_BAD_REQUEST ?
+        HTTP_BAD_REQUEST : HTTP_UNAUTHORIZED;
+    RecordCheckinStatusAndReportUMA(status, recorder_, false);
     callback_.Run(response_proto);
     return;
   }
@@ -162,8 +201,9 @@
       !response_proto.ParseFromString(response_string)) {
     LOG(ERROR) << "Failed to get checkin response. HTTP Status: "
                << response_status << ". Retrying.";
-    RecordCheckinStatusToUMA(response_status != net::HTTP_OK ?
-        HTTP_NOT_OK : RESPONSE_PARSING_FAILED);
+    CheckinRequestStatus status = response_status != net::HTTP_OK ?
+        HTTP_NOT_OK : RESPONSE_PARSING_FAILED;
+    RecordCheckinStatusAndReportUMA(status, recorder_, true);
     RetryWithBackoff(true);
     return;
   }
@@ -173,12 +213,12 @@
       response_proto.android_id() == 0 ||
       response_proto.security_token() == 0) {
     LOG(ERROR) << "Android ID or security token is 0. Retrying.";
-    RecordCheckinStatusToUMA(ZERO_ID_OR_TOKEN);
+    RecordCheckinStatusAndReportUMA(ZERO_ID_OR_TOKEN, recorder_, true);
     RetryWithBackoff(true);
     return;
   }
 
-  RecordCheckinStatusToUMA(SUCCESS);
+  RecordCheckinStatusAndReportUMA(SUCCESS, recorder_, false);
   callback_.Run(response_proto);
 }
 
diff --git a/google_apis/gcm/engine/checkin_request.h b/google_apis/gcm/engine/checkin_request.h
index 5ae8dd3..0f04505 100644
--- a/google_apis/gcm/engine/checkin_request.h
+++ b/google_apis/gcm/engine/checkin_request.h
@@ -16,6 +16,7 @@
 #include "google_apis/gcm/protocol/checkin.pb.h"
 #include "net/base/backoff_entry.h"
 #include "net/url_request/url_fetcher_delegate.h"
+#include "url/gurl.h"
 
 namespace net {
 class URLRequestContextGetter;
@@ -23,6 +24,8 @@
 
 namespace gcm {
 
+class GCMStatsRecorder;
+
 // Enables making check-in requests with the GCM infrastructure. When called
 // with android_id and security_token both set to 0 it is an initial check-in
 // used to obtain credentials. These should be persisted and used for subsequent
@@ -55,10 +58,12 @@
     checkin_proto::ChromeBuildProto chrome_build_proto;
   };
 
-  CheckinRequest(const RequestInfo& request_info,
+  CheckinRequest(const GURL& checkin_url,
+                 const RequestInfo& request_info,
                  const net::BackoffEntry::Policy& backoff_policy,
                  const CheckinRequestCallback& callback,
-                 net::URLRequestContextGetter* request_context_getter);
+                 net::URLRequestContextGetter* request_context_getter,
+                 GCMStatsRecorder* recorder);
   virtual ~CheckinRequest();
 
   void Start();
@@ -75,9 +80,13 @@
   CheckinRequestCallback callback_;
 
   net::BackoffEntry backoff_entry_;
+  GURL checkin_url_;
   scoped_ptr<net::URLFetcher> url_fetcher_;
   const RequestInfo request_info_;
 
+  // Recorder that records GCM activities for debugging purpose. Not owned.
+  GCMStatsRecorder* recorder_;
+
   base::WeakPtrFactory<CheckinRequest> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(CheckinRequest);
diff --git a/google_apis/gcm/engine/checkin_request_unittest.cc b/google_apis/gcm/engine/checkin_request_unittest.cc
index e750df0..306563e 100644
--- a/google_apis/gcm/engine/checkin_request_unittest.cc
+++ b/google_apis/gcm/engine/checkin_request_unittest.cc
@@ -6,6 +6,7 @@
 #include <vector>
 
 #include "google_apis/gcm/engine/checkin_request.h"
+#include "google_apis/gcm/monitoring/gcm_stats_recorder.h"
 #include "google_apis/gcm/protocol/checkin.pb.h"
 #include "net/base/backoff_entry.h"
 #include "net/url_request/test_url_fetcher_factory.h"
@@ -49,6 +50,7 @@
 const uint64 kAndroidId = 42UL;
 const uint64 kBlankAndroidId = 999999UL;
 const uint64 kBlankSecurityToken = 999999UL;
+const char kCheckinURL[] = "http://foo.bar/checkin";
 const char kChromeVersion[] = "Version String";
 const uint64 kSecurityToken = 77;
 const char kSettingsDigest[] = "settings_digest";
@@ -90,6 +92,7 @@
   checkin_proto::ChromeBuildProto chrome_build_proto_;
   std::vector<std::string> account_ids_;
   scoped_ptr<CheckinRequest> request_;
+  GCMStatsRecorder recorder_;
 };
 
 CheckinRequestTest::CheckinRequestTest()
@@ -131,10 +134,12 @@
   // Then create a request with that protobuf and specified android_id,
   // security_token.
   request_.reset(new CheckinRequest(
+      GURL(kCheckinURL),
       request_info,
       kDefaultBackoffPolicy,
       base::Bind(&CheckinRequestTest::FetcherCallback, base::Unretained(this)),
-      url_request_context_getter_.get()));
+      url_request_context_getter_.get(),
+      &recorder_));
 
   // Setting android_id_ and security_token_ to blank value, not used elsewhere
   // in the tests.
@@ -179,17 +184,17 @@
   SetResponseStatusAndString(net::HTTP_OK, response_string);
 }
 
-TEST_F(CheckinRequestTest, FetcherData) {
+TEST_F(CheckinRequestTest, FetcherDataAndURL) {
   CreateRequest(kAndroidId, kSecurityToken);
   request_->Start();
 
   // Get data sent by request.
   net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
   ASSERT_TRUE(fetcher);
-  fetcher->set_response_code(net::HTTP_OK);
+  EXPECT_EQ(GURL(kCheckinURL), fetcher->GetOriginalURL());
+
   checkin_proto::AndroidCheckinRequest request_proto;
   request_proto.ParseFromString(fetcher->upload_data());
-
   EXPECT_EQ(kAndroidId, static_cast<uint64>(request_proto.id()));
   EXPECT_EQ(kSecurityToken, request_proto.security_token());
   EXPECT_EQ(chrome_build_proto_.platform(),
diff --git a/google_apis/gcm/engine/gservices_settings.cc b/google_apis/gcm/engine/gservices_settings.cc
index 20b9d7d..8e228ac 100644
--- a/google_apis/gcm/engine/gservices_settings.cc
+++ b/google_apis/gcm/engine/gservices_settings.cc
@@ -20,6 +20,7 @@
 const char kRegistrationURLKey[] = "gcm_registration_url";
 
 const int64 kDefaultCheckinInterval = 2 * 24 * 60 * 60;  // seconds = 2 days.
+const int64 kMinimumCheckinInterval = 12 * 60 * 60;      // seconds = 12 hours.
 const char kDefaultCheckinURL[] = "https://android.clients.google.com/checkin";
 const char kDefaultMCSHostname[] = "https://mtalk.google.com";
 const int kDefaultMCSSecurePort = 5228;
@@ -30,11 +31,18 @@
 
 namespace gcm {
 
-const int64 GServicesSettings::kMinimumCheckinInterval = 12 * 60 * 60;
+// static
+const base::TimeDelta GServicesSettings::MinimumCheckinInterval() {
+  return base::TimeDelta::FromSeconds(kMinimumCheckinInterval);
+}
 
-GServicesSettings::GServicesSettings(GCMStore* gcm_store)
-    : gcm_store_(gcm_store),
-      checkin_interval_(kDefaultCheckinInterval),
+// static
+const GURL GServicesSettings::DefaultCheckinURL() {
+  return GURL(kDefaultCheckinURL);
+}
+
+GServicesSettings::GServicesSettings()
+    : checkin_interval_(base::TimeDelta::FromSeconds(kDefaultCheckinInterval)),
       checkin_url_(kDefaultCheckinURL),
       mcs_hostname_(kDefaultMCSHostname),
       mcs_secure_port_(kDefaultMCSSecurePort),
@@ -44,12 +52,12 @@
 
 GServicesSettings::~GServicesSettings() {}
 
-void GServicesSettings::UpdateFromCheckinResponse(
+bool GServicesSettings::UpdateFromCheckinResponse(
   const checkin_proto::AndroidCheckinResponse& checkin_response) {
   if (!checkin_response.has_digest() ||
       checkin_response.digest() == digest_) {
     // There are no changes as digest is the same or no settings provided.
-    return;
+    return false;
   }
 
   std::map<std::string, std::string> settings;
@@ -63,12 +71,10 @@
   // passed the verificaiton in update settings.
   if (UpdateSettings(settings)) {
     digest_ = checkin_response.digest();
-    gcm_store_->SetGServicesSettings(
-        settings,
-        digest_,
-        base::Bind(&GServicesSettings::SetGServicesSettingsCallback,
-                   weak_ptr_factory_.GetWeakPtr()));
+    return true;
   }
+
+  return false;
 }
 
 void GServicesSettings::UpdateFromLoadResult(
@@ -77,6 +83,17 @@
     digest_ = load_result.gservices_digest;
 }
 
+std::map<std::string, std::string> GServicesSettings::GetSettingsMap() const {
+  std::map<std::string, std::string> settings;
+  settings[kCheckinIntervalKey] =
+      base::Int64ToString(checkin_interval_.InSeconds());
+  settings[kCheckinURLKey] = checkin_url_.spec();
+  settings[kMCSHostnameKey] = mcs_hostname_;
+  settings[kMCSSecurePortKey] = base::IntToString(mcs_secure_port_);
+  settings[kRegistrationURLKey] = registration_url_.spec();
+  return settings;
+}
+
 bool GServicesSettings::UpdateSettings(
     const std::map<std::string, std::string>& settings) {
   int64 new_checkin_interval = kMinimumCheckinInterval;
@@ -95,6 +112,10 @@
                << " is less than allowed minimum: " << kMinimumCheckinInterval;
     new_checkin_interval = kMinimumCheckinInterval;
   }
+  if (new_checkin_interval == std::numeric_limits<int64>::max()) {
+    LOG(ERROR) << "Checkin interval is too big: " << new_checkin_interval;
+    return false;
+  }
 
   std::string new_mcs_hostname;
   iter = settings.find(kMCSHostnameKey);
@@ -123,32 +144,34 @@
     return false;
   }
 
-  std::string new_checkin_url;
+  GURL new_checkin_url;
   iter = settings.find(kCheckinURLKey);
   if (iter == settings.end()) {
     LOG(ERROR) << "Setting not found: " << kCheckinURLKey;
     return false;
   }
-  new_checkin_url = iter->second;
-  if (new_checkin_url.empty()) {
-    LOG(ERROR) << "Empty checkin URL provided.";
+  new_checkin_url = GURL(iter->second);
+  if (!new_checkin_url.is_valid()) {
+    LOG(ERROR) << "Invalid checkin URL provided: "
+               << new_checkin_url.possibly_invalid_spec();
     return false;
   }
 
-  std::string new_registration_url;
+  GURL new_registration_url;
   iter = settings.find(kRegistrationURLKey);
   if (iter == settings.end()) {
     LOG(ERROR) << "Setting not found: " << kRegistrationURLKey;
     return false;
   }
-  new_registration_url = iter->second;
-  if (new_registration_url.empty()) {
-    LOG(ERROR) << "Empty registration URL provided.";
+  new_registration_url = GURL(iter->second);
+  if (!new_registration_url.is_valid()) {
+    LOG(ERROR) << "Invalid registration URL provided: "
+               << new_registration_url.possibly_invalid_spec();
     return false;
   }
 
   // We only update the settings once all of them are correct.
-  checkin_interval_ = new_checkin_interval;
+  checkin_interval_ = base::TimeDelta::FromSeconds(new_checkin_interval);
   mcs_hostname_ = new_mcs_hostname;
   mcs_secure_port_ = new_mcs_secure_port;
   checkin_url_ = new_checkin_url;
@@ -156,8 +179,4 @@
   return true;
 }
 
-void GServicesSettings::SetGServicesSettingsCallback(bool success) {
-  DCHECK(success);
-}
-
 }  // namespace gcm
diff --git a/google_apis/gcm/engine/gservices_settings.h b/google_apis/gcm/engine/gservices_settings.h
index 775c676..92e0e23 100644
--- a/google_apis/gcm/engine/gservices_settings.h
+++ b/google_apis/gcm/engine/gservices_settings.h
@@ -9,9 +9,11 @@
 #include <string>
 
 #include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
 #include "google_apis/gcm/base/gcm_export.h"
 #include "google_apis/gcm/engine/gcm_store.h"
 #include "google_apis/gcm/protocol/checkin.pb.h"
+#include "url/gurl.h"
 
 namespace gcm {
 
@@ -20,57 +22,53 @@
 class GCM_EXPORT GServicesSettings {
  public:
   // Minimum periodic checkin interval in seconds.
-  static const int64 kMinimumCheckinInterval;
+  static const base::TimeDelta MinimumCheckinInterval();
 
-  // Create an instance of GServicesSettings class. |gcm_store| is used to store
-  // the settings after they are extracted from checkin response.
-  explicit GServicesSettings(GCMStore* gcm_store);
+  // Default checkin URL.
+  static const GURL DefaultCheckinURL();
+
+  GServicesSettings();
   ~GServicesSettings();
 
-  // Udpates the settings based on |checkin_response|.
-  void UpdateFromCheckinResponse(
+  // Updates the settings based on |checkin_response|.
+  bool UpdateFromCheckinResponse(
       const checkin_proto::AndroidCheckinResponse& checkin_response);
 
-  // Updates the settings based on |load_result|.
+  // Updates the settings based on |load_result|. Returns true if update was
+  // successful, false otherwise.
   void UpdateFromLoadResult(const GCMStore::LoadResult& load_result);
 
-  const std::string& digest() const { return digest_; }
+  // Gets the settings as a map of string to string for storing.
+  std::map<std::string, std::string> GetSettingsMap() const;
 
-  // TODO(fgorski): Consider returning TimeDelta.
-  int64 checkin_interval() const { return checkin_interval_; }
+  std::string digest() const { return digest_; }
+
+  base::TimeDelta checkin_interval() const { return checkin_interval_; }
+
+  GURL checkin_url() const { return checkin_url_; }
 
   // TODO(fgorski): Consider returning GURL and use it for validation.
-  const std::string& checkin_url() const { return checkin_url_; }
-
-  // TODO(fgorski): Consider returning GURL and use it for validation.
-  const std::string& mcs_hostname() const { return mcs_hostname_; }
+  std::string mcs_hostname() const { return mcs_hostname_; }
 
   int mcs_secure_port() const { return mcs_secure_port_; }
 
-  // TODO(fgorski): Consider returning GURL and use it for validation.
-  const std::string& registration_url() const { return registration_url_; }
+  GURL registration_url() const { return registration_url_; }
 
  private:
   // Parses the |settings| to fill in specific fields.
   // TODO(fgorski): Change to a status variable that can be logged to UMA.
   bool UpdateSettings(const std::map<std::string, std::string>& settings);
 
-  // Callback passed to GCMStore::SetGServicesSettings.
-  void SetGServicesSettingsCallback(bool success);
-
-  // GCM store to persist the settings. Not owned.
-  GCMStore* gcm_store_;
-
   // Digest (hash) of the settings, used to check whether settings need update.
   // It is meant to be sent with checkin request, instead of sending the whole
   // settings table.
   std::string digest_;
 
-  // Time in seconds between periodic checkins.
-  int64 checkin_interval_;
+  // Time delta between periodic checkins.
+  base::TimeDelta checkin_interval_;
 
   // URL that should be used for checkins.
-  std::string checkin_url_;
+  GURL checkin_url_;
 
   // Hostname of the MCS server.
   std::string mcs_hostname_;
@@ -79,7 +77,7 @@
   int mcs_secure_port_;
 
   // URL that should be used for regisrations and unregistrations.
-  std::string registration_url_;
+  GURL registration_url_;
 
   // Factory for creating references in callbacks.
   base::WeakPtrFactory<GServicesSettings> weak_ptr_factory_;
diff --git a/google_apis/gcm/engine/gservices_settings_unittest.cc b/google_apis/gcm/engine/gservices_settings_unittest.cc
index de756f8..886bc6d 100644
--- a/google_apis/gcm/engine/gservices_settings_unittest.cc
+++ b/google_apis/gcm/engine/gservices_settings_unittest.cc
@@ -26,77 +26,6 @@
 const char kDefaultRegistrationURL[] =
     "https://android.clients.google.com/c2dm/register3";
 
-class FakeGCMStore : public GCMStore {
- public:
-  FakeGCMStore();
-  virtual ~FakeGCMStore();
-
-  virtual void Load(const gcm::GCMStore::LoadCallback& callback) OVERRIDE {}
-  virtual void Close() OVERRIDE {}
-  virtual void Destroy(const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {
-  }
-  virtual void SetDeviceCredentials(
-      uint64 device_android_id,
-      uint64 device_security_token,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {}
-  virtual void AddRegistration(
-      const std::string& app_id,
-      const linked_ptr<gcm::RegistrationInfo>& registration,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {}
-  virtual void RemoveRegistration(
-      const std::string& app_id,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {}
-  virtual void AddIncomingMessage(
-      const std::string& persistent_id,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {}
-  virtual void RemoveIncomingMessage(
-      const std::string& persistent_id,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {}
-  virtual void RemoveIncomingMessages(
-      const PersistentIdList& persistent_ids,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {}
-  virtual bool AddOutgoingMessage(
-      const std::string& persistent_id,
-      const gcm::MCSMessage& message,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {
-    return true;
-  }
-  virtual void OverwriteOutgoingMessage(
-      const std::string& persistent_id,
-      const gcm::MCSMessage& message,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {}
-  virtual void RemoveOutgoingMessage(
-      const std::string& persistent_id,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {}
-  virtual void RemoveOutgoingMessages(
-      const PersistentIdList& persistent_ids,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {}
-  virtual void SetLastCheckinTime(
-      const base::Time& last_checkin_time,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {}
-
-  // G-service settings handling.
-  virtual void SetGServicesSettings(
-      const std::map<std::string, std::string>& settings,
-      const std::string& settings_digest,
-      const gcm::GCMStore::UpdateCallback& callback) OVERRIDE {
-    settings_saved_ = true;
-  }
-
-  void Reset() {
-    settings_saved_ = false;
-  }
-
-  bool settings_saved() const { return settings_saved_; }
-
- private:
-  bool settings_saved_;
-};
-
-FakeGCMStore::FakeGCMStore() : settings_saved_(false) {}
-
-FakeGCMStore::~FakeGCMStore() {}
-
 }  // namespace
 
 class GServicesSettingsTest : public testing::Test {
@@ -119,17 +48,14 @@
     return alternative_settings_;
   }
 
-  FakeGCMStore& gcm_store() { return gcm_store_; }
-
   std::map<std::string, std::string> alternative_settings_;
 
  private:
-  FakeGCMStore gcm_store_;
   GServicesSettings gserivces_settings_;
 };
 
 GServicesSettingsTest::GServicesSettingsTest()
-    : gserivces_settings_(&gcm_store_) {
+    : gserivces_settings_() {
 }
 
 GServicesSettingsTest::~GServicesSettingsTest() {}
@@ -145,19 +71,21 @@
 }
 
 void GServicesSettingsTest::CheckAllSetToDefault() {
-  EXPECT_EQ(kDefaultCheckinInterval, settings().checkin_interval());
-  EXPECT_EQ(kDefaultCheckinURL, settings().checkin_url());
+  EXPECT_EQ(base::TimeDelta::FromSeconds(kDefaultCheckinInterval),
+            settings().checkin_interval());
+  EXPECT_EQ(GURL(kDefaultCheckinURL), settings().checkin_url());
   EXPECT_EQ(kDefaultMCSHostname, settings().mcs_hostname());
   EXPECT_EQ(kDefaultMCSSecurePort, settings().mcs_secure_port());
-  EXPECT_EQ(kDefaultRegistrationURL, settings().registration_url());
+  EXPECT_EQ(GURL(kDefaultRegistrationURL), settings().registration_url());
 }
 
 void GServicesSettingsTest::CheckAllSetToAlternative() {
-  EXPECT_EQ(kAlternativeCheckinInterval, settings().checkin_interval());
-  EXPECT_EQ(kAlternativeCheckinURL, settings().checkin_url());
+  EXPECT_EQ(base::TimeDelta::FromSeconds(kAlternativeCheckinInterval),
+            settings().checkin_interval());
+  EXPECT_EQ(GURL(kAlternativeCheckinURL), settings().checkin_url());
   EXPECT_EQ(kAlternativeMCSHostname, settings().mcs_hostname());
   EXPECT_EQ(kAlternativeMCSSecurePort, settings().mcs_secure_port());
-  EXPECT_EQ(kAlternativeRegistrationURL, settings().registration_url());
+  EXPECT_EQ(GURL(kAlternativeRegistrationURL), settings().registration_url());
 }
 
 void GServicesSettingsTest::SetWithAlternativeSettings(
@@ -218,10 +146,10 @@
   checkin_response.set_digest("digest_value");
   SetWithAlternativeSettings(checkin_response);
 
-  settings().UpdateFromCheckinResponse(checkin_response);
-  EXPECT_TRUE(gcm_store().settings_saved());
+  EXPECT_TRUE(settings().UpdateFromCheckinResponse(checkin_response));
 
   CheckAllSetToAlternative();
+  EXPECT_EQ(alternative_settings_, settings().GetSettingsMap());
   EXPECT_EQ("digest_value", settings().digest());
 }
 
@@ -235,10 +163,9 @@
   alternative_settings_["checkin_interval"] = base::IntToString(3600);
   SetWithAlternativeSettings(checkin_response);
 
-  settings().UpdateFromCheckinResponse(checkin_response);
-  EXPECT_TRUE(gcm_store().settings_saved());
+  EXPECT_TRUE(settings().UpdateFromCheckinResponse(checkin_response));
 
-  EXPECT_EQ(GServicesSettings::kMinimumCheckinInterval,
+  EXPECT_EQ(GServicesSettings::MinimumCheckinInterval(),
             settings().checkin_interval());
   EXPECT_EQ("digest_value", settings().digest());
 }
@@ -251,8 +178,7 @@
   alternative_settings_.erase("gcm_hostname");
   SetWithAlternativeSettings(checkin_response);
 
-  settings().UpdateFromCheckinResponse(checkin_response);
-  EXPECT_FALSE(gcm_store().settings_saved());
+  EXPECT_FALSE(settings().UpdateFromCheckinResponse(checkin_response));
 
   CheckAllSetToDefault();
   EXPECT_EQ(std::string(), settings().digest());
@@ -263,8 +189,7 @@
   checkin_proto::AndroidCheckinResponse checkin_response;
 
   SetWithAlternativeSettings(checkin_response);
-  settings().UpdateFromCheckinResponse(checkin_response);
-  EXPECT_FALSE(gcm_store().settings_saved());
+  EXPECT_FALSE(settings().UpdateFromCheckinResponse(checkin_response));
 
   CheckAllSetToDefault();
   EXPECT_EQ(std::string(), settings().digest());
@@ -280,8 +205,7 @@
   checkin_proto::AndroidCheckinResponse checkin_response;
   checkin_response.set_digest("old_digest");
   SetWithAlternativeSettings(checkin_response);
-  settings().UpdateFromCheckinResponse(checkin_response);
-  EXPECT_FALSE(gcm_store().settings_saved());
+  EXPECT_FALSE(settings().UpdateFromCheckinResponse(checkin_response));
 
   CheckAllSetToAlternative();
   EXPECT_EQ("old_digest", settings().digest());
diff --git a/google_apis/gcm/engine/registration_request.cc b/google_apis/gcm/engine/registration_request.cc
index 13a040b..dd3f369 100644
--- a/google_apis/gcm/engine/registration_request.cc
+++ b/google_apis/gcm/engine/registration_request.cc
@@ -22,8 +22,6 @@
 
 namespace {
 
-const char kRegistrationURL[] =
-    "https://android.clients.google.com/c2dm/register3";
 const char kRegistrationRequestContentType[] =
     "application/x-www-form-urlencoded";
 
@@ -99,6 +97,7 @@
 RegistrationRequest::RequestInfo::~RequestInfo() {}
 
 RegistrationRequest::RegistrationRequest(
+    const GURL& registration_url,
     const RequestInfo& request_info,
     const net::BackoffEntry::Policy& backoff_policy,
     const RegistrationCallback& callback,
@@ -107,6 +106,7 @@
     GCMStatsRecorder* recorder)
     : callback_(callback),
       request_info_(request_info),
+      registration_url_(registration_url),
       backoff_entry_(&backoff_policy),
       request_context_getter_(request_context_getter),
       retries_left_(max_retry_count),
@@ -126,7 +126,7 @@
 
   DCHECK(!url_fetcher_.get());
   url_fetcher_.reset(net::URLFetcher::Create(
-      GURL(kRegistrationURL), net::URLFetcher::POST, this));
+      registration_url_, net::URLFetcher::POST, this));
   url_fetcher_->SetRequestContext(request_context_getter_);
 
   std::string android_id = base::Uint64ToString(request_info_.android_id);
diff --git a/google_apis/gcm/engine/registration_request.h b/google_apis/gcm/engine/registration_request.h
index 95ec4d9..30bed41 100644
--- a/google_apis/gcm/engine/registration_request.h
+++ b/google_apis/gcm/engine/registration_request.h
@@ -16,6 +16,7 @@
 #include "google_apis/gcm/base/gcm_export.h"
 #include "net/base/backoff_entry.h"
 #include "net/url_request/url_fetcher_delegate.h"
+#include "url/gurl.h"
 
 namespace net {
 class URLRequestContextGetter;
@@ -80,6 +81,7 @@
   };
 
   RegistrationRequest(
+      const GURL& registration_url,
       const RequestInfo& request_info,
       const net::BackoffEntry::Policy& backoff_policy,
       const RegistrationCallback& callback,
@@ -104,6 +106,7 @@
 
   RegistrationCallback callback_;
   RequestInfo request_info_;
+  GURL registration_url_;
 
   net::BackoffEntry backoff_entry_;
   scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
diff --git a/google_apis/gcm/engine/registration_request_unittest.cc b/google_apis/gcm/engine/registration_request_unittest.cc
index 859f20b..37f2575 100644
--- a/google_apis/gcm/engine/registration_request_unittest.cc
+++ b/google_apis/gcm/engine/registration_request_unittest.cc
@@ -22,6 +22,7 @@
 const char kAppId[] = "TestAppId";
 const char kDeveloperId[] = "Project1";
 const char kLoginHeader[] = "AidLogin";
+const char kRegistrationURL[] = "http://foo.bar/register";
 const uint64 kSecurityToken = 77UL;
 
 // Backoff policy for testing registration request.
@@ -108,6 +109,7 @@
     senders.push_back(tokenizer.token());
 
   request_.reset(new RegistrationRequest(
+      GURL(kRegistrationURL),
       RegistrationRequest::RequestInfo(kAndroidId,
                                        kSecurityToken,
                                        kAppId,
@@ -152,7 +154,7 @@
   EXPECT_EQ("2501", registration_id_);
 }
 
-TEST_F(RegistrationRequestTest, RequestDataPassedToFetcher) {
+TEST_F(RegistrationRequestTest, RequestDataAndURL) {
   CreateRequest(kDeveloperId);
   request_->Start();
 
@@ -160,6 +162,8 @@
   net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
   ASSERT_TRUE(fetcher);
 
+  EXPECT_EQ(GURL(kRegistrationURL), fetcher->GetOriginalURL());
+
   // Verify that authorization header was put together properly.
   net::HttpRequestHeaders headers;
   fetcher->GetExtraRequestHeaders(&headers);
diff --git a/google_apis/gcm/engine/unregistration_request.cc b/google_apis/gcm/engine/unregistration_request.cc
index dbcce84..92136bf 100644
--- a/google_apis/gcm/engine/unregistration_request.cc
+++ b/google_apis/gcm/engine/unregistration_request.cc
@@ -17,14 +17,11 @@
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_status.h"
-#include "url/gurl.h"
 
 namespace gcm {
 
 namespace {
 
-const char kRegistrationURL[] =
-    "https://android.clients.google.com/c2dm/register3";
 const char kRequestContentType[] = "application/x-www-form-urlencoded";
 
 // Request constants.
@@ -113,6 +110,7 @@
 UnregistrationRequest::RequestInfo::~RequestInfo() {}
 
 UnregistrationRequest::UnregistrationRequest(
+    const GURL& registration_url,
     const RequestInfo& request_info,
     const net::BackoffEntry::Policy& backoff_policy,
     const UnregistrationCallback& callback,
@@ -120,6 +118,7 @@
     GCMStatsRecorder* recorder)
     : callback_(callback),
       request_info_(request_info),
+      registration_url_(registration_url),
       backoff_entry_(&backoff_policy),
       request_context_getter_(request_context_getter),
       recorder_(recorder),
@@ -135,7 +134,7 @@
   DCHECK(!url_fetcher_.get());
 
   url_fetcher_.reset(net::URLFetcher::Create(
-      GURL(kRegistrationURL), net::URLFetcher::POST, this));
+      registration_url_, net::URLFetcher::POST, this));
   url_fetcher_->SetRequestContext(request_context_getter_);
 
   std::string android_id = base::Uint64ToString(request_info_.android_id);
diff --git a/google_apis/gcm/engine/unregistration_request.h b/google_apis/gcm/engine/unregistration_request.h
index ad9b82c..b25e28c 100644
--- a/google_apis/gcm/engine/unregistration_request.h
+++ b/google_apis/gcm/engine/unregistration_request.h
@@ -13,6 +13,7 @@
 #include "google_apis/gcm/base/gcm_export.h"
 #include "net/base/backoff_entry.h"
 #include "net/url_request/url_fetcher_delegate.h"
+#include "url/gurl.h"
 
 namespace net {
 class URLRequestContextGetter;
@@ -72,6 +73,7 @@
   // once registration has been revoked or there has been an error that makes
   // further retries pointless.
   UnregistrationRequest(
+      const GURL& registration_url,
       const RequestInfo& request_info,
       const net::BackoffEntry::Policy& backoff_policy,
       const UnregistrationCallback& callback,
@@ -92,6 +94,7 @@
 
   UnregistrationCallback callback_;
   RequestInfo request_info_;
+  GURL registration_url_;
 
   net::BackoffEntry backoff_entry_;
   scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
diff --git a/google_apis/gcm/engine/unregistration_request_unittest.cc b/google_apis/gcm/engine/unregistration_request_unittest.cc
index dff9fb7..02f4968 100644
--- a/google_apis/gcm/engine/unregistration_request_unittest.cc
+++ b/google_apis/gcm/engine/unregistration_request_unittest.cc
@@ -21,6 +21,7 @@
 const char kLoginHeader[] = "AidLogin";
 const char kAppId[] = "TestAppId";
 const char kDeletedAppId[] = "deleted=TestAppId";
+const char kRegistrationURL[] = "http://foo.bar/register";
 const uint64 kSecurityToken = 77UL;
 
 // Backoff policy for testing registration request.
@@ -91,6 +92,7 @@
 
 void UnregistrationRequestTest::CreateRequest() {
   request_.reset(new UnregistrationRequest(
+      GURL(kRegistrationURL),
       UnregistrationRequest::RequestInfo(kAndroidId,
                                          kSecurityToken,
                                          kAppId),
@@ -126,6 +128,8 @@
   net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
   ASSERT_TRUE(fetcher);
 
+  EXPECT_EQ(GURL(kRegistrationURL), fetcher->GetOriginalURL());
+
   // Verify that authorization header was put together properly.
   net::HttpRequestHeaders headers;
   fetcher->GetExtraRequestHeaders(&headers);
diff --git a/google_apis/gcm/gcm_client_impl.cc b/google_apis/gcm/gcm_client_impl.cc
index 2a59bbf..a0a2142 100644
--- a/google_apis/gcm/gcm_client_impl.cc
+++ b/google_apis/gcm/gcm_client_impl.cc
@@ -19,8 +19,6 @@
 #include "google_apis/gcm/engine/checkin_request.h"
 #include "google_apis/gcm/engine/connection_factory_impl.h"
 #include "google_apis/gcm/engine/gcm_store_impl.h"
-#include "google_apis/gcm/engine/gservices_settings.h"
-#include "google_apis/gcm/engine/mcs_client.h"
 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h"
 #include "google_apis/gcm/protocol/mcs.pb.h"
 #include "net/http/http_network_session.h"
@@ -194,7 +192,6 @@
   account_ids_ = account_ids;
 
   gcm_store_.reset(new GCMStoreImpl(path, blocking_task_runner));
-  gservices_settings_.reset(new GServicesSettings(gcm_store_.get()));
 
   delegate_ = delegate;
 
@@ -222,7 +219,7 @@
   device_checkin_info_.android_id = result->device_android_id;
   device_checkin_info_.secret = result->device_security_token;
   last_checkin_time_ = result->last_checkin_time;
-  gservices_settings_->UpdateFromLoadResult(*result);
+  gservices_settings_.UpdateFromLoadResult(*result);
   InitializeMCSClient(result.Pass());
 
   if (device_checkin_info_.IsValid()) {
@@ -303,15 +300,17 @@
 
   CheckinRequest::RequestInfo request_info(device_checkin_info_.android_id,
                                            device_checkin_info_.secret,
-                                           gservices_settings_->digest(),
+                                           gservices_settings_.digest(),
                                            account_ids_,
                                            chrome_build_proto_);
   checkin_request_.reset(
-      new CheckinRequest(request_info,
+      new CheckinRequest(gservices_settings_.checkin_url(),
+                         request_info,
                          kDefaultBackoffPolicy,
                          base::Bind(&GCMClientImpl::OnCheckinCompleted,
                                     weak_ptr_factory_.GetWeakPtr()),
-                         url_request_context_getter_));
+                         url_request_context_getter_,
+                         &recorder_));
   checkin_request_->Start();
 }
 
@@ -342,7 +341,14 @@
 
   if (device_checkin_info_.IsValid()) {
     // First update G-services settings, as something might have changed.
-    gservices_settings_->UpdateFromCheckinResponse(checkin_response);
+    if (gservices_settings_.UpdateFromCheckinResponse(checkin_response)) {
+      gcm_store_->SetGServicesSettings(
+          gservices_settings_.GetSettingsMap(),
+          gservices_settings_.digest(),
+          base::Bind(&GCMClientImpl::SetGServicesSettingsCallback,
+                     weak_ptr_factory_.GetWeakPtr()));
+    }
+
     last_checkin_time_ = clock_->Now();
     gcm_store_->SetLastCheckinTime(
         last_checkin_time_,
@@ -352,6 +358,10 @@
   }
 }
 
+void GCMClientImpl::SetGServicesSettingsCallback(bool success) {
+  DCHECK(success);
+}
+
 void GCMClientImpl::SchedulePeriodicCheckin() {
   // Make sure no checkin is in progress.
   if (checkin_request_.get())
@@ -373,8 +383,7 @@
 }
 
 base::TimeDelta GCMClientImpl::GetTimeToNextCheckin() const {
-  return last_checkin_time_ +
-         base::TimeDelta::FromSeconds(gservices_settings_->checkin_interval()) -
+  return last_checkin_time_ + gservices_settings_.checkin_interval() -
          clock_->Now();
 }
 
@@ -432,7 +441,8 @@
   DCHECK_EQ(0u, pending_registration_requests_.count(app_id));
 
   RegistrationRequest* registration_request =
-      new RegistrationRequest(request_info,
+      new RegistrationRequest(gservices_settings_.registration_url(),
+                              request_info,
                               kDefaultBackoffPolicy,
                               base::Bind(&GCMClientImpl::OnRegisterCompleted,
                                          weak_ptr_factory_.GetWeakPtr(),
@@ -507,6 +517,7 @@
 
   UnregistrationRequest* unregistration_request =
       new UnregistrationRequest(
+          gservices_settings_.registration_url(),
           request_info,
           kDefaultBackoffPolicy,
           base::Bind(&GCMClientImpl::OnUnregisterCompleted,
@@ -691,7 +702,7 @@
       HandleIncomingDataMessage(data_message_stanza, message_data);
       break;
     case DELETED_MESSAGES:
-      recorder_.RecordDataMessageRecieved(data_message_stanza.category(),
+      recorder_.RecordDataMessageReceived(data_message_stanza.category(),
                                           data_message_stanza.from(),
                                           data_message_stanza.ByteSize(),
                                           true,
@@ -722,7 +733,7 @@
       std::find(iter->second->sender_ids.begin(),
                 iter->second->sender_ids.end(),
                 data_message_stanza.from()) == iter->second->sender_ids.end();
-  recorder_.RecordDataMessageRecieved(app_id, data_message_stanza.from(),
+  recorder_.RecordDataMessageReceived(app_id, data_message_stanza.from(),
       data_message_stanza.ByteSize(), !not_registered,
       GCMStatsRecorder::DATA_MESSAGE);
   if (not_registered) {
diff --git a/google_apis/gcm/gcm_client_impl.h b/google_apis/gcm/gcm_client_impl.h
index f38a08d..85f206b 100644
--- a/google_apis/gcm/gcm_client_impl.h
+++ b/google_apis/gcm/gcm_client_impl.h
@@ -15,6 +15,7 @@
 #include "base/stl_util.h"
 #include "google_apis/gcm/base/mcs_message.h"
 #include "google_apis/gcm/engine/gcm_store.h"
+#include "google_apis/gcm/engine/gservices_settings.h"
 #include "google_apis/gcm/engine/mcs_client.h"
 #include "google_apis/gcm/engine/registration_request.h"
 #include "google_apis/gcm/engine/unregistration_request.h"
@@ -45,7 +46,6 @@
 class CheckinRequest;
 class ConnectionFactory;
 class GCMClientImplTest;
-class GServicesSettings;
 
 // Helper class for building GCM internals. Allows tests to inject fake versions
 // as necessary.
@@ -179,6 +179,10 @@
   // Function also cleans up the pending checkin.
   void OnCheckinCompleted(
       const checkin_proto::AndroidCheckinResponse& checkin_response);
+
+  // Callback passed to GCMStore::SetGServicesSettings.
+  void SetGServicesSettingsCallback(bool success);
+
   // Schedules next periodic device checkin and makes sure there is at most one
   // pending checkin at a time. This function is meant to be called after a
   // successful checkin.
@@ -275,7 +279,7 @@
       pending_unregistration_requests_deleter_;
 
   // G-services settings that were provided by MCS.
-  scoped_ptr<GServicesSettings> gservices_settings_;
+  GServicesSettings gservices_settings_;
 
   // Time of the last successful checkin.
   base::Time last_checkin_time_;
diff --git a/google_apis/gcm/gcm_client_impl_unittest.cc b/google_apis/gcm/gcm_client_impl_unittest.cc
index 25c0afd..ba49590 100644
--- a/google_apis/gcm/gcm_client_impl_unittest.cc
+++ b/google_apis/gcm/gcm_client_impl_unittest.cc
@@ -281,8 +281,8 @@
     return last_error_details_;
   }
 
-  const GServicesSettings* gservices_settings() const {
-    return gcm_client_->gservices_settings_.get();
+  const GServicesSettings& gservices_settings() const {
+    return gcm_client_->gservices_settings_;
   }
 
   int64 CurrentTime();
@@ -723,7 +723,14 @@
   settings["gcm_registration_url"] = "http://alternative.url/registration";
   CompleteCheckin(
       kDeviceAndroidId, kDeviceSecurityToken, kSettingsDefaultDigest, settings);
-  EXPECT_EQ(kSettingsCheckinInterval, gservices_settings()->checkin_interval());
+  EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval),
+            gservices_settings().checkin_interval());
+  EXPECT_EQ(GURL("http://alternative.url/checkin"),
+            gservices_settings().checkin_url());
+  EXPECT_EQ(GURL("http://alternative.url/registration"),
+            gservices_settings().registration_url());
+  EXPECT_EQ("http://alternative.gcm.host", gservices_settings().mcs_hostname());
+  EXPECT_EQ(443, gservices_settings().mcs_secure_port());
 }
 
 // This test only checks that periodic checkin happens.
@@ -743,4 +750,27 @@
       kDeviceAndroidId, kDeviceSecurityToken, kSettingsDefaultDigest, settings);
 }
 
+TEST_F(GCMClientImplCheckinTest, LoadGSettingsFromStore) {
+  std::map<std::string, std::string> settings;
+  settings["checkin_interval"] = base::IntToString(kSettingsCheckinInterval);
+  settings["checkin_url"] = "http://alternative.url/checkin";
+  settings["gcm_hostname"] = "http://alternative.gcm.host";
+  settings["gcm_secure_port"] = "443";
+  settings["gcm_registration_url"] = "http://alternative.url/registration";
+  CompleteCheckin(
+      kDeviceAndroidId, kDeviceSecurityToken, kSettingsDefaultDigest, settings);
+
+  BuildGCMClient(base::TimeDelta());
+  InitializeGCMClient();
+
+  EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval),
+            gservices_settings().checkin_interval());
+  EXPECT_EQ(GURL("http://alternative.url/checkin"),
+            gservices_settings().checkin_url());
+  EXPECT_EQ(GURL("http://alternative.url/registration"),
+            gservices_settings().registration_url());
+  EXPECT_EQ("http://alternative.gcm.host", gservices_settings().mcs_hostname());
+  EXPECT_EQ(443, gservices_settings().mcs_secure_port());
+}
+
 }  // namespace gcm
diff --git a/google_apis/gcm/monitoring/gcm_stats_recorder.cc b/google_apis/gcm/monitoring/gcm_stats_recorder.cc
index ed93891..649720f 100644
--- a/google_apis/gcm/monitoring/gcm_stats_recorder.cc
+++ b/google_apis/gcm/monitoring/gcm_stats_recorder.cc
@@ -19,7 +19,7 @@
 
 namespace {
 
-// Insert an itme to the front of deque while maintaining the size of the deque.
+// Insert an item to the front of deque while maintaining the size of the deque.
 // Overflow item is discarded.
 template <typename T>
 T* InsertCircularBuffer(std::deque<T>* q, const T& item) {
@@ -147,6 +147,12 @@
 GCMStatsRecorder::Activity::~Activity() {
 }
 
+GCMStatsRecorder::CheckinActivity::CheckinActivity() {
+}
+
+GCMStatsRecorder::CheckinActivity::~CheckinActivity() {
+}
+
 GCMStatsRecorder::ConnectionActivity::ConnectionActivity() {
 }
 
@@ -189,12 +195,54 @@
 }
 
 void GCMStatsRecorder::Clear() {
+  checkin_activities_.clear();
   connection_activities_.clear();
   registration_activities_.clear();
   receiving_activities_.clear();
   sending_activities_.clear();
 }
 
+void GCMStatsRecorder::RecordCheckin(
+    const std::string& event,
+    const std::string& details) {
+  CheckinActivity data;
+  CheckinActivity* inserted_data = InsertCircularBuffer(
+      &checkin_activities_, data);
+  inserted_data->event = event;
+  inserted_data->details = details;
+}
+
+void GCMStatsRecorder::RecordCheckinInitiated(uint64 android_id) {
+  if (!is_recording_)
+    return;
+  RecordCheckin("Checkin initiated",
+                base::StringPrintf("Android Id: %" PRIu64, android_id));
+}
+
+void GCMStatsRecorder::RecordCheckinDelayedDueToBackoff(int64 delay_msec) {
+  if (!is_recording_)
+    return;
+  RecordCheckin("Checkin backoff",
+                base::StringPrintf("Delayed for %" PRId64 " msec",
+                                   delay_msec));
+}
+
+void GCMStatsRecorder::RecordCheckinSuccess() {
+  if (!is_recording_)
+    return;
+  RecordCheckin("Checkin succeeded", std::string());
+}
+
+void GCMStatsRecorder::RecordCheckinFailure(std::string status,
+                                            bool will_retry) {
+  if (!is_recording_)
+    return;
+  RecordCheckin("Checkin failed", base::StringPrintf(
+      "%s.%s",
+      status.c_str(),
+      will_retry ? " Will retry." : "Will not retry."));
+}
+
 void GCMStatsRecorder::RecordConnection(
     const std::string& event,
     const std::string& details) {
@@ -332,7 +380,7 @@
   inserted_data->details = details;
 }
 
-void GCMStatsRecorder::RecordDataMessageRecieved(
+void GCMStatsRecorder::RecordDataMessageReceived(
     const std::string& app_id,
     const std::string& from,
     int message_byte_size,
@@ -364,6 +412,10 @@
 
 void GCMStatsRecorder::CollectActivities(
     RecordedActivities* recorder_activities) const {
+  recorder_activities->checkin_activities.insert(
+      recorder_activities->checkin_activities.begin(),
+      checkin_activities_.begin(),
+      checkin_activities_.end());
   recorder_activities->connection_activities.insert(
       recorder_activities->connection_activities.begin(),
       connection_activities_.begin(),
diff --git a/google_apis/gcm/monitoring/gcm_stats_recorder.h b/google_apis/gcm/monitoring/gcm_stats_recorder.h
index fb8e805..ffee1ae 100644
--- a/google_apis/gcm/monitoring/gcm_stats_recorder.h
+++ b/google_apis/gcm/monitoring/gcm_stats_recorder.h
@@ -49,6 +49,12 @@
     virtual ~ConnectionActivity();
   };
 
+  // Contains relevant data of a check-in activity.
+  struct GCM_EXPORT CheckinActivity : Activity {
+    CheckinActivity();
+    virtual ~CheckinActivity();
+  };
+
   // Contains relevant data of a registration/unregistration step.
   struct GCM_EXPORT RegistrationActivity : Activity {
     RegistrationActivity();
@@ -82,6 +88,7 @@
     RecordedActivities();
     virtual ~RecordedActivities();
 
+    std::vector<GCMStatsRecorder::CheckinActivity> checkin_activities;
     std::vector<GCMStatsRecorder::ConnectionActivity> connection_activities;
     std::vector<GCMStatsRecorder::RegistrationActivity> registration_activities;
     std::vector<GCMStatsRecorder::ReceivingActivity> receiving_activities;
@@ -106,6 +113,19 @@
   // to the front of a queue so that entries in the queue had reverse
   // chronological order.
 
+  // Records that a check-in has been initiated.
+  void RecordCheckinInitiated(uint64 android_id);
+
+  // Records that a check-in has been delayed due to backoff.
+  void RecordCheckinDelayedDueToBackoff(int64 delay_msec);
+
+  // Records that a check-in request has succeeded.
+  void RecordCheckinSuccess();
+
+  // Records that a check-in request has failed. If a retry will be tempted then
+  // will_retry should be true.
+  void RecordCheckinFailure(std::string status, bool will_retry);
+
   // Records that a connection to MCS has been initiated.
   void RecordConnectionInitiated(const std::string& host);
 
@@ -156,7 +176,7 @@
   // sent to a registered app, to_registered_app shoudl be false. If it
   // indicates that a message has been dropped on the server, is_message_dropped
   // should be true.
-  void RecordDataMessageRecieved(const std::string& app_id,
+  void RecordDataMessageReceived(const std::string& app_id,
                                  const std::string& from,
                                  int message_byte_size,
                                  bool to_registered_app,
@@ -182,6 +202,9 @@
   // Collect all recorded activities into the struct.
   void CollectActivities(RecordedActivities* recorder_activities) const;
 
+  const std::deque<CheckinActivity>& checkin_activities() const {
+    return checkin_activities_;
+  }
   const std::deque<ConnectionActivity>& connection_activities() const {
     return connection_activities_;
   }
@@ -196,6 +219,8 @@
   }
 
  protected:
+  void RecordCheckin(const std::string& event,
+                     const std::string& details);
   void RecordConnection(const std::string& event,
                         const std::string& details);
   void RecordRegistration(const std::string& app_id,
@@ -215,6 +240,7 @@
 
   bool is_recording_;
 
+  std::deque<CheckinActivity> checkin_activities_;
   std::deque<ConnectionActivity> connection_activities_;
   std::deque<RegistrationActivity> registration_activities_;
   std::deque<ReceivingActivity> receiving_activities_;
diff --git a/google_apis/gcm/monitoring/gcm_stats_recorder_unittest.cc b/google_apis/gcm/monitoring/gcm_stats_recorder_unittest.cc
index ccf3caf..d33fc24 100644
--- a/google_apis/gcm/monitoring/gcm_stats_recorder_unittest.cc
+++ b/google_apis/gcm/monitoring/gcm_stats_recorder_unittest.cc
@@ -15,6 +15,8 @@
 
 namespace {
 
+static uint64 kAndroidId = 4U;
+static const char kCheckinStatus[] = "URL_FETCHING_FAILED";
 static const char kHost[] = "www.example.com";
 static const char kAppId[] = "app id 1";
 static const char kFrom[] = "from";
@@ -37,6 +39,16 @@
 static const UnregistrationRequest::Status kUnregistrationStatus =
     UnregistrationRequest::SUCCESS;
 
+static const char kCheckinInitiatedEvent[] = "Checkin initiated";
+static const char kCheckinInitiatedDetails[] = "Android Id: 4";
+static const char kCheckinDelayedDueToBackoffEvent[] = "Checkin backoff";
+static const char kCheckinDelayedDueToBackoffDetails[] =
+    "Delayed for 15000 msec";
+static const char kCheckinSuccessEvent[] = "Checkin succeeded";
+static const char kCheckinSuccessDetails[] = "";
+static const char kCheckinFailureEvent[] = "Checkin failed";
+static const char kCheckinFailureDetails[] = "URL_FETCHING_FAILED. Will retry.";
+
 static const char kConnectionInitiatedEvent[] = "Connection initiated";
 static const char kConnectionInitiatedDetails[] = "www.example.com";
 static const char kConnectionDelayedDueToBackoffEvent[] = "Connection backoff";
@@ -91,6 +103,10 @@
   virtual ~GCMStatsRecorderTest();
   virtual void SetUp() OVERRIDE;
 
+  void VerifyRecordedCheckinCount(int expected_count) {
+    EXPECT_EQ(expected_count,
+              static_cast<int>(recorder_.checkin_activities().size()));
+  }
   void VerifyRecordedConnectionCount(int expected_count) {
     EXPECT_EQ(expected_count,
               static_cast<int>(recorder_.connection_activities().size()));
@@ -108,6 +124,34 @@
               static_cast<int>(recorder_.sending_activities().size()));
   }
 
+  void VerifyCheckinInitiated(const std::string& remark) {
+    VerifyCheckin(recorder_.checkin_activities(),
+                  kCheckinInitiatedEvent,
+                  kCheckinInitiatedDetails,
+                  remark);
+  }
+
+  void VerifyCheckinDelayedDueToBackoff(const std::string& remark) {
+    VerifyCheckin(recorder_.checkin_activities(),
+                  kCheckinDelayedDueToBackoffEvent,
+                  kCheckinDelayedDueToBackoffDetails,
+                  remark);
+  }
+
+  void VerifyCheckinSuccess(const std::string& remark) {
+    VerifyCheckin(recorder_.checkin_activities(),
+                  kCheckinSuccessEvent,
+                  kCheckinSuccessDetails,
+                  remark);
+  }
+
+  void VerifyCheckinFailure(const std::string& remark) {
+    VerifyCheckin(recorder_.checkin_activities(),
+                  kCheckinFailureEvent,
+                  kCheckinFailureDetails,
+                  remark);
+  }
+
   void VerifyConnectionInitiated(const std::string& remark) {
     VerifyConnection(recorder_.connection_activities(),
                      kConnectionInitiatedEvent,
@@ -191,7 +235,7 @@
                        remark);
   }
 
-  void VerifyDataMessageRecieved(const std::string& remark) {
+  void VerifyDataMessageReceived(const std::string& remark) {
     VerifyReceivingData(recorder_.receiving_activities(),
                         kDataReceivedEvent,
                         kDataReceivedDetails,
@@ -205,7 +249,7 @@
                         remark);
   }
 
-  void VerifyDataMessageRecievedNotRegistered(const std::string& remark) {
+  void VerifyDataMessageReceivedNotRegistered(const std::string& remark) {
     VerifyReceivingData(recorder_.receiving_activities(),
                         kDataReceivedNotRegisteredEvent,
                         kDataReceivedNotRegisteredDetails,
@@ -234,6 +278,15 @@
   }
 
  protected:
+  void VerifyCheckin(
+      const std::deque<GCMStatsRecorder::CheckinActivity>& queue,
+      const std::string& event,
+      const std::string& details,
+      const std::string& remark) {
+    EXPECT_EQ(event, queue.front().event) << remark;
+    EXPECT_EQ(details, queue.front().details) << remark;
+  }
+
   void VerifyConnection(
       const std::deque<GCMStatsRecorder::ConnectionActivity>& queue,
       const std::string& event,
@@ -320,6 +373,24 @@
   VerifyRecordedSendingCount(0);
 }
 
+TEST_F(GCMStatsRecorderTest, CheckinTest) {
+  recorder_.RecordCheckinInitiated(kAndroidId);
+  VerifyRecordedCheckinCount(1);
+  VerifyCheckinInitiated("1st call");
+
+  recorder_.RecordCheckinDelayedDueToBackoff(kDelay);
+  VerifyRecordedCheckinCount(2);
+  VerifyCheckinDelayedDueToBackoff("2nd call");
+
+  recorder_.RecordCheckinSuccess();
+  VerifyRecordedCheckinCount(3);
+  VerifyCheckinSuccess("3rd call");
+
+  recorder_.RecordCheckinFailure(kCheckinStatus, true);
+  VerifyRecordedCheckinCount(4);
+  VerifyCheckinFailure("4th call");
+}
+
 TEST_F(GCMStatsRecorderTest, ConnectionTest) {
   recorder_.RecordConnectionInitiated(kHost);
   VerifyRecordedConnectionCount(1);
@@ -370,20 +441,20 @@
 }
 
 TEST_F(GCMStatsRecorderTest, RecordReceivingTest) {
-  recorder_.RecordDataMessageRecieved(kAppId, kFrom, kByteSize, true,
+  recorder_.RecordDataMessageReceived(kAppId, kFrom, kByteSize, true,
                                       GCMStatsRecorder::DATA_MESSAGE);
   VerifyRecordedReceivingCount(1);
-  VerifyDataMessageRecieved("1st call");
+  VerifyDataMessageReceived("1st call");
 
-  recorder_.RecordDataMessageRecieved(kAppId, kFrom, kByteSize, true,
+  recorder_.RecordDataMessageReceived(kAppId, kFrom, kByteSize, true,
                                       GCMStatsRecorder::DELETED_MESSAGES);
   VerifyRecordedReceivingCount(2);
   VerifyDataDeletedMessage("2nd call");
 
-  recorder_.RecordDataMessageRecieved(kAppId, kFrom, kByteSize, false,
+  recorder_.RecordDataMessageReceived(kAppId, kFrom, kByteSize, false,
                                       GCMStatsRecorder::DATA_MESSAGE);
   VerifyRecordedReceivingCount(3);
-  VerifyDataMessageRecievedNotRegistered("3rd call");
+  VerifyDataMessageReceivedNotRegistered("3rd call");
 }
 
 TEST_F(GCMStatsRecorderTest, RecordSendingTest) {
diff --git a/google_apis/gcm/tools/mcs_probe.cc b/google_apis/gcm/tools/mcs_probe.cc
index af757d2..b7f984d 100644
--- a/google_apis/gcm/tools/mcs_probe.cc
+++ b/google_apis/gcm/tools/mcs_probe.cc
@@ -28,6 +28,7 @@
 #include "google_apis/gcm/engine/checkin_request.h"
 #include "google_apis/gcm/engine/connection_factory_impl.h"
 #include "google_apis/gcm/engine/gcm_store_impl.h"
+#include "google_apis/gcm/engine/gservices_settings.h"
 #include "google_apis/gcm/engine/mcs_client.h"
 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h"
 #include "net/base/host_mapping_rules.h"
@@ -433,10 +434,12 @@
       0, 0, std::string(), std::vector<std::string>(), chrome_build_proto);
 
   checkin_request_.reset(new CheckinRequest(
+      GServicesSettings::DefaultCheckinURL(),
       request_info,
       kDefaultBackoffPolicy,
       base::Bind(&MCSProbe::OnCheckInCompleted, base::Unretained(this)),
-      url_request_context_getter_.get()));
+      url_request_context_getter_.get(),
+      &recorder_));
   checkin_request_->Start();
 }
 
diff --git a/google_apis/google_apis.target.darwin-arm.mk b/google_apis/google_apis.target.darwin-arm.mk
index 70a0cd4..9c6fc87 100644
--- a/google_apis/google_apis.target.darwin-arm.mk
+++ b/google_apis/google_apis.target.darwin-arm.mk
@@ -73,7 +73,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -169,7 +168,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/google_apis/google_apis.target.darwin-x86.mk b/google_apis/google_apis.target.darwin-x86.mk
index 0862b7f..b1a4eed 100644
--- a/google_apis/google_apis.target.darwin-x86.mk
+++ b/google_apis/google_apis.target.darwin-x86.mk
@@ -75,7 +75,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -170,7 +169,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/google_apis/google_apis.target.darwin-x86_64.mk b/google_apis/google_apis.target.darwin-x86_64.mk
index 425de89..bd4231c 100644
--- a/google_apis/google_apis.target.darwin-x86_64.mk
+++ b/google_apis/google_apis.target.darwin-x86_64.mk
@@ -75,7 +75,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -172,7 +171,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/google_apis/google_apis.target.linux-arm.mk b/google_apis/google_apis.target.linux-arm.mk
index 70a0cd4..9c6fc87 100644
--- a/google_apis/google_apis.target.linux-arm.mk
+++ b/google_apis/google_apis.target.linux-arm.mk
@@ -73,7 +73,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -169,7 +168,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/google_apis/google_apis.target.linux-x86.mk b/google_apis/google_apis.target.linux-x86.mk
index 0862b7f..b1a4eed 100644
--- a/google_apis/google_apis.target.linux-x86.mk
+++ b/google_apis/google_apis.target.linux-x86.mk
@@ -75,7 +75,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -170,7 +169,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/google_apis/google_apis.target.linux-x86_64.mk b/google_apis/google_apis.target.linux-x86_64.mk
index 425de89..bd4231c 100644
--- a/google_apis/google_apis.target.linux-x86_64.mk
+++ b/google_apis/google_apis.target.linux-x86_64.mk
@@ -75,7 +75,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -172,7 +171,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_image.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_image.txt
new file mode 100644
index 0000000..154f91e
--- /dev/null
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_image.txt
@@ -0,0 +1,117 @@
+Name
+
+    CHROMIUM_image
+
+Name Strings
+
+    GL_CHROMIUM_image
+
+Version
+
+    Last Modifed Date: Apr 30, 2014
+
+Dependencies
+
+    OpenGL ES 2.0 is required.
+
+Overview
+
+    This extension allows for more efficient uploading of texture data through
+    Chromium's OpenGL ES 2.0 implementation as well as enable hardware overlay
+    support by providing ability to create buffers capable of being scanned out
+    directly by the display controller.
+
+    For security reasons Chromium accesses the GPU from a separate process. User
+    processes are not allowed to access the GPU directly. This multi-process
+    architechure has the advantage that GPU operations can be secured and
+    pipelined but it has the disadvantage that all data that is going to be
+    passed to GPU must first be made available to the separate GPU process.
+
+    This extension helps the application directly allocate and access texture
+    memory.
+
+Issues
+
+    None
+
+New Tokens
+
+    Accepted by the <pname> parameter of GetImageParameterivCHROMIUM:
+
+        IMAGE_ROWBYTES_CHROMIUM 0x78F0
+
+    Accepted by the <usage> parameter of CreateImageCHROMIUM:
+
+        IMAGE_MAP_CHROMIUM 0x78F1
+        IMAGE_SCANOUT_CHROMIUM 0x78F2
+
+New Procedures and Functions
+
+    GLuint CreateImageCHROMIUM(GLsizei width, GLsizei height,
+                               GLenum internalformat, GLenum usage)
+
+    Allocate an image with width equal to <width> and height equal
+    to <height> stored in format <internalformat>.
+
+    Returns a unique identifier for the allocated image that could be used
+    in subsequent operations.
+
+    INVALID_VALUE is generated if <width> or <height> is nonpositive.
+
+    INVALID_ENUM is generated if <usage> is not one of
+    IMAGE_MAP_CHROMIUM and IMAGE_SCANOUT_CHROMIUM.
+
+    void DestroyImageCHROMIUM(GLuint image_id)
+
+    Frees the image previously allocated by a call to CreateImageCHROMIUM.
+
+    INVALID_OPERATION is generated if <image_id> is not a valid image id.
+
+    void* MapImageCHROMIUM(GLuint image_id)
+
+    Returns a pointer to in the user memory for the application to modify
+    the image. It is illegal to call this function on an image not created
+    with IMAGE_MAP_CHROMIUM usage.
+
+    INVALID_OPERATION is generated if <image_id> is not a valid image id.
+
+    INVALID_OPERATION is generated if the image was already mapped by a previous
+    call to this method.
+
+    void UnmapImageCHROMIUM(GLuint image_id)
+
+    Removes the mapping created by a call to MapImageCHROMIUM.
+
+    Note that after calling UnmapImageCHROMIUM the application should assume
+    that the memory returned by MapImageCHROMIUM is off limits and is no longer
+    accessible by the application. Accessing it after calling
+    UnmapImageCHROMIUM will produce undefined results.
+
+    INVALID_OPERATION is generated if <image_id> is not a valid image id.
+
+    INVALID_OPERATION is generated if the image was not already mapped by a
+    previous call to MapImageCHROMIUM.
+
+    void GetImageParameterivCHROMIUM(GLuint image_id, GLenum pname,
+                                     GLint* params)
+
+    Sets <params> to the integer value of the parameter specified by <pname>
+    for the image specified by <image_id>. <params> is expected to be
+    properly allocated before calling this method.
+
+    INVALID_OPERATION is generated if <image_id> is not a valid image id.
+
+    INVALID_ENUM is generated if <pname> is not IMAGE_ROWBYTES_CHROMIUM.
+
+Errors
+
+    None.
+
+New State
+
+    None.
+
+Revision History
+
+    5/9/2013    Documented the extension
+    4/30/2014   Moved usage flag to creation function.
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_map_image.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_map_image.txt
deleted file mode 100644
index 6304fda..0000000
--- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_map_image.txt
+++ /dev/null
@@ -1,107 +0,0 @@
-Name
-
-    CHROMIUM_map_image
-
-Name Strings
-
-    GL_CHROMIUM_map_image
-
-Version
-
-    Last Modifed Date: May 9, 2013
-
-Dependencies
-
-    OpenGL ES 2.0 is required.
-
-Overview
-
-    This extension allows for more efficient uploading of texture data through
-    Chromium's OpenGL ES 2.0 implementation.
-
-    For security reasons Chromium accesses the GPU from a separate process. User
-    processes are not allowed to access the GPU directly. This multi-process
-    architechure has the advantage that GPU operations can be secured and
-    pipelined but it has the disadvantage that all data that is going to be
-    passed to GPU must first be made available to the separate GPU process.
-
-    This extension helps the application directly allocate and access texture
-    memory.
-
-Issues
-
-    None
-
-New Tokens
-
-    None
-
-New Procedures and Functions
-
-    GLuint CreateImageCHROMIUM (GLsizei width, GLsizei height,
-                                GLenum internalformat)
-
-    Allocate an image with width equal to <width> and height equal
-    to <height> stored in format <internalformat>.
-
-    Returns a unique identifier for the allocated image that could be used
-    in subsequent operations.
-
-    INVALID_VALUE is generated if <width> or <height> is nonpositive.
-
-    void DestroyImageCHROMIUM (GLuint image_id)
-
-    Frees the image previously allocated by a call to CreateImageCHROMIUM.
-
-    INVALID_OPERATION is generated if <image_id> is not a valid image id.
-
-    void* MapImageCHROMIUM (GLuint image_id, GLenum access)
-
-    Returns a pointer to in the user memory for the application to modify
-    the image. <access> parameter defines if the user will read or write the
-    pixels.
-
-    INVALID_OPERATION is generated if <image_id> is not a valid image id.
-
-    INVALID_OPERATION is generated if the image was already mapped by a previous
-    call to this method.
-
-    INVALID_ENUM is generated if <access> is not one of WRITE_ONLY, READ_ONLY
-    and READ_WRITE.
-
-    void UnmapImageCHROMIUM (GLuint image_id)
-
-    Removes the mapping created by a call to MapImageCHROMIUM.
-
-    Note that after calling UnmapImageCHROMIUM the application should assume
-    that the memory returned by MapImageCHROMIUM is off limits and is no longer
-    accessible by the application. Accessing it after calling
-    UnmapImageCHROMIUM will produce undefined results.
-
-    INVALID_OPERATION is generated if <image_id> is not a valid image id.
-
-    INVALID_OPERATION is generated if the image was not already mapped by a
-    previous call to MapImageCHROMIUM.
-
-    void GetImageParameterivCHROMIUM(GLuint image_id, GLenum pname,
-                                     GLint* params)
-
-    Sets <params> to the integer value of the parameter specified by <pname>
-    for the image specified by <image_id>. <params> is expected to be
-    properly allocated before calling this method.
-
-    INVALID_OPERATION is generated if <image_id> is not a valid image id.
-
-    INVALID_ENUM is generated if <pname> is not IMAGE_ROWBYTES_CHROMIUM.
-
-Errors
-
-    None.
-
-New State
-
-    None.
-
-Revision History
-
-    5/9/2013    Documented the extension
diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h
index 0bdf717..d78f8ef 100644
--- a/gpu/GLES2/gl2extchromium.h
+++ b/gpu/GLES2/gl2extchromium.h
@@ -94,7 +94,7 @@
 #endif
 #endif  /* GL_CHROMIUM_pixel_transfer_buffer_object */
 
-/* GL_CHROMIUM_map_image */
+/* GL_CHROMIUM_image */
 #ifndef GL_CHROMIUM_map_image
 #define GL_CHROMIUM_map_image 1
 
@@ -102,21 +102,29 @@
 #define GL_IMAGE_ROWBYTES_CHROMIUM 0x78F0
 #endif
 
-#ifndef GL_READ_WRITE
-#define GL_READ_WRITE 0x88BA
+#ifndef GL_IMAGE_MAP_CHROMIUM
+#define GL_IMAGE_MAP_CHROMIUM 0x78F1
+#endif
+
+#ifndef GL_IMAGE_SCANOUT_CHROMIUM
+#define GL_IMAGE_SCANOUT_CHROMIUM 0x78F2
 #endif
 
 #ifdef GL_GLEXT_PROTOTYPES
-GL_APICALL GLuint GL_APIENTRY glCreateImageCHROMIUM(
-    GLsizei width, GLsizei height, GLenum internalformat);
+GL_APICALL GLuint GL_APIENTRY glCreateImageCHROMIUM(GLsizei width,
+                                                    GLsizei height,
+                                                    GLenum internalformat,
+                                                    GLenum usage);
 GL_APICALL void GL_APIENTRY glDestroyImageCHROMIUM(GLuint image_id);
 GL_APICALL void GL_APIENTRY glGetImageParameterivCHROMIUM(
     GLuint image_id, GLenum pname, GLint* params);
-GL_APICALL void* GL_APIENTRY glMapImageCHROMIUM(GLuint image_id, GLenum access);
+GL_APICALL void* GL_APIENTRY glMapImageCHROMIUM(GLuint image_id);
 GL_APICALL void GL_APIENTRY glUnmapImageCHROMIUM(GLuint image_id);
 #endif
-typedef GLuint (GL_APIENTRYP PFNGLCREATEIMAGECHROMIUMPROC) (
-    GLsizei width, GLsizei height, GLenum internalformat);
+typedef GLuint(GL_APIENTRYP PFNGLCREATEIMAGECHROMIUMPROC)(
+    GLsizei width,
+    GLsizei height,
+    GLenum internalformat);
 typedef void (
     GL_APIENTRYP PFNGLDESTROYIMAGECHROMIUMPROC) (GLuint image_id);
 typedef void (
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 7105edf..ca03986 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -78,8 +78,7 @@
   {'name': 'polygon_offset_fill'},
   {'name': 'sample_alpha_to_coverage'},
   {'name': 'sample_coverage'},
-  {'name': 'scissor_test',
-   'state_flag': 'framebuffer_state_.clear_state_dirty'},
+  {'name': 'scissor_test'},
   {'name': 'stencil_test',
    'state_flag': 'framebuffer_state_.clear_state_dirty'},
 ]
@@ -109,10 +108,30 @@
     'func': 'ColorMask',
     'enum': 'GL_COLOR_WRITEMASK',
     'states': [
-      {'name': 'color_mask_red', 'type': 'GLboolean', 'default': 'true'},
-      {'name': 'color_mask_green', 'type': 'GLboolean', 'default': 'true'},
-      {'name': 'color_mask_blue', 'type': 'GLboolean', 'default': 'true'},
-      {'name': 'color_mask_alpha', 'type': 'GLboolean', 'default': 'true'},
+      {
+        'name': 'color_mask_red',
+        'type': 'GLboolean',
+        'default': 'true',
+        'cached': True
+      },
+      {
+        'name': 'color_mask_green',
+        'type': 'GLboolean',
+        'default': 'true',
+        'cached': True
+      },
+      {
+        'name': 'color_mask_blue',
+        'type': 'GLboolean',
+        'default': 'true',
+        'cached': True
+      },
+      {
+        'name': 'color_mask_alpha',
+        'type': 'GLboolean',
+        'default': 'true',
+        'cached': True
+      },
     ],
     'state_flag': 'framebuffer_state_.clear_state_dirty',
   },
@@ -262,12 +281,14 @@
         'type': 'GLuint',
         'enum': 'GL_STENCIL_WRITEMASK',
         'default': '0xFFFFFFFFU',
+        'cached': True,
       },
       {
         'name': 'stencil_back_writemask',
         'type': 'GLuint',
         'enum': 'GL_STENCIL_BACK_WRITEMASK',
         'default': '0xFFFFFFFFU',
+        'cached': True,
       },
     ],
   },
@@ -411,7 +432,12 @@
     'func': 'DepthMask',
     'enum': 'GL_DEPTH_WRITEMASK',
     'states': [
-      {'name': 'depth_mask', 'type': 'GLboolean', 'default': 'true'},
+      {
+        'name': 'depth_mask',
+        'type': 'GLboolean',
+        'default': 'true',
+        'cached': True
+      },
     ],
     'state_flag': 'framebuffer_state_.clear_state_dirty',
   },
@@ -1379,7 +1405,8 @@
   },
   'CreateImageCHROMIUM': {
     'type': 'Manual',
-    'cmd_args': 'GLsizei width, GLsizei height, GLenum internalformat',
+    'cmd_args':
+        'GLsizei width, GLsizei height, GLenum internalformat, GLenum usage',
     'result': ['GLuint'],
     'client_test': False,
     'gen_cmd': False,
@@ -1629,30 +1656,30 @@
     'type': 'Custom',
     'immediate': False,
     'cmd_args':
-        'GLidProgram program, GLuint index, uint32 name_bucket_id, '
+        'GLidProgram program, GLuint index, uint32_t name_bucket_id, '
         'void* result',
     'result': [
-      'int32 success',
-      'int32 size',
-      'uint32 type',
+      'int32_t success',
+      'int32_t size',
+      'uint32_t type',
     ],
   },
   'GetActiveUniform': {
     'type': 'Custom',
     'immediate': False,
     'cmd_args':
-        'GLidProgram program, GLuint index, uint32 name_bucket_id, '
+        'GLidProgram program, GLuint index, uint32_t name_bucket_id, '
         'void* result',
     'result': [
-      'int32 success',
-      'int32 size',
-      'uint32 type',
+      'int32_t success',
+      'int32_t size',
+      'uint32_t type',
     ],
   },
   'GetAttachedShaders': {
     'type': 'Custom',
     'immediate': False,
-    'cmd_args': 'GLidProgram program, void* result, uint32 result_size',
+    'cmd_args': 'GLidProgram program, void* result, uint32_t result_size',
     'result': ['SizedResult<GLuint>'],
   },
   'GetAttribLocation': {
@@ -1735,11 +1762,11 @@
     'extension': True,
     'chromium': True,
     'client_test': False,
-    'cmd_args': 'GLidProgram program, uint32 bucket_id',
+    'cmd_args': 'GLidProgram program, uint32_t bucket_id',
     'result': [
-      'uint32 link_status',
-      'uint32 num_attribs',
-      'uint32 num_uniforms',
+      'uint32_t link_status',
+      'uint32_t num_attribs',
+      'uint32_t num_uniforms',
     ],
   },
   'GetProgramInfoLog': {
@@ -1770,10 +1797,10 @@
       'GLenumShaderType shadertype, GLenumShaderPrecision precisiontype, '
       'void* result',
     'result': [
-      'int32 success',
-      'int32 min_range',
-      'int32 max_range',
-      'int32 precision',
+      'int32_t success',
+      'int32_t min_range',
+      'int32_t max_range',
+      'int32_t precision',
     ],
   },
   'GetShaderSource': {
@@ -1786,7 +1813,7 @@
   'GetString': {
     'type': 'Custom',
     'client_test': False,
-    'cmd_args': 'GLenumStringType name, uint32 bucket_id',
+    'cmd_args': 'GLenumStringType name, uint32_t bucket_id',
   },
   'GetTexParameterfv': {
     'type': 'GETn',
@@ -1971,10 +1998,10 @@
     'cmd_args':
         'GLint x, GLint y, GLsizei width, GLsizei height, '
         'GLenumReadPixelFormat format, GLenumReadPixelType type, '
-        'uint32 pixels_shm_id, uint32 pixels_shm_offset, '
-        'uint32 result_shm_id, uint32 result_shm_offset, '
+        'uint32_t pixels_shm_id, uint32_t pixels_shm_offset, '
+        'uint32_t result_shm_id, uint32_t result_shm_offset, '
         'GLboolean async',
-    'result': ['uint32'],
+    'result': ['uint32_t'],
     'defer_reads': True,
   },
   'RegisterSharedIdsCHROMIUM': {
@@ -2229,7 +2256,7 @@
     'type': 'Custom',
     'impl_func': False,
     'immediate': False,
-    'cmd_args': 'uint32 bucket_id',
+    'cmd_args': 'uint32_t bucket_id',
     'extension': True,
     'chromium': True,
   },
@@ -2238,7 +2265,7 @@
     'impl_func': False,
     'immediate': False,
     'client_test': False,
-    'cmd_args': 'uint32 bucket_id',
+    'cmd_args': 'uint32_t bucket_id',
     'extension': True,
     'chromium': True,
   },
@@ -2470,7 +2497,7 @@
         'GLintTextureBorder border, '
         'GLenumTextureFormat format, GLenumPixelType type, '
         'const void* pixels, '
-        'uint32 async_upload_token, '
+        'uint32_t async_upload_token, '
         'void* sync_data',
     'extension': True,
     'chromium': True,
@@ -2484,7 +2511,7 @@
         'GLsizei width, GLsizei height, '
         'GLenumTextureFormat format, GLenumPixelType type, '
         'const void* data, '
-        'uint32 async_upload_token, '
+        'uint32_t async_upload_token, '
         'void* sync_data',
     'extension': True,
     'chromium': True,
@@ -2596,6 +2623,11 @@
   words = SplitWords(input_string)
   return Lower(words)
 
+def CachedStateName(item):
+  if item.get('cached', False):
+    return 'cached_' + item['name']
+  return item['name']
+
 
 class CWriter(object):
   """Writes to a file formatting it for Google's style guidelines."""
@@ -2772,7 +2804,7 @@
     for value, arg in enumerate(args):
       file.Write(",\n      static_cast<%s>(%d)" % (arg.type, value + 11))
     file.Write(");\n")
-    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
+    file.Write("  EXPECT_EQ(static_cast<uint32_t>(cmds::%s::kCmdId),\n" %
                func.name)
     file.Write("            cmd.header.command);\n")
     func.type_handler.WriteCmdSizeTest(func, file)
@@ -2816,7 +2848,7 @@
     file.Write(
         "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
     file.Write(
-        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
+        "    uint32_t immediate_data_size, const gles2::cmds::%s& c) {\n" %
         func.name)
     self.WriteHandlerDeferReadWrite(func, file);
     if len(func.GetOriginalArgs()) > 0:
@@ -2837,7 +2869,7 @@
     file.Write(
         "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
     file.Write(
-        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
+        "    uint32_t immediate_data_size, const gles2::cmds::%s& c) {\n" %
         func.name)
     self.WriteHandlerDeferReadWrite(func, file);
     last_arg = func.GetLastOriginalArg()
@@ -2857,7 +2889,7 @@
     file.Write(
         "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
     file.Write(
-        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
+        "    uint32_t immediate_data_size, const gles2::cmds::%s& c) {\n" %
         func.name)
     self.WriteHandlerDeferReadWrite(func, file);
     last_arg = func.GetLastOriginalArg()
@@ -2953,8 +2985,32 @@
 
   def WriteServiceUnitTest(self, func, file):
     """Writes the service unit test for a command."""
-    valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+
+    if func.name == 'Enable':
+      valid_test = """
+TEST_P(%(test_name)s, %(name)sValidArgs) {
+  SetupExpectationsForEnableDisable(%(gl_args)s, true);
+  SpecializedSetup<cmds::%(name)s, 0>(true);
+  cmds::%(name)s cmd;
+  cmd.Init(%(args)s);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+"""
+    elif func.name == 'Disable':
+      valid_test = """
+TEST_P(%(test_name)s, %(name)sValidArgs) {
+  SetupExpectationsForEnableDisable(%(gl_args)s, false);
+  SpecializedSetup<cmds::%(name)s, 0>(true);
+  cmds::%(name)s cmd;
+  cmd.Init(%(args)s);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+"""
+    else:
+      valid_test = """
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
   SpecializedSetup<cmds::%(name)s, 0>(true);
   cmds::%(name)s cmd;
@@ -2966,7 +3022,7 @@
     self.WriteValidUnitTest(func, file, valid_test)
 
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
   SpecializedSetup<cmds::%(name)s, 0>(false);
   cmds::%(name)s cmd;
@@ -3147,8 +3203,8 @@
 
   def WriteImmediateCmdComputeSize(self, func, file):
     """Writes the size computation code for the immediate version of a cmd."""
-    file.Write("  static uint32 ComputeSize(uint32 size_in_bytes) {\n")
-    file.Write("    return static_cast<uint32>(\n")
+    file.Write("  static uint32_t ComputeSize(uint32_t size_in_bytes) {\n")
+    file.Write("    return static_cast<uint32_t>(\n")
     file.Write("        sizeof(ValueType) +  // NOLINT\n")
     file.Write("        RoundSizeToMultipleOfEntries(size_in_bytes));\n")
     file.Write("  }\n")
@@ -3156,7 +3212,7 @@
 
   def WriteImmediateCmdSetHeader(self, func, file):
     """Writes the SetHeader function for the immediate version of a cmd."""
-    file.Write("  void SetHeader(uint32 size_in_bytes) {\n")
+    file.Write("  void SetHeader(uint32_t size_in_bytes) {\n")
     file.Write("    header.SetCmdByTotalSize<ValueType>(size_in_bytes);\n")
     file.Write("  }\n")
     file.Write("\n")
@@ -3188,7 +3244,7 @@
   def WriteImmediateCmdHelper(self, func, file):
     """Writes the cmd helper definition for the immediate version of a cmd."""
     code = """  void %(name)s(%(typed_args)s) {
-    const uint32 s = 0;  // TODO(gman): compute correct size
+    const uint32_t s = 0;  // TODO(gman): compute correct size
     gles2::cmds::%(name)s* c =
         GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(s);
     if (c) {
@@ -3238,6 +3294,10 @@
     if 'state_flag' in state:
       file.Write("    %s = true;\n" % state['state_flag'])
     if not func.GetInfo("no_gl"):
+      for ndx,item in enumerate(states):
+        if item.get('cached', False):
+          file.Write("    state_.%s = %s;\n" %
+                     (CachedStateName(item), args[ndx].name))
       file.Write("    %s(%s);\n" %
                  (func.GetGLFunctionName(), func.MakeOriginalArgString("")))
     file.Write("  }\n")
@@ -3252,7 +3312,7 @@
       if 'range_checks' in item:
         for check_ndx, range_check in enumerate(item['range_checks']):
           valid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidValue%(ndx)d_%(check_ndx)d) {
+TEST_P(%(test_name)s, %(name)sInvalidValue%(ndx)d_%(check_ndx)d) {
   SpecializedSetup<cmds::%(name)s, 0>(false);
   cmds::%(name)s cmd;
   cmd.Init(%(args)s);
@@ -3429,7 +3489,8 @@
 
   def WriteImmediateCmdGetTotalSize(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("    uint32 total_size = 0;  // TODO(gman): get correct size.\n")
+    file.Write(
+        "    uint32_t total_size = 0;  // TODO(gman): get correct size.\n")
 
   def WriteImmediateCmdInit(self, func, file):
     """Overrriden from TypeHandler."""
@@ -3490,7 +3551,7 @@
     file.Write(
         "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
     file.Write(
-        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
+        "    uint32_t immediate_data_size, const gles2::cmds::%s& c) {\n" %
         func.name)
     file.Write("  // TODO: for now this is a no-op\n")
     file.Write(
@@ -3643,16 +3704,16 @@
     if name.endswith("Immediate"):
       name = name[0:-9]
     if name == 'BufferData' or name == 'BufferSubData':
-      file.Write("  uint32 data_size = size;\n")
+      file.Write("  uint32_t data_size = size;\n")
     elif (name == 'CompressedTexImage2D' or
           name == 'CompressedTexSubImage2D'):
-      file.Write("  uint32 data_size = imageSize;\n")
+      file.Write("  uint32_t data_size = imageSize;\n")
     elif (name == 'CompressedTexSubImage2DBucket'):
       file.Write("  Bucket* bucket = GetBucket(c.bucket_id);\n")
-      file.Write("  uint32 data_size = bucket->size();\n")
+      file.Write("  uint32_t data_size = bucket->size();\n")
       file.Write("  GLsizei imageSize = data_size;\n")
     elif name == 'TexImage2D' or name == 'TexSubImage2D':
-      code = """  uint32 data_size;
+      code = """  uint32_t data_size;
   if (!GLES2Util::ComputeImageDataSize(
       width, height, format, type, unpack_alignment_, &data_size)) {
     return error::kOutOfBounds;
@@ -3660,7 +3721,8 @@
 """
       file.Write(code)
     else:
-      file.Write("// uint32 data_size = 0;  // TODO(gman): get correct size!\n")
+      file.Write(
+          "// uint32_t data_size = 0;  // TODO(gman): get correct size!\n")
 
   def WriteImmediateCmdGetTotalSize(self, func, file):
     """Overrriden from TypeHandler."""
@@ -3724,7 +3786,7 @@
 
     if len(func.GetOriginalArgs()) == 1:
       valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
   SpecializedSetup<cmds::%(name)s, 0>(true);
   cmds::%(name)s cmd;
@@ -3735,7 +3797,7 @@
 """
       if func.GetInfo("gen_func"):
           valid_test += """
-TEST_F(%(test_name)s, %(name)sValidArgsNewId) {
+TEST_P(%(test_name)s, %(name)sValidArgsNewId) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(kNewServiceId));
   EXPECT_CALL(*gl_, %(gl_gen_func_name)s(1, _))
      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
@@ -3753,7 +3815,7 @@
       })
     else:
       valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
   SpecializedSetup<cmds::%(name)s, 0>(true);
   cmds::%(name)s cmd;
@@ -3764,7 +3826,7 @@
 """
       if func.GetInfo("gen_func"):
           valid_test += """
-TEST_F(%(test_name)s, %(name)sValidArgsNewId) {
+TEST_P(%(test_name)s, %(name)sValidArgsNewId) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(first_gl_arg)s, kNewServiceId));
   EXPECT_CALL(*gl_, %(gl_gen_func_name)s(1, _))
      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
@@ -3784,7 +3846,7 @@
       })
 
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
   SpecializedSetup<cmds::%(name)s, 0>(false);
   cmds::%(name)s cmd;
@@ -3886,7 +3948,7 @@
 
   def WriteGetDataSizeCode(self, func, file):
     """Overrriden from TypeHandler."""
-    code = """  uint32 data_size;
+    code = """  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3971,7 +4033,7 @@
   def WriteServiceUnitTest(self, func, file):
     """Overrriden from TypeHandler."""
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
   GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
@@ -3987,7 +4049,7 @@
         'resource_name': func.GetInfo('resource_type'),
       })
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(_, _)).Times(0);
   GetSharedMemoryAs<GLuint*>()[0] = client_%(resource_name)s_id_;
   SpecializedSetup<cmds::%(name)s, 0>(false);
@@ -4003,7 +4065,7 @@
   def WriteImmediateServiceUnitTest(self, func, file):
     """Overrriden from TypeHandler."""
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
   cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>();
@@ -4020,7 +4082,7 @@
         'resource_name': func.GetInfo('resource_type'),
       })
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(_, _)).Times(0);
   cmds::%(name)s* cmd = GetImmediateAs<cmds::%(name)s>();
   SpecializedSetup<cmds::%(name)s, 0>(false);
@@ -4035,13 +4097,13 @@
 
   def WriteImmediateCmdComputeSize(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("  static uint32 ComputeDataSize(GLsizei n) {\n")
+    file.Write("  static uint32_t ComputeDataSize(GLsizei n) {\n")
     file.Write(
-        "    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT\n")
+        "    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT\n")
     file.Write("  }\n")
     file.Write("\n")
-    file.Write("  static uint32 ComputeSize(GLsizei n) {\n")
-    file.Write("    return static_cast<uint32>(\n")
+    file.Write("  static uint32_t ComputeSize(GLsizei n) {\n")
+    file.Write("    return static_cast<uint32_t>(\n")
     file.Write("        sizeof(ValueType) + ComputeDataSize(n));  // NOLINT\n")
     file.Write("  }\n")
     file.Write("\n")
@@ -4077,7 +4139,7 @@
                 last_arg.type, last_arg.name))
     file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
                (copy_args, last_arg.name))
-    file.Write("    const uint32 size = ComputeSize(_n);\n")
+    file.Write("    const uint32_t size = ComputeSize(_n);\n")
     file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
                "cmd, size);\n")
     file.Write("  }\n")
@@ -4086,7 +4148,7 @@
   def WriteImmediateCmdHelper(self, func, file):
     """Overrriden from TypeHandler."""
     code = """  void %(name)s(%(typed_args)s) {
-    const uint32 size = gles2::cmds::%(name)s::ComputeSize(n);
+    const uint32_t size = gles2::cmds::%(name)s::ComputeSize(n);
     gles2::cmds::%(name)s* c =
         GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
     if (c) {
@@ -4109,7 +4171,7 @@
                (func.name, func.name))
     file.Write("  void* next_cmd = cmd.Set(\n")
     file.Write("      &cmd, static_cast<GLsizei>(arraysize(ids)), ids);\n")
-    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
+    file.Write("  EXPECT_EQ(static_cast<uint32_t>(cmds::%s::kCmdId),\n" %
                func.name)
     file.Write("            cmd.header.command);\n")
     file.Write("  EXPECT_EQ(sizeof(cmd) +\n")
@@ -4132,12 +4194,12 @@
 
   def InitFunction(self, func):
     """Overrriden from TypeHandler."""
-    func.AddCmdArg(Argument("client_id", 'uint32'))
+    func.AddCmdArg(Argument("client_id", 'uint32_t'))
 
   def WriteServiceUnitTest(self, func, file):
     """Overrriden from TypeHandler."""
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s))
       .WillOnce(Return(kNewServiceId));
   SpecializedSetup<cmds::%(name)s, 0>(true);
@@ -4156,7 +4218,7 @@
           'resource_type': func.name[6:],
         })
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
   SpecializedSetup<cmds::%(name)s, 0>(false);
   cmds::%(name)s cmd;
@@ -4170,7 +4232,7 @@
 
   def WriteHandlerImplementation (self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("  uint32 client_id = c.client_id;\n")
+    file.Write("  uint32_t client_id = c.client_id;\n")
     file.Write("  if (!%sHelper(%s)) {\n" %
                (func.name, func.MakeCmdArgString("")))
     file.Write("    return error::kInvalidArguments;\n")
@@ -4236,7 +4298,7 @@
 
   def WriteGetDataSizeCode(self, func, file):
     """Overrriden from TypeHandler."""
-    code = """  uint32 data_size;
+    code = """  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -4268,7 +4330,7 @@
   def WriteServiceUnitTest(self, func, file):
     """Overrriden from TypeHandler."""
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   EXPECT_CALL(
       *gl_,
       %(gl_func_name)s(1, Pointee(kService%(upper_resource_name)sId)))
@@ -4288,7 +4350,7 @@
           'upper_resource_name': func.GetInfo('resource_type'),
         })
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs) {
   GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
   SpecializedSetup<cmds::%(name)s, 0>(false);
   cmds::%(name)s cmd;
@@ -4301,7 +4363,7 @@
   def WriteImmediateServiceUnitTest(self, func, file):
     """Overrriden from TypeHandler."""
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   EXPECT_CALL(
       *gl_,
       %(gl_func_name)s(1, Pointee(kService%(upper_resource_name)sId)))
@@ -4321,7 +4383,7 @@
           'upper_resource_name': func.GetInfo('resource_type'),
         })
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs) {
   cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
   SpecializedSetup<cmds::%(name)s, 0>(false);
   GLuint temp = kInvalidClientId;
@@ -4383,13 +4445,13 @@
 
   def WriteImmediateCmdComputeSize(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("  static uint32 ComputeDataSize(GLsizei n) {\n")
+    file.Write("  static uint32_t ComputeDataSize(GLsizei n) {\n")
     file.Write(
-        "    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT\n")
+        "    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT\n")
     file.Write("  }\n")
     file.Write("\n")
-    file.Write("  static uint32 ComputeSize(GLsizei n) {\n")
-    file.Write("    return static_cast<uint32>(\n")
+    file.Write("  static uint32_t ComputeSize(GLsizei n) {\n")
+    file.Write("    return static_cast<uint32_t>(\n")
     file.Write("        sizeof(ValueType) + ComputeDataSize(n));  // NOLINT\n")
     file.Write("  }\n")
     file.Write("\n")
@@ -4425,7 +4487,7 @@
                 last_arg.type, last_arg.name))
     file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
                (copy_args, last_arg.name))
-    file.Write("    const uint32 size = ComputeSize(_n);\n")
+    file.Write("    const uint32_t size = ComputeSize(_n);\n")
     file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
                "cmd, size);\n")
     file.Write("  }\n")
@@ -4434,7 +4496,7 @@
   def WriteImmediateCmdHelper(self, func, file):
     """Overrriden from TypeHandler."""
     code = """  void %(name)s(%(typed_args)s) {
-    const uint32 size = gles2::cmds::%(name)s::ComputeSize(n);
+    const uint32_t size = gles2::cmds::%(name)s::ComputeSize(n);
     gles2::cmds::%(name)s* c =
         GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
     if (c) {
@@ -4457,7 +4519,7 @@
                (func.name, func.name))
     file.Write("  void* next_cmd = cmd.Set(\n")
     file.Write("      &cmd, static_cast<GLsizei>(arraysize(ids)), ids);\n")
-    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
+    file.Write("  EXPECT_EQ(static_cast<uint32_t>(cmds::%s::kCmdId),\n" %
                func.name)
     file.Write("            cmd.header.command);\n")
     file.Write("  EXPECT_EQ(sizeof(cmd) +\n")
@@ -4487,7 +4549,7 @@
     file.Write(
         "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
     file.Write(
-        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
+        "    uint32_t immediate_data_size, const gles2::cmds::%s& c) {\n" %
         func.name)
     last_arg = func.GetLastOriginalArg()
 
@@ -4567,7 +4629,7 @@
   WaitForCmd();
   result->CopyResult(params);
   GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
       GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
     }
   });
@@ -4617,7 +4679,7 @@
   def WriteServiceUnitTest(self, func, file):
     """Overrriden from TypeHandler."""
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
@@ -4654,7 +4716,7 @@
       })
 
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
   SpecializedSetup<cmds::%(name)s, 0>(false);
   cmds::%(name)s::Result* result =
@@ -4686,7 +4748,7 @@
       expected_call = ("EXPECT_CALL(*gl_, %%(gl_func_name)s(%s));" %
           ", ".join(gl_arg_strings))
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   SpecializedSetup<cmds::%(name)s, 0>(true);
   cmds::%(name)s cmd;
   cmd.Init(%(args)s);
@@ -4704,7 +4766,7 @@
     self.WriteValidUnitTest(func, file, valid_test, extra)
 
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
   SpecializedSetup<cmds::%(name)s, 0>(false);
   cmds::%(name)s cmd;
@@ -4718,7 +4780,7 @@
   def WriteImmediateServiceUnitTest(self, func, file):
     """Writes the service unit test for a command."""
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
   SpecializedSetup<cmds::%(name)s, 0>(true);
   %(data_type)s temp[%(data_count)s] = { %(data_value)s, };
@@ -4748,7 +4810,7 @@
     self.WriteValidUnitTest(func, file, valid_test, extra)
 
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
   cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_any_args)s, _)).Times(0);
   SpecializedSetup<cmds::%(name)s, 0>(false);
@@ -4762,7 +4824,7 @@
 
   def WriteGetDataSizeCode(self, func, file):
     """Overrriden from TypeHandler."""
-    code = """  uint32 data_size;
+    code = """  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(%s), %d, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -4834,14 +4896,14 @@
 
   def WriteImmediateCmdComputeSize(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("  static uint32 ComputeDataSize() {\n")
-    file.Write("    return static_cast<uint32>(\n")
+    file.Write("  static uint32_t ComputeDataSize() {\n")
+    file.Write("    return static_cast<uint32_t>(\n")
     file.Write("        sizeof(%s) * %d);  // NOLINT\n" %
                (func.info.data_type, func.info.count))
     file.Write("  }\n")
     file.Write("\n")
-    file.Write("  static uint32 ComputeSize() {\n")
-    file.Write("    return static_cast<uint32>(\n")
+    file.Write("  static uint32_t ComputeSize() {\n")
+    file.Write("    return static_cast<uint32_t>(\n")
     file.Write(
         "        sizeof(ValueType) + ComputeDataSize());  // NOLINT\n")
     file.Write("  }\n")
@@ -4879,7 +4941,7 @@
                 last_arg.type, last_arg.name))
     file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
                (copy_args, last_arg.name))
-    file.Write("    const uint32 size = ComputeSize();\n")
+    file.Write("    const uint32_t size = ComputeSize();\n")
     file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
                "cmd, size);\n")
     file.Write("  }\n")
@@ -4888,7 +4950,7 @@
   def WriteImmediateCmdHelper(self, func, file):
     """Overrriden from TypeHandler."""
     code = """  void %(name)s(%(typed_args)s) {
-    const uint32 size = gles2::cmds::%(name)s::ComputeSize();
+    const uint32_t size = gles2::cmds::%(name)s::ComputeSize();
     gles2::cmds::%(name)s* c =
         GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
     if (c) {
@@ -4921,7 +4983,7 @@
       file.Write(",\n      static_cast<%s>(%d)" % (arg.type, value + 11))
     file.Write(",\n      data);\n")
     args = func.GetCmdArgs()
-    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n"
+    file.Write("  EXPECT_EQ(static_cast<uint32_t>(cmds::%s::kCmdId),\n"
                % func.name)
     file.Write("            cmd.header.command);\n")
     file.Write("  EXPECT_EQ(sizeof(cmd) +\n")
@@ -4949,7 +5011,7 @@
     TypeHandler.WriteServiceUnitTest(self, func, file)
 
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgsCountTooLarge) {
+TEST_P(%(test_name)s, %(name)sValidArgsCountTooLarge) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
   SpecializedSetup<cmds::%(name)s, 0>(true);
   cmds::%(name)s cmd;
@@ -4984,7 +5046,7 @@
   def WriteImmediateServiceUnitTest(self, func, file):
     """Overridden from TypeHandler."""
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
   EXPECT_CALL(
       *gl_,
@@ -5015,7 +5077,7 @@
     self.WriteValidUnitTest(func, file, valid_test, extra)
 
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
   cmds::%(name)s& cmd = *GetImmediateAs<cmds::%(name)s>();
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_any_args)s, _)).Times(0);
   SpecializedSetup<cmds::%(name)s, 0>(false);
@@ -5029,7 +5091,7 @@
 
   def WriteGetDataSizeCode(self, func, file):
     """Overrriden from TypeHandler."""
-    code = """  uint32 data_size;
+    code = """  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(%s), %d, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -5107,14 +5169,14 @@
 
   def WriteImmediateCmdComputeSize(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("  static uint32 ComputeDataSize(GLsizei count) {\n")
-    file.Write("    return static_cast<uint32>(\n")
+    file.Write("  static uint32_t ComputeDataSize(GLsizei count) {\n")
+    file.Write("    return static_cast<uint32_t>(\n")
     file.Write("        sizeof(%s) * %d * count);  // NOLINT\n" %
                (func.info.data_type, func.info.count))
     file.Write("  }\n")
     file.Write("\n")
-    file.Write("  static uint32 ComputeSize(GLsizei count) {\n")
-    file.Write("    return static_cast<uint32>(\n")
+    file.Write("  static uint32_t ComputeSize(GLsizei count) {\n")
+    file.Write("    return static_cast<uint32_t>(\n")
     file.Write(
         "        sizeof(ValueType) + ComputeDataSize(count));  // NOLINT\n")
     file.Write("  }\n")
@@ -5152,7 +5214,7 @@
                 last_arg.type, last_arg.name))
     file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" %
                (copy_args, last_arg.name))
-    file.Write("    const uint32 size = ComputeSize(_count);\n")
+    file.Write("    const uint32_t size = ComputeSize(_count);\n")
     file.Write("    return NextImmediateCmdAddressTotalSize<ValueType>("
                "cmd, size);\n")
     file.Write("  }\n")
@@ -5161,7 +5223,7 @@
   def WriteImmediateCmdHelper(self, func, file):
     """Overrriden from TypeHandler."""
     code = """  void %(name)s(%(typed_args)s) {
-    const uint32 size = gles2::cmds::%(name)s::ComputeSize(count);
+    const uint32_t size = gles2::cmds::%(name)s::ComputeSize(count);
     gles2::cmds::%(name)s* c =
         GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size);
     if (c) {
@@ -5201,7 +5263,7 @@
     for value, arg in enumerate(args):
       file.Write(",\n      static_cast<%s>(%d)" % (arg.type, value + 1))
     file.Write(",\n      data);\n")
-    file.Write("  EXPECT_EQ(static_cast<uint32>(cmds::%s::kCmdId),\n" %
+    file.Write("  EXPECT_EQ(static_cast<uint32_t>(cmds::%s::kCmdId),\n" %
                func.name)
     file.Write("            cmd.header.command);\n")
     file.Write("  EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);\n")
@@ -5245,7 +5307,7 @@
   def WriteServiceUnitTest(self, func, file):
     """Overrriden from TypeHandler."""
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   EXPECT_CALL(*gl_, %(name)sv(%(local_args)s));
   SpecializedSetup<cmds::%(name)s, 0>(true);
   cmds::%(name)s cmd;
@@ -5263,7 +5325,7 @@
       })
 
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
   EXPECT_CALL(*gl_, %(name)sv(_, _, _).Times(0);
   SpecializedSetup<cmds::%(name)s, 0>(false);
   cmds::%(name)s cmd;
@@ -5285,15 +5347,15 @@
 
   def WriteImmediateCmdComputeSize(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("  static uint32 ComputeSize(uint32 data_size) {\n")
-    file.Write("    return static_cast<uint32>(\n")
+    file.Write("  static uint32_t ComputeSize(uint32_t data_size) {\n")
+    file.Write("    return static_cast<uint32_t>(\n")
     file.Write("        sizeof(ValueType) + data_size);  // NOLINT\n")
     file.Write("  }\n")
 
   def WriteImmediateCmdSetHeader(self, func, file):
     """Overrriden from TypeHandler."""
     code = """
-  void SetHeader(uint32 data_size) {
+  void SetHeader(uint32_t data_size) {
     header.SetCmdBySize<ValueType>(data_size);
   }
 """
@@ -5307,7 +5369,7 @@
     for arg in args:
       set_code.append("    %s = _%s;" % (arg.name, arg.name))
     code = """
-  void Init(%(typed_args)s, uint32 _data_size) {
+  void Init(%(typed_args)s, uint32_t _data_size) {
     SetHeader(_data_size);
 %(set_code)s
     memcpy(ImmediateDataAddress(this), _%(last_arg)s, _data_size);
@@ -5323,7 +5385,7 @@
   def WriteImmediateCmdSet(self, func, file):
     """Overrriden from TypeHandler."""
     last_arg = func.GetLastOriginalArg()
-    file.Write("  void* Set(void* cmd%s, uint32 _data_size) {\n" %
+    file.Write("  void* Set(void* cmd%s, uint32_t _data_size) {\n" %
                func.MakeTypedOriginalArgString("_", True))
     file.Write("    static_cast<ValueType*>(cmd)->Init(%s, _data_size);\n" %
                func.MakeOriginalArgString("_"))
@@ -5335,7 +5397,7 @@
   def WriteImmediateCmdHelper(self, func, file):
     """Overrriden from TypeHandler."""
     code = """  void %(name)s(%(typed_args)s) {
-    const uint32 data_size = strlen(name);
+    const uint32_t data_size = strlen(name);
     gles2::cmds::%(name)s* c =
         GetImmediateCmdSpace<gles2::cmds::%(name)s>(data_size);
     if (c) {
@@ -5370,7 +5432,7 @@
 %(init_code)s
       test_str,
       strlen(test_str));
-  EXPECT_EQ(static_cast<uint32>(cmds::%(func_name)s::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::%(func_name)s::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) +
             RoundSizeToMultipleOfEntries(strlen(test_str)),
@@ -5379,7 +5441,7 @@
             reinterpret_cast<char*>(&cmd) + sizeof(cmd) +
                 RoundSizeToMultipleOfEntries(strlen(test_str)));
 %(check_code)s
-  EXPECT_EQ(static_cast<uint32>(strlen(test_str)), cmd.data_size);
+  EXPECT_EQ(static_cast<uint32_t>(strlen(test_str)), cmd.data_size);
   EXPECT_EQ(0, memcmp(test_str, ImmediateDataAddress(&cmd), strlen(test_str)));
   CheckBytesWritten(
       next_cmd,
@@ -5417,7 +5479,7 @@
   def WriteServiceImplementation(self, func, file):
     """Overrriden from TypeHandler."""
     file.Write("""error::Error GLES2DecoderImpl::Handle%(name)s(
-  uint32 immediate_data_size, const gles2::cmds::%(name)s& c) {
+  uint32_t immediate_data_size, const gles2::cmds::%(name)s& c) {
   GLuint bucket_id = static_cast<GLuint>(c.%(bucket_id)s);
   Bucket* bucket = GetBucket(bucket_id);
   if (!bucket || bucket->size() == 0) {
@@ -5446,15 +5508,15 @@
 
   def InitFunction(self, func):
     """Overrriden from TypeHandler."""
-    func.AddCmdArg(Argument("result_shm_id", 'uint32'))
-    func.AddCmdArg(Argument("result_shm_offset", 'uint32'))
+    func.AddCmdArg(Argument("result_shm_id", 'uint32_t'))
+    func.AddCmdArg(Argument("result_shm_offset", 'uint32_t'))
     if func.GetInfo('result') == None:
-      func.AddInfo('result', ['uint32'])
+      func.AddInfo('result', ['uint32_t'])
 
   def WriteServiceUnitTest(self, func, file):
     """Overrriden from TypeHandler."""
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));
   SpecializedSetup<cmds::%(name)s, 0>(true);
   cmds::%(name)s cmd;
@@ -5471,7 +5533,7 @@
         })
 
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
+TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
   SpecializedSetup<cmds::%(name)s, 0>(false);
   cmds::%(name)s cmd;
@@ -5484,7 +5546,7 @@
         })
 
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) {
+TEST_P(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) {
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)).Times(0);
   SpecializedSetup<cmds::%(name)s, 0>(false);
   cmds::%(name)s cmd;
@@ -5503,7 +5565,7 @@
     file.Write(
         "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name)
     file.Write(
-        "    uint32 immediate_data_size, const gles2::cmds::%s& c) {\n" %
+        "    uint32_t immediate_data_size, const gles2::cmds::%s& c) {\n" %
         func.name)
     args = func.GetOriginalArgs()
     for arg in args:
@@ -5573,7 +5635,7 @@
   expected.cmd.Init(1, result1.id, result1.offset);
 
   EXPECT_CALL(*command_buffer(), OnFlush())
-      .WillOnce(SetMemory(result1.ptr, uint32(1)))
+      .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
       .RetiresOnSaturation();
 
   GLboolean result = gl_->%(name)s(1);
@@ -5600,7 +5662,7 @@
     func.ClearCmdArgs()
     func.AddCmdArg(cmd_args[0])
     # add on a bucket id.
-    func.AddCmdArg(Argument('bucket_id', 'uint32'))
+    func.AddCmdArg(Argument('bucket_id', 'uint32_t'))
 
   def WriteGLES2Implementation(self, func, file):
     """Overrriden from TypeHandler."""
@@ -5653,9 +5715,9 @@
   def WriteServiceUnitTest(self, func, file):
     """Overrriden from TypeHandler."""
     valid_test = """
-TEST_F(%(test_name)s, %(name)sValidArgs) {
+TEST_P(%(test_name)s, %(name)sValidArgs) {
   const char* kInfo = "hello";
-  const uint32 kBucketId = 123;
+  const uint32_t kBucketId = 123;
   SpecializedSetup<cmds::%(name)s, 0>(true);
 %(expect_len_code)s
   EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s))
@@ -5693,8 +5755,8 @@
     self.WriteValidUnitTest(func, file, valid_test, sub)
 
     invalid_test = """
-TEST_F(%(test_name)s, %(name)sInvalidArgs) {
-  const uint32 kBucketId = 123;
+TEST_P(%(test_name)s, %(name)sInvalidArgs) {
+  const uint32_t kBucketId = 123;
   EXPECT_CALL(*gl_, %(gl_func_name)s(_, _, _, _))
       .Times(0);
   cmds::%(name)s cmd;
@@ -5725,11 +5787,11 @@
   """A class that represents a function argument."""
 
   cmd_type_map_ = {
-    'GLenum': 'uint32',
-    'GLint': 'int32',
-    'GLintptr': 'int32',
-    'GLsizei': 'int32',
-    'GLsizeiptr': 'int32',
+    'GLenum': 'uint32_t',
+    'GLint': 'int32_t',
+    'GLintptr': 'int32_t',
+    'GLsizei': 'int32_t',
+    'GLsizeiptr': 'int32_t',
     'GLfloat': 'float',
     'GLclampf': 'float',
   }
@@ -5745,7 +5807,7 @@
     if type in self.cmd_type_map_:
       self.cmd_type = self.cmd_type_map_[type]
     else:
-      self.cmd_type = 'uint32'
+      self.cmd_type = 'uint32_t'
 
   def IsPointer(self):
     """Returns true if argument is a pointer."""
@@ -5882,7 +5944,7 @@
   """class for data_size which Bucket commands do not need."""
 
   def __init__(self, name):
-    Argument.__init__(self, name, "uint32")
+    Argument.__init__(self, name, "uint32_t")
 
   def GetBucketVersion(self):
     return None
@@ -6152,8 +6214,8 @@
 
   def AddCmdArgs(self, args):
     """Overridden from Argument."""
-    args.append(Argument("%s_shm_id" % self.name, 'uint32'))
-    args.append(Argument("%s_shm_offset" % self.name, 'uint32'))
+    args.append(Argument("%s_shm_id" % self.name, 'uint32_t'))
+    args.append(Argument("%s_shm_offset" % self.name, 'uint32_t'))
 
   def WriteGetCode(self, file):
     """Overridden from Argument."""
@@ -6198,7 +6260,7 @@
   """An string input argument where the string is passed in a bucket."""
 
   def __init__(self, name, type):
-    Argument.__init__(self, name + "_bucket_id", "uint32")
+    Argument.__init__(self, name + "_bucket_id", "uint32_t")
 
   def WriteGetCode(self, file):
     """Overridden from Argument."""
@@ -6515,9 +6577,9 @@
 
   def WriteCmdComputeSize(self, file):
     """Writes the ComputeSize function for the command."""
-    file.Write("  static uint32 ComputeSize() {\n")
+    file.Write("  static uint32_t ComputeSize() {\n")
     file.Write(
-        "    return static_cast<uint32>(sizeof(ValueType));  // NOLINT\n")
+        "    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT\n")
     file.Write("  }\n")
     file.Write("\n")
 
@@ -7079,14 +7141,45 @@
     file.Write("  EnableFlags();\n")
     for capability in _CAPABILITY_FLAGS:
       file.Write("  bool %s;\n" % capability['name'])
+      file.Write("  bool cached_%s;\n" % capability['name'])
     file.Write("};\n\n")
 
     for state_name in sorted(_STATES.keys()):
       state = _STATES[state_name]
       for item in state['states']:
         file.Write("%s %s;\n" % (item['type'], item['name']))
+        if item.get('cached', False):
+          file.Write("%s cached_%s;\n" % (item['type'], item['name']))
     file.Write("\n")
 
+    file.Write("""
+        inline void SetDeviceCapabilityState(GLenum cap, bool enable) {
+          switch (cap) {
+        """)
+    for capability in _CAPABILITY_FLAGS:
+      file.Write("""\
+            case GL_%s:
+          """ % capability['name'].upper())
+      file.Write("""\
+              if (enable_flags.cached_%(name)s == enable &&
+                  !ignore_cached_state)
+                return;
+              enable_flags.cached_%(name)s = enable;
+              break;
+          """ % capability)
+
+    file.Write("""\
+            default:
+              NOTREACHED();
+              return;
+          }
+          if (enable)
+            glEnable(cap);
+          else
+            glDisable(cap);
+        }
+        """)
+
     file.Close()
 
   def WriteClientContextStateHeader(self, filename):
@@ -7155,6 +7248,9 @@
       code.append("%s(%s)" %
                   (capability['name'],
                    ('false', 'true')['default' in capability]))
+      code.append("cached_%s(%s)" %
+                  (capability['name'],
+                   ('false', 'true')['default' in capability]))
     file.Write("ContextState::EnableFlags::EnableFlags()\n    : %s {\n}\n" %
                ",\n      ".join(code))
     file.Write("\n")
@@ -7164,6 +7260,8 @@
       state = _STATES[state_name]
       for item in state['states']:
         file.Write("  %s = %s;\n" % (item['name'], item['default']))
+        if item.get('cached', False):
+          file.Write("  cached_%s = %s;\n" % (item['name'], item['default']))
     file.Write("}\n")
 
     file.Write("""
@@ -7173,9 +7271,10 @@
       for capability in _CAPABILITY_FLAGS:
         capability_name = capability['name']
         if test_prev:
-          file.Write("  if (prev_state->enable_flags.%s != enable_flags.%s)\n" %
+          file.Write("""  if (prev_state->enable_flags.cached_%s !=
+                              enable_flags.cached_%s)\n""" %
                      (capability_name, capability_name))
-        file.Write("    EnableDisable(GL_%s, enable_flags.%s);\n" %
+        file.Write("    EnableDisable(GL_%s, enable_flags.cached_%s);\n" %
                    (capability_name.upper(), capability_name))
 
     file.Write("  if (prev_state) {")
@@ -7200,7 +7299,7 @@
               file.Write("  if (")
             args = []
             for place, item in enumerate(group):
-              item_name = item['name']
+              item_name = CachedStateName(item)
               args.append('%s' % item_name)
               if test_prev:
                 if place > 0:
@@ -7213,20 +7312,22 @@
                 (state['func'], ('GL_FRONT', 'GL_BACK')[ndx], ", ".join(args)))
         elif state['type'] == 'NamedParameter':
           for item in state['states']:
+            item_name = CachedStateName(item)
+
             if 'extension_flag' in item:
               file.Write("  if (feature_info_->feature_flags().%s)\n  " %
                          item['extension_flag'])
             if test_prev:
               file.Write("  if (prev_state->%s != %s)\n" %
-                         (item['name'], item['name']))
+                         (item_name, item_name))
             file.Write("  gl%s(%s, %s);\n" %
-                       (state['func'], item['enum'], item['name']))
+                       (state['func'], item['enum'], item_name))
         else:
           if test_prev:
             file.Write("  if (")
           args = []
           for place, item in enumerate(state['states']):
-            item_name = item['name']
+            item_name = CachedStateName(item)
             args.append('%s' % item_name)
             if test_prev:
               if place > 0:
@@ -7329,16 +7430,25 @@
     for capability in _CAPABILITY_FLAGS:
       file.Write("    case GL_%s:\n" % capability['name'].upper())
       if 'state_flag' in capability:
-        file.Write("""      if (state_.enable_flags.%(name)s != enabled) {
-        state_.enable_flags.%(name)s = enabled;
-        %(state_flag)s = true;
-      }
-      return false;
-""" % capability)
+
+        file.Write("""\
+            state_.enable_flags.%(name)s = enabled;
+            if (state_.enable_flags.cached_%(name)s != enabled
+                || state_.ignore_cached_state) {
+              %(state_flag)s = true;
+            }
+            return false;
+            """ % capability)
       else:
-        file.Write("""      state_.enable_flags.%(name)s = enabled;
-      return true;
-""" % capability)
+        file.Write("""\
+            state_.enable_flags.%(name)s = enabled;
+            if (state_.enable_flags.cached_%(name)s != enabled
+                || state_.ignore_cached_state) {
+              state_.enable_flags.cached_%(name)s = enabled;
+              return true;
+            }
+            return false;
+            """ % capability)
     file.Write("""    default:
       NOTREACHED();
       return false;
@@ -7591,7 +7701,7 @@
     enums = sorted(_ENUM_LISTS.keys())
     for enum in enums:
       if _ENUM_LISTS[enum]['type'] == 'GLenum':
-        file.Write("static std::string GetString%s(uint32 value);\n" % enum)
+        file.Write("static std::string GetString%s(uint32_t value);\n" % enum)
     file.Write("\n")
     file.Close()
 
@@ -7629,7 +7739,7 @@
     enums = sorted(_ENUM_LISTS.keys())
     for enum in enums:
       if _ENUM_LISTS[enum]['type'] == 'GLenum':
-        file.Write("std::string GLES2Util::GetString%s(uint32 value) {\n" %
+        file.Write("std::string GLES2Util::GetString%s(uint32_t value) {\n" %
                    enum)
         if len(_ENUM_LISTS[enum]['valid']) > 0:
           file.Write("  static const EnumToString string_table[] = {\n")
diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h
index 22ffea6..083fb29 100644
--- a/gpu/command_buffer/client/client_test_helper.h
+++ b/gpu/command_buffer/client/client_test_helper.h
@@ -9,8 +9,8 @@
 
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
+#include "gpu/command_buffer/client/gpu_control.h"
 #include "gpu/command_buffer/common/cmd_buffer_common.h"
-#include "gpu/command_buffer/common/gpu_control.h"
 #include "gpu/command_buffer/common/gpu_memory_allocation.h"
 #include "gpu/command_buffer/service/command_buffer_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -88,10 +88,11 @@
   virtual ~MockClientGpuControl();
 
   MOCK_METHOD0(GetCapabilities, Capabilities());
-  MOCK_METHOD4(CreateGpuMemoryBuffer,
+  MOCK_METHOD5(CreateGpuMemoryBuffer,
                gfx::GpuMemoryBuffer*(size_t width,
                                      size_t height,
                                      unsigned internalformat,
+                                     unsigned usage,
                                      int32* id));
   MOCK_METHOD1(DestroyGpuMemoryBuffer, void(int32 id));
   MOCK_METHOD0(InsertSyncPoint, uint32());
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc
index 080aa6b..b50527a 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -225,7 +225,7 @@
   if (token < 0)
     return;
   if (token > token_) return;  // we wrapped
-  if (last_token_read() > token)
+  if (last_token_read() >= token)
     return;
   Flush();
   command_buffer_->WaitForTokenInRange(token, token_);
diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc
index 42d8b4b..c2d1361 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc
@@ -44,10 +44,12 @@
       TransferBufferManagerInterface* transfer_buffer_manager)
       : CommandBufferService(transfer_buffer_manager),
         flush_locked_(false),
-        last_flush_(-1) {}
+        last_flush_(-1),
+        flush_count_(0) {}
   virtual ~CommandBufferServiceLocked() {}
 
   virtual void Flush(int32 put_offset) OVERRIDE {
+    flush_count_++;
     if (!flush_locked_) {
       last_flush_ = -1;
       CommandBufferService::Flush(put_offset);
@@ -60,6 +62,8 @@
 
   void UnlockFlush() { flush_locked_ = false; }
 
+  int FlushCount() { return flush_count_; }
+
   virtual void WaitForGetOffsetInRange(int32 start, int32 end) OVERRIDE {
     if (last_flush_ != -1) {
       CommandBufferService::Flush(last_flush_);
@@ -71,6 +75,7 @@
  private:
   bool flush_locked_;
   int last_flush_;
+  int flush_count_;
   DISALLOW_COPY_AND_ASSIGN(CommandBufferServiceLocked);
 };
 
@@ -586,6 +591,46 @@
   EXPECT_EQ(error::kNoError, GetError());
 }
 
+// Checks WaitForToken doesn't Flush if token is already read.
+TEST_F(CommandBufferHelperTest, TestWaitForTokenFlush) {
+  CommandBufferEntry args[2];
+  args[0].value_uint32 = 3;
+  args[1].value_float = 4.f;
+
+  // Add a first command.
+  AddCommandWithExpect(error::kNoError, kUnusedCommandId + 3, 2, args);
+  int32 token = helper_->InsertToken();
+
+  EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _))
+      .WillOnce(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken),
+                      Return(error::kNoError)));
+
+  int flush_count = command_buffer_->FlushCount();
+
+  // Test that waiting for pending token causes a Flush.
+  helper_->WaitForToken(token);
+  EXPECT_EQ(command_buffer_->FlushCount(), flush_count + 1);
+
+  // Test that we don't Flush repeatedly.
+  helper_->WaitForToken(token);
+  EXPECT_EQ(command_buffer_->FlushCount(), flush_count + 1);
+
+  // Add another command.
+  AddCommandWithExpect(error::kNoError, kUnusedCommandId + 4, 2, args);
+
+  // Test that we don't Flush repeatedly even if commands are pending.
+  helper_->WaitForToken(token);
+  EXPECT_EQ(command_buffer_->FlushCount(), flush_count + 1);
+
+  helper_->Finish();
+
+  // Check that the commands did happen.
+  Mock::VerifyAndClearExpectations(api_mock_.get());
+
+  // Check the error status.
+  EXPECT_EQ(error::kNoError, GetError());
+}
+
 TEST_F(CommandBufferHelperTest, FreeRingBuffer) {
   EXPECT_TRUE(helper_->HaveRingBuffer());
 
diff --git a/gpu/command_buffer/client/fenced_allocator.h b/gpu/command_buffer/client/fenced_allocator.h
index 77fadc3..8e222e1 100644
--- a/gpu/command_buffer/client/fenced_allocator.h
+++ b/gpu/command_buffer/client/fenced_allocator.h
@@ -7,11 +7,13 @@
 #ifndef GPU_COMMAND_BUFFER_CLIENT_FENCED_ALLOCATOR_H_
 #define GPU_COMMAND_BUFFER_CLIENT_FENCED_ALLOCATOR_H_
 
+#include <stdint.h>
+
 #include <vector>
 
 #include "base/bind.h"
 #include "base/logging.h"
-#include "gpu/command_buffer/common/types.h"
+#include "base/macros.h"
 #include "gpu/gpu_export.h"
 
 namespace gpu {
@@ -101,7 +103,7 @@
     State state;
     Offset offset;
     unsigned int size;
-    int32 token;  // token to wait for in the FREE_PENDING_TOKEN case.
+    int32_t token;  // token to wait for in the FREE_PENDING_TOKEN case.
   };
 
   // Comparison functor for memory block sorting.
@@ -115,7 +117,7 @@
   typedef std::vector<Block> Container;
   typedef unsigned int BlockIndex;
 
-  static const int32 kUnusedToken = 0;
+  static const int32_t kUnusedToken = 0;
 
   // Gets the index of a memory block, given its offset.
   BlockIndex GetBlockByOffset(Offset offset);
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index 52582f6..6ad04d2 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -737,8 +737,8 @@
 GLboolean GLES2UnmapBufferCHROMIUM(GLuint target) {
   return gles2::GetGLContext()->UnmapBufferCHROMIUM(target);
 }
-void* GLES2MapImageCHROMIUM(GLuint image_id, GLenum access) {
-  return gles2::GetGLContext()->MapImageCHROMIUM(image_id, access);
+void* GLES2MapImageCHROMIUM(GLuint image_id) {
+  return gles2::GetGLContext()->MapImageCHROMIUM(image_id);
 }
 void GLES2UnmapImageCHROMIUM(GLuint image_id) {
   gles2::GetGLContext()->UnmapImageCHROMIUM(image_id);
@@ -798,9 +798,10 @@
 }
 GLuint GLES2CreateImageCHROMIUM(GLsizei width,
                                 GLsizei height,
-                                GLenum internalformat) {
+                                GLenum internalformat,
+                                GLenum usage) {
   return gles2::GetGLContext()->CreateImageCHROMIUM(
-      width, height, internalformat);
+      width, height, internalformat, usage);
 }
 void GLES2DestroyImageCHROMIUM(GLuint image_id) {
   gles2::GetGLContext()->DestroyImageCHROMIUM(image_id);
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index bcbeabf..9868fd8 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -27,9 +27,9 @@
 
 void BindAttribLocation(GLuint program,
                         GLuint index,
-                        uint32 name_shm_id,
-                        uint32 name_shm_offset,
-                        uint32 data_size) {
+                        uint32_t name_shm_id,
+                        uint32_t name_shm_offset,
+                        uint32_t data_size) {
   gles2::cmds::BindAttribLocation* c =
       GetCmdSpace<gles2::cmds::BindAttribLocation>();
   if (c) {
@@ -39,7 +39,7 @@
 
 void BindAttribLocationBucket(GLuint program,
                               GLuint index,
-                              uint32 name_bucket_id) {
+                              uint32_t name_bucket_id) {
   gles2::cmds::BindAttribLocationBucket* c =
       GetCmdSpace<gles2::cmds::BindAttribLocationBucket>();
   if (c) {
@@ -118,8 +118,8 @@
 
 void BufferData(GLenum target,
                 GLsizeiptr size,
-                uint32 data_shm_id,
-                uint32 data_shm_offset,
+                uint32_t data_shm_id,
+                uint32_t data_shm_offset,
                 GLenum usage) {
   gles2::cmds::BufferData* c = GetCmdSpace<gles2::cmds::BufferData>();
   if (c) {
@@ -130,8 +130,8 @@
 void BufferSubData(GLenum target,
                    GLintptr offset,
                    GLsizeiptr size,
-                   uint32 data_shm_id,
-                   uint32 data_shm_offset) {
+                   uint32_t data_shm_id,
+                   uint32_t data_shm_offset) {
   gles2::cmds::BufferSubData* c = GetCmdSpace<gles2::cmds::BufferSubData>();
   if (c) {
     c->Init(target, offset, size, data_shm_id, data_shm_offset);
@@ -139,8 +139,8 @@
 }
 
 void CheckFramebufferStatus(GLenum target,
-                            uint32 result_shm_id,
-                            uint32 result_shm_offset) {
+                            uint32_t result_shm_id,
+                            uint32_t result_shm_offset) {
   gles2::cmds::CheckFramebufferStatus* c =
       GetCmdSpace<gles2::cmds::CheckFramebufferStatus>();
   if (c) {
@@ -200,8 +200,8 @@
                           GLsizei height,
                           GLint border,
                           GLsizei imageSize,
-                          uint32 data_shm_id,
-                          uint32 data_shm_offset) {
+                          uint32_t data_shm_id,
+                          uint32_t data_shm_offset) {
   gles2::cmds::CompressedTexImage2D* c =
       GetCmdSpace<gles2::cmds::CompressedTexImage2D>();
   if (c) {
@@ -239,8 +239,8 @@
                              GLsizei height,
                              GLenum format,
                              GLsizei imageSize,
-                             uint32 data_shm_id,
-                             uint32 data_shm_offset) {
+                             uint32_t data_shm_id,
+                             uint32_t data_shm_offset) {
   gles2::cmds::CompressedTexSubImage2D* c =
       GetCmdSpace<gles2::cmds::CompressedTexSubImage2D>();
   if (c) {
@@ -301,14 +301,14 @@
   }
 }
 
-void CreateProgram(uint32 client_id) {
+void CreateProgram(uint32_t client_id) {
   gles2::cmds::CreateProgram* c = GetCmdSpace<gles2::cmds::CreateProgram>();
   if (c) {
     c->Init(client_id);
   }
 }
 
-void CreateShader(GLenum type, uint32 client_id) {
+void CreateShader(GLenum type, uint32_t client_id) {
   gles2::cmds::CreateShader* c = GetCmdSpace<gles2::cmds::CreateShader>();
   if (c) {
     c->Init(type, client_id);
@@ -323,8 +323,8 @@
 }
 
 void DeleteBuffers(GLsizei n,
-                   uint32 buffers_shm_id,
-                   uint32 buffers_shm_offset) {
+                   uint32_t buffers_shm_id,
+                   uint32_t buffers_shm_offset) {
   gles2::cmds::DeleteBuffers* c = GetCmdSpace<gles2::cmds::DeleteBuffers>();
   if (c) {
     c->Init(n, buffers_shm_id, buffers_shm_offset);
@@ -332,7 +332,7 @@
 }
 
 void DeleteBuffersImmediate(GLsizei n, const GLuint* buffers) {
-  const uint32 size = gles2::cmds::DeleteBuffersImmediate::ComputeSize(n);
+  const uint32_t size = gles2::cmds::DeleteBuffersImmediate::ComputeSize(n);
   gles2::cmds::DeleteBuffersImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::DeleteBuffersImmediate>(size);
   if (c) {
@@ -341,8 +341,8 @@
 }
 
 void DeleteFramebuffers(GLsizei n,
-                        uint32 framebuffers_shm_id,
-                        uint32 framebuffers_shm_offset) {
+                        uint32_t framebuffers_shm_id,
+                        uint32_t framebuffers_shm_offset) {
   gles2::cmds::DeleteFramebuffers* c =
       GetCmdSpace<gles2::cmds::DeleteFramebuffers>();
   if (c) {
@@ -351,7 +351,8 @@
 }
 
 void DeleteFramebuffersImmediate(GLsizei n, const GLuint* framebuffers) {
-  const uint32 size = gles2::cmds::DeleteFramebuffersImmediate::ComputeSize(n);
+  const uint32_t size =
+      gles2::cmds::DeleteFramebuffersImmediate::ComputeSize(n);
   gles2::cmds::DeleteFramebuffersImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::DeleteFramebuffersImmediate>(
           size);
@@ -368,8 +369,8 @@
 }
 
 void DeleteRenderbuffers(GLsizei n,
-                         uint32 renderbuffers_shm_id,
-                         uint32 renderbuffers_shm_offset) {
+                         uint32_t renderbuffers_shm_id,
+                         uint32_t renderbuffers_shm_offset) {
   gles2::cmds::DeleteRenderbuffers* c =
       GetCmdSpace<gles2::cmds::DeleteRenderbuffers>();
   if (c) {
@@ -378,7 +379,8 @@
 }
 
 void DeleteRenderbuffersImmediate(GLsizei n, const GLuint* renderbuffers) {
-  const uint32 size = gles2::cmds::DeleteRenderbuffersImmediate::ComputeSize(n);
+  const uint32_t size =
+      gles2::cmds::DeleteRenderbuffersImmediate::ComputeSize(n);
   gles2::cmds::DeleteRenderbuffersImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::DeleteRenderbuffersImmediate>(
           size);
@@ -395,8 +397,8 @@
 }
 
 void DeleteTextures(GLsizei n,
-                    uint32 textures_shm_id,
-                    uint32 textures_shm_offset) {
+                    uint32_t textures_shm_id,
+                    uint32_t textures_shm_offset) {
   gles2::cmds::DeleteTextures* c = GetCmdSpace<gles2::cmds::DeleteTextures>();
   if (c) {
     c->Init(n, textures_shm_id, textures_shm_offset);
@@ -404,7 +406,7 @@
 }
 
 void DeleteTexturesImmediate(GLsizei n, const GLuint* textures) {
-  const uint32 size = gles2::cmds::DeleteTexturesImmediate::ComputeSize(n);
+  const uint32_t size = gles2::cmds::DeleteTexturesImmediate::ComputeSize(n);
   gles2::cmds::DeleteTexturesImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::DeleteTexturesImmediate>(size);
   if (c) {
@@ -531,7 +533,9 @@
   }
 }
 
-void GenBuffers(GLsizei n, uint32 buffers_shm_id, uint32 buffers_shm_offset) {
+void GenBuffers(GLsizei n,
+                uint32_t buffers_shm_id,
+                uint32_t buffers_shm_offset) {
   gles2::cmds::GenBuffers* c = GetCmdSpace<gles2::cmds::GenBuffers>();
   if (c) {
     c->Init(n, buffers_shm_id, buffers_shm_offset);
@@ -539,7 +543,7 @@
 }
 
 void GenBuffersImmediate(GLsizei n, GLuint* buffers) {
-  const uint32 size = gles2::cmds::GenBuffersImmediate::ComputeSize(n);
+  const uint32_t size = gles2::cmds::GenBuffersImmediate::ComputeSize(n);
   gles2::cmds::GenBuffersImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::GenBuffersImmediate>(size);
   if (c) {
@@ -555,8 +559,8 @@
 }
 
 void GenFramebuffers(GLsizei n,
-                     uint32 framebuffers_shm_id,
-                     uint32 framebuffers_shm_offset) {
+                     uint32_t framebuffers_shm_id,
+                     uint32_t framebuffers_shm_offset) {
   gles2::cmds::GenFramebuffers* c = GetCmdSpace<gles2::cmds::GenFramebuffers>();
   if (c) {
     c->Init(n, framebuffers_shm_id, framebuffers_shm_offset);
@@ -564,7 +568,7 @@
 }
 
 void GenFramebuffersImmediate(GLsizei n, GLuint* framebuffers) {
-  const uint32 size = gles2::cmds::GenFramebuffersImmediate::ComputeSize(n);
+  const uint32_t size = gles2::cmds::GenFramebuffersImmediate::ComputeSize(n);
   gles2::cmds::GenFramebuffersImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::GenFramebuffersImmediate>(
           size);
@@ -574,8 +578,8 @@
 }
 
 void GenRenderbuffers(GLsizei n,
-                      uint32 renderbuffers_shm_id,
-                      uint32 renderbuffers_shm_offset) {
+                      uint32_t renderbuffers_shm_id,
+                      uint32_t renderbuffers_shm_offset) {
   gles2::cmds::GenRenderbuffers* c =
       GetCmdSpace<gles2::cmds::GenRenderbuffers>();
   if (c) {
@@ -584,7 +588,7 @@
 }
 
 void GenRenderbuffersImmediate(GLsizei n, GLuint* renderbuffers) {
-  const uint32 size = gles2::cmds::GenRenderbuffersImmediate::ComputeSize(n);
+  const uint32_t size = gles2::cmds::GenRenderbuffersImmediate::ComputeSize(n);
   gles2::cmds::GenRenderbuffersImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::GenRenderbuffersImmediate>(
           size);
@@ -594,8 +598,8 @@
 }
 
 void GenTextures(GLsizei n,
-                 uint32 textures_shm_id,
-                 uint32 textures_shm_offset) {
+                 uint32_t textures_shm_id,
+                 uint32_t textures_shm_offset) {
   gles2::cmds::GenTextures* c = GetCmdSpace<gles2::cmds::GenTextures>();
   if (c) {
     c->Init(n, textures_shm_id, textures_shm_offset);
@@ -603,7 +607,7 @@
 }
 
 void GenTexturesImmediate(GLsizei n, GLuint* textures) {
-  const uint32 size = gles2::cmds::GenTexturesImmediate::ComputeSize(n);
+  const uint32_t size = gles2::cmds::GenTexturesImmediate::ComputeSize(n);
   gles2::cmds::GenTexturesImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::GenTexturesImmediate>(size);
   if (c) {
@@ -613,9 +617,9 @@
 
 void GetActiveAttrib(GLuint program,
                      GLuint index,
-                     uint32 name_bucket_id,
-                     uint32 result_shm_id,
-                     uint32 result_shm_offset) {
+                     uint32_t name_bucket_id,
+                     uint32_t result_shm_id,
+                     uint32_t result_shm_offset) {
   gles2::cmds::GetActiveAttrib* c = GetCmdSpace<gles2::cmds::GetActiveAttrib>();
   if (c) {
     c->Init(program, index, name_bucket_id, result_shm_id, result_shm_offset);
@@ -624,9 +628,9 @@
 
 void GetActiveUniform(GLuint program,
                       GLuint index,
-                      uint32 name_bucket_id,
-                      uint32 result_shm_id,
-                      uint32 result_shm_offset) {
+                      uint32_t name_bucket_id,
+                      uint32_t result_shm_id,
+                      uint32_t result_shm_offset) {
   gles2::cmds::GetActiveUniform* c =
       GetCmdSpace<gles2::cmds::GetActiveUniform>();
   if (c) {
@@ -635,9 +639,9 @@
 }
 
 void GetAttachedShaders(GLuint program,
-                        uint32 result_shm_id,
-                        uint32 result_shm_offset,
-                        uint32 result_size) {
+                        uint32_t result_shm_id,
+                        uint32_t result_shm_offset,
+                        uint32_t result_size) {
   gles2::cmds::GetAttachedShaders* c =
       GetCmdSpace<gles2::cmds::GetAttachedShaders>();
   if (c) {
@@ -645,7 +649,9 @@
   }
 }
 
-void GetBooleanv(GLenum pname, uint32 params_shm_id, uint32 params_shm_offset) {
+void GetBooleanv(GLenum pname,
+                 uint32_t params_shm_id,
+                 uint32_t params_shm_offset) {
   gles2::cmds::GetBooleanv* c = GetCmdSpace<gles2::cmds::GetBooleanv>();
   if (c) {
     c->Init(pname, params_shm_id, params_shm_offset);
@@ -654,8 +660,8 @@
 
 void GetBufferParameteriv(GLenum target,
                           GLenum pname,
-                          uint32 params_shm_id,
-                          uint32 params_shm_offset) {
+                          uint32_t params_shm_id,
+                          uint32_t params_shm_offset) {
   gles2::cmds::GetBufferParameteriv* c =
       GetCmdSpace<gles2::cmds::GetBufferParameteriv>();
   if (c) {
@@ -663,14 +669,16 @@
   }
 }
 
-void GetError(uint32 result_shm_id, uint32 result_shm_offset) {
+void GetError(uint32_t result_shm_id, uint32_t result_shm_offset) {
   gles2::cmds::GetError* c = GetCmdSpace<gles2::cmds::GetError>();
   if (c) {
     c->Init(result_shm_id, result_shm_offset);
   }
 }
 
-void GetFloatv(GLenum pname, uint32 params_shm_id, uint32 params_shm_offset) {
+void GetFloatv(GLenum pname,
+               uint32_t params_shm_id,
+               uint32_t params_shm_offset) {
   gles2::cmds::GetFloatv* c = GetCmdSpace<gles2::cmds::GetFloatv>();
   if (c) {
     c->Init(pname, params_shm_id, params_shm_offset);
@@ -680,8 +688,8 @@
 void GetFramebufferAttachmentParameteriv(GLenum target,
                                          GLenum attachment,
                                          GLenum pname,
-                                         uint32 params_shm_id,
-                                         uint32 params_shm_offset) {
+                                         uint32_t params_shm_id,
+                                         uint32_t params_shm_offset) {
   gles2::cmds::GetFramebufferAttachmentParameteriv* c =
       GetCmdSpace<gles2::cmds::GetFramebufferAttachmentParameteriv>();
   if (c) {
@@ -689,7 +697,9 @@
   }
 }
 
-void GetIntegerv(GLenum pname, uint32 params_shm_id, uint32 params_shm_offset) {
+void GetIntegerv(GLenum pname,
+                 uint32_t params_shm_id,
+                 uint32_t params_shm_offset) {
   gles2::cmds::GetIntegerv* c = GetCmdSpace<gles2::cmds::GetIntegerv>();
   if (c) {
     c->Init(pname, params_shm_id, params_shm_offset);
@@ -698,15 +708,15 @@
 
 void GetProgramiv(GLuint program,
                   GLenum pname,
-                  uint32 params_shm_id,
-                  uint32 params_shm_offset) {
+                  uint32_t params_shm_id,
+                  uint32_t params_shm_offset) {
   gles2::cmds::GetProgramiv* c = GetCmdSpace<gles2::cmds::GetProgramiv>();
   if (c) {
     c->Init(program, pname, params_shm_id, params_shm_offset);
   }
 }
 
-void GetProgramInfoLog(GLuint program, uint32 bucket_id) {
+void GetProgramInfoLog(GLuint program, uint32_t bucket_id) {
   gles2::cmds::GetProgramInfoLog* c =
       GetCmdSpace<gles2::cmds::GetProgramInfoLog>();
   if (c) {
@@ -716,8 +726,8 @@
 
 void GetRenderbufferParameteriv(GLenum target,
                                 GLenum pname,
-                                uint32 params_shm_id,
-                                uint32 params_shm_offset) {
+                                uint32_t params_shm_id,
+                                uint32_t params_shm_offset) {
   gles2::cmds::GetRenderbufferParameteriv* c =
       GetCmdSpace<gles2::cmds::GetRenderbufferParameteriv>();
   if (c) {
@@ -727,15 +737,15 @@
 
 void GetShaderiv(GLuint shader,
                  GLenum pname,
-                 uint32 params_shm_id,
-                 uint32 params_shm_offset) {
+                 uint32_t params_shm_id,
+                 uint32_t params_shm_offset) {
   gles2::cmds::GetShaderiv* c = GetCmdSpace<gles2::cmds::GetShaderiv>();
   if (c) {
     c->Init(shader, pname, params_shm_id, params_shm_offset);
   }
 }
 
-void GetShaderInfoLog(GLuint shader, uint32 bucket_id) {
+void GetShaderInfoLog(GLuint shader, uint32_t bucket_id) {
   gles2::cmds::GetShaderInfoLog* c =
       GetCmdSpace<gles2::cmds::GetShaderInfoLog>();
   if (c) {
@@ -745,8 +755,8 @@
 
 void GetShaderPrecisionFormat(GLenum shadertype,
                               GLenum precisiontype,
-                              uint32 result_shm_id,
-                              uint32 result_shm_offset) {
+                              uint32_t result_shm_id,
+                              uint32_t result_shm_offset) {
   gles2::cmds::GetShaderPrecisionFormat* c =
       GetCmdSpace<gles2::cmds::GetShaderPrecisionFormat>();
   if (c) {
@@ -754,14 +764,14 @@
   }
 }
 
-void GetShaderSource(GLuint shader, uint32 bucket_id) {
+void GetShaderSource(GLuint shader, uint32_t bucket_id) {
   gles2::cmds::GetShaderSource* c = GetCmdSpace<gles2::cmds::GetShaderSource>();
   if (c) {
     c->Init(shader, bucket_id);
   }
 }
 
-void GetString(GLenum name, uint32 bucket_id) {
+void GetString(GLenum name, uint32_t bucket_id) {
   gles2::cmds::GetString* c = GetCmdSpace<gles2::cmds::GetString>();
   if (c) {
     c->Init(name, bucket_id);
@@ -770,8 +780,8 @@
 
 void GetTexParameterfv(GLenum target,
                        GLenum pname,
-                       uint32 params_shm_id,
-                       uint32 params_shm_offset) {
+                       uint32_t params_shm_id,
+                       uint32_t params_shm_offset) {
   gles2::cmds::GetTexParameterfv* c =
       GetCmdSpace<gles2::cmds::GetTexParameterfv>();
   if (c) {
@@ -781,8 +791,8 @@
 
 void GetTexParameteriv(GLenum target,
                        GLenum pname,
-                       uint32 params_shm_id,
-                       uint32 params_shm_offset) {
+                       uint32_t params_shm_id,
+                       uint32_t params_shm_offset) {
   gles2::cmds::GetTexParameteriv* c =
       GetCmdSpace<gles2::cmds::GetTexParameteriv>();
   if (c) {
@@ -792,8 +802,8 @@
 
 void GetUniformfv(GLuint program,
                   GLint location,
-                  uint32 params_shm_id,
-                  uint32 params_shm_offset) {
+                  uint32_t params_shm_id,
+                  uint32_t params_shm_offset) {
   gles2::cmds::GetUniformfv* c = GetCmdSpace<gles2::cmds::GetUniformfv>();
   if (c) {
     c->Init(program, location, params_shm_id, params_shm_offset);
@@ -802,8 +812,8 @@
 
 void GetUniformiv(GLuint program,
                   GLint location,
-                  uint32 params_shm_id,
-                  uint32 params_shm_offset) {
+                  uint32_t params_shm_id,
+                  uint32_t params_shm_offset) {
   gles2::cmds::GetUniformiv* c = GetCmdSpace<gles2::cmds::GetUniformiv>();
   if (c) {
     c->Init(program, location, params_shm_id, params_shm_offset);
@@ -812,8 +822,8 @@
 
 void GetVertexAttribfv(GLuint index,
                        GLenum pname,
-                       uint32 params_shm_id,
-                       uint32 params_shm_offset) {
+                       uint32_t params_shm_id,
+                       uint32_t params_shm_offset) {
   gles2::cmds::GetVertexAttribfv* c =
       GetCmdSpace<gles2::cmds::GetVertexAttribfv>();
   if (c) {
@@ -823,8 +833,8 @@
 
 void GetVertexAttribiv(GLuint index,
                        GLenum pname,
-                       uint32 params_shm_id,
-                       uint32 params_shm_offset) {
+                       uint32_t params_shm_id,
+                       uint32_t params_shm_offset) {
   gles2::cmds::GetVertexAttribiv* c =
       GetCmdSpace<gles2::cmds::GetVertexAttribiv>();
   if (c) {
@@ -834,8 +844,8 @@
 
 void GetVertexAttribPointerv(GLuint index,
                              GLenum pname,
-                             uint32 pointer_shm_id,
-                             uint32 pointer_shm_offset) {
+                             uint32_t pointer_shm_id,
+                             uint32_t pointer_shm_offset) {
   gles2::cmds::GetVertexAttribPointerv* c =
       GetCmdSpace<gles2::cmds::GetVertexAttribPointerv>();
   if (c) {
@@ -850,14 +860,16 @@
   }
 }
 
-void IsBuffer(GLuint buffer, uint32 result_shm_id, uint32 result_shm_offset) {
+void IsBuffer(GLuint buffer,
+              uint32_t result_shm_id,
+              uint32_t result_shm_offset) {
   gles2::cmds::IsBuffer* c = GetCmdSpace<gles2::cmds::IsBuffer>();
   if (c) {
     c->Init(buffer, result_shm_id, result_shm_offset);
   }
 }
 
-void IsEnabled(GLenum cap, uint32 result_shm_id, uint32 result_shm_offset) {
+void IsEnabled(GLenum cap, uint32_t result_shm_id, uint32_t result_shm_offset) {
   gles2::cmds::IsEnabled* c = GetCmdSpace<gles2::cmds::IsEnabled>();
   if (c) {
     c->Init(cap, result_shm_id, result_shm_offset);
@@ -865,15 +877,17 @@
 }
 
 void IsFramebuffer(GLuint framebuffer,
-                   uint32 result_shm_id,
-                   uint32 result_shm_offset) {
+                   uint32_t result_shm_id,
+                   uint32_t result_shm_offset) {
   gles2::cmds::IsFramebuffer* c = GetCmdSpace<gles2::cmds::IsFramebuffer>();
   if (c) {
     c->Init(framebuffer, result_shm_id, result_shm_offset);
   }
 }
 
-void IsProgram(GLuint program, uint32 result_shm_id, uint32 result_shm_offset) {
+void IsProgram(GLuint program,
+               uint32_t result_shm_id,
+               uint32_t result_shm_offset) {
   gles2::cmds::IsProgram* c = GetCmdSpace<gles2::cmds::IsProgram>();
   if (c) {
     c->Init(program, result_shm_id, result_shm_offset);
@@ -881,22 +895,26 @@
 }
 
 void IsRenderbuffer(GLuint renderbuffer,
-                    uint32 result_shm_id,
-                    uint32 result_shm_offset) {
+                    uint32_t result_shm_id,
+                    uint32_t result_shm_offset) {
   gles2::cmds::IsRenderbuffer* c = GetCmdSpace<gles2::cmds::IsRenderbuffer>();
   if (c) {
     c->Init(renderbuffer, result_shm_id, result_shm_offset);
   }
 }
 
-void IsShader(GLuint shader, uint32 result_shm_id, uint32 result_shm_offset) {
+void IsShader(GLuint shader,
+              uint32_t result_shm_id,
+              uint32_t result_shm_offset) {
   gles2::cmds::IsShader* c = GetCmdSpace<gles2::cmds::IsShader>();
   if (c) {
     c->Init(shader, result_shm_id, result_shm_offset);
   }
 }
 
-void IsTexture(GLuint texture, uint32 result_shm_id, uint32 result_shm_offset) {
+void IsTexture(GLuint texture,
+               uint32_t result_shm_id,
+               uint32_t result_shm_offset) {
   gles2::cmds::IsTexture* c = GetCmdSpace<gles2::cmds::IsTexture>();
   if (c) {
     c->Init(texture, result_shm_id, result_shm_offset);
@@ -937,10 +955,10 @@
                 GLsizei height,
                 GLenum format,
                 GLenum type,
-                uint32 pixels_shm_id,
-                uint32 pixels_shm_offset,
-                uint32 result_shm_id,
-                uint32 result_shm_offset,
+                uint32_t pixels_shm_id,
+                uint32_t pixels_shm_offset,
+                uint32_t result_shm_id,
+                uint32_t result_shm_offset,
                 GLboolean async) {
   gles2::cmds::ReadPixels* c = GetCmdSpace<gles2::cmds::ReadPixels>();
   if (c) {
@@ -992,11 +1010,11 @@
 }
 
 void ShaderBinary(GLsizei n,
-                  uint32 shaders_shm_id,
-                  uint32 shaders_shm_offset,
+                  uint32_t shaders_shm_id,
+                  uint32_t shaders_shm_offset,
                   GLenum binaryformat,
-                  uint32 binary_shm_id,
-                  uint32 binary_shm_offset,
+                  uint32_t binary_shm_id,
+                  uint32_t binary_shm_offset,
                   GLsizei length) {
   gles2::cmds::ShaderBinary* c = GetCmdSpace<gles2::cmds::ShaderBinary>();
   if (c) {
@@ -1011,16 +1029,16 @@
 }
 
 void ShaderSource(GLuint shader,
-                  uint32 data_shm_id,
-                  uint32 data_shm_offset,
-                  uint32 data_size) {
+                  uint32_t data_shm_id,
+                  uint32_t data_shm_offset,
+                  uint32_t data_size) {
   gles2::cmds::ShaderSource* c = GetCmdSpace<gles2::cmds::ShaderSource>();
   if (c) {
     c->Init(shader, data_shm_id, data_shm_offset, data_size);
   }
 }
 
-void ShaderSourceBucket(GLuint shader, uint32 data_bucket_id) {
+void ShaderSourceBucket(GLuint shader, uint32_t data_bucket_id) {
   gles2::cmds::ShaderSourceBucket* c =
       GetCmdSpace<gles2::cmds::ShaderSourceBucket>();
   if (c) {
@@ -1081,8 +1099,8 @@
                 GLint border,
                 GLenum format,
                 GLenum type,
-                uint32 pixels_shm_id,
-                uint32 pixels_shm_offset) {
+                uint32_t pixels_shm_id,
+                uint32_t pixels_shm_offset) {
   gles2::cmds::TexImage2D* c = GetCmdSpace<gles2::cmds::TexImage2D>();
   if (c) {
     c->Init(target,
@@ -1107,8 +1125,8 @@
 
 void TexParameterfv(GLenum target,
                     GLenum pname,
-                    uint32 params_shm_id,
-                    uint32 params_shm_offset) {
+                    uint32_t params_shm_id,
+                    uint32_t params_shm_offset) {
   gles2::cmds::TexParameterfv* c = GetCmdSpace<gles2::cmds::TexParameterfv>();
   if (c) {
     c->Init(target, pname, params_shm_id, params_shm_offset);
@@ -1118,7 +1136,7 @@
 void TexParameterfvImmediate(GLenum target,
                              GLenum pname,
                              const GLfloat* params) {
-  const uint32 size = gles2::cmds::TexParameterfvImmediate::ComputeSize();
+  const uint32_t size = gles2::cmds::TexParameterfvImmediate::ComputeSize();
   gles2::cmds::TexParameterfvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::TexParameterfvImmediate>(size);
   if (c) {
@@ -1135,8 +1153,8 @@
 
 void TexParameteriv(GLenum target,
                     GLenum pname,
-                    uint32 params_shm_id,
-                    uint32 params_shm_offset) {
+                    uint32_t params_shm_id,
+                    uint32_t params_shm_offset) {
   gles2::cmds::TexParameteriv* c = GetCmdSpace<gles2::cmds::TexParameteriv>();
   if (c) {
     c->Init(target, pname, params_shm_id, params_shm_offset);
@@ -1144,7 +1162,7 @@
 }
 
 void TexParameterivImmediate(GLenum target, GLenum pname, const GLint* params) {
-  const uint32 size = gles2::cmds::TexParameterivImmediate::ComputeSize();
+  const uint32_t size = gles2::cmds::TexParameterivImmediate::ComputeSize();
   gles2::cmds::TexParameterivImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::TexParameterivImmediate>(size);
   if (c) {
@@ -1160,8 +1178,8 @@
                    GLsizei height,
                    GLenum format,
                    GLenum type,
-                   uint32 pixels_shm_id,
-                   uint32 pixels_shm_offset,
+                   uint32_t pixels_shm_id,
+                   uint32_t pixels_shm_offset,
                    GLboolean internal) {
   gles2::cmds::TexSubImage2D* c = GetCmdSpace<gles2::cmds::TexSubImage2D>();
   if (c) {
@@ -1188,8 +1206,8 @@
 
 void Uniform1fv(GLint location,
                 GLsizei count,
-                uint32 v_shm_id,
-                uint32 v_shm_offset) {
+                uint32_t v_shm_id,
+                uint32_t v_shm_offset) {
   gles2::cmds::Uniform1fv* c = GetCmdSpace<gles2::cmds::Uniform1fv>();
   if (c) {
     c->Init(location, count, v_shm_id, v_shm_offset);
@@ -1197,7 +1215,7 @@
 }
 
 void Uniform1fvImmediate(GLint location, GLsizei count, const GLfloat* v) {
-  const uint32 size = gles2::cmds::Uniform1fvImmediate::ComputeSize(count);
+  const uint32_t size = gles2::cmds::Uniform1fvImmediate::ComputeSize(count);
   gles2::cmds::Uniform1fvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform1fvImmediate>(size);
   if (c) {
@@ -1214,8 +1232,8 @@
 
 void Uniform1iv(GLint location,
                 GLsizei count,
-                uint32 v_shm_id,
-                uint32 v_shm_offset) {
+                uint32_t v_shm_id,
+                uint32_t v_shm_offset) {
   gles2::cmds::Uniform1iv* c = GetCmdSpace<gles2::cmds::Uniform1iv>();
   if (c) {
     c->Init(location, count, v_shm_id, v_shm_offset);
@@ -1223,7 +1241,7 @@
 }
 
 void Uniform1ivImmediate(GLint location, GLsizei count, const GLint* v) {
-  const uint32 size = gles2::cmds::Uniform1ivImmediate::ComputeSize(count);
+  const uint32_t size = gles2::cmds::Uniform1ivImmediate::ComputeSize(count);
   gles2::cmds::Uniform1ivImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform1ivImmediate>(size);
   if (c) {
@@ -1240,8 +1258,8 @@
 
 void Uniform2fv(GLint location,
                 GLsizei count,
-                uint32 v_shm_id,
-                uint32 v_shm_offset) {
+                uint32_t v_shm_id,
+                uint32_t v_shm_offset) {
   gles2::cmds::Uniform2fv* c = GetCmdSpace<gles2::cmds::Uniform2fv>();
   if (c) {
     c->Init(location, count, v_shm_id, v_shm_offset);
@@ -1249,7 +1267,7 @@
 }
 
 void Uniform2fvImmediate(GLint location, GLsizei count, const GLfloat* v) {
-  const uint32 size = gles2::cmds::Uniform2fvImmediate::ComputeSize(count);
+  const uint32_t size = gles2::cmds::Uniform2fvImmediate::ComputeSize(count);
   gles2::cmds::Uniform2fvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform2fvImmediate>(size);
   if (c) {
@@ -1266,8 +1284,8 @@
 
 void Uniform2iv(GLint location,
                 GLsizei count,
-                uint32 v_shm_id,
-                uint32 v_shm_offset) {
+                uint32_t v_shm_id,
+                uint32_t v_shm_offset) {
   gles2::cmds::Uniform2iv* c = GetCmdSpace<gles2::cmds::Uniform2iv>();
   if (c) {
     c->Init(location, count, v_shm_id, v_shm_offset);
@@ -1275,7 +1293,7 @@
 }
 
 void Uniform2ivImmediate(GLint location, GLsizei count, const GLint* v) {
-  const uint32 size = gles2::cmds::Uniform2ivImmediate::ComputeSize(count);
+  const uint32_t size = gles2::cmds::Uniform2ivImmediate::ComputeSize(count);
   gles2::cmds::Uniform2ivImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform2ivImmediate>(size);
   if (c) {
@@ -1292,8 +1310,8 @@
 
 void Uniform3fv(GLint location,
                 GLsizei count,
-                uint32 v_shm_id,
-                uint32 v_shm_offset) {
+                uint32_t v_shm_id,
+                uint32_t v_shm_offset) {
   gles2::cmds::Uniform3fv* c = GetCmdSpace<gles2::cmds::Uniform3fv>();
   if (c) {
     c->Init(location, count, v_shm_id, v_shm_offset);
@@ -1301,7 +1319,7 @@
 }
 
 void Uniform3fvImmediate(GLint location, GLsizei count, const GLfloat* v) {
-  const uint32 size = gles2::cmds::Uniform3fvImmediate::ComputeSize(count);
+  const uint32_t size = gles2::cmds::Uniform3fvImmediate::ComputeSize(count);
   gles2::cmds::Uniform3fvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform3fvImmediate>(size);
   if (c) {
@@ -1318,8 +1336,8 @@
 
 void Uniform3iv(GLint location,
                 GLsizei count,
-                uint32 v_shm_id,
-                uint32 v_shm_offset) {
+                uint32_t v_shm_id,
+                uint32_t v_shm_offset) {
   gles2::cmds::Uniform3iv* c = GetCmdSpace<gles2::cmds::Uniform3iv>();
   if (c) {
     c->Init(location, count, v_shm_id, v_shm_offset);
@@ -1327,7 +1345,7 @@
 }
 
 void Uniform3ivImmediate(GLint location, GLsizei count, const GLint* v) {
-  const uint32 size = gles2::cmds::Uniform3ivImmediate::ComputeSize(count);
+  const uint32_t size = gles2::cmds::Uniform3ivImmediate::ComputeSize(count);
   gles2::cmds::Uniform3ivImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform3ivImmediate>(size);
   if (c) {
@@ -1344,8 +1362,8 @@
 
 void Uniform4fv(GLint location,
                 GLsizei count,
-                uint32 v_shm_id,
-                uint32 v_shm_offset) {
+                uint32_t v_shm_id,
+                uint32_t v_shm_offset) {
   gles2::cmds::Uniform4fv* c = GetCmdSpace<gles2::cmds::Uniform4fv>();
   if (c) {
     c->Init(location, count, v_shm_id, v_shm_offset);
@@ -1353,7 +1371,7 @@
 }
 
 void Uniform4fvImmediate(GLint location, GLsizei count, const GLfloat* v) {
-  const uint32 size = gles2::cmds::Uniform4fvImmediate::ComputeSize(count);
+  const uint32_t size = gles2::cmds::Uniform4fvImmediate::ComputeSize(count);
   gles2::cmds::Uniform4fvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform4fvImmediate>(size);
   if (c) {
@@ -1370,8 +1388,8 @@
 
 void Uniform4iv(GLint location,
                 GLsizei count,
-                uint32 v_shm_id,
-                uint32 v_shm_offset) {
+                uint32_t v_shm_id,
+                uint32_t v_shm_offset) {
   gles2::cmds::Uniform4iv* c = GetCmdSpace<gles2::cmds::Uniform4iv>();
   if (c) {
     c->Init(location, count, v_shm_id, v_shm_offset);
@@ -1379,7 +1397,7 @@
 }
 
 void Uniform4ivImmediate(GLint location, GLsizei count, const GLint* v) {
-  const uint32 size = gles2::cmds::Uniform4ivImmediate::ComputeSize(count);
+  const uint32_t size = gles2::cmds::Uniform4ivImmediate::ComputeSize(count);
   gles2::cmds::Uniform4ivImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::Uniform4ivImmediate>(size);
   if (c) {
@@ -1390,8 +1408,8 @@
 void UniformMatrix2fv(GLint location,
                       GLsizei count,
                       GLboolean transpose,
-                      uint32 value_shm_id,
-                      uint32 value_shm_offset) {
+                      uint32_t value_shm_id,
+                      uint32_t value_shm_offset) {
   gles2::cmds::UniformMatrix2fv* c =
       GetCmdSpace<gles2::cmds::UniformMatrix2fv>();
   if (c) {
@@ -1403,7 +1421,7 @@
                                GLsizei count,
                                GLboolean transpose,
                                const GLfloat* value) {
-  const uint32 size =
+  const uint32_t size =
       gles2::cmds::UniformMatrix2fvImmediate::ComputeSize(count);
   gles2::cmds::UniformMatrix2fvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::UniformMatrix2fvImmediate>(
@@ -1416,8 +1434,8 @@
 void UniformMatrix3fv(GLint location,
                       GLsizei count,
                       GLboolean transpose,
-                      uint32 value_shm_id,
-                      uint32 value_shm_offset) {
+                      uint32_t value_shm_id,
+                      uint32_t value_shm_offset) {
   gles2::cmds::UniformMatrix3fv* c =
       GetCmdSpace<gles2::cmds::UniformMatrix3fv>();
   if (c) {
@@ -1429,7 +1447,7 @@
                                GLsizei count,
                                GLboolean transpose,
                                const GLfloat* value) {
-  const uint32 size =
+  const uint32_t size =
       gles2::cmds::UniformMatrix3fvImmediate::ComputeSize(count);
   gles2::cmds::UniformMatrix3fvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::UniformMatrix3fvImmediate>(
@@ -1442,8 +1460,8 @@
 void UniformMatrix4fv(GLint location,
                       GLsizei count,
                       GLboolean transpose,
-                      uint32 value_shm_id,
-                      uint32 value_shm_offset) {
+                      uint32_t value_shm_id,
+                      uint32_t value_shm_offset) {
   gles2::cmds::UniformMatrix4fv* c =
       GetCmdSpace<gles2::cmds::UniformMatrix4fv>();
   if (c) {
@@ -1455,7 +1473,7 @@
                                GLsizei count,
                                GLboolean transpose,
                                const GLfloat* value) {
-  const uint32 size =
+  const uint32_t size =
       gles2::cmds::UniformMatrix4fvImmediate::ComputeSize(count);
   gles2::cmds::UniformMatrix4fvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::UniformMatrix4fvImmediate>(
@@ -1487,8 +1505,8 @@
 }
 
 void VertexAttrib1fv(GLuint indx,
-                     uint32 values_shm_id,
-                     uint32 values_shm_offset) {
+                     uint32_t values_shm_id,
+                     uint32_t values_shm_offset) {
   gles2::cmds::VertexAttrib1fv* c = GetCmdSpace<gles2::cmds::VertexAttrib1fv>();
   if (c) {
     c->Init(indx, values_shm_id, values_shm_offset);
@@ -1496,7 +1514,7 @@
 }
 
 void VertexAttrib1fvImmediate(GLuint indx, const GLfloat* values) {
-  const uint32 size = gles2::cmds::VertexAttrib1fvImmediate::ComputeSize();
+  const uint32_t size = gles2::cmds::VertexAttrib1fvImmediate::ComputeSize();
   gles2::cmds::VertexAttrib1fvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::VertexAttrib1fvImmediate>(
           size);
@@ -1513,8 +1531,8 @@
 }
 
 void VertexAttrib2fv(GLuint indx,
-                     uint32 values_shm_id,
-                     uint32 values_shm_offset) {
+                     uint32_t values_shm_id,
+                     uint32_t values_shm_offset) {
   gles2::cmds::VertexAttrib2fv* c = GetCmdSpace<gles2::cmds::VertexAttrib2fv>();
   if (c) {
     c->Init(indx, values_shm_id, values_shm_offset);
@@ -1522,7 +1540,7 @@
 }
 
 void VertexAttrib2fvImmediate(GLuint indx, const GLfloat* values) {
-  const uint32 size = gles2::cmds::VertexAttrib2fvImmediate::ComputeSize();
+  const uint32_t size = gles2::cmds::VertexAttrib2fvImmediate::ComputeSize();
   gles2::cmds::VertexAttrib2fvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::VertexAttrib2fvImmediate>(
           size);
@@ -1539,8 +1557,8 @@
 }
 
 void VertexAttrib3fv(GLuint indx,
-                     uint32 values_shm_id,
-                     uint32 values_shm_offset) {
+                     uint32_t values_shm_id,
+                     uint32_t values_shm_offset) {
   gles2::cmds::VertexAttrib3fv* c = GetCmdSpace<gles2::cmds::VertexAttrib3fv>();
   if (c) {
     c->Init(indx, values_shm_id, values_shm_offset);
@@ -1548,7 +1566,7 @@
 }
 
 void VertexAttrib3fvImmediate(GLuint indx, const GLfloat* values) {
-  const uint32 size = gles2::cmds::VertexAttrib3fvImmediate::ComputeSize();
+  const uint32_t size = gles2::cmds::VertexAttrib3fvImmediate::ComputeSize();
   gles2::cmds::VertexAttrib3fvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::VertexAttrib3fvImmediate>(
           size);
@@ -1565,8 +1583,8 @@
 }
 
 void VertexAttrib4fv(GLuint indx,
-                     uint32 values_shm_id,
-                     uint32 values_shm_offset) {
+                     uint32_t values_shm_id,
+                     uint32_t values_shm_offset) {
   gles2::cmds::VertexAttrib4fv* c = GetCmdSpace<gles2::cmds::VertexAttrib4fv>();
   if (c) {
     c->Init(indx, values_shm_id, values_shm_offset);
@@ -1574,7 +1592,7 @@
 }
 
 void VertexAttrib4fvImmediate(GLuint indx, const GLfloat* values) {
-  const uint32 size = gles2::cmds::VertexAttrib4fvImmediate::ComputeSize();
+  const uint32_t size = gles2::cmds::VertexAttrib4fvImmediate::ComputeSize();
   gles2::cmds::VertexAttrib4fvImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::VertexAttrib4fvImmediate>(
           size);
@@ -1670,8 +1688,8 @@
 }
 
 void GenQueriesEXT(GLsizei n,
-                   uint32 queries_shm_id,
-                   uint32 queries_shm_offset) {
+                   uint32_t queries_shm_id,
+                   uint32_t queries_shm_offset) {
   gles2::cmds::GenQueriesEXT* c = GetCmdSpace<gles2::cmds::GenQueriesEXT>();
   if (c) {
     c->Init(n, queries_shm_id, queries_shm_offset);
@@ -1679,7 +1697,7 @@
 }
 
 void GenQueriesEXTImmediate(GLsizei n, GLuint* queries) {
-  const uint32 size = gles2::cmds::GenQueriesEXTImmediate::ComputeSize(n);
+  const uint32_t size = gles2::cmds::GenQueriesEXTImmediate::ComputeSize(n);
   gles2::cmds::GenQueriesEXTImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::GenQueriesEXTImmediate>(size);
   if (c) {
@@ -1688,8 +1706,8 @@
 }
 
 void DeleteQueriesEXT(GLsizei n,
-                      uint32 queries_shm_id,
-                      uint32 queries_shm_offset) {
+                      uint32_t queries_shm_id,
+                      uint32_t queries_shm_offset) {
   gles2::cmds::DeleteQueriesEXT* c =
       GetCmdSpace<gles2::cmds::DeleteQueriesEXT>();
   if (c) {
@@ -1698,7 +1716,7 @@
 }
 
 void DeleteQueriesEXTImmediate(GLsizei n, const GLuint* queries) {
-  const uint32 size = gles2::cmds::DeleteQueriesEXTImmediate::ComputeSize(n);
+  const uint32_t size = gles2::cmds::DeleteQueriesEXTImmediate::ComputeSize(n);
   gles2::cmds::DeleteQueriesEXTImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::DeleteQueriesEXTImmediate>(
           size);
@@ -1709,8 +1727,8 @@
 
 void BeginQueryEXT(GLenum target,
                    GLuint id,
-                   uint32 sync_data_shm_id,
-                   uint32 sync_data_shm_offset) {
+                   uint32_t sync_data_shm_id,
+                   uint32_t sync_data_shm_offset) {
   gles2::cmds::BeginQueryEXT* c = GetCmdSpace<gles2::cmds::BeginQueryEXT>();
   if (c) {
     c->Init(target, id, sync_data_shm_id, sync_data_shm_offset);
@@ -1749,8 +1767,8 @@
 }
 
 void GenVertexArraysOES(GLsizei n,
-                        uint32 arrays_shm_id,
-                        uint32 arrays_shm_offset) {
+                        uint32_t arrays_shm_id,
+                        uint32_t arrays_shm_offset) {
   gles2::cmds::GenVertexArraysOES* c =
       GetCmdSpace<gles2::cmds::GenVertexArraysOES>();
   if (c) {
@@ -1759,7 +1777,8 @@
 }
 
 void GenVertexArraysOESImmediate(GLsizei n, GLuint* arrays) {
-  const uint32 size = gles2::cmds::GenVertexArraysOESImmediate::ComputeSize(n);
+  const uint32_t size =
+      gles2::cmds::GenVertexArraysOESImmediate::ComputeSize(n);
   gles2::cmds::GenVertexArraysOESImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::GenVertexArraysOESImmediate>(
           size);
@@ -1769,8 +1788,8 @@
 }
 
 void DeleteVertexArraysOES(GLsizei n,
-                           uint32 arrays_shm_id,
-                           uint32 arrays_shm_offset) {
+                           uint32_t arrays_shm_id,
+                           uint32_t arrays_shm_offset) {
   gles2::cmds::DeleteVertexArraysOES* c =
       GetCmdSpace<gles2::cmds::DeleteVertexArraysOES>();
   if (c) {
@@ -1779,7 +1798,7 @@
 }
 
 void DeleteVertexArraysOESImmediate(GLsizei n, const GLuint* arrays) {
-  const uint32 size =
+  const uint32_t size =
       gles2::cmds::DeleteVertexArraysOESImmediate::ComputeSize(n);
   gles2::cmds::DeleteVertexArraysOESImmediate* c =
       GetImmediateCmdSpaceTotalSize<
@@ -1790,8 +1809,8 @@
 }
 
 void IsVertexArrayOES(GLuint array,
-                      uint32 result_shm_id,
-                      uint32 result_shm_offset) {
+                      uint32_t result_shm_id,
+                      uint32_t result_shm_offset) {
   gles2::cmds::IsVertexArrayOES* c =
       GetCmdSpace<gles2::cmds::IsVertexArrayOES>();
   if (c) {
@@ -1818,8 +1837,8 @@
                                  GLsizei count,
                                  GLenum type,
                                  GLuint offset,
-                                 uint32 result_shm_id,
-                                 uint32 result_shm_offset) {
+                                 uint32_t result_shm_id,
+                                 uint32_t result_shm_offset) {
   gles2::cmds::GetMaxValueInBufferCHROMIUM* c =
       GetCmdSpace<gles2::cmds::GetMaxValueInBufferCHROMIUM>();
   if (c) {
@@ -1830,8 +1849,8 @@
 void GenSharedIdsCHROMIUM(GLuint namespace_id,
                           GLuint id_offset,
                           GLsizei n,
-                          uint32 ids_shm_id,
-                          uint32 ids_shm_offset) {
+                          uint32_t ids_shm_id,
+                          uint32_t ids_shm_offset) {
   gles2::cmds::GenSharedIdsCHROMIUM* c =
       GetCmdSpace<gles2::cmds::GenSharedIdsCHROMIUM>();
   if (c) {
@@ -1841,8 +1860,8 @@
 
 void DeleteSharedIdsCHROMIUM(GLuint namespace_id,
                              GLsizei n,
-                             uint32 ids_shm_id,
-                             uint32 ids_shm_offset) {
+                             uint32_t ids_shm_id,
+                             uint32_t ids_shm_offset) {
   gles2::cmds::DeleteSharedIdsCHROMIUM* c =
       GetCmdSpace<gles2::cmds::DeleteSharedIdsCHROMIUM>();
   if (c) {
@@ -1852,8 +1871,8 @@
 
 void RegisterSharedIdsCHROMIUM(GLuint namespace_id,
                                GLsizei n,
-                               uint32 ids_shm_id,
-                               uint32 ids_shm_offset) {
+                               uint32_t ids_shm_id,
+                               uint32_t ids_shm_offset) {
   gles2::cmds::RegisterSharedIdsCHROMIUM* c =
       GetCmdSpace<gles2::cmds::RegisterSharedIdsCHROMIUM>();
   if (c) {
@@ -1862,8 +1881,8 @@
 }
 
 void EnableFeatureCHROMIUM(GLuint bucket_id,
-                           uint32 result_shm_id,
-                           uint32 result_shm_offset) {
+                           uint32_t result_shm_id,
+                           uint32_t result_shm_offset) {
   gles2::cmds::EnableFeatureCHROMIUM* c =
       GetCmdSpace<gles2::cmds::EnableFeatureCHROMIUM>();
   if (c) {
@@ -1878,7 +1897,7 @@
   }
 }
 
-void GetRequestableExtensionsCHROMIUM(uint32 bucket_id) {
+void GetRequestableExtensionsCHROMIUM(uint32_t bucket_id) {
   gles2::cmds::GetRequestableExtensionsCHROMIUM* c =
       GetCmdSpace<gles2::cmds::GetRequestableExtensionsCHROMIUM>();
   if (c) {
@@ -1886,7 +1905,7 @@
   }
 }
 
-void RequestExtensionCHROMIUM(uint32 bucket_id) {
+void RequestExtensionCHROMIUM(uint32_t bucket_id) {
   gles2::cmds::RequestExtensionCHROMIUM* c =
       GetCmdSpace<gles2::cmds::RequestExtensionCHROMIUM>();
   if (c) {
@@ -1894,11 +1913,11 @@
   }
 }
 
-void GetMultipleIntegervCHROMIUM(uint32 pnames_shm_id,
-                                 uint32 pnames_shm_offset,
+void GetMultipleIntegervCHROMIUM(uint32_t pnames_shm_id,
+                                 uint32_t pnames_shm_offset,
                                  GLuint count,
-                                 uint32 results_shm_id,
-                                 uint32 results_shm_offset,
+                                 uint32_t results_shm_id,
+                                 uint32_t results_shm_offset,
                                  GLsizeiptr size) {
   gles2::cmds::GetMultipleIntegervCHROMIUM* c =
       GetCmdSpace<gles2::cmds::GetMultipleIntegervCHROMIUM>();
@@ -1912,7 +1931,7 @@
   }
 }
 
-void GetProgramInfoCHROMIUM(GLuint program, uint32 bucket_id) {
+void GetProgramInfoCHROMIUM(GLuint program, uint32_t bucket_id) {
   gles2::cmds::GetProgramInfoCHROMIUM* c =
       GetCmdSpace<gles2::cmds::GetProgramInfoCHROMIUM>();
   if (c) {
@@ -1920,7 +1939,7 @@
   }
 }
 
-void GetTranslatedShaderSourceANGLE(GLuint shader, uint32 bucket_id) {
+void GetTranslatedShaderSourceANGLE(GLuint shader, uint32_t bucket_id) {
   gles2::cmds::GetTranslatedShaderSourceANGLE* c =
       GetCmdSpace<gles2::cmds::GetTranslatedShaderSourceANGLE>();
   if (c) {
@@ -1993,8 +2012,8 @@
 }
 
 void ProduceTextureCHROMIUM(GLenum target,
-                            uint32 mailbox_shm_id,
-                            uint32 mailbox_shm_offset) {
+                            uint32_t mailbox_shm_id,
+                            uint32_t mailbox_shm_offset) {
   gles2::cmds::ProduceTextureCHROMIUM* c =
       GetCmdSpace<gles2::cmds::ProduceTextureCHROMIUM>();
   if (c) {
@@ -2003,7 +2022,7 @@
 }
 
 void ProduceTextureCHROMIUMImmediate(GLenum target, const GLbyte* mailbox) {
-  const uint32 size =
+  const uint32_t size =
       gles2::cmds::ProduceTextureCHROMIUMImmediate::ComputeSize();
   gles2::cmds::ProduceTextureCHROMIUMImmediate* c =
       GetImmediateCmdSpaceTotalSize<
@@ -2014,8 +2033,8 @@
 }
 
 void ConsumeTextureCHROMIUM(GLenum target,
-                            uint32 mailbox_shm_id,
-                            uint32 mailbox_shm_offset) {
+                            uint32_t mailbox_shm_id,
+                            uint32_t mailbox_shm_offset) {
   gles2::cmds::ConsumeTextureCHROMIUM* c =
       GetCmdSpace<gles2::cmds::ConsumeTextureCHROMIUM>();
   if (c) {
@@ -2024,7 +2043,7 @@
 }
 
 void ConsumeTextureCHROMIUMImmediate(GLenum target, const GLbyte* mailbox) {
-  const uint32 size =
+  const uint32_t size =
       gles2::cmds::ConsumeTextureCHROMIUMImmediate::ComputeSize();
   gles2::cmds::ConsumeTextureCHROMIUMImmediate* c =
       GetImmediateCmdSpaceTotalSize<
@@ -2036,9 +2055,9 @@
 
 void BindUniformLocationCHROMIUM(GLuint program,
                                  GLint location,
-                                 uint32 name_shm_id,
-                                 uint32 name_shm_offset,
-                                 uint32 data_size) {
+                                 uint32_t name_shm_id,
+                                 uint32_t name_shm_offset,
+                                 uint32_t data_size) {
   gles2::cmds::BindUniformLocationCHROMIUM* c =
       GetCmdSpace<gles2::cmds::BindUniformLocationCHROMIUM>();
   if (c) {
@@ -2048,7 +2067,7 @@
 
 void BindUniformLocationCHROMIUMBucket(GLuint program,
                                        GLint location,
-                                       uint32 name_bucket_id) {
+                                       uint32_t name_bucket_id) {
   gles2::cmds::BindUniformLocationCHROMIUMBucket* c =
       GetCmdSpace<gles2::cmds::BindUniformLocationCHROMIUMBucket>();
   if (c) {
@@ -2096,11 +2115,11 @@
                                 GLsizei height,
                                 GLenum format,
                                 GLenum type,
-                                uint32 data_shm_id,
-                                uint32 data_shm_offset,
-                                uint32 async_upload_token,
-                                uint32 sync_data_shm_id,
-                                uint32 sync_data_shm_offset) {
+                                uint32_t data_shm_id,
+                                uint32_t data_shm_offset,
+                                uint32_t async_upload_token,
+                                uint32_t sync_data_shm_id,
+                                uint32_t sync_data_shm_offset) {
   gles2::cmds::AsyncTexSubImage2DCHROMIUM* c =
       GetCmdSpace<gles2::cmds::AsyncTexSubImage2DCHROMIUM>();
   if (c) {
@@ -2128,11 +2147,11 @@
                              GLint border,
                              GLenum format,
                              GLenum type,
-                             uint32 pixels_shm_id,
-                             uint32 pixels_shm_offset,
-                             uint32 async_upload_token,
-                             uint32 sync_data_shm_id,
-                             uint32 sync_data_shm_offset) {
+                             uint32_t pixels_shm_id,
+                             uint32_t pixels_shm_offset,
+                             uint32_t async_upload_token,
+                             uint32_t sync_data_shm_id,
+                             uint32_t sync_data_shm_offset) {
   gles2::cmds::AsyncTexImage2DCHROMIUM* c =
       GetCmdSpace<gles2::cmds::AsyncTexImage2DCHROMIUM>();
   if (c) {
@@ -2170,8 +2189,8 @@
 
 void DiscardFramebufferEXT(GLenum target,
                            GLsizei count,
-                           uint32 attachments_shm_id,
-                           uint32 attachments_shm_offset) {
+                           uint32_t attachments_shm_id,
+                           uint32_t attachments_shm_offset) {
   gles2::cmds::DiscardFramebufferEXT* c =
       GetCmdSpace<gles2::cmds::DiscardFramebufferEXT>();
   if (c) {
@@ -2182,7 +2201,7 @@
 void DiscardFramebufferEXTImmediate(GLenum target,
                                     GLsizei count,
                                     const GLenum* attachments) {
-  const uint32 size =
+  const uint32_t size =
       gles2::cmds::DiscardFramebufferEXTImmediate::ComputeSize(count);
   gles2::cmds::DiscardFramebufferEXTImmediate* c =
       GetImmediateCmdSpaceTotalSize<
@@ -2208,7 +2227,9 @@
   }
 }
 
-void DrawBuffersEXT(GLsizei count, uint32 bufs_shm_id, uint32 bufs_shm_offset) {
+void DrawBuffersEXT(GLsizei count,
+                    uint32_t bufs_shm_id,
+                    uint32_t bufs_shm_offset) {
   gles2::cmds::DrawBuffersEXT* c = GetCmdSpace<gles2::cmds::DrawBuffersEXT>();
   if (c) {
     c->Init(count, bufs_shm_id, bufs_shm_offset);
@@ -2216,7 +2237,8 @@
 }
 
 void DrawBuffersEXTImmediate(GLsizei count, const GLenum* bufs) {
-  const uint32 size = gles2::cmds::DrawBuffersEXTImmediate::ComputeSize(count);
+  const uint32_t size =
+      gles2::cmds::DrawBuffersEXTImmediate::ComputeSize(count);
   gles2::cmds::DrawBuffersEXTImmediate* c =
       GetImmediateCmdSpaceTotalSize<gles2::cmds::DrawBuffersEXTImmediate>(size);
   if (c) {
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 3fe999a..6d5edd2 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -6,24 +6,24 @@
 
 #include "gpu/command_buffer/client/gles2_implementation.h"
 
+#include <GLES2/gl2ext.h>
+#include <GLES2/gl2extchromium.h>
 #include <algorithm>
+#include <limits>
 #include <map>
 #include <queue>
 #include <set>
-#include <limits>
 #include <sstream>
 #include <string>
-#include <GLES2/gl2ext.h>
-#include <GLES2/gl2extchromium.h>
 #include "base/bind.h"
 #include "gpu/command_buffer/client/buffer_tracker.h"
+#include "gpu/command_buffer/client/gpu_control.h"
 #include "gpu/command_buffer/client/gpu_memory_buffer_tracker.h"
 #include "gpu/command_buffer/client/program_info_manager.h"
 #include "gpu/command_buffer/client/query_tracker.h"
 #include "gpu/command_buffer/client/transfer_buffer.h"
 #include "gpu/command_buffer/client/vertex_array_object_manager.h"
 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
-#include "gpu/command_buffer/common/gpu_control.h"
 #include "gpu/command_buffer/common/trace_event.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 
@@ -32,8 +32,8 @@
 #endif
 
 #if defined(GPU_CLIENT_DEBUG)
-#include "ui/gl/gl_switches.h"
 #include "base/command_line.h"
+#include "ui/gl/gl_switches.h"
 #endif
 
 namespace gpu {
@@ -2189,7 +2189,8 @@
       case GL_EXTENSIONS:
         str += std::string(str.empty() ? "" : " ") +
             "GL_CHROMIUM_flipy "
-            "GL_EXT_unpack_subimage";
+            "GL_EXT_unpack_subimage "
+            "GL_CHROMIUM_map_sub";
         if (capabilities_.map_image) {
           // The first space character is intentional.
           str += " GL_CHROMIUM_map_image";
@@ -3948,8 +3949,10 @@
   return gpu_control_->InsertSyncPoint();
 }
 
-GLuint GLES2Implementation::CreateImageCHROMIUMHelper(
-    GLsizei width, GLsizei height, GLenum internalformat) {
+GLuint GLES2Implementation::CreateImageCHROMIUMHelper(GLsizei width,
+                                                      GLsizei height,
+                                                      GLenum internalformat,
+                                                      GLenum usage) {
   if (width <= 0) {
     SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "width <= 0");
     return 0;
@@ -3965,7 +3968,7 @@
 
   // Create new buffer.
   GLuint buffer_id = gpu_memory_buffer_tracker_->CreateBuffer(
-      width, height, internalformat);
+      width, height, internalformat, usage);
   if (buffer_id == 0) {
     SetGLError(GL_OUT_OF_MEMORY, "glCreateImageCHROMIUM", "out of GPU memory.");
     return 0;
@@ -3973,14 +3976,18 @@
   return buffer_id;
 }
 
-GLuint GLES2Implementation::CreateImageCHROMIUM(
-    GLsizei width, GLsizei height, GLenum internalformat) {
+GLuint GLES2Implementation::CreateImageCHROMIUM(GLsizei width,
+                                                GLsizei height,
+                                                GLenum internalformat,
+                                                GLenum usage) {
   GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateImageCHROMIUM("
-      << width << ", "
-      << height << ", "
-      << GLES2Util::GetStringTextureInternalFormat(internalformat) << ")");
-  GLuint image_id = CreateImageCHROMIUMHelper(width, height, internalformat);
+  GPU_CLIENT_LOG(
+      "[" << GetLogPrefix() << "] glCreateImageCHROMIUM(" << width << ", "
+          << height << ", "
+          << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", "
+          << GLES2Util::GetStringTextureInternalFormat(usage) << ")");
+  GLuint image_id =
+      CreateImageCHROMIUMHelper(width, height, internalformat, usage);
   CheckGLError();
   return image_id;
 }
@@ -4031,47 +4038,28 @@
   CheckGLError();
 }
 
-void* GLES2Implementation::MapImageCHROMIUMHelper(GLuint image_id,
-                                                  GLenum access) {
+void* GLES2Implementation::MapImageCHROMIUMHelper(GLuint image_id) {
   gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer(
       image_id);
   if (!gpu_buffer) {
     SetGLError(GL_INVALID_OPERATION, "glMapImageCHROMIUM", "invalid image");
     return NULL;
   }
-  gfx::GpuMemoryBuffer::AccessMode mode;
-  switch(access) {
-    case GL_WRITE_ONLY:
-      mode = gfx::GpuMemoryBuffer::WRITE_ONLY;
-      break;
-    case GL_READ_ONLY:
-      mode = gfx::GpuMemoryBuffer::READ_ONLY;
-      break;
-    case GL_READ_WRITE:
-      mode = gfx::GpuMemoryBuffer::READ_WRITE;
-      break;
-    default:
-      SetGLError(GL_INVALID_ENUM, "glMapImageCHROMIUM",
-                 "invalid GPU access mode");
-      return NULL;
-  }
 
   if (gpu_buffer->IsMapped()) {
     SetGLError(GL_INVALID_OPERATION, "glMapImageCHROMIUM", "already mapped");
     return NULL;
   }
 
-  return gpu_buffer->Map(mode);
+  return gpu_buffer->Map();
 }
 
-void* GLES2Implementation::MapImageCHROMIUM(
-    GLuint image_id, GLenum access) {
+void* GLES2Implementation::MapImageCHROMIUM(GLuint image_id) {
   GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapImageCHROMIUM("
-      << image_id << ", "
-      << GLES2Util::GetStringEnum(access) << ")");
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapImageCHROMIUM(" << image_id
+                     << ")");
 
-  void* mapped = MapImageCHROMIUMHelper(image_id, access);
+  void* mapped = MapImageCHROMIUMHelper(image_id);
   CheckGLError();
   return mapped;
 }
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 45fb270..7404e90 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -543,10 +543,12 @@
       GLenum target, GLintptr offset, GLsizeiptr size, const void* data,
       ScopedTransferBufferPtr* buffer);
 
-  GLuint CreateImageCHROMIUMHelper(
-      GLsizei width, GLsizei height, GLenum internalformat);
+  GLuint CreateImageCHROMIUMHelper(GLsizei width,
+                                   GLsizei height,
+                                   GLenum internalformat,
+                                   GLenum usage);
   void DestroyImageCHROMIUMHelper(GLuint image_id);
-  void* MapImageCHROMIUMHelper(GLuint image_id, GLenum access);
+  void* MapImageCHROMIUMHelper(GLuint image_id);
   void UnmapImageCHROMIUMHelper(GLuint image_id);
   void GetImageParameterivCHROMIUMHelper(
       GLuint image_id, GLenum pname, GLint* params);
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 8b5d22b..b24819b 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -572,7 +572,7 @@
 
 virtual GLboolean UnmapBufferCHROMIUM(GLuint target) OVERRIDE;
 
-virtual void* MapImageCHROMIUM(GLuint image_id, GLenum access) OVERRIDE;
+virtual void* MapImageCHROMIUM(GLuint image_id) OVERRIDE;
 
 virtual void UnmapImageCHROMIUM(GLuint image_id) OVERRIDE;
 
@@ -619,7 +619,8 @@
 
 virtual GLuint CreateImageCHROMIUM(GLsizei width,
                                    GLsizei height,
-                                   GLenum internalformat) OVERRIDE;
+                                   GLenum internalformat,
+                                   GLenum usage) OVERRIDE;
 
 virtual void DestroyImageCHROMIUM(GLuint image_id) OVERRIDE;
 
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
index 3ac35cd..88cf0f4 100644
--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -587,7 +587,7 @@
   WaitForCmd();
   result->CopyResult(params);
   GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
       GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
     }
   });
@@ -617,7 +617,7 @@
   WaitForCmd();
   result->CopyResult(params);
   GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
       GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
     }
   });
@@ -642,7 +642,7 @@
   WaitForCmd();
   result->CopyResult(params);
   GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
       GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
     }
   });
@@ -677,7 +677,7 @@
   WaitForCmd();
   result->CopyResult(params);
   GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
       GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
     }
   });
@@ -703,7 +703,7 @@
   WaitForCmd();
   result->CopyResult(params);
   GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
       GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
     }
   });
@@ -731,7 +731,7 @@
   WaitForCmd();
   result->CopyResult(params);
   GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
       GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
     }
   });
@@ -788,7 +788,7 @@
   WaitForCmd();
   result->CopyResult(params);
   GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
       GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
     }
   });
@@ -816,7 +816,7 @@
   WaitForCmd();
   result->CopyResult(params);
   GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
       GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
     }
   });
@@ -899,7 +899,7 @@
   WaitForCmd();
   result->CopyResult(params);
   GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
       GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
     }
   });
@@ -929,7 +929,7 @@
   WaitForCmd();
   result->CopyResult(params);
   GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
       GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
     }
   });
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index 5ab9f0e..b76caa2 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -2722,7 +2722,8 @@
   const char* expected_str =
       "foobar "
       "GL_CHROMIUM_flipy "
-      "GL_EXT_unpack_subimage";
+      "GL_EXT_unpack_subimage "
+      "GL_CHROMIUM_map_sub";
   const char kBad = 0x12;
   struct Cmds {
     cmd::SetBucketSize set_bucket_size1;
@@ -3249,9 +3250,9 @@
   };
 
   GLsizei max = std::numeric_limits<GLsizei>::max();
-  EXPECT_CALL(*gpu_control_, CreateGpuMemoryBuffer(max, max, _, _))
+  EXPECT_CALL(*gpu_control_, CreateGpuMemoryBuffer(max, max, _, _, _))
       .WillOnce(Return(static_cast<gfx::GpuMemoryBuffer*>(NULL)));
-  gl_->CreateImageCHROMIUM(max, max, 0);
+  gl_->CreateImageCHROMIUM(max, max, 0, GL_IMAGE_MAP_CHROMIUM);
   // The context should be lost.
   Cmds expected;
   expected.cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB);
@@ -3267,9 +3268,9 @@
   };
 
   GLsizei max = std::numeric_limits<GLsizei>::max();
-  EXPECT_CALL(*gpu_control_, CreateGpuMemoryBuffer(max, max, _, _))
+  EXPECT_CALL(*gpu_control_, CreateGpuMemoryBuffer(max, max, _, _, _))
       .WillOnce(Return(static_cast<gfx::GpuMemoryBuffer*>(NULL)));
-  gl_->CreateImageCHROMIUM(max, max, 0);
+  gl_->CreateImageCHROMIUM(max, max, 0, GL_IMAGE_MAP_CHROMIUM);
   // The context should not be lost.
   EXPECT_TRUE(NoCommandsWritten());
 }
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
index d568a19..e6bd8a1 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -133,7 +133,7 @@
   expected.cmd.Init(1, result1.id, result1.offset);
 
   EXPECT_CALL(*command_buffer(), OnFlush())
-      .WillOnce(SetMemory(result1.ptr, uint32(1)))
+      .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
       .RetiresOnSaturation();
 
   GLboolean result = gl_->CheckFramebufferStatus(1);
@@ -772,7 +772,7 @@
   expected.cmd.Init(1, result1.id, result1.offset);
 
   EXPECT_CALL(*command_buffer(), OnFlush())
-      .WillOnce(SetMemory(result1.ptr, uint32(1)))
+      .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
       .RetiresOnSaturation();
 
   GLboolean result = gl_->IsBuffer(1);
@@ -791,7 +791,7 @@
   expected.cmd.Init(1, result1.id, result1.offset);
 
   EXPECT_CALL(*command_buffer(), OnFlush())
-      .WillOnce(SetMemory(result1.ptr, uint32(1)))
+      .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
       .RetiresOnSaturation();
 
   GLboolean result = gl_->IsEnabled(1);
@@ -810,7 +810,7 @@
   expected.cmd.Init(1, result1.id, result1.offset);
 
   EXPECT_CALL(*command_buffer(), OnFlush())
-      .WillOnce(SetMemory(result1.ptr, uint32(1)))
+      .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
       .RetiresOnSaturation();
 
   GLboolean result = gl_->IsFramebuffer(1);
@@ -829,7 +829,7 @@
   expected.cmd.Init(1, result1.id, result1.offset);
 
   EXPECT_CALL(*command_buffer(), OnFlush())
-      .WillOnce(SetMemory(result1.ptr, uint32(1)))
+      .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
       .RetiresOnSaturation();
 
   GLboolean result = gl_->IsProgram(1);
@@ -848,7 +848,7 @@
   expected.cmd.Init(1, result1.id, result1.offset);
 
   EXPECT_CALL(*command_buffer(), OnFlush())
-      .WillOnce(SetMemory(result1.ptr, uint32(1)))
+      .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
       .RetiresOnSaturation();
 
   GLboolean result = gl_->IsRenderbuffer(1);
@@ -867,7 +867,7 @@
   expected.cmd.Init(1, result1.id, result1.offset);
 
   EXPECT_CALL(*command_buffer(), OnFlush())
-      .WillOnce(SetMemory(result1.ptr, uint32(1)))
+      .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
       .RetiresOnSaturation();
 
   GLboolean result = gl_->IsShader(1);
@@ -886,7 +886,7 @@
   expected.cmd.Init(1, result1.id, result1.offset);
 
   EXPECT_CALL(*command_buffer(), OnFlush())
-      .WillOnce(SetMemory(result1.ptr, uint32(1)))
+      .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
       .RetiresOnSaturation();
 
   GLboolean result = gl_->IsTexture(1);
@@ -1679,7 +1679,7 @@
   expected.cmd.Init(1, result1.id, result1.offset);
 
   EXPECT_CALL(*command_buffer(), OnFlush())
-      .WillOnce(SetMemory(result1.ptr, uint32(1)))
+      .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
       .RetiresOnSaturation();
 
   GLboolean result = gl_->IsVertexArrayOES(1);
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index 0135c3e..eee1899 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -381,7 +381,7 @@
 virtual GLboolean EnableFeatureCHROMIUM(const char* feature) = 0;
 virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) = 0;
 virtual GLboolean UnmapBufferCHROMIUM(GLuint target) = 0;
-virtual void* MapImageCHROMIUM(GLuint image_id, GLenum access) = 0;
+virtual void* MapImageCHROMIUM(GLuint image_id) = 0;
 virtual void UnmapImageCHROMIUM(GLuint image_id) = 0;
 virtual void* MapBufferSubDataCHROMIUM(GLuint target,
                                        GLintptr offset,
@@ -415,7 +415,8 @@
 virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) = 0;
 virtual GLuint CreateImageCHROMIUM(GLsizei width,
                                    GLsizei height,
-                                   GLenum internalformat) = 0;
+                                   GLenum internalformat,
+                                   GLenum usage) = 0;
 virtual void DestroyImageCHROMIUM(GLuint image_id) = 0;
 virtual void GetImageParameterivCHROMIUM(GLuint image_id,
                                          GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
index ad0e29c..3053e3b 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -412,7 +412,7 @@
 virtual GLboolean EnableFeatureCHROMIUM(const char* feature) OVERRIDE;
 virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) OVERRIDE;
 virtual GLboolean UnmapBufferCHROMIUM(GLuint target) OVERRIDE;
-virtual void* MapImageCHROMIUM(GLuint image_id, GLenum access) OVERRIDE;
+virtual void* MapImageCHROMIUM(GLuint image_id) OVERRIDE;
 virtual void UnmapImageCHROMIUM(GLuint image_id) OVERRIDE;
 virtual void* MapBufferSubDataCHROMIUM(GLuint target,
                                        GLintptr offset,
@@ -446,7 +446,8 @@
 virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) OVERRIDE;
 virtual GLuint CreateImageCHROMIUM(GLsizei width,
                                    GLsizei height,
-                                   GLenum internalformat) OVERRIDE;
+                                   GLenum internalformat,
+                                   GLenum usage) OVERRIDE;
 virtual void DestroyImageCHROMIUM(GLuint image_id) OVERRIDE;
 virtual void GetImageParameterivCHROMIUM(GLuint image_id,
                                          GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
index f894c1c..6497717 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -675,8 +675,7 @@
 GLboolean GLES2InterfaceStub::UnmapBufferCHROMIUM(GLuint /* target */) {
   return 0;
 }
-void* GLES2InterfaceStub::MapImageCHROMIUM(GLuint /* image_id */,
-                                           GLenum /* access */) {
+void* GLES2InterfaceStub::MapImageCHROMIUM(GLuint /* image_id */) {
   return 0;
 }
 void GLES2InterfaceStub::UnmapImageCHROMIUM(GLuint /* image_id */) {
@@ -728,7 +727,8 @@
 }
 GLuint GLES2InterfaceStub::CreateImageCHROMIUM(GLsizei /* width */,
                                                GLsizei /* height */,
-                                               GLenum /* internalformat */) {
+                                               GLenum /* internalformat */,
+                                               GLenum /* usage */) {
   return 0;
 }
 void GLES2InterfaceStub::DestroyImageCHROMIUM(GLuint /* image_id */) {
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
index a6f8256..e05fc00 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -412,7 +412,7 @@
 virtual GLboolean EnableFeatureCHROMIUM(const char* feature) OVERRIDE;
 virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) OVERRIDE;
 virtual GLboolean UnmapBufferCHROMIUM(GLuint target) OVERRIDE;
-virtual void* MapImageCHROMIUM(GLuint image_id, GLenum access) OVERRIDE;
+virtual void* MapImageCHROMIUM(GLuint image_id) OVERRIDE;
 virtual void UnmapImageCHROMIUM(GLuint image_id) OVERRIDE;
 virtual void* MapBufferSubDataCHROMIUM(GLuint target,
                                        GLintptr offset,
@@ -446,7 +446,8 @@
 virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) OVERRIDE;
 virtual GLuint CreateImageCHROMIUM(GLsizei width,
                                    GLsizei height,
-                                   GLenum internalformat) OVERRIDE;
+                                   GLenum internalformat,
+                                   GLenum usage) OVERRIDE;
 virtual void DestroyImageCHROMIUM(GLuint image_id) OVERRIDE;
 virtual void GetImageParameterivCHROMIUM(GLuint image_id,
                                          GLenum pname,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
index 9bb0b60..988668e 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -1178,10 +1178,9 @@
   return gl_->UnmapBufferCHROMIUM(target);
 }
 
-void* GLES2TraceImplementation::MapImageCHROMIUM(GLuint image_id,
-                                                 GLenum access) {
+void* GLES2TraceImplementation::MapImageCHROMIUM(GLuint image_id) {
   TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::MapImageCHROMIUM");
-  return gl_->MapImageCHROMIUM(image_id, access);
+  return gl_->MapImageCHROMIUM(image_id);
 }
 
 void GLES2TraceImplementation::UnmapImageCHROMIUM(GLuint image_id) {
@@ -1272,9 +1271,10 @@
 
 GLuint GLES2TraceImplementation::CreateImageCHROMIUM(GLsizei width,
                                                      GLsizei height,
-                                                     GLenum internalformat) {
+                                                     GLenum internalformat,
+                                                     GLenum usage) {
   TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CreateImageCHROMIUM");
-  return gl_->CreateImageCHROMIUM(width, height, internalformat);
+  return gl_->CreateImageCHROMIUM(width, height, internalformat, usage);
 }
 
 void GLES2TraceImplementation::DestroyImageCHROMIUM(GLuint image_id) {
diff --git a/gpu/command_buffer/client/gpu_control.h b/gpu/command_buffer/client/gpu_control.h
new file mode 100644
index 0000000..a78641e
--- /dev/null
+++ b/gpu/command_buffer/client/gpu_control.h
@@ -0,0 +1,74 @@
+// 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.
+
+#ifndef GPU_COMMAND_BUFFER_CLIENT_GPU_CONTROL_H_
+#define GPU_COMMAND_BUFFER_CLIENT_GPU_CONTROL_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "gpu/command_buffer/common/capabilities.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/gpu_export.h"
+
+namespace gfx {
+class GpuMemoryBuffer;
+}
+
+namespace gpu {
+struct ManagedMemoryStats;
+
+// Common interface for GpuControl implementations.
+class GPU_EXPORT GpuControl {
+ public:
+  GpuControl() {}
+  virtual ~GpuControl() {}
+
+  virtual Capabilities GetCapabilities() = 0;
+
+  // Create a gpu memory buffer of the given dimensions and format. Returns
+  // its ID or -1 on error.
+  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(
+      size_t width,
+      size_t height,
+      unsigned internalformat,
+      unsigned usage,
+      int32_t* id) = 0;
+
+  // Destroy a gpu memory buffer. The ID must be positive.
+  virtual void DestroyGpuMemoryBuffer(int32_t id) = 0;
+
+  // Inserts a sync point, returning its ID. Sync point IDs are global and can
+  // be used for cross-context synchronization.
+  virtual uint32_t InsertSyncPoint() = 0;
+
+  // Runs |callback| when a sync point is reached.
+  virtual void SignalSyncPoint(uint32_t sync_point,
+                               const base::Closure& callback) = 0;
+
+  // Runs |callback| when a query created via glCreateQueryEXT() has cleared
+  // passed the glEndQueryEXT() point.
+  virtual void SignalQuery(uint32_t query, const base::Closure& callback) = 0;
+
+  virtual void SetSurfaceVisible(bool visible) = 0;
+
+  virtual void SendManagedMemoryStats(const ManagedMemoryStats& stats) = 0;
+
+  // Invokes the callback once the context has been flushed.
+  virtual void Echo(const base::Closure& callback) = 0;
+
+  // Attaches an external stream to the texture given by |texture_id| and
+  // returns a stream identifier.
+  virtual uint32_t CreateStreamTexture(uint32_t texture_id) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GpuControl);
+};
+
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_CLIENT_GPU_CONTROL_H_
diff --git a/gpu/command_buffer/client/gpu_memory_buffer_factory.h b/gpu/command_buffer/client/gpu_memory_buffer_factory.h
index 42dde40..c7f0b4c 100644
--- a/gpu/command_buffer/client/gpu_memory_buffer_factory.h
+++ b/gpu/command_buffer/client/gpu_memory_buffer_factory.h
@@ -15,10 +15,10 @@
 
 class GPU_EXPORT GpuMemoryBufferFactory {
  public:
-  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(
-      size_t width,
-      size_t height,
-      unsigned internalformat) = 0;
+  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(size_t width,
+                                                      size_t height,
+                                                      unsigned internalformat,
+                                                      unsigned usage) = 0;
 
  protected:
   virtual ~GpuMemoryBufferFactory() {}
diff --git a/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc b/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc
index 863028a..9ffe0e3 100644
--- a/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc
+++ b/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc
@@ -6,7 +6,7 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/common/gpu_control.h"
+#include "gpu/command_buffer/client/gpu_control.h"
 
 namespace gpu {
 namespace gles2 {
@@ -21,12 +21,14 @@
   }
 }
 
-int32 GpuMemoryBufferTracker::CreateBuffer(
-    size_t width, size_t height, int32 internalformat) {
+int32 GpuMemoryBufferTracker::CreateBuffer(size_t width,
+                                           size_t height,
+                                           int32 internalformat,
+                                           int32 usage) {
   int32 image_id = 0;
   DCHECK(gpu_control_);
   gfx::GpuMemoryBuffer* buffer = gpu_control_->CreateGpuMemoryBuffer(
-      width, height, internalformat, &image_id);
+      width, height, internalformat, usage, &image_id);
   if (!buffer)
     return 0;
 
diff --git a/gpu/command_buffer/client/gpu_memory_buffer_tracker.h b/gpu/command_buffer/client/gpu_memory_buffer_tracker.h
index 8415881..25ec949 100644
--- a/gpu/command_buffer/client/gpu_memory_buffer_tracker.h
+++ b/gpu/command_buffer/client/gpu_memory_buffer_tracker.h
@@ -24,7 +24,10 @@
   explicit GpuMemoryBufferTracker(GpuControl* gpu_control);
   virtual ~GpuMemoryBufferTracker();
 
-  int32 CreateBuffer(size_t width, size_t height, int32 internalformat);
+  int32 CreateBuffer(size_t width,
+                     size_t height,
+                     int32 internalformat,
+                     int32 usage);
   gfx::GpuMemoryBuffer* GetBuffer(int32 image_id);
   void RemoveBuffer(int32 image_id);
 
diff --git a/gpu/command_buffer/client/mapped_memory.h b/gpu/command_buffer/client/mapped_memory.h
index e7f62ff..789e69c 100644
--- a/gpu/command_buffer/client/mapped_memory.h
+++ b/gpu/command_buffer/client/mapped_memory.h
@@ -5,11 +5,13 @@
 #ifndef GPU_COMMAND_BUFFER_CLIENT_MAPPED_MEMORY_H_
 #define GPU_COMMAND_BUFFER_CLIENT_MAPPED_MEMORY_H_
 
+#include <stdint.h>
+
 #include "base/bind.h"
+#include "base/macros.h"
 #include "base/memory/scoped_vector.h"
 #include "gpu/command_buffer/client/fenced_allocator.h"
 #include "gpu/command_buffer/common/buffer.h"
-#include "gpu/command_buffer/common/types.h"
 #include "gpu/gpu_export.h"
 
 namespace gpu {
@@ -19,7 +21,7 @@
 // Manages a shared memory segment.
 class GPU_EXPORT MemoryChunk {
  public:
-  MemoryChunk(int32 shm_id,
+  MemoryChunk(int32_t shm_id,
               scoped_refptr<gpu::Buffer> shm,
               CommandBufferHelper* helper,
               const base::Closure& poll_callback);
@@ -42,7 +44,7 @@
   }
 
   // The shared memory id for this chunk.
-  int32 shm_id() const {
+  int32_t shm_id() const {
     return shm_id_;
   }
 
@@ -93,7 +95,7 @@
   bool IsInChunk(void* pointer) const {
     return pointer >= shm_->memory() &&
            pointer <
-               reinterpret_cast<const int8*>(shm_->memory()) + shm_->size();
+               reinterpret_cast<const int8_t*>(shm_->memory()) + shm_->size();
   }
 
   // Returns true of any memory in this chunk is in use.
@@ -106,7 +108,7 @@
   }
 
  private:
-  int32 shm_id_;
+  int32_t shm_id_;
   scoped_refptr<gpu::Buffer> shm_;
   FencedAllocatorWrapper allocator_;
 
@@ -144,7 +146,7 @@
   // Returns:
   //   pointer to allocated block of memory. NULL if failure.
   void* Alloc(
-      unsigned int size, int32* shm_id, unsigned int* shm_offset);
+      unsigned int size, int32_t* shm_id, unsigned int* shm_offset);
 
   // Frees a block of memory.
   //
@@ -158,7 +160,7 @@
   // Parameters:
   //   pointer: the pointer to the memory block to free.
   //   token: the token value to wait for before re-using the memory.
-  void FreePendingToken(void* pointer, int32 token);
+  void FreePendingToken(void* pointer, int32_t token);
 
   // Free Any Shared memory that is not in use.
   void FreeUnused();
diff --git a/gpu/command_buffer/client/ring_buffer.cc b/gpu/command_buffer/client/ring_buffer.cc
index 25f6342..813bb34 100644
--- a/gpu/command_buffer/client/ring_buffer.cc
+++ b/gpu/command_buffer/client/ring_buffer.cc
@@ -13,13 +13,16 @@
 
 namespace gpu {
 
-RingBuffer::RingBuffer(
-    Offset base_offset, unsigned int size, CommandBufferHelper* helper)
+RingBuffer::RingBuffer(unsigned int alignment, Offset base_offset,
+                       unsigned int size, CommandBufferHelper* helper,
+                       void* base)
     : helper_(helper),
       base_offset_(base_offset),
       size_(size),
       free_offset_(0),
-      in_use_offset_(0) {
+      in_use_offset_(0),
+      alignment_(alignment),
+      base_(static_cast<int8*>(base) - base_offset) {
 }
 
 RingBuffer::~RingBuffer() {
@@ -49,13 +52,16 @@
   blocks_.pop_front();
 }
 
-RingBuffer::Offset RingBuffer::Alloc(unsigned int size) {
+void* RingBuffer::Alloc(unsigned int size) {
   DCHECK_LE(size, size_) << "attempt to allocate more than maximum memory";
   DCHECK(blocks_.empty() || blocks_.back().state != IN_USE)
       << "Attempt to alloc another block before freeing the previous.";
   // Similarly to malloc, an allocation of 0 allocates at least 1 byte, to
   // return different pointers every time.
   if (size == 0) size = 1;
+  // Allocate rounded to alignment size so that the offsets are always
+  // memory-aligned.
+  size = RoundToAlignment(size);
 
   // Wait until there is enough room.
   while (size > GetLargestFreeSizeNoWaiting()) {
@@ -74,11 +80,12 @@
   if (free_offset_ == size_) {
     free_offset_ = 0;
   }
-  return offset + base_offset_;
+  return GetPointer(offset + base_offset_);
 }
 
-void RingBuffer::FreePendingToken(RingBuffer::Offset offset,
+void RingBuffer::FreePendingToken(void* pointer,
                                   unsigned int token) {
+  Offset offset = GetOffset(pointer);
   offset -= base_offset_;
   DCHECK(!blocks_.empty()) << "no allocations to free";
   for (Container::reverse_iterator it = blocks_.rbegin();
diff --git a/gpu/command_buffer/client/ring_buffer.h b/gpu/command_buffer/client/ring_buffer.h
index 81f1cdd..dfe16f7 100644
--- a/gpu/command_buffer/client/ring_buffer.h
+++ b/gpu/command_buffer/client/ring_buffer.h
@@ -10,7 +10,7 @@
 #include <deque>
 
 #include "base/logging.h"
-#include "gpu/command_buffer/common/types.h"
+#include "base/macros.h"
 #include "gpu/gpu_export.h"
 
 namespace gpu {
@@ -25,11 +25,13 @@
 
   // Creates a RingBuffer.
   // Parameters:
+  //   alignment: Alignment for allocations.
   //   base_offset: The offset of the start of the buffer.
   //   size: The size of the buffer in bytes.
   //   helper: A CommandBufferHelper for dealing with tokens.
-  RingBuffer(
-      Offset base_offset, unsigned int size, CommandBufferHelper* helper);
+  //   base: The physical address that corresponds to base_offset.
+  RingBuffer(unsigned int alignment, Offset base_offset,
+             unsigned int size, CommandBufferHelper* helper, void* base);
 
   ~RingBuffer();
 
@@ -41,16 +43,16 @@
   //   size: the size of the memory block to allocate.
   //
   // Returns:
-  //   the offset of the allocated memory block.
-  Offset Alloc(unsigned int size);
+  //   the pointer to the allocated memory block.
+  void* Alloc(unsigned int size);
 
   // Frees a block of memory, pending the passage of a token. That memory won't
   // be re-allocated until the token has passed through the command stream.
   //
   // Parameters:
-  //   offset: the offset of the memory block to free.
+  //   pointer: the pointer to the memory block to free.
   //   token: the token value to wait for before re-using the memory.
-  void FreePendingToken(Offset offset, unsigned int token);
+  void FreePendingToken(void* pointer, unsigned int token);
 
   // Gets the size of the largest free block that is available without waiting.
   unsigned int GetLargestFreeSizeNoWaiting();
@@ -62,6 +64,22 @@
     return size_;
   }
 
+  // Gets a pointer to a memory block given the base memory and the offset.
+  void* GetPointer(RingBuffer::Offset offset) const {
+    return static_cast<int8*>(base_) + offset;
+  }
+
+  // Gets the offset to a memory block given the base memory and the address.
+  RingBuffer::Offset GetOffset(void* pointer) const {
+    return static_cast<int8*>(pointer) - static_cast<int8*>(base_);
+  }
+
+  // Rounds the given size to the alignment in use.
+  unsigned int RoundToAlignment(unsigned int size) {
+    return (size + alignment_ - 1) & ~(alignment_ - 1);
+  }
+
+
  private:
   enum State {
     IN_USE,
@@ -105,92 +123,13 @@
   // Range between in_use_mark and free_mark is in use.
   Offset in_use_offset_;
 
-  DISALLOW_IMPLICIT_CONSTRUCTORS(RingBuffer);
-};
+  // Alignment for allocations.
+  unsigned int alignment_;
 
-// This class functions just like RingBuffer, but its API uses pointers
-// instead of offsets.
-class RingBufferWrapper {
- public:
-  // Parameters:
-  //   base_offset: The offset to the start of the buffer
-  //   size: The size of the buffer in bytes.
-  //   helper: A CommandBufferHelper for dealing with tokens.
-  //   base: The physical address that corresponds to base_offset.
-  RingBufferWrapper(RingBuffer::Offset base_offset,
-                    unsigned int size,
-                    CommandBufferHelper* helper,
-                    void* base)
-      : allocator_(base_offset, size, helper),
-        base_(static_cast<int8*>(base) - base_offset) {
-  }
-
-  // Allocates a block of memory. If the buffer is out of directly available
-  // memory, this function may wait until memory that was freed "pending a
-  // token" can be re-used.
-  //
-  // Parameters:
-  //   size: the size of the memory block to allocate.
-  //
-  // Returns:
-  //   the pointer to the allocated memory block, or NULL if out of
-  //   memory.
-  void* Alloc(unsigned int size) {
-    RingBuffer::Offset offset = allocator_.Alloc(size);
-    return GetPointer(offset);
-  }
-
-  // Allocates a block of memory. If the buffer is out of directly available
-  // memory, this function may wait until memory that was freed "pending a
-  // token" can be re-used.
-  // This is a type-safe version of Alloc, returning a typed pointer.
-  //
-  // Parameters:
-  //   count: the number of elements to allocate.
-  //
-  // Returns:
-  //   the pointer to the allocated memory block, or NULL if out of
-  //   memory.
-  template <typename T> T* AllocTyped(unsigned int count) {
-    return static_cast<T*>(Alloc(count * sizeof(T)));
-  }
-
-  // Frees a block of memory, pending the passage of a token. That memory won't
-  // be re-allocated until the token has passed through the command stream.
-  //
-  // Parameters:
-  //   pointer: the pointer to the memory block to free.
-  //   token: the token value to wait for before re-using the memory.
-  void FreePendingToken(void* pointer, unsigned int token) {
-    DCHECK(pointer);
-    allocator_.FreePendingToken(GetOffset(pointer), token);
-  }
-
-  // Gets a pointer to a memory block given the base memory and the offset.
-  void* GetPointer(RingBuffer::Offset offset) const {
-    return static_cast<int8*>(base_) + offset;
-  }
-
-  // Gets the offset to a memory block given the base memory and the address.
-  RingBuffer::Offset GetOffset(void* pointer) const {
-    return static_cast<int8*>(pointer) - static_cast<int8*>(base_);
-  }
-
-  // Gets the size of the largest free block that is available without waiting.
-  unsigned int GetLargestFreeSizeNoWaiting() {
-    return allocator_.GetLargestFreeSizeNoWaiting();
-  }
-
-  // Gets the size of the largest free block that can be allocated if the
-  // caller can wait.
-  unsigned int GetLargestFreeOrPendingSize() {
-    return allocator_.GetLargestFreeOrPendingSize();
-  }
-
- private:
-  RingBuffer allocator_;
+  // The physical address that corresponds to base_offset.
   void* base_;
-  DISALLOW_IMPLICIT_CONSTRUCTORS(RingBufferWrapper);
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(RingBuffer);
 };
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/client/ring_buffer_test.cc b/gpu/command_buffer/client/ring_buffer_test.cc
index e46ec43..0b58e3a 100644
--- a/gpu/command_buffer/client/ring_buffer_test.cc
+++ b/gpu/command_buffer/client/ring_buffer_test.cc
@@ -35,6 +35,7 @@
  protected:
   static const unsigned int kBaseOffset = 128;
   static const unsigned int kBufferSize = 1024;
+  static const unsigned int kAlignment = 4;
 
   void RunPendingSetToken() {
     for (std::vector<const void*>::iterator it = set_token_arguments_.begin();
@@ -107,6 +108,8 @@
   std::vector<const void*> set_token_arguments_;
   bool delay_set_token_;
 
+  scoped_ptr<int8[]> buffer_;
+  int8* buffer_start_;
 };
 
 #ifndef _MSC_VER
@@ -122,7 +125,11 @@
  protected:
   virtual void SetUp() {
     BaseRingBufferTest::SetUp();
-    allocator_.reset(new RingBuffer(kBaseOffset, kBufferSize, helper_.get()));
+
+    buffer_.reset(new int8[kBufferSize + kBaseOffset]);
+    buffer_start_ = buffer_.get() + kBaseOffset;
+    allocator_.reset(new RingBuffer(kAlignment, kBaseOffset, kBufferSize,
+                                    helper_.get(), buffer_start_));
   }
 
   virtual void TearDown() {
@@ -140,12 +147,12 @@
   const unsigned int kSize = 16;
   EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize());
   EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSizeNoWaiting());
-  RingBuffer::Offset offset = allocator_->Alloc(kSize);
-  EXPECT_GE(kBufferSize, offset - kBaseOffset + kSize);
+  void* pointer = allocator_->Alloc(kSize);
+  EXPECT_GE(kBufferSize, allocator_->GetOffset(pointer) - kBaseOffset + kSize);
   EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize());
   EXPECT_EQ(kBufferSize - kSize, allocator_->GetLargestFreeSizeNoWaiting());
   int32 token = helper_->InsertToken();
-  allocator_->FreePendingToken(offset, token);
+  allocator_->FreePendingToken(pointer, token);
 }
 
 // Checks the free-pending-token mechanism.
@@ -158,10 +165,11 @@
   // Allocate several buffers to fill in the memory.
   int32 tokens[kAllocCount];
   for (unsigned int ii = 0; ii < kAllocCount; ++ii) {
-    RingBuffer::Offset offset = allocator_->Alloc(kSize);
-    EXPECT_GE(kBufferSize, offset - kBaseOffset + kSize);
+    void* pointer = allocator_->Alloc(kSize);
+    EXPECT_GE(kBufferSize,
+              allocator_->GetOffset(pointer) - kBaseOffset + kSize);
     tokens[ii] = helper_->InsertToken();
-    allocator_->FreePendingToken(offset, tokens[ii]);
+    allocator_->FreePendingToken(pointer, tokens[ii]);
   }
 
   EXPECT_EQ(kBufferSize - (kSize * kAllocCount),
@@ -171,131 +179,38 @@
 
   // This allocation will need to reclaim the space freed above, so that should
   // process the commands until a token is passed.
-  RingBuffer::Offset offset1 = allocator_->Alloc(kSize);
-  EXPECT_EQ(kBaseOffset, offset1);
+  void* pointer1 = allocator_->Alloc(kSize);
+  EXPECT_EQ(kBaseOffset, allocator_->GetOffset(pointer1));
 
   // Check that the token has indeed passed.
   EXPECT_LE(tokens[0], GetToken());
 
-  allocator_->FreePendingToken(offset1, helper_->InsertToken());
+  allocator_->FreePendingToken(pointer1, helper_->InsertToken());
 }
 
 // Tests GetLargestFreeSizeNoWaiting
 TEST_F(RingBufferTest, TestGetLargestFreeSizeNoWaiting) {
   EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSizeNoWaiting());
 
-  RingBuffer::Offset offset = allocator_->Alloc(kBufferSize);
+  void* pointer = allocator_->Alloc(kBufferSize);
   EXPECT_EQ(0u, allocator_->GetLargestFreeSizeNoWaiting());
-  allocator_->FreePendingToken(offset, helper_->InsertToken());
+  allocator_->FreePendingToken(pointer, helper_->InsertToken());
 }
 
 TEST_F(RingBufferTest, TestFreeBug) {
   // The first and second allocations must not match.
-  const unsigned int kAlloc1 = 10;
+  const unsigned int kAlloc1 = 3*kAlignment;
   const unsigned int kAlloc2 = 20;
-  RingBuffer::Offset offset = allocator_->Alloc(kAlloc1);
+  void* pointer = allocator_->Alloc(kAlloc1);
   EXPECT_EQ(kBufferSize - kAlloc1, allocator_->GetLargestFreeSizeNoWaiting());
-  allocator_->FreePendingToken(offset, helper_.get()->InsertToken());
-  offset = allocator_->Alloc(kAlloc2);
+  allocator_->FreePendingToken(pointer, helper_.get()->InsertToken());
+  pointer = allocator_->Alloc(kAlloc2);
   EXPECT_EQ(kBufferSize - kAlloc1 - kAlloc2,
             allocator_->GetLargestFreeSizeNoWaiting());
-  allocator_->FreePendingToken(offset, helper_.get()->InsertToken());
-  offset = allocator_->Alloc(kBufferSize);
+  allocator_->FreePendingToken(pointer, helper_.get()->InsertToken());
+  pointer = allocator_->Alloc(kBufferSize);
   EXPECT_EQ(0u, allocator_->GetLargestFreeSizeNoWaiting());
-  allocator_->FreePendingToken(offset, helper_.get()->InsertToken());
-}
-
-// Test fixture for RingBufferWrapper test - Creates a
-// RingBufferWrapper, using a CommandBufferHelper with a mock
-// AsyncAPIInterface for its interface (calling it directly, not through the
-// RPC mechanism), making sure Noops are ignored and SetToken are properly
-// forwarded to the engine.
-class RingBufferWrapperTest : public BaseRingBufferTest {
- protected:
-  virtual void SetUp() {
-    BaseRingBufferTest::SetUp();
-
-    // Though allocating this buffer isn't strictly necessary, it makes
-    // allocations point to valid addresses, so they could be used for
-    // something.
-    buffer_.reset(new int8[kBufferSize + kBaseOffset]);
-    buffer_start_ = buffer_.get() + kBaseOffset;
-    allocator_.reset(new RingBufferWrapper(
-        kBaseOffset, kBufferSize, helper_.get(), buffer_start_));
-  }
-
-  virtual void TearDown() {
-    // If the GpuScheduler posts any tasks, this forces them to run.
-    base::MessageLoop::current()->RunUntilIdle();
-
-    BaseRingBufferTest::TearDown();
-  }
-
-  scoped_ptr<RingBufferWrapper> allocator_;
-  scoped_ptr<int8[]> buffer_;
-  int8* buffer_start_;
-};
-
-// Checks basic alloc and free.
-TEST_F(RingBufferWrapperTest, TestBasic) {
-  const unsigned int kSize = 16;
-  void* pointer = allocator_->Alloc(kSize);
-  ASSERT_TRUE(pointer);
-  EXPECT_LE(buffer_start_, static_cast<int8*>(pointer));
-  EXPECT_GE(kBufferSize, static_cast<int8*>(pointer) - buffer_start_ + kSize);
-
-  allocator_->FreePendingToken(pointer, helper_->InsertToken());
-
-  int8* pointer_int8 = allocator_->AllocTyped<int8>(kSize);
-  ASSERT_TRUE(pointer_int8);
-  EXPECT_LE(buffer_start_, pointer_int8);
-  EXPECT_GE(buffer_start_ + kBufferSize, pointer_int8 + kSize);
-  allocator_->FreePendingToken(pointer_int8, helper_->InsertToken());
-
-  unsigned int* pointer_uint = allocator_->AllocTyped<unsigned int>(kSize);
-  ASSERT_TRUE(pointer_uint);
-  EXPECT_LE(buffer_start_, reinterpret_cast<int8*>(pointer_uint));
-  EXPECT_GE(buffer_start_ + kBufferSize,
-            reinterpret_cast<int8* >(pointer_uint + kSize));
-
-  // Check that it did allocate kSize * sizeof(unsigned int). We can't tell
-  // directly, except from the remaining size.
-  EXPECT_EQ(kBufferSize - kSize - kSize - kSize * sizeof(*pointer_uint),
-            allocator_->GetLargestFreeSizeNoWaiting());
-  allocator_->FreePendingToken(pointer_uint, helper_->InsertToken());
-}
-
-// Checks the free-pending-token mechanism.
-TEST_F(RingBufferWrapperTest, TestFreePendingToken) {
-  const unsigned int kSize = 16;
-  const unsigned int kAllocCount = kBufferSize / kSize;
-  CHECK(kAllocCount * kSize == kBufferSize);
-
-  delay_set_token_ = true;
-  // Allocate several buffers to fill in the memory.
-  int32 tokens[kAllocCount];
-  for (unsigned int ii = 0; ii < kAllocCount; ++ii) {
-    void* pointer = allocator_->Alloc(kSize);
-    EXPECT_TRUE(pointer != NULL);
-    tokens[ii] = helper_->InsertToken();
-    allocator_->FreePendingToken(pointer, helper_->InsertToken());
-  }
-
-  EXPECT_EQ(kBufferSize - (kSize * kAllocCount),
-            allocator_->GetLargestFreeSizeNoWaiting());
-
-  RunPendingSetToken();
-
-  // This allocation will need to reclaim the space freed above, so that should
-  // process the commands until the token is passed.
-  void* pointer1 = allocator_->Alloc(kSize);
-  EXPECT_EQ(buffer_start_, static_cast<int8*>(pointer1));
-
-  // Check that the token has indeed passed.
-  EXPECT_LE(tokens[0], GetToken());
-
-  allocator_->FreePendingToken(pointer1, helper_->InsertToken());
-  EXPECT_LE(command_buffer_->GetLastState().token, helper_->InsertToken());
+  allocator_->FreePendingToken(pointer, helper_.get()->InsertToken());
 }
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/client/transfer_buffer.cc b/gpu/command_buffer/client/transfer_buffer.cc
index 70c4bf0..c5ce3d5 100644
--- a/gpu/command_buffer/client/transfer_buffer.cc
+++ b/gpu/command_buffer/client/transfer_buffer.cc
@@ -13,9 +13,6 @@
 
 namespace gpu {
 
-AlignedRingBuffer::~AlignedRingBuffer() {
-}
-
 TransferBuffer::TransferBuffer(
     CommandBufferHelper* helper)
     : helper_(helper),
@@ -92,9 +89,8 @@
     if (id != -1) {
       DCHECK(buffer);
       buffer_ = buffer;
-      ring_buffer_.reset(new AlignedRingBuffer(
+      ring_buffer_.reset(new RingBuffer(
           alignment_,
-          id,
           result_size_,
           buffer_->size() - result_size_,
           helper_,
diff --git a/gpu/command_buffer/client/transfer_buffer.h b/gpu/command_buffer/client/transfer_buffer.h
index 28971d7..348ad32 100644
--- a/gpu/command_buffer/client/transfer_buffer.h
+++ b/gpu/command_buffer/client/transfer_buffer.h
@@ -16,40 +16,6 @@
 
 class CommandBufferHelper;
 
-// Wraps RingBufferWrapper to provide aligned allocations.
-class AlignedRingBuffer : public RingBufferWrapper {
- public:
-  AlignedRingBuffer(
-      unsigned int alignment,
-      int32 shm_id,
-      RingBuffer::Offset base_offset,
-      unsigned int size,
-      CommandBufferHelper* helper,
-      void* base)
-      : RingBufferWrapper(base_offset, size, helper, base),
-        alignment_(alignment),
-        shm_id_(shm_id) {
-  }
-  ~AlignedRingBuffer();
-
-  // Hiding Alloc from RingBufferWrapper
-  void* Alloc(unsigned int size) {
-    return RingBufferWrapper::Alloc(RoundToAlignment(size));
-  }
-
-  int32 GetShmId() const {
-    return shm_id_;
-  }
-
- private:
-  unsigned int RoundToAlignment(unsigned int size) {
-    return (size + alignment_ - 1) & ~(alignment_ - 1);
-  }
-
-  unsigned int alignment_;
-  int32 shm_id_;
-};
-
 // Interface for managing the transfer buffer.
 class GPU_EXPORT TransferBufferInterface {
  public:
@@ -120,7 +86,7 @@
   void AllocateRingBuffer(unsigned int size);
 
   CommandBufferHelper* helper_;
-  scoped_ptr<AlignedRingBuffer> ring_buffer_;
+  scoped_ptr<RingBuffer> ring_buffer_;
 
   // size reserved for results
   unsigned int result_size_;
diff --git a/gpu/command_buffer/client/transfer_buffer_unittest.cc b/gpu/command_buffer/client/transfer_buffer_unittest.cc
index 7201477..9f3b51e 100644
--- a/gpu/command_buffer/client/transfer_buffer_unittest.cc
+++ b/gpu/command_buffer/client/transfer_buffer_unittest.cc
@@ -181,6 +181,17 @@
   transfer_buffer_->FreePendingToken(ptr, 1);
 }
 
+TEST_F(TransferBufferTest, MemoryAlignmentAfterZeroAllocation) {
+  Initialize(32u);
+  void* ptr = transfer_buffer_->Alloc(0);
+  EXPECT_EQ((reinterpret_cast<uintptr_t>(ptr) & (kAlignment - 1)), 0u);
+  transfer_buffer_->FreePendingToken(ptr, -1);
+  // Check that the pointer is aligned on the following allocation.
+  ptr = transfer_buffer_->Alloc(4);
+  EXPECT_EQ((reinterpret_cast<uintptr_t>(ptr) & (kAlignment - 1)), 0u);
+  transfer_buffer_->FreePendingToken(ptr, 1);
+}
+
 TEST_F(TransferBufferTest, Flush) {
   Initialize(16u);
   unsigned int size_allocated = 0;
diff --git a/gpu/command_buffer/client/vertex_array_object_manager.h b/gpu/command_buffer/client/vertex_array_object_manager.h
index d5b07ec..34f630d 100644
--- a/gpu/command_buffer/client/vertex_array_object_manager.h
+++ b/gpu/command_buffer/client/vertex_array_object_manager.h
@@ -6,10 +6,11 @@
 #define GPU_COMMAND_BUFFER_CLIENT_VERTEX_ARRAY_OBJECT_MANAGER_H_
 
 #include <GLES2/gl2.h>
+
 #include "base/containers/hash_tables.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "gles2_impl_export.h"
-#include "gpu/command_buffer/common/types.h"
 
 namespace gpu {
 namespace gles2 {
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt
index f8d8bc5..0c20a5b 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -178,7 +178,7 @@
 GL_APICALL GLboolean    GL_APIENTRY glEnableFeatureCHROMIUM (const char* feature);
 GL_APICALL void*        GL_APIENTRY glMapBufferCHROMIUM (GLuint target, GLenum access);
 GL_APICALL GLboolean    GL_APIENTRY glUnmapBufferCHROMIUM (GLuint target);
-GL_APICALL void*        GL_APIENTRY glMapImageCHROMIUM (GLuint image_id, GLenum access);
+GL_APICALL void*        GL_APIENTRY glMapImageCHROMIUM (GLuint image_id);
 GL_APICALL void         GL_APIENTRY glUnmapImageCHROMIUM (GLuint image_id);
 
 GL_APICALL void*        GL_APIENTRY glMapBufferSubDataCHROMIUM (GLuint target, GLintptrNotNegative offset, GLsizeiptr size, GLenum access);
@@ -192,7 +192,7 @@
 GL_APICALL void         GL_APIENTRY glGetMultipleIntegervCHROMIUM (const GLenum* pnames, GLuint count, GLint* results, GLsizeiptr size);
 GL_APICALL void         GL_APIENTRY glGetProgramInfoCHROMIUM (GLidProgram program, GLsizeiNotNegative bufsize, GLsizei* size, void* info);
 GL_APICALL GLuint       GL_APIENTRY glCreateStreamTextureCHROMIUM (GLuint texture);
-GL_APICALL GLuint       GL_APIENTRY glCreateImageCHROMIUM (GLsizei width, GLsizei height, GLenum internalformat);
+GL_APICALL GLuint       GL_APIENTRY glCreateImageCHROMIUM (GLsizei width, GLsizei height, GLenum internalformat, GLenum usage);
 GL_APICALL void         GL_APIENTRY glDestroyImageCHROMIUM (GLuint image_id);
 GL_APICALL void         GL_APIENTRY glGetImageParameterivCHROMIUM (GLuint image_id, GLenum pname, GLint* params);
 GL_APICALL void         GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLidShader shader, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* source);
diff --git a/gpu/command_buffer/common/buffer.h b/gpu/command_buffer/common/buffer.h
index 5a31035..d8a8356 100644
--- a/gpu/command_buffer/common/buffer.h
+++ b/gpu/command_buffer/common/buffer.h
@@ -5,10 +5,10 @@
 #ifndef GPU_COMMAND_BUFFER_COMMON_BUFFER_H_
 #define GPU_COMMAND_BUFFER_COMMON_BUFFER_H_
 
+#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/shared_memory.h"
-#include "gpu/command_buffer/common/types.h"
 #include "gpu/gpu_export.h"
 
 namespace base {
diff --git a/gpu/command_buffer/common/capabilities.h b/gpu/command_buffer/common/capabilities.h
index 81e3d55..ba5cf4b 100644
--- a/gpu/command_buffer/common/capabilities.h
+++ b/gpu/command_buffer/common/capabilities.h
@@ -21,8 +21,6 @@
   bool texture_storage;
   bool discard_framebuffer;
   bool sync_query;
-
-  // Capabilities below are not populated by GLES2Decoder.
   bool map_image;
 
   Capabilities();
diff --git a/gpu/command_buffer/common/cmd_buffer_common.h b/gpu/command_buffer/common/cmd_buffer_common.h
index ef6b932..828731b 100644
--- a/gpu/command_buffer/common/cmd_buffer_common.h
+++ b/gpu/command_buffer/common/cmd_buffer_common.h
@@ -8,10 +8,11 @@
 #define GPU_COMMAND_BUFFER_COMMON_CMD_BUFFER_COMMON_H_
 
 #include <stddef.h>
+#include <stdint.h>
 
 #include "base/logging.h"
+#include "base/macros.h"
 #include "gpu/command_buffer/common/bitfield_helpers.h"
-#include "gpu/command_buffer/common/types.h"
 #include "gpu/gpu_export.h"
 
 namespace gpu {
@@ -29,24 +30,24 @@
 
 // Computes the number of command buffer entries needed for a certain size. In
 // other words it rounds up to a multiple of entries.
-inline uint32 ComputeNumEntries(size_t size_in_bytes) {
-  return static_cast<uint32>(
-      (size_in_bytes + sizeof(uint32) - 1) / sizeof(uint32));  // NOLINT
+inline uint32_t ComputeNumEntries(size_t size_in_bytes) {
+  return static_cast<uint32_t>(
+      (size_in_bytes + sizeof(uint32_t) - 1) / sizeof(uint32_t));  // NOLINT
 }
 
 // Rounds up to a multiple of entries in bytes.
 inline size_t RoundSizeToMultipleOfEntries(size_t size_in_bytes) {
-  return ComputeNumEntries(size_in_bytes) * sizeof(uint32);  // NOLINT
+  return ComputeNumEntries(size_in_bytes) * sizeof(uint32_t);  // NOLINT
 }
 
 // Struct that defines the command header in the command buffer.
 struct CommandHeader {
-  Uint32 size:21;
-  Uint32 command:11;
+  uint32_t size:21;
+  uint32_t command:11;
 
-  GPU_EXPORT static const int32 kMaxSize = (1 << 21) - 1;
+  GPU_EXPORT static const int32_t kMaxSize = (1 << 21) - 1;
 
-  void Init(uint32 _command, int32 _size) {
+  void Init(uint32_t _command, int32_t _size) {
     DCHECK_LE(_size, kMaxSize);
     command = _command;
     size = _size;
@@ -62,7 +63,7 @@
 
   // Sets the header by a size in bytes of the immediate data after the command.
   template <typename T>
-  void SetCmdBySize(uint32 size_of_data_in_bytes) {
+  void SetCmdBySize(uint32_t size_of_data_in_bytes) {
     COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
     Init(T::kCmdId,
          ComputeNumEntries(sizeof(T) + size_of_data_in_bytes));  // NOLINT
@@ -70,7 +71,7 @@
 
   // Sets the header by a size in bytes.
   template <typename T>
-  void SetCmdByTotalSize(uint32 size_in_bytes) {
+  void SetCmdByTotalSize(uint32_t size_in_bytes) {
     COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
     DCHECK_GE(size_in_bytes, sizeof(T));  // NOLINT
     Init(T::kCmdId, ComputeNumEntries(size_in_bytes));
@@ -82,8 +83,8 @@
 // Union that defines possible command buffer entries.
 union CommandBufferEntry {
   CommandHeader value_header;
-  Uint32 value_uint32;
-  Int32 value_int32;
+  uint32_t value_uint32;
+  int32_t value_int32;
   float value_float;
 };
 
@@ -123,7 +124,7 @@
 //   cmd: Address of command.
 //   size_of_data_in_bytes: Size of the data for the command.
 template <typename T>
-void* NextImmediateCmdAddress(void* cmd, uint32 size_of_data_in_bytes) {
+void* NextImmediateCmdAddress(void* cmd, uint32_t size_of_data_in_bytes) {
   COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
   return reinterpret_cast<char*>(cmd) + sizeof(T) +   // NOLINT
       RoundSizeToMultipleOfEntries(size_of_data_in_bytes);
@@ -135,7 +136,8 @@
 //   cmd: Address of command.
 //   size_of_cmd_in_bytes: Size of the cmd and data.
 template <typename T>
-void* NextImmediateCmdAddressTotalSize(void* cmd, uint32 total_size_in_bytes) {
+void* NextImmediateCmdAddressTotalSize(void* cmd,
+                                       uint32_t total_size_in_bytes) {
   COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
   DCHECK_GE(total_size_in_bytes, sizeof(T));  // NOLINT
   return reinterpret_cast<char*>(cmd) +
@@ -181,18 +183,18 @@
   typedef Noop ValueType;
   static const CommandId kCmdId = kNoop;
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
-  static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  void SetHeader(uint32 skip_count) {
+  void SetHeader(uint32_t skip_count) {
     DCHECK_GT(skip_count, 0u);
     header.Init(kCmdId, skip_count);
   }
 
-  void Init(uint32 skip_count) {
+  void Init(uint32_t skip_count) {
     SetHeader(skip_count);
   }
 
-  static void* Set(void* cmd, uint32 skip_count) {
+  static void* Set(void* cmd, uint32_t skip_count) {
     static_cast<ValueType*>(cmd)->Init(skip_count);
     return NextImmediateCmdAddress<ValueType>(
         cmd, skip_count * sizeof(CommandBufferEntry));  // NOLINT
@@ -210,23 +212,23 @@
   typedef SetToken ValueType;
   static const CommandId kCmdId = kSetToken;
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
-  static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
   void SetHeader() {
     header.SetCmd<ValueType>();
   }
 
-  void Init(uint32 _token) {
+  void Init(uint32_t _token) {
     SetHeader();
     token = _token;
   }
-  static void* Set(void* cmd, uint32 token) {
+  static void* Set(void* cmd, uint32_t token) {
     static_cast<ValueType*>(cmd)->Init(token);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   CommandHeader header;
-  uint32 token;
+  uint32_t token;
 };
 
 COMPILE_ASSERT(sizeof(SetToken) == 8, Sizeof_SetToken_is_not_8);
@@ -251,25 +253,25 @@
   typedef SetBucketSize ValueType;
   static const CommandId kCmdId = kSetBucketSize;
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
-  static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
   void SetHeader() {
     header.SetCmd<ValueType>();
   }
 
-  void Init(uint32 _bucket_id, uint32 _size) {
+  void Init(uint32_t _bucket_id, uint32_t _size) {
     SetHeader();
     bucket_id = _bucket_id;
     size = _size;
   }
-  static void* Set(void* cmd, uint32 _bucket_id, uint32 _size) {
+  static void* Set(void* cmd, uint32_t _bucket_id, uint32_t _size) {
     static_cast<ValueType*>(cmd)->Init(_bucket_id, _size);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   CommandHeader header;
-  uint32 bucket_id;
-  uint32 size;
+  uint32_t bucket_id;
+  uint32_t size;
 };
 
 COMPILE_ASSERT(sizeof(SetBucketSize) == 12, Sizeof_SetBucketSize_is_not_8);
@@ -287,17 +289,17 @@
   typedef SetBucketData ValueType;
   static const CommandId kCmdId = kSetBucketData;
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
-  static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
   void SetHeader() {
     header.SetCmd<ValueType>();
   }
 
-  void Init(uint32 _bucket_id,
-            uint32 _offset,
-            uint32 _size,
-            uint32 _shared_memory_id,
-            uint32 _shared_memory_offset) {
+  void Init(uint32_t _bucket_id,
+            uint32_t _offset,
+            uint32_t _size,
+            uint32_t _shared_memory_id,
+            uint32_t _shared_memory_offset) {
     SetHeader();
     bucket_id = _bucket_id;
     offset = _offset;
@@ -306,11 +308,11 @@
     shared_memory_offset = _shared_memory_offset;
   }
   static void* Set(void* cmd,
-                   uint32 _bucket_id,
-                   uint32 _offset,
-                   uint32 _size,
-                   uint32 _shared_memory_id,
-                   uint32 _shared_memory_offset) {
+                   uint32_t _bucket_id,
+                   uint32_t _offset,
+                   uint32_t _size,
+                   uint32_t _shared_memory_id,
+                   uint32_t _shared_memory_offset) {
     static_cast<ValueType*>(cmd)->Init(
         _bucket_id,
         _offset,
@@ -321,11 +323,11 @@
   }
 
   CommandHeader header;
-  uint32 bucket_id;
-  uint32 offset;
-  uint32 size;
-  uint32 shared_memory_id;
-  uint32 shared_memory_offset;
+  uint32_t bucket_id;
+  uint32_t offset;
+  uint32_t size;
+  uint32_t shared_memory_id;
+  uint32_t shared_memory_offset;
 };
 
 COMPILE_ASSERT(sizeof(SetBucketData) == 24, Sizeof_SetBucketData_is_not_24);
@@ -349,24 +351,24 @@
   typedef SetBucketDataImmediate ValueType;
   static const CommandId kCmdId = kSetBucketDataImmediate;
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
-  static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  void SetHeader(uint32 size) {
+  void SetHeader(uint32_t size) {
     header.SetCmdBySize<ValueType>(size);
   }
 
-  void Init(uint32 _bucket_id,
-            uint32 _offset,
-            uint32 _size) {
+  void Init(uint32_t _bucket_id,
+            uint32_t _offset,
+            uint32_t _size) {
     SetHeader(_size);
     bucket_id = _bucket_id;
     offset = _offset;
     size = _size;
   }
   static void* Set(void* cmd,
-                   uint32 _bucket_id,
-                   uint32 _offset,
-                   uint32 _size) {
+                   uint32_t _bucket_id,
+                   uint32_t _offset,
+                   uint32_t _size) {
     static_cast<ValueType*>(cmd)->Init(
         _bucket_id,
         _offset,
@@ -375,9 +377,9 @@
   }
 
   CommandHeader header;
-  uint32 bucket_id;
-  uint32 offset;
-  uint32 size;
+  uint32_t bucket_id;
+  uint32_t offset;
+  uint32_t size;
 };
 
 COMPILE_ASSERT(sizeof(SetBucketDataImmediate) == 16,
@@ -405,20 +407,20 @@
   typedef GetBucketStart ValueType;
   static const CommandId kCmdId = kGetBucketStart;
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
-  static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  typedef uint32 Result;
+  typedef uint32_t Result;
 
   void SetHeader() {
     header.SetCmd<ValueType>();
   }
 
-  void Init(uint32 _bucket_id,
-            uint32 _result_memory_id,
-            uint32 _result_memory_offset,
-            uint32 _data_memory_size,
-            uint32 _data_memory_id,
-            uint32 _data_memory_offset) {
+  void Init(uint32_t _bucket_id,
+            uint32_t _result_memory_id,
+            uint32_t _result_memory_offset,
+            uint32_t _data_memory_size,
+            uint32_t _data_memory_id,
+            uint32_t _data_memory_offset) {
     SetHeader();
     bucket_id = _bucket_id;
     result_memory_id = _result_memory_id;
@@ -428,12 +430,12 @@
     data_memory_offset = _data_memory_offset;
   }
   static void* Set(void* cmd,
-                   uint32 _bucket_id,
-                   uint32 _result_memory_id,
-                   uint32 _result_memory_offset,
-                   uint32 _data_memory_size,
-                   uint32 _data_memory_id,
-                   uint32 _data_memory_offset) {
+                   uint32_t _bucket_id,
+                   uint32_t _result_memory_id,
+                   uint32_t _result_memory_offset,
+                   uint32_t _data_memory_size,
+                   uint32_t _data_memory_id,
+                   uint32_t _data_memory_offset) {
     static_cast<ValueType*>(cmd)->Init(
         _bucket_id,
         _result_memory_id,
@@ -445,12 +447,12 @@
   }
 
   CommandHeader header;
-  uint32 bucket_id;
-  uint32 result_memory_id;
-  uint32 result_memory_offset;
-  uint32 data_memory_size;
-  uint32 data_memory_id;
-  uint32 data_memory_offset;
+  uint32_t bucket_id;
+  uint32_t result_memory_id;
+  uint32_t result_memory_offset;
+  uint32_t data_memory_size;
+  uint32_t data_memory_id;
+  uint32_t data_memory_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetBucketStart) == 28, Sizeof_GetBucketStart_is_not_28);
@@ -475,17 +477,17 @@
   typedef GetBucketData ValueType;
   static const CommandId kCmdId = kGetBucketData;
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
-  static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
   void SetHeader() {
     header.SetCmd<ValueType>();
   }
 
-  void Init(uint32 _bucket_id,
-            uint32 _offset,
-            uint32 _size,
-            uint32 _shared_memory_id,
-            uint32 _shared_memory_offset) {
+  void Init(uint32_t _bucket_id,
+            uint32_t _offset,
+            uint32_t _size,
+            uint32_t _shared_memory_id,
+            uint32_t _shared_memory_offset) {
     SetHeader();
     bucket_id = _bucket_id;
     offset = _offset;
@@ -494,11 +496,11 @@
     shared_memory_offset = _shared_memory_offset;
   }
   static void* Set(void* cmd,
-                   uint32 _bucket_id,
-                   uint32 _offset,
-                   uint32 _size,
-                   uint32 _shared_memory_id,
-                   uint32 _shared_memory_offset) {
+                   uint32_t _bucket_id,
+                   uint32_t _offset,
+                   uint32_t _size,
+                   uint32_t _shared_memory_id,
+                   uint32_t _shared_memory_offset) {
     static_cast<ValueType*>(cmd)->Init(
         _bucket_id,
         _offset,
@@ -509,11 +511,11 @@
   }
 
   CommandHeader header;
-  uint32 bucket_id;
-  uint32 offset;
-  uint32 size;
-  uint32 shared_memory_id;
-  uint32 shared_memory_offset;
+  uint32_t bucket_id;
+  uint32_t offset;
+  uint32_t size;
+  uint32_t shared_memory_id;
+  uint32_t shared_memory_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetBucketData) == 24, Sizeof_GetBucketData_is_not_20);
diff --git a/gpu/command_buffer/common/constants.h b/gpu/command_buffer/common/constants.h
index 75ca374..054708f 100644
--- a/gpu/command_buffer/common/constants.h
+++ b/gpu/command_buffer/common/constants.h
@@ -5,11 +5,12 @@
 #ifndef GPU_COMMAND_BUFFER_COMMON_CONSTANTS_H_
 #define GPU_COMMAND_BUFFER_COMMON_CONSTANTS_H_
 
-#include "gpu/command_buffer/common/types.h"
+#include <stddef.h>
+#include <stdint.h>
 
 namespace gpu {
 
-typedef int32 CommandBufferOffset;
+typedef int32_t CommandBufferOffset;
 const CommandBufferOffset kInvalidCommandBufferOffset = -1;
 
 // This enum must stay in sync with NPDeviceContext3DError.
@@ -46,10 +47,10 @@
 
 // Invalid shared memory Id, returned by RegisterSharedMemory in case of
 // failure.
-const int32 kInvalidSharedMemoryId = -1;
+const int32_t kInvalidSharedMemoryId = -1;
 
 // Common Command Buffer shared memory transfer buffer ID.
-const int32 kCommandBufferSharedMemoryId = 4;
+const int32_t kCommandBufferSharedMemoryId = 4;
 
 // The size to set for the program cache.
 const size_t kDefaultMaxProgramCacheMemoryBytes = 6 * 1024 * 1024;
diff --git a/gpu/command_buffer/common/gles2_cmd_format.h b/gpu/command_buffer/common/gles2_cmd_format.h
index f11b1e9..79baf97 100644
--- a/gpu/command_buffer/common/gles2_cmd_format.h
+++ b/gpu/command_buffer/common/gles2_cmd_format.h
@@ -10,13 +10,14 @@
 
 #include <KHR/khrplatform.h>
 
+#include <stdint.h>
 #include <string.h>
 
 #include "base/atomicops.h"
+#include "base/macros.h"
 #include "gpu/command_buffer/common/bitfield_helpers.h"
 #include "gpu/command_buffer/common/cmd_buffer_common.h"
 #include "gpu/command_buffer/common/gles2_cmd_ids.h"
-#include "gpu/command_buffer/common/types.h"
 
 // GL types are forward declared to avoid including the GL headers. The problem
 // is determining which GL headers to include from code that is common to the
@@ -83,19 +84,19 @@
   // Returns the total size in bytes of the SizedResult for a given number of
   // results including the size field.
   static size_t ComputeSize(size_t num_results) {
-    return sizeof(T) * num_results + sizeof(uint32);  // NOLINT
+    return sizeof(T) * num_results + sizeof(uint32_t);  // NOLINT
   }
 
   // Returns the total size in bytes of the SizedResult for a given size of
   // results.
   static size_t ComputeSizeFromBytes(size_t size_of_result_in_bytes) {
-    return size_of_result_in_bytes + sizeof(uint32);  // NOLINT
+    return size_of_result_in_bytes + sizeof(uint32_t);  // NOLINT
   }
 
   // Returns the maximum number of results for a given buffer size.
-  static uint32 ComputeMaxResults(size_t size_of_buffer) {
-    return (size_of_buffer >= sizeof(uint32)) ?
-        ((size_of_buffer - sizeof(uint32)) / sizeof(T)) : 0;  // NOLINT
+  static uint32_t ComputeMaxResults(size_t size_of_buffer) {
+    return (size_of_buffer >= sizeof(uint32_t)) ?
+        ((size_of_buffer - sizeof(uint32_t)) / sizeof(T)) : 0;  // NOLINT
   }
 
   // Set the size for a given number of results.
@@ -104,7 +105,7 @@
   }
 
   // Get the number of elements in the result
-  int32 GetNumResults() const {
+  int32_t GetNumResults() const {
     return size / sizeof(T);  // NOLINT
   }
 
@@ -113,31 +114,31 @@
     memcpy(dst, &data, size);
   }
 
-  uint32 size;  // in bytes.
-  int32 data;  // this is just here to get an offset.
+  uint32_t size;  // in bytes.
+  int32_t data;  // this is just here to get an offset.
 };
 
-COMPILE_ASSERT(sizeof(SizedResult<int8>) == 8, SizedResult_size_not_8);
-COMPILE_ASSERT(offsetof(SizedResult<int8>, size) == 0,
+COMPILE_ASSERT(sizeof(SizedResult<int8_t>) == 8, SizedResult_size_not_8);
+COMPILE_ASSERT(offsetof(SizedResult<int8_t>, size) == 0,
                OffsetOf_SizedResult_size_not_0);
-COMPILE_ASSERT(offsetof(SizedResult<int8>, data) == 4,
+COMPILE_ASSERT(offsetof(SizedResult<int8_t>, data) == 4,
                OffsetOf_SizedResult_data_not_4);
 
 // The data for one attrib or uniform from GetProgramInfoCHROMIUM.
 struct ProgramInput {
-  uint32 type;             // The type (GL_VEC3, GL_MAT3, GL_SAMPLER_2D, etc.
-  int32 size;              // The size (how big the array is for uniforms)
-  uint32 location_offset;  // offset from ProgramInfoHeader to 'size' locations
-                           // for uniforms, 1 for attribs.
-  uint32 name_offset;      // offset from ProgrmaInfoHeader to start of name.
-  uint32 name_length;      // length of the name.
+  uint32_t type;             // The type (GL_VEC3, GL_MAT3, GL_SAMPLER_2D, etc.
+  int32_t size;              // The size (how big the array is for uniforms)
+  uint32_t location_offset;  // offset from ProgramInfoHeader to 'size'
+                             // locations for uniforms, 1 for attribs.
+  uint32_t name_offset;      // offset from ProgrmaInfoHeader to start of name.
+  uint32_t name_length;      // length of the name.
 };
 
 // The format of the bucket filled out by GetProgramInfoCHROMIUM
 struct ProgramInfoHeader {
-  uint32 link_status;
-  uint32 num_attribs;
-  uint32 num_uniforms;
+  uint32_t link_status;
+  uint32_t num_attribs;
+  uint32_t num_uniforms;
   // ProgramInput inputs[num_attribs + num_uniforms];
 };
 
@@ -149,7 +150,7 @@
   }
 
   base::subtle::Atomic32 process_count;
-  uint64 result;
+  uint64_t result;
 };
 
 struct AsyncUploadSync {
@@ -157,12 +158,12 @@
     base::subtle::Release_Store(&async_upload_token, 0);
   }
 
-  void SetAsyncUploadToken(uint32 token) {
+  void SetAsyncUploadToken(uint32_t token) {
     DCHECK_NE(token, 0u);
     base::subtle::Release_Store(&async_upload_token, token);
   }
 
-  bool HasAsyncUploadTokenPassed(uint32 token) {
+  bool HasAsyncUploadTokenPassed(uint32_t token) {
     DCHECK_NE(token, 0u);
     uint32_t current_token = base::subtle::Acquire_Load(&async_upload_token);
     return (current_token - token < 0x80000000);
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index c63282f..9461628 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -17,8 +17,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -34,7 +34,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 texture;
+  uint32_t texture;
 };
 
 COMPILE_ASSERT(sizeof(ActiveTexture) == 8, Sizeof_ActiveTexture_is_not_8);
@@ -49,8 +49,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -67,8 +67,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  uint32 shader;
+  uint32_t program;
+  uint32_t shader;
 };
 
 COMPILE_ASSERT(sizeof(AttachShader) == 12, Sizeof_AttachShader_is_not_12);
@@ -85,17 +85,17 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _program,
             GLuint _index,
-            uint32 _name_shm_id,
-            uint32 _name_shm_offset,
-            uint32 _data_size) {
+            uint32_t _name_shm_id,
+            uint32_t _name_shm_offset,
+            uint32_t _data_size) {
     SetHeader();
     program = _program;
     index = _index;
@@ -107,20 +107,20 @@
   void* Set(void* cmd,
             GLuint _program,
             GLuint _index,
-            uint32 _name_shm_id,
-            uint32 _name_shm_offset,
-            uint32 _data_size) {
+            uint32_t _name_shm_id,
+            uint32_t _name_shm_offset,
+            uint32_t _data_size) {
     static_cast<ValueType*>(cmd)
         ->Init(_program, _index, _name_shm_id, _name_shm_offset, _data_size);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  uint32 index;
-  uint32 name_shm_id;
-  uint32 name_shm_offset;
-  uint32 data_size;
+  uint32_t program;
+  uint32_t index;
+  uint32_t name_shm_id;
+  uint32_t name_shm_offset;
+  uint32_t data_size;
 };
 
 COMPILE_ASSERT(sizeof(BindAttribLocation) == 24,
@@ -144,28 +144,31 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _program, GLuint _index, uint32 _name_bucket_id) {
+  void Init(GLuint _program, GLuint _index, uint32_t _name_bucket_id) {
     SetHeader();
     program = _program;
     index = _index;
     name_bucket_id = _name_bucket_id;
   }
 
-  void* Set(void* cmd, GLuint _program, GLuint _index, uint32 _name_bucket_id) {
+  void* Set(void* cmd,
+            GLuint _program,
+            GLuint _index,
+            uint32_t _name_bucket_id) {
     static_cast<ValueType*>(cmd)->Init(_program, _index, _name_bucket_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  uint32 index;
-  uint32 name_bucket_id;
+  uint32_t program;
+  uint32_t index;
+  uint32_t name_bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(BindAttribLocationBucket) == 16,
@@ -185,8 +188,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -203,8 +206,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 buffer;
+  uint32_t target;
+  uint32_t buffer;
 };
 
 COMPILE_ASSERT(sizeof(BindBuffer) == 12, Sizeof_BindBuffer_is_not_12);
@@ -221,8 +224,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -239,8 +242,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 framebuffer;
+  uint32_t target;
+  uint32_t framebuffer;
 };
 
 COMPILE_ASSERT(sizeof(BindFramebuffer) == 12, Sizeof_BindFramebuffer_is_not_12);
@@ -257,8 +260,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -275,8 +278,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 renderbuffer;
+  uint32_t target;
+  uint32_t renderbuffer;
 };
 
 COMPILE_ASSERT(sizeof(BindRenderbuffer) == 12,
@@ -294,8 +297,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -312,8 +315,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 texture;
+  uint32_t target;
+  uint32_t texture;
 };
 
 COMPILE_ASSERT(sizeof(BindTexture) == 12, Sizeof_BindTexture_is_not_12);
@@ -330,8 +333,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -377,8 +380,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -394,7 +397,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 mode;
+  uint32_t mode;
 };
 
 COMPILE_ASSERT(sizeof(BlendEquation) == 8, Sizeof_BlendEquation_is_not_8);
@@ -409,8 +412,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -427,8 +430,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 modeRGB;
-  uint32 modeAlpha;
+  uint32_t modeRGB;
+  uint32_t modeAlpha;
 };
 
 COMPILE_ASSERT(sizeof(BlendEquationSeparate) == 12,
@@ -446,8 +449,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -464,8 +467,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 sfactor;
-  uint32 dfactor;
+  uint32_t sfactor;
+  uint32_t dfactor;
 };
 
 COMPILE_ASSERT(sizeof(BlendFunc) == 12, Sizeof_BlendFunc_is_not_12);
@@ -482,8 +485,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -509,10 +512,10 @@
   }
 
   gpu::CommandHeader header;
-  uint32 srcRGB;
-  uint32 dstRGB;
-  uint32 srcAlpha;
-  uint32 dstAlpha;
+  uint32_t srcRGB;
+  uint32_t dstRGB;
+  uint32_t srcAlpha;
+  uint32_t dstAlpha;
 };
 
 COMPILE_ASSERT(sizeof(BlendFuncSeparate) == 20,
@@ -534,16 +537,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _target,
             GLsizeiptr _size,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset,
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset,
             GLenum _usage) {
     SetHeader();
     target = _target;
@@ -556,8 +559,8 @@
   void* Set(void* cmd,
             GLenum _target,
             GLsizeiptr _size,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset,
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset,
             GLenum _usage) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _size, _data_shm_id, _data_shm_offset, _usage);
@@ -565,11 +568,11 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 size;
-  uint32 data_shm_id;
-  uint32 data_shm_offset;
-  uint32 usage;
+  uint32_t target;
+  int32_t size;
+  uint32_t data_shm_id;
+  uint32_t data_shm_offset;
+  uint32_t usage;
 };
 
 COMPILE_ASSERT(sizeof(BufferData) == 24, Sizeof_BufferData_is_not_24);
@@ -591,8 +594,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -600,8 +603,8 @@
   void Init(GLenum _target,
             GLintptr _offset,
             GLsizeiptr _size,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset) {
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset) {
     SetHeader();
     target = _target;
     offset = _offset;
@@ -614,19 +617,19 @@
             GLenum _target,
             GLintptr _offset,
             GLsizeiptr _size,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset) {
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _offset, _size, _data_shm_id, _data_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 offset;
-  int32 size;
-  uint32 data_shm_id;
-  uint32 data_shm_offset;
+  uint32_t target;
+  int32_t offset;
+  int32_t size;
+  uint32_t data_shm_id;
+  uint32_t data_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(BufferSubData) == 24, Sizeof_BufferSubData_is_not_24);
@@ -651,13 +654,15 @@
 
   typedef GLenum Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLenum _target, uint32 _result_shm_id, uint32 _result_shm_offset) {
+  void Init(GLenum _target,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     target = _target;
     result_shm_id = _result_shm_id;
@@ -666,17 +671,17 @@
 
   void* Set(void* cmd,
             GLenum _target,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t target;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(CheckFramebufferStatus) == 16,
@@ -696,8 +701,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -713,7 +718,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 mask;
+  uint32_t mask;
 };
 
 COMPILE_ASSERT(sizeof(Clear) == 8, Sizeof_Clear_is_not_8);
@@ -726,8 +731,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -773,8 +778,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -805,8 +810,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -822,7 +827,7 @@
   }
 
   gpu::CommandHeader header;
-  int32 s;
+  int32_t s;
 };
 
 COMPILE_ASSERT(sizeof(ClearStencil) == 8, Sizeof_ClearStencil_is_not_8);
@@ -836,8 +841,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -863,10 +868,10 @@
   }
 
   gpu::CommandHeader header;
-  uint32 red;
-  uint32 green;
-  uint32 blue;
-  uint32 alpha;
+  uint32_t red;
+  uint32_t green;
+  uint32_t blue;
+  uint32_t alpha;
 };
 
 COMPILE_ASSERT(sizeof(ColorMask) == 20, Sizeof_ColorMask_is_not_20);
@@ -884,8 +889,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -901,7 +906,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 shader;
+  uint32_t shader;
 };
 
 COMPILE_ASSERT(sizeof(CompileShader) == 8, Sizeof_CompileShader_is_not_8);
@@ -916,8 +921,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -929,8 +934,8 @@
             GLsizei _height,
             GLint _border,
             GLsizei _imageSize,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset) {
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset) {
     SetHeader();
     target = _target;
     level = _level;
@@ -951,8 +956,8 @@
             GLsizei _height,
             GLint _border,
             GLsizei _imageSize,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset) {
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(_target,
                                        _level,
                                        _internalformat,
@@ -966,15 +971,15 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 level;
-  uint32 internalformat;
-  int32 width;
-  int32 height;
-  int32 border;
-  int32 imageSize;
-  uint32 data_shm_id;
-  uint32 data_shm_offset;
+  uint32_t target;
+  int32_t level;
+  uint32_t internalformat;
+  int32_t width;
+  int32_t height;
+  int32_t border;
+  int32_t imageSize;
+  uint32_t data_shm_id;
+  uint32_t data_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(CompressedTexImage2D) == 40,
@@ -1006,8 +1011,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -1043,13 +1048,13 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 level;
-  uint32 internalformat;
-  int32 width;
-  int32 height;
-  int32 border;
-  uint32 bucket_id;
+  uint32_t target;
+  int32_t level;
+  uint32_t internalformat;
+  int32_t width;
+  int32_t height;
+  int32_t border;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(CompressedTexImage2DBucket) == 32,
@@ -1077,8 +1082,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -1091,8 +1096,8 @@
             GLsizei _height,
             GLenum _format,
             GLsizei _imageSize,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset) {
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset) {
     SetHeader();
     target = _target;
     level = _level;
@@ -1115,8 +1120,8 @@
             GLsizei _height,
             GLenum _format,
             GLsizei _imageSize,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset) {
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(_target,
                                        _level,
                                        _xoffset,
@@ -1131,16 +1136,16 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 level;
-  int32 xoffset;
-  int32 yoffset;
-  int32 width;
-  int32 height;
-  uint32 format;
-  int32 imageSize;
-  uint32 data_shm_id;
-  uint32 data_shm_offset;
+  uint32_t target;
+  int32_t level;
+  int32_t xoffset;
+  int32_t yoffset;
+  int32_t width;
+  int32_t height;
+  uint32_t format;
+  int32_t imageSize;
+  uint32_t data_shm_id;
+  uint32_t data_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(CompressedTexSubImage2D) == 44,
@@ -1174,8 +1179,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -1220,14 +1225,14 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 level;
-  int32 xoffset;
-  int32 yoffset;
-  int32 width;
-  int32 height;
-  uint32 format;
-  uint32 bucket_id;
+  uint32_t target;
+  int32_t level;
+  int32_t xoffset;
+  int32_t yoffset;
+  int32_t width;
+  int32_t height;
+  uint32_t format;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(CompressedTexSubImage2DBucket) == 36,
@@ -1257,8 +1262,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -1297,14 +1302,14 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 level;
-  uint32 internalformat;
-  int32 x;
-  int32 y;
-  int32 width;
-  int32 height;
-  int32 border;
+  uint32_t target;
+  int32_t level;
+  uint32_t internalformat;
+  int32_t x;
+  int32_t y;
+  int32_t width;
+  int32_t height;
+  int32_t border;
 };
 
 COMPILE_ASSERT(sizeof(CopyTexImage2D) == 36, Sizeof_CopyTexImage2D_is_not_36);
@@ -1333,8 +1338,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -1373,14 +1378,14 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 level;
-  int32 xoffset;
-  int32 yoffset;
-  int32 x;
-  int32 y;
-  int32 width;
-  int32 height;
+  uint32_t target;
+  int32_t level;
+  int32_t xoffset;
+  int32_t yoffset;
+  int32_t x;
+  int32_t y;
+  int32_t width;
+  int32_t height;
 };
 
 COMPILE_ASSERT(sizeof(CopyTexSubImage2D) == 36,
@@ -1410,24 +1415,24 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(uint32 _client_id) {
+  void Init(uint32_t _client_id) {
     SetHeader();
     client_id = _client_id;
   }
 
-  void* Set(void* cmd, uint32 _client_id) {
+  void* Set(void* cmd, uint32_t _client_id) {
     static_cast<ValueType*>(cmd)->Init(_client_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 client_id;
+  uint32_t client_id;
 };
 
 COMPILE_ASSERT(sizeof(CreateProgram) == 8, Sizeof_CreateProgram_is_not_8);
@@ -1442,26 +1447,26 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLenum _type, uint32 _client_id) {
+  void Init(GLenum _type, uint32_t _client_id) {
     SetHeader();
     type = _type;
     client_id = _client_id;
   }
 
-  void* Set(void* cmd, GLenum _type, uint32 _client_id) {
+  void* Set(void* cmd, GLenum _type, uint32_t _client_id) {
     static_cast<ValueType*>(cmd)->Init(_type, _client_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 type;
-  uint32 client_id;
+  uint32_t type;
+  uint32_t client_id;
 };
 
 COMPILE_ASSERT(sizeof(CreateShader) == 12, Sizeof_CreateShader_is_not_12);
@@ -1478,8 +1483,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -1495,7 +1500,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 mode;
+  uint32_t mode;
 };
 
 COMPILE_ASSERT(sizeof(CullFace) == 8, Sizeof_CullFace_is_not_8);
@@ -1508,13 +1513,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLsizei _n, uint32 _buffers_shm_id, uint32 _buffers_shm_offset) {
+  void Init(GLsizei _n,
+            uint32_t _buffers_shm_id,
+            uint32_t _buffers_shm_offset) {
     SetHeader();
     n = _n;
     buffers_shm_id = _buffers_shm_id;
@@ -1523,17 +1530,17 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _buffers_shm_id,
-            uint32 _buffers_shm_offset) {
+            uint32_t _buffers_shm_id,
+            uint32_t _buffers_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_n, _buffers_shm_id, _buffers_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 buffers_shm_id;
-  uint32 buffers_shm_offset;
+  int32_t n;
+  uint32_t buffers_shm_id;
+  uint32_t buffers_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(DeleteBuffers) == 16, Sizeof_DeleteBuffers_is_not_16);
@@ -1551,13 +1558,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -1572,12 +1579,12 @@
 
   void* Set(void* cmd, GLsizei _n, const GLuint* _buffers) {
     static_cast<ValueType*>(cmd)->Init(_n, _buffers);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(DeleteBuffersImmediate) == 8,
@@ -1593,15 +1600,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLsizei _n,
-            uint32 _framebuffers_shm_id,
-            uint32 _framebuffers_shm_offset) {
+            uint32_t _framebuffers_shm_id,
+            uint32_t _framebuffers_shm_offset) {
     SetHeader();
     n = _n;
     framebuffers_shm_id = _framebuffers_shm_id;
@@ -1610,17 +1617,17 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _framebuffers_shm_id,
-            uint32 _framebuffers_shm_offset) {
+            uint32_t _framebuffers_shm_id,
+            uint32_t _framebuffers_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_n, _framebuffers_shm_id, _framebuffers_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 framebuffers_shm_id;
-  uint32 framebuffers_shm_offset;
+  int32_t n;
+  uint32_t framebuffers_shm_id;
+  uint32_t framebuffers_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(DeleteFramebuffers) == 16,
@@ -1640,13 +1647,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -1661,12 +1668,12 @@
 
   void* Set(void* cmd, GLsizei _n, const GLuint* _framebuffers) {
     static_cast<ValueType*>(cmd)->Init(_n, _framebuffers);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(DeleteFramebuffersImmediate) == 8,
@@ -1682,8 +1689,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -1699,7 +1706,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 program;
+  uint32_t program;
 };
 
 COMPILE_ASSERT(sizeof(DeleteProgram) == 8, Sizeof_DeleteProgram_is_not_8);
@@ -1714,15 +1721,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLsizei _n,
-            uint32 _renderbuffers_shm_id,
-            uint32 _renderbuffers_shm_offset) {
+            uint32_t _renderbuffers_shm_id,
+            uint32_t _renderbuffers_shm_offset) {
     SetHeader();
     n = _n;
     renderbuffers_shm_id = _renderbuffers_shm_id;
@@ -1731,17 +1738,17 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _renderbuffers_shm_id,
-            uint32 _renderbuffers_shm_offset) {
+            uint32_t _renderbuffers_shm_id,
+            uint32_t _renderbuffers_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_n, _renderbuffers_shm_id, _renderbuffers_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 renderbuffers_shm_id;
-  uint32 renderbuffers_shm_offset;
+  int32_t n;
+  uint32_t renderbuffers_shm_id;
+  uint32_t renderbuffers_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(DeleteRenderbuffers) == 16,
@@ -1761,13 +1768,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -1782,12 +1789,12 @@
 
   void* Set(void* cmd, GLsizei _n, const GLuint* _renderbuffers) {
     static_cast<ValueType*>(cmd)->Init(_n, _renderbuffers);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(DeleteRenderbuffersImmediate) == 8,
@@ -1803,8 +1810,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -1820,7 +1827,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 shader;
+  uint32_t shader;
 };
 
 COMPILE_ASSERT(sizeof(DeleteShader) == 8, Sizeof_DeleteShader_is_not_8);
@@ -1835,13 +1842,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLsizei _n, uint32 _textures_shm_id, uint32 _textures_shm_offset) {
+  void Init(GLsizei _n,
+            uint32_t _textures_shm_id,
+            uint32_t _textures_shm_offset) {
     SetHeader();
     n = _n;
     textures_shm_id = _textures_shm_id;
@@ -1850,17 +1859,17 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _textures_shm_id,
-            uint32 _textures_shm_offset) {
+            uint32_t _textures_shm_id,
+            uint32_t _textures_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_n, _textures_shm_id, _textures_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 textures_shm_id;
-  uint32 textures_shm_offset;
+  int32_t n;
+  uint32_t textures_shm_id;
+  uint32_t textures_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(DeleteTextures) == 16, Sizeof_DeleteTextures_is_not_16);
@@ -1879,13 +1888,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -1900,12 +1909,12 @@
 
   void* Set(void* cmd, GLsizei _n, const GLuint* _textures) {
     static_cast<ValueType*>(cmd)->Init(_n, _textures);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(DeleteTexturesImmediate) == 8,
@@ -1921,8 +1930,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -1938,7 +1947,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 func;
+  uint32_t func;
 };
 
 COMPILE_ASSERT(sizeof(DepthFunc) == 8, Sizeof_DepthFunc_is_not_8);
@@ -1952,8 +1961,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -1969,7 +1978,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 flag;
+  uint32_t flag;
 };
 
 COMPILE_ASSERT(sizeof(DepthMask) == 8, Sizeof_DepthMask_is_not_8);
@@ -1983,8 +1992,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2019,8 +2028,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2037,8 +2046,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  uint32 shader;
+  uint32_t program;
+  uint32_t shader;
 };
 
 COMPILE_ASSERT(sizeof(DetachShader) == 12, Sizeof_DetachShader_is_not_12);
@@ -2055,8 +2064,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2072,7 +2081,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 cap;
+  uint32_t cap;
 };
 
 COMPILE_ASSERT(sizeof(Disable) == 8, Sizeof_Disable_is_not_8);
@@ -2085,8 +2094,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2102,7 +2111,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 index;
+  uint32_t index;
 };
 
 COMPILE_ASSERT(sizeof(DisableVertexAttribArray) == 8,
@@ -2118,8 +2127,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(2);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2137,9 +2146,9 @@
   }
 
   gpu::CommandHeader header;
-  uint32 mode;
-  int32 first;
-  int32 count;
+  uint32_t mode;
+  int32_t first;
+  int32_t count;
 };
 
 COMPILE_ASSERT(sizeof(DrawArrays) == 16, Sizeof_DrawArrays_is_not_16);
@@ -2157,8 +2166,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(2);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2181,10 +2190,10 @@
   }
 
   gpu::CommandHeader header;
-  uint32 mode;
-  int32 count;
-  uint32 type;
-  uint32 index_offset;
+  uint32_t mode;
+  int32_t count;
+  uint32_t type;
+  uint32_t index_offset;
 };
 
 COMPILE_ASSERT(sizeof(DrawElements) == 20, Sizeof_DrawElements_is_not_20);
@@ -2205,8 +2214,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2222,7 +2231,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 cap;
+  uint32_t cap;
 };
 
 COMPILE_ASSERT(sizeof(Enable) == 8, Sizeof_Enable_is_not_8);
@@ -2235,8 +2244,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2252,7 +2261,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 index;
+  uint32_t index;
 };
 
 COMPILE_ASSERT(sizeof(EnableVertexAttribArray) == 8,
@@ -2268,8 +2277,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2293,8 +2302,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2318,8 +2327,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2346,10 +2355,10 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 attachment;
-  uint32 renderbuffertarget;
-  uint32 renderbuffer;
+  uint32_t target;
+  uint32_t attachment;
+  uint32_t renderbuffertarget;
+  uint32_t renderbuffer;
 };
 
 COMPILE_ASSERT(sizeof(FramebufferRenderbuffer) == 20,
@@ -2371,8 +2380,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2402,11 +2411,11 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 attachment;
-  uint32 textarget;
-  uint32 texture;
-  int32 level;
+  uint32_t target;
+  uint32_t attachment;
+  uint32_t textarget;
+  uint32_t texture;
+  int32_t level;
 };
 
 COMPILE_ASSERT(sizeof(FramebufferTexture2D) == 24,
@@ -2430,8 +2439,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2447,7 +2456,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 mode;
+  uint32_t mode;
 };
 
 COMPILE_ASSERT(sizeof(FrontFace) == 8, Sizeof_FrontFace_is_not_8);
@@ -2461,13 +2470,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLsizei _n, uint32 _buffers_shm_id, uint32 _buffers_shm_offset) {
+  void Init(GLsizei _n,
+            uint32_t _buffers_shm_id,
+            uint32_t _buffers_shm_offset) {
     SetHeader();
     n = _n;
     buffers_shm_id = _buffers_shm_id;
@@ -2476,17 +2487,17 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _buffers_shm_id,
-            uint32 _buffers_shm_offset) {
+            uint32_t _buffers_shm_id,
+            uint32_t _buffers_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_n, _buffers_shm_id, _buffers_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 buffers_shm_id;
-  uint32 buffers_shm_offset;
+  int32_t n;
+  uint32_t buffers_shm_id;
+  uint32_t buffers_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GenBuffers) == 16, Sizeof_GenBuffers_is_not_16);
@@ -2504,13 +2515,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -2525,12 +2536,12 @@
 
   void* Set(void* cmd, GLsizei _n, GLuint* _buffers) {
     static_cast<ValueType*>(cmd)->Init(_n, _buffers);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(GenBuffersImmediate) == 8,
@@ -2546,8 +2557,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -2563,7 +2574,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
+  uint32_t target;
 };
 
 COMPILE_ASSERT(sizeof(GenerateMipmap) == 8, Sizeof_GenerateMipmap_is_not_8);
@@ -2578,15 +2589,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLsizei _n,
-            uint32 _framebuffers_shm_id,
-            uint32 _framebuffers_shm_offset) {
+            uint32_t _framebuffers_shm_id,
+            uint32_t _framebuffers_shm_offset) {
     SetHeader();
     n = _n;
     framebuffers_shm_id = _framebuffers_shm_id;
@@ -2595,17 +2606,17 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _framebuffers_shm_id,
-            uint32 _framebuffers_shm_offset) {
+            uint32_t _framebuffers_shm_id,
+            uint32_t _framebuffers_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_n, _framebuffers_shm_id, _framebuffers_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 framebuffers_shm_id;
-  uint32 framebuffers_shm_offset;
+  int32_t n;
+  uint32_t framebuffers_shm_id;
+  uint32_t framebuffers_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GenFramebuffers) == 16, Sizeof_GenFramebuffers_is_not_16);
@@ -2624,13 +2635,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -2645,12 +2656,12 @@
 
   void* Set(void* cmd, GLsizei _n, GLuint* _framebuffers) {
     static_cast<ValueType*>(cmd)->Init(_n, _framebuffers);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(GenFramebuffersImmediate) == 8,
@@ -2666,15 +2677,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLsizei _n,
-            uint32 _renderbuffers_shm_id,
-            uint32 _renderbuffers_shm_offset) {
+            uint32_t _renderbuffers_shm_id,
+            uint32_t _renderbuffers_shm_offset) {
     SetHeader();
     n = _n;
     renderbuffers_shm_id = _renderbuffers_shm_id;
@@ -2683,17 +2694,17 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _renderbuffers_shm_id,
-            uint32 _renderbuffers_shm_offset) {
+            uint32_t _renderbuffers_shm_id,
+            uint32_t _renderbuffers_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_n, _renderbuffers_shm_id, _renderbuffers_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 renderbuffers_shm_id;
-  uint32 renderbuffers_shm_offset;
+  int32_t n;
+  uint32_t renderbuffers_shm_id;
+  uint32_t renderbuffers_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GenRenderbuffers) == 16,
@@ -2713,13 +2724,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -2734,12 +2745,12 @@
 
   void* Set(void* cmd, GLsizei _n, GLuint* _renderbuffers) {
     static_cast<ValueType*>(cmd)->Init(_n, _renderbuffers);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(GenRenderbuffersImmediate) == 8,
@@ -2755,13 +2766,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLsizei _n, uint32 _textures_shm_id, uint32 _textures_shm_offset) {
+  void Init(GLsizei _n,
+            uint32_t _textures_shm_id,
+            uint32_t _textures_shm_offset) {
     SetHeader();
     n = _n;
     textures_shm_id = _textures_shm_id;
@@ -2770,17 +2783,17 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _textures_shm_id,
-            uint32 _textures_shm_offset) {
+            uint32_t _textures_shm_id,
+            uint32_t _textures_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_n, _textures_shm_id, _textures_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 textures_shm_id;
-  uint32 textures_shm_offset;
+  int32_t n;
+  uint32_t textures_shm_id;
+  uint32_t textures_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GenTextures) == 16, Sizeof_GenTextures_is_not_16);
@@ -2798,13 +2811,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -2819,12 +2832,12 @@
 
   void* Set(void* cmd, GLsizei _n, GLuint* _textures) {
     static_cast<ValueType*>(cmd)->Init(_n, _textures);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(GenTexturesImmediate) == 8,
@@ -2841,22 +2854,22 @@
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
   struct Result {
-    int32 success;
-    int32 size;
-    uint32 type;
+    int32_t success;
+    int32_t size;
+    uint32_t type;
   };
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _program,
             GLuint _index,
-            uint32 _name_bucket_id,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _name_bucket_id,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     program = _program;
     index = _index;
@@ -2868,20 +2881,20 @@
   void* Set(void* cmd,
             GLuint _program,
             GLuint _index,
-            uint32 _name_bucket_id,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _name_bucket_id,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(
         _program, _index, _name_bucket_id, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  uint32 index;
-  uint32 name_bucket_id;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t program;
+  uint32_t index;
+  uint32_t name_bucket_id;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetActiveAttrib) == 24, Sizeof_GetActiveAttrib_is_not_24);
@@ -2911,22 +2924,22 @@
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
   struct Result {
-    int32 success;
-    int32 size;
-    uint32 type;
+    int32_t success;
+    int32_t size;
+    uint32_t type;
   };
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _program,
             GLuint _index,
-            uint32 _name_bucket_id,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _name_bucket_id,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     program = _program;
     index = _index;
@@ -2938,20 +2951,20 @@
   void* Set(void* cmd,
             GLuint _program,
             GLuint _index,
-            uint32 _name_bucket_id,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _name_bucket_id,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(
         _program, _index, _name_bucket_id, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  uint32 index;
-  uint32 name_bucket_id;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t program;
+  uint32_t index;
+  uint32_t name_bucket_id;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetActiveUniform) == 24,
@@ -2983,16 +2996,16 @@
 
   typedef SizedResult<GLuint> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _program,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset,
-            uint32 _result_size) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset,
+            uint32_t _result_size) {
     SetHeader();
     program = _program;
     result_shm_id = _result_shm_id;
@@ -3002,19 +3015,19 @@
 
   void* Set(void* cmd,
             GLuint _program,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset,
-            uint32 _result_size) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset,
+            uint32_t _result_size) {
     static_cast<ValueType*>(cmd)
         ->Init(_program, _result_shm_id, _result_shm_offset, _result_size);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
-  uint32 result_size;
+  uint32_t program;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
+  uint32_t result_size;
 };
 
 COMPILE_ASSERT(sizeof(GetAttachedShaders) == 20,
@@ -3038,13 +3051,15 @@
 
   typedef SizedResult<GLboolean> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLenum _pname, uint32 _params_shm_id, uint32 _params_shm_offset) {
+  void Init(GLenum _pname,
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     pname = _pname;
     params_shm_id = _params_shm_id;
@@ -3053,17 +3068,17 @@
 
   void* Set(void* cmd,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetBooleanv) == 16, Sizeof_GetBooleanv_is_not_16);
@@ -3084,16 +3099,16 @@
 
   typedef SizedResult<GLint> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     target = _target;
     pname = _pname;
@@ -3104,18 +3119,18 @@
   void* Set(void* cmd,
             GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t target;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetBufferParameteriv) == 20,
@@ -3139,26 +3154,26 @@
 
   typedef GLenum Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(uint32 _result_shm_id, uint32 _result_shm_offset) {
+  void Init(uint32_t _result_shm_id, uint32_t _result_shm_offset) {
     SetHeader();
     result_shm_id = _result_shm_id;
     result_shm_offset = _result_shm_offset;
   }
 
-  void* Set(void* cmd, uint32 _result_shm_id, uint32 _result_shm_offset) {
+  void* Set(void* cmd, uint32_t _result_shm_id, uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(_result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetError) == 12, Sizeof_GetError_is_not_12);
@@ -3176,13 +3191,15 @@
 
   typedef SizedResult<GLfloat> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLenum _pname, uint32 _params_shm_id, uint32 _params_shm_offset) {
+  void Init(GLenum _pname,
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     pname = _pname;
     params_shm_id = _params_shm_id;
@@ -3191,17 +3208,17 @@
 
   void* Set(void* cmd,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetFloatv) == 16, Sizeof_GetFloatv_is_not_16);
@@ -3221,8 +3238,8 @@
 
   typedef SizedResult<GLint> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -3230,8 +3247,8 @@
   void Init(GLenum _target,
             GLenum _attachment,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     target = _target;
     attachment = _attachment;
@@ -3244,19 +3261,19 @@
             GLenum _target,
             GLenum _attachment,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(
         _target, _attachment, _pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 attachment;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t target;
+  uint32_t attachment;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetFramebufferAttachmentParameteriv) == 24,
@@ -3284,13 +3301,15 @@
 
   typedef SizedResult<GLint> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLenum _pname, uint32 _params_shm_id, uint32 _params_shm_offset) {
+  void Init(GLenum _pname,
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     pname = _pname;
     params_shm_id = _params_shm_id;
@@ -3299,17 +3318,17 @@
 
   void* Set(void* cmd,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetIntegerv) == 16, Sizeof_GetIntegerv_is_not_16);
@@ -3330,16 +3349,16 @@
 
   typedef SizedResult<GLint> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _program,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     program = _program;
     pname = _pname;
@@ -3350,18 +3369,18 @@
   void* Set(void* cmd,
             GLuint _program,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_program, _pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t program;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetProgramiv) == 20, Sizeof_GetProgramiv_is_not_20);
@@ -3382,26 +3401,26 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _program, uint32 _bucket_id) {
+  void Init(GLuint _program, uint32_t _bucket_id) {
     SetHeader();
     program = _program;
     bucket_id = _bucket_id;
   }
 
-  void* Set(void* cmd, GLuint _program, uint32 _bucket_id) {
+  void* Set(void* cmd, GLuint _program, uint32_t _bucket_id) {
     static_cast<ValueType*>(cmd)->Init(_program, _bucket_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  uint32 bucket_id;
+  uint32_t program;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(GetProgramInfoLog) == 12,
@@ -3421,16 +3440,16 @@
 
   typedef SizedResult<GLint> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     target = _target;
     pname = _pname;
@@ -3441,18 +3460,18 @@
   void* Set(void* cmd,
             GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t target;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetRenderbufferParameteriv) == 20,
@@ -3476,16 +3495,16 @@
 
   typedef SizedResult<GLint> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _shader,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     shader = _shader;
     pname = _pname;
@@ -3496,18 +3515,18 @@
   void* Set(void* cmd,
             GLuint _shader,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_shader, _pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 shader;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t shader;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetShaderiv) == 20, Sizeof_GetShaderiv_is_not_20);
@@ -3528,26 +3547,26 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _shader, uint32 _bucket_id) {
+  void Init(GLuint _shader, uint32_t _bucket_id) {
     SetHeader();
     shader = _shader;
     bucket_id = _bucket_id;
   }
 
-  void* Set(void* cmd, GLuint _shader, uint32 _bucket_id) {
+  void* Set(void* cmd, GLuint _shader, uint32_t _bucket_id) {
     static_cast<ValueType*>(cmd)->Init(_shader, _bucket_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 shader;
-  uint32 bucket_id;
+  uint32_t shader;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(GetShaderInfoLog) == 12,
@@ -3566,22 +3585,22 @@
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
   struct Result {
-    int32 success;
-    int32 min_range;
-    int32 max_range;
-    int32 precision;
+    int32_t success;
+    int32_t min_range;
+    int32_t max_range;
+    int32_t precision;
   };
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _shadertype,
             GLenum _precisiontype,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     shadertype = _shadertype;
     precisiontype = _precisiontype;
@@ -3592,18 +3611,18 @@
   void* Set(void* cmd,
             GLenum _shadertype,
             GLenum _precisiontype,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_shadertype, _precisiontype, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 shadertype;
-  uint32 precisiontype;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t shadertype;
+  uint32_t precisiontype;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetShaderPrecisionFormat) == 20,
@@ -3633,26 +3652,26 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _shader, uint32 _bucket_id) {
+  void Init(GLuint _shader, uint32_t _bucket_id) {
     SetHeader();
     shader = _shader;
     bucket_id = _bucket_id;
   }
 
-  void* Set(void* cmd, GLuint _shader, uint32 _bucket_id) {
+  void* Set(void* cmd, GLuint _shader, uint32_t _bucket_id) {
     static_cast<ValueType*>(cmd)->Init(_shader, _bucket_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 shader;
-  uint32 bucket_id;
+  uint32_t shader;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(GetShaderSource) == 12, Sizeof_GetShaderSource_is_not_12);
@@ -3669,26 +3688,26 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLenum _name, uint32 _bucket_id) {
+  void Init(GLenum _name, uint32_t _bucket_id) {
     SetHeader();
     name = _name;
     bucket_id = _bucket_id;
   }
 
-  void* Set(void* cmd, GLenum _name, uint32 _bucket_id) {
+  void* Set(void* cmd, GLenum _name, uint32_t _bucket_id) {
     static_cast<ValueType*>(cmd)->Init(_name, _bucket_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 name;
-  uint32 bucket_id;
+  uint32_t name;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(GetString) == 12, Sizeof_GetString_is_not_12);
@@ -3706,16 +3725,16 @@
 
   typedef SizedResult<GLfloat> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     target = _target;
     pname = _pname;
@@ -3726,18 +3745,18 @@
   void* Set(void* cmd,
             GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t target;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetTexParameterfv) == 20,
@@ -3761,16 +3780,16 @@
 
   typedef SizedResult<GLint> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     target = _target;
     pname = _pname;
@@ -3781,18 +3800,18 @@
   void* Set(void* cmd,
             GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t target;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetTexParameteriv) == 20,
@@ -3816,16 +3835,16 @@
 
   typedef SizedResult<GLfloat> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _program,
             GLint _location,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     program = _program;
     location = _location;
@@ -3836,18 +3855,18 @@
   void* Set(void* cmd,
             GLuint _program,
             GLint _location,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_program, _location, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  int32 location;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t program;
+  int32_t location;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetUniformfv) == 20, Sizeof_GetUniformfv_is_not_20);
@@ -3870,16 +3889,16 @@
 
   typedef SizedResult<GLint> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _program,
             GLint _location,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     program = _program;
     location = _location;
@@ -3890,18 +3909,18 @@
   void* Set(void* cmd,
             GLuint _program,
             GLint _location,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_program, _location, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  int32 location;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t program;
+  int32_t location;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetUniformiv) == 20, Sizeof_GetUniformiv_is_not_20);
@@ -3924,16 +3943,16 @@
 
   typedef SizedResult<GLfloat> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _index,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     index = _index;
     pname = _pname;
@@ -3944,18 +3963,18 @@
   void* Set(void* cmd,
             GLuint _index,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_index, _pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 index;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t index;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetVertexAttribfv) == 20,
@@ -3979,16 +3998,16 @@
 
   typedef SizedResult<GLint> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _index,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     index = _index;
     pname = _pname;
@@ -3999,18 +4018,18 @@
   void* Set(void* cmd,
             GLuint _index,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_index, _pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 index;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t index;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetVertexAttribiv) == 20,
@@ -4034,16 +4053,16 @@
 
   typedef SizedResult<GLuint> Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _index,
             GLenum _pname,
-            uint32 _pointer_shm_id,
-            uint32 _pointer_shm_offset) {
+            uint32_t _pointer_shm_id,
+            uint32_t _pointer_shm_offset) {
     SetHeader();
     index = _index;
     pname = _pname;
@@ -4054,18 +4073,18 @@
   void* Set(void* cmd,
             GLuint _index,
             GLenum _pname,
-            uint32 _pointer_shm_id,
-            uint32 _pointer_shm_offset) {
+            uint32_t _pointer_shm_id,
+            uint32_t _pointer_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_index, _pname, _pointer_shm_id, _pointer_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 index;
-  uint32 pname;
-  uint32 pointer_shm_id;
-  uint32 pointer_shm_offset;
+  uint32_t index;
+  uint32_t pname;
+  uint32_t pointer_shm_id;
+  uint32_t pointer_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetVertexAttribPointerv) == 20,
@@ -4087,8 +4106,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -4105,8 +4124,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 mode;
+  uint32_t target;
+  uint32_t mode;
 };
 
 COMPILE_ASSERT(sizeof(Hint) == 12, Sizeof_Hint_is_not_12);
@@ -4120,15 +4139,17 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  typedef uint32 Result;
+  typedef uint32_t Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _buffer, uint32 _result_shm_id, uint32 _result_shm_offset) {
+  void Init(GLuint _buffer,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     buffer = _buffer;
     result_shm_id = _result_shm_id;
@@ -4137,17 +4158,17 @@
 
   void* Set(void* cmd,
             GLuint _buffer,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_buffer, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 buffer;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t buffer;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(IsBuffer) == 16, Sizeof_IsBuffer_is_not_16);
@@ -4164,15 +4185,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  typedef uint32 Result;
+  typedef uint32_t Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLenum _cap, uint32 _result_shm_id, uint32 _result_shm_offset) {
+  void Init(GLenum _cap, uint32_t _result_shm_id, uint32_t _result_shm_offset) {
     SetHeader();
     cap = _cap;
     result_shm_id = _result_shm_id;
@@ -4181,17 +4202,17 @@
 
   void* Set(void* cmd,
             GLenum _cap,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_cap, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 cap;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t cap;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(IsEnabled) == 16, Sizeof_IsEnabled_is_not_16);
@@ -4209,17 +4230,17 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  typedef uint32 Result;
+  typedef uint32_t Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _framebuffer,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     framebuffer = _framebuffer;
     result_shm_id = _result_shm_id;
@@ -4228,17 +4249,17 @@
 
   void* Set(void* cmd,
             GLuint _framebuffer,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_framebuffer, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 framebuffer;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t framebuffer;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(IsFramebuffer) == 16, Sizeof_IsFramebuffer_is_not_16);
@@ -4257,15 +4278,17 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  typedef uint32 Result;
+  typedef uint32_t Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _program, uint32 _result_shm_id, uint32 _result_shm_offset) {
+  void Init(GLuint _program,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     program = _program;
     result_shm_id = _result_shm_id;
@@ -4274,17 +4297,17 @@
 
   void* Set(void* cmd,
             GLuint _program,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_program, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t program;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(IsProgram) == 16, Sizeof_IsProgram_is_not_16);
@@ -4303,17 +4326,17 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  typedef uint32 Result;
+  typedef uint32_t Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _renderbuffer,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     renderbuffer = _renderbuffer;
     result_shm_id = _result_shm_id;
@@ -4322,17 +4345,17 @@
 
   void* Set(void* cmd,
             GLuint _renderbuffer,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_renderbuffer, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 renderbuffer;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t renderbuffer;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(IsRenderbuffer) == 16, Sizeof_IsRenderbuffer_is_not_16);
@@ -4351,15 +4374,17 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  typedef uint32 Result;
+  typedef uint32_t Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _shader, uint32 _result_shm_id, uint32 _result_shm_offset) {
+  void Init(GLuint _shader,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     shader = _shader;
     result_shm_id = _result_shm_id;
@@ -4368,17 +4393,17 @@
 
   void* Set(void* cmd,
             GLuint _shader,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_shader, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 shader;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t shader;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(IsShader) == 16, Sizeof_IsShader_is_not_16);
@@ -4395,15 +4420,17 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  typedef uint32 Result;
+  typedef uint32_t Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _texture, uint32 _result_shm_id, uint32 _result_shm_offset) {
+  void Init(GLuint _texture,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     texture = _texture;
     result_shm_id = _result_shm_id;
@@ -4412,17 +4439,17 @@
 
   void* Set(void* cmd,
             GLuint _texture,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_texture, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 texture;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t texture;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(IsTexture) == 16, Sizeof_IsTexture_is_not_16);
@@ -4441,8 +4468,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -4472,8 +4499,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -4489,7 +4516,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 program;
+  uint32_t program;
 };
 
 COMPILE_ASSERT(sizeof(LinkProgram) == 8, Sizeof_LinkProgram_is_not_8);
@@ -4504,8 +4531,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -4522,8 +4549,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 pname;
-  int32 param;
+  uint32_t pname;
+  int32_t param;
 };
 
 COMPILE_ASSERT(sizeof(PixelStorei) == 12, Sizeof_PixelStorei_is_not_12);
@@ -4540,8 +4567,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -4579,10 +4606,10 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  typedef uint32 Result;
+  typedef uint32_t Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -4593,10 +4620,10 @@
             GLsizei _height,
             GLenum _format,
             GLenum _type,
-            uint32 _pixels_shm_id,
-            uint32 _pixels_shm_offset,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset,
+            uint32_t _pixels_shm_id,
+            uint32_t _pixels_shm_offset,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset,
             GLboolean _async) {
     SetHeader();
     x = _x;
@@ -4619,10 +4646,10 @@
             GLsizei _height,
             GLenum _format,
             GLenum _type,
-            uint32 _pixels_shm_id,
-            uint32 _pixels_shm_offset,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset,
+            uint32_t _pixels_shm_id,
+            uint32_t _pixels_shm_offset,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset,
             GLboolean _async) {
     static_cast<ValueType*>(cmd)->Init(_x,
                                        _y,
@@ -4639,17 +4666,17 @@
   }
 
   gpu::CommandHeader header;
-  int32 x;
-  int32 y;
-  int32 width;
-  int32 height;
-  uint32 format;
-  uint32 type;
-  uint32 pixels_shm_id;
-  uint32 pixels_shm_offset;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
-  uint32 async;
+  int32_t x;
+  int32_t y;
+  int32_t width;
+  int32_t height;
+  uint32_t format;
+  uint32_t type;
+  uint32_t pixels_shm_id;
+  uint32_t pixels_shm_offset;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
+  uint32_t async;
 };
 
 COMPILE_ASSERT(sizeof(ReadPixels) == 48, Sizeof_ReadPixels_is_not_48);
@@ -4682,8 +4709,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -4709,8 +4736,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -4737,10 +4764,10 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 internalformat;
-  int32 width;
-  int32 height;
+  uint32_t target;
+  uint32_t internalformat;
+  int32_t width;
+  int32_t height;
 };
 
 COMPILE_ASSERT(sizeof(RenderbufferStorage) == 20,
@@ -4762,8 +4789,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -4781,7 +4808,7 @@
 
   gpu::CommandHeader header;
   float value;
-  uint32 invert;
+  uint32_t invert;
 };
 
 COMPILE_ASSERT(sizeof(SampleCoverage) == 12, Sizeof_SampleCoverage_is_not_12);
@@ -4798,8 +4825,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -4818,10 +4845,10 @@
   }
 
   gpu::CommandHeader header;
-  int32 x;
-  int32 y;
-  int32 width;
-  int32 height;
+  int32_t x;
+  int32_t y;
+  int32_t width;
+  int32_t height;
 };
 
 COMPILE_ASSERT(sizeof(Scissor) == 20, Sizeof_Scissor_is_not_20);
@@ -4837,18 +4864,18 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLsizei _n,
-            uint32 _shaders_shm_id,
-            uint32 _shaders_shm_offset,
+            uint32_t _shaders_shm_id,
+            uint32_t _shaders_shm_offset,
             GLenum _binaryformat,
-            uint32 _binary_shm_id,
-            uint32 _binary_shm_offset,
+            uint32_t _binary_shm_id,
+            uint32_t _binary_shm_offset,
             GLsizei _length) {
     SetHeader();
     n = _n;
@@ -4862,11 +4889,11 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _shaders_shm_id,
-            uint32 _shaders_shm_offset,
+            uint32_t _shaders_shm_id,
+            uint32_t _shaders_shm_offset,
             GLenum _binaryformat,
-            uint32 _binary_shm_id,
-            uint32 _binary_shm_offset,
+            uint32_t _binary_shm_id,
+            uint32_t _binary_shm_offset,
             GLsizei _length) {
     static_cast<ValueType*>(cmd)->Init(_n,
                                        _shaders_shm_id,
@@ -4879,13 +4906,13 @@
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 shaders_shm_id;
-  uint32 shaders_shm_offset;
-  uint32 binaryformat;
-  uint32 binary_shm_id;
-  uint32 binary_shm_offset;
-  int32 length;
+  int32_t n;
+  uint32_t shaders_shm_id;
+  uint32_t shaders_shm_offset;
+  uint32_t binaryformat;
+  uint32_t binary_shm_id;
+  uint32_t binary_shm_offset;
+  int32_t length;
 };
 
 COMPILE_ASSERT(sizeof(ShaderBinary) == 32, Sizeof_ShaderBinary_is_not_32);
@@ -4911,16 +4938,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _shader,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset,
-            uint32 _data_size) {
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset,
+            uint32_t _data_size) {
     SetHeader();
     shader = _shader;
     data_shm_id = _data_shm_id;
@@ -4930,19 +4957,19 @@
 
   void* Set(void* cmd,
             GLuint _shader,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset,
-            uint32 _data_size) {
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset,
+            uint32_t _data_size) {
     static_cast<ValueType*>(cmd)
         ->Init(_shader, _data_shm_id, _data_shm_offset, _data_size);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 shader;
-  uint32 data_shm_id;
-  uint32 data_shm_offset;
-  uint32 data_size;
+  uint32_t shader;
+  uint32_t data_shm_id;
+  uint32_t data_shm_offset;
+  uint32_t data_size;
 };
 
 COMPILE_ASSERT(sizeof(ShaderSource) == 20, Sizeof_ShaderSource_is_not_20);
@@ -4963,26 +4990,26 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _shader, uint32 _data_bucket_id) {
+  void Init(GLuint _shader, uint32_t _data_bucket_id) {
     SetHeader();
     shader = _shader;
     data_bucket_id = _data_bucket_id;
   }
 
-  void* Set(void* cmd, GLuint _shader, uint32 _data_bucket_id) {
+  void* Set(void* cmd, GLuint _shader, uint32_t _data_bucket_id) {
     static_cast<ValueType*>(cmd)->Init(_shader, _data_bucket_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 shader;
-  uint32 data_bucket_id;
+  uint32_t shader;
+  uint32_t data_bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(ShaderSourceBucket) == 12,
@@ -5000,8 +5027,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5019,9 +5046,9 @@
   }
 
   gpu::CommandHeader header;
-  uint32 func;
-  int32 ref;
-  uint32 mask;
+  uint32_t func;
+  int32_t ref;
+  uint32_t mask;
 };
 
 COMPILE_ASSERT(sizeof(StencilFunc) == 16, Sizeof_StencilFunc_is_not_16);
@@ -5039,8 +5066,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5059,10 +5086,10 @@
   }
 
   gpu::CommandHeader header;
-  uint32 face;
-  uint32 func;
-  int32 ref;
-  uint32 mask;
+  uint32_t face;
+  uint32_t func;
+  int32_t ref;
+  uint32_t mask;
 };
 
 COMPILE_ASSERT(sizeof(StencilFuncSeparate) == 20,
@@ -5084,8 +5111,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5101,7 +5128,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 mask;
+  uint32_t mask;
 };
 
 COMPILE_ASSERT(sizeof(StencilMask) == 8, Sizeof_StencilMask_is_not_8);
@@ -5116,8 +5143,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5134,8 +5161,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 face;
-  uint32 mask;
+  uint32_t face;
+  uint32_t mask;
 };
 
 COMPILE_ASSERT(sizeof(StencilMaskSeparate) == 12,
@@ -5153,8 +5180,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5172,9 +5199,9 @@
   }
 
   gpu::CommandHeader header;
-  uint32 fail;
-  uint32 zfail;
-  uint32 zpass;
+  uint32_t fail;
+  uint32_t zfail;
+  uint32_t zpass;
 };
 
 COMPILE_ASSERT(sizeof(StencilOp) == 16, Sizeof_StencilOp_is_not_16);
@@ -5191,8 +5218,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5215,10 +5242,10 @@
   }
 
   gpu::CommandHeader header;
-  uint32 face;
-  uint32 fail;
-  uint32 zfail;
-  uint32 zpass;
+  uint32_t face;
+  uint32_t fail;
+  uint32_t zfail;
+  uint32_t zpass;
 };
 
 COMPILE_ASSERT(sizeof(StencilOpSeparate) == 20,
@@ -5240,8 +5267,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5254,8 +5281,8 @@
             GLint _border,
             GLenum _format,
             GLenum _type,
-            uint32 _pixels_shm_id,
-            uint32 _pixels_shm_offset) {
+            uint32_t _pixels_shm_id,
+            uint32_t _pixels_shm_offset) {
     SetHeader();
     target = _target;
     level = _level;
@@ -5278,8 +5305,8 @@
             GLint _border,
             GLenum _format,
             GLenum _type,
-            uint32 _pixels_shm_id,
-            uint32 _pixels_shm_offset) {
+            uint32_t _pixels_shm_id,
+            uint32_t _pixels_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(_target,
                                        _level,
                                        _internalformat,
@@ -5294,16 +5321,16 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 level;
-  int32 internalformat;
-  int32 width;
-  int32 height;
-  int32 border;
-  uint32 format;
-  uint32 type;
-  uint32 pixels_shm_id;
-  uint32 pixels_shm_offset;
+  uint32_t target;
+  int32_t level;
+  int32_t internalformat;
+  int32_t width;
+  int32_t height;
+  int32_t border;
+  uint32_t format;
+  uint32_t type;
+  uint32_t pixels_shm_id;
+  uint32_t pixels_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(TexImage2D) == 44, Sizeof_TexImage2D_is_not_44);
@@ -5336,8 +5363,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5355,8 +5382,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 pname;
+  uint32_t target;
+  uint32_t pname;
   float param;
 };
 
@@ -5376,16 +5403,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     target = _target;
     pname = _pname;
@@ -5396,18 +5423,18 @@
   void* Set(void* cmd,
             GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t target;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(TexParameterfv) == 20, Sizeof_TexParameterfv_is_not_20);
@@ -5428,13 +5455,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize() {
-    return static_cast<uint32>(sizeof(GLfloat) * 1);  // NOLINT
+  static uint32_t ComputeDataSize() {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 1);  // NOLINT
   }
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize());  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize());  // NOLINT
   }
 
   void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); }
@@ -5448,13 +5475,13 @@
 
   void* Set(void* cmd, GLenum _target, GLenum _pname, const GLfloat* _params) {
     static_cast<ValueType*>(cmd)->Init(_target, _pname, _params);
-    const uint32 size = ComputeSize();
+    const uint32_t size = ComputeSize();
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 pname;
+  uint32_t target;
+  uint32_t pname;
 };
 
 COMPILE_ASSERT(sizeof(TexParameterfvImmediate) == 12,
@@ -5472,8 +5499,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5491,9 +5518,9 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 pname;
-  int32 param;
+  uint32_t target;
+  uint32_t pname;
+  int32_t param;
 };
 
 COMPILE_ASSERT(sizeof(TexParameteri) == 16, Sizeof_TexParameteri_is_not_16);
@@ -5512,16 +5539,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     SetHeader();
     target = _target;
     pname = _pname;
@@ -5532,18 +5559,18 @@
   void* Set(void* cmd,
             GLenum _target,
             GLenum _pname,
-            uint32 _params_shm_id,
-            uint32 _params_shm_offset) {
+            uint32_t _params_shm_id,
+            uint32_t _params_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _pname, _params_shm_id, _params_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 pname;
-  uint32 params_shm_id;
-  uint32 params_shm_offset;
+  uint32_t target;
+  uint32_t pname;
+  uint32_t params_shm_id;
+  uint32_t params_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(TexParameteriv) == 20, Sizeof_TexParameteriv_is_not_20);
@@ -5564,13 +5591,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize() {
-    return static_cast<uint32>(sizeof(GLint) * 1);  // NOLINT
+  static uint32_t ComputeDataSize() {
+    return static_cast<uint32_t>(sizeof(GLint) * 1);  // NOLINT
   }
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize());  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize());  // NOLINT
   }
 
   void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); }
@@ -5584,13 +5611,13 @@
 
   void* Set(void* cmd, GLenum _target, GLenum _pname, const GLint* _params) {
     static_cast<ValueType*>(cmd)->Init(_target, _pname, _params);
-    const uint32 size = ComputeSize();
+    const uint32_t size = ComputeSize();
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 pname;
+  uint32_t target;
+  uint32_t pname;
 };
 
 COMPILE_ASSERT(sizeof(TexParameterivImmediate) == 12,
@@ -5608,8 +5635,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5622,8 +5649,8 @@
             GLsizei _height,
             GLenum _format,
             GLenum _type,
-            uint32 _pixels_shm_id,
-            uint32 _pixels_shm_offset,
+            uint32_t _pixels_shm_id,
+            uint32_t _pixels_shm_offset,
             GLboolean _internal) {
     SetHeader();
     target = _target;
@@ -5648,8 +5675,8 @@
             GLsizei _height,
             GLenum _format,
             GLenum _type,
-            uint32 _pixels_shm_id,
-            uint32 _pixels_shm_offset,
+            uint32_t _pixels_shm_id,
+            uint32_t _pixels_shm_offset,
             GLboolean _internal) {
     static_cast<ValueType*>(cmd)->Init(_target,
                                        _level,
@@ -5666,17 +5693,17 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 level;
-  int32 xoffset;
-  int32 yoffset;
-  int32 width;
-  int32 height;
-  uint32 format;
-  uint32 type;
-  uint32 pixels_shm_id;
-  uint32 pixels_shm_offset;
-  uint32 internal;
+  uint32_t target;
+  int32_t level;
+  int32_t xoffset;
+  int32_t yoffset;
+  int32_t width;
+  int32_t height;
+  uint32_t format;
+  uint32_t type;
+  uint32_t pixels_shm_id;
+  uint32_t pixels_shm_offset;
+  uint32_t internal;
 };
 
 COMPILE_ASSERT(sizeof(TexSubImage2D) == 48, Sizeof_TexSubImage2D_is_not_48);
@@ -5711,8 +5738,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5729,7 +5756,7 @@
   }
 
   gpu::CommandHeader header;
-  int32 location;
+  int32_t location;
   float x;
 };
 
@@ -5746,16 +5773,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     SetHeader();
     location = _location;
     count = _count;
@@ -5766,18 +5793,18 @@
   void* Set(void* cmd,
             GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_location, _count, _v_shm_id, _v_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 v_shm_id;
-  uint32 v_shm_offset;
+  int32_t location;
+  int32_t count;
+  uint32_t v_shm_id;
+  uint32_t v_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(Uniform1fv) == 20, Sizeof_Uniform1fv_is_not_20);
@@ -5798,13 +5825,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLfloat) * 1 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 1 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -5820,13 +5847,13 @@
 
   void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _v) {
     static_cast<ValueType*>(cmd)->Init(_location, _count, _v);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
+  int32_t location;
+  int32_t count;
 };
 
 COMPILE_ASSERT(sizeof(Uniform1fvImmediate) == 12,
@@ -5844,8 +5871,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5862,8 +5889,8 @@
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 x;
+  int32_t location;
+  int32_t x;
 };
 
 COMPILE_ASSERT(sizeof(Uniform1i) == 12, Sizeof_Uniform1i_is_not_12);
@@ -5879,16 +5906,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     SetHeader();
     location = _location;
     count = _count;
@@ -5899,18 +5926,18 @@
   void* Set(void* cmd,
             GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_location, _count, _v_shm_id, _v_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 v_shm_id;
-  uint32 v_shm_offset;
+  int32_t location;
+  int32_t count;
+  uint32_t v_shm_id;
+  uint32_t v_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(Uniform1iv) == 20, Sizeof_Uniform1iv_is_not_20);
@@ -5931,13 +5958,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLint) * 1 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLint) * 1 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -5953,13 +5980,13 @@
 
   void* Set(void* cmd, GLint _location, GLsizei _count, const GLint* _v) {
     static_cast<ValueType*>(cmd)->Init(_location, _count, _v);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
+  int32_t location;
+  int32_t count;
 };
 
 COMPILE_ASSERT(sizeof(Uniform1ivImmediate) == 12,
@@ -5977,8 +6004,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -5996,7 +6023,7 @@
   }
 
   gpu::CommandHeader header;
-  int32 location;
+  int32_t location;
   float x;
   float y;
 };
@@ -6015,16 +6042,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     SetHeader();
     location = _location;
     count = _count;
@@ -6035,18 +6062,18 @@
   void* Set(void* cmd,
             GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_location, _count, _v_shm_id, _v_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 v_shm_id;
-  uint32 v_shm_offset;
+  int32_t location;
+  int32_t count;
+  uint32_t v_shm_id;
+  uint32_t v_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(Uniform2fv) == 20, Sizeof_Uniform2fv_is_not_20);
@@ -6067,13 +6094,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLfloat) * 2 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 2 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -6089,13 +6116,13 @@
 
   void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _v) {
     static_cast<ValueType*>(cmd)->Init(_location, _count, _v);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
+  int32_t location;
+  int32_t count;
 };
 
 COMPILE_ASSERT(sizeof(Uniform2fvImmediate) == 12,
@@ -6113,8 +6140,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -6132,9 +6159,9 @@
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 x;
-  int32 y;
+  int32_t location;
+  int32_t x;
+  int32_t y;
 };
 
 COMPILE_ASSERT(sizeof(Uniform2i) == 16, Sizeof_Uniform2i_is_not_16);
@@ -6151,16 +6178,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     SetHeader();
     location = _location;
     count = _count;
@@ -6171,18 +6198,18 @@
   void* Set(void* cmd,
             GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_location, _count, _v_shm_id, _v_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 v_shm_id;
-  uint32 v_shm_offset;
+  int32_t location;
+  int32_t count;
+  uint32_t v_shm_id;
+  uint32_t v_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(Uniform2iv) == 20, Sizeof_Uniform2iv_is_not_20);
@@ -6203,13 +6230,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLint) * 2 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLint) * 2 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -6225,13 +6252,13 @@
 
   void* Set(void* cmd, GLint _location, GLsizei _count, const GLint* _v) {
     static_cast<ValueType*>(cmd)->Init(_location, _count, _v);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
+  int32_t location;
+  int32_t count;
 };
 
 COMPILE_ASSERT(sizeof(Uniform2ivImmediate) == 12,
@@ -6249,8 +6276,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -6269,7 +6296,7 @@
   }
 
   gpu::CommandHeader header;
-  int32 location;
+  int32_t location;
   float x;
   float y;
   float z;
@@ -6290,16 +6317,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     SetHeader();
     location = _location;
     count = _count;
@@ -6310,18 +6337,18 @@
   void* Set(void* cmd,
             GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_location, _count, _v_shm_id, _v_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 v_shm_id;
-  uint32 v_shm_offset;
+  int32_t location;
+  int32_t count;
+  uint32_t v_shm_id;
+  uint32_t v_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(Uniform3fv) == 20, Sizeof_Uniform3fv_is_not_20);
@@ -6342,13 +6369,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLfloat) * 3 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 3 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -6364,13 +6391,13 @@
 
   void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _v) {
     static_cast<ValueType*>(cmd)->Init(_location, _count, _v);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
+  int32_t location;
+  int32_t count;
 };
 
 COMPILE_ASSERT(sizeof(Uniform3fvImmediate) == 12,
@@ -6388,8 +6415,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -6408,10 +6435,10 @@
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 x;
-  int32 y;
-  int32 z;
+  int32_t location;
+  int32_t x;
+  int32_t y;
+  int32_t z;
 };
 
 COMPILE_ASSERT(sizeof(Uniform3i) == 20, Sizeof_Uniform3i_is_not_20);
@@ -6429,16 +6456,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     SetHeader();
     location = _location;
     count = _count;
@@ -6449,18 +6476,18 @@
   void* Set(void* cmd,
             GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_location, _count, _v_shm_id, _v_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 v_shm_id;
-  uint32 v_shm_offset;
+  int32_t location;
+  int32_t count;
+  uint32_t v_shm_id;
+  uint32_t v_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(Uniform3iv) == 20, Sizeof_Uniform3iv_is_not_20);
@@ -6481,13 +6508,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLint) * 3 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLint) * 3 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -6503,13 +6530,13 @@
 
   void* Set(void* cmd, GLint _location, GLsizei _count, const GLint* _v) {
     static_cast<ValueType*>(cmd)->Init(_location, _count, _v);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
+  int32_t location;
+  int32_t count;
 };
 
 COMPILE_ASSERT(sizeof(Uniform3ivImmediate) == 12,
@@ -6527,8 +6554,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -6553,7 +6580,7 @@
   }
 
   gpu::CommandHeader header;
-  int32 location;
+  int32_t location;
   float x;
   float y;
   float z;
@@ -6576,16 +6603,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     SetHeader();
     location = _location;
     count = _count;
@@ -6596,18 +6623,18 @@
   void* Set(void* cmd,
             GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_location, _count, _v_shm_id, _v_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 v_shm_id;
-  uint32 v_shm_offset;
+  int32_t location;
+  int32_t count;
+  uint32_t v_shm_id;
+  uint32_t v_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(Uniform4fv) == 20, Sizeof_Uniform4fv_is_not_20);
@@ -6628,13 +6655,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLfloat) * 4 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 4 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -6650,13 +6677,13 @@
 
   void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _v) {
     static_cast<ValueType*>(cmd)->Init(_location, _count, _v);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
+  int32_t location;
+  int32_t count;
 };
 
 COMPILE_ASSERT(sizeof(Uniform4fvImmediate) == 12,
@@ -6674,8 +6701,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -6700,11 +6727,11 @@
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 x;
-  int32 y;
-  int32 z;
-  int32 w;
+  int32_t location;
+  int32_t x;
+  int32_t y;
+  int32_t z;
+  int32_t w;
 };
 
 COMPILE_ASSERT(sizeof(Uniform4i) == 24, Sizeof_Uniform4i_is_not_24);
@@ -6723,16 +6750,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     SetHeader();
     location = _location;
     count = _count;
@@ -6743,18 +6770,18 @@
   void* Set(void* cmd,
             GLint _location,
             GLsizei _count,
-            uint32 _v_shm_id,
-            uint32 _v_shm_offset) {
+            uint32_t _v_shm_id,
+            uint32_t _v_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_location, _count, _v_shm_id, _v_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 v_shm_id;
-  uint32 v_shm_offset;
+  int32_t location;
+  int32_t count;
+  uint32_t v_shm_id;
+  uint32_t v_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(Uniform4iv) == 20, Sizeof_Uniform4iv_is_not_20);
@@ -6775,13 +6802,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLint) * 4 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLint) * 4 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -6797,13 +6824,13 @@
 
   void* Set(void* cmd, GLint _location, GLsizei _count, const GLint* _v) {
     static_cast<ValueType*>(cmd)->Init(_location, _count, _v);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
+  int32_t location;
+  int32_t count;
 };
 
 COMPILE_ASSERT(sizeof(Uniform4ivImmediate) == 12,
@@ -6821,8 +6848,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -6830,8 +6857,8 @@
   void Init(GLint _location,
             GLsizei _count,
             GLboolean _transpose,
-            uint32 _value_shm_id,
-            uint32 _value_shm_offset) {
+            uint32_t _value_shm_id,
+            uint32_t _value_shm_offset) {
     SetHeader();
     location = _location;
     count = _count;
@@ -6844,19 +6871,19 @@
             GLint _location,
             GLsizei _count,
             GLboolean _transpose,
-            uint32 _value_shm_id,
-            uint32 _value_shm_offset) {
+            uint32_t _value_shm_id,
+            uint32_t _value_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_location, _count, _transpose, _value_shm_id, _value_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 transpose;
-  uint32 value_shm_id;
-  uint32 value_shm_offset;
+  int32_t location;
+  int32_t count;
+  uint32_t transpose;
+  uint32_t value_shm_id;
+  uint32_t value_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(UniformMatrix2fv) == 24,
@@ -6880,13 +6907,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLfloat) * 4 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 4 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -6910,14 +6937,14 @@
             GLboolean _transpose,
             const GLfloat* _value) {
     static_cast<ValueType*>(cmd)->Init(_location, _count, _transpose, _value);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 transpose;
+  int32_t location;
+  int32_t count;
+  uint32_t transpose;
 };
 
 COMPILE_ASSERT(sizeof(UniformMatrix2fvImmediate) == 16,
@@ -6937,8 +6964,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -6946,8 +6973,8 @@
   void Init(GLint _location,
             GLsizei _count,
             GLboolean _transpose,
-            uint32 _value_shm_id,
-            uint32 _value_shm_offset) {
+            uint32_t _value_shm_id,
+            uint32_t _value_shm_offset) {
     SetHeader();
     location = _location;
     count = _count;
@@ -6960,19 +6987,19 @@
             GLint _location,
             GLsizei _count,
             GLboolean _transpose,
-            uint32 _value_shm_id,
-            uint32 _value_shm_offset) {
+            uint32_t _value_shm_id,
+            uint32_t _value_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_location, _count, _transpose, _value_shm_id, _value_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 transpose;
-  uint32 value_shm_id;
-  uint32 value_shm_offset;
+  int32_t location;
+  int32_t count;
+  uint32_t transpose;
+  uint32_t value_shm_id;
+  uint32_t value_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(UniformMatrix3fv) == 24,
@@ -6996,13 +7023,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLfloat) * 9 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 9 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -7026,14 +7053,14 @@
             GLboolean _transpose,
             const GLfloat* _value) {
     static_cast<ValueType*>(cmd)->Init(_location, _count, _transpose, _value);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 transpose;
+  int32_t location;
+  int32_t count;
+  uint32_t transpose;
 };
 
 COMPILE_ASSERT(sizeof(UniformMatrix3fvImmediate) == 16,
@@ -7053,8 +7080,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -7062,8 +7089,8 @@
   void Init(GLint _location,
             GLsizei _count,
             GLboolean _transpose,
-            uint32 _value_shm_id,
-            uint32 _value_shm_offset) {
+            uint32_t _value_shm_id,
+            uint32_t _value_shm_offset) {
     SetHeader();
     location = _location;
     count = _count;
@@ -7076,19 +7103,19 @@
             GLint _location,
             GLsizei _count,
             GLboolean _transpose,
-            uint32 _value_shm_id,
-            uint32 _value_shm_offset) {
+            uint32_t _value_shm_id,
+            uint32_t _value_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_location, _count, _transpose, _value_shm_id, _value_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 transpose;
-  uint32 value_shm_id;
-  uint32 value_shm_offset;
+  int32_t location;
+  int32_t count;
+  uint32_t transpose;
+  uint32_t value_shm_id;
+  uint32_t value_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(UniformMatrix4fv) == 24,
@@ -7112,13 +7139,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLfloat) * 16 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 16 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -7142,14 +7169,14 @@
             GLboolean _transpose,
             const GLfloat* _value) {
     static_cast<ValueType*>(cmd)->Init(_location, _count, _transpose, _value);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 location;
-  int32 count;
-  uint32 transpose;
+  int32_t location;
+  int32_t count;
+  uint32_t transpose;
 };
 
 COMPILE_ASSERT(sizeof(UniformMatrix4fvImmediate) == 16,
@@ -7169,8 +7196,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -7186,7 +7213,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 program;
+  uint32_t program;
 };
 
 COMPILE_ASSERT(sizeof(UseProgram) == 8, Sizeof_UseProgram_is_not_8);
@@ -7201,8 +7228,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -7218,7 +7245,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 program;
+  uint32_t program;
 };
 
 COMPILE_ASSERT(sizeof(ValidateProgram) == 8, Sizeof_ValidateProgram_is_not_8);
@@ -7233,8 +7260,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -7251,7 +7278,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
+  uint32_t indx;
   float x;
 };
 
@@ -7269,13 +7296,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _indx, uint32 _values_shm_id, uint32 _values_shm_offset) {
+  void Init(GLuint _indx,
+            uint32_t _values_shm_id,
+            uint32_t _values_shm_offset) {
     SetHeader();
     indx = _indx;
     values_shm_id = _values_shm_id;
@@ -7284,17 +7313,17 @@
 
   void* Set(void* cmd,
             GLuint _indx,
-            uint32 _values_shm_id,
-            uint32 _values_shm_offset) {
+            uint32_t _values_shm_id,
+            uint32_t _values_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_indx, _values_shm_id, _values_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
-  uint32 values_shm_id;
-  uint32 values_shm_offset;
+  uint32_t indx;
+  uint32_t values_shm_id;
+  uint32_t values_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(VertexAttrib1fv) == 16, Sizeof_VertexAttrib1fv_is_not_16);
@@ -7313,13 +7342,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize() {
-    return static_cast<uint32>(sizeof(GLfloat) * 1);  // NOLINT
+  static uint32_t ComputeDataSize() {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 1);  // NOLINT
   }
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize());  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize());  // NOLINT
   }
 
   void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); }
@@ -7332,12 +7361,12 @@
 
   void* Set(void* cmd, GLuint _indx, const GLfloat* _values) {
     static_cast<ValueType*>(cmd)->Init(_indx, _values);
-    const uint32 size = ComputeSize();
+    const uint32_t size = ComputeSize();
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
+  uint32_t indx;
 };
 
 COMPILE_ASSERT(sizeof(VertexAttrib1fvImmediate) == 8,
@@ -7353,8 +7382,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -7372,7 +7401,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
+  uint32_t indx;
   float x;
   float y;
 };
@@ -7393,13 +7422,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _indx, uint32 _values_shm_id, uint32 _values_shm_offset) {
+  void Init(GLuint _indx,
+            uint32_t _values_shm_id,
+            uint32_t _values_shm_offset) {
     SetHeader();
     indx = _indx;
     values_shm_id = _values_shm_id;
@@ -7408,17 +7439,17 @@
 
   void* Set(void* cmd,
             GLuint _indx,
-            uint32 _values_shm_id,
-            uint32 _values_shm_offset) {
+            uint32_t _values_shm_id,
+            uint32_t _values_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_indx, _values_shm_id, _values_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
-  uint32 values_shm_id;
-  uint32 values_shm_offset;
+  uint32_t indx;
+  uint32_t values_shm_id;
+  uint32_t values_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(VertexAttrib2fv) == 16, Sizeof_VertexAttrib2fv_is_not_16);
@@ -7437,13 +7468,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize() {
-    return static_cast<uint32>(sizeof(GLfloat) * 2);  // NOLINT
+  static uint32_t ComputeDataSize() {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 2);  // NOLINT
   }
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize());  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize());  // NOLINT
   }
 
   void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); }
@@ -7456,12 +7487,12 @@
 
   void* Set(void* cmd, GLuint _indx, const GLfloat* _values) {
     static_cast<ValueType*>(cmd)->Init(_indx, _values);
-    const uint32 size = ComputeSize();
+    const uint32_t size = ComputeSize();
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
+  uint32_t indx;
 };
 
 COMPILE_ASSERT(sizeof(VertexAttrib2fvImmediate) == 8,
@@ -7477,8 +7508,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -7497,7 +7528,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
+  uint32_t indx;
   float x;
   float y;
   float z;
@@ -7521,13 +7552,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _indx, uint32 _values_shm_id, uint32 _values_shm_offset) {
+  void Init(GLuint _indx,
+            uint32_t _values_shm_id,
+            uint32_t _values_shm_offset) {
     SetHeader();
     indx = _indx;
     values_shm_id = _values_shm_id;
@@ -7536,17 +7569,17 @@
 
   void* Set(void* cmd,
             GLuint _indx,
-            uint32 _values_shm_id,
-            uint32 _values_shm_offset) {
+            uint32_t _values_shm_id,
+            uint32_t _values_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_indx, _values_shm_id, _values_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
-  uint32 values_shm_id;
-  uint32 values_shm_offset;
+  uint32_t indx;
+  uint32_t values_shm_id;
+  uint32_t values_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(VertexAttrib3fv) == 16, Sizeof_VertexAttrib3fv_is_not_16);
@@ -7565,13 +7598,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize() {
-    return static_cast<uint32>(sizeof(GLfloat) * 3);  // NOLINT
+  static uint32_t ComputeDataSize() {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 3);  // NOLINT
   }
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize());  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize());  // NOLINT
   }
 
   void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); }
@@ -7584,12 +7617,12 @@
 
   void* Set(void* cmd, GLuint _indx, const GLfloat* _values) {
     static_cast<ValueType*>(cmd)->Init(_indx, _values);
-    const uint32 size = ComputeSize();
+    const uint32_t size = ComputeSize();
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
+  uint32_t indx;
 };
 
 COMPILE_ASSERT(sizeof(VertexAttrib3fvImmediate) == 8,
@@ -7605,8 +7638,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -7631,7 +7664,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
+  uint32_t indx;
   float x;
   float y;
   float z;
@@ -7658,13 +7691,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _indx, uint32 _values_shm_id, uint32 _values_shm_offset) {
+  void Init(GLuint _indx,
+            uint32_t _values_shm_id,
+            uint32_t _values_shm_offset) {
     SetHeader();
     indx = _indx;
     values_shm_id = _values_shm_id;
@@ -7673,17 +7708,17 @@
 
   void* Set(void* cmd,
             GLuint _indx,
-            uint32 _values_shm_id,
-            uint32 _values_shm_offset) {
+            uint32_t _values_shm_id,
+            uint32_t _values_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_indx, _values_shm_id, _values_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
-  uint32 values_shm_id;
-  uint32 values_shm_offset;
+  uint32_t indx;
+  uint32_t values_shm_id;
+  uint32_t values_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(VertexAttrib4fv) == 16, Sizeof_VertexAttrib4fv_is_not_16);
@@ -7702,13 +7737,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize() {
-    return static_cast<uint32>(sizeof(GLfloat) * 4);  // NOLINT
+  static uint32_t ComputeDataSize() {
+    return static_cast<uint32_t>(sizeof(GLfloat) * 4);  // NOLINT
   }
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize());  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize());  // NOLINT
   }
 
   void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); }
@@ -7721,12 +7756,12 @@
 
   void* Set(void* cmd, GLuint _indx, const GLfloat* _values) {
     static_cast<ValueType*>(cmd)->Init(_indx, _values);
-    const uint32 size = ComputeSize();
+    const uint32_t size = ComputeSize();
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
+  uint32_t indx;
 };
 
 COMPILE_ASSERT(sizeof(VertexAttrib4fvImmediate) == 8,
@@ -7742,8 +7777,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -7776,12 +7811,12 @@
   }
 
   gpu::CommandHeader header;
-  uint32 indx;
-  int32 size;
-  uint32 type;
-  uint32 normalized;
-  int32 stride;
-  uint32 offset;
+  uint32_t indx;
+  int32_t size;
+  uint32_t type;
+  uint32_t normalized;
+  int32_t stride;
+  uint32_t offset;
 };
 
 COMPILE_ASSERT(sizeof(VertexAttribPointer) == 28,
@@ -7807,8 +7842,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -7827,10 +7862,10 @@
   }
 
   gpu::CommandHeader header;
-  int32 x;
-  int32 y;
-  int32 width;
-  int32 height;
+  int32_t x;
+  int32_t y;
+  int32_t width;
+  int32_t height;
 };
 
 COMPILE_ASSERT(sizeof(Viewport) == 20, Sizeof_Viewport_is_not_20);
@@ -7847,8 +7882,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -7901,16 +7936,16 @@
   }
 
   gpu::CommandHeader header;
-  int32 srcX0;
-  int32 srcY0;
-  int32 srcX1;
-  int32 srcY1;
-  int32 dstX0;
-  int32 dstY0;
-  int32 dstX1;
-  int32 dstY1;
-  uint32 mask;
-  uint32 filter;
+  int32_t srcX0;
+  int32_t srcY0;
+  int32_t srcX1;
+  int32_t srcY1;
+  int32_t dstX0;
+  int32_t dstY0;
+  int32_t dstX1;
+  int32_t dstY1;
+  uint32_t mask;
+  uint32_t filter;
 };
 
 COMPILE_ASSERT(sizeof(BlitFramebufferCHROMIUM) == 44,
@@ -7945,8 +7980,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -7976,11 +8011,11 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 samples;
-  uint32 internalformat;
-  int32 width;
-  int32 height;
+  uint32_t target;
+  int32_t samples;
+  uint32_t internalformat;
+  int32_t width;
+  int32_t height;
 };
 
 COMPILE_ASSERT(sizeof(RenderbufferStorageMultisampleCHROMIUM) == 24,
@@ -8006,8 +8041,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -8037,11 +8072,11 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 samples;
-  uint32 internalformat;
-  int32 width;
-  int32 height;
+  uint32_t target;
+  int32_t samples;
+  uint32_t internalformat;
+  int32_t width;
+  int32_t height;
 };
 
 COMPILE_ASSERT(sizeof(RenderbufferStorageMultisampleEXT) == 24,
@@ -8066,8 +8101,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -8100,12 +8135,12 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 attachment;
-  uint32 textarget;
-  uint32 texture;
-  int32 level;
-  int32 samples;
+  uint32_t target;
+  uint32_t attachment;
+  uint32_t textarget;
+  uint32_t texture;
+  int32_t level;
+  int32_t samples;
 };
 
 COMPILE_ASSERT(sizeof(FramebufferTexture2DMultisampleEXT) == 28,
@@ -8131,8 +8166,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -8162,11 +8197,11 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 levels;
-  uint32 internalFormat;
-  int32 width;
-  int32 height;
+  uint32_t target;
+  int32_t levels;
+  uint32_t internalFormat;
+  int32_t width;
+  int32_t height;
 };
 
 COMPILE_ASSERT(sizeof(TexStorage2DEXT) == 24, Sizeof_TexStorage2DEXT_is_not_24);
@@ -8189,13 +8224,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLsizei _n, uint32 _queries_shm_id, uint32 _queries_shm_offset) {
+  void Init(GLsizei _n,
+            uint32_t _queries_shm_id,
+            uint32_t _queries_shm_offset) {
     SetHeader();
     n = _n;
     queries_shm_id = _queries_shm_id;
@@ -8204,17 +8241,17 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _queries_shm_id,
-            uint32 _queries_shm_offset) {
+            uint32_t _queries_shm_id,
+            uint32_t _queries_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_n, _queries_shm_id, _queries_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 queries_shm_id;
-  uint32 queries_shm_offset;
+  int32_t n;
+  uint32_t queries_shm_id;
+  uint32_t queries_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GenQueriesEXT) == 16, Sizeof_GenQueriesEXT_is_not_16);
@@ -8232,13 +8269,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -8253,12 +8290,12 @@
 
   void* Set(void* cmd, GLsizei _n, GLuint* _queries) {
     static_cast<ValueType*>(cmd)->Init(_n, _queries);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(GenQueriesEXTImmediate) == 8,
@@ -8274,13 +8311,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLsizei _n, uint32 _queries_shm_id, uint32 _queries_shm_offset) {
+  void Init(GLsizei _n,
+            uint32_t _queries_shm_id,
+            uint32_t _queries_shm_offset) {
     SetHeader();
     n = _n;
     queries_shm_id = _queries_shm_id;
@@ -8289,17 +8328,17 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _queries_shm_id,
-            uint32 _queries_shm_offset) {
+            uint32_t _queries_shm_id,
+            uint32_t _queries_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_n, _queries_shm_id, _queries_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 queries_shm_id;
-  uint32 queries_shm_offset;
+  int32_t n;
+  uint32_t queries_shm_id;
+  uint32_t queries_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(DeleteQueriesEXT) == 16,
@@ -8319,13 +8358,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -8340,12 +8379,12 @@
 
   void* Set(void* cmd, GLsizei _n, const GLuint* _queries) {
     static_cast<ValueType*>(cmd)->Init(_n, _queries);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(DeleteQueriesEXTImmediate) == 8,
@@ -8361,16 +8400,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _target,
             GLuint _id,
-            uint32 _sync_data_shm_id,
-            uint32 _sync_data_shm_offset) {
+            uint32_t _sync_data_shm_id,
+            uint32_t _sync_data_shm_offset) {
     SetHeader();
     target = _target;
     id = _id;
@@ -8381,18 +8420,18 @@
   void* Set(void* cmd,
             GLenum _target,
             GLuint _id,
-            uint32 _sync_data_shm_id,
-            uint32 _sync_data_shm_offset) {
+            uint32_t _sync_data_shm_id,
+            uint32_t _sync_data_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _id, _sync_data_shm_id, _sync_data_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 id;
-  uint32 sync_data_shm_id;
-  uint32 sync_data_shm_offset;
+  uint32_t target;
+  uint32_t id;
+  uint32_t sync_data_shm_id;
+  uint32_t sync_data_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(BeginQueryEXT) == 20, Sizeof_BeginQueryEXT_is_not_20);
@@ -8413,8 +8452,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -8431,8 +8470,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 submit_count;
+  uint32_t target;
+  uint32_t submit_count;
 };
 
 COMPILE_ASSERT(sizeof(EndQueryEXT) == 12, Sizeof_EndQueryEXT_is_not_12);
@@ -8449,8 +8488,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -8466,7 +8505,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 bucket_id;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(InsertEventMarkerEXT) == 8,
@@ -8482,8 +8521,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -8499,7 +8538,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 bucket_id;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(PushGroupMarkerEXT) == 8,
@@ -8515,8 +8554,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -8542,13 +8581,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLsizei _n, uint32 _arrays_shm_id, uint32 _arrays_shm_offset) {
+  void Init(GLsizei _n, uint32_t _arrays_shm_id, uint32_t _arrays_shm_offset) {
     SetHeader();
     n = _n;
     arrays_shm_id = _arrays_shm_id;
@@ -8557,16 +8596,16 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _arrays_shm_id,
-            uint32 _arrays_shm_offset) {
+            uint32_t _arrays_shm_id,
+            uint32_t _arrays_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(_n, _arrays_shm_id, _arrays_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 arrays_shm_id;
-  uint32 arrays_shm_offset;
+  int32_t n;
+  uint32_t arrays_shm_id;
+  uint32_t arrays_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GenVertexArraysOES) == 16,
@@ -8586,13 +8625,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -8607,12 +8646,12 @@
 
   void* Set(void* cmd, GLsizei _n, GLuint* _arrays) {
     static_cast<ValueType*>(cmd)->Init(_n, _arrays);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(GenVertexArraysOESImmediate) == 8,
@@ -8628,13 +8667,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLsizei _n, uint32 _arrays_shm_id, uint32 _arrays_shm_offset) {
+  void Init(GLsizei _n, uint32_t _arrays_shm_id, uint32_t _arrays_shm_offset) {
     SetHeader();
     n = _n;
     arrays_shm_id = _arrays_shm_id;
@@ -8643,16 +8682,16 @@
 
   void* Set(void* cmd,
             GLsizei _n,
-            uint32 _arrays_shm_id,
-            uint32 _arrays_shm_offset) {
+            uint32_t _arrays_shm_id,
+            uint32_t _arrays_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(_n, _arrays_shm_id, _arrays_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 n;
-  uint32 arrays_shm_id;
-  uint32 arrays_shm_offset;
+  int32_t n;
+  uint32_t arrays_shm_id;
+  uint32_t arrays_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(DeleteVertexArraysOES) == 16,
@@ -8672,13 +8711,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(GLuint) * n);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(GLuint) * n);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei n) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(n));  // NOLINT
+  static uint32_t ComputeSize(GLsizei n) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(n));  // NOLINT
   }
 
   void SetHeader(GLsizei n) {
@@ -8693,12 +8732,12 @@
 
   void* Set(void* cmd, GLsizei _n, const GLuint* _arrays) {
     static_cast<ValueType*>(cmd)->Init(_n, _arrays);
-    const uint32 size = ComputeSize(_n);
+    const uint32_t size = ComputeSize(_n);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 n;
+  int32_t n;
 };
 
 COMPILE_ASSERT(sizeof(DeleteVertexArraysOESImmediate) == 8,
@@ -8714,15 +8753,17 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  typedef uint32 Result;
+  typedef uint32_t Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _array, uint32 _result_shm_id, uint32 _result_shm_offset) {
+  void Init(GLuint _array,
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     array = _array;
     result_shm_id = _result_shm_id;
@@ -8731,17 +8772,17 @@
 
   void* Set(void* cmd,
             GLuint _array,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_array, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 array;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t array;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(IsVertexArrayOES) == 16,
@@ -8761,8 +8802,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -8778,7 +8819,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 array;
+  uint32_t array;
 };
 
 COMPILE_ASSERT(sizeof(BindVertexArrayOES) == 8,
@@ -8794,8 +8835,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -8822,8 +8863,8 @@
 
   typedef GLuint Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -8832,8 +8873,8 @@
             GLsizei _count,
             GLenum _type,
             GLuint _offset,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     buffer_id = _buffer_id;
     count = _count;
@@ -8848,20 +8889,20 @@
             GLsizei _count,
             GLenum _type,
             GLuint _offset,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(
         _buffer_id, _count, _type, _offset, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 buffer_id;
-  int32 count;
-  uint32 type;
-  uint32 offset;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t buffer_id;
+  int32_t count;
+  uint32_t type;
+  uint32_t offset;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GetMaxValueInBufferCHROMIUM) == 28,
@@ -8887,8 +8928,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -8896,8 +8937,8 @@
   void Init(GLuint _namespace_id,
             GLuint _id_offset,
             GLsizei _n,
-            uint32 _ids_shm_id,
-            uint32 _ids_shm_offset) {
+            uint32_t _ids_shm_id,
+            uint32_t _ids_shm_offset) {
     SetHeader();
     namespace_id = _namespace_id;
     id_offset = _id_offset;
@@ -8910,19 +8951,19 @@
             GLuint _namespace_id,
             GLuint _id_offset,
             GLsizei _n,
-            uint32 _ids_shm_id,
-            uint32 _ids_shm_offset) {
+            uint32_t _ids_shm_id,
+            uint32_t _ids_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_namespace_id, _id_offset, _n, _ids_shm_id, _ids_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 namespace_id;
-  uint32 id_offset;
-  int32 n;
-  uint32 ids_shm_id;
-  uint32 ids_shm_offset;
+  uint32_t namespace_id;
+  uint32_t id_offset;
+  int32_t n;
+  uint32_t ids_shm_id;
+  uint32_t ids_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(GenSharedIdsCHROMIUM) == 24,
@@ -8946,16 +8987,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _namespace_id,
             GLsizei _n,
-            uint32 _ids_shm_id,
-            uint32 _ids_shm_offset) {
+            uint32_t _ids_shm_id,
+            uint32_t _ids_shm_offset) {
     SetHeader();
     namespace_id = _namespace_id;
     n = _n;
@@ -8966,18 +9007,18 @@
   void* Set(void* cmd,
             GLuint _namespace_id,
             GLsizei _n,
-            uint32 _ids_shm_id,
-            uint32 _ids_shm_offset) {
+            uint32_t _ids_shm_id,
+            uint32_t _ids_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_namespace_id, _n, _ids_shm_id, _ids_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 namespace_id;
-  int32 n;
-  uint32 ids_shm_id;
-  uint32 ids_shm_offset;
+  uint32_t namespace_id;
+  int32_t n;
+  uint32_t ids_shm_id;
+  uint32_t ids_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(DeleteSharedIdsCHROMIUM) == 20,
@@ -8999,16 +9040,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _namespace_id,
             GLsizei _n,
-            uint32 _ids_shm_id,
-            uint32 _ids_shm_offset) {
+            uint32_t _ids_shm_id,
+            uint32_t _ids_shm_offset) {
     SetHeader();
     namespace_id = _namespace_id;
     n = _n;
@@ -9019,18 +9060,18 @@
   void* Set(void* cmd,
             GLuint _namespace_id,
             GLsizei _n,
-            uint32 _ids_shm_id,
-            uint32 _ids_shm_offset) {
+            uint32_t _ids_shm_id,
+            uint32_t _ids_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_namespace_id, _n, _ids_shm_id, _ids_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 namespace_id;
-  int32 n;
-  uint32 ids_shm_id;
-  uint32 ids_shm_offset;
+  uint32_t namespace_id;
+  int32_t n;
+  uint32_t ids_shm_id;
+  uint32_t ids_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(RegisterSharedIdsCHROMIUM) == 20,
@@ -9054,15 +9095,15 @@
 
   typedef GLint Result;
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _bucket_id,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     SetHeader();
     bucket_id = _bucket_id;
     result_shm_id = _result_shm_id;
@@ -9071,17 +9112,17 @@
 
   void* Set(void* cmd,
             GLuint _bucket_id,
-            uint32 _result_shm_id,
-            uint32 _result_shm_offset) {
+            uint32_t _result_shm_id,
+            uint32_t _result_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_bucket_id, _result_shm_id, _result_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 bucket_id;
-  uint32 result_shm_id;
-  uint32 result_shm_offset;
+  uint32_t bucket_id;
+  uint32_t result_shm_id;
+  uint32_t result_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(EnableFeatureCHROMIUM) == 16,
@@ -9101,8 +9142,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -9120,8 +9161,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 width;
-  uint32 height;
+  uint32_t width;
+  uint32_t height;
   float scale_factor;
 };
 
@@ -9141,24 +9182,24 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(uint32 _bucket_id) {
+  void Init(uint32_t _bucket_id) {
     SetHeader();
     bucket_id = _bucket_id;
   }
 
-  void* Set(void* cmd, uint32 _bucket_id) {
+  void* Set(void* cmd, uint32_t _bucket_id) {
     static_cast<ValueType*>(cmd)->Init(_bucket_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 bucket_id;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(GetRequestableExtensionsCHROMIUM) == 8,
@@ -9174,24 +9215,24 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(uint32 _bucket_id) {
+  void Init(uint32_t _bucket_id) {
     SetHeader();
     bucket_id = _bucket_id;
   }
 
-  void* Set(void* cmd, uint32 _bucket_id) {
+  void* Set(void* cmd, uint32_t _bucket_id) {
     static_cast<ValueType*>(cmd)->Init(_bucket_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 bucket_id;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(RequestExtensionCHROMIUM) == 8,
@@ -9207,17 +9248,17 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(uint32 _pnames_shm_id,
-            uint32 _pnames_shm_offset,
+  void Init(uint32_t _pnames_shm_id,
+            uint32_t _pnames_shm_offset,
             GLuint _count,
-            uint32 _results_shm_id,
-            uint32 _results_shm_offset,
+            uint32_t _results_shm_id,
+            uint32_t _results_shm_offset,
             GLsizeiptr _size) {
     SetHeader();
     pnames_shm_id = _pnames_shm_id;
@@ -9229,11 +9270,11 @@
   }
 
   void* Set(void* cmd,
-            uint32 _pnames_shm_id,
-            uint32 _pnames_shm_offset,
+            uint32_t _pnames_shm_id,
+            uint32_t _pnames_shm_offset,
             GLuint _count,
-            uint32 _results_shm_id,
-            uint32 _results_shm_offset,
+            uint32_t _results_shm_id,
+            uint32_t _results_shm_offset,
             GLsizeiptr _size) {
     static_cast<ValueType*>(cmd)->Init(_pnames_shm_id,
                                        _pnames_shm_offset,
@@ -9245,12 +9286,12 @@
   }
 
   gpu::CommandHeader header;
-  uint32 pnames_shm_id;
-  uint32 pnames_shm_offset;
-  uint32 count;
-  uint32 results_shm_id;
-  uint32 results_shm_offset;
-  int32 size;
+  uint32_t pnames_shm_id;
+  uint32_t pnames_shm_offset;
+  uint32_t count;
+  uint32_t results_shm_id;
+  uint32_t results_shm_offset;
+  int32_t size;
 };
 
 COMPILE_ASSERT(sizeof(GetMultipleIntegervCHROMIUM) == 28,
@@ -9277,31 +9318,31 @@
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
   struct Result {
-    uint32 link_status;
-    uint32 num_attribs;
-    uint32 num_uniforms;
+    uint32_t link_status;
+    uint32_t num_attribs;
+    uint32_t num_uniforms;
   };
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _program, uint32 _bucket_id) {
+  void Init(GLuint _program, uint32_t _bucket_id) {
     SetHeader();
     program = _program;
     bucket_id = _bucket_id;
   }
 
-  void* Set(void* cmd, GLuint _program, uint32 _bucket_id) {
+  void* Set(void* cmd, GLuint _program, uint32_t _bucket_id) {
     static_cast<ValueType*>(cmd)->Init(_program, _bucket_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  uint32 bucket_id;
+  uint32_t program;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(GetProgramInfoCHROMIUM) == 12,
@@ -9325,26 +9366,26 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _shader, uint32 _bucket_id) {
+  void Init(GLuint _shader, uint32_t _bucket_id) {
     SetHeader();
     shader = _shader;
     bucket_id = _bucket_id;
   }
 
-  void* Set(void* cmd, GLuint _shader, uint32 _bucket_id) {
+  void* Set(void* cmd, GLuint _shader, uint32_t _bucket_id) {
     static_cast<ValueType*>(cmd)->Init(_shader, _bucket_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 shader;
-  uint32 bucket_id;
+  uint32_t shader;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(GetTranslatedShaderSourceANGLE) == 12,
@@ -9362,8 +9403,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -9382,10 +9423,10 @@
   }
 
   gpu::CommandHeader header;
-  int32 x;
-  int32 y;
-  int32 width;
-  int32 height;
+  int32_t x;
+  int32_t y;
+  int32_t width;
+  int32_t height;
 };
 
 COMPILE_ASSERT(sizeof(PostSubBufferCHROMIUM) == 20,
@@ -9407,8 +9448,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -9438,11 +9479,11 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 width;
-  int32 height;
-  uint32 ioSurfaceId;
-  uint32 plane;
+  uint32_t target;
+  int32_t width;
+  int32_t height;
+  uint32_t ioSurfaceId;
+  uint32_t plane;
 };
 
 COMPILE_ASSERT(sizeof(TexImageIOSurface2DCHROMIUM) == 24,
@@ -9466,8 +9507,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -9500,12 +9541,12 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 source_id;
-  uint32 dest_id;
-  int32 level;
-  int32 internalformat;
-  uint32 dest_type;
+  uint32_t target;
+  uint32_t source_id;
+  uint32_t dest_id;
+  int32_t level;
+  int32_t internalformat;
+  uint32_t dest_type;
 };
 
 COMPILE_ASSERT(sizeof(CopyTextureCHROMIUM) == 28,
@@ -9531,8 +9572,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -9555,10 +9596,10 @@
   }
 
   gpu::CommandHeader header;
-  uint32 mode;
-  int32 first;
-  int32 count;
-  int32 primcount;
+  uint32_t mode;
+  int32_t first;
+  int32_t count;
+  int32_t primcount;
 };
 
 COMPILE_ASSERT(sizeof(DrawArraysInstancedANGLE) == 20,
@@ -9580,8 +9621,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -9611,11 +9652,11 @@
   }
 
   gpu::CommandHeader header;
-  uint32 mode;
-  int32 count;
-  uint32 type;
-  uint32 index_offset;
-  int32 primcount;
+  uint32_t mode;
+  int32_t count;
+  uint32_t type;
+  uint32_t index_offset;
+  int32_t primcount;
 };
 
 COMPILE_ASSERT(sizeof(DrawElementsInstancedANGLE) == 24,
@@ -9639,8 +9680,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -9657,8 +9698,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 index;
-  uint32 divisor;
+  uint32_t index;
+  uint32_t divisor;
 };
 
 COMPILE_ASSERT(sizeof(VertexAttribDivisorANGLE) == 12,
@@ -9676,15 +9717,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _target,
-            uint32 _mailbox_shm_id,
-            uint32 _mailbox_shm_offset) {
+            uint32_t _mailbox_shm_id,
+            uint32_t _mailbox_shm_offset) {
     SetHeader();
     target = _target;
     mailbox_shm_id = _mailbox_shm_id;
@@ -9693,17 +9734,17 @@
 
   void* Set(void* cmd,
             GLenum _target,
-            uint32 _mailbox_shm_id,
-            uint32 _mailbox_shm_offset) {
+            uint32_t _mailbox_shm_id,
+            uint32_t _mailbox_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _mailbox_shm_id, _mailbox_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 mailbox_shm_id;
-  uint32 mailbox_shm_offset;
+  uint32_t target;
+  uint32_t mailbox_shm_id;
+  uint32_t mailbox_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(ProduceTextureCHROMIUM) == 16,
@@ -9723,13 +9764,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeDataSize() {
-    return static_cast<uint32>(sizeof(GLbyte) * 64);  // NOLINT
+  static uint32_t ComputeDataSize() {
+    return static_cast<uint32_t>(sizeof(GLbyte) * 64);  // NOLINT
   }
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize());  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize());  // NOLINT
   }
 
   void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); }
@@ -9742,12 +9783,12 @@
 
   void* Set(void* cmd, GLenum _target, const GLbyte* _mailbox) {
     static_cast<ValueType*>(cmd)->Init(_target, _mailbox);
-    const uint32 size = ComputeSize();
+    const uint32_t size = ComputeSize();
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
+  uint32_t target;
 };
 
 COMPILE_ASSERT(sizeof(ProduceTextureCHROMIUMImmediate) == 8,
@@ -9763,15 +9804,15 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _target,
-            uint32 _mailbox_shm_id,
-            uint32 _mailbox_shm_offset) {
+            uint32_t _mailbox_shm_id,
+            uint32_t _mailbox_shm_offset) {
     SetHeader();
     target = _target;
     mailbox_shm_id = _mailbox_shm_id;
@@ -9780,17 +9821,17 @@
 
   void* Set(void* cmd,
             GLenum _target,
-            uint32 _mailbox_shm_id,
-            uint32 _mailbox_shm_offset) {
+            uint32_t _mailbox_shm_id,
+            uint32_t _mailbox_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _mailbox_shm_id, _mailbox_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  uint32 mailbox_shm_id;
-  uint32 mailbox_shm_offset;
+  uint32_t target;
+  uint32_t mailbox_shm_id;
+  uint32_t mailbox_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(ConsumeTextureCHROMIUM) == 16,
@@ -9810,13 +9851,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeDataSize() {
-    return static_cast<uint32>(sizeof(GLbyte) * 64);  // NOLINT
+  static uint32_t ComputeDataSize() {
+    return static_cast<uint32_t>(sizeof(GLbyte) * 64);  // NOLINT
   }
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize());  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize());  // NOLINT
   }
 
   void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); }
@@ -9829,12 +9870,12 @@
 
   void* Set(void* cmd, GLenum _target, const GLbyte* _mailbox) {
     static_cast<ValueType*>(cmd)->Init(_target, _mailbox);
-    const uint32 size = ComputeSize();
+    const uint32_t size = ComputeSize();
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
+  uint32_t target;
 };
 
 COMPILE_ASSERT(sizeof(ConsumeTextureCHROMIUMImmediate) == 8,
@@ -9850,17 +9891,17 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLuint _program,
             GLint _location,
-            uint32 _name_shm_id,
-            uint32 _name_shm_offset,
-            uint32 _data_size) {
+            uint32_t _name_shm_id,
+            uint32_t _name_shm_offset,
+            uint32_t _data_size) {
     SetHeader();
     program = _program;
     location = _location;
@@ -9872,20 +9913,20 @@
   void* Set(void* cmd,
             GLuint _program,
             GLint _location,
-            uint32 _name_shm_id,
-            uint32 _name_shm_offset,
-            uint32 _data_size) {
+            uint32_t _name_shm_id,
+            uint32_t _name_shm_offset,
+            uint32_t _data_size) {
     static_cast<ValueType*>(cmd)
         ->Init(_program, _location, _name_shm_id, _name_shm_offset, _data_size);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  int32 location;
-  uint32 name_shm_id;
-  uint32 name_shm_offset;
-  uint32 data_size;
+  uint32_t program;
+  int32_t location;
+  uint32_t name_shm_id;
+  uint32_t name_shm_offset;
+  uint32_t data_size;
 };
 
 COMPILE_ASSERT(sizeof(BindUniformLocationCHROMIUM) == 24,
@@ -9909,13 +9950,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLuint _program, GLint _location, uint32 _name_bucket_id) {
+  void Init(GLuint _program, GLint _location, uint32_t _name_bucket_id) {
     SetHeader();
     program = _program;
     location = _location;
@@ -9925,15 +9966,15 @@
   void* Set(void* cmd,
             GLuint _program,
             GLint _location,
-            uint32 _name_bucket_id) {
+            uint32_t _name_bucket_id) {
     static_cast<ValueType*>(cmd)->Init(_program, _location, _name_bucket_id);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 program;
-  int32 location;
-  uint32 name_bucket_id;
+  uint32_t program;
+  int32_t location;
+  uint32_t name_bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(BindUniformLocationCHROMIUMBucket) == 16,
@@ -9954,8 +9995,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -9972,8 +10013,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 imageId;
+  uint32_t target;
+  int32_t imageId;
 };
 
 COMPILE_ASSERT(sizeof(BindTexImage2DCHROMIUM) == 12,
@@ -9991,8 +10032,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -10009,8 +10050,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 imageId;
+  uint32_t target;
+  int32_t imageId;
 };
 
 COMPILE_ASSERT(sizeof(ReleaseTexImage2DCHROMIUM) == 12,
@@ -10028,8 +10069,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -10045,7 +10086,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 bucket_id;
+  uint32_t bucket_id;
 };
 
 COMPILE_ASSERT(sizeof(TraceBeginCHROMIUM) == 8,
@@ -10061,8 +10102,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -10087,8 +10128,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -10101,11 +10142,11 @@
             GLsizei _height,
             GLenum _format,
             GLenum _type,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset,
-            uint32 _async_upload_token,
-            uint32 _sync_data_shm_id,
-            uint32 _sync_data_shm_offset) {
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset,
+            uint32_t _async_upload_token,
+            uint32_t _sync_data_shm_id,
+            uint32_t _sync_data_shm_offset) {
     SetHeader();
     target = _target;
     level = _level;
@@ -10131,11 +10172,11 @@
             GLsizei _height,
             GLenum _format,
             GLenum _type,
-            uint32 _data_shm_id,
-            uint32 _data_shm_offset,
-            uint32 _async_upload_token,
-            uint32 _sync_data_shm_id,
-            uint32 _sync_data_shm_offset) {
+            uint32_t _data_shm_id,
+            uint32_t _data_shm_offset,
+            uint32_t _async_upload_token,
+            uint32_t _sync_data_shm_id,
+            uint32_t _sync_data_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(_target,
                                        _level,
                                        _xoffset,
@@ -10153,19 +10194,19 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 level;
-  int32 xoffset;
-  int32 yoffset;
-  int32 width;
-  int32 height;
-  uint32 format;
-  uint32 type;
-  uint32 data_shm_id;
-  uint32 data_shm_offset;
-  uint32 async_upload_token;
-  uint32 sync_data_shm_id;
-  uint32 sync_data_shm_offset;
+  uint32_t target;
+  int32_t level;
+  int32_t xoffset;
+  int32_t yoffset;
+  int32_t width;
+  int32_t height;
+  uint32_t format;
+  uint32_t type;
+  uint32_t data_shm_id;
+  uint32_t data_shm_offset;
+  uint32_t async_upload_token;
+  uint32_t sync_data_shm_id;
+  uint32_t sync_data_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(AsyncTexSubImage2DCHROMIUM) == 56,
@@ -10205,8 +10246,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -10219,11 +10260,11 @@
             GLint _border,
             GLenum _format,
             GLenum _type,
-            uint32 _pixels_shm_id,
-            uint32 _pixels_shm_offset,
-            uint32 _async_upload_token,
-            uint32 _sync_data_shm_id,
-            uint32 _sync_data_shm_offset) {
+            uint32_t _pixels_shm_id,
+            uint32_t _pixels_shm_offset,
+            uint32_t _async_upload_token,
+            uint32_t _sync_data_shm_id,
+            uint32_t _sync_data_shm_offset) {
     SetHeader();
     target = _target;
     level = _level;
@@ -10249,11 +10290,11 @@
             GLint _border,
             GLenum _format,
             GLenum _type,
-            uint32 _pixels_shm_id,
-            uint32 _pixels_shm_offset,
-            uint32 _async_upload_token,
-            uint32 _sync_data_shm_id,
-            uint32 _sync_data_shm_offset) {
+            uint32_t _pixels_shm_id,
+            uint32_t _pixels_shm_offset,
+            uint32_t _async_upload_token,
+            uint32_t _sync_data_shm_id,
+            uint32_t _sync_data_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(_target,
                                        _level,
                                        _internalformat,
@@ -10271,19 +10312,19 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 level;
-  int32 internalformat;
-  int32 width;
-  int32 height;
-  int32 border;
-  uint32 format;
-  uint32 type;
-  uint32 pixels_shm_id;
-  uint32 pixels_shm_offset;
-  uint32 async_upload_token;
-  uint32 sync_data_shm_id;
-  uint32 sync_data_shm_offset;
+  uint32_t target;
+  int32_t level;
+  int32_t internalformat;
+  int32_t width;
+  int32_t height;
+  int32_t border;
+  uint32_t format;
+  uint32_t type;
+  uint32_t pixels_shm_id;
+  uint32_t pixels_shm_offset;
+  uint32_t async_upload_token;
+  uint32_t sync_data_shm_id;
+  uint32_t sync_data_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(AsyncTexImage2DCHROMIUM) == 56,
@@ -10323,8 +10364,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -10340,7 +10381,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 target;
+  uint32_t target;
 };
 
 COMPILE_ASSERT(sizeof(WaitAsyncTexImage2DCHROMIUM) == 8,
@@ -10356,8 +10397,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -10383,16 +10424,16 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
   void Init(GLenum _target,
             GLsizei _count,
-            uint32 _attachments_shm_id,
-            uint32 _attachments_shm_offset) {
+            uint32_t _attachments_shm_id,
+            uint32_t _attachments_shm_offset) {
     SetHeader();
     target = _target;
     count = _count;
@@ -10403,18 +10444,18 @@
   void* Set(void* cmd,
             GLenum _target,
             GLsizei _count,
-            uint32 _attachments_shm_id,
-            uint32 _attachments_shm_offset) {
+            uint32_t _attachments_shm_id,
+            uint32_t _attachments_shm_offset) {
     static_cast<ValueType*>(cmd)
         ->Init(_target, _count, _attachments_shm_id, _attachments_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 count;
-  uint32 attachments_shm_id;
-  uint32 attachments_shm_offset;
+  uint32_t target;
+  int32_t count;
+  uint32_t attachments_shm_id;
+  uint32_t attachments_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(DiscardFramebufferEXT) == 20,
@@ -10436,13 +10477,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLenum) * 1 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLenum) * 1 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -10461,13 +10502,13 @@
             GLsizei _count,
             const GLenum* _attachments) {
     static_cast<ValueType*>(cmd)->Init(_target, _count, _attachments);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  uint32 target;
-  int32 count;
+  uint32_t target;
+  int32_t count;
 };
 
 COMPILE_ASSERT(sizeof(DiscardFramebufferEXTImmediate) == 12,
@@ -10485,8 +10526,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -10503,8 +10544,8 @@
   }
 
   gpu::CommandHeader header;
-  uint32 current;
-  uint32 other;
+  uint32_t current;
+  uint32_t other;
 };
 
 COMPILE_ASSERT(sizeof(LoseContextCHROMIUM) == 12,
@@ -10522,8 +10563,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -10539,7 +10580,7 @@
   }
 
   gpu::CommandHeader header;
-  uint32 sync_point;
+  uint32_t sync_point;
 };
 
 COMPILE_ASSERT(sizeof(WaitSyncPointCHROMIUM) == 8,
@@ -10555,13 +10596,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
 
-  void Init(GLsizei _count, uint32 _bufs_shm_id, uint32 _bufs_shm_offset) {
+  void Init(GLsizei _count, uint32_t _bufs_shm_id, uint32_t _bufs_shm_offset) {
     SetHeader();
     count = _count;
     bufs_shm_id = _bufs_shm_id;
@@ -10570,16 +10611,16 @@
 
   void* Set(void* cmd,
             GLsizei _count,
-            uint32 _bufs_shm_id,
-            uint32 _bufs_shm_offset) {
+            uint32_t _bufs_shm_id,
+            uint32_t _bufs_shm_offset) {
     static_cast<ValueType*>(cmd)->Init(_count, _bufs_shm_id, _bufs_shm_offset);
     return NextCmdAddress<ValueType>(cmd);
   }
 
   gpu::CommandHeader header;
-  int32 count;
-  uint32 bufs_shm_id;
-  uint32 bufs_shm_offset;
+  int32_t count;
+  uint32_t bufs_shm_id;
+  uint32_t bufs_shm_offset;
 };
 
 COMPILE_ASSERT(sizeof(DrawBuffersEXT) == 16, Sizeof_DrawBuffersEXT_is_not_16);
@@ -10598,13 +10639,13 @@
   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeDataSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(GLenum) * 1 * count);  // NOLINT
+  static uint32_t ComputeDataSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(GLenum) * 1 * count);  // NOLINT
   }
 
-  static uint32 ComputeSize(GLsizei count) {
-    return static_cast<uint32>(sizeof(ValueType) +
-                               ComputeDataSize(count));  // NOLINT
+  static uint32_t ComputeSize(GLsizei count) {
+    return static_cast<uint32_t>(sizeof(ValueType) +
+                                 ComputeDataSize(count));  // NOLINT
   }
 
   void SetHeader(GLsizei count) {
@@ -10619,12 +10660,12 @@
 
   void* Set(void* cmd, GLsizei _count, const GLenum* _bufs) {
     static_cast<ValueType*>(cmd)->Init(_count, _bufs);
-    const uint32 size = ComputeSize(_count);
+    const uint32_t size = ComputeSize(_count);
     return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
   }
 
   gpu::CommandHeader header;
-  int32 count;
+  int32_t count;
 };
 
 COMPILE_ASSERT(sizeof(DrawBuffersEXTImmediate) == 8,
@@ -10640,8 +10681,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -10667,8 +10708,8 @@
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
 
-  static uint32 ComputeSize() {
-    return static_cast<uint32>(sizeof(ValueType));  // NOLINT
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
   }
 
   void SetHeader() { header.SetCmd<ValueType>(); }
@@ -10725,13 +10766,13 @@
   }
 
   gpu::CommandHeader header;
-  int32 plane_z_order;
-  uint32 plane_transform;
-  uint32 overlay_texture_id;
-  int32 bounds_x;
-  int32 bounds_y;
-  int32 bounds_width;
-  int32 bounds_height;
+  int32_t plane_z_order;
+  uint32_t plane_transform;
+  uint32_t overlay_texture_id;
+  int32_t bounds_x;
+  int32_t bounds_y;
+  int32_t bounds_width;
+  int32_t bounds_height;
   float uv_x;
   float uv_y;
   float uv_width;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 9b6836d..115137d 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -17,7 +17,7 @@
 TEST_F(GLES2FormatTest, ActiveTexture) {
   cmds::ActiveTexture& cmd = *GetBufferAs<cmds::ActiveTexture>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::ActiveTexture::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ActiveTexture::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.texture);
@@ -28,7 +28,7 @@
   cmds::AttachShader& cmd = *GetBufferAs<cmds::AttachShader>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::AttachShader::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::AttachShader::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
@@ -41,17 +41,17 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLuint>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14),
-                           static_cast<uint32>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::BindAttribLocation::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14),
+                           static_cast<uint32_t>(15));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BindAttribLocation::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
   EXPECT_EQ(static_cast<GLuint>(12), cmd.index);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.name_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.name_shm_offset);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.data_size);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.name_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.name_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.data_size);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -61,13 +61,13 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLuint>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::BindAttribLocationBucket::kCmdId),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BindAttribLocationBucket::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
   EXPECT_EQ(static_cast<GLuint>(12), cmd.index);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.name_bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.name_bucket_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -75,7 +75,8 @@
   cmds::BindBuffer& cmd = *GetBufferAs<cmds::BindBuffer>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLuint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::BindBuffer::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BindBuffer::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLuint>(12), cmd.buffer);
@@ -86,7 +87,7 @@
   cmds::BindFramebuffer& cmd = *GetBufferAs<cmds::BindFramebuffer>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLuint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::BindFramebuffer::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BindFramebuffer::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -98,7 +99,7 @@
   cmds::BindRenderbuffer& cmd = *GetBufferAs<cmds::BindRenderbuffer>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLuint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::BindRenderbuffer::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BindRenderbuffer::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -110,7 +111,8 @@
   cmds::BindTexture& cmd = *GetBufferAs<cmds::BindTexture>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLuint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::BindTexture::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BindTexture::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLuint>(12), cmd.texture);
@@ -124,7 +126,8 @@
                            static_cast<GLclampf>(12),
                            static_cast<GLclampf>(13),
                            static_cast<GLclampf>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::BlendColor::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BlendColor::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLclampf>(11), cmd.red);
   EXPECT_EQ(static_cast<GLclampf>(12), cmd.green);
@@ -136,7 +139,7 @@
 TEST_F(GLES2FormatTest, BlendEquation) {
   cmds::BlendEquation& cmd = *GetBufferAs<cmds::BlendEquation>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::BlendEquation::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BlendEquation::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.mode);
@@ -148,7 +151,7 @@
       *GetBufferAs<cmds::BlendEquationSeparate>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLenum>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::BlendEquationSeparate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BlendEquationSeparate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.modeRGB);
@@ -160,7 +163,7 @@
   cmds::BlendFunc& cmd = *GetBufferAs<cmds::BlendFunc>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLenum>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::BlendFunc::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BlendFunc::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.sfactor);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.dfactor);
@@ -174,7 +177,7 @@
                            static_cast<GLenum>(12),
                            static_cast<GLenum>(13),
                            static_cast<GLenum>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::BlendFuncSeparate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BlendFuncSeparate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.srcRGB);
@@ -189,15 +192,16 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
                            static_cast<GLsizeiptr>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14),
                            static_cast<GLenum>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::BufferData::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BufferData::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLsizeiptr>(12), cmd.size);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.data_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.data_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.data_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.data_shm_offset);
   EXPECT_EQ(static_cast<GLenum>(15), cmd.usage);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
@@ -208,16 +212,16 @@
                            static_cast<GLenum>(11),
                            static_cast<GLintptr>(12),
                            static_cast<GLsizeiptr>(13),
-                           static_cast<uint32>(14),
-                           static_cast<uint32>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::BufferSubData::kCmdId),
+                           static_cast<uint32_t>(14),
+                           static_cast<uint32_t>(15));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BufferSubData::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLintptr>(12), cmd.offset);
   EXPECT_EQ(static_cast<GLsizeiptr>(13), cmd.size);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.data_shm_id);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.data_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.data_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.data_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -226,21 +230,21 @@
       *GetBufferAs<cmds::CheckFramebufferStatus>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::CheckFramebufferStatus::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CheckFramebufferStatus::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, Clear) {
   cmds::Clear& cmd = *GetBufferAs<cmds::Clear>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLbitfield>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::Clear::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Clear::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLbitfield>(11), cmd.mask);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -253,7 +257,8 @@
                            static_cast<GLclampf>(12),
                            static_cast<GLclampf>(13),
                            static_cast<GLclampf>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::ClearColor::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ClearColor::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLclampf>(11), cmd.red);
   EXPECT_EQ(static_cast<GLclampf>(12), cmd.green);
@@ -265,7 +270,8 @@
 TEST_F(GLES2FormatTest, ClearDepthf) {
   cmds::ClearDepthf& cmd = *GetBufferAs<cmds::ClearDepthf>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLclampf>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::ClearDepthf::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ClearDepthf::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLclampf>(11), cmd.depth);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -274,7 +280,7 @@
 TEST_F(GLES2FormatTest, ClearStencil) {
   cmds::ClearStencil& cmd = *GetBufferAs<cmds::ClearStencil>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::ClearStencil::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ClearStencil::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.s);
@@ -288,7 +294,7 @@
                            static_cast<GLboolean>(12),
                            static_cast<GLboolean>(13),
                            static_cast<GLboolean>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::ColorMask::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ColorMask::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLboolean>(11), cmd.red);
   EXPECT_EQ(static_cast<GLboolean>(12), cmd.green);
@@ -300,7 +306,7 @@
 TEST_F(GLES2FormatTest, CompileShader) {
   cmds::CompileShader& cmd = *GetBufferAs<cmds::CompileShader>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::CompileShader::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CompileShader::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.shader);
@@ -317,9 +323,9 @@
                            static_cast<GLsizei>(15),
                            static_cast<GLint>(16),
                            static_cast<GLsizei>(17),
-                           static_cast<uint32>(18),
-                           static_cast<uint32>(19));
-  EXPECT_EQ(static_cast<uint32>(cmds::CompressedTexImage2D::kCmdId),
+                           static_cast<uint32_t>(18),
+                           static_cast<uint32_t>(19));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CompressedTexImage2D::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -329,8 +335,8 @@
   EXPECT_EQ(static_cast<GLsizei>(15), cmd.height);
   EXPECT_EQ(static_cast<GLint>(16), cmd.border);
   EXPECT_EQ(static_cast<GLsizei>(17), cmd.imageSize);
-  EXPECT_EQ(static_cast<uint32>(18), cmd.data_shm_id);
-  EXPECT_EQ(static_cast<uint32>(19), cmd.data_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(18), cmd.data_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(19), cmd.data_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -345,7 +351,7 @@
                            static_cast<GLsizei>(15),
                            static_cast<GLint>(16),
                            static_cast<GLuint>(17));
-  EXPECT_EQ(static_cast<uint32>(cmds::CompressedTexImage2DBucket::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CompressedTexImage2DBucket::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -370,9 +376,9 @@
                            static_cast<GLsizei>(16),
                            static_cast<GLenum>(17),
                            static_cast<GLsizei>(18),
-                           static_cast<uint32>(19),
-                           static_cast<uint32>(20));
-  EXPECT_EQ(static_cast<uint32>(cmds::CompressedTexSubImage2D::kCmdId),
+                           static_cast<uint32_t>(19),
+                           static_cast<uint32_t>(20));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CompressedTexSubImage2D::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -383,8 +389,8 @@
   EXPECT_EQ(static_cast<GLsizei>(16), cmd.height);
   EXPECT_EQ(static_cast<GLenum>(17), cmd.format);
   EXPECT_EQ(static_cast<GLsizei>(18), cmd.imageSize);
-  EXPECT_EQ(static_cast<uint32>(19), cmd.data_shm_id);
-  EXPECT_EQ(static_cast<uint32>(20), cmd.data_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(19), cmd.data_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(20), cmd.data_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -400,7 +406,7 @@
                            static_cast<GLsizei>(16),
                            static_cast<GLenum>(17),
                            static_cast<GLuint>(18));
-  EXPECT_EQ(static_cast<uint32>(cmds::CompressedTexSubImage2DBucket::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CompressedTexSubImage2DBucket::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -425,7 +431,7 @@
                            static_cast<GLsizei>(16),
                            static_cast<GLsizei>(17),
                            static_cast<GLint>(18));
-  EXPECT_EQ(static_cast<uint32>(cmds::CopyTexImage2D::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CopyTexImage2D::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -450,7 +456,7 @@
                            static_cast<GLint>(16),
                            static_cast<GLsizei>(17),
                            static_cast<GLsizei>(18));
-  EXPECT_EQ(static_cast<uint32>(cmds::CopyTexSubImage2D::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CopyTexSubImage2D::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -466,30 +472,30 @@
 
 TEST_F(GLES2FormatTest, CreateProgram) {
   cmds::CreateProgram& cmd = *GetBufferAs<cmds::CreateProgram>();
-  void* next_cmd = cmd.Set(&cmd, static_cast<uint32>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::CreateProgram::kCmdId),
+  void* next_cmd = cmd.Set(&cmd, static_cast<uint32_t>(11));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CreateProgram::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
-  EXPECT_EQ(static_cast<uint32>(11), cmd.client_id);
+  EXPECT_EQ(static_cast<uint32_t>(11), cmd.client_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, CreateShader) {
   cmds::CreateShader& cmd = *GetBufferAs<cmds::CreateShader>();
   void* next_cmd =
-      cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<uint32>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::CreateShader::kCmdId),
+      cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<uint32_t>(12));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CreateShader::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.type);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.client_id);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.client_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, CullFace) {
   cmds::CullFace& cmd = *GetBufferAs<cmds::CullFace>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::CullFace::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CullFace::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.mode);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -499,14 +505,14 @@
   cmds::DeleteBuffers& cmd = *GetBufferAs<cmds::DeleteBuffers>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteBuffers::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteBuffers::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.buffers_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.buffers_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.buffers_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.buffers_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -517,7 +523,7 @@
   cmds::DeleteBuffersImmediate& cmd =
       *GetBufferAs<cmds::DeleteBuffersImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteBuffersImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteBuffersImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -532,14 +538,14 @@
   cmds::DeleteFramebuffers& cmd = *GetBufferAs<cmds::DeleteFramebuffers>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteFramebuffers::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteFramebuffers::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.framebuffers_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.framebuffers_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.framebuffers_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.framebuffers_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -550,7 +556,7 @@
   cmds::DeleteFramebuffersImmediate& cmd =
       *GetBufferAs<cmds::DeleteFramebuffersImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteFramebuffersImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteFramebuffersImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -564,7 +570,7 @@
 TEST_F(GLES2FormatTest, DeleteProgram) {
   cmds::DeleteProgram& cmd = *GetBufferAs<cmds::DeleteProgram>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteProgram::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteProgram::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
@@ -575,14 +581,14 @@
   cmds::DeleteRenderbuffers& cmd = *GetBufferAs<cmds::DeleteRenderbuffers>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteRenderbuffers::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteRenderbuffers::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.renderbuffers_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.renderbuffers_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.renderbuffers_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.renderbuffers_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -593,7 +599,7 @@
   cmds::DeleteRenderbuffersImmediate& cmd =
       *GetBufferAs<cmds::DeleteRenderbuffersImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteRenderbuffersImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteRenderbuffersImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -607,7 +613,7 @@
 TEST_F(GLES2FormatTest, DeleteShader) {
   cmds::DeleteShader& cmd = *GetBufferAs<cmds::DeleteShader>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteShader::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteShader::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.shader);
@@ -618,14 +624,14 @@
   cmds::DeleteTextures& cmd = *GetBufferAs<cmds::DeleteTextures>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteTextures::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteTextures::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.textures_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.textures_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.textures_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.textures_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -636,7 +642,7 @@
   cmds::DeleteTexturesImmediate& cmd =
       *GetBufferAs<cmds::DeleteTexturesImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteTexturesImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteTexturesImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -650,7 +656,7 @@
 TEST_F(GLES2FormatTest, DepthFunc) {
   cmds::DepthFunc& cmd = *GetBufferAs<cmds::DepthFunc>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::DepthFunc::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DepthFunc::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.func);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -659,7 +665,7 @@
 TEST_F(GLES2FormatTest, DepthMask) {
   cmds::DepthMask& cmd = *GetBufferAs<cmds::DepthMask>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLboolean>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::DepthMask::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DepthMask::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLboolean>(11), cmd.flag);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -669,7 +675,8 @@
   cmds::DepthRangef& cmd = *GetBufferAs<cmds::DepthRangef>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLclampf>(11), static_cast<GLclampf>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::DepthRangef::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DepthRangef::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLclampf>(11), cmd.zNear);
   EXPECT_EQ(static_cast<GLclampf>(12), cmd.zFar);
@@ -680,7 +687,7 @@
   cmds::DetachShader& cmd = *GetBufferAs<cmds::DetachShader>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::DetachShader::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DetachShader::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
@@ -691,7 +698,7 @@
 TEST_F(GLES2FormatTest, Disable) {
   cmds::Disable& cmd = *GetBufferAs<cmds::Disable>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::Disable::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Disable::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.cap);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -701,7 +708,7 @@
   cmds::DisableVertexAttribArray& cmd =
       *GetBufferAs<cmds::DisableVertexAttribArray>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::DisableVertexAttribArray::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DisableVertexAttribArray::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.index);
@@ -714,7 +721,8 @@
                            static_cast<GLenum>(11),
                            static_cast<GLint>(12),
                            static_cast<GLsizei>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::DrawArrays::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DrawArrays::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.mode);
   EXPECT_EQ(static_cast<GLint>(12), cmd.first);
@@ -729,7 +737,7 @@
                            static_cast<GLsizei>(12),
                            static_cast<GLenum>(13),
                            static_cast<GLuint>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::DrawElements::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DrawElements::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.mode);
@@ -742,7 +750,7 @@
 TEST_F(GLES2FormatTest, Enable) {
   cmds::Enable& cmd = *GetBufferAs<cmds::Enable>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::Enable::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Enable::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.cap);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -752,7 +760,7 @@
   cmds::EnableVertexAttribArray& cmd =
       *GetBufferAs<cmds::EnableVertexAttribArray>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::EnableVertexAttribArray::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::EnableVertexAttribArray::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.index);
@@ -762,7 +770,7 @@
 TEST_F(GLES2FormatTest, Finish) {
   cmds::Finish& cmd = *GetBufferAs<cmds::Finish>();
   void* next_cmd = cmd.Set(&cmd);
-  EXPECT_EQ(static_cast<uint32>(cmds::Finish::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Finish::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
@@ -770,7 +778,7 @@
 TEST_F(GLES2FormatTest, Flush) {
   cmds::Flush& cmd = *GetBufferAs<cmds::Flush>();
   void* next_cmd = cmd.Set(&cmd);
-  EXPECT_EQ(static_cast<uint32>(cmds::Flush::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Flush::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
@@ -783,7 +791,7 @@
                            static_cast<GLenum>(12),
                            static_cast<GLenum>(13),
                            static_cast<GLuint>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::FramebufferRenderbuffer::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::FramebufferRenderbuffer::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -801,7 +809,7 @@
                            static_cast<GLenum>(13),
                            static_cast<GLuint>(14),
                            static_cast<GLint>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::FramebufferTexture2D::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::FramebufferTexture2D::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -815,7 +823,7 @@
 TEST_F(GLES2FormatTest, FrontFace) {
   cmds::FrontFace& cmd = *GetBufferAs<cmds::FrontFace>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::FrontFace::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::FrontFace::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.mode);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -825,13 +833,14 @@
   cmds::GenBuffers& cmd = *GetBufferAs<cmds::GenBuffers>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::GenBuffers::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenBuffers::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.buffers_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.buffers_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.buffers_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.buffers_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -841,7 +850,7 @@
   };
   cmds::GenBuffersImmediate& cmd = *GetBufferAs<cmds::GenBuffersImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::GenBuffersImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenBuffersImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -855,7 +864,7 @@
 TEST_F(GLES2FormatTest, GenerateMipmap) {
   cmds::GenerateMipmap& cmd = *GetBufferAs<cmds::GenerateMipmap>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::GenerateMipmap::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenerateMipmap::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -866,14 +875,14 @@
   cmds::GenFramebuffers& cmd = *GetBufferAs<cmds::GenFramebuffers>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::GenFramebuffers::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenFramebuffers::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.framebuffers_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.framebuffers_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.framebuffers_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.framebuffers_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -884,7 +893,7 @@
   cmds::GenFramebuffersImmediate& cmd =
       *GetBufferAs<cmds::GenFramebuffersImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::GenFramebuffersImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenFramebuffersImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -899,14 +908,14 @@
   cmds::GenRenderbuffers& cmd = *GetBufferAs<cmds::GenRenderbuffers>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::GenRenderbuffers::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenRenderbuffers::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.renderbuffers_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.renderbuffers_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.renderbuffers_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.renderbuffers_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -917,7 +926,7 @@
   cmds::GenRenderbuffersImmediate& cmd =
       *GetBufferAs<cmds::GenRenderbuffersImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::GenRenderbuffersImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenRenderbuffersImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -932,13 +941,14 @@
   cmds::GenTextures& cmd = *GetBufferAs<cmds::GenTextures>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::GenTextures::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenTextures::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.textures_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.textures_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.textures_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.textures_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -948,7 +958,7 @@
   };
   cmds::GenTexturesImmediate& cmd = *GetBufferAs<cmds::GenTexturesImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::GenTexturesImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenTexturesImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -964,17 +974,17 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLuint>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14),
-                           static_cast<uint32>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetActiveAttrib::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14),
+                           static_cast<uint32_t>(15));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetActiveAttrib::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
   EXPECT_EQ(static_cast<GLuint>(12), cmd.index);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.name_bucket_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.name_bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -983,17 +993,17 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLuint>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14),
-                           static_cast<uint32>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetActiveUniform::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14),
+                           static_cast<uint32_t>(15));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetActiveUniform::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
   EXPECT_EQ(static_cast<GLuint>(12), cmd.index);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.name_bucket_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.name_bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1001,16 +1011,16 @@
   cmds::GetAttachedShaders& cmd = *GetBufferAs<cmds::GetAttachedShaders>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetAttachedShaders::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetAttachedShaders::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.result_size);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.result_size);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1020,13 +1030,14 @@
   cmds::GetBooleanv& cmd = *GetBufferAs<cmds::GetBooleanv>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetBooleanv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetBooleanv::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1035,26 +1046,26 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetBufferParameteriv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetBufferParameteriv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, GetError) {
   cmds::GetError& cmd = *GetBufferAs<cmds::GetError>();
   void* next_cmd =
-      cmd.Set(&cmd, static_cast<uint32>(11), static_cast<uint32>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetError::kCmdId), cmd.header.command);
+      cmd.Set(&cmd, static_cast<uint32_t>(11), static_cast<uint32_t>(12));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetError::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
-  EXPECT_EQ(static_cast<uint32>(11), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(11), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1062,13 +1073,13 @@
   cmds::GetFloatv& cmd = *GetBufferAs<cmds::GetFloatv>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetFloatv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetFloatv::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1079,17 +1090,17 @@
                            static_cast<GLenum>(11),
                            static_cast<GLenum>(12),
                            static_cast<GLenum>(13),
-                           static_cast<uint32>(14),
-                           static_cast<uint32>(15));
+                           static_cast<uint32_t>(14),
+                           static_cast<uint32_t>(15));
   EXPECT_EQ(
-      static_cast<uint32>(cmds::GetFramebufferAttachmentParameteriv::kCmdId),
+      static_cast<uint32_t>(cmds::GetFramebufferAttachmentParameteriv::kCmdId),
       cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.attachment);
   EXPECT_EQ(static_cast<GLenum>(13), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1097,13 +1108,14 @@
   cmds::GetIntegerv& cmd = *GetBufferAs<cmds::GetIntegerv>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetIntegerv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetIntegerv::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1112,27 +1124,27 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetProgramiv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetProgramiv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, GetProgramInfoLog) {
   cmds::GetProgramInfoLog& cmd = *GetBufferAs<cmds::GetProgramInfoLog>();
   void* next_cmd =
-      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetProgramInfoLog::kCmdId),
+      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetProgramInfoLog::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.bucket_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1142,15 +1154,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetRenderbufferParameteriv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetRenderbufferParameteriv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1159,26 +1171,27 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetShaderiv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetShaderiv::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.shader);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, GetShaderInfoLog) {
   cmds::GetShaderInfoLog& cmd = *GetBufferAs<cmds::GetShaderInfoLog>();
   void* next_cmd =
-      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetShaderInfoLog::kCmdId),
+      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetShaderInfoLog::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.shader);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.bucket_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1188,38 +1201,38 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetShaderPrecisionFormat::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetShaderPrecisionFormat::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.shadertype);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.precisiontype);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, GetShaderSource) {
   cmds::GetShaderSource& cmd = *GetBufferAs<cmds::GetShaderSource>();
   void* next_cmd =
-      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetShaderSource::kCmdId),
+      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetShaderSource::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.shader);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.bucket_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, GetString) {
   cmds::GetString& cmd = *GetBufferAs<cmds::GetString>();
   void* next_cmd =
-      cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<uint32>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetString::kCmdId), cmd.header.command);
+      cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<uint32_t>(12));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetString::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.name);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.bucket_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1228,15 +1241,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetTexParameterfv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetTexParameterfv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1245,15 +1258,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetTexParameteriv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetTexParameteriv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1262,15 +1275,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLint>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetUniformfv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetUniformfv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
   EXPECT_EQ(static_cast<GLint>(12), cmd.location);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1279,15 +1292,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLint>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetUniformiv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetUniformiv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
   EXPECT_EQ(static_cast<GLint>(12), cmd.location);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1298,15 +1311,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetVertexAttribfv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetVertexAttribfv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.index);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1315,15 +1328,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetVertexAttribiv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetVertexAttribiv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.index);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1333,15 +1346,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetVertexAttribPointerv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetVertexAttribPointerv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.index);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.pointer_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.pointer_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.pointer_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.pointer_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1349,7 +1362,7 @@
   cmds::Hint& cmd = *GetBufferAs<cmds::Hint>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLenum>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::Hint::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Hint::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.mode);
@@ -1360,13 +1373,13 @@
   cmds::IsBuffer& cmd = *GetBufferAs<cmds::IsBuffer>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::IsBuffer::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::IsBuffer::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.buffer);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1374,13 +1387,13 @@
   cmds::IsEnabled& cmd = *GetBufferAs<cmds::IsEnabled>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::IsEnabled::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::IsEnabled::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.cap);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1388,14 +1401,14 @@
   cmds::IsFramebuffer& cmd = *GetBufferAs<cmds::IsFramebuffer>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::IsFramebuffer::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::IsFramebuffer::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.framebuffer);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1403,13 +1416,13 @@
   cmds::IsProgram& cmd = *GetBufferAs<cmds::IsProgram>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::IsProgram::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::IsProgram::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1417,14 +1430,14 @@
   cmds::IsRenderbuffer& cmd = *GetBufferAs<cmds::IsRenderbuffer>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::IsRenderbuffer::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::IsRenderbuffer::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.renderbuffer);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1432,13 +1445,13 @@
   cmds::IsShader& cmd = *GetBufferAs<cmds::IsShader>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::IsShader::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::IsShader::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.shader);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1446,20 +1459,20 @@
   cmds::IsTexture& cmd = *GetBufferAs<cmds::IsTexture>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::IsTexture::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::IsTexture::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.texture);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, LineWidth) {
   cmds::LineWidth& cmd = *GetBufferAs<cmds::LineWidth>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLfloat>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::LineWidth::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::LineWidth::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLfloat>(11), cmd.width);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -1468,7 +1481,8 @@
 TEST_F(GLES2FormatTest, LinkProgram) {
   cmds::LinkProgram& cmd = *GetBufferAs<cmds::LinkProgram>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::LinkProgram::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::LinkProgram::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -1478,7 +1492,8 @@
   cmds::PixelStorei& cmd = *GetBufferAs<cmds::PixelStorei>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::PixelStorei::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::PixelStorei::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.pname);
   EXPECT_EQ(static_cast<GLint>(12), cmd.param);
@@ -1489,7 +1504,7 @@
   cmds::PolygonOffset& cmd = *GetBufferAs<cmds::PolygonOffset>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLfloat>(11), static_cast<GLfloat>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::PolygonOffset::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::PolygonOffset::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLfloat>(11), cmd.factor);
@@ -1506,12 +1521,13 @@
                            static_cast<GLsizei>(14),
                            static_cast<GLenum>(15),
                            static_cast<GLenum>(16),
-                           static_cast<uint32>(17),
-                           static_cast<uint32>(18),
-                           static_cast<uint32>(19),
-                           static_cast<uint32>(20),
+                           static_cast<uint32_t>(17),
+                           static_cast<uint32_t>(18),
+                           static_cast<uint32_t>(19),
+                           static_cast<uint32_t>(20),
                            static_cast<GLboolean>(21));
-  EXPECT_EQ(static_cast<uint32>(cmds::ReadPixels::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ReadPixels::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.x);
   EXPECT_EQ(static_cast<GLint>(12), cmd.y);
@@ -1519,10 +1535,10 @@
   EXPECT_EQ(static_cast<GLsizei>(14), cmd.height);
   EXPECT_EQ(static_cast<GLenum>(15), cmd.format);
   EXPECT_EQ(static_cast<GLenum>(16), cmd.type);
-  EXPECT_EQ(static_cast<uint32>(17), cmd.pixels_shm_id);
-  EXPECT_EQ(static_cast<uint32>(18), cmd.pixels_shm_offset);
-  EXPECT_EQ(static_cast<uint32>(19), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(20), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(17), cmd.pixels_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(18), cmd.pixels_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(19), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(20), cmd.result_shm_offset);
   EXPECT_EQ(static_cast<GLboolean>(21), cmd.async);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
@@ -1531,7 +1547,7 @@
   cmds::ReleaseShaderCompiler& cmd =
       *GetBufferAs<cmds::ReleaseShaderCompiler>();
   void* next_cmd = cmd.Set(&cmd);
-  EXPECT_EQ(static_cast<uint32>(cmds::ReleaseShaderCompiler::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ReleaseShaderCompiler::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -1544,7 +1560,7 @@
                            static_cast<GLenum>(12),
                            static_cast<GLsizei>(13),
                            static_cast<GLsizei>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::RenderbufferStorage::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::RenderbufferStorage::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -1558,7 +1574,7 @@
   cmds::SampleCoverage& cmd = *GetBufferAs<cmds::SampleCoverage>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLclampf>(11), static_cast<GLboolean>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::SampleCoverage::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::SampleCoverage::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLclampf>(11), cmd.value);
@@ -1573,7 +1589,7 @@
                            static_cast<GLint>(12),
                            static_cast<GLsizei>(13),
                            static_cast<GLsizei>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Scissor::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Scissor::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.x);
   EXPECT_EQ(static_cast<GLint>(12), cmd.y);
@@ -1586,21 +1602,21 @@
   cmds::ShaderBinary& cmd = *GetBufferAs<cmds::ShaderBinary>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13),
                            static_cast<GLenum>(14),
-                           static_cast<uint32>(15),
-                           static_cast<uint32>(16),
+                           static_cast<uint32_t>(15),
+                           static_cast<uint32_t>(16),
                            static_cast<GLsizei>(17));
-  EXPECT_EQ(static_cast<uint32>(cmds::ShaderBinary::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ShaderBinary::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.shaders_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.shaders_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.shaders_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.shaders_shm_offset);
   EXPECT_EQ(static_cast<GLenum>(14), cmd.binaryformat);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.binary_shm_id);
-  EXPECT_EQ(static_cast<uint32>(16), cmd.binary_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.binary_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(16), cmd.binary_shm_offset);
   EXPECT_EQ(static_cast<GLsizei>(17), cmd.length);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
@@ -1609,28 +1625,28 @@
   cmds::ShaderSource& cmd = *GetBufferAs<cmds::ShaderSource>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::ShaderSource::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ShaderSource::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.shader);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.data_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.data_shm_offset);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.data_size);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.data_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.data_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.data_size);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, ShaderSourceBucket) {
   cmds::ShaderSourceBucket& cmd = *GetBufferAs<cmds::ShaderSourceBucket>();
   void* next_cmd =
-      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::ShaderSourceBucket::kCmdId),
+      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ShaderSourceBucket::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.shader);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.data_bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.data_bucket_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1640,7 +1656,8 @@
                            static_cast<GLenum>(11),
                            static_cast<GLint>(12),
                            static_cast<GLuint>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::StencilFunc::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::StencilFunc::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.func);
   EXPECT_EQ(static_cast<GLint>(12), cmd.ref);
@@ -1655,7 +1672,7 @@
                            static_cast<GLenum>(12),
                            static_cast<GLint>(13),
                            static_cast<GLuint>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::StencilFuncSeparate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::StencilFuncSeparate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.face);
@@ -1668,7 +1685,8 @@
 TEST_F(GLES2FormatTest, StencilMask) {
   cmds::StencilMask& cmd = *GetBufferAs<cmds::StencilMask>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::StencilMask::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::StencilMask::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.mask);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -1678,7 +1696,7 @@
   cmds::StencilMaskSeparate& cmd = *GetBufferAs<cmds::StencilMaskSeparate>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLuint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::StencilMaskSeparate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::StencilMaskSeparate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.face);
@@ -1692,7 +1710,7 @@
                            static_cast<GLenum>(11),
                            static_cast<GLenum>(12),
                            static_cast<GLenum>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::StencilOp::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::StencilOp::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.fail);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.zfail);
@@ -1707,7 +1725,7 @@
                            static_cast<GLenum>(12),
                            static_cast<GLenum>(13),
                            static_cast<GLenum>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::StencilOpSeparate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::StencilOpSeparate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.face);
@@ -1728,9 +1746,10 @@
                            static_cast<GLint>(16),
                            static_cast<GLenum>(17),
                            static_cast<GLenum>(18),
-                           static_cast<uint32>(19),
-                           static_cast<uint32>(20));
-  EXPECT_EQ(static_cast<uint32>(cmds::TexImage2D::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(19),
+                           static_cast<uint32_t>(20));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TexImage2D::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLint>(12), cmd.level);
@@ -1740,8 +1759,8 @@
   EXPECT_EQ(static_cast<GLint>(16), cmd.border);
   EXPECT_EQ(static_cast<GLenum>(17), cmd.format);
   EXPECT_EQ(static_cast<GLenum>(18), cmd.type);
-  EXPECT_EQ(static_cast<uint32>(19), cmd.pixels_shm_id);
-  EXPECT_EQ(static_cast<uint32>(20), cmd.pixels_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(19), cmd.pixels_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(20), cmd.pixels_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1751,7 +1770,7 @@
                            static_cast<GLenum>(11),
                            static_cast<GLenum>(12),
                            static_cast<GLfloat>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::TexParameterf::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TexParameterf::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -1765,15 +1784,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::TexParameterfv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TexParameterfv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1786,7 +1805,7 @@
       *GetBufferAs<cmds::TexParameterfvImmediate>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLenum>(12), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::TexParameterfvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TexParameterfvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
             cmd.header.size * 4u);
@@ -1803,7 +1822,7 @@
                            static_cast<GLenum>(11),
                            static_cast<GLenum>(12),
                            static_cast<GLint>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::TexParameteri::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TexParameteri::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -1817,15 +1836,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
                            static_cast<GLenum>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::TexParameteriv::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TexParameteriv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLenum>(12), cmd.pname);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.params_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.params_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1838,7 +1857,7 @@
       *GetBufferAs<cmds::TexParameterivImmediate>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLenum>(12), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::TexParameterivImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TexParameterivImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
             cmd.header.size * 4u);
@@ -1860,10 +1879,10 @@
                            static_cast<GLsizei>(16),
                            static_cast<GLenum>(17),
                            static_cast<GLenum>(18),
-                           static_cast<uint32>(19),
-                           static_cast<uint32>(20),
+                           static_cast<uint32_t>(19),
+                           static_cast<uint32_t>(20),
                            static_cast<GLboolean>(21));
-  EXPECT_EQ(static_cast<uint32>(cmds::TexSubImage2D::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TexSubImage2D::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -1874,8 +1893,8 @@
   EXPECT_EQ(static_cast<GLsizei>(16), cmd.height);
   EXPECT_EQ(static_cast<GLenum>(17), cmd.format);
   EXPECT_EQ(static_cast<GLenum>(18), cmd.type);
-  EXPECT_EQ(static_cast<uint32>(19), cmd.pixels_shm_id);
-  EXPECT_EQ(static_cast<uint32>(20), cmd.pixels_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(19), cmd.pixels_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(20), cmd.pixels_shm_offset);
   EXPECT_EQ(static_cast<GLboolean>(21), cmd.internal);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
@@ -1884,7 +1903,7 @@
   cmds::Uniform1f& cmd = *GetBufferAs<cmds::Uniform1f>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLint>(11), static_cast<GLfloat>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform1f::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform1f::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLfloat>(12), cmd.x);
@@ -1896,14 +1915,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLint>(11),
                            static_cast<GLsizei>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform1fv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform1fv::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.v_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.v_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1919,7 +1939,7 @@
       sizeof(cmd) + kNumElements * sizeof(GLfloat) * 1;
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform1fvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform1fvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(1), cmd.location);
@@ -1933,7 +1953,7 @@
   cmds::Uniform1i& cmd = *GetBufferAs<cmds::Uniform1i>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLint>(11), static_cast<GLint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform1i::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform1i::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLint>(12), cmd.x);
@@ -1945,14 +1965,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLint>(11),
                            static_cast<GLsizei>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform1iv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform1iv::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.v_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.v_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -1968,7 +1989,7 @@
       sizeof(cmd) + kNumElements * sizeof(GLint) * 1;
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform1ivImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform1ivImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(1), cmd.location);
@@ -1984,7 +2005,7 @@
                            static_cast<GLint>(11),
                            static_cast<GLfloat>(12),
                            static_cast<GLfloat>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform2f::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform2f::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLfloat>(12), cmd.x);
@@ -1997,14 +2018,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLint>(11),
                            static_cast<GLsizei>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform2fv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform2fv::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.v_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.v_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2022,7 +2044,7 @@
       sizeof(cmd) + kNumElements * sizeof(GLfloat) * 2;
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform2fvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform2fvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(1), cmd.location);
@@ -2038,7 +2060,7 @@
                            static_cast<GLint>(11),
                            static_cast<GLint>(12),
                            static_cast<GLint>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform2i::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform2i::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLint>(12), cmd.x);
@@ -2051,14 +2073,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLint>(11),
                            static_cast<GLsizei>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform2iv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform2iv::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.v_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.v_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2076,7 +2099,7 @@
       sizeof(cmd) + kNumElements * sizeof(GLint) * 2;
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform2ivImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform2ivImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(1), cmd.location);
@@ -2093,7 +2116,7 @@
                            static_cast<GLfloat>(12),
                            static_cast<GLfloat>(13),
                            static_cast<GLfloat>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform3f::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform3f::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLfloat>(12), cmd.x);
@@ -2107,14 +2130,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLint>(11),
                            static_cast<GLsizei>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform3fv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform3fv::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.v_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.v_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2134,7 +2158,7 @@
       sizeof(cmd) + kNumElements * sizeof(GLfloat) * 3;
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform3fvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform3fvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(1), cmd.location);
@@ -2151,7 +2175,7 @@
                            static_cast<GLint>(12),
                            static_cast<GLint>(13),
                            static_cast<GLint>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform3i::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform3i::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLint>(12), cmd.x);
@@ -2165,14 +2189,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLint>(11),
                            static_cast<GLsizei>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform3iv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform3iv::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.v_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.v_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2192,7 +2217,7 @@
       sizeof(cmd) + kNumElements * sizeof(GLint) * 3;
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform3ivImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform3ivImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(1), cmd.location);
@@ -2210,7 +2235,7 @@
                            static_cast<GLfloat>(13),
                            static_cast<GLfloat>(14),
                            static_cast<GLfloat>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform4f::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform4f::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLfloat>(12), cmd.x);
@@ -2225,14 +2250,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLint>(11),
                            static_cast<GLsizei>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform4fv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform4fv::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.v_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.v_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2254,7 +2280,7 @@
       sizeof(cmd) + kNumElements * sizeof(GLfloat) * 4;
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform4fvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform4fvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(1), cmd.location);
@@ -2272,7 +2298,7 @@
                            static_cast<GLint>(13),
                            static_cast<GLint>(14),
                            static_cast<GLint>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform4i::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform4i::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLint>(12), cmd.x);
@@ -2287,14 +2313,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLint>(11),
                            static_cast<GLsizei>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform4iv::kCmdId), cmd.header.command);
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform4iv::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.v_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.v_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2316,7 +2343,7 @@
       sizeof(cmd) + kNumElements * sizeof(GLint) * 4;
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLint>(1), static_cast<GLsizei>(2), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::Uniform4ivImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Uniform4ivImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(1), cmd.location);
@@ -2332,16 +2359,16 @@
                            static_cast<GLint>(11),
                            static_cast<GLsizei>(12),
                            static_cast<GLboolean>(13),
-                           static_cast<uint32>(14),
-                           static_cast<uint32>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::UniformMatrix2fv::kCmdId),
+                           static_cast<uint32_t>(14),
+                           static_cast<uint32_t>(15));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix2fv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
   EXPECT_EQ(static_cast<GLboolean>(13), cmd.transpose);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.value_shm_id);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.value_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.value_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.value_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2367,7 +2394,7 @@
                            static_cast<GLsizei>(2),
                            static_cast<GLboolean>(3),
                            data);
-  EXPECT_EQ(static_cast<uint32>(cmds::UniformMatrix2fvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix2fvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(1), cmd.location);
@@ -2384,16 +2411,16 @@
                            static_cast<GLint>(11),
                            static_cast<GLsizei>(12),
                            static_cast<GLboolean>(13),
-                           static_cast<uint32>(14),
-                           static_cast<uint32>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::UniformMatrix3fv::kCmdId),
+                           static_cast<uint32_t>(14),
+                           static_cast<uint32_t>(15));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix3fv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
   EXPECT_EQ(static_cast<GLboolean>(13), cmd.transpose);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.value_shm_id);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.value_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.value_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.value_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2429,7 +2456,7 @@
                            static_cast<GLsizei>(2),
                            static_cast<GLboolean>(3),
                            data);
-  EXPECT_EQ(static_cast<uint32>(cmds::UniformMatrix3fvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix3fvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(1), cmd.location);
@@ -2446,16 +2473,16 @@
                            static_cast<GLint>(11),
                            static_cast<GLsizei>(12),
                            static_cast<GLboolean>(13),
-                           static_cast<uint32>(14),
-                           static_cast<uint32>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::UniformMatrix4fv::kCmdId),
+                           static_cast<uint32_t>(14),
+                           static_cast<uint32_t>(15));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix4fv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.location);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
   EXPECT_EQ(static_cast<GLboolean>(13), cmd.transpose);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.value_shm_id);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.value_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.value_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.value_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2505,7 +2532,7 @@
                            static_cast<GLsizei>(2),
                            static_cast<GLboolean>(3),
                            data);
-  EXPECT_EQ(static_cast<uint32>(cmds::UniformMatrix4fvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::UniformMatrix4fvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(1), cmd.location);
@@ -2519,7 +2546,8 @@
 TEST_F(GLES2FormatTest, UseProgram) {
   cmds::UseProgram& cmd = *GetBufferAs<cmds::UseProgram>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::UseProgram::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::UseProgram::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -2528,7 +2556,7 @@
 TEST_F(GLES2FormatTest, ValidateProgram) {
   cmds::ValidateProgram& cmd = *GetBufferAs<cmds::ValidateProgram>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::ValidateProgram::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ValidateProgram::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
@@ -2539,7 +2567,7 @@
   cmds::VertexAttrib1f& cmd = *GetBufferAs<cmds::VertexAttrib1f>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLfloat>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib1f::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib1f::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.indx);
@@ -2551,14 +2579,14 @@
   cmds::VertexAttrib1fv& cmd = *GetBufferAs<cmds::VertexAttrib1fv>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib1fv::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib1fv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.indx);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.values_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.values_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.values_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.values_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2570,7 +2598,7 @@
   cmds::VertexAttrib1fvImmediate& cmd =
       *GetBufferAs<cmds::VertexAttrib1fvImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib1fvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib1fvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
             cmd.header.size * 4u);
@@ -2586,7 +2614,7 @@
                            static_cast<GLuint>(11),
                            static_cast<GLfloat>(12),
                            static_cast<GLfloat>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib2f::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib2f::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.indx);
@@ -2599,14 +2627,14 @@
   cmds::VertexAttrib2fv& cmd = *GetBufferAs<cmds::VertexAttrib2fv>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib2fv::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib2fv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.indx);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.values_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.values_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.values_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.values_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2619,7 +2647,7 @@
   cmds::VertexAttrib2fvImmediate& cmd =
       *GetBufferAs<cmds::VertexAttrib2fvImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib2fvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib2fvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
             cmd.header.size * 4u);
@@ -2636,7 +2664,7 @@
                            static_cast<GLfloat>(12),
                            static_cast<GLfloat>(13),
                            static_cast<GLfloat>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib3f::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib3f::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.indx);
@@ -2650,14 +2678,14 @@
   cmds::VertexAttrib3fv& cmd = *GetBufferAs<cmds::VertexAttrib3fv>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib3fv::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib3fv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.indx);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.values_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.values_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.values_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.values_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2671,7 +2699,7 @@
   cmds::VertexAttrib3fvImmediate& cmd =
       *GetBufferAs<cmds::VertexAttrib3fvImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib3fvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib3fvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
             cmd.header.size * 4u);
@@ -2689,7 +2717,7 @@
                            static_cast<GLfloat>(13),
                            static_cast<GLfloat>(14),
                            static_cast<GLfloat>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib4f::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib4f::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.indx);
@@ -2704,14 +2732,14 @@
   cmds::VertexAttrib4fv& cmd = *GetBufferAs<cmds::VertexAttrib4fv>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib4fv::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib4fv::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.indx);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.values_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.values_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.values_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.values_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2726,7 +2754,7 @@
   cmds::VertexAttrib4fvImmediate& cmd =
       *GetBufferAs<cmds::VertexAttrib4fvImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttrib4fvImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttrib4fvImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
             cmd.header.size * 4u);
@@ -2745,7 +2773,7 @@
                            static_cast<GLboolean>(14),
                            static_cast<GLsizei>(15),
                            static_cast<GLuint>(16));
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttribPointer::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttribPointer::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.indx);
@@ -2764,7 +2792,7 @@
                            static_cast<GLint>(12),
                            static_cast<GLsizei>(13),
                            static_cast<GLsizei>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::Viewport::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::Viewport::kCmdId), cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.x);
   EXPECT_EQ(static_cast<GLint>(12), cmd.y);
@@ -2787,7 +2815,7 @@
                            static_cast<GLint>(18),
                            static_cast<GLbitfield>(19),
                            static_cast<GLenum>(20));
-  EXPECT_EQ(static_cast<uint32>(cmds::BlitFramebufferCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BlitFramebufferCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.srcX0);
@@ -2812,9 +2840,9 @@
                            static_cast<GLenum>(13),
                            static_cast<GLsizei>(14),
                            static_cast<GLsizei>(15));
-  EXPECT_EQ(
-      static_cast<uint32>(cmds::RenderbufferStorageMultisampleCHROMIUM::kCmdId),
-      cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(
+                cmds::RenderbufferStorageMultisampleCHROMIUM::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.samples);
@@ -2834,7 +2862,7 @@
                            static_cast<GLsizei>(14),
                            static_cast<GLsizei>(15));
   EXPECT_EQ(
-      static_cast<uint32>(cmds::RenderbufferStorageMultisampleEXT::kCmdId),
+      static_cast<uint32_t>(cmds::RenderbufferStorageMultisampleEXT::kCmdId),
       cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -2856,7 +2884,7 @@
                            static_cast<GLint>(15),
                            static_cast<GLsizei>(16));
   EXPECT_EQ(
-      static_cast<uint32>(cmds::FramebufferTexture2DMultisampleEXT::kCmdId),
+      static_cast<uint32_t>(cmds::FramebufferTexture2DMultisampleEXT::kCmdId),
       cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -2876,7 +2904,7 @@
                            static_cast<GLenum>(13),
                            static_cast<GLsizei>(14),
                            static_cast<GLsizei>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::TexStorage2DEXT::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TexStorage2DEXT::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -2891,14 +2919,14 @@
   cmds::GenQueriesEXT& cmd = *GetBufferAs<cmds::GenQueriesEXT>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::GenQueriesEXT::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenQueriesEXT::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.queries_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.queries_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.queries_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.queries_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2909,7 +2937,7 @@
   cmds::GenQueriesEXTImmediate& cmd =
       *GetBufferAs<cmds::GenQueriesEXTImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::GenQueriesEXTImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenQueriesEXTImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -2924,14 +2952,14 @@
   cmds::DeleteQueriesEXT& cmd = *GetBufferAs<cmds::DeleteQueriesEXT>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteQueriesEXT::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteQueriesEXT::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.queries_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.queries_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.queries_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.queries_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2942,7 +2970,7 @@
   cmds::DeleteQueriesEXTImmediate& cmd =
       *GetBufferAs<cmds::DeleteQueriesEXTImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteQueriesEXTImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteQueriesEXTImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -2958,15 +2986,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
                            static_cast<GLuint>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::BeginQueryEXT::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BeginQueryEXT::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLuint>(12), cmd.id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.sync_data_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.sync_data_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.sync_data_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.sync_data_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -2974,7 +3002,8 @@
   cmds::EndQueryEXT& cmd = *GetBufferAs<cmds::EndQueryEXT>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLuint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::EndQueryEXT::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::EndQueryEXT::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLuint>(12), cmd.submit_count);
@@ -2984,7 +3013,7 @@
 TEST_F(GLES2FormatTest, InsertEventMarkerEXT) {
   cmds::InsertEventMarkerEXT& cmd = *GetBufferAs<cmds::InsertEventMarkerEXT>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::InsertEventMarkerEXT::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::InsertEventMarkerEXT::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.bucket_id);
@@ -2994,7 +3023,7 @@
 TEST_F(GLES2FormatTest, PushGroupMarkerEXT) {
   cmds::PushGroupMarkerEXT& cmd = *GetBufferAs<cmds::PushGroupMarkerEXT>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::PushGroupMarkerEXT::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::PushGroupMarkerEXT::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.bucket_id);
@@ -3004,7 +3033,7 @@
 TEST_F(GLES2FormatTest, PopGroupMarkerEXT) {
   cmds::PopGroupMarkerEXT& cmd = *GetBufferAs<cmds::PopGroupMarkerEXT>();
   void* next_cmd = cmd.Set(&cmd);
-  EXPECT_EQ(static_cast<uint32>(cmds::PopGroupMarkerEXT::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::PopGroupMarkerEXT::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -3014,14 +3043,14 @@
   cmds::GenVertexArraysOES& cmd = *GetBufferAs<cmds::GenVertexArraysOES>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::GenVertexArraysOES::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenVertexArraysOES::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.arrays_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.arrays_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.arrays_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.arrays_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3032,7 +3061,7 @@
   cmds::GenVertexArraysOESImmediate& cmd =
       *GetBufferAs<cmds::GenVertexArraysOESImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::GenVertexArraysOESImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenVertexArraysOESImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -3048,14 +3077,14 @@
       *GetBufferAs<cmds::DeleteVertexArraysOES>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteVertexArraysOES::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteVertexArraysOES::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.arrays_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.arrays_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.arrays_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.arrays_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3066,7 +3095,7 @@
   cmds::DeleteVertexArraysOESImmediate& cmd =
       *GetBufferAs<cmds::DeleteVertexArraysOESImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(arraysize(ids)), ids);
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteVertexArraysOESImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteVertexArraysOESImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(cmd.n * 4u),
             cmd.header.size * 4u);
@@ -3081,21 +3110,21 @@
   cmds::IsVertexArrayOES& cmd = *GetBufferAs<cmds::IsVertexArrayOES>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::IsVertexArrayOES::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::IsVertexArrayOES::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.array);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, BindVertexArrayOES) {
   cmds::BindVertexArrayOES& cmd = *GetBufferAs<cmds::BindVertexArrayOES>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::BindVertexArrayOES::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BindVertexArrayOES::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.array);
@@ -3105,7 +3134,8 @@
 TEST_F(GLES2FormatTest, SwapBuffers) {
   cmds::SwapBuffers& cmd = *GetBufferAs<cmds::SwapBuffers>();
   void* next_cmd = cmd.Set(&cmd);
-  EXPECT_EQ(static_cast<uint32>(cmds::SwapBuffers::kCmdId), cmd.header.command);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::SwapBuffers::kCmdId),
+            cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
@@ -3118,17 +3148,17 @@
                            static_cast<GLsizei>(12),
                            static_cast<GLenum>(13),
                            static_cast<GLuint>(14),
-                           static_cast<uint32>(15),
-                           static_cast<uint32>(16));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetMaxValueInBufferCHROMIUM::kCmdId),
+                           static_cast<uint32_t>(15),
+                           static_cast<uint32_t>(16));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetMaxValueInBufferCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.buffer_id);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
   EXPECT_EQ(static_cast<GLenum>(13), cmd.type);
   EXPECT_EQ(static_cast<GLuint>(14), cmd.offset);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(16), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(16), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3138,16 +3168,16 @@
                            static_cast<GLuint>(11),
                            static_cast<GLuint>(12),
                            static_cast<GLsizei>(13),
-                           static_cast<uint32>(14),
-                           static_cast<uint32>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::GenSharedIdsCHROMIUM::kCmdId),
+                           static_cast<uint32_t>(14),
+                           static_cast<uint32_t>(15));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GenSharedIdsCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.namespace_id);
   EXPECT_EQ(static_cast<GLuint>(12), cmd.id_offset);
   EXPECT_EQ(static_cast<GLsizei>(13), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.ids_shm_id);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.ids_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.ids_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.ids_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3157,15 +3187,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLsizei>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::DeleteSharedIdsCHROMIUM::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteSharedIdsCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.namespace_id);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.ids_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.ids_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.ids_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.ids_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3175,15 +3205,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLsizei>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::RegisterSharedIdsCHROMIUM::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::RegisterSharedIdsCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.namespace_id);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.n);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.ids_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.ids_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.ids_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.ids_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3192,14 +3222,14 @@
       *GetBufferAs<cmds::EnableFeatureCHROMIUM>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::EnableFeatureCHROMIUM::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::EnableFeatureCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.bucket_id);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3209,7 +3239,7 @@
                            static_cast<GLuint>(11),
                            static_cast<GLuint>(12),
                            static_cast<GLfloat>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::ResizeCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ResizeCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.width);
@@ -3221,22 +3251,23 @@
 TEST_F(GLES2FormatTest, GetRequestableExtensionsCHROMIUM) {
   cmds::GetRequestableExtensionsCHROMIUM& cmd =
       *GetBufferAs<cmds::GetRequestableExtensionsCHROMIUM>();
-  void* next_cmd = cmd.Set(&cmd, static_cast<uint32>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetRequestableExtensionsCHROMIUM::kCmdId),
-            cmd.header.command);
+  void* next_cmd = cmd.Set(&cmd, static_cast<uint32_t>(11));
+  EXPECT_EQ(
+      static_cast<uint32_t>(cmds::GetRequestableExtensionsCHROMIUM::kCmdId),
+      cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
-  EXPECT_EQ(static_cast<uint32>(11), cmd.bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(11), cmd.bucket_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
 TEST_F(GLES2FormatTest, RequestExtensionCHROMIUM) {
   cmds::RequestExtensionCHROMIUM& cmd =
       *GetBufferAs<cmds::RequestExtensionCHROMIUM>();
-  void* next_cmd = cmd.Set(&cmd, static_cast<uint32>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::RequestExtensionCHROMIUM::kCmdId),
+  void* next_cmd = cmd.Set(&cmd, static_cast<uint32_t>(11));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::RequestExtensionCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
-  EXPECT_EQ(static_cast<uint32>(11), cmd.bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(11), cmd.bucket_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3244,20 +3275,20 @@
   cmds::GetMultipleIntegervCHROMIUM& cmd =
       *GetBufferAs<cmds::GetMultipleIntegervCHROMIUM>();
   void* next_cmd = cmd.Set(&cmd,
-                           static_cast<uint32>(11),
-                           static_cast<uint32>(12),
+                           static_cast<uint32_t>(11),
+                           static_cast<uint32_t>(12),
                            static_cast<GLuint>(13),
-                           static_cast<uint32>(14),
-                           static_cast<uint32>(15),
+                           static_cast<uint32_t>(14),
+                           static_cast<uint32_t>(15),
                            static_cast<GLsizeiptr>(16));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetMultipleIntegervCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetMultipleIntegervCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
-  EXPECT_EQ(static_cast<uint32>(11), cmd.pnames_shm_id);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.pnames_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(11), cmd.pnames_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.pnames_shm_offset);
   EXPECT_EQ(static_cast<GLuint>(13), cmd.count);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.results_shm_id);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.results_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.results_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.results_shm_offset);
   EXPECT_EQ(static_cast<GLsizeiptr>(16), cmd.size);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
@@ -3266,12 +3297,12 @@
   cmds::GetProgramInfoCHROMIUM& cmd =
       *GetBufferAs<cmds::GetProgramInfoCHROMIUM>();
   void* next_cmd =
-      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetProgramInfoCHROMIUM::kCmdId),
+      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetProgramInfoCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.bucket_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3279,12 +3310,12 @@
   cmds::GetTranslatedShaderSourceANGLE& cmd =
       *GetBufferAs<cmds::GetTranslatedShaderSourceANGLE>();
   void* next_cmd =
-      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::GetTranslatedShaderSourceANGLE::kCmdId),
+      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::GetTranslatedShaderSourceANGLE::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.shader);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.bucket_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3296,7 +3327,7 @@
                            static_cast<GLint>(12),
                            static_cast<GLint>(13),
                            static_cast<GLint>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::PostSubBufferCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::PostSubBufferCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.x);
@@ -3315,7 +3346,7 @@
                            static_cast<GLsizei>(13),
                            static_cast<GLuint>(14),
                            static_cast<GLuint>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::TexImageIOSurface2DCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TexImageIOSurface2DCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -3335,7 +3366,7 @@
                            static_cast<GLint>(14),
                            static_cast<GLint>(15),
                            static_cast<GLenum>(16));
-  EXPECT_EQ(static_cast<uint32>(cmds::CopyTextureCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::CopyTextureCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -3355,7 +3386,7 @@
                            static_cast<GLint>(12),
                            static_cast<GLsizei>(13),
                            static_cast<GLsizei>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::DrawArraysInstancedANGLE::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DrawArraysInstancedANGLE::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.mode);
@@ -3374,7 +3405,7 @@
                            static_cast<GLenum>(13),
                            static_cast<GLuint>(14),
                            static_cast<GLsizei>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::DrawElementsInstancedANGLE::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DrawElementsInstancedANGLE::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.mode);
@@ -3390,7 +3421,7 @@
       *GetBufferAs<cmds::VertexAttribDivisorANGLE>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::VertexAttribDivisorANGLE::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::VertexAttribDivisorANGLE::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.index);
@@ -3404,14 +3435,14 @@
       *GetBufferAs<cmds::ProduceTextureCHROMIUM>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::ProduceTextureCHROMIUM::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ProduceTextureCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.mailbox_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.mailbox_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.mailbox_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.mailbox_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3486,8 +3517,9 @@
   cmds::ProduceTextureCHROMIUMImmediate& cmd =
       *GetBufferAs<cmds::ProduceTextureCHROMIUMImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::ProduceTextureCHROMIUMImmediate::kCmdId),
-            cmd.header.command);
+  EXPECT_EQ(
+      static_cast<uint32_t>(cmds::ProduceTextureCHROMIUMImmediate::kCmdId),
+      cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
             cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -3501,14 +3533,14 @@
       *GetBufferAs<cmds::ConsumeTextureCHROMIUM>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::ConsumeTextureCHROMIUM::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ConsumeTextureCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.mailbox_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.mailbox_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.mailbox_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.mailbox_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3583,8 +3615,9 @@
   cmds::ConsumeTextureCHROMIUMImmediate& cmd =
       *GetBufferAs<cmds::ConsumeTextureCHROMIUMImmediate>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::ConsumeTextureCHROMIUMImmediate::kCmdId),
-            cmd.header.command);
+  EXPECT_EQ(
+      static_cast<uint32_t>(cmds::ConsumeTextureCHROMIUMImmediate::kCmdId),
+      cmd.header.command);
   EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
             cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -3599,17 +3632,17 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLint>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14),
-                           static_cast<uint32>(15));
-  EXPECT_EQ(static_cast<uint32>(cmds::BindUniformLocationCHROMIUM::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14),
+                           static_cast<uint32_t>(15));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BindUniformLocationCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
   EXPECT_EQ(static_cast<GLint>(12), cmd.location);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.name_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.name_shm_offset);
-  EXPECT_EQ(static_cast<uint32>(15), cmd.data_size);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.name_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.name_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(15), cmd.data_size);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3619,14 +3652,14 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLuint>(11),
                            static_cast<GLint>(12),
-                           static_cast<uint32>(13));
+                           static_cast<uint32_t>(13));
   EXPECT_EQ(
-      static_cast<uint32>(cmds::BindUniformLocationCHROMIUMBucket::kCmdId),
+      static_cast<uint32_t>(cmds::BindUniformLocationCHROMIUMBucket::kCmdId),
       cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.program);
   EXPECT_EQ(static_cast<GLint>(12), cmd.location);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.name_bucket_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.name_bucket_id);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3635,7 +3668,7 @@
       *GetBufferAs<cmds::BindTexImage2DCHROMIUM>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::BindTexImage2DCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BindTexImage2DCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -3648,7 +3681,7 @@
       *GetBufferAs<cmds::ReleaseTexImage2DCHROMIUM>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLint>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::ReleaseTexImage2DCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ReleaseTexImage2DCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -3659,7 +3692,7 @@
 TEST_F(GLES2FormatTest, TraceBeginCHROMIUM) {
   cmds::TraceBeginCHROMIUM& cmd = *GetBufferAs<cmds::TraceBeginCHROMIUM>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::TraceBeginCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TraceBeginCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.bucket_id);
@@ -3669,7 +3702,7 @@
 TEST_F(GLES2FormatTest, TraceEndCHROMIUM) {
   cmds::TraceEndCHROMIUM& cmd = *GetBufferAs<cmds::TraceEndCHROMIUM>();
   void* next_cmd = cmd.Set(&cmd);
-  EXPECT_EQ(static_cast<uint32>(cmds::TraceEndCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::TraceEndCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -3687,12 +3720,12 @@
                            static_cast<GLsizei>(16),
                            static_cast<GLenum>(17),
                            static_cast<GLenum>(18),
-                           static_cast<uint32>(19),
-                           static_cast<uint32>(20),
-                           static_cast<uint32>(21),
-                           static_cast<uint32>(22),
-                           static_cast<uint32>(23));
-  EXPECT_EQ(static_cast<uint32>(cmds::AsyncTexSubImage2DCHROMIUM::kCmdId),
+                           static_cast<uint32_t>(19),
+                           static_cast<uint32_t>(20),
+                           static_cast<uint32_t>(21),
+                           static_cast<uint32_t>(22),
+                           static_cast<uint32_t>(23));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::AsyncTexSubImage2DCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -3703,11 +3736,11 @@
   EXPECT_EQ(static_cast<GLsizei>(16), cmd.height);
   EXPECT_EQ(static_cast<GLenum>(17), cmd.format);
   EXPECT_EQ(static_cast<GLenum>(18), cmd.type);
-  EXPECT_EQ(static_cast<uint32>(19), cmd.data_shm_id);
-  EXPECT_EQ(static_cast<uint32>(20), cmd.data_shm_offset);
-  EXPECT_EQ(static_cast<uint32>(21), cmd.async_upload_token);
-  EXPECT_EQ(static_cast<uint32>(22), cmd.sync_data_shm_id);
-  EXPECT_EQ(static_cast<uint32>(23), cmd.sync_data_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(19), cmd.data_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(20), cmd.data_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(21), cmd.async_upload_token);
+  EXPECT_EQ(static_cast<uint32_t>(22), cmd.sync_data_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(23), cmd.sync_data_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3723,12 +3756,12 @@
                            static_cast<GLint>(16),
                            static_cast<GLenum>(17),
                            static_cast<GLenum>(18),
-                           static_cast<uint32>(19),
-                           static_cast<uint32>(20),
-                           static_cast<uint32>(21),
-                           static_cast<uint32>(22),
-                           static_cast<uint32>(23));
-  EXPECT_EQ(static_cast<uint32>(cmds::AsyncTexImage2DCHROMIUM::kCmdId),
+                           static_cast<uint32_t>(19),
+                           static_cast<uint32_t>(20),
+                           static_cast<uint32_t>(21),
+                           static_cast<uint32_t>(22),
+                           static_cast<uint32_t>(23));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::AsyncTexImage2DCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -3739,11 +3772,11 @@
   EXPECT_EQ(static_cast<GLint>(16), cmd.border);
   EXPECT_EQ(static_cast<GLenum>(17), cmd.format);
   EXPECT_EQ(static_cast<GLenum>(18), cmd.type);
-  EXPECT_EQ(static_cast<uint32>(19), cmd.pixels_shm_id);
-  EXPECT_EQ(static_cast<uint32>(20), cmd.pixels_shm_offset);
-  EXPECT_EQ(static_cast<uint32>(21), cmd.async_upload_token);
-  EXPECT_EQ(static_cast<uint32>(22), cmd.sync_data_shm_id);
-  EXPECT_EQ(static_cast<uint32>(23), cmd.sync_data_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(19), cmd.pixels_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(20), cmd.pixels_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(21), cmd.async_upload_token);
+  EXPECT_EQ(static_cast<uint32_t>(22), cmd.sync_data_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(23), cmd.sync_data_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3751,7 +3784,7 @@
   cmds::WaitAsyncTexImage2DCHROMIUM& cmd =
       *GetBufferAs<cmds::WaitAsyncTexImage2DCHROMIUM>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::WaitAsyncTexImage2DCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::WaitAsyncTexImage2DCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
@@ -3762,7 +3795,7 @@
   cmds::WaitAllAsyncTexImage2DCHROMIUM& cmd =
       *GetBufferAs<cmds::WaitAllAsyncTexImage2DCHROMIUM>();
   void* next_cmd = cmd.Set(&cmd);
-  EXPECT_EQ(static_cast<uint32>(cmds::WaitAllAsyncTexImage2DCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::WaitAllAsyncTexImage2DCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -3774,15 +3807,15 @@
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLenum>(11),
                            static_cast<GLsizei>(12),
-                           static_cast<uint32>(13),
-                           static_cast<uint32>(14));
-  EXPECT_EQ(static_cast<uint32>(cmds::DiscardFramebufferEXT::kCmdId),
+                           static_cast<uint32_t>(13),
+                           static_cast<uint32_t>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DiscardFramebufferEXT::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
   EXPECT_EQ(static_cast<GLsizei>(12), cmd.count);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.attachments_shm_id);
-  EXPECT_EQ(static_cast<uint32>(14), cmd.attachments_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.attachments_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(14), cmd.attachments_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3799,7 +3832,7 @@
       sizeof(cmd) + kNumElements * sizeof(GLenum) * 1;
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(1), static_cast<GLsizei>(2), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::DiscardFramebufferEXTImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DiscardFramebufferEXTImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(1), cmd.target);
@@ -3813,7 +3846,7 @@
   cmds::LoseContextCHROMIUM& cmd = *GetBufferAs<cmds::LoseContextCHROMIUM>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLenum>(12));
-  EXPECT_EQ(static_cast<uint32>(cmds::LoseContextCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::LoseContextCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.current);
@@ -3826,7 +3859,7 @@
   cmds::WaitSyncPointCHROMIUM& cmd =
       *GetBufferAs<cmds::WaitSyncPointCHROMIUM>();
   void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
-  EXPECT_EQ(static_cast<uint32>(cmds::WaitSyncPointCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::WaitSyncPointCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLuint>(11), cmd.sync_point);
@@ -3837,14 +3870,14 @@
   cmds::DrawBuffersEXT& cmd = *GetBufferAs<cmds::DrawBuffersEXT>();
   void* next_cmd = cmd.Set(&cmd,
                            static_cast<GLsizei>(11),
-                           static_cast<uint32>(12),
-                           static_cast<uint32>(13));
-  EXPECT_EQ(static_cast<uint32>(cmds::DrawBuffersEXT::kCmdId),
+                           static_cast<uint32_t>(12),
+                           static_cast<uint32_t>(13));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DrawBuffersEXT::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(11), cmd.count);
-  EXPECT_EQ(static_cast<uint32>(12), cmd.bufs_shm_id);
-  EXPECT_EQ(static_cast<uint32>(13), cmd.bufs_shm_offset);
+  EXPECT_EQ(static_cast<uint32_t>(12), cmd.bufs_shm_id);
+  EXPECT_EQ(static_cast<uint32_t>(13), cmd.bufs_shm_offset);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
@@ -3859,7 +3892,7 @@
   const size_t kExpectedCmdSize =
       sizeof(cmd) + kNumElements * sizeof(GLenum) * 1;
   void* next_cmd = cmd.Set(&cmd, static_cast<GLsizei>(1), data);
-  EXPECT_EQ(static_cast<uint32>(cmds::DrawBuffersEXTImmediate::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DrawBuffersEXTImmediate::kCmdId),
             cmd.header.command);
   EXPECT_EQ(kExpectedCmdSize, cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLsizei>(1), cmd.count);
@@ -3872,7 +3905,7 @@
   cmds::DiscardBackbufferCHROMIUM& cmd =
       *GetBufferAs<cmds::DiscardBackbufferCHROMIUM>();
   void* next_cmd = cmd.Set(&cmd);
-  EXPECT_EQ(static_cast<uint32>(cmds::DiscardBackbufferCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::DiscardBackbufferCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
@@ -3893,7 +3926,7 @@
                            static_cast<GLfloat>(19),
                            static_cast<GLfloat>(20),
                            static_cast<GLfloat>(21));
-  EXPECT_EQ(static_cast<uint32>(cmds::ScheduleOverlayPlaneCHROMIUM::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::ScheduleOverlayPlaneCHROMIUM::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLint>(11), cmd.plane_z_order);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils.h b/gpu/command_buffer/common/gles2_cmd_utils.h
index 52d93a3..f6432a7 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils.h
@@ -8,12 +8,13 @@
 #ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_H_
 #define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_H_
 
+#include <stdint.h>
+
 #include <limits>
 #include <string>
 #include <vector>
 
 #include "gpu/command_buffer/common/gles2_utils_export.h"
-#include "gpu/command_buffer/common/types.h"
 
 namespace gpu {
 namespace gles2 {
@@ -23,12 +24,12 @@
 
 // Multiplies 2 32 bit unsigned numbers checking for overflow.
 // If there was no overflow returns true.
-inline bool SafeMultiplyUint32(uint32 a, uint32 b, uint32* dst) {
+inline bool SafeMultiplyUint32(uint32_t a, uint32_t b, uint32_t* dst) {
   if (b == 0) {
     *dst = 0;
     return true;
   }
-  uint32 v = a * b;
+  uint32_t v = a * b;
   if (v / b != a) {
     *dst = 0;
     return false;
@@ -38,7 +39,7 @@
 }
 
 // Does an add checking for overflow.  If there was no overflow returns true.
-inline bool SafeAddUint32(uint32 a, uint32 b, uint32* dst) {
+inline bool SafeAddUint32(uint32_t a, uint32_t b, uint32_t* dst) {
   if (a + b < a) {
     *dst = 0;
     return false;
@@ -48,10 +49,10 @@
 }
 
 // Does an add checking for overflow.  If there was no overflow returns true.
-inline bool SafeAddInt32(int32 a, int32 b, int32* dst) {
-  int64 sum64 = static_cast<int64>(a) + b;
-  int32 sum32 = static_cast<int32>(sum64);
-  bool safe = sum64 == static_cast<int64>(sum32);
+inline bool SafeAddInt32(int32_t a, int32_t b, int32_t* dst) {
+  int64_t sum64 = static_cast<int64_t>(a) + b;
+  int32_t sum32 = static_cast<int32_t>(sum64);
+  bool safe = sum64 == static_cast<int64_t>(sum32);
   *dst = safe ? sum32 : 0;
   return safe;
 }
@@ -59,7 +60,7 @@
 // Return false if |value| is more than a 32 bit integer can represent.
 template<typename T>
 inline bool FitInt32NonNegative(T value) {
-  const int32 max = std::numeric_limits<int32>::max();
+  const int32_t max = std::numeric_limits<int32_t>::max();
   return (std::numeric_limits<T>::max() <= max ||
           value <= static_cast<T>(max));
 }
@@ -83,7 +84,7 @@
   };
 
   struct EnumToString {
-    uint32 value;
+    uint32_t value;
     const char* name;
   };
 
@@ -113,12 +114,12 @@
   int GLGetNumValuesReturned(int id) const;
 
   // Computes the size of a single group of elements from a format and type pair
-  static uint32 ComputeImageGroupSize(int format, int type);
+  static uint32_t ComputeImageGroupSize(int format, int type);
 
   // Computes the size of an image row including alignment padding
   static bool ComputeImagePaddedRowSize(
       int width, int format, int type, int unpack_alignment,
-      uint32* padded_row_size);
+      uint32_t* padded_row_size);
 
   // Computes the size of image data for TexImage2D and TexSubImage2D.
   // Optionally the unpadded and padded row sizes can be returned. If height < 2
@@ -126,40 +127,40 @@
   // padding is not necessary.
   static bool ComputeImageDataSizes(
       int width, int height, int format, int type, int unpack_alignment,
-      uint32* size, uint32* unpadded_row_size, uint32* padded_row_size);
+      uint32_t* size, uint32_t* unpadded_row_size, uint32_t* padded_row_size);
 
   static size_t RenderbufferBytesPerPixel(int format);
 
-  static uint32 GetGLDataTypeSizeForUniforms(int type);
+  static uint32_t GetGLDataTypeSizeForUniforms(int type);
 
-  static size_t GetGLTypeSizeForTexturesAndBuffers(uint32 type);
+  static size_t GetGLTypeSizeForTexturesAndBuffers(uint32_t type);
 
-  static uint32 GLErrorToErrorBit(uint32 gl_error);
+  static uint32_t GLErrorToErrorBit(uint32_t gl_error);
 
-  static uint32 GLErrorBitToGLError(uint32 error_bit);
+  static uint32_t GLErrorBitToGLError(uint32_t error_bit);
 
-  static uint32 IndexToGLFaceTarget(int index);
+  static uint32_t IndexToGLFaceTarget(int index);
 
-  static uint32 GetPreferredGLReadPixelsFormat(uint32 internal_format);
+  static uint32_t GetPreferredGLReadPixelsFormat(uint32_t internal_format);
 
-  static uint32 GetPreferredGLReadPixelsType(
-      uint32 internal_format, uint32 texture_type);
+  static uint32_t GetPreferredGLReadPixelsType(
+      uint32_t internal_format, uint32_t texture_type);
 
   // Returns a bitmask for the channels the given format supports.
   // See ChannelBits.
-  static uint32 GetChannelsForFormat(int format);
+  static uint32_t GetChannelsForFormat(int format);
 
   // Returns a bitmask for the channels the given attachment type needs.
-  static uint32 GetChannelsNeededForAttachmentType(
-      int type, uint32 max_color_attachments);
+  static uint32_t GetChannelsNeededForAttachmentType(
+      int type, uint32_t max_color_attachments);
 
-  static bool IsNPOT(uint32 value) {
+  static bool IsNPOT(uint32_t value) {
     return value > 0 && (value & (value - 1)) != 0;
   }
 
-  static std::string GetStringEnum(uint32 value);
-  static std::string GetStringBool(uint32 value);
-  static std::string GetStringError(uint32 value);
+  static std::string GetStringEnum(uint32_t value);
+  static std::string GetStringBool(uint32_t value);
+  static std::string GetStringError(uint32_t value);
 
   // Parses a uniform name.
   //   array_pos: the position of the last '[' character in name.
@@ -178,7 +179,7 @@
 
  private:
   static std::string GetQualifiedEnumString(
-      const EnumToString* table, size_t count, uint32 value);
+      const EnumToString* table, size_t count, uint32_t value);
 
   static const EnumToString* const enum_to_string_table_;
   static const size_t enum_to_string_table_len_;
@@ -191,18 +192,18 @@
  public:
   ContextCreationAttribHelper();
 
-  void Serialize(std::vector<int32>* attribs);
-  bool Parse(const std::vector<int32>& attribs);
+  void Serialize(std::vector<int32_t>* attribs);
+  bool Parse(const std::vector<int32_t>& attribs);
 
   // -1 if invalid or unspecified.
-  int32 alpha_size_;
-  int32 blue_size_;
-  int32 green_size_;
-  int32 red_size_;
-  int32 depth_size_;
-  int32 stencil_size_;
-  int32 samples_;
-  int32 sample_buffers_;
+  int32_t alpha_size_;
+  int32_t blue_size_;
+  int32_t green_size_;
+  int32_t red_size_;
+  int32_t depth_size_;
+  int32_t stencil_size_;
+  int32_t samples_;
+  int32_t sample_buffers_;
   bool buffer_preserved_;
   bool share_resources_;
   bool bind_generates_resource_;
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
index 4798a6f..d4f5776 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
@@ -11,60 +11,60 @@
 #ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_AUTOGEN_H_
 #define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_AUTOGEN_H_
 
-static std::string GetStringAttachment(uint32 value);
-static std::string GetStringBackbufferAttachment(uint32 value);
-static std::string GetStringBlitFilter(uint32 value);
-static std::string GetStringBufferParameter(uint32 value);
-static std::string GetStringBufferTarget(uint32 value);
-static std::string GetStringBufferUsage(uint32 value);
-static std::string GetStringCapability(uint32 value);
-static std::string GetStringCmpFunction(uint32 value);
-static std::string GetStringCompressedTextureFormat(uint32 value);
-static std::string GetStringDrawMode(uint32 value);
-static std::string GetStringDstBlendFactor(uint32 value);
-static std::string GetStringEquation(uint32 value);
-static std::string GetStringFaceMode(uint32 value);
-static std::string GetStringFaceType(uint32 value);
-static std::string GetStringFrameBufferParameter(uint32 value);
-static std::string GetStringFrameBufferTarget(uint32 value);
-static std::string GetStringGLState(uint32 value);
-static std::string GetStringGetMaxIndexType(uint32 value);
-static std::string GetStringGetTexParamTarget(uint32 value);
-static std::string GetStringHintMode(uint32 value);
-static std::string GetStringHintTarget(uint32 value);
-static std::string GetStringIndexType(uint32 value);
-static std::string GetStringPixelStore(uint32 value);
-static std::string GetStringPixelType(uint32 value);
-static std::string GetStringProgramParameter(uint32 value);
-static std::string GetStringQueryObjectParameter(uint32 value);
-static std::string GetStringQueryParameter(uint32 value);
-static std::string GetStringQueryTarget(uint32 value);
-static std::string GetStringReadPixelFormat(uint32 value);
-static std::string GetStringReadPixelType(uint32 value);
-static std::string GetStringRenderBufferFormat(uint32 value);
-static std::string GetStringRenderBufferParameter(uint32 value);
-static std::string GetStringRenderBufferTarget(uint32 value);
-static std::string GetStringResetStatus(uint32 value);
-static std::string GetStringShaderBinaryFormat(uint32 value);
-static std::string GetStringShaderParameter(uint32 value);
-static std::string GetStringShaderPrecision(uint32 value);
-static std::string GetStringShaderType(uint32 value);
-static std::string GetStringSrcBlendFactor(uint32 value);
-static std::string GetStringStencilOp(uint32 value);
-static std::string GetStringStringType(uint32 value);
-static std::string GetStringTextureBindTarget(uint32 value);
-static std::string GetStringTextureFormat(uint32 value);
-static std::string GetStringTextureInternalFormat(uint32 value);
-static std::string GetStringTextureInternalFormatStorage(uint32 value);
-static std::string GetStringTextureMagFilterMode(uint32 value);
-static std::string GetStringTextureMinFilterMode(uint32 value);
-static std::string GetStringTextureParameter(uint32 value);
-static std::string GetStringTexturePool(uint32 value);
-static std::string GetStringTextureTarget(uint32 value);
-static std::string GetStringTextureUsage(uint32 value);
-static std::string GetStringTextureWrapMode(uint32 value);
-static std::string GetStringVertexAttribType(uint32 value);
-static std::string GetStringVertexAttribute(uint32 value);
-static std::string GetStringVertexPointer(uint32 value);
+static std::string GetStringAttachment(uint32_t value);
+static std::string GetStringBackbufferAttachment(uint32_t value);
+static std::string GetStringBlitFilter(uint32_t value);
+static std::string GetStringBufferParameter(uint32_t value);
+static std::string GetStringBufferTarget(uint32_t value);
+static std::string GetStringBufferUsage(uint32_t value);
+static std::string GetStringCapability(uint32_t value);
+static std::string GetStringCmpFunction(uint32_t value);
+static std::string GetStringCompressedTextureFormat(uint32_t value);
+static std::string GetStringDrawMode(uint32_t value);
+static std::string GetStringDstBlendFactor(uint32_t value);
+static std::string GetStringEquation(uint32_t value);
+static std::string GetStringFaceMode(uint32_t value);
+static std::string GetStringFaceType(uint32_t value);
+static std::string GetStringFrameBufferParameter(uint32_t value);
+static std::string GetStringFrameBufferTarget(uint32_t value);
+static std::string GetStringGLState(uint32_t value);
+static std::string GetStringGetMaxIndexType(uint32_t value);
+static std::string GetStringGetTexParamTarget(uint32_t value);
+static std::string GetStringHintMode(uint32_t value);
+static std::string GetStringHintTarget(uint32_t value);
+static std::string GetStringIndexType(uint32_t value);
+static std::string GetStringPixelStore(uint32_t value);
+static std::string GetStringPixelType(uint32_t value);
+static std::string GetStringProgramParameter(uint32_t value);
+static std::string GetStringQueryObjectParameter(uint32_t value);
+static std::string GetStringQueryParameter(uint32_t value);
+static std::string GetStringQueryTarget(uint32_t value);
+static std::string GetStringReadPixelFormat(uint32_t value);
+static std::string GetStringReadPixelType(uint32_t value);
+static std::string GetStringRenderBufferFormat(uint32_t value);
+static std::string GetStringRenderBufferParameter(uint32_t value);
+static std::string GetStringRenderBufferTarget(uint32_t value);
+static std::string GetStringResetStatus(uint32_t value);
+static std::string GetStringShaderBinaryFormat(uint32_t value);
+static std::string GetStringShaderParameter(uint32_t value);
+static std::string GetStringShaderPrecision(uint32_t value);
+static std::string GetStringShaderType(uint32_t value);
+static std::string GetStringSrcBlendFactor(uint32_t value);
+static std::string GetStringStencilOp(uint32_t value);
+static std::string GetStringStringType(uint32_t value);
+static std::string GetStringTextureBindTarget(uint32_t value);
+static std::string GetStringTextureFormat(uint32_t value);
+static std::string GetStringTextureInternalFormat(uint32_t value);
+static std::string GetStringTextureInternalFormatStorage(uint32_t value);
+static std::string GetStringTextureMagFilterMode(uint32_t value);
+static std::string GetStringTextureMinFilterMode(uint32_t value);
+static std::string GetStringTextureParameter(uint32_t value);
+static std::string GetStringTexturePool(uint32_t value);
+static std::string GetStringTextureTarget(uint32_t value);
+static std::string GetStringTextureUsage(uint32_t value);
+static std::string GetStringTextureWrapMode(uint32_t value);
+static std::string GetStringVertexAttribType(uint32_t value);
+static std::string GetStringVertexAttribute(uint32_t value);
+static std::string GetStringVertexPointer(uint32_t value);
 
 #endif  // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
index 5283c24..14800ba 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -256,9 +256,6 @@
      0x9242, "GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM",
     },
     {
-     0x88BA, "GL_READ_WRITE",
-    },
-    {
      0x88BB, "GL_BUFFER_ACCESS_OES",
     },
     {
@@ -1000,6 +997,9 @@
      0x0C01, "GL_DRAW_BUFFER_EXT",
     },
     {
+     0x78F2, "GL_IMAGE_SCANOUT_CHROMIUM",
+    },
+    {
      0x93C7, "GL_COMPRESSED_RGBA_ASTC_6x5x5_OES",
     },
     {
@@ -1273,6 +1273,9 @@
      0x84CA, "GL_TEXTURE10",
     },
     {
+     0x78F1, "GL_IMAGE_MAP_CHROMIUM",
+    },
+    {
      0x84CF, "GL_TEXTURE15",
     },
     {
@@ -2353,7 +2356,7 @@
 const size_t GLES2Util::enum_to_string_table_len_ =
     sizeof(enum_to_string_table) / sizeof(enum_to_string_table[0]);
 
-std::string GLES2Util::GetStringAttachment(uint32 value) {
+std::string GLES2Util::GetStringAttachment(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_COLOR_ATTACHMENT0, "GL_COLOR_ATTACHMENT0"},
       {GL_DEPTH_ATTACHMENT, "GL_DEPTH_ATTACHMENT"},
@@ -2363,7 +2366,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringBackbufferAttachment(uint32 value) {
+std::string GLES2Util::GetStringBackbufferAttachment(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_COLOR_EXT, "GL_COLOR_EXT"},
       {GL_DEPTH_EXT, "GL_DEPTH_EXT"},
@@ -2373,7 +2376,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringBlitFilter(uint32 value) {
+std::string GLES2Util::GetStringBlitFilter(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_NEAREST, "GL_NEAREST"}, {GL_LINEAR, "GL_LINEAR"},
   };
@@ -2381,7 +2384,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringBufferParameter(uint32 value) {
+std::string GLES2Util::GetStringBufferParameter(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_BUFFER_SIZE, "GL_BUFFER_SIZE"}, {GL_BUFFER_USAGE, "GL_BUFFER_USAGE"},
   };
@@ -2389,7 +2392,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringBufferTarget(uint32 value) {
+std::string GLES2Util::GetStringBufferTarget(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_ARRAY_BUFFER, "GL_ARRAY_BUFFER"},
       {GL_ELEMENT_ARRAY_BUFFER, "GL_ELEMENT_ARRAY_BUFFER"},
@@ -2398,7 +2401,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringBufferUsage(uint32 value) {
+std::string GLES2Util::GetStringBufferUsage(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_STREAM_DRAW, "GL_STREAM_DRAW"},
       {GL_STATIC_DRAW, "GL_STATIC_DRAW"},
@@ -2408,7 +2411,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringCapability(uint32 value) {
+std::string GLES2Util::GetStringCapability(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_BLEND, "GL_BLEND"},
       {GL_CULL_FACE, "GL_CULL_FACE"},
@@ -2424,7 +2427,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringCmpFunction(uint32 value) {
+std::string GLES2Util::GetStringCmpFunction(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_NEVER, "GL_NEVER"},
       {GL_LESS, "GL_LESS"},
@@ -2439,11 +2442,11 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringCompressedTextureFormat(uint32 value) {
+std::string GLES2Util::GetStringCompressedTextureFormat(uint32_t value) {
   return GLES2Util::GetQualifiedEnumString(NULL, 0, value);
 }
 
-std::string GLES2Util::GetStringDrawMode(uint32 value) {
+std::string GLES2Util::GetStringDrawMode(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_POINTS, "GL_POINTS"},
       {GL_LINE_STRIP, "GL_LINE_STRIP"},
@@ -2457,7 +2460,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringDstBlendFactor(uint32 value) {
+std::string GLES2Util::GetStringDstBlendFactor(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_ZERO, "GL_ZERO"},
       {GL_ONE, "GL_ONE"},
@@ -2478,7 +2481,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringEquation(uint32 value) {
+std::string GLES2Util::GetStringEquation(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_FUNC_ADD, "GL_FUNC_ADD"},
       {GL_FUNC_SUBTRACT, "GL_FUNC_SUBTRACT"},
@@ -2488,7 +2491,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringFaceMode(uint32 value) {
+std::string GLES2Util::GetStringFaceMode(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_CW, "GL_CW"}, {GL_CCW, "GL_CCW"},
   };
@@ -2496,7 +2499,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringFaceType(uint32 value) {
+std::string GLES2Util::GetStringFaceType(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_FRONT, "GL_FRONT"},
       {GL_BACK, "GL_BACK"},
@@ -2506,7 +2509,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringFrameBufferParameter(uint32 value) {
+std::string GLES2Util::GetStringFrameBufferParameter(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
        "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE"},
@@ -2521,7 +2524,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringFrameBufferTarget(uint32 value) {
+std::string GLES2Util::GetStringFrameBufferTarget(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_FRAMEBUFFER, "GL_FRAMEBUFFER"},
   };
@@ -2529,7 +2532,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringGLState(uint32 value) {
+std::string GLES2Util::GetStringGLState(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_ACTIVE_TEXTURE, "GL_ACTIVE_TEXTURE"},
       {GL_ALIASED_LINE_WIDTH_RANGE, "GL_ALIASED_LINE_WIDTH_RANGE"},
@@ -2640,7 +2643,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringGetMaxIndexType(uint32 value) {
+std::string GLES2Util::GetStringGetMaxIndexType(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_UNSIGNED_BYTE, "GL_UNSIGNED_BYTE"},
       {GL_UNSIGNED_SHORT, "GL_UNSIGNED_SHORT"},
@@ -2650,7 +2653,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringGetTexParamTarget(uint32 value) {
+std::string GLES2Util::GetStringGetTexParamTarget(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_TEXTURE_2D, "GL_TEXTURE_2D"},
       {GL_TEXTURE_CUBE_MAP, "GL_TEXTURE_CUBE_MAP"},
@@ -2659,7 +2662,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringHintMode(uint32 value) {
+std::string GLES2Util::GetStringHintMode(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_FASTEST, "GL_FASTEST"},
       {GL_NICEST, "GL_NICEST"},
@@ -2669,7 +2672,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringHintTarget(uint32 value) {
+std::string GLES2Util::GetStringHintTarget(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_GENERATE_MIPMAP_HINT, "GL_GENERATE_MIPMAP_HINT"},
   };
@@ -2677,7 +2680,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringIndexType(uint32 value) {
+std::string GLES2Util::GetStringIndexType(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_UNSIGNED_BYTE, "GL_UNSIGNED_BYTE"},
       {GL_UNSIGNED_SHORT, "GL_UNSIGNED_SHORT"},
@@ -2686,7 +2689,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringPixelStore(uint32 value) {
+std::string GLES2Util::GetStringPixelStore(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_PACK_ALIGNMENT, "GL_PACK_ALIGNMENT"},
       {GL_UNPACK_ALIGNMENT, "GL_UNPACK_ALIGNMENT"},
@@ -2700,7 +2703,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringPixelType(uint32 value) {
+std::string GLES2Util::GetStringPixelType(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_UNSIGNED_BYTE, "GL_UNSIGNED_BYTE"},
       {GL_UNSIGNED_SHORT_5_6_5, "GL_UNSIGNED_SHORT_5_6_5"},
@@ -2711,7 +2714,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringProgramParameter(uint32 value) {
+std::string GLES2Util::GetStringProgramParameter(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_DELETE_STATUS, "GL_DELETE_STATUS"},
       {GL_LINK_STATUS, "GL_LINK_STATUS"},
@@ -2727,7 +2730,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringQueryObjectParameter(uint32 value) {
+std::string GLES2Util::GetStringQueryObjectParameter(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_QUERY_RESULT_EXT, "GL_QUERY_RESULT_EXT"},
       {GL_QUERY_RESULT_AVAILABLE_EXT, "GL_QUERY_RESULT_AVAILABLE_EXT"},
@@ -2736,7 +2739,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringQueryParameter(uint32 value) {
+std::string GLES2Util::GetStringQueryParameter(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_CURRENT_QUERY_EXT, "GL_CURRENT_QUERY_EXT"},
   };
@@ -2744,7 +2747,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringQueryTarget(uint32 value) {
+std::string GLES2Util::GetStringQueryTarget(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_ANY_SAMPLES_PASSED_EXT, "GL_ANY_SAMPLES_PASSED_EXT"},
       {GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
@@ -2761,7 +2764,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringReadPixelFormat(uint32 value) {
+std::string GLES2Util::GetStringReadPixelFormat(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_ALPHA, "GL_ALPHA"}, {GL_RGB, "GL_RGB"}, {GL_RGBA, "GL_RGBA"},
   };
@@ -2769,7 +2772,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringReadPixelType(uint32 value) {
+std::string GLES2Util::GetStringReadPixelType(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_UNSIGNED_BYTE, "GL_UNSIGNED_BYTE"},
       {GL_UNSIGNED_SHORT_5_6_5, "GL_UNSIGNED_SHORT_5_6_5"},
@@ -2780,7 +2783,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringRenderBufferFormat(uint32 value) {
+std::string GLES2Util::GetStringRenderBufferFormat(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_RGBA4, "GL_RGBA4"},
       {GL_RGB565, "GL_RGB565"},
@@ -2792,7 +2795,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringRenderBufferParameter(uint32 value) {
+std::string GLES2Util::GetStringRenderBufferParameter(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_RENDERBUFFER_RED_SIZE, "GL_RENDERBUFFER_RED_SIZE"},
       {GL_RENDERBUFFER_GREEN_SIZE, "GL_RENDERBUFFER_GREEN_SIZE"},
@@ -2808,7 +2811,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringRenderBufferTarget(uint32 value) {
+std::string GLES2Util::GetStringRenderBufferTarget(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_RENDERBUFFER, "GL_RENDERBUFFER"},
   };
@@ -2816,7 +2819,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringResetStatus(uint32 value) {
+std::string GLES2Util::GetStringResetStatus(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_GUILTY_CONTEXT_RESET_ARB, "GL_GUILTY_CONTEXT_RESET_ARB"},
       {GL_INNOCENT_CONTEXT_RESET_ARB, "GL_INNOCENT_CONTEXT_RESET_ARB"},
@@ -2826,11 +2829,11 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringShaderBinaryFormat(uint32 value) {
+std::string GLES2Util::GetStringShaderBinaryFormat(uint32_t value) {
   return GLES2Util::GetQualifiedEnumString(NULL, 0, value);
 }
 
-std::string GLES2Util::GetStringShaderParameter(uint32 value) {
+std::string GLES2Util::GetStringShaderParameter(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_SHADER_TYPE, "GL_SHADER_TYPE"},
       {GL_DELETE_STATUS, "GL_DELETE_STATUS"},
@@ -2844,7 +2847,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringShaderPrecision(uint32 value) {
+std::string GLES2Util::GetStringShaderPrecision(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_LOW_FLOAT, "GL_LOW_FLOAT"},
       {GL_MEDIUM_FLOAT, "GL_MEDIUM_FLOAT"},
@@ -2857,7 +2860,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringShaderType(uint32 value) {
+std::string GLES2Util::GetStringShaderType(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_VERTEX_SHADER, "GL_VERTEX_SHADER"},
       {GL_FRAGMENT_SHADER, "GL_FRAGMENT_SHADER"},
@@ -2866,7 +2869,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringSrcBlendFactor(uint32 value) {
+std::string GLES2Util::GetStringSrcBlendFactor(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_ZERO, "GL_ZERO"},
       {GL_ONE, "GL_ONE"},
@@ -2888,7 +2891,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringStencilOp(uint32 value) {
+std::string GLES2Util::GetStringStencilOp(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_KEEP, "GL_KEEP"},
       {GL_ZERO, "GL_ZERO"},
@@ -2903,7 +2906,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringStringType(uint32 value) {
+std::string GLES2Util::GetStringStringType(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_VENDOR, "GL_VENDOR"},
       {GL_RENDERER, "GL_RENDERER"},
@@ -2915,7 +2918,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringTextureBindTarget(uint32 value) {
+std::string GLES2Util::GetStringTextureBindTarget(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_TEXTURE_2D, "GL_TEXTURE_2D"},
       {GL_TEXTURE_CUBE_MAP, "GL_TEXTURE_CUBE_MAP"},
@@ -2924,7 +2927,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringTextureFormat(uint32 value) {
+std::string GLES2Util::GetStringTextureFormat(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_ALPHA, "GL_ALPHA"},
       {GL_LUMINANCE, "GL_LUMINANCE"},
@@ -2936,7 +2939,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringTextureInternalFormat(uint32 value) {
+std::string GLES2Util::GetStringTextureInternalFormat(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_ALPHA, "GL_ALPHA"},
       {GL_LUMINANCE, "GL_LUMINANCE"},
@@ -2948,7 +2951,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringTextureInternalFormatStorage(uint32 value) {
+std::string GLES2Util::GetStringTextureInternalFormatStorage(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_RGB565, "GL_RGB565"},
       {GL_RGBA4, "GL_RGBA4"},
@@ -2963,7 +2966,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringTextureMagFilterMode(uint32 value) {
+std::string GLES2Util::GetStringTextureMagFilterMode(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_NEAREST, "GL_NEAREST"}, {GL_LINEAR, "GL_LINEAR"},
   };
@@ -2971,7 +2974,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringTextureMinFilterMode(uint32 value) {
+std::string GLES2Util::GetStringTextureMinFilterMode(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_NEAREST, "GL_NEAREST"},
       {GL_LINEAR, "GL_LINEAR"},
@@ -2984,7 +2987,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringTextureParameter(uint32 value) {
+std::string GLES2Util::GetStringTextureParameter(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_TEXTURE_MAG_FILTER, "GL_TEXTURE_MAG_FILTER"},
       {GL_TEXTURE_MIN_FILTER, "GL_TEXTURE_MIN_FILTER"},
@@ -2996,7 +2999,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringTexturePool(uint32 value) {
+std::string GLES2Util::GetStringTexturePool(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_TEXTURE_POOL_MANAGED_CHROMIUM, "GL_TEXTURE_POOL_MANAGED_CHROMIUM"},
       {GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
@@ -3006,7 +3009,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringTextureTarget(uint32 value) {
+std::string GLES2Util::GetStringTextureTarget(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_TEXTURE_2D, "GL_TEXTURE_2D"},
       {GL_TEXTURE_CUBE_MAP_POSITIVE_X, "GL_TEXTURE_CUBE_MAP_POSITIVE_X"},
@@ -3020,7 +3023,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringTextureUsage(uint32 value) {
+std::string GLES2Util::GetStringTextureUsage(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_NONE, "GL_NONE"},
       {GL_FRAMEBUFFER_ATTACHMENT_ANGLE, "GL_FRAMEBUFFER_ATTACHMENT_ANGLE"},
@@ -3029,7 +3032,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringTextureWrapMode(uint32 value) {
+std::string GLES2Util::GetStringTextureWrapMode(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_CLAMP_TO_EDGE, "GL_CLAMP_TO_EDGE"},
       {GL_MIRRORED_REPEAT, "GL_MIRRORED_REPEAT"},
@@ -3039,7 +3042,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringVertexAttribType(uint32 value) {
+std::string GLES2Util::GetStringVertexAttribType(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_BYTE, "GL_BYTE"},
       {GL_UNSIGNED_BYTE, "GL_UNSIGNED_BYTE"},
@@ -3051,7 +3054,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringVertexAttribute(uint32 value) {
+std::string GLES2Util::GetStringVertexAttribute(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED"},
       {GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
@@ -3066,7 +3069,7 @@
       string_table, arraysize(string_table), value);
 }
 
-std::string GLES2Util::GetStringVertexPointer(uint32 value) {
+std::string GLES2Util::GetStringVertexPointer(uint32_t value) {
   static const EnumToString string_table[] = {
       {GL_VERTEX_ATTRIB_ARRAY_POINTER, "GL_VERTEX_ATTRIB_ARRAY_POINTER"},
   };
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc b/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc
index 0ded3b9..d0e7e03 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc
+++ b/gpu/command_buffer/common/gles2_cmd_utils_unittest.cc
@@ -20,7 +20,7 @@
 };
 
 TEST_F(GLES2UtilTest, SafeMultiplyUint32) {
-  uint32 result = 0;
+  uint32_t result = 0;
   EXPECT_TRUE(SafeMultiplyUint32(2u, 3u, &result));
   EXPECT_EQ(6u, result);
   EXPECT_FALSE(SafeMultiplyUint32(0x80000000u, 2u, &result));
@@ -32,7 +32,7 @@
 }
 
 TEST_F(GLES2UtilTest, SafeAddUint32) {
-  uint32 result = 0;
+  uint32_t result = 0;
   EXPECT_TRUE(SafeAddUint32(2u, 3u, &result));
   EXPECT_EQ(5u, result);
   EXPECT_FALSE(SafeAddUint32(0x80000000u, 0x80000000u, &result));
@@ -48,9 +48,9 @@
 }
 
 TEST_F(GLES2UtilTest, SafeAddInt32) {
-  int32 result = 0;
-  const int32 kMax = std::numeric_limits<int32>::max();
-  const int32 kMin = std::numeric_limits<int32>::min();
+  int32_t result = 0;
+  const int32_t kMax = std::numeric_limits<int32_t>::max();
+  const int32_t kMin = std::numeric_limits<int32_t>::min();
   EXPECT_TRUE(SafeAddInt32(2, 3, &result));
   EXPECT_EQ(5, result);
   EXPECT_FALSE(SafeAddInt32(kMax, 1, &result));
@@ -89,11 +89,11 @@
 }
 
 TEST_F(GLES2UtilTest, ComputeImageDataSizesFormats) {
-  const uint32 kWidth = 16;
-  const uint32 kHeight = 12;
-  uint32 size;
-  uint32 unpadded_row_size;
-  uint32 padded_row_size;
+  const uint32_t kWidth = 16;
+  const uint32_t kHeight = 12;
+  uint32_t size;
+  uint32_t unpadded_row_size;
+  uint32_t padded_row_size;
   EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
       kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size,
       &padded_row_size));
@@ -146,11 +146,11 @@
 }
 
 TEST_F(GLES2UtilTest, ComputeImageDataSizeTypes) {
-  const uint32 kWidth = 16;
-  const uint32 kHeight = 12;
-  uint32 size;
-  uint32 unpadded_row_size;
-  uint32 padded_row_size;
+  const uint32_t kWidth = 16;
+  const uint32_t kHeight = 12;
+  uint32_t size;
+  uint32_t unpadded_row_size;
+  uint32_t padded_row_size;
   EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
       kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size,
       &padded_row_size));
@@ -184,11 +184,11 @@
 }
 
 TEST_F(GLES2UtilTest, ComputeImageDataSizesUnpackAlignment) {
-  const uint32 kWidth = 19;
-  const uint32 kHeight = 12;
-  uint32 size;
-  uint32 unpadded_row_size;
-  uint32 padded_row_size;
+  const uint32_t kWidth = 19;
+  const uint32_t kHeight = 12;
+  uint32_t size;
+  uint32_t unpadded_row_size;
+  uint32_t padded_row_size;
   EXPECT_TRUE(GLES2Util::ComputeImageDataSizes(
       kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, 1, &size, &unpadded_row_size,
       &padded_row_size));
diff --git a/gpu/command_buffer/common/gpu_control.h b/gpu/command_buffer/common/gpu_control.h
deleted file mode 100644
index e15d5e6..0000000
--- a/gpu/command_buffer/common/gpu_control.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef GPU_COMMAND_BUFFER_COMMON_GPU_CONTROL_H_
-#define GPU_COMMAND_BUFFER_COMMON_GPU_CONTROL_H_
-
-#include <vector>
-
-#include "base/callback.h"
-#include "gpu/command_buffer/common/capabilities.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/types.h"
-#include "gpu/gpu_export.h"
-
-namespace gfx {
-class GpuMemoryBuffer;
-}
-
-namespace gpu {
-struct ManagedMemoryStats;
-
-// Common interface for GpuControl implementations.
-class GPU_EXPORT GpuControl {
- public:
-  GpuControl() {}
-  virtual ~GpuControl() {}
-
-  virtual Capabilities GetCapabilities() = 0;
-
-  // Create a gpu memory buffer of the given dimensions and format. Returns
-  // its ID or -1 on error.
-  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(
-      size_t width,
-      size_t height,
-      unsigned internalformat,
-      int32* id) = 0;
-
-  // Destroy a gpu memory buffer. The ID must be positive.
-  virtual void DestroyGpuMemoryBuffer(int32 id) = 0;
-
-  // Inserts a sync point, returning its ID. Sync point IDs are global and can
-  // be used for cross-context synchronization.
-  virtual uint32 InsertSyncPoint() = 0;
-
-  // Runs |callback| when a sync point is reached.
-  virtual void SignalSyncPoint(uint32 sync_point,
-                               const base::Closure& callback) = 0;
-
-  // Runs |callback| when a query created via glCreateQueryEXT() has cleared
-  // passed the glEndQueryEXT() point.
-  virtual void SignalQuery(uint32 query, const base::Closure& callback) = 0;
-
-  virtual void SetSurfaceVisible(bool visible) = 0;
-
-  virtual void SendManagedMemoryStats(const ManagedMemoryStats& stats) = 0;
-
-  // Invokes the callback once the context has been flushed.
-  virtual void Echo(const base::Closure& callback) = 0;
-
-  // Attaches an external stream to the texture given by |texture_id| and
-  // returns a stream identifier.
-  virtual uint32 CreateStreamTexture(uint32 texture_id) = 0;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(GpuControl);
-};
-
-}  // namespace gpu
-
-#endif  // GPU_COMMAND_BUFFER_COMMON_GPU_CONTROL_H_
diff --git a/gpu/command_buffer/common/id_allocator.h b/gpu/command_buffer/common/id_allocator.h
index 46fcd1a..3f2dc4a 100644
--- a/gpu/command_buffer/common/id_allocator.h
+++ b/gpu/command_buffer/common/id_allocator.h
@@ -7,17 +7,19 @@
 #ifndef GPU_COMMAND_BUFFER_CLIENT_ID_ALLOCATOR_H_
 #define GPU_COMMAND_BUFFER_CLIENT_ID_ALLOCATOR_H_
 
+#include <stdint.h>
+
 #include <set>
 #include <utility>
 
 #include "base/compiler_specific.h"
-#include "gpu/command_buffer/common/types.h"
+#include "base/macros.h"
 #include "gpu/gpu_export.h"
 
 namespace gpu {
 
 // A resource ID, key to the resource maps.
-typedef uint32 ResourceId;
+typedef uint32_t ResourceId;
 // Invalid resource ID.
 static const ResourceId kInvalidResource = 0u;
 
diff --git a/gpu/command_buffer/common/mailbox.h b/gpu/command_buffer/common/mailbox.h
index 06b4b59..a45c91f 100644
--- a/gpu/command_buffer/common/mailbox.h
+++ b/gpu/command_buffer/common/mailbox.h
@@ -5,9 +5,9 @@
 #ifndef GPU_COMMAND_BUFFER_MAILBOX_H_
 #define GPU_COMMAND_BUFFER_MAILBOX_H_
 
+#include <stdint.h>
 #include <string.h>
 
-#include "gpu/command_buffer/common/types.h"
 #include "gpu/gpu_export.h"
 
 // From gl2/gl2ext.h.
@@ -21,7 +21,7 @@
   Mailbox();
   bool IsZero() const;
   void SetZero();
-  void SetName(const int8* name);
+  void SetName(const int8_t* name);
 
   // Generate a unique unguessable mailbox name.
   static Mailbox Generate();
@@ -31,7 +31,7 @@
   // check, only to catch bugs where clients forgot to call Mailbox::Generate.
   bool Verify() const;
 
-  int8 name[GL_MAILBOX_SIZE_CHROMIUM];
+  int8_t name[GL_MAILBOX_SIZE_CHROMIUM];
   bool operator<(const Mailbox& other) const {
     return memcmp(this, &other, sizeof other) < 0;
   }
diff --git a/gpu/command_buffer/common/mailbox_holder.cc b/gpu/command_buffer/common/mailbox_holder.cc
index a8cb6fb..87dec36 100644
--- a/gpu/command_buffer/common/mailbox_holder.cc
+++ b/gpu/command_buffer/common/mailbox_holder.cc
@@ -9,8 +9,8 @@
 MailboxHolder::MailboxHolder() : texture_target(0), sync_point(0) {}
 
 MailboxHolder::MailboxHolder(const Mailbox& mailbox,
-                             uint32 texture_target,
-                             uint32 sync_point)
+                             uint32_t texture_target,
+                             uint32_t sync_point)
     : mailbox(mailbox),
       texture_target(texture_target),
       sync_point(sync_point) {}
diff --git a/gpu/command_buffer/common/mailbox_holder.h b/gpu/command_buffer/common/mailbox_holder.h
index a17d8d3..7c7a0e2 100644
--- a/gpu/command_buffer/common/mailbox_holder.h
+++ b/gpu/command_buffer/common/mailbox_holder.h
@@ -5,10 +5,10 @@
 #ifndef GPU_COMMAND_BUFFER_MAILBOX_HOLDER_H_
 #define GPU_COMMAND_BUFFER_MAILBOX_HOLDER_H_
 
+#include <stdint.h>
 #include <string.h>
 
 #include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/types.h"
 #include "gpu/gpu_export.h"
 
 namespace gpu {
@@ -16,11 +16,11 @@
 struct GPU_EXPORT MailboxHolder {
   MailboxHolder();
   MailboxHolder(const gpu::Mailbox& mailbox,
-                uint32 texture_target,
-                uint32 sync_point);
+                uint32_t texture_target,
+                uint32_t sync_point);
   gpu::Mailbox mailbox;
-  uint32 texture_target;
-  uint32 sync_point;
+  uint32_t texture_target;
+  uint32_t sync_point;
 };
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/common/types.h b/gpu/command_buffer/common/types.h
deleted file mode 100644
index 718ecca..0000000
--- a/gpu/command_buffer/common/types.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains cross-platform basic type definitions
-
-#ifndef GPU_COMMAND_BUFFER_COMMON_TYPES_H_
-#define GPU_COMMAND_BUFFER_COMMON_TYPES_H_
-
-#if !defined(_MSC_VER)
-#include <stdint.h>
-#endif
-#include <cstddef>
-#include <string>
-
-typedef signed char         schar;
-typedef signed char         int8;
-// TODO(mbelshe) Remove these type guards.  These are
-//               temporary to avoid conflicts with npapi.h.
-#ifndef _INT16
-#define _INT16
-typedef short               int16;
-#endif
-#ifndef _INT32
-#define _INT32
-typedef int                 int32;
-#endif
-
-// The NSPR system headers define 64-bit as |long| when possible.  In order to
-// not have typedef mismatches, we do the same on LP64.
-#if defined(__LP64__) && !defined(__APPLE__) && !defined(__OpenBSD__)
-typedef long                int64;
-#else
-typedef long long           int64;
-#endif
-
-// NOTE: unsigned types are DANGEROUS in loops and other arithmetical
-// places.  Use the signed types unless your variable represents a bit
-// pattern (eg a hash value) or you really need the extra bit.  Do NOT
-// use 'unsigned' to express "this value should always be positive";
-// use assertions for this.
-
-typedef unsigned char      uint8;
-// TODO(mbelshe) Remove these type guards.  These are
-//               temporary to avoid conflicts with npapi.h.
-#ifndef _UINT16
-#define _UINT16
-typedef unsigned short     uint16;
-#endif
-#ifndef _UINT32
-#define _UINT32
-typedef unsigned int       uint32;
-#endif
-
-// See the comment above about NSPR and 64-bit.
-#if defined(__LP64__) && !defined(__APPLE__) && !defined(__OpenBSD__)
-typedef unsigned long uint64;
-#else
-typedef unsigned long long uint64;
-#endif
-
-// A macro to disallow the copy constructor and operator= functions
-// This should be used in the private: declarations for a class
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
-  TypeName(const TypeName&);               \
-  void operator=(const TypeName&)
-
-// A macro to disallow all the implicit constructors, namely the
-// default constructor, copy constructor and operator= functions.
-//
-// This should be used in the private: declarations for a class
-// that wants to prevent anyone from instantiating it. This is
-// especially useful for classes containing only static methods.
-#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
-  TypeName();                                    \
-  DISALLOW_COPY_AND_ASSIGN(TypeName)
-
-// The arraysize(arr) macro returns the # of elements in an array arr.
-// The expression is a compile-time constant, and therefore can be
-// used in defining new arrays, for example.  If you use arraysize on
-// a pointer by mistake, you will get a compile-time error.
-//
-// One caveat is that arraysize() doesn't accept any array of an
-// anonymous type or a type defined inside a function.  In these rare
-// cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below.  This is
-// due to a limitation in C++'s template system.  The limitation might
-// eventually be removed, but it hasn't happened yet.
-
-// This template function declaration is used in defining arraysize.
-// Note that the function doesn't need an implementation, as we only
-// use its type.
-template <typename T, size_t N>
-char (&ArraySizeHelper(T (&array)[N]))[N];
-
-// That gcc wants both of these prototypes seems mysterious. VC, for
-// its part, can't decide which to use (another mystery). Matching of
-// template overloads: the final frontier.
-#if !defined(_MSC_VER)
-template <typename T, size_t N>
-char (&ArraySizeHelper(const T (&array)[N]))[N];
-#endif
-
-#define arraysize(array) (sizeof(ArraySizeHelper(array)))
-
-// The COMPILE_ASSERT macro can be used to verify that a compile time
-// expression is true. For example, you could use it to verify the
-// size of a static array:
-//
-//   COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES,
-//                  content_type_names_incorrect_size);
-//
-// or to make sure a struct is smaller than a certain size:
-//
-//   COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
-//
-// The second argument to the macro is the name of the variable. If
-// the expression is false, most compilers will issue a warning/error
-// containing the name of the variable.
-
-template <bool>
-struct GpuCompileAssert {
-};
-
-#undef COMPILE_ASSERT
-#define COMPILE_ASSERT(expr, msg) \
-  typedef GpuCompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
-
-// Implementation details of COMPILE_ASSERT:
-//
-// - COMPILE_ASSERT works by defining an array type that has -1
-//   elements (and thus is invalid) when the expression is false.
-//
-// - The simpler definition
-//
-//     #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
-//
-//   does not work, as gcc supports variable-length arrays whose sizes
-//   are determined at run-time (this is gcc's extension and not part
-//   of the C++ standard).  As a result, gcc fails to reject the
-//   following code with the simple definition:
-//
-//     int foo;
-//     COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
-//                               // not a compile-time constant.
-//
-// - By using the type CompileAssert<(bool(expr))>, we ensures that
-//   expr is a compile-time constant.  (Template arguments must be
-//   determined at compile-time.)
-//
-// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
-//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
-//
-//     CompileAssert<bool(expr)>
-//
-//   instead, these compilers will refuse to compile
-//
-//     COMPILE_ASSERT(5 > 0, some_message);
-//
-//   (They seem to think the ">" in "5 > 0" marks the end of the
-//   template argument list.)
-//
-// - The array size is (bool(expr) ? 1 : -1), instead of simply
-//
-//     ((expr) ? 1 : -1).
-//
-//   This is to avoid running into a bug in MS VC 7.1, which
-//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
-
-namespace gpu {
-#if defined(_MSC_VER)
-typedef short Int16;
-typedef unsigned short Uint16;
-typedef int Int32;
-typedef unsigned int Uint32;
-#else
-typedef int16_t Int16;
-typedef uint16_t Uint16;
-typedef int32_t Int32;
-typedef uint32_t Uint32;
-#endif
-
-typedef std::string String;
-
-}  // namespace gpu
-
-#endif  // GPU_COMMAND_BUFFER_COMMON_TYPES_H_
diff --git a/gpu/command_buffer/gles2_utils.target.darwin-arm.mk b/gpu/command_buffer/gles2_utils.target.darwin-arm.mk
index ed4442a..bb58f90 100644
--- a/gpu/command_buffer/gles2_utils.target.darwin-arm.mk
+++ b/gpu/command_buffer/gles2_utils.target.darwin-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -131,7 +130,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/command_buffer/gles2_utils.target.darwin-x86.mk b/gpu/command_buffer/gles2_utils.target.darwin-x86.mk
index 7ed5b6a..57163f1 100644
--- a/gpu/command_buffer/gles2_utils.target.darwin-x86.mk
+++ b/gpu/command_buffer/gles2_utils.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer/gles2_utils.target.darwin-x86_64.mk b/gpu/command_buffer/gles2_utils.target.darwin-x86_64.mk
index b785282..bb0d63a 100644
--- a/gpu/command_buffer/gles2_utils.target.darwin-x86_64.mk
+++ b/gpu/command_buffer/gles2_utils.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer/gles2_utils.target.linux-arm.mk b/gpu/command_buffer/gles2_utils.target.linux-arm.mk
index ed4442a..bb58f90 100644
--- a/gpu/command_buffer/gles2_utils.target.linux-arm.mk
+++ b/gpu/command_buffer/gles2_utils.target.linux-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -131,7 +130,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/command_buffer/gles2_utils.target.linux-x86.mk b/gpu/command_buffer/gles2_utils.target.linux-x86.mk
index 7ed5b6a..57163f1 100644
--- a/gpu/command_buffer/gles2_utils.target.linux-x86.mk
+++ b/gpu/command_buffer/gles2_utils.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer/gles2_utils.target.linux-x86_64.mk b/gpu/command_buffer/gles2_utils.target.linux-x86_64.mk
index b785282..bb0d63a 100644
--- a/gpu/command_buffer/gles2_utils.target.linux-x86_64.mk
+++ b/gpu/command_buffer/gles2_utils.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc
index 5795106..a2b2255 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_android.cc
@@ -30,6 +30,14 @@
   return false;
 }
 
+bool IsNvidia31() {
+  const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
+  const char* version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
+  return vendor && version &&
+         std::string(vendor).find("NVIDIA") != std::string::npos &&
+         std::string(version).find("OpenGL ES 3.1") != std::string::npos;
+}
+
 }
 
 // We only used threaded uploads when we can:
@@ -54,6 +62,7 @@
           context->HasExtension("GL_OES_EGL_image") &&
           !IsBroadcom() &&
           !IsImagination() &&
+          !IsNvidia31() &&
           !base::android::SysUtils::IsLowEndDevice()) {
         return new AsyncPixelTransferManagerEGL;
       }
diff --git a/gpu/command_buffer/service/context_state.cc b/gpu/command_buffer/service/context_state.cc
index 2eb3f99..77d1f92 100644
--- a/gpu/command_buffer/service/context_state.cc
+++ b/gpu/command_buffer/service/context_state.cc
@@ -18,7 +18,7 @@
 
 namespace {
 
-void EnableDisable(GLenum pname, bool enable) {
+static void EnableDisable(GLenum pname, bool enable) {
   if (enable) {
     glEnable(pname);
   } else {
@@ -92,6 +92,7 @@
                            Logger* logger)
     : active_texture_unit(0),
       pack_reverse_row_order(false),
+      ignore_cached_state(false),
       fbo_binding_for_scissor_workaround_dirty_(false),
       feature_info_(feature_info),
       error_state_(ErrorState::Create(error_state_client, logger)) {
diff --git a/gpu/command_buffer/service/context_state.h b/gpu/command_buffer/service/context_state.h
index 83818e9..e436e74 100644
--- a/gpu/command_buffer/service/context_state.h
+++ b/gpu/command_buffer/service/context_state.h
@@ -101,6 +101,10 @@
 
   void Initialize();
 
+  void SetIgnoreCachedStateForTest(bool ignore) {
+    ignore_cached_state = ignore;
+  }
+
   void RestoreState(const ContextState* prev_state) const;
   void InitCapabilities(const ContextState* prev_state) const;
   void InitState(const ContextState* prev_state) const;
@@ -126,6 +130,44 @@
       GLenum pname, GLfloat* params, GLsizei* num_written) const;
   bool GetEnabled(GLenum cap) const;
 
+  inline void SetDeviceColorMask(GLboolean red,
+                                 GLboolean green,
+                                 GLboolean blue,
+                                 GLboolean alpha) {
+    if (cached_color_mask_red == red && cached_color_mask_green == green &&
+        cached_color_mask_blue == blue && cached_color_mask_alpha == alpha &&
+        !ignore_cached_state)
+      return;
+    cached_color_mask_red = red;
+    cached_color_mask_green = green;
+    cached_color_mask_blue = blue;
+    cached_color_mask_alpha = alpha;
+    glColorMask(red, green, blue, alpha);
+  }
+
+  inline void SetDeviceDepthMask(GLboolean mask) {
+    if (cached_depth_mask == mask && !ignore_cached_state)
+      return;
+    cached_depth_mask = mask;
+    glDepthMask(mask);
+  }
+
+  inline void SetDeviceStencilMaskSeparate(GLenum op, GLuint mask) {
+    if (op == GL_FRONT) {
+      if (cached_stencil_front_writemask == mask && !ignore_cached_state)
+        return;
+      cached_stencil_front_writemask = mask;
+    } else if (op == GL_BACK) {
+      if (cached_stencil_back_writemask == mask && !ignore_cached_state)
+        return;
+      cached_stencil_back_writemask = mask;
+    } else {
+      NOTREACHED();
+      return;
+    }
+    glStencilMaskSeparate(op, mask);
+  }
+
   ErrorState* GetErrorState();
 
   #include "gpu/command_buffer/service/context_state_autogen.h"
@@ -162,6 +204,7 @@
   QueryMap current_queries;
 
   bool pack_reverse_row_order;
+  bool ignore_cached_state;
 
   mutable bool fbo_binding_for_scissor_workaround_dirty_;
   FeatureInfo* feature_info_;
diff --git a/gpu/command_buffer/service/context_state_autogen.h b/gpu/command_buffer/service/context_state_autogen.h
index 6e408a3..309301f 100644
--- a/gpu/command_buffer/service/context_state_autogen.h
+++ b/gpu/command_buffer/service/context_state_autogen.h
@@ -15,14 +15,23 @@
 struct EnableFlags {
   EnableFlags();
   bool blend;
+  bool cached_blend;
   bool cull_face;
+  bool cached_cull_face;
   bool depth_test;
+  bool cached_depth_test;
   bool dither;
+  bool cached_dither;
   bool polygon_offset_fill;
+  bool cached_polygon_offset_fill;
   bool sample_alpha_to_coverage;
+  bool cached_sample_alpha_to_coverage;
   bool sample_coverage;
+  bool cached_sample_coverage;
   bool scissor_test;
+  bool cached_scissor_test;
   bool stencil_test;
+  bool cached_stencil_test;
 };
 
 GLfloat blend_color_red;
@@ -42,12 +51,17 @@
 GLclampf depth_clear;
 GLint stencil_clear;
 GLboolean color_mask_red;
+GLboolean cached_color_mask_red;
 GLboolean color_mask_green;
+GLboolean cached_color_mask_green;
 GLboolean color_mask_blue;
+GLboolean cached_color_mask_blue;
 GLboolean color_mask_alpha;
+GLboolean cached_color_mask_alpha;
 GLenum cull_mode;
 GLenum depth_func;
 GLboolean depth_mask;
+GLboolean cached_depth_mask;
 GLclampf z_near;
 GLclampf z_far;
 GLenum front_face;
@@ -71,7 +85,9 @@
 GLint stencil_back_ref;
 GLuint stencil_back_mask;
 GLuint stencil_front_writemask;
+GLuint cached_stencil_front_writemask;
 GLuint stencil_back_writemask;
+GLuint cached_stencil_back_writemask;
 GLenum stencil_front_fail_op;
 GLenum stencil_front_z_fail_op;
 GLenum stencil_front_z_pass_op;
@@ -83,4 +99,62 @@
 GLsizei viewport_width;
 GLsizei viewport_height;
 
+inline void SetDeviceCapabilityState(GLenum cap, bool enable) {
+  switch (cap) {
+    case GL_BLEND:
+      if (enable_flags.cached_blend == enable && !ignore_cached_state)
+        return;
+      enable_flags.cached_blend = enable;
+      break;
+    case GL_CULL_FACE:
+      if (enable_flags.cached_cull_face == enable && !ignore_cached_state)
+        return;
+      enable_flags.cached_cull_face = enable;
+      break;
+    case GL_DEPTH_TEST:
+      if (enable_flags.cached_depth_test == enable && !ignore_cached_state)
+        return;
+      enable_flags.cached_depth_test = enable;
+      break;
+    case GL_DITHER:
+      if (enable_flags.cached_dither == enable && !ignore_cached_state)
+        return;
+      enable_flags.cached_dither = enable;
+      break;
+    case GL_POLYGON_OFFSET_FILL:
+      if (enable_flags.cached_polygon_offset_fill == enable &&
+          !ignore_cached_state)
+        return;
+      enable_flags.cached_polygon_offset_fill = enable;
+      break;
+    case GL_SAMPLE_ALPHA_TO_COVERAGE:
+      if (enable_flags.cached_sample_alpha_to_coverage == enable &&
+          !ignore_cached_state)
+        return;
+      enable_flags.cached_sample_alpha_to_coverage = enable;
+      break;
+    case GL_SAMPLE_COVERAGE:
+      if (enable_flags.cached_sample_coverage == enable && !ignore_cached_state)
+        return;
+      enable_flags.cached_sample_coverage = enable;
+      break;
+    case GL_SCISSOR_TEST:
+      if (enable_flags.cached_scissor_test == enable && !ignore_cached_state)
+        return;
+      enable_flags.cached_scissor_test = enable;
+      break;
+    case GL_STENCIL_TEST:
+      if (enable_flags.cached_stencil_test == enable && !ignore_cached_state)
+        return;
+      enable_flags.cached_stencil_test = enable;
+      break;
+    default:
+      NOTREACHED();
+      return;
+  }
+  if (enable)
+    glEnable(cap);
+  else
+    glDisable(cap);
+}
 #endif  // GPU_COMMAND_BUFFER_SERVICE_CONTEXT_STATE_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/context_state_impl_autogen.h b/gpu/command_buffer/service/context_state_impl_autogen.h
index 5b3709c..056a382 100644
--- a/gpu/command_buffer/service/context_state_impl_autogen.h
+++ b/gpu/command_buffer/service/context_state_impl_autogen.h
@@ -14,14 +14,23 @@
 
 ContextState::EnableFlags::EnableFlags()
     : blend(false),
+      cached_blend(false),
       cull_face(false),
+      cached_cull_face(false),
       depth_test(false),
+      cached_depth_test(false),
       dither(true),
+      cached_dither(true),
       polygon_offset_fill(false),
+      cached_polygon_offset_fill(false),
       sample_alpha_to_coverage(false),
+      cached_sample_alpha_to_coverage(false),
       sample_coverage(false),
+      cached_sample_coverage(false),
       scissor_test(false),
-      stencil_test(false) {
+      cached_scissor_test(false),
+      stencil_test(false),
+      cached_stencil_test(false) {
 }
 
 void ContextState::Initialize() {
@@ -42,12 +51,17 @@
   depth_clear = 1.0f;
   stencil_clear = 0;
   color_mask_red = true;
+  cached_color_mask_red = true;
   color_mask_green = true;
+  cached_color_mask_green = true;
   color_mask_blue = true;
+  cached_color_mask_blue = true;
   color_mask_alpha = true;
+  cached_color_mask_alpha = true;
   cull_mode = GL_BACK;
   depth_func = GL_LESS;
   depth_mask = true;
+  cached_depth_mask = true;
   z_near = 0.0f;
   z_far = 1.0f;
   front_face = GL_CCW;
@@ -71,7 +85,9 @@
   stencil_back_ref = 0;
   stencil_back_mask = 0xFFFFFFFFU;
   stencil_front_writemask = 0xFFFFFFFFU;
+  cached_stencil_front_writemask = 0xFFFFFFFFU;
   stencil_back_writemask = 0xFFFFFFFFU;
+  cached_stencil_back_writemask = 0xFFFFFFFFU;
   stencil_front_fail_op = GL_KEEP;
   stencil_front_z_fail_op = GL_KEEP;
   stencil_front_z_pass_op = GL_KEEP;
@@ -86,39 +102,45 @@
 
 void ContextState::InitCapabilities(const ContextState* prev_state) const {
   if (prev_state) {
-    if (prev_state->enable_flags.blend != enable_flags.blend)
-      EnableDisable(GL_BLEND, enable_flags.blend);
-    if (prev_state->enable_flags.cull_face != enable_flags.cull_face)
-      EnableDisable(GL_CULL_FACE, enable_flags.cull_face);
-    if (prev_state->enable_flags.depth_test != enable_flags.depth_test)
-      EnableDisable(GL_DEPTH_TEST, enable_flags.depth_test);
-    if (prev_state->enable_flags.dither != enable_flags.dither)
-      EnableDisable(GL_DITHER, enable_flags.dither);
-    if (prev_state->enable_flags.polygon_offset_fill !=
-        enable_flags.polygon_offset_fill)
-      EnableDisable(GL_POLYGON_OFFSET_FILL, enable_flags.polygon_offset_fill);
-    if (prev_state->enable_flags.sample_alpha_to_coverage !=
-        enable_flags.sample_alpha_to_coverage)
+    if (prev_state->enable_flags.cached_blend != enable_flags.cached_blend)
+      EnableDisable(GL_BLEND, enable_flags.cached_blend);
+    if (prev_state->enable_flags.cached_cull_face !=
+        enable_flags.cached_cull_face)
+      EnableDisable(GL_CULL_FACE, enable_flags.cached_cull_face);
+    if (prev_state->enable_flags.cached_depth_test !=
+        enable_flags.cached_depth_test)
+      EnableDisable(GL_DEPTH_TEST, enable_flags.cached_depth_test);
+    if (prev_state->enable_flags.cached_dither != enable_flags.cached_dither)
+      EnableDisable(GL_DITHER, enable_flags.cached_dither);
+    if (prev_state->enable_flags.cached_polygon_offset_fill !=
+        enable_flags.cached_polygon_offset_fill)
+      EnableDisable(GL_POLYGON_OFFSET_FILL,
+                    enable_flags.cached_polygon_offset_fill);
+    if (prev_state->enable_flags.cached_sample_alpha_to_coverage !=
+        enable_flags.cached_sample_alpha_to_coverage)
       EnableDisable(GL_SAMPLE_ALPHA_TO_COVERAGE,
-                    enable_flags.sample_alpha_to_coverage);
-    if (prev_state->enable_flags.sample_coverage !=
-        enable_flags.sample_coverage)
-      EnableDisable(GL_SAMPLE_COVERAGE, enable_flags.sample_coverage);
-    if (prev_state->enable_flags.scissor_test != enable_flags.scissor_test)
-      EnableDisable(GL_SCISSOR_TEST, enable_flags.scissor_test);
-    if (prev_state->enable_flags.stencil_test != enable_flags.stencil_test)
-      EnableDisable(GL_STENCIL_TEST, enable_flags.stencil_test);
+                    enable_flags.cached_sample_alpha_to_coverage);
+    if (prev_state->enable_flags.cached_sample_coverage !=
+        enable_flags.cached_sample_coverage)
+      EnableDisable(GL_SAMPLE_COVERAGE, enable_flags.cached_sample_coverage);
+    if (prev_state->enable_flags.cached_scissor_test !=
+        enable_flags.cached_scissor_test)
+      EnableDisable(GL_SCISSOR_TEST, enable_flags.cached_scissor_test);
+    if (prev_state->enable_flags.cached_stencil_test !=
+        enable_flags.cached_stencil_test)
+      EnableDisable(GL_STENCIL_TEST, enable_flags.cached_stencil_test);
   } else {
-    EnableDisable(GL_BLEND, enable_flags.blend);
-    EnableDisable(GL_CULL_FACE, enable_flags.cull_face);
-    EnableDisable(GL_DEPTH_TEST, enable_flags.depth_test);
-    EnableDisable(GL_DITHER, enable_flags.dither);
-    EnableDisable(GL_POLYGON_OFFSET_FILL, enable_flags.polygon_offset_fill);
+    EnableDisable(GL_BLEND, enable_flags.cached_blend);
+    EnableDisable(GL_CULL_FACE, enable_flags.cached_cull_face);
+    EnableDisable(GL_DEPTH_TEST, enable_flags.cached_depth_test);
+    EnableDisable(GL_DITHER, enable_flags.cached_dither);
+    EnableDisable(GL_POLYGON_OFFSET_FILL,
+                  enable_flags.cached_polygon_offset_fill);
     EnableDisable(GL_SAMPLE_ALPHA_TO_COVERAGE,
-                  enable_flags.sample_alpha_to_coverage);
-    EnableDisable(GL_SAMPLE_COVERAGE, enable_flags.sample_coverage);
-    EnableDisable(GL_SCISSOR_TEST, enable_flags.scissor_test);
-    EnableDisable(GL_STENCIL_TEST, enable_flags.stencil_test);
+                  enable_flags.cached_sample_alpha_to_coverage);
+    EnableDisable(GL_SAMPLE_COVERAGE, enable_flags.cached_sample_coverage);
+    EnableDisable(GL_SCISSOR_TEST, enable_flags.cached_scissor_test);
+    EnableDisable(GL_STENCIL_TEST, enable_flags.cached_stencil_test);
   }
 }
 
@@ -155,18 +177,20 @@
       glClearDepth(depth_clear);
     if ((stencil_clear != prev_state->stencil_clear))
       glClearStencil(stencil_clear);
-    if ((color_mask_red != prev_state->color_mask_red) ||
-        (color_mask_green != prev_state->color_mask_green) ||
-        (color_mask_blue != prev_state->color_mask_blue) ||
-        (color_mask_alpha != prev_state->color_mask_alpha))
-      glColorMask(
-          color_mask_red, color_mask_green, color_mask_blue, color_mask_alpha);
+    if ((cached_color_mask_red != prev_state->cached_color_mask_red) ||
+        (cached_color_mask_green != prev_state->cached_color_mask_green) ||
+        (cached_color_mask_blue != prev_state->cached_color_mask_blue) ||
+        (cached_color_mask_alpha != prev_state->cached_color_mask_alpha))
+      glColorMask(cached_color_mask_red,
+                  cached_color_mask_green,
+                  cached_color_mask_blue,
+                  cached_color_mask_alpha);
     if ((cull_mode != prev_state->cull_mode))
       glCullFace(cull_mode);
     if ((depth_func != prev_state->depth_func))
       glDepthFunc(depth_func);
-    if ((depth_mask != prev_state->depth_mask))
-      glDepthMask(depth_mask);
+    if ((cached_depth_mask != prev_state->cached_depth_mask))
+      glDepthMask(cached_depth_mask);
     if ((z_near != prev_state->z_near) || (z_far != prev_state->z_far))
       glDepthRange(z_near, z_far);
     if ((front_face != prev_state->front_face))
@@ -205,10 +229,12 @@
         (stencil_back_mask != prev_state->stencil_back_mask))
       glStencilFuncSeparate(
           GL_BACK, stencil_back_func, stencil_back_ref, stencil_back_mask);
-    if ((stencil_front_writemask != prev_state->stencil_front_writemask))
-      glStencilMaskSeparate(GL_FRONT, stencil_front_writemask);
-    if ((stencil_back_writemask != prev_state->stencil_back_writemask))
-      glStencilMaskSeparate(GL_BACK, stencil_back_writemask);
+    if ((cached_stencil_front_writemask !=
+         prev_state->cached_stencil_front_writemask))
+      glStencilMaskSeparate(GL_FRONT, cached_stencil_front_writemask);
+    if ((cached_stencil_back_writemask !=
+         prev_state->cached_stencil_back_writemask))
+      glStencilMaskSeparate(GL_BACK, cached_stencil_back_writemask);
     if ((stencil_front_fail_op != prev_state->stencil_front_fail_op) ||
         (stencil_front_z_fail_op != prev_state->stencil_front_z_fail_op) ||
         (stencil_front_z_pass_op != prev_state->stencil_front_z_pass_op))
@@ -242,11 +268,13 @@
                  color_clear_alpha);
     glClearDepth(depth_clear);
     glClearStencil(stencil_clear);
-    glColorMask(
-        color_mask_red, color_mask_green, color_mask_blue, color_mask_alpha);
+    glColorMask(cached_color_mask_red,
+                cached_color_mask_green,
+                cached_color_mask_blue,
+                cached_color_mask_alpha);
     glCullFace(cull_mode);
     glDepthFunc(depth_func);
-    glDepthMask(depth_mask);
+    glDepthMask(cached_depth_mask);
     glDepthRange(z_near, z_far);
     glFrontFace(front_face);
     glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
@@ -263,8 +291,8 @@
         GL_FRONT, stencil_front_func, stencil_front_ref, stencil_front_mask);
     glStencilFuncSeparate(
         GL_BACK, stencil_back_func, stencil_back_ref, stencil_back_mask);
-    glStencilMaskSeparate(GL_FRONT, stencil_front_writemask);
-    glStencilMaskSeparate(GL_BACK, stencil_back_writemask);
+    glStencilMaskSeparate(GL_FRONT, cached_stencil_front_writemask);
+    glStencilMaskSeparate(GL_BACK, cached_stencil_back_writemask);
     glStencilOpSeparate(GL_FRONT,
                         stencil_front_fail_op,
                         stencil_front_z_fail_op,
diff --git a/gpu/command_buffer/service/error_state.h b/gpu/command_buffer/service/error_state.h
index 0e6a4b0..95f118c 100644
--- a/gpu/command_buffer/service/error_state.h
+++ b/gpu/command_buffer/service/error_state.h
@@ -7,8 +7,10 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_ERROR_STATE_H_
 #define GPU_COMMAND_BUFFER_SERVICE_ERROR_STATE_H_
 
+#include <stdint.h>
+
 #include "base/compiler_specific.h"
-#include "gpu/command_buffer/common/types.h"
+#include "base/macros.h"
 #include "gpu/gpu_export.h"
 
 namespace gpu {
@@ -67,7 +69,7 @@
 
   static ErrorState* Create(ErrorStateClient* client, Logger* logger);
 
-  virtual uint32 GetGLError() = 0;
+  virtual uint32_t GetGLError() = 0;
 
   virtual void SetGLError(
       const char* filename,
diff --git a/gpu/command_buffer/service/error_state_mock.h b/gpu/command_buffer/service/error_state_mock.h
index e418ca5..eb056f3 100644
--- a/gpu/command_buffer/service/error_state_mock.h
+++ b/gpu/command_buffer/service/error_state_mock.h
@@ -18,7 +18,7 @@
   MockErrorState();
   virtual ~MockErrorState();
 
-  MOCK_METHOD0(GetGLError, uint32());
+  MOCK_METHOD0(GetGLError, uint32_t());
   MOCK_METHOD5(SetGLError, void(
       const char* filename, int line,
       unsigned error, const char* function_name, const char* msg));
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
index 87c7803..bda65ac 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
@@ -7,7 +7,6 @@
 #include <algorithm>
 
 #include "base/basictypes.h"
-#include "gpu/command_buffer/common/types.h"
 #include "gpu/command_buffer/service/gl_utils.h"
 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 4b75c2e..e690bc3 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -278,15 +278,6 @@
   return true;
 }
 
-// Wrapper for glEnable/glDisable that doesn't suck.
-static void EnableDisable(GLenum pname, bool enable) {
-  if (enable) {
-    glEnable(pname);
-  } else {
-    glDisable(pname);
-  }
-}
-
 // This class prevents any GL errors that occur when it is in scope from
 // being reported to the client.
 class ScopedGLErrorSuppressor {
@@ -661,6 +652,7 @@
   virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
   virtual void SetAsyncPixelTransferManagerForTest(
       AsyncPixelTransferManager* manager) OVERRIDE;
+  virtual void SetIgnoreCachedStateForTest(bool ignore) OVERRIDE;
   void ProcessFinishedAsyncTransfers();
 
   virtual bool GetServiceTextureId(uint32 client_texture_id,
@@ -1105,12 +1097,9 @@
   }
 
   // Creates a vertex attrib manager for the given vertex array.
-  scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
-      GLuint client_id,
-      GLuint service_id,
-      bool client_visible) {
+  void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
     return vertex_array_manager()->CreateVertexAttribManager(
-        client_id, service_id, group_->max_vertex_attribs(), client_visible);
+      client_id, service_id, group_->max_vertex_attribs());
   }
 
   void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
@@ -1932,7 +1921,7 @@
   glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
   const int width = decoder_->offscreen_size_.width();
   const int height = decoder_->offscreen_size_.height();
-  glDisable(GL_SCISSOR_TEST);
+  decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
   decoder->BlitFramebufferHelper(0,
                                  0,
                                  width,
@@ -1954,7 +1943,7 @@
       "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
   decoder_->RestoreCurrentFramebufferBindings();
   if (decoder_->state_.enable_flags.scissor_test) {
-    glEnable(GL_SCISSOR_TEST);
+    decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
   }
 }
 
@@ -2358,17 +2347,7 @@
   disallowed_features_ = disallowed_features;
 
   state_.attrib_values.resize(group_->max_vertex_attribs());
-  vertex_array_manager_.reset(new VertexArrayManager());
-
-  GLuint default_vertex_attrib_service_id = 0;
-  if (features().native_vertex_array_object) {
-    glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
-    glBindVertexArrayOES(default_vertex_attrib_service_id);
-  }
-
-  state_.default_vertex_attrib_manager =
-      CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
-
+  state_.default_vertex_attrib_manager = new VertexAttribManager();
   state_.default_vertex_attrib_manager->Initialize(
       group_->max_vertex_attribs(),
       feature_info_->workarounds().init_vertex_attributes);
@@ -2377,6 +2356,7 @@
   DoBindVertexArrayOES(0);
 
   query_manager_.reset(new QueryManager(this, feature_info_.get()));
+  vertex_array_manager_.reset(new VertexArrayManager());
 
   util_.set_num_compressed_texture_formats(
       validators_->compressed_texture_format.GetValues().size());
@@ -2688,6 +2668,7 @@
 #endif
 
   caps.post_sub_buffer = supports_post_sub_buffer_;
+  caps.map_image = !!image_manager();
 
   return caps;
 }
@@ -3070,12 +3051,12 @@
     if (backbuffer_needs_clear_bits_) {
       glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
           offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
-      glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+      state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
       glClearStencil(0);
       glStencilMask(-1);
       glClearDepth(1.0f);
-      glDepthMask(true);
-      glDisable(GL_SCISSOR_TEST);
+      state_.SetDeviceDepthMask(GL_TRUE);
+      state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
       glClear(backbuffer_needs_clear_bits_);
       backbuffer_needs_clear_bits_ = 0;
       RestoreClearState();
@@ -3578,13 +3559,13 @@
     ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
     glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
         offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
-    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+    state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
     glClearStencil(0);
-    glStencilMaskSeparate(GL_FRONT, -1);
-    glStencilMaskSeparate(GL_BACK, -1);
+    state_.SetDeviceStencilMaskSeparate(GL_FRONT, -1);
+    state_.SetDeviceStencilMaskSeparate(GL_BACK, -1);
     glClearDepth(0);
-    glDepthMask(GL_TRUE);
-    glDisable(GL_SCISSOR_TEST);
+    state_.SetDeviceDepthMask(GL_TRUE);
+    state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
     RestoreClearState();
   }
@@ -3847,23 +3828,25 @@
 
 void GLES2DecoderImpl::ApplyDirtyState() {
   if (framebuffer_state_.clear_state_dirty) {
-    glColorMask(
-        state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
-        state_.color_mask_alpha &&
-            BoundFramebufferHasColorAttachmentWithAlpha(true));
+    bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
+    state_.SetDeviceColorMask(state_.color_mask_red,
+                              state_.color_mask_green,
+                              state_.color_mask_blue,
+                              state_.color_mask_alpha && have_alpha);
+
     bool have_depth = BoundFramebufferHasDepthAttachment();
-    glDepthMask(state_.depth_mask && have_depth);
-    EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
+    state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
+
     bool have_stencil = BoundFramebufferHasStencilAttachment();
-    glStencilMaskSeparate(
+    state_.SetDeviceStencilMaskSeparate(
         GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
-    glStencilMaskSeparate(
+    state_.SetDeviceStencilMaskSeparate(
         GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
-    EnableDisable(
+
+    state_.SetDeviceCapabilityState(
+        GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
+    state_.SetDeviceCapabilityState(
         GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
-    EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
-    EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
-    EnableDisable(GL_BLEND, state_.enable_flags.blend);
     framebuffer_state_.clear_state_dirty = false;
   }
 }
@@ -3936,6 +3919,10 @@
   state_.RestoreVertexAttribs();
 }
 
+void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
+  state_.SetIgnoreCachedStateForTest(ignore);
+}
+
 void GLES2DecoderImpl::OnFboChanged() const {
   if (workarounds().restore_scissor_on_fbo_change)
     state_.fbo_binding_for_scissor_workaround_dirty_ = true;
@@ -4719,7 +4706,7 @@
   if (name == NULL) {
     return error::kOutOfBounds;
   }
-  String name_str(name, name_size);
+  std::string name_str(name, name_size);
   DoBindAttribLocation(program, index, name_str.c_str());
   return error::kNoError;
 }
@@ -4784,7 +4771,7 @@
   if (name == NULL) {
     return error::kOutOfBounds;
   }
-  String name_str(name, name_size);
+  std::string name_str(name, name_size);
   DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
   return error::kNoError;
 }
@@ -5029,7 +5016,7 @@
         (GLES2Util::GetChannelsForFormat(
              framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
                                                                        1.0f);
-    glColorMask(true, true, true, true);
+    state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
     clear_bits |= GL_COLOR_BUFFER_BIT;
   }
 
@@ -5043,11 +5030,11 @@
   if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
       framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
     glClearDepth(1.0f);
-    glDepthMask(true);
+    state_.SetDeviceDepthMask(GL_TRUE);
     clear_bits |= GL_DEPTH_BUFFER_BIT;
   }
 
-  glDisable(GL_SCISSOR_TEST);
+  state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
   glClear(clear_bits);
 
   framebuffer_manager()->MarkAttachmentsAsCleared(
@@ -5073,7 +5060,7 @@
   glClearStencil(state_.stencil_clear);
   glClearDepth(state_.depth_clear);
   if (state_.enable_flags.scissor_test) {
-    glEnable(GL_SCISSOR_TEST);
+    state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
   }
 }
 
@@ -5250,10 +5237,11 @@
     return;
   }
 
-  glDisable(GL_SCISSOR_TEST);
+  state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
   BlitFramebufferHelper(
       srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-  EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
+  state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
+                                  state_.enable_flags.scissor_test);
 }
 
 void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
@@ -5492,11 +5480,11 @@
   GLboolean scissor_enabled = false;
   glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
   if (scissor_enabled)
-    glDisable(GL_SCISSOR_TEST);
+    state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
 
-  GLboolean color_mask[4] = {true, true, true, true};
+  GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
   glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
-  glColorMask(true, true, true, true);
+  state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 
   GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
   glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
@@ -5525,9 +5513,10 @@
 
   // Restore cached state.
   if (scissor_enabled)
-    glEnable(GL_SCISSOR_TEST);
+    state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
 
-  glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
+  state_.SetDeviceColorMask(
+      color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
   glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
   glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
   glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
@@ -7632,7 +7621,7 @@
   if (!name) {
     return error::kOutOfBounds;
   }
-  String name_str(name, name_size);
+  std::string name_str(name, name_size);
   return GetAttribLocationHelper(
     c.program, c.location_shm_id, c.location_shm_offset, name_str);
 }
@@ -7691,7 +7680,7 @@
   if (!name) {
     return error::kOutOfBounds;
   }
-  String name_str(name, name_size);
+  std::string name_str(name, name_size);
   return GetUniformLocationHelper(
     c.program, c.location_shm_id, c.location_shm_offset, name_str);
 }
@@ -7843,8 +7832,8 @@
     glClearStencil(0);
     glStencilMask(-1);
     glClearDepth(1.0f);
-    glDepthMask(true);
-    glDisable(GL_SCISSOR_TEST);
+    state_.SetDeviceDepthMask(GL_TRUE);
+    state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
     glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
 
     RestoreClearState();
@@ -9170,8 +9159,8 @@
           ScopedFrameBufferBinder binder(this,
                                          offscreen_saved_frame_buffer_->id());
           glClearColor(0, 0, 0, 0);
-          glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-          glDisable(GL_SCISSOR_TEST);
+          state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+          state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
           glClear(GL_COLOR_BUFFER_BIT);
           RestoreClearState();
         }
@@ -9695,14 +9684,14 @@
   if (!features().native_vertex_array_object) {
     // Emulated VAO
     for (GLsizei ii = 0; ii < n; ++ii) {
-      CreateVertexAttribManager(client_ids[ii], 0, true);
+      CreateVertexAttribManager(client_ids[ii], 0);
     }
   } else {
     scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
 
     glGenVertexArraysOES(n, service_ids.get());
     for (GLsizei ii = 0; ii < n; ++ii) {
-      CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
+      CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
     }
   }
 
@@ -9725,6 +9714,7 @@
 
 void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
   VertexAttribManager* vao = NULL;
+  GLuint service_id = 0;
   if (client_id != 0) {
     vao = GetVertexAttribManager(client_id);
     if (!vao) {
@@ -9736,6 +9726,8 @@
           "glBindVertexArrayOES", "bad vertex array id.");
       current_decoder_error_ = error::kNoError;
       return;
+    } else {
+      service_id = vao->service_id();
     }
   } else {
     vao = state_.default_vertex_attrib_manager.get();
@@ -9747,7 +9739,6 @@
     if (!features().native_vertex_array_object) {
       EmulateVertexArrayState();
     } else {
-      GLuint service_id = vao->service_id();
       glBindVertexArrayOES(service_id);
     }
   }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index c573b23..ad06a6e 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -152,6 +152,8 @@
   virtual void ClearAllAttributes() const = 0;
   virtual void RestoreAllAttributes() const = 0;
 
+  virtual void SetIgnoreCachedStateForTest(bool ignore) = 0;
+
   // Gets the QueryManager for this context.
   virtual QueryManager* GetQueryManager() = 0;
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index c94c0bf..6220afc 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -13,7 +13,7 @@
 #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_
 
 error::Error GLES2DecoderImpl::HandleActiveTexture(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ActiveTexture& c) {
   GLenum texture = static_cast<GLenum>(c.texture);
   DoActiveTexture(texture);
@@ -21,7 +21,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleAttachShader(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::AttachShader& c) {
   GLuint program = c.program;
   GLuint shader = c.shader;
@@ -30,7 +30,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBindBuffer(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BindBuffer& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLuint buffer = c.buffer;
@@ -43,7 +43,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBindFramebuffer(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BindFramebuffer& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLuint framebuffer = c.framebuffer;
@@ -56,7 +56,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBindRenderbuffer(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BindRenderbuffer& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLuint renderbuffer = c.renderbuffer;
@@ -69,7 +69,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBindTexture(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BindTexture& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLuint texture = c.texture;
@@ -82,7 +82,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBlendColor(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BlendColor& c) {
   GLclampf red = static_cast<GLclampf>(c.red);
   GLclampf green = static_cast<GLclampf>(c.green);
@@ -100,7 +100,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBlendEquation(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BlendEquation& c) {
   GLenum mode = static_cast<GLenum>(c.mode);
   if (!validators_->equation.IsValid(mode)) {
@@ -117,7 +117,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBlendEquationSeparate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BlendEquationSeparate& c) {
   GLenum modeRGB = static_cast<GLenum>(c.modeRGB);
   GLenum modeAlpha = static_cast<GLenum>(c.modeAlpha);
@@ -141,7 +141,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBlendFunc(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BlendFunc& c) {
   GLenum sfactor = static_cast<GLenum>(c.sfactor);
   GLenum dfactor = static_cast<GLenum>(c.dfactor);
@@ -166,7 +166,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBlendFuncSeparate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BlendFuncSeparate& c) {
   GLenum srcRGB = static_cast<GLenum>(c.srcRGB);
   GLenum dstRGB = static_cast<GLenum>(c.dstRGB);
@@ -203,12 +203,12 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBufferSubData(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BufferSubData& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLintptr offset = static_cast<GLintptr>(c.offset);
   GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
-  uint32 data_size = size;
+  uint32_t data_size = size;
   const void* data = GetSharedMemoryAs<const void*>(
       c.data_shm_id, c.data_shm_offset, data_size);
   if (!validators_->buffer_target.IsValid(target)) {
@@ -227,7 +227,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleCheckFramebufferStatus(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::CheckFramebufferStatus& c) {
   GLenum target = static_cast<GLenum>(c.target);
   typedef cmds::CheckFramebufferStatus::Result Result;
@@ -245,7 +245,7 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleClear(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleClear(uint32_t immediate_data_size,
                                            const gles2::cmds::Clear& c) {
   error::Error error;
   error = WillAccessBoundFramebufferForDraw();
@@ -257,7 +257,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleClearColor(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ClearColor& c) {
   GLclampf red = static_cast<GLclampf>(c.red);
   GLclampf green = static_cast<GLclampf>(c.green);
@@ -275,7 +275,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleClearDepthf(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ClearDepthf& c) {
   GLclampf depth = static_cast<GLclampf>(c.depth);
   if (state_.depth_clear != depth) {
@@ -286,7 +286,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleClearStencil(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ClearStencil& c) {
   GLint s = static_cast<GLint>(c.s);
   if (state_.stencil_clear != s) {
@@ -297,7 +297,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleColorMask(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ColorMask& c) {
   GLboolean red = static_cast<GLboolean>(c.red);
   GLboolean green = static_cast<GLboolean>(c.green);
@@ -315,7 +315,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleCompileShader(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::CompileShader& c) {
   GLuint shader = c.shader;
   DoCompileShader(shader);
@@ -323,7 +323,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2D(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::CompressedTexSubImage2D& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLint level = static_cast<GLint>(c.level);
@@ -333,7 +333,7 @@
   GLsizei height = static_cast<GLsizei>(c.height);
   GLenum format = static_cast<GLenum>(c.format);
   GLsizei imageSize = static_cast<GLsizei>(c.imageSize);
-  uint32 data_size = imageSize;
+  uint32_t data_size = imageSize;
   const void* data = GetSharedMemoryAs<const void*>(
       c.data_shm_id, c.data_shm_offset, data_size);
   if (!validators_->texture_target.IsValid(target)) {
@@ -370,7 +370,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleCopyTexImage2D(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::CopyTexImage2D& c) {
   error::Error error;
   error = WillAccessBoundFramebufferForRead();
@@ -411,7 +411,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleCopyTexSubImage2D(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::CopyTexSubImage2D& c) {
   error::Error error;
   error = WillAccessBoundFramebufferForRead();
@@ -442,9 +442,9 @@
 }
 
 error::Error GLES2DecoderImpl::HandleCreateProgram(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::CreateProgram& c) {
-  uint32 client_id = c.client_id;
+  uint32_t client_id = c.client_id;
   if (!CreateProgramHelper(client_id)) {
     return error::kInvalidArguments;
   }
@@ -452,21 +452,21 @@
 }
 
 error::Error GLES2DecoderImpl::HandleCreateShader(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::CreateShader& c) {
   GLenum type = static_cast<GLenum>(c.type);
   if (!validators_->shader_type.IsValid(type)) {
     LOCAL_SET_GL_ERROR_INVALID_ENUM("glCreateShader", type, "type");
     return error::kNoError;
   }
-  uint32 client_id = c.client_id;
+  uint32_t client_id = c.client_id;
   if (!CreateShaderHelper(type, client_id)) {
     return error::kInvalidArguments;
   }
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleCullFace(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleCullFace(uint32_t immediate_data_size,
                                               const gles2::cmds::CullFace& c) {
   GLenum mode = static_cast<GLenum>(c.mode);
   if (!validators_->face_type.IsValid(mode)) {
@@ -481,10 +481,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteBuffers(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteBuffers& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -498,10 +498,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteBuffersImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteBuffersImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -515,10 +515,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteFramebuffers(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteFramebuffers& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -532,10 +532,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteFramebuffersImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteFramebuffersImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -549,10 +549,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteRenderbuffers(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteRenderbuffers& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -566,10 +566,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteRenderbuffersImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteRenderbuffersImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -583,10 +583,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteTextures(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteTextures& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -600,10 +600,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteTexturesImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteTexturesImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -617,7 +617,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDepthFunc(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DepthFunc& c) {
   GLenum func = static_cast<GLenum>(c.func);
   if (!validators_->cmp_function.IsValid(func)) {
@@ -632,7 +632,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDepthMask(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DepthMask& c) {
   GLboolean flag = static_cast<GLboolean>(c.flag);
   if (state_.depth_mask != flag) {
@@ -643,7 +643,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDepthRangef(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DepthRangef& c) {
   GLclampf zNear = static_cast<GLclampf>(c.zNear);
   GLclampf zFar = static_cast<GLclampf>(c.zFar);
@@ -652,7 +652,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDetachShader(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DetachShader& c) {
   GLuint program = c.program;
   GLuint shader = c.shader;
@@ -660,7 +660,7 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleDisable(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleDisable(uint32_t immediate_data_size,
                                              const gles2::cmds::Disable& c) {
   GLenum cap = static_cast<GLenum>(c.cap);
   if (!validators_->capability.IsValid(cap)) {
@@ -672,14 +672,14 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDisableVertexAttribArray(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DisableVertexAttribArray& c) {
   GLuint index = static_cast<GLuint>(c.index);
   DoDisableVertexAttribArray(index);
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleEnable(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleEnable(uint32_t immediate_data_size,
                                             const gles2::cmds::Enable& c) {
   GLenum cap = static_cast<GLenum>(c.cap);
   if (!validators_->capability.IsValid(cap)) {
@@ -691,14 +691,14 @@
 }
 
 error::Error GLES2DecoderImpl::HandleEnableVertexAttribArray(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::EnableVertexAttribArray& c) {
   GLuint index = static_cast<GLuint>(c.index);
   DoEnableVertexAttribArray(index);
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleFinish(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleFinish(uint32_t immediate_data_size,
                                             const gles2::cmds::Finish& c) {
   error::Error error;
   error = WillAccessBoundFramebufferForRead();
@@ -708,14 +708,14 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleFlush(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleFlush(uint32_t immediate_data_size,
                                            const gles2::cmds::Flush& c) {
   DoFlush();
   return error::kNoError;
 }
 
 error::Error GLES2DecoderImpl::HandleFramebufferRenderbuffer(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::FramebufferRenderbuffer& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum attachment = static_cast<GLenum>(c.attachment);
@@ -742,7 +742,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleFramebufferTexture2D(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::FramebufferTexture2D& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum attachment = static_cast<GLenum>(c.attachment);
@@ -773,7 +773,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleFrontFace(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::FrontFace& c) {
   GLenum mode = static_cast<GLenum>(c.mode);
   if (!validators_->face_mode.IsValid(mode)) {
@@ -788,10 +788,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenBuffers(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenBuffers& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -807,10 +807,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenBuffersImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenBuffersImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -826,7 +826,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenerateMipmap(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenerateMipmap& c) {
   GLenum target = static_cast<GLenum>(c.target);
   if (!validators_->texture_bind_target.IsValid(target)) {
@@ -838,10 +838,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenFramebuffers(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenFramebuffers& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -857,10 +857,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenFramebuffersImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenFramebuffersImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -876,10 +876,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenRenderbuffers(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenRenderbuffers& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -895,10 +895,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenRenderbuffersImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenRenderbuffersImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -914,10 +914,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenTextures(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenTextures& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -933,10 +933,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenTexturesImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenTexturesImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -952,7 +952,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetBooleanv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetBooleanv& c) {
   GLenum pname = static_cast<GLenum>(c.pname);
   typedef cmds::GetBooleanv::Result Result;
@@ -984,7 +984,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetBufferParameteriv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetBufferParameteriv& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum pname = static_cast<GLenum>(c.pname);
@@ -1013,7 +1013,7 @@
   result->SetNumResults(num_values);
   return error::kNoError;
 }
-error::Error GLES2DecoderImpl::HandleGetError(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleGetError(uint32_t immediate_data_size,
                                               const gles2::cmds::GetError& c) {
   typedef cmds::GetError::Result Result;
   Result* result_dst = GetSharedMemoryAs<Result*>(
@@ -1026,7 +1026,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetFloatv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetFloatv& c) {
   GLenum pname = static_cast<GLenum>(c.pname);
   typedef cmds::GetFloatv::Result Result;
@@ -1058,7 +1058,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetFramebufferAttachmentParameteriv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetFramebufferAttachmentParameteriv& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum attachment = static_cast<GLenum>(c.attachment);
@@ -1103,7 +1103,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetIntegerv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetIntegerv& c) {
   GLenum pname = static_cast<GLenum>(c.pname);
   typedef cmds::GetIntegerv::Result Result;
@@ -1135,7 +1135,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetProgramiv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetProgramiv& c) {
   GLuint program = c.program;
   GLenum pname = static_cast<GLenum>(c.pname);
@@ -1168,7 +1168,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetRenderbufferParameteriv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetRenderbufferParameteriv& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum pname = static_cast<GLenum>(c.pname);
@@ -1207,7 +1207,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetShaderiv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetShaderiv& c) {
   GLuint shader = c.shader;
   GLenum pname = static_cast<GLenum>(c.pname);
@@ -1240,7 +1240,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetTexParameterfv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetTexParameterfv& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum pname = static_cast<GLenum>(c.pname);
@@ -1277,7 +1277,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetTexParameteriv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetTexParameteriv& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum pname = static_cast<GLenum>(c.pname);
@@ -1314,7 +1314,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetVertexAttribfv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetVertexAttribfv& c) {
   GLuint index = static_cast<GLuint>(c.index);
   GLenum pname = static_cast<GLenum>(c.pname);
@@ -1347,7 +1347,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetVertexAttribiv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetVertexAttribiv& c) {
   GLuint index = static_cast<GLuint>(c.index);
   GLenum pname = static_cast<GLenum>(c.pname);
@@ -1379,7 +1379,7 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleHint(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleHint(uint32_t immediate_data_size,
                                           const gles2::cmds::Hint& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum mode = static_cast<GLenum>(c.mode);
@@ -1410,7 +1410,7 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleIsBuffer(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleIsBuffer(uint32_t immediate_data_size,
                                               const gles2::cmds::IsBuffer& c) {
   GLuint buffer = c.buffer;
   typedef cmds::IsBuffer::Result Result;
@@ -1424,7 +1424,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleIsEnabled(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::IsEnabled& c) {
   GLenum cap = static_cast<GLenum>(c.cap);
   typedef cmds::IsEnabled::Result Result;
@@ -1442,7 +1442,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleIsFramebuffer(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::IsFramebuffer& c) {
   GLuint framebuffer = c.framebuffer;
   typedef cmds::IsFramebuffer::Result Result;
@@ -1456,7 +1456,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleIsProgram(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::IsProgram& c) {
   GLuint program = c.program;
   typedef cmds::IsProgram::Result Result;
@@ -1470,7 +1470,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleIsRenderbuffer(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::IsRenderbuffer& c) {
   GLuint renderbuffer = c.renderbuffer;
   typedef cmds::IsRenderbuffer::Result Result;
@@ -1483,7 +1483,7 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleIsShader(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleIsShader(uint32_t immediate_data_size,
                                               const gles2::cmds::IsShader& c) {
   GLuint shader = c.shader;
   typedef cmds::IsShader::Result Result;
@@ -1497,7 +1497,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleIsTexture(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::IsTexture& c) {
   GLuint texture = c.texture;
   typedef cmds::IsTexture::Result Result;
@@ -1511,7 +1511,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleLineWidth(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::LineWidth& c) {
   GLfloat width = static_cast<GLfloat>(c.width);
   if (width <= 0.0f) {
@@ -1526,7 +1526,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleLinkProgram(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::LinkProgram& c) {
   GLuint program = c.program;
   DoLinkProgram(program);
@@ -1534,7 +1534,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandlePolygonOffset(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::PolygonOffset& c) {
   GLfloat factor = static_cast<GLfloat>(c.factor);
   GLfloat units = static_cast<GLfloat>(c.units);
@@ -1548,14 +1548,14 @@
 }
 
 error::Error GLES2DecoderImpl::HandleReleaseShaderCompiler(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ReleaseShaderCompiler& c) {
   DoReleaseShaderCompiler();
   return error::kNoError;
 }
 
 error::Error GLES2DecoderImpl::HandleRenderbufferStorage(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::RenderbufferStorage& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum internalformat = static_cast<GLenum>(c.internalformat);
@@ -1583,7 +1583,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleSampleCoverage(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::SampleCoverage& c) {
   GLclampf value = static_cast<GLclampf>(c.value);
   GLboolean invert = static_cast<GLboolean>(c.invert);
@@ -1591,7 +1591,7 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleScissor(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleScissor(uint32_t immediate_data_size,
                                              const gles2::cmds::Scissor& c) {
   GLint x = static_cast<GLint>(c.x);
   GLint y = static_cast<GLint>(c.y);
@@ -1617,7 +1617,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleStencilFunc(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::StencilFunc& c) {
   GLenum func = static_cast<GLenum>(c.func);
   GLint ref = static_cast<GLint>(c.ref);
@@ -1641,7 +1641,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleStencilFuncSeparate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::StencilFuncSeparate& c) {
   GLenum face = static_cast<GLenum>(c.face);
   GLenum func = static_cast<GLenum>(c.func);
@@ -1683,7 +1683,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleStencilMask(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::StencilMask& c) {
   GLuint mask = static_cast<GLuint>(c.mask);
   if (state_.stencil_front_writemask != mask ||
@@ -1696,7 +1696,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleStencilMaskSeparate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::StencilMaskSeparate& c) {
   GLenum face = static_cast<GLenum>(c.face);
   GLuint mask = static_cast<GLuint>(c.mask);
@@ -1724,7 +1724,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleStencilOp(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::StencilOp& c) {
   GLenum fail = static_cast<GLenum>(c.fail);
   GLenum zfail = static_cast<GLenum>(c.zfail);
@@ -1759,7 +1759,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleStencilOpSeparate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::StencilOpSeparate& c) {
   GLenum face = static_cast<GLenum>(c.face);
   GLenum fail = static_cast<GLenum>(c.fail);
@@ -1809,7 +1809,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleTexParameterf(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::TexParameterf& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum pname = static_cast<GLenum>(c.pname);
@@ -1827,11 +1827,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleTexParameterfv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::TexParameterfv& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum pname = static_cast<GLenum>(c.pname);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -1853,11 +1853,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleTexParameterfvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::TexParameterfvImmediate& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum pname = static_cast<GLenum>(c.pname);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -1882,7 +1882,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleTexParameteri(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::TexParameteri& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum pname = static_cast<GLenum>(c.pname);
@@ -1900,11 +1900,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleTexParameteriv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::TexParameteriv& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum pname = static_cast<GLenum>(c.pname);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -1926,11 +1926,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleTexParameterivImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::TexParameterivImmediate& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum pname = static_cast<GLenum>(c.pname);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -1955,7 +1955,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform1f(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform1f& c) {
   GLint location = static_cast<GLint>(c.location);
   GLfloat x = static_cast<GLfloat>(c.x);
@@ -1967,11 +1967,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform1fv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform1fv& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -1985,11 +1985,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform1fvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform1fvImmediate& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2006,7 +2006,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform1i(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform1i& c) {
   GLint location = static_cast<GLint>(c.location);
   GLint x = static_cast<GLint>(c.x);
@@ -2015,11 +2015,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform1iv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform1iv& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLint), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2033,11 +2033,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform1ivImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform1ivImmediate& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLint), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2054,7 +2054,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform2f(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform2f& c) {
   GLint location = static_cast<GLint>(c.location);
   GLfloat x = static_cast<GLfloat>(c.x);
@@ -2067,11 +2067,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform2fv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform2fv& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 2, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2085,11 +2085,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform2fvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform2fvImmediate& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 2, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2106,7 +2106,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform2i(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform2i& c) {
   GLint location = static_cast<GLint>(c.location);
   GLint x = static_cast<GLint>(c.x);
@@ -2119,11 +2119,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform2iv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform2iv& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLint), 2, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2137,11 +2137,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform2ivImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform2ivImmediate& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLint), 2, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2158,7 +2158,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform3f(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform3f& c) {
   GLint location = static_cast<GLint>(c.location);
   GLfloat x = static_cast<GLfloat>(c.x);
@@ -2172,11 +2172,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform3fv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform3fv& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 3, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2190,11 +2190,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform3fvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform3fvImmediate& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 3, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2211,7 +2211,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform3i(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform3i& c) {
   GLint location = static_cast<GLint>(c.location);
   GLint x = static_cast<GLint>(c.x);
@@ -2225,11 +2225,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform3iv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform3iv& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLint), 3, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2243,11 +2243,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform3ivImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform3ivImmediate& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLint), 3, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2264,7 +2264,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform4f(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform4f& c) {
   GLint location = static_cast<GLint>(c.location);
   GLfloat x = static_cast<GLfloat>(c.x);
@@ -2279,11 +2279,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform4fv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform4fv& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2297,11 +2297,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform4fvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform4fvImmediate& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2318,7 +2318,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform4i(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform4i& c) {
   GLint location = static_cast<GLint>(c.location);
   GLint x = static_cast<GLint>(c.x);
@@ -2333,11 +2333,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform4iv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform4iv& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLint), 4, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2351,11 +2351,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniform4ivImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::Uniform4ivImmediate& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLint), 4, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2372,12 +2372,12 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniformMatrix2fv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::UniformMatrix2fv& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
   GLboolean transpose = static_cast<GLboolean>(c.transpose);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2396,12 +2396,12 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniformMatrix2fvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::UniformMatrix2fvImmediate& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
   GLboolean transpose = static_cast<GLboolean>(c.transpose);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 4, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2423,12 +2423,12 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniformMatrix3fv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::UniformMatrix3fv& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
   GLboolean transpose = static_cast<GLboolean>(c.transpose);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 9, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2447,12 +2447,12 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniformMatrix3fvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::UniformMatrix3fvImmediate& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
   GLboolean transpose = static_cast<GLboolean>(c.transpose);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 9, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2474,12 +2474,12 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniformMatrix4fv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::UniformMatrix4fv& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
   GLboolean transpose = static_cast<GLboolean>(c.transpose);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 16, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2498,12 +2498,12 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUniformMatrix4fvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::UniformMatrix4fvImmediate& c) {
   GLint location = static_cast<GLint>(c.location);
   GLsizei count = static_cast<GLsizei>(c.count);
   GLboolean transpose = static_cast<GLboolean>(c.transpose);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLfloat), 16, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2525,7 +2525,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleUseProgram(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::UseProgram& c) {
   GLuint program = c.program;
   DoUseProgram(program);
@@ -2533,7 +2533,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleValidateProgram(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ValidateProgram& c) {
   GLuint program = c.program;
   DoValidateProgram(program);
@@ -2541,7 +2541,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib1f(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib1f& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
   GLfloat x = static_cast<GLfloat>(c.x);
@@ -2550,10 +2550,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib1fv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib1fv& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2567,10 +2567,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib1fvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib1fvImmediate& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2587,7 +2587,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib2f(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib2f& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
   GLfloat x = static_cast<GLfloat>(c.x);
@@ -2597,10 +2597,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib2fv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib2fv& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLfloat), 2, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2614,10 +2614,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib2fvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib2fvImmediate& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLfloat), 2, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2634,7 +2634,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib3f(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib3f& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
   GLfloat x = static_cast<GLfloat>(c.x);
@@ -2645,10 +2645,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib3fv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib3fv& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLfloat), 3, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2662,10 +2662,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib3fvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib3fvImmediate& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLfloat), 3, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2682,7 +2682,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib4f(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib4f& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
   GLfloat x = static_cast<GLfloat>(c.x);
@@ -2694,10 +2694,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib4fv(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib4fv& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2711,10 +2711,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttrib4fvImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::VertexAttrib4fvImmediate& c) {
   GLuint indx = static_cast<GLuint>(c.indx);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2730,7 +2730,7 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleViewport(uint32 immediate_data_size,
+error::Error GLES2DecoderImpl::HandleViewport(uint32_t immediate_data_size,
                                               const gles2::cmds::Viewport& c) {
   GLint x = static_cast<GLint>(c.x);
   GLint y = static_cast<GLint>(c.y);
@@ -2749,7 +2749,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBlitFramebufferCHROMIUM(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BlitFramebufferCHROMIUM& c) {
   error::Error error;
   error = WillAccessBoundFramebufferForDraw();
@@ -2779,7 +2779,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleRenderbufferStorageMultisampleCHROMIUM(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::RenderbufferStorageMultisampleCHROMIUM& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLsizei samples = static_cast<GLsizei>(c.samples);
@@ -2821,7 +2821,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleRenderbufferStorageMultisampleEXT(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::RenderbufferStorageMultisampleEXT& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLsizei samples = static_cast<GLsizei>(c.samples);
@@ -2860,7 +2860,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleFramebufferTexture2DMultisampleEXT(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::FramebufferTexture2DMultisampleEXT& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum attachment = static_cast<GLenum>(c.attachment);
@@ -2901,7 +2901,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleTexStorage2DEXT(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::TexStorage2DEXT& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLsizei levels = static_cast<GLsizei>(c.levels);
@@ -2934,10 +2934,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenQueriesEXT(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenQueriesEXT& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2953,10 +2953,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenQueriesEXTImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenQueriesEXTImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2972,10 +2972,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteQueriesEXT(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteQueriesEXT& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -2989,10 +2989,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteQueriesEXTImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteQueriesEXTImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3006,7 +3006,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleInsertEventMarkerEXT(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::InsertEventMarkerEXT& c) {
   GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
   Bucket* bucket = GetBucket(bucket_id);
@@ -3022,7 +3022,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandlePushGroupMarkerEXT(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::PushGroupMarkerEXT& c) {
   GLuint bucket_id = static_cast<GLuint>(c.bucket_id);
   Bucket* bucket = GetBucket(bucket_id);
@@ -3038,17 +3038,17 @@
 }
 
 error::Error GLES2DecoderImpl::HandlePopGroupMarkerEXT(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::PopGroupMarkerEXT& c) {
   DoPopGroupMarkerEXT();
   return error::kNoError;
 }
 
 error::Error GLES2DecoderImpl::HandleGenVertexArraysOES(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenVertexArraysOES& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3064,10 +3064,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenVertexArraysOESImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GenVertexArraysOESImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3083,10 +3083,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteVertexArraysOES(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteVertexArraysOES& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3100,10 +3100,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteVertexArraysOESImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DeleteVertexArraysOESImmediate& c) {
   GLsizei n = static_cast<GLsizei>(c.n);
-  uint32 data_size;
+  uint32_t data_size;
   if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3117,7 +3117,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleIsVertexArrayOES(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::IsVertexArrayOES& c) {
   GLuint array = c.array;
   typedef cmds::IsVertexArrayOES::Result Result;
@@ -3131,7 +3131,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBindVertexArrayOES(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BindVertexArrayOES& c) {
   GLuint array = c.array;
   DoBindVertexArrayOES(array);
@@ -3139,14 +3139,14 @@
 }
 
 error::Error GLES2DecoderImpl::HandleSwapBuffers(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::SwapBuffers& c) {
   DoSwapBuffers();
   return error::kNoError;
 }
 
 error::Error GLES2DecoderImpl::HandleGetMaxValueInBufferCHROMIUM(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::GetMaxValueInBufferCHROMIUM& c) {
   GLuint buffer_id = c.buffer_id;
   GLsizei count = static_cast<GLsizei>(c.count);
@@ -3173,7 +3173,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleTexImageIOSurface2DCHROMIUM(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::TexImageIOSurface2DCHROMIUM& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLsizei width = static_cast<GLsizei>(c.width);
@@ -3200,7 +3200,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleCopyTextureCHROMIUM(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::CopyTextureCHROMIUM& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLenum source_id = static_cast<GLenum>(c.source_id);
@@ -3225,10 +3225,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleProduceTextureCHROMIUM(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ProduceTextureCHROMIUM& c) {
   GLenum target = static_cast<GLenum>(c.target);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3247,10 +3247,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleProduceTextureCHROMIUMImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ProduceTextureCHROMIUMImmediate& c) {
   GLenum target = static_cast<GLenum>(c.target);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3272,10 +3272,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleConsumeTextureCHROMIUM(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ConsumeTextureCHROMIUM& c) {
   GLenum target = static_cast<GLenum>(c.target);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3294,10 +3294,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleConsumeTextureCHROMIUMImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ConsumeTextureCHROMIUMImmediate& c) {
   GLenum target = static_cast<GLenum>(c.target);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3319,7 +3319,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBindTexImage2DCHROMIUM(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::BindTexImage2DCHROMIUM& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLint imageId = static_cast<GLint>(c.imageId);
@@ -3333,7 +3333,7 @@
 }
 
 error::Error GLES2DecoderImpl::HandleReleaseTexImage2DCHROMIUM(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::ReleaseTexImage2DCHROMIUM& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLint imageId = static_cast<GLint>(c.imageId);
@@ -3347,18 +3347,18 @@
 }
 
 error::Error GLES2DecoderImpl::HandleTraceEndCHROMIUM(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::TraceEndCHROMIUM& c) {
   DoTraceEndCHROMIUM();
   return error::kNoError;
 }
 
 error::Error GLES2DecoderImpl::HandleDiscardFramebufferEXT(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DiscardFramebufferEXT& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3377,11 +3377,11 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDiscardFramebufferEXTImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DiscardFramebufferEXTImmediate& c) {
   GLenum target = static_cast<GLenum>(c.target);
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3403,10 +3403,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDrawBuffersEXT(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DrawBuffersEXT& c) {
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3424,10 +3424,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDrawBuffersEXTImmediate(
-    uint32 immediate_data_size,
+    uint32_t immediate_data_size,
     const gles2::cmds::DrawBuffersEXTImmediate& c) {
   GLsizei count = static_cast<GLsizei>(c.count);
-  uint32 data_size;
+  uint32_t data_size;
   if (!ComputeDataSize(count, sizeof(GLenum), 1, &data_size)) {
     return error::kOutOfBounds;
   }
@@ -3451,37 +3451,71 @@
   switch (cap) {
     case GL_BLEND:
       state_.enable_flags.blend = enabled;
-      return true;
+      if (state_.enable_flags.cached_blend != enabled ||
+          state_.ignore_cached_state) {
+        state_.enable_flags.cached_blend = enabled;
+        return true;
+      }
+      return false;
     case GL_CULL_FACE:
       state_.enable_flags.cull_face = enabled;
-      return true;
+      if (state_.enable_flags.cached_cull_face != enabled ||
+          state_.ignore_cached_state) {
+        state_.enable_flags.cached_cull_face = enabled;
+        return true;
+      }
+      return false;
     case GL_DEPTH_TEST:
-      if (state_.enable_flags.depth_test != enabled) {
-        state_.enable_flags.depth_test = enabled;
+      state_.enable_flags.depth_test = enabled;
+      if (state_.enable_flags.cached_depth_test != enabled ||
+          state_.ignore_cached_state) {
         framebuffer_state_.clear_state_dirty = true;
       }
       return false;
     case GL_DITHER:
       state_.enable_flags.dither = enabled;
-      return true;
+      if (state_.enable_flags.cached_dither != enabled ||
+          state_.ignore_cached_state) {
+        state_.enable_flags.cached_dither = enabled;
+        return true;
+      }
+      return false;
     case GL_POLYGON_OFFSET_FILL:
       state_.enable_flags.polygon_offset_fill = enabled;
-      return true;
+      if (state_.enable_flags.cached_polygon_offset_fill != enabled ||
+          state_.ignore_cached_state) {
+        state_.enable_flags.cached_polygon_offset_fill = enabled;
+        return true;
+      }
+      return false;
     case GL_SAMPLE_ALPHA_TO_COVERAGE:
       state_.enable_flags.sample_alpha_to_coverage = enabled;
-      return true;
+      if (state_.enable_flags.cached_sample_alpha_to_coverage != enabled ||
+          state_.ignore_cached_state) {
+        state_.enable_flags.cached_sample_alpha_to_coverage = enabled;
+        return true;
+      }
+      return false;
     case GL_SAMPLE_COVERAGE:
       state_.enable_flags.sample_coverage = enabled;
-      return true;
+      if (state_.enable_flags.cached_sample_coverage != enabled ||
+          state_.ignore_cached_state) {
+        state_.enable_flags.cached_sample_coverage = enabled;
+        return true;
+      }
+      return false;
     case GL_SCISSOR_TEST:
-      if (state_.enable_flags.scissor_test != enabled) {
-        state_.enable_flags.scissor_test = enabled;
-        framebuffer_state_.clear_state_dirty = true;
+      state_.enable_flags.scissor_test = enabled;
+      if (state_.enable_flags.cached_scissor_test != enabled ||
+          state_.ignore_cached_state) {
+        state_.enable_flags.cached_scissor_test = enabled;
+        return true;
       }
       return false;
     case GL_STENCIL_TEST:
-      if (state_.enable_flags.stencil_test != enabled) {
-        state_.enable_flags.stencil_test = enabled;
+      state_.enable_flags.stencil_test = enabled;
+      if (state_.enable_flags.cached_stencil_test != enabled ||
+          state_.ignore_cached_state) {
         framebuffer_state_.clear_state_dirty = true;
       }
       return false;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
index 8043514..94bf3aa 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -81,6 +81,7 @@
   MOCK_METHOD0(ResetAsyncPixelTransferManagerForTest, void());
   MOCK_METHOD1(SetAsyncPixelTransferManagerForTest,
       void(AsyncPixelTransferManager*));
+  MOCK_METHOD1(SetIgnoreCachedStateForTest, void(bool ignore));
   MOCK_METHOD3(DoCommand, error::Error(unsigned int command,
                                        unsigned int arg_count,
                                        const void* cmd_data));
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index e0bfc2c..f3f9321 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
 
 #include "base/command_line.h"
 #include "base/strings/string_number_conversions.h"
@@ -16,7 +16,7 @@
 #include "gpu/command_buffer/service/context_group.h"
 #include "gpu/command_buffer/service/context_state.h"
 #include "gpu/command_buffer/service/gl_surface_mock.h"
-#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
 #include "gpu/command_buffer/service/image_manager.h"
 #include "gpu/command_buffer/service/mailbox_manager.h"
@@ -39,6 +39,7 @@
 using ::testing::InSequence;
 using ::testing::Invoke;
 using ::testing::MatcherCast;
+using ::testing::Mock;
 using ::testing::Pointee;
 using ::testing::Return;
 using ::testing::SaveArg;
@@ -53,1757 +54,58 @@
 
 using namespace cmds;
 
-class GLES2DecoderTest : public GLES2DecoderTestBase {
- public:
-  GLES2DecoderTest() { }
-
- protected:
-  void CheckReadPixelsOutOfRange(
-      GLint in_read_x, GLint in_read_y,
-      GLsizei in_read_width, GLsizei in_read_height,
-      bool init);
-};
-
-class GLES2DecoderTestWithExtensionsOnGLES2
-    : public GLES2DecoderTest,
-      public ::testing::WithParamInterface<const char*> {
- public:
-  GLES2DecoderTestWithExtensionsOnGLES2() {}
-
-  virtual void SetUp() {
-    InitState init;
-    init.extensions = GetParam();
-    init.gl_version = "opengl es 2.0";
-    init.has_alpha = true;
-    init.has_depth = true;
-    init.request_alpha = true;
-    init.request_depth = true;
-    InitDecoder(init);
-  }
-};
-
-class GLES2DecoderWithShaderTest : public GLES2DecoderWithShaderTestBase {
- public:
-  GLES2DecoderWithShaderTest()
-      : GLES2DecoderWithShaderTestBase() {
-  }
-
-  void CheckTextureChangesMarkFBOAsNotComplete(bool bound_fbo);
-  void CheckRenderbufferChangesMarkFBOAsNotComplete(bool bound_fbo);
-};
-
-class GLES2DecoderGeometryInstancingTest : public GLES2DecoderWithShaderTest {
- public:
-  GLES2DecoderGeometryInstancingTest()
-      : GLES2DecoderWithShaderTest() {
-  }
-
-  virtual void SetUp() {
-    InitState init;
-    init.extensions = "GL_ANGLE_instanced_arrays";
-    init.gl_version = "opengl es 2.0";
-    init.has_alpha = true;
-    init.has_depth = true;
-    init.request_alpha = true;
-    init.request_depth = true;
-    init.bind_generates_resource = true;
-    InitDecoder(init);
-    SetupDefaultProgram();
-  }
-};
-
-class GLES2DecoderRGBBackbufferTest : public GLES2DecoderWithShaderTest {
- public:
-  GLES2DecoderRGBBackbufferTest() { }
-
-  virtual void SetUp() {
-    // Test codepath with workaround clear_alpha_in_readpixels because
-    // ReadPixelsEmulator emulates the incorrect driver behavior.
-    CommandLine command_line(0, NULL);
-    command_line.AppendSwitchASCII(
-        switches::kGpuDriverBugWorkarounds,
-        base::IntToString(gpu::CLEAR_ALPHA_IN_READPIXELS));
-    InitState init;
-    init.gl_version = "3.0";
-    init.bind_generates_resource = true;
-    InitDecoderWithCommandLine(init, &command_line);
-    SetupDefaultProgram();
-  }
-};
-
-class GLES2DecoderManualInitTest : public GLES2DecoderWithShaderTest {
- public:
-  GLES2DecoderManualInitTest() { }
-
-  // Override default setup so nothing gets setup.
-  virtual void SetUp() {
-  }
-};
-
-class GLES2DecoderCompressedFormatsTest : public GLES2DecoderManualInitTest {
- public:
-  GLES2DecoderCompressedFormatsTest() { }
-
-  static bool ValueInArray(GLint value, GLint* array, GLint count) {
-    for (GLint ii = 0; ii < count; ++ii) {
-      if (array[ii] == value) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  void CheckFormats(const char* extension, const GLenum* formats, int count) {
-    InitState init;
-    init.extensions = extension;
-    init.gl_version = "3.0";
-    init.bind_generates_resource = true;
-    InitDecoder(init);
-
-    EXPECT_CALL(*gl_, GetError())
-        .WillOnce(Return(GL_NO_ERROR))
-        .WillOnce(Return(GL_NO_ERROR))
-        .WillOnce(Return(GL_NO_ERROR))
-        .WillOnce(Return(GL_NO_ERROR))
-        .RetiresOnSaturation();
-
-    typedef GetIntegerv::Result Result;
-    Result* result = static_cast<Result*>(shared_memory_address_);
-    GetIntegerv cmd;
-    result->size = 0;
-    EXPECT_CALL(*gl_, GetIntegerv(_, _))
-        .Times(0)
-        .RetiresOnSaturation();
-    cmd.Init(
-        GL_NUM_COMPRESSED_TEXTURE_FORMATS,
-        shared_memory_id_, shared_memory_offset_);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_EQ(1, result->GetNumResults());
-    GLint num_formats = result->GetData()[0];
-    EXPECT_EQ(count, num_formats);
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    result->size = 0;
-    cmd.Init(
-        GL_COMPRESSED_TEXTURE_FORMATS,
-        shared_memory_id_, shared_memory_offset_);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_EQ(num_formats, result->GetNumResults());
-
-    for (int i = 0; i < count; ++i) {
-      EXPECT_TRUE(ValueInArray(
-        formats[i],
-        result->GetData(), result->GetNumResults()));
-    }
-
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  }
-};
-
-class GLES2DecoderRestoreStateTest : public GLES2DecoderManualInitTest {
- public:
-  GLES2DecoderRestoreStateTest() { }
-
- protected:
-  void AddExpectationsForActiveTexture(GLenum unit);
-  void AddExpectationsForBindTexture(GLenum target, GLuint id);
-  void InitializeContextState(
-      ContextState* state, uint32 non_default_unit, uint32 active_unit);
-};
-
-void GLES2DecoderRestoreStateTest::AddExpectationsForActiveTexture(
-    GLenum unit) {
-  EXPECT_CALL(*gl_, ActiveTexture(unit))
-      .Times(1)
-      .RetiresOnSaturation();
-}
-
-void GLES2DecoderRestoreStateTest::AddExpectationsForBindTexture(GLenum target,
-                                                                 GLuint id) {
-  EXPECT_CALL(*gl_, BindTexture(target, id))
-      .Times(1)
-      .RetiresOnSaturation();
-}
-
-void GLES2DecoderRestoreStateTest::InitializeContextState(
-    ContextState* state, uint32 non_default_unit, uint32 active_unit) {
-  state->texture_units.resize(group().max_texture_units());
-  for (uint32 tt = 0; tt < state->texture_units.size(); ++tt) {
-    TextureRef* ref_cube_map =
-        group().texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
-    state->texture_units[tt].bound_texture_cube_map = ref_cube_map;
-    TextureRef* ref_2d =
-        (tt == non_default_unit)
-            ? group().texture_manager()->GetTexture(client_texture_id_)
-            : group().texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
-    state->texture_units[tt].bound_texture_2d = ref_2d;
-  }
-  state->active_texture_unit = active_unit;
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysNoAttributesSucceeds) {
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDefaultDirtyState();
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-// Tests when the math overflows (0x40000000 * sizeof GLfloat)
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysSimulatedAttrib0OverflowFails) {
-  const GLsizei kLargeCount = 0x40000000;
-  SetupTexture();
-  EXPECT_CALL(*gl_, DrawArrays(_, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kLargeCount);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-  EXPECT_FALSE(GetDecoder()->WasContextLost());
-}
-
-// Tests when the math overflows (0x7FFFFFFF + 1 = 0x8000000 verts)
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysSimulatedAttrib0PosToNegFails) {
-  const GLsizei kLargeCount = 0x7FFFFFFF;
-  SetupTexture();
-  EXPECT_CALL(*gl_, DrawArrays(_, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kLargeCount);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-  EXPECT_FALSE(GetDecoder()->WasContextLost());
-}
-
-// Tests when the driver returns an error
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysSimulatedAttrib0OOMFails) {
-  const GLsizei kFakeLargeCount = 0x1234;
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0WithError(
-      kFakeLargeCount, 0, GL_OUT_OF_MEMORY);
-  EXPECT_CALL(*gl_, DrawArrays(_, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kFakeLargeCount);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-  EXPECT_FALSE(GetDecoder()->WasContextLost());
-}
-
-// Test that we lose context.
-TEST_F(GLES2DecoderManualInitTest, LoseContextWhenOOM) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_alpha = true;
-  init.has_depth = true;
-  init.request_alpha = true;
-  init.request_depth = true;
-  init.bind_generates_resource = true;
-  init.lose_context_when_out_of_memory = true;
-  InitDecoder(init);
-  SetupDefaultProgram();
-
-  const GLsizei kFakeLargeCount = 0x1234;
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0WithError(
-      kFakeLargeCount, 0, GL_OUT_OF_MEMORY);
-  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0).RetiresOnSaturation();
-  // Other contexts in the group should be lost also.
-  EXPECT_CALL(*mock_decoder_, LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kFakeLargeCount);
-  // This context should be lost.
-  EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-  EXPECT_TRUE(decoder_->WasContextLost());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysBadTextureUsesBlack) {
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  // This is an NPOT texture. As the default filtering requires mips
-  // this should trigger replacing with black textures before rendering.
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               kSharedMemoryId, kSharedMemoryOffset);
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  {
-    InSequence sequence;
-    EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
-        .Times(1)
-        .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, BindTexture(
-        GL_TEXTURE_2D, TestHelper::kServiceBlackTexture2dId))
-        .Times(1)
-        .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-        .Times(1)
-        .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
-        .Times(1)
-        .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
-        .Times(1)
-        .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
-        .Times(1)
-        .RetiresOnSaturation();
-  }
-  SetupExpectationsForApplyingDefaultDirtyState();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysMissingAttributesFails) {
-  DoEnableVertexAttribArray(1);
-
-  EXPECT_CALL(*gl_, DrawArrays(_, _, _))
-      .Times(0);
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest,
-       DrawArraysMissingAttributesZeroCountSucceeds) {
-  DoEnableVertexAttribArray(1);
-
-  EXPECT_CALL(*gl_, DrawArrays(_, _, _))
-      .Times(0);
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, 0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysValidAttributesSucceeds) {
-  SetupTexture();
-  SetupVertexBuffer();
-  DoEnableVertexAttribArray(1);
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-  AddExpectationsForSimulatedAttrib0(kNumVertices, kServiceBufferId);
-  SetupExpectationsForApplyingDefaultDirtyState();
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-// Same as DrawArraysValidAttributesSucceeds, but with workaround
-// |init_vertex_attributes|.
-TEST_F(GLES2DecoderManualInitTest, InitVertexAttributes) {
+void GLES2DecoderRGBBackbufferTest::SetUp() {
+  // Test codepath with workaround clear_alpha_in_readpixels because
+  // ReadPixelsEmulator emulates the incorrect driver behavior.
   CommandLine command_line(0, NULL);
   command_line.AppendSwitchASCII(
       switches::kGpuDriverBugWorkarounds,
-      base::IntToString(gpu::INIT_VERTEX_ATTRIBUTES));
+      base::IntToString(gpu::CLEAR_ALPHA_IN_READPIXELS));
   InitState init;
   init.gl_version = "3.0";
-  init.has_alpha = true;
-  init.has_depth = true;
-  init.request_alpha = true;
-  init.request_depth = true;
   init.bind_generates_resource = true;
   InitDecoderWithCommandLine(init, &command_line);
   SetupDefaultProgram();
-  SetupTexture();
-  SetupVertexBuffer();
-  DoEnableVertexAttribArray(1);
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-  AddExpectationsForSimulatedAttrib0(kNumVertices, kServiceBufferId);
-  SetupExpectationsForApplyingDefaultDirtyState();
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysDeletedBufferFails) {
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-  DeleteVertexBuffer();
-
-  EXPECT_CALL(*gl_, DrawArrays(_, _, _))
-      .Times(0);
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+// Override default setup so nothing gets setup.
+void GLES2DecoderManualInitTest::SetUp() {
 }
 
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysDeletedProgramSucceeds) {
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDefaultDirtyState();
-  DoDeleteProgram(client_program_id_, kServiceProgramId);
-
-  EXPECT_CALL(*gl_, DrawArrays(_, _, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
-      .Times(1);
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+void GLES2DecoderManualInitTest::EnableDisableTest(GLenum cap,
+                                                   bool enable,
+                                                   bool expect_set) {
+  if (expect_set) {
+    SetupExpectationsForEnableDisable(cap, enable);
+  }
+  if (enable) {
+    Enable cmd;
+    cmd.Init(cap);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  } else {
+    Disable cmd;
+    cmd.Init(cap);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  }
 }
 
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysWithInvalidModeFails) {
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  EXPECT_CALL(*gl_, DrawArrays(_, _, _))
-      .Times(0);
-  DrawArrays cmd;
-  cmd.Init(GL_QUADS, 0, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-  cmd.Init(GL_POLYGON, 0, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysInvalidCountFails) {
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  // Try start > 0
-  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0);
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 1, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Try with count > size
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices + 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Try with attrib offset > 0
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 4);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Try with size > 2 (ie, vec3 instead of vec2)
-  DoVertexAttribPointer(1, 3, GL_FLOAT, 0, 0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Try with stride > 8 (vec2 + vec2 byte)
-  DoVertexAttribPointer(1, 2, GL_FLOAT, sizeof(GLfloat) * 3, 0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysInstancedANGLEFails) {
-  SetupTexture();
-  SetupVertexBuffer();
-  DoEnableVertexAttribArray(1);
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawArraysInstancedANGLENoAttributesFails) {
-  SetupTexture();
-
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawArraysInstancedANGLESimulatedAttrib0) {
-  SetupTexture();
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  AddExpectationsForSimulatedAttrib0(kNumVertices, kServiceBufferId);
-  SetupExpectationsForApplyingDefaultDirtyState();
-
-  DoVertexAttribDivisorANGLE(0, 1);
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices, 3))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 0))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 1))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 3);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawArraysInstancedANGLEMissingAttributesFails) {
-  DoEnableVertexAttribArray(1);
-
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
-      .Times(0);
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawArraysInstancedANGLEMissingAttributesZeroCountSucceeds) {
-  DoEnableVertexAttribArray(1);
-
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
-      .Times(0);
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, 0, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawArraysInstancedANGLEValidAttributesSucceeds) {
-  SetupTexture();
-  SetupVertexBuffer();
-  DoEnableVertexAttribArray(1);
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-  AddExpectationsForSimulatedAttrib0(kNumVertices, kServiceBufferId);
-  SetupExpectationsForApplyingDefaultDirtyState();
-
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices, 1))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawArraysInstancedANGLEWithInvalidModeFails) {
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
-      .Times(0);
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_QUADS, 0, 1, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-  cmd.Init(GL_POLYGON, 0, 1, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawArraysInstancedANGLEInvalidPrimcountFails) {
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
-      .Times(0);
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, 1, -1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-// Per-instance data is twice as large, but number of instances is half
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawArraysInstancedANGLELargeInstanceSucceeds) {
-  SetupTexture();
-  SetupVertexBuffer();
-  SetupExpectationsForApplyingDefaultDirtyState();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
-  DoVertexAttribDivisorANGLE(0, 1);
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices,
-                                             kNumVertices / 2))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices, kNumVertices / 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-// Per-instance data is twice as large, but divisor is twice
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawArraysInstancedANGLELargeDivisorSucceeds) {
-  SetupTexture();
-  SetupVertexBuffer();
-  SetupExpectationsForApplyingDefaultDirtyState();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
-  DoVertexAttribDivisorANGLE(0, 2);
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices,
-                                             kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest, DrawArraysInstancedANGLELargeFails) {
-  SetupTexture();
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
-  DoVertexAttribDivisorANGLE(0, 1);
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices, kNumVertices + 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices + 1, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-// Per-index data is twice as large, but number of indices is half
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawArraysInstancedANGLELargeIndexSucceeds) {
-  SetupTexture();
-  SetupVertexBuffer();
-  SetupExpectationsForApplyingDefaultDirtyState();
-  DoVertexAttribPointer(1, 4, GL_FLOAT, 0, 0);
-
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
-  DoVertexAttribDivisorANGLE(0, 1);
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices / 2,
-                                             kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices / 2, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawArraysInstancedANGLENoDivisor0Fails) {
-  SetupTexture();
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
-  DoVertexAttribDivisorANGLE(0, 1);
-  DoVertexAttribDivisorANGLE(1, 1);
-  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawArraysInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsNoAttributesSucceeds) {
-  SetupTexture();
-  SetupIndexBuffer();
-  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, 0);
-  SetupExpectationsForApplyingDefaultDirtyState();
-  EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount,
-                                 GL_UNSIGNED_SHORT,
-                                 BufferOffset(kValidIndexRangeStart * 2)))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsMissingAttributesFails) {
-  SetupIndexBuffer();
-  DoEnableVertexAttribArray(1);
-
-  EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
-      .Times(0);
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest,
-       DrawElementsMissingAttributesZeroCountSucceeds) {
-  SetupIndexBuffer();
-  DoEnableVertexAttribArray(1);
-
-  EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
-      .Times(0);
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsExtraAttributesFails) {
-  SetupIndexBuffer();
-  DoEnableVertexAttribArray(6);
-
-  EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
-      .Times(0);
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsValidAttributesSucceeds) {
-  SetupTexture();
-  SetupVertexBuffer();
-  SetupIndexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, kServiceBufferId);
-  SetupExpectationsForApplyingDefaultDirtyState();
-
-  EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount,
-                                 GL_UNSIGNED_SHORT,
-                                 BufferOffset(kValidIndexRangeStart * 2)))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsDeletedBufferFails) {
-  SetupVertexBuffer();
-  SetupIndexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-  DeleteIndexBuffer();
-
-  EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
-      .Times(0);
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsDeletedProgramSucceeds) {
-  SetupTexture();
-  SetupIndexBuffer();
-  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, 0);
-  SetupExpectationsForApplyingDefaultDirtyState();
-  DoDeleteProgram(client_program_id_, kServiceProgramId);
-
-  EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
-      .Times(1);
-  EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
-      .Times(1);
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsWithInvalidModeFails) {
-  SetupVertexBuffer();
-  SetupIndexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
-      .Times(0);
-  DrawElements cmd;
-  cmd.Init(GL_QUADS, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-  cmd.Init(GL_POLYGON, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsInvalidCountFails) {
-  SetupVertexBuffer();
-  SetupIndexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  // Try start > 0
-  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, kNumIndices, GL_UNSIGNED_SHORT, 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Try with count > size
-  cmd.Init(GL_TRIANGLES, kNumIndices + 1, GL_UNSIGNED_SHORT, 0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsOutOfRangeIndicesFails) {
-  SetupVertexBuffer();
-  SetupIndexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, kInvalidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kInvalidIndexRangeStart * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsOddOffsetForUint16Fails) {
-  SetupVertexBuffer();
-  SetupIndexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, kInvalidIndexRangeCount, GL_UNSIGNED_SHORT, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsInstancedANGLEFails) {
-  SetupTexture();
-  SetupVertexBuffer();
-  SetupIndexBuffer();
-  DoEnableVertexAttribArray(1);
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLENoAttributesFails) {
-  SetupTexture();
-  SetupIndexBuffer();
-
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLESimulatedAttrib0) {
-  SetupTexture();
-  SetupVertexBuffer();
-  SetupIndexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, kServiceBufferId);
-  SetupExpectationsForApplyingDefaultDirtyState();
-
-  DoVertexAttribDivisorANGLE(0, 1);
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(
-                        GL_TRIANGLES,
-                        kValidIndexRangeCount,
-                        GL_UNSIGNED_SHORT,
-                        BufferOffset(kValidIndexRangeStart * 2),
-                        3))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 0))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 1))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, 3);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLEMissingAttributesFails) {
-  SetupIndexBuffer();
-  DoEnableVertexAttribArray(1);
-
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
-      .Times(0);
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLEMissingAttributesZeroCountSucceeds) {
-  SetupIndexBuffer();
-  DoEnableVertexAttribArray(1);
-
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
-      .Times(0);
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLEValidAttributesSucceeds) {
-  SetupIndexBuffer();
-  SetupTexture();
-  SetupVertexBuffer();
-  DoEnableVertexAttribArray(1);
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, kServiceBufferId);
-  SetupExpectationsForApplyingDefaultDirtyState();
-
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(
-                        GL_TRIANGLES,
-                        kValidIndexRangeCount,
-                        GL_UNSIGNED_SHORT,
-                        BufferOffset(kValidIndexRangeStart * 2),
-                        1))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLEWithInvalidModeFails) {
-  SetupIndexBuffer();
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
-      .Times(0);
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_QUADS, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-  cmd.Init(GL_INVALID_ENUM, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-}
-
-// Per-instance data is twice as large, but number of instances is half
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLELargeInstanceSucceeds) {
-  SetupTexture();
-  SetupIndexBuffer();
-  SetupVertexBuffer();
-  SetupExpectationsForApplyingDefaultDirtyState();
-  //Add offset so we're sure we're accessing data near the end of the buffer.
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0,
-                        (kNumVertices - kMaxValidIndex - 1) * 2 *
-                            sizeof(GLfloat));
-
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
-  DoVertexAttribDivisorANGLE(0, 1);
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(
-                        GL_TRIANGLES,
-                        kValidIndexRangeCount,
-                        GL_UNSIGNED_SHORT,
-                        BufferOffset(kValidIndexRangeStart * 2),
-                        kNumVertices / 2))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, kNumVertices / 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-// Per-instance data is twice as large, but divisor is twice
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLELargeDivisorSucceeds) {
-  SetupTexture();
-  SetupIndexBuffer();
-  SetupVertexBuffer();
-  SetupExpectationsForApplyingDefaultDirtyState();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
-  DoVertexAttribDivisorANGLE(0, 2);
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(
-                        GL_TRIANGLES,
-                        kValidIndexRangeCount,
-                        GL_UNSIGNED_SHORT,
-                        BufferOffset(kValidIndexRangeStart * 2),
-                        kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLELargeFails) {
-  SetupTexture();
-  SetupIndexBuffer();
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
-  DoVertexAttribDivisorANGLE(0, 1);
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, kNumVertices + 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  cmd.Init(GL_TRIANGLES, kInvalidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kInvalidIndexRangeStart * 2, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLEInvalidPrimcountFails) {
-  SetupTexture();
-  SetupIndexBuffer();
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
-  DoVertexAttribDivisorANGLE(0, 1);
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, -1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-// Per-index data is twice as large, but values of indices are smaller
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLELargeIndexSucceeds) {
-  SetupTexture();
-  SetupIndexBuffer();
-  SetupVertexBuffer();
-  SetupExpectationsForApplyingDefaultDirtyState();
-  DoVertexAttribPointer(1, 4, GL_FLOAT, 0, 0);
-
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
-  DoVertexAttribDivisorANGLE(0, 1);
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(
-                        GL_TRIANGLES,
-                        kValidIndexRangeCount,
-                        GL_UNSIGNED_SHORT,
-                        BufferOffset(kValidIndexRangeStart * 2),
-                        kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderGeometryInstancingTest,
-       DrawElementsInstancedANGLENoDivisor0Fails) {
-  SetupTexture();
-  SetupIndexBuffer();
-  SetupVertexBuffer();
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
-  DoVertexAttribDivisorANGLE(0, 1);
-  DoVertexAttribDivisorANGLE(1, 1);
-  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawElementsInstancedANGLE cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervSucceeds) {
-  const float dummy = 0;
-  const GLuint kOffsetToTestFor = sizeof(dummy) * 4;
-  const GLuint kIndexToTest = 1;
-  GetVertexAttribPointerv::Result* result =
-      static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_);
-  result->size = 0;
-  const GLuint* result_value = result->GetData();
-  // Test that initial value is 0.
-  GetVertexAttribPointerv cmd;
-  cmd.Init(kIndexToTest, GL_VERTEX_ATTRIB_ARRAY_POINTER,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(sizeof(*result_value), result->size);
-  EXPECT_EQ(0u, *result_value);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Set the value and see that we get it.
-  SetupVertexBuffer();
-  DoVertexAttribPointer(kIndexToTest, 2, GL_FLOAT, 0, kOffsetToTestFor);
-  result->size = 0;
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(sizeof(*result_value), result->size);
-  EXPECT_EQ(kOffsetToTestFor, *result_value);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) {
-  const GLuint kIndexToTest = 1;
-  GetVertexAttribPointerv::Result* result =
-      static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_);
-  result->size = 0;
-  const GLuint* result_value = result->GetData();
-  // Test pname invalid fails.
-  GetVertexAttribPointerv cmd;
-  cmd.Init(kIndexToTest, GL_VERTEX_ATTRIB_ARRAY_POINTER + 1,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0u, result->size);
-  EXPECT_EQ(kInitialResult, *result_value);
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-
-  // Test index out of range fails.
-  result->size = 0;
-  cmd.Init(kNumVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_POINTER,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0u, result->size);
-  EXPECT_EQ(kInitialResult, *result_value);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-
-  // Test memory id bad fails.
-  cmd.Init(kIndexToTest, GL_VERTEX_ATTRIB_ARRAY_POINTER,
-           kInvalidSharedMemoryId, shared_memory_offset_);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-
-  // Test memory offset bad fails.
-  cmd.Init(kIndexToTest, GL_VERTEX_ATTRIB_ARRAY_POINTER,
-           shared_memory_id_, kInvalidSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformivSucceeds) {
-  GetUniformiv::Result* result =
-      static_cast<GetUniformiv::Result*>(shared_memory_address_);
-  result->size = 0;
-  GetUniformiv cmd;
-  cmd.Init(client_program_id_,
-           kUniform2FakeLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, GetUniformiv(kServiceProgramId, kUniform2RealLocation, _))
-      .Times(1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
-            result->size);
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformivArrayElementSucceeds) {
-  GetUniformiv::Result* result =
-      static_cast<GetUniformiv::Result*>(shared_memory_address_);
-  result->size = 0;
-  GetUniformiv cmd;
-  cmd.Init(client_program_id_,
-           kUniform2ElementFakeLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_,
-              GetUniformiv(kServiceProgramId, kUniform2ElementRealLocation, _))
-      .Times(1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
-            result->size);
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) {
-  GetUniformiv::Result* result =
-      static_cast<GetUniformiv::Result*>(shared_memory_address_);
-  result->size = 0;
-  GetUniformiv cmd;
-  // non-existant program
-  cmd.Init(kInvalidClientId,
-           kUniform2FakeLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, GetUniformiv(_, _, _))
-      .Times(0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0U, result->size);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  // Valid id that is not a program. The GL spec requires a different error for
-  // this case.
-#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
-  result->size = kInitialResult;
-  cmd.Init(client_shader_id_,
-           kUniform2FakeLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0U, result->size);
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
-  // Unlinked program
-  EXPECT_CALL(*gl_, CreateProgram())
-      .Times(1)
-      .WillOnce(Return(kNewServiceId))
-      .RetiresOnSaturation();
-  CreateProgram cmd2;
-  cmd2.Init(kNewClientId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  result->size = kInitialResult;
-  cmd.Init(kNewClientId,
-           kUniform2FakeLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0U, result->size);
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadLocationFails) {
-  GetUniformiv::Result* result =
-      static_cast<GetUniformiv::Result*>(shared_memory_address_);
-  result->size = 0;
-  GetUniformiv cmd;
-  // invalid location
-  cmd.Init(client_program_id_, kInvalidUniformLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, GetUniformiv(_, _, _))
-      .Times(0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0U, result->size);
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadSharedMemoryFails) {
-  GetUniformiv cmd;
-  cmd.Init(client_program_id_,
-           kUniform2FakeLocation,
-           kInvalidSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, GetUniformiv(_, _, _))
-      .Times(0);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_program_id_, kUniform2FakeLocation,
-           kSharedMemoryId, kInvalidSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-};
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformfvSucceeds) {
-  GetUniformfv::Result* result =
-      static_cast<GetUniformfv::Result*>(shared_memory_address_);
-  result->size = 0;
-  GetUniformfv cmd;
-  cmd.Init(client_program_id_,
-           kUniform2FakeLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, GetUniformfv(kServiceProgramId, kUniform2RealLocation, _))
-      .Times(1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
-            result->size);
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformfvArrayElementSucceeds) {
-  GetUniformfv::Result* result =
-      static_cast<GetUniformfv::Result*>(shared_memory_address_);
-  result->size = 0;
-  GetUniformfv cmd;
-  cmd.Init(client_program_id_,
-           kUniform2ElementFakeLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_,
-              GetUniformfv(kServiceProgramId, kUniform2ElementRealLocation, _))
-      .Times(1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
-            result->size);
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) {
-  GetUniformfv::Result* result =
-      static_cast<GetUniformfv::Result*>(shared_memory_address_);
-  result->size = 0;
-  GetUniformfv cmd;
-  // non-existant program
-  cmd.Init(kInvalidClientId,
-           kUniform2FakeLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, GetUniformfv(_, _, _))
-      .Times(0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0U, result->size);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  // Valid id that is not a program. The GL spec requires a different error for
-  // this case.
-#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
-  result->size = kInitialResult;
-  cmd.Init(client_shader_id_,
-           kUniform2FakeLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0U, result->size);
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
-  // Unlinked program
-  EXPECT_CALL(*gl_, CreateProgram())
-      .Times(1)
-      .WillOnce(Return(kNewServiceId))
-      .RetiresOnSaturation();
-  CreateProgram cmd2;
-  cmd2.Init(kNewClientId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  result->size = kInitialResult;
-  cmd.Init(kNewClientId,
-           kUniform2FakeLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0U, result->size);
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadLocationFails) {
-  GetUniformfv::Result* result =
-      static_cast<GetUniformfv::Result*>(shared_memory_address_);
-  result->size = 0;
-  GetUniformfv cmd;
-  // invalid location
-  cmd.Init(client_program_id_, kInvalidUniformLocation,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, GetUniformfv(_, _, _))
-      .Times(0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0U, result->size);
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadSharedMemoryFails) {
-  GetUniformfv cmd;
-  cmd.Init(client_program_id_,
-           kUniform2FakeLocation,
-           kInvalidSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, GetUniformfv(_, _, _))
-      .Times(0);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_program_id_, kUniform2FakeLocation,
-           kSharedMemoryId, kInvalidSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-};
-
-TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersSucceeds) {
-  GetAttachedShaders cmd;
-  typedef GetAttachedShaders::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->size = 0;
-  EXPECT_CALL(*gl_, GetAttachedShaders(kServiceProgramId, 1, _, _))
-      .WillOnce(DoAll(SetArgumentPointee<2>(1),
-                      SetArgumentPointee<3>(kServiceShaderId)));
-  cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_,
-           Result::ComputeSize(1));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(1, result->GetNumResults());
-  EXPECT_EQ(client_shader_id_, result->GetData()[0]);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersResultNotInitFail) {
-  GetAttachedShaders cmd;
-  typedef GetAttachedShaders::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->size = 1;
-  EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _))
-      .Times(0);
-  cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_,
-           Result::ComputeSize(1));
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersBadProgramFails) {
-  GetAttachedShaders cmd;
-  typedef GetAttachedShaders::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->size = 0;
-  EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _))
-      .Times(0);
-  cmd.Init(kInvalidClientId, shared_memory_id_, shared_memory_offset_,
-           Result::ComputeSize(1));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0U, result->size);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersBadSharedMemoryFails) {
-  GetAttachedShaders cmd;
-  typedef GetAttachedShaders::Result Result;
-  cmd.Init(client_program_id_, kInvalidSharedMemoryId, shared_memory_offset_,
-           Result::ComputeSize(1));
-  EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _))
-      .Times(0);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_program_id_, shared_memory_id_, kInvalidSharedMemoryOffset,
-           Result::ComputeSize(1));
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatSucceeds) {
-  ScopedGLImplementationSetter gl_impl(::gfx::kGLImplementationEGLGLES2);
-  GetShaderPrecisionFormat cmd;
-  typedef GetShaderPrecisionFormat::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->success = 0;
-  const GLint range[2] = { 62, 62 };
-  const GLint precision = 16;
-  EXPECT_CALL(*gl_,GetShaderPrecisionFormat(_, _, _, _))
-      .WillOnce(DoAll(SetArrayArgument<2>(range,range+2),
-                      SetArgumentPointee<3>(precision)))
-      .RetiresOnSaturation();
-  cmd.Init(GL_VERTEX_SHADER, GL_HIGH_FLOAT,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_NE(0, result->success);
-  EXPECT_EQ(range[0], result->min_range);
-  EXPECT_EQ(range[1], result->max_range);
-  EXPECT_EQ(precision, result->precision);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatResultNotInitFails) {
-  GetShaderPrecisionFormat cmd;
-  typedef GetShaderPrecisionFormat::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->success = 1;
-  // NOTE: GL might not be called. There is no Desktop OpenGL equivalent
-  cmd.Init(GL_VERTEX_SHADER, GL_HIGH_FLOAT,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatBadArgsFails) {
-  typedef GetShaderPrecisionFormat::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->success = 0;
-  GetShaderPrecisionFormat cmd;
-  cmd.Init(GL_TEXTURE_2D, GL_HIGH_FLOAT,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-  result->success = 0;
-  cmd.Init(GL_VERTEX_SHADER, GL_TEXTURE_2D,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest,
-       GetShaderPrecisionFormatBadSharedMemoryFails) {
-  GetShaderPrecisionFormat cmd;
-  cmd.Init(GL_VERTEX_SHADER, GL_HIGH_FLOAT,
-           kInvalidSharedMemoryId, shared_memory_offset_);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(GL_VERTEX_SHADER, GL_TEXTURE_2D,
-           shared_memory_id_, kInvalidSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformSucceeds) {
-  const GLuint kUniformIndex = 1;
-  const uint32 kBucketId = 123;
-  GetActiveUniform cmd;
-  typedef GetActiveUniform::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->success = 0;
-  cmd.Init(client_program_id_, kUniformIndex, kBucketId,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_NE(0, result->success);
-  EXPECT_EQ(kUniform2Size, result->size);
-  EXPECT_EQ(kUniform2Type, result->type);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
-  ASSERT_TRUE(bucket != NULL);
-  EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kUniform2Name,
-                      bucket->size()));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformResultNotInitFails) {
-  const GLuint kUniformIndex = 1;
-  const uint32 kBucketId = 123;
-  GetActiveUniform cmd;
-  typedef GetActiveUniform::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->success = 1;
-  cmd.Init(client_program_id_, kUniformIndex, kBucketId,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformBadProgramFails) {
-  const GLuint kUniformIndex = 1;
-  const uint32 kBucketId = 123;
-  GetActiveUniform cmd;
-  typedef GetActiveUniform::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->success = 0;
-  cmd.Init(kInvalidClientId, kUniformIndex, kBucketId,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0, result->success);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
-  result->success = 0;
-  cmd.Init(client_shader_id_, kUniformIndex, kBucketId,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0, result->success);
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformBadIndexFails) {
-  const uint32 kBucketId = 123;
-  GetActiveUniform cmd;
-  typedef GetActiveUniform::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->success = 0;
-  cmd.Init(client_program_id_, kBadUniformIndex, kBucketId,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0, result->success);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformBadSharedMemoryFails) {
-  const GLuint kUniformIndex = 1;
-  const uint32 kBucketId = 123;
-  GetActiveUniform cmd;
-  cmd.Init(client_program_id_, kUniformIndex, kBucketId,
-           kInvalidSharedMemoryId, shared_memory_offset_);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_program_id_, kUniformIndex, kBucketId,
-           shared_memory_id_, kInvalidSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribSucceeds) {
-  const GLuint kAttribIndex = 1;
-  const uint32 kBucketId = 123;
-  GetActiveAttrib cmd;
-  typedef GetActiveAttrib::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->success = 0;
-  cmd.Init(client_program_id_, kAttribIndex, kBucketId,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_NE(0, result->success);
-  EXPECT_EQ(kAttrib2Size, result->size);
-  EXPECT_EQ(kAttrib2Type, result->type);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
-  ASSERT_TRUE(bucket != NULL);
-  EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kAttrib2Name,
-                      bucket->size()));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribResultNotInitFails) {
-  const GLuint kAttribIndex = 1;
-  const uint32 kBucketId = 123;
-  GetActiveAttrib cmd;
-  typedef GetActiveAttrib::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->success = 1;
-  cmd.Init(client_program_id_, kAttribIndex, kBucketId,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadProgramFails) {
-  const GLuint kAttribIndex = 1;
-  const uint32 kBucketId = 123;
-  GetActiveAttrib cmd;
-  typedef GetActiveAttrib::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->success = 0;
-  cmd.Init(kInvalidClientId, kAttribIndex, kBucketId,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0, result->success);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
-  result->success = 0;
-  cmd.Init(client_shader_id_, kAttribIndex, kBucketId,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0, result->success);
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadIndexFails) {
-  const uint32 kBucketId = 123;
-  GetActiveAttrib cmd;
-  typedef GetActiveAttrib::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->success = 0;
-  cmd.Init(client_program_id_, kBadAttribIndex, kBucketId,
-           shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(0, result->success);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadSharedMemoryFails) {
-  const GLuint kAttribIndex = 1;
-  const uint32 kBucketId = 123;
-  GetActiveAttrib cmd;
-  cmd.Init(client_program_id_, kAttribIndex, kBucketId,
-           kInvalidSharedMemoryId, shared_memory_offset_);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_program_id_, kAttribIndex, kBucketId,
-           shared_memory_id_, kInvalidSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetShaderInfoLogValidArgs) {
-  const char* kInfo = "hello";
-  const uint32 kBucketId = 123;
-  CompileShader compile_cmd;
-  GetShaderInfoLog cmd;
-  EXPECT_CALL(*gl_, ShaderSource(kServiceShaderId, 1, _, _));
-  EXPECT_CALL(*gl_, CompileShader(kServiceShaderId));
-  EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_COMPILE_STATUS, _))
-      .WillOnce(SetArgumentPointee<2>(GL_FALSE))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_INFO_LOG_LENGTH, _))
-      .WillOnce(SetArgumentPointee<2>(strlen(kInfo) + 1))
-      .RetiresOnSaturation();
-  EXPECT_CALL(
-      *gl_, GetShaderInfoLog(kServiceShaderId, strlen(kInfo) + 1, _, _))
-      .WillOnce(DoAll(SetArgumentPointee<2>(strlen(kInfo)),
-                      SetArrayArgument<3>(kInfo, kInfo + strlen(kInfo) + 1)));
-  compile_cmd.Init(client_shader_id_);
-  cmd.Init(client_shader_id_, kBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(compile_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
-  ASSERT_TRUE(bucket != NULL);
-  EXPECT_EQ(strlen(kInfo) + 1, bucket->size());
-  EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kInfo,
-                      bucket->size()));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetShaderInfoLogInvalidArgs) {
-  const uint32 kBucketId = 123;
-  GetShaderInfoLog cmd;
-  cmd.Init(kInvalidClientId, kBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, GetIntegervCached) {
+TEST_P(GLES2DecoderTest, GetIntegervCached) {
   struct TestInfo {
     GLenum pname;
     GLint expected;
   };
   TestInfo tests[] = {
-    { GL_MAX_TEXTURE_SIZE, TestHelper::kMaxTextureSize, },
-    { GL_MAX_CUBE_MAP_TEXTURE_SIZE, TestHelper::kMaxCubeMapTextureSize, },
-    { GL_MAX_RENDERBUFFER_SIZE, TestHelper::kMaxRenderbufferSize, },
+      {
+       GL_MAX_TEXTURE_SIZE, TestHelper::kMaxTextureSize,
+      },
+      {
+       GL_MAX_CUBE_MAP_TEXTURE_SIZE, TestHelper::kMaxCubeMapTextureSize,
+      },
+      {
+       GL_MAX_RENDERBUFFER_SIZE, TestHelper::kMaxRenderbufferSize,
+      },
   };
   typedef GetIntegerv::Result Result;
   for (size_t ii = 0; ii < sizeof(tests) / sizeof(tests[0]); ++ii) {
@@ -1813,1309 +115,100 @@
         .WillOnce(Return(GL_NO_ERROR))
         .WillOnce(Return(GL_NO_ERROR))
         .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, GetIntegerv(test.pname, _))
-        .Times(0);
+    EXPECT_CALL(*gl_, GetIntegerv(test.pname, _)).Times(0);
     result->size = 0;
     GetIntegerv cmd2;
     cmd2.Init(test.pname, shared_memory_id_, shared_memory_offset_);
     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-    EXPECT_EQ(
-        decoder_->GetGLES2Util()->GLGetNumValuesReturned(test.pname),
-        result->GetNumResults());
+    EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(test.pname),
+              result->GetNumResults());
     EXPECT_EQ(GL_NO_ERROR, GetGLError());
     EXPECT_EQ(test.expected, result->GetData()[0]);
   }
 }
 
-TEST_F(GLES2DecoderTest, CompileShaderValidArgs) {
-  EXPECT_CALL(*gl_, ShaderSource(kServiceShaderId, 1, _, _));
-  EXPECT_CALL(*gl_, CompileShader(kServiceShaderId));
-  EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_COMPILE_STATUS, _))
-      .WillOnce(SetArgumentPointee<2>(GL_TRUE))
-      .RetiresOnSaturation();
-  CompileShader cmd;
-  cmd.Init(client_shader_id_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, CompileShaderInvalidArgs) {
-  CompileShader cmd;
-  cmd.Init(kInvalidClientId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
-  cmd.Init(client_program_id_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
-}
-
-TEST_F(GLES2DecoderTest, ShaderSourceAndGetShaderSourceValidArgs) {
-  const uint32 kBucketId = 123;
-  const char kSource[] = "hello";
-  const uint32 kSourceSize = sizeof(kSource) - 1;
-  memcpy(shared_memory_address_, kSource, kSourceSize);
-  ShaderSource cmd;
-  cmd.Init(client_shader_id_,
-           kSharedMemoryId, kSharedMemoryOffset, kSourceSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  memset(shared_memory_address_, 0, kSourceSize);
-  GetShaderSource get_cmd;
-  get_cmd.Init(client_shader_id_, kBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(get_cmd));
-  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
-  ASSERT_TRUE(bucket != NULL);
-  EXPECT_EQ(kSourceSize + 1, bucket->size());
-  EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kSource,
-                      bucket->size()));
-}
-
-TEST_F(GLES2DecoderTest, ShaderSourceInvalidArgs) {
-  const char kSource[] = "hello";
-  const uint32 kSourceSize = sizeof(kSource) - 1;
-  memcpy(shared_memory_address_, kSource, kSourceSize);
-  ShaderSource cmd;
-  cmd.Init(kInvalidClientId,
-           kSharedMemoryId, kSharedMemoryOffset, kSourceSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kSharedMemoryOffset, kSourceSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
-  cmd.Init(client_shader_id_,
-           kInvalidSharedMemoryId, kSharedMemoryOffset, kSourceSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_shader_id_,
-           kSharedMemoryId, kInvalidSharedMemoryOffset, kSourceSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_shader_id_,
-           kSharedMemoryId, kSharedMemoryOffset, kSharedBufferSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, ShaderSourceBucketAndGetShaderSourceValidArgs) {
-  const uint32 kInBucketId = 123;
-  const uint32 kOutBucketId = 125;
-  const char kSource[] = "hello";
-  const uint32 kSourceSize = sizeof(kSource) - 1;
-  SetBucketAsCString(kInBucketId, kSource);
-  ShaderSourceBucket cmd;
-  cmd.Init(client_shader_id_, kInBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  ClearSharedMemory();
-  GetShaderSource get_cmd;
-  get_cmd.Init(client_shader_id_, kOutBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(get_cmd));
-  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kOutBucketId);
-  ASSERT_TRUE(bucket != NULL);
-  EXPECT_EQ(kSourceSize + 1, bucket->size());
-  EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kSource,
-                      bucket->size()));
-}
-
-TEST_F(GLES2DecoderTest, ShaderSourceBucketInvalidArgs) {
-  const uint32 kBucketId = 123;
-  const char kSource[] = "hello";
-  const uint32 kSourceSize = sizeof(kSource) - 1;
-  memcpy(shared_memory_address_, kSource, kSourceSize);
-  ShaderSourceBucket cmd;
-  // Test no bucket.
-  cmd.Init(client_texture_id_, kBucketId);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  // Test invalid client.
-  SetBucketAsCString(kBucketId, kSource);
-  cmd.Init(kInvalidClientId, kBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, ShaderSourceStripComments) {
-  const uint32 kInBucketId = 123;
-  const char kSource[] = "hello/*te\ast*/world//a\ab";
-  SetBucketAsCString(kInBucketId, kSource);
-  ShaderSourceBucket cmd;
-  cmd.Init(client_shader_id_, kInBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, GenerateMipmapWrongFormatsFails) {
-  EXPECT_CALL(*gl_, GenerateMipmapEXT(_))
-       .Times(0);
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-      0, 0);
-  GenerateMipmap cmd;
-  cmd.Init(GL_TEXTURE_2D);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, GenerateMipmapHandlesOutOfMemory) {
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  TextureManager* manager = group().texture_manager();
-  TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
-  ASSERT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  GLint width = 0;
-  GLint height = 0;
-  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 2, &width, &height));
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-      kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, GenerateMipmapEXT(GL_TEXTURE_2D))
-      .Times(1);
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_OUT_OF_MEMORY))
-      .RetiresOnSaturation();
-  GenerateMipmap cmd;
-  cmd.Init(GL_TEXTURE_2D);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 2, &width, &height));
-}
-
-TEST_F(GLES2DecoderTest, GenerateMipmapClearsUnclearedTexture) {
-  EXPECT_CALL(*gl_, GenerateMipmapEXT(_))
-       .Times(0);
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
-      0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
-  EXPECT_CALL(*gl_, GenerateMipmapEXT(GL_TEXTURE_2D));
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  GenerateMipmap cmd;
-  cmd.Init(GL_TEXTURE_2D);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-// Same as GenerateMipmapClearsUnclearedTexture, but with workaround
-// |set_texture_filters_before_generating_mipmap|.
-TEST_F(GLES2DecoderManualInitTest, SetTextureFiltersBeforeGenerateMipmap) {
-  CommandLine command_line(0, NULL);
-  command_line.AppendSwitchASCII(
-      switches::kGpuDriverBugWorkarounds,
-      base::IntToString(gpu::SET_TEXTURE_FILTER_BEFORE_GENERATING_MIPMAP));
-  InitState init;
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoderWithCommandLine(init, &command_line);
-
-  EXPECT_CALL(*gl_, GenerateMipmapEXT(_))
-       .Times(0);
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
-      0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
-  EXPECT_CALL(*gl_, TexParameteri(
-      GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GenerateMipmapEXT(GL_TEXTURE_2D));
-  EXPECT_CALL(*gl_, TexParameteri(
-      GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  GenerateMipmap cmd;
-  cmd.Init(GL_TEXTURE_2D);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, Uniform1iValidArgs) {
-  EXPECT_CALL(*gl_, Uniform1i(kUniform1RealLocation, 2));
-  Uniform1i cmd;
-  cmd.Init(kUniform1FakeLocation, 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, Uniform1ivValidArgs) {
-  EXPECT_CALL(
-      *gl_, Uniform1iv(kUniform1RealLocation, 1,
-          reinterpret_cast<const GLint*>(shared_memory_address_)));
-  Uniform1iv cmd;
-  cmd.Init(kUniform1FakeLocation,
-           1, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, Uniform1ivInvalidArgs2_0) {
-  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
-  Uniform1iv cmd;
-  cmd.Init(kUniform1FakeLocation,
-           1, kInvalidSharedMemoryId, 0);
-  EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, Uniform1ivInvalidArgs2_1) {
-  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
-  Uniform1iv cmd;
-  cmd.Init(kUniform1FakeLocation,
-           1, shared_memory_id_, kInvalidSharedMemoryOffset);
-  EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, Uniform1ivImmediateValidArgs) {
-  Uniform1ivImmediate& cmd = *GetImmediateAs<Uniform1ivImmediate>();
-  EXPECT_CALL(
-      *gl_,
-      Uniform1iv(kUniform1RealLocation, 1,
-          reinterpret_cast<GLint*>(ImmediateDataAddress(&cmd))));
-  GLint temp[1 * 2] = { 0, };
-  cmd.Init(kUniform1FakeLocation, 1,
-           &temp[0]);
-  EXPECT_EQ(error::kNoError,
-            ExecuteImmediateCmd(cmd, sizeof(temp)));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, Uniform1ivInvalidValidArgs) {
-  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
-  Uniform1iv cmd;
-  cmd.Init(kUniform1FakeLocation,
-           2, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, Uniform1ivZeroCount) {
-  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
-  Uniform1iv cmd;
-  cmd.Init(kUniform1FakeLocation,
-           0, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, Uniform1iSamplerIsLmited) {
-  EXPECT_CALL(*gl_, Uniform1i(_, _)).Times(0);
-  Uniform1i cmd;
-  cmd.Init(
-      kUniform1FakeLocation,
-      kNumTextureUnits);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, Uniform1ivSamplerIsLimited) {
-  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
-  Uniform1ivImmediate& cmd = *GetImmediateAs<Uniform1ivImmediate>();
-  GLint temp[] = { kNumTextureUnits };
-  cmd.Init(kUniform1FakeLocation, 1,
-           &temp[0]);
-  EXPECT_EQ(error::kNoError,
-            ExecuteImmediateCmd(cmd, sizeof(temp)));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, BindBufferToDifferentTargetFails) {
-  // Bind the buffer to GL_ARRAY_BUFFER
-  DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
-  // Attempt to rebind to GL_ELEMENT_ARRAY_BUFFER
-  // NOTE: Real GLES2 does not have this restriction but WebGL and we do.
-  // This can be restriction can be removed at runtime.
-  EXPECT_CALL(*gl_, BindBuffer(_, _))
-      .Times(0);
-  BindBuffer cmd;
-  cmd.Init(GL_ELEMENT_ARRAY_BUFFER, client_buffer_id_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, ActiveTextureValidArgs) {
-  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
-  SpecializedSetup<ActiveTexture, 0>(true);
-  ActiveTexture cmd;
-  cmd.Init(GL_TEXTURE1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, ActiveTextureInvalidArgs) {
-  EXPECT_CALL(*gl_, ActiveTexture(_)).Times(0);
-  SpecializedSetup<ActiveTexture, 0>(false);
-  ActiveTexture cmd;
-  cmd.Init(GL_TEXTURE0 - 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-  cmd.Init(kNumTextureUnits);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, CheckFramebufferStatusWithNoBoundTarget) {
-  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(_))
-      .Times(0);
-  CheckFramebufferStatus::Result* result =
-      static_cast<CheckFramebufferStatus::Result*>(shared_memory_address_);
-  *result = 0;
-  CheckFramebufferStatus cmd;
-  cmd.Init(GL_FRAMEBUFFER, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), *result);
-}
-
-TEST_F(GLES2DecoderWithShaderTest, BindAndDeleteFramebuffer) {
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDefaultDirtyState();
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  DoDeleteFramebuffer(
-      client_framebuffer_id_, kServiceFramebufferId,
-      true, GL_FRAMEBUFFER, 0,
-      true, GL_FRAMEBUFFER, 0);
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, FramebufferRenderbufferWithNoBoundTarget) {
-  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(_, _, _, _))
-      .Times(0);
-  FramebufferRenderbuffer cmd;
-  cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      client_renderbuffer_id_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, FramebufferTexture2DWithNoBoundTarget) {
-  EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _))
-      .Times(0);
-  FramebufferTexture2D cmd;
-  cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_,
-      0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithNoBoundTarget) {
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _))
-      .Times(0);
-  GetFramebufferAttachmentParameteriv cmd;
-  cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-      GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, shared_memory_id_,
-      shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithRenderbuffer) {
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      kServiceRenderbufferId))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  GetFramebufferAttachmentParameteriv::Result* result =
-      static_cast<GetFramebufferAttachmentParameteriv::Result*>(
-          shared_memory_address_);
-  result->size = 0;
-  const GLint* result_value = result->GetData();
-  FramebufferRenderbuffer fbrb_cmd;
-  GetFramebufferAttachmentParameteriv cmd;
-  fbrb_cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      client_renderbuffer_id_);
-  cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-      GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, shared_memory_id_,
-      shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(static_cast<GLuint>(*result_value), client_renderbuffer_id_);
-}
-
-TEST_F(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithTexture) {
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kServiceTextureId, 0))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  GetFramebufferAttachmentParameteriv::Result* result =
-      static_cast<GetFramebufferAttachmentParameteriv::Result*>(
-          shared_memory_address_);
-  result->SetNumResults(0);
-  const GLint* result_value = result->GetData();
-  FramebufferTexture2D fbtex_cmd;
-  GetFramebufferAttachmentParameteriv cmd;
-  fbtex_cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_,
-      0);
-  cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-      GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, shared_memory_id_,
-      shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(static_cast<GLuint>(*result_value), client_texture_id_);
-}
-
-TEST_F(GLES2DecoderTest, GetRenderbufferParameterivWithNoBoundTarget) {
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _))
-      .Times(0);
-  GetRenderbufferParameteriv cmd;
-  cmd.Init(
-      GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, shared_memory_id_,
-      shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, RenderbufferStorageWithNoBoundTarget) {
-  EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _))
-      .Times(0);
-  RenderbufferStorage cmd;
-  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 3, 4);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-namespace {
-
-// A class to emulate glReadPixels
-class ReadPixelsEmulator {
- public:
-  // pack_alignment is the alignment you want ReadPixels to use
-  // when copying. The actual data passed in pixels should be contiguous.
-  ReadPixelsEmulator(GLsizei width, GLsizei height, GLint bytes_per_pixel,
-                     const void* src_pixels, const void* expected_pixels,
-                     GLint pack_alignment)
-      : width_(width),
-        height_(height),
-        pack_alignment_(pack_alignment),
-        bytes_per_pixel_(bytes_per_pixel),
-        src_pixels_(reinterpret_cast<const int8*>(src_pixels)),
-        expected_pixels_(reinterpret_cast<const int8*>(expected_pixels)) {
-  }
-
-  void ReadPixels(
-      GLint x, GLint y, GLsizei width, GLsizei height,
-      GLenum format, GLenum type, void* pixels) const {
-    DCHECK_GE(x, 0);
-    DCHECK_GE(y, 0);
-    DCHECK_LE(x + width, width_);
-    DCHECK_LE(y + height, height_);
-    for (GLint yy = 0; yy < height; ++yy) {
-      const int8* src = GetPixelAddress(src_pixels_, x, y + yy);
-      const void* dst = ComputePackAlignmentAddress(0, yy, width, pixels);
-      memcpy(const_cast<void*>(dst), src, width * bytes_per_pixel_);
-    }
-  }
-
-  bool CompareRowSegment(
-      GLint x, GLint y, GLsizei width, const void* data) const {
-    DCHECK(x + width <= width_ || width == 0);
-    return memcmp(data, GetPixelAddress(expected_pixels_, x, y),
-                  width * bytes_per_pixel_) == 0;
-  }
-
-  // Helper to compute address of pixel in pack aligned data.
-  const void* ComputePackAlignmentAddress(
-      GLint x, GLint y, GLsizei width, const void* address) const {
-    GLint unpadded_row_size = ComputeImageDataSize(width, 1);
-    GLint two_rows_size = ComputeImageDataSize(width, 2);
-    GLsizei padded_row_size = two_rows_size - unpadded_row_size;
-    GLint offset = y * padded_row_size + x * bytes_per_pixel_;
-    return static_cast<const int8*>(address) + offset;
-  }
-
-  GLint ComputeImageDataSize(GLint width, GLint height) const {
-    GLint row_size = width * bytes_per_pixel_;
-    if (height > 1) {
-      GLint temp = row_size + pack_alignment_ - 1;
-      GLint padded_row_size = (temp / pack_alignment_) * pack_alignment_;
-      GLint size_of_all_but_last_row = (height - 1) * padded_row_size;
-      return size_of_all_but_last_row + row_size;
-    } else {
-      return height * row_size;
-    }
-  }
-
- private:
-  const int8* GetPixelAddress(const int8* base, GLint x, GLint y) const {
-    return base + (width_ * y + x) * bytes_per_pixel_;
-  }
-
-  GLsizei width_;
-  GLsizei height_;
-  GLint pack_alignment_;
-  GLint bytes_per_pixel_;
-  const int8* src_pixels_;
-  const int8* expected_pixels_;
-};
-
-}  // anonymous namespace
-
-void GLES2DecoderTest::CheckReadPixelsOutOfRange(
-    GLint in_read_x, GLint in_read_y,
-    GLsizei in_read_width, GLsizei in_read_height,
-    bool init) {
-  const GLsizei kWidth = 5;
-  const GLsizei kHeight = 3;
-  const GLint kBytesPerPixel = 3;
-  const GLint kPackAlignment = 4;
-  const GLenum kFormat = GL_RGB;
-  static const int8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
-    12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19, 18, 19, 13,
-    29, 28, 23, 22, 21, 22, 21, 29, 28, 23, 22, 21, 22, 21, 28,
-    31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32, 37, 32, 34,
-  };
-
-  ClearSharedMemory();
-
-  // We need to setup an FBO so we can know the max size that ReadPixels will
-  // access
-  if (init) {
-    DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-    DoTexImage2D(
-        GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0,
-        kFormat, GL_UNSIGNED_BYTE, kSharedMemoryId,
-        kSharedMemoryOffset);
-    DoBindFramebuffer(
-        GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-    DoFramebufferTexture2D(
-        GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-        client_texture_id_, kServiceTextureId, 0, GL_NO_ERROR);
-    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
-        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
-        .RetiresOnSaturation();
-  }
-
-  ReadPixelsEmulator emu(
-      kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment);
-  typedef ReadPixels::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  uint32 result_shm_id = kSharedMemoryId;
-  uint32 result_shm_offset = kSharedMemoryOffset;
-  uint32 pixels_shm_id = kSharedMemoryId;
-  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
-  void* dest = &result[1];
-  EXPECT_CALL(*gl_, GetError())
-     .WillOnce(Return(GL_NO_ERROR))
-     .WillOnce(Return(GL_NO_ERROR))
-     .RetiresOnSaturation();
-  // ReadPixels will be called for valid size only even though the command
-  // is requesting a larger size.
-  GLint read_x = std::max(0, in_read_x);
-  GLint read_y = std::max(0, in_read_y);
-  GLint read_end_x = std::max(0, std::min(kWidth, in_read_x + in_read_width));
-  GLint read_end_y = std::max(0, std::min(kHeight, in_read_y + in_read_height));
-  GLint read_width = read_end_x - read_x;
-  GLint read_height = read_end_y - read_y;
-  if (read_width > 0 && read_height > 0) {
-    for (GLint yy = read_y; yy < read_end_y; ++yy) {
-      EXPECT_CALL(
-          *gl_, ReadPixels(read_x, yy, read_width, 1,
-                           kFormat, GL_UNSIGNED_BYTE, _))
-          .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels))
-          .RetiresOnSaturation();
-    }
-  }
-  ReadPixels cmd;
-  cmd.Init(in_read_x, in_read_y, in_read_width, in_read_height,
-           kFormat, GL_UNSIGNED_BYTE,
-           pixels_shm_id, pixels_shm_offset,
-           result_shm_id, result_shm_offset,
-           false);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-
-  GLint unpadded_row_size = emu.ComputeImageDataSize(in_read_width, 1);
-  scoped_ptr<int8[]> zero(new int8[unpadded_row_size]);
-  scoped_ptr<int8[]> pack(new int8[kPackAlignment]);
-  memset(zero.get(), 0, unpadded_row_size);
-  memset(pack.get(), kInitialMemoryValue, kPackAlignment);
-  for (GLint yy = 0; yy < in_read_height; ++yy) {
-    const int8* row = static_cast<const int8*>(
-        emu.ComputePackAlignmentAddress(0, yy, in_read_width, dest));
-    GLint y = in_read_y + yy;
-    if (y < 0 || y >= kHeight) {
-      EXPECT_EQ(0, memcmp(zero.get(), row, unpadded_row_size));
-    } else {
-      // check off left.
-      GLint num_left_pixels = std::max(-in_read_x, 0);
-      GLint num_left_bytes = num_left_pixels * kBytesPerPixel;
-      EXPECT_EQ(0, memcmp(zero.get(), row, num_left_bytes));
-
-      // check off right.
-      GLint num_right_pixels = std::max(in_read_x + in_read_width - kWidth, 0);
-      GLint num_right_bytes = num_right_pixels * kBytesPerPixel;
-      EXPECT_EQ(0, memcmp(zero.get(),
-                            row + unpadded_row_size - num_right_bytes,
-                            num_right_bytes));
-
-      // check middle.
-      GLint x = std::max(in_read_x, 0);
-      GLint num_middle_pixels =
-          std::max(in_read_width - num_left_pixels - num_right_pixels, 0);
-      EXPECT_TRUE(emu.CompareRowSegment(
-          x, y, num_middle_pixels, row + num_left_bytes));
-    }
-
-    // check padding
-    if (yy != in_read_height - 1) {
-      GLint num_padding_bytes =
-          (kPackAlignment - 1) - (unpadded_row_size % kPackAlignment);
-      EXPECT_EQ(0,
-                memcmp(pack.get(), row + unpadded_row_size, num_padding_bytes));
-    }
-  }
-}
-
-TEST_F(GLES2DecoderTest, ReadPixels) {
-  const GLsizei kWidth = 5;
-  const GLsizei kHeight = 3;
-  const GLint kBytesPerPixel = 3;
-  const GLint kPackAlignment = 4;
-  static const int8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
-    12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19, 18, 19, 13,
-    29, 28, 23, 22, 21, 22, 21, 29, 28, 23, 22, 21, 22, 21, 28,
-    31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32, 37, 32, 34,
-  };
-
-  surface_->SetSize(gfx::Size(INT_MAX, INT_MAX));
-
-  ReadPixelsEmulator emu(
-      kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment);
-  typedef ReadPixels::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  uint32 result_shm_id = kSharedMemoryId;
-  uint32 result_shm_offset = kSharedMemoryOffset;
-  uint32 pixels_shm_id = kSharedMemoryId;
-  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
-  void* dest = &result[1];
-  EXPECT_CALL(*gl_, GetError())
-     .WillOnce(Return(GL_NO_ERROR))
-     .WillOnce(Return(GL_NO_ERROR))
-     .RetiresOnSaturation();
-  EXPECT_CALL(
-      *gl_, ReadPixels(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, _))
-      .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels));
-  ReadPixels cmd;
-  cmd.Init(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE,
-           pixels_shm_id, pixels_shm_offset,
-           result_shm_id, result_shm_offset,
-           false);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  for (GLint yy = 0; yy < kHeight; ++yy) {
-    EXPECT_TRUE(emu.CompareRowSegment(
-        0, yy, kWidth,
-        emu.ComputePackAlignmentAddress(0, yy, kWidth, dest)));
-  }
-}
-
-TEST_F(GLES2DecoderRGBBackbufferTest, ReadPixelsNoAlphaBackbuffer) {
-  const GLsizei kWidth = 3;
-  const GLsizei kHeight = 3;
-  const GLint kBytesPerPixel = 4;
-  const GLint kPackAlignment = 4;
-  static const uint8 kExpectedPixels[kWidth * kHeight * kBytesPerPixel] = {
-    12, 13, 14, 255, 19, 18, 19, 255, 13, 14, 18, 255,
-    29, 28, 23, 255, 21, 22, 21, 255, 28, 23, 22, 255,
-    31, 34, 39, 255, 32, 37, 32, 255, 34, 39, 37, 255,
-  };
-  static const uint8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
-    12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19,
-    29, 28, 23, 22, 21, 22, 21, 29, 28, 23, 22, 21,
-    31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32,
-  };
-
-  surface_->SetSize(gfx::Size(INT_MAX, INT_MAX));
-
-  ReadPixelsEmulator emu(
-      kWidth, kHeight, kBytesPerPixel, kSrcPixels, kExpectedPixels,
-      kPackAlignment);
-  typedef ReadPixels::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  uint32 result_shm_id = kSharedMemoryId;
-  uint32 result_shm_offset = kSharedMemoryOffset;
-  uint32 pixels_shm_id = kSharedMemoryId;
-  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
-  void* dest = &result[1];
-  EXPECT_CALL(*gl_, GetError())
-     .WillOnce(Return(GL_NO_ERROR))
-     .WillOnce(Return(GL_NO_ERROR))
-     .RetiresOnSaturation();
-  EXPECT_CALL(
-      *gl_, ReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, _))
-      .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels));
-  ReadPixels cmd;
-  cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
-           pixels_shm_id, pixels_shm_offset,
-           result_shm_id, result_shm_offset,
-           false);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  for (GLint yy = 0; yy < kHeight; ++yy) {
-    EXPECT_TRUE(emu.CompareRowSegment(
-        0, yy, kWidth,
-        emu.ComputePackAlignmentAddress(0, yy, kWidth, dest)));
-  }
-}
-
-TEST_F(GLES2DecoderTest, ReadPixelsOutOfRange) {
-  static GLint tests[][4] = {
-    { -2, -1, 9, 5, },  // out of range on all sides
-    { 2, 1, 9, 5, },  // out of range on right, bottom
-    { -7, -4, 9, 5, },  // out of range on left, top
-    { 0, -5, 9, 5, },  // completely off top
-    { 0, 3, 9, 5, },  // completely off bottom
-    { -9, 0, 9, 5, },  // completely off left
-    { 5, 0, 9, 5, },  // completely off right
-  };
-
-  for (size_t tt = 0; tt < arraysize(tests); ++tt) {
-    CheckReadPixelsOutOfRange(
-        tests[tt][0], tests[tt][1], tests[tt][2], tests[tt][3], tt == 0);
-  }
-}
-
-TEST_F(GLES2DecoderTest, ReadPixelsInvalidArgs) {
-  typedef ReadPixels::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  uint32 result_shm_id = kSharedMemoryId;
-  uint32 result_shm_offset = kSharedMemoryOffset;
-  uint32 pixels_shm_id = kSharedMemoryId;
-  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
-  EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0);
-  ReadPixels cmd;
-  cmd.Init(0, 0, -1, 1, GL_RGB, GL_UNSIGNED_BYTE,
-           pixels_shm_id, pixels_shm_offset,
-           result_shm_id, result_shm_offset,
-           false);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(0, 0, 1, -1, GL_RGB, GL_UNSIGNED_BYTE,
-           pixels_shm_id, pixels_shm_offset,
-           result_shm_id, result_shm_offset,
-           false);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(0, 0, 1, 1, GL_RGB, GL_INT,
-           pixels_shm_id, pixels_shm_offset,
-           result_shm_id, result_shm_offset,
-           false);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-  cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE,
-           kInvalidSharedMemoryId, pixels_shm_offset,
-           result_shm_id, result_shm_offset,
-           false);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE,
-           pixels_shm_id, kInvalidSharedMemoryOffset,
-           result_shm_id, result_shm_offset,
-           false);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE,
-           pixels_shm_id, pixels_shm_offset,
-           kInvalidSharedMemoryId, result_shm_offset,
-           false);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE,
-           pixels_shm_id, pixels_shm_offset,
-           result_shm_id, kInvalidSharedMemoryOffset,
-           false);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderManualInitTest, ReadPixelsAsyncError) {
-  InitState init;
-  init.extensions = "GL_ARB_sync";
-  init.gl_version = "opengl es 3.0";
-  init.has_alpha = true;
-  init.request_alpha = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  typedef ReadPixels::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-
-  const GLsizei kWidth = 4;
-  const GLsizei kHeight = 4;
-  uint32 result_shm_id = kSharedMemoryId;
-  uint32 result_shm_offset = kSharedMemoryOffset;
-  uint32 pixels_shm_id = kSharedMemoryId;
-  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
-
-  EXPECT_CALL(*gl_, GetError())
-     // first error check must pass to get to the test
-     .WillOnce(Return(GL_NO_ERROR))
-     // second check is after BufferData, simulate fail here
-     .WillOnce(Return(GL_INVALID_OPERATION))
-     // third error check is fall-through call to sync ReadPixels
-     .WillOnce(Return(GL_NO_ERROR))
-     .RetiresOnSaturation();
-
-  EXPECT_CALL(*gl_, ReadPixels(0, 0, kWidth, kHeight, GL_RGB,
-    GL_UNSIGNED_BYTE, _)).Times(1);
-  EXPECT_CALL(*gl_, GenBuffersARB(1, _)).Times(1);
-  EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, _)).Times(2);
-  EXPECT_CALL(*gl_, BufferData(GL_PIXEL_PACK_BUFFER_ARB, _, NULL,
-    GL_STREAM_READ)).Times(1);
-
-  ReadPixels cmd;
-  cmd.Init(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE,
-           pixels_shm_id, pixels_shm_offset,
-           result_shm_id, result_shm_offset,
-           true);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, BindAttribLocation) {
-  const GLint kLocation = 2;
-  const char* kName = "testing";
-  const uint32 kNameSize = strlen(kName);
-  EXPECT_CALL(
-      *gl_, BindAttribLocation(kServiceProgramId, kLocation, StrEq(kName)))
-      .Times(1);
-  memcpy(shared_memory_address_, kName, kNameSize);
-  BindAttribLocation cmd;
-  cmd.Init(client_program_id_, kLocation, kSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, BindAttribLocationInvalidArgs) {
-  const GLint kLocation = 2;
-  const char* kName = "testing";
-  const char* kBadName = "test\aing";
-  const uint32 kNameSize = strlen(kName);
-  const uint32 kBadNameSize = strlen(kBadName);
-  EXPECT_CALL(*gl_, BindAttribLocation(_, _, _)).Times(0);
-  memcpy(shared_memory_address_, kName, kNameSize);
-  BindAttribLocation cmd;
-  cmd.Init(kInvalidClientId, kLocation,
-           kSharedMemoryId, kSharedMemoryOffset, kNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(client_program_id_, kLocation,
-           kInvalidSharedMemoryId, kSharedMemoryOffset, kNameSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_program_id_, kLocation,
-           kSharedMemoryId, kInvalidSharedMemoryOffset, kNameSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_program_id_, kLocation,
-           kSharedMemoryId, kSharedMemoryOffset, kSharedBufferSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  memcpy(shared_memory_address_, kBadName, kBadNameSize);
-  cmd.Init(client_program_id_, kLocation,
-           kSharedMemoryId, kSharedMemoryOffset, kBadNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, BindAttribLocationBucket) {
-  const uint32 kBucketId = 123;
-  const GLint kLocation = 2;
-  const char* kName = "testing";
-  EXPECT_CALL(
-      *gl_, BindAttribLocation(kServiceProgramId, kLocation, StrEq(kName)))
-      .Times(1);
-  SetBucketAsCString(kBucketId, kName);
-  BindAttribLocationBucket cmd;
-  cmd.Init(client_program_id_, kLocation, kBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, BindAttribLocationBucketInvalidArgs) {
-  const uint32 kBucketId = 123;
-  const GLint kLocation = 2;
-  const char* kName = "testing";
-  EXPECT_CALL(*gl_, BindAttribLocation(_, _, _)).Times(0);
-  BindAttribLocationBucket cmd;
-  // check bucket does not exist.
-  cmd.Init(client_program_id_, kLocation, kBucketId);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  // check bucket is empty.
-  SetBucketAsCString(kBucketId, NULL);
-  cmd.Init(client_program_id_, kLocation, kBucketId);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  // Check bad program id
-  SetBucketAsCString(kBucketId, kName);
-  cmd.Init(kInvalidClientId, kLocation, kBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetAttribLocation) {
-  const uint32 kNameSize = strlen(kAttrib2Name);
-  const char* kNonExistentName = "foobar";
-  const uint32 kNonExistentNameSize = strlen(kNonExistentName);
-  typedef GetAttribLocation::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  *result = -1;
-  char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
-  const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
-  memcpy(name, kAttrib2Name, kNameSize);
-  GetAttribLocation cmd;
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(kAttrib2Location, *result);
-  *result = -1;
-  memcpy(name, kNonExistentName, kNonExistentNameSize);
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kNonExistentNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetAttribLocationInvalidArgs) {
-  const uint32 kNameSize = strlen(kAttrib2Name);
-  const char* kBadName = "foo\abar";
-  const uint32 kBadNameSize = strlen(kBadName);
-  typedef GetAttribLocation::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  *result = -1;
-  char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
-  const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
-  memcpy(name, kAttrib2Name, kNameSize);
-  GetAttribLocation cmd;
-  cmd.Init(kInvalidClientId,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  *result = -1;
-  cmd.Init(client_program_id_,
-           kInvalidSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kInvalidSharedMemoryOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kInvalidSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kInvalidSharedMemoryOffset,
-           kNameSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kSharedBufferSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  memcpy(name, kBadName, kBadNameSize);
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kBadNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetAttribLocationBucket) {
-  const uint32 kBucketId = 123;
-  const char* kNonExistentName = "foobar";
-  typedef GetAttribLocationBucket::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  SetBucketAsCString(kBucketId, kAttrib2Name);
-  *result = -1;
-  GetAttribLocationBucket cmd;
-  cmd.Init(client_program_id_, kBucketId,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(kAttrib2Location, *result);
-  SetBucketAsCString(kBucketId, kNonExistentName);
-  *result = -1;
-  cmd.Init(client_program_id_, kBucketId,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetAttribLocationBucketInvalidArgs) {
-  const uint32 kBucketId = 123;
-  typedef GetAttribLocationBucket::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  *result = -1;
-  GetAttribLocationBucket cmd;
-  // Check no bucket
-  cmd.Init(client_program_id_, kBucketId,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  // Check bad program id.
-  SetBucketAsCString(kBucketId, kAttrib2Name);
-  cmd.Init(kInvalidClientId, kBucketId,
-           kSharedMemoryId, kSharedMemoryOffset);
-  *result = -1;
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  // Check bad memory
-  cmd.Init(client_program_id_, kBucketId,
-           kInvalidSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_program_id_, kBucketId,
-           kSharedMemoryId, kInvalidSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformLocation) {
-  const uint32 kNameSize = strlen(kUniform2Name);
-  const char* kNonExistentName = "foobar";
-  const uint32 kNonExistentNameSize = strlen(kNonExistentName);
-  typedef GetUniformLocation::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  *result = -1;
-  char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
-  const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
-  memcpy(name, kUniform2Name, kNameSize);
-  GetUniformLocation cmd;
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(kUniform2FakeLocation, *result);
-  memcpy(name, kNonExistentName, kNonExistentNameSize);
-  *result = -1;
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kNonExistentNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformLocationInvalidArgs) {
-  const uint32 kNameSize = strlen(kUniform2Name);
-  const char* kBadName = "foo\abar";
-  const uint32 kBadNameSize = strlen(kBadName);
-  typedef GetUniformLocation::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  *result = -1;
-  char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
-  const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
-  memcpy(name, kUniform2Name, kNameSize);
-  GetUniformLocation cmd;
-  cmd.Init(kInvalidClientId,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  *result = -1;
-  cmd.Init(client_program_id_,
-           kInvalidSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kInvalidSharedMemoryOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kInvalidSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kInvalidSharedMemoryOffset,
-           kNameSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kSharedBufferSize);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  memcpy(name, kBadName, kBadNameSize);
-  cmd.Init(client_program_id_,
-           kSharedMemoryId, kNameOffset,
-           kSharedMemoryId, kSharedMemoryOffset,
-           kBadNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformLocationBucket) {
-  const uint32 kBucketId = 123;
-  const char* kNonExistentName = "foobar";
-  typedef GetUniformLocationBucket::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  SetBucketAsCString(kBucketId, kUniform2Name);
-  *result = -1;
-  GetUniformLocationBucket cmd;
-  cmd.Init(client_program_id_, kBucketId,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(kUniform2FakeLocation, *result);
-  SetBucketAsCString(kBucketId, kNonExistentName);
-  *result = -1;
-  cmd.Init(client_program_id_, kBucketId,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetUniformLocationBucketInvalidArgs) {
-  const uint32 kBucketId = 123;
-  typedef GetUniformLocationBucket::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  *result = -1;
-  GetUniformLocationBucket cmd;
-  // Check no bucket
-  cmd.Init(client_program_id_, kBucketId,
-           kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  // Check bad program id.
-  SetBucketAsCString(kBucketId, kUniform2Name);
-  cmd.Init(kInvalidClientId, kBucketId,
-           kSharedMemoryId, kSharedMemoryOffset);
-  *result = -1;
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(-1, *result);
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  // Check bad memory
-  cmd.Init(client_program_id_, kBucketId,
-           kInvalidSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_program_id_, kBucketId,
-           kSharedMemoryId, kInvalidSharedMemoryOffset);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) {
+TEST_P(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) {
   SetupIndexBuffer();
   GetMaxValueInBufferCHROMIUM::Result* result =
       static_cast<GetMaxValueInBufferCHROMIUM::Result*>(shared_memory_address_);
   *result = 0;
 
   GetMaxValueInBufferCHROMIUM cmd;
-  cmd.Init(client_element_buffer_id_, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
+  cmd.Init(client_element_buffer_id_,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(7u, *result);
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
+  cmd.Init(client_element_buffer_id_,
+           kValidIndexRangeCount + 1,
            GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
+           kValidIndexRangeStart * 2,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(100u, *result);
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 
-  cmd.Init(kInvalidClientId, kValidIndexRangeCount,
+  cmd.Init(kInvalidClientId,
+           kValidIndexRangeCount,
            GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
+           kValidIndexRangeStart * 2,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(client_element_buffer_id_, kOutOfRangeIndexRangeEnd,
-           GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
-           GL_UNSIGNED_SHORT,
-           kOutOfRangeIndexRangeEnd * 2, kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
-           GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_buffer_id_, kValidIndexRangeCount + 1,
-           GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
+  cmd.Init(client_element_buffer_id_,
+           kOutOfRangeIndexRangeEnd,
            GL_UNSIGNED_SHORT,
            kValidIndexRangeStart * 2,
-           kInvalidSharedMemoryId, kSharedMemoryOffset);
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  cmd.Init(client_element_buffer_id_,
+           kValidIndexRangeCount + 1,
+           GL_UNSIGNED_SHORT,
+           kOutOfRangeIndexRangeEnd * 2,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  cmd.Init(client_element_buffer_id_,
+           kValidIndexRangeCount + 1,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_buffer_id_,
+           kValidIndexRangeCount + 1,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  cmd.Init(client_element_buffer_id_,
+           kValidIndexRangeCount + 1,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           kInvalidSharedMemoryId,
+           kSharedMemoryOffset);
   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
+  cmd.Init(client_element_buffer_id_,
+           kValidIndexRangeCount + 1,
            GL_UNSIGNED_SHORT,
            kValidIndexRangeStart * 2,
-           kSharedMemoryId, kInvalidSharedMemoryOffset);
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset);
   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest, SharedIds) {
+TEST_P(GLES2DecoderTest, SharedIds) {
   GenSharedIdsCHROMIUM gen_cmd;
   RegisterSharedIdsCHROMIUM reg_cmd;
   DeleteSharedIdsCHROMIUM del_cmd;
@@ -3186,7 +279,7 @@
   EXPECT_EQ(kOffset + 1, ids[1]);
 }
 
-TEST_F(GLES2DecoderTest, GenSharedIdsCHROMIUMBadArgs) {
+TEST_P(GLES2DecoderTest, GenSharedIdsCHROMIUMBadArgs) {
   const GLuint kNamespaceId = id_namespaces::kTextures;
   GenSharedIdsCHROMIUM cmd;
   cmd.Init(kNamespaceId, 0, -1, kSharedMemoryId, kSharedMemoryOffset);
@@ -3197,7 +290,7 @@
   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest, RegisterSharedIdsCHROMIUMBadArgs) {
+TEST_P(GLES2DecoderTest, RegisterSharedIdsCHROMIUMBadArgs) {
   const GLuint kNamespaceId = id_namespaces::kTextures;
   RegisterSharedIdsCHROMIUM cmd;
   cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset);
@@ -3208,7 +301,7 @@
   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest, RegisterSharedIdsCHROMIUMDuplicateIds) {
+TEST_P(GLES2DecoderTest, RegisterSharedIdsCHROMIUMDuplicateIds) {
   const GLuint kNamespaceId = id_namespaces::kTextures;
   const GLuint kRegisterId = 3;
   RegisterSharedIdsCHROMIUM cmd;
@@ -3221,7 +314,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest, DeleteSharedIdsCHROMIUMBadArgs) {
+TEST_P(GLES2DecoderTest, DeleteSharedIdsCHROMIUMBadArgs) {
   const GLuint kNamespaceId = id_namespaces::kTextures;
   DeleteSharedIdsCHROMIUM cmd;
   cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset);
@@ -3232,234 +325,7 @@
   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest, TexSubImage2DValidArgs) {
-  const int kWidth = 16;
-  const int kHeight = 8;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 1, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-      kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, TexSubImage2D(
-      GL_TEXTURE_2D, 1, 1, 0, kWidth - 1, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
-      shared_memory_address_))
-      .Times(1)
-      .RetiresOnSaturation();
-  TexSubImage2D cmd;
-  cmd.Init(
-      GL_TEXTURE_2D, 1, 1, 0, kWidth - 1, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
-      kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, TexSubImage2DBadArgs) {
-  const int kWidth = 16;
-  const int kHeight = 8;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 1, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-      0, 0);
-  TexSubImage2D cmd;
-  cmd.Init(GL_TEXTURE0, 1, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
-           kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_TRUE, GL_UNSIGNED_BYTE,
-           kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_INT,
-           kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, -1, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
-           kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 1, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
-           kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, -1, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
-           kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 1, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
-           kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth + 1, kHeight, GL_RGBA,
-           GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight + 1, GL_RGBA,
-           GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE,
-           kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGBA,
-           GL_UNSIGNED_SHORT_4_4_4_4, kSharedMemoryId, kSharedMemoryOffset,
-           GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
-           kInvalidSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
-           kSharedMemoryId, kInvalidSharedMemoryOffset, GL_FALSE);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, CopyTexSubImage2DValidArgs) {
-  const int kWidth = 16;
-  const int kHeight = 8;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 1, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-      kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, CopyTexSubImage2D(
-      GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth, kHeight))
-      .Times(1)
-      .RetiresOnSaturation();
-  CopyTexSubImage2D cmd;
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth, kHeight);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, CopyTexSubImage2DBadArgs) {
-  const int kWidth = 16;
-  const int kHeight = 8;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 1, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-      0, 0);
-  CopyTexSubImage2D cmd;
-  cmd.Init(GL_TEXTURE0, 1, 0, 0, 0, 0, kWidth, kHeight);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, -1, 0, 0, 0, kWidth, kHeight);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 1, 0, 0, 0, kWidth, kHeight);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, -1, 0, 0, kWidth, kHeight);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 1, 0, 0, kWidth, kHeight);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth + 1, kHeight);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth, kHeight + 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-// Check that if a renderbuffer is attached and GL returns
-// GL_FRAMEBUFFER_COMPLETE that the buffer is cleared and state is restored.
-TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearColor) {
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  ClearColor color_cmd;
-  ColorMask color_mask_cmd;
-  Enable enable_cmd;
-  FramebufferRenderbuffer cmd;
-  color_cmd.Init(0.1f, 0.2f, 0.3f, 0.4f);
-  color_mask_cmd.Init(0, 1, 0, 1);
-  enable_cmd.Init(GL_SCISSOR_TEST);
-  cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      client_renderbuffer_id_);
-  InSequence sequence;
-  EXPECT_CALL(*gl_, ClearColor(0.1f, 0.2f, 0.3f, 0.4f))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      kServiceRenderbufferId))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(color_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(color_mask_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearDepth) {
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  ClearDepthf depth_cmd;
-  DepthMask depth_mask_cmd;
-  FramebufferRenderbuffer cmd;
-  depth_cmd.Init(0.5f);
-  depth_mask_cmd.Init(false);
-  cmd.Init(
-      GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
-      client_renderbuffer_id_);
-  InSequence sequence;
-  EXPECT_CALL(*gl_, ClearDepth(0.5f))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
-      GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
-      kServiceRenderbufferId))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(depth_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(depth_mask_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearStencil) {
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  ClearStencil stencil_cmd;
-  StencilMaskSeparate stencil_mask_separate_cmd;
-  FramebufferRenderbuffer cmd;
-  stencil_cmd.Init(123);
-  stencil_mask_separate_cmd.Init(GL_BACK, 0x1234u);
-  cmd.Init(
-      GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
-      client_renderbuffer_id_);
-  InSequence sequence;
-  EXPECT_CALL(*gl_, ClearStencil(123))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
-      GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
-      kServiceRenderbufferId))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_mask_separate_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, IsBuffer) {
+TEST_P(GLES2DecoderTest, IsBuffer) {
   EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
   DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
   EXPECT_TRUE(DoIsBuffer(client_buffer_id_));
@@ -3467,19 +333,23 @@
   EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
 }
 
-TEST_F(GLES2DecoderTest, IsFramebuffer) {
+TEST_P(GLES2DecoderTest, IsFramebuffer) {
   EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
   EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_));
-  DoDeleteFramebuffer(
-      client_framebuffer_id_, kServiceFramebufferId,
-      true, GL_FRAMEBUFFER, 0,
-      true, GL_FRAMEBUFFER, 0);
+  DoDeleteFramebuffer(client_framebuffer_id_,
+                      kServiceFramebufferId,
+                      true,
+                      GL_FRAMEBUFFER,
+                      0,
+                      true,
+                      GL_FRAMEBUFFER,
+                      0);
   EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
 }
 
-TEST_F(GLES2DecoderTest, IsProgram) {
+TEST_P(GLES2DecoderTest, IsProgram) {
   // IsProgram is true as soon as the program is created.
   EXPECT_TRUE(DoIsProgram(client_program_id_));
   EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
@@ -3487,26 +357,25 @@
       .RetiresOnSaturation();
   DoDeleteProgram(client_program_id_, kServiceProgramId);
   EXPECT_FALSE(DoIsProgram(client_program_id_));
-
 }
 
-TEST_F(GLES2DecoderTest, IsRenderbuffer) {
+TEST_P(GLES2DecoderTest, IsRenderbuffer) {
   EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
   EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_));
   DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
   EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
 }
 
-TEST_F(GLES2DecoderTest, IsShader) {
+TEST_P(GLES2DecoderTest, IsShader) {
   // IsShader is true as soon as the program is created.
   EXPECT_TRUE(DoIsShader(client_shader_id_));
   DoDeleteShader(client_shader_id_, kServiceShaderId);
   EXPECT_FALSE(DoIsShader(client_shader_id_));
 }
 
-TEST_F(GLES2DecoderTest, IsTexture) {
+TEST_P(GLES2DecoderTest, IsTexture) {
   EXPECT_FALSE(DoIsTexture(client_texture_id_));
   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
   EXPECT_TRUE(DoIsTexture(client_texture_id_));
@@ -3514,1070 +383,7 @@
   EXPECT_FALSE(DoIsTexture(client_texture_id_));
 }
 
-#if 0  // Turn this test on once we allow GL_DEPTH_STENCIL_ATTACHMENT
-TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearDepthStencil) {
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  ClearDepthf depth_cmd;
-  ClearStencil stencil_cmd;
-  FramebufferRenderbuffer cmd;
-  depth_cmd.Init(0.5f);
-  stencil_cmd.Init(123);
-  cmd.Init(
-      GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
-      client_renderbuffer_id_);
-  InSequence sequence;
-  EXPECT_CALL(*gl_, ClearDepth(0.5f))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, ClearStencil(123))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
-      GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
-      kServiceRenderbufferId))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(depth_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_cmd));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-#endif
-
-TEST_F(GLES2DecoderWithShaderTest, VertexAttribPointer) {
-  SetupVertexBuffer();
-  static const GLenum types[] = {
-    GL_BYTE,
-    GL_UNSIGNED_BYTE,
-    GL_SHORT,
-    GL_UNSIGNED_SHORT,
-    GL_FLOAT,
-    GL_FIXED,
-    GL_INT,
-    GL_UNSIGNED_INT,
-  };
-  static const GLsizei sizes[] = {
-    1,
-    1,
-    2,
-    2,
-    4,
-    4,
-    4,
-    4,
-  };
-  static const GLuint indices[] = {
-    0,
-    1,
-    kNumVertexAttribs - 1,
-    kNumVertexAttribs,
-  };
-  static const GLsizei offset_mult[] = {
-    0,
-    0,
-    1,
-    1,
-    2,
-    1000,
-  };
-  static const GLsizei offset_offset[] = {
-    0,
-    1,
-    0,
-    1,
-    0,
-    0,
-  };
-  static const GLsizei stride_mult[] = {
-    -1,
-    0,
-    0,
-    1,
-    1,
-    2,
-    1000,
-  };
-  static const GLsizei stride_offset[] = {
-    0,
-    0,
-    1,
-    0,
-    1,
-    0,
-    0,
-  };
-  for (size_t tt = 0; tt < arraysize(types); ++tt) {
-    GLenum type = types[tt];
-    GLsizei num_bytes = sizes[tt];
-    for (size_t ii = 0; ii < arraysize(indices); ++ii) {
-      GLuint index = indices[ii];
-      for (GLint size = 0; size < 5; ++size) {
-        for (size_t oo = 0; oo < arraysize(offset_mult); ++oo) {
-          GLuint offset = num_bytes * offset_mult[oo] + offset_offset[oo];
-          for (size_t ss = 0; ss < arraysize(stride_mult); ++ss) {
-            GLsizei stride = num_bytes * stride_mult[ss] + stride_offset[ss];
-            for (int normalize = 0; normalize < 2; ++normalize) {
-              bool index_good = index < static_cast<GLuint>(kNumVertexAttribs);
-              bool size_good = (size > 0 && size < 5);
-              bool offset_good = (offset % num_bytes == 0);
-              bool stride_good = (stride % num_bytes == 0) && stride >= 0 &&
-                                 stride <= 255;
-              bool type_good = (type != GL_INT && type != GL_UNSIGNED_INT &&
-                                type != GL_FIXED);
-              bool good = size_good && offset_good && stride_good &&
-                          type_good && index_good;
-              bool call = good && (type != GL_FIXED);
-              if (call) {
-                EXPECT_CALL(*gl_, VertexAttribPointer(
-                    index, size, type, normalize, stride,
-                    BufferOffset(offset)));
-              }
-              VertexAttribPointer cmd;
-              cmd.Init(index, size, type, normalize, stride, offset);
-              EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-              if (good) {
-                EXPECT_EQ(GL_NO_ERROR, GetGLError());
-              } else if (size_good &&
-                         offset_good &&
-                         stride_good &&
-                         type_good &&
-                         !index_good) {
-                EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-              } else if (size_good &&
-                         offset_good &&
-                         stride_good &&
-                         !type_good &&
-                         index_good) {
-                EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-              } else if (size_good &&
-                         offset_good &&
-                         !stride_good &&
-                         type_good &&
-                         index_good) {
-                if (stride < 0 || stride > 255) {
-                  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-                } else {
-                  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-                }
-              } else if (size_good &&
-                         !offset_good &&
-                         stride_good &&
-                         type_good &&
-                         index_good) {
-                EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-              } else if (!size_good &&
-                         offset_good &&
-                         stride_good &&
-                         type_good &&
-                         index_good) {
-                EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-              } else {
-                EXPECT_NE(GL_NO_ERROR, GetGLError());
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-// Test that with an RGB backbuffer if we set the color mask to 1,1,1,1 it is
-// set to 1,1,1,0 at Draw time but is 1,1,1,1 at query time.
-TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMask) {
-  ColorMask cmd;
-  cmd.Init(true, true, true, true);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDirtyState(
-      true,    // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1110,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays draw_cmd;
-  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_COLOR_WRITEMASK, result->GetData()))
-      .Times(0);
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_COLOR_WRITEMASK, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_COLOR_WRITEMASK),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(1, result->GetData()[0]);
-  EXPECT_EQ(1, result->GetData()[1]);
-  EXPECT_EQ(1, result->GetData()[2]);
-  EXPECT_EQ(1, result->GetData()[3]);
-}
-
-// Test that with no depth if we set DepthMask true that it's set to false at
-// draw time but querying it returns true.
-TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferDepthMask) {
-  EXPECT_CALL(*gl_, DepthMask(true))
-      .Times(0)
-      .RetiresOnSaturation();
-  DepthMask cmd;
-  cmd.Init(true);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDirtyState(
-      true,    // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1110,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays draw_cmd;
-  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_WRITEMASK, result->GetData()))
-      .Times(0);
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_DEPTH_WRITEMASK, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_WRITEMASK),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(1, result->GetData()[0]);
-}
-
-// Test that with no stencil if we set the stencil mask it's still set to 0 at
-// draw time but gets our value if we query.
-TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferStencilMask) {
-  const GLint kMask = 123;
-  EXPECT_CALL(*gl_, StencilMask(kMask))
-      .Times(0)
-      .RetiresOnSaturation();
-  StencilMask cmd;
-  cmd.Init(kMask);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDirtyState(
-      true,    // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1110,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays draw_cmd;
-  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_WRITEMASK, result->GetData()))
-      .Times(0);
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_STENCIL_WRITEMASK, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_WRITEMASK),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(kMask, result->GetData()[0]);
-}
-
-// Test that if an FBO is bound we get the correct masks.
-TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMaskFBO) {
-  ColorMask cmd;
-  cmd.Init(true, true, true, true);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  SetupTexture();
-  SetupVertexBuffer();
-  DoEnableVertexAttribArray(0);
-  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
-  DoEnableVertexAttribArray(1);
-  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
-  DoEnableVertexAttribArray(2);
-  DoVertexAttribPointer(2, 2, GL_FLOAT, 0, 0);
-  SetupExpectationsForApplyingDirtyState(
-      true,    // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1110,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays draw_cmd;
-  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Check that no extra calls are made on the next draw.
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Setup Frame buffer.
-  // needs to be 1x1 or else it's not renderable.
-  const GLsizei kWidth = 1;
-  const GLsizei kHeight = 1;
-  const GLenum kFormat = GL_RGB;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  // Pass some data so the texture will be marked as cleared.
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0,
-      kFormat, GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset);
-  DoBindFramebuffer(
-      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      client_texture_id_, kServiceTextureId, 0, GL_NO_ERROR);
-  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
-      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
-      .RetiresOnSaturation();
-
-  // This time state needs to be set.
-  SetupExpectationsForApplyingDirtyState(
-      false,    // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1110,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Check that no extra calls are made on the next draw.
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Unbind
-  DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
-
-  SetupExpectationsForApplyingDirtyState(
-      true,    // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1110,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, ActualAlphaMatchesRequestedAlpha) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_alpha = true;
-  init.request_alpha = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(8))
-      .RetiresOnSaturation();
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_ALPHA_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ALPHA_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(8, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, ActualAlphaDoesNotMatchRequestedAlpha) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_alpha = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(8))
-      .RetiresOnSaturation();
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_ALPHA_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ALPHA_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(0, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, ActualDepthMatchesRequestedDepth) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_depth = true;
-  init.request_depth = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(24))
-      .RetiresOnSaturation();
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(24, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, ActualDepthDoesNotMatchRequestedDepth) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_depth = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(24))
-      .RetiresOnSaturation();
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(0, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, ActualStencilMatchesRequestedStencil) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_stencil = true;
-  init.request_stencil = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(8))
-      .RetiresOnSaturation();
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(8, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, ActualStencilDoesNotMatchRequestedStencil) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_stencil = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(8))
-      .RetiresOnSaturation();
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(0, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, DepthEnableWithDepth) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_depth = true;
-  init.request_depth = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  Enable cmd;
-  cmd.Init(GL_DEPTH_TEST);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  SetupDefaultProgram();
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDirtyState(
-      true,    // Framebuffer is RGB
-      true,    // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1110,  // color bits
-      true,    // depth mask
-      true,    // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays draw_cmd;
-  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_TEST, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_DEPTH_TEST, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_TEST),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(1, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, DepthEnableWithoutRequestedDepth) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_depth = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  Enable cmd;
-  cmd.Init(GL_DEPTH_TEST);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  SetupDefaultProgram();
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDirtyState(
-      true,    // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1110,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays draw_cmd;
-  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_TEST, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_DEPTH_TEST, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_TEST),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(1, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, StencilEnableWithStencil) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_stencil = true;
-  init.request_stencil = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  Enable cmd;
-  cmd.Init(GL_STENCIL_TEST);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  SetupDefaultProgram();
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDirtyState(
-      true,    // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      true,    // Framebuffer has stencil
-      0x1110,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      -1,      // front stencil mask
-      -1,      // back stencil mask
-      true,    // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays draw_cmd;
-  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_TEST, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_STENCIL_TEST, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_TEST),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(1, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, StencilEnableWithoutRequestedStencil) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_stencil = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  Enable cmd;
-  cmd.Init(GL_STENCIL_TEST);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  SetupDefaultProgram();
-  SetupTexture();
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDirtyState(
-      true,    // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1110,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays draw_cmd;
-  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_TEST, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_STENCIL_TEST, shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_TEST),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(1, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, PackedDepthStencilReportsCorrectValues) {
-  InitState init;
-  init.extensions = "GL_OES_packed_depth_stencil";
-  init.gl_version = "opengl es 2.0";
-  init.has_depth = true;
-  init.has_stencil = true;
-  init.request_depth = true;
-  init.request_stencil = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(8))
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(8, result->GetData()[0]);
-  result->size = 0;
-  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(24))
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(24, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, PackedDepthStencilNoRequestedStencil) {
-  InitState init;
-  init.extensions = "GL_OES_packed_depth_stencil";
-  init.gl_version = "opengl es 2.0";
-  init.has_depth = true;
-  init.has_stencil = true;
-  init.request_depth = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(8))
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(0, result->GetData()[0]);
-  result->size = 0;
-  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(24))
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(24, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, PackedDepthStencilRenderbufferDepth) {
-  InitState init;
-  init.extensions = "GL_OES_packed_depth_stencil";
-  init.gl_version = "opengl es 2.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))  // for RenderbufferStoage
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))  // for FramebufferRenderbuffer
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-
-  EXPECT_CALL(*gl_, RenderbufferStorageEXT(
-      GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50))
-      .Times(1)
-      .RetiresOnSaturation();
-  RenderbufferStorage cmd;
-  cmd.Init(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
-      GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
-      kServiceRenderbufferId))
-      .Times(1)
-      .RetiresOnSaturation();
-  FramebufferRenderbuffer fbrb_cmd;
-  fbrb_cmd.Init(
-      GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
-      client_renderbuffer_id_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
-
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(8))
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(0, result->GetData()[0]);
-  result->size = 0;
-  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(24))
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(24, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, PackedDepthStencilRenderbufferStencil) {
-  InitState init;
-  init.extensions = "GL_OES_packed_depth_stencil";
-  init.gl_version = "opengl es 2.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))  // for RenderbufferStoage
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))  // for FramebufferRenderbuffer
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-
-  EXPECT_CALL(*gl_, RenderbufferStorageEXT(
-      GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50))
-      .Times(1)
-      .RetiresOnSaturation();
-  RenderbufferStorage cmd;
-  cmd.Init(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
-      GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
-      kServiceRenderbufferId))
-      .Times(1)
-      .RetiresOnSaturation();
-  FramebufferRenderbuffer fbrb_cmd;
-  fbrb_cmd.Init(
-      GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
-      client_renderbuffer_id_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
-
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  result->size = 0;
-  GetIntegerv cmd2;
-  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(8))
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(8, result->GetData()[0]);
-  result->size = 0;
-  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
-      .WillOnce(SetArgumentPointee<1>(24))
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(
-      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
-      result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(0, result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderTest, GetMultipleIntegervCHROMIUMValidArgs) {
+TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMValidArgs) {
   const GLsizei kCount = 3;
   GLenum* pnames = GetSharedMemoryAs<GLenum*>();
   pnames[0] = GL_DEPTH_WRITEMASK;
@@ -4591,29 +397,31 @@
     num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]);
   }
   const GLsizei result_size = num_results * sizeof(*results);
-  memset(results,  0, result_size);
+  memset(results, 0, result_size);
 
   const GLint kSentinel = 0x12345678;
   results[num_results] = kSentinel;
 
   GetMultipleIntegervCHROMIUM cmd;
-  cmd.Init(
-      kSharedMemoryId, kSharedMemoryOffset, kCount,
-      kSharedMemoryId, kSharedMemoryOffset + sizeof(*pnames) * kCount,
-      result_size);
+  cmd.Init(kSharedMemoryId,
+           kSharedMemoryOffset,
+           kCount,
+           kSharedMemoryId,
+           kSharedMemoryOffset + sizeof(*pnames) * kCount,
+           result_size);
 
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(1, results[0]);  // Depth writemask
-  EXPECT_EQ(1, results[1]);  // color writemask red
-  EXPECT_EQ(1, results[2]);  // color writemask green
-  EXPECT_EQ(1, results[3]);  // color writemask blue
-  EXPECT_EQ(1, results[4]);  // color writemask alpha
-  EXPECT_EQ(-1, results[5]);  // stencil writemask alpha
+  EXPECT_EQ(1, results[0]);                    // Depth writemask
+  EXPECT_EQ(1, results[1]);                    // color writemask red
+  EXPECT_EQ(1, results[2]);                    // color writemask green
+  EXPECT_EQ(1, results[3]);                    // color writemask blue
+  EXPECT_EQ(1, results[4]);                    // color writemask alpha
+  EXPECT_EQ(-1, results[5]);                   // stencil writemask alpha
   EXPECT_EQ(kSentinel, results[num_results]);  // End of results
 }
 
-TEST_F(GLES2DecoderTest, GetMultipleIntegervCHROMIUMInvalidArgs) {
+TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMInvalidArgs) {
   const GLsizei kCount = 3;
   // Offset the pnames because GLGetError will use the first uint32.
   const uint32 kPnameOffset = sizeof(uint32);
@@ -4629,66 +437,82 @@
     num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]);
   }
   const GLsizei result_size = num_results * sizeof(*results);
-  memset(results,  0, result_size);
+  memset(results, 0, result_size);
 
   const GLint kSentinel = 0x12345678;
   results[num_results] = kSentinel;
 
   GetMultipleIntegervCHROMIUM cmd;
   // Check bad pnames pointer.
-  cmd.Init(
-      kInvalidSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
-      kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
-      result_size);
+  cmd.Init(kInvalidSharedMemoryId,
+           kSharedMemoryOffset + kPnameOffset,
+           kCount,
+           kSharedMemoryId,
+           kSharedMemoryOffset + kResultsOffset,
+           result_size);
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
   // Check bad pnames pointer.
-  cmd.Init(
-      kSharedMemoryId, kInvalidSharedMemoryOffset, kCount,
-      kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
-      result_size);
+  cmd.Init(kSharedMemoryId,
+           kInvalidSharedMemoryOffset,
+           kCount,
+           kSharedMemoryId,
+           kSharedMemoryOffset + kResultsOffset,
+           result_size);
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
   // Check bad count.
-  cmd.Init(
-      kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, -1,
-      kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
-      result_size);
+  cmd.Init(kSharedMemoryId,
+           kSharedMemoryOffset + kPnameOffset,
+           -1,
+           kSharedMemoryId,
+           kSharedMemoryOffset + kResultsOffset,
+           result_size);
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
   // Check bad results pointer.
-  cmd.Init(
-      kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
-      kInvalidSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
-      result_size);
+  cmd.Init(kSharedMemoryId,
+           kSharedMemoryOffset + kPnameOffset,
+           kCount,
+           kInvalidSharedMemoryId,
+           kSharedMemoryOffset + kResultsOffset,
+           result_size);
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
   // Check bad results pointer.
-  cmd.Init(
-      kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
-      kSharedMemoryId, kInvalidSharedMemoryOffset,
-      result_size);
+  cmd.Init(kSharedMemoryId,
+           kSharedMemoryOffset + kPnameOffset,
+           kCount,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset,
+           result_size);
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
   // Check bad size.
-  cmd.Init(
-      kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
-      kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
-      result_size + 1);
+  cmd.Init(kSharedMemoryId,
+           kSharedMemoryOffset + kPnameOffset,
+           kCount,
+           kSharedMemoryId,
+           kSharedMemoryOffset + kResultsOffset,
+           result_size + 1);
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
   // Check bad size.
-  cmd.Init(
-      kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
-      kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
-      result_size - 1);
+  cmd.Init(kSharedMemoryId,
+           kSharedMemoryOffset + kPnameOffset,
+           kCount,
+           kSharedMemoryId,
+           kSharedMemoryOffset + kResultsOffset,
+           result_size - 1);
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
   // Check bad enum.
-  cmd.Init(
-      kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
-      kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
-      result_size);
+  cmd.Init(kSharedMemoryId,
+           kSharedMemoryOffset + kPnameOffset,
+           kCount,
+           kSharedMemoryId,
+           kSharedMemoryOffset + kResultsOffset,
+           result_size);
   GLenum temp = pnames[2];
   pnames[2] = GL_TRUE;
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -4707,925 +531,7 @@
   EXPECT_EQ(kSentinel, results[num_results]);  // End of results
 }
 
-TEST_F(GLES2DecoderTest, TexImage2DRedefinitionSucceeds) {
-  const int kWidth = 16;
-  const int kHeight = 8;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  EXPECT_CALL(*gl_, GetError())
-      .WillRepeatedly(Return(GL_NO_ERROR));
-  for (int ii = 0; ii < 2; ++ii) {
-    TexImage2D cmd;
-    if (ii == 0) {
-      EXPECT_CALL(*gl_, TexImage2D(
-          GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
-          GL_UNSIGNED_BYTE, _))
-          .Times(1)
-          .RetiresOnSaturation();
-      cmd.Init(
-          GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
-          GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset);
-    } else {
-      SetupClearTextureExpectations(
-          kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
-          0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, kWidth, kHeight);
-      cmd.Init(
-          GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
-          GL_UNSIGNED_BYTE, 0, 0);
-    }
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_CALL(*gl_, TexSubImage2D(
-        GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight - 1, GL_RGBA, GL_UNSIGNED_BYTE,
-        shared_memory_address_))
-        .Times(1)
-        .RetiresOnSaturation();
-    // Consider this TexSubImage2D command part of the previous TexImage2D
-    // (last GL_TRUE argument). It will be skipped if there are bugs in the
-    // redefinition case.
-    TexSubImage2D cmd2;
-    cmd2.Init(
-        GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight - 1, GL_RGBA, GL_UNSIGNED_BYTE,
-        kSharedMemoryId, kSharedMemoryOffset, GL_TRUE);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  }
-}
-
-TEST_F(GLES2DecoderTest, TexImage2DGLError) {
-  GLenum target = GL_TEXTURE_2D;
-  GLint level = 0;
-  GLenum internal_format = GL_RGBA;
-  GLsizei width = 2;
-  GLsizei height = 4;
-  GLint border = 0;
-  GLenum format = GL_RGBA;
-  GLenum type = GL_UNSIGNED_BYTE;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  TextureManager* manager = group().texture_manager();
-  TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
-  ASSERT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_OUT_OF_MEMORY))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, TexImage2D(target, level, internal_format,
-                               width, height, border, format, type, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  TexImage2D cmd;
-  cmd.Init(target, level, internal_format, width, height, border, format,
-           type, kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
-}
-
-TEST_F(GLES2DecoderTest, BufferDataGLError) {
-  GLenum target = GL_ARRAY_BUFFER;
-  GLsizeiptr size = 4;
-  DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
-  BufferManager* manager = group().buffer_manager();
-  Buffer* buffer = manager->GetBuffer(client_buffer_id_);
-  ASSERT_TRUE(buffer != NULL);
-  EXPECT_EQ(0, buffer->size());
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_OUT_OF_MEMORY))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, BufferData(target, size, _, GL_STREAM_DRAW))
-      .Times(1)
-      .RetiresOnSaturation();
-  BufferData cmd;
-  cmd.Init(target, size, 0, 0, GL_STREAM_DRAW);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-  EXPECT_EQ(0, buffer->size());
-}
-
-TEST_F(GLES2DecoderTest, CopyTexImage2DGLError) {
-  GLenum target = GL_TEXTURE_2D;
-  GLint level = 0;
-  GLenum internal_format = GL_RGBA;
-  GLsizei width = 2;
-  GLsizei height = 4;
-  GLint border = 0;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  TextureManager* manager = group().texture_manager();
-  TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
-  ASSERT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_OUT_OF_MEMORY))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, CopyTexImage2D(
-      target, level, internal_format, 0, 0, width, height, border))
-      .Times(1)
-      .RetiresOnSaturation();
-  CopyTexImage2D cmd;
-  cmd.Init(target, level, internal_format, 0, 0, width, height, border);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
-}
-
-TEST_F(GLES2DecoderTest, FramebufferRenderbufferGLError) {
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_OUT_OF_MEMORY))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      kServiceRenderbufferId))
-      .Times(1)
-      .RetiresOnSaturation();
-  FramebufferRenderbuffer cmd;
-  cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      client_renderbuffer_id_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, FramebufferTexture2DGLError) {
-  const GLsizei kWidth = 5;
-  const GLsizei kHeight = 3;
-  const GLenum kFormat = GL_RGB;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0,
-               kFormat, GL_UNSIGNED_BYTE, 0, 0);
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_OUT_OF_MEMORY))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kServiceTextureId, 0))
-      .Times(1)
-      .RetiresOnSaturation();
-  FramebufferTexture2D fbtex_cmd;
-  fbtex_cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_,
-      0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, RenderbufferStorageGLError) {
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_OUT_OF_MEMORY))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, RenderbufferStorageEXT(
-      GL_RENDERBUFFER, GL_RGBA, 100, 50))
-      .Times(1)
-      .RetiresOnSaturation();
-  RenderbufferStorage cmd;
-  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 100, 50);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, RenderbufferStorageBadArgs) {
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  RenderbufferStorage cmd;
-  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, TestHelper::kMaxRenderbufferSize + 1, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 1, TestHelper::kMaxRenderbufferSize + 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest,
-       RenderbufferStorageMultisampleCHROMIUMGLError) {
-  InitState init;
-  init.extensions = "GL_EXT_framebuffer_multisample";
-  init.gl_version = "2.1";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_OUT_OF_MEMORY))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, RenderbufferStorageMultisampleEXT(
-      GL_RENDERBUFFER, 1, GL_RGBA, 100, 50))
-      .Times(1)
-      .RetiresOnSaturation();
-  RenderbufferStorageMultisampleCHROMIUM cmd;
-  cmd.Init(GL_RENDERBUFFER, 1, GL_RGBA4, 100, 50);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest,
-       RenderbufferStorageMultisampleCHROMIUMBadArgs) {
-  InitState init;
-  init.extensions = "GL_EXT_framebuffer_multisample";
-  init.gl_version = "2.1";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  EXPECT_CALL(*gl_, RenderbufferStorageMultisampleEXT(_, _, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  RenderbufferStorageMultisampleCHROMIUM cmd;
-  cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples + 1,
-           GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples,
-           GL_RGBA4, TestHelper::kMaxRenderbufferSize + 1, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples,
-           GL_RGBA4, 1, TestHelper::kMaxRenderbufferSize + 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleCHROMIUM) {
-  InitState init;
-  init.extensions = "GL_EXT_framebuffer_multisample";
-  init.gl_version = "2.1";
-  InitDecoder(init);
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  InSequence sequence;
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(
-      *gl_,
-      RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
-                                        TestHelper::kMaxSamples,
-                                        GL_RGBA,
-                                        TestHelper::kMaxRenderbufferSize,
-                                        1))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  RenderbufferStorageMultisampleCHROMIUM cmd;
-  cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples,
-           GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest,
-       RenderbufferStorageMultisampleEXTNotSupported) {
-  InitState init;
-  init.extensions = "GL_EXT_framebuffer_multisample";
-  init.gl_version = "2.1";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  InSequence sequence;
-  // GL_EXT_framebuffer_multisample uses RenderbufferStorageMultisampleCHROMIUM.
-  RenderbufferStorageMultisampleEXT cmd;
-  cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples,
-           GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-class GLES2DecoderMultisampledRenderToTextureTest
-    : public GLES2DecoderTestWithExtensionsOnGLES2 {};
-
-TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
-       NotCompatibleWithRenderbufferStorageMultisampleCHROMIUM) {
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  RenderbufferStorageMultisampleCHROMIUM cmd;
-  cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples,
-           GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
-       RenderbufferStorageMultisampleEXT) {
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  InSequence sequence;
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  if (strstr(GetParam(), "GL_IMG_multisampled_render_to_texture")) {
-    EXPECT_CALL(
-        *gl_,
-        RenderbufferStorageMultisampleIMG(GL_RENDERBUFFER,
-                                          TestHelper::kMaxSamples,
-                                          GL_RGBA,
-                                          TestHelper::kMaxRenderbufferSize,
-                                          1))
-        .Times(1)
-        .RetiresOnSaturation();
-  } else {
-    EXPECT_CALL(
-        *gl_,
-        RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
-                                          TestHelper::kMaxSamples,
-                                          GL_RGBA,
-                                          TestHelper::kMaxRenderbufferSize,
-                                          1))
-        .Times(1)
-        .RetiresOnSaturation();
-  }
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  RenderbufferStorageMultisampleEXT cmd;
-  cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples,
-           GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-INSTANTIATE_TEST_CASE_P(
-    GLES2DecoderMultisampledRenderToTextureTests,
-    GLES2DecoderMultisampledRenderToTextureTest,
-    ::testing::Values("GL_EXT_multisampled_render_to_texture",
-                      "GL_IMG_multisampled_render_to_texture"));
-
-TEST_F(GLES2DecoderTest, ReadPixelsGLError) {
-  GLenum kFormat = GL_RGBA;
-  GLint x = 0;
-  GLint y = 0;
-  GLsizei width = 2;
-  GLsizei height = 4;
-  typedef ReadPixels::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  uint32 result_shm_id = kSharedMemoryId;
-  uint32 result_shm_offset = kSharedMemoryOffset;
-  uint32 pixels_shm_id = kSharedMemoryId;
-  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_OUT_OF_MEMORY))
-      .RetiresOnSaturation();
-  EXPECT_CALL(
-      *gl_, ReadPixels(x, y, width, height, kFormat, GL_UNSIGNED_BYTE, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  ReadPixels cmd;
-  cmd.Init(x, y, width, height, kFormat, GL_UNSIGNED_BYTE,
-           pixels_shm_id, pixels_shm_offset,
-           result_shm_id, result_shm_offset,
-           false);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
-}
-
-TEST_F(GLES2DecoderCompressedFormatsTest, GetCompressedTextureFormatsS3TC) {
-  const GLenum formats[] = {
-    GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
-    GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
-    GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
-    GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
-  };
-  CheckFormats("GL_EXT_texture_compression_s3tc", formats, 4);
-}
-
-TEST_F(GLES2DecoderCompressedFormatsTest, GetCompressedTextureFormatsATC) {
-  const GLenum formats[] = {
-    GL_ATC_RGB_AMD,
-    GL_ATC_RGBA_EXPLICIT_ALPHA_AMD,
-    GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD
-  };
-  CheckFormats("GL_AMD_compressed_ATC_texture", formats, 3);
-}
-
-TEST_F(GLES2DecoderCompressedFormatsTest, GetCompressedTextureFormatsPVRTC) {
-  const GLenum formats[] = {
-    GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG,
-    GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,
-    GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,
-    GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
-  };
-  CheckFormats("GL_IMG_texture_compression_pvrtc", formats, 4);
-}
-
-TEST_F(GLES2DecoderCompressedFormatsTest, GetCompressedTextureFormatsETC1) {
-  const GLenum formats[] = {
-    GL_ETC1_RGB8_OES
-  };
-  CheckFormats("GL_OES_compressed_ETC1_RGB8_texture", formats, 1);
-}
-
-TEST_F(GLES2DecoderManualInitTest, GetNoCompressedTextureFormats) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  GetIntegerv cmd;
-  result->size = 0;
-  EXPECT_CALL(*gl_, GetIntegerv(_, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  cmd.Init(
-      GL_NUM_COMPRESSED_TEXTURE_FORMATS,
-      shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(1, result->GetNumResults());
-  GLint num_formats = result->GetData()[0];
-  EXPECT_EQ(0, num_formats);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  result->size = 0;
-  cmd.Init(
-      GL_COMPRESSED_TEXTURE_FORMATS,
-      shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(num_formats, result->GetNumResults());
-
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, CompressedTexImage2DBucketBadBucket) {
-  InitState init;
-  init.extensions = "GL_EXT_texture_compression_s3tc";
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  const uint32 kBadBucketId = 123;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  CompressedTexImage2DBucket cmd;
-  cmd.Init(
-      GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 4, 4, 0,
-      kBadBucketId);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-  CompressedTexSubImage2DBucket cmd2;
-  cmd2.Init(
-      GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
-      kBadBucketId);
-  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
-}
-
-namespace {
-
-struct S3TCTestData {
-  GLenum format;
-  size_t block_size;
-};
-
-}  // anonymous namespace.
-
-TEST_F(GLES2DecoderManualInitTest, CompressedTexImage2DS3TC) {
-  InitState init;
-  init.extensions = "GL_EXT_texture_compression_s3tc";
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  const uint32 kBucketId = 123;
-  CommonDecoder::Bucket* bucket = decoder_->CreateBucket(kBucketId);
-  ASSERT_TRUE(bucket != NULL);
-
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-
-  static const S3TCTestData test_data[] = {
-    { GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, },
-    { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, },
-    { GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 16, },
-    { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 16, },
-  };
-
-  for (size_t ii = 0; ii < arraysize(test_data); ++ii) {
-    const S3TCTestData& test = test_data[ii];
-    CompressedTexImage2DBucket cmd;
-    // test small width.
-    DoCompressedTexImage2D(
-        GL_TEXTURE_2D, 0, test.format, 2, 4, 0, test.block_size,
-        kBucketId);
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    // test bad width.
-    cmd.Init(
-        GL_TEXTURE_2D, 0, test.format, 5, 4, 0,
-        kBucketId);
-    bucket->SetSize(test.block_size * 2);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-
-    // test small height.
-    DoCompressedTexImage2D(
-        GL_TEXTURE_2D, 0, test.format, 4, 2, 0, test.block_size,
-        kBucketId);
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    // test too bad height.
-    cmd.Init(
-        GL_TEXTURE_2D, 0, test.format, 4, 5, 0,
-        kBucketId);
-    bucket->SetSize(test.block_size * 2);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-
-    // test small for level 0.
-    DoCompressedTexImage2D(
-        GL_TEXTURE_2D, 0, test.format, 1, 1, 0, test.block_size,
-        kBucketId);
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    // test small for level 0.
-    DoCompressedTexImage2D(
-        GL_TEXTURE_2D, 0, test.format, 2, 2, 0, test.block_size,
-        kBucketId);
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    // test size too large.
-    cmd.Init(
-        GL_TEXTURE_2D, 0, test.format, 4, 4, 0,
-        kBucketId);
-    bucket->SetSize(test.block_size * 2);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-
-    // test size too small.
-    cmd.Init(
-        GL_TEXTURE_2D, 0, test.format, 4, 4, 0,
-        kBucketId);
-    bucket->SetSize(test.block_size / 2);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-
-    // test with 3 mips.
-    DoCompressedTexImage2D(
-        GL_TEXTURE_2D, 0, test.format, 4, 4, 0, test.block_size, kBucketId);
-    DoCompressedTexImage2D(
-        GL_TEXTURE_2D, 1, test.format, 2, 2, 0, test.block_size, kBucketId);
-    DoCompressedTexImage2D(
-        GL_TEXTURE_2D, 2, test.format, 1, 1, 0, test.block_size, kBucketId);
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    // Test a 16x16
-    DoCompressedTexImage2D(
-        GL_TEXTURE_2D, 0, test.format, 16, 16, 0, test.block_size * 4 * 4,
-        kBucketId);
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    CompressedTexSubImage2DBucket sub_cmd;
-    bucket->SetSize(test.block_size);
-    // Test sub image bad xoffset
-    sub_cmd.Init(
-        GL_TEXTURE_2D, 0, 1, 0, 4, 4, test.format, kBucketId);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
-    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-
-    // Test sub image bad yoffset
-    sub_cmd.Init(
-        GL_TEXTURE_2D, 0, 0, 2, 4, 4, test.format, kBucketId);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
-    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-
-    // Test sub image bad width
-    bucket->SetSize(test.block_size * 2);
-    sub_cmd.Init(
-        GL_TEXTURE_2D, 0, 0, 0, 5, 4, test.format, kBucketId);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
-    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-
-    // Test sub image bad height
-    sub_cmd.Init(
-        GL_TEXTURE_2D, 0, 0, 0, 4, 5, test.format, kBucketId);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
-    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-
-    // Test sub image bad size
-    bucket->SetSize(test.block_size + 1);
-    sub_cmd.Init(
-        GL_TEXTURE_2D, 0, 0, 0, 4, 4, test.format, kBucketId);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
-    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-
-    for (GLint yoffset = 0; yoffset <= 8; yoffset += 4) {
-      for (GLint xoffset = 0; xoffset <= 8; xoffset += 4) {
-        for (GLsizei height = 4; height <= 8; height +=4 ) {
-          for (GLsizei width = 4; width <= 8; width += 4) {
-            GLsizei size = test.block_size * (width / 4) * (height / 4);
-            bucket->SetSize(size);
-            EXPECT_CALL(*gl_, CompressedTexSubImage2D(
-                GL_TEXTURE_2D, 0, xoffset, yoffset, width, height, test.format,
-                size, _))
-                .Times(1)
-                .RetiresOnSaturation();
-            sub_cmd.Init(
-                GL_TEXTURE_2D, 0, xoffset, yoffset, width, height, test.format,
-                kBucketId);
-            EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
-            EXPECT_EQ(GL_NO_ERROR, GetGLError());
-          }
-        }
-      }
-    }
-  }
-}
-
-TEST_F(GLES2DecoderManualInitTest, CompressedTexImage2DETC1) {
-  InitState init;
-  init.extensions = "GL_OES_compressed_ETC1_RGB8_texture";
-  init.gl_version = "opengl es 2.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  const uint32 kBucketId = 123;
-  CommonDecoder::Bucket* bucket = decoder_->CreateBucket(kBucketId);
-  ASSERT_TRUE(bucket != NULL);
-
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-
-  const GLenum kFormat = GL_ETC1_RGB8_OES;
-  const size_t kBlockSize = 8;
-
-  CompressedTexImage2DBucket cmd;
-  // test small width.
-  DoCompressedTexImage2D(GL_TEXTURE_2D, 0, kFormat, 4, 8, 0, 16, kBucketId);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // test small height.
-  DoCompressedTexImage2D(GL_TEXTURE_2D, 0, kFormat, 8, 4, 0, 16, kBucketId);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // test size too large.
-  cmd.Init(GL_TEXTURE_2D, 0, kFormat, 4, 4, 0, kBucketId);
-  bucket->SetSize(kBlockSize * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-
-  // test size too small.
-  cmd.Init(GL_TEXTURE_2D, 0, kFormat, 4, 4, 0, kBucketId);
-  bucket->SetSize(kBlockSize / 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-
-  // Test a 16x16
-  DoCompressedTexImage2D(
-      GL_TEXTURE_2D, 0, kFormat, 16, 16, 0, kBlockSize * 16, kBucketId);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Test CompressedTexSubImage not allowed
-  CompressedTexSubImage2DBucket sub_cmd;
-  bucket->SetSize(kBlockSize);
-  sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 4, 4, kFormat, kBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-
-  // Test TexSubImage not allowed for ETC1 compressed texture
-  TextureRef* texture_ref = GetTexture(client_texture_id_);
-  ASSERT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  GLenum type, internal_format;
-  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
-  EXPECT_EQ(kFormat, internal_format);
-  TexSubImage2D texsub_cmd;
-  texsub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE,
-           kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(texsub_cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-
-  // Test CopyTexSubImage not allowed for ETC1 compressed texture
-  CopyTexSubImage2D copy_cmd;
-  copy_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetProgramInfoCHROMIUMValidArgs) {
-  const uint32 kBucketId = 123;
-  GetProgramInfoCHROMIUM cmd;
-  cmd.Init(client_program_id_, kBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
-  EXPECT_GT(bucket->size(), 0u);
-}
-
-TEST_F(GLES2DecoderWithShaderTest, GetProgramInfoCHROMIUMInvalidArgs) {
-  const uint32 kBucketId = 123;
-  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
-  EXPECT_TRUE(bucket == NULL);
-  GetProgramInfoCHROMIUM cmd;
-  cmd.Init(kInvalidClientId, kBucketId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  bucket = decoder_->GetBucket(kBucketId);
-  ASSERT_TRUE(bucket != NULL);
-  EXPECT_EQ(sizeof(ProgramInfoHeader), bucket->size());
-  ProgramInfoHeader* info = bucket->GetDataAs<ProgramInfoHeader*>(
-      0, sizeof(ProgramInfoHeader));
-  ASSERT_TRUE(info != 0);
-  EXPECT_EQ(0u, info->link_status);
-  EXPECT_EQ(0u, info->num_attribs);
-  EXPECT_EQ(0u, info->num_uniforms);
-}
-
-TEST_F(GLES2DecoderManualInitTest, EGLImageExternalBindTexture) {
-  InitState init;
-  init.extensions = "GL_OES_EGL_image_external";
-  init.gl_version = "opengl es 2.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_EXTERNAL_OES, kNewServiceId));
-  EXPECT_CALL(*gl_, GenTextures(1, _))
-      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
-  BindTexture cmd;
-  cmd.Init(GL_TEXTURE_EXTERNAL_OES, kNewClientId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  TextureRef* texture_ref = GetTexture(kNewClientId);
-  EXPECT_TRUE(texture_ref != NULL);
-  EXPECT_TRUE(texture_ref->texture()->target() == GL_TEXTURE_EXTERNAL_OES);
-}
-
-TEST_F(GLES2DecoderManualInitTest, EGLImageExternalGetBinding) {
-  InitState init;
-  init.extensions = "GL_OES_EGL_image_external";
-  init.gl_version = "opengl es 2.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES,
-                                result->GetData()))
-      .Times(0);
-  result->size = 0;
-  GetIntegerv cmd;
-  cmd.Init(GL_TEXTURE_BINDING_EXTERNAL_OES,
-           shared_memory_id_,
-           shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
-      GL_TEXTURE_BINDING_EXTERNAL_OES), result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(client_texture_id_, (uint32)result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, EGLImageExternalTextureDefaults) {
-  InitState init;
-  init.extensions = "GL_OES_EGL_image_external";
-  init.gl_version = "opengl es 2.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
-
-  TextureRef* texture_ref = GetTexture(client_texture_id_);
-  EXPECT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  EXPECT_TRUE(texture->target() == GL_TEXTURE_EXTERNAL_OES);
-  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
-  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
-  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
-}
-
-TEST_F(GLES2DecoderManualInitTest, EGLImageExternalTextureParam) {
-  InitState init;
-  init.extensions = "GL_OES_EGL_image_external";
-  init.gl_version = "opengl es 2.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
-
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_EXTERNAL_OES,
-                                  GL_TEXTURE_MIN_FILTER,
-                                  GL_NEAREST));
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_EXTERNAL_OES,
-                                  GL_TEXTURE_MIN_FILTER,
-                                  GL_LINEAR));
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_EXTERNAL_OES,
-                                  GL_TEXTURE_WRAP_S,
-                                  GL_CLAMP_TO_EDGE));
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_EXTERNAL_OES,
-                                  GL_TEXTURE_WRAP_T,
-                                  GL_CLAMP_TO_EDGE));
-  TexParameteri cmd;
-  cmd.Init(GL_TEXTURE_EXTERNAL_OES,
-           GL_TEXTURE_MIN_FILTER,
-           GL_NEAREST);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  cmd.Init(GL_TEXTURE_EXTERNAL_OES,
-           GL_TEXTURE_MIN_FILTER,
-           GL_LINEAR);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  cmd.Init(GL_TEXTURE_EXTERNAL_OES,
-           GL_TEXTURE_WRAP_S,
-           GL_CLAMP_TO_EDGE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  cmd.Init(GL_TEXTURE_EXTERNAL_OES,
-           GL_TEXTURE_WRAP_T,
-           GL_CLAMP_TO_EDGE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  TextureRef* texture_ref = GetTexture(client_texture_id_);
-  EXPECT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  EXPECT_TRUE(texture->target() == GL_TEXTURE_EXTERNAL_OES);
-  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
-  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
-  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
-}
-
-TEST_F(GLES2DecoderManualInitTest, EGLImageExternalTextureParamInvalid) {
-  InitState init;
-  init.extensions = "GL_OES_EGL_image_external";
-  init.gl_version = "opengl es 2.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
-
-  TexParameteri cmd;
-  cmd.Init(GL_TEXTURE_EXTERNAL_OES,
-           GL_TEXTURE_MIN_FILTER,
-           GL_NEAREST_MIPMAP_NEAREST);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-
-  cmd.Init(GL_TEXTURE_EXTERNAL_OES,
-           GL_TEXTURE_WRAP_S,
-           GL_REPEAT);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-
-  cmd.Init(GL_TEXTURE_EXTERNAL_OES,
-           GL_TEXTURE_WRAP_T,
-           GL_REPEAT);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-
-  TextureRef* texture_ref = GetTexture(client_texture_id_);
-  EXPECT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  EXPECT_TRUE(texture->target() == GL_TEXTURE_EXTERNAL_OES);
-  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
-  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
-  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
-}
-
-TEST_F(GLES2DecoderManualInitTest, EGLImageExternalTexImage2DError) {
-  InitState init;
-  init.extensions = "GL_OES_EGL_image_external";
-  init.gl_version = "opengl es 2.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  GLenum target = GL_TEXTURE_EXTERNAL_OES;
-  GLint level = 0;
-  GLenum internal_format = GL_RGBA;
-  GLsizei width = 2;
-  GLsizei height = 4;
-  GLint border = 0;
-  GLenum format = GL_RGBA;
-  GLenum type = GL_UNSIGNED_BYTE;
-  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
-  ASSERT_TRUE(GetTexture(client_texture_id_) != NULL);
-  TexImage2D cmd;
-  cmd.Init(target, level, internal_format, width, height, border, format,
-           type, kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-
-  // TexImage2D is not allowed with GL_TEXTURE_EXTERNAL_OES targets.
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) {
+TEST_P(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) {
   InitState init;
   init.gl_version = "3.0";
   InitDecoder(init);
@@ -5651,1381 +557,25 @@
   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
 }
 
-TEST_F(GLES2DecoderManualInitTest, DefaultTextureZero) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-
-  BindTexture cmd1;
-  cmd1.Init(GL_TEXTURE_2D, 0);
-  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  BindTexture cmd2;
-  cmd2.Init(GL_TEXTURE_CUBE_MAP, 0);
-  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, 0));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, DefaultTextureBGR) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  BindTexture cmd1;
-  cmd1.Init(GL_TEXTURE_2D, 0);
-  EXPECT_CALL(
-      *gl_, BindTexture(GL_TEXTURE_2D, TestHelper::kServiceDefaultTexture2dId));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  BindTexture cmd2;
-  cmd2.Init(GL_TEXTURE_CUBE_MAP, 0);
-  EXPECT_CALL(*gl_,
-              BindTexture(GL_TEXTURE_CUBE_MAP,
-                          TestHelper::kServiceDefaultTextureCubemapId));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-// Test that default texture 0 is immutable.
-TEST_F(GLES2DecoderManualInitTest, NoDefaultTexParameterf) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-
-  {
-    BindTexture cmd1;
-    cmd1.Init(GL_TEXTURE_2D, 0);
-    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    TexParameterf cmd2;
-    cmd2.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  }
-
-  {
-    BindTexture cmd1;
-    cmd1.Init(GL_TEXTURE_CUBE_MAP, 0);
-    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, 0));
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    TexParameterf cmd2;
-    cmd2.Init(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  }
-}
-
-TEST_F(GLES2DecoderManualInitTest, NoDefaultTexParameteri) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-
-  {
-    BindTexture cmd1;
-    cmd1.Init(GL_TEXTURE_2D, 0);
-    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    TexParameteri cmd2;
-    cmd2.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  }
-
-  {
-    BindTexture cmd1;
-    cmd1.Init(GL_TEXTURE_CUBE_MAP, 0);
-    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, 0));
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    TexParameteri cmd2;
-    cmd2.Init(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  }
-}
-
-TEST_F(GLES2DecoderManualInitTest, NoDefaultTexParameterfv) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-
-  {
-    BindTexture cmd1;
-    cmd1.Init(GL_TEXTURE_2D, 0);
-    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    TexParameterfv cmd2;
-    cmd2.Init(GL_TEXTURE_2D,
-              GL_TEXTURE_MAG_FILTER,
-              shared_memory_id_,
-              shared_memory_offset_);
-    GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST;
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  }
-
-  {
-    BindTexture cmd1;
-    cmd1.Init(GL_TEXTURE_CUBE_MAP, 0);
-    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, 0));
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    TexParameterfv cmd2;
-    cmd2.Init(GL_TEXTURE_CUBE_MAP,
-              GL_TEXTURE_MAG_FILTER,
-              shared_memory_id_,
-              shared_memory_offset_);
-    GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST;
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  }
-}
-
-TEST_F(GLES2DecoderManualInitTest, NoDefaultTexParameteriv) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-
-  {
-    BindTexture cmd1;
-    cmd1.Init(GL_TEXTURE_2D, 0);
-    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    TexParameteriv cmd2;
-    cmd2.Init(GL_TEXTURE_2D,
-              GL_TEXTURE_MAG_FILTER,
-              shared_memory_id_,
-              shared_memory_offset_);
-    GetSharedMemoryAs<GLint*>()[0] = GL_NEAREST;
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  }
-
-  {
-    BindTexture cmd1;
-    cmd1.Init(GL_TEXTURE_CUBE_MAP, 0);
-    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, 0));
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-    TexParameteriv cmd2;
-    cmd2.Init(GL_TEXTURE_CUBE_MAP,
-              GL_TEXTURE_MAG_FILTER,
-              shared_memory_id_,
-              shared_memory_offset_);
-    GetSharedMemoryAs<GLint*>()[0] = GL_NEAREST;
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  }
-}
-
-TEST_F(GLES2DecoderManualInitTest, NoDefaultTexImage2D) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-
-  BindTexture cmd1;
-  cmd1.Init(GL_TEXTURE_2D, 0);
-  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  TexImage2D cmd2;
-  cmd2.Init(GL_TEXTURE_2D,
-            0,
-            GL_RGBA,
-            2,
-            2,
-            0,
-            GL_RGBA,
-            GL_UNSIGNED_BYTE,
-            kSharedMemoryId,
-            kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, NoDefaultTexSubImage2D) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-
-  BindTexture cmd1;
-  cmd1.Init(GL_TEXTURE_2D, 0);
-  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  TexSubImage2D cmd2;
-  cmd2.Init(GL_TEXTURE_2D,
-            0,
-            1,
-            1,
-            1,
-            1,
-            GL_RGBA,
-            GL_UNSIGNED_BYTE,
-            kSharedMemoryId,
-            kSharedMemoryOffset,
-            GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleBindTexture) {
-  InitState init;
-  init.extensions = "GL_ARB_texture_rectangle";
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_RECTANGLE_ARB, kNewServiceId));
-  EXPECT_CALL(*gl_, GenTextures(1, _))
-     .WillOnce(SetArgumentPointee<1>(kNewServiceId));
-  BindTexture cmd;
-  cmd.Init(GL_TEXTURE_RECTANGLE_ARB, kNewClientId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  Texture* texture = GetTexture(kNewClientId)->texture();
-  EXPECT_TRUE(texture != NULL);
-  EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
-}
-
-TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleGetBinding) {
-  InitState init;
-  init.extensions = "GL_ARB_texture_rectangle";
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindTexture(
-      GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB,
-                                result->GetData()))
-      .Times(0);
-  result->size = 0;
-  GetIntegerv cmd;
-  cmd.Init(GL_TEXTURE_BINDING_RECTANGLE_ARB,
-           shared_memory_id_,
-           shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
-      GL_TEXTURE_BINDING_RECTANGLE_ARB), result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_EQ(client_texture_id_, (uint32)result->GetData()[0]);
-}
-
-TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTextureDefaults) {
-  InitState init;
-  init.extensions = "GL_ARB_texture_rectangle";
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindTexture(
-      GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
-
-  Texture* texture = GetTexture(client_texture_id_)->texture();
-  EXPECT_TRUE(texture != NULL);
-  EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
-  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
-  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
-  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
-}
-
-TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParam) {
-  InitState init;
-  init.extensions = "GL_ARB_texture_rectangle";
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  DoBindTexture(
-      GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
-
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
-                                  GL_TEXTURE_MIN_FILTER,
-                                  GL_NEAREST));
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
-                                  GL_TEXTURE_MIN_FILTER,
-                                  GL_LINEAR));
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
-                                  GL_TEXTURE_WRAP_S,
-                                  GL_CLAMP_TO_EDGE));
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
-                                  GL_TEXTURE_WRAP_T,
-                                  GL_CLAMP_TO_EDGE));
-  TexParameteri cmd;
-  cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
-           GL_TEXTURE_MIN_FILTER,
-           GL_NEAREST);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
-           GL_TEXTURE_MIN_FILTER,
-           GL_LINEAR);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
-           GL_TEXTURE_WRAP_S,
-           GL_CLAMP_TO_EDGE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
-           GL_TEXTURE_WRAP_T,
-           GL_CLAMP_TO_EDGE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  Texture* texture = GetTexture(client_texture_id_)->texture();
-  EXPECT_TRUE(texture != NULL);
-  EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
-  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
-  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
-  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
-}
-
-TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParamInvalid) {
-  InitState init;
-  init.extensions = "GL_ARB_texture_rectangle";
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  DoBindTexture(
-      GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
-
-  TexParameteri cmd;
-  cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
-           GL_TEXTURE_MIN_FILTER,
-           GL_NEAREST_MIPMAP_NEAREST);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-
-  cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
-           GL_TEXTURE_WRAP_S,
-           GL_REPEAT);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-
-  cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
-           GL_TEXTURE_WRAP_T,
-           GL_REPEAT);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-
-  Texture* texture = GetTexture(client_texture_id_)->texture();
-  EXPECT_TRUE(texture != NULL);
-  EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
-  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
-  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
-  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
-}
-
-TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTexImage2DError) {
-  InitState init;
-  init.extensions = "GL_ARB_texture_rectangle";
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  GLenum target = GL_TEXTURE_RECTANGLE_ARB;
-  GLint level = 0;
-  GLenum internal_format = GL_RGBA;
-  GLsizei width = 2;
-  GLsizei height = 4;
-  GLint border = 0;
-  GLenum format = GL_RGBA;
-  GLenum type = GL_UNSIGNED_BYTE;
-  DoBindTexture(
-      GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
-  ASSERT_TRUE(GetTexture(client_texture_id_) != NULL);
-  TexImage2D cmd;
-  cmd.Init(target, level, internal_format, width, height, border, format,
-           type, kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-
-  // TexImage2D is not allowed with GL_TEXTURE_RECTANGLE_ARB targets.
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, EnableFeatureCHROMIUMBadBucket) {
+TEST_P(GLES2DecoderTest, EnableFeatureCHROMIUMBadBucket) {
   const uint32 kBadBucketId = 123;
   EnableFeatureCHROMIUM cmd;
   cmd.Init(kBadBucketId, shared_memory_id_, shared_memory_offset_);
   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) {
+TEST_P(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) {
   const uint32 kBadBucketId = 123;
   RequestExtensionCHROMIUM cmd;
   cmd.Init(kBadBucketId);
   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DNULL) {
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
-      0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
-  EXPECT_CALL(*gl_, TexSubImage2D(
-      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-      shared_memory_address_))
-      .Times(1)
-      .RetiresOnSaturation();
-  TexSubImage2D cmd;
-  cmd.Init(
-      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-      kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  // Test if we call it again it does not clear.
-  EXPECT_CALL(*gl_, TexSubImage2D(
-      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-      shared_memory_address_))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) {
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-      kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_CALL(*gl_, TexSubImage2D(
-      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-      shared_memory_address_))
-      .Times(1)
-      .RetiresOnSaturation();
-  TexSubImage2D cmd;
-  cmd.Init(
-      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-      kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  // Test if we call it again it does not clear.
-  EXPECT_CALL(*gl_, TexSubImage2D(
-      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-      shared_memory_address_))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(
-    GLES2DecoderManualInitTest,
-    TexSubImage2DDoesNotClearAfterTexImage2DNULLThenDataWithTexImage2DIsFaster) {
-  CommandLine command_line(0, NULL);
-  command_line.AppendSwitchASCII(
-      switches::kGpuDriverBugWorkarounds,
-      base::IntToString(gpu::TEXSUBIMAGE2D_FASTER_THAN_TEXIMAGE2D));
-  InitState init;
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoderWithCommandLine(init, &command_line);
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-
-  {
-    // Uses texSubimage internally because the above workaround is active and
-    // the update is for the full size of the texture.
-    EXPECT_CALL(*gl_,
-                TexSubImage2D(
-                    GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, _))
-        .Times(1)
-        .RetiresOnSaturation();
-    cmds::TexImage2D cmd;
-    cmd.Init(GL_TEXTURE_2D,
-             0,
-             GL_RGBA,
-             2,
-             2,
-             0,
-             GL_RGBA,
-             GL_UNSIGNED_BYTE,
-             kSharedMemoryId,
-             kSharedMemoryOffset);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  }
-
-  EXPECT_CALL(*gl_, TexSubImage2D(
-      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-      shared_memory_address_))
-      .Times(1)
-      .RetiresOnSaturation();
-  TexSubImage2D cmd;
-  cmd.Init(
-      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-      kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  // Test if we call it again it does not clear.
-  EXPECT_CALL(*gl_, TexSubImage2D(
-      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-      shared_memory_address_))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DWithDataThenNULL) {
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  // Put in data (so it should be marked as cleared)
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               kSharedMemoryId, kSharedMemoryOffset);
-  // Put in no data.
-  TexImage2D tex_cmd;
-  tex_cmd.Init(
-      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
-  // It won't actually call TexImage2D, just mark it as uncleared.
-  EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
-  // Next call to TexSubImage2d should clear.
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
-      0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
-  EXPECT_CALL(*gl_, TexSubImage2D(
-      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-      shared_memory_address_))
-      .Times(1)
-      .RetiresOnSaturation();
-  TexSubImage2D cmd;
-  cmd.Init(
-      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-      kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawArraysClearsAfterTexImage2DNULL) {
-  SetupAllNeededVertexBuffers();
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  // Create an uncleared texture with 2 levels.
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  // Expect 2 levels will be cleared.
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
-      0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
-      1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1);
-  SetupExpectationsForApplyingDefaultDirtyState();
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // But not again
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawElementsClearsAfterTexImage2DNULL) {
-  SetupAllNeededVertexBuffers();
-  SetupIndexBuffer();
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  // Create an uncleared texture with 2 levels.
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  // Expect 2 levels will be cleared.
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
-      0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
-      1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1);
-  SetupExpectationsForApplyingDefaultDirtyState();
-
-  EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount,
-                                 GL_UNSIGNED_SHORT,
-                                 BufferOffset(kValidIndexRangeStart * 2)))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // But not again
-  EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount,
-                                 GL_UNSIGNED_SHORT,
-                                 BufferOffset(kValidIndexRangeStart * 2)))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawClearsAfterTexImage2DNULLInFBO) {
-  const GLuint kFBOClientTextureId = 4100;
-  const GLuint kFBOServiceTextureId = 4101;
-
-  SetupAllNeededVertexBuffers();
-  // Register a texture id.
-  EXPECT_CALL(*gl_, GenTextures(_, _))
-      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
-      .RetiresOnSaturation();
-  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
-
-  // Setup "render to" texture.
-  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
-  DoBindFramebuffer(
-      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
-
-  // Setup "render from" texture.
-  SetupTexture();
-
-  SetupExpectationsForFramebufferClearing(
-      GL_FRAMEBUFFER,         // target
-      GL_COLOR_BUFFER_BIT,    // clear bits
-      0, 0, 0, 0,             // color
-      0,                      // stencil
-      1.0f,                   // depth
-      false);                 // scissor test
-
-  SetupExpectationsForApplyingDirtyState(
-      false,   // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1111,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // But not again.
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawWitFBOThatCantClearDoesNotDraw) {
-  const GLuint kFBOClientTextureId = 4100;
-  const GLuint kFBOServiceTextureId = 4101;
-
-  // Register a texture id.
-  EXPECT_CALL(*gl_, GenTextures(_, _))
-      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
-      .RetiresOnSaturation();
-  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
-
-  // Setup "render to" texture.
-  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
-  DoBindFramebuffer(
-      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
-
-  // Setup "render from" texture.
-  SetupTexture();
-
-  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
-      .WillOnce(Return(GL_FRAMEBUFFER_UNSUPPORTED))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, DrawArrays(_, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_FRAMEBUFFER_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, CopyTexImage2DMarksTextureAsCleared) {
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-
-  TextureManager* manager = group().texture_manager();
-  TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
-  ASSERT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  CopyTexImage2D cmd;
-  cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-
-  EXPECT_TRUE(texture->SafeToRenderFrom());
-}
-
-TEST_F(GLES2DecoderTest, CopyTexSubImage2DClearsUnclearedTexture) {
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
-
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
-      0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
-  EXPECT_CALL(*gl_, CopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1))
-      .Times(1)
-      .RetiresOnSaturation();
-  CopyTexSubImage2D cmd;
-  cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderManualInitTest, CompressedImage2DMarksTextureAsCleared) {
-  InitState init;
-  init.extensions = "GL_EXT_texture_compression_s3tc";
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, CompressedTexImage2D(
-      GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, 8, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  CompressedTexImage2D cmd;
-  cmd.Init(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
-           8, kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  TextureManager* manager = group().texture_manager();
-  TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
-  EXPECT_TRUE(texture_ref->texture()->SafeToRenderFrom());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnClear) {
-  const GLuint kFBOClientTextureId = 4100;
-  const GLuint kFBOServiceTextureId = 4101;
-
-  // Register a texture id.
-  EXPECT_CALL(*gl_, GenTextures(_, _))
-      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
-      .RetiresOnSaturation();
-  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
-
-  // Setup "render to" texture.
-  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
-  DoBindFramebuffer(
-      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
-
-  // Setup "render from" texture.
-  SetupTexture();
-
-  SetupExpectationsForFramebufferClearing(
-      GL_FRAMEBUFFER,         // target
-      GL_COLOR_BUFFER_BIT,    // clear bits
-      0, 0, 0, 0,             // color
-      0,                      // stencil
-      1.0f,                   // depth
-      false);                 // scissor test
-  SetupExpectationsForApplyingDirtyState(
-      false,   // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1111,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT))
-      .Times(1)
-      .RetiresOnSaturation();
-
-  Clear cmd;
-  cmd.Init(GL_COLOR_BUFFER_BIT);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnReadPixels) {
-  const GLuint kFBOClientTextureId = 4100;
-  const GLuint kFBOServiceTextureId = 4101;
-
-  // Register a texture id.
-  EXPECT_CALL(*gl_, GenTextures(_, _))
-      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
-      .RetiresOnSaturation();
-  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
-
-  // Setup "render to" texture.
-  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
-  DoBindFramebuffer(
-      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
-
-  // Setup "render from" texture.
-  SetupTexture();
-
-  SetupExpectationsForFramebufferClearing(
-      GL_FRAMEBUFFER,         // target
-      GL_COLOR_BUFFER_BIT,    // clear bits
-      0, 0, 0, 0,             // color
-      0,                      // stencil
-      1.0f,                   // depth
-      false);                 // scissor test
-
-  EXPECT_CALL(*gl_, GetError())
-     .WillOnce(Return(GL_NO_ERROR))
-     .WillOnce(Return(GL_NO_ERROR))
-     .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  typedef ReadPixels::Result Result;
-  Result* result = GetSharedMemoryAs<Result*>();
-  uint32 result_shm_id = kSharedMemoryId;
-  uint32 result_shm_offset = kSharedMemoryOffset;
-  uint32 pixels_shm_id = kSharedMemoryId;
-  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
-  ReadPixels cmd;
-  cmd.Init(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-           pixels_shm_id, pixels_shm_offset,
-           result_shm_id, result_shm_offset,
-           false);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest,
-       UnClearedAttachmentsGetClearedOnReadPixelsAndDrawBufferGetsRestored) {
-  InitState init;
-  init.extensions = "GL_EXT_framebuffer_multisample";
-  init.gl_version = "2.1";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  const GLuint kFBOClientTextureId = 4100;
-  const GLuint kFBOServiceTextureId = 4101;
-
-  // Register a texture id.
-  EXPECT_CALL(*gl_, GenTextures(_, _))
-      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
-      .RetiresOnSaturation();
-  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
-
-  // Setup "render from" texture.
-  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
-  DoBindFramebuffer(
-      GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(
-      GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
-
-  SetupExpectationsForFramebufferClearingMulti(
-      kServiceFramebufferId,  // read framebuffer service id
-      0,                      // backbuffer service id
-      GL_READ_FRAMEBUFFER,    // target
-      GL_COLOR_BUFFER_BIT,    // clear bits
-      0, 0, 0, 0,             // color
-      0,                      // stencil
-      1.0f,                   // depth
-      false);                 // scissor test
-
-  EXPECT_CALL(*gl_, GetError())
-     .WillOnce(Return(GL_NO_ERROR))
-     .WillOnce(Return(GL_NO_ERROR))
-     .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  typedef ReadPixels::Result Result;
-  uint32 result_shm_id = kSharedMemoryId;
-  uint32 result_shm_offset = kSharedMemoryOffset;
-  uint32 pixels_shm_id = kSharedMemoryId;
-  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);
-  ReadPixels cmd;
-  cmd.Init(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
-           pixels_shm_id, pixels_shm_offset,
-           result_shm_id, result_shm_offset,
-           false);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, DrawClearsAfterRenderbufferStorageInFBO) {
-  SetupTexture();
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  DoRenderbufferStorage(
-      GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 100, 50, GL_NO_ERROR);
-  DoFramebufferRenderbuffer(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
-
-  SetupExpectationsForFramebufferClearing(
-      GL_FRAMEBUFFER,         // target
-      GL_COLOR_BUFFER_BIT,    // clear bits
-      0, 0, 0, 0,             // color
-      0,                      // stencil
-      1.0f,                   // depth
-      false);                 // scissor test
-
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDirtyState(
-      false,   // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1111,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, DrawArraysClearsAfterTexImage2DNULLCubemap) {
-  static const GLenum faces[] = {
-    GL_TEXTURE_CUBE_MAP_POSITIVE_X,
-    GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
-    GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
-    GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
-    GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
-    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
-  };
-  SetupCubemapProgram();
-  DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId);
-  // Fill out all the faces for 2 levels, leave 2 uncleared.
-  for (int ii = 0; ii < 6; ++ii) {
-    GLenum face = faces[ii];
-    int32 shm_id =
-        (face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ? 0 : kSharedMemoryId;
-    uint32 shm_offset =
-        (face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ? 0 : kSharedMemoryOffset;
-    DoTexImage2D(face, 0, GL_RGBA, 2, 2, 0, GL_RGBA,
-                 GL_UNSIGNED_BYTE, shm_id, shm_offset);
-    DoTexImage2D(face, 1, GL_RGBA, 1, 1, 0, GL_RGBA,
-                 GL_UNSIGNED_BYTE, shm_id, shm_offset);
-  }
-  // Expect 2 levels will be cleared.
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_CUBE_MAP,
-      GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE,
-      2, 2);
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_CUBE_MAP,
-      GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE,
-      1, 1);
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDefaultDirtyState();
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-}
-
-TEST_F(GLES2DecoderTest, TextureUsageAngleExtNotEnabledByDefault) {
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-
-  TexParameteri cmd;
-  cmd.Init(GL_TEXTURE_2D,
-           GL_TEXTURE_USAGE_ANGLE,
-           GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest,
-       DrawClearsAfterRenderbuffersWithMultipleAttachments) {
-  const GLuint kFBOClientTextureId = 4100;
-  const GLuint kFBOServiceTextureId = 4101;
-
-  // Register a texture id.
-  EXPECT_CALL(*gl_, GenTextures(_, _))
-      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
-      .RetiresOnSaturation();
-  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
-
-  // Setup "render to" texture.
-  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
-  DoBindFramebuffer(
-      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
-
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  DoRenderbufferStorage(
-      GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT,
-      1, 1, GL_NO_ERROR);
-  DoFramebufferRenderbuffer(
-      GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
-      client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
-
-  SetupTexture();
-  SetupExpectationsForFramebufferClearing(
-      GL_FRAMEBUFFER,         // target
-      GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,    // clear bits
-      0, 0, 0, 0,             // color
-      0,                      // stencil
-      1.0f,                   // depth
-      false);                 // scissor test
-
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDirtyState(
-      false,   // Framebuffer is RGB
-      true,    // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1111,  // color bits
-      true,    // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, CopyTexImageWithInCompleteFBOFails) {
-  GLenum target = GL_TEXTURE_2D;
-  GLint level = 0;
-  GLenum internal_format = GL_RGBA;
-  GLsizei width = 2;
-  GLsizei height = 4;
-  GLint border = 0;
-  SetupTexture();
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  DoRenderbufferStorage(
-      GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 0, 0, GL_NO_ERROR);
-  DoFramebufferRenderbuffer(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
-
-  EXPECT_CALL(*gl_, CopyTexImage2D(_, _, _, _, _, _, _, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  CopyTexImage2D cmd;
-  cmd.Init(target, level, internal_format, 0, 0, width, height, border);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_FRAMEBUFFER_OPERATION, GetGLError());
-}
-
-void GLES2DecoderWithShaderTest::CheckRenderbufferChangesMarkFBOAsNotComplete(
-    bool bound_fbo) {
-  FramebufferManager* framebuffer_manager = group().framebuffer_manager();
-  SetupTexture();
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  DoRenderbufferStorage(
-      GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
-  DoFramebufferRenderbuffer(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
-
-
-  if (!bound_fbo) {
-    DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
-  }
-
-  Framebuffer* framebuffer =
-      framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
-  ASSERT_TRUE(framebuffer != NULL);
-  framebuffer_manager->MarkAsComplete(framebuffer);
-  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
-
-  // Test that renderbufferStorage marks fbo as not complete.
-  DoRenderbufferStorage(
-      GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
-  EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
-  framebuffer_manager->MarkAsComplete(framebuffer);
-  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
-
-  // Test deleting renderbuffer marks fbo as not complete.
-  DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
-  if (bound_fbo) {
-    EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
-  } else {
-    EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
-  }
-  // Cleanup
-  DoDeleteFramebuffer(
-      client_framebuffer_id_, kServiceFramebufferId,
-      bound_fbo, GL_FRAMEBUFFER, 0,
-      bound_fbo, GL_FRAMEBUFFER, 0);
-}
-
-TEST_F(GLES2DecoderWithShaderTest,
-       RenderbufferChangesMarkFBOAsNotCompleteBoundFBO) {
-  CheckRenderbufferChangesMarkFBOAsNotComplete(true);
-}
-
-TEST_F(GLES2DecoderWithShaderTest,
-       RenderbufferChangesMarkFBOAsNotCompleteUnboundFBO) {
-  CheckRenderbufferChangesMarkFBOAsNotComplete(false);
-}
-
-void GLES2DecoderWithShaderTest::CheckTextureChangesMarkFBOAsNotComplete(
-    bool bound_fbo) {
-  FramebufferManager* framebuffer_manager = group().framebuffer_manager();
-  const GLuint kFBOClientTextureId = 4100;
-  const GLuint kFBOServiceTextureId = 4101;
-
-  // Register a texture id.
-  EXPECT_CALL(*gl_, GenTextures(_, _))
-      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
-      .RetiresOnSaturation();
-  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
-
-  SetupTexture();
-
-  // Setup "render to" texture.
-  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
-  DoBindFramebuffer(
-      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
-
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  DoRenderbufferStorage(
-      GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT,
-      1, 1, GL_NO_ERROR);
-  DoFramebufferRenderbuffer(
-      GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
-      client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
-
-  if (!bound_fbo) {
-    DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
-  }
-
-  Framebuffer* framebuffer =
-      framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
-  ASSERT_TRUE(framebuffer != NULL);
-  framebuffer_manager->MarkAsComplete(framebuffer);
-  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
-
-  // Test TexImage2D marks fbo as not complete.
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, 0, 0);
-  EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
-  framebuffer_manager->MarkAsComplete(framebuffer);
-  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
-
-  // Test CopyImage2D marks fbo as not complete.
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1, 0))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  CopyTexImage2D cmd;
-  cmd.Init(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1, 0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
-
-  // Test deleting texture marks fbo as not complete.
-  framebuffer_manager->MarkAsComplete(framebuffer);
-  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
-  DoDeleteTexture(kFBOClientTextureId, kFBOServiceTextureId);
-
-  if (bound_fbo) {
-    EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
-  } else {
-    EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
-  }
-  // Cleanup
-  DoDeleteFramebuffer(
-      client_framebuffer_id_, kServiceFramebufferId,
-      bound_fbo, GL_FRAMEBUFFER, 0,
-      bound_fbo, GL_FRAMEBUFFER, 0);
-}
-
-TEST_F(GLES2DecoderWithShaderTest, TextureChangesMarkFBOAsNotCompleteBoundFBO) {
-  CheckTextureChangesMarkFBOAsNotComplete(true);
-}
-
-TEST_F(GLES2DecoderWithShaderTest,
-       TextureChangesMarkFBOAsNotCompleteUnboundFBO) {
-  CheckTextureChangesMarkFBOAsNotComplete(false);
-}
-
-TEST_F(GLES2DecoderWithShaderTest,
-       DrawingWithFBOTwiceChecksForFBOCompleteOnce) {
-  const GLuint kFBOClientTextureId = 4100;
-  const GLuint kFBOServiceTextureId = 4101;
-
-  SetupAllNeededVertexBuffers();
-
-  // Register a texture id.
-  EXPECT_CALL(*gl_, GenTextures(_, _))
-      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
-      .RetiresOnSaturation();
-  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
-
-  // Setup "render to" texture that is cleared.
-  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-      kSharedMemoryId, kSharedMemoryOffset);
-  DoBindFramebuffer(
-      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
-
-  // Setup "render from" texture.
-  SetupTexture();
-
-  // Make sure we check for framebuffer complete.
-  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
-      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
-      .RetiresOnSaturation();
-
-  SetupExpectationsForApplyingDirtyState(
-      false,   // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1111,  // color bits
-      false,   // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
-
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // But not again.
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, BeginQueryEXTDisabled) {
+TEST_P(GLES2DecoderTest, BeginQueryEXTDisabled) {
   // Test something fails if off.
 }
 
-TEST_F(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
+TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
   InitState init;
   init.extensions = "GL_EXT_occlusion_query_boolean";
   init.gl_version = "opengl es 2.0";
@@ -7052,8 +602,8 @@
 
   // Test valid parameters work.
   EXPECT_CALL(*gl_, GenQueriesARB(1, _))
-     .WillOnce(SetArgumentPointee<1>(kNewServiceId))
-     .RetiresOnSaturation();
+      .WillOnce(SetArgumentPointee<1>(kNewServiceId))
+      .RetiresOnSaturation();
   EXPECT_CALL(*gl_, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId))
       .Times(1)
       .RetiresOnSaturation();
@@ -7072,9 +622,10 @@
   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
 
-  begin_cmd.Init(
-      GL_ANY_SAMPLES_PASSED_EXT, kNewClientId,
-      kSharedMemoryId, kSharedMemoryOffset);
+  begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT,
+                 kNewClientId,
+                 kSharedMemoryId,
+                 kSharedMemoryOffset);
   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 
@@ -7101,9 +652,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
   EXPECT_TRUE(query->pending());
 
-  EXPECT_CALL(*gl_, DeleteQueriesARB(1, _))
-      .Times(1)
-      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation();
 }
 
 struct QueryType {
@@ -7112,22 +661,21 @@
 };
 
 const QueryType kQueryTypes[] = {
-  { GL_COMMANDS_ISSUED_CHROMIUM, false },
-  { GL_LATENCY_QUERY_CHROMIUM, false },
-  { GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, false },
-  { GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, false },
-  { GL_GET_ERROR_QUERY_CHROMIUM, false },
-  { GL_COMMANDS_COMPLETED_CHROMIUM, false },
-  { GL_ANY_SAMPLES_PASSED_EXT, true },
+    {GL_COMMANDS_ISSUED_CHROMIUM, false},
+    {GL_LATENCY_QUERY_CHROMIUM, false},
+    {GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, false},
+    {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, false},
+    {GL_GET_ERROR_QUERY_CHROMIUM, false},
+    {GL_COMMANDS_COMPLETED_CHROMIUM, false},
+    {GL_ANY_SAMPLES_PASSED_EXT, true},
 };
 
-static void CheckBeginEndQueryBadMemoryFails(
-    GLES2DecoderTestBase* test,
-    GLuint client_id,
-    GLuint service_id,
-    const QueryType& query_type,
-    int32 shm_id,
-    uint32 shm_offset) {
+static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test,
+                                             GLuint client_id,
+                                             GLuint service_id,
+                                             const QueryType& query_type,
+                                             int32 shm_id,
+                                             uint32 shm_offset) {
   // We need to reset the decoder on each iteration, because we lose the
   // context every time.
   GLES2DecoderTestBase::InitState init;
@@ -7145,8 +693,8 @@
 
   if (query_type.is_gl) {
     EXPECT_CALL(*gl, GenQueriesARB(1, _))
-       .WillOnce(SetArgumentPointee<1>(service_id))
-       .RetiresOnSaturation();
+        .WillOnce(SetArgumentPointee<1>(service_id))
+        .RetiresOnSaturation();
     EXPECT_CALL(*gl, BeginQueryARB(query_type.type, service_id))
         .Times(1)
         .RetiresOnSaturation();
@@ -7179,12 +727,11 @@
   error::Error error2 = test->ExecuteCmd(end_cmd);
 
   if (query_type.is_gl) {
-    EXPECT_CALL(*gl,
-        GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
+    EXPECT_CALL(
+        *gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
         .WillOnce(SetArgumentPointee<2>(1))
         .RetiresOnSaturation();
-    EXPECT_CALL(*gl,
-        GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_EXT, _))
+    EXPECT_CALL(*gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_EXT, _))
         .WillOnce(SetArgumentPointee<2>(1))
         .RetiresOnSaturation();
   }
@@ -7198,53 +745,57 @@
   ASSERT_TRUE(query_manager != NULL);
   bool process_success = query_manager->ProcessPendingQueries();
 
-  EXPECT_TRUE(error1 != error::kNoError ||
-              error2 != error::kNoError ||
+  EXPECT_TRUE(error1 != error::kNoError || error2 != error::kNoError ||
               !process_success);
 
   if (query_type.is_gl) {
-    EXPECT_CALL(*gl, DeleteQueriesARB(1, _))
-        .Times(1)
-        .RetiresOnSaturation();
+    EXPECT_CALL(*gl, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation();
   }
   if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM)
     EXPECT_CALL(*gl, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
   test->ResetDecoder();
 }
 
-TEST_F(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) {
+TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) {
   for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
-    CheckBeginEndQueryBadMemoryFails(
-        this, kNewClientId, kNewServiceId,
-        kQueryTypes[i],
-        kInvalidSharedMemoryId, kSharedMemoryOffset);
+    CheckBeginEndQueryBadMemoryFails(this,
+                                     kNewClientId,
+                                     kNewServiceId,
+                                     kQueryTypes[i],
+                                     kInvalidSharedMemoryId,
+                                     kSharedMemoryOffset);
   }
 }
 
-TEST_F(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
+TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
   for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
     // Out-of-bounds.
-    CheckBeginEndQueryBadMemoryFails(
-        this, kNewClientId, kNewServiceId,
-        kQueryTypes[i],
-        kSharedMemoryId, kInvalidSharedMemoryOffset);
+    CheckBeginEndQueryBadMemoryFails(this,
+                                     kNewClientId,
+                                     kNewServiceId,
+                                     kQueryTypes[i],
+                                     kSharedMemoryId,
+                                     kInvalidSharedMemoryOffset);
     // Overflow.
-    CheckBeginEndQueryBadMemoryFails(
-        this, kNewClientId, kNewServiceId,
-        kQueryTypes[i],
-        kSharedMemoryId, 0xfffffffcu);
+    CheckBeginEndQueryBadMemoryFails(this,
+                                     kNewClientId,
+                                     kNewServiceId,
+                                     kQueryTypes[i],
+                                     kSharedMemoryId,
+                                     0xfffffffcu);
   }
 }
 
-TEST_F(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) {
+TEST_P(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) {
   BeginQueryEXT begin_cmd;
 
   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
 
   // Test valid parameters work.
-  begin_cmd.Init(
-      GL_COMMANDS_ISSUED_CHROMIUM, kNewClientId,
-      kSharedMemoryId, kSharedMemoryOffset);
+  begin_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM,
+                 kNewClientId,
+                 kSharedMemoryId,
+                 kSharedMemoryOffset);
   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 
@@ -7262,15 +813,16 @@
   EXPECT_FALSE(query->pending());
 }
 
-TEST_F(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) {
+TEST_P(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) {
   BeginQueryEXT begin_cmd;
 
   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
 
   // Test valid parameters work.
-  begin_cmd.Init(
-      GL_GET_ERROR_QUERY_CHROMIUM, kNewClientId,
-      kSharedMemoryId, kSharedMemoryOffset);
+  begin_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM,
+                 kNewClientId,
+                 kSharedMemoryId,
+                 kSharedMemoryOffset);
   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 
@@ -7296,7 +848,7 @@
             static_cast<GLenum>(sync->result));
 }
 
-TEST_F(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) {
+TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) {
   InitState init;
   init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
   init.gl_version = "opengl es 2.0";
@@ -7355,105 +907,11 @@
   ResetDecoder();
 }
 
-TEST_F(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) {
-  Mailbox mailbox = Mailbox::Generate();
-
-  memcpy(shared_memory_address_, mailbox.name, sizeof(mailbox.name));
-
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  TextureRef* texture_ref = group().texture_manager()->GetTexture(
-      client_texture_id_);
-  ASSERT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  EXPECT_EQ(kServiceTextureId, texture->service_id());
-
-  ProduceTextureCHROMIUM produce_cmd;
-  produce_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(produce_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Texture didn't change.
-  GLsizei width;
-  GLsizei height;
-  GLenum type;
-  GLenum internal_format;
-
-  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
-  EXPECT_EQ(3, width);
-  EXPECT_EQ(1, height);
-  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
-  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
-  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
-
-  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
-  EXPECT_EQ(2, width);
-  EXPECT_EQ(4, height);
-  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
-  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
-  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
-
-  // Service ID has not changed.
-  EXPECT_EQ(kServiceTextureId, texture->service_id());
-
-  // Create new texture for consume.
-  EXPECT_CALL(*gl_, GenTextures(_, _))
-      .WillOnce(SetArgumentPointee<1>(kNewServiceId))
-      .RetiresOnSaturation();
-  DoBindTexture(GL_TEXTURE_2D, kNewClientId, kNewServiceId);
-
-  // Assigns and binds original service size texture ID.
-  EXPECT_CALL(*gl_, DeleteTextures(1, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
-      .Times(1)
-      .RetiresOnSaturation();
-
-  memcpy(shared_memory_address_, mailbox.name, sizeof(mailbox.name));
-  ConsumeTextureCHROMIUM consume_cmd;
-  consume_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(consume_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Texture is redefined.
-  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
-  EXPECT_EQ(3, width);
-  EXPECT_EQ(1, height);
-  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
-  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
-  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
-
-  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
-  EXPECT_EQ(2, width);
-  EXPECT_EQ(4, height);
-  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
-  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
-  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
-
-  // Service ID is restored.
-  EXPECT_EQ(kServiceTextureId, texture->service_id());
-}
-
-
-TEST_F(GLES2DecoderTest, CanChangeSurface) {
-  scoped_refptr<GLSurfaceMock> other_surface(new GLSurfaceMock);
-  EXPECT_CALL(*other_surface.get(), GetBackingFrameBufferObject()).
-      WillOnce(Return(7));
-  EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 7));
-
-  decoder_->SetSurface(other_surface);
-}
-
-TEST_F(GLES2DecoderTest, IsEnabledReturnsCachedValue) {
+TEST_P(GLES2DecoderTest, IsEnabledReturnsCachedValue) {
   // NOTE: There are no expectations because no GL functions should be
   // called for DEPTH_TEST or STENCIL_TEST
   static const GLenum kStates[] = {
-    GL_DEPTH_TEST,
-    GL_STENCIL_TEST,
+      GL_DEPTH_TEST, GL_STENCIL_TEST,
   };
   for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
     Enable enable_cmd;
@@ -7474,834 +932,7 @@
   }
 }
 
-TEST_F(GLES2DecoderManualInitTest, DepthTextureBadArgs) {
-  InitState init;
-  init.extensions = "GL_ANGLE_depth_texture";
-  init.gl_version = "opengl es 2.0";
-  init.has_depth = true;
-  init.has_stencil = true;
-  init.request_depth = true;
-  init.request_stencil = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  // Check trying to upload data fails.
-  TexImage2D tex_cmd;
-  tex_cmd.Init(
-      GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
-      1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
-      kSharedMemoryId, kSharedMemoryOffset);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  // Try level > 0.
-  tex_cmd.Init(
-      GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT,
-      1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  // Make a 1 pixel depth texture.
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
-               1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 0);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // Check that trying to update it fails.
-  TexSubImage2D tex_sub_cmd;
-  tex_sub_cmd.Init(
-      GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
-      kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(tex_sub_cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-
-  // Check that trying to CopyTexImage2D fails
-  CopyTexImage2D copy_tex_cmd;
-  copy_tex_cmd.Init(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 1, 1, 0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(copy_tex_cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-
-  // Check that trying to CopyTexSubImage2D fails
-  CopyTexSubImage2D copy_sub_cmd;
-  copy_sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(copy_sub_cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, GenerateMipmapDepthTexture) {
-  InitState init;
-  init.extensions = "GL_ANGLE_depth_texture";
-  init.gl_version = "opengl es 2.0";
-  init.has_depth = true;
-  init.has_stencil = true;
-  init.request_depth = true;
-  init.request_stencil = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
-               2, 2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
-               0, 0);
-  GenerateMipmap cmd;
-  cmd.Init(GL_TEXTURE_2D);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, DrawClearsDepthTexture) {
-  InitState init;
-  init.extensions = "GL_ANGLE_depth_texture";
-  init.gl_version = "opengl es 2.0";
-  init.has_alpha = true;
-  init.has_depth = true;
-  init.request_alpha = true;
-  init.request_depth = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  SetupDefaultProgram();
-  SetupAllNeededVertexBuffers();
-  const GLenum attachment = GL_DEPTH_ATTACHMENT;
-  const GLenum target = GL_TEXTURE_2D;
-  const GLint level = 0;
-  DoBindTexture(target, client_texture_id_, kServiceTextureId);
-
-  // Create a depth texture.
-  DoTexImage2D(target, level, GL_DEPTH_COMPONENT, 1, 1, 0,
-               GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 0);
-
-  EXPECT_CALL(*gl_, GenFramebuffersEXT(1, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, _))
-      .Times(1)
-      .RetiresOnSaturation();
-
-  EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
-      GL_DRAW_FRAMEBUFFER_EXT, attachment, target, kServiceTextureId, level))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT))
-      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
-      .RetiresOnSaturation();
-
-  EXPECT_CALL(*gl_, ClearStencil(0))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, StencilMask(-1))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, ClearDepth(1.0f))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, DepthMask(true))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, Disable(GL_SCISSOR_TEST))
-      .Times(1)
-      .RetiresOnSaturation();
-
-  EXPECT_CALL(*gl_, Clear(GL_DEPTH_BUFFER_BIT))
-      .Times(1)
-      .RetiresOnSaturation();
-
-  SetupExpectationsForRestoreClearState(
-      0.0f, 0.0f, 0.0f, 0.0f, 0, 1.0f, false);
-
-  EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0))
-      .Times(1)
-      .RetiresOnSaturation();
-
-  SetupExpectationsForApplyingDefaultDirtyState();
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderWithShaderTest, BindUniformLocationCHROMIUM) {
-  const GLint kLocation = 2;
-  const char* kName = "testing";
-  const uint32 kNameSize = strlen(kName);
-  const char* kBadName1 = "gl_testing";
-  const uint32 kBadName1Size = strlen(kBadName1);
-  const char* kBadName2 = "testing[1]";
-  const uint32 kBadName2Size = strlen(kBadName2);
-  memcpy(shared_memory_address_, kName, kNameSize);
-  BindUniformLocationCHROMIUM cmd;
-  cmd.Init(client_program_id_, kLocation, kSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  // check negative location
-  memcpy(shared_memory_address_, kName, kNameSize);
-  cmd.Init(client_program_id_, -1, kSharedMemoryId, kSharedMemoryOffset,
-           kNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  // check highest location
-  memcpy(shared_memory_address_, kName, kNameSize);
-  GLint kMaxLocation =
-      (kMaxFragmentUniformVectors + kMaxVertexUniformVectors) * 4 - 1;
-  cmd.Init(client_program_id_, kMaxLocation, kSharedMemoryId,
-           kSharedMemoryOffset, kNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  // check too high location
-  memcpy(shared_memory_address_, kName, kNameSize);
-  cmd.Init(client_program_id_, kMaxLocation + 1, kSharedMemoryId,
-           kSharedMemoryOffset, kNameSize);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-  // check bad name "gl_..."
-  memcpy(shared_memory_address_, kBadName1, kBadName1Size);
-  cmd.Init(client_program_id_, kLocation, kSharedMemoryId, kSharedMemoryOffset,
-           kBadName1Size);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  // check bad name "name[1]" non zero
-  memcpy(shared_memory_address_, kBadName2, kBadName2Size);
-  cmd.Init(client_program_id_, kLocation, kSharedMemoryId, kSharedMemoryOffset,
-           kBadName2Size);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-class GLES2DecoderVertexArraysOESTest : public GLES2DecoderWithShaderTest {
- public:
-  GLES2DecoderVertexArraysOESTest() { }
-
-  bool vertex_array_deleted_manually_;
-
-  virtual void SetUp() {
-    InitState init;
-    init.extensions = "GL_OES_vertex_array_object";
-    init.gl_version = "opengl es 2.0";
-    init.bind_generates_resource = true;
-    InitDecoder(init);
-    SetupDefaultProgram();
-
-    AddExpectationsForGenVertexArraysOES();
-    GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
-
-    vertex_array_deleted_manually_ = false;
-  }
-
-  virtual void TearDown() {
-    // This should only be set if the test handled deletion of the vertex array
-    // itself. Necessary because vertex_array_objects are not sharable, and thus
-    // not managed in the ContextGroup, meaning they will be destroyed during
-    // test tear down
-    if (!vertex_array_deleted_manually_) {
-      AddExpectationsForDeleteVertexArraysOES();
-    }
-
-    GLES2DecoderWithShaderTest::TearDown();
-  }
-
-  void GenVertexArraysOESValidArgs() {
-    AddExpectationsForGenVertexArraysOES();
-    GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
-    GenVertexArraysOES cmd;
-    cmd.Init(1, shared_memory_id_, shared_memory_offset_);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-    EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
-    AddExpectationsForDeleteVertexArraysOES();
-  }
-
-  void GenVertexArraysOESInvalidArgs() {
-    EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
-    GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
-    GenVertexArraysOES cmd;
-    cmd.Init(1, shared_memory_id_, shared_memory_offset_);
-    EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
-  }
-
-  void GenVertexArraysOESImmediateValidArgs() {
-    AddExpectationsForGenVertexArraysOES();
-    GenVertexArraysOESImmediate* cmd =
-        GetImmediateAs<GenVertexArraysOESImmediate>();
-    GLuint temp = kNewClientId;
-    cmd->Init(1, &temp);
-    EXPECT_EQ(error::kNoError,
-              ExecuteImmediateCmd(*cmd, sizeof(temp)));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-    EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
-    AddExpectationsForDeleteVertexArraysOES();
-  }
-
-  void GenVertexArraysOESImmediateInvalidArgs() {
-    EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
-    GenVertexArraysOESImmediate* cmd =
-        GetImmediateAs<GenVertexArraysOESImmediate>();
-    cmd->Init(1, &client_vertexarray_id_);
-    EXPECT_EQ(error::kInvalidArguments,
-              ExecuteImmediateCmd(*cmd, sizeof(&client_vertexarray_id_)));
-  }
-
-  void DeleteVertexArraysOESValidArgs() {
-    AddExpectationsForDeleteVertexArraysOES();
-    GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
-    DeleteVertexArraysOES cmd;
-    cmd.Init(1, shared_memory_id_, shared_memory_offset_);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-    EXPECT_TRUE(
-        GetVertexArrayInfo(client_vertexarray_id_) == NULL);
-    vertex_array_deleted_manually_ = true;
-  }
-
-  void DeleteVertexArraysOESInvalidArgs() {
-    GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
-    DeleteVertexArraysOES cmd;
-    cmd.Init(1, shared_memory_id_, shared_memory_offset_);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  }
-
-  void DeleteVertexArraysOESImmediateValidArgs() {
-    AddExpectationsForDeleteVertexArraysOES();
-    DeleteVertexArraysOESImmediate& cmd =
-        *GetImmediateAs<DeleteVertexArraysOESImmediate>();
-    cmd.Init(1, &client_vertexarray_id_);
-    EXPECT_EQ(error::kNoError,
-              ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_)));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-    EXPECT_TRUE(
-        GetVertexArrayInfo(client_vertexarray_id_) == NULL);
-    vertex_array_deleted_manually_ = true;
-  }
-
-  void DeleteVertexArraysOESImmediateInvalidArgs() {
-    DeleteVertexArraysOESImmediate& cmd =
-        *GetImmediateAs<DeleteVertexArraysOESImmediate>();
-    GLuint temp = kInvalidClientId;
-    cmd.Init(1, &temp);
-    EXPECT_EQ(error::kNoError,
-              ExecuteImmediateCmd(cmd, sizeof(temp)));
-  }
-
-  void DeleteBoundVertexArraysOESImmediateValidArgs() {
-    BindVertexArrayOESValidArgs();
-
-    AddExpectationsForDeleteBoundVertexArraysOES();
-    DeleteVertexArraysOESImmediate& cmd =
-        *GetImmediateAs<DeleteVertexArraysOESImmediate>();
-    cmd.Init(1, &client_vertexarray_id_);
-    EXPECT_EQ(error::kNoError,
-              ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_)));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-    EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_) == NULL);
-    vertex_array_deleted_manually_ = true;
-  }
-
-  void IsVertexArrayOESValidArgs() {
-    IsVertexArrayOES cmd;
-    cmd.Init(client_vertexarray_id_, shared_memory_id_, shared_memory_offset_);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  }
-
-  void IsVertexArrayOESInvalidArgsBadSharedMemoryId() {
-    IsVertexArrayOES cmd;
-    cmd.Init(
-        client_vertexarray_id_, kInvalidSharedMemoryId, shared_memory_offset_);
-    EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
-    cmd.Init(
-        client_vertexarray_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
-    EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
-  }
-
-  void BindVertexArrayOESValidArgs() {
-    AddExpectationsForBindVertexArrayOES();
-    BindVertexArrayOES cmd;
-    cmd.Init(client_vertexarray_id_);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  }
-
-  void BindVertexArrayOESValidArgsNewId() {
-    BindVertexArrayOES cmd;
-    cmd.Init(kNewClientId);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-  }
-};
-
-class GLES2DecoderEmulatedVertexArraysOESTest
-    : public GLES2DecoderVertexArraysOESTest {
- public:
-  GLES2DecoderEmulatedVertexArraysOESTest() { }
-
-  virtual void SetUp() {
-    InitState init;
-    init.gl_version = "3.0";
-    init.bind_generates_resource = true;
-    InitDecoder(init);
-    SetupDefaultProgram();
-
-    AddExpectationsForGenVertexArraysOES();
-    GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
-
-    vertex_array_deleted_manually_ = false;
-  }
-};
-
-// Test vertex array objects with native support
-TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESValidArgs) {
-  GenVertexArraysOESValidArgs();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, GenVertexArraysOESValidArgs) {
-  GenVertexArraysOESValidArgs();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESInvalidArgs) {
-  GenVertexArraysOESInvalidArgs();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, ) {
-  GenVertexArraysOESInvalidArgs();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESImmediateValidArgs) {
-  GenVertexArraysOESImmediateValidArgs();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
-    GenVertexArraysOESImmediateValidArgs) {
-  GenVertexArraysOESImmediateValidArgs();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest,
-    GenVertexArraysOESImmediateInvalidArgs) {
-  GenVertexArraysOESImmediateInvalidArgs();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
-    GenVertexArraysOESImmediateInvalidArgs) {
-  GenVertexArraysOESImmediateInvalidArgs();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest, DeleteVertexArraysOESValidArgs) {
-  DeleteVertexArraysOESValidArgs();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
-    DeleteVertexArraysOESValidArgs) {
-  DeleteVertexArraysOESValidArgs();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest, DeleteVertexArraysOESInvalidArgs) {
-  DeleteVertexArraysOESInvalidArgs();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
-    DeleteVertexArraysOESInvalidArgs) {
-  DeleteVertexArraysOESInvalidArgs();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest,
-    DeleteVertexArraysOESImmediateValidArgs) {
-  DeleteVertexArraysOESImmediateValidArgs();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
-    DeleteVertexArraysOESImmediateValidArgs) {
-  DeleteVertexArraysOESImmediateValidArgs();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest,
-    DeleteVertexArraysOESImmediateInvalidArgs) {
-  DeleteVertexArraysOESImmediateInvalidArgs();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
-    DeleteVertexArraysOESImmediateInvalidArgs) {
-  DeleteVertexArraysOESImmediateInvalidArgs();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest,
-       DeleteBoundVertexArraysOESImmediateValidArgs) {
-  DeleteBoundVertexArraysOESImmediateValidArgs();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
-       DeleteBoundVertexArraysOESImmediateValidArgs) {
-  DeleteBoundVertexArraysOESImmediateValidArgs();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest, IsVertexArrayOESValidArgs) {
-  IsVertexArrayOESValidArgs();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, IsVertexArrayOESValidArgs) {
-  IsVertexArrayOESValidArgs();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest,
-    IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
-  IsVertexArrayOESInvalidArgsBadSharedMemoryId();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
-    IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
-  IsVertexArrayOESInvalidArgsBadSharedMemoryId();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgs) {
-  BindVertexArrayOESValidArgs();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, BindVertexArrayOESValidArgs) {
-  BindVertexArrayOESValidArgs();
-}
-
-TEST_F(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgsNewId) {
-  BindVertexArrayOESValidArgsNewId();
-}
-TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
-    BindVertexArrayOESValidArgsNewId) {
-  BindVertexArrayOESValidArgsNewId();
-}
-
-TEST_F(GLES2DecoderTest, BindTexImage2DCHROMIUM) {
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  TextureRef* texture_ref = group().texture_manager()->GetTexture(
-      client_texture_id_);
-  ASSERT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  EXPECT_EQ(kServiceTextureId, texture->service_id());
-
-  group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
-  EXPECT_FALSE(group().image_manager()->LookupImage(1) == NULL);
-
-  GLsizei width;
-  GLsizei height;
-  GLenum type;
-  GLenum internal_format;
-
-  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
-  EXPECT_EQ(3, width);
-  EXPECT_EQ(1, height);
-  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
-  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
-  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
-  EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
-
-  // Bind image to texture.
-  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
-  bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
-  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
-  // Image should now be set.
-  EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
-
-  // Define new texture image.
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
-  // Image should no longer be set.
-  EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
-}
-
-TEST_F(GLES2DecoderTest, BindTexImage2DCHROMIUMCubeMapNotAllowed) {
-  group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
-  DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId);
-
-  BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
-  bind_tex_image_2d_cmd.Init(GL_TEXTURE_CUBE_MAP, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, OrphanGLImageWithTexImage2D) {
-  group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
-  DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId);
-
-  BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
-  bind_tex_image_2d_cmd.Init(GL_TEXTURE_CUBE_MAP, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
-  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
-
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  TextureRef* texture_ref = group().texture_manager()->GetTexture(
-      client_texture_id_);
-  ASSERT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
-}
-
-TEST_F(GLES2DecoderTest, ReleaseTexImage2DCHROMIUM) {
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               0, 0);
-  TextureRef* texture_ref = group().texture_manager()->GetTexture(
-      client_texture_id_);
-  ASSERT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  EXPECT_EQ(kServiceTextureId, texture->service_id());
-
-  group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
-  EXPECT_FALSE(group().image_manager()->LookupImage(1) == NULL);
-
-  GLsizei width;
-  GLsizei height;
-  GLenum type;
-  GLenum internal_format;
-
-  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
-  EXPECT_EQ(3, width);
-  EXPECT_EQ(1, height);
-  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
-  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
-  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
-  EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
-
-  // Bind image to texture.
-  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
-  bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
-  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
-  // Image should now be set.
-  EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
-
-  // Release image from texture.
-  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  ReleaseTexImage2DCHROMIUM release_tex_image_2d_cmd;
-  release_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(release_tex_image_2d_cmd));
-  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
-  // Image should no longer be set.
-  EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
-}
-
-class MockGLImage : public gfx::GLImage {
- public:
-  MockGLImage() {}
-
-  // Overridden from gfx::GLImage:
-  MOCK_METHOD0(Destroy, void());
-  MOCK_METHOD0(GetSize, gfx::Size());
-  MOCK_METHOD1(BindTexImage, bool(unsigned));
-  MOCK_METHOD1(ReleaseTexImage, void(unsigned));
-  MOCK_METHOD0(WillUseTexImage, void());
-  MOCK_METHOD0(DidUseTexImage, void());
-  MOCK_METHOD0(WillModifyTexImage, void());
-  MOCK_METHOD0(DidModifyTexImage, void());
-
- protected:
-  virtual ~MockGLImage() {}
-};
-
-TEST_F(GLES2DecoderWithShaderTest, UseTexImage) {
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               kSharedMemoryId, kSharedMemoryOffset);
-
-  TextureRef* texture_ref = group().texture_manager()->GetTexture(
-      client_texture_id_);
-  ASSERT_TRUE(texture_ref != NULL);
-  Texture* texture = texture_ref->texture();
-  EXPECT_EQ(kServiceTextureId, texture->service_id());
-
-  const int32 kImageId = 1;
-  scoped_refptr<MockGLImage> image(new MockGLImage);
-  group().image_manager()->AddImage(image.get(), kImageId);
-
-  // Bind image to texture.
-  EXPECT_CALL(*image, BindTexImage(GL_TEXTURE_2D))
-      .Times(1)
-      .WillOnce(Return(true))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*image, GetSize())
-      .Times(1)
-      .WillOnce(Return(gfx::Size(1, 1)))
-      .RetiresOnSaturation();
-  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
-  bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, kImageId);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
-
-  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
-  SetupExpectationsForApplyingDefaultDirtyState();
-
-  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
-      .Times(3)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*image, WillUseTexImage())
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*image, DidUseTexImage())
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawArrays cmd;
-  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
-      .Times(2)
-      .RetiresOnSaturation();
-  // Image will be 'in use' as long as bound to a framebuffer.
-  EXPECT_CALL(*image, WillUseTexImage())
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kServiceTextureId, 0))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  FramebufferTexture2D fbtex_cmd;
-  fbtex_cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_,
-      0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      kServiceRenderbufferId))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
-      .Times(2)
-      .RetiresOnSaturation();
-  // Image should no longer be 'in use' after being unbound from framebuffer.
-  EXPECT_CALL(*image, DidUseTexImage())
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  FramebufferRenderbuffer fbrb_cmd;
-  fbrb_cmd.Init(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
-      client_renderbuffer_id_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
-}
-
-TEST_F(GLES2DecoderManualInitTest, DrawWithGLImageExternal) {
-  InitState init;
-  init.extensions = "GL_OES_EGL_image_external";
-  init.gl_version = "opengl es 2.0";
-  init.has_alpha = true;
-  init.has_depth = true;
-  init.request_alpha = true;
-  init.request_depth = true;
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  TextureRef* texture_ref = GetTexture(client_texture_id_);
-  scoped_refptr<MockGLImage> image(new MockGLImage);
-  group().texture_manager()->SetTarget(texture_ref, GL_TEXTURE_EXTERNAL_OES);
-  group().texture_manager()->SetLevelInfo(texture_ref,
-                                          GL_TEXTURE_EXTERNAL_OES,
-                                          0,
-                                          GL_RGBA,
-                                          0,
-                                          0,
-                                          1,
-                                          0,
-                                          GL_RGBA,
-                                          GL_UNSIGNED_BYTE,
-                                          true);
-  group().texture_manager()->SetLevelImage(
-      texture_ref, GL_TEXTURE_EXTERNAL_OES, 0, image);
-
-  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  SetupSamplerExternalProgram();
-  SetupIndexBuffer();
-  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, 0);
-  SetupExpectationsForApplyingDefaultDirtyState();
-  EXPECT_TRUE(group().texture_manager()->CanRender(texture_ref));
-
-  InSequence s;
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*image, WillUseTexImage())
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
-      .Times(1);
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*image, DidUseTexImage())
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
-      .Times(1)
-      .RetiresOnSaturation();
-  DrawElements cmd;
-  cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
-           kValidIndexRangeStart * 2);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) {
+TEST_P(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) {
   InitState init;
   init.extensions = "GL_ARB_texture_rectangle";
   init.gl_version = "3.0";
@@ -8312,8 +943,7 @@
   EXPECT_TRUE(texture != NULL);
   EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
 
-  DoBindTexture(
-      GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
 
   TexParameteri cmd;
   cmd.Init(GL_TEXTURE_2D,
@@ -8330,319 +960,11 @@
 
   EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM);
 
-  cmd.Init(GL_TEXTURE_2D,
-           GL_TEXTURE_POOL_CHROMIUM,
-           GL_NONE);
+  cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, GL_NONE);
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderManualInitTest, AsyncPixelTransfers) {
-  InitState init;
-  init.extensions = "GL_CHROMIUM_async_pixel_transfers";
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  // Set up the texture.
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  TextureRef* texture_ref = GetTexture(client_texture_id_);
-  Texture* texture = texture_ref->texture();
-
-  // Set a mock Async delegate
-  StrictMock<gpu::MockAsyncPixelTransferManager>* manager =
-      new StrictMock<gpu::MockAsyncPixelTransferManager>;
-  manager->Initialize(group().texture_manager());
-  decoder_->SetAsyncPixelTransferManagerForTest(manager);
-  StrictMock<gpu::MockAsyncPixelTransferDelegate>* delegate = NULL;
-
-  // Tex(Sub)Image2D upload commands.
-  AsyncTexImage2DCHROMIUM teximage_cmd;
-  teximage_cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA,
-                    GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset,
-                    0, 0, 0);
-  AsyncTexSubImage2DCHROMIUM texsubimage_cmd;
-  texsubimage_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA,
-                      GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset,
-                      0, 0, 0);
-  WaitAsyncTexImage2DCHROMIUM wait_cmd;
-  wait_cmd.Init(GL_TEXTURE_2D);
-  WaitAllAsyncTexImage2DCHROMIUM wait_all_cmd;
-  wait_all_cmd.Init();
-
-  // No transfer state exists initially.
-  EXPECT_FALSE(
-      decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-          texture_ref));
-
-  base::Closure bind_callback;
-
-  // AsyncTexImage2D
-  {
-    // Create transfer state since it doesn't exist.
-    EXPECT_EQ(texture_ref->num_observers(), 0);
-    EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
-        .WillOnce(Return(
-            delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
-        .RetiresOnSaturation();
-    EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _))
-        .WillOnce(SaveArg<2>(&bind_callback))
-        .RetiresOnSaturation();
-    // Command succeeds.
-    EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-    EXPECT_EQ(
-        delegate,
-        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-            texture_ref));
-    EXPECT_TRUE(texture->IsImmutable());
-    // The texture is safe but the level has not been defined yet.
-    EXPECT_TRUE(texture->SafeToRenderFrom());
-    GLsizei width, height;
-    EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
-    EXPECT_EQ(texture_ref->num_observers(), 1);
-  }
-  {
-    // Async redefinitions are not allowed!
-    // Command fails.
-    EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
-    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-    EXPECT_EQ(
-        delegate,
-        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-            texture_ref));
-    EXPECT_TRUE(texture->IsImmutable());
-    EXPECT_TRUE(texture->SafeToRenderFrom());
-  }
-
-  // Binding/defining of the async transfer
-  {
-    // TODO(epenner): We should check that the manager gets the
-    // BindCompletedAsyncTransfers() call, which is required to
-    // guarantee the delegate calls the bind callback.
-
-    // Simulate the bind callback from the delegate.
-    bind_callback.Run();
-
-    // After the bind callback is run, the texture is safe,
-    // and has the right size etc.
-    EXPECT_TRUE(texture->SafeToRenderFrom());
-    GLsizei width, height;
-    EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
-    EXPECT_EQ(width, 8);
-    EXPECT_EQ(height, 8);
-  }
-
-  // AsyncTexSubImage2D
-  EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
-  decoder_->GetAsyncPixelTransferManager()
-      ->ClearPixelTransferDelegateForTest(texture_ref);
-  EXPECT_EQ(texture_ref->num_observers(), 0);
-  texture->SetImmutable(false);
-  {
-    // Create transfer state since it doesn't exist.
-    EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
-        .WillOnce(Return(
-            delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
-        .RetiresOnSaturation();
-    EXPECT_CALL(*delegate, AsyncTexSubImage2D(_, _))
-        .RetiresOnSaturation();
-    // Command succeeds.
-    EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-    EXPECT_EQ(
-        delegate,
-        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-            texture_ref));
-    EXPECT_TRUE(texture->IsImmutable());
-    EXPECT_TRUE(texture->SafeToRenderFrom());
-  }
-  {
-    // No transfer is in progress.
-    EXPECT_CALL(*delegate, TransferIsInProgress())
-        .WillOnce(Return(false))  // texSubImage validation
-        .WillOnce(Return(false))  // async validation
-        .RetiresOnSaturation();
-    EXPECT_CALL(*delegate, AsyncTexSubImage2D(_, _))
-        .RetiresOnSaturation();
-    // Command succeeds.
-    EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-    EXPECT_EQ(
-        delegate,
-        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-            texture_ref));
-    EXPECT_TRUE(texture->IsImmutable());
-    EXPECT_TRUE(texture->SafeToRenderFrom());
-  }
-  {
-    // A transfer is still in progress!
-    EXPECT_CALL(*delegate, TransferIsInProgress())
-        .WillOnce(Return(true))
-        .RetiresOnSaturation();
-    // No async call, command fails.
-    EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
-    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-    EXPECT_EQ(
-        delegate,
-        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-            texture_ref));
-    EXPECT_TRUE(texture->IsImmutable());
-    EXPECT_TRUE(texture->SafeToRenderFrom());
-  }
-
-  // Delete delegate on DeleteTexture.
-  {
-    EXPECT_EQ(texture_ref->num_observers(), 1);
-    EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
-    DoDeleteTexture(client_texture_id_, kServiceTextureId);
-    EXPECT_FALSE(
-        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-            texture_ref));
-    texture = NULL;
-    texture_ref = NULL;
-    delegate = NULL;
-  }
-
-  // WaitAsyncTexImage2D
-  {
-    // Get a fresh texture since the existing texture cannot be respecified
-    // asynchronously and AsyncTexSubImage2D does not involve binding.
-    EXPECT_CALL(*gl_, GenTextures(1, _))
-        .WillOnce(SetArgumentPointee<1>(kServiceTextureId));
-    DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-    texture_ref = GetTexture(client_texture_id_);
-    texture = texture_ref->texture();
-    texture->SetImmutable(false);
-    // Create transfer state since it doesn't exist.
-    EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
-        .WillOnce(Return(
-            delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
-        .RetiresOnSaturation();
-    EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _))
-        .RetiresOnSaturation();
-    // Start async transfer.
-    EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-    EXPECT_EQ(
-        delegate,
-        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-            texture_ref));
-
-    EXPECT_TRUE(texture->IsImmutable());
-    // Wait for completion.
-    EXPECT_CALL(*delegate, WaitForTransferCompletion());
-    EXPECT_CALL(*manager, BindCompletedAsyncTransfers());
-    EXPECT_EQ(error::kNoError, ExecuteCmd(wait_cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  }
-
-  // WaitAllAsyncTexImage2D
-  EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
-  DoDeleteTexture(client_texture_id_, kServiceTextureId);
-  EXPECT_FALSE(
-      decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-          texture_ref));
-  texture = NULL;
-  texture_ref = NULL;
-  delegate = NULL;
-  {
-    // Get a fresh texture since the existing texture cannot be respecified
-    // asynchronously and AsyncTexSubImage2D does not involve binding.
-    EXPECT_CALL(*gl_, GenTextures(1, _))
-        .WillOnce(SetArgumentPointee<1>(kServiceTextureId));
-    DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-    texture_ref = GetTexture(client_texture_id_);
-    texture = texture_ref->texture();
-    texture->SetImmutable(false);
-    // Create transfer state since it doesn't exist.
-    EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
-        .WillOnce(Return(
-            delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
-        .RetiresOnSaturation();
-    EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _))
-        .RetiresOnSaturation();
-    // Start async transfer.
-    EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-    EXPECT_EQ(
-        delegate,
-        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-            texture_ref));
-
-    EXPECT_TRUE(texture->IsImmutable());
-    // Wait for completion of all uploads.
-    EXPECT_CALL(*manager, WaitAllAsyncTexImage2D()).RetiresOnSaturation();
-    EXPECT_CALL(*manager, BindCompletedAsyncTransfers());
-    EXPECT_EQ(error::kNoError, ExecuteCmd(wait_all_cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  }
-
-  // Remove PixelTransferManager before the decoder destroys.
-  EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
-  decoder_->ResetAsyncPixelTransferManagerForTest();
-  manager = NULL;
-}
-
-TEST_F(GLES2DecoderManualInitTest, AsyncPixelTransferManager) {
-  InitState init;
-  init.extensions = "GL_CHROMIUM_async_pixel_transfers";
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  // Set up the texture.
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  TextureRef* texture_ref = GetTexture(client_texture_id_);
-
-  // Set a mock Async delegate.
-  StrictMock<gpu::MockAsyncPixelTransferManager>* manager =
-      new StrictMock<gpu::MockAsyncPixelTransferManager>;
-  manager->Initialize(group().texture_manager());
-  decoder_->SetAsyncPixelTransferManagerForTest(manager);
-  StrictMock<gpu::MockAsyncPixelTransferDelegate>* delegate = NULL;
-
-  AsyncTexImage2DCHROMIUM teximage_cmd;
-  teximage_cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA,
-                    GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset,
-                    0, 0, 0);
-
-  // No transfer delegate exists initially.
-  EXPECT_FALSE(
-      decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-          texture_ref));
-
-  // Create delegate on AsyncTexImage2D.
-  {
-    EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
-        .WillOnce(Return(
-             delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
-        .RetiresOnSaturation();
-    EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _)).RetiresOnSaturation();
-
-    // Command succeeds.
-    EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
-    EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  }
-
-  // Delegate is cached.
-  EXPECT_EQ(delegate,
-            decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
-                texture_ref));
-
-  // Delete delegate on manager teardown.
-  {
-    EXPECT_EQ(texture_ref->num_observers(), 1);
-    EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
-    decoder_->ResetAsyncPixelTransferManagerForTest();
-    manager = NULL;
-
-    // Texture ref still valid.
-    EXPECT_EQ(texture_ref, GetTexture(client_texture_id_));
-    EXPECT_EQ(texture_ref->num_observers(), 0);
-  }
-}
-
 namespace {
 
 class SizeOnlyMemoryTracker : public MemoryTracker {
@@ -8654,15 +976,15 @@
     const size_t kInitialManagedPoolSize = 0;
     pool_infos_[MemoryTracker::kUnmanaged].initial_size =
         kInitialUnmanagedPoolSize;
-    pool_infos_[MemoryTracker::kManaged].initial_size =
-        kInitialManagedPoolSize;
+    pool_infos_[MemoryTracker::kManaged].initial_size = kInitialManagedPoolSize;
   }
 
   // Ensure a certain amount of GPU memory is free. Returns true on success.
   MOCK_METHOD1(EnsureGPUMemoryAvailable, bool(size_t size_needed));
 
-  virtual void TrackMemoryAllocatedChange(
-      size_t old_size, size_t new_size, Pool pool) {
+  virtual void TrackMemoryAllocatedChange(size_t old_size,
+                                          size_t new_size,
+                                          Pool pool) {
     PoolInfo& info = pool_infos_[pool];
     info.size += new_size - old_size;
   }
@@ -8673,13 +995,9 @@
   }
 
  private:
-  virtual ~SizeOnlyMemoryTracker() {
-  }
+  virtual ~SizeOnlyMemoryTracker() {}
   struct PoolInfo {
-    PoolInfo()
-        : initial_size(0),
-          size(0) {
-    }
+    PoolInfo() : initial_size(0), size(0) {}
     size_t initial_size;
     size_t size;
   };
@@ -8688,7 +1006,7 @@
 
 }  // anonymous namespace.
 
-TEST_F(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) {
+TEST_P(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) {
   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
       new SizeOnlyMemoryTracker();
   set_memory_tracker(memory_tracker.get());
@@ -8701,7 +1019,7 @@
   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
 }
 
-TEST_F(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) {
+TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) {
   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
       new SizeOnlyMemoryTracker();
   set_memory_tracker(memory_tracker.get());
@@ -8711,28 +1029,55 @@
   InitDecoder(init);
   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
-      .WillOnce(Return(true)).RetiresOnSaturation();
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               kSharedMemoryId, kSharedMemoryOffset);
+      .WillOnce(Return(true))
+      .RetiresOnSaturation();
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGBA,
+               8,
+               4,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
-      .WillOnce(Return(true)).RetiresOnSaturation();
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-               kSharedMemoryId, kSharedMemoryOffset);
+      .WillOnce(Return(true))
+      .RetiresOnSaturation();
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGBA,
+               4,
+               4,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
   EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
   // Check we get out of memory and no call to glTexImage2D if Ensure fails.
   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
-      .WillOnce(Return(false)).RetiresOnSaturation();
+      .WillOnce(Return(false))
+      .RetiresOnSaturation();
   TexImage2D cmd;
-  cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
-           kSharedMemoryId, kSharedMemoryOffset);
+  cmd.Init(GL_TEXTURE_2D,
+           0,
+           GL_RGBA,
+           4,
+           4,
+           0,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
   EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
 }
 
-TEST_F(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) {
+TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) {
   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
       new SizeOnlyMemoryTracker();
   set_memory_tracker(memory_tracker.get());
@@ -8744,7 +1089,8 @@
   // Check we get out of memory and no call to glTexStorage2DEXT
   // if Ensure fails.
   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
-      .WillOnce(Return(false)).RetiresOnSaturation();
+      .WillOnce(Return(false))
+      .RetiresOnSaturation();
   TexStorage2DEXT cmd;
   cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4);
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -8752,7 +1098,7 @@
   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
 }
 
-TEST_F(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) {
+TEST_P(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) {
   GLenum target = GL_TEXTURE_2D;
   GLint level = 0;
   GLenum internal_format = GL_RGBA;
@@ -8770,13 +1116,15 @@
   InitDecoder(init);
   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
-      .WillOnce(Return(true)).RetiresOnSaturation();
+      .WillOnce(Return(true))
+      .RetiresOnSaturation();
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
       .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, CopyTexImage2D(
-      target, level, internal_format, 0, 0, width, height, border))
+  EXPECT_CALL(*gl_,
+              CopyTexImage2D(
+                  target, level, internal_format, 0, 0, width, height, border))
       .Times(1)
       .RetiresOnSaturation();
   CopyTexImage2D cmd;
@@ -8786,13 +1134,14 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
   // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
-      .WillOnce(Return(false)).RetiresOnSaturation();
+      .WillOnce(Return(false))
+      .RetiresOnSaturation();
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
 }
 
-TEST_F(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) {
+TEST_P(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) {
   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
       new SizeOnlyMemoryTracker();
   set_memory_tracker(memory_tracker.get());
@@ -8800,16 +1149,16 @@
   init.gl_version = "3.0";
   init.bind_generates_resource = true;
   InitDecoder(init);
-  DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
-                    kServiceRenderbufferId);
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
       .RetiresOnSaturation();
   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
-      .WillOnce(Return(true)).RetiresOnSaturation();
-  EXPECT_CALL(*gl_, RenderbufferStorageEXT(
-      GL_RENDERBUFFER, GL_RGBA, 8, 4))
+      .WillOnce(Return(true))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 8, 4))
       .Times(1)
       .RetiresOnSaturation();
   RenderbufferStorage cmd;
@@ -8820,13 +1169,14 @@
   // Check we get out of memory and no call to glRenderbufferStorage if Ensure
   // fails.
   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
-      .WillOnce(Return(false)).RetiresOnSaturation();
+      .WillOnce(Return(false))
+      .RetiresOnSaturation();
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
 }
 
-TEST_F(GLES2DecoderManualInitTest, MemoryTrackerBufferData) {
+TEST_P(GLES2DecoderManualInitTest, MemoryTrackerBufferData) {
   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
       new SizeOnlyMemoryTracker();
   set_memory_tracker(memory_tracker.get());
@@ -8834,14 +1184,14 @@
   init.gl_version = "3.0";
   init.bind_generates_resource = true;
   InitDecoder(init);
-  DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_,
-               kServiceBufferId);
+  DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
       .RetiresOnSaturation();
   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
-      .WillOnce(Return(true)).RetiresOnSaturation();
+      .WillOnce(Return(true))
+      .RetiresOnSaturation();
   EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW))
       .Times(1)
       .RetiresOnSaturation();
@@ -8853,731 +1203,22 @@
   // Check we get out of memory and no call to glBufferData if Ensure
   // fails.
   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
-      .WillOnce(Return(false)).RetiresOnSaturation();
+      .WillOnce(Return(false))
+      .RetiresOnSaturation();
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
 }
 
-TEST_F(GLES2DecoderTest, DrawBuffersEXTImmediateSuccceeds) {
-  const GLsizei count = 1;
-  const GLenum bufs[] = { GL_COLOR_ATTACHMENT0 };
-  DrawBuffersEXTImmediate& cmd =
-      *GetImmediateAs<DrawBuffersEXTImmediate>();
-  cmd.Init(count, bufs);
+INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest, ::testing::Bool());
 
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  EXPECT_CALL(*gl_, DrawBuffersARB(count, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_EQ(error::kNoError,
-            ExecuteImmediateCmd(cmd, sizeof(bufs)));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
+INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderWithShaderTest, ::testing::Bool());
 
-TEST_F(GLES2DecoderTest, DrawBuffersEXTImmediateFails) {
-  const GLsizei count = 1;
-  const GLenum bufs[] = { GL_COLOR_ATTACHMENT1_EXT };
-  DrawBuffersEXTImmediate& cmd =
-      *GetImmediateAs<DrawBuffersEXTImmediate>();
-  cmd.Init(count, bufs);
+INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderManualInitTest, ::testing::Bool());
 
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  EXPECT_EQ(error::kNoError,
-            ExecuteImmediateCmd(cmd, sizeof(bufs)));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderTest, DrawBuffersEXTImmediateBackbuffer) {
-  const GLsizei count = 1;
-  const GLenum bufs[] = { GL_BACK };
-  DrawBuffersEXTImmediate& cmd =
-      *GetImmediateAs<DrawBuffersEXTImmediate>();
-  cmd.Init(count, bufs);
-
-  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
-                    kServiceFramebufferId);
-  EXPECT_EQ(error::kNoError,
-            ExecuteImmediateCmd(cmd, sizeof(bufs)));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-
-  DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);  // unbind
-
-  EXPECT_CALL(*gl_, DrawBuffersARB(count, _))
-      .Times(1)
-      .RetiresOnSaturation();
-
-  EXPECT_EQ(error::kNoError,
-            ExecuteImmediateCmd(cmd, sizeof(bufs)));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, InvalidateFramebufferBinding) {
-  InitState init;
-  init.gl_version = "opengl es 3.0";
-  InitDecoder(init);
-
-  // EXPECT_EQ can't be used to compare function pointers
-  EXPECT_TRUE(
-      gfx::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") ==
-      gfx::g_driver_gl.fn.glDiscardFramebufferEXTFn);
-  EXPECT_TRUE(
-      gfx::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") !=
-      gfx::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT"));
-}
-
-TEST_F(GLES2DecoderManualInitTest, DiscardFramebufferEXT) {
-  InitState init;
-  init.extensions = "GL_EXT_discard_framebuffer";
-  init.gl_version = "opengl es 2.0";
-  InitDecoder(init);
-
-  // EXPECT_EQ can't be used to compare function pointers
-  EXPECT_TRUE(
-      gfx::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") ==
-      gfx::g_driver_gl.fn.glDiscardFramebufferEXTFn);
-
-  const GLenum target = GL_FRAMEBUFFER;
-  const GLsizei count = 1;
-  const GLenum attachments[] = { GL_COLOR_ATTACHMENT0 };
-
-  SetupTexture();
-  DoBindFramebuffer(
-      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(GL_FRAMEBUFFER,
-                         GL_COLOR_ATTACHMENT0,
-                         GL_TEXTURE_2D,
-                         client_texture_id_,
-                         kServiceTextureId,
-                         0,
-                         GL_NO_ERROR);
-  FramebufferManager* framebuffer_manager = group().framebuffer_manager();
-  Framebuffer* framebuffer =
-      framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
-  EXPECT_TRUE(framebuffer->IsCleared());
-
-  EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  DiscardFramebufferEXTImmediate& cmd =
-      *GetImmediateAs<DiscardFramebufferEXTImmediate>();
-  cmd.Init(target, count, attachments);
-
-  EXPECT_EQ(error::kNoError,
-            ExecuteImmediateCmd(cmd, sizeof(attachments)));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  EXPECT_FALSE(framebuffer->IsCleared());
-}
-
-TEST_F(GLES2DecoderTest, DiscardFramebufferEXTUnsupported) {
-  const GLenum target = GL_FRAMEBUFFER;
-  const GLsizei count = 1;
-  const GLenum attachments[] = { GL_COLOR_EXT };
-  DiscardFramebufferEXTImmediate& cmd =
-      *GetImmediateAs<DiscardFramebufferEXTImmediate>();
-  cmd.Init(target, count, attachments);
-
-  // Should not result into a call into GL.
-  EXPECT_EQ(error::kNoError,
-            ExecuteImmediateCmd(cmd, sizeof(attachments)));
-  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
-}
-
-TEST_F(GLES2DecoderRestoreStateTest, NullPreviousStateBGR) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  SetupTexture();
-
-  InSequence sequence;
-  // Expect to restore texture bindings for unit GL_TEXTURE0.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
-  AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP,
-                                TestHelper::kServiceDefaultTextureCubemapId);
-
-  // Expect to restore texture bindings for remaining units.
-  for (uint32 i = 1; i < group().max_texture_units() ; ++i) {
-    AddExpectationsForActiveTexture(GL_TEXTURE0 + i);
-    AddExpectationsForBindTexture(GL_TEXTURE_2D,
-                                  TestHelper::kServiceDefaultTexture2dId);
-    AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP,
-                                  TestHelper::kServiceDefaultTextureCubemapId);
-  }
-
-  // Expect to restore the active texture unit to GL_TEXTURE0.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-
-  GetDecoder()->RestoreAllTextureUnitBindings(NULL);
-}
-
-TEST_F(GLES2DecoderRestoreStateTest, NullPreviousState) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-  SetupTexture();
-
-  InSequence sequence;
-  // Expect to restore texture bindings for unit GL_TEXTURE0.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
-  AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0);
-
-  // Expect to restore texture bindings for remaining units.
-  for (uint32 i = 1; i < group().max_texture_units(); ++i) {
-    AddExpectationsForActiveTexture(GL_TEXTURE0 + i);
-    AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);
-    AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0);
-  }
-
-  // Expect to restore the active texture unit to GL_TEXTURE0.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-
-  GetDecoder()->RestoreAllTextureUnitBindings(NULL);
-}
-
-TEST_F(GLES2DecoderRestoreStateTest, WithPreviousStateBGR) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-  SetupTexture();
-
-  // Construct a previous ContextState with all texture bindings
-  // set to default textures.
-  ContextState prev_state(NULL, NULL, NULL);
-  InitializeContextState(&prev_state, std::numeric_limits<uint32>::max(), 0);
-
-  InSequence sequence;
-  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE0 unit,
-  // since the rest of the bindings haven't changed between the current
-  // state and the |prev_state|.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
-
-  // Expect to restore active texture unit to GL_TEXTURE0.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-
-  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
-}
-
-TEST_F(GLES2DecoderRestoreStateTest, WithPreviousState) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-  SetupTexture();
-
-  // Construct a previous ContextState with all texture bindings
-  // set to default textures.
-  ContextState prev_state(NULL, NULL, NULL);
-  InitializeContextState(&prev_state, std::numeric_limits<uint32>::max(), 0);
-
-  InSequence sequence;
-  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE0 unit,
-  // since the rest of the bindings haven't changed between the current
-  // state and the |prev_state|.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
-
-  // Expect to restore active texture unit to GL_TEXTURE0.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-
-  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
-}
-
-TEST_F(GLES2DecoderRestoreStateTest, ActiveUnit1) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-
-  // Bind a non-default texture to GL_TEXTURE1 unit.
-  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
-  ActiveTexture cmd;
-  cmd.Init(GL_TEXTURE1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  SetupTexture();
-
-  // Construct a previous ContextState with all texture bindings
-  // set to default textures.
-  ContextState prev_state(NULL, NULL, NULL);
-  InitializeContextState(&prev_state, std::numeric_limits<uint32>::max(), 0);
-
-  InSequence sequence;
-  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE1 unit,
-  // since the rest of the bindings haven't changed between the current
-  // state and the |prev_state|.
-  AddExpectationsForActiveTexture(GL_TEXTURE1);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
-
-  // Expect to restore active texture unit to GL_TEXTURE1.
-  AddExpectationsForActiveTexture(GL_TEXTURE1);
-
-  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
-}
-
-TEST_F(GLES2DecoderRestoreStateTest, NonDefaultUnit0BGR) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  // Bind a non-default texture to GL_TEXTURE1 unit.
-  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
-  SpecializedSetup<ActiveTexture, 0>(true);
-  ActiveTexture cmd;
-  cmd.Init(GL_TEXTURE1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  SetupTexture();
-
-  // Construct a previous ContextState with GL_TEXTURE_2D target in
-  // GL_TEXTURE0 unit bound to a non-default texture and the rest
-  // set to default textures.
-  ContextState prev_state(NULL, NULL, NULL);
-  InitializeContextState(&prev_state, 0, kServiceTextureId);
-
-  InSequence sequence;
-  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE0 unit to
-  // a default texture.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D,
-                                TestHelper::kServiceDefaultTexture2dId);
-
-  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE1 unit to
-  // non-default.
-  AddExpectationsForActiveTexture(GL_TEXTURE1);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
-
-  // Expect to restore active texture unit to GL_TEXTURE1.
-  AddExpectationsForActiveTexture(GL_TEXTURE1);
-
-  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
-}
-
-TEST_F(GLES2DecoderRestoreStateTest, NonDefaultUnit1BGR) {
-  InitState init;
-  init.gl_version = "3.0";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  // Bind a non-default texture to GL_TEXTURE0 unit.
-  SetupTexture();
-
-  // Construct a previous ContextState with GL_TEXTURE_2D target in
-  // GL_TEXTURE1 unit bound to a non-default texture and the rest
-  // set to default textures.
-  ContextState prev_state(NULL, NULL, NULL);
-  InitializeContextState(&prev_state, 1, kServiceTextureId);
-
-  InSequence sequence;
-  // Expect to restore GL_TEXTURE_2D binding to the non-default texture
-  // for GL_TEXTURE0 unit.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
-
-  // Expect to restore GL_TEXTURE_2D binding to the default texture
-  // for GL_TEXTURE1 unit.
-  AddExpectationsForActiveTexture(GL_TEXTURE1);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D,
-                                TestHelper::kServiceDefaultTexture2dId);
-
-  // Expect to restore active texture unit to GL_TEXTURE0.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-
-  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
-}
-
-TEST_F(GLES2DecoderRestoreStateTest, DefaultUnit0) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-
-  // Bind a non-default texture to GL_TEXTURE1 unit.
-  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
-  SpecializedSetup<ActiveTexture, 0>(true);
-  ActiveTexture cmd;
-  cmd.Init(GL_TEXTURE1);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-  SetupTexture();
-
-  // Construct a previous ContextState with GL_TEXTURE_2D target in
-  // GL_TEXTURE0 unit bound to a non-default texture and the rest
-  // set to default textures.
-  ContextState prev_state(NULL, NULL, NULL);
-  InitializeContextState(&prev_state, 0, kServiceTextureId);
-
-  InSequence sequence;
-  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE0 unit to
-  // the 0 texture.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);
-
-  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE1 unit to
-  // non-default.
-  AddExpectationsForActiveTexture(GL_TEXTURE1);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
-
-  // Expect to restore active texture unit to GL_TEXTURE1.
-  AddExpectationsForActiveTexture(GL_TEXTURE1);
-
-  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
-}
-
-TEST_F(GLES2DecoderRestoreStateTest, DefaultUnit1) {
-  InitState init;
-  init.gl_version = "3.0";
-  InitDecoder(init);
-
-  // Bind a non-default texture to GL_TEXTURE0 unit.
-  SetupTexture();
-
-  // Construct a previous ContextState with GL_TEXTURE_2D target in
-  // GL_TEXTURE1 unit bound to a non-default texture and the rest
-  // set to default textures.
-  ContextState prev_state(NULL, NULL, NULL);
-  InitializeContextState(&prev_state, 1, kServiceTextureId);
-
-  InSequence sequence;
-  // Expect to restore GL_TEXTURE_2D binding to the non-default texture
-  // for GL_TEXTURE0 unit.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
-
-  // Expect to restore GL_TEXTURE_2D binding to the 0 texture
-  // for GL_TEXTURE1 unit.
-  AddExpectationsForActiveTexture(GL_TEXTURE1);
-  AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);
-
-  // Expect to restore active texture unit to GL_TEXTURE0.
-  AddExpectationsForActiveTexture(GL_TEXTURE0);
-
-  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
-}
-
-// TODO(vmiura): Tests for VAO restore.
-
-// TODO(vmiura): Tests for ContextState::RestoreAttribute().
-
-// TODO(vmiura): Tests for ContextState::RestoreBufferBindings().
-
-// TODO(vmiura): Tests for ContextState::RestoreProgramBindings().
-
-// TODO(vmiura): Tests for RestoreRenderbufferBindings().
-
-// TODO(vmiura): Tests for RestoreProgramBindings().
-
-// TODO(vmiura): Tests for RestoreGlobalState().
-
-TEST_F(GLES2DecoderManualInitTest, ClearUniformsBeforeFirstProgramUse) {
-  CommandLine command_line(0, NULL);
-  command_line.AppendSwitchASCII(
-      switches::kGpuDriverBugWorkarounds,
-      base::IntToString(gpu::CLEAR_UNIFORMS_BEFORE_FIRST_PROGRAM_USE));
-  InitState init;
-  init.gl_version = "3.0";
-  init.has_alpha = true;
-  init.request_alpha = true;
-  init.bind_generates_resource = true;
-  InitDecoderWithCommandLine(init, &command_line);
-  {
-    static AttribInfo attribs[] = {
-      { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
-      { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
-      { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
-    };
-    static UniformInfo uniforms[] = {
-      { kUniform1Name, kUniform1Size, kUniform1Type,
-        kUniform1FakeLocation, kUniform1RealLocation,
-        kUniform1DesiredLocation },
-      { kUniform2Name, kUniform2Size, kUniform2Type,
-        kUniform2FakeLocation, kUniform2RealLocation,
-        kUniform2DesiredLocation },
-      { kUniform3Name, kUniform3Size, kUniform3Type,
-        kUniform3FakeLocation, kUniform3RealLocation,
-        kUniform3DesiredLocation },
-    };
-    SetupShader(attribs, arraysize(attribs), uniforms, arraysize(uniforms),
-                client_program_id_, kServiceProgramId,
-                client_vertex_shader_id_, kServiceVertexShaderId,
-                client_fragment_shader_id_, kServiceFragmentShaderId);
-    TestHelper::SetupExpectationsForClearingUniforms(
-        gl_.get(), uniforms, arraysize(uniforms));
-  }
-
-  {
-    EXPECT_CALL(*gl_, UseProgram(kServiceProgramId))
-        .Times(1)
-        .RetiresOnSaturation();
-    cmds::UseProgram cmd;
-    cmd.Init(client_program_id_);
-    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  }
-}
-
-TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatOnGLES2) {
-  InitState init;
-  init.extensions = "GL_OES_texture_float";
-  init.gl_version = "opengl es 2.0";
-  InitDecoder(init);
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 17, 0, GL_LUMINANCE,
-               GL_FLOAT, 0, 0);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 17, 0, GL_ALPHA, GL_FLOAT,
-               0, 0);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16, 17, 0,
-               GL_LUMINANCE_ALPHA, GL_FLOAT, 0, 0);
-}
-
-TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatOnGLES3) {
-  InitState init;
-  init.extensions = "GL_OES_texture_float GL_EXT_color_buffer_float";
-  init.gl_version = "opengl es 3.0";
-  InitDecoder(init);
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 17, 0, GL_RGBA, GL_FLOAT, 0,
-               0);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 17, 0, GL_LUMINANCE,
-               GL_FLOAT, 0, 0);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 17, 0, GL_ALPHA, GL_FLOAT,
-               0, 0);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16, 17, 0,
-               GL_LUMINANCE_ALPHA, GL_FLOAT, 0, 0);
-}
-
-TEST_F(GLES2DecoderManualInitTest, TexSubImage2DFloatOnGLES3) {
-  InitState init;
-  init.extensions = "GL_OES_texture_float GL_EXT_color_buffer_float";
-  init.gl_version = "opengl es 3.0";
-  InitDecoder(init);
-  const int kWidth = 8;
-  const int kHeight = 4;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, kWidth, kHeight, 0, GL_RGBA,
-               GL_FLOAT, 0, 0);
-  EXPECT_CALL(*gl_, TexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA32F, kWidth, kHeight, 0, GL_RGBA, GL_FLOAT,
-      shared_memory_address_))
-      .Times(1)
-      .RetiresOnSaturation();
-  TexSubImage2D cmd;
-  cmd.Init(
-      GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_FLOAT,
-      kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, TexSubImage2DFloatDoesClearOnGLES3) {
-  InitState init;
-  init.extensions = "GL_OES_texture_float GL_EXT_color_buffer_float";
-  init.gl_version = "opengl es 3.0";
-  InitDecoder(init);
-  const int kWidth = 8;
-  const int kHeight = 4;
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, kWidth, kHeight, 0, GL_RGBA,
-               GL_FLOAT, 0, 0);
-  SetupClearTextureExpectations(
-      kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
-      0, GL_RGBA32F, GL_RGBA, GL_FLOAT, kWidth, kHeight);
-  EXPECT_CALL(*gl_, TexSubImage2D(
-      GL_TEXTURE_2D, 0, 1, 0, kWidth - 1, kHeight, GL_RGBA, GL_FLOAT,
-      shared_memory_address_))
-      .Times(1)
-      .RetiresOnSaturation();
-  TexSubImage2D cmd;
-  cmd.Init(
-      GL_TEXTURE_2D, 0, 1, 0, kWidth - 1, kHeight, GL_RGBA, GL_FLOAT,
-      kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatConvertsFormatDesktop) {
-  InitState init;
-  init.extensions = "GL_ARB_texture_float";
-  init.gl_version = "2.1";
-  InitDecoder(init);
-  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 17, 0, GL_RGBA, GL_FLOAT, 0,
-               0);
-  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
-  DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0,
-                                    GL_RGBA, GL_FLOAT, 0, 0, GL_RGBA32F_ARB);
-  DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0,
-                                    GL_RGB, GL_FLOAT, 0, 0, GL_RGB32F_ARB);
-  DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 17, 0,
-                                    GL_LUMINANCE, GL_FLOAT, 0, 0,
-                                    GL_LUMINANCE32F_ARB);
-  DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 17, 0,
-                                    GL_ALPHA, GL_FLOAT, 0, 0, GL_ALPHA32F_ARB);
-  DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16,
-                                    17, 0, GL_LUMINANCE_ALPHA, GL_FLOAT, 0, 0,
-                                    GL_LUMINANCE_ALPHA32F_ARB);
-}
-
-TEST_F(GLES2DecoderManualInitTest, ReadFormatExtension) {
-  InitState init;
-  init.extensions = "GL_OES_read_format";
-  init.gl_version = "2.1";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetError())
-      .Times(6)
-      .RetiresOnSaturation();
-
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  GetIntegerv cmd;
-  const GLuint kFBOClientTextureId = 4100;
-  const GLuint kFBOServiceTextureId = 4101;
-
-  // Register a texture id.
-  EXPECT_CALL(*gl_, GenTextures(_, _))
-      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
-      .RetiresOnSaturation();
-  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
-
-  // Setup "render to" texture.
-  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
-  DoBindFramebuffer(
-      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
-
-  result->size = 0;
-  EXPECT_CALL(*gl_, GetIntegerv(_, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  cmd.Init(
-      GL_IMPLEMENTATION_COLOR_READ_FORMAT,
-      shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(1, result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  result->size = 0;
-  EXPECT_CALL(*gl_, GetIntegerv(_, _))
-      .Times(1)
-      .RetiresOnSaturation();
-  cmd.Init(
-      GL_IMPLEMENTATION_COLOR_READ_TYPE,
-      shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(1, result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_F(GLES2DecoderManualInitTest, NoReadFormatExtension) {
-  InitState init;
-  init.gl_version = "2.1";
-  init.bind_generates_resource = true;
-  InitDecoder(init);
-
-  EXPECT_CALL(*gl_, GetError())
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .WillOnce(Return(GL_NO_ERROR))
-      .RetiresOnSaturation();
-
-  typedef GetIntegerv::Result Result;
-  Result* result = static_cast<Result*>(shared_memory_address_);
-  GetIntegerv cmd;
-  const GLuint kFBOClientTextureId = 4100;
-  const GLuint kFBOServiceTextureId = 4101;
-
-  // Register a texture id.
-  EXPECT_CALL(*gl_, GenTextures(_, _))
-      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
-      .RetiresOnSaturation();
-  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
-
-  // Setup "render to" texture.
-  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
-  DoTexImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
-  DoBindFramebuffer(
-      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
-  DoFramebufferTexture2D(
-      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-      kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
-
-  result->size = 0;
-  EXPECT_CALL(*gl_, GetIntegerv(_, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  cmd.Init(
-      GL_IMPLEMENTATION_COLOR_READ_FORMAT,
-      shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(1, result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-
-  result->size = 0;
-  EXPECT_CALL(*gl_, GetIntegerv(_, _))
-      .Times(0)
-      .RetiresOnSaturation();
-  cmd.Init(
-      GL_IMPLEMENTATION_COLOR_READ_TYPE,
-      shared_memory_id_, shared_memory_offset_);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(1, result->GetNumResults());
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-// TODO(gman): Complete this test.
-// TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) {
-// }
-
-// TODO(gman): BufferData
-
-// TODO(gman): BufferDataImmediate
-
-// TODO(gman): BufferSubData
-
-// TODO(gman): BufferSubDataImmediate
-
-// TODO(gman): CompressedTexImage2D
-
-// TODO(gman): CompressedTexImage2DImmediate
-
-// TODO(gman): CompressedTexSubImage2DImmediate
-
-// TODO(gman): DeleteProgram
-
-// TODO(gman): DeleteShader
-
-// TODO(gman): PixelStorei
-
-// TODO(gman): TexImage2D
-
-// TODO(gman): TexImage2DImmediate
-
-// TODO(gman): TexSubImage2DImmediate
-
-// TODO(gman): UseProgram
-
-// TODO(gman): SwapBuffers
+INSTANTIATE_TEST_CASE_P(Service,
+                        GLES2DecoderRGBBackbufferTest,
+                        ::testing::Bool());
 
 }  // namespace gles2
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h
new file mode 100644
index 0000000..fea20ab
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.h
@@ -0,0 +1,80 @@
+// 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.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_H_
+#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_H_
+
+#include "gpu/command_buffer/common/gles2_cmd_format.h"
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/service/buffer_manager.h"
+#include "gpu/command_buffer/service/cmd_buffer_engine.h"
+#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/framebuffer_manager.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h"
+#include "gpu/command_buffer/service/program_manager.h"
+#include "gpu/command_buffer/service/query_manager.h"
+#include "gpu/command_buffer/service/renderbuffer_manager.h"
+#include "gpu/command_buffer/service/shader_manager.h"
+#include "gpu/command_buffer/service/test_helper.h"
+#include "gpu/command_buffer/service/texture_manager.h"
+#include "gpu/command_buffer/service/vertex_array_manager.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/gl_context_stub_with_extensions.h"
+#include "ui/gl/gl_mock.h"
+#include "ui/gl/gl_surface_stub.h"
+
+namespace base {
+class CommandLine;
+}
+
+namespace gpu {
+namespace gles2 {
+
+class GLES2DecoderTest : public GLES2DecoderTestBase {
+ public:
+  GLES2DecoderTest() {}
+
+ protected:
+  void CheckReadPixelsOutOfRange(GLint in_read_x,
+                                 GLint in_read_y,
+                                 GLsizei in_read_width,
+                                 GLsizei in_read_height,
+                                 bool init);
+};
+
+class GLES2DecoderWithShaderTest : public GLES2DecoderWithShaderTestBase {
+ public:
+  GLES2DecoderWithShaderTest() : GLES2DecoderWithShaderTestBase() {}
+
+  void CheckTextureChangesMarkFBOAsNotComplete(bool bound_fbo);
+  void CheckRenderbufferChangesMarkFBOAsNotComplete(bool bound_fbo);
+};
+
+class GLES2DecoderRGBBackbufferTest : public GLES2DecoderWithShaderTest {
+ public:
+  GLES2DecoderRGBBackbufferTest() {}
+
+  virtual void SetUp();
+};
+
+class GLES2DecoderManualInitTest : public GLES2DecoderWithShaderTest {
+ public:
+  GLES2DecoderManualInitTest() {}
+
+  // Override default setup so nothing gets setup.
+  virtual void SetUp();
+
+  void DirtyStateMaskTest(GLuint color_bits,
+                          bool depth_mask,
+                          GLuint front_stencil_mask,
+                          GLuint back_stencil_mask);
+  void EnableDisableTest(GLenum cap, bool enable, bool expect_set);
+};
+
+}  // namespace gles2
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
index 7da87dd..f851473 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
@@ -37,6 +37,8 @@
   GLES2DecoderTest1() { }
 };
 
+INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest1, ::testing::Bool());
+
 template <>
 void GLES2DecoderTestBase::SpecializedSetup<cmds::GenerateMipmap, 0>(
     bool valid) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
index 17cf9c5..ebe62fb 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
@@ -14,7 +14,7 @@
 
 // TODO(gman): ActiveTexture
 
-TEST_F(GLES2DecoderTest1, AttachShaderValidArgs) {
+TEST_P(GLES2DecoderTest1, AttachShaderValidArgs) {
   EXPECT_CALL(*gl_, AttachShader(kServiceProgramId, kServiceShaderId));
   SpecializedSetup<cmds::AttachShader, 0>(true);
   cmds::AttachShader cmd;
@@ -26,7 +26,7 @@
 
 // TODO(gman): BindAttribLocationBucket
 
-TEST_F(GLES2DecoderTest1, BindBufferValidArgs) {
+TEST_P(GLES2DecoderTest1, BindBufferValidArgs) {
   EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, kServiceBufferId));
   SpecializedSetup<cmds::BindBuffer, 0>(true);
   cmds::BindBuffer cmd;
@@ -35,7 +35,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BindBufferValidArgsNewId) {
+TEST_P(GLES2DecoderTest1, BindBufferValidArgsNewId) {
   EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, kNewServiceId));
   EXPECT_CALL(*gl_, GenBuffersARB(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
@@ -47,7 +47,7 @@
   EXPECT_TRUE(GetBuffer(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, BindBufferInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, BindBufferInvalidArgs0_0) {
   EXPECT_CALL(*gl_, BindBuffer(_, _)).Times(0);
   SpecializedSetup<cmds::BindBuffer, 0>(false);
   cmds::BindBuffer cmd;
@@ -56,7 +56,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BindFramebufferValidArgs) {
+TEST_P(GLES2DecoderTest1, BindFramebufferValidArgs) {
   EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER, kServiceFramebufferId));
   SpecializedSetup<cmds::BindFramebuffer, 0>(true);
   cmds::BindFramebuffer cmd;
@@ -65,7 +65,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BindFramebufferValidArgsNewId) {
+TEST_P(GLES2DecoderTest1, BindFramebufferValidArgsNewId) {
   EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER, kNewServiceId));
   EXPECT_CALL(*gl_, GenFramebuffersEXT(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
@@ -77,7 +77,7 @@
   EXPECT_TRUE(GetFramebuffer(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, BindFramebufferInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, BindFramebufferInvalidArgs0_0) {
   EXPECT_CALL(*gl_, BindFramebufferEXT(_, _)).Times(0);
   SpecializedSetup<cmds::BindFramebuffer, 0>(false);
   cmds::BindFramebuffer cmd;
@@ -86,7 +86,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BindFramebufferInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, BindFramebufferInvalidArgs0_1) {
   EXPECT_CALL(*gl_, BindFramebufferEXT(_, _)).Times(0);
   SpecializedSetup<cmds::BindFramebuffer, 0>(false);
   cmds::BindFramebuffer cmd;
@@ -95,7 +95,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BindRenderbufferValidArgs) {
+TEST_P(GLES2DecoderTest1, BindRenderbufferValidArgs) {
   EXPECT_CALL(*gl_,
               BindRenderbufferEXT(GL_RENDERBUFFER, kServiceRenderbufferId));
   SpecializedSetup<cmds::BindRenderbuffer, 0>(true);
@@ -105,7 +105,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BindRenderbufferValidArgsNewId) {
+TEST_P(GLES2DecoderTest1, BindRenderbufferValidArgsNewId) {
   EXPECT_CALL(*gl_, BindRenderbufferEXT(GL_RENDERBUFFER, kNewServiceId));
   EXPECT_CALL(*gl_, GenRenderbuffersEXT(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
@@ -117,7 +117,7 @@
   EXPECT_TRUE(GetRenderbuffer(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, BindRenderbufferInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, BindRenderbufferInvalidArgs0_0) {
   EXPECT_CALL(*gl_, BindRenderbufferEXT(_, _)).Times(0);
   SpecializedSetup<cmds::BindRenderbuffer, 0>(false);
   cmds::BindRenderbuffer cmd;
@@ -126,7 +126,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BindTextureValidArgs) {
+TEST_P(GLES2DecoderTest1, BindTextureValidArgs) {
   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId));
   SpecializedSetup<cmds::BindTexture, 0>(true);
   cmds::BindTexture cmd;
@@ -135,7 +135,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BindTextureValidArgsNewId) {
+TEST_P(GLES2DecoderTest1, BindTextureValidArgsNewId) {
   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kNewServiceId));
   EXPECT_CALL(*gl_, GenTextures(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
@@ -147,7 +147,7 @@
   EXPECT_TRUE(GetTexture(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, BindTextureInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, BindTextureInvalidArgs0_0) {
   EXPECT_CALL(*gl_, BindTexture(_, _)).Times(0);
   SpecializedSetup<cmds::BindTexture, 0>(false);
   cmds::BindTexture cmd;
@@ -156,7 +156,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BindTextureInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, BindTextureInvalidArgs0_1) {
   EXPECT_CALL(*gl_, BindTexture(_, _)).Times(0);
   SpecializedSetup<cmds::BindTexture, 0>(false);
   cmds::BindTexture cmd;
@@ -165,7 +165,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BlendColorValidArgs) {
+TEST_P(GLES2DecoderTest1, BlendColorValidArgs) {
   EXPECT_CALL(*gl_, BlendColor(1, 2, 3, 4));
   SpecializedSetup<cmds::BlendColor, 0>(true);
   cmds::BlendColor cmd;
@@ -174,7 +174,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BlendEquationValidArgs) {
+TEST_P(GLES2DecoderTest1, BlendEquationValidArgs) {
   EXPECT_CALL(*gl_, BlendEquation(GL_FUNC_SUBTRACT));
   SpecializedSetup<cmds::BlendEquation, 0>(true);
   cmds::BlendEquation cmd;
@@ -183,7 +183,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BlendEquationInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, BlendEquationInvalidArgs0_0) {
   EXPECT_CALL(*gl_, BlendEquation(_)).Times(0);
   SpecializedSetup<cmds::BlendEquation, 0>(false);
   cmds::BlendEquation cmd;
@@ -192,7 +192,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BlendEquationInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, BlendEquationInvalidArgs0_1) {
   EXPECT_CALL(*gl_, BlendEquation(_)).Times(0);
   SpecializedSetup<cmds::BlendEquation, 0>(false);
   cmds::BlendEquation cmd;
@@ -201,7 +201,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BlendEquationSeparateValidArgs) {
+TEST_P(GLES2DecoderTest1, BlendEquationSeparateValidArgs) {
   EXPECT_CALL(*gl_, BlendEquationSeparate(GL_FUNC_SUBTRACT, GL_FUNC_ADD));
   SpecializedSetup<cmds::BlendEquationSeparate, 0>(true);
   cmds::BlendEquationSeparate cmd;
@@ -210,7 +210,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs0_0) {
   EXPECT_CALL(*gl_, BlendEquationSeparate(_, _)).Times(0);
   SpecializedSetup<cmds::BlendEquationSeparate, 0>(false);
   cmds::BlendEquationSeparate cmd;
@@ -219,7 +219,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs0_1) {
   EXPECT_CALL(*gl_, BlendEquationSeparate(_, _)).Times(0);
   SpecializedSetup<cmds::BlendEquationSeparate, 0>(false);
   cmds::BlendEquationSeparate cmd;
@@ -228,7 +228,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs1_0) {
   EXPECT_CALL(*gl_, BlendEquationSeparate(_, _)).Times(0);
   SpecializedSetup<cmds::BlendEquationSeparate, 0>(false);
   cmds::BlendEquationSeparate cmd;
@@ -237,7 +237,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs1_1) {
+TEST_P(GLES2DecoderTest1, BlendEquationSeparateInvalidArgs1_1) {
   EXPECT_CALL(*gl_, BlendEquationSeparate(_, _)).Times(0);
   SpecializedSetup<cmds::BlendEquationSeparate, 0>(false);
   cmds::BlendEquationSeparate cmd;
@@ -246,7 +246,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BlendFuncValidArgs) {
+TEST_P(GLES2DecoderTest1, BlendFuncValidArgs) {
   EXPECT_CALL(*gl_, BlendFunc(GL_ZERO, GL_ZERO));
   SpecializedSetup<cmds::BlendFunc, 0>(true);
   cmds::BlendFunc cmd;
@@ -255,7 +255,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, BlendFuncSeparateValidArgs) {
+TEST_P(GLES2DecoderTest1, BlendFuncSeparateValidArgs) {
   EXPECT_CALL(*gl_, BlendFuncSeparate(GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO));
   SpecializedSetup<cmds::BlendFuncSeparate, 0>(true);
   cmds::BlendFuncSeparate cmd;
@@ -267,7 +267,7 @@
 
 // TODO(gman): BufferSubData
 
-TEST_F(GLES2DecoderTest1, CheckFramebufferStatusValidArgs) {
+TEST_P(GLES2DecoderTest1, CheckFramebufferStatusValidArgs) {
   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER));
   SpecializedSetup<cmds::CheckFramebufferStatus, 0>(true);
   cmds::CheckFramebufferStatus cmd;
@@ -276,7 +276,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, CheckFramebufferStatusInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, CheckFramebufferStatusInvalidArgs0_0) {
   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(_)).Times(0);
   SpecializedSetup<cmds::CheckFramebufferStatus, 0>(false);
   cmds::CheckFramebufferStatus cmd;
@@ -285,7 +285,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, CheckFramebufferStatusInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, CheckFramebufferStatusInvalidArgs0_1) {
   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(_)).Times(0);
   SpecializedSetup<cmds::CheckFramebufferStatus, 0>(false);
   cmds::CheckFramebufferStatus cmd;
@@ -294,7 +294,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, CheckFramebufferStatusInvalidArgsBadSharedMemoryId) {
+TEST_P(GLES2DecoderTest1, CheckFramebufferStatusInvalidArgsBadSharedMemoryId) {
   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)).Times(0);
   SpecializedSetup<cmds::CheckFramebufferStatus, 0>(false);
   cmds::CheckFramebufferStatus cmd;
@@ -304,7 +304,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, ClearValidArgs) {
+TEST_P(GLES2DecoderTest1, ClearValidArgs) {
   EXPECT_CALL(*gl_, Clear(1));
   SpecializedSetup<cmds::Clear, 0>(true);
   cmds::Clear cmd;
@@ -313,7 +313,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, ClearColorValidArgs) {
+TEST_P(GLES2DecoderTest1, ClearColorValidArgs) {
   EXPECT_CALL(*gl_, ClearColor(1, 2, 3, 4));
   SpecializedSetup<cmds::ClearColor, 0>(true);
   cmds::ClearColor cmd;
@@ -322,7 +322,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, ClearDepthfValidArgs) {
+TEST_P(GLES2DecoderTest1, ClearDepthfValidArgs) {
   EXPECT_CALL(*gl_, ClearDepth(0.5f));
   SpecializedSetup<cmds::ClearDepthf, 0>(true);
   cmds::ClearDepthf cmd;
@@ -331,7 +331,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, ClearStencilValidArgs) {
+TEST_P(GLES2DecoderTest1, ClearStencilValidArgs) {
   EXPECT_CALL(*gl_, ClearStencil(1));
   SpecializedSetup<cmds::ClearStencil, 0>(true);
   cmds::ClearStencil cmd;
@@ -340,7 +340,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, ColorMaskValidArgs) {
+TEST_P(GLES2DecoderTest1, ColorMaskValidArgs) {
   SpecializedSetup<cmds::ColorMask, 0>(true);
   cmds::ColorMask cmd;
   cmd.Init(true, true, true, true);
@@ -356,7 +356,7 @@
 // TODO(gman): CompressedTexSubImage2DBucket
 // TODO(gman): CopyTexImage2D
 
-TEST_F(GLES2DecoderTest1, CopyTexSubImage2DValidArgs) {
+TEST_P(GLES2DecoderTest1, CopyTexSubImage2DValidArgs) {
   EXPECT_CALL(*gl_, CopyTexSubImage2D(GL_TEXTURE_2D, 2, 3, 4, 5, 6, 7, 8));
   SpecializedSetup<cmds::CopyTexSubImage2D, 0>(true);
   cmds::CopyTexSubImage2D cmd;
@@ -365,7 +365,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, CopyTexSubImage2DInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, CopyTexSubImage2DInvalidArgs0_0) {
   EXPECT_CALL(*gl_, CopyTexSubImage2D(_, _, _, _, _, _, _, _)).Times(0);
   SpecializedSetup<cmds::CopyTexSubImage2D, 0>(false);
   cmds::CopyTexSubImage2D cmd;
@@ -374,7 +374,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, CopyTexSubImage2DInvalidArgs6_0) {
+TEST_P(GLES2DecoderTest1, CopyTexSubImage2DInvalidArgs6_0) {
   EXPECT_CALL(*gl_, CopyTexSubImage2D(_, _, _, _, _, _, _, _)).Times(0);
   SpecializedSetup<cmds::CopyTexSubImage2D, 0>(false);
   cmds::CopyTexSubImage2D cmd;
@@ -383,7 +383,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, CopyTexSubImage2DInvalidArgs7_0) {
+TEST_P(GLES2DecoderTest1, CopyTexSubImage2DInvalidArgs7_0) {
   EXPECT_CALL(*gl_, CopyTexSubImage2D(_, _, _, _, _, _, _, _)).Times(0);
   SpecializedSetup<cmds::CopyTexSubImage2D, 0>(false);
   cmds::CopyTexSubImage2D cmd;
@@ -392,7 +392,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, CreateProgramValidArgs) {
+TEST_P(GLES2DecoderTest1, CreateProgramValidArgs) {
   EXPECT_CALL(*gl_, CreateProgram()).WillOnce(Return(kNewServiceId));
   SpecializedSetup<cmds::CreateProgram, 0>(true);
   cmds::CreateProgram cmd;
@@ -402,7 +402,7 @@
   EXPECT_TRUE(GetProgram(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, CreateShaderValidArgs) {
+TEST_P(GLES2DecoderTest1, CreateShaderValidArgs) {
   EXPECT_CALL(*gl_, CreateShader(GL_VERTEX_SHADER))
       .WillOnce(Return(kNewServiceId));
   SpecializedSetup<cmds::CreateShader, 0>(true);
@@ -413,7 +413,7 @@
   EXPECT_TRUE(GetShader(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, CreateShaderInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, CreateShaderInvalidArgs0_0) {
   EXPECT_CALL(*gl_, CreateShader(_)).Times(0);
   SpecializedSetup<cmds::CreateShader, 0>(false);
   cmds::CreateShader cmd;
@@ -422,7 +422,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, CullFaceValidArgs) {
+TEST_P(GLES2DecoderTest1, CullFaceValidArgs) {
   EXPECT_CALL(*gl_, CullFace(GL_FRONT));
   SpecializedSetup<cmds::CullFace, 0>(true);
   cmds::CullFace cmd;
@@ -431,7 +431,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, DeleteBuffersValidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteBuffersValidArgs) {
   EXPECT_CALL(*gl_, DeleteBuffersARB(1, Pointee(kServiceBufferId))).Times(1);
   GetSharedMemoryAs<GLuint*>()[0] = client_buffer_id_;
   SpecializedSetup<cmds::DeleteBuffers, 0>(true);
@@ -442,7 +442,7 @@
   EXPECT_TRUE(GetBuffer(client_buffer_id_) == NULL);
 }
 
-TEST_F(GLES2DecoderTest1, DeleteBuffersInvalidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteBuffersInvalidArgs) {
   GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
   SpecializedSetup<cmds::DeleteBuffers, 0>(false);
   cmds::DeleteBuffers cmd;
@@ -450,7 +450,7 @@
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, DeleteBuffersImmediateValidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteBuffersImmediateValidArgs) {
   EXPECT_CALL(*gl_, DeleteBuffersARB(1, Pointee(kServiceBufferId))).Times(1);
   cmds::DeleteBuffersImmediate& cmd =
       *GetImmediateAs<cmds::DeleteBuffersImmediate>();
@@ -462,7 +462,7 @@
   EXPECT_TRUE(GetBuffer(client_buffer_id_) == NULL);
 }
 
-TEST_F(GLES2DecoderTest1, DeleteBuffersImmediateInvalidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteBuffersImmediateInvalidArgs) {
   cmds::DeleteBuffersImmediate& cmd =
       *GetImmediateAs<cmds::DeleteBuffersImmediate>();
   SpecializedSetup<cmds::DeleteBuffersImmediate, 0>(false);
@@ -471,7 +471,7 @@
   EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
 }
 
-TEST_F(GLES2DecoderTest1, DeleteFramebuffersValidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteFramebuffersValidArgs) {
   EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, Pointee(kServiceFramebufferId)))
       .Times(1);
   GetSharedMemoryAs<GLuint*>()[0] = client_framebuffer_id_;
@@ -483,7 +483,7 @@
   EXPECT_TRUE(GetFramebuffer(client_framebuffer_id_) == NULL);
 }
 
-TEST_F(GLES2DecoderTest1, DeleteFramebuffersInvalidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteFramebuffersInvalidArgs) {
   GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
   SpecializedSetup<cmds::DeleteFramebuffers, 0>(false);
   cmds::DeleteFramebuffers cmd;
@@ -491,7 +491,7 @@
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, DeleteFramebuffersImmediateValidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteFramebuffersImmediateValidArgs) {
   EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, Pointee(kServiceFramebufferId)))
       .Times(1);
   cmds::DeleteFramebuffersImmediate& cmd =
@@ -504,7 +504,7 @@
   EXPECT_TRUE(GetFramebuffer(client_framebuffer_id_) == NULL);
 }
 
-TEST_F(GLES2DecoderTest1, DeleteFramebuffersImmediateInvalidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteFramebuffersImmediateInvalidArgs) {
   cmds::DeleteFramebuffersImmediate& cmd =
       *GetImmediateAs<cmds::DeleteFramebuffersImmediate>();
   SpecializedSetup<cmds::DeleteFramebuffersImmediate, 0>(false);
@@ -513,7 +513,7 @@
   EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
 }
 
-TEST_F(GLES2DecoderTest1, DeleteProgramValidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteProgramValidArgs) {
   EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId));
   SpecializedSetup<cmds::DeleteProgram, 0>(true);
   cmds::DeleteProgram cmd;
@@ -522,7 +522,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, DeleteRenderbuffersValidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteRenderbuffersValidArgs) {
   EXPECT_CALL(*gl_, DeleteRenderbuffersEXT(1, Pointee(kServiceRenderbufferId)))
       .Times(1);
   GetSharedMemoryAs<GLuint*>()[0] = client_renderbuffer_id_;
@@ -534,7 +534,7 @@
   EXPECT_TRUE(GetRenderbuffer(client_renderbuffer_id_) == NULL);
 }
 
-TEST_F(GLES2DecoderTest1, DeleteRenderbuffersInvalidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteRenderbuffersInvalidArgs) {
   GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
   SpecializedSetup<cmds::DeleteRenderbuffers, 0>(false);
   cmds::DeleteRenderbuffers cmd;
@@ -542,7 +542,7 @@
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, DeleteRenderbuffersImmediateValidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteRenderbuffersImmediateValidArgs) {
   EXPECT_CALL(*gl_, DeleteRenderbuffersEXT(1, Pointee(kServiceRenderbufferId)))
       .Times(1);
   cmds::DeleteRenderbuffersImmediate& cmd =
@@ -555,7 +555,7 @@
   EXPECT_TRUE(GetRenderbuffer(client_renderbuffer_id_) == NULL);
 }
 
-TEST_F(GLES2DecoderTest1, DeleteRenderbuffersImmediateInvalidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteRenderbuffersImmediateInvalidArgs) {
   cmds::DeleteRenderbuffersImmediate& cmd =
       *GetImmediateAs<cmds::DeleteRenderbuffersImmediate>();
   SpecializedSetup<cmds::DeleteRenderbuffersImmediate, 0>(false);
@@ -564,7 +564,7 @@
   EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
 }
 
-TEST_F(GLES2DecoderTest1, DeleteShaderValidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteShaderValidArgs) {
   EXPECT_CALL(*gl_, DeleteShader(kServiceShaderId));
   SpecializedSetup<cmds::DeleteShader, 0>(true);
   cmds::DeleteShader cmd;
@@ -573,7 +573,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, DeleteTexturesValidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteTexturesValidArgs) {
   EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(kServiceTextureId))).Times(1);
   GetSharedMemoryAs<GLuint*>()[0] = client_texture_id_;
   SpecializedSetup<cmds::DeleteTextures, 0>(true);
@@ -584,7 +584,7 @@
   EXPECT_TRUE(GetTexture(client_texture_id_) == NULL);
 }
 
-TEST_F(GLES2DecoderTest1, DeleteTexturesInvalidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteTexturesInvalidArgs) {
   GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
   SpecializedSetup<cmds::DeleteTextures, 0>(false);
   cmds::DeleteTextures cmd;
@@ -592,7 +592,7 @@
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, DeleteTexturesImmediateValidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteTexturesImmediateValidArgs) {
   EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(kServiceTextureId))).Times(1);
   cmds::DeleteTexturesImmediate& cmd =
       *GetImmediateAs<cmds::DeleteTexturesImmediate>();
@@ -604,7 +604,7 @@
   EXPECT_TRUE(GetTexture(client_texture_id_) == NULL);
 }
 
-TEST_F(GLES2DecoderTest1, DeleteTexturesImmediateInvalidArgs) {
+TEST_P(GLES2DecoderTest1, DeleteTexturesImmediateInvalidArgs) {
   cmds::DeleteTexturesImmediate& cmd =
       *GetImmediateAs<cmds::DeleteTexturesImmediate>();
   SpecializedSetup<cmds::DeleteTexturesImmediate, 0>(false);
@@ -613,7 +613,7 @@
   EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
 }
 
-TEST_F(GLES2DecoderTest1, DepthFuncValidArgs) {
+TEST_P(GLES2DecoderTest1, DepthFuncValidArgs) {
   EXPECT_CALL(*gl_, DepthFunc(GL_NEVER));
   SpecializedSetup<cmds::DepthFunc, 0>(true);
   cmds::DepthFunc cmd;
@@ -622,7 +622,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, DepthMaskValidArgs) {
+TEST_P(GLES2DecoderTest1, DepthMaskValidArgs) {
   SpecializedSetup<cmds::DepthMask, 0>(true);
   cmds::DepthMask cmd;
   cmd.Init(true);
@@ -630,7 +630,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, DepthRangefValidArgs) {
+TEST_P(GLES2DecoderTest1, DepthRangefValidArgs) {
   EXPECT_CALL(*gl_, DepthRange(1, 2));
   SpecializedSetup<cmds::DepthRangef, 0>(true);
   cmds::DepthRangef cmd;
@@ -639,7 +639,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, DetachShaderValidArgs) {
+TEST_P(GLES2DecoderTest1, DetachShaderValidArgs) {
   EXPECT_CALL(*gl_, DetachShader(kServiceProgramId, kServiceShaderId));
   SpecializedSetup<cmds::DetachShader, 0>(true);
   cmds::DetachShader cmd;
@@ -648,8 +648,8 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, DisableValidArgs) {
-  EXPECT_CALL(*gl_, Disable(GL_BLEND));
+TEST_P(GLES2DecoderTest1, DisableValidArgs) {
+  SetupExpectationsForEnableDisable(GL_BLEND, false);
   SpecializedSetup<cmds::Disable, 0>(true);
   cmds::Disable cmd;
   cmd.Init(GL_BLEND);
@@ -657,7 +657,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, DisableInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, DisableInvalidArgs0_0) {
   EXPECT_CALL(*gl_, Disable(_)).Times(0);
   SpecializedSetup<cmds::Disable, 0>(false);
   cmds::Disable cmd;
@@ -666,7 +666,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, DisableInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, DisableInvalidArgs0_1) {
   EXPECT_CALL(*gl_, Disable(_)).Times(0);
   SpecializedSetup<cmds::Disable, 0>(false);
   cmds::Disable cmd;
@@ -675,7 +675,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, DisableVertexAttribArrayValidArgs) {
+TEST_P(GLES2DecoderTest1, DisableVertexAttribArrayValidArgs) {
   EXPECT_CALL(*gl_, DisableVertexAttribArray(1));
   SpecializedSetup<cmds::DisableVertexAttribArray, 0>(true);
   cmds::DisableVertexAttribArray cmd;
@@ -687,8 +687,8 @@
 
 // TODO(gman): DrawElements
 
-TEST_F(GLES2DecoderTest1, EnableValidArgs) {
-  EXPECT_CALL(*gl_, Enable(GL_BLEND));
+TEST_P(GLES2DecoderTest1, EnableValidArgs) {
+  SetupExpectationsForEnableDisable(GL_BLEND, true);
   SpecializedSetup<cmds::Enable, 0>(true);
   cmds::Enable cmd;
   cmd.Init(GL_BLEND);
@@ -696,7 +696,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, EnableInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, EnableInvalidArgs0_0) {
   EXPECT_CALL(*gl_, Enable(_)).Times(0);
   SpecializedSetup<cmds::Enable, 0>(false);
   cmds::Enable cmd;
@@ -705,7 +705,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, EnableInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, EnableInvalidArgs0_1) {
   EXPECT_CALL(*gl_, Enable(_)).Times(0);
   SpecializedSetup<cmds::Enable, 0>(false);
   cmds::Enable cmd;
@@ -714,7 +714,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, EnableVertexAttribArrayValidArgs) {
+TEST_P(GLES2DecoderTest1, EnableVertexAttribArrayValidArgs) {
   EXPECT_CALL(*gl_, EnableVertexAttribArray(1));
   SpecializedSetup<cmds::EnableVertexAttribArray, 0>(true);
   cmds::EnableVertexAttribArray cmd;
@@ -723,7 +723,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FinishValidArgs) {
+TEST_P(GLES2DecoderTest1, FinishValidArgs) {
   EXPECT_CALL(*gl_, Finish());
   SpecializedSetup<cmds::Finish, 0>(true);
   cmds::Finish cmd;
@@ -732,7 +732,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FlushValidArgs) {
+TEST_P(GLES2DecoderTest1, FlushValidArgs) {
   EXPECT_CALL(*gl_, Flush());
   SpecializedSetup<cmds::Flush, 0>(true);
   cmds::Flush cmd;
@@ -741,7 +741,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FramebufferRenderbufferValidArgs) {
+TEST_P(GLES2DecoderTest1, FramebufferRenderbufferValidArgs) {
   EXPECT_CALL(*gl_,
               FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
                                          GL_COLOR_ATTACHMENT0,
@@ -757,7 +757,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FramebufferRenderbufferInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, FramebufferRenderbufferInvalidArgs0_0) {
   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::FramebufferRenderbuffer, 0>(false);
   cmds::FramebufferRenderbuffer cmd;
@@ -769,7 +769,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FramebufferRenderbufferInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, FramebufferRenderbufferInvalidArgs0_1) {
   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::FramebufferRenderbuffer, 0>(false);
   cmds::FramebufferRenderbuffer cmd;
@@ -781,7 +781,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FramebufferRenderbufferInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest1, FramebufferRenderbufferInvalidArgs2_0) {
   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::FramebufferRenderbuffer, 0>(false);
   cmds::FramebufferRenderbuffer cmd;
@@ -793,7 +793,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FramebufferTexture2DValidArgs) {
+TEST_P(GLES2DecoderTest1, FramebufferTexture2DValidArgs) {
   EXPECT_CALL(*gl_,
               FramebufferTexture2DEXT(GL_FRAMEBUFFER,
                                       GL_COLOR_ATTACHMENT0,
@@ -811,7 +811,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs0_0) {
   EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
   SpecializedSetup<cmds::FramebufferTexture2D, 0>(false);
   cmds::FramebufferTexture2D cmd;
@@ -824,7 +824,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs0_1) {
   EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
   SpecializedSetup<cmds::FramebufferTexture2D, 0>(false);
   cmds::FramebufferTexture2D cmd;
@@ -837,7 +837,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs2_0) {
   EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
   SpecializedSetup<cmds::FramebufferTexture2D, 0>(false);
   cmds::FramebufferTexture2D cmd;
@@ -850,7 +850,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs4_0) {
+TEST_P(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs4_0) {
   EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
   SpecializedSetup<cmds::FramebufferTexture2D, 0>(false);
   cmds::FramebufferTexture2D cmd;
@@ -863,7 +863,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, FrontFaceValidArgs) {
+TEST_P(GLES2DecoderTest1, FrontFaceValidArgs) {
   EXPECT_CALL(*gl_, FrontFace(GL_CW));
   SpecializedSetup<cmds::FrontFace, 0>(true);
   cmds::FrontFace cmd;
@@ -872,7 +872,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GenBuffersValidArgs) {
+TEST_P(GLES2DecoderTest1, GenBuffersValidArgs) {
   EXPECT_CALL(*gl_, GenBuffersARB(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
   GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
@@ -884,7 +884,7 @@
   EXPECT_TRUE(GetBuffer(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, GenBuffersInvalidArgs) {
+TEST_P(GLES2DecoderTest1, GenBuffersInvalidArgs) {
   EXPECT_CALL(*gl_, GenBuffersARB(_, _)).Times(0);
   GetSharedMemoryAs<GLuint*>()[0] = client_buffer_id_;
   SpecializedSetup<cmds::GenBuffers, 0>(false);
@@ -893,7 +893,7 @@
   EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, GenBuffersImmediateValidArgs) {
+TEST_P(GLES2DecoderTest1, GenBuffersImmediateValidArgs) {
   EXPECT_CALL(*gl_, GenBuffersARB(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
   cmds::GenBuffersImmediate* cmd = GetImmediateAs<cmds::GenBuffersImmediate>();
@@ -905,7 +905,7 @@
   EXPECT_TRUE(GetBuffer(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, GenBuffersImmediateInvalidArgs) {
+TEST_P(GLES2DecoderTest1, GenBuffersImmediateInvalidArgs) {
   EXPECT_CALL(*gl_, GenBuffersARB(_, _)).Times(0);
   cmds::GenBuffersImmediate* cmd = GetImmediateAs<cmds::GenBuffersImmediate>();
   SpecializedSetup<cmds::GenBuffersImmediate, 0>(false);
@@ -914,7 +914,7 @@
             ExecuteImmediateCmd(*cmd, sizeof(&client_buffer_id_)));
 }
 
-TEST_F(GLES2DecoderTest1, GenerateMipmapValidArgs) {
+TEST_P(GLES2DecoderTest1, GenerateMipmapValidArgs) {
   EXPECT_CALL(*gl_, GenerateMipmapEXT(GL_TEXTURE_2D));
   SpecializedSetup<cmds::GenerateMipmap, 0>(true);
   cmds::GenerateMipmap cmd;
@@ -923,7 +923,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GenerateMipmapInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, GenerateMipmapInvalidArgs0_0) {
   EXPECT_CALL(*gl_, GenerateMipmapEXT(_)).Times(0);
   SpecializedSetup<cmds::GenerateMipmap, 0>(false);
   cmds::GenerateMipmap cmd;
@@ -932,7 +932,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GenerateMipmapInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, GenerateMipmapInvalidArgs0_1) {
   EXPECT_CALL(*gl_, GenerateMipmapEXT(_)).Times(0);
   SpecializedSetup<cmds::GenerateMipmap, 0>(false);
   cmds::GenerateMipmap cmd;
@@ -941,7 +941,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GenFramebuffersValidArgs) {
+TEST_P(GLES2DecoderTest1, GenFramebuffersValidArgs) {
   EXPECT_CALL(*gl_, GenFramebuffersEXT(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
   GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
@@ -953,7 +953,7 @@
   EXPECT_TRUE(GetFramebuffer(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, GenFramebuffersInvalidArgs) {
+TEST_P(GLES2DecoderTest1, GenFramebuffersInvalidArgs) {
   EXPECT_CALL(*gl_, GenFramebuffersEXT(_, _)).Times(0);
   GetSharedMemoryAs<GLuint*>()[0] = client_framebuffer_id_;
   SpecializedSetup<cmds::GenFramebuffers, 0>(false);
@@ -962,7 +962,7 @@
   EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, GenFramebuffersImmediateValidArgs) {
+TEST_P(GLES2DecoderTest1, GenFramebuffersImmediateValidArgs) {
   EXPECT_CALL(*gl_, GenFramebuffersEXT(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
   cmds::GenFramebuffersImmediate* cmd =
@@ -975,7 +975,7 @@
   EXPECT_TRUE(GetFramebuffer(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, GenFramebuffersImmediateInvalidArgs) {
+TEST_P(GLES2DecoderTest1, GenFramebuffersImmediateInvalidArgs) {
   EXPECT_CALL(*gl_, GenFramebuffersEXT(_, _)).Times(0);
   cmds::GenFramebuffersImmediate* cmd =
       GetImmediateAs<cmds::GenFramebuffersImmediate>();
@@ -985,7 +985,7 @@
             ExecuteImmediateCmd(*cmd, sizeof(&client_framebuffer_id_)));
 }
 
-TEST_F(GLES2DecoderTest1, GenRenderbuffersValidArgs) {
+TEST_P(GLES2DecoderTest1, GenRenderbuffersValidArgs) {
   EXPECT_CALL(*gl_, GenRenderbuffersEXT(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
   GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
@@ -997,7 +997,7 @@
   EXPECT_TRUE(GetRenderbuffer(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, GenRenderbuffersInvalidArgs) {
+TEST_P(GLES2DecoderTest1, GenRenderbuffersInvalidArgs) {
   EXPECT_CALL(*gl_, GenRenderbuffersEXT(_, _)).Times(0);
   GetSharedMemoryAs<GLuint*>()[0] = client_renderbuffer_id_;
   SpecializedSetup<cmds::GenRenderbuffers, 0>(false);
@@ -1006,7 +1006,7 @@
   EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, GenRenderbuffersImmediateValidArgs) {
+TEST_P(GLES2DecoderTest1, GenRenderbuffersImmediateValidArgs) {
   EXPECT_CALL(*gl_, GenRenderbuffersEXT(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
   cmds::GenRenderbuffersImmediate* cmd =
@@ -1019,7 +1019,7 @@
   EXPECT_TRUE(GetRenderbuffer(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, GenRenderbuffersImmediateInvalidArgs) {
+TEST_P(GLES2DecoderTest1, GenRenderbuffersImmediateInvalidArgs) {
   EXPECT_CALL(*gl_, GenRenderbuffersEXT(_, _)).Times(0);
   cmds::GenRenderbuffersImmediate* cmd =
       GetImmediateAs<cmds::GenRenderbuffersImmediate>();
@@ -1029,7 +1029,7 @@
             ExecuteImmediateCmd(*cmd, sizeof(&client_renderbuffer_id_)));
 }
 
-TEST_F(GLES2DecoderTest1, GenTexturesValidArgs) {
+TEST_P(GLES2DecoderTest1, GenTexturesValidArgs) {
   EXPECT_CALL(*gl_, GenTextures(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
   GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
@@ -1041,7 +1041,7 @@
   EXPECT_TRUE(GetTexture(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, GenTexturesInvalidArgs) {
+TEST_P(GLES2DecoderTest1, GenTexturesInvalidArgs) {
   EXPECT_CALL(*gl_, GenTextures(_, _)).Times(0);
   GetSharedMemoryAs<GLuint*>()[0] = client_texture_id_;
   SpecializedSetup<cmds::GenTextures, 0>(false);
@@ -1050,7 +1050,7 @@
   EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, GenTexturesImmediateValidArgs) {
+TEST_P(GLES2DecoderTest1, GenTexturesImmediateValidArgs) {
   EXPECT_CALL(*gl_, GenTextures(1, _))
       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
   cmds::GenTexturesImmediate* cmd =
@@ -1063,7 +1063,7 @@
   EXPECT_TRUE(GetTexture(kNewClientId) != NULL);
 }
 
-TEST_F(GLES2DecoderTest1, GenTexturesImmediateInvalidArgs) {
+TEST_P(GLES2DecoderTest1, GenTexturesImmediateInvalidArgs) {
   EXPECT_CALL(*gl_, GenTextures(_, _)).Times(0);
   cmds::GenTexturesImmediate* cmd =
       GetImmediateAs<cmds::GenTexturesImmediate>();
@@ -1082,7 +1082,7 @@
 
 // TODO(gman): GetAttribLocationBucket
 
-TEST_F(GLES2DecoderTest1, GetBooleanvValidArgs) {
+TEST_P(GLES2DecoderTest1, GetBooleanvValidArgs) {
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
@@ -1100,7 +1100,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetBooleanvInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, GetBooleanvInvalidArgs0_0) {
   EXPECT_CALL(*gl_, GetBooleanv(_, _)).Times(0);
   SpecializedSetup<cmds::GetBooleanv, 0>(false);
   cmds::GetBooleanv::Result* result =
@@ -1113,7 +1113,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetBooleanvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest1, GetBooleanvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, GetBooleanv(_, _)).Times(0);
   SpecializedSetup<cmds::GetBooleanv, 0>(false);
   cmds::GetBooleanv::Result* result =
@@ -1125,7 +1125,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetBooleanvInvalidArgs1_1) {
+TEST_P(GLES2DecoderTest1, GetBooleanvInvalidArgs1_1) {
   EXPECT_CALL(*gl_, GetBooleanv(_, _)).Times(0);
   SpecializedSetup<cmds::GetBooleanv, 0>(false);
   cmds::GetBooleanv::Result* result =
@@ -1137,7 +1137,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetBufferParameterivValidArgs) {
+TEST_P(GLES2DecoderTest1, GetBufferParameterivValidArgs) {
   SpecializedSetup<cmds::GetBufferParameteriv, 0>(true);
   typedef cmds::GetBufferParameteriv::Result Result;
   Result* result = static_cast<Result*>(shared_memory_address_);
@@ -1153,7 +1153,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetBufferParameterivInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, GetBufferParameterivInvalidArgs0_0) {
   EXPECT_CALL(*gl_, GetBufferParameteriv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetBufferParameteriv, 0>(false);
   cmds::GetBufferParameteriv::Result* result =
@@ -1169,7 +1169,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetBufferParameterivInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest1, GetBufferParameterivInvalidArgs1_0) {
   EXPECT_CALL(*gl_, GetBufferParameteriv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetBufferParameteriv, 0>(false);
   cmds::GetBufferParameteriv::Result* result =
@@ -1185,7 +1185,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetBufferParameterivInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest1, GetBufferParameterivInvalidArgs2_0) {
   EXPECT_CALL(*gl_, GetBufferParameteriv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetBufferParameteriv, 0>(false);
   cmds::GetBufferParameteriv::Result* result =
@@ -1197,7 +1197,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetBufferParameterivInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest1, GetBufferParameterivInvalidArgs2_1) {
   EXPECT_CALL(*gl_, GetBufferParameteriv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetBufferParameteriv, 0>(false);
   cmds::GetBufferParameteriv::Result* result =
@@ -1212,7 +1212,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetErrorValidArgs) {
+TEST_P(GLES2DecoderTest1, GetErrorValidArgs) {
   EXPECT_CALL(*gl_, GetError());
   SpecializedSetup<cmds::GetError, 0>(true);
   cmds::GetError cmd;
@@ -1221,7 +1221,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetErrorInvalidArgsBadSharedMemoryId) {
+TEST_P(GLES2DecoderTest1, GetErrorInvalidArgsBadSharedMemoryId) {
   EXPECT_CALL(*gl_, GetError()).Times(0);
   SpecializedSetup<cmds::GetError, 0>(false);
   cmds::GetError cmd;
@@ -1231,7 +1231,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, GetFloatvValidArgs) {
+TEST_P(GLES2DecoderTest1, GetFloatvValidArgs) {
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
@@ -1249,7 +1249,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetFloatvInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, GetFloatvInvalidArgs0_0) {
   EXPECT_CALL(*gl_, GetFloatv(_, _)).Times(0);
   SpecializedSetup<cmds::GetFloatv, 0>(false);
   cmds::GetFloatv::Result* result =
@@ -1262,7 +1262,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetFloatvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest1, GetFloatvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, GetFloatv(_, _)).Times(0);
   SpecializedSetup<cmds::GetFloatv, 0>(false);
   cmds::GetFloatv::Result* result =
@@ -1274,7 +1274,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetFloatvInvalidArgs1_1) {
+TEST_P(GLES2DecoderTest1, GetFloatvInvalidArgs1_1) {
   EXPECT_CALL(*gl_, GetFloatv(_, _)).Times(0);
   SpecializedSetup<cmds::GetFloatv, 0>(false);
   cmds::GetFloatv::Result* result =
@@ -1286,7 +1286,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetFramebufferAttachmentParameterivValidArgs) {
+TEST_P(GLES2DecoderTest1, GetFramebufferAttachmentParameterivValidArgs) {
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
@@ -1314,7 +1314,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs0_0) {
   EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _))
       .Times(0);
   SpecializedSetup<cmds::GetFramebufferAttachmentParameteriv, 0>(false);
@@ -1333,7 +1333,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs0_1) {
   EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _))
       .Times(0);
   SpecializedSetup<cmds::GetFramebufferAttachmentParameteriv, 0>(false);
@@ -1352,7 +1352,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs3_0) {
+TEST_P(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs3_0) {
   EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _))
       .Times(0);
   SpecializedSetup<cmds::GetFramebufferAttachmentParameteriv, 0>(false);
@@ -1370,7 +1370,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs3_1) {
+TEST_P(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs3_1) {
   EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _))
       .Times(0);
   SpecializedSetup<cmds::GetFramebufferAttachmentParameteriv, 0>(false);
@@ -1388,7 +1388,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetIntegervValidArgs) {
+TEST_P(GLES2DecoderTest1, GetIntegervValidArgs) {
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
@@ -1406,7 +1406,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetIntegervInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, GetIntegervInvalidArgs0_0) {
   EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0);
   SpecializedSetup<cmds::GetIntegerv, 0>(false);
   cmds::GetIntegerv::Result* result =
@@ -1419,7 +1419,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetIntegervInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest1, GetIntegervInvalidArgs1_0) {
   EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0);
   SpecializedSetup<cmds::GetIntegerv, 0>(false);
   cmds::GetIntegerv::Result* result =
@@ -1431,7 +1431,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetIntegervInvalidArgs1_1) {
+TEST_P(GLES2DecoderTest1, GetIntegervInvalidArgs1_1) {
   EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0);
   SpecializedSetup<cmds::GetIntegerv, 0>(false);
   cmds::GetIntegerv::Result* result =
@@ -1443,7 +1443,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetProgramivValidArgs) {
+TEST_P(GLES2DecoderTest1, GetProgramivValidArgs) {
   SpecializedSetup<cmds::GetProgramiv, 0>(true);
   typedef cmds::GetProgramiv::Result Result;
   Result* result = static_cast<Result*>(shared_memory_address_);
@@ -1459,7 +1459,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetProgramivInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest1, GetProgramivInvalidArgs2_0) {
   EXPECT_CALL(*gl_, GetProgramiv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetProgramiv, 0>(false);
   cmds::GetProgramiv::Result* result =
@@ -1471,7 +1471,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetProgramivInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest1, GetProgramivInvalidArgs2_1) {
   EXPECT_CALL(*gl_, GetProgramiv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetProgramiv, 0>(false);
   cmds::GetProgramiv::Result* result =
@@ -1486,9 +1486,9 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetProgramInfoLogValidArgs) {
+TEST_P(GLES2DecoderTest1, GetProgramInfoLogValidArgs) {
   const char* kInfo = "hello";
-  const uint32 kBucketId = 123;
+  const uint32_t kBucketId = 123;
   SpecializedSetup<cmds::GetProgramInfoLog, 0>(true);
 
   cmds::GetProgramInfoLog cmd;
@@ -1502,15 +1502,15 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetProgramInfoLogInvalidArgs) {
-  const uint32 kBucketId = 123;
+TEST_P(GLES2DecoderTest1, GetProgramInfoLogInvalidArgs) {
+  const uint32_t kBucketId = 123;
   cmds::GetProgramInfoLog cmd;
   cmd.Init(kInvalidClientId, kBucketId);
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetRenderbufferParameterivValidArgs) {
+TEST_P(GLES2DecoderTest1, GetRenderbufferParameterivValidArgs) {
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
@@ -1535,7 +1535,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs0_0) {
   EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetRenderbufferParameteriv, 0>(false);
   cmds::GetRenderbufferParameteriv::Result* result =
@@ -1552,7 +1552,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs2_0) {
   EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetRenderbufferParameteriv, 0>(false);
   cmds::GetRenderbufferParameteriv::Result* result =
@@ -1566,7 +1566,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs2_1) {
   EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetRenderbufferParameteriv, 0>(false);
   cmds::GetRenderbufferParameteriv::Result* result =
@@ -1582,7 +1582,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetShaderivValidArgs) {
+TEST_P(GLES2DecoderTest1, GetShaderivValidArgs) {
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
@@ -1604,7 +1604,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetShaderivInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest1, GetShaderivInvalidArgs2_0) {
   EXPECT_CALL(*gl_, GetShaderiv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetShaderiv, 0>(false);
   cmds::GetShaderiv::Result* result =
@@ -1616,7 +1616,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetShaderivInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest1, GetShaderivInvalidArgs2_1) {
   EXPECT_CALL(*gl_, GetShaderiv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetShaderiv, 0>(false);
   cmds::GetShaderiv::Result* result =
@@ -1636,7 +1636,7 @@
 // TODO(gman): GetShaderSource
 // TODO(gman): GetString
 
-TEST_F(GLES2DecoderTest1, GetTexParameterfvValidArgs) {
+TEST_P(GLES2DecoderTest1, GetTexParameterfvValidArgs) {
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
@@ -1660,7 +1660,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetTexParameterfvInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, GetTexParameterfvInvalidArgs0_0) {
   EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetTexParameterfv, 0>(false);
   cmds::GetTexParameterfv::Result* result =
@@ -1676,7 +1676,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetTexParameterfvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest1, GetTexParameterfvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetTexParameterfv, 0>(false);
   cmds::GetTexParameterfv::Result* result =
@@ -1692,7 +1692,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetTexParameterfvInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest1, GetTexParameterfvInvalidArgs2_0) {
   EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetTexParameterfv, 0>(false);
   cmds::GetTexParameterfv::Result* result =
@@ -1704,7 +1704,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetTexParameterfvInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest1, GetTexParameterfvInvalidArgs2_1) {
   EXPECT_CALL(*gl_, GetTexParameterfv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetTexParameterfv, 0>(false);
   cmds::GetTexParameterfv::Result* result =
@@ -1719,7 +1719,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetTexParameterivValidArgs) {
+TEST_P(GLES2DecoderTest1, GetTexParameterivValidArgs) {
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .WillOnce(Return(GL_NO_ERROR))
@@ -1743,7 +1743,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetTexParameterivInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs0_0) {
   EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetTexParameteriv, 0>(false);
   cmds::GetTexParameteriv::Result* result =
@@ -1759,7 +1759,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetTexParameterivInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs1_0) {
   EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetTexParameteriv, 0>(false);
   cmds::GetTexParameteriv::Result* result =
@@ -1775,7 +1775,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_0) {
   EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetTexParameteriv, 0>(false);
   cmds::GetTexParameteriv::Result* result =
@@ -1787,7 +1787,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_1) {
   EXPECT_CALL(*gl_, GetTexParameteriv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetTexParameteriv, 0>(false);
   cmds::GetTexParameteriv::Result* result =
@@ -1809,7 +1809,7 @@
 
 // TODO(gman): GetUniformLocationBucket
 
-TEST_F(GLES2DecoderTest1, GetVertexAttribfvValidArgs) {
+TEST_P(GLES2DecoderTest1, GetVertexAttribfvValidArgs) {
   SpecializedSetup<cmds::GetVertexAttribfv, 0>(true);
   typedef cmds::GetVertexAttribfv::Result Result;
   Result* result = static_cast<Result*>(shared_memory_address_);
@@ -1826,7 +1826,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetVertexAttribfvInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest1, GetVertexAttribfvInvalidArgs2_0) {
   EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetVertexAttribfv, 0>(false);
   cmds::GetVertexAttribfv::Result* result =
@@ -1838,7 +1838,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetVertexAttribfvInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest1, GetVertexAttribfvInvalidArgs2_1) {
   EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetVertexAttribfv, 0>(false);
   cmds::GetVertexAttribfv::Result* result =
@@ -1853,7 +1853,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetVertexAttribivValidArgs) {
+TEST_P(GLES2DecoderTest1, GetVertexAttribivValidArgs) {
   SpecializedSetup<cmds::GetVertexAttribiv, 0>(true);
   typedef cmds::GetVertexAttribiv::Result Result;
   Result* result = static_cast<Result*>(shared_memory_address_);
@@ -1870,7 +1870,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, GetVertexAttribivInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest1, GetVertexAttribivInvalidArgs2_0) {
   EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetVertexAttribiv, 0>(false);
   cmds::GetVertexAttribiv::Result* result =
@@ -1882,7 +1882,7 @@
   EXPECT_EQ(0u, result->size);
 }
 
-TEST_F(GLES2DecoderTest1, GetVertexAttribivInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest1, GetVertexAttribivInvalidArgs2_1) {
   EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0);
   SpecializedSetup<cmds::GetVertexAttribiv, 0>(false);
   cmds::GetVertexAttribiv::Result* result =
@@ -1898,7 +1898,7 @@
 }
 // TODO(gman): GetVertexAttribPointerv
 
-TEST_F(GLES2DecoderTest1, HintValidArgs) {
+TEST_P(GLES2DecoderTest1, HintValidArgs) {
   EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST));
   SpecializedSetup<cmds::Hint, 0>(true);
   cmds::Hint cmd;
@@ -1907,7 +1907,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, HintInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, HintInvalidArgs0_0) {
   EXPECT_CALL(*gl_, Hint(_, _)).Times(0);
   SpecializedSetup<cmds::Hint, 0>(false);
   cmds::Hint cmd;
@@ -1916,7 +1916,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, IsBufferValidArgs) {
+TEST_P(GLES2DecoderTest1, IsBufferValidArgs) {
   SpecializedSetup<cmds::IsBuffer, 0>(true);
   cmds::IsBuffer cmd;
   cmd.Init(client_buffer_id_, shared_memory_id_, shared_memory_offset_);
@@ -1924,7 +1924,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, IsBufferInvalidArgsBadSharedMemoryId) {
+TEST_P(GLES2DecoderTest1, IsBufferInvalidArgsBadSharedMemoryId) {
   SpecializedSetup<cmds::IsBuffer, 0>(false);
   cmds::IsBuffer cmd;
   cmd.Init(client_buffer_id_, kInvalidSharedMemoryId, shared_memory_offset_);
@@ -1933,7 +1933,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, IsEnabledValidArgs) {
+TEST_P(GLES2DecoderTest1, IsEnabledValidArgs) {
   SpecializedSetup<cmds::IsEnabled, 0>(true);
   cmds::IsEnabled cmd;
   cmd.Init(GL_BLEND, shared_memory_id_, shared_memory_offset_);
@@ -1941,7 +1941,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, IsEnabledInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest1, IsEnabledInvalidArgs0_0) {
   EXPECT_CALL(*gl_, IsEnabled(_)).Times(0);
   SpecializedSetup<cmds::IsEnabled, 0>(false);
   cmds::IsEnabled cmd;
@@ -1950,7 +1950,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, IsEnabledInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest1, IsEnabledInvalidArgs0_1) {
   EXPECT_CALL(*gl_, IsEnabled(_)).Times(0);
   SpecializedSetup<cmds::IsEnabled, 0>(false);
   cmds::IsEnabled cmd;
@@ -1959,7 +1959,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, IsEnabledInvalidArgsBadSharedMemoryId) {
+TEST_P(GLES2DecoderTest1, IsEnabledInvalidArgsBadSharedMemoryId) {
   SpecializedSetup<cmds::IsEnabled, 0>(false);
   cmds::IsEnabled cmd;
   cmd.Init(GL_BLEND, kInvalidSharedMemoryId, shared_memory_offset_);
@@ -1968,7 +1968,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, IsFramebufferValidArgs) {
+TEST_P(GLES2DecoderTest1, IsFramebufferValidArgs) {
   SpecializedSetup<cmds::IsFramebuffer, 0>(true);
   cmds::IsFramebuffer cmd;
   cmd.Init(client_framebuffer_id_, shared_memory_id_, shared_memory_offset_);
@@ -1976,7 +1976,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, IsFramebufferInvalidArgsBadSharedMemoryId) {
+TEST_P(GLES2DecoderTest1, IsFramebufferInvalidArgsBadSharedMemoryId) {
   SpecializedSetup<cmds::IsFramebuffer, 0>(false);
   cmds::IsFramebuffer cmd;
   cmd.Init(
@@ -1987,7 +1987,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest1, IsProgramValidArgs) {
+TEST_P(GLES2DecoderTest1, IsProgramValidArgs) {
   SpecializedSetup<cmds::IsProgram, 0>(true);
   cmds::IsProgram cmd;
   cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_);
@@ -1995,7 +1995,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest1, IsProgramInvalidArgsBadSharedMemoryId) {
+TEST_P(GLES2DecoderTest1, IsProgramInvalidArgsBadSharedMemoryId) {
   SpecializedSetup<cmds::IsProgram, 0>(false);
   cmds::IsProgram cmd;
   cmd.Init(client_program_id_, kInvalidSharedMemoryId, shared_memory_offset_);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
index 93f3faf..b162d4d 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
@@ -225,6 +225,8 @@
   }
 };
 
+INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest2, ::testing::Bool());
+
 template <>
 void GLES2DecoderTestBase::SpecializedSetup<cmds::GenQueriesEXT, 0>(
     bool valid) {
@@ -592,63 +594,63 @@
 
 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h"
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_INT) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_INT) {
   TestAcceptedUniform(GL_INT, Program::kUniform1i);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_INT_VEC2) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_INT_VEC2) {
   TestAcceptedUniform(GL_INT_VEC2, Program::kUniform2i);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_INT_VEC3) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_INT_VEC3) {
   TestAcceptedUniform(GL_INT_VEC3, Program::kUniform3i);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_INT_VEC4) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_INT_VEC4) {
   TestAcceptedUniform(GL_INT_VEC4, Program::kUniform4i);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_BOOL) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_BOOL) {
   TestAcceptedUniform(GL_BOOL, Program::kUniform1i | Program::kUniform1f);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_BOOL_VEC2) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_BOOL_VEC2) {
   TestAcceptedUniform(GL_BOOL_VEC2, Program::kUniform2i | Program::kUniform2f);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_BOOL_VEC3) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_BOOL_VEC3) {
   TestAcceptedUniform(GL_BOOL_VEC3, Program::kUniform3i | Program::kUniform3f);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_BOOL_VEC4) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_BOOL_VEC4) {
   TestAcceptedUniform(GL_BOOL_VEC4, Program::kUniform4i | Program::kUniform4f);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniformTypeFLOAT) {
+TEST_P(GLES2DecoderTest2, AcceptsUniformTypeFLOAT) {
   TestAcceptedUniform(GL_FLOAT, Program::kUniform1f);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_VEC2) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_VEC2) {
   TestAcceptedUniform(GL_FLOAT_VEC2, Program::kUniform2f);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_VEC3) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_VEC3) {
   TestAcceptedUniform(GL_FLOAT_VEC3, Program::kUniform3f);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_VEC4) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_VEC4) {
   TestAcceptedUniform(GL_FLOAT_VEC4, Program::kUniform4f);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_MAT2) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_MAT2) {
   TestAcceptedUniform(GL_FLOAT_MAT2, Program::kUniformMatrix2f);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_MAT3) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_MAT3) {
   TestAcceptedUniform(GL_FLOAT_MAT3, Program::kUniformMatrix3f);
 }
 
-TEST_F(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_MAT4) {
+TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_FLOAT_MAT4) {
   TestAcceptedUniform(GL_FLOAT_MAT4, Program::kUniformMatrix4f);
 }
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
index 49d9430..209b1e6 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
@@ -12,7 +12,7 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
 #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
 
-TEST_F(GLES2DecoderTest2, IsRenderbufferValidArgs) {
+TEST_P(GLES2DecoderTest2, IsRenderbufferValidArgs) {
   SpecializedSetup<cmds::IsRenderbuffer, 0>(true);
   cmds::IsRenderbuffer cmd;
   cmd.Init(client_renderbuffer_id_, shared_memory_id_, shared_memory_offset_);
@@ -20,7 +20,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, IsRenderbufferInvalidArgsBadSharedMemoryId) {
+TEST_P(GLES2DecoderTest2, IsRenderbufferInvalidArgsBadSharedMemoryId) {
   SpecializedSetup<cmds::IsRenderbuffer, 0>(false);
   cmds::IsRenderbuffer cmd;
   cmd.Init(
@@ -31,7 +31,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, IsShaderValidArgs) {
+TEST_P(GLES2DecoderTest2, IsShaderValidArgs) {
   SpecializedSetup<cmds::IsShader, 0>(true);
   cmds::IsShader cmd;
   cmd.Init(client_shader_id_, shared_memory_id_, shared_memory_offset_);
@@ -39,7 +39,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, IsShaderInvalidArgsBadSharedMemoryId) {
+TEST_P(GLES2DecoderTest2, IsShaderInvalidArgsBadSharedMemoryId) {
   SpecializedSetup<cmds::IsShader, 0>(false);
   cmds::IsShader cmd;
   cmd.Init(client_shader_id_, kInvalidSharedMemoryId, shared_memory_offset_);
@@ -48,7 +48,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, IsTextureValidArgs) {
+TEST_P(GLES2DecoderTest2, IsTextureValidArgs) {
   SpecializedSetup<cmds::IsTexture, 0>(true);
   cmds::IsTexture cmd;
   cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_);
@@ -56,7 +56,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, IsTextureInvalidArgsBadSharedMemoryId) {
+TEST_P(GLES2DecoderTest2, IsTextureInvalidArgsBadSharedMemoryId) {
   SpecializedSetup<cmds::IsTexture, 0>(false);
   cmds::IsTexture cmd;
   cmd.Init(client_texture_id_, kInvalidSharedMemoryId, shared_memory_offset_);
@@ -65,7 +65,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, LineWidthValidArgs) {
+TEST_P(GLES2DecoderTest2, LineWidthValidArgs) {
   EXPECT_CALL(*gl_, LineWidth(0.5f));
   SpecializedSetup<cmds::LineWidth, 0>(true);
   cmds::LineWidth cmd;
@@ -74,7 +74,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, LineWidthInvalidValue0_0) {
+TEST_P(GLES2DecoderTest2, LineWidthInvalidValue0_0) {
   SpecializedSetup<cmds::LineWidth, 0>(false);
   cmds::LineWidth cmd;
   cmd.Init(0.0f);
@@ -82,7 +82,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, LinkProgramValidArgs) {
+TEST_P(GLES2DecoderTest2, LinkProgramValidArgs) {
   EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId));
   SpecializedSetup<cmds::LinkProgram, 0>(true);
   cmds::LinkProgram cmd;
@@ -92,7 +92,7 @@
 }
 // TODO(gman): PixelStorei
 
-TEST_F(GLES2DecoderTest2, PolygonOffsetValidArgs) {
+TEST_P(GLES2DecoderTest2, PolygonOffsetValidArgs) {
   EXPECT_CALL(*gl_, PolygonOffset(1, 2));
   SpecializedSetup<cmds::PolygonOffset, 0>(true);
   cmds::PolygonOffset cmd;
@@ -104,7 +104,7 @@
 
 // TODO(gman): ReleaseShaderCompiler
 
-TEST_F(GLES2DecoderTest2, RenderbufferStorageValidArgs) {
+TEST_P(GLES2DecoderTest2, RenderbufferStorageValidArgs) {
   SpecializedSetup<cmds::RenderbufferStorage, 0>(true);
   cmds::RenderbufferStorage cmd;
   cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 3, 4);
@@ -112,7 +112,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, RenderbufferStorageInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest2, RenderbufferStorageInvalidArgs0_0) {
   EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::RenderbufferStorage, 0>(false);
   cmds::RenderbufferStorage cmd;
@@ -121,7 +121,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, RenderbufferStorageInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, RenderbufferStorageInvalidArgs2_0) {
   EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::RenderbufferStorage, 0>(false);
   cmds::RenderbufferStorage cmd;
@@ -130,7 +130,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, RenderbufferStorageInvalidArgs3_0) {
+TEST_P(GLES2DecoderTest2, RenderbufferStorageInvalidArgs3_0) {
   EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::RenderbufferStorage, 0>(false);
   cmds::RenderbufferStorage cmd;
@@ -139,7 +139,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, SampleCoverageValidArgs) {
+TEST_P(GLES2DecoderTest2, SampleCoverageValidArgs) {
   EXPECT_CALL(*gl_, SampleCoverage(1, true));
   SpecializedSetup<cmds::SampleCoverage, 0>(true);
   cmds::SampleCoverage cmd;
@@ -148,7 +148,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, ScissorValidArgs) {
+TEST_P(GLES2DecoderTest2, ScissorValidArgs) {
   EXPECT_CALL(*gl_, Scissor(1, 2, 3, 4));
   SpecializedSetup<cmds::Scissor, 0>(true);
   cmds::Scissor cmd;
@@ -157,7 +157,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, ScissorInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, ScissorInvalidArgs2_0) {
   EXPECT_CALL(*gl_, Scissor(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::Scissor, 0>(false);
   cmds::Scissor cmd;
@@ -166,7 +166,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, ScissorInvalidArgs3_0) {
+TEST_P(GLES2DecoderTest2, ScissorInvalidArgs3_0) {
   EXPECT_CALL(*gl_, Scissor(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::Scissor, 0>(false);
   cmds::Scissor cmd;
@@ -180,7 +180,7 @@
 
 // TODO(gman): ShaderSourceBucket
 
-TEST_F(GLES2DecoderTest2, StencilFuncValidArgs) {
+TEST_P(GLES2DecoderTest2, StencilFuncValidArgs) {
   EXPECT_CALL(*gl_, StencilFunc(GL_NEVER, 2, 3));
   SpecializedSetup<cmds::StencilFunc, 0>(true);
   cmds::StencilFunc cmd;
@@ -189,7 +189,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, StencilFuncSeparateValidArgs) {
+TEST_P(GLES2DecoderTest2, StencilFuncSeparateValidArgs) {
   EXPECT_CALL(*gl_, StencilFuncSeparate(GL_FRONT, GL_NEVER, 3, 4));
   SpecializedSetup<cmds::StencilFuncSeparate, 0>(true);
   cmds::StencilFuncSeparate cmd;
@@ -198,7 +198,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, StencilMaskValidArgs) {
+TEST_P(GLES2DecoderTest2, StencilMaskValidArgs) {
   SpecializedSetup<cmds::StencilMask, 0>(true);
   cmds::StencilMask cmd;
   cmd.Init(1);
@@ -206,7 +206,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, StencilMaskSeparateValidArgs) {
+TEST_P(GLES2DecoderTest2, StencilMaskSeparateValidArgs) {
   SpecializedSetup<cmds::StencilMaskSeparate, 0>(true);
   cmds::StencilMaskSeparate cmd;
   cmd.Init(GL_FRONT, 2);
@@ -214,7 +214,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, StencilOpValidArgs) {
+TEST_P(GLES2DecoderTest2, StencilOpValidArgs) {
   EXPECT_CALL(*gl_, StencilOp(GL_KEEP, GL_INCR, GL_KEEP));
   SpecializedSetup<cmds::StencilOp, 0>(true);
   cmds::StencilOp cmd;
@@ -223,7 +223,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, StencilOpSeparateValidArgs) {
+TEST_P(GLES2DecoderTest2, StencilOpSeparateValidArgs) {
   EXPECT_CALL(*gl_, StencilOpSeparate(GL_FRONT, GL_INCR, GL_KEEP, GL_KEEP));
   SpecializedSetup<cmds::StencilOpSeparate, 0>(true);
   cmds::StencilOpSeparate cmd;
@@ -233,7 +233,7 @@
 }
 // TODO(gman): TexImage2D
 
-TEST_F(GLES2DecoderTest2, TexParameterfValidArgs) {
+TEST_P(GLES2DecoderTest2, TexParameterfValidArgs) {
   EXPECT_CALL(*gl_,
               TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
   SpecializedSetup<cmds::TexParameterf, 0>(true);
@@ -243,7 +243,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest2, TexParameterfInvalidArgs0_0) {
   EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameterf, 0>(false);
   cmds::TexParameterf cmd;
@@ -252,7 +252,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest2, TexParameterfInvalidArgs0_1) {
   EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameterf, 0>(false);
   cmds::TexParameterf cmd;
@@ -261,7 +261,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, TexParameterfInvalidArgs1_0) {
   EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameterf, 0>(false);
   cmds::TexParameterf cmd;
@@ -270,7 +270,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfvValidArgs) {
+TEST_P(GLES2DecoderTest2, TexParameterfvValidArgs) {
   SpecializedSetup<cmds::TexParameterfv, 0>(true);
   cmds::TexParameterfv cmd;
   cmd.Init(GL_TEXTURE_2D,
@@ -287,7 +287,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest2, TexParameterfvInvalidArgs0_0) {
   EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameterfv, 0>(false);
   cmds::TexParameterfv cmd;
@@ -300,7 +300,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest2, TexParameterfvInvalidArgs0_1) {
   EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameterfv, 0>(false);
   cmds::TexParameterfv cmd;
@@ -313,7 +313,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, TexParameterfvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameterfv, 0>(false);
   cmds::TexParameterfv cmd;
@@ -326,7 +326,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, TexParameterfvInvalidArgs2_0) {
   EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameterfv, 0>(false);
   cmds::TexParameterfv cmd;
@@ -335,7 +335,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfvInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest2, TexParameterfvInvalidArgs2_1) {
   EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameterfv, 0>(false);
   cmds::TexParameterfv cmd;
@@ -347,7 +347,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, TexParameterfvImmediateValidArgs) {
   cmds::TexParameterfvImmediate& cmd =
       *GetImmediateAs<cmds::TexParameterfvImmediate>();
   SpecializedSetup<cmds::TexParameterfvImmediate, 0>(true);
@@ -364,7 +364,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs0_0) {
   cmds::TexParameterfvImmediate& cmd =
       *GetImmediateAs<cmds::TexParameterfvImmediate>();
   EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
@@ -377,7 +377,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs0_1) {
   cmds::TexParameterfvImmediate& cmd =
       *GetImmediateAs<cmds::TexParameterfvImmediate>();
   EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
@@ -390,7 +390,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, TexParameterfvImmediateInvalidArgs1_0) {
   cmds::TexParameterfvImmediate& cmd =
       *GetImmediateAs<cmds::TexParameterfvImmediate>();
   EXPECT_CALL(*gl_, TexParameterf(_, _, _)).Times(0);
@@ -403,7 +403,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameteriValidArgs) {
+TEST_P(GLES2DecoderTest2, TexParameteriValidArgs) {
   EXPECT_CALL(*gl_,
               TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
   SpecializedSetup<cmds::TexParameteri, 0>(true);
@@ -413,7 +413,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameteriInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest2, TexParameteriInvalidArgs0_0) {
   EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameteri, 0>(false);
   cmds::TexParameteri cmd;
@@ -422,7 +422,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameteriInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest2, TexParameteriInvalidArgs0_1) {
   EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameteri, 0>(false);
   cmds::TexParameteri cmd;
@@ -431,7 +431,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameteriInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, TexParameteriInvalidArgs1_0) {
   EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameteri, 0>(false);
   cmds::TexParameteri cmd;
@@ -440,7 +440,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterivValidArgs) {
+TEST_P(GLES2DecoderTest2, TexParameterivValidArgs) {
   SpecializedSetup<cmds::TexParameteriv, 0>(true);
   cmds::TexParameteriv cmd;
   cmd.Init(GL_TEXTURE_2D,
@@ -457,7 +457,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterivInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest2, TexParameterivInvalidArgs0_0) {
   EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameteriv, 0>(false);
   cmds::TexParameteriv cmd;
@@ -470,7 +470,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterivInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest2, TexParameterivInvalidArgs0_1) {
   EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameteriv, 0>(false);
   cmds::TexParameteriv cmd;
@@ -483,7 +483,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterivInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, TexParameterivInvalidArgs1_0) {
   EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameteriv, 0>(false);
   cmds::TexParameteriv cmd;
@@ -496,7 +496,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterivInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, TexParameterivInvalidArgs2_0) {
   EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameteriv, 0>(false);
   cmds::TexParameteriv cmd;
@@ -505,7 +505,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterivInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest2, TexParameterivInvalidArgs2_1) {
   EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
   SpecializedSetup<cmds::TexParameteriv, 0>(false);
   cmds::TexParameteriv cmd;
@@ -517,7 +517,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterivImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, TexParameterivImmediateValidArgs) {
   cmds::TexParameterivImmediate& cmd =
       *GetImmediateAs<cmds::TexParameterivImmediate>();
   SpecializedSetup<cmds::TexParameterivImmediate, 0>(true);
@@ -534,7 +534,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterivImmediateInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest2, TexParameterivImmediateInvalidArgs0_0) {
   cmds::TexParameterivImmediate& cmd =
       *GetImmediateAs<cmds::TexParameterivImmediate>();
   EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
@@ -547,7 +547,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterivImmediateInvalidArgs0_1) {
+TEST_P(GLES2DecoderTest2, TexParameterivImmediateInvalidArgs0_1) {
   cmds::TexParameterivImmediate& cmd =
       *GetImmediateAs<cmds::TexParameterivImmediate>();
   EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
@@ -560,7 +560,7 @@
   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, TexParameterivImmediateInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, TexParameterivImmediateInvalidArgs1_0) {
   cmds::TexParameterivImmediate& cmd =
       *GetImmediateAs<cmds::TexParameterivImmediate>();
   EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
@@ -574,7 +574,7 @@
 }
 // TODO(gman): TexSubImage2D
 
-TEST_F(GLES2DecoderTest2, Uniform1fValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform1fValidArgs) {
   EXPECT_CALL(*gl_, Uniform1fv(1, 1, _));
   SpecializedSetup<cmds::Uniform1f, 0>(true);
   cmds::Uniform1f cmd;
@@ -583,7 +583,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform1fvValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform1fvValidArgs) {
   EXPECT_CALL(
       *gl_,
       Uniform1fv(
@@ -595,7 +595,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform1fvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, Uniform1fvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, Uniform1fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform1fv, 0>(false);
   cmds::Uniform1fv cmd;
@@ -604,7 +604,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform1fvInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, Uniform1fvInvalidArgs2_0) {
   EXPECT_CALL(*gl_, Uniform1fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform1fv, 0>(false);
   cmds::Uniform1fv cmd;
@@ -612,7 +612,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform1fvInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest2, Uniform1fvInvalidArgs2_1) {
   EXPECT_CALL(*gl_, Uniform1fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform1fv, 0>(false);
   cmds::Uniform1fv cmd;
@@ -620,7 +620,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform1fvValidArgsCountTooLarge) {
+TEST_P(GLES2DecoderTest2, Uniform1fvValidArgsCountTooLarge) {
   EXPECT_CALL(
       *gl_,
       Uniform1fv(
@@ -635,7 +635,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform1fvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform1fvImmediateValidArgs) {
   cmds::Uniform1fvImmediate& cmd = *GetImmediateAs<cmds::Uniform1fvImmediate>();
   EXPECT_CALL(
       *gl_,
@@ -652,7 +652,7 @@
 // TODO(gman): Uniform1iv
 // TODO(gman): Uniform1ivImmediate
 
-TEST_F(GLES2DecoderTest2, Uniform2fValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform2fValidArgs) {
   EXPECT_CALL(*gl_, Uniform2fv(1, 1, _));
   SpecializedSetup<cmds::Uniform2f, 0>(true);
   cmds::Uniform2f cmd;
@@ -661,7 +661,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2fvValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform2fvValidArgs) {
   EXPECT_CALL(
       *gl_,
       Uniform2fv(
@@ -673,7 +673,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2fvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, Uniform2fvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, Uniform2fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform2fv, 0>(false);
   cmds::Uniform2fv cmd;
@@ -682,7 +682,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2fvInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, Uniform2fvInvalidArgs2_0) {
   EXPECT_CALL(*gl_, Uniform2fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform2fv, 0>(false);
   cmds::Uniform2fv cmd;
@@ -690,7 +690,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2fvInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest2, Uniform2fvInvalidArgs2_1) {
   EXPECT_CALL(*gl_, Uniform2fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform2fv, 0>(false);
   cmds::Uniform2fv cmd;
@@ -698,7 +698,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2fvValidArgsCountTooLarge) {
+TEST_P(GLES2DecoderTest2, Uniform2fvValidArgsCountTooLarge) {
   EXPECT_CALL(
       *gl_,
       Uniform2fv(
@@ -713,7 +713,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2fvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform2fvImmediateValidArgs) {
   cmds::Uniform2fvImmediate& cmd = *GetImmediateAs<cmds::Uniform2fvImmediate>();
   EXPECT_CALL(
       *gl_,
@@ -727,7 +727,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2iValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform2iValidArgs) {
   EXPECT_CALL(*gl_, Uniform2iv(1, 1, _));
   SpecializedSetup<cmds::Uniform2i, 0>(true);
   cmds::Uniform2i cmd;
@@ -736,7 +736,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2ivValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform2ivValidArgs) {
   EXPECT_CALL(
       *gl_,
       Uniform2iv(1, 2, reinterpret_cast<const GLint*>(shared_memory_address_)));
@@ -747,7 +747,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2ivInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, Uniform2ivInvalidArgs1_0) {
   EXPECT_CALL(*gl_, Uniform2iv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform2iv, 0>(false);
   cmds::Uniform2iv cmd;
@@ -756,7 +756,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2ivInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, Uniform2ivInvalidArgs2_0) {
   EXPECT_CALL(*gl_, Uniform2iv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform2iv, 0>(false);
   cmds::Uniform2iv cmd;
@@ -764,7 +764,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2ivInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest2, Uniform2ivInvalidArgs2_1) {
   EXPECT_CALL(*gl_, Uniform2iv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform2iv, 0>(false);
   cmds::Uniform2iv cmd;
@@ -772,7 +772,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2ivValidArgsCountTooLarge) {
+TEST_P(GLES2DecoderTest2, Uniform2ivValidArgsCountTooLarge) {
   EXPECT_CALL(
       *gl_,
       Uniform2iv(3, 3, reinterpret_cast<const GLint*>(shared_memory_address_)));
@@ -786,7 +786,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform2ivImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform2ivImmediateValidArgs) {
   cmds::Uniform2ivImmediate& cmd = *GetImmediateAs<cmds::Uniform2ivImmediate>();
   EXPECT_CALL(
       *gl_,
@@ -800,7 +800,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3fValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform3fValidArgs) {
   EXPECT_CALL(*gl_, Uniform3fv(1, 1, _));
   SpecializedSetup<cmds::Uniform3f, 0>(true);
   cmds::Uniform3f cmd;
@@ -809,7 +809,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3fvValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform3fvValidArgs) {
   EXPECT_CALL(
       *gl_,
       Uniform3fv(
@@ -821,7 +821,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3fvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, Uniform3fvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, Uniform3fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform3fv, 0>(false);
   cmds::Uniform3fv cmd;
@@ -830,7 +830,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3fvInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, Uniform3fvInvalidArgs2_0) {
   EXPECT_CALL(*gl_, Uniform3fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform3fv, 0>(false);
   cmds::Uniform3fv cmd;
@@ -838,7 +838,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3fvInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest2, Uniform3fvInvalidArgs2_1) {
   EXPECT_CALL(*gl_, Uniform3fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform3fv, 0>(false);
   cmds::Uniform3fv cmd;
@@ -846,7 +846,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3fvValidArgsCountTooLarge) {
+TEST_P(GLES2DecoderTest2, Uniform3fvValidArgsCountTooLarge) {
   EXPECT_CALL(
       *gl_,
       Uniform3fv(
@@ -861,7 +861,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3fvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform3fvImmediateValidArgs) {
   cmds::Uniform3fvImmediate& cmd = *GetImmediateAs<cmds::Uniform3fvImmediate>();
   EXPECT_CALL(
       *gl_,
@@ -875,7 +875,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3iValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform3iValidArgs) {
   EXPECT_CALL(*gl_, Uniform3iv(1, 1, _));
   SpecializedSetup<cmds::Uniform3i, 0>(true);
   cmds::Uniform3i cmd;
@@ -884,7 +884,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3ivValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform3ivValidArgs) {
   EXPECT_CALL(
       *gl_,
       Uniform3iv(1, 2, reinterpret_cast<const GLint*>(shared_memory_address_)));
@@ -895,7 +895,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3ivInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, Uniform3ivInvalidArgs1_0) {
   EXPECT_CALL(*gl_, Uniform3iv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform3iv, 0>(false);
   cmds::Uniform3iv cmd;
@@ -904,7 +904,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3ivInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, Uniform3ivInvalidArgs2_0) {
   EXPECT_CALL(*gl_, Uniform3iv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform3iv, 0>(false);
   cmds::Uniform3iv cmd;
@@ -912,7 +912,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3ivInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest2, Uniform3ivInvalidArgs2_1) {
   EXPECT_CALL(*gl_, Uniform3iv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform3iv, 0>(false);
   cmds::Uniform3iv cmd;
@@ -920,7 +920,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3ivValidArgsCountTooLarge) {
+TEST_P(GLES2DecoderTest2, Uniform3ivValidArgsCountTooLarge) {
   EXPECT_CALL(
       *gl_,
       Uniform3iv(3, 3, reinterpret_cast<const GLint*>(shared_memory_address_)));
@@ -934,7 +934,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform3ivImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform3ivImmediateValidArgs) {
   cmds::Uniform3ivImmediate& cmd = *GetImmediateAs<cmds::Uniform3ivImmediate>();
   EXPECT_CALL(
       *gl_,
@@ -948,7 +948,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4fValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform4fValidArgs) {
   EXPECT_CALL(*gl_, Uniform4fv(1, 1, _));
   SpecializedSetup<cmds::Uniform4f, 0>(true);
   cmds::Uniform4f cmd;
@@ -957,7 +957,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4fvValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform4fvValidArgs) {
   EXPECT_CALL(
       *gl_,
       Uniform4fv(
@@ -969,7 +969,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4fvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, Uniform4fvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, Uniform4fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform4fv, 0>(false);
   cmds::Uniform4fv cmd;
@@ -978,7 +978,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4fvInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, Uniform4fvInvalidArgs2_0) {
   EXPECT_CALL(*gl_, Uniform4fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform4fv, 0>(false);
   cmds::Uniform4fv cmd;
@@ -986,7 +986,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4fvInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest2, Uniform4fvInvalidArgs2_1) {
   EXPECT_CALL(*gl_, Uniform4fv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform4fv, 0>(false);
   cmds::Uniform4fv cmd;
@@ -994,7 +994,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4fvValidArgsCountTooLarge) {
+TEST_P(GLES2DecoderTest2, Uniform4fvValidArgsCountTooLarge) {
   EXPECT_CALL(
       *gl_,
       Uniform4fv(
@@ -1009,7 +1009,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4fvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform4fvImmediateValidArgs) {
   cmds::Uniform4fvImmediate& cmd = *GetImmediateAs<cmds::Uniform4fvImmediate>();
   EXPECT_CALL(
       *gl_,
@@ -1023,7 +1023,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4iValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform4iValidArgs) {
   EXPECT_CALL(*gl_, Uniform4iv(1, 1, _));
   SpecializedSetup<cmds::Uniform4i, 0>(true);
   cmds::Uniform4i cmd;
@@ -1032,7 +1032,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4ivValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform4ivValidArgs) {
   EXPECT_CALL(
       *gl_,
       Uniform4iv(1, 2, reinterpret_cast<const GLint*>(shared_memory_address_)));
@@ -1043,7 +1043,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4ivInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, Uniform4ivInvalidArgs1_0) {
   EXPECT_CALL(*gl_, Uniform4iv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform4iv, 0>(false);
   cmds::Uniform4iv cmd;
@@ -1052,7 +1052,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4ivInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, Uniform4ivInvalidArgs2_0) {
   EXPECT_CALL(*gl_, Uniform4iv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform4iv, 0>(false);
   cmds::Uniform4iv cmd;
@@ -1060,7 +1060,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4ivInvalidArgs2_1) {
+TEST_P(GLES2DecoderTest2, Uniform4ivInvalidArgs2_1) {
   EXPECT_CALL(*gl_, Uniform4iv(_, _, _)).Times(0);
   SpecializedSetup<cmds::Uniform4iv, 0>(false);
   cmds::Uniform4iv cmd;
@@ -1068,7 +1068,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4ivValidArgsCountTooLarge) {
+TEST_P(GLES2DecoderTest2, Uniform4ivValidArgsCountTooLarge) {
   EXPECT_CALL(
       *gl_,
       Uniform4iv(3, 3, reinterpret_cast<const GLint*>(shared_memory_address_)));
@@ -1082,7 +1082,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, Uniform4ivImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, Uniform4ivImmediateValidArgs) {
   cmds::Uniform4ivImmediate& cmd = *GetImmediateAs<cmds::Uniform4ivImmediate>();
   EXPECT_CALL(
       *gl_,
@@ -1096,7 +1096,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix2fvValidArgs) {
+TEST_P(GLES2DecoderTest2, UniformMatrix2fvValidArgs) {
   EXPECT_CALL(*gl_,
               UniformMatrix2fv(
                   1,
@@ -1110,7 +1110,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix2fvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix2fvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, UniformMatrix2fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix2fv, 0>(false);
   cmds::UniformMatrix2fv cmd;
@@ -1119,7 +1119,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix2fvInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix2fvInvalidArgs2_0) {
   EXPECT_CALL(*gl_, UniformMatrix2fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix2fv, 0>(false);
   cmds::UniformMatrix2fv cmd;
@@ -1128,7 +1128,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix2fvInvalidArgs3_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix2fvInvalidArgs3_0) {
   EXPECT_CALL(*gl_, UniformMatrix2fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix2fv, 0>(false);
   cmds::UniformMatrix2fv cmd;
@@ -1136,7 +1136,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix2fvInvalidArgs3_1) {
+TEST_P(GLES2DecoderTest2, UniformMatrix2fvInvalidArgs3_1) {
   EXPECT_CALL(*gl_, UniformMatrix2fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix2fv, 0>(false);
   cmds::UniformMatrix2fv cmd;
@@ -1144,7 +1144,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix2fvValidArgsCountTooLarge) {
+TEST_P(GLES2DecoderTest2, UniformMatrix2fvValidArgsCountTooLarge) {
   EXPECT_CALL(*gl_,
               UniformMatrix2fv(
                   3,
@@ -1162,7 +1162,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix2fvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, UniformMatrix2fvImmediateValidArgs) {
   cmds::UniformMatrix2fvImmediate& cmd =
       *GetImmediateAs<cmds::UniformMatrix2fvImmediate>();
   EXPECT_CALL(
@@ -1178,7 +1178,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix2fvImmediateInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix2fvImmediateInvalidArgs2_0) {
   cmds::UniformMatrix2fvImmediate& cmd =
       *GetImmediateAs<cmds::UniformMatrix2fvImmediate>();
   EXPECT_CALL(*gl_, UniformMatrix2fv(_, _, _, _)).Times(0);
@@ -1191,7 +1191,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix3fvValidArgs) {
+TEST_P(GLES2DecoderTest2, UniformMatrix3fvValidArgs) {
   EXPECT_CALL(*gl_,
               UniformMatrix3fv(
                   1,
@@ -1205,7 +1205,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix3fvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix3fvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, UniformMatrix3fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix3fv, 0>(false);
   cmds::UniformMatrix3fv cmd;
@@ -1214,7 +1214,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix3fvInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix3fvInvalidArgs2_0) {
   EXPECT_CALL(*gl_, UniformMatrix3fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix3fv, 0>(false);
   cmds::UniformMatrix3fv cmd;
@@ -1223,7 +1223,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix3fvInvalidArgs3_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix3fvInvalidArgs3_0) {
   EXPECT_CALL(*gl_, UniformMatrix3fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix3fv, 0>(false);
   cmds::UniformMatrix3fv cmd;
@@ -1231,7 +1231,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix3fvInvalidArgs3_1) {
+TEST_P(GLES2DecoderTest2, UniformMatrix3fvInvalidArgs3_1) {
   EXPECT_CALL(*gl_, UniformMatrix3fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix3fv, 0>(false);
   cmds::UniformMatrix3fv cmd;
@@ -1239,7 +1239,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix3fvValidArgsCountTooLarge) {
+TEST_P(GLES2DecoderTest2, UniformMatrix3fvValidArgsCountTooLarge) {
   EXPECT_CALL(*gl_,
               UniformMatrix3fv(
                   3,
@@ -1257,7 +1257,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix3fvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, UniformMatrix3fvImmediateValidArgs) {
   cmds::UniformMatrix3fvImmediate& cmd =
       *GetImmediateAs<cmds::UniformMatrix3fvImmediate>();
   EXPECT_CALL(
@@ -1273,7 +1273,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix3fvImmediateInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix3fvImmediateInvalidArgs2_0) {
   cmds::UniformMatrix3fvImmediate& cmd =
       *GetImmediateAs<cmds::UniformMatrix3fvImmediate>();
   EXPECT_CALL(*gl_, UniformMatrix3fv(_, _, _, _)).Times(0);
@@ -1286,7 +1286,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix4fvValidArgs) {
+TEST_P(GLES2DecoderTest2, UniformMatrix4fvValidArgs) {
   EXPECT_CALL(*gl_,
               UniformMatrix4fv(
                   1,
@@ -1300,7 +1300,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix4fvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix4fvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, UniformMatrix4fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix4fv, 0>(false);
   cmds::UniformMatrix4fv cmd;
@@ -1309,7 +1309,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix4fvInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix4fvInvalidArgs2_0) {
   EXPECT_CALL(*gl_, UniformMatrix4fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix4fv, 0>(false);
   cmds::UniformMatrix4fv cmd;
@@ -1318,7 +1318,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix4fvInvalidArgs3_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix4fvInvalidArgs3_0) {
   EXPECT_CALL(*gl_, UniformMatrix4fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix4fv, 0>(false);
   cmds::UniformMatrix4fv cmd;
@@ -1326,7 +1326,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix4fvInvalidArgs3_1) {
+TEST_P(GLES2DecoderTest2, UniformMatrix4fvInvalidArgs3_1) {
   EXPECT_CALL(*gl_, UniformMatrix4fv(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::UniformMatrix4fv, 0>(false);
   cmds::UniformMatrix4fv cmd;
@@ -1334,7 +1334,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix4fvValidArgsCountTooLarge) {
+TEST_P(GLES2DecoderTest2, UniformMatrix4fvValidArgsCountTooLarge) {
   EXPECT_CALL(*gl_,
               UniformMatrix4fv(
                   3,
@@ -1352,7 +1352,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix4fvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, UniformMatrix4fvImmediateValidArgs) {
   cmds::UniformMatrix4fvImmediate& cmd =
       *GetImmediateAs<cmds::UniformMatrix4fvImmediate>();
   EXPECT_CALL(
@@ -1368,7 +1368,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UniformMatrix4fvImmediateInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, UniformMatrix4fvImmediateInvalidArgs2_0) {
   cmds::UniformMatrix4fvImmediate& cmd =
       *GetImmediateAs<cmds::UniformMatrix4fvImmediate>();
   EXPECT_CALL(*gl_, UniformMatrix4fv(_, _, _, _)).Times(0);
@@ -1381,7 +1381,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UseProgramValidArgs) {
+TEST_P(GLES2DecoderTest2, UseProgramValidArgs) {
   EXPECT_CALL(*gl_, UseProgram(kServiceProgramId));
   SpecializedSetup<cmds::UseProgram, 0>(true);
   cmds::UseProgram cmd;
@@ -1390,7 +1390,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, UseProgramInvalidArgs0_0) {
+TEST_P(GLES2DecoderTest2, UseProgramInvalidArgs0_0) {
   EXPECT_CALL(*gl_, UseProgram(_)).Times(0);
   SpecializedSetup<cmds::UseProgram, 0>(false);
   cmds::UseProgram cmd;
@@ -1399,7 +1399,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, ValidateProgramValidArgs) {
+TEST_P(GLES2DecoderTest2, ValidateProgramValidArgs) {
   EXPECT_CALL(*gl_, ValidateProgram(kServiceProgramId));
   SpecializedSetup<cmds::ValidateProgram, 0>(true);
   cmds::ValidateProgram cmd;
@@ -1408,7 +1408,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib1fValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib1fValidArgs) {
   EXPECT_CALL(*gl_, VertexAttrib1f(1, 2));
   SpecializedSetup<cmds::VertexAttrib1f, 0>(true);
   cmds::VertexAttrib1f cmd;
@@ -1417,7 +1417,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib1fvValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib1fvValidArgs) {
   SpecializedSetup<cmds::VertexAttrib1fv, 0>(true);
   cmds::VertexAttrib1fv cmd;
   cmd.Init(1, shared_memory_id_, shared_memory_offset_);
@@ -1429,7 +1429,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib1fvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, VertexAttrib1fvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, VertexAttrib1fv(_, _)).Times(0);
   SpecializedSetup<cmds::VertexAttrib1fv, 0>(false);
   cmds::VertexAttrib1fv cmd;
@@ -1438,7 +1438,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib1fvInvalidArgs1_1) {
+TEST_P(GLES2DecoderTest2, VertexAttrib1fvInvalidArgs1_1) {
   EXPECT_CALL(*gl_, VertexAttrib1fv(_, _)).Times(0);
   SpecializedSetup<cmds::VertexAttrib1fv, 0>(false);
   cmds::VertexAttrib1fv cmd;
@@ -1447,7 +1447,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib1fvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib1fvImmediateValidArgs) {
   cmds::VertexAttrib1fvImmediate& cmd =
       *GetImmediateAs<cmds::VertexAttrib1fvImmediate>();
   SpecializedSetup<cmds::VertexAttrib1fvImmediate, 0>(true);
@@ -1462,7 +1462,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib2fValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib2fValidArgs) {
   EXPECT_CALL(*gl_, VertexAttrib2f(1, 2, 3));
   SpecializedSetup<cmds::VertexAttrib2f, 0>(true);
   cmds::VertexAttrib2f cmd;
@@ -1471,7 +1471,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib2fvValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib2fvValidArgs) {
   SpecializedSetup<cmds::VertexAttrib2fv, 0>(true);
   cmds::VertexAttrib2fv cmd;
   cmd.Init(1, shared_memory_id_, shared_memory_offset_);
@@ -1483,7 +1483,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib2fvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, VertexAttrib2fvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, VertexAttrib2fv(_, _)).Times(0);
   SpecializedSetup<cmds::VertexAttrib2fv, 0>(false);
   cmds::VertexAttrib2fv cmd;
@@ -1492,7 +1492,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib2fvInvalidArgs1_1) {
+TEST_P(GLES2DecoderTest2, VertexAttrib2fvInvalidArgs1_1) {
   EXPECT_CALL(*gl_, VertexAttrib2fv(_, _)).Times(0);
   SpecializedSetup<cmds::VertexAttrib2fv, 0>(false);
   cmds::VertexAttrib2fv cmd;
@@ -1501,7 +1501,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib2fvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib2fvImmediateValidArgs) {
   cmds::VertexAttrib2fvImmediate& cmd =
       *GetImmediateAs<cmds::VertexAttrib2fvImmediate>();
   SpecializedSetup<cmds::VertexAttrib2fvImmediate, 0>(true);
@@ -1516,7 +1516,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib3fValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib3fValidArgs) {
   EXPECT_CALL(*gl_, VertexAttrib3f(1, 2, 3, 4));
   SpecializedSetup<cmds::VertexAttrib3f, 0>(true);
   cmds::VertexAttrib3f cmd;
@@ -1525,7 +1525,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib3fvValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib3fvValidArgs) {
   SpecializedSetup<cmds::VertexAttrib3fv, 0>(true);
   cmds::VertexAttrib3fv cmd;
   cmd.Init(1, shared_memory_id_, shared_memory_offset_);
@@ -1537,7 +1537,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib3fvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, VertexAttrib3fvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, VertexAttrib3fv(_, _)).Times(0);
   SpecializedSetup<cmds::VertexAttrib3fv, 0>(false);
   cmds::VertexAttrib3fv cmd;
@@ -1546,7 +1546,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib3fvInvalidArgs1_1) {
+TEST_P(GLES2DecoderTest2, VertexAttrib3fvInvalidArgs1_1) {
   EXPECT_CALL(*gl_, VertexAttrib3fv(_, _)).Times(0);
   SpecializedSetup<cmds::VertexAttrib3fv, 0>(false);
   cmds::VertexAttrib3fv cmd;
@@ -1555,7 +1555,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib3fvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib3fvImmediateValidArgs) {
   cmds::VertexAttrib3fvImmediate& cmd =
       *GetImmediateAs<cmds::VertexAttrib3fvImmediate>();
   SpecializedSetup<cmds::VertexAttrib3fvImmediate, 0>(true);
@@ -1570,7 +1570,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib4fValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib4fValidArgs) {
   EXPECT_CALL(*gl_, VertexAttrib4f(1, 2, 3, 4, 5));
   SpecializedSetup<cmds::VertexAttrib4f, 0>(true);
   cmds::VertexAttrib4f cmd;
@@ -1579,7 +1579,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib4fvValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib4fvValidArgs) {
   SpecializedSetup<cmds::VertexAttrib4fv, 0>(true);
   cmds::VertexAttrib4fv cmd;
   cmd.Init(1, shared_memory_id_, shared_memory_offset_);
@@ -1591,7 +1591,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib4fvInvalidArgs1_0) {
+TEST_P(GLES2DecoderTest2, VertexAttrib4fvInvalidArgs1_0) {
   EXPECT_CALL(*gl_, VertexAttrib4fv(_, _)).Times(0);
   SpecializedSetup<cmds::VertexAttrib4fv, 0>(false);
   cmds::VertexAttrib4fv cmd;
@@ -1600,7 +1600,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib4fvInvalidArgs1_1) {
+TEST_P(GLES2DecoderTest2, VertexAttrib4fvInvalidArgs1_1) {
   EXPECT_CALL(*gl_, VertexAttrib4fv(_, _)).Times(0);
   SpecializedSetup<cmds::VertexAttrib4fv, 0>(false);
   cmds::VertexAttrib4fv cmd;
@@ -1609,7 +1609,7 @@
   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
 }
 
-TEST_F(GLES2DecoderTest2, VertexAttrib4fvImmediateValidArgs) {
+TEST_P(GLES2DecoderTest2, VertexAttrib4fvImmediateValidArgs) {
   cmds::VertexAttrib4fvImmediate& cmd =
       *GetImmediateAs<cmds::VertexAttrib4fvImmediate>();
   SpecializedSetup<cmds::VertexAttrib4fvImmediate, 0>(true);
@@ -1625,7 +1625,7 @@
 }
 // TODO(gman): VertexAttribPointer
 
-TEST_F(GLES2DecoderTest2, ViewportValidArgs) {
+TEST_P(GLES2DecoderTest2, ViewportValidArgs) {
   EXPECT_CALL(*gl_, Viewport(1, 2, 3, 4));
   SpecializedSetup<cmds::Viewport, 0>(true);
   cmds::Viewport cmd;
@@ -1634,7 +1634,7 @@
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, ViewportInvalidArgs2_0) {
+TEST_P(GLES2DecoderTest2, ViewportInvalidArgs2_0) {
   EXPECT_CALL(*gl_, Viewport(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::Viewport, 0>(false);
   cmds::Viewport cmd;
@@ -1643,7 +1643,7 @@
   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
 }
 
-TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) {
+TEST_P(GLES2DecoderTest2, ViewportInvalidArgs3_0) {
   EXPECT_CALL(*gl_, Viewport(_, _, _, _)).Times(0);
   SpecializedSetup<cmds::Viewport, 0>(false);
   cmds::Viewport cmd;
@@ -1668,7 +1668,7 @@
 
 // TODO(gman): PushGroupMarkerEXT
 
-TEST_F(GLES2DecoderTest2, PopGroupMarkerEXTValidArgs) {
+TEST_P(GLES2DecoderTest2, PopGroupMarkerEXTValidArgs) {
   SpecializedSetup<cmds::PopGroupMarkerEXT, 0>(true);
   cmds::PopGroupMarkerEXT cmd;
   cmd.Init();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc
index b41eed2..3fadaf0 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3.cc
@@ -34,7 +34,9 @@
   GLES2DecoderTest3() { }
 };
 
-TEST_F(GLES2DecoderTest3, TraceBeginCHROMIUM) {
+INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest3, ::testing::Bool());
+
+TEST_P(GLES2DecoderTest3, TraceBeginCHROMIUM) {
   const uint32 kBucketId = 123;
   const char kName[] = "test_command";
   SetBucketAsCString(kBucketId, kName);
@@ -44,7 +46,7 @@
   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
 }
 
-TEST_F(GLES2DecoderTest3, TraceEndCHROMIUM) {
+TEST_P(GLES2DecoderTest3, TraceEndCHROMIUM) {
   // Test end fails if no begin.
   TraceEndCHROMIUM end_cmd;
   end_cmd.Init();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_async_pixel.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_async_pixel.cc
new file mode 100644
index 0000000..445c86f
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_async_pixel.cc
@@ -0,0 +1,390 @@
+// 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.
+
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "gpu/command_buffer/common/gles2_cmd_format.h"
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/common/id_allocator.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
+#include "gpu/command_buffer/service/cmd_buffer_engine.h"
+#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/context_state.h"
+#include "gpu/command_buffer/service/gl_surface_mock.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
+
+#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/image_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/mocks.h"
+#include "gpu/command_buffer/service/program_manager.h"
+#include "gpu/command_buffer/service/test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_mock.h"
+#include "ui/gl/gl_surface_stub.h"
+
+#if !defined(GL_DEPTH24_STENCIL8)
+#define GL_DEPTH24_STENCIL8 0x88F0
+#endif
+
+using ::gfx::MockGLInterface;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::MatcherCast;
+using ::testing::Mock;
+using ::testing::Pointee;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::SetArrayArgument;
+using ::testing::SetArgumentPointee;
+using ::testing::SetArgPointee;
+using ::testing::StrEq;
+using ::testing::StrictMock;
+
+namespace gpu {
+namespace gles2 {
+
+using namespace cmds;
+
+TEST_P(GLES2DecoderManualInitTest, AsyncPixelTransfers) {
+  InitState init;
+  init.extensions = "GL_CHROMIUM_async_pixel_transfers";
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  // Set up the texture.
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  TextureRef* texture_ref = GetTexture(client_texture_id_);
+  Texture* texture = texture_ref->texture();
+
+  // Set a mock Async delegate
+  StrictMock<gpu::MockAsyncPixelTransferManager>* manager =
+      new StrictMock<gpu::MockAsyncPixelTransferManager>;
+  manager->Initialize(group().texture_manager());
+  decoder_->SetAsyncPixelTransferManagerForTest(manager);
+  StrictMock<gpu::MockAsyncPixelTransferDelegate>* delegate = NULL;
+
+  // Tex(Sub)Image2D upload commands.
+  AsyncTexImage2DCHROMIUM teximage_cmd;
+  teximage_cmd.Init(GL_TEXTURE_2D,
+                    0,
+                    GL_RGBA,
+                    8,
+                    8,
+                    0,
+                    GL_RGBA,
+                    GL_UNSIGNED_BYTE,
+                    kSharedMemoryId,
+                    kSharedMemoryOffset,
+                    0,
+                    0,
+                    0);
+  AsyncTexSubImage2DCHROMIUM texsubimage_cmd;
+  texsubimage_cmd.Init(GL_TEXTURE_2D,
+                       0,
+                       0,
+                       0,
+                       8,
+                       8,
+                       GL_RGBA,
+                       GL_UNSIGNED_BYTE,
+                       kSharedMemoryId,
+                       kSharedMemoryOffset,
+                       0,
+                       0,
+                       0);
+  WaitAsyncTexImage2DCHROMIUM wait_cmd;
+  wait_cmd.Init(GL_TEXTURE_2D);
+  WaitAllAsyncTexImage2DCHROMIUM wait_all_cmd;
+  wait_all_cmd.Init();
+
+  // No transfer state exists initially.
+  EXPECT_FALSE(
+      decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+          texture_ref));
+
+  base::Closure bind_callback;
+
+  // AsyncTexImage2D
+  {
+    // Create transfer state since it doesn't exist.
+    EXPECT_EQ(texture_ref->num_observers(), 0);
+    EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
+        .WillOnce(Return(
+            delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
+        .RetiresOnSaturation();
+    EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _))
+        .WillOnce(SaveArg<2>(&bind_callback))
+        .RetiresOnSaturation();
+    // Command succeeds.
+    EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+    EXPECT_EQ(
+        delegate,
+        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+            texture_ref));
+    EXPECT_TRUE(texture->IsImmutable());
+    // The texture is safe but the level has not been defined yet.
+    EXPECT_TRUE(texture->SafeToRenderFrom());
+    GLsizei width, height;
+    EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+    EXPECT_EQ(texture_ref->num_observers(), 1);
+  }
+  {
+    // Async redefinitions are not allowed!
+    // Command fails.
+    EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
+    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+    EXPECT_EQ(
+        delegate,
+        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+            texture_ref));
+    EXPECT_TRUE(texture->IsImmutable());
+    EXPECT_TRUE(texture->SafeToRenderFrom());
+  }
+
+  // Binding/defining of the async transfer
+  {
+    // TODO(epenner): We should check that the manager gets the
+    // BindCompletedAsyncTransfers() call, which is required to
+    // guarantee the delegate calls the bind callback.
+
+    // Simulate the bind callback from the delegate.
+    bind_callback.Run();
+
+    // After the bind callback is run, the texture is safe,
+    // and has the right size etc.
+    EXPECT_TRUE(texture->SafeToRenderFrom());
+    GLsizei width, height;
+    EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+    EXPECT_EQ(width, 8);
+    EXPECT_EQ(height, 8);
+  }
+
+  // AsyncTexSubImage2D
+  EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
+  decoder_->GetAsyncPixelTransferManager()->ClearPixelTransferDelegateForTest(
+      texture_ref);
+  EXPECT_EQ(texture_ref->num_observers(), 0);
+  texture->SetImmutable(false);
+  {
+    // Create transfer state since it doesn't exist.
+    EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
+        .WillOnce(Return(
+            delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
+        .RetiresOnSaturation();
+    EXPECT_CALL(*delegate, AsyncTexSubImage2D(_, _)).RetiresOnSaturation();
+    // Command succeeds.
+    EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+    EXPECT_EQ(
+        delegate,
+        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+            texture_ref));
+    EXPECT_TRUE(texture->IsImmutable());
+    EXPECT_TRUE(texture->SafeToRenderFrom());
+  }
+  {
+    // No transfer is in progress.
+    EXPECT_CALL(*delegate, TransferIsInProgress())
+        .WillOnce(Return(false))  // texSubImage validation
+        .WillOnce(Return(false))  // async validation
+        .RetiresOnSaturation();
+    EXPECT_CALL(*delegate, AsyncTexSubImage2D(_, _)).RetiresOnSaturation();
+    // Command succeeds.
+    EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+    EXPECT_EQ(
+        delegate,
+        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+            texture_ref));
+    EXPECT_TRUE(texture->IsImmutable());
+    EXPECT_TRUE(texture->SafeToRenderFrom());
+  }
+  {
+    // A transfer is still in progress!
+    EXPECT_CALL(*delegate, TransferIsInProgress())
+        .WillOnce(Return(true))
+        .RetiresOnSaturation();
+    // No async call, command fails.
+    EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
+    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+    EXPECT_EQ(
+        delegate,
+        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+            texture_ref));
+    EXPECT_TRUE(texture->IsImmutable());
+    EXPECT_TRUE(texture->SafeToRenderFrom());
+  }
+
+  // Delete delegate on DeleteTexture.
+  {
+    EXPECT_EQ(texture_ref->num_observers(), 1);
+    EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
+    DoDeleteTexture(client_texture_id_, kServiceTextureId);
+    EXPECT_FALSE(
+        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+            texture_ref));
+    texture = NULL;
+    texture_ref = NULL;
+    delegate = NULL;
+  }
+
+  // WaitAsyncTexImage2D
+  {
+    // Get a fresh texture since the existing texture cannot be respecified
+    // asynchronously and AsyncTexSubImage2D does not involve binding.
+    EXPECT_CALL(*gl_, GenTextures(1, _))
+        .WillOnce(SetArgumentPointee<1>(kServiceTextureId));
+    DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+    texture_ref = GetTexture(client_texture_id_);
+    texture = texture_ref->texture();
+    texture->SetImmutable(false);
+    // Create transfer state since it doesn't exist.
+    EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
+        .WillOnce(Return(
+            delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
+        .RetiresOnSaturation();
+    EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _)).RetiresOnSaturation();
+    // Start async transfer.
+    EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+    EXPECT_EQ(
+        delegate,
+        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+            texture_ref));
+
+    EXPECT_TRUE(texture->IsImmutable());
+    // Wait for completion.
+    EXPECT_CALL(*delegate, WaitForTransferCompletion());
+    EXPECT_CALL(*manager, BindCompletedAsyncTransfers());
+    EXPECT_EQ(error::kNoError, ExecuteCmd(wait_cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  }
+
+  // WaitAllAsyncTexImage2D
+  EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
+  DoDeleteTexture(client_texture_id_, kServiceTextureId);
+  EXPECT_FALSE(
+      decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+          texture_ref));
+  texture = NULL;
+  texture_ref = NULL;
+  delegate = NULL;
+  {
+    // Get a fresh texture since the existing texture cannot be respecified
+    // asynchronously and AsyncTexSubImage2D does not involve binding.
+    EXPECT_CALL(*gl_, GenTextures(1, _))
+        .WillOnce(SetArgumentPointee<1>(kServiceTextureId));
+    DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+    texture_ref = GetTexture(client_texture_id_);
+    texture = texture_ref->texture();
+    texture->SetImmutable(false);
+    // Create transfer state since it doesn't exist.
+    EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
+        .WillOnce(Return(
+            delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
+        .RetiresOnSaturation();
+    EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _)).RetiresOnSaturation();
+    // Start async transfer.
+    EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+    EXPECT_EQ(
+        delegate,
+        decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+            texture_ref));
+
+    EXPECT_TRUE(texture->IsImmutable());
+    // Wait for completion of all uploads.
+    EXPECT_CALL(*manager, WaitAllAsyncTexImage2D()).RetiresOnSaturation();
+    EXPECT_CALL(*manager, BindCompletedAsyncTransfers());
+    EXPECT_EQ(error::kNoError, ExecuteCmd(wait_all_cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  }
+
+  // Remove PixelTransferManager before the decoder destroys.
+  EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
+  decoder_->ResetAsyncPixelTransferManagerForTest();
+  manager = NULL;
+}
+
+TEST_P(GLES2DecoderManualInitTest, AsyncPixelTransferManager) {
+  InitState init;
+  init.extensions = "GL_CHROMIUM_async_pixel_transfers";
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  // Set up the texture.
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  TextureRef* texture_ref = GetTexture(client_texture_id_);
+
+  // Set a mock Async delegate.
+  StrictMock<gpu::MockAsyncPixelTransferManager>* manager =
+      new StrictMock<gpu::MockAsyncPixelTransferManager>;
+  manager->Initialize(group().texture_manager());
+  decoder_->SetAsyncPixelTransferManagerForTest(manager);
+  StrictMock<gpu::MockAsyncPixelTransferDelegate>* delegate = NULL;
+
+  AsyncTexImage2DCHROMIUM teximage_cmd;
+  teximage_cmd.Init(GL_TEXTURE_2D,
+                    0,
+                    GL_RGBA,
+                    8,
+                    8,
+                    0,
+                    GL_RGBA,
+                    GL_UNSIGNED_BYTE,
+                    kSharedMemoryId,
+                    kSharedMemoryOffset,
+                    0,
+                    0,
+                    0);
+
+  // No transfer delegate exists initially.
+  EXPECT_FALSE(
+      decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+          texture_ref));
+
+  // Create delegate on AsyncTexImage2D.
+  {
+    EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
+        .WillOnce(Return(
+            delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
+        .RetiresOnSaturation();
+    EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _)).RetiresOnSaturation();
+
+    // Command succeeds.
+    EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  }
+
+  // Delegate is cached.
+  EXPECT_EQ(delegate,
+            decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
+                texture_ref));
+
+  // Delete delegate on manager teardown.
+  {
+    EXPECT_EQ(texture_ref->num_observers(), 1);
+    EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
+    decoder_->ResetAsyncPixelTransferManagerForTest();
+    manager = NULL;
+
+    // Texture ref still valid.
+    EXPECT_EQ(texture_ref, GetTexture(client_texture_id_));
+    EXPECT_EQ(texture_ref->num_observers(), 0);
+  }
+}
+
+}  // namespace gles2
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc
new file mode 100644
index 0000000..cf3ecd0
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc
@@ -0,0 +1,552 @@
+// 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.
+
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "gpu/command_buffer/common/gles2_cmd_format.h"
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/common/id_allocator.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
+#include "gpu/command_buffer/service/cmd_buffer_engine.h"
+#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/context_state.h"
+#include "gpu/command_buffer/service/gl_surface_mock.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
+
+#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/image_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/mocks.h"
+#include "gpu/command_buffer/service/program_manager.h"
+#include "gpu/command_buffer/service/test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_mock.h"
+#include "ui/gl/gl_surface_stub.h"
+
+#if !defined(GL_DEPTH24_STENCIL8)
+#define GL_DEPTH24_STENCIL8 0x88F0
+#endif
+
+using ::gfx::MockGLInterface;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::MatcherCast;
+using ::testing::Mock;
+using ::testing::Pointee;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::SetArrayArgument;
+using ::testing::SetArgumentPointee;
+using ::testing::SetArgPointee;
+using ::testing::StrEq;
+using ::testing::StrictMock;
+
+namespace gpu {
+namespace gles2 {
+
+using namespace cmds;
+
+TEST_P(GLES2DecoderWithShaderTest, GetVertexAttribPointervSucceeds) {
+  const float dummy = 0;
+  const GLuint kOffsetToTestFor = sizeof(dummy) * 4;
+  const GLuint kIndexToTest = 1;
+  GetVertexAttribPointerv::Result* result =
+      static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_);
+  result->size = 0;
+  const GLuint* result_value = result->GetData();
+  // Test that initial value is 0.
+  GetVertexAttribPointerv cmd;
+  cmd.Init(kIndexToTest,
+           GL_VERTEX_ATTRIB_ARRAY_POINTER,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(sizeof(*result_value), result->size);
+  EXPECT_EQ(0u, *result_value);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Set the value and see that we get it.
+  SetupVertexBuffer();
+  DoVertexAttribPointer(kIndexToTest, 2, GL_FLOAT, 0, kOffsetToTestFor);
+  result->size = 0;
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(sizeof(*result_value), result->size);
+  EXPECT_EQ(kOffsetToTestFor, *result_value);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) {
+  const GLuint kIndexToTest = 1;
+  GetVertexAttribPointerv::Result* result =
+      static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_);
+  result->size = 0;
+  const GLuint* result_value = result->GetData();
+  // Test pname invalid fails.
+  GetVertexAttribPointerv cmd;
+  cmd.Init(kIndexToTest,
+           GL_VERTEX_ATTRIB_ARRAY_POINTER + 1,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0u, result->size);
+  EXPECT_EQ(kInitialResult, *result_value);
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+
+  // Test index out of range fails.
+  result->size = 0;
+  cmd.Init(kNumVertexAttribs,
+           GL_VERTEX_ATTRIB_ARRAY_POINTER,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0u, result->size);
+  EXPECT_EQ(kInitialResult, *result_value);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+
+  // Test memory id bad fails.
+  cmd.Init(kIndexToTest,
+           GL_VERTEX_ATTRIB_ARRAY_POINTER,
+           kInvalidSharedMemoryId,
+           shared_memory_offset_);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+
+  // Test memory offset bad fails.
+  cmd.Init(kIndexToTest,
+           GL_VERTEX_ATTRIB_ARRAY_POINTER,
+           shared_memory_id_,
+           kInvalidSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, BindBufferToDifferentTargetFails) {
+  // Bind the buffer to GL_ARRAY_BUFFER
+  DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
+  // Attempt to rebind to GL_ELEMENT_ARRAY_BUFFER
+  // NOTE: Real GLES2 does not have this restriction but WebGL and we do.
+  // This can be restriction can be removed at runtime.
+  EXPECT_CALL(*gl_, BindBuffer(_, _)).Times(0);
+  BindBuffer cmd;
+  cmd.Init(GL_ELEMENT_ARRAY_BUFFER, client_buffer_id_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, VertexAttribPointer) {
+  SetupVertexBuffer();
+  static const GLenum types[] = {
+      GL_BYTE,  GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT,
+      GL_FLOAT, GL_FIXED,         GL_INT,   GL_UNSIGNED_INT,
+  };
+  static const GLsizei sizes[] = {
+      1, 1, 2, 2, 4, 4, 4, 4,
+  };
+  static const GLuint indices[] = {
+      0, 1, kNumVertexAttribs - 1, kNumVertexAttribs,
+  };
+  static const GLsizei offset_mult[] = {
+      0, 0, 1, 1, 2, 1000,
+  };
+  static const GLsizei offset_offset[] = {
+      0, 1, 0, 1, 0, 0,
+  };
+  static const GLsizei stride_mult[] = {
+      -1, 0, 0, 1, 1, 2, 1000,
+  };
+  static const GLsizei stride_offset[] = {
+      0, 0, 1, 0, 1, 0, 0,
+  };
+  for (size_t tt = 0; tt < arraysize(types); ++tt) {
+    GLenum type = types[tt];
+    GLsizei num_bytes = sizes[tt];
+    for (size_t ii = 0; ii < arraysize(indices); ++ii) {
+      GLuint index = indices[ii];
+      for (GLint size = 0; size < 5; ++size) {
+        for (size_t oo = 0; oo < arraysize(offset_mult); ++oo) {
+          GLuint offset = num_bytes * offset_mult[oo] + offset_offset[oo];
+          for (size_t ss = 0; ss < arraysize(stride_mult); ++ss) {
+            GLsizei stride = num_bytes * stride_mult[ss] + stride_offset[ss];
+            for (int normalize = 0; normalize < 2; ++normalize) {
+              bool index_good = index < static_cast<GLuint>(kNumVertexAttribs);
+              bool size_good = (size > 0 && size < 5);
+              bool offset_good = (offset % num_bytes == 0);
+              bool stride_good =
+                  (stride % num_bytes == 0) && stride >= 0 && stride <= 255;
+              bool type_good = (type != GL_INT && type != GL_UNSIGNED_INT &&
+                                type != GL_FIXED);
+              bool good = size_good && offset_good && stride_good &&
+                          type_good && index_good;
+              bool call = good && (type != GL_FIXED);
+              if (call) {
+                EXPECT_CALL(*gl_,
+                            VertexAttribPointer(index,
+                                                size,
+                                                type,
+                                                normalize,
+                                                stride,
+                                                BufferOffset(offset)));
+              }
+              VertexAttribPointer cmd;
+              cmd.Init(index, size, type, normalize, stride, offset);
+              EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+              if (good) {
+                EXPECT_EQ(GL_NO_ERROR, GetGLError());
+              } else if (size_good && offset_good && stride_good && type_good &&
+                         !index_good) {
+                EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+              } else if (size_good && offset_good && stride_good &&
+                         !type_good && index_good) {
+                EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+              } else if (size_good && offset_good && !stride_good &&
+                         type_good && index_good) {
+                if (stride < 0 || stride > 255) {
+                  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+                } else {
+                  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+                }
+              } else if (size_good && !offset_good && stride_good &&
+                         type_good && index_good) {
+                EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+              } else if (!size_good && offset_good && stride_good &&
+                         type_good && index_good) {
+                EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+              } else {
+                EXPECT_NE(GL_NO_ERROR, GetGLError());
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+class GLES2DecoderVertexArraysOESTest : public GLES2DecoderWithShaderTest {
+ public:
+  GLES2DecoderVertexArraysOESTest() {}
+
+  bool vertex_array_deleted_manually_;
+
+  virtual void SetUp() {
+    InitState init;
+    init.extensions = "GL_OES_vertex_array_object";
+    init.gl_version = "opengl es 2.0";
+    init.bind_generates_resource = true;
+    InitDecoder(init);
+    SetupDefaultProgram();
+
+    AddExpectationsForGenVertexArraysOES();
+    GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
+
+    vertex_array_deleted_manually_ = false;
+  }
+
+  virtual void TearDown() {
+    // This should only be set if the test handled deletion of the vertex array
+    // itself. Necessary because vertex_array_objects are not sharable, and thus
+    // not managed in the ContextGroup, meaning they will be destroyed during
+    // test tear down
+    if (!vertex_array_deleted_manually_) {
+      AddExpectationsForDeleteVertexArraysOES();
+    }
+
+    GLES2DecoderWithShaderTest::TearDown();
+  }
+
+  void GenVertexArraysOESValidArgs() {
+    AddExpectationsForGenVertexArraysOES();
+    GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
+    GenVertexArraysOES cmd;
+    cmd.Init(1, shared_memory_id_, shared_memory_offset_);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+    EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
+    AddExpectationsForDeleteVertexArraysOES();
+  }
+
+  void GenVertexArraysOESInvalidArgs() {
+    EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
+    GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
+    GenVertexArraysOES cmd;
+    cmd.Init(1, shared_memory_id_, shared_memory_offset_);
+    EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
+  }
+
+  void GenVertexArraysOESImmediateValidArgs() {
+    AddExpectationsForGenVertexArraysOES();
+    GenVertexArraysOESImmediate* cmd =
+        GetImmediateAs<GenVertexArraysOESImmediate>();
+    GLuint temp = kNewClientId;
+    cmd->Init(1, &temp);
+    EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp)));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+    EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
+    AddExpectationsForDeleteVertexArraysOES();
+  }
+
+  void GenVertexArraysOESImmediateInvalidArgs() {
+    EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
+    GenVertexArraysOESImmediate* cmd =
+        GetImmediateAs<GenVertexArraysOESImmediate>();
+    cmd->Init(1, &client_vertexarray_id_);
+    EXPECT_EQ(error::kInvalidArguments,
+              ExecuteImmediateCmd(*cmd, sizeof(&client_vertexarray_id_)));
+  }
+
+  void DeleteVertexArraysOESValidArgs() {
+    AddExpectationsForDeleteVertexArraysOES();
+    GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
+    DeleteVertexArraysOES cmd;
+    cmd.Init(1, shared_memory_id_, shared_memory_offset_);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+    EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_) == NULL);
+    vertex_array_deleted_manually_ = true;
+  }
+
+  void DeleteVertexArraysOESInvalidArgs() {
+    GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
+    DeleteVertexArraysOES cmd;
+    cmd.Init(1, shared_memory_id_, shared_memory_offset_);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  }
+
+  void DeleteVertexArraysOESImmediateValidArgs() {
+    AddExpectationsForDeleteVertexArraysOES();
+    DeleteVertexArraysOESImmediate& cmd =
+        *GetImmediateAs<DeleteVertexArraysOESImmediate>();
+    cmd.Init(1, &client_vertexarray_id_);
+    EXPECT_EQ(error::kNoError,
+              ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_)));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+    EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_) == NULL);
+    vertex_array_deleted_manually_ = true;
+  }
+
+  void DeleteVertexArraysOESImmediateInvalidArgs() {
+    DeleteVertexArraysOESImmediate& cmd =
+        *GetImmediateAs<DeleteVertexArraysOESImmediate>();
+    GLuint temp = kInvalidClientId;
+    cmd.Init(1, &temp);
+    EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+  }
+
+  void DeleteBoundVertexArraysOESImmediateValidArgs() {
+    BindVertexArrayOESValidArgs();
+
+    AddExpectationsForDeleteBoundVertexArraysOES();
+    DeleteVertexArraysOESImmediate& cmd =
+        *GetImmediateAs<DeleteVertexArraysOESImmediate>();
+    cmd.Init(1, &client_vertexarray_id_);
+    EXPECT_EQ(error::kNoError,
+              ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_)));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+    EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_) == NULL);
+    vertex_array_deleted_manually_ = true;
+  }
+
+  void IsVertexArrayOESValidArgs() {
+    IsVertexArrayOES cmd;
+    cmd.Init(client_vertexarray_id_, shared_memory_id_, shared_memory_offset_);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  }
+
+  void IsVertexArrayOESInvalidArgsBadSharedMemoryId() {
+    IsVertexArrayOES cmd;
+    cmd.Init(
+        client_vertexarray_id_, kInvalidSharedMemoryId, shared_memory_offset_);
+    EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+    cmd.Init(
+        client_vertexarray_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
+    EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+  }
+
+  void BindVertexArrayOESValidArgs() {
+    AddExpectationsForBindVertexArrayOES();
+    BindVertexArrayOES cmd;
+    cmd.Init(client_vertexarray_id_);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  }
+
+  void BindVertexArrayOESValidArgsNewId() {
+    BindVertexArrayOES cmd;
+    cmd.Init(kNewClientId);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(Service,
+                        GLES2DecoderVertexArraysOESTest,
+                        ::testing::Bool());
+
+class GLES2DecoderEmulatedVertexArraysOESTest
+    : public GLES2DecoderVertexArraysOESTest {
+ public:
+  GLES2DecoderEmulatedVertexArraysOESTest() {}
+
+  virtual void SetUp() {
+    InitState init;
+    init.gl_version = "3.0";
+    init.bind_generates_resource = true;
+    InitDecoder(init);
+    SetupDefaultProgram();
+
+    AddExpectationsForGenVertexArraysOES();
+    GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
+
+    vertex_array_deleted_manually_ = false;
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(Service,
+                        GLES2DecoderEmulatedVertexArraysOESTest,
+                        ::testing::Bool());
+
+// Test vertex array objects with native support
+TEST_P(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESValidArgs) {
+  GenVertexArraysOESValidArgs();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, GenVertexArraysOESValidArgs) {
+  GenVertexArraysOESValidArgs();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESInvalidArgs) {
+  GenVertexArraysOESInvalidArgs();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, ) {
+  GenVertexArraysOESInvalidArgs();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESImmediateValidArgs) {
+  GenVertexArraysOESImmediateValidArgs();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
+       GenVertexArraysOESImmediateValidArgs) {
+  GenVertexArraysOESImmediateValidArgs();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest,
+       GenVertexArraysOESImmediateInvalidArgs) {
+  GenVertexArraysOESImmediateInvalidArgs();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
+       GenVertexArraysOESImmediateInvalidArgs) {
+  GenVertexArraysOESImmediateInvalidArgs();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest, DeleteVertexArraysOESValidArgs) {
+  DeleteVertexArraysOESValidArgs();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
+       DeleteVertexArraysOESValidArgs) {
+  DeleteVertexArraysOESValidArgs();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest, DeleteVertexArraysOESInvalidArgs) {
+  DeleteVertexArraysOESInvalidArgs();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
+       DeleteVertexArraysOESInvalidArgs) {
+  DeleteVertexArraysOESInvalidArgs();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest,
+       DeleteVertexArraysOESImmediateValidArgs) {
+  DeleteVertexArraysOESImmediateValidArgs();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
+       DeleteVertexArraysOESImmediateValidArgs) {
+  DeleteVertexArraysOESImmediateValidArgs();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest,
+       DeleteVertexArraysOESImmediateInvalidArgs) {
+  DeleteVertexArraysOESImmediateInvalidArgs();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
+       DeleteVertexArraysOESImmediateInvalidArgs) {
+  DeleteVertexArraysOESImmediateInvalidArgs();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest,
+       DeleteBoundVertexArraysOESImmediateValidArgs) {
+  DeleteBoundVertexArraysOESImmediateValidArgs();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
+       DeleteBoundVertexArraysOESImmediateValidArgs) {
+  DeleteBoundVertexArraysOESImmediateValidArgs();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest, IsVertexArrayOESValidArgs) {
+  IsVertexArrayOESValidArgs();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, IsVertexArrayOESValidArgs) {
+  IsVertexArrayOESValidArgs();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest,
+       IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
+  IsVertexArrayOESInvalidArgsBadSharedMemoryId();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
+       IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
+  IsVertexArrayOESInvalidArgsBadSharedMemoryId();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgs) {
+  BindVertexArrayOESValidArgs();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, BindVertexArrayOESValidArgs) {
+  BindVertexArrayOESValidArgs();
+}
+
+TEST_P(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgsNewId) {
+  BindVertexArrayOESValidArgsNewId();
+}
+TEST_P(GLES2DecoderEmulatedVertexArraysOESTest,
+       BindVertexArrayOESValidArgsNewId) {
+  BindVertexArrayOESValidArgsNewId();
+}
+
+TEST_P(GLES2DecoderTest, BufferDataGLError) {
+  GLenum target = GL_ARRAY_BUFFER;
+  GLsizeiptr size = 4;
+  DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
+  BufferManager* manager = group().buffer_manager();
+  Buffer* buffer = manager->GetBuffer(client_buffer_id_);
+  ASSERT_TRUE(buffer != NULL);
+  EXPECT_EQ(0, buffer->size());
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_OUT_OF_MEMORY))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, BufferData(target, size, _, GL_STREAM_DRAW))
+      .Times(1)
+      .RetiresOnSaturation();
+  BufferData cmd;
+  cmd.Init(target, size, 0, 0, GL_STREAM_DRAW);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+  EXPECT_EQ(0, buffer->size());
+}
+
+// TODO(gman): BufferData
+
+// TODO(gman): BufferDataImmediate
+
+// TODO(gman): BufferSubData
+
+// TODO(gman): BufferSubDataImmediate
+
+}  // namespace gles2
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index b1ed1df..e812b41 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -53,7 +53,15 @@
       client_vertex_shader_id_(121),
       client_fragment_shader_id_(122),
       client_query_id_(123),
-      client_vertexarray_id_(124) {
+      client_vertexarray_id_(124),
+      ignore_cached_state_for_test_(GetParam()),
+      cached_color_mask_red_(true),
+      cached_color_mask_green_(true),
+      cached_color_mask_blue_(true),
+      cached_color_mask_alpha_(true),
+      cached_depth_mask_(true),
+      cached_stencil_front_mask_(0xFFFFFFFFU),
+      cached_stencil_back_mask_(0xFFFFFFFFU) {
   memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_));
 }
 
@@ -86,7 +94,8 @@
       request_depth(false),
       request_stencil(false),
       bind_generates_resource(false),
-      lose_context_when_out_of_memory(false) {}
+      lose_context_when_out_of_memory(false) {
+}
 
 void GLES2DecoderTestBase::InitDecoder(const InitState& init) {
   InitDecoderWithCommandLine(init, NULL);
@@ -146,11 +155,6 @@
   EXPECT_TRUE(
       group_->Initialize(mock_decoder_.get(), DisallowedFeatures()));
 
-  if (group_->feature_info()->feature_flags().native_vertex_array_object) {
-    EXPECT_CALL(*gl_, GenVertexArraysOES(1, _)).Times(1).RetiresOnSaturation();
-    EXPECT_CALL(*gl_, BindVertexArrayOES(_)).Times(1).RetiresOnSaturation();
-  }
-
   if (group_->feature_info()->workarounds().init_vertex_attributes)
     AddExpectationsForVertexAttribManager();
 
@@ -307,6 +311,7 @@
   std::vector<int32> attribs(attributes, attributes + arraysize(attributes));
 
   decoder_.reset(GLES2Decoder::Create(group_.get()));
+  decoder_->SetIgnoreCachedStateForTest(ignore_cached_state_for_test_);
   decoder_->GetLogger()->set_log_synthesized_gl_errors(false);
   decoder_->Initialize(surface_,
                        context_,
@@ -555,9 +560,7 @@
     EXPECT_CALL(*gl_, ClearColor(0.0f, 0.0f, 0.0f, 0.0f))
         .Times(1)
         .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, ColorMask(true, true, true, true))
-        .Times(1)
-        .RetiresOnSaturation();
+    SetupExpectationsForColorMask(true, true, true, true);
   }
   if ((clear_bits & GL_STENCIL_BUFFER_BIT) != 0) {
     EXPECT_CALL(*gl_, ClearStencil(0))
@@ -571,13 +574,9 @@
     EXPECT_CALL(*gl_, ClearDepth(1.0f))
         .Times(1)
         .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, DepthMask(1))
-        .Times(1)
-        .RetiresOnSaturation();
+    SetupExpectationsForDepthMask(true);
   }
-  EXPECT_CALL(*gl_, Disable(GL_SCISSOR_TEST))
-      .Times(1)
-      .RetiresOnSaturation();
+  SetupExpectationsForEnableDisable(GL_SCISSOR_TEST, false);
   EXPECT_CALL(*gl_, Clear(clear_bits))
       .Times(1)
       .RetiresOnSaturation();
@@ -647,6 +646,98 @@
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
 }
 
+void GLES2DecoderTestBase::SetupExpectationsForColorMask(bool red,
+                                                         bool green,
+                                                         bool blue,
+                                                         bool alpha) {
+  if (ignore_cached_state_for_test_ || cached_color_mask_red_ != red ||
+      cached_color_mask_green_ != green || cached_color_mask_blue_ != blue ||
+      cached_color_mask_alpha_ != alpha) {
+    cached_color_mask_red_ = red;
+    cached_color_mask_green_ = green;
+    cached_color_mask_blue_ = blue;
+    cached_color_mask_alpha_ = alpha;
+    EXPECT_CALL(*gl_, ColorMask(red, green, blue, alpha))
+        .Times(1)
+        .RetiresOnSaturation();
+  }
+}
+
+void GLES2DecoderTestBase::SetupExpectationsForDepthMask(bool mask) {
+  if (ignore_cached_state_for_test_ || cached_depth_mask_ != mask) {
+    cached_depth_mask_ = mask;
+    EXPECT_CALL(*gl_, DepthMask(mask)).Times(1).RetiresOnSaturation();
+  }
+}
+
+void GLES2DecoderTestBase::SetupExpectationsForEnableDisable(GLenum cap,
+                                                             bool enable) {
+  switch (cap) {
+    case GL_BLEND:
+      if (enable_flags_.cached_blend == enable &&
+          !ignore_cached_state_for_test_)
+        return;
+      enable_flags_.cached_blend = enable;
+      break;
+    case GL_CULL_FACE:
+      if (enable_flags_.cached_cull_face == enable &&
+          !ignore_cached_state_for_test_)
+        return;
+      enable_flags_.cached_cull_face = enable;
+      break;
+    case GL_DEPTH_TEST:
+      if (enable_flags_.cached_depth_test == enable &&
+          !ignore_cached_state_for_test_)
+        return;
+      enable_flags_.cached_depth_test = enable;
+      break;
+    case GL_DITHER:
+      if (enable_flags_.cached_dither == enable &&
+          !ignore_cached_state_for_test_)
+        return;
+      enable_flags_.cached_dither = enable;
+      break;
+    case GL_POLYGON_OFFSET_FILL:
+      if (enable_flags_.cached_polygon_offset_fill == enable &&
+          !ignore_cached_state_for_test_)
+        return;
+      enable_flags_.cached_polygon_offset_fill = enable;
+      break;
+    case GL_SAMPLE_ALPHA_TO_COVERAGE:
+      if (enable_flags_.cached_sample_alpha_to_coverage == enable &&
+          !ignore_cached_state_for_test_)
+        return;
+      enable_flags_.cached_sample_alpha_to_coverage = enable;
+      break;
+    case GL_SAMPLE_COVERAGE:
+      if (enable_flags_.cached_sample_coverage == enable &&
+          !ignore_cached_state_for_test_)
+        return;
+      enable_flags_.cached_sample_coverage = enable;
+      break;
+    case GL_SCISSOR_TEST:
+      if (enable_flags_.cached_scissor_test == enable &&
+          !ignore_cached_state_for_test_)
+        return;
+      enable_flags_.cached_scissor_test = enable;
+      break;
+    case GL_STENCIL_TEST:
+      if (enable_flags_.cached_stencil_test == enable &&
+          !ignore_cached_state_for_test_)
+        return;
+      enable_flags_.cached_stencil_test = enable;
+      break;
+    default:
+      NOTREACHED();
+      return;
+  }
+  if (enable) {
+    EXPECT_CALL(*gl_, Enable(cap)).Times(1).RetiresOnSaturation();
+  } else {
+    EXPECT_CALL(*gl_, Disable(cap)).Times(1).RetiresOnSaturation();
+  }
+}
+
 void GLES2DecoderTestBase::SetupExpectationsForApplyingDirtyState(
     bool framebuffer_is_rgb,
     bool framebuffer_has_depth,
@@ -656,87 +747,60 @@
     bool depth_enabled,
     GLuint front_stencil_mask,
     GLuint back_stencil_mask,
-    bool stencil_enabled,
-    bool cull_face_enabled,
-    bool scissor_test_enabled,
-    bool blend_enabled) {
-  EXPECT_CALL(*gl_, ColorMask(
-      (color_bits & 0x1000) != 0,
-      (color_bits & 0x0100) != 0,
-      (color_bits & 0x0010) != 0,
-      (color_bits & 0x0001) && !framebuffer_is_rgb))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, DepthMask(depth_mask))
-      .Times(1)
-      .RetiresOnSaturation();
-  if (framebuffer_has_depth && depth_enabled) {
-    EXPECT_CALL(*gl_, Enable(GL_DEPTH_TEST))
-        .Times(1)
-        .RetiresOnSaturation();
-  } else {
-    EXPECT_CALL(*gl_, Disable(GL_DEPTH_TEST))
+    bool stencil_enabled) {
+  bool color_mask_red = (color_bits & 0x1000) != 0;
+  bool color_mask_green = (color_bits & 0x0100) != 0;
+  bool color_mask_blue = (color_bits & 0x0010) != 0;
+  bool color_mask_alpha = (color_bits & 0x0001) && !framebuffer_is_rgb;
+
+  SetupExpectationsForColorMask(
+      color_mask_red, color_mask_green, color_mask_blue, color_mask_alpha);
+  SetupExpectationsForDepthMask(depth_mask);
+
+  if (ignore_cached_state_for_test_ ||
+      cached_stencil_front_mask_ != front_stencil_mask) {
+    cached_stencil_front_mask_ = front_stencil_mask;
+    EXPECT_CALL(*gl_, StencilMaskSeparate(GL_FRONT, front_stencil_mask))
         .Times(1)
         .RetiresOnSaturation();
   }
-  EXPECT_CALL(*gl_, StencilMaskSeparate(GL_FRONT, front_stencil_mask))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, StencilMaskSeparate(GL_BACK, back_stencil_mask))
-      .Times(1)
-      .RetiresOnSaturation();
-  if (framebuffer_has_stencil && stencil_enabled) {
-    EXPECT_CALL(*gl_, Enable(GL_STENCIL_TEST))
-        .Times(1)
-        .RetiresOnSaturation();
-  } else {
-    EXPECT_CALL(*gl_, Disable(GL_STENCIL_TEST))
+
+  if (ignore_cached_state_for_test_ ||
+      cached_stencil_back_mask_ != back_stencil_mask) {
+    cached_stencil_back_mask_ = back_stencil_mask;
+    EXPECT_CALL(*gl_, StencilMaskSeparate(GL_BACK, back_stencil_mask))
         .Times(1)
         .RetiresOnSaturation();
   }
-  if (cull_face_enabled) {
-    EXPECT_CALL(*gl_, Enable(GL_CULL_FACE))
-        .Times(1)
-        .RetiresOnSaturation();
-  } else {
-    EXPECT_CALL(*gl_, Disable(GL_CULL_FACE))
-        .Times(1)
-        .RetiresOnSaturation();
-  }
-  if (scissor_test_enabled) {
-    EXPECT_CALL(*gl_, Enable(GL_SCISSOR_TEST))
-        .Times(1)
-        .RetiresOnSaturation();
-  } else {
-    EXPECT_CALL(*gl_, Disable(GL_SCISSOR_TEST))
-        .Times(1)
-        .RetiresOnSaturation();
-  }
-  if (blend_enabled) {
-    EXPECT_CALL(*gl_, Enable(GL_BLEND))
-        .Times(1)
-        .RetiresOnSaturation();
-  } else {
-    EXPECT_CALL(*gl_, Disable(GL_BLEND))
-        .Times(1)
-        .RetiresOnSaturation();
-  }
+
+  SetupExpectationsForEnableDisable(GL_DEPTH_TEST,
+                                    framebuffer_has_depth && depth_enabled);
+  SetupExpectationsForEnableDisable(GL_STENCIL_TEST,
+                                    framebuffer_has_stencil && stencil_enabled);
 }
 
 void GLES2DecoderTestBase::SetupExpectationsForApplyingDefaultDirtyState() {
-  SetupExpectationsForApplyingDirtyState(
-      false,   // Framebuffer is RGB
-      false,   // Framebuffer has depth
-      false,   // Framebuffer has stencil
-      0x1111,  // color bits
-      true,    // depth mask
-      false,   // depth enabled
-      0,       // front stencil mask
-      0,       // back stencil mask
-      false,   // stencil enabled
-      false,   // cull_face_enabled
-      false,   // scissor_test_enabled
-      false);  // blend_enabled
+  SetupExpectationsForApplyingDirtyState(false,   // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1111,  // color bits
+                                         true,    // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+}
+
+GLES2DecoderTestBase::EnableFlags::EnableFlags()
+    : cached_blend(false),
+      cached_cull_face(false),
+      cached_depth_test(false),
+      cached_dither(true),
+      cached_polygon_offset_fill(false),
+      cached_sample_alpha_to_coverage(false),
+      cached_sample_coverage(false),
+      cached_scissor_test(false),
+      cached_stencil_test(false) {
 }
 
 void GLES2DecoderTestBase::DoBindFramebuffer(
@@ -1308,6 +1372,19 @@
   EXPECT_EQ(error::kNoError, ExecuteCmd(link_cmd));
 }
 
+void GLES2DecoderTestBase::DoEnableDisable(GLenum cap, bool enable) {
+  SetupExpectationsForEnableDisable(cap, enable);
+  if (enable) {
+    cmds::Enable cmd;
+    cmd.Init(cap);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  } else {
+    cmds::Disable cmd;
+    cmd.Init(cap);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  }
+}
+
 void GLES2DecoderTestBase::DoEnableVertexAttribArray(GLint index) {
   EXPECT_CALL(*gl_, EnableVertexAttribArray(index))
       .Times(1)
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index 52e7211..91ff2e1 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -34,7 +34,7 @@
 
 class MemoryTracker;
 
-class GLES2DecoderTestBase : public testing::Test {
+class GLES2DecoderTestBase : public ::testing::TestWithParam<bool> {
  public:
   GLES2DecoderTestBase();
   virtual ~GLES2DecoderTestBase();
@@ -269,6 +269,8 @@
       GLuint index, GLint size, GLenum type, GLsizei stride, GLuint offset);
   void DoVertexAttribDivisorANGLE(GLuint index, GLuint divisor);
 
+  void DoEnableDisable(GLenum cap, bool enable);
+
   void DoEnableVertexAttribArray(GLint index);
 
   void DoBufferData(GLenum target, GLsizei size);
@@ -330,6 +332,13 @@
       GLclampf restore_depth,
       bool restore_scissor_test);
 
+  void SetupExpectationsForDepthMask(bool mask);
+  void SetupExpectationsForEnableDisable(GLenum cap, bool enable);
+  void SetupExpectationsForColorMask(bool red,
+                                     bool green,
+                                     bool blue,
+                                     bool alpha);
+
   void SetupExpectationsForApplyingDirtyState(
       bool framebuffer_is_rgb,
       bool framebuffer_has_depth,
@@ -339,10 +348,7 @@
       bool depth_enabled,
       GLuint front_stencil_mask,
       GLuint back_stencil_mask,
-      bool stencil_enabled,
-      bool cull_face_enabled,
-      bool scissor_test_enabled,
-      bool blend_enabled);
+      bool stencil_enabled);
 
   void SetupExpectationsForApplyingDefaultDirtyState();
 
@@ -510,6 +516,30 @@
 
   int8 immediate_buffer_[256];
 
+  const bool ignore_cached_state_for_test_;
+  bool cached_color_mask_red_;
+  bool cached_color_mask_green_;
+  bool cached_color_mask_blue_;
+  bool cached_color_mask_alpha_;
+  bool cached_depth_mask_;
+  uint32 cached_stencil_front_mask_;
+  uint32 cached_stencil_back_mask_;
+
+  struct EnableFlags {
+    EnableFlags();
+    bool cached_blend;
+    bool cached_cull_face;
+    bool cached_depth_test;
+    bool cached_dither;
+    bool cached_polygon_offset_fill;
+    bool cached_sample_alpha_to_coverage;
+    bool cached_sample_coverage;
+    bool cached_scissor_test;
+    bool cached_stencil_test;
+  };
+
+  EnableFlags enable_flags_;
+
  private:
   class MockCommandBufferEngine : public CommandBufferEngine {
    public:
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc
new file mode 100644
index 0000000..49ebfc3
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc
@@ -0,0 +1,428 @@
+// 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.
+
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "gpu/command_buffer/common/gles2_cmd_format.h"
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/common/id_allocator.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
+#include "gpu/command_buffer/service/cmd_buffer_engine.h"
+#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/context_state.h"
+#include "gpu/command_buffer/service/gl_surface_mock.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
+
+#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/image_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/mocks.h"
+#include "gpu/command_buffer/service/program_manager.h"
+#include "gpu/command_buffer/service/test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_mock.h"
+#include "ui/gl/gl_surface_stub.h"
+
+#if !defined(GL_DEPTH24_STENCIL8)
+#define GL_DEPTH24_STENCIL8 0x88F0
+#endif
+
+using ::gfx::MockGLInterface;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::MatcherCast;
+using ::testing::Mock;
+using ::testing::Pointee;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::SetArrayArgument;
+using ::testing::SetArgumentPointee;
+using ::testing::SetArgPointee;
+using ::testing::StrEq;
+using ::testing::StrictMock;
+
+namespace gpu {
+namespace gles2 {
+
+using namespace cmds;
+
+class GLES2DecoderRestoreStateTest : public GLES2DecoderManualInitTest {
+ public:
+  GLES2DecoderRestoreStateTest() {}
+
+ protected:
+  void AddExpectationsForActiveTexture(GLenum unit);
+  void AddExpectationsForBindTexture(GLenum target, GLuint id);
+  void InitializeContextState(ContextState* state,
+                              uint32 non_default_unit,
+                              uint32 active_unit);
+};
+
+INSTANTIATE_TEST_CASE_P(Service,
+                        GLES2DecoderRestoreStateTest,
+                        ::testing::Bool());
+
+void GLES2DecoderRestoreStateTest::AddExpectationsForActiveTexture(
+    GLenum unit) {
+  EXPECT_CALL(*gl_, ActiveTexture(unit)).Times(1).RetiresOnSaturation();
+}
+
+void GLES2DecoderRestoreStateTest::AddExpectationsForBindTexture(GLenum target,
+                                                                 GLuint id) {
+  EXPECT_CALL(*gl_, BindTexture(target, id)).Times(1).RetiresOnSaturation();
+}
+
+void GLES2DecoderRestoreStateTest::InitializeContextState(
+    ContextState* state,
+    uint32 non_default_unit,
+    uint32 active_unit) {
+  state->texture_units.resize(group().max_texture_units());
+  for (uint32 tt = 0; tt < state->texture_units.size(); ++tt) {
+    TextureRef* ref_cube_map =
+        group().texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
+    state->texture_units[tt].bound_texture_cube_map = ref_cube_map;
+    TextureRef* ref_2d =
+        (tt == non_default_unit)
+            ? group().texture_manager()->GetTexture(client_texture_id_)
+            : group().texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
+    state->texture_units[tt].bound_texture_2d = ref_2d;
+  }
+  state->active_texture_unit = active_unit;
+}
+
+TEST_P(GLES2DecoderRestoreStateTest, NullPreviousStateBGR) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  SetupTexture();
+
+  InSequence sequence;
+  // Expect to restore texture bindings for unit GL_TEXTURE0.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
+  AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP,
+                                TestHelper::kServiceDefaultTextureCubemapId);
+
+  // Expect to restore texture bindings for remaining units.
+  for (uint32 i = 1; i < group().max_texture_units(); ++i) {
+    AddExpectationsForActiveTexture(GL_TEXTURE0 + i);
+    AddExpectationsForBindTexture(GL_TEXTURE_2D,
+                                  TestHelper::kServiceDefaultTexture2dId);
+    AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP,
+                                  TestHelper::kServiceDefaultTextureCubemapId);
+  }
+
+  // Expect to restore the active texture unit to GL_TEXTURE0.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+
+  GetDecoder()->RestoreAllTextureUnitBindings(NULL);
+}
+
+TEST_P(GLES2DecoderRestoreStateTest, NullPreviousState) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+  SetupTexture();
+
+  InSequence sequence;
+  // Expect to restore texture bindings for unit GL_TEXTURE0.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
+  AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+
+  // Expect to restore texture bindings for remaining units.
+  for (uint32 i = 1; i < group().max_texture_units(); ++i) {
+    AddExpectationsForActiveTexture(GL_TEXTURE0 + i);
+    AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);
+    AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+  }
+
+  // Expect to restore the active texture unit to GL_TEXTURE0.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+
+  GetDecoder()->RestoreAllTextureUnitBindings(NULL);
+}
+
+TEST_P(GLES2DecoderRestoreStateTest, WithPreviousStateBGR) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  SetupTexture();
+
+  // Construct a previous ContextState with all texture bindings
+  // set to default textures.
+  ContextState prev_state(NULL, NULL, NULL);
+  InitializeContextState(&prev_state, std::numeric_limits<uint32>::max(), 0);
+
+  InSequence sequence;
+  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE0 unit,
+  // since the rest of the bindings haven't changed between the current
+  // state and the |prev_state|.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
+
+  // Expect to restore active texture unit to GL_TEXTURE0.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+
+  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
+}
+
+TEST_P(GLES2DecoderRestoreStateTest, WithPreviousState) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+  SetupTexture();
+
+  // Construct a previous ContextState with all texture bindings
+  // set to default textures.
+  ContextState prev_state(NULL, NULL, NULL);
+  InitializeContextState(&prev_state, std::numeric_limits<uint32>::max(), 0);
+
+  InSequence sequence;
+  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE0 unit,
+  // since the rest of the bindings haven't changed between the current
+  // state and the |prev_state|.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
+
+  // Expect to restore active texture unit to GL_TEXTURE0.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+
+  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
+}
+
+TEST_P(GLES2DecoderRestoreStateTest, ActiveUnit1) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+
+  // Bind a non-default texture to GL_TEXTURE1 unit.
+  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
+  ActiveTexture cmd;
+  cmd.Init(GL_TEXTURE1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  SetupTexture();
+
+  // Construct a previous ContextState with all texture bindings
+  // set to default textures.
+  ContextState prev_state(NULL, NULL, NULL);
+  InitializeContextState(&prev_state, std::numeric_limits<uint32>::max(), 0);
+
+  InSequence sequence;
+  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE1 unit,
+  // since the rest of the bindings haven't changed between the current
+  // state and the |prev_state|.
+  AddExpectationsForActiveTexture(GL_TEXTURE1);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
+
+  // Expect to restore active texture unit to GL_TEXTURE1.
+  AddExpectationsForActiveTexture(GL_TEXTURE1);
+
+  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
+}
+
+TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit0BGR) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  // Bind a non-default texture to GL_TEXTURE1 unit.
+  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
+  SpecializedSetup<ActiveTexture, 0>(true);
+  ActiveTexture cmd;
+  cmd.Init(GL_TEXTURE1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  SetupTexture();
+
+  // Construct a previous ContextState with GL_TEXTURE_2D target in
+  // GL_TEXTURE0 unit bound to a non-default texture and the rest
+  // set to default textures.
+  ContextState prev_state(NULL, NULL, NULL);
+  InitializeContextState(&prev_state, 0, kServiceTextureId);
+
+  InSequence sequence;
+  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE0 unit to
+  // a default texture.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D,
+                                TestHelper::kServiceDefaultTexture2dId);
+
+  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE1 unit to
+  // non-default.
+  AddExpectationsForActiveTexture(GL_TEXTURE1);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
+
+  // Expect to restore active texture unit to GL_TEXTURE1.
+  AddExpectationsForActiveTexture(GL_TEXTURE1);
+
+  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
+}
+
+TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit1BGR) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  // Bind a non-default texture to GL_TEXTURE0 unit.
+  SetupTexture();
+
+  // Construct a previous ContextState with GL_TEXTURE_2D target in
+  // GL_TEXTURE1 unit bound to a non-default texture and the rest
+  // set to default textures.
+  ContextState prev_state(NULL, NULL, NULL);
+  InitializeContextState(&prev_state, 1, kServiceTextureId);
+
+  InSequence sequence;
+  // Expect to restore GL_TEXTURE_2D binding to the non-default texture
+  // for GL_TEXTURE0 unit.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
+
+  // Expect to restore GL_TEXTURE_2D binding to the default texture
+  // for GL_TEXTURE1 unit.
+  AddExpectationsForActiveTexture(GL_TEXTURE1);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D,
+                                TestHelper::kServiceDefaultTexture2dId);
+
+  // Expect to restore active texture unit to GL_TEXTURE0.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+
+  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
+}
+
+TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit0) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+
+  // Bind a non-default texture to GL_TEXTURE1 unit.
+  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
+  SpecializedSetup<ActiveTexture, 0>(true);
+  ActiveTexture cmd;
+  cmd.Init(GL_TEXTURE1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  SetupTexture();
+
+  // Construct a previous ContextState with GL_TEXTURE_2D target in
+  // GL_TEXTURE0 unit bound to a non-default texture and the rest
+  // set to default textures.
+  ContextState prev_state(NULL, NULL, NULL);
+  InitializeContextState(&prev_state, 0, kServiceTextureId);
+
+  InSequence sequence;
+  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE0 unit to
+  // the 0 texture.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);
+
+  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE1 unit to
+  // non-default.
+  AddExpectationsForActiveTexture(GL_TEXTURE1);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
+
+  // Expect to restore active texture unit to GL_TEXTURE1.
+  AddExpectationsForActiveTexture(GL_TEXTURE1);
+
+  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
+}
+
+TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit1) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+
+  // Bind a non-default texture to GL_TEXTURE0 unit.
+  SetupTexture();
+
+  // Construct a previous ContextState with GL_TEXTURE_2D target in
+  // GL_TEXTURE1 unit bound to a non-default texture and the rest
+  // set to default textures.
+  ContextState prev_state(NULL, NULL, NULL);
+  InitializeContextState(&prev_state, 1, kServiceTextureId);
+
+  InSequence sequence;
+  // Expect to restore GL_TEXTURE_2D binding to the non-default texture
+  // for GL_TEXTURE0 unit.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
+
+  // Expect to restore GL_TEXTURE_2D binding to the 0 texture
+  // for GL_TEXTURE1 unit.
+  AddExpectationsForActiveTexture(GL_TEXTURE1);
+  AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);
+
+  // Expect to restore active texture unit to GL_TEXTURE0.
+  AddExpectationsForActiveTexture(GL_TEXTURE0);
+
+  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
+}
+
+TEST_P(GLES2DecoderManualInitTest, ContextStateCapabilityCaching) {
+  struct TestInfo {
+    GLenum gl_enum;
+    bool default_state;
+    bool expect_set;
+  };
+
+  // TODO(vmiura): Should autogen this to match build_gles2_cmd_buffer.py.
+  TestInfo test[] = {{GL_BLEND, false, true},
+                     {GL_CULL_FACE, false, true},
+                     {GL_DEPTH_TEST, false, false},
+                     {GL_DITHER, true, true},
+                     {GL_POLYGON_OFFSET_FILL, false, true},
+                     {GL_SAMPLE_ALPHA_TO_COVERAGE, false, true},
+                     {GL_SAMPLE_COVERAGE, false, true},
+                     {GL_SCISSOR_TEST, false, true},
+                     {GL_STENCIL_TEST, false, false},
+                     {0, false, false}};
+
+  InitState init;
+  init.gl_version = "2.1";
+  InitDecoder(init);
+
+  for (int i = 0; test[i].gl_enum; i++) {
+    bool enable_state = test[i].default_state;
+
+    // Test setting default state initially is ignored.
+    EnableDisableTest(test[i].gl_enum, enable_state, test[i].expect_set);
+
+    // Test new and cached state changes.
+    for (int n = 0; n < 3; n++) {
+      enable_state = !enable_state;
+      EnableDisableTest(test[i].gl_enum, enable_state, test[i].expect_set);
+      EnableDisableTest(test[i].gl_enum, enable_state, test[i].expect_set);
+    }
+  }
+}
+
+// TODO(vmiura): Tests for VAO restore.
+
+// TODO(vmiura): Tests for ContextState::RestoreAttribute().
+
+// TODO(vmiura): Tests for ContextState::RestoreBufferBindings().
+
+// TODO(vmiura): Tests for ContextState::RestoreProgramBindings().
+
+// TODO(vmiura): Tests for ContextState::RestoreRenderbufferBindings().
+
+// TODO(vmiura): Tests for ContextState::RestoreProgramBindings().
+
+// TODO(vmiura): Tests for ContextState::RestoreGlobalState().
+
+}  // namespace gles2
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc
new file mode 100644
index 0000000..b5e6801
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc
@@ -0,0 +1,2268 @@
+// 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.
+
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "gpu/command_buffer/common/gles2_cmd_format.h"
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/common/id_allocator.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
+#include "gpu/command_buffer/service/cmd_buffer_engine.h"
+#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/context_state.h"
+#include "gpu/command_buffer/service/gl_surface_mock.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
+
+#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/image_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/mocks.h"
+#include "gpu/command_buffer/service/program_manager.h"
+#include "gpu/command_buffer/service/test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_mock.h"
+#include "ui/gl/gl_surface_stub.h"
+
+#if !defined(GL_DEPTH24_STENCIL8)
+#define GL_DEPTH24_STENCIL8 0x88F0
+#endif
+
+using ::gfx::MockGLInterface;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::MatcherCast;
+using ::testing::Mock;
+using ::testing::Pointee;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::SetArrayArgument;
+using ::testing::SetArgumentPointee;
+using ::testing::SetArgPointee;
+using ::testing::StrEq;
+using ::testing::StrictMock;
+
+namespace gpu {
+namespace gles2 {
+
+using namespace cmds;
+
+class GLES2DecoderGeometryInstancingTest : public GLES2DecoderWithShaderTest {
+ public:
+  GLES2DecoderGeometryInstancingTest() : GLES2DecoderWithShaderTest() {}
+
+  virtual void SetUp() {
+    InitState init;
+    init.extensions = "GL_ANGLE_instanced_arrays";
+    init.gl_version = "opengl es 2.0";
+    init.has_alpha = true;
+    init.has_depth = true;
+    init.request_alpha = true;
+    init.request_depth = true;
+    init.bind_generates_resource = true;
+    InitDecoder(init);
+    SetupDefaultProgram();
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(Service,
+                        GLES2DecoderGeometryInstancingTest,
+                        ::testing::Bool());
+
+void GLES2DecoderManualInitTest::DirtyStateMaskTest(GLuint color_bits,
+                                                    bool depth_mask,
+                                                    GLuint front_stencil_mask,
+                                                    GLuint back_stencil_mask) {
+  ColorMask color_mask_cmd;
+  color_mask_cmd.Init((color_bits & 0x1000) != 0,
+                      (color_bits & 0x0100) != 0,
+                      (color_bits & 0x0010) != 0,
+                      (color_bits & 0x0001) != 0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(color_mask_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  DepthMask depth_mask_cmd;
+  depth_mask_cmd.Init(depth_mask);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(depth_mask_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  StencilMaskSeparate front_stencil_mask_cmd;
+  front_stencil_mask_cmd.Init(GL_FRONT, front_stencil_mask);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(front_stencil_mask_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  StencilMaskSeparate back_stencil_mask_cmd;
+  back_stencil_mask_cmd.Init(GL_BACK, back_stencil_mask);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(back_stencil_mask_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  SetupExpectationsForApplyingDirtyState(
+      false,               // Framebuffer is RGB
+      true,                // Framebuffer has depth
+      true,                // Framebuffer has stencil
+      color_bits,          // color bits
+      depth_mask,          // depth mask
+      false,               // depth enabled
+      front_stencil_mask,  // front stencil mask
+      back_stencil_mask,   // back stencil mask
+      false);              // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays draw_cmd;
+  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+// Test that with an RGB backbuffer if we set the color mask to 1,1,1,1 it is
+// set to 1,1,1,0 at Draw time but is 1,1,1,1 at query time.
+TEST_P(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMask) {
+  ColorMask cmd;
+  cmd.Init(true, true, true, true);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDirtyState(true,    // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1110,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays draw_cmd;
+  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_COLOR_WRITEMASK, result->GetData()))
+      .Times(0);
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_COLOR_WRITEMASK, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(
+      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_COLOR_WRITEMASK),
+      result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(1, result->GetData()[0]);
+  EXPECT_EQ(1, result->GetData()[1]);
+  EXPECT_EQ(1, result->GetData()[2]);
+  EXPECT_EQ(1, result->GetData()[3]);
+}
+
+// Test that with no depth if we set DepthMask true that it's set to false at
+// draw time but querying it returns true.
+TEST_P(GLES2DecoderRGBBackbufferTest, RGBBackbufferDepthMask) {
+  EXPECT_CALL(*gl_, DepthMask(true)).Times(0).RetiresOnSaturation();
+  DepthMask cmd;
+  cmd.Init(true);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDirtyState(true,    // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1110,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays draw_cmd;
+  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_WRITEMASK, result->GetData()))
+      .Times(0);
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_DEPTH_WRITEMASK, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(
+      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_WRITEMASK),
+      result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(1, result->GetData()[0]);
+}
+
+// Test that with no stencil if we set the stencil mask it's still set to 0 at
+// draw time but gets our value if we query.
+TEST_P(GLES2DecoderRGBBackbufferTest, RGBBackbufferStencilMask) {
+  const GLint kMask = 123;
+  EXPECT_CALL(*gl_, StencilMask(kMask)).Times(0).RetiresOnSaturation();
+  StencilMask cmd;
+  cmd.Init(kMask);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDirtyState(true,    // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1110,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays draw_cmd;
+  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_WRITEMASK, result->GetData()))
+      .Times(0);
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_STENCIL_WRITEMASK, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(
+      decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_WRITEMASK),
+      result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(kMask, result->GetData()[0]);
+}
+
+// Test that if an FBO is bound we get the correct masks.
+TEST_P(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMaskFBO) {
+  ColorMask cmd;
+  cmd.Init(true, true, true, true);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  SetupTexture();
+  SetupVertexBuffer();
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
+  DoEnableVertexAttribArray(1);
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+  DoEnableVertexAttribArray(2);
+  DoVertexAttribPointer(2, 2, GL_FLOAT, 0, 0);
+  SetupExpectationsForApplyingDirtyState(true,    // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1110,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays draw_cmd;
+  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Check that no extra calls are made on the next draw.
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Setup Frame buffer.
+  // needs to be 1x1 or else it's not renderable.
+  const GLsizei kWidth = 1;
+  const GLsizei kHeight = 1;
+  const GLenum kFormat = GL_RGB;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  // Pass some data so the texture will be marked as cleared.
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               kFormat,
+               kWidth,
+               kHeight,
+               0,
+               kFormat,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         client_texture_id_,
+                         kServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
+      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+      .RetiresOnSaturation();
+
+  // This time state needs to be set.
+  SetupExpectationsForApplyingDirtyState(false,   // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1110,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Check that no extra calls are made on the next draw.
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Unbind
+  DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
+
+  SetupExpectationsForApplyingDirtyState(true,    // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1110,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, DepthEnableWithDepth) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_depth = true;
+  init.request_depth = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  Enable cmd;
+  cmd.Init(GL_DEPTH_TEST);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  SetupDefaultProgram();
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDirtyState(true,    // Framebuffer is RGB
+                                         true,    // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1110,  // color bits
+                                         true,    // depth mask
+                                         true,    // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays draw_cmd;
+  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_TEST, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_DEPTH_TEST, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_TEST),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(1, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, DepthEnableWithoutRequestedDepth) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_depth = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  Enable cmd;
+  cmd.Init(GL_DEPTH_TEST);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  SetupDefaultProgram();
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDirtyState(true,    // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1110,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays draw_cmd;
+  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_TEST, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_DEPTH_TEST, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_TEST),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(1, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, StencilEnableWithStencil) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_stencil = true;
+  init.request_stencil = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  Enable cmd;
+  cmd.Init(GL_STENCIL_TEST);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  SetupDefaultProgram();
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDirtyState(true,    // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         true,    // Framebuffer has stencil
+                                         0x1110,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         -1,      // front stencil mask
+                                         -1,      // back stencil mask
+                                         true);   // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays draw_cmd;
+  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_TEST, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_STENCIL_TEST, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_TEST),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(1, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, StencilEnableWithoutRequestedStencil) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_stencil = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  Enable cmd;
+  cmd.Init(GL_STENCIL_TEST);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  SetupDefaultProgram();
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDirtyState(true,    // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1110,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays draw_cmd;
+  draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_TEST, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_STENCIL_TEST, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_TEST),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(1, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, CachedColorMask) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_alpha = true;
+  init.has_depth = true;
+  init.has_stencil = true;
+  init.request_alpha = true;
+  init.request_depth = true;
+  init.request_stencil = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  SetupDefaultProgram();
+  SetupAllNeededVertexBuffers();
+  SetupTexture();
+
+  // Test all color_bits combinations twice.
+  for (int i = 0; i < 32; i++) {
+    GLuint color_bits = (i & 1 ? 0x0001 : 0x0000) | (i & 2 ? 0x0010 : 0x0000) |
+                        (i & 4 ? 0x0100 : 0x0000) | (i & 8 ? 0x1000 : 0x0000);
+
+    // Toggle depth_test to force ApplyDirtyState each time.
+    DirtyStateMaskTest(color_bits, false, 0xffffffff, 0xffffffff);
+    DirtyStateMaskTest(color_bits, true, 0xffffffff, 0xffffffff);
+    DirtyStateMaskTest(color_bits, false, 0xffffffff, 0xffffffff);
+  }
+}
+
+TEST_P(GLES2DecoderManualInitTest, CachedDepthMask) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_alpha = true;
+  init.has_depth = true;
+  init.has_stencil = true;
+  init.request_alpha = true;
+  init.request_depth = true;
+  init.request_stencil = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  SetupDefaultProgram();
+  SetupAllNeededVertexBuffers();
+  SetupTexture();
+
+  // Test all depth_mask combinations twice.
+  for (int i = 0; i < 4; i++) {
+    bool depth_mask = (i & 1) == 1;
+
+    // Toggle color masks to force ApplyDirtyState each time.
+    DirtyStateMaskTest(0x1010, depth_mask, 0xffffffff, 0xffffffff);
+    DirtyStateMaskTest(0x0101, depth_mask, 0xffffffff, 0xffffffff);
+    DirtyStateMaskTest(0x1010, depth_mask, 0xffffffff, 0xffffffff);
+  }
+}
+
+TEST_P(GLES2DecoderManualInitTest, CachedStencilMask) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_alpha = true;
+  init.has_depth = true;
+  init.has_stencil = true;
+  init.request_alpha = true;
+  init.request_depth = true;
+  init.request_stencil = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  SetupDefaultProgram();
+  SetupAllNeededVertexBuffers();
+  SetupTexture();
+
+  // Test all stencil_mask combinations twice.
+  for (int i = 0; i < 4; i++) {
+    GLuint stencil_mask = (i & 1) ? 0xf0f0f0f0 : 0x0f0f0f0f;
+
+    // Toggle color masks to force ApplyDirtyState each time.
+    DirtyStateMaskTest(0x1010, true, stencil_mask, 0xffffffff);
+    DirtyStateMaskTest(0x0101, true, stencil_mask, 0xffffffff);
+    DirtyStateMaskTest(0x1010, true, stencil_mask, 0xffffffff);
+  }
+
+  for (int i = 0; i < 4; i++) {
+    GLuint stencil_mask = (i & 1) ? 0xf0f0f0f0 : 0x0f0f0f0f;
+
+    // Toggle color masks to force ApplyDirtyState each time.
+    DirtyStateMaskTest(0x1010, true, 0xffffffff, stencil_mask);
+    DirtyStateMaskTest(0x0101, true, 0xffffffff, stencil_mask);
+    DirtyStateMaskTest(0x1010, true, 0xffffffff, stencil_mask);
+  }
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysNoAttributesSucceeds) {
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDefaultDirtyState();
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+// Tests when the math overflows (0x40000000 * sizeof GLfloat)
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysSimulatedAttrib0OverflowFails) {
+  const GLsizei kLargeCount = 0x40000000;
+  SetupTexture();
+  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0).RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kLargeCount);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+  EXPECT_FALSE(GetDecoder()->WasContextLost());
+}
+
+// Tests when the math overflows (0x7FFFFFFF + 1 = 0x8000000 verts)
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysSimulatedAttrib0PosToNegFails) {
+  const GLsizei kLargeCount = 0x7FFFFFFF;
+  SetupTexture();
+  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0).RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kLargeCount);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+  EXPECT_FALSE(GetDecoder()->WasContextLost());
+}
+
+// Tests when the driver returns an error
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysSimulatedAttrib0OOMFails) {
+  const GLsizei kFakeLargeCount = 0x1234;
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0WithError(
+      kFakeLargeCount, 0, GL_OUT_OF_MEMORY);
+  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0).RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kFakeLargeCount);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+  EXPECT_FALSE(GetDecoder()->WasContextLost());
+}
+
+// Test that we lose context.
+TEST_P(GLES2DecoderManualInitTest, LoseContextWhenOOM) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_alpha = true;
+  init.has_depth = true;
+  init.request_alpha = true;
+  init.request_depth = true;
+  init.bind_generates_resource = true;
+  init.lose_context_when_out_of_memory = true;
+  InitDecoder(init);
+  SetupDefaultProgram();
+
+  const GLsizei kFakeLargeCount = 0x1234;
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0WithError(
+      kFakeLargeCount, 0, GL_OUT_OF_MEMORY);
+  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0).RetiresOnSaturation();
+  // Other contexts in the group should be lost also.
+  EXPECT_CALL(*mock_decoder_, LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kFakeLargeCount);
+  // This context should be lost.
+  EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+  EXPECT_TRUE(decoder_->WasContextLost());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysBadTextureUsesBlack) {
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  // This is an NPOT texture. As the default filtering requires mips
+  // this should trigger replacing with black textures before rendering.
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGBA,
+               3,
+               1,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  {
+    InSequence sequence;
+    EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
+        .Times(1)
+        .RetiresOnSaturation();
+    EXPECT_CALL(
+        *gl_, BindTexture(GL_TEXTURE_2D, TestHelper::kServiceBlackTexture2dId))
+        .Times(1)
+        .RetiresOnSaturation();
+    EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+        .Times(1)
+        .RetiresOnSaturation();
+    EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
+        .Times(1)
+        .RetiresOnSaturation();
+    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
+        .Times(1)
+        .RetiresOnSaturation();
+    EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
+        .Times(1)
+        .RetiresOnSaturation();
+  }
+  SetupExpectationsForApplyingDefaultDirtyState();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysMissingAttributesFails) {
+  DoEnableVertexAttribArray(1);
+
+  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0);
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest,
+       DrawArraysMissingAttributesZeroCountSucceeds) {
+  DoEnableVertexAttribArray(1);
+
+  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0);
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, 0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysValidAttributesSucceeds) {
+  SetupTexture();
+  SetupVertexBuffer();
+  DoEnableVertexAttribArray(1);
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+  AddExpectationsForSimulatedAttrib0(kNumVertices, kServiceBufferId);
+  SetupExpectationsForApplyingDefaultDirtyState();
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+// Same as DrawArraysValidAttributesSucceeds, but with workaround
+// |init_vertex_attributes|.
+TEST_P(GLES2DecoderManualInitTest, InitVertexAttributes) {
+  CommandLine command_line(0, NULL);
+  command_line.AppendSwitchASCII(
+      switches::kGpuDriverBugWorkarounds,
+      base::IntToString(gpu::INIT_VERTEX_ATTRIBUTES));
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_alpha = true;
+  init.has_depth = true;
+  init.request_alpha = true;
+  init.request_depth = true;
+  init.bind_generates_resource = true;
+  InitDecoderWithCommandLine(init, &command_line);
+  SetupDefaultProgram();
+  SetupTexture();
+  SetupVertexBuffer();
+  DoEnableVertexAttribArray(1);
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+  AddExpectationsForSimulatedAttrib0(kNumVertices, kServiceBufferId);
+  SetupExpectationsForApplyingDefaultDirtyState();
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysDeletedBufferFails) {
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+  DeleteVertexBuffer();
+
+  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0);
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysDeletedProgramSucceeds) {
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDefaultDirtyState();
+  DoDeleteProgram(client_program_id_, kServiceProgramId);
+
+  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId)).Times(1);
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysWithInvalidModeFails) {
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0);
+  DrawArrays cmd;
+  cmd.Init(GL_QUADS, 0, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  cmd.Init(GL_POLYGON, 0, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysInvalidCountFails) {
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  // Try start > 0
+  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0);
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 1, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Try with count > size
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices + 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Try with attrib offset > 0
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 4);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Try with size > 2 (ie, vec3 instead of vec2)
+  DoVertexAttribPointer(1, 3, GL_FLOAT, 0, 0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Try with stride > 8 (vec2 + vec2 byte)
+  DoVertexAttribPointer(1, 2, GL_FLOAT, sizeof(GLfloat) * 3, 0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysInstancedANGLEFails) {
+  SetupTexture();
+  SetupVertexBuffer();
+  DoEnableVertexAttribArray(1);
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawArraysInstancedANGLENoAttributesFails) {
+  SetupTexture();
+
+  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawArraysInstancedANGLESimulatedAttrib0) {
+  SetupTexture();
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  AddExpectationsForSimulatedAttrib0(kNumVertices, kServiceBufferId);
+  SetupExpectationsForApplyingDefaultDirtyState();
+
+  DoVertexAttribDivisorANGLE(0, 1);
+  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices, 3))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 0))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 1))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 3);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawArraysInstancedANGLEMissingAttributesFails) {
+  DoEnableVertexAttribArray(1);
+
+  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _)).Times(0);
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawArraysInstancedANGLEMissingAttributesZeroCountSucceeds) {
+  DoEnableVertexAttribArray(1);
+
+  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _)).Times(0);
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, 0, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawArraysInstancedANGLEValidAttributesSucceeds) {
+  SetupTexture();
+  SetupVertexBuffer();
+  DoEnableVertexAttribArray(1);
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+  AddExpectationsForSimulatedAttrib0(kNumVertices, kServiceBufferId);
+  SetupExpectationsForApplyingDefaultDirtyState();
+
+  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices, 1))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawArraysInstancedANGLEWithInvalidModeFails) {
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _)).Times(0);
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_QUADS, 0, 1, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  cmd.Init(GL_POLYGON, 0, 1, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawArraysInstancedANGLEInvalidPrimcountFails) {
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _)).Times(0);
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, 1, -1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+// Per-instance data is twice as large, but number of instances is half
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawArraysInstancedANGLELargeInstanceSucceeds) {
+  SetupTexture();
+  SetupVertexBuffer();
+  SetupExpectationsForApplyingDefaultDirtyState();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
+  DoVertexAttribDivisorANGLE(0, 1);
+  EXPECT_CALL(
+      *gl_,
+      DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices, kNumVertices / 2))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices, kNumVertices / 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+// Per-instance data is twice as large, but divisor is twice
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawArraysInstancedANGLELargeDivisorSucceeds) {
+  SetupTexture();
+  SetupVertexBuffer();
+  SetupExpectationsForApplyingDefaultDirtyState();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
+  DoVertexAttribDivisorANGLE(0, 2);
+  EXPECT_CALL(
+      *gl_,
+      DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest, DrawArraysInstancedANGLELargeFails) {
+  SetupTexture();
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
+  DoVertexAttribDivisorANGLE(0, 1);
+  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices, kNumVertices + 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices + 1, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+// Per-index data is twice as large, but number of indices is half
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawArraysInstancedANGLELargeIndexSucceeds) {
+  SetupTexture();
+  SetupVertexBuffer();
+  SetupExpectationsForApplyingDefaultDirtyState();
+  DoVertexAttribPointer(1, 4, GL_FLOAT, 0, 0);
+
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
+  DoVertexAttribDivisorANGLE(0, 1);
+  EXPECT_CALL(
+      *gl_,
+      DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices / 2, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices / 2, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawArraysInstancedANGLENoDivisor0Fails) {
+  SetupTexture();
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
+  DoVertexAttribDivisorANGLE(0, 1);
+  DoVertexAttribDivisorANGLE(1, 1);
+  EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  DrawArraysInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsNoAttributesSucceeds) {
+  SetupTexture();
+  SetupIndexBuffer();
+  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, 0);
+  SetupExpectationsForApplyingDefaultDirtyState();
+  EXPECT_CALL(*gl_,
+              DrawElements(GL_TRIANGLES,
+                           kValidIndexRangeCount,
+                           GL_UNSIGNED_SHORT,
+                           BufferOffset(kValidIndexRangeStart * 2)))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsMissingAttributesFails) {
+  SetupIndexBuffer();
+  DoEnableVertexAttribArray(1);
+
+  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest,
+       DrawElementsMissingAttributesZeroCountSucceeds) {
+  SetupIndexBuffer();
+  DoEnableVertexAttribArray(1);
+
+  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT, kValidIndexRangeStart * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsExtraAttributesFails) {
+  SetupIndexBuffer();
+  DoEnableVertexAttribArray(6);
+
+  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsValidAttributesSucceeds) {
+  SetupTexture();
+  SetupVertexBuffer();
+  SetupIndexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, kServiceBufferId);
+  SetupExpectationsForApplyingDefaultDirtyState();
+
+  EXPECT_CALL(*gl_,
+              DrawElements(GL_TRIANGLES,
+                           kValidIndexRangeCount,
+                           GL_UNSIGNED_SHORT,
+                           BufferOffset(kValidIndexRangeStart * 2)))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsDeletedBufferFails) {
+  SetupVertexBuffer();
+  SetupIndexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+  DeleteIndexBuffer();
+
+  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsDeletedProgramSucceeds) {
+  SetupTexture();
+  SetupIndexBuffer();
+  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, 0);
+  SetupExpectationsForApplyingDefaultDirtyState();
+  DoDeleteProgram(client_program_id_, kServiceProgramId);
+
+  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(1);
+  EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId)).Times(1);
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsWithInvalidModeFails) {
+  SetupVertexBuffer();
+  SetupIndexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
+  DrawElements cmd;
+  cmd.Init(GL_QUADS,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  cmd.Init(GL_POLYGON,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsInvalidCountFails) {
+  SetupVertexBuffer();
+  SetupIndexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  // Try start > 0
+  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES, kNumIndices, GL_UNSIGNED_SHORT, 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Try with count > size
+  cmd.Init(GL_TRIANGLES, kNumIndices + 1, GL_UNSIGNED_SHORT, 0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsOutOfRangeIndicesFails) {
+  SetupVertexBuffer();
+  SetupIndexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES,
+           kInvalidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kInvalidIndexRangeStart * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsOddOffsetForUint16Fails) {
+  SetupVertexBuffer();
+  SetupIndexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES, kInvalidIndexRangeCount, GL_UNSIGNED_SHORT, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsInstancedANGLEFails) {
+  SetupTexture();
+  SetupVertexBuffer();
+  SetupIndexBuffer();
+  DoEnableVertexAttribArray(1);
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLENoAttributesFails) {
+  SetupTexture();
+  SetupIndexBuffer();
+
+  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLESimulatedAttrib0) {
+  SetupTexture();
+  SetupVertexBuffer();
+  SetupIndexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, kServiceBufferId);
+  SetupExpectationsForApplyingDefaultDirtyState();
+
+  DoVertexAttribDivisorANGLE(0, 1);
+  EXPECT_CALL(
+      *gl_,
+      DrawElementsInstancedANGLE(GL_TRIANGLES,
+                                 kValidIndexRangeCount,
+                                 GL_UNSIGNED_SHORT,
+                                 BufferOffset(kValidIndexRangeStart * 2),
+                                 3))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 0))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 1))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           3);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLEMissingAttributesFails) {
+  SetupIndexBuffer();
+  DoEnableVertexAttribArray(1);
+
+  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _)).Times(0);
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLEMissingAttributesZeroCountSucceeds) {
+  SetupIndexBuffer();
+  DoEnableVertexAttribArray(1);
+
+  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _)).Times(0);
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT, kValidIndexRangeStart * 2, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLEValidAttributesSucceeds) {
+  SetupIndexBuffer();
+  SetupTexture();
+  SetupVertexBuffer();
+  DoEnableVertexAttribArray(1);
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, kServiceBufferId);
+  SetupExpectationsForApplyingDefaultDirtyState();
+
+  EXPECT_CALL(
+      *gl_,
+      DrawElementsInstancedANGLE(GL_TRIANGLES,
+                                 kValidIndexRangeCount,
+                                 GL_UNSIGNED_SHORT,
+                                 BufferOffset(kValidIndexRangeStart * 2),
+                                 1))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLEWithInvalidModeFails) {
+  SetupIndexBuffer();
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _)).Times(0);
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_QUADS,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  cmd.Init(GL_INVALID_ENUM,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
+// Per-instance data is twice as large, but number of instances is half
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLELargeInstanceSucceeds) {
+  SetupTexture();
+  SetupIndexBuffer();
+  SetupVertexBuffer();
+  SetupExpectationsForApplyingDefaultDirtyState();
+  // Add offset so we're sure we're accessing data near the end of the buffer.
+  DoVertexAttribPointer(
+      1,
+      2,
+      GL_FLOAT,
+      0,
+      (kNumVertices - kMaxValidIndex - 1) * 2 * sizeof(GLfloat));
+
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
+  DoVertexAttribDivisorANGLE(0, 1);
+  EXPECT_CALL(
+      *gl_,
+      DrawElementsInstancedANGLE(GL_TRIANGLES,
+                                 kValidIndexRangeCount,
+                                 GL_UNSIGNED_SHORT,
+                                 BufferOffset(kValidIndexRangeStart * 2),
+                                 kNumVertices / 2))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           kNumVertices / 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+// Per-instance data is twice as large, but divisor is twice
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLELargeDivisorSucceeds) {
+  SetupTexture();
+  SetupIndexBuffer();
+  SetupVertexBuffer();
+  SetupExpectationsForApplyingDefaultDirtyState();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
+  DoVertexAttribDivisorANGLE(0, 2);
+  EXPECT_CALL(
+      *gl_,
+      DrawElementsInstancedANGLE(GL_TRIANGLES,
+                                 kValidIndexRangeCount,
+                                 GL_UNSIGNED_SHORT,
+                                 BufferOffset(kValidIndexRangeStart * 2),
+                                 kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLELargeFails) {
+  SetupTexture();
+  SetupIndexBuffer();
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
+  DoVertexAttribDivisorANGLE(0, 1);
+  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           kNumVertices + 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  cmd.Init(GL_TRIANGLES,
+           kInvalidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kInvalidIndexRangeStart * 2,
+           kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLEInvalidPrimcountFails) {
+  SetupTexture();
+  SetupIndexBuffer();
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
+  DoVertexAttribDivisorANGLE(0, 1);
+  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           -1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+// Per-index data is twice as large, but values of indices are smaller
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLELargeIndexSucceeds) {
+  SetupTexture();
+  SetupIndexBuffer();
+  SetupVertexBuffer();
+  SetupExpectationsForApplyingDefaultDirtyState();
+  DoVertexAttribPointer(1, 4, GL_FLOAT, 0, 0);
+
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
+  DoVertexAttribDivisorANGLE(0, 1);
+  EXPECT_CALL(
+      *gl_,
+      DrawElementsInstancedANGLE(GL_TRIANGLES,
+                                 kValidIndexRangeCount,
+                                 GL_UNSIGNED_SHORT,
+                                 BufferOffset(kValidIndexRangeStart * 2),
+                                 kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderGeometryInstancingTest,
+       DrawElementsInstancedANGLENoDivisor0Fails) {
+  SetupTexture();
+  SetupIndexBuffer();
+  SetupVertexBuffer();
+  DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
+
+  DoEnableVertexAttribArray(0);
+  DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
+  DoVertexAttribDivisorANGLE(0, 1);
+  DoVertexAttribDivisorANGLE(1, 1);
+  EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  DrawElementsInstancedANGLE cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2,
+           kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawArraysClearsAfterTexImage2DNULL) {
+  SetupAllNeededVertexBuffers();
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  // Create an uncleared texture with 2 levels.
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  // Expect 2 levels will be cleared.
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_2D,
+                                GL_TEXTURE_2D,
+                                0,
+                                GL_RGBA,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                2,
+                                2);
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_2D,
+                                GL_TEXTURE_2D,
+                                1,
+                                GL_RGBA,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                1,
+                                1);
+  SetupExpectationsForApplyingDefaultDirtyState();
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // But not again
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawElementsClearsAfterTexImage2DNULL) {
+  SetupAllNeededVertexBuffers();
+  SetupIndexBuffer();
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  // Create an uncleared texture with 2 levels.
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  // Expect 2 levels will be cleared.
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_2D,
+                                GL_TEXTURE_2D,
+                                0,
+                                GL_RGBA,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                2,
+                                2);
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_2D,
+                                GL_TEXTURE_2D,
+                                1,
+                                GL_RGBA,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                1,
+                                1);
+  SetupExpectationsForApplyingDefaultDirtyState();
+
+  EXPECT_CALL(*gl_,
+              DrawElements(GL_TRIANGLES,
+                           kValidIndexRangeCount,
+                           GL_UNSIGNED_SHORT,
+                           BufferOffset(kValidIndexRangeStart * 2)))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // But not again
+  EXPECT_CALL(*gl_,
+              DrawElements(GL_TRIANGLES,
+                           kValidIndexRangeCount,
+                           GL_UNSIGNED_SHORT,
+                           BufferOffset(kValidIndexRangeStart * 2)))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawClearsAfterTexImage2DNULLInFBO) {
+  const GLuint kFBOClientTextureId = 4100;
+  const GLuint kFBOServiceTextureId = 4101;
+
+  SetupAllNeededVertexBuffers();
+  // Register a texture id.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
+      .RetiresOnSaturation();
+  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
+
+  // Setup "render to" texture.
+  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         kFBOClientTextureId,
+                         kFBOServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+
+  // Setup "render from" texture.
+  SetupTexture();
+
+  SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER,       // target
+                                          GL_COLOR_BUFFER_BIT,  // clear bits
+                                          0,
+                                          0,
+                                          0,
+                                          0,       // color
+                                          0,       // stencil
+                                          1.0f,    // depth
+                                          false);  // scissor test
+
+  SetupExpectationsForApplyingDirtyState(false,   // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1111,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // But not again.
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawWitFBOThatCantClearDoesNotDraw) {
+  const GLuint kFBOClientTextureId = 4100;
+  const GLuint kFBOServiceTextureId = 4101;
+
+  // Register a texture id.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
+      .RetiresOnSaturation();
+  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
+
+  // Setup "render to" texture.
+  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         kFBOClientTextureId,
+                         kFBOServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+
+  // Setup "render from" texture.
+  SetupTexture();
+
+  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
+      .WillOnce(Return(GL_FRAMEBUFFER_UNSUPPORTED))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0).RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_FRAMEBUFFER_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, DrawClearsAfterRenderbufferStorageInFBO) {
+  SetupTexture();
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoRenderbufferStorage(
+      GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 100, 50, GL_NO_ERROR);
+  DoFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                            GL_COLOR_ATTACHMENT0,
+                            GL_RENDERBUFFER,
+                            client_renderbuffer_id_,
+                            kServiceRenderbufferId,
+                            GL_NO_ERROR);
+
+  SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER,       // target
+                                          GL_COLOR_BUFFER_BIT,  // clear bits
+                                          0,
+                                          0,
+                                          0,
+                                          0,       // color
+                                          0,       // stencil
+                                          1.0f,    // depth
+                                          false);  // scissor test
+
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDirtyState(false,   // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1111,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, DrawArraysClearsAfterTexImage2DNULLCubemap) {
+  InitState init;
+  init.gl_version = "opengl es 2.0";
+  init.has_alpha = true;
+  init.has_depth = true;
+  init.request_alpha = true;
+  init.request_depth = true;
+  InitDecoder(init);
+
+  static const GLenum faces[] = {
+      GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+      GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+      GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
+  };
+  SetupCubemapProgram();
+  DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId);
+  // Fill out all the faces for 2 levels, leave 2 uncleared.
+  for (int ii = 0; ii < 6; ++ii) {
+    GLenum face = faces[ii];
+    int32 shm_id =
+        (face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ? 0 : kSharedMemoryId;
+    uint32 shm_offset =
+        (face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ? 0 : kSharedMemoryOffset;
+    DoTexImage2D(face,
+                 0,
+                 GL_RGBA,
+                 2,
+                 2,
+                 0,
+                 GL_RGBA,
+                 GL_UNSIGNED_BYTE,
+                 shm_id,
+                 shm_offset);
+    DoTexImage2D(face,
+                 1,
+                 GL_RGBA,
+                 1,
+                 1,
+                 0,
+                 GL_RGBA,
+                 GL_UNSIGNED_BYTE,
+                 shm_id,
+                 shm_offset);
+  }
+  // Expect 2 levels will be cleared.
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_CUBE_MAP,
+                                GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+                                0,
+                                GL_RGBA,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                2,
+                                2);
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_CUBE_MAP,
+                                GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+                                1,
+                                GL_RGBA,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                1,
+                                1);
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDefaultDirtyState();
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest,
+       DrawClearsAfterRenderbuffersWithMultipleAttachments) {
+  const GLuint kFBOClientTextureId = 4100;
+  const GLuint kFBOServiceTextureId = 4101;
+
+  // Register a texture id.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
+      .RetiresOnSaturation();
+  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
+
+  // Setup "render to" texture.
+  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         kFBOClientTextureId,
+                         kFBOServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoRenderbufferStorage(GL_RENDERBUFFER,
+                        GL_DEPTH_COMPONENT16,
+                        GL_DEPTH_COMPONENT,
+                        1,
+                        1,
+                        GL_NO_ERROR);
+  DoFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                            GL_DEPTH_ATTACHMENT,
+                            GL_RENDERBUFFER,
+                            client_renderbuffer_id_,
+                            kServiceRenderbufferId,
+                            GL_NO_ERROR);
+
+  SetupTexture();
+  SetupExpectationsForFramebufferClearing(
+      GL_FRAMEBUFFER,                             // target
+      GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,  // clear bits
+      0,
+      0,
+      0,
+      0,       // color
+      0,       // stencil
+      1.0f,    // depth
+      false);  // scissor test
+
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDirtyState(false,   // Framebuffer is RGB
+                                         true,    // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1111,  // color bits
+                                         true,    // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest,
+       DrawingWithFBOTwiceChecksForFBOCompleteOnce) {
+  const GLuint kFBOClientTextureId = 4100;
+  const GLuint kFBOServiceTextureId = 4101;
+
+  SetupAllNeededVertexBuffers();
+
+  // Register a texture id.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
+      .RetiresOnSaturation();
+  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
+
+  // Setup "render to" texture that is cleared.
+  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGBA,
+               1,
+               1,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         kFBOClientTextureId,
+                         kFBOServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+
+  // Setup "render from" texture.
+  SetupTexture();
+
+  // Make sure we check for framebuffer complete.
+  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
+      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+      .RetiresOnSaturation();
+
+  SetupExpectationsForApplyingDirtyState(false,   // Framebuffer is RGB
+                                         false,   // Framebuffer has depth
+                                         false,   // Framebuffer has stencil
+                                         0x1111,  // color bits
+                                         false,   // depth mask
+                                         false,   // depth enabled
+                                         0,       // front stencil mask
+                                         0,       // back stencil mask
+                                         false);  // stencil enabled
+
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // But not again.
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, DrawClearsDepthTexture) {
+  InitState init;
+  init.extensions = "GL_ANGLE_depth_texture";
+  init.gl_version = "opengl es 2.0";
+  init.has_alpha = true;
+  init.has_depth = true;
+  init.request_alpha = true;
+  init.request_depth = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  SetupDefaultProgram();
+  SetupAllNeededVertexBuffers();
+  const GLenum attachment = GL_DEPTH_ATTACHMENT;
+  const GLenum target = GL_TEXTURE_2D;
+  const GLint level = 0;
+  DoBindTexture(target, client_texture_id_, kServiceTextureId);
+
+  // Create a depth texture.
+  DoTexImage2D(target,
+               level,
+               GL_DEPTH_COMPONENT,
+               1,
+               1,
+               0,
+               GL_DEPTH_COMPONENT,
+               GL_UNSIGNED_INT,
+               0,
+               0);
+
+  // Enable GL_SCISSOR_TEST to make sure we disable it in the clear,
+  // then re-enable it.
+  DoEnableDisable(GL_SCISSOR_TEST, true);
+
+  EXPECT_CALL(*gl_, GenFramebuffersEXT(1, _)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, _))
+      .Times(1)
+      .RetiresOnSaturation();
+
+  EXPECT_CALL(*gl_,
+              FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT,
+                                      attachment,
+                                      target,
+                                      kServiceTextureId,
+                                      level))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT))
+      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+      .RetiresOnSaturation();
+
+  EXPECT_CALL(*gl_, ClearStencil(0)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, StencilMask(-1)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, ClearDepth(1.0f)).Times(1).RetiresOnSaturation();
+  SetupExpectationsForDepthMask(true);
+  SetupExpectationsForEnableDisable(GL_SCISSOR_TEST, false);
+
+  EXPECT_CALL(*gl_, Clear(GL_DEPTH_BUFFER_BIT)).Times(1).RetiresOnSaturation();
+
+  SetupExpectationsForRestoreClearState(0.0f, 0.0f, 0.0f, 0.0f, 0, 1.0f, true);
+
+  EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, _)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0))
+      .Times(1)
+      .RetiresOnSaturation();
+
+  SetupExpectationsForApplyingDefaultDirtyState();
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+}  // namespace gles2
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
new file mode 100644
index 0000000..edffc8f
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
@@ -0,0 +1,2335 @@
+// 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.
+
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "gpu/command_buffer/common/gles2_cmd_format.h"
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/common/id_allocator.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
+#include "gpu/command_buffer/service/cmd_buffer_engine.h"
+#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/context_state.h"
+#include "gpu/command_buffer/service/gl_surface_mock.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
+
+#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/image_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/mocks.h"
+#include "gpu/command_buffer/service/program_manager.h"
+#include "gpu/command_buffer/service/test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_mock.h"
+#include "ui/gl/gl_surface_stub.h"
+
+#if !defined(GL_DEPTH24_STENCIL8)
+#define GL_DEPTH24_STENCIL8 0x88F0
+#endif
+
+using ::gfx::MockGLInterface;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::MatcherCast;
+using ::testing::Mock;
+using ::testing::Pointee;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::SetArrayArgument;
+using ::testing::SetArgumentPointee;
+using ::testing::SetArgPointee;
+using ::testing::StrEq;
+using ::testing::StrictMock;
+
+namespace gpu {
+namespace gles2 {
+
+using namespace cmds;
+
+class GLES2DecoderTestWithExtensionsOnGLES2 : public GLES2DecoderTest {
+ public:
+  GLES2DecoderTestWithExtensionsOnGLES2() {}
+
+  virtual void SetUp() {}
+  void Init(const char* extensions) {
+    InitState init;
+    init.extensions = extensions;
+    init.gl_version = "opengl es 2.0";
+    init.has_alpha = true;
+    init.has_depth = true;
+    init.request_alpha = true;
+    init.request_depth = true;
+    InitDecoder(init);
+  }
+};
+
+TEST_P(GLES2DecoderTest, CheckFramebufferStatusWithNoBoundTarget) {
+  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(_)).Times(0);
+  CheckFramebufferStatus::Result* result =
+      static_cast<CheckFramebufferStatus::Result*>(shared_memory_address_);
+  *result = 0;
+  CheckFramebufferStatus cmd;
+  cmd.Init(GL_FRAMEBUFFER, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), *result);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, BindAndDeleteFramebuffer) {
+  SetupTexture();
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDefaultDirtyState();
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoDeleteFramebuffer(client_framebuffer_id_,
+                      kServiceFramebufferId,
+                      true,
+                      GL_FRAMEBUFFER,
+                      0,
+                      true,
+                      GL_FRAMEBUFFER,
+                      0);
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, FramebufferRenderbufferWithNoBoundTarget) {
+  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(_, _, _, _)).Times(0);
+  FramebufferRenderbuffer cmd;
+  cmd.Init(GL_FRAMEBUFFER,
+           GL_COLOR_ATTACHMENT0,
+           GL_RENDERBUFFER,
+           client_renderbuffer_id_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, FramebufferTexture2DWithNoBoundTarget) {
+  EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
+  FramebufferTexture2D cmd;
+  cmd.Init(GL_FRAMEBUFFER,
+           GL_COLOR_ATTACHMENT0,
+           GL_TEXTURE_2D,
+           client_texture_id_,
+           0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithNoBoundTarget) {
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _))
+      .Times(0);
+  GetFramebufferAttachmentParameteriv cmd;
+  cmd.Init(GL_FRAMEBUFFER,
+           GL_COLOR_ATTACHMENT0,
+           GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithRenderbuffer) {
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+                                         GL_COLOR_ATTACHMENT0,
+                                         GL_RENDERBUFFER,
+                                         kServiceRenderbufferId))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  GetFramebufferAttachmentParameteriv::Result* result =
+      static_cast<GetFramebufferAttachmentParameteriv::Result*>(
+          shared_memory_address_);
+  result->size = 0;
+  const GLint* result_value = result->GetData();
+  FramebufferRenderbuffer fbrb_cmd;
+  GetFramebufferAttachmentParameteriv cmd;
+  fbrb_cmd.Init(GL_FRAMEBUFFER,
+                GL_COLOR_ATTACHMENT0,
+                GL_RENDERBUFFER,
+                client_renderbuffer_id_);
+  cmd.Init(GL_FRAMEBUFFER,
+           GL_COLOR_ATTACHMENT0,
+           GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(static_cast<GLuint>(*result_value), client_renderbuffer_id_);
+}
+
+TEST_P(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithTexture) {
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              FramebufferTexture2DEXT(GL_FRAMEBUFFER,
+                                      GL_COLOR_ATTACHMENT0,
+                                      GL_TEXTURE_2D,
+                                      kServiceTextureId,
+                                      0))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  GetFramebufferAttachmentParameteriv::Result* result =
+      static_cast<GetFramebufferAttachmentParameteriv::Result*>(
+          shared_memory_address_);
+  result->SetNumResults(0);
+  const GLint* result_value = result->GetData();
+  FramebufferTexture2D fbtex_cmd;
+  GetFramebufferAttachmentParameteriv cmd;
+  fbtex_cmd.Init(GL_FRAMEBUFFER,
+                 GL_COLOR_ATTACHMENT0,
+                 GL_TEXTURE_2D,
+                 client_texture_id_,
+                 0);
+  cmd.Init(GL_FRAMEBUFFER,
+           GL_COLOR_ATTACHMENT0,
+           GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(static_cast<GLuint>(*result_value), client_texture_id_);
+}
+
+TEST_P(GLES2DecoderTest, GetRenderbufferParameterivWithNoBoundTarget) {
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0);
+  GetRenderbufferParameteriv cmd;
+  cmd.Init(GL_RENDERBUFFER,
+           GL_RENDERBUFFER_WIDTH,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, RenderbufferStorageWithNoBoundTarget) {
+  EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0);
+  RenderbufferStorage cmd;
+  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 3, 4);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+namespace {
+
+// A class to emulate glReadPixels
+class ReadPixelsEmulator {
+ public:
+  // pack_alignment is the alignment you want ReadPixels to use
+  // when copying. The actual data passed in pixels should be contiguous.
+  ReadPixelsEmulator(GLsizei width,
+                     GLsizei height,
+                     GLint bytes_per_pixel,
+                     const void* src_pixels,
+                     const void* expected_pixels,
+                     GLint pack_alignment)
+      : width_(width),
+        height_(height),
+        pack_alignment_(pack_alignment),
+        bytes_per_pixel_(bytes_per_pixel),
+        src_pixels_(reinterpret_cast<const int8*>(src_pixels)),
+        expected_pixels_(reinterpret_cast<const int8*>(expected_pixels)) {}
+
+  void ReadPixels(GLint x,
+                  GLint y,
+                  GLsizei width,
+                  GLsizei height,
+                  GLenum format,
+                  GLenum type,
+                  void* pixels) const {
+    DCHECK_GE(x, 0);
+    DCHECK_GE(y, 0);
+    DCHECK_LE(x + width, width_);
+    DCHECK_LE(y + height, height_);
+    for (GLint yy = 0; yy < height; ++yy) {
+      const int8* src = GetPixelAddress(src_pixels_, x, y + yy);
+      const void* dst = ComputePackAlignmentAddress(0, yy, width, pixels);
+      memcpy(const_cast<void*>(dst), src, width * bytes_per_pixel_);
+    }
+  }
+
+  bool CompareRowSegment(GLint x,
+                         GLint y,
+                         GLsizei width,
+                         const void* data) const {
+    DCHECK(x + width <= width_ || width == 0);
+    return memcmp(data,
+                  GetPixelAddress(expected_pixels_, x, y),
+                  width * bytes_per_pixel_) == 0;
+  }
+
+  // Helper to compute address of pixel in pack aligned data.
+  const void* ComputePackAlignmentAddress(GLint x,
+                                          GLint y,
+                                          GLsizei width,
+                                          const void* address) const {
+    GLint unpadded_row_size = ComputeImageDataSize(width, 1);
+    GLint two_rows_size = ComputeImageDataSize(width, 2);
+    GLsizei padded_row_size = two_rows_size - unpadded_row_size;
+    GLint offset = y * padded_row_size + x * bytes_per_pixel_;
+    return static_cast<const int8*>(address) + offset;
+  }
+
+  GLint ComputeImageDataSize(GLint width, GLint height) const {
+    GLint row_size = width * bytes_per_pixel_;
+    if (height > 1) {
+      GLint temp = row_size + pack_alignment_ - 1;
+      GLint padded_row_size = (temp / pack_alignment_) * pack_alignment_;
+      GLint size_of_all_but_last_row = (height - 1) * padded_row_size;
+      return size_of_all_but_last_row + row_size;
+    } else {
+      return height * row_size;
+    }
+  }
+
+ private:
+  const int8* GetPixelAddress(const int8* base, GLint x, GLint y) const {
+    return base + (width_ * y + x) * bytes_per_pixel_;
+  }
+
+  GLsizei width_;
+  GLsizei height_;
+  GLint pack_alignment_;
+  GLint bytes_per_pixel_;
+  const int8* src_pixels_;
+  const int8* expected_pixels_;
+};
+
+}  // anonymous namespace
+
+void GLES2DecoderTest::CheckReadPixelsOutOfRange(GLint in_read_x,
+                                                 GLint in_read_y,
+                                                 GLsizei in_read_width,
+                                                 GLsizei in_read_height,
+                                                 bool init) {
+  const GLsizei kWidth = 5;
+  const GLsizei kHeight = 3;
+  const GLint kBytesPerPixel = 3;
+  const GLint kPackAlignment = 4;
+  const GLenum kFormat = GL_RGB;
+  static const int8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
+      12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19, 18, 19, 13,
+      29, 28, 23, 22, 21, 22, 21, 29, 28, 23, 22, 21, 22, 21, 28,
+      31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32, 37, 32, 34,
+  };
+
+  ClearSharedMemory();
+
+  // We need to setup an FBO so we can know the max size that ReadPixels will
+  // access
+  if (init) {
+    DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+    DoTexImage2D(GL_TEXTURE_2D,
+                 0,
+                 kFormat,
+                 kWidth,
+                 kHeight,
+                 0,
+                 kFormat,
+                 GL_UNSIGNED_BYTE,
+                 kSharedMemoryId,
+                 kSharedMemoryOffset);
+    DoBindFramebuffer(
+        GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+    DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                           GL_COLOR_ATTACHMENT0,
+                           GL_TEXTURE_2D,
+                           client_texture_id_,
+                           kServiceTextureId,
+                           0,
+                           GL_NO_ERROR);
+    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
+        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
+        .RetiresOnSaturation();
+  }
+
+  ReadPixelsEmulator emu(
+      kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment);
+  typedef ReadPixels::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  uint32 result_shm_id = kSharedMemoryId;
+  uint32 result_shm_offset = kSharedMemoryOffset;
+  uint32 pixels_shm_id = kSharedMemoryId;
+  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
+  void* dest = &result[1];
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  // ReadPixels will be called for valid size only even though the command
+  // is requesting a larger size.
+  GLint read_x = std::max(0, in_read_x);
+  GLint read_y = std::max(0, in_read_y);
+  GLint read_end_x = std::max(0, std::min(kWidth, in_read_x + in_read_width));
+  GLint read_end_y = std::max(0, std::min(kHeight, in_read_y + in_read_height));
+  GLint read_width = read_end_x - read_x;
+  GLint read_height = read_end_y - read_y;
+  if (read_width > 0 && read_height > 0) {
+    for (GLint yy = read_y; yy < read_end_y; ++yy) {
+      EXPECT_CALL(
+          *gl_,
+          ReadPixels(read_x, yy, read_width, 1, kFormat, GL_UNSIGNED_BYTE, _))
+          .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels))
+          .RetiresOnSaturation();
+    }
+  }
+  ReadPixels cmd;
+  cmd.Init(in_read_x,
+           in_read_y,
+           in_read_width,
+           in_read_height,
+           kFormat,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           pixels_shm_offset,
+           result_shm_id,
+           result_shm_offset,
+           false);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+
+  GLint unpadded_row_size = emu.ComputeImageDataSize(in_read_width, 1);
+  scoped_ptr<int8[]> zero(new int8[unpadded_row_size]);
+  scoped_ptr<int8[]> pack(new int8[kPackAlignment]);
+  memset(zero.get(), 0, unpadded_row_size);
+  memset(pack.get(), kInitialMemoryValue, kPackAlignment);
+  for (GLint yy = 0; yy < in_read_height; ++yy) {
+    const int8* row = static_cast<const int8*>(
+        emu.ComputePackAlignmentAddress(0, yy, in_read_width, dest));
+    GLint y = in_read_y + yy;
+    if (y < 0 || y >= kHeight) {
+      EXPECT_EQ(0, memcmp(zero.get(), row, unpadded_row_size));
+    } else {
+      // check off left.
+      GLint num_left_pixels = std::max(-in_read_x, 0);
+      GLint num_left_bytes = num_left_pixels * kBytesPerPixel;
+      EXPECT_EQ(0, memcmp(zero.get(), row, num_left_bytes));
+
+      // check off right.
+      GLint num_right_pixels = std::max(in_read_x + in_read_width - kWidth, 0);
+      GLint num_right_bytes = num_right_pixels * kBytesPerPixel;
+      EXPECT_EQ(0,
+                memcmp(zero.get(),
+                       row + unpadded_row_size - num_right_bytes,
+                       num_right_bytes));
+
+      // check middle.
+      GLint x = std::max(in_read_x, 0);
+      GLint num_middle_pixels =
+          std::max(in_read_width - num_left_pixels - num_right_pixels, 0);
+      EXPECT_TRUE(
+          emu.CompareRowSegment(x, y, num_middle_pixels, row + num_left_bytes));
+    }
+
+    // check padding
+    if (yy != in_read_height - 1) {
+      GLint num_padding_bytes =
+          (kPackAlignment - 1) - (unpadded_row_size % kPackAlignment);
+      EXPECT_EQ(0,
+                memcmp(pack.get(), row + unpadded_row_size, num_padding_bytes));
+    }
+  }
+}
+
+TEST_P(GLES2DecoderTest, ReadPixels) {
+  const GLsizei kWidth = 5;
+  const GLsizei kHeight = 3;
+  const GLint kBytesPerPixel = 3;
+  const GLint kPackAlignment = 4;
+  static const int8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
+      12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19, 18, 19, 13,
+      29, 28, 23, 22, 21, 22, 21, 29, 28, 23, 22, 21, 22, 21, 28,
+      31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32, 37, 32, 34,
+  };
+
+  surface_->SetSize(gfx::Size(INT_MAX, INT_MAX));
+
+  ReadPixelsEmulator emu(
+      kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment);
+  typedef ReadPixels::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  uint32 result_shm_id = kSharedMemoryId;
+  uint32 result_shm_offset = kSharedMemoryOffset;
+  uint32 pixels_shm_id = kSharedMemoryId;
+  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
+  void* dest = &result[1];
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              ReadPixels(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, _))
+      .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels));
+  ReadPixels cmd;
+  cmd.Init(0,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGB,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           pixels_shm_offset,
+           result_shm_id,
+           result_shm_offset,
+           false);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  for (GLint yy = 0; yy < kHeight; ++yy) {
+    EXPECT_TRUE(emu.CompareRowSegment(
+        0, yy, kWidth, emu.ComputePackAlignmentAddress(0, yy, kWidth, dest)));
+  }
+}
+
+TEST_P(GLES2DecoderRGBBackbufferTest, ReadPixelsNoAlphaBackbuffer) {
+  const GLsizei kWidth = 3;
+  const GLsizei kHeight = 3;
+  const GLint kBytesPerPixel = 4;
+  const GLint kPackAlignment = 4;
+  static const uint8 kExpectedPixels[kWidth * kHeight * kBytesPerPixel] = {
+      12, 13, 14, 255, 19, 18, 19, 255, 13, 14, 18, 255,
+      29, 28, 23, 255, 21, 22, 21, 255, 28, 23, 22, 255,
+      31, 34, 39, 255, 32, 37, 32, 255, 34, 39, 37, 255,
+  };
+  static const uint8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
+      12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19, 29, 28, 23, 22, 21, 22,
+      21, 29, 28, 23, 22, 21, 31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32,
+  };
+
+  surface_->SetSize(gfx::Size(INT_MAX, INT_MAX));
+
+  ReadPixelsEmulator emu(kWidth,
+                         kHeight,
+                         kBytesPerPixel,
+                         kSrcPixels,
+                         kExpectedPixels,
+                         kPackAlignment);
+  typedef ReadPixels::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  uint32 result_shm_id = kSharedMemoryId;
+  uint32 result_shm_offset = kSharedMemoryOffset;
+  uint32 pixels_shm_id = kSharedMemoryId;
+  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
+  void* dest = &result[1];
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              ReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, _))
+      .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels));
+  ReadPixels cmd;
+  cmd.Init(0,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           pixels_shm_offset,
+           result_shm_id,
+           result_shm_offset,
+           false);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  for (GLint yy = 0; yy < kHeight; ++yy) {
+    EXPECT_TRUE(emu.CompareRowSegment(
+        0, yy, kWidth, emu.ComputePackAlignmentAddress(0, yy, kWidth, dest)));
+  }
+}
+
+TEST_P(GLES2DecoderTest, ReadPixelsOutOfRange) {
+  static GLint tests[][4] = {
+      {
+       -2, -1, 9, 5,
+      },  // out of range on all sides
+      {
+       2, 1, 9, 5,
+      },  // out of range on right, bottom
+      {
+       -7, -4, 9, 5,
+      },  // out of range on left, top
+      {
+       0, -5, 9, 5,
+      },  // completely off top
+      {
+       0, 3, 9, 5,
+      },  // completely off bottom
+      {
+       -9, 0, 9, 5,
+      },  // completely off left
+      {
+       5, 0, 9, 5,
+      },  // completely off right
+  };
+
+  for (size_t tt = 0; tt < arraysize(tests); ++tt) {
+    CheckReadPixelsOutOfRange(
+        tests[tt][0], tests[tt][1], tests[tt][2], tests[tt][3], tt == 0);
+  }
+}
+
+TEST_P(GLES2DecoderTest, ReadPixelsInvalidArgs) {
+  typedef ReadPixels::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  uint32 result_shm_id = kSharedMemoryId;
+  uint32 result_shm_offset = kSharedMemoryOffset;
+  uint32 pixels_shm_id = kSharedMemoryId;
+  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
+  EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0);
+  ReadPixels cmd;
+  cmd.Init(0,
+           0,
+           -1,
+           1,
+           GL_RGB,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           pixels_shm_offset,
+           result_shm_id,
+           result_shm_offset,
+           false);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(0,
+           0,
+           1,
+           -1,
+           GL_RGB,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           pixels_shm_offset,
+           result_shm_id,
+           result_shm_offset,
+           false);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(0,
+           0,
+           1,
+           1,
+           GL_RGB,
+           GL_INT,
+           pixels_shm_id,
+           pixels_shm_offset,
+           result_shm_id,
+           result_shm_offset,
+           false);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  cmd.Init(0,
+           0,
+           1,
+           1,
+           GL_RGB,
+           GL_UNSIGNED_BYTE,
+           kInvalidSharedMemoryId,
+           pixels_shm_offset,
+           result_shm_id,
+           result_shm_offset,
+           false);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(0,
+           0,
+           1,
+           1,
+           GL_RGB,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           kInvalidSharedMemoryOffset,
+           result_shm_id,
+           result_shm_offset,
+           false);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(0,
+           0,
+           1,
+           1,
+           GL_RGB,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           pixels_shm_offset,
+           kInvalidSharedMemoryId,
+           result_shm_offset,
+           false);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(0,
+           0,
+           1,
+           1,
+           GL_RGB,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           pixels_shm_offset,
+           result_shm_id,
+           kInvalidSharedMemoryOffset,
+           false);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderManualInitTest, ReadPixelsAsyncError) {
+  InitState init;
+  init.extensions = "GL_ARB_sync";
+  init.gl_version = "opengl es 3.0";
+  init.has_alpha = true;
+  init.request_alpha = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  typedef ReadPixels::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+
+  const GLsizei kWidth = 4;
+  const GLsizei kHeight = 4;
+  uint32 result_shm_id = kSharedMemoryId;
+  uint32 result_shm_offset = kSharedMemoryOffset;
+  uint32 pixels_shm_id = kSharedMemoryId;
+  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
+
+  EXPECT_CALL(*gl_, GetError())
+      // first error check must pass to get to the test
+      .WillOnce(Return(GL_NO_ERROR))
+      // second check is after BufferData, simulate fail here
+      .WillOnce(Return(GL_INVALID_OPERATION))
+      // third error check is fall-through call to sync ReadPixels
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+
+  EXPECT_CALL(*gl_,
+              ReadPixels(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, _))
+      .Times(1);
+  EXPECT_CALL(*gl_, GenBuffersARB(1, _)).Times(1);
+  EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, _)).Times(2);
+  EXPECT_CALL(*gl_,
+              BufferData(GL_PIXEL_PACK_BUFFER_ARB, _, NULL, GL_STREAM_READ))
+      .Times(1);
+
+  ReadPixels cmd;
+  cmd.Init(0,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGB,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           pixels_shm_offset,
+           result_shm_id,
+           result_shm_offset,
+           true);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+// Check that if a renderbuffer is attached and GL returns
+// GL_FRAMEBUFFER_COMPLETE that the buffer is cleared and state is restored.
+TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearColor) {
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  ClearColor color_cmd;
+  ColorMask color_mask_cmd;
+  Enable enable_cmd;
+  FramebufferRenderbuffer cmd;
+  color_cmd.Init(0.1f, 0.2f, 0.3f, 0.4f);
+  color_mask_cmd.Init(0, 1, 0, 1);
+  enable_cmd.Init(GL_SCISSOR_TEST);
+  cmd.Init(GL_FRAMEBUFFER,
+           GL_COLOR_ATTACHMENT0,
+           GL_RENDERBUFFER,
+           client_renderbuffer_id_);
+  InSequence sequence;
+  EXPECT_CALL(*gl_, ClearColor(0.1f, 0.2f, 0.3f, 0.4f))
+      .Times(1)
+      .RetiresOnSaturation();
+  SetupExpectationsForEnableDisable(GL_SCISSOR_TEST, true);
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+                                         GL_COLOR_ATTACHMENT0,
+                                         GL_RENDERBUFFER,
+                                         kServiceRenderbufferId))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(color_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(color_mask_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearDepth) {
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  ClearDepthf depth_cmd;
+  DepthMask depth_mask_cmd;
+  FramebufferRenderbuffer cmd;
+  depth_cmd.Init(0.5f);
+  depth_mask_cmd.Init(false);
+  cmd.Init(GL_FRAMEBUFFER,
+           GL_DEPTH_ATTACHMENT,
+           GL_RENDERBUFFER,
+           client_renderbuffer_id_);
+  InSequence sequence;
+  EXPECT_CALL(*gl_, ClearDepth(0.5f)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+                                         GL_DEPTH_ATTACHMENT,
+                                         GL_RENDERBUFFER,
+                                         kServiceRenderbufferId))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(depth_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(depth_mask_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearStencil) {
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  ClearStencil stencil_cmd;
+  StencilMaskSeparate stencil_mask_separate_cmd;
+  FramebufferRenderbuffer cmd;
+  stencil_cmd.Init(123);
+  stencil_mask_separate_cmd.Init(GL_BACK, 0x1234u);
+  cmd.Init(GL_FRAMEBUFFER,
+           GL_STENCIL_ATTACHMENT,
+           GL_RENDERBUFFER,
+           client_renderbuffer_id_);
+  InSequence sequence;
+  EXPECT_CALL(*gl_, ClearStencil(123)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+                                         GL_STENCIL_ATTACHMENT,
+                                         GL_RENDERBUFFER,
+                                         kServiceRenderbufferId))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_mask_separate_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+#if 0  // Turn this test on once we allow GL_DEPTH_STENCIL_ATTACHMENT
+TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearDepthStencil) {
+  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
+                    kServiceFramebufferId);
+  ClearDepthf depth_cmd;
+  ClearStencil stencil_cmd;
+  FramebufferRenderbuffer cmd;
+  depth_cmd.Init(0.5f);
+  stencil_cmd.Init(123);
+  cmd.Init(
+      GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
+      client_renderbuffer_id_);
+  InSequence sequence;
+  EXPECT_CALL(*gl_, ClearDepth(0.5f))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, ClearStencil(123))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
+      GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
+      kServiceRenderbufferId))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(depth_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+#endif
+
+TEST_P(GLES2DecoderManualInitTest, ActualAlphaMatchesRequestedAlpha) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_alpha = true;
+  init.request_alpha = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(8))
+      .RetiresOnSaturation();
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_ALPHA_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ALPHA_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(8, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, ActualAlphaDoesNotMatchRequestedAlpha) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_alpha = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(8))
+      .RetiresOnSaturation();
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_ALPHA_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ALPHA_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(0, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, ActualDepthMatchesRequestedDepth) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_depth = true;
+  init.request_depth = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(24))
+      .RetiresOnSaturation();
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(24, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, ActualDepthDoesNotMatchRequestedDepth) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_depth = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(24))
+      .RetiresOnSaturation();
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(0, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, ActualStencilMatchesRequestedStencil) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_stencil = true;
+  init.request_stencil = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(8))
+      .RetiresOnSaturation();
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(8, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, ActualStencilDoesNotMatchRequestedStencil) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_stencil = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(8))
+      .RetiresOnSaturation();
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(0, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilReportsCorrectValues) {
+  InitState init;
+  init.extensions = "GL_OES_packed_depth_stencil";
+  init.gl_version = "opengl es 2.0";
+  init.has_depth = true;
+  init.has_stencil = true;
+  init.request_depth = true;
+  init.request_stencil = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(8))
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(8, result->GetData()[0]);
+  result->size = 0;
+  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(24))
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(24, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilNoRequestedStencil) {
+  InitState init;
+  init.extensions = "GL_OES_packed_depth_stencil";
+  init.gl_version = "opengl es 2.0";
+  init.has_depth = true;
+  init.has_stencil = true;
+  init.request_depth = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(8))
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(0, result->GetData()[0]);
+  result->size = 0;
+  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(24))
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(24, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilRenderbufferDepth) {
+  InitState init;
+  init.extensions = "GL_OES_packed_depth_stencil";
+  init.gl_version = "opengl es 2.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))  // for RenderbufferStoage
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))  // for FramebufferRenderbuffer
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+
+  EXPECT_CALL(
+      *gl_,
+      RenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50))
+      .Times(1)
+      .RetiresOnSaturation();
+  RenderbufferStorage cmd;
+  cmd.Init(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_CALL(*gl_,
+              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+                                         GL_DEPTH_ATTACHMENT,
+                                         GL_RENDERBUFFER,
+                                         kServiceRenderbufferId))
+      .Times(1)
+      .RetiresOnSaturation();
+  FramebufferRenderbuffer fbrb_cmd;
+  fbrb_cmd.Init(GL_FRAMEBUFFER,
+                GL_DEPTH_ATTACHMENT,
+                GL_RENDERBUFFER,
+                client_renderbuffer_id_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
+
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(8))
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(0, result->GetData()[0]);
+  result->size = 0;
+  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(24))
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(24, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilRenderbufferStencil) {
+  InitState init;
+  init.extensions = "GL_OES_packed_depth_stencil";
+  init.gl_version = "opengl es 2.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))  // for RenderbufferStoage
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))  // for FramebufferRenderbuffer
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+
+  EXPECT_CALL(
+      *gl_,
+      RenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50))
+      .Times(1)
+      .RetiresOnSaturation();
+  RenderbufferStorage cmd;
+  cmd.Init(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_CALL(*gl_,
+              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+                                         GL_STENCIL_ATTACHMENT,
+                                         GL_RENDERBUFFER,
+                                         kServiceRenderbufferId))
+      .Times(1)
+      .RetiresOnSaturation();
+  FramebufferRenderbuffer fbrb_cmd;
+  fbrb_cmd.Init(GL_FRAMEBUFFER,
+                GL_STENCIL_ATTACHMENT,
+                GL_RENDERBUFFER,
+                client_renderbuffer_id_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
+
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->size = 0;
+  GetIntegerv cmd2;
+  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(8))
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(8, result->GetData()[0]);
+  result->size = 0;
+  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
+      .WillOnce(SetArgumentPointee<1>(24))
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(0, result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderTest, FramebufferRenderbufferGLError) {
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_OUT_OF_MEMORY))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+                                         GL_COLOR_ATTACHMENT0,
+                                         GL_RENDERBUFFER,
+                                         kServiceRenderbufferId))
+      .Times(1)
+      .RetiresOnSaturation();
+  FramebufferRenderbuffer cmd;
+  cmd.Init(GL_FRAMEBUFFER,
+           GL_COLOR_ATTACHMENT0,
+           GL_RENDERBUFFER,
+           client_renderbuffer_id_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, FramebufferTexture2DGLError) {
+  const GLsizei kWidth = 5;
+  const GLsizei kHeight = 3;
+  const GLenum kFormat = GL_RGB;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               kFormat,
+               kWidth,
+               kHeight,
+               0,
+               kFormat,
+               GL_UNSIGNED_BYTE,
+               0,
+               0);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_OUT_OF_MEMORY))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              FramebufferTexture2DEXT(GL_FRAMEBUFFER,
+                                      GL_COLOR_ATTACHMENT0,
+                                      GL_TEXTURE_2D,
+                                      kServiceTextureId,
+                                      0))
+      .Times(1)
+      .RetiresOnSaturation();
+  FramebufferTexture2D fbtex_cmd;
+  fbtex_cmd.Init(GL_FRAMEBUFFER,
+                 GL_COLOR_ATTACHMENT0,
+                 GL_TEXTURE_2D,
+                 client_texture_id_,
+                 0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, RenderbufferStorageGLError) {
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_OUT_OF_MEMORY))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 100, 50))
+      .Times(1)
+      .RetiresOnSaturation();
+  RenderbufferStorage cmd;
+  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 100, 50);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, RenderbufferStorageBadArgs) {
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  RenderbufferStorage cmd;
+  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, TestHelper::kMaxRenderbufferSize + 1, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 1, TestHelper::kMaxRenderbufferSize + 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest,
+       RenderbufferStorageMultisampleCHROMIUMGLError) {
+  InitState init;
+  init.extensions = "GL_EXT_framebuffer_multisample";
+  init.gl_version = "2.1";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_OUT_OF_MEMORY))
+      .RetiresOnSaturation();
+  EXPECT_CALL(
+      *gl_,
+      RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 1, GL_RGBA, 100, 50))
+      .Times(1)
+      .RetiresOnSaturation();
+  RenderbufferStorageMultisampleCHROMIUM cmd;
+  cmd.Init(GL_RENDERBUFFER, 1, GL_RGBA4, 100, 50);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest,
+       RenderbufferStorageMultisampleCHROMIUMBadArgs) {
+  InitState init;
+  init.extensions = "GL_EXT_framebuffer_multisample";
+  init.gl_version = "2.1";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  EXPECT_CALL(*gl_, RenderbufferStorageMultisampleEXT(_, _, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  RenderbufferStorageMultisampleCHROMIUM cmd;
+  cmd.Init(GL_RENDERBUFFER,
+           TestHelper::kMaxSamples + 1,
+           GL_RGBA4,
+           TestHelper::kMaxRenderbufferSize,
+           1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_RENDERBUFFER,
+           TestHelper::kMaxSamples,
+           GL_RGBA4,
+           TestHelper::kMaxRenderbufferSize + 1,
+           1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_RENDERBUFFER,
+           TestHelper::kMaxSamples,
+           GL_RGBA4,
+           1,
+           TestHelper::kMaxRenderbufferSize + 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleCHROMIUM) {
+  InitState init;
+  init.extensions = "GL_EXT_framebuffer_multisample";
+  init.gl_version = "2.1";
+  InitDecoder(init);
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  InSequence sequence;
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(
+      *gl_,
+      RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
+                                        TestHelper::kMaxSamples,
+                                        GL_RGBA,
+                                        TestHelper::kMaxRenderbufferSize,
+                                        1))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  RenderbufferStorageMultisampleCHROMIUM cmd;
+  cmd.Init(GL_RENDERBUFFER,
+           TestHelper::kMaxSamples,
+           GL_RGBA4,
+           TestHelper::kMaxRenderbufferSize,
+           1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest,
+       RenderbufferStorageMultisampleEXTNotSupported) {
+  InitState init;
+  init.extensions = "GL_EXT_framebuffer_multisample";
+  init.gl_version = "2.1";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  InSequence sequence;
+  // GL_EXT_framebuffer_multisample uses RenderbufferStorageMultisampleCHROMIUM.
+  RenderbufferStorageMultisampleEXT cmd;
+  cmd.Init(GL_RENDERBUFFER,
+           TestHelper::kMaxSamples,
+           GL_RGBA4,
+           TestHelper::kMaxRenderbufferSize,
+           1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+class GLES2DecoderMultisampledRenderToTextureTest
+    : public GLES2DecoderTestWithExtensionsOnGLES2 {
+ public:
+  void TestNotCompatibleWithRenderbufferStorageMultisampleCHROMIUM() {
+    DoBindRenderbuffer(
+        GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+    RenderbufferStorageMultisampleCHROMIUM cmd;
+    cmd.Init(GL_RENDERBUFFER,
+             TestHelper::kMaxSamples,
+             GL_RGBA4,
+             TestHelper::kMaxRenderbufferSize,
+             1);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  }
+
+  void TestRenderbufferStorageMultisampleEXT(const char* extension) {
+    DoBindRenderbuffer(
+        GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+    InSequence sequence;
+    EXPECT_CALL(*gl_, GetError())
+        .WillOnce(Return(GL_NO_ERROR))
+        .RetiresOnSaturation();
+    if (strstr(extension, "GL_IMG_multisampled_render_to_texture")) {
+      EXPECT_CALL(
+          *gl_,
+          RenderbufferStorageMultisampleIMG(GL_RENDERBUFFER,
+                                            TestHelper::kMaxSamples,
+                                            GL_RGBA,
+                                            TestHelper::kMaxRenderbufferSize,
+                                            1))
+          .Times(1)
+          .RetiresOnSaturation();
+    } else {
+      EXPECT_CALL(
+          *gl_,
+          RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
+                                            TestHelper::kMaxSamples,
+                                            GL_RGBA,
+                                            TestHelper::kMaxRenderbufferSize,
+                                            1))
+          .Times(1)
+          .RetiresOnSaturation();
+    }
+    EXPECT_CALL(*gl_, GetError())
+        .WillOnce(Return(GL_NO_ERROR))
+        .RetiresOnSaturation();
+    RenderbufferStorageMultisampleEXT cmd;
+    cmd.Init(GL_RENDERBUFFER,
+             TestHelper::kMaxSamples,
+             GL_RGBA4,
+             TestHelper::kMaxRenderbufferSize,
+             1);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(Service,
+                        GLES2DecoderMultisampledRenderToTextureTest,
+                        ::testing::Bool());
+
+TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
+       NotCompatibleWithRenderbufferStorageMultisampleCHROMIUM_EXT) {
+  Init("GL_EXT_multisampled_render_to_texture");
+  TestNotCompatibleWithRenderbufferStorageMultisampleCHROMIUM();
+}
+
+TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
+       NotCompatibleWithRenderbufferStorageMultisampleCHROMIUM_IMG) {
+  Init("GL_IMG_multisampled_render_to_texture");
+  TestNotCompatibleWithRenderbufferStorageMultisampleCHROMIUM();
+}
+
+TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
+       RenderbufferStorageMultisampleEXT_EXT) {
+  Init("GL_EXT_multisampled_render_to_texture");
+  TestRenderbufferStorageMultisampleEXT(
+      "GL_EXT_multisampled_render_to_texture");
+}
+
+TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
+       RenderbufferStorageMultisampleEXT_IMG) {
+  Init("GL_IMG_multisampled_render_to_texture");
+  TestRenderbufferStorageMultisampleEXT(
+      "GL_IMG_multisampled_render_to_texture");
+}
+
+TEST_P(GLES2DecoderTest, ReadPixelsGLError) {
+  GLenum kFormat = GL_RGBA;
+  GLint x = 0;
+  GLint y = 0;
+  GLsizei width = 2;
+  GLsizei height = 4;
+  typedef ReadPixels::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  uint32 result_shm_id = kSharedMemoryId;
+  uint32 result_shm_offset = kSharedMemoryOffset;
+  uint32 pixels_shm_id = kSharedMemoryId;
+  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_OUT_OF_MEMORY))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              ReadPixels(x, y, width, height, kFormat, GL_UNSIGNED_BYTE, _))
+      .Times(1)
+      .RetiresOnSaturation();
+  ReadPixels cmd;
+  cmd.Init(x,
+           y,
+           width,
+           height,
+           kFormat,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           pixels_shm_offset,
+           result_shm_id,
+           result_shm_offset,
+           false);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnClear) {
+  const GLuint kFBOClientTextureId = 4100;
+  const GLuint kFBOServiceTextureId = 4101;
+
+  // Register a texture id.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
+      .RetiresOnSaturation();
+  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
+
+  // Setup "render to" texture.
+  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         kFBOClientTextureId,
+                         kFBOServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+
+  // Setup "render from" texture.
+  SetupTexture();
+
+  SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER,       // target
+                                          GL_COLOR_BUFFER_BIT,  // clear bits
+                                          0,
+                                          0,
+                                          0,
+                                          0,       // color
+                                          0,       // stencil
+                                          1.0f,    // depth
+                                          false);  // scissor test
+  SetupExpectationsForApplyingDirtyState(false,    // Framebuffer is RGB
+                                         false,    // Framebuffer has depth
+                                         false,    // Framebuffer has stencil
+                                         0x1111,   // color bits
+                                         false,    // depth mask
+                                         false,    // depth enabled
+                                         0,        // front stencil mask
+                                         0,        // back stencil mask
+                                         false);   // stencil enabled
+
+  EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT)).Times(1).RetiresOnSaturation();
+
+  Clear cmd;
+  cmd.Init(GL_COLOR_BUFFER_BIT);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnReadPixels) {
+  const GLuint kFBOClientTextureId = 4100;
+  const GLuint kFBOServiceTextureId = 4101;
+
+  // Register a texture id.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
+      .RetiresOnSaturation();
+  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
+
+  // Setup "render to" texture.
+  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         kFBOClientTextureId,
+                         kFBOServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+
+  // Setup "render from" texture.
+  SetupTexture();
+
+  SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER,       // target
+                                          GL_COLOR_BUFFER_BIT,  // clear bits
+                                          0,
+                                          0,
+                                          0,
+                                          0,       // color
+                                          0,       // stencil
+                                          1.0f,    // depth
+                                          false);  // scissor test
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
+      .Times(1)
+      .RetiresOnSaturation();
+  typedef ReadPixels::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  uint32 result_shm_id = kSharedMemoryId;
+  uint32 result_shm_offset = kSharedMemoryOffset;
+  uint32 pixels_shm_id = kSharedMemoryId;
+  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
+  ReadPixels cmd;
+  cmd.Init(0,
+           0,
+           1,
+           1,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           pixels_shm_offset,
+           result_shm_id,
+           result_shm_offset,
+           false);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest,
+       UnClearedAttachmentsGetClearedOnReadPixelsAndDrawBufferGetsRestored) {
+  InitState init;
+  init.extensions = "GL_EXT_framebuffer_multisample";
+  init.gl_version = "2.1";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  const GLuint kFBOClientTextureId = 4100;
+  const GLuint kFBOServiceTextureId = 4101;
+
+  // Register a texture id.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
+      .RetiresOnSaturation();
+  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
+
+  // Setup "render from" texture.
+  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoBindFramebuffer(
+      GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_READ_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         kFBOClientTextureId,
+                         kFBOServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+
+  // Enable GL_SCISSOR_TEST to make sure we disable it in the clear,
+  // then re-enable after.
+  DoEnableDisable(GL_SCISSOR_TEST, true);
+
+  SetupExpectationsForFramebufferClearingMulti(
+      kServiceFramebufferId,  // read framebuffer service id
+      0,                      // backbuffer service id
+      GL_READ_FRAMEBUFFER,    // target
+      GL_COLOR_BUFFER_BIT,    // clear bits
+      0,
+      0,
+      0,
+      0,      // color
+      0,      // stencil
+      1.0f,   // depth
+      true);  // scissor test
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
+      .Times(1)
+      .RetiresOnSaturation();
+  typedef ReadPixels::Result Result;
+  uint32 result_shm_id = kSharedMemoryId;
+  uint32 result_shm_offset = kSharedMemoryOffset;
+  uint32 pixels_shm_id = kSharedMemoryId;
+  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);
+  ReadPixels cmd;
+  cmd.Init(0,
+           0,
+           1,
+           1,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           pixels_shm_id,
+           pixels_shm_offset,
+           result_shm_id,
+           result_shm_offset,
+           false);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, CopyTexImageWithInCompleteFBOFails) {
+  GLenum target = GL_TEXTURE_2D;
+  GLint level = 0;
+  GLenum internal_format = GL_RGBA;
+  GLsizei width = 2;
+  GLsizei height = 4;
+  GLint border = 0;
+  SetupTexture();
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 0, 0, GL_NO_ERROR);
+  DoFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                            GL_COLOR_ATTACHMENT0,
+                            GL_RENDERBUFFER,
+                            client_renderbuffer_id_,
+                            kServiceRenderbufferId,
+                            GL_NO_ERROR);
+
+  EXPECT_CALL(*gl_, CopyTexImage2D(_, _, _, _, _, _, _, _))
+      .Times(0)
+      .RetiresOnSaturation();
+  CopyTexImage2D cmd;
+  cmd.Init(target, level, internal_format, 0, 0, width, height, border);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_FRAMEBUFFER_OPERATION, GetGLError());
+}
+
+void GLES2DecoderWithShaderTest::CheckRenderbufferChangesMarkFBOAsNotComplete(
+    bool bound_fbo) {
+  FramebufferManager* framebuffer_manager = group().framebuffer_manager();
+  SetupTexture();
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
+  DoFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                            GL_COLOR_ATTACHMENT0,
+                            GL_RENDERBUFFER,
+                            client_renderbuffer_id_,
+                            kServiceRenderbufferId,
+                            GL_NO_ERROR);
+
+  if (!bound_fbo) {
+    DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
+  }
+
+  Framebuffer* framebuffer =
+      framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
+  ASSERT_TRUE(framebuffer != NULL);
+  framebuffer_manager->MarkAsComplete(framebuffer);
+  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
+
+  // Test that renderbufferStorage marks fbo as not complete.
+  DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
+  EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
+  framebuffer_manager->MarkAsComplete(framebuffer);
+  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
+
+  // Test deleting renderbuffer marks fbo as not complete.
+  DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
+  if (bound_fbo) {
+    EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
+  } else {
+    EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
+  }
+  // Cleanup
+  DoDeleteFramebuffer(client_framebuffer_id_,
+                      kServiceFramebufferId,
+                      bound_fbo,
+                      GL_FRAMEBUFFER,
+                      0,
+                      bound_fbo,
+                      GL_FRAMEBUFFER,
+                      0);
+}
+
+TEST_P(GLES2DecoderWithShaderTest,
+       RenderbufferChangesMarkFBOAsNotCompleteBoundFBO) {
+  CheckRenderbufferChangesMarkFBOAsNotComplete(true);
+}
+
+TEST_P(GLES2DecoderWithShaderTest,
+       RenderbufferChangesMarkFBOAsNotCompleteUnboundFBO) {
+  CheckRenderbufferChangesMarkFBOAsNotComplete(false);
+}
+
+void GLES2DecoderWithShaderTest::CheckTextureChangesMarkFBOAsNotComplete(
+    bool bound_fbo) {
+  FramebufferManager* framebuffer_manager = group().framebuffer_manager();
+  const GLuint kFBOClientTextureId = 4100;
+  const GLuint kFBOServiceTextureId = 4101;
+
+  // Register a texture id.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
+      .RetiresOnSaturation();
+  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
+
+  SetupTexture();
+
+  // Setup "render to" texture.
+  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         kFBOClientTextureId,
+                         kFBOServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+
+  DoBindRenderbuffer(
+      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoRenderbufferStorage(GL_RENDERBUFFER,
+                        GL_DEPTH_COMPONENT16,
+                        GL_DEPTH_COMPONENT,
+                        1,
+                        1,
+                        GL_NO_ERROR);
+  DoFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                            GL_DEPTH_ATTACHMENT,
+                            GL_RENDERBUFFER,
+                            client_renderbuffer_id_,
+                            kServiceRenderbufferId,
+                            GL_NO_ERROR);
+
+  if (!bound_fbo) {
+    DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
+  }
+
+  Framebuffer* framebuffer =
+      framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
+  ASSERT_TRUE(framebuffer != NULL);
+  framebuffer_manager->MarkAsComplete(framebuffer);
+  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
+
+  // Test TexImage2D marks fbo as not complete.
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, 0, 0);
+  EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
+  framebuffer_manager->MarkAsComplete(framebuffer);
+  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
+
+  // Test CopyImage2D marks fbo as not complete.
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1, 0))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  CopyTexImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1, 0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
+
+  // Test deleting texture marks fbo as not complete.
+  framebuffer_manager->MarkAsComplete(framebuffer);
+  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
+  DoDeleteTexture(kFBOClientTextureId, kFBOServiceTextureId);
+
+  if (bound_fbo) {
+    EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
+  } else {
+    EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
+  }
+  // Cleanup
+  DoDeleteFramebuffer(client_framebuffer_id_,
+                      kServiceFramebufferId,
+                      bound_fbo,
+                      GL_FRAMEBUFFER,
+                      0,
+                      bound_fbo,
+                      GL_FRAMEBUFFER,
+                      0);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, TextureChangesMarkFBOAsNotCompleteBoundFBO) {
+  CheckTextureChangesMarkFBOAsNotComplete(true);
+}
+
+TEST_P(GLES2DecoderWithShaderTest,
+       TextureChangesMarkFBOAsNotCompleteUnboundFBO) {
+  CheckTextureChangesMarkFBOAsNotComplete(false);
+}
+
+TEST_P(GLES2DecoderTest, CanChangeSurface) {
+  scoped_refptr<GLSurfaceMock> other_surface(new GLSurfaceMock);
+  EXPECT_CALL(*other_surface.get(), GetBackingFrameBufferObject())
+      .WillOnce(Return(7));
+  EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 7));
+
+  decoder_->SetSurface(other_surface);
+}
+
+TEST_P(GLES2DecoderTest, DrawBuffersEXTImmediateSuccceeds) {
+  const GLsizei count = 1;
+  const GLenum bufs[] = {GL_COLOR_ATTACHMENT0};
+  DrawBuffersEXTImmediate& cmd = *GetImmediateAs<DrawBuffersEXTImmediate>();
+  cmd.Init(count, bufs);
+
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  EXPECT_CALL(*gl_, DrawBuffersARB(count, _)).Times(1).RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, DrawBuffersEXTImmediateFails) {
+  const GLsizei count = 1;
+  const GLenum bufs[] = {GL_COLOR_ATTACHMENT1_EXT};
+  DrawBuffersEXTImmediate& cmd = *GetImmediateAs<DrawBuffersEXTImmediate>();
+  cmd.Init(count, bufs);
+
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, DrawBuffersEXTImmediateBackbuffer) {
+  const GLsizei count = 1;
+  const GLenum bufs[] = {GL_BACK};
+  DrawBuffersEXTImmediate& cmd = *GetImmediateAs<DrawBuffersEXTImmediate>();
+  cmd.Init(count, bufs);
+
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+  DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);  // unbind
+
+  EXPECT_CALL(*gl_, DrawBuffersARB(count, _)).Times(1).RetiresOnSaturation();
+
+  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, InvalidateFramebufferBinding) {
+  InitState init;
+  init.gl_version = "opengl es 3.0";
+  InitDecoder(init);
+
+  // EXPECT_EQ can't be used to compare function pointers
+  EXPECT_TRUE(
+      gfx::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") ==
+      gfx::g_driver_gl.fn.glDiscardFramebufferEXTFn);
+  EXPECT_TRUE(
+      gfx::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") !=
+      gfx::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT"));
+}
+
+TEST_P(GLES2DecoderManualInitTest, DiscardFramebufferEXT) {
+  InitState init;
+  init.extensions = "GL_EXT_discard_framebuffer";
+  init.gl_version = "opengl es 2.0";
+  InitDecoder(init);
+
+  // EXPECT_EQ can't be used to compare function pointers
+  EXPECT_TRUE(
+      gfx::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") ==
+      gfx::g_driver_gl.fn.glDiscardFramebufferEXTFn);
+
+  const GLenum target = GL_FRAMEBUFFER;
+  const GLsizei count = 1;
+  const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
+
+  SetupTexture();
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         client_texture_id_,
+                         kServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+  FramebufferManager* framebuffer_manager = group().framebuffer_manager();
+  Framebuffer* framebuffer =
+      framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
+  EXPECT_TRUE(framebuffer->IsCleared());
+
+  EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
+      .Times(1)
+      .RetiresOnSaturation();
+  DiscardFramebufferEXTImmediate& cmd =
+      *GetImmediateAs<DiscardFramebufferEXTImmediate>();
+  cmd.Init(target, count, attachments);
+
+  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_FALSE(framebuffer->IsCleared());
+}
+
+TEST_P(GLES2DecoderTest, DiscardFramebufferEXTUnsupported) {
+  const GLenum target = GL_FRAMEBUFFER;
+  const GLsizei count = 1;
+  const GLenum attachments[] = {GL_COLOR_EXT};
+  DiscardFramebufferEXTImmediate& cmd =
+      *GetImmediateAs<DiscardFramebufferEXTImmediate>();
+  cmd.Init(target, count, attachments);
+
+  // Should not result into a call into GL.
+  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest,
+       DiscardedAttachmentsEXTMarksFramebufferIncomplete) {
+  InitState init;
+  init.extensions = "GL_EXT_discard_framebuffer";
+  init.gl_version = "opengl es 2.0";
+  init.has_alpha = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  const GLuint kFBOClientTextureId = 4100;
+  const GLuint kFBOServiceTextureId = 4101;
+
+  // Register a texture id.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
+      .RetiresOnSaturation();
+  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
+
+  // Setup "render to" texture.
+  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         kFBOClientTextureId,
+                         kFBOServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+
+  // Setup "render from" texture.
+  SetupTexture();
+
+  SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER,       // target
+                                          GL_COLOR_BUFFER_BIT,  // clear bits
+                                          0,
+                                          0,
+                                          0,
+                                          0,       // color
+                                          0,       // stencil
+                                          1.0f,    // depth
+                                          false);  // scissor test
+  SetupExpectationsForApplyingDirtyState(false,    // Framebuffer is RGB
+                                         false,    // Framebuffer has depth
+                                         false,    // Framebuffer has stencil
+                                         0x1111,   // color bits
+                                         false,    // depth mask
+                                         false,    // depth enabled
+                                         0,        // front stencil mask
+                                         0,        // back stencil mask
+                                         false);   // stencil enabled
+
+  EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT)).Times(1).RetiresOnSaturation();
+
+  Clear clear_cmd;
+  clear_cmd.Init(GL_COLOR_BUFFER_BIT);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(clear_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Check that framebuffer is cleared and complete.
+  FramebufferManager* framebuffer_manager = group().framebuffer_manager();
+  Framebuffer* framebuffer =
+      framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
+  EXPECT_TRUE(framebuffer->IsCleared());
+  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
+
+  // Check that Discard GL_COLOR_ATTACHMENT0, sets the attachment as uncleared
+  // and the framebuffer as incomplete.
+  EXPECT_TRUE(
+      gfx::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") ==
+      gfx::g_driver_gl.fn.glDiscardFramebufferEXTFn);
+
+  const GLenum target = GL_FRAMEBUFFER;
+  const GLsizei count = 1;
+  const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
+
+  DiscardFramebufferEXTImmediate& discard_cmd =
+      *GetImmediateAs<DiscardFramebufferEXTImmediate>();
+  discard_cmd.Init(target, count, attachments);
+
+  EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError,
+            ExecuteImmediateCmd(discard_cmd, sizeof(attachments)));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_FALSE(framebuffer->IsCleared());
+  EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
+}
+
+TEST_P(GLES2DecoderManualInitTest, ReadFormatExtension) {
+  InitState init;
+  init.extensions = "GL_OES_read_format";
+  init.gl_version = "2.1";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError()).Times(6).RetiresOnSaturation();
+
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  GetIntegerv cmd;
+  const GLuint kFBOClientTextureId = 4100;
+  const GLuint kFBOServiceTextureId = 4101;
+
+  // Register a texture id.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
+      .RetiresOnSaturation();
+  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
+
+  // Setup "render to" texture.
+  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         kFBOClientTextureId,
+                         kFBOServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+
+  result->size = 0;
+  EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(1).RetiresOnSaturation();
+  cmd.Init(GL_IMPLEMENTATION_COLOR_READ_FORMAT,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(1, result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  result->size = 0;
+  EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(1).RetiresOnSaturation();
+  cmd.Init(GL_IMPLEMENTATION_COLOR_READ_TYPE,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(1, result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, NoReadFormatExtension) {
+  InitState init;
+  init.gl_version = "2.1";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  GetIntegerv cmd;
+  const GLuint kFBOClientTextureId = 4100;
+  const GLuint kFBOServiceTextureId = 4101;
+
+  // Register a texture id.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
+      .RetiresOnSaturation();
+  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
+
+  // Setup "render to" texture.
+  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  DoFramebufferTexture2D(GL_FRAMEBUFFER,
+                         GL_COLOR_ATTACHMENT0,
+                         GL_TEXTURE_2D,
+                         kFBOClientTextureId,
+                         kFBOServiceTextureId,
+                         0,
+                         GL_NO_ERROR);
+
+  result->size = 0;
+  EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0).RetiresOnSaturation();
+  cmd.Init(GL_IMPLEMENTATION_COLOR_READ_FORMAT,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(1, result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  result->size = 0;
+  EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0).RetiresOnSaturation();
+  cmd.Init(GL_IMPLEMENTATION_COLOR_READ_TYPE,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(1, result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+// TODO(gman): PixelStorei
+
+// TODO(gman): SwapBuffers
+
+}  // namespace gles2
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc
new file mode 100644
index 0000000..5c0cecf
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc
@@ -0,0 +1,1391 @@
+// 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.
+
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "gpu/command_buffer/common/gles2_cmd_format.h"
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/common/id_allocator.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
+#include "gpu/command_buffer/service/cmd_buffer_engine.h"
+#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/context_state.h"
+#include "gpu/command_buffer/service/gl_surface_mock.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
+
+#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/image_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/mocks.h"
+#include "gpu/command_buffer/service/program_manager.h"
+#include "gpu/command_buffer/service/test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_mock.h"
+#include "ui/gl/gl_surface_stub.h"
+
+#if !defined(GL_DEPTH24_STENCIL8)
+#define GL_DEPTH24_STENCIL8 0x88F0
+#endif
+
+using ::gfx::MockGLInterface;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::MatcherCast;
+using ::testing::Mock;
+using ::testing::Pointee;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::SetArrayArgument;
+using ::testing::SetArgumentPointee;
+using ::testing::SetArgPointee;
+using ::testing::StrEq;
+using ::testing::StrictMock;
+
+namespace gpu {
+namespace gles2 {
+
+using namespace cmds;
+
+TEST_P(GLES2DecoderWithShaderTest, GetProgramInfoCHROMIUMValidArgs) {
+  const uint32 kBucketId = 123;
+  GetProgramInfoCHROMIUM cmd;
+  cmd.Init(client_program_id_, kBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
+  EXPECT_GT(bucket->size(), 0u);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetProgramInfoCHROMIUMInvalidArgs) {
+  const uint32 kBucketId = 123;
+  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
+  EXPECT_TRUE(bucket == NULL);
+  GetProgramInfoCHROMIUM cmd;
+  cmd.Init(kInvalidClientId, kBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  bucket = decoder_->GetBucket(kBucketId);
+  ASSERT_TRUE(bucket != NULL);
+  EXPECT_EQ(sizeof(ProgramInfoHeader), bucket->size());
+  ProgramInfoHeader* info =
+      bucket->GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
+  ASSERT_TRUE(info != 0);
+  EXPECT_EQ(0u, info->link_status);
+  EXPECT_EQ(0u, info->num_attribs);
+  EXPECT_EQ(0u, info->num_uniforms);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformivSucceeds) {
+  GetUniformiv::Result* result =
+      static_cast<GetUniformiv::Result*>(shared_memory_address_);
+  result->size = 0;
+  GetUniformiv cmd;
+  cmd.Init(client_program_id_,
+           kUniform2FakeLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_CALL(*gl_, GetUniformiv(kServiceProgramId, kUniform2RealLocation, _))
+      .Times(1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
+            result->size);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformivArrayElementSucceeds) {
+  GetUniformiv::Result* result =
+      static_cast<GetUniformiv::Result*>(shared_memory_address_);
+  result->size = 0;
+  GetUniformiv cmd;
+  cmd.Init(client_program_id_,
+           kUniform2ElementFakeLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_CALL(*gl_,
+              GetUniformiv(kServiceProgramId, kUniform2ElementRealLocation, _))
+      .Times(1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
+            result->size);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) {
+  GetUniformiv::Result* result =
+      static_cast<GetUniformiv::Result*>(shared_memory_address_);
+  result->size = 0;
+  GetUniformiv cmd;
+  // non-existant program
+  cmd.Init(kInvalidClientId,
+           kUniform2FakeLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_CALL(*gl_, GetUniformiv(_, _, _)).Times(0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0U, result->size);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+// Valid id that is not a program. The GL spec requires a different error for
+// this case.
+#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
+  result->size = kInitialResult;
+  cmd.Init(client_shader_id_,
+           kUniform2FakeLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0U, result->size);
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
+  // Unlinked program
+  EXPECT_CALL(*gl_, CreateProgram())
+      .Times(1)
+      .WillOnce(Return(kNewServiceId))
+      .RetiresOnSaturation();
+  CreateProgram cmd2;
+  cmd2.Init(kNewClientId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  result->size = kInitialResult;
+  cmd.Init(kNewClientId,
+           kUniform2FakeLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0U, result->size);
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadLocationFails) {
+  GetUniformiv::Result* result =
+      static_cast<GetUniformiv::Result*>(shared_memory_address_);
+  result->size = 0;
+  GetUniformiv cmd;
+  // invalid location
+  cmd.Init(client_program_id_,
+           kInvalidUniformLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_CALL(*gl_, GetUniformiv(_, _, _)).Times(0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0U, result->size);
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadSharedMemoryFails) {
+  GetUniformiv cmd;
+  cmd.Init(client_program_id_,
+           kUniform2FakeLocation,
+           kInvalidSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_CALL(*gl_, GetUniformiv(_, _, _)).Times(0);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_program_id_,
+           kUniform2FakeLocation,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+};
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformfvSucceeds) {
+  GetUniformfv::Result* result =
+      static_cast<GetUniformfv::Result*>(shared_memory_address_);
+  result->size = 0;
+  GetUniformfv cmd;
+  cmd.Init(client_program_id_,
+           kUniform2FakeLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_CALL(*gl_, GetUniformfv(kServiceProgramId, kUniform2RealLocation, _))
+      .Times(1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
+            result->size);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformfvArrayElementSucceeds) {
+  GetUniformfv::Result* result =
+      static_cast<GetUniformfv::Result*>(shared_memory_address_);
+  result->size = 0;
+  GetUniformfv cmd;
+  cmd.Init(client_program_id_,
+           kUniform2ElementFakeLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_CALL(*gl_,
+              GetUniformfv(kServiceProgramId, kUniform2ElementRealLocation, _))
+      .Times(1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
+            result->size);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) {
+  GetUniformfv::Result* result =
+      static_cast<GetUniformfv::Result*>(shared_memory_address_);
+  result->size = 0;
+  GetUniformfv cmd;
+  // non-existant program
+  cmd.Init(kInvalidClientId,
+           kUniform2FakeLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_CALL(*gl_, GetUniformfv(_, _, _)).Times(0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0U, result->size);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+// Valid id that is not a program. The GL spec requires a different error for
+// this case.
+#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
+  result->size = kInitialResult;
+  cmd.Init(client_shader_id_,
+           kUniform2FakeLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0U, result->size);
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
+  // Unlinked program
+  EXPECT_CALL(*gl_, CreateProgram())
+      .Times(1)
+      .WillOnce(Return(kNewServiceId))
+      .RetiresOnSaturation();
+  CreateProgram cmd2;
+  cmd2.Init(kNewClientId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  result->size = kInitialResult;
+  cmd.Init(kNewClientId,
+           kUniform2FakeLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0U, result->size);
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadLocationFails) {
+  GetUniformfv::Result* result =
+      static_cast<GetUniformfv::Result*>(shared_memory_address_);
+  result->size = 0;
+  GetUniformfv cmd;
+  // invalid location
+  cmd.Init(client_program_id_,
+           kInvalidUniformLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_CALL(*gl_, GetUniformfv(_, _, _)).Times(0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0U, result->size);
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadSharedMemoryFails) {
+  GetUniformfv cmd;
+  cmd.Init(client_program_id_,
+           kUniform2FakeLocation,
+           kInvalidSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_CALL(*gl_, GetUniformfv(_, _, _)).Times(0);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_program_id_,
+           kUniform2FakeLocation,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+};
+
+TEST_P(GLES2DecoderWithShaderTest, GetAttachedShadersSucceeds) {
+  GetAttachedShaders cmd;
+  typedef GetAttachedShaders::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->size = 0;
+  EXPECT_CALL(*gl_, GetAttachedShaders(kServiceProgramId, 1, _, _)).WillOnce(
+      DoAll(SetArgumentPointee<2>(1), SetArgumentPointee<3>(kServiceShaderId)));
+  cmd.Init(client_program_id_,
+           shared_memory_id_,
+           shared_memory_offset_,
+           Result::ComputeSize(1));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(1, result->GetNumResults());
+  EXPECT_EQ(client_shader_id_, result->GetData()[0]);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetAttachedShadersResultNotInitFail) {
+  GetAttachedShaders cmd;
+  typedef GetAttachedShaders::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->size = 1;
+  EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _)).Times(0);
+  cmd.Init(client_program_id_,
+           shared_memory_id_,
+           shared_memory_offset_,
+           Result::ComputeSize(1));
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetAttachedShadersBadProgramFails) {
+  GetAttachedShaders cmd;
+  typedef GetAttachedShaders::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->size = 0;
+  EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _)).Times(0);
+  cmd.Init(kInvalidClientId,
+           shared_memory_id_,
+           shared_memory_offset_,
+           Result::ComputeSize(1));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0U, result->size);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetAttachedShadersBadSharedMemoryFails) {
+  GetAttachedShaders cmd;
+  typedef GetAttachedShaders::Result Result;
+  cmd.Init(client_program_id_,
+           kInvalidSharedMemoryId,
+           shared_memory_offset_,
+           Result::ComputeSize(1));
+  EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _)).Times(0);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_program_id_,
+           shared_memory_id_,
+           kInvalidSharedMemoryOffset,
+           Result::ComputeSize(1));
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatSucceeds) {
+  ScopedGLImplementationSetter gl_impl(::gfx::kGLImplementationEGLGLES2);
+  GetShaderPrecisionFormat cmd;
+  typedef GetShaderPrecisionFormat::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->success = 0;
+  const GLint range[2] = {62, 62};
+  const GLint precision = 16;
+  EXPECT_CALL(*gl_, GetShaderPrecisionFormat(_, _, _, _))
+      .WillOnce(DoAll(SetArrayArgument<2>(range, range + 2),
+                      SetArgumentPointee<3>(precision)))
+      .RetiresOnSaturation();
+  cmd.Init(GL_VERTEX_SHADER,
+           GL_HIGH_FLOAT,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_NE(0, result->success);
+  EXPECT_EQ(range[0], result->min_range);
+  EXPECT_EQ(range[1], result->max_range);
+  EXPECT_EQ(precision, result->precision);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatResultNotInitFails) {
+  GetShaderPrecisionFormat cmd;
+  typedef GetShaderPrecisionFormat::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->success = 1;
+  // NOTE: GL might not be called. There is no Desktop OpenGL equivalent
+  cmd.Init(GL_VERTEX_SHADER,
+           GL_HIGH_FLOAT,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatBadArgsFails) {
+  typedef GetShaderPrecisionFormat::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->success = 0;
+  GetShaderPrecisionFormat cmd;
+  cmd.Init(
+      GL_TEXTURE_2D, GL_HIGH_FLOAT, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  result->success = 0;
+  cmd.Init(GL_VERTEX_SHADER,
+           GL_TEXTURE_2D,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest,
+       GetShaderPrecisionFormatBadSharedMemoryFails) {
+  GetShaderPrecisionFormat cmd;
+  cmd.Init(GL_VERTEX_SHADER,
+           GL_HIGH_FLOAT,
+           kInvalidSharedMemoryId,
+           shared_memory_offset_);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(GL_VERTEX_SHADER,
+           GL_TEXTURE_2D,
+           shared_memory_id_,
+           kInvalidSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformSucceeds) {
+  const GLuint kUniformIndex = 1;
+  const uint32 kBucketId = 123;
+  GetActiveUniform cmd;
+  typedef GetActiveUniform::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->success = 0;
+  cmd.Init(client_program_id_,
+           kUniformIndex,
+           kBucketId,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_NE(0, result->success);
+  EXPECT_EQ(kUniform2Size, result->size);
+  EXPECT_EQ(kUniform2Type, result->type);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
+  ASSERT_TRUE(bucket != NULL);
+  EXPECT_EQ(
+      0,
+      memcmp(
+          bucket->GetData(0, bucket->size()), kUniform2Name, bucket->size()));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformResultNotInitFails) {
+  const GLuint kUniformIndex = 1;
+  const uint32 kBucketId = 123;
+  GetActiveUniform cmd;
+  typedef GetActiveUniform::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->success = 1;
+  cmd.Init(client_program_id_,
+           kUniformIndex,
+           kBucketId,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBadProgramFails) {
+  const GLuint kUniformIndex = 1;
+  const uint32 kBucketId = 123;
+  GetActiveUniform cmd;
+  typedef GetActiveUniform::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->success = 0;
+  cmd.Init(kInvalidClientId,
+           kUniformIndex,
+           kBucketId,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0, result->success);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
+  result->success = 0;
+  cmd.Init(client_shader_id_,
+           kUniformIndex,
+           kBucketId,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0, result->success);
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBadIndexFails) {
+  const uint32 kBucketId = 123;
+  GetActiveUniform cmd;
+  typedef GetActiveUniform::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->success = 0;
+  cmd.Init(client_program_id_,
+           kBadUniformIndex,
+           kBucketId,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0, result->success);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBadSharedMemoryFails) {
+  const GLuint kUniformIndex = 1;
+  const uint32 kBucketId = 123;
+  GetActiveUniform cmd;
+  cmd.Init(client_program_id_,
+           kUniformIndex,
+           kBucketId,
+           kInvalidSharedMemoryId,
+           shared_memory_offset_);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_program_id_,
+           kUniformIndex,
+           kBucketId,
+           shared_memory_id_,
+           kInvalidSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribSucceeds) {
+  const GLuint kAttribIndex = 1;
+  const uint32 kBucketId = 123;
+  GetActiveAttrib cmd;
+  typedef GetActiveAttrib::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->success = 0;
+  cmd.Init(client_program_id_,
+           kAttribIndex,
+           kBucketId,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_NE(0, result->success);
+  EXPECT_EQ(kAttrib2Size, result->size);
+  EXPECT_EQ(kAttrib2Type, result->type);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
+  ASSERT_TRUE(bucket != NULL);
+  EXPECT_EQ(
+      0,
+      memcmp(bucket->GetData(0, bucket->size()), kAttrib2Name, bucket->size()));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribResultNotInitFails) {
+  const GLuint kAttribIndex = 1;
+  const uint32 kBucketId = 123;
+  GetActiveAttrib cmd;
+  typedef GetActiveAttrib::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->success = 1;
+  cmd.Init(client_program_id_,
+           kAttribIndex,
+           kBucketId,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribBadProgramFails) {
+  const GLuint kAttribIndex = 1;
+  const uint32 kBucketId = 123;
+  GetActiveAttrib cmd;
+  typedef GetActiveAttrib::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->success = 0;
+  cmd.Init(kInvalidClientId,
+           kAttribIndex,
+           kBucketId,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0, result->success);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
+  result->success = 0;
+  cmd.Init(client_shader_id_,
+           kAttribIndex,
+           kBucketId,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0, result->success);
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribBadIndexFails) {
+  const uint32 kBucketId = 123;
+  GetActiveAttrib cmd;
+  typedef GetActiveAttrib::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  result->success = 0;
+  cmd.Init(client_program_id_,
+           kBadAttribIndex,
+           kBucketId,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(0, result->success);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribBadSharedMemoryFails) {
+  const GLuint kAttribIndex = 1;
+  const uint32 kBucketId = 123;
+  GetActiveAttrib cmd;
+  cmd.Init(client_program_id_,
+           kAttribIndex,
+           kBucketId,
+           kInvalidSharedMemoryId,
+           shared_memory_offset_);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_program_id_,
+           kAttribIndex,
+           kBucketId,
+           shared_memory_id_,
+           kInvalidSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetShaderInfoLogValidArgs) {
+  const char* kInfo = "hello";
+  const uint32 kBucketId = 123;
+  CompileShader compile_cmd;
+  GetShaderInfoLog cmd;
+  EXPECT_CALL(*gl_, ShaderSource(kServiceShaderId, 1, _, _));
+  EXPECT_CALL(*gl_, CompileShader(kServiceShaderId));
+  EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_COMPILE_STATUS, _))
+      .WillOnce(SetArgumentPointee<2>(GL_FALSE))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_INFO_LOG_LENGTH, _))
+      .WillOnce(SetArgumentPointee<2>(strlen(kInfo) + 1))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetShaderInfoLog(kServiceShaderId, strlen(kInfo) + 1, _, _))
+      .WillOnce(DoAll(SetArgumentPointee<2>(strlen(kInfo)),
+                      SetArrayArgument<3>(kInfo, kInfo + strlen(kInfo) + 1)));
+  compile_cmd.Init(client_shader_id_);
+  cmd.Init(client_shader_id_, kBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(compile_cmd));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
+  ASSERT_TRUE(bucket != NULL);
+  EXPECT_EQ(strlen(kInfo) + 1, bucket->size());
+  EXPECT_EQ(0,
+            memcmp(bucket->GetData(0, bucket->size()), kInfo, bucket->size()));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetShaderInfoLogInvalidArgs) {
+  const uint32 kBucketId = 123;
+  GetShaderInfoLog cmd;
+  cmd.Init(kInvalidClientId, kBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, CompileShaderValidArgs) {
+  EXPECT_CALL(*gl_, ShaderSource(kServiceShaderId, 1, _, _));
+  EXPECT_CALL(*gl_, CompileShader(kServiceShaderId));
+  EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_COMPILE_STATUS, _))
+      .WillOnce(SetArgumentPointee<2>(GL_TRUE))
+      .RetiresOnSaturation();
+  CompileShader cmd;
+  cmd.Init(client_shader_id_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest, CompileShaderInvalidArgs) {
+  CompileShader cmd;
+  cmd.Init(kInvalidClientId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
+  cmd.Init(client_program_id_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
+}
+
+TEST_P(GLES2DecoderTest, ShaderSourceAndGetShaderSourceValidArgs) {
+  const uint32 kBucketId = 123;
+  const char kSource[] = "hello";
+  const uint32 kSourceSize = sizeof(kSource) - 1;
+  memcpy(shared_memory_address_, kSource, kSourceSize);
+  ShaderSource cmd;
+  cmd.Init(
+      client_shader_id_, kSharedMemoryId, kSharedMemoryOffset, kSourceSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  memset(shared_memory_address_, 0, kSourceSize);
+  GetShaderSource get_cmd;
+  get_cmd.Init(client_shader_id_, kBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(get_cmd));
+  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
+  ASSERT_TRUE(bucket != NULL);
+  EXPECT_EQ(kSourceSize + 1, bucket->size());
+  EXPECT_EQ(
+      0, memcmp(bucket->GetData(0, bucket->size()), kSource, bucket->size()));
+}
+
+TEST_P(GLES2DecoderTest, ShaderSourceInvalidArgs) {
+  const char kSource[] = "hello";
+  const uint32 kSourceSize = sizeof(kSource) - 1;
+  memcpy(shared_memory_address_, kSource, kSourceSize);
+  ShaderSource cmd;
+  cmd.Init(kInvalidClientId, kSharedMemoryId, kSharedMemoryOffset, kSourceSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
+  cmd.Init(
+      client_program_id_, kSharedMemoryId, kSharedMemoryOffset, kSourceSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+#endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
+  cmd.Init(client_shader_id_,
+           kInvalidSharedMemoryId,
+           kSharedMemoryOffset,
+           kSourceSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_shader_id_,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset,
+           kSourceSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_shader_id_,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kSharedBufferSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest, ShaderSourceBucketAndGetShaderSourceValidArgs) {
+  const uint32 kInBucketId = 123;
+  const uint32 kOutBucketId = 125;
+  const char kSource[] = "hello";
+  const uint32 kSourceSize = sizeof(kSource) - 1;
+  SetBucketAsCString(kInBucketId, kSource);
+  ShaderSourceBucket cmd;
+  cmd.Init(client_shader_id_, kInBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  ClearSharedMemory();
+  GetShaderSource get_cmd;
+  get_cmd.Init(client_shader_id_, kOutBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(get_cmd));
+  CommonDecoder::Bucket* bucket = decoder_->GetBucket(kOutBucketId);
+  ASSERT_TRUE(bucket != NULL);
+  EXPECT_EQ(kSourceSize + 1, bucket->size());
+  EXPECT_EQ(
+      0, memcmp(bucket->GetData(0, bucket->size()), kSource, bucket->size()));
+}
+
+TEST_P(GLES2DecoderTest, ShaderSourceBucketInvalidArgs) {
+  const uint32 kBucketId = 123;
+  const char kSource[] = "hello";
+  const uint32 kSourceSize = sizeof(kSource) - 1;
+  memcpy(shared_memory_address_, kSource, kSourceSize);
+  ShaderSourceBucket cmd;
+  // Test no bucket.
+  cmd.Init(client_texture_id_, kBucketId);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  // Test invalid client.
+  SetBucketAsCString(kBucketId, kSource);
+  cmd.Init(kInvalidClientId, kBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, ShaderSourceStripComments) {
+  const uint32 kInBucketId = 123;
+  const char kSource[] = "hello/*te\ast*/world//a\ab";
+  SetBucketAsCString(kInBucketId, kSource);
+  ShaderSourceBucket cmd;
+  cmd.Init(client_shader_id_, kInBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, Uniform1iValidArgs) {
+  EXPECT_CALL(*gl_, Uniform1i(kUniform1RealLocation, 2));
+  Uniform1i cmd;
+  cmd.Init(kUniform1FakeLocation, 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, Uniform1ivValidArgs) {
+  EXPECT_CALL(
+      *gl_,
+      Uniform1iv(kUniform1RealLocation,
+                 1,
+                 reinterpret_cast<const GLint*>(shared_memory_address_)));
+  Uniform1iv cmd;
+  cmd.Init(kUniform1FakeLocation, 1, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, Uniform1ivInvalidArgs2_0) {
+  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
+  Uniform1iv cmd;
+  cmd.Init(kUniform1FakeLocation, 1, kInvalidSharedMemoryId, 0);
+  EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, Uniform1ivInvalidArgs2_1) {
+  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
+  Uniform1iv cmd;
+  cmd.Init(
+      kUniform1FakeLocation, 1, shared_memory_id_, kInvalidSharedMemoryOffset);
+  EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, Uniform1ivImmediateValidArgs) {
+  Uniform1ivImmediate& cmd = *GetImmediateAs<Uniform1ivImmediate>();
+  EXPECT_CALL(*gl_,
+              Uniform1iv(kUniform1RealLocation,
+                         1,
+                         reinterpret_cast<GLint*>(ImmediateDataAddress(&cmd))));
+  GLint temp[1 * 2] = {
+      0,
+  };
+  cmd.Init(kUniform1FakeLocation, 1, &temp[0]);
+  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, Uniform1ivInvalidValidArgs) {
+  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
+  Uniform1iv cmd;
+  cmd.Init(kUniform1FakeLocation, 2, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, Uniform1ivZeroCount) {
+  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
+  Uniform1iv cmd;
+  cmd.Init(kUniform1FakeLocation, 0, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, Uniform1iSamplerIsLmited) {
+  EXPECT_CALL(*gl_, Uniform1i(_, _)).Times(0);
+  Uniform1i cmd;
+  cmd.Init(kUniform1FakeLocation, kNumTextureUnits);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, Uniform1ivSamplerIsLimited) {
+  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
+  Uniform1ivImmediate& cmd = *GetImmediateAs<Uniform1ivImmediate>();
+  GLint temp[] = {kNumTextureUnits};
+  cmd.Init(kUniform1FakeLocation, 1, &temp[0]);
+  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, BindAttribLocation) {
+  const GLint kLocation = 2;
+  const char* kName = "testing";
+  const uint32 kNameSize = strlen(kName);
+  EXPECT_CALL(*gl_,
+              BindAttribLocation(kServiceProgramId, kLocation, StrEq(kName)))
+      .Times(1);
+  memcpy(shared_memory_address_, kName, kNameSize);
+  BindAttribLocation cmd;
+  cmd.Init(client_program_id_,
+           kLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest, BindAttribLocationInvalidArgs) {
+  const GLint kLocation = 2;
+  const char* kName = "testing";
+  const char* kBadName = "test\aing";
+  const uint32 kNameSize = strlen(kName);
+  const uint32 kBadNameSize = strlen(kBadName);
+  EXPECT_CALL(*gl_, BindAttribLocation(_, _, _)).Times(0);
+  memcpy(shared_memory_address_, kName, kNameSize);
+  BindAttribLocation cmd;
+  cmd.Init(kInvalidClientId,
+           kLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(client_program_id_,
+           kLocation,
+           kInvalidSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_program_id_,
+           kLocation,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset,
+           kNameSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_program_id_,
+           kLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kSharedBufferSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  memcpy(shared_memory_address_, kBadName, kBadNameSize);
+  cmd.Init(client_program_id_,
+           kLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kBadNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, BindAttribLocationBucket) {
+  const uint32 kBucketId = 123;
+  const GLint kLocation = 2;
+  const char* kName = "testing";
+  EXPECT_CALL(*gl_,
+              BindAttribLocation(kServiceProgramId, kLocation, StrEq(kName)))
+      .Times(1);
+  SetBucketAsCString(kBucketId, kName);
+  BindAttribLocationBucket cmd;
+  cmd.Init(client_program_id_, kLocation, kBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest, BindAttribLocationBucketInvalidArgs) {
+  const uint32 kBucketId = 123;
+  const GLint kLocation = 2;
+  const char* kName = "testing";
+  EXPECT_CALL(*gl_, BindAttribLocation(_, _, _)).Times(0);
+  BindAttribLocationBucket cmd;
+  // check bucket does not exist.
+  cmd.Init(client_program_id_, kLocation, kBucketId);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  // check bucket is empty.
+  SetBucketAsCString(kBucketId, NULL);
+  cmd.Init(client_program_id_, kLocation, kBucketId);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  // Check bad program id
+  SetBucketAsCString(kBucketId, kName);
+  cmd.Init(kInvalidClientId, kLocation, kBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetAttribLocation) {
+  const uint32 kNameSize = strlen(kAttrib2Name);
+  const char* kNonExistentName = "foobar";
+  const uint32 kNonExistentNameSize = strlen(kNonExistentName);
+  typedef GetAttribLocation::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  *result = -1;
+  char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
+  const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
+  memcpy(name, kAttrib2Name, kNameSize);
+  GetAttribLocation cmd;
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(kAttrib2Location, *result);
+  *result = -1;
+  memcpy(name, kNonExistentName, kNonExistentNameSize);
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNonExistentNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetAttribLocationInvalidArgs) {
+  const uint32 kNameSize = strlen(kAttrib2Name);
+  const char* kBadName = "foo\abar";
+  const uint32 kBadNameSize = strlen(kBadName);
+  typedef GetAttribLocation::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  *result = -1;
+  char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
+  const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
+  memcpy(name, kAttrib2Name, kNameSize);
+  GetAttribLocation cmd;
+  cmd.Init(kInvalidClientId,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  *result = -1;
+  cmd.Init(client_program_id_,
+           kInvalidSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kInvalidSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset,
+           kNameSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kSharedBufferSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  memcpy(name, kBadName, kBadNameSize);
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kBadNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetAttribLocationBucket) {
+  const uint32 kBucketId = 123;
+  const char* kNonExistentName = "foobar";
+  typedef GetAttribLocationBucket::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  SetBucketAsCString(kBucketId, kAttrib2Name);
+  *result = -1;
+  GetAttribLocationBucket cmd;
+  cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(kAttrib2Location, *result);
+  SetBucketAsCString(kBucketId, kNonExistentName);
+  *result = -1;
+  cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetAttribLocationBucketInvalidArgs) {
+  const uint32 kBucketId = 123;
+  typedef GetAttribLocationBucket::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  *result = -1;
+  GetAttribLocationBucket cmd;
+  // Check no bucket
+  cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  // Check bad program id.
+  SetBucketAsCString(kBucketId, kAttrib2Name);
+  cmd.Init(kInvalidClientId, kBucketId, kSharedMemoryId, kSharedMemoryOffset);
+  *result = -1;
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  // Check bad memory
+  cmd.Init(client_program_id_,
+           kBucketId,
+           kInvalidSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_program_id_,
+           kBucketId,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformLocation) {
+  const uint32 kNameSize = strlen(kUniform2Name);
+  const char* kNonExistentName = "foobar";
+  const uint32 kNonExistentNameSize = strlen(kNonExistentName);
+  typedef GetUniformLocation::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  *result = -1;
+  char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
+  const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
+  memcpy(name, kUniform2Name, kNameSize);
+  GetUniformLocation cmd;
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(kUniform2FakeLocation, *result);
+  memcpy(name, kNonExistentName, kNonExistentNameSize);
+  *result = -1;
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNonExistentNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformLocationInvalidArgs) {
+  const uint32 kNameSize = strlen(kUniform2Name);
+  const char* kBadName = "foo\abar";
+  const uint32 kBadNameSize = strlen(kBadName);
+  typedef GetUniformLocation::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  *result = -1;
+  char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
+  const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
+  memcpy(name, kUniform2Name, kNameSize);
+  GetUniformLocation cmd;
+  cmd.Init(kInvalidClientId,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  *result = -1;
+  cmd.Init(client_program_id_,
+           kInvalidSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kInvalidSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset,
+           kNameSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kSharedBufferSize);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  memcpy(name, kBadName, kBadNameSize);
+  cmd.Init(client_program_id_,
+           kSharedMemoryId,
+           kNameOffset,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kBadNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformLocationBucket) {
+  const uint32 kBucketId = 123;
+  const char* kNonExistentName = "foobar";
+  typedef GetUniformLocationBucket::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  SetBucketAsCString(kBucketId, kUniform2Name);
+  *result = -1;
+  GetUniformLocationBucket cmd;
+  cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(kUniform2FakeLocation, *result);
+  SetBucketAsCString(kBucketId, kNonExistentName);
+  *result = -1;
+  cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+}
+
+TEST_P(GLES2DecoderWithShaderTest, GetUniformLocationBucketInvalidArgs) {
+  const uint32 kBucketId = 123;
+  typedef GetUniformLocationBucket::Result Result;
+  Result* result = GetSharedMemoryAs<Result*>();
+  *result = -1;
+  GetUniformLocationBucket cmd;
+  // Check no bucket
+  cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  // Check bad program id.
+  SetBucketAsCString(kBucketId, kUniform2Name);
+  cmd.Init(kInvalidClientId, kBucketId, kSharedMemoryId, kSharedMemoryOffset);
+  *result = -1;
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(-1, *result);
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  // Check bad memory
+  cmd.Init(client_program_id_,
+           kBucketId,
+           kInvalidSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(client_program_id_,
+           kBucketId,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderWithShaderTest, BindUniformLocationCHROMIUM) {
+  const GLint kLocation = 2;
+  const char* kName = "testing";
+  const uint32 kNameSize = strlen(kName);
+  const char* kBadName1 = "gl_testing";
+  const uint32 kBadName1Size = strlen(kBadName1);
+  const char* kBadName2 = "testing[1]";
+  const uint32 kBadName2Size = strlen(kBadName2);
+  memcpy(shared_memory_address_, kName, kNameSize);
+  BindUniformLocationCHROMIUM cmd;
+  cmd.Init(client_program_id_,
+           kLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  // check negative location
+  memcpy(shared_memory_address_, kName, kNameSize);
+  cmd.Init(
+      client_program_id_, -1, kSharedMemoryId, kSharedMemoryOffset, kNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  // check highest location
+  memcpy(shared_memory_address_, kName, kNameSize);
+  GLint kMaxLocation =
+      (kMaxFragmentUniformVectors + kMaxVertexUniformVectors) * 4 - 1;
+  cmd.Init(client_program_id_,
+           kMaxLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  // check too high location
+  memcpy(shared_memory_address_, kName, kNameSize);
+  cmd.Init(client_program_id_,
+           kMaxLocation + 1,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kNameSize);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  // check bad name "gl_..."
+  memcpy(shared_memory_address_, kBadName1, kBadName1Size);
+  cmd.Init(client_program_id_,
+           kLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kBadName1Size);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  // check bad name "name[1]" non zero
+  memcpy(shared_memory_address_, kBadName2, kBadName2Size);
+  cmd.Init(client_program_id_,
+           kLocation,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           kBadName2Size);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, ClearUniformsBeforeFirstProgramUse) {
+  CommandLine command_line(0, NULL);
+  command_line.AppendSwitchASCII(
+      switches::kGpuDriverBugWorkarounds,
+      base::IntToString(gpu::CLEAR_UNIFORMS_BEFORE_FIRST_PROGRAM_USE));
+  InitState init;
+  init.gl_version = "3.0";
+  init.has_alpha = true;
+  init.request_alpha = true;
+  init.bind_generates_resource = true;
+  InitDecoderWithCommandLine(init, &command_line);
+  {
+    static AttribInfo attribs[] = {
+        {
+         kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location,
+        },
+        {
+         kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location,
+        },
+        {
+         kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location,
+        },
+    };
+    static UniformInfo uniforms[] = {
+        {kUniform1Name, kUniform1Size, kUniform1Type, kUniform1FakeLocation,
+         kUniform1RealLocation, kUniform1DesiredLocation},
+        {kUniform2Name, kUniform2Size, kUniform2Type, kUniform2FakeLocation,
+         kUniform2RealLocation, kUniform2DesiredLocation},
+        {kUniform3Name, kUniform3Size, kUniform3Type, kUniform3FakeLocation,
+         kUniform3RealLocation, kUniform3DesiredLocation},
+    };
+    SetupShader(attribs,
+                arraysize(attribs),
+                uniforms,
+                arraysize(uniforms),
+                client_program_id_,
+                kServiceProgramId,
+                client_vertex_shader_id_,
+                kServiceVertexShaderId,
+                client_fragment_shader_id_,
+                kServiceFragmentShaderId);
+    TestHelper::SetupExpectationsForClearingUniforms(
+        gl_.get(), uniforms, arraysize(uniforms));
+  }
+
+  {
+    EXPECT_CALL(*gl_, UseProgram(kServiceProgramId))
+        .Times(1)
+        .RetiresOnSaturation();
+    cmds::UseProgram cmd;
+    cmd.Init(client_program_id_);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  }
+}
+
+// TODO(gman): DeleteProgram
+
+// TODO(gman): UseProgram
+
+// TODO(gman): DeleteShader
+
+}  // namespace gles2
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
new file mode 100644
index 0000000..a9af8a1
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
@@ -0,0 +1,2744 @@
+// 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.
+
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "gpu/command_buffer/common/gles2_cmd_format.h"
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/common/id_allocator.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
+#include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
+#include "gpu/command_buffer/service/cmd_buffer_engine.h"
+#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/context_state.h"
+#include "gpu/command_buffer/service/gl_surface_mock.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
+
+#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/image_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/mocks.h"
+#include "gpu/command_buffer/service/program_manager.h"
+#include "gpu/command_buffer/service/test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_mock.h"
+#include "ui/gl/gl_surface_stub.h"
+
+#if !defined(GL_DEPTH24_STENCIL8)
+#define GL_DEPTH24_STENCIL8 0x88F0
+#endif
+
+using ::gfx::MockGLInterface;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::MatcherCast;
+using ::testing::Mock;
+using ::testing::Pointee;
+using ::testing::Return;
+using ::testing::SaveArg;
+using ::testing::SetArrayArgument;
+using ::testing::SetArgumentPointee;
+using ::testing::SetArgPointee;
+using ::testing::StrEq;
+using ::testing::StrictMock;
+
+namespace gpu {
+namespace gles2 {
+
+using namespace cmds;
+
+TEST_P(GLES2DecoderTest, GenerateMipmapWrongFormatsFails) {
+  EXPECT_CALL(*gl_, GenerateMipmapEXT(_)).Times(0);
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  GenerateMipmap cmd;
+  cmd.Init(GL_TEXTURE_2D);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, GenerateMipmapHandlesOutOfMemory) {
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  TextureManager* manager = group().texture_manager();
+  TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
+  ASSERT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  GLint width = 0;
+  GLint height = 0;
+  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 2, &width, &height));
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGBA,
+               16,
+               16,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
+  EXPECT_CALL(*gl_, GenerateMipmapEXT(GL_TEXTURE_2D)).Times(1);
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_OUT_OF_MEMORY))
+      .RetiresOnSaturation();
+  GenerateMipmap cmd;
+  cmd.Init(GL_TEXTURE_2D);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 2, &width, &height));
+}
+
+TEST_P(GLES2DecoderTest, GenerateMipmapClearsUnclearedTexture) {
+  EXPECT_CALL(*gl_, GenerateMipmapEXT(_)).Times(0);
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_2D,
+                                GL_TEXTURE_2D,
+                                0,
+                                GL_RGBA,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                2,
+                                2);
+  EXPECT_CALL(*gl_, GenerateMipmapEXT(GL_TEXTURE_2D));
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  GenerateMipmap cmd;
+  cmd.Init(GL_TEXTURE_2D);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+// Same as GenerateMipmapClearsUnclearedTexture, but with workaround
+// |set_texture_filters_before_generating_mipmap|.
+TEST_P(GLES2DecoderManualInitTest, SetTextureFiltersBeforeGenerateMipmap) {
+  CommandLine command_line(0, NULL);
+  command_line.AppendSwitchASCII(
+      switches::kGpuDriverBugWorkarounds,
+      base::IntToString(gpu::SET_TEXTURE_FILTER_BEFORE_GENERATING_MIPMAP));
+  InitState init;
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoderWithCommandLine(init, &command_line);
+
+  EXPECT_CALL(*gl_, GenerateMipmapEXT(_)).Times(0);
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_2D,
+                                GL_TEXTURE_2D,
+                                0,
+                                GL_RGBA,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                2,
+                                2);
+  EXPECT_CALL(
+      *gl_,
+      TexParameteri(
+          GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GenerateMipmapEXT(GL_TEXTURE_2D));
+  EXPECT_CALL(
+      *gl_,
+      TexParameteri(
+          GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  GenerateMipmap cmd;
+  cmd.Init(GL_TEXTURE_2D);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, ActiveTextureValidArgs) {
+  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
+  SpecializedSetup<ActiveTexture, 0>(true);
+  ActiveTexture cmd;
+  cmd.Init(GL_TEXTURE1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, ActiveTextureInvalidArgs) {
+  EXPECT_CALL(*gl_, ActiveTexture(_)).Times(0);
+  SpecializedSetup<ActiveTexture, 0>(false);
+  ActiveTexture cmd;
+  cmd.Init(GL_TEXTURE0 - 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  cmd.Init(kNumTextureUnits);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, TexSubImage2DValidArgs) {
+  const int kWidth = 16;
+  const int kHeight = 8;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D,
+               1,
+               GL_RGBA,
+               kWidth,
+               kHeight,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
+  EXPECT_CALL(*gl_,
+              TexSubImage2D(GL_TEXTURE_2D,
+                            1,
+                            1,
+                            0,
+                            kWidth - 1,
+                            kHeight,
+                            GL_RGBA,
+                            GL_UNSIGNED_BYTE,
+                            shared_memory_address_))
+      .Times(1)
+      .RetiresOnSaturation();
+  TexSubImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           1,
+           0,
+           kWidth - 1,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, TexSubImage2DBadArgs) {
+  const int kWidth = 16;
+  const int kHeight = 8;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D,
+               1,
+               GL_RGBA,
+               kWidth,
+               kHeight,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               0,
+               0);
+  TexSubImage2D cmd;
+  cmd.Init(GL_TEXTURE0,
+           1,
+           0,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           0,
+           0,
+           kWidth,
+           kHeight,
+           GL_TRUE,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           0,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_INT,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           -1,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           1,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           0,
+           -1,
+           kWidth,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           0,
+           1,
+           kWidth,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           0,
+           0,
+           kWidth + 1,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           0,
+           0,
+           kWidth,
+           kHeight + 1,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           0,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGB,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           0,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_SHORT_4_4_4_4,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           0,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kInvalidSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  cmd.Init(GL_TEXTURE_2D,
+           1,
+           0,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kInvalidSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest, CopyTexSubImage2DValidArgs) {
+  const int kWidth = 16;
+  const int kHeight = 8;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D,
+               1,
+               GL_RGBA,
+               kWidth,
+               kHeight,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
+  EXPECT_CALL(*gl_,
+              CopyTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth, kHeight))
+      .Times(1)
+      .RetiresOnSaturation();
+  CopyTexSubImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth, kHeight);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, CopyTexSubImage2DBadArgs) {
+  const int kWidth = 16;
+  const int kHeight = 8;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D,
+               1,
+               GL_RGBA,
+               kWidth,
+               kHeight,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               0,
+               0);
+  CopyTexSubImage2D cmd;
+  cmd.Init(GL_TEXTURE0, 1, 0, 0, 0, 0, kWidth, kHeight);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+  cmd.Init(GL_TEXTURE_2D, 1, -1, 0, 0, 0, kWidth, kHeight);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_TEXTURE_2D, 1, 1, 0, 0, 0, kWidth, kHeight);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_TEXTURE_2D, 1, 0, -1, 0, 0, kWidth, kHeight);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_TEXTURE_2D, 1, 0, 1, 0, 0, kWidth, kHeight);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth + 1, kHeight);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  cmd.Init(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth, kHeight + 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, TexImage2DRedefinitionSucceeds) {
+  const int kWidth = 16;
+  const int kHeight = 8;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  EXPECT_CALL(*gl_, GetError()).WillRepeatedly(Return(GL_NO_ERROR));
+  for (int ii = 0; ii < 2; ++ii) {
+    TexImage2D cmd;
+    if (ii == 0) {
+      EXPECT_CALL(*gl_,
+                  TexImage2D(GL_TEXTURE_2D,
+                             0,
+                             GL_RGBA,
+                             kWidth,
+                             kHeight,
+                             0,
+                             GL_RGBA,
+                             GL_UNSIGNED_BYTE,
+                             _))
+          .Times(1)
+          .RetiresOnSaturation();
+      cmd.Init(GL_TEXTURE_2D,
+               0,
+               GL_RGBA,
+               kWidth,
+               kHeight,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
+    } else {
+      SetupClearTextureExpectations(kServiceTextureId,
+                                    kServiceTextureId,
+                                    GL_TEXTURE_2D,
+                                    GL_TEXTURE_2D,
+                                    0,
+                                    GL_RGBA,
+                                    GL_RGBA,
+                                    GL_UNSIGNED_BYTE,
+                                    kWidth,
+                                    kHeight);
+      cmd.Init(GL_TEXTURE_2D,
+               0,
+               GL_RGBA,
+               kWidth,
+               kHeight,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               0,
+               0);
+    }
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_CALL(*gl_,
+                TexSubImage2D(GL_TEXTURE_2D,
+                              0,
+                              0,
+                              0,
+                              kWidth,
+                              kHeight - 1,
+                              GL_RGBA,
+                              GL_UNSIGNED_BYTE,
+                              shared_memory_address_))
+        .Times(1)
+        .RetiresOnSaturation();
+    // Consider this TexSubImage2D command part of the previous TexImage2D
+    // (last GL_TRUE argument). It will be skipped if there are bugs in the
+    // redefinition case.
+    TexSubImage2D cmd2;
+    cmd2.Init(GL_TEXTURE_2D,
+              0,
+              0,
+              0,
+              kWidth,
+              kHeight - 1,
+              GL_RGBA,
+              GL_UNSIGNED_BYTE,
+              kSharedMemoryId,
+              kSharedMemoryOffset,
+              GL_TRUE);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  }
+}
+
+TEST_P(GLES2DecoderTest, TexImage2DGLError) {
+  GLenum target = GL_TEXTURE_2D;
+  GLint level = 0;
+  GLenum internal_format = GL_RGBA;
+  GLsizei width = 2;
+  GLsizei height = 4;
+  GLint border = 0;
+  GLenum format = GL_RGBA;
+  GLenum type = GL_UNSIGNED_BYTE;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  TextureManager* manager = group().texture_manager();
+  TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
+  ASSERT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_OUT_OF_MEMORY))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              TexImage2D(target,
+                         level,
+                         internal_format,
+                         width,
+                         height,
+                         border,
+                         format,
+                         type,
+                         _))
+      .Times(1)
+      .RetiresOnSaturation();
+  TexImage2D cmd;
+  cmd.Init(target,
+           level,
+           internal_format,
+           width,
+           height,
+           border,
+           format,
+           type,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
+}
+
+TEST_P(GLES2DecoderTest, CopyTexImage2DGLError) {
+  GLenum target = GL_TEXTURE_2D;
+  GLint level = 0;
+  GLenum internal_format = GL_RGBA;
+  GLsizei width = 2;
+  GLsizei height = 4;
+  GLint border = 0;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  TextureManager* manager = group().texture_manager();
+  TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
+  ASSERT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_OUT_OF_MEMORY))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              CopyTexImage2D(
+                  target, level, internal_format, 0, 0, width, height, border))
+      .Times(1)
+      .RetiresOnSaturation();
+  CopyTexImage2D cmd;
+  cmd.Init(target, level, internal_format, 0, 0, width, height, border);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+  EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
+}
+
+TEST_P(GLES2DecoderManualInitTest, CompressedTexImage2DBucketBadBucket) {
+  InitState init;
+  init.extensions = "GL_EXT_texture_compression_s3tc";
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  const uint32 kBadBucketId = 123;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  CompressedTexImage2DBucket cmd;
+  cmd.Init(GL_TEXTURE_2D,
+           0,
+           GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
+           4,
+           4,
+           0,
+           kBadBucketId);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+  CompressedTexSubImage2DBucket cmd2;
+  cmd2.Init(GL_TEXTURE_2D,
+            0,
+            0,
+            0,
+            4,
+            4,
+            GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
+            kBadBucketId);
+  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
+}
+
+namespace {
+
+struct S3TCTestData {
+  GLenum format;
+  size_t block_size;
+};
+
+}  // anonymous namespace.
+
+TEST_P(GLES2DecoderManualInitTest, CompressedTexImage2DS3TC) {
+  InitState init;
+  init.extensions = "GL_EXT_texture_compression_s3tc";
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  const uint32 kBucketId = 123;
+  CommonDecoder::Bucket* bucket = decoder_->CreateBucket(kBucketId);
+  ASSERT_TRUE(bucket != NULL);
+
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+
+  static const S3TCTestData test_data[] = {
+      {
+       GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8,
+      },
+      {
+       GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8,
+      },
+      {
+       GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 16,
+      },
+      {
+       GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 16,
+      },
+  };
+
+  for (size_t ii = 0; ii < arraysize(test_data); ++ii) {
+    const S3TCTestData& test = test_data[ii];
+    CompressedTexImage2DBucket cmd;
+    // test small width.
+    DoCompressedTexImage2D(
+        GL_TEXTURE_2D, 0, test.format, 2, 4, 0, test.block_size, kBucketId);
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    // test bad width.
+    cmd.Init(GL_TEXTURE_2D, 0, test.format, 5, 4, 0, kBucketId);
+    bucket->SetSize(test.block_size * 2);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+    // test small height.
+    DoCompressedTexImage2D(
+        GL_TEXTURE_2D, 0, test.format, 4, 2, 0, test.block_size, kBucketId);
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    // test too bad height.
+    cmd.Init(GL_TEXTURE_2D, 0, test.format, 4, 5, 0, kBucketId);
+    bucket->SetSize(test.block_size * 2);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+    // test small for level 0.
+    DoCompressedTexImage2D(
+        GL_TEXTURE_2D, 0, test.format, 1, 1, 0, test.block_size, kBucketId);
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    // test small for level 0.
+    DoCompressedTexImage2D(
+        GL_TEXTURE_2D, 0, test.format, 2, 2, 0, test.block_size, kBucketId);
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    // test size too large.
+    cmd.Init(GL_TEXTURE_2D, 0, test.format, 4, 4, 0, kBucketId);
+    bucket->SetSize(test.block_size * 2);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+
+    // test size too small.
+    cmd.Init(GL_TEXTURE_2D, 0, test.format, 4, 4, 0, kBucketId);
+    bucket->SetSize(test.block_size / 2);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+
+    // test with 3 mips.
+    DoCompressedTexImage2D(
+        GL_TEXTURE_2D, 0, test.format, 4, 4, 0, test.block_size, kBucketId);
+    DoCompressedTexImage2D(
+        GL_TEXTURE_2D, 1, test.format, 2, 2, 0, test.block_size, kBucketId);
+    DoCompressedTexImage2D(
+        GL_TEXTURE_2D, 2, test.format, 1, 1, 0, test.block_size, kBucketId);
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    // Test a 16x16
+    DoCompressedTexImage2D(GL_TEXTURE_2D,
+                           0,
+                           test.format,
+                           16,
+                           16,
+                           0,
+                           test.block_size * 4 * 4,
+                           kBucketId);
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    CompressedTexSubImage2DBucket sub_cmd;
+    bucket->SetSize(test.block_size);
+    // Test sub image bad xoffset
+    sub_cmd.Init(GL_TEXTURE_2D, 0, 1, 0, 4, 4, test.format, kBucketId);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
+    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+    // Test sub image bad yoffset
+    sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 2, 4, 4, test.format, kBucketId);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
+    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+    // Test sub image bad width
+    bucket->SetSize(test.block_size * 2);
+    sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 5, 4, test.format, kBucketId);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
+    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+    // Test sub image bad height
+    sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 4, 5, test.format, kBucketId);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
+    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+    // Test sub image bad size
+    bucket->SetSize(test.block_size + 1);
+    sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 4, 4, test.format, kBucketId);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+
+    for (GLint yoffset = 0; yoffset <= 8; yoffset += 4) {
+      for (GLint xoffset = 0; xoffset <= 8; xoffset += 4) {
+        for (GLsizei height = 4; height <= 8; height += 4) {
+          for (GLsizei width = 4; width <= 8; width += 4) {
+            GLsizei size = test.block_size * (width / 4) * (height / 4);
+            bucket->SetSize(size);
+            EXPECT_CALL(*gl_,
+                        CompressedTexSubImage2D(GL_TEXTURE_2D,
+                                                0,
+                                                xoffset,
+                                                yoffset,
+                                                width,
+                                                height,
+                                                test.format,
+                                                size,
+                                                _))
+                .Times(1)
+                .RetiresOnSaturation();
+            sub_cmd.Init(GL_TEXTURE_2D,
+                         0,
+                         xoffset,
+                         yoffset,
+                         width,
+                         height,
+                         test.format,
+                         kBucketId);
+            EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
+            EXPECT_EQ(GL_NO_ERROR, GetGLError());
+          }
+        }
+      }
+    }
+  }
+}
+
+TEST_P(GLES2DecoderManualInitTest, CompressedTexImage2DETC1) {
+  InitState init;
+  init.extensions = "GL_OES_compressed_ETC1_RGB8_texture";
+  init.gl_version = "opengl es 2.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  const uint32 kBucketId = 123;
+  CommonDecoder::Bucket* bucket = decoder_->CreateBucket(kBucketId);
+  ASSERT_TRUE(bucket != NULL);
+
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+
+  const GLenum kFormat = GL_ETC1_RGB8_OES;
+  const size_t kBlockSize = 8;
+
+  CompressedTexImage2DBucket cmd;
+  // test small width.
+  DoCompressedTexImage2D(GL_TEXTURE_2D, 0, kFormat, 4, 8, 0, 16, kBucketId);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // test small height.
+  DoCompressedTexImage2D(GL_TEXTURE_2D, 0, kFormat, 8, 4, 0, 16, kBucketId);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // test size too large.
+  cmd.Init(GL_TEXTURE_2D, 0, kFormat, 4, 4, 0, kBucketId);
+  bucket->SetSize(kBlockSize * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+
+  // test size too small.
+  cmd.Init(GL_TEXTURE_2D, 0, kFormat, 4, 4, 0, kBucketId);
+  bucket->SetSize(kBlockSize / 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+
+  // Test a 16x16
+  DoCompressedTexImage2D(
+      GL_TEXTURE_2D, 0, kFormat, 16, 16, 0, kBlockSize * 16, kBucketId);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Test CompressedTexSubImage not allowed
+  CompressedTexSubImage2DBucket sub_cmd;
+  bucket->SetSize(kBlockSize);
+  sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 4, 4, kFormat, kBucketId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+  // Test TexSubImage not allowed for ETC1 compressed texture
+  TextureRef* texture_ref = GetTexture(client_texture_id_);
+  ASSERT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  GLenum type, internal_format;
+  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
+  EXPECT_EQ(kFormat, internal_format);
+  TexSubImage2D texsub_cmd;
+  texsub_cmd.Init(GL_TEXTURE_2D,
+                  0,
+                  0,
+                  0,
+                  4,
+                  4,
+                  GL_RGBA,
+                  GL_UNSIGNED_BYTE,
+                  kSharedMemoryId,
+                  kSharedMemoryOffset,
+                  GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(texsub_cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+  // Test CopyTexSubImage not allowed for ETC1 compressed texture
+  CopyTexSubImage2D copy_cmd;
+  copy_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, EGLImageExternalBindTexture) {
+  InitState init;
+  init.extensions = "GL_OES_EGL_image_external";
+  init.gl_version = "opengl es 2.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_EXTERNAL_OES, kNewServiceId));
+  EXPECT_CALL(*gl_, GenTextures(1, _))
+      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
+  BindTexture cmd;
+  cmd.Init(GL_TEXTURE_EXTERNAL_OES, kNewClientId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  TextureRef* texture_ref = GetTexture(kNewClientId);
+  EXPECT_TRUE(texture_ref != NULL);
+  EXPECT_TRUE(texture_ref->texture()->target() == GL_TEXTURE_EXTERNAL_OES);
+}
+
+TEST_P(GLES2DecoderManualInitTest, EGLImageExternalGetBinding) {
+  InitState init;
+  init.extensions = "GL_OES_EGL_image_external";
+  init.gl_version = "opengl es 2.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_,
+              GetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, result->GetData()))
+      .Times(0);
+  result->size = 0;
+  GetIntegerv cmd;
+  cmd.Init(GL_TEXTURE_BINDING_EXTERNAL_OES,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
+                GL_TEXTURE_BINDING_EXTERNAL_OES),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(client_texture_id_, (uint32)result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, EGLImageExternalTextureDefaults) {
+  InitState init;
+  init.extensions = "GL_OES_EGL_image_external";
+  init.gl_version = "opengl es 2.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
+
+  TextureRef* texture_ref = GetTexture(client_texture_id_);
+  EXPECT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  EXPECT_TRUE(texture->target() == GL_TEXTURE_EXTERNAL_OES);
+  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
+  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
+  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
+}
+
+TEST_P(GLES2DecoderManualInitTest, EGLImageExternalTextureParam) {
+  InitState init;
+  init.extensions = "GL_OES_EGL_image_external";
+  init.gl_version = "opengl es 2.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
+
+  EXPECT_CALL(*gl_,
+              TexParameteri(
+                  GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
+  EXPECT_CALL(
+      *gl_,
+      TexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+  EXPECT_CALL(
+      *gl_,
+      TexParameteri(
+          GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+  EXPECT_CALL(
+      *gl_,
+      TexParameteri(
+          GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+  TexParameteri cmd;
+  cmd.Init(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  cmd.Init(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  cmd.Init(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  cmd.Init(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  TextureRef* texture_ref = GetTexture(client_texture_id_);
+  EXPECT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  EXPECT_TRUE(texture->target() == GL_TEXTURE_EXTERNAL_OES);
+  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
+  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
+  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
+}
+
+TEST_P(GLES2DecoderManualInitTest, EGLImageExternalTextureParamInvalid) {
+  InitState init;
+  init.extensions = "GL_OES_EGL_image_external";
+  init.gl_version = "opengl es 2.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
+
+  TexParameteri cmd;
+  cmd.Init(GL_TEXTURE_EXTERNAL_OES,
+           GL_TEXTURE_MIN_FILTER,
+           GL_NEAREST_MIPMAP_NEAREST);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+
+  cmd.Init(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+
+  cmd.Init(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_REPEAT);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+
+  TextureRef* texture_ref = GetTexture(client_texture_id_);
+  EXPECT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  EXPECT_TRUE(texture->target() == GL_TEXTURE_EXTERNAL_OES);
+  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
+  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
+  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
+}
+
+TEST_P(GLES2DecoderManualInitTest, EGLImageExternalTexImage2DError) {
+  InitState init;
+  init.extensions = "GL_OES_EGL_image_external";
+  init.gl_version = "opengl es 2.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  GLenum target = GL_TEXTURE_EXTERNAL_OES;
+  GLint level = 0;
+  GLenum internal_format = GL_RGBA;
+  GLsizei width = 2;
+  GLsizei height = 4;
+  GLint border = 0;
+  GLenum format = GL_RGBA;
+  GLenum type = GL_UNSIGNED_BYTE;
+  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
+  ASSERT_TRUE(GetTexture(client_texture_id_) != NULL);
+  TexImage2D cmd;
+  cmd.Init(target,
+           level,
+           internal_format,
+           width,
+           height,
+           border,
+           format,
+           type,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+
+  // TexImage2D is not allowed with GL_TEXTURE_EXTERNAL_OES targets.
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, DefaultTextureZero) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+
+  BindTexture cmd1;
+  cmd1.Init(GL_TEXTURE_2D, 0);
+  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  BindTexture cmd2;
+  cmd2.Init(GL_TEXTURE_CUBE_MAP, 0);
+  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, 0));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, DefaultTextureBGR) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  BindTexture cmd1;
+  cmd1.Init(GL_TEXTURE_2D, 0);
+  EXPECT_CALL(
+      *gl_, BindTexture(GL_TEXTURE_2D, TestHelper::kServiceDefaultTexture2dId));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  BindTexture cmd2;
+  cmd2.Init(GL_TEXTURE_CUBE_MAP, 0);
+  EXPECT_CALL(*gl_,
+              BindTexture(GL_TEXTURE_CUBE_MAP,
+                          TestHelper::kServiceDefaultTextureCubemapId));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+// Test that default texture 0 is immutable.
+TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameterf) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+
+  {
+    BindTexture cmd1;
+    cmd1.Init(GL_TEXTURE_2D, 0);
+    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    TexParameterf cmd2;
+    cmd2.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  }
+
+  {
+    BindTexture cmd1;
+    cmd1.Init(GL_TEXTURE_CUBE_MAP, 0);
+    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, 0));
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    TexParameterf cmd2;
+    cmd2.Init(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  }
+}
+
+TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameteri) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+
+  {
+    BindTexture cmd1;
+    cmd1.Init(GL_TEXTURE_2D, 0);
+    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    TexParameteri cmd2;
+    cmd2.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  }
+
+  {
+    BindTexture cmd1;
+    cmd1.Init(GL_TEXTURE_CUBE_MAP, 0);
+    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, 0));
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    TexParameteri cmd2;
+    cmd2.Init(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  }
+}
+
+TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameterfv) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+
+  {
+    BindTexture cmd1;
+    cmd1.Init(GL_TEXTURE_2D, 0);
+    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    TexParameterfv cmd2;
+    cmd2.Init(GL_TEXTURE_2D,
+              GL_TEXTURE_MAG_FILTER,
+              shared_memory_id_,
+              shared_memory_offset_);
+    GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST;
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  }
+
+  {
+    BindTexture cmd1;
+    cmd1.Init(GL_TEXTURE_CUBE_MAP, 0);
+    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, 0));
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    TexParameterfv cmd2;
+    cmd2.Init(GL_TEXTURE_CUBE_MAP,
+              GL_TEXTURE_MAG_FILTER,
+              shared_memory_id_,
+              shared_memory_offset_);
+    GetSharedMemoryAs<GLfloat*>()[0] = GL_NEAREST;
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  }
+}
+
+TEST_P(GLES2DecoderManualInitTest, NoDefaultTexParameteriv) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+
+  {
+    BindTexture cmd1;
+    cmd1.Init(GL_TEXTURE_2D, 0);
+    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    TexParameteriv cmd2;
+    cmd2.Init(GL_TEXTURE_2D,
+              GL_TEXTURE_MAG_FILTER,
+              shared_memory_id_,
+              shared_memory_offset_);
+    GetSharedMemoryAs<GLint*>()[0] = GL_NEAREST;
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  }
+
+  {
+    BindTexture cmd1;
+    cmd1.Init(GL_TEXTURE_CUBE_MAP, 0);
+    EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_CUBE_MAP, 0));
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    TexParameteriv cmd2;
+    cmd2.Init(GL_TEXTURE_CUBE_MAP,
+              GL_TEXTURE_MAG_FILTER,
+              shared_memory_id_,
+              shared_memory_offset_);
+    GetSharedMemoryAs<GLint*>()[0] = GL_NEAREST;
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+    EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+  }
+}
+
+TEST_P(GLES2DecoderManualInitTest, NoDefaultTexImage2D) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+
+  BindTexture cmd1;
+  cmd1.Init(GL_TEXTURE_2D, 0);
+  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  TexImage2D cmd2;
+  cmd2.Init(GL_TEXTURE_2D,
+            0,
+            GL_RGBA,
+            2,
+            2,
+            0,
+            GL_RGBA,
+            GL_UNSIGNED_BYTE,
+            kSharedMemoryId,
+            kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, NoDefaultTexSubImage2D) {
+  InitState init;
+  init.gl_version = "3.0";
+  InitDecoder(init);
+
+  BindTexture cmd1;
+  cmd1.Init(GL_TEXTURE_2D, 0);
+  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, 0));
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  TexSubImage2D cmd2;
+  cmd2.Init(GL_TEXTURE_2D,
+            0,
+            1,
+            1,
+            1,
+            1,
+            GL_RGBA,
+            GL_UNSIGNED_BYTE,
+            kSharedMemoryId,
+            kSharedMemoryOffset,
+            GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleBindTexture) {
+  InitState init;
+  init.extensions = "GL_ARB_texture_rectangle";
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_RECTANGLE_ARB, kNewServiceId));
+  EXPECT_CALL(*gl_, GenTextures(1, _))
+      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
+  BindTexture cmd;
+  cmd.Init(GL_TEXTURE_RECTANGLE_ARB, kNewClientId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  Texture* texture = GetTexture(kNewClientId)->texture();
+  EXPECT_TRUE(texture != NULL);
+  EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
+}
+
+TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleGetBinding) {
+  InitState init;
+  init.extensions = "GL_ARB_texture_rectangle";
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindTexture(
+      GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  EXPECT_CALL(*gl_,
+              GetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, result->GetData()))
+      .Times(0);
+  result->size = 0;
+  GetIntegerv cmd;
+  cmd.Init(GL_TEXTURE_BINDING_RECTANGLE_ARB,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
+                GL_TEXTURE_BINDING_RECTANGLE_ARB),
+            result->GetNumResults());
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  EXPECT_EQ(client_texture_id_, (uint32)result->GetData()[0]);
+}
+
+TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTextureDefaults) {
+  InitState init;
+  init.extensions = "GL_ARB_texture_rectangle";
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindTexture(
+      GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
+
+  Texture* texture = GetTexture(client_texture_id_)->texture();
+  EXPECT_TRUE(texture != NULL);
+  EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
+  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
+  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
+  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
+}
+
+TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParam) {
+  InitState init;
+  init.extensions = "GL_ARB_texture_rectangle";
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  DoBindTexture(
+      GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
+
+  EXPECT_CALL(*gl_,
+              TexParameteri(
+                  GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
+  EXPECT_CALL(*gl_,
+              TexParameteri(
+                  GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+  EXPECT_CALL(
+      *gl_,
+      TexParameteri(
+          GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+  EXPECT_CALL(
+      *gl_,
+      TexParameteri(
+          GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+  TexParameteri cmd;
+  cmd.Init(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  cmd.Init(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  cmd.Init(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  cmd.Init(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  Texture* texture = GetTexture(client_texture_id_)->texture();
+  EXPECT_TRUE(texture != NULL);
+  EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
+  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
+  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
+  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
+}
+
+TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParamInvalid) {
+  InitState init;
+  init.extensions = "GL_ARB_texture_rectangle";
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  DoBindTexture(
+      GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
+
+  TexParameteri cmd;
+  cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
+           GL_TEXTURE_MIN_FILTER,
+           GL_NEAREST_MIPMAP_NEAREST);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+
+  cmd.Init(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+
+  cmd.Init(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_REPEAT);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+
+  Texture* texture = GetTexture(client_texture_id_)->texture();
+  EXPECT_TRUE(texture != NULL);
+  EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
+  EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
+  EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
+  EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
+}
+
+TEST_P(GLES2DecoderManualInitTest, ARBTextureRectangleTexImage2DError) {
+  InitState init;
+  init.extensions = "GL_ARB_texture_rectangle";
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  GLenum target = GL_TEXTURE_RECTANGLE_ARB;
+  GLint level = 0;
+  GLenum internal_format = GL_RGBA;
+  GLsizei width = 2;
+  GLsizei height = 4;
+  GLint border = 0;
+  GLenum format = GL_RGBA;
+  GLenum type = GL_UNSIGNED_BYTE;
+  DoBindTexture(
+      GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
+  ASSERT_TRUE(GetTexture(client_texture_id_) != NULL);
+  TexImage2D cmd;
+  cmd.Init(target,
+           level,
+           internal_format,
+           width,
+           height,
+           border,
+           format,
+           type,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+
+  // TexImage2D is not allowed with GL_TEXTURE_RECTANGLE_ARB targets.
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, TexSubImage2DClearsAfterTexImage2DNULL) {
+  InitState init;
+  init.gl_version = "opengl es 2.0";
+  init.has_alpha = true;
+  init.has_depth = true;
+  init.request_alpha = true;
+  init.request_depth = true;
+  InitDecoder(init);
+
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_2D,
+                                GL_TEXTURE_2D,
+                                0,
+                                GL_RGBA,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                2,
+                                2);
+  EXPECT_CALL(*gl_,
+              TexSubImage2D(GL_TEXTURE_2D,
+                            0,
+                            1,
+                            1,
+                            1,
+                            1,
+                            GL_RGBA,
+                            GL_UNSIGNED_BYTE,
+                            shared_memory_address_))
+      .Times(1)
+      .RetiresOnSaturation();
+  TexSubImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D,
+           0,
+           1,
+           1,
+           1,
+           1,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  // Test if we call it again it does not clear.
+  EXPECT_CALL(*gl_,
+              TexSubImage2D(GL_TEXTURE_2D,
+                            0,
+                            1,
+                            1,
+                            1,
+                            1,
+                            GL_RGBA,
+                            GL_UNSIGNED_BYTE,
+                            shared_memory_address_))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest, TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) {
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGBA,
+               2,
+               2,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
+  EXPECT_CALL(*gl_,
+              TexSubImage2D(GL_TEXTURE_2D,
+                            0,
+                            1,
+                            1,
+                            1,
+                            1,
+                            GL_RGBA,
+                            GL_UNSIGNED_BYTE,
+                            shared_memory_address_))
+      .Times(1)
+      .RetiresOnSaturation();
+  TexSubImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D,
+           0,
+           1,
+           1,
+           1,
+           1,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  // Test if we call it again it does not clear.
+  EXPECT_CALL(*gl_,
+              TexSubImage2D(GL_TEXTURE_2D,
+                            0,
+                            1,
+                            1,
+                            1,
+                            1,
+                            GL_RGBA,
+                            GL_UNSIGNED_BYTE,
+                            shared_memory_address_))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(
+    GLES2DecoderManualInitTest,
+    TexSubImage2DDoesNotClearAfterTexImage2DNULLThenDataWithTexImage2DIsFaster) {
+  CommandLine command_line(0, NULL);
+  command_line.AppendSwitchASCII(
+      switches::kGpuDriverBugWorkarounds,
+      base::IntToString(gpu::TEXSUBIMAGE2D_FASTER_THAN_TEXIMAGE2D));
+  InitState init;
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoderWithCommandLine(init, &command_line);
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+
+  {
+    // Uses texSubimage internally because the above workaround is active and
+    // the update is for the full size of the texture.
+    EXPECT_CALL(*gl_,
+                TexSubImage2D(
+                    GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, _))
+        .Times(1)
+        .RetiresOnSaturation();
+    cmds::TexImage2D cmd;
+    cmd.Init(GL_TEXTURE_2D,
+             0,
+             GL_RGBA,
+             2,
+             2,
+             0,
+             GL_RGBA,
+             GL_UNSIGNED_BYTE,
+             kSharedMemoryId,
+             kSharedMemoryOffset);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  }
+
+  EXPECT_CALL(*gl_,
+              TexSubImage2D(GL_TEXTURE_2D,
+                            0,
+                            1,
+                            1,
+                            1,
+                            1,
+                            GL_RGBA,
+                            GL_UNSIGNED_BYTE,
+                            shared_memory_address_))
+      .Times(1)
+      .RetiresOnSaturation();
+  TexSubImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D,
+           0,
+           1,
+           1,
+           1,
+           1,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  // Test if we call it again it does not clear.
+  EXPECT_CALL(*gl_,
+              TexSubImage2D(GL_TEXTURE_2D,
+                            0,
+                            1,
+                            1,
+                            1,
+                            1,
+                            GL_RGBA,
+                            GL_UNSIGNED_BYTE,
+                            shared_memory_address_))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DWithDataThenNULL) {
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  // Put in data (so it should be marked as cleared)
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGBA,
+               2,
+               2,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
+  // Put in no data.
+  TexImage2D tex_cmd;
+  tex_cmd.Init(
+      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  // It won't actually call TexImage2D, just mark it as uncleared.
+  EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
+  // Next call to TexSubImage2d should clear.
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_2D,
+                                GL_TEXTURE_2D,
+                                0,
+                                GL_RGBA,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                2,
+                                2);
+  EXPECT_CALL(*gl_,
+              TexSubImage2D(GL_TEXTURE_2D,
+                            0,
+                            1,
+                            1,
+                            1,
+                            1,
+                            GL_RGBA,
+                            GL_UNSIGNED_BYTE,
+                            shared_memory_address_))
+      .Times(1)
+      .RetiresOnSaturation();
+  TexSubImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D,
+           0,
+           1,
+           1,
+           1,
+           1,
+           GL_RGBA,
+           GL_UNSIGNED_BYTE,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest, CopyTexImage2DMarksTextureAsCleared) {
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+
+  TextureManager* manager = group().texture_manager();
+  TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
+  ASSERT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  CopyTexImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+
+  EXPECT_TRUE(texture->SafeToRenderFrom());
+}
+
+TEST_P(GLES2DecoderTest, CopyTexSubImage2DClearsUnclearedTexture) {
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_2D,
+                                GL_TEXTURE_2D,
+                                0,
+                                GL_RGBA,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                2,
+                                2);
+  EXPECT_CALL(*gl_, CopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1))
+      .Times(1)
+      .RetiresOnSaturation();
+  CopyTexSubImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderManualInitTest, CompressedImage2DMarksTextureAsCleared) {
+  InitState init;
+  init.extensions = "GL_EXT_texture_compression_s3tc";
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(
+      *gl_,
+      CompressedTexImage2D(
+          GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, 8, _))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  CompressedTexImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D,
+           0,
+           GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+           4,
+           4,
+           0,
+           8,
+           kSharedMemoryId,
+           kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  TextureManager* manager = group().texture_manager();
+  TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
+  EXPECT_TRUE(texture_ref->texture()->SafeToRenderFrom());
+}
+
+TEST_P(GLES2DecoderTest, TextureUsageAngleExtNotEnabledByDefault) {
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+
+  TexParameteri cmd;
+  cmd.Init(
+      GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) {
+  Mailbox mailbox = Mailbox::Generate();
+
+  memcpy(shared_memory_address_, mailbox.name, sizeof(mailbox.name));
+
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 1, GL_RGBA, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  TextureRef* texture_ref =
+      group().texture_manager()->GetTexture(client_texture_id_);
+  ASSERT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  EXPECT_EQ(kServiceTextureId, texture->service_id());
+
+  ProduceTextureCHROMIUM produce_cmd;
+  produce_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(produce_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Texture didn't change.
+  GLsizei width;
+  GLsizei height;
+  GLenum type;
+  GLenum internal_format;
+
+  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+  EXPECT_EQ(3, width);
+  EXPECT_EQ(1, height);
+  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
+  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+
+  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
+  EXPECT_EQ(2, width);
+  EXPECT_EQ(4, height);
+  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
+  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+
+  // Service ID has not changed.
+  EXPECT_EQ(kServiceTextureId, texture->service_id());
+
+  // Create new texture for consume.
+  EXPECT_CALL(*gl_, GenTextures(_, _))
+      .WillOnce(SetArgumentPointee<1>(kNewServiceId))
+      .RetiresOnSaturation();
+  DoBindTexture(GL_TEXTURE_2D, kNewClientId, kNewServiceId);
+
+  // Assigns and binds original service size texture ID.
+  EXPECT_CALL(*gl_, DeleteTextures(1, _)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
+      .Times(1)
+      .RetiresOnSaturation();
+
+  memcpy(shared_memory_address_, mailbox.name, sizeof(mailbox.name));
+  ConsumeTextureCHROMIUM consume_cmd;
+  consume_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(consume_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Texture is redefined.
+  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+  EXPECT_EQ(3, width);
+  EXPECT_EQ(1, height);
+  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
+  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+
+  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
+  EXPECT_EQ(2, width);
+  EXPECT_EQ(4, height);
+  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
+  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+
+  // Service ID is restored.
+  EXPECT_EQ(kServiceTextureId, texture->service_id());
+}
+
+TEST_P(GLES2DecoderManualInitTest, DepthTextureBadArgs) {
+  InitState init;
+  init.extensions = "GL_ANGLE_depth_texture";
+  init.gl_version = "opengl es 2.0";
+  init.has_depth = true;
+  init.has_stencil = true;
+  init.request_depth = true;
+  init.request_stencil = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  // Check trying to upload data fails.
+  TexImage2D tex_cmd;
+  tex_cmd.Init(GL_TEXTURE_2D,
+               0,
+               GL_DEPTH_COMPONENT,
+               1,
+               1,
+               0,
+               GL_DEPTH_COMPONENT,
+               GL_UNSIGNED_INT,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  // Try level > 0.
+  tex_cmd.Init(GL_TEXTURE_2D,
+               1,
+               GL_DEPTH_COMPONENT,
+               1,
+               1,
+               0,
+               GL_DEPTH_COMPONENT,
+               GL_UNSIGNED_INT,
+               0,
+               0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+  // Make a 1 pixel depth texture.
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_DEPTH_COMPONENT,
+               1,
+               1,
+               0,
+               GL_DEPTH_COMPONENT,
+               GL_UNSIGNED_INT,
+               0,
+               0);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // Check that trying to update it fails.
+  TexSubImage2D tex_sub_cmd;
+  tex_sub_cmd.Init(GL_TEXTURE_2D,
+                   0,
+                   0,
+                   0,
+                   1,
+                   1,
+                   GL_DEPTH_COMPONENT,
+                   GL_UNSIGNED_INT,
+                   kSharedMemoryId,
+                   kSharedMemoryOffset,
+                   GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(tex_sub_cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+  // Check that trying to CopyTexImage2D fails
+  CopyTexImage2D copy_tex_cmd;
+  copy_tex_cmd.Init(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 1, 1, 0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(copy_tex_cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+
+  // Check that trying to CopyTexSubImage2D fails
+  CopyTexSubImage2D copy_sub_cmd;
+  copy_sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(copy_sub_cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, GenerateMipmapDepthTexture) {
+  InitState init;
+  init.extensions = "GL_ANGLE_depth_texture";
+  init.gl_version = "opengl es 2.0";
+  init.has_depth = true;
+  init.has_stencil = true;
+  init.request_depth = true;
+  init.request_stencil = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_DEPTH_COMPONENT,
+               2,
+               2,
+               0,
+               GL_DEPTH_COMPONENT,
+               GL_UNSIGNED_INT,
+               0,
+               0);
+  GenerateMipmap cmd;
+  cmd.Init(GL_TEXTURE_2D);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, BindTexImage2DCHROMIUM) {
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  TextureRef* texture_ref =
+      group().texture_manager()->GetTexture(client_texture_id_);
+  ASSERT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  EXPECT_EQ(kServiceTextureId, texture->service_id());
+
+  group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
+  EXPECT_FALSE(group().image_manager()->LookupImage(1) == NULL);
+
+  GLsizei width;
+  GLsizei height;
+  GLenum type;
+  GLenum internal_format;
+
+  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+  EXPECT_EQ(3, width);
+  EXPECT_EQ(1, height);
+  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
+  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+  EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+
+  // Bind image to texture.
+  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
+  bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
+  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+  // Image should now be set.
+  EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+
+  // Define new texture image.
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+  // Image should no longer be set.
+  EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+}
+
+TEST_P(GLES2DecoderTest, BindTexImage2DCHROMIUMCubeMapNotAllowed) {
+  group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
+  DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId);
+
+  BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
+  bind_tex_image_2d_cmd.Init(GL_TEXTURE_CUBE_MAP, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, OrphanGLImageWithTexImage2D) {
+  group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
+  DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId);
+
+  BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
+  bind_tex_image_2d_cmd.Init(GL_TEXTURE_CUBE_MAP, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
+  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  TextureRef* texture_ref =
+      group().texture_manager()->GetTexture(client_texture_id_);
+  ASSERT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+}
+
+TEST_P(GLES2DecoderTest, ReleaseTexImage2DCHROMIUM) {
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
+  TextureRef* texture_ref =
+      group().texture_manager()->GetTexture(client_texture_id_);
+  ASSERT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  EXPECT_EQ(kServiceTextureId, texture->service_id());
+
+  group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
+  EXPECT_FALSE(group().image_manager()->LookupImage(1) == NULL);
+
+  GLsizei width;
+  GLsizei height;
+  GLenum type;
+  GLenum internal_format;
+
+  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+  EXPECT_EQ(3, width);
+  EXPECT_EQ(1, height);
+  EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
+  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+  EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+  EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+
+  // Bind image to texture.
+  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
+  bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
+  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+  // Image should now be set.
+  EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+
+  // Release image from texture.
+  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  ReleaseTexImage2DCHROMIUM release_tex_image_2d_cmd;
+  release_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(release_tex_image_2d_cmd));
+  EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+  // Image should no longer be set.
+  EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+}
+
+class MockGLImage : public gfx::GLImage {
+ public:
+  MockGLImage() {}
+
+  // Overridden from gfx::GLImage:
+  MOCK_METHOD0(Destroy, void());
+  MOCK_METHOD0(GetSize, gfx::Size());
+  MOCK_METHOD1(BindTexImage, bool(unsigned));
+  MOCK_METHOD1(ReleaseTexImage, void(unsigned));
+  MOCK_METHOD0(WillUseTexImage, void());
+  MOCK_METHOD0(DidUseTexImage, void());
+  MOCK_METHOD0(WillModifyTexImage, void());
+  MOCK_METHOD0(DidModifyTexImage, void());
+
+ protected:
+  virtual ~MockGLImage() {}
+};
+
+TEST_P(GLES2DecoderWithShaderTest, UseTexImage) {
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGBA,
+               1,
+               1,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               kSharedMemoryId,
+               kSharedMemoryOffset);
+
+  TextureRef* texture_ref =
+      group().texture_manager()->GetTexture(client_texture_id_);
+  ASSERT_TRUE(texture_ref != NULL);
+  Texture* texture = texture_ref->texture();
+  EXPECT_EQ(kServiceTextureId, texture->service_id());
+
+  const int32 kImageId = 1;
+  scoped_refptr<MockGLImage> image(new MockGLImage);
+  group().image_manager()->AddImage(image.get(), kImageId);
+
+  // Bind image to texture.
+  EXPECT_CALL(*image, BindTexImage(GL_TEXTURE_2D))
+      .Times(1)
+      .WillOnce(Return(true))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*image, GetSize())
+      .Times(1)
+      .WillOnce(Return(gfx::Size(1, 1)))
+      .RetiresOnSaturation();
+  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
+  bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, kImageId);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
+
+  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
+  SetupExpectationsForApplyingDefaultDirtyState();
+
+  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(3).RetiresOnSaturation();
+  EXPECT_CALL(*image, WillUseTexImage()).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*image, DidUseTexImage()).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
+      .Times(1)
+      .RetiresOnSaturation();
+  DrawArrays cmd;
+  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  DoBindFramebuffer(
+      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
+  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
+      .Times(2)
+      .RetiresOnSaturation();
+  // Image will be 'in use' as long as bound to a framebuffer.
+  EXPECT_CALL(*image, WillUseTexImage()).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              FramebufferTexture2DEXT(GL_FRAMEBUFFER,
+                                      GL_COLOR_ATTACHMENT0,
+                                      GL_TEXTURE_2D,
+                                      kServiceTextureId,
+                                      0))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  FramebufferTexture2D fbtex_cmd;
+  fbtex_cmd.Init(GL_FRAMEBUFFER,
+                 GL_COLOR_ATTACHMENT0,
+                 GL_TEXTURE_2D,
+                 client_texture_id_,
+                 0);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_,
+              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
+                                         GL_COLOR_ATTACHMENT0,
+                                         GL_RENDERBUFFER,
+                                         kServiceRenderbufferId))
+      .Times(1)
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
+      .Times(2)
+      .RetiresOnSaturation();
+  // Image should no longer be 'in use' after being unbound from framebuffer.
+  EXPECT_CALL(*image, DidUseTexImage()).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  FramebufferRenderbuffer fbrb_cmd;
+  fbrb_cmd.Init(GL_FRAMEBUFFER,
+                GL_COLOR_ATTACHMENT0,
+                GL_RENDERBUFFER,
+                client_renderbuffer_id_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
+}
+
+TEST_P(GLES2DecoderManualInitTest, DrawWithGLImageExternal) {
+  InitState init;
+  init.extensions = "GL_OES_EGL_image_external";
+  init.gl_version = "opengl es 2.0";
+  init.has_alpha = true;
+  init.has_depth = true;
+  init.request_alpha = true;
+  init.request_depth = true;
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  TextureRef* texture_ref = GetTexture(client_texture_id_);
+  scoped_refptr<MockGLImage> image(new MockGLImage);
+  group().texture_manager()->SetTarget(texture_ref, GL_TEXTURE_EXTERNAL_OES);
+  group().texture_manager()->SetLevelInfo(texture_ref,
+                                          GL_TEXTURE_EXTERNAL_OES,
+                                          0,
+                                          GL_RGBA,
+                                          0,
+                                          0,
+                                          1,
+                                          0,
+                                          GL_RGBA,
+                                          GL_UNSIGNED_BYTE,
+                                          true);
+  group().texture_manager()->SetLevelImage(
+      texture_ref, GL_TEXTURE_EXTERNAL_OES, 0, image);
+
+  DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  SetupSamplerExternalProgram();
+  SetupIndexBuffer();
+  AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, 0);
+  SetupExpectationsForApplyingDefaultDirtyState();
+  EXPECT_TRUE(group().texture_manager()->CanRender(texture_ref));
+
+  InSequence s;
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*image, WillUseTexImage()).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(1);
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*image, DidUseTexImage()).Times(1).RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)).Times(1).RetiresOnSaturation();
+  DrawElements cmd;
+  cmd.Init(GL_TRIANGLES,
+           kValidIndexRangeCount,
+           GL_UNSIGNED_SHORT,
+           kValidIndexRangeStart * 2);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, TexImage2DFloatOnGLES2) {
+  InitState init;
+  init.extensions = "GL_OES_texture_float";
+  init.gl_version = "opengl es 2.0";
+  InitDecoder(init);
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
+  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 17, 0, GL_LUMINANCE, GL_FLOAT, 0, 0);
+  DoTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 17, 0, GL_ALPHA, GL_FLOAT, 0, 0);
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_LUMINANCE_ALPHA,
+               16,
+               17,
+               0,
+               GL_LUMINANCE_ALPHA,
+               GL_FLOAT,
+               0,
+               0);
+}
+
+TEST_P(GLES2DecoderManualInitTest, TexImage2DFloatOnGLES3) {
+  InitState init;
+  init.extensions = "GL_OES_texture_float GL_EXT_color_buffer_float";
+  init.gl_version = "opengl es 3.0";
+  InitDecoder(init);
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
+  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 17, 0, GL_LUMINANCE, GL_FLOAT, 0, 0);
+  DoTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 17, 0, GL_ALPHA, GL_FLOAT, 0, 0);
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_LUMINANCE_ALPHA,
+               16,
+               17,
+               0,
+               GL_LUMINANCE_ALPHA,
+               GL_FLOAT,
+               0,
+               0);
+}
+
+TEST_P(GLES2DecoderManualInitTest, TexSubImage2DFloatOnGLES3) {
+  InitState init;
+  init.extensions = "GL_OES_texture_float GL_EXT_color_buffer_float";
+  init.gl_version = "opengl es 3.0";
+  InitDecoder(init);
+  const int kWidth = 8;
+  const int kHeight = 4;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGBA32F,
+               kWidth,
+               kHeight,
+               0,
+               GL_RGBA,
+               GL_FLOAT,
+               0,
+               0);
+  EXPECT_CALL(*gl_,
+              TexImage2D(GL_TEXTURE_2D,
+                         0,
+                         GL_RGBA32F,
+                         kWidth,
+                         kHeight,
+                         0,
+                         GL_RGBA,
+                         GL_FLOAT,
+                         shared_memory_address_))
+      .Times(1)
+      .RetiresOnSaturation();
+  TexSubImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D,
+           0,
+           0,
+           0,
+           kWidth,
+           kHeight,
+           GL_RGBA,
+           GL_FLOAT,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, TexSubImage2DFloatDoesClearOnGLES3) {
+  InitState init;
+  init.extensions = "GL_OES_texture_float GL_EXT_color_buffer_float";
+  init.gl_version = "opengl es 3.0";
+  InitDecoder(init);
+  const int kWidth = 8;
+  const int kHeight = 4;
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGBA32F,
+               kWidth,
+               kHeight,
+               0,
+               GL_RGBA,
+               GL_FLOAT,
+               0,
+               0);
+  SetupClearTextureExpectations(kServiceTextureId,
+                                kServiceTextureId,
+                                GL_TEXTURE_2D,
+                                GL_TEXTURE_2D,
+                                0,
+                                GL_RGBA32F,
+                                GL_RGBA,
+                                GL_FLOAT,
+                                kWidth,
+                                kHeight);
+  EXPECT_CALL(*gl_,
+              TexSubImage2D(GL_TEXTURE_2D,
+                            0,
+                            1,
+                            0,
+                            kWidth - 1,
+                            kHeight,
+                            GL_RGBA,
+                            GL_FLOAT,
+                            shared_memory_address_))
+      .Times(1)
+      .RetiresOnSaturation();
+  TexSubImage2D cmd;
+  cmd.Init(GL_TEXTURE_2D,
+           0,
+           1,
+           0,
+           kWidth - 1,
+           kHeight,
+           GL_RGBA,
+           GL_FLOAT,
+           kSharedMemoryId,
+           kSharedMemoryOffset,
+           GL_FALSE);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderManualInitTest, TexImage2DFloatConvertsFormatDesktop) {
+  InitState init;
+  init.extensions = "GL_ARB_texture_float";
+  init.gl_version = "2.1";
+  InitDecoder(init);
+  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+  DoTexImage2D(
+      GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
+  DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
+  DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D,
+                                    0,
+                                    GL_RGBA,
+                                    16,
+                                    17,
+                                    0,
+                                    GL_RGBA,
+                                    GL_FLOAT,
+                                    0,
+                                    0,
+                                    GL_RGBA32F_ARB);
+  DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D,
+                                    0,
+                                    GL_RGB,
+                                    16,
+                                    17,
+                                    0,
+                                    GL_RGB,
+                                    GL_FLOAT,
+                                    0,
+                                    0,
+                                    GL_RGB32F_ARB);
+  DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D,
+                                    0,
+                                    GL_LUMINANCE,
+                                    16,
+                                    17,
+                                    0,
+                                    GL_LUMINANCE,
+                                    GL_FLOAT,
+                                    0,
+                                    0,
+                                    GL_LUMINANCE32F_ARB);
+  DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D,
+                                    0,
+                                    GL_ALPHA,
+                                    16,
+                                    17,
+                                    0,
+                                    GL_ALPHA,
+                                    GL_FLOAT,
+                                    0,
+                                    0,
+                                    GL_ALPHA32F_ARB);
+  DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D,
+                                    0,
+                                    GL_LUMINANCE_ALPHA,
+                                    16,
+                                    17,
+                                    0,
+                                    GL_LUMINANCE_ALPHA,
+                                    GL_FLOAT,
+                                    0,
+                                    0,
+                                    GL_LUMINANCE_ALPHA32F_ARB);
+}
+
+class GLES2DecoderCompressedFormatsTest : public GLES2DecoderManualInitTest {
+ public:
+  GLES2DecoderCompressedFormatsTest() {}
+
+  static bool ValueInArray(GLint value, GLint* array, GLint count) {
+    for (GLint ii = 0; ii < count; ++ii) {
+      if (array[ii] == value) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void CheckFormats(const char* extension, const GLenum* formats, int count) {
+    InitState init;
+    init.extensions = extension;
+    init.gl_version = "3.0";
+    init.bind_generates_resource = true;
+    InitDecoder(init);
+
+    EXPECT_CALL(*gl_, GetError())
+        .WillOnce(Return(GL_NO_ERROR))
+        .WillOnce(Return(GL_NO_ERROR))
+        .WillOnce(Return(GL_NO_ERROR))
+        .WillOnce(Return(GL_NO_ERROR))
+        .RetiresOnSaturation();
+
+    typedef GetIntegerv::Result Result;
+    Result* result = static_cast<Result*>(shared_memory_address_);
+    GetIntegerv cmd;
+    result->size = 0;
+    EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0).RetiresOnSaturation();
+    cmd.Init(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
+             shared_memory_id_,
+             shared_memory_offset_);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(1, result->GetNumResults());
+    GLint num_formats = result->GetData()[0];
+    EXPECT_EQ(count, num_formats);
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+    result->size = 0;
+    cmd.Init(GL_COMPRESSED_TEXTURE_FORMATS,
+             shared_memory_id_,
+             shared_memory_offset_);
+    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+    EXPECT_EQ(num_formats, result->GetNumResults());
+
+    for (int i = 0; i < count; ++i) {
+      EXPECT_TRUE(
+          ValueInArray(formats[i], result->GetData(), result->GetNumResults()));
+    }
+
+    EXPECT_EQ(GL_NO_ERROR, GetGLError());
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(Service,
+                        GLES2DecoderCompressedFormatsTest,
+                        ::testing::Bool());
+
+TEST_P(GLES2DecoderCompressedFormatsTest, GetCompressedTextureFormatsS3TC) {
+  const GLenum formats[] = {
+      GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+      GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT};
+  CheckFormats("GL_EXT_texture_compression_s3tc", formats, 4);
+}
+
+TEST_P(GLES2DecoderCompressedFormatsTest, GetCompressedTextureFormatsATC) {
+  const GLenum formats[] = {GL_ATC_RGB_AMD, GL_ATC_RGBA_EXPLICIT_ALPHA_AMD,
+                            GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD};
+  CheckFormats("GL_AMD_compressed_ATC_texture", formats, 3);
+}
+
+TEST_P(GLES2DecoderCompressedFormatsTest, GetCompressedTextureFormatsPVRTC) {
+  const GLenum formats[] = {
+      GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,
+      GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG};
+  CheckFormats("GL_IMG_texture_compression_pvrtc", formats, 4);
+}
+
+TEST_P(GLES2DecoderCompressedFormatsTest, GetCompressedTextureFormatsETC1) {
+  const GLenum formats[] = {GL_ETC1_RGB8_OES};
+  CheckFormats("GL_OES_compressed_ETC1_RGB8_texture", formats, 1);
+}
+
+TEST_P(GLES2DecoderManualInitTest, GetNoCompressedTextureFormats) {
+  InitState init;
+  init.gl_version = "3.0";
+  init.bind_generates_resource = true;
+  InitDecoder(init);
+
+  EXPECT_CALL(*gl_, GetError())
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .WillOnce(Return(GL_NO_ERROR))
+      .RetiresOnSaturation();
+
+  typedef GetIntegerv::Result Result;
+  Result* result = static_cast<Result*>(shared_memory_address_);
+  GetIntegerv cmd;
+  result->size = 0;
+  EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0).RetiresOnSaturation();
+  cmd.Init(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
+           shared_memory_id_,
+           shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(1, result->GetNumResults());
+  GLint num_formats = result->GetData()[0];
+  EXPECT_EQ(0, num_formats);
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+
+  result->size = 0;
+  cmd.Init(
+      GL_COMPRESSED_TEXTURE_FORMATS, shared_memory_id_, shared_memory_offset_);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(num_formats, result->GetNumResults());
+
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+// TODO(gman): Complete this test.
+// TEST_P(GLES2DecoderTest, CompressedTexImage2DGLError) {
+// }
+
+// TODO(gman): CompressedTexImage2D
+
+// TODO(gman): CompressedTexImage2DImmediate
+
+// TODO(gman): CompressedTexSubImage2DImmediate
+
+// TODO(gman): TexImage2D
+
+// TODO(gman): TexImage2DImmediate
+
+// TODO(gman): TexSubImage2DImmediate
+
+}  // namespace gles2
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/gpu_control_service.cc b/gpu/command_buffer/service/gpu_control_service.cc
index 893b872..f9f19eb 100644
--- a/gpu/command_buffer/service/gpu_control_service.cc
+++ b/gpu/command_buffer/service/gpu_control_service.cc
@@ -4,84 +4,21 @@
 
 #include "gpu/command_buffer/service/gpu_control_service.h"
 
-#include "gpu/command_buffer/client/gpu_memory_buffer_factory.h"
 #include "gpu/command_buffer/service/gpu_memory_buffer_manager.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
 #include "gpu/command_buffer/service/query_manager.h"
 
 namespace gpu {
 
 GpuControlService::GpuControlService(
     GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager,
-    GpuMemoryBufferFactory* gpu_memory_buffer_factory,
-    gles2::MailboxManager* mailbox_manager,
-    gles2::QueryManager* query_manager,
-    const gpu::Capabilities& decoder_capabilities)
+    gles2::QueryManager* query_manager)
     : gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
-      gpu_memory_buffer_factory_(gpu_memory_buffer_factory),
-      mailbox_manager_(mailbox_manager),
-      query_manager_(query_manager),
-      capabilities_(decoder_capabilities) {
-  capabilities_.map_image =
-      gpu_memory_buffer_manager_ && gpu_memory_buffer_factory_;
+      query_manager_(query_manager) {
 }
 
 GpuControlService::~GpuControlService() {
 }
 
-gpu::Capabilities GpuControlService::GetCapabilities() {
-  return capabilities_;
-}
-
-gfx::GpuMemoryBuffer* GpuControlService::CreateGpuMemoryBuffer(
-    size_t width,
-    size_t height,
-    unsigned internalformat,
-    int32* id) {
-  *id = -1;
-
-  CHECK(gpu_memory_buffer_factory_) << "No GPU memory buffer factory provided";
-  linked_ptr<gfx::GpuMemoryBuffer> buffer = make_linked_ptr(
-      gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(width,
-                                                        height,
-                                                        internalformat));
-  if (!buffer.get())
-    return NULL;
-
-  static int32 next_id = 1;
-  *id = next_id++;
-
-  if (!RegisterGpuMemoryBuffer(*id,
-                               buffer->GetHandle(),
-                               width,
-                               height,
-                               internalformat)) {
-    *id = -1;
-    return NULL;
-  }
-
-  gpu_memory_buffers_[*id] = buffer;
-  return buffer.get();
-}
-
-void GpuControlService::DestroyGpuMemoryBuffer(int32 id) {
-  GpuMemoryBufferMap::iterator it = gpu_memory_buffers_.find(id);
-  if (it != gpu_memory_buffers_.end())
-    gpu_memory_buffers_.erase(it);
-
-  gpu_memory_buffer_manager_->DestroyGpuMemoryBuffer(id);
-}
-
-uint32 GpuControlService::InsertSyncPoint() {
-  NOTREACHED();
-  return 0u;
-}
-
-void GpuControlService::SignalSyncPoint(uint32 sync_point,
-                                        const base::Closure& callback) {
-  NOTREACHED();
-}
-
 void GpuControlService::SignalQuery(uint32 query_id,
                                     const base::Closure& callback) {
   DCHECK(query_manager_);
@@ -92,35 +29,18 @@
     query->AddCallback(callback);
 }
 
-void GpuControlService::SetSurfaceVisible(bool visible) {
-  NOTREACHED();
-}
-
-void GpuControlService::SendManagedMemoryStats(
-    const ManagedMemoryStats& stats) {
-  NOTREACHED();
-}
-
-void GpuControlService::Echo(const base::Closure& callback) {
-  NOTREACHED();
-}
-
-uint32 GpuControlService::CreateStreamTexture(uint32 texture_id) {
-  NOTREACHED();
-  return 0;
-}
-
-bool GpuControlService::RegisterGpuMemoryBuffer(
+void GpuControlService::RegisterGpuMemoryBuffer(
     int32 id,
     gfx::GpuMemoryBufferHandle buffer,
     size_t width,
     size_t height,
     unsigned internalformat) {
-  return gpu_memory_buffer_manager_->RegisterGpuMemoryBuffer(id,
-                                                             buffer,
-                                                             width,
-                                                             height,
-                                                             internalformat);
+  gpu_memory_buffer_manager_->RegisterGpuMemoryBuffer(
+      id, buffer, width, height, internalformat);
+}
+
+void GpuControlService::UnregisterGpuMemoryBuffer(int32 id) {
+  gpu_memory_buffer_manager_->UnregisterGpuMemoryBuffer(id);
 }
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/gpu_control_service.h b/gpu/command_buffer/service/gpu_control_service.h
index 74fd4d5..9a64946 100644
--- a/gpu/command_buffer/service/gpu_control_service.h
+++ b/gpu/command_buffer/service/gpu_control_service.h
@@ -5,66 +5,36 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_CONTROL_SERVICE_H_
 #define GPU_COMMAND_BUFFER_SERVICE_GPU_CONTROL_SERVICE_H_
 
-#include <map>
-
-#include "base/memory/linked_ptr.h"
-#include "gpu/command_buffer/common/gpu_control.h"
+#include "base/callback.h"
+#include "gpu/command_buffer/common/capabilities.h"
+#include "gpu/gpu_export.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 
 namespace gpu {
-class GpuMemoryBufferFactory;
 class GpuMemoryBufferManagerInterface;
 
 namespace gles2 {
-class MailboxManager;
 class QueryManager;
 }
 
-class GPU_EXPORT GpuControlService : public GpuControl {
+class GPU_EXPORT GpuControlService {
  public:
   GpuControlService(GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager,
-                    GpuMemoryBufferFactory* gpu_memory_buffer_factory,
-                    gles2::MailboxManager* mailbox_manager,
-                    gles2::QueryManager* query_manager,
-                    const gpu::Capabilities& decoder_capabilities);
+                    gles2::QueryManager* query_manager);
   virtual ~GpuControlService();
 
+  void SignalQuery(uint32 query, const base::Closure& callback);
 
-  // GpuControl implementation.
-  virtual gpu::Capabilities GetCapabilities() OVERRIDE;
-  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(
-      size_t width,
-      size_t height,
-      unsigned internalformat,
-      int32* id) OVERRIDE;
-  virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
-  virtual uint32 InsertSyncPoint() OVERRIDE;
-  virtual void SignalSyncPoint(uint32 sync_point,
-                               const base::Closure& callback) OVERRIDE;
-  virtual void SignalQuery(uint32 query,
-                           const base::Closure& callback) OVERRIDE;
-  virtual void SetSurfaceVisible(bool visible) OVERRIDE;
-  virtual void SendManagedMemoryStats(const ManagedMemoryStats& stats)
-      OVERRIDE;
-  virtual void Echo(const base::Closure& callback) OVERRIDE;
-  virtual uint32 CreateStreamTexture(uint32 texture_id) OVERRIDE;
-
-  // Register an existing gpu memory buffer and get an ID that can be used
-  // to identify it in the command buffer.
-  bool RegisterGpuMemoryBuffer(int32 id,
+  void RegisterGpuMemoryBuffer(int32 id,
                                gfx::GpuMemoryBufferHandle buffer,
                                size_t width,
                                size_t height,
                                unsigned internalformat);
+  void UnregisterGpuMemoryBuffer(int32 id);
 
  private:
   GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager_;
-  GpuMemoryBufferFactory* gpu_memory_buffer_factory_;
-  gles2::MailboxManager* mailbox_manager_;
   gles2::QueryManager* query_manager_;
-  typedef std::map<int32, linked_ptr<gfx::GpuMemoryBuffer> > GpuMemoryBufferMap;
-  GpuMemoryBufferMap gpu_memory_buffers_;
-  gpu::Capabilities capabilities_;
 
   DISALLOW_COPY_AND_ASSIGN(GpuControlService);
 };
diff --git a/gpu/command_buffer/service/gpu_memory_buffer_manager.h b/gpu/command_buffer/service/gpu_memory_buffer_manager.h
index fb44ede..3ddcaad 100644
--- a/gpu/command_buffer/service/gpu_memory_buffer_manager.h
+++ b/gpu/command_buffer/service/gpu_memory_buffer_manager.h
@@ -15,12 +15,12 @@
  public:
   virtual ~GpuMemoryBufferManagerInterface() {}
 
-  virtual bool RegisterGpuMemoryBuffer(int32 id,
+  virtual void RegisterGpuMemoryBuffer(int32 id,
                                        gfx::GpuMemoryBufferHandle buffer,
                                        size_t width,
                                        size_t height,
                                        unsigned internalformat) = 0;
-  virtual void DestroyGpuMemoryBuffer(int32 id) = 0;
+  virtual void UnregisterGpuMemoryBuffer(int32 id) = 0;
 };
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/image_manager.cc b/gpu/command_buffer/service/image_manager.cc
index f39eba2..a3ac435 100644
--- a/gpu/command_buffer/service/image_manager.cc
+++ b/gpu/command_buffer/service/image_manager.cc
@@ -15,19 +15,19 @@
 ImageManager::~ImageManager() {
 }
 
-bool ImageManager::RegisterGpuMemoryBuffer(int32 id,
+void ImageManager::RegisterGpuMemoryBuffer(int32 id,
                                            gfx::GpuMemoryBufferHandle buffer,
                                            size_t width,
                                            size_t height,
                                            unsigned internalformat) {
   if (id <= 0) {
     DVLOG(0) << "Cannot register GPU memory buffer with non-positive ID.";
-    return false;
+    return;
   }
 
   if (LookupImage(id)) {
     DVLOG(0) << "GPU memory buffer ID already in use.";
-    return false;
+    return;
   }
 
   scoped_refptr<gfx::GLImage> gl_image =
@@ -35,16 +35,15 @@
                                                     gfx::Size(width, height),
                                                     internalformat);
   if (!gl_image)
-    return false;
+    return;
 
   if (release_after_use_)
     gl_image->SetReleaseAfterUse();
 
   AddImage(gl_image.get(), id);
-  return true;
 }
 
-void ImageManager::DestroyGpuMemoryBuffer(int32 id) {
+void ImageManager::UnregisterGpuMemoryBuffer(int32 id) {
   RemoveImage(id);
 }
 
diff --git a/gpu/command_buffer/service/image_manager.h b/gpu/command_buffer/service/image_manager.h
index 51e006d..95d836f 100644
--- a/gpu/command_buffer/service/image_manager.h
+++ b/gpu/command_buffer/service/image_manager.h
@@ -26,12 +26,12 @@
   ImageManager();
 
   // Overridden from GpuMemoryBufferManagerInterface:
-  virtual bool RegisterGpuMemoryBuffer(int32 id,
+  virtual void RegisterGpuMemoryBuffer(int32 id,
                                        gfx::GpuMemoryBufferHandle buffer,
                                        size_t width,
                                        size_t height,
                                        unsigned internalformat) OVERRIDE;
-  virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
+  virtual void UnregisterGpuMemoryBuffer(int32 id) OVERRIDE;
 
   void AddImage(gfx::GLImage* gl_image, int32 service_id);
   void RemoveImage(int32 service_id);
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
index f9b81db..20766db 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -24,6 +24,7 @@
 #include "base/sequence_checker.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/threading/thread.h"
+#include "gpu/command_buffer/client/gpu_memory_buffer_factory.h"
 #include "gpu/command_buffer/service/command_buffer_service.h"
 #include "gpu/command_buffer/service/context_group.h"
 #include "gpu/command_buffer/service/gl_context_virtual.h"
@@ -296,8 +297,11 @@
       base::Bind(&RunTaskWithResult<bool>, init_task, &result, &completion));
   completion.Wait();
 
-  if (result)
+  if (result) {
     capabilities_ = capabilities;
+    capabilities_.map_image =
+        capabilities_.map_image && g_gpu_memory_buffer_factory;
+  }
   return result;
 }
 
@@ -409,15 +413,11 @@
     DestroyOnGpuThread();
     return false;
   }
+  *params.capabilities = decoder_->GetCapabilities();
 
   gpu_control_.reset(
       new GpuControlService(decoder_->GetContextGroup()->image_manager(),
-                            g_gpu_memory_buffer_factory,
-                            decoder_->GetContextGroup()->mailbox_manager(),
-                            decoder_->GetQueryManager(),
-                            decoder_->GetCapabilities()));
-
-  *params.capabilities = gpu_control_->GetCapabilities();
+                            decoder_->GetQueryManager()));
 
   if (!params.is_offscreen) {
     decoder_->SetResizeCallback(base::Bind(
@@ -607,18 +607,40 @@
     size_t width,
     size_t height,
     unsigned internalformat,
+    unsigned usage,
     int32* id) {
   CheckSequencedThread();
-  base::AutoLock lock(command_buffer_lock_);
-  return gpu_control_->CreateGpuMemoryBuffer(width,
-                                             height,
-                                             internalformat,
-                                             id);
+
+  *id = -1;
+  linked_ptr<gfx::GpuMemoryBuffer> buffer =
+      make_linked_ptr(g_gpu_memory_buffer_factory->CreateGpuMemoryBuffer(
+          width, height, internalformat, usage));
+  if (!buffer.get())
+    return NULL;
+
+  static int32 next_id = 1;
+  *id = next_id++;
+
+  base::Closure task = base::Bind(&GpuControlService::RegisterGpuMemoryBuffer,
+                                  base::Unretained(gpu_control_.get()),
+                                  *id,
+                                  buffer->GetHandle(),
+                                  width,
+                                  height,
+                                  internalformat);
+
+  QueueTask(task);
+
+  gpu_memory_buffers_[*id] = buffer;
+  return buffer.get();
 }
 
 void InProcessCommandBuffer::DestroyGpuMemoryBuffer(int32 id) {
   CheckSequencedThread();
-  base::Closure task = base::Bind(&GpuControl::DestroyGpuMemoryBuffer,
+  GpuMemoryBufferMap::iterator it = gpu_memory_buffers_.find(id);
+  if (it != gpu_memory_buffers_.end())
+    gpu_memory_buffers_.erase(it);
+  base::Closure task = base::Bind(&GpuControlService::UnregisterGpuMemoryBuffer,
                                   base::Unretained(gpu_control_.get()),
                                   id);
 
@@ -667,7 +689,7 @@
 void InProcessCommandBuffer::SignalQuery(unsigned query,
                                          const base::Closure& callback) {
   CheckSequencedThread();
-  QueueTask(base::Bind(&GpuControl::SignalQuery,
+  QueueTask(base::Bind(&GpuControlService::SignalQuery,
                        base::Unretained(gpu_control_.get()),
                        query,
                        WrapCallback(callback)));
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h
index 7045c9f..1b35e08 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.h
+++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -5,17 +5,19 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_IN_PROCESS_COMMAND_BUFFER_H_
 #define GPU_COMMAND_BUFFER_SERVICE_IN_PROCESS_COMMAND_BUFFER_H_
 
+#include <map>
 #include <vector>
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/memory/linked_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
+#include "gpu/command_buffer/client/gpu_control.h"
 #include "gpu/command_buffer/common/command_buffer.h"
-#include "gpu/command_buffer/common/gpu_control.h"
 #include "gpu/gpu_export.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 #include "ui/gfx/native_widget_types.h"
@@ -50,6 +52,7 @@
 }
 
 class CommandBufferServiceBase;
+class GpuControlService;
 class GpuMemoryBufferFactory;
 class GpuScheduler;
 class TransferBufferManagerInterface;
@@ -95,11 +98,11 @@
 
   // GpuControl implementation:
   virtual gpu::Capabilities GetCapabilities() OVERRIDE;
-  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(
-      size_t width,
-      size_t height,
-      unsigned internalformat,
-      int32* id) OVERRIDE;
+  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(size_t width,
+                                                      size_t height,
+                                                      unsigned internalformat,
+                                                      unsigned usage,
+                                                      int32* id) OVERRIDE;
   virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
   virtual uint32 InsertSyncPoint() OVERRIDE;
   virtual void SignalSyncPoint(uint32 sync_point,
@@ -201,6 +204,8 @@
   State last_state_;
   int32 last_put_offset_;
   gpu::Capabilities capabilities_;
+  typedef std::map<int32, linked_ptr<gfx::GpuMemoryBuffer> > GpuMemoryBufferMap;
+  GpuMemoryBufferMap gpu_memory_buffers_;
 
   // Accessed on both threads:
   scoped_ptr<CommandBufferServiceBase> command_buffer_;
@@ -209,7 +214,7 @@
   scoped_refptr<Service> service_;
   State state_after_last_flush_;
   base::Lock state_after_last_flush_lock_;
-  scoped_ptr<GpuControl> gpu_control_;
+  scoped_ptr<GpuControlService> gpu_control_;
   scoped_refptr<gfx::GLShareGroup> gl_share_group_;
 
 #if defined(OS_ANDROID)
diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc
index a3a64ca..c589be4 100644
--- a/gpu/command_buffer/service/test_helper.cc
+++ b/gpu/command_buffer/service/test_helper.cc
@@ -9,7 +9,6 @@
 
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_tokenizer.h"
-#include "gpu/command_buffer/common/types.h"
 #include "gpu/command_buffer/service/buffer_manager.h"
 #include "gpu/command_buffer/service/error_state_mock.h"
 #include "gpu/command_buffer/service/gl_utils.h"
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index c3a824c..76863c6 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -399,6 +399,13 @@
       }
     }
   }
+
+  // If texture is uncleared and is attached to a framebuffer,
+  // that framebuffer must be marked possibly incomplete.
+  if (!cleared && IsAttachedToFramebuffer()) {
+    IncAllFramebufferStateChangeCount();
+  }
+
   UpdateSafeToRenderFrom(cleared);
 }
 
diff --git a/gpu/command_buffer/service/vertex_array_manager.cc b/gpu/command_buffer/service/vertex_array_manager.cc
index 1560c04..9747519 100644
--- a/gpu/command_buffer/service/vertex_array_manager.cc
+++ b/gpu/command_buffer/service/vertex_array_manager.cc
@@ -28,22 +28,14 @@
   vertex_attrib_managers_.clear();
 }
 
-scoped_refptr<VertexAttribManager>
-VertexArrayManager::CreateVertexAttribManager(GLuint client_id,
-                                              GLuint service_id,
-                                              uint32 num_vertex_attribs,
-                                              bool client_visible) {
+void VertexArrayManager::CreateVertexAttribManager(
+    GLuint client_id, GLuint service_id, uint32 num_vertex_attribs) {
   scoped_refptr<VertexAttribManager> vertex_attrib_manager(
     new VertexAttribManager(this, service_id, num_vertex_attribs));
-
-  if (client_visible) {
-    std::pair<VertexAttribManagerMap::iterator, bool> result =
-        vertex_attrib_managers_.insert(
-            std::make_pair(client_id, vertex_attrib_manager));
-    DCHECK(result.second);
-  }
-
-  return vertex_attrib_manager;
+  std::pair<VertexAttribManagerMap::iterator, bool> result =
+      vertex_attrib_managers_.insert(
+      std::make_pair(client_id, vertex_attrib_manager));
+  DCHECK(result.second);
 }
 
 VertexAttribManager* VertexArrayManager::GetVertexAttribManager(
diff --git a/gpu/command_buffer/service/vertex_array_manager.h b/gpu/command_buffer/service/vertex_array_manager.h
index 97ecc1a..4fc567c 100644
--- a/gpu/command_buffer/service/vertex_array_manager.h
+++ b/gpu/command_buffer/service/vertex_array_manager.h
@@ -28,13 +28,9 @@
   // Must call before destruction.
   void Destroy(bool have_context);
 
-  // Creates a VertexAttribManager and if client_visible,
-  // maps it to the client_id.
-  scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
-      GLuint client_id,
-      GLuint service_id,
-      uint32 num_vertex_attribs,
-      bool client_visible);
+  // Creates a VertexArrayInfo for the given vertex array.
+  void CreateVertexAttribManager(GLuint client_id, GLuint service_id,
+      uint32 num_vertex_attribs);
 
   // Gets the vertex attrib manager for the given vertex array.
   VertexAttribManager* GetVertexAttribManager(GLuint client_id);
diff --git a/gpu/command_buffer/service/vertex_array_manager_unittest.cc b/gpu/command_buffer/service/vertex_array_manager_unittest.cc
index 617a5f6..3e3fd89 100644
--- a/gpu/command_buffer/service/vertex_array_manager_unittest.cc
+++ b/gpu/command_buffer/service/vertex_array_manager_unittest.cc
@@ -58,7 +58,7 @@
 
   // Check we can create
   manager_->CreateVertexAttribManager(
-      kClient1Id, kService1Id, kNumVertexAttribs, true);
+      kClient1Id, kService1Id, kNumVertexAttribs);
   // Check creation success
   VertexAttribManager* info1 = manager_->GetVertexAttribManager(kClient1Id);
   ASSERT_TRUE(info1 != NULL);
@@ -84,8 +84,7 @@
   const GLuint kService1Id = 11;
   VertexArrayManager manager;
   // Check we can create
-  manager.CreateVertexAttribManager(
-      kClient1Id, kService1Id, kNumVertexAttribs, true);
+  manager.CreateVertexAttribManager(kClient1Id, kService1Id, kNumVertexAttribs);
   // Check creation success
   VertexAttribManager* info1 = manager.GetVertexAttribManager(kClient1Id);
   ASSERT_TRUE(info1 != NULL);
diff --git a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
index 5948d76..ad8b5d0 100644
--- a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
+++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
@@ -42,7 +42,7 @@
     Die();
   }
 
-  MOCK_METHOD1(Map, void*(gfx::GpuMemoryBuffer::AccessMode));
+  MOCK_METHOD0(Map, void*());
   MOCK_METHOD0(Unmap, void());
   MOCK_CONST_METHOD0(IsMapped, bool());
   MOCK_CONST_METHOD0(GetStride, uint32());
@@ -58,8 +58,8 @@
   MockGpuMemoryBufferFactory() {}
   virtual ~MockGpuMemoryBufferFactory() {}
 
-  MOCK_METHOD3(CreateGpuMemoryBuffer,
-               gfx::GpuMemoryBuffer*(size_t, size_t, unsigned));
+  MOCK_METHOD4(CreateGpuMemoryBuffer,
+               gfx::GpuMemoryBuffer*(size_t, size_t, unsigned, unsigned));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockGpuMemoryBufferFactory);
@@ -126,8 +126,10 @@
   handle.type = gfx::SHARED_MEMORY_BUFFER;
   handle.handle = duped_shared_memory_handle;
 
-  EXPECT_CALL(*gpu_memory_buffer_factory_.get(), CreateGpuMemoryBuffer(
-      kImageWidth, kImageHeight, GL_RGBA8_OES))
+  EXPECT_CALL(
+      *gpu_memory_buffer_factory_.get(),
+      CreateGpuMemoryBuffer(
+          kImageWidth, kImageHeight, GL_RGBA8_OES, GL_IMAGE_MAP_CHROMIUM))
       .Times(1)
       .WillOnce(Return(gpu_memory_buffer))
       .RetiresOnSaturation();
@@ -138,7 +140,7 @@
 
   // Create the image. This should add the image ID to the ImageManager.
   GLuint image_id = glCreateImageCHROMIUM(
-      kImageWidth, kImageHeight, GL_RGBA8_OES);
+      kImageWidth, kImageHeight, GL_RGBA8_OES, GL_IMAGE_MAP_CHROMIUM);
   EXPECT_NE(0u, image_id);
   EXPECT_TRUE(image_manager_->LookupImage(image_id) != NULL);
 
@@ -149,12 +151,11 @@
   shared_memory.Map(bytes);
   EXPECT_TRUE(shared_memory.memory());
 
-  EXPECT_CALL(*gpu_memory_buffer, Map(gfx::GpuMemoryBuffer::READ_WRITE))
+  EXPECT_CALL(*gpu_memory_buffer, Map())
       .Times(1)
       .WillOnce(Return(shared_memory.memory()))
       .RetiresOnSaturation();
-  uint8* mapped_buffer = static_cast<uint8*>(
-      glMapImageCHROMIUM(image_id, GL_READ_WRITE));
+  uint8* mapped_buffer = static_cast<uint8*>(glMapImageCHROMIUM(image_id));
   ASSERT_TRUE(mapped_buffer != NULL);
 
   // Assign a value to each pixel.
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 2471451..b0b947e 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "gpu/command_buffer/client/gles2_implementation.h"
 #include "gpu/command_buffer/client/gles2_lib.h"
+#include "gpu/command_buffer/client/gpu_memory_buffer_factory.h"
 #include "gpu/command_buffer/client/transfer_buffer.h"
 #include "gpu/command_buffer/common/constants.h"
 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
@@ -44,7 +45,7 @@
       image_manager(NULL) {}
 
 GLManager::GLManager()
-    : context_lost_allowed_(false) {
+    : context_lost_allowed_(false), gpu_memory_buffer_factory_(NULL) {
   SetupBaseContext();
 }
 
@@ -171,12 +172,10 @@
       ::gpu::gles2::DisallowedFeatures(),
       attribs)) << "could not initialize decoder";
 
-  gpu_control_.reset(
+  gpu_control_service_.reset(
       new GpuControlService(decoder_->GetContextGroup()->image_manager(),
-                            options.gpu_memory_buffer_factory,
-                            decoder_->GetContextGroup()->mailbox_manager(),
-                            decoder_->GetQueryManager(),
-                            decoder_->GetCapabilities()));
+                            decoder_->GetQueryManager()));
+  gpu_memory_buffer_factory_ = options.gpu_memory_buffer_factory;
 
   command_buffer_->SetPutOffsetChangeCallback(
       base::Bind(&GLManager::PumpCommands, base::Unretained(this)));
@@ -197,7 +196,7 @@
                                      transfer_buffer_.get(),
                                      options.bind_generates_resource,
                                      options.lose_context_when_out_of_memory,
-                                     gpu_control_.get()));
+                                     this));
 
   ASSERT_TRUE(gles2_implementation_->Initialize(
       kStartTransferBufferSize,
@@ -269,4 +268,66 @@
   return gpu_scheduler_->SetGetBuffer(transfer_buffer_id);
 }
 
+Capabilities GLManager::GetCapabilities() {
+  return decoder_->GetCapabilities();
+}
+
+gfx::GpuMemoryBuffer* GLManager::CreateGpuMemoryBuffer(
+    size_t width,
+    size_t height,
+    unsigned internalformat,
+    unsigned usage,
+    int32* id) {
+  *id = -1;
+  scoped_ptr<gfx::GpuMemoryBuffer> buffer(
+      gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(
+          width, height, internalformat, usage));
+  if (!buffer.get())
+    return NULL;
+
+  static int32 next_id = 1;
+  *id = next_id++;
+  gpu_control_service_->RegisterGpuMemoryBuffer(
+      *id, buffer->GetHandle(), width, height, internalformat);
+  gfx::GpuMemoryBuffer* raw_buffer = buffer.get();
+  memory_buffers_.add(*id, buffer.Pass());
+  return raw_buffer;
+}
+
+void GLManager::DestroyGpuMemoryBuffer(int32 id) {
+  memory_buffers_.erase(id);
+  gpu_control_service_->UnregisterGpuMemoryBuffer(id);
+}
+
+uint32 GLManager::InsertSyncPoint() {
+  NOTIMPLEMENTED();
+  return 0u;
+}
+
+void GLManager::SignalSyncPoint(uint32 sync_point,
+                             const base::Closure& callback) {
+  NOTIMPLEMENTED();
+}
+
+void GLManager::SignalQuery(uint32 query, const base::Closure& callback) {
+  NOTIMPLEMENTED();
+}
+
+void GLManager::SetSurfaceVisible(bool visible) {
+  NOTIMPLEMENTED();
+}
+
+void GLManager::SendManagedMemoryStats(const ManagedMemoryStats& stats) {
+  NOTIMPLEMENTED();
+}
+
+void GLManager::Echo(const base::Closure& callback) {
+  NOTIMPLEMENTED();
+}
+
+uint32 GLManager::CreateStreamTexture(uint32 texture_id) {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
 }  // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h
index 6eb5909..feb40a1 100644
--- a/gpu/command_buffer/tests/gl_manager.h
+++ b/gpu/command_buffer/tests/gl_manager.h
@@ -5,8 +5,10 @@
 #ifndef GPU_COMMAND_BUFFER_TESTS_GL_MANAGER_H_
 #define GPU_COMMAND_BUFFER_TESTS_GL_MANAGER_H_
 
+#include "base/containers/scoped_ptr_hash_map.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "gpu/command_buffer/client/gpu_control.h"
 #include "gpu/command_buffer/service/feature_info.h"
 #include "ui/gfx/size.h"
 
@@ -39,7 +41,7 @@
 
 };
 
-class GLManager {
+class GLManager : private GpuControl {
  public:
   struct Options {
     Options();
@@ -63,7 +65,7 @@
     GpuMemoryBufferFactory* gpu_memory_buffer_factory;
   };
   GLManager();
-  ~GLManager();
+  virtual ~GLManager();
 
   void Initialize(const Options& options);
   void Destroy();
@@ -94,6 +96,24 @@
 
   const gpu::gles2::FeatureInfo::Workarounds& workarounds() const;
 
+  // GpuControl implementation.
+  virtual Capabilities GetCapabilities() OVERRIDE;
+  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(size_t width,
+                                                      size_t height,
+                                                      unsigned internalformat,
+                                                      unsigned usage,
+                                                      int32* id) OVERRIDE;
+  virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
+  virtual uint32 InsertSyncPoint() OVERRIDE;
+  virtual void SignalSyncPoint(uint32 sync_point,
+                               const base::Closure& callback) OVERRIDE;
+  virtual void SignalQuery(uint32 query,
+                           const base::Closure& callback) OVERRIDE;
+  virtual void SetSurfaceVisible(bool visible) OVERRIDE;
+  virtual void SendManagedMemoryStats(const ManagedMemoryStats& stats) OVERRIDE;
+  virtual void Echo(const base::Closure& callback) OVERRIDE;
+  virtual uint32 CreateStreamTexture(uint32 texture_id) OVERRIDE;
+
  private:
   void PumpCommands();
   bool GetBufferChanged(int32 transfer_buffer_id);
@@ -102,7 +122,7 @@
   scoped_refptr<gles2::MailboxManager> mailbox_manager_;
   scoped_refptr<gfx::GLShareGroup> share_group_;
   scoped_ptr<CommandBufferService> command_buffer_;
-  scoped_ptr<GpuControlService> gpu_control_;
+  scoped_ptr<GpuControlService> gpu_control_service_;
   scoped_ptr<gles2::GLES2Decoder> decoder_;
   scoped_ptr<GpuScheduler> gpu_scheduler_;
   scoped_refptr<gfx::GLSurface> surface_;
@@ -112,6 +132,10 @@
   scoped_ptr<gles2::GLES2Implementation> gles2_implementation_;
   bool context_lost_allowed_;
 
+  // Client GpuControl implementation.
+  GpuMemoryBufferFactory* gpu_memory_buffer_factory_;
+  base::ScopedPtrHashMap<int32, gfx::GpuMemoryBuffer> memory_buffers_;
+
   // Used on Android to virtualize GL for all contexts.
   static int use_count_;
   static scoped_refptr<gfx::GLShareGroup>* base_share_group_;
diff --git a/gpu/command_buffer_client.gypi b/gpu/command_buffer_client.gypi
index cb52ee7..1e9f778 100644
--- a/gpu/command_buffer_client.gypi
+++ b/gpu/command_buffer_client.gypi
@@ -19,6 +19,7 @@
     'command_buffer/client/cmd_buffer_helper.h',
     'command_buffer/client/fenced_allocator.cc',
     'command_buffer/client/fenced_allocator.h',
+    'command_buffer/client/gpu_control.h',
     'command_buffer/client/mapped_memory.cc',
     'command_buffer/client/mapped_memory.h',
     'command_buffer/client/ring_buffer.cc',
diff --git a/gpu/command_buffer_client.target.darwin-arm.mk b/gpu/command_buffer_client.target.darwin-arm.mk
index 86df9b6..2ae7df5 100644
--- a/gpu/command_buffer_client.target.darwin-arm.mk
+++ b/gpu/command_buffer_client.target.darwin-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +133,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/command_buffer_client.target.darwin-x86.mk b/gpu/command_buffer_client.target.darwin-x86.mk
index 499d47a..b859b01 100644
--- a/gpu/command_buffer_client.target.darwin-x86.mk
+++ b/gpu/command_buffer_client.target.darwin-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer_client.target.darwin-x86_64.mk b/gpu/command_buffer_client.target.darwin-x86_64.mk
index b3ff4f2..658b4d3 100644
--- a/gpu/command_buffer_client.target.darwin-x86_64.mk
+++ b/gpu/command_buffer_client.target.darwin-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer_client.target.linux-arm.mk b/gpu/command_buffer_client.target.linux-arm.mk
index 86df9b6..2ae7df5 100644
--- a/gpu/command_buffer_client.target.linux-arm.mk
+++ b/gpu/command_buffer_client.target.linux-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +133,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/command_buffer_client.target.linux-x86.mk b/gpu/command_buffer_client.target.linux-x86.mk
index 499d47a..b859b01 100644
--- a/gpu/command_buffer_client.target.linux-x86.mk
+++ b/gpu/command_buffer_client.target.linux-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer_client.target.linux-x86_64.mk b/gpu/command_buffer_client.target.linux-x86_64.mk
index b3ff4f2..658b4d3 100644
--- a/gpu/command_buffer_client.target.linux-x86_64.mk
+++ b/gpu/command_buffer_client.target.linux-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer_common.gypi b/gpu/command_buffer_common.gypi
index b5f3858..7c9d2ec 100644
--- a/gpu/command_buffer_common.gypi
+++ b/gpu/command_buffer_common.gypi
@@ -23,7 +23,6 @@
     'command_buffer/common/gles2_cmd_format_autogen.h',
     'command_buffer/common/gles2_cmd_ids.h',
     'command_buffer/common/gles2_cmd_ids_autogen.h',
-    'command_buffer/common/gpu_control.h',
     'command_buffer/common/id_allocator.cc',
     'command_buffer/common/id_allocator.h',
     'command_buffer/common/mailbox.cc',
@@ -32,6 +31,5 @@
     'command_buffer/common/mailbox_holder.h',
     'command_buffer/common/thread_local.h',
     'command_buffer/common/time.h',
-    'command_buffer/common/types.h',
   ],
 }
diff --git a/gpu/command_buffer_common.target.darwin-arm.mk b/gpu/command_buffer_common.target.darwin-arm.mk
index bcdc154..570cb0b 100644
--- a/gpu/command_buffer_common.target.darwin-arm.mk
+++ b/gpu/command_buffer_common.target.darwin-arm.mk
@@ -49,7 +49,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +136,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/command_buffer_common.target.darwin-x86.mk b/gpu/command_buffer_common.target.darwin-x86.mk
index 59a3a39..63923cc 100644
--- a/gpu/command_buffer_common.target.darwin-x86.mk
+++ b/gpu/command_buffer_common.target.darwin-x86.mk
@@ -51,7 +51,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer_common.target.darwin-x86_64.mk b/gpu/command_buffer_common.target.darwin-x86_64.mk
index f296568..f127637 100644
--- a/gpu/command_buffer_common.target.darwin-x86_64.mk
+++ b/gpu/command_buffer_common.target.darwin-x86_64.mk
@@ -51,7 +51,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer_common.target.linux-arm.mk b/gpu/command_buffer_common.target.linux-arm.mk
index bcdc154..570cb0b 100644
--- a/gpu/command_buffer_common.target.linux-arm.mk
+++ b/gpu/command_buffer_common.target.linux-arm.mk
@@ -49,7 +49,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +136,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/command_buffer_common.target.linux-x86.mk b/gpu/command_buffer_common.target.linux-x86.mk
index 59a3a39..63923cc 100644
--- a/gpu/command_buffer_common.target.linux-x86.mk
+++ b/gpu/command_buffer_common.target.linux-x86.mk
@@ -51,7 +51,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer_common.target.linux-x86_64.mk b/gpu/command_buffer_common.target.linux-x86_64.mk
index f296568..f127637 100644
--- a/gpu/command_buffer_common.target.linux-x86_64.mk
+++ b/gpu/command_buffer_common.target.linux-x86_64.mk
@@ -51,7 +51,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/command_buffer_service.target.darwin-arm.mk b/gpu/command_buffer_service.target.darwin-arm.mk
index ac787a2..9cf8417 100644
--- a/gpu/command_buffer_service.target.darwin-arm.mk
+++ b/gpu/command_buffer_service.target.darwin-arm.mk
@@ -91,7 +91,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -142,11 +141,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -226,7 +220,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -278,11 +271,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/command_buffer_service.target.darwin-arm64.mk b/gpu/command_buffer_service.target.darwin-arm64.mk
index e75de87..ddd6521 100644
--- a/gpu/command_buffer_service.target.darwin-arm64.mk
+++ b/gpu/command_buffer_service.target.darwin-arm64.mk
@@ -138,11 +138,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -269,11 +264,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/command_buffer_service.target.darwin-mips.mk b/gpu/command_buffer_service.target.darwin-mips.mk
index ec9a16c..3f8fedd 100644
--- a/gpu/command_buffer_service.target.darwin-mips.mk
+++ b/gpu/command_buffer_service.target.darwin-mips.mk
@@ -141,11 +141,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -276,11 +271,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/command_buffer_service.target.darwin-x86.mk b/gpu/command_buffer_service.target.darwin-x86.mk
index d1ede33..61de8d3 100644
--- a/gpu/command_buffer_service.target.darwin-x86.mk
+++ b/gpu/command_buffer_service.target.darwin-x86.mk
@@ -93,7 +93,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -143,11 +142,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -228,7 +222,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -279,11 +272,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/command_buffer_service.target.darwin-x86_64.mk b/gpu/command_buffer_service.target.darwin-x86_64.mk
index ab5da14..0257408 100644
--- a/gpu/command_buffer_service.target.darwin-x86_64.mk
+++ b/gpu/command_buffer_service.target.darwin-x86_64.mk
@@ -93,7 +93,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -143,11 +142,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -228,7 +222,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -279,11 +272,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/command_buffer_service.target.linux-arm.mk b/gpu/command_buffer_service.target.linux-arm.mk
index ac787a2..9cf8417 100644
--- a/gpu/command_buffer_service.target.linux-arm.mk
+++ b/gpu/command_buffer_service.target.linux-arm.mk
@@ -91,7 +91,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -142,11 +141,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -226,7 +220,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -278,11 +271,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/command_buffer_service.target.linux-arm64.mk b/gpu/command_buffer_service.target.linux-arm64.mk
index e75de87..ddd6521 100644
--- a/gpu/command_buffer_service.target.linux-arm64.mk
+++ b/gpu/command_buffer_service.target.linux-arm64.mk
@@ -138,11 +138,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -269,11 +264,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/command_buffer_service.target.linux-mips.mk b/gpu/command_buffer_service.target.linux-mips.mk
index ec9a16c..3f8fedd 100644
--- a/gpu/command_buffer_service.target.linux-mips.mk
+++ b/gpu/command_buffer_service.target.linux-mips.mk
@@ -141,11 +141,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -276,11 +271,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/command_buffer_service.target.linux-x86.mk b/gpu/command_buffer_service.target.linux-x86.mk
index d1ede33..61de8d3 100644
--- a/gpu/command_buffer_service.target.linux-x86.mk
+++ b/gpu/command_buffer_service.target.linux-x86.mk
@@ -93,7 +93,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -143,11 +142,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -228,7 +222,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -279,11 +272,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/command_buffer_service.target.linux-x86_64.mk b/gpu/command_buffer_service.target.linux-x86_64.mk
index ab5da14..0257408 100644
--- a/gpu/command_buffer_service.target.linux-x86_64.mk
+++ b/gpu/command_buffer_service.target.linux-x86_64.mk
@@ -93,7 +93,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -143,11 +142,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -228,7 +222,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -279,11 +272,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/config/gpu_control_list.cc b/gpu/config/gpu_control_list.cc
index 30593ed..f921b00 100644
--- a/gpu/config/gpu_control_list.cc
+++ b/gpu/config/gpu_control_list.cc
@@ -94,6 +94,10 @@
 const char kMultiGpuCategoryStringActive[] = "active";
 const char kMultiGpuCategoryStringAny[] = "any";
 
+const char kGLTypeStringGL[] = "gl";
+const char kGLTypeStringGLES[] = "gles";
+const char kGLTypeStringANGLE[] = "angle";
+
 const char kVersionStyleStringNumerical[] = "numerical";
 const char kVersionStyleStringLexical[] = "lexical";
 
@@ -551,6 +555,31 @@
     dictionary_entry_count++;
   }
 
+  std::string gl_type;
+  if (value->GetString("gl_type", &gl_type)) {
+    if (!entry->SetGLType(gl_type)) {
+      LOG(WARNING) << "Malformed gl_type entry " << entry->id();
+      return NULL;
+    }
+    dictionary_entry_count++;
+  }
+
+  const base::DictionaryValue* gl_version_value = NULL;
+  if (value->GetDictionary("gl_version", &gl_version_value)) {
+    std::string version_op = "any";
+    std::string version_string;
+    std::string version_string2;
+    gl_version_value->GetString(kOp, &version_op);
+    gl_version_value->GetString("value", &version_string);
+    gl_version_value->GetString("value2", &version_string2);
+    if (!entry->SetGLVersionInfo(
+            version_op, version_string, version_string2)) {
+      LOG(WARNING) << "Malformed gl_version entry " << entry->id();
+      return NULL;
+    }
+    dictionary_entry_count++;
+  }
+
   const base::DictionaryValue* gl_vendor_value = NULL;
   if (value->GetDictionary("gl_vendor", &gl_vendor_value)) {
     std::string vendor_op;
@@ -768,6 +797,12 @@
     LOG(WARNING) << "Entry with unknown fields " << entry->id();
     return NULL;
   }
+
+  // If GL_VERSION is specified, but no info about whether it's GL or GLES,
+  // we use the default for the platform.  See GLType enum declaration.
+  if (entry->gl_version_info_.get() != NULL && entry->gl_type_ == kGLTypeNone)
+    entry->gl_type_ = GetDefaultGLType();
+
   return entry;
 }
 
@@ -776,7 +811,8 @@
       disabled_(false),
       vendor_id_(0),
       multi_gpu_style_(kMultiGpuStyleNone),
-      multi_gpu_category_(kMultiGpuCategoryPrimary) {
+      multi_gpu_category_(kMultiGpuCategoryPrimary),
+      gl_type_(kGLTypeNone) {
 }
 
 GpuControlList::GpuControlListEntry::~GpuControlListEntry() { }
@@ -838,6 +874,15 @@
   return true;
 }
 
+bool GpuControlList::GpuControlListEntry::SetGLType(
+    const std::string& gl_type_string) {
+  GLType gl_type = StringToGLType(gl_type_string);
+  if (gl_type == kGLTypeNone)
+    return false;
+  gl_type_ = gl_type;
+  return true;
+}
+
 bool GpuControlList::GpuControlListEntry::SetDriverVendorInfo(
     const std::string& vendor_op,
     const std::string& vendor_value) {
@@ -864,6 +909,15 @@
   return driver_date_info_->IsValid();
 }
 
+bool GpuControlList::GpuControlListEntry::SetGLVersionInfo(
+    const std::string& version_op,
+    const std::string& version_string,
+    const std::string& version_string2) {
+  gl_version_info_.reset(new VersionInfo(
+      version_op, std::string(), version_string, version_string2));
+  return gl_version_info_->IsValid();
+}
+
 bool GpuControlList::GpuControlListEntry::SetGLVendorInfo(
     const std::string& vendor_op,
     const std::string& vendor_value) {
@@ -984,6 +1038,38 @@
   exceptions_.push_back(exception);
 }
 
+bool GpuControlList::GpuControlListEntry::GLVersionInfoMismatch(
+    const std::string& gl_version) const {
+  if (gl_version.empty())
+    return false;
+
+  if (gl_version_info_.get() == NULL && gl_type_ == kGLTypeNone)
+    return false;
+
+  std::vector<std::string> segments;
+  base::SplitString(gl_version, ' ', &segments);
+  std::string number;
+  GLType gl_type = kGLTypeNone;
+  if (segments.size() > 2 &&
+      segments[0] == "OpenGL" && segments[1] == "ES") {
+    number = segments[2];
+    gl_type = kGLTypeGLES;
+    if (segments.size() > 3 &&
+        StartsWithASCII(segments[3], "(ANGLE", false)) {
+      gl_type = kGLTypeANGLE;
+    }
+  } else {
+    number = segments[0];
+    gl_type = kGLTypeGL;
+  }
+
+  if (gl_type_ != kGLTypeNone && gl_type_ != gl_type)
+    return true;
+  if (gl_version_info_.get() != NULL && !gl_version_info_->Contains(number))
+    return true;
+  return false;
+}
+
 // static
 GpuControlList::GpuControlListEntry::MultiGpuStyle
 GpuControlList::GpuControlListEntry::StringToMultiGpuStyle(
@@ -1010,6 +1096,37 @@
   return kMultiGpuCategoryNone;
 }
 
+// static
+GpuControlList::GpuControlListEntry::GLType
+GpuControlList::GpuControlListEntry::StringToGLType(
+    const std::string& gl_type) {
+  if (gl_type == kGLTypeStringGL)
+    return kGLTypeGL;
+  if (gl_type == kGLTypeStringGLES)
+    return kGLTypeGLES;
+  if (gl_type == kGLTypeStringANGLE)
+    return kGLTypeANGLE;
+  return kGLTypeNone;
+}
+
+// static
+GpuControlList::GpuControlListEntry::GLType
+GpuControlList::GpuControlListEntry::GetDefaultGLType() {
+#if defined(OS_CHROMEOS)
+  return kGLTypeGL;
+#elif defined(OS_LINUX) || defined(OS_OPENBSD)
+  return kGLTypeGL;
+#elif defined(OS_MACOSX)
+  return kGLTypeGL;
+#elif defined(OS_WIN)
+  return kGLTypeANGLE;
+#elif defined(OS_ANDROID)
+  return kGLTypeGLES;
+#else
+  return kGLTypeNone;
+#endif
+}
+
 void GpuControlList::GpuControlListEntry::LogControlListMatch(
     const std::string& control_list_logging_name) const {
   static const char kControlListMatchMessage[] =
@@ -1096,6 +1213,8 @@
     if (!driver_date_info_->Contains(gpu_info.driver_date, '-'))
       return false;
   }
+  if (GLVersionInfoMismatch(gpu_info.gl_version))
+    return false;
   if (gl_vendor_info_.get() != NULL && !gpu_info.gl_vendor.empty() &&
       !gl_vendor_info_->Contains(gpu_info.gl_vendor))
     return false;
diff --git a/gpu/config/gpu_control_list.h b/gpu/config/gpu_control_list.h
index c3f1cf6..2616940 100644
--- a/gpu/config/gpu_control_list.h
+++ b/gpu/config/gpu_control_list.h
@@ -339,6 +339,13 @@
       kMultiGpuCategoryNone
     };
 
+    enum GLType {
+      kGLTypeGL,  // This is default on MacOSX, Linux, ChromeOS
+      kGLTypeGLES,  // This is default on Android
+      kGLTypeANGLE,  // This is default on Windows
+      kGLTypeNone
+    };
+
     GpuControlListEntry();
     ~GpuControlListEntry();
 
@@ -359,6 +366,8 @@
 
     bool SetMultiGpuCategory(const std::string& multi_gpu_category_string);
 
+    bool SetGLType(const std::string& gl_type_string);
+
     bool SetDriverVendorInfo(const std::string& vendor_op,
                              const std::string& vendor_value);
 
@@ -371,6 +380,10 @@
                            const std::string& date_string,
                            const std::string& date_string2);
 
+    bool SetGLVersionInfo(const std::string& version_op,
+                          const std::string& version_string,
+                          const std::string& version_string2);
+
     bool SetGLVendorInfo(const std::string& vendor_op,
                          const std::string& vendor_value);
 
@@ -417,17 +430,27 @@
 
     void AddException(ScopedGpuControlListEntry exception);
 
+    // Return true if GL_VERSION string does not fit the entry info
+    // on GL type and GL version.
+    bool GLVersionInfoMismatch(const std::string& gl_version) const;
+
     static MultiGpuStyle StringToMultiGpuStyle(const std::string& style);
 
     static MultiGpuCategory StringToMultiGpuCategory(
         const std::string& category);
 
+    static GLType StringToGLType(const std::string& gl_type);
+
     // map a feature_name to feature_id. If the string is not a registered
     // feature name, return false.
     static bool StringToFeature(const std::string& feature_name,
                                 int* feature_id,
                                 const FeatureMap& feature_map);
 
+    // Return the default GL type, depending on the OS.
+    // See GLType declaration.
+    static GLType GetDefaultGLType();
+
     uint32 id_;
     bool disabled_;
     std::string description_;
@@ -438,9 +461,11 @@
     std::vector<uint32> device_id_list_;
     MultiGpuStyle multi_gpu_style_;
     MultiGpuCategory multi_gpu_category_;
+    GLType gl_type_;
     scoped_ptr<StringInfo> driver_vendor_info_;
     scoped_ptr<VersionInfo> driver_version_info_;
     scoped_ptr<VersionInfo> driver_date_info_;
+    scoped_ptr<VersionInfo> gl_version_info_;
     scoped_ptr<StringInfo> gl_vendor_info_;
     scoped_ptr<StringInfo> gl_renderer_info_;
     scoped_ptr<StringInfo> gl_extensions_info_;
diff --git a/gpu/config/gpu_control_list_entry_unittest.cc b/gpu/config/gpu_control_list_entry_unittest.cc
index 7caad43..6ae866b 100644
--- a/gpu/config/gpu_control_list_entry_unittest.cc
+++ b/gpu/config/gpu_control_list_entry_unittest.cc
@@ -56,6 +56,7 @@
     gpu_info_.driver_vendor = "NVIDIA";
     gpu_info_.driver_version = "1.6.18";
     gpu_info_.driver_date = "7-14-2009";
+    gpu_info_.gl_version = "2.1 NVIDIA-8.24.11 310.90.9b01";
     gpu_info_.gl_vendor = "NVIDIA Corporation";
     gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine";
     gpu_info_.performance_stats.graphics = 5.0;
@@ -376,6 +377,99 @@
   EXPECT_TRUE(entry.get() == NULL);
 }
 
+TEST_F(GpuControlListEntryTest, GlVersionGLESEntry) {
+  const std::string json = LONG_STRING_CONST(
+      {
+        "id": 1,
+        "gl_type": "gles",
+        "gl_version": {
+          "op": "=",
+          "value": "3.0"
+        },
+        "features": [
+          "test_feature_0"
+        ]
+      }
+  );
+  ScopedEntry entry(GetEntryFromString(json));
+  EXPECT_TRUE(entry.get() != NULL);
+
+  GPUInfo gpu_info;
+  gpu_info.gl_version = "OpenGL ES 3.0 V@66.0 AU@ (CL@)";
+  EXPECT_TRUE(entry->Contains(GpuControlList::kOsAndroid, "4.4.2", gpu_info));
+
+  gpu_info.gl_version = "OpenGL ES 3.1 V@66.0 AU@ (CL@)";
+  EXPECT_FALSE(entry->Contains(GpuControlList::kOsAndroid, "4.4.2", gpu_info));
+
+  gpu_info.gl_version = "3.0 NVIDIA-8.24.11 310.90.9b01";
+  EXPECT_FALSE(entry->Contains(GpuControlList::kOsMacosx, "10.9", gpu_info));
+
+  gpu_info.gl_version = "OpenGL ES 3.0 (ANGLE 1.2.0.2450)";
+  EXPECT_FALSE(entry->Contains(GpuControlList::kOsWin, "6.1", gpu_info));
+}
+
+TEST_F(GpuControlListEntryTest, GlVersionANGLEEntry) {
+  const std::string json = LONG_STRING_CONST(
+      {
+        "id": 1,
+        "gl_type": "angle",
+        "gl_version": {
+          "op": ">",
+          "value": "2.0"
+        },
+        "features": [
+          "test_feature_0"
+        ]
+      }
+  );
+  ScopedEntry entry(GetEntryFromString(json));
+  EXPECT_TRUE(entry.get() != NULL);
+
+  GPUInfo gpu_info;
+  gpu_info.gl_version = "OpenGL ES 3.0 V@66.0 AU@ (CL@)";
+  EXPECT_FALSE(entry->Contains(GpuControlList::kOsAndroid, "4.4.2", gpu_info));
+
+  gpu_info.gl_version = "3.0 NVIDIA-8.24.11 310.90.9b01";
+  EXPECT_FALSE(entry->Contains(GpuControlList::kOsMacosx, "10.9", gpu_info));
+
+  gpu_info.gl_version = "OpenGL ES 3.0 (ANGLE 1.2.0.2450)";
+  EXPECT_TRUE(entry->Contains(GpuControlList::kOsWin, "6.1", gpu_info));
+
+  gpu_info.gl_version = "OpenGL ES 2.0 (ANGLE 1.2.0.2450)";
+  EXPECT_FALSE(entry->Contains(GpuControlList::kOsWin, "6.1", gpu_info));
+}
+
+TEST_F(GpuControlListEntryTest, GlVersionGLEntry) {
+  const std::string json = LONG_STRING_CONST(
+      {
+        "id": 1,
+        "gl_type": "gl",
+        "gl_version": {
+          "op": "<",
+          "value": "4.0"
+        },
+        "features": [
+          "test_feature_0"
+        ]
+      }
+  );
+  ScopedEntry entry(GetEntryFromString(json));
+  EXPECT_TRUE(entry.get() != NULL);
+
+  GPUInfo gpu_info;
+  gpu_info.gl_version = "OpenGL ES 3.0 V@66.0 AU@ (CL@)";
+  EXPECT_FALSE(entry->Contains(GpuControlList::kOsAndroid, "4.4.2", gpu_info));
+
+  gpu_info.gl_version = "3.0 NVIDIA-8.24.11 310.90.9b01";
+  EXPECT_TRUE(entry->Contains(GpuControlList::kOsMacosx, "10.9", gpu_info));
+
+  gpu_info.gl_version = "4.0 NVIDIA-8.24.11 310.90.9b01";
+  EXPECT_FALSE(entry->Contains(GpuControlList::kOsMacosx, "10.9", gpu_info));
+
+  gpu_info.gl_version = "OpenGL ES 3.0 (ANGLE 1.2.0.2450)";
+  EXPECT_FALSE(entry->Contains(GpuControlList::kOsWin, "6.1", gpu_info));
+}
+
 TEST_F(GpuControlListEntryTest, GlVendorEntry) {
   const std::string json = LONG_STRING_CONST(
       {
diff --git a/gpu/config/gpu_control_list_format.txt b/gpu/config/gpu_control_list_format.txt
index 8bd0ec1..879b91e 100644
--- a/gpu/config/gpu_control_list_format.txt
+++ b/gpu/config/gpu_control_list_format.txt
@@ -32,27 +32,32 @@
 // 8. "driver_version" is a VERSION structure (defined below).
 // 9. "driver_date" is a VERSION structure (defined below).
 //    The version is interpreted as "year.month.day".
-// 10. "gl_vendor" is a STRING structure (defined below).
-// 11. "gl_renderer" is a STRING structure (defined below).
-// 12. "gl_extensions" is a STRING structure (defined below).
-// 13. "perf_graphics" is a FLOAT structure (defined below).
-// 14. "perf_gaming" is a FLOAT structure (defined below).
-// 15. "perf_overall" is a FLOAT structure (defined below).
-// 16. "machine_model_name" is an array of strings.  The strings can contain
+// 10. "gl_type" is a string, valid values include "gl", "gles", and "angle".
+//    If "gl_version" is specified and "gl_type" is not, use the default value.
+//    The default value on Android is "gles", on Windows is "angle", on other
+//    platforms is "gl".
+// 11. "gl_version" is a VERSION structure (defined below).
+// 12. "gl_vendor" is a STRING structure (defined below).
+// 13. "gl_renderer" is a STRING structure (defined below).
+// 14. "gl_extensions" is a STRING structure (defined below).
+// 15. "perf_graphics" is a FLOAT structure (defined below).
+// 16. "perf_gaming" is a FLOAT structure (defined below).
+// 17. "perf_overall" is a FLOAT structure (defined below).
+// 18. "machine_model_name" is an array of strings.  The strings can contain
 //     any characters.
-// 17. "machine_model_version" is a VERSION structure (defined below).
-// 18. "gpu_count" is a INT structure (defined below).
-// 19  "cpu_info" is a STRING structure (defined below).
-// 20. "exceptions" is a list of entries.
-// 21. "features" is a list of gpu control list options, which can be
+// 19. "machine_model_version" is a VERSION structure (defined below).
+// 20. "gpu_count" is a INT structure (defined below).
+// 21  "cpu_info" is a STRING structure (defined below).
+// 22. "exceptions" is a list of entries.
+// 23. "features" is a list of gpu control list options, which can be
 //     configured by a specific list. See its *_json.cc file for a list of
 //     supported features. This field is mandatory.
-// 22. "description" has the description of the entry.
-// 23. "webkit_bugs" is an array of associated webkit bug numbers.
-// 24. "cr_bugs" is an array of associated webkit bug numbers.
-// 25. "disabled" is a boolean. If it is present, the entry will be skipped.
+// 24. "description" has the description of the entry.
+// 25. "webkit_bugs" is an array of associated webkit bug numbers.
+// 26. "cr_bugs" is an array of associated webkit bug numbers.
+// 27. "disabled" is a boolean. If it is present, the entry will be skipped.
 //     This can not be used in exceptions.
-// 26. "direct_rendering" is a boolean. If present, this will filter on whether
+// 28. "direct_rendering" is a boolean. If present, this will filter on whether
 // the GL contexts are direct or indirect based on the value.
 //
 // VERSION includes "op", "style", "value", and "value2".  "op" can be any of
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc
index 4240a9f..bf699f6 100644
--- a/gpu/config/gpu_driver_bug_list_json.cc
+++ b/gpu/config/gpu_driver_bug_list_json.cc
@@ -19,7 +19,7 @@
 {
   "name": "gpu driver bug list",
   // Please update the version number whenever you change this file.
-  "version": "5.1",
+  "version": "5.3",
   "entries": [
     {
       "id": 1,
@@ -932,6 +932,41 @@
       "features": [
         "disable_d3d11"
       ]
+    },
+    {
+      "id": 71,
+      "description": "Vivante's support of OES_standard_derivatives is buggy",
+      "cr_bugs": [368005],
+      "os": {
+        "type": "android"
+      },
+      "gl_extensions": {
+        "op": "contains",
+        "value": "GL_VIV_shader_binary"
+      },
+      "features": [
+        "disable_oes_standard_derivatives"
+      ]
+    },
+    {
+      "id": 72,
+      "description": "Use virtual contexts on NVIDIA with GLES 3.1",
+      "cr_bugs": [369316],
+      "os": {
+        "type": "android"
+      },
+      "gl_type": "gles",
+      "gl_version": {
+        "op": "=",
+        "value": "3.1"
+      },
+      "gl_vendor": {
+        "op": "beginwith",
+        "value": "NVidia"
+      },
+      "features": [
+        "use_virtualized_gl_contexts"
+      ]
     }
   ]
 }
diff --git a/gpu/config/gpu_info.cc b/gpu/config/gpu_info.cc
index 4734a5b..2c7e67b 100644
--- a/gpu/config/gpu_info.cc
+++ b/gpu/config/gpu_info.cc
@@ -62,7 +62,6 @@
     std::string vertex_shader_version;
     std::string machine_model_name;
     std::string machine_model_version;
-    std::string gl_version;
     std::string gl_version_string;
     std::string gl_vendor;
     std::string gl_renderer;
@@ -114,7 +113,6 @@
   enumerator->AddString("pixelShaderVersion", pixel_shader_version);
   enumerator->AddString("vertexShaderVersion", vertex_shader_version);
   enumerator->AddString("glVersion", gl_version);
-  enumerator->AddString("glVersionString", gl_version_string);
   enumerator->AddString("glVendor", gl_vendor);
   enumerator->AddString("glRenderer", gl_renderer);
   enumerator->AddString("glExtensions", gl_extensions);
diff --git a/gpu/config/gpu_info.h b/gpu/config/gpu_info.h
index 096c533..40630b3 100644
--- a/gpu/config/gpu_info.h
+++ b/gpu/config/gpu_info.h
@@ -112,20 +112,16 @@
   // See machine_model_name's comment.
   std::string machine_model_version;
 
-  // The version of OpenGL we are using.
-  // TODO(zmo): should be able to tell if it's GL or GLES.
+  // The GL_VERSION string.
   std::string gl_version;
 
-  // The GL_VERSION string.  "" if we are not using OpenGL.
-  std::string gl_version_string;
-
-  // The GL_VENDOR string.  "" if we are not using OpenGL.
+  // The GL_VENDOR string.
   std::string gl_vendor;
 
-  // The GL_RENDERER string.  "" if we are not using OpenGL.
+  // The GL_RENDERER string.
   std::string gl_renderer;
 
-  // The GL_EXTENSIONS string.  "" if we are not using OpenGL.
+  // The GL_EXTENSIONS string.
   std::string gl_extensions;
 
   // GL window system binding vendor.  "" if not available.
diff --git a/gpu/config/gpu_info_collector.cc b/gpu/config/gpu_info_collector.cc
index 2f57a4b..e464a96 100644
--- a/gpu/config/gpu_info_collector.cc
+++ b/gpu/config/gpu_info_collector.cc
@@ -99,7 +99,7 @@
   gpu_info->gl_renderer = GetGLString(GL_RENDERER);
   gpu_info->gl_vendor = GetGLString(GL_VENDOR);
   gpu_info->gl_extensions = GetGLString(GL_EXTENSIONS);
-  gpu_info->gl_version_string = GetGLString(GL_VERSION);
+  gpu_info->gl_version = GetGLString(GL_VERSION);
   std::string glsl_version_string = GetGLString(GL_SHADING_LANGUAGE_VERSION);
 
   gfx::GLWindowSystemBindingInfo window_system_binding_info;
@@ -122,7 +122,6 @@
   // clears the current context.
   context->ReleaseCurrent(surface.get());
 
-  gpu_info->gl_version = GetVersionFromString(gpu_info->gl_version_string);
   std::string glsl_version = GetVersionFromString(glsl_version_string);
   gpu_info->pixel_shader_version = glsl_version;
   gpu_info->vertex_shader_version = glsl_version;
@@ -135,9 +134,8 @@
   DCHECK(basic_gpu_info);
   basic_gpu_info->gl_renderer = context_gpu_info.gl_renderer;
   basic_gpu_info->gl_vendor = context_gpu_info.gl_vendor;
-  basic_gpu_info->gl_version_string = context_gpu_info.gl_version_string;
-  basic_gpu_info->gl_extensions = context_gpu_info.gl_extensions;
   basic_gpu_info->gl_version = context_gpu_info.gl_version;
+  basic_gpu_info->gl_extensions = context_gpu_info.gl_extensions;
   basic_gpu_info->pixel_shader_version =
       context_gpu_info.pixel_shader_version;
   basic_gpu_info->vertex_shader_version =
diff --git a/gpu/config/gpu_info_collector_android.cc b/gpu/config/gpu_info_collector_android.cc
index 21c04d1..fc6a547 100644
--- a/gpu/config/gpu_info_collector_android.cc
+++ b/gpu/config/gpu_info_collector_android.cc
@@ -110,7 +110,7 @@
 
 CollectInfoResult CollectDriverInfoGL(GPUInfo* gpu_info) {
   gpu_info->driver_version = GetDriverVersionFromString(
-      gpu_info->gl_version_string);
+      gpu_info->gl_version);
   gpu_info->gpu.vendor_string = gpu_info->gl_vendor;
   gpu_info->gpu.device_string = gpu_info->gl_renderer;
   return kCollectInfoSuccess;
diff --git a/gpu/config/gpu_info_collector_mac.mm b/gpu/config/gpu_info_collector_mac.mm
index 8eff59a..e4d404e 100644
--- a/gpu/config/gpu_info_collector_mac.mm
+++ b/gpu/config/gpu_info_collector_mac.mm
@@ -203,11 +203,10 @@
   // Mac OpenGL drivers have the driver version
   // at the end of the gl version string preceded by a dash.
   // Use some jiggery-pokery to turn that utf8 string into a std::wstring.
-  std::string gl_version_string = gpu_info->gl_version_string;
-  size_t pos = gl_version_string.find_last_of('-');
+  size_t pos = gpu_info->gl_version.find_last_of('-');
   if (pos == std::string::npos)
     return kCollectInfoNonFatalFailure;
-  gpu_info->driver_version = gl_version_string.substr(pos + 1);
+  gpu_info->driver_version = gpu_info->gl_version.substr(pos + 1);
   return kCollectInfoSuccess;
 }
 
diff --git a/gpu/config/gpu_info_collector_ozone.cc b/gpu/config/gpu_info_collector_ozone.cc
index 698cfad..b8dac84 100644
--- a/gpu/config/gpu_info_collector_ozone.cc
+++ b/gpu/config/gpu_info_collector_ozone.cc
@@ -49,11 +49,11 @@
   DCHECK(gpu_info);
   // Extract driver vendor, version from a string like:
   // "OpenGL ES 3.0 V@6.0 AU@ (CL@2946718)"
-  size_t begin = gpu_info->gl_version_string.find_first_of("0123456789");
+  size_t begin = gpu_info->gl_version.find_first_of("0123456789");
   if (begin == std::string::npos)
     return kCollectInfoNonFatalFailure;
 
-  std::string sub_string = gpu_info->gl_version_string.substr(begin);
+  std::string sub_string = gpu_info->gl_version.substr(begin);
   std::vector<std::string> pieces;
   base::SplitStringAlongWhitespace(sub_string, &pieces);
   if (pieces.size() < 3)
diff --git a/gpu/config/gpu_info_collector_unittest.cc b/gpu/config/gpu_info_collector_unittest.cc
index 0629359..c5e15c8 100644
--- a/gpu/config/gpu_info_collector_unittest.cc
+++ b/gpu/config/gpu_info_collector_unittest.cc
@@ -28,10 +28,9 @@
     const char* driver_vendor = "";  // not implemented
     const char* driver_version = "";
     const char* shader_version = "1.40";
-    const char* gl_version = "3.1";
     const char* gl_renderer = "Quadro FX 380/PCI/SSE2";
     const char* gl_vendor = "NVIDIA Corporation";
-    const char* gl_version_string = "3.1.0";
+    const char* gl_version = "3.1.0";
     const char* gl_shading_language_version = "1.40 NVIDIA via Cg compiler";
     const char* gl_extensions =
         "GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 "
@@ -42,10 +41,9 @@
     const char* driver_vendor = "";  // not implemented
     const char* driver_version = "1.6.18";
     const char* shader_version = "1.20";
-    const char* gl_version = "2.1";
     const char* gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine";
     const char* gl_vendor = "NVIDIA Corporation";
-    const char* gl_version_string = "2.1 NVIDIA-1.6.18";
+    const char* gl_version = "2.1 NVIDIA-1.6.18";
     const char* gl_shading_language_version = "1.20 ";
     const char* gl_extensions =
         "GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 "
@@ -56,10 +54,9 @@
     const char* driver_vendor = "NVIDIA";
     const char* driver_version = "195.36.24";
     const char* shader_version = "1.50";
-    const char* gl_version = "3.2";
     const char* gl_renderer = "Quadro FX 380/PCI/SSE2";
     const char* gl_vendor = "NVIDIA Corporation";
-    const char* gl_version_string = "3.2.0 NVIDIA 195.36.24";
+    const char* gl_version = "3.2.0 NVIDIA 195.36.24";
     const char* gl_shading_language_version = "1.50 NVIDIA via Cg compiler";
     const char* gl_extensions =
         "GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 "
@@ -71,10 +68,9 @@
     test_values_.driver_version =driver_version;
     test_values_.pixel_shader_version = shader_version;
     test_values_.vertex_shader_version = shader_version;
-    test_values_.gl_version = gl_version;
     test_values_.gl_renderer = gl_renderer;
     test_values_.gl_vendor = gl_vendor;
-    test_values_.gl_version_string = gl_version_string;
+    test_values_.gl_version = gl_version;
     test_values_.gl_extensions = gl_extensions;
     test_values_.can_lose_context = false;
 
@@ -86,7 +82,7 @@
             gl_shading_language_version)));
     EXPECT_CALL(*gl_, GetString(GL_VERSION))
         .WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
-            gl_version_string)));
+            gl_version)));
     EXPECT_CALL(*gl_, GetString(GL_VENDOR))
         .WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
             gl_vendor)));
@@ -145,36 +141,25 @@
 TEST_F(GPUInfoCollectorTest, DISABLED_GLVersionGL) {
   GPUInfo gpu_info;
   CollectGraphicsInfoGL(&gpu_info);
-  EXPECT_EQ(test_values_.gl_version,
-            gpu_info.gl_version);
-}
-
-TEST_F(GPUInfoCollectorTest, DISABLED_GLVersionStringGL) {
-  GPUInfo gpu_info;
-  CollectGraphicsInfoGL(&gpu_info);
-  EXPECT_EQ(test_values_.gl_version_string,
-            gpu_info.gl_version_string);
+  EXPECT_EQ(test_values_.gl_version, gpu_info.gl_version);
 }
 
 TEST_F(GPUInfoCollectorTest, DISABLED_GLRendererGL) {
   GPUInfo gpu_info;
   CollectGraphicsInfoGL(&gpu_info);
-  EXPECT_EQ(test_values_.gl_renderer,
-            gpu_info.gl_renderer);
+  EXPECT_EQ(test_values_.gl_renderer, gpu_info.gl_renderer);
 }
 
 TEST_F(GPUInfoCollectorTest, DISABLED_GLVendorGL) {
   GPUInfo gpu_info;
   CollectGraphicsInfoGL(&gpu_info);
-  EXPECT_EQ(test_values_.gl_vendor,
-            gpu_info.gl_vendor);
+  EXPECT_EQ(test_values_.gl_vendor, gpu_info.gl_vendor);
 }
 
 TEST_F(GPUInfoCollectorTest, DISABLED_GLExtensionsGL) {
   GPUInfo gpu_info;
   CollectGraphicsInfoGL(&gpu_info);
-  EXPECT_EQ(test_values_.gl_extensions,
-            gpu_info.gl_extensions);
+  EXPECT_EQ(test_values_.gl_extensions, gpu_info.gl_extensions);
 }
 
 }  // namespace gpu
diff --git a/gpu/config/gpu_info_collector_win.cc b/gpu/config/gpu_info_collector_win.cc
index ed92fee..73d5423 100644
--- a/gpu/config/gpu_info_collector_win.cc
+++ b/gpu/config/gpu_info_collector_win.cc
@@ -633,10 +633,8 @@
   if (!gpu_info->driver_version.empty())
     return kCollectInfoSuccess;
 
-  std::string gl_version_string = gpu_info->gl_version_string;
-
   bool parsed = RE2::PartialMatch(
-      gl_version_string, "([\\d\\.]+)$", &gpu_info->driver_version);
+      gpu_info->gl_version, "([\\d\\.]+)$", &gpu_info->driver_version);
   return parsed ? kCollectInfoSuccess : kCollectInfoNonFatalFailure;
 }
 
diff --git a/gpu/config/gpu_info_collector_x11.cc b/gpu/config/gpu_info_collector_x11.cc
index a603d1d..d4288b7 100644
--- a/gpu/config/gpu_info_collector_x11.cc
+++ b/gpu/config/gpu_info_collector_x11.cc
@@ -254,11 +254,11 @@
 CollectInfoResult CollectDriverInfoGL(GPUInfo* gpu_info) {
   DCHECK(gpu_info);
 
-  std::string gl_version_string = gpu_info->gl_version_string;
-  if (StartsWithASCII(gl_version_string, "OpenGL ES", true))
-    gl_version_string = gl_version_string.substr(10);
+  std::string gl_version = gpu_info->gl_version;
+  if (StartsWithASCII(gl_version, "OpenGL ES", true))
+    gl_version = gl_version.substr(10);
   std::vector<std::string> pieces;
-  base::SplitStringAlongWhitespace(gl_version_string, &pieces);
+  base::SplitStringAlongWhitespace(gl_version, &pieces);
   // In linux, the gl version string might be in the format of
   //   GLVersion DriverVendor DriverVersion
   if (pieces.size() < 3)
diff --git a/gpu/config/gpu_info_unittest.cc b/gpu/config/gpu_info_unittest.cc
index 42cbd3c..1843b5a 100644
--- a/gpu/config/gpu_info_unittest.cc
+++ b/gpu/config/gpu_info_unittest.cc
@@ -21,7 +21,6 @@
   EXPECT_EQ(gpu_info.pixel_shader_version, "");
   EXPECT_EQ(gpu_info.vertex_shader_version, "");
   EXPECT_EQ(gpu_info.gl_version, "");
-  EXPECT_EQ(gpu_info.gl_version_string, "");
   EXPECT_EQ(gpu_info.gl_vendor, "");
   EXPECT_EQ(gpu_info.gl_renderer, "");
   EXPECT_EQ(gpu_info.gl_extensions, "");
diff --git a/gpu/config/software_rendering_list_json.cc b/gpu/config/software_rendering_list_json.cc
index 5e6c2ee..837d9b4 100644
--- a/gpu/config/software_rendering_list_json.cc
+++ b/gpu/config/software_rendering_list_json.cc
@@ -18,7 +18,7 @@
 {
   "name": "software rendering list",
   // Please update the version number whenever you change this file.
-  "version": "8.2",
+  "version": "8.4",
   "entries": [
     {
       "id": 1,
@@ -162,12 +162,20 @@
     },
     {
       "id": 17,
-      "description": "Intel mesa drivers are crash-prone",
+      "description": "Older Intel mesa drivers are crash-prone",
       "cr_bugs": [76703, 164555, 225200, 340886],
       "os": {
         "type": "linux"
       },
       "vendor_id": "0x8086",
+      "driver_vendor": {
+        "op": "=",
+        "value": "Mesa"
+      },
+      "driver_version": {
+        "op": "<",
+        "value": "10.1"
+      },
       "exceptions": [
         {
           "device_id": ["0x0102", "0x0106", "0x0112", "0x0116", "0x0122", "0x0126", "0x010a", "0x0152", "0x0156", "0x015a", "0x0162", "0x0166"],
@@ -198,7 +206,7 @@
           }
         },
         {
-          "device_id": ["0x0a16"],
+          "device_id": ["0x0a16", "0x0a26"],
           "driver_version": {
             "op": ">=",
             "value": "10.0.1"
@@ -429,12 +437,28 @@
     },
     {
       "id": 37,
-      "description": "Drivers are unreliable for Optimus on Linux",
-      "cr_bugs": [131308],
+      "description": "Older drivers are unreliable for Optimus on Linux",
+      "cr_bugs": [131308, 363418],
       "os": {
         "type": "linux"
       },
       "multi_gpu_style": "optimus",
+      "exceptions": [
+        {
+          "driver_vendor": {
+            "op": "=",
+            "value": "Mesa"
+          },
+          "driver_version": {
+            "op": ">=",
+            "value": "10.1"
+          },
+          "gl_vendor": {
+            "op": "beginwith",
+            "value": "Intel"
+          }
+        }
+      ],
       "features": [
         "all"
       ]
diff --git a/gpu/disk_cache_proto.target.darwin-arm.mk b/gpu/disk_cache_proto.target.darwin-arm.mk
index bd23f9e..829dbb9 100644
--- a/gpu/disk_cache_proto.target.darwin-arm.mk
+++ b/gpu/disk_cache_proto.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "gpu_gpu_gyp_disk_cache_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['command_buffer/service/disk_cache_proto.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'command_buffer/service', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +65,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -155,7 +155,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/disk_cache_proto.target.darwin-arm64.mk b/gpu/disk_cache_proto.target.darwin-arm64.mk
index acbbb77..6916aa1 100644
--- a/gpu/disk_cache_proto.target.darwin-arm64.mk
+++ b/gpu/disk_cache_proto.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "gpu_gpu_gyp_disk_cache_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['command_buffer/service/disk_cache_proto.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'command_buffer/service', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/gpu/disk_cache_proto.target.darwin-mips.mk b/gpu/disk_cache_proto.target.darwin-mips.mk
index 8c20a25..e637b63 100644
--- a/gpu/disk_cache_proto.target.darwin-mips.mk
+++ b/gpu/disk_cache_proto.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "gpu_gpu_gyp_disk_cache_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['command_buffer/service/disk_cache_proto.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'command_buffer/service', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/gpu/disk_cache_proto.target.darwin-x86.mk b/gpu/disk_cache_proto.target.darwin-x86.mk
index 322ff8b..f40980b 100644
--- a/gpu/disk_cache_proto.target.darwin-x86.mk
+++ b/gpu/disk_cache_proto.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "gpu_gpu_gyp_disk_cache_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['command_buffer/service/disk_cache_proto.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'command_buffer/service', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/disk_cache_proto.target.darwin-x86_64.mk b/gpu/disk_cache_proto.target.darwin-x86_64.mk
index 2483f0b..4ecfb5c 100644
--- a/gpu/disk_cache_proto.target.darwin-x86_64.mk
+++ b/gpu/disk_cache_proto.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "gpu_gpu_gyp_disk_cache_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['command_buffer/service/disk_cache_proto.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'command_buffer/service', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/disk_cache_proto.target.linux-arm.mk b/gpu/disk_cache_proto.target.linux-arm.mk
index bd23f9e..829dbb9 100644
--- a/gpu/disk_cache_proto.target.linux-arm.mk
+++ b/gpu/disk_cache_proto.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "gpu_gpu_gyp_disk_cache_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['command_buffer/service/disk_cache_proto.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'command_buffer/service', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +65,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -155,7 +155,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/disk_cache_proto.target.linux-arm64.mk b/gpu/disk_cache_proto.target.linux-arm64.mk
index acbbb77..6916aa1 100644
--- a/gpu/disk_cache_proto.target.linux-arm64.mk
+++ b/gpu/disk_cache_proto.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "gpu_gpu_gyp_disk_cache_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['command_buffer/service/disk_cache_proto.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'command_buffer/service', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/gpu/disk_cache_proto.target.linux-mips.mk b/gpu/disk_cache_proto.target.linux-mips.mk
index 8c20a25..e637b63 100644
--- a/gpu/disk_cache_proto.target.linux-mips.mk
+++ b/gpu/disk_cache_proto.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "gpu_gpu_gyp_disk_cache_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['command_buffer/service/disk_cache_proto.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'command_buffer/service', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/gpu/disk_cache_proto.target.linux-x86.mk b/gpu/disk_cache_proto.target.linux-x86.mk
index 322ff8b..f40980b 100644
--- a/gpu/disk_cache_proto.target.linux-x86.mk
+++ b/gpu/disk_cache_proto.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "gpu_gpu_gyp_disk_cache_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['command_buffer/service/disk_cache_proto.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'command_buffer/service', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/disk_cache_proto.target.linux-x86_64.mk b/gpu/disk_cache_proto.target.linux-x86_64.mk
index 2483f0b..4ecfb5c 100644
--- a/gpu/disk_cache_proto.target.linux-x86_64.mk
+++ b/gpu/disk_cache_proto.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "gpu_gpu_gyp_disk_cache_proto_target_genproto":
 # "{'inputs': ['../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['command_buffer/service/disk_cache_proto.proto'], 'action': ['python', '../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'command_buffer/service', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/gpu/command_buffer/service', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/gpu/command_buffer/service/disk_cache_proto_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -157,7 +157,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gl_in_process_context.target.darwin-arm.mk b/gpu/gl_in_process_context.target.darwin-arm.mk
index b6c367f..96b2a89 100644
--- a/gpu/gl_in_process_context.target.darwin-arm.mk
+++ b/gpu/gl_in_process_context.target.darwin-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gl_in_process_context.target.darwin-x86.mk b/gpu/gl_in_process_context.target.darwin-x86.mk
index 1d0d54b..bdd9307 100644
--- a/gpu/gl_in_process_context.target.darwin-x86.mk
+++ b/gpu/gl_in_process_context.target.darwin-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gl_in_process_context.target.darwin-x86_64.mk b/gpu/gl_in_process_context.target.darwin-x86_64.mk
index 2d66906..ac16350 100644
--- a/gpu/gl_in_process_context.target.darwin-x86_64.mk
+++ b/gpu/gl_in_process_context.target.darwin-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gl_in_process_context.target.linux-arm.mk b/gpu/gl_in_process_context.target.linux-arm.mk
index b6c367f..96b2a89 100644
--- a/gpu/gl_in_process_context.target.linux-arm.mk
+++ b/gpu/gl_in_process_context.target.linux-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gl_in_process_context.target.linux-x86.mk b/gpu/gl_in_process_context.target.linux-x86.mk
index 1d0d54b..bdd9307 100644
--- a/gpu/gl_in_process_context.target.linux-x86.mk
+++ b/gpu/gl_in_process_context.target.linux-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gl_in_process_context.target.linux-x86_64.mk b/gpu/gl_in_process_context.target.linux-x86_64.mk
index 2d66906..ac16350 100644
--- a/gpu/gl_in_process_context.target.linux-x86_64.mk
+++ b/gpu/gl_in_process_context.target.linux-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_c_lib.target.darwin-arm.mk b/gpu/gles2_c_lib.target.darwin-arm.mk
index 4a19caf..bcdefef 100644
--- a/gpu/gles2_c_lib.target.darwin-arm.mk
+++ b/gpu/gles2_c_lib.target.darwin-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +133,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gles2_c_lib.target.darwin-x86.mk b/gpu/gles2_c_lib.target.darwin-x86.mk
index 77f1bdf..bdedf70 100644
--- a/gpu/gles2_c_lib.target.darwin-x86.mk
+++ b/gpu/gles2_c_lib.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_c_lib.target.darwin-x86_64.mk b/gpu/gles2_c_lib.target.darwin-x86_64.mk
index 1789b98..3ad741a 100644
--- a/gpu/gles2_c_lib.target.darwin-x86_64.mk
+++ b/gpu/gles2_c_lib.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_c_lib.target.linux-arm.mk b/gpu/gles2_c_lib.target.linux-arm.mk
index 4a19caf..bcdefef 100644
--- a/gpu/gles2_c_lib.target.linux-arm.mk
+++ b/gpu/gles2_c_lib.target.linux-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +133,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gles2_c_lib.target.linux-x86.mk b/gpu/gles2_c_lib.target.linux-x86.mk
index 77f1bdf..bdedf70 100644
--- a/gpu/gles2_c_lib.target.linux-x86.mk
+++ b/gpu/gles2_c_lib.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_c_lib.target.linux-x86_64.mk b/gpu/gles2_c_lib.target.linux-x86_64.mk
index 1789b98..3ad741a 100644
--- a/gpu/gles2_c_lib.target.linux-x86_64.mk
+++ b/gpu/gles2_c_lib.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_cmd_helper.target.darwin-arm.mk b/gpu/gles2_cmd_helper.target.darwin-arm.mk
index c376a69..e7db423 100644
--- a/gpu/gles2_cmd_helper.target.darwin-arm.mk
+++ b/gpu/gles2_cmd_helper.target.darwin-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -129,7 +128,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gles2_cmd_helper.target.darwin-x86.mk b/gpu/gles2_cmd_helper.target.darwin-x86.mk
index 15d28dd..55fbd06 100644
--- a/gpu/gles2_cmd_helper.target.darwin-x86.mk
+++ b/gpu/gles2_cmd_helper.target.darwin-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_cmd_helper.target.darwin-x86_64.mk b/gpu/gles2_cmd_helper.target.darwin-x86_64.mk
index 9aa4d71..d262852 100644
--- a/gpu/gles2_cmd_helper.target.darwin-x86_64.mk
+++ b/gpu/gles2_cmd_helper.target.darwin-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_cmd_helper.target.linux-arm.mk b/gpu/gles2_cmd_helper.target.linux-arm.mk
index c376a69..e7db423 100644
--- a/gpu/gles2_cmd_helper.target.linux-arm.mk
+++ b/gpu/gles2_cmd_helper.target.linux-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -129,7 +128,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gles2_cmd_helper.target.linux-x86.mk b/gpu/gles2_cmd_helper.target.linux-x86.mk
index 15d28dd..55fbd06 100644
--- a/gpu/gles2_cmd_helper.target.linux-x86.mk
+++ b/gpu/gles2_cmd_helper.target.linux-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_cmd_helper.target.linux-x86_64.mk b/gpu/gles2_cmd_helper.target.linux-x86_64.mk
index 9aa4d71..d262852 100644
--- a/gpu/gles2_cmd_helper.target.linux-x86_64.mk
+++ b/gpu/gles2_cmd_helper.target.linux-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
index 7e88297..4e06918 100644
--- a/gpu/gles2_conform_support/egl/display.cc
+++ b/gpu/gles2_conform_support/egl/display.cc
@@ -11,7 +11,6 @@
 #include "gpu/command_buffer/client/gles2_lib.h"
 #include "gpu/command_buffer/client/transfer_buffer.h"
 #include "gpu/command_buffer/service/context_group.h"
-#include "gpu/command_buffer/service/gpu_control_service.h"
 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
 #include "gpu/gles2_conform_support/egl/config.h"
 #include "gpu/gles2_conform_support/egl/surface.h"
@@ -170,8 +169,7 @@
     return EGL_NO_SURFACE;
   }
 
-  gpu_control_.reset(new gpu::GpuControlService(
-      NULL, NULL, group->mailbox_manager(), NULL, decoder_->GetCapabilities()));
+  gpu_control_service_.reset(new gpu::GpuControlService(NULL, NULL));
 
   command_buffer->SetPutOffsetChangeCallback(
       base::Bind(&gpu::GpuScheduler::PutChanged,
@@ -237,7 +235,7 @@
                                           transfer_buffer_.get(),
                                           bind_generates_resources,
                                           lose_context_when_out_of_memory,
-                                          gpu_control_.get()));
+                                          this));
 
   if (!context_->Initialize(
       kTransferBufferSize,
@@ -271,4 +269,53 @@
   return true;
 }
 
+gpu::Capabilities Display::GetCapabilities() {
+  return decoder_->GetCapabilities();
+}
+
+gfx::GpuMemoryBuffer* Display::CreateGpuMemoryBuffer(
+    size_t width,
+    size_t height,
+    unsigned internalformat,
+    unsigned usage,
+    int32* id) {
+  NOTIMPLEMENTED();
+  return NULL;
+}
+
+void Display::DestroyGpuMemoryBuffer(int32 id) {
+  NOTIMPLEMENTED();
+}
+
+uint32 Display::InsertSyncPoint() {
+  NOTIMPLEMENTED();
+  return 0u;
+}
+
+void Display::SignalSyncPoint(uint32 sync_point,
+                             const base::Closure& callback) {
+  NOTIMPLEMENTED();
+}
+
+void Display::SignalQuery(uint32 query, const base::Closure& callback) {
+  NOTIMPLEMENTED();
+}
+
+void Display::SetSurfaceVisible(bool visible) {
+  NOTIMPLEMENTED();
+}
+
+void Display::SendManagedMemoryStats(const gpu::ManagedMemoryStats& stats) {
+  NOTIMPLEMENTED();
+}
+
+void Display::Echo(const base::Closure& callback) {
+  NOTIMPLEMENTED();
+}
+
+uint32 Display::CreateStreamTexture(uint32 texture_id) {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
 }  // namespace egl
diff --git a/gpu/gles2_conform_support/egl/display.h b/gpu/gles2_conform_support/egl/display.h
index f7c0ff3..89fb754 100644
--- a/gpu/gles2_conform_support/egl/display.h
+++ b/gpu/gles2_conform_support/egl/display.h
@@ -9,8 +9,10 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
+#include "gpu/command_buffer/client/gpu_control.h"
 #include "gpu/command_buffer/service/command_buffer_service.h"
 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/gpu_control_service.h"
 #include "gpu/command_buffer/service/gpu_scheduler.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gl/gl_context.h"
@@ -34,7 +36,7 @@
 class Config;
 class Surface;
 
-class Display {
+class Display : private gpu::GpuControl {
  public:
   explicit Display(EGLNativeDisplayType display_id);
   virtual ~Display();
@@ -72,6 +74,25 @@
   void DestroyContext(EGLContext ctx);
   bool MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx);
 
+  // GpuControl implementation.
+  virtual gpu::Capabilities GetCapabilities() OVERRIDE;
+  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(size_t width,
+                                                      size_t height,
+                                                      unsigned internalformat,
+                                                      unsigned usage,
+                                                      int32* id) OVERRIDE;
+  virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
+  virtual uint32 InsertSyncPoint() OVERRIDE;
+  virtual void SignalSyncPoint(uint32 sync_point,
+                               const base::Closure& callback) OVERRIDE;
+  virtual void SignalQuery(uint32 query,
+                           const base::Closure& callback) OVERRIDE;
+  virtual void SetSurfaceVisible(bool visible) OVERRIDE;
+  virtual void SendManagedMemoryStats(
+      const gpu::ManagedMemoryStats& stats) OVERRIDE;
+  virtual void Echo(const base::Closure& callback) OVERRIDE;
+  virtual uint32 CreateStreamTexture(uint32 texture_id) OVERRIDE;
+
  private:
   EGLNativeDisplayType display_id_;
 
@@ -84,7 +105,7 @@
   scoped_ptr<gpu::CommandBufferService> command_buffer_;
   scoped_ptr<gpu::GpuScheduler> gpu_scheduler_;
   scoped_ptr<gpu::gles2::GLES2Decoder> decoder_;
-  scoped_ptr<gpu::GpuControl> gpu_control_;
+  scoped_ptr<gpu::GpuControlService> gpu_control_service_;
   scoped_refptr<gfx::GLContext> gl_context_;
   scoped_refptr<gfx::GLSurface> gl_surface_;
   scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper_;
diff --git a/gpu/gles2_conform_support/gles2_conform_support.gyp b/gpu/gles2_conform_support/gles2_conform_support.gyp
index d34996e..92af9d9 100644
--- a/gpu/gles2_conform_support/gles2_conform_support.gyp
+++ b/gpu/gles2_conform_support/gles2_conform_support.gyp
@@ -107,8 +107,7 @@
       ],
       'conditions': [
         # See http://crbug.com/162998#c4 for why this is needed.
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and use_allocator!="none"', {
           'dependencies': [
             '../../base/allocator/allocator.gyp:allocator',
           ],
diff --git a/gpu/gles2_implementation.target.darwin-arm.mk b/gpu/gles2_implementation.target.darwin-arm.mk
index 35f6cc3..2efcb98 100644
--- a/gpu/gles2_implementation.target.darwin-arm.mk
+++ b/gpu/gles2_implementation.target.darwin-arm.mk
@@ -51,7 +51,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -146,7 +145,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gles2_implementation.target.darwin-x86.mk b/gpu/gles2_implementation.target.darwin-x86.mk
index dcec676..1447e4d 100644
--- a/gpu/gles2_implementation.target.darwin-x86.mk
+++ b/gpu/gles2_implementation.target.darwin-x86.mk
@@ -53,7 +53,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -148,7 +147,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_implementation.target.darwin-x86_64.mk b/gpu/gles2_implementation.target.darwin-x86_64.mk
index deb383c..fdb8315 100644
--- a/gpu/gles2_implementation.target.darwin-x86_64.mk
+++ b/gpu/gles2_implementation.target.darwin-x86_64.mk
@@ -53,7 +53,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -148,7 +147,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_implementation.target.linux-arm.mk b/gpu/gles2_implementation.target.linux-arm.mk
index 35f6cc3..2efcb98 100644
--- a/gpu/gles2_implementation.target.linux-arm.mk
+++ b/gpu/gles2_implementation.target.linux-arm.mk
@@ -51,7 +51,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -146,7 +145,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gles2_implementation.target.linux-x86.mk b/gpu/gles2_implementation.target.linux-x86.mk
index dcec676..1447e4d 100644
--- a/gpu/gles2_implementation.target.linux-x86.mk
+++ b/gpu/gles2_implementation.target.linux-x86.mk
@@ -53,7 +53,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -148,7 +147,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gles2_implementation.target.linux-x86_64.mk b/gpu/gles2_implementation.target.linux-x86_64.mk
index deb383c..fdb8315 100644
--- a/gpu/gles2_implementation.target.linux-x86_64.mk
+++ b/gpu/gles2_implementation.target.linux-x86_64.mk
@@ -53,7 +53,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -148,7 +147,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index 8022d48..b0ccb99 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -228,6 +228,7 @@
         'command_buffer/service/feature_info_unittest.cc',
         'command_buffer/service/framebuffer_manager_unittest.cc',
         'command_buffer/service/gles2_cmd_decoder_unittest.cc',
+        'command_buffer/service/gles2_cmd_decoder_unittest.h',
         'command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h',
         'command_buffer/service/gles2_cmd_decoder_unittest_1.cc',
         'command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h',
@@ -235,8 +236,15 @@
         'command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h',
         'command_buffer/service/gles2_cmd_decoder_unittest_3.cc',
         'command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h',
+        'command_buffer/service/gles2_cmd_decoder_unittest_async_pixel.cc',
         'command_buffer/service/gles2_cmd_decoder_unittest_base.cc',
         'command_buffer/service/gles2_cmd_decoder_unittest_base.h',
+        'command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc',
+        'command_buffer/service/gles2_cmd_decoder_unittest_drawing.cc',
+        'command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc',
+        'command_buffer/service/gles2_cmd_decoder_unittest_programs.cc',
+        'command_buffer/service/gles2_cmd_decoder_unittest_textures.cc',
+        'command_buffer/service/gles2_cmd_decoder_unittest_attribs.cc',
         'command_buffer/service/gl_surface_mock.cc',
         'command_buffer/service/gl_surface_mock.h',
         'command_buffer/service/gpu_scheduler_unittest.cc',
@@ -279,8 +287,7 @@
           ],
         }],
         # See http://crbug.com/162998#c4 for why this is needed.
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and use_allocator!="none"', {
           'dependencies': [
             '../base/allocator/allocator.gyp:allocator',
           ],
diff --git a/gpu/gpu.target.darwin-arm.mk b/gpu/gpu.target.darwin-arm.mk
index e738bd9..3cf8726 100644
--- a/gpu/gpu.target.darwin-arm.mk
+++ b/gpu/gpu.target.darwin-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +136,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gpu.target.darwin-x86.mk b/gpu/gpu.target.darwin-x86.mk
index 94ac29c..5dda7d0 100644
--- a/gpu/gpu.target.darwin-x86.mk
+++ b/gpu/gpu.target.darwin-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu.target.darwin-x86_64.mk b/gpu/gpu.target.darwin-x86_64.mk
index 8eab841..f70f32f 100644
--- a/gpu/gpu.target.darwin-x86_64.mk
+++ b/gpu/gpu.target.darwin-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu.target.linux-arm.mk b/gpu/gpu.target.linux-arm.mk
index e738bd9..3cf8726 100644
--- a/gpu/gpu.target.linux-arm.mk
+++ b/gpu/gpu.target.linux-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +136,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gpu.target.linux-x86.mk b/gpu/gpu.target.linux-x86.mk
index 94ac29c..5dda7d0 100644
--- a/gpu/gpu.target.linux-x86.mk
+++ b/gpu/gpu.target.linux-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu.target.linux-x86_64.mk b/gpu/gpu.target.linux-x86_64.mk
index 8eab841..f70f32f 100644
--- a/gpu/gpu.target.linux-x86_64.mk
+++ b/gpu/gpu.target.linux-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu_config.target.darwin-arm.mk b/gpu/gpu_config.target.darwin-arm.mk
index 07af379..b4bf96b 100644
--- a/gpu/gpu_config.target.darwin-arm.mk
+++ b/gpu/gpu_config.target.darwin-arm.mk
@@ -53,7 +53,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -148,7 +147,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gpu_config.target.darwin-x86.mk b/gpu/gpu_config.target.darwin-x86.mk
index 15517dd..cdcfe0f 100644
--- a/gpu/gpu_config.target.darwin-x86.mk
+++ b/gpu/gpu_config.target.darwin-x86.mk
@@ -55,7 +55,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +149,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu_config.target.darwin-x86_64.mk b/gpu/gpu_config.target.darwin-x86_64.mk
index 4307af0..a4acadd 100644
--- a/gpu/gpu_config.target.darwin-x86_64.mk
+++ b/gpu/gpu_config.target.darwin-x86_64.mk
@@ -55,7 +55,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +149,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu_config.target.linux-arm.mk b/gpu/gpu_config.target.linux-arm.mk
index 07af379..b4bf96b 100644
--- a/gpu/gpu_config.target.linux-arm.mk
+++ b/gpu/gpu_config.target.linux-arm.mk
@@ -53,7 +53,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -148,7 +147,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gpu_config.target.linux-x86.mk b/gpu/gpu_config.target.linux-x86.mk
index 15517dd..cdcfe0f 100644
--- a/gpu/gpu_config.target.linux-x86.mk
+++ b/gpu/gpu_config.target.linux-x86.mk
@@ -55,7 +55,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +149,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu_config.target.linux-x86_64.mk b/gpu/gpu_config.target.linux-x86_64.mk
index 4307af0..a4acadd 100644
--- a/gpu/gpu_config.target.linux-x86_64.mk
+++ b/gpu/gpu_config.target.linux-x86_64.mk
@@ -55,7 +55,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +149,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu_ipc.target.darwin-arm.mk b/gpu/gpu_ipc.target.darwin-arm.mk
index 7a01f56..2f77652 100644
--- a/gpu/gpu_ipc.target.darwin-arm.mk
+++ b/gpu/gpu_ipc.target.darwin-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gpu_ipc.target.darwin-x86.mk b/gpu/gpu_ipc.target.darwin-x86.mk
index c8c8023..973c696 100644
--- a/gpu/gpu_ipc.target.darwin-x86.mk
+++ b/gpu/gpu_ipc.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu_ipc.target.darwin-x86_64.mk b/gpu/gpu_ipc.target.darwin-x86_64.mk
index d6221b4..c3c8db0 100644
--- a/gpu/gpu_ipc.target.darwin-x86_64.mk
+++ b/gpu/gpu_ipc.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu_ipc.target.linux-arm.mk b/gpu/gpu_ipc.target.linux-arm.mk
index 7a01f56..2f77652 100644
--- a/gpu/gpu_ipc.target.linux-arm.mk
+++ b/gpu/gpu_ipc.target.linux-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/gpu/gpu_ipc.target.linux-x86.mk b/gpu/gpu_ipc.target.linux-x86.mk
index c8c8023..973c696 100644
--- a/gpu/gpu_ipc.target.linux-x86.mk
+++ b/gpu/gpu_ipc.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/gpu_ipc.target.linux-x86_64.mk b/gpu/gpu_ipc.target.linux-x86_64.mk
index d6221b4..c3c8db0 100644
--- a/gpu/gpu_ipc.target.linux-x86_64.mk
+++ b/gpu/gpu_ipc.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/gpu/skia_bindings/gpu_skia_bindings.target.darwin-arm.mk b/gpu/skia_bindings/gpu_skia_bindings.target.darwin-arm.mk
index 5019f50..19737e8 100644
--- a/gpu/skia_bindings/gpu_skia_bindings.target.darwin-arm.mk
+++ b/gpu/skia_bindings/gpu_skia_bindings.target.darwin-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -91,11 +90,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -165,7 +159,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -213,11 +206,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/skia_bindings/gpu_skia_bindings.target.darwin-arm64.mk b/gpu/skia_bindings/gpu_skia_bindings.target.darwin-arm64.mk
index 08eadcc..58f160e 100644
--- a/gpu/skia_bindings/gpu_skia_bindings.target.darwin-arm64.mk
+++ b/gpu/skia_bindings/gpu_skia_bindings.target.darwin-arm64.mk
@@ -87,11 +87,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -204,11 +199,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/skia_bindings/gpu_skia_bindings.target.darwin-mips.mk b/gpu/skia_bindings/gpu_skia_bindings.target.darwin-mips.mk
index b3951b1..f71604a 100644
--- a/gpu/skia_bindings/gpu_skia_bindings.target.darwin-mips.mk
+++ b/gpu/skia_bindings/gpu_skia_bindings.target.darwin-mips.mk
@@ -90,11 +90,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -211,11 +206,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/skia_bindings/gpu_skia_bindings.target.darwin-x86.mk b/gpu/skia_bindings/gpu_skia_bindings.target.darwin-x86.mk
index 8def36a..d815cd8 100644
--- a/gpu/skia_bindings/gpu_skia_bindings.target.darwin-x86.mk
+++ b/gpu/skia_bindings/gpu_skia_bindings.target.darwin-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -92,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -167,7 +161,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -214,11 +207,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/skia_bindings/gpu_skia_bindings.target.darwin-x86_64.mk b/gpu/skia_bindings/gpu_skia_bindings.target.darwin-x86_64.mk
index 6bd85aa..2c63628 100644
--- a/gpu/skia_bindings/gpu_skia_bindings.target.darwin-x86_64.mk
+++ b/gpu/skia_bindings/gpu_skia_bindings.target.darwin-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -92,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -167,7 +161,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -214,11 +207,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/skia_bindings/gpu_skia_bindings.target.linux-arm.mk b/gpu/skia_bindings/gpu_skia_bindings.target.linux-arm.mk
index 5019f50..19737e8 100644
--- a/gpu/skia_bindings/gpu_skia_bindings.target.linux-arm.mk
+++ b/gpu/skia_bindings/gpu_skia_bindings.target.linux-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -91,11 +90,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -165,7 +159,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -213,11 +206,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/skia_bindings/gpu_skia_bindings.target.linux-arm64.mk b/gpu/skia_bindings/gpu_skia_bindings.target.linux-arm64.mk
index 08eadcc..58f160e 100644
--- a/gpu/skia_bindings/gpu_skia_bindings.target.linux-arm64.mk
+++ b/gpu/skia_bindings/gpu_skia_bindings.target.linux-arm64.mk
@@ -87,11 +87,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -204,11 +199,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/skia_bindings/gpu_skia_bindings.target.linux-mips.mk b/gpu/skia_bindings/gpu_skia_bindings.target.linux-mips.mk
index b3951b1..f71604a 100644
--- a/gpu/skia_bindings/gpu_skia_bindings.target.linux-mips.mk
+++ b/gpu/skia_bindings/gpu_skia_bindings.target.linux-mips.mk
@@ -90,11 +90,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -211,11 +206,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/skia_bindings/gpu_skia_bindings.target.linux-x86.mk b/gpu/skia_bindings/gpu_skia_bindings.target.linux-x86.mk
index 8def36a..d815cd8 100644
--- a/gpu/skia_bindings/gpu_skia_bindings.target.linux-x86.mk
+++ b/gpu/skia_bindings/gpu_skia_bindings.target.linux-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -92,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -167,7 +161,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -214,11 +207,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/gpu/skia_bindings/gpu_skia_bindings.target.linux-x86_64.mk b/gpu/skia_bindings/gpu_skia_bindings.target.linux-x86_64.mk
index 6bd85aa..2c63628 100644
--- a/gpu/skia_bindings/gpu_skia_bindings.target.linux-x86_64.mk
+++ b/gpu/skia_bindings/gpu_skia_bindings.target.linux-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -92,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -167,7 +161,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -214,11 +207,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ipc/BUILD.gn b/ipc/BUILD.gn
index cccbb58..9d9e49a 100644
--- a/ipc/BUILD.gn
+++ b/ipc/BUILD.gn
@@ -114,8 +114,7 @@
 
     # TODO(brettw) hook up tcmalloc to this target.
     #if (is_posix && !is_mac && !is_android) {
-    #  # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-    #  if ((use_allocator!="none" && use_allocator!="see_use_tcmalloc") || (use_allocator=="see_use_tcmalloc" && linux_use_tcmalloc)) {
+    #  if (use_allocator!="none") {
     #    deps += "/base/allocator"
     #  }
     #}
@@ -145,8 +144,7 @@
 
     # TODO(brettw) hook up tcmalloc to this target.
     #if (is_posix && !is_mac && !is_android) {
-    #  # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-    #  if ((use_allocator!="none" && use_allocator!="see_use_tcmalloc") || (use_allocator=="see_use_tcmalloc" && linux_use_tcmalloc)) {
+    #  if (use_allocator!="none") {
     #    deps += "//base/allocator"
     #  }
     #}
diff --git a/ipc/ipc.gyp b/ipc/ipc.gyp
index dac7cfa..c5a8c0b 100644
--- a/ipc/ipc.gyp
+++ b/ipc/ipc.gyp
@@ -74,8 +74,7 @@
         }],
         ['os_posix == 1 and OS != "mac" and OS != "android"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
@@ -113,8 +112,7 @@
         }],
         ['os_posix == 1 and OS != "mac" and OS != "android"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
diff --git a/ipc/ipc.target.darwin-arm.mk b/ipc/ipc.target.darwin-arm.mk
index 24a7dce..097ddf8 100644
--- a/ipc/ipc.target.darwin-arm.mk
+++ b/ipc/ipc.target.darwin-arm.mk
@@ -58,7 +58,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -145,7 +144,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ipc/ipc.target.darwin-x86.mk b/ipc/ipc.target.darwin-x86.mk
index 9ec6f12..a146f6c 100644
--- a/ipc/ipc.target.darwin-x86.mk
+++ b/ipc/ipc.target.darwin-x86.mk
@@ -60,7 +60,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ipc/ipc.target.darwin-x86_64.mk b/ipc/ipc.target.darwin-x86_64.mk
index 35b3628..89ee327 100644
--- a/ipc/ipc.target.darwin-x86_64.mk
+++ b/ipc/ipc.target.darwin-x86_64.mk
@@ -60,7 +60,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ipc/ipc.target.linux-arm.mk b/ipc/ipc.target.linux-arm.mk
index 24a7dce..097ddf8 100644
--- a/ipc/ipc.target.linux-arm.mk
+++ b/ipc/ipc.target.linux-arm.mk
@@ -58,7 +58,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -145,7 +144,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ipc/ipc.target.linux-x86.mk b/ipc/ipc.target.linux-x86.mk
index 9ec6f12..a146f6c 100644
--- a/ipc/ipc.target.linux-x86.mk
+++ b/ipc/ipc.target.linux-x86.mk
@@ -60,7 +60,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ipc/ipc.target.linux-x86_64.mk b/ipc/ipc.target.linux-x86_64.mk
index 35b3628..89ee327 100644
--- a/ipc/ipc.target.linux-x86_64.mk
+++ b/ipc/ipc.target.linux-x86_64.mk
@@ -60,7 +60,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc
index 7c96c83..5c4d743 100644
--- a/ipc/ipc_channel_proxy.cc
+++ b/ipc/ipc_channel_proxy.cc
@@ -243,10 +243,10 @@
   Logging* logger = Logging::GetInstance();
   std::string name;
   logger->GetMessageText(message.type(), &name, &message, NULL);
-  TRACE_EVENT1("toplevel", "ChannelProxy::Context::OnDispatchMessage",
+  TRACE_EVENT1("ipc", "ChannelProxy::Context::OnDispatchMessage",
                "name", name);
 #else
-  TRACE_EVENT2("toplevel", "ChannelProxy::Context::OnDispatchMessage",
+  TRACE_EVENT2("ipc", "ChannelProxy::Context::OnDispatchMessage",
                "class", IPC_MESSAGE_ID_CLASS(message.type()),
                "line", IPC_MESSAGE_ID_LINE(message.type()));
 #endif
diff --git a/ipc/ipc_channel_reader.cc b/ipc/ipc_channel_reader.cc
index 8b638a9..401e4e1 100644
--- a/ipc/ipc_channel_reader.cc
+++ b/ipc/ipc_channel_reader.cc
@@ -83,10 +83,10 @@
       Logging* logger = Logging::GetInstance();
       std::string name;
       logger->GetMessageText(m.type(), &name, &m, NULL);
-      TRACE_EVENT1("toplevel", "ChannelReader::DispatchInputData",
+      TRACE_EVENT1("ipc,toplevel", "ChannelReader::DispatchInputData",
                    "name", name);
 #else
-      TRACE_EVENT2("toplevel", "ChannelReader::DispatchInputData",
+      TRACE_EVENT2("ipc,toplevel", "ChannelReader::DispatchInputData",
                    "class", IPC_MESSAGE_ID_CLASS(m.type()),
                    "line", IPC_MESSAGE_ID_LINE(m.type()));
 #endif
diff --git a/ipc/ipc_message.h b/ipc/ipc_message.h
index 17cbd24..1b13d67 100644
--- a/ipc/ipc_message.h
+++ b/ipc/ipc_message.h
@@ -217,12 +217,12 @@
 
   // Called to trace when message is sent.
   void TraceMessageBegin() {
-    TRACE_EVENT_FLOW_BEGIN0(TRACE_DISABLED_BY_DEFAULT("toplevel.flow"), "IPC",
+    TRACE_EVENT_FLOW_BEGIN0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), "IPC",
         header()->flags);
   }
   // Called to trace when message is received.
   void TraceMessageEnd() {
-    TRACE_EVENT_FLOW_END0(TRACE_DISABLED_BY_DEFAULT("toplevel.flow"), "IPC",
+    TRACE_EVENT_FLOW_END0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), "IPC",
         header()->flags);
   }
 
diff --git a/ipc/ipc_message_start.h b/ipc/ipc_message_start.h
index 6474eab..0d8193c 100644
--- a/ipc/ipc_message_start.h
+++ b/ipc/ipc_message_start.h
@@ -102,6 +102,7 @@
   MojoMsgStart,
   TranslateMsgStart,
   PushMessagingMsgStart,
+  GinJavaBridgeMsgStart,
   LastIPCMsgStart  // Must come last.
 };
 
diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc
index 9e04f61..0e0018c 100644
--- a/ipc/ipc_sync_channel.cc
+++ b/ipc/ipc_sync_channel.cc
@@ -442,9 +442,9 @@
   Logging* logger = Logging::GetInstance();
   std::string name;
   logger->GetMessageText(message->type(), &name, message, NULL);
-  TRACE_EVENT1("toplevel", "SyncChannel::Send", "name", name);
+  TRACE_EVENT1("ipc", "SyncChannel::Send", "name", name);
 #else
-  TRACE_EVENT2("toplevel", "SyncChannel::Send",
+  TRACE_EVENT2("ipc", "SyncChannel::Send",
                "class", IPC_MESSAGE_ID_CLASS(message->type()),
                "line", IPC_MESSAGE_ID_LINE(message->type()));
 #endif
diff --git a/jingle/jingle_glue.target.darwin-arm.mk b/jingle/jingle_glue.target.darwin-arm.mk
index 08b981a..47df842 100644
--- a/jingle/jingle_glue.target.darwin-arm.mk
+++ b/jingle/jingle_glue.target.darwin-arm.mk
@@ -49,7 +49,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -151,7 +150,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/jingle/jingle_glue.target.darwin-x86.mk b/jingle/jingle_glue.target.darwin-x86.mk
index d4de780..efd21e8 100644
--- a/jingle/jingle_glue.target.darwin-x86.mk
+++ b/jingle/jingle_glue.target.darwin-x86.mk
@@ -51,7 +51,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -152,7 +151,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/jingle/jingle_glue.target.darwin-x86_64.mk b/jingle/jingle_glue.target.darwin-x86_64.mk
index fd7c913..83e5990 100644
--- a/jingle/jingle_glue.target.darwin-x86_64.mk
+++ b/jingle/jingle_glue.target.darwin-x86_64.mk
@@ -51,7 +51,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -153,7 +152,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/jingle/jingle_glue.target.linux-arm.mk b/jingle/jingle_glue.target.linux-arm.mk
index 08b981a..47df842 100644
--- a/jingle/jingle_glue.target.linux-arm.mk
+++ b/jingle/jingle_glue.target.linux-arm.mk
@@ -49,7 +49,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -151,7 +150,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/jingle/jingle_glue.target.linux-x86.mk b/jingle/jingle_glue.target.linux-x86.mk
index d4de780..efd21e8 100644
--- a/jingle/jingle_glue.target.linux-x86.mk
+++ b/jingle/jingle_glue.target.linux-x86.mk
@@ -51,7 +51,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -152,7 +151,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/jingle/jingle_glue.target.linux-x86_64.mk b/jingle/jingle_glue.target.linux-x86_64.mk
index fd7c913..83e5990 100644
--- a/jingle/jingle_glue.target.linux-x86_64.mk
+++ b/jingle/jingle_glue.target.linux-x86_64.mk
@@ -51,7 +51,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -153,7 +152,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/jingle/notifier/listener/notification_defines_unittest.cc b/jingle/notifier/listener/notification_defines_unittest.cc
index 389f3cc..d783239 100644
--- a/jingle/notifier/listener/notification_defines_unittest.cc
+++ b/jingle/notifier/listener/notification_defines_unittest.cc
@@ -17,7 +17,7 @@
 // Converting it to string shouldn't cause a crash.
 TEST_F(NotificationTest, BinaryData) {
   const char kNonUtf8Data[] = { '\xff', '\0' };
-  EXPECT_FALSE(IsStringUTF8(kNonUtf8Data));
+  EXPECT_FALSE(base::IsStringUTF8(kNonUtf8Data));
   Notification notification;
   notification.data = kNonUtf8Data;
   EXPECT_EQ("{ channel: \"\", data: \"\\u00FF\" }", notification.ToString());
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc
index 1e2180d..4cf948b 100644
--- a/media/audio/audio_input_controller.cc
+++ b/media/audio/audio_input_controller.cc
@@ -189,14 +189,16 @@
   stream_ = stream_to_control;
 
   if (!stream_) {
-    handler_->OnError(this, STREAM_CREATE_ERROR);
+    if (handler_)
+      handler_->OnError(this, STREAM_CREATE_ERROR);
     return;
   }
 
   if (stream_ && !stream_->Open()) {
     stream_->Close();
     stream_ = NULL;
-    handler_->OnError(this, STREAM_OPEN_ERROR);
+    if (handler_)
+      handler_->OnError(this, STREAM_OPEN_ERROR);
     return;
   }
 
@@ -222,7 +224,8 @@
   }
 
   state_ = CREATED;
-  handler_->OnCreated(this);
+  if (handler_)
+    handler_->OnCreated(this);
 
   if (user_input_monitor_) {
     user_input_monitor_->EnableKeyPressMonitoring();
@@ -249,7 +252,8 @@
   }
 
   stream_->Start(this);
-  handler_->OnRecording(this);
+  if (handler_)
+    handler_->OnRecording(this);
 }
 
 void AudioInputController::DoClose() {
@@ -262,10 +266,10 @@
   // Delete the timer on the same thread that created it.
   no_data_timer_.reset();
 
-  DoStopCloseAndClearStream(NULL);
+  DoStopCloseAndClearStream();
   SetDataIsActive(false);
 
-  if (LowLatencyMode())
+  if (SharedMemoryAndSyncSocketMode())
     sync_writer_->Close();
 
   if (user_input_monitor_)
@@ -276,7 +280,8 @@
 
 void AudioInputController::DoReportError() {
   DCHECK(task_runner_->BelongsToCurrentThread());
-  handler_->OnError(this, STREAM_ERROR);
+  if (handler_)
+    handler_->OnError(this, STREAM_ERROR);
 }
 
 void AudioInputController::DoSetVolume(double volume) {
@@ -320,7 +325,8 @@
     // The data-is-active marker will be false only if it has been more than
     // one second since a data packet was recorded. This can happen if a
     // capture device has been removed or disabled.
-    handler_->OnError(this, NO_DATA_ERROR);
+    if (handler_)
+      handler_->OnError(this, NO_DATA_ERROR);
   }
 
   // Mark data as non-active. The flag will be re-enabled in OnData() each
@@ -359,14 +365,30 @@
   // DoCheckForNoData() does not report an error to the event handler.
   SetDataIsActive(true);
 
-  // Use SyncSocket if we are in a low-latency mode.
-  if (LowLatencyMode()) {
+  // Use SharedMemory and SyncSocket if the client has created a SyncWriter.
+  // Used by all low-latency clients except WebSpeech.
+  if (SharedMemoryAndSyncSocketMode()) {
     sync_writer_->Write(data, size, volume, key_pressed);
     sync_writer_->UpdateRecordedBytes(hardware_delay_bytes);
     return;
   }
 
-  handler_->OnData(this, data, size);
+  // TODO(henrika): Investigate if we can avoid the extra copy here.
+  // (see http://crbug.com/249316 for details). AFAIK, this scope is only
+  // active for WebSpeech clients.
+  scoped_ptr<uint8[]> audio_data(new uint8[size]);
+  memcpy(audio_data.get(), data, size);
+
+  // Ownership of the audio buffer will be with the callback until it is run,
+  // when ownership is passed to the callback function.
+  task_runner_->PostTask(FROM_HERE, base::Bind(
+      &AudioInputController::DoOnData, this, base::Passed(&audio_data), size));
+}
+
+void AudioInputController::DoOnData(scoped_ptr<uint8[]> data, uint32 size) {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  if (handler_)
+    handler_->OnData(this, data.get(), size);
 }
 
 void AudioInputController::OnError(AudioInputStream* stream) {
@@ -375,8 +397,7 @@
       &AudioInputController::DoReportError, this));
 }
 
-void AudioInputController::DoStopCloseAndClearStream(
-    base::WaitableEvent* done) {
+void AudioInputController::DoStopCloseAndClearStream() {
   DCHECK(task_runner_->BelongsToCurrentThread());
 
   // Allow calling unconditionally and bail if we don't have a stream to close.
@@ -386,9 +407,8 @@
     stream_ = NULL;
   }
 
-  // Should be last in the method, do not touch "this" from here on.
-  if (done != NULL)
-    done->Signal();
+  // The event handler should not be touched after the stream has been closed.
+  handler_ = NULL;
 }
 
 void AudioInputController::SetDataIsActive(bool enabled) {
diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h
index 566e2a6..ac1a690 100644
--- a/media/audio/audio_input_controller.h
+++ b/media/audio/audio_input_controller.h
@@ -224,7 +224,7 @@
                       uint32 hardware_delay_bytes, double volume) OVERRIDE;
   virtual void OnError(AudioInputStream* stream) OVERRIDE;
 
-  bool LowLatencyMode() const { return sync_writer_ != NULL; }
+  bool SharedMemoryAndSyncSocketMode() const { return sync_writer_ != NULL; }
 
  protected:
   friend class base::RefCountedThreadSafe<AudioInputController>;
@@ -251,14 +251,14 @@
   void DoReportError();
   void DoSetVolume(double volume);
   void DoSetAutomaticGainControl(bool enabled);
+  void DoOnData(scoped_ptr<uint8[]> data, uint32 size);
 
   // Method which ensures that OnError() is triggered when data recording
   // times out. Called on the audio thread.
   void DoCheckForNoData();
 
   // Helper method that stops, closes, and NULL:s |*stream_|.
-  // Signals event when done if the event is not NULL.
-  void DoStopCloseAndClearStream(base::WaitableEvent* done);
+  void DoStopCloseAndClearStream();
 
   void SetDataIsActive(bool enabled);
   bool GetDataIsActive();
diff --git a/media/audio/cras/cras_input.h b/media/audio/cras/cras_input.h
index 2b7176b..36bf9b1 100644
--- a/media/audio/cras/cras_input.h
+++ b/media/audio/cras/cras_input.h
@@ -51,7 +51,7 @@
                           const timespec* sample_ts,
                           void* arg);
 
-  // Handles notificaiton that there was an error with the playback stream.
+  // Handles notification that there was an error with the playback stream.
   static int StreamError(cras_client* client,
                          cras_stream_id_t stream_id,
                          int err,
diff --git a/media/audio/cras/cras_unified.h b/media/audio/cras/cras_unified.h
index 36a58e5..2b29050 100644
--- a/media/audio/cras/cras_unified.h
+++ b/media/audio/cras/cras_unified.h
@@ -54,7 +54,7 @@
                              const timespec* output_ts,
                              void* arg);
 
-  // Handles notificaiton that there was an error with the playback stream.
+  // Handles notification that there was an error with the playback stream.
   static int StreamError(cras_client* client,
                          cras_stream_id_t stream_id,
                          int err,
diff --git a/media/audio/win/wavein_input_win.cc b/media/audio/win/wavein_input_win.cc
index 0577125..43a356f 100644
--- a/media/audio/win/wavein_input_win.cc
+++ b/media/audio/win/wavein_input_win.cc
@@ -224,7 +224,8 @@
 
 void PCMWaveInAudioInputStream::HandleError(MMRESULT error) {
   DLOG(WARNING) << "PCMWaveInAudio error " << error;
-  callback_->OnError(this);
+  if (callback_)
+    callback_->OnError(this);
 }
 
 void PCMWaveInAudioInputStream::QueueNextPacket(WAVEHDR *buffer) {
diff --git a/media/base/android/java/src/org/chromium/media/MediaDrmBridge.java b/media/base/android/java/src/org/chromium/media/MediaDrmBridge.java
index 31e5055..aceb362 100644
--- a/media/base/android/java/src/org/chromium/media/MediaDrmBridge.java
+++ b/media/base/android/java/src/org/chromium/media/MediaDrmBridge.java
@@ -277,7 +277,7 @@
      * @param nativeMediaDrmBridge Native object of this class.
      */
     @CalledByNative
-    private static MediaDrmBridge create(byte[] schemeUUID, int nativeMediaDrmBridge) {
+    private static MediaDrmBridge create(byte[] schemeUUID, long nativeMediaDrmBridge) {
         UUID cryptoScheme = getUUIDFromBytes(schemeUUID);
         if (cryptoScheme == null || !MediaDrm.isCryptoSchemeSupported(cryptoScheme)) {
             return null;
diff --git a/media/base/android/java/src/org/chromium/media/MediaPlayerListener.java b/media/base/android/java/src/org/chromium/media/MediaPlayerListener.java
index 555086a..ed37f19 100644
--- a/media/base/android/java/src/org/chromium/media/MediaPlayerListener.java
+++ b/media/base/android/java/src/org/chromium/media/MediaPlayerListener.java
@@ -121,7 +121,7 @@
     }
 
     @CalledByNative
-    private static MediaPlayerListener create(int nativeMediaPlayerListener,
+    private static MediaPlayerListener create(long nativeMediaPlayerListener,
             Context context, MediaPlayerBridge mediaPlayerBridge) {
         final MediaPlayerListener listener =
                 new MediaPlayerListener(nativeMediaPlayerListener, context);
diff --git a/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
index a6cb24b..6a38747 100644
--- a/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
+++ b/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
@@ -53,6 +53,11 @@
     private boolean mIsClosed;
 
     /**
+     * True if there is a thread processing input data.
+     */
+    private boolean mHasInputThread;
+
+    /**
      * The identifier of this device.
      */
     private long mNativePointer;
@@ -73,6 +78,7 @@
         mRequestMap = new HashMap<UsbEndpoint, UsbRequest>();
         mHandler = new Handler();
         mIsClosed = false;
+        mHasInputThread = false;
         mNativePointer = 0;
 
         for (int i = 0; i < device.getInterfaceCount(); ++i) {
@@ -124,6 +130,7 @@
         if (bufferForEndpoints.isEmpty()) {
             return;
         }
+        mHasInputThread = true;
         // bufferForEndpoints must not be accessed hereafter on this thread.
         new Thread() {
             public void run() {
@@ -188,13 +195,35 @@
         if (endpoint == null) {
             return;
         }
-        UsbRequest request = mRequestMap.get(endpoint);
-        if (request == null) {
-            request = new UsbRequest();
-            request.initialize(mConnection, endpoint);
-            mRequestMap.put(endpoint, request);
+        if (shouldUseBulkTransfer()) {
+            // We use bulkTransfer instead of UsbRequest.queue because queueing
+            // a UsbRequest is currently not thread safe.
+            // Note that this is not exactly correct because we don't care
+            // about the transfer attribute (bmAttribute) of the endpoint.
+            // See also:
+            //  http://stackoverflow.com/questions/9644415/
+            //  https://code.google.com/p/android/issues/detail?id=59467
+            //
+            // TODO(yhirano): Delete this block once the problem is fixed.
+            final int TIMEOUT = 100;
+            mConnection.bulkTransfer(endpoint, bs, 0, bs.length, TIMEOUT);
+        } else {
+            UsbRequest request = mRequestMap.get(endpoint);
+            if (request == null) {
+                request = new UsbRequest();
+                request.initialize(mConnection, endpoint);
+                mRequestMap.put(endpoint, request);
+            }
+            request.queue(ByteBuffer.wrap(bs), bs.length);
         }
-        request.queue(ByteBuffer.wrap(bs), bs.length);
+    }
+
+    /**
+     * Returns true if |bulkTransfer| should be used in |send|.
+     * See comments in |send|.
+     */
+    private boolean shouldUseBulkTransfer() {
+        return mHasInputThread;
     }
 
     /**
diff --git a/media/base/android/java/src/org/chromium/media/VideoCaptureFactory.java b/media/base/android/java/src/org/chromium/media/VideoCaptureFactory.java
index 6083861..25c7cba 100644
--- a/media/base/android/java/src/org/chromium/media/VideoCaptureFactory.java
+++ b/media/base/android/java/src/org/chromium/media/VideoCaptureFactory.java
@@ -5,6 +5,7 @@
 package org.chromium.media;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.hardware.Camera;
 import android.util.Log;
 
@@ -27,7 +28,7 @@
 @JNINamespace("media")
 class VideoCaptureFactory {
 
-    protected static class CamParams {
+    static class CamParams {
         final int mId;
         final String mName;
         final int mWidth;
@@ -41,7 +42,7 @@
         }
     }
 
-    protected static class ChromiumCameraInfo {
+    static class ChromiumCameraInfo {
         private final int mId;
         private final Camera.CameraInfo mCameraInfo;
         // Special devices have more cameras than usual. Those devices are
@@ -52,6 +53,8 @@
         };
         private static final String TAG = "ChromiumCameraInfo";
 
+        private static int sNumberOfSystemCameras = -1;
+
         private static boolean isSpecialDevice() {
             for (String[] device : s_SPECIAL_DEVICE_LIST) {
                 if (device[0].contentEquals(android.os.Build.MODEL) &&
@@ -62,19 +65,44 @@
             return false;
         }
 
+        private static boolean isSpecialCamera(int id) {
+            return id >= sNumberOfSystemCameras;
+        }
+
+        private static int toSpecialCameraId(int id) {
+            assert isSpecialCamera(id);
+            return id - sNumberOfSystemCameras;
+        }
+
         private ChromiumCameraInfo(int index) {
             mId = index;
             mCameraInfo = isSpecialCamera(index) ? null : getCameraInfo(mId);
         }
 
         @CalledByNative("ChromiumCameraInfo")
-        private static int getNumberOfCameras() {
+        private static int getNumberOfCameras(Context appContext) {
+            // Camera.getNumberOfCammeras() will not fail without permission, but the
+            // following operation on camera will do. Without permission isn't fatal
+            // error in WebView, specially for those application which has no purpose
+            // to use camera, but happens to load page required it.
+            // So, we output a warning log and pretend system have no camera at all.
+            if (sNumberOfSystemCameras == -1) {
+                if (PackageManager.PERMISSION_GRANTED ==
+                        appContext.getPackageManager().checkPermission(
+                                "android.permission.CAMERA", appContext.getPackageName())) {
+                    sNumberOfSystemCameras = Camera.getNumberOfCameras();
+                } else {
+                    sNumberOfSystemCameras = 0;
+                    Log.w(TAG, "Missing android.permission.CAMERA permission, "
+                            + "no system camera available.");
+                }
+            }
             if (isSpecialDevice()) {
                 Log.d(TAG, "Special device: " + android.os.Build.MODEL);
-                return Camera.getNumberOfCameras() +
+                return sNumberOfSystemCameras +
                        VideoCaptureTango.numberOfCameras();
             } else {
-                return Camera.getNumberOfCameras();
+                return sNumberOfSystemCameras;
             }
         }
 
@@ -91,8 +119,7 @@
         @CalledByNative("ChromiumCameraInfo")
         private String getDeviceName() {
             if (isSpecialCamera(mId)) {
-                return VideoCaptureTango.getCamParams(
-                        mId - Camera.getNumberOfCameras()).mName;
+                return VideoCaptureTango.getCamParams(toSpecialCameraId(mId)).mName;
             } else {
                 if (mCameraInfo == null) {
                     return "";
@@ -127,17 +154,12 @@
         }
     }
 
-    protected static boolean isSpecialCamera(int id) {
-        return id >= Camera.getNumberOfCameras();
-    }
-
     // Factory methods.
     @CalledByNative
     static VideoCapture createVideoCapture(
             Context context, int id, long nativeVideoCaptureDeviceAndroid) {
-      if (isSpecialCamera(id)) {
-          return new VideoCaptureTango(context,
-                  id - Camera.getNumberOfCameras(),
+      if (ChromiumCameraInfo.isSpecialCamera(id)) {
+          return new VideoCaptureTango(context, ChromiumCameraInfo.toSpecialCameraId(id),
                   nativeVideoCaptureDeviceAndroid);
       } else {
           return new VideoCaptureAndroid(context, id,
@@ -147,9 +169,9 @@
 
     @CalledByNative
     static VideoCapture.CaptureFormat[] getDeviceSupportedFormats(int id) {
-        return isSpecialCamera(id) ?
+        return ChromiumCameraInfo.isSpecialCamera(id) ?
                 VideoCaptureTango.getDeviceSupportedFormats(
-                        id - Camera.getNumberOfCameras()) :
+                        ChromiumCameraInfo.toSpecialCameraId(id)) :
                 VideoCaptureAndroid.getDeviceSupportedFormats(id);
     }
 
diff --git a/media/base/audio_buffer.cc b/media/base/audio_buffer.cc
index 4b972b9..33d4ecb 100644
--- a/media/base/audio_buffer.cc
+++ b/media/base/audio_buffer.cc
@@ -11,6 +11,12 @@
 
 namespace media {
 
+static base::TimeDelta CalculateDuration(int frames, double sample_rate) {
+  DCHECK_GT(sample_rate, 0);
+  return base::TimeDelta::FromMicroseconds(
+      frames * base::Time::kMicrosecondsPerSecond / sample_rate);
+}
+
 AudioBuffer::AudioBuffer(SampleFormat sample_format,
                          ChannelLayout channel_layout,
                          int channel_count,
@@ -18,8 +24,7 @@
                          int frame_count,
                          bool create_buffer,
                          const uint8* const* data,
-                         const base::TimeDelta timestamp,
-                         const base::TimeDelta duration)
+                         const base::TimeDelta timestamp)
     : sample_format_(sample_format),
       channel_layout_(channel_layout),
       channel_count_(channel_count),
@@ -28,7 +33,9 @@
       trim_start_(0),
       end_of_stream_(!create_buffer && data == NULL && frame_count == 0),
       timestamp_(timestamp),
-      duration_(duration) {
+      duration_(end_of_stream_
+                    ? base::TimeDelta()
+                    : CalculateDuration(adjusted_frame_count_, sample_rate_)) {
   CHECK_GE(channel_count_, 0);
   CHECK_LE(channel_count_, limits::kMaxChannels);
   CHECK_GE(frame_count, 0);
@@ -91,8 +98,7 @@
     int sample_rate,
     int frame_count,
     const uint8* const* data,
-    const base::TimeDelta timestamp,
-    const base::TimeDelta duration) {
+    const base::TimeDelta timestamp) {
   // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer.
   CHECK(data[0]);
@@ -103,8 +109,7 @@
                                             frame_count,
                                             true,
                                             data,
-                                            timestamp,
-                                            duration));
+                                            timestamp));
 }
 
 // static
@@ -122,7 +127,6 @@
                                             frame_count,
                                             true,
                                             NULL,
-                                            kNoTimestamp(),
                                             kNoTimestamp()));
 }
 
@@ -132,8 +136,7 @@
     int channel_count,
     int sample_rate,
     int frame_count,
-    const base::TimeDelta timestamp,
-    const base::TimeDelta duration) {
+    const base::TimeDelta timestamp) {
   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer.
   // Since data == NULL, format doesn't matter.
   return make_scoped_refptr(new AudioBuffer(kSampleFormatF32,
@@ -143,8 +146,7 @@
                                             frame_count,
                                             false,
                                             NULL,
-                                            timestamp,
-                                            duration));
+                                            timestamp));
 }
 
 // static
@@ -156,7 +158,6 @@
                                             0,
                                             false,
                                             NULL,
-                                            kNoTimestamp(),
                                             kNoTimestamp()));
 }
 
@@ -246,33 +247,66 @@
   CHECK_GE(frames_to_trim, 0);
   CHECK_LE(frames_to_trim, adjusted_frame_count_);
 
-  // Adjust timestamp_ and duration_ to reflect the smaller number of frames.
-  double offset = static_cast<double>(duration_.InMicroseconds()) *
-                  frames_to_trim / adjusted_frame_count_;
-  base::TimeDelta offset_as_time =
-      base::TimeDelta::FromMicroseconds(static_cast<int64>(offset));
-  timestamp_ += offset_as_time;
-  duration_ -= offset_as_time;
-
-  // Finally adjust the number of frames in this buffer and where the start
-  // really is.
+  // Adjust the number of frames in this buffer and where the start really is.
   adjusted_frame_count_ -= frames_to_trim;
   trim_start_ += frames_to_trim;
+
+  // Adjust timestamp_ and duration_ to reflect the smaller number of frames.
+  const base::TimeDelta old_duration = duration_;
+  duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
+  timestamp_ += old_duration - duration_;
 }
 
 void AudioBuffer::TrimEnd(int frames_to_trim) {
   CHECK_GE(frames_to_trim, 0);
   CHECK_LE(frames_to_trim, adjusted_frame_count_);
 
-  // Adjust duration_ only to reflect the smaller number of frames.
-  double offset = static_cast<double>(duration_.InMicroseconds()) *
-                  frames_to_trim / adjusted_frame_count_;
-  base::TimeDelta offset_as_time =
-      base::TimeDelta::FromMicroseconds(static_cast<int64>(offset));
-  duration_ -= offset_as_time;
-
-  // Finally adjust the number of frames in this buffer.
+  // Adjust the number of frames and duration for this buffer.
   adjusted_frame_count_ -= frames_to_trim;
+  duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
+}
+
+void AudioBuffer::TrimRange(int start, int end) {
+  CHECK_GE(start, 0);
+  CHECK_LE(end, adjusted_frame_count_);
+
+  const int frames_to_trim = end - start;
+  CHECK_GE(frames_to_trim, 0);
+  CHECK_LE(frames_to_trim, adjusted_frame_count_);
+
+  const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
+  const int frames_to_copy = adjusted_frame_count_ - end;
+  if (frames_to_copy > 0) {
+    switch (sample_format_) {
+      case kSampleFormatPlanarS16:
+      case kSampleFormatPlanarF32:
+        // Planar data must be shifted per channel.
+        for (int ch = 0; ch < channel_count_; ++ch) {
+          memmove(channel_data_[ch] + (trim_start_ + start) * bytes_per_channel,
+                  channel_data_[ch] + (trim_start_ + end) * bytes_per_channel,
+                  bytes_per_channel * frames_to_copy);
+        }
+        break;
+      case kSampleFormatU8:
+      case kSampleFormatS16:
+      case kSampleFormatS32:
+      case kSampleFormatF32: {
+        // Interleaved data can be shifted all at once.
+        const int frame_size = channel_count_ * bytes_per_channel;
+        memmove(channel_data_[0] + (trim_start_ + start) * frame_size,
+                channel_data_[0] + (trim_start_ + end) * frame_size,
+                frame_size * frames_to_copy);
+        break;
+      }
+      case kUnknownSampleFormat:
+        NOTREACHED() << "Invalid sample format!";
+    }
+  } else {
+    CHECK_EQ(frames_to_copy, 0);
+  }
+
+  // Trim the leftover data off the end of the buffer and update duration.
+  TrimEnd(frames_to_trim);
 }
 
 }  // namespace media
diff --git a/media/base/audio_buffer.h b/media/base/audio_buffer.h
index 5d7ab7f..a07985c 100644
--- a/media/base/audio_buffer.h
+++ b/media/base/audio_buffer.h
@@ -34,16 +34,13 @@
   // number of buffers must be equal to |channel_count|. |frame_count| is the
   // number of frames in each buffer. |data| must not be null and |frame_count|
   // must be >= 0.
-  //
-  // TODO(jrummell): Compute duration rather than pass it in.
   static scoped_refptr<AudioBuffer> CopyFrom(SampleFormat sample_format,
                                              ChannelLayout channel_layout,
                                              int channel_count,
                                              int sample_rate,
                                              int frame_count,
                                              const uint8* const* data,
-                                             const base::TimeDelta timestamp,
-                                             const base::TimeDelta duration);
+                                             const base::TimeDelta timestamp);
 
   // Create an AudioBuffer with |frame_count| frames. Buffer is allocated, but
   // not initialized. Timestamp and duration are set to kNoTimestamp().
@@ -59,8 +56,7 @@
       int channel_count,
       int sample_rate,
       int frame_count,
-      const base::TimeDelta timestamp,
-      const base::TimeDelta duration);
+      const base::TimeDelta timestamp);
 
   // Create a AudioBuffer indicating we've reached end of stream.
   // Calling any method other than end_of_stream() on the resulting buffer
@@ -87,6 +83,10 @@
   // Duration is adjusted to reflect the fewer frames.
   void TrimEnd(int frames_to_trim);
 
+  // Trim an AudioBuffer by removing |end - start| frames from [|start|, |end|).
+  // Even if |start| is zero, timestamp() is not adjusted, only duration().
+  void TrimRange(int start, int end);
+
   // Return the number of channels.
   int channel_count() const { return channel_count_; }
 
@@ -102,7 +102,6 @@
   base::TimeDelta timestamp() const { return timestamp_; }
   base::TimeDelta duration() const { return duration_; }
   void set_timestamp(base::TimeDelta timestamp) { timestamp_ = timestamp; }
-  void set_duration(base::TimeDelta duration) { duration_ = duration; }
 
   // If there's no data in this buffer, it represents end of stream.
   bool end_of_stream() const { return end_of_stream_; }
@@ -126,8 +125,7 @@
               int frame_count,
               bool create_buffer,
               const uint8* const* data,
-              const base::TimeDelta timestamp,
-              const base::TimeDelta duration);
+              const base::TimeDelta timestamp);
 
   virtual ~AudioBuffer();
 
diff --git a/media/base/audio_buffer_converter.cc b/media/base/audio_buffer_converter.cc
index 74e570d..59c6681 100644
--- a/media/base/audio_buffer_converter.cc
+++ b/media/base/audio_buffer_converter.cc
@@ -227,8 +227,6 @@
 
   // Compute the timestamp.
   output_buffer->set_timestamp(timestamp_helper_.GetTimestamp());
-  output_buffer->set_duration(
-      timestamp_helper_.GetFrameDuration(request_frames));
   timestamp_helper_.AddFrames(request_frames);
 
   queued_outputs_.push_back(output_buffer);
diff --git a/media/base/audio_buffer_converter_unittest.cc b/media/base/audio_buffer_converter_unittest.cc
index c5c816c..3445996 100644
--- a/media/base/audio_buffer_converter_unittest.cc
+++ b/media/base/audio_buffer_converter_unittest.cc
@@ -29,7 +29,6 @@
                                 0,
                                 1,
                                 frames,
-                                base::TimeDelta::FromSeconds(0),
                                 base::TimeDelta::FromSeconds(0));
 }
 
diff --git a/media/base/audio_buffer_queue_unittest.cc b/media/base/audio_buffer_queue_unittest.cc
index fc04857..dfb2098 100644
--- a/media/base/audio_buffer_queue_unittest.cc
+++ b/media/base/audio_buffer_queue_unittest.cc
@@ -5,7 +5,6 @@
 #include "base/basictypes.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/strings/stringprintf.h"
 #include "base/time/time.h"
 #include "media/base/audio_buffer.h"
 #include "media/base/audio_buffer_queue.h"
@@ -18,15 +17,18 @@
 
 const int kSampleRate = 44100;
 
-static void VerifyResult(float* channel_data,
-                         int frames,
-                         float start,
-                         float increment) {
-  for (int i = 0; i < frames; ++i) {
-    SCOPED_TRACE(base::StringPrintf(
-        "i=%d/%d start=%f, increment=%f", i, frames, start, increment));
-    ASSERT_EQ(start, channel_data[i]);
-    start += increment;
+static void VerifyBus(AudioBus* bus,
+                      int offset,
+                      int frames,
+                      int buffer_size,
+                      float start,
+                      float increment) {
+  for (int ch = 0; ch < bus->channels(); ++ch) {
+    const float v = start + ch * buffer_size * increment;
+    for (int i = offset; i < offset + frames; ++i) {
+      ASSERT_FLOAT_EQ(v + (i - offset) * increment, bus->channel(ch)[i])
+          << "i=" << i << ", ch=" << ch;
+    }
   }
 }
 
@@ -34,18 +36,16 @@
 static scoped_refptr<AudioBuffer> MakeTestBuffer(SampleFormat format,
                                                  ChannelLayout channel_layout,
                                                  T start,
-                                                 T end,
+                                                 T step,
                                                  int frames) {
-  const base::TimeDelta kNoTime = kNoTimestamp();
   return MakeAudioBuffer<T>(format,
                             channel_layout,
                             ChannelLayoutToChannelCount(channel_layout),
                             kSampleRate,
                             start,
-                            end,
+                            step,
                             frames,
-                            kNoTime,
-                            kNoTime);
+                            kNoTimestamp());
 }
 
 TEST(AudioBufferQueueTest, AppendAndClear) {
@@ -96,7 +96,7 @@
 
   EXPECT_EQ(4, buffer.ReadFrames(4, 0, bus.get()));
   EXPECT_EQ(4, buffer.frames());
-  VerifyResult(bus->channel(0), 4, 10.0f, 1.0f);
+  VerifyBus(bus.get(), 0, 4, bus->frames(), 10, 1);
 
   buffer.Append(MakeTestBuffer<float>(
       kSampleFormatF32, channel_layout, 20.0f, 1.0f, 8));
@@ -108,7 +108,7 @@
   buffer.SeekFrames(16);
   EXPECT_EQ(4, buffer.ReadFrames(4, 0, bus.get()));
   EXPECT_EQ(0, buffer.frames());
-  VerifyResult(bus->channel(0), 4, 34.0f, 1.0f);
+  VerifyBus(bus.get(), 0, 4, bus->frames(), 34, 1);
 
   buffer.Append(MakeTestBuffer<float>(
       kSampleFormatF32, channel_layout, 40.0f, 1.0f, 8));
@@ -118,13 +118,13 @@
   EXPECT_EQ(16, buffer.frames());
 
   EXPECT_EQ(4, buffer.ReadFrames(4, 0, bus.get()));
-  VerifyResult(bus->channel(0), 4, 40.0f, 1.0f);
+  VerifyBus(bus.get(), 0, 4, bus->frames(), 40, 1);
 
   // Read off the end of the buffer.
   EXPECT_EQ(12, buffer.frames());
   buffer.SeekFrames(8);
   EXPECT_EQ(4, buffer.ReadFrames(100, 0, bus.get()));
-  VerifyResult(bus->channel(0), 4, 54.0f, 1.0f);
+  VerifyBus(bus.get(), 0, 4, bus->frames(), 54, 1);
 }
 
 TEST(AudioBufferQueueTest, Seek) {
@@ -162,19 +162,17 @@
       MakeTestBuffer<float>(kSampleFormatF32, channel_layout, 33.0f, 1.0f, 60));
   EXPECT_EQ(76, buffer.frames());
 
-  // Read 3 frames from the buffer. F32 is interleaved, so ch[0] should be
-  // 1, 3, 5, and ch[1] should be 2, 4, 6.
+  // Read 3 frames from the buffer.
   scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
   EXPECT_EQ(3, buffer.ReadFrames(3, 0, bus.get()));
   EXPECT_EQ(73, buffer.frames());
-  VerifyResult(bus->channel(0), 3, 1.0f, 2.0f);
-  VerifyResult(bus->channel(1), 3, 2.0f, 2.0f);
+  VerifyBus(bus.get(), 0, 3, 6, 1, 1);
 
   // Now read 5 frames, which will span buffers. Append the data into AudioBus.
   EXPECT_EQ(5, buffer.ReadFrames(5, 3, bus.get()));
   EXPECT_EQ(68, buffer.frames());
-  VerifyResult(bus->channel(0), 8, 1.0f, 2.0f);
-  VerifyResult(bus->channel(1), 8, 2.0f, 2.0f);
+  VerifyBus(bus.get(), 0, 6, 6, 1, 1);
+  VerifyBus(bus.get(), 6, 2, 10, 13, 1);
 
   // Now skip into the third buffer.
   buffer.SeekFrames(20);
@@ -182,30 +180,24 @@
 
   // Now read 2 frames, which are in the third buffer.
   EXPECT_EQ(2, buffer.ReadFrames(2, 0, bus.get()));
-  VerifyResult(bus->channel(0), 2, 57.0f, 2.0f);
-  VerifyResult(bus->channel(1), 2, 58.0f, 2.0f);
+  VerifyBus(bus.get(), 0, 2, 60, 45, 1);
 }
 
 TEST(AudioBufferQueueTest, ReadU8) {
   const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
   const int channels = ChannelLayoutToChannelCount(channel_layout);
+  const int frames = 4;
   AudioBufferQueue buffer;
 
   // Add 4 frames of data.
   buffer.Append(
-      MakeTestBuffer<uint8>(kSampleFormatU8, channel_layout, 128, 1, 4));
+      MakeTestBuffer<uint8>(kSampleFormatU8, channel_layout, 128, 1, frames));
 
-  // Read all 4 frames from the buffer. Data is interleaved, so ch[0] should be
-  // 128, 132, 136, 140, other channels similar. However, values are converted
-  // from [0, 255] to [-1.0, 1.0] with a bias of 128. Thus the first buffer
-  // value should be 0.0, then 1/127, 2/127, etc.
-  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
-  EXPECT_EQ(4, buffer.ReadFrames(4, 0, bus.get()));
+  // Read all 4 frames from the buffer.
+  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
+  EXPECT_EQ(frames, buffer.ReadFrames(frames, 0, bus.get()));
   EXPECT_EQ(0, buffer.frames());
-  VerifyResult(bus->channel(0), 4, 0.0f, 4.0f / 127.0f);
-  VerifyResult(bus->channel(1), 4, 1.0f / 127.0f, 4.0f / 127.0f);
-  VerifyResult(bus->channel(2), 4, 2.0f / 127.0f, 4.0f / 127.0f);
-  VerifyResult(bus->channel(3), 4, 3.0f / 127.0f, 4.0f / 127.0f);
+  VerifyBus(bus.get(), 0, frames, bus->frames(), 0, 1.0f / 127.0f);
 }
 
 TEST(AudioBufferQueueTest, ReadS16) {
@@ -220,14 +212,13 @@
       MakeTestBuffer<int16>(kSampleFormatS16, channel_layout, 9, 1, 20));
   EXPECT_EQ(24, buffer.frames());
 
-  // Read 6 frames from the buffer. Data is interleaved, so ch[0] should be
-  // 1, 3, 5, 7, 9, 11, and ch[1] should be 2, 4, 6, 8, 10, 12.
-  // Data is converted to float from -1.0 to 1.0 based on int16 range.
-  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
-  EXPECT_EQ(6, buffer.ReadFrames(6, 0, bus.get()));
+  // Read 6 frames from the buffer.
+  const int frames = 6;
+  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, buffer.frames());
+  EXPECT_EQ(frames, buffer.ReadFrames(frames, 0, bus.get()));
   EXPECT_EQ(18, buffer.frames());
-  VerifyResult(bus->channel(0), 6, 1.0f / kint16max, 2.0f / kint16max);
-  VerifyResult(bus->channel(1), 6, 2.0f / kint16max, 2.0f / kint16max);
+  VerifyBus(bus.get(), 0, 4, 4, 1.0f / kint16max, 1.0f / kint16max);
+  VerifyBus(bus.get(), 4, 2, 20, 9.0f / kint16max, 1.0f / kint16max);
 }
 
 TEST(AudioBufferQueueTest, ReadS32) {
@@ -242,20 +233,17 @@
       MakeTestBuffer<int32>(kSampleFormatS32, channel_layout, 9, 1, 20));
   EXPECT_EQ(24, buffer.frames());
 
-  // Read 6 frames from the buffer. Data is interleaved, so ch[0] should be
-  // 1, 3, 5, 7, 100, 106, and ch[1] should be 2, 4, 6, 8, 103, 109.
-  // Data is converted to float from -1.0 to 1.0 based on int32 range.
+  // Read 6 frames from the buffer.
   scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
   EXPECT_EQ(6, buffer.ReadFrames(6, 0, bus.get()));
   EXPECT_EQ(18, buffer.frames());
-  VerifyResult(bus->channel(0), 6, 1.0f / kint32max, 2.0f / kint32max);
-  VerifyResult(bus->channel(1), 6, 2.0f / kint32max, 2.0f / kint32max);
+  VerifyBus(bus.get(), 0, 4, 4, 1.0f / kint32max, 1.0f / kint32max);
+  VerifyBus(bus.get(), 4, 2, 20, 9.0f / kint32max, 1.0f / kint32max);
 
   // Read the next 2 frames.
   EXPECT_EQ(2, buffer.ReadFrames(2, 0, bus.get()));
   EXPECT_EQ(16, buffer.frames());
-  VerifyResult(bus->channel(0), 2, 13.0f / kint32max, 2.0f / kint32max);
-  VerifyResult(bus->channel(1), 2, 14.0f / kint32max, 2.0f / kint32max);
+  VerifyBus(bus.get(), 0, 2, 20, 11.0f / kint32max, 1.0f / kint32max);
 }
 
 TEST(AudioBufferQueueTest, ReadF32Planar) {
@@ -270,15 +258,12 @@
       kSampleFormatPlanarF32, channel_layout, 50.0f, 1.0f, 10));
   EXPECT_EQ(14, buffer.frames());
 
-  // Read 6 frames from the buffer. F32 is planar, so ch[0] should be
-  // 1, 2, 3, 4, 50, 51, and ch[1] should be 5, 6, 7, 8, 60, 61.
+  // Read 6 frames from the buffer.
   scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
   EXPECT_EQ(6, buffer.ReadFrames(6, 0, bus.get()));
   EXPECT_EQ(8, buffer.frames());
-  VerifyResult(bus->channel(0), 4, 1.0f, 1.0f);
-  VerifyResult(bus->channel(0) + 4, 2, 50.0f, 1.0f);
-  VerifyResult(bus->channel(1), 4, 5.0f, 1.0f);
-  VerifyResult(bus->channel(1) + 4, 2, 60.0f, 1.0f);
+  VerifyBus(bus.get(), 0, 4, 4, 1, 1);
+  VerifyBus(bus.get(), 4, 2, 10, 50, 1);
 }
 
 TEST(AudioBufferQueueTest, ReadS16Planar) {
@@ -289,20 +274,16 @@
   // Add 24 frames of data.
   buffer.Append(
       MakeTestBuffer<int16>(kSampleFormatPlanarS16, channel_layout, 1, 1, 4));
-  buffer.Append(MakeTestBuffer<int16>(
-      kSampleFormatPlanarS16, channel_layout, 100, 5, 20));
+  buffer.Append(
+      MakeTestBuffer<int16>(kSampleFormatPlanarS16, channel_layout, 5, 1, 20));
   EXPECT_EQ(24, buffer.frames());
 
-  // Read 6 frames from the buffer. Data is planar, so ch[0] should be
-  // 1, 2, 3, 4, 100, 105, and ch[1] should be 5, 6, 7, 8, 200, 205.
-  // Data is converted to float from -1.0 to 1.0 based on int16 range.
+  // Read 6 frames from the buffer.
   scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
   EXPECT_EQ(6, buffer.ReadFrames(6, 0, bus.get()));
   EXPECT_EQ(18, buffer.frames());
-  VerifyResult(bus->channel(0), 4, 1.0f / kint16max, 1.0f / kint16max);
-  VerifyResult(bus->channel(0) + 4, 2, 100.0f / kint16max, 5.0f / kint16max);
-  VerifyResult(bus->channel(1), 4, 5.0f / kint16max, 1.0f / kint16max);
-  VerifyResult(bus->channel(1) + 4, 2, 200.0f / kint16max, 5.0f / kint16max);
+  VerifyBus(bus.get(), 0, 4, 4, 1.0f / kint16max, 1.0f / kint16max);
+  VerifyBus(bus.get(), 4, 2, 20, 5.0f / kint16max, 1.0f / kint16max);
 }
 
 TEST(AudioBufferQueueTest, ReadManyChannels) {
@@ -319,14 +300,13 @@
       kSampleFormatF32, channel_layout, 16.0f * channels, 1.0f, 60));
   EXPECT_EQ(76, buffer.frames());
 
-  // Read 3 frames from the buffer. F32 is interleaved, so ch[0] should be
-  // 1, 17, 33, and ch[1] should be 2, 18, 34. Just check a few channels.
+  // Read 3 frames from the buffer.
   scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
   EXPECT_EQ(30, buffer.ReadFrames(30, 0, bus.get()));
   EXPECT_EQ(46, buffer.frames());
-  for (int i = 0; i < channels; ++i) {
-    VerifyResult(bus->channel(i), 30, static_cast<float>(i), 8.0f);
-  }
+  VerifyBus(bus.get(), 0, 6, 6, 0, 1);
+  VerifyBus(bus.get(), 6, 10, 10, 6 * channels, 1);
+  VerifyBus(bus.get(), 16, 14, 60, 16 * channels, 1);
 }
 
 TEST(AudioBufferQueueTest, Peek) {
@@ -335,43 +315,32 @@
   AudioBufferQueue buffer;
 
   // Add 60 frames of data.
-  buffer.Append(
-      MakeTestBuffer<float>(kSampleFormatF32, channel_layout, 0.0f, 1.0f, 60));
-  EXPECT_EQ(60, buffer.frames());
+  const int frames = 60;
+  buffer.Append(MakeTestBuffer<float>(
+      kSampleFormatF32, channel_layout, 0.0f, 1.0f, frames));
+  EXPECT_EQ(frames, buffer.frames());
 
   // Peek at the first 30 frames.
-  scoped_ptr<AudioBus> bus1 = AudioBus::Create(channels, 100);
-  EXPECT_EQ(60, buffer.frames());
-  EXPECT_EQ(60, buffer.PeekFrames(100, 0, 0, bus1.get()));
+  scoped_ptr<AudioBus> bus1 = AudioBus::Create(channels, frames);
+  EXPECT_EQ(frames, buffer.frames());
+  EXPECT_EQ(frames, buffer.PeekFrames(60, 0, 0, bus1.get()));
   EXPECT_EQ(30, buffer.PeekFrames(30, 0, 0, bus1.get()));
-  EXPECT_EQ(60, buffer.frames());
+  EXPECT_EQ(frames, buffer.frames());
+  VerifyBus(bus1.get(), 0, 30, bus1->frames(), 0, 1);
 
   // Now read the next 30 frames (which should be the same as those peeked at).
-  scoped_ptr<AudioBus> bus2 = AudioBus::Create(channels, 100);
+  scoped_ptr<AudioBus> bus2 = AudioBus::Create(channels, frames);
   EXPECT_EQ(30, buffer.ReadFrames(30, 0, bus2.get()));
-  for (int i = 0; i < channels; ++i) {
-    VerifyResult(bus1->channel(i),
-                 30,
-                 static_cast<float>(i),
-                 static_cast<float>(channels));
-    VerifyResult(bus2->channel(i),
-                 30,
-                 static_cast<float>(i),
-                 static_cast<float>(channels));
-  }
+  VerifyBus(bus2.get(), 0, 30, bus2->frames(), 0, 1);
 
   // Peek 10 frames forward
+  bus1->Zero();
   EXPECT_EQ(5, buffer.PeekFrames(5, 10, 0, bus1.get()));
-  for (int i = 0; i < channels; ++i) {
-    VerifyResult(bus1->channel(i),
-                 5,
-                 static_cast<float>(i + 40 * channels),
-                 static_cast<float>(channels));
-  }
+  VerifyBus(bus1.get(), 0, 5, bus1->frames(), 40, 1);
 
   // Peek to the end of the buffer.
   EXPECT_EQ(30, buffer.frames());
-  EXPECT_EQ(30, buffer.PeekFrames(100, 0, 0, bus1.get()));
+  EXPECT_EQ(30, buffer.PeekFrames(60, 0, 0, bus1.get()));
   EXPECT_EQ(30, buffer.PeekFrames(30, 0, 0, bus1.get()));
 }
 
@@ -380,36 +349,43 @@
   const int channels = ChannelLayoutToChannelCount(channel_layout);
   const base::TimeDelta start_time1;
   const base::TimeDelta start_time2 = base::TimeDelta::FromSeconds(30);
-  const base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
   AudioBufferQueue buffer;
   scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
 
+  scoped_refptr<AudioBuffer> audio_buffer =
+      MakeAudioBuffer<int16>(kSampleFormatS16,
+                             channel_layout,
+                             channels,
+                             kSampleRate,
+                             1,
+                             1,
+                             10,
+                             start_time1);
+
   // Add two buffers (second one added later):
   //   first:  start=0s,  duration=10s
   //   second: start=30s, duration=10s
-  buffer.Append(MakeAudioBuffer<int16>(kSampleFormatS16,
-                                       channel_layout,
-                                       channels,
-                                       kSampleRate,
-                                       1,
-                                       1,
-                                       10,
-                                       start_time1,
-                                       duration));
+  buffer.Append(audio_buffer);
   EXPECT_EQ(10, buffer.frames());
 
   // Check starting time.
   EXPECT_EQ(start_time1, buffer.current_time());
 
   // Read 2 frames, should be 2s in (since duration is 1s per sample).
-  EXPECT_EQ(2, buffer.ReadFrames(2, 0, bus.get()));
-  EXPECT_EQ(start_time1 + base::TimeDelta::FromSeconds(2),
-            buffer.current_time());
+  int frames_read = 2;
+  EXPECT_EQ(frames_read, buffer.ReadFrames(frames_read, 0, bus.get()));
+  EXPECT_EQ(
+      start_time1 +
+          frames_read * audio_buffer->duration() / audio_buffer->frame_count(),
+      buffer.current_time());
 
   // Skip 2 frames.
   buffer.SeekFrames(2);
-  EXPECT_EQ(start_time1 + base::TimeDelta::FromSeconds(4),
-            buffer.current_time());
+  frames_read += 2;
+  EXPECT_EQ(
+      start_time1 +
+          frames_read * audio_buffer->duration() / audio_buffer->frame_count(),
+      buffer.current_time());
 
   // Add second buffer for more data.
   buffer.Append(MakeAudioBuffer<int16>(kSampleFormatS16,
@@ -419,28 +395,32 @@
                                        1,
                                        1,
                                        10,
-                                       start_time2,
-                                       duration));
+                                       start_time2));
   EXPECT_EQ(16, buffer.frames());
 
   // Read until almost the end of buffer1.
+  frames_read += 5;
   EXPECT_EQ(5, buffer.ReadFrames(5, 0, bus.get()));
-  EXPECT_EQ(start_time1 + base::TimeDelta::FromSeconds(9),
-            buffer.current_time());
+  EXPECT_EQ(
+      start_time1 +
+          frames_read * audio_buffer->duration() / audio_buffer->frame_count(),
+      buffer.current_time());
 
   // Read 1 value, so time moved to buffer2.
   EXPECT_EQ(1, buffer.ReadFrames(1, 0, bus.get()));
   EXPECT_EQ(start_time2, buffer.current_time());
 
   // Read all 10 frames in buffer2, timestamp should be last time from buffer2.
+  frames_read = 10;
   EXPECT_EQ(10, buffer.ReadFrames(10, 0, bus.get()));
-  EXPECT_EQ(start_time2 + base::TimeDelta::FromSeconds(10),
-            buffer.current_time());
+  const base::TimeDelta expected_current_time =
+      start_time2 +
+      frames_read * audio_buffer->duration() / audio_buffer->frame_count();
+  EXPECT_EQ(expected_current_time, buffer.current_time());
 
   // Try to read more frames (which don't exist), timestamp should remain.
   EXPECT_EQ(0, buffer.ReadFrames(5, 0, bus.get()));
-  EXPECT_EQ(start_time2 + base::TimeDelta::FromSeconds(10),
-            buffer.current_time());
+  EXPECT_EQ(expected_current_time, buffer.current_time());
 }
 
 TEST(AudioBufferQueueTest, NoTime) {
diff --git a/media/base/audio_buffer_unittest.cc b/media/base/audio_buffer_unittest.cc
index c40c076..039dc0a 100644
--- a/media/base/audio_buffer_unittest.cc
+++ b/media/base/audio_buffer_unittest.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
 #include "media/base/audio_buffer.h"
 #include "media/base/audio_bus.h"
 #include "media/base/test_helpers.h"
@@ -11,39 +9,175 @@
 
 namespace media {
 
-const static int kSampleRate = 44100;
+static const int kSampleRate = 48000;
 
-static void VerifyResult(float* channel_data,
-                         int frames,
-                         float start,
-                         float increment) {
-  for (int i = 0; i < frames; ++i) {
-    SCOPED_TRACE(base::StringPrintf(
-        "i=%d/%d start=%f, increment=%f", i, frames, start, increment));
-    ASSERT_EQ(channel_data[i], start);
-    start += increment;
+static void VerifyBusWithOffset(AudioBus* bus,
+                                int offset,
+                                int frames,
+                                float start,
+                                float start_offset,
+                                float increment) {
+  for (int ch = 0; ch < bus->channels(); ++ch) {
+    const float v = start_offset + start + ch * bus->frames() * increment;
+    for (int i = offset; i < offset + frames; ++i) {
+      ASSERT_FLOAT_EQ(v + i * increment, bus->channel(ch)[i]) << "i=" << i
+                                                              << ", ch=" << ch;
+    }
   }
 }
 
+static void VerifyBus(AudioBus* bus, int frames, float start, float increment) {
+  VerifyBusWithOffset(bus, 0, frames, start, 0, increment);
+}
+
+static void TrimRangeTest(SampleFormat sample_format) {
+  const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
+  const int channels = ChannelLayoutToChannelCount(channel_layout);
+  const int frames = kSampleRate / 10;
+  const base::TimeDelta timestamp = base::TimeDelta();
+  const base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
+  scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<float>(sample_format,
+                                                             channel_layout,
+                                                             channels,
+                                                             kSampleRate,
+                                                             0,
+                                                             1,
+                                                             frames,
+                                                             timestamp);
+  EXPECT_EQ(frames, buffer->frame_count());
+  EXPECT_EQ(timestamp, buffer->timestamp());
+  EXPECT_EQ(duration, buffer->duration());
+
+  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
+
+  // Verify all frames before trimming.
+  buffer->ReadFrames(frames, 0, 0, bus.get());
+  VerifyBus(bus.get(), frames, 0, 1);
+
+  // Trim 10ms of frames from the middle of the buffer.
+  int trim_start = frames / 2;
+  const int trim_length = kSampleRate / 100;
+  const base::TimeDelta trim_duration = base::TimeDelta::FromMilliseconds(10);
+  buffer->TrimRange(trim_start, trim_start + trim_length);
+  EXPECT_EQ(frames - trim_length, buffer->frame_count());
+  EXPECT_EQ(timestamp, buffer->timestamp());
+  EXPECT_EQ(duration - trim_duration, buffer->duration());
+  bus->Zero();
+  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
+  VerifyBus(bus.get(), trim_start, 0, 1);
+  VerifyBusWithOffset(bus.get(),
+                      trim_start,
+                      buffer->frame_count() - trim_start,
+                      0,
+                      trim_length,
+                      1);
+
+  // Trim 10ms of frames from the start, which just adjusts the buffer's
+  // internal start offset.
+  buffer->TrimStart(trim_length);
+  trim_start -= trim_length;
+  EXPECT_EQ(frames - 2 * trim_length, buffer->frame_count());
+  EXPECT_EQ(timestamp + trim_duration, buffer->timestamp());
+  EXPECT_EQ(duration - 2 * trim_duration, buffer->duration());
+  bus->Zero();
+  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
+  VerifyBus(bus.get(), trim_start, trim_length, 1);
+  VerifyBusWithOffset(bus.get(),
+                      trim_start,
+                      buffer->frame_count() - trim_start,
+                      trim_length,
+                      trim_length,
+                      1);
+
+  // Trim 10ms of frames from the end, which just adjusts the buffer's frame
+  // count.
+  buffer->TrimEnd(trim_length);
+  EXPECT_EQ(frames - 3 * trim_length, buffer->frame_count());
+  EXPECT_EQ(timestamp + trim_duration, buffer->timestamp());
+  EXPECT_EQ(duration - 3 * trim_duration, buffer->duration());
+  bus->Zero();
+  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
+  VerifyBus(bus.get(), trim_start, trim_length, 1);
+  VerifyBusWithOffset(bus.get(),
+                      trim_start,
+                      buffer->frame_count() - trim_start,
+                      trim_length,
+                      trim_length,
+                      1);
+
+  // Trim another 10ms from the inner portion of the buffer.
+  buffer->TrimRange(trim_start, trim_start + trim_length);
+  EXPECT_EQ(frames - 4 * trim_length, buffer->frame_count());
+  EXPECT_EQ(timestamp + trim_duration, buffer->timestamp());
+  EXPECT_EQ(duration - 4 * trim_duration, buffer->duration());
+  bus->Zero();
+  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
+  VerifyBus(bus.get(), trim_start, trim_length, 1);
+  VerifyBusWithOffset(bus.get(),
+                      trim_start,
+                      buffer->frame_count() - trim_start,
+                      trim_length,
+                      trim_length * 2,
+                      1);
+
+  // Trim off the end using TrimRange() to ensure end index is exclusive.
+  buffer->TrimRange(buffer->frame_count() - trim_length, buffer->frame_count());
+  EXPECT_EQ(frames - 5 * trim_length, buffer->frame_count());
+  EXPECT_EQ(timestamp + trim_duration, buffer->timestamp());
+  EXPECT_EQ(duration - 5 * trim_duration, buffer->duration());
+  bus->Zero();
+  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
+  VerifyBus(bus.get(), trim_start, trim_length, 1);
+  VerifyBusWithOffset(bus.get(),
+                      trim_start,
+                      buffer->frame_count() - trim_start,
+                      trim_length,
+                      trim_length * 2,
+                      1);
+
+  // Trim off the start using TrimRange() to ensure start index is inclusive.
+  buffer->TrimRange(0, trim_length);
+  trim_start -= trim_length;
+  EXPECT_EQ(frames - 6 * trim_length, buffer->frame_count());
+  EXPECT_EQ(timestamp + trim_duration, buffer->timestamp());
+  EXPECT_EQ(duration - 6 * trim_duration, buffer->duration());
+  bus->Zero();
+  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
+  VerifyBus(bus.get(), trim_start, 2 * trim_length, 1);
+  VerifyBusWithOffset(bus.get(),
+                      trim_start,
+                      buffer->frame_count() - trim_start,
+                      trim_length * 2,
+                      trim_length * 2,
+                      1);
+}
+
 TEST(AudioBufferTest, CopyFrom) {
-  const ChannelLayout channel_layout = CHANNEL_LAYOUT_MONO;
-  const int frames = 8;
-  const base::TimeDelta start_time;
-  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
-  scoped_refptr<AudioBuffer> buffer =
+  const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_MONO;
+  scoped_refptr<AudioBuffer> original_buffer =
       MakeAudioBuffer<uint8>(kSampleFormatU8,
-                             channel_layout,
-                             ChannelLayoutToChannelCount(channel_layout),
+                             kChannelLayout,
+                             ChannelLayoutToChannelCount(kChannelLayout),
                              kSampleRate,
                              1,
                              1,
-                             frames,
-                             start_time,
-                             duration);
-  EXPECT_EQ(frames, buffer->frame_count());
-  EXPECT_EQ(buffer->timestamp(), start_time);
-  EXPECT_EQ(buffer->duration().InSeconds(), frames);
-  EXPECT_FALSE(buffer->end_of_stream());
+                             kSampleRate / 100,
+                             base::TimeDelta());
+  scoped_refptr<AudioBuffer> new_buffer =
+      AudioBuffer::CopyFrom(kSampleFormatU8,
+                            original_buffer->channel_layout(),
+                            original_buffer->channel_count(),
+                            original_buffer->sample_rate(),
+                            original_buffer->frame_count(),
+                            &original_buffer->channel_data()[0],
+                            original_buffer->timestamp());
+  EXPECT_EQ(original_buffer->frame_count(), new_buffer->frame_count());
+  EXPECT_EQ(original_buffer->timestamp(), new_buffer->timestamp());
+  EXPECT_EQ(original_buffer->duration(), new_buffer->duration());
+  EXPECT_EQ(original_buffer->sample_rate(), new_buffer->sample_rate());
+  EXPECT_EQ(original_buffer->channel_count(), new_buffer->channel_count());
+  EXPECT_EQ(original_buffer->channel_layout(), new_buffer->channel_layout());
+  EXPECT_FALSE(original_buffer->end_of_stream());
 }
 
 TEST(AudioBufferTest, CreateEOSBuffer) {
@@ -55,8 +189,7 @@
   const uint8 kTestData[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
                               15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
                               27, 28, 29, 30, 31 };
-  const base::TimeDelta kTimestampA = base::TimeDelta::FromMicroseconds(1337);
-  const base::TimeDelta kTimestampB = base::TimeDelta::FromMicroseconds(1234);
+  const base::TimeDelta kTimestamp = base::TimeDelta::FromMicroseconds(1337);
 
   const uint8* const data[] = { kTestData };
   scoped_refptr<AudioBuffer> buffer =
@@ -66,8 +199,7 @@
                             kSampleRate,
                             16,
                             data,
-                            kTimestampA,
-                            kTimestampB);
+                            kTimestamp);
   EXPECT_EQ(16, buffer->frame_count());  // 2 channels of 8-bit data
 
   buffer = AudioBuffer::CopyFrom(kSampleFormatF32,
@@ -76,17 +208,15 @@
                                  kSampleRate,
                                  2,
                                  data,
-                                 kTimestampA,
-                                 kTimestampB);
+                                 kTimestamp);
   EXPECT_EQ(2, buffer->frame_count());  // now 4 channels of 32-bit data
 }
 
 TEST(AudioBufferTest, ReadU8) {
   const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
   const int channels = ChannelLayoutToChannelCount(channel_layout);
-  const int frames = 4;
+  const int frames = 10;
   const base::TimeDelta start_time;
-  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
   scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<uint8>(kSampleFormatU8,
                                                              channel_layout,
                                                              channels,
@@ -94,19 +224,16 @@
                                                              128,
                                                              1,
                                                              frames,
-                                                             start_time,
-                                                             duration);
-
-  // Read all 4 frames from the buffer. Data is interleaved, so ch[0] should be
-  // 128, 132, 136, 140, other channels similar. However, values are converted
-  // from [0, 255] to [-1.0, 1.0] with a bias of 128. Thus the first buffer
-  // value should be 0.0, then 1/127, 2/127, etc.
-  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
+                                                             start_time);
+  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
   buffer->ReadFrames(frames, 0, 0, bus.get());
-  VerifyResult(bus->channel(0), frames, 0.0f, 4.0f / 127.0f);
-  VerifyResult(bus->channel(1), frames, 1.0f / 127.0f, 4.0f / 127.0f);
-  VerifyResult(bus->channel(2), frames, 2.0f / 127.0f, 4.0f / 127.0f);
-  VerifyResult(bus->channel(3), frames, 3.0f / 127.0f, 4.0f / 127.0f);
+  VerifyBus(bus.get(), frames, 0, 1.0f / 127.0f);
+
+  // Now read the same data one frame at a time.
+  bus->Zero();
+  for (int i = 0; i < frames; ++i)
+    buffer->ReadFrames(1, i, i, bus.get());
+  VerifyBus(bus.get(), frames, 0, 1.0f / 127.0f);
 }
 
 TEST(AudioBufferTest, ReadS16) {
@@ -114,7 +241,6 @@
   const int channels = ChannelLayoutToChannelCount(channel_layout);
   const int frames = 10;
   const base::TimeDelta start_time;
-  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
   scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<int16>(kSampleFormatS16,
                                                              channel_layout,
                                                              channels,
@@ -122,32 +248,23 @@
                                                              1,
                                                              1,
                                                              frames,
-                                                             start_time,
-                                                             duration);
-
-  // Read 6 frames from the buffer. Data is interleaved, so ch[0] should be 1,
-  // 3, 5, 7, 9, 11, and ch[1] should be 2, 4, 6, 8, 10, 12. Data is converted
-  // to float from -1.0 to 1.0 based on int16 range.
-  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
-  buffer->ReadFrames(6, 0, 0, bus.get());
-  VerifyResult(bus->channel(0), 6, 1.0f / kint16max, 2.0f / kint16max);
-  VerifyResult(bus->channel(1), 6, 2.0f / kint16max, 2.0f / kint16max);
+                                                             start_time);
+  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
+  buffer->ReadFrames(frames, 0, 0, bus.get());
+  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
 
   // Now read the same data one frame at a time.
-  bus = AudioBus::Create(channels, 100);
-  for (int i = 0; i < frames; ++i) {
+  bus->Zero();
+  for (int i = 0; i < frames; ++i)
     buffer->ReadFrames(1, i, i, bus.get());
-  }
-  VerifyResult(bus->channel(0), frames, 1.0f / kint16max, 2.0f / kint16max);
-  VerifyResult(bus->channel(1), frames, 2.0f / kint16max, 2.0f / kint16max);
+  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
 }
 
 TEST(AudioBufferTest, ReadS32) {
   const ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
   const int channels = ChannelLayoutToChannelCount(channel_layout);
-  const int frames = 6;
+  const int frames = 20;
   const base::TimeDelta start_time;
-  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
   scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<int32>(kSampleFormatS32,
                                                              channel_layout,
                                                              channels,
@@ -155,22 +272,15 @@
                                                              1,
                                                              1,
                                                              frames,
-                                                             start_time,
-                                                             duration);
-
-  // Read 6 frames from the buffer. Data is interleaved, so ch[0] should be 1,
-  // 3, 5, 7, 9, 11, and ch[1] should be 2, 4, 6, 8, 10, 12. Data is converted
-  // to float from -1.0 to 1.0 based on int32 range.
-  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
+                                                             start_time);
+  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
   buffer->ReadFrames(frames, 0, 0, bus.get());
-  VerifyResult(bus->channel(0), frames, 1.0f / kint32max, 2.0f / kint32max);
-  VerifyResult(bus->channel(1), frames, 2.0f / kint32max, 2.0f / kint32max);
+  VerifyBus(bus.get(), frames, 1.0f / kint32max, 1.0f / kint32max);
 
-  // Now read 2 frames starting at frame offset 3. ch[0] should be 7, 9, and
-  // ch[1] should be 8, 10.
-  buffer->ReadFrames(2, 3, 0, bus.get());
-  VerifyResult(bus->channel(0), 2, 7.0f / kint32max, 2.0f / kint32max);
-  VerifyResult(bus->channel(1), 2, 8.0f / kint32max, 2.0f / kint32max);
+  // Read second 10 frames.
+  bus->Zero();
+  buffer->ReadFrames(10, 10, 0, bus.get());
+  VerifyBus(bus.get(), 10, 11.0f / kint32max, 1.0f / kint32max);
 }
 
 TEST(AudioBufferTest, ReadF32) {
@@ -178,7 +288,6 @@
   const int channels = ChannelLayoutToChannelCount(channel_layout);
   const int frames = 20;
   const base::TimeDelta start_time;
-  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
   scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<float>(kSampleFormatF32,
                                                              channel_layout,
                                                              channels,
@@ -186,21 +295,15 @@
                                                              1.0f,
                                                              1.0f,
                                                              frames,
-                                                             start_time,
-                                                             duration);
-
-  // Read first 10 frames from the buffer. F32 is interleaved, so ch[0] should
-  // be 1, 3, 5, ... and ch[1] should be 2, 4, 6, ...
-  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
+                                                             start_time);
+  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
   buffer->ReadFrames(10, 0, 0, bus.get());
-  VerifyResult(bus->channel(0), 10, 1.0f, 2.0f);
-  VerifyResult(bus->channel(1), 10, 2.0f, 2.0f);
+  VerifyBus(bus.get(), 10, 1, 1);
 
   // Read second 10 frames.
-  bus = AudioBus::Create(channels, 100);
+  bus->Zero();
   buffer->ReadFrames(10, 10, 0, bus.get());
-  VerifyResult(bus->channel(0), 10, 21.0f, 2.0f);
-  VerifyResult(bus->channel(1), 10, 22.0f, 2.0f);
+  VerifyBus(bus.get(), 10, 11, 1);
 }
 
 TEST(AudioBufferTest, ReadS16Planar) {
@@ -208,7 +311,6 @@
   const int channels = ChannelLayoutToChannelCount(channel_layout);
   const int frames = 20;
   const base::TimeDelta start_time;
-  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
   scoped_refptr<AudioBuffer> buffer =
       MakeAudioBuffer<int16>(kSampleFormatPlanarS16,
                              channel_layout,
@@ -217,32 +319,25 @@
                              1,
                              1,
                              frames,
-                             start_time,
-                             duration);
-
-  // Read 6 frames from the buffer. Data is planar, so ch[0] should be 1, 2, 3,
-  // 4, 5, 6, and ch[1] should be 21, 22, 23, 24, 25, 26. Data is converted to
-  // float from -1.0 to 1.0 based on int16 range.
-  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
-  buffer->ReadFrames(6, 0, 0, bus.get());
-  VerifyResult(bus->channel(0), 6, 1.0f / kint16max, 1.0f / kint16max);
-  VerifyResult(bus->channel(1), 6, 21.0f / kint16max, 1.0f / kint16max);
+                             start_time);
+  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
+  buffer->ReadFrames(10, 0, 0, bus.get());
+  VerifyBus(bus.get(), 10, 1.0f / kint16max, 1.0f / kint16max);
 
   // Read all the frames backwards, one by one. ch[0] should be 20, 19, ...
-  bus = AudioBus::Create(channels, 100);
-  for (int i = 0; i < frames; ++i) {
-    buffer->ReadFrames(1, frames - i - 1, i, bus.get());
-  }
-  VerifyResult(bus->channel(0), frames, 20.0f / kint16max, -1.0f / kint16max);
-  VerifyResult(bus->channel(1), frames, 40.0f / kint16max, -1.0f / kint16max);
+  bus->Zero();
+  for (int i = frames - 1; i >= 0; --i)
+    buffer->ReadFrames(1, i, i, bus.get());
+  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
 
   // Read 0 frames with different offsets. Existing data in AudioBus should be
   // unchanged.
   buffer->ReadFrames(0, 0, 0, bus.get());
+  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
   buffer->ReadFrames(0, 0, 10, bus.get());
+  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
   buffer->ReadFrames(0, 10, 0, bus.get());
-  VerifyResult(bus->channel(0), frames, 20.0f / kint16max, -1.0f / kint16max);
-  VerifyResult(bus->channel(1), frames, 40.0f / kint16max, -1.0f / kint16max);
+  VerifyBus(bus.get(), frames, 1.0f / kint16max, 1.0f / kint16max);
 }
 
 TEST(AudioBufferTest, ReadF32Planar) {
@@ -250,7 +345,6 @@
   const int channels = ChannelLayoutToChannelCount(channel_layout);
   const int frames = 100;
   const base::TimeDelta start_time;
-  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
   scoped_refptr<AudioBuffer> buffer =
       MakeAudioBuffer<float>(kSampleFormatPlanarF32,
                              channel_layout,
@@ -259,103 +353,102 @@
                              1.0f,
                              1.0f,
                              frames,
-                             start_time,
-                             duration);
+                             start_time);
 
   // Read all 100 frames from the buffer. F32 is planar, so ch[0] should be 1,
   // 2, 3, 4, ..., ch[1] should be 101, 102, 103, ..., and so on for all 4
   // channels.
   scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
   buffer->ReadFrames(frames, 0, 0, bus.get());
-  VerifyResult(bus->channel(0), frames, 1.0f, 1.0f);
-  VerifyResult(bus->channel(1), frames, 101.0f, 1.0f);
-  VerifyResult(bus->channel(2), frames, 201.0f, 1.0f);
-  VerifyResult(bus->channel(3), frames, 301.0f, 1.0f);
+  VerifyBus(bus.get(), frames, 1, 1);
 
   // Now read 20 frames from the middle of the buffer.
-  bus = AudioBus::Create(channels, 100);
+  bus->Zero();
   buffer->ReadFrames(20, 50, 0, bus.get());
-  VerifyResult(bus->channel(0), 20, 51.0f, 1.0f);
-  VerifyResult(bus->channel(1), 20, 151.0f, 1.0f);
-  VerifyResult(bus->channel(2), 20, 251.0f, 1.0f);
-  VerifyResult(bus->channel(3), 20, 351.0f, 1.0f);
+  VerifyBus(bus.get(), 20, 51, 1);
 }
 
 TEST(AudioBufferTest, EmptyBuffer) {
   const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
   const int channels = ChannelLayoutToChannelCount(channel_layout);
-  const int frames = 100;
+  const int frames = kSampleRate / 100;
   const base::TimeDelta start_time;
-  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
   scoped_refptr<AudioBuffer> buffer = AudioBuffer::CreateEmptyBuffer(
-      channel_layout, channels, kSampleRate, frames, start_time, duration);
+      channel_layout, channels, kSampleRate, frames, start_time);
   EXPECT_EQ(frames, buffer->frame_count());
   EXPECT_EQ(start_time, buffer->timestamp());
-  EXPECT_EQ(frames, buffer->duration().InSeconds());
+  EXPECT_EQ(base::TimeDelta::FromMilliseconds(10), buffer->duration());
   EXPECT_FALSE(buffer->end_of_stream());
 
   // Read all 100 frames from the buffer. All data should be 0.
-  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
+  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
   buffer->ReadFrames(frames, 0, 0, bus.get());
-  VerifyResult(bus->channel(0), frames, 0.0f, 0.0f);
-  VerifyResult(bus->channel(1), frames, 0.0f, 0.0f);
-  VerifyResult(bus->channel(2), frames, 0.0f, 0.0f);
-  VerifyResult(bus->channel(3), frames, 0.0f, 0.0f);
+  VerifyBus(bus.get(), frames, 0, 0);
 }
 
 TEST(AudioBufferTest, Trim) {
   const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
   const int channels = ChannelLayoutToChannelCount(channel_layout);
-  const int frames = 100;
+  const int frames = kSampleRate / 10;
   const base::TimeDelta start_time;
-  const base::TimeDelta duration = base::TimeDelta::FromSeconds(frames);
+  const base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
   scoped_refptr<AudioBuffer> buffer =
       MakeAudioBuffer<float>(kSampleFormatPlanarF32,
                              channel_layout,
                              channels,
                              kSampleRate,
-                             1.0f,
+                             0.0f,
                              1.0f,
                              frames,
-                             start_time,
-                             duration);
+                             start_time);
   EXPECT_EQ(frames, buffer->frame_count());
   EXPECT_EQ(start_time, buffer->timestamp());
-  EXPECT_EQ(frames, buffer->duration().InSeconds());
+  EXPECT_EQ(duration, buffer->duration());
 
-  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, 100);
-  buffer->ReadFrames(20, 0, 0, bus.get());
-  VerifyResult(bus->channel(0), 20, 1.0f, 1.0f);
+  const int ten_ms_of_frames = kSampleRate / 100;
+  const base::TimeDelta ten_ms = base::TimeDelta::FromMilliseconds(10);
 
-  // Trim off 10 frames from the start.
-  buffer->TrimStart(10);
-  EXPECT_EQ(buffer->frame_count(), frames - 10);
-  EXPECT_EQ(buffer->timestamp(), start_time + base::TimeDelta::FromSeconds(10));
-  EXPECT_EQ(buffer->duration(), base::TimeDelta::FromSeconds(90));
-  buffer->ReadFrames(20, 0, 0, bus.get());
-  VerifyResult(bus->channel(0), 20, 11.0f, 1.0f);
+  scoped_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
+  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
+  VerifyBus(bus.get(), buffer->frame_count(), 0.0f, 1.0f);
 
-  // Trim off 10 frames from the end.
-  buffer->TrimEnd(10);
-  EXPECT_EQ(buffer->frame_count(), frames - 20);
-  EXPECT_EQ(buffer->timestamp(), start_time + base::TimeDelta::FromSeconds(10));
-  EXPECT_EQ(buffer->duration(), base::TimeDelta::FromSeconds(80));
-  buffer->ReadFrames(20, 0, 0, bus.get());
-  VerifyResult(bus->channel(0), 20, 11.0f, 1.0f);
+  // Trim off 10ms of frames from the start.
+  buffer->TrimStart(ten_ms_of_frames);
+  EXPECT_EQ(start_time + ten_ms, buffer->timestamp());
+  EXPECT_EQ(frames - ten_ms_of_frames, buffer->frame_count());
+  EXPECT_EQ(duration - ten_ms, buffer->duration());
+  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
+  VerifyBus(bus.get(), buffer->frame_count(), ten_ms_of_frames, 1.0f);
 
-  // Trim off 50 more from the start.
-  buffer->TrimStart(50);
-  EXPECT_EQ(buffer->frame_count(), frames - 70);
-  EXPECT_EQ(buffer->timestamp(), start_time + base::TimeDelta::FromSeconds(60));
-  EXPECT_EQ(buffer->duration(), base::TimeDelta::FromSeconds(30));
-  buffer->ReadFrames(10, 0, 0, bus.get());
-  VerifyResult(bus->channel(0), 10, 61.0f, 1.0f);
+  // Trim off 10ms of frames from the end.
+  buffer->TrimEnd(ten_ms_of_frames);
+  EXPECT_EQ(start_time + ten_ms, buffer->timestamp());
+  EXPECT_EQ(frames - 2 * ten_ms_of_frames, buffer->frame_count());
+  EXPECT_EQ(duration - 2 * ten_ms, buffer->duration());
+  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
+  VerifyBus(bus.get(), buffer->frame_count(), ten_ms_of_frames, 1.0f);
 
-  // Trim off the last 30 frames.
-  buffer->TrimEnd(30);
-  EXPECT_EQ(buffer->frame_count(), 0);
-  EXPECT_EQ(buffer->timestamp(), start_time + base::TimeDelta::FromSeconds(60));
-  EXPECT_EQ(buffer->duration(), base::TimeDelta::FromSeconds(0));
+  // Trim off 40ms more from the start.
+  buffer->TrimStart(4 * ten_ms_of_frames);
+  EXPECT_EQ(start_time + 5 * ten_ms, buffer->timestamp());
+  EXPECT_EQ(frames - 6 * ten_ms_of_frames, buffer->frame_count());
+  EXPECT_EQ(duration - 6 * ten_ms, buffer->duration());
+  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
+  VerifyBus(bus.get(), buffer->frame_count(), 5 * ten_ms_of_frames, 1.0f);
+
+  // Trim off the final 40ms from the end.
+  buffer->TrimEnd(4 * ten_ms_of_frames);
+  EXPECT_EQ(0, buffer->frame_count());
+  EXPECT_EQ(start_time + 5 * ten_ms, buffer->timestamp());
+  EXPECT_EQ(base::TimeDelta(), buffer->duration());
+}
+
+TEST(AudioBufferTest, TrimRangePlanar) {
+  TrimRangeTest(kSampleFormatPlanarF32);
+}
+
+TEST(AudioBufferTest, TrimRangeInterleaved) {
+  TrimRangeTest(kSampleFormatF32);
 }
 
 }  // namespace media
diff --git a/media/base/audio_discard_helper.cc b/media/base/audio_discard_helper.cc
index 3088130..f7279d7 100644
--- a/media/base/audio_discard_helper.cc
+++ b/media/base/audio_discard_helper.cc
@@ -9,7 +9,6 @@
 #include "base/logging.h"
 #include "media/base/audio_buffer.h"
 #include "media/base/buffers.h"
-#include "media/base/decoder_buffer.h"
 
 namespace media {
 
@@ -24,11 +23,13 @@
                 << " diff " << diff.InMicroseconds() << " us";
 }
 
-AudioDiscardHelper::AudioDiscardHelper(int sample_rate)
+AudioDiscardHelper::AudioDiscardHelper(int sample_rate, size_t decoder_delay)
     : sample_rate_(sample_rate),
+      decoder_delay_(decoder_delay),
       timestamp_helper_(sample_rate_),
       discard_frames_(0),
-      last_input_timestamp_(kNoTimestamp()) {
+      last_input_timestamp_(kNoTimestamp()),
+      delayed_discard_(false) {
   DCHECK_GT(sample_rate_, 0);
 }
 
@@ -44,6 +45,8 @@
   discard_frames_ = initial_discard;
   last_input_timestamp_ = kNoTimestamp();
   timestamp_helper_.SetBaseTimestamp(kNoTimestamp());
+  delayed_discard_ = false;
+  delayed_discard_padding_ = DecoderBuffer::DiscardPadding();
 }
 
 bool AudioDiscardHelper::ProcessBuffers(
@@ -59,15 +62,32 @@
   last_input_timestamp_ = encoded_buffer->timestamp();
 
   // If this is the first buffer seen, setup the timestamp helper.
-  if (!initialized()) {
+  const bool first_buffer = !initialized();
+  if (first_buffer) {
     // Clamp the base timestamp to zero.
     timestamp_helper_.SetBaseTimestamp(
         std::max(base::TimeDelta(), encoded_buffer->timestamp()));
   }
   DCHECK(initialized());
 
-  if (!decoded_buffer || !decoded_buffer->frame_count())
+  if (!decoded_buffer) {
+    // If there's a one buffer delay for decoding, we need to save it so it can
+    // be processed with the next decoder buffer.
+    if (first_buffer) {
+      delayed_discard_ = true;
+      delayed_discard_padding_ = encoded_buffer->discard_padding();
+    }
     return false;
+  }
+
+  const size_t original_frame_count = decoded_buffer->frame_count();
+
+  // If there's a one buffer delay for decoding, pick up the last encoded
+  // buffer's discard padding for processing with the current decoded buffer.
+  DecoderBuffer::DiscardPadding current_discard_padding =
+      encoded_buffer->discard_padding();
+  if (delayed_discard_)
+    std::swap(current_discard_padding, delayed_discard_padding_);
 
   if (discard_frames_ > 0) {
     const size_t decoded_frames = decoded_buffer->frame_count();
@@ -75,20 +95,73 @@
     discard_frames_ -= frames_to_discard;
 
     // If everything would be discarded, indicate a new buffer is required.
-    if (frames_to_discard == decoded_frames)
+    if (frames_to_discard == decoded_frames) {
+      // For simplicity disallow cases where a buffer with discard padding is
+      // present.  Doing so allows us to avoid complexity around tracking
+      // discards across buffers.
+      DCHECK(current_discard_padding.first == base::TimeDelta());
+      DCHECK(current_discard_padding.second == base::TimeDelta());
       return false;
+    }
 
     decoded_buffer->TrimStart(frames_to_discard);
   }
 
-  // TODO(dalecurtis): Applying the current buffer's discard padding doesn't
-  // make sense in the Vorbis case because there is a delay of one buffer before
-  // decoded buffers are returned. Fix and add support for more than just end
-  // trimming.  See http://crbug.com/360961.
-  if (encoded_buffer->discard_padding() > base::TimeDelta()) {
+  // Handle front discard padding.
+  if (current_discard_padding.first > base::TimeDelta()) {
+    const size_t decoded_frames = decoded_buffer->frame_count();
+    const size_t start_frames_to_discard =
+        TimeDeltaToFrames(current_discard_padding.first);
+
+    // Regardless of the timestamp on the encoded buffer, the corresponding
+    // decoded output will appear |decoder_delay_| frames later.
+    size_t discard_start = decoder_delay_;
+    if (decoder_delay_ > 0) {
+      // If we have a |decoder_delay_| and have already discarded frames from
+      // this buffer, the |discard_start| must be adjusted by the number of
+      // frames already discarded.
+      const size_t frames_discarded_so_far =
+          original_frame_count - decoded_buffer->frame_count();
+      CHECK_LE(frames_discarded_so_far, decoder_delay_);
+      discard_start -= frames_discarded_so_far;
+    }
+
+    // For simplicity require the start of the discard to be within the current
+    // buffer.  Doing so allows us avoid complexity around tracking discards
+    // across buffers.
+    CHECK_LT(discard_start, decoded_frames);
+
+    const size_t frames_to_discard =
+        std::min(start_frames_to_discard, decoded_frames - discard_start);
+
+    // Carry over any frames which need to be discarded from the front of the
+    // next buffer.
+    DCHECK(!discard_frames_);
+    discard_frames_ = start_frames_to_discard - frames_to_discard;
+
+    // If everything would be discarded, indicate a new buffer is required.
+    if (frames_to_discard == decoded_frames) {
+      // The buffer should not have been marked with end discard if the front
+      // discard removes everything.
+      DCHECK(current_discard_padding.second == base::TimeDelta());
+      return false;
+    }
+
+    decoded_buffer->TrimRange(discard_start, discard_start + frames_to_discard);
+  } else {
+    DCHECK(current_discard_padding.first == base::TimeDelta());
+  }
+
+  // Handle end discard padding.
+  if (current_discard_padding.second > base::TimeDelta()) {
+    // Limit end discarding to when there is no |decoder_delay_|, otherwise it's
+    // non-trivial determining where to start discarding end frames.
+    CHECK(!decoder_delay_);
+
     const size_t decoded_frames = decoded_buffer->frame_count();
     const size_t end_frames_to_discard =
-        TimeDeltaToFrames(encoded_buffer->discard_padding());
+        TimeDeltaToFrames(current_discard_padding.second);
+
     if (end_frames_to_discard > decoded_frames) {
       DLOG(ERROR) << "Encountered invalid discard padding value.";
       return false;
@@ -100,13 +173,11 @@
 
     decoded_buffer->TrimEnd(end_frames_to_discard);
   } else {
-    DCHECK(encoded_buffer->discard_padding() == base::TimeDelta());
+    DCHECK(current_discard_padding.second == base::TimeDelta());
   }
 
-  // Assign timestamp and duration to the buffer.
+  // Assign timestamp to the buffer.
   decoded_buffer->set_timestamp(timestamp_helper_.GetTimestamp());
-  decoded_buffer->set_duration(
-      timestamp_helper_.GetFrameDuration(decoded_buffer->frame_count()));
   timestamp_helper_.AddFrames(decoded_buffer->frame_count());
   return true;
 }
diff --git a/media/base/audio_discard_helper.h b/media/base/audio_discard_helper.h
index 388cbd4..deeb45f 100644
--- a/media/base/audio_discard_helper.h
+++ b/media/base/audio_discard_helper.h
@@ -9,17 +9,31 @@
 #include "base/time/time.h"
 #include "media/base/audio_timestamp_helper.h"
 #include "media/base/buffers.h"
+#include "media/base/decoder_buffer.h"
 #include "media/base/media_export.h"
 
 namespace media {
 
 class AudioBuffer;
-class DecoderBuffer;
 
 // Helper class for managing timestamps and discard events around decoding.
 class MEDIA_EXPORT AudioDiscardHelper {
  public:
-  explicit AudioDiscardHelper(int sample_rate);
+  // |sample_rate| is the sample rate of decoded data which will be handed into
+  // the ProcessBuffers() call.
+  //
+  // |decoder_delay| is the number of frames a decoder will output before data
+  // corresponding to the first encoded buffer is output.  Callers only need to
+  // specify this if the decoder inserts frames which have no corresponding
+  // encoded buffer.
+  //
+  // For example, most MP3 decoders will output 529 junk frames before the data
+  // corresponding to the first encoded buffer is output.  These frames are not
+  // represented in the encoded data stream and instead are an artifact of how
+  // most MP3 decoders work.  See http://lame.sourceforge.net/tech-FAQ.txt
+  //
+  // NOTE: End discard is only supported when there is no |decoder_delay|.
+  AudioDiscardHelper(int sample_rate, size_t decoder_delay);
   ~AudioDiscardHelper();
 
   // Converts a TimeDelta to a frame count based on the constructed sample rate.
@@ -50,11 +64,15 @@
 
  private:
   const int sample_rate_;
+  const size_t decoder_delay_;
   AudioTimestampHelper timestamp_helper_;
 
   size_t discard_frames_;
   base::TimeDelta last_input_timestamp_;
 
+  bool delayed_discard_;
+  DecoderBuffer::DiscardPadding delayed_discard_padding_;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(AudioDiscardHelper);
 };
 
diff --git a/media/base/audio_discard_helper_unittest.cc b/media/base/audio_discard_helper_unittest.cc
index 7788e7f..55d2b61 100644
--- a/media/base/audio_discard_helper_unittest.cc
+++ b/media/base/audio_discard_helper_unittest.cc
@@ -33,7 +33,6 @@
                          0.0f,
                          kDataStep,
                          frames,
-                         kNoTimestamp(),
                          kNoTimestamp());
 }
 
@@ -47,7 +46,7 @@
 }
 
 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) {
-  AudioDiscardHelper discard_helper(kSampleRate);
+  AudioDiscardHelper discard_helper(kSampleRate, 0);
 
   EXPECT_EQ(0u, discard_helper.TimeDeltaToFrames(base::TimeDelta()));
   EXPECT_EQ(
@@ -71,7 +70,7 @@
 }
 
 TEST(AudioDiscardHelperTest, BasicProcessBuffers) {
-  AudioDiscardHelper discard_helper(kSampleRate);
+  AudioDiscardHelper discard_helper(kSampleRate, 0);
   ASSERT_FALSE(discard_helper.initialized());
 
   const base::TimeDelta kTimestamp = base::TimeDelta();
@@ -103,7 +102,7 @@
 }
 
 TEST(AudioDiscardHelperTest, NegativeTimestampClampsToZero) {
-  AudioDiscardHelper discard_helper(kSampleRate);
+  AudioDiscardHelper discard_helper(kSampleRate, 0);
   ASSERT_FALSE(discard_helper.initialized());
 
   const base::TimeDelta kTimestamp = -base::TimeDelta::FromSeconds(1);
@@ -123,7 +122,7 @@
 }
 
 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) {
-  AudioDiscardHelper discard_helper(kSampleRate);
+  AudioDiscardHelper discard_helper(kSampleRate, 0);
   ASSERT_FALSE(discard_helper.initialized());
 
   const base::TimeDelta kTimestamp = base::TimeDelta();
@@ -149,7 +148,7 @@
 }
 
 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) {
-  AudioDiscardHelper discard_helper(kSampleRate);
+  AudioDiscardHelper discard_helper(kSampleRate, 0);
   ASSERT_FALSE(discard_helper.initialized());
 
   const base::TimeDelta kTimestamp = base::TimeDelta();
@@ -182,7 +181,7 @@
 }
 
 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) {
-  AudioDiscardHelper discard_helper(kSampleRate);
+  AudioDiscardHelper discard_helper(kSampleRate, 0);
   ASSERT_FALSE(discard_helper.initialized());
 
   const base::TimeDelta kTimestamp = base::TimeDelta();
@@ -207,8 +206,8 @@
   EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
 }
 
-TEST(AudioDiscardHelperTest, DiscardPadding) {
-  AudioDiscardHelper discard_helper(kSampleRate);
+TEST(AudioDiscardHelperTest, DiscardEndPadding) {
+  AudioDiscardHelper discard_helper(kSampleRate, 0);
   ASSERT_FALSE(discard_helper.initialized());
 
   const base::TimeDelta kTimestamp = base::TimeDelta();
@@ -220,18 +219,39 @@
   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
 
   // Set a discard padding equivalent to half the buffer.
-  encoded_buffer->set_discard_padding(kDuration / 2);
+  encoded_buffer->set_discard_padding(
+      std::make_pair(base::TimeDelta(), kDuration / 2));
 
   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
   ASSERT_TRUE(discard_helper.initialized());
   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
   EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
   EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
-  ASSERT_FLOAT_EQ(0, ExtractDecodedData(decoded_buffer, 0));
 }
 
-TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
-  AudioDiscardHelper discard_helper(kSampleRate);
+TEST(AudioDiscardHelperTest, BadDiscardEndPadding) {
+  AudioDiscardHelper discard_helper(kSampleRate, 0);
+  ASSERT_FALSE(discard_helper.initialized());
+
+  const base::TimeDelta kTimestamp = base::TimeDelta();
+  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
+  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
+
+  scoped_refptr<DecoderBuffer> encoded_buffer =
+      CreateEncodedBuffer(kTimestamp, kDuration);
+  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
+
+  // Set a discard padding equivalent to double the buffer size.
+  encoded_buffer->set_discard_padding(
+      std::make_pair(base::TimeDelta(), kDuration * 2));
+
+  // Verify the end discard padding is rejected.
+  ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
+  ASSERT_TRUE(discard_helper.initialized());
+}
+
+TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardEndPadding) {
+  AudioDiscardHelper discard_helper(kSampleRate, 0);
   ASSERT_FALSE(discard_helper.initialized());
 
   const base::TimeDelta kTimestamp = base::TimeDelta();
@@ -243,7 +263,8 @@
   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
 
   // Set a discard padding equivalent to a quarter of the buffer.
-  encoded_buffer->set_discard_padding(kDuration / 4);
+  encoded_buffer->set_discard_padding(
+      std::make_pair(base::TimeDelta(), kDuration / 4));
 
   // Set an initial discard of a quarter of the buffer.
   const int kDiscardFrames = kTestFrames / 4;
@@ -258,4 +279,106 @@
                   ExtractDecodedData(decoded_buffer, 0));
 }
 
+TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
+  AudioDiscardHelper discard_helper(kSampleRate, 0);
+  ASSERT_FALSE(discard_helper.initialized());
+
+  const base::TimeDelta kTimestamp = base::TimeDelta();
+  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
+  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
+
+  scoped_refptr<DecoderBuffer> encoded_buffer =
+      CreateEncodedBuffer(kTimestamp, kDuration);
+  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
+
+  // Set all the discard values to be different to ensure each is properly used.
+  const int kDiscardFrames = kTestFrames / 4;
+  encoded_buffer->set_discard_padding(
+      std::make_pair(kDuration / 8, kDuration / 16));
+  discard_helper.Reset(kDiscardFrames);
+
+  ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
+  ASSERT_TRUE(discard_helper.initialized());
+  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
+  EXPECT_EQ(kDuration - kDuration / 4 - kDuration / 8 - kDuration / 16,
+            decoded_buffer->duration());
+  EXPECT_EQ(kTestFrames - kTestFrames / 4 - kTestFrames / 8 - kTestFrames / 16,
+            decoded_buffer->frame_count());
+}
+
+TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPaddingAndCodecDelay) {
+  // Use a codec delay of 5ms.
+  const int kCodecDelay = kSampleRate / 100 / 2;
+  AudioDiscardHelper discard_helper(kSampleRate, kCodecDelay);
+  ASSERT_FALSE(discard_helper.initialized());
+  discard_helper.Reset(kCodecDelay);
+
+  const base::TimeDelta kTimestamp = base::TimeDelta();
+  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
+  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
+
+  scoped_refptr<DecoderBuffer> encoded_buffer =
+      CreateEncodedBuffer(kTimestamp, kDuration);
+  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
+
+  // Set a discard padding equivalent to half of the buffer.
+  encoded_buffer->set_discard_padding(
+      std::make_pair(kDuration / 2, base::TimeDelta()));
+
+  // All of the first buffer should be discarded.
+  ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
+  ASSERT_TRUE(discard_helper.initialized());
+
+  // Processing another buffer (with the same discard padding) should discard
+  // the back half of the buffer since kCodecDelay is half a buffer.
+  encoded_buffer->set_timestamp(kTimestamp + kDuration);
+  decoded_buffer = CreateDecodedBuffer(kTestFrames);
+  ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
+  ASSERT_NEAR(kCodecDelay * kDataStep,
+              ExtractDecodedData(decoded_buffer, kCodecDelay),
+              kDataStep * 1000);
+  ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
+  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
+  EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
+  EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
+
+  // Verify it was actually the latter half of the buffer that was removed.
+  ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
+}
+
+TEST(AudioDiscardHelperTest, DelayedDiscardInitialDiscardAndDiscardPadding) {
+  AudioDiscardHelper discard_helper(kSampleRate, 0);
+  ASSERT_FALSE(discard_helper.initialized());
+
+  const base::TimeDelta kTimestamp = base::TimeDelta();
+  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
+  const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
+
+  scoped_refptr<DecoderBuffer> encoded_buffer =
+      CreateEncodedBuffer(kTimestamp, kDuration);
+
+  // Set all the discard values to be different to ensure each is properly used.
+  const int kDiscardFrames = kTestFrames / 4;
+  encoded_buffer->set_discard_padding(
+      std::make_pair(kDuration / 8, kDuration / 16));
+  discard_helper.Reset(kDiscardFrames);
+
+  // Verify nothing is output for the first buffer, yet initialized is true.
+  ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL));
+  ASSERT_TRUE(discard_helper.initialized());
+
+  // Create an encoded buffer with no discard padding.
+  encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration);
+  scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
+
+  // Verify that when the decoded buffer is consumed, the discards from the
+  // previous encoded buffer are applied.
+  ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
+  EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
+  EXPECT_EQ(kDuration - kDuration / 4 - kDuration / 8 - kDuration / 16,
+            decoded_buffer->duration());
+  EXPECT_EQ(kTestFrames - kTestFrames / 4 - kTestFrames / 8 - kTestFrames / 16,
+            decoded_buffer->frame_count());
+}
+
 }  // namespace media
diff --git a/media/base/audio_splicer.cc b/media/base/audio_splicer.cc
index b83765e..2fb4180 100644
--- a/media/base/audio_splicer.cc
+++ b/media/base/audio_splicer.cc
@@ -35,20 +35,6 @@
                               const AudioTimestampHelper& timestamp_helper) {
   buffer->TrimStart(frames_to_trim);
   buffer->set_timestamp(timestamp_helper.GetTimestamp());
-  buffer->set_duration(
-      timestamp_helper.GetFrameDuration(buffer->frame_count()));
-}
-
-// AudioBuffer::TrimEnd() is not as accurate as the timestamp helper, so
-// manually adjust the duration after trimming.
-static void AccurateTrimEnd(int frames_to_trim,
-                            const scoped_refptr<AudioBuffer> buffer,
-                            const AudioTimestampHelper& timestamp_helper) {
-  DCHECK_LT(std::abs(timestamp_helper.GetFramesToTarget(buffer->timestamp())),
-            kMinGapSize);
-  buffer->TrimEnd(frames_to_trim);
-  buffer->set_duration(
-      timestamp_helper.GetFrameDuration(buffer->frame_count()));
 }
 
 // Returns an AudioBus whose frame buffer is backed by the provided AudioBuffer.
@@ -177,13 +163,12 @@
 
     // Create a buffer with enough silence samples to fill the gap and
     // add it to the output buffer.
-    scoped_refptr<AudioBuffer> gap = AudioBuffer::CreateEmptyBuffer(
-        input->channel_layout(),
-        input->channel_count(),
-        input->sample_rate(),
-        frames_to_fill,
-        expected_timestamp,
-        output_timestamp_helper_.GetFrameDuration(frames_to_fill));
+    scoped_refptr<AudioBuffer> gap =
+        AudioBuffer::CreateEmptyBuffer(input->channel_layout(),
+                                       input->channel_count(),
+                                       input->sample_rate(),
+                                       frames_to_fill,
+                                       expected_timestamp);
     AddOutputBuffer(gap);
 
     // Add the input buffer now that the gap has been filled.
@@ -304,7 +289,7 @@
 
   // The first post splice buffer is expected to match |splice_timestamp_|.
   if (!post_splice_sanitizer_->HasNextBuffer())
-    DCHECK(splice_timestamp_ == input->timestamp());
+    CHECK(splice_timestamp_ == input->timestamp());
 
   // At this point we have all the fade out preroll buffers from the decoder.
   // We now need to wait until we have enough data to perform the crossfade (or
@@ -443,14 +428,18 @@
     // If only part of the buffer was consumed, trim it appropriately and stick
     // it into the output queue.
     if (frames_before_splice) {
-      AccurateTrimEnd(preroll->frame_count() - frames_before_splice,
-                      preroll,
-                      output_ts_helper);
+      preroll->TrimEnd(preroll->frame_count() - frames_before_splice);
       CHECK(output_sanitizer_->AddInput(preroll));
       frames_before_splice = 0;
     }
   }
 
+  // Ensure outputs were properly allocated.  The method should not have been
+  // called if there is not enough data to crossfade.
+  // TODO(dalecurtis): Convert to DCHECK() once http://crbug.com/356073 fixed.
+  CHECK(output_bus);
+  CHECK(*crossfade_buffer);
+
   // All necessary buffers have been processed, it's safe to reset.
   pre_splice_sanitizer_->Reset();
   DCHECK_EQ(output_bus->frames(), frames_read);
@@ -466,8 +455,6 @@
   const AudioTimestampHelper& output_ts_helper =
       output_sanitizer_->timestamp_helper();
   crossfade_buffer->set_timestamp(output_ts_helper.GetTimestamp());
-  crossfade_buffer->set_duration(
-      output_ts_helper.GetFrameDuration(pre_splice_bus->frames()));
 
   // AudioBuffer::ReadFrames() only allows output into an AudioBus, so wrap
   // our AudioBuffer in one so we can avoid extra data copies.
diff --git a/media/base/audio_splicer_unittest.cc b/media/base/audio_splicer_unittest.cc
index 71e1728..2e46b9f 100644
--- a/media/base/audio_splicer_unittest.cc
+++ b/media/base/audio_splicer_unittest.cc
@@ -35,16 +35,15 @@
   }
 
   scoped_refptr<AudioBuffer> GetNextInputBuffer(float value, int frame_size) {
-    scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<float>(
-        kSampleFormat,
-        kChannelLayout,
-        kChannels,
-        kDefaultSampleRate,
-        value,
-        0.0f,
-        frame_size,
-        input_timestamp_helper_.GetTimestamp(),
-        input_timestamp_helper_.GetFrameDuration(frame_size));
+    scoped_refptr<AudioBuffer> buffer =
+        MakeAudioBuffer<float>(kSampleFormat,
+                               kChannelLayout,
+                               kChannels,
+                               kDefaultSampleRate,
+                               value,
+                               0.0f,
+                               frame_size,
+                               input_timestamp_helper_.GetTimestamp());
     input_timestamp_helper_.AddFrames(frame_size);
     return buffer;
   }
@@ -139,8 +138,7 @@
                                     input->sample_rate(),
                                     input->frame_count(),
                                     &input->channel_data()[0],
-                                    input->timestamp(),
-                                    input->duration());
+                                    input->timestamp());
     return splicer_.AddInput(buffer_copy);
   }
 
@@ -248,7 +246,8 @@
   base::TimeDelta gap_duration = input_2->timestamp() - gap_timestamp;
   EXPECT_GT(gap_duration, base::TimeDelta());
   EXPECT_EQ(gap_timestamp, output_2->timestamp());
-  EXPECT_EQ(gap_duration, output_2->duration());
+  EXPECT_NEAR(
+      gap_duration.InMicroseconds(), output_2->duration().InMicroseconds(), 1);
   EXPECT_EQ(kGapSize, output_2->frame_count());
   EXPECT_TRUE(VerifyData(output_2, 0.0f));
 
@@ -444,7 +443,7 @@
   VerifyPreSpliceOutput(overlapped_buffer,
                         overlapping_buffer,
                         221,
-                        base::TimeDelta::FromMicroseconds(5012));
+                        base::TimeDelta::FromMicroseconds(5011));
 
   // Due to rounding the crossfade size may vary by up to a frame.
   const int kExpectedCrossfadeSize = 220;
@@ -619,11 +618,13 @@
       GetNextInputBuffer(1.0f, kBufferSize);
   // Fuzz the duration slightly so that the buffer overlaps the splice timestamp
   // by a microsecond, which is not enough to crossfade.
-  first_buffer->set_duration(first_buffer->duration() +
-                             base::TimeDelta::FromMicroseconds(1));
-  splicer_.SetSpliceTimestamp(input_timestamp_helper_.GetTimestamp());
+  const base::TimeDelta kSpliceTimestamp =
+      input_timestamp_helper_.GetTimestamp() -
+      base::TimeDelta::FromMicroseconds(1);
+  splicer_.SetSpliceTimestamp(kSpliceTimestamp);
   scoped_refptr<AudioBuffer> second_buffer =
       GetNextInputBuffer(0.0f, kBufferSize);
+  second_buffer->set_timestamp(kSpliceTimestamp);
 
   // The splicer should be internally queuing input since |first_buffer| is part
   // of the supposed splice.
diff --git a/media/base/decoder_buffer.cc b/media/base/decoder_buffer.cc
index b6d7d26..2059817 100644
--- a/media/base/decoder_buffer.cc
+++ b/media/base/decoder_buffer.cc
@@ -83,7 +83,8 @@
     << " size: " << size_
     << " side_data_size: " << side_data_size_
     << " encrypted: " << (decrypt_config_ != NULL)
-    << " discard_padding (ms): " << discard_padding_.InMilliseconds();
+    << " discard_padding (ms): (" << discard_padding_.first.InMilliseconds()
+    << ", " << discard_padding_.second.InMilliseconds() << ")";
   return s.str();
 }
 
diff --git a/media/base/decoder_buffer.h b/media/base/decoder_buffer.h
index 8edc539..4ff836d 100644
--- a/media/base/decoder_buffer.h
+++ b/media/base/decoder_buffer.h
@@ -6,6 +6,7 @@
 #define MEDIA_BASE_DECODER_BUFFER_H_
 
 #include <string>
+#include <utility>
 
 #include "base/logging.h"
 #include "base/memory/aligned_memory.h"
@@ -105,12 +106,16 @@
     return side_data_size_;
   }
 
-  base::TimeDelta discard_padding() const {
+  // A discard window indicates the amount of data which should be discard from
+  // this buffer after decoding.  The first value is the amount of the front and
+  // the second the amount off the back.
+  typedef std::pair<base::TimeDelta, base::TimeDelta> DiscardPadding;
+  const DiscardPadding& discard_padding() const {
     DCHECK(!end_of_stream());
     return discard_padding_;
   }
 
-  void set_discard_padding(const base::TimeDelta discard_padding) {
+  void set_discard_padding(const DiscardPadding& discard_padding) {
     DCHECK(!end_of_stream());
     discard_padding_ = discard_padding;
   }
@@ -166,7 +171,7 @@
   int side_data_size_;
   scoped_ptr<uint8, base::AlignedFreeDeleter> side_data_;
   scoped_ptr<DecryptConfig> decrypt_config_;
-  base::TimeDelta discard_padding_;
+  DiscardPadding discard_padding_;
   base::TimeDelta splice_timestamp_;
 
   // Constructor helper method for memory allocations.
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 68b6e5e..515c0bc 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -40,6 +40,11 @@
 // for experimentation purposes, in particular library load time issue, the
 // usage of this library can be enabled by using this flag.
 const char kEnableAVFoundation[] = "enable-avfoundation";
+// QTKit is the media capture API predecessor to AVFoundation, available up and
+// until Mac OS X 10.9 (despite being deprecated in this last one). This flag
+// is used for troubleshooting and testing, and forces QTKit in builds and
+// configurations where AVFoundation would be used otherwise.
+const char kForceQTKit[] = "force-qtkit";
 #endif
 
 #if defined(OS_WIN)
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index 289a3b1..90a25f4 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -30,6 +30,7 @@
 
 #if defined(OS_MACOSX)
 MEDIA_EXPORT extern const char kEnableAVFoundation[];
+MEDIA_EXPORT extern const char kForceQTKit[];
 #endif
 
 #if defined(OS_WIN)
diff --git a/media/base/simd/convert_yuv_to_rgb.h b/media/base/simd/convert_yuv_to_rgb.h
index 2991d56..6c0a966 100644
--- a/media/base/simd/convert_yuv_to_rgb.h
+++ b/media/base/simd/convert_yuv_to_rgb.h
@@ -28,7 +28,8 @@
                                          const uint8* uplane,
                                          const uint8* vplane,
                                          uint8* rgbframe,
-                                         ptrdiff_t width);
+                                         ptrdiff_t width,
+                                         const int16 convert_table[1024][4]);
 
 MEDIA_EXPORT void ConvertYUVAToARGB_C(const uint8* yplane,
                                       const uint8* uplane,
@@ -48,7 +49,8 @@
                                          const uint8* vplane,
                                          const uint8* aplane,
                                          uint8* rgbframe,
-                                         ptrdiff_t width);
+                                         ptrdiff_t width,
+                                         const int16 convert_table[1024][4]);
 
 MEDIA_EXPORT void ConvertYUVToRGB32_SSE(const uint8* yplane,
                                         const uint8* uplane,
@@ -90,22 +92,27 @@
                                        const uint8* v_buf,
                                        uint8* rgb_buf,
                                        ptrdiff_t width,
-                                       ptrdiff_t source_dx);
+                                       ptrdiff_t source_dx,
+                                       const int16 convert_table[1024][4]);
 
-MEDIA_EXPORT void LinearScaleYUVToRGB32Row_C(const uint8* y_buf,
-                                             const uint8* u_buf,
-                                             const uint8* v_buf,
-                                             uint8* rgb_buf,
-                                             ptrdiff_t width,
-                                             ptrdiff_t source_dx);
+MEDIA_EXPORT void LinearScaleYUVToRGB32Row_C(
+    const uint8* y_buf,
+    const uint8* u_buf,
+    const uint8* v_buf,
+    uint8* rgb_buf,
+    ptrdiff_t width,
+    ptrdiff_t source_dx,
+    const int16 convert_table[1024][4]);
 
-MEDIA_EXPORT void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf,
-                                                      const uint8* u_buf,
-                                                      const uint8* v_buf,
-                                                      uint8* rgb_buf,
-                                                      int dest_width,
-                                                      int source_x,
-                                                      int source_dx);
+MEDIA_EXPORT void LinearScaleYUVToRGB32RowWithRange_C(
+    const uint8* y_buf,
+    const uint8* u_buf,
+    const uint8* v_buf,
+    uint8* rgb_buf,
+    int dest_width,
+    int source_x,
+    int source_dx,
+    const int16 convert_table[1024][4]);
 
 }  // namespace media
 
@@ -123,62 +130,75 @@
                                            const uint8* uplane,
                                            const uint8* vplane,
                                            uint8* rgbframe,
-                                           ptrdiff_t width);
+                                           ptrdiff_t width,
+                                           const int16 convert_table[1024][4]);
 
 MEDIA_EXPORT void ConvertYUVAToARGBRow_MMX(const uint8* yplane,
                                            const uint8* uplane,
                                            const uint8* vplane,
                                            const uint8* aplane,
                                            uint8* rgbframe,
-                                           ptrdiff_t width);
+                                           ptrdiff_t width,
+                                           const int16 convert_table[1024][4]);
 
 MEDIA_EXPORT void ConvertYUVToRGB32Row_SSE(const uint8* yplane,
                                            const uint8* uplane,
                                            const uint8* vplane,
                                            uint8* rgbframe,
-                                           ptrdiff_t width);
+                                           ptrdiff_t width,
+                                           const int16 convert_table[1024][4]);
 
 MEDIA_EXPORT void ScaleYUVToRGB32Row_MMX(const uint8* y_buf,
                                          const uint8* u_buf,
                                          const uint8* v_buf,
                                          uint8* rgb_buf,
                                          ptrdiff_t width,
-                                         ptrdiff_t source_dx);
+                                         ptrdiff_t source_dx,
+                                         const int16 convert_table[1024][4]);
 
 MEDIA_EXPORT void ScaleYUVToRGB32Row_SSE(const uint8* y_buf,
                                          const uint8* u_buf,
                                          const uint8* v_buf,
                                          uint8* rgb_buf,
                                          ptrdiff_t width,
-                                         ptrdiff_t source_dx);
+                                         ptrdiff_t source_dx,
+                                         const int16 convert_table[1024][4]);
 
-MEDIA_EXPORT void ScaleYUVToRGB32Row_SSE2_X64(const uint8* y_buf,
-                                              const uint8* u_buf,
-                                              const uint8* v_buf,
-                                              uint8* rgb_buf,
-                                              ptrdiff_t width,
-                                              ptrdiff_t source_dx);
+MEDIA_EXPORT void ScaleYUVToRGB32Row_SSE2_X64(
+    const uint8* y_buf,
+    const uint8* u_buf,
+    const uint8* v_buf,
+    uint8* rgb_buf,
+    ptrdiff_t width,
+    ptrdiff_t source_dx,
+    const int16 convert_table[1024][4]);
 
-MEDIA_EXPORT void LinearScaleYUVToRGB32Row_MMX(const uint8* y_buf,
-                                               const uint8* u_buf,
-                                               const uint8* v_buf,
-                                               uint8* rgb_buf,
-                                               ptrdiff_t width,
-                                               ptrdiff_t source_dx);
+MEDIA_EXPORT void LinearScaleYUVToRGB32Row_MMX(
+    const uint8* y_buf,
+    const uint8* u_buf,
+    const uint8* v_buf,
+    uint8* rgb_buf,
+    ptrdiff_t width,
+    ptrdiff_t source_dx,
+    const int16 convert_table[1024][4]);
 
-MEDIA_EXPORT void LinearScaleYUVToRGB32Row_SSE(const uint8* y_buf,
-                                               const uint8* u_buf,
-                                               const uint8* v_buf,
-                                               uint8* rgb_buf,
-                                               ptrdiff_t width,
-                                               ptrdiff_t source_dx);
+MEDIA_EXPORT void LinearScaleYUVToRGB32Row_SSE(
+    const uint8* y_buf,
+    const uint8* u_buf,
+    const uint8* v_buf,
+    uint8* rgb_buf,
+    ptrdiff_t width,
+    ptrdiff_t source_dx,
+    const int16 convert_table[1024][4]);
 
-MEDIA_EXPORT void LinearScaleYUVToRGB32Row_MMX_X64(const uint8* y_buf,
-                                                   const uint8* u_buf,
-                                                   const uint8* v_buf,
-                                                   uint8* rgb_buf,
-                                                   ptrdiff_t width,
-                                                   ptrdiff_t source_dx);
+MEDIA_EXPORT void LinearScaleYUVToRGB32Row_MMX_X64(
+    const uint8* y_buf,
+    const uint8* u_buf,
+    const uint8* v_buf,
+    uint8* rgb_buf,
+    ptrdiff_t width,
+    ptrdiff_t source_dx,
+    const int16 convert_table[1024][4]);
 
 }  // extern "C"
 
diff --git a/media/base/simd/convert_yuv_to_rgb_c.cc b/media/base/simd/convert_yuv_to_rgb_c.cc
index 0466112..9d6476b 100644
--- a/media/base/simd/convert_yuv_to_rgb_c.cc
+++ b/media/base/simd/convert_yuv_to_rgb_c.cc
@@ -38,21 +38,22 @@
 static inline void ConvertYUVToRGB32_C(uint8 y,
                                        uint8 u,
                                        uint8 v,
-                                       uint8* rgb_buf) {
-  int b = kCoefficientsRgbY[256+u][B_INDEX];
-  int g = kCoefficientsRgbY[256+u][G_INDEX];
-  int r = kCoefficientsRgbY[256+u][R_INDEX];
-  int a = kCoefficientsRgbY[256+u][A_INDEX];
+                                       uint8* rgb_buf,
+                                       const int16 convert_table[1024][4]) {
+  int b = convert_table[256+u][B_INDEX];
+  int g = convert_table[256+u][G_INDEX];
+  int r = convert_table[256+u][R_INDEX];
+  int a = convert_table[256+u][A_INDEX];
 
-  b = paddsw(b, kCoefficientsRgbY[512+v][B_INDEX]);
-  g = paddsw(g, kCoefficientsRgbY[512+v][G_INDEX]);
-  r = paddsw(r, kCoefficientsRgbY[512+v][R_INDEX]);
-  a = paddsw(a, kCoefficientsRgbY[512+v][A_INDEX]);
+  b = paddsw(b, convert_table[512+v][B_INDEX]);
+  g = paddsw(g, convert_table[512+v][G_INDEX]);
+  r = paddsw(r, convert_table[512+v][R_INDEX]);
+  a = paddsw(a, convert_table[512+v][A_INDEX]);
 
-  b = paddsw(b, kCoefficientsRgbY[y][B_INDEX]);
-  g = paddsw(g, kCoefficientsRgbY[y][G_INDEX]);
-  r = paddsw(r, kCoefficientsRgbY[y][R_INDEX]);
-  a = paddsw(a, kCoefficientsRgbY[y][A_INDEX]);
+  b = paddsw(b, convert_table[y][B_INDEX]);
+  g = paddsw(g, convert_table[y][G_INDEX]);
+  r = paddsw(r, convert_table[y][R_INDEX]);
+  a = paddsw(a, convert_table[y][A_INDEX]);
 
   b >>= 6;
   g >>= 6;
@@ -69,18 +70,19 @@
                                        uint8 u,
                                        uint8 v,
                                        uint8 a,
-                                       uint8* rgb_buf) {
-  int b = kCoefficientsRgbY[256+u][0];
-  int g = kCoefficientsRgbY[256+u][1];
-  int r = kCoefficientsRgbY[256+u][2];
+                                       uint8* rgb_buf,
+                                       const int16 convert_table[1024][4]) {
+  int b = convert_table[256+u][0];
+  int g = convert_table[256+u][1];
+  int r = convert_table[256+u][2];
 
-  b = paddsw(b, kCoefficientsRgbY[512+v][0]);
-  g = paddsw(g, kCoefficientsRgbY[512+v][1]);
-  r = paddsw(r, kCoefficientsRgbY[512+v][2]);
+  b = paddsw(b, convert_table[512+v][0]);
+  g = paddsw(g, convert_table[512+v][1]);
+  r = paddsw(r, convert_table[512+v][2]);
 
-  b = paddsw(b, kCoefficientsRgbY[y][0]);
-  g = paddsw(g, kCoefficientsRgbY[y][1]);
-  r = paddsw(r, kCoefficientsRgbY[y][2]);
+  b = paddsw(b, convert_table[y][0]);
+  g = paddsw(g, convert_table[y][1]);
+  r = paddsw(r, convert_table[y][2]);
 
   b >>= 6;
   g >>= 6;
@@ -100,15 +102,16 @@
                             const uint8* u_buf,
                             const uint8* v_buf,
                             uint8* rgb_buf,
-                            ptrdiff_t width) {
+                            ptrdiff_t width,
+                            const int16 convert_table[1024][4]) {
   for (int x = 0; x < width; x += 2) {
     uint8 u = u_buf[x >> 1];
     uint8 v = v_buf[x >> 1];
     uint8 y0 = y_buf[x];
-    ConvertYUVToRGB32_C(y0, u, v, rgb_buf);
+    ConvertYUVToRGB32_C(y0, u, v, rgb_buf, convert_table);
     if ((x + 1) < width) {
       uint8 y1 = y_buf[x + 1];
-      ConvertYUVToRGB32_C(y1, u, v, rgb_buf + 4);
+      ConvertYUVToRGB32_C(y1, u, v, rgb_buf + 4, convert_table);
     }
     rgb_buf += 8;  // Advance 2 pixels.
   }
@@ -119,17 +122,18 @@
                             const uint8* v_buf,
                             const uint8* a_buf,
                             uint8* rgba_buf,
-                            ptrdiff_t width) {
+                            ptrdiff_t width,
+                            const int16 convert_table[1024][4]) {
   for (int x = 0; x < width; x += 2) {
     uint8 u = u_buf[x >> 1];
     uint8 v = v_buf[x >> 1];
     uint8 y0 = y_buf[x];
     uint8 a0 = a_buf[x];
-    ConvertYUVAToARGB_C(y0, u, v, a0, rgba_buf);
+    ConvertYUVAToARGB_C(y0, u, v, a0, rgba_buf, convert_table);
     if ((x + 1) < width) {
       uint8 y1 = y_buf[x + 1];
       uint8 a1 = a_buf[x + 1];
-      ConvertYUVAToARGB_C(y1, u, v, a1, rgba_buf + 4);
+      ConvertYUVAToARGB_C(y1, u, v, a1, rgba_buf + 4, convert_table);
     }
     rgba_buf += 8;  // Advance 2 pixels.
   }
@@ -144,17 +148,18 @@
                           const uint8* v_buf,
                           uint8* rgb_buf,
                           ptrdiff_t width,
-                          ptrdiff_t source_dx) {
+                          ptrdiff_t source_dx,
+                          const int16 convert_table[1024][4]) {
   int x = 0;
   for (int i = 0; i < width; i += 2) {
     int y = y_buf[x >> 16];
     int u = u_buf[(x >> 17)];
     int v = v_buf[(x >> 17)];
-    ConvertYUVToRGB32_C(y, u, v, rgb_buf);
+    ConvertYUVToRGB32_C(y, u, v, rgb_buf, convert_table);
     x += source_dx;
     if ((i + 1) < width) {
       y = y_buf[x >> 16];
-      ConvertYUVToRGB32_C(y, u, v, rgb_buf+4);
+      ConvertYUVToRGB32_C(y, u, v, rgb_buf+4, convert_table);
       x += source_dx;
     }
     rgb_buf += 8;
@@ -166,13 +171,14 @@
                                 const uint8* v_buf,
                                 uint8* rgb_buf,
                                 ptrdiff_t width,
-                                ptrdiff_t source_dx) {
+                                ptrdiff_t source_dx,
+                                const int16 convert_table[1024][4]) {
   // Avoid point-sampling for down-scaling by > 2:1.
   int source_x = 0;
   if (source_dx >= 0x20000)
     source_x += 0x8000;
   LinearScaleYUVToRGB32RowWithRange_C(y_buf, u_buf, v_buf, rgb_buf, width,
-                                      source_x, source_dx);
+                                      source_x, source_dx, convert_table);
 }
 
 void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf,
@@ -181,7 +187,8 @@
                                          uint8* rgb_buf,
                                          int dest_width,
                                          int x,
-                                         int source_dx) {
+                                         int source_dx,
+                                         const int16 convert_table[1024][4]) {
   for (int i = 0; i < dest_width; i += 2) {
     int y0 = y_buf[x >> 16];
     int y1 = y_buf[(x >> 16) + 1];
@@ -194,14 +201,14 @@
     int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
     int u = (uv_frac * u1 + (uv_frac ^ 65535) * u0) >> 16;
     int v = (uv_frac * v1 + (uv_frac ^ 65535) * v0) >> 16;
-    ConvertYUVToRGB32_C(y, u, v, rgb_buf);
+    ConvertYUVToRGB32_C(y, u, v, rgb_buf, convert_table);
     x += source_dx;
     if ((i + 1) < dest_width) {
       y0 = y_buf[x >> 16];
       y1 = y_buf[(x >> 16) + 1];
       y_frac = (x & 65535);
       y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
-      ConvertYUVToRGB32_C(y, u, v, rgb_buf+4);
+      ConvertYUVToRGB32_C(y, u, v, rgb_buf+4, convert_table);
       x += source_dx;
     }
     rgb_buf += 8;
@@ -218,7 +225,7 @@
                          int uvstride,
                          int rgbstride,
                          YUVType yuv_type) {
-  unsigned int y_shift = yuv_type;
+  unsigned int y_shift = GetVerticalShift(yuv_type);
   for (int y = 0; y < height; ++y) {
     uint8* rgb_row = rgbframe + y * rgbstride;
     const uint8* y_ptr = yplane + y * ystride;
@@ -229,7 +236,8 @@
                            u_ptr,
                            v_ptr,
                            rgb_row,
-                           width);
+                           width,
+                           GetLookupTable(yuv_type));
   }
 }
 
@@ -258,7 +266,8 @@
                            v_ptr,
                            a_ptr,
                            rgba_row,
-                           width);
+                           width,
+                           GetLookupTable(yuv_type));
   }
 }
 
diff --git a/media/base/simd/convert_yuv_to_rgb_mmx.asm b/media/base/simd/convert_yuv_to_rgb_mmx.asm
index 39a4f75..7395419 100644
--- a/media/base/simd/convert_yuv_to_rgb_mmx.asm
+++ b/media/base/simd/convert_yuv_to_rgb_mmx.asm
@@ -17,6 +17,7 @@
 ;                                          const uint8* u_buf,
 ;                                          const uint8* v_buf,
 ;                                          uint8* rgb_buf,
-;                                          ptrdiff_t width);
+;                                          ptrdiff_t width,
+;                                          const int16 convert_table[1024][4]);
 %define SYMBOL ConvertYUVToRGB32Row_MMX
 %include "convert_yuv_to_rgb_mmx.inc"
diff --git a/media/base/simd/convert_yuv_to_rgb_mmx.inc b/media/base/simd/convert_yuv_to_rgb_mmx.inc
index f143574..4b69d1b 100644
--- a/media/base/simd/convert_yuv_to_rgb_mmx.inc
+++ b/media/base/simd/convert_yuv_to_rgb_mmx.inc
@@ -9,10 +9,7 @@
 
 mangle(SYMBOL):
   %assign   stack_offset 0
-  PROLOGUE  5, 7, 3, Y, U, V, ARGB, WIDTH, TEMP, TABLE
-
-  extern    mangle(kCoefficientsRgbY)
-  LOAD_SYM  TABLEq, mangle(kCoefficientsRgbY)
+  PROLOGUE  6, 7, 3, Y, U, V, ARGB, WIDTH, TABLE, TEMP
 
   jmp       .convertend
 
diff --git a/media/base/simd/convert_yuv_to_rgb_sse.asm b/media/base/simd/convert_yuv_to_rgb_sse.asm
index 8b3ee58..44b123f 100644
--- a/media/base/simd/convert_yuv_to_rgb_sse.asm
+++ b/media/base/simd/convert_yuv_to_rgb_sse.asm
@@ -19,5 +19,6 @@
 ;                                          const uint8* v_buf,
 ;                                          uint8* rgb_buf,
 ;                                          ptrdiff_t width);
+;                                          const int16 convert_table[1024][4]);
 %define SYMBOL ConvertYUVToRGB32Row_SSE
 %include "convert_yuv_to_rgb_mmx.inc"
diff --git a/media/base/simd/convert_yuv_to_rgb_x86.cc b/media/base/simd/convert_yuv_to_rgb_x86.cc
index d1d6e16..969890d 100644
--- a/media/base/simd/convert_yuv_to_rgb_x86.cc
+++ b/media/base/simd/convert_yuv_to_rgb_x86.cc
@@ -9,6 +9,7 @@
 #endif
 
 #include "media/base/simd/convert_yuv_to_rgb.h"
+#include "media/base/simd/yuv_to_rgb_table.h"
 #include "media/base/yuv_convert.h"
 
 namespace media {
@@ -23,7 +24,7 @@
                            int uvstride,
                            int rgbstride,
                            YUVType yuv_type) {
-  unsigned int y_shift = yuv_type;
+  unsigned int y_shift = GetVerticalShift(yuv_type);
   for (int y = 0; y < height; ++y) {
     uint8* rgb_row = rgbframe + y * rgbstride;
     const uint8* y_ptr = yplane + y * ystride;
@@ -34,7 +35,8 @@
                              u_ptr,
                              v_ptr,
                              rgb_row,
-                             width);
+                             width,
+                             GetLookupTable(yuv_type));
   }
 
   EmptyRegisterState();
@@ -52,7 +54,7 @@
                            int astride,
                            int rgbstride,
                            YUVType yuv_type) {
-  unsigned int y_shift = yuv_type;
+  unsigned int y_shift = GetVerticalShift(yuv_type);
   for (int y = 0; y < height; ++y) {
     uint8* rgb_row = rgbframe + y * rgbstride;
     const uint8* y_ptr = yplane + y * ystride;
@@ -65,7 +67,8 @@
                              v_ptr,
                              a_ptr,
                              rgb_row,
-                             width);
+                             width,
+                             GetLookupTable(yuv_type));
   }
 
   EmptyRegisterState();
@@ -81,7 +84,7 @@
                            int uvstride,
                            int rgbstride,
                            YUVType yuv_type) {
-  unsigned int y_shift = yuv_type;
+  unsigned int y_shift = GetVerticalShift(yuv_type);
   for (int y = 0; y < height; ++y) {
     uint8* rgb_row = rgbframe + y * rgbstride;
     const uint8* y_ptr = yplane + y * ystride;
@@ -92,7 +95,8 @@
                              u_ptr,
                              v_ptr,
                              rgb_row,
-                             width);
+                             width,
+                             GetLookupTable(yuv_type));
   }
 
   EmptyRegisterState();
diff --git a/media/base/simd/convert_yuva_to_argb_mmx.asm b/media/base/simd/convert_yuva_to_argb_mmx.asm
index b39315d..395f326 100644
--- a/media/base/simd/convert_yuva_to_argb_mmx.asm
+++ b/media/base/simd/convert_yuva_to_argb_mmx.asm
@@ -19,5 +19,6 @@
 ;                                          const uint8* a_buf,
 ;                                          uint8* rgb_buf,
 ;                                          ptrdiff_t width);
+;                                          const int16 convert_table[1024][4]);
 %define SYMBOL ConvertYUVAToARGBRow_MMX
 %include "convert_yuva_to_argb_mmx.inc"
diff --git a/media/base/simd/convert_yuva_to_argb_mmx.inc b/media/base/simd/convert_yuva_to_argb_mmx.inc
index 2e9e62d..5faa6a5 100644
--- a/media/base/simd/convert_yuva_to_argb_mmx.inc
+++ b/media/base/simd/convert_yuva_to_argb_mmx.inc
@@ -9,11 +9,9 @@
 
 mangle(SYMBOL):
   %assign   stack_offset 0
-  PROLOGUE  6, 7, 3, Y, U, V, A, ARGB, WIDTH, TEMP
-  extern    mangle(kCoefficientsRgbY)
+  PROLOGUE  7, 7, 3, Y, U, V, A, ARGB, WIDTH, TABLE, TEMP
   PUSH      WIDTHq
   DEFINE_ARGS Y, U, V, A, ARGB, TABLE, TEMP
-  LOAD_SYM  TABLEq, mangle(kCoefficientsRgbY)
   jmp       .convertend
 
 .convertloop:
diff --git a/media/base/simd/linear_scale_yuv_to_rgb_mmx.asm b/media/base/simd/linear_scale_yuv_to_rgb_mmx.asm
index 4041834..bf2f708 100644
--- a/media/base/simd/linear_scale_yuv_to_rgb_mmx.asm
+++ b/media/base/simd/linear_scale_yuv_to_rgb_mmx.asm
@@ -19,5 +19,6 @@
 ;                                   uint8* rgb_buf,
 ;                                   ptrdiff_t width,
 ;                                   ptrdiff_t source_dx);
+;                                   const int16 convert_table[1024][4]);
 %define SYMBOL LinearScaleYUVToRGB32Row_MMX
 %include "linear_scale_yuv_to_rgb_mmx.inc"
diff --git a/media/base/simd/linear_scale_yuv_to_rgb_mmx.inc b/media/base/simd/linear_scale_yuv_to_rgb_mmx.inc
index dce591d..48f62ac 100644
--- a/media/base/simd/linear_scale_yuv_to_rgb_mmx.inc
+++ b/media/base/simd/linear_scale_yuv_to_rgb_mmx.inc
@@ -10,8 +10,6 @@
 mangle(SYMBOL):
   %assign   stack_offset 0
 
-  extern    mangle(kCoefficientsRgbY)
-
 ; Parameters are in the following order:
 ; 1. Y plane
 ; 2. U plane
@@ -19,8 +17,9 @@
 ; 4. ARGB frame
 ; 5. Width
 ; 6. Source dx
+; 7. Conversion lookup table
 
-PROLOGUE  6, 7, 3, Y, R0, R1, ARGB, R2, R3, TEMP
+PROLOGUE  7, 7, 3, Y, R0, R1, ARGB, R2, TEMP, R3
 
 %if gprsize == 8
 %define     WORD_SIZE   QWORD
@@ -34,7 +33,7 @@
 %define     COMPLd              R2d     ; Component A value
 %define     U_ARG_REGq          R0q     ; U plane address argument
 %define     V_ARG_REGq          R1q     ; V plane address argument
-%define     SOURCE_DX_ARG_REGq  R3q     ; Source dx argument
+%define     SOURCE_DX_ARG_REGq  TEMPq   ; Source dx argument
 %define     WIDTH_ARG_REGq      R2q     ; Width argument
 
 %define     COMPRq              R0q     ; Component B value
@@ -56,11 +55,6 @@
   imul      WIDTH_ARG_REGq, SOURCE_DX_ARG_REGq  ; source_width = width * source_dx
   PUSH      WIDTH_ARG_REGq
 
-; Load the address of kCoefficientsRgbY into TABLE
-  mov       TEMPq, SOURCE_DX_ARG_REGq    ; Need to save source_dx first
-  LOAD_SYM  TABLE, mangle(kCoefficientsRgbY)
-%define     SOURCE_DX_ARG_REGq  TEMPq   ; Overwrite SOURCE_DX_ARG_REGq to TEMPq
-
 %macro EPILOGUE 0
   ADD       rsp, 4 * gprsize
 %endmacro
diff --git a/media/base/simd/linear_scale_yuv_to_rgb_mmx_x64.asm b/media/base/simd/linear_scale_yuv_to_rgb_mmx_x64.asm
index f7e1d90..89e4e2a 100644
--- a/media/base/simd/linear_scale_yuv_to_rgb_mmx_x64.asm
+++ b/media/base/simd/linear_scale_yuv_to_rgb_mmx_x64.asm
@@ -32,8 +32,9 @@
 ; 4. ARGB frame
 ; 5. Width
 ; 6. Source dx
+; 7. Conversion lookup table
 
-PROLOGUE  6, 7, 3, Y, U, V, ARGB, WIDTH, SOURCE_DX, COMPL
+PROLOGUE  7, 7, 3, Y, U, V, ARGB, WIDTH, SOURCE_DX, R1
 
 %define     TABLEq     r10
 %define     Xq         r11
@@ -41,6 +42,9 @@
 %define     COMPRd     r13d
 %define     COMPRq     r13
 %define     FRACTIONq  r14
+%define     COMPL      R1
+%define     COMPLq     R1q
+%define     COMPLd     R1d
 
   PUSH      TABLEq
   PUSH      Xq
@@ -56,7 +60,7 @@
   POP       TABLEq
 %endmacro
 
-  LOAD_SYM  TABLEq, mangle(kCoefficientsRgbY)
+  mov       TABLEq, R1q
 
   imul      WIDTHq, SOURCE_DXq           ; source_width = width * source_dx
   xor       Xq, Xq                       ; x = 0
diff --git a/media/base/simd/scale_yuv_to_rgb_mmx.asm b/media/base/simd/scale_yuv_to_rgb_mmx.asm
index 583b7cb..1223651 100644
--- a/media/base/simd/scale_yuv_to_rgb_mmx.asm
+++ b/media/base/simd/scale_yuv_to_rgb_mmx.asm
@@ -19,5 +19,6 @@
 ;                             uint8* rgb_buf,
 ;                             ptrdiff_t width,
 ;                             ptrdiff_t source_dx);
+;                             const int16 convert_table[1024][4]);
 %define SYMBOL ScaleYUVToRGB32Row_MMX
 %include "scale_yuv_to_rgb_mmx.inc"
diff --git a/media/base/simd/scale_yuv_to_rgb_mmx.inc b/media/base/simd/scale_yuv_to_rgb_mmx.inc
index a599b0c..60351db 100644
--- a/media/base/simd/scale_yuv_to_rgb_mmx.inc
+++ b/media/base/simd/scale_yuv_to_rgb_mmx.inc
@@ -19,8 +19,9 @@
 ; 4. ARGB frame
 ; 5. Width
 ; 6. Source dx
+; 7. Lookup table address
 
-PROLOGUE  6, 7, 3, Y, U, V, ARGB, R1, R2, TEMP
+PROLOGUE  7, 7, 3, Y, U, V, ARGB, R1, R2, TEMP
 
 %ifdef ARCH_X86_64
 %define     WORD_SIZE   QWORD
@@ -33,10 +34,11 @@
 
 %define     SOURCE_DX   WORD_SIZE [rsp]
 
-  LOAD_SYM  R1q, mangle(kCoefficientsRgbY)
+  mov       R1q, TEMPq
+
 %define     WIDTH       WORD_SIZE [rsp + gprsize]
 %define     TABLE       R1q
-%define     Xq           R2q
+%define     Xq          R2q
 
   ; Set Xq index to 0.
   xor       Xq, Xq
diff --git a/media/base/simd/scale_yuv_to_rgb_sse.asm b/media/base/simd/scale_yuv_to_rgb_sse.asm
index 536ed18..fc98bbe 100644
--- a/media/base/simd/scale_yuv_to_rgb_sse.asm
+++ b/media/base/simd/scale_yuv_to_rgb_sse.asm
@@ -19,5 +19,6 @@
 ;                             uint8* rgb_buf,
 ;                             ptrdiff_t width,
 ;                             ptrdiff_t source_dx);
+;                             const int16 convert_table[1024][4]);
 %define SYMBOL ScaleYUVToRGB32Row_SSE
 %include "scale_yuv_to_rgb_mmx.inc"
diff --git a/media/base/simd/scale_yuv_to_rgb_sse2_x64.asm b/media/base/simd/scale_yuv_to_rgb_sse2_x64.asm
index d678687..cf0d140 100644
--- a/media/base/simd/scale_yuv_to_rgb_sse2_x64.asm
+++ b/media/base/simd/scale_yuv_to_rgb_sse2_x64.asm
@@ -32,17 +32,21 @@
 ; 4. ARGB frame
 ; 5. Width
 ; 6. Source dx
+; 7. Convert table
 
-PROLOGUE  6, 7, 3, Y, U, V, ARGB, WIDTH, SOURCE_DX, COMP
+PROLOGUE  7, 7, 3, Y, U, V, ARGB, WIDTH, SOURCE_DX, R1
 
 %define     TABLEq   r10
 %define     Xq       r11
 %define     INDEXq   r12
+%define     COMPq    R1q
+%define     COMPd    R1d
+
   PUSH      r10
   PUSH      r11
   PUSH      r12
 
-  LOAD_SYM  TABLEq, mangle(kCoefficientsRgbY)
+  mov TABLEq, R1q
 
   ; Set Xq index to 0.
   xor       Xq, Xq
diff --git a/media/base/simd/yuv_to_rgb_table.cc b/media/base/simd/yuv_to_rgb_table.cc
index 253280d..5bc35af 100644
--- a/media/base/simd/yuv_to_rgb_table.cc
+++ b/media/base/simd/yuv_to_rgb_table.cc
@@ -335,4 +335,335 @@
 #undef RGBV
 #undef ALPHA
 
+// JPEG color range version:
+
+// Defines the R,G,B,A contributions from Y.
+#define RGBY(i) { \
+  static_cast<int16>(64 * i + 0.5), \
+  static_cast<int16>(64 * i + 0.5), \
+  static_cast<int16>(64 * i + 0.5), \
+  0 \
+}
+
+// Defines the R,G,B,A contributions from U.
+// The contribution to A is the same for any value of U
+// causing the final A value to be 255 in every conversion.
+// Android's pixel layout is RGBA, while other platforms
+// are BGRA.
+#if defined(OS_ANDROID)
+#define RGBU(i) { \
+  0, \
+  static_cast<int16>(-0.34414 * 64 * (i - 128) + 0.5), \
+  static_cast<int16>(1.772 * 64 * (i - 128) + 0.5), \
+  static_cast<int16>(256 * 64 - 1) \
+}
+#else
+#define RGBU(i) { \
+  static_cast<int16>(1.772 * 64 * (i - 128) + 0.5), \
+  static_cast<int16>(-0.34414 * 64 * (i - 128) + 0.5), \
+  0, \
+  static_cast<int16>(256 * 64 - 1) \
+}
+#endif
+
+// Defines the R,G,B,A contributions from V.
+// Android's pixel layout is RGBA, while other platforms
+// are BGRA.
+#if defined(OS_ANDROID)
+#define RGBV(i) { \
+  static_cast<int16>(1.402 * 64 * (i - 128) + 0.5), \
+  static_cast<int16>(-0.71414 * 64 * (i - 128) + 0.5), \
+  0, \
+  0 \
+}
+#else
+#define RGBV(i) { \
+  0, \
+  static_cast<int16>(-0.813 * 64 * (i - 128) + 0.5), \
+  static_cast<int16>(1.402 * 64 * (i - 128) + 0.5), \
+  0 \
+}
+#endif
+
+// Used to define a set of multiplier words for each alpha level.
+#define ALPHA(i) { \
+  i, i, i, i \
+}
+
+// The following table defines the RGBA contributions
+// for each component of YUVA. The Y table is first followed
+// by the U, and V tables. The alpha multiplier table follows.
+// These tables are aligned and kept adjacent to optimize for
+// SIMD and caching.
+
+SIMD_ALIGNED(const int16 kCoefficientsRgbY_JPEG[256 * 4][4]) = {
+  RGBY(0x00), RGBY(0x01), RGBY(0x02), RGBY(0x03),
+  RGBY(0x04), RGBY(0x05), RGBY(0x06), RGBY(0x07),
+  RGBY(0x08), RGBY(0x09), RGBY(0x0A), RGBY(0x0B),
+  RGBY(0x0C), RGBY(0x0D), RGBY(0x0E), RGBY(0x0F),
+  RGBY(0x10), RGBY(0x11), RGBY(0x12), RGBY(0x13),
+  RGBY(0x14), RGBY(0x15), RGBY(0x16), RGBY(0x17),
+  RGBY(0x18), RGBY(0x19), RGBY(0x1A), RGBY(0x1B),
+  RGBY(0x1C), RGBY(0x1D), RGBY(0x1E), RGBY(0x1F),
+  RGBY(0x20), RGBY(0x21), RGBY(0x22), RGBY(0x23),
+  RGBY(0x24), RGBY(0x25), RGBY(0x26), RGBY(0x27),
+  RGBY(0x28), RGBY(0x29), RGBY(0x2A), RGBY(0x2B),
+  RGBY(0x2C), RGBY(0x2D), RGBY(0x2E), RGBY(0x2F),
+  RGBY(0x30), RGBY(0x31), RGBY(0x32), RGBY(0x33),
+  RGBY(0x34), RGBY(0x35), RGBY(0x36), RGBY(0x37),
+  RGBY(0x38), RGBY(0x39), RGBY(0x3A), RGBY(0x3B),
+  RGBY(0x3C), RGBY(0x3D), RGBY(0x3E), RGBY(0x3F),
+  RGBY(0x40), RGBY(0x41), RGBY(0x42), RGBY(0x43),
+  RGBY(0x44), RGBY(0x45), RGBY(0x46), RGBY(0x47),
+  RGBY(0x48), RGBY(0x49), RGBY(0x4A), RGBY(0x4B),
+  RGBY(0x4C), RGBY(0x4D), RGBY(0x4E), RGBY(0x4F),
+  RGBY(0x50), RGBY(0x51), RGBY(0x52), RGBY(0x53),
+  RGBY(0x54), RGBY(0x55), RGBY(0x56), RGBY(0x57),
+  RGBY(0x58), RGBY(0x59), RGBY(0x5A), RGBY(0x5B),
+  RGBY(0x5C), RGBY(0x5D), RGBY(0x5E), RGBY(0x5F),
+  RGBY(0x60), RGBY(0x61), RGBY(0x62), RGBY(0x63),
+  RGBY(0x64), RGBY(0x65), RGBY(0x66), RGBY(0x67),
+  RGBY(0x68), RGBY(0x69), RGBY(0x6A), RGBY(0x6B),
+  RGBY(0x6C), RGBY(0x6D), RGBY(0x6E), RGBY(0x6F),
+  RGBY(0x70), RGBY(0x71), RGBY(0x72), RGBY(0x73),
+  RGBY(0x74), RGBY(0x75), RGBY(0x76), RGBY(0x77),
+  RGBY(0x78), RGBY(0x79), RGBY(0x7A), RGBY(0x7B),
+  RGBY(0x7C), RGBY(0x7D), RGBY(0x7E), RGBY(0x7F),
+  RGBY(0x80), RGBY(0x81), RGBY(0x82), RGBY(0x83),
+  RGBY(0x84), RGBY(0x85), RGBY(0x86), RGBY(0x87),
+  RGBY(0x88), RGBY(0x89), RGBY(0x8A), RGBY(0x8B),
+  RGBY(0x8C), RGBY(0x8D), RGBY(0x8E), RGBY(0x8F),
+  RGBY(0x90), RGBY(0x91), RGBY(0x92), RGBY(0x93),
+  RGBY(0x94), RGBY(0x95), RGBY(0x96), RGBY(0x97),
+  RGBY(0x98), RGBY(0x99), RGBY(0x9A), RGBY(0x9B),
+  RGBY(0x9C), RGBY(0x9D), RGBY(0x9E), RGBY(0x9F),
+  RGBY(0xA0), RGBY(0xA1), RGBY(0xA2), RGBY(0xA3),
+  RGBY(0xA4), RGBY(0xA5), RGBY(0xA6), RGBY(0xA7),
+  RGBY(0xA8), RGBY(0xA9), RGBY(0xAA), RGBY(0xAB),
+  RGBY(0xAC), RGBY(0xAD), RGBY(0xAE), RGBY(0xAF),
+  RGBY(0xB0), RGBY(0xB1), RGBY(0xB2), RGBY(0xB3),
+  RGBY(0xB4), RGBY(0xB5), RGBY(0xB6), RGBY(0xB7),
+  RGBY(0xB8), RGBY(0xB9), RGBY(0xBA), RGBY(0xBB),
+  RGBY(0xBC), RGBY(0xBD), RGBY(0xBE), RGBY(0xBF),
+  RGBY(0xC0), RGBY(0xC1), RGBY(0xC2), RGBY(0xC3),
+  RGBY(0xC4), RGBY(0xC5), RGBY(0xC6), RGBY(0xC7),
+  RGBY(0xC8), RGBY(0xC9), RGBY(0xCA), RGBY(0xCB),
+  RGBY(0xCC), RGBY(0xCD), RGBY(0xCE), RGBY(0xCF),
+  RGBY(0xD0), RGBY(0xD1), RGBY(0xD2), RGBY(0xD3),
+  RGBY(0xD4), RGBY(0xD5), RGBY(0xD6), RGBY(0xD7),
+  RGBY(0xD8), RGBY(0xD9), RGBY(0xDA), RGBY(0xDB),
+  RGBY(0xDC), RGBY(0xDD), RGBY(0xDE), RGBY(0xDF),
+  RGBY(0xE0), RGBY(0xE1), RGBY(0xE2), RGBY(0xE3),
+  RGBY(0xE4), RGBY(0xE5), RGBY(0xE6), RGBY(0xE7),
+  RGBY(0xE8), RGBY(0xE9), RGBY(0xEA), RGBY(0xEB),
+  RGBY(0xEC), RGBY(0xED), RGBY(0xEE), RGBY(0xEF),
+  RGBY(0xF0), RGBY(0xF1), RGBY(0xF2), RGBY(0xF3),
+  RGBY(0xF4), RGBY(0xF5), RGBY(0xF6), RGBY(0xF7),
+  RGBY(0xF8), RGBY(0xF9), RGBY(0xFA), RGBY(0xFB),
+  RGBY(0xFC), RGBY(0xFD), RGBY(0xFE), RGBY(0xFF),
+
+  // Chroma U table.
+  RGBU(0x00), RGBU(0x01), RGBU(0x02), RGBU(0x03),
+  RGBU(0x04), RGBU(0x05), RGBU(0x06), RGBU(0x07),
+  RGBU(0x08), RGBU(0x09), RGBU(0x0A), RGBU(0x0B),
+  RGBU(0x0C), RGBU(0x0D), RGBU(0x0E), RGBU(0x0F),
+  RGBU(0x10), RGBU(0x11), RGBU(0x12), RGBU(0x13),
+  RGBU(0x14), RGBU(0x15), RGBU(0x16), RGBU(0x17),
+  RGBU(0x18), RGBU(0x19), RGBU(0x1A), RGBU(0x1B),
+  RGBU(0x1C), RGBU(0x1D), RGBU(0x1E), RGBU(0x1F),
+  RGBU(0x20), RGBU(0x21), RGBU(0x22), RGBU(0x23),
+  RGBU(0x24), RGBU(0x25), RGBU(0x26), RGBU(0x27),
+  RGBU(0x28), RGBU(0x29), RGBU(0x2A), RGBU(0x2B),
+  RGBU(0x2C), RGBU(0x2D), RGBU(0x2E), RGBU(0x2F),
+  RGBU(0x30), RGBU(0x31), RGBU(0x32), RGBU(0x33),
+  RGBU(0x34), RGBU(0x35), RGBU(0x36), RGBU(0x37),
+  RGBU(0x38), RGBU(0x39), RGBU(0x3A), RGBU(0x3B),
+  RGBU(0x3C), RGBU(0x3D), RGBU(0x3E), RGBU(0x3F),
+  RGBU(0x40), RGBU(0x41), RGBU(0x42), RGBU(0x43),
+  RGBU(0x44), RGBU(0x45), RGBU(0x46), RGBU(0x47),
+  RGBU(0x48), RGBU(0x49), RGBU(0x4A), RGBU(0x4B),
+  RGBU(0x4C), RGBU(0x4D), RGBU(0x4E), RGBU(0x4F),
+  RGBU(0x50), RGBU(0x51), RGBU(0x52), RGBU(0x53),
+  RGBU(0x54), RGBU(0x55), RGBU(0x56), RGBU(0x57),
+  RGBU(0x58), RGBU(0x59), RGBU(0x5A), RGBU(0x5B),
+  RGBU(0x5C), RGBU(0x5D), RGBU(0x5E), RGBU(0x5F),
+  RGBU(0x60), RGBU(0x61), RGBU(0x62), RGBU(0x63),
+  RGBU(0x64), RGBU(0x65), RGBU(0x66), RGBU(0x67),
+  RGBU(0x68), RGBU(0x69), RGBU(0x6A), RGBU(0x6B),
+  RGBU(0x6C), RGBU(0x6D), RGBU(0x6E), RGBU(0x6F),
+  RGBU(0x70), RGBU(0x71), RGBU(0x72), RGBU(0x73),
+  RGBU(0x74), RGBU(0x75), RGBU(0x76), RGBU(0x77),
+  RGBU(0x78), RGBU(0x79), RGBU(0x7A), RGBU(0x7B),
+  RGBU(0x7C), RGBU(0x7D), RGBU(0x7E), RGBU(0x7F),
+  RGBU(0x80), RGBU(0x81), RGBU(0x82), RGBU(0x83),
+  RGBU(0x84), RGBU(0x85), RGBU(0x86), RGBU(0x87),
+  RGBU(0x88), RGBU(0x89), RGBU(0x8A), RGBU(0x8B),
+  RGBU(0x8C), RGBU(0x8D), RGBU(0x8E), RGBU(0x8F),
+  RGBU(0x90), RGBU(0x91), RGBU(0x92), RGBU(0x93),
+  RGBU(0x94), RGBU(0x95), RGBU(0x96), RGBU(0x97),
+  RGBU(0x98), RGBU(0x99), RGBU(0x9A), RGBU(0x9B),
+  RGBU(0x9C), RGBU(0x9D), RGBU(0x9E), RGBU(0x9F),
+  RGBU(0xA0), RGBU(0xA1), RGBU(0xA2), RGBU(0xA3),
+  RGBU(0xA4), RGBU(0xA5), RGBU(0xA6), RGBU(0xA7),
+  RGBU(0xA8), RGBU(0xA9), RGBU(0xAA), RGBU(0xAB),
+  RGBU(0xAC), RGBU(0xAD), RGBU(0xAE), RGBU(0xAF),
+  RGBU(0xB0), RGBU(0xB1), RGBU(0xB2), RGBU(0xB3),
+  RGBU(0xB4), RGBU(0xB5), RGBU(0xB6), RGBU(0xB7),
+  RGBU(0xB8), RGBU(0xB9), RGBU(0xBA), RGBU(0xBB),
+  RGBU(0xBC), RGBU(0xBD), RGBU(0xBE), RGBU(0xBF),
+  RGBU(0xC0), RGBU(0xC1), RGBU(0xC2), RGBU(0xC3),
+  RGBU(0xC4), RGBU(0xC5), RGBU(0xC6), RGBU(0xC7),
+  RGBU(0xC8), RGBU(0xC9), RGBU(0xCA), RGBU(0xCB),
+  RGBU(0xCC), RGBU(0xCD), RGBU(0xCE), RGBU(0xCF),
+  RGBU(0xD0), RGBU(0xD1), RGBU(0xD2), RGBU(0xD3),
+  RGBU(0xD4), RGBU(0xD5), RGBU(0xD6), RGBU(0xD7),
+  RGBU(0xD8), RGBU(0xD9), RGBU(0xDA), RGBU(0xDB),
+  RGBU(0xDC), RGBU(0xDD), RGBU(0xDE), RGBU(0xDF),
+  RGBU(0xE0), RGBU(0xE1), RGBU(0xE2), RGBU(0xE3),
+  RGBU(0xE4), RGBU(0xE5), RGBU(0xE6), RGBU(0xE7),
+  RGBU(0xE8), RGBU(0xE9), RGBU(0xEA), RGBU(0xEB),
+  RGBU(0xEC), RGBU(0xED), RGBU(0xEE), RGBU(0xEF),
+  RGBU(0xF0), RGBU(0xF1), RGBU(0xF2), RGBU(0xF3),
+  RGBU(0xF4), RGBU(0xF5), RGBU(0xF6), RGBU(0xF7),
+  RGBU(0xF8), RGBU(0xF9), RGBU(0xFA), RGBU(0xFB),
+  RGBU(0xFC), RGBU(0xFD), RGBU(0xFE), RGBU(0xFF),
+
+  // Chroma V table.
+  RGBV(0x00), RGBV(0x01), RGBV(0x02), RGBV(0x03),
+  RGBV(0x04), RGBV(0x05), RGBV(0x06), RGBV(0x07),
+  RGBV(0x08), RGBV(0x09), RGBV(0x0A), RGBV(0x0B),
+  RGBV(0x0C), RGBV(0x0D), RGBV(0x0E), RGBV(0x0F),
+  RGBV(0x10), RGBV(0x11), RGBV(0x12), RGBV(0x13),
+  RGBV(0x14), RGBV(0x15), RGBV(0x16), RGBV(0x17),
+  RGBV(0x18), RGBV(0x19), RGBV(0x1A), RGBV(0x1B),
+  RGBV(0x1C), RGBV(0x1D), RGBV(0x1E), RGBV(0x1F),
+  RGBV(0x20), RGBV(0x21), RGBV(0x22), RGBV(0x23),
+  RGBV(0x24), RGBV(0x25), RGBV(0x26), RGBV(0x27),
+  RGBV(0x28), RGBV(0x29), RGBV(0x2A), RGBV(0x2B),
+  RGBV(0x2C), RGBV(0x2D), RGBV(0x2E), RGBV(0x2F),
+  RGBV(0x30), RGBV(0x31), RGBV(0x32), RGBV(0x33),
+  RGBV(0x34), RGBV(0x35), RGBV(0x36), RGBV(0x37),
+  RGBV(0x38), RGBV(0x39), RGBV(0x3A), RGBV(0x3B),
+  RGBV(0x3C), RGBV(0x3D), RGBV(0x3E), RGBV(0x3F),
+  RGBV(0x40), RGBV(0x41), RGBV(0x42), RGBV(0x43),
+  RGBV(0x44), RGBV(0x45), RGBV(0x46), RGBV(0x47),
+  RGBV(0x48), RGBV(0x49), RGBV(0x4A), RGBV(0x4B),
+  RGBV(0x4C), RGBV(0x4D), RGBV(0x4E), RGBV(0x4F),
+  RGBV(0x50), RGBV(0x51), RGBV(0x52), RGBV(0x53),
+  RGBV(0x54), RGBV(0x55), RGBV(0x56), RGBV(0x57),
+  RGBV(0x58), RGBV(0x59), RGBV(0x5A), RGBV(0x5B),
+  RGBV(0x5C), RGBV(0x5D), RGBV(0x5E), RGBV(0x5F),
+  RGBV(0x60), RGBV(0x61), RGBV(0x62), RGBV(0x63),
+  RGBV(0x64), RGBV(0x65), RGBV(0x66), RGBV(0x67),
+  RGBV(0x68), RGBV(0x69), RGBV(0x6A), RGBV(0x6B),
+  RGBV(0x6C), RGBV(0x6D), RGBV(0x6E), RGBV(0x6F),
+  RGBV(0x70), RGBV(0x71), RGBV(0x72), RGBV(0x73),
+  RGBV(0x74), RGBV(0x75), RGBV(0x76), RGBV(0x77),
+  RGBV(0x78), RGBV(0x79), RGBV(0x7A), RGBV(0x7B),
+  RGBV(0x7C), RGBV(0x7D), RGBV(0x7E), RGBV(0x7F),
+  RGBV(0x80), RGBV(0x81), RGBV(0x82), RGBV(0x83),
+  RGBV(0x84), RGBV(0x85), RGBV(0x86), RGBV(0x87),
+  RGBV(0x88), RGBV(0x89), RGBV(0x8A), RGBV(0x8B),
+  RGBV(0x8C), RGBV(0x8D), RGBV(0x8E), RGBV(0x8F),
+  RGBV(0x90), RGBV(0x91), RGBV(0x92), RGBV(0x93),
+  RGBV(0x94), RGBV(0x95), RGBV(0x96), RGBV(0x97),
+  RGBV(0x98), RGBV(0x99), RGBV(0x9A), RGBV(0x9B),
+  RGBV(0x9C), RGBV(0x9D), RGBV(0x9E), RGBV(0x9F),
+  RGBV(0xA0), RGBV(0xA1), RGBV(0xA2), RGBV(0xA3),
+  RGBV(0xA4), RGBV(0xA5), RGBV(0xA6), RGBV(0xA7),
+  RGBV(0xA8), RGBV(0xA9), RGBV(0xAA), RGBV(0xAB),
+  RGBV(0xAC), RGBV(0xAD), RGBV(0xAE), RGBV(0xAF),
+  RGBV(0xB0), RGBV(0xB1), RGBV(0xB2), RGBV(0xB3),
+  RGBV(0xB4), RGBV(0xB5), RGBV(0xB6), RGBV(0xB7),
+  RGBV(0xB8), RGBV(0xB9), RGBV(0xBA), RGBV(0xBB),
+  RGBV(0xBC), RGBV(0xBD), RGBV(0xBE), RGBV(0xBF),
+  RGBV(0xC0), RGBV(0xC1), RGBV(0xC2), RGBV(0xC3),
+  RGBV(0xC4), RGBV(0xC5), RGBV(0xC6), RGBV(0xC7),
+  RGBV(0xC8), RGBV(0xC9), RGBV(0xCA), RGBV(0xCB),
+  RGBV(0xCC), RGBV(0xCD), RGBV(0xCE), RGBV(0xCF),
+  RGBV(0xD0), RGBV(0xD1), RGBV(0xD2), RGBV(0xD3),
+  RGBV(0xD4), RGBV(0xD5), RGBV(0xD6), RGBV(0xD7),
+  RGBV(0xD8), RGBV(0xD9), RGBV(0xDA), RGBV(0xDB),
+  RGBV(0xDC), RGBV(0xDD), RGBV(0xDE), RGBV(0xDF),
+  RGBV(0xE0), RGBV(0xE1), RGBV(0xE2), RGBV(0xE3),
+  RGBV(0xE4), RGBV(0xE5), RGBV(0xE6), RGBV(0xE7),
+  RGBV(0xE8), RGBV(0xE9), RGBV(0xEA), RGBV(0xEB),
+  RGBV(0xEC), RGBV(0xED), RGBV(0xEE), RGBV(0xEF),
+  RGBV(0xF0), RGBV(0xF1), RGBV(0xF2), RGBV(0xF3),
+  RGBV(0xF4), RGBV(0xF5), RGBV(0xF6), RGBV(0xF7),
+  RGBV(0xF8), RGBV(0xF9), RGBV(0xFA), RGBV(0xFB),
+  RGBV(0xFC), RGBV(0xFD), RGBV(0xFE), RGBV(0xFF),
+
+  // Alpha multipliers for each  alpha level.
+  ALPHA(0x00), ALPHA(0x01), ALPHA(0x02), ALPHA(0x03),
+  ALPHA(0x04), ALPHA(0x05), ALPHA(0x06), ALPHA(0x07),
+  ALPHA(0x08), ALPHA(0x09), ALPHA(0x0A), ALPHA(0x0B),
+  ALPHA(0x0C), ALPHA(0x0D), ALPHA(0x0E), ALPHA(0x0F),
+  ALPHA(0x10), ALPHA(0x11), ALPHA(0x12), ALPHA(0x13),
+  ALPHA(0x14), ALPHA(0x15), ALPHA(0x16), ALPHA(0x17),
+  ALPHA(0x18), ALPHA(0x19), ALPHA(0x1A), ALPHA(0x1B),
+  ALPHA(0x1C), ALPHA(0x1D), ALPHA(0x1E), ALPHA(0x1F),
+  ALPHA(0x20), ALPHA(0x21), ALPHA(0x22), ALPHA(0x23),
+  ALPHA(0x24), ALPHA(0x25), ALPHA(0x26), ALPHA(0x27),
+  ALPHA(0x28), ALPHA(0x29), ALPHA(0x2A), ALPHA(0x2B),
+  ALPHA(0x2C), ALPHA(0x2D), ALPHA(0x2E), ALPHA(0x2F),
+  ALPHA(0x30), ALPHA(0x31), ALPHA(0x32), ALPHA(0x33),
+  ALPHA(0x34), ALPHA(0x35), ALPHA(0x36), ALPHA(0x37),
+  ALPHA(0x38), ALPHA(0x39), ALPHA(0x3A), ALPHA(0x3B),
+  ALPHA(0x3C), ALPHA(0x3D), ALPHA(0x3E), ALPHA(0x3F),
+  ALPHA(0x40), ALPHA(0x41), ALPHA(0x42), ALPHA(0x43),
+  ALPHA(0x44), ALPHA(0x45), ALPHA(0x46), ALPHA(0x47),
+  ALPHA(0x48), ALPHA(0x49), ALPHA(0x4A), ALPHA(0x4B),
+  ALPHA(0x4C), ALPHA(0x4D), ALPHA(0x4E), ALPHA(0x4F),
+  ALPHA(0x50), ALPHA(0x51), ALPHA(0x52), ALPHA(0x53),
+  ALPHA(0x54), ALPHA(0x55), ALPHA(0x56), ALPHA(0x57),
+  ALPHA(0x58), ALPHA(0x59), ALPHA(0x5A), ALPHA(0x5B),
+  ALPHA(0x5C), ALPHA(0x5D), ALPHA(0x5E), ALPHA(0x5F),
+  ALPHA(0x60), ALPHA(0x61), ALPHA(0x62), ALPHA(0x63),
+  ALPHA(0x64), ALPHA(0x65), ALPHA(0x66), ALPHA(0x67),
+  ALPHA(0x68), ALPHA(0x69), ALPHA(0x6A), ALPHA(0x6B),
+  ALPHA(0x6C), ALPHA(0x6D), ALPHA(0x6E), ALPHA(0x6F),
+  ALPHA(0x70), ALPHA(0x71), ALPHA(0x72), ALPHA(0x73),
+  ALPHA(0x74), ALPHA(0x75), ALPHA(0x76), ALPHA(0x77),
+  ALPHA(0x78), ALPHA(0x79), ALPHA(0x7A), ALPHA(0x7B),
+  ALPHA(0x7C), ALPHA(0x7D), ALPHA(0x7E), ALPHA(0x7F),
+  ALPHA(0x80), ALPHA(0x81), ALPHA(0x82), ALPHA(0x83),
+  ALPHA(0x84), ALPHA(0x85), ALPHA(0x86), ALPHA(0x87),
+  ALPHA(0x88), ALPHA(0x89), ALPHA(0x8A), ALPHA(0x8B),
+  ALPHA(0x8C), ALPHA(0x8D), ALPHA(0x8E), ALPHA(0x8F),
+  ALPHA(0x90), ALPHA(0x91), ALPHA(0x92), ALPHA(0x93),
+  ALPHA(0x94), ALPHA(0x95), ALPHA(0x96), ALPHA(0x97),
+  ALPHA(0x98), ALPHA(0x99), ALPHA(0x9A), ALPHA(0x9B),
+  ALPHA(0x9C), ALPHA(0x9D), ALPHA(0x9E), ALPHA(0x9F),
+  ALPHA(0xA0), ALPHA(0xA1), ALPHA(0xA2), ALPHA(0xA3),
+  ALPHA(0xA4), ALPHA(0xA5), ALPHA(0xA6), ALPHA(0xA7),
+  ALPHA(0xA8), ALPHA(0xA9), ALPHA(0xAA), ALPHA(0xAB),
+  ALPHA(0xAC), ALPHA(0xAD), ALPHA(0xAE), ALPHA(0xAF),
+  ALPHA(0xB0), ALPHA(0xB1), ALPHA(0xB2), ALPHA(0xB3),
+  ALPHA(0xB4), ALPHA(0xB5), ALPHA(0xB6), ALPHA(0xB7),
+  ALPHA(0xB8), ALPHA(0xB9), ALPHA(0xBA), ALPHA(0xBB),
+  ALPHA(0xBC), ALPHA(0xBD), ALPHA(0xBE), ALPHA(0xBF),
+  ALPHA(0xC0), ALPHA(0xC1), ALPHA(0xC2), ALPHA(0xC3),
+  ALPHA(0xC4), ALPHA(0xC5), ALPHA(0xC6), ALPHA(0xC7),
+  ALPHA(0xC8), ALPHA(0xC9), ALPHA(0xCA), ALPHA(0xCB),
+  ALPHA(0xCC), ALPHA(0xCD), ALPHA(0xCE), ALPHA(0xCF),
+  ALPHA(0xD0), ALPHA(0xD1), ALPHA(0xD2), ALPHA(0xD3),
+  ALPHA(0xD4), ALPHA(0xD5), ALPHA(0xD6), ALPHA(0xD7),
+  ALPHA(0xD8), ALPHA(0xD9), ALPHA(0xDA), ALPHA(0xDB),
+  ALPHA(0xDC), ALPHA(0xDD), ALPHA(0xDE), ALPHA(0xDF),
+  ALPHA(0xE0), ALPHA(0xE1), ALPHA(0xE2), ALPHA(0xE3),
+  ALPHA(0xE4), ALPHA(0xE5), ALPHA(0xE6), ALPHA(0xE7),
+  ALPHA(0xE8), ALPHA(0xE9), ALPHA(0xEA), ALPHA(0xEB),
+  ALPHA(0xEC), ALPHA(0xED), ALPHA(0xEE), ALPHA(0xEF),
+  ALPHA(0xF0), ALPHA(0xF1), ALPHA(0xF2), ALPHA(0xF3),
+  ALPHA(0xF4), ALPHA(0xF5), ALPHA(0xF6), ALPHA(0xF7),
+  ALPHA(0xF8), ALPHA(0xF9), ALPHA(0xFA), ALPHA(0xFB),
+  ALPHA(0xFC), ALPHA(0xFD), ALPHA(0xFE), ALPHA(0xFF),
+};
+
+#undef RGBY
+#undef RGBU
+#undef RGBV
+#undef ALPHA
+
 }  // extern "C"
diff --git a/media/base/simd/yuv_to_rgb_table.h b/media/base/simd/yuv_to_rgb_table.h
index aebf1b2..1ed6fd8 100644
--- a/media/base/simd/yuv_to_rgb_table.h
+++ b/media/base/simd/yuv_to_rgb_table.h
@@ -20,6 +20,7 @@
 
 // Align the table to 16-bytes to allow faster reading.
 extern SIMD_ALIGNED(const int16 kCoefficientsRgbY[256 * 4][4]);
+extern SIMD_ALIGNED(const int16 kCoefficientsRgbY_JPEG[256 * 4][4]);
 
 }  // extern "C"
 
diff --git a/media/base/test_helpers.cc b/media/base/test_helpers.cc
index 98d4971..929b2f3 100644
--- a/media/base/test_helpers.cc
+++ b/media/base/test_helpers.cc
@@ -151,29 +151,25 @@
 template <class T>
 scoped_refptr<AudioBuffer> MakeAudioBuffer(SampleFormat format,
                                            ChannelLayout channel_layout,
-                                           int channel_count,
+                                           size_t channel_count,
                                            int sample_rate,
                                            T start,
                                            T increment,
-                                           int frames,
-                                           base::TimeDelta timestamp,
-                                           base::TimeDelta duration) {
-  int channels = ChannelLayoutToChannelCount(channel_layout);
-  scoped_refptr<AudioBuffer> output = AudioBuffer::CreateBuffer(
-      format, channel_layout, channel_count, sample_rate, frames);
+                                           size_t frames,
+                                           base::TimeDelta timestamp) {
+  const size_t channels = ChannelLayoutToChannelCount(channel_layout);
+  scoped_refptr<AudioBuffer> output =
+      AudioBuffer::CreateBuffer(format,
+                                channel_layout,
+                                static_cast<int>(channel_count),
+                                sample_rate,
+                                static_cast<int>(frames));
   output->set_timestamp(timestamp);
-  output->set_duration(duration);
 
-  // Create a block of memory with values:
-  //   start
-  //   start + increment
-  //   start + 2 * increment, ...
-  // For interleaved data, raw data will be:
-  //   start
-  //   start + channels * increment
-  //   start + 2 * channels * increment, ...
-  //
-  // For planar data, values in channel 0 will be:
+  const bool is_planar =
+      format == kSampleFormatPlanarS16 || format == kSampleFormatPlanarF32;
+
+  // Values in channel 0 will be:
   //   start
   //   start + increment
   //   start + 2 * increment, ...
@@ -181,13 +177,13 @@
   //   start + frames * increment
   //   start + (frames + 1) * increment
   //   start + (frames + 2) * increment, ...
-  const size_t output_size =
-      output->channel_data().size() == 1 ? frames * channels : frames;
-  for (size_t ch = 0; ch < output->channel_data().size(); ++ch) {
-    T* buffer = reinterpret_cast<T*>(output->channel_data()[ch]);
-    const T v = static_cast<T>(start + ch * output_size * increment);
-    for (size_t i = 0; i < output_size; ++i) {
-      buffer[i] = static_cast<T>(v + i * increment);
+  for (size_t ch = 0; ch < channels; ++ch) {
+    T* buffer =
+        reinterpret_cast<T*>(output->channel_data()[is_planar ? ch : 0]);
+    const T v = static_cast<T>(start + ch * frames * increment);
+    for (size_t i = 0; i < frames; ++i) {
+      buffer[is_planar ? i : ch + i * channels] =
+          static_cast<T>(v + i * increment);
     }
   }
   return output;
@@ -199,13 +195,12 @@
   template scoped_refptr<AudioBuffer> MakeAudioBuffer<type>( \
       SampleFormat format,                                   \
       ChannelLayout channel_layout,                          \
-      int channel_count,                                     \
+      size_t channel_count,                                  \
       int sample_rate,                                       \
       type start,                                            \
       type increment,                                        \
-      int frames,                                            \
-      base::TimeDelta start_time,                            \
-      base::TimeDelta duration)
+      size_t frames,                                         \
+      base::TimeDelta start_time)
 DEFINE_MAKE_AUDIO_BUFFER_INSTANCE(uint8);
 DEFINE_MAKE_AUDIO_BUFFER_INSTANCE(int16);
 DEFINE_MAKE_AUDIO_BUFFER_INSTANCE(int32);
diff --git a/media/base/test_helpers.h b/media/base/test_helpers.h
index f342af4..8dc3895 100644
--- a/media/base/test_helpers.h
+++ b/media/base/test_helpers.h
@@ -86,41 +86,32 @@
 };
 
 // Create an AudioBuffer containing |frames| frames of data, where each sample
-// is of type T.
+// is of type T.  |start| and |increment| are used to specify the values for the
+// samples, which are created in channel order.  The value for frame and channel
+// is determined by:
 //
-// For interleaved formats, each frame will have the data from |channels|
-// channels interleaved. |start| and |increment| are used to specify the values
-// for the samples. Since this is interleaved data, channel 0 data will be:
-//   |start|
-//   |start| + |channels| * |increment|
-//   |start| + 2 * |channels| * |increment|, and so on.
-// Data for subsequent channels is similar. No check is done that |format|
-// requires data to be of type T, but it is verified that |format| is an
-// interleaved format.
+//   |start| + |channel| * |frames| * |increment| + index * |increment|
 //
-// For planar formats, there will be a block for each of |channel| channels.
-// |start| and |increment| are used to specify the values for the samples, which
-// are created in channel order. Since this is planar data, channel 0 data will
-// be:
-//   |start|
-//   |start| + |increment|
-//   |start| + 2 * |increment|, and so on.
-// Data for channel 1 will follow where channel 0 ends. Subsequent channels are
-// similar. No check is done that |format| requires data to be of type T, but it
-// is verified that |format| is a planar format.
+// E.g., for a stereo buffer the values in channel 0 will be:
+//   start
+//   start + increment
+//   start + 2 * increment, ...
 //
-// |start_time| will be used as the start time for the samples. |duration| is
-// the duration.
+// While, values in channel 1 will be:
+//   start + frames * increment
+//   start + (frames + 1) * increment
+//   start + (frames + 2) * increment, ...
+//
+// |start_time| will be used as the start time for the samples.
 template <class T>
 scoped_refptr<AudioBuffer> MakeAudioBuffer(SampleFormat format,
                                            ChannelLayout channel_layout,
-                                           int channel_count,
+                                           size_t channel_count,
                                            int sample_rate,
                                            T start,
                                            T increment,
-                                           int frames,
-                                           base::TimeDelta timestamp,
-                                           base::TimeDelta duration);
+                                           size_t frames,
+                                           base::TimeDelta timestamp);
 
 // Create a fake video DecoderBuffer for testing purpose. The buffer contains
 // part of video decoder config info embedded so that the testing code can do
diff --git a/media/base/video_decoder.cc b/media/base/video_decoder.cc
index ed875f4..118e2a3 100644
--- a/media/base/video_decoder.cc
+++ b/media/base/video_decoder.cc
@@ -24,4 +24,8 @@
   return true;
 }
 
+int VideoDecoder::GetMaxDecodeRequests() const {
+  return 1;
+}
+
 }  // namespace media
diff --git a/media/base/video_decoder.h b/media/base/video_decoder.h
index 2153dfd..226b7b2 100644
--- a/media/base/video_decoder.h
+++ b/media/base/video_decoder.h
@@ -47,11 +47,16 @@
                           const PipelineStatusCB& status_cb) = 0;
 
   // Requests a |buffer| to be decoded. The status of the decoder and decoded
-  // frame are returned via the provided callback. Only one decode may be in
-  // flight at any given time.
+  // frame are returned via the provided callback. Some decoders may allow
+  // decoding multiple buffers in parallel. Callers should call
+  // GetMaxDecodeRequests() to get number of buffers that may be decoded in
+  // parallel. Decoder must call |decode_cb| in the same order in which Decode()
+  // is called.
   //
   // Implementations guarantee that the callback will not be called from within
-  // this method.
+  // this method and that |decode_cb| will not be blocked on the following
+  // Decode() calls (i.e. |decode_cb| will be called even Decode() is never
+  // called again).
   //
   // If the returned status is kOk:
   // - Non-EOS (end of stream) frame contains decoded video data.
@@ -65,6 +70,8 @@
   // Some VideoDecoders may queue up multiple VideoFrames from a single
   // DecoderBuffer, if we have any such queued frames this will return the next
   // one. Otherwise we return a NULL VideoFrame.
+  //
+  // TODO(xhwang): Revisit this method.
   virtual scoped_refptr<VideoFrame> GetDecodeOutput();
 
   // Resets decoder state, fulfilling all pending DecodeCB and dropping extra
@@ -89,6 +96,9 @@
   // use a fixed set of VideoFrames for decoding.
   virtual bool CanReadWithoutStalling() const;
 
+  // Returns maximum number of parallel decode requests.
+  virtual int GetMaxDecodeRequests() const;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(VideoDecoder);
 };
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 3d01455..089af93 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -83,6 +83,8 @@
       return "YV12A";
     case VideoFrame::YV12J:
       return "YV12J";
+    case VideoFrame::NV12:
+      return "NV12";
   }
   NOTREACHED() << "Invalid videoframe format provided: " << format;
   return "";
@@ -114,6 +116,7 @@
     case VideoFrame::YV12J:
     case VideoFrame::I420:
     case VideoFrame::YV12A:
+    case VideoFrame::NV12:
       // YUV formats have width/height requirements due to chroma subsampling.
       if (static_cast<size_t>(coded_size.height()) <
           RoundUp(visible_rect.bottom(), 2))
@@ -208,6 +211,53 @@
   }
 }
 
+#if defined(OS_POSIX)
+// static
+scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs(
+    Format format,
+    const gfx::Size& coded_size,
+    const gfx::Rect& visible_rect,
+    const gfx::Size& natural_size,
+    const std::vector<int> dmabuf_fds,
+    base::TimeDelta timestamp,
+    const base::Closure& no_longer_needed_cb) {
+  if (!IsValidConfig(format, coded_size, visible_rect, natural_size))
+    return NULL;
+
+  if (dmabuf_fds.size() != NumPlanes(format)) {
+    LOG(FATAL) << "Not enough dmabuf fds provided!";
+    return NULL;
+  }
+
+  scoped_refptr<VideoFrame> frame(
+      new VideoFrame(format,
+                     coded_size,
+                     visible_rect,
+                     natural_size,
+                     scoped_ptr<gpu::MailboxHolder>(),
+                     timestamp,
+                     false));
+
+  for (size_t i = 0; i < dmabuf_fds.size(); ++i) {
+    int duped_fd = HANDLE_EINTR(dup(dmabuf_fds[i]));
+    if (duped_fd == -1) {
+      // The already-duped in previous iterations fds will be closed when
+      // the partially-created frame drops out of scope here.
+      DLOG(ERROR) << "Failed duplicating a dmabuf fd";
+      return NULL;
+    }
+
+    frame->dmabuf_fds_[i].reset(duped_fd);
+    // Data is accessible only via fds.
+    frame->data_[i] = NULL;
+    frame->strides_[i] = 0;
+  }
+
+  frame->no_longer_needed_cb_ = no_longer_needed_cb;
+  return frame;
+}
+#endif
+
 // static
 scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData(
     Format format,
@@ -334,6 +384,8 @@
     case VideoFrame::HOLE:
 #endif  // defined(VIDEO_HOLE)
       return 0;
+    case VideoFrame::NV12:
+      return 2;
     case VideoFrame::YV12:
     case VideoFrame::YV16:
     case VideoFrame::I420:
@@ -400,6 +452,16 @@
           break;
       }
     }
+    case VideoFrame::NV12: {
+      switch (plane) {
+        case VideoFrame::kYPlane:
+          return gfx::Size(width, height);
+        case VideoFrame::kUVPlane:
+          return gfx::Size(width, height / 2);
+        default:
+          break;
+      }
+    }
     case VideoFrame::UNKNOWN:
     case VideoFrame::NATIVE_TEXTURE:
 #if defined(VIDEO_HOLE)
@@ -419,6 +481,46 @@
   return PlaneSize(format, plane, coded_size).GetArea();
 }
 
+// static
+int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) {
+  switch (format) {
+    case VideoFrame::YV12A:
+      if (plane == kAPlane)
+        return 8;
+    // fallthrough
+    case VideoFrame::YV12:
+    case VideoFrame::YV16:
+    case VideoFrame::I420:
+    case VideoFrame::YV12J: {
+      switch (plane) {
+        case kYPlane:
+          return 8;
+        case kUPlane:
+        case kVPlane:
+          return 2;
+        default:
+          break;
+      }
+    }
+
+    case VideoFrame::NV12: {
+      switch (plane) {
+        case kYPlane:
+          return 8;
+        case kUVPlane:
+          return 4;
+        default:
+          break;
+      }
+    }
+    default:
+      break;
+  }
+
+  NOTREACHED() << "Unsupported video frame format: " << format;
+  return 0;
+}
+
 // Release data allocated by AllocateYUV().
 static void ReleaseData(uint8* data) {
   DCHECK(data);
@@ -537,7 +639,14 @@
     case YV12J:
       if (plane == kYPlane)
         return width;
-      return RoundUp(width, 2) / 2;
+      else if (plane <= kVPlane)
+        return RoundUp(width, 2) / 2;
+      break;
+
+    case NV12:
+      if (plane <= kUVPlane)
+        return width;
+      break;
 
     default:
       break;
@@ -560,10 +669,20 @@
         return height;
     // Fallthrough.
     case YV12:
+    case YV12J:
     case I420:
       if (plane == kYPlane)
         return height;
-      return RoundUp(height, 2) / 2;
+      else if (plane <= kVPlane)
+        return RoundUp(height, 2) / 2;
+      break;
+
+    case NV12:
+      if (plane == kYPlane)
+        return height;
+      else if (plane == kUVPlane)
+        return RoundUp(height, 2) / 2;
+      break;
 
     default:
       break;
@@ -596,6 +715,12 @@
   release_sync_points_.push_back(sync_point);
 }
 
+#if defined(OS_POSIX)
+int VideoFrame::dmabuf_fd(size_t plane) const {
+  return dmabuf_fds_[plane].get();
+}
+#endif
+
 void VideoFrame::HashFrameForTesting(base::MD5Context* context) {
   for (int plane = 0; plane < kMaxPlanes; ++plane) {
     if (!IsValidPlane(plane))
diff --git a/media/base/video_frame.h b/media/base/video_frame.h
index 024cb4c..a3f296d 100644
--- a/media/base/video_frame.h
+++ b/media/base/video_frame.h
@@ -36,6 +36,7 @@
 
     kYPlane = 0,
     kUPlane = 1,
+    kUVPlane = kUPlane,
     kVPlane = 2,
     kAPlane = 3,
   };
@@ -55,7 +56,8 @@
 #endif  // defined(VIDEO_HOLE)
     NATIVE_TEXTURE = 6,  // Native texture.  Pixel-format agnostic.
     YV12J = 7,  // JPEG color range version of YV12
-    FORMAT_MAX = YV12J,  // Must always be equal to largest entry logged.
+    NV12 = 8,  // 12bpp 1x1 Y plane followed by an interleaved 2x2 UV plane.
+    FORMAT_MAX = NV12,  // Must always be equal to largest entry logged.
   };
 
   // Returns the name of a Format as a string.
@@ -122,6 +124,27 @@
       base::TimeDelta timestamp,
       const base::Closure& no_longer_needed_cb);
 
+#if defined(OS_POSIX)
+  // Wraps provided dmabufs
+  // (https://www.kernel.org/doc/Documentation/dma-buf-sharing.txt) with a
+  // VideoFrame. The dmabuf fds are dup()ed on creation, so that the VideoFrame
+  // retains a reference to them, and are automatically close()d on destruction,
+  // dropping the reference. The caller may safely close() its reference after
+  // calling WrapExternalDmabufs().
+  // The image data is only accessible via dmabuf fds, which are usually passed
+  // directly to a hardware device and/or to another process, or can also be
+  // mapped via mmap() for CPU access.
+  // When the frame is destroyed, |no_longer_needed_cb.Run()| will be called.
+  static scoped_refptr<VideoFrame> WrapExternalDmabufs(
+      Format format,
+      const gfx::Size& coded_size,
+      const gfx::Rect& visible_rect,
+      const gfx::Size& natural_size,
+      const std::vector<int> dmabuf_fds,
+      base::TimeDelta timestamp,
+      const base::Closure& no_longer_needed_cb);
+#endif
+
   // Wraps external YUV data of the given parameters with a VideoFrame.
   // The returned VideoFrame does not own the data passed in. When the frame
   // is destroyed |no_longer_needed_cb.Run()| will be called.
@@ -185,6 +208,9 @@
                                     size_t plane,
                                     const gfx::Size& coded_size);
 
+  // Returns horizontal bits per pixel for given |plane| and |format|.
+  static int PlaneHorizontalBitsPerPixel(Format format, size_t plane);
+
   Format format() const { return format_; }
 
   const gfx::Size& coded_size() const { return coded_size_; }
@@ -212,6 +238,11 @@
   // Returns the shared-memory handle, if present
   base::SharedMemoryHandle shared_memory_handle() const;
 
+#if defined(OS_POSIX)
+  // Returns backing dmabuf file descriptor for given |plane|, if present.
+  int dmabuf_fd(size_t plane) const;
+#endif
+
   // Returns true if this VideoFrame represents the end of the stream.
   bool end_of_stream() const { return end_of_stream_; }
 
@@ -285,6 +316,12 @@
   // Shared memory handle, if this frame was allocated from shared memory.
   base::SharedMemoryHandle shared_memory_handle_;
 
+#if defined(OS_POSIX)
+  // Dmabufs for each plane, if this frame is wrapping memory
+  // acquired via dmabuf.
+  base::ScopedFD dmabuf_fds_[kMaxPlanes];
+#endif
+
   base::Closure no_longer_needed_cb_;
 
   base::TimeDelta timestamp_;
diff --git a/media/base/yuv_convert.cc b/media/base/yuv_convert.cc
index 2b27c1d..5ad8f30 100644
--- a/media/base/yuv_convert.cc
+++ b/media/base/yuv_convert.cc
@@ -25,6 +25,7 @@
 #include "media/base/simd/convert_rgb_to_yuv.h"
 #include "media/base/simd/convert_yuv_to_rgb.h"
 #include "media/base/simd/filter_yuv.h"
+#include "media/base/simd/yuv_to_rgb_table.h"
 
 #if defined(ARCH_CPU_X86_FAMILY)
 #if defined(COMPILER_MSVC)
@@ -79,21 +80,24 @@
                                          const uint8*,
                                          const uint8*,
                                          uint8*,
-                                         ptrdiff_t);
+                                         ptrdiff_t,
+                                         const int16[1024][4]);
 
 typedef void (*ConvertYUVAToARGBRowProc)(const uint8*,
                                          const uint8*,
                                          const uint8*,
                                          const uint8*,
                                          uint8*,
-                                         ptrdiff_t);
+                                         ptrdiff_t,
+                                         const int16[1024][4]);
 
 typedef void (*ScaleYUVToRGB32RowProc)(const uint8*,
                                        const uint8*,
                                        const uint8*,
                                        uint8*,
                                        ptrdiff_t,
-                                       ptrdiff_t);
+                                       ptrdiff_t,
+                                       const int16[1024][4]);
 
 static FilterYUVRowsProc g_filter_yuv_rows_proc_ = NULL;
 static ConvertYUVToRGB32RowProc g_convert_yuv_to_rgb32_row_proc_ = NULL;
@@ -112,6 +116,31 @@
 typedef void (*EmptyRegisterStateProc)();
 static EmptyRegisterStateProc g_empty_register_state_proc_ = NULL;
 
+// Get the appropriate value to bitshift by for vertical indices.
+int GetVerticalShift(YUVType type) {
+  switch (type) {
+    case YV16:
+      return 0;
+    case YV12:
+    case YV12J:
+      return 1;
+  }
+  NOTREACHED();
+  return 0;
+}
+
+const int16 (&GetLookupTable(YUVType type))[1024][4] {
+  switch (type) {
+    case YV12:
+    case YV16:
+      return kCoefficientsRgbY;
+    case YV12J:
+      return kCoefficientsRgbY_JPEG;
+  }
+  NOTREACHED();
+  return kCoefficientsRgbY;
+}
+
 void InitializeCPUSpecificYUVConversions() {
   CHECK(!g_filter_yuv_rows_proc_);
   CHECK(!g_convert_yuv_to_rgb32_row_proc_);
@@ -222,7 +251,7 @@
   if (source_width > kFilterBufferSize || view_rotate)
     filter = FILTER_NONE;
 
-  unsigned int y_shift = yuv_type;
+  unsigned int y_shift = GetVerticalShift(yuv_type);
   // Diagram showing origin and direction of source sampling.
   // ->0   4<-
   // 7       3
@@ -354,14 +383,25 @@
       v_ptr = v_buf + (source_y >> y_shift) * uv_pitch;
     }
     if (source_dx == kFractionMax) {  // Not scaled
-      g_convert_yuv_to_rgb32_row_proc_(y_ptr, u_ptr, v_ptr, dest_pixel, width);
+      g_convert_yuv_to_rgb32_row_proc_(
+          y_ptr, u_ptr, v_ptr, dest_pixel, width, kCoefficientsRgbY);
     } else {
       if (filter & FILTER_BILINEAR_H) {
-        g_linear_scale_yuv_to_rgb32_row_proc_(
-            y_ptr, u_ptr, v_ptr, dest_pixel, width, source_dx);
+        g_linear_scale_yuv_to_rgb32_row_proc_(y_ptr,
+                                              u_ptr,
+                                              v_ptr,
+                                              dest_pixel,
+                                              width,
+                                              source_dx,
+                                              kCoefficientsRgbY);
       } else {
-        g_scale_yuv_to_rgb32_row_proc_(
-            y_ptr, u_ptr, v_ptr, dest_pixel, width, source_dx);
+        g_scale_yuv_to_rgb32_row_proc_(y_ptr,
+                                       u_ptr,
+                                       v_ptr,
+                                       dest_pixel,
+                                       width,
+                                       source_dx,
+                                       kCoefficientsRgbY);
       }
     }
   }
@@ -505,7 +545,8 @@
                                           rgb_buf,
                                           dest_rect_width,
                                           source_left,
-                                          x_step);
+                                          x_step,
+                                          kCoefficientsRgbY);
     } else {
       // If the frame is too large then we linear scale a single row.
       LinearScaleYUVToRGB32RowWithRange_C(y0_ptr,
@@ -514,7 +555,8 @@
                                           rgb_buf,
                                           dest_rect_width,
                                           source_left,
-                                          x_step);
+                                          x_step,
+                                          kCoefficientsRgbY);
     }
 
     // Advance vertically in the source and destination image.
diff --git a/media/base/yuv_convert.h b/media/base/yuv_convert.h
index 8f64c79..cf13edb 100644
--- a/media/base/yuv_convert.h
+++ b/media/base/yuv_convert.h
@@ -7,6 +7,7 @@
 
 #include "base/basictypes.h"
 #include "media/base/media_export.h"
+#include "media/base/simd/yuv_to_rgb_table.h"
 
 // Visual Studio 2010 does not support MMX intrinsics on x64.
 // Some win64 yuv_convert code paths use SSE+MMX yasm, so without rewriting
@@ -22,12 +23,18 @@
 namespace media {
 
 // Type of YUV surface.
-// The value of these enums matter as they are used to shift vertical indices.
 enum YUVType {
-  YV16 = 0,  // YV16 is half width and full height chroma channels.
-  YV12 = 1,  // YV12 is half width and half height chroma channels.
+  YV16  = 0,  // YV16 is half width and full height chroma channels.
+  YV12  = 1,  // YV12 is half width and half height chroma channels.
+  YV12J = 2,  // YV12J is the same as YV12, but in JPEG color range.
 };
 
+// Get the appropriate value to bitshift by for vertical indices.
+MEDIA_EXPORT int GetVerticalShift(YUVType type);
+
+// Get the appropriate lookup table for a given YUV format.
+MEDIA_EXPORT const int16 (&GetLookupTable(YUVType type))[1024][4];
+
 // Mirror means flip the image horizontally, as in looking in a mirror.
 // Rotate happens after mirroring.
 enum Rotate {
diff --git a/media/base/yuv_convert_perftest.cc b/media/base/yuv_convert_perftest.cc
index 0188ce6..0f30beb 100644
--- a/media/base/yuv_convert_perftest.cc
+++ b/media/base/yuv_convert_perftest.cc
@@ -76,7 +76,8 @@
           yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2),
           yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
           rgb_bytes_converted_.get(),
-          kWidth);
+          kWidth,
+          GetLookupTable(YV12));
     }
   }
   double total_time_seconds =
@@ -100,7 +101,8 @@
           yuv_bytes_.get() + kSourceUOffset + (chroma_row * kSourceWidth / 2),
           yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
           rgb_bytes_converted_.get(),
-          kWidth);
+          kWidth,
+          GetLookupTable(YV12));
     }
   }
   double total_time_seconds =
@@ -126,7 +128,8 @@
           yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
           rgb_bytes_converted_.get(),
           kWidth,
-          kSourceDx);
+          kSourceDx,
+          GetLookupTable(YV12));
     }
   }
   double total_time_seconds =
@@ -152,7 +155,8 @@
           yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
           rgb_bytes_converted_.get(),
           kWidth,
-          kSourceDx);
+          kSourceDx,
+          GetLookupTable(YV12));
     }
   }
   double total_time_seconds =
@@ -178,7 +182,8 @@
           yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
           rgb_bytes_converted_.get(),
           kWidth,
-          kSourceDx);
+          kSourceDx,
+          GetLookupTable(YV12));
     }
   }
   double total_time_seconds =
@@ -204,7 +209,8 @@
           yuv_bytes_.get() + kSourceVOffset + (chroma_row * kSourceWidth / 2),
           rgb_bytes_converted_.get(),
           kWidth,
-          kSourceDx);
+          kSourceDx,
+          GetLookupTable(YV12));
     }
   }
   double total_time_seconds =
diff --git a/media/base/yuv_convert_unittest.cc b/media/base/yuv_convert_unittest.cc
index 7c964f3..73deb1f 100644
--- a/media/base/yuv_convert_unittest.cc
+++ b/media/base/yuv_convert_unittest.cc
@@ -11,6 +11,7 @@
 #include "media/base/simd/convert_rgb_to_yuv.h"
 #include "media/base/simd/convert_yuv_to_rgb.h"
 #include "media/base/simd/filter_yuv.h"
+#include "media/base/simd/yuv_to_rgb_table.h"
 #include "media/base/yuv_convert.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/rect.h"
@@ -162,6 +163,7 @@
   YUVScaleTest() {
     switch (GetParam().yuv_type) {
       case media::YV12:
+      case media::YV12J:
         ReadYV12Data(&yuv_bytes_);
         break;
       case media::YV16:
@@ -178,6 +180,7 @@
   uint8* v_plane() {
     switch (GetParam().yuv_type) {
       case media::YV12:
+      case media::YV12J:
         return yuv_bytes_.get() + kSourceVOffset;
       case media::YV16:
         return yuv_bytes_.get() + kSourceYSize * 3 / 2;
@@ -618,12 +621,14 @@
                          yuv_bytes.get() + kSourceUOffset,
                          yuv_bytes.get() + kSourceVOffset,
                          rgb_bytes_reference.get(),
-                         kWidth);
+                         kWidth,
+                         GetLookupTable(YV12));
   ConvertYUVToRGB32Row_MMX(yuv_bytes.get(),
                            yuv_bytes.get() + kSourceUOffset,
                            yuv_bytes.get() + kSourceVOffset,
                            rgb_bytes_converted.get(),
-                           kWidth);
+                           kWidth,
+                           GetLookupTable(YV12));
   media::EmptyRegisterState();
   EXPECT_EQ(0, memcmp(rgb_bytes_reference.get(),
                       rgb_bytes_converted.get(),
@@ -647,12 +652,14 @@
                          yuv_bytes.get() + kSourceUOffset,
                          yuv_bytes.get() + kSourceVOffset,
                          rgb_bytes_reference.get(),
-                         kWidth);
+                         kWidth,
+                         GetLookupTable(YV12));
   ConvertYUVToRGB32Row_SSE(yuv_bytes.get(),
                            yuv_bytes.get() + kSourceUOffset,
                            yuv_bytes.get() + kSourceVOffset,
                            rgb_bytes_converted.get(),
-                           kWidth);
+                           kWidth,
+                           GetLookupTable(YV12));
   media::EmptyRegisterState();
   EXPECT_EQ(0, memcmp(rgb_bytes_reference.get(),
                       rgb_bytes_converted.get(),
@@ -678,13 +685,15 @@
                        yuv_bytes.get() + kSourceVOffset,
                        rgb_bytes_reference.get(),
                        kWidth,
-                       kSourceDx);
+                       kSourceDx,
+                       GetLookupTable(YV12));
   ScaleYUVToRGB32Row_MMX(yuv_bytes.get(),
                          yuv_bytes.get() + kSourceUOffset,
                          yuv_bytes.get() + kSourceVOffset,
                          rgb_bytes_converted.get(),
                          kWidth,
-                         kSourceDx);
+                         kSourceDx,
+                         GetLookupTable(YV12));
   media::EmptyRegisterState();
   EXPECT_EQ(0, memcmp(rgb_bytes_reference.get(),
                       rgb_bytes_converted.get(),
@@ -710,13 +719,15 @@
                        yuv_bytes.get() + kSourceVOffset,
                        rgb_bytes_reference.get(),
                        kWidth,
-                       kSourceDx);
+                       kSourceDx,
+                       GetLookupTable(YV12));
   ScaleYUVToRGB32Row_SSE(yuv_bytes.get(),
                          yuv_bytes.get() + kSourceUOffset,
                          yuv_bytes.get() + kSourceVOffset,
                          rgb_bytes_converted.get(),
                          kWidth,
-                         kSourceDx);
+                         kSourceDx,
+                         GetLookupTable(YV12));
   media::EmptyRegisterState();
   EXPECT_EQ(0, memcmp(rgb_bytes_reference.get(),
                       rgb_bytes_converted.get(),
@@ -742,13 +753,15 @@
                              yuv_bytes.get() + kSourceVOffset,
                              rgb_bytes_reference.get(),
                              kWidth,
-                             kSourceDx);
+                             kSourceDx,
+                             GetLookupTable(YV12));
   LinearScaleYUVToRGB32Row_MMX(yuv_bytes.get(),
                                yuv_bytes.get() + kSourceUOffset,
                                yuv_bytes.get() + kSourceVOffset,
                                rgb_bytes_converted.get(),
                                kWidth,
-                               kSourceDx);
+                               kSourceDx,
+                               GetLookupTable(YV12));
   media::EmptyRegisterState();
   EXPECT_EQ(0, memcmp(rgb_bytes_reference.get(),
                       rgb_bytes_converted.get(),
@@ -774,13 +787,15 @@
                              yuv_bytes.get() + kSourceVOffset,
                              rgb_bytes_reference.get(),
                              kWidth,
-                             kSourceDx);
+                             kSourceDx,
+                             GetLookupTable(YV12));
   LinearScaleYUVToRGB32Row_SSE(yuv_bytes.get(),
                                yuv_bytes.get() + kSourceUOffset,
                                yuv_bytes.get() + kSourceVOffset,
                                rgb_bytes_converted.get(),
                                kWidth,
-                               kSourceDx);
+                               kSourceDx,
+                               GetLookupTable(YV12));
   media::EmptyRegisterState();
   EXPECT_EQ(0, memcmp(rgb_bytes_reference.get(),
                       rgb_bytes_converted.get(),
@@ -924,13 +939,15 @@
                        yuv_bytes.get() + kSourceVOffset,
                        rgb_bytes_reference.get(),
                        kWidth,
-                       kSourceDx);
+                       kSourceDx,
+                       GetLookupTable(YV12));
   ScaleYUVToRGB32Row_SSE2_X64(yuv_bytes.get(),
                               yuv_bytes.get() + kSourceUOffset,
                               yuv_bytes.get() + kSourceVOffset,
                               rgb_bytes_converted.get(),
                               kWidth,
-                              kSourceDx);
+                              kSourceDx,
+                              GetLookupTable(YV12));
   media::EmptyRegisterState();
   EXPECT_EQ(0, memcmp(rgb_bytes_reference.get(),
                       rgb_bytes_converted.get(),
@@ -950,13 +967,15 @@
                              yuv_bytes.get() + kSourceVOffset,
                              rgb_bytes_reference.get(),
                              kWidth,
-                             kSourceDx);
+                             kSourceDx,
+                             GetLookupTable(YV12));
   LinearScaleYUVToRGB32Row_MMX_X64(yuv_bytes.get(),
                                    yuv_bytes.get() + kSourceUOffset,
                                    yuv_bytes.get() + kSourceVOffset,
                                    rgb_bytes_converted.get(),
                                    kWidth,
-                                   kSourceDx);
+                                   kSourceDx,
+                                   GetLookupTable(YV12));
   media::EmptyRegisterState();
   EXPECT_EQ(0, memcmp(rgb_bytes_reference.get(),
                       rgb_bytes_converted.get(),
diff --git a/media/cast/audio_sender/audio_encoder.cc b/media/cast/audio_sender/audio_encoder.cc
index 6becdd5..6f31726 100644
--- a/media/cast/audio_sender/audio_encoder.cc
+++ b/media/cast/audio_sender/audio_encoder.cc
@@ -10,6 +10,7 @@
 #include "base/bind_helpers.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/stl_util.h"
 #include "base/sys_byteorder.h"
 #include "base/time/time.h"
 #include "media/base/audio_bus.h"
@@ -18,39 +19,47 @@
 #include "media/cast/logging/logging_defines.h"
 #include "third_party/opus/src/include/opus.h"
 
+namespace media {
+namespace cast {
+
 namespace {
 
-void LogAudioFrameEvent(
-    const scoped_refptr<media::cast::CastEnvironment>& cast_environment,
-    base::TimeTicks event_time,
-    media::cast::CastLoggingEvent event_type,
-    media::cast::RtpTimestamp rtp_timestamp,
-    uint32 frame_id) {
-  cast_environment->Logging()->InsertFrameEvent(
-      event_time, event_type, rtp_timestamp, frame_id);
-}
+// The fixed number of audio frames per second and, inversely, the duration of
+// one frame's worth of samples.
+const int kFramesPerSecond = 100;
+const int kFrameDurationMillis = 1000 / kFramesPerSecond;  // No remainder!
+
+// Threshold used to decide whether audio being delivered to the encoder is
+// coming in too slow with respect to the capture timestamps.
+const int kUnderrunThresholdMillis = 3 * kFrameDurationMillis;
 
 void LogAudioFrameEncodedEvent(
     const scoped_refptr<media::cast::CastEnvironment>& cast_environment,
     base::TimeTicks event_time,
-    media::cast::CastLoggingEvent event_type,
     media::cast::RtpTimestamp rtp_timestamp,
     uint32 frame_id,
     size_t frame_size) {
+  if (!cast_environment->CurrentlyOn(CastEnvironment::MAIN)) {
+    cast_environment->PostTask(
+        CastEnvironment::MAIN,
+        FROM_HERE,
+        base::Bind(&LogAudioFrameEncodedEvent,
+                   cast_environment, event_time,
+                   rtp_timestamp, frame_id, frame_size));
+    return;
+  }
   cast_environment->Logging()->InsertEncodedFrameEvent(
-      event_time, event_type, rtp_timestamp, frame_id,
+      event_time, kAudioFrameEncoded, rtp_timestamp, frame_id,
       static_cast<int>(frame_size), /* key_frame - unused */ false,
       /*target_bitrate - unused*/ 0);
 }
 
 }  // namespace
 
-namespace media {
-namespace cast {
 
 // Base class that handles the common problem of feeding one or more AudioBus'
-// data into a 10 ms buffer and then, once the buffer is full, encoding the
-// signal and emitting an EncodedAudioFrame via the FrameEncodedCallback.
+// data into a buffer and then, once the buffer is full, encoding the signal and
+// emitting an EncodedAudioFrame via the FrameEncodedCallback.
 //
 // Subclasses complete the implementation by handling the actual encoding
 // details.
@@ -65,15 +74,15 @@
       : cast_environment_(cast_environment),
         codec_(codec),
         num_channels_(num_channels),
-        samples_per_10ms_(sampling_rate / 100),
+        samples_per_frame_(sampling_rate / kFramesPerSecond),
         callback_(callback),
         cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED),
         buffer_fill_end_(0),
         frame_id_(0),
-        rtp_timestamp_(0) {
-    if (num_channels_ <= 0 || samples_per_10ms_ <= 0 ||
-        sampling_rate % 100 != 0 ||
-        samples_per_10ms_ * num_channels_ >
+        frame_rtp_timestamp_(0) {
+    if (num_channels_ <= 0 || samples_per_frame_ <= 0 ||
+        sampling_rate % kFramesPerSecond != 0 ||
+        samples_per_frame_ * num_channels_ >
             transport::EncodedAudioFrame::kMaxNumberOfSamples) {
       cast_initialization_status_ = STATUS_INVALID_AUDIO_CONFIGURATION;
     }
@@ -86,72 +95,75 @@
   void EncodeAudio(scoped_ptr<AudioBus> audio_bus,
                    const base::TimeTicks& recorded_time) {
     DCHECK_EQ(cast_initialization_status_, STATUS_AUDIO_INITIALIZED);
+    DCHECK(!recorded_time.is_null());
 
+    // Determine whether |recorded_time| is consistent with the amount of audio
+    // data having been processed in the past.  Resolve the underrun problem by
+    // dropping data from the internal buffer and skipping ahead the next
+    // frame's RTP timestamp by the estimated number of frames missed.  On the
+    // other hand, don't attempt to resolve overruns: A receiver should
+    // gracefully deal with an excess of audio data.
+    const base::TimeDelta frame_duration =
+        base::TimeDelta::FromMilliseconds(kFrameDurationMillis);
+    base::TimeDelta buffer_fill_duration =
+        buffer_fill_end_ * frame_duration / samples_per_frame_;
+    if (!frame_capture_time_.is_null()) {
+      const base::TimeDelta amount_ahead_by =
+          recorded_time - (frame_capture_time_ + buffer_fill_duration);
+      if (amount_ahead_by >
+              base::TimeDelta::FromMilliseconds(kUnderrunThresholdMillis)) {
+        buffer_fill_end_ = 0;
+        buffer_fill_duration = base::TimeDelta();
+        const int64 num_frames_missed = amount_ahead_by /
+            base::TimeDelta::FromMilliseconds(kFrameDurationMillis);
+        frame_rtp_timestamp_ +=
+            static_cast<uint32>(num_frames_missed * samples_per_frame_);
+        DVLOG(1) << "Skipping RTP timestamp ahead to account for "
+                 << num_frames_missed * samples_per_frame_
+                 << " samples' worth of underrun.";
+      }
+    }
+    frame_capture_time_ = recorded_time - buffer_fill_duration;
+
+    // Encode all audio in |audio_bus| into zero or more frames.
     int src_pos = 0;
-    int packet_count = 0;
     while (src_pos < audio_bus->frames()) {
       const int num_samples_to_xfer = std::min(
-          samples_per_10ms_ - buffer_fill_end_, audio_bus->frames() - src_pos);
+          samples_per_frame_ - buffer_fill_end_, audio_bus->frames() - src_pos);
       DCHECK_EQ(audio_bus->channels(), num_channels_);
       TransferSamplesIntoBuffer(
           audio_bus.get(), src_pos, buffer_fill_end_, num_samples_to_xfer);
       src_pos += num_samples_to_xfer;
       buffer_fill_end_ += num_samples_to_xfer;
 
-      if (buffer_fill_end_ == samples_per_10ms_) {
-        scoped_ptr<transport::EncodedAudioFrame> audio_frame(
-            new transport::EncodedAudioFrame());
-        audio_frame->codec = codec_;
-        audio_frame->frame_id = frame_id_++;
-        rtp_timestamp_ += samples_per_10ms_;
-        audio_frame->rtp_timestamp = rtp_timestamp_;
+      if (buffer_fill_end_ < samples_per_frame_)
+        break;
 
-        // Update logging.
+      scoped_ptr<transport::EncodedAudioFrame> audio_frame(
+          new transport::EncodedAudioFrame());
+      audio_frame->codec = codec_;
+      audio_frame->frame_id = frame_id_;
+      audio_frame->rtp_timestamp = frame_rtp_timestamp_;
+
+      if (EncodeFromFilledBuffer(&audio_frame->data)) {
+        LogAudioFrameEncodedEvent(cast_environment_,
+                                  cast_environment_->Clock()->NowTicks(),
+                                  audio_frame->rtp_timestamp,
+                                  audio_frame->frame_id,
+                                  audio_frame->data.size());
         cast_environment_->PostTask(
             CastEnvironment::MAIN,
             FROM_HERE,
-            base::Bind(&LogAudioFrameEvent,
-                       cast_environment_,
-                       cast_environment_->Clock()->NowTicks(),
-                       kAudioFrameReceived,
-                       audio_frame->rtp_timestamp,
-                       audio_frame->frame_id));
-
-        if (EncodeFromFilledBuffer(&audio_frame->data)) {
-          // Update logging.
-          cast_environment_->PostTask(
-              CastEnvironment::MAIN,
-              FROM_HERE,
-              base::Bind(&LogAudioFrameEncodedEvent,
-                         cast_environment_,
-                         cast_environment_->Clock()->NowTicks(),
-                         kAudioFrameEncoded,
-                         audio_frame->rtp_timestamp,
-                         audio_frame->frame_id,
-                         audio_frame->data.size()));
-          // Compute an offset to determine the recorded time for the first
-          // audio sample in the buffer.
-          const base::TimeDelta buffer_time_offset =
-              (buffer_fill_end_ - src_pos) *
-              base::TimeDelta::FromMilliseconds(10) / samples_per_10ms_;
-          // TODO(miu): Consider batching EncodedAudioFrames so we only post a
-          // at most one task for each call to this method.
-          // Postpone every packet by 10mS with respect to the previous. Playout
-          // is postponed already by 10mS, and this will better correlate with
-          // the pacer's expectations.
-          //TODO(mikhal): Turn this into a list of packets.
-          // Update the end2end allowed error once this is fixed.
-          cast_environment_->PostDelayedTask(
-              CastEnvironment::MAIN,
-              FROM_HERE,
-              base::Bind(callback_,
-                         base::Passed(&audio_frame),
-                         recorded_time - buffer_time_offset),
-              base::TimeDelta::FromMilliseconds(packet_count * 10));
-          ++packet_count;
-        }
-        buffer_fill_end_ = 0;
+            base::Bind(callback_,
+                       base::Passed(&audio_frame),
+                       frame_capture_time_));
       }
+
+      // Reset the internal buffer, frame ID, and timestamps for the next frame.
+      buffer_fill_end_ = 0;
+      ++frame_id_;
+      frame_rtp_timestamp_ += samples_per_frame_;
+      frame_capture_time_ += frame_duration;
     }
   }
 
@@ -168,7 +180,7 @@
   const scoped_refptr<CastEnvironment> cast_environment_;
   const transport::AudioCodec codec_;
   const int num_channels_;
-  const int samples_per_10ms_;
+  const int samples_per_frame_;
   const FrameEncodedCallback callback_;
 
   // Subclass' ctor is expected to set this to STATUS_AUDIO_INITIALIZED.
@@ -183,9 +195,19 @@
   // A counter used to label EncodedAudioFrames.
   uint32 frame_id_;
 
-  // For audio, rtp_timestamp is computed as the sum of the audio samples seen
-  // so far.
-  uint32 rtp_timestamp_;
+  // The RTP timestamp for the next frame of encoded audio.  This is defined as
+  // the number of audio samples encoded so far, plus the estimated number of
+  // samples that were missed due to data underruns.  A receiver uses this value
+  // to detect gaps in the audio signal data being provided.  Per the spec, RTP
+  // timestamp values are allowed to overflow and roll around past zero.
+  uint32 frame_rtp_timestamp_;
+
+  // The local system time associated with the start of the next frame of
+  // encoded audio.  This value is passed on to a receiver as a reference clock
+  // timestamp for the purposes of synchronizing audio and video.  Its
+  // progression is expected to drift relative to the elapsed time implied by
+  // the RTP timestamps.
+  base::TimeTicks frame_capture_time_;
 
   DISALLOW_COPY_AND_ASSIGN(ImplBase);
 };
@@ -204,7 +226,7 @@
                  callback),
         encoder_memory_(new uint8[opus_encoder_get_size(num_channels)]),
         opus_encoder_(reinterpret_cast<OpusEncoder*>(encoder_memory_.get())),
-        buffer_(new float[num_channels * samples_per_10ms_]) {
+        buffer_(new float[num_channels * samples_per_frame_]) {
     if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED)
       return;
     if (opus_encoder_init(opus_encoder_,
@@ -250,8 +272,8 @@
     const opus_int32 result =
         opus_encode_float(opus_encoder_,
                           buffer_.get(),
-                          samples_per_10ms_,
-                          reinterpret_cast<uint8*>(&out->at(0)),
+                          samples_per_frame_,
+                          reinterpret_cast<uint8*>(string_as_array(out)),
                           kOpusMaxPayloadSize);
     if (result > 1) {
       out->resize(result);
@@ -292,7 +314,7 @@
                  num_channels,
                  sampling_rate,
                  callback),
-        buffer_(new int16[num_channels * samples_per_10ms_]) {
+        buffer_(new int16[num_channels * samples_per_frame_]) {
     if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED)
       return;
     cast_initialization_status_ = STATUS_AUDIO_INITIALIZED;
@@ -314,9 +336,9 @@
 
   virtual bool EncodeFromFilledBuffer(std::string* out) OVERRIDE {
     // Output 16-bit PCM integers in big-endian byte order.
-    out->resize(num_channels_ * samples_per_10ms_ * sizeof(int16));
+    out->resize(num_channels_ * samples_per_frame_ * sizeof(int16));
     const int16* src = buffer_.get();
-    const int16* const src_end = src + num_channels_ * samples_per_10ms_;
+    const int16* const src_end = src + num_channels_ * samples_per_frame_;
     uint16* dest = reinterpret_cast<uint16*>(&out->at(0));
     for (; src < src_end; ++src, ++dest)
       *dest = base::HostToNet16(*src);
diff --git a/media/cast/audio_sender/audio_encoder_unittest.cc b/media/cast/audio_sender/audio_encoder_unittest.cc
index e2a467e..0ca07bb 100644
--- a/media/cast/audio_sender/audio_encoder_unittest.cc
+++ b/media/cast/audio_sender/audio_encoder_unittest.cc
@@ -29,21 +29,29 @@
 class TestEncodedAudioFrameReceiver {
  public:
   explicit TestEncodedAudioFrameReceiver(transport::AudioCodec codec)
-      : codec_(codec), frames_received_(0) {}
+      : codec_(codec), frames_received_(0), rtp_lower_bound_(0) {}
   virtual ~TestEncodedAudioFrameReceiver() {}
 
   int frames_received() const { return frames_received_; }
 
-  void SetRecordedTimeLowerBound(const base::TimeTicks& t) { lower_bound_ = t; }
-
-  void SetRecordedTimeUpperBound(const base::TimeTicks& t) { upper_bound_ = t; }
+  void SetCaptureTimeBounds(const base::TimeTicks& lower_bound,
+                            const base::TimeTicks& upper_bound) {
+    lower_bound_ = lower_bound;
+    upper_bound_ = upper_bound;
+  }
 
   void FrameEncoded(scoped_ptr<transport::EncodedAudioFrame> encoded_frame,
                     const base::TimeTicks& recorded_time) {
     EXPECT_EQ(codec_, encoded_frame->codec);
     EXPECT_EQ(static_cast<uint8>(frames_received_ & 0xff),
               encoded_frame->frame_id);
-    EXPECT_LT(0u, encoded_frame->rtp_timestamp);
+    // RTP timestamps should be monotonically increasing and integer multiples
+    // of the fixed frame size.
+    EXPECT_LE(rtp_lower_bound_, encoded_frame->rtp_timestamp);
+    rtp_lower_bound_ = encoded_frame->rtp_timestamp;
+    // Note: In audio_encoder.cc, 100 is the fixed audio frame rate.
+    const int kSamplesPerFrame = kDefaultAudioSamplingRate / 100;
+    EXPECT_EQ(0u, encoded_frame->rtp_timestamp % kSamplesPerFrame);
     EXPECT_TRUE(!encoded_frame->data.empty());
 
     EXPECT_LE(lower_bound_, recorded_time);
@@ -56,6 +64,7 @@
  private:
   const transport::AudioCodec codec_;
   int frames_received_;
+  uint32 rtp_lower_bound_;
   base::TimeTicks lower_bound_;
   base::TimeTicks upper_bound_;
 
@@ -108,18 +117,26 @@
 
     CreateObjectsForCodec(codec);
 
-    receiver_->SetRecordedTimeLowerBound(testing_clock_->NowTicks());
+    // Note: In audio_encoder.cc, 10 ms is the fixed frame duration.
+    const base::TimeDelta frame_duration =
+        base::TimeDelta::FromMilliseconds(10);
+
     for (size_t i = 0; i < scenario.num_durations; ++i) {
+      const bool simulate_missing_data = scenario.durations_in_ms[i] < 0;
       const base::TimeDelta duration =
-          base::TimeDelta::FromMilliseconds(scenario.durations_in_ms[i]);
-      receiver_->SetRecordedTimeUpperBound(testing_clock_->NowTicks() +
-                                           duration);
-
-      audio_encoder_->InsertAudio(audio_bus_factory_->NextAudioBus(duration),
-                                  testing_clock_->NowTicks());
-      task_runner_->RunTasks();
-
-      testing_clock_->Advance(duration);
+          base::TimeDelta::FromMilliseconds(abs(scenario.durations_in_ms[i]));
+      receiver_->SetCaptureTimeBounds(
+          testing_clock_->NowTicks() - frame_duration,
+          testing_clock_->NowTicks() + duration);
+      if (simulate_missing_data) {
+        task_runner_->RunTasks();
+        testing_clock_->Advance(duration);
+      } else {
+        audio_encoder_->InsertAudio(audio_bus_factory_->NextAudioBus(duration),
+                                    testing_clock_->NowTicks());
+        task_runner_->RunTasks();
+        testing_clock_->Advance(duration);
+      }
     }
 
     DVLOG(1) << "Received " << receiver_->frames_received()
@@ -192,6 +209,12 @@
 static const int64 kManyCalls_Mixed5[] = {3, 14, 15, 9, 26, 53, 58, 9, 7,
                                           9, 3,  23, 8, 4,  6,  2,  6, 43};
 
+static const int64 kOneBigUnderrun[] = {10, 10, 10, 10, -1000, 10, 10, 10};
+static const int64 kTwoBigUnderruns[] = {10, 10, 10, 10, -712, 10, 10, 10,
+                                         -1311, 10, 10, 10};
+static const int64 kMixedUnderruns[] = {31, -64, 4, 15, 9, 26, -53, 5,  8, -9,
+                                        7,  9, 32, 38, -4, 62, -64, 3};
+
 INSTANTIATE_TEST_CASE_P(
     AudioEncoderTestScenarios,
     AudioEncoderTest,
@@ -212,7 +235,10 @@
         TestScenario(kManyCalls_Mixed2, arraysize(kManyCalls_Mixed2)),
         TestScenario(kManyCalls_Mixed3, arraysize(kManyCalls_Mixed3)),
         TestScenario(kManyCalls_Mixed4, arraysize(kManyCalls_Mixed4)),
-        TestScenario(kManyCalls_Mixed5, arraysize(kManyCalls_Mixed5))));
+        TestScenario(kManyCalls_Mixed5, arraysize(kManyCalls_Mixed5)),
+        TestScenario(kOneBigUnderrun, arraysize(kOneBigUnderrun)),
+        TestScenario(kTwoBigUnderruns, arraysize(kTwoBigUnderruns)),
+        TestScenario(kMixedUnderruns, arraysize(kMixedUnderruns))));
 
 }  // namespace cast
 }  // namespace media
diff --git a/media/cast/audio_sender/audio_sender.cc b/media/cast/audio_sender/audio_sender.cc
index 590010d..c0393b8 100644
--- a/media/cast/audio_sender/audio_sender.cc
+++ b/media/cast/audio_sender/audio_sender.cc
@@ -50,7 +50,7 @@
             NULL,
             audio_config.rtcp_mode,
             base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval),
-            audio_config.sender_ssrc,
+            audio_config.rtp_config.ssrc,
             audio_config.incoming_feedback_ssrc,
             audio_config.rtcp_c_name),
       timers_initialized_(false),
@@ -65,6 +65,16 @@
                                     weak_factory_.GetWeakPtr())));
     cast_initialization_cb_ = audio_encoder_->InitializationResult();
   }
+
+  media::cast::transport::CastTransportAudioConfig transport_config;
+  transport_config.codec = audio_config.codec;
+  transport_config.rtp.config = audio_config.rtp_config;
+  transport_config.frequency = audio_config.frequency;
+  transport_config.channels = audio_config.channels;
+  transport_config.rtp.max_outstanding_frames =
+      audio_config.rtp_config.max_delay_ms / 100 + 1;
+  transport_sender_->InitializeAudio(transport_config);
+
   transport_sender_->SubscribeAudioRtpStatsCallback(
       base::Bind(&AudioSender::StoreStatistics, weak_factory_.GetWeakPtr()));
 }
diff --git a/media/cast/audio_sender/audio_sender_unittest.cc b/media/cast/audio_sender/audio_sender_unittest.cc
index 4e55c4f..047d2e4 100644
--- a/media/cast/audio_sender/audio_sender_unittest.cc
+++ b/media/cast/audio_sender/audio_sender_unittest.cc
@@ -69,9 +69,6 @@
     audio_config_.bitrate = kDefaultAudioEncoderBitrate;
     audio_config_.rtp_config.payload_type = 127;
 
-    transport::CastTransportAudioConfig transport_config;
-    transport_config.base.rtp_config.payload_type = 127;
-    transport_config.channels = 2;
     net::IPEndPoint dummy_endpoint;
 
     transport_sender_.reset(new transport::CastTransportSenderImpl(
@@ -83,7 +80,6 @@
         base::TimeDelta(),
         task_runner_,
         &transport_));
-    transport_sender_->InitializeAudio(transport_config);
     audio_sender_.reset(new AudioSender(
         cast_environment_, audio_config_, transport_sender_.get()));
     task_runner_->RunTasks();
diff --git a/media/cast/cast_config.cc b/media/cast/cast_config.cc
index 14e3795..c470269 100644
--- a/media/cast/cast_config.cc
+++ b/media/cast/cast_config.cc
@@ -22,8 +22,7 @@
 // these classes to centralize the logic?
 
 VideoSenderConfig::VideoSenderConfig()
-    : sender_ssrc(0),
-      incoming_feedback_ssrc(0),
+    : incoming_feedback_ssrc(0),
       rtcp_interval(kDefaultRtcpIntervalMs),
       rtcp_mode(kRtcpReducedSize),
       use_external_encoder(false),
@@ -41,8 +40,7 @@
       number_of_encode_threads(1) {}
 
 AudioSenderConfig::AudioSenderConfig()
-    : sender_ssrc(0),
-      incoming_feedback_ssrc(0),
+    : incoming_feedback_ssrc(0),
       rtcp_interval(kDefaultRtcpIntervalMs),
       rtcp_mode(kRtcpReducedSize),
       use_external_encoder(false),
diff --git a/media/cast/cast_config.h b/media/cast/cast_config.h
index 22f5a64..7172f68 100644
--- a/media/cast/cast_config.h
+++ b/media/cast/cast_config.h
@@ -30,7 +30,7 @@
 struct AudioSenderConfig {
   AudioSenderConfig();
 
-  uint32 sender_ssrc;
+  // The sender ssrc is in rtp_config.ssrc.
   uint32 incoming_feedback_ssrc;
 
   int rtcp_interval;
@@ -49,7 +49,7 @@
 struct VideoSenderConfig {
   VideoSenderConfig();
 
-  uint32 sender_ssrc;
+  // The sender ssrc is in rtp_config.ssrc.
   uint32 incoming_feedback_ssrc;
 
   int rtcp_interval;
diff --git a/media/cast/logging/encoding_event_subscriber_unittest.cc b/media/cast/logging/encoding_event_subscriber_unittest.cc
index 8c919c0..264ae93 100644
--- a/media/cast/logging/encoding_event_subscriber_unittest.cc
+++ b/media/cast/logging/encoding_event_subscriber_unittest.cc
@@ -78,7 +78,7 @@
   // Entry with RTP timestamp 0 should get dropped.
   for (int i = 0; i < 11; i++) {
     cast_environment_->Logging()->InsertFrameEvent(now,
-                                                   kVideoFrameCaptured,
+                                                   kVideoFrameCaptureBegin,
                                                    i * 100,
                                                    /*frame_id*/ 0);
     cast_environment_->Logging()->InsertFrameEvent(now,
@@ -508,12 +508,12 @@
   base::TimeTicks now(testing_clock_->NowTicks());
 
   cast_environment_->Logging()->InsertFrameEvent(now,
-                                                 kVideoFrameCaptured,
+                                                 kVideoFrameCaptureBegin,
                                                  rtp_timestamp,
                                                  /*frame_id*/ 0);
 
   cast_environment_->Logging()->InsertFrameEvent(now,
-                                                 kVideoFrameReceived,
+                                                 kVideoFrameCaptureEnd,
                                                  rtp_timestamp + 30,
                                                  /*frame_id*/ 1);
 
@@ -531,7 +531,7 @@
   rtp_timestamp = 67890;
 
   cast_environment_->Logging()->InsertFrameEvent(now,
-                                                 kVideoFrameCaptured,
+                                                 kVideoFrameCaptureBegin,
                                                  rtp_timestamp,
                                                  /*frame_id*/ 0);
   GetEventsAndReset();
@@ -545,13 +545,13 @@
   base::TimeTicks now(testing_clock_->NowTicks());
 
   cast_environment_->Logging()->InsertFrameEvent(now,
-                                                 kVideoFrameCaptured,
+                                                 kVideoFrameCaptureBegin,
                                                  rtp_timestamp,
                                                  /*frame_id*/ 0);
 
   // RtpTimestamp has now wrapped around.
   cast_environment_->Logging()->InsertFrameEvent(now,
-                                                 kVideoFrameReceived,
+                                                 kVideoFrameCaptureEnd,
                                                  rtp_timestamp + 30,
                                                  /*frame_id*/ 1);
 
diff --git a/media/cast/logging/logging_defines.cc b/media/cast/logging/logging_defines.cc
index 4452d99..bcb9c37 100644
--- a/media/cast/logging/logging_defines.cc
+++ b/media/cast/logging/logging_defines.cc
@@ -25,13 +25,13 @@
     ENUM_TO_STRING(RembBitrate);
     ENUM_TO_STRING(AudioAckSent);
     ENUM_TO_STRING(VideoAckSent);
-    ENUM_TO_STRING(AudioFrameReceived);
-    ENUM_TO_STRING(AudioFrameCaptured);
+    ENUM_TO_STRING(AudioFrameCaptureBegin);
+    ENUM_TO_STRING(AudioFrameCaptureEnd);
     ENUM_TO_STRING(AudioFrameEncoded);
     ENUM_TO_STRING(AudioPlayoutDelay);
     ENUM_TO_STRING(AudioFrameDecoded);
-    ENUM_TO_STRING(VideoFrameCaptured);
-    ENUM_TO_STRING(VideoFrameReceived);
+    ENUM_TO_STRING(VideoFrameCaptureBegin);
+    ENUM_TO_STRING(VideoFrameCaptureEnd);
     ENUM_TO_STRING(VideoFrameSentToEncoder);
     ENUM_TO_STRING(VideoFrameEncoded);
     ENUM_TO_STRING(VideoFrameDecoded);
@@ -58,8 +58,8 @@
     case kRembBitrate:
       return OTHER_EVENT;
     case kAudioAckSent:
-    case kAudioFrameReceived:
-    case kAudioFrameCaptured:
+    case kAudioFrameCaptureBegin:
+    case kAudioFrameCaptureEnd:
     case kAudioFrameEncoded:
     case kAudioPlayoutDelay:
     case kAudioFrameDecoded:
@@ -70,8 +70,8 @@
       return AUDIO_EVENT;
     case kVideoAckReceived:
     case kVideoAckSent:
-    case kVideoFrameCaptured:
-    case kVideoFrameReceived:
+    case kVideoFrameCaptureBegin:
+    case kVideoFrameCaptureEnd:
     case kVideoFrameSentToEncoder:
     case kVideoFrameEncoded:
     case kVideoFrameDecoded:
diff --git a/media/cast/logging/logging_defines.h b/media/cast/logging/logging_defines.h
index 3acf6f9..f1d5c81 100644
--- a/media/cast/logging/logging_defines.h
+++ b/media/cast/logging/logging_defines.h
@@ -25,21 +25,21 @@
   kPacketLoss,
   kJitterMs,
   kVideoAckReceived,  // Sender side frame event.
-  kRembBitrate,  // Generic event. No longer used.
+  kRembBitrate,       // Generic event. No longer used.
   // Receiver side frame events.
   kAudioAckSent,
   kVideoAckSent,
   // Audio sender.
-  kAudioFrameReceived,
-  kAudioFrameCaptured,
+  kAudioFrameCaptureBegin,
+  kAudioFrameCaptureEnd,
   kAudioFrameEncoded,
   // Audio receiver.
   kAudioFrameDecoded,
   kAudioPlayoutDelay,
   // Video sender.
-  kVideoFrameCaptured,
-  kVideoFrameReceived,
-  kVideoFrameSentToEncoder,
+  kVideoFrameCaptureBegin,
+  kVideoFrameCaptureEnd,
+  kVideoFrameSentToEncoder,  // Deprecated
   kVideoFrameEncoded,
   // Video receiver.
   kVideoFrameDecoded,
diff --git a/media/cast/logging/logging_impl_unittest.cc b/media/cast/logging/logging_impl_unittest.cc
index 9cb7171..cced0ac 100644
--- a/media/cast/logging/logging_impl_unittest.cc
+++ b/media/cast/logging/logging_impl_unittest.cc
@@ -52,8 +52,8 @@
   base::TimeTicks now;
   do {
     now = testing_clock_.NowTicks();
-    logging_.InsertFrameEvent(now, kAudioFrameCaptured, rtp_timestamp,
-                               frame_id);
+    logging_.InsertFrameEvent(
+        now, kAudioFrameCaptureBegin, rtp_timestamp, frame_id);
     testing_clock_.Advance(
         base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
     rtp_timestamp += kFrameIntervalMs * 90;
@@ -111,7 +111,10 @@
     int delay = kPlayoutDelayMs +
                 base::RandInt(-kRandomSizeInterval, kRandomSizeInterval);
     logging_.InsertFrameEventWithDelay(
-        testing_clock_.NowTicks(), kAudioFrameCaptured, rtp_timestamp, frame_id,
+        testing_clock_.NowTicks(),
+        kAudioFrameCaptureBegin,
+        rtp_timestamp,
+        frame_id,
         base::TimeDelta::FromMilliseconds(delay));
     testing_clock_.Advance(base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
     rtp_timestamp += kFrameIntervalMs * 90;
@@ -132,8 +135,10 @@
   uint32 frame_id = 0u;
   uint32 num_events = 0u;
   do {
-    logging_.InsertFrameEvent(testing_clock_.NowTicks(), kAudioFrameCaptured,
-                               rtp_timestamp, frame_id);
+    logging_.InsertFrameEvent(testing_clock_.NowTicks(),
+                              kAudioFrameCaptureBegin,
+                              rtp_timestamp,
+                              frame_id);
     ++num_events;
     if (frame_id % 2) {
       logging_.InsertEncodedFrameEvent(testing_clock_.NowTicks(),
@@ -205,9 +210,10 @@
   // Now logging_ has two subscribers.
   logging_.AddRawEventSubscriber(&event_subscriber_2);
 
-  logging_.InsertFrameEvent(testing_clock_.NowTicks(), kAudioFrameCaptured,
-                             /*rtp_timestamp*/ 0u,
-                             /*frame_id*/ 0u);
+  logging_.InsertFrameEvent(testing_clock_.NowTicks(),
+                            kAudioFrameCaptureBegin,
+                            /*rtp_timestamp*/ 0u,
+                            /*frame_id*/ 0u);
 
   std::vector<FrameEvent> frame_events;
   event_subscriber_.GetFrameEventsAndReset(&frame_events);
diff --git a/media/cast/logging/proto/proto_utils.cc b/media/cast/logging/proto/proto_utils.cc
index 6ca194b..90517e1 100644
--- a/media/cast/logging/proto/proto_utils.cc
+++ b/media/cast/logging/proto/proto_utils.cc
@@ -23,13 +23,13 @@
     TO_PROTO_ENUM(kRembBitrate, REMB_BITRATE);
     TO_PROTO_ENUM(kAudioAckSent, AUDIO_ACK_SENT);
     TO_PROTO_ENUM(kVideoAckSent, VIDEO_ACK_SENT);
-    TO_PROTO_ENUM(kAudioFrameReceived, AUDIO_FRAME_RECEIVED);
-    TO_PROTO_ENUM(kAudioFrameCaptured, AUDIO_FRAME_CAPTURED);
+    TO_PROTO_ENUM(kAudioFrameCaptureEnd, AUDIO_FRAME_CAPTURE_END);
+    TO_PROTO_ENUM(kAudioFrameCaptureBegin, AUDIO_FRAME_CAPTURE_BEGIN);
     TO_PROTO_ENUM(kAudioFrameEncoded, AUDIO_FRAME_ENCODED);
     TO_PROTO_ENUM(kAudioPlayoutDelay, AUDIO_PLAYOUT_DELAY);
     TO_PROTO_ENUM(kAudioFrameDecoded, AUDIO_FRAME_DECODED);
-    TO_PROTO_ENUM(kVideoFrameCaptured, VIDEO_FRAME_CAPTURED);
-    TO_PROTO_ENUM(kVideoFrameReceived, VIDEO_FRAME_RECEIVED);
+    TO_PROTO_ENUM(kVideoFrameCaptureBegin, VIDEO_FRAME_CAPTURE_BEGIN);
+    TO_PROTO_ENUM(kVideoFrameCaptureEnd, VIDEO_FRAME_CAPTURE_END);
     TO_PROTO_ENUM(kVideoFrameSentToEncoder, VIDEO_FRAME_SENT_TO_ENCODER);
     TO_PROTO_ENUM(kVideoFrameEncoded, VIDEO_FRAME_ENCODED);
     TO_PROTO_ENUM(kVideoFrameDecoded, VIDEO_FRAME_DECODED);
diff --git a/media/cast/logging/proto/raw_events.proto b/media/cast/logging/proto/raw_events.proto
index 8f232cf..adbd943 100644
--- a/media/cast/logging/proto/raw_events.proto
+++ b/media/cast/logging/proto/raw_events.proto
@@ -19,22 +19,22 @@
   PACKET_LOSS = 2;
   JITTER_MS = 3;
   VIDEO_ACK_RECEIVED = 4;  // Sender side frame event.
-  REMB_BITRATE = 5;  // Generic event. No longer used.
+  REMB_BITRATE = 5;        // Generic event. No longer used.
   // Audio receiver.
   AUDIO_ACK_SENT = 6;
   // Video receiver.
   VIDEO_ACK_SENT = 7;
   // Audio sender.
-  AUDIO_FRAME_RECEIVED = 8;
-  AUDIO_FRAME_CAPTURED = 9;
+  AUDIO_FRAME_CAPTURE_END = 8;
+  AUDIO_FRAME_CAPTURE_BEGIN = 9;
   AUDIO_FRAME_ENCODED = 10;
   // Audio receiver.
   AUDIO_PLAYOUT_DELAY = 11;
   AUDIO_FRAME_DECODED = 12;
   // Video sender.
-  VIDEO_FRAME_CAPTURED = 13;
-  VIDEO_FRAME_RECEIVED = 14;
-  VIDEO_FRAME_SENT_TO_ENCODER = 15;
+  VIDEO_FRAME_CAPTURE_BEGIN = 13;
+  VIDEO_FRAME_CAPTURE_END = 14;
+  VIDEO_FRAME_SENT_TO_ENCODER = 15;  // Deprecated
   VIDEO_FRAME_ENCODED = 16;
   // Video receiver.
   VIDEO_FRAME_DECODED = 17;
diff --git a/media/cast/logging/serialize_deserialize_test.cc b/media/cast/logging/serialize_deserialize_test.cc
index d1d7a4a..b309ced 100644
--- a/media/cast/logging/serialize_deserialize_test.cc
+++ b/media/cast/logging/serialize_deserialize_test.cc
@@ -20,7 +20,7 @@
 namespace {
 
 const media::cast::CastLoggingEvent kVideoFrameEvents[] = {
-    media::cast::kVideoFrameCaptured,      media::cast::kVideoFrameReceived,
+    media::cast::kVideoFrameCaptureBegin,  media::cast::kVideoFrameCaptureEnd,
     media::cast::kVideoFrameSentToEncoder, media::cast::kVideoFrameEncoded,
     media::cast::kVideoFrameDecoded,       media::cast::kVideoRenderDelay};
 
diff --git a/media/cast/logging/stats_event_subscriber.cc b/media/cast/logging/stats_event_subscriber.cc
index 008add1..e292d66 100644
--- a/media/cast/logging/stats_event_subscriber.cc
+++ b/media/cast/logging/stats_event_subscriber.cc
@@ -23,7 +23,8 @@
 const size_t kMaxPacketEventTimeMapSize = 1000;
 
 CastLoggingEvent GetCapturedEvent(EventMediaType media_type) {
-  return media_type == AUDIO_EVENT ? kAudioFrameCaptured : kVideoFrameCaptured;
+  return media_type == AUDIO_EVENT ?
+      kAudioFrameCaptureBegin : kVideoFrameCaptureBegin;
 }
 
 CastLoggingEvent GetEncodedEvent(EventMediaType media_type) {
diff --git a/media/cast/logging/stats_event_subscriber_unittest.cc b/media/cast/logging/stats_event_subscriber_unittest.cc
index 7d6b5c8..90602d5 100644
--- a/media/cast/logging/stats_event_subscriber_unittest.cc
+++ b/media/cast/logging/stats_event_subscriber_unittest.cc
@@ -74,7 +74,7 @@
   base::TimeTicks start_time = sender_clock_->NowTicks();
   for (int i = 0; i < num_frames; i++) {
     cast_environment_->Logging()->InsertFrameEvent(sender_clock_->NowTicks(),
-                                                   kVideoFrameCaptured,
+                                                   kVideoFrameCaptureBegin,
                                                    rtp_timestamp,
                                                    frame_id);
 
@@ -220,7 +220,7 @@
   base::TimeDelta total_latency;
   for (int i = 0; i < num_frames; i++) {
     cast_environment_->Logging()->InsertFrameEvent(sender_clock_->NowTicks(),
-                                                   kVideoFrameCaptured,
+                                                   kVideoFrameCaptureBegin,
                                                    rtp_timestamp,
                                                    frame_id);
 
diff --git a/media/cast/rtcp/receiver_rtcp_event_subscriber_unittest.cc b/media/cast/rtcp/receiver_rtcp_event_subscriber_unittest.cc
index 0a8852f..aa0d8fa 100644
--- a/media/cast/rtcp/receiver_rtcp_event_subscriber_unittest.cc
+++ b/media/cast/rtcp/receiver_rtcp_event_subscriber_unittest.cc
@@ -75,12 +75,14 @@
         /*max_packet_id*/ 10u, /*size*/ 128u);
 
     // Unrelated events
-    cast_environment_->Logging()->InsertFrameEvent(
-        testing_clock_->NowTicks(), kVideoFrameReceived, /*rtp_timestamp*/ 100u,
-        /*frame_id*/ 1u);
-    cast_environment_->Logging()->InsertFrameEvent(
-        testing_clock_->NowTicks(), kAudioFrameReceived, /*rtp_timestamp*/ 100u,
-        /*frame_id*/ 1u);
+    cast_environment_->Logging()->InsertFrameEvent(testing_clock_->NowTicks(),
+                                                   kVideoFrameCaptureEnd,
+                                                   /*rtp_timestamp*/ 100u,
+                                                   /*frame_id*/ 1u);
+    cast_environment_->Logging()->InsertFrameEvent(testing_clock_->NowTicks(),
+                                                   kAudioFrameCaptureEnd,
+                                                   /*rtp_timestamp*/ 100u,
+                                                   /*frame_id*/ 1u);
   }
 
   base::SimpleTestTickClock* testing_clock_;  // Owned by CastEnvironment.
diff --git a/media/cast/rtcp/rtcp.cc b/media/cast/rtcp/rtcp.cc
index 5e7c4fe..234a1e9 100644
--- a/media/cast/rtcp/rtcp.cc
+++ b/media/cast/rtcp/rtcp.cc
@@ -123,8 +123,8 @@
       switch (it->frame_status) {
         case transport::kRtcpSenderFrameStatusDroppedByFlowControl:
           // A frame that have been dropped by the flow control would have
-          // kVideoFrameCaptured as its last event in the log.
-          log_event = kVideoFrameCaptured;
+          // kVideoFrameCaptureBegin as its last event in the log.
+          log_event = kVideoFrameCaptureBegin;
           break;
         case transport::kRtcpSenderFrameStatusDroppedByEncoder:
           // A frame that have been dropped by the encoder would have
diff --git a/media/cast/rtcp/rtcp_receiver.cc b/media/cast/rtcp/rtcp_receiver.cc
index 8c0e593..9345d58 100644
--- a/media/cast/rtcp/rtcp_receiver.cc
+++ b/media/cast/rtcp/rtcp_receiver.cc
@@ -10,35 +10,11 @@
 
 namespace {
 
-media::cast::CastLoggingEvent TranslateToLogEventFromWireFormat(uint8 event) {
-  switch (event) {
-    case 1:
-      return media::cast::kAudioAckSent;
-    case 2:
-      return media::cast::kAudioPlayoutDelay;
-    case 3:
-      return media::cast::kAudioFrameDecoded;
-    case 4:
-      return media::cast::kAudioPacketReceived;
-    case 5:
-      return media::cast::kVideoAckSent;
-    case 6:
-      return media::cast::kVideoFrameDecoded;
-    case 7:
-      return media::cast::kVideoRenderDelay;
-    case 8:
-      return media::cast::kVideoPacketReceived;
-    case 9:
-      return media::cast::kDuplicateAudioPacketReceived;
-    case 10:
-      return media::cast::kDuplicateVideoPacketReceived;
-    default:
-      // If the sender adds new log messages we will end up here until we add
-      // the new messages in the receiver.
-      VLOG(1) << "Unexpected log message received: " << static_cast<int>(event);
-      NOTREACHED();
-      return media::cast::kUnknown;
-  }
+bool IsRtcpPacketEvent(media::cast::CastLoggingEvent event_type) {
+  return event_type == media::cast::kAudioPacketReceived ||
+         event_type == media::cast::kVideoPacketReceived ||
+         event_type == media::cast::kDuplicateAudioPacketReceived ||
+         event_type == media::cast::kDuplicateVideoPacketReceived;
 }
 
 media::cast::transport::RtcpSenderFrameStatus
@@ -61,15 +37,26 @@
   }
 }
 
-// A receiver event is identified by frame RTP timestamp, event timestamp and
-// event type.
-size_t HashReceiverEvent(uint32 frame_rtp_timestamp,
-                         const base::TimeTicks& event_timestamp,
-                         media::cast::CastLoggingEvent event_type) {
+// A receiver frame event is identified by frame RTP timestamp, event timestamp
+// and event type.
+// A receiver packet event is identified by all of the above plus packet id.
+// The key format is as follows:
+// First uint64:
+//   bits 0-11: zeroes (unused).
+//   bits 12-15: event type ID.
+//   bits 16-31: packet ID if packet event, 0 otherwise.
+//   bits 32-63: RTP timestamp.
+// Second uint64:
+//   bits 0-63: event TimeTicks internal value.
+std::pair<uint64, uint64> GetReceiverEventKey(
+    uint32 frame_rtp_timestamp, const base::TimeTicks& event_timestamp,
+    uint8 event_type, uint16 packet_id_or_zero) {
   uint64 value1 = event_type;
+  value1 <<= 16;
+  value1 |= packet_id_or_zero;
   value1 <<= 32;
   value1 |= frame_rtp_timestamp;
-  return base::HashInts64(
+  return std::make_pair(
       value1, static_cast<uint64>(event_timestamp.ToInternalValue()));
 }
 
@@ -490,8 +477,10 @@
     RtcpReceiverEventLogMessages* event_log_messages) {
   const RtcpField& rtcp_field = rtcp_parser->Field();
 
-  const CastLoggingEvent event_type =
-      TranslateToLogEventFromWireFormat(rtcp_field.cast_receiver_log.event);
+  const uint8 event = rtcp_field.cast_receiver_log.event;
+  const CastLoggingEvent event_type = TranslateToLogEventFromWireFormat(event);
+  uint16 packet_id = IsRtcpPacketEvent(event_type) ?
+      rtcp_field.cast_receiver_log.delay_delta_or_packet_id.packet_id : 0;
   const base::TimeTicks event_timestamp =
       base::TimeTicks() +
       base::TimeDelta::FromMilliseconds(
@@ -503,21 +492,19 @@
   // a queue and a set of events. We enqueue every new event and insert it
   // into the set. When the queue becomes too big we remove the oldest event
   // from both the queue and the set.
-  // Different events may have the same hash value. That's okay because full
-  // accuracy is not important in this case.
-  const size_t event_hash =
-      HashReceiverEvent(frame_rtp_timestamp, event_timestamp, event_type);
-  if (receiver_event_hash_set_.find(event_hash) !=
-      receiver_event_hash_set_.end()) {
+  ReceiverEventKey key =
+      GetReceiverEventKey(
+          frame_rtp_timestamp, event_timestamp, event, packet_id);
+  if (receiver_event_key_set_.find(key) != receiver_event_key_set_.end()) {
     return;
   } else {
-    receiver_event_hash_set_.insert(event_hash);
-    receiver_event_hash_queue_.push(event_hash);
+    receiver_event_key_set_.insert(key);
+    receiver_event_key_queue_.push(key);
 
-    if (receiver_event_hash_queue_.size() > receiver_event_history_size_) {
-      const size_t oldest_hash = receiver_event_hash_queue_.front();
-      receiver_event_hash_queue_.pop();
-      receiver_event_hash_set_.erase(oldest_hash);
+    if (receiver_event_key_queue_.size() > receiver_event_history_size_) {
+      const ReceiverEventKey oldest_key = receiver_event_key_queue_.front();
+      receiver_event_key_queue_.pop();
+      receiver_event_key_set_.erase(oldest_key);
     }
   }
 
diff --git a/media/cast/rtcp/rtcp_receiver.h b/media/cast/rtcp/rtcp_receiver.h
index 2e88246..c8b6435 100644
--- a/media/cast/rtcp/rtcp_receiver.h
+++ b/media/cast/rtcp/rtcp_receiver.h
@@ -123,8 +123,9 @@
 
   // Maintains a history of receiver events.
   size_t receiver_event_history_size_;
-  base::hash_set<size_t> receiver_event_hash_set_;
-  std::queue<size_t> receiver_event_hash_queue_;
+  typedef std::pair<uint64, uint64> ReceiverEventKey;
+  base::hash_set<ReceiverEventKey> receiver_event_key_set_;
+  std::queue<ReceiverEventKey> receiver_event_key_queue_;
 
   DISALLOW_COPY_AND_ASSIGN(RtcpReceiver);
 };
diff --git a/media/cast/rtcp/rtcp_receiver_unittest.cc b/media/cast/rtcp/rtcp_receiver_unittest.cc
index 8e8e4f9..74a60dc 100644
--- a/media/cast/rtcp/rtcp_receiver_unittest.cc
+++ b/media/cast/rtcp/rtcp_receiver_unittest.cc
@@ -511,6 +511,12 @@
   event_log.event_timestamp = testing_clock.NowTicks();
   event_log.packet_id = kLostPacketId1;
   frame_log.event_log_messages_.push_back(event_log);
+
+  event_log.type = kVideoPacketReceived;
+  event_log.event_timestamp = testing_clock.NowTicks();
+  event_log.packet_id = kLostPacketId2;
+  frame_log.event_log_messages_.push_back(event_log);
+
   receiver_log.push_back(frame_log);
 
   cast_log_verification.SetExpectedReceiverLog(receiver_log);
@@ -519,14 +525,16 @@
   p.AddRr(kSenderSsrc, 1);
   p.AddRb(kSourceSsrc);
   p.AddReceiverLog(kSenderSsrc);
-  p.AddReceiverFrameLog(kRtpTimestamp, 2, kTimeBaseMs);
-  p.AddReceiverEventLog(kDelayDeltaMs, 5, 0);
-  p.AddReceiverEventLog(kLostPacketId1, 8, kTimeDelayMs);
+  p.AddReceiverFrameLog(kRtpTimestamp, 3, kTimeBaseMs);
+  p.AddReceiverEventLog(kDelayDeltaMs, kVideoAckSent, 0);
+  p.AddReceiverEventLog(kLostPacketId1, kVideoPacketReceived, kTimeDelayMs);
+  p.AddReceiverEventLog(kLostPacketId2, kVideoPacketReceived, kTimeDelayMs);
 
   // Adds duplicated receiver event.
-  p.AddReceiverFrameLog(kRtpTimestamp, 2, kTimeBaseMs);
-  p.AddReceiverEventLog(kDelayDeltaMs, 5, 0);
-  p.AddReceiverEventLog(kLostPacketId1, 8, kTimeDelayMs);
+  p.AddReceiverFrameLog(kRtpTimestamp, 3, kTimeBaseMs);
+  p.AddReceiverEventLog(kDelayDeltaMs, kVideoAckSent, 0);
+  p.AddReceiverEventLog(kLostPacketId1, kVideoPacketReceived, kTimeDelayMs);
+  p.AddReceiverEventLog(kLostPacketId2, kVideoPacketReceived, kTimeDelayMs);
 
   EXPECT_CALL(mock_rtt_feedback_,
               OnReceivedDelaySinceLastReport(
@@ -574,7 +582,7 @@
   p.AddReceiverLog(kSenderSsrc);
   for (int i = 0; i < 100; ++i) {
     p.AddReceiverFrameLog(kRtpTimestamp, 1, kTimeBaseMs + i * kTimeDelayMs);
-    p.AddReceiverEventLog(kDelayDeltaMs, 5, 0);
+    p.AddReceiverEventLog(kDelayDeltaMs, kVideoAckSent, 0);
   }
 
   EXPECT_CALL(mock_rtt_feedback_,
diff --git a/media/cast/rtcp/rtcp_sender.cc b/media/cast/rtcp/rtcp_sender.cc
index a95e1de..ba1a079 100644
--- a/media/cast/rtcp/rtcp_sender.cc
+++ b/media/cast/rtcp/rtcp_sender.cc
@@ -25,36 +25,6 @@
 // 12 bits.
 const int64 kMaxWireFormatTimeDeltaMs = INT64_C(0xfff);
 
-// Converts a log event type to an integer value.
-// NOTE: We have only allocated 4 bits to represent the type of event over the
-// wire. Therefore, this function can only return values from 0 to 15.
-int ConvertEventTypeToWireFormat(const CastLoggingEvent& event) {
-  switch (event) {
-    case kAudioAckSent:
-      return 1;
-    case kAudioPlayoutDelay:
-      return 2;
-    case kAudioFrameDecoded:
-      return 3;
-    case kAudioPacketReceived:
-      return 4;
-    case kVideoAckSent:
-      return 5;
-    case kVideoFrameDecoded:
-      return 6;
-    case kVideoRenderDelay:
-      return 7;
-    case kVideoPacketReceived:
-      return 8;
-    case kDuplicateAudioPacketReceived:
-      return 9;
-    case kDuplicateVideoPacketReceived:
-      return 10;
-    default:
-      return 0;  // Not an interesting event.
-  }
-}
-
 uint16 MergeEventTypeAndTimestampForWireFormat(
     const CastLoggingEvent& event,
     const base::TimeDelta& time_delta) {
diff --git a/media/cast/rtcp/rtcp_sender_unittest.cc b/media/cast/rtcp/rtcp_sender_unittest.cc
index 0d0a686..6746a68 100644
--- a/media/cast/rtcp/rtcp_sender_unittest.cc
+++ b/media/cast/rtcp/rtcp_sender_unittest.cc
@@ -273,8 +273,8 @@
 
   p.AddReceiverLog(kSendingSsrc);
   p.AddReceiverFrameLog(kRtpTimestamp, 2, kTimeBaseMs);
-  p.AddReceiverEventLog(0, 5, 0);
-  p.AddReceiverEventLog(kLostPacketId1, 8, kTimeDelayMs);
+  p.AddReceiverEventLog(0, kVideoAckSent, 0);
+  p.AddReceiverEventLog(kLostPacketId1, kVideoPacketReceived, kTimeDelayMs);
 
   test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
 
@@ -335,7 +335,8 @@
       kTimeBaseMs + (kRtcpMaxReceiverLogMessages - num_events) * kTimeDelayMs);
   for (int i = 0; i < num_events; i++) {
     p.AddReceiverEventLog(
-        kLostPacketId1, 8, static_cast<uint16>(kTimeDelayMs * i));
+        kLostPacketId1, kVideoPacketReceived,
+        static_cast<uint16>(kTimeDelayMs * i));
   }
 
   test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
@@ -399,7 +400,7 @@
        i < kRtcpMaxReceiverLogMessages;
        ++i) {
     p.AddReceiverFrameLog(kRtpTimestamp + i, 1, kTimeBaseMs + i * kTimeDelayMs);
-    p.AddReceiverEventLog(0, 5, 0);
+    p.AddReceiverEventLog(0, kVideoAckSent, 0);
   }
   test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
 
@@ -450,7 +451,7 @@
   const int kTimeBetweenEventsMs = 410;
   p.AddReceiverFrameLog(kRtpTimestamp, 10, kTimeBaseMs + kTimeBetweenEventsMs);
   for (int i = 0; i < 10; ++i) {
-    p.AddReceiverEventLog(0, 5, i * kTimeBetweenEventsMs);
+    p.AddReceiverEventLog(0, kVideoAckSent, i * kTimeBetweenEventsMs);
   }
   test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
 
@@ -505,17 +506,17 @@
           kRtpTimestamp,
           1,
           time_base_ms - kSecondRedundancyOffset * kTimeBetweenEventsMs);
-      p.AddReceiverEventLog(0, 5, 0);
+      p.AddReceiverEventLog(0, kVideoAckSent, 0);
     }
     if (i >= kFirstRedundancyOffset) {
       p.AddReceiverFrameLog(
           kRtpTimestamp,
           1,
           time_base_ms - kFirstRedundancyOffset * kTimeBetweenEventsMs);
-      p.AddReceiverEventLog(0, 5, 0);
+      p.AddReceiverEventLog(0, kVideoAckSent, 0);
     }
     p.AddReceiverFrameLog(kRtpTimestamp, 1, time_base_ms);
-    p.AddReceiverEventLog(0, 5, 0);
+    p.AddReceiverEventLog(0, kVideoAckSent, 0);
 
     test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
 
diff --git a/media/cast/rtcp/rtcp_utility.cc b/media/cast/rtcp/rtcp_utility.cc
index fd86e8e..da6ef9d 100644
--- a/media/cast/rtcp/rtcp_utility.cc
+++ b/media/cast/rtcp/rtcp_utility.cc
@@ -1051,5 +1051,63 @@
   return true;
 }
 
+uint8 ConvertEventTypeToWireFormat(CastLoggingEvent event) {
+  switch (event) {
+    case kAudioAckSent:
+      return 1;
+    case kAudioPlayoutDelay:
+      return 2;
+    case kAudioFrameDecoded:
+      return 3;
+    case kAudioPacketReceived:
+      return 4;
+    case kVideoAckSent:
+      return 5;
+    case kVideoFrameDecoded:
+      return 6;
+    case kVideoRenderDelay:
+      return 7;
+    case kVideoPacketReceived:
+      return 8;
+    case kDuplicateAudioPacketReceived:
+      return 9;
+    case kDuplicateVideoPacketReceived:
+      return 10;
+    default:
+      return 0;  // Not an interesting event.
+  }
+}
+
+CastLoggingEvent TranslateToLogEventFromWireFormat(uint8 event) {
+  switch (event) {
+    case 1:
+      return media::cast::kAudioAckSent;
+    case 2:
+      return media::cast::kAudioPlayoutDelay;
+    case 3:
+      return media::cast::kAudioFrameDecoded;
+    case 4:
+      return media::cast::kAudioPacketReceived;
+    case 5:
+      return media::cast::kVideoAckSent;
+    case 6:
+      return media::cast::kVideoFrameDecoded;
+    case 7:
+      return media::cast::kVideoRenderDelay;
+    case 8:
+      return media::cast::kVideoPacketReceived;
+    case 9:
+      return media::cast::kDuplicateAudioPacketReceived;
+    case 10:
+      return media::cast::kDuplicateVideoPacketReceived;
+    default:
+      // If the sender adds new log messages we will end up here until we add
+      // the new messages in the receiver.
+      VLOG(1) << "Unexpected log message received: " << static_cast<int>(event);
+      NOTREACHED();
+      return media::cast::kUnknown;
+  }
+}
+
 }  // namespace cast
 }  // namespace media
diff --git a/media/cast/rtcp/rtcp_utility.h b/media/cast/rtcp/rtcp_utility.h
index 8d6d00e..fa85744 100644
--- a/media/cast/rtcp/rtcp_utility.h
+++ b/media/cast/rtcp/rtcp_utility.h
@@ -7,6 +7,7 @@
 
 #include "media/cast/cast_config.h"
 #include "media/cast/cast_defines.h"
+#include "media/cast/logging/logging_defines.h"
 #include "media/cast/rtcp/rtcp_defines.h"
 
 namespace media {
@@ -343,6 +344,14 @@
   DISALLOW_COPY_AND_ASSIGN(RtcpParser);
 };
 
+// Converts a log event type to an integer value.
+// NOTE: We have only allocated 4 bits to represent the type of event over the
+// wire. Therefore, this function can only return values from 0 to 15.
+uint8 ConvertEventTypeToWireFormat(CastLoggingEvent event);
+
+// The inverse of |ConvertEventTypeToWireFormat()|.
+CastLoggingEvent TranslateToLogEventFromWireFormat(uint8 event);
+
 }  // namespace cast
 }  // namespace media
 
diff --git a/media/cast/rtcp/sender_rtcp_event_subscriber.cc b/media/cast/rtcp/sender_rtcp_event_subscriber.cc
index f00ca3a..05bcf3b 100644
--- a/media/cast/rtcp/sender_rtcp_event_subscriber.cc
+++ b/media/cast/rtcp/sender_rtcp_event_subscriber.cc
@@ -25,7 +25,7 @@
 void SenderRtcpEventSubscriber::OnReceiveFrameEvent(
     const FrameEvent& frame_event) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  if (frame_event.type != kVideoFrameCaptured &&
+  if (frame_event.type != kVideoFrameCaptureBegin &&
       frame_event.type != kVideoFrameSentToEncoder &&
       frame_event.type != kVideoFrameEncoded) {
     // Not interested in other events.
@@ -48,7 +48,7 @@
     // We already have this frame (RTP timestamp) in our map.
     // Only update events that are later in the chain.
     // This is due to that events can be reordered on the wire.
-    if (frame_event.type == kVideoFrameCaptured) {
+    if (frame_event.type == kVideoFrameCaptureBegin) {
       return;  // First event in chain can not be late by definition.
     }
 
diff --git a/media/cast/rtcp/sender_rtcp_event_subscriber_unittest.cc b/media/cast/rtcp/sender_rtcp_event_subscriber_unittest.cc
index 3850e80..95f2306 100644
--- a/media/cast/rtcp/sender_rtcp_event_subscriber_unittest.cc
+++ b/media/cast/rtcp/sender_rtcp_event_subscriber_unittest.cc
@@ -46,10 +46,10 @@
 };
 
 TEST_F(SenderRtcpEventSubscriberTest, InsertEntry) {
-  cast_environment_->Logging()->InsertFrameEvent(testing_clock_->NowTicks(),
-                                                 kVideoFrameCaptured, 100u, 1u);
-  cast_environment_->Logging()->InsertFrameEvent(testing_clock_->NowTicks(),
-                                                 kVideoFrameCaptured, 200u, 2u);
+  cast_environment_->Logging()->InsertFrameEvent(
+      testing_clock_->NowTicks(), kVideoFrameCaptureBegin, 100u, 1u);
+  cast_environment_->Logging()->InsertFrameEvent(
+      testing_clock_->NowTicks(), kVideoFrameCaptureBegin, 200u, 2u);
   cast_environment_->Logging()->InsertFrameEvent(
       testing_clock_->NowTicks(), kVideoFrameSentToEncoder, 100u, 1u);
   cast_environment_->Logging()->InsertFrameEvent(testing_clock_->NowTicks(),
@@ -70,7 +70,7 @@
 
   ++it;
   EXPECT_EQ(200u, it->first);
-  EXPECT_EQ(kVideoFrameCaptured, it->second.type);
+  EXPECT_EQ(kVideoFrameCaptureBegin, it->second.type);
 
   ++it;
   EXPECT_EQ(300u, it->first);
@@ -78,8 +78,8 @@
 }
 
 TEST_F(SenderRtcpEventSubscriberTest, MapReset) {
-  cast_environment_->Logging()->InsertFrameEvent(testing_clock_->NowTicks(),
-                                                 kVideoFrameCaptured, 100u, 1u);
+  cast_environment_->Logging()->InsertFrameEvent(
+      testing_clock_->NowTicks(), kVideoFrameCaptureBegin, 100u, 1u);
 
   RtcpEventMap events;
   event_subscriber_.GetRtcpEventsAndReset(&events);
@@ -93,7 +93,7 @@
 TEST_F(SenderRtcpEventSubscriberTest, DropEventsWhenSizeExceeded) {
   for (uint32 i = 1u; i <= 10u; ++i) {
     cast_environment_->Logging()->InsertFrameEvent(
-        testing_clock_->NowTicks(), kVideoFrameCaptured, i * 10, i);
+        testing_clock_->NowTicks(), kVideoFrameCaptureBegin, i * 10, i);
   }
 
   RtcpEventMap events;
@@ -105,7 +105,7 @@
 
   for (uint32 i = 1u; i <= 11u; ++i) {
     cast_environment_->Logging()->InsertFrameEvent(
-        testing_clock_->NowTicks(), kVideoFrameCaptured, i * 10, i);
+        testing_clock_->NowTicks(), kVideoFrameCaptureBegin, i * 10, i);
   }
 
   event_subscriber_.GetRtcpEventsAndReset(&events);
diff --git a/media/cast/rtcp/test_rtcp_packet_builder.cc b/media/cast/rtcp/test_rtcp_packet_builder.cc
index 8688bd6..a7c5e2c 100644
--- a/media/cast/rtcp/test_rtcp_packet_builder.cc
+++ b/media/cast/rtcp/test_rtcp_packet_builder.cc
@@ -3,7 +3,9 @@
 // found in the LICENSE file.
 
 #include "media/cast/rtcp/test_rtcp_packet_builder.h"
+
 #include "base/logging.h"
+#include "media/cast/rtcp/rtcp_utility.h"
 
 namespace media {
 namespace cast {
@@ -246,9 +248,10 @@
 }
 
 void TestRtcpPacketBuilder::AddReceiverEventLog(uint16 event_data,
-                                                uint8 event_id,
+                                                CastLoggingEvent event,
                                                 uint16 event_timesamp_delta) {
   big_endian_writer_.WriteU16(event_data);
+  uint8 event_id = ConvertEventTypeToWireFormat(event);
   uint16 type_and_delta = static_cast<uint16>(event_id) << 12;
   type_and_delta += event_timesamp_delta & 0x0fff;
   big_endian_writer_.WriteU16(type_and_delta);
diff --git a/media/cast/rtcp/test_rtcp_packet_builder.h b/media/cast/rtcp/test_rtcp_packet_builder.h
index 7aa0fd5..eb4a2b7 100644
--- a/media/cast/rtcp/test_rtcp_packet_builder.h
+++ b/media/cast/rtcp/test_rtcp_packet_builder.h
@@ -87,7 +87,7 @@
                            int num_events,
                            uint32 event_timesamp_base);
   void AddReceiverEventLog(uint16 event_data,
-                           uint8 event_id,
+                           CastLoggingEvent event,
                            uint16 event_timesamp_delta);
 
   scoped_ptr<Packet> GetPacket();
diff --git a/media/cast/test/end2end_unittest.cc b/media/cast/test/end2end_unittest.cc
index d283cc9..4b8f6fe 100644
--- a/media/cast/test/end2end_unittest.cc
+++ b/media/cast/test/end2end_unittest.cc
@@ -466,7 +466,7 @@
                  int audio_sampling_frequency,
                  bool external_audio_decoder,
                  int max_number_of_video_buffers_used) {
-    audio_sender_config_.sender_ssrc = 1;
+    audio_sender_config_.rtp_config.ssrc = 1;
     audio_sender_config_.incoming_feedback_ssrc = 2;
     audio_sender_config_.rtp_config.payload_type = 96;
     audio_sender_config_.use_external_encoder = false;
@@ -477,7 +477,7 @@
 
     audio_receiver_config_.feedback_ssrc =
         audio_sender_config_.incoming_feedback_ssrc;
-    audio_receiver_config_.incoming_ssrc = audio_sender_config_.sender_ssrc;
+    audio_receiver_config_.incoming_ssrc = audio_sender_config_.rtp_config.ssrc;
     audio_receiver_config_.rtp_payload_type =
         audio_sender_config_.rtp_config.payload_type;
     audio_receiver_config_.use_external_decoder = external_audio_decoder;
@@ -488,7 +488,7 @@
     test_receiver_audio_callback_->SetExpectedSamplingFrequency(
         audio_receiver_config_.frequency);
 
-    video_sender_config_.sender_ssrc = 3;
+    video_sender_config_.rtp_config.ssrc = 3;
     video_sender_config_.incoming_feedback_ssrc = 4;
     video_sender_config_.rtp_config.payload_type = 97;
     video_sender_config_.use_external_encoder = false;
@@ -506,20 +506,11 @@
 
     video_receiver_config_.feedback_ssrc =
         video_sender_config_.incoming_feedback_ssrc;
-    video_receiver_config_.incoming_ssrc = video_sender_config_.sender_ssrc;
+    video_receiver_config_.incoming_ssrc = video_sender_config_.rtp_config.ssrc;
     video_receiver_config_.rtp_payload_type =
         video_sender_config_.rtp_config.payload_type;
     video_receiver_config_.use_external_decoder = false;
     video_receiver_config_.codec = video_sender_config_.codec;
-
-    transport_audio_config_.base.ssrc = audio_sender_config_.sender_ssrc;
-    transport_audio_config_.codec = audio_sender_config_.codec;
-    transport_audio_config_.base.rtp_config = audio_sender_config_.rtp_config;
-    transport_audio_config_.frequency = audio_sender_config_.frequency;
-    transport_audio_config_.channels = audio_sender_config_.channels;
-    transport_video_config_.base.ssrc = video_sender_config_.sender_ssrc;
-    transport_video_config_.codec = video_sender_config_.codec;
-    transport_video_config_.base.rtp_config = video_sender_config_.rtp_config;
   }
 
   void FeedAudioFrames(int count, bool will_be_checked) {
@@ -573,8 +564,6 @@
         base::TimeDelta::FromSeconds(1),
         task_runner_,
         &sender_to_receiver_));
-    transport_sender_->InitializeAudio(transport_audio_config_);
-    transport_sender_->InitializeVideo(transport_video_config_);
 
     cast_sender_ =
         CastSender::Create(cast_environment_sender_, transport_sender_.get());
@@ -661,8 +650,6 @@
   VideoReceiverConfig video_receiver_config_;
   AudioSenderConfig audio_sender_config_;
   VideoSenderConfig video_sender_config_;
-  transport::CastTransportAudioConfig transport_audio_config_;
-  transport::CastTransportVideoConfig transport_video_config_;
 
   base::TimeTicks start_time_;
   base::SimpleTestTickClock* testing_clock_sender_;
@@ -982,13 +969,15 @@
 TEST_F(End2EndTest, CryptoVideo) {
   Configure(transport::kVp8, transport::kPcm16, 32000, false, 1);
 
-  transport_video_config_.base.aes_iv_mask =
+  video_sender_config_.rtp_config.aes_iv_mask =
       ConvertFromBase16String("1234567890abcdeffedcba0987654321");
-  transport_video_config_.base.aes_key =
+  video_sender_config_.rtp_config.aes_key =
       ConvertFromBase16String("deadbeefcafeb0b0b0b0cafedeadbeef");
 
-  video_receiver_config_.aes_iv_mask = transport_video_config_.base.aes_iv_mask;
-  video_receiver_config_.aes_key = transport_video_config_.base.aes_key;
+  video_receiver_config_.aes_iv_mask =
+      video_sender_config_.rtp_config.aes_iv_mask;
+  video_receiver_config_.aes_key =
+      video_sender_config_.rtp_config.aes_key;
 
   Create();
 
@@ -1018,13 +1007,15 @@
 TEST_F(End2EndTest, CryptoAudio) {
   Configure(transport::kVp8, transport::kPcm16, 32000, false, 1);
 
-  transport_audio_config_.base.aes_iv_mask =
+  audio_sender_config_.rtp_config.aes_iv_mask =
       ConvertFromBase16String("abcdeffedcba12345678900987654321");
-  transport_audio_config_.base.aes_key =
+    audio_sender_config_.rtp_config.aes_key =
       ConvertFromBase16String("deadbeefcafecafedeadbeefb0b0b0b0");
 
-  audio_receiver_config_.aes_iv_mask = transport_audio_config_.base.aes_iv_mask;
-  audio_receiver_config_.aes_key = transport_audio_config_.base.aes_key;
+  audio_receiver_config_.aes_iv_mask =
+      audio_sender_config_.rtp_config.aes_iv_mask;
+  audio_receiver_config_.aes_key =
+      audio_sender_config_.rtp_config.aes_key;
 
   Create();
 
@@ -1100,21 +1091,17 @@
 
     int expected_event_count_for_frame = 0;
 
-    EXPECT_EQ(1, map_it->second.counter[kVideoFrameCaptured]);
+    EXPECT_EQ(1, map_it->second.counter[kVideoFrameCaptureBegin]);
     expected_event_count_for_frame +=
-        map_it->second.counter[kVideoFrameCaptured];
-
-    EXPECT_EQ(1, map_it->second.counter[kVideoFrameSentToEncoder]);
-    expected_event_count_for_frame +=
-        map_it->second.counter[kVideoFrameSentToEncoder];
+        map_it->second.counter[kVideoFrameCaptureBegin];
 
     EXPECT_EQ(1, map_it->second.counter[kVideoFrameEncoded]);
     expected_event_count_for_frame +=
         map_it->second.counter[kVideoFrameEncoded];
 
-    EXPECT_EQ(1, map_it->second.counter[kVideoFrameReceived]);
+    EXPECT_EQ(1, map_it->second.counter[kVideoFrameCaptureEnd]);
     expected_event_count_for_frame +=
-        map_it->second.counter[kVideoFrameReceived];
+        map_it->second.counter[kVideoFrameCaptureEnd];
 
     EXPECT_EQ(1, map_it->second.counter[kVideoRenderDelay]);
     expected_event_count_for_frame += map_it->second.counter[kVideoRenderDelay];
@@ -1203,7 +1190,6 @@
   std::map<RtpTimestamp, LoggingEventCounts> event_counter_for_frame =
       GetEventCountForFrameEvents(frame_events_);
 
-  int received_count = 0;
   int encoded_count = 0;
 
   // Verify the right number of events were logged for each event type.
@@ -1211,11 +1197,9 @@
            event_counter_for_frame.begin();
        it != event_counter_for_frame.end();
        ++it) {
-    received_count += it->second.counter[kAudioFrameReceived];
     encoded_count += it->second.counter[kAudioFrameEncoded];
   }
 
-  EXPECT_EQ(num_audio_frames_requested, received_count);
   EXPECT_EQ(num_audio_frames_requested, encoded_count);
 
   // Verify that each frame have the expected types of events logged.
@@ -1228,10 +1212,6 @@
 
     int expected_event_count_for_frame = 0;
 
-    EXPECT_EQ(1, map_it->second.counter[kAudioFrameReceived]);
-    expected_event_count_for_frame +=
-        map_it->second.counter[kAudioFrameReceived];
-
     EXPECT_EQ(1, map_it->second.counter[kAudioFrameEncoded]);
     expected_event_count_for_frame +=
         map_it->second.counter[kAudioFrameEncoded];
diff --git a/media/cast/test/sender.cc b/media/cast/test/sender.cc
index 4a30ea9..50074b0 100644
--- a/media/cast/test/sender.cc
+++ b/media/cast/test/sender.cc
@@ -100,7 +100,7 @@
   audio_config.channels = kAudioChannels;
   audio_config.bitrate = 64000;
   audio_config.codec = transport::kOpus;
-  audio_config.sender_ssrc = 1;
+  audio_config.rtp_config.ssrc = 1;
   audio_config.incoming_feedback_ssrc = 2;
   audio_config.rtp_config.payload_type = 127;
   audio_config.rtp_config.max_delay_ms = 300;
@@ -133,7 +133,7 @@
   video_config.max_qp = 40;
 
   // SSRCs and payload type. Don't change them.
-  video_config.sender_ssrc = 11;
+  video_config.rtp_config.ssrc = 11;
   video_config.incoming_feedback_ssrc = 12;
   video_config.rtp_config.payload_type = 96;
   video_config.rtp_config.max_delay_ms = 300;
@@ -575,9 +575,7 @@
               frames_read,
               &avframe->data[0],
               // Note: Not all files have correct values for pkt_pts.
-              base::TimeDelta::FromMilliseconds(avframe->pkt_pts),
-              // TODO(hclam): Give accurate duration based on samples.
-              base::TimeDelta());
+              base::TimeDelta::FromMilliseconds(avframe->pkt_pts));
       audio_algo_.EnqueueBuffer(buffer);
     } while (packet_temp.size > 0);
     avcodec_free_frame(&avframe);
@@ -746,7 +744,9 @@
 
 namespace {
 void UpdateCastTransportStatus(
-    media::cast::transport::CastTransportStatus status) {}
+    media::cast::transport::CastTransportStatus status) {
+  VLOG(21) << "Transport status: " << status;
+}
 
 void LogRawEvents(
     const scoped_refptr<media::cast::CastEnvironment>& cast_environment,
@@ -906,14 +906,8 @@
 
   // Running transport on the main thread.
   // Setting up transport config.
-  media::cast::transport::CastTransportAudioConfig transport_audio_config;
-  media::cast::transport::CastTransportVideoConfig transport_video_config;
   net::IPEndPoint remote_endpoint =
       CreateUDPAddress(remote_ip_address, remote_port);
-  transport_audio_config.base.ssrc = audio_config.sender_ssrc;
-  transport_audio_config.base.rtp_config = audio_config.rtp_config;
-  transport_video_config.base.ssrc = video_config.sender_ssrc;
-  transport_video_config.base.rtp_config = video_config.rtp_config;
 
   // Enable raw event and stats logging.
   // Running transport on the main thread.
@@ -940,8 +934,6 @@
           base::Bind(&LogRawEvents, cast_environment),
           base::TimeDelta::FromSeconds(1),
           io_message_loop.message_loop_proxy());
-  transport_sender->InitializeAudio(transport_audio_config);
-  transport_sender->InitializeVideo(transport_video_config);
 
   // CastSender initialization.
   scoped_ptr<media::cast::CastSender> cast_sender =
diff --git a/media/cast/test/utility/udp_proxy.cc b/media/cast/test/utility/udp_proxy.cc
index eed3744..1132815 100644
--- a/media/cast/test/utility/udp_proxy.cc
+++ b/media/cast/test/utility/udp_proxy.cc
@@ -385,6 +385,24 @@
   return pipe.Pass();
 }
 
+scoped_ptr<PacketPipe> BadNetwork() {
+  scoped_ptr<PacketPipe> pipe;
+  // This represents the buffer on the sender.
+  BuildPipe(&pipe, new Buffer(64 << 10, 5000000)); // 64 kb buf, 5mbit/s
+  BuildPipe(&pipe, new RandomDrop(0.05));  // 5% packet drop
+  BuildPipe(&pipe, new RandomSortedDelay(2E-3, 20E-3, 1));
+  // This represents the buffer on the router.
+  BuildPipe(&pipe, new Buffer(64 << 10, 2000000));  // 64 kb buf, 2mbit/s
+  BuildPipe(&pipe, new ConstantDelay(1E-3));
+  // Random 40ms every other second
+  //  BuildPipe(&pipe, new NetworkGlitchPipe(2, 40E-1));
+  BuildPipe(&pipe, new RandomUnsortedDelay(5E-3));
+  // This represents the buffer on the receiving device.
+  BuildPipe(&pipe, new Buffer(64 << 10, 4000000));  // 64 kb buf, 4mbit/s
+  return pipe.Pass();
+}
+
+
 scoped_ptr<PacketPipe> EvilNetwork() {
   // This represents the buffer on the sender.
   scoped_ptr<PacketPipe> pipe;
@@ -413,7 +431,7 @@
       destination_(destination),
       proxy_thread_("media::cast::test::UdpProxy Thread"),
       to_dest_pipe_(to_dest_pipe.Pass()),
-      from_dest_pipe_(to_dest_pipe.Pass()) {
+      from_dest_pipe_(from_dest_pipe.Pass()) {
     proxy_thread_.StartWithOptions(
         base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
     base::WaitableEvent start_event(false, false);
diff --git a/media/cast/test/utility/udp_proxy.h b/media/cast/test/utility/udp_proxy.h
index 41c686e..9dce0cf 100644
--- a/media/cast/test/utility/udp_proxy.h
+++ b/media/cast/test/utility/udp_proxy.h
@@ -93,8 +93,14 @@
 // good wifi network. ~5mbit, 1% packet loss, ~3ms latency.
 scoped_ptr<PacketPipe> WifiNetwork();
 
+// This method builds a stack of PacketPipes to emulate a
+// bad wifi network. ~2mbit, 5% packet loss, ~7ms latency
+// 40ms dropouts every ~2 seconds. Can reorder packets.
+scoped_ptr<PacketPipe> BadNetwork();
+
 // This method builds a stack of PacketPipes to emulate a crappy wifi network.
 // ~1mbit, 20% packet loss, ~40ms latency and packets can get reordered.
+// 300ms drouputs every ~2 seconds.
 scoped_ptr<PacketPipe> EvilNetwork();
 
 }  // namespace test
diff --git a/media/cast/test/utility/udp_proxy_main.cc b/media/cast/test/utility/udp_proxy_main.cc
index 68a885f..0202d8c 100644
--- a/media/cast/test/utility/udp_proxy_main.cc
+++ b/media/cast/test/utility/udp_proxy_main.cc
@@ -4,6 +4,7 @@
 
 #include <cstdio>
 #include <cstdlib>
+#include <deque>
 #include <string>
 
 #include "base/at_exit.h"
@@ -13,11 +14,112 @@
 #include "base/message_loop/message_loop.h"
 #include "media/cast/test/utility/udp_proxy.h"
 
+base::TimeTicks last_printout;
+
+class ByteCounter {
+ public:
+  ByteCounter() : bytes_(0), packets_(0) {
+    push(base::TimeTicks::Now());
+  }
+
+  base::TimeDelta time_range() {
+    return time_data_.back() - time_data_.front();
+  }
+
+  void push(base::TimeTicks now) {
+    byte_data_.push_back(bytes_);
+    packet_data_.push_back(packets_);
+    time_data_.push_back(now);
+    while (time_range().InSeconds() > 10) {
+      byte_data_.pop_front();
+      packet_data_.pop_front();
+      time_data_.pop_front();
+    }
+  }
+
+  double megabits_per_second() {
+    double megabits = (byte_data_.back() - byte_data_.front()) * 8 / 1E6;
+    return megabits / time_range().InSecondsF();
+  }
+
+  double packets_per_second() {
+    double packets = packet_data_.back()- packet_data_.front();
+    return packets / time_range().InSecondsF();
+  }
+
+  void Increment(uint64 x) {
+    bytes_ += x;
+    packets_ ++;
+  }
+
+ private:
+  uint64 bytes_;
+  uint64 packets_;
+  std::deque<uint64> byte_data_;
+  std::deque<uint64> packet_data_;
+  std::deque<base::TimeTicks> time_data_;
+};
+
+ByteCounter in_pipe_input_counter;
+ByteCounter in_pipe_output_counter;
+ByteCounter out_pipe_input_counter;
+ByteCounter out_pipe_output_counter;
+
+class ByteCounterPipe : public media::cast::test::PacketPipe {
+ public:
+  ByteCounterPipe(ByteCounter* counter) : counter_(counter) {}
+  virtual void Send(scoped_ptr<media::cast::transport::Packet> packet)
+      OVERRIDE {
+    counter_->Increment(packet->size());
+    pipe_->Send(packet.Pass());
+  }
+ private:
+  ByteCounter* counter_;
+};
+
+void SetupByteCounters(scoped_ptr<media::cast::test::PacketPipe>* pipe,
+                       ByteCounter* pipe_input_counter,
+                       ByteCounter* pipe_output_counter) {
+  media::cast::test::PacketPipe* new_pipe =
+      new ByteCounterPipe(pipe_input_counter);
+  new_pipe->AppendToPipe(pipe->Pass());
+  new_pipe->AppendToPipe(
+      scoped_ptr<media::cast::test::PacketPipe>(
+          new ByteCounterPipe(pipe_output_counter)).Pass());
+  pipe->reset(new_pipe);
+}
+
+void CheckByteCounters() {
+  base::TimeTicks now = base::TimeTicks::Now();
+  in_pipe_input_counter.push(now);
+  in_pipe_output_counter.push(now);
+  out_pipe_input_counter.push(now);
+  out_pipe_output_counter.push(now);
+  if ((now - last_printout).InSeconds() >= 5) {
+    fprintf(stderr, "Sending  : %5.2f / %5.2f mbps %6.2f / %6.2f packets / s\n",
+            in_pipe_output_counter.megabits_per_second(),
+            in_pipe_input_counter.megabits_per_second(),
+            in_pipe_output_counter.packets_per_second(),
+            in_pipe_input_counter.packets_per_second());
+    fprintf(stderr, "Receiving: %5.2f / %5.2f mbps %6.2f / %6.2f packets / s\n",
+            out_pipe_output_counter.megabits_per_second(),
+            out_pipe_input_counter.megabits_per_second(),
+            out_pipe_output_counter.packets_per_second(),
+            out_pipe_input_counter.packets_per_second());
+
+    last_printout = now;
+  }
+  base::MessageLoopProxy::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&CheckByteCounters),
+      base::TimeDelta::FromMilliseconds(100));
+}
+
 int main(int argc, char** argv) {
   if (argc < 5) {
     fprintf(stderr,
             "Usage: udp_proxy <localport> <remotehost> <remoteport> <type>\n"
-            "Where type is one of: perfect, wifi, evil\n");
+            "Where type is one of: perfect, wifi, bad, evil\n");
     exit(1);
   }
 
@@ -42,6 +144,9 @@
   } else if (network_type == "wifi") {
     in_pipe = media::cast::test::WifiNetwork().Pass();
     out_pipe = media::cast::test::WifiNetwork().Pass();
+  } else if (network_type == "bad") {
+    in_pipe = media::cast::test::BadNetwork().Pass();
+    out_pipe = media::cast::test::BadNetwork().Pass();
   } else if (network_type == "evil") {
     in_pipe = media::cast::test::EvilNetwork().Pass();
     out_pipe = media::cast::test::EvilNetwork().Pass();
@@ -50,6 +155,10 @@
     exit(1);
   }
 
+  SetupByteCounters(&in_pipe, &in_pipe_input_counter, &in_pipe_output_counter);
+  SetupByteCounters(
+      &out_pipe, &out_pipe_input_counter, &out_pipe_output_counter);
+
   printf("Press Ctrl-C when done.\n");
   scoped_ptr<media::cast::test::UDPProxy> proxy(
       media::cast::test::UDPProxy::Create(local_endpoint,
@@ -57,6 +166,9 @@
                                           in_pipe.Pass(),
                                           out_pipe.Pass(),
                                           NULL));
-  base::MessageLoop().Run();  // Run forever.
+  base::MessageLoop message_loop;
+  last_printout = base::TimeTicks::Now();
+  CheckByteCounters();
+  message_loop.Run();
   return 1;
 }
diff --git a/media/cast/transport/cast_transport_config.cc b/media/cast/transport/cast_transport_config.cc
index cdff2fc..b6dba52 100644
--- a/media/cast/transport/cast_transport_config.cc
+++ b/media/cast/transport/cast_transport_config.cc
@@ -9,19 +9,20 @@
 namespace transport {
 
 namespace {
-const int kDefaultRtpHistoryMs = 1000;
 const int kDefaultRtpMaxDelayMs = 100;
 }  // namespace
 
 RtpConfig::RtpConfig()
-    : history_ms(kDefaultRtpHistoryMs),
+    : ssrc(0),
       max_delay_ms(kDefaultRtpMaxDelayMs),
       payload_type(0) {}
 
-CastTransportBaseConfig::CastTransportBaseConfig()
-    : ssrc(0) {}
+RtpConfig::~RtpConfig() {}
 
-CastTransportBaseConfig::~CastTransportBaseConfig() {}
+CastTransportRtpConfig::CastTransportRtpConfig()
+    : max_outstanding_frames(-1) {}
+
+CastTransportRtpConfig::~CastTransportRtpConfig() {}
 
 CastTransportAudioConfig::CastTransportAudioConfig()
     : codec(kOpus), frequency(0), channels(0) {}
diff --git a/media/cast/transport/cast_transport_config.h b/media/cast/transport/cast_transport_config.h
index cddd6d1..d72d1f8 100644
--- a/media/cast/transport/cast_transport_config.h
+++ b/media/cast/transport/cast_transport_config.h
@@ -36,27 +36,26 @@
 
 struct RtpConfig {
   RtpConfig();
-  int history_ms;  // The time RTP packets are stored for retransmissions.
+  ~RtpConfig();
+  uint32 ssrc;
   int max_delay_ms;
   int payload_type;
-};
-
-// TODO(mikhal): Consider combining this with the cast_sender config.
-struct CastTransportBaseConfig {
-  CastTransportBaseConfig();
-  ~CastTransportBaseConfig();
-
-  uint32 ssrc;
-  RtpConfig rtp_config;
   std::string aes_key;      // Binary string of size kAesKeySize.
   std::string aes_iv_mask;  // Binary string of size kAesBlockSize.
 };
 
+struct CastTransportRtpConfig {
+  CastTransportRtpConfig();
+  ~CastTransportRtpConfig();
+  RtpConfig config;
+  int max_outstanding_frames;
+};
+
 struct CastTransportAudioConfig {
   CastTransportAudioConfig();
   ~CastTransportAudioConfig();
 
-  CastTransportBaseConfig base;
+  CastTransportRtpConfig rtp;
   AudioCodec codec;
   int frequency;
   int channels;
@@ -66,7 +65,7 @@
   CastTransportVideoConfig();
   ~CastTransportVideoConfig();
 
-  CastTransportBaseConfig base;
+  CastTransportRtpConfig rtp;
   VideoCodec codec;
 };
 
diff --git a/media/cast/transport/cast_transport_sender.h b/media/cast/transport/cast_transport_sender.h
index 79abce6..605cd04 100644
--- a/media/cast/transport/cast_transport_sender.h
+++ b/media/cast/transport/cast_transport_sender.h
@@ -12,8 +12,7 @@
 // 2. Create CastSender (accepts CastTransportSender as an input).
 // 3. Call CastTransportSender::SetPacketReceiver to ensure that the packets
 //    received by the CastTransportSender will be sent to the CastSender.
-// 4. Initialize audio and/or video.
-// Steps 3 & 4 can be done interchangeably.
+// Steps 3 can be done interchangeably.
 
 // Destruction: The CastTransportSender is assumed to be valid as long as the
 // CastSender is alive. Therefore the CastSender should be destructed before the
@@ -69,7 +68,7 @@
 
   // Audio/Video initialization.
   // Encoded frames cannot be transmitted until the relevant initialize method
-  // is called.
+  // is called. Usually called by CastSender.
   virtual void InitializeAudio(const CastTransportAudioConfig& config) = 0;
 
   virtual void InitializeVideo(const CastTransportVideoConfig& config) = 0;
diff --git a/media/cast/transport/cast_transport_sender_impl.cc b/media/cast/transport/cast_transport_sender_impl.cc
index 6a60347..d8ab4a4 100644
--- a/media/cast/transport/cast_transport_sender_impl.cc
+++ b/media/cast/transport/cast_transport_sender_impl.cc
@@ -74,7 +74,7 @@
 
 void CastTransportSenderImpl::InitializeAudio(
     const CastTransportAudioConfig& config) {
-  pacer_.RegisterAudioSsrc(config.base.ssrc);
+  pacer_.RegisterAudioSsrc(config.rtp.config.ssrc);
   audio_sender_.reset(new TransportAudioSender(
       config, clock_, transport_task_runner_, &pacer_));
   if (audio_sender_->initialized())
@@ -85,7 +85,7 @@
 
 void CastTransportSenderImpl::InitializeVideo(
     const CastTransportVideoConfig& config) {
-  pacer_.RegisterVideoSsrc(config.base.ssrc);
+  pacer_.RegisterVideoSsrc(config.rtp.config.ssrc);
   video_sender_.reset(new TransportVideoSender(
       config, clock_, transport_task_runner_, &pacer_));
   if (video_sender_->initialized())
diff --git a/media/cast/transport/rtp_sender/packet_storage/packet_storage.cc b/media/cast/transport/rtp_sender/packet_storage/packet_storage.cc
index ea1eb0b..6206d02 100644
--- a/media/cast/transport/rtp_sender/packet_storage/packet_storage.cc
+++ b/media/cast/transport/rtp_sender/packet_storage/packet_storage.cc
@@ -12,49 +12,28 @@
 namespace cast {
 namespace transport {
 
-// Limit the max time delay to avoid frame id wrap around; 256 / 60 fps.
-const int kMaxAllowedTimeStoredMs = 4000;
-
 typedef PacketMap::iterator PacketMapIterator;
-typedef TimeToPacketMap::iterator TimeToPacketIterator;
 
-
-PacketStorage::PacketStorage(base::TickClock* clock, int max_time_stored_ms)
-    : clock_(clock) {
-  max_time_stored_ = base::TimeDelta::FromMilliseconds(max_time_stored_ms);
-  DCHECK_LE(max_time_stored_ms, kMaxAllowedTimeStoredMs) << "Invalid argument";
+PacketStorage::PacketStorage(int stored_frames)
+    : stored_frames_(stored_frames) {
 }
 
 PacketStorage::~PacketStorage() {
 }
 
-void PacketStorage::CleanupOldPackets(base::TimeTicks now) {
-  TimeToPacketIterator time_it = time_to_packet_map_.begin();
+bool PacketStorage::IsValid() const {
+  return stored_frames_ > 0 && stored_frames_ <= kMaxStoredFrames;
+}
 
-  // Check max size.
-  while (time_to_packet_map_.size() >= kMaxStoredPackets) {
-    PacketMapIterator store_it = stored_packets_.find(time_it->second);
-
-    // We should always find the packet.
-    DCHECK(store_it != stored_packets_.end()) << "Invalid state";
-    time_to_packet_map_.erase(time_it);
-    stored_packets_.erase(store_it);
-    time_it = time_to_packet_map_.begin();
-  }
-
-  // Time out old packets.
-  while (time_it != time_to_packet_map_.end()) {
-    if (now < time_it->first + max_time_stored_) {
+void PacketStorage::CleanupOldPackets(uint32 current_frame_id) {
+  uint32 frame_to_remove = current_frame_id - stored_frames_;
+  while (!stored_packets_.empty()) {
+    if (IsOlderFrameId(stored_packets_.begin()->first.first,
+                       frame_to_remove)) {
+      stored_packets_.erase(stored_packets_.begin());
+    } else {
       break;
     }
-    // Packet too old.
-    PacketMapIterator store_it = stored_packets_.find(time_it->second);
-
-    // We should always find the packet.
-    DCHECK(store_it != stored_packets_.end()) << "Invalid state";
-    time_to_packet_map_.erase(time_it);
-    stored_packets_.erase(store_it);
-    time_it = time_to_packet_map_.begin();
   }
 }
 
@@ -62,11 +41,8 @@
                                 uint16 packet_id,
                                 const PacketKey& key,
                                 PacketRef packet) {
-  base::TimeTicks now = clock_->NowTicks();
-  CleanupOldPackets(now);
-
-  // Internally we only use the 8 LSB of the frame id.
-  uint32 index = ((0xff & frame_id) << 16) + packet_id;
+  CleanupOldPackets(frame_id);
+  StorageIndex index(frame_id, packet_id);
   PacketMapIterator it = stored_packets_.find(index);
   if (it != stored_packets_.end()) {
     // We have already saved this.
@@ -74,7 +50,6 @@
     return;
   }
   stored_packets_[index] = std::make_pair(key, packet);
-  time_to_packet_map_.insert(std::make_pair(now, index));
 }
 
 void PacketStorage::GetPackets(
@@ -109,11 +84,10 @@
   }
 }
 
-bool PacketStorage::GetPacket(uint8 frame_id,
-                              uint16 packet_id,
-                              SendPacketVector* packets) {
-  // Internally we only use the 8 LSB of the frame id.
-  uint32 index = (static_cast<uint32>(frame_id) << 16) + packet_id;
+bool PacketStorage::GetPacket32(uint32 frame_id,
+                                uint16 packet_id,
+                                SendPacketVector* packets) {
+  StorageIndex index(frame_id, packet_id);
   PacketMapIterator it = stored_packets_.find(index);
   if (it == stored_packets_.end()) {
     return false;
@@ -137,6 +111,26 @@
   return true;
 }
 
+bool PacketStorage::GetPacket(uint8 frame_id_8bit,
+                              uint16 packet_id,
+                              SendPacketVector* packets) {
+  if (stored_packets_.empty()) {
+    return false;
+  }
+  uint32 last_stored = stored_packets_.rbegin()->first.first;
+  uint32 frame_id_32bit = (last_stored & ~0xFF) | frame_id_8bit;
+  if (IsNewerFrameId(frame_id_32bit, last_stored)) {
+    frame_id_32bit -= 0x100;
+  }
+  DCHECK_EQ(frame_id_8bit, frame_id_32bit & 0xff);
+  DCHECK(IsOlderFrameId(frame_id_32bit, last_stored) &&
+         IsNewerFrameId(frame_id_32bit + stored_frames_ + 1, last_stored))
+      << " 32bit: " << frame_id_32bit
+      << " 8bit: " << static_cast<int>(frame_id_8bit)
+      << " last_stored: " << last_stored;
+  return GetPacket32(frame_id_32bit, packet_id, packets);
+}
+
 }  // namespace transport
 }  // namespace cast
 }  // namespace media
diff --git a/media/cast/transport/rtp_sender/packet_storage/packet_storage.h b/media/cast/transport/rtp_sender/packet_storage/packet_storage.h
index b5981e8..85efc66 100644
--- a/media/cast/transport/rtp_sender/packet_storage/packet_storage.h
+++ b/media/cast/transport/rtp_sender/packet_storage/packet_storage.h
@@ -23,16 +23,25 @@
 namespace transport {
 
 class StoredPacket;
-typedef std::map<uint32, std::pair<PacketKey, PacketRef> > PacketMap;
-typedef std::multimap<base::TimeTicks, uint32> TimeToPacketMap;
+
+// StorageIndex contains {frame_id, packet_id}.
+typedef std::pair<uint32, uint16> StorageIndex;
+typedef std::map<StorageIndex, std::pair<PacketKey, PacketRef> > PacketMap;
+
+// Frame IDs are generally stored as 8-bit values when sent over the
+// wire. This means that having a history longer than 255 frames makes
+// no sense.
+const int kMaxStoredFrames = 255;
 
 class PacketStorage {
  public:
-  static const unsigned int kMaxStoredPackets = 1000;
-
-  PacketStorage(base::TickClock* clock, int max_time_stored_ms);
+  PacketStorage(int stored_frames);
   virtual ~PacketStorage();
 
+  // Returns true if this class is configured correctly.
+  // (stored frames > 0 && stored_frames < kMaxStoredFrames)
+  bool IsValid() const;
+
   void StorePacket(uint32 frame_id,
                    uint16 packet_id,
                    const PacketKey& key,
@@ -44,15 +53,20 @@
       SendPacketVector* packets_to_resend);
 
   // Copies packet into the packet list.
-  bool GetPacket(uint8 frame_id, uint16 packet_id, SendPacketVector* packets);
-
+  bool GetPacket(uint8 frame_id_8bit,
+                 uint16 packet_id,
+                 SendPacketVector* packets);
  private:
-  void CleanupOldPackets(base::TimeTicks now);
+  FRIEND_TEST_ALL_PREFIXES(PacketStorageTest, PacketContent);
 
-  base::TickClock* const clock_;  // Not owned by this class.
-  base::TimeDelta max_time_stored_;
+  // Same as GetPacket, but takes a 32-bit frame id.
+  bool GetPacket32(uint32 frame_id,
+                   uint16 packet_id,
+                   SendPacketVector* packets);
+  void CleanupOldPackets(uint32 current_frame_id);
+
   PacketMap stored_packets_;
-  TimeToPacketMap time_to_packet_map_;
+  int stored_frames_;
 
   DISALLOW_COPY_AND_ASSIGN(PacketStorage);
 };
diff --git a/media/cast/transport/rtp_sender/packet_storage/packet_storage_unittest.cc b/media/cast/transport/rtp_sender/packet_storage/packet_storage_unittest.cc
index ae046f5..a43ae6e 100644
--- a/media/cast/transport/rtp_sender/packet_storage/packet_storage_unittest.cc
+++ b/media/cast/transport/rtp_sender/packet_storage/packet_storage_unittest.cc
@@ -16,117 +16,45 @@
 namespace cast {
 namespace transport {
 
-static const int kMaxDeltaStoredMs = 500;
-static const base::TimeDelta kDeltaBetweenFrames =
-    base::TimeDelta::FromMilliseconds(33);
-
-static const int64 kStartMillisecond = INT64_C(12345678900000);
+static int kStoredFrames = 10;
 
 class PacketStorageTest : public ::testing::Test {
  protected:
-  PacketStorageTest() : packet_storage_(&testing_clock_, kMaxDeltaStoredMs) {
-    testing_clock_.Advance(
-        base::TimeDelta::FromMilliseconds(kStartMillisecond));
+  PacketStorageTest() : packet_storage_(kStoredFrames) {
   }
 
-  base::SimpleTestTickClock testing_clock_;
   PacketStorage packet_storage_;
 
   DISALLOW_COPY_AND_ASSIGN(PacketStorageTest);
 };
 
-TEST_F(PacketStorageTest, TimeOut) {
-  Packet test_123(100, 123);  // 100 insertions of the value 123.
-  SendPacketVector packets;
-  for (uint32 frame_id = 0; frame_id < 30; ++frame_id) {
-    base::TimeTicks frame_tick = testing_clock_.NowTicks();
-    for (uint16 packet_id = 0; packet_id < 10; ++packet_id) {
-      packet_storage_.StorePacket(frame_id,
-                                  packet_id,
-                                  PacedPacketSender::MakePacketKey(frame_tick,
-                                                                   1, // ssrc
-                                                                   packet_id),
-                                  new base::RefCountedData<Packet>(test_123));
-    }
-    testing_clock_.Advance(kDeltaBetweenFrames);
-  }
-
-  // All packets belonging to the first 14 frames is expected to be expired.
-  for (uint32 frame_id = 0; frame_id < 14; ++frame_id) {
-    for (uint16 packet_id = 0; packet_id < 10; ++packet_id) {
-      Packet packet;
-      EXPECT_FALSE(packet_storage_.GetPacket(frame_id, packet_id, &packets));
-    }
-  }
-  // All packets belonging to the next 15 frames is expected to be valid.
-  for (uint32 frame_id = 14; frame_id < 30; ++frame_id) {
-    for (uint16 packet_id = 0; packet_id < 10; ++packet_id) {
-      EXPECT_TRUE(packet_storage_.GetPacket(frame_id, packet_id, &packets));
-      EXPECT_TRUE(packets.front().second->data == test_123);
-    }
-  }
-}
-
-TEST_F(PacketStorageTest, MaxNumberOfPackets) {
-  Packet test_123(100, 123);  // 100 insertions of the value 123.
-  SendPacketVector packets;
-
-  uint32 frame_id = 0;
-  base::TimeTicks frame_tick = testing_clock_.NowTicks();
-  for (uint16 packet_id = 0; packet_id <= PacketStorage::kMaxStoredPackets;
-       ++packet_id) {
-    packet_storage_.StorePacket(frame_id,
-                                packet_id,
-                                PacedPacketSender::MakePacketKey(frame_tick,
-                                                                 1, // ssrc
-                                                                 packet_id),
-                                new base::RefCountedData<Packet>(test_123));
-  }
-  uint16 packet_id = 0;
-  EXPECT_FALSE(packet_storage_.GetPacket(frame_id, packet_id, &packets));
-
-  ++packet_id;
-  for (; packet_id <= PacketStorage::kMaxStoredPackets; ++packet_id) {
-    EXPECT_TRUE(packet_storage_.GetPacket(frame_id, packet_id, &packets));
-    EXPECT_TRUE(packets.back().second->data == test_123);
-  }
-}
-
 TEST_F(PacketStorageTest, PacketContent) {
-  Packet test_123(100, 123);  // 100 insertions of the value 123.
-  Packet test_234(200, 234);  // 200 insertions of the value 234.
-  SendPacketVector packets;
-
-  for (uint32 frame_id = 0; frame_id < 10; ++frame_id) {
-    base::TimeTicks frame_tick = testing_clock_.NowTicks();
-    for (uint16 packet_id = 0; packet_id < 10; ++packet_id) {
-      // Every other packet.
-      if (packet_id % 2 == 0) {
-        packet_storage_.StorePacket(frame_id,
-                                    packet_id,
-                                    PacedPacketSender::MakePacketKey(frame_tick,
-                                                                     1, // ssrc
-                                                                     packet_id),
-                                    new base::RefCountedData<Packet>(test_123));
-      } else {
-        packet_storage_.StorePacket(frame_id,
-                                    packet_id,
-                                    PacedPacketSender::MakePacketKey(frame_tick,
-                                                                     1, // ssrc
-                                                                     packet_id),
-                                    new base::RefCountedData<Packet>(test_234));
-      }
+  base::TimeTicks frame_tick;
+  for (uint32 frame_id = 0; frame_id < 200; ++frame_id) {
+    for (uint16 packet_id = 0; packet_id < 5; ++packet_id) {
+      Packet test_packet(frame_id + 1, packet_id);
+      packet_storage_.StorePacket(
+          frame_id,
+          packet_id,
+          PacedPacketSender::MakePacketKey(frame_tick,
+                                           1, // ssrc
+                                           packet_id),
+          new base::RefCountedData<Packet>(test_packet));
     }
-    testing_clock_.Advance(kDeltaBetweenFrames);
-  }
-  for (uint32 frame_id = 0; frame_id < 10; ++frame_id) {
-    for (uint16 packet_id = 0; packet_id < 10; ++packet_id) {
-      EXPECT_TRUE(packet_storage_.GetPacket(frame_id, packet_id, &packets));
-      // Every other packet.
-      if (packet_id % 2 == 0) {
-        EXPECT_TRUE(packets.back().second->data == test_123);
-      } else {
-        EXPECT_TRUE(packets.back().second->data == test_234);
+
+    for (uint32 f = 0; f <= frame_id; f++) {
+      for (uint16 packet_id = 0; packet_id < 5; ++packet_id) {
+        SendPacketVector packets;
+        if (packet_storage_.GetPacket32(f, packet_id, &packets)) {
+          EXPECT_GT(f + kStoredFrames, frame_id);
+          EXPECT_EQ(f + 1, packets.back().second->data.size());
+          EXPECT_EQ(packet_id, packets.back().second->data[0]);
+          EXPECT_TRUE(packet_storage_.GetPacket(f & 0xff, packet_id, &packets));
+          EXPECT_TRUE(packets.back().second->data ==
+                      packets.front().second->data);
+        } else {
+          EXPECT_LE(f + kStoredFrames, frame_id);
+        }
       }
     }
   }
diff --git a/media/cast/transport/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc b/media/cast/transport/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc
index 1a51b89..5f0edc8 100644
--- a/media/cast/transport/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc
+++ b/media/cast/transport/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc
@@ -26,7 +26,6 @@
 static const int kMaxPacketLength = 1500;
 static const int kSsrc = 0x12345;
 static const unsigned int kFrameSize = 5000;
-static const int kMaxPacketStorageTimeMs = 300;
 static const uint32 kStartFrameId = UINT32_C(0xffffffff);
 }
 
@@ -102,7 +101,7 @@
   RtpPacketizerTest()
       : task_runner_(new test::FakeSingleThreadTaskRunner(&testing_clock_)),
         video_frame_(),
-        packet_storage_(&testing_clock_, kMaxPacketStorageTimeMs) {
+        packet_storage_(200) {
     config_.sequence_number = kSeqNum;
     config_.ssrc = kSsrc;
     config_.payload_type = kPayload;
diff --git a/media/cast/transport/rtp_sender/rtp_sender.cc b/media/cast/transport/rtp_sender/rtp_sender.cc
index 41bb97e..6c479bb 100644
--- a/media/cast/transport/rtp_sender/rtp_sender.cc
+++ b/media/cast/transport/rtp_sender/rtp_sender.cc
@@ -33,26 +33,32 @@
 
 RtpSender::~RtpSender() {}
 
-void RtpSender::InitializeAudio(const CastTransportAudioConfig& config) {
-  storage_.reset(new PacketStorage(clock_, config.base.rtp_config.history_ms));
+bool RtpSender::InitializeAudio(const CastTransportAudioConfig& config) {
+  storage_.reset(new PacketStorage(config.rtp.max_outstanding_frames));
+  if (!storage_->IsValid()) {
+    return false;
+  }
   config_.audio = true;
-  config_.ssrc = config.base.ssrc;
-  config_.payload_type = config.base.rtp_config.payload_type;
+  config_.ssrc = config.rtp.config.ssrc;
+  config_.payload_type = config.rtp.config.payload_type;
   config_.frequency = config.frequency;
   config_.audio_codec = config.codec;
-  packetizer_.reset(
-      new RtpPacketizer(transport_, storage_.get(), config_));
+  packetizer_.reset(new RtpPacketizer(transport_, storage_.get(), config_));
+  return true;
 }
 
-void RtpSender::InitializeVideo(const CastTransportVideoConfig& config) {
-  storage_.reset(new PacketStorage(clock_, config.base.rtp_config.history_ms));
+bool RtpSender::InitializeVideo(const CastTransportVideoConfig& config) {
+  storage_.reset(new PacketStorage(config.rtp.max_outstanding_frames));
+  if (!storage_->IsValid()) {
+    return false;
+  }
   config_.audio = false;
-  config_.ssrc = config.base.ssrc;
-  config_.payload_type = config.base.rtp_config.payload_type;
+  config_.ssrc = config.rtp.config.ssrc;
+  config_.payload_type = config.rtp.config.payload_type;
   config_.frequency = kVideoFrequency;
   config_.video_codec = config.codec;
-  packetizer_.reset(
-      new RtpPacketizer(transport_, storage_.get(), config_));
+  packetizer_.reset(new RtpPacketizer(transport_, storage_.get(), config_));
+  return true;
 }
 
 void RtpSender::IncomingEncodedVideoFrame(const EncodedVideoFrame* video_frame,
@@ -89,6 +95,10 @@
         // Get packet from storage.
         success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend);
 
+        // Check that we got at least one packet.
+        DCHECK(packet_id != 0 || success)
+            << "Failed to resend frame " << static_cast<int>(frame_id);
+
         // Resend packet to the network.
         if (success) {
           VLOG(3) << "Resend " << static_cast<int>(frame_id) << ":"
@@ -108,6 +118,10 @@
         uint16 packet_id = *set_it;
         success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend);
 
+        // Check that we got at least one packet.
+        DCHECK(set_it != packets_set.begin() || success)
+            << "Failed to resend frame " << frame_id;
+
         // Resend packet to the network.
         if (success) {
           VLOG(3) << "Resend " << static_cast<int>(frame_id) << ":"
diff --git a/media/cast/transport/rtp_sender/rtp_sender.h b/media/cast/transport/rtp_sender/rtp_sender.h
index 171ffe2..3fe0182 100644
--- a/media/cast/transport/rtp_sender/rtp_sender.h
+++ b/media/cast/transport/rtp_sender/rtp_sender.h
@@ -41,12 +41,12 @@
   ~RtpSender();
 
   // Initialize audio stack. Audio must be initialized prior to sending encoded
-  // audio frames.
-  void InitializeAudio(const CastTransportAudioConfig& config);
+  // audio frames. Returns false if configuration is invalid.
+  bool InitializeAudio(const CastTransportAudioConfig& config);
 
   // Initialize video stack. Video must be initialized prior to sending encoded
-  // video frames.
-  void InitializeVideo(const CastTransportVideoConfig& config);
+  // video frames. Returns false if configuration is invalid.
+  bool InitializeVideo(const CastTransportVideoConfig& config);
 
   // The video_frame objects ownership is handled by the main cast thread.
   void IncomingEncodedVideoFrame(const EncodedVideoFrame* video_frame,
diff --git a/media/cast/transport/transport/udp_transport.cc b/media/cast/transport/transport/udp_transport.cc
index 578b959..bcce4f7 100644
--- a/media/cast/transport/transport/udp_transport.cc
+++ b/media/cast/transport/transport/udp_transport.cc
@@ -52,6 +52,7 @@
                                      net_log,
                                      net::NetLog::Source())),
       send_pending_(false),
+      receive_pending_(false),
       client_connected_(false),
       status_callback_(status_callback),
       weak_factory_(this) {
@@ -84,7 +85,18 @@
     NOTREACHED() << "Either local or remote address has to be defined.";
   }
 
-  ReceiveNextPacket(net::ERR_IO_PENDING);
+  ScheduleReceiveNextPacket();
+}
+
+void UdpTransport::ScheduleReceiveNextPacket() {
+  DCHECK(io_thread_proxy_->RunsTasksOnCurrentThread());
+  if (!packet_receiver_.is_null() && !receive_pending_) {
+    receive_pending_ = true;
+    io_thread_proxy_->PostTask(FROM_HERE,
+                               base::Bind(&UdpTransport::ReceiveNextPacket,
+                                          weak_factory_.GetWeakPtr(),
+                                          net::ERR_IO_PENDING));
+  }
 }
 
 void UdpTransport::ReceiveNextPacket(int length_or_status) {
@@ -104,16 +116,18 @@
           &recv_addr_,
           base::Bind(&UdpTransport::ReceiveNextPacket,
                      weak_factory_.GetWeakPtr()));
-      if (length_or_status == net::ERR_IO_PENDING)
+      if (length_or_status == net::ERR_IO_PENDING) {
+        receive_pending_ = true;
         return;
+      }
     }
 
     // Note: At this point, either a packet is ready or an error has occurred.
-
     if (length_or_status < 0) {
       VLOG(1) << "Failed to receive packet: Status code is "
-              << length_or_status << ".  Stop receiving packets.";
+              << length_or_status;
       status_callback_.Run(TRANSPORT_SOCKET_ERROR);
+      receive_pending_ = false;
       return;
     }
 
@@ -181,6 +195,8 @@
     status_callback_.Run(TRANSPORT_SOCKET_ERROR);
     return true;
   } else {
+    // Successful send, re-start reading if needed.
+    ScheduleReceiveNextPacket();
     return true;
   }
 }
@@ -195,6 +211,9 @@
   if (result < 0) {
     LOG(ERROR) << "Failed to send packet: " << result << ".";
     status_callback_.Run(TRANSPORT_SOCKET_ERROR);
+  } else {
+    // Successful send, re-start reading if needed.
+    ScheduleReceiveNextPacket();
   }
 
   if (!cb.is_null()) {
diff --git a/media/cast/transport/transport/udp_transport.h b/media/cast/transport/transport/udp_transport.h
index fb00d17..17b0d77 100644
--- a/media/cast/transport/transport/udp_transport.h
+++ b/media/cast/transport/transport/udp_transport.h
@@ -57,6 +57,9 @@
   // response from UdpSocket::RecvFrom().
   void ReceiveNextPacket(int length_or_status);
 
+  // Schedule packet receiving, if needed.
+  void ScheduleReceiveNextPacket();
+
   void OnSent(const scoped_refptr<net::IOBuffer>& buf,
               PacketRef packet,
               const base::Closure& cb,
@@ -67,6 +70,7 @@
   net::IPEndPoint remote_addr_;
   const scoped_ptr<net::UDPSocket> udp_socket_;
   bool send_pending_;
+  bool receive_pending_;
   bool client_connected_;
   scoped_ptr<Packet> next_packet_;
   scoped_refptr<net::WrappedIOBuffer> recv_buf_;
diff --git a/media/cast/transport/transport_audio_sender.cc b/media/cast/transport/transport_audio_sender.cc
index b704e23..3635137 100644
--- a/media/cast/transport/transport_audio_sender.cc
+++ b/media/cast/transport/transport_audio_sender.cc
@@ -20,9 +20,9 @@
     PacedSender* const paced_packet_sender)
     : rtp_sender_(clock, transport_task_runner, paced_packet_sender),
       encryptor_() {
-  rtp_sender_.InitializeAudio(config);
-  initialized_ =
-      encryptor_.Initialize(config.base.aes_key, config.base.aes_iv_mask);
+  initialized_ = rtp_sender_.InitializeAudio(config) &&
+      encryptor_.Initialize(config.rtp.config.aes_key,
+                            config.rtp.config.aes_iv_mask);
 }
 
 TransportAudioSender::~TransportAudioSender() {}
@@ -30,6 +30,9 @@
 void TransportAudioSender::InsertCodedAudioFrame(
     const EncodedAudioFrame* audio_frame,
     const base::TimeTicks& recorded_time) {
+  if (!initialized_) {
+    return;
+  }
   if (encryptor_.initialized()) {
     EncodedAudioFrame encrypted_frame;
     if (!EncryptAudioFrame(*audio_frame, &encrypted_frame)) {
@@ -44,6 +47,9 @@
 bool TransportAudioSender::EncryptAudioFrame(
     const EncodedAudioFrame& audio_frame,
     EncodedAudioFrame* encrypted_frame) {
+  if (!initialized_) {
+    return false;
+  }
   if (!encryptor_.Encrypt(
           audio_frame.frame_id, audio_frame.data, &encrypted_frame->data))
     return false;
@@ -56,6 +62,9 @@
 
 void TransportAudioSender::ResendPackets(
     const MissingFramesAndPacketsMap& missing_frames_and_packets) {
+  if (!initialized_) {
+    return;
+  }
   rtp_sender_.ResendPackets(missing_frames_and_packets);
 }
 
diff --git a/media/cast/transport/transport_video_sender.cc b/media/cast/transport/transport_video_sender.cc
index 1862458..ef120bc 100644
--- a/media/cast/transport/transport_video_sender.cc
+++ b/media/cast/transport/transport_video_sender.cc
@@ -4,8 +4,6 @@
 
 #include "media/cast/transport/transport_video_sender.h"
 
-#include <list>
-
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
@@ -21,13 +19,10 @@
     base::TickClock* clock,
     const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
     PacedSender* const paced_packet_sender)
-    : rtp_max_delay_(base::TimeDelta::FromMilliseconds(
-          config.base.rtp_config.max_delay_ms)),
-      encryptor_(),
-      rtp_sender_(clock, transport_task_runner, paced_packet_sender) {
-  rtp_sender_.InitializeVideo(config);
-  initialized_ =
-      encryptor_.Initialize(config.base.aes_key, config.base.aes_iv_mask);
+    : rtp_sender_(clock, transport_task_runner, paced_packet_sender) {
+  initialized_ = rtp_sender_.InitializeVideo(config) &&
+      encryptor_.Initialize(config.rtp.config.aes_key,
+                            config.rtp.config.aes_iv_mask);
 }
 
 TransportVideoSender::~TransportVideoSender() {}
@@ -35,6 +30,9 @@
 void TransportVideoSender::InsertCodedVideoFrame(
     const EncodedVideoFrame* coded_frame,
     const base::TimeTicks& capture_time) {
+  if (!initialized_) {
+    return;
+  }
   if (encryptor_.initialized()) {
     EncodedVideoFrame encrypted_video_frame;
 
@@ -54,6 +52,9 @@
 bool TransportVideoSender::EncryptVideoFrame(
     const EncodedVideoFrame& video_frame,
     EncodedVideoFrame* encrypted_frame) {
+  if (!initialized_) {
+    return false;
+  }
   if (!encryptor_.Encrypt(
           video_frame.frame_id, video_frame.data, &(encrypted_frame->data)))
     return false;
@@ -68,6 +69,9 @@
 
 void TransportVideoSender::ResendPackets(
     const MissingFramesAndPacketsMap& missing_frames_and_packets) {
+  if (!initialized_) {
+    return;
+  }
   rtp_sender_.ResendPackets(missing_frames_and_packets);
 }
 
diff --git a/media/cast/video_sender/external_video_encoder.cc b/media/cast/video_sender/external_video_encoder.cc
index bbb67e0..9280e53 100644
--- a/media/cast/video_sender/external_video_encoder.cc
+++ b/media/cast/video_sender/external_video_encoder.cc
@@ -401,12 +401,6 @@
     ++skip_count_;
     return false;
   }
-  base::TimeTicks now = cast_environment_->Clock()->NowTicks();
-  cast_environment_->Logging()->InsertFrameEvent(
-      now,
-      kVideoFrameSentToEncoder,
-      GetVideoRtpTimestamp(capture_time),
-      kFrameIdUnknown);
 
   encoder_task_runner_->PostTask(
       FROM_HERE,
diff --git a/media/cast/video_sender/external_video_encoder_unittest.cc b/media/cast/video_sender/external_video_encoder_unittest.cc
index 98e3d3d..1f2e4dd 100644
--- a/media/cast/video_sender/external_video_encoder_unittest.cc
+++ b/media/cast/video_sender/external_video_encoder_unittest.cc
@@ -84,7 +84,7 @@
  protected:
   ExternalVideoEncoderTest()
       : test_video_encoder_callback_(new TestVideoEncoderCallback()) {
-    video_config_.sender_ssrc = 1;
+    video_config_.rtp_config.ssrc = 1;
     video_config_.incoming_feedback_ssrc = 2;
     video_config_.rtp_config.payload_type = 127;
     video_config_.use_external_encoder = true;
diff --git a/media/cast/video_sender/video_encoder_impl.cc b/media/cast/video_sender/video_encoder_impl.cc
index 0ee7ee4..2eceda3 100644
--- a/media/cast/video_sender/video_encoder_impl.cc
+++ b/media/cast/video_sender/video_encoder_impl.cc
@@ -114,12 +114,6 @@
     return false;
   }
 
-  base::TimeTicks now = cast_environment_->Clock()->NowTicks();
-  cast_environment_->Logging()->InsertFrameEvent(
-      now,
-      kVideoFrameSentToEncoder,
-      GetVideoRtpTimestamp(capture_time),
-      kFrameIdUnknown);
   cast_environment_->PostTask(CastEnvironment::VIDEO,
                               FROM_HERE,
                               base::Bind(&EncodeVideoFrameOnEncoderThread,
diff --git a/media/cast/video_sender/video_encoder_impl_unittest.cc b/media/cast/video_sender/video_encoder_impl_unittest.cc
index b4eed6d..0577239 100644
--- a/media/cast/video_sender/video_encoder_impl_unittest.cc
+++ b/media/cast/video_sender/video_encoder_impl_unittest.cc
@@ -65,7 +65,7 @@
  protected:
   VideoEncoderImplTest()
       : test_video_encoder_callback_(new TestVideoEncoderCallback()) {
-    video_config_.sender_ssrc = 1;
+    video_config_.rtp_config.ssrc = 1;
     video_config_.incoming_feedback_ssrc = 2;
     video_config_.rtp_config.payload_type = 127;
     video_config_.use_external_encoder = false;
diff --git a/media/cast/video_sender/video_sender.cc b/media/cast/video_sender/video_sender.cc
index ee0e3d1..07e34d5 100644
--- a/media/cast/video_sender/video_sender.cc
+++ b/media/cast/video_sender/video_sender.cc
@@ -61,6 +61,7 @@
       rtcp_feedback_(new LocalRtcpVideoSenderFeedback(this)),
       last_acked_frame_id_(-1),
       last_sent_frame_id_(-1),
+      frames_in_encoder_(0),
       duplicate_ack_(0),
       last_skip_count_(0),
       current_requested_bitrate_(video_config.start_bitrate),
@@ -88,6 +89,13 @@
         cast_environment, video_config, max_unacked_frames_));
   }
 
+
+  media::cast::transport::CastTransportVideoConfig transport_config;
+  transport_config.codec = video_config.codec;
+  transport_config.rtp.config = video_config.rtp_config;
+  transport_config.rtp.max_outstanding_frames = max_unacked_frames_ + 1;
+  transport_sender_->InitializeVideo(transport_config);
+
   rtcp_.reset(
       new Rtcp(cast_environment_,
                rtcp_feedback_.get(),
@@ -96,7 +104,7 @@
                NULL,
                video_config.rtcp_mode,
                base::TimeDelta::FromMilliseconds(video_config.rtcp_interval),
-               video_config.sender_ssrc,
+               video_config.rtp_config.ssrc,
                video_config.incoming_feedback_ssrc,
                video_config.rtcp_c_name));
   rtcp_->SetCastReceiverEventHistorySize(kReceiverRtcpEventHistorySize);
@@ -136,10 +144,10 @@
 
   RtpTimestamp rtp_timestamp = GetVideoRtpTimestamp(capture_time);
   cast_environment_->Logging()->InsertFrameEvent(
-      capture_time, kVideoFrameCaptured, rtp_timestamp, kFrameIdUnknown);
+      capture_time, kVideoFrameCaptureBegin, rtp_timestamp, kFrameIdUnknown);
   cast_environment_->Logging()->InsertFrameEvent(
       cast_environment_->Clock()->NowTicks(),
-      kVideoFrameReceived,
+      kVideoFrameCaptureEnd,
       rtp_timestamp,
       kFrameIdUnknown);
 
@@ -150,11 +158,13 @@
       "timestamp", capture_time.ToInternalValue(),
       "rtp_timestamp", GetVideoRtpTimestamp(capture_time));
 
-  if (!video_encoder_->EncodeVideoFrame(
+  if (video_encoder_->EncodeVideoFrame(
           video_frame,
           capture_time,
           base::Bind(&VideoSender::SendEncodedVideoFrameMainThread,
                      weak_factory_.GetWeakPtr()))) {
+    frames_in_encoder_++;
+    UpdateFramesInFlight();
   }
 }
 
@@ -168,6 +178,8 @@
             << static_cast<int>(encoded_frame->frame_id);
   }
 
+  DCHECK_GT(frames_in_encoder_, 0);
+  frames_in_encoder_--;
   uint32 frame_id = encoded_frame->frame_id;
   cast_environment_->Logging()->InsertEncodedFrameEvent(
       last_send_time_, kVideoFrameEncoded, encoded_frame->rtp_timestamp,
@@ -226,13 +238,13 @@
   for (RtcpEventMap::iterator it = rtcp_events.begin(); it != rtcp_events.end();
        ++it) {
     CastLoggingEvent event_type = it->second.type;
-    if (event_type == kVideoFrameCaptured ||
+    if (event_type == kVideoFrameCaptureBegin ||
         event_type == kVideoFrameSentToEncoder ||
         event_type == kVideoFrameEncoded) {
       transport::RtcpSenderFrameLogMessage frame_message;
       frame_message.rtp_timestamp = it->first;
       switch (event_type) {
-        case kVideoFrameCaptured:
+        case kVideoFrameCaptureBegin:
           frame_message.frame_status =
               transport::kRtcpSenderFrameStatusDroppedByFlowControl;
           break;
@@ -296,10 +308,14 @@
         VLOG(1) << "ACK timeout resend first key frame";
         ResendFrame(0);
       } else {
-        DCHECK_LE(0, last_acked_frame_id_);
-        uint32 frame_id = static_cast<uint32>(last_acked_frame_id_ + 1);
-        VLOG(1) << "ACK timeout resend frame:" << static_cast<int>(frame_id);
-        ResendFrame(frame_id);
+        if (last_acked_frame_id_ == last_sent_frame_id_) {
+          // Last frame acked, no point in doing anything
+        } else {
+          DCHECK_LE(0, last_acked_frame_id_);
+          uint32 frame_id = static_cast<uint32>(last_acked_frame_id_ + 1);
+          VLOG(1) << "ACK timeout resend frame:" << static_cast<int>(frame_id);
+          ResendFrame(frame_id);
+        }
       }
     }
   }
@@ -346,12 +362,6 @@
   base::TimeDelta min_rtt;
   base::TimeDelta max_rtt;
 
-  // Update delay and max number of frames in flight based on the the new
-  // received target delay.
-  rtp_max_delay_ =
-      base::TimeDelta::FromMilliseconds(cast_feedback.target_delay_ms_);
-  max_unacked_frames_ = 1 + static_cast<uint8>(cast_feedback.target_delay_ms_ *
-                                               max_frame_rate_ / 1000);
   if (rtcp_->Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)) {
     // Don't use a RTT lower than our average.
     rtt = std::max(rtt, avg_rtt);
@@ -443,9 +453,11 @@
     } else {
       frames_in_flight = static_cast<uint32>(last_sent_frame_id_) + 1;
     }
+    frames_in_flight += frames_in_encoder_;
     VLOG(2) << frames_in_flight
             << " Frames in flight; last sent: " << last_sent_frame_id_
-            << " last acked:" << last_acked_frame_id_;
+            << " last acked:" << last_acked_frame_id_
+            << " frames in encoder: " << frames_in_encoder_;
     if (frames_in_flight >= max_unacked_frames_) {
       video_encoder_->SkipNextFrame(true);
       return;
diff --git a/media/cast/video_sender/video_sender.h b/media/cast/video_sender/video_sender.h
index 6baac28..89ff938 100644
--- a/media/cast/video_sender/video_sender.h
+++ b/media/cast/video_sender/video_sender.h
@@ -118,6 +118,7 @@
   uint8 max_unacked_frames_;
   int last_acked_frame_id_;
   int last_sent_frame_id_;
+  int frames_in_encoder_;
   int duplicate_ack_;
   base::TimeTicks last_send_time_;
   base::TimeTicks last_checked_skip_count_time_;
diff --git a/media/cast/video_sender/video_sender_unittest.cc b/media/cast/video_sender/video_sender_unittest.cc
index 99a0809..d8b0740 100644
--- a/media/cast/video_sender/video_sender_unittest.cc
+++ b/media/cast/video_sender/video_sender_unittest.cc
@@ -109,7 +109,6 @@
                             task_runner_,
                             task_runner_,
                             task_runner_);
-    transport::CastTransportVideoConfig transport_config;
     net::IPEndPoint dummy_endpoint;
     transport_sender_.reset(new transport::CastTransportSenderImpl(
         NULL,
@@ -120,7 +119,6 @@
         base::TimeDelta(),
         task_runner_,
         &transport_));
-    transport_sender_->InitializeVideo(transport_config);
   }
 
   virtual ~VideoSenderTest() {}
@@ -136,7 +134,7 @@
 
   void InitEncoder(bool external) {
     VideoSenderConfig video_config;
-    video_config.sender_ssrc = 1;
+    video_config.rtp_config.ssrc = 1;
     video_config.incoming_feedback_ssrc = 2;
     video_config.rtcp_c_name = "video_test@10.1.1.1";
     video_config.rtp_config.payload_type = 127;
diff --git a/media/cdm/json_web_key.cc b/media/cdm/json_web_key.cc
index a6aa885..4b9d822 100644
--- a/media/cdm/json_web_key.cc
+++ b/media/cdm/json_web_key.cc
@@ -121,7 +121,7 @@
 }
 
 bool ExtractKeysFromJWKSet(const std::string& jwk_set, KeyIdAndKeyPairs* keys) {
-  if (!IsStringASCII(jwk_set))
+  if (!base::IsStringASCII(jwk_set))
     return false;
 
   scoped_ptr<base::Value> root(base::JSONReader().ReadToValue(jwk_set));
diff --git a/media/cdm/ppapi/cdm_adapter.cc b/media/cdm/ppapi/cdm_adapter.cc
index 4d8f038..eb40456 100644
--- a/media/cdm/ppapi/cdm_adapter.cc
+++ b/media/cdm/ppapi/cdm_adapter.cc
@@ -9,6 +9,7 @@
 #include "media/cdm/ppapi/cdm_logging.h"
 #include "media/cdm/ppapi/supported_cdm_versions.h"
 #include "ppapi/c/ppb_console.h"
+#include "ppapi/cpp/private/uma_private.h"
 
 #if defined(CHECK_DOCUMENT_URL)
 #include "ppapi/cpp/dev/url_util_dev.h"
@@ -224,6 +225,8 @@
       output_link_mask_(0),
       output_protection_mask_(0),
       query_output_protection_in_progress_(false),
+      uma_for_output_protection_query_reported_(false),
+      uma_for_output_protection_positive_result_reported_(false),
 #endif
       allocator_(this),
       cdm_(NULL),
@@ -841,6 +844,7 @@
           &CdmAdapter::QueryOutputProtectionStatusDone));
   if (result == PP_OK_COMPLETIONPENDING) {
     query_output_protection_in_progress_ = true;
+    ReportOutputProtectionQuery();
     return;
   }
 
@@ -883,6 +887,45 @@
 }
 
 #if defined(OS_CHROMEOS)
+void CdmAdapter::ReportOutputProtectionUMA(OutputProtectionStatus status) {
+  pp::UMAPrivate uma_interface_(this);
+  uma_interface_.HistogramEnumeration(
+      "Media.EME.OutputProtection", status, OUTPUT_PROTECTION_MAX);
+}
+
+void CdmAdapter::ReportOutputProtectionQuery() {
+  if (uma_for_output_protection_query_reported_)
+    return;
+
+  ReportOutputProtectionUMA(OUTPUT_PROTECTION_QUERIED);
+  uma_for_output_protection_query_reported_ = true;
+}
+
+void CdmAdapter::ReportOutputProtectionQueryResult() {
+  if (uma_for_output_protection_positive_result_reported_)
+    return;
+
+  // Report UMAs for output protection query result.
+  uint32_t external_links = (output_link_mask_ & ~cdm::kLinkTypeInternal);
+
+  if (!external_links) {
+    ReportOutputProtectionUMA(OUTPUT_PROTECTION_NO_EXTERNAL_LINK);
+    uma_for_output_protection_positive_result_reported_ = true;
+    return;
+  }
+
+  if ((output_protection_mask_ & external_links) == external_links) {
+    ReportOutputProtectionUMA(
+        OUTPUT_PROTECTION_ALL_EXTERNAL_LINKS_PROTECTED);
+    uma_for_output_protection_positive_result_reported_ = true;
+    return;
+  }
+
+  // Do not report a negative result because it could be a false negative.
+  // Instead, we will calculate number of negatives using the total number of
+  // queries and success results.
+}
+
 void CdmAdapter::SendPlatformChallengeDone(int32_t result) {
   challenge_in_progress_ = false;
 
@@ -927,6 +970,8 @@
   // Return a protection status of none on error.
   if (result != PP_OK)
     output_link_mask_ = output_protection_mask_ = 0;
+  else
+    ReportOutputProtectionQueryResult();
 
   cdm_->OnQueryOutputProtectionStatus(output_link_mask_,
                                       output_protection_mask_);
diff --git a/media/cdm/ppapi/cdm_adapter.h b/media/cdm/ppapi/cdm_adapter.h
index 1a05ada..51f4567 100644
--- a/media/cdm/ppapi/cdm_adapter.h
+++ b/media/cdm/ppapi/cdm_adapter.h
@@ -106,6 +106,14 @@
   virtual cdm::FileIO* CreateFileIO(cdm::FileIOClient* client) OVERRIDE;
 
  private:
+  // These are reported to UMA server. Do not change the existing values!
+  enum OutputProtectionStatus {
+    OUTPUT_PROTECTION_QUERIED = 0,
+    OUTPUT_PROTECTION_NO_EXTERNAL_LINK = 1,
+    OUTPUT_PROTECTION_ALL_EXTERNAL_LINKS_PROTECTED = 2,
+    OUTPUT_PROTECTION_MAX = 3
+  };
+
   typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock;
   typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame;
   typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames;
@@ -165,6 +173,10 @@
 #endif  // !defined(NDEBUG)
 
 #if defined(OS_CHROMEOS)
+  void ReportOutputProtectionUMA(OutputProtectionStatus status);
+  void ReportOutputProtectionQuery();
+  void ReportOutputProtectionQueryResult();
+
   void SendPlatformChallengeDone(int32_t result);
   void EnableProtectionDone(int32_t result);
   void QueryOutputProtectionStatusDone(int32_t result);
@@ -184,6 +196,11 @@
   uint32_t output_link_mask_;
   uint32_t output_protection_mask_;
   bool query_output_protection_in_progress_;
+
+  // Tracks whether an output protection query and a positive query result (no
+  // unprotected external link) have been reported to UMA.
+  bool uma_for_output_protection_query_reported_;
+  bool uma_for_output_protection_positive_result_reported_;
 #endif
 
   PpbBufferAllocator allocator_;
diff --git a/media/ffmpeg/ffmpeg_regression_tests.cc b/media/ffmpeg/ffmpeg_regression_tests.cc
index 0b68fd0..311a28e 100644
--- a/media/ffmpeg/ffmpeg_regression_tests.cc
+++ b/media/ffmpeg/ffmpeg_regression_tests.cc
@@ -323,6 +323,7 @@
 FLAKY_FFMPEG_TEST_CASE(Cr99652, "security/99652.webm");
 FLAKY_FFMPEG_TEST_CASE(Cr100464, "security/100464.webm");
 FLAKY_FFMPEG_TEST_CASE(Cr111342, "security/111342.ogm");
+FLAKY_FFMPEG_TEST_CASE(Cr368980, "security/368980.mp4");
 FLAKY_FFMPEG_TEST_CASE(OGV_0, "security/big_dims.ogv");
 FLAKY_FFMPEG_TEST_CASE(OGV_3, "security/smclock_1_0.ogv");
 FLAKY_FFMPEG_TEST_CASE(OGV_4, "security/smclock.ogv.1.0.ogv");
diff --git a/media/filters/audio_clock.cc b/media/filters/audio_clock.cc
new file mode 100644
index 0000000..0454e85
--- /dev/null
+++ b/media/filters/audio_clock.cc
@@ -0,0 +1,135 @@
+// 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.
+
+#include "media/filters/audio_clock.h"
+
+#include "base/logging.h"
+#include "media/base/buffers.h"
+
+namespace media {
+
+AudioClock::AudioClock(int sample_rate)
+    : sample_rate_(sample_rate), last_endpoint_timestamp_(kNoTimestamp()) {
+}
+
+AudioClock::~AudioClock() {
+}
+
+void AudioClock::WroteAudio(int frames,
+                            int delay_frames,
+                            float playback_rate,
+                            base::TimeDelta timestamp) {
+  CHECK_GT(playback_rate, 0);
+  CHECK(timestamp != kNoTimestamp());
+  DCHECK_GE(frames, 0);
+  DCHECK_GE(delay_frames, 0);
+
+  if (last_endpoint_timestamp_ == kNoTimestamp())
+    PushBufferedAudio(delay_frames, 0, kNoTimestamp());
+
+  TrimBufferedAudioToMatchDelay(delay_frames);
+  PushBufferedAudio(frames, playback_rate, timestamp);
+
+  last_endpoint_timestamp_ = timestamp;
+}
+
+void AudioClock::WroteSilence(int frames, int delay_frames) {
+  DCHECK_GE(frames, 0);
+  DCHECK_GE(delay_frames, 0);
+
+  if (last_endpoint_timestamp_ == kNoTimestamp())
+    PushBufferedAudio(delay_frames, 0, kNoTimestamp());
+
+  TrimBufferedAudioToMatchDelay(delay_frames);
+  PushBufferedAudio(frames, 0, kNoTimestamp());
+}
+
+base::TimeDelta AudioClock::CurrentMediaTimestamp() const {
+  int silence_frames = 0;
+  for (size_t i = 0; i < buffered_audio_.size(); ++i) {
+    // Account for silence ahead of the buffer closest to being played.
+    if (buffered_audio_[i].playback_rate == 0) {
+      silence_frames += buffered_audio_[i].frames;
+      continue;
+    }
+
+    // Multiply by playback rate as frames represent time-scaled audio.
+    return buffered_audio_[i].endpoint_timestamp -
+           base::TimeDelta::FromMicroseconds(
+               ((buffered_audio_[i].frames * buffered_audio_[i].playback_rate) +
+                silence_frames) /
+               sample_rate_ * base::Time::kMicrosecondsPerSecond);
+  }
+
+  // Either:
+  //   1) AudioClock is uninitialziated and we'll return kNoTimestamp()
+  //   2) All previously buffered audio has been replaced by silence,
+  //      meaning media time is now at the last endpoint
+  return last_endpoint_timestamp_;
+}
+
+void AudioClock::TrimBufferedAudioToMatchDelay(int delay_frames) {
+  if (buffered_audio_.empty())
+    return;
+
+  size_t i = buffered_audio_.size() - 1;
+  while (true) {
+    if (buffered_audio_[i].frames <= delay_frames) {
+      // Reached the end before accounting for all of |delay_frames|. This
+      // means we haven't written enough audio data yet to account for hardware
+      // delay. In this case, do nothing.
+      if (i == 0)
+        return;
+
+      // Keep accounting for |delay_frames|.
+      delay_frames -= buffered_audio_[i].frames;
+      --i;
+      continue;
+    }
+
+    // All of |delay_frames| has been accounted for: adjust amount of frames
+    // left in current buffer. All preceeding elements with index < |i| should
+    // be considered played out and hence discarded.
+    buffered_audio_[i].frames = delay_frames;
+    break;
+  }
+
+  // At this point |i| points at what will be the new head of |buffered_audio_|
+  // however if it contains no audio it should be removed as well.
+  if (buffered_audio_[i].frames == 0)
+    ++i;
+
+  buffered_audio_.erase(buffered_audio_.begin(), buffered_audio_.begin() + i);
+}
+
+void AudioClock::PushBufferedAudio(int frames,
+                                   float playback_rate,
+                                   base::TimeDelta endpoint_timestamp) {
+  if (playback_rate == 0)
+    DCHECK(endpoint_timestamp == kNoTimestamp());
+
+  if (frames == 0)
+    return;
+
+  // Avoid creating extra elements where possible.
+  if (!buffered_audio_.empty() &&
+      buffered_audio_.back().playback_rate == playback_rate) {
+    buffered_audio_.back().frames += frames;
+    buffered_audio_.back().endpoint_timestamp = endpoint_timestamp;
+    return;
+  }
+
+  buffered_audio_.push_back(
+      BufferedAudio(frames, playback_rate, endpoint_timestamp));
+}
+
+AudioClock::BufferedAudio::BufferedAudio(int frames,
+                                         float playback_rate,
+                                         base::TimeDelta endpoint_timestamp)
+    : frames(frames),
+      playback_rate(playback_rate),
+      endpoint_timestamp(endpoint_timestamp) {
+}
+
+}  // namespace media
diff --git a/media/filters/audio_clock.h b/media/filters/audio_clock.h
new file mode 100644
index 0000000..a0d8212
--- /dev/null
+++ b/media/filters/audio_clock.h
@@ -0,0 +1,76 @@
+// 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.
+
+#ifndef MEDIA_FILTERS_AUDIO_CLOCK_H_
+#define MEDIA_FILTERS_AUDIO_CLOCK_H_
+
+#include <deque>
+
+#include "base/time/time.h"
+#include "media/base/media_export.h"
+
+namespace media {
+
+// Models a queue of buffered audio in a playback pipeline for use with
+// estimating the amount of delay in wall clock time. Takes changes in playback
+// rate into account to handle scenarios where multiple rates may be present in
+// a playback pipeline with large delay.
+class MEDIA_EXPORT AudioClock {
+ public:
+  explicit AudioClock(int sample_rate);
+  ~AudioClock();
+
+  // |frames| amount of audio data scaled to |playback_rate| was written.
+  // |delay_frames| is the current amount of hardware delay.
+  // |timestamp| is the endpoint media timestamp of the audio data written.
+  void WroteAudio(int frames,
+                  int delay_frames,
+                  float playback_rate,
+                  base::TimeDelta timestamp);
+
+  // |frames| amount of silence was written.
+  // |delay_frames| is the current amount of hardware delay.
+  void WroteSilence(int frames, int delay_frames);
+
+  // Calculates the current media timestamp taking silence and changes in
+  // playback rate into account.
+  base::TimeDelta CurrentMediaTimestamp() const;
+
+  // Returns the last endpoint timestamp provided to WroteAudio().
+  base::TimeDelta last_endpoint_timestamp() const {
+    return last_endpoint_timestamp_;
+  }
+
+ private:
+  void TrimBufferedAudioToMatchDelay(int delay_frames);
+  void PushBufferedAudio(int frames,
+                         float playback_rate,
+                         base::TimeDelta endpoint_timestamp);
+
+  const int sample_rate_;
+
+  // Initially set to kNoTimestamp(), otherwise is the last endpoint timestamp
+  // delivered to WroteAudio(). A copy is kept outside of |buffered_audio_| to
+  // handle the case where all of |buffered_audio_| has been replaced with
+  // silence.
+  base::TimeDelta last_endpoint_timestamp_;
+
+  struct BufferedAudio {
+    BufferedAudio(int frames,
+                  float playback_rate,
+                  base::TimeDelta endpoint_timestamp);
+
+    int frames;
+    float playback_rate;
+    base::TimeDelta endpoint_timestamp;
+  };
+
+  std::deque<BufferedAudio> buffered_audio_;
+
+  DISALLOW_COPY_AND_ASSIGN(AudioClock);
+};
+
+}  // namespace media
+
+#endif  // MEDIA_FILTERS_AUDIO_CLOCK_H_
diff --git a/media/filters/audio_clock_unittest.cc b/media/filters/audio_clock_unittest.cc
new file mode 100644
index 0000000..a924a24
--- /dev/null
+++ b/media/filters/audio_clock_unittest.cc
@@ -0,0 +1,177 @@
+// 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.
+
+#include "media/base/audio_timestamp_helper.h"
+#include "media/base/buffers.h"
+#include "media/filters/audio_clock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+class AudioClockTest : public testing::Test {
+ public:
+  AudioClockTest()
+      : sample_rate_(10),
+        timestamp_helper_(sample_rate_),
+        clock_(sample_rate_) {
+    timestamp_helper_.SetBaseTimestamp(base::TimeDelta());
+  }
+
+  virtual ~AudioClockTest() {}
+
+  void WroteAudio(int frames, int delay_frames, float playback_rate) {
+    timestamp_helper_.AddFrames(static_cast<int>(frames * playback_rate));
+    clock_.WroteAudio(
+        frames, delay_frames, playback_rate, timestamp_helper_.GetTimestamp());
+  }
+
+  void WroteSilence(int frames, int delay_frames) {
+    clock_.WroteSilence(frames, delay_frames);
+  }
+
+  int CurrentMediaTimestampInMilliseconds() {
+    return clock_.CurrentMediaTimestamp().InMilliseconds();
+  }
+
+  int LastEndpointTimestampInMilliseconds() {
+    return clock_.last_endpoint_timestamp().InMilliseconds();
+  }
+
+  const int sample_rate_;
+  AudioTimestampHelper timestamp_helper_;
+  AudioClock clock_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AudioClockTest);
+};
+
+TEST_F(AudioClockTest, TimestampsStartAtNoTimestamp) {
+  EXPECT_EQ(kNoTimestamp(), clock_.CurrentMediaTimestamp());
+  EXPECT_EQ(kNoTimestamp(), clock_.last_endpoint_timestamp());
+}
+
+TEST_F(AudioClockTest, Playback) {
+  // The first time we write data we should expect a negative time matching the
+  // current delay.
+  WroteAudio(10, 20, 1.0);
+  EXPECT_EQ(-2000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(1000, LastEndpointTimestampInMilliseconds());
+
+  // The media time should keep advancing as we write data.
+  WroteAudio(10, 20, 1.0);
+  EXPECT_EQ(-1000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(2000, LastEndpointTimestampInMilliseconds());
+
+  WroteAudio(10, 20, 1.0);
+  EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(3000, LastEndpointTimestampInMilliseconds());
+
+  WroteAudio(10, 20, 1.0);
+  EXPECT_EQ(1000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(4000, LastEndpointTimestampInMilliseconds());
+
+  // Introduce a rate change to slow down time. Current time will keep advancing
+  // by one second until it hits the slowed down audio.
+  WroteAudio(10, 20, 0.5);
+  EXPECT_EQ(2000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(4500, LastEndpointTimestampInMilliseconds());
+
+  WroteAudio(10, 20, 0.5);
+  EXPECT_EQ(3000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(5000, LastEndpointTimestampInMilliseconds());
+
+  WroteAudio(10, 20, 0.5);
+  EXPECT_EQ(4000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(5500, LastEndpointTimestampInMilliseconds());
+
+  WroteAudio(10, 20, 0.5);
+  EXPECT_EQ(4500, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(6000, LastEndpointTimestampInMilliseconds());
+
+  // Introduce a rate change to speed up time. Current time will keep advancing
+  // by half a second until it hits the the sped up audio.
+  WroteAudio(10, 20, 2);
+  EXPECT_EQ(5000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(8000, LastEndpointTimestampInMilliseconds());
+
+  WroteAudio(10, 20, 2);
+  EXPECT_EQ(5500, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(10000, LastEndpointTimestampInMilliseconds());
+
+  WroteAudio(10, 20, 2);
+  EXPECT_EQ(6000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(12000, LastEndpointTimestampInMilliseconds());
+
+  WroteAudio(10, 20, 2);
+  EXPECT_EQ(8000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(14000, LastEndpointTimestampInMilliseconds());
+
+  // Write silence to simulate reaching end of stream.
+  WroteSilence(10, 20);
+  EXPECT_EQ(10000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(14000, LastEndpointTimestampInMilliseconds());
+
+  WroteSilence(10, 20);
+  EXPECT_EQ(12000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(14000, LastEndpointTimestampInMilliseconds());
+
+  WroteSilence(10, 20);
+  EXPECT_EQ(14000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(14000, LastEndpointTimestampInMilliseconds());
+
+  // At this point media time should stop increasing.
+  WroteSilence(10, 20);
+  EXPECT_EQ(14000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(14000, LastEndpointTimestampInMilliseconds());
+}
+
+TEST_F(AudioClockTest, AlternatingAudioAndSilence) {
+  // Buffer #1: [0, 1000)
+  WroteAudio(10, 20, 1.0);
+  EXPECT_EQ(-2000, CurrentMediaTimestampInMilliseconds());
+
+  // Buffer #2: 1000ms of silence
+  WroteSilence(10, 20);
+  EXPECT_EQ(-1000, CurrentMediaTimestampInMilliseconds());
+
+  // Buffer #3: [1000, 2000), buffer #1 is at front
+  WroteAudio(10, 20, 1.0);
+  EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
+
+  // Buffer #4: 1000ms of silence, time shouldn't advance
+  WroteSilence(10, 20);
+  EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
+
+  // Buffer #5: [2000, 3000), buffer #3 is at front
+  WroteAudio(10, 20, 1.0);
+  EXPECT_EQ(1000, CurrentMediaTimestampInMilliseconds());
+}
+
+TEST_F(AudioClockTest, ZeroDelay) {
+  // The first time we write data we should expect the first timestamp
+  // immediately.
+  WroteAudio(10, 0, 1.0);
+  EXPECT_EQ(0, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(1000, LastEndpointTimestampInMilliseconds());
+
+  // Ditto for all subsequent buffers.
+  WroteAudio(10, 0, 1.0);
+  EXPECT_EQ(1000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(2000, LastEndpointTimestampInMilliseconds());
+
+  WroteAudio(10, 0, 1.0);
+  EXPECT_EQ(2000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(3000, LastEndpointTimestampInMilliseconds());
+
+  // Ditto for silence.
+  WroteSilence(10, 0);
+  EXPECT_EQ(3000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(3000, LastEndpointTimestampInMilliseconds());
+
+  WroteSilence(10, 0);
+  EXPECT_EQ(3000, CurrentMediaTimestampInMilliseconds());
+  EXPECT_EQ(3000, LastEndpointTimestampInMilliseconds());
+}
+
+}  // namespace media
diff --git a/media/filters/audio_renderer_algorithm_unittest.cc b/media/filters/audio_renderer_algorithm_unittest.cc
index ed6b6cc..596c8cc 100644
--- a/media/filters/audio_renderer_algorithm_unittest.cc
+++ b/media/filters/audio_renderer_algorithm_unittest.cc
@@ -113,7 +113,6 @@
               1,
               1,
               kFrameSize,
-              kNoTimestamp(),
               kNoTimestamp());
           break;
         case kSampleFormatS16:
@@ -125,7 +124,6 @@
               1,
               1,
               kFrameSize,
-              kNoTimestamp(),
               kNoTimestamp());
           break;
         case kSampleFormatS32:
@@ -137,7 +135,6 @@
               1,
               1,
               kFrameSize,
-              kNoTimestamp(),
               kNoTimestamp());
           break;
         default:
diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
index bb80661..2b82162 100644
--- a/media/filters/audio_renderer_impl.cc
+++ b/media/filters/audio_renderer_impl.cc
@@ -20,6 +20,7 @@
 #include "media/base/audio_splicer.h"
 #include "media/base/bind_to_current_loop.h"
 #include "media/base/demuxer_stream.h"
+#include "media/filters/audio_clock.h"
 #include "media/filters/decrypting_demuxer_stream.h"
 
 namespace media {
@@ -57,8 +58,6 @@
       pending_read_(false),
       received_end_of_stream_(false),
       rendered_end_of_stream_(false),
-      audio_time_buffered_(kNoTimestamp()),
-      current_time_(kNoTimestamp()),
       underflow_disabled_(false),
       preroll_aborted_(false),
       weak_factory_(this) {
@@ -169,8 +168,7 @@
     DCHECK_EQ(state_, kPaused);
     DCHECK(!flush_cb_.is_null());
 
-    audio_time_buffered_ = kNoTimestamp();
-    current_time_ = kNoTimestamp();
+    audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate()));
     received_end_of_stream_ = false;
     rendered_end_of_stream_ = false;
     preroll_aborted_ = false;
@@ -288,6 +286,8 @@
                             hardware_config_->GetHighLatencyBufferSize());
   }
 
+  audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate()));
+
   audio_buffer_stream_.Initialize(
       stream,
       false,
@@ -565,27 +565,33 @@
 int AudioRendererImpl::Render(AudioBus* audio_bus,
                               int audio_delay_milliseconds) {
   const int requested_frames = audio_bus->frames();
-  base::TimeDelta current_time = kNoTimestamp();
-  base::TimeDelta max_time = kNoTimestamp();
   base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds(
       audio_delay_milliseconds);
-
+  const int delay_frames = static_cast<int>(playback_delay.InSecondsF() *
+                                            audio_parameters_.sample_rate());
   int frames_written = 0;
+  base::Closure time_cb;
   base::Closure underflow_cb;
   {
     base::AutoLock auto_lock(lock_);
 
     // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread.
-    if (!algorithm_)
+    if (!algorithm_) {
+      audio_clock_->WroteSilence(requested_frames, delay_frames);
       return 0;
+    }
 
     float playback_rate = algorithm_->playback_rate();
-    if (playback_rate == 0)
+    if (playback_rate == 0) {
+      audio_clock_->WroteSilence(requested_frames, delay_frames);
       return 0;
+    }
 
     // Mute audio by returning 0 when not playing.
-    if (state_ != kPlaying)
+    if (state_ != kPlaying) {
+      audio_clock_->WroteSilence(requested_frames, delay_frames);
       return 0;
+    }
 
     // We use the following conditions to determine end of playback:
     //   1) Algorithm can not fill the audio callback buffer
@@ -602,8 +608,15 @@
     //   3) We are in the kPlaying state
     //
     // Otherwise the buffer has data we can send to the device.
-    const base::TimeDelta time_before_filling = algorithm_->GetTime();
-    frames_written = algorithm_->FillBuffer(audio_bus, requested_frames);
+    const base::TimeDelta media_timestamp_before_filling =
+        audio_clock_->CurrentMediaTimestamp();
+    if (algorithm_->frames_buffered() > 0) {
+      frames_written = algorithm_->FillBuffer(audio_bus, requested_frames);
+      audio_clock_->WroteAudio(
+          frames_written, delay_frames, playback_rate, algorithm_->GetTime());
+    }
+    audio_clock_->WroteSilence(requested_frames - frames_written, delay_frames);
+
     if (frames_written == 0) {
       const base::TimeTicks now = now_cb_.Run();
 
@@ -628,55 +641,24 @@
                                         weak_factory_.GetWeakPtr()));
     }
 
-    // Adjust the delay according to playback rate.
-    base::TimeDelta adjusted_playback_delay = base::TimeDelta::FromMicroseconds(
-        ceil(playback_delay.InMicroseconds() * playback_rate));
-
-    // The |audio_time_buffered_| is the ending timestamp of the last frame
-    // buffered at the audio device. |playback_delay| is the amount of time
-    // buffered at the audio device. The current time can be computed by their
-    // difference.
-    if (audio_time_buffered_ != kNoTimestamp()) {
-      base::TimeDelta previous_time = current_time_;
-      current_time_ = audio_time_buffered_ - adjusted_playback_delay;
-
-      // Time can change in one of two ways:
-      //   1) The time of the audio data at the audio device changed, or
-      //   2) The playback delay value has changed
-      //
-      // We only want to set |current_time| (and thus execute |time_cb_|) if
-      // time has progressed and we haven't signaled end of stream yet.
-      //
-      // Why? The current latency of the system results in getting the last call
-      // to FillBuffer() later than we'd like, which delays firing the 'ended'
-      // event, which delays the looping/trigging performance of short sound
-      // effects.
-      //
-      // TODO(scherkus): revisit this and switch back to relying on playback
-      // delay after we've revamped our audio IPC subsystem.
-      if (current_time_ > previous_time && !rendered_end_of_stream_) {
-        current_time = current_time_;
-      }
-    } else if (frames_written > 0) {
-      // Nothing has been buffered yet, so use the first buffer's timestamp.
-      DCHECK(time_before_filling != kNoTimestamp());
-      current_time_ = current_time =
-          time_before_filling - adjusted_playback_delay;
+    // We only want to execute |time_cb_| if time has progressed and we haven't
+    // signaled end of stream yet.
+    if (media_timestamp_before_filling !=
+            audio_clock_->CurrentMediaTimestamp() &&
+        !rendered_end_of_stream_) {
+      time_cb = base::Bind(time_cb_,
+                           audio_clock_->CurrentMediaTimestamp(),
+                           audio_clock_->last_endpoint_timestamp());
     }
 
-    // The call to FillBuffer() on |algorithm_| has increased the amount of
-    // buffered audio data. Update the new amount of time buffered.
-    max_time = algorithm_->GetTime();
-    audio_time_buffered_ = max_time;
-
     if (frames_written > 0) {
       UpdateEarliestEndTime_Locked(
           frames_written, playback_delay, now_cb_.Run());
     }
   }
 
-  if (current_time != kNoTimestamp() && max_time != kNoTimestamp())
-    time_cb_.Run(current_time, max_time);
+  if (!time_cb.is_null())
+    time_cb.Run();
 
   if (!underflow_cb.is_null())
     underflow_cb.Run();
diff --git a/media/filters/audio_renderer_impl.h b/media/filters/audio_renderer_impl.h
index f6f41f1..4e8ad01 100644
--- a/media/filters/audio_renderer_impl.h
+++ b/media/filters/audio_renderer_impl.h
@@ -37,11 +37,12 @@
 
 namespace media {
 
-class AudioBus;
 class AudioBufferConverter;
+class AudioBus;
+class AudioClock;
+class AudioHardwareConfig;
 class AudioSplicer;
 class DecryptingDemuxerStream;
-class AudioHardwareConfig;
 
 class MEDIA_EXPORT AudioRendererImpl
     : public AudioRenderer,
@@ -246,10 +247,7 @@
   bool received_end_of_stream_;
   bool rendered_end_of_stream_;
 
-  // The timestamp of the last frame (i.e. furthest in the future) buffered as
-  // well as the current time that takes current playback delay into account.
-  base::TimeDelta audio_time_buffered_;
-  base::TimeDelta current_time_;
+  scoped_ptr<AudioClock> audio_clock_;
 
   base::TimeDelta preroll_timestamp_;
 
diff --git a/media/filters/audio_renderer_impl_unittest.cc b/media/filters/audio_renderer_impl_unittest.cc
index 1ae27e3..8a9af82 100644
--- a/media/filters/audio_renderer_impl_unittest.cc
+++ b/media/filters/audio_renderer_impl_unittest.cc
@@ -288,8 +288,7 @@
                                kPlayingAudio,
                                0.0f,
                                size,
-                               next_timestamp_->GetTimestamp(),
-                               next_timestamp_->GetFrameDuration(size));
+                               next_timestamp_->GetTimestamp());
     next_timestamp_->AddFrames(size);
 
     DeliverBuffer(AudioDecoder::kOk, buffer);
@@ -969,15 +968,33 @@
   EXPECT_TRUE(ConsumeBufferedData(kFramesToConsume, NULL));
   WaitForPendingRead();
 
-  // Ensure we received a time update for the first buffer and it's zero.
+  // ConsumeBufferedData() uses an audio delay of zero, so ensure we received
+  // a time update that's equal to |kFramesToConsume| from above.
   timestamp_helper.SetBaseTimestamp(base::TimeDelta());
-  EXPECT_EQ(timestamp_helper.base_timestamp(), last_time_update());
   timestamp_helper.AddFrames(kFramesToConsume);
+  EXPECT_EQ(timestamp_helper.GetTimestamp(), last_time_update());
 
-  // ConsumeBufferedData() uses an audio delay of zero, so the next buffer
-  // should have a timestamp equal to the duration of |kFramesToConsume|.
+  // The next time update should match the remaining frames_buffered().
+  timestamp_helper.AddFrames(frames_buffered());
   EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL));
   EXPECT_EQ(timestamp_helper.GetTimestamp(), last_time_update());
 }
 
+TEST_F(AudioRendererImplTest, ImmediateEndOfStream) {
+  Initialize();
+  {
+    SCOPED_TRACE("Preroll()");
+    WaitableMessageLoopEvent event;
+    renderer_->Preroll(base::TimeDelta(), event.GetPipelineStatusCB());
+    WaitForPendingRead();
+    DeliverEndOfStream();
+    event.RunAndWaitForStatus(PIPELINE_OK);
+  }
+  Play();
+
+  // Read a single frame. We shouldn't be able to satisfy it.
+  EXPECT_FALSE(ConsumeBufferedData(1, NULL));
+  WaitForEnded();
+}
+
 }  // namespace media
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc
index d2a2b64..7503b22 100644
--- a/media/filters/chunk_demuxer.cc
+++ b/media/filters/chunk_demuxer.cc
@@ -113,12 +113,14 @@
   // spec's similarly named source buffer attributes that are used in coded
   // frame processing.
   bool Append(const uint8* data, size_t length,
-              TimeDelta append_window_start_,
-              TimeDelta append_window_end_,
+              TimeDelta append_window_start,
+              TimeDelta append_window_end,
               TimeDelta* timestamp_offset);
 
   // Aborts the current append sequence and resets the parser.
-  void Abort();
+  void Abort(TimeDelta append_window_start,
+             TimeDelta append_window_end,
+             TimeDelta* timestamp_offset);
 
   // Calls Remove(|start|, |end|, |duration|) on all
   // ChunkDemuxerStreams managed by this object.
@@ -301,8 +303,18 @@
   return err;
 }
 
-void SourceState::Abort() {
+void SourceState::Abort(TimeDelta append_window_start,
+                        TimeDelta append_window_end,
+                        base::TimeDelta* timestamp_offset) {
+  DCHECK(timestamp_offset);
+  DCHECK(!timestamp_offset_during_append_);
+  timestamp_offset_during_append_ = timestamp_offset;
+  append_window_start_during_append_ = append_window_start;
+  append_window_end_during_append_ = append_window_end;
+
   stream_parser_->Flush();
+  timestamp_offset_during_append_ = NULL;
+
   frame_processor_->Reset();
   parsing_media_segment_ = false;
 }
@@ -648,6 +660,7 @@
     const StreamParser::TextBufferQueueMap& text_map) {
   DVLOG(2) << "OnNewBuffers()";
   DCHECK(timestamp_offset_during_append_);
+  DCHECK(parsing_media_segment_);
 
   const TimeDelta timestamp_offset_before_processing =
       *timestamp_offset_during_append_;
@@ -696,7 +709,9 @@
 ChunkDemuxerStream::ChunkDemuxerStream(Type type, bool splice_frames_enabled)
     : type_(type),
       state_(UNINITIALIZED),
-      splice_frames_enabled_(splice_frames_enabled) {}
+      splice_frames_enabled_(splice_frames_enabled),
+      partial_append_window_trimming_enabled_(false) {
+}
 
 void ChunkDemuxerStream::StartReturningData() {
   DVLOG(1) << "ChunkDemuxerStream::StartReturningData()";
@@ -827,6 +842,18 @@
   base::AutoLock auto_lock(lock_);
   if (!stream_) {
     DCHECK_EQ(state_, UNINITIALIZED);
+
+    // On platforms which support splice frames, enable splice frames and
+    // partial append window support for a limited set of codecs.
+    // TODO(dalecurtis): Verify this works for codecs other than MP3 and Vorbis.
+    // Right now we want to be extremely conservative to ensure we don't break
+    // the world.
+    const bool mp3_or_vorbis =
+        config.codec() == kCodecMP3 || config.codec() == kCodecVorbis;
+    splice_frames_enabled_ = splice_frames_enabled_ && mp3_or_vorbis;
+    partial_append_window_trimming_enabled_ =
+        splice_frames_enabled_ && mp3_or_vorbis;
+
     stream_.reset(
         new SourceBufferStream(config, log_cb, splice_frames_enabled_));
     return true;
@@ -1264,12 +1291,17 @@
     host_->AddBufferedTimeRange(ranges.start(i), ranges.end(i));
 }
 
-void ChunkDemuxer::Abort(const std::string& id) {
+void ChunkDemuxer::Abort(const std::string& id,
+                         TimeDelta append_window_start,
+                         TimeDelta append_window_end,
+                         TimeDelta* timestamp_offset) {
   DVLOG(1) << "Abort(" << id << ")";
   base::AutoLock auto_lock(lock_);
   DCHECK(!id.empty());
   CHECK(IsValidId(id));
-  source_state_map_[id]->Abort();
+  source_state_map_[id]->Abort(append_window_start,
+                               append_window_end,
+                               timestamp_offset);
 }
 
 void ChunkDemuxer::Remove(const std::string& id, TimeDelta start,
diff --git a/media/filters/chunk_demuxer.h b/media/filters/chunk_demuxer.h
index 475c1b1..6586746 100644
--- a/media/filters/chunk_demuxer.h
+++ b/media/filters/chunk_demuxer.h
@@ -96,6 +96,10 @@
     stream_->set_memory_limit_for_testing(memory_limit);
   }
 
+  bool supports_partial_append_window_trimming() const {
+    return partial_append_window_trimming_enabled_;
+  }
+
  private:
   enum State {
     UNINITIALIZED,
@@ -117,7 +121,8 @@
   mutable base::Lock lock_;
   State state_;
   ReadCB read_cb_;
-  const bool splice_frames_enabled_;
+  bool splice_frames_enabled_;
+  bool partial_append_window_trimming_enabled_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream);
 };
@@ -221,7 +226,12 @@
 
   // Aborts parsing the current segment and reset the parser to a state where
   // it can accept a new segment.
-  void Abort(const std::string& id);
+  // Some pending frames can be emitted during that process. These frames are
+  // applied |timestamp_offset|.
+  void Abort(const std::string& id,
+             base::TimeDelta append_window_start,
+             base::TimeDelta append_window_end,
+             base::TimeDelta* timestamp_offset);
 
   // Remove buffers between |start| and |end| for the source buffer
   // associated with |id|.
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc
index 73253fd..3bca45f 100644
--- a/media/filters/chunk_demuxer_unittest.cc
+++ b/media/filters/chunk_demuxer_unittest.cc
@@ -324,6 +324,15 @@
                            use_legacy_frame_processor_);
   }
 
+  ChunkDemuxer::Status AddIdForMp2tSource(const std::string& source_id) {
+    std::vector<std::string> codecs;
+    std::string type = "video/mp2t";
+    codecs.push_back("mp4a.40.2");
+    codecs.push_back("avc1.640028");
+    return demuxer_->AddId(source_id, type, codecs,
+                           use_legacy_frame_processor_);
+  }
+
   void AppendData(const uint8* data, size_t length) {
     AppendData(kSourceId, data, length);
   }
@@ -1038,6 +1047,8 @@
       EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format());
       EXPECT_EQ(is_audio_encrypted,
                 audio_stream->audio_decoder_config().is_encrypted());
+      EXPECT_TRUE(static_cast<ChunkDemuxerStream*>(audio_stream)
+                      ->supports_partial_append_window_trimming());
     } else {
       EXPECT_FALSE(audio_stream);
     }
@@ -1047,6 +1058,8 @@
       EXPECT_TRUE(video_stream);
       EXPECT_EQ(is_video_encrypted,
                 video_stream->video_decoder_config().is_encrypted());
+      EXPECT_FALSE(static_cast<ChunkDemuxerStream*>(video_stream)
+                       ->supports_partial_append_window_trimming());
     } else {
       EXPECT_FALSE(video_stream);
     }
@@ -1087,6 +1100,8 @@
     ASSERT_TRUE(text_stream);
     EXPECT_EQ(DemuxerStream::TEXT, text_stream->type());
     EXPECT_EQ(kTextSubtitles, text_config.kind());
+    EXPECT_FALSE(static_cast<ChunkDemuxerStream*>(text_stream)
+                     ->supports_partial_append_window_trimming());
 
     DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
     if (has_audio) {
@@ -1102,6 +1117,8 @@
       EXPECT_EQ(kSampleFormatPlanarF32, config.sample_format());
       EXPECT_EQ(is_audio_encrypted,
                 audio_stream->audio_decoder_config().is_encrypted());
+      EXPECT_TRUE(static_cast<ChunkDemuxerStream*>(audio_stream)
+                      ->supports_partial_append_window_trimming());
     } else {
       EXPECT_FALSE(audio_stream);
     }
@@ -1111,6 +1128,8 @@
       EXPECT_TRUE(video_stream);
       EXPECT_EQ(is_video_encrypted,
                 video_stream->video_decoder_config().is_encrypted());
+      EXPECT_FALSE(static_cast<ChunkDemuxerStream*>(video_stream)
+                       ->supports_partial_append_window_trimming());
     } else {
       EXPECT_FALSE(video_stream);
     }
@@ -2697,12 +2716,63 @@
   // Confirm we're in the middle of parsing a media segment.
   ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId));
 
-  demuxer_->Abort(kSourceId);
+  demuxer_->Abort(kSourceId,
+                  append_window_start_for_next_append_,
+                  append_window_end_for_next_append_,
+                  &timestamp_offset_map_[kSourceId]);
+
   // After Abort(), parsing should no longer be in the middle of a media
   // segment.
   ASSERT_FALSE(demuxer_->IsParsingMediaSegment(kSourceId));
 }
 
+#if defined(USE_PROPRIETARY_CODECS)
+#if defined(ENABLE_MPEG2TS_STREAM_PARSER)
+TEST_P(ChunkDemuxerTest, EmitBuffersDuringAbort) {
+  EXPECT_CALL(*this, DemuxerOpened());
+  demuxer_->Initialize(
+      &host_, CreateInitDoneCB(kInfiniteDuration(), PIPELINE_OK), true);
+  EXPECT_EQ(ChunkDemuxer::kOk, AddIdForMp2tSource(kSourceId));
+
+  // For info:
+  // DTS/PTS derived using dvbsnoop -s ts -if bear-1280x720.ts -tssubdecode
+  // Video: first PES:
+  //        PTS: 126912 (0x0001efc0)  [= 90 kHz-Timestamp: 0:00:01.4101]
+  //        DTS: 123909 (0x0001e405)  [= 90 kHz-Timestamp: 0:00:01.3767]
+  // Audio: first PES:
+  //        PTS: 126000 (0x0001ec30)  [= 90 kHz-Timestamp: 0:00:01.4000]
+  //        DTS: 123910 (0x0001e406)  [= 90 kHz-Timestamp: 0:00:01.3767]
+  // Video: last PES:
+  //        PTS: 370155 (0x0005a5eb)  [= 90 kHz-Timestamp: 0:00:04.1128]
+  //        DTS: 367152 (0x00059a30)  [= 90 kHz-Timestamp: 0:00:04.0794]
+  // Audio: last PES:
+  //        PTS: 353788 (0x000565fc)  [= 90 kHz-Timestamp: 0:00:03.9309]
+
+  scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("bear-1280x720.ts");
+  AppendData(kSourceId, buffer->data(), buffer->data_size());
+
+  // Confirm we're in the middle of parsing a media segment.
+  ASSERT_TRUE(demuxer_->IsParsingMediaSegment(kSourceId));
+
+  // Abort on the Mpeg2 TS parser triggers the emission of the last video
+  // buffer which is pending in the stream parser.
+  Ranges<base::TimeDelta> range_before_abort =
+      demuxer_->GetBufferedRanges(kSourceId);
+  demuxer_->Abort(kSourceId,
+                  append_window_start_for_next_append_,
+                  append_window_end_for_next_append_,
+                  &timestamp_offset_map_[kSourceId]);
+  Ranges<base::TimeDelta> range_after_abort =
+      demuxer_->GetBufferedRanges(kSourceId);
+
+  ASSERT_EQ(range_before_abort.size(), 1u);
+  ASSERT_EQ(range_after_abort.size(), 1u);
+  EXPECT_EQ(range_after_abort.start(0), range_before_abort.start(0));
+  EXPECT_GT(range_after_abort.end(0), range_before_abort.end(0));
+}
+#endif
+#endif
+
 TEST_P(ChunkDemuxerTest, WebMIsParsingMediaSegmentDetection) {
   // TODO(wolenetz): Also test 'unknown' sized clusters.
   // See http://crbug.com/335676.
@@ -3026,11 +3096,14 @@
       kSourceId, kAudioTrackNum,
       "0K 30K 60K 90K 120K 150K 180K 210K 240K 270K 300K 330K");
 
-  // Verify that frames that start outside the window are not included
+  // Verify that frames that end outside the window are not included
   // in the buffer. Also verify that buffers that start inside the
   // window and extend beyond the end of the window are not included.
-  CheckExpectedRanges(kSourceId, "{ [30,270) }");
-  CheckExpectedBuffers(stream, "30 60 90 120 150 180 210 240");
+  //
+  // The first 20ms of the first buffer should be trimmed off since it
+  // overlaps the start of the append window.
+  CheckExpectedRanges(kSourceId, "{ [20,270) }");
+  CheckExpectedBuffers(stream, "20 30 60 90 120 150 180 210 240");
 
   // Extend the append window to [20,650).
   append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650);
@@ -3039,7 +3112,22 @@
   AppendSingleStreamCluster(
       kSourceId, kAudioTrackNum,
       "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K");
-  CheckExpectedRanges(kSourceId, "{ [30,270) [360,630) }");
+  CheckExpectedRanges(kSourceId, "{ [20,270) [360,630) }");
+}
+
+TEST_P(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) {
+  ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
+
+  // Set the append window to [10,20).
+  append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(10);
+  append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(20);
+
+  // Append a cluster that starts before and ends after the append window.
+  AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K");
+
+  // Verify that everything is dropped in this case.  No partial append should
+  // be generated.
+  CheckExpectedRanges(kSourceId, "{ }");
 }
 
 TEST_P(ChunkDemuxerTest, AppendWindow_Text) {
diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc
index 9d9d87c..4f712be 100644
--- a/media/filters/decoder_stream.cc
+++ b/media/filters/decoder_stream.cc
@@ -51,6 +51,7 @@
                                           decoders.Pass(),
                                           set_decryptor_ready_cb)),
       active_splice_(false),
+      pending_decode_requests_(0),
       weak_factory_(this) {}
 
 template <DemuxerStream::Type StreamType>
@@ -87,36 +88,45 @@
   FUNCTION_DVLOG(2);
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
-         state_ == STATE_ERROR) << state_;
+         state_ == STATE_ERROR || state_ == STATE_REINITIALIZING_DECODER ||
+         state_ == STATE_PENDING_DEMUXER_READ)
+      << state_;
   // No two reads in the flight at any time.
   DCHECK(read_cb_.is_null());
   // No read during resetting or stopping process.
   DCHECK(reset_cb_.is_null());
   DCHECK(stop_cb_.is_null());
 
+  read_cb_ = read_cb;
+
   if (state_ == STATE_ERROR) {
-    task_runner_->PostTask(FROM_HERE, base::Bind(
-        read_cb, DECODE_ERROR, scoped_refptr<Output>()));
+    task_runner_->PostTask(FROM_HERE,
+                           base::Bind(base::ResetAndReturn(&read_cb_),
+                                      DECODE_ERROR,
+                                      scoped_refptr<Output>()));
     return;
   }
 
-  read_cb_ = read_cb;
+  if (!ready_outputs_.empty()) {
+    task_runner_->PostTask(FROM_HERE, base::Bind(
+        base::ResetAndReturn(&read_cb_), OK, ready_outputs_.front()));
+    ready_outputs_.pop_front();
+  }
+
+  // Decoder may be in reinitializing state as result of the previous Read().
+  if (state_ == STATE_REINITIALIZING_DECODER)
+    return;
+
+  if (!CanDecodeMore())
+    return;
 
   if (state_ == STATE_FLUSHING_DECODER) {
     FlushDecoder();
     return;
   }
 
-  scoped_refptr<Output> output = decoder_->GetDecodeOutput();
-
-  // If the decoder has queued output ready to go we don't need a demuxer read.
-  if (output) {
-    task_runner_->PostTask(
-        FROM_HERE, base::Bind(base::ResetAndReturn(&read_cb_), OK, output));
-    return;
-  }
-
-  ReadFromDemuxerStream();
+  if (state_ != STATE_PENDING_DEMUXER_READ)
+    ReadFromDemuxerStream();
 }
 
 template <DemuxerStream::Type StreamType>
@@ -129,6 +139,13 @@
 
   reset_cb_ = closure;
 
+  if (!read_cb_.is_null()) {
+    task_runner_->PostTask(FROM_HERE, base::Bind(
+        base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>()));
+  }
+
+  ready_outputs_.clear();
+
   // During decoder reinitialization, the Decoder does not need to be and
   // cannot be Reset(). |decrypting_demuxer_stream_| was reset before decoder
   // reinitialization.
@@ -141,11 +158,6 @@
   if (state_ == STATE_PENDING_DEMUXER_READ && !decrypting_demuxer_stream_)
     return;
 
-  // The Decoder API guarantees that if Decoder::Reset() is called during
-  // a pending decode, the decode callback must be fired before the reset
-  // callback is fired. Therefore, we can call Decoder::Reset() regardless
-  // of if we have a pending decode and always satisfy the reset callback when
-  // the decoder reset is finished.
   if (decrypting_demuxer_stream_) {
     decrypting_demuxer_stream_->Reset(base::Bind(
         &DecoderStream<StreamType>::ResetDecoder, weak_factory_.GetWeakPtr()));
@@ -175,9 +187,10 @@
   weak_factory_.InvalidateWeakPtrs();
 
   // Post callbacks to prevent reentrance into this object.
-  if (!read_cb_.is_null())
+  if (!read_cb_.is_null()) {
     task_runner_->PostTask(FROM_HERE, base::Bind(
         base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>()));
+  }
   if (!reset_cb_.is_null())
     task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_));
 
@@ -213,6 +226,24 @@
 }
 
 template <DemuxerStream::Type StreamType>
+bool DecoderStream<StreamType>::CanDecodeMore() const {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+
+  // Limit total number of outputs stored in |ready_outputs_| and being decoded.
+  // It only makes sense to saturate decoder completely when output queue is
+  // empty.
+  int num_decodes =
+      static_cast<int>(ready_outputs_.size()) + pending_decode_requests_;
+  return num_decodes < decoder_->GetMaxDecodeRequests();
+}
+
+template <>
+bool DecoderStream<DemuxerStream::AUDIO>::CanDecodeMore() const {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  return !pending_decode_requests_ && ready_outputs_.empty();
+}
+
+template <DemuxerStream::Type StreamType>
 void DecoderStream<StreamType>::OnDecoderSelected(
     scoped_ptr<Decoder> selected_decoder,
     scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
@@ -255,22 +286,11 @@
 }
 
 template <DemuxerStream::Type StreamType>
-void DecoderStream<StreamType>::AbortRead() {
-  // Abort read during pending reset. It is safe to fire the |read_cb_| directly
-  // instead of posting it because the renderer won't call into this class
-  // again when it's in kFlushing state.
-  // TODO(xhwang): Improve the resetting process to avoid this dependency on the
-  // caller.
-  DCHECK(!reset_cb_.is_null());
-  SatisfyRead(ABORTED, NULL);
-}
-
-template <DemuxerStream::Type StreamType>
 void DecoderStream<StreamType>::Decode(
     const scoped_refptr<DecoderBuffer>& buffer) {
   FUNCTION_DVLOG(2);
   DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
-  DCHECK(!read_cb_.is_null());
+  DCHECK(CanDecodeMore());
   DCHECK(reset_cb_.is_null());
   DCHECK(stop_cb_.is_null());
   DCHECK(buffer);
@@ -278,6 +298,7 @@
   int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size();
 
   TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this);
+  ++pending_decode_requests_;
   decoder_->Decode(buffer,
                    base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
                               weak_factory_.GetWeakPtr(),
@@ -286,7 +307,8 @@
 
 template <DemuxerStream::Type StreamType>
 void DecoderStream<StreamType>::FlushDecoder() {
-  Decode(DecoderBuffer::CreateEOSBuffer());
+  if (pending_decode_requests_ == 0)
+    Decode(DecoderBuffer::CreateEOSBuffer());
 }
 
 template <DemuxerStream::Type StreamType>
@@ -294,28 +316,42 @@
     int buffer_size,
     typename Decoder::Status status,
     const scoped_refptr<Output>& output) {
-  FUNCTION_DVLOG(2);
-  DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
-  DCHECK(!read_cb_.is_null());
+  FUNCTION_DVLOG(2) << status << " " << output;
+  DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
+         state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
+      << state_;
   DCHECK(stop_cb_.is_null());
   DCHECK_EQ(status == Decoder::kOk, output != NULL);
+  DCHECK_GT(pending_decode_requests_, 0);
+
+  --pending_decode_requests_;
 
   TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this);
 
+  if (state_ == STATE_ERROR) {
+    DCHECK(read_cb_.is_null());
+    return;
+  }
+
   if (status == Decoder::kDecodeError) {
     state_ = STATE_ERROR;
-    SatisfyRead(DECODE_ERROR, NULL);
+    ready_outputs_.clear();
+    if (!read_cb_.is_null())
+      SatisfyRead(DECODE_ERROR, NULL);
     return;
   }
 
   if (status == Decoder::kDecryptError) {
     state_ = STATE_ERROR;
-    SatisfyRead(DECRYPT_ERROR, NULL);
+    ready_outputs_.clear();
+    if (!read_cb_.is_null())
+      SatisfyRead(DECRYPT_ERROR, NULL);
     return;
   }
 
   if (status == Decoder::kAborted) {
-    SatisfyRead(ABORTED, NULL);
+    if (!read_cb_.is_null())
+      SatisfyRead(ABORTED, NULL);
     return;
   }
 
@@ -326,10 +362,8 @@
 
   // Drop decoding result if Reset() was called during decoding.
   // The resetting process will be handled when the decoder is reset.
-  if (!reset_cb_.is_null()) {
-    AbortRead();
+  if (!reset_cb_.is_null())
     return;
-  }
 
   // Decoder flushed. Reinitialize the decoder.
   if (state_ == STATE_FLUSHING_DECODER &&
@@ -347,14 +381,27 @@
   }
 
   DCHECK(output);
-  SatisfyRead(OK, output);
+
+  // Store decoded output.
+  ready_outputs_.push_back(output);
+  scoped_refptr<Output> extra_output;
+  while ((extra_output = decoder_->GetDecodeOutput()) != NULL) {
+    ready_outputs_.push_back(extra_output);
+  }
+
+  // Satisfy outstanding read request, if any.
+  if (!read_cb_.is_null()) {
+    scoped_refptr<Output> read_result = ready_outputs_.front();
+    ready_outputs_.pop_front();
+    SatisfyRead(OK, output);
+  }
 }
 
 template <DemuxerStream::Type StreamType>
 void DecoderStream<StreamType>::ReadFromDemuxerStream() {
   FUNCTION_DVLOG(2);
   DCHECK_EQ(state_, STATE_NORMAL) << state_;
-  DCHECK(!read_cb_.is_null());
+  DCHECK(CanDecodeMore());
   DCHECK(reset_cb_.is_null());
   DCHECK(stop_cb_.is_null());
 
@@ -369,11 +416,19 @@
     const scoped_refptr<DecoderBuffer>& buffer) {
   FUNCTION_DVLOG(2) << ": " << status;
   DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK_EQ(state_, STATE_PENDING_DEMUXER_READ) << state_;
+  DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR ||
+         state_ == STATE_STOPPED)
+      << state_;
   DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
-  DCHECK(!read_cb_.is_null());
   DCHECK(stop_cb_.is_null());
 
+  // Decoding has been stopped (e.g due to an error).
+  if (state_ != STATE_PENDING_DEMUXER_READ) {
+    DCHECK(state_ == STATE_ERROR || state_ == STATE_STOPPED);
+    DCHECK(read_cb_.is_null());
+    return;
+  }
+
   state_ = STATE_NORMAL;
 
   if (status == DemuxerStream::kConfigChanged) {
@@ -385,7 +440,6 @@
 
     state_ = STATE_FLUSHING_DECODER;
     if (!reset_cb_.is_null()) {
-      AbortRead();
       // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
       // which will continue the resetting process in it's callback.
       if (!decrypting_demuxer_stream_)
@@ -398,7 +452,6 @@
   }
 
   if (!reset_cb_.is_null()) {
-    AbortRead();
     // If we are using DecryptingDemuxerStream, we already called DDS::Reset()
     // which will continue the resetting process in it's callback.
     if (!decrypting_demuxer_stream_)
@@ -421,6 +474,10 @@
 
   DCHECK(status == DemuxerStream::kOk) << status;
   Decode(buffer);
+
+  // Read more data if the decoder supports multiple parallel decoding requests.
+  if (CanDecodeMore() && !buffer->end_of_stream())
+    ReadFromDemuxerStream();
 }
 
 template <DemuxerStream::Type StreamType>
@@ -428,6 +485,7 @@
   FUNCTION_DVLOG(2);
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK_EQ(state_, STATE_FLUSHING_DECODER) << state_;
+  DCHECK_EQ(pending_decode_requests_, 0);
 
   DCHECK(StreamTraits::GetDecoderConfig(*stream_).IsValidConfig());
   state_ = STATE_REINITIALIZING_DECODER;
@@ -455,9 +513,8 @@
   state_ = (status == PIPELINE_OK) ? STATE_NORMAL : STATE_ERROR;
 
   if (!reset_cb_.is_null()) {
-    if (!read_cb_.is_null())
-      AbortRead();
     base::ResetAndReturn(&reset_cb_).Run();
+    return;
   }
 
   if (read_cb_.is_null())
diff --git a/media/filters/decoder_stream.h b/media/filters/decoder_stream.h
index 62caca5..2856f85 100644
--- a/media/filters/decoder_stream.h
+++ b/media/filters/decoder_stream.h
@@ -88,6 +88,9 @@
   // behavior.
   bool CanReadWithoutStalling() const;
 
+  // Returns true if one more decode request can be submitted to the decoder.
+  bool CanDecodeMore() const;
+
   // Allows callers to register for notification of splice buffers from the
   // demuxer.  I.e., DecoderBuffer::splice_timestamp() is not kNoTimestamp().
   //
@@ -130,9 +133,6 @@
   void SatisfyRead(Status status,
                    const scoped_refptr<Output>& output);
 
-  // Abort pending |read_cb_|.
-  void AbortRead();
-
   // Decodes |buffer| and returns the result via OnDecodeOutputReady().
   void Decode(const scoped_refptr<DecoderBuffer>& buffer);
 
@@ -189,6 +189,13 @@
   // splice_timestamp() of kNoTimestamp() is encountered.
   bool active_splice_;
 
+  // Decoded buffers that haven't been read yet. Used when the decoder supports
+  // parallel decoding.
+  std::list<scoped_refptr<Output> > ready_outputs_;
+
+  // Number of outstanding decode requests sent to the |decoder_|.
+  int pending_decode_requests_;
+
   // NOTE: Weak pointers must be invalidated before all other member variables.
   base::WeakPtrFactory<DecoderStream<StreamType> > weak_factory_;
 
@@ -200,6 +207,9 @@
 template <>
 bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const;
 
+template <>
+bool DecoderStream<DemuxerStream::AUDIO>::CanDecodeMore() const;
+
 typedef DecoderStream<DemuxerStream::VIDEO> VideoFrameStream;
 typedef DecoderStream<DemuxerStream::AUDIO> AudioBufferStream;
 
diff --git a/media/filters/decrypting_audio_decoder.cc b/media/filters/decrypting_audio_decoder.cc
index 91ee63b..d00e3b9 100644
--- a/media/filters/decrypting_audio_decoder.cc
+++ b/media/filters/decrypting_audio_decoder.cc
@@ -371,8 +371,6 @@
     }
 
     frame->set_timestamp(current_time);
-    frame->set_duration(
-        timestamp_helper_->GetFrameDuration(frame->frame_count()));
     timestamp_helper_->AddFrames(frame->frame_count());
   }
 }
diff --git a/media/filters/decrypting_audio_decoder_unittest.cc b/media/filters/decrypting_audio_decoder_unittest.cc
index d7f1f9d..007a288 100644
--- a/media/filters/decrypting_audio_decoder_unittest.cc
+++ b/media/filters/decrypting_audio_decoder_unittest.cc
@@ -104,7 +104,6 @@
                                                     channels,
                                                     kSampleRate,
                                                     kFakeAudioFrameSize,
-                                                    kNoTimestamp(),
                                                     kNoTimestamp());
     decoded_frame_list_.push_back(decoded_frame_);
 
@@ -363,14 +362,12 @@
       ChannelLayoutToChannelCount(config_.channel_layout()),
       kSampleRate,
       kFakeAudioFrameSize,
-      kNoTimestamp(),
       kNoTimestamp());
   scoped_refptr<AudioBuffer> frame_b = AudioBuffer::CreateEmptyBuffer(
       config_.channel_layout(),
       ChannelLayoutToChannelCount(config_.channel_layout()),
       kSampleRate,
       kFakeAudioFrameSize,
-      kNoTimestamp(),
       kNoTimestamp());
   decoded_frame_list_.push_back(frame_a);
   decoded_frame_list_.push_back(frame_b);
diff --git a/media/filters/fake_demuxer_stream.cc b/media/filters/fake_demuxer_stream.cc
index 5c5ca50..ba86363 100644
--- a/media/filters/fake_demuxer_stream.cc
+++ b/media/filters/fake_demuxer_stream.cc
@@ -111,6 +111,15 @@
   DoRead();
 }
 
+void FakeDemuxerStream::SatisfyReadAndHoldNext() {
+  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK_EQ(read_to_hold_, next_read_num_);
+  DCHECK(!read_cb_.is_null());
+
+  ++read_to_hold_;
+  DoRead();
+}
+
 void FakeDemuxerStream::Reset() {
   read_to_hold_ = -1;
 
diff --git a/media/filters/fake_demuxer_stream.h b/media/filters/fake_demuxer_stream.h
index 1c1144e..95bfa96 100644
--- a/media/filters/fake_demuxer_stream.h
+++ b/media/filters/fake_demuxer_stream.h
@@ -49,6 +49,9 @@
   // Satisfies the pending read with the next scheduled status and buffer.
   void SatisfyRead();
 
+  // Satisfies pending read request and then holds the following read.
+  void SatisfyReadAndHoldNext();
+
   // Satisfies the pending read (if any) with kAborted and NULL. This call
   // always clears |hold_next_read_|.
   void Reset();
diff --git a/media/filters/fake_video_decoder.cc b/media/filters/fake_video_decoder.cc
index 3da1065..fa36219 100644
--- a/media/filters/fake_video_decoder.cc
+++ b/media/filters/fake_video_decoder.cc
@@ -14,26 +14,29 @@
 namespace media {
 
 FakeVideoDecoder::FakeVideoDecoder(int decoding_delay,
-                                   bool supports_get_decode_output)
-    : task_runner_(base::MessageLoopProxy::current()),
-      decoding_delay_(decoding_delay),
+                                   bool supports_get_decode_output,
+                                   int max_parallel_decoding_requests)
+    : decoding_delay_(decoding_delay),
       supports_get_decode_output_(supports_get_decode_output),
-      state_(UNINITIALIZED),
+      max_parallel_decoding_requests_(max_parallel_decoding_requests),
+      state_(STATE_UNINITIALIZED),
+      hold_decode_(false),
       total_bytes_decoded_(0),
       weak_factory_(this) {
   DCHECK_GE(decoding_delay, 0);
 }
 
 FakeVideoDecoder::~FakeVideoDecoder() {
-  DCHECK_EQ(state_, UNINITIALIZED);
+  DCHECK_EQ(state_, STATE_UNINITIALIZED);
 }
 
 void FakeVideoDecoder::Initialize(const VideoDecoderConfig& config,
                                   bool low_delay,
                                   const PipelineStatusCB& status_cb) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(config.IsValidConfig());
-  DCHECK(decode_cb_.IsNull()) << "No reinitialization during pending decode.";
+  DCHECK(held_decode_callbacks_.empty())
+      << "No reinitialization during pending decode.";
   DCHECK(reset_cb_.IsNull()) << "No reinitialization during pending reset.";
 
   current_config_ = config;
@@ -44,74 +47,73 @@
     decoded_frames_.clear();
   }
 
-  state_ = NORMAL;
+  state_ = STATE_NORMAL;
   init_cb_.RunOrHold(PIPELINE_OK);
 }
 
 void FakeVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
                               const DecodeCB& decode_cb) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(decode_cb_.IsNull()) << "Overlapping decodes are not supported.";
+  DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(reset_cb_.IsNull());
-  DCHECK_LE(decoded_frames_.size(), static_cast<size_t>(decoding_delay_));
+  DCHECK_LE(decoded_frames_.size(),
+            decoding_delay_ + held_decode_callbacks_.size());
+  DCHECK_LT(static_cast<int>(held_decode_callbacks_.size()),
+            max_parallel_decoding_requests_);
 
   int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size();
-  decode_cb_.SetCallback(
+  DecodeCB wrapped_decode_cb =
       BindToCurrentLoop(base::Bind(&FakeVideoDecoder::OnFrameDecoded,
                                    weak_factory_.GetWeakPtr(),
                                    buffer_size,
-                                   decode_cb)));
+                                   decode_cb));
 
-  if (buffer->end_of_stream() && decoded_frames_.empty()) {
-    decode_cb_.RunOrHold(kOk, VideoFrame::CreateEOSFrame());
+  if (state_ == STATE_ERROR) {
+    wrapped_decode_cb.Run(kDecodeError, scoped_refptr<VideoFrame>());
     return;
   }
 
-  if (!buffer->end_of_stream()) {
+  if (buffer->end_of_stream()) {
+    state_ = STATE_END_OF_STREAM;
+  } else {
     DCHECK(VerifyFakeVideoBufferForTest(buffer, current_config_));
     scoped_refptr<VideoFrame> video_frame = VideoFrame::CreateColorFrame(
         current_config_.coded_size(), 0, 0, 0, buffer->timestamp());
     decoded_frames_.push_back(video_frame);
-
-    if (decoded_frames_.size() <= static_cast<size_t>(decoding_delay_)) {
-      decode_cb_.RunOrHold(kNotEnoughData, scoped_refptr<VideoFrame>());
-      return;
-    }
   }
 
-  scoped_refptr<VideoFrame> frame = decoded_frames_.front();
-  decoded_frames_.pop_front();
-  decode_cb_.RunOrHold(kOk, frame);
+  RunOrHoldDecode(wrapped_decode_cb);
 }
 
 void FakeVideoDecoder::Reset(const base::Closure& closure) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(reset_cb_.IsNull());
+
   reset_cb_.SetCallback(BindToCurrentLoop(closure));
+  decoded_frames_.clear();
 
   // Defer the reset if a decode is pending.
-  if (!decode_cb_.IsNull())
+  if (!held_decode_callbacks_.empty())
     return;
 
   DoReset();
 }
 
 void FakeVideoDecoder::Stop() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
 
   if (!init_cb_.IsNull())
     SatisfyInit();
-  if (!decode_cb_.IsNull())
+  if (!held_decode_callbacks_.empty())
     SatisfyDecode();
   if (!reset_cb_.IsNull())
     SatisfyReset();
 
   decoded_frames_.clear();
-  state_ = UNINITIALIZED;
+  state_ = STATE_UNINITIALIZED;
 }
 
 scoped_refptr<VideoFrame> FakeVideoDecoder::GetDecodeOutput() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
   if (!supports_get_decode_output_ || decoded_frames_.empty())
     return NULL;
   scoped_refptr<VideoFrame> out = decoded_frames_.front();
@@ -120,49 +122,71 @@
 }
 
 void FakeVideoDecoder::HoldNextInit() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
   init_cb_.HoldCallback();
 }
 
-void FakeVideoDecoder::HoldNextDecode() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  decode_cb_.HoldCallback();
+void FakeVideoDecoder::HoldDecode() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  hold_decode_ = true;
 }
 
 void FakeVideoDecoder::HoldNextReset() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(thread_checker_.CalledOnValidThread());
   reset_cb_.HoldCallback();
 }
 
 void FakeVideoDecoder::SatisfyInit() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(decode_cb_.IsNull());
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(held_decode_callbacks_.empty());
   DCHECK(reset_cb_.IsNull());
 
   init_cb_.RunHeldCallback();
 }
 
 void FakeVideoDecoder::SatisfyDecode() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  decode_cb_.RunHeldCallback();
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(hold_decode_);
 
-  if (!reset_cb_.IsNull())
+  hold_decode_ = false;
+
+  while (!held_decode_callbacks_.empty()) {
+    SatisfySingleDecode();
+  }
+}
+
+void FakeVideoDecoder::SatisfySingleDecode() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(!held_decode_callbacks_.empty());
+
+  DecodeCB decode_cb = held_decode_callbacks_.front();
+  held_decode_callbacks_.pop_front();
+  RunDecodeCallback(decode_cb);
+
+  if (!reset_cb_.IsNull() && held_decode_callbacks_.empty())
     DoReset();
 }
 
 void FakeVideoDecoder::SatisfyReset() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(decode_cb_.IsNull());
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(held_decode_callbacks_.empty());
   reset_cb_.RunHeldCallback();
 }
 
-void FakeVideoDecoder::DoReset() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(decode_cb_.IsNull());
-  DCHECK(!reset_cb_.IsNull());
+void FakeVideoDecoder::SimulateError() {
+  DCHECK(thread_checker_.CalledOnValidThread());
 
+  state_ = STATE_ERROR;
+  while (!held_decode_callbacks_.empty()) {
+    held_decode_callbacks_.front().Run(kDecodeError,
+                                       scoped_refptr<VideoFrame>());
+    held_decode_callbacks_.pop_front();
+  }
   decoded_frames_.clear();
-  reset_cb_.RunOrHold();
+}
+
+int FakeVideoDecoder::GetMaxDecodeRequests() const {
+  return max_parallel_decoding_requests_;
 }
 
 void FakeVideoDecoder::OnFrameDecoded(
@@ -170,9 +194,59 @@
     const DecodeCB& decode_cb,
     Status status,
     const scoped_refptr<VideoFrame>& video_frame) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
   if (status == kOk || status == kNotEnoughData)
     total_bytes_decoded_ += buffer_size;
   decode_cb.Run(status, video_frame);
 }
 
+void FakeVideoDecoder::RunOrHoldDecode(const DecodeCB& decode_cb) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  if (hold_decode_) {
+    held_decode_callbacks_.push_back(decode_cb);
+  } else {
+    DCHECK(held_decode_callbacks_.empty());
+    RunDecodeCallback(decode_cb);
+  }
+}
+
+void FakeVideoDecoder::RunDecodeCallback(const DecodeCB& decode_cb) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  if (!reset_cb_.IsNull()) {
+    DCHECK(decoded_frames_.empty());
+    decode_cb.Run(kAborted, scoped_refptr<VideoFrame>());
+    return;
+  }
+
+  // Make sure we leave decoding_delay_ frames in the queue and also frames for
+  // all pending decode callbacks, except the current one.
+  if (decoded_frames_.size() <=
+          decoding_delay_ + held_decode_callbacks_.size() &&
+      state_ != STATE_END_OF_STREAM) {
+    decode_cb.Run(kNotEnoughData, scoped_refptr<VideoFrame>());
+    return;
+  }
+
+  scoped_refptr<VideoFrame> frame;
+  if (decoded_frames_.empty()) {
+    DCHECK_EQ(state_, STATE_END_OF_STREAM);
+    frame = VideoFrame::CreateEOSFrame();
+  } else {
+    frame = decoded_frames_.front();
+    decoded_frames_.pop_front();
+  }
+  decode_cb.Run(kOk, frame);
+}
+
+void FakeVideoDecoder::DoReset() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(held_decode_callbacks_.empty());
+  DCHECK(!reset_cb_.IsNull());
+
+  reset_cb_.RunOrHold();
+}
+
 }  // namespace media
diff --git a/media/filters/fake_video_decoder.h b/media/filters/fake_video_decoder.h
index 240203f..03ed111 100644
--- a/media/filters/fake_video_decoder.h
+++ b/media/filters/fake_video_decoder.h
@@ -11,6 +11,7 @@
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
 #include "media/base/callback_holder.h"
 #include "media/base/decoder_buffer.h"
 #include "media/base/pipeline_status.h"
@@ -30,7 +31,9 @@
 class FakeVideoDecoder : public VideoDecoder {
  public:
   // Constructs an object with a decoding delay of |decoding_delay| frames.
-  FakeVideoDecoder(int decoding_delay, bool supports_get_decode_output);
+  FakeVideoDecoder(int decoding_delay,
+                   bool supports_get_decode_output,
+                   int max_parallel_decoding_requests);
   virtual ~FakeVideoDecoder();
 
   // VideoDecoder implementation.
@@ -42,10 +45,11 @@
   virtual void Reset(const base::Closure& closure) OVERRIDE;
   virtual void Stop() OVERRIDE;
   virtual scoped_refptr<VideoFrame> GetDecodeOutput() OVERRIDE;
+  virtual int GetMaxDecodeRequests() const OVERRIDE;
 
   // Holds the next init/decode/reset callback from firing.
   void HoldNextInit();
-  void HoldNextDecode();
+  void HoldDecode();
   void HoldNextReset();
 
   // Satisfies the pending init/decode/reset callback, which must be ready to
@@ -54,12 +58,19 @@
   void SatisfyDecode();
   void SatisfyReset();
 
+  // Satisfies single  decode request.
+  void SatisfySingleDecode();
+
+  void SimulateError();
+
   int total_bytes_decoded() const { return total_bytes_decoded_; }
 
  private:
   enum State {
-    UNINITIALIZED,
-    NORMAL
+    STATE_UNINITIALIZED,
+    STATE_NORMAL,
+    STATE_END_OF_STREAM,
+    STATE_ERROR,
   };
 
   // Callback for updating |total_bytes_decoded_|.
@@ -68,20 +79,29 @@
                       Status status,
                       const scoped_refptr<VideoFrame>& video_frame);
 
+  // Runs |decode_cb| or puts it to |held_decode_callbacks_| depending on
+  // current value of |hold_decode_|.
+  void RunOrHoldDecode(const DecodeCB& decode_cb);
+
+  // Runs |decode_cb| with a frame from |decoded_frames_|.
+  void RunDecodeCallback(const DecodeCB& decode_cb);
+
   void DoReset();
 
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  base::ThreadChecker thread_checker_;
 
-  const int decoding_delay_;
-
-  bool supports_get_decode_output_;
+  const size_t decoding_delay_;
+  const bool supports_get_decode_output_;
+  const int max_parallel_decoding_requests_;
 
   State state_;
 
   CallbackHolder<PipelineStatusCB> init_cb_;
-  CallbackHolder<DecodeCB> decode_cb_;
   CallbackHolder<base::Closure> reset_cb_;
 
+  bool hold_decode_;
+  std::list<DecodeCB> held_decode_callbacks_;
+
   VideoDecoderConfig current_config_;
 
   std::list<scoped_refptr<VideoFrame> > decoded_frames_;
diff --git a/media/filters/fake_video_decoder_unittest.cc b/media/filters/fake_video_decoder_unittest.cc
index d376758..d05a31f 100644
--- a/media/filters/fake_video_decoder_unittest.cc
+++ b/media/filters/fake_video_decoder_unittest.cc
@@ -18,14 +18,15 @@
 static const int kTotalBuffers = 12;
 static const int kDurationMs = 30;
 
-class FakeVideoDecoderTest : public testing::Test {
+class FakeVideoDecoderTest : public testing::Test,
+                             public testing::WithParamInterface<int> {
  public:
   FakeVideoDecoderTest()
-      : decoder_(new FakeVideoDecoder(kDecodingDelay, false)),
+      : decoder_(new FakeVideoDecoder(kDecodingDelay, false, GetParam())),
         num_input_buffers_(0),
         num_decoded_frames_(0),
-        decode_status_(VideoDecoder::kNotEnoughData),
-        is_decode_pending_(false),
+        last_decode_status_(VideoDecoder::kNotEnoughData),
+        pending_decode_requests_(0),
         is_reset_pending_(false) {}
 
   virtual ~FakeVideoDecoderTest() {
@@ -55,12 +56,11 @@
   // Callback for VideoDecoder::Read().
   void FrameReady(VideoDecoder::Status status,
                   const scoped_refptr<VideoFrame>& frame) {
-    DCHECK(is_decode_pending_);
-    ASSERT_TRUE(status == VideoDecoder::kOk ||
-                status == VideoDecoder::kNotEnoughData);
-    is_decode_pending_ = false;
-    decode_status_ = status;
-    frame_decoded_ = frame;
+    DCHECK_GT(pending_decode_requests_, 0);
+
+    --pending_decode_requests_;
+    last_decode_status_ = status;
+    last_decoded_frame_ = frame;
 
     if (frame && !frame->end_of_stream())
       num_decoded_frames_++;
@@ -70,37 +70,36 @@
     PENDING,
     OK,
     NOT_ENOUGH_DATA,
-    ABROTED,
+    ABORTED,
     EOS
   };
 
   void ExpectReadResult(CallbackResult result) {
     switch (result) {
       case PENDING:
-        EXPECT_TRUE(is_decode_pending_);
-        ASSERT_FALSE(frame_decoded_);
+        EXPECT_GT(pending_decode_requests_, 0);
         break;
       case OK:
-        EXPECT_FALSE(is_decode_pending_);
-        ASSERT_EQ(VideoDecoder::kOk, decode_status_);
-        ASSERT_TRUE(frame_decoded_);
-        EXPECT_FALSE(frame_decoded_->end_of_stream());
+        EXPECT_EQ(0, pending_decode_requests_);
+        ASSERT_EQ(VideoDecoder::kOk, last_decode_status_);
+        ASSERT_TRUE(last_decoded_frame_);
+        EXPECT_FALSE(last_decoded_frame_->end_of_stream());
         break;
       case NOT_ENOUGH_DATA:
-        EXPECT_FALSE(is_decode_pending_);
-        ASSERT_EQ(VideoDecoder::kNotEnoughData, decode_status_);
-        ASSERT_FALSE(frame_decoded_);
+        EXPECT_EQ(0, pending_decode_requests_);
+        ASSERT_EQ(VideoDecoder::kNotEnoughData, last_decode_status_);
+        ASSERT_FALSE(last_decoded_frame_);
         break;
-      case ABROTED:
-        EXPECT_FALSE(is_decode_pending_);
-        ASSERT_EQ(VideoDecoder::kOk, decode_status_);
-        EXPECT_FALSE(frame_decoded_);
+      case ABORTED:
+        EXPECT_EQ(0, pending_decode_requests_);
+        ASSERT_EQ(VideoDecoder::kAborted, last_decode_status_);
+        EXPECT_FALSE(last_decoded_frame_);
         break;
       case EOS:
-        EXPECT_FALSE(is_decode_pending_);
-        ASSERT_EQ(VideoDecoder::kOk, decode_status_);
-        ASSERT_TRUE(frame_decoded_);
-        EXPECT_TRUE(frame_decoded_->end_of_stream());
+        EXPECT_EQ(0, pending_decode_requests_);
+        ASSERT_EQ(VideoDecoder::kOk, last_decode_status_);
+        ASSERT_TRUE(last_decoded_frame_);
+        EXPECT_TRUE(last_decoded_frame_->end_of_stream());
         break;
     }
   }
@@ -118,9 +117,7 @@
       buffer = DecoderBuffer::CreateEOSBuffer();
     }
 
-    decode_status_ = VideoDecoder::kDecodeError;
-    frame_decoded_ = NULL;
-    is_decode_pending_ = true;
+    ++pending_decode_requests_;
 
     decoder_->Decode(
         buffer,
@@ -131,20 +128,20 @@
   void ReadOneFrame() {
     do {
       Decode();
-    } while (decode_status_ == VideoDecoder::kNotEnoughData &&
-             !is_decode_pending_);
+    } while (last_decode_status_ == VideoDecoder::kNotEnoughData &&
+             pending_decode_requests_ == 0);
   }
 
   void ReadUntilEOS() {
     do {
       ReadOneFrame();
-    } while (frame_decoded_ && !frame_decoded_->end_of_stream());
+    } while (last_decoded_frame_ && !last_decoded_frame_->end_of_stream());
   }
 
   void EnterPendingReadState() {
     // Pass the initial NOT_ENOUGH_DATA stage.
     ReadOneFrame();
-    decoder_->HoldNextDecode();
+    decoder_->HoldDecode();
     ReadOneFrame();
     ExpectReadResult(PENDING);
   }
@@ -202,7 +199,7 @@
     message_loop_.RunUntilIdle();
 
     // All pending callbacks must have been fired.
-    DCHECK(!is_decode_pending_);
+    DCHECK_EQ(pending_decode_requests_, 0);
     DCHECK(!is_reset_pending_);
   }
 
@@ -215,26 +212,33 @@
   int num_decoded_frames_;
 
   // Callback result/status.
-  VideoDecoder::Status decode_status_;
-  scoped_refptr<VideoFrame> frame_decoded_;
-  bool is_decode_pending_;
+  VideoDecoder::Status last_decode_status_;
+  scoped_refptr<VideoFrame> last_decoded_frame_;
+  int pending_decode_requests_;
   bool is_reset_pending_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoderTest);
 };
 
-TEST_F(FakeVideoDecoderTest, Initialize) {
+INSTANTIATE_TEST_CASE_P(NoParallelDecode,
+                        FakeVideoDecoderTest,
+                        ::testing::Values(1));
+INSTANTIATE_TEST_CASE_P(ParallelDecode,
+                        FakeVideoDecoderTest,
+                        ::testing::Values(3));
+
+TEST_P(FakeVideoDecoderTest, Initialize) {
   Initialize();
 }
 
-TEST_F(FakeVideoDecoderTest, Read_AllFrames) {
+TEST_P(FakeVideoDecoderTest, Read_AllFrames) {
   Initialize();
   ReadUntilEOS();
   EXPECT_EQ(kTotalBuffers, num_decoded_frames_);
 }
 
-TEST_F(FakeVideoDecoderTest, Read_DecodingDelay) {
+TEST_P(FakeVideoDecoderTest, Read_DecodingDelay) {
   Initialize();
 
   while (num_input_buffers_ < kTotalBuffers) {
@@ -243,8 +247,8 @@
   }
 }
 
-TEST_F(FakeVideoDecoderTest, Read_ZeroDelay) {
-  decoder_.reset(new FakeVideoDecoder(0, false));
+TEST_P(FakeVideoDecoderTest, Read_ZeroDelay) {
+  decoder_.reset(new FakeVideoDecoder(0, false, 1));
   Initialize();
 
   while (num_input_buffers_ < kTotalBuffers) {
@@ -253,22 +257,56 @@
   }
 }
 
-TEST_F(FakeVideoDecoderTest, Read_Pending_NotEnoughData) {
+TEST_P(FakeVideoDecoderTest, Read_Pending_NotEnoughData) {
   Initialize();
-  decoder_->HoldNextDecode();
+  decoder_->HoldDecode();
   ReadOneFrame();
   ExpectReadResult(PENDING);
   SatisfyReadAndExpect(NOT_ENOUGH_DATA);
 }
 
-TEST_F(FakeVideoDecoderTest, Read_Pending_OK) {
+TEST_P(FakeVideoDecoderTest, Read_Pending_OK) {
   Initialize();
   ReadOneFrame();
   EnterPendingReadState();
   SatisfyReadAndExpect(OK);
 }
 
-TEST_F(FakeVideoDecoderTest, Reinitialize) {
+TEST_P(FakeVideoDecoderTest, Read_Parallel) {
+  int max_decode_requests = GetParam();
+  if (max_decode_requests < 2)
+    return;
+
+  Initialize();
+  ReadOneFrame();
+  decoder_->HoldDecode();
+  for (int i = 0; i < max_decode_requests; ++i) {
+    ReadOneFrame();
+    ExpectReadResult(PENDING);
+  }
+  EXPECT_EQ(max_decode_requests, pending_decode_requests_);
+  SatisfyReadAndExpect(OK);
+}
+
+TEST_P(FakeVideoDecoderTest, ReadWithHold_DecodingDelay) {
+  Initialize();
+
+  // Hold all decodes and satisfy one decode at a time.
+  decoder_->HoldDecode();
+  int num_decodes_satisfied = 0;
+  while (num_decoded_frames_ == 0) {
+    while (pending_decode_requests_ < decoder_->GetMaxDecodeRequests())
+      Decode();
+    decoder_->SatisfySingleDecode();
+    ++num_decodes_satisfied;
+    message_loop_.RunUntilIdle();
+  }
+
+  DCHECK_EQ(num_decoded_frames_, 1);
+  DCHECK_EQ(num_decodes_satisfied, kDecodingDelay + 1);
+}
+
+TEST_P(FakeVideoDecoderTest, Reinitialize) {
   Initialize();
   ReadOneFrame();
   InitializeWithConfig(TestVideoConfig::Large());
@@ -277,7 +315,7 @@
 
 // Reinitializing the decoder during the middle of the decoding process can
 // cause dropped frames.
-TEST_F(FakeVideoDecoderTest, Reinitialize_FrameDropped) {
+TEST_P(FakeVideoDecoderTest, Reinitialize_FrameDropped) {
   Initialize();
   ReadOneFrame();
   Initialize();
@@ -285,66 +323,66 @@
   EXPECT_LT(num_decoded_frames_, kTotalBuffers);
 }
 
-TEST_F(FakeVideoDecoderTest, Reset) {
+TEST_P(FakeVideoDecoderTest, Reset) {
   Initialize();
   ReadOneFrame();
   ResetAndExpect(OK);
 }
 
-TEST_F(FakeVideoDecoderTest, Reset_DuringPendingRead) {
+TEST_P(FakeVideoDecoderTest, Reset_DuringPendingRead) {
   Initialize();
   EnterPendingReadState();
   ResetAndExpect(PENDING);
-  SatisfyRead();
+  SatisfyReadAndExpect(ABORTED);
 }
 
-TEST_F(FakeVideoDecoderTest, Reset_Pending) {
+TEST_P(FakeVideoDecoderTest, Reset_Pending) {
   Initialize();
   EnterPendingResetState();
   SatisfyReset();
 }
 
-TEST_F(FakeVideoDecoderTest, Reset_PendingDuringPendingRead) {
+TEST_P(FakeVideoDecoderTest, Reset_PendingDuringPendingRead) {
   Initialize();
   EnterPendingReadState();
   EnterPendingResetState();
-  SatisfyRead();
+  SatisfyReadAndExpect(ABORTED);
   SatisfyReset();
 }
 
-TEST_F(FakeVideoDecoderTest, Stop) {
+TEST_P(FakeVideoDecoderTest, Stop) {
   Initialize();
   ReadOneFrame();
   ExpectReadResult(OK);
   Stop();
 }
 
-TEST_F(FakeVideoDecoderTest, Stop_DuringPendingInitialization) {
+TEST_P(FakeVideoDecoderTest, Stop_DuringPendingInitialization) {
   EnterPendingInitState();
   Stop();
 }
 
-TEST_F(FakeVideoDecoderTest, Stop_DuringPendingRead) {
+TEST_P(FakeVideoDecoderTest, Stop_DuringPendingRead) {
   Initialize();
   EnterPendingReadState();
   Stop();
 }
 
-TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReset) {
+TEST_P(FakeVideoDecoderTest, Stop_DuringPendingReset) {
   Initialize();
   EnterPendingResetState();
   Stop();
 }
 
-TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReadAndPendingReset) {
+TEST_P(FakeVideoDecoderTest, Stop_DuringPendingReadAndPendingReset) {
   Initialize();
   EnterPendingReadState();
   EnterPendingResetState();
   Stop();
 }
 
-TEST_F(FakeVideoDecoderTest, GetDecodeOutput) {
-  decoder_.reset(new FakeVideoDecoder(kDecodingDelay, true));
+TEST_P(FakeVideoDecoderTest, GetDecodeOutput) {
+  decoder_.reset(new FakeVideoDecoder(kDecodingDelay, true, 1));
   Initialize();
 
   while (num_input_buffers_ < kTotalBuffers) {
diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc
index fec5da5..00832a0 100644
--- a/media/filters/ffmpeg_audio_decoder.cc
+++ b/media/filters/ffmpeg_audio_decoder.cc
@@ -126,8 +126,12 @@
 }
 
 FFmpegAudioDecoder::FFmpegAudioDecoder(
-    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
-    : task_runner_(task_runner), state_(kUninitialized), av_sample_format_(0) {
+    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+    const LogCB& log_cb)
+    : task_runner_(task_runner),
+      state_(kUninitialized),
+      av_sample_format_(0),
+      log_cb_(log_cb) {
 }
 
 FFmpegAudioDecoder::~FFmpegAudioDecoder() {
@@ -351,6 +355,12 @@
                     << ", Sample Format: " << av_frame_->format << " vs "
                     << av_sample_format_;
 
+        if (config_.codec() == kCodecAAC &&
+            av_frame_->sample_rate == 2 * config_.samples_per_second()) {
+          MEDIA_LOG(log_cb_) << "Implicit HE-AAC signalling is being used."
+                             << " Please use mp4a.40.5 instead of mp4a.40.2 in"
+                             << " the mimetype.";
+        }
         // This is an unrecoverable error, so bail out.
         queued_audio_.clear();
         av_frame_unref(av_frame_.get());
@@ -427,7 +437,8 @@
 
   // Success!
   av_frame_.reset(av_frame_alloc());
-  discard_helper_.reset(new AudioDiscardHelper(config_.samples_per_second()));
+  discard_helper_.reset(new AudioDiscardHelper(config_.samples_per_second(),
+                                               config_.codec_delay()));
   av_sample_format_ = codec_context_->sample_fmt;
 
   if (codec_context_->channels !=
diff --git a/media/filters/ffmpeg_audio_decoder.h b/media/filters/ffmpeg_audio_decoder.h
index ea3bc46..8936022 100644
--- a/media/filters/ffmpeg_audio_decoder.h
+++ b/media/filters/ffmpeg_audio_decoder.h
@@ -12,6 +12,7 @@
 #include "base/time/time.h"
 #include "media/base/audio_decoder.h"
 #include "media/base/demuxer_stream.h"
+#include "media/base/media_log.h"
 #include "media/base/sample_format.h"
 #include "media/ffmpeg/ffmpeg_deleters.h"
 
@@ -29,8 +30,9 @@
 
 class MEDIA_EXPORT FFmpegAudioDecoder : public AudioDecoder {
  public:
-  explicit FFmpegAudioDecoder(
-      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
+  FFmpegAudioDecoder(
+      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+      const LogCB& log_cb);
   virtual ~FFmpegAudioDecoder();
 
   // AudioDecoder implementation.
@@ -87,6 +89,8 @@
   // them up.
   std::list<scoped_refptr<AudioBuffer> > queued_audio_;
 
+  LogCB log_cb_;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(FFmpegAudioDecoder);
 };
 
diff --git a/media/filters/ffmpeg_audio_decoder_unittest.cc b/media/filters/ffmpeg_audio_decoder_unittest.cc
index 60d1f40..ccd30aa 100644
--- a/media/filters/ffmpeg_audio_decoder_unittest.cc
+++ b/media/filters/ffmpeg_audio_decoder_unittest.cc
@@ -26,7 +26,8 @@
 class FFmpegAudioDecoderTest : public testing::Test {
  public:
   FFmpegAudioDecoderTest()
-      : decoder_(new FFmpegAudioDecoder(message_loop_.message_loop_proxy())),
+      : decoder_(new FFmpegAudioDecoder(message_loop_.message_loop_proxy(),
+                                        LogCB())),
         pending_decode_(false),
         pending_reset_(false) {
     FFmpegGlue::InitializeFFmpeg();
@@ -175,7 +176,7 @@
   ASSERT_EQ(3u, decoded_audio_.size());
   ExpectDecodedAudio(0, 0, 2902);
   ExpectDecodedAudio(1, 2902, 13061);
-  ExpectDecodedAudio(2, 15963, 23220);
+  ExpectDecodedAudio(2, 15963, 23219);
 
   // Call one more time to trigger EOS.
   Decode();
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index 40a8c91..dd41410 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -50,6 +50,11 @@
   return base::Time();
 }
 
+static base::TimeDelta FramesToTimeDelta(int frames, double sample_rate) {
+  return base::TimeDelta::FromMicroseconds(
+      frames * base::Time::kMicrosecondsPerSecond / sample_rate);
+}
+
 //
 // FFmpegDemuxerStream
 //
@@ -90,10 +95,12 @@
   // Calculate the duration.
   duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration);
 
+#if defined(USE_PROPRIETARY_CODECS)
   if (stream_->codec->codec_id == AV_CODEC_ID_H264) {
     bitstream_converter_.reset(
         new FFmpegH264ToAnnexBBitstreamConverter(stream_->codec));
   }
+#endif
 
   if (is_encrypted) {
     AVDictionaryEntry* key = av_dict_get(stream->metadata, "enc_key_id", NULL,
@@ -122,11 +129,13 @@
     return;
   }
 
+#if defined(USE_PROPRIETARY_CODECS)
   // Convert the packet if there is a bitstream filter.
   if (packet->data && bitstream_converter_enabled_ &&
       !bitstream_converter_->ConvertPacket(packet.get())) {
     LOG(ERROR) << "Format conversion failed.";
   }
+#endif
 
   // Get side data if any. For now, the only type of side_data is VP8 Alpha. We
   // keep this generic so that other side_data types in the future can be
@@ -189,20 +198,28 @@
     }
 
     int skip_samples_size = 0;
-    uint8* skip_samples = av_packet_get_side_data(packet.get(),
-                                                  AV_PKT_DATA_SKIP_SAMPLES,
-                                                  &skip_samples_size);
+    const uint32* skip_samples_ptr =
+        reinterpret_cast<const uint32*>(av_packet_get_side_data(
+            packet.get(), AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
     const int kSkipSamplesValidSize = 10;
-    const int kSkipSamplesOffset = 4;
+    const int kSkipEndSamplesOffset = 1;
     if (skip_samples_size >= kSkipSamplesValidSize) {
-      int discard_padding_samples = base::ByteSwapToLE32(
-          *(reinterpret_cast<const uint32*>(skip_samples +
-                                            kSkipSamplesOffset)));
-      // TODO(vigneshv): Change decoder buffer to use number of samples so that
-      // this conversion can be avoided.
-      buffer->set_discard_padding(base::TimeDelta::FromMicroseconds(
-          discard_padding_samples * 1000000.0 /
-          audio_decoder_config().samples_per_second()));
+      // Because FFmpeg rolls codec delay and skip samples into one we can only
+      // allow front discard padding on the first buffer.  Otherwise the discard
+      // helper can't figure out which data to discard.  See AudioDiscardHelper.
+      int discard_front_samples = base::ByteSwapToLE32(*skip_samples_ptr);
+      if (last_packet_timestamp_ != kNoTimestamp()) {
+        DLOG(ERROR) << "Skip samples are only allowed for the first packet.";
+        discard_front_samples = 0;
+      }
+
+      const int discard_end_samples =
+          base::ByteSwapToLE32(*(skip_samples_ptr + kSkipEndSamplesOffset));
+      const int samples_per_second =
+          audio_decoder_config().samples_per_second();
+      buffer->set_discard_padding(std::make_pair(
+          FramesToTimeDelta(discard_front_samples, samples_per_second),
+          FramesToTimeDelta(discard_end_samples, samples_per_second)));
     }
 
     if (decrypt_config)
@@ -280,8 +297,13 @@
 
 void FFmpegDemuxerStream::EnableBitstreamConverter() {
   DCHECK(task_runner_->BelongsToCurrentThread());
+
+#if defined(USE_PROPRIETARY_CODECS)
   CHECK(bitstream_converter_.get());
   bitstream_converter_enabled_ = true;
+#else
+  NOTREACHED() << "Proprietary codecs not enabled.";
+#endif
 }
 
 bool FFmpegDemuxerStream::SupportsConfigChanges() { return false; }
diff --git a/media/filters/ffmpeg_demuxer.h b/media/filters/ffmpeg_demuxer.h
index c04803b..778ab5a 100644
--- a/media/filters/ffmpeg_demuxer.h
+++ b/media/filters/ffmpeg_demuxer.h
@@ -129,7 +129,10 @@
   DecoderBufferQueue buffer_queue_;
   ReadCB read_cb_;
 
+#if defined(USE_PROPRIETARY_CODECS)
   scoped_ptr<FFmpegH264ToAnnexBBitstreamConverter> bitstream_converter_;
+#endif
+
   bool bitstream_converter_enabled_;
 
   std::string encryption_key_id_;
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc
index 9b684ff..cab5963 100644
--- a/media/filters/ffmpeg_demuxer_unittest.cc
+++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/files/file_path.h"
+#include "base/logging.h"
 #include "base/path_service.h"
 #include "base/threading/thread.h"
 #include "media/base/decrypt_config.h"
@@ -17,6 +18,7 @@
 #include "media/ffmpeg/ffmpeg_common.h"
 #include "media/filters/ffmpeg_demuxer.h"
 #include "media/filters/file_data_source.h"
+#include "media/formats/mp4/avc.h"
 #include "media/formats/webm/webm_crypto_helpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -725,6 +727,60 @@
   InitializeDemuxer();
   ReadUntilEndOfStream(demuxer_->GetStream(DemuxerStream::AUDIO));
 }
+
+
+static void ValidateAnnexB(DemuxerStream* stream,
+                           DemuxerStream::Status status,
+                           const scoped_refptr<DecoderBuffer>& buffer) {
+  EXPECT_EQ(status, DemuxerStream::kOk);
+
+  if (buffer->end_of_stream()) {
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
+    return;
+  }
+
+  bool is_valid =
+      mp4::AVC::IsValidAnnexB(buffer->data(), buffer->data_size());
+  EXPECT_TRUE(is_valid);
+
+  if (!is_valid) {
+    LOG(ERROR) << "Buffer contains invalid Annex B data.";
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
+    return;
+  }
+
+  stream->Read(base::Bind(&ValidateAnnexB, stream));
+};
+
+TEST_F(FFmpegDemuxerTest, IsValidAnnexB) {
+  const char* files[] = {
+    "bear-1280x720-av_frag.mp4",
+    "bear-1280x720-av_with-aud-nalus_frag.mp4"
+  };
+
+  for (size_t i = 0; i < arraysize(files); ++i) {
+    DVLOG(1) << "Testing " << files[i];
+    CreateDemuxer(files[i]);
+    InitializeDemuxer();
+
+    // Ensure the expected streams are present.
+    DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
+    ASSERT_TRUE(stream);
+    stream->EnableBitstreamConverter();
+
+    stream->Read(base::Bind(&ValidateAnnexB, stream));
+    message_loop_.Run();
+
+    WaitableMessageLoopEvent event;
+    demuxer_->Stop(event.GetClosure());
+    event.RunAndWait();
+    demuxer_.reset();
+    data_source_.reset();
+  }
+}
+
 #endif
 
 }  // namespace media
diff --git a/media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.cc b/media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.cc
index 31f03f5..17eff7b 100644
--- a/media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.cc
+++ b/media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.cc
@@ -6,6 +6,7 @@
 
 #include "base/logging.h"
 #include "media/ffmpeg/ffmpeg_common.h"
+#include "media/formats/mp4/box_definitions.h"
 
 namespace media {
 
@@ -19,43 +20,37 @@
 FFmpegH264ToAnnexBBitstreamConverter::~FFmpegH264ToAnnexBBitstreamConverter() {}
 
 bool FFmpegH264ToAnnexBBitstreamConverter::ConvertPacket(AVPacket* packet) {
-  uint32 output_packet_size = 0;
-  uint32 configuration_size = 0;
-  uint32 io_size = 0;
-  if (packet == NULL) {
+  scoped_ptr<mp4::AVCDecoderConfigurationRecord> avc_config;
+
+  if (packet == NULL || !packet->data)
     return false;
-  }
 
   // Calculate the needed output buffer size.
   if (!configuration_processed_) {
-    // FFmpeg's AVCodecContext's extradata field contains the Decoder
-    // Specific Information from MP4 headers that contain the H.264 SPS and
-    // PPS members. See ISO/IEC 14496-15 Chapter 5.2.4
-    // AVCDecoderConfigurationRecord for exact specification.
-    // Extradata must be at least 7 bytes long.
-    if (stream_context_->extradata == NULL ||
-        stream_context_->extradata_size <= 7) {
-      return false;  // Can't go on with conversion without configuration.
-    }
-    configuration_size += converter_.ParseConfigurationAndCalculateSize(
-        stream_context_->extradata,
-        stream_context_->extradata_size);
-    if (configuration_size == 0) {
-      return false;  // Not possible to parse the configuration.
+    if (!stream_context_->extradata || stream_context_->extradata_size <= 0)
+      return false;
+
+    avc_config.reset(new mp4::AVCDecoderConfigurationRecord());
+
+    if (!converter_.ParseConfiguration(
+            stream_context_->extradata,
+            stream_context_->extradata_size,
+            avc_config.get())) {
+      return false;
     }
   }
-  uint32 output_nal_size =
-      converter_.CalculateNeededOutputBufferSize(packet->data, packet->size);
-  if (output_nal_size == 0) {
+
+  uint32 output_packet_size = converter_.CalculateNeededOutputBufferSize(
+      packet->data, packet->size, avc_config.get());
+
+  if (output_packet_size == 0)
     return false;  // Invalid input packet.
-  }
-  output_packet_size = configuration_size + output_nal_size;
 
   // Allocate new packet for the output.
   AVPacket dest_packet;
-  if (av_new_packet(&dest_packet, output_packet_size) != 0) {
+  if (av_new_packet(&dest_packet, output_packet_size) != 0)
     return false;  // Memory allocation failure.
-  }
+
   // This is a bit tricky: since the interface does not allow us to replace
   // the pointer of the old packet with a new one, we will initially copy the
   // metadata from old packet to new bigger packet.
@@ -67,25 +62,19 @@
   dest_packet.flags = packet->flags;
   dest_packet.stream_index = packet->stream_index;
 
-  // Process the configuration if not done earlier.
-  if (!configuration_processed_) {
-    if (!converter_.ConvertAVCDecoderConfigToByteStream(
-            stream_context_->extradata, stream_context_->extradata_size,
-            dest_packet.data, &configuration_size)) {
-      return false;  // Failed to convert the buffer.
-    }
-    configuration_processed_ = true;
-  }
-
   // Proceed with the conversion of the actual in-band NAL units, leave room
   // for configuration in the beginning.
-  io_size = dest_packet.size - configuration_size;
+  uint32 io_size = dest_packet.size;
   if (!converter_.ConvertNalUnitStreamToByteStream(
           packet->data, packet->size,
-          dest_packet.data + configuration_size, &io_size)) {
+          avc_config.get(),
+          dest_packet.data, &io_size)) {
     return false;
   }
 
+  if (avc_config)
+    configuration_processed_ = true;
+
   // At the end we must destroy the old packet.
   av_free_packet(packet);
   *packet = dest_packet;  // Finally, replace the values in the input packet.
@@ -94,4 +83,3 @@
 }
 
 }  // namespace media
-
diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc
index 12980c1..bc2346d 100644
--- a/media/filters/ffmpeg_video_decoder.cc
+++ b/media/filters/ffmpeg_video_decoder.cc
@@ -72,8 +72,8 @@
          format == VideoFrame::YV12J);
 
   gfx::Size size(codec_context->width, codec_context->height);
-  int ret;
-  if ((ret = av_image_check_size(size.width(), size.height(), 0, NULL)) < 0)
+  const int ret = av_image_check_size(size.width(), size.height(), 0, NULL);
+  if (ret < 0)
     return ret;
 
   gfx::Size natural_size;
@@ -85,12 +85,22 @@
     natural_size = config_.natural_size();
   }
 
-  if (!VideoFrame::IsValidConfig(format, size, gfx::Rect(size), natural_size))
+  // FFmpeg has specific requirements on the allocation size of the frame.  The
+  // following logic replicates FFmpeg's allocation strategy to ensure buffers
+  // are not overread / overwritten.  See ff_init_buffer_info() for details.
+  //
+  // When lowres is non-zero, dimensions should be divided by 2^(lowres), but
+  // since we don't use this, just DCHECK that it's zero.
+  DCHECK_EQ(codec_context->lowres, 0);
+  gfx::Size coded_size(std::max(size.width(), codec_context->coded_width),
+                       std::max(size.height(), codec_context->coded_height));
+
+  if (!VideoFrame::IsValidConfig(
+          format, coded_size, gfx::Rect(size), natural_size))
     return AVERROR(EINVAL);
 
-  scoped_refptr<VideoFrame> video_frame =
-      frame_pool_.CreateFrame(format, size, gfx::Rect(size),
-                              natural_size, kNoTimestamp());
+  scoped_refptr<VideoFrame> video_frame = frame_pool_.CreateFrame(
+      format, coded_size, gfx::Rect(size), natural_size, kNoTimestamp());
 
   for (int i = 0; i < 3; i++) {
     frame->base[i] = video_frame->data(i);
@@ -101,8 +111,8 @@
   frame->opaque = NULL;
   video_frame.swap(reinterpret_cast<VideoFrame**>(&frame->opaque));
   frame->type = FF_BUFFER_TYPE_USER;
-  frame->width = codec_context->width;
-  frame->height = codec_context->height;
+  frame->width = coded_size.width();
+  frame->height = coded_size.height();
   frame->format = codec_context->pix_fmt;
 
   return 0;
diff --git a/media/filters/h264_to_annex_b_bitstream_converter.cc b/media/filters/h264_to_annex_b_bitstream_converter.cc
index fc45607..49456dd 100644
--- a/media/filters/h264_to_annex_b_bitstream_converter.cc
+++ b/media/filters/h264_to_annex_b_bitstream_converter.cc
@@ -5,10 +5,13 @@
 #include "media/filters/h264_to_annex_b_bitstream_converter.h"
 
 #include "base/logging.h"
+#include "media/filters/h264_parser.h"
+#include "media/formats/mp4/box_definitions.h"
 
 namespace media {
 
 static const uint8 kStartCodePrefix[3] = {0, 0, 1};
+static const uint32 kParamSetStartCodeSize = 1 + sizeof(kStartCodePrefix);
 
 // Helper function which determines whether NAL unit of given type marks
 // access unit boundary.
@@ -33,80 +36,55 @@
 
 H264ToAnnexBBitstreamConverter::~H264ToAnnexBBitstreamConverter() {}
 
-uint32 H264ToAnnexBBitstreamConverter::ParseConfigurationAndCalculateSize(
+bool H264ToAnnexBBitstreamConverter::ParseConfiguration(
     const uint8* configuration_record,
-    uint32 configuration_record_size) {
-  // FFmpeg's AVCodecContext's extradata field contains the Decoder Specific
-  // Information from MP4 headers that contain the H.264 SPS and PPS members.
-  // ISO 14496-15 Chapter 5.2.4 AVCDecoderConfigurationRecord.
-  // AVCConfigurationRecord must be at least 7 bytes long.
-  if (configuration_record == NULL || configuration_record_size < 7) {
-    return 0;  // Error: invalid input
-  }
-  const uint8* decoder_configuration = configuration_record;
-  uint32 parameter_set_size_bytes = 0;
+    int configuration_record_size,
+    mp4::AVCDecoderConfigurationRecord* avc_config) {
+  DCHECK(configuration_record);
+  DCHECK_GT(configuration_record_size, 0);
+  DCHECK(avc_config);
 
-  // We can skip the four first bytes as they're only profile information
-  decoder_configuration += 4;
-  // Fifth byte's two LSBs contain the interleaving field's size minus one
-  uint8 size_of_len_field = (*decoder_configuration & 0x3) + 1;
-  if (size_of_len_field != 1 && size_of_len_field != 2 &&
-      size_of_len_field != 4) {
-    return 0;  // Error: invalid input, NAL unit field len is not correct
-  }
-  decoder_configuration++;
-  // Sixth byte's five LSBs contain the number of SPSs
-  uint8 sps_count = *decoder_configuration & 0x1F;
-  decoder_configuration++;
-  // Then we have N * SPS's with two byte length field and actual SPS
-  while (sps_count-- > 0) {
-    if ((decoder_configuration - configuration_record) + 2 >
-         static_cast<int32>(configuration_record_size)) {
-      return 0;  // Error: ran out of data
-    }
-    uint16 sps_len = decoder_configuration[0] << 8 | decoder_configuration[1];
-    decoder_configuration += 2;
-    // write the SPS to output, always with zero byte + start code prefix
-    parameter_set_size_bytes += 1 + sizeof(kStartCodePrefix);
-    decoder_configuration += sps_len;
-    parameter_set_size_bytes += sps_len;
-  }
-  // Then we have the numner of pps in one byte
-  uint8 pps_count = *decoder_configuration;
-  decoder_configuration++;
-  // And finally, we have N * PPS with two byte length field and actual PPS
-  while (pps_count-- > 0) {
-    if ((decoder_configuration - configuration_record) + 2 >
-         static_cast<int32>(configuration_record_size)) {
-      return 0;  // Error: ran out of data
-    }
-    uint16 pps_len = decoder_configuration[0] << 8 | decoder_configuration[1];
-    decoder_configuration += 2;
-    // write the SPS to output, always with zero byte + start code prefix
-    parameter_set_size_bytes += 1 + sizeof(kStartCodePrefix);
-    decoder_configuration += pps_len;
-    parameter_set_size_bytes += pps_len;
-  }
+  if (!avc_config->Parse(configuration_record, configuration_record_size))
+    return false;  // Error: invalid input
+
   // We're done processing the AVCDecoderConfigurationRecord,
   // store the needed information for parsing actual payload
-  nal_unit_length_field_width_ = size_of_len_field;
+  nal_unit_length_field_width_ = avc_config->length_size;
   configuration_processed_ = true;
-  return parameter_set_size_bytes;
+  return true;
+}
+
+uint32 H264ToAnnexBBitstreamConverter::GetConfigSize(
+    const mp4::AVCDecoderConfigurationRecord& avc_config) const {
+  uint32 config_size = 0;
+
+  for (size_t i = 0; i < avc_config.sps_list.size(); ++i)
+    config_size += kParamSetStartCodeSize + avc_config.sps_list[i].size();
+
+  for (size_t i = 0; i < avc_config.pps_list.size(); ++i)
+    config_size += kParamSetStartCodeSize + avc_config.pps_list[i].size();
+
+  return config_size;
 }
 
 uint32 H264ToAnnexBBitstreamConverter::CalculateNeededOutputBufferSize(
     const uint8* input,
-    uint32 input_size) const {
+    uint32 input_size,
+    const mp4::AVCDecoderConfigurationRecord* avc_config) const {
   uint32 output_size = 0;
   uint32 data_left = input_size;
   bool first_nal_in_this_access_unit = first_nal_unit_in_access_unit_;
 
-  if (input == NULL || input_size == 0) {
+  if (input_size == 0)
     return 0;  // Error: invalid input data
-  }
+
   if (!configuration_processed_) {
     return 0;  // Error: configuration not handled, we don't know nal unit width
   }
+
+  if (avc_config)
+    output_size += GetConfigSize(*avc_config);
+
   CHECK(nal_unit_length_field_width_ == 1 ||
         nal_unit_length_field_width_ == 2 ||
         nal_unit_length_field_width_ == 4);
@@ -152,93 +130,37 @@
 }
 
 bool H264ToAnnexBBitstreamConverter::ConvertAVCDecoderConfigToByteStream(
-    const uint8* input,
-    uint32 input_size,
+    const mp4::AVCDecoderConfigurationRecord& avc_config,
     uint8* output,
     uint32* output_size) {
-  uint8* outscan = output;
-  // FFmpeg's AVCodecContext's extradata field contains the Decoder Specific
-  // Information from MP4 headers that contain the H.264 SPS and PPS members.
-  // ISO 14496-15 Chapter 5.2.4 AVCDecoderConfigurationRecord.
-  const uint8* decoder_configuration = input;
-  uint32 decoderconfiguration_size = input_size;
-  uint32 out_size = 0;
-
-  if (decoder_configuration == NULL || decoderconfiguration_size == 0) {
-    return 0;  // Error: input invalid
+  uint8* out = output;
+  uint32 out_size = *output_size;
+  *output_size = 0;
+  for (size_t i = 0; i < avc_config.sps_list.size(); ++i) {
+    if (!WriteParamSet(avc_config.sps_list[i], &out, &out_size))
+      return false;
   }
 
-  // We can skip the four first bytes as they're only profile information.
-  decoder_configuration += 4;
-  // Fifth byte's two LSBs contain the interleaving field's size minus one
-  uint8 size_of_len_field = (*decoder_configuration & 0x3) + 1;
-  if (size_of_len_field != 1 && size_of_len_field != 2 &&
-      size_of_len_field != 4) {
-    return 0;  // Error: invalid input, NAL unit field len is not correct
+  for (size_t i = 0; i < avc_config.pps_list.size(); ++i) {
+    if (!WriteParamSet(avc_config.pps_list[i], &out, &out_size))
+      return false;
   }
-  decoder_configuration++;
-  // Sixth byte's five LSBs contain the number of SPSs
-  uint8 sps_count = *decoder_configuration & 0x1F;
-  decoder_configuration++;
-  // Then we have N * SPS's with two byte length field and actual SPS
-  while (sps_count-- > 0) {
-    uint16 sps_len = decoder_configuration[0] << 8 |
-                     decoder_configuration[1];
-    decoder_configuration += 2;
-    if (out_size + 1 + sizeof(kStartCodePrefix) + sps_len >
-        *output_size) {
-      *output_size = 0;
-      return 0;  // too small output buffer;
-    }
-    // write the SPS to output, always with zero byte + start code prefix
-    *outscan = 0;  // zero byte
-    outscan += 1;
-    memcpy(outscan, kStartCodePrefix, sizeof(kStartCodePrefix));
-    outscan += sizeof(kStartCodePrefix);
-    memcpy(outscan, decoder_configuration, sps_len);
-    decoder_configuration += sps_len;
-    outscan += sps_len;
-    out_size += 1 + sizeof(kStartCodePrefix) + sps_len;
-  }
-  // Then we have the numner of pps in one byte
-  uint8 pps_count = *decoder_configuration;
-  decoder_configuration++;
-  // And finally, we have N * PPS with two byte length field and actual PPS
-  while (pps_count-- > 0) {
-    uint16 pps_len = decoder_configuration[0] << 8 | decoder_configuration[1];
-    decoder_configuration += 2;
-    if (out_size + 1 + sizeof(kStartCodePrefix) + pps_len >
-        *output_size) {
-      *output_size = 0;
-      return 0;  // too small output buffer;
-    }
-    // write the SPS to output, always with zero byte + start code prefix
-    *outscan = 0;  // zero byte
-    outscan += 1;
-    memcpy(outscan, kStartCodePrefix, sizeof(kStartCodePrefix));
-    outscan += sizeof(kStartCodePrefix);
-    memcpy(outscan, decoder_configuration, pps_len);
-    decoder_configuration += pps_len;
-    outscan += pps_len;
-    out_size += 1 + sizeof(kStartCodePrefix) + pps_len;
-  }
-  // We're done processing the AVCDecoderConfigurationRecord, store the needed
-  // information
-  nal_unit_length_field_width_ = size_of_len_field;
+
+  nal_unit_length_field_width_ = avc_config.length_size;
   configuration_processed_ = true;
-  *output_size = out_size;
+  *output_size = out - output;
   return true;
 }
 
 bool H264ToAnnexBBitstreamConverter::ConvertNalUnitStreamToByteStream(
     const uint8* input, uint32 input_size,
+    const mp4::AVCDecoderConfigurationRecord* avc_config,
     uint8* output, uint32* output_size) {
   const uint8* inscan = input;  // We read the input from here progressively
   uint8* outscan = output;  // We write the output to here progressively
   uint32 data_left = input_size;
 
-  if (inscan == NULL || input_size == 0 ||
-      outscan == NULL || *output_size == 0) {
+  if (input_size == 0 || *output_size == 0) {
     *output_size = 0;
     return false;  // Error: invalid input
   }
@@ -249,6 +171,7 @@
         nal_unit_length_field_width_ == 4);
 
   // Do the actual conversion for the actual input packet
+  int nal_unit_count = 0;
   while (data_left > 0) {
     uint8 i;
     uint32 nal_unit_length;
@@ -269,6 +192,30 @@
       return false;  // Error: not enough data for correct conversion
     }
 
+    // Five least significant bits of first NAL unit byte signify
+    // nal_unit_type.
+    int nal_unit_type = *inscan & 0x1F;
+    nal_unit_count++;
+
+    // Insert the config after the AUD if an AUD is the first NAL unit or
+    // before all NAL units if the first one isn't an AUD.
+    if (avc_config &&
+        (nal_unit_type != H264NALU::kAUD ||  nal_unit_count > 1)) {
+      uint32 output_bytes_used = outscan - output;
+
+      DCHECK_GE(*output_size, output_bytes_used);
+
+      uint32 config_size = *output_size - output_bytes_used;
+      if (!ConvertAVCDecoderConfigToByteStream(*avc_config,
+                                               outscan,
+                                               &config_size)) {
+        DVLOG(1) << "Failed to insert parameter sets.";
+        *output_size = 0;
+        return false;  // Failed to convert the buffer.
+      }
+      outscan += config_size;
+      avc_config = NULL;
+    }
     uint32 start_code_len;
     first_nal_unit_in_access_unit_ ?
         start_code_len = sizeof(kStartCodePrefix) + 1 :
@@ -279,10 +226,6 @@
       return false;  // Error: too small output buffer
     }
 
-    // Five least significant bits of first NAL unit byte signify
-    // nal_unit_type.
-    int nal_unit_type = *inscan & 0x1F;
-
     // Check if this packet marks access unit boundary by checking the
     // packet type.
     if (IsAccessUnitBoundaryNal(nal_unit_type)) {
@@ -313,4 +256,30 @@
   return true;
 }
 
+bool H264ToAnnexBBitstreamConverter::WriteParamSet(
+    const std::vector<uint8>& param_set,
+    uint8** out,
+    uint32* out_size) const {
+  uint32 bytes_left = *out_size;
+  if (bytes_left < kParamSetStartCodeSize ||
+      bytes_left - kParamSetStartCodeSize < param_set.size()) {
+    return false;
+  }
+
+  uint8* start = *out;
+  uint8* buf = start;
+
+  // Write the 4 byte Annex B start code.
+  *buf++ = 0;  // zero byte
+  memcpy(buf, kStartCodePrefix, sizeof(kStartCodePrefix));
+  buf += sizeof(kStartCodePrefix);
+
+  memcpy(buf, &param_set[0], param_set.size());
+  buf += param_set.size();
+
+  *out = buf;
+  *out_size -= buf - start;
+  return true;
+}
+
 }  // namespace media
diff --git a/media/filters/h264_to_annex_b_bitstream_converter.h b/media/filters/h264_to_annex_b_bitstream_converter.h
index afb204a..b6a27d0 100644
--- a/media/filters/h264_to_annex_b_bitstream_converter.h
+++ b/media/filters/h264_to_annex_b_bitstream_converter.h
@@ -5,11 +5,17 @@
 #ifndef MEDIA_FILTERS_H264_TO_ANNEX_B_BITSTREAM_CONVERTER_H_
 #define MEDIA_FILTERS_H264_TO_ANNEX_B_BITSTREAM_CONVERTER_H_
 
+#include <vector>
+
 #include "base/basictypes.h"
 #include "media/base/media_export.h"
 
 namespace media {
 
+namespace mp4 {
+struct AVCDecoderConfigurationRecord;
+}
+
 // H264ToAnnexBBitstreamConverter is a class to convert H.264 bitstream from
 // MP4 format (as specified in ISO/IEC 14496-15) into H.264 bytestream
 // (as specified in ISO/IEC 14496-10 Annex B).
@@ -27,88 +33,112 @@
   //     Pointer to buffer containing AVCDecoderConfigurationRecord.
   //   configuration_record_size
   //     Size of the buffer in bytes.
+  //   avc_config
+  //     Pointer to place the parsed AVCDecoderConfigurationRecord data into.
   //
   // Returns
-  //   Required buffer size for AVCDecoderConfigurationRecord when converted
-  //   to bytestream format, or 0 if could not determine the configuration
-  //   from the input buffer.
-  uint32 ParseConfigurationAndCalculateSize(const uint8* configuration_record,
-                                            uint32 configuration_record_size);
+  //   Returns true if |configuration_record| was successfully parsed. False
+  //   is returned if a parsing error occurred.
+  //   |avc_config| only contains valid data when true is returned.
+  bool ParseConfiguration(
+      const uint8* configuration_record,
+      int configuration_record_size,
+      mp4::AVCDecoderConfigurationRecord* avc_config);
+
+  // Returns the buffer size needed to store the parameter sets in |avc_config|
+  // in Annex B form.
+  uint32 GetConfigSize(
+      const mp4::AVCDecoderConfigurationRecord& avc_config) const;
 
   // Calculates needed buffer size for the bitstream converted into bytestream.
   // Lightweight implementation that does not do the actual conversion.
   //
   // Parameters
-  //   configuration_record
-  //     Pointer to buffer containing AVCDecoderConfigurationRecord.
-  //   configuration_record_size
+  //   input
+  //     Pointer to buffer containing NAL units in MP4 format.
+  //   input_size
   //     Size of the buffer in bytes.
+  //   avc_config
+  //     The AVCDecoderConfigurationRecord that contains the parameter sets that
+  //     will be inserted into the output. NULL if no parameter sets need to be
+  //     inserted.
   //
   // Returns
-  //   Required buffer size for the input NAL unit buffer when converted
-  //   to bytestream format, or 0 if could not determine the configuration
-  //   from the input buffer.
-  uint32 CalculateNeededOutputBufferSize(const uint8* input,
-                                         uint32 input_size) const;
+  //   Required buffer size for the output NAL unit buffer when converted
+  //   to bytestream format, or 0 if could not determine the size of
+  //   the output buffer from the data in |input| and |avc_config|.
+  uint32 CalculateNeededOutputBufferSize(
+      const uint8* input,
+      uint32 input_size,
+      const mp4::AVCDecoderConfigurationRecord* avc_config) const;
 
   // ConvertAVCDecoderConfigToByteStream converts the
   // AVCDecoderConfigurationRecord from the MP4 headers to bytestream format.
   // Client is responsible for making sure the output buffer is large enough
   // to hold the output data. Client can precalculate the needed output buffer
-  // size by using ParseConfigurationAndCalculateSize.
-  //
-  // In case of failed conversion object H264BitstreamConverter may have written
-  // some bytes to buffer pointed by pinput but user should ignore those bytes.
-  // None of the outputs should be considered valid.
+  // size by using GetConfigSize().
   //
   // Parameters
-  //   pinput
-  //     Pointer to buffer containing AVCDecoderConfigurationRecord.
-  //   input_size
-  //     Size of the buffer in bytes.
-  //   poutput
+  //   avc_config
+  //     The AVCDecoderConfigurationRecord that contains the parameter sets that
+  //     will be written to |output|.
+  //   output
   //     Pointer to buffer where the output should be written to.
-  //   poutput_size (i/o)
+  //   output_size (i/o)
   //     Pointer to the size of the output buffer. Will contain the number of
   //     bytes written to output after successful call.
   //
   // Returns
-  //    true  if successful conversion
-  //    false if conversion not successful (poutput_size will hold the amount
+  //    true  if successful conversion|
+  //    false if conversion not successful (|output_size| will hold the amount
   //          of converted data)
-  bool ConvertAVCDecoderConfigToByteStream(const uint8* input,
-                                           uint32 input_size,
-                                           uint8* output,
-                                           uint32* output_size);
+  bool ConvertAVCDecoderConfigToByteStream(
+      const mp4::AVCDecoderConfigurationRecord& avc_config,
+      uint8* output,
+      uint32* output_size);
 
   // ConvertNalUnitStreamToByteStream converts the NAL unit from MP4 format
   // to bytestream format. Client is responsible for making sure the output
   // buffer is large enough to hold the output data. Client can precalculate the
   // needed output buffer size by using CalculateNeededOutputBufferSize.
   //
-  // In case of failed conversion object H264BitstreamConverter may have written
-  // some bytes to buffer pointed by pinput but user should ignore those bytes.
-  // None of the outputs should be considered valid.
-  //
   // Parameters
-  //   pinput
-  //     Pointer to buffer containing AVCDecoderConfigurationRecord.
+  //   input
+  //     Pointer to buffer containing NAL units in MP4 format.
   //   input_size
   //     Size of the buffer in bytes.
-  //   poutput
+  //   avc_config
+  //     The AVCDecoderConfigurationRecord that contains the parameter sets to
+  //     insert into the output. NULL if no parameter sets need to be inserted.
+  //   output
   //     Pointer to buffer where the output should be written to.
-  //   poutput_size (i/o)
+  //   output_size (i/o)
   //     Pointer to the size of the output buffer. Will contain the number of
   //     bytes written to output after successful call.
   //
   // Returns
   //    true  if successful conversion
-  //    false if conversion not successful (poutput_size will hold the amount
+  //    false if conversion not successful (output_size will hold the amount
   //          of converted data)
-  bool ConvertNalUnitStreamToByteStream(const uint8* input, uint32 input_size,
-                                        uint8* output, uint32* output_size);
+  bool ConvertNalUnitStreamToByteStream(
+      const uint8* input,
+      uint32 input_size,
+      const mp4::AVCDecoderConfigurationRecord* avc_config,
+      uint8* output,
+      uint32* output_size);
 
  private:
+  // Writes Annex B start code and |param_set| to |*out|.
+  //  |*out| - Is the memory location to write the parameter set.
+  //  |*out_size| - Number of bytes available for the parameter set.
+  // Returns true if the start code and param set were successfully
+  // written. On a successful write, |*out| is updated to point to the first
+  // byte after the data that was written. |*out_size| is updated to reflect
+  // the new number of bytes left in |*out|.
+  bool WriteParamSet(const std::vector<uint8>& param_set,
+                     uint8** out,
+                     uint32* out_size) const;
+
   // Flag for indicating whether global parameter sets have been processed.
   bool configuration_processed_;
   // Flag for indicating whether next NAL unit starts new access unit.
@@ -122,4 +152,3 @@
 }  // namespace media
 
 #endif  // MEDIA_FILTERS_H264_TO_ANNEX_B_BITSTREAM_CONVERTER_H_
-
diff --git a/media/filters/h264_to_annex_b_bitstream_converter_unittest.cc b/media/filters/h264_to_annex_b_bitstream_converter_unittest.cc
index a921e6e..46f3d7b 100644
--- a/media/filters/h264_to_annex_b_bitstream_converter_unittest.cc
+++ b/media/filters/h264_to_annex_b_bitstream_converter_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "media/filters/h264_to_annex_b_bitstream_converter.h"
+#include "media/formats/mp4/box_definitions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace media {
@@ -14,6 +15,9 @@
 
   virtual ~H264ToAnnexBBitstreamConverterTest() {}
 
+ protected:
+  mp4::AVCDecoderConfigurationRecord avc_config_;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(H264ToAnnexBBitstreamConverterTest);
 };
@@ -269,65 +273,38 @@
   H264ToAnnexBBitstreamConverter converter;
 
   // Parse the headers.
-  uint32 config_size = converter.ParseConfigurationAndCalculateSize(
+  EXPECT_TRUE(converter.ParseConfiguration(
       kHeaderDataOkWithFieldLen4,
-      sizeof(kHeaderDataOkWithFieldLen4));
+      sizeof(kHeaderDataOkWithFieldLen4),
+      &avc_config_));
+  uint32 config_size = converter.GetConfigSize(avc_config_);
   EXPECT_GT(config_size, 0U);
 
   // Go on with converting the headers.
   output.reset(new uint8[config_size]);
   EXPECT_TRUE(output.get() != NULL);
   EXPECT_TRUE(converter.ConvertAVCDecoderConfigToByteStream(
-                  kHeaderDataOkWithFieldLen4,
-                  sizeof(kHeaderDataOkWithFieldLen4),
-                  output.get(),
-                  &config_size));
+      avc_config_,
+      output.get(),
+      &config_size));
 
   // Calculate buffer size for actual NAL unit.
   uint32 output_size = converter.CalculateNeededOutputBufferSize(
       kPacketDataOkWithFieldLen4,
-      sizeof(kPacketDataOkWithFieldLen4));
+      sizeof(kPacketDataOkWithFieldLen4),
+      &avc_config_);
   EXPECT_GT(output_size, 0U);
-  output_size += config_size;
   output.reset(new uint8[output_size]);
   EXPECT_TRUE(output.get() != NULL);
 
-  uint32 output_size_left_for_nal_unit = output_size - config_size;
+  uint32 output_size_left_for_nal_unit = output_size;
   // Do the conversion for actual NAL unit.
   EXPECT_TRUE(converter.ConvertNalUnitStreamToByteStream(
                   kPacketDataOkWithFieldLen4,
                   sizeof(kPacketDataOkWithFieldLen4),
-                  output.get() + config_size,
+                  &avc_config_,
+                  output.get(),
                   &output_size_left_for_nal_unit));
-
-  // Classes allocated in stack are automatically destroyed.
-}
-
-TEST_F(H264ToAnnexBBitstreamConverterTest, FailureNullData) {
-  // Initialize converter.
-  H264ToAnnexBBitstreamConverter converter;
-
-  // Simulate situation where there is no header data.
-  uint32 config_size = converter.ParseConfigurationAndCalculateSize(NULL, 0);
-  EXPECT_EQ(config_size, 0U);
-
-  // Go on with converting the headers with NULL parameters.
-  EXPECT_FALSE(converter.ConvertAVCDecoderConfigToByteStream(NULL,
-                                                             0,
-                                                             NULL,
-                                                             &config_size));
-
-  // Simulate NULL parameters for buffer calculation.
-  uint32 output_size = converter.CalculateNeededOutputBufferSize(NULL, 0);
-  EXPECT_EQ(output_size, 0U);
-
-  // Do the conversion for actual NAL unit with NULL paramaters.
-  EXPECT_FALSE(converter.ConvertNalUnitStreamToByteStream(NULL,
-                                                          0,
-                                                          NULL,
-                                                          &output_size));
-
-  // Classes allocated in stack are automatically destroyed.
 }
 
 TEST_F(H264ToAnnexBBitstreamConverterTest, FailureHeaderBufferOverflow) {
@@ -343,12 +320,10 @@
   corrupted_header[5] = corrupted_header[5] | 0xA;
 
   // Parse the headers
-  uint32 config_size = converter.ParseConfigurationAndCalculateSize(
+  EXPECT_FALSE(converter.ParseConfiguration(
       corrupted_header,
-      sizeof(corrupted_header));
-  EXPECT_EQ(config_size, 0U);  // Failure as a result of buffer overflows.
-
-  // Classes allocated in stack are automatically destroyed.
+      sizeof(corrupted_header),
+      &avc_config_));
 }
 
 TEST_F(H264ToAnnexBBitstreamConverterTest, FailureNalUnitBreakage) {
@@ -357,19 +332,20 @@
   H264ToAnnexBBitstreamConverter converter;
 
   // Parse the headers.
-  uint32 config_size = converter.ParseConfigurationAndCalculateSize(
+  EXPECT_TRUE(converter.ParseConfiguration(
       kHeaderDataOkWithFieldLen4,
-      sizeof(kHeaderDataOkWithFieldLen4));
+      sizeof(kHeaderDataOkWithFieldLen4),
+      &avc_config_));
+  uint32 config_size = converter.GetConfigSize(avc_config_);
   EXPECT_GT(config_size, 0U);
 
   // Go on with converting the headers.
   output.reset(new uint8[config_size]);
   EXPECT_TRUE(output.get() != NULL);
   EXPECT_TRUE(converter.ConvertAVCDecoderConfigToByteStream(
-                  kHeaderDataOkWithFieldLen4,
-                  sizeof(kHeaderDataOkWithFieldLen4),
-                  output.get(),
-                  &config_size));
+      avc_config_,
+      output.get(),
+      &config_size));
 
   // Simulate NAL unit broken in middle by writing only some of the data.
   uint8 corrupted_nal_unit[sizeof(kPacketDataOkWithFieldLen4) - 100];
@@ -380,24 +356,24 @@
   // incomplete input buffer.
   uint32 output_size = converter.CalculateNeededOutputBufferSize(
       corrupted_nal_unit,
-      sizeof(corrupted_nal_unit));
+      sizeof(corrupted_nal_unit),
+      &avc_config_);
   EXPECT_EQ(output_size, 0U);
 
   // Ignore the error and try to go on with conversion simulating wrong usage.
-  output_size = sizeof(kPacketDataOkWithFieldLen4) + config_size;
+  output_size = sizeof(kPacketDataOkWithFieldLen4);
   output.reset(new uint8[output_size]);
   EXPECT_TRUE(output.get() != NULL);
 
-  uint32 output_size_left_for_nal_unit = output_size - config_size;
+  uint32 output_size_left_for_nal_unit = output_size;
   // Do the conversion for actual NAL unit, expecting failure.
   EXPECT_FALSE(converter.ConvertNalUnitStreamToByteStream(
                    corrupted_nal_unit,
                    sizeof(corrupted_nal_unit),
-                   output.get() + config_size,
+                   &avc_config_,
+                   output.get(),
                    &output_size_left_for_nal_unit));
   EXPECT_EQ(output_size_left_for_nal_unit, 0U);
-
-  // Classes allocated in stack are automatically destroyed.
 }
 
 TEST_F(H264ToAnnexBBitstreamConverterTest, FailureTooSmallOutputBuffer) {
@@ -406,9 +382,11 @@
   H264ToAnnexBBitstreamConverter converter;
 
   // Parse the headers.
-  uint32 config_size = converter.ParseConfigurationAndCalculateSize(
+  EXPECT_TRUE(converter.ParseConfiguration(
       kHeaderDataOkWithFieldLen4,
-      sizeof(kHeaderDataOkWithFieldLen4));
+      sizeof(kHeaderDataOkWithFieldLen4),
+      &avc_config_));
+  uint32 config_size = converter.GetConfigSize(avc_config_);
   EXPECT_GT(config_size, 0U);
   uint32 real_config_size = config_size;
 
@@ -417,10 +395,9 @@
   output.reset(new uint8[config_size]);
   EXPECT_TRUE(output.get() != NULL);
   EXPECT_FALSE(converter.ConvertAVCDecoderConfigToByteStream(
-                   kHeaderDataOkWithFieldLen4,
-                   sizeof(kHeaderDataOkWithFieldLen4),
-                   output.get(),
-                   &config_size));
+      avc_config_,
+      output.get(),
+      &config_size));
   EXPECT_EQ(config_size, 0U);
 
   // Still too small (but only 1 byte short).
@@ -428,10 +405,9 @@
   output.reset(new uint8[config_size]);
   EXPECT_TRUE(output.get() != NULL);
   EXPECT_FALSE(converter.ConvertAVCDecoderConfigToByteStream(
-                   kHeaderDataOkWithFieldLen4,
-                   sizeof(kHeaderDataOkWithFieldLen4),
-                   output.get(),
-                   &config_size));
+      avc_config_,
+      output.get(),
+      &config_size));
   EXPECT_EQ(config_size, 0U);
 
   // Finally, retry with valid buffer.
@@ -439,32 +415,30 @@
   output.reset(new uint8[config_size]);
   EXPECT_TRUE(output.get() != NULL);
   EXPECT_TRUE(converter.ConvertAVCDecoderConfigToByteStream(
-                  kHeaderDataOkWithFieldLen4,
-                  sizeof(kHeaderDataOkWithFieldLen4),
-                  output.get(),
-                  &config_size));
+      avc_config_,
+      output.get(),
+      &config_size));
 
   // Calculate buffer size for actual NAL unit.
   uint32 output_size = converter.CalculateNeededOutputBufferSize(
       kPacketDataOkWithFieldLen4,
-      sizeof(kPacketDataOkWithFieldLen4));
+      sizeof(kPacketDataOkWithFieldLen4),
+      &avc_config_);
   EXPECT_GT(output_size, 0U);
-  output_size += config_size;
   // Simulate too small output buffer.
   output_size -= 1;
   output.reset(new uint8[output_size]);
   EXPECT_TRUE(output.get() != NULL);
 
-  uint32 output_size_left_for_nal_unit = output_size - config_size;
+  uint32 output_size_left_for_nal_unit = output_size;
   // Do the conversion for actual NAL unit (expect failure).
   EXPECT_FALSE(converter.ConvertNalUnitStreamToByteStream(
                    kPacketDataOkWithFieldLen4,
                    sizeof(kPacketDataOkWithFieldLen4),
-                   output.get() + config_size,
+                   &avc_config_,
+                   output.get(),
                    &output_size_left_for_nal_unit));
   EXPECT_EQ(output_size_left_for_nal_unit, 0U);
-
-  // Classes allocated in stack are automatically destroyed.
 }
 
 // Generated from crash dump in http://crbug.com/234449 using xxd -i [file].
@@ -487,23 +461,25 @@
   H264ToAnnexBBitstreamConverter converter;
 
   // Parse the headers.
-  uint32 config_size = converter.ParseConfigurationAndCalculateSize(
+  EXPECT_TRUE(converter.ParseConfiguration(
       kCorruptedPacketConfiguration,
-      sizeof(kCorruptedPacketConfiguration));
+      sizeof(kCorruptedPacketConfiguration),
+      &avc_config_));
+  uint32 config_size = converter.GetConfigSize(avc_config_);
   EXPECT_GT(config_size, 0U);
 
   // Go on with converting the headers.
   output.reset(new uint8[config_size]);
   EXPECT_TRUE(converter.ConvertAVCDecoderConfigToByteStream(
-      kCorruptedPacketConfiguration,
-      sizeof(kCorruptedPacketConfiguration),
+      avc_config_,
       output.get(),
       &config_size));
 
   // Expect an error here.
   uint32 output_size = converter.CalculateNeededOutputBufferSize(
       kCorruptedPacketData,
-      sizeof(kCorruptedPacketData));
+      sizeof(kCorruptedPacketData),
+      &avc_config_);
   EXPECT_EQ(output_size, 0U);
 }
 
diff --git a/media/filters/legacy_frame_processor.cc b/media/filters/legacy_frame_processor.cc
index 56d0cb2..71c2801 100644
--- a/media/filters/legacy_frame_processor.cc
+++ b/media/filters/legacy_frame_processor.cc
@@ -193,16 +193,39 @@
 
     if (presentation_timestamp < append_window_start ||
         frame_end_timestamp > append_window_end) {
-      DVLOG(1) << "Dropping buffer outside append window."
-               << " presentation_timestamp "
-               << presentation_timestamp.InSecondsF();
-      track->set_needs_random_access_point(true);
+      // See if a partial discard can be done around |append_window_start|.
+      if (track->stream()->supports_partial_append_window_trimming() &&
+          presentation_timestamp < append_window_start &&
+          frame_end_timestamp > append_window_start &&
+          frame_end_timestamp <= append_window_end) {
+        DCHECK((*itr)->IsKeyframe());
+        DVLOG(1) << "Truncating buffer which overlaps append window start."
+                 << " presentation_timestamp "
+                 << presentation_timestamp.InSecondsF()
+                 << " append_window_start " << append_window_start.InSecondsF();
 
-      // This triggers a discontinuity so we need to treat the next frames
-      // appended within the append window as if they were the beginning of a
-      // new segment.
-      *new_media_segment = true;
-      continue;
+        // Adjust the timestamp of this buffer forward to |append_window_start|,
+        // while decreasing the duration appropriately.
+        const scoped_refptr<StreamParserBuffer>& buffer = *itr;
+        buffer->set_discard_padding(std::make_pair(
+            append_window_start - presentation_timestamp, base::TimeDelta()));
+        buffer->set_timestamp(append_window_start);
+        buffer->SetDecodeTimestamp(append_window_start);
+        buffer->set_duration(frame_end_timestamp - append_window_start);
+
+        // TODO(dalecurtis): This could also be done with |append_window_end|,
+        // but is not necessary since splice frames cover the overlap there.
+      } else {
+        track->set_needs_random_access_point(true);
+        DVLOG(1) << "Dropping buffer outside append window."
+                 << " presentation_timestamp "
+                 << presentation_timestamp.InSecondsF();
+        // This triggers a discontinuity so we need to treat the next frames
+        // appended within the append window as if they were the beginning of a
+        // new segment.
+        *new_media_segment = true;
+        continue;
+      }
     }
 
     // If the track needs a keyframe, then filter out buffers until we
diff --git a/media/filters/opus_audio_decoder.cc b/media/filters/opus_audio_decoder.cc
index bbdcb3f..27c58c6 100644
--- a/media/filters/opus_audio_decoder.cc
+++ b/media/filters/opus_audio_decoder.cc
@@ -418,7 +418,8 @@
     return false;
   }
 
-  discard_helper_.reset(new AudioDiscardHelper(config_.samples_per_second()));
+  discard_helper_.reset(
+      new AudioDiscardHelper(config_.samples_per_second(), 0));
   start_input_timestamp_ = kNoTimestamp();
   return true;
 }
diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc
index 96a4e34..2d4c4d9 100644
--- a/media/filters/pipeline_integration_test.cc
+++ b/media/filters/pipeline_integration_test.cc
@@ -322,7 +322,11 @@
   void Seek(base::TimeDelta seek_time, int new_position, int seek_append_size) {
     chunk_demuxer_->StartWaitingForSeek(seek_time);
 
-    chunk_demuxer_->Abort(kSourceId);
+    // TODO(wolenetz): Test timestamp offset updating once "sequence" append
+    // mode processing is implemented. See http://crbug.com/249422.
+    chunk_demuxer_->Abort(
+        kSourceId,
+        base::TimeDelta(), kInfiniteDuration(), &last_timestamp_offset_);
 
     DCHECK_GE(new_position, 0);
     DCHECK_LT(new_position, file_data_->data_size());
@@ -338,12 +342,10 @@
 
     // TODO(wolenetz): Test timestamp offset updating once "sequence" append
     // mode processing is implemented. See http://crbug.com/249422.
-    base::TimeDelta timestamp_offset;
     chunk_demuxer_->AppendData(
         kSourceId, file_data_->data() + current_position_, size,
-        base::TimeDelta(), kInfiniteDuration(), &timestamp_offset);
+        base::TimeDelta(), kInfiniteDuration(), &last_timestamp_offset_);
     current_position_ += size;
-    last_timestamp_offset_ = timestamp_offset;
   }
 
   void AppendAtTime(base::TimeDelta timestamp_offset,
@@ -356,6 +358,21 @@
     last_timestamp_offset_ = timestamp_offset;
   }
 
+  void AppendAtTimeWithWindow(base::TimeDelta timestamp_offset,
+                              base::TimeDelta append_window_start,
+                              base::TimeDelta append_window_end,
+                              const uint8* pData,
+                              int size) {
+    CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
+    chunk_demuxer_->AppendData(kSourceId,
+                               pData,
+                               size,
+                               append_window_start,
+                               append_window_end,
+                               &timestamp_offset);
+    last_timestamp_offset_ = timestamp_offset;
+  }
+
   void EndOfStream() {
     chunk_demuxer_->MarkEndOfStream(PIPELINE_OK);
   }
@@ -855,6 +872,17 @@
   EXPECT_TRUE(WaitUntilOnEnded());
 }
 
+TEST_F(PipelineIntegrationTest, BasicPlaybackHashed_MP3) {
+  ASSERT_TRUE(Start(GetTestDataFilePath("sfx.mp3"), PIPELINE_OK, kHashed));
+
+  Play();
+
+  ASSERT_TRUE(WaitUntilOnEnded());
+
+  // Verify codec delay and preroll are stripped.
+  EXPECT_EQ("3.05,2.87,3.00,3.32,3.58,4.08,", GetAudioHash());
+}
+
 TEST_P(PipelineIntegrationTest, MediaSource_MP3) {
   MockMediaSource source("sfx.mp3", kMP3, kAppendWholeFile, GetParam());
   StartHashedPipelineWithMediaSource(&source);
@@ -878,17 +906,25 @@
   StartPipelineWithMediaSource(&source);
   EXPECT_EQ(313, source.last_timestamp_offset().InMilliseconds());
 
+  // There are 576 silent frames at the start of this mp3.  The second append
+  // should trim them off.
+  const base::TimeDelta mp3_preroll_duration =
+      base::TimeDelta::FromSecondsD(576.0 / 44100);
+  const base::TimeDelta append_time =
+      source.last_timestamp_offset() - mp3_preroll_duration;
+
   scoped_refptr<DecoderBuffer> second_file = ReadTestDataFile("sfx.mp3");
-  source.AppendAtTime(
-      source.last_timestamp_offset() - base::TimeDelta::FromMilliseconds(10),
-      second_file->data(),
-      second_file->data_size());
+  source.AppendAtTimeWithWindow(append_time,
+                                append_time + mp3_preroll_duration,
+                                kInfiniteDuration(),
+                                second_file->data(),
+                                second_file->data_size());
   source.EndOfStream();
 
-  EXPECT_EQ(616, source.last_timestamp_offset().InMilliseconds());
+  EXPECT_EQ(613, source.last_timestamp_offset().InMilliseconds());
   EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
   EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds());
-  EXPECT_EQ(616, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
+  EXPECT_EQ(613, pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds());
 
   Play();
 
diff --git a/media/filters/pipeline_integration_test_base.cc b/media/filters/pipeline_integration_test_base.cc
index 8abb891..1fd5288 100644
--- a/media/filters/pipeline_integration_test_base.cc
+++ b/media/filters/pipeline_integration_test_base.cc
@@ -263,7 +263,7 @@
 
   ScopedVector<AudioDecoder> audio_decoders;
   audio_decoders.push_back(
-      new FFmpegAudioDecoder(message_loop_.message_loop_proxy()));
+      new FFmpegAudioDecoder(message_loop_.message_loop_proxy(), LogCB()));
   audio_decoders.push_back(
       new OpusAudioDecoder(message_loop_.message_loop_proxy()));
 
diff --git a/media/filters/skcanvas_video_renderer.cc b/media/filters/skcanvas_video_renderer.cc
index 9781b4c..998a640 100644
--- a/media/filters/skcanvas_video_renderer.cc
+++ b/media/filters/skcanvas_video_renderer.cc
@@ -88,7 +88,7 @@
   }
 
   if (video_frame->format() == media::VideoFrame::YV12J) {
-    yuv_type = media::YV12;
+    yuv_type = media::YV12J;
     y_shift = 1;
   }
 
@@ -229,7 +229,6 @@
   switch (video_frame->format()) {
     case media::VideoFrame::YV12:
     case media::VideoFrame::I420:
-    case media::VideoFrame::YV12J:
       media::ConvertYUVToRGB32(
           video_frame->data(media::VideoFrame::kYPlane) + y_offset,
           video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
@@ -243,6 +242,20 @@
           media::YV12);
       break;
 
+    case media::VideoFrame::YV12J:
+      media::ConvertYUVToRGB32(
+          video_frame->data(media::VideoFrame::kYPlane) + y_offset,
+          video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
+          video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
+          static_cast<uint8*>(bitmap->getPixels()),
+          video_frame->visible_rect().width(),
+          video_frame->visible_rect().height(),
+          video_frame->stride(media::VideoFrame::kYPlane),
+          video_frame->stride(media::VideoFrame::kUPlane),
+          bitmap->rowBytes(),
+          media::YV12J);
+      break;
+
     case media::VideoFrame::YV16:
       media::ConvertYUVToRGB32(
           video_frame->data(media::VideoFrame::kYPlane) + y_offset,
diff --git a/media/filters/source_buffer_stream.cc b/media/filters/source_buffer_stream.cc
index 6207c99..9247a25 100644
--- a/media/filters/source_buffer_stream.cc
+++ b/media/filters/source_buffer_stream.cc
@@ -1399,11 +1399,6 @@
   DCHECK(audio_configs_.empty());
   DVLOG(3) << "UpdateVideoConfig.";
 
-  if (video_configs_[0].is_encrypted() != config.is_encrypted()) {
-    MEDIA_LOG(log_cb_) << "Video Encryption changes not allowed.";
-    return false;
-  }
-
   if (video_configs_[0].codec() != config.codec()) {
     MEDIA_LOG(log_cb_) << "Video codec changes not allowed.";
     return false;
@@ -1642,36 +1637,32 @@
   if (pre_splice_buffers.front()->timestamp() >= splice_timestamp)
     return;
 
-  // Sanitize |pre_splice_buffers| so that there are no recursive splices.
+  // If any |pre_splice_buffers| are already splices, do not generate a splice.
   for (size_t i = 0; i < pre_splice_buffers.size(); ++i) {
     const BufferQueue& original_splice_buffers =
         pre_splice_buffers[i]->get_splice_buffers();
-    if (original_splice_buffers.empty())
-      continue;
-
-    // Remove the original splice and move our index back to compensate.  NOTE:
-    // |i| will underflow if the splice is the first buffer, this is okay.  It
-    // will be corrected below or on the next loop iteration.
-    pre_splice_buffers.erase(pre_splice_buffers.begin() + i--);
-
-    // Cull all buffers which start after the end of the new splice point or
-    // after original overlapping buffer; this may introduce gaps, but no more
-    // than Remove() does currently.
-    const scoped_refptr<StreamParserBuffer>& overlapping_buffer =
-        original_splice_buffers.back();
-    for (BufferQueue::const_iterator it = original_splice_buffers.begin();
-         it != original_splice_buffers.end();
-         ++it) {
-      const scoped_refptr<StreamParserBuffer>& buffer = *it;
-      if (buffer->timestamp() <= max_splice_end_timestamp &&
-          (buffer->timestamp() < overlapping_buffer->timestamp() ||
-           buffer == overlapping_buffer)) {
-        // Add the buffer and adjust the index forward to compensate.
-        pre_splice_buffers.insert(pre_splice_buffers.begin() + ++i, buffer);
-      }
+    if (!original_splice_buffers.empty()) {
+      DVLOG(1) << "Can't generate splice: overlapped buffers contain a "
+                  "pre-existing splice.";
+      return;
     }
   }
 
+  // Don't generate splice frames which represent less than two frames, since we
+  // need at least that much to generate a crossfade.  Per the spec, make this
+  // check using the sample rate of the overlapping buffers.
+  const base::TimeDelta splice_duration =
+      pre_splice_buffers.back()->timestamp() +
+      pre_splice_buffers.back()->duration() - splice_timestamp;
+  const base::TimeDelta minimum_splice_duration = base::TimeDelta::FromSecondsD(
+      2.0 / audio_configs_[append_config_index_].samples_per_second());
+  if (splice_duration < minimum_splice_duration) {
+    DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have "
+             << splice_duration.InMicroseconds() << " us, but need "
+             << minimum_splice_duration.InMicroseconds() << " us.";
+    return;
+  }
+
   new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers);
 }
 
diff --git a/media/filters/source_buffer_stream_unittest.cc b/media/filters/source_buffer_stream_unittest.cc
index 9739410..d830b1f 100644
--- a/media/filters/source_buffer_stream_unittest.cc
+++ b/media/filters/source_buffer_stream_unittest.cc
@@ -3665,32 +3665,24 @@
   CheckNoNextBuffer();
 }
 
-TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_DoubleSpliceEarlierOverlap) {
+// Do not allow splices on top of splices.
+TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_NoDoubleSplice) {
   SetAudioStream();
   Seek(0);
   NewSegmentAppend("0K 2K 4K 6K 8K 10K 12K");
   NewSegmentAppend("11K 13K 15K 17K");
 
+  // Verify the splice was created.
+  CheckExpectedBuffers("0K 2K 4K 6K 8K 10K 12K C 11K 13K 15K 17K");
+  CheckNoNextBuffer();
+  Seek(0);
+
   // Create a splice before the first splice which would include it.
   NewSegmentAppend("9K");
 
-  // TODO(dalecurtis/wolenetz): Technically 15K and 17K should be included here,
-  // but since the range merge algorithm doesn't use exact durations, they're
-  // currently dropped.
-  CheckExpectedBuffers("0K 2K 4K 6K 8K 10K 11K 13K C 9K");
-  CheckNoNextBuffer();
-}
-
-TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_DoubleSpliceLaterOverlap) {
-  SetAudioStream();
-  Seek(0);
-  NewSegmentAppend("0K 2K 4K 6K 8K 10K 12K");
-  NewSegmentAppend("10K 13K 15K 17K");
-
-  // Create a splice after the first splice which would include it.
-  NewSegmentAppend("11K");
-
-  CheckExpectedBuffers("0K 2K 4K 6K 8K 10K 13K 15K C 11K");
+  // A splice on top of a splice should result in a discard of the original
+  // splice and no new splice frame being generated.
+  CheckExpectedBuffers("0K 2K 4K 6K 8K 9K 13K 15K 17K");
   CheckNoNextBuffer();
 }
 
@@ -3740,6 +3732,23 @@
   CheckNoNextBuffer();
 }
 
+// Ensure splices are not created if there are not enough frames to crossfade.
+TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_NoTinySplices) {
+  SetAudioStream();
+  Seek(0);
+
+  // Overlap the range [0, 2) with [1, 3).  Since each frame has a duration of
+  // 2ms this results in an overlap of 1ms between the ranges.  A splice frame
+  // should not be generated since it requires at least 2 frames, or 2ms in this
+  // case, of data to crossfade.
+  NewSegmentAppend("0K");
+  CheckExpectedRangesByTimestamp("{ [0,2) }");
+  NewSegmentAppend("1K");
+  CheckExpectedRangesByTimestamp("{ [0,3) }");
+  CheckExpectedBuffers("0K 1K");
+  CheckNoNextBuffer();
+}
+
 // TODO(vrk): Add unit tests where keyframes are unaligned between streams.
 // (crbug.com/133557)
 
diff --git a/media/filters/video_frame_stream_unittest.cc b/media/filters/video_frame_stream_unittest.cc
index cd2fbd9..d5f516b 100644
--- a/media/filters/video_frame_stream_unittest.cc
+++ b/media/filters/video_frame_stream_unittest.cc
@@ -22,21 +22,37 @@
 
 static const int kNumConfigs = 3;
 static const int kNumBuffersInOneConfig = 5;
-static const int kDecodingDelay = 7;
 
 namespace media {
 
+struct VideoFrameStreamTestParams {
+  VideoFrameStreamTestParams(bool is_encrypted,
+                             bool enable_get_decode_output,
+                             int decoding_delay,
+                             int parallel_decoding)
+      : is_encrypted(is_encrypted),
+        enable_get_decode_output(enable_get_decode_output),
+        decoding_delay(decoding_delay),
+        parallel_decoding(parallel_decoding) {}
+
+  bool is_encrypted;
+  bool enable_get_decode_output;
+  int decoding_delay;
+  int parallel_decoding;
+};
+
 class VideoFrameStreamTest
     : public testing::Test,
-      public testing::WithParamInterface<std::tr1::tuple<bool, bool> > {
+      public testing::WithParamInterface<VideoFrameStreamTestParams> {
  public:
   VideoFrameStreamTest()
       : demuxer_stream_(new FakeDemuxerStream(kNumConfigs,
                                               kNumBuffersInOneConfig,
-                                              IsEncrypted())),
+                                              GetParam().is_encrypted)),
         decryptor_(new NiceMock<MockDecryptor>()),
-        decoder_(
-            new FakeVideoDecoder(kDecodingDelay, IsGetDecodeOutputEnabled())),
+        decoder_(new FakeVideoDecoder(GetParam().decoding_delay,
+                                      GetParam().enable_get_decode_output,
+                                      GetParam().parallel_decoding)),
         is_initialized_(false),
         num_decoded_frames_(0),
         pending_initialize_(false),
@@ -73,14 +89,6 @@
     EXPECT_FALSE(is_initialized_);
   }
 
-  bool IsEncrypted() {
-    return std::tr1::get<0>(GetParam());
-  }
-
-  bool IsGetDecodeOutputEnabled() {
-    return std::tr1::get<1>(GetParam());
-  }
-
   MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&));
 
   void OnStatistics(const PipelineStatistics& statistics) {
@@ -121,8 +129,8 @@
     }
 
     DCHECK_EQ(stream_type, Decryptor::kVideo);
-    scoped_refptr<DecoderBuffer> decrypted = DecoderBuffer::CopyFrom(
-        encrypted->data(), encrypted->data_size());
+    scoped_refptr<DecoderBuffer> decrypted =
+        DecoderBuffer::CopyFrom(encrypted->data(), encrypted->data_size());
     decrypted->set_timestamp(encrypted->timestamp());
     decrypted->set_duration(encrypted->duration());
     decrypt_cb.Run(Decryptor::kSuccess, decrypted);
@@ -132,16 +140,19 @@
   void FrameReady(VideoFrameStream::Status status,
                   const scoped_refptr<VideoFrame>& frame) {
     DCHECK(pending_read_);
-    // TODO(xhwang): Add test cases where the fake decoder returns error or
-    // the fake demuxer aborts demuxer read.
-    ASSERT_TRUE(status == VideoFrameStream::OK ||
-                status == VideoFrameStream::ABORTED) << status;
     frame_read_ = frame;
+    last_read_status_ = status;
     if (frame.get() && !frame->end_of_stream())
       num_decoded_frames_++;
     pending_read_ = false;
   }
 
+  void FrameReadyHoldDemuxer(VideoFrameStream::Status status,
+                             const scoped_refptr<VideoFrame>& frame) {
+    FrameReady(status, frame);
+
+  }
+
   void OnReset() {
     DCHECK(!pending_read_);
     DCHECK(pending_reset_);
@@ -225,7 +236,7 @@
         break;
 
       case DECODER_DECODE:
-        decoder_->HoldNextDecode();
+        decoder_->HoldDecode();
         ReadUntilPending();
         break;
 
@@ -323,6 +334,7 @@
   bool pending_stop_;
   int total_bytes_decoded_;
   scoped_refptr<VideoFrame> frame_read_;
+  VideoFrameStream::Status last_read_status_;
 
   // Decryptor has no key to decrypt a frame.
   bool has_no_key_;
@@ -331,14 +343,38 @@
   DISALLOW_COPY_AND_ASSIGN(VideoFrameStreamTest);
 };
 
-INSTANTIATE_TEST_CASE_P(Clear, VideoFrameStreamTest,
-  testing::Combine(testing::Values(false), testing::Values(false)));
-INSTANTIATE_TEST_CASE_P(Clear_GetDecodeOutput, VideoFrameStreamTest,
-  testing::Combine(testing::Values(false), testing::Values(true)));
-INSTANTIATE_TEST_CASE_P(Encrypted, VideoFrameStreamTest,
-  testing::Combine(testing::Values(true), testing::Values(false)));
-INSTANTIATE_TEST_CASE_P(Encrypted_GetDecodeOutput, VideoFrameStreamTest,
-  testing::Combine(testing::Values(true), testing::Values(true)));
+INSTANTIATE_TEST_CASE_P(
+    Clear,
+    VideoFrameStreamTest,
+    ::testing::Values(
+        VideoFrameStreamTestParams(false, false, 0, 1),
+        VideoFrameStreamTestParams(false, false, 3, 1),
+        VideoFrameStreamTestParams(false, false, 7, 1)));
+INSTANTIATE_TEST_CASE_P(
+    Clear_GetDecodeOutput,
+    VideoFrameStreamTest,
+    ::testing::Values(
+        VideoFrameStreamTestParams(false, true, 0, 1),
+        VideoFrameStreamTestParams(false, true, 3, 1),
+        VideoFrameStreamTestParams(false, true, 7, 1)));
+INSTANTIATE_TEST_CASE_P(
+    Encrypted,
+    VideoFrameStreamTest,
+    ::testing::Values(
+        VideoFrameStreamTestParams(true, false, 7, 1)));
+INSTANTIATE_TEST_CASE_P(
+    Encrypted_GetDecodeOutput,
+    VideoFrameStreamTest,
+    ::testing::Values(
+        VideoFrameStreamTestParams(true, true, 7, 1)));
+
+INSTANTIATE_TEST_CASE_P(
+    Clear_Parallel,
+    VideoFrameStreamTest,
+    ::testing::Values(
+        VideoFrameStreamTestParams(false, false, 0, 3),
+        VideoFrameStreamTestParams(false, false, 2, 3)));
+
 
 TEST_P(VideoFrameStreamTest, Initialization) {
   Initialize();
@@ -367,6 +403,86 @@
   Read();
 }
 
+TEST_P(VideoFrameStreamTest, Read_BlockedDemuxer) {
+  Initialize();
+  demuxer_stream_->HoldNextRead();
+  ReadOneFrame();
+  EXPECT_TRUE(pending_read_);
+
+  int demuxed_buffers = 0;
+
+  // Pass frames from the demuxer to the VideoFrameStream until the first read
+  // request is satisfied.
+  while (pending_read_) {
+    ++demuxed_buffers;
+    demuxer_stream_->SatisfyReadAndHoldNext();
+    message_loop_.RunUntilIdle();
+  }
+
+  EXPECT_EQ(std::min(GetParam().decoding_delay + 1, kNumBuffersInOneConfig + 1),
+            demuxed_buffers);
+
+  // At this point the stream is waiting on read from the demuxer, but there is
+  // no pending read from the stream. The stream should be blocked if we try
+  // reading from it again.
+  ReadUntilPending();
+
+  demuxer_stream_->SatisfyRead();
+  message_loop_.RunUntilIdle();
+  EXPECT_FALSE(pending_read_);
+}
+
+TEST_P(VideoFrameStreamTest, Read_BlockedDemuxerAndDecoder) {
+  // Test applies only when the decoder allows multiple parallel requests.
+  if (GetParam().parallel_decoding == 1)
+    return;
+
+  Initialize();
+  demuxer_stream_->HoldNextRead();
+  decoder_->HoldDecode();
+  ReadOneFrame();
+  EXPECT_TRUE(pending_read_);
+
+  int demuxed_buffers = 0;
+
+  // Pass frames from the demuxer to the VideoFrameStream until the first read
+  // request is satisfied, while always keeping one decode request pending.
+  while (pending_read_) {
+    ++demuxed_buffers;
+    demuxer_stream_->SatisfyReadAndHoldNext();
+    message_loop_.RunUntilIdle();
+
+    // Always keep one decode request pending.
+    if (demuxed_buffers > 1) {
+      decoder_->SatisfySingleDecode();
+      message_loop_.RunUntilIdle();
+    }
+  }
+
+  ReadUntilPending();
+  EXPECT_TRUE(pending_read_);
+
+  // Unblocking one decode request should unblock read even when demuxer is
+  // still blocked.
+  decoder_->SatisfySingleDecode();
+  message_loop_.RunUntilIdle();
+  EXPECT_FALSE(pending_read_);
+
+  // Stream should still be blocked on the demuxer after unblocking the decoder.
+  decoder_->SatisfyDecode();
+  ReadUntilPending();
+  EXPECT_TRUE(pending_read_);
+
+  // Verify that the stream has returned all frames that have been demuxed,
+  // accounting for the decoder delay.
+  EXPECT_EQ(demuxed_buffers - GetParam().decoding_delay, num_decoded_frames_);
+
+  // Unblocking the demuxer will unblock the stream.
+  demuxer_stream_->SatisfyRead();
+  message_loop_.RunUntilIdle();
+  EXPECT_FALSE(pending_read_);
+}
+
 // No Reset() before initialization is successfully completed.
 
 TEST_P(VideoFrameStreamTest, Reset_AfterInitialization) {
@@ -450,7 +566,7 @@
 }
 
 TEST_P(VideoFrameStreamTest, Stop_DuringSetDecryptor) {
-  if (!IsEncrypted()) {
+  if (!GetParam().is_encrypted) {
     DVLOG(1) << "SetDecryptor test only runs when the stream is encrytped.";
     return;
   }
@@ -556,4 +672,38 @@
   Stop();
 }
 
+TEST_P(VideoFrameStreamTest, DecoderErrorWhenReading) {
+  Initialize();
+  EnterPendingState(DECODER_DECODE);
+  decoder_->SimulateError();
+  message_loop_.RunUntilIdle();
+  ASSERT_FALSE(pending_read_);
+  ASSERT_EQ(VideoFrameStream::DECODE_ERROR, last_read_status_);
+}
+
+TEST_P(VideoFrameStreamTest, DecoderErrorWhenNotReading) {
+  Initialize();
+
+  decoder_->HoldDecode();
+  ReadOneFrame();
+  EXPECT_TRUE(pending_read_);
+
+  // Satisfy decode requests until we get the first frame out.
+  while (pending_read_) {
+    decoder_->SatisfySingleDecode();
+    message_loop_.RunUntilIdle();
+  }
+
+  // Trigger an error in the decoding.
+  decoder_->SimulateError();
+
+  // The error must surface from Read() as DECODE_ERROR.
+  while (last_read_status_ == VideoFrameStream::OK) {
+    ReadOneFrame();
+    message_loop_.RunUntilIdle();
+    EXPECT_FALSE(pending_read_);
+  }
+  EXPECT_EQ(VideoFrameStream::DECODE_ERROR, last_read_status_);
+}
+
 }  // namespace media
diff --git a/media/filters/video_renderer_impl.cc b/media/filters/video_renderer_impl.cc
index ba9e04f..6b6711e 100644
--- a/media/filters/video_renderer_impl.cc
+++ b/media/filters/video_renderer_impl.cc
@@ -26,6 +26,7 @@
     bool drop_frames)
     : task_runner_(task_runner),
       video_frame_stream_(task_runner, decoders.Pass(), set_decryptor_ready_cb),
+      low_delay_(false),
       received_end_of_stream_(false),
       frame_available_(&lock_),
       state_(kUninitialized),
@@ -168,6 +169,8 @@
   DCHECK(!get_duration_cb.is_null());
   DCHECK_EQ(kUninitialized, state_);
 
+  low_delay_ = low_delay;
+
   init_cb_ = init_cb;
   statistics_cb_ = statistics_cb;
   max_time_cb_ = max_time_cb;
@@ -407,7 +410,8 @@
 bool VideoRendererImpl::ShouldTransitionToPrerolled_Locked() {
   return state_ == kPrerolling &&
       (!video_frame_stream_.CanReadWithoutStalling() ||
-       ready_frames_.size() >= static_cast<size_t>(limits::kMaxVideoFrames));
+       ready_frames_.size() >= static_cast<size_t>(limits::kMaxVideoFrames) ||
+       (low_delay_ && ready_frames_.size() > 0));
 }
 
 void VideoRendererImpl::AddReadyFrame_Locked(
@@ -453,6 +457,7 @@
   switch (state_) {
     case kPaused:
     case kPrerolling:
+    case kPrerolled:
     case kPlaying:
       pending_read_ = true;
       video_frame_stream_.Read(base::Bind(&VideoRendererImpl::FrameReady,
@@ -461,7 +466,6 @@
 
     case kUninitialized:
     case kInitializing:
-    case kPrerolled:
     case kFlushing:
     case kFlushed:
     case kEnded:
diff --git a/media/filters/video_renderer_impl.h b/media/filters/video_renderer_impl.h
index 30dc7d6..a7dccf2 100644
--- a/media/filters/video_renderer_impl.h
+++ b/media/filters/video_renderer_impl.h
@@ -137,6 +137,9 @@
   // Provides video frames to VideoRendererImpl.
   VideoFrameStream video_frame_stream_;
 
+  // Flag indicating low-delay mode.
+  bool low_delay_;
+
   // Queue of incoming frames yet to be painted.
   typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue;
   VideoFrameQueue ready_frames_;
diff --git a/media/filters/video_renderer_impl_unittest.cc b/media/filters/video_renderer_impl_unittest.cc
index 9380646..6ba6bae 100644
--- a/media/filters/video_renderer_impl_unittest.cc
+++ b/media/filters/video_renderer_impl_unittest.cc
@@ -36,6 +36,10 @@
 
 namespace media {
 
+ACTION_P(RunClosure, closure) {
+  closure.Run();
+}
+
 MATCHER_P(HasTimestamp, ms, "") {
   *result_listener << "has timestamp " << arg->timestamp().InMilliseconds();
   return arg->timestamp().InMilliseconds() == ms;
@@ -80,6 +84,10 @@
   MOCK_METHOD1(OnTimeUpdate, void(base::TimeDelta));
 
   void Initialize() {
+    InitializeWithLowDelay(false);
+  }
+
+  void InitializeWithLowDelay(bool low_delay) {
     // Monitor decodes from the decoder.
     EXPECT_CALL(*decoder_, Decode(_, _))
         .WillRepeatedly(Invoke(this, &VideoRendererImplTest::FrameRequested));
@@ -96,20 +104,20 @@
     renderer_->SetPlaybackRate(1.0f);
 
     // Initialize, we shouldn't have any reads.
-    InitializeRenderer(PIPELINE_OK);
+    InitializeRenderer(PIPELINE_OK, low_delay);
   }
 
-  void InitializeRenderer(PipelineStatus expected) {
+  void InitializeRenderer(PipelineStatus expected, bool low_delay) {
     SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expected));
     WaitableMessageLoopEvent event;
-    CallInitialize(event.GetPipelineStatusCB());
+    CallInitialize(event.GetPipelineStatusCB(), low_delay);
     event.RunAndWaitForStatus(expected);
   }
 
-  void CallInitialize(const PipelineStatusCB& status_cb) {
+  void CallInitialize(const PipelineStatusCB& status_cb, bool low_delay) {
     renderer_->Initialize(
         &demuxer_stream_,
-        false,
+        low_delay,
         status_cb,
         base::Bind(&MockStatisticsCB::OnStatistics,
                    base::Unretained(&statistics_cb_object_)),
@@ -218,6 +226,10 @@
     }
   }
 
+  bool IsReadPending() {
+    return !read_cb_.is_null();
+  }
+
   void WaitForError(PipelineStatus expected) {
     SCOPED_TRACE(base::StringPrintf("WaitForError(%d)", expected));
     error_event_.RunAndWaitForStatus(expected);
@@ -376,7 +388,7 @@
 TEST_F(VideoRendererImplTest, StopWhileInitializing) {
   EXPECT_CALL(*decoder_, Initialize(_, _, _))
       .WillOnce(RunCallback<2>(PIPELINE_OK));
-  CallInitialize(base::Bind(&ExpectNotCalled));
+  CallInitialize(base::Bind(&ExpectNotCalled), false);
   Stop();
 
   // ~VideoRendererImpl() will CHECK() if we left anything initialized.
@@ -413,6 +425,7 @@
 
   // Queue the end of stream frame and wait for the last frame to be rendered.
   QueueFrames("eos");
+  SatisfyPendingRead();
   EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(kVideoDurationInMs)));
   AdvanceTimeInMs(kVideoDurationInMs);
   WaitForEnded();
@@ -428,8 +441,7 @@
   Play();
 
   QueueFrames("error");
-  EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10)));
-  AdvanceTimeInMs(10);
+  SatisfyPendingRead();
   WaitForError(PIPELINE_ERROR_DECODE);
   Shutdown();
 }
@@ -468,6 +480,27 @@
   Shutdown();
 }
 
+TEST_F(VideoRendererImplTest, Preroll_LowDelay) {
+  // In low-delay mode only one frame is required to finish preroll.
+  InitializeWithLowDelay(true);
+  QueueFrames("0");
+
+  EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(0)));
+  Preroll(0, PIPELINE_OK);
+  Play();
+
+  QueueFrames("10");
+  SatisfyPendingRead();
+
+  WaitableMessageLoopEvent event;
+  EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10)))
+      .WillOnce(RunClosure(event.GetClosure()));
+  AdvanceTimeInMs(10);
+  event.RunAndWait();
+
+  Shutdown();
+}
+
 TEST_F(VideoRendererImplTest, PlayAfterPreroll) {
   Initialize();
   QueueFrames("0 10 20 30");
@@ -475,10 +508,9 @@
   Preroll(0, PIPELINE_OK);
   Play();
 
-  // Advance time past prerolled time to trigger a Read().
-  EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10)));
-  AdvanceTimeInMs(10);
-  WaitForPendingRead();
+  // Check that there is an outstanding Read() request.
+  EXPECT_TRUE(IsReadPending());
+
   Shutdown();
 }
 
@@ -524,6 +556,7 @@
   // Queue an extra frame so that we'll have enough frames to satisfy
   // preroll even after the first frame is painted.
   QueueFrames("40");
+  SatisfyPendingRead();
   Play();
 
   // Simulate a Pause/Preroll/Play rebuffer sequence.
@@ -552,10 +585,8 @@
   Preroll(0, PIPELINE_OK);
   Play();
 
-  // Advance time a bit to trigger a Read().
-  EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10)));
-  AdvanceTimeInMs(10);
-  WaitForPendingRead();
+  // Check that there is an outstanding Read() request.
+  EXPECT_TRUE(IsReadPending());
 
   WaitableMessageLoopEvent event;
   renderer_->Stop(event.GetClosure());
@@ -569,10 +600,9 @@
   Preroll(0, PIPELINE_OK);
   Play();
 
-  // Advance time a bit to trigger a Read().
-  EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10)));
-  AdvanceTimeInMs(10);
-  WaitForPendingRead();
+  // Check that there is an outstanding Read() request.
+  EXPECT_TRUE(IsReadPending());
+
   QueueFrames("abort");
   SatisfyPendingRead();
 
@@ -591,10 +621,8 @@
   Preroll(0, PIPELINE_OK);
   Play();
 
-  // Advance time a bit to trigger a Read().
-  EXPECT_CALL(mock_display_cb_, Display(HasTimestamp(10)));
-  AdvanceTimeInMs(10);
-  WaitForPendingRead();
+  // Check that there is an outstanding Read() request.
+  EXPECT_TRUE(IsReadPending());
 
   Pause();
   Flush();
@@ -614,7 +642,7 @@
 
   EXPECT_CALL(*decoder_, Initialize(_, _, _))
       .WillOnce(RunCallback<2>(DECODER_ERROR_NOT_SUPPORTED));
-  InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED);
+  InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED, false);
 
   Stop();
 }
diff --git a/media/formats/mp2t/mp2t_stream_parser.cc b/media/formats/mp2t/mp2t_stream_parser.cc
index c00bba7..4849755 100644
--- a/media/formats/mp2t/mp2t_stream_parser.cc
+++ b/media/formats/mp2t/mp2t_stream_parser.cc
@@ -211,6 +211,7 @@
   // stream parser already involves the end of the current segment.
   segment_started_ = false;
   first_video_frame_in_segment_ = true;
+  discarded_frames_dts_.clear();
 
   // Remove any bytes left in the TS buffer.
   // (i.e. any partial TS packet => less than 188 bytes).
@@ -539,23 +540,27 @@
   stream_parser_buffer->SetDecodeTimestamp(
       stream_parser_buffer->GetDecodeTimestamp() - time_offset_);
 
-  // Ignore the incoming buffer if it is not associated with any config.
-  if (buffer_queue_chain_.empty()) {
-    DVLOG(1) << "Ignoring video buffer with no corresponding video config:"
+  // Discard the incoming buffer:
+  // - if it is not associated with any config,
+  // - or if only non-key frames have been added to a new segment.
+  if (buffer_queue_chain_.empty() ||
+      (first_video_frame_in_segment_ && !stream_parser_buffer->IsKeyframe())) {
+    DVLOG(1) << "Discard video buffer:"
              << " keyframe=" << stream_parser_buffer->IsKeyframe()
              << " dts="
              << stream_parser_buffer->GetDecodeTimestamp().InMilliseconds();
+    if (discarded_frames_dts_.empty() ||
+        discarded_frames_min_pts_ > stream_parser_buffer->timestamp()) {
+      discarded_frames_min_pts_ = stream_parser_buffer->timestamp();
+    }
+    discarded_frames_dts_.push_back(
+        stream_parser_buffer->GetDecodeTimestamp());
     return;
   }
 
-  // A segment cannot start with a non key frame.
-  // Ignore the frame if that's the case.
-  if (first_video_frame_in_segment_ && !stream_parser_buffer->IsKeyframe()) {
-    DVLOG(1) << "Ignoring non-key frame:"
-             << " dts="
-             << stream_parser_buffer->GetDecodeTimestamp().InMilliseconds();
-    return;
-  }
+  // Fill the gap created by frames that have been discarded.
+  if (!discarded_frames_dts_.empty())
+    FillVideoGap(stream_parser_buffer);
 
   first_video_frame_in_segment_ = false;
   buffer_queue_chain_.back().video_queue.push_back(stream_parser_buffer);
@@ -577,6 +582,12 @@
   VideoDecoderConfig last_video_config =
       buffer_queue_chain_.back().video_config;
 
+  // Do not have all the configs, need more data.
+  if (selected_audio_pid_ >= 0 && !last_audio_config.IsValidConfig())
+    return true;
+  if (selected_video_pid_ >= 0 && !last_video_config.IsValidConfig())
+    return true;
+
   // Buffer emission.
   while (!buffer_queue_chain_.empty()) {
     // Start a segment if needed.
@@ -619,5 +630,33 @@
   return true;
 }
 
+void Mp2tStreamParser::FillVideoGap(
+    const scoped_refptr<StreamParserBuffer>& stream_parser_buffer) {
+  DCHECK(!buffer_queue_chain_.empty());
+  DCHECK(!discarded_frames_dts_.empty());
+  DCHECK(stream_parser_buffer->IsKeyframe());
+
+  // PTS is interpolated between the min PTS of discarded frames
+  // and the PTS of the first valid buffer.
+  base::TimeDelta pts = discarded_frames_min_pts_;
+  base::TimeDelta pts_delta =
+      (stream_parser_buffer->timestamp() - pts) / discarded_frames_dts_.size();
+
+  while (!discarded_frames_dts_.empty()) {
+    scoped_refptr<StreamParserBuffer> frame =
+        StreamParserBuffer::CopyFrom(
+            stream_parser_buffer->data(),
+            stream_parser_buffer->data_size(),
+            stream_parser_buffer->IsKeyframe(),
+            stream_parser_buffer->type(),
+            stream_parser_buffer->track_id());
+    frame->SetDecodeTimestamp(discarded_frames_dts_.front());
+    frame->set_timestamp(pts);
+    buffer_queue_chain_.back().video_queue.push_back(frame);
+    pts += pts_delta;
+    discarded_frames_dts_.pop_front();
+  }
+}
+
 }  // namespace mp2t
 }  // namespace media
diff --git a/media/formats/mp2t/mp2t_stream_parser.h b/media/formats/mp2t/mp2t_stream_parser.h
index 85629dc..61f3440 100644
--- a/media/formats/mp2t/mp2t_stream_parser.h
+++ b/media/formats/mp2t/mp2t_stream_parser.h
@@ -92,6 +92,12 @@
       scoped_refptr<StreamParserBuffer> stream_parser_buffer);
   bool EmitRemainingBuffers();
 
+  // At the beginning of a new segment, some video frames might be discarded.
+  // This function fills the hole by duplicating the first valid key frame
+  // given by |stream_parser_buffer|.
+  void FillVideoGap(
+      const scoped_refptr<StreamParserBuffer>& stream_parser_buffer);
+
   // List of callbacks.
   InitCB init_cb_;
   NewConfigCB config_cb_;
@@ -115,6 +121,11 @@
   int selected_audio_pid_;
   int selected_video_pid_;
 
+  // DTS of discarded buffers.
+  // Min PTS of discarded buffers.
+  std::list<base::TimeDelta> discarded_frames_dts_;
+  base::TimeDelta discarded_frames_min_pts_;
+
   // Pending audio & video buffers.
   std::list<BufferQueueWithConfig> buffer_queue_chain_;
 
diff --git a/media/formats/mp2t/mp2t_stream_parser_unittest.cc b/media/formats/mp2t/mp2t_stream_parser_unittest.cc
index af73df5..1f32986 100644
--- a/media/formats/mp2t/mp2t_stream_parser_unittest.cc
+++ b/media/formats/mp2t/mp2t_stream_parser_unittest.cc
@@ -69,6 +69,9 @@
                    const StreamParser::TextTrackConfigMap& tc) {
     DVLOG(1) << "OnNewConfig: audio=" << ac.IsValidConfig()
              << ", video=" << vc.IsValidConfig();
+    // Test streams have both audio and video, verify the configs are valid.
+    EXPECT_TRUE(ac.IsValidConfig());
+    EXPECT_TRUE(vc.IsValidConfig());
     return true;
   }
 
@@ -145,8 +148,6 @@
   }
 
   bool ParseMpeg2TsFile(const std::string& filename, int append_bytes) {
-    InitializeParser();
-
     scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename);
     EXPECT_TRUE(AppendDataInPieces(buffer->data(),
                                    buffer->data_size(),
@@ -157,6 +158,7 @@
 
 TEST_F(Mp2tStreamParserTest, UnalignedAppend17) {
   // Test small, non-segment-aligned appends.
+  InitializeParser();
   ParseMpeg2TsFile("bear-1280x720.ts", 17);
   EXPECT_EQ(video_frame_count_, 81);
   parser_->Flush();
@@ -165,17 +167,28 @@
 
 TEST_F(Mp2tStreamParserTest, UnalignedAppend512) {
   // Test small, non-segment-aligned appends.
+  InitializeParser();
   ParseMpeg2TsFile("bear-1280x720.ts", 512);
   EXPECT_EQ(video_frame_count_, 81);
   parser_->Flush();
   EXPECT_EQ(video_frame_count_, 82);
 }
 
+TEST_F(Mp2tStreamParserTest, AppendAfterFlush512) {
+  InitializeParser();
+  ParseMpeg2TsFile("bear-1280x720.ts", 512);
+  parser_->Flush();
+
+  ParseMpeg2TsFile("bear-1280x720.ts", 512);
+  parser_->Flush();
+}
+
 TEST_F(Mp2tStreamParserTest, TimestampWrapAround) {
   // "bear-1280x720_ptswraparound.ts" has been transcoded
   // from bear-1280x720.mp4 by applying a time offset of 95442s
   // (close to 2^33 / 90000) which results in timestamps wrap around
   // in the Mpeg2 TS stream.
+  InitializeParser();
   ParseMpeg2TsFile("bear-1280x720_ptswraparound.ts", 512);
   EXPECT_EQ(video_frame_count_, 81);
   EXPECT_GE(video_min_dts_, base::TimeDelta::FromSeconds(95443 - 10));
diff --git a/media/formats/mp4/aac.cc b/media/formats/mp4/aac.cc
index 45cc129..71deded 100644
--- a/media/formats/mp4/aac.cc
+++ b/media/formats/mp4/aac.cc
@@ -8,6 +8,7 @@
 
 #include "base/logging.h"
 #include "media/base/bit_reader.h"
+#include "media/base/media_log.h"
 #include "media/formats/mp4/rcheck.h"
 #include "media/formats/mpeg/adts_constants.h"
 
@@ -22,7 +23,7 @@
 AAC::~AAC() {
 }
 
-bool AAC::Parse(const std::vector<uint8>& data) {
+bool AAC::Parse(const std::vector<uint8>& data, const LogCB& log_cb) {
 #if defined(OS_ANDROID)
   codec_specific_data_ = data;
 #endif
@@ -57,6 +58,9 @@
     RCHECK(reader.ReadBits(5, &profile_));
   }
 
+  MEDIA_LOG(log_cb) << "Audio codec: mp4a.40."
+                    << std::hex << static_cast<int>(profile_);
+
   RCHECK(SkipDecoderGASpecificConfig(&reader));
   RCHECK(SkipErrorSpecificConfig());
 
diff --git a/media/formats/mp4/aac.h b/media/formats/mp4/aac.h
index 0b1d950..67f981e 100644
--- a/media/formats/mp4/aac.h
+++ b/media/formats/mp4/aac.h
@@ -10,6 +10,7 @@
 #include "base/basictypes.h"
 #include "media/base/channel_layout.h"
 #include "media/base/media_export.h"
+#include "media/base/media_log.h"
 
 namespace media {
 
@@ -30,7 +31,7 @@
   // The function will parse the data and get the ElementaryStreamDescriptor,
   // then it will parse the ElementaryStreamDescriptor to get audio stream
   // configurations.
-  bool Parse(const std::vector<uint8>& data);
+  bool Parse(const std::vector<uint8>& data, const LogCB& log_cb);
 
   // Gets the output sample rate for the AAC stream.
   // |sbr_in_mimetype| should be set to true if the SBR mode is
diff --git a/media/formats/mp4/aac_unittest.cc b/media/formats/mp4/aac_unittest.cc
index d3ca839..9d65c31 100644
--- a/media/formats/mp4/aac_unittest.cc
+++ b/media/formats/mp4/aac_unittest.cc
@@ -10,135 +10,135 @@
 
 namespace mp4 {
 
-TEST(AACTest, BasicProfileTest) {
-  AAC aac;
+class AACTest : public testing::Test {
+ public:
+  bool Parse(const std::vector<uint8>& data) {
+    return aac_.Parse(data, LogCB());
+  }
+
+  AAC aac_;
+};
+
+TEST_F(AACTest, BasicProfileTest) {
   uint8 buffer[] = {0x12, 0x10};
   std::vector<uint8> data;
 
   data.assign(buffer, buffer + sizeof(buffer));
 
-  EXPECT_TRUE(aac.Parse(data));
-  EXPECT_EQ(aac.GetOutputSamplesPerSecond(false), 44100);
-  EXPECT_EQ(aac.GetChannelLayout(false), CHANNEL_LAYOUT_STEREO);
+  EXPECT_TRUE(Parse(data));
+  EXPECT_EQ(aac_.GetOutputSamplesPerSecond(false), 44100);
+  EXPECT_EQ(aac_.GetChannelLayout(false), CHANNEL_LAYOUT_STEREO);
 }
 
-TEST(AACTest, ExtensionTest) {
-  AAC aac;
+TEST_F(AACTest, ExtensionTest) {
   uint8 buffer[] = {0x13, 0x08, 0x56, 0xe5, 0x9d, 0x48, 0x80};
   std::vector<uint8> data;
 
   data.assign(buffer, buffer + sizeof(buffer));
 
-  EXPECT_TRUE(aac.Parse(data));
-  EXPECT_EQ(aac.GetOutputSamplesPerSecond(false), 48000);
-  EXPECT_EQ(aac.GetOutputSamplesPerSecond(true), 48000);
-  EXPECT_EQ(aac.GetChannelLayout(false), CHANNEL_LAYOUT_STEREO);
+  EXPECT_TRUE(Parse(data));
+  EXPECT_EQ(aac_.GetOutputSamplesPerSecond(false), 48000);
+  EXPECT_EQ(aac_.GetOutputSamplesPerSecond(true), 48000);
+  EXPECT_EQ(aac_.GetChannelLayout(false), CHANNEL_LAYOUT_STEREO);
 }
 
 // Test implicit SBR with mono channel config.
 // Mono channel layout should only be reported if SBR is not
 // specified. Otherwise stereo should be reported.
 // See ISO-14496-3 Section 1.6.6.1.2 for details about this special casing.
-TEST(AACTest, ImplicitSBR_ChannelConfig0) {
-  AAC aac;
+TEST_F(AACTest, ImplicitSBR_ChannelConfig0) {
   uint8 buffer[] = {0x13, 0x08};
   std::vector<uint8> data;
 
   data.assign(buffer, buffer + sizeof(buffer));
 
-  EXPECT_TRUE(aac.Parse(data));
+  EXPECT_TRUE(Parse(data));
 
   // Test w/o implict SBR.
-  EXPECT_EQ(aac.GetOutputSamplesPerSecond(false), 24000);
-  EXPECT_EQ(aac.GetChannelLayout(false), CHANNEL_LAYOUT_MONO);
+  EXPECT_EQ(aac_.GetOutputSamplesPerSecond(false), 24000);
+  EXPECT_EQ(aac_.GetChannelLayout(false), CHANNEL_LAYOUT_MONO);
 
   // Test implicit SBR.
-  EXPECT_EQ(aac.GetOutputSamplesPerSecond(true), 48000);
-  EXPECT_EQ(aac.GetChannelLayout(true), CHANNEL_LAYOUT_STEREO);
+  EXPECT_EQ(aac_.GetOutputSamplesPerSecond(true), 48000);
+  EXPECT_EQ(aac_.GetChannelLayout(true), CHANNEL_LAYOUT_STEREO);
 }
 
 // Tests implicit SBR with a stereo channel config.
-TEST(AACTest, ImplicitSBR_ChannelConfig1) {
-  AAC aac;
+TEST_F(AACTest, ImplicitSBR_ChannelConfig1) {
   uint8 buffer[] = {0x13, 0x10};
   std::vector<uint8> data;
 
   data.assign(buffer, buffer + sizeof(buffer));
 
-  EXPECT_TRUE(aac.Parse(data));
+  EXPECT_TRUE(Parse(data));
 
   // Test w/o implict SBR.
-  EXPECT_EQ(aac.GetOutputSamplesPerSecond(false), 24000);
-  EXPECT_EQ(aac.GetChannelLayout(false), CHANNEL_LAYOUT_STEREO);
+  EXPECT_EQ(aac_.GetOutputSamplesPerSecond(false), 24000);
+  EXPECT_EQ(aac_.GetChannelLayout(false), CHANNEL_LAYOUT_STEREO);
 
   // Test implicit SBR.
-  EXPECT_EQ(aac.GetOutputSamplesPerSecond(true), 48000);
-  EXPECT_EQ(aac.GetChannelLayout(true), CHANNEL_LAYOUT_STEREO);
+  EXPECT_EQ(aac_.GetOutputSamplesPerSecond(true), 48000);
+  EXPECT_EQ(aac_.GetChannelLayout(true), CHANNEL_LAYOUT_STEREO);
 }
 
-TEST(AACTest, SixChannelTest) {
-  AAC aac;
+TEST_F(AACTest, SixChannelTest) {
   uint8 buffer[] = {0x11, 0xb0};
   std::vector<uint8> data;
 
   data.assign(buffer, buffer + sizeof(buffer));
 
-  EXPECT_TRUE(aac.Parse(data));
-  EXPECT_EQ(aac.GetOutputSamplesPerSecond(false), 48000);
-  EXPECT_EQ(aac.GetChannelLayout(false), CHANNEL_LAYOUT_5_1_BACK);
+  EXPECT_TRUE(Parse(data));
+  EXPECT_EQ(aac_.GetOutputSamplesPerSecond(false), 48000);
+  EXPECT_EQ(aac_.GetChannelLayout(false), CHANNEL_LAYOUT_5_1_BACK);
 }
 
-TEST(AACTest, DataTooShortTest) {
-  AAC aac;
+TEST_F(AACTest, DataTooShortTest) {
   std::vector<uint8> data;
 
-  EXPECT_FALSE(aac.Parse(data));
+  EXPECT_FALSE(Parse(data));
 
   data.push_back(0x12);
-  EXPECT_FALSE(aac.Parse(data));
+  EXPECT_FALSE(Parse(data));
 }
 
-TEST(AACTest, IncorrectProfileTest) {
-  AAC aac;
+TEST_F(AACTest, IncorrectProfileTest) {
   uint8 buffer[] = {0x0, 0x08};
   std::vector<uint8> data;
 
   data.assign(buffer, buffer + sizeof(buffer));
 
-  EXPECT_FALSE(aac.Parse(data));
+  EXPECT_FALSE(Parse(data));
 
   data[0] = 0x08;
-  EXPECT_TRUE(aac.Parse(data));
+  EXPECT_TRUE(Parse(data));
 
   data[0] = 0x28;
-  EXPECT_FALSE(aac.Parse(data));
+  EXPECT_FALSE(Parse(data));
 }
 
-TEST(AACTest, IncorrectFrequencyTest) {
-  AAC aac;
+TEST_F(AACTest, IncorrectFrequencyTest) {
   uint8 buffer[] = {0x0f, 0x88};
   std::vector<uint8> data;
 
   data.assign(buffer, buffer + sizeof(buffer));
 
-  EXPECT_FALSE(aac.Parse(data));
+  EXPECT_FALSE(Parse(data));
 
   data[0] = 0x0e;
   data[1] = 0x08;
-  EXPECT_TRUE(aac.Parse(data));
+  EXPECT_TRUE(Parse(data));
 }
 
-TEST(AACTest, IncorrectChannelTest) {
-  AAC aac;
+TEST_F(AACTest, IncorrectChannelTest) {
   uint8 buffer[] = {0x0e, 0x00};
   std::vector<uint8> data;
 
   data.assign(buffer, buffer + sizeof(buffer));
 
-  EXPECT_FALSE(aac.Parse(data));
+  EXPECT_FALSE(Parse(data));
 
   data[1] = 0x08;
-  EXPECT_TRUE(aac.Parse(data));
+  EXPECT_TRUE(Parse(data));
 }
 
 }  // namespace mp4
diff --git a/media/formats/mp4/avc.cc b/media/formats/mp4/avc.cc
index ed7e5aa..6c2bc2a 100644
--- a/media/formats/mp4/avc.cc
+++ b/media/formats/mp4/avc.cc
@@ -172,13 +172,18 @@
 
 // Verifies AnnexB NALU order according to ISO/IEC 14496-10 Section 7.4.1.2.3
 bool AVC::IsValidAnnexB(const std::vector<uint8>& buffer) {
-  DVLOG(1) << __FUNCTION__;
+  return IsValidAnnexB(&buffer[0], buffer.size());
+}
 
-  if (buffer.empty())
+bool AVC::IsValidAnnexB(const uint8* buffer, size_t size) {
+  DVLOG(1) << __FUNCTION__;
+  DCHECK(buffer);
+
+  if (size == 0)
     return true;
 
   H264Parser parser;
-  parser.SetStream(&buffer[0], buffer.size());
+  parser.SetStream(buffer, size);
 
   typedef enum {
     kAUDAllowed,
diff --git a/media/formats/mp4/avc.h b/media/formats/mp4/avc.h
index 8155883..0d84eef 100644
--- a/media/formats/mp4/avc.h
+++ b/media/formats/mp4/avc.h
@@ -39,8 +39,11 @@
 
   // Verifies that the contents of |buffer| conform to
   // Section 7.4.1.2.3 of ISO/IEC 14496-10.
-  // Returns true if |buffer| contains conformant AnnexB data.
+  // Returns true if |buffer| contains conformant Annex B data
+  // TODO(acolwell): Remove the std::vector version when we can use,
+  // C++11's std::vector<T>::data() method.
   static bool IsValidAnnexB(const std::vector<uint8>& buffer);
+  static bool IsValidAnnexB(const uint8* buffer, size_t size);
 };
 
 }  // namespace mp4
diff --git a/media/formats/mp4/box_definitions.cc b/media/formats/mp4/box_definitions.cc
index 1912aae..8d0f554 100644
--- a/media/formats/mp4/box_definitions.cc
+++ b/media/formats/mp4/box_definitions.cc
@@ -349,6 +349,16 @@
 FourCC AVCDecoderConfigurationRecord::BoxType() const { return FOURCC_AVCC; }
 
 bool AVCDecoderConfigurationRecord::Parse(BoxReader* reader) {
+  return ParseInternal(reader, reader->log_cb());
+}
+
+bool AVCDecoderConfigurationRecord::Parse(const uint8* data, int data_size) {
+  BufferReader reader(data, data_size);
+  return ParseInternal(&reader, LogCB());
+}
+
+bool AVCDecoderConfigurationRecord::ParseInternal(BufferReader* reader,
+                                                  const LogCB& log_cb) {
   RCHECK(reader->Read1(&version) && version == 1 &&
          reader->Read1(&profile_indication) &&
          reader->Read1(&profile_compatibility) &&
@@ -359,6 +369,8 @@
          (length_size_minus_one & 0xfc) == 0xfc);
   length_size = (length_size_minus_one & 0x3) + 1;
 
+  RCHECK(length_size != 3); // Only values of 1, 2, and 4 are valid.
+
   uint8 num_sps;
   RCHECK(reader->Read1(&num_sps) && (num_sps & 0xe0) == 0xe0);
   num_sps &= 0x1f;
@@ -368,6 +380,14 @@
     uint16 sps_length;
     RCHECK(reader->Read2(&sps_length) &&
            reader->ReadVec(&sps_list[i], sps_length));
+    RCHECK(sps_list[i].size() > 4);
+
+    if (!log_cb.is_null()) {
+      MEDIA_LOG(log_cb) << "Video codec: avc1." << std::hex
+                        << static_cast<int>(sps_list[i][1])
+                        << static_cast<int>(sps_list[i][2])
+                        << static_cast<int>(sps_list[i][3]);
+    }
   }
 
   uint8 num_pps;
@@ -458,7 +478,13 @@
 
   object_type = es_desc.object_type();
 
-  RCHECK(aac.Parse(es_desc.decoder_specific_info()));
+  if (object_type != 0x40) {
+    MEDIA_LOG(reader->log_cb()) << "Audio codec: mp4a."
+                                << std::hex << static_cast<int>(object_type);
+  }
+
+  if (es_desc.IsAAC(object_type))
+    RCHECK(aac.Parse(es_desc.decoder_specific_info(), reader->log_cb()));
 
   return true;
 }
@@ -760,19 +786,116 @@
   return true;
 }
 
+SampleToGroup::SampleToGroup() : grouping_type(0), grouping_type_parameter(0) {}
+SampleToGroup::~SampleToGroup() {}
+FourCC SampleToGroup::BoxType() const { return FOURCC_SBGP; }
+
+bool SampleToGroup::Parse(BoxReader* reader) {
+  RCHECK(reader->ReadFullBoxHeader() &&
+         reader->Read4(&grouping_type));
+
+  if (reader->version() == 1)
+    RCHECK(reader->Read4(&grouping_type_parameter));
+
+  if (grouping_type != FOURCC_SEIG) {
+    DLOG(WARNING) << "SampleToGroup box with grouping_type '" << grouping_type
+                  << "' is not supported.";
+    return true;
+  }
+
+  uint32 count;
+  RCHECK(reader->Read4(&count));
+  entries.resize(count);
+  for (uint32 i = 0; i < count; ++i) {
+    RCHECK(reader->Read4(&entries[i].sample_count) &&
+           reader->Read4(&entries[i].group_description_index));
+  }
+  return true;
+}
+
+CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
+    : is_encrypted(false), iv_size(0) {}
+CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {}
+
+SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {}
+SampleGroupDescription::~SampleGroupDescription() {}
+FourCC SampleGroupDescription::BoxType() const { return FOURCC_SGPD; }
+
+bool SampleGroupDescription::Parse(BoxReader* reader) {
+  RCHECK(reader->ReadFullBoxHeader() &&
+         reader->Read4(&grouping_type));
+
+  if (grouping_type != FOURCC_SEIG) {
+    DLOG(WARNING) << "SampleGroupDescription box with grouping_type '"
+                  << grouping_type << "' is not supported.";
+    return true;
+  }
+
+  const uint8 version = reader->version();
+
+  const size_t kKeyIdSize = 16;
+  const size_t kEntrySize = sizeof(uint32) + kKeyIdSize;
+  uint32 default_length = 0;
+  if (version == 1) {
+      RCHECK(reader->Read4(&default_length));
+      RCHECK(default_length == 0 || default_length >= kEntrySize);
+  }
+
+  uint32 count;
+  RCHECK(reader->Read4(&count));
+  entries.resize(count);
+  for (uint32 i = 0; i < count; ++i) {
+    if (version == 1) {
+      if (default_length == 0) {
+        uint32 description_length = 0;
+        RCHECK(reader->Read4(&description_length));
+        RCHECK(description_length >= kEntrySize);
+      }
+    }
+
+    uint8 flag;
+    RCHECK(reader->SkipBytes(2) &&  // reserved.
+           reader->Read1(&flag) &&
+           reader->Read1(&entries[i].iv_size) &&
+           reader->ReadVec(&entries[i].key_id, kKeyIdSize));
+
+    entries[i].is_encrypted = (flag != 0);
+    if (entries[i].is_encrypted) {
+      RCHECK(entries[i].iv_size == 8 || entries[i].iv_size == 16);
+    } else {
+      RCHECK(entries[i].iv_size == 0);
+    }
+  }
+  return true;
+}
+
 TrackFragment::TrackFragment() {}
 TrackFragment::~TrackFragment() {}
 FourCC TrackFragment::BoxType() const { return FOURCC_TRAF; }
 
 bool TrackFragment::Parse(BoxReader* reader) {
-  return reader->ScanChildren() &&
+  RCHECK(reader->ScanChildren() &&
          reader->ReadChild(&header) &&
          // Media Source specific: 'tfdt' required
          reader->ReadChild(&decode_time) &&
          reader->MaybeReadChildren(&runs) &&
          reader->MaybeReadChild(&auxiliary_offset) &&
          reader->MaybeReadChild(&auxiliary_size) &&
-         reader->MaybeReadChild(&sdtp);
+         reader->MaybeReadChild(&sdtp));
+
+  // There could be multiple SampleGroupDescription and SampleToGroup boxes with
+  // different grouping types. For common encryption, the relevant grouping type
+  // is 'seig'. Continue reading until 'seig' is found, or until running out of
+  // child boxes.
+  while (sample_group_description.grouping_type != FOURCC_SEIG &&
+         reader->HasChild(&sample_group_description)) {
+    RCHECK(reader->ReadChild(&sample_group_description));
+  }
+  while (sample_to_group.grouping_type != FOURCC_SEIG &&
+         reader->HasChild(&sample_to_group)) {
+    RCHECK(reader->ReadChild(&sample_to_group));
+  }
+  return true;
 }
 
 MovieFragment::MovieFragment() {}
diff --git a/media/formats/mp4/box_definitions.h b/media/formats/mp4/box_definitions.h
index 9daa82e..2fc4a48 100644
--- a/media/formats/mp4/box_definitions.h
+++ b/media/formats/mp4/box_definitions.h
@@ -150,6 +150,13 @@
 struct MEDIA_EXPORT AVCDecoderConfigurationRecord : Box {
   DECLARE_BOX_METHODS(AVCDecoderConfigurationRecord);
 
+  // Parses AVCDecoderConfigurationRecord data encoded in |data|.
+  // Note: This method is intended to parse data outside the MP4StreamParser
+  //       context and therefore the box header is not expected to be present
+  //       in |data|.
+  // Returns true if |data| was successfully parsed.
+  bool Parse(const uint8* data, int data_size);
+
   uint8 version;
   uint8 profile_indication;
   uint8 profile_compatibility;
@@ -161,6 +168,9 @@
 
   std::vector<SPS> sps_list;
   std::vector<PPS> pps_list;
+
+ private:
+  bool ParseInternal(BufferReader* reader, const LogCB& log_cb);
 };
 
 struct MEDIA_EXPORT PixelAspectRatioBox : Box {
@@ -355,6 +365,40 @@
   std::vector<SampleDependsOn> sample_depends_on_;
 };
 
+struct MEDIA_EXPORT CencSampleEncryptionInfoEntry {
+  CencSampleEncryptionInfoEntry();
+  ~CencSampleEncryptionInfoEntry();
+
+  bool is_encrypted;
+  uint8 iv_size;
+  std::vector<uint8> key_id;
+};
+
+struct MEDIA_EXPORT SampleGroupDescription : Box {  // 'sgpd'.
+  DECLARE_BOX_METHODS(SampleGroupDescription);
+
+  uint32 grouping_type;
+  std::vector<CencSampleEncryptionInfoEntry> entries;
+};
+
+struct MEDIA_EXPORT SampleToGroupEntry {
+  enum GroupDescriptionIndexBase {
+    kTrackGroupDescriptionIndexBase = 0,
+    kFragmentGroupDescriptionIndexBase = 0x10000,
+  };
+
+  uint32 sample_count;
+  uint32 group_description_index;
+};
+
+struct MEDIA_EXPORT SampleToGroup : Box {  // 'sbgp'.
+  DECLARE_BOX_METHODS(SampleToGroup);
+
+  uint32 grouping_type;
+  uint32 grouping_type_parameter;  // Version 1 only.
+  std::vector<SampleToGroupEntry> entries;
+};
+
 struct MEDIA_EXPORT TrackFragment : Box {
   DECLARE_BOX_METHODS(TrackFragment);
 
@@ -364,6 +408,8 @@
   SampleAuxiliaryInformationOffset auxiliary_offset;
   SampleAuxiliaryInformationSize auxiliary_size;
   IndependentAndDisposableSamples sdtp;
+  SampleGroupDescription sample_group_description;
+  SampleToGroup sample_to_group;
 };
 
 struct MEDIA_EXPORT MovieFragment : Box {
diff --git a/media/formats/mp4/box_reader.cc b/media/formats/mp4/box_reader.cc
index 7910217..fd81d13 100644
--- a/media/formats/mp4/box_reader.cc
+++ b/media/formats/mp4/box_reader.cc
@@ -183,6 +183,12 @@
   return !err && pos() == size();
 }
 
+bool BoxReader::HasChild(Box* child) {
+  DCHECK(scanned_);
+  DCHECK(child);
+  return children_.count(child->BoxType()) > 0;
+}
+
 bool BoxReader::ReadChild(Box* child) {
   DCHECK(scanned_);
   FourCC child_type = child->BoxType();
diff --git a/media/formats/mp4/box_reader.h b/media/formats/mp4/box_reader.h
index d4b608e..3360204 100644
--- a/media/formats/mp4/box_reader.h
+++ b/media/formats/mp4/box_reader.h
@@ -29,7 +29,10 @@
 class MEDIA_EXPORT BufferReader {
  public:
   BufferReader(const uint8* buf, const int size)
-    : buf_(buf), size_(size), pos_(0) {}
+      : buf_(buf), size_(size), pos_(0) {
+    CHECK(buf);
+    CHECK_GE(size, 0);
+  }
 
   bool HasBytes(int count) { return (pos() + count <= size()); }
 
@@ -105,6 +108,9 @@
   // buffer position. Must be called before any of the *Child functions work.
   bool ScanChildren() WARN_UNUSED_RESULT;
 
+  // Return true if child with type |child.BoxType()| exists.
+  bool HasChild(Box* child) WARN_UNUSED_RESULT;
+
   // Read exactly one child box from the set of children. The type of the child
   // will be determined by the BoxType() method of |child|.
   bool ReadChild(Box* child) WARN_UNUSED_RESULT;
@@ -136,6 +142,8 @@
   uint8 version() const { return version_; }
   uint32 flags() const  { return flags_; }
 
+  const LogCB& log_cb() const { return log_cb_; }
+
  private:
   BoxReader(const uint8* buf, const int size, const LogCB& log_cb);
 
diff --git a/media/formats/mp4/fourccs.h b/media/formats/mp4/fourccs.h
index fce069b..d9086fa 100644
--- a/media/formats/mp4/fourccs.h
+++ b/media/formats/mp4/fourccs.h
@@ -53,9 +53,12 @@
   FOURCC_PSSH = 0x70737368,
   FOURCC_SAIO = 0x7361696f,
   FOURCC_SAIZ = 0x7361697a,
+  FOURCC_SBGP = 0x73626770,
   FOURCC_SCHI = 0x73636869,
   FOURCC_SCHM = 0x7363686d,
   FOURCC_SDTP = 0x73647470,
+  FOURCC_SEIG = 0x73656967,
+  FOURCC_SGPD = 0x73677064,
   FOURCC_SIDX = 0x73696478,
   FOURCC_SINF = 0x73696e66,
   FOURCC_SKIP = 0x736b6970,
diff --git a/media/formats/mp4/mp4_stream_parser.cc b/media/formats/mp4/mp4_stream_parser.cc
index 76fdeaf..a46178b 100644
--- a/media/formats/mp4/mp4_stream_parser.cc
+++ b/media/formats/mp4/mp4_stream_parser.cc
@@ -428,12 +428,6 @@
   if (!audio && !video)
     runs_->AdvanceRun();
 
-  // AuxInfo is required for encrypted samples.
-  // See ISO Common Encryption spec: ISO/IEC FDIS 23001-7:2011(E);
-  // Section 7: Common Encryption Sample Auxiliary Information.
-  if (runs_->is_encrypted() && !runs_->aux_info_size())
-    return false;
-
   // Attempt to cache the auxiliary information first. Aux info is usually
   // placed in a contiguous block before the sample data, rather than being
   // interleaved. If we didn't cache it, this would require that we retain the
diff --git a/media/formats/mp4/mp4_stream_parser_unittest.cc b/media/formats/mp4/mp4_stream_parser_unittest.cc
index d19e47c..ef0bd44 100644
--- a/media/formats/mp4/mp4_stream_parser_unittest.cc
+++ b/media/formats/mp4/mp4_stream_parser_unittest.cc
@@ -209,7 +209,11 @@
 // SampleAuxiliaryInformation{Sizes|Offsets}Box (saiz|saio) are missing.
 // The parser should fail instead of crash. See http://crbug.com/361347
 TEST_F(MP4StreamParserTest, MissingSampleAuxInfo) {
-  ParseMP4File("bear-1280x720-a_frag-cenc_missing-saiz-saio.mp4", 512);
+  InitializeParser();
+
+  scoped_refptr<DecoderBuffer> buffer =
+      ReadTestDataFile("bear-1280x720-a_frag-cenc_missing-saiz-saio.mp4");
+  EXPECT_FALSE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
 }
 
 // Test a file where all video samples start with an Access Unit
diff --git a/media/formats/mp4/sample_to_group_iterator.cc b/media/formats/mp4/sample_to_group_iterator.cc
new file mode 100644
index 0000000..01c7072
--- /dev/null
+++ b/media/formats/mp4/sample_to_group_iterator.cc
@@ -0,0 +1,47 @@
+// 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.
+
+#include "media/formats/mp4/sample_to_group_iterator.h"
+
+#include "base/logging.h"
+
+namespace media {
+namespace mp4 {
+
+SampleToGroupIterator::SampleToGroupIterator(
+    const SampleToGroup& sample_to_group)
+    : remaining_samples_(0),
+      sample_to_group_table_(sample_to_group.entries),
+      iterator_(sample_to_group_table_.begin()) {
+  // Handle the case that the table contains an entry with sample count 0.
+  while (iterator_ != sample_to_group_table_.end()) {
+    remaining_samples_ = iterator_->sample_count;
+    if (remaining_samples_ > 0)
+      break;
+    ++iterator_;
+  }
+}
+
+SampleToGroupIterator::~SampleToGroupIterator() {}
+
+bool SampleToGroupIterator::Advance() {
+  DCHECK(IsValid());
+
+  --remaining_samples_;
+  // Handle the case that the table contains an entry with sample count 0.
+  while (remaining_samples_ == 0) {
+    ++iterator_;
+    if (iterator_ == sample_to_group_table_.end())
+      return false;
+    remaining_samples_ = iterator_->sample_count;
+  }
+  return true;
+}
+
+bool SampleToGroupIterator::IsValid() const {
+  return remaining_samples_ > 0;
+}
+
+}  // namespace mp4
+}  // namespace media
diff --git a/media/formats/mp4/sample_to_group_iterator.h b/media/formats/mp4/sample_to_group_iterator.h
new file mode 100644
index 0000000..c2ea60f
--- /dev/null
+++ b/media/formats/mp4/sample_to_group_iterator.h
@@ -0,0 +1,49 @@
+// 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.
+
+#ifndef MEDIA_FORMATS_MP4_SAMPLE_TO_GROUP_ITERATOR_H_
+#define MEDIA_FORMATS_MP4_SAMPLE_TO_GROUP_ITERATOR_H_
+
+#include <vector>
+
+#include "media/formats/mp4/box_definitions.h"
+
+namespace media {
+namespace mp4 {
+
+// Sample To Group Box ('sbgp') can be used to find the group that a sample
+// belongs to and the associated description of that sample group. It is
+// compactly coded though. This class implements the iterator to iterate
+// through the compressed table to get the associated sample group description
+// index.
+class MEDIA_EXPORT SampleToGroupIterator {
+ public:
+  explicit SampleToGroupIterator(const SampleToGroup& sample_to_group);
+  ~SampleToGroupIterator();
+
+  // Advances the iterator to refer to the next sample. Return status
+  // indicating whether the sample is still valid.
+  bool Advance();
+
+  // Returns whether the current sample is valid.
+  bool IsValid() const;
+
+  // Returns group description index for current sample.
+  uint32 group_description_index() const {
+    return iterator_->group_description_index;
+  }
+
+ private:
+  // Track how many samples remaining for current table entry.
+  uint32 remaining_samples_;
+  const std::vector<SampleToGroupEntry>& sample_to_group_table_;
+  std::vector<SampleToGroupEntry>::const_iterator iterator_;
+
+  DISALLOW_COPY_AND_ASSIGN(SampleToGroupIterator);
+};
+
+}  // namespace mp4
+}  // namespace media
+
+#endif  // MEDIA_FORMATS_MP4_SAMPLE_TO_GROUP_ITERATOR_H_
diff --git a/media/formats/mp4/sample_to_group_iterator_unittest.cc b/media/formats/mp4/sample_to_group_iterator_unittest.cc
new file mode 100644
index 0000000..3e8148c
--- /dev/null
+++ b/media/formats/mp4/sample_to_group_iterator_unittest.cc
@@ -0,0 +1,65 @@
+// 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.
+
+#include "media/formats/mp4/sample_to_group_iterator.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+namespace mp4 {
+
+namespace {
+const SampleToGroupEntry kCompactSampleToGroupTable[] =
+    {{10, 8}, {9, 5}, {25, 7}, {48, 63}, {8, 2}};
+}  // namespace
+
+class SampleToGroupIteratorTest : public testing::Test {
+ public:
+  SampleToGroupIteratorTest() {
+    // Build sample group description index table from kSampleToGroupTable.
+    for (size_t i = 0; i < arraysize(kCompactSampleToGroupTable); ++i) {
+      for (uint32 j = 0; j < kCompactSampleToGroupTable[i].sample_count; ++j) {
+        sample_to_group_table_.push_back(
+            kCompactSampleToGroupTable[i].group_description_index);
+      }
+    }
+
+    sample_to_group_.entries.assign(
+        kCompactSampleToGroupTable,
+        kCompactSampleToGroupTable + arraysize(kCompactSampleToGroupTable));
+    sample_to_group_iterator_.reset(
+        new SampleToGroupIterator(sample_to_group_));
+  }
+
+ protected:
+  std::vector<uint32> sample_to_group_table_;
+  SampleToGroup sample_to_group_;
+  scoped_ptr<SampleToGroupIterator> sample_to_group_iterator_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SampleToGroupIteratorTest);
+};
+
+TEST_F(SampleToGroupIteratorTest, EmptyTable) {
+  SampleToGroup sample_to_group;
+  SampleToGroupIterator iterator(sample_to_group);
+  EXPECT_FALSE(iterator.IsValid());
+}
+
+TEST_F(SampleToGroupIteratorTest, Advance) {
+  ASSERT_EQ(sample_to_group_table_[0],
+            sample_to_group_iterator_->group_description_index());
+  for (uint32 sample = 1; sample < sample_to_group_table_.size(); ++sample) {
+    ASSERT_TRUE(sample_to_group_iterator_->Advance());
+    ASSERT_EQ(sample_to_group_table_[sample],
+              sample_to_group_iterator_->group_description_index());
+    ASSERT_TRUE(sample_to_group_iterator_->IsValid());
+  }
+  ASSERT_FALSE(sample_to_group_iterator_->Advance());
+  ASSERT_FALSE(sample_to_group_iterator_->IsValid());
+}
+
+}  // namespace mp4
+}  // namespace media
diff --git a/media/formats/mp4/track_run_iterator.cc b/media/formats/mp4/track_run_iterator.cc
index bc38352..2fff4b3 100644
--- a/media/formats/mp4/track_run_iterator.cc
+++ b/media/formats/mp4/track_run_iterator.cc
@@ -9,6 +9,7 @@
 #include "media/base/buffers.h"
 #include "media/base/stream_parser_buffer.h"
 #include "media/formats/mp4/rcheck.h"
+#include "media/formats/mp4/sample_to_group_iterator.h"
 
 namespace {
 static const uint32 kSampleIsDifferenceSampleFlagMask = 0x10000;
@@ -22,6 +23,7 @@
   int duration;
   int cts_offset;
   bool is_keyframe;
+  uint32 cenc_group_description_index;
 };
 
 struct TrackRunInfo {
@@ -40,6 +42,8 @@
   std::vector<uint8> aux_info_sizes;  // Populated if default_size == 0.
   int aux_info_total_size;
 
+  std::vector<CencSampleEncryptionInfoEntry> sample_encryption_info;
+
   TrackRunInfo();
   ~TrackRunInfo();
 };
@@ -215,6 +219,9 @@
       }
     }
 
+    SampleToGroupIterator sample_to_group_itr(traf.sample_to_group);
+    bool is_sample_to_group_valid = sample_to_group_itr.IsValid();
+
     int64 run_start_dts = traf.decode_time.decode_time;
     int sample_count_sum = 0;
     bool is_sync_sample_box_present =
@@ -226,6 +233,7 @@
       tri.timescale = trak->media.header.timescale;
       tri.start_dts = run_start_dts;
       tri.sample_start_offset = trun.data_offset;
+      tri.sample_encryption_info = traf.sample_group_description.entries;
 
       tri.is_audio = (stsd.type == kAudio);
       if (tri.is_audio) {
@@ -289,10 +297,41 @@
         // and downstream code's "is keyframe" concept.
         if (!is_sync_sample_box_present)
           tri.samples[k].is_keyframe = true;
+
+        if (!is_sample_to_group_valid) {
+          // Set group description index to 0 to read encryption information
+          // from TrackEncryption Box.
+          tri.samples[k].cenc_group_description_index = 0;
+          continue;
+        }
+
+        // ISO-14496-12 Section 8.9.2.3 and 8.9.4 : group description index
+        // (1) ranges from 1 to the number of sample group entries in the track
+        // level SampleGroupDescription Box, or (2) takes the value 0 to
+        // indicate that this sample is a member of no group, in this case, the
+        // sample is associated with the default values specified in
+        // TrackEncryption Box, or (3) starts at 0x10001, i.e. the index value
+        // 1, with the value 1 in the top 16 bits, to reference fragment-local
+        // SampleGroupDescription Box.
+        // Case (1) is not supported currently. We might not need it either as
+        // the same functionality can be better achieved using (2).
+        uint32 index = sample_to_group_itr.group_description_index();
+        if (index >= SampleToGroupEntry::kFragmentGroupDescriptionIndexBase) {
+          index -= SampleToGroupEntry::kFragmentGroupDescriptionIndexBase;
+          RCHECK(index != 0 && index <= tri.sample_encryption_info.size());
+        } else if (index != 0) {
+          NOTIMPLEMENTED() << "'sgpd' box in 'moov' is not supported.";
+          return false;
+        }
+        tri.samples[k].cenc_group_description_index = index;
+        is_sample_to_group_valid = sample_to_group_itr.Advance();
       }
       runs_.push_back(tri);
       sample_count_sum += trun.sample_count;
     }
+
+    // We should have iterated through all samples in SampleToGroup Box.
+    RCHECK(!sample_to_group_itr.IsValid());
   }
 
   std::sort(runs_.begin(), runs_.end(), CompareMinTrackRunDataOffset());
@@ -325,7 +364,7 @@
 // info is available in the stream.
 bool TrackRunIterator::AuxInfoNeedsToBeCached() {
   DCHECK(IsRunValid());
-  return is_encrypted() && aux_info_size() > 0 && cenc_info_.size() == 0;
+  return aux_info_size() > 0 && cenc_info_.size() == 0;
 }
 
 // This implementation currently only caches CENC auxiliary info.
@@ -339,8 +378,10 @@
     if (!info_size)
       info_size = run_itr_->aux_info_sizes[i];
 
-    BufferReader reader(buf + pos, info_size);
-    RCHECK(cenc_info_[i].Parse(track_encryption().default_iv_size, &reader));
+    if (IsSampleEncrypted(i)) {
+      BufferReader reader(buf + pos, info_size);
+      RCHECK(cenc_info_[i].Parse(GetIvSize(i), &reader));
+    }
     pos += info_size;
   }
 
@@ -387,8 +428,8 @@
 }
 
 bool TrackRunIterator::is_encrypted() const {
-  DCHECK(IsRunValid());
-  return track_encryption().is_encrypted;
+  DCHECK(IsSampleValid());
+  return IsSampleEncrypted(sample_itr_ - run_itr_->samples.begin());
 }
 
 int64 TrackRunIterator::aux_info_offset() const {
@@ -454,10 +495,17 @@
 }
 
 scoped_ptr<DecryptConfig> TrackRunIterator::GetDecryptConfig() {
+  DCHECK(is_encrypted());
+
+  if (cenc_info_.empty()) {
+    DCHECK_EQ(0, aux_info_size());
+    MEDIA_LOG(log_cb_) << "Aux Info is not available.";
+    return scoped_ptr<DecryptConfig>();
+  }
+
   size_t sample_idx = sample_itr_ - run_itr_->samples.begin();
-  DCHECK(sample_idx < cenc_info_.size());
+  DCHECK_LT(sample_idx, cenc_info_.size());
   const FrameCENCInfo& cenc_info = cenc_info_[sample_idx];
-  DCHECK(is_encrypted() && !AuxInfoNeedsToBeCached());
 
   size_t total_size = 0;
   if (!cenc_info.subsamples.empty() &&
@@ -467,7 +515,7 @@
     return scoped_ptr<DecryptConfig>();
   }
 
-  const std::vector<uint8>& kid = track_encryption().default_kid;
+  const std::vector<uint8>& kid = GetKeyId(sample_idx);
   return scoped_ptr<DecryptConfig>(new DecryptConfig(
       std::string(reinterpret_cast<const char*>(&kid[0]), kid.size()),
       std::string(reinterpret_cast<const char*>(cenc_info.iv),
@@ -475,5 +523,40 @@
       cenc_info.subsamples));
 }
 
+uint32 TrackRunIterator::GetGroupDescriptionIndex(uint32 sample_index) const {
+  DCHECK(IsRunValid());
+  DCHECK_LT(sample_index, run_itr_->samples.size());
+  return run_itr_->samples[sample_index].cenc_group_description_index;
+}
+
+const CencSampleEncryptionInfoEntry&
+TrackRunIterator::GetSampleEncryptionInfoEntry(
+    uint32 group_description_index) const {
+  DCHECK(IsRunValid());
+  DCHECK_NE(group_description_index, 0u);
+  DCHECK_LE(group_description_index, run_itr_->sample_encryption_info.size());
+  // |group_description_index| is 1-based. Subtract by 1 to index the vector.
+  return run_itr_->sample_encryption_info[group_description_index - 1];
+}
+
+bool TrackRunIterator::IsSampleEncrypted(size_t sample_index) const {
+  uint32 index = GetGroupDescriptionIndex(sample_index);
+  return (index == 0) ? track_encryption().is_encrypted
+                      : GetSampleEncryptionInfoEntry(index).is_encrypted;
+}
+
+const std::vector<uint8>& TrackRunIterator::GetKeyId(
+    size_t sample_index) const {
+  uint32 index = GetGroupDescriptionIndex(sample_index);
+  return (index == 0) ? track_encryption().default_kid
+                      : GetSampleEncryptionInfoEntry(index).key_id;
+}
+
+uint8 TrackRunIterator::GetIvSize(size_t sample_index) const {
+  uint32 index = GetGroupDescriptionIndex(sample_index);
+  return (index == 0) ? track_encryption().default_iv_size
+                      : GetSampleEncryptionInfoEntry(index).iv_size;
+}
+
 }  // namespace mp4
 }  // namespace media
diff --git a/media/formats/mp4/track_run_iterator.h b/media/formats/mp4/track_run_iterator.h
index 829dd11..8167478 100644
--- a/media/formats/mp4/track_run_iterator.h
+++ b/media/formats/mp4/track_run_iterator.h
@@ -87,6 +87,15 @@
   void ResetRun();
   const TrackEncryption& track_encryption() const;
 
+  uint32 GetGroupDescriptionIndex(uint32 sample_index) const;
+  const CencSampleEncryptionInfoEntry& GetSampleEncryptionInfoEntry(
+      uint32 group_description_index) const;
+
+  // Sample encryption information.
+  bool IsSampleEncrypted(size_t sample_index) const;
+  uint8 GetIvSize(size_t sample_index) const;
+  const std::vector<uint8>& GetKeyId(size_t sample_index) const;
+
   const Movie* moov_;
   LogCB log_cb_;
 
diff --git a/media/formats/mp4/track_run_iterator_unittest.cc b/media/formats/mp4/track_run_iterator_unittest.cc
index ea37bab..2ef3f83 100644
--- a/media/formats/mp4/track_run_iterator_unittest.cc
+++ b/media/formats/mp4/track_run_iterator_unittest.cc
@@ -37,6 +37,11 @@
   0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x44
 };
 
+static const uint8 kCencSampleGroupKeyId[] = {
+  0x46, 0x72, 0x61, 0x67, 0x53, 0x61, 0x6d, 0x70,
+  0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b
+};
+
 namespace media {
 namespace mp4 {
 
@@ -133,9 +138,28 @@
     sinf->type.type = FOURCC_CENC;
     sinf->info.track_encryption.is_encrypted = true;
     sinf->info.track_encryption.default_iv_size = 8;
-    sinf->info.track_encryption.default_kid.insert(
-        sinf->info.track_encryption.default_kid.begin(),
-        kKeyId, kKeyId + arraysize(kKeyId));
+    sinf->info.track_encryption.default_kid.assign(kKeyId,
+                                                   kKeyId + arraysize(kKeyId));
+  }
+
+  // Add SampleGroupDescription Box with two entries (an unencrypted entry and
+  // an encrypted entry). Populate SampleToGroup Box from input array.
+  void AddCencSampleGroup(TrackFragment* frag,
+                          const SampleToGroupEntry* sample_to_group_entries,
+                          size_t num_entries) {
+    frag->sample_group_description.grouping_type = FOURCC_SEIG;
+    frag->sample_group_description.entries.resize(2);
+    frag->sample_group_description.entries[0].is_encrypted = false;
+    frag->sample_group_description.entries[0].iv_size = 0;
+    frag->sample_group_description.entries[1].is_encrypted = true;
+    frag->sample_group_description.entries[1].iv_size = 8;
+    frag->sample_group_description.entries[1].key_id.assign(
+        kCencSampleGroupKeyId,
+        kCencSampleGroupKeyId + arraysize(kCencSampleGroupKeyId));
+
+    frag->sample_to_group.grouping_type = FOURCC_SEIG;
+    frag->sample_to_group.entries.assign(sample_to_group_entries,
+                                         sample_to_group_entries + num_entries);
   }
 
   // Add aux info covering the first track run to a TrackFragment, and update
@@ -149,6 +173,20 @@
     frag->runs[0].sample_sizes[1] = 10;
   }
 
+  bool InitMoofWithArbitraryAuxInfo(MovieFragment* moof) {
+    // Add aux info header (equal sized aux info for every sample).
+    for (uint32 i = 0; i < moof->tracks.size(); ++i) {
+      moof->tracks[i].auxiliary_offset.offsets.push_back(50);
+      moof->tracks[i].auxiliary_size.sample_count = 10;
+      moof->tracks[i].auxiliary_size.default_sample_info_size = 8;
+    }
+
+    // We don't care about the actual data in aux.
+    std::vector<uint8> aux_info(1000);
+    return iter_->Init(*moof) &&
+           iter_->CacheAuxInfo(&aux_info[0], aux_info.size());
+  }
+
   void SetAscending(std::vector<uint32>* vec) {
     vec->resize(10);
     for (size_t i = 0; i < vec->size(); i++)
@@ -356,6 +394,77 @@
   EXPECT_EQ(config->subsamples()[1].cypher_bytes, 4u);
 }
 
+TEST_F(TrackRunIteratorTest, CencSampleGroupTest) {
+  MovieFragment moof = CreateFragment();
+
+  const SampleToGroupEntry kSampleToGroupTable[] = {
+      // Associated with the second entry in SampleGroupDescription Box.
+      {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 2},
+      // Associated with the first entry in SampleGroupDescription Box.
+      {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 1}};
+  AddCencSampleGroup(
+      &moof.tracks[0], kSampleToGroupTable, arraysize(kSampleToGroupTable));
+
+  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
+  ASSERT_TRUE(InitMoofWithArbitraryAuxInfo(&moof));
+
+  std::string cenc_sample_group_key_id(
+      kCencSampleGroupKeyId,
+      kCencSampleGroupKeyId + arraysize(kCencSampleGroupKeyId));
+  // The first sample is encrypted and the second sample is unencrypted.
+  EXPECT_TRUE(iter_->is_encrypted());
+  EXPECT_EQ(cenc_sample_group_key_id, iter_->GetDecryptConfig()->key_id());
+  iter_->AdvanceSample();
+  EXPECT_FALSE(iter_->is_encrypted());
+}
+
+TEST_F(TrackRunIteratorTest, CencSampleGroupWithTrackEncryptionBoxTest) {
+  // Add TrackEncryption Box.
+  AddEncryption(&moov_.tracks[0]);
+
+  MovieFragment moof = CreateFragment();
+
+  const SampleToGroupEntry kSampleToGroupTable[] = {
+      // Associated with the second entry in SampleGroupDescription Box.
+      {2, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 2},
+      // Associated with the default values specified in TrackEncryption Box.
+      {4, 0},
+      // Associated with the first entry in SampleGroupDescription Box.
+      {3, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 1}};
+  AddCencSampleGroup(
+      &moof.tracks[0], kSampleToGroupTable, arraysize(kSampleToGroupTable));
+
+  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
+  ASSERT_TRUE(InitMoofWithArbitraryAuxInfo(&moof));
+
+  std::string track_encryption_key_id(kKeyId, kKeyId + arraysize(kKeyId));
+  std::string cenc_sample_group_key_id(
+      kCencSampleGroupKeyId,
+      kCencSampleGroupKeyId + arraysize(kCencSampleGroupKeyId));
+
+  for (size_t i = 0; i < kSampleToGroupTable[0].sample_count; ++i) {
+    EXPECT_TRUE(iter_->is_encrypted());
+    EXPECT_EQ(cenc_sample_group_key_id, iter_->GetDecryptConfig()->key_id());
+    iter_->AdvanceSample();
+  }
+
+  for (size_t i = 0; i < kSampleToGroupTable[1].sample_count; ++i) {
+    EXPECT_TRUE(iter_->is_encrypted());
+    EXPECT_EQ(track_encryption_key_id, iter_->GetDecryptConfig()->key_id());
+    iter_->AdvanceSample();
+  }
+
+  for (size_t i = 0; i < kSampleToGroupTable[2].sample_count; ++i) {
+    EXPECT_FALSE(iter_->is_encrypted());
+    iter_->AdvanceSample();
+  }
+
+  // The remaining samples should be associated with the default values
+  // specified in TrackEncryption Box.
+  EXPECT_TRUE(iter_->is_encrypted());
+  EXPECT_EQ(track_encryption_key_id, iter_->GetDecryptConfig()->key_id());
+}
+
 // It is legal for aux info blocks to be shared among multiple formats.
 TEST_F(TrackRunIteratorTest, SharedAuxInfoTest) {
   AddEncryption(&moov_.tracks[0]);
diff --git a/media/formats/webm/webm_cluster_parser.cc b/media/formats/webm/webm_cluster_parser.cc
index 3816fdb..172eafa 100644
--- a/media/formats/webm/webm_cluster_parser.cc
+++ b/media/formats/webm/webm_cluster_parser.cc
@@ -416,8 +416,9 @@
   }
 
   if (discard_padding != 0) {
-    buffer->set_discard_padding(base::TimeDelta::FromMicroseconds(
-                                    discard_padding / 1000));
+    buffer->set_discard_padding(std::make_pair(
+        base::TimeDelta(),
+        base::TimeDelta::FromMicroseconds(discard_padding / 1000)));
   }
 
   return track->AddBuffer(buffer);
diff --git a/media/media.gyp b/media/media.gyp
index 3e215b1..a799028 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -357,6 +357,8 @@
         'ffmpeg/ffmpeg_common.cc',
         'ffmpeg/ffmpeg_common.h',
         'ffmpeg/ffmpeg_deleters.h',
+        'filters/audio_clock.cc',
+        'filters/audio_clock.h',
         'filters/audio_file_reader.cc',
         'filters/audio_file_reader.h',
         'filters/audio_renderer_algorithm.cc',
@@ -385,8 +387,6 @@
         'filters/ffmpeg_demuxer.h',
         'filters/ffmpeg_glue.cc',
         'filters/ffmpeg_glue.h',
-        'filters/ffmpeg_h264_to_annex_b_bitstream_converter.cc',
-        'filters/ffmpeg_h264_to_annex_b_bitstream_converter.h',
         'filters/ffmpeg_video_decoder.cc',
         'filters/ffmpeg_video_decoder.h',
         'filters/file_data_source.cc',
@@ -401,8 +401,6 @@
         'filters/h264_bit_reader.h',
         'filters/h264_parser.cc',
         'filters/h264_parser.h',
-        'filters/h264_to_annex_b_bitstream_converter.cc',
-        'filters/h264_to_annex_b_bitstream_converter.h',
         'filters/in_memory_url_protocol.cc',
         'filters/in_memory_url_protocol.h',
         'filters/legacy_frame_processor.cc',
@@ -846,6 +844,10 @@
         }],
         ['proprietary_codecs==1', {
           'sources': [
+            'filters/ffmpeg_h264_to_annex_b_bitstream_converter.cc',
+            'filters/ffmpeg_h264_to_annex_b_bitstream_converter.h',
+            'filters/h264_to_annex_b_bitstream_converter.cc',
+            'filters/h264_to_annex_b_bitstream_converter.h',
             'formats/mp2t/es_parser.h',
             'formats/mp2t/es_parser_adts.cc',
             'formats/mp2t/es_parser_adts.h',
@@ -879,6 +881,8 @@
             'formats/mp4/es_descriptor.h',
             'formats/mp4/mp4_stream_parser.cc',
             'formats/mp4/mp4_stream_parser.h',
+            'formats/mp4/sample_to_group_iterator.cc',
+            'formats/mp4/sample_to_group_iterator.h',
             'formats/mp4/track_run_iterator.cc',
             'formats/mp4/track_run_iterator.h',
             'formats/mpeg/adts_constants.cc',
@@ -1018,6 +1022,7 @@
         'cdm/aes_decryptor_unittest.cc',
         'cdm/json_web_key_unittest.cc',
         'ffmpeg/ffmpeg_common_unittest.cc',
+        'filters/audio_clock_unittest.cc',
         'filters/audio_decoder_selector_unittest.cc',
         'filters/audio_file_reader_unittest.cc',
         'filters/audio_renderer_algorithm_unittest.cc',
@@ -1036,12 +1041,10 @@
         'filters/ffmpeg_audio_decoder_unittest.cc',
         'filters/ffmpeg_demuxer_unittest.cc',
         'filters/ffmpeg_glue_unittest.cc',
-        'filters/ffmpeg_h264_to_annex_b_bitstream_converter_unittest.cc',
         'filters/ffmpeg_video_decoder_unittest.cc',
         'filters/file_data_source_unittest.cc',
         'filters/h264_bit_reader_unittest.cc',
         'filters/h264_parser_unittest.cc',
-        'filters/h264_to_annex_b_bitstream_converter_unittest.cc',
         'filters/in_memory_url_protocol_unittest.cc',
         'filters/opus_audio_decoder_unittest.cc',
         'filters/pipeline_integration_test.cc',
@@ -1053,6 +1056,7 @@
         'filters/video_frame_scheduler_unittest.cc',
         'filters/video_frame_stream_unittest.cc',
         'filters/video_renderer_impl_unittest.cc',
+        'midi/midi_manager_unittest.cc',
         'midi/midi_manager_usb_unittest.cc',
         'midi/midi_message_queue_unittest.cc',
         'midi/midi_message_util_unittest.cc',
@@ -1103,8 +1107,7 @@
         }],
         ['os_posix==1 and OS!="mac"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
@@ -1163,6 +1166,8 @@
         }],
         ['proprietary_codecs==1', {
           'sources': [
+            'filters/ffmpeg_h264_to_annex_b_bitstream_converter_unittest.cc',
+            'filters/h264_to_annex_b_bitstream_converter_unittest.cc',
             'formats/common/stream_parser_test_base.cc',
             'formats/common/stream_parser_test_base.h',
             'formats/mp2t/es_parser_h264_unittest.cc',
@@ -1172,11 +1177,17 @@
             'formats/mp4/box_reader_unittest.cc',
             'formats/mp4/es_descriptor_unittest.cc',
             'formats/mp4/mp4_stream_parser_unittest.cc',
+            'formats/mp4/sample_to_group_iterator_unittest.cc',
             'formats/mp4/track_run_iterator_unittest.cc',
             'formats/mpeg/adts_stream_parser_unittest.cc',
             'formats/mpeg/mp3_stream_parser_unittest.cc',
           ],
         }],
+        ['enable_mpeg2ts_stream_parser==1', {
+          'defines': [
+            'ENABLE_MPEG2TS_STREAM_PARSER',
+          ],
+        }],
         # TODO(wolenetz): Fix size_t to int truncations in win64. See
         # http://crbug.com/171009
         ['OS=="win" and target_arch=="x64"', {
@@ -1690,8 +1701,7 @@
           'conditions': [
             ['os_posix==1 and OS!="mac"', {
               'conditions': [
-                # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-                ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+                ['use_allocator!="none"', {
                   'dependencies': [
                     '../base/allocator/allocator.gyp:allocator',
                   ],
diff --git a/media/media.target.darwin-arm.mk b/media/media.target.darwin-arm.mk
index c0ec9e3..72e88e7 100644
--- a/media/media.target.darwin-arm.mk
+++ b/media/media.target.darwin-arm.mk
@@ -129,6 +129,7 @@
 	media/cdm/aes_decryptor.cc \
 	media/cdm/json_web_key.cc \
 	media/cdm/key_system_names.cc \
+	media/filters/audio_clock.cc \
 	media/filters/audio_renderer_algorithm.cc \
 	media/filters/audio_renderer_impl.cc \
 	media/filters/chunk_demuxer.cc \
@@ -144,7 +145,6 @@
 	media/filters/gpu_video_decoder.cc \
 	media/filters/h264_bit_reader.cc \
 	media/filters/h264_parser.cc \
-	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/filters/legacy_frame_processor.cc \
 	media/filters/skcanvas_video_renderer.cc \
 	media/filters/source_buffer_stream.cc \
@@ -190,6 +190,7 @@
 	media/formats/webm/webm_video_client.cc \
 	media/formats/webm/webm_webvtt_parser.cc \
 	media/base/media_stub.cc \
+	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/formats/mp2t/es_parser_adts.cc \
 	media/formats/mp2t/es_parser_h264.cc \
 	media/formats/mp2t/mp2t_stream_parser.cc \
@@ -205,6 +206,7 @@
 	media/formats/mp4/cenc.cc \
 	media/formats/mp4/es_descriptor.cc \
 	media/formats/mp4/mp4_stream_parser.cc \
+	media/formats/mp4/sample_to_group_iterator.cc \
 	media/formats/mp4/track_run_iterator.cc \
 	media/formats/mpeg/adts_constants.cc \
 	media/formats/mpeg/adts_stream_parser.cc \
@@ -226,7 +228,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -276,11 +277,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -355,7 +351,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -405,11 +400,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/media/media.target.darwin-arm64.mk b/media/media.target.darwin-arm64.mk
index 9e8a4d4..5d1cd08 100644
--- a/media/media.target.darwin-arm64.mk
+++ b/media/media.target.darwin-arm64.mk
@@ -129,6 +129,7 @@
 	media/cdm/aes_decryptor.cc \
 	media/cdm/json_web_key.cc \
 	media/cdm/key_system_names.cc \
+	media/filters/audio_clock.cc \
 	media/filters/audio_renderer_algorithm.cc \
 	media/filters/audio_renderer_impl.cc \
 	media/filters/chunk_demuxer.cc \
@@ -144,7 +145,6 @@
 	media/filters/gpu_video_decoder.cc \
 	media/filters/h264_bit_reader.cc \
 	media/filters/h264_parser.cc \
-	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/filters/legacy_frame_processor.cc \
 	media/filters/skcanvas_video_renderer.cc \
 	media/filters/source_buffer_stream.cc \
@@ -190,6 +190,7 @@
 	media/formats/webm/webm_video_client.cc \
 	media/formats/webm/webm_webvtt_parser.cc \
 	media/base/media_stub.cc \
+	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/formats/mp2t/es_parser_adts.cc \
 	media/formats/mp2t/es_parser_h264.cc \
 	media/formats/mp2t/mp2t_stream_parser.cc \
@@ -205,6 +206,7 @@
 	media/formats/mp4/cenc.cc \
 	media/formats/mp4/es_descriptor.cc \
 	media/formats/mp4/mp4_stream_parser.cc \
+	media/formats/mp4/sample_to_group_iterator.cc \
 	media/formats/mp4/track_run_iterator.cc \
 	media/formats/mpeg/adts_constants.cc \
 	media/formats/mpeg/adts_stream_parser.cc \
@@ -272,11 +274,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -396,11 +393,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/media/media.target.darwin-mips.mk b/media/media.target.darwin-mips.mk
index 135966c..16aded3 100644
--- a/media/media.target.darwin-mips.mk
+++ b/media/media.target.darwin-mips.mk
@@ -129,6 +129,7 @@
 	media/cdm/aes_decryptor.cc \
 	media/cdm/json_web_key.cc \
 	media/cdm/key_system_names.cc \
+	media/filters/audio_clock.cc \
 	media/filters/audio_renderer_algorithm.cc \
 	media/filters/audio_renderer_impl.cc \
 	media/filters/chunk_demuxer.cc \
@@ -144,7 +145,6 @@
 	media/filters/gpu_video_decoder.cc \
 	media/filters/h264_bit_reader.cc \
 	media/filters/h264_parser.cc \
-	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/filters/legacy_frame_processor.cc \
 	media/filters/skcanvas_video_renderer.cc \
 	media/filters/source_buffer_stream.cc \
@@ -190,6 +190,7 @@
 	media/formats/webm/webm_video_client.cc \
 	media/formats/webm/webm_webvtt_parser.cc \
 	media/base/media_stub.cc \
+	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/formats/mp2t/es_parser_adts.cc \
 	media/formats/mp2t/es_parser_h264.cc \
 	media/formats/mp2t/mp2t_stream_parser.cc \
@@ -205,6 +206,7 @@
 	media/formats/mp4/cenc.cc \
 	media/formats/mp4/es_descriptor.cc \
 	media/formats/mp4/mp4_stream_parser.cc \
+	media/formats/mp4/sample_to_group_iterator.cc \
 	media/formats/mp4/track_run_iterator.cc \
 	media/formats/mpeg/adts_constants.cc \
 	media/formats/mpeg/adts_stream_parser.cc \
@@ -275,11 +277,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -403,11 +400,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/media/media.target.darwin-x86.mk b/media/media.target.darwin-x86.mk
index 44a507a..872d616 100644
--- a/media/media.target.darwin-x86.mk
+++ b/media/media.target.darwin-x86.mk
@@ -129,6 +129,7 @@
 	media/cdm/aes_decryptor.cc \
 	media/cdm/json_web_key.cc \
 	media/cdm/key_system_names.cc \
+	media/filters/audio_clock.cc \
 	media/filters/audio_renderer_algorithm.cc \
 	media/filters/audio_renderer_impl.cc \
 	media/filters/chunk_demuxer.cc \
@@ -144,7 +145,6 @@
 	media/filters/gpu_video_decoder.cc \
 	media/filters/h264_bit_reader.cc \
 	media/filters/h264_parser.cc \
-	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/filters/legacy_frame_processor.cc \
 	media/filters/skcanvas_video_renderer.cc \
 	media/filters/source_buffer_stream.cc \
@@ -190,6 +190,7 @@
 	media/formats/webm/webm_video_client.cc \
 	media/formats/webm/webm_webvtt_parser.cc \
 	media/base/media_stub.cc \
+	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/formats/mp2t/es_parser_adts.cc \
 	media/formats/mp2t/es_parser_h264.cc \
 	media/formats/mp2t/mp2t_stream_parser.cc \
@@ -205,6 +206,7 @@
 	media/formats/mp4/cenc.cc \
 	media/formats/mp4/es_descriptor.cc \
 	media/formats/mp4/mp4_stream_parser.cc \
+	media/formats/mp4/sample_to_group_iterator.cc \
 	media/formats/mp4/track_run_iterator.cc \
 	media/formats/mpeg/adts_constants.cc \
 	media/formats/mpeg/adts_stream_parser.cc \
@@ -229,7 +231,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -278,11 +279,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -358,7 +354,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -407,11 +402,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/media/media.target.darwin-x86_64.mk b/media/media.target.darwin-x86_64.mk
index 45a57bf..dcf21c1 100644
--- a/media/media.target.darwin-x86_64.mk
+++ b/media/media.target.darwin-x86_64.mk
@@ -129,6 +129,7 @@
 	media/cdm/aes_decryptor.cc \
 	media/cdm/json_web_key.cc \
 	media/cdm/key_system_names.cc \
+	media/filters/audio_clock.cc \
 	media/filters/audio_renderer_algorithm.cc \
 	media/filters/audio_renderer_impl.cc \
 	media/filters/chunk_demuxer.cc \
@@ -144,7 +145,6 @@
 	media/filters/gpu_video_decoder.cc \
 	media/filters/h264_bit_reader.cc \
 	media/filters/h264_parser.cc \
-	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/filters/legacy_frame_processor.cc \
 	media/filters/skcanvas_video_renderer.cc \
 	media/filters/source_buffer_stream.cc \
@@ -190,6 +190,7 @@
 	media/formats/webm/webm_video_client.cc \
 	media/formats/webm/webm_webvtt_parser.cc \
 	media/base/media_stub.cc \
+	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/formats/mp2t/es_parser_adts.cc \
 	media/formats/mp2t/es_parser_h264.cc \
 	media/formats/mp2t/mp2t_stream_parser.cc \
@@ -205,6 +206,7 @@
 	media/formats/mp4/cenc.cc \
 	media/formats/mp4/es_descriptor.cc \
 	media/formats/mp4/mp4_stream_parser.cc \
+	media/formats/mp4/sample_to_group_iterator.cc \
 	media/formats/mp4/track_run_iterator.cc \
 	media/formats/mpeg/adts_constants.cc \
 	media/formats/mpeg/adts_stream_parser.cc \
@@ -229,7 +231,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -278,11 +279,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -358,7 +354,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -407,11 +402,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/media/media.target.linux-arm.mk b/media/media.target.linux-arm.mk
index c0ec9e3..72e88e7 100644
--- a/media/media.target.linux-arm.mk
+++ b/media/media.target.linux-arm.mk
@@ -129,6 +129,7 @@
 	media/cdm/aes_decryptor.cc \
 	media/cdm/json_web_key.cc \
 	media/cdm/key_system_names.cc \
+	media/filters/audio_clock.cc \
 	media/filters/audio_renderer_algorithm.cc \
 	media/filters/audio_renderer_impl.cc \
 	media/filters/chunk_demuxer.cc \
@@ -144,7 +145,6 @@
 	media/filters/gpu_video_decoder.cc \
 	media/filters/h264_bit_reader.cc \
 	media/filters/h264_parser.cc \
-	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/filters/legacy_frame_processor.cc \
 	media/filters/skcanvas_video_renderer.cc \
 	media/filters/source_buffer_stream.cc \
@@ -190,6 +190,7 @@
 	media/formats/webm/webm_video_client.cc \
 	media/formats/webm/webm_webvtt_parser.cc \
 	media/base/media_stub.cc \
+	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/formats/mp2t/es_parser_adts.cc \
 	media/formats/mp2t/es_parser_h264.cc \
 	media/formats/mp2t/mp2t_stream_parser.cc \
@@ -205,6 +206,7 @@
 	media/formats/mp4/cenc.cc \
 	media/formats/mp4/es_descriptor.cc \
 	media/formats/mp4/mp4_stream_parser.cc \
+	media/formats/mp4/sample_to_group_iterator.cc \
 	media/formats/mp4/track_run_iterator.cc \
 	media/formats/mpeg/adts_constants.cc \
 	media/formats/mpeg/adts_stream_parser.cc \
@@ -226,7 +228,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -276,11 +277,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -355,7 +351,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -405,11 +400,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/media/media.target.linux-arm64.mk b/media/media.target.linux-arm64.mk
index 9e8a4d4..5d1cd08 100644
--- a/media/media.target.linux-arm64.mk
+++ b/media/media.target.linux-arm64.mk
@@ -129,6 +129,7 @@
 	media/cdm/aes_decryptor.cc \
 	media/cdm/json_web_key.cc \
 	media/cdm/key_system_names.cc \
+	media/filters/audio_clock.cc \
 	media/filters/audio_renderer_algorithm.cc \
 	media/filters/audio_renderer_impl.cc \
 	media/filters/chunk_demuxer.cc \
@@ -144,7 +145,6 @@
 	media/filters/gpu_video_decoder.cc \
 	media/filters/h264_bit_reader.cc \
 	media/filters/h264_parser.cc \
-	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/filters/legacy_frame_processor.cc \
 	media/filters/skcanvas_video_renderer.cc \
 	media/filters/source_buffer_stream.cc \
@@ -190,6 +190,7 @@
 	media/formats/webm/webm_video_client.cc \
 	media/formats/webm/webm_webvtt_parser.cc \
 	media/base/media_stub.cc \
+	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/formats/mp2t/es_parser_adts.cc \
 	media/formats/mp2t/es_parser_h264.cc \
 	media/formats/mp2t/mp2t_stream_parser.cc \
@@ -205,6 +206,7 @@
 	media/formats/mp4/cenc.cc \
 	media/formats/mp4/es_descriptor.cc \
 	media/formats/mp4/mp4_stream_parser.cc \
+	media/formats/mp4/sample_to_group_iterator.cc \
 	media/formats/mp4/track_run_iterator.cc \
 	media/formats/mpeg/adts_constants.cc \
 	media/formats/mpeg/adts_stream_parser.cc \
@@ -272,11 +274,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -396,11 +393,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/media/media.target.linux-mips.mk b/media/media.target.linux-mips.mk
index 135966c..16aded3 100644
--- a/media/media.target.linux-mips.mk
+++ b/media/media.target.linux-mips.mk
@@ -129,6 +129,7 @@
 	media/cdm/aes_decryptor.cc \
 	media/cdm/json_web_key.cc \
 	media/cdm/key_system_names.cc \
+	media/filters/audio_clock.cc \
 	media/filters/audio_renderer_algorithm.cc \
 	media/filters/audio_renderer_impl.cc \
 	media/filters/chunk_demuxer.cc \
@@ -144,7 +145,6 @@
 	media/filters/gpu_video_decoder.cc \
 	media/filters/h264_bit_reader.cc \
 	media/filters/h264_parser.cc \
-	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/filters/legacy_frame_processor.cc \
 	media/filters/skcanvas_video_renderer.cc \
 	media/filters/source_buffer_stream.cc \
@@ -190,6 +190,7 @@
 	media/formats/webm/webm_video_client.cc \
 	media/formats/webm/webm_webvtt_parser.cc \
 	media/base/media_stub.cc \
+	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/formats/mp2t/es_parser_adts.cc \
 	media/formats/mp2t/es_parser_h264.cc \
 	media/formats/mp2t/mp2t_stream_parser.cc \
@@ -205,6 +206,7 @@
 	media/formats/mp4/cenc.cc \
 	media/formats/mp4/es_descriptor.cc \
 	media/formats/mp4/mp4_stream_parser.cc \
+	media/formats/mp4/sample_to_group_iterator.cc \
 	media/formats/mp4/track_run_iterator.cc \
 	media/formats/mpeg/adts_constants.cc \
 	media/formats/mpeg/adts_stream_parser.cc \
@@ -275,11 +277,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -403,11 +400,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/media/media.target.linux-x86.mk b/media/media.target.linux-x86.mk
index 44a507a..872d616 100644
--- a/media/media.target.linux-x86.mk
+++ b/media/media.target.linux-x86.mk
@@ -129,6 +129,7 @@
 	media/cdm/aes_decryptor.cc \
 	media/cdm/json_web_key.cc \
 	media/cdm/key_system_names.cc \
+	media/filters/audio_clock.cc \
 	media/filters/audio_renderer_algorithm.cc \
 	media/filters/audio_renderer_impl.cc \
 	media/filters/chunk_demuxer.cc \
@@ -144,7 +145,6 @@
 	media/filters/gpu_video_decoder.cc \
 	media/filters/h264_bit_reader.cc \
 	media/filters/h264_parser.cc \
-	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/filters/legacy_frame_processor.cc \
 	media/filters/skcanvas_video_renderer.cc \
 	media/filters/source_buffer_stream.cc \
@@ -190,6 +190,7 @@
 	media/formats/webm/webm_video_client.cc \
 	media/formats/webm/webm_webvtt_parser.cc \
 	media/base/media_stub.cc \
+	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/formats/mp2t/es_parser_adts.cc \
 	media/formats/mp2t/es_parser_h264.cc \
 	media/formats/mp2t/mp2t_stream_parser.cc \
@@ -205,6 +206,7 @@
 	media/formats/mp4/cenc.cc \
 	media/formats/mp4/es_descriptor.cc \
 	media/formats/mp4/mp4_stream_parser.cc \
+	media/formats/mp4/sample_to_group_iterator.cc \
 	media/formats/mp4/track_run_iterator.cc \
 	media/formats/mpeg/adts_constants.cc \
 	media/formats/mpeg/adts_stream_parser.cc \
@@ -229,7 +231,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -278,11 +279,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -358,7 +354,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -407,11 +402,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/media/media.target.linux-x86_64.mk b/media/media.target.linux-x86_64.mk
index 45a57bf..dcf21c1 100644
--- a/media/media.target.linux-x86_64.mk
+++ b/media/media.target.linux-x86_64.mk
@@ -129,6 +129,7 @@
 	media/cdm/aes_decryptor.cc \
 	media/cdm/json_web_key.cc \
 	media/cdm/key_system_names.cc \
+	media/filters/audio_clock.cc \
 	media/filters/audio_renderer_algorithm.cc \
 	media/filters/audio_renderer_impl.cc \
 	media/filters/chunk_demuxer.cc \
@@ -144,7 +145,6 @@
 	media/filters/gpu_video_decoder.cc \
 	media/filters/h264_bit_reader.cc \
 	media/filters/h264_parser.cc \
-	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/filters/legacy_frame_processor.cc \
 	media/filters/skcanvas_video_renderer.cc \
 	media/filters/source_buffer_stream.cc \
@@ -190,6 +190,7 @@
 	media/formats/webm/webm_video_client.cc \
 	media/formats/webm/webm_webvtt_parser.cc \
 	media/base/media_stub.cc \
+	media/filters/h264_to_annex_b_bitstream_converter.cc \
 	media/formats/mp2t/es_parser_adts.cc \
 	media/formats/mp2t/es_parser_h264.cc \
 	media/formats/mp2t/mp2t_stream_parser.cc \
@@ -205,6 +206,7 @@
 	media/formats/mp4/cenc.cc \
 	media/formats/mp4/es_descriptor.cc \
 	media/formats/mp4/mp4_stream_parser.cc \
+	media/formats/mp4/sample_to_group_iterator.cc \
 	media/formats/mp4/track_run_iterator.cc \
 	media/formats/mpeg/adts_constants.cc \
 	media/formats/mpeg/adts_stream_parser.cc \
@@ -229,7 +231,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -278,11 +279,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -358,7 +354,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -407,11 +402,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/media/media_android_imageformat_list.target.darwin-arm.mk b/media/media_android_imageformat_list.target.darwin-arm.mk
index f3f98c8..c238050 100644
--- a/media/media_android_imageformat_list.target.darwin-arm.mk
+++ b/media/media_android_imageformat_list.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_imageformat_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'video/capture/android/imageformat_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['base/android/java/src/org/chromium/media/ImageFormat.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/media/media_android_imageformat_list.target.darwin-arm64.mk b/media/media_android_imageformat_list.target.darwin-arm64.mk
index 4f7f40f..47464f8 100644
--- a/media/media_android_imageformat_list.target.darwin-arm64.mk
+++ b/media/media_android_imageformat_list.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_imageformat_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'video/capture/android/imageformat_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['base/android/java/src/org/chromium/media/ImageFormat.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/media_android_imageformat_list.target.darwin-mips.mk b/media/media_android_imageformat_list.target.darwin-mips.mk
index 80bca0a..7693d15 100644
--- a/media/media_android_imageformat_list.target.darwin-mips.mk
+++ b/media/media_android_imageformat_list.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_imageformat_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'video/capture/android/imageformat_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['base/android/java/src/org/chromium/media/ImageFormat.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/media_android_imageformat_list.target.darwin-x86.mk b/media/media_android_imageformat_list.target.darwin-x86.mk
index 16ad927..9f4f8ca 100644
--- a/media/media_android_imageformat_list.target.darwin-x86.mk
+++ b/media/media_android_imageformat_list.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_imageformat_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'video/capture/android/imageformat_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['base/android/java/src/org/chromium/media/ImageFormat.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_android_imageformat_list.target.darwin-x86_64.mk b/media/media_android_imageformat_list.target.darwin-x86_64.mk
index d0dd777..23b7e79 100644
--- a/media/media_android_imageformat_list.target.darwin-x86_64.mk
+++ b/media/media_android_imageformat_list.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_imageformat_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'video/capture/android/imageformat_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['base/android/java/src/org/chromium/media/ImageFormat.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_android_imageformat_list.target.linux-arm.mk b/media/media_android_imageformat_list.target.linux-arm.mk
index f3f98c8..c238050 100644
--- a/media/media_android_imageformat_list.target.linux-arm.mk
+++ b/media/media_android_imageformat_list.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_imageformat_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'video/capture/android/imageformat_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['base/android/java/src/org/chromium/media/ImageFormat.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/media/media_android_imageformat_list.target.linux-arm64.mk b/media/media_android_imageformat_list.target.linux-arm64.mk
index 4f7f40f..47464f8 100644
--- a/media/media_android_imageformat_list.target.linux-arm64.mk
+++ b/media/media_android_imageformat_list.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_imageformat_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'video/capture/android/imageformat_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['base/android/java/src/org/chromium/media/ImageFormat.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/media_android_imageformat_list.target.linux-mips.mk b/media/media_android_imageformat_list.target.linux-mips.mk
index 80bca0a..7693d15 100644
--- a/media/media_android_imageformat_list.target.linux-mips.mk
+++ b/media/media_android_imageformat_list.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_imageformat_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'video/capture/android/imageformat_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['base/android/java/src/org/chromium/media/ImageFormat.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/media_android_imageformat_list.target.linux-x86.mk b/media/media_android_imageformat_list.target.linux-x86.mk
index 16ad927..9f4f8ca 100644
--- a/media/media_android_imageformat_list.target.linux-x86.mk
+++ b/media/media_android_imageformat_list.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_imageformat_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'video/capture/android/imageformat_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['base/android/java/src/org/chromium/media/ImageFormat.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_android_imageformat_list.target.linux-x86_64.mk b/media/media_android_imageformat_list.target.linux-x86_64.mk
index d0dd777..23b7e79 100644
--- a/media/media_android_imageformat_list.target.linux-x86_64.mk
+++ b/media/media_android_imageformat_list.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_imageformat_list_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'video/capture/android/imageformat_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['base/android/java/src/org/chromium/media/ImageFormat.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/media/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/media/ImageFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_android_jni_headers.target.darwin-arm.mk b/media/media_android_jni_headers.target.darwin-arm.mk
index bda76a5..3a80b56 100644
--- a/media/media_android_jni_headers.target.darwin-arm.mk
+++ b/media/media_android_jni_headers.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/AudioManagerAndroid.java', 'base/android/java/src/org/chromium/media/AudioRecordInput.java', 'base/android/java/src/org/chromium/media/MediaCodecBridge.java', 'base/android/java/src/org/chromium/media/MediaDrmBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java', 'base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -134,7 +143,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -218,7 +226,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/media/media_android_jni_headers.target.darwin-arm64.mk b/media/media_android_jni_headers.target.darwin-arm64.mk
index ba18516..123a3e5 100644
--- a/media/media_android_jni_headers.target.darwin-arm64.mk
+++ b/media/media_android_jni_headers.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/AudioManagerAndroid.java', 'base/android/java/src/org/chromium/media/AudioRecordInput.java', 'base/android/java/src/org/chromium/media/MediaCodecBridge.java', 'base/android/java/src/org/chromium/media/MediaDrmBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java', 'base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/media_android_jni_headers.target.darwin-mips.mk b/media/media_android_jni_headers.target.darwin-mips.mk
index 60b2080..902eff7 100644
--- a/media/media_android_jni_headers.target.darwin-mips.mk
+++ b/media/media_android_jni_headers.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/AudioManagerAndroid.java', 'base/android/java/src/org/chromium/media/AudioRecordInput.java', 'base/android/java/src/org/chromium/media/MediaCodecBridge.java', 'base/android/java/src/org/chromium/media/MediaDrmBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java', 'base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/media_android_jni_headers.target.darwin-x86.mk b/media/media_android_jni_headers.target.darwin-x86.mk
index f5df59e..46366f1 100644
--- a/media/media_android_jni_headers.target.darwin-x86.mk
+++ b/media/media_android_jni_headers.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/AudioManagerAndroid.java', 'base/android/java/src/org/chromium/media/AudioRecordInput.java', 'base/android/java/src/org/chromium/media/MediaCodecBridge.java', 'base/android/java/src/org/chromium/media/MediaDrmBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java', 'base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -136,7 +145,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,7 +228,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_android_jni_headers.target.darwin-x86_64.mk b/media/media_android_jni_headers.target.darwin-x86_64.mk
index c7f3373..7022a20 100644
--- a/media/media_android_jni_headers.target.darwin-x86_64.mk
+++ b/media/media_android_jni_headers.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/AudioManagerAndroid.java', 'base/android/java/src/org/chromium/media/AudioRecordInput.java', 'base/android/java/src/org/chromium/media/MediaCodecBridge.java', 'base/android/java/src/org/chromium/media/MediaDrmBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java', 'base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -136,7 +145,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,7 +228,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_android_jni_headers.target.linux-arm.mk b/media/media_android_jni_headers.target.linux-arm.mk
index bda76a5..3a80b56 100644
--- a/media/media_android_jni_headers.target.linux-arm.mk
+++ b/media/media_android_jni_headers.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/AudioManagerAndroid.java', 'base/android/java/src/org/chromium/media/AudioRecordInput.java', 'base/android/java/src/org/chromium/media/MediaCodecBridge.java', 'base/android/java/src/org/chromium/media/MediaDrmBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java', 'base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -134,7 +143,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -218,7 +226,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/media/media_android_jni_headers.target.linux-arm64.mk b/media/media_android_jni_headers.target.linux-arm64.mk
index ba18516..123a3e5 100644
--- a/media/media_android_jni_headers.target.linux-arm64.mk
+++ b/media/media_android_jni_headers.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/AudioManagerAndroid.java', 'base/android/java/src/org/chromium/media/AudioRecordInput.java', 'base/android/java/src/org/chromium/media/MediaCodecBridge.java', 'base/android/java/src/org/chromium/media/MediaDrmBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java', 'base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/media_android_jni_headers.target.linux-mips.mk b/media/media_android_jni_headers.target.linux-mips.mk
index 60b2080..902eff7 100644
--- a/media/media_android_jni_headers.target.linux-mips.mk
+++ b/media/media_android_jni_headers.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/AudioManagerAndroid.java', 'base/android/java/src/org/chromium/media/AudioRecordInput.java', 'base/android/java/src/org/chromium/media/MediaCodecBridge.java', 'base/android/java/src/org/chromium/media/MediaDrmBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java', 'base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/media_android_jni_headers.target.linux-x86.mk b/media/media_android_jni_headers.target.linux-x86.mk
index f5df59e..46366f1 100644
--- a/media/media_android_jni_headers.target.linux-x86.mk
+++ b/media/media_android_jni_headers.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/AudioManagerAndroid.java', 'base/android/java/src/org/chromium/media/AudioRecordInput.java', 'base/android/java/src/org/chromium/media/MediaCodecBridge.java', 'base/android/java/src/org/chromium/media/MediaDrmBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java', 'base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -136,7 +145,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,7 +228,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_android_jni_headers.target.linux-x86_64.mk b/media/media_android_jni_headers.target.linux-x86_64.mk
index c7f3373..7022a20 100644
--- a/media/media_android_jni_headers.target.linux-x86_64.mk
+++ b/media/media_android_jni_headers.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/AudioManagerAndroid.java', 'base/android/java/src/org/chromium/media/AudioRecordInput.java', 'base/android/java/src/org/chromium/media/MediaCodecBridge.java', 'base/android/java/src/org/chromium/media/MediaDrmBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerBridge.java', 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java', 'base/android/java/src/org/chromium/media/UsbMidiDeviceFactoryAndroid.java', 'base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioManagerAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/AudioRecordInput_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaDrmBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/MediaPlayerListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/UsbMidiDeviceFactoryAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/WebAudioMediaCodecBridge_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -136,7 +145,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,7 +228,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_asm.target.darwin-x86.mk b/media/media_asm.target.darwin-x86.mk
index ebe269f..63ce5d2 100644
--- a/media/media_asm.target.darwin-x86.mk
+++ b/media/media_asm.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_asm_target_assemble":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/yasm', '../third_party/x86inc/x86inc.asm', 'base/simd/convert_rgb_to_yuv_ssse3.inc', 'base/simd/convert_yuv_to_rgb_mmx.inc', 'base/simd/convert_yuva_to_argb_mmx.inc', 'base/simd/linear_scale_yuv_to_rgb_mmx.inc', 'base/simd/media_export.asm', 'base/simd/scale_yuv_to_rgb_mmx.inc'], 'extension': 'asm', 'process_outputs_as_sources': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/media/%(INPUT_ROOT)s.o'], 'rule_name': 'assemble', 'rule_sources': ['base/simd/convert_rgb_to_yuv_ssse3.asm', 'base/simd/convert_yuv_to_rgb_mmx.asm', 'base/simd/convert_yuv_to_rgb_sse.asm', 'base/simd/convert_yuva_to_argb_mmx.asm', 'base/simd/empty_register_state_mmx.asm', 'base/simd/linear_scale_yuv_to_rgb_mmx.asm', 'base/simd/linear_scale_yuv_to_rgb_sse.asm', 'base/simd/scale_yuv_to_rgb_mmx.asm', 'base/simd/scale_yuv_to_rgb_sse.asm'], 'action': ['$(gyp_shared_intermediate_dir)/yasm', '-DCHROMIUM', '-I..', '-felf32', '-m', 'x86', '-DARCH_X86_32', '-DELF', '-o', '$(gyp_shared_intermediate_dir)/media/%(INPUT_ROOT)s.o', '$(RULE_SOURCES)'], 'message': 'Compile assembly $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -136,7 +145,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,7 +228,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_asm.target.darwin-x86_64.mk b/media/media_asm.target.darwin-x86_64.mk
index aa08ae4..ac60c0f 100644
--- a/media/media_asm.target.darwin-x86_64.mk
+++ b/media/media_asm.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_asm_target_assemble":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/yasm', '../third_party/x86inc/x86inc.asm', 'base/simd/convert_rgb_to_yuv_ssse3.inc', 'base/simd/convert_yuv_to_rgb_mmx.inc', 'base/simd/convert_yuva_to_argb_mmx.inc', 'base/simd/linear_scale_yuv_to_rgb_mmx.inc', 'base/simd/media_export.asm', 'base/simd/scale_yuv_to_rgb_mmx.inc'], 'extension': 'asm', 'process_outputs_as_sources': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/media/%(INPUT_ROOT)s.o'], 'rule_name': 'assemble', 'rule_sources': ['base/simd/convert_rgb_to_yuv_ssse3.asm', 'base/simd/convert_yuv_to_rgb_mmx.asm', 'base/simd/convert_yuv_to_rgb_sse.asm', 'base/simd/convert_yuva_to_argb_mmx.asm', 'base/simd/empty_register_state_mmx.asm', 'base/simd/linear_scale_yuv_to_rgb_mmx.asm', 'base/simd/linear_scale_yuv_to_rgb_sse.asm', 'base/simd/scale_yuv_to_rgb_mmx.asm', 'base/simd/scale_yuv_to_rgb_sse.asm', 'base/simd/linear_scale_yuv_to_rgb_mmx_x64.asm', 'base/simd/scale_yuv_to_rgb_sse2_x64.asm'], 'action': ['$(gyp_shared_intermediate_dir)/yasm', '-DCHROMIUM', '-I..', '-DPIC', '-felf64', '-m', 'amd64', '-DARCH_X86_64', '-DARCH_X86_64', '-DELF', '-DPIC', '-o', '$(gyp_shared_intermediate_dir)/media/%(INPUT_ROOT)s.o', '$(RULE_SOURCES)'], 'message': 'Compile assembly $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx_x64.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx_x64.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx_x64.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx_x64.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx_x64.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse2_x64.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse2_x64.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse2_x64.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse2_x64.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse2_x64.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,7 +167,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -240,7 +250,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_asm.target.linux-x86.mk b/media/media_asm.target.linux-x86.mk
index ebe269f..63ce5d2 100644
--- a/media/media_asm.target.linux-x86.mk
+++ b/media/media_asm.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_asm_target_assemble":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/yasm', '../third_party/x86inc/x86inc.asm', 'base/simd/convert_rgb_to_yuv_ssse3.inc', 'base/simd/convert_yuv_to_rgb_mmx.inc', 'base/simd/convert_yuva_to_argb_mmx.inc', 'base/simd/linear_scale_yuv_to_rgb_mmx.inc', 'base/simd/media_export.asm', 'base/simd/scale_yuv_to_rgb_mmx.inc'], 'extension': 'asm', 'process_outputs_as_sources': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/media/%(INPUT_ROOT)s.o'], 'rule_name': 'assemble', 'rule_sources': ['base/simd/convert_rgb_to_yuv_ssse3.asm', 'base/simd/convert_yuv_to_rgb_mmx.asm', 'base/simd/convert_yuv_to_rgb_sse.asm', 'base/simd/convert_yuva_to_argb_mmx.asm', 'base/simd/empty_register_state_mmx.asm', 'base/simd/linear_scale_yuv_to_rgb_mmx.asm', 'base/simd/linear_scale_yuv_to_rgb_sse.asm', 'base/simd/scale_yuv_to_rgb_mmx.asm', 'base/simd/scale_yuv_to_rgb_sse.asm'], 'action': ['$(gyp_shared_intermediate_dir)/yasm', '-DCHROMIUM', '-I..', '-felf32', '-m', 'x86', '-DARCH_X86_32', '-DELF', '-o', '$(gyp_shared_intermediate_dir)/media/%(INPUT_ROOT)s.o', '$(RULE_SOURCES)'], 'message': 'Compile assembly $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -136,7 +145,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,7 +228,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_asm.target.linux-x86_64.mk b/media/media_asm.target.linux-x86_64.mk
index aa08ae4..ac60c0f 100644
--- a/media/media_asm.target.linux-x86_64.mk
+++ b/media/media_asm.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_media_asm_target_assemble":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/yasm', '../third_party/x86inc/x86inc.asm', 'base/simd/convert_rgb_to_yuv_ssse3.inc', 'base/simd/convert_yuv_to_rgb_mmx.inc', 'base/simd/convert_yuva_to_argb_mmx.inc', 'base/simd/linear_scale_yuv_to_rgb_mmx.inc', 'base/simd/media_export.asm', 'base/simd/scale_yuv_to_rgb_mmx.inc'], 'extension': 'asm', 'process_outputs_as_sources': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/media/%(INPUT_ROOT)s.o'], 'rule_name': 'assemble', 'rule_sources': ['base/simd/convert_rgb_to_yuv_ssse3.asm', 'base/simd/convert_yuv_to_rgb_mmx.asm', 'base/simd/convert_yuv_to_rgb_sse.asm', 'base/simd/convert_yuva_to_argb_mmx.asm', 'base/simd/empty_register_state_mmx.asm', 'base/simd/linear_scale_yuv_to_rgb_mmx.asm', 'base/simd/linear_scale_yuv_to_rgb_sse.asm', 'base/simd/scale_yuv_to_rgb_mmx.asm', 'base/simd/scale_yuv_to_rgb_sse.asm', 'base/simd/linear_scale_yuv_to_rgb_mmx_x64.asm', 'base/simd/scale_yuv_to_rgb_sse2_x64.asm'], 'action': ['$(gyp_shared_intermediate_dir)/yasm', '-DCHROMIUM', '-I..', '-DPIC', '-felf64', '-m', 'amd64', '-DARCH_X86_64', '-DARCH_X86_64', '-DELF', '-DPIC', '-o', '$(gyp_shared_intermediate_dir)/media/%(INPUT_ROOT)s.o', '$(RULE_SOURCES)'], 'message': 'Compile assembly $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_rgb_to_yuv_ssse3.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/convert_yuva_to_argb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/empty_register_state_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_mmx.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -82,6 +90,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -90,6 +99,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx_x64.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx_x64.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx_x64.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx_x64.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/linear_scale_yuv_to_rgb_mmx_x64.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +108,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse2_x64.o: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse2_x64.o: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse2_x64.o: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse2_x64.o: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/scale_yuv_to_rgb_sse2_x64.o: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -156,7 +167,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -240,7 +250,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_mmx.target.darwin-x86.mk b/media/media_mmx.target.darwin-x86.mk
index 93b0bf6..337698d 100644
--- a/media/media_mmx.target.darwin-x86.mk
+++ b/media/media_mmx.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_mmx.target.darwin-x86_64.mk b/media/media_mmx.target.darwin-x86_64.mk
index c783a3a..ffdaf62 100644
--- a/media/media_mmx.target.darwin-x86_64.mk
+++ b/media/media_mmx.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-mmmx \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mmmx \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_mmx.target.linux-x86.mk b/media/media_mmx.target.linux-x86.mk
index 93b0bf6..337698d 100644
--- a/media/media_mmx.target.linux-x86.mk
+++ b/media/media_mmx.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_mmx.target.linux-x86_64.mk b/media/media_mmx.target.linux-x86_64.mk
index c783a3a..ffdaf62 100644
--- a/media/media_mmx.target.linux-x86_64.mk
+++ b/media/media_mmx.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-mmmx \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mmmx \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_sse.target.darwin-x86.mk b/media/media_sse.target.darwin-x86.mk
index 99bbb88..facedeb 100644
--- a/media/media_sse.target.darwin-x86.mk
+++ b/media/media_sse.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_sse.target.darwin-x86_64.mk b/media/media_sse.target.darwin-x86_64.mk
index e347abe..6c64cd5 100644
--- a/media/media_sse.target.darwin-x86_64.mk
+++ b/media/media_sse.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-msse \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-msse \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_sse.target.linux-x86.mk b/media/media_sse.target.linux-x86.mk
index 99bbb88..facedeb 100644
--- a/media/media_sse.target.linux-x86.mk
+++ b/media/media_sse.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_sse.target.linux-x86_64.mk b/media/media_sse.target.linux-x86_64.mk
index e347abe..6c64cd5 100644
--- a/media/media_sse.target.linux-x86_64.mk
+++ b/media/media_sse.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-msse \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-msse \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_sse2.target.darwin-x86.mk b/media/media_sse2.target.darwin-x86.mk
index 654dda5..8f5b325 100644
--- a/media/media_sse2.target.darwin-x86.mk
+++ b/media/media_sse2.target.darwin-x86.mk
@@ -46,7 +46,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_sse2.target.darwin-x86_64.mk b/media/media_sse2.target.darwin-x86_64.mk
index 69537cd..4d89473 100644
--- a/media/media_sse2.target.darwin-x86_64.mk
+++ b/media/media_sse2.target.darwin-x86_64.mk
@@ -46,7 +46,6 @@
 	-msse2 \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-msse2 \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_sse2.target.linux-x86.mk b/media/media_sse2.target.linux-x86.mk
index 654dda5..8f5b325 100644
--- a/media/media_sse2.target.linux-x86.mk
+++ b/media/media_sse2.target.linux-x86.mk
@@ -46,7 +46,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/media_sse2.target.linux-x86_64.mk b/media/media_sse2.target.linux-x86_64.mk
index 69537cd..4d89473 100644
--- a/media/media_sse2.target.linux-x86_64.mk
+++ b/media/media_sse2.target.linux-x86_64.mk
@@ -46,7 +46,6 @@
 	-msse2 \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-msse2 \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/midi/OWNERS b/media/midi/OWNERS
new file mode 100644
index 0000000..278892b
--- /dev/null
+++ b/media/midi/OWNERS
@@ -0,0 +1,5 @@
+# On Android port and USB support, yhirano@ is the best reviewer.
+# On Win32 port, yukawa@ is the best reviewer.
+toyoshim@chromium.org
+yhirano@chromium.org
+yukawa@chromium.org
diff --git a/media/midi/midi_manager.cc b/media/midi/midi_manager.cc
index 7384703..aba8441 100644
--- a/media/midi/midi_manager.cc
+++ b/media/midi/midi_manager.cc
@@ -5,18 +5,12 @@
 #include "media/midi/midi_manager.h"
 
 #include "base/bind.h"
-#include "base/bind_helpers.h"
 #include "base/debug/trace_event.h"
+#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_loop_proxy.h"
 
 namespace media {
 
-#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(USE_ALSA) && \
-    !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
-MidiManager* MidiManager::Create() {
-  return new MidiManager;
-}
-#endif
-
 MidiManager::MidiManager()
     : initialized_(false),
       result_(MIDI_NOT_SUPPORTED) {
@@ -25,23 +19,68 @@
 MidiManager::~MidiManager() {
 }
 
+#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(USE_ALSA) && \
+    !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+MidiManager* MidiManager::Create() {
+  return new MidiManager;
+}
+#endif
+
 void MidiManager::StartSession(MidiManagerClient* client, int client_id) {
-  // Lazily initialize the MIDI back-end.
-  if (!initialized_) {
-    initialized_ = true;
-    result_ = Initialize();
+  bool session_is_ready;
+  bool session_needs_initialization = false;
+  bool too_many_pending_clients_exist = false;
+
+  {
+    base::AutoLock auto_lock(lock_);
+    session_is_ready = initialized_;
+    if (!session_is_ready) {
+      // Do not accept a new request if the pending client list contains too
+      // many clients.
+      too_many_pending_clients_exist =
+          pending_clients_.size() >= kMaxPendingClientCount;
+
+      if (!too_many_pending_clients_exist) {
+        // Call StartInitialization() only for the first request.
+        session_needs_initialization = pending_clients_.empty();
+        pending_clients_.insert(
+            std::pair<int, MidiManagerClient*>(client_id, client));
+      }
+    }
   }
 
-  if (result_ == MIDI_OK) {
-    base::AutoLock auto_lock(clients_lock_);
-    clients_.insert(client);
+  // Lazily initialize the MIDI back-end.
+  if (!session_is_ready) {
+    if (session_needs_initialization) {
+      TRACE_EVENT0("midi", "MidiManager::StartInitialization");
+      session_thread_runner_ =
+          base::MessageLoop::current()->message_loop_proxy();
+      StartInitialization();
+    }
+    if (too_many_pending_clients_exist) {
+      // Return an error immediately if there are too many requests.
+      client->CompleteStartSession(client_id, MIDI_INITIALIZATION_ERROR);
+      return;
+    }
+    // CompleteInitialization() will be called asynchronously when platform
+    // dependent initialization is finished.
+    return;
   }
-  // TODO(toyoshim): Make Initialize() asynchronous.
-  client->CompleteStartSession(client_id, result_);
+
+  // Platform dependent initialization was already finished for previously
+  // initialized clients.
+  MidiResult result;
+  {
+    base::AutoLock auto_lock(lock_);
+    if (result_ == MIDI_OK)
+      clients_.insert(client);
+    result = result_;
+  }
+  client->CompleteStartSession(client_id, result);
 }
 
 void MidiManager::EndSession(MidiManagerClient* client) {
-  base::AutoLock auto_lock(clients_lock_);
+  base::AutoLock auto_lock(lock_);
   ClientList::iterator i = clients_.find(client);
   if (i != clients_.end())
     clients_.erase(i);
@@ -54,9 +93,19 @@
   NOTREACHED();
 }
 
-MidiResult MidiManager::Initialize() {
-  TRACE_EVENT0("midi", "MidiManager::Initialize");
-  return MIDI_NOT_SUPPORTED;
+void MidiManager::StartInitialization() {
+  CompleteInitialization(MIDI_NOT_SUPPORTED);
+}
+
+void MidiManager::CompleteInitialization(MidiResult result) {
+  DCHECK(session_thread_runner_.get());
+  // It is safe to post a task to the IO thread from here because the IO thread
+  // should have stopped if the MidiManager is going to be destructed.
+  session_thread_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&MidiManager::CompleteInitializationInternal,
+                 base::Unretained(this),
+                 result));
 }
 
 void MidiManager::AddInputPort(const MidiPortInfo& info) {
@@ -72,10 +121,30 @@
     const uint8* data,
     size_t length,
     double timestamp) {
-  base::AutoLock auto_lock(clients_lock_);
+  base::AutoLock auto_lock(lock_);
 
   for (ClientList::iterator i = clients_.begin(); i != clients_.end(); ++i)
     (*i)->ReceiveMidiData(port_index, data, length, timestamp);
 }
 
+void MidiManager::CompleteInitializationInternal(MidiResult result) {
+  TRACE_EVENT0("midi", "MidiManager::CompleteInitialization");
+
+  base::AutoLock auto_lock(lock_);
+  DCHECK(clients_.empty());
+  DCHECK(!pending_clients_.empty());
+  DCHECK(!initialized_);
+  initialized_ = true;
+  result_ = result;
+
+  for (PendingClientMap::iterator it = pending_clients_.begin();
+       it != pending_clients_.end();
+       ++it) {
+    if (result_ == MIDI_OK)
+      clients_.insert(it->second);
+    it->second->CompleteStartSession(it->first, result_);
+  }
+  pending_clients_.clear();
+}
+
 }  // namespace media
diff --git a/media/midi/midi_manager.h b/media/midi/midi_manager.h
index c21c66a..f6c424b 100644
--- a/media/midi/midi_manager.h
+++ b/media/midi/midi_manager.h
@@ -5,16 +5,22 @@
 #ifndef MEDIA_MIDI_MIDI_MANAGER_H_
 #define MEDIA_MIDI_MIDI_MANAGER_H_
 
+#include <map>
 #include <set>
 #include <vector>
 
 #include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
 #include "base/synchronization/lock.h"
 #include "base/time/time.h"
 #include "media/base/media_export.h"
 #include "media/midi/midi_port_info.h"
 #include "media/midi/midi_result.h"
 
+namespace base {
+class SingleThreadTaskRunner;
+}  // namespace base
+
 namespace media {
 
 // A MidiManagerClient registers with the MidiManager to receive MIDI data.
@@ -49,16 +55,22 @@
 // Manages access to all MIDI hardware.
 class MEDIA_EXPORT MidiManager {
  public:
-  static MidiManager* Create();
+  static const size_t kMaxPendingClientCount = 128;
 
   MidiManager();
   virtual ~MidiManager();
 
+  // The constructor and the destructor will be called on the CrBrowserMain
+  // thread.
+  static MidiManager* Create();
+
   // A client calls StartSession() to receive and send MIDI data.
   // If the session is ready to start, the MIDI system is lazily initialized
   // and the client is registered to receive MIDI data.
   // CompleteStartSession() is called with MIDI_OK if the session is started.
   // Otherwise CompleteStartSession() is called with proper MidiResult code.
+  // StartSession() and EndSession() can be called on the Chrome_IOThread.
+  // CompleteStartSession() will be invoked on the same Chrome_IOThread.
   void StartSession(MidiManagerClient* client, int client_id);
 
   // A client calls EndSession() to stop receiving MIDI data.
@@ -81,17 +93,32 @@
   // input_ports() is a list of MIDI ports for receiving MIDI data.
   // Each individual port in this list can be identified by its
   // integer index into this list.
-  const MidiPortInfoList& input_ports() { return input_ports_; }
+  const MidiPortInfoList& input_ports() const { return input_ports_; }
 
   // output_ports() is a list of MIDI ports for sending MIDI data.
   // Each individual port in this list can be identified by its
   // integer index into this list.
-  const MidiPortInfoList& output_ports() { return output_ports_; }
+  const MidiPortInfoList& output_ports() const { return output_ports_; }
 
  protected:
-  // Initializes the MIDI system, returning |true| on success.
-  // The default implementation is for unsupported platforms.
-  virtual MidiResult Initialize();
+  friend class MidiManagerUsb;
+
+  // Initializes the platform dependent MIDI system. MidiManager class has a
+  // default implementation that synchronously calls CompleteInitialization()
+  // with MIDI_NOT_SUPPORTED on the caller thread. A derived class for a
+  // specific platform should override this method correctly.
+  // This method is called on Chrome_IOThread thread inside StartSession().
+  // Platform dependent initialization can be processed synchronously or
+  // asynchronously. When the initialization is completed,
+  // CompleteInitialization() should be called with |result|.
+  // |result| should be MIDI_OK on success, otherwise a proper MidiResult.
+  virtual void StartInitialization();
+
+  // Called from a platform dependent implementation of StartInitialization().
+  // It invokes CompleteInitializationInternal() on the thread that calls
+  // StartSession() and distributes |result| to MIDIManagerClient objects in
+  // |pending_clients_|.
+  void CompleteInitialization(MidiResult result);
 
   void AddInputPort(const MidiPortInfo& info);
   void AddOutputPort(const MidiPortInfo& info);
@@ -112,20 +139,40 @@
                     (time - base::TimeTicks()).InSecondsF());
   }
 
-  bool initialized_;
-  MidiResult result_;
+  size_t clients_size_for_testing() const { return clients_.size(); }
+  size_t pending_clients_size_for_testing() const {
+    return pending_clients_.size();
+  }
+
+ private:
+  void CompleteInitializationInternal(MidiResult result);
 
   // Keeps track of all clients who wish to receive MIDI data.
   typedef std::set<MidiManagerClient*> ClientList;
   ClientList clients_;
 
-  // Protects access to our clients.
-  base::Lock clients_lock_;
+  // Keeps track of all clients who are waiting for CompleteStartSession().
+  typedef std::map<int, MidiManagerClient*> PendingClientMap;
+  PendingClientMap pending_clients_;
+
+  // Keeps a SingleThreadTaskRunner of the thread that calls StartSession in
+  // order to invoke CompleteStartSession() on the thread.
+  scoped_refptr<base::SingleThreadTaskRunner> session_thread_runner_;
+
+  // Keeps true if platform dependent initialization is already completed.
+  bool initialized_;
+
+  // Keeps the platform dependent initialization result if initialization is
+  // completed. Otherwise keeps MIDI_NOT_SUPPORTED.
+  MidiResult result_;
+
+  // Protects access to |clients_|, |pending_clients_|, |initialized_|, and
+  // |result_|.
+  base::Lock lock_;
 
   MidiPortInfoList input_ports_;
   MidiPortInfoList output_ports_;
 
- private:
   DISALLOW_COPY_AND_ASSIGN(MidiManager);
 };
 
diff --git a/media/midi/midi_manager_alsa.cc b/media/midi/midi_manager_alsa.cc
index dd12fc0..c4be32f 100644
--- a/media/midi/midi_manager_alsa.cc
+++ b/media/midi/midi_manager_alsa.cc
@@ -10,7 +10,6 @@
 #include <string>
 
 #include "base/bind.h"
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
@@ -129,11 +128,7 @@
     pipe_fd_[i] = -1;
 }
 
-MidiResult MidiManagerAlsa::Initialize() {
-  // TODO(toyoshim): Make Initialize() asynchronous.
-  // See http://crbug.com/339746.
-  TRACE_EVENT0("midi", "MidiManagerAlsa::Initialize");
-
+void MidiManagerAlsa::StartInitialization() {
   // Enumerate only hardware MIDI devices because software MIDIs running in
   // the browser process is not secure.
   snd_ctl_card_info_t* card;
@@ -190,14 +185,14 @@
 
   if (pipe(pipe_fd_) < 0) {
     VPLOG(1) << "pipe() failed";
-    return MIDI_INITIALIZATION_ERROR;
+    CompleteInitialization(MIDI_INITIALIZATION_ERROR);
+  } else {
+    event_thread_.Start();
+    event_thread_.message_loop()->PostTask(
+        FROM_HERE,
+        base::Bind(&MidiManagerAlsa::EventReset, base::Unretained(this)));
+    CompleteInitialization(MIDI_OK);
   }
-  event_thread_.Start();
-  event_thread_.message_loop()->PostTask(
-      FROM_HERE,
-      base::Bind(&MidiManagerAlsa::EventReset, base::Unretained(this)));
-
-  return MIDI_OK;
 }
 
 MidiManagerAlsa::~MidiManagerAlsa() {
diff --git a/media/midi/midi_manager_alsa.h b/media/midi/midi_manager_alsa.h
index 803496b..04e1d09 100644
--- a/media/midi/midi_manager_alsa.h
+++ b/media/midi/midi_manager_alsa.h
@@ -21,7 +21,7 @@
   virtual ~MidiManagerAlsa();
 
   // MidiManager implementation.
-  virtual MidiResult Initialize() OVERRIDE;
+  virtual void StartInitialization() OVERRIDE;
   virtual void DispatchSendMidiData(MidiManagerClient* client,
                                     uint32 port_index,
                                     const std::vector<uint8>& data,
diff --git a/media/midi/midi_manager_mac.cc b/media/midi/midi_manager_mac.cc
index 0c9c869..c1302e6 100644
--- a/media/midi/midi_manager_mac.cc
+++ b/media/midi/midi_manager_mac.cc
@@ -6,7 +6,7 @@
 
 #include <string>
 
-#include "base/debug/trace_event.h"
+#include "base/bind.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/sys_string_conversions.h"
@@ -36,19 +36,14 @@
       send_thread_("MidiSendThread") {
 }
 
-MidiResult MidiManagerMac::Initialize() {
-  TRACE_EVENT0("midi", "MidiManagerMac::Initialize");
-
+void MidiManagerMac::StartInitialization() {
   // CoreMIDI registration.
   midi_client_ = 0;
-  OSStatus result = MIDIClientCreate(
-      CFSTR("Google Chrome"),
-      NULL,
-      NULL,
-      &midi_client_);
+  OSStatus result =
+      MIDIClientCreate(CFSTR("Chrome"), NULL, NULL, &midi_client_);
 
   if (result != noErr)
-    return MIDI_INITIALIZATION_ERROR;
+    return CompleteInitialization(MIDI_INITIALIZATION_ERROR);
 
   coremidi_input_ = 0;
 
@@ -60,14 +55,14 @@
       this,
       &coremidi_input_);
   if (result != noErr)
-    return MIDI_INITIALIZATION_ERROR;
+    return CompleteInitialization(MIDI_INITIALIZATION_ERROR);
 
   result = MIDIOutputPortCreate(
       midi_client_,
       CFSTR("MIDI Output"),
       &coremidi_output_);
   if (result != noErr)
-    return MIDI_INITIALIZATION_ERROR;
+    return CompleteInitialization(MIDI_INITIALIZATION_ERROR);
 
   uint32 destination_count = MIDIGetNumberOfDestinations();
   destinations_.resize(destination_count);
@@ -98,11 +93,10 @@
     AddInputPort(info);
   }
 
-  // TODO(toyoshim): Fix the memory management here!
   packet_list_ = reinterpret_cast<MIDIPacketList*>(midi_buffer_);
   midi_packet_ = MIDIPacketListInit(packet_list_);
 
-  return MIDI_OK;
+  CompleteInitialization(MIDI_OK);
 }
 
 void MidiManagerMac::DispatchSendMidiData(MidiManagerClient* client,
diff --git a/media/midi/midi_manager_mac.h b/media/midi/midi_manager_mac.h
index 5bd072d..5c514ff 100644
--- a/media/midi/midi_manager_mac.h
+++ b/media/midi/midi_manager_mac.h
@@ -24,7 +24,7 @@
   virtual ~MidiManagerMac();
 
   // MidiManager implementation.
-  virtual MidiResult Initialize() OVERRIDE;
+  virtual void StartInitialization() OVERRIDE;
   virtual void DispatchSendMidiData(MidiManagerClient* client,
                                     uint32 port_index,
                                     const std::vector<uint8>& data,
diff --git a/media/midi/midi_manager_unittest.cc b/media/midi/midi_manager_unittest.cc
new file mode 100644
index 0000000..c5c4138
--- /dev/null
+++ b/media/midi/midi_manager_unittest.cc
@@ -0,0 +1,239 @@
+// 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.
+
+#include "media/midi/midi_manager.h"
+
+#include <vector>
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "base/run_loop.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+namespace {
+
+class FakeMidiManager : public MidiManager {
+ public:
+  FakeMidiManager() : start_initialization_is_called_(false) {}
+  virtual ~FakeMidiManager() {}
+
+  // MidiManager implementation.
+  virtual void StartInitialization() OVERRIDE {
+    start_initialization_is_called_ = true;
+  }
+
+  virtual void DispatchSendMidiData(MidiManagerClient* client,
+                                    uint32 port_index,
+                                    const std::vector<uint8>& data,
+                                    double timestamp) OVERRIDE {}
+
+  // Utility functions for testing.
+  void CallCompleteInitialization(MidiResult result) {
+    CompleteInitialization(result);
+  }
+
+  size_t GetClientCount() const {
+    return clients_size_for_testing();
+  }
+
+  size_t GetPendingClientCount() const {
+    return pending_clients_size_for_testing();
+  }
+
+  bool start_initialization_is_called_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FakeMidiManager);
+};
+
+class FakeMidiManagerClient : public MidiManagerClient {
+ public:
+  explicit FakeMidiManagerClient(int client_id)
+      : client_id_(client_id),
+        result_(MIDI_NOT_SUPPORTED),
+        wait_for_result_(true) {}
+  virtual ~FakeMidiManagerClient() {}
+
+  // MidiManagerClient implementation.
+  virtual void CompleteStartSession(int client_id, MidiResult result) OVERRIDE {
+    EXPECT_TRUE(wait_for_result_);
+    CHECK_EQ(client_id_, client_id);
+    result_ = result;
+    wait_for_result_ = false;
+  }
+
+  virtual void ReceiveMidiData(uint32 port_index, const uint8* data,
+                               size_t size, double timestamp) OVERRIDE {}
+  virtual void AccumulateMidiBytesSent(size_t size) OVERRIDE {}
+
+  int client_id() const { return client_id_; }
+  MidiResult result() const { return result_; }
+
+  MidiResult WaitForResult() {
+    base::RunLoop run_loop;
+    // CompleteStartSession() is called inside the message loop on the same
+    // thread. Protection for |wait_for_result_| is not needed.
+    while (wait_for_result_)
+      run_loop.RunUntilIdle();
+    return result();
+  }
+
+ private:
+  int client_id_;
+  MidiResult result_;
+  bool wait_for_result_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient);
+};
+
+class MidiManagerTest : public ::testing::Test {
+ public:
+  MidiManagerTest()
+      : manager_(new FakeMidiManager),
+        message_loop_(new base::MessageLoop) {}
+  virtual ~MidiManagerTest() {}
+
+ protected:
+  void StartTheFirstSession(FakeMidiManagerClient* client) {
+    EXPECT_FALSE(manager_->start_initialization_is_called_);
+    EXPECT_EQ(0U, manager_->GetClientCount());
+    EXPECT_EQ(0U, manager_->GetPendingClientCount());
+    manager_->StartSession(client, client->client_id());
+    EXPECT_EQ(0U, manager_->GetClientCount());
+    EXPECT_EQ(1U, manager_->GetPendingClientCount());
+    EXPECT_TRUE(manager_->start_initialization_is_called_);
+    EXPECT_EQ(0U, manager_->GetClientCount());
+    EXPECT_EQ(1U, manager_->GetPendingClientCount());
+    EXPECT_TRUE(manager_->start_initialization_is_called_);
+  }
+
+  void StartTheNthSession(FakeMidiManagerClient* client, size_t nth) {
+    EXPECT_EQ(nth != 1, manager_->start_initialization_is_called_);
+    EXPECT_EQ(0U, manager_->GetClientCount());
+    EXPECT_EQ(nth - 1, manager_->GetPendingClientCount());
+
+    // StartInitialization() should not be called for the second and later
+    // sessions.
+    manager_->start_initialization_is_called_ = false;
+    manager_->StartSession(client, client->client_id());
+    EXPECT_EQ(nth == 1, manager_->start_initialization_is_called_);
+    manager_->start_initialization_is_called_ = true;
+  }
+
+  void EndSession(FakeMidiManagerClient* client, size_t before, size_t after) {
+    EXPECT_EQ(before, manager_->GetClientCount());
+    manager_->EndSession(client);
+    EXPECT_EQ(after, manager_->GetClientCount());
+  }
+
+  void CompleteInitialization(MidiResult result) {
+    manager_->CallCompleteInitialization(result);
+  }
+
+  void RunLoopUntilIdle() {
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
+
+ protected:
+  scoped_ptr<FakeMidiManager> manager_;
+
+ private:
+  scoped_ptr<base::MessageLoop> message_loop_;
+
+  DISALLOW_COPY_AND_ASSIGN(MidiManagerTest);
+};
+
+TEST_F(MidiManagerTest, StartAndEndSession) {
+  scoped_ptr<FakeMidiManagerClient> client;
+  client.reset(new FakeMidiManagerClient(0));
+
+  StartTheFirstSession(client.get());
+  CompleteInitialization(MIDI_OK);
+  EXPECT_EQ(MIDI_OK, client->WaitForResult());
+  EndSession(client.get(), 1U, 0U);
+}
+
+TEST_F(MidiManagerTest, StartAndEndSessionWithError) {
+  scoped_ptr<FakeMidiManagerClient> client;
+  client.reset(new FakeMidiManagerClient(1));
+
+  StartTheFirstSession(client.get());
+  CompleteInitialization(MIDI_INITIALIZATION_ERROR);
+  EXPECT_EQ(MIDI_INITIALIZATION_ERROR, client->WaitForResult());
+  EndSession(client.get(), 0U, 0U);
+}
+
+TEST_F(MidiManagerTest, StartMultipleSessions) {
+  scoped_ptr<FakeMidiManagerClient> client1;
+  scoped_ptr<FakeMidiManagerClient> client2;
+  client1.reset(new FakeMidiManagerClient(0));
+  client2.reset(new FakeMidiManagerClient(1));
+
+  StartTheFirstSession(client1.get());
+  StartTheNthSession(client2.get(), 2);
+  CompleteInitialization(MIDI_OK);
+  EXPECT_EQ(MIDI_OK, client1->WaitForResult());
+  EXPECT_EQ(MIDI_OK, client2->WaitForResult());
+  EndSession(client1.get(), 2U, 1U);
+  EndSession(client2.get(), 1U, 0U);
+}
+
+TEST_F(MidiManagerTest, TooManyPendingSessions) {
+  // Push as many client requests for starting session as possible.
+  ScopedVector<FakeMidiManagerClient> many_existing_clients;
+  many_existing_clients.resize(MidiManager::kMaxPendingClientCount);
+  for (size_t i = 0; i < MidiManager::kMaxPendingClientCount; ++i) {
+    many_existing_clients[i] = new FakeMidiManagerClient(i);
+    StartTheNthSession(many_existing_clients[i], i + 1);
+  }
+
+  // Push the last client that should be rejected for too many pending requests.
+  scoped_ptr<FakeMidiManagerClient> additional_client(
+      new FakeMidiManagerClient(MidiManager::kMaxPendingClientCount));
+  manager_->start_initialization_is_called_ = false;
+  manager_->StartSession(additional_client.get(),
+                         additional_client->client_id());
+  EXPECT_FALSE(manager_->start_initialization_is_called_);
+  EXPECT_EQ(MIDI_INITIALIZATION_ERROR, additional_client->result());
+
+  // Other clients still should not receive a result.
+  RunLoopUntilIdle();
+  for (size_t i = 0; i < many_existing_clients.size(); ++i)
+    EXPECT_EQ(MIDI_NOT_SUPPORTED, many_existing_clients[i]->result());
+
+  // The result MIDI_OK should be distributed to other clients.
+  CompleteInitialization(MIDI_OK);
+  for (size_t i = 0; i < many_existing_clients.size(); ++i)
+    EXPECT_EQ(MIDI_OK, many_existing_clients[i]->WaitForResult());
+
+  // Close all successful sessions in FIFO order.
+  size_t sessions = many_existing_clients.size();
+  for (size_t i = 0; i < many_existing_clients.size(); ++i, --sessions)
+    EndSession(many_existing_clients[i], sessions, sessions - 1);
+}
+
+TEST_F(MidiManagerTest, CreateMidiManager) {
+  scoped_ptr<FakeMidiManagerClient> client;
+  client.reset(new FakeMidiManagerClient(0));
+
+  scoped_ptr<MidiManager> manager(MidiManager::Create());
+  manager->StartSession(client.get(), client->client_id());
+
+  // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc.
+  // Do not change the condition for disabling this test.
+#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(USE_ALSA) && \
+    !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+  EXPECT_EQ(MIDI_NOT_SUPPORTED, client->WaitForResult());
+#else
+  EXPECT_EQ(MIDI_OK, client->WaitForResult());
+#endif
+}
+
+}  // namespace
+
+}  // namespace media
diff --git a/media/midi/midi_manager_usb.cc b/media/midi/midi_manager_usb.cc
index 3ac1dda..f2cf866 100644
--- a/media/midi/midi_manager_usb.cc
+++ b/media/midi/midi_manager_usb.cc
@@ -5,7 +5,6 @@
 #include "media/midi/midi_manager_usb.h"
 
 #include "base/callback.h"
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
@@ -17,16 +16,6 @@
 
 namespace media {
 
-namespace {
-
-// Noop callback for (sync) Initialize.
-// TODO(yhirano): This function should go away when
-// MidiManager::Initialize() becomes asynchronous. See http://crbug.com/339746.
-void Noop(bool result) {
-}
-
-}  // namespace
-
 MidiManagerUsb::MidiManagerUsb(scoped_ptr<UsbMidiDevice::Factory> factory)
     : device_factory_(factory.Pass()) {
 }
@@ -34,13 +23,13 @@
 MidiManagerUsb::~MidiManagerUsb() {
 }
 
-MidiResult MidiManagerUsb::Initialize() {
-  TRACE_EVENT0("midi", "MidiManagerUsb::Initialize");
-  Initialize(base::Bind(Noop));
-  return MIDI_OK;
+void MidiManagerUsb::StartInitialization() {
+  Initialize(
+      base::Bind(&MidiManager::CompleteInitialization, base::Unretained(this)));
 }
 
-void MidiManagerUsb::Initialize(base::Callback<void(bool result)> callback) {
+void MidiManagerUsb::Initialize(
+    base::Callback<void(MidiResult result)> callback) {
   initialize_callback_ = callback;
   // This is safe because EnumerateDevices cancels the operation on destruction.
   device_factory_->EnumerateDevices(
@@ -83,7 +72,7 @@
 void MidiManagerUsb::OnEnumerateDevicesDone(bool result,
                                             UsbMidiDevice::Devices* devices) {
   if (!result) {
-    initialize_callback_.Run(false);
+    initialize_callback_.Run(MIDI_INITIALIZATION_ERROR);
     return;
   }
   devices->swap(devices_);
@@ -97,7 +86,7 @@
                                      descriptor.size(),
                                      &jacks);
     if (!parse_result) {
-      initialize_callback_.Run(false);
+      initialize_callback_.Run(MIDI_INITIALIZATION_ERROR);
       return;
     }
     std::vector<UsbMidiJack> input_jacks;
@@ -115,7 +104,7 @@
     }
     input_stream_.reset(new UsbMidiInputStream(input_jacks, this));
   }
-  initialize_callback_.Run(true);
+  initialize_callback_.Run(MIDI_OK);
 }
 
 }  // namespace media
diff --git a/media/midi/midi_manager_usb.h b/media/midi/midi_manager_usb.h
index 59548dd..694a051 100644
--- a/media/midi/midi_manager_usb.h
+++ b/media/midi/midi_manager_usb.h
@@ -32,7 +32,7 @@
   virtual ~MidiManagerUsb();
 
   // MidiManager implementation.
-  virtual MidiResult Initialize() OVERRIDE;
+  virtual void StartInitialization() OVERRIDE;
   virtual void DispatchSendMidiData(MidiManagerClient* client,
                                     uint32 port_index,
                                     const std::vector<uint8>& data,
@@ -61,7 +61,9 @@
   // result.
   // When this factory is destroyed during the operation, the operation
   // will be canceled silently (i.e. |callback| will not be called).
-  void Initialize(base::Callback<void(bool result)> callback);
+  // The function is public just for unit tests. Do not call this function
+  // outside code for testing.
+  void Initialize(base::Callback<void(MidiResult result)> callback);
 
  private:
   void OnEnumerateDevicesDone(bool result, UsbMidiDevice::Devices* devices);
@@ -71,7 +73,7 @@
   ScopedVector<UsbMidiOutputStream> output_streams_;
   scoped_ptr<UsbMidiInputStream> input_stream_;
 
-  base::Callback<void(bool result)> initialize_callback_;
+  base::Callback<void(MidiResult result)> initialize_callback_;
 
   // A map from <endpoint_number, cable_number> to the index of input jacks.
   base::hash_map<std::pair<int, int>, size_t> input_jack_dictionary_;
diff --git a/media/midi/midi_manager_usb_unittest.cc b/media/midi/midi_manager_usb_unittest.cc
index 4acc4c9..88bfd93 100644
--- a/media/midi/midi_manager_usb_unittest.cc
+++ b/media/midi/midi_manager_usb_unittest.cc
@@ -6,6 +6,8 @@
 
 #include <string>
 
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
 #include "media/midi/usb_midi_device.h"
@@ -71,10 +73,15 @@
 
 class FakeMidiManagerClient : public MidiManagerClient {
  public:
-  explicit FakeMidiManagerClient(Logger* logger) : logger_(logger) {}
+  explicit FakeMidiManagerClient(Logger* logger)
+      : complete_start_session_(false),
+        result_(MIDI_NOT_SUPPORTED),
+        logger_(logger) {}
   virtual ~FakeMidiManagerClient() {}
 
   virtual void CompleteStartSession(int client_id, MidiResult result) OVERRIDE {
+    complete_start_session_ = true;
+    result_ = result;
   }
 
   virtual void ReceiveMidiData(uint32 port_index,
@@ -95,6 +102,9 @@
                                        static_cast<unsigned>(size)));
   }
 
+  bool complete_start_session_;
+  MidiResult result_;
+
  private:
   Logger* logger_;
 
@@ -116,14 +126,30 @@
   DISALLOW_COPY_AND_ASSIGN(TestUsbMidiDeviceFactory);
 };
 
+class MidiManagerUsbForTesting : public MidiManagerUsb {
+ public:
+  explicit MidiManagerUsbForTesting(
+      scoped_ptr<UsbMidiDevice::Factory> device_factory)
+      : MidiManagerUsb(device_factory.PassAs<UsbMidiDevice::Factory>()) {}
+  virtual ~MidiManagerUsbForTesting() {}
+
+  void CallCompleteInitialization(MidiResult result) {
+    CompleteInitialization(result);
+    base::RunLoop run_loop;
+    run_loop.RunUntilIdle();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MidiManagerUsbForTesting);
+};
+
 class MidiManagerUsbTest : public ::testing::Test {
  public:
-  MidiManagerUsbTest()
-      : initialize_callback_run_(false), initialize_result_(false) {
+  MidiManagerUsbTest() : message_loop_(new base::MessageLoop) {
     scoped_ptr<TestUsbMidiDeviceFactory> factory(new TestUsbMidiDeviceFactory);
     factory_ = factory.get();
     manager_.reset(
-        new MidiManagerUsb(factory.PassAs<UsbMidiDevice::Factory>()));
+        new MidiManagerUsbForTesting(factory.PassAs<UsbMidiDevice::Factory>()));
   }
   virtual ~MidiManagerUsbTest() {
     std::string leftover_logs = logger_.TakeLog();
@@ -134,24 +160,39 @@
 
  protected:
   void Initialize() {
-    manager_->Initialize(base::Bind(&MidiManagerUsbTest::OnInitializeDone,
-                                    base::Unretained(this)));
+    client_.reset(new FakeMidiManagerClient(&logger_));
+    manager_->StartSession(client_.get(), 0);
   }
 
-  void OnInitializeDone(bool result) {
-    initialize_callback_run_ = true;
-    initialize_result_ = result;
+  void Finalize() {
+    manager_->EndSession(client_.get());
   }
 
-  bool initialize_callback_run_;
-  bool initialize_result_;
+  bool IsInitializationCallbackInvoked() {
+    return client_->complete_start_session_;
+  }
 
-  scoped_ptr<MidiManagerUsb> manager_;
+  MidiResult GetInitializationResult() {
+    return client_->result_;
+  }
+
+  void RunCallbackUntilCallbackInvoked(
+      bool result, UsbMidiDevice::Devices* devices) {
+    factory_->callback_.Run(result, devices);
+    base::RunLoop run_loop;
+    while (!client_->complete_start_session_)
+      run_loop.RunUntilIdle();
+  }
+
+  scoped_ptr<MidiManagerUsbForTesting> manager_;
+  scoped_ptr<FakeMidiManagerClient> client_;
   // Owned by manager_.
   TestUsbMidiDeviceFactory* factory_;
   Logger logger_;
 
  private:
+  scoped_ptr<base::MessageLoop> message_loop_;
+
   DISALLOW_COPY_AND_ASSIGN(MidiManagerUsbTest);
 };
 
@@ -179,10 +220,9 @@
   Initialize();
   ScopedVector<UsbMidiDevice> devices;
   devices.push_back(device.release());
-  EXPECT_FALSE(initialize_callback_run_);
-  factory_->callback_.Run(true, &devices);
-  EXPECT_TRUE(initialize_callback_run_);
-  EXPECT_TRUE(initialize_result_);
+  EXPECT_FALSE(IsInitializationCallbackInvoked());
+  RunCallbackUntilCallbackInvoked(true, &devices);
+  EXPECT_EQ(MIDI_OK, GetInitializationResult());
 
   ASSERT_EQ(1u, manager_->input_ports().size());
   ASSERT_EQ(2u, manager_->output_ports().size());
@@ -201,10 +241,9 @@
 TEST_F(MidiManagerUsbTest, InitializeFail) {
   Initialize();
 
-  EXPECT_FALSE(initialize_callback_run_);
-  factory_->callback_.Run(false, NULL);
-  EXPECT_TRUE(initialize_callback_run_);
-  EXPECT_FALSE(initialize_result_);
+  EXPECT_FALSE(IsInitializationCallbackInvoked());
+  RunCallbackUntilCallbackInvoked(false, NULL);
+  EXPECT_EQ(MIDI_INITIALIZATION_ERROR, GetInitializationResult());
 }
 
 TEST_F(MidiManagerUsbTest, InitializeFailBecauseOfInvalidDescriptor) {
@@ -215,10 +254,9 @@
   Initialize();
   ScopedVector<UsbMidiDevice> devices;
   devices.push_back(device.release());
-  EXPECT_FALSE(initialize_callback_run_);
-  factory_->callback_.Run(true, &devices);
-  EXPECT_TRUE(initialize_callback_run_);
-  EXPECT_FALSE(initialize_result_);
+  EXPECT_FALSE(IsInitializationCallbackInvoked());
+  RunCallbackUntilCallbackInvoked(true, &devices);
+  EXPECT_EQ(MIDI_INITIALIZATION_ERROR, GetInitializationResult());
   EXPECT_EQ("UsbMidiDevice::GetDescriptor\n", logger_.TakeLog());
 }
 
@@ -251,10 +289,9 @@
   Initialize();
   ScopedVector<UsbMidiDevice> devices;
   devices.push_back(device.release());
-  EXPECT_FALSE(initialize_callback_run_);
-  factory_->callback_.Run(true, &devices);
-  ASSERT_TRUE(initialize_callback_run_);
-  ASSERT_TRUE(initialize_result_);
+  EXPECT_FALSE(IsInitializationCallbackInvoked());
+  RunCallbackUntilCallbackInvoked(true, &devices);
+  EXPECT_EQ(MIDI_OK, GetInitializationResult());
   ASSERT_EQ(2u, manager_->output_streams().size());
 
   manager_->DispatchSendMidiData(&client, 1, ToVector(data), 0);
@@ -269,7 +306,6 @@
 
 TEST_F(MidiManagerUsbTest, Receive) {
   scoped_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
-  FakeMidiManagerClient client(&logger_);
   uint8 descriptor[] = {
     0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
     0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
@@ -299,15 +335,13 @@
   ScopedVector<UsbMidiDevice> devices;
   UsbMidiDevice* device_raw = device.get();
   devices.push_back(device.release());
-  EXPECT_FALSE(initialize_callback_run_);
-  factory_->callback_.Run(true, &devices);
-  ASSERT_TRUE(initialize_callback_run_);
-  ASSERT_TRUE(initialize_result_);
+  EXPECT_FALSE(IsInitializationCallbackInvoked());
+  RunCallbackUntilCallbackInvoked(true, &devices);
+  EXPECT_EQ(MIDI_OK, GetInitializationResult());
 
-  manager_->StartSession(&client, 0);
   manager_->ReceiveUsbMidiData(device_raw, 2, data, arraysize(data),
                                base::TimeTicks());
-  manager_->EndSession(&client);
+  Finalize();
 
   EXPECT_EQ("UsbMidiDevice::GetDescriptor\n"
             "MidiManagerClient::ReceiveMidiData port_index = 0 "
diff --git a/media/midi/midi_manager_win.cc b/media/midi/midi_manager_win.cc
index d556e3a..54a1db8 100644
--- a/media/midi/midi_manager_win.cc
+++ b/media/midi/midi_manager_win.cc
@@ -21,7 +21,6 @@
 #include <algorithm>
 #include <string>
 #include "base/bind.h"
-#include "base/debug/trace_event.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -497,8 +496,7 @@
     : send_thread_("MidiSendThread") {
 }
 
-MidiResult MidiManagerWin::Initialize() {
-  TRACE_EVENT0("midi", "MidiManagerWin::Initialize");
+void MidiManagerWin::StartInitialization() {
   const UINT num_in_devices = midiInGetNumDevs();
   in_devices_.reserve(num_in_devices);
   for (UINT device_id = 0; device_id < num_in_devices; ++device_id) {
@@ -518,7 +516,7 @@
         base::WideToUTF8(caps.szPname),
         base::IntToString(static_cast<int>(caps.vDriverVersion)));
     AddInputPort(info);
-    in_device->set_port_index(input_ports_.size() - 1);
+    in_device->set_port_index(input_ports().size() - 1);
     in_devices_.push_back(in_device.Pass());
   }
 
@@ -544,20 +542,18 @@
     out_devices_.push_back(out_port.Pass());
   }
 
-  return MIDI_OK;
+  CompleteInitialization(MIDI_OK);
 }
 
 MidiManagerWin::~MidiManagerWin() {
   // Cleanup order is important. |send_thread_| must be stopped before
   // |out_devices_| is cleared.
-  for (size_t i = 0; i < output_ports_.size(); ++i)
+  for (size_t i = 0; i < output_ports().size(); ++i)
     out_devices_[i]->Quit();
   send_thread_.Stop();
 
   out_devices_.clear();
-  output_ports_.clear();
   in_devices_.clear();
-  input_ports_.clear();
 }
 
 void MidiManagerWin::DispatchSendMidiData(MidiManagerClient* client,
diff --git a/media/midi/midi_manager_win.h b/media/midi/midi_manager_win.h
index 7b38ab4..8a951f8 100644
--- a/media/midi/midi_manager_win.h
+++ b/media/midi/midi_manager_win.h
@@ -20,7 +20,7 @@
   virtual ~MidiManagerWin();
 
   // MidiManager implementation.
-  virtual MidiResult Initialize() OVERRIDE;
+  virtual void StartInitialization() OVERRIDE;
   virtual void DispatchSendMidiData(MidiManagerClient* client,
                                     uint32 port_index,
                                     const std::vector<uint8>& data,
diff --git a/media/midi/midi_result.h b/media/midi/midi_result.h
index 99233c4..1e10401 100644
--- a/media/midi/midi_result.h
+++ b/media/midi/midi_result.h
@@ -12,6 +12,11 @@
   MIDI_OK,
   MIDI_NOT_SUPPORTED,
   MIDI_INITIALIZATION_ERROR,
+
+  // |MIDI_RESULT_LAST| is used in content/common/media/midi_messages.h with
+  // IPC_ENUM_TRAITS_MAX_VALUE macro. Keep the value up to date. Otherwise
+  // a new value can not be passed to the renderer.
+  MIDI_RESULT_LAST = MIDI_INITIALIZATION_ERROR,
 };
 
 }  // namespace media
diff --git a/media/player_android.target.darwin-arm.mk b/media/player_android.target.darwin-arm.mk
index c483151..1d9f9fc 100644
--- a/media/player_android.target.darwin-arm.mk
+++ b/media/player_android.target.darwin-arm.mk
@@ -54,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -151,7 +150,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/media/player_android.target.darwin-x86.mk b/media/player_android.target.darwin-x86.mk
index 9207458..eae7270 100644
--- a/media/player_android.target.darwin-x86.mk
+++ b/media/player_android.target.darwin-x86.mk
@@ -56,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -153,7 +152,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/player_android.target.darwin-x86_64.mk b/media/player_android.target.darwin-x86_64.mk
index 4686fac..a1ff689 100644
--- a/media/player_android.target.darwin-x86_64.mk
+++ b/media/player_android.target.darwin-x86_64.mk
@@ -56,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -153,7 +152,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/player_android.target.linux-arm.mk b/media/player_android.target.linux-arm.mk
index c483151..1d9f9fc 100644
--- a/media/player_android.target.linux-arm.mk
+++ b/media/player_android.target.linux-arm.mk
@@ -54,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -151,7 +150,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/media/player_android.target.linux-x86.mk b/media/player_android.target.linux-x86.mk
index 9207458..eae7270 100644
--- a/media/player_android.target.linux-x86.mk
+++ b/media/player_android.target.linux-x86.mk
@@ -56,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -153,7 +152,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/player_android.target.linux-x86_64.mk b/media/player_android.target.linux-x86_64.mk
index 4686fac..a1ff689 100644
--- a/media/player_android.target.linux-x86_64.mk
+++ b/media/player_android.target.linux-x86_64.mk
@@ -56,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -153,7 +152,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/shared_memory_support.target.darwin-arm.mk b/media/shared_memory_support.target.darwin-arm.mk
index b9585c2..b4a0245 100644
--- a/media/shared_memory_support.target.darwin-arm.mk
+++ b/media/shared_memory_support.target.darwin-arm.mk
@@ -44,7 +44,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -131,7 +130,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/media/shared_memory_support.target.darwin-x86.mk b/media/shared_memory_support.target.darwin-x86.mk
index b27f1eb..4155f3e 100644
--- a/media/shared_memory_support.target.darwin-x86.mk
+++ b/media/shared_memory_support.target.darwin-x86.mk
@@ -46,7 +46,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/shared_memory_support.target.darwin-x86_64.mk b/media/shared_memory_support.target.darwin-x86_64.mk
index 0d67cc0..523ca62 100644
--- a/media/shared_memory_support.target.darwin-x86_64.mk
+++ b/media/shared_memory_support.target.darwin-x86_64.mk
@@ -46,7 +46,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/shared_memory_support.target.linux-arm.mk b/media/shared_memory_support.target.linux-arm.mk
index b9585c2..b4a0245 100644
--- a/media/shared_memory_support.target.linux-arm.mk
+++ b/media/shared_memory_support.target.linux-arm.mk
@@ -44,7 +44,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -131,7 +130,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/media/shared_memory_support.target.linux-x86.mk b/media/shared_memory_support.target.linux-x86.mk
index b27f1eb..4155f3e 100644
--- a/media/shared_memory_support.target.linux-x86.mk
+++ b/media/shared_memory_support.target.linux-x86.mk
@@ -46,7 +46,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/shared_memory_support.target.linux-x86_64.mk b/media/shared_memory_support.target.linux-x86_64.mk
index 0d67cc0..523ca62 100644
--- a/media/shared_memory_support.target.linux-x86_64.mk
+++ b/media/shared_memory_support.target.linux-x86_64.mk
@@ -46,7 +46,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/shared_memory_support_sse.target.darwin-x86.mk b/media/shared_memory_support_sse.target.darwin-x86.mk
index d557031..ba3889e 100644
--- a/media/shared_memory_support_sse.target.darwin-x86.mk
+++ b/media/shared_memory_support_sse.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/shared_memory_support_sse.target.darwin-x86_64.mk b/media/shared_memory_support_sse.target.darwin-x86_64.mk
index 9e1ab52..3904a33 100644
--- a/media/shared_memory_support_sse.target.darwin-x86_64.mk
+++ b/media/shared_memory_support_sse.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-msse \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-msse \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/shared_memory_support_sse.target.linux-x86.mk b/media/shared_memory_support_sse.target.linux-x86.mk
index d557031..ba3889e 100644
--- a/media/shared_memory_support_sse.target.linux-x86.mk
+++ b/media/shared_memory_support_sse.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/shared_memory_support_sse.target.linux-x86_64.mk b/media/shared_memory_support_sse.target.linux-x86_64.mk
index 9e1ab52..3904a33 100644
--- a/media/shared_memory_support_sse.target.linux-x86_64.mk
+++ b/media/shared_memory_support_sse.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-msse \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-msse \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/test/data/bali_640x360_P420_alpha.yuv b/media/test/data/bali_640x360_P420_alpha.yuv
new file mode 100644
index 0000000..ca52ae7
--- /dev/null
+++ b/media/test/data/bali_640x360_P420_alpha.yuv
@@ -0,0 +1 @@
+DEHKLLMNNPPPPQSQSRRRSSRRQSQQPONMLJKJGGFCAA>>:;:;;88888899989::988:9767755544211100..--++)'))(())((((''(((('())))**++,,**++,,,,,,,,++++*)))))))))))((''&&&&&&&&&&&&&&&&&&''&&&&&&&&&&'''''''(()+,,-/0224557778899999999::9999::8876677:>EJQYahlquwxxwuqmjhhghjlnnoooopopoqstwy|~~~~|xrldYNA4.,)++++,*+++.4:BOZenx~ƒ†…ƒ‚}wmgXH;/)%$$#$%%'*.178>CLS^emt{€€|zuoiaYSORQTTQSLD=60'%#$$""#"""!!#!"! #%&(+07=DKPW^cglrwxyxwuvvuuuok_WKFA??@@@@@@????==:99975543100/039<CNV]flqty{|zzvrmd]OE92,+)((''''&((()))+*-01236778=>?CFFJNU\bkptxz{}‚‚‚ƒƒ€€~}{yzvttx{€‚ƒ†ˆ‡‡…ƒ~|zxutty€„†…ƒƒƒ€|xpfXJ=4/.-,038=DNZbksx|€‚€ƒƒ‚‚~}{yvwwzz|„ˆŠ‹‹‹ŠŠŠŠˆ‡‡‡ˆˆˆ†€ypdXOHEA><;FIILLLMNNPPPPQRQTSRRSSRRRRQQPONMLJJHHHEAA@=<;<<:8:::::89999:::98888876665544211100..--++*())(())((((''(((('())))**++,,,,++,,,,,,,,++++*)))))))))))((''&&&&&&&&&&&&&&&&&&''&&&&&&&&&&'''''''(()+,-/01124557888899999999::9999::999878;=DKQY_gosyz|||ztqljkklmooppoomlkjjjkkorwz~€~~~wsk`UH<2+*++++++,,+,17?JVamw}…†…„{tk^P?3*&$$$%&(,/258=AEJRZcjr|€€zundZSOMTbpfVNE=6)#$###""#"""!!#""!!"$&+-4=CJPV\belquyz{zwuvvuuuskaVKEB??@@@@@@????>><:::755431000116<CMU]flqty{|zzwvof^RG;3.+)((''''&'(()))+,..0035689;=ABDGKOX^dkpty}~€‚‚„„††‡‡††„„‚€~}|{wsrrvyz}ƒ„…………ƒ}{yyxy~…††……‚‚{umbRD92/...038=BMXbksx|€‚€€|zwwtssvxz„ˆ‹‹‹‹‹‹‹‰ˆˆˆ‰‰ˆ†xnbWNIFA><;HHIKLLNOOOPPQQQRQSRRRRRRQPPPNMLKJJHGEDA@@>=<;:8:9899899:9999::999988776655332100//..-,,++*(((((((((((((())))))))**,,,,,,,,--,,,,,,,,,,+*++**))))))((''''''''&&&&(''('%'&''&&&&&&''&&''''(((())*,..013345558888999988999999999:99778;>CGOU^bjqv{}}~{xvpnllklmnoommkigeca^adjmrw{€‚‚‚|vqi^QB6.*+***++++++05=EQ_jr{€…ˆ††‚}xncTE6-&$$%&',/148=>BDHLU^eow€„„ƒzsh`VPN]euvo`fys@$!######""""!"""##$$*.39AGMS[`ejpsx{}|xvvuvvvsoj`TMD@????@@????@>==<;::755421/0..28;BMT\hnrux|~}|{vqicVJ>4.+)))((''(((())*+,-01134589=>@AEJMSZ_fkrv{‚ƒƒƒ…†‡‡ˆ†……„†}|zwtrppquvy}ƒƒ………~~{yzz{†‡‡†‚„}yrj\N>51-,,.037<CMW`irx|€€€}{xwtroorux„‰ŠŠŒŒŠŠŠŠŠŠ‰‰‰‡€wk^SNIFA>;:IJJKMLNOOOPPQQQRSRRRQQPPPPOOMLKKIIGFDCA@?><;;:9977999:::998:::999988776643332100......-,+*))(())(((((((())))))))**,,,,,,,,--,,,,,,,,,,+*++***)))))((('''''''&&&&(((('&'''&&&&&&&''&&''''(((()))+-/01223555468899998899999999;:9977::?DJRY^flsx|~}|yvsnljjihhiffefd`^ZXUUX\aeluz€‚‚‚~|vmbWI;4,*,******++.28ANXcoy€†ˆ‡‡ƒ~}tj[M=0)$$$%+.168;?BDCFKOXdmu~ƒ††‚}wncWOWl`ilpkdw^I+!$####""""!"""#"%(.3;@FMRY_cgnquy}|{yvvvwwwuph`TKDB????@@????>===<;::755411./..27;BJT\fnruxwz~}|wslcZN?81+())((''))(())*+-.013334679>>DINSY_aimtx}€ƒ„††‡ˆ‰ˆˆˆ……ƒ€~|yvtqoooppsuxƒƒ„„ƒ~~}{||~†††…„‚€{vofXI;3//0..025:BMU^gpw|€~~~~|{xvtqmllnrv{‡‰Š‹‹ŒŒŠŠŠŠŠŠ‹‹Š…€wj]RKGEB?<;HIJJLLMNOOOOQQRRRQRRQQPPPOPOLJJJHGGECA@?>=<;:9::888889::::::::99888865544322210000//----,+)))(((((((((((()))))))****,,,,,,,,,,,,,,,,,,,+**++*())*())))((''''''''''''''''''''&&''''''''((((((***+--.1112455678888999999::9899998769:;@ELSY`fmsvy{yvwspkhedd__^^^^_]ZWTRONOSX_fpz€„ƒ„„}xql\OB8/+*****+++,-28?IWamw€‡ŠŠˆ‡ƒ{vm_RB4*%%%(.249<@CDEDFINU_iqz‚†‡„€yri]U\ijqYIRiqcRWG! !$##"""#"""""&(-4;?EKSW]bdintyz||{xwwwwxwsoj_TJD???>>??????>>==<:997543211///06:@KS\ekrvwy{}{zzwqg\OB81-+))((''((')(**+,-/0232479:?DHNRY`dgmrv{‚…†ˆˆŠŠ‰‰ˆˆ†…ƒ€~}xvtplkjjkmot{‚‚ƒƒ€~}}}~‚…††„ƒ‚€zslbRC82/..../26;BMWaiqwz~€~}}{wusrmiiimqv|„ŠŠŠŠ‹‹‰‰‰‰‹‹‹ŠŠ…vgZNHGEC@><JJKJLLNNOOPPOOPRRQPPQQPPPOOMLJJJHGEDCA@?>=<;;:::99889:::::::::99888876543322100000////--,+*))((((())(((((())))++**++,,,,,,,,,,--,,,,,,,+++++,*))))))))((''''((((''''''''''''''((''''''(((())**++--.0103333567888999999::9899887778:;@EJPYaiouvvvtqolfc_ZYYXXZZXXYYXUOMJGEHPYcjs{‚ƒƒ€}vmcWI<2.-****+++,,07<FS`ku~…‰Šˆ‡„yrdWG6-))).158:?BDFEFFLNRYdow~ƒ……{tk`\djkeWLQi[ONV\YT&""$$$##$"""$(-4:@EKQW]^bhlqvyz||zzwwwwvutpj`SICA==>>>>>>>>>>=<;:9975432311../38?IR\fmptwz{{}|zvqi_RG:2.)))((('((*)*++,,-./13369;@FKPUZ_dhmqvz}‚„…‡‡ˆŠŠŠŠ‰‡…ƒ€zxvtokhgeegjms{‚‚‚€~~~€ƒ†‡†„ƒ„€}xri^O@71.-../226;CMXaiquz}~~~~~}{zywsmmkgggjnqx„‡ŠŠŠŠŠ‰‰ˆˆŠ‹‹‹ˆ…~uh[NIGDC@?@KKKMMMMOOOPPPPRSQQPPPPOOPOMMKKIIHFEDBA?>==<;;;998899::::::::::9988887655321111111100/.--,,++******))**(())******++,,-------,,,--,,--,,,,--++,,**++))))(((((((((((('''((((('&&&''('''((((((()**++,,,-/01233466799888888::88986655678:>BGNW_gmqoomkhgb^XWTSRUUWWXXVVUPKFB><AGQ]fow……‚€{si^PB60,,*+++*++,-49BO[ht|„‰‹‰‡†‚|tj]O>1++/479<>BCEFFGGILPX`jr{„…ƒ|ulb^`S[NUTEOSJFDcjdZ%!$$$$$$#$&)038?ELQV[^`eimqstwzzzywvvwxxuqk`RJC?<<==>>>>>>==;;<:7786432210./.37>HQ[clqtvxz}~|zxtkaRG=40,)((((())+++,,,-../146:?EIORW\afinsux~‚…‡‡‡‡ˆ‹‹Š‰ˆ…‚}{wspnkihdbcgint{€‚‚€€€~€€‚…ˆˆ†…„ƒ€}wqeYK=61-..-.148=FOX`iqv|}}}|}|}ywwsnkjgfccejqw~„‡ŠŠŠ‰‰‰‰ˆˆ‹‹Œ‹‰ƒ}teZRJHGDB@?JILLMLPNOOPPPPOPQQPPPPOOOMMMKJJHFDCB@?>====<;;::8899::::::::::9988887655321111111100/.--,,++******))**))))******++---------,----..---,,,--++,,++++))))(((((((((((('''((((('&%&''('''((((((()**++,,,-/1112335568888888899888755455669=AEKS^ehhffedb]ZURSRQRRRVVWWVSPMGA=879AJWaks}€‚…‚‚€|voeYG:2.,*+++*+++,17?KXdq|ƒˆŠˆ‡†‚|umbRA4//269=?BDGFGGHHHKPV[emu~‚„‚|xnc`UNG:C@59:>@CKT]S##$%%$$$&&*.5;?GLQXZ]`cfgkoqsuyyzyvuvuvvuph^QHA=<<<<======<<;:98777543220//..28=FRZckqvuw{}}||{tlbWK<41-)(*****)+++,,,.//258=BEKPTY^chmpsv|~‚„‡‡†‡ˆˆŠŠŠ‰†ƒ€}yuqoljgda_`cgjnty}€€€€€€ƒ‚‚…ˆ‰ˆ†…„€}vncWJ<73.//./158>FO[cjpw{}~}||{zxurojgfcb``dipv~„‡ŠŠŠ‰‰‰‰ˆŠˆ‹Œ‹ˆ…~tgYQKHGDBA@KKNNMMOOOOPPPQQQQOPPPPOOLLMLMJHFECBA???=>=<<<<;;;;::::::;;;;::::8877744432221122220000..-,,,**))******(*)))***++**,,,-----..........----,,,+++++++)))))())((((''))((((((((((((((''((((((((()**++,,+,--021122445677887777776655443568:>CJRY_bdb``^\ZWTRPPQSTTUUVVSPMGC;5124;EP\hqy~ƒ‚ƒ€€}wpj^PA6/+****(**++/7<FT`mx€†‡ˆ‡†ƒypeYJ;4369;?DFGGHHIIIHILQV_gqz}umd`TUWD;2CZ/-0AQEML8"%%%%$$'*04;AFLRV[^_bdeijjlqtvxxxssutttrmi_QH@<;:;;;;:;;;;;:98876534222100./19=DNZaiquvxz||||ytlcZM@81-+)))*(+++,,,-///26:>DHNSX^cikosu|}ƒ„„†††ˆ‰‰‰‰‰†„|wtpjhfca^]_cgimou{€~€„ƒ…‡‰Šˆ††ƒƒ€|ulaTF;740/0.026=BHR\dipx|}}~}|{wuqolgd_\\\\aiov}…‰‰Š‰ˆˆ‡‡ˆŠ‹‹Œ‰„|sg\QJIFECA@LLNNMMOOOOPPPQQQRQPPPPOMLLKLJHHFDB@@??>?>=<<<<;;;;::::::;;;;::::8877744432221122110000....,,**********(**))***++**,,,,----............--,,,+++++++***)))))(((())))((((((((((((((''((((((((()**++,,+,--..00112445778877776655443333469=BINUWVWZ[[[ZZVUSSSSTUUWXVUROIC=60--27@KVcmv}‚€ƒ€zsmcVI;2-***+*)*++.29DQ^gt}ƒ‡ˆ‡†ƒ|sk_QC97:=?CEEGGGGIIIIIIINW`jsyvhkpd]][MEBWY(+4<;7=DK'%%%%&(*05:@GLRW\]`bddgeefilpsvvvssutuurmf\PG@<999:;;:;;;;;:9::765342220//./27<DNXbiquvxz||||ysnf[NC82+,,++*)+++,-..0139=CHMQW\`fjnqvz|~€€‚„„†††‡ˆˆˆ‡†„}wskgea`\\\^behknptz~~~}~ƒ††‡‰‰‰ˆ†……‚|ulaTF=864200249>FLU]emsw|}|}|zwurmjeb_[YYXZ`jmv~…ˆ‰Š‰ˆˆ‡‡‡‰Œ‹ŒŒˆ‚|sg]RLJFEC@>MMNNNNOOOOPPPQQQQQQQOONNMMKHIGDBA@@@????>=<;<<<<<<;;;;::::;;::98997765432233221110.011////-,,,,,++******++++****++++,,----//-.//.-....---,-,++++****)((())))(((()))((((((((((((((((((()))))))***,,++,,--///33454556666664455443211257;?EKOUVUY[[\[ZWWUVVVVWWXWVSOKF=71,*+.3;FP]gqxƒ€~{wpi]PA3.**)**))**,29@KWdny€‡ˆ‡†„|tmeWJB?>@CFGGIIJJJJHHFFEGMWcmw|}skei`ed`VA<C:1*2.,0<Ab2%%&&(-06:@FLSXZ^_bcdddbacdjmrtsttssssspme[PD=988889:;:::::998875542221/00/016;EMXaipuvxyz{||yxqh_SD:3.--++,,,,-../139=AFLPV[aejnrvy|‚„…„…‡‡‡‡‡†„€|{sjgb][YZ]_cehkmpsvz|}}}}~ƒ„ˆ†‰ŠŠŠˆ‡…ƒƒ|uk`SF>98541147=DJSYafnuz}~||{{xspjga_ZXSRSV^hmw€†‰Š‰ˆˆ††‡‡‰Š‹‹‰†‚}sh\RMHGDCA@MMNNPPOOOOPPQRQQQQNNMMMMLLJHGEBA@???@@>=>=;<<<<<:9;;;;::::99::98777765432233221110.0111///-,,,++**++****++++****++++,,--..---.//.-....-----,++++++**))))))))(((()))((((((((((((())(((()))))))*****++,,--/0100143556666664444332100146:>DINQUVZ[[\\\YYXXXXWWZXWTRMGA94.*)+-07@KWalu}‚~}ytmdUG:0+*********07=ES`jw~ƒ††…„|woh`TJEBDEGHHIIJJKKHGBBBBEP[gttoiflgegeXJC@G9123,9<EIcK%%(*,18;AGLRVY^_aacde`]\\^dhnqtutsssssojdZLA=;887789988888776665553221/0/..26;DNYbipuvxyz{|||xri_SI<71//----..//137;AFKOU[_ejnruw|~‚‚„…†……††ƒƒ~zumg`[XYZ\_behkloqtw{{}}|~~ƒ†‰‰‰ŠŠˆ‡‡‡‡„‚|uj_RE?:965547;AHPV\cjsx}|||zwsmh`[XURPOOS\fmwˆ‰‰‰ˆ‡††‡‡‰ŠŠˆ‡…{sh^RMHFCB@?MMOOQQQPOOOOPPOOPPONLLKIJIGFDBAB@@????@@===<====<<;;::::::888898776665443333222022022200/..-,,,,,,++**,,+*****++++,,--.........///....-,---,,,++++****))))))))(())))))))(((((((((((((()))')))***+++++,,---.//1231455665542433121./2569>DHLQUX\^^]^][YYYYXWYXYTSOIB=6.+(()*.4;FR^hqy€~}{vph\N@4-*)**)****.6:BP\hq|‚………ƒ}{undZQKFFFHHIIIJJJIGD><;=@JVctihigcfd`^B3LSX<@RSD<:CHXfU<$,08=BEKQW[]dfeee`\\WUVY]djqtvtsstrplibWJ@;6666788887777666654331//10//-/14:CMV_gotwwy{{{{|yslaVJ=740/////./025:@EKQW\`ekmrty{~~~~~€€‚ƒƒ„ƒ„„ƒ„ƒ‚€zvqh_YVVY\_cfikmnoqtw{{{{{}‚„ˆŠ‹ŒŒ‹‰††‡‡ƒ{tj^RIA<;:888;>ELSY`fmtz|~}}|{wtolc]VSOMIHLQZemx‚‡ŠŠ‰ˆ††‡†ˆ‰‰‰ˆ‡„~yqj_TNHECA?>MMOOPPPOOOOOPPOONNNMLKKJIGFDBA@?@@????@@?>=<====<<;;:::::::99:877766654444333223222211000/.-,,--,,++++,,,+****++++,,--.........///....-,---,,,++++*+**))))))))(((())))))(((((((((((((()))')))***++++++,,..-./0101222333322321110./2569?EJNTXZ\__``^\[[[[YXY[XVQLE=6/*))))),07ALXbnu}€€~~}ysmcUI90*)))()****07>IWdnw~ƒ„„ƒ|wqkaXPIGGHHIJJJJKJE@<969;ES^pookie`]YSMIJLS``__XKA8+;Rnn5(7<BFNYY[`liTMVa[[aRPPUZaipuutstrponh`UI?856656776666665544332220///.../04:CMV_gotwywy{{{|ysmcYL@:62111111348=DIPT\`fimruy|~}}}}€€€ƒƒƒ‚‚‚‚|ytld]XWY\^bfikmooprvy|z{{||‚„ˆ‹‹ŒŒ‹‰‡‡‡‡ƒ{tj^PGC?>=;;>@CJQX]ejqv{~~}}}{vrmf`YRMJECCHQ\eq|„ˆ‡ˆ‰ˆ†††‡ˆ‰‰‰†…‚~wsi_TMGDB@@>NNOOOONNOOONPPQPNNLLJJIHGFCA@@@@?>?????>??>===<<<<<<::;;::;;:9887776565233443344332221110//--,..--,,,,,+******++++,,--........00//....,---,,,,,,*,+*))))))))))))))(())(((((((((())(((())**))))*)****+++++,,-/////0111122122110/.01149<@GLRVZ^^_`aa`^]]][YY[ZXSNGB:3+()))))*.3;FS^itz~{wog[N>3*)))******/5<DS`lv|ƒƒƒ€|xuog\RKHHHIKKKKJHEA<82216AP_aniRhdZTRGQQJQYabaa`]U?4<I[rr:6>ILcmhcmwJOKTZ[YWJIKNV`iquwuwtssqkh^SF<643344554444555553221200/.,.././4:CLU^gnswwzxyz{||todZQC;663222327:@FMUY`ekotwz|€€~~}}~€€‚‚‚€€}}{xtphd[YZZ]afilooqrrtvy|}|||{ƒ…‰Š‹‰‡‡††ƒ{rj\PIDBAA?AAFIQV]bhouy}~~}{xtpjc[SLFC?=?DO[gs~„ˆˆˆ‰‡……†‡ˆ‰ˆ‡„‚}yskaUMEBA?>>NNOOOONNOOOOPPONLLKKJJHGDB@@@>>>>>?????>???===<<<<<<::;;::9988887776565565334455332221110///.-....--,,,+++****++++,,--........00//...-,---,,,,,,,,,*))))))))))))))(())(((((((((())(((())**)))))())))++++*+,---.//011111101100//.0126:=CGOTY\^`abcca___\[[ZZZUNKC=5.*'(((((),07AMXdnv}€}~}yslaTE7-*))))****-39BM[fq{€‚„‚€}zupi`WPMJJIKKKJIFA=84/-,1;QirsmM]aWUONPMGBNVb`XUX]T=9BT^qZLO[m~w€jh[Ybmpwtd\P@AJT_ksuwvvtssqkh^SF<6422332222333333432210/-..,--,,-38@HS\hoswxxyyz{{{tni]SG>8765556:?DJOW^diotxz€‚€~}||}}~~}}~zywsqngb\YY]acglmprrrsux{}}zz{|ƒˆŠŽŒ‡‡‡††ƒ{rj\RNHFFFEGIKOW^cflrx|~~~}{{ytmf^XOGA=9:<FR\hw‚†ˆˆˆˆ‡……‡‡‰‰ˆ‡…‚€{vrkaUMEA@>>>OONNOOOOPPOPNMNLKJIHFFFDBB@@??>>==>>??@@>=>>====<<<<;:<<;;;;888777665555555554554432222210000./0.--,,-,,,,,,+***++,,------//0001....-,--..---,,,,,++****))(((((((((())**))(())(())(((())))))))))**++++*))*---....//0111100///0./0137=AFLPVZ^`bdeddabaa_\[ZYYTOF?9/*('('&&''*.5<HR]gqz}€}zvpfYL=3,****))**,16=IWcmw~€‚‚|zvulg^UOKMMMNMJGB>:41+**.9Pq~xe`\GYYUQRNLMHQVYLL\_KGA*FL]TO[nto€smhmlepz‚qj\F=KUalswwxxvtsqng]PD:310011112211100111/0/----,-,+,,028>GR\enrvwwy{{{zzwrk`VH@<96689;BGLS[ahmru}‚ƒƒƒ~|}}|}~}€~}}zzywurpmgb]\]_beinoqrrstvy||}zz{}ƒˆ‹Ž‘Šˆˆˆ††ƒ|rh]TPMKLLKLNRX^beknsx}~|}||ywrle]QH@:777>GSbny‡‰Šˆ‡†††††‰ˆ…„ƒ{wslbVLFA?>:9OONNOOOOOOMNMLKJJIIHFCCA??====>>>>>>??@@>=>>==>>==<<<;<<;;;;988766665555555565554444442211100/0/..--.,-,,,,,+***++,,-----.//0000....----...---,,,,++****))))(((((((())))))(())(())(((())))))))))**((((**)*,,-....//00000////--/01459?CINTZ^`cefffeda``_[ZZZWQLB<3-*('('&&&')-18CMYcmw|~€}||xql_SD6-**(())***.49DR_jr{~€‚€~{yupjaXQMLLLLKGC>:5/+('+/5Ts||{o_VHFVVQU[RKT\[jRIZdeZGBFKOJXf_lmqo€{lgl_[pfgKU@HWdnswwxxxwvsng]PD:20//000000//000000/..-,,,,++*+-.17>GQ[entxxxxyz|zzwqkbXNE?=98<@DHOW^eipty~‚ƒ…‚‚€€|{{z{}|~~~€~|zyxvvutsrpnhc__`adgjnpqrsvvxz}|{zz{}ƒˆ‹ŽŽ‰‡ˆˆˆ†ƒ{sj_XTSPPPQRVZ\bfjoqvz~~}|||yvnh`YND<8447>IVdpz‚‡ˆˆˆ‡…††ˆ‰‰‡„„‚}yxqlbVLE@>=:9ONONOONNMLKMLKJHIHEDCB@?;;<<:<<<==>>>>?@>>>>====??==<<<<<;;::877777766667754576655554443211100100/.-,-----,,,+++++++,,--.//////....---.....-,,-,++********(*((''(((())))(((('((())))))))(((((())))))**)))))*++,,.///0/00..//.../166=AGLRX]`cefgijgfca_[ZZXWVPF=8/*('(('&&&''+.5=IT^iqy|~{||}xpe[J;0+)(())**)+28BLXdow}|{{zvsne[TNLJLJGD@;50)($"'+6Ybtwxo`SLJZ[TUa_STZ\^]ST^ldTJM^NQ`ikurfko[IGTV]RXSQRMKVdntwwwvwwvskh\PC92.----.-..////.....-..,,,,,,*+-/17>GPZenquxxxxy|{{xsng\OGB?<=BHMRWaglrw|€„ƒƒ‚ƒ€}}zzyyyz{{{{|{zwrsssrsrpnifb``deiloqrsuvwz|}|{zz{}€„‰ŒŽŠˆ‰‰‡†ƒ{slb\XXWUUVX[^agloruy|~~}|{{ytnf^SJ@83137@LXgs}„‡‰ˆˆ‡†…†ˆˆˆ‡ƒƒ}|xurkbVLC?<:99ONNNMMMMLKKKJIGFFEECA>>=;;:::;<<==>>>>?@>>>>====>>==<<<<<<;::99977776666777788665555444322211110//..------,,,+++++++,,--.../////...---.....-,,-,++********))(((((((())))((((''(())))))))((((((**))))**)))))*++,,+-/./...--//./.137;BGLRV]_cfgikkjgfca_][[YWRIC;4-(''(&'('&'((,19BNXcmvz|~{||{wrj`PB5,)(())**)*/5<GUcksz~}~}}{{yuph_VQMJIIEA<70*&#" $*;_afkqmeLFU[\VTX[YOXRQZX^`gibR@VNDe~ynf_V^K:8=QVHPSGFGKVdouwxxwyywuli\PC90-++++,---....-----,--,,,,++**,-17>GPZdmquxxxxwzzzwtoh^RJE@CFKPW\ahmtx}„…ƒ‚‚€~~}}zzxxwyzzzzzxwusqqqqrrpokfbbcdfiloqrsvvwz}}|{zz{}…‰Œ‹‰‡‡‡†„‚{slb^ZYXXXZ[]`gkprsx}~~~}|{{ytle[QE;52239BP_jv†ˆ‰ˆˆ‡††‡ˆˆˆ‡ƒ‚{xxvslcVLC?;999OOONMMNLKKJIHGFFDCB@=<<;77998:<<>=>>>>??>>??>>>>==>><<>>=;;;9887777766665678666646555554322102220/.//,-,------++,,++----../0....///.....-/-,--,+****))))**))))**(())))))))(*))(())))))))(((((())))))++++++**+++,----....../000227;?FLQU\`acgjjmmigfca^[[ZWSOG=70+((('&&'&&())*/4<GT^hrx{|{{}|ytmeWH:0))))))*)).28BN\how|}|}||{zxtmbYRLIIFB;63+&#! ##(;MUhfc\Y2@Z[WR]QPZVZUP^[W^`jeW4ONNoordbgXZWM8=GCQWD:6?M[gpvxxyyxxvtni_OB80*++,+++++**+-,,+***)+,,**+)++--07>FPZclqwwxxxxz{{xvpi`VNGFHNRY]dipuzƒ†…„€€€€}}{yvvuttuuwvvvwurqqpqqrsqokhdccdgiloqrsvvxz|}}{zz{~†Œ‘‹‰‰ˆŠˆ‡†}vkda^\[\\_abeinsww{}}}}|{{zwrleYNB94224<FTcnz„‡Š‰ˆ‡†…†‡ˆˆˆ†ƒ€|yxxvtneXMC?;99:OOOMLLKJKKIHGFEEB?>;:::978999;;;;=>>????>>==>>>>==>>====;<;;:9887777666666778966675555543331121100010---------,,--,,----....-...///.......-,,,,+****))(())**))**))))))))))))))(())))))))(((((())))))++++,,**++++++--....../00237;@EKQVZadeikkllijifc`^[YXVPI@91-*)(('&&'&'&&()-27ANWbnuz{|{{}{wqi^N?4+*())))))*05=JXalt{|}~}{{|zuof_UNJFC=72,'#!$""#>`^RV_^\URRUZ\]T`\LKZ_^gSJ[c`\VFWKRg_dcgeeedQ4:HECB=/9CP[hqwxxxxxxvtnj_PA70****)*+**++,***))))))))(()**+,.27=EQ[cjruwxxxxx{{yupjbXQMLRV\`flsw}ƒ„ƒƒ‚€€|zywtrpoprtsrrtvutppopqrrrmjebbcdgiloqrswwxz}|{{zz|}†ŒŽ‹‰‰ˆ‡ˆ‰‡ƒ}vkdb_][^^acfjorvy|}€}{{{{yvpkaUJ=73128>KXds}„‡ŠŠˆ‡†…†‡ˆˆ‡…~zyxwvtneXLD=:89:OOMMMMKIHGGGEDDA>=;:9887678:;;;;;<====>=>>>>>>>><>=====<<<;;::9877776677777777888876545543332211011//..-----,,------------...-./../.----..-,++,+**))(())(&(&)(**))))))))))))))(())(((())(((((((()))***++++++++++++----....00228<AGKQUZ_dfhkmlnnlijda^]ZWWSOE<5.**)((''''''(('',/4=HS^jqwzyz||{yrpdUD8/+)(((((()/3;GT`grx{}}}}|wsk`UOEB>94+)$!!#! /eg[FLd]VSQUURDN_iRBNXTW^VY[[XUUSPBHW]h^fcfk^<2EC=DE71:CQ\hqvxxxxvvvtoi^O@6.)''''())))(*)***)((((%%'()**+--16>ENWbkqtvxxxyz{{xvrnc[VSUX^dhms{~„ƒƒ€~~}ywwurnmllmklmpstrqonoqrrqrliec`befhlnoruwwxz}{{zzy{}‚‡ŒŽ‹‰ˆ‰‰ˆŠˆƒ}vleb_^^_`cfhlotvy|€}}yzzyvtmg^OD;6433:@O]iv€‡‰‹‰ˆ‡†‡‡‡ˆˆ…ƒ{wywvvtogYMC=989>OOMMLKIHGFEECBB?;:998787678:;;;;;<=====>>>>>>>====<<==>>==<<:;:9888877777777778866787655554333331110//..--++,,------------....//../.----..-,++,+**))(())()**)&))))))*)))))))))(())(((())(((((((()))***++++++++++++,,--.../0158<BGLQWZ^cgilmpqpqmkgc`^]ZWTOH@93,)*)((''''''(('')-18BNXenuxz{{zzzvqgZI=/*)(((((((-17?MXdowz}~~}|zuof[PGA:4/)&"!!! !7YghZ`]c_HMWTROQ^lT5@IKGS[^\WOFEEBHKJV`N]``e[QGDTG9((3:CQ\hqvxxvvvvusoi^O@6.)''''''(((())**)(''''%%'()**,//38>EQWbkqtvxwwwy{{{wunia]\]`glpsw}‚ƒƒ„€~}|zyutpokjiihjkmpstrqonoqrrrpkhca`bbdgjlmotwwy{|{zzzy}~ƒˆŒŽ‹‰ˆˆ‰ŠŠˆƒ}vledbaaabehkosvz{}~~}|yzzyvsleYME;6435<DSamy‚ˆ‹Š‰ˆ‡†‡‡‡ˆˆ…‚}ywvvvvtldYMC=89;@NMLKJGIHGFDB@B==:987766667889;::::<<<<<<==>>>>>>==>>==>><<====;;:9999788889999886788766665443333332100..--,,,,,,,,------........///....--.-,,,,++))))))))*/28-')))))**))))))))(((())))(((((((((()))*+*+,,*++,,++++,,,-//00159>DIKQW[_ceikmoppprmhea_\ZXWSLC<5/)('''''''&''&&(''*/5<IUaisx{zz{|{xskaQ@3+((('''''+.6=IUamuy|}}yrj]SE>6/,&# !! !#Ohmhcab`_SPSX\ZdTEC=DLP[`VPV?BEBEFHPQPOZW\_TIOU\O,.49CP\hquvvuuuuvtnh]N@4,('&((%%''&&))(()&%%%%&&&'(*,.1148?FQWaiosvxuuwxyzzyvsmgdcdhlrv{ƒƒ‚€€€}}{zxuuqomkgdcfhjmorttrqmopqrqpmkgeaabbcfiimoquyyzzzzzyy|ƒˆŒŽŠˆ‡‡‰ŠŠ‰…}vkffdccdfjkmouwy{}}}}|z{{zwqkcXMA95237?IVdo{…‹‹‹‰‡‡†‡‰‰ˆ‡…€|xuuuwvtph[OB<7:=EMLKJJHGFECCB@=9966655444666678:::9:<<<<<==>>>>>>>>>>>>>>=<====;;::999888889999998777776665544333332100/---,,--++,,,,,,--........///....----,,,,+)))))))))*6CC4'())))**))))))))))(())((''(((((((())*++++,,*++,,++++,,,-//0258>CGMRV[`dfikmoqqppokfc`][XUTOF?81-*('''''''&''&&''')-28CR\fpuy||{||yuodVF6,((('''''),3;CQ]juy|zum_QF<3-*%"!!! !5Wmy\^ba^YXJKPZb[]YMBHFGKYWPPYC4:KORJHHFJLPPPLN\hVO)-5:DO\grvttuutvurmi]N@4+'&%%%%%&&&&()(('&%%&&&&()*,.03459?FQXajosvxuuwxy{{zxvrmjiiorw|€ƒ„‚‚~}}zxwuspplieaabfhknqrttqpnopqqpomiebaabccefhjnruyxz{{{zyy|ƒˆŽŽŠ‰‰‡ˆ‰‰‡ƒ}vkffddddfilnsuwy{{{zzyyz{yvpjbWI>85348@M\iu‡‹‹‹‰‡‡†‡‰‰‰ˆ„yvtttuvtog\QE<9=CJONLIGFFEDA?=<9666654434665557788::;<<<==>>====>>??>>>>??>>==<<<;::::::::99::::998899757776555555332200..--++++*+++++,,--------../..////.---,,,,+**))))**))2:9-)((((((((())))))(((()'(((((((())((+++,,+,-,,+,,,,,,,,.,..0237<CGMRW\_ehjmnpprrponkgc^[ZWTPJC93,)))''&&''&''''&(''&+/5@MXcntxzz{||{xsj\L<0)'&&'''()-29BNYenw|~€€‚~wqgVH;1-*%$#!!##\c_uQ>TJXdUA=O@LTSPNQ:;HMKHHNJUY\^behhaJBKFDBMNLYfVW+,2:EQ]gqssrrrstusni^OA4,(%%$$$$$$&&&'(('&%%'''()+-./1247;@FOV`hosuwuwxx{}}|yxvsqqrwy~„ƒƒ€€‚€~|{{xwuqpnkgc_acfhjlpsstsqpoooopnmkgca_``_acefhlqtx{{{|zwxy}€„‰ŽŽŠˆˆ‰ŠŠ‰ˆ…|tlgfeeeefjknqrtyz{{zyyyxxxsmg`UG=9767;DR`lx†‹‹‹ˆ‡‡ˆ‰ŠŠ‰ˆƒxussttttqg]QE=>BGNLKJGGFDCB@>;97553333323455667988::9:;;==>>==>>??????@>??>>==<<<<;:;;<;::::::::998876778876666655332210..--++++*+++,,,,--------../..////.---,,,++**))))))))**++)((((((((()))))))(&)()))(((((())))+++,,+,-,,+,----,,,././047:@EIPV[`dgilnqrrropnlhda][YVRLE<6/+*))('&&''&''''+5</&(-2;GT_kty{{{|||{unaQB5+'&&'''()-1:ANYantz~€€€‚zsiZJ;/(%&%$!!"7uYKB<;KOVaT?12;@?EBGJA8FIKEIEN[^`bdeecZ>=ICEB^NCP[\J(+3<EQ]gqssrrrstusmh^O@6,)%%&&$$$$%%%&&&&&%%$%')+,/01346:>CIOXaiosvxxwvxy{}~}{zwwwy}€ƒ„„ƒƒ€~|{zxusoolgb_^_acgjlorssutqpoooopnokeba_^]_``ddglqtwxy{|zwxy~†ŠŽŽŽŒ‹ˆˆˆˆˆŠŠˆ‚{rlgeeeefgghmpqsvxzzyxyyxxvslf_QG=:99:=FTbmyƒŠ‹‹‹ˆˆ‡ˆ‰ŠŠ‰ˆƒxussttttqg]QD>AHLPLLIGFECA@><965432212223344557888999:;;<=>>>>??????@@?????>?>====<:;;<<:::::9::99998677777568774433211/---,,+++,,,,----------.......////.--,,,+***)))((((((+5B<,'''(((((((((((()((((((((((((())++++++,++,,,,,------./..0159>DHNRY_behklopssoommkgb_\YXSOI@81,*))*''('''''''&+4-'''+.7COZhpxz|zz||~yqfWE7,('&'&'(,/49BKUaksz}€„}vl_O;-$$###$#%<kL;453=LLbbaUB='799:BA=GKJLPTX]_`adbc^T<5@CEEjmMICDH105<FR[gqsttssttttmg^PA5-)%%%%$$%%$$%%%%%%&%'))*,.023579:?EKQYahosvxwuuwz}}~~€€‚‚„……„‚‚ƒ‚€}{zwvqnnkeb``abdhjlppruutrrpopppnlmjfb_^]]]\^`bgjpsv{{{{zyvz~‚‡ŠŽŽŽŒŠˆˆˆŠŠŠ‰†{rjfeedcbabfikosvwxwwwxywwtpjd]PD=:88<BJXer|…‹‹ŠŠˆ‰‰‰ŠŠŠŠ†‚|wtsssttsqi_RGCFJPVKIGFGDC?<:9754321101002244444788889:;;<=>>>>??????@@????@@?>====;<<;;;;::::9::99997679887877775432210.---+++++++++,,,,------......./---,--,,++**))))(((())'61**'((((((((((((((()(((((((((()))*+++++++++,,,,,----..////137:AFMSX\`dijmnprqqpnllhd`][XWQKC;5.+)(()))'&''''&&'%$%'('*.5?LVcowz|{zz||ztl\K</('&'&'*+06:AJT`jry}ƒ‚€yqbR@1(#$$$$$'BnY>6;58AQbioqhP=F>46CGFPNMNVY[^`abb`]XTR5EGGBNaMJU]K.16=FR]iqsttssttttlh]OA5-)%%%%$$%%%$%%%%%%%&'*+.002457:<<AEKQYahosuyxwvx{~ƒ„ƒ„„„‡‡†……„ƒƒ€€}|yvsrmlifcaabbcfgkoqrtuutrpooooonlkhd`^]\\ZZ[\acinsv{{}|ywy|€ƒˆ‹ŽŽŽŒŠˆˆˆ‰‰‰ˆ…€|siedda`_^`cfjosuvvuuuuwwwtpkcZNE><;;?FQ^iv€ˆ‹‹Š‰ˆˆˆ‰Š‹‰Š‡€zwtsssttsqiaUKFJPVZKIGEEC@;9865422100////11333356897889;;=>=>????@@@@A@@@AA@@?>=====<<<:;<:;<;:::99:97788888877775533210.--,,++++****,,,,,,----....,./.---,--,,****))))((((**'&(((())((((''''(((((()'((')))******+++++++++,,,----....000036:>DJLT[_aeijmonooonkjjfb^\[XTOG?70+*)))*2/((''''''&&&%$&#(-1;HUamuy||zz|{zun`P?2*'%&()*/39=AIS]fov}‚‚ƒƒ‚{tiZF6,&$##%(([kX<6<BAIYentwtVKHCADLPMGCLTXZ]``cba]XTNF>BACDKZTPLL9117>HR^jrtttusttsrli_QB5-)%'''%%&&%%%%&&%&''(,..01356:<>@CHMR\bhosvxyxxy{~„‡ˆˆˆ‰‰‰ˆ‡……„ƒ„€}|yvtpliidb`aabcefilnqstutrqooooponlieb_][[Z[[]]^bglrvz{|}zwz}†‰‹ŽŽŒ‰‡‡‡ˆˆˆ…‚~vnhdcb_`\\`ehknsuuuuuusuuusoj`YOD?>>?EKVbmvˆŒŠ‰‰‰‡‡‰ŠŠ‹ˆ„yvsrrttvurleVOJMT[_HHFCA?<98655222100////01213356777889;;=>=>????@@@@A@@@AAAA?>>>====<<<;;;<<;:::99999999888877775544320.--,,+++++**+,,,,,,----....,./.--.---,,****))))(((((())''((((''(('''''((((()'((')))******+++++++++,,,--..//..000136:AFLSW\`cgikmnlljjiihhc_\[[VSLC;4-**)))**)((''''''%&&&$&%(+.7CQ]hry|}{{||{vofWD3)'%&(*.26:>CJR\elu{€‚ƒƒ|ypaO>0'###$%)DKF8??=>JZdoswr[TNA>ABMKEPTYZ[^``a_\XTMGB:8MB@GUZZVE,247>JT^jrtttussssrli^PB7/+('''%%&&&&%%&&&'(*++.03457:;>@BEKQT\bhosvxwwvw}€„‡ŠŒ‹‰‡†…„ƒ‚€|{vsokhfb_`bbaceehklpqstutrqoonnomnlieb^\ZYYYXYZ\`glrvz{}{xwz}†‰‹ŽŒŠ‰‡‡‡ˆˆˆ…€zslgdb`^^\\`eiloqttssssstvsrnj`XNGC@?BIO[dpzƒ‰‹Š‰‰‰‰‰Š‹‹‹ˆ„yurrsttuusmd[SOQY`dHEDB@=984553101100..../11123566699::;;==>>????@@AAAA?A@@A@???>==<<======<<;:::::::999977997766555310..-,++++++**++++++---.--+--/--,,--..,,++**))))((('''((((''''''''''''''''''''(((((())**+++,,,,,,,--,----.0300../00047<CINRW[_cgiklkiigggfeca]\[YUQI?80,))))(((((('&''&&&&&&%%&')05?O[epwz{z||||xri[K;-&'))-157;?DKOYbkrz~€‚ƒƒ}uhVE6+&"$#$(@NJ>799<JUbqtwtlNCB97>FFPRW[]^_a`^[WRLF@852TC;GPYX\@0269@KVaksuuttstttrlh_QA60,)('''%''&&&$&&'(*,-.0357:;==BDFHOSX^djosvwyyy{„†Š‘‘ŽŒ‰ˆ‡…‚~}ytqnjhc_^`_aeefghilkoqrtttsqoonmnmlieb^[[YXYXWWY\`flqvy|}{{{z~†ˆ‹ŽŒŠˆ†‡‡‰‰…‚}wqjfc_^^\]^afinprtsssrrstttrog`VNHECCFKU_gr{…‹‹‹Š‰‰‰‰Š‹‰‹‰…~zvtstuuutrke_WVX^diGEC@=9864332200000..../11123566699::;;==>>????@@AAAAABBBA@???>==<<======<<;;::::9999::77887766553210..-,++++++**++++++,,-.---./---------,,++**))))((('''''((''''''''''''''''''''(((((())**,++,,,,,,,--,---../0..../11469?DKPTX[_cghiihffeedca`^^\[XSNE=4.*)))))((((('&''&&&&&&&&&'+.2<IVclwz{zyy{|zuk^N?2*))+/379>@EKOWahpx~‚‚‚ƒƒ~wn_N=/'##$%&BuwD&)3:HTcpvxunK;./27.;VYZ]^`aa][VRLFA93.-7?EQOOL_M955:AJUbluwvuuuututlh_QA60,)(''''''''&'&'(*,-.03579<=?ADFHJQUZ`djosuvxz{€…ˆŒŽ’““’‘‰ˆ‡„€~~yvrliea`]^`_accfghillopqsusqpppnmnmkgea]ZYWVWTSTTY\djqw{||zyyz~†ˆ‹ŽŒŠˆ†‡ˆˆˆ…€zupfc`^]\]]^afjlprsrppooprrrpme]TMJGFFJNXblv€ˆ‹‹Š‰‰‰‰‹Š‹ŠŠˆ„}yvtstuvuusnja[Y\`fkFCA=:86743111./0//.....011344568::99;;==>>????@BAA@@BBAA@@????>>========<<;;;;99:998998877666644111/---,++**+++++++++++++-----,.--------,*)**)*)))((('((((''&&&&''''&&&&&&&&&&&&''(('(**+*++,,,,,,-----.--..--...//0368;@HNSTY\_behecbaabb``__`^^[WRKA:2,*****))((((''''''&&&&&&%%).3:DR`lswzzzyy{ztmcSC4+**-257<?CFJNU]gnv~€ƒ‚ysfVC3'%$##"5id,#'/:CSbntusk`6%%*+7LYZ[_`_a_YUQKE=71/.338HPQOUNRW45:ALYcmuwyxuutwtrok`RB91-***(''''''''()+-/012468;=?ACFIKNSW[aflptvwxz}‡‹’••—–“’Š‡†„€|ytolgd`\\^``acegffgikmnprtusqqoonomkifda]YVUTSTSTUX\dkpux{zxxxz~‚‡‰ŒŒŠˆˆ†ˆ‡†„~ysleb`^]\[]^bejmpqrrnnnorssuqmg_WOMIGINU\fp{‚‡‹Š‰ˆ‰‰‰ŠŠ‰‰‰†‚}xusttvvwwuqld]]_djoCA<:986543111...//.....0111245688899;;==>>???@@BAABBBBAA@@??????========<<;;;;;;:998998877666644111/---,++**+++++++++++++,----.---------,*)**)*)))((('((((''&&&&''''&&&&&&&&&&&&''(('(**+*++,,,,,,-----..../..///001269>DINSW[^^bedb`_][\\]]_```][VOF>6.******)))(((''''''&&&&&&%%(+28BO\iqvy{zxxxzvogXF8/--/38;>@DGJMT\dlv}€‚ƒ}vl]J8+&#"" 3L="&/48DRantwxZ=$21?MUZ[[_`a`]YVQLE?80,-/20.?MQRTMII65:AMZcmuwwwvuwwtspi`RB91-**))(((((())),,-013468:;?ACEJMORW[_cglquvwy{~ƒŠŽ“–—˜—–“’Š‡…}ytnjgc`\[\^``acfffgjklnppsvusqqooolljfd`][WVUSRQPQRS[aiouy|ywxxz~‚‡‰ŒŒŠ‰‰ˆ‰‡†ƒ}vpga_^]\ZZ\_dhjmopppnnnorsttqkf^VPNLKMRXbkt}„ˆ‹‹‰ˆ‰‰‰Š‰ˆ‡‡…}xvtuuvvwwurngaabgmr@=;:8865432200..--..../111225677::::<<==<>??AAAAAAAABB@@@@??????>>>>====<;;;;;99:9988788666655554110-,-,****++++++,,++,,,,,,--,,,,,,,,,,,,))()))((((''&'((((&&&&&&&&%%&&&&&&''''''((()**++++,,,,,,----.///00..////2048;AGKOUW\]_bba^\\[[Z[]]`aa`^YTLD;3,******)))('&''''((''''&&&&'*/5?NXeovxy{zwxwtoi[M>411269>@AEGJMSZbhsz€‚‚ƒƒ„„xreS?0(#$.+10&$&226CQ`mty|iIJ[[YXXY\_`__]YUNJD=70--,.--.^SRONORI47<AOYdnvxwwuuvvwuokbRD:2-**))***'(()*,-.014579:<?BEHILPQSZ\beimpsvy{‚‡Ž“—˜™˜—•”’ŒŠŠ‡„€{unida^\Z[]]__bddefgiklopqttsrqpoonnkifb^[YVUTQPPOOOSYaiovxzzyxyz~†ŠŽ‹‰‰‰‰‰ˆ‡{vmb^^][[[Z]adiknqsqpoomorsttpkd]VQQOOQV]fow†Š‰‰Šˆ‰‰Š‰‡†…„‚€|yvutvvvxxvuqjecehls=::86555432200.---..../111435677999:<<==>???AAAABBAABBA@@@??????>>>>====;;;;;;:::9987888877755435322/.-,****++++++,,++--,,++,,,,,,,,,,++++)))+**((((''&&'''''&&&&&&&%%%%%%%%&&&&''(((*****+,--,,,,----.///00//00/0336:?DIMSVZ\]_aa^\ZZYYXZ]_bbb`]XRI?61,******))*))'((('((''''&&&&'*-3;HT_msxyyxwwwurjaQD7337:<?ACBEHLOV`gpz€€ƒƒ}tkYF5+&&=6&%%!%+/6CQ`mtxzzxrme][Z\^_`_\YTPJD=5.,+,----7uXQNLJS?/6;DQ[cmuwwuvvvvwupj_RD:3.++*)**+*++,,--/024689<>@DGJKNRUW[_cgknstvx{~„‰”™™š—–”“‘ŒŠˆ†}uoid^[YYZZ[^__acdefgiknoqqttrqqpoonnjhfb]XWTSRONNMLNQWahpwzzzzz{{‚‡‹‰‰‰‰‰ˆ…€ztlb^[ZYYZZ]afjjmqpqonnmoqrssold]XSPPSUZaks{‚‰ŠŠŠ‰‰‰‰‰ˆ†…„ƒ€|yvuuuvvwwwvqjhgikos;:876644322000.-....../12233566699:;<<==>>?@BBBBBBBBBB@@???>>>??==>>==<<;:;:::9999888989::99:8997975520+*)**+-+-,,,-..-,,,,)++,+,,,,,,,,+*)**))(((((''&&&&&&&&%%%%%%%%%%%%%%&&&&(((())*****+,,,,,,--...///////001235:>CGKOUXZ[_`_^]ZYYYYZ^accdb`\VPE<6/+******))**))))('((''&&'''''(+09CP]iryzywwvwxvmeWH=679;>ACCDFJMMS^flu|€€€€‚ƒ€zo^M<0'&#"$%$$$*/5AQ^mv{||{vnhc]Z^_`a]YUOID=6-+*+-....<jfPQNT^X87>DP[fouwuvwwvvwuoh`QE:3.-,++,,,,-,+,-.123569;>@DGIKNQTW[^beimnrsvx{„‰‘—šš˜—“‘’‹‡…‚ytmd_ZXWWWYZZ]^_adefgjmopprsssqpoponmhhea[VTRQPNMLIKMOV_hptyxxwxxz„ˆŽŒŒŠŠ‰ˆˆ„€yria]ZXXXYZ]afimproonnonquvtsojc]XTRSUY]gmu~…‰Š‰‰‰‰‰‰‰†„ƒ‚~~|yxuwuvvwwwtroiginqu:9876654321111.-....../12233566699:;<<==>>?@BBBBBBBBBB@@???>>>??==<<===;:;;:::9999889:=>@@??@ABBBA>><83.+***./011121110/...--+,+,,,,,,,,+*))*))(((((''&&&&&&&&%%%%%%%%%%%%%%&&&&(((())*****+,,,,,---...///////001358<BFKORWX\^^^_]ZWVVVVY\accdba\VMC;4-+**++**))**))))('(('''''''''')-4>LXgpuxxwvuvwtqhZPB::;=?ADCEFJJLPZbjrz~€€€€‚‚zqgVC4(&##$25!#)-5AN^luz}{xplf`^_`_]YRNIB:5/,+*+,--..2QbSSSObgB7<FS^gpuwvuvvvvvspi]QE:3..-,,,,,,,+,-./14688:<>ADHJMPSVY\_cdhmqstww{…Š–——•”‘ŽŠ‡†ƒ€|wmg`[WUUVWYZZ\]_adeggkmopprsssrpoponmigc^YURPNMLKKIGIMT]fmsvyxwwz|€„ˆŒŽŽŒŠŠŠˆˆ„xof^ZYVWWXY]ahjmmqponoopquvtsojb\ZXVUW]biqy†Š‰‰‰‰‰‰‰‰†ƒ‚~}}|yxusuvvwwwtrojhioqu98766544321110.-.....//123345677:::;==>>>>@ABBCCCCBBBAA@@@?>??????<===<<:99:::9998889;@DFHHHHIIKJJHIFA:3.,-/145679:::8854110/-+*---,,,,+***)((((((((&&&&&&%%&&%%%%%%$$%%%%%%%%&&((''))*****+,,,,--..-.....//0011368:>EKOTWX[[\^__\[ZXWYX\`cdefc^[TKA92,*+++++++++*))))))))''((((((&&),2:GUbmtvxxuuuxvskbSH=;=?ACDEEFFJMPW]fnw~‚€€€‚ƒ~wm[I7+##!#*-##'.5@O\itz}~{yumfc`_][WQLIB92-+,++,,-//115FWQKNWV<8=GT^hrxwxuwwwwvsnh_PF:42...-,,,,++-/12335::<>@CFILORTV[^acgkprvwxy|€„‰”–•”’Œ‹ˆ„‚|yrkdZTUUTTUVXZZ[^_ceghlmnooqssrqpoqpqmjea[XTQPMKHGEDEFKQZflswxxywy|€ƒ‡‹ŒŽŒ‹ŠŠŠ‰ˆ„~wnf\XWWVWX[^bgjlmqromnnoprtsrojb\YYWW[`flt|‚‡‰‰Šˆ‰ˆˆ‰‡ƒ€~}|{||yvsuwvvwxwvromklpsw8766553332110..-.....//1234556779:;<==>>??@ABBCCCCBBBA@@@@?>>>========<;:;;::999879:=AFJMOOOPRSSRRSROIC931258;>@ADDDECB?<:9730/,--,,,,,+*****)))((((&&&&&&%%&&%%%%%%$$%%%%%%%%&&''''))*****+,,,,--....../////01357<@EKOSV[\\]_^]`^\[ZZZ]`acdedc]YPG>70+++++++++++*)))))))))'((((((&&'+07BP\iquwxvttvvsmgYNB=?@BDDEFGFHKOSYahr{€€€€‚ƒƒ€{scP?0'$"!#""#'-2@MZitx~~{yungb_][WRMFA:2-+***+,-/00242LWKII[N68@JU`jtxxwwwwwwwtoj^OE<50....-,,,..-/12335:;=>ADHJMPRVX[^beimquvx{|}„‰Ž““‘‹ˆ†‚€|wtng`WSURSSRTVYZ[^_adgjlmooprssrqpopomkgb_YUQOMKHFDCAACHOYclrwxwwx{}„ˆ‹ŒŒ‹ŠŠŠŠ‰ˆ„~wnf]YYXVWY\_bhknpoopnoorstutspib\YYY[]cipw…ˆ‰ˆ‰ˆˆ‰‰ˆ…€~|{x{}}ywuvwvwwxxwtqmkknsw6666553332110/-,..////0234676778:::<<<==>??@CCCCCCBBB@@>>??>==========<<;:::9989::;=@EINRVWWXY[[ZZZ\YTKC<:;>ACIKMPSTRONJJIE@=81/-,-+++*,**))*))(('''''&&&%%%%%%%$$$$$$$$%%%%%%%%''''()**++++-----..//////1/112248<?DIPRVZ[]^abcc`_^\\\]`baadeca]VMD;4.++**+++++,++****)+))((''''''&&()/5?LXforuuuutvwtpk_SHA@BCEFFFGGGIMMR[dmv}‚„ƒ‚}tiXE5($"$#$##&,4@MZhsz}||yulec^\WQLFA:2-****++,-.//..3YTPIJMV=:AKV_lwyyxuuvxxvsnh]OD=62//....-,..-/023568:<?AFIJMQSVX\_dfjnrvx{|}~…ŠŽ‘‘Š†…ƒ}xrnhaZWSQPORRRSYZ[\_achjlnppsssrrooopolgda\WRONKJGCA><<?ELV_ipx{ywwy‚…‰‹ŒŠ‰‰ŠŠ‰‰‡ƒ€yne]XXXWXZ^`chkmnppppopqruutrnib]ZXZ^bgmv|‚†‰Šˆˆˆ†ˆˆ‡‚~|zxxx||zwvuuwxyyywtqmkmqtv65666543321100.-0011113534677789:::;<<==>??@BBBBAAAAAA@?==?>========<<;;:::99979::<=AGKPSXZZ[\^^___a_\UMECDIMPVX[^_`b__]YVRNGB=62/.-,,,+++))*))(''''''''&%%%%%%%$$$$$$$$%%%%%%%%'''''(**++++----./////0/00011258=ADINRW[]^abdgffdb_^^^_accddec_\RJA91+++**+++++,++********((''''''(((),2;FS`kruwuuuuwvqngYNGCBDFGFGFFFHIILT^hqy~‚‚ƒ‚€xo`M<.'#%#$$$(/9AN\grwz{{xtle_\UQKC?82,*****+,,-.//..2LdXJLLX=9AKWbmvyyxwuvxxvsmg]OC<622/110/.,../1023568:<@CFIKNRSVY]_dfkoquy|€ƒƒˆ‹ŽŠ‰‡†‚|xtpic]WSQOOOPPRUVY[\^`chjlnppqrrqqqqqpomie_ZTNMKIFC@?;::<AJU_hovwwuwy~ƒ…‰ŠŒ‹Šˆˆ‡‡ˆˆ‡ƒxqg`ZZZY\[_cfhkooppoooqrsurtrmhb][Z[^djqx„‡‰Šˆˆˆˆ‰ˆ‡‚~zxttx{{xyvwwyyyyxwtqmknpru774455433211110..122113457777899::;;==??@>@AB@CCDDBBA@?>>=>>====>>>=;;:::99987889:;=BGKORVZZ[\]^adbab`]WPNOSX\_acejjhgffc_]XVQIA<52-++-++***)(((''''&&''&%%%$$$$####$$$$$$%%%%%%%&''''))++,,--../////000/001269=BFJNTVZ]]acehjkieec`__`acefdca[WMD>7/+,,++,,,,++,,++****++)())((((((&'*/7DQ]iruuuustxwtpk_TJCDDGEGFGGFDFEFMWcnx~‚‚‚‚‚‚ƒƒ{sdSA1'$$%&&',58DNZgrvwyyurme]WQJE?80+)))++*+--..//001CfVRNPV8=CMXcnuxzxxwwxxvtmg]PD<62322222/-./02213579:=@CGJMORUXY^acglprvz~€„ƒ…‰ŒŒŠˆ‡„‚|xtpkc\WSPOOONPQSTVW[^_cdegmooopqrqqqqrpomhc^YSNKHCB@=;977:@KT_ipuwwuwz}ƒ†‰ŠŒ‹Šˆ‡†‡‡††ƒzrid]ZXZ]\_aehlooqqqqprsuutsplgb\\\^_fmszˆ‰Š‰ˆˆ‰ŠŠ‰‡}yvstx|zxyxwyxxzzxwurmkmqtu775433432111110//022333568997788::;;:<???@@AAAAABBBA@A>=>===<<<<===<;;::9998778779<>@DILORUXWX[\_bbdfdc`[WZ^^ceggikkmikkigec_YUOH@92-,,**)**)(((''''&&%%%%%%$$$$##$$$$$$$$%%%%%%%&''''))++,,--..//////0011248;?DHLPTV^_bdeijkmllifeca`bbddedd^YSJA92.+,,++,,,,++,,++****+++)))(((((('&)-4@MYdnsvuutuwxwsofYOHDDFFFFGFDA?>BFP]jt|‚ƒ‚‚‚‚ƒƒ|vjZF6+%%&&).17>FN[grvwxxurmcXRKD>80))*))+++,--..//000?baQLOLE<BNYeovyzxxwwxxvtmg]PD<843222221-.//0213579:=@CGJMPSVXZ^acglprv{‚†…ˆŠŒŒ‹ˆ†…‚|ytqkc^WSQPOOPRSUUWYZ[^abdhjmooopqtsqqqrpolic\WPLFC@=<986568>JU`ipuwwuxy€„†‰‹‹Šˆˆ‡…†‡††ƒ€ypfb^\\\]^_bfinpqrrqrrtuvvvtqkea]\]_bhow~„‰ŠŠ‰ˆˆ‰ŠŠ‰‡€|xsqvy{zzxwwvxxxxxwurommnqs6654443210121121113334446577899:99::<;=???@A@AAA@@>@@@?>=<=>==<<==<<;:9999887666569;?BFJMPSUUTSTX]aceegec``bcfegiiiillkliigdcb`[ULE=5.,**)**)(((&&''&%%%%%%%$$######$$###$%%%%%%$%''''()*+,,--..///////01567<@EIMSWY\_dhjmnpprqojihdcabccbca`[TMC<5/.,,,,+,,,,,-,,++++++++****(())((((*-2<HUdmsvvvvvvyywti_SIEDEGGFEEB>;;<@LXdrz‚ƒƒ‚‚‚‚‚€wp_L;.&&')-05;@IP\gqvwwwspk_UMF?5.+())**++,,,-..//1114NeRKOU^M?Q[gqwzzxxwwwwusmh\OE=854332220//////12479;>ACHKLNSUWZ^bcgmqtx~‚ƒ†‡‰Š‹‹Š‰†„ƒ}ytqkf_XTROOORRUXXZZ]^_bcegjkmnopqrtssrrspnnid]VQKDA>;:762248?JV`kqvyxvx{„‡Š‹‹ˆ‡‡†…†‡‰‡„xogb`^]_``cehjnqrrrssuvuxvvsric^]\^bflsy€‡‰‹‹ŠŠ‰ŠŠ‹Š†{vtrtx||xxxwwxxyyxwtqmkmort6654443210122221114455556577989:::;;<=>????@A@AA@@A@??>>=<<=<<==<<;;::99989966654589<?BFHKJJIJJIOTX]_ehhhedegfeedddceefggfgihhheb[SLA60*))**))(('&''&%%%%%%%$$###########$%%%%%%%&''''()*+,,--..///////0469;AGLQRXZ`dgimoqsswuromjfecacdcbb`[UOF<51/.,,,,,,,,,,-,,++,,,,++++**(())((((),19DR_jqvutttvyzzumbXMGFFGGFEC?;878<FTbmv‚„ƒ‚‚‚‚zseTB2)')+049?EMT]hqwxwwroi\PH@8/+))))**++,,,-..//1122=ghRPIZaJM[hsxzyxwwwwwusmh\OE=85434322000000004679;>ACHKMORTXY]^cglptx~‚…ˆˆŠ‹Œ‰‰ˆ…ƒ‚€}ytpjd]XVTUSUXXZ\]_``bcdhiikmoopqpqsrsrrsrpomf`ZTMC=:97531028@KWakrvwxvx{„‡Š‹‹‰ˆ‡†‡ˆ‡ˆˆ…xogb``___adfiloqrssttvvwxvvrpic^\[^bgow}„ˆ‹Œ‹ŠŠ‰ŠŠŠ‰„|xsppsy{{yxxyyxxyyxwtqomnprt55554442232233333455556666679;;;;;<<<>>>????AB@@@@@?>>====>=;;;;::::::998877555544557:9<>=>>:99;CIQW_dhihgfeeba\WTTX\\]]]`adfhjkmj`VLA4-*)**(()('&&&&&%%%%%%$$$$#"####"$##$%&&&&&'''((***+,.----//0001247<?DKPTVY_bgjmoqrvuyxwtqmieddddccb_YVQFA92,,,,,,----,,..----..-,----+**())))))),27?N]iqtuutuvwyywpg\QIGGHEGEC=74449AO_ky€„…ƒ€ƒ„ƒ~wkZH9.*-04:>CJQX_hqxxyvqoh\OD90*)))))****+,--...//103;RdTTGNNRQZgtz|zzyvvvvtqng\OF>:7665553110000013567:=ACGJMORSVXY`bhjnsx}„†Š‹‰Š‰ˆ„ƒ‚|yvphc\XVWWVY[]abceegjklnnpqrssqqrssrrrqtrrqnje_XQJB<65532027@KValsvwwvz}…ˆ‹‹‹Š‰ˆˆˆ‰ŠŠ†…€yohdb`_^_bgfjnrqssstuxxxzwurlfa]]]`ejry…‰‹Œ‹ŠŠ‹ŠŒŠˆ‚|wqmpuy{{xwvvvxxwwyxutpoprsu55554444334344445555556666679;;;;<<<=?>>????@A@@@@?=====<;<<::;;::::::998776655433331456653300029@HQY]begefb_YTOHFFFHKLPQTY\afkmpnleYL>1,+++*))(('&&&&%%%%%%$$"""#####"$$$$%&&&&&''(((***+,.----//001249<AFKPUY\cginnrtvxz{|{wtrmjgfdccb`^YVOH@82-,,,,,,------..----....--...,+*))))))),/5>KYensuutuvwyyxtj_UMHFGFEC@:51024=JZgv~„†„€€‚‚€yqaN>30139>BHNSZ_hqvxyxsnh\L>4-()*)))**+++,--...//014=TNQOKQLBM]jv||{yxvvvvtqnh_RF>:7665533111100002467:=@BEHJMPSUY[^`eilrx~‚‡Š‹‹Š‡‡…ƒ‚€~{wtpjd^]XZ[[]`bdeiillnpqqrrvvvvttstsrrrtuttusokf^XPF@;8653238@KValsvwvx{~‚†ˆ‹‹‹Š‰ˆˆˆ‰ŠŠ‡„xohec`__`cefjnrsuttuvwyyywuqle^]]^`fnv|‚ˆ‹ŒŒŠ‹ŠŠ‹‹‰‡|wplosy{{xxwvvxxwwxxutqpoqsu66554444444455555555665566899:::;;;=====??????????>><;<<=;=;;;::::::99887654543211/..0110--.,+,.58AJQY\]aaa\UMC:556878:;AFKQYcjlrvtmcUJ:1-.,+*))'&&&&&&&%%%$$$##""########$%%%&&'''(((**+,,----./001348?BHNQY]acfjmrsvwz||yzzvrnljeddbba]YRMIA:3-+,,,,------........//./012210--*)))))),/3;IWcmrutttvvx{wuoeWMIGFEC@=72-,.28EUbq|‚…ƒ€€‚‚{vjYH:778>BGKOSZbjqw{yxtnh]M>3,))))****,,*,....0/0023ORY\RPRTKA[kuz|zywvwwvurmg^QF>97665432221100111345:=>ADGILPSUWY^_cfjqw~ƒ‡‰‹‹Šˆ…„‚€€}{xtojea__]^abdehijknprtuvwvxxwvvvttrrrstuvvwutrmi`\SHA:743126@LWbltxwvxz‚†ŠŒ‹‰ˆˆˆ‰ŠŠŠˆƒ~woib`_^`bdghlprttuuwyzzyzwtnic^]]_chqx„ˆŒŒŒŠŒ‹‹Œ‹‰…yrmkotxzzwvuvvxxxvxyvurpqutt6655444444445555555566668899::::;;;===>>??????>>>>==<;;;<<<;::::::::99886644442211/.....,,+,++,.04:DINRVYYXRI>40..-,+,.027?GPZcjquwskaUH<751/+)(&&&&&&&&%%%$$$##""########$%%%%&'''(()**+,----.//02358=DKNS[^cfhlnotwxz|{}yxwsplihecb`]ZXRKF?92-++,,,,------..//....///0124443.-,+**))),-2:FSaksutttuuwyzxoe]QKGFDB>:50,**06AR_my……‚€€€‚„‚~woaSC<;>BGKNSW\djqw{zyvqj^O?3,*())****,,,-,,...01123?bocRJKHPSaluz|zywvwwvurnh^QF>976654322211001113457:=>CEGKMPSWW[\_djpxƒˆ‰ŠŠˆ†„‚€~}zxtoieaa_`aacdfiikmmnqtwvxxzzyxxxutrrrsuvyyzzyvsphbZQJA;86538@LYdntwyxz{€ƒ‡‹ŽŽŒŠ‰Š‰ŠŠŠ‰ˆƒ~wngbba`_adgimqtttuuwy{{yxvrmfa^]]`cjt|†‹ŒŒ‹ŠŒŒŒ‹‰…zqllotxzzwvuvwxxxvxyxurprvvu65554444555555555555557788:::;;;<<==><=???>>>>>>>===;;;;::;::9::9:;988976554321100//..-,++++++**+/5;AGLLONJC93-*))******+.4<FOZcmrwusj`RMD=:53-*(&&&&''&&%$#$$#"#"#####$$$$$$$%%&&''()))+,--..///0258<AJPT[_cgjmprsuwwz||yxwqonkgd`b^[XSOKD=61.-,,,,----.-..//./....//022446540/--,,*))*,09BP\gpttttttvxzyqi_VLGFC@<83.+().5?LZiv……ƒ€€‚ƒ„‚}tk[LCACGJNQSV\cirw{zzwqi^PA4.******++,,....//..0022MnaAKHJAMU`mv||{xvvwwvvtoh^QG?:855554411220011133556;>AEEHJMPTVW\]bhow}ƒ†ˆ‰ˆ…ƒ‚€~~}{yvrmhdbbcbacddfghklnoqsvxxyz{}yyxusrrrsuw{~||z}|xqkcZRIA:6448AMXdosvzyy~…ˆŽŽŒ‹Š‹‹‹‹‹Šˆ…wmfb^]\]_cfinrstuuuvxyyzwtpld_]^^cgow|…ŠŒŒŠŠŒŒŒ‰„wpkipuwyywwwwxwwxvxzywsopruu65554433555555444466668889:::;;;<<<<>=>???>>=====<<<::::<8::;999899988765544220/....--,+******))**-4:=@CA@:4,+*)****))))),.2;GP[eluvtqiaZROJE@:3,(''*++*(&%$$$#""######$$$$$$$%%&&''())*+,--./000148;BGMTZ`deknqqtwwxy{yvtspmkhhdb_]XURMGB;51---,,,,----....///.0000//1135456520.-,,,**,-18BMZensuttttvxywrj_VLGEB>951-)(),3:FVdr}„ƒ€€„„{qbUMHIKMOQSX\cgptvwwwsmbSE>;,*++**++--...../..0246VcJBJGKIHW`mv||{zwwxxwvtoh_RH@:8555544442201111333568;>ADFIKNQSUX\bhpw}ƒˆˆˆ†…‚€~}{|ytplgcbcccc`cdefhijmopqrtwy{||zzxusrrrsvy{~}~€|yrkdZRH?7248AMZfovxyy{…ˆŽŽŒ‹Š‹‹‹‹‹Šˆ…wngb^\[]_bejorsvvuvxz|{xwsnha^\\^bhpw€†‹Œ‹Š‹Œ‹ŠŒ‰ƒ~tljjotwyywwwvwvvwxz{ywtstuvw556677555556766677777788:::::;;;==<===>>>>==<<<<<<;;;;;;99<;::888777655555223///.,----++))))*)(()(),1569840,*(((****))))))+-39EP[equvurlgb^YQMF>80,-23322-'%$$##########$$%%%%%''&(())*+,---.//0147:?FMSZ^dgjlnpqrvwwwusromkifb_\[XTRNHD?730----,,----../-.0/../111122224467641/----++++.15>JUdlrttsssvwxwslaWLFBA<83/,)''*28CRaoz€ƒ‚‚€€„…‚}wl_UONONQRUX[`fjrwwwwtmbTINJ-)))**++---...////016QlG7<9?IIJVamw{|{yxwyxwvuqlaRG@<96655433333111133443689<>AEGJMNPRT[`hqy~ƒ‡ˆˆ‡†„€}|zyvrnieba`aaaaab`abdegghjnrsuxzzzxvtrrrrtvwy{z~‚„„‚~{qkbZQE<549DP[fpwyyyz~‚†‰ŒŒ‹ŠŠŒŒ‹ŠŠ‡ypje\[ZZ\`djnsuuvvxyz{{xvqkd_[YYZ`hs{‚ˆŒŽ‹‹‹Œ‹‹ŒŒ‰ƒ}skhjnsxyxwwuuvwxvx{{zwstuuvx666677556666766677777788:::::;<<==<===>>>>==<<<<;;:::::::999998887776555543210/..,,,,,++*)))))(())(*,-00-*))(())))))(())))*+-28CP\ipuwutpllfa[TKE?:;?@A??71,%$##########$$%%%%%'''((***+,-...//037:>CJPW^cfklmopstttsrpnkifda]\ZXSPMID@;62/.----,,----.../0////011112222335652//..--,,,,-03;GS`jrtsrsstvwwslbXNF@?950,,)'').6?L[iu}‚‚‚€~ƒ„ƒ€}sg]UOOPUUWZ\^cglrvvvsk_RPGB/*****++----../////25a†]98IQOOKUclx}~}yxxxxzxuqlbTG@<966554333332246887755679<>ADFHJLNPX^gov~ƒ‡ˆˆ…„‚€~~}{ywvsmgda`^]^]\Z[Z[Z\]`cbdfimquvwwtsqqrrrtvvxzx|~ƒ„‚~zrjaYOE<9;FQ]hqxzzz}€„‡ŠŒŒ‹ŠŠŒŒ‹Šˆ…‚ztlf^XWY[bhmrtttuvxyz{yutnh`[ZYX[bkt|ƒˆŒŒ‹ŠŠŠ‰‹Œ‹ˆ‚{rliknsyyxwvwvutuvx{{zwtsuvuw77757755776676558867889989::9<==;>>?<<====<<==;;:999999999988898965555332322/..,-,,++*****))(('(('&'(())''(('())('))((((((((*.4=GS^hrwyvuuspnhb]VQNOPQSSOHA7,%#!""$$###$%%%%&&'''''()*,,,-..011258=BIOV\afikmoprutrqniiffc]ZYVTPLJGEB>820...-------------.001111334422211344220000.-,.---/39EP_gqtssrstvvusndYNEA=84.++)'').3:GWgpz‚ƒƒ€}~ƒ„ƒzoe\VTSUVXZY[\ciosvutmaXS7>7+,,++,,+,--../000136UwgIJITTQOYdpx}}|yyxzyzyyslcUG@<96644432213469=<=<<;86579<=@CDFIJPU]gryƒ‡‡‡…ƒ€~}{zxvvpleb^\YYUVUTSSSSRTTUXZ]afknnqqqrrrrrrrsssuxxz}‚„‚€xribVKB>?JS_jqy{{z~€…‰ŒŽŒ‹‹‹ŒŒŒŒŒˆƒ}wpg`]Y\^cjpsuttuwxz{zwsqjd]YWWW\dmw~†‹ŒŒ‹‹ŠŠŠ‹‹Œ‹ˆ‚{pkikmsyyxwuuvvwwvw{{{vtsvutt776777667777666677778899:9;;:;;;:;;<>>====<<;;;;999999998888888877664422120/..-+,,+++**)**))(('(('&'(('''''''())('))((((''(((+.6=HR]hrvyxxwutqnhfa`acdffd[SH:+$$""#####$%%%%&&''''())*,,,-./11147:AFMSY`dgjlnpqssolhfc`\\YURNKHEEA><750/.-..------------.0111121334443322452221110/-....-/28CP\gorssrrrtttrmdYNE@<72.+)('''+17AQ`lw€ƒƒ€}~ƒ„…ƒ~uh`YWVWWWWUWX^fmtuurhZXL7@:,,,++,,+,,-../00022>X_\TWC@NUUXfpx}}|yyxz{zyyslcUI@:866444333389<CFEFEDB>:7778;<=@CGJPY`iry…ˆ‡†ƒ€€~{zzxvtnic_YTSPNMLJIJKLLLLMPQTX]ehknqpqqqprrrrrqqqruvz~€‚‚|xpg[TIABKT`krwyy{}€…‰ŒŽŒ‹‹‹ŒŒŒ‹‹‰…{tme`^^afkpsutuwxzyzxurnf`ZVWUX]eowˆŠŒ‹‹ŠŠ‹ŒŒ‹Š†wohgjmsyyxwvuvvvvwy{{zvrrttss7768988869887777667878::::;;;;<<<<<<<<<=<<<<<<::9988998888887777555521111110---,+***))))))((''''('''''''&&''''(((())))''''(('(,24>GQ[cjosvvuttssopoqruvvrjeWI9)"!!""$$$%$$%%&&&&'()*+,,,,-/012369=CIOV\afilnopsqlkfb\ZVRPLJHGCA=:9842/....------....----00012233555555445544322210////-..028BMXeosrqqqqstsqmeZOE>;60,''((')+.5?LZft|ƒ‚€}~ƒ……†€ynf]YXXWURRPV\bjrvuraXY@6<2,+,,-------../01003;[f^Z`[;HTXVhpz}}{yxxyyyyztmcUJ@96545543246;?EJNPPROKD>967779<>AFKRZclsy…‡††„€}||zxuqmg_YSPMGFFEDEDDDEFGGIJMRY^dgjloqrrsrrronkklmmoqv|€{tlb[PJFNWblsy{{}‚†ŠŽŽŒ‹‹Œ‹‹‹ŒŠ…‚}vqjfeefmpstuuwxyyyzwsnhb]WRSSX]goy‚‰‹Œ‹‹‹‹‹‹ŒŒ‰†wlefiouyywvuuvvvvuwzzzvtrqqqp888899997:889977668878::::;;;;<<<<<<<<<<<<<<::::88888877778757745555111100.--,,,+**))(('((''&&&&'&''''''&&''''((((((''''''(('(*+05=GNT]cfilnqrtuwxz|~……zsfVF5(!!""$$$%$$%%&&&&()*),----/002358;AFLSY`ehjlmnoqnhc\YTPNHDA?><;8764200///..------....0000011123345555555566444322000/0/-/.028@LVcorrqropqrqqmeZOE=84/+(()(()+-3:EVdpz€‚€}|}‚†‡†€{qi`[XWUQQOLOT^irutvbQK?882.,,--------.//000125Mk_WdV8;PWWdqz}}{yxxyyy{ytmcUJ@:7755554459@GMSX[\[YUNB;85667:>@FOV]fnv}‚†‡†„ƒ€~~~||zxuqke^TLGCABBAABAAAABCCDFKPW]`cjmqppqqrttplieebbfhntz€}yog_WPOQYbltz{{}„ˆ‰ŽŽŒ‹‹ŒŒ‹‹‰ˆƒ~zuqkkjkpsuuvvxxyzzyurlf^URPRRW]hr|„‰ŒŒ‹‹‹‹‹‹ŒŒŠ…~wmecjpvyywuuuvvvvuvxxxvsrpqpn9999999999888877877789::::::;<<<<<<<==<;<<;:::887776777777667546545311200/.-,+++**))''''&&(((())&%%&''''&&''''''''''''''''&('''')+4;BHNRXZ]bdhnuw}€„†ˆ‹ˆ†‚|reUG5&#!"$$$$$$%%%%'(****,-../011358;=BGNV\beiklooomia\TNHEA?=<96534321////----..........//00112333455566775566554433220011../137>JT`kpqroonpqppme[PC;51-*''()()*,/7BP_lw‚~}}ƒƒ……~umc^ZUQMIGGHP[jqvtkRBKNF>60,,--,,----/0//10/25H[[[i[76PTVdrz~zyyyyzzxxsmdUJ@:75564446;@HPX^bghfb_VKB964358@FKSZdkry€„‡ˆ…„‚€}|~}zxvrjbZMGC>?>>@?@@@???A@CCGNT[afimoqrqqssqpje]YUVZ]ckswz}{rld[XUY^gouz}}~„‡ŠŽ‘‘ŒŒŒŽ‹Š‡…|{{xxtpqqtuvvvwwy{zywtoic[TPOOPU\gq~…‹ŒŒ‹‹‹‹ŒŒ‰„~skffkqwzywtuvvvuuuvwwwsqnnnpn9999999999888877887789::::::;<<<<<<<==<;::::997766666566765555655431110//..,,****)(''''&&&''''((&%%&''''&&''''''''''''''''('''&&%(*059<CDHKOT\dnv|€„‡‰ŠŠ‰…ƒ|ocRA.$"#$$$$$$%%&&'(*+++--../013467;?DJQX^dgjlonmmh`ZPJCA=:86544311200////----..........//00123344556677777777665533321000///137=HS_jpsspnmnorolg\QE:4/+)('()()*+/5<JZgs|~|||€‚„„ƒ~xpg_YTPHECCGPZfptfM>D\\M?60,,--,,----.///00.2=RY^cdTIQQOVgqz~~zyyyyzzywsmfXKA:75543448=ENU^flqrple]PE<6538<BKPV`hou}…†‡†ƒ€~}~~|zvrjbVMFA?=>=?<>==><=?>?CGNT[aeioppqpqsqqoic[QJHMTZckquzyvoia]\]bgov{{{„†ˆ‹‘ŽŒŒŒŒ‹ˆ‡„zyzz{{zxvxwwwwwxyx{zywsmf_WPPNLOU^it~†Œ‹‹‹‹ŒŒ‰zriffjqwzxwuuvvvuuuvwwvrpmnmkj888899999987887788889:::::::;<<<<<<<<<;:::::987766665455556566555211000/.-++**)*)))('&&%&%%%&&%%&%%&''''&&&&''''''''''&&&&(&%%&%%%%'*/11238@IPYcjsz€‚„……ˆ††‚xo]L8'##$$$$$$$%(((*))*+--/.0013578=AGOUZaehknolljc\TIC=96654444312200000/-----...//....//1112334455667777777766554333021100//48;ER^iprqnmkmnrpmh]QE:3.+)(&())*+*.2;FVeqz€‚~|z{~ƒ„ƒzrj\VPKB?==DMXfphI7B^i`QD80-.--,,..---./0./13A]]baUSYXSPYdq{~}{yxyzzzywtneWKA;8444446;AJT]fotyyzsj`UG=747;BJPV_fosz€ƒ††…ƒƒ~~}}||}{wqh_UJB?><<<=<>=;;<==?@DGNV[agjlnnoqqrrplg_WKC<?GQYahmuuvqkgdbadjry}~|‚†ˆ‘ŽŒ‹‹‹‰‡ƒ€}{{}{}}}{{zzzyyxyzz|{zuoiaZSNLJLOU_kv€‡Œ‹‹‹ŒŒŽŒ‰zqhdejrwzxvuuuvvvvuvwwwsoolljh99999999998788778888::::::::;<<<<<<<<<;:::9987776666445544553334521100.---*++*()))((&&''&%%%&&%%&%%&''''&&&&''''''''''&&&&''%%&%%%$$&())*)*0<CKT]flrvyz|‚ƒ†…~tdS?*!!$$$$$$%&((()*+,,-../0013689>DJRX]bgjmnmmjd]ULB9874433333311100000/-----...//..../011233355557788777777765554322110110048;CNZioqqnllompqog^SG;2-*)(()))++*,39BP_lv}|zz{~‚‚{vj[SLE?:9:AKWbpkN9LjocRE90-...--....-./00123FbibSMjbRUSWfr{~}{yxxyyyzwtneWKA:7443346<BMVblu{€}ulbUI<77;BHOV]flsy‚…††ƒ}}~|}~}{wqh_TJC?=<;;;<<;;;<<<<=BGNV[`fkkmpqpqromje\RJ?76=EPX`flswrmiifgimtz}~„‡‰‘ŽŒ‹‹Šˆ„€{ywsuw|}~{{zzxyzz|{ytmg]VNHIHIOU`mw‚ŠŒ‹‹ŒŒŒ‹‡xmebhlrwxywvvvvvvvuvwwvsomhhge:::::::9998777778888:99999;;::::;;<<<<:;:;99887765555455544443343201/---+,*)((''&&'&'&%$%%%%%%%%&&%%&&''&&&&&&&'&&''''''&&%'&&&&$$%%%%%&%&'+05?FNTZaeilpx~…†„yiXD-"$####$%&'())*++-,-../012469>AIRV\bfhknnnmg`XPF;7444443333212100000/....-.--//..001111334555579999999988776655442211111148;@LWdmpponkmnnqold\NA5-))*)*))**+,18=KZht{~~}zyy|~€€}wj_RHA<557?IT`jqJ?auqgVG<4/.,,....--./00003;Zz{eHN\\HIRYdqz|yxvxxyyxuoeXJ@84332137<EPZdpy„ƒ~umaUI?<>AHPW_emrx}ƒ…‡‡†‚~~}}~~~~|wqj_SI@;<;:999<<;;;;<9=AGOV]cilnoooononmgb[OG:304;ENV`fnqsojjkloru{}~‚…ˆŠŽŽŒŠ‹ŠŠˆƒ|vrniltx}~€|{{{{{{}{xqkd\TLHFFIMWdp|…‹ŽŽ‹‹‹‹ŒŒŒˆ„~ukcaglrwyywuuuuuvtvwvvuqnkjheb::::;;:99987777788889:99::;;;;::;;;;;;:9:8776676555444544444432221/0/.,,,*(((('''&'&'&$$%%%%%%%%$$%%&&&&&&&&&&&'&&''''''&&%'&&&&$$%%%%%$%$&&&*09@EJMNSZbny‚†„ym\D-$#####$%&'())***,---/0/1369<BGLTY^egjlnnmgc\UJB;7444443333212100000/....----....001112334555679999::::98877665442222111348;@KValpponlnnnppmg_RC6.***)*****)*/6;IXery~}zxxz}|wl_RF=6148=FR^kd=BgvofXJ=5.,++,...--.//../0Cn{v^ONYT>NYcer{~}{yxvxyzyxuodWJ@84311248@HP\gs|‚„ƒ~ul`THAAFIOW[cjpx}ƒ†‰‰‡„‚~~}{|~~~~{wqh^PH@;:99999::99999:=AHPY^dilnooonnomjdaWOB61./3;FQ[cjnqroonprtw{~~€ƒ‡ŒŽŽŠŠ‹Š‰†zrkebemrx|~€€||{{{{{}{vniaXOICDEGMXfr}‡ŒŽŽ‹‹ŠŒŒŒŒ‰ƒ|qjbbgltyyywuuuuuuuwwvtspmkifeb;;;;;;;;::9887888888:8999::::9:::999;:888877765454445444234441220//0.-++**)((((('&'&%&&%&&%%%%%%$$$%&&''''&&%%&'%%&&&&&&&&&&&&&&%%%%$$%%$$$$$$',158;=CKWiv€…„zn[C,##$$$$$%&'())*,,,---/0/136:>DKQX\afjjjnmid`XOF>96545444444333321000///.-----...0001133445567789988999998877665443322322136=BIT_iqrpnkmooprpkcWI<0+++))*++,+-/6;GVbnw}~{xxz}~€€~yobSD82036<EQ]jaDFowrh]L@5/---,,--....-.02<_klrXGNNZSQRgjt|~~{yxwwyzxwuogYJ@84211249=GR_jwƒ„ƒ~uk`TLGEIPVZ`gnv|‡ŠŠˆ†~~||||~{wqi^PF?986857777787768<BGQZ_gimnmmnmmnjgc[RH=6.+-05=FS\eloqqqqtuxz|~}€ƒ…‰ŠŽŽŽŒ‹Š‹Šˆƒ~wla\Y^fksy~€~}|||}|||yslf\SJEBABFO[ht‰ŽŽ‹‹‹‹‹ŒŒŒŠ†€{pfacfkszyxwuttvvvvvvuspnjhgea^;;;;::;;::987888888899999::;9:;;9999:877756666434465444323444111/.-.-,++**)(('(('&&&%&&%&&%%%%%%$$$%&&''''&&%%&'&&&&&&&&&&&&&&&&%%%%$$$$####"""$&',./6BQds„ƒylX>)##$$$$$%&'())*,,,--.001369?DJNU[_ffgknnlhcZSJC<665554444443333210000//.-----...0001133355556789999999998767665543322231247<AIR]fnrpnlnooprrlf[M?4,,)+)*+++*,05<FUalv}~{xxy|}~{reSB72036:DO[g[ERutoj_NA6/-+++,--......03KjjulLGFHMLNRons{}~{yxwwwyxwtngYJ@84212239>HUbmy€„…‚~uk`TLHMSXY\dmt{…‰‰Š‡„€€~~~||}{~{vpg\PD=;76667777767767>CJSY_fjmomnmmnmkf_YPE:2.++-18ALVajmtttuxy{}~€‚„ˆŒŒŒ‹Š‹Š‡{sg[SPX`kqvz~~}}}}}||zwrkcZQGB??CHQ]jw‚‰‹Œ‹‹‹ŒŒŒŠ†€xnf_bgltxyxvtttuuuuuuuspnjhfda];;;:::;;:9987788889998999;;;::::99988877655554555544333323554100....,+++**)'''''&&&%&%%$$%%%$$$$$%&%%&')'&&&''''''''&&''''&&%%%%#%$$$$####""#"$$#%&',4>N`q}„‚ykW<'##$$$$%&'()**+++,,.12249=BFKQT[adghimnlif`WNG?8766544444442222110000///.------.0001123455557779999::9999888866554433332458=BIQZckpqommooqrvqjbQC6.))+*+**,+.3:?GS`js|€}yyx{|~€€{sgWF:3149:BNYeTK^ztqk`PC70,,,+,,,----.0/3Rqzw_FEL>>LUUeiq|~{yxwwxxyxuofYJ@9412114;AIWcoz„‡‡„xm`UQQSVX[agpw}…ˆ‰‰ˆ…ƒ~~~}{{}~~}|upf[OB<864456766554457;BKSZ`gjllmmlkmlic]VMA8/,**,06?JT^imsvwwz{~~€€€‚…ˆ‹ŒŒŒ‹‹ŠŠ‡€zpeXKJP\dkrw{}~~~}}}{{xuog^XMD?==@GS_l{„‹Ž‹‹‹ŠŒŒŒ‹‰…uld`chntxxwtssssssuuttqpnjfec`[;;:;::;;:98777888888899989;;::99::8988664455544444333322222221//--,,+****)('''''&%&%&%$$$%%%$$$$$%%'(++--+('('''''''%%&&&&$$$%%%%$$$$$####""#"###$%&+1>M_p}„‚ykW>'##%%$$%&'()**+,,-./0259?DHMQV[]deijkjjjic[SJA97566544444442222221/000.--------.0001123456657778999::999999776655443333346:>CIQ[dkpqonnoqstvtnfZJ<0****+*+,/26<BKT`kt|€~zxx{|~€€|vl[K=5025:BMWdPSgvurmcSD;2-,,+,,,--,--.08lzuubNED>EQQTffq|}{yxwwxxyxtneXJ@9401/15;CMYfr~†‡‡†‚|pdYVVXZ\]dirx~…ˆ‰‰‡ƒ~~~|||}~~|ytof[OC:644444555444457<DMU\bhkllmmlkiifa[TI@30+))+04:EP\fmrvy{|€‚‚‚ƒƒ…‰‹ŽŽŒŠ‰ŠŠŠˆ†xmcUJJNWahpwz}~~}~~~|{ytle^RHA<:>BKWco|†‹ŒŒ‹Œ‹ŒŒŠˆƒ|ujb`chntxwuttsrrrsttsqromjfc`][;::;;;;;9:877788877788889:::::989987776655433333443333221100//.-,+**+++*((''''&&&%%&%%%$$$$$#$$$$%&',03442-+)()))&&&%%$$$$$$#%$$&$####$#$##""#""! $')/:J\my…zkXA)"$#$%%&'()))*+*,.-0259AEJNSV]_cdfhkkkkjf_VMD>86565544433332222110../0.------...0001112346667889989::::9999776665553333567:?DIQZcjoqponqrstvuqkaQB4**++,+.036;AEMValu}‚€~z{{|€~yoaOA71148ALWdLLjvvqleVF;2-++*+,,--,-,00IzrUK^]TPWLMQPiir~}{zywyyyyxtnfXJ?8411/27?FP[hv…‡‹‰†rg]XXY\]`elrz€„ˆ‰‰†ƒ€~}~|~~}~€|yuoeYMA9522232233443348=ENV]ejkmmmnllkie^ZPE:2+))*,/38EO[cjrwy}~€‚ƒ„„„„†‰ŒŒŒŠ‰‰‰‰†…~uj`VKGMT^irx{}~}}{zwqld[OD=::;BLWgs‡‹ŒŒ‹‹‹‹‹‹‹ŠŠˆ}sga^bgotvwurnqqrrssssrqnljfa^[Y;::;;;;;:9877788787788889::::9778877776544333333222211111100//.-,+*****)((''''&&&%%&%$%$$$$$#$$$%$&'+05:=9722100.,(&$$##$$$$#%$$%#####$###"#"#"""!"%(/9GVjy„|n]J1$%#$%%&'()))*+,-.036:@FKOSX\_acfjkkkjjic\SJB;64655544433333333110/.//-------...0001112345677889989:::::988877665553355668<@EIQXaiprrpoqrstvvtneWF8.-.,+.157;@DJQX`js}ƒƒ|{{z}‚‚€{reUD82148AITcKFivvrlfWH=2-,,*+,,-----1DtwmZ8OOMSWQRROcjs}€}{zyxwyyyxuneVI>843125;AIS^lx‚‰Š‹Š†th`[[\]]bflrv|…††„‚~}}|||}~}zxtndZNA9521112211111149>GPY`gjmmmmmllkhc]WMB7/*)))+/3:FO[cipv{~€ƒ†…†ƒ„„†‡ŠŒŒŒŠ‰‰‰‰†…}vl`SKJMT^hpv{}~}}|{zvpjbVKC=::;BNZiu‰‹Œ‹Œ‹‹‹‹‹‹‹‰†€xpe`^bhntvvtrpqqqqrrrrqpmjgca^ZX;9;::;;;::89878788877899999888887766665522221111222210000/00//..,+**))))))'&%%''%%&&%%%$$$##%%$$##$&+.37;;:6777765/*%$$$$$$$####"#####""""""""!!!!#$)-6BRcs~‚~scP8'&$$'''(((**++,./25=CHMQTY]_bdhkkjmkhie^VLD?97665566553333332211///..-------../10011123455678899899999987899764434345676:>@FKPX`iqstrppqsuvxvpg\K;2----169=BEJMT[ajs|„……€~{z}~‚€xk[J;3347>ISaJJjvtrofXI<4-,,*+,,-----.KxzqJ7UNLIMSMRWchr{€~{zyxxyyywtmeYK=752548=ELXcp|†ŒŠ†}tib^\]]_aejpvyƒ…„„ƒ}}}}}~}~}yxumcYK?7321000000000/6:@GQYahmlmmmmlkie`ZUK?5-+++**.4?IS\cjqu{„††„ƒ„„†‡ŠŒ‹‹Š‰‰ˆ‰‰ˆ…~vl_RJKQVajqy|~~~|||{xsne\QG?:89=DO_lyƒŠ‹‹‹‹‹‹ŒŒŒ‹Š‰„}vlc^^bgnuutsrqppppqqqqomkgfc`\WV;9;:9:;;99998777888778889998886677665543222211112111100/0///..--+,**))))('%%%%&&%%&&%%%$$$########$%(*.166456699872-'$$$$$$$####"#####""""""""!!  !#&+2<M]o{‚vfU=*&%'+-,())**++-/26<BIMSU[^_befhjjjiigc_XOF@965665566553333332211///..-------../1001112345567887789999998789976653554568:<@CGKPU`hosttqppsuvxwslaP@6/..18<?BEJPRW]cks{ƒ…„€v{‚xo`O>5347>GR^IHlvtsofXJ=4-,,*+,,------;`pjQ8[WNLPYUMTc`fv}~}zyxxyyywtofXK@96689>ELS]ht~‡ŒŽŠ„|rhc`_^]]^`djov}ƒ„‚~}}}~~~}}yvrmcYK?731000....../04:BKSZcjmlllmmlkic]WPE<3-+),+-09BLU]cjrv{ƒ…††„ƒ„„†‡ŠŒŠŠ‰ˆˆ†ˆ‡‡„}vl_RNNSZbksy|~~}~}||{wrkf\QG<888=FSco{…Š‹‹‹‹‹‹ŒŒŒ‹Š‰…|sic^^biovvtspopqqqqqqqomjgdb^ZWW::<<::::;9::9887888888889977765555445543222211222200//////./.--,++*)('''''%%%%%##%%%$$$$%%#"######$$%'(*++-///26661.(%##""""####$$#""""""""!!!"""""#%)0:JZkx€wi[F/&%*/23,)))*+,-28;AGKQUZ^`cdfhiiiigfdaYPHA<764555555554433322200//.-.-------..0011112325666788888899889888887775445567:<=AEJMQX_gouuusrrtvtvwsndUG:1027<@EHMPTX[_diq{‚‰†ƒ~s^j|€yz€|seTD8336<FP_JGkvsqnfXK>5.,,)*,,,,,,-+2LenaPn|iQO^^NLa^Vk‚|zyyyyyxxvofYJ?;;=ACHLTZbmx†‹ŒŒ‰ƒznga`_]ZXY\bipw}„‚~|}}|}~~~~}{ztqkcWI=630/...---,,-/5<CLU]djmklkllmjhe]WOD91,**,+/5@HRX^ckrw}€…††…ƒƒ„†‡ŠŒŒŠŠˆˆ‡‡ˆ‡‡ƒ|vl`SQRU[elty}~}|}|||{wpibXMA9688>FXdq~‡ŠŠŠ‹‹ŒŒŒŒŒŒ‹ˆ‚{qf`\^cjrvwtsqpqrrrssqoljlge^\ZYY::<<::;;;99988878888888888777655443344332111112222/////.///..--,++)*('''''''''%##%%$$$$$%%#"######$$$$$&&&')**+///+)&%##""""####$$#"""""""! !!"""""#%)/8EWftznaP6)).59;3*))*+.16;@FLQVZ\adcfihhiihgc_YRKB<7655555555554433322200//...---..--..0011112325666688889977899888777765655668:=ADHILQW_emtwusssrttvvtphYJ>859<ADINRVY\_dhlu|‚ˆ†‚wnky~|p{‚}ujXI:337=EO^KHarsrnfZK>5.,,+,,,,,,,,,-4FSkkuteb`aZNBSfkz}{zyyyyyxxsmf\PDCACGJNRZajr|„‰‹Œ‰ˆuic_\ZURSTX`fnwƒƒ~|}{{}~~~~~|yvuqkbVI=63/.---,,,+++/4<CMW_gjmnlklllieb]WOD91,+++/5?GMU\diotx}~„††…ƒƒ„†‡ŠŒŒŒ‰‰ˆ‡‡ˆˆˆƒ|vlaUQSZ`gov{~~}|{}}|{upiaTI=7669?J\ju‰ŠŠŠ‹‹ŒŒŒŒŒŒ‹†ynd[[^ciqvwsrqqrrrrssrokjhfb]\]^^::::;;;;:99877878877887787776643333322221111110011000///.,..,,,,*))))'&&''&&%%$$%%$$$$$$$$#########$$$%%&&%%&&'%(*''%$""""""""""""##!!""""      !!!"$'+4>Qboy€|sgWB-)1;?A7,**,-169=CJQVX^bfeggjhiihfa]VOLD<97754545566444443221100//...-------../01111233456667766889989887766665666676:=@CEIJMQW\emsvwuspssssuuqj_PC<<>AEJNRX[^aegkpvz€†…xwujfqf[hszyo^M=4249CP[PO_qsrkeZK>6/,*++++++,,--+++8YrlgdpdWVTS]hu{}{{zyzyxxxvoi_UMJJLMPTYahov~†Š‹Š‡‚zre]ZVRMJMOS]fr|€ƒ~|||}~~~~}~{xxupibTI>52.----,++++*05>GOYahknlmkkkljgcZULB8/+++04=GNV]binswy|‚„‡‡…‚ƒ„†Š‹Œ‹‹Š‰‡†‡ˆˆ‡ƒ|ulaVRU\biqx|~~~~}~~}xume^RE:6648AM\ly‚Š‹‹‹ŠŠ‹ŒŒŒ‹ˆƒ~vl`YY^elsvwusqrqqrrrrrolhgc`\\^`b;;::;;;;:98777878877777787775433111111110000001100.-////--.+,,,,)()'''&&&&&&%%$$$$$$$$$$$$##########$$%%%%$$%%$##%&%$#""""""""""""""!!  !!        !"#$)/9K]lw~tk\J3),4<?4))*,/38<CGNSX\adfghhhjigda[VOHD>955655545544444443221100//.-.-------../0111123344566776677887788776666655688:=@BEEILMQVZdlswwvtrrrrtssqlbWNEBDJMQU[_dfikpsvz}€ƒ‚vut|dPD?@D^^XohJ8049?KZNM^lrrmeZK>6/,*++++++,,,,,,+5M]chkcDHMLS`ir{}{yywxyyyxuqkc\XRQPTV[`fnu|‚ˆ‹‹Š†xmcYSLHDBEMU^iv}‚ƒ~||}}~~}|{xwtpibTI>52----,,++++,19@HP[bhlmkllkkkieaXSJ@5/*+-3;EPU]ciorwz||‚„††…‚ƒ„†Š‹Œ‹‹‰ˆ‡†‡ˆˆ‡ƒ|ui^WUX_fmty}~~|}}}||xukf\PB84459DP_o{…Š‹‹‹‹‹‹‹ŒŒŒŠˆƒ}uh^YY^elswwusrrqqssssrolheb^^^_bd<;;;::::98988677887766776566421111110000/11100////00/.--,,-,,+,,))('&&%%&&%%%%%$"#########$$""""######$$$$$$$$$"""$$$#""""""""""""""!!          !"##'-5CVhs}{raR>.+/75/*+,.05;>DJPW\`cfiijjjiec_ZTOGB<765456544554445443222110/..---,--,,--...011112333555566777788898866666665679<=@CEFILKMOTYcltvwvtrrrrrrsqoh^TLHJOSY^bhknstvyz}€ƒ€mYZqhU[bi^PxVf`_T<:?YnbKGN_prleZK>5.-+,,,,,,,,,++,2;PVWbfQO]IELVeqz~~|xwxyz{{{yvphc^[YWZ^cgmry‡‰‹‹‰ƒvk_QLD=8;@MYeq{„„~~}€~}|{zxuupibTI=30--,,++**++-3:BJT\dhkjljjkjigc_XOF<3-)-2;FOV]djprvz{}~‚„††„„‚ƒ„†‰‹‹‹‹‰ˆ‡‡‡ˆ‰‡ƒ}vmbWSZaipx{}~~~}}}|}wuicWJ?62229DTbp}†Š‹‹‰‹Œ‹‹‹‹Š‡†zqh]WX_fmtvtutqrsrsstsqnkfca_`_adf<;;;::::988877768877666655443111111100000000//0///0/.---,,,++*))))(''%%%&&%%%%%$"######"##$$""""######$$$$$$$$"$#"$$###"""""""""""""!!         !!"##%)4@N`mz}ufYI5,+-,+*+-047>CGNUZ^bdgiijjjfa\VQJD@;7665663344554445442222110/..---,--,,--../01111233355456766778878876666666789==?BEHIKLMOPS[bkpuzyusqqqqsutsne[TPQUZ_ejqux€ƒ‡†„vX@PZRP@X`^dlNJA@GKh˜“rICLcsqkf[K>5.-+,,,,,,,,-/Hn}„†„tcfjV[JN\Xeqz|}{xwzzy{{{zxvoga_][_chmsx}„‡Š‹Š‡ƒ|uiZL@7339CP\hv}ƒ†„~~€€~}zyxxwspibTI=30--,,++**++-39CKT\djkkjjjihhea[VMB81,+07BKS]fjoty}~}}~„†‡…„‚ƒ…†‰‹‹‹‹ˆ†††‡ˆ‰‡ƒ}vj_XW]emqy{}~~~|}xrh^UH;3122;FXgs€‰Š‹Œ‹‹Œ‹‹‹‰ˆ†ƒ|tkc[WX_fmtvurqqqrrqrrqpmjeca`aadef;;;:::999877776655665556422221001100////..-----//...--+++++)))*)(('&&&&%%%$$$$$$$$$$$###########$$""####$$""##""########""""""""!!!!        !!""""$(.8GWgsz|xnaR>-*((**,-058>ELRY\`cdhijihd_YTNHB>976335444455553344332211000/....,,--.---../001202344555555556666887666447679:<>ABFHJJLNLNQQYbhptz{vtqqpprtvvqkd]XW[]djqw|ƒ‡‡‡‡ˆˆˆŠ‹Œ~jVQZVZ\cfib\EDLQD@LhwmYGZwsole[K=6/--,,,,,,++-/[~€vx}xiiwkRIV_Xdq|~~|yxwwy{{|{zwojeb`bdimry}†ˆ‰‹‰…‚{qeVF;404=HUamx……„€€}|{xxwwvrkbVJ=3.,,---,,+**/3:DNXaeiiiiiijieb\WQH>5.-/5>HT\dkov{~}|}~„„††„‚„‚…ˆ‹Œ‹Šˆ‡‡‡‡ˆ‰ˆ…~uj^Z\`hosy{}~~~|xph\SE80-,0<J\iw„ˆŠ‹‹ŠŠ‹‹ŠŠŠŠ†€yumbXTWahosvurprrsrqtsroliecccddefh<<;:::9988777766556655542222100///10////..----/./.----++++*+))))(('&&&&%%%$$$$$$$$$$############$$""####$$""##""##""""""!!!!!!!!!!!!        !!!"""#&*3?P_mv|zsj[M6,+*+,/046;AHMTY]adgjmkjd^ZRJEA>9554454444455553344332211000/..--,---..--.0/0012023335555555566667775656679;=>@ABEGIKLMMMOPSV^gnuzzxusqsssuwwtpjd_^`diou~ƒ‰‘ŒpVIIW_mrklnYGQCFGIIKTb^O[tnmic[L>6/,,,,,,,,+++,.>Yhpkfd_nkPO^^Tdpy~~|yxxxzz{|{yvojeccfimqvz}…‡ˆ‰‰…‚{qeTD8218BM[fr}„„„‚€€}|{xxwwvqlbVI<3.,,---,,+**.5<GNXafiiiiiiihe`\XOE92/04<DOYbinsy~€~}|}~„„††„‚ƒ„…ˆŠŒ‹Šˆ‡‡‡‡ˆ‰ˆ„~uka\_cipvz{}~|uph\O@5.++3>O_ly„‰Š‹ŠŠŠ‹‹ŠŠŠˆ…€yrk^VSXaipuvsrqrrrrssssolieddeffghg::;;;;99877766656655444200111110/0./..//..--------,,,,,+**(*)'&&((('%%&%&&%%$$##$$$$$$$$####"""###""##""""""###"""!!!!!!!!!!!!!!!!!!     !   !! !#$'.8GWfpz|wocTC2,--0136:@EKRUY]aeijjjhaYSLGB=:674445555444555433333321100//..--,,----..//./11111112445555554455555445568<<>@ABFIIJLMMNONOSX[ckrwxxtsrrqsvxxxuojfdehlqw€‡Š’‘’’‘””•“Š^;BX]Wgag}pVd\KDCGOU[VOUijnlcZL>70,,,,,,++,,,,6SKNVWaPIWQNXR[Xepz}}{xwxyzz{|{{xsjfcffjotwz}‚„‡‰‡…€zqdSC725<ER]jv‚„‚€€€€}|yvvxxvqldWI;2-++,,.-++),/6=GR\bfhihhiiige`ZTMC8127;DKV^ekrv|~~}{}„…†…‚‚„…†‰‹‹Š‰ˆ‡‡‡ˆ‰‰ˆ…~uk`Y_dkqw|~}~~{wodYL=4-+,5@Rap‡Š‹ŠŠŠŠŠŠ‰‰‰‡…yphZVSWaiortsooqqqrrrsrmkheffgiihge::;;;;9987776665552211210/121221221/..//..------++))+++)***)()(('''&%%%$&&%%$$##$$####$$####"""###""##""""""""""""!!!!!!!!!!!!!!!!!!     !   !! !"#%*2?O`jt}}wl\O@222568:?CGMQW[_bfhijgb[TMFA=:7654444444444444543333321100/...--..----..//./111111334444555544555545568:<=@BCDFHJJKLNNOONOSTY^hnuxwusrrqsvzzzwuojfijmt{ˆŽ‘‘“••–——–•‘u^VYP3]s‚|wj\TWRSMMYWQNU^fd`YMA7.,,,,,,++++*,2A]aPZ[Q]T:BEJT^eqz}|{xwxyyy{|{{vojfehhlpuux{|‚…‡‡…€zqdSC837>IVaoyƒ…‚€€€€€€~~}|yvvxxvqldWI;2-++,,-,+++-29AJT\bfhihhiiigd_YQJ@725=BJS\bhnsw{|}{zz{…††…ƒƒ„…†‰‹‹Š‰ˆ‡‡‡‰Š‹Š…~tia^`hlsy|~}~~{wodYJ;4-,/6CXdt€ˆ‹‹ŠŠŠŠŠŠ‰ˆ†‡…€xmeYURXajptrrqpqqstssrpmkjijjhhhfd^<<;;::998766665533331011021146674310//..--,,,+,,,,++**++)))'(())&&%%%%%#%%%%################""""$$""""""""####""!!!!!!!!!!!!    !!    !  !  "!!""#&,9EUcnx}zreYK;669;>>CHLRTX]adfhigc]UPJB=8766654344445544554433333211//......-------..../11001243334455554555443688:<>@BDEGGIJKLMNNOONPOQSYbjqyvttsrqsvy|}ywrmijinuz…‹Ž‘’˜™˜˜™š˜“ˆ„kSy€yob]LEV^YUQOMOPRYa\QC71--,,,,,+,,-*-5ZgWTaVcT:GLSX^hu|}}zzywwxz{{{xslgcccfiloruyy}……ƒ€zrdTE:58AN[gr{ƒƒ‚€~€€~{zyvvwxwslcVH;2-++++****+.4;FNV\cfghgghhhhd_WOG<59<BHPX_dinrvyywvxyz„…†…„ƒƒ…ˆ‹ŒŒŠŠ‰ˆ‰‰ŠŠ‹Š„}ujbabjpuz}}}~~€€€{vndWG:3,*0;HZjx‚ˆ‹‹Š‹‹ŠŠ‰ˆ‡„‡„vlbUQRYajqvursqppqrssqomllkljjhddaZ<;:::::8876655643321//001/1458;<:8531100....-+--,,++****))(''(((&&%%%%%$%%%%$$####$$########""""##""""""""####""!!!!!!!!             !!!!!""%%)2<IZhr{}vmcWG<;=?BDIMRVX]^beehhf`YSKF=976554664444455665544333333110///....-------..../110012243344444434445578;<<?ACDFFHIIJKLMNNOOOOPORV]dluxvtsrqsvwz}{ysnjjmqsv{€…ŠŽ‘’•—ššš˜˜”‘ˆ…|{|€€{sg\NGV[XZPLJMOLLY^VH=4.+,,,,,,,,,,-5E]\G[VWOFWVG>Pdmx~}zzyxwyzzzxuojdbbbbgkkosuxz}‚‚ypeTE96:CP^jv„…ƒ‚€~~~}{zyvwyxwslcVH;1+*********06=GOW_fhiggghhgfb]WOG?<@DIQX\bhllruvvsrswz}‚…‡†ƒ„„„‡ˆ‹Œ‹ŠŠŠ‹‹ŒŒ‹Š„~uk``flrxz|}}~~€~zskbSD81,+1;M_n{…Š‹Œ‹‹‹ŠŠ‰ˆˆ‡†|si^SPR[bjrttrrrrrrsttsqonlllljhf`[V;;99999876665343221///.//2278<>BB@=9554211/....---++*)))))((''('&&%%%%$$%%%%&&%%$$%%$$##########""""""""""""##""""!!!!!!        !!!!""#%&*3BN^ht}zsjbUGABCHLPTWZ]_bdefgeb\WOGB;85455556655445566555544442200000/..----..----///011011212222222423435678<=>ABDEEEHIHIKLLMOOMNONNMOPU^grvvtststtwy|}zuoljllmpsz„Š”•–˜š™—•‘‹„€|{{}~€{tk^RNUOPUVVMGKOSSTWRG;4+..-,,,---,..05:=QNQEDOPC>Pkgw|{xwwyyyzyxutlib[]^aeigmpquwy{~}wlbRF89=HTbny‚†„ƒ~~~}|{yxvxyxwslbVG90+))))**))+18@IRZafgihhhhggeaZUNFBAEJPY[_dhkmprqomorvz~€ƒ„…„„„„‡‰ŒŽŽ‹Š‹‹ŒŒŒŠ„~rgbbgmtyz{}~€}xri]NB7.+,3?Obrˆ‹‹Œ‹‹‹‹‹Š‰ˆ‡†yqg[QPR[clquvtsrssttttrrppolkkkfc\UP;;:9998876554333221///./.16:;@CFIFDA><;855431120..,,+***))((''('&&%%%%$$%%%%&&%%$$$$$$##########""""""""""""##""""!!!!!!        !!"#"""#%'/:GVcnx|wrjaSHHKNRVZ]`abdefedc`\UNF>966666666655555566665555443310000/..----..----///0//01011233545555555789<=AACCEGHHIIIJLLMNNNMLMLKHIJOWblsvusqrttwy{|zuolihfgglpy|‡“•––˜–’‰‚yz|~~~yqj]UURRNNLNIDGOPNJMPJD9----,,,---,--.3=PWPLCISQCAOmiw|zxwwxyyzxwtslg_YXZ`fknolnnorvy|}{ukaPD89@JVdq|ƒ‚€~~~}|yvvvxyxwslbVG90+)))))))),29AJS[bfghihhhgfb_YUMIDGJRX^_bejllmlkiilpuy|ƒ„††„„„‡‰ŒŽŽ‹‹‹‹ŒŒŒŠ…~rhcfjpuz{|}~€|wqh]N@6.+*6CTdt‡ŒŒŒ‹‹‹‹‹Š‰ˆ‡„wndVOOT[dlttsssrrrrsttssqpoonmhc_WNI<<::99888554544121/..../036:=AFJMMKHGEB??<<;87765411.,))))(''&&&%%%%&&%%&&%%%%%%%%$$##$$########""#####$""##$$""!!!!  !!          !$$##!!$&+2?M\ht~|vrkdYTRVX\`ccefffifda_XQKC<6687667777776656668976553333100000/-./....-/./-/01224455566866786688;>???ACDFFHHIIJJKKKLJKKKMLKJHFCDIS^iqtvtsssuwxy{zuqkfd`_behpw{…ŒŽ‘’–•••“Ž‡~yyxz{xsnha^[YVTMMJIJFCGKGCHPMLH/).-,,+-,----,06FXQQIQUGA=>Jky|{zwvuwzzwuurldZWWY^gmcF@Dcknquz~{uj_PC9=DO]hu}‚‚€~~~~~~~~}~{zwwvvwxxvrkaSF80,(('''(()-4;BKS\cfghhiiiifc`[XRLKLQV\_ceiiijihdddintx{‚ƒ„„„……‡ŠŽŽŒŒŽŽŒˆ…tkggmsvy{|}}}~~€xofXK?5-+.8FXjw„ŠŒŒŒ‹‹‹‹‹Š‰‡„~ulbWPNS^gmttssqqrrtttuuutspoolf`ZQIH<<;:98875554332210...../036:?DHLRRPNMKIHFDDC?@@><;9952-+*))'&&&&%$%%&&%%&&%%%%%%%%%%$$$$#########"#####%$$#$$$$"!!!!             #"##"!$&'.8FXepz}{wrle`^^]adffijiiigc_[TMF>999886677777777888:89976643301000000//0/0//00.144456668::<=>=>@@ABBDDFFFFHIJIIIKKKKLLLLKKKKLKLJHGCB@?CLYdqtvtssttwyyyxvpib\XWZ\`krx€‡Š‘••–”’Žˆ|yywvtnecaZYWVYWMKLJE><CGGGIPSS\L%-.,-,+,,-.--.4LMWf[ST@<7:Iizz{xvvuwyysrurjd\XZ[jhM=D@8]iejsyzxsh]L@;?GT`mw€„ƒ€~~}}}}}~}{ywvvvwxxvqjaSF81+(('''((*.4=FNW^eghghiiiifca^ZVPORW[^aeghhifb_^_cimtx{‚‚‚‚„†ˆŒŽŽŽŒŒŽŽŠ…|sjiiotz|{||}~€}wofXH=4--1;L\n}„ŠŒŒ‹‹‹‹‹Š‰‡„~th^RNPT]elrussrrsstttuuuutqpmhc[SMHJ;;:98777543332101/--.....26;?EILRSSRQOOMKLKJIIJIFDB@=951.*)('('&%%%%&&&&&&&&%&&&%%%%%$%%$##$$$######$%$%%%%%%%$#""!!         !!   !!!!$&(-5@Q`lv}|xtplkhhhkkkkkjjieb^YRKD?;9999777788988889;<>??>>:64221/110/21132134577;<<<?BBCGGIJLLMOOPRRTSRTTSSSSRRSSRTRPPONNLJKKIIIFCB>;:9=IUcotusssstwwyzwtpe\SPNPS\cmqy‚ˆ‘‘““’‘Œ†|xwwwpf]YVRQMNVQFGFC;;?CGHKMOMOQ]@#*,-,-,,,-,--0<<Wc`^S=:3AZp{~yxwwvvusjhppje`\\aZ\UE@7Jcaajswvvph[M@<BJWdoz‚‚€}}}}}}|~~|zxvtutvwwuqj`TG80+((''&'((06@IOZaeghhhhhjhhfb`\XVVVZ]`dfeedb_YXX\bhotxz~€€‚…‡ŠŽŽŽŽŽŽŽŠ…~wmklqty{|{z|~~€€|upeXI=4..5>N_o}‰‹ŒŒ‹‹‹‹‹Š‰‡†„{qf[QOQY`iqttqqqqrssttuwwutrolg`XNHEJ::8877775442220/..------/247=BGKQRRRSRPONMNPPPQROPLGDA=940+)('''&&&&&&&&&&&&%&&&%%%%%%%%%%#$$$$###$$%%'%%%%%%%$#""!!         !!!!!!  !!!"%').4>JZfq{€|ywtussqpooppoojgd^UNHA<;999988889989;;=BFIJMNKIC@853223333467:;=<?@DFFIKPPPRUWWY[Z]aaacdgffeehgeeeeeddba_]\[XTQNLJHGDB?<:855<DR^jtvtssstvwxwwtmcZMGAELU^iov~‡Œ‘‘“‘‘‘ƒ~zxvwxskc]XSMJMRQJFDDAACCGLOQNLNJ^iL*&--,-,,-,-/07>`k__K:96Maqy}ywwwuvwp_V_hiea\aS=EH?KX`YW[fryxuneXL?@EN\it|‚€€}}}}}}|~}|zyutrrsutqoh^RE80+((''&'),19CKS[cghhhhhhiihhfea][[[\_acec`]YWTRW^ekqtxz~‚…ˆŒŽŽŽŽŠ†€xpmntxz{|{|}~~~€€}wqgZK=4//3?Rcr€ˆ‹Œ‹Œ‹‹‹‹‹Š‰‡†zod[QNSY`jqssssrprstuuvwwwwspme^ULEDP888877766431111/.---,,,,,.059?CGLPQQQQQPPOQSTTVVSUSSPKGA<52-)('(''%%&&&&&(''%&&&%%&&&&%%%%%%%%&&$$%&&&&'&%%%$$$$##""      !!! !!"""$$&+/4;DQ`js|~|zzzxvxvvurtrrnid]UNF?;:;;::9999::::=AGPTY\_`^[UMA654549;=@CEFIMMOSVVZZ\^_bedghiknmorssttuvuvvwwvvtuttrpooligd_[VOKGD@=87434<GP]irttssstvxvyvtndVLA:>GR[enu~…Œ‘“‘‘Š…zxvuwvolf^XRVWTQKHDBACBDDILNTSLMJDl\9+---,/2///1@\rm_[C98>Xf]p|zxvvvuvo]]b^`[XZU[I^F@D]VMQblqurspgYKBBHS_lv~}}}}}}}~}{xvurqqrsrpmh]QE82+)((&'()-4<ENW^dhiihhiihjjigfc^\\]_`bcdc]URONPW_gmruy{~‚…ˆŒŽŽŽŽŽŽŽ‘Š‡‚zrqqvz|{zz{}~}€|xpfZL>5229DVgv‚ŠŒŒ‹Œ‹‹‹‹Š‰ˆ†xnbYQNS[bkqrrqqqqqrrtvwvvwwuqoe]TJEHU8887776534311/00.---,,,,++.269>BGHJJLLMLNPPRSSWYZXXXVSPLGB:4/+)(''&%&&&&&('''(((''&&''&&&&%%&&&&&&''&&'''&%%$$$$$$$"!     !!! !"""#%%(+/27>JWblu}~||||z|zzywwuusmg]UNE?=<;;<<;;;:9;;@EMV^eknprqoj`QC;:=@CHIMQTVXZ[]cdgikmnprrqttuwyzyx{|~}~~~~}|}}}|zzzywtpjf_XPJB=94348>FR^jsuussstwxwxxtmcP@228BNXaju}†Œ‘’‘‹…|xvvwxxuqjha^XSPPKGFFGEEDFHIOYSDBBJ`h6)+--,..11;OhhVWO999J`eS]{{yuuutoh^c_VWUPOLOb\]]EOR_gsmtp}uqdWJACJVcox€ƒ~}||}}}}}{{zyvrqqqqrrpmh]QD70,)(()'(+.6>IQX`fhiihhiihjjjihfa]]]_aa_]YTQMJLPW`hmrwz{~‚…‡‹ŽŽŽŽŽŽŽŽŽŒˆ…~uttx{{|zz{}~~~€€~yrh[MA833;GXhxƒŠŒŒ‹‹Š‹‹‹‹‹Šˆ†xnbWRRW_fkqrroopqqrrtvwzzyxwtpi`TKGJ\99976553331///....,+++,,+++./379=ABEGGHIKNNNPPUWXYZZWWVSQIC>84.+*'''&&&'((('((((''''''''')%%&'''()(''&''''%%$$$$%%$$"!      !!!!!!""!"$&(*,/26<BNWdmtx|{}}}}~~}}{{yxvsld[RIB?>>><<=<<;=>AGQV_isz}ƒ„ƒ{qcUHEHKOSX[_chhlmnqrstuwwy|z{{{|~~€‚ƒƒ‚ƒ„…„„„‚‚‚‚ƒ€}zuoibZQLF@<>ACIR^hquutsssvvxyyxy{{|^/-?IS^jt|…’’’ŽŠ…€|ywxvxyzxxricWVQRNMIKHFHEFGIMVLCADB?UK$*/,//1<`SKQP\SN9;;Q_jketzztswqeb^ZRPSQJJFDRSdaZJNOWbjih_WlbUICEOZhp{€~}|||||||{zywtponnqrqolg]PC70+)(((')+18BJT[bgiiihhiiijjiigd___^^_^YWPLIGGKQXbjpuvz|}ƒˆ‹ŽŽŽŽˆ…xuux{||z{}}}~€€~|xqh^QD;44>K]m|‡‹Œ‹ŠŠ‹‹‹ŠŠ‰‰ˆ†€xmaWTT[agmqsspopqrsrsuwz|{zwuohaULIPb8876544200////..--,+++++***++-/1488:==@CCEFHJJPSUWYZ[XYXXRMIB;62.+('''')))(())))((''''''')''''(())))('((''&%$$$$%%##"!      !!!!!!""!"%'(*+.25:@ENXdjqsuy{~}~~|{yyuld\TMFC>>=<<<=<?DIOX`kv€†ŠŽ‘‡}qfYSV\`dgloqstvwwy{{|}}~|}}}{{€€€€‚‚€‚‚‚‚„ƒƒƒ‚ƒ‚ƒ………‡†‡…ƒ‚|xtmf`YVRONNPV_irtttssstvvw‘œ ž£ z(3EP]gu‡”“‘‰†€|zywwxy{zvkiaQRXYRRNKIJJIJOQTQQA6DA<;WT,(121<OgoWb^YTM7<AS^dquwxwvtvrdYOR[SNMMJKQ_[ZZJS_^_\I[aQ^laVHGJR\hu}ƒ~|||||||||{zxuromnmpppnjf\OC70+)(((').4<GMU`fhhihhhiiijjihea]]]\\YVQLIEBBFLSZbjpuvz|}‚„ˆ‹ŽŽ‘‘ˆ„|yyz{||z{}}}~€€~|zsh_RF=66?O`p~†‹ŒŠŠŠ‹‹‹ŠŠ‰‰ˆ†wl`VUV^djprsspopqqrtuuwzz{zxvrle[QNZi7765333110//..----+++*))**))**(+--/1325:;<@ADEHLORTVXYYYZXVRNGA;51.,)(****)())(()(((((''(())))))**+)))'((('&&&%%&&$$#"""   !!""""$%%&()-.046;@HOW_fimpsw{{}€€€~}~}{upicZSMGB?@>=>?BHOX`kt~‰”—••”†|reacgkptuwz|}}||}}€€~~}}}}{z{{{{}~€‚€‚‚€€‚ƒ„†‡‡„†‡…„€|zvsolgd_\\_fksuvuqsrstwƒš£¡¢¥«®¨h,>OZiu€Š‘•“‘ŽŒˆ„€|{ywwxzzzwnkcODT`XYQLMKLQRUUPJBOFE<=:BcXJVF0^ysrnW>QUQ:;JY_VivrpvxvvriURW]THJJJLRTMT[L[UV\U@`g^_nbRGHKValv~€~|{{yy{{{{|{zwsponllooonje[OA80+*)((().6>HQXbgijiiiiiijligida^ZYWXUOHEA=>CIPW]fkqtxz}~~‚…‡ŒŽ‘Ž‘‘‘‘‹‰…|}||{{{{||~~€}{{rh^SG=89BSds€ˆ‹‹ŠŠ‹‹‹‹‹‹ŠŠ‰‡}vj_VRW_enrutspopqrqvuvx{}~~|zwqjcYXbr7766433110//..----+++*))**))))'*))),+-.10258<=@CEIMQUVWX[Z[YXSLD?:61.-,+++*)++)))))))((((())****))****()(('&&&%%&&$$$#"""  !!""""$%%&'+-.0469<@HNUZ`ddhnpsxz||~}€‚€€|ztnha[UMGEC@@DINV`hp|†”—˜––—‘Šwmknrsuw|~~~~~}}}}}}||||||zzz{{{}~~‚‚‚‚‚‚‚‚€€‚ƒƒ„†„…†‡‡‡„ƒ}zwwtpnmrtwwwspnnx„—¡ŸŸ¡¨¬°±®’48IZiu‚Œ’•“‘ŽŒˆ„‚~|yxxxzz{{yrbNCPSS^XQQIMUVWQN><MJC::;:Dc^Rlc\pifƒZ<P[T==@FLBXŽ”{oxxzxrbVcbRIMKJJMRT^][VSJD[hgd^`s\QKJKXcny~€}|{{yy{{{{|zyurommllooonje[O@70+*)(()+18BKT\dhijihiihhhigeb`[XXXSNIDB>:;?DLSZagmsvy{}~~~~‚…ˆŽ‘‘‘ŽŒˆ†€}}}}{{{{||}}€}|zwri_UJ@:;EWfv‰‹‹ŠŠ‹‹‹‹‹‹ŠŠ‰…ui^VR[bhosttspopqqsvuwz{}~€~yunh`bmy775543120/..--,,,,++++***)))'''())))**))*-..0359:?CGMSVY[]__]ZVPJC?:631,,,+**++,+++++****)+,*,,,++**++))**('&&&'''%%$$##"!     !!!!""#%$%((,/0479:>@DJPQTW\cginqvx{~€ƒƒ}zvohaXVQKFGKRXagpz„Š“—————’Œxssvwyzz{}}~}~}{||{{||zzzzzxyzzz}}~~‚‚‚‚‚‚€‚€€€‚‚‚ƒ‚ƒ…„„„††…‡‡„‚‚€€}}}}~|xsv…—¢ŸŸš¦«®¯®«šA5GYft‚”•”‘Ž‰†ƒ||zwxwz{|{si`SSR\hbWTLNWXTRK85IC=;:7:>Thf^D,`UUoVRQZI<>KUH;V}zZTabfd_]ZasiGGJJILLTXXPMINQdc`SR_cnmNIP^hs{€~|{zzyz{{{{{ywsqnllklooomjd[PB70+*)*))/4<EMW_eikkhgghggfddb`[YWRPKFC=876<BHPU[`hotwz{}~}}~‚…‰ŽŽŽ‘‘‘Ž‰†‚}}|{{z{|}~~~}}zyvpi`UMB;=J[jy…ŠŒŒ‹‹‹‹‹‹‹‹‹Š‰„~tg]WY]flstutsonpqpsvuwz|‚‚}ytnjnv€55443211..--,,++++****)))(((((('''''(()))())*,.1258>CHOUW\^`^^\ZUOID@=731/-++,+,,,,,++++++,,,---,,,,,,+***)'''''''%%$$##"!     !!!!"""#$%((*,/257:>BDDDEHLSY^bfimovyz€‚…‰‡„‚|yvpid`ZVUWZahny‰‹“––””“‡ywwxxywz{{z{{yxyyyxxuuttrrrstuvvwwzz}}}~~~~||~~€‚‚€€‚ƒ†‡ˆˆˆ‰ˆ†……………‡…ƒ€“ž ›ž¡¦ªª¨¦¥ž–T1HXguƒŒ’•”‘Œ‹ˆƒ||xyyz|~}|xrd_VWadb[RPSPRVPK7.38;;88>CLbqkDVvkYTZm_P@>?QJA@B:9<=<<<==GOQe\BEJKKKHOPUSPQRVWP=MOTTabWJVakv~~zzzzy{{{{{{ywspmllkloopnjd[MA60++*)+,27AJRYagjkkjigfffdbb^ZVSOLGB=77337<BHPW^ekouy|}}~}}~‚…‰ŽŽŽ‘‘‘Ž‰†ƒ}|{{z{}~~~~}|zxuohaYPE?AL]l{†‹ŒŒ‹‹‹‹‹‹‹‹Š‹‰„~tg^YYahovvtsponpqqrvuwz{~‚„…„}yutx‡5554200/.--,-,++**(((())''''((('''((''(''())****,./5:AFNUX\^`a_^[XROJEA<;80--++----,++,,,,-...----..,,+*)))(''''''%%$$$$"!       !!""###$$%'')+.1369=>>??@DGLQW\`cgimpuz~†‡†‡„€}yuroieddfkpx‚ˆŠ‹Ž””“‘‹…}xtuwuvvuuvuuwtrromkjjhgggeffdfiklmpqrstuuuutuuttuvvwxy|}~‚‚€……†ˆ‡‡‰‰‰‰ŠŠŒ‹Œ‹‰“Ÿ›™› £¤¤¢œš–”‘s3DXguƒ””““ŽŒˆƒ}yzyyyz|}}wsic][ddecXXXYVVSC62/7=<:7>KSxx]HPhpjgXUQQ@A?<7>BDFGGFEGFFMTF?BBCMPNKKJIIOVWYSEEO68FUUGCXMXdmx€}zyyyy{z{{{zxvsomkkklmonlhbYK?40,+,,.18@GNU\djljjhhhgffc_^ZUQLHB>:4/136:@DJQY`hmswz}~~~|~‚‡‰Ž‘‘‘‹ˆ„~}{{z{}}~~}}zyvrngbZPGBEPao}†‹‹‹ŠŠ‹‹‹‹‹‹‹Šˆ…}rh_Z[ckswwvspmnqqqrtvwwy~ƒ‡ˆ‡…‚||ˆ334211//.,,++,++**((((((''''((''''''&&''')))******,.19?DLOVZ]_aa_ZXXUQKGB>730..-...-,,----..........---,+++*''''''&&%%$$#"               !!""###$$%'')*-0377;<<<<?CGKPVY]]`dfjmrw{€„ˆˆˆ‡…}}xusqprt|‚ˆ‰ŠŽ““’Š‚zurqsrqrqoollgeeeaa^]YXWUUVWWWZ\`abdhhiijjjjihhjjihiknortwz|~€‚„„„ƒƒ„…†‡ˆˆŠ‹ŒŽŽŽ—š˜”˜ž¢¡œ”ˆ€|’‚AFXguƒŒ’”“ŽŽŒŠ‡ƒ~|||zz{z}}{v_a^V_^ddZWV^_QWC9329;;978@HE5=IKCAloiUG>:CA=GDB=<;;88599@TNF@?EJJLKIFHNYb[UMFJUWNEKJEWNU\eqz€~{yyyyxyz{{{zxtqmmkkklopnlhbXJ?4///0259=DJSZ`gkkjjigfffea_ZVRKDA;60.,/25<AFMT\cinswz}~€€€„ˆŒ‘‘‘‹†…ƒ€}|zzz{}}~~}}zywtohd\SJEHRcr‡‹‹ŠŠ‹‹‹‹‹Œ‹ŠŠ…}re]\ahmuxwuspoppprqrtuvy~ƒ‡‰‰ˆ…‚ƒˆŒŽ220000..,++*))****(('''''''''(((((''''&'))))********-06:@GNSZ\\[^_]\[XVSMIC931...0.//..//////////.//---,+++*))((((&&&&%%$#!!!!     !!!   !!"#$$$%%%&()*+./369<===AEGLPTVXXYX[_chouz…ŠŒŠˆ†ƒ€}|zy{}„‰‰‹‹ŒŽ‘‘‘‘‘Ž‡~sqpmmjjhdc`\[ZXTRPOMJHHGECDHHIKMRRVXZ[^```]^\[]\^_\[[]]aejnrux{~‚‚„………††††‡‰‹‡}„•—•“–œ¡¢™‰|y{pxŒŒ‹‰\LXhv„Œ‘“’‹‰‡ƒ}qbozzy|€}‚~i[WXZ^dhYHJNK=KG7C::;95669;D;7?GAMSSvdP?<CCJH?F8Jr}wsnVT=MjPJCFJHGEFCDGOXVONKFDGGEWIQYSS_lt{}}zyxyyzzy{{zyvtqnjjkllnqomgaUH@64579<@EHLRV^dillkkhfgddba\WRLE<72-))*.27<CHOX_gjpuwz}~€€‚‡‹Ž‘‘‘ŒŠ‡„‚€}{||z|~~~~~}zywsoid]VMHKVfuƒˆŒ‹‹ŒŒ‹ŠŠŠ‹‹ˆ…|sf^]cirwxwuqpqqppqrrrrsv|‚†‰ŠŠˆ‡‡ˆ‹Ž110011/,*)**(())))((''''''''''''&&''''&'))))))********-28?EJNSWYZ]_`a``_YSLD:200.//00///000000000/00...-,,,+))''((&&&&%%$#!!!!     !! !!"####$%$$$%%%&(+,+.057;<=@@EIJMOSTTUTUUW[^fmu}‚‡Œ‹Šˆ„„…‚~„ˆŠŠ‹ŒŒ‘‘‘Ž‡zrkhfdb][XUSPKHFB?>=;8776789>ACEHKLPSUWYWWVUVTSRQQPPOOOOQTX[aejovz}„……„„…………‡pŒ”™›—‹}~~|n|ŠŒ‹sLYgv„‹“‘‹‰‡…‚iamcz…‡ˆ‚wjb\VTa\FCHQRHRb]L::;6565649E@6Xh_UNTYOF;?<@AEI=4c{nWdjMKLHJIKMJFCBBAAHLMMKE=?@@KPEWX\_blu|}}zxwwxyyzzzyxzzrkkhgkklookf`UJ@::;?BDHNRVY]bgkmmiihhffd`]XSNH>5/,)))*.27<CHOY`eksuwz~€ƒ‡‹Ž‘‘‘Ž‹ˆ†„‚€}|||}~~~~~}{xvrmie_XOLNXhv„ŠŒŒŒ‹‹ŒŒ‹Š‹‹‹‹ˆ„{qg`agouzzwurqqqppqrrrrrty~„ˆŠŠ‰‹‹‹211/00/++++*)(((((''''''&&&&&%&&%&''''(())(())******))+,.4:@EINSXY^`abbde^ULA610/.000001221123311111////..-,++*)))(('&&&%$""!!     !!!  !#&()('&%#$%%'$&)*+,/259<?BEGIKNMPRUUWWVWWX_cjoz‚‡ŒŠ‡……†††…„„…ˆ‰ŠŠŒŒŒ‘’‘‡|qf^]ZURNIC?=:9521223022259=?BFHJMPSUUWWWWVVWSPONKHD?>::>BEJQSY_dipw}€ƒ‡†…ƒ‚ƒ„‡ŠŽ‹Ž—œœ”ŒŠ„wsƒ{r|{{‚ZZguƒ‰’Ž‹Šˆ„†‹wpqro‹””‘Œxkoh]Xfc][FGOZcmf;MG:78678659BDEZ`TOHIJ@@=?BNZcH<2Wzm]MPXRNJMNJGFLMFAA;;?DGIIFIJLJOO?XXRbhox~~}|ywvvwwvyxzwvohoz‚~sljorjig\SLHCEGJORTWY[`fhjklkkjhgfda_[VQJA8/+(()((,38;BLSZagmrwz{€€€„†Š‘ŽŽ‹ˆ…ƒ}}{}}~~~~}|{xuqmjfaYSMQ\lz„‹ŒŠ‹‹‹‹Œ‹‹Œ‹Šˆ|rfcgisy{zvvsspooopqrronquz…ˆŠŠŒŒ‘‘1//.--+*+***((''''&&&&&&%&&&&%&&%&''''(())**++********+,,,059?EIMSY^bdfiif^TH<3101/0111122110222111100//..-,++*)))(('&&&%$""!!     !!  "$',/00/-+'&%$&&'(*+/359=@CFIKOPPQRRTVXZ\]]^aejrx€†ŒŽŒ‡……†ˆˆˆ‡‡‡‡ˆŠŠŠŠ‹‘”““‰|l\QNLF?;9531./0....-/2336<>BEHKMPRTWWWWXXWVTSRNJFD>:41/..28=BIOU[`gnvz~}€zvy‚Š‘™›™•‘ŽŽŽ‰{nsmly€Ž›–v~v€Ž‚zƒ‹‘“tp}px’”‚cagjcU\[\PPOIZdX9MK=8878;76=?GcTN7<68=FDAACKW]CF<a\be[@?JDNZVPHFFHC=>;8=AGIIJLLNOQXZXYXZepy}}|{xwuvtyxssvpfJL[p†™`X\SGK[^YQLHJLQVXZ[^cfkmnmnljihgecb`\TMG=4-*(()((,27=ELS[ahntxy|€€€„†Š‘ŽŽ‹ˆ…ƒ|{zz}}~~~~}}{xsolifa[URU_m}‡‹ŽŽ‹‹‹‹Œ‹‹Œ‹Šˆ{sifimtz{zwussrpoopqppnkmqv{†ˆŠŒŽ‘‘‘0/..--+)*)(()('&&&&&%%%%&&&&&&%%&&''(())))))********++,,---.06<AFLQX^dglmke[NB711222122233333222222210/.------+***(('&&&%$$"!      ! ! "&+/4<>>>960,)(')))*.169=BFGJLOPRTTTTVZ\`deeefiqu{€…Œ‰‡…†‰Š‰‰ˆˆ‡ˆ‡†ˆˆŠŒ’“’ŒˆzhREA=9731000../----..048<?BFIJLORRVXXZZZZXXWSSMKFB;60---++,017;AHRY`fmpvuŒ’“•šŸ™„m‘‰’’‘’ƒ¡´¼½¾¾¾»°ž‘}y‡qt‚‡ˆzY{ƒkz‹‚mcuxwj\fjkheb`RTUKEOb\+(=><;9;@E<98:FC@G?:987L@ACEJUSFI_]SZeRRX9BhrhUIFDABB?:7;@CGHIKMPRRUX[[X`foz~}|zwvwuuyt_`whbkrnna`JGFINNEYb\UPPQVY[]`deimopomkijhhgee`]ZTLD;1*)))())-49?FNU\cjpuw{}~€€€„ˆ’Ž‹‹‹ˆ…ƒ€~{yyz}}}~~~}{yvspliea\WUXbp~ˆŒ‹Š‹‹‹‹‹‹ŒŒŒ‹‡€{slkmrw{|zxtssoonnpqqnkhhlpv~„ˆˆ‘’/...-+*)()('((&&&&%%%%%%%%%%%%%%%&''(())))))********++,,,,,-,.29>CKQY`hmrqkcUH:32222223344444333333321/.....--+***(('&&&%$"!!        "%*/39@GKKKGC>70+)*,-/157=AFJLOORTUVVXX\`ehlmnnnprx}†‹ŒŒˆ†…†ˆ‰ŠŠŠ‰‡‡†„††ˆ‹Ž‘”Œ‡{iQD<77353//....----0036:>BDHJNQQRVWXYYZZZXWUURNJF@951-,,,++,,-05;DLT[beuŽ”—’”•™žŸ˜ykomŽ’‘’’’¡¶»¹»½½½¼»»´–‡ƒˆvpihjk_]`vwy{kUVrƒnUZjmjll`]TQTNJSvu<413;<<:@KG847?FDLE;<9;J<ACEIUKH=MieZVJVO;nnniXLE@>=>A<8:<@CDGIJKLNQV[[X]gqu|}xxtsvvmUsmld]^inf^CDNPQJDH]le`ZUTWZ\^adfiloqqomkijhhgee`[XQJB90)()))*,08;AIOW^ejpvx{}€€‚…ŠŒ’ŽŽŒŒ‹‹‰†ƒ}{yz{{{|}}}zyvsqnjgd`\WW]esŠ‹‹‹‹‹‹‹‹ŒŒŒ‹‡€{spnquy}}{wsssponnnnnkihijmqz€…ˆ‘’--,,++('('''&&&%%%%%%%%%%%%%&&&&&&''(())))**********,+,,--..--.27:?JR]hmqsodXK=42222123444443333443212311/00..,,++))('''&%%#"!!!   !"#$(/5=GMRVY[VRJC<60./0449=CFJLORRUUWZZ[\`bfmrtsqqsuy~‚…Š‹‰†……†‰‹‹‹Š‡…„ƒ‚†‰Œ’’Ž‹€o]RLD<84541--//---.2268>BEIJLOPSSVWYYZ[ZZYWUTPLHB=61.++,,,,,,-148?INTYm‘™––ŒŽš”‘}]5c…„‰‘””Ÿ¸¾¼»¿¿¾½¼¾¶³º¤„ˆ†‰|_Rgcspgwz{zlW\dXL[cfb]agWHGNMLZmhJ:9ID><8DA9673EYSA39<<IMBDECJVED9Mwpk2B@Auyng`RNF??=>><;:>BDCDFGFHJPSWY[]gqwxzyvtslrnmorfG6@daHKKLLHFL\kpkhc]YWYZ_achikopqpnljhhhgfdc`ZWOG?5-)'''+,04:ADKRZ^emrvy{}~ƒ†‰Œ‘ŽŽŽŒŒ‹‰‡…‚€~|zyxy{{{|}}yvsplihfc`\[Y^gu‰Œ‹‹‹‹‹‹‹ŒŒ‹Š‡{uqruy{~}zxtsrppoooopmjgfflpw}‚ˆŒ‘’--,,+)''''&&&%$$$$$$$$$$$$$$%%&&&&''(())))********,,,,----../1/.24;DLXbjsvqiYL=53323234444556666444323331/000.--,,))))('&%%#"!!!   !"$(-5>HRW^degfaYQGA;5457:?CGJLNQTVYYZ[[\`ejnrvvvttvyy~‚†ˆˆˆ„„…†‡‰ŠŠ‡…~zyyzƒŠ’‘…ylc\WPID:71./..---0168:@DHIMNOPSSVWYY[[ZZXXURPJE?94/-,,+,+,-.036<BHNTT…ž™š~kyn]pxŠ•˜•Š{\]„•¶½¾½¼½¾¿¾¹¦ls³¸°†˜¡wIZhuz|{{{scRWbOQQ_QAAKX^QNLIOLQX>8FEA<5COQ987<I`JLPNUOCDBRLJTBF<VxkD><<qywqefXHFFDB@=:9;=@CDFGHIJMQRVXWWhuxw{yyvsn`dmjoji_Y_OJKKHDSeklnnmkfa\Z]^bbeglmmooomkjhhhfecb^YUME=4,)'''+/38;BELTZ`hmrvy{}~€€‚…Š‘ŽŽŽŒŒ‹‰‡…‚€~|zyxy{{{{yywtrojggec`\[Zakv‰ŒŒŒ‹‹‹‹‹‹‹‹‹Š‡{uqtw{}}zvusrppoooopmjgffinu{…Œ‘Œ,,,+*(''&&&%%%$$$$$$$$$$$$$$$$$$&&''(())))******++--------..1311238>GT`jstqj[M<54433245544666644555434331/011/.---*)**))'&$"""""  !#&+3;GPXahnoqqlg]TLF?<:=ADHJKPQSVX\[\\\`chnruvvvuvvx{~‚„‡‡†„„†„„…„‚‚~yvvslou|‡Œ’’ŽŠwqmia[VOH?93/-.-/038=@BFIJLNPQSTVWYZ[[ZXVUTRMIB<72/-,----./028=@FKOTqœœ ¤“rYghu€w”Œ‰Švvo»¾¾¾²°¼¾¿½¸“v§º¯…˜ƒQ<H^ov~xtwzoTAsgZY\^H=?;<MaPMNMKBKOD@@A=8BID89689>6OVO@KCFC^YLQAE:nyM0=Bprwxteh^JGGDC@:78:<>ACEFHHJPUUUXQXmvzxxsHZspgZafeqo_TLJNNLOflkllmnnkhd_\]]_`ccgiikmkkjjhgfedc`]XRKC:1,)'&(,04;>BGMV^bhptwz|}~~~}~ƒ†Š‘ŽŽŽŽ‹‹Šˆ‡…}{ywxy{{{zyxurnjgefdc`^\\dnyƒŠŒ‹‹‹‹‹‹‹‹‹‹‹Š‡{usuy|}~}ywttsppoopoolifceintx~„Œ‘‹++**)'''$%%%$$$#########$$$$$$$$&&''(())))****++,,-------...1311238>GT`jrusiZJ=4343335665566665555543433211010.---,++*))'&%###""!#(-5@IT^fouyzxrlf_UQMGEGJIJNOPTUX[^]___aeknotvvusstuy|€‚„…„††ƒ€~~~{wsplgc^agq‡Ž’‘Œˆ~xxuqnkd^VL@91./158<?BDHJKMNQRSTVWXYZZXVUTRNID?93/.---,,-.148:?DHKP_–œœ¡¢£š‡{‰ŽŽxm`yu{ah|£¹¾½ºž™¬·½½½¬‰“°¥‡|˜ŠiOTOnzoY^dlmlej€e]XTL?:9>EITRMKKKTMKEAB?><CE?=;:;A:;KLIA@EFJWXPJCB>zV12?b_fvvsk^YQFFFCB>;98;=>BDGHKLOW][YYdmvywuq;Qsd>[okvwNCSOJEQbihgjjlnoomgc_\\\\^\\^adfhjjjiggfecb`\WPIA80+('(+.38<?AGNV]dkptwz|}~~~}~‚…‹‘ŽŽŽŽŒŒŠˆ„‚|zxwxy{{zyxwrolhfdecc``^_hp{…ŠŒ‹‹‹‹‹‹‹‹‹‹‹Š‡|vtu{|~}{yutsrppooponkgfceinpw~„Œ‘ŒŠ)'))'&%%%%%%$$##""""########$$$$&&&'(()))))*++,,++----......141/238>GU_jtyrh[H;33356556666666666666655554432110.,.-,+*+*'&%$##"!!!!#%*18BMW`hry}{ysoic^ZWTSNNPTSSRTWY[_``aacfikorrtsrrrtvy}~‚„„ƒ~{xtplgc_XQORYeq|†ŽŽ‰€|}||yxtnibYNB;65:=@@DGJLLMNOPRTVWXZXVWSROMID>:630..//..1358<?CEKRR{šš¢žš‹ij¥˜ˆ…„hZT^f|Ÿ¶«»¼±›¥¯¤ ²£†}• ˜†Ÿ’}^^tq_YLKShi]iniq^XR::;=?8JPOFLFESKEDHJLSB8<?;:;=PMSHGPLAD@a]RQAD@Jh27;MZ]gtupj_UNJFBCCB><<>@BEFIJOPRU[^Y\bnvxwttqusdQdovmK?GKJGWljihiklknnmjhb^\ZZWTRSUY\_fhjjiggfeca^\WNG?5.(&&*,059<@DHOV_fmquz|{|}}||~ƒ†‹‘ŽŽŒŒŽŽŒŠ‡…ƒ{yyxxyyyxxvspmhebcecda`aelt€‰ŒŒ‹ŠŠ‹‹‹‹‹‹ŠŠ‰‡…‚{vwxz}‚{yvsrqoooopolkgebdglpv}…Š‘‹‰*)(('&%%%%%%$#!!"""""####"""##$$&&&''()))*)*++,,++----....../321238>FS^itxsh[J;54456556666666666666655554432110110-++**('&&%$$"!!!##$'*19CMWbjrvyxvpqlhed^\[YWZ\ZZY[\_aeffffhijlpqrsrrqqqty}€€~}yvrmhd_[YTGABDMYgv„Ž‹„}{}~~}zvskdYNC??@CDFIKLLMNOPQTVWYXURSNMMID?:842/////1258:>@CFHJN^•ššžŸ—ŒwW\‰¤§–„tbYadIZ¾®†²µ©®nq‹¡š}e™Š™‹gagf]cdYTWf\Teiic\bR;<>D=<FRNJRQCINOQMNRZE<>E=8;:H[fLKPCCBG`RUXAF=W=>CGPXKNqupg_WNJCACC@=<>@ACFMLNVYWZZ[]`hrxyvupoqpnnryfJBJJCAJbefhhhhklmlkie_[YXTOMJLKPY_cgijigfedba]ZUNG>4+'&(+.059>@EKRXbgnswz|{|}}||~€„‡Œ‘ŽŽŒŒŽŽŒŠ‡„‚€~{yxwwxxxyyvspjfb`adddaabgoxƒ‰Œ‹‹‹‹‹‹‹‹‹‹ŠŠ‰‡…€xvuw{~zwusrqoooopolkfcbdfkpv}…Œ‘‹‰)(''%$$$##""""!!""""""##"!!!!"$$&&&''()))*++++,,----....----/133128>HT^juxrh]L=56665576666666666666666665444221000/.,+*)'&'&%$#"""""#&+2:CMW`gnopoomljjjhgcb`^^__a_cefhlkjiijjlnqtsrqonpqvz~€|zxvqke_[WRNJG@>@BFP`qŒŽ‰zuy{~€~}yuoeYPIHGGGJJJJLNNNQSUVVSQNMJIGD@:6440012357:<>@BEGIJPS„ž˜œŸ˜’vYQx–˜~wf‡_( }½»©„}—¬®w[e˜‰>Z“ ˜zUY\]twm_\]ZSVmhghVHE9=MSF@>Td\`u[FLNNGCUA=@=CA779DWS?5CBDC;@O\O>D?;9@JMUSLYjnqjZOMHB@BB?<:=AACFSUS]bba`_^bjsxxwsprpkHTxvFFMNFLgjfdfeegijkkklf`\VUQOGC@CDNV]dhiihgfcdca]ZUME<3,(')+/25:?AFLR[dipux{{||||{}}„ˆŽŽ‹‹ŒŒŽŽŒŠ‡ƒ€~}{ywxwxxxwvtqlhc_^^cdcbaejqy‚ŠŒŒ‹‹‹‹‹‹ŒŒ‹Š‰†ƒxsuw{}}|xutrrqnnooqpljgcbeglsx†Œ‘Œ‹‰(&&&%$$$""""""!!"""""""""!!!!"$$&&&''())**++++,,--......----.022128>DO[epvtkaP@77765556666666666666666665444223200/.,+*)'&'&%$#"""""#&+2;AKU\ceddcacfijjjhgecdceffhklmopnmmmnnnqstsrrppqvz|zzzwupkf]WQJHDDA@>>=>BJZl}‰Œ‹†|rgkqv{~‚‚ƒ€}{tle[SNKIIIJJMMNNPRSROKKIFFDC@;863322579;<>ACDFJLMQQdŸœ œ‘ƒ‚…cQf„ƒ†ƒƒŸ›Z*#x¼»´¥‚]|œ›ˆbVkŽ{lp–¤fC\_cz’’vmdb\haV\X=9?DKWYD9BBc\WbYKFC@:LT38>IJ<435>FJHDAG@E7@GT=@<=:H]X[]?EOM^^_ZO??@ABBB@=>AACFTYW_cecbabgltxwtsl`\rlf_TMCL[dsmhedcbcehjkkkhc]YROJC:76<DMV]fhiihffccb`\XSKB80,(')+/25:?BGLR]flrux{{||{{{}}„ˆŽŽ‹‹ŒŒŽŽŒ‰†ƒ€|zxvvvwxxvttoke`^]]`cbbcfms{„Š‹‹‹‹‹‹‹‹‹‹‹Š‰†‚~xsuw{}}|xurqqpnnoopoljfdeeiorz‚‰’Œ‹‰&%&&$$$$$#!!  !!!!!!!!""""##"!$$''&''()*++,,------....--....0/01016<DLXfnstmbSH=6566557786666666666677775544442111//-,+*(''&%%#"""!"%&+29AHPU[\XTRV\afjlkiggfhhhlllnprrrpoopprttwxtrrsrsxyyvvsoje_YRLD@?@@?===;=AHVgy‡Š‡ƒwhXZaipw{€ƒ‚‚„‚€{uof\UQNJIJLLNNOPPNHFDBEDBA>;7557879<>?BDFHKLMOPQTƒ£Ÿ¢Ÿ™‰pˆ‹uPW|{vs{ —@*#hº¹¶²¦…`dvƒƒi`}‡}pc„‹ODfrŽˆ’Š}|cacSRX\R3>KS^kF/05MSMQJIFDDDW;88=@732548DD;>?BAS@AF@=BJRHVgQQW@F@0OOMP@;?DFHB?>?@BBDHQYZ_fgddefinuyxuqpc]jgJHSNMYesnieccbcceeiihgd_ZRLG@9215:CLV]dfhhfeedca^[XQIB7/*('),046<BCHOW_hmrwyz|||{{{{}…ŠŽŒŽ‹‹ŽŽŒ‹‡„€~}|ywvwvwwwvurmic]Y\[_accdhpx~ˆŒ‹Š‹‹‹‹‹‹ŠŠŠŠ‡„€ytrsw{||{xurppnnnnonmljhgefinq}†Œ‹Š&%$$###!! !!  !!  !!!!!!!!""##$$''''())*++,,------....--....///0004:@KWbjqrofYND<786555555665555555566665554443111/,,+*)(''&%%$#""!"#%(06>CKQSSOJIOTZaeghghhgijjmnpqqqrrqqquuw{{{zwttuvvwutrolga[SKD@>>?>=><<;<=AGRcx†Š‡‚ucOJOXbkrz…†‡…ƒ€yvod[SOKKLLMMMMHFCA@ABCBA=;<:9;>AABCDFHJLNOSUQScš¡ž—‘qY~‡t^Md}{vqu‚2**Mµ´±°«ˆrijmohu|mdtvb>>Xƒ¡™–•Œuf[UKMX_^GKBFZUD329>5:NIIC>;FS:589<F;2228@NF=?7NYQYK9BCQAHVUORN7@20IKY@6:>CFIFA??AACGHU\YZchceagmr{wsj^gg^^RGF::KS_rmiecbadddhgggf`]UMD=5-,.3<FNX_dfgfeeca``^[TOH?7/*('),069;?CHOYaiouwyz|||{{{{~…ŠŽŒŒŒ‹‹Œ‰…‚}}zywuvwxwwutqlfa[XWZ_abcflqy‚ŠŒŠ‹‹‹‹‹‹ŠŠŠŠ‡„~vqpruxz|ywtrppnnnnnmkjjhgeehmq}†‹Š‰&$$$###!   !         !!!"$$%%''())))*++,,--......-.////....//0027<FQ\fkppibWMC<97556345555555444455466653323311/-++*(((''%%$$"""##%).3:>DHKKHGFIOV[^`adcegijjkmopqqsrstvwxz{{||ywvvtrppolie^VLD?@?=>====;;;;<?FPas‚‰‡‚wdM;@ENYcmx„ˆ‡ˆ‡…~yuk_VPMLMLMLFC?;::=ACCCCCCCDDCDDDGJKLNOQOQRUUp£¡œ™”ƒJLnƒlPOqxwwp‚p3105£®§¨¤Š€xj`TYWfjcmlhS8?Tƒ¥ “—’’”tI<^ob[TNLFCCKRD3@D9::8>G43BKK?3A>?713059DC><Pe`i_;=<ANQIEOHMM;<F=C@?817?A@@AA@@AAHIJMMLR`hgfZ_pedcTKDEJEOOJ@BNCIdumgdabddcefhhfc^XPF<3+))/5>IQY`eggeddcb`_\XUPG>4-)((*,058:=BIRZbjpvvxy{{|{zz{}†‰ŒŒ‹‹Œ‹‹ŒŒŒ‹ˆ„}|zwutuvvvutroje_ZUWY]`adhptz„ŽŒŒŒŒŒŒŠŠ‹‹Š‰‡ƒ}tppptvxzxurqqonnnmmnlkkiifghms~‡ŽŒ‹‰‰$!##"!          !"!"$$%%''())))*++,,--......-.////....////029AKW`ekpnh`ULF>;:86644445555444455466665323321/-,,+*((((&%%$"""##%&+039>@CBBCGINSWYX[\\]_aadgikmpqtstuxyy|||||yzxuqnlifc_XPGB?>>==><=<<::9:;=CM^p€ˆ‰†|jS715=HO^ju}„‡†‡‡…‚~{vpi[SOMLKHB?;;;>AEFGGIIJJJJJJJJLMNOQRRRRSWVv£ž›•Œn:Ic‰ˆxXNYrxzx„`854.z¤Ÿ¢¤–‰~mdXNB?D]jhcJ<EQ~Ÿž˜™¢Ÿ”cCN|}vmd`SJPYXZPG<:FG:;=EA?ADUPBA705=6,036:?UbYVN<;=D^XHDFHQ]WLJMKM@>@;<?>:;>@A@>??CFGHITahk\FNN`kZOT]T4/@HCAFGGTrrlheddeccdeihe`[UK@5-())/6>IQ[bfhgedcbba_\XTOE=3-)((*,058:=AJS[bjpvvxy{{|{zz{~†‰ŒŒŒ‹‹‰‰Š‹ŒŒŒ‹ˆ„~|{yxvtuvvxwvtnic\XTTX\`aejqx~ˆŽŒŒŒ‹‹‹‹‹‹Š‰…€yollnpvwzxurqonnnnmmmmmkjjjhjov€ŠŽŽŒŠ‰‰"!!!  !  !!!"!""#%%''())))*++,,--..//......00......,//15;DNYchopkd^UNGC@=:85331444444445566666544332//-,++)()''&&&$$##""$&'-15;:<;=?CEJOQTSSQQRTY]`adgjmprruwy{}€€€~{xtqmid`_YRLE><<<<<<<;::999999;>IYm~ˆŠ†€q\>*+/7?KVdnv}ƒ†‡‡…„‚yri]SLKGDB=<;>CGHJMNNPRSTSPOOOOOPQRSRSUVVV|£ž˜‹j6Ua{Œ}dRLfu}‚‰V9788I”˜ž£”…}wl`ULFI\c\ZGAFJr™•’”žžzZs‰yli\ZV]lqyvjb[TUVUU\hPC?;FNI;019G7--/48Kf`URP=>CJA=>JMFDMNI>ALVVVSWF:=A=:>AACEGEAMRQ^SOY\IERZZdY[TC:>9EG<0<Rpwrooihncjhbbfeea[SH<1(('*/6?JS[cefgfdbaa`_^YRMD;2,**)+-1578<@IS\dlqvvxzz{{{zyz€‚‡‹ŒŒ‹‹‰‰‰‰ŠŠ‹‹‹‹Š‡ƒ€}{xxvuvvvvuusqmh_ZVRSW[_bgmu{‰ŽŒŒŒŒ‹‹‹‹‹ŒŠˆƒ}tniilpuwyvurqonmmmlnnnmmlkkiioxƒŒŽŽŽŒ‰ŠŠ"!!!    !!"!"##%%'(())))*++,,-...///.....//......,-..15=HQ[dhmmhd\XQLGE?<96334444444455666654443311/-,++))(''&&&%$###!"%$(-243578:>CHLMMKKLLMOQW[adgjmprrxyz|„‚~{xsokf^ZWSMF?::;;;;;;::99887777:=DRey…‰†‚yhL0*),09CMZfqy~‚„„„‚€vmbUKFA@CCCEHKNQTUUUVWXWUTSSQQRPTSQUTUTZ‹žœ—s,<Xq†}hMGLfu|uJ:;<<:gŽ‘–†wrtmeYPPTZUQQIFGGfŽ‹‡‹“—•‰}|]NQTMOUNRn‰Œps…pbZMFKXONF;GO@2.37<8/-..3<?C?KVJMI;78;;:<>>A=8:;<CHJMP@ADA>?AABDCCFJJIMRPHCPQBEJITS@?B@AKQfktyxunftxwdX]T^^cfea]UF;1((')07@KU\dfggfdbaa`_\XRMD;2,)))+-1578<AJV_flqvxyzz{{{zyz~€‡‹ŒŒ‹Š‰‰‰‰ŠŠ‹‹‹‹Š‡ƒ€}{xvutuuuuvvtplg_XSOQU[_eiov|‚‰Ž‹‹‹‹ŠŠ‹‹‹Œˆ†zohdgkpuwwusqqonmmmlnnnnnmmkkms|†ŽŽŒ‹‰ŠŠ!!       !!"#$&&'(()**+,+,,.../////.....----//.-,+,-,17=GQ\diiifd_ZUQNID@:653333334444554443332210/.-,,+*)('&&&&$$$#""#$$(-0132689>ADFHHGJLNQUZ[_cfknrrsw{|€~€}|ywqngc]XPMGB=;:::9::99998876666679>K_r€‰ˆ‚}nW;))')-4=IS]hoxƒ„„‚{uvxpaTIEDGIJMRUY[]^]YWXZ]ZXVVUTSRSTRSSV]b•˜˜•Œ}+9N`{ycNKDIPRIA=>>=<9n„Šnmjb_WPPSQJMPIJGEJvˆ„‚€ˆ’‰~[AIOMLJE>5?[ajte[NRWHJL=?:52892550-*'*1;?>TL=74774395358;;:98==;:BQDA?EMGCA=??BGIR^Z]dTV^\J=RZQ:@LGEPapvsswtssmpieJSAH]cegea[SG;1+&'*19BKT]dfggfcbaa_^[WRJC92-*+),.0468=CLW`gmrvxzzz{z{{z}ƒˆŒ‹‹Š‰‰‰ˆˆ‰‰ŠŠŠŠ‰†„€~|xvvuuuuuvuuoje]VQOQW^bfkqy}„‹ŽŽŒŠŠŠŠ‰‰‹‹Š‰†‚~vmeeejnswwtqoqponmmnmnpppnmnlpu~‡Ž‹Š‰‰‰!!!!    !"#$&&'(()**+,,,,.../////.....------,,.,,--047@FR[^cefeb`[XUSMHE=643222344445544433344100/-,++**('((&&%#%$$##$$$'+,-3789=??@CEFMRU[^`dgiklnquwzz}||zwvsojd]WPICA?>;;88889988887765555548:FUj{…‰†‚vdG-(&()),5>HU]gpv}|pe_f{xpeZONPVZbilnooplf_ZY[_^ZVVVTTRPOPPOOY™ —–”Œ318VnpSJPHA<;=@AAA@>7Er~sedaXZRKNNJKMLFGGJLYu‡…z{”ŽwF:ABCAA@>;6/2V€Œ‡vb`UQSI=D98849?=2.1/.-)<A98<86347;<AC:43662<BCG<99;=FFB>8<?@A>AECBIIYQjuMPipraIA@HIH=ThnpqrjZpfl^UR@@LU]chedb[SH:1+'(,2:CLU]dfggfbbaa_^\XRJB:3,++),.0158=ENW`iptvxz{{{zzzz}ƒ†Š‹‹‰‰ˆˆˆˆ‰‰ŠŠŠŠ‰†ƒzxvvvuuuuuvuuoje]VQOQW^bglrz‡ŽŽŒŠŠŠŠ‰‰‰Š‰‰†zrha`bgnsvvsqoooonoonmnpoonmnntzƒŠŽŽ‹Š‰‰‰!###!   "##$%%()()+++,--,..../.././/-----,,,,,,,-,,,.18@HQVZ^`abaa`]ZVPJE@:53322333344334333320/00.-+++*(''''%&$%##$$$##%'*,/37;>@?@CIMVZ]aiknnoopsvxwywvwutqnjc^XQJC<98;<::876567776666542333356=L`s‡ˆ…|pW9'%%'((,/7@KVajojdonSj€}th_]clv}€„‚~}}unghhie_YVSRPNLKLJIGL” š”ˆƒE.6Og\GIRJEB?@@@?>=26FQqnc]ZWVPOMIHFKLIIPRWZXix|†•ŽmC;<;899:9763/;f~††saSNICEKJ=26J;4,34/+*3?=DE953496<BD<7655434334577::>JVI60,38:<E?;=@FZ\QCL[gb]HAHJE=YmmmprtZClvt†FW`WGIP[fghgb[RH:1+)*/4;DNW`dfggfdba`_^\YRIB:0*()*-11479>HSZckquxy{|||zyyy|€ƒ‰‹‹‹‰‰‡‡‡‡ˆˆŠŠŠŠˆ…ƒzxwvuuvvvvuusmgc\SONSY_cgmt|ƒ‰Ž‹‰‰‰‰ŠŠŠ‹Šˆ…€ymd]\`gotuusqonponnnnnnnmmnnqqv}…ŽŒ‹Š‰‰‰!#%%"   ! !#$%%()()+++,--,......././/----,,,,**++,+,,,,16?FLOSX[]^`_`_\WSNHA:532233334433433321///0/-,,-+))'''&&$$#$%$$%%%'+059=ADFJKOU[^cfjnrrstvuwwwtsqomkif`\VPKB:756889::9867566655554331111237BVjy„ˆ…‚yeF,%'%')*06;DSbmhk]dxqxyxyrsrwƒ……ƒ†‚‚……ƒ}~xpg[QOLLGGECCCAzž•Š„ƒY.5A`VCHMJHEBCCBA@?^n^BXlg_XSRNOMKGHMMKMLTVWVXZo˜•„oUB8;:576421.--Dj|‰Œ€eTNJDAIJ/),/32<:,*19,'4?94343413400334331000149<:=CLD/).375BM;?UXQSV`mZ@DPb]KD@B[njnpmpvweEb¨’Kd]LBJQ`hhigb\SH:1+)*.3=GOY`dfggfdba`_^ZWQJB:322337;;<<@EMT\emswyy{||}{xxx{€ƒ‰‹ŒŒ‰‰‡‡‡‡ˆˆŠŠŠŠˆ…‚~{ywvtsvvvvuusmhbZQNOSY`dipw†‹ŽŒŠ‰‰‰‰ŠŠ‹‹Šˆƒ{rh^ZZ^ekrvusqopnonnnnnmmmmnnrrzƒ‰Œ‹‹‹ŠŠ#$&'%   !"#$%%&'()))***,..-.--..-.///.,,--,,+++++*,+,**+-/4;?DIMQVY\]_`b^]UNLB>7312233343333221111//..,,-**)''&&&%$#&%%%%)+/39;@EHNQVWX_fjmnquxzzyxwurpkkgeb^YVQMFA;74446578788665544444443211000023;Lbu‚ˆ‰‡rY=)%$%%(.1:GS[^Yacfoqqkiopu~‚„€~||xy}‡ŒŽ‘”•“ŽŠ‡{l[LA>>B><9;X˜‘Š‡ƒ€q4/=X[IKMKKTFDCE@>:_•jg`ecZSPLPOMGHJLMRMM[VKQTd–ƒl]QE;2247641.,*-He|ŒzeV]WQSOD::249?<007:+(+44644438:EOD=7542/--0.038:?>E>5/1:?@?85EURYW_mj[LNLZmS]etuls€twtyvUcODS[TAHWfgghhc[RG92-+,27@JSZaegggfecba_^[XTOJD@?BGHMOPPPSSX]ciqvzz{{{{zxyyy}ƒ†ŠŒ‹Š‰ˆ‡‡‡‡‰‰ŠŠŠŠ‡„‚}ywwuuuwwvvvvrlg_XNLOTY`elsx€‡‹ŽŒŠ‰‰‰‰ŠŠŠŠ‹†ypdYRU[cltwtspnmoonnnnlkkkknoot{„ŒŒŒŒŒ#$&'&"  !"#$&&''()))***,..-------.///-,,--,,))++))**+***+,.36<@DGMPVX\_`a`_ZRKE=512233333333221111//..,,+**)''''&%$%$%(*+/49?DHLRVY\`deiptvwxyzyyxtpnigd`[WQNJHC>84311124455766543333333332111//-/015CXl~ˆŒŠ†|jQ;&%)45.0<KNGGGONNRMQTWVUZhruyvvuw{„’’“––—•‰ŠŽ‹€r[H>889759~–ˆ‚€Q=?Q_PMNLIJFCDB@>7Uš’‚vgVZ`YPMRNHEEJHKNNNYYSHJS’ˆq]IC43789952-***0J`|•–nadcsk\XSMD738DHI@7+/355326GLIKF67:864:A=8/+-7>AM]A2?CHBHG=GMQRU^gd]UVU`egIWorpmo„~hib[\[YMDI[`H;FOffijfa]SJ<2-,/38BKSZaeggggecdcddeeb_^YUXX[`ehillnnppstwz||{zzzxwxxz~„ŠŒ‹Š‰ˆ‡‡‡‡‰‰ŠŠŠŠ‡„~{ywuvvwwvvvvrlg_WMKNTYafnu{‚ˆŒŽŒŠ‰‰‰‰ŠŠŠŠŠ‡uk^SMQYdmsvsrpnoqonnnnlkkkkkmns|…‘ŒŒŒŒŒ!#&'&#   "#$%&''('(*+***,-/----....00.,,,*++*))**)))***)++++,.259=@EJQV[]__`a\UNG;52222223322210000....---+**(((''&&')-/38;BHMQT[_bfikpstwy{{zyxurolid`[XRLHD>;95211100000033333322222422222210.----.4<Lez‡Œ‹„ueO9)6SUJGT\ZQPQSTY_PJFEFG?FILU^gp{ƒŽ’‘—˜•‘xyw‚’•{aH93467H‚‰‚}jKGWcUOSMEFCBBB<7Frž—†ymZTXZVPIFEFGIGHHIKOPIFJQŽˆ€eA52>C>;720)()**5Ld‚”“ˆ}wturcbXLKLB<MNF>7;:75427<<:>??;:758DEK;.112>JOiqO/=RNLTQR_sZLRZgQ]R;=\fYOT`\^ZYb^VPQID@LJ@ENA<H:1^kkjhb\TI;1--/5<EMT\dgighffhjlnqrqtsppptyz}€ƒƒ€€€ƒƒ„„‚~}|{vuy}ƒ‰Œ‹‹Š‰‰‡‡ˆˆˆˆŠŠ‹Š†ƒ|zxwwwwxxwwutrle^TMJLS\ciqx}†‹ŽŽ‹Šˆ‰‰‹‹‹‹‰†~vgWMIOYbltutrpnnnnnnnmkjiefiknuˆ’‹ŒŒ‹ "$%%" !!"#%%&&'(()****,-..,---....//.,,,*++*))**))))****++***+-257=BGKRY\_bba]TLF;5222123321010000....--,++*(((((++.14:>EINUX]bhjmpstvxzz{yxutqojfa^XROIC=:623210/////00/02222112222243200000/.-,,-.16EZp‚Ž‹‰€yiO:CXWQRK]mpbeh]e`YdcRKE>DDEFGDI\mŽ•––‘ŒƒŠ„”™œš•ŽzYA7<GLh‰}rnngXLOMDDB?A?<;bŒŸ™‰~si^XUQMHDFIJJHGFILEFEGMM~ˆymF<7BGD@80(##%')*8P`xŒ“„ujuiqxdikYJW^QC<97840/025668:89GOG9CC7**+1Nhkmd_HBGCTPOS\mcL]fZMG9CNj[CcieXIIC??ELF77?MYRMGKQ[4Ogkijhb\TH>51139AHPX_cfijlnpqsvz}€ƒ†‡…†††‡‰ŠŠ‹‹ŠŠŠŠŠŠ‹‹ŠŠŠŠŠ‡†{z|€‚‡‹‹‹ŠŠˆ‡‡ˆˆˆ‰ŠŠ‹‰…‚|zxwwwwxxwwutqke^SKINS\dkry€‡ŽŒŠ‰‰‹‹‹‹‹‹‡„|rcQIGPZeotutrpnnnnnnnmkigbdfhnv‹‘‹‹‹‹"$$" !!"#$&'''()*))++--------.....--,,,*++***))(()))*****))**++//48<BGNU[addd]UME93311222200011//....---*+*)()*,/58<BGMPT[_dhmprtwyxxxwvtrpmkgb^YTOJF>;511000..////////./1111112211132111/...-,++,./2<Pg|ˆŽ‹Œ„xrww|~ufQ??Pcuy\OWX_nwtaICCCDFCACDGK\q~~}…Ž‘–•Ž‹“šŸœ•–•Œyc`ny…–ƒ~ŒŠ‚qXLMIGCA?=ELV—Ÿxmb]]ZRIHGHHIHFEFHE<=ESYl†tmiQ@>BFDB=3&! !$'*+>Q`qƒ„tniu~tvpebcZ\G;<;961345369585D;;?;7;65-/9^pqeV]UTOODLSV]WSN\KEPHBZL^m]_`VM+.953674=MQcl_UGDOecihikkgc^VI?8354;FKTYbgnprvvz}ƒ‡‰ŽŒ‹‹‹Œ‹‹‹‹ŠŠ‹‹ŒŽŽŽŽŽ‹‰Š„€€ƒ„‰Œ‹ŠŠ‰ˆ‡‡‡‡ˆ‰ŠŠŠ‰…‚|{yxxwwwwwwutrkd\RIHMS\elrzƒˆŽ‘ŽŽŒŠˆ‰ŠŠ‹‹‹Š‡ƒym^MEGS]hqtusrpnnnnnnomkheccdhoxƒŒŽŒŒŽŽŒ     !!"#$&'''()*))++--------.....-,,,,*++***))))))**))**++****++-04:@GOU[beif]VJB8322122100011//....--,++*)*,148?CGNT[\bhkoruwyyxvusqplkigb^YTOKEA:62/--./--.-...../.../00000011000221110..,-,++++-/7E[rƒŒŠtq‚’•‘‹ƒ~{qXMQdZ`QJPele~|\QHEDDGFCAEFEGIV_’•š’’‘”—žœŽ”—ˆŒ‘‘’•…~|~…XhXJLKGC@A==Co“¡§›Œˆ}ukgdcaaMH]f`WIFEEC929H\hx_`XGDCEB?>8-"!#'*+,/:M\jw„‡‚xw}~‚zuj^OUH<DHOXT=:@<67B42>?CFZU<>31547Uid\V\[Q@;Cajh^\ZUFDL?AMXHVh^\NEK?G;?6?CH\ehxoNL=Aeffijkkgc^VLA:679?FOW`hotw|‚…ˆ‹’’’ŽŒ‹‹Š‹‹‹ŠŠ‹‹‹‹ŠŒŒŒŽŽŒ‹‰ˆ†ˆ‰ŒŒ‹Šˆ‡‡‡‡‡ˆ‰ŠŠŠ‰…‚|{yxxwwwwwwutpjaYPHGLS\elt{ƒˆŽŽŒŠŠ‹ŠŠ‹‹‹Š‡xiVIEJT^jrtusrpnnnnnnomkhebbchqy…ŒŒŽŽŒ!!!"#$%''()()**,,,-..,........-,+***++***))))((((((()(())*'))++-29?GNU_dgjd\RKB:55431200010..//.---.-,,.168?FJOT[_dilmpsuwvvtromihea`]YUPLFB;710.----.---.-----.-..//./0000//00121122/.++,+**))),0:Ndxƒ„z|‹‘Šƒ…Š†ƒ‚‚}zlX]nbVOe„‚w|n`OEAFFEHEFHJLJA?Sn‡•““˜šŽŠŒˆqŠŽ””Ž„{y{‘q…]HJKEA?;::J}—£§œekƒ~unlkjii•–’Œƒx\F>713Kekrnea]MHDDA??=2(%'),,,,-:L]gpv{†‘•„‡uoaQbVNWUXUX>5ECEBD16A:FOKFC0.;9,4JZSNP\UF=FKTLQILQUGEGJMVWHIXZM@EOIG8?C89DXny}ysR4=Qhgggijlhb^WNE=8;<CLU_gqy}†‰‘’’“•”’’Ž‹Š‡‡‡‡‡ˆŠŠŠŠ‰‰‰ŠŠ‰ˆ‹ŒŒ‹ŽŽŽ’ŽŒ‰ˆ‡††‡‡‰Š‹‹Šˆ…‚|{zwwwwwwwwusog`YOGFLT]fmv~„‰ŒŽ‹Š‰‡‰‰‹‹‹Š†€whTHELW`kruurrpommnnnomjgdaachq}‡Ž’ŒŒŽŽŒ! !!$#$%''()()*+,,,-../........-,+******))))))((((((''(()))())++*+06>EPY_gkic[SMEA=876521010/.//----+-/137<CIOU\aejmpsssstrpomjeb^ZWSRNKEA;641,,,,,--,-,,,------+-....-.////////010000/.++++**))()*2@TeosŒ…‚yvv……~~\Rksnf]o‡|umg[WPEEJRKEDCEIKGGJ^–‘“”˜™‰ˆŒ‹†rw†‰‚€zxyŽ“”ŽcGIIEBCOG8Qˆ¦©£^,X{yxvzz„•Ÿ¡™“ˆydM>6/8Selsnga^UKA?A?@>81*.///-+*+:P[gjl“¡˜–˜†{kceebXTDVM<>B?IA0=;AF?GN:.?VD-5IT[JAJ<<LLHP5:<@FWVFEEON\f_M85GYKSL67RY?DJfp_jrOCWcfghhjjlhd_XOF><>BMV_is}‚‡ŒŽ‘“”””””“‹ˆ„~{yy{~€‚ƒ†‡†‡‡†‡‡‡‡‰‰ŒŒŽ’““‘ŒŠˆ‡††‡‡‰Š‹‹Šˆ…‚|{zxwwwwwwwusog_UJFEKR[clw…ŠŒŽ‹Š‰Š‹‹‹‹‹Š†€ufSIJR[emrssqppommllonmjgd``cis~ˆŒŒŽŽŒ!!""$$%&&')*(**,,,,-,-........,+++++**))))))))''((''''''))())()))),19@IR\dikib\WQKGC>=;9533100...-,-//47:?GMTZ`cgmprrtsqqljhea\XTOLHEA=9510.-.++,+++++++++,,--,,,,------.........//.//..,+**)))))(*+5FZf|~†ƒqbphioWXeX\ggd__qƒ’„tlgbZMDFJPJEECDGIKLLOx˜’‘’—ž—ŠˆŽŽ…u}ˆy‹Œ{wv‰ŽqDLKIIC?>7ZŸ¥ª¥Š+4Mr‚}y{‹›¡ ”Ž†t]H;4/9MYbghc[VTOA>??AB>813310/-+*+5L_hdk˜¢¤¤¤¢˜~`VhqfUOaVE<HW>2<:DORK>/&4GWE2;GUcVCED5;F[S<737:EDHB1:AFab8<Y_XL[PKSnh`c`jnNV_]`fegefijkkheaXQHBCHNYbku‡‹‘’”””’“’Ž‹‡€xrlfb``bdgkorx{|~€„„……†‡ˆ‰ŠŠ‹Ž‘‘””“’‹‰ˆ‡‡†‡‰Š‹‹Š‡…‚|{zxwxxwwwwurmf\PGDDJPZcmw‡ŒŽŒ‹ŠŠ‹‹‹ŒŒŒ‹†€ufVOPW_gostrpnponnnnnnmjgea_djt‹‘ŽŽŽŽŽŒ!!""$%%&&')*+(*+,,,-,,........,++++++)))))))))(''(''''''((())(((((*.3:BLT^dhjhc^XVRNKFC?=:8632/.../0369>CHPV]agjmptrpnljfb^[USNKFA=9311-,,--,++*++++++++++,,,,++++,,,,,,--.......//...--,+**))))))(+5Mpzyuqmii^\vso}wtfZ]bTKTbuŒ†uimmgVDAIHJGDEEFFHILMu–Ž‹—ž•‹Œ‹ŽŽ‹Œ’‡Ž‰zvv„‹‹‹zKGHFFEA>5c“¡§§¥šW2=?FI>Aj‡š™’…€ufZS;11>LXZ]^`XTPMC=>BDGB?966431.-)*+5Rb_]n€Š“ŸŸ›‹xixsh`[WZKGV`=94;AGFH89>H<E>9<HQYN<;_C=FZ^E1.66<HE@=EHHT^enkgeieimlfPUi`fl`ekiiecfgggkkkjfaZSLKNRZdoy‰ŒŽ‘“’’ŽŠƒ{rj`XRJFEEGKLR[_glnsvz}}~~€ƒ„…‡‡ˆ‹ŒŽ’ŒŠ‰‡‡†‡‰Š‹‹Š‡…‚|{zxwxxwwwwurne[OEAAGQ[eoy‡ŒŽŒ‹ŠŠ‹‹‹ŒŒŒ‹†€wh\RTZclsttrqpponnnnnnmjgebadlvƒ‘ŽŽŽŽŽŒ !!"$%&&'&'()**++-.----,-.......-,,+++(**)(((((((''((''&&&&((((&&')**/4;DMW\dhhgdd`[YWRQMIECA:6522237:>DHNTY_ehkmnonmjfa^XUPLJE>;730/.-,,++,-++**++++++++++++++++++++,,,,,,,,--------,,,,,+**))))((+0a}oeivodi^f{zym]f`^|ucdlt|‹Œ“Œ…yudUKLLGDEDFFJMMJi”ŒŒ“›‰[r…‰‡Œ‘”‘†{yutŠ‘‘‹\DIHHCA<:rš£¨©¦št0<;974/P~‡‚yqeXPG5:BLRRTVXUOKHD<9AJKFD@;97651.+.17@V^[bkt~„ˆˆˆ‰…ƒ‚~uiUPUTUddLB7522;><?@4779<;:=A:60-:;>7gZ3-0>NA6<JPRLcxwrpnkjikii`Vhs`Zqqmihfeffghjmmljida\YY\cju~†ŠŠ‰†~ti`UKA>;<;;:<>BJOWagosvxzz{}€€€ƒ…‡ˆˆ‰Œˆ‡‡ˆ‰Š‹‹Š‹ˆ†~}{ywwxxwwwvvqkdZQFABHR\hqy‰ŽŒ‹Š‰Š‹‹‹ŒŒ‹Š‡€vj^YZ_gnuvtrpppnnnnnnnmjfdbabn{†’ŽŽŽŒ‹ !""$%&&'&'()**,,,--.--,-......-,++******)(((((((''((''&&&&((((&&&(**+/3<GNV]bdfedcc`^YWSSPMJEA;988==AFKQW]`bhjkihhea\YTPJF>:731//-++,,,,++-,++**++++++++++++++++++++,,,,,,,,,,------,,,,,++*))))*-3G€zqzwtwiikgju`MK[\egebd_g{}‡€“›££Š†xUCHHEGHHIHIIG`•ŠŒ™ˆ/9OcqˆŒŽŒ„ywuw‘šš˜•h@GFEA@=Ey™¢¥ª¦19;;;949fy{zvqg_XPLGGHIJNPNPRNJIF=4@NNKECA?:7642247:7CW]_dlpqsusvwrjhjfVIMUZQVXN12,9E?<IJ29<881/9KD00794<9=Q+,1692HemRPJqzvronkkjjknmqqu]Jmrnigffffghikklmmljijkpv|„ŠŽŒŒŒ‹‹‰†€}vme]VOGA>=;<<<>?BFMV]fmsvwwvwy||~€‚…†††‹ŒŒ‹ˆˆˆˆŠ‹‹ŠŠ‡†~}{ywxxxwwvutnjc[PE@CHQ\hq{ƒ‰ŽŒ‹Š‰Š‹‹‹ŒŒ‹Š‡€vj_[]dkquwupppnnnnnnnnmjfdbaep~ˆ‘’ŽŽŽŽŒ!##$$$&%&('()++,,,,,-........---,,+****))))))((((''(((('&((''((''''(*)+05=ELRX^acdcedaa^][[XTQLHEECDIMPV[_bdgihgda^[SOJE@:61--,,+++++,,,,,,,,,,++****++**************++,,,,--,,----,,++**++,,)+**.7Qdxdf‚…€ppffibOMLNMZgm_TOL^hpj€‰‘¥¨¡œ’xU@IFHIGIJHHHTŽŠ‹‹”Œ@;;<Ig}‡Ž‹{uvwx”žžšzBAFJC>>V~˜Ÿ£¦¦ž}.9=<<:54Jgkljf_VTPNKJKJLNONNNNMKGA5APRPIFFE?<96:;;8799LX]`ejjptvxpZGFHJIDDGQJFHG>;C26<?<99EC=9:;B<<<35<17;?`SK?<<F[ebSOY{xurnkjjiijmnqrsmktpkigffgggihkprtvuvxz}†ŠŒŽ‹ˆˆ…„~{xrmhb\YRME?;:<==>?ACIRYbhptwvvvwyzz{|~ƒ„„„ˆ‰‹‹‹Œ‹‹‰‰‰‹ŠŠŠ‰ˆ…~|zxxxxxvvwvsojcXNE?BHR]kt}ƒŠŽŽŒŠ‰ŠŠ‹Œ‹‹Š‰†wh__bjqvwwtrqpnnnonnoomjfeacfr€‰‘ŽŽŽŽ !"#$$$&'(('()+,,,,,,-........---,,+****))))))((((''((((((((''((''''''('*,4;@GNRVY\^^_aa`a__^\ZVSQPPPTWZ^_acgffb^[WSLGA;50-++**)+*+,++,,,,,,,,,,++****++**************++,,,,--,,,,,,++++****++)+,+0Nsysly…ˆŠ„}|vsyydUP[[K`gdb][V`cd~œž¯³­«¤Ÿ—‚G@FILMMLIDBG‰†‹‘ŽD4>>?E\y††„ztwy{—œ›œ™ŠN?EGD@?h“››Ÿ£ž}.68;:8617S__\][TMIIHFJNNNMMMLKLLLF@JRSVGDHIFD@<=BFB@>>DTXZZ[__ehnpne[TLB;<<GSPV]]Z8-4857;7BC;>B01;CSL8@769<OYID:8Xut\QLp{xsomkiiihilnqpnputokigffggijkpty}‚†ˆ‹Ž‹Š‡ƒ}zurnlifc`^]WQKC@<;;=>?@@EKV^dlsyxyywxyyyyz{}€‚‚ƒ„ƒ…†‰ŠŒ‰‰‰‰ŠŠ‹Š‰ˆ…~|zxwwxxvvvusniaWMD?AHT_lv€‡ŒŽŽŒ‹Š‰ŠŠ‹Œ‹‹Š‰„}rg``hmuwyxvrqpnnnonnnnlihgdejv‚‹‘ŽŽŽ!"!"#$%'&'())**+,,,,,-......--..-,,+****))((((((((''((((((((''''''''(())'',07<CFJNQRVY]_^_`_a``a^][[\^__acdecb^ZTNID<52-+**))*)++**++*,,,,,,,,,,,,+++++++)************++--,,--,,++++++++*)****)+-/I~x|~xw„wvzvpkffoghYFcpWWfcdefk™­°¬¯²¬®«¡wC<HKJGJEAABm‡ƒ„Œ’k.:>@@@Srƒ‚uowx|“˜˜—–“aCHHEADy•›—˜ ›q-6899:973>QVUWVRNJIIGGJMMNLMNJJHIKN\e`UEEEGLLJFDSbSCCB=OWUTPKGIOSY[Z\XK::ILROKIRXK=:.5?9:8>B:86.(*,44(9757?H<B>;<h}‚UM_„|urpmkjgghiintoovtspmjhhghjkosx|€…‰ŽŒŠ‡„~vplgfc_`a_]]ZUOHA><<==>?@BEOW^hpv{}|{xxzyyyz|~ƒ„ƒ‚†‡ˆ‰ˆŒŒ‹‰‰ŒŒŠ‰‡„~{zxwwxxvvvuqmg^ULC?AIUamxˆŽ‹Š‰‰‰Š‹ŒŠŠŠˆƒyoeacjouxzxsqqponnoomnmkjihefmy†Œ‘ŽŽ "#"##$%'&'())*+,,-,,,-......--..-,,+****))((((((((''((((((((''''''''''((''().26:@CGILMSUWX\_aadedcaaa`adeca`]YRMIC;2-*)()'****++++++,,,,,,,,,,,,,,+++++++,++**********+,------,,++++++++*))))))+,?y‰j|{|y€Š€ur|}ypvy~vj\QXkgSGdwyzy‚¨­ª³¹´·¹±›h7IHGFFCCC=WŽ‰}„‹’S4@?=@BNpƒtqxz~””——–xHHLFBG˜“Œ–Ÿœb,699::8521<KQQSQNMLGGGHMJLKMMIGEEKSWWVMJFGILQRPMQ^]PMC9HVRMD=9666:999510:FNQA=ADD8?><HI>9?DE95535/$2<=CA6;CD>:878ENMEMho}|xupnkhgghiorquuuspnlllnopsv{€ƒ‡‘’“”’’ŽŒ‰„|ungc`a_^^^_^\[YTMG?<:;<<=>@DIQ[ajv|€~{yyzzz{{€ƒ‡…ƒ‚…††ˆ‰ŠŠŠ‹‹‹‹‰‡„€}{yxwwxxvvusplf]TJA>BJUcp{‚‰ŽŠŠ‰‰‰Š‹ŒŠŠ‰‡‚xmc^bipuxyvsppoonlmnnomkjhgfgp}‡ŽŽŽ‹‹‹  !!#$$$%%&'(())*+++,--......//-----,,+****))('''((((''((((((((((((''''&&&(''((()-036:=AAGKLORVW\^bbcccccaaa_[WQMHA;3.)'(())((*+*++**++,---------------,+++,,********+++++,----,,--++++++***((()))*7k‘qXowz‚††~€€„|nvspwphcVc}oG4Xv|z…œ£®·º»»»¹­ŠBBELJDBCD>F~Œ‚}…‘ˆ=8?>>ECa‚wsy~…ˆˆ“––‰ONIFAJƒšž›š›š^+677999730-8GNOOMKKIGGFKKMKMMJHFCFSMKNRSIIIJQVW[aiYLJB9EVSJB>@EH@:2//--07CE7223:;>C>DMK?=9BH96864479AC943<A=;9::=<748>@BJOXcnmliggiililtvuttqrrtvvx|€ƒˆŠ’”“•”‘Œ‰„~umgb^[[]]^^^]\\ZXRMH@;:::;==@EIS[foy€……‚€~}{yzz{{}ƒ…ˆ†…‚‚ƒƒ†ˆ‹‹Œ‹ŠŒ‹‰‡„€{ywvwwvwvuuupke\RG@?CKYgs}„ŠŽŽŒŠŠ‰‰‰ŠŠŠŠŠ‰‡ui]]ajouxxusqppnmlmmoonlljigjs~ˆ‘ŒŽŒŒŽŽŽ  !!#$$$%%&'(())*++,,-.......//-----,,+****))('''((((''(((((((())((''''&&&''''''(+*,.0156;?@CGLPTZ]^_````]\ZVQLGA:3.+)'()((())*++**++,,,---------------,+++,,++******+++++,----,,--,,,,++***())))*,GohWYqu|‰†‡ƒ‹Œƒ}‚€{qulpmXEdsjRG]ft‚˜¨µ»»¼»ºµž]7>AEBCC?@Cd‘ˆ~~Š—f1@@>CHq€xxz~{zŒ•—[@EGHJ‚›œžšš”Q07:9:9863/.0;EMONMKIGGGEKMKKJHEFCDXQLNSTHIIKMU_rwod]KB=M[RHGMQRPH?30/00022//0325;;F;;EB938>A=7979:>>82363BO=6589:<;9=CB9:BEHR]aagihjootyzyyxvxz|~€ƒ‡‰ŒŽ’“•““ˆƒ{skc^]\[XZ\\\]]\\\YVRKE=;:9:;<<>EJR_gq|‚‡‡…ƒ€|{z{||ƒ…‰Šˆ†ƒƒ†‰‹ŒŒ‹ˆ†‚~zxvvwwvvvuttoid[OF@?EMZft~…‹ŽŠ‰‰‰‰‰ŠŠŠŠŠˆ„|re\Y^gnswvrqpppnmlmmonnmljihmvŒ‘Œ‹’“”’‹ !""$$%%&&''(****++*-............---,,+**))))((((((((((((((((''''''((''&&''''''&&((((++*-1468>BGLOQUVVYYWURNKE@83))''((')(**)**,,,+--,-......----------,,++,,,,+*++++++,,--------,-,,..06+)++**)*,5Y^cw^k~ˆ€xˆ‹||{{qmvoxu\AVp}ucY]b{Š‘“£¯º¼»»º¸§p06=BADEDDCNƒ†~}‚’ŽH1?BKm~|{€€†‰‰‡‰Ž”•e?CCEP—œœŸ›™’@3;;:::9863/.0=JLMLLLJJGIKMIDCAEDEEX[MOTSBHIKMN[mmlgfI?D[^RPVWWVK@82.*)-.../../147984852.1;A>;;69:;<981::144728BIG>75>CDFC>9?PX[Y\dmqtvy}~}}}~ƒ„‡ŠŒŒŒŽŽ’”’Œ‡‚{pg]WXY[\\]]\\\\\\[[WUPJD<:99:;<<@GKS]kv…‰‰‰†ƒ}|z{|{€„†Š‹Š†ƒ€…„‡ŒŒ‹Œ‰…‚}zwuuvvvvvvtrmgaYOE?=EQ^kv‚†‹ŽŽŠ‰‰‡‡ˆ‰ŠŠŠŠˆ‚xn_VU[blsvvtqponmkklmoppomkjjoz…Ž‘‘Ž‘‹‰ !""$$%%&&''())**++*-............---,,+**))))((((((((((((((((((''''((''&&''''''&&(((())((+,.257:>BDIJJMNKHGC@:2,)((''(('))*+***,,----,-......----------,,,,,,,,,+,,++++,,------------..4S@(++**)*2HRnŠ‡Šqim~“……ˆƒ{{€vprmM?UBbxx|nX_j€Œ˜Ÿ¨²»»»ºº¦t47<??CECCCFcyzƒˆD-C\ƒ~|}‚……ˆŒŒŽ’’zIFAFL–ššœœ™•I5<9::::9542.+4ELONNKIJLLMKGLPRPKDAE]ONTS?EHJMNQ^b`^^MKR]]Y\_\WPE=86-&'*++-----0125@A><<FGHBF?<79779345631/26137:9?<:><?EKJGA7=Ni`H]x|z}ƒ„……†ˆ‰Š‹Š‹ŒŒŽŽŽŽŒˆ€xlcVNLPTXY[[\\[[[[\\[YWUPJC;:989;<?BEMWajs†‹‹Šˆƒ|{z{{|€„ˆ‹‹Š‰…€‚ƒ†ŒŒŽŽŒ‹ˆ„|yvttvvuuuutrmg`XKA<=EQ_lxƒ‰ŒŽŽŠ‰‰‰‰ˆ‰ŠŠŠŠ‡wl]SSZcmtwusqpomlkklmopqpolkmt}‰Ž”ŒŠ‰‰ˆˆˆ   !!""$$%$%'((*****++,.......//------,+,,**)())''''((((((((''''''''''((('''''''''''))))))))))*,/0357:?AAABA=;62,)'&''(()))))*++,-,+,,-,-.....//////----------,,,,,,,,,,,,,,-----------++,/1-*****+,AX_{xƒ~RJTe†‡‡‚ˆ€ttwsupbT>Lut€‡rX_oƒž¥®´¹»º¹£i17:<>AA@@FCDm‘†}{}€Š‰;2gƒ€}€…‡‡‰ŠŽŽƒVKDDK}’–˜›šš“P59:;<;;:941.,/@KPPLJHHLLMPQQQPMG:01aVMQM4=CFGJV]ba^^bbddddc`ZRE<977.'')**+++,,.0019=AHKFFOOKEB<E>FORF?961433453538CF=@A9:@GKIG?7QaV^tƒ†Š‹ŠŒŒŒŒ‹Š‰ˆ‡‰‰‰‡†…wndVMFFLSVYYYZZZ[[[[[[ZZWTOIA::989;<=AJX^alw€†Š‹‹‰„€}zzy{}„‡Š‹‹ˆ†‚‚ƒ‡‰ŒŒ‹†„|xvttuuuuuutqlf]UI@:=EQ_mz…‹ŽŽŒŠˆˆ‡‡‡ˆŠŠŠ‰…~wi\QSZenuwvtrqonlkklmnoppnmkmu‚ˆ’•’Ž‹‰†‡‡…ˆˆ  !!!""$$%$%'((*++**++........//------,+++**)())''''((((((((((''''''''((((''''''''''(((())))***)*,-..13677762/,)((((''(())))*+++--,,--..//../0//////-----------,,,,,,,,,,,,,------..---.-,-,,,**++-8OQy‡€Tb[OJMi›™‰†‘Ž|ty|z€yoH?^xxu„†nScq˜¦©¬°·ºµšN/9:>>=@A>ABBK{Œƒ}zx‹@wƒ}{‡‡‚†‹Ž‘‘‘’mNLEI|—–——–’U59;;<;;9743.-,9IOSVWWWWVSQY[XOB3,(,]^OPJ,/49?T[`e_`jlmhiiij`TF?::992)(,*++***)*-..2=IKMPNXOILHAFMQVNB/264//1460/8K@;85NTIA99@DGA9=Q[Tk‹‘Ž‹Š‰††„€~}}}|yxoj`VLFDGKQTXXWXXXYYYYZZZZVRLFA::989;<?ALTW`lw‚‡Š‹Šˆƒ}zy{{}„‡‹Œ‹‰†…‚€€ƒ…ˆ‰ŠŒ‰‡ƒ~ywvusuuuutttqke\TI@;>FRan{†‹ŽŽ‹‰ˆˆ‡‡‡ˆŠŠŠ‰…}sfXPS[gqvwusrponlklmmnpqppnmqyŒ”—”‹‹‡†‡‡ˆŠŠ  !!!"#$#$%&('()++++,,..////////----,,-,+***))))((((((((((((''''&&''''((((''''''''''(((((()))*))******,,----+*)('&&((((()))**+,,,-....//./001111/////-..//..--------,,,,,,,,----..........--++++,-0JKP…bMHEJSh®©¡›— ˜Œ„vvopkoO:;Hb„Š„~iV\yŸ¥§§©³©|729<=<<?A@B>?BQƒŠ‚{{v€wƒ|w|ƒ†|„ŠŒŒ‘’“‘{ROGIx•“””“`7<;;<==:841/+-8Xmvuoja]YV_eb\K4&%%'TcLLH-..0T`fbaexqpigjkml\IB?<===6/12210.)(%'+../9ALOIV`QJF?GKLEEJF1#093-./0,/?Mx_C<EPTSL=9:==A8<MXj“ŽŠˆ†…|wsrrqssqoke\TJFEHLRTXXXXYYZZZZYY[ZVQMGA<989:<=>DIPYboy‚†‰ŒŠˆƒ€}zxzz}ƒ…‰Œ‹Š‰ˆ„ƒ€‚‚…ˆ‹‹‹†ƒ}xxvstuuutttspjd[SG?=>HTcp‡ŒŽ‹‰ˆ†††‡ˆ‰ŠŠŠˆƒ{qcWQW`jrvvurrponmmmmmnqqqmmot~Ž–”ŽŒ‰‰ŠŠŒŒŒŒ‹Š !!!!"#$$$%%&'())))++,,--..////..----,,,+****))))((((((((((((((''&')(''((((''''''''''(((((((()*))**))))))*****))(()(((((()))*+,,,-.//////./0011111/00//..//..--------,,......--....//......--,,++-.5VIh‰KGEXr†—¡§­­¬§¢›€†‹}okmsr]??83Gmw‚~Y]p€’ž¤¡ŸŠO4;;:::8;:<?>BMOd‰…{ywy„Ž‰|x~…€~ˆˆŒ’‹‰ƒSIHOp‹‘””’‘Œj:<;=<=<85400..[€„}soi[WUTZ]]XE,&)(*HlULJ/,/Tkkkgl{yojhegkme\RJEA@B?<9768630*##$(,-./8AFQ[`RKLTQZc_WQI5!+<<1.00.+*<v‘”‡eI?JPPQN<7BDB:CWhŠŠ…‚|{vqliiiklnnmhc\SJFFIMQUYYXXYYZZZZYYYXVQKE@:98:;<=AFKT\dqz‚†‰‹‰‡ƒ€|yzz{ƒ…ŠŒ‹Šˆ‡‡‡„ƒ„…ˆŠ‰†‚}xwutussttttrojd\RG?>CMYer‡ŒŽ‹‰ˆ‡‡†‡ˆ‰ŠŠŠˆƒzobVSX`jsywurqponmmmmmnpqpomm}”˜“‰†ˆ‰ŒŒŽ‹‹ŒŒ  !!""""#$%%%&&'((')***+,,,,....//.-----,+*)**(())))))))))))(((((()*,)&(''(((((('''(''''((((((()()))))****))())))((*))(())(())*+,....//.//1111111111221111/////.------..----,-...-............------./?]nnnG>aŽšŸ¨¦¡££«ªª©Žwx|zb[KHCDJqy}o^jwˆ“œ™’ŠlD:=:<=ACC?=<>BHJRmˆxuv|…Šzv{y…t}‘“‘’hEIQg„“ŽˆŽ‹u<9:<=;:944/.+K{~zvrpe_XQJHCDGB400-.AlZML01Ejmrox‚|vnifchlomh^XTPOIA=<9<986,%"#$&*..-.2D^eh\PVXdlinlidZG8846/--4<?EYvz…‘’‡oQDLTUR>9=DB8=WoŠ‡{xsokhgfghjllmoic\SKGFIMRSXXXXXYZZZZ[Y[XUPJD>:989:;<AGLS\gs|‚†‰Šˆ…€zyyw{‚†ŠŒ‹Šˆˆ‡††ƒƒ‚‚„†††…ƒ}yvtrstttttsomgc[QG?@FP\huˆŽŽ‹‡†††‡ˆ‰ŠŠ‰‡‚xm`UT\dntwttqponmmmmmmnqqpmp†——’‰††‡‰‹Œ‹‰‹Ž’  !!""""!"%%%&&'(()****+,,,,....//.-----+**)**))))))))))))))(((()))).9+'''((((((''''''''((((((()()))))****))()))))))))()))))**+-,,//./01001111111111222211/////.------..----,-..............//..----./EtzeCRBX¨¥¤£¦¨¥£­¯®«¢‘†„…‰wlj`e[eW_w{{efr{†ŽŽ‰tJB:A>==BIJOJDB??HQRq‰{wuw|‡‚sqy{wkn‡wbs˜šš•{ECM^†‘Ž„wŒŒz@68;;962110,8q}ywuuk`VSTMEA:;;<9644>hZPP39fjqtˆƒ}zroqslcftxofe_XQJE@>@=<7*$$$$&--.,),Gdeg^[[dqy…†‚}{~wa<04.+6FFD?CLL^`\s|}{[FGLFG@7?@=A[s†ypnjhgggghjlnmmkf]UNGHKORUVVXXXXYZZZZZZXUPJD>:989:;<BGNV_jt}‚†‰Šˆ„€}yxxx|€„ˆŠ‹Š‰ˆ‡‡‡…ƒ‚€ƒƒ„ƒ„ƒ„yvtsrsstssromfaYOD?AGR^jw‰ŽŽŽ‹Š‡†††‡ˆ‰ŠŠ‰‡€vj]TT\entwtsppollnnmmmnprmw—”‹‰‡†…†ˆŠ‹‹‹‹‘Ž !!""####"#$$%'''(())**+,,---....//.---,,,+****))))))))))))))((((((((''''''(((((((())((''(((())))))))))))))))))))))))())*)**++,-.,-..00111122222212111111110/////...-....-----..-....////......----,,./DmLB@EQ†¨­ª©  ¡¡ž¬¯¯¥ ¢›‘’“vnaenihfep€‚l`nv}ƒ„yT.4>D>?@?@@IEDM>:AFOIx‡}vsyz‚ƒuttpWa}wm{”•˜˜ŽUBEdš—‹r…~A77998432/0.G{‹yptpom`ps[:F@:;;;:8=]\PSA^jnx‰Šƒ~zz}|n__^iwtmeaYXUQKGDB>2'#"$#*1..+*+K^_aT\Ya`m{usyzzrjT504>?=978>Qlkb]]csi[NJFOPI?=@>A[x‚rlkihgffhjlmmnkc\VNLIKOSTVVWWXXYYYYZZYWUPHB=:87:::=CIPXakv~‚†ŠŠ‡ƒ{vvwy}…‰‹‹Š‰‡ˆˆ†‡……‚€ƒ‚ƒƒ„ƒzwsrrsrrrqppme^XNC?CJValy„‹ŽŽŒ‰‡†††‡ˆ‰ŠŠŠ†~tg\TW^gqvvtromlmmmmmmmomo‚“•ŽŒ‹ŠŠ‰ˆˆ‹‹‹‹ŽŽ   !!""####"#%%&&'((())**+,,---....//.---,,,+****))))))))))))))((((((((''''''(((((((())((''(((())))))))**))))))))))))))()++**++,,..-///00111122222212422222110/////........-----.......////.......---,,./=TGCDTt›³²£¦¨¢¤¥£ª§¥ž—˜¢¡•“Šqdcdimgfkuyt|`kv}z|j<,29?>?@???BFHJA<>AJMLy‡}uvz†ˆxl[V\w€†‘Œ‹“cCCOŒ ¡–^‚?78977744566M”‰~qŸ—•†~€P;DD<;:<<;S\NWeqs‰ˆ„€ƒƒ…xg`_^`bb_ab]XUSROMHF<)$#%$%.2/.++2N\_WGQ[]]amzywwurhijZJF>.6;5+*4T‚Š‹‰~g]SNPVNLM>8=>EZƒ~sigefhfijkmmmjf_XPMKMQSTVVVVXXYYYYZZXVSNGA=::9::;>DJQYcmw~„ˆ‰‰‡ƒ}yvvwy}…‰‹‹Š‰‡ˆˆ††„…€ƒƒ‚{utssttssrqpme^VLC?DKXcn{…ŒŽŽŒ‰‡†††‡ˆ‰ŠŠˆ„|rfZSY`kswvtpponlmnnllmmrŠ–’ŒŒŠ‰ˆŠ‹‰‡‡‡‰ŽŽŽŒ    !"""""##$$$$''('(((***++,,--......--..,,++,+++**))))**))))))))))(((((((((('&((((''(((((('''(('(())))))))))))))******)(****,-,--../00/.002011333322243333331100000/..//..--.----..-................---+//>FFCNq„¦²±˜š­®±²¶·¯¬£™’˜–~vi[ojdehnvz‚‚{jfr{{x_1,01:CDDA>=<9CJH::=HMCR†„|y||ƒŽ‰kHQTk€’˜“‹ˆ~mJCDv™ ¡Œs“v?:;;<>?@>CB2V  ‡}“—˜„opkU27?D?;<=<J_]gpo}ƒƒ††…Š‰rcbdfceb^UNTTURRPPNKC/%#$$&+442/-5DP^ZGCIW]\\ar~yqhimievhH:-0064./4R‹Š…a^r|viXKGCEGBA@Am„qjhhfgijlmlolg`YRMLNQSTVVVVVXZZZ[ZZZWSMF@=;::9;>>DLQZeoy~„‡‡†…|wvvx{}†Š‹‹Š‰‡ˆ††…†…‚€€€‚ƒ‚|wstrrrsssppmd]TJCAENZer}ˆŒŠ‰ˆ‡‡ˆˆ‰‹‹‡ƒ|qcXSZbksuuspnnmnlmmkmlv˜’‰ŠŠ‹Š‹ˆ†…†ŠŒŽŽŽŒ      !"""""##%%%%''(((((***++,,--......----,,++,+++**))))**))))))))))(((((((((('&((((((()(((('''(('(())))))))))))))******+*****----..//00/0012322333355334433331100000/////.......-...-................---+.09AEOp†°µµžŒª¯³µ¹¸³­ ˜’•š—”{zjbi`acst|€†‘~RbpxuX,(+17<@AB@>><;AA<=;AKH9ZŠ†}{{€†‹EIV_xŠ“™š—•‰tqQDEWˆ™–v‚JBBCDFDC@==92n©¥¢›~ˆ…|yg[IA7548?@;<:Cahkqv„…‡ˆŒ’•€e`ghjjhdd^M;=LRPPQPMI>*""%'*056425EQPRF@FHP[\_[bnhfcXQRYciK301./2/,-8o„€€rv„††…xM=FB?CELbsxmjgighjlnnojg`YROMNQTUVVVVVXZZ[\\ZYVSMF@<:;;:<@CHMT\gpz„‡‡†ƒ|wwwx{}†Š‹‹‰ˆ‡ˆ††‡†…‚€€€‚‚€}xtsssrttsqpmd]SGAAGP^ju€‰ŽŒŠ‰‰ˆ‡ˆˆ‰ŠŠ‡ƒzn`UV\dmsuuspnmlmllkngw—‘ŒŠŠ‹‹ŠŠ‡„‡ŠŽŽŽŽ‹"!""!!""######$$$$''''(((***++,,--......--,,,,,,,+++*)))))**))))****))))(((((((('&''''(())((((''''''(())))))))))))))******+*++,.,--..//01111112332443344444433332211000000//..........................----,,,/<DUt…Ž¥³´·¡œ¡«¥©©§¨£›’‹‘’‰|xqggemnqt†‹š ›SRjutR'(+.86:IDA?=<:9=:=;?GMDF{‡{y€…‹|GOXzŠŒŽ‘““yaFCDi™˜Š_DA?=?@=9:7R`B…®¢•Š‰ŠŽqhiZQC864324>C?<AWkntz‚…‹š˜igffimpmkf\B00>LRQRSRJ7&""'+,3659:@KROD7<AIPTWW]`cY\\H=72:GWO6//21/..I_gx{y{|~‚€wkobT>CHEEGEPPS^cgghkllmolga]TOMNRUVVVUWYYYZ\]\\ZURLFA>===<>BGLPW`irz€„‡‡†ƒ~yvxxy|}†‰‹‹ˆ‡†‡†††‡…€€€}xtqsrsttrqljd]QE?BHT`kx‚ŠŽ‹Š‰ˆˆˆ‰‰ˆ‰‰†‚xm^VU]fotusqpnnmjikjh~–—‘Š‹ŒŒ‰‰‰‰‰‹ŽŒ‰"!!!""""######$$$$''''(((***++,,--......--,,,,,,,+++*)))))**))))****))))(((((((('&''''''''((((''''''(())))))))))))))******+*++,---..//001111123234444444554433332211000000//....................--..------,,,/?Qo†‰˜®¦¥²p~¦Ÿš¤¬© ™Ž…“Šˆzsljckqut}…ŒŸ©­nJejhL*+&,.>MKJBAA?<;>;;=>DHFFwˆ~{{}ƒuJRv‡…„€‡ŽyrNFCKsrLE@?=>=<::5GdX©›—ƒ~‚€f[PMMC6643126>IHBE`osx€ˆ–“sqkkjklpspjX9./3BOQRRPA-%$'+-0;?BABFGHLB89>HOQNVYYXOC3,.1334BOO:7618;6N=<Spuyzub]kqq…m>LE>HHKMNQUV_dilnnnkgb_VQOOSVVVVUWYYYZ\]]]YWRLFA@?>?@BEJNR[bkt{€‚……„}yvwwy|ƒ‡ŠŠŠˆ‡†‡††‡‡…„€~€€€~yssrstsssrnhaZQE?BKXcny„ŠŽ‹‰ˆˆˆˆ‰Š‰ˆˆ…wl\SW_hptusqpnlkmjil‚––‹‹‰‰‰Š‹‘Œ‰""####"#%%$$$$$%%%''''(((***++,,----....--,,--,,,+++*)))******))**)))))((((('''''&(('''''((((('''&''(())))))))***********+***,---..//0010011132455665444665444332222111000//...........-.---......--,,,,----,0Ce€Ž‹¡©š«—pr‘¥®®¬¬§ž˜„‡“Ž‚€ƒ}pifnrs{ƒ„“©®ŠG_^]G..3.-6G:>FCB@<>=<<<=BKLHzrzŠ‡€|{€…ŠlMc{€yndk}‚_EDBLcpTFEA>===;:814Zj¥“€yvmeWLCBA74334:CKSSSEGOUX\s…‡|€€zqmlopvwqiS4-005HRTQH8-*+,.2>IMNOONGEF:8:>BJOOTSI@-+A`z›£¦¥¥£”~k]WF2=@5?Yosyzj\ayŒŽ‡†JCG<EKEUcXVUSWZ_ekkmmg_XTRQUVUVVUVXYYZ\[[[XUOLFBA@@@BDHLRV\dmu|€‚„„‚€{wvwv{|ƒˆŠ‰‰‡††‡‡‡‡†…ƒ‚€~~~~~yusssstsrqlf_XOE>DMZeq}…‹ŽŒŠ‰‰‡ˆˆ‰‰ˆ‡„~tgZSW_irtuspollkljj„—•‘ŽŒŽŒŒ‰‰‰‘‘Œ‰#######$%%$$%%%&&&''''(((***++,,----------,,,,,,,+++*)))******)))))))))((((('''''&(('''''((((('')'''(())))))))***********+***,--..//00111133333355666655665444332222111000////../......-.-,,------,,++,,----,0Jx‘™“’‘™£œˆˆ©²¶ª˜˜Ž„„Šs{xtvsiqw|„ŒŒ—©°£RUWV@*+AC20037DA@@=?<==;;?DJG{vjŽ†|z†ˆ`Rfmc^^^k‚‰~H?CAABGHDB?=>;95225Td‚¥Ÿ€|vi_UTLD?834;?GRVY[XYYMIGIOU]izŠŒ†xihry~zmF.,0317IOI</.-.12GY[Z]^YTOG<76<AFJMNK=2)7Xy¦¶»»»»º»ºµ®ª™h/1540?Xku}€{w‚†‚s|mbAJEHMNnuhbd[VVW]]ddda[UTSUVUVVTUXYYZ[]\\XUQLGCBABBDFKOTX_fov|‚„ƒ€}yvuwx{|…‰‹‰‰‡††‡‡‡†††…ƒ€~~~~~zuqqrssssplf^VMC@EQ]gs~†‹ŽŽ‹Š‰ˆˆˆˆ‰‰‰‡ƒ|sfYT[ckrrtropmkjkk‰˜”‹‹ŒŒ‹‹ˆˆ‰‘’ŽŽŽŒ‰$#"#%%$%&&%%%%%&''(((((()+++,,,,.......-,,,,,+++++++**********))****))))((((''''&&&&&&&&''''''''&&(((((()))))))*****++++++,,,,--////112233433444456666665666554433221010000//.-/+.--.-----,,,,,,,,,,,,,,----+0[†—›ž“‰“–š §¬­¨‘™Ÿ‘‰Šrwvwz{rx}„Šƒp®¥XNPJ5(*7C/-0007CE=A><;;9;@EKH|~sj„Šƒ}wzˆƒZ_d[\]\ew‚‡o?@A@?BFDB>=;98400;Ub|›|pskXUPE997<CJOTVYX[]\`ZJDDKS\i|–waZu…ˆŠŠp6-026628DA1,0221<Waahqm`WPF627@IJLH<3,0>ZzŽ¤»¾¾¿¾¾¾¾½º·´°ª}9(024?Mdtw‚ƒ„||‰Š‡LHHOSPZtkjie`]YYZ]^]YWUUUUUUUVWWXZZ[\\[YUSMIEDDEEGJNRV[bhpu}€ƒ„‚{wuvvx{~‚†‹Œ‹Šˆ‡‡ˆ††‡‡††„}{{}}~{zvssttssqojd^UKCBIT_jw‚‡ŒŒˆ‰‡‡ˆˆˆˆˆ‡‚{reWS[bkrvvqolkihk‰—“‹ŠŒŽ‹Š‰‰†ˆ‹‘‘’‘ŒŽŒˆ&$#$%%$%&&%%%&%&''((((())+++,,,,.......---,,,,++++++**********))****))))((((''''&&&&&&&&''''''''&&(((((()))))))*****++++++,,,,--////1122334334444566666656665544332210100/0//./.8/,,------,,,,,,,,,,,,,,--,++2g„ œ™™‘‘Œš£•“¦¤¥¡£’Ž“Œ‰‹”‚yy|~ywtv|{a3›ˆLPKE/'(,.,,+.16;FA?C=?<<;<AFEy€smoŒ‚|{~„ˆrSZRUWYfv€€†‚U??=@CCCC==864100=R_y{plj]JJA457@JNSTYZ[\^_bbOEFLR[i{™š{bmŒ˜—˜Ž\--13775353++1449T_emx|ueYJ>64@MONH6.,=HWvŒ¦¹¾¾¿¾¾¾¾¾¼º·³°®¥„8.4348Uhg~z}~‚‡Œ{hGDNNNOyxkhjhgojd_][\YWXYWUVVUVXYZ[\]]\ZXURNIGGGHHJNRVZ^dlrw}€„ƒ}zuuvxz|ƒ‡‹Œ‹Šˆ‡‡ˆ‡‡‡‡†††‚€}|}~~}}{wssttssqojd]TKCCJVbkyƒŠŒŽŽ‹Š‰‡‡‡ˆˆˆˆˆ‡‚zpcYT[dmtuspnmkijŒ™’Š‹‹‹‹‹Šˆ„„ˆ““‘ŽŒˆ(&$%%%%%&&&&''''(())))*+**++,,,,,,,,---,++,,,,++++************))))))(())((((''''&&&&&&&&''''''''&&(((((()))))))***++++,,,,,,----//0002223333344455565566665555553322110//...../MK0----,,,,,,++++++++++++,+,*+5h{Œ ¢¡Ÿ›š›‰Ž¢… §¦¢œ‰’Œ‰Ž„xv{}|yvokojW;]dNMPN@+')+-/;1.027JD==>@>?;;?@Djxsnu‹€||‚…^XWTT[jz}xx‡{M>@ABCGH=:8431.0<R\xtqmd]KH=875?MSY[\aa`abc]JKNSTZdu›žw‘ £ ƒA//0258:51--.049M^epz…‰pYB:99DQWQB//5CMc†¤¹¿¾¾¾¾¾¾¾½»º¸µ±¬¨ r018G5>XVou{|‚„{c†n>HGOPo~tmlhdedbb_[WUVWXXVVVUUWXY^`][ZZYXSNJIHHJKMQRV\`fmuz„{vtuvwy}…‰‹ŒŠ‰‡†‡‡‡†‡††……„ƒ€}}{}~}zwusssssqnicZPIDGO[cq{„ŠŒŽŽ‹‰‰ˆˆˆˆˆ‡ˆ‡†€xmbVV]fnuwsqolml‹—“Ž‹‰ŠŠŠŠ‡†„‚~‹““‘ŒŒŽ‘Ž‹‡'&$%%%''&&&&''''(()))*++**++,,,,,,,,---,++,,,,++++************))))))(())((((''''&&%%%%%%&&&&&'''&&(((((()))))))***++++,,,,,,----//0002223333344455565566665566553322110//.....,),.------,,,,++++++++++++,++++6f{‘££›™š›–‘…¢™œ§žšš•“‹‡Œƒzvuyyxrme\WQJPNNMPK<+'*),0.+,344459>>@@?=;=A?_‰vnln…“‡~{}ƒ‹pQPU^dq|xsl}‰kB?CBCFD=:7521/0;MZtz~xsh\YSF>?:5;PWY_dfqslf]XWVLLQYao‡™ —›žž›Œa130146674421036I\eow|ŠŒl:7:;<<>@=70/7?Ef—¶¾½¾¾¾¾¾¾¾»»º¶³­§ž›–U0LW@0CBaYm€}€xFM~[?EKNV`^URJIIJLMRQMKJOSWWUVTWYVT[dee^Y[_]VPKIJIKLORUY^chov|ƒ~ztsuvx{}…‰ŒŒŠ‰‡†‡‡‡†‡††…†…ƒƒ€~~~}zxutssssqnicZPFFHP\es}†ŒŒŽŽ‹‰‰ˆ‡‡ˆˆ‡‡†„vl_VX_gpuvsrpknˆ–“Ž‹‹‰Š‹‡…„ƒ~t~Š‘‘ŒŒŒŒŽ‘ŽŠ†''&&''''''''((''(((()***)*++,,,,,,,,,,,,++++***,++**********))))))(((())((((''&&&&&&&&&&%%%%&'''&&''(((()))))))*))**+++,,,,,----.0/102223433444555665566665555543311110///.-..-..----,,,,,,,++*)**********)*)6j†—Ÿš—•š’‘‰›—™›˜–‹ˆŽ“ŒŒ‹„yz{}wpbgaPEKQONOQLJ<'&()+-*)*,+/31619>>A>=?>?P‡uonlrŒƒ|~|„‚UASdpyzreY`xy\CDB?DH>:74310/:L`ƒŽ…maVTSFBB>8<SX[ahnv†ywrvgbfegix›˜š™—”‘†nD6667986234453E`flu|ƒŒ‘b27765567530047Bu¬º½¾¾¿¾½¿½¾¼º¸µ²«¡—’~MKUT19TjX^}~~€zyƒwMENNeWSTRPUYVXWVQONMOWUTVX[\[TWZ\b^ZZ`ddf]OLKLLMQTX\`fjpv}~€€|yuttwx|ƒ‡‹Œ‹‰ˆ‡†‡‡††‡†††…†…‚‚}~~}|yuvttsqpmgaZPFEIS^hv†ŠŒŽŠ‰‡††‡ˆˆˆˆ‡ƒ|tj]WYairvvtqlm‡˜‘‘Ž‹‰ˆˆ‡ƒ‚…|jn€‹‘ŒŒŒŒŽ’’Š…''''''''''''(((((()))***)*++,,,,++++++++++++*,++******++****))))((((''((((((''&&&&&&&&&&%%%%%&''&&''(((())))))))))**+++,,-,,--../00002223444554555665566665555543311110///.----..----,,,,,,,++*)**********++/6kŒ™™–œ‹˜’‚’•˜™–—“Œƒ„‚Š†ƒƒˆzztniajcK9COOQOPOH8'(()***)*,+.5;JG9:@@=><9;Bz‚wwuwƒ’Š~€ˆqXahv{wn\G>HZeWECEC@@9731/0-;I`Š›ŒcGSTVHDGCCHRX_hjn€‘‰ƒwf^elgmrutw‚‡ŒŽ‰„~wpV=:9898543258:Yttuxƒ‡‰b675443020..266EqŸ´»»½¾¼¼¸´¶ºº¹³®¤™‘Œ†ZRLUR14MO=h€€||xnTKLLMNPMONLDLXUMECCEGVRQ[YSYWceemkhhfmoh^QMLNNORUX\bhnsz~€‚‚~zvtstwx|ƒ‡‹Œ‹‰ˆ‡†‡‡†††††‡†‡†„‚~~~}yusrrpnomgaZPIHMW`kx†ŠŽŽŠ‰‡†††‡‡††„{si\W\ckrwwqplƒ–’Ž‹Š‹Š‰‡„…|ddtƒ‘ŒŒŒŒŽ’Œ‰†((((((((''(((((()))))****)*,,,,,+*++++*****)(+*)))**))))))))))))((((''''''''&&&&%%%%%%%%%%%%&&&'&&&'((''))))))))))**++++,-,,..//./1011112344554555666666555555432211000/...---------,,,,++++***************0@>h˜“–š‘–•Œ—›š–‹†‡‰ƒ„……Š}yqqpmlgcTJKKMNQNJH7'((())+(*.,+,7P=83<:??=<9;l‚‚ˆ’„~‚„‚YitxzxjWD97:KaTB?CCCA841/..<KZv˜žˆRGGWXMHCBLLV[\eu…–œ“{`SMbyƒŠŒŽ…tit|vsmhaS@<;98766656:Uw~{„…ˆ†c:863200/-.049<JUo‘¤¬³¶±§–š¨®°¯¨ž’‹‰Š‡XIJGWI07E4Kty}wep>LP^c]_`VRHZhhlke[SUgRGX_Zcia[gmlc`Xkl^SOOOPPRUVZ^bgnuz}‚}yvusvxx|ƒ‡Š‹Š‰ˆ‡‡‡‡††††††‡ˆ‡…ƒ€€~}yusrrpomjg_YPIJQ[epy‚‡ŠŽ‹Š‰ˆ‡‡†‡‡‡‡„€zqf\X^fnuvwrp~–“‹ŠŠ‹‰…†ƒƒ{d^iwƒŽŽŽ‘‘Œ‰ˆ((((((((''(((((()))))****)*,,,,,*+++++*****)(+*)))))))))))))))))((((''''''''&&&&%%%%%%%%%%%%&&&&&&&'((''(())()))))**++++,-,-,,--./1011112333555555666666555555332211000/..---,--,,,,,,,,++++***************,.0a†’”–Ž•••—››˜–ˆ‡€Žƒƒ‹ˆ‚‹…wywvrme^UNLIKNNNKI:)((())**+---,/3+0VDB=?@>;=\“Œ‰††‹—€}‚‡qrwwytgTC8548LZODAFDD=51//.<Mez•™s4@LNPLA<?BSX]dp…˜ž–tum]Rbx|ŠŸšœ”{nrtrlfc[YPDA>=:97779:Mv„€€„‡…€g<75631/.-/39;CU_fks{‹••Š}w€‘š›—‹‡‡†~ZDDIKQP<<Mm}wx~~l_‰‚CMYccekhYP\flmmnlga`XPJM[Z]ZVOVbeUHA]dWQQOPPPRVXZ^diov{~‚}yvsuwxz}…‡Š‹Š‰ˆ‡‡‡‡††††††‡‡ˆ‡ƒ‚‚~|xusqqqomjg_XOILS]gp{„ˆ‹Ž‹Š‰ˆ‡†…‡ˆ‡†„€ypf\\bipwvuqy””‹‰‰‰‡ˆ…„„zd^`jv„ŽŽŒŒŽ‘‘ŒŠŒ((((((((((()))))********++++++++++++++******))(())))))))))))))))((('&&&(''&&&&&&%%%%$$%%%%%%%%%%&&&'''&''('((())))**++,,,-,,-...000110111233445556565565465554442120//.-------,,,,++++++**++****+,(*))****))),Z}‹”Ž‹Œœžœ™œ•‰ŠŒ‘’‹‡Šƒ‚‹Ž€}xvtmd]RE>BGMMKHH>-(')*(()*-.,+(),.:CP;?=><>J‘Š‡†Œ“˜•ˆ~‚…duxvpcO>777:EV\O?>B?@:40./:Kg„’—h.6QdTHB>>AE[ad{‘—‚vx{p~”–‹€š¤¢¢ “~rmhgd_ZZTOIB@>=;98:4[‰ˆw{…‚|{jD6643/../15:?Ph}~ywma_becdlx€ƒ‡ˆƒ|{ncY?@7<7EZBAbvxu|‚€dL`OMijgg`^[_hjmlnnkha^__WYZXUW\]ajhB08WoWQQPQQQSVY\`djpw|€‚‚}yttvxy|ƒˆŠŒŒ‹‰ˆ‡‡††‡‡‡†‡‡‡ˆˆ‡„‚‚‚}xutttqomje^VMIOV`iu~„ˆŒŽŠˆ‡††‡‡‡‡††ƒxpd]]dksvuou–Ž‹ˆ‡‡ˆ‡†„ƒ~g__enz„‰ŠŒŒŽŽŽŽ‘’ŽŠ‰‘((((((((((()))))********+++++++++++*********))(())))))))))))))))((('&&&%%%&&&&&&%%%%$$%%%%%%%%%%&&&'''&''''((())))**++,,,----.//001110111233445556565565554444322100/.--------,,,,******))**))**/2))))(())))),Pm}ŽŒŽ‹ˆ‰››šœ˜‡‡Ž‰Š‡ƒ‰‘ƒxwwtoe_UD@CJNIKHF=-(')*'(((*,++.-3+).8<>?<:<@“ŒŠŽ‘•–—Š€…Šinwup`LB88<DZf_TMDB@?;51//;H[}’’Y2Srx`LEA?@AOfnw•Ÿ–‚s‚¥«Ÿ¥¦¦›—®°ª¥—‡{rie`]ZVRNKEA==>??>;Z…~sw~€{xnQ8753300158?BVvŒŽ‡}iZVROMT[^`d`]\ZbtYB?=B4=AK7Kegnz‚…h&bqSZ]dklfhcbhopppkgd__\ZXYYYZTT\^X6(1OaURRPQQRTXZ\`fkrx}€ƒƒ}zvsuxy|„‡Œ‹‹Š‰ˆ‡‡††††‡†‡‡‡ˆ‰ˆ††„„}xtssspnlie^VMLQXakv~„ˆŒ‰‡†††‡‡‡‡††ƒwod^`gnswttŠ•‘‹‡…†‡ˆ†ƒ…iccbfq~‰ŒŽŽŽŽŽŽ‘ˆŽ”))(((())))))))****)*********++,,++******++))))((((((((((((((''''&&''&&&&&&&%%%%%%%$$$$%%$$$$$%%%&%&&&&&'''''(((()))*)+,,,,,,-...////01/11222445555654444433333201///..----,,,,++**++++***********)))'''''''()+Ik~†„‡‰…‚‹˜’‹ŽŒ}‡‹Œ‰ˆˆ„€€…’qtyslhaSLHGF<@IGE</(()*)((**+,+-,--*,/54=<7;L–—‹’–••“†€ƒ‡‚ruum[K<87D_lrh]WOF@B?810-8D_rŒˆPNwŒƒoSJHAA>NUe|…‹’ ­µ²²²¬¥ œ®³®¤ŸŽ}slec^YWXTMHB@@BCB@Cb‚†‚xw|}yvo[@:;;<7257<@E[xŠŒ‘‘‘‚qjc\VSMGFHHLXgsoLGI>G8>EDG?HWay€8E’’€IXVQVckb]lmqtqmhd`][ZYXXYZWZ]\VE?LWYUQPQPRRUY[_chltx|€‚‚€}zxwvz{}€„‡‹‹Š‰‰ˆ‡‡††††‡†††‡ˆŠˆ‡…ƒƒ~zwssssonlgd\TMNS[cmx€…‰ŒŽ‹‰‰ˆ‡‡‡‡††††ƒ~wme`bhovuq†“‹‰ˆ‡ˆ†…ˆkeebbhv‚ŒŽŒŽŒ••***)))))**))******)***********++))***)))**))))((((((((((((((''''&&''&&&&&&&%%%%%%%$$$$%%%%%%%%%%%$$$&&&&''''''(()))))+,,,,,,-...////0010122233555554444433333310////..----,,++++))****))))))))))*))&'''''''()+<sƒ‹Š†‹‚z~Ž–Œ‹z‚‰†~nv†„ƒˆ}qqqqocYQOMHF@AJEC>0'()*)('+**+,*)*)++-.17:@Kkœ™‘‘–˜—‡’Žƒ‚„‡ˆurtm[ICCCJWeok`UPPIAA@:5/2C[qƒyNc‡‚zzeG=E>NVP]yŠ–¥±³µ³°­«¤›”ª­¦¡¢–‡tnjda\bpg\QHEDDDDDP|’ƒ{z~wui_\Y]\_P48;>ABWo‚…Š‘Œywupcca]\[^afmpfBA=@BC;LAIG?Rgv€peŠ“„PPWKJVOKWqrrtqniea^\[[YY[\\\\\XVZ[XUUSQPPRRUX\_cinsw|€‚‚|yvwx{|}€„‡‹‹Š‰‰ˆ‡‡†††††…††‡ˆˆˆ††ƒƒƒzwssqqonkfbZSNPU]eq|‚‡‰ŒŽ‰ˆˆ‡††††…………ƒ~wmdcgirwr|’‘‰ŠŠŠ‡‡„‡…rhifbbjx…ŽŽŽŽŽŽ‘Œ‘˜•))****(****())++**))******++******))))((((((((((((((((((((''((''&&&&&&%%&&'%%%%%$$$$$$$$$$$$$%%%&%%&&&&&&&''''''''))(*,,++,,-...//00111012222244555544332233220./..-----,+++**))))))))('(((())))))''''''''&(),2k‹ŠŒŠƒz„ŒŽ•Š}}†‚sgd~‰†‡ŠŽq^_^`gdQQSUMLNNJFE?1'')))))(+(),*+*+,-,,047Uz‘•’”•—–›zŠ–ˆ„††‰ƒ|{vqssu}ˆ‹‚jY[ZUNGFGA72?Njxl\„•—‰„‹‘tL@>JULRmŒž¨±³°¬¨££¤¢Ÿ£œ•’‘Œ€smkhmmjsjcZSKHHICBN}”˜Ž‚€}wriiotzzve=68:>BNaz†‹„zx{{zsfdjg`\_fgjnZ[[X96:>MKCFDO`y|[rŒ’„TGRK6GMelprtsqoke_][[ZZZ\\[\][Z\ZWWUSQPPNRRUY]_cjnrv|€‚‚€~zxxy{|~„ˆ‹‹‰ˆˆ‡‡‡††…………†††‡ˆˆ‡†…ƒ€~yvrqqqonlgc\RPTY_hr|ƒ‡ŠŠ‰ˆ‡‡‡‡‡††……„~wmfegmuv{‘Œ‰‰ŠŠˆ‡†ˆ„oiiidbeozˆ‘’ŽŒŒŒŒŽ––•))))))(****+++++**))********))**)))))))(((((((((((((((((((''''''&&&&&&%%&&%%%%%%$$$$$$$$$$$$$%%%%%%%%%%&&&''''''''))(*,,++,,-...//00//1012222244444444222233310//.------++++**))((((((''&&&&''((''''''''''&()/3N‰Œˆ…€|‚†‹’Œ‹ˆwinnft‚‹‡Š‹ŠaOOPTV_]OMONKJKHGE?1''))*#*+**'&(+++*+,++.An’šš”’“•—–•z•Žˆƒ†ˆ‰‡†’”–•’”——’‰uRPRXRMGEJC64Jmˆw{”™›‘’Ÿ£Ÿ…hiZO@Mf«°°²­¥  ¡¬¤Ž £¤¤¢ž“i[do€vqnf_SJHKKGB@]Œ˜Ž‚€xuxxqv€‰„sP46;??DSiy}qlqusqmgcgf_[_cbgb\`seB7;=>FJQG;Nx{d{‹Š‚\IO>+@T]dqqrssolfa]\\[[[[Z[[\\\\ZXUUQPPPOPRUY]_chlrvy~‚€~|yy{{|~†‰‹‹ˆˆ‡‡‡‡††…………†††‡ˆˆ‡†…ƒ€~zvsqqqonlgb[RPTY`is~ƒ‡‹Ž‰ˆ‡†††††††……ƒ}wmfgjqu{‘Š‹Š‹Š‡††‡tjnliecgq~‰’‘ŽŽŽŽŽ‘’—””**))))*++***++++**))******))))))))))))((''((((((((((((((((''&&&&&&&&&&&%%%%%%%%%$$$$$$$$#$$$$%%%%%%%%%&&%%''''''''(())**)+,-,--.000011101222223333333322112322///.-----,++****))(('''&''''''''&&''&&''''''&(,1;Ek†‡…„ƒ†ƒ…‹ˆ‚ƒ„‚‡„qv‰ŒŽŽ‚[NLTXTGWb[ONNKJKFC=/%'(*,Im8#(,,))+,,././2T€˜ ˜’’•š––~{‘•‰„„ˆ‹ˆz’”˜™—–———–…`VXXZ\UJFGB:>a‰“•—–š¤¥¤ “†“š†_@OŒ¦®°¯­¢œž ¢Š¤¥¦¥ Ÿ”[<J`z‡~sleZJFHLKGADo“uz…„…ƒ}~ˆ†‚wa55:<=@HUflkcgif```[Y\][Z[_`_JQ\g`I:C?7ACFRGHex„ˆ‹…}RJT=-GA05eussqnjfa^][ZZZ[[Z[\[[\[ZVSRMMNNORUZ]`cejquz~‚€~|zz|{}~†‰Š‹ˆˆ‡‡††………………†††‡ˆˆˆ†„‚€}yussqppnlg`XTPW\clu~„ˆŒŽŒŠ‰‡†††††‡‡†„ƒ|wmggntzŠ“Ž‹‰‹ŒŠ‡„††vllmliffju€‹ŽŽŒŒŽŽ––”’********+*****++**))++****)))))))(((((((''((((((((((((((((''&&&&&&&&&&&%%%%%%%%%$$$$$$$$#$$$$%%%$$%%%%&%%%&&&&&&''((())))+,-,--.////1110122222332233221111110////------,++**))))''&&&&''&&&&&&&&''%%''&&''')18EYru}…‚‚ˆƒ~{z€|†˜¡ŸŸ’“”ŒŒ‰pWOQ]cZXUii_LFLKJGC:-$&'))9=(&'(()(*/0-0/-=a~›Ÿ”’”——””ˆ|}ƒ–ƒƒ„ˆŒ‚‘•™–˜™™™’rW[Z]_`YMDDA@n’’—–˜¤ª¦šs…š ¥Œ`l›ª¬¬©Ÿ™™™œ”›Ÿ–—šš˜”Y<AJr•}pibTJHFDEHAP}…€‡‹ŒŒˆ€ƒ~{tg>257<<AFR\][^`\VYYTOSTWXZ]WEBLU_la9;631=Y[eWVp€†‡†ƒ…cIJE8=@4=ftttrnifa^][ZZ[[Y[[\][[ZYUSPOOLOQRUZ^adgjptx}ƒ‚€|{|||}€ƒ†‰‰‰ˆˆ‡‡††………………†††‡††‡…„‚|xtssqppnif`XRQW\dnv„ˆŒŽŒŠ‰‡†††††‡‡†„ƒ|wmiimuŒ–‹‹‰Š‹ˆ……‡|lmonmkhhnwƒŒŽŽŽŽŽŽŽ“—””’**********++++******))***)**))))))(('''''''(((((((''(('''&&&&&%%$$%%%%%%%&%%%%%%%%$$$$##$$$$$$$$%%%%&&&&$$%%&&&'''''(()))+++,,-....011111113221123212233000000..----,,,+*+**)))(''&%&&&&&&%%&&%%%%&&''(&')*+7F[u{tdmqtxullkls€œ¢¤¡”•ŽŠŒz^WY]aba^fglp_[SMHHB7*'''((&'''''&'((*+-/,5Ldx‘œ—“”˜•”‘ƒ~|}“Š†‚…‰|ƒˆŽ’•—˜——Šrdac\[_]VJB@?^’–‘’’™’h[q—¡¦¨™}ž¥©¤™–•”—ŽŽ›•””“•–“…WACJaœ—‰{qjbQGBAFHD@a”ˆ“Œ…€ƒ€xtohH//28;>@CJRTWXWUTSPNQSTWYP:+<HNOSM@G?94@WJQON[p{„‹‰„eKCE@38E^pttsqnie`]\[[\\[ZZ[ZZ[ZZWSPNMNNOPSVZ^`chjorw|€ƒƒ€~|{|~€‚…ˆ‡†ˆ‡†††…„„„………‡‡‡‡‡†‡…„‚€|xusrqpomje_XSRV^enx‚…ˆ‹‹Š‰†…††††‡‡†…‚|vnkko…”‘Œ‹‹‰Š‰…†Šnmnomonilqy„ŽŽŽŒŒ‹‹‹Ž‘–•”‘Ž**********++++******))**))))))))))(('''''''((((((('''(''&&&&&&%%%%%%%%%%%&%%%%%%%%$$$$##$$$$$$$$%%%%%%%%$$$%&&&'''''(()))+++,,-....011111113223321110000//////----,,,,+*)**)))((&&%%&&&%%%$$%%$$&&%&&%&(**-5EYnqa`[X^cd\SX[\]s¡˜””‰ŒŽ€`UWeiidfdghrzqmhe]KA0&&''''&'''''&'((*++,/:Vht–“—˜”’Ž~yyy…•†„ƒˆŽ…‰’•—–Œˆujgffd`^\ZQF=;[–‘ŠŽŒˆ‰‚pfa\e£Ÿœ˜Ž•Ÿ¢––’‘‰‡—’““’‘‘‘ˆ{gMNf¦£•‹zoeUHDUt‰€hjyŽ—’’”‰‚€yrkifQ/,./58;=BIMPQQPPQONPRSQC00>?8;>:?CC=>=AJGIX[J^kŠ†ƒuXFIRD<NYlttsqnid_]\[[[[[ZZ[\\ZXYURONMNNNOSVY\`cfhmrv{€€}}~~ƒ…ˆ‡‡‡‡…………„ƒ„„……‡‡‡‡‡†‡…„‚€}yrrqqpomid^XUUX^gpx‚…ˆ‹ŒŠŠ‰‡†††††‡‡†…€zsnml€“‘‹Š‰‰Š‰‡…ˆ‡qnqpopomjlt{ˆŽŽŒŒ‹‹ŠŠ’–•”“Ž++++++****++++******))))))((()((((('&&'''''(((((((''''((&&%%%%%%%%%%%%%%%%%%%%$$$$$$$$##$$$$$$$$$$$$$$$$$$$%&&&'''''(((()+++,,-...-/11110002112210/10/0...//.---,,,++++)))))(('&%%%%$$$$$$$$$$$$%%&&%'&&*.4BZrzjb^VWY\YOCKQTZm‡—†‡’Œ‘gUR[ibdjhcdjtpumplwxgD%'&*'('&''('&)()(*+.7EVft”’‘”–”‹€|„”‡‚‚€†‹‹ƒ•’“““‡„ƒ‚ƒ~xxvpb]ZQH??}›ŠŠˆ„|m\_`_cx•™¢¦žˆz“š—’“‡s†ˆ‘•“Ž‹ŠŠˆ€|`Tyª£•‡vk]LDK]x‹’‘~›˜‰‚|xtnfa^V4-.)*.38<BFJMMMNMNOKH?3,/7BF7?FF@KOLI>BMI@LRT_bt†…xKAJZaPZopqssqnje_][ZZZZZZZZZZZXWTPNMLLMMNRUX\acdgjquz~‚ƒƒ€}~‚„ˆˆ‡‡‡†…„……ƒƒƒ„……††‡‡ˆ‡ˆ…ƒ~{vsqqppnlhd]XSV\`hry‚†‰‹Œ‹‰Š‰‡†††††††……€yrnkwŒŒŒŠŠŠŠˆ‡‹‰ulnmnpppmot|ŠŽŽŒ‹’”—”“’++++++****++++******)))))(((((((((('&&'''''(((((((''''''&&%%%%%%%%%%%%%%%%%%%%$$$$$$$$##$$$$$$$$$$$$$$$$$$$%&&&'%%'''((()+++,,-.../01111000211111021//.---..-,,,,++++**)(()(((&&%%%%%%##########%%%%%&'',1@Vu|uf^WYfdWQLEIVU\dx{|ŠŠŽŽ†lZ]`kgiknlbhopkopshmr|d<),,)())(''''((**-;NZbx“ŒŽ•‘Ž‰|…†…†”‹„‚€…Œ„|‹‘’‘”š¡—œŸ˜~h]\YPH=uœ•ŠˆnZ`ppknp‚•¦¡ˆŽŽ~s‚‰„‚†ˆ„~~phƒ¥œ™•‰yocRDCHnŽyš›‘Œ‰yskf^[ZV@,+('))+/479<????<81,*+.35EU>6;?EIK?BQNJ<LLNUV_hy‚„r<=ERb[`opqssqnje_\[ZZZZZZZZ[\YWURONJIIKLNRUY]`bdgipty}ƒƒ€€€€ƒ„ˆŠˆ‡‡†„„„ƒƒƒƒ„……††‡‡ˆˆ‡…ƒ~zvrqqppnlhd\XUWZajry‚†‰‹ŒŒŠ‰‡‡††††††††ƒ~wqkq‰ŒŒŠ‰Š‰ˆ‡†ˆŠ{mqqrrtvvwx}„Š‹Œ‹‹ŒŽ’’“–”“‘‘Ž++++++++++++**********))(((((())(())''('''''((((((''''''&&%%$$$$&&%%%%%%$$$$$$$$$$$$$$##$$$$##$$$$$$%%$$$$$%%&&&&&'''())*+++++-...00001101110011110.-----,-.-,++++**)++)((''&&'&%$##$$$$######$$%%%%&&(+1=UrzvsgUQ]qtc]]QIJ[bcspƒŠ†‡ŒˆqSPWlumpmpnmmsmojrtmfsr~‹`7%(+*++*(19-)(().;MZc…ˆŒŒ‰†‹‰ˆ‡‹ˆ•‘ˆ‚}}}„‰lHXbfw“™œ¥¦¬ª¦™Šwa^ZSLIj˜˜„}r[s‰|yz€‚€‘¡£—ˆŠˆ†‡†yop|‡‹„~„™Ÿ“‚vu‚›•’†zqj`PCT}Š‡€s…‘˜˜Œ†€unhaZWQNF0)(('('&')*))(('&')++.168=EJND>:=<HXUHI:0NMECRdj}{dNBBCMV`nrrsrqmid^\[ZZZZZZZZYYWUTQOMJJIKLOSVY[`ceeknry~‚„„‚€€€„‡‰Šˆ‡‡…ƒƒƒƒ‚ƒ„…†‡ˆˆˆˆ‡‡†ƒ~yurppppokhd]WUZ]bkt|‚†ŠŒŒ‹‰ˆ‡†††……†††…‚}wqo†‡ˆˆˆŠ‰ˆ„…‰‚qrvz||~€ƒ„„‰ŒŽŽ‹ŠŒ‘’““‘”’‘,,,,,,,,++++**********))(((((((((((('''(''''((((((''''''&&%%$$$$%%%%%%%%$$$$$$$$$$$$$$##$$$$%%$$%%$$$$$$$$$$%%&&&&'''())*+++++-...//./00/011110000/.-----,,,,,++*****)()(('&&&&&$$###"####""""##%$$&''(-6Nlzuqxsnvwwuib\G/@jos}nˆ†‰‰}XGNYuqsumks…vggmv~vflyv…Œa7$(+++*0>0')))-;NZiŒ‰†‰‹‡†„†Š†ƒ‡‹‘˜—‹{zvzˆ`5OYfqx’¥°°±©¡˜†nc^\PIc“™“•‰„v]u’”‹Œˆ„ˆ”œ •zx~‚}xtq’”‚mt‡˜¢ª¦¡–~ˆ‹ƒ|vqldXEg…‰Š…|“”…€wngb]UOIC:.(&'&&&&&'((((')****,.16:=CDLHG<59NG<;@G:3AIHTdw‚ve\VkhQV]fqrsrqmid^[ZZZZZZZZZYYWURONKJJJKLOSVY^_bbdhlqx}ƒƒ‚€€‚ƒ„‡ŠŠ‡††……„ƒ‚‚ƒ…†‡ˆˆˆ‰ˆ‡†„}yurppoomjfb\WUY_fmu|‚ˆŒŒ‹‹‰‡‡†††……†††„{vp‚‹‡…‰ˆˆˆˆ‡‰Š{yƒ†‡‰Š‹ŒŽŽŽŒŒŒŽ‘‘‘‘‘,,++++++++++**++****))))''''''''''''''''''''(((((())((''&&&&%$%&%%%%%%%%%%%%$$$$$$##$$$$$$$$$$$$%%##$$$$$$$$$$&&&&&&&()))*,,,,--......//./0000////..-,++,,,,,,,+*))))(((''&&%%%$##""""""""""""##$$%%%(+5Fdyxsw||zz{vtj_UE<Jdryuq‰ˆ††„lMO]ipszxwrmq€tqjgnyz}jozuz„‚xZ.+'*(()))+++.@PYp‡†‚‚‚‚}~ƒˆŠ‡ƒš“„zwusyƒ‹\GJRZk‡Ÿ­±®¯©ŸŽtd`ZTNaœ“•ˆt^v“ŽŒ’”Ž……”™phtxkt•¤ª¨‚ZPYk„—™”Š’™“ŠƒztqpneXEg‚…Š‹‡~Œ‹†wh[SPOJB9.'$&$%%$%&%%''(')('')-./792367?FRD564JOJY>3+1?P[cb^jjVWird\[`lqsqpmid^[ZZZYYZZYYYYVTQMKJHHJKMPSVZ\^`bdgkqv{€ƒƒƒ„†‰‹Šˆ‡†…„„ƒƒ€ƒ………‡‰ˆˆ‹†‡…„€~ysrqponliea\XV\`fmt{‡ŠŒ‹‹‰†††††……†‡…ƒ€{p~Ž‹ˆ††‡‡†‡ˆŒ…„ˆŒŽŽŽŽŽŽŒŒŒŒ‹‹ŒŽŽ,,++++++++++********))))''''''''''''''''''''(((((())((''&&&&&&&&%%%%%%%%%%%%$$$$$$##$$$$$$%%##$$%%$#$$$$$$$$$$&&&&&&&()))*,,,,--......//./00//////..-,+++++++++*)))(((('&&&%%%$$##""##!!!!!!!!""$$%%%*0Dbxwqv|~|zxtph\PHQaj}~jwŠ‚ƒ‚zWQWqymr{qqquytwu€op~yto_urbmŠŒŽrN3((()**+++4GT^xŠ…€{ptx|}€„„Ž—™•Œ€vpmqz„W:O]s‡Ÿ­°¬®§Š]IMNQNN_š˜š€jP\…‰ŒŽŠˆ…Ž“{jkox€•§«§£—{SJJGYƒ˜„Šš—“ˆ}sonnofPA]‚ŽŽ…{‚€…€tbG:4342.(%%#%%%$$$%$%%%&%'(*,/015?53/*+.2>^R?@QJ<QG-+4AZ_RTIOtr€vnSQ]hprqpmid^[ZXXWWXXYYXXUSPLJHHHIKMPSVZ\^`acfjpuzƒƒ‚ƒ„ˆŠ‹Š‡ˆ†…„ƒƒƒƒƒƒ„‡„‡‰ˆˆ‰‡‡…„‚|wsrqponliea\XX\`hov}ƒ‡Š‹‹‰‡†††††……††…‚~z|ŽŠŠ‰‡†‡‡ˆŠŒ‹’””‘ŽŽŽŽŒŒ‹‹Œ‹‹ŒŒŒŒŒŒŒŒ,,++++++++********))))((((''''''''''''''(('''((())((((''&&&&&&''&&&&&&%%%%%%%%%%#####$$$$$%%###$%%%%%%$$$$$$$$&&&%&&(())(*,,,,------..////..---------,++**++***))))(((&&&&&$$$####!!!!!!!!""""##$%%$(/>Wsxqtz||z{zzrjf[NIWivˆ}p€‚€‚iKNPcnnhikptuqfuxyposvkeX`plW—’‘mdg?2')))(*5ALYcˆ‚}}|vnpstvrv}„Ž’Œ†{urppz…WQ`rŠš®²°©C=DEDKPP[Š›šžšT:=ds{‚…{xy‚|h_aixˆ–¢Ÿœ›“~UFHOk‹–•’š”‹trskhkoaHFSlx€{rnyy~}cB40.,*(('&$#$$$%%$%&&%$%'',/1022473-(&&)*.E_PXYZYVI,+-9QPTL\y}}‚‡zSQOXcppqpmhc]ZXWWWWXVXXWWUQOKJGFFHJLORUY[^_`aeinty‚‚‚‚‚ƒƒ„ˆ‹‹Šˆˆ†…„„ƒƒƒƒ„„‡ˆ‰‰Š‰‰‰‡†ƒ‚|vsrqonmkhe_[XX^cjry~ƒˆ‹Š‰‰‡………………„……„‚||‘‘ˆˆ†…†ˆ‰‘’’“’ŒŽŽŽŽŽŽŽŠŒŒŽŽ‹‹‹‹Š‹‹,,++++++++********))))((((''''''''''''''((''(((())))((''&&''&&''&&&&&&%%%%%%%%%%$$$$$%%%$$%%##$%%%%%%%$$$$$$$$&&&%&&(())*+,,,,------..////..---------,++****)))((((''''&&&%$$$#"##!!!!!!!!!"""###%'',8Lktrrw{|zz|yxqlbVNJ[v‡ˆxuƒ}}€yYGGSinokekfjsmhl~rosohigGjnTn”†qhft?MD)(,*)2<LYf…‡zyy{uljnnjkknr‡Šˆ‡…zqtrnvƒˆe`v›ª¯¨wiQB==@PYZ[‡”œ…V8ASgw{vrpopspjls~‰–›—ŽŒ}T=>N{••—•Œ~cS\`befUHBFWswqi`jpuuS401/,*(('%$#$$$%%$%%$&(+-.12463220.(&%%')+<SXNVT\WH?/2@JORXR\lsyvmYMWnrqqmhc]ZXWWWWWWXWWWTPNIGFEEGILORUY[]]_aeikqw}‚‚‚‚‚ƒ…†ˆ‹‹‹‰‡†…„„ƒƒƒƒ„„†‡‰‰‰ŠŠˆˆ†ƒ€{vsrqonmkhc^[XZ`eltz~ƒˆ‹Šˆ‰‡………………„……„}Š‰‡‡‡ŠŒŽ‘’’‘ŽŽŽŽŽŒŒŒŒŒŒŒ‘ŽŠŒ‹‹++++++++********)))))(''))((('''(('''''''''((())))((((((''((''&&''&&&&&%&&%%%%%%$$$$$%%%&&&&%%%%%%&&$$%%%%%%%%&&%&&'())**+++----....--//--------.,,,,+*)))(())(((('&&&%%$$%$##""##!!!!!!!!!""#""$%(+5Gasqsv{|yyy{xusj`UJJc‡u}z{|nMEL]hiijebdgjmluw„rc‚‚xoiGPw_Ekdf[hhnvZ:+++4?KW`„„~vywvsljkhcdifinquwx|€uqnnrx‚lzŠ•¢žwawQ=7@Xnph`Ž””`9@ao†rmjikpnjkw†Ÿ¤œŒƒ}{wdHA=Mr„†‹Š†yM/3AQa_PJKUozrlb[dppkJ,/0/+*(('&&%$%%%&%('()+02121574.+*)%&')+)+7AFQQUMVgCA@JMRSMXV_]fk{toaKVirrpmgc]YWWWVVWWWWWVSOMHFDBCEHKNRUXZ]^^`dhkpv|€€‚„†‡‰‹‹Šˆ††………ƒƒ„„„ƒ†‡ŠŠŠ‰ˆŠ‰†ƒzurqqommjhd_XZ_agou|€…‰ŒŠˆˆ††…………………ƒˆ‘‹‡‡‡ŠŒ’’’‘ŽŽŽŽŒŒ‹ŠŒŽ‹‹‹ŠŒ’’‘ŒŒŒ++++++++********))))((''))((('''((''''''''(((()*))(((((((((('''''''&&&&&&&%%%%%%%%$$#%&&&&&&%%%%%%&&%%&&%%%%%%&&%&&'())***++----....--..--------,++++*))))(())(((('&&&%%$$##"""!""!!!!!!!!!!"#$$%'*3C[noov{{wruwvwutg]UJIiˆs|z|}bIGP`acfjffhcUNVYXcgQ]YWQVD>co]€‰dWg]hfYVI9/3>JVZ~„}zvuvrpoliecba^_agecby}qlnmlu‚}sˆ“RS[Q>:Jk„Ž…rc‰{‚pLQkvŠynifbejioy—¦žŽzvqqkM=:<Kcu…ˆ—‚pD/,/?cg^Y[h„ˆsf]fmj_F*-0-+*('&&&%$%%"#%))**/4568>FCD<+'(&&&()))07?IY]U]cP@ELFMWk\SWS^kyK@]Lfkfqomgc]YWVVVVWWWWVURPKFEBABDGKNRUXZ\]^^afjou{‚‚ƒ„†‡Š‹‹Šˆ‡…„……ƒƒ„„…‡†ˆŠŠŠ‰‹Š†…}ytprqommjhc^WY_diqw}€…‹ŒŠˆˆ††……………………‚…‹‰ŠŠŒŽŽŽŽ‘‘ŽŒ‰‡……‡ŒŒ‹‰‰‹Œ’“‘Ž‘’++++++******)))))))(''''(('((((((((((((('((((())))((((((((('&&((''''&&&&''%%%%&&&&&&&&&&&&&&%%%%%%%%&&%%%%&&&&&&&'((()()**++----..----.---------,+*****)))((((((((&&&&%$###"""!!        !"!!""#$$'0B\nlmq{{tqrvxxywof\RDBn…xk€xxyqVFHQbhjmfbUTNDKHHEFJE>887;BAF^ZJˆŒpa~tpnaTKHA;>JPVyƒ}ytqqqssohe_[ZWYZaaWHIqupoifkw‚u|‡[OVN?<LvŽššo_†‹ŒŠsNceezzŽ†wmgb]bfej‚£ ’‡xleh^HB=;GZgv‰Ž…{`<,,3GivnYXf€‹ƒ…qlmeU>)*,,**('&%%$#$$#"$&%&,:BEEDGGB=5)&&&&&()'*/3:DDJWd`ZVF@;@LWXZ\>B[T28fQN]irpmhb\XVTTUWWWWWUTQNJEA@@ACFJMQTXYZ[\]`chmrz|~€ƒ……Š‹‹ˆ‡ˆ‡„…„„„„ƒƒ„††‡ŠŠ‹ŠŠˆ‡„}xsqpqpmljga]Z[`djqx}†‹‹‹‹ˆ††……………………‚Ž’‹‡‹ŽŽŽŒ‹ŽŒˆ†ƒ€‚ˆŒ‹Œ‰ŠŠ‘”“ŽŒŒ‘Ž++++++******)))))))(''''(('(((((((((((((((((())))))((((((((())((((''&&&&'''%&&''''''''''&&&&&&%%%%%%&&%%%%&&&&&&&'((()()**++,,,,..----.---------,+**)))))(''''''''&&%%$###""""!       !"!!!"#$%,<VqphntytmmprswxvnbVM=:h†‡rrwrwykNCHUgilvdWGDGAJPKKJJDGA>;;@F?O]:k{…ˆ‡„~tcTMIEA@FJQr‚zvsronprnie_[YONT`^RF2Gjmnjhhnv€|c@KNNEHo¢žj\o…‹†y51Lw“‰€wkd^[^c\f™Ÿ–‡|o\al\FB@DMWakqwvunU8+-;Rht~wd^dx††„„{i_S4&)-,*)''&%%$$$$#""#$(/:BDC?:8760'''&'((''*16:=8GQX[YVOIKCLYZRPF6Q\MVjYJYrspnhb\XVTTTSVVUUTSPLJEA@?@BEJMQTXYXZZ\^aejqw}~€ƒ…†ˆ‹‹Š‰‡†„…„„„„ƒƒ„††‡Š‹‹Š‰‡‡„€|vsqqqpmljga]Z]afks{€ƒ‰‹‹‹‹ˆ††……………†††Š‹‹ŠŒŽŽŽŒŒŽ‹‰…‚€|y{~‚‰ŽŽŒ‹ŠŠŠ‹““’Ž‹’‘‘Ž,,+++++*******)))))('()(''((''))))(())(((((())))))**)(((()*((()))('''&''''''''((''''''''''''&&''&&&&&&&&%%%%%%''''(((())*+++++,,------------,,+++***)))))(''''&&&&&%##$#"""!""!!!!  !!!!!!!!###&)7OmrikqvslijkoqvwtkcVK?;j‹tyrpxwbKHPag_`hWJFDICHNKLKMECB@>?>E@AJD:<w‡„}rbUMFDCCBFLg„wusqnlnongb[X[SNNCLOI9,FjjfjhjowzG<BIIGm“¢££¡sa]Ž†‡C+=€˜„{wh_\YXZSu¡˜€p[PY\M;:BIRW[adfjkaM7,7I\inv~vjyŒ…z}k\J,%(***('&%$%%$###"""!&/7:<?>==;81('''(('(&*1;=79BGI[^[\GFADKKIV`R@YRcn^J\stpmgb\WUTSTTTTTTSRNKGC@??@AEILPTWXYZZZ\^bgntx}~€ƒ†ˆ‰‹‹Š‰‡†„…„„ƒƒƒƒ„…ˆˆ‹‹‹ŠŠˆ‡„€|vrqpppoljga]Z\`hnu{€…ˆ‹‹Š‰††………………„†ŠŒŒŽŽŒŒ‹‹ŒŒŒŠŠˆ†‚~|yyxy|€…‹ŽŒŠŠŒŽ““’‹‹‘Ž,,,,,,,+******)))))('()(''(((())))(())((((()))))))****))()*((()))''''&''''''''((''((((((''''&&''&&&&&&&&%%%%%%''''(((())*+++++,,------------,,+++***)))))(''''&&&&&%####""!!!!! !!!!!!!!!!!!#"#)0FftmkptsmkhijmpsurkcVJ>6f—’~quxz\CHQek_]_PDFILGMQOMJJDBA@A?@BDCCF@n„‰‡ƒzkYNKECBBADG_…xvtqnjikjga^ZVPG>63;=867VmggffgowqF:7;_Œ£¦¤¦ž‡u`eyŒ†‰K1@„—‡ƒzsbZXVVNTˆ›’„yjONYP;19BKQWY\_cfe\J60=Qcikku|~™œ’‚z|wdT>*&'))*('&%$%%$###"""#*3:=?A>>;630+&''((((&)-2319<:DU[RW\D?DQTU^i]Lbwx~gDXktomfb\WUSRSSTTTTSRNKEC@??@AEILPTVWXYYYY\`dkqx}~€ƒ†ˆ‰‹‹ˆ‡‡…„…„„ƒƒƒƒ„…ˆ‰‹‹‹ŠŠˆ„{urqpqonkhe`\[^cimv}‡‰‹‹Š‡††…………………‡ŽŽŽŒ‹‰‰‰ŠŠ‹‹‹ˆ„|yxxwwx{}ˆŽ‹‹“’Œ‹‹‘’ŽŒ‹**************)())))(((())))))))))))))))))******++**,,,+****))))))((((((''''))))))))((''((''''((&&''''&&&&&&&&'''')))***)*,,,,,,,,,,..--,,,,,+**))))))((('&&&&&&%%%$##"""!!!    !!    !!! "$#$(/B^qmjottlhfdadintsskbUH81U”‘„vnszm[HKSda\]ZLDJONNORSRKGGEFILA<>@?CEDW‡‡†€rgUJGCBAB@>@\‡ysopokhhhea]YTPH91155556<iligcehm}X02As˜¢¥§¤•…m\vq‚‚`7>w‘‡}shVRUTTMq›–…yn^OZaT54;GNTX\^abc`YF9?KZdgfglph“™‚ysi^T?,())())'%%$#####""!#%09<=>?@<831/*''((((&&(-.1347:<JZZJSOC=@IHLPLZmwnidEWmuunic[XSRQPPSTSSRQOJEB>=>@BFIMNRUVWXXWWX]bhnuz|‚…‡‰‰Šˆ‡‡……„„ƒƒƒƒƒ…†ˆ‰Š‹‹‰‰‡‡„€{urqppoljfc_\]_ciqx}‚‡ŠŒŒŠ‰‡‡…………………ŽŽŽ‹‰ˆˆ†‰ŠŠ‰‰ˆƒ}yvvuvvwy{{ƒŠŽŽŽŒ‹’’‘Ž‹‹‹Š’“‘ŽŒ‹**************)((())(((())))))))))))))))))***+**++--,,,+**++*)))))(((((((((())))))))((((((((''''''''''&&&&&&&&''''((*****+,,,,,,,,,,--,,,+,,,+**))))))))('&&&&&&%%%$$$"""!!!    !!    !! "(5%&-?Wrtlntunieb_\_inswqjaTG6-J’„trrvaOJLO]YSROCFMONKLPY[PHHIFHLPNBA@@CDA€ˆ…}n_QICA>;=<9;T…}qopnhfgec_\VUPD533113356Mplhfecltt>,O~˜ £¢˜Š}cZw`v|r:6oskXNORRQW†–‡wmcXTVZUB?DKRW[]_`caZRHELR\bdgkpy€™Ž}sng_ZU@,*'(())'%%$####!""!#,7<=>?@?<8530+('((((''&+.135557;CMOBFUZ>AO\TVY\bMS\JRivwple_WRPPQPQSSSRQNHDA>=>@AEIMOSUVWWWVVW[_fmrw}ƒ†‡‰‰Šˆ‡††…„„ƒƒƒƒƒ…†‡ˆŠŠ‹‰‰‡‡„ytrqppoljfc_\]`fkry~‚‡Š‹‹‰‡‡‡…………„‚‹’‘‘ŽŒ‹‰ˆˆ†ˆŠ‰†ƒ}xwtuvwwwxz{{€…ŠŽŽŽ‹Œ‘‘Œ‰ŠŠ‹”“Œ‹****++******))(''()))())))))))))(())**++*+++++,,++,,,,,,,,,,*)))))(()))))))))))))))))))))))))(''''''''&&&&&&&&''''((()++**,,,,,,,,,,,,,,,+--++*)))))(((('&%%%%%%$$$#%%"""!    !!    !!  "%(,>Vounqsvojea]WV]iqvvrk`SF58[‰|prsl\QFGPTLDACDGMKKJLN]\OFDBA@@RVD=A>D>>i‡vmd[TD;888779B~~rlljhdc_XVWVRL<..1/./0275drja`cgis_9^|™›”ŠnNR^CavsG7rxlaGGGMNNdƒˆwh^ORTPLSUPSVY\^__bdb`RJNW]`dlolp™Ž|oieb[YS=+(&''(&&%%$###$"!!"&1;==?@A@>;864-&$&&''%$&(,/0256777<IFFKPGCFNMUdbZTVVOEIezqlf^XRPPQOQQQQRQLHC@>=>@DGJMOSUVVVUTUVY]cjpv|€‡ˆŠŠ‰ˆ‡†……„…„ƒƒƒƒ…†ˆˆ‹ŠŠŠŒŠ‡ƒ~xrpqqpnljeb^]]ahntz„ˆŠŠ‰ˆ†††††„„„‡’’‘ŽŒ‹Š‰‰‰†ˆ…‚}zwwvuwwwxyyz{|€†‹ŽŽŽŽ‘ŒŠŠ‰‹’•“Œ****++******))(''())))))))))))))(())**++++++++,,++,,,,,,,,,,*)))))))))))))))))))))))))))))))))((''''''&&&&&&&&''''((()**)+,,,,,,,,,,,,,,,+++++*)))))((((&&%%%%%%$$$#$$"""!          !! ""'-<Vpunnswpifb\TPP^krxvog]PD56Mw†tmps^LTEDLHEA?DEGFIIIIPVVOEEF?>=;9D??>=A@J€tlgdTA;6764468b~smjgec_\QLNMIE6**/.,./018Oojedcabfp[c{ŠŒ„zmRFFCBW~upU:vŠtk\BEGLKRkvui^TSTVXC<PZY[Z]`bcdfebVP^giglxl]w“|nga_]VUR?+(('('&&%%$##$#"!!!)5<>>?@A@?=<85+$"##$$##%&*.10379<;:9889CMLLQ[UX_aWEI_dKOqtmd]XSQPOQQQQQPOLHC@>=?ACFINOSTUVVUTTUW\bkpw|€ƒ‡‰ŠŠ‰ˆ‡‡†…„„„ƒƒƒƒ…†ˆˆ‰‹ŠŠ‹Šˆ€}wrpqqpnljda^]^biqu{€„ˆŠŠ‰ˆ††………„„…‘’Ž‹Šˆˆˆ‰ˆ‚|wwvvuvvwwwxxz{}ƒ‡ŒŽŽŽŒ‘ŽŠ‰‰ŠŒ‘“•“Œ********))*))))'()))))))))))****))**))**+,*,++,,,,----..,,,-+*++**++****))**++****))))))))))))))''''''''''''''(())(())***+++++--,,,,,,,,++*)***)))((('((&%%%%%%%$$$#"""""!!    !! #')9TovpnswskeaZTMJO]iotsme[NC75I]kfhqSEGC=BEGCBDEHFGIIIKQQNF@BBCED>;B==>?@:m{rkfcM@D=411235;rrieeeb`ZQKNOKE6-**--.//.7@inifb`\`jiiw„†xlT>FBAKX}xjbBz†tfW@BHJLVdge\TSTVVE4.8Vg``_ceddggg\_imlr{r^`‚ˆ|le_]\WQPN>+%&''''&%%%$$$!"!"&1:=?@@@CB@?>;4,$"""$$""$%'*./15:===71.+.6HVXPRYYiiLIbbZLmukc\XXZROPPPQQQNJFA>=>@CCFJMPRSRUWTSSUW[bjpv|‚‡‰‹‰ˆˆ‡‡†…„……ƒƒƒ„†‡Š‹Œ‹Š‹‰…€{trppppnljc`]]_eipu|ƒ†ˆŠ‹‰ˆ†„„……„„Š‘“’‘ŽŽ‹‰‰‰ˆ‡‰„zyywwwwvwwwwvxyz{„‰ŽŽŽ‹‹‰‰†‰Ž•–”’ŽŒ‹))******)))))))())))))))))))******++**+++,++++,---------,,-,,+++++++++****++++++++**))**))))))))((((''''''''''(())(())))*+++,,----,,,,,,++*)))))**((('&&&%%%%%&$$$##"""""!        !!#%+7Vpyolqvvoga\UMDEO]gnqskbWJ>424`~hgmoJFC>:@CGEDDEDGHHIIFKOQTXdnnqokcURU_P79Wxqjg_OB@93212312Hrjcba_^YQLIMNMG;.*.1/./237Joni_\[]bmsw{|uk\A?BDMS`rn__Mu„seSAGIJMZ]ZXVTSUR@0.4C_jmnkggfgiieckortzg[W`z{lc]YXYRPMJ;*&%&(''&%%%$#"""!#-9<>AA@@B@@?>;5("####$##$%%%(*.1379862,++.<R`Z[_alfaPIFSJfrne\W_^^YOPPPPNKHDA>=>@CFILNQQQQSTSQQTX\ckqx~€ƒ‡ŠŠŠ‰ˆ‡†……„„„ƒƒƒ„†‡Š‹‹Œ‹ŠŠ‰„€ztqppppnkic`]]`flsv|ƒ‡ŠŒ‹Šˆ†…………ƒ‡ŒŽ’’Ž‹‡‡‡ˆ‰‡€}yxyxxwwvwwwxxxzz{„ˆŽŽŽ‘ŒŠ‰ˆ‡‰Œ“––“ŽŒ‹‹(())))))(((())))))))))))))))****+++++++++++,,,,--...------..,,,,++++++**++++**,,,,+***++*)**))))((((((''''''''(())**))****++,,,,--,,,,,,**+***)))*)))&%%&%$$##%%$"!"##""!!!        !! !#'5Qnxrnpuuslc]VLA=DP]forpi^WJ<411f|khokEE?99=BEFFEEDFIECFCCLi‚•š†xvwiU_qyY7?snke[M?621110./13Xkc`^]\XRMJIJMNNG9+*-/-/343RrmaWXY\amzvpjbM<@?B]`gbYZXRmm`NHJMLORRTTUSQM=303@Sgqtxzvokilljmry}rZIZPWffc^[XYTMJHD5'$&&')('%%%$#"# #)7=>=@@@@AA@@?<3& ##"#%$$#$$%'(),-.*+*+*)+-7P\RZcdba[\i[K[soi_c[@V_SOOOMLHGC@==>ABDGLOQQQRTRQPQSX\cksy}€ƒ‡ŠŠ‰ˆ‡…„„„ƒ‚‚‚‚ƒƒ…‡Š‹‹‹ŠŠŠ‰…~ysppppomjhca]^bgnsy}ƒˆŠ‹‰ˆ†††„„†Œ“‘‹‰‡……ŠŠ{{xxxxyyxvwwwxxwwz|†‰ŽŽ’‘ŒŠ‰ˆˆ‹Ž“—•’ŽŒ‹Š(())))))(((())))))))))))))))****++++++++++,,,,,.......------,,,,++++++++,,,,++,,++*+++++*)**))))((((((''''''''(())**))****++,,,,,,,,,,,,**))*)))(((((&&&&%$$##%%$$""##""!!!        !!#$(7LkwmmsuvuqiaZOA:=DO^hmnlf^UH<43>tvhgncAC@:9?ECDEDCAEHKFBBHh£ªª¡•‹|wx{hWg‚{T/`ole[K=62231/./12<dc_[YXVSPLKKKKOMJB61-+-31+/Zf^XU]]_fowjaYC=<Facb`]ZPTdd{dUGHMPQRTUUUQOH?411;N^mwtrwxurqqqprstu]GVODQZ^_[XUURLHE?2&$'''''&%%%$##"#(3<=>?@@@@AA@@?<2% ##"#&&##$$&.))&%&***+*++,.3FJ[__X`dZ_YLVqrbZE)4NNLOOOMLHEB?==>ABFILOQQRSRQPPQSX_dlsy}„‡ŠŠ‰ˆ‡…„…„ƒ‚‚‚‚ƒƒ†ˆŠ‹‹‹ŠŠ‹ˆƒ~ztppppomigb`]^bhnty~ƒ‡‰ŒŠ‰‡…………†Š“‘’‹‹ŒŠ‡‹„ywyzyxxyxwwwwvwwwxz|ƒ‡ŽŽŽ‘“ŽŒ‰ˆ‡‹‘”–’‘ŽŒ‹Š))**))))(())))))))))*)))))******++++,,+++,---.-.//......-.-,-,--,,,,,,,,--,,++,,,,+++++++*++****))((((''(((())*******(******,,,,+,,,,,,,*)()))**('&&&%%%%%%%%%&'**%$#""!""!     "#  !!%(0Ijwmhntxtsnf\SC76?HQ^hoplg\QF:46P~rabl_ABA:6?EBBBCC@CHQJ?H^Šž¥­¥”Ž’”ŠqZb}‰w;FrkeZO@622233/.155>^`WVUTSRNLMMKLLKKH</),/-&'4_b_[X[^deqn^R=;@^_UZZ\WPGPQk`PCJJMNRX\`]ZNE;313EYfpvuqprqmjloonnlpKOUGFQ[]\ZVUTNJFB:-##$%&''%%%%$##$'29;<>??@AAAA@@?:/#! !"""#&#!"%)+))++**++++,*,//1DVmigf_fjXRVngh`N+1FOPNNNLKGDA>==>ABDGMOPPRRQPPPORY`gou{~‚…ˆ‰‰‰ˆ‡…„„‚‚‚ƒ„†‰Š‹‹‹‹Š‰…‚~ysoooonlhda`_adjpv|€„ˆ‰‹‰‡‡…„…†‹‘”’ŽŽŽ‹ŒŒ…|{yzxyxxwwxxxxxxxwx{~„‹ŽŽ’‘Œ‹ŠŠ‰Œ”—–“‘ŽŒŒŠŠ(())(((((())))))))))*)))))**++**++++,,,,+,---..///......-.,,-,--,,----,,++,,+,,,,,,,,,,++*++****))((((''(((())*******(******,,,,+,,,,,,,*()+))))(&&&&%%%%%%%%%&*00&#"!"!""!     !!!!#%&1FdyogkrxvvrjaWJ807AJT`iprme[OD81<aƒpefnZ@D@96<CDAACCBDEHEKdƒ™ ¤¬§•˜œ}vtj…‘†e3pje\RC2.,,***+,/0/;V\WSPPONMLMKMKJIHE@5.1.)$):Z^abca]^hhaH:BUZW[`aYRLIDGNXMFLQOORU[a_VL@9307J_kotvsnmlgeijgg_\ZGZNIHR]^\ZVURJFC@5*$$$$''&'&&&%##&08;;<?@?@AAAA@@?:/##%!!""""##%'(***++**++++++./38@TbhmoideUMWije^\XUONMNNNLJFDA>==>ABGJMNPPRRPPOONSZ`hpu{~‚…ˆ‰‰‰ˆ‡…„„‚‚‚‚…‡ŠŠ‹‹‹‹Š‰…}uqoooonlhda``bflrx~‚†‹ŒŠŠˆ‡…„†ŠŽ’’“’ŽŽŽ~y{yyxxxxwwwwwwwwwwy|‚‡‘‘ŽŽ•Œ‹ŠŠ‹•—•’ŽŒŒŠŠ(((())(()))))*****))+*++**++++,,,,++,,,,,,..--//..........--....,,..------,,,,,,,,,,,,,,,,++**++(((((((())))))))**++**+++++++++,,,,,,,,+**))))(('&%%%%%%$$$$$$&&)(%#""!!""!!!!!!  !"$)-@auskkrvxxtoe\M>01:DPZbjqricXLC71Eu‚lgjqVAF>99?CDCBBCACEDIa—£¦¨ª¬ª¡œ™–‡vyz’ŽŽ|Edlf`WOGGFEEFEFJLWZTHLRSRONMLKKKKKHGDDD>73.*'#%>YYW[\]]^]bUIRYRTWVUSMJG@4;EADIMLLQTW\\VI<701=P`lptvtnkhgfiige_[NURGHMZaa^[USMGD@=1($##%%%&&&&&$""+59:<>>??@BBAA@@?:/##$#""!###""%((**++++***+,.148=BDGTfggmiNL^jjd`ZTLLNMNNNMKGC@>=>?ADFIMMPPPPPPNOOUZbiqx}ƒ…ˆˆŠˆ‡…ƒƒ‚€ƒ†ˆŠŠŠŠ‰ˆˆˆ„ztpoooomkgecbbchnuz~‚ˆŒŒŠˆ‡‡††Š’’‘Ž‘ŽŽyyxywxxxxwxxwwwwwwxz}„‰’’ŽŽŽ““ŒŒ‹‰ˆ‹‘–—•‘‹‹‹Š(((())(())))*+******+*+++*++,,,,,,++,,----..-.//..........--....,-,,,,----,,,,--.-,,,,,,,,+++*++*((((((())))))****++**+++++++++,,,,,,,,+**))))((&&%%%%%%%#$$$$##%$"#""!!""!!!!""!!#%(1?[vskkqvvvvof\QB4/5>HU^fnqng_UI=67V{‚lfiqT?E>99BEEDCCCBCEHYp‹—š¤¬«ª®£¡žœ”r†‡€ˆ’†iQd_]]\YYVTUTSTTRWWY[SNMNKLKLKJIIJHEEBA>:73-(&'&CWPPW\YWZ`bUUWYUTRPKGBB?43>HCEIJLOQUXWQF=722>N]hpxxqkiifffghgXD8FMJHR^`a\XUPHDA=9,%#"#$$%&&&&%##&08;<>@???@BBAA@@=;/#  ""!!###""%'**********+/069?<=<?DKQ_qmIGXY_de[SVQNNNNNMLHE?==>?BFHKMMPPPPOONOQV\biqz~ƒ…ˆ‰‰ˆ‡…ƒƒ‚€ƒ†‰‹‹‹Š‰ˆˆ„€|uqnooooljgebcefjqw{€„ŠŒŠ‰ˆ……‰’“”‘‘ŽŽŽŽ†wy|yyzxxwwxxxwwvvwwxz~…‹’“’‘’•‘Œ‹Š‡ŠŒ’•••‘ŒŒ‹Š''(((((())))))++++,,+++++*++,,,,,,,,----..--//////..................----..----,,------++,,++**,,+***))))**))))**********++++++++,,,,+***))((''''&%%%%%$$$$$$$$$$&$####"!""!!!!""#"%)1=XsqjlprrsrmdYNC5/07BMVbiopke[OC75Be~lhflO@C@87BGECCEFC@@Nk––ž§ªª¬¢££¤¢Œ}ƒ‰‹”šŠzRYXWUTOOPPOOOOPPRV[[UPIIFEEFEEFHHHHEA?>:853,'&(.PZUSUTSUY]bWRRNPNKFA=?A7.3=AADFKMNRWYQF:834>KWelrslhhgfffghicN6@FEIX^^\XUSKEB?;5)######$%%$$###)29=>?@@??@A@@@??>:.#!!""!!"""""$&+++)******,04666689<CFEHUTFG\R]ef[W\SMNMNNMKGD?==?@DGHKMMNNNOPOOPQV_ckrw}ƒ…ˆŠˆˆ…„‚‚€€€~€„‡ŠŒ‹Š‰ˆ‡„€ytpoppnnkigeecghlsx}ƒ‡‹ŒŠ…†‡Ž’“’ŽŽŽŽŒzszzxyyyyxxwwwwwxzyww{‡Ž““’••Œ‹‰ˆŠ“—•”Œ‰''(((((())))))++++,,,,,,,,------,,------....////....................----..----..------,,,,,,++,,+***))))**))))**********++++++++,,++****))((''''%%%%%%$$$$$$$$$$%$####"!""!!!!!!"#'-7Povjknprrqg`VL?2,.2<GR[fmooi`XK?21Iq}lgjlL@CC:8@DEDEGGC?C^}Œ•˜’•š£®°®°®©«’tvŽ£¡£–ƒ`QUSRQQQQQRRQQPPQSTSVQMKGECB@A@?CCBB@>>:9630*%'*2R_XPRURPTa[DICEFEB><>>5/,-:@AEJLMNNPOC9743:HU^glmlihfffe_XVLOULCFOZ^\ZVSOHC><93'$#####$%%$$###)3:=>?@@@?@@@@@??>:.#!!""!!""""!"$(**)******,/3444569@GIIIMC@AUhonfbcgSLMMNMLJFC@??@ADGHKMMNNOPRTTTWY_fktz}ƒ‡‰Šˆˆ…„‚‚€€€~€…ˆŒŠ‰ˆ†ƒytpooonnljgedehiov{ƒ‡‹‹‰‰‡†‹”‘’‘‘ŽŽŽŽŽsx{{yyyxxxxwwwwwwwxxy|‚ˆŽ’“’‘Ž”‘ŒŠŠˆ‰Œ’•—•”Œ‹Š''((((()))**++++++,,,,,,+-----------......////00//..............................------,,,,,,,,,,+***))********++****++**++++++++,+******))''&&&&&&$$$$$$$%$$$#$$$%#"""#""""!!!##%(*7Kjypilmppme\QD91++.8@KVajpple\QG;35Y{ylgknQ@EC<7?DEEFHGB?No…•˜‰¡¯¹º»¸ª§’|“˜¢žŸsMUXXVWVSRSSRPRRUUUUWPNJHFFEECBBAAAA@>><;:63.)(+*5T][XSQOR[aJ;??CB?;8873/--9DIKLNPOOQO?652.5DQWY]dihkkfgi\OW8LYKGNY]\ZVSQKD@<:91&####$"#$$####")4=????@A@AA@@@@@?<-#! """"""""!"#'')*+*+))++-102479669=@ED?CFAKfg`_\ZUNMNNMLJFCA??ABEHIJLLNNPRVWZZ]aaemt{~€„‡‰Š‰†„ƒƒ‚€~‚‡‹Ž‹Š‰ˆ†|wronmmnmjhgdefjlpw}€ƒˆ‹ŽŒŠ‡‡Š“‘ŽŽ‹ˆzux|}zyxxxxwwwwwvuuxxy~ƒŠ”“‘Ž“–Œ‹‹ˆˆŠŽ’•–”“Ž‹Š''((((()))**++++++,,,,,,,...--------.....///////................................--...-,,,,,,,,,,+*************++********++++++++,+******)(''&&&&&&%%$$$$$%$$$#$$$$#"""#"!!"!""##'.7EfyrkknmlkcXK?4,))-3:GP[fmqpkbXMA516^{y~mein`?CC>8>EEEFIHDHaw‰Œ”’ƒ‹¤±¹»¼º²¯©ª¬®  ¥—\XXXVTTTPQQQPPQSUXYYTPMFFEEDDEDCC@@A@>>=;;950-+,.7UUWWRQPTZUB;;>>=;8751//2>HLMMNPPOQUG(/0.2<EOSV^bbegihkid_QQTOOWZ[XWTOJD@?;95-%""$#"##$$####")6>A@AAAAABA@@@@@@>/#! """"""""!"##$$()()**++,/135653668=?>CCC=I_ff\ZTUOLNNMLJFCA?@BCEHJLLLOORUYZ_aegglpw{~€„‡‰‡‡†„ƒƒ‚€~„ˆŽŒŠ‰†ƒytpnnmmnmjhfefgjmty~‚†‰ŽŽŒŠ‡ˆŽ“‘‘ŽŒ‹‹‹Š€utz|{{zxxxxwwwwwvvvxxy~…Œ’”“‘“‘‹ŒŠˆˆ‹”•–”’‹Š(())**)))******++++---------......--/......0////.../............///////.////////-./.....-,,,,,++,,,,++++++++*********+,,,,++***+++++**))('''&&%%$$%%%%%%%%$$$$$$$$########"""#$'+1=Zxrjjqpph]TH8-(%&)-5?IT^fnome]RF;20>gwvkbelvK?D@::EDDFGFL`tˆ†Ž‘„‘£±µ¶º»¶¹»º»º®¦¢žŠjZVRRQSSTPPNMMRTRTUUSQNKHFEDCDCCCBBBA@@>===9841...AWVQPQPOMUV;5;<=:8432019GMNMNNNNNQSSG=)(/5;CJMV[_bdfgfcabUVTKPY[[YUQMEA<;:60'$$$$$$##"#""""#'2>ACCB@??@BAAAA@?=3%!  "!!!!!!!!!!"""&))**++*+/1324468;;:9==BGMR[fba\VPTQNNMJFB@@BBCFIKMLMMQUZ\`ekoppptw}€ƒ‡‰‰ˆ†„„‚€€„‡ŠŒŒ‹‡„{wronmmmlkjgffgilqw{€‚…ŠŽŽŠ‰ˆŒ’““’ŽŽŽŽŒ‰‡‹ˆywx{}}zyxxwwwwwwwwwwwxz€‡’“’‘““‹ˆ‹Šˆ‰Œ‘“•–“ŽŒ‹‹‰(())**))****++++,----.------......../...//./////../-............///////.........-./.....-,,,,,++,,,,++++++++*********+,,,,++**++++++**))('''&&%%$$%%%%%%%%$$$$$$$$########""""%(-8Mrxpmqtri_SF5)'%%&)09CNWbkpmh`YO@2/0Cmxxmccnzr=A?:8ACBEAG_vƒ€Ž‡Ž”“™ ¤¯®°¹¼¼¹³°µ´µ©©¡wUTYesyyyyum^NLLNNORRPNKHFEDECCCCBBA@@@?>==:9863..,@SPONNKKMQR:69:8652202=KPONNNNNNPUUTT929:;=AFRWZ[_b`a_\_YSNKOXZYXSPJ?<9750*%$$$$$$######""#&/;@ACB@?@AAABBA@?<5)!!!!!!!!!!!!!!"""$&(**(()*,/0124547755699;BJSblbZRPOSPMMJFCACCCDHJLMLNORU[afkrvwxxxy}€€„‡‰‰‡†„‚€€€‚„‡ŠŽŒŠ‡„{ysommmmmlkifgggimrx|…ˆ‹Šˆ‰’’ŽŽŽ‹‡‡Œyy{|||zyxxwwwwwwwwwwwx{‚‡“”’‘‘“‘Œ‹‹Šˆˆ‹“•••’ŽŒ‹Šˆ))))******+++++,,----.-............././0//00//////..........................................-,,,,,,,+++++++*****++++,,,,,,++*++++++*****)'&&&&%%$$%%%%%%%%$$$$$$###########"#$'+4GivnjqvvncVF5'$$$%&)1:EPZdlpkf]RG:.-4Usxxlcahw~U:@76?ACDAQu†Œ†’•“––“—š›¥¦¬¹¾¼³³²³±¬¤¨¦”€^bt~~}|{xxutk`YXWURROLJGDEFFDDDBCA@??@>=<;:98754.-/?OLMLJIGIPL66965310/5CMRRNOMMLLMPSW\VF;9<;=@IPVWZZZY[ZYUPLLSXZVRNLC9840,(%$$$$$$$$$$###""#$+8@ABCBAAA@@AA>??<7*!""!!!!!""""""##""$&+*)**)****/2244010/57<@EJ[fjaYTOPPNLKGCABAEFIKLMMMNQU]aipx|}}{zz~‚††ˆˆ‡‡„ƒ€€€ƒ†ˆ‹ŽŒ‹‰†‚~ytommmlmmkjihghhjnty~†ŠŒŠ‰’‘Ž‹‹ˆ†‰ˆyyy|}{{zyxxvvwwwwwwvvvy}ƒ‡““‘‘“ŒŠŠˆˆ”•“•‘ŒŒ‰ˆ))))****+++++,,,-..................../00//00//////......................//..................-,,,,,,,+++++++*****++++,,,,,,+++++++++*****)'&&&&%%$$%%%%%%%%$$$$$$#########$#"#%(0=^ysinvvqgZL6($#$$%&+3;FQ[ennjaZMA3--8\xws~pacht€u@=:5<@ACLf†”––˜™’„Œ‘‘š ¤²¶·´±¯¬­Ÿ™––”nt{zvwvwtssstqomjhdb]YTRNLEDDBABA@AA@?==<;:9875430--@MGGFFFFKQF686530//8IQSSQOMMKKLLPRYWXL;69<=CJMRTVTTTUVQMMSXYVSOLIB81/+%#$$$$$$%%$$%#"$""##&2=?@AACCA?=@BB@?>8,""""!!!!""""""##""$$+)*+,*(((+0//0-**1403879>OWaWQZYQPMKIFC@@CEEHLMKMMLOT[cjsz‚€~~~„†ˆ‰††ƒƒ€€€ƒ†‡‰ŠŽ‹‹ˆ…‚{wrnmmmlllkjhhghhjouz}†ŠŒ‹‰Š’‘ŽŽ‹ˆ††Œ†zxz{}{zzxwwvvvvwwwwvvvy}ƒˆ“‘““ŒŒ‰‡‡Œ’””•“‘ŽŒ‹‰ˆ))))***++++,,,,,-.......////....--//000000//////................//--00////////....///.......-,----,,++*,++++,,,,,,,,,,,,,,+,,,,,++++***)*)&&&&%%$$$$$$%%$$$$$$##########$$##%),6Nswljruqk_O:*$!""#$'+3=HR^dkje]RH=1,5Hk}}€sbcht€e5968?CB[|“‘™ž˜”œ”‡Š‘˜¤£©«¯³´©£‘Œ†tgtuutrqroonnnllifb`__^\\\XUTQMJHEA==>===<:98765210..<KHEFCBBGRA6872111=LTWWSQPOKKKKMQRSNTSE<=?@CHORUTONNLPPPPRRPNKID>6/.+&%$$$$$$$$$$$$$$####$+8>@@@@BA>>?>?=<;5+"!!""!""""""!!####$$'((*))(+./,+)*))*-17<=CGNW[aotbUONMKGDB@AEHHIKMMMMLORZbkv|€ƒ‚€~|…‡ˆ††„ƒƒ€€€€„‡ˆŠŒŒ‹ˆ†ƒysomkkklkkkigfghimqv{†Š‹ˆ’Ž‹Œ‰…„Š€|yy{|{{yxxwvvuuvvvvwwxz~„ŠŽ’‘“’ŽŽŽŽ‰‰ŠŽ“•“”’‘Œ‹Šˆ‡))))**+*,,,,,,---...../0////////..//000000//////....////........//--//////////....///.......-,--,,,,,,,,++++,,,,,,,,,,,,,,,,,,,,++++***)('&&&&%%$$$$$$%%$$$$$$##$$$$$$$$$$#$(+2Ek|okpttncUB-#""""#$'-5=HR]fjjbXMB705Gi|~}v}wbdfp€‚~H776=AHjŠ—š–˜£¤›ž›‹ŒŽ˜¢¦­¬®±­¦œ“‹ˆ‹‹„ˆ€kooqqpmmkjkjiihdbe`__ZYXXXWTQSRSRRPG?==;::98776422...=DBACBBDIT>664024BOSVWSSPOLJJLLMQSMNTSLB?@BDIMNMMJDDEGHFDDCEFC@91,+)'&%%$$%%$$$$%%%%%%%%#%,6<???@???@><:83*#""!!"!""""""""####$$&'''&*,09<3(('&')1=CEMPQUVY_p€y^XNKLIA@BBCFGIKMNNNMNOU^gr{€ƒ‚€~…‡‡†…‚‚ƒ€€‚‚†‰Š‹Œ‹ˆ‡ƒ€{wrnlkkklkkkigfghimqv{†Œ‹‹ŠŠ‘‘ŒŒ‹‡ƒ†Œ†|zyz|||{yxwvvvuuvvvvwwxz~„ŠŽŽ‘•ŽŒˆ‰Œ‘“•“”’‘Œ‹Š‰‡†))))++,,,,,-----....../0////////0000000000//00//..////..........00////////....//......////...---,,,,,,-+++++,,,,,,,,--,,,-,,,,,,++++**))('''&&%%%%%%$$$$$$$$$$!#$$$$$$$$#$$$(.<`tlqvyqhZN5$!!##!#%'.5<GQ[dieaVJA96?]‚ˆ~zv{{hbbl~„ƒt195<@Ov‘›žŸ¢¡¤ œ™Œ“ž¤¥¤¡ Ÿž˜‘Š{txu{Šikklmjkigghffda[V[\ZXZXTQPPOMMMMNQSRGA<;9:89886551/0/2FGEEBDEIRP633216GQTTUURROMKKKKKMMPONOLD62:?AEFGHFBCCCB?CFIJHFA<0+(')'''&&%%$%$%''&&&$$%%%&*07;>?=?@?<84-&#!"#!"" """""""""""#&&%&'''(')4:/(&%''+1;BEJNQSSWXYj~]^oPHGC@@@BEFIKLLNNMNMQWcmv}€~}}~‚‡‰‰‡…„‚‚ƒ„ˆŠ‹Œ‹ˆ‡†‚}wtqlkkkkkkkjhfffgimqv{‚‡‹‹‹‹Ž‘ŽŽŽŒŒ‰„‚ŠŒ|yy||}{zxwwuuuuuuvuvuuxz…‰’”ŽŽŽŒ‰ŠŽ‘”””•’ŽŒŠ‰ˆ‡)))))*,,,-----......../1////////00000000000/000/..////..........//////////..-///......////...---,,,,,,-+++++,,,,,,,,--,,--,,,,,,++++**))('''&&%%%%%%$$$$$$$$$$$$$$$$$$$$%%$&)3Oyqpw}zpdTC-#!""##$&(+3<GR\bfd`UKDCL`{Œ†zwvz|ia`j|„ƒˆZ+26>Uz›¥¦¥§¢™ Ÿ”ŽŽ—Ÿ¢Ÿœ”Šuiba\n‡v_gghhfecbdeb___]ZXZXVQOMIIIKKKLKKMNMGC?<:99875554110.9HEBEDFFJOF22437HRUTTSSSQOMKJKLKKMMKKJ?0%',29;CGFD@@A@BFJIHFC@6/*'''&''''&&&%$%'('''&$%%%%%&*-38:=>;61*$""%$"#$%!""""""""##"#$$%%&&'(&'(&'('&&%'*26>DGMNPSZcnaN^\ICA??@BFHIKLLNNMNJOS]iqy~}|}„†‡ˆ†…„‚‚‚…‰ŠŒŒ‹‰Š‡„€|wsnmlkkkkkkjhffffhlqv{‚‡‹‹ŒŒ’‘ŽŒŠ‡ƒ„Œˆ{vxyzz{ywvwuuuuuuuuvuuy{†ŒŽŽŽŽ””ŽŽ‹‰‹Ž‘””•”’Ž‹‰ˆ‡†****,-,,,-......./////00//11////0000000000000011//////.0////..//..//////........////////.....-......,,,,,,,,,,,,----,,-,--..--,,,,++**))((&&&&%%%%%%%%$$%$$$$$%$$$$$$$%%%%%'+;fwqr{yk^M:(#"!"#"#&(*1:EOZ`cc`VOQ\m}ˆŒ‡xxv|}k`^dz„ˆŽC+2<Tz—Ÿ§©ª©¥žŸ¡šŽ‹‰‰’˜š›‹…~wlghiaq}„]bfhfdb_dbb`^][YVVVTQOKIGGEFHHIJJJKMOOHC<97765665333/0CKGFGGCFIM?112:GRTUSSRSQPNMLLLKKJIGFD:,#$$%)-6<=><>AABFIECA:4,(('*++*()(''&&&&&&'&''&$&%$###"%+.231-'"""#$%""###"""""#"$%%&&)+'&&$&&%%''&&''(()),.18=EJPW`jvu\Y\j^G@AA?AFHIKKKLNMKJLPWemv|~~~}z~…ˆˆ‡†„ƒ€ƒˆŠ‹‹Š‹†…{wsnkkkkjjkjhggggghlqv|„‰ŠŠ‘‘ŽŽŽŽŒ‰…„‡Œ„~zyxy{{zxvvutusuuvvvuwvx}€…‹ŽŽŒ”’ŽŽŠ‰‘“”•”“’Œ‹‹‹Šˆ‡†****,-,,,,....////////00////////000000000001001100//////////..//..//////........////////.....-......,,,,,,,,,,,,----,,,-....--,,,,++**)(''&&&&%%%%%%%%$$$$$$$$!$$$$$$$%%%%&),?q„try€‚ufYF1$#"""#"#%'*19DOZ`cdaZ]gq~†‰Š„y~€j`\^v‡ŒŒz6/5Ow‹— §©©¨§¢œœ—‹‡|‚Œ’‘Šyuvsfagkr}u~lV_cb`\\_]\[\XVSSSQPMKHFDAABAACDDDEGIIJGB<8665666533227KOGGGGJGHL=028FPTTUSRPOPNMLKKKKJIFEB8*###%&'&)+/:<<@DDEFB5-*+---*++*)*)((''&&&&&&&%%&&%$$$#"##"$$""!""!##"""###"""""#$$),15975.)'((%%''&&''(((*+*,/7DMTX[\[^hiWPJC?>?ACFHIKKKKLMKJJOVbitz~~~}zƒ‡‡‡…„ƒ‚‡ˆ‹ŒŽ‹Š‰„„zvpliklljjjigfffgijnrw{†ŠŠŠ‹ŽŽŽŒŽ‹‡„…‹ˆ}yxxy{{{yvvutstuuvvvuuwy~ƒˆ‹Ž’”ŽŽŽŒ‰‰‘“”•”’ŽŒ‹‹‹Šˆ‡†**+++,--+,..//0000001111111100110011001111111111111100//////.../..////////....//..00////.....----..-,,,,,,,,------..,,,.....----,,+***)(((&&&&&&%%%%%%$$%$$$####$$$$$$$$%%%+.@outy€€p_Q=+$###"#"#%(,08CNX^ac__ku}…‰‹‹ƒ|ƒ…|m_[\t…{nv~b21Dp…”¥¨¨¨¨£œ™“„wu„ugelqj`eZpp]qyUSWYYYZZVWVTSSNOPLLKIFDA?=<;<?@A@CEFFECCA<756446555662;KICDCHHHIN=16FPTUTTUSPONNMMLKKIIGE?5%##$$%&''(*-2;BFDA;2--,---,-,*+*((((((&&%'%%%%%%%$####""""""""##""#"#""###""####%*18AGIHD<3*$#%%&&&&'')*++)+,0;ELJOPV]c^UNJEB@?@ACFHHJKKMMKJIJOT]hry~€}‚ƒ†‡†……ƒ€€€ƒ‡‰ŒŽŽ‹ŠŠ…‚}wsnjijjjjjjhgffggilptx|…‰ŠŠŽŽŽŽŽŠ…ƒˆŒ„{xwyz{zyxvvuttstuvvuuvwz~„‰ŒŽ”’ŽŠŠ‹’““””“ŽŒ‹‹Š‰ˆˆ‡**+++,--./..//0000001111111100110011001111111100111100//////.../..////////....0000//..//.....----..-,,,,,,,,------..........----,,+***)((('''&&&%%%%%%$$%$$$####$$$$$$$$%%',/>jusz€zeWI3'$#####"#$'*-6ALV]`ba_n|…ˆˆŒƒxx{}}o]Z[gf_i{ƒ|H)>d}Ž–Ÿ¤¦¨¦¢—“€u|vprpoleahhdgpeN^Ic…YMQSTUSUUSRRPNHIKJJGEB@=;98999;=<?BCCEEBB@<764456666643>IEDCDEDFHTC6BOTUTSQQOONNMLKKKIIGE?2$%#$$%&''(*)4@BB?7.+-./,..--,,++(''''''&&((('%%%%$####""""""""##"""#!#""##$$##"%*4?JSWWVRLA3'$#%&&&&)),/-,.36;<?HKP]llg_YQNGC??@ACFHHJKKKKJIHILR]gpx~€‚…†‡†……‚‚€‚…‰‹ŽŽŽŽ‹Šˆ„€zvpkjjhjjjjjhgffghjlptx|€…ˆ‘ŒŒŒŽ‡„„ˆ‰}zwwyz{zyxvvuttstuvvtvwx}…‹ŒŒŽ–‘ŽŽŽŠ‹Ž’“”•’ŽŒ‹Š‰ˆ‡††**+++,....-.//11000000001111001100111111111000//00000000////////....//////............//..--....,---,,,,,,,,------..--......----,,++**)(((((('&&&&&&%$%%$$%$######$$%%$$%%'-3>eusv|paP=+$#%$######&)-6@KV\adebn€…‰ŠŒ‡uwx{~o\YZfcgpzx|=-Vs‡“š ¥§¥£Ÿš–†z{wqjihjegjhqw{rTHQW~bIOONKPMSRNLJHDEHEDDCA?<6544366779>BBBAAA@@<963465654468=FEDDEECELWG@MSUSSQPOOOMMMLKKJJHF>1$$#$%%((''(*+4960+-..--..-.-.-**($#&'*'&'())*'&&$$$##""!######"""##%$"!"!!""""#(2@LVaihgaZPB3*$$%%&&(*05:=A=8L\lvuvvsngaZQMHD@?ABDGIIJJJKKIIIIJP[grzƒ‚€„†‡‡…„„ƒ€‚…ˆŠ‹ŒŒ‹‹‡ƒ~xrnjjiijjjjihhgfhjjmrvz~ƒ‡Š““ŽŒŽŠ„ƒ…Š…}yvvyz{zxwuutsrrtuvvvvvw~ˆ‹Œ’˜‘ŽŒŠŒ‘’”””’ŽŒŠˆ‡†„„‚**+++,....-.00112222220011110011111111111110000000000000////////....//////............--..--..--,---,,,,,,,,------..--......----,,++**)(((('%%&&&&&&%$%%$$%$######$$%%$$%&)/6Aa~usuxkZJ5&"$%$$$####&)-5?IS\adgnz„†ˆ†}kpwvxzr`]^dguz{y}Žx/>hzŠ“™ž£¢¡ ›‡€zvpggfhgegox|xwob\Wg]CKJFFIJTUMGFD@?BA?@?@>:63310034459>@@???>>>>843556665467@HFDDFEEHOXKHPUURQPOOOMMLLLLKKIG?3$$#$%%''&'(*('*'(,/.///.0.-/./-'%##&'*(''(((&''&%$%$#"""######""##)52%!!!!""""$,8DS_ktxtoh\N?0*%%%').0/4<HY[Pu€wsvvutqmf]TLFB?AACEGIIJJJKKIIHHJP[grz€„„‚ƒƒ†ˆ‡…„ƒ‚‚ƒ†‰ŠŒŒŒŠ‰‰„€{vpkiiiiiijiihhggjkkosxz€…ˆ’”‘ŽŽŽŽŒ†ƒ„‡‰ƒ€}yvvxzzyxwutssrrtuvvvvwz~„ŠŒŽ•”ŽŽŽŒŠŒ‘‘“”“‘ŒŒŠ‰‡†„„„‚,*+--,--..-.11002233222222221111001111112200122211110/00////////////////////.........---..-,--,,....,,,,--------------......------**)))(((''((''&&&&%%%%%%%$$$$$##$$$$$%&'+1:B\|uqqqlV?-&$#%$%$###$&).2;EQZbhmv€‚„ƒ„z_Omjippsda`fs~xvy…‰ˆa3[r‚Š˜žŸœ˜‹††‚pgaaehgb^fowpovxxovo8DGBAA?AEEDAC>;=<;<=:853211/./11159<=>>>>===;8556776888:<DHFGEFFFHMTNHQUSQPOONMMMMLKKJKFA5&%$%%%&'&'))(&%$(+-//...00//01/'""#%',*(((''''''%%%%$$##"""""""###&-*$"!!!!!""%/=KZiv~„zrg\M>1)'),04<JTMDOO_~|vvuutqmf^VMFB?DABDGIIIJKIIHHGGHOYgr|ƒ††…††‡‡‡…ƒ‚„„ˆ‰ŠŒŒŠˆ†…„~xtnjhhiihhjjihggfikmpty|‡Œ‘””‘ŽŽŠƒ…‰‡‚~{xwvxzyxwvtssssstuuuuvy|‚†‰ŒŒ•’Š‰Œ‘““’‘ŒŒ‹‰‡†‡…ƒƒ,*+-..--../011112233222222221111001111112211333311110/00////////////////////.........---..-,--,,----,,,,--------------......----,,**)))(((''''''&&&&%%%%%%%$$$$$##$$$$$%%(.4;FWwuqqonS7'%%#%%%$###$&)-39CPZcmt{€|ub<Gkppsqwhdcfs|wv„‰‚PCet†Ž–™š˜•†„ˆ†p\`aghc`]cly}ukl{||L9BC<;;<@><<=;998778641//./-,-///269:;>>>====;877777997:<=DGFDDFEEHLPNHNPPONMLMMMMLJKJIGC9&$$%%%&''())(&%$%+../..22/0355/'  !#',*(((((''''&&&&%%$$""""""#$##!""#"#!!!!""&0?LYj{‡Šˆzqf\MA8436ASalk[]bgy}‚€wttuusnibWNEBBABDFGIIIJKIIHHGGKR]is~…‡‡‡‡‡‡‡‡…ƒ‚€…‡‰‰ŒŒŠ‰ˆ†ƒ|vqljhhiihhjjihgggiknquz}„ˆŽ”•‘ŽŒŽ†‚‚†Š…€}yxvwyzyxwvsssssstuuuvwy|‚†ŠŽ’•’Ž‹ŠŽ’‘“ŽŒŒŠˆ‡†„ƒ„‚---.....//01112222222221121122111211222233333333330000//////////................//--.-,,,,,,,,,,------------------....--./....--,,+))))))(''&&''''&&%%%%%%%%%%%%"$$$%%%%'+05<IXmxkhkmY2$%%$%%%%%%%&&(+28AM\hu|~|{wp\;(?fyrqtzjdcbmt{……}{z|uIRmy‚‹“—”‰ƒ„m_\`a^adcgt}pktxtwj-9><867:::867553266510/-,,,(*-,,/1467:<<<;;<=977899<DKA>:?EGGEDEEFGIOEAKNKLMLKKKKKKJHGGE=+#%%&&'')*,)(&%$%,.///111688:80&   "'-.,*&)()'''''&%%%&$$$$$############""!!""%.=L]m‰Š‰‚}umh^TPIFHTbfekeelsvyx|zvuwtrqkcYPHCAADEGHHIIJJJJGGFGLS^it…Š‰ˆ‰ˆˆˆ†„ƒ‚‚„‡ˆŒ‹‹ˆ‰†…‚~xrnjihhhhhhhhhggghjkprv{~ˆ”•‘‘ŽŽŽŽŠƒƒ…ˆˆƒ€}zwwyzyzvvutsttttttttsvx|ƒ‡ŒŽŒŽ””Ž‹ˆ‹Ž‘‘ŽŒŠŠ‡‡†…ƒ€,-./..../001122222223321121122111211222233333322000000//////////................//,,,-,,,,,,,,,,------------------....--./....----+))))))('''&'''''&&%%%%%%%%%%%%$$$%&%%)-33=JYgrngfid@$%%$%%%%%&&%%(*.6ANat|yumaJ4.6Yxsry{laagir†ywwzzdK]pxy€ƒŠŽ’Š‚vlhddgaY\binv…|rllnqsv>1475455564322210231/..,,,,('))+,/02389:<<<<<;:89<=?YbHB@>BIIFFGFFHGHJBCHJKLKJJJJKKJHGGD@5&%%&&(***+*'%%$%,.//.048=>;=;3' "*012/-,++)''))&%%%%&$$$$$$##########""!!""'.<K^n}ˆ‹‹‡‚yupkf`WWX]fg_[SO]dRJkqmrvuuqmd\RJCBCDEGIIIIHHHHGGFGLS]jvˆ‹‹Š‹Šˆ‡†„‚‚‚…‡Š‹‹Œˆˆ‡‡„€ztqmkihhhhjjjjhgggijmqty{~…“•”‘ŽŒŽŽ‡‚…ˆˆ‚|ywvxzywwvutsssssstttvvz…ŠŒ•‘Š‰‹ŽŽŽ‹ŠŠˆ‡†‚€ƒ........000111222233332223333322333333333333333322110000/////////////..............-,,,,,,,,,,--,,----------------....--.///..--,,+)*****)(())('((('&%&&%%%%%%%%%$%%&%%%*/16=MZfonhdcfV+!%$$$$%%%&'(().6FXo‚„€}xofUE?69Tupl||kcbeiv…†usuvyzbL`pprv|„ƒ{rjgihhmlkmryxz~‚ymaVKKGMK.03111112310..//-//---++,,'$))'(,,03588::9:;:::;:=??BCCBADFILIFHGDFIJH@>FHJLIFGIJKJHFEC@9)$$&$(++++*(%%%&+.00.1:=@B@=:4(%-24785/-.*&&%&''%%%%$$$#%#%$%%##""""##"""#%*4GYj}†‹ŒŠ‡†ƒ~{zwmlgY[W\f^F@F5<`v|wssntog\SJDCCBEGHIIIIIIIHHEHMT_mxƒ‰ŒŒŒ‹ˆ††„‚‚„‡ˆ‹‹‹Šˆˆ†ƒ}ytoljhhhiiiihhhgggiknrtx{€Š’••’‘ŒŽ‰ƒ„„ˆ„~~zxvuwxxwvuutsssssssuuvy{€†‹ŒŽ””ŽŽŽ‹‰ˆ‹ŽŽŽŽŽ‹‰‡†††„‚‚ƒ„........00011122223322222333332233333333333333334411000000///////////.............-,,,,,,,,,,,,,,,----------------....--/.////--,,+)*****)(())))((('&%&&%%%%%%%%$'+)'%&(+,/5>LZfoqkgcfcA"$#%$%%%%%&))+3DTl…ˆ„{tj_VPIDFRabf~zncahk~‰‡{ssuvw|yOQgljkoustkgjklot|}€†‡„„yq^MD;1224---.0011.///,*++++-,,,++++(%&&'(*+.135787567779::>BDFHJFFFFHJLMKJIHKKJG@@DHJIDDGIJIHGEB?9+$$%&(+,,,+)&%%%*.00/6>@DCA?>3( !"'07<<99852.(('%&&%%%%$$$#"#$%%%%#####$$$$$#$(2GYj|‡ŒŒŒ‹ˆ„…ƒ‚{un]\cieZPVO?Kj}~vthC`qhaUMFEEEGHHIJJIIGGFFEHMT`nxƒ‰ŒŒŒ‹ˆ†„ƒ‚‚„…ˆ‰‹‹Š‰†…†ƒ€|wsmkihhhhhiihhhgggiknruy{‚””’‘ŽŒŒŠ…€ƒˆˆƒ€}zxvuwxxwvuutsssssssuuvy|‚‡ŒŒ‹–“ŒŒŠˆ‰ŽŽŽ‘‹‹‰‡††ƒ€‚ƒ†‡--..///-/011112222222222233333223333334222333333332211111000/.//////..--..........-+,,,,,,,,,,,,,,------------------............,,,+++++****))))(()('&%%%%%%&&&'*8C7'&'&)-06?L[fotpigbeZ/$##$&$$&'(,3=Ocx…‹‹…wld`YWRNOXadn{wngfhp‡Œƒyknrprw{WAWbfacegwnalos{ƒˆˆ†ŠŒŒ‰~kWD86444471*()/.----,,*)))*****(''''%#$&&''*,/1345533333788<BFIJIJJHILLPRQPOQNKHIHCABEFBBCGGHIHF@?9,%%%'(+-..-*(%##)-..1:@EIEBB=1$#%+2:=?=:8642+*)%$%$###%%#"$$%%%%$%&%&''())('),2EVgy‡Ž‹‰‰ˆ…„€|pdkoji[]h[5Adv|wrbcpjaXNFEEGIIIJJJIIGGDDFGKUamxƒ‰ŒŽŒŒŠˆ†ƒ‚ƒ„‡‹‹ŒŠ‰ˆ†……‚€|xrljhhhhggiihhhggijlosvz}Š’“”“ŒŽˆ€€„Š…‚~{yxwvxxwvtttsrrrssssuuuy~ƒŠŒŒŽ”‘ŽŽ‹ˆ‡ŠŽŽ‹Š‰††…ƒƒƒ…‡ˆ--..//0/111111333333333334444433333333343333333333222221100000//////..--........,,++,,,,,,,,,,,,,,++----------------............++++++++++++))))(()()'&&&&&&'''(-FZL00+')-28ANZenrsliccfQ)##%%$#((.9K`tƒ‰‰ŠŠƒyjcaa`\XVUYhuvsxrhfio€†unnnopwyY8KW\^]Z[nyjwyr}…‡‡‰ŠŠ‰‚oW>9448?;697.'(*,--,,+*('''((''&'&%%%#$$#$&%'),./10222222478>CIKLLLMONNQTWXXXVROKJIGBAA?=?BCEFGFD@<5*&&'()*,,.-*('&%(-.00<CEIIEB:+! "%07;;;<;:741.,+'#%%###$$#"""!!!##$$$%&'())+,.18FYjzˆŽŽŽŽŽŽŒŒ‹‡…yrh^OG>40031:AMmyuvvsokc[QIFFHJJJJJJJJHHFFEGKUamw‚‰ŒŒŠ‡„‚‚ƒ„‡Š‹ŒŠ‰‡…„‚€€|vpkihhhhggiihhhggijlosvz–‘’ŽŒŒ‹†€€„‰ƒ€~{wvuvxxwvtttsrrrrsssuuw{~ƒŠŒŽ’”‹ˆˆ‹ŽŽŒ‹‰†ƒƒƒƒ…‡‡‰--////0011111133333333333333333344443333443333333322441000000000................,,,,,,,,,,,,,,,,,,++,,--------------......//..--++++++**++**))))((()((((''((((()+?UP<;-)*.2:EP[dmorlhdbegC#"%&$%+.;Oi|‡†‰‰ˆxcXX^a`_]ZWWe{{ozsggfmtxyvpomoruz\36KVVXXR\ntxrbk~zˆ†}iP@98865889;?5('''*,*)(('%%%$&%%%%$$$$$$"!$%$&(*.,-///0111499?EGMNOOOQTUVWYY]ZYXURNJIIGDB><=ABABCB>8/*''&')**+,,*(((%'+/03@BGJJH@2' &5:<=>=93/--.--*(&$$#!!!#"!!   !"$$%())*.-,.04EZp~}„ŒŽŒŽŽ‹Š‡}uj`WOE7.(&#&*6:@NYiottnf^SLHGIIJJJJJIIIHFFEFLWalx€ˆŒŒŒŠ†ƒ‚„†ˆŠ‹‹Š‡‡†…ƒ€{voljihhhgghhhhhghjknotw{„’”’‘ŽŒ‹Œ‹‰ƒ€€…‡„}|xwtvxwvvtssrrrrrrsstuy}‡‹Œ””‹ŒŠˆˆŒ‘‘ŠŠ‰†…ƒ‚ƒ…ˆ‡ˆ..//0000111111333333333333333355444433334433333333334410000000..................,,,,,,,,,,,,,,,,,,++,,--------------.....///..----++++**++**))))(((((((((()))))**2IXK:-*+/6>GR^gkkflmc`cif;"$$%),5Ih‚…„…†…|oXJNPX^bb``\Zc}~{‚ujjhkmouxrmnnruw^1.7KQPQMNX^ZRFBi}{uzvkP;56:987768;<;.&%%&''%%%$$$$#$##$##"""""!!##$%&)+,,----.0147;>FJKNPQQSVWZ[\Y[]\ZYUSONNKIGDB>>@@AA?<5/*''&'((*+++*(((''+..4BBGIHF?-#  )5;=?>72.+)&$(,,*&$#"#""!#"!! !!#$%'*)*,,05;9ESd{x|‰ŽŒŒ‹Š†yskfZRB9.((+09DFLONQ\kkicWOJIIJLJJJJIIHGEEEFLWanyˆŒŒŒ‹‰†ƒ‚……‡Š‹Œ‹Š‡†„ƒƒzumjhhggggghhhhhghjmorux~‹•’’Ž‹‹‹‹‹…‚€€……‚}zxwuvxwvutssrrrrrrsssux}„‰ŒŽ•“ŽŒ‹ŠŠˆˆŒŽŽ‘‘‘‘‹Š‡…„„„…ˆ‰‰Š////000022221133333333333333444455553333444444443344432011000000..........----------+++++,,,++,,++,,,,,,,,,,,,------.....///..--++,,,,**++**))**))(())'')+**,,+,-09LT<--/3:BLU`hjga`khbbcoc/$(+/>^~‡„‡…w]B5<ELRX\_adbbds€ˆˆ{nkjijlrtpkklouu_2,.9HKHNKJLBB?4;dxzpbN;4579;;:968:;;6(%$$%%%$$##""""""""""""""!!!#$%&&(+---,--/.;A=BEILORSTUUUX\^]^^]]\XUSSTRQPIFD@=;>=<94.*))(((((*++****(')*.4AFHHEB7)  "#,6=><940,*('$$'(*($###$$"!"""! !$%'(+--/36<Qhnjp{ŠŽŠ‹ŒŠˆ†‡†ytlf\RE732249?GEDGIKWZY]aTIHKMIKLIJIIHFEDEFLW`nx€ˆŒŒŒŠˆ…‚‚ƒ…‡ˆ‰ŒŒŠ‰ˆ†…ƒ„zsligggggggghhhhhijmosxxƒ”‘‹ŠŠ‹‹ˆ…€‚‡ƒ}zyvvwxwuttssrqssssrstw|‡ŒŽŽŽ–“ŽŒŒŠ‰‰‰‘‘‘Œ‹ˆ†…ƒ„„†ˆ‹ŠŠ////002222112233333333333333444455555333444444443344431121000000..........----,,,,,,+++++,,,++,,++,,,,,,,,,,,,------......//..--++,,,,,*+++*))**))(())**+*-.////111/GA1128?HP[cije[QZmgbagqT$#),2Hl„ƒƒyiI.)24;DJRXZ]adfhu‚‡†qigfhlmkiikloqv_,)+.4FHEGF>65IF53Vd]H<55689;;::979:;=-%%#$%%$$##""""""    !!!!    #$&&%&(*+***,.49;<CHNORRRSSTUW\]]^bb`^YVXYXXWWUMIC=978730,+)))(((*++*****(*,/5AFFEC=/# !%-6<?;71.+)&%##"#$&#"$))%%#"###"#%')*,022/1=\u~zy|~€€ˆŠŠ‹ŒŠ‰‡„‚„ƒ|wpic\PFA:768:??ADFINKNHJ^eSUZHFJJJJJGFEDDHOXboz‚‡‹ŒŠ‰†…‚‚…‡ˆˆ‹ŒŒ‰ˆˆ‡‡…„}vrmigffffggghhhhhjlprtw|ˆ’”Œ‰ˆ‰‰‰‡ƒ€€ƒ†‚~|ywuvwxwuttssttrrrrrstw|€‡Ž‘“‹‰‰‰‹Ž‘‘‘‘ŽŒŠ‡…„„…‡‰‰ŠŠˆ00112233332222223343234444444444555555334444445555443322322200000.......--,...--,,,,+++++,+,+++,*,,,,,------..------..........----..--,+,,,+****))*))++-..00121100119B=57>ENT]fjjbUKHakecdnq>!(*6Qy‚}~sW9&(+,15<AHPTZ_dlr~‰‚z|shdbgmqmkijkoop^+)+**7FIEC>3,131*1DC843247:::;;;78:;<6(('&%&''%$""##""!!!!!!    ! "#$%(***,,,.367;<BGLORQQQSVVZZ\[`aca^\]^]Y\^WSNID<75640..-,*)())**++++,+,-17@DEDA7+!""#(.4;>:4/*)&%#""!"$!%&)))&$#"$%%%&&*++,./-.;KXctxws|{„‡ŠŠŠŠ‡„y|‚…ƒ|xrib\VOB:>:=@CEGHLNUQVZJHVS_i\MIJJKIGECDHQXdoy€ˆ‰‹ˆˆ…‚‚ƒ„‡ˆŠ‹‰ˆ‰‰‡†„{vqmhgfeeeggghghhimmpqtvŽ’‘Ž‹‹Š‰ˆˆŠ‡…‚€€„†‚}{yxyyyutssrrrrrrqqssuv{‚Š‘”’ŽŒŠŠˆˆ‰‘‘‘‘ŽŽŒŠ‡††„ˆ‰ŠŠ‹ˆ‡001122333322222233432344444444445555554444444455554433323333200000......------,,,,,,+++++++,,+++*,,,,,------,,------......--..--....--,+,,,+****))+++--/0122334444444>JC9BLT]fklj`UE8Hiidbita*#+:Z|}xwc7%'*),,059@EMS[frx„’…yxse``aipofgkmnor],(*-129FA@<6**)('(,/023598::9:;;9779<;-(*+,())*)('%#$$""""!!     "#$%&)))*,,,/3689<AEJORRPPTVX[\\_^`ab`___\[[[ZWINH<74220/.-,+)))**+++++-,-0;@DED?5& !"$).39;950+'&$#""""##$%(***$%###$&('*++++*+3APWB=9<:Zlr~†ŠŠ‰‰ˆƒ|us{€„ƒ~xpkg_UNDB@@CFKKMLLQNH?KKLOXglbIIKIHFDCEIP\epy€…‡‰ˆ‡„‚‚„…ˆ‰ŠŠ‹‹‰‰‰‰‡†ƒ€zuqmgffeffgghfgiiilnqruvƒŽ‹Š‰ˆ‡„…†„„‚†…‚€~{yxyywttssrrqqqpqqssux~…Œ‘’”’‹‹Šˆˆ‰Ž‘‘Œ‹Š‡†‡ˆ‡‰Š‹Šˆ‰„001222332222333333433444444455555555555555444444556644444222100000/.....------,,,,,,++++++,-++++,,+,,,--,,,,,,------....--------------,++++***++**,,//1233456656567788DLDHRY`fmmi[P>05VpiccjqH$)8Z~{xs\.&&)((+,039?FKXiwyƒŒzud^\]clphggilorZ-'*-5;9RH=:92+%'$&&)-.27@=989:998668<<7-+-/,,,...,)%#$##"""   "##$&'())),,/373139>AHMPQOQSUVXZ]][[adcbb_^_ab\RTRG;753320-.-+++,,++,,./003;@CCA;1$!!%'(-26:93-)(&%$""$%#$%()),-(%$$$&''()**)(+/8ETU=5*'/BXk}ˆŠ‹‰ˆ„}ukhqx‚~xsleaYRKCBFFFIPQSWTLIPNORYeV]]MKJJGEDEJS]fqyƒ†‡†…„ƒƒ…‡Š‹‹Š‰‰‰‰‰‰‡†‚~xsokggedffggghghikmprtvxˆ“ŽŒŠˆ‰ˆ‡„…ƒƒ„~ƒ†ƒ€€|xxzxwtsssrrqqrqqqstsy€†Œ’‘’•‘Œ‹Šˆ‡ŠŒŽŽ‘‘Œˆˆ‡ˆ‰‰‹‹ŠŠ‰†„222222332222333333433444444455555555555566555555556655554422111100/.....------,,,,,,,+++++,-++++,,,-,,--,,,,,,------....--------------,+++**,,++,-/03367668899888:;;;;>JURT\cjrmcWJ8.,?fmebelf;$5Qw|vq^6&'))'()*.38>GWlyu|†Œƒzvh^\[^chggegmprZ+'*-5<Cc[B793,,(%(()*,.5<;557887876577:2++-,++,-./,*)(&&$"!   "##$&'('((()-110/05:>AGNRTPRSSUUWXX[\]a_`__[[YY[VSNG@674210---++,,,,--.1333;>AA?9/$!"(+,/19<ED>3+'&$&&#$#&))(*..-,)%$%'*((((((+264<1*''*5CZn~‰Š‹Š‡ƒ|qjeiqx‚‚}xsokeYRLJIOOQUY\\VQWRKNTWZUIPXKDEEEDFNT]grx‚……„ƒƒ……†‰Š‹‹‰ˆˆ‰‰‰‡‡†}xsokffedffggghiijlnpruv}Ž“Ž‹ˆ‡‡††††…„„€€……ƒ€~|yxzuwtrssrrqqqqqqrst{ˆ‘““‹‹Šˆ‡‰‘‘‘‘‹‹‰ˆˆŠŠŠ‹Œ‹‰ˆ†‚333333331344333322444555443345555555556677555555556666554432221111/...----,,,,----,,,,,,++++++++,,--,,--------------....----..--....--,+,,,,---.1222559;::;;;<;;<<===@CFOVZ\fnvnaSF5.,3Mpifcem]/*Dj{upeA&%')'&))*/48AZryos‚ˆzvna][^efffcfjlkZ-%&,17Jg[N8//,++((*++*,.13224577685596582*)+,,++,,+,+)(''&$  ""#$&''''''((*(),/28>AKQQRTSRSSSTTRUXZ\Y[^]]dc`ZRQQMI887211/0-------//34548=>><6+##$&)/19M`lpk_RA3+*&"""&-64688830-,*++*))))&%*+'%%'''(2C\p‹‹Œ‹‡„|pc\`hry€„‚}ztpkhbbca`_b_^][bmhY[^]YWP@8OVeZGFFGLU`isz€ƒ„„‚ƒ„„†‰ŠŠ‹‰‡‡ˆˆˆˆ‡ƒ}wrnjgfedfffghhiijmorstyƒŒˆ‡†‡††††…„ƒ€„„€~}|zyzvvsqrrrrrqppqqrsu{„‰Ž”‘ŒŒ‹ˆ‡ˆŽ‘ŽŒŠˆ‡‰‰‹ŒŒ‹Š‡†ƒ333333333444333322444555444456555555556677655555556666554432221111/...------,,----,,,,,,++++++++,,--,,--------------....----..--....--,+,,,,-../24758;>?=>>>@@@AAABBCDFJLSVYZjvn_OD5/,-9ZtiedjlZ.2YwvpiO*')'(&)*)+/5D`wsjn~ƒztoqf^\\`bffcgmlm\.&&++0MgYRQ9**++,,-,,-.---//14587556875@P+*-,,+++*+++,*('&$""""##$$%%''((*/98<FLRSTPTXUTQOQOQSUVW^ab_bfc]UTRQM:5;9400....--/025684489;60'##%%+6F[s€„…†ƒzm`TB.%$,9AFGFEACB<4442221000/-*'$$$$$&(4H_u„‹ŒŒ‹Šƒ{qaWY`jsy‚‚ƒ€|wqjghddda`afkllc[WXW`efaa[LUk\JEFKOXbisz|€‚„„„…††ˆ‰‰‰‰‰‡‡ˆ‡†„„}{wrnjfeedffffffiijmorsu|ˆ“‘‹ˆ‡†…………„ƒ„ƒ€€…„€~|zyxvvsqrrrrrqppqqrsv}†‹•‹ŒŠ‡†Š‘‘ŽŠ‡‡‡Š‹Š‹Œ‰‰‡†„‚2222223344465544334444445555554466666666556666666666766544442111110/..----,,,,----,,++,,+,,,-,+,----,,+,..--------....------....//.--,*+,,--/0125789<>?ABACDCDCDDDEEEGHKQY_^\cpkZL?3/.-0AipldfmsY-GlwumY5&()'))*,-1;Sqxljr||tomqm`][_acfgijlm_.%*,.1Pe]WUV:+'(((()*-./-,,-.0445314433KxR!//.---,++*++*('&%"  ! !!#$$#"&&&(,37=EJOSWSSPROQNQOPRTRZ`efghddZN>QNY@0;=7220000100168862452*&#%&(4J^p‚‰‹‹ŒŽŽ‹„zkT1):EMIA?EFFEA;:8:::<<:863,&! """%'7NdwˆŒ‹‹‹‹†}ncUSYckt{€†…ƒ€zzyxxwmlnmuyupklqosrikjkno]NTOGCMUZbirx{~€€‚…†‡‡‰ŠŠˆ‡ˆ††‡‡„ƒ‚}yupnjggfffeggfgijkmprvv‘ŽŠˆ‡††‡‡†ƒƒ…‚€€„‡ƒ€€~|zyxvvsqqqqqrrqqppqrx€‡‘”’ŽŒ‹‹ˆˆˆ‹‘’’ŽŠ†ˆˆŠ‹ŠŒŒ‹‡†„„ƒƒ2222333344465544444444445555554455556666556666666666666543443222110/..----,,,,----,,++,,+,,,-,+,-----,,-..--------....------....//../.,-..//113689<>?ABDEFGGGGGGHHIIIKJNU]dggadg[L?2/.-04TpkidhruJ<azwpc=%'&'()*+-0A`xvklx~xsmlovd]\[aceffikl]/&*,-3Sg[Y[XN9*'&&')(-00/.++-012311699Ie€‡6&.00/11..-,++('&%$$%%"!" ! !! !#""')-/7?DFINQLNPRPMJLNQRRSW]effhgdZUVKIZN67=:62111111278864230(%%',Cax‚‰ŽŽ‹‰‹ŽŽ…wO0:BMB><@LJID?967:;<<9998-$ !$$$*?Si}‰ŽŠŠŒŒŠtdSKPZeov|„††…ƒ€€{zwuqsxzyxtufadkjpqong_TWgbfTLT\ejsvz}€‚†‡ˆˆ‰Šˆ‡‡‡…††…„~|xtomifeeefeggfgijlnqqtw„’‘Œˆ‡†‡ˆ‡†„„…€‚†ˆ€€~|zzyvtsqqqqqqqooppqry€‰Ž’•’Ž‹Œ‰ˆˆŒ‘‘‘Šˆˆ‰Š‹‹‹‹Š†„ƒƒƒƒ3333444444454455554444555555555544456666455677665666666654443322110/..------------,,,,,,,,,,,,,,------,,--,,----------------....////010...013559:;?ACDDEGIIJJLKKLLLKLNOSY`gmpmd\UK?62////;_phedjtk@UwysiF(''))()*-3Fi{rkn|zqmkdavk\]\`cdcchjj]0'*+-3XhZYYVRJ>,&&'''+23/..,,-../24>FPaxŠ”w+13234321/-+((%#"####"    !! !#$&)-3:@DEFHHGJLNONNMMPOQU\`feijgd[RMJZeXF?<:7320112366876332+'')Ai‰Ž‘’‘Ž‘‘ŒŒ’†lB?FLEDMITYUOMIB==>AA>>?<2($#%%&'.BXmŒ‹‹‹‰ƒyeNBHR_ipx€†ˆˆ……€~yvutuqtwwkfc]Z`^bfb[a\Z=AQd]^[_emrvzz|‚…†‡‰Š‰ˆ‡……„„‚‚}zvsnlieeeefffffgijnosst{Ž””ŒŠˆˆ‰‰ˆ‡…„…€€‚‡‡‚‚~|yxyusrpqqqpppoopppu{‚‰‘”‘Œˆ†‡ˆŒ‘‘‘‹ˆ‰‰Š‹ŒŒŒ‰ˆ…„‚‚„†333344444454445555444455555555554445666645567766566666665444332211//..------------,,,,,,,,,,,,,,------,,--,,----..----------......0335400023378<>?CEFEHJMNNNOPPOPPPOQRRUZahnospbRC>7543//1Cjpfeely^Nt|voP+&(**((*-2Jmyolrxnlgbdopb`^^acabeih\0'+,06_e[]][POL@.('&'(.2/-,,*+,,-7BNYix„Œ–˜[-4566321/-+*)(&#"""!    !#$$&(-269>ABDEEINKOPPOPMOSV\l_aoljc[QLYe_UOIA98852212567798662,(9b‚‡Œ“——”“•–’‹Š’Ž{R<FIJJKNSVXX\aa^UUQONMGA4&##%&((.AWmŒ‹‹‹ˆudI9=JW`kv}„‡‰‰ˆ†‚}~~tjada^`h]aYUWafaWZa…ACW_[`diosvxy|ƒ…ˆˆŠ‰‡†„ƒƒ„‚~|yurmkheeeeffeefgijnosst|””‘‰ˆˆ‰‰ˆ†…„ƒ€€‚‡‡~|yywusrpppqqppooppqv|„‹“”Œ‹‰‡‡‰ŒŒˆ‰ŠŠ‹Š‰‰ˆ‡…„„„…‰33444444554444445544444455444455555566666677666666667664554433331100..----,,---,----,,,,,,,,,,,,,,--..,,,-,,----......------..//..014577667799>@ABFGKMMOOQQSUUTTTTSSSSUV\ciqqqoe[PC<8542105Pqieffru]q€ysY0&&)*)),.5Rqvmmu~qeggiiith_^\_``cdghZ0&,-1:ee^`^[OMNQD-)('%'//+)+**+/8GWbn{†Šˆ–›“6$/3444400--.-,)&$!!  !"""#%)-.16:>@BCEMSRQNMIHMQU[ejoplmj`SNK`cUPPNI?8743334478:<<<949Z‹Š’—–“•šš—’ŒŠŠŒ‘…^>IIJHLMRTZ^_bcd]Z^]ZXTE0%##%%&&-ASi}ŒŽŒŠŠ„|pbE/1>JXelw‡‹Œ‰‡†…‚€xjaZY^\WWW\^^_jeXiƒˆ}LZa^ZYforsvz|‚…‡‰‰‡„……ƒ‚ƒ~~~~}zxtqkkgedeeedeeghilnpsss‚“““‹‡‡‡ˆ†…„ƒ€€ƒ‰†€€~|zxvuqqpppoooooonopw}…–“ŒŒ‹‰ˆˆ‹‘ŽŒˆˆ‰ŠŠŠ‰‰‡‡†…„„„†44444444554444445555444444444455555566666677776666667634554433331100/.----,,---,----,,,,--,,,,,,----..,,,,,,..--......--------//134468;<<<<<;;=@DDHJLNOQRSUWXYXYXXXXXXZ[`fkpsqoeZQPKA8433208^qgdhnvuxƒ€xa3(*(**+,.<Zxsmls~vjiiiijpma]\^cabfhfY0+.34?fd^]^ZMJPTSC,'&$$&*.*-317AKWhp|‚‹‡”šx(/244310/,--++)%#!  "!#&(*,,-279<@BGMPQIBHKNSY__ejglni\TVMRdXSOPPMHA80/13666666<8=YzŠ‹‹Œ‘‘““‘••—’ˆˆ‰lFFIILMOQSVY\^__\\[\[XQB,$"##$$&)7Mcx†‹‹‹‰ˆ‚ynX=,)/@LYet~„‹ŽŒ‹Š‡‚€yvtdefeZZ^jjg_LHNk…ˆŽtSPLQYgnsuuw|€‚„†ˆˆ†…„…„€€~||}}{xtqkieedddddfffgilnpqtu‡•”‘Ž‹‰‡‡††……„„‚€‚‡…€€~zywtsqqpoooooooonnrxŠ‘–“ŽŒˆ‡‡‹ŽŽŽŒŠ‡ˆ‰ŠŠŠ‰‰‡…„„„……‡Ž44444444554444444434444444554455555566666677777777778AC;6644443231000/....,,---,------------,,----..--------......------....--//13558;=AABB@==@CFHKNPRTUXY[[[\]\\Z[[\\^_bhnsvtqg]TLQUPB5211/>enhfhqy~yi>%'*())*0Bdyolkq€ukhgiigflc_]^bbdgfgV31114Gfc]__YFFNSTRC+&$##'6=69?EOX`jx…Š“–›™U*,.10/...-,++*'$"""%'*+++,/37:@JKQQNJOLNPSW^^^acaaZVYSUc^QONNNLHE>72.+//02345Os‡ŠŒŠŠ‘€ps€Ž’Œ‡‡Š‹rHAHIJLNQSSSVWYWW\^^\XUE,!! "$%$'4Jbw„ŠŠ‰†~uiR3(56>DO^o|‚‰ŽŒŒŠ…‚€ztneZWVX^djdedRL[{‡‰Ž}of[Valonw}„†‡‡††…„ƒ‚€{|{{{yxtokheddccddeeeghloqrty–”‘Š‰‰‰‡…„ƒ„ƒ€‚ˆ„‚‚€€|yvvusqpqppoonnnnlot{„‹‘“–’ŽŒ‹‰ˆ†‡ŒŽŒ‹‡†ˆˆ‰Š‰ˆˆ†††„…†…ˆ44444444554444444434444444444455555566666677777777778DWN96544432310000....-,--------------..------..--------......------....--//23579;?DDEFEBACEIKNQSTVX[]^_````_`````bdgkpsvtrk`WMHDHMKA4101Gkkdchp}…€zpV0(*(+-17Jiumkhozojhhiieceha`_^bdeefU31112Pga_c`WEFKPQRP?)###%1DNDCMSZbiy„ˆ‰‘— –;/.00//./.-++*'$"! !#%&&*,,-/37?DEKMNKIJMOQSWZ^^a`b^YUSUc]QPNNNLHEDC>830.,+//Diƒ„„ˆŠŒŽˆwU=AYx†…ŠŒŒuPDHIIILMNORSURRTWYXVRPC.!! "$%$&2E]r‚ŠŠ‰†ƒ}sfR/&7;?AMany…‰ŒŒ‹†‚yskcYSQPKOVX^_^_v‰Ž‘•™œ›ŸŸ—}WU[TU[`cp~ƒ„ƒƒ€~|{zz{|ywsnjgdddccddeeegimpstu~’—”’ŽŒ‰ŠŠŠ†ƒƒ„ƒƒ‰ƒ€|yxvtrqqpoooonnnnnpu|…Œ‘’”•ŽŒ‹‰ˆ†‡ŒŒŒ‹‹‰ˆ‡ˆˆ‰Š‰ˆˆ‡†††††…ˆ44443455444444444444555544334455665566776677776666667:GN<555444331//00...---..-...,,--..------..---...........------------....//1469;>BHJMMLIGGJLNPSWY[^_bbcddddccddeeffjnquvwrlcZQJCBBFIID:10Pofcbfr~„~ykWC536:BJYoqjgenumkijjheecmda`_bdddeS0,*,2[idaghWIKMOOOOL9&$%(0AVXKHRXagr{‡‰‡Œ”šž„%(.320//.+)***(&# !""$&'*-/24:ADGPTYYZ[]^emvustpkf`_ZPWf`SPOOMKIFDBBC=:421+2\~‚ƒƒ…‡Š‰€mK*()=cƒŽ‡„‡ŒvPAIJKKKMOONNNKKPSSONMKC.!!""$%%(2H]rƒ‰‡†ƒ€{obM-)+/6?Malu|‚…ˆŒŠ‰ˆ…yskfYUQPR]_]\bgo{’•› Ÿ¢¥¤œWLNSQJG@;ALVl~‚ƒ~zyyz{zyvsmhedddddddeeegjmqstu†–•”‘Œ‹‹‹‹‡‚‚ƒ‚€†‰‚€€‚€€}xwuspoppppnnnnmnopu~‡‘‘•”ŽŒ‰‰††ˆŒŽŠ‹Œ‹‰‡‡‡ˆˆˆ‡†……†‡‡……„Š‘44443455444444444444555544444455555566776677776666666657:3554443310000....--..-..-..-.//------..---...........------------....//357:<@DIMORRPMJLNQSUXZ_abeegffhhiihhiiiinqtuvurlcZTMFB@>=DMNE?>\ldccis}yrf\UV[`dlrnigdlxoijihfbdbmlfecdfddcR0)**<gidfegOLOMNNMNNK8((.6:K\ZLQY]dmw~…ˆ‰‹Ž’–››h(//./-+)(())('$!!""#%%),/112FWdlqrvxzvrttvtrtsstrmaUXeaTONNNLIFDBCBDFIA0/Ao‚z{~ƒ„…}a7%()%2W}Œ†ƒ…Š‰sIDIJKKKMNNMMIFKLNNNOKIB-!!""$%%(3I_t‚‡‡„€~wn^F(+3/*3M_iqx|ƒ†ˆ‰ˆ‡}xpieb[U[\^\]agqŠ”™ ›’…iSHVaain\MJHGGDBJf|‚|zyz{zyxurmhddddddddeeegjmqsuw——’ŽŒŒ‹ŒŒŒˆ‚‚ƒ‚€†ˆ‚€|zxwuspopooonmnnmnopvˆ‘”“‘ŽŒ‰‰ˆ‡Š‹ŠŠˆ‡ˆˆ‡ˆˆˆ‡†…††‡‡………Ž‘44444444444444445555554454554455456666677766666655665563455543333222110./.---.............//..........////..--------..--------00368;?CFKNRVXWSOPQTWZ[^bcfehijkkkkkjkllmnrsssutpkb]TNKDC@><:=CEEOghddfoy||wysppprropnhefbk{pgfffeccbmvjfeadcdbQ,**,IlgfhgfKKONNONLLKH82599=SZTOSZ_iq|„‡‰‹‘•š›™C*,,***''&&&&&%#   !"!&'*/9Nahjjijpyyvustsqooponprrtsqm`UQOONLIGECBBEJQ``P[{€{||€„~m8&(%'/NwŠ†ƒ†ˆ‚hCDIJKKJKNMMLFFJKLLKJIG>.! "#$$%(3K`w†‰…‚~{tl\G.&1)(:P[elqw{~ƒ………„ƒ€{smijkhaZ^cgkpx‚‹‚B.0;M]`nqtfVXchimmh^RVgy{xyxzzyxupkfdbbddddddeegknqss{’—•Ž‹‹ŒŒŽ‡‚ƒ€€ˆ‡‚‚ƒ~|yvtrqpoooomlllmmosy‚ŠŽ“’Œ‹‰‰ˆ‰ŒŽŠŠ‰‰ˆˆ‡‡‡ˆˆˆ‡‡‡‡‡ˆ…„„†4433444444445544555544445455445545666667776666665566555553554333332211110/..-../00//////..//..........////..--------....------/0/28;@DHLQVY[[ZUSTUZ\^begjjlmmnnnnnmnpprsuvvvtsoib]UPMHEB@=9856;CRfeceisyuxvttuxvsolfbbebi}pijhjhiijo{nihcceb^N,*+/XlhfjnaELPPOPNLKIGFB?<=;=E9<KV^fnr|„ˆŠŽ“–›ž‰,!&(''&&&%%$$#"!   !#"'?Zfgdcdegrxxutvtsromkkllnpprv{}t\PLNNLHFECBCDHSamrz‚~{}}}~y],$%&$$/NtŠ†ƒ„‡€Z9DHLMMLMNMLKFHKLMMKJIG>.#!"""%(8Pfz‡‡‚~~{tiX>+,0,.EQZ^gkquz|}~‚€|yutspngefhkqxƒŠŒ‹\2DL\ba]nsm†Ÿ£©¦“ˆ€‚ogmvwxzywxsojedbbdddddefgimooru~—™“Œ‹ŠŒŽ‡ƒ€ˆ‡‚‚‚€}{yvtrqpoooollllmmoszƒ‘‘‘ŒŒ‹‰‰‡ˆŒŽŠŠ‰‰ˆˆ‡‰‡‡ˆ‡††‡‡ˆ†ƒ‚ƒ‰5544443333444444444555444444445555775556666666666666665555542244332111000//../....//////////////......////..../---..--..------/0146:@DHLQX\^a`ZXYZ\``dhijlmnooooooqqrrstwwvutqmfa\WQMJHDA?;96213<Wjcfeorghgfjkjifgiffed`fxsomiifeghh}rhfdaga\N,*)<gkhilmSBKOPQQONLIGCB@B>?9;54BQZbglu€ƒ‡‰‘•—˜šs $'&'%%$$""!!  "7[lica`acirzwuuwvtsrpnnlllkkloptz€wZLONLKGECCCCJT`kt€„}y{{xuoJ)&&%&&.Ntˆƒ……zO7BFJLLMLLLKHEIKKMKJHFD>.#  !!!%,<Tk~‰‡}yrgS8"'18=LQZ\`fknqrwy|~~~|wxwuqqqojnsz‡Œ‹‰ˆA'7EQ[]QUb}š³¼»º¹±¢Ž~p™wt|zzzyvsnkgcbbdddccdegilnqss„™—’‹Š‹Ž’„‚ˆ…ƒ€}zxvtrpooonmllllnlot|†Œ‘‘Œ‹‰‰‰ŠŽŽ‹‹‰ˆ‡‡ˆ‡‡‡‡†††‰ˆˆ„€‚†‘5544443333444444444555444444445555665556666666666666665555454444332111000//..///..////0/////////....../////.....--..--..----..00146:>AHLPV\`cda^\]_abfhilnppqoooooqqrsuwxxvtsokfa\VSPMJFD@=:74111GjeacilXKRUTTNJKWhfa_\Zdxpjidgjjgdexxkhfchg[J,'.PnihlojEELPSTRQOMIEC><@E>;9=9?TV[`gmv~„ˆŠ’•—˜X&&$$$$%%""!!   4Zkje``bcclvyuvuxxxxusqpnnlljjjklnsz‚y\ONLKGECBBEJRant€}ywwsp`9,,(&'(/Os‡‚€„„vI7BFJLLMLJJICEIJIIIHIGE?-$##!"#%,@Xm€ˆ‡‚€zrdP5""&2BMPVY\aeikmqtxz|||{{|{wtttrptx~ˆŒ‹ˆ‚71<ES_VQMn ¶¾º¶·£«´™Ž“š–€fXp{yvrmgccbccccccdehjmoqsuŠ›˜“ŽŒŒ‹‹Žƒ‚‚‚‚ƒŠ…‚‚€}zwutrpooonmllllmmpu}‡Ž‘Ž‘ŽŒ‹‰‰‰ŠŽŠŠ‰ˆ‡†‰‡‡‡†…†ˆ‰‡…‚†Š‘554444444433334444554444444444446666555677666666666666555344444444321100000////.//////////////////////.////.//.//.....---------/1358;@EJOT[aejiea]_bdfjljmnnpnnnnnqrtwyzxwvtrnid`\WTROLHFB@<97312:^ia`bkX04;:62/7Nhd\ZWS]xrigbdhjhilr}mfcbjo\G'(@hkijpp]?HNSTUSQPNIEA?=<>EB=8@ARdQYafku}‚†‰‹Ž’–—‘=&((%&%$##""!!  "Eloe^\`ddfjxzwvwxy{zyxvurqpqmkkkiijlr{„z[PLJFECDCDITant~zvsstqrZ7/0,(''2Qu„€~‚ƒp=3AHKJLMLJIABGIIIJIHIHF>,"#%#$%'/C[qƒ‰…ƒ€}ypaM2 !%9KPTVUX\^cegklsvxy{{{}~zzxxuvy|ƒ‡‰…„33<DT[LEX”´½½«–¨¤¬¹²‘†ž•…w_nxwvokgecbbbcccccegjmoqswŽ™˜’ŽŒŠ‹Š„‚ƒƒ‚‚‚…‰ƒ‚ƒ€{xwusrpoooomkklllnqv‰’Ž‘ŽŒ‹‡‡ŠŒŒ‹Œ‹‡‰‰‰ˆ†………ˆ‰‰†ƒ‚…‰Ž‘‘554444444433334444554444444444446666555677666666666666555344444444322210000///////////////////////////.////./////.....--------/01357:=BFMS[aejmjfcbdehkkjmnnpnnnopqsvx{{xwtsqmgd`\XVSPMJGDB>:74213Nj`]`gg5'*++,.9Re_WVPMVxshggcekejkn‚tiffmv`C&BdjhilpqNBKPUVVTROLGEC?=9:@JJ?9>E[XPX`bju{„‰ŠŽ’’•†- ()'''%%%""!!   /]nk_^`cegjqzwuvwxy{}}}}ywvtrqonmkjfhgksyqULJFECCCDJTblr|zrppqnnmaE1//++5Uw…~~€i2#5EJKNMLG?=CIKJJJIHIHF<*"##"%%&0G_wˆ‰…ƒ€}wo`H-#%,BPTWWWYZZ]\`dfkqtvxyy{}}}}|xz}~€ƒ……‚y77;AMRJDo¦·¾¶ˆ| ´º¸¶‘~Š—–’˜‚uvutokgecbaabbbbcegjmost|“™—ŒŒ‹Œ‰ƒ‚ƒƒ‚€€…‰…‚‚‚€}zvtrrqpnnkkkklllnpwŠŽŽŽŒ‹††ŠŒ‹Œ‹‰Š‰‡††………ˆ‡‡ƒ‚‰’445543555544444444333353444455556655555656665566667777664444443344343311111100////////0000//./00////00.///0000/..-....----..../134679<AELRZ`fknnjgfgiiijiklnpooorswx{|yxxwvsnige_\ZXSQOKIFB?:8622/?cc^afjG&(*)+/;Te[WRMNTtwfghiiifhlp~mkjhuzpgihhlpnphCGMQUWURRNIFEA>=;859FI?:9BIPPV^fmu~„‡ŠŒ’“w%"(((&%%$! !""Bjnb^`cefjpw{wtvxw{|~}~~}zxuvwtrqojgfeffmsz|iPJGFCECGLUbrxyupmnpoopomaG2-,7Vy‚~€~d0#$*;FHJH?53<CIKLKKJHHE8%""""$$&3Md{‰Š…„‚}vm]C)"*:LUWZ]\\[ZYTUZdhlqttuwx~€~}}~€‚‚‚~~‚rG9@CKICM‰©¶½¶{Yƒ‘©²ªŽƒ‹–“¡£œˆuqrokfbbaaabbccdfhkoqqr~–™”‰Š‹’‰ƒ‚€‚ƒ‰ƒ‚‚€~zwtsqoooonmlkklljmpxƒ‹ŽŽŽŒŒŒŒŠ‡†‰ŽŠ‰ˆˆ‡‡††††‡…ƒ€ƒ†‘“’‘555543455544444444333344444455444455555665555566667777664444444444222211111100////////0000//./00////00.///0000/..-....----..//0135789<AEKQX^djppmjgfhhijlknoqpqswy|}~{yzywrmjfc_\[XTRPMIFB?;962304[g`_bhW(%)),0<VfZUQOPUrxheeebekhimzƒskjio|zxoloppq\AHNPSUTROLGC@><:95328CG>15=CFQ[^enu{‚†ˆŠŒ‘”k%&&""#" ! #Nnl`_eddirwz|wtsuxz{{|}}||xtuxvtttrpkigefhmszx`KHDCDDHMXfrxwrqnmonnqromk`TB?\z|~€y[(""#!*8AA7/9@BFGIKLJIHD6%""""$$(:Qi{ˆŠ…„‚xmZ?&%1DRVY[^__ZYWTSY]ekmoompsx|}}‚‚|‚ƒmVCFEIE@a“¨²·¸ªŽ|†–•›•š”’’“›¦•ƒronhfdbbbbaacddfglnqrs„™™”Œ‰ŠŠŒ‘Ž‰ƒ‚‚€„‡‚‚‚‚€~zwusqooonmlkkklmknry„ŒŽŒŒŒ‹Œ‰‡‡ŠŽŽŒŠ‰ˆˆ††††††„ƒ…‹–•’Ž65554345555555444433443333445544555566666655445566756666545544443333211111110000//////0000//0000..//00//////00/..-....----..000135689<AEIQU[biptrnjggfhikloqvyy|}‚~{zwqmjfb_\[XUROLJGC?<973213Li^]aca0$()+0>XdWSQRTXirfabcaailrpq€ujffhq{zyuonprnNDJNORRROKJEA><:75331/2@C:37<?DT\acnu|„…ˆ†‹“’X"$!!  "#$&# -Yokedhhinrusvwustuvyzyz{yrjiihquqprvwrolhfilpswrSIFFBEIP]krwvonmnpmprqojeiooko€|~}wS$!#$#"%#+*(/:?EGIIJEFF?1%#$""$%-?Vm€Š‰„ƒ€ylX:&*;JU[ZZ]__]ZWUSV[`eikljkowz|||}€‚‚‚~ƒ‚mVOLGIBAlš¥««¨šš¡ ¡˜“™š˜Ž˜˜ˆskidbbbabbbcceggjnqssŠœ™–ŠŠŠ‘ˆƒ„ƒ‚…‚€}zwsqonnmllkkjjjkkns{†ŒŽŽŒ‹ŠŠ‹‡‡†ŠŽŽŒ‹‰ˆ‡†……………ƒ‚…Š••”‘655555665555554444554433334455545555666666555555666766666555444433333311111100000/////0000//0000////00//////00/..-....----..00013568:=?CHNTZ`gnrusnjighhinqv|ƒƒ……‡‡‡ƒ~{zwqnkfb_\[XUROLJGC?<973200@c`X]be@%((*/A[bVRQTVVdsg`ccchmmokgqsh^_cimrx{xttm]GIKMNOOOKKJEA>;9653321/2<=437AGRYYaemuy‚†…ˆ‘M  "%(+-% 7amhdgimmrxunprrqposvvwyzphcehmnopnmkkrxwoihjlmrtsdMHDCGKUcotvtnmmonkntrpljhimr{ƒ€{~|sK$!$$"$$$'*+).:AEHIKMLE<0&$$##&'0DYq…‹ˆ„‚whT4%0BLRYZ[^``_\WUSTY^afhiknpuquz|}€‚‚‚€„€n[ZZTQHDqœ¦¥£ž•—˜Š‹™—–“–š˜•šœ“‰‚jedabbabbbcceghkppsv‹š˜•ŠŠŠŒ†„ƒƒ€~€ƒ‚}zvsqnnmlllkkjjkjlnt~ˆŒŽŽŠŠ‰‹‹ˆ†‡Œ‘ŒŠˆ‡††…„„……‚‚‚ˆ“•””‘55665566645555444455443333345544555555556666666666666666665554443333332211001111/////0//00//0000///////////////..-....----..//123579:=?CGLSX_flqwurokighiot{†‡‡‡ˆ‰ˆ‡…}zwrolhdb^[[YUSOLJGC?;8621./4SdZW[cS&%(+2C]aXRQVYX`ricjjnlkmkllcgie`]cinquzzn^OMNMMNNMLKJIEB?=96522/.../6A?7>GNWaU]dlt{‚‚†‹‘•A  !!!!  !%(/4-Aemhehjknvwpiknrponoqttuvkcaaagjmnqnlifju{slljjlnpqmWFCCHNXeptxqnopqnjmrroljjhkt}‚|}}rC#$$"##"%%',.**4=BGHGHE</%$$$$&)2G^u†‹‰…€tgS1&6DKOV[\_^]_\YVTTX\`caceikppmuw|€‚‚‚ƒƒpdgcZVQOu¦¥£™–“ŽŽ’”™•”›¡ ‘‘Ž|fbca`abaaccegilqquy™–’Š‰ŠŠ†…ƒ~ƒ‚ƒ‚{xuqnmmllkjkkjhkkmow€‰Š‹‰ˆ‰‹ˆ……‡Ž’ŒŒ‹‰ˆ†………„„…ƒ‚ƒ‡”–•”“9999886676555533445544333333444455555555666666666666667666664444333333221122111100///0//////000000/////////////..-....----..//013579:=?CGLPW\ciorutpmifhltx|„………†ˆ†„{vspnlhdb^[ZWTQNKIHC?;86220/1Cb[XZ`]2%+.0@Z]VSUWXY`smdhpqqnnqmnk_]bidfgklngaUQSSTQQOOMKIHGEB?>;762100//,-7FE?CHNidU_glqx}~ƒ†‹‘•‰8   """""""" !#"'/8HZhhhkmmqwvligillmmopqqtr][[[_`ekopnoqmjditwqokkmlnnreIDBIQ[hqwunnpppmfirrpnkljiq{„€z|{k;$&%$%%%#%',12+$(6ADGFB7+#$%$$&*6Mcz‰‡„ƒ|reL.&7EKOSYY\^]][WUUUX\^abddccikjorx|€‚ƒ|rnkge`\\|ž¤¢œ™“‰Š‡z’“—˜••™¢Ÿž“†}kcbbbabaaccegilqrt{’š–’Š‰Š‘‹…„‚~‚ˆ†€€‚{xupnmllljjkkjkjjmqx‚‹Œ‹Œ‹‰‡ˆ‡‡…††’‹Š‹‰ˆ†…„„……ƒ‚…‹‘–•””’Œ9899998777665554444444333333444444446666556666666666666665664444433322221111111111//////--//0000110000//00/////..-....----.../013579;>@BFJOTY_eiptwsplggmwz}€ƒƒƒƒ…„‚‚~zvusplifca^[YVROMJHFC>:86330//5Y`WX\aC&),0A\]WVVYYY_sqijkmqljjlnjjdXYYR=:>BFRSWYYYVSOOKJGFDB@?<;9740/.----/8FKFFCSrcY`iisz}ƒ‡Œ”‹2! !!"####"$$%$$""(%5HMRZdjootxwiceddgggknpnojRQXW[\_cfhlpsutnjdkyyspllmlorpUDCJQ]muxrnoppnibhqspmmmmlu}„€|{yh7%''%%'(&'*./41*$%-:DC@3*$$$$'',9Pg|‡†„ƒyn_A)(<EJNRVY[]]\\[[ZZ[]_`a``_beedhlpx{}€€|wsspkgfe™ž–Žˆ……~sVo‹•˜™””—š˜‰yydaccabaabcegjmpru}”™–“Š‰ŠŠŽ“Š„ƒ‚~€‚ˆ…‚‚€{wtpnmkkkkjkkhijkmsz„ŒŒ‹‰‡††…„‚…‰ŒŒŠŠ‰ˆ†……†……„„…Š”•”“’’ŽŒ;::::::877665554444444333333444444445555556666666666666665554444443321221111110011//////--//0000..//////00/////..-....----.../013579;>@BDHLRV\agmrvvspljnuy{~€€€€|zyuroljgeb`^[ZWROMJHFC>:86330..1Ib\Y[`T((+0B[]WUUWWX\ovlnquyqoqrkike]\ZL==@HNTXY[[YVSQOMIDCBA>>=<:8520...//159CLIB2F^g]^djsy‚„†Œ•Š2! "$#$$$$$$$%%%$%5SlbNJWblqx{obaacaaccbgklnaAELRXY]bcdgmquuwsmiit~yqnkmmmprcHEJUarvxropppnb_gqupmkjhlr|ƒ~}}ze1&&'%%&(())&%)24,&%%.;>1&$%%('(-?Voˆ†„ƒ€€ynZ8(0?GJNQTY\][]][[[[]^^_`_^]^bcbcgjovy}}}€€{uttrsqop„”š–’šš”v{ƒ‰‹–™›š˜––—˜•ƒ|o`ababaabcegjmqst˜™•’ŠŠ‹‘“Š„ƒ‚€ƒˆ…€}zuspmmkkkkjkkijilns|‡‹ŒŠˆ†………„„‡‹‘ŒŒ‰‰ˆ‡‡…††……„„ˆ”•”””““ŽŒ<;::::::98887766444444333444333344556655555555666655666655444444333322221111000000////....//////00//0//////.....--....-------.012479:=?AEGKNRW]bjpuwvtmlovx{{~~|z|{{zxvqolkiecb_\YWTROMJEEA=977321-./9]aYY_a6&+0C[^YYYZ[[_kwqnmpy{xtwohef^WTG<>BHMRVZ\[ZWUSPLHDA@><<;:8764311/015;?;;JMFAB]g_`dkry€ƒ†Œ‘—ˆ/"&#$$%&##!$$%#*FhuqdLAJ`t|yg_b^_acccaaeikT?CJHOTWZaa`dintyzwtqloy{rmmmmkmmiPILWfvxuqqrqpm\^fptqmkkiks}ƒ{}xa,'('(('(*)'&'(-00'(()*//*)'&(%&0F\sƒˆˆƒ€€yjU1'5EKJLPRTXZ\\\\[\]]\]``_`]^^[Y\`elotwyz}~xrstuwutv…Œ‘“ ¬¬¢•z{ƒ‡Œ’•šž¡•”˜™’‚xdb``aabacehknrtt…——“ŒŒŠŒŽ‘’‰ƒƒƒ‚€€„ˆ…€€€{wvuqnmlkjjjkkkkjkowˆ‹‹Šˆ…„ƒƒƒ…ˆŒŽŒŒŠŠ‰ˆ†…††……ƒ…’••”””’’’ŽŒ=<;;;;::98887766544444333444333344556655555555666655666655444433333322221111000000////....//////00/////////.....--....-------.012479:=?ADEILOSY^dkrvwwrprsvwz{z{{zzzywuroljheba^[YUROMKHEB?;976411../2Ma[Y[bO'+/=X`\\\^^`agwuoqw‚‚wvxrkheUJOA:=@CKQUXYYYWVRPMJEC@>=;::::86532334<=;;=<>S]Zcijcddmsy~€ƒˆ——ƒ+('&%&&$#%$!(Onxi`c^K<ATntdY[]^bbbfe_`hdO=?ICGHNUVUWZ`hoty|{xuqlt|tlllkjhhhXKR[mwvqpqrqpeW[fosplkkjmt}ƒ||wY)'(())*))('''(*-4.(()****))*)))3Kat…ˆ†‚xfL-,<GJKLNQRVXYZZ\\\\^^\Z^]Z]__\YZ\^biostwywqnpuuuuvw‚† ³¶®£€{„Œ‹‹‹”š™šž –”š“‡|rabaa```bfhknrtvˆ™•‘ŽŒŒŠŒŽ‘‡‚‚‚‚€~„ˆ…€€€{wtqpmmlkjjjkkkkkmrw€‰‹‹ˆ‡…„ƒƒƒ†ˆŒŽŒŒŠŠ‰ˆ†…††………Š”••”””’’’ŽŒ==>=<<<;;;99887765444444334433445555665555666666665566665544333333321111111111////....---.//00//00/////...........//..//.-....012468:=?ACEGJNPV[_fjntwurqrtvxyxxyyxxwutonlihfb_]ZWSPNLIFC?>:97422/.--.=^^YY`a;(-=Xe`_^_ciigs}ut|Š…ywwunj_QJPE:=@CGNQVVWVUURPMIFDA@><:::::7544579=<<;=6,3L^fginndbjqw{€„†”—…&!)')'&%$#"5qyrke_]XN?>QRVYYY\^bbeeeefWD=<BHEHFMQOQT_hosstvyywups}xolkkjhif[RTapvtprssrm^VYbnrnjjjimt~}~uT'()(()*)(('()'),21)'(*+*+,,0--/;Si|ˆ‡„‚ƒ}scC+/>IKKMPPQRUWXYZZ\]_^]]]]\\]^ZWXY[[`ippquqghmosvxwz‹®³«žŽ…„‚‚ƒ‚‚Š—œœ›Ÿ¡œ–’˜‚~f`_``a`adhmprtwŠ˜•’ŒŒŒ’Žƒ€‚‚€„ˆ…€}{wsqnmlkkkkkkkllkmqx‚‰‹‹‹‡………ƒƒƒ‡‹ŽŒ‹‰ˆˆ‡†††……„‡”–•”””“‘‘‘Ž‹@@?===<<;;99887777555544334433445555665555666666665566665544333333321111111100////....---.////--00/////...........//..//.-.....02468:=?ACEILMNRV[`glpvxxtrtvvvwwuuvvutsnmkgfe`_]XUQNLJGDB?=;:8641/.---2Q`[Z^bR*,9Udcddelppir~z}‡Š|v|unf`UK=:9<?AFHMRSTSTSRPMJGEB@>=;:;:7544456;>=<;;3/+*<Yfgjrthcdktz~‚Š”˜‡,"))'''#@rvnjjkijfZA8IMEOUVY\acdeg^C4E?AQKEHHILNS]flrttstuxyxvx}}umjlhffcaWZiuwsprstphVTXalrnjkijnu~|}rK$')))()((***)*')03-''(****-0339G\s…‡…‚‚|r`A+3BJKKMPPPPRTVYYYZ\___]\\[Y_^[TUY_`ZbjjmodZ`gnswy|€…‘ ¨©•Ž‡‡‡„‚‡•œ›™žŸ•—‘Š~o_`__`_cfkmppuv‹˜•’ŒŒ‹‹Ž“…‚‚‚€„ˆ…~yurplllkkkkkkklllory‚‰‹‹‹‡………„„†ŠŒŠ‰ˆˆ‡†††…„ˆŽ“––•”““’Ž‹A@ACB@?><<;:::88776666554455444444445566665566555566665554443333222222011110//////....---.--...........---............//.......02458:;>@BDFILMQUX]dhlquxtrttuuusssrtrroljhfdb_[YVSPLJHFCB?>:87641/-,,,-A_]YZ^b=)7Qffiknqutpt|‚ŠŠpmuslj_XH789:<=AEKPQPPQPONOKFB@?>=;;988543237=>><<81...+0Jchhqqogfmsx}ƒŠ“–(!'+('"3suokkmmloo[C8<ODJUXZ[\^^[L94586EMIBIJJLT\cgimprqppuxzzz}}unhjgcaab\`pzxqqqrslbPPW`jpkjljjqy|~€qC&''(''()*))**)(*-150'(())*,234>Rfz‡‰…‚}yo]:+9EIMOOOPOOPRRVWYZ[^^_`]YXXW][TSUYed_dehk]V^fmtz{‡Œ”¡ ž—“‹‹‹††ŠŠŠ‡‡‰›š˜ž˜–’ƒyda`aaadgiloswz’˜’‘ŽŒ‹‰‰Œ’‹„ƒ‚€€„Š…|ywtqpomkjkkjjjjjjkns}…‹Š‹Š‡…„„…ƒ†‹ŽŽŒŠ‰ŠŠ‡†††…ƒ…‹’”•••”’‘’‘ŒBAA@?@?>>;;:::88776666554455444444445566666666555566666644443333222222011110//////....------...........---............//....../123468;=@CEEGJLPSVZ]cglquuqqqpprrppqpmmljheca^ZXVTQMKHFEBA><:76420.,+++-3O`VUY`W,2Jaklmqvxvqqs€mtlnvieh^XWB8::99:=AHNPMKLNOONLHC?<;:8778854325:?@><<71//0/.+5Sjjjurhejr{€ƒ‰‹’v$('(&jwmhjprttxrZG<7GIESWYZZXE657:81:DB@BDHIQ]dgfghginnprvxwvyzuojhea_`a_dswvsqrrpiYNOU`ilijljjq||€m<%'()))*+*+**++*++/471&'()),18<I\rƒŒ‰…„‚€wjV4,:DIMOOPRQONOPRUYZ]^_a`]YWUU\_]YSONaggfgfZYagrv|~ƒ‰Ž‘—››—‹’””‘˜ ¢žš’‹Š‘—˜–š›™’‡ˆ‡tfeddegilmpsw~•™“‘ŽŒ‹ŠŠŽ‘Šƒƒƒ„‰„~|vsqmllmlkijjjjjjlou…‹ŒŒ‹‰‡…„„…†‰ŽŒŒŠŠˆ†…†„„‰”••••””’’‘ŒFFEDDCA???<:998877777755333344443344555566666655555566555544333322211101111000////....--,,,,--..//------........--...........//112356;;>>@CEGINQTWY^chnnoommnnoommmkkjhgeba^[YTRQNKIHECA>>;86631/.,,++,.<\XST\_A)=Tflos{zvolgin[bq†Œxg[OSSB::;9977;CJMKHFJKMLKEB<::88887643237>BB@><5111100/,'@]flmpmjmvy~ƒˆŒŒ‘O#(&Qzqkjpuw{}`VG;3;B;?IUZO5)6;9=@=;;>BDGIQZchifabc`_eikoqstsrqqjd`_^`_chwxtturqodRMNT_fhjmkikr|„}€m@2.*++++****+,--,--08</&(),..9ASgy‰‰…„‚~udH-+:CGKNOPRSRONNORSX[]___^ZVTQZ`c_ZWTU_giie[_hnuz~‚‡Š‘–”™¤¤¢žœššššŒŽ””˜›–‡~‹†}lhkiikmnrsuw‚—˜“‘ŽŒŒŒ“‰ƒ‚ƒ€€„‡‚~~{wurolllkjikiiiijjmpw‡Œ‹Š‹‰†…„„„‰‹’ŒŒ‰‰‡……†„†Œ“••””“‘”’Ž‹HHFECCBBA?>><<:988777655433344443344665566666655555555555544333322211111111000////....--,,,,--....------........--...........//0123578:;=?BEGHKORVXY]begikkkiijjiiihhfedb_^[WUSPNLJHFCA?=<886420,+++++,,2M_VQW[W,0=P^houztmh_WQJZr…Ž†€sfe`I=9;99778>CIHEEFHIHGC@<:85545653357=CDBB=94222010../,+Dcjmpqmpsv~€…ˆ‰w $"B{qhjovy|‚w\VVI9257876;8,05679:>>>EHLQTZ[aijfa^cf_Z\_abfoqmlnqjd`_^^]alvtqqrqoo`LKOU]cekmjjnu}†‚‚„rRIE<0,,+*++*+..,+--.2:92)-8>7=MbtƒŒ‰…„ƒ‚€ueJ/'0>FJKNQPPOONMNNORX]]^_^[WTSW_fhdcbejklnjcipv|‚‡‹ŠŠ‹‹“š¢£ š˜™š—•––ŽŠŽ‘’““•‡„‚vpnmooqrswxy…—–’ŒŒ“‰ƒ‚ƒ„ˆƒ~~{wurpmlljiihiiiijjmpxˆ‹‰Šˆ……„…‡‹“’ŽŒŠ‰ˆ‡…„„‰”••”“’’’‰MMIHGFDBCA@?=<;;8986556666554444444455555555556644444445544333332222222221//////......,,,,,,--,.---...------------..--..........0023668;<>@BEHHMORVXZ\`bdeddbcegfeefecba^[ZXURPOLJHHEAA>;;86421.++++++,-,<[YRU[bE&19EW`ksoha\XUIH`|‰…{uujN<9<:87658=@A@BCCCCDA?<96430//146;?BEECB=6323311210320(3Rgmmjt}wtvz‚€j7 4uujjnvw~u[TUVN>423565432788::99CJNPT\_`^ejhe`cghec_]YPP`omjlqkb]\]^\^ovqopqrqlRLLOSX\ellgimv€†……ˆ†ylc[SD4-+++++++,++++,.4;=033:>DZnŒ‰ˆˆ†„{uj][WLEADFHNONONLJD@ILTZZYX\\[WY^flooprsstqsrqsw{‚ƒ†‹Œ‹ŠˆˆŠŒ‘“—š™™”“–˜˜–“‘ŽŽŽ’”†…Š„}wustvwwxwz|Š•”’‹‹‹‹Ž‘ˆ‚‚‚‚€~~„ˆ~|ywtqpnlljjjiiihhkklqyƒŠ‰ˆŠ‡………‡‰Œ‘•’‹Šˆ†„ƒ…‰Ž”•””“’‘’Ž‹NNLKIHEDECCA?=<<:996556666553333444455555555554444444445533333332222222221//////......,,,,,,--,.--,---------------..--..........00234779:<>?ACGJMQSUUVX\\^]]^_acba``_`^]ZWVTROOKIGFCA?><;98521.,++++++-,-1G_WQZd_0(0:MX[ced^XYZRJNlztpoorbQA<54421/14554678;<><:;964332158?BEFFEB>9311222255555450/=Zinny}{ueRT8'/ltihlow~|gWWZ[XRA3468<3/1666:>?BJMOTWW[__bfgfedeehea[YRE@Qfjjkpi`[[\\\eyzppqsqpbJHKNPU\eolikp{†ˆ‰Š‰‰…ypd[I6,+++*++,++++*,/5>735=BQizˆŽ‰ˆˆ†ƒ}tj\]affeWJFGLLJKGA.*>BFVXXY\`_]^emrsstvyyxxwvxz}‚ƒ†ˆŒŒ‹‹‰‰ˆ‰Œ“•––’‘’“““‹’–•”“”‘Œ†{wyzzz||‹““ŽŠŠŠŠŒ‘…‚‚‚‚€~~€‚ˆ~{ywrqpnlkiiiiiihhjklq{…‹Œ‰‰‰†…†‡‹Œ‘““’‹Šˆ†„ƒ†Ž”••”“’‘“‘Ž‹ONNMKJHFEDCB@?>=;;977677555555444444444444444444333334544333333322222211110///....----,,,,,,,,,,--,---------------------.....-.-001445789:;=?AFGKLOPQQSVWXXXXZ[]]\]\\\ZXURRPOLJJGECAA?;9764320,,,,**,,,,,-7U[SU]eO&,4@MSUYXTRVYXUR]lmkfhibXK8-.-+*(('''''*-148<ACDDEGGC@AEFGGGFEA;40000155766655633.0Ibgs{|xX $+kvlnqoryscW\\[^\UA556530-/4DIFFXdTQVZZY^^bded```dcdc\WTM?:CUbggkg_ZY[]]n~wpprqqsXFEKNQW]ejlmrx€‡Ž‰ˆsk^L4-,,,-,,-+++++-16:;;BLZrŽŽŒŠ‡‡†|sh`]bfcbbYGOMG>9=?9#/3.GXZ\_cdcfkrvwyyyyz|~}|}€ƒ…††ŠŒŽŒŽ‘‘’’‘‘‘ŽŒŒ‘‘Œ‹Š‹Š„€€€€€ƒ„Œ’ŽŒŠ‰‰‰ŒŽ„‚‚~~‚ˆ~zxvrppnlkiihfhiiiikms}‡‹Œ‰‰ˆ†…†‰‹’”’‘Ž‹Šˆ‡…‡ˆ’–•“’’‘‘ŽŽ‘Ž‹PONNMKJHGEDB@>>=<;987677555555444444444444444444333334544333333322222211110///....----,,,,,,,,,,,,,,,,,,----------------.....-..//03345789:;=@DEIJLNMOOPQRRRUWYZYXYXXWVTQONMLJIHFDB@>;977531/.,,,,++,,,,,,/C_WSXch>*-3@LPLLLMNRVYVTgkkhcbb^[J+('&%##!!""#$&)09ENQRPOONMJIIHGGFCA<7100001567666445554105I^owyye0*izmnmnrxw\XZ[\]a__G65531-.04FJILelSSSRSW]]acb_\\\]_^ZYQNC:7=O`g`ij`\\\[ax~urpsqqlLBEIMQW^djnuy†‹’’““ŽŒˆ€vk[D0-.----,,++++,/4;;=@Nbvˆ’ŒŠˆˆ‡‚{pe_DFciea^Scmg_VL=@;9<@KY_acefhnrvyz||||}~}~€‚†††‰Ž““•––———————•••“‘Œ‹ŒŒŒŽŽŒŒ‰‡…„ƒ„…„ƒ„„„‚‚„„ƒ‡Ž‹ŠŠ‰‰‰ŒŒ‚€€€€~~‚‡~|zwurppnlkiihfffhhijovˆŒ‰‰‡…†…ŠŒ‘“”’ŽŒ‹ŠŠˆ‡ˆ”–”“‘‘‘‘ŽŽ’Ž‹TSRPNNMKIGFDCB>==;9:8677466655444444444444444443333345442222331133222211000///..--,,,,,,,,,,,+++++++,,--------------------........013355778:=@DDFHIKMMMMNNOOPSTSTTTSSRROMMKIIGGFD@?<<:75421.-,,,--,,,,,,,-.5TaVX_fa0+/6ALJFGHGHMVUSXiopcZ\daWC'%%#!!""##$')/:KUTRPOOONJJIIGDDCA=7300001446777;895653560.07?EB5,jxnnrqpzz]XZ\_aa`aO@74430/--26>ABJNQWXUTUZ]__ZZ\[]]YTQMGA<66=O\^V`lb]]]\lƒ~uqqrsp_DBFHLOV_cgr|…‰Ž‘’““”“ŽŒ†tgV=//......++,+-.07<@ERj€ŽŒ‹ŠŠ‰ƒ|pdcP=^gbeehhhhlolbODKQQYafgknrsx{€~~~€~|}~ƒ„‡”˜šž   ¡¢£¡£¢ ™—”ŒŒŒŒŒ‹‡†‚‚ƒƒƒƒƒ‚ƒ……‡ˆˆ†……‰Œ‹‹Š‰ˆˆˆŒŽ‰‚~~~~~~}€†~{yvtqonllkihgfeeggijpw€ˆŒŒˆ‰‡…„‡‹Ž“–”’‹‰ŠŠŠŠ‹‘––”’“‘Ž‹“Ž‹UTSSPOOMKIFFCB@>=;:8977765665544444444443344443233333332222211111122221100/////.--,,,,,,,,++++++****++++,,++,,------------......//01115577:<<>ACDFFHJJLMLNNNNPQPQPPONLLJJHFFEDCB@?<::86420/.--,+----,,,,,,..?a`WX_gO(*.6BMJGIEDHKMTW^mqf_`de^T9!$"! """$',1?P[YXYVRUQNJGFFDA@?<9400001244668<><9557754410/-.+1evmkoqpw{cY[^^dffP>8;84422101347:BKPX[YZYY]]]]ZZ[\\YTPMI=8656=KSTQYhe[]]awƒ}vtutsqR?BFGKOV_houˆŽ‘”–—••“’ŽŒŒ‡}sbM5---....,,,++-,27K\dtˆ’‘ŽŒ‹‹ˆ‚ylcbcZ^eccefiiggjooppokdgmrsuuyz€‚‚„„‚€€€~|{zxy{|}…œ£¦ª««««¬­®°­ªª©£Ÿš–‹‹‹‹‰‡„„€€€€€€‚ƒ‡Š‰†„…‰‹Œ‹‹‰‰‰‰‰‹ˆƒ€~~|~||}€ƒ}{yvtqomllkihffefggijqz„Œ‹ŠŠ…„„‡Œ‘••’‘ŽŒŠ‰‰Š‰‹‘”•““”‘Ž‹’ŠXWUSRRQOMKHIEC@>=;;9977765554444333333333322333344222211111100110120110011//...---,,++++++******))**++**++*+++,,,,--,,----..-.////01333356799;=?ACEEFHIIKKLMNNMMMKKJHGFDDBCCB@A@><;967410/.---,+----,,-,++--4PeYWX`g=#,/6CKJFDCBEFHQWerjihb]X\S2($!! !"%)/=S^^``\[[TQKFBAA?>778821001233478;@A=8875544320-,-6lwljonnwzh\\[]`aW:(.7;9520036435:?GPUXWTVYY^^]\Z[]^^ZTRQG;7524:FMQSVdf]^[f€ƒzwvtstvkK=BEJQU\ky~ˆ’•–˜™—•’‘Œ‹ƒym]C2.,//00...++-..4CawŽ”’ŽŒŒŒ…€ug`_aabacddggeehnrrvy~}||~~†††ˆ‡ƒ€~|{xwtrsttt~¦¬¯±´´´¶·º»»º´³²®©¥•Ž‹ˆ†‚€~zzy{{{|}ˆŠˆ……‡‰Š‹ŠŠ‰ŠŠ‰ŠŒˆƒ€€€~~}}~‚~zxurqnmkjiihffffggijs|†ŒŒ‰†„„†Œ“••’ŒŠ‰ˆˆ‰‰‘–•’’’‘‘Œ‹Ž‘ŒŠYXWWUTSPNMIHECA?><<:877765554444333322222211222233222211111100110120000000//...---,,++**********))****))+++*++,,,,--,,--....-.//001122223668::<=??ACDEGGIIIJJJLLIGFFDCDA@A@@>=><<9864520//..--,,----,,-,+,,-/;ZaZUYed3&,/9CKHEECAAAHPZkuwp^PU`bJ( !!!!#%+6N`bedb_YOHA8500277569842111233567:>=:8875544533,-Bmumjmqqvyga\`^aX:))-07:952028755:?HORX[WOOVZaa^\Z[^]^ZXVWNB<655<FOUSR^g^Z\m‚xvustsqvtSAGLMP_s}„Ž’””–—™˜“‘Ž‹ŒŒŒˆ~sfW>149;;<862-*+022C_y‹““’ŽŒ‹ŠŠ…|ob_baabbdeeeggjkprtx}€„ƒƒ……„……ˆˆˆ‡‡ƒ€zxwttpqonnqu«±²·¹¹¹»¼¾½½¼»º¹·°¬¡–”•ˆ…„ƒ‚~|ywvuvvvwy{~…ˆ„„ˆ‰ŠŠ‰ŠŠ‰Š‹‡„‚€€€€}}~|yvsrnmlkkjihffhhhhimt}‡Œ‹Šˆƒƒ…ˆ””’‘Ž‹Šˆˆˆ‹’”’‘ŽŽ‹Œ‹Ž‘‹[[ZXXXTQONLIGDB@?=<;88875555323333332222221122000111111111//00001110//0/-/..--.---+++*))))**)((((()()*+++++++,,,,,,,----..--..0000000012445788:<<=>ABDDEEFGGGGFEGDCCCAAA?===:<=;9864332///..------,,---------3Hg`WU\g_)&&/5@HGFDA@@BIT_nro`PT]^W;!!""$'.D]ccdc\ND7,(#!#'(+.15:<943347679;==@:897565445307b}xmgkqsuw`Z\_abS-&(-/36477418;899>FOTUWWTPPRW^___\\^\[ZZ\\XK?<89DNTUVV[daW_v€}yvtprrjjwxXEIMVcw‚Š’”••–—™”‰„‡‹‡|qcSEGLPPPMHC@81214Ed|”“Œ‹‹‹ˆ†xk`_cbcaabcfghjossu{ƒ…†‡ˆ‰‰ˆˆ††ˆ†…„ƒ€~yvspohfimpmn˜­²³¸¼¼½½¾¾¾½¼»»»»¶°§žž–‹€€€{yxvsrorpprrvw„€{~…‹‹Š‰ŠŠŠ‹Š†„ƒ€€€~~€ƒ{xwsplllljiiihfiihhilu€‰Œ‹ŒŠ†„„†Š’•’Ž‹‹‰‡ˆŠŒ’’“‘ŽŽŽŒ‹‹‹Ž‹‰[[[[YYVTRNMJGEB@@>=<998755553333333322222211220001111111110000000000100//..-,,,++++++)))))**)((((()(')*****+++++,,,,----..--..00110000124446889:=>=>?ABBCDEEDDDCCB@>>===<<;;;:::77522221///.----..--.-...-,,--3ShZWY^iQ#%*,3>FHDCB@<AIRfppk`[^]]T+!!"%*6QdbceZF0,)%$"##$$&(*/9;844447;==?BBE@;:86766750Ku}tkimqvzua[_Z_gK((+.-1038:7<FE>;>>GMVXTSSSPQSQUZ^^]ZZYYYX^d`OCB>?FRUUUVXa`[i€€|wususj`bkuxXFKXo}†‘’‘‘’’’‡€~zz‰ŒŠƒxsid_bfffb]VQJA846Ml„‘’’‹Š‰‰‡|rdb`bcbb`abdglptw{|…‡ˆ‰ŠŠŠŠˆˆ†…‚~}}}|xsnjff_hmpkoŸ¯´¸»¾¾¾½¾¾½¾½¼»»»ºµ¬¦‰zz}~zxvtromkhhjjljoy}v{‚‹Š‰ŠŠŠ‹Š†…„ƒ~~€„‚zwupnkjiijiiihfhhhhjpw‰ŒŠŒŠ†„„ˆŒ”—“‘ŒŠ‰ˆˆ‰’“’’’’“—˜“ŽŽŒŒ‹‹‹Ž‹‰[[\\[YWVSQNLJHFD@>=<:9765542223322221102222222111100000011000000//0/....---,,,+*++**))(())))(())((()()))*****++++,,,----------/1..0011223333667799<>>@@AAAAAA@??=>><;;::::999866555221110000----.....--------./8Wc\XYcd@!%)+1;FIB@@>=@EUjsrmkihieD!""#'.?^iedbL3*+)%#!#""#&(+/79666679=@BCFHGB?;8766543I~yrmilqsyud[^]aaD$)++-.047:=9>JF<9=ELPTXURRRNMONPSV[ZXZZ[VTZa]NHFCCDLRUUVV_`ar|xwvtvtd]`glssVO^sƒŽ‘‘ŽŒŒˆ…}qotvyŒŽ‹†€}zxy{}|zwrkf\VKFK[q‡”’Œˆ‰‡†…|xkaadbaccehiknquy}}‚…‡ŠŠŠ‰Šˆ‡ˆ†…ƒ~zvvwvvusmhb\_dacgm‚¡«³¸»½½½¾½¶¾¿¾½½½½¼´ª …styyyz{zxurpkgffijhdemnw{ww|‚‡‹ˆˆŠ‹‰†‡„ƒ„‚€€€„‚{wtrpllkkjjiighhhiikq|„ŠŠŠ…„ƒˆ•–”’ŽŒŠ‰ˆ‹‹‘“”“’““˜¡¡›’Ž‹‹‹ŒŒ‘ŒŠ^^\\[YWVTROLJHEECA=<:976654222331111111111111100//000000110/////./..--..,,,,--**++**))((((((''(('''()))))))******+++**,-----..--//001122445566779:;<>>>@?????>>><;:9998888778866553221110000/-..-,---,-------./0?_cXVYba.#''+.7CGFBB>;<DXv}sjgbnt]/ !$'1Hhmml]7*-)'%#"!#%#$&*-46666679=@DFHHGC@<985441:s‚uonqstyyb^`]agI%%*/9:78>>?A>=FD?=@FMNLMLKNQMLNOOQRSVWW[\VTUWUNKKGEEHNUUVV\dj}|vusuuuua]bbekso_i{‰‹ˆ††‡„€xkhmtrx…‹ŒŠ‡„„†ŠŽŒ‹‡{tlf\\_m{‹’‘Š‡‡……„}tf]^_bdcfgklquw{„…‡ŠŒŒ‹‹Š‹Š†„€…wnjjkljd[WTQRUSW`‚Ÿ¡ª¶³µ»¸¸¼¾¼½½¿½½½½¼¹¦}imqtuvvwvuronkidipopkfltsjekpuvˆˆ‹‹‡††…………ƒ‚‚€ƒ‚}wurqllkkjiiighiiiikq{†‹Œ‹‹Š…„‰“–”“‘‹ŠŠ‰‘’““’‘‘“œ£¤œŒŠŒ‹ŒŽŽŒŠ]]\\[YXWTRPNLIGDB?<;:987643322111100111100000000////....//..........----,,,,--++**)((()(&'((&&''&&'((((())))()****++++,,,,--,.--0000112222223456778;<=====<<<<<;::::9988776888655533210000000///..--,,.---...---1Fd^UV]hV%&'&(+3?IGA??<:C^qjjbapsqM##'3NmpqnP--,)$""!!"#""$),0456678:=@DHJHGA>=875110^€xtqtuz|~gY_]bgU&,)-4=GEHLOIGDEIEFEDEKLIFCEJKIIKNRTQQRUYY\\URTQOPOKHFELSVWUYds{wrsvvvwr_[__agkqtt‚ŒŒŒˆ„ƒ‚ƒ…yecholm{…‹‹‹‹Ž“–•–“ˆƒ|wolqx„Ž“‹‰†„„„{o`Z_`^bgjnqsv|}€†ˆ‰‰ŠŒŽ‹‹‰ˆ‡‡ƒ~wz}|{sfZZXTPMWPGQ^jl‰£¨­µ¹»²Œ˜œ¬¾¾¿¾¾½½¼½·¢rYcilppqttttrqpnkgjonoppmqvm\[`emzˆŠ‹ˆ…………………‚‚‚‚„ƒ~xurolkjlhhiiihhhhjou}‡Œ‹Š‹ˆ„‚‡”•’Ž‹‹Ž“””’‘’™£¢—ŽŒ‹Š‹ŒŠ^^]][YYWVSQOLJHDB?<;:987643322221100////../000//....//////------/.--,,,,,,,,,,****((((('&'(('&''&&&'((((((()**))**++++,,,,,-,,.-..00112222223456779:;<<===<<;;97777777776654446533332111000000////..//..--...--,.3PgYRXbeF#%$#$(.;EIF@?>>Hcpncekhkf8!$(1PopokG.,)&#" !!"#"!#(+-14679:<>?AEIJIA=>>:50/[yxsqtx|{~pV\^`h^,),,0:CDEOQSXSMQOCINMGFGEDCCDIIHGMNTUTUVXZ^_YTSQOOQOLHDHQVWX[fuztrsstuwr_[\``ago|‹ŒŒŠ‡„ƒ„€wdbdljbq‰ŒŽŒ’–™š™—”Ž‹‡ƒ}…Š‘Šˆ…„„ƒ{m^[^^^einrwz|ƒ‡ŠŒŒŒŒŒŒŠ‰ˆ…‚{ytquy|vvld[T^aFDl’š™§²·¸¸¹¾¦w™Œ‘»¾¾¿¾¾¾½²]RW^cgkloqtssrqqroloromkkloooaORV`t†ˆ‹ˆ……„………„‚‚‚ƒ„ƒ€}xtpmlkihhhiiihhhkpw€‰Œ‹Œ‹ˆ„ƒ‹’–“’ŽŒ‹ŒŒ“”•’‘‘’™ Ÿ—Œ‹‹‹ŒŠ^^]][ZYWTSQONJHEC@<;:976644310110000//.....0////..........----,,--++,-,,+++***))))('')''('''&&&&&&''''''((((()))(***,,++,,,,---.111122113333335556798:::::8:::888777666666544443333222221111000////.//.-..--.----/6[bRQWab9"##""',6BHGCBB?PgbXZ]gknZ("%-Ffmjf@+,'&#! !$%##"$(+-/336:<==>AFIKC??A<25`wrlstxz||u[Z]]dg:++,-.6=AGOTXfbWICDMLIGEB@ABBCGIGHJNSVWWYZZ]a]YUSRRSNMHDEMUXZ[fsvqswxvuvq`[^]`dgsˆ‘‰†„ƒƒ„ƒtbccii^j{‡ŒŽŽ’•™ššš—–’‘Œ‰‡†ŠŒ‹Šˆ‡‡……whZTX^bhkos{„†‰ŠŽŽŒ‹Œ‹Š‡‡ƒ‚~}zzzug\armnge^_qsIZ™¬±´¹»»½¾¼»µ¬¸°³¼¾¾¾¿¾º§uHEORX\`dkoppprrqsvvrrxtlgginrriRAMWoƒ‡‹ˆ…ƒ„„„„ƒƒ‚‚„ƒ†‚~zwrnllihhhhhhhhimqz„‹‹ŠŒ‹ˆ„…Ž”•“’‘‘ŽŒ‹ŒŽ•—•‘‘“› œ–ŽŠŠŠŒŒŒŠ^]]][ZYWUTQNLIGEDB=<:9766433211100..//.....0//..,,........----,,,,+++,++***)))))(('&'(''('&&&&&&&&'''''''''((((()***++++,,,,--./111122113333335556778899999888777666666666444443333222221111000/////00/...--.-,,+--=b\TUZ_W-!"!#"(2BJJHCBAX_OLOW_hkC#)9YhibA,*&$" !$$#!!#$'+-0369<==>ADHIGCA?8Lpvmmlpvvyzs_Y]\^eI)-,11059@HOWakhWJGJNNJEA@>>??BDFHILMOSVXYXZ[]^\XXWWTONJEDGQWYZervsvzyxuwr_XY\_dkxƒŽ‘Œ‰†ƒƒ‚„‚~qbacfg]h{‡ŽŽ’“˜™šš˜–•’‹ŒŒ‰‰‡‡†„~vh^WUajghov}„‰‹ŽŒŒ‹‰†„„}}ytonj]SIennpuhU\jLo¦´¸»½¿¿¾»´³·º»½¾¾¿¿½»°—dFKSQOQUZ^bgjmprqrruyyrswqppoqwvshKEYp„ˆ‹ƒ‚„ƒ„ƒƒƒƒ„…‡‚€|yupnlkhhhhhhhhimr{…‹Š‰ŒŠ‡„‰’••’‘‘‘ŒŒŒŽ‘––“‘‘’˜œ™Œ‹‹ŒŒŽŒŽŽŒŒŠ^^^^[ZZXVSQOMJJGEB@>;96664331111//.-----....--..,,--..---,,,-,,,++++++++***)**))))(''&&&&&%%%%%%%%$%'&''(('&''))((******+,,,.../00112111223334446655777787777777666666777766664333333322222211100000//..----,,,,,,+-GdWRU[cV,!"! "'0<MROKGKa]QJKMYnc.%1Rd`V?,&""""!!#%%##""$(),.2449:<>?ABAB>;H_tqljiputvvq`Y\]^f_)+/0325888?HXil_UMMPSUSME==<<<?CFHJLMMQSVYYYWX\[ZYXXTPNIECDMSW[ennpruvsuvng\X]_hs€’‘‹‹‰‡‡†…‡…oaaabeal{ŠŽ“•–™™š˜—”’‘ŽŽ‹Šˆˆ‡ƒ~vlb^_gossy}‚‡‹ŒŽŒŠˆ‰„}{wutskqo_YpsmklsjZX[Wuª¸º¼¾¾¼¸±ªµº¼¾¾½¾¿»´›rQKTTQMNNNSV\`dilooppsyƒvwwssmiprpoaBKp„‰ˆ€€‚‚ƒ„„„„‡ˆ…~{xusoljhhhggghjms~ˆ‹Œ‰Šˆ†‡••“ŽŒŒ‹Œ”•“‘Ž–˜”Œ‰ŠŒŽ‹‡ŒŠ[[[[[ZYWVSQOMJHEDB?=;97764331111//.-------------,,------,,,,,,+++++***))))))))))))'&&&&&&&%%%%%%%%$%'&''(('&''))((******+,,,.../00112111223334445555777787666667777666777765664333333322222211000000//..----,,,,)***0QfUPV\b[-!   &+9HQTMIQe\NNPSetK!$/NaYUK;'""""!!#%%$##"$')*,/14668;;;<;7Icrsmfgjopu{wmaZY\^`d@-,/02589736AR\UKHPRUUWZUL@=;::=?DGLLMMORVYYYXYZZXUUUSOLIDABHOVXbjjjlpsqsrke_YZ`o{‡”’‹‹‰‡‰‰‰‰†oaaaekiq…Ž’’“––—•”Œ‹‹‘‘‘ŽŒŠˆˆ‡ƒ€yrnjhny~……‰ŒŽŽŽ‹Šˆ‡„€}zwuvrrronpqrnoqmkhfYS_c|©·º½½»º¶¯¥°¸»½¾¿»¶©~UMRRQOLMNOOOQV[_cgkpqqrt||wqsxqj`mvxwn\ay„‰„}}€€‚„„„…ˆ†…ƒ€}{wtqmlhgggghhimu~ˆ‹‹ˆ‰ˆ‡‰‘•“‘ŽŒŒ‹‘”•‘’’›žš“‹‹ŒŠŠ‹ŒŠ†ŽŽŒŠZZZZZYYWTSQOMJHEDB?=;:9764322000//.-----------,,,,,,,,,,,,,,+**(++++))((((('''(((('&&&%%$$$$$$$$$$#$&&&&&&&&''(())))**++,,,,../000112222233323444466666677666667777666667766554333333333221110////////.-----,,++,,+()5_bSPU\fa2 "(*7CRTOJ[i[PKQZpk5 ,Jc]TMG*""""!"$%%&%#$$',+**.//1269841Owpmgdfimppwpmc\YZ]^`Q1//2258<;:8<=KE=;EQWVXZ\ZQF>;;;;=BFLNNMPPUZZYY[\YUQOOLKJHDCACKRW`gghjmompmdcb\ZdsŽ’’’Ž‹‹‰ˆ‹ŒŒŠ‰ƒsb`bhru}Œ‘Ž‘’“”“‘Œˆ„„‡‘’‘‘‘‹Š‰ˆ…{yxsrx„†‰‹ŽŽ‹‡ƒ€||zywsqpomppkjknpqmiejc^c_v¥µº¼¾¼º¹µ£¬­¸»¼¹±“eJLSRQQQPPOOOMMQTZ^agipqrtssusv{|tq}ƒˆ‰py€ƒ†}y||}~‚ƒƒ…†ˆ…„‚€}{wrpnjihfgggkoxˆŠ‰ˆˆˆˆŒ““Ž“––‘Ž—œ—ˆˆ‹Š‹Œ‰„€ŽŽŽ‹\\\\ZYXVUTQONKIFC@?=;:9764322000//------,,,,,,,,,,,,,,,,,,++***())**)()))))(((((((&&&&%%$$$$$$$$$$#$&&&&&&&&''(())))****++,,-./000112222233333565566666666666666777666667766554333333333221110///////../----,,++,,))'):d`USV_id4!"##$%+3>MSPSgnZNNSatX#(>afYMB*""""!"$%&'%&%%(0/*))**+++,.,NrqkhgkooopviXea\ZZYUX4..366679;78@?B;19EORPRUSQJD=999;=BFLNPRTTUWYZ[\\YRLKIIGHEDCAAFKT]ddehklkmj_`hd`hw‰’’‘ŽŠŠ‰ŠŒŒ‹ŒŠ†ub_dkv{‡‘ŽŽŽ‘‘Ž‹ˆ„~~ƒ‹‘’‘ŽŽ‹Š‹Šˆ…‚€~}€„‡‰‹ŒŽŽŽ‡~xuqmmrsppqonmlklonnncY`ed`ZU`ž´¹»º¸¸¸´®°©²º¸¬QLMRRRPOQPPNMMNLNQUY^chlnrqprvx†‡…zŠ‘’‰y…ƒzx{{{|}}€‚ƒ…†‡†…„€}{zwsomjhggghkpzƒˆŠˆˆˆ‡‰”“ŽŽ’••’ŽŽ“›œš‘‹‹‹‹‹Œ†}ŒŒŠYYYYYXWUSRPNLKIFFD?==:8764332000/.---,,,,,,,--,,--++,,++******((**))))))))(((((('&$&%%%%%%%%$$$$$$"#%%%%&&''&&(())))***+,,,--//00000123323444456666666555766666676666677666655543333333322221100//../...------++,++('''BkbTRW_hc8!#$$$()*6FQTXliYPTXhsA)3FOJ</%!!  !!"%&'&$(&(+/,('&(&$$!*Lrnmhhlmnmpr[Khf`\ZYQYL*.1699788:75786328DKMKKMMHEB>:88:>AELNQTWXVVXZ\]\XPMJLJFEGDEEDAFMW`abehiikfZ]ghjp}Ž‘‰‰‰‰ŒŒŠˆŠ‹…wd_fpz‘“’ŒŒ‹ŽŽ‹‰…‚}„Š’”’ŒŒŒŒ‹Šˆ„ƒ‚„ˆŠŒŽŽŠ„{voga\_chklpqroonllnmlU@MX_[H@YŒ°¶¹¶¯µ·«¯±­¶¶ª€NOQOQQSRRSQPNNLOONNSUX\bfimoqt|…Ž–•’‡’˜šˆ„ƒvvyzzzz{~€‚ƒ†‡…„ƒ‚€~zuqolkjihjls|…ˆŠ††‰ŠŒ“’Ž’••’“™žœ–ŽŠŠŠ‹‹‹Š„}|Œ‹‹‰YYYYYXWUSRPNLKIFFDA?<<8764332000.----,++++****++,,++**))))))))(())))(()(((''''&&&&&%%%%%%%%%$$$$$$#$%%%%&&''''(())))***+,,..-//00000122233454456666666556666666665666677666655543333333322221100//......----,,++,+++(%#)HmaYWW_ggC!$%&%%$'/;JP\teWUW_rj2,,()%# !!  !!#$')./,,(&+)('%$""$%WtmollnokmrrF>hle\XZPXW0+159:<<;>;55463.39DIHHFFEDBA>:88:<?DGLOSXYVVXZ[\XVPJKKHGFFFGGGFCIPX]`dgijjcX[cinw‰‘Œ‹‰‰‹Œ‹‡ˆ‹…yd_ft‡’’‘Ž‹‹Š‰‰†ˆŠŠ‰„€}|†””Œ‹‹‹ŒŒŠ‹‰‰ˆ‡ˆˆˆ‰ŽŽŽŒ‡‚}uhXLIORT\`bcfmpoonnjeN=R_^V>3Np¥´¶¯‹˜°—¦²°± ˜oMOT]WSTXWURQQPOOOOOPQUX[`hq}ˆ“š¡¢ž™™—•ŽŠ…wuyzzzz{|~€……ƒ‚ƒ‚~~}xvtpnkihilt€‡Šˆ……†‰”•’Ž“•”‘Ž•žŸš‘‰ŠŒŒˆ‚w}‹ŽŒŠˆWWXXWWUTTSPNMKHEEA?=<;98532220//-,---,+*++++++++****)))))*))))))(((('''((('''&&&%%%%$$$$$$%%$$$$$$%%%%%%&&''(((((()))*++,,,--/////00122244455566666666666555555556566556666666433333332221/111//00......,,,,++,,+,*,,(%%*KmbXVW]diK##$$$$"! &2?FkwcXWUevP#''%#"! !!! !##%.9@<:/(++)&%#"#!=spklonmposk:+`kid\[UK[A)/49::=@@=86542-149@DDA=?ABAB?<:98;=BEJLQVVTTVXYZVTOJKLKHHHHJKJHDDIMV^ceefheWXdmt€‘ŽŒŠ‰‰Š‹ŽŽ‰‡‡Š†}h_jvŒ’ŽŠ‰‡…ƒƒ‚…ŠŒ‡„|‚ˆ”‘Š‰‰ˆ‹‹‹ŠŒŠ‰ŠŠŽŽŽŽŽŒ‰†zm[N\a\]^^ZZXY`ejmmmeWG=GJKNB?M^•¯²”R‡¤}š³·ª…v\MNRXQTYa]TUVVTQPRRPNOPR]n~œ¢£¢ ›Ÿ£Ÿšš˜’Œ‰Šˆ‡ƒ~xvxxzz{{z|~…„€~}{wutrollknyˆ‹ˆ†…‡Š‘””ŽŽŒŒŽ‘••‘Ž’šž•‹ŠŠ‹Œ†}rx†‹‰†WWWWUUTTRQPNLJHEDA?=<;98652220//-,,--+*+************))))))))))))(''''''(((((&&&&%%%%$$$$$$$$$$$$$$%%%%%%&&''(((((()))*++,,,--///11001222444555666666666655555555565665566666664333333322210011////....--,,,,+++++++,,)&#(/Mm`VUX^fl[&"$%#" !)3HlqbWVZhp2&#$#!! !!! !$"(.3782/++-*'%#"#-hnkjjmpllta.5_kigc`bJ[Q++<>;:=?D>7559830258<@=:7:>>>?>=:97:<?DIMOSSQQSUVWTRNJKKKKIGJMMLIFACIOW\acffcYZepz‡ŽŽ‹ˆˆˆŠŽŒ‰ˆ‡‰„}h_ly…‘‹ˆ†„~|xy~„‡‡‡…ƒ‰Ž‘‹ˆ‡‡ˆŠ‹‹‹‹‹‹Œ‹‰‡…~wod[mm[RWVY`\XXY^dffc\UF51GQORZ]z¢ªŽ_”‰sŸ²µ¨vVIILOOOSVVROTUTUTRQQRQNMa~–¥«°¯ª§¡œžžœœœ˜“’‡€ywxxzz{{{{|}‚ƒ€€€€€~~|zywtromnqzƒˆ‰ˆ††‰”•”ŽŽŒ’””‘’˜œž™‘‹‰ˆ‰‹‰€voxˆŒŠˆ„VVVVTTTRQONLJHGECAA><:87543320//-,++++**********))))))))((((((((''''''''''''&&&%%%$$$###""$#$$$$$$%%%%&'''''((((()))**++,--.-.000022223433555666666666665555556666666666666666443322111111000/0.//.-..-,++++++)))*,--+)%$'-MobUTW]dl_4!$#"! !%*Epn`YY`rU#%"""!     "$(-/2761,-./,)%$""XvmggllmukO3Cahjjhd^L\[5.:@?@@BB>835:@B<4379976567::<><<::78;>CIOQQQONOQTUSQLLKKLLKKMNNNLGDABFOT\acec\[iv‚‰‹ŽŒŠ‡…††ˆŠ‰†ˆˆˆˆ„~jbp{‡‹ˆ„‚€|wqosy|€ƒ†‡„‡‰Œ‹ˆ‡ˆ‡ˆŠŠŠŠŠ‹’’Œˆˆ…‚€xsssrqigjhiicWPQW[ZVTUUOCCTSVY]get¤€™‰…£¯¯¦|WJHIMLLRUQOPPRUWWUQRTOTfˆ¦²¹¼º¸°©¥››ž  ¡Ÿœ™™•‡{v{zzz{{{zy|~‚}}~~}}||ywrqppu}„Š‰…ƒ‡ŠŽ•”’Ž’“Ž‘–š›˜“‰ŠˆŠŒŒ†{rnw…‰Šˆ…UUTTSSSPPNLKIGEDBA@=<;7574331///-,++++**********))))))))((((((((''''''''''&&%%%%%%$$$###""##$$$$$$%%%%&'''''((((())**+++,-....00002222344445666666666666555555666666666666664444332211111100///.//.-..,,++++++*)()+++*(&(+./PndXTWZ^ffC""   !Gwm^VZeq:!##"!     #&-2111,+,-12.*'$#<sjjgikpt_<;ZegjfggaMV_F29E?DCEC<;756>FEA955564332599;;<<;:99<AEJPRTRMLMOPQQMLKKKLLNNOOOOMGDA@BGKRYaec[^o|ˆ‹ŠŒŠ‡……†„…„‚€†††‡ƒ|jcq~ŒŠ†ƒ~ypggmsv{~‚……‰‰Œ‹‹‹ˆ‰‡ˆ‡‡‰‰ŠŒŽŽ‹‡…‚€~vrpppqstqoc]aSEEPWTNHINPMKQQPTSfa`‘”|¥¨©¬ªŸmLHHMNMMNPPSTTSRSTRQQPUnª·»½¿¼ºµ­¨žžŸžž ¤£ŸŸ¡ ™|u{{zz{{yyzy}€{{|}~~}}}}{zwtrrx€‡Šˆƒ„‰Œ‘•“ŒŒŒ‹Œ’“”˜š˜”‹‰‰‰ŠŒŠ„xnmx†‡ˆˆ…TTRRSQPOONLIHFDCA?><;:866532100/-,,+++*)****))))((((((((((((((((''''''&&%%%%%%$$$$$%$#########$$$$%%$%%&'''''()))))**++,,-.-./0101223345554555557766666656665566666655555555444433221111100/..--/.-,--,+++****)((**+-,)'+,.0/HkcVSTX]_fQ/!!#Uzg][^j`%"# "! !! #(*,*++),,-461,(%2lnffjijp]<HgfaabcccWRVI65=;=C??=97532:BDB<543230312589;=>=;:<@DJMPSVURPONNMLKKKLLMNNPQPOOMHFCA@@CHRZaa`fxƒŠ‹‰‰†„„‚„‚|y{„‡…„€{jes‚ŽŒ‡ƒ‚€~vl`_dkosw|‚…‡Š‰‰ŠŠ‰‰‡††ˆ‰‰Š‹ŒŠŒŒŒŒŠŒŒ‡„}|zwtqqqpqqn\9489<DINMKKKMIJFMRRPlljŠ˜‰Œ §¨©¨UFGHJJILLOKKPOMMOPPQOXw™­¸»½¾¾¾¾¼´­¤Ÿ Ÿ¤ œ ¦¥ž—„vz|{zzzzyxy|~€wwy}}|}}}}}||yxtrz‚‰‰†„†ˆ––“ŽŒŒŒŒŒŽ‘”’•˜›™–‹Š‰‰Š‹‹†}uonz‡ˆˆ‡…RRQQPOONMMKHFECBA?=<;976653210/.-,,,++*)****))))((((((((((((((((''''''&&%%%%&&%%$$$$##########$$$$%%$%%&''&&'())))**+++,,-.../0101223345555555557766666656665566666655555555554433221111000/.---..-,++*)))))''*)))*+-,)),,-013Egj]TRSY^dbF$!!!"'fxb[]`nJ""!   !&(*++***--.120,,/cpjedhkn_M`jhdaacb[_[J?47899;<:97565108ABB=6310//012237:;=>>=?DHKMPRTSSQPNMKKKKKLLNPPQTSPOLIFCB@>?@GQU[bm|†ŠŠ‰‡„ƒ‚‚‚}vqu‡…„€{jiv…Šƒ‚€~}xma]`eimqv}„„†‰‰‡‡ˆ‡††††††‡‰Š‹‰ˆ††‡ˆˆ‡‰ˆ„~|{zwvtpqqpqnM)5688<CDJPSOKHKMVZZV^_l„’˜™ž¨ª§¤wDHIIKJILLMJJLKJLMLMMTsœ¯¸¼¼¾¾¾¾¾¼¹³­¤ Ÿš™˜›ž¥¥¡›‹|z}{z}|zzxx{}vsuwz{|}}||||{ywtz‚‰‰†„†ˆ–“‘ŽŒŒ‹‹‘‘“—›š–ŒŠˆ‡‰Œ‰‚yqon{‡ˆˆ‡…QQPPOOMMMKHFECBAA?;;986654320///-,-+,,****))))((((((((((((((''''((''&&&&%%%%%%$$$$$$##########$$$$%%%%$%'''''()))***++,,-,-./01123223455555555445577666666665555555555555544333333111100////...-,,,+,,++****))))())-/0.+*+/3477Bcn^SQSU]cj[1   $$3lrb^[am0 "!""$(*,*,+++./012/,.`oghgijphdjkhe``acb]VH8205768>@<84364107AFDB:430.013454679<>AABEFHKNOOQSRPNLJIIKKMMOPSSUSPNLIFDD@AA>AEKTar„‰‰‰ˆ†„€€€znkv€ˆˆ„€yjjw…Œ‹‡‚€}zvkd_^_ehmsy€…††ˆˆ‡‡„„‡…………………‡†ƒ|}~~‚‚„††~}zywvuutuvkR/.:<>CGKGGHOPQXXV\`aeidm‹—“œ§©¦ mAFJILKJIJIJJJJJJIKJSl–®·¼½¾¾¾¾¾¾¾¾¹µ®¥£¡š™™˜˜££Ÿ•„z~}{{{{yzxxz~sptuww|{|~~~}}{yv{ƒ‰‰…‚‡Œ‘•”‘Ž‹ŠŠ‹Œ’‘‘“–™™•‘Š‰ˆ‰Š‹Œˆuoon{…ˆˆ‡†OONNMMLLLJGFDB@@@=;::76643220///-,++,,****))))((((((((((((((''''((''&&&&%%%%%%$$$$$$##########$$$$%%%%%''''''()))**++,,,,-..001132223455555555555566666666665555555555555544333333111100/.....--,,,+++**))))))(()))-/21/-.147:=>>UjeXSRVX_ihN%  %((;qr]_akb "!!!$(*,,.---./0110,UrfcdhkpnjhgefdaabcdfY51333459AGC94451104>EFA:51/.013566779<>BBCEFJJLLLNOQSOMLIIJJLMPRTTUSOMJHFDCAAA@>?BO[pƒŠŠˆ…‚€~zqhlt‚‡‡†ymlx…‰‰„|{|vkb_\[_`fmu~ˆ‡„††‡‡„„…„……„„……ƒ€{vqpqou|~‚…‚~|{|{{{yxy{wgJ@AFP[^XKMX\]^\Zadefkkc{”‹›§§¥™cCHJIJKJIHHIIJJHHIIOfª·º¾¾½¾¾¾¾¾¾¾¾º¶«§£¡›™™š–—Ÿ¢¢œŽ€{{|{{{zxxy{}nlnqttxy{|}|||{zy{ƒŠˆ„ƒŠŽ••“ŽŽŽŠ‰Š‹Œ‘’“——˜–‘ŒŠ‰‡Š‰Š‹Š„}uoon}†‰‰‡†LLLKKKIIJGDBCA@>>;:87755421000/...,+,,****))))(((((((((())((''''''''&&'&&&&%%%%%$$$$########$$$$$$%%%&''((''()*****++,,---//0012433334455555665555555555666655555555555444333333221110///..--,--**++**)(((''''(((()-1442/236:<BEA>Idm\SQQUZfma9"%',,Htjc``pF! "!%&+-/20..000221LrhbcejppigdddddcefdjbE1255348:DX]93332103:EKF;53.,/13567879;>BCDFFIGJJKLNORRRNKIHHJJMOSTURMKIGDCB@@@A@@?FSiz„‡…‚~}|ujcivƒŠˆ†‚yomy…ˆ†‚~||zufefed^^ait€ˆ‡………††„„„„„…ƒ…ƒ‚€zvmbaees{|}‚€|}€‚€~~yphdehiidW[`a``bcfgjkohbl‹–Ÿ§©¤SCFKKIJIHFGGGHJGGHI]„£²¹¼½¾¾¾¾¾¾¾¾¾¾½¸³­¥Ÿ›š˜–•‘“—™™”…zyzz{zyxxyy~pjllqrtvy|~|z|||z}ƒˆ‡„„Š–”ŽŠ‰Š‹Ž’’”˜š™˜“Œ‹Š‰ˆ‰Œ‹‹‹‡|tnon|ˆ‰‰ˆ‡KKKIJJHHGHFDBA?=<::877663210000.--,+,,****))))(((((((((())((''''''''&&'&&&&%%%%%$$##########$$$$$$%%%&''(())))****++,,,---/00112433334455555665555555555666655555555555444333333221110///.---,,+**))**)(((''''''(()-167524:<>BFJBC@?VkbWQPS[_gn^4$+,-.Oxj__`l4 "$&&)-1232244441IsmfffinphedddddeegddYC7534437;?CLN723322128CHF=830../0156669;<@BDFFGFGHHIMPPQNLKIHHHHJNPSTPMKIGDCA?@@CDCAAHYjt|€€~}|~|wnbbkw„Š‰ˆ„{omy„‡ƒ}z||yulhjhe`^^iv…‹Šˆ„„„„„„„„„„†…ƒ€}woeWNQXmvy{}€~ƒ†‡†ˆˆ‡}wqssqnjdW_a`__`eeghlogcg{•ž¥¥£‡JEKJIHFHGGGGGGGIHFLnš¯¸¼¿¾¾¾¾¾¾¾¾¾¾¾½»´¬¦¡™•‘‰…„‹…{yzyyzzyyz{€qjggnqpsvxz|z{{}{~…ˆ‡ƒ…’•’ŒŠŠ‹Œ”—˜š™—’ŒŠ‰‰ˆ‰‹‹‹‹Š†ytnno}‡‰‰‰ˆIIIIHHGEDDCBB@?><;98866543000//-.--,,+*)))**))((((((''))))))))))((''''&&%%%%%%%%$$$$$$$$$$%%%%$$%%&&%&'())**))*,++,,....///011223344446456666666666666664455545564444433422222221100//...-,,++*)))))''&&''(('&%%&')+16:976>?BHLMJIC?<PbeZRRUX\_inR1)))))SsbZ`j[ "$$&***.024545775=ikhhkklqgdeghhcdeih^G@B332227FD@732121111466:@C<;6..//1234569;<=ACDEFFGEGHILNNMMKIHHGGILNPROLJIGEDC@@@BDDDDEIS`ktxz{{|vqh^`jw„‹ŠŠ†}on{ƒƒƒ|{{{|{skjjhebcn~Š†ƒ‚‚ƒƒƒ‚„…ƒztf^MCDVmswz|~}~‚„‡‹ŒŽŽŠˆtppmmcX\___`abdfgeckgdiu ¤ ‚G?GIKIFFFFFFFHEGFFZˆ¨·¼¾¾¾¾¾¾¾¾¾¾¾¾¾½¹²¬§¤ ˜”‰…‚†‰zyyxxxxzzz{qgehhmoou{|}}{{{z~„ˆ‡ƒŠ’–•‘ŽŒŒŒ‹‹Ž‘•˜™š—“‹Š‰‰ˆ‰Š‹‹‹‡}yrnmn€†‹Œ‹‹GGGGEEEDCCA@@?=<:987755443000//----,,+*)))**))(((((((())))))))))((''''&&%%%%%%%%$$$$$$$$$$%%%%$$%%&&%&'())**))*,+,,-....//011122334444566666666666666644445554334544443334222222100//..---,++*))))((''&&&&''&&%%&'(*/7<=;8<BHJLLJIED?=GXje[XXXY[bhfR*"()(Ztd]blL&$&**+-0378:;987fjgikjophcfggghfgilWA?B7353337CKE731///0124699799951.././025789;<>ABCEEEEEDGGHHIIHHFFGGGJOQROLJHFEDC@@@@CEEEEGHP[dmty{wqfb^_ky†‹‰‹…{oo{€€|{{{{}}ypoljiffq‰…‚€€‚ƒƒƒ…„‚}ztgZTKHPctvvy{}~‚„‡‹ŽŽŽ‹‰wponj[_`a``cacefgc^efhnq†šŸF@FGHGHEEEEEFEEDFOtž²º½¾¾¾¾¾¾¾¾¾¾¾¾¾½¹²¬§£Ÿ˜“Š…„…†‹‹„{yyyyyyyywy}rgeggjnnsvyz|{{{z…ˆ‡…”•“ŽŒŒŒŒ‹‹Ž“–˜—•‘ŠŠŠ‰‰ˆ‰ŠŒŒ‰†|xpmls‚ŠŽŽŽŽEEEEDDBA@@A@><;::876745422100/...-,,,,+*******))))))))******))))((''((&&&&%%&&%%%%$$%%%%%%%%%%%%&&''''()))*****,,,+,././/111111233443444555555556655554345555334443333332333111111//....-,++**)()(('''&%'%&&&&%%%%&*19?BB==FKKLJJHEB??A;I`jdYYYWY]`kgA&&&(bvdbdj:!(+*,--145688?jkgiigltkdfghhiill_H:BE>3153016A[R520/..01348<:966642-,---/04798;==?AABBCCDCCCCCCCDEDEFFGGJKNQLIGFEECA@?@CDGGFFIGMV_gosqgSX_bn{ˆŠ‰‰„|qp{~|{yxyy}}tonnkilv…’‡ƒ~€€‚ƒƒ‚‚€~ysha[WQQZhsuwxz}€‚„‡ŠŽŽ‰wpljb]`abbbacdfgd^Ydfemrz‘šžšx@BFEDHGGECDFDDCEJd’¬¸º½¾¾¾¾¾¾¾¾¾¾¾¾½¼¶²¬§¢›–‡„‚ƒ…‰‡}{{zzyxxwvw}sddgefkloswx{{{{z‡ˆ†ˆ””’‹‹‹‹”–—”“‰‰ˆˆ†‡†ŠŒŒ‹†€{yutw~ˆŽ‘‘BBBBBBAA@@@?<;::9765554322210/...-**+++*******))))))))******))))))((((&&&&%%&&%%%%$$%%%%%%%%%%%%&&''''))))*****,,,,,//.//111111134443455555555556655554445554334443333222233211110/..-.-,,+**)((((('&&%%%$%%%%%%&'(+/:BGHC=FNOPNJJEB?=<:69Mhi]XVTUY]ciV2!$,`vccbg1"*,0321378<8=iqjhjhiolfgjjgjnn[B9:?DI;3442016?PI30////276769<<9853/++,,--/159:;==>@@@@>?A@??=>>@?AACDDDDEHJJIHFDEECA@?@CDEFGFHGGJOX`fcVIO^en|‰Š‹Š…|pqz}~}yyzzz|€wtqonlnyˆ’†~~€ƒ„ƒ‚€~{xriea[WW]isuwwz}„…ˆŒŽŽŽ‰‚xpgc``abccccdfffa]]hhhkru€•ž›u<BEFIGFGDCDECCBEWƒ¥´»½½¾¾¾¾¾¾¾¾¾¾¾¾¾º¶²®©¢™–‘ˆ„‚~}{~…~{{zz{zxwvw}wgefgejlopsuy{{}|‡‡…Š’””’‹‹‹‹’”––‘Œ‰‰‰‰ˆ†‡‡ŠŒ‹‰ƒ€ƒ‡‰Œ‘“‘@@AA@@??=>><::998744343322110/..++,+,++)))******++****++++++******('(('&&&&&&&&&&&%%%&&&%%%%%%&&&&&&''')******++,---.///0011202224445566666655555555555545543333333333222122111000..----,+**)))((('&&%%%&%$$$$$%$&&*.8ELPIDGRTVRMIDA><<992.8VebWUSVX\^ggK+'craeh]'*,27=CKLI@IjsmjmiipnfhiikngZL;9:=?@;642200467;71/11/037:97:@A=:53/++,----/2669;;<?=;;:;=><;;=>>??@ACCBADFFGGFDCBB@?@?@BCCDDEEEFEGJQUQJEGWfs~ˆˆˆ‡ƒympw{}{zyyyz|€„~wqqoor}‹“Œ…€z{z~ƒ…ƒ‚~|}}}|uqmida`cbisvww{|ƒ„†ˆ‹ŽŽŽŠ‚ypebbcdccccccfdcc]^ijjmrstŒ›˜r>AEDECCEDDDEDBDKm™®¶º½¾¾¾¾¾¾¾¾¾¾¾¾¾¾º¸µ®« •‘ŽŒŠ…ƒ~zy~~{zzzyxxwvu|zhehgdejnnqtvy|}|ˆ††Ž’‘“ŽŒŒ‹‹ŒŒ“–”‘Œˆ‹‹Œ‹‡ˆŠ‹‰…„††‡‰‹‘‘”““@@@@????<<;:99887666533322110/..,+++++*)))******++****++++++****))*((('&&&&&&&&&&&&&&&&&%%%%&&'''''''()*))++++,,,--..//0001111222344556666665555555555553454333333333322122211100/.--,-,++*))(((('&&&%$$&&$$%&$#$$&)-8EOTRMKSXVSOKGC?;:732/.,=XgaYTSVX[`gbB&$^oaeeV:85=@ILQXcrrlmljkppjiklojSEFGHCABA>84420//36763.-.11149=;7;BD@=71/+,,----/14678:;=:889<<<;;;:::===>?ABCCDDEDCA@@@AA??@@AABBBBDCDDCDEFDEEShuƒ‡†‡…€tmqxxzzzyyyz{|‰ŒxurqqwŒ’‹…€{zy{~‚„ƒ‚~ywxzyzwxpnlmmlhmtwwx{}‚…††‡ˆ‹Š‡unjfbfeddcccccdb`_floljpxyŽ“oCBGDEDACDDDEDBCW…¦³·¼¾¾¾¾¾¾¾¾¾¾¾¾¾¾½½¹¸²« ™•–•”‘ŽŠ…~vuyyyzzyxwwuvyzgeedefiklnrvy}}|„ˆ†ˆ“’‘‘ŒŒ‹‹ŒŒ‘’‘ŒˆˆŠ‘––’Ž‹Š‹ŠˆŒ’’’‘’‘“‘‘’’????>>==>;;;9788767643321100.-..++++*+++********++****,,,,,,,,+**,+(**((&&''''''''''''((''&%&'''(()))))***+,,,....../0/00010022223445555666655665566554444443333332122221101000/..--,,+++*))((('''&&&%$$$&$#####$#$&+6ALVZVQSXYXTNKHD?<8310./,,Dah^VTTTX_chcE,^i]chP+7<ET]djosjjlmmppllmmgP<BMQOHILIA:5432.-055540/,+253389989@DCB<51---,,.//134468898777;::98989::9;=<=@ABDABBB@?@@>>????@@AAAAABBBCCCBBBETiv€‚‚{oiovvwxxxyzuuv‡’€yvtrx‚ŒŠƒ{xxx|‚„…ƒxpptwuwvusrsutqlktwxx{…†…†‡ˆˆ…}uspkfcefffdccbc`[]cgkqnoru{‰ˆpFCCEEEBABCDEFCJj—¬µ»¼¾¿¾¾¾¾¾¾¾¾¾¾¾¾¾¾½»¹³¨£¢  ¡œ–“Œvuwxyzzywwwvxz}heecfdghknrvy}{}…††‰”“’ŽŒŒ‹‹‹’‘ŽŒŠˆˆ‹–›š—•‘Ž‘“•–”““’’’‘‘’‘’<<<<<<;;<9888755656532211100.---++++************++***+,,,,,,,,,,+**)((((''''''''''''''((''''''''(()))))*+++,,,.../../0000010022223445555666655665566554444443333332122111100000/.--,,++***)(('''''&%%%$$$$$$#####$$%)0:FQYXQQXYXXSOLHD?;752/.-/*1HeiYSSVXY\dibVjqcdbJ8K_eggntlhjlmppkml]=-5I[]TOMEGG=74230/,0:=621.--03668::89>AEB@93/--,,-.0222455567778989:988888889;;=?@ABBBB?>??>>>>>>?@@AAA???@AAB@BAJ[ky{{|}yrkipttvwwwyxrgl€“zxvsy‚ŒŽˆƒ|yyy|ƒ…†„xoimmopsvvuuwvutpmrwz{„……††‡‡„ytpnijgffecccca]Z]cgmuuuomp†ˆpLDDDEDACCCDDEFV€£²¸»½¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¼»¸¶µ±ª¦£›”Žƒzuwxyzzywwwwwz}hedcdeghimqtz|{}„…†‰“”“’ŽŽŒŒ‹‹‹ŠŠˆˆ‹˜œ™˜–•–––———•”““““’’’‘Œ<<;;;;::998876776655211100..-,++**************++**++--,,------,,,+****))((('''((((((((((((''(((())))))*+,,+,----..////00011102222344445556665555555555444444333311110000000////.--,-,++***))(('''&&%$#$$##"#""""###$&-6CMSTPNUZ[[YTMIGB?<732/+,,,+3Ui_ZWWWYYZbjqutponligeblrjhgjnqrnj\>")3G]_ZRMB8EE;5220/./7HL<31//..3789;867<BFCA<71/-,,-/1324435555666668777799887788;=>?@@???>?>=<====>?@AAA@@>>>@@?BIWcrzwvzyqj^blqsuuvwwwqcWn˜‚}yx{„Œ‹†‚}zz{|€„…ˆ‡ƒ|sb_dghlnpsuxxvtstttuz~ƒ„………‡‡‡ƒ{wxusoigfedcbb_^Z^fmtwvupliv†pQGFFFDCBCDEEAJd’ª´¹½½½¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾»°«¦Ž„zuwyzyyywwwvwz}lccdddfhjmrs{z|~…††‹“–’‘ŽŒ‹‹‹‘Ž‹ŠŠ‹Ž”—œššš˜š™™—˜—–•”““”••’“‡::::;;::99776666554431110/..-,++,,************++**++----......,,++++++)))((((())))))))))))))(((())))))*+,,,,------////000111022223444455566655555555555444443333111100000////....-,+++***))(('''&&%%$$####""!!""""!#$)3>GLIFIOY\^]XQNLGC?:74/+*)+(*+<Ye_UZUVWZaefjjjgefb`jspihkntwo\8'-6/Ifg`]WO76JC851///..2:9421.0111567;857=BEEC=82.+,,-/024543444445554566779988777788;<==??>===<<====>?AAAA??>?>>?AIT_mwvtvupeXOUafkoqtuywn[;2m–‹}{~„Œ‹†‚}zz|‚†‡ˆ‡†‚xiYY]`dfglrvwwvvuutwz|‚ƒƒ„……†ƒ~zyzuromgddcb__^]ajsywvupmko~YDGFEBBBCDEEANs›¬¶¹¼½¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾½¾¾¾¾½µ¬ xnpsuwwyyyywwwvwz}kccbddfhjmqtz||~„…‡““’‘ŽŒ‹‹‹Ž‘‹Š‹Ž’“•–šš›™ššš™™˜—–••““’‘‘ŽŠ…€{99:::9::8888666644442011/..--,++****)))***+++,,+++,,--........-,+,+*++))**)))))()'((((((**))))(((()*++++,,--..--..//0000001101222233334555666655554455333444222211110.//00//--...-,++**)))((''&&&%%$#"##""""!!!!!!""#'09CEA?BMWZ__^WUPKGC?90('('&&&'#*C[_YWSRUWY\`bccdcclwqiglptyh?!#((9Neidcc[L42A9420//.,-/1/011/15412579888=EGFD@;50,++../1344433333344456677667755557788:;>>=<<<<<<==<?@@@AA@@><==AES_isvrrqldUB>FPX\bgmstthYVLfŽ†€‚‡ŒŠ†‚~~}„‡ˆ‰‡‰ˆq_QSUZ]`fjrttuuwvvyyz}‚„„„„ƒƒ~||zuupkhfda_][\eipsussnjigr|cGFFFDBCCDCDBR~ ­¶º½½¾¿¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾½½¾¾¾¾½µ¥Žscdeinsxyzzyxwvwwy~ncbbdfegjlou{|}‚…ˆ•”“ŽŒ‹‰‰Ž‹Š‹Ž’•—™™šœ›šš™šš˜˜––”’’Œˆ…€yumd99::99998888655532222000...--,++))++**)*+++++,,+,,,,---........,--,+,,+*++***)))*(**))))**))**))))*+++++,,--..--..//0000001112332222333455444455554444333444222211110.//....----++++**)))((''&&&%%$$##""!!!!!!!!!!""#'-8BGD>BHPW]`_^\ZTNKE?.'&&%((('&$$(@]bTOTWWZ^_acedluspkorvxe;%&(&'=]iiec_UI,+86310/.-*+,./00002672236::89>BDEEA<61,++...0133333222244444456466655555677:;<==9::;;;<=<?@?@??C@>==?GRZgrtqtrkcU>029?DIQZ`fmnh_ehr‚‘‹„‚‚ŠŽŠ†„‚€€„‡ˆˆŠˆˆŠ…zmVMOPTW]dkpqsttvwxyz|}}~€€‚„„„‚}|yttnjgc`^^\ajpppqqqmihfiroPLJJEBBBBABEU…£°·»½½¾¿¾¾¾¾¾¾¾¾¾¾¾¾¾¾½¼¼¼¾½¼¹©ˆhY_dehhkqxyyyywvvvy~sfccgiijlnqv|}~€‚…‰Ž’‘’ŽŒ‹‰‰Ž‹ŠŠŽ‘”˜™›››™™˜˜–————–•“‰ƒ~ztldYQP8899997788875555322220/....--,++++++***++++++,----............--..-+,,,++++*))****))****+)***+*(*++,++++,,--..--..//0000/1111222223322333345445555334433453222220011/././....-,,,++**))((((&&&%%&%$##"""!!!!!!!!! !"#&+4AFFDGIOUZ_bca_\WSM>.))%$$$&(*((($*G]]UY]`acchhmsplkmqswkN4,+&'*C^ibWRYSJ-(76000/--*,0/11121389757:<><;;@CEEB?;50,+,,-.0112332200223344444444554234679;<;978888:;<>==??BBBA?<>CP[fqussng_R@2//0369@FOW_b`[^V]tŽ†„„‡‹‰……„„„„„†‡ˆˆ‰ˆˆˆŠ†ylVJHJLR[gnnoprtwyxx{}~~~€ƒ‚ƒ€~{xvrnjd`^[]ehjmpqonligddfkWTPICBABBBAEX‡¤°¶º¼¼¾¾¾¾¾¾¾¾¾¾¾¾¾¾½¼»ºº½½»·­…\PW]`dghijrwxxxvvwx|€yqprssssttw}~‚†Š‘’‘ŽŒŒ‹ŠŠ‹Š‹“—˜˜š™š™˜•”’‘‘ŽŒˆ€wpg`XNGDHN8888887788755555322220/....--,++++++***++++++,----......//////....-.,,,,,+++**++++**++**+,***+++*++,++++,,--..--..//000000111222223322333333443333554433330002220000../....---,+++**))(')&'&&%%%$$##""!!       !!  !#&+4?HJJKNPSZ_eeffb^XM4)+(&$%'&&+-..+&%*:KWgljkmnkurmmosuwlSI52<=12LcdZSLMMG0%65/00.---/201212369=;988;<==>@?@B@?=92.,,,-.0112332210113344443333444233568:;989888879:;;;<=@ABA?=@NYcopqsoh\N<.-,-/00047:CINPWYRZi‹†……‡ˆ†…ƒƒ‚‚ƒƒ†‡ŠŠŠ‰ˆ‡‰Š‡~o[HDEHQcikkmprxywwy{{{|}}~~‚ƒ‚}{yurnje[PT\efgnonnligddb`XRPFDBBAAABDXˆ¥±·¹¼¾½¾¾¾¾¾¾¾¾¾¾¾¾¾¼º¸·»»½¹±•\EPY\^bfgihltxyyzz|‚…‚‚‚‚€~~~~€‚‚†ŒŽ‘ŒŒ‹ŠŠŒŒ’–——˜˜™™—•“ŒŠˆ†„ysg_VNEEFJLPS88777777765555553222200///.--,,,,,++++*,,,,,,,..--//....00////......--..,,,,+++*++++****,,++++,,**,,,,+-,,--..--..//000000011112222222343333333333333333320.0111000/......--,,+++**))(&&''&&%%$$$##""!!!  !!  !!  !"%+3=EILOQQT[`fkjfdc[H1,/,()))')*,,-/.01128AQX`cfrroortuteQPO;;HOJO[`XURKKOF1$3500/-.-16855324469?>=;;<@@BA><?B@@=;4/----/1122222222222244321122332121156775677777888899::<=?@=@HWanqqrog\P>0.-,--//011248<BHIKPXj~|y|~€€€‚††‡‰‰Š‹‰‡†‰‹Œ‰s\HBCJ[cffhmryywwyzzzzz{|~~~{zwusole_ahd_dmoonlhfbaa_[NNHFCBBBB>DY‰¦°·¹»½½¾¾¾¾¾¾¾¾¾¾¾¾¼»¹¶µ·º»¹­‚FEOV\^`ddgiiow{{|…‡‡ŠŠ‹‹ŠŠ‰‡†„„††…„ƒƒ‡ŒŽ‘ŽŒŒŒŒŠ‰‹‘”•—–•–——–”Ž‰…}xuqncVLFBA@CHMMPT77777768765555553222200///.---,,,,++*)*,++,,--....--..//00////..----....----,+++,,**++++,,++++,,,,,,,,+--,--..--..//00000001110122222233333333332233333333210011//......----++++))))(''&'&&%%$$$##""!!    !!  !!  !#(.6>EIKPSTW_djnliebV>.-,***--(**,,,**-.0110..((drllkhim`ILNPDCNRQY^ZY][UUTR<'/6830.--17=<:63335;@AACA?@BBA<:<>==<:51.---/11112222222222331111113321//112443345555667799::<=>?>FP]krnolf\N=0.,,,,-////00101359;>AK`f`dhkpqsvz}ƒ……‡‰‰‹‰‰†„‡ŠŒŒ„vcG?HWcfdekpzyvwyz{yxxxz{|}~}|€|zvsrooplknkkoooljhfbab`\KLOGCBBBBABV„£®¶¹¼½¾¾¾¾¾¾¾¾¾¾¾¾¾¼º¸³¯µ»»·§pHLQY\^bdgjjjms{„‡‹ŽŽ‹ˆ‡‡‡‡††…„ˆŒŽŽŽŽŒŒŒŒŠ‰‹‘“”“•““”“ŽŒ†uld`ZOE@<=>A@CHLNOR77777777665544333222201000/...-,------............11110000000000--..-.0...--..----,,,,,,,,--,,,,,,,,--,.....-...000000000.11110022221111345433222222221111110.00--------,,+,++****))((((&%&%%%$$##! !!           "$*08@EHKPSVZbfkonie^O0*)))**-1,,,,--*%#$',0016.Zvjjkolh\UJIJIEKROX]a`aaZX_^ZK/)4A@5.-0:ACB<64469;?CDEHDBABC<78999:8840--,.00111122112222221000002211//01001122444466668989;===@JVdnlnje[M;3/,+,,--..//00//00221236@EEIMSU[achotyz€†…ˆ‰†„……‡Š‡yeIGVdeacisyyvvyyzywtqvwz|}}}~}}{yvsrnnoonmlmnjggebaab]OKSPDBDCBCDRw›®¶º¼½¼½½½¾¾¾¾¾¾¿¿¼»»µ«­´¸·®šo_cdddgjjkmnnry}…‡‰‘‘ŽŒ‹†‡†……†„…‰‹Œ‹‹Œ‹ŠŒŽŒ‘‘“Œ‰…€vkaUME>98:;<>@@DFILLL77777777665544333222201000/.....------....,,...../11110000000000/...-.0.......----,,,,,,,,--,,,,,,------....-...000000000.//00//11111111233133222222221111111/00....----,,+,+**)**))((((''%%$$$###!!!!          !$',4=CFGHKQUZafhlkieZB-(*++**((++++,,,'#"%%),2;Zulikjke[MLEGE95JPQW`_[__ZZ[_VS:+/DM9//3@DEE@99:88<>?BDHID??::7555589983.-,.00111122112200000000000011///1001111233444566879899:ANYhmmje\N>520.+,,--..//00//00221220/04468<@GHNV\diouy}€‚‚ƒƒ„‡‹Œ‡|hSX_dbdowxwvvyywvpnnotwz{}}~~~}|zyvtrqqpnnmljfdbaa`a`VMMPHCCCCBDKo—¬¶¹¼½¼¼¼¼½½½½¼¼»»¸·±­¦¦«¯®¤—€xzwwvvwwwvyy}}€ƒ…ˆ‹‘’‘’’‘‘ŽŒ‰‡†…„„„„„ˆŒŒŒŒŒŒ‹‹Œ‹‰ŠŒŒŽ’‘ŽŽŒ†…}xngZOE>;:7879<=?@ADFGJJJ77777766665544333222310/00/...----..-------/..//0000000000111100000000//00////..------,,,,,,----....../-..--..//00//////////00//00001122211212222211100000000000//..----,+++**)))))('''''&%$$#""!!""!!        !#)/6>EFFFINUY`ehjiigW7.-,-)**))((((*++)(''%&*(IpjjfgecPAKMIDB@@FNXbd\Zb_WQR\YOD:36=2./08?EFB;>@:889:;?HKF?:75654467;;852/--//0011112222////0000////00//./0011112222123466777759CP^hjhf]P?6421.,,,,,./....//00110222000/0//0026<CIOU\bjnrvx{}~ƒˆŠ€qeabfnvwxvuuutrmhggjmswyz|~~}~~|ywuvstrppomifdda___a[KIJLIECD@AGm•©²¹ºº¼¼ºº¹¸µ³±°®«¨¦£¡Ÿ ¤£ ™”‹ŠŠˆˆ†……„ƒ‚€‚‚……‡‰‹Ž‘’’’’‘ŽŒ‰‡‡ƒ‚‚ƒƒƒ†‰‰‹‹ŒŒŒŒŒ‹Š‰ŠŒŠŒ‹‹…€{vqiaZMC=<===<:989<???CDDDDDD77777766666554333222310/000///..--..-------/00//0000000000110000000000//00////..------,,,,,,,,--....../.......////////////0000//0000112221021122111110000000////....----+++**))))))(''''&&$$##""!!""!!        !&)/6>DGGHGKPX]`ddeebI-++)+'))))(((((***))'&&'>hfgfgdcN@DMML><JNIW_c__`d`TTZ]aOGB;48879114<CCBB?:99778;FLME=74435567:<><830-//00001122220///////////..//./0011111101111233444448DQ^ggd_UC54410/-,,,,--,,..../011022211100.-..,../37<@GMSY^dhlpsx€…ˆ‡€sghqy|{xwwvqlgd\TV`gmrwxz}~}~}|}{yxvutsrqomjfba___`]PHJIHDACCGQj£­°±±±±­¬ª©§¤¤¡Ÿžœ›šœœšš™˜•’‘‘ŽŒŠˆ†„ƒ…„ƒ……‡‰‹Ž‘’’’’‘Šˆ‡ƒ‚‚‚‚‚…ˆˆ‰ŠŒŒŒŒ‰ˆ‰†‡‡…‚‚}ypjcZOGB;9;;;<==<<:9:=?A@CDDCCAA887766776666553332222210110/////------........////000000111100000000//////////..------,,----,+--......./////................////00001122221121110000//000///..--....---,++*****)))('''(&%$$#$##"""!!!!      #%)/6?FHHHHKOTY[^_b`W9'*)'((((()(((()+++*(),$Cl`bbdceP;B<:KG>=EDSda]]ab_c^ab`bTHDHVJ>BG9,05;?BGB:766336AJMGB:53355679>?A>:51..//0011235510////00..////////0000000000000011222238CQ^cb`XJ;4430///-,,,,,,,--//0111111121000/.-----..--.13;?DHLRW^dipuwwrlmsxwwyvspja]XMHQZ]dmrrw}~~~~~}~}|{ywvutusplhfa_``__[NLJEEHPV^jv ¤¦¦¦¤£  Ÿžœ››™—–˜˜˜˜˜˜——––•“’’ŽŒŠˆ†ƒ„‚ƒ††‡‰Ž’““’’‘ŽŠ‡ƒ‚‚‚‚„††ˆˆ‰‰ŠŠ‡~|zvrnia\ULF>;:9:89;<<==<<;:<>>BBABC@@@?777777776666553332222210000/////------......//////000000111100000000000000////..------,,--------.......///////..............////00001111221111110000//000///..--..--,,,*+*,+**))))''''&%$$####""""!!       !#%)/4<BGHIIIPUVWZYZWF-''''((((((((((++,,,)&&=md[[afhS>@;76@F=556Pcccddda_`debcXLDGJA;@A:1.028ADE?634012:BEFB;7445579;=?AA>:51/0011112344420/////...////////////0////00////////16AMZa]ZRE9121////..,,,,,,--//0111111121120/..-,-----./../0036:>DIMSV[^^^afjklljgd]UQMMOIEQ^fjmpu{€||||}}{yyvvttqmjhecaa```TLNQX_ks|‚”›žžŸŸœ›œ›™™™˜™˜——–––••”““‘ŽŽŒ‹ŠŠ‰‡†ƒƒ‚‚‚ƒƒ„‡‰Ž’’’’‘Šˆ…ƒ‚‚‚‚‚„„†‡‡‡„‚}wmfdaYQKHA<;;;;;:;<<;<<==<<:;<=??BBBB@@?@776678776655442211223310////////--....//..////..00000011111111111111111100////....--------------....////////................/////0//0000221111000000//00/....-..--,,++++++**)(*(''''&&%$###"#""!!!!     !"%()-3;ADFHJLORSUUSM?4)''''))(((())))++-++)*0ll`_adfV8AD<239@DBKEI_baffbc_cddgeguK@>?=>@A90/.7EED@821.-/29@BB?;6543368:<?BB?:62011001234452200//..../......--..////////......../3>IW[VSLA70///...--,,,,,-.../1000001111100/.-.-,---..0..//0/00/1568<>ACEHMPTVVXUSNECCFKF?DR[aflov}€||}||}|{yxwwsqomjgebcacb\_kq{ƒŠ’˜›››œœ›››››™™˜—••••””’ŽŽ‹‹‹‰ˆ†…‚€‚‚…‡‡‹ŒŽ‘’’‘ŽŒŠ†„ƒ‚‚‚ƒ„…‚ƒ‚wl_UJE@?A?B@:<<;<;<<<<<<=<<=:9<<==?BCCB@BD776678776655443322223100//00////......////////..00000011111111111111111100////....--------------....////////................/////0//0000111111000000//00/....-,,,,+++++++***((*'''''&%%$#"""""""!!!      "#&),04<ADFGJLNPRRSOG7-'''('))(((())))++*,+(,ekhhfcgW7AHG8-/7:=>D?Peegjecddb_aebfdGBBDEEEE>3/.279AE>3/.-./29>A?976645578;>@@@>:611100123444422210/....--....----.................1<FSVRNI@6-,,,-..--,,,,,-.../10////0011100/.-..--.//.0///000////./0../10468=>?BAA>;;;>BB>?ENSZbenu}~}}|}~|{yxyyvtqonkjgilrvx|‚‹’–š™šœœœ›››››››š™™šš˜—””””””Œ‰‰ˆŠŽŽŒŠˆ‡„‚€€€€~‚„ˆŠ‹Œ‘‘Ž‹‡…„‚ƒ„„€zri^TJC?@@?BA=<<;<<<<;=<<<;;;<;<<==@CDDEEFF66776866775554332222210/..///////0////....////////0000111111111111111111//.////...--,,-------------.00//////..........------....///////////000000000/////....-,,,,++++++**)())((''&&&%%%$##""!""!!!!     !$&+.27?BHIIJLNOPQQMH:,'&&&'()((((**))*))*,-]legdbfV,<FRQJ=337;55:Rfqnme^abc_]af[ROKKJHJIHB80/125@GD:1-----16<;;755544568==>?@=97321011244554444410...--...-------..//..--..----,09BMUPLF?5-,,,,,,,,,,++,-...///00000011110///......////0000000000........./0/001111367:;;==AGKPW_hry~€}|}~}|{{{zvvtsqonotz‚ˆ•——™™››››››š››ššš˜š—˜——˜˜–‹’’’‘‰…ƒ…’”””•”“’ŽŒˆ†ƒ€€}†ˆŠŒŽŽŽ‹Š†„ƒƒ‚ƒ‚‚~{tmia\PB@@?B@><<<==;;;;;;<;<:<=???@BEFFGGHG77776866776554332222210/////////-/////....////////0000111111111111111110///./.....--,,-------------.00//////..........------....///////////000000000/////....-,,,,++++++**('))((''&&%%%$$##""!""!!!!    !"#&(,039AFIIIJLNOPPNID4('&&&'((((')))*(((()-[ndge`h[-2>GTYXQF8:<98?^ltrlhje^`aaff\SROLNONLLH?3/237=CF?4/---,-/477765554679<=>@A?<9621011234555577522///.-...-------......--..-----.7AJROJF?5-******++++++,-...///00000011110000////..////0000000000..--........../////13366778;<?ENYcnw}€~€~}|zy{{zywuvw†Š“–˜——™™š››››™˜˜˜–”’Ž‹‰‰ˆˆ‰Š‹„€†‹Ž‰rrz‚’™››››š–“‹ˆ„‚€€€~‚…‡ˆ‰ŠŠŠ‹‹‰ˆˆ…ƒƒ‚ƒ‚‚‚|xsoh`QB=<><;;<<<<;;;;;;;=>??@BBBCEGGGHHHG88777766665544322222211000///000//////..////....////0001111111110/./1100///.--.,--,,,,----,,,,,,....////////........--...--.........///.//000000000000///....---,,++,,+**)''''(('&&%%%$$#""!"!!!  ""       #%(),15<CIJIHIJKNMLLE?.'&%&'((('')()(((()*(Qmcedac]./7=FPWXYM729:?<\trrpcYa^[`fhe]WSQQRQPNLJC933/18=CA81-**+*,.135445678879<>@A>=:7520/1213455689643100.-...,,,,,++,,-----,,,----,,5@FQNIE@7.(())))****,,--..--..////0000111000//////////00000000000/...-..--.../////0001222344556;IWcmx„€}€~zyxz{{{{|€‡‹Ž’“•••–—™™šš™š˜”‘Š†|uolhffkmpqs{‚„‚thnz‹˜Ÿž ž  š™”‘Œ‰…€|z{{}€…†ˆ‰ˆˆ‰‰‰‰††ƒ‚ƒƒ‚‚€€€€€}wsh]M@?<;::;;<<;;:;;;>@@AABCDFFFHGGGFFF6677996666554432222221100////010//////..//////....//0000111111110/./00//.-..---,--,,,-----,,,,,,....////..///.....------.--.............//000000000000///....---,,+++++*)'''''&&&&&%%$$$#""!"!!!  !!    !#%(++.37>EJJHEDFGIKJGC;+&&&''())'')('((()+%Oibde`ea0,38=GNUYXP4/9AEHlttto`X`[Z_chg`YVTTQPPQPLGA:53127=@:2,***)**-012357888779<>??>=:752112133467876542000/..-,,,,,++++,,,,-,,,++,,--1<ENMHE@94*())))**))+++,++--..////00001111110/////////00000000000/....--..///000//00011223443333:GVblv}}~~{vsvz~‚‡Š””“•––——•’‹…wpic[UPMHHMQ`]_dnsqlgs…–Ÿ£¢¡¡¡¡Ÿ›‘Œ‡„}ytrssx{~€‚ƒ†‡……††††ƒƒƒ‚€€€€~~~~‚ƒ‚yqj]L@===<;;:<<<;<>>ACCDDEFGGGGGFFEEEE7777666655554432222210000000//0///////-///////...../0000111111000///.......-------,,,,,,+,,,,,,,--..////00////....,.....----..........,-..//////0000/////....---,,++++*(((''''%%&&%%$$$##""!!!!!        %'*+,049@FIIHEBBFGGFE?5)&&&''((((''(()****Tm`bea`c1*566=DIPWXT>==><KlpstUV`cabeeegc]YXWSPPQQMLF>81/138<<3,+*)))*,/13589:9:7778:>@AA@=:642012334567535422110..---,,++++++,,++,,++**)).8>FKGDA:5.''(''&((())))()++--./../0010001221111//////////00//11//..--.......///1/00/1112344442249CS`ksyƒ€}|wqotx}ƒƒ…†ˆ‰‰ŽŽŽŽŒ†~woh`XSNLFCDDDEM]XROTZ_gn”ž ŸŸžŸž›–‘Œ†€|toiddeimsw|~€„„„„„ƒ‚‚‚€}~~~}~~€„€~zrgZF><;;<<><>>?ABCEFGGFFFFFFFFEEECCD6677776655554432220000000000///.//////-///0000......///001////00////.....---,,,++++++++++,,,,,,,--..////00////.....-....----........,,-...//////0000/////....---,,++**)(((''''&%&%%%$$###""!!!!!       "$',-/39<@FIIGB??BEFEA=/(&&&&&''''''())*+._kaab_dd5&29;>>BJOPPI>;<ACTmqrne[Ycaekmkhe^][YVRPSROMJE=30/24993,+*))))+.01489:;<97779=@BBA=::6520013345655555432110/////--,+++,,,,,,++**)),2:@HHC@<6/('''''''())))()**++,--.../100001111110/////////00//00//..---------.112311111123555522247CQ^ipz€€€}|zvpoquy}€€‚‚€}}}~{ri\TLIIKLONLJHHIKQQOKIKT_o†’’““’’Œˆ{sme`\YVVX[beipsv{~€€€~~|{{|}}||~~€ƒ|wodWF===@AA?@@ACFGFFGGGGFFFFFFEEEFCC6666665544554432210000////000010//////.---............//////////..--------,,,+++++++**,,++,,,,,,--....////////....-,-...----........---/...///////////../...-,,,,,++)))(''''''&&%%%$$####""!! !!   "$%),.27;@CHHGFA>>BCECB:,'%%&&''((()')(*)3el^`_]`j?"/4:<@B@CHJJ?8;A@<Zqqsomi]eghlppida^^\WSPQPONKGC:3005473.+*))((*,-045789:86777:=ABB><;:752111224567797553442213330/.,,,----++**+)))*-6<DJA?:51*'&'''%%''&%&''(****+++./..001111221110//....////00..00-----------04455322012456766333347?NZeov|€€~{zxunkloux{||zzyxtsqnmlg^VNJJIIKMLNNJGGHJLKHFGKNZm{}|{}yzvqjb[UMGDBEGOUY^_deilqtyxy}~}|{{{zz{{|}||{|}€|tkbUI@AABCCDEEFFFGGGGFGHHGGFFFFFFGG6666665544555422210000////000010//////.---............/////////...------,,,,+++*****++,,++,,,,,,--..//////////...-----------........---....//////////////...-,,,,,++)))(''''''&&%%$$$##"#""!!        !#%(+/38<BEGIHFCA>>ABDB?7)'%%&&''((((**+':ki^__]boG -238:DGKFEHG=>Qd[DOjlmgjiegkmpqnief`\ZWTQOMLLKGF>7114363.-+))(()*+-13379:766677:=>>><<;975211123435579:76753333330/....--,,++*****)(+19@FC>:53.(''''%%%%%&%%%&')))*)*,,-..011112222210/....////..//..----------.156884320235677883333246?JYcmux~€}{yvrmjkorv{||zxwusqniida\XRPNKKKKJIFCCDFECCB@ADOZ[YYYYYVQNFA=98779?EJRV\___aceimpqvz}~|{zzzz{{{|||{{|~€yskaWKCDEEEDDEEEEEEFFEFFFFFFFEEGFGE6654556644333322102211000///////000.......-.//..----/.........----,,------,,+*******))*+,,,,----+,--..//00..........--,-----------..............///...///.------++++)))(''&&&&&&$$%%$#$$#"!!     #$(+-18<DGJLLJGB?ABCEFB=2&('&&&''''(')))Gog`[^abjU!.:<==;EGXOLJHB=EOWWXdjhgiiabiqrojchhd_]ZVTQLIKIFDA:614675/,,++))))*,-015988855569:;<>===;97543002222568997995442101100///.++-*****))()-5;@C>;73/,)%$&&%%%$%%%%%&''''()**,---./012322220000.0///.--..--,,,,,,**--/1468534422345896666521134=IV`irv}€~zyvrljfkotx|{}{zzwusqmie_[XTQMLJGEB@?=@>><<;;==?????><<9:::89::9:<BHMSX[^`^]_^behlpux}~|yyyxxzz{y{{|{||~|ytldZMFFDFFEECCCCCEEEEDEEFGFHHGFHF4433332233323311211100///.......//......-.--..--,,,,,---/-----,,,,,,----++,,+*))))***)*+,,,,,,,,+,--..////..........--,-----------------......//....//....------+*++)))(''&&&&&&%%%%$#$$""!!      "%*,.29AFKPOLJGDBABEFIF<,('&&&&((')%(')Vlc_\bhglS2JLLNSUJGJNKIA<D@BGQ^aeghji_gjnplbejgbac^WTPLHGFEDB=834675/++++****))++0269995534457:=>>>=;97532111333335888876421/0000000/.-,,**))))())-6;@>:641.*&$&&$$%$%%%%%&''''''))++,,../02222221111////..------,,--,+,,,-/11344123434456866666411344<FR[eov{}€}ywtrkdgjlquy{{||{yxwtrokgc`\WVTQNJFA<:88887677::::9;;;<=>><9;;99;?EJOS[^`_`_\ZY[`ejqvz{{yyxxzz|{y{{||||}~}ytmc[NEFFEDCDCBBBCCCCDEFGGIIHHFGF54224322322211110000////////......//..----++,--,+-,,,,,,-+***+++,,++,,,,++++++**)))))))*++++++++,,,,..----..........---------------,------....//--...0--------,,+*****('''&&&&&&&&%$####""""  !"%()-/4;AHMPPLIFEB@BBDJG8**'$$&('''&'$7fmc]_chhlZ&+CKJNMOTSKING@9NaVZWR]dilkkqnlnpob_eggebb_WSPLHCBACB?:30254.,,++++,,+**+-/3578652113688;<=>>>>;955312331024425775422001123431/--***))))(((18;=:6640.+)%%%%%%%%&&&&&&&&''(()***,,-.01000011111/00////.-,,,+**+*+++-.0111112333223455566766644559ANYbkqx~}xurniefgjmqvy{{{zzzxxvtpligfca]XSMIFDA>::6777677899<<==<<=<:9889<@FJPUZ]```][USTZ]dhpv{{zzxyyy{{{|}|}{{|}}|xtkb[OEDEDCCBAAACCCDEFFHHJJIHFFD33222222221110010000//......----....--,,,,++*,,+,++++++++++++,,,++**++++********)))))))*++,,++++,,,,..--,-..........----------------..----......--....--------,,,+****('''&&&&&&&&%$$$$#""      "#&)),.28>DGJKKIFEBCBCBFB0(+'&'&'''(*%@pmbb`ffhoL#*0EQJGF@BLQFKJ?<FT[dWVcinonlopklpeW_jjhica_XRRMIDA>>=<93/011,++++++,,+,+,,/.3565531/057789;<>@@?=:76334300011114445332222234320--,**)))(&&'*38:<865430,*(&%%%%%%%%%&&&&&&''()**,,-//0000011111000////.-,,++++**+++,-...../01221233355666555334437?KT]emty~|vrpnlgbegjoux{{zzzzyywtrnlkkihd`[XUPMHFA;877666777::;;;;::887779<BGLQW[]__][WQMMTY`gptwzzwwxyyzzy{|||{zy{}}xribYNEDCCCABAACCDEFFJKJJJIGFED1132222211111/.//........-------,.,,++*,+++,+++*****++**++++**,,*)****++****(******+*)****++,,,,,,++------......--..--------------,,------.......-..-,--------,,++++))((''&&&&&&&&%$$$###"""   #$'*,-.26;@BFIJIGGDAAA@?8-*,('%''&(''<pkddegjlh=+/3?ZLCFG<PRNKIGFLQ_f`X_gmoonpqopof_ejhgiffa]XRNGB=;:;:74110-,++**)*,+--,*,./01345420037589::<>A@?<:8697531//.//122444433355431/.-,,*)(*)'%''-2499856720-+'%%%%$$$$$%%%%&$%%'(**,,........---/0000..0..-,,++++++**++,,,,----01111233444433332232126:BNWbjqx{zurmmkfbbekqtvzxyzyxxvttolmmmljiggb^ZVQLE?986656777789::998866569>BFMSX\^^^]YUNIHJS[ckqwz{xuvvwxwwyz{}}z{{{zvpi`XPFDCB@@ABCDDDGHHJLKJHGECA1110111100/.//-..-------,+++,,,,-,++++*+)*++***)))******++**))++))**))))))))()((''(**)****++,,,,++++,,------------..--------------,,--,,,,--,,,,.,-.-,------,,,,++++))((''''&&&&&&&%%%$$#"""  !$%)*,-.16;?CEGJJIHEBBA@9.*++('()(((*>kmfcfkmog5&.10=XXKNKJLMRSNDFFPQhieafltolknnknl`bdffefghf_ZVRJB=;:866:;83/-,*(()**,-./...../124642223568999<??>=><:;9753221/0132334433344321/.-,,+*)))('&&),15::997661/,'$%$$$$##$$$$$$&&'(**,,--......---/.....///.---,,++++**++,,,,--..////0112222211112210/0235>JV^gotyyvrpmlhcaejlptwxyyxvsqomjiijjkjmmkie`ZSKD<87666667777776666555768>DINTZ\\^^]UQJFBGOXaiotxxxvttuvvuuy{{zxyyzxvqibYPECABBCDDEGHIJIKKJJHFCAB000000//0/////0.----+,,,,*,,,,,,,+**))*)())))))*))*)****++**))))(('(((('(()))((((((())********++++++,,,,,,,,,,------..--,,------,,++++**+++++++++++-----,,+*,,+,,,****(('''''%''&&&&%%$#$#""   "%(),+.147>BEFHIKJIHDDC?0*)*(&(*&)(*)dpgeejjoW*(0/4DV\LKHILKBIRKE?IY_YX[`jpskjjelnlg_aegc_afhe_]YUNGB=:879=D?51-+)((((+,--//..--.//3345521136779;<<<????>><9866533334444542300000.-..-,+*)))('&'(,27::;;9841.*$#####""""##$%$&()*,,,,-....--,,,---.././/....--,,,,++,,,,,,,,----..//01000000//11/.////15;FO\ckry{wtpmiheaagjoruwwtqqnkihfdddhjijljgd_YQH>987665566775544445555569?ELQWY[^_]ZSMIC@IPX`gntyywurrstrrruy{yyyz|xvpjd\SJAACDFEHJJJJIIKJIFFCA?////....//.././---,,+,,,,*,,++))(*))(()('((('())***)))))**))))))(('((((&''(('&'''''())**********++++,,,,,,,,,,--------,,,,------,,++++**+++++++++++++,,+,,+*,,++++****((''''&&''&&&&&&$#$#""   "&)*,.148>CEFIJKKJJIFFF9++**)'&&'((#TojijnpoO,43.-4CJNOQMSSSOLKDBGG[^UK\biqommjgmomifdba``_cfb^ZYVPKD?<<=<<B=53/)((((()+,//./.-----/2466321135689;;=??@@@@??=<;:998888755410....,.-..-,+*)))(''&'(-147:;97630,($####""""###$%'&'(*,,,-....--,,,-----////....--,,,,--,,,,,,,,----..///00000//..00....../128DNX`hpuzywoljgeb`agnqssuqomiedb`[\^`cfhihd_YPG>988665566775544445544568>CJNTZ\]_][WPJEDDJQZbhpswxvtrpqqqrruz{zyyz{zwsog_XMFECGHIJJJJIIIIIFDA=<....--...--,-.--,,))****+((((((('''''''''''(((''''(((())**(((())(((('&&&&&&&&&&&''&'))****++))))))+++++++,,*++,-,,,,+*++*,,+,,,,****++++**++++++******+*+,++++++******))))('&'((''%%&&%%$$!!     $(+,/137;AGLMNLJKJLKJJC.&)'%'''(('&Mqhciopi?"300/14=GRZ^XVXYUMIB6<HbcZYhqmrrqmnmiijkgda_b`_^]\USUSQMIC@@C?8:9561(&''((())*./00.,+++,,-03101/025788:;=???@@AAB>@@@?>>=;;8542/-,---,-.,,+**)))('&&&%&+/24688441.,'"#######$$$$%&'(++,,--..,,++,,--......////..,,,,------..--------..//000011//..//..--....017?IS\emswwvpjhhd_^^flnpppnlgba^[WTSSX[`ea_ZWME=986665566775566556666669<AGMSWZ\_]\YSNHFEHMT]ekpuwxxvspmnopqsx{zyyy{zwtqjc[UMIHIHIJIGIGHGFC@=;9....-----,,--,,,,+**))((('''((((''''''''(('(''''''(((())**))(((()(((&&&&&&&&&&&&''&'(())))**(())))+++++++,+**+,-,,+,**+,,+**,,,,****++++***+++********+**,++++++******))))('''((''%%&&%%$$""    "%),/147;=BHNRQOMLKKMLH7*&&('&'&&($Ntiejjle2#120.306EIOWYVVVWVMD;08F^RU[akjruqmprnjiggdb`]^^YUTNMPRNLMF??A<763551+'''(((()*-.//.-,,++*+,-.00/0035778::;<>@@@@AABBBAAA?=;87531//.--,,,+++**)))''&&&%$&(+.025442/-)%#######$$%%%&'(++,,,,--,,++,,--......////.-,,,,------......----.///0000111/0000/.--..//0122;EP[ainvyupmjie_Z]bhknqrplfb^YUQNLOOSXYWUPJB9786666677887777889999:::;AFKQVY[\]^ZUQKGFHMRXahlpuwyywrmmoonorv{zzz{||yxtolc\RKIIIIHHGEEDC?=;76....,+-,,,--,,,,+****(''(&&&&&''''&&''''''&&%%''''(((())(())((('''''%%%%%%%%%%%%&&&&&&''(''''())))*)*+++*++++++,++++****))+++*++**********))))**************++++******)))))((((((('%%%%%$$""!!   $&)-037;>@CHMPQONNLLMK?-)(('*('&%&TvjefjdgC#.210.-/9HORXYY^dZTMG>1<HZZTW^hjmqqswvqiaafd_ZY^_VPNIHJNMMMIDB@<854774-(%&'()))),/..-...+)(('))*--.014566899;<=>??A=>?@@BBA=::8664210//-,+**+*))(('&%%$#$$$%),.1234/.+&#"$##$#%%&&&''(****++++,,,,----.-......//.-,,,+---------.-------.///00011001100/.00//00230149AJV]fkrxwqpjec]ZZ^cglmonlgb[VSPIGGHJMMKFC=88:9887788888888:<<<;;;;<;?CHMRXZZ\^[WRJIGILQUZagmqtxyxvrmonpqrsv{{{{|}€€{xsohaVNIHGGDDCDA?;:752,,,,--,*++++******((*)))&%%%&&&&&&%%&&&&''&&%%''''&&(())((((('((''&&%%%%%%%%%%%%&&&&&&'''&&&'())))*)))++*******+***++***))****))))))))))))(()))*))))))))**))**********)))))(((((((((((&%$$""!!   $(*-037?CDEHIJLMOMMLJB2''''(*)%%$StkafhiiM&.10..-+/>MWPUVY__][TH>7CQ^^UWc_[htstwyzqffki`[Z[\ZRKIHJJJKJJFDA<875654-(%&'())))+-,,-....*''&$%(*+-/25568988;<<<===;::;>>><9::::8732100.,+***+))((&&%%##$$##%&*,.11/.-*%%$##$$%%&&&''(****++++,,,,--...-......//.-,,,+,,,,-----.-------.////00000011100/1111222223236>GQYajpuxrnhc^[VY^`ekmnnnhc\VSNHDA@CCB@==:;<;::::;;;;;;;;<=======>==BDIPSWXZ\YWTNJKJJNSW\dgkqtxyxvromqrrrty|{{|€ƒ~}wqlaULIHEBCB?=;97633++,,,,,+****))))(((&&&&&&%%%%%%%%%%%%%%%%%%%%%&&''&&&'((((((((''&&%%%#%%%%%%%%%%%%&&&&%&&&&&'))(''*())()))))))****++*)))))))(((())))(()))((())))))(((())))))))))))**)))))))((())((''((&$$%$#"!!! %'*/27:@EGFGEFIKNNMJD7,*((()*+$#A{m_^edj_%+1038/++-8DLORSUZ[^]QJB=HRWYQRZRTbrstx}|wusoh`\YVUTPHHIHGGEFJGDA>976543.('''(((')*++++-//.,*'%"$'(+.046776679=<<<=<:976798877:;<<;76320/.,*****))(('&&&#$$$$$#$'*-.10/.,)&$$$%%%%&&''(())**++,,----..///,---...//.-,,++**++++,----,----....//00001112221133334455434467<DLT_eltvsmhc_YUTX^cgkmmmje]XRNHE?<:<>>?>>=>>???<<=>????@@????>>>=<>BHLPTVXYZWUPLKHINRUY_dhnrvyzyvrqqqrssvy~€€‚ƒ…„‚~yri_QGFC?==;9644330+++,,+******))(((((&&&&&&%$$$$%%%%%%%%%%%%%%%%&&''&&%&((''((((''&&%%$%%%%%%%%%%%%%&&&&%%&&&&'''''')((('(()))))))(())))))))))((((((''''(((((())))))(((((())))))))))**)))))))((())(('''''%%%$###!! %),/4:=BGIIHFEGJNONNG>3))))*)((-qwi`dijb5%.1122-**,5BLNNSW[]\ZNF<8HVY[[S`dY[bmptswwwunjaZTQPPLFGHIFDDEIJHCB?;98851+((()))*)')*++,...,-,(%$$'*.26887668:;=<<<;:9664666577;9897521//.-,,,,,**))('''&$$$$$#$%(*.01//0-)(&%%%%%&&''(()))*++,,----..-------......-,,++**++++,---..........//001122123333344455777877778;@IQYdhpttmha[ZSRV]`dkmmlid^XUOLHC?@@@AAA@@@AAA@@?@AAAA@@??==>><;;<?BGMSUVXYYVRMLJLNRTX\afkqsvwzywtrqqtvxx}ƒ…†…ƒwocVGC@<;:964332/.**))****))(())(('''&&&&&%$##$$$$$$%%%%%%%%%%%%%%&&&&&%&&(&'(('&&''&&%%%%%%%%%%%%%%%%%%$$%&''''''''((((((((*((((((((())))((((((((''''''(((((((((((((((())(((((())****))))))*)()))((''(('%&&%$##""!  "%(,/4;?AEHIGFEFLNONMNG7'')**)((]{mceiph@!.20/.,*)+-7AFJRRTX^c^OEA=M_ffjnwq_YS`edkrxyumjd[VSPOJDEFHFDDDHHGFFFC>:852+)))+*+,,((')+,-.-,.,*)'&&(+.59854799<<=<::9755545555653666210///.-,/..,++,****'%$$$#$$$%),.21121.+(%#%''&&&'(((()*++++,,,,....----....,-..,+++****++,,--/.....//..//00223221243345556677888888779>EMU]emsrmib][WSV\_cgkijiec[XTOLGEDBCCDCBCCBBAAAABBBB@@?=<;;;;99:;@EKPRWYZZXSPOLOQSXY\achlqsvy{{xusuuuwz|ƒ„‚‚ƒ……ƒzqfYHA<98755211.,,**))((**))(())((''&&&&%%$$###$$$$$%%%%%%&&%%%%%%&&&&&%''(&''''&&''&&%%%%%%%%%%%%%%%%%%$$%&''''''''((((((((('''''''''((((''''''''&&&&&&''''((((((''((((''(((((())****)))))))(()))((''(('%&&&%$#""!  $&(,.37;<?ADA@AEKLMMLHC4(('))*%UwolhnrpW&+/3/..,+**+8@KORRUVVY^QCCO^gkjgmjVYa^ZWWcortplni_YVRNHC@CEGFEFGEFHIIFD?;94.**-**.11.+(')+,,,,-+,+,))()-164345688;:988764222333332222210//-----....,--****(&%%%$$$$%(*.100210.+(&%&&&&&'(((()*++++,,,,......--//..,---++++****++,,--/...//////00112343233334455666778999888998;AIQ[bnrsole`[[YXY_cgikjjhe^[XSPJGEDEFECCCBBAAAABBBBA@?=<;::9999:>EHNRUW[ZYVSQQRTVX[]`bbhmpswx||zxusvx||~‚…„‚€‚‚~yri[J>8754220/.-+,**))(())))(()('''&&&%%$$$$$$$$%%$$$$%%%%%%%%&&&&%%'''''''&''&&&&''&%%%&%%%%%$$$$$$%%%%%%%&&&'&''(('''%'('&&&&&&&''&(''''''&&&%%%%%%&&&&&%%&&'''''''''''''((((()(((**))(()))(())))'(((((('''&$###!  $%*,-1467:<=;>@BIJLJJF>2*'()(%Syocagso]$'//.--++***,/BKMRSSQPU[ZLDNbkooerj_[heaaMWglomkjgc^]XNGB?@ACEFDDEHIIHFDB@=7/,,//03682.*'(())+,+,--..++--000011236676544111012222100.//////..--..//11/.,*))*)('&&#%$$%)-1323330/,)&%%%&'''(((**++,,,,,-...../..////..-+**++*))++++++,.//01111222222233333444556666666887799888777?FOZciqusnje`^[YX\`eghklid`\WUPKHHGFEECCBA??@@BBAAA@?=<;:987889<@DJOTWY[[YVTVVXY[\]_ddghlprtx||{xuvxz}‚„…€~|yriZI;5531/.-,++++))))(())))(()('''&&&%%$$$$$$$$%%$$$$%%%%%%%%%%&&%%'''''''&''&&&&''&%%%&%%%%%$$$$$$%%%%%%%&&&'&''(('''%%%%%&&&&&&&&&'''''%%&&%$$$$%%%%%%%&&%%&&&&''&&&&&&''''((&'((**))(()))))))))'(((((('''&#$##!   "%(+-023347:;>BDFIKKJFB6*'))&G|o`_fqqe7 ,0.---++***-=GDGQTWROQYYRJSbjq^ovbeoha`bRP\dhjhd_`b^YQGB@?@BCCDDEFFFFEDB@=7/-/13425420+)((((***,/12200..--//../02241111011012222100///////...-..//11/..,,,*)('&&$%$$$'+-2555410-+(&%%&''''((**++,,,,-....../00110000/-+++++**+,,,,+,.//011112222222222223434566655557877998887666<CNXaiqtvtqjgb`][Z]dgkjhhfc^YVTPKHGFEDCBAAABBBBBBA@?=<;:977889<AEJOQUWZ[[[Y[[Z[\_acceffhknqtx{|zwxx{€‚ƒ„‚|{{yuqg^M=200.-,,+++++(((((())))(''''''&&%%%$$$$$$##%%%%$%&%%%&&%%$$%%%%&&'''''%((''&&''''&&%%%%%%$$%%$$$$$$%%&&&&&&'&''&&''%%%%%%&&&&&&&&&&&&%&%%%%$$$$$$$$$$$$$$%%%%&&&%&&&&&&'''''''())))))***)(())('''(('&&&('$%#"""     #')./12237:=@BCFHJMLGA4)(*'6uvkkjpqj8%-.----++))*0FCBIQSQPOSRMXY[`k]Knovnigd^YYVRYabe`\][[\SKFA?>?@CFFEDCEECBA@<72.04872-121-,*))()(),/255442..,..--///.///////00133332111..//0000..--00000/.-,,*)('&$%%$$$$(+.2455211.+)'%%''((()++++----........001111200/,,----,,--,,,,..//1111111122111101223444554444566688888888659BLV_jsx|zwrkgc`ZX]adghhjhd`\YVQLIGFEDC@??BDCDECBA@?;;;:89:::<?CHNSWZ\^^____^^_bdffffcbehkorvz||zz{}ƒ‚‚~{yvtsni^QA2..-+,,-++**(((((())))('''&&''&%%%$$$$$$##%%%%%&&%%%&&&&''%%%%&&''''&'((''&&&&''&&%%%%%%$$%%$$$$$$%%&&&&&&'&''&&&&%%%%%%%%%%%%%%%%%%&$$$$$##############$$##$$$$%%%%&&&&&'&''()))))))))(((((('))(('&&&'&'%$##""   ""'),.01358<BCDDFJLOLGA2((,,l|kkqrnlA#*------++*))-/9FLQPPPPKLPW^`[b^W_eproiiec][X]`aa]\ZUXXSOLE?<=>?CCBAAEFB@?ABA90.1550-/211/.,)))++/-0358830.,,,--...-.--..-0/013333332200001111../000000/.,++*)(''&%%$$$$%),0244221/-,('%%%((()++++------......000000001011/---..--,,----./00000011110011012223444455444466777777774448@LWaju|~}zvpie_YW[]cffijifb\ZVQLIGGFEBBDFGFGGECB@@?=<;9:::;=ADHNSWZ\__``aa``acegggfc``bdjosx}||zz{~€€€}xvtrqmh_VF6---+++,,,++''(((((())('&&&&&'&%%%$$$$##$$%%&&&&&&&&''&&&&&&&&&&''%%%&((''(('''''&&&$&&&%%%%%%%%%%%%&&''&&&&%%&&%%&&$$%%%%$$%%%%%$$$$#####""""""!"""""""####$$##$%%%%%%&&&&&'(((''))))))))))(())))''&((&&'%%$""  !##')*+.039<@BFJMNNOOJFA1()*[wlmvsoP  #,,,,,,,,,**+15:@HORONKHKKUadXQZeigackh[Xda___\__\ZYSQORRNHB@><;;=<<=?====?DKA1**.0.//33201/,*-0110214883/+*)),+,,,,,-....///02123234433221100//..00110/.,,++*(''&&%$%#$#&'++/0111//-+)'''((())*+++,,,+++,...-0000//01001100..--..--,,----,..../00////000011222233443333466666777654447@LWclv||vrie\USX\aeiijifb_[VRMIIHGGFGHJJJJGEDCC@>=<;;==??AEHMRVZ^`accbbabedeffffc`][\djnsuy{{zz{~~~ywuronlicYM=.***+++,+))(((((((())('''&&&&&%%%$$$$##$$%%&&&&&&&&''&&&&&&&&&&&&%%%&''''((''''&%&&&%&&%%%%%%%%%%%%&&''&&&&&&&&%%%%###%%%$$$$$$$####"##"""!!!"""!!!!!!!""!!""""#$$$%%%%%&&&('''''))))))))))))))))****''''&$$#!!!!"$')*+-/16>BFIMPRRTRJF?.()9zrinwwqT! "&,,++,++,,***/05>FILLIJLMLXbcYEHST_fldda_`bike^^_^]ZRPQSRLEBA><87788989999;BPI1*),-022421/0//023445222330-*)**)+++----.////0/0100023443333221100..//00/./--,+*)()(&&%%$#$$$'(*-./0100/.,)'(()(()**)+,,....//.-////..,-////....-...--,,,,,,,-..-.//////0000001100002322222333334554444469@LYcpv{{}}wqh_VPQW\aehjjlgda\VRMLKJJJKLLMMLIGFDC@?=<<<==??CGHMRVY]__cddebddeeffffc]]ZX[aflpsyz{{yz~~}xvrpmnlje^TC1+)*)**+*(('''())('))('''''&&%%%%%%%%$$$$%%&&&&&&''''''&&&&&&%%''&&''''''''&&&&''%%&%%%$$%&%%&&%%%%%&&&%%''&&%%%%$$$$"###$$$$##""""""!!!!! !!!!!! ! !!!!!##""!"##$$$%%%%%&'&&(((((())))))))))))****((((&%$$""!!!$()*++./5=AEJSUTTVQJE;*)(Tuqmsyte* "!%*,,***+,.,+++*3=BHKGHHFDFP_SFKSQTbgeijf^_\bjdZX[\\ZSPTVSQLCB?;:7544545688:AE@8,)+,.334422145665676310//,+*)(((()+----.0/011////0001331223333110/,-/../-.,-,+++*))(&$$$$$#$$$'(+,,/0221/-+*)))******+,..00/0/-./////....////......-,,,++++,,--....//////00////////00122211111123334434578ANYenwz{|yuoeXPPQTZbfgjkjgdb]XRPOMOMNOONNLIHFED@@?>=<>>>>AEINQU[]]acefffgffggffdb_[URQV^dhkrvz|z{|zzxuqrllkif_XJ:,)+*))))(('''())('))('''''&&%%%%%%$#$$$%%%&&&&&&&&&&''&&&&&&%%''&&''''''''&&&&&&&&&%%%%%%&%%&&%%%%%&&&%%%%&&%%%%$$$$#"""####""!!!!!!          !!! !!!  !$$!!!"##$%$$%%&&&'))(((((())))))))********(((('%$$##""#&())*+..48>HKRVUURKHD9)(,ksjqxsi7$"#'*++**)+,./,*,+5AGGIIF@?;=FRJ?IRYkhfhhceg\P]gaXTWXZZVQUSMMJCC@==:755534688<>>><0))+-0144434688875431/---,+*)((((()*,../0/011///////01113234445320/,+../----,++**++(''%$&$$$$#&&(*+.133220//,**++++,,,.0000/0110.////....////....//-,,,----..--....//111100//////////002211222223334454576:CNYcjsyyyurj_VOSRW\bgmklkieb\XWRQPPOPPNNJHGEDDB@@??=??AACEGNQU[]^bdgihghggggfeda]XRONORYaglptx{zyzzxxwsmmligd\SC4-*)((''((€€€€~~~~~~}}||}}~€€€€€€€€€€~~~~~~~~~}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~}|{zzzzyyyyyyyyyz}€‚…†‰ˆ‰ˆˆˆ‰‰ˆˆ†…ƒ‚‚ƒƒ‚€|{zzzzz|}ƒƒ……„‚€~‚€ƒ†‡‡„‚ƒˆ„„‚€~~~~~~~~~~€ƒƒ‚€~}{||{}~~~~~~~}}}€ƒ„„…†‡‡ƒ~}}}}||{{{{||{}||}~€€€€€€€~||{|~~~€€€ƒƒƒ€}{xwyz~€€€€~}|}~~~~‚„}|€€€€~~~~~~}}||}}€€€€€€€€€€€~~~~~~~~~}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~}|{zzzzyyyyyyyyyz}€‚‡ˆˆˆˆ‡„„„„„„ƒ„ƒ€~~~‚ƒƒ‚€|{zzzzz{}~€‚ƒ„„ƒ€€‚ƒƒƒ‚‚ƒ………~x{‚…„‚~~~~~‚ƒƒƒ‚€}{||{}}}~~~~~}}}~ƒ„„…†‡‡ƒ~}}}}||{{{{||}~~~}~€€€€€~|yy{|~~~~~€€€‚~}{zyz{~€€€€~}|}~~~~‚„}{y€€€€€~~~~}}{{}~€€€€€€€€€€€~~~~~~}}}}}}}}~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~~~}||zyyzzyyyyyyyy{}€ƒ…ˆ‡†ƒ‚€ƒƒ„……‚~~}}‚„„ƒ‚|{z{{zz{~€‚„„ƒ€€ƒƒƒƒ‚‚‚‚ƒƒ…„€yssu€†ˆ~~~~~€‚ƒƒƒ‚€}|}}}}|||}~~~}}}}~€‚ƒ……††‡„‚~~}}}|{zz{|}}€€€€€€€€~}|{yz{|~~~}}€€‚‚ƒ‚}}zzyz|}€€€€‚‚‚€~~|~~~~~~€‚ƒ~yy€€€€€~~||}}}}~€€€€€€€€€€€~~~~~~}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}||z{{zzyyyyyyyyy|‚„„‚„…††‡„}|{}‚„„ƒ‚€}{z{{{{{}~€‚„„ƒ‚‚ƒƒƒƒƒƒƒ„ƒyvuvzƒ€~~€ƒ‚ƒƒ€‚}|}}}}|||}~~~~}|}}‚‚„…††‡…ƒ~~}}}|{{{|}€€€€€€|{xwxy{|~~}|}€€‚‚„ƒ~|{zy{|}€€‚‚€}}|~~~~~~ƒ„€{yy€€€~~}}|{}}}€€€€€€€€€€€€€€€€€}}~~~~~}}}||}}}}}}}}}}~~~~}}~~~~~~~~~~~~~~~~~~}}||{{yyyyyyxxxxyz|€€‚ƒƒƒƒ†‡‡…„‚}|{{|ƒƒƒƒ|{zzzz|}€‚„„„ƒƒ„„ƒƒƒƒƒ~€~}|z{‚€€€‚„ƒƒ‚‚€€€€€~|{}}}}}}|}~~}}}}|~€ƒƒƒ„…†„‚€}~~}|||}€€€‚ƒƒ‚€€€~|yxwwxz|}}}|{|‚‚……ƒ‚€~|{{{|~‚‚ƒƒ‚}{z}~~~~~‚„{yx€€€}}||{z||}€€€€€€€€€€€€€€€€€~~~~}}}}||}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~}}||{{zzyyyyxxxxyz{~‚ƒ„…………†‡‡…‚€|{{{|ƒƒƒƒ‚€}{zzzzz|~€€‚„„„„„„ƒƒƒƒ}|}~}}}~}~ƒ…ƒ€ƒ„ƒƒ‚~~€€€~|{}}}}}}}~~~~}}||}ƒƒƒ„…†„‚€}~~~~~‚ƒƒ‚‚‚€€€~|}}zywvvxz|}}}|{|‚‚……ƒ‚€~}{||}‚‚‚}{yz|~~~~~~‚ƒ‚}{y€€~~{|{{{{|~€€€‚‚€€€€€€€€€€€€€€€€€€}}}}}|{}}}}}}}}}}}}}}}~~~~~~}}~~}}}}}}~~~~~~}}||||{{zyyyxxxxy{|~‚„„†††††…††„}{z{{}~€‚‚ƒ‚{{{zz{{}~€€€ƒ„„„ƒƒƒƒƒ‚€|}~~~~}}„ˆ‰ƒ}}‚„„‚„‡‡ƒ‚‚~|||‚‚€~}|||}}}}}}~~~|{{}~ƒƒƒ„…†…ƒ‚ƒƒ„„ƒ€€€€€€~}~~~}zyvuuw{|}}||z|€€‚‚……ƒƒ€~}~~‚ƒ€~|zwxz}~„‚|z€~}}{{{zz{}~€€€€€€€€€€€€€€€€€€€€€€}}}}||{}}}}}}}}}}}}}}}~~~~~~}}~~}}}}}}~~~~~~}}}}||}|{{zyyyxxxxy{}‚„„†††††…†…‚|{|{{{}€‚ƒƒ‚€|{{zz{{|}€€ƒ„„ƒƒƒƒ‚~}}€€~~€€~}{{ƒ…††…„„‚€~}|‚‚€~}|||}}}}}}~~~~}{{|‚ƒƒƒ„…†…ƒ€‚ƒƒ„ƒƒ€€~}~~~}zxuttw{~}||z|€€‚‚……ƒƒ‚€€€‚‚‚~|wvw{~ƒƒ€}{€€€€~~}{{zzz{~~~~€€€€€€€€€€€€€~}}}|{{{{|||||||}}}}}}}}}}~~}}}}}}~~}}}}}}}}}}}}}}}}|||zzyxxxxwxy}€ƒ……††„………„ƒ||||||||~€‚ƒ„ƒ~|{zz{{|}}~€€‚„„ƒƒ‚€~~€~~€~}||y~‚€{vvz|}|ƒƒƒ~|{{{|||}|~}}~~}}{|~‚ƒƒƒƒ†…ƒ€€‚ƒƒ„„ƒ‚‚~~~~~~}~~~~{xusstw{|}}|{{}€ƒ††„„ƒƒƒƒ€‚ƒ„ƒzwvy|~~~~„„~z€€€€~}|{{{{{|~~~€€€€€€€€€€€€€~}~}|{{{{|||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|||zzyxxywxz{‚‚ƒ…††„………„~||||||||}~~€ƒ„ƒ‚€}zzz{{{|}€€‚„„ƒƒ‚}}~}|}~€~}|zxyzx|‚~xtqqrtw|ƒƒƒ~}|}}||}}|~}}}}||{|~‚ƒƒƒƒ„„‚€€€‚ƒƒƒƒ‚€~}||}}~}~~}}yvsrrsw{}~}|{{}€ƒ……„„„„ƒƒ‚‚„…ƒ}yvwy~~~~‚…ƒ{€€€€~}||{{|}}}~~~€€€€€€€€€€€€€€€~~~}|{zz{{||||||||}}}}}}}}}}}}|||||}||||}}}}}}}}}}||{|{|zzyxxwy|~ƒƒƒ„…„„„……„~||||||||}}~€€‚‚ƒƒ~|{{||{}~€‚„…„ƒ‚€~}}~€}|}~|{{zzywvv|‚‚~xtvxz}~€€‚ƒƒ~}|||||}}}}}}}}|{{{}€ƒƒƒƒƒƒ‚€€‚‚‚‚€€}|{y{|~~~}}}zxusqqrvz}~}|z|~€€€‚ƒ……„„„„ƒƒƒ‚ƒƒ„…ƒ€{xvxy~~~~€ƒ…„€|€€}}|{|||}}}~~~€€€€€€€€€€€€€€~||{zzz||{{||||||}}}}}}}}}}~~~~||||||||}}}}}}}}}}||{{{{zzyxyx{~€‚„„ƒ„„„„„„„„}{||||||||}}~€‚‚ƒƒ|{{||{|}~€‚‚„„ƒ€~~}€€~~|zz{{zxxvw{~zz{||||}€€‚ƒƒ~}||||}}}}}}}}|{{yz}€€‚ƒƒƒƒƒ‚€€€~|yyxy{~~~}}|ywtqppsvz}~|{{}~€€€‚ƒ……„„„„ƒƒ‚‚‚ƒ„‚{xvx|~~~€ƒ…„€|~~}}|}}~~~~}~~~€€€€€€‚~}|{{{{{{{{{{{{||||}}~~~~}~~~€||||||||}}}}}}}}}}{{{{{{zzyyy{~€‚ƒ‚ƒ„„„„„ƒƒƒ}||||||}}|}|}}~€‚‚ƒƒ„€}y{||{||}€‚ƒƒ„‚}~~~|yz~}}~~||}}|{wvyxuy€~{z{~ƒƒ~~}}}}}}}}}||zyzyyz}‚ƒƒƒƒ‚‚‚‚}|{ywvwx|}~}~~}|xuspnpruy}|{|~€‚ƒ…………„‚‚‚‚‚‚ƒ‚}zwvz}€€~~‚††~~~}}|}}~~~~~~~€€€€€€€€‚~}|{{{{{{{{{{{||||||}}||||{}~~~|||||||||}}}}}}}}||{{{{zzzzyyz|€‚ƒ„‚‚‚‚‚‚‚€}||||||}}|||}}~€‚‚ƒƒ„~}}||}~€€‚ƒ„‚}~~}ztsw}~}|}~€€‚„„‚|tswwy~€{z{~ƒƒ~~}~~}}}}}}{{yyxxwx{}‚ƒƒƒ‚‚€€€€~{zywvvwz}~~|zwurpnnpuy}|{|~€‚ƒ……ƒƒ‚€€€€‚|zwx{€€€‚„„~~~}~~~~€€€€€€‚‚‚‚€~~}|{{{zz{{{{{{||}}}}}}}}}}}}||||||}}}}}}}}}}||||{{{{{{zzzzxz|}€€‚‚‚€€€€‚‚~~}||||||||}}}}}~€‚‚ƒƒ„ƒ€~||}~€ƒƒƒ‚€}~~||yy|}„‡…€~~€€ƒ„„ƒ~wsuwz}}|z|‚‚‚}|}}}}~~}|zyyxwutvy}€‚ƒƒ€€~}|zxwvuuvy~€|zusqpnnpuz}}|{|~€€€‚„„ƒ€€€€€€}zvvy|€€€€„„~~~}~~~€€€€€‚‚‚‚€~}|{z{{zz{{{{{{||||}}}}}}}}}}||||||}}}}}}}}}}||||{{{{{{zzzzxz|~€€€€€}{z|||||||{|}}}}~€‚‚ƒ‚ƒƒ€~}~€€‚€€ƒƒ‚~~~}}{}}€ƒ…‚€€‚‚‚‚€}ysprw{|z{|‚‚‚€~}|}}}}}}|zyxwwutrtx}€‚‚‚€€€€€€€}|zywvusuvz€€€~|yutrpnnpuz}}|{|~€€€‚„„ƒ€€€€~zwuuy|€€€€„„~~~~~€€€€€€€€€€‚‚€€€~}|{{{{{{{{{{z|||}}}}||||}}}}}}}}}}~~~~~~}}}}|||z{{{{zzzyyyy|~€‚~}}~€€}||{{||||||}}}}}~€‚‚ƒ‚€‚‚ƒ€€€€‚„ƒ~|||~}ƒ„‚€}{xtolu|~{{|€‚‚ƒƒ}|||||||{yxwwvtsprv{~€‚‚€€}||}~~}|yxvvusstw|~€€€|yvtsrompty}}||}€€€‚‚ƒƒ‚€€~~~~}zxusvz}€€„ƒ}~~€€€€€€€€‚‚€€€~}|{{{{{{{{{{z|||}}}}||||}}}}}}}}}}~~~~~~}}}}|||z{{{{zzzyyyz}‚€~}}~€€}{||{{||||||}}}}}~€‚‚ƒ‚€€€‚‚ƒ€€€‚„ƒ~{xy||~‚ƒ‚ƒ„ƒ‚‚€}{ywuoks|}{{|€‚‚ƒƒ€}{z||||{{zywvsrponouz}~~|zz{|}|zxxvtsrrtw}€€€€~|xttrqonpty}}||}€€€‚‚ƒƒ‚€€~~}}{xtrsv{~€€„‚~€€€€€€€€€€€€‚‚‚‚‚‚‚€€€€~}|{{zz{{{{{{||}}}}}}}}}}}}~~}}||~~~~~~}}}}||{{zzzzyyyxxz{‚„ƒ€}}~€‚‚‚|{{{{{||||||}}}}~~€‚‚‚ƒ‚€€ƒ‚€€€‚ƒƒƒ‚€~|{||~‚†‡‡…„ƒƒ€}{zyzxtmqz|z{}€‚‚ƒƒ~{z{{|{{{zxwvsqnmlmry}~|zyxxz{}|yxwtrqpqsx}€€€€~|wtsrqonpty}}||~€€€‚‚ƒƒ€€€}|yxtpqrw}€€}}~€€‚}€€€€€€€€€€€€€€€‚‚‚‚‚‚„……††„‚~}}}}~~||}}}}}}}}}}}}~~}}}}~~~~~~}}}}||{{zzzzyyyxy{~‚ƒƒ‚€€€€‚‚|{{{||||||||}}}}~~€‚ƒƒ‚ƒ‚€€€‚ƒƒ‚€~~}}}~„„……„……‚~|zyyxxvpnw{z{}€‚‚ƒƒ~{z{{{{{zyxutqnkjikpv|~}zxwvvvx{||zywtrqpquy~€€€~|vtsrrpnpv{}}||~€€€‚‚ƒƒ€€€}|zxtqnorw}€€}||}~€€}€€€€€€€€€€€€‚‚€ƒ…ˆ‰‰‹‹ˆ‡ƒ€~€‚ƒƒ††…‚~}|||}}}}}}}~~}}~~~~~~~~~~~|||||{{zzzzyyyy{~ƒƒ„„‚‚€ƒ‚}|{{{||||||||}}}}}}€€€€„„ƒƒ‚‚‚„ƒ‚}~€€‚‚ƒ‚~~€‚‚„„ƒ~{{zzyxwwpnuyy|}‚‚‚‚€}{z{{yyzxxvtqomkifiov|~{xvtsstxz{zzyvtrqpqty€€€€€zvtssrqqrx||||}~‚ƒ‚€€€€€€~|zxvrokouy~€€~z|~€€€€~€€€€€€‚‚€ƒ„…ˆ‰‰‰‰‰ˆ‡…ƒ…‡ˆ‰Š‰‡‡†ƒ€~~}}}}}}}}~~}}~~~~~~~~~~~|||||{{yyyyyyy{‚‚„„……ƒ‚€‚€€|{{{{||||||||}}}}}}}~€‚‚ƒƒƒƒ‚‚‚ƒ‚}|}€‚‚‚ƒƒ~}‚‚ƒƒ‚~|{{zzyxwwvsuyy}~‚‚‚‚€}{z{{{{{zxvuroljgfiov|~{xvtutuxz{zyxvtrqpqu{€€€€€{wutusrsux||||}~‚ƒ‚€€€€€~|zwtqnkou{€€€{y{}€€€€~€€€€€€€€€€€€€€„‡ˆ‡ˆˆˆˆ‡‡††ˆ‡‰‰‡‡ˆ‰ˆ„‚~~}}}}}}~~~~~~~~}}~~~~}}||{{zzyyxzy{}€„„………„„‚€‚€}{{{{{||||||||}}}}}}~€‚‚‚‚ƒƒƒƒƒƒ‚€}|~€€‚ƒƒƒ€~€€‚‚‚‚‚‚~|{zzyxxwwwxtsxz|€€‚‚€}{z{{{{zzywurolifeflu|~€|yxuvvwyz|{zyxvsrstx}€€€€€zxvwvsuuvz}{{{|€€€‚ƒ‚€€€€€}yvqollpv}€€€€€}zx{~€€€€€€~}€€€€€€€€€€€€‚ƒ‚‚‚ƒ…††……†………………†ˆˆ†‚€~}}}}}}~~~~~~~~~~~~~~}}||{{zzyyxz|‚„…†††††„‚‚‚~{z{|||||||||||}}}}}}~€‚‚‚‚ƒƒƒƒƒƒ‚~{{~€€‚ƒƒƒ‚€€‚‚ƒ‚‚‚‚‚‚|{zzzyxxwwwwssy{|~€€‚‚€}{z{{{{zzywurolifeflu|~~}{zxxz{}~€€~|{yxxy|~€€€€€~{yxwvutvy{{{{|€€€‚ƒ‚€€€€€}yvqnkkry~€€€€}xwz~€€€€€€~}‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€€€€~|}}‚„…ƒ~{{~~€ƒ†‡ˆ†ƒ€~~}}}}}}~~~~~~~~~~}}|{{{zzyz{}„‡†…………††‚ƒ€€€€~||{{{{zz{{{{{{||}}||}}|}€ƒƒƒƒƒƒ‚€}||}€‚‚‚‚ƒƒ‚‚ƒ…„…ƒƒ‚‚€|{zzzyyxxvxwtrvz~€ƒƒ|{yz{||{zyxutoljgfhlu|~~~}|||~€€‚‚‚‚€~}~~€€€€~{yywutvz|||}~~€€‚ƒ‚€€€€€}yupljltz~€€€{wuz~€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€€~|}}~€}xwxxyy|€‚†……ƒ‚€€~~~~~~~~}}|{{{zzz|}€‚…†…†………ƒƒ|zzz{{{{zz{{{{{{||}}|||||}€ƒƒƒƒƒ‚~}{{|€‚‚‚‚ƒƒƒ„…†……ƒƒ‚‚ƒ€}{zzzyyxwxxxtqry|€|{yz{||{zyxutqnkhgimu|~~~~}~€ƒƒƒƒƒ‚‚€€€€€€€€€~{xvuwz|||}~~€€‚ƒ‚€€€€~}yupllpu|€€}yvwz~€€€€€€‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€€~~~~~~~~}}||}}~zxxyzz{{|~€ƒƒ„†…„ƒƒ€€€€€€~~~~~~}}|{{{zzz}€ƒ……„„………„‚€€|zxxxzz{{zz{{{{||||}}||{{{||€€‚‚‚ƒƒ€~}||{|€‚‚ƒƒƒ…„……†††„ƒƒƒ‚‚€}|{zzyyxxxyvsnpw|€€€|{zzz}}}{zywtrokhhinv|~}}~€‚„ƒƒƒƒ~€€€~~~€‚€~zwuwy|||}}€€€ƒ„}~{wtojkpw}€€€}yux{€€€€€€~‚‚‚‚‚‚‚‚‚‚€€€€€€€€€€€€~~~~~~~~}}||||{{xxy{{{||}}~€‚ƒ„……†††††††…~~~~~~~~}}|{{{zz{~‚„„„„…„ƒ‚~~||{zxwyzzzzzzzz{{{{zz{{zzzz{{{|}€€€‚‚‚‚‚€}|{{z{~‚‚ƒƒƒ„…‡‡‡†„‚‚‚€}|{zzyywwx{}ytrw|€ƒƒ€}}{||}}|~~}ywspoljkov{}~}~€‚€€~|zyxyyz|€€€~}}|~€‚ƒ|wuwy|||}}~~€ƒ„|~~~~~}{wrmkmtz~€€}yux{€€€€€€~ƒƒƒƒ‚‚‚‚‚‚€€€€€€€€€€~~~~}}}}}}}|~~}}||{{{{{{}}}}~~€‚ƒ„ƒ†‡ˆ‰‰Š‰…€}~~~~}}||{{{{{|}€„„„„…†„~}|yyyywwwyzzzzzz||{{{zyzzyzzzz{{z{~€‚‚€~}}{{{{|~€‚‚ƒ„„…††…‚€€€~~{zyyxxwwxx{{utx|}‚‚~}|||}~€€|zvsonnnrz}~~€€|zxwvtrqruy~€€€~~|||}‚„„~xwxz|||~~~~~€‚ƒ‚~€~}{urmjnv}€~|xux|€€€€€€~ƒƒƒƒ‚‚‚‚‚‚€€€€€€~~~~}}}}}}}|}}||}}{{{{||}}}}}}}~~€‚ƒ…‡ˆˆ‰ˆ†~}}~~~~}}||{{{{{|~‚‚„„„‚~{zxwvwwwwwwwyzzzzzz{{{{yyyy{yyyzz{{z{|~€‚‚‚~}|{{{{{}€‚‚‚ƒ„…†…ƒ€|{}}{yyyxxwwvvwvwvwz}‚‚‚‚~}|||}ƒ„„}xvtrstx{~~zyxwvusqpqty~€€€€~{vxz~ƒƒ‚|xyz|||~~~~~~~‚‚~~~}yupnmqy~€~€|wux|€€€€€€~ƒƒƒƒ‚‚‚‚‚‚€€€€€€€€~~~~}}||||||||||||||||||||||||||}|{{}}€ƒƒƒ„„……„€}}~~~}}}||{{zz{}~ƒ„„ƒƒ{xvvwwvvxxwxyyzzzzzzzy{{zyzzzzyyyyyz{{|}€‚‚‚€~}{||zz||‚„„ƒ~~~~|v|€~|zyyxxxwvvuvywvy}‚‚‚‚~}||~ƒ…„ƒ€|zyy{{{~€€€€~yxxwuutrrsuz~€€€‚ƒ}yutw{ƒ‚}{yz{{{|}}}~~€‚‚~~|zuqoot{€€€|wux|€€€€€}ƒƒƒƒ‚‚‚‚‚‚€€€€€€€~~~~}}||||||||||||||||||||||||||}}|{||}€€ƒ„€||~~~}}}||{{zz{}‚ƒƒƒ‚€|ywvvvvvvxxwxyyzzzzzzzyyyyyyyyyxxyyyz{{|}~€‚‚‚€~|{||{{||‚ƒ‚€||}{xy€‚}{yyxxxwxzxvvtvy}‚‚‚‚~}|{||}€ƒƒ‚€~~}~€€€~€~{yxwuutsstw{€€€€€|vsty~ƒ€|zz{{{|}}}~}|}€~yuqnou|€€|vux|€€€€€€€}„„„„‚‚‚‚‚‚€€€€€€}}}}||||||||||}}}}||||||||||~~~~~~}}{}~}|{|€„…„}yz}~}}}}{zzz{{}€‚ƒ„„ƒ~zxwwwwwwwxxyxyyzzzzzzzz{{yyxxyyxxyyyyzz|}€€€‚‚‚‚~|{|||}|~€€‚‚‚€}|z|{x{ƒ€}{yxxxwx{zussv{}‚‚ƒƒ€}|zzz||~€€€€€€€€€~~€€ƒ€~{yxxxvvsuuz~€€€€‚€}yutw|€‚~z{{{{z{}}~~}{yz}~|xtpnpw}~~xttz}€€€€€~|„„„„‚‚‚‚‚‚€€€€}||||||||||||||||}}}}}||||}}~~~~~~~~~~}|~ƒ‡‡‚|yz}~}}}}|{zz{~ƒ„„„„ƒ€|yxwwwwwwwxxyxyyzzzzzzzzyyyyxxyyxxyyyy{{}~€‚‚ƒƒ€|{|}}~~€€}|z|{x{ƒ€}{yxxxwy}€zuttv{}‚‚ƒƒ€}|zz{|||~€€€€€~€€ƒ|yxxxvwwxw{~€€€€‚€}zvtw{~€€|{{{{z{}}}~~{wvy||wtposx~~~|wrtz}€€€€€~|ƒƒ„„‚‚‚‚€~}}||{{||||||||||}}~~~|}}|{||}}}}~~~~~~…ˆ‰ƒ~{{}~}}}|||||~‚„„……ƒƒ‚|wwwwwwwwwxxyxzz{{{{{{zyzyyyxxxxxxyyyyz|~€€€ƒƒƒƒ}|}|~€€€€‚‚ƒ|z{zv~‚ƒ€}{yxxxyz}ytrrtz~€€ƒƒ|zzz{{|}€ƒƒƒ‚‚‚€€€~€€ƒ|zyyyxxwxz~€€€€€€}{xuvz}€}|{{{z{}}}}yvx{}}~~~{vsopty~€€{uruz}€€€€€~{ƒƒƒƒ‚‚‚‚€~~~||||{{{||||||||||~€€€~~~~|||}}}}~~~~~~~~„‡‡…{{}~}}}||}~„……„…„ƒƒ~zxwwwwwwwwxxyxzz{{{{{{zyzzyyxxxxxxyyyy|}~€ƒƒƒƒ‚€~|~€ƒ……ƒ‚‚€||yxx~‚ƒ€}{yxxxy||wuurtz~€€‚‚}{{{{{|}€ƒƒƒ‚€€€€€€€~€€ƒ€}|{{{zyxy{€€€€}{xwwx{|{}||{{{|}}}}€~zwx{}}~~~{wsppu{~~~~zuruz}€€€€€{xƒƒ‚‚‚€€€~~~~~~}}{{{{{{||}}}}}}}}||~}|||~~~~~~~~~~~~~ƒ†‰…‚|z|}}|}}‚†‡‡†…„…‚~|yxxxwwwwxxxxyyzz{{{{{{zzzzyyyyyyyyyyyz|~€€‚‚‚‚‚€€„…††‚€€€|{xvv}‚„€}{zzyyyz}~yuuqtz~€€‚€~}~}|z{|ƒƒƒ‚€~}~€€~~€‚{z{{{zyyz}€‚‚~|{yyyyyz{{{{{||||{}~€€~{wy{}~~€€~{vsqrx|}~}}~~|yssu{€€€€€€}zuƒƒ‚‚‚‚€€~~~~~~~~~~}}}}||||||}}}}}}}}||}~~~~}|||~~~~~~~~~~~~~ƒ†‡‡„€~~€}}~…‡‡ˆ‡†…ƒ‚{ywvwwwwwwxxxyyyzz{{{{{{zzzzyyyywwwwyyz{|‚‚‚‚‚‚€€ƒ†‡††„‚€€‚‚€}|yvv|ƒ}{zzyyxxx|~{xsu{~€€ƒ‚‚€}|{|~‚ƒƒ}z|~€€~~€‚}{{{{zyyz}€€€}{{{{{{{yy{{{||||{}~€€~|zz|~~€€~{wsqsx|}~~~~~}ytsw|€€€€€€}ywƒƒ‚‚‚‚‚€€€€€~~~~~~~~~}}}{||}}}}}}}}}}||||||}}}}||}}}}}}~~~~~~~~‚…†‡…}~~€ƒ†‡ˆˆ‡‡…‚~zxwwvvvwwxxxxzzz{zz{{{{{{zzzzyyxxyyyyyy{}€‚‚‚‚‚‚ƒ„…†……ƒ„€€~€ƒ‚~~vu{‚}{zzzz{zwx}}xtu{~€€‚‚„ƒ„ƒ‚‚}||}‚||{{€€~€‚‚€}{{{{zyy{}€€€€€€€}|{|}~~}{zz{{{zz{{z|~€€||||}}~~~{wsruy}}~~~}xttw|€€€€{xwƒƒ‚‚‚‚€€€€~~~~~~~~~}}}{||}}}}}}}}}}||||||}}}}}}}}}}}}~~~~~~~~€ƒ…††‚}}}}~‚…†‡ˆˆ†ƒ€}zwxxvvvvwwxxyyzz{{{{{{{{{{zzzzyyyyyyyyz{}€‚‚‚‚‚‚‚‚„†…††…ƒ‚€€~}€€zvz‚}{zzzz|€‚ƒ~ysu{~€€‚‚„…„„„ƒ~||~~|z{|~€€~€‚‚€}{{{{zyy|}€€€€€€}|{|}~~}{xzz{{zz{{z|~€€||||}~~€€~{wsrwz~}~~~}xttx|€€€€€|zx„„‚€~~~~~~~~}}~~}|||}}}}}}}}}}||||}}}}}}}}~~}}~~~~~~}~~~~€‚…‡…‚~~~~€‚„††††„|yxwwwwwwwwwxxyyzz{{{{{{{{{{zzzzzzzzyyzz|€‚‚‚‚€‚‚ƒƒ„†††…„€€~‚‚€|{y{€}|{zzzxxww{zvrv{€€€€€€‚……„„„‚€}}€€}{{|€€€€€€€‚‚€~|}}{yyz{~€€€€€~{{}}~~~}{xyz{{zz{{z|~€{{|}}|~~€}wstx|}~||||wuty~€€€€~~ƒƒ‚€€~~~~}}~~}|||}}}}}}}}}}}}}}}}}}}}}}~~}}~~}}~~~~~~}~~~~ƒ…†ƒ€€‚„…††…ƒ|zxwvwwwwwwwwxxyyzz{{{{{{{{{{zzzzzzzzz{|~€‚‚‚‚‚‚‚€€‚‚ƒƒƒ„…†…ƒ€€€€€ƒ‚‚ƒƒ‚€}~€€}|{zzz{{}}{xttv{}~€€€€€‚„„ƒƒƒ€}}€€}{{|€€€€€€€‚‚€}{{{{zyz{~€€€€€~}}~~~~~}{xyz{{zz{{z|~€}{{|}~|~~€}wttx|}~||||wuuy~€€€€€‚‚‚€€€€€~€‚‚~~}}}}||~~~~~~~~}}~~}}}}}}}}}}~~}}}}~~~~~~~~ƒ…††„‚ƒ„„…†…‡‡„|yxuvvvvwwwwwwxxyyzz{{||{{{{{{{{{{zzz||~€ƒƒƒƒ‚‚‚€‚ƒƒƒ„„„ƒ€€~€€‚„‚‚€€~|{{{zy|}|xvux{~€€€€€€‚‚‚‚€€€~}||{{}~€€€€€‚ƒƒ}|{{zzyz}~€€€€€€~~~~}yxxy{{{{zz||€~{{|~~}}‚‚|wtvz|~}}}}~|wtv{€€€€€€‚‚‚€€€€€~€€††„ƒ‚‚‚‚€€}}~~~~~~~~~~~~}}}}}}}}}}}}~~}}}}~~~~~~~~ƒ††…„…†‡‡ˆ†……‚€~zwwvvvvwwwwwwxxyyzz{{||||||~~~~~~~~}€‚‚‚ƒ‚ƒƒƒ‚‚~~€€‚ƒƒ‚€~~€€€€~€€|{{{zyzz{usv{~~€€€€€€€€}{{}}{{{}~€€€€‚‚€}||{zzy{}~€€€€€€€€€€€~~|{yxxyzz{{||||~€}{{|~~}}€‚‚|vtuz|~}}}}~|xuw{€€€€€€€€€€€€€€„ˆ‰ˆ‡……ƒƒƒƒ€€~~~~~~~~~~~~}}}}}}}}}}||}}}~~|~~~~~~~~~~~~~~€ƒ††††‡ˆˆˆ‡†„‚€|zwuuuuuvvvxxyzyyyy{|{|~~}~~€€€€‚‚„„ƒƒ„„„„ƒ‚~}{}€‚‚‚‚‚‚€€~~~~€€€€€€€~~‚€{z{zzyy{vvz{}~€€€€€€‚}zzy}~~}{{}~€€€€€}|{{zz{|~€€€€€€€‚||{{yyyyz{|||{|€}|||~~}}€ƒƒ{wuuz}}}}~~€~yvx|~~~~€€‚}€€€€€€€€„ˆ‰ˆ‡ˆˆˆˆˆˆ††ƒ~}~~~~~~~~~}}}}}}}}}}||}}|}}~~~~~~~~~~~~~~~€€€ƒ††††‡ˆˆˆ‡†„‚yvtttttuvvz~€€~}{{{|~ƒƒ„……†‡ˆˆˆˆˆˆˆˆˆˆˆˆ††††„ƒ€~|}~€€€‚‚‚‚‚~~‚‚€~~~€€€€€€~ƒ‚~{{{{zzyz||}~€€‚„„‚|zz~€~|zz}~€€€€€}|{{zzz|~€€€€€‚ƒ‚‚ƒƒ‚~{{z{yyyyz{|||{|€€~|||~~}}€ƒƒ{utx|}}}}~~€~yxy|~~~~~€‚ƒƒ|€€€€€€€€€„…†‡ˆˆ‰‰‰ŠŠŠ‡„€~~}}~~~}~~~~~~}}}}}}||||}}}}~~~~~~~~~~~~€€€‚‚„………†‡‡‡…„‚}xtstsrrsw|ƒˆ‰ˆ†‚€€€„…„‡ˆ‰Š‹ŒŒ‹‹‹‹‰‰ˆˆ‰‰‰‰ˆˆˆˆˆˆ…„‚€~~€€€€‚‚‚}‚€~~€€€‚ƒ€€~€‚ƒ~z{{|zz{{}}~‚ƒ†…ƒ€€€{zz}~€€€€€€€}||z{y{}~€€€€€‚„ƒƒƒƒ‚{z{zyyxzxz||||{}~€~||}}~}}€‚ƒ€zuuy{}}}}}~‚{y{|}~€„…„|€€€€€€€€€‚‚……††‡‰‰‰Š‰†‚€}~~~}~~~~~~}}}}}}||||}}}}~~~~~~~~~~~~€€€‚ƒƒƒ„………†…„‚~zwtsttx|ƒ‡‡‰ˆ††„…‡ˆ‰ˆ‰‰‰‰‰‰‰‰‰‡‡ˆˆ‡‡‡‡‡‡††‡‡‡‡††††„ƒƒ€€‚ƒ…‰‹Š„€€€~€€‚€€€€€€~€€}~€€{x{}}ƒ‚€‚‚€€~{zz}~€€€€€€€}||z{z{}~€€€€‚„ƒƒƒ‚€}{z{zyyxzxz||||z{|~||}}~}}€ƒ„€ztvz|}}}}}~‚{y{|}~€‚ƒ„|€€€€ƒ„†‡ˆ‰‰ˆ‡ƒ‚€€~~}|~~|~~~|||||||||}}}~~~~~~~~~~~~~~€€€‚‚„†††…†„€zvvw{…‡ˆˆ††……‡‰ˆˆˆˆˆ‡††……„„ƒƒ„„„„…………„„……‡‡‡‡‡‡‡‡††ƒ€€‚…‡ˆ†‡†‡‚€~~~~~€€€€€€~~~€€~{|}~€ƒƒ‚€€ƒ‚ƒ€€€€‚{z|~~~€€€€€€€€}|zz{{}€€€€ƒ„„„€€~}zzzyyyyz{{{{zz|}}{||{|{~ƒytvz|}}}}}€‚‚€}z|}~~~}}~€ƒ‚|€€~~~€‚ƒ…ˆŠŠˆ‡„ƒ}}}||||~~~|||||||||}}}~~~~~~~~~~~~~~€€~~}}‚ƒ„„…………‚€~~…†‡††……ƒ„…†††„„…ƒƒƒƒƒƒƒ„„ƒƒƒƒƒƒƒƒ„„„„……„„„„„„††…ƒ„†‡†…‚ƒ„ƒ€€~~~~~€€€€€~~€€~}|~~€}}}}}€~|}€‚ƒ€€€€€€€€~{z|~~~€€€€€€€€}|zyz{}€€€€‚‚€~}zzzyyyyz{{{{zz|}~~}{||{|{~ƒytvz|}}}}~ƒƒ€~{}}~~~}}}~€€}€€~~†‡ˆˆ‰‰‡…„€~}}}}}}}}||||||||||}}~~~~~~~~~~~~~~~~||}}€‚ƒ……‡‡†„„……†…„„„‚‚ƒƒƒƒ‚‚‚€€~~€€€€€€‚‚‚ƒƒ‚„„„„„„„ƒ„…†ƒ{}„‚€~~}€~€‚‚‚€€~~€€~}|{}}||‚€€€€‚‚€€€€~}z{~~~~~~€€€€€€‚€}}~}|}~€€€€€€€€~}~~~~}zzzzyyzz{{{{{{z{~~||||{||}ƒ€ztvz|||||~€„„€~}}~~}{{|~€€~~~~‚„†ˆˆ‰‰ˆ„}}}}}}}}||||||||||}}~~~~~~€€~~~~~~~~€€€~~~}‚„…†……†……„„„„‚‚€~||{{|||~€‚‚‚‚ƒ€€}}}ƒƒ‚‚‚‚€€€}z}„„€~}}}€}z{‚……ƒ€€€€€€~|||}~€~}~€€€ƒ……„ƒ‚€€€}|z{~~~~€€€€€€€€€€~€€€€€€||{}~~~}zzzzyyzz{{{{{{z{}}||||{||}ƒ€ztvz|||||~€‚‚€~~~~}{z{|~~~€€€€~~~~}}€ƒ„†‰‰‰…~{|||||{{{{{zz||||||}}~~~~‚€~}}~~~€€€€€€€ƒƒƒ„„……††„„ƒƒ„‚~{zyyyyyz|~€ƒƒ„„„„„„ƒƒ€}{{{{}}~‚ƒƒƒ‚‚€~}€„†€~}|~„ƒ~…ƒ€€€€~~~~}zz|}~~€€‚‚‚‚‚€€€€€€~{{|€€€€€€€€‚‚‚‚€€€€€€€~}{{}|~~|{zyzzyyy{{{{{{{yy{{||||{||}€‚zuw{|||{}~€‚~~~~~|zxz{}~€€~~~~}}}~€„‡‰‰†|z{{||{{{zzz{{{{{{|||}~~~~€€ƒ„†††ƒ~~€‚‚‚‚ƒƒ…„„„„„ƒƒ„„„„ƒƒƒƒƒƒƒ~|{zyy{{|~~€ƒƒ„„„…………„„‚~}}}|}~‚ƒ…„„‚~~‚‚‚…~~~{yz}€€€~}~~~€~€‚‚€~~~~~}}{||}|‚ƒƒƒ„ƒ‚~€€|{|~€€}~~~€‚‚‚€€€€€€€~}{{~}}}|{zyxxyyy{{{zzyyyyzz{{{{{||}€‚zvx{|||{}~€‚€~~~}zxxz|}~~~~~~~~~~~}}}}€…ˆˆ†zyzz||{{{zzzzz{{{{{|||}}~~~„†Š‰‰ˆƒ‚‚‚ƒƒ„„„„„„†…††…‡„ƒ„„ƒ‚€€€ƒ‚‚‚~}|}~€ƒ‚ƒƒ„„„„„ƒƒ‚~~~~€‚„†…‚~|€~~~}„„‚}|~~~}~~}}}~€‚€}~~~}}~~~€‚‚‚€€€€€}z{|}€‚~}}€ƒƒ‚€€€€€€€€€€~}||}|{zxwwwyzz{{zzzzyyzz{{{{|{{|~€~zwy{}||{}~€‚€~~}{xvx{|~~~~~~~}}||}}}}€…‰‰ˆ{yzz||{{{zzzzzzzzz{{||}}~~€‚…ˆŠŠ‰ˆ†…„„„„„„………†††††…„„…„ƒƒƒ€~{zz~‚ƒ……‡†„€~€ƒƒƒƒƒ„„„„„ƒ‚~~~~‚ƒ„„‚€~}€~~~~}wz~~€}|~||}~||{z{{{}~}}}|{zz{}}}~~‚~~~~€}z{~~~€€~~€€€‚ƒƒ‚€€€€€€€€€€€€~}~~€€€~|{zxwwwyzz{{zzzzyyzz{{{{|{{|~€~zxz{}||{}~€‚€~}{xwy|}~~}~~~~~~~~}}||||}}„‰‹‰‚{yz{{{{{{{{{yyzzyyz{|}||~~€ƒ††‰ˆˆ‡†ˆ‰‰‡‡ˆˆ††……„„†…„…………„ƒ€}|zwvuz‚ƒƒƒ…‡ˆˆ†„ƒ‚‚„„„„ƒƒ…„‚‚€€~~€‚ƒƒ„„}zwy|}}||~~~€|vtw|~€€|{~}|z{zzz{{{|~~}~{{{zyyxwz|}}}~€ƒƒ€~~~€€z{}‚€‚ƒ„„ƒ€}}}€€€€€€€€}||~€€}{yxxxxxz{||zzzxyyyy{{z|||||~|yx{||{{{}~€€}zwx{~~~~~~~~~~~~}}||||}}„‰‹ˆ{yz{{{{{zzzzyyzzyyz{z{||~~€ƒ…………ƒ…†ˆ‰‰ˆˆ‡‡‡‡††‡‡†…„………‚zwtsrruz‚ƒ‚ƒ„†††††…„„„„„„ƒƒ‚€€€€€€‚„………„€{trtxxwxyyzuxzy{}||{zzz|{||||zzzyz|||~}{z|{yyy{{zyy|}}~~}~‚‚€~~~€€zz}~€ƒ„…„€€€€‚ƒ‚€~{{|~€€€€€€€€}||~€€}{yxxxxxz{{{zzzxyyyy{{|}}}||}}|yy||{{{{}€}zwx{}~~~~~~~~}}||||}}€…‰‰„|{|{zzzyyyyzzzzzzzyz{{||}~€€ƒ„„‚ƒ„‡‡ˆˆˆ‰ˆˆ‡†ˆ†‡ˆ‡†‡†…ƒ‚~wtppqqquz€ƒ„€}„†……††„„………„ƒ‚€€‚‚ƒƒ„……………‚|vtsuvustuy{xx„€{xxwyz|{{zxyzxwyyxxz|||}{{{{}~}}~~~}~€€€€€€€~{{~‚ƒƒƒ‚€€€€€€‚„ƒ€}|||}€€€€~|{}~€€}{yyyyyyyzzzyyzzyyxz{||}}{zz}}{zz{|z{{{}€‚€€€~~}zwx{~~~~~~~~~~}}||||}}}„‡ˆ…ƒ}||{zzyyyyzzzzzzyxyz{||}~€€‚ƒ‚‚ƒ„…………„†ˆˆ‡ˆ‡†‡‡†…„ƒ€|vsrqqrrsvxƒ„}{}€ƒ„………………„‚€‚ƒ„„……………†…„†„~ywwtuvvustw|}||{}}}{zwvxz|{zxwz|~}}|{zz|||}||{|}~~~~~}}€€€~~~~€~€ƒ„„„ƒ~~€~|‚ƒ‚||{|}€€€€€~~}}~}}}{yyyyyyyzzzyyxxyyxz{||}}{{{||{z{||{{{{}€~~~~}zwxz~~~~~~~~~~~}}}}}}}|||||~€…ˆ††ƒ||yyyyyyyyyyyyyyzzz|}}~~€€€€€ƒƒ„„ƒƒ…†‡‡‡‡‡†††„ƒƒ~{wsssssrstux~‚„‚{z|~€€‚ƒ……†ƒ‚‚‚ƒ†‡††††…„………†…‚~zzywtuvussuyz|~‚‚~{{zyvvz{zxvsu{~~zz|zyzz{{}}~~~~}}|{}~~~~~€‚€‚‚‚€€|xvx€‚‚‚{zz{~€€€€€€€€~~~~}}~~|zxxxxxxzzzzyyxxwxyzz{{~~}|{|||{z{|z||{}}}~€~}}~~yxyz~~~~~~~~}}}}}}}}}}|||||}~………†…„‚|{zzyyyyyyyyyyzzz|}}~~€€€€‚‚„„†‡‡‡‡‡…„„„‚€~{xvttttttstuvx|„„‚||}}~‚‚ƒ…„„„‡ˆ‰Š‰‡‡ˆˆ‡†…„„„ƒ~{{ywtturqruvy|€ƒƒ€|yxwvtwywusqpqsux{|}}|{zz|||}}}|{|||~~~}}~€€€‚‚‚€€€€€€{sry‚‚‚{z{}~€€€€€€€€~~~~|||||zyyyyzz{{zzyyxxwxyzz{{~~}zy|{{{{||z|{|~{{}~}}}~~{yz|~~~~~~~~}}}}}||||||||||}}~€ƒƒ…ˆˆ†„€~{zyyyyyyyyyyyz{{|~}~~~€€€ƒ„„‡ˆˆ‰ˆ‡†…ƒ„ƒ€}zxvvwxvvvuuuuvvw|„„ƒ}€€‚ƒ„†…‡‹ŒŒŒŠ‰‰ˆ‰‰ˆ…ƒ‚€€€€|{zzwtuvuttwxz~€„‚{ywvtttsrrrssuuuuuy{}}~~}~€€€~||~~~}}}|~||~~~~~€‚€€€~}€€|st|‚„„‚{z|}~€€€€€€€€~~|{|||{yyyxyy{{zyyyyxwxyzz{{~~|{z{{{{{|{{{|~‚{{}~~~~}}~~|z{}~~~~~~~~~~}}}}|||||||||||}}|}€€‚…†‡‡„~{yyyyyyyyyyyz{{{|}~‚…†ˆ‰‰Š‰‰ˆ†…„‚€~{zxwuvwyyywwvvvvwwx{‚„„ƒ€~~€}{{~€„†††……‡‡††††ƒ~~}}|{|}zxwwtutv{|xx{}|zxtsuusolmrwwvvwvtvz~ƒ„‚€~€€~}||~€€~}~€~~~}~€€€€|y{}zvx‚„„‚}||}~€€€€€‚ƒƒ‚‚‚‚€~~}|zzyxyy{{zyyyyxwxyzz{{~~|zyzz{z{|{{{}€~xy|}~~}}}}zy}~~~~~~~~~~~~~~~|||||||{||||||||}}}}}}‚ƒ…‡‡‡ƒ}zyxxxxwwyyyyzz{|€ƒ…‡ŠŠŠ‰ˆ‡‡†…„‚~}|{yxxxxxxxxxwwwwwwwxy{~‚ƒ„ƒƒ‚}vuwxxwz|}„……ƒ~‚†‡„€€}ƒ‚}xvvvtwxwrpuxyzwustwwphhpvyxyyyxwy{~~ƒƒ‚€}{|~}€€€~‚‚}~{zz|~}€|{z{}||}~|z|€‚ƒ…ƒ~}}~€‚ƒƒƒ……„„„‚‚‚€}|zyyz{{yxxxxwwxz{zz|~{yyzzy{{{{{{|€zvy|~~}|wwy}~~~~~~~~~~~~~}}~~|||||||{||||||||}}}}}}}}}‚„‡ˆ‡}zzzzzyyyyyyzz|~‚ƒ…‡ˆˆŠ‰ˆ†…„ƒƒ€}|{zxyyyyyyyyyyyxxxxxxxyy{}€ƒƒ„ƒ‚}|xusrsuvvxz|||}}}‚‚ƒƒ„††‡…ƒ€€„‚}yuvvtrqrnknsw{zwtttuoecjswxz{{zyvx{{z~}{zz}‚ƒ€€€}}}~~}{zz{{|~~{zz{|||||€}~ƒ„…„ƒ€~~~‚‚ƒƒƒƒ‚‚€€€|{z{{yxxyxwwxyzzz|~{yxxyyz{{{{{|€~yvy|~~}{wvy}~~~~~~~~~~~~~~~~~||||||{{{{||||||}}}}~~}}}}€‚†ˆ‡…‚~|{{zzzyyyz|}ƒ†‡ˆˆ‡†‡†„‚€€|{zz{zzzzzyyzzzzzzyyyyyy{{z{{‚ƒ}wolotuqsyy{{z}~‚„ƒƒ„ƒƒ‚‚‚€~ƒ‚zwwuupklnlmpw}}xuttsoihlswy{||{{xwwwtx‚€|z{~‚€€€~{||}{xuvxz{}{xxx{|~}€‚€~€€„††ƒ€€€€‚„„‚ƒ‚€€€€€€ƒ‚ƒ}{zyyywwxxwxyzyz|~|xwwwy{{{zz|}€‚~zvx|~€~{vux}~~~~~~~~~~~~~~~~~||||||{{{{||}}}}}}}}~~~~~~€„‡ˆ‡…ƒƒ‚}}|||}~€ƒ†ˆ‡‡†…„‚€~}||||{{||||{{{{{zz{{zzyyyy{{{{{|€ƒƒ€~€€yrlinrrnpux|||~‚„ƒƒƒƒ‚‚‚€~}ywwunmiopnnrvsmmptusomptwy{||{{yxwvstxƒƒ}‚ƒ‚€€}|{{}}|}zyz{{x{~~€€‚€‚ƒ…‡„‚‚‚‚‚€€€}|~~~€€€~|zyyyyxwwxyzyz||xwvwyz{{zz|}€‚€|x{|~€€~yuvy}~~~~~}}~~~~~~}}||||||{{{{||}}}}}}~~~~‚†ˆ‡†‡‡††ƒ‚~~€ƒ„†‡†…„ƒ€~|}{{{{||}}|}||||{{{{{{{{{{zzzz{{{{|~€‚„ƒ€ƒ‚|smjlmrvux{}}}‚ƒ€€€}|ƒ‚zxvrmiglqttromlmquvtqoruwxz{}{zyyxvtppty}€€}ƒ…ƒ€€}}~}}~~}yx{{||€€€€€~‚‚‚ƒ„„„‚€€€€€€‚ƒƒ„„„„‚€~~}|{{}~~€|yyxxvvwzyy{|}€€|xwvvxzzzzz{}€‚{|}~~~|yvw{}}~~~~~~}}||||||{{{{||}}}}~~~~~~€‚„†††ˆˆˆ‡…ƒ‚ƒ„…†††„‚|zz||}}}}}}}|}||||||||||||||{{{{|||||~ƒ……‡„€~|ztlhikr|€~~€€€€~~}€||…ƒ€|yvohdelrvvtroooqruutstuwwwz{~|zwvxxwuuvwxww|€‚‚‚€€€€€€€~}}}{z~€€~€€€€€~~‚‚‚‚‚‚‚€€€€€€‚ƒ„††‡‡†„‚~}|zy{{|~€€~zvwwvvvxxyz|}€€|xuvvxzzzzz{}€‚€|}}~~~|yvx}}}}}~~~~~~}}}}||||{{z|||}}}}~~€€‚ƒ……‡ˆ‰‰‡………„„„‚~{{zz{|~~~~~}}}}|||||||||||||||||||}}||~ƒ…„‡ˆ†„ƒƒ‚€|unlmv€‚~}}€~}~€}z|…„‚|ytnf`emrtwwtrrssrtuusstustyz}}xtsuwxwstwwwx|€€€€€€€€€~~}||yz}}}€€~€€€~}||‚‚‚‚€‚‚€€€‚‚‚……†‡‡†„‚~~~|{zzyz|€|ywvvvvxxy{z}€€}xttwyzzzzz{€~}~~~~~~~}{ywy|}~~~~~~}}}}||||{{z|||}}}}~~~~~€€ƒ„†††………ƒ€}|{{|{}}}~~~~~}}}}|||||||||||||||||||}}}}€„„†‰ŠŠˆ†…„„€~{vtw}€€‚~}{{{|~€€~|z||y{€‚„…€ztnfcfmsvxxwwvuttuvwvwutqruvyywrqsuxvttvvwwz|}~€€€€€€€€€€~}}}zz|zwvtw{~}|~€‚‚‚ƒ€‚‚‚‚„……„„…ƒ~{{|}zyyxwy{~‚|yvvvvxxyz{~€}xttwyzzzzz{€}{|~~~~~~~}{ywy|€‚‚~~~~~~}}||||||||||||||~~~~~~~~~~}}~‚ƒƒ‚~|{{{}}}~~~~~~~}}|||{||||||||||||||{|~~~~|‚†‰ˆ‰‹‹‹‡……ƒ€‚„€zy{~~~‚~zyyzz}€€~{xz€†‡†€ztojegnruvvxxxutttwxyz{yusuwwvrporssrqrtuvxzyz|}€€€€€€€€}}}~~€~|xtns|€~‚„„„ƒ€€€‚‚‚ƒ„ƒƒ‚„ƒ|yyyyzxxxvvz}yvttwxxxy{~€€zustwyzyyxz}~{xz}}|||zwwy}ƒ…~~~~~~}}||||||||||||||~~~~~~~~~~~~}|||}~~}{{z|||}}~~~~~~~~}}|||{||||||||||||||{|}}}}~€‡‹†~„‹‹Š…„„ƒƒ…‡‰…}z{€€€|zyyyxz}€€€~|wtx‚†‡†ztojfgnruvwwxxuttvwxy|}ywuwxwtpnnooonorsuwyzyz{}€€€€€€~~~€€}zvtx€‚‚‚‚ƒ€€€€€€‚‚‚ƒ„ƒƒ‚‚€~zwwvwxwxxuvy{}€‚}xuuwxxxx{~€ytqtwyzyyxz}€}xwz|~}}|yvz‚……ƒ‚~~~~~~~~}}||||||||||||~~~~~~~~~~~~~~~~~|}}||||||}}}}~~~~~~~~~~~~}}|{||||||||}}|||||||||}‚‰‡z|€„…ƒ€ƒƒ‡Šƒ}|ƒƒ~|||zyvwy~}~|zurw€†ˆ‡ƒ}unkhhnsstuxywsqsuwyy||zxxyxvsommljgkmqtuxz{|{z{|}€€€€~}}ƒ„‚€~zvuy€‚‚‚‚‚€€‚„‚€€‚ƒ„‚ƒ‚‚|yuuuvvvvuvwwyz|~|ywwxxxx{€}xsrtwxyyyx{~}uu{}~€~}|{y|‚ƒ‚‚‚ƒƒ~~~~~~~~}}||||||||||||~~~~~~~~~~~~~~~~~|}}||||||}}}}~~~~~~~~~~~~}}|{||||||||{{|||||||||}…‚}z}xwz|yssx{xttx‚†ƒ~}|~~}~~{ywvyz{zwtqw€ƒ……ƒ}umkhjnstuxxwpjfgijmrsvwvvwwtqokgddhgkruxz{|}|{{z{€€€„…†…ƒ~}zwyz|}~}}}{wz‚ƒ€€‚ƒ„‚ƒ‚{wtsstvvvuuvwyy{~€€|wwwwwx{~€|wrqtwyzyyx{ysu|~€~}||„ƒ‚€€€€~~}}}}}|}}||||||}}}}~~~~~~~~~~~~~~~~~~}}}}||||||||~~~~~~~~~~~~}}}|||||||{{zz{{{{|||||}{z}zrttuvtuvspoont|‚|zxw{~€~}zwvvxyzwrry€ƒ„†‚}wolihlruxxwrg_]]\`joqsqrrtsrqmhdddijmrx|~~~}{z{}€|z|~€„†}ywwwywvsuz}}yw|€‚ƒ€€€€‚‚ƒ‚‚|yvssrsuuvutuwwxz}€~zxwwwy|~~zuqqtwz{yxx{€}vty}~~}{|€„„‚ƒ~~~~~~}}}}}}}|||||||}}}}~~~~~~~~~~~~~~~~~~~~}}}}||||||||~~~~~~~~~~~~~~}}}|||||||{{{{{{{{{{{{z{|zwxzwruz||zrnoonnt}}xvvz}€~}{xwwxyyxvvz€„……ƒ}xqnjimsvxvvpcTOOMWdorsqponllikjiggjmnosvz}~|zyz}€~{{|}„‡ƒ{ywx}~||~~|wvx|€€€ƒ€€€€€€‚‚ƒ‚‚|wtrrrsuuuttuwwxx|}€|ywvww{~~zuqqtwz{yxx{~€{vty}~~}{}‚ƒƒ‚~~~~€€~~~~}}}}}}}|||||||}}|~~~~~~~~~~~~~~~~~~~~~~~~~~~~|}}}{||||||}}}}~~~~~~~~~~}|}|||||||{{zz{{{{{{{{{|}yvuzvnqwwz~~tqoopos|~vuv{}~}{zxwxxwwwxz‚‚ƒƒƒ~unjkpsuuuvqiTLNV_irttsqoifeefhigefmqrsuwz{{yxxz|~}|}|{}€‚†‰Š…|zwz}€|urrv||}~ƒ€€€€‚ƒƒƒ‚€|vtqqrstttstvvvwwz||}€~ywuvx{~yrpquxyyyyx{{uty}}~}|‚„„ƒƒ~}}}}~~~~~~}}}}}}}|||||||}}|~~~~~~~~~~~~~~~~~~~~~~~~~~~~|}}}{||||||}}}}~~~~~~~~~~}|}|||||||{z{{{{{{{{{{{||xpnqplmrssw{ztqqqooq{€yvw{|}}~}|{yxxxvvuwy|~z}€ztpqtuuvttpka\[bhmqrpnmnnkigeccccgntttuxyzywutwz}}}~€…ˆ…„„‡ˆ‡ƒ{y{|~€€|yxtorv{€€€€€€‚ƒ„ƒ‚~{urqqrstttstvvvvvyz|}€zwwwx{~xrpquxyyyyx{~ysuz}}}|‚„ƒƒ‚€}}}}}}~~~~~~~~~~~~}}}}}}}}}}~~~~}}~~~~~~~~~~~~~~~}}}||||||||}}}}}}}}~~}}||||{|}}||||||||{{{{|}|wohhklosqory{uprtsqu||wx||||~~||{zwvuttvww{{{}€zwvvututrnifbchopoljgfimqpmhe_Z[dpvxxxxxvsnmprw|‚‚~~}…Œ…~z{|}~€€€~€}vqpuz}€€~~€‚……ƒ‚}yurpqssssstvvvuuuvx{}€€|wvvx}}vqqrwxxxwxx{zttz~~}€‚„„ƒƒ~}~~||}}~~~~~~~~~~~~}}}}}}}}}}}}~~}}~~~~~~~~~~~~~~~}}}||||||||}}}}}}}}~~}}||||{|}}||||||||}}}}|}}xpkkjkmpmmpv|ytsvvtw|~|yz||||{|}|zywvtstuvvx||}~~|yxwvwwwtoljhkopolgb``chnpnjgc_`hrvxxxxurmhhnsvz~~‚ƒ~~~~~‚‡‡ƒ€}|~~€€€‚‚€ztqotwz{|~}€„…ƒ‚|xtqpqssssstvvutttuwz|€€|wvvx}~{uposwxxxwwy{~~xtvz|}€ƒƒƒƒ‚~{y{||||}}~~~~}}}}}}~~}}}}}}}}}}~~~~~~~~~~~~~~~~}~~~~~~}}}|}}||||}}}}}}}}~~~~}}}}}}{{{||||||||||||||||}zrljklmlghks{zxvuuvy}~}{{|~|z|{{{zzwvvsrruux|€}}}|{yxvvwtpnlnoqrpkd]XX]cjomidb^_fptuvxxtnhdfovwxyyz{~~~€€„‹””Šƒ~}~€€€‚€€}{sopqqty}‚ƒƒƒ|wtrqrrrrrstvvutsstwy|{wuvy|ztppswyxxxwy{~|urvx{‚ƒƒ‚‚{vy{{{{{||~~~~}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~~~~~}~~~~~~}}}|}}||||}}}}}}}}~~~~}}}}||{{{||||||||||||||||}zrljlllgdfjqy}zywxxz}}|||{||z{zzz{zyxvussstty€}}}|{yyyyyvnjmoqqqokcZVW_fhecbaaacgnqrtuurlfadkruwzz{}{xxz}‚ƒ…‰‹‰„€~}~€‚‚€€€€zwvy|~€€‚ƒƒ€{wrpoqrrrrstvvutsstw{~zusuy|~ytppswyxxwwy|~zvtux‚ƒ‚{vuy{{{{{zz}}~~}}}}||}}}}}}}}||}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}{{||}}}}}}~~}~~~}}||||zz{{|||}}}||||~~}}~~~{rkhkmkedhnr{€~{zzzz|}|{{||||{zzyzzzzywtsrrsv~€€~}|||yxyyxuoklopppmib[XZdc^VXY\^cgjmpqrstqkgcciouwz{|}|zwvy~€‚†††‡‡†ƒ€~}€‚ƒ€€€€~}~~~‚ƒ‚zupoopqqssstvvusssrv{~€€{vsuz}|wrnpsyyyyvvy{~ystw}‚ƒ}vrtz{{{zzz}}}}}}}}}||}}}}}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}||||}}}}}}}}}}||||{{{{|||}}}}}}}~~}}~~}skijkieflsv|~|}}z|}|{{||||{{zz{{zyywsqqrsv{€€|vuvwxupmljjlmnkf__iok[KNNOWagjkloqrqoiebcimrvz{|}}€€‚ƒ„‡†‡‡‡‚~ƒ‚~}}~~~~~‚}ytpoopqqssstuuussstx|€ytsuy||wqpqtwwwwvvy{|wsty‚‚yrrw{}{{zzz}}}}}}}}||}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}|||||}}}}}}}}}}}||||||||||}}}}}}}}~~~~~}ukhhijgipuy|~~}~}||{{{{|}}{{{zz{||zxrpnorsx~‚}wrstvwtpiecfjkkhdhjlh\RKHHPZefbagopokgc``cgmv{|{{}„…†ˆ‰‰‰‰Šˆƒ€€€€~}~ƒ‚~}}}~€~~~~~~€€~|wsonoppqssstuuussstw}~xttvy{{vopruwwvvvvy{{wsw~‚‚zurrw{{zyz{|€}}}}}}}}||}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}|||||}}}}}}}}}}}||||||||||}}}}~~~~~~~~ƒƒ|pjjkkoquy}~}||}€€|{{{}~||{{{yzzwtpnmnqqtz€~xrqqtvsohcdghg^_cjlmhaWQNMOYfaWW`imnkfb_]_bmu|}{{}€ƒ…†††‡ˆˆŠ‰Š†ƒ‚€€ƒ‚||}~€~~~~~~~~€~|xspmlmpqssstuuussstw}~wstvy{ztopsvwwvvvvy{{wu|‚ƒ‚‚~{wurrw{{zyz{~‚||||||||||||}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}||||||||||||}}}}}}{{}}}}~~}}~~~~}}~~‚‡‡vpnmovxz|~}{|}~~ƒ„‚}{{|}}}}|{{zyvtrqmjkoqqu{|zuqnorrqoheehlh]UXckig_WTVY^bi`WPYekjga_^\`dmv||{|„…†……†‡ˆ‰Š‰‡„ƒ„„‚€€ƒƒ}}}~~~~~~~~~€‚€}{wsollmprrrssttssrrvy~€|vssuz{xsopruwvuuuvx{yw{„„‚zvvrotyzzzzz}€„||||||||||||}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}||||||||||||}}||}}~~}}}}~~~~~~~~}}~‚†‰ƒ}xvvtux{}~}|}~€„‡‡…}}}}}}}|{zyxvsqnmlkmopqtwwxvuqpnnppqogbempm`VWYacd^YZ``_`d^ZPS`hcUSV]]`dnty~~|{}~‚ƒ‚ƒƒ…ˆ‰Š‰‰†„„„ƒ€€‚ƒ€}}}~~~}}}}~~€}{wsolkloqrrssttssrrvz€{vssuyzvqnoruvvutuvxzw{€‚‚€{xxzxx|~ƒ„||||||||}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}{{||||}}||||||||}}}}}}}}~~~~~~~~}||€†ˆ†€~~zzz|~~}{|~€‚ƒ†ŠŠ‡„€}}|~}||zyxvspnnonklorsrrqpqtrnkmopogcfkigdYQV\bca`bc_\XYVRQU^fcSJNY\`fnsx~~}}|}|~€‚„†ˆŠ‰‡††„ƒ‚ƒ‚€}{}~}||||}~€~{yvsojklopqrtttrssqrvzzsrsuyyupnpruuttstvxxz~‚‚‚€~||€€€‚ƒ„ƒƒƒƒ„„„„||||||||}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}||||||||||||||}}}}}}}}~~~~~~~~~~€„‰ˆ†„‚‚€€~z}~}|~€€‚…ŠŠŠ‡…ƒ€~~}||zyxvromkmmkjnprrttqnoqqlklnmiegic]Z[UW[a`^\_fga\XTOTX]baWMOX_ekrvz}}~~}~€€€‚ƒ……‡‡††‡„‚‚…„€~~~~}~}||||}~€€}zxvsojjknoqrtttrssrtx|€€~ysrsuwwtonpruuttsuvvz‚‚‚‚‚„„„„„„„…„„„„„„„„||}}||||}}}}~~~~~~}}~~}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}{{||{{{{zz||||}}}}}}}}~~~~~~~~~~~~‚‡‡†…‚‚€€{z~~}~€€‚ƒ„ƒ„‰‰Šˆ‡…‚~~|{zxwtrnjklmjjlorrturmonjinoonlhiicYY\Z]aa^TOZiojbZXZ__`de[PT\dkqvz|}}~~~~€€€€‚‚‚‚‚‚…‡ˆ††ƒ„††‚~}~~}|||||~€€|{xurniijnpqrtttrrrruy}€€~yrqsuwvqnnpsutsstsvy‚‚‚‚‚ƒ………„†„ƒ„„ƒ‚ƒƒƒƒƒƒƒ}}}}||||}}}}~~~~~~}}}}}}}}}}~~}}}}~~~~~~~~~~~~~~~~~~~~~~~~}}~~||{{{{}}||||}}}}}}}}~~~~~~~~~~€ƒ†ˆ…„ƒ‚‚€€zz€~}}~~€€‚‚ƒ…††ˆ‰†‚€}|zxvsqmjhjjkkkoqrtsqnmklprqppljjlf^[]abc`VMUalojb]^enmhig`Z]ckrwyz|}}}}€‚‚ƒƒ„‚‚„„†ˆ‡„„†ˆ…€€~~~}|||||~€€~{zwurniijnpqrtttrrrsvz~€}wrqsuvtpmnpsutsrstv|€„„……………ƒƒ‚€~}}‚‚‚ƒƒ}}}}|||||}}}~~~~~~}}}}}}}}}}~~}}}}~~~~~~~~~~~~~~~~}}~~~~}}||{{|{{||||||||}~~}}~~~~~~~~~~~„‡ˆ…ƒ‚ƒ‚€}yy||{|yyy|}}€‚…‡†ƒƒ‚~~|{wqnmighjnonnqrttsomnrrppopljlke]]aefaYNS]gnnjgdbfooiiiaY[dnuxzz|}}}}~€„ƒ……ƒ‚‚‚ƒ…Š‹‰…†ˆ‰„€}~}||{{{~~|zywvspljknoqrtttrrrsw|€€|uqqsuvromnrsutsssvz€ƒƒ„„„„„„„zxz{|y{€‚‚€}}}}|||||}}}~~~~~~}}}}}}}}}}}}||||~~~~~~~~~~~~~~~~~~~~~~}}||{{|{{||||||||}~~~~~~~~~~~~~~†‰‡„ƒ‚ƒ‚€|{}|zyxwwwwy{||…†„„‚~}}{xqnmkiikoqsrsssstsrssqrrrppool_Y^ehe]UT^gloligecipkcbfc\]epvy{z|}}}}~~~~~~€€€‚ƒ„‡‰ˆ†‡ˆ†„‚€~}||{{{~~}{yxvvspljknoqrtttrrrty|€zuqqsuupmlnrsttsrry‚ƒƒƒƒƒ„„}{vqrtwz{y|€ƒ‚~~||}}}}||~~~~~~~~~~~~~~}}}}||||}}}}~~~~~~~~~~~~~~~~~~~~~}}}||||||||}}}}}}~~~~~~~~~~~~~~€‚…ˆ‡…ƒƒ€ƒ‚€€~|~|xxxxvvuw{||‚„…ƒ‚}|||zrnmlllmprvvvtttttuvtqrttrrqpi`[bkne[V\ejmnkgddgmmidegdbekruz|}}~~~~~}||{|~€€€€‚ƒ……†††‡‡…‚€~~}{zzz{}~}{zxxwvtqnllmoqsssrrrruz}yspqrttplloqtssrqu|ƒƒ‚‚‚‚}vsqomorxyz|„}{}}}}}}}}~~~~~~~~~~~~~~}}}}||||}}}}~~~~~~~~~~~~~~~~~~~~}}}}||||||||}}}}}}~~~~~~~~~~~~~~€€„‡‡…ƒ‚€€ƒƒ€‚‚€}{|zxxxxvvuvz|}~ƒ…„‚}|}|zrnmopoprtxxxwvvttvtsrsuusrqqj`_gnph__ejmnmjfefikkhiihffjmquz|}}~~~~~||{z|~€€€€€€€€ƒ„……ˆ‰‡„€~€~|{zz{}~~~|zxxwvuqnlmnpqsssrrrrvz~€~wrpqrtsommpstssrtz‚ƒƒƒ‚‚}wsponmlmsyz{~€ƒ‚~{z~~~~}}|~~~~~~~~~~~~~~~}}}}||||}}}}}}}}}}~~~~~~~~~~~~}}}}}}}}||}}}}}}}}~~~~~~~~~~~€„ˆˆ…‚‚‚‚€‚~|z{yxxxxvvuvxy{|}‚„ƒƒ€}z{|yuomprtuvx{{{ywuttvurruuttrqrngekoolhilopnhgfeghffimlihkmprvz||}~}~~}}{{z{}~~~€€€€€€‚‚„†‡†„}~€}{{{{|~}|{zxxwvupnmmoqqrssrrruy}€~wrpqstqnlmpsssrsyƒƒƒ€~xsrponnmloswy{‚~{zy~~~~~}|~~~~~~~~~~~~~~~}}}}||||}}}}}}}}}}}}}}~~~~~~~~~~~~}}}}}}}}||}}}}}}}}~~~~~~~~~~€…‡ˆ†ƒ‚‚€‚ƒ|ywxxwwxxvwwwtnlmx‚…„ƒ€}zyzzxroqsuwz}~~}|yxvvvuvvssqppoqokkoppmmnqqogaacbaaadjmmklnpqux{||}|}}}zzzzyz}~~~}}€€‚ƒ„„„„ƒ~€}{{{|}|{{zxxwvuqnmnpqqrssrrruz}€{tqpqstpllmpssssv|ƒƒƒyrppooonkjmqwz{}€‚‚€}zxx~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}~~~}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~€„ˆ‰†ƒ~~‚„‚~ƒ…}ywwvvvwyyyxxqmjjr€†„‚~y{{{ywtrtwz|~€yxwvvutsssponloqpprrommprqmd__aba``glonmnpprvy|}}}}}|{{{zz{{}~~~~}~€€€€‚…††~€}{zz{||{zzzxxwvuromnqqrssrqqruz}€€~ysqpqqqnkkmqssuv|ƒ„„ƒspoooomlkjnuwy|€~yxww~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~€„ˆˆ†„„€~~ƒƒ‚€€„„€{ywwvvvwxyxwurnmmp|……‚€€€~|zxuvwz|~€|{zxvvutsqnmnnpstuutpoprsrngcccdcdhloplloqrtwz|~}}}}|{{{zz{{}~~~~}~€€€‚„…‚}~|zzz{||{zzzxxwvuromnqqrssrqqsvz}~~|wtqpqqqnkloqssw{„„ƒ„‚wponnnnmlkjnuyz}€€~yxww~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~}}}}}}}}}}}}}}}}|~~~~~~~~~}}~~~~ƒ‡‡†…ƒ‚}}€‚ƒ…ƒ€„{ywwvvuwxxutttrqmn{…†ƒ€€€€~|zxxxy{|~€~{yyyxvuutrooqsttvvwvtrqruuqjedeeefhnponoprsuz|}}}}|||{zzzzz{}~~}~~€€€€€€€~~~€~~{zxx{||{zzyyxwwtqonnpqssrqpqty|}|||vrppppomllortv{€‚ƒ…ƒ„~qnlnommlkkkntxz€€{yxvv~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~}}}}}}}}}}}}}}}}|~~~~~~~~~}}~~~~†‰‡…ƒ}|~€‚ƒ„„„€}ywwvvwvvurrry{vtu}…‡„‚€€~{zzzzz{{|}~}|{zyxwvwvtsstuwwwxzzywstvvsokihfegipqppqrtuw{|}}}}|||{zzzzz{}~~}~~~€€€€€€€€€€€}~|zz{||{zzyyxwutqonnpqssrqpqty|}||ytpopponmlmpsux}‚ƒ„„ƒ~vllmmnmmlkkkovz}€€~zxvvv~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~}}}}}}||}}~~~~~~}}~~~~‚†ˆˆ…„€}|~€‚„„„‚~‚ƒ€}ywwvxwvuropsy|{}~…‡†‚‚‚€~}|{zzzz|||}~~~~|{zzyxxvvvvvwwyy{}}|xvvwwupnkihjlrqrrtwwx{||}}}}}|{z{zzzz{|~~~€€€€€€}}{zzz}{{z{{zxvtttsrpopqrrrrorw|}}|zuroooonmlmnprw|‚ƒ„‚zollmmmlkkjilrx{€€}yuutv~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~}}}}}}||}}~~~~~~~~}}~~ƒ‡ˆ‡…ƒ{{~€‚„…ƒ~}€ƒ€|xxxxxvsspmosw}€€††ƒ€€€€~|{{{|||||}~~~~|{zzyxyyxxwxxxz{|}}|zyvwwwurqomnosttvwzzy|||}}}}}|{z{zz{z{|~~~~~€€€€€€}{xy{}}{|||{{{zxvtsssrpopqrrrrrux|}|zwrpoooonmlmnptz‚ƒƒƒ{rmllmmmlkkjjmsy|€‚~{vuutv~~~~~~~~~~||~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~}}}}}}}}}}}}}}}}~~~~~~~~}}~~€…ˆ‡†ƒ€~||‚‚„ƒ€€‚ƒ€}yyzzyxurpmmrw|}{{ƒ†„€€€€€€€~~~|}{zyzyzyzxxwwxy{}~~~}{xwvvyywutrtvuwxz|||}~~}}}}}|||{zzz{{}~}}€||{xuuy~}{{zzzzxvtrrssqpprrrqqrvz|{{ytqoooooomkmoru{ƒ‚€yqmkllmlkkjiinuy}‚‚|xvvvvv~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~}}}}}}}}}}}}~~}}~~~~~~~~~~~ƒ‡†…„}|}}‚‚ƒƒ„‚~€|y{{|zxuqonqv{}~{x}‚‚€€€€€€€€€€€~|{zzyyxyyzyxwwxz{}~~~}{|z{zz{zyxxxyz|}}}}z|||}}}||||||{||{|~~€~||}|zxz}‚}{zzzzxvtrrssqpprrrqqsx{}zywsonoooomlkkns}‚ƒ‚€|tnkkllmlkkjiintx|€‚€{wuuuuu~~~~~~~~~~~~}}}}~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||}}~~~~~~~~~~~~~~~~†‡……ƒ||}}€€€ƒ„ƒƒ„ˆ„~€‚~zz}}{zxuqorvz{|{|‚ƒ‚€€€€€€€€€~|{zzywwyy{{yxwx|}~€~~~}}}}}||}|{z{~|z{yyz|}}||}}}}}}}}~~~~~~~€}}{{|{|€‚‚~zyyyxxwusqrtrqqsrrssvz||zxtrpnnnommkikov}€ƒƒ‚€€yrmklmmmkkkjjkou{}xuttttt~~~~~~~~~~~~}}}}~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}~~~~~~~~~~~~„†„ƒ~||}~€ƒ„ƒ…ˆˆ„~}€}ywx|}|zwsqrtwxx{}ƒ…„€€€€€€€€€€~|{zzyyyyy{{zyxxx{}~~~~~~~~~}}}||}}{yxyyzz|}}||}}}}}}}}~~~~€‚‚‚€~~}}{{|}}€}{zyyyxxwusqrtrqqsrrstw{||zwsqpnnnommkkmsz€‚ƒ‚€}vqlklmmmkkkjjlpvz|vtsssss~~~~~~~~}}~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}}~~~~~~~~~~~~~~€ƒ……‚€~|}}~€ƒ†‡ˆ„‚|{~€{vsty€~{yvsrquyz}€„„€}}{{{{zzxxxz{{xwwy}~~~~}}}}~{xxz{}~|~}|||}}}}}~}}~~~~‚ƒ„ƒ‚~}}{|{{}~€}|yzzxxywusqstrqqsrssu{{||zvroooooomlkjnxƒ‚ƒ‚zsnljkllljjjiimrv|€‚{vsrrrrr~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||}}}}~~~~~~~~~~~~~~€ƒ……‚~||~}~€ƒ…†‡†‚~~}~€|wuvy~€€}{xurruz{}€~}€„€~~}}||{{zzzzz{{{xwvw{~~~€€~}}}}}||yxy{}€€~}|||}}}}}}}}~~~~€‚ƒ„„ƒ€}}|{|€€~|yzzxxywurpqrrqqsrstx{{{{xuqoooooomlknt{ƒƒƒ„~xpmkjkllljjjjjmry~€‚~yurrrrrr~~~~~~~~~~~~~~~~~~~~}}}{~~~~}}}}}}}~~~}}}}}}}{||||||||||}}~~~~€€~~~~~~€~|~€„„ƒ‚{||~~~ƒ†ˆ‡ƒ~~~|~€}xvwy}€~}{wuvy{y{}{xz‚‚€~~~~~~~~~~~~~~~~|{{z{zx{|{zyxxwy|}}~~}}~{zz|€‚ƒ‚€~}}|~}}}}}}}~~~~~~€„„„„ƒ}€€~€|{zzyxxwuqooprrrrrsw{||zyvspooooonlkknw~ƒ„„„|upllkkllmkkkijptz~€€€{xusrqqqs~~~~~~~~~~~~~~~~~~~~}}}{}}}}}}}}}}}~~~}}}}}}}{||||||||||}}~~~~~~~~~~~~€~~~€„…„ƒ‚||~}~~ƒ†‰‰…ƒ‚€€~|~€}usu{|~€|yyz|{xyyywx~€~~~~~~~~~~~~~~~~~}}}}|{y|}}|zyxwxz|~~}||}}~|{zz~‚„„ƒ€€~}}}}}}}}~~~~~~~~€„„„„ƒ‚€}|~~€|{zzyxxwuqooprrrrsuy{|{ywtrpooooonlknr{„ƒƒƒ~yspllllmmmkkkjkpv}€zvsrqqqsu~~~~~~~~~~~~~~~~~~~~~~~~~~||~~~~~~~~~~~~~~}}}}}}||||||||||||}}}}~~~~~~~~€~~…‡………|||~}ƒ…ˆ‰…„……ƒ~z}€|vsx{}}ƒƒ~}}}}zxxxxy}~~~~~~~~~~~~~~~~€~~€~~}{|}}||zzzzyy{}~€€€}}~~|zzƒ…„‚€€‚„ƒ€~~}~~~~~~~~~}~~|~€‚ƒƒƒƒƒƒƒƒƒ‚€€€|zyzzyxvtonoprrrstw|||zvvsqpooooonmlnvƒƒƒƒ‚€|uqomllmmmmkjjjnqw|€ytsrrpqvy€€~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~~~}}}}}}||||||||||||}}}}~~~~~~~~~~€ƒƒ~„††…†ƒ{{~†‰ˆ†…‚‚††…‚y|~zvx|~|ƒƒ€}zyxyz{|~~~~~~~~~~~~~~~~€€€}}|}~~}~}|{z{{z{{}~}}}}}~~}{{€ƒ…ƒ€€‚‚€€~~}~~~~~~~~~}}}~€‚ƒƒƒƒ…‡„„‚ƒ………„ƒ‚€}|zzzyxvtonoprrrsw{}}{yussqpooooomknrz€‚‚ƒ‚xsqomllmmmmkjjkosz~€|wsrrrrtx{~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}||{{||||||||}}}}~~~~~~~~~~~~}……††……‚}|„ˆ‰…‚€‚†‡†„xx€~yy||z|€‚ƒƒ€~~zwxyz{}}}}}}~~~~~~~~~~~~€€~||||~}}~~||||||z{||}|||{}~}}||}……ƒ‚‚‚€€~~~~}}~~~~}||‚‚‚„ƒƒƒƒ„„„„‡ˆŒ‹‰„||zyxwtpopqqrrvy|~|{xurrqonnnmmklov~‚‚‚}urpnllmmmmmmiimqx}€{vsrrtvx|~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}||||||||||||}}}}}}~~~~~~~~~~~}€ƒ††ƒ‚„…†‚|…‡ƒ||„…†„uv}‚{{}}zy~€‚‚€~~|zxyz{}}~~||}}}}}}}}~~~~€€~}}}}~}}~~~~}}||{{{{{{{{z|||}||}„„‚}|}€€~~~}}~~~~}‚†…„ƒ€‚ƒƒƒƒ‚‚‚…ˆŠ‹ŒŠ‡††ƒ€|yywtpopqrrtx{}~{ywtrqppnnnmmklqz€‚‚‚~ztromllmmmmmmiimry~yutssvy}€€€€€~~~~~~~~~}}}}~~~~||}}}}}}}}||||||||||||}}}}}}~~}}~~~~~~~~~~€‚„…†€‚…†„~ƒ„€zz}~€€ƒ‡†~usy€€}{~|{z{‚€{zyxz{}}~~|z||||||}}~~~~~€€€~}}}~~~~~}}}~}|||||z|{{zz{{{{}~„„‚}|}€€€€€~~}~ƒƒ€~~„„„„ƒ‚‚„ˆ‰‹ŒŠ‡……ˆ‰…~{xwspooqqswy}}|ywusrpooooonmlms|‚‚‚€~xsqolllllmmmmkjns{€€}yvtrsw|€€€€~~~~~~~~~}}}}~~~~~~}}}}}}}}||||||||||||}}}}}}~~}}~~~~~~~~~~€‚„…„~„……ƒƒ‚}z{}}}††~usy~~{z{€€€~~|{{zz{}}}~~}||||||||~~}}~~~€€€~}}|}~~~~~~}~}}}|}}}}|{zzzz{{}~‚‚€~|}~‚‚ƒ‚€€€€€€€€€€€}||ƒƒ„„„‚‚„‡ˆŠŒ‹‰…‡‡‡‡‰ˆ…ƒ|wtqpqrsuz|~}{xvsrpqonnmmmklov~‚€~xqomlllllmmmmjjou|€€}wttsv{~€‚~}~~}}~~~~~~~~~~}}}}}}||||||||||}}}}~}}~~~~~~}}}}}}~~~€‚„„„€€„†…ƒƒƒ„{{{|~‚‡†}svy‚€€~|z}~€€~}}~}}{z{{|}€ƒ‚|zz||}}~~~~~~~~}~~~~~~~~}}}}}~~}|||~~|{{yzz{{|~~~~ƒ„„ƒƒ‚€€€€€€€€€€}}}€……„‚‚‚„………ƒ‚‚‡‰ˆ‡ˆ‹Š‡€ysrrsqty}~}{zvsrqqppnnmkkjkqz€€€€€}wqonlmmmmlllkkkou~€{trtux|~}~~}}}}~~~~~~~~~~}}}}}}||||||||||}}}}~~~~~~~~~}}}}}}~~~€‚„„„€€ƒ…†………†ƒ}z{|ƒˆ†tqu|€€~|z{}~~|{z|}~|{{|}ƒ‡ˆ‚{zz||||}}~~~~~~}~~~~~~~~}~~~~~}||||}~~}|{{{{|~}}}€‚‚„„„ƒƒ‚~}€‚ƒ‚€‚‚‚€€}}~€‚ƒ„††„‚‚‚ƒ‚‚‚„„††ƒ‡ˆ‰ˆ‰ˆ‰‚yusqqv{~|ywsrpqqppnnmkkjmt|€€€}wponlmmmmlllkkkrx€zutvy{}€~€€€€~~~~~}}}}~~~~~~~||||||||||||||||||}~~€~~~~~}}}}}|}}}}~‚…„‚€€„††……ˆƒ~z{}„‡…xxy~‚€€}{}}}{zxxx|~}}}~ƒ†‰‹ˆ{zzz{{{{}~~~~~~~~~~~~~~~}}~~~|~}~~€€€~|||}}|~~€ƒƒ‚ƒ„}{zƒ†‡†††‡„€€~|}~€€‚††„‚‚ƒƒƒ…†…„ƒ……‡ŠŠ‡xtrrz}€{yvqppqqpponnllknw€€€~woommmmmmmmljimsz€€~ytuxz~‚~{€€€€~~~~~}}}}~~~~~~~||||||||||||||||||}~~€~~}}}}}|}}}}~€ƒ„‚€€„„†††}xy}†ˆ‡ƒ~~~€€€€~}}}{zxvtuy|}‚…ˆ‰ŠŒ‹…|{zz{{{{{}~~~~}}}}~~~~~~}}||}~~~}~}}|}}€€€~||||}~‚ƒ‚‚‚‚„|z|~€‚ƒƒ„†‚€|{}~€„……‚€€‚‚ƒƒ„…„ƒ€€||Œ—Œˆ{z{€~zwtpppqqpponnljinw€‚‚€€{tonlmmmmmmmljinuz€~}xux|€€{x~~~~~~~~}}}}~~}}}|||||||||||||{{|||~~~‚‚ƒ~}}}}}||}}~~}‚ƒƒ€€€‚ƒ………„€~|}…†‡…~~}~~}|}|{ywtttvx~‚„†ˆ‰‰ŠŒŒ‹‚{zzzz{||}~~~~~~~~~~~~~~}{{y||}~~~~~}}~€€~|{{{|~‚ƒ‚€€‚ƒƒ~}}|~ƒ~~{|~~€‚…ƒ€€‚‚‚ƒƒƒƒƒƒ‚‚€}€‹ŽŒ‘Ž…}{|zyvrooqqqooonmkhjpzƒ€|unnlmmmnnnmkikow}€€{vvy}€€~wv€€~~~~~~}}}}}}}}||||||||||||||}}|||~~~€ƒ„ƒ‚~}||}}}}}}~~€‚ƒƒ€€€ƒ„„„…††‡‡ˆˆ‡…ƒ}}}~~€~|{{{yvursrtw|€‚„‡‰‰‰‰‹ŒŽ‰{{{||||}~~~~~~~~~~~~~}|{|}~~€€~~~~€€~|{zz|~ƒƒ€~~€‚ƒƒ}|||}}}‚‚€~}~{|~‚…ƒ€‚ƒƒƒƒƒƒƒƒƒ„„ƒ‚„Š‘‹†ƒ~zyyyxyxwsqoqqqooonmkklt}€‚€{rmmlmmmnnnmjhkrx}€€{xy}~€€€xtu~~~~~~}}}}}}|}||||||||||||||||||~~}}„………}|||}~€€ƒ‚ƒ‚€€€€€‚„„……‡ˆˆˆˆ‡†„~|~~~~}{zzzwvtsqqqtx|‚‚…‰‹‹ˆ}{|}|}}~~~~~~~~~~~~~}}}~€~~~~~€~}}{xz{€‚|}~€„„~|{|}{{|€€}||~‚…†ƒ€ƒ…………ƒ‚ƒ……………„†ŠŽ‰‚}{vs|€€|tv}{tqpqpomnmmkjms€€zqmmlmmmnnmliiltz}€~zy{~€}tsu~~~~~~}}}}}}|}||||||||||||||||||~~}}ƒ„……ƒ||}€‚‚ƒƒ‚‚ƒ‚ƒ‚€€€~~€ƒ„ƒ€„‡ˆ‡…„~|}~}~}|zyxxuutrsrqsv{‚‚†ˆ‰‹Œ„|{||}}~~~~~~~~~~~~~~€€~~~}}}}||}~€~}}{yy}€~}{|}€ƒ‚€~}~}}~€€€~~}||~‚…†ƒ€€‚†‡‡……ƒƒ…„„„„…†ˆ‹Œ†~vqq|„ƒ}wy|wsqqpomnmmkinw‚‚€€xpmmlmmmnnmliinu{~€~||~€€€€~xssw~~}}~~}}}{||||||||||||||||}}}}~~~~~€‚…†…}|~€ƒ„„„††………ƒƒ‚„ƒ}}‡ˆ…„„~|||}}|zwvxvtuusssrsvx|€‚ƒ„†‡‰‹ŒŽ‹|{|}}}~~~~~~~~}}~}}}}|}|{zxz{|}{zz|€€~{||{|~ƒ†ƒ€€€~€€~}{}‚ƒ…„‚„ˆ‰ˆ‡…„†††……„„…‡ˆŠ‡}uos}ƒ€~~vv|zsrpppnmkkjpy€€‚€€~wpmmllkmmmkjhinv|~}€€€€€€zqru|~~}}~~}}}{||||||||||||||||}}}}~~~~~€‚…†‡ƒ~‚„…„„……„„„‚‚€€€€€‚ƒ~z}‡ˆ…„„}{}}}}|zzyvtsuvutttuvxz|€‚ƒˆ‰‹‹ŽŽ‰~}}~}~~~~~~~}}}€€~}||{|{{{{|{yzz}~}{zz|€€~{|||~„†„€€~~€€~~}~€‚ƒ…„‚„ˆ‰ˆ‡…„†††…………††ˆŠ‡€vqqy}|z~|||~|yspppnmkkkqz€‚€{uommllkmmmmlgipx}~€€~~€€€}vqty}~~~~~~~~}}||||||||||||}}}}}}}}}}~~~~~~„…†„„„†…ƒ……„„ƒ‚~€€€€€ƒƒ€|}‡Šˆ‡†‚~~~}{{zzxuvvwwvxuvyy{{}€…‰Š‹Žˆ~}~~~~~~~~}~€€|{zz{z{{}~~~}|{|}€~{xz}€|z{|}~€„†ƒ~~€‚‚‚€~}|~€‚„…„‚„‡ˆˆ‡†…†‡‡‡††………†‰†„}tuy|€€‚ƒ€~vpppnmljkr}€€|rlmmllllmmljhkty~€}vrtx|}~~~~~~}}||||||||||||}}}}}}}}}}~~~~~~~‚„……„‚„…„‚‚‚€~~€€€€€€€‚ƒ‚~|€‡Šˆ‡‡…€}|{{|||yxvuuvxz{{{||}„‡‰ŠŒŽ‡€}~~~~~€}{zyyzz{|~€€€~}~€€€~{xz}€|yy{|~€…†‚~~~€€~~}|}‚„…„ƒ†‡ˆ‡ˆ†„†‡††††††‡‡‡…‚||~‚€€‚„ƒƒ‚€~uppnmljkr}€€|tnmmllllmmlihltz~€zutvz{}€€~~~~~~~~~~~~}}}}|}{{||||||||}}}}}}}}~~~~~~~~}€‚†……†ƒ„ƒ‚€€€€€~~~€€€€€€€€‚ƒ~}€‡Š‰ˆ†„ƒ€|{zz|}}zxuttuyz||~}~€€€€‚…‡ˆŠŠŒŒŒ‡~~~€~~~€~|{yyxy{}}€€ƒ‚‚~€€€€zw{}~zwyy{‚„„~}}~€~||}~‚„ƒ‚€„†‡ˆˆ†ƒƒ††††…‡‡‡ˆˆ…‚€}|}‚€€‚…†„€zroonkkms~€‚€€}uollllkmmmmjjmw}€~}~€~wtuxy{~~~~~~~~~~~~~~~~}}|}}||||||||}}}}}}}}}}~~~~~~}€‚„…†„†ƒ‚€€€€€~€€€€€€€€ƒ€‡Š‰ˆ……„ƒ€}zxxxz||{xusrsvz||~€€€€‚†ŠŠ‰‹ŒŒŒŒ†€~~~€€~~}|{zzyz|}}~~‚…‡†…ƒ€€~~|{}~€~zwyy{‚„„~}}}}~~}||}ƒ…„‚€ƒ„‡ˆ‡††…††††…‡ˆˆ††…‚€ƒƒ‚…………ƒ‚}uponkkmv~€‚€€}tnllllkmmmmjiow}€~}~€ysuvxy{~~~~~~~~~}~~~~~~~~~~}|||||||||||}}~~~~}}}}~~~~~~~~€„†††„ƒ€~~~€€~~ƒƒ€†Š‰‡†…„{wvuuvy{{{wusssuy{}~€€~|€…ŠŒ‹‹ŒŒŒ‰„~~}}~}||{{{|}~~~‚‡‰Š‰‡…ƒ€~~||}€}xvwy|‚ƒ„~}|||~~}}{{}ƒ……„‚‚‚ƒ„†‡††„……………†ˆˆ†…„‚‚‚ƒƒ„„‚ƒ††……„‚€zspnkjnx€‚€€|umllkkmmnljijqy|~}}~€‚‚}xuxyyy{~~~~~~~~~}~~~~~~~~~~}|||||||||||}}~~~~}}}}~~~~~~~~€ƒ…††…„‚~~~€€~}~€‚‚‚ƒ‰Š†„€{xrooruy{{{yvsssuy{}}}~€€|{|†Š‹‹‹‹‹‹Š…€€€‚~~~}}|||{{||}}ƒ†ˆˆŠŠˆ†„‚€~~|}€€~yxyy|~€‚„„~~}}~~}}||}‚ƒƒ„ƒ‚‚‚‚‚ƒƒ„†‡‡…ƒƒ………†‡‡…„„ƒƒƒ„„……†‡ˆˆ‡…ƒƒƒ‚{wtqpsz€‚€€|slllkkmmlkjhks{}~}}~€‚zwvyzyy{~~~~~~~~~€€~~~~~~~~~~~~}}}|||||||||||}}}}}}~~~~~~}}~~~~ƒ„……‚€~~~~~€€}|…†‚|}|xqnoty|}}zzvwvwyz||}€|{|}„ˆ‰Š‰‰ˆ…€€‚€~}}}}||{{{{}ƒ…‰‰ŠŠŠ‰Š…„~}}}|}|zwxx{~‚ƒ‚‚~~~~€€~|}~€‚ƒ‚‚‚ƒƒ‚‚‚„‡…ƒ„„„……††……„ƒ„„……††††††††„„ƒƒƒ‚€}{yy~‚€~{rnkkklmmlkjimv|~~~‚‚{wuxzzxxz~~~~~~~~~~~~~~~~~~~~~}}}|||||||||||}}}}}}~~~~~~}}~~~~‚ƒƒ€~~~~~~~€‚‚|€‚€ƒƒ~xrorvz~~~~|||||}~~€}|{z|}~€„ˆ‹ŒŒˆ…€~~}}}||}}}~€‚„…ˆŠŠ‰‹‹‰ˆƒ‚€~||}}€€|zwxz}‚‚ƒƒƒƒ~~€€~}‚„‚ƒ………„„„‚‚‚~‚„…ƒ„…„……†††…„„………………††††††……„„„ƒ„„‚€‚‚‚‚‚€~{rnkkklmmlkihmw}~|}‚‚{wwyyywwz~}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}||||~~~~~~~~~~~~}}~~~~~~~~€€€€~~~~~~€€~}}}}}~~|}€ƒ‚„„„ƒ}vpqvy|}~~~}~€‚‚‚~}|{{||{|€‚…ŠŠ‡„€‚€~}||{{{||}€„„…†ˆ‰ŠŠŠŠ‰†ƒ€€~||}€€}|zxy{~€ƒƒƒ„„ƒ€~~~|}€ƒƒƒƒ„„ƒƒƒ…„ƒ†ƒƒ€~ƒ…ƒ„„……†…………ƒ‚ƒƒ……„……†‡‡‡‡‡‡††††„„„ƒƒƒ„„„„‚€€yrnkkklnnlkgipx~}}€}zwyyyxvvz~}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}~~}}~~~~~~~~~~~~}}}}~~~~~~~~~~~~~~~~~~~~~}}}}}~~ƒ‚~{~€ƒ„„ƒƒ‚}usux{|~~~~€€€€€~}|z{{||{|}€€‚‚€€€~}|{|{{{{{„†‡‡‰‹ŠŠŠŠ‡„€~}zz|}€€~||zxyz}}}€‚‚‚ƒƒƒ€~~~~€ƒƒƒƒ„„„„ƒ……††††……‚‚ƒƒ„„……†ˆˆ†~€€€ƒ†………………††††„„„ƒƒƒ„„„„„‚€€yqlkkkllllkikqy}~}}€€|yxyyxwvvz~€€}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}~~}}~~~~}~~~~~}}}}}}~~~~}}~~~~~~}~~~~~~~~~~}}}}}}}}}}~‚€}z}„„ƒƒƒƒzsrvyz}~~~}|{{{{{zzz|~}~‚‚€€}|z{{{z{{|€‚†ˆˆ‰‰‹ŠŠ‹Šˆ…~|zyz|~€€~|z{yzzz{}€ƒƒƒ‚€€€€~~|}€‚‚ƒƒ„„ƒƒ………………„„„„„„ƒƒ„††‡†…€yux|}~€ƒ„…‡„………„……„…„„„‚„„……„„ƒƒyqmkkllllkjilt{}}}€€‚|yyzzxvvvy}€€€~}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}~~}}~~~~}}~~~~}}}}}}~~~~}}~~~~~~}~~~~~~~~~~}}}}}}}}}||~‚‚{z}‚„ƒ‚„„xtuxy{}{|}}~}||{{{zzz|~}~€‚‚‚€~}|{zzz{|}~„‡ˆˆˆˆ‰ŠŠŠ‰‰‡ƒ}zyz|~€€}}{|{zyy}€‚‚‚€€‚‚€~€€‚‚ƒƒ„„ƒƒ„„……„„„„„„ƒƒ„„†………‚}tnpx}~~}~~€ˆ‹Š†…†„„‚‚ƒ„„……„ƒƒƒƒ„„„„ƒ}tnllllllkjimu|}€€€|yy|€xtty}€~~~~~}}}~~~~~~~~~~|}}}}}}~~~~||}|}}}}}}}}~~}}}}}}|}~~}}}}}}}}}}~~~~}}~~~~~~~~~~~~~~||}}||||}}}~€‚~xy~ƒ„„„„ƒ~ww{yy}€zy||}~€~}}}||{{zyz||€~}|{zz{z~€‚‚ƒ„††††ˆ‰Š‰‰‰ˆ†ƒ|zy}~~~~~}|zy{~€€‚‚‚‚ƒƒ‚‚‚‚‚ƒ„ƒƒƒƒ„„ƒƒƒƒ„„„„„„„†„ƒ€~zrnntz~~}}~~‡ˆ„„„„„ƒ€ƒ„†ˆ†ƒ€ƒ„„……ƒ€ysonmmmmkihnw~~}€€€{yy}„ƒytty~€~~~~~}}}~~~~~~~~~~~~|}}}}}}~~~~~~}|}}}}}}}}~~}}}}}}{}}}}}}}}}}}}}~~~~}}~~~~~~}}~~~~~~~~~~}}||||}}}~~‚€|xz~‚ƒ„„ƒ‚~~{z|~|z|}~~€~}}}||{{zyz|}€~}|||{~€‚‚‚‚„………†‡‰‰ŠŠ‰‰†‚}zy|}||~~~~~€€‚ƒƒ‚‚ƒƒ‚‚ƒ„ƒƒ‚‚ƒ‚‚‚ƒƒ„„……„„ƒ„‡ˆ…~usu{{}}y{~~Œƒ~‚ƒƒ„‚€ƒ„†‡ˆ‡‚€ƒƒƒƒ„ƒzsponmmkiipx~~}€‚€~zzz~„ytty~‚€€~}}}}~~~~~~~~~~~~~~|}}}}}}~~~~~~~~~~~~}}}}~~~~}}~~}}}}}}}}}}}}|||~~~~~~~}}~~~~}}}}}}}}~~}}}}||}}~‚‚€{xz~„………ƒ~{}}}~~}}|||||{zy{~€€€~~~}}}|~‚ƒ„…ƒ‚‚€€‚„††ˆ‰‰‰‰Š‰ˆ„}{||}}~~€~~~€€€€€‚ƒƒ‚‚‚‚ƒƒƒƒ‚€€‚‚‚‚„„…………„…ˆˆ†}sw}~~||~ˆŠ€zzz}€‚‚~~ƒ†‡‡ˆˆ}~‚‚ƒ„„ƒ‚|vronmjhhqz~}€zwxzƒƒ{wttx|‚€€~}}}}~~~~~~~~~~~~~~|}}}}}}~~~~~~~~~~~~}}}}~~~~}}~~}}}}}}}}}}}}|||~~~~~~~}}}}}}~~~~}}||}}~~}}}}}}}}}}‚|xx}‚„„„ƒ|~‚‚}~~}||||{{{|€€~€~}~~}}}|~~„†‡…„‚€€‚……‡ˆˆˆˆ‰‰ˆ…|||}}~~€€€}}~€€€€€€‚‚‚‚‚ƒƒƒƒ‚€€‚‚ƒƒ„„……†††‡ˆˆ…€uw|~~yy~ƒ‹‡zyyyyz{~‚‚€‚‚‚„ˆ„€}}€‚‚ƒ„„ƒ‚~xtqnkglv{€}{x{‚}wustx|‚‚€€~~~~~~~~}}~~~~~~}}}}}}}}~~~~~~~~~~~~}}}}}}}}~~}}~~}}}}}}~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}~}‚€|xz}~„…„‚€€~€‚€~€€~~}}{zyz~€€~~~~}|}}}}}€‚…‡…„€€€„…††ˆˆˆ‡‡‡…„‚}|}}~~}€€€€€‚‚‚~||€€€€€€€‚‚‚‚ƒ€€€€€‚‚‚„„„„††‡ˆ‡‡†‚yw{{{xz…„zwvwyyyyy|~}{}~€ƒ…‡‡}|‚‚„„„„‚~ztolkmu}€€€€}zx|‚xrqssw|‚‚€€~~~~~~~~}}~~~~~~}}}}}}}}~~~~~~~~~~~~}}}}}}}}~~}}~~}}}}}}}}}}~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}‚}zy{}€‚„„€|{}~~€€~~}}{z|€€€}}|{|||{}}}||€‚ƒ‚€€€ƒ„……†‡‡†„……‡†ƒ€~~}}~€€€‚‚‚~|}€€€‚€€€‚‚€€€€€€‚‚‚‚‚ƒƒ„…„„‚}wzzwu{‚‚|vuvwvvvvuqqszƒ„†††‡†ƒ~{~€€ƒƒƒ‚ƒƒƒ€{umjpx~€€€€|y{}vttspty‚‚}}~~~~~~}}}}~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}~~}}}}}}}}~~~~~~~~~~~~~~}}}}}}}|}}}}}}}}}}}}}}}}}}~zxy}€€ƒƒ€€}{|}~~~~~~}|{{€€~~~~{zy{||~~~~~~€€€€„„„„…„„„…‡ˆˆ†„ƒ~~~€€€ƒ‚€|}€‚„ƒ~~€€‚€€€€€€€‚ƒƒƒƒ‚€€‚~ywtrrz€}vtttutttuokrz„†………‡ˆ‡†‚~~~ƒ„‚‚ƒ‚‚€zqnty}€€€€€||y}‚ysrrqoty‚‚~~~~~~~~}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}~}}}}}~~}}}}}}}}~~~~~~~~~~~~~~}}}}}}}|}}}}}}}}}}}}}}}}|||{vx|~‚‚€}|}~~~~}}~~~||}€}~~~~}{||{|{}~~~€€~~~€€‚‚ƒ‚‚ƒƒƒ„…†‡‡…„ƒ€~€€ƒ‚€~€ƒ††…‚€~€€‚€€€€€€€ƒƒ„„„ƒy{|~~{uqqryzutttuuvtnlt|~~€…†……‡ˆˆ‡…€€~€‚ƒƒ‚|vsuz}€€€€~||€{vsssnnuz‚€€~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}~~~~}}||}}}}}}~~~~~~~~~~~~~~}}~~}}}}}}}}}}}}||||||€€€€€}yxz|‚‚}||~}}~~~|}~}}~~}}|z{zz{||~~~~~}~~€‚‚‚€‚ƒƒ„†‡††„„ƒ€€‚€‚‚„†‰ˆ…‚€€‚‚ƒ„€€‚ƒ{wy|}~€€‚€zposz{xuttuuttojq{~~~~€††††‡‡…ƒ‚€€€|y~€€‚‚zuw{~€€~}~„€{vssurlksx‚€€~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}~~~~}}}}}}}}~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}~~||||||}}|~~{zz{~€‚}{{|~~~~~}~~}}~}}|{{{zz|~~‚‚~}~~€‚‚‚€€€€ƒ„†‡……„„ƒ„„„‚€€‚~‚„…‡‡†‚€€‚ƒ„ƒ€€€€‚„ƒ€~€€ƒ‚„„sprz{wtttuuuqkr{}~~~~}€†††‡‡…„„€yty}€‚‚€|xy|~€~‚‚|vssssqkmv{€€€€~~~~~~}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}~~~~~}zzzxyz|~~€zvy}‚‚€{z{|}~}~~€|}}~{z{~~|||}~|}~€~~~~€€€€ƒ„„„‚ƒƒƒ„††„‚‚€€‚€~€‚ƒ††…ƒ€€€€„…„‚‚ƒ‚ƒ…„„ƒƒƒƒ‚ƒ††xssz{wuutturlly~~~~~~~‚‡……††„€€€zpsx}€‚}zz|€€€€~€~|xusqrrmjmw}€€€€~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~}zyywwxy|~€}zz|€€{z|}}}||~~~~{{{zz{|||||~~}}|}~~€~~~~€€€€€€€€€€‚‚‚€ƒ…………ƒƒ‚‚€€€‚€~€‚ƒ††…ƒ€€€€€ƒ„ƒ‚ƒƒƒ‚ƒ…„„„„ƒƒ‚ƒ……‚}wuyyvtttttojr}~~~~~~~‚…„‚„„‚€€€{qpt{|{{}€€€€~€|xtqqqqrqsx}€€€€€€€~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}~~~~~€€€€~~~~~~~~}}}}~~~~}}~~~~~~}~~}yxxvwwxy|€€€zx|€|y{{zzy}~}}zzxyzz{{||}}€}|}€€~}|||}€€€€€~~~~~‚ƒ„„ƒƒƒƒ~€ƒ‚€€‚€‚†……ƒ€~€€€‚„ƒƒ‚‚‚‚„…„„……„ƒƒƒ‚‚ƒ€zxyyustutrjlx}~~~~~~~„€€€€€‚€€|sqrx}}|}€€€€~€|xxxwustyxz‚‚€€€€~~~~~~~~}}~}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~€€€€~~~~~~~~}}}}~~~~}}~~~~~~}~~}yxxusstvx{|~€€€}||}}zxxz|~~~|||{zyxxz{||}~~}}}~€€~}||||}~~~~~}~~~~€€€‚‚‚€€€‚ƒ‚€€‚ƒ†…ƒ€~„‚‚„ƒƒ‚‚‚‚‚„„„……„ƒƒƒywyxtsssrnirz}~~~~~~~€€„„‚€€{qpquz~~}|}€€€€~|xwy}€~~€‚„„……~~~~~~~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}~~~€€~~~~~~~~~~~~~~~~~~~~~~~~~~~~|zzvtqrrvwy}~€€~||{zz}€~~~||{xxxy{{{{|}}~}}~~~€~}|||}|||}~~||}}}}}}~~~~~~€€€€€€€€ƒ„„ƒ‚€‚‚€ƒ„ƒ~~}~~}‚ƒ‚ƒƒ‚‚„„‚‚ƒƒ„„„„„„‚€€~xvxwusssqkku}~~~~~~~~}~~€„†ˆ„ƒƒ€€uoquw|}}}€€€€€{xuw{~‚„ƒ‚‚„„……†~~~~~~~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~€€€€~~~~~~~~~~~~~~~~~~~~~~~~~~~~{zzwtqqqrvy||€€~|{z|~€€}}}}{yxwwx{{{{||~~}}}~~}~}||{|{{{|||||||}}||}~~~~~~~~~~€‚……„„„ƒ‚‚‚~~„ƒ€~}~~|}ƒƒ„„„„„„„ƒƒ„„ƒƒ„„„„„„‚€€ytrxwvtssqjnz~~~~~~~~~~…‹ˆ‡…ƒƒ‚~vrswy|}}}€€€€€~zxyz€‚‚ƒƒ……‡‰Š‹~~}}~~~~~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}~~~~~~~~~~~~~~~~~~}}}}}~~~~~~~~~~~~~~|xvusrqqsv{}~~|~~€€€{{|~€€}zyvwyyxxyz{{{||}~~~~|}}~~~~}{{{{{{zz{{{{||||{|}}}}~~||}}~~~€‚„…„…ƒ‚‚ƒ„„‚€~ƒ‚€€€}}€ƒƒ‚‚ƒƒƒƒ‚„„ƒ„„„„„„ƒƒ‚€{xuuuwwuusojoz~~~~~~~~~…‹……††ƒ‚€~yy{|€€€€~{y|~€‚ƒ„„‡ˆ‰Š‹~~}}~~~~~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}~~~~~~~~~~~~~~|xvttsrrtx{|{{z{{|~~€}|yxwwwxzyyyz{{{||}~~|||~~~~}{{{{{{zz{{{{{{{{{{||}}}}}}}}}}}„††…ƒ€€€‚ƒ„‚ƒ†…ƒƒ€€‚€€€€‚ƒ„„„„„ƒƒƒƒ‚~{vvuutvvvutpkqz}~~~~~~~~‡‰ƒ€‚…†ƒ‚€€€€€€€€€€€€~{{~€‚ƒƒ…„†††‡Š‹~~}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}~~~€€€€~~}}~~~~~~~~}~~~~~~~~~~~~~~~~|zwwwtsstz|||z{{||}|{}€~zxvwxyzyzzyz{}}||}}~€~}}}}}||zzzzzzzzzz{{{{{{{{{{{{{{{|||~€‚……„~~~~ƒ„‡‡†…ƒ‚‚€€€‚‚€}{|}~~‚„„ƒƒƒƒ‚‚€}{xuutuvwwvsqnqz}~}}ƒ€‚…ƒ€„„ƒƒƒƒ‚‚ƒƒ„„ƒƒƒƒ‚€}|}€„…‡‡„„„„†ˆŠ~~}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}~~~~€€€€~~~~~~~~~~~~}~~~~~~~~~~~~~~~~|zwxwuttvy|||z{{|||~~€€}{yvwxyzzyxyz{{|}}}}~€€}}|{{{{zzzzzzzzzz{{{{{{{{{{{{{{{|||~€„…ƒ~~~~~~~€€€ƒ„„„ƒ‚ƒ‚ƒƒ„„„„ƒ‚}~}}}‚„„„„ƒƒƒƒƒ€}{yutttuvvsolnx‚„…‡‡†…ƒ…†…‚‚‚ƒ„„„„ƒƒ‚‚ƒƒ„„ƒƒƒƒ‚€‚„†‡ˆˆ‡…ƒƒ†ˆŠ~~}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}~~~~~~€€€€~~~~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~|{xyyxvwy|||||||||{|~€}||zwyzzyyxyyz{|~}}}}~}~€€}}{{{{{||zzzzzzzz{{{{{{||||||||||||}~€‚€~}}}~~~~~~€€€€€€€„†‡‡†‡‡„‚€€~~‚ƒƒƒƒƒƒƒƒƒƒ€~zwtsttopoov„…††††††…„…………„„„„……††„ƒ‚‚‚‚‚‚‚‚ƒ„ƒƒ‚‚…„„‡ˆˆ‰†„‚ƒƒƒ„ƒ†‡ˆŠŠ~~}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}~~~~~€€€€~~~~~}}~~~~~~~~~~~~~~~~~~~~~~~~~~|{xxxxxy{{||||||}|~€€zxxyyzzz{{{|zzz{}}{{{{{{|}}}{{{||||{{zzzzzz{{{{{{||||||||||||}}€~}|}}~~~~~~€€€€€€‚ƒ†‡‡‡†…„„‚‚‚€€‚‚‚ƒƒƒƒƒ‚‚€|zwusvwz~‚„…†…………„ƒƒ…………„„„„„„„„†„„„‚‚ƒƒ‚…†‰ˆˆˆ†„ƒ‚€€ƒƒ„„…†‡‡‡~~~~}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~}}~~}}}}~~~~~~~~~~~}~~~~}}~~~~~~~~~~€€~~~~~~~~~}~~}}~~{zyxxwyz{{||{||||}€€}yttvw{{{|}~}|zzzz|{|zz{||}~}}{{z{{{||{{{{z{{{{{{{|}|||}}}~~}}}}}~~}}}}}}~~~~~~~~~~~~‚‚ƒƒƒƒƒƒƒƒ‚ƒ‚€€€‚ƒƒƒƒƒƒƒ„„‚‚€€}}~€€‚„ƒ……………„„ƒƒ„„‚€‚ƒƒ„††……‚€€ƒƒ…„„‡ˆˆ†„……ƒƒƒƒƒƒƒ„„…………~~~~}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}~~~~~~~~~~~~}~~}}}}~~~~~~~~~~~~~~~~~~~~~~~~}}~~}|zyyyyy{{||{||{}‚‚€{vttw{||~~~}{zzzz{yzz{z||{}}}|{z{{{||{{{{z{{{||||}}|||}}}}}~~}}}~~}}}}}}}~~~~~~~~~~~~‚‚ƒƒƒƒƒƒ€€€~~€‚‚ƒƒƒƒƒ„„ƒƒ„‚‚ƒ‚‚ƒƒ„…‡ˆ‡‡‡‡„‚€}|z~~€‚‚„…††……ƒ‚€€€€‚ƒƒƒ…‡ŠŠ†……ƒƒƒ‚‚‚‚ƒƒ„„……~~~~}}}}}~~~~~}~~~~~~~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~~~~}}}~}{yyzyyyzz|||{{|~‚‚}zwuuvz|}{}}|{xxxyyzxy{{||||||zzz{{{||{{{{{||}}}}}}}||}}}}~~~~~~~~~~}}}}}}}}~~~~~~~~~~~~€€ƒ‚ƒƒƒ€~~€‚ƒ„„„„„„„……ƒƒ„…„…††‡ˆ‡†…„€~{zzyy|€‚ƒ„„‡‡‡‡‡††„ƒ€‚‚‚ƒƒƒ„ˆŠ‰…„‚€€€€ƒƒ‚‚~~~~}}}}}~~~~~~~~~}~~~~~~~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~~~~}}}~}{yyzyyzzz{{{{|~‚‚€~|zwuuux{{{{{{zxxxyyzz{yyzz{{{{zzz{{{||{{{{{||}}}}}}}|}}}}}~~~~~~~~~~~~}}}}}}||~~~~~~~~~~€€€€€€€€‚ƒƒ„„„„„„…………„……†‡‡ˆ‰†ƒ‚€}{|…†ˆˆ‰‰‡††††††…„‚‚‚‚ƒƒ‚ƒ†‡‰…€€€€€€~~~~}}~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~}}}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|z{{zzzzz{{zz|‚‚€~{zz|zwuvvvy|||}|yyvvwxzz{zzzz{{{{{z{{zz||||{{{|}~}}~~}}}}}}~~~~~~~~€€€~}}}}~~~~}}}}}}~~~~~~€€€€€€€€€€€€€€€€‚‚ƒ……„„………†„„ƒƒ„„„„„……„„„„ƒƒƒƒ„…†‡‡†……‚ƒ…†……‡†„~‚‚ƒƒƒ„……‡†ƒ€€€€€€€~~~~}}~~~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~}}}}}}}}~~~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~~€|z{{|{zzz{||~‚ƒƒ||{{yxvqrv|}|||{yywwwwzz|{zzz{{{{{{zyzz{{||{{{|{|||~~~~}}}}}}~~~~~~~~€€€€~~~~~~~~~}}}}}}~~~~~~€€€€€€€€€€€€€€€€€‚‚ƒ…„……………††……„ƒ„„……††…………„„„„„„„…„„„ƒƒ€„†††‡ˆ‡…‚‚‚ƒƒƒƒ„…‡‡…ƒ€€}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}~~~}}~€€}|{{~}|{z{{~‚ƒƒƒ|zyzzywvtqw|~||zxwywwuwxy{{zzy{{{{{{{zz{zz{{}}}~|{}}}}}}}}}}~~~~~~~~~~€€‚€~~~~}}}}}}}}}}~~~~~€€‚‚ƒ„……‡‡…………†‡…ƒ………†‡†‡‡‡‡††††„…„„ƒƒ„„‚€€‚„†‡ˆˆ†…ƒ€€‚‚ƒƒ‚‚ƒ„…†‡…ƒ€~~~~}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}~~}|{{{z||{|ƒ„„€|z{{zyyyxvqpv|}{yvvwyxxuuuxzzzzyzz{{{{{zz{{{{{{{|}|{||||||}}~~~~~~~~~~~~€€‚‚‚‚~~~~}}}}}}}}}}~~~~~~~~~~€€‚‚ƒƒƒƒ„…………†‡‡†……ƒ…†‡ˆˆˆˆˆ‰‰ˆ‡…ƒƒ‚‚ƒƒ€€€€ƒ„…‡‰‡…ƒ‚‚‚‚ƒƒƒƒ‚ƒ„…†……‚€}}}}}}~~~~~~~~~~~~~~~~€€€€~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~|||{{{{{z}ƒ…ƒ}|}|{zxwspotx{zyvvvwwxyyxwxxyzzy{{{{{{{||}}}|||}}}}}}||}}}}~~~~~~~~~~~~€ƒ‚‚€~~~|}}|}}}~~}}}}}}||~~~~~~}}€€€€€€‚‚‚‚ƒ……††‡‡‡†…„„„†ˆ‰‰‰‰‰‹Š†…ƒ‚€€€€€~~~‚…†ˆ‰‡…ƒ‚‚‚‚ƒƒ‚‚‚ƒƒ„„……„‚~~€€€€}}}}}}~~}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~€€€~|~}{{{{|}‚‚€~||~€|ywuqnnrvyyyvvvuwy{{{ywwyzzy{{{{{{{||}}}|||{{{{||}}~~}}~~~~~~~~~~~~€€‚‚€~~~}}|}}}||}}}}}}~~~~~~~~€€€€€€‚„……†‡‡‡†„„„…†‡‡‡ˆˆ‡…‚€}~~~„…††ˆ†„ƒƒ„„ƒƒ‚‚‚‚‚ƒƒ„………„‚€€€€}}}}}}~~~~~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~||}~~~~~~~~~~~~~~~~~~}}~~~€€€€~~~~~~€€}|{z{z}€}{||~‚‚€}yxwtrpquyyxwuuwy{}}||zyyyzxzzz||{|}}}}||||{{{{zz{{}}}}|~~~}}}}}}~~€‚€~~~}}}}}}}}|}}}}}}}~~~~~~~€€€€€€€‚ƒ…†…‡‡‡……„„„…‡†…„€~~~~~}}~~~~‚ƒ…†ˆ†…„„„„ƒ‚‚‚‚‚‚„„……‡…„‚€€€€€}}}}}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|}~~~~~~~~~~~~~~~~~~~~€€€€~~~~~~€€€€~|{z{~€€~}|{||~‚‚~zyxusppsuxxwwvwy{|}||z{yyywxyyzz{|}}}}{{{|||||{{{{{{{{{|||}}}}}}~~€‚‚€~~}}}}}}}}|}}}}}}}}}~~~~~€€€€€€€€€‚„……††……„„ƒ„††„‚€~}~~}}}}~~~~ƒ„…‡†…„„„„ƒ‚‚‚€ƒƒ„†ˆˆƒ€€€€}}}}}}~~~~~~~~~~~~~~~~~~~~~~~}~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€~~~~~~€€|{{~€‚ƒ‚|{{{|}€‚€~}ywwsooqsuwxvwxxyy||{||zyyxwwxyyyz{{}}{{z|{{{{zzzzzzyyzz{{{|||}}~~~~~~‚ƒ‚‚€~}}}}}}}}}}}}}}}||}}~~~~€€€€€€€€€€€€„„…‡†…‡††††………‚€}}~~}}|}}~€ƒ„……††„ƒƒƒƒ„‚‚€€‚„„†‰ˆ†ƒ€€}}}}}}~~~~~~~~~~~~~~~~~~~~~~~}~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€~~~~~~€€€€€|{|ƒ‚€€{{{|}~€‚ƒ‚€~zyxtpopoqsuvyzzyy{{{||zzzxwwxyyyz{{|||||{{{{{zzzyyyzzzz{{{|||}}}}~~~~~€‚‚ƒ‚€~}}}}}}}}}}}}}}~~~~~~~~~~€€€€€€€€€€~‚ƒ…„…††‡††………„ƒ}}}}|||}}~€ƒ…„†††…„„„€€‚„†‡Š‡„€~~~~~~~~~~~~~~~~~}~~~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€~~~~~~}}€€€€~|}ƒƒ€~|{||}|~€‚„ƒƒ~{xurqponoqsvwzyzyz}}}}{{zyyyyyzzyz||||||zz{zyyzyxxzzzzzz||||||||}}~~~~€‚‚€~}}}}}||||||}}}}}}~~~~€€€€~~~~ƒ„ƒ…†‡‡‡……………ƒ€~}{z{{|||~~~~‚‚„………………ƒ‚€~~‚€‚ƒƒ…ˆˆ…‚~~~~~~~~~~~~~~}~~}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~€€€€€€€€€€€€~~}}€‚‚‚€~}‚ƒ‚~|{{||}|~€‚‚‚€~{vtrononnprsvyz|zxyy{{{{zzzyyyyyyz||||||||{zyyyxyyyyzz||||||||||{|||}~~~€‚€€~}}}}||||||}}}}}}~~~~~~~~~~~~~~‚‚ƒ…‡‡‡……………„‚€~|{{{|||~~~~€‚‚ƒ………………ƒ‚€}|~€€‚ƒƒ…ˆˆ†ƒ‚‚klmnooonooortuvvwxzzzzwurpqqppppqqrssuxyzzyyyy||}}~€€€€€€€€€€}~~}}}}}}}}{{||||||||||||}}~~~€‚ƒ„„…………††……††„ƒ‚|sjd^[]_ada_][^cehhe``bglsz€„……„„{qf]YX]bjtz~{urppmifaadgknpquyz€€€€€€|wpmjjjjjjjkknqqtuuuuuvvuwvwyxupf[XTV[^choy€‚‚ƒ€€~~|xvtomjggcdfgghfhjjmprtttttsrrqpoqutuuz|zvplhbbdca\Z]dknttsrrsuwz~‚ƒ…‚mooppporssttuvwwxzzzzxvtrpqqppppqqrsuvvxzzzzzz{{||{}~~€€€€}~~}}}}}}}}}}||}|~}||||||}}~~~‚‚ƒ„„…………††‡‡††„ƒ}wpgc_^^`bb]ZYX[_dghfc`acfmu~‚……„„‚{si_\Z[bhpw}}{wtrpmnifcbbejmppqsv{€€€|zupkihhhhhhiklnortuuuuuvvuwvwyxupg]VUW\^cgpw€€€€~~{wtoljihgeegiiijjkjmprttttsrppqpoqsrpsw{||ytqmhdccb`\Z]dlsuusrrsuwz~„†ˆ…moqqssrstutuvwxxy{{{ywusqpppppqqsssstuuwyyy{}}||||}}}~}~~~~||~~~~}}||}}~~~}|}}~~~~~~‚ƒƒ„„…………‡‡†††„ƒ‚}vmg`]^`cda^[XVY]fmojea``emt{‚ƒ………ƒ€vmfcaadhot{yusqnmnjiihedehpy†„zwz~€€}{wrnjhhhjjiiijlnosvwvvvvwwwwwxxyupg]WUVZ^dhpw}€€€€€€€€|ztrojghhgghhjjjkklnnpstsuuropppoprrqrtxz||wsqkgecca_[]aelsutsstuvxy}„ˆ‰‡nonprrqrtuvwxyzz{|{{yvvsqppppprrssuuuwwxyyy{{{||||}}}~}~~~~~~~~~~}}~~~}|}}~~~~€‚ƒ„„……††‡‡†††„ƒ‚wnc^__dddb`YTT[epuvneaabfkqwƒ………„{smgbbeilostpnmllllmmkigglwƒ…‚ynqy€‚€zvqkihjiikkjjjkmoqrtvwwwwwwwwwxyzxsj`XTW[`cgnu|€€~|yurnlihhhhffgkmmmnonllpsvtssroooomoqportxz{yvrlhca`adaacdhnstrqqtuuwz†‰‰ˆnnmnpqstuuuvwx{||{ywvurqqqppqrrttvxxxxxxzz{{y{}}}}}~~~~~~~~}}~~~~€€€€~~~~~€€€€‚‚ƒƒ„„‡‡‡‡……………‚~yohfbeffc^\WUWamv|{rkca`chnu{„„…„‚}vrjeefikopoomllkknonnjijov}‚xqqw~|wrnkhhiikklkiiknoqruvxxxxxxxvxxyyyukbZWVZ`chms|~€~|xsnjihgheefgijnoooonljkpsssuuroomnppommptxxzxspmida_aebaejnsuurpqtuwwy}†ŠŠŠnnnopqtuuvwxz{}~}}{zxvutrqqqrrrsuvwxxxxxyyzzzzy{}}}}}}~~~~~~~~~~~€€€€€€€~€€€‚‚‚ƒƒ„……††……………‚€zslhdcdec`^ZX^iv|~wpic``dkry‚„……„€yrkdbehjlnonlllllppppnorsxzwtonv||vrpkhjlmoopnkijlpptuxyyyxxxxyxyyz{ytlcZWY]_bglsy~}ywsonliggfddefiklnoooolijmpsssssromlnppommruxxuspmkfbabeefimpuxvsqpqtvvtuy…ŠŠŠjlnopqsuvxxzz}~~}{zxvutssqqqqrrsuuwxxyyyz{{yyz|}}|||}~~~~~~€~€€€€€€€€ƒƒ‚ƒƒ„„„…………†„…ƒztnhecca`^]\]fr{ƒ€zukeb^bgms{€ƒ„…ƒ|unlgdfjkjiikkkmorttrtuvx{|xqmmppijtusnjjklmoprspkhikmoswxyxxxxyyyyzzz{zunf_ZZ\_bglqwz{}|zwrokigeecbbdegimopqponmljhlortsrsronlnpqnmnqtutrqnnkgdabffkpsvxzwrpqsuvtstx„‰‹‹jlnopqsuvyz|~~~~}|{zxvutssqqqqrruvwxxxyyyz{{{{z|}}|||}}~~~~~€€€€€€€€€€€€€€€€‚‚‚‚ƒƒ„„…………„ƒƒ‚~xrlfb``ba`^_dpy}ƒ€{vrlda`fkqyƒ„…ƒ~xqnigikjhiklllnqtvuttxyyyzvonprokjjnniiloqonrttpkhikmoswyzzzyyyyyyzzz{zvnfa^[]_bgjowz{zvsqmiggecbceeefilnoqsponmjhhkpstsrsspnlnpromnoppnlkkkhdcdehkrw{~~{usrstuwtsrv€‡‡ˆmmopopqwx{}}~}}{yvutsqqqqppqstuvxyzzz{{zzzz{{}}yz|}|}~~}}~~€€€€€€€€€€€‚‚€‚‚ƒƒ„„„„„ƒƒƒ{tnie`\]``^^ckv}‚‚ƒƒ€|umga`bgpv|„„„‚}|wqljgklihknmnpruvvwv|~zwwwwxzvkhiinsooqvytmnqrpkiijmprwyzyyyxyyyyzzzzyxohd`^^acfkpsxytrnlhgddb_abdfgimmqqrrpmmnjiilrvuuttspnlmopmkkkkjijhfecbbegkou{~€~xtsrtvxwtqpu|ƒ††mmmooprwy|~}}{yvutsssrrrrsttuvxyzz{zz{{||{{yyz||}}~~~€€€€€€€€€€€€€‚‚€‚‚ƒƒƒ„„„ƒƒƒ}xqje_]]^__`cir{€‚‚ƒƒ‚xqkebagmtz‚„„ƒ~yrmjgghkjkkmnrtwyzz{€ysuz~}vqoieeiosu{‚{tqrrpkiijlorw{|||zzzz{{{{zzzxrkd`^^acfhlpsspkjfdcbbdedfhikmnnnnppnlkllkjnrvuuttspnlnqpkhgfffededccbbehlrx}}{wsprtvwurqprz……llnooruw{~~~~~||{yvvusrrqqpqqsuvvwwzzzzzzzzzzz{{{|}~}~~~~€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚‚‚€€€‚‚ƒƒƒƒƒƒ„‚€}xrmgc``_```afnx‚ƒƒƒƒƒ€|vnh``chou|‚ƒƒƒysnjfehjjklpsuxzz|z|}~vqx~yvtolkjijnpx{wqpvwupkghkmprw|}||{{{z||{{|{{xrkda``bcegjnpoigegdbabbcgihjnoonmnoomnnomkkosuuuuuspmmopoicbeea`adcdeeffhmry}|{zuqqssuurqqppx‚‚lllnqtvx{{}}~~{{zwvutrrrqqqrstuvwxxzzzzzzz{{zz{zz{|}}~}€€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚€€€‚‚ƒƒƒƒƒ…„{vrmhdb_\Z``bekr{‚ƒƒƒƒƒ€~xrlc_bflrz€ƒƒƒ~xtnjfehjjklqty{|{zxvvvvw}‚€|xsqpoonpt{xtsx}}ytlhhklorw|}||||{{zz{{yyxvplgc``adghikjjhbacddcegfgijknoonnoqqpnnonlmqtvvvwvurpoprmgaabb`_`abcccdghmry}|zxtqrssuttsrqqt{kmmoqswxyz{|~~~|zyxwvutrqqrrstuvuvxxwxxx{{z|zz{{{{||}}~~€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚€€‚‚‚‚‚‚ƒƒƒƒ€{uplgec`^]]__bgqz€ƒƒƒƒ‚ƒƒ‚{vof`bekqw}‚‚€xvqjfdfhjkmtx}|}~‚{vvuv|‚|zyy{vtvstw|wqt|~}xrlhhjloqv|}}}}{|||zywwwvtsojea``cijjgggecacddihijkkklnonmmmpmmprronnruvttvvspnopplf`aa^^__abccehhjnsx|{xvrprstvtqrrqqsy~lnmoruwxyz{|}}{zyxxwuttqqqqqqrssvwxxyyzzyyyzzz||||||}}~~€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒ{vojfeec`__`ceinv|€ƒƒƒƒƒƒ‚~|voga`dhnu{‚‚}{uqnhfghkkpvzz~€‚‡Šƒ~~~~|xvssqopqruxzxuv}~}xrlhhjnpty|}}}~}}}|zywvutspmidbaadefedggebceggjjkjjjiknonmlllllprrpoosvxuuvvtqnoppkebba^^\_adefijjkosy{zxvrprstvtqooppqwzymmmotuvxxz{{||}{xwwvvusrppqqrsstxxxxyyzzzzzzzz{{{{||~~}€€€€€€€€ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒ‚‚‚}wqlieeecbabefhks{€‚ƒƒƒƒƒƒ‚‚€}vohbaaglrz~|wtpmifegklqvz{‚†…ytruvwtrqmknoosuuxzyvw~~xqokiklnqv{}~~~~~|{ywussttqnhebbbeffgggghhggjkjlmjijkknmmllnmnopoqrortvttruvtqmnqokc``ccbaacdefijlmqtxzywtqqruuvsqpppppuutmnoqsttuwxzzzzzywwuutsrqqqqqrrstwwxxyyyzzz{{zz{{{{}}~~}€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒ‚‚‚|wplifeeeeefghlqx~€‚ƒƒƒƒƒƒ‚‚ƒzsmhbcfkpw}|ytrpnkhehlpptx{‚„‚}wsqmnpqppnmmmpuy{zyzwvz~xqmiiknprw{}~~~~|{zxvstssrolhgcaadgghhhhiijjmnmnnkjijjkkkjlmnmlprssstwwutuvwtqopqokfbbdddbbefhjjijnrvyyxurqqruwtpnppppoqqpnoqqrqrswxyyyxxxvvutsrqppppqssttuvwwwxyz{{{{}}~~~~~~~~€€€€€€€€€‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒ}wpjhhghhhiiklpw€‚ƒƒƒƒƒƒƒƒ‚~{uojfceipt{}|zvppppmifgjnoswz~€~zuppnmnoonnnmpux{€{xuu|~xpkiikntuy|~~~~}|zxvvtutsrmjijfbbdhklmljllnoqrrpnljeggijkknmmnnprtttwyzwtuvvtpopqolfddeddcbdhjlllkosxxxvrqppsvxwspnponnnoonoqqrrstuwxxyxwwuussrqqppppqssttuvvwxyyz{{{{{{}}~~~~~~~~€€€€€€€€€‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒ~ysnjiiklllmmmotz€‚ƒƒƒƒƒƒƒƒ‚|vpkfceimswzywtqppomkgdgloquz~ƒ~xsomoqpmmmooqw{ƒ…{wvz€~xpljklorwz|~~~}|{yxvvtutspolkhgcdhmptutqpqrsrttqmkjhhhijiigiklnprsuvyzxutuvusoopqolfffdcbbbdhjmmnlpsvxvurqppsvxwtqonmlkknnppqqrssuvwwvwwwwvuttsrrqqqqrrsttuvwxyzyz||z{{z{{|||}~~}~}€€€€€€‚‚ƒƒƒƒ‚‚‚‚ƒƒƒ‚‚€€{tnjijknopoponrv|‚ƒƒƒƒƒƒƒƒƒƒƒ‚‚~yrmhddglouwwvsqoomlkiehknosw}€€|vrplkjfgklnqu{€ƒ„†ƒ{vuz~wpkklmoqv{}~€€~}{zzywutrqonkjhgghotw{zxvtrsvwwvsnlijjjhiiiggjlnqssvvxyyustvuqoorrpledbcbabcehknnmmosvwutrqoqsvwwtqomkjjjlmppooqrrtvwwvvvssttsssrrqqqqrrsttuuvwxyyzyyzyxuuussux||{zzyzz|}~€€€€€€€€€€€€‚‚ƒƒƒƒ‚‚‚‚ƒƒƒ‚ƒ~wpjihiloprqqpnrw|‚ƒƒƒƒƒƒƒƒƒƒƒ‚‚€zuoiecekorstsqpoomnljfeinpqw}~}|{xspljhhiknosy‚…„†…}vrw}~wpkklmoqw|~~~~}}|zyxvtspooljihinu|€}zvtvxzzvspmlhgghiiikjjmnqsstvz{yustvwrporrpgddb```acehknonmpswutspprstuvvtqomkjhhklnoooopqsuvwuttuuuuttssrrqqrrssttuvvwxyy{|ywtrokjhilpwwusrpqrrux|~€€€€~€€€‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒƒzslhghjkooooooqu|€‚‚ƒƒƒƒƒƒƒƒƒƒ‚‚€|vqjdadimopqqppppnpokhginpptz~}~|xuqmjiiimnrw}‚ƒ…††‡ƒzvw‚wpkkjkoqv}€€€~}|zyxvuqpnoljhhkt{€‚„€{wvw{|zxtpnljihiigiiillnoqsuxy|yutuwvrrrssme`bbaa_`cfhknnnnquvtrqqqstuvxwtomljihhjknoppprstuvutttuuuussqqrrrrsssttuvvwwxyy{{xuqljihfefjnmifcbdehloswz|~~~€€€€‚‚‚ƒƒƒƒƒƒƒƒ„ƒƒ‚}yqjgeccdimpppoprw|€‚‚ƒƒƒƒƒƒƒƒƒƒ‚‚~xrkecceilmpppqqqqrrmhfilpqsx|}}{wtqmljjjnrw|€‚…†††‡…}uv}|vplllmoqv}€€€~~}{zxwvrqopmkjjnv~‚„„ƒ}yy{||ywurqnlihfffghhjlpqqqrv{{yuwxwvrrrssme`a````adgilnnklquvtqppqsttuvvqnomljhhjkklnopqqqssssttssrrrrrrrrssssststuvvvxyz{yxvrmljigecbccbbbb`adeehou{}~}}~~€€€€‚‚‚‚‚‚ƒƒƒƒƒ‚€|xsmfc````foqrqpqw|ƒƒƒƒƒƒƒƒƒƒƒƒƒƒ‚xrnfacfkjjkmoprsstspjghknpqtz|{ytpqlkklmqw{~‚„…††††{tu|€~wpllklnrx}~~~}||zxvusqoqomllqw}ƒ„€}{z{zyxwtrpmjigffiihgijnpqrsw{|zvuxwurrrrqia^_]^`bdfhkmnmlmrsuttrprtttuwwrnmmkifehkklmnpqqqssssrrssrrrrrrrrrsssttvvvvvwxyz{yxvrnmkjhfdcbcdbaabdddccflqw{}}~~~€€€€€€‚‚‚‚‚‚ƒƒ‚‚~zupkhd_]\`ekpsrqrtz‚ƒƒƒƒƒƒƒƒƒƒƒƒƒƒ‚{uojeacehjkmopsuxxvslihjnoqtxyxsnlljkkmqvz~€‚„„…††††wsuy{uokkklosw|~€€€|{zxvtrpqomlkqwz}€|yuuustsrppolhgfhjiiihhkmopqswzywstvwuqqrroh`]_]^`cegilonmlmqrrqqqqsvwuwyxtollkiedfhmnqqppqqrsttttssrrsrrrrrrsttuuuuwwyyxyz{{{xurrrrnjgggfcfffffdeba`cjtxz||}~~~€€€€€€‚‚ƒƒƒƒƒƒƒ}wqleb_][\^blnqsrtwz€ƒƒ„„„„„„„ƒƒƒƒƒƒƒ‚~wqkeceggijmpqsx{{yvojhhoppsuurmkkjkllnqx‚ƒƒƒ…………‡†„|srwxupljklnrw|€€€~}}}|zyvtsrqonnqsvyz|zwppqmkkmkmmkifdceiiihgggjoppswz|zvtuutrrsrne^\\[`bcehkoqnkilpqsrpppsuttuxxqmnnlhgdefmnppppqqrsssssrrssrqrrrrsstuuuuuxxwxxyz{{{zzxxyyurmlijmqsuttqmhbbbcksvwxz|}}~~€€€€€€‚‚ƒƒƒƒ‚‚|vojdb_^]`aeimprsuy|~€‚ƒƒ„„„„„„„ƒƒƒƒƒƒƒ„‚xrleacdhjjmqtw{}}{xslhhloppplifhhjlllnqx‚ƒƒƒ……„…‡„€ysrsvtoljjknrx}€€€€~}}}}|zzxvusrpnpoqtvwvqmhfecbadgjnkhddceijjhjlljjjotxz|wstuutrrsrne^\\[_befloopnkjmopppppqsutstzysnmmkgeccelmmmmonpqqqqppqqppqqqqrsstuuvvvvwxxxyz{|{{{{||||wuonnquxy{{{ytmecbcehkoruxyz{{~}~€€‚‚ƒƒƒƒƒƒ‚~xokgfcaaabdglorsuz€ƒƒƒƒƒƒƒƒ„„„„ƒƒ‚‚ƒƒƒƒ‚~unhb`dghikrvy~~~{vohgknqlieebdehkkmnrx‚ƒ„„„„…………ƒywxxupmkijotx}~~}}}||}||{zxvtqnpnnnpsusof```^]^cfjllkgdcgjklmpponmknqw{{xuuvvussrqog]Z[_bgiikopomjjmpqssqqsuvvtsxxqnmlihebefklmmlmnpqqqqppqqrrqqqqqrttuvvvwwxxxxyz{|{{||||{{zxvvvxyz|{|||ytokhdb`bdgijijlqv|}~€€‚‚ƒƒƒƒƒƒ~ysnigdbabfglnpquy|‚ƒ„ƒƒƒƒƒƒƒƒ„„……ƒƒƒƒ„„ƒƒ~vrlfcchjknswz~€{yrjfhlnjebbceehlmnpru|‚ƒ„„„„……ƒ€€}xuzzupkiijnsx}~~~~{xxy||}|zwusqnnnmnpqqlda`aaabgknppmhdcfikopsuronlkou{{wtuvvusstsme\Y[afgkkloqplhijnprsqqsuvvruyvqnljjiebdbkjjklmoqrrqqppqqrrrrsstuuuttvvwwxxxxyz{{||{|||||||{{||{{||||{zvsqmieabd``]_bdgnwz~€€€€‚‚ƒƒƒƒƒƒƒ‚€{vqljhebaejlqsvw|~ƒƒƒƒƒƒƒƒƒƒƒƒ„……†……………………ƒ{slfdegjlpv{~‚‚}yslfehlkc`acfhmoonoty~‚ƒƒƒƒ„ƒƒ„ƒ|srwzupllmnnqx}€€€}xtpqwy{|}|zvspnonnnqrnkfggjmnrtuvupkfbbeilosw{xrnjint{{vtuvwtrstrlc[YV_hlmmoprnjggjmqtspqtvxwstxupolkjhedefjijkmnnpppqqppqqrrrrsttuuuuuvvxxxxxxyz{||||~}}}}||||{{||||||{zyyurmkhgda^\\]^`gpx}€€‚‚‚‚ƒƒƒƒƒƒƒ‚}xrmkhgghkptxyz}‚‚ƒƒƒƒƒƒƒƒƒƒ„„……††††††…………ƒ}umfcdgjosw}‚‚‚~xtoigilkhcbfknrsqmou|€‚ƒƒƒƒ„……‚yroovyupllklnqx}€€€~xrieemty||zwspoommkmoppooqvxyyzzzzwrlfbcegjmqx{|vofejszzvtuvvsrstsnf_]\ahlnooppmighjostrstvwwutvxuomlkjhfefhjjjkmnppqqqqqqrrrrrrsttuuuuuvvxxxxzzyz{{}}||}}||||{{{{{{||zz||zyxusomigea`````enw}‚‚ƒƒ„„„„ƒƒ‚|wqmkkiimsy|~€€ƒƒƒƒƒƒƒƒƒƒ„„„„……††‡‡‡‡††……„ƒ|wphefhlosz‚‚‚€zvqkijknifdiotvxsmmqw}€ƒ‚‚„„……ƒ~vooqwyvokkjknsy~‚|rh`\]ent{{wsqponlmnopqppqv|}||~~~|zskfcdfhjlsx~|vnfadnwxvuvwwtuutroiba^agkoqssqmigikqsststwxxuuxyvolllkidfhijjjkmnppqqqqqqrrrrrrstuuwwwwvvxxyyxyzz||||||}}||||{{{{{{{{zz|||z{yxwtqnkjhfda^bkt}‚‚ƒƒ„„„„ƒƒƒ~ytnmjjkqvz~€‚ƒƒƒƒƒƒƒƒƒƒƒƒƒƒ„„„„…††‡‡‡‡‡††……„ƒ}yskffgjosx~ƒƒƒ‚~{vojhjmljjqw{|{uommr|„„„„„„‚|usrquxvokkjknsy~zpha]_fntxwsommonlmoppqrruz}~~~~~|xqjgdehikmqv{{vld`bltxvuvwwtuuvtpifebejnpsssqnigkmrvurstwxxuruxuoljjkigilmijjjlmoqppppppppqrsstuvwxxxxwwxxzzxxxy{}||{{zz{{zy|zyyyy{{{{||{{zz|||{wusqmga^agr|€‚‚‚ƒƒ„„‚ƒƒ‚€~xrkjklqw|ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ„„„†‡‡ˆˆˆ‡‡†††…„ƒ|vpheehmrx~‚„„ƒ‚€€|wsliimnmnu}~ytomnrxƒ„„„„ƒ‚{uuwuvvvnlkmlotz‚‚|riccdhorssolllkklmnoppqquz}€~~}vngcdefgjmrvyyulc_bkuxvuvwvutvvsnigihhloprtrnjgfjnquuttuxxwsquwrnkkjhfgjkmijkklmnoppppppqqqrssttuvxxyywwxxzz{zy{{}||||}}{{zyxyxxyyzz{{||||||{{{{zzxvqha^`jt|€‚‚‚ƒƒ„„……‚€|wupmklmrw~€‚ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ„„„†‡‡ˆˆˆ‡‡‡††…„ƒ~zupgedgjov|‚ƒƒ‚~yuvtmjimopqxztollrxƒ„„„„ƒ‚|wtz}zvvwplkknnsx}‚‚€zsjggklnpppnnmmllnnpqqqqqsw}~zsmebcehijnswyytmf`ajsvtuvxvutvurnjijkknprsutnjiimrtussuvxxvrswxsnkkjhfgjoqijjjklnppqpqqqrqqrssuuwxyyyyxxyyyzzz{{{{||||}}{{yyyxyyyz{y{{{{||||{{{{{{|zukb^ajt|€‚ƒƒ„„ƒ„ƒ‚€}wpnlllnqtz~€ƒƒƒ„„ƒƒƒƒƒƒƒƒƒƒƒƒ„„……†‡‡ˆˆˆˆˆ‡‡††…„|wpjfdeimr{ƒƒ€|ustuokkmopry}zvqkjov„„„„„„€zvw{|xtttqnlmmosy‚€|uqmmnnmoppmmomomnoqqqqppsx}~~~~}ysmhcdegjlpsy|ysmfbckrttuwxwvuuuqnklmmnpqsttqmlkmqvwvstvvxxtptyysnlkkiegilqijkklklmnppqqqqqrsvvwxwxyyyyyyyyxyzz{{{{||||zzzzyxwvuuuwwxzz{{||||||||{{|yvnd`ags{~ƒƒ„„ƒ„‚€ztplkkllmqw}ƒƒƒ„„ƒƒƒƒƒƒƒƒƒƒƒƒ„„……†‡‡ˆˆˆˆˆ‡‡‡†ƒ‚}xurlfdeimrw}~zumlorokjjlorw}€|vqnmqw~ƒ„„„„‚}z|}xusrrsrnlllnry‚€{vrsssnmoppnnommnoppqqqqqtx|~~~~~|xqkgceghkosu{|ytoieenqrtuwxwvvvvqlijmpqsttuusomnotwxvtuvvwwsrtyxrnlkkihjlothijllmmnmoqqrrrrsuwwvvxxyyxy{{{{{{{{||||}}|{{{yyxxwwwwuutuwy{|{{{{||||||{{xpfaaeqz~‚ƒ„„ƒ‚}wqnkhhiijotz‚‚ƒƒƒƒ„„„„ƒƒƒƒƒƒƒƒƒƒƒ„…††‡‡ˆˆˆˆˆ‡†‡…‚€}xsrmgddfiptz}}ysmefmqnjhllnsv{}vromrx~‚ƒ„ƒƒƒz{{vsopqtpmmmlmqw‚{xssvvtommpppqqomnoopprrssuz|~~}}zvoiecdghlosz}|wrlighorttvxwwvwwwrnlmoqsututvspoorvywsstuuwwttvxvqonljjjknqwhijllnppqrrrrrsstvwwwwyyzzyz||||{{||}}|z{{{z{{yyyyyywwuuvxwyy{}}}}||||{{{{ysja_clu{€ƒƒ}wrkgggfgilrw}€‚‚ƒƒƒƒ„„„„ƒƒƒƒƒƒƒƒƒƒƒ„…††‡‡‡ˆˆˆˆ‡†‡…‚zuqoniffhhnsxxuoidcegnnnnpoqstz}xsolou}„…„„ƒƒ~|zxurqrsqmjlklnuz|yvsuwzzvppprrrtqomnpppqrrssty|€~}|zvojeddfhkpty{zvpmkjnsvuuwxxwvwwvsnlmoqstvvuvsqpsuxzvutuxxxxttxzwolkljjjmprrijjllmopqqqrrsttuuxxy{{zzz{{||{{||||||||{{y{yyzzzzzzzzyywwxxxy{{||}}|||zz{ztmd`cjtz~€€‚‚wsmgccbdgiqu}€‚ƒƒƒƒ„„„„ƒƒƒƒƒƒƒƒƒƒƒ„…†…†‡‡‡‡‡‡††…‚zwtpnnkihiilprqlgdba`cioqrv{{xwz~€|xrmnqwƒ…†……„„‚{urqstpljkjkmpsutppty{zurqttuvupnmnnoqqsqqruy}~{xuojedceimquzzxronnprvyxvxzzyyxxxrljmprtwwuvwurswy}{wuuvxyzyuuxytnkkkkkkllnmijlmlmopppqstuvvvwxxy{{{||||||||||||||{{yyyzyyyyyyzzzzyyyyyyy{{{||||{{|zz{zwqkbaenw}€€|smga`aceiow|€‚ƒƒƒƒ„„„„ƒƒƒƒƒƒƒƒƒƒƒ„„…††‡‡‡‡‡‡…„ƒ|xsqpnolhgiijlkjgda_ceimquz}~€}|‚{wspnrxƒ…†……‚||}xrquwvpljkjiilpqpmlqvz{vsvwzxvrpnnprrrrrsrtvy|~~{wrnieefiknrxzyvqonnpuxzwxz{{yyyyxrklnprtuvvwwutvy|}{wuwxxyywuw{yrmkjjjkkkljjjklmnopppqrtvvvvwxyyz||||||||||||||||{zzxxwwxyyyyyzzzzyyyyzz{|||{|{{{{{{{{{ztoheektz~€~ysje``_cjqv}€€€‚ƒƒƒƒƒ„„„„ƒƒƒ‚‚‚‚‚ƒƒ„„„„…………†††…„‚€|tqpponmkhghhiieadcdcjlnptx}yw|†Š‹‰€xqpsyƒ…………„ƒƒƒ~ysrw{yqkjjkjknnmlilru{{ywx{|xxspopqrrrprttuwy|~~{ywqlhddfgjnrvvtqqqppruzzxwy{zyyyzzsnnqrsuuvuvvtsvy{}zwwyyxzyxuvz{smjiiijjjjhjjklmnopppqstvvvvwxyyz|||||}}||||||||{{zyxxyyxyyyyyzzzzzzyyzzyzzz{|{{{{{{{{{zwrmgcfnuy{{zwqhc`aciqx{~€€€‚ƒƒƒƒ„„„„ƒƒƒ‚‚‚‚‚ƒƒ„„„„……………„„‚}{vtqppnnpqlhgghhfbcbbdjnrtvvyvqsttx††‚}zwx|ƒ…………„„‚‚}yww{xrkjiihjkkjijmswxxywx{|xvrnnpqssrprttuwy|~~}}ztpkfeegikosurqppooosx}|yyz{zyyz|xrmnrtuvvvwwvtux{}}zwwyyz{{yvy|zrmkhiijjikjkjkmnnoppqstuvuustuvy{{{}{|}~}}||||{{{zzyxxyyyyyyyyyyxyzzzzzzz{{{{{{{{{{{{{{{ytqjebflqtutqmhecciov{€€‚‚ƒƒ‚‚ƒƒ……ƒƒƒƒ‚‚‚‚ƒƒ„„„„„„………‚}zwusqqppnnpqpgeefgfdccbdhlpswwqijlmprv{ƒƒƒ€}|‚„…††…‚~{yz|wqmkjkkkmkmkkouxzxxwyz{xvtppqrssrrrttuxz}~}|zxsnkhghkmmopppppppootz~{zz{{zz{{xplotuuvwwwwvuvy|~€zwxxy||}zv||xqljjkjgfikilijjknopprstutsolkmpsvvvwy|}~~~~~||{{{zyy{{yyyyyyxxwwwxzzzzzzz{{{{{{{{{{{{{{{|zumf`cfkmlkhdbbbgms|}€€‚‚ƒƒ‚‚ƒƒ‚‚ƒƒ‚‚‚‚ƒƒƒƒƒƒ‚‚|yvtssqppppqrstpjffghgeffb_`fmsuwvpnknprv}‚‚ƒ††„ƒ‚ƒ„…††…„‚}{z„~wqmkklllllnopqux{zyxyzzwvrppqrttrrrttuux}~~{wqnigghkmponnooooonpu|€~{zzzzzz||wolrvvuvwxyyttvy}}ywxyz||{wv||xplkkjhfgiknpjjijloqrrstusqmhgfgjnnoqrvvy||{{||{{zzzzyyxxyyyyyyxxxxxxzzzz{{{{{{{{zzy{||||||wqhb_bccddcaabfmqx~~~€€€€‚‚ƒƒ„„‚‚„ƒ€€~~}}}}{ywwtsprpnnooqsuvurkhhiiiijjd_[aluwxwqmnqvz~„†‡‰‰ˆˆ…ƒ„…†……‚|z~…ˆ‚yrmkjlmmlqsx}}xxzzxxz{zvtqpppsutqqrttuvy~~zuqmjhhilljhjkmnpomorw|~}|zzzzz|~{tontvstwwxwvqsw|~|xwyy{||ytu}}yqmjjjggghkqvjjkkloqrrstusqkfdceeggghklmpvxz{}}{{zzzzyyyyyyyyxxxxyy{{zzzz{{{{{{{{zzy{||||}}xrkdca__``aaabfltz~€|zxwy}€‚‚€~}{xwtsqqpponnnnnlijjhgghijjlorvxywrkgghikkpokaVXeouvwrnot{„…†ˆ‰‹‹‹‰…~}€…†…………‚ƒƒˆ‡€xpmknprqpt{€€yyyyxxz{{xurrrrstsqqrttuwz}zuolighjigdbehjlmnprvxz}}|||{{|}}zsnouwuvxxxwtqsw|€€|yyzy{{{wqsz}yqmlkkigghltyhjjlnprrrsuxvuplhegfffddffghlpvyz{{yyyzzyxxxxxxxxxyyzzzzzz{{{{zzzzzz{{{|||||{zysnjgc_\_^^^abglu{€€}yrkgfhpx}{xuommlkhffffedccdcbccdc`````bfkrvyywrlgfijhjqtqgZYdouwtqonrv}‚‚„‡Š‹‹Š‡„ƒ}z€……ƒƒƒƒ‚„‡„|vpmlnsx{|}~{xtuvuwxx{|zwsrrrssrqppprruy|~€}xsmifgiifd``cfjmooqvxz{}}|}}||}~}ztpquuuwxxywuqrv}€{xzz{{|yrmqz}womlmkjhfgmv}hjjlmoppqrtvvuroljjigggdddedeglprvwxyyyyxxxxxxxxxxyyzzzzzz{{{{zzzzzz{{z{|||||{zwsokgb`_^[[]^cgow~~€}xnc\\]bhnrolhda`_]]]]\\[ZWWXWYZ\]^^]]___bgjmnpqpkjhffdegmsodairuwurpnnprx~ƒ…‡ˆˆˆ†‚ƒ†‚~€ƒ‚|€…ˆ‚zvpmlot|‚…„|tohfimuwwzzzvrqqqrrqpooprswx{~{vqlhffhhec]]beknnruuxz~}|}}||}~~{xtrvxuwxxyvspqv}€{xyy{{{xqlqz{uomlmmkjiglv}ikjlnoppqqstuvurpppmmkjihgecdefilpruwxwwwwwwwwwwvvyyzzz{{x{{{{zzzzzzzzzzz{||}}{yvspnkhfc_\]\^bhmt{~}ype_YY[^beheb^\[XWYXWWVVUSTTRSVWWXYUXVX[_adggfgimkigdb_`dimrpmrwvvtqpooorx|€ƒ„„‚€‚ˆŠƒz|€~}~‡‡‚zsmlkow~„„ƒ~slgijltuyz{wsqpprsqponnnqsux{}zuoighjkkgcaabfknqqtvwy~}|~|{|~zusvvvwyy{tnlnu|‚€{xyz{{yvnkpyxqonnnkifehlu{ikkmnoppqqrsstttuuvuusrqnmkhfdccfjnprtvvuuuuuuuuvvwwyyyz{z{{{{zzzzzzzzzz{|~~}}|{ywvtqmifc`_]\\^bgnqqne^[[[]_`__][ZYXY[\^``aa_^]]\^`abca^\[ZZZ\_behikijgb`ceggdhqvswxwwurponnory}~~{|ƒŠŠ‚z{|xyˆ‰ƒ~€‚€„††ulefjompsy|yurrrstsokknortwx{~~{vqligghjjieeeimqrssuvxz~}|~|{|~{xvvwwyzzxsmlnu|{xyz{{xrjipwvqonnnopollptyhjkmmnnoqqqrrtuuuuwwxywwurpkgecabcfgkqstttsuuuuuuvwwwwwyzzzzzz{{zzzzzz{{|||}}|zwxwvsljgdc`b_\\^dihd__]^\\\\\\^_aabdegllkkkigedbdggijifda^]]\Z\_`dgihd`bhmoi]\luvyyxwvtpnmnosy|}~~|zzˆŽˆƒ€}y}…‹ŒŠ‹ŽŒ‹ˆ…„…„……}thdejlpu|}ytrsrsvspmlmoqtvyyyxsrplggikllkhjlpvwvutuwx{~}}~|{|~~{zyxxyzyxsmlmt|‚€zyzzzzxogipttonmnoprromosvikkmmnnoqqrtsuuuttwwxyxxxxvqliecba`_ahnqrrstttttuvxxxxwyzz||{{{{zzzzzz{{{{|}}|zxwsromnnlie`\[^]\\]____^^^^^ehmnpqqrtuutrplihgefggimonnmjiedbb`_``abceknnog\Vetwxxwutrrqollr{}xv|€|}†Œ†~‚‰Œ‹‰ƒytx‚…†‡ˆ‰†vpkkptvz{wsrsrsromllmprsuvvtsqnmkkkklmmnnotw{{xtrtvy~~}}~||~~}{zxxyzzysmmnt|€~zy{{zzwogirvtqrqprsuxwtqrtjllnmnopqrttvvttttwwwwxxxxwwsojgb`^\`dkopprrrrssssuuuvwxxy{||zz{zzzzzyywwvw||€}{yvtssonnnmjb^\[]^\[[\]^__`adgmtwy}}~~~{{yurnlihgghikpuuvvtrnmjhgdfdadhnqnklojeioruxwtqlonhfgpz{wt{~~{~†Œˆ„‚…ŠŽ‰…ƒ€wrv~ƒ„‡ˆ‹ŒŒˆ…‚|vruz{wsqrssromnqryxuroqpnlkkhigjlnoqsv|~|wuuvy{€~|}}}~€€€€}yzz{{yyrmlmr{zy{{zzvqgjruvtsrqpsuz{xtttkmmopppqqrttttttttwwwwxxxxxxwsqmjfa]]bhnppqqqqrrrrsstuvwwxz{zyz{zzzzzwpiikpuy||yusqqpqqmgdbba_]\][[\^]^]`aadgnu{‚‚‚‚|yuromjihiiimouy|}||zvqmifdcfhnsrjghnw{~{upqtronpmmlosy~}{}ƒ„‚†‹ŒŒ‹‹‰ˆŠˆ‰‰…„ƒ|vy}}z|„‰ŒŒŠˆ†zy{zvspnnnoot}„‰‰„xooqpnljihijknpqsuy{|{xsorvy|€€}}}~€€€€€€}yyz{||ysnkls}{z{{{{umejswtrsrqpsu}~{wuumonopprrssuuuuuuvvwwwwxxxxxxwvsrpjc[Y^fopprrqqppqqssrtuvvxz{zzzzzzzytmd`bdinrvutrpqpnlke`[XZYWXVYYY]ceeeccefgkqwz~€~zupmkkkjhhiimry}€€}yunhdbinrsrkhhk|€€~wlhgmurroqv~‚ƒ‡‰ŒŠ‡‚‚…ˆ‰‡Š‹Š‡‡†ˆ‡…‡†}€€wry‚‡‹ŒŽŽŒŒ‰‰…|~ywtqljmox‚‰‹‰€xpnopqpkjhghilnppsu{~~{uqprvy|€‚}}}}~€€zz|}||xrolmt~€~{{{{{{thdjrusrrrooqx}}|yvunpprttttttuuuuuuvvwwwwxxxxxxwvustnd\Z^empppppprrrrrrqstuuwxyxxzz{{zwphea^_adimnlklmlljhaZUTVVWUTTX]dkpqqmjgdbceilpux||zvrolkkkkjklnrv{~~~|zwqmgglsutsslhpy„ˆ‰}rnsz}{vuz€ƒ„‡‹ŒŽ‹Šˆ†‰Œ‹‹‡ƒ‚ƒ~}…ˆ„‚zpov~„‰‹‹‹‰‡„~~ysrqqrv}…ˆ„|tomnnopqpmlkiiklnpqsvzzzwspptwz~€~~~€€}{|}~||xromnt~€~{{{{{ypgdjqssrrrqqqx{{zxwvqprrttstttwwvvttuuuuwwxxxvwwusttqme]XZcmpoonppqqqqqqqqrrttuvwwxxyxxtmgc^``abeegggfgged_[TPORVWZY[`elrx{{wnhe_]]`eijlpqtqpnmmkkklmpqty|~}ytroomtz€~{{|wyƒ……ŽŒ‡|rv}ƒ……„ƒ„†ˆŠŠ‹‹ˆ‰‰ˆˆˆ‹ŒŒŒŽŽ‡ƒ†„{y‚†‡„ysqw~„†ŠŒŒ‰‰ƒ}w{}{sppq{‚‰‰ƒwmnmoopprrrpnmjjlmnoqsvz{wtqqrtx|€€~€‚‚€€~|{{}}{vsonot}|yz{{yunebjturrssrrrvzyyyvvpsuuuutuvvwwvvvvvvvwwwxxxvvvussspld\UXbiooopppooooppppppsttuwwxx{ywtohc_aabdddcca_``^][WOMLPRTX]ckry}€‚}tkda]^]^aefgijlnmmmllmoqtwy}}|{ywuqnmpu}‡Ž‹‡„„ŠŠ‚‹“‰|v{‡ŽŽŒŒŽŽŒŒˆ„„„‡‹‰Š‹ŠŠˆ„†„€…‡†€|vttz…ˆŠŒ‹ˆƒxpnqy}ztnkr‡†€uonmmlmnrtttrpmkjlmnprtwzyuqqqrtx|€€~€‚‚ƒ€~|}}}}zvsonot}~|{{{{yukbdmssrrqqrruyyxyyvvpsvvuvvvxxxxxxxxvwvwxwwwxxwwvvuuqnh_XY]djmmnnnoonnooppppqrtuuwxxxxxuqnjhdcbabdb__]^]ZXVUPMJHMU]dnw‚ƒƒ„ƒvlfddfed_^_bdfhklmnoopqtvxzzzwwsqppnnqz…Œ‘Œˆ‹Ž…‡“‘Š~rwƒ’’’“‘Œˆ…ƒƒˆ‹‹ŠŠˆ‰ŒŽ‹‡†„…†„€|yxvv{ˆŠŠŠŠˆƒwolry}xnhn~„‚|tnmmnnoopruvurpolllopqrtw|zvsppsux}€€€~}€‚ƒ‚‚ƒ~{}}||yvsomnu}}{z{}|ztjdgousqqopprvy{zyxxwvwvvwxzzyyxxxxwwwwzzzxxxxxwwvvuuspke^Z]_dilnoooonnoopppppqrrtvxxxxywtpnlkigdacddb`_[XVUSQPOOQ]gq{ƒ………„„wmhfjprojgb`adddhknsutuutsrrrqqppnmmpy†Š“’Ž“’‹ˆ‹’Ž{ˆ“‘ŽŒ“’‹‹‹ˆ†ƒ‚†‰ŠŠŠ‰Š‰‹Š‰„€€„ˆˆ…„}|y}ƒˆŠŠŠŠˆ„~qhljf_`hz„‚~yspnnnnonptwyxtqnmnnopqrux{yvsqqsux}€€€€€‚ƒ‚‚ƒ~{||||yvuqmnu}}|{||zyrjfluusqqoppruxyzyxvwwwxxwwyyzzywwwwxzzzzzzyyyxxxwvvvspmha^^^_aehknoommnnpppppprsuvwyxyxxvtroonljhhid`^\VTTTTUWXZ^it|€ƒƒƒƒƒ‚~xoffjsvurnme_^`bgimqrsqqonmomlonopomq{„‡Ž“••”–—–’‹‰ˆˆ…‚…ˆŒ”’Ž‘’“”’ŽŠˆ‡ˆ‹‹ŒŒŠ‰ˆ‡†‚ˆŒŒ‹Š‰‰…€ƒ‡‡ˆŠˆ‡‡„{te]Z_it|}xyuqprromlmrvyywtqnnnnopprx|}{xwtttvy~€‚€€€€‚ƒƒ}{{{||ywtrmqw}~}|~}|xtlhrywqppppqqsxxyzzyywwxxyyyyzzywwwz{zzzzzzyyyxxxwvwwutrkgcbbaa`agjlnmmnnnnooooqrsuvwwxzzxvvtrpnmigcb_][XWY[\_aeipx~‚ƒƒƒƒ‚ƒzskfhov|zusokghiiihjlihhghknmllnprqrx{ƒ†Ž•—™›œœš—‰„€}‡Œ‘—š˜’’—œŸŸœ˜”ŽŠ‡‡Š‹‹Šˆ††„ƒƒ†‰ŒŽŠ‹‹‹Œ‹‰†……„……ƒ}|rnuƒ~xvtwvtsuvsmlmrwz{ytqnnnnpqstw{|zxwuuvxz‚€€€€‚ƒƒƒƒ}{}}}|zwurptz}~}|{}}ytlkvyvpppppqqqruyzzzzxxxxyyzzzzyyyyyyxxxxzyyyyzyxywwuwwuqmiiea`__bcfjmonnnnnnnnqqrtuwxz{{zxxtpmlhfc^\[Y\^_bcfinty|}€‚‚‚‚‚‚|tnffjqw|{wpmpsqkljiijjjooponjiptvxz|ƒƒ†Ž•šœœœ˜•‰ƒ€„ˆŽ”š  œ”’”–™™š™—•–Š…ƒ‚…ˆ…ƒ‚„€€†ŒŽŽŠ‰Š‰‰Š‹Œ‰†ƒ€€‚„„~{|wr|†‡vtw~}xrpsqmlnsx{{wtqnmmoqqssvwwvuuuwuw|‚€€€€‚ƒƒƒƒƒ|{|}~|zvurpu{}~}|}~}{ros||tpppoopppqvzzzzzyyzz{{||{{{{yyyyzzzzzyzzz{zyywwuxxyxtqnjgda_]^bglmnnoopppppprtuwwyzytqnjgea][[YZ[^acgknru{~€€‚‚‚‚‚‚}wpheejpwuxz{€~wsrpmkihffhlmjhhpw{}€‚‚ƒ„Š’›ž˜’‹‹‹‰ˆ‰‹˜žž›˜•’Ž’‘‹…wu~€ƒƒ‚ƒ„ŠŽŠ†„„ˆŠŠˆ‰‹Š†‚~~~‚}~€}yx||zwt{ƒ†€uqrqnnoquxyvtqnmlmmmkknonlmmopuw{€‚€€€€‚ƒƒƒƒƒ|{~~~|ywvtsy}~}}{tpx~{soppqqrrqsvzzz||zzyyzz{{{yzzzzyzzyx{{{{{zz{{yyxxwwxxwwvrnjfb`__bgkmonoppoprttuwvssqnkfd`[YWX[]^`behlqux{~€€€‚‚€yskegjkqsz‚…‡‡‰ˆ†…‚~zslddd_]bjlnnrv{|~Œ™žžž˜ŒŒŽ‘˜˜˜˜™™•ŽŽŽŠ…€volov…‡ŠŒ†„„…ƒ€€‚ƒ†…„~€‚€}yxuz|€ƒ†€xtrrppqrvzytpnmmmjkkknmmonooortuy{z|~‚‚€‚‚ƒƒƒƒ‚€€€€€}zzyvv{€€~~~~€|wv~zrppppqsttu{|{{{{zz{{|||||z{{zzz{{zy{{{{{{{zzzzzyzzyyyywutqnjd`^_cglmnoooopqrsttslida^ZYWWWYZ^chjmpuz{}€€€€€€|upifkosuz„‰‹‹‹Š‰‹‹ˆ…‚}zsjfgjkhhijkrz|tuƒ”›žžœš“ŽŽ’—œœš•˜œžš•ŒŠˆ‡‰Šˆ†ƒ€€zw|†ŠŽ‰|{~|||~ƒ„„‚€‚‚„†„€€}|}€~|{|yvssrrsuxzzurlkjjjklmnmlllkmmmlnsuwxz€‚ƒƒ‚‚„„„„ƒ€€€€€{{zzy~~~€yux‚|tqppqruuz~}zz{{yy{{{{{{zz{{{{zz||{{zzzz||{{|{{{zzzz{{{{xvtqlfa__cilmnopoqssutojd^ZXWVVX[^_bhnruy{~€‚‚‚‚‚‚|yroru}€|z‚‹‘‹ˆ‹ŒŒ‹‹Ž‹‚rioma\ahlqyxqm{šœš”’‘ŽŽ”™š™˜—šš˜•‘Œ‰††ˆ‰‰ˆ††‰Š‹‹‹ŽŽŠ‚{xz}~~„………ƒ„†…ƒƒ„ƒ„†…€~~}|yyyyzzwttstx}~ysomnnkkklnprrponlkijjijorw|€‚‚ƒ„„„„„„‚€€~z{{{z~€€€€xsw€ƒ{qpqrsstw|€|y{{{||{{{{{{zzzzzz|||}||||||||{{{{||{{{{{{{{|zxvqkda_^`cefghloppolhb][[\^^^cgkoruy{~‚‚‚‚‚‚‚‚‚‚{ww~ƒ†‡…„„‰Ž“‹ˆŠŠ‹‹ŠŠ’’‡wttj`]`is|}untŠ˜œ›™—”˜——”’’–™™–“’••”‘ŽŠˆ‡‡‡ˆˆˆˆ‡‹ŒŒ‹ŒŽŽŠ…ƒyy{{z}ƒ…†ˆˆ‡††„ƒ‚ƒ‚ƒ…„€{yyzy{}|zwxvwuuux|zspoljjkknrtvwyyyyvtsssokjlntz~‚ƒ„…………„ƒ‚‚‚|{|~}ƒ‚€€}tov~€ytsrstuux}€~|{|||{{{{||||{{{{zz{{||||{}}}||}}||||{{||||zz||{ztokgd`_^^_``dgihec_]Z[]`bgimrvy{~‚‚‚‚‚‚‚‚‚‚€€‚‚‚‚€~z|€‚‚†‡‡†‡Œ’Š†…†ˆ‰Š‘’’‹|ww{slfguxpt‰•™››–”šššš™–•–—•“‘’‹Šˆˆ‡‡‡‰Š‰‰ŒŽŽŽŠ‡…‚€|zzzxxz}€ƒƒ„…‡ˆ‹‡‚€€‚zyy{z{}~}{xyxwvststtqoklloqoprvz}~~}{yyy{ztnihkq{‚ƒƒ†††‡„ƒƒ‚ƒ‚‚}{|~€‚…‚€€€€zqnt}}yvuttvvvz~€~|{||}{{||{{||{{{{zz{{||||{}}}}}}}||||{{|||||||||{ytplhe`^^\\\^ab`__^__bfjotx||~€€€‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚€}~„„ƒ…‡‡†††‰ŽŽ‰„‚ƒˆŽ’•–•Œ{|ƒ…„}vzxnn—š›˜“•šš™™™–”““’‘ŽŒŒŒ‹‹‹Š‰………‰‹Š‰ˆŠŒ‹‰ˆˆˆ„~y{yusuy~}yx{„‰Š‡…ƒ‚{zy{z{|~|zyxxxuronppoorstttstx|€€€‚‚‚~wnhhpzƒ„†ˆ‡‡…„…ƒ‚‚€~~€„„‚€€‚€zokr||wusuuvvvz~€~|{|}{{||||||{{{{{{||||{{{{}}~~}}||||||}}}}||||zzyxwsnjea]]][\\^`__`bglswy|}€€‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚}€……„ƒ†‡ˆ‡††…ŠŽŽŠ†€|}}‹“˜—–ƒ€ƒ‰Š„„whfs†”š›™š—ššš™”’‘ŽŒŽŽŠ‰Š‹‹ŒŒŒ‰……†‹‹Šˆ‡‰‹‹‹Š‰ˆyz{wutvy|}zxw‡ŒŠ†€€‚}wz{yz{|€€|yzxwtqnlknoqqruuuvwxz}€€€€‚€ƒ„„…‚|rjhp|‚…†‡ˆ‡‡†……ƒ‚‚‚ƒ…„zqnw~|xuuvvwvwy~~|~~~~{{||{{{{{{{{{{||||||}}}}}}}}||||||}}}}|||||||{ywvrpmkgba^^`befjnrxz|~€€€€€‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‰Œ…„„†‡‡‡ˆ†„†‰Š†‚|{||€Ž—™™•‹„‚ƒ†‹Ž‹…†‡~tmt…‘—š—™™ššš™•’Ž‹‹ŠŠŠ‰‰‡‡ˆŠŒŒŠ††‡ŒŠ‰ŠŒŒŒ‹ˆ„|yyzyz|~|{{€†Š‰ˆ†„†‡ƒ}ywwxz}~zuqqonkjjmprrrsvxxyyz{€€€€‚‚‚‚„……†…ƒ{pfhr~„‡ˆˆ‡‡†……„ƒ‚‚ƒ„„……„‚‚‚|uu{}xwwwwywwy~|ywusq{{{{zzzzyyz|zz{{{{}}}}~~}|}}}}}}||}}{{||||||||{{||ywspniedehknrv~~€€€€€‚‚‚‚‚‚‚‚ƒƒ‚‚‚‚ƒƒƒƒƒ‚‚‚‚‚ƒ‡‹‰„„‡ˆ‰‰‰ˆ††††ˆ‰ˆ„|{{}Š–››š˜Œ„‚‚†ˆ†‡‰…|totƒŽ–˜™™š››››™”Œ‰‰‰‰Šˆ……†‰Œ‹ŠŠ‹’”’Ž‘’ŠŠ‰‰ˆ…|{zyy{‚„††ˆŠ‰ˆ†‡ŒŒ‹‰…}vuvw{zvsqpmmnoruutuwxy||}}}}~€‚ƒƒƒ„……‡‡‡‡ˆ…zkdiu‚†‡‰ˆ‡‡†‡……ƒƒ‚…†‡†ƒƒƒƒƒƒƒ~z{„zwvuxxvw{€€{rjiii{{{{zzzzyyz{}}||}}}}}}~~}|}}}}}}||}}zz||||||||{{||{zxzxvsrqsvx{}€€~~~‚‚‚‚‚‚‚‚ƒƒ‚‚ƒƒƒƒƒƒƒƒƒ‚‡‰ŒŽŠ‹ŒŠˆˆˆˆˆˆ†…‡†ƒ~zz~‹”™œœ›‘‡‚‚ƒ††‰Š‡}pko}Œ•—˜˜šœš–‘Œ‹‹Š‰‡ƒƒ…‰ŒŒ‹‹Œ”–•“’””“Ž‹‰ˆˆ‰ˆ†ƒ~vsru{‚‡‡…„„…†…„„†‡‰‹ŠŠ„zxsrqqsrqsuvwwx{zzz{}}}}}}~€‚ƒ„…†‡ˆ‡‡‡‡ˆˆƒuhejx„‰‰ˆˆ‡‡†††„„…‡ˆ‰‡…ƒƒƒƒƒƒ‚€€„†…}zxw{{yxy{skgjljj||{{zzyyyyzz||}}||~~~~}}}}||||||||zz{{zz||{|}}}}||z|~~|z{|}~€€€€€€€€‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒ„„ƒƒƒ€ˆŒ”Š‹Œ‹‹ŒŒ‹Š‰‡……‡†{{‡”–™›œš‘ˆ„…†ˆ‰‹ˆ|omr~˜™˜˜™œžŸžœ–’‘‹‰Š‹ˆˆ‰ˆŠŠŠŒ“”–•–——–“Ž‹‰ˆ‡‡………vliku€‡Š†ƒƒ„ƒ|y{€†‡ŠŒ‰†sqrrtutwyyzz}}||}~~€€€€€„†ˆˆ‰‰Š‰‰‰‡†…~peeq€…‡ˆˆˆˆˆˆ†……†ˆŠŠ‡…„„„„„„„ƒƒ…ˆƒ€}{{}}|zxvojlmkllozzzz{{zzzzzzzz{{{{~~~~}}}}||||||{{yyyxzz{{zz}}~~}}}~~€€‚‚‚€€€€‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒ„„ƒƒƒ‚…‹ŽŠ‰Š‹‹‘‘’‹‡„…ˆˆ…†Œ’“”•–™œ›‘ˆ‡‡ŠŒˆ|sqsyŠ˜›™——šœœœ˜”“’••”’’‘‘Œ‹ŠŒ‘“•–—˜—•“‹ˆ‡……„„†„€tgbehnv€ƒ„ƒzzzvv|ƒ††ˆˆ†}zwyz{|}|{{{}~}|}~~~~~€€ƒ…‡ŠŠ‹‹Š‰‰‰ˆ‡‡…{megq~†ˆ‰‰‰‰‰‡††‡‰Š‹‡…„„„„„„ƒƒ„ˆ‰„~|}}~ztlinrrpqruyyyyyyyyzzzzyyz{|}~~€€~~}}}}}}||}}{{||zzzzzzyz||}}}~€€€€~~~~~€€‚‚‚‚ƒƒƒƒ„„ƒƒ‚‚„„„‚ƒƒƒ†Š‹Š‹ŠŠŠŠŽ“—–“‹…„ˆŒ‹’•”““”—›˜ˆ‡ŠŽ‰|vy}€ˆ–œ˜——™šš™”””˜™š™——”““““’‘ŽŽ’•––”””“‹†„ƒƒ„‡ˆ†xhhnkhnv~‚ƒ€~zxxxy{‚‚ƒ„„}{z~|||{{||}~}||~€€€€€€‚„‡Š‹‹‹‰‰‰ŠŠŠˆˆŠ€pgdis‚ˆ‰Š‰ˆ‰‡…†‡ŠŒŠ†„„„„„„„ƒ…‡ˆˆƒ‚}tklnprtuwx{xxxxyyyyzzzzzzz{|}}}~~~~}}}}}}||||{{{{zzzzzzyz||}}}~€€‚‚‚‚‚‚‚‚}}}|}}~~€€‚‚‚‚ƒƒƒƒƒƒƒƒƒƒ„„„„„‚ƒƒƒ‰‘Š‡‹Š†ƒˆ‚€†—›š”ˆ‚‡’’“•”““”—šš”ŽŠ‹‹Œˆ€tpvˆ“œš—šœœ›š˜—™••žŸ™•””””•”’“””““”“’’’ŒŠ†ƒ‚„†ˆˆ„yqrusonr{€|{yuuwwuttrrv|~~||}|}||||}~}|}€€€€€€~‚„ˆŒŒ‹ŠŠŠŠŠˆ‡ˆ…yjcenz„‰ŠŠ‰‰‡…†ˆŒŒŠ†„„„„„„„„„ˆ‹Š„€€€{pkmosvy{|~€xxxxxxyyyyzz{{||}}~~}~~~}}||||||{{zz{yzzzz{|{{|||}€‚‚‚‚‚‚‚~|{{|{{{||~€€€‚‚‚‚ƒƒƒƒƒƒ……ƒƒƒƒ„„„„ƒƒ…‹‘ŽŠ†ŒŠŠ‰ˆ‚~„˜™™•‘Š‚‹’‘’•”•—˜››˜‘ŒŠŒŒˆƒztnr{‹šžœœŸŸŸžš˜—Ÿ ¡ ˜•“’’”•–—••”““””““’‰‡††ˆ‰‰‡{|{wsqt|ƒ„€|xwsnqvvtpmqx}|}}|}}|{}}}}€€€€€€€€‚…‰Œ‹ŠŠŠŠ‰‰‰Š‡pgcjx‚‰Š‹Š‰†…†‰ŒŒŠ†„„„………ƒ„„‰Œ‰…€€‚vljlpsvz}~€€xxxxxxyyyyzz{{||}~~~}~~~}}||||||{{||{yzzzz{||||||}~€‚‚‚‚‚‚‚~~|||{z{{||~€€€‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒ„„„„ƒƒ…‹ŽŒŒŽŒŠ‰‰…ƒŒ”–•“‘‹‚‰’‘‹“•–—˜šš˜“ŽŒŒŠ†€{tt‘œ¢¢žžœ˜–—”šŸœ™–’‘’•–—˜—––––—–”‘ŽŒŠˆ‰Š‹‹Š†ƒ€{{{~‚ƒ}{{wrlknsuusqqt{„ƒzxxz|||{}}}}€€€€€}}}~…‰‹‹ŠŠŠŠ‰‰‰ŠŠ„znikxƒˆ‹‹Š‰†…†‰ŒŒŠ†„„„………ƒ…‡Š‹‰…‚‚€wlkmosw{~~€€wwwwwwxxyyzzzz{|~~~~~~}}}}}||}{zyzzzz{{zzzzz{||}~~€€~}{{{{{{|}}~~€‚ƒƒƒƒƒƒƒƒƒƒƒƒ„„„ƒ‚‚…Œ’ŽŽ‹…ƒˆ“’…‚ˆŽŽ‹ŒŽ••———˜˜•‘Ž‹Š‡€|yy~‰•›Ÿžžš˜˜˜–˜›š™•”””•–••••–•—˜š›š˜’ŽŽŽŽŽ‘‘‹‡ƒ‚ƒ„…ƒ€€€|qeampsvxywuv|„‡ƒzxyz||z{{€€€~|{||„ˆ‹ŒŒ‹‹ŠŠŠŠŠ‰„ypnvˆŒ‹Š‰†„‡‰ŽŒ‰†„……†††……‡‰‹ˆ…ƒxnlnprvz€€wwwwwwxxyyzzzzz{||~~~}}}}}||}{zyzzzzzzzzzzz{||}~€€€~}{{{zz{|}}~~€‚‚ƒƒƒƒƒƒƒƒƒƒƒƒ„„„ƒ‚‚†Ž’‘‘‘‘‘Žˆƒ…Œˆ†ˆ‹Š‰‹Œ“–—˜˜˜™•’‘‘ŒŒˆ}‚„‹“˜˜˜™—••–•”•—–••––––˜˜––••˜˜š•˜š”ŽŽŽ‘”•”‘Š…„…‡†„€€€~yqbOViotwvusqv€‡‡ƒ…‡‡„€~{z|{}}||zzxwx{}€„ˆŽ‹ŒŒ‹‹ŠŠŠŠŠ‰‡€vptˆŒ‹Š‰†„‡‹ŽŒ‰†„……‡‡‡†…†‰Š‰…€ymkpruy|‚‚‚xxwwxxyxyyzzzz{{||}}~}~~~~}}}}}}||{{{yywwwxyzzz{||~€€‚€€~}}{zz{{z{|}}€‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒƒƒ‚…Ž“’“‘‘‘”“’‹…„ŠŒ‰‡‰ŠŠ‰‰‹Œ”—™™™˜—”’Œˆ}…ƒƒ†‘”•––““““••••”•–˜™›™™———–˜š›œœ˜•“’ŽŽ‘”——–”Ž‹‹‰‰‡ƒ€€€|ylU73Whptvwwst|†‰‰‰‰ˆŠ‹‹‡‚|zz{zwuttutuw|€†ŠŽŒŒ‹ŠŠŠŠŠŠŠ‰wpt~ˆŒŒ‹‰†„ˆ‹‹‰…†…†††‡…†ˆ‹ŒŠ…{nlpsuy~„…ƒƒƒƒƒ‚‚ƒxxxxxxyxyyzzzz{{{{}}~}~~~~}}}}}}||{{|{zxxxxyzzz{{{~€€€€€~}{zz{{z{|}}€‚‚‚‚ƒƒ‚‚‚‚‚‚‚‚‚‚‚‚‚…Ž–•””““””’Žˆ„‡‹Ž‹ˆ‰ŠŠŠŠŠ‹ŒŽ‘•—™™——’Ž‹†‚‚ƒ„ƒ†‰’“’‘‘“––—•••–˜œ›ž›œœ™šš›œ›™™––•’‘’”–˜—––“Œ‹ŠŠŽ‰„‚}ucC,/Vknnrwyupv€‚}x{~ƒƒ†‚€}zyvutux~„‹Ž‘ŒŒ‹ŠŠŠŠŠŠŠ‰wsv‰Œ‹‰††‰Šˆ…††‡ˆˆ‡…†‰Œ‹ˆ~smqtuz€ƒ†„ƒƒƒƒƒ‚ƒxxzzyyxxxyyz{{}}}}}}~~~~~~}}~~}}}}|zzz{yxxwwyyzz{{}~€€€€€~}}|{{{z{{|}~~€€€‚‚‚‚‚‚ƒƒƒ‚‚‚‚‚‚‚‚„Ž–———••––”‘Žˆ„†ŠŒŽŠŠˆ‰‹‹‹‹‹ŒŽ‘“–˜™•ŒŽŽ‹‰„‚‚„…††‹Ž‘’•——••”–˜›™›¡ž˜Ÿ‘—™š™™——••••—˜—˜˜—–“‘‹‰ˆ‰‹‘Œ†€taJ<F`qrnorvusuz}ztvx{~€€ƒ‚‚€~}{vtsvz€†ŠŽŒ‹‹Š‹‹‹‹Œ‹‰€uswˆ‹Œ‹‰††ŠŽŽŠˆ††‡ˆ‰‰‡…†ŠŒsmqtvyˆ‰ˆ„ƒƒ„„„‚~sxxxxxxxxyyzzzz||}}}}~~~~~~}}~~}}}}|zzzyxxxyyyyyy{{|}}€€€€€€€~~}}|{{{zz{|}~~€€€‚‚‚‚‚‚ƒ‚‚‚‚‚‚‚‚‚„‹–˜—˜•”–•”‘Ž‰……‰‹Š‰‰‰ˆ‰‰‰‹‹‹ŒŽ“–—”ŒŒŒ†~~„ˆ‘’’“–˜™–””–™›žž†‰˜Š˜›š™™™••–—šš™˜˜˜˜”‹‰‰†„…†…}ul[JNgwyuqotvutw}{y}€€€€€€~}}ywvvw{†‹Œ‹‹Š‹‹‹‹Œ‹‰€utxƒŠŒŒ‹ˆ…†ŠŽŽŠˆˆˆ‡ˆ‰‰ˆ††ŠŒˆxpqvvx€‰‹ŒŠ…ƒƒ„„„‚xmxxxxwwzzzzz{||{|||}}}}}}~~~~~~}}||||{zyyyyyyyyzz{{|}}~€€€€€€~~}|}|}{zz{{|}}}~€€€‚‚‚‚ƒƒƒƒƒƒ‚‚‚‚€€…“˜——–”–•“Œ‰……ˆŒ‹‡ˆˆ‰ŠŠŠ‹‹‰ŠŒŽ‘’””Ž‘Ž‡~xvwx}†––’‘‘–šš—“”—™™‰Œ’“’šžŸžŸ›š˜—–—š››ššš˜’ŠŠ‰ˆ‡„ƒ‚{tkaVO\v€{vppuwtx~ƒ‚~~€€€€€€~~|ywvvz~‚‡ŒŽŒŒŒŠ‹‹‹‹‹Œˆwv{„ŠŽ‹‰†‡‹ŽŠˆˆˆ‡‰‰‰‰‡ˆ‹‰}pruvx~†ŠŒŒˆ„ƒƒ„„ƒrixxxxyyzzz{z|||{|||}}}}~~~~~~}}||||{zyyxxyyyyzz{{|}}~€€€€€~}|}|}{{{{{||}}~€‚‚‚‚‚‚‚‚‚~zxƒ’—˜—–•”’Ž‹‡†‰Œ‘Š‡‡‡ˆ‰‰ŠŠˆ‰Š‹ŽŽ‘ŽŒ‘‘‘ŽŒ†~yxxyŽ——•”’“•˜š–‘“•™š›‰‘——œš””™žžž žš™˜—š›œ›››š“‹Šˆˆ†ƒ{wrmga`k{€|{wpirywx}„…€€€ƒƒ€~{ywvvz~‚ˆ“‘ŒŒŒŠ‹‹‹‹‹Œˆvu|…‹Ž‹‰†ˆŒŽŠˆˆˆ‡‰‰‰‡…‡‡pquvw~…ŠŽŒˆ„„„„„‚ynjxxxxyzzz{{{{||||||~~~~~~~~}}}|{|}}}}||{||||zzz{{{{~~}}~~€€€€~~{{}}||{{||}}~€‚‚‚‚‚€€€‚‚‚~wom|‹”•””•”’‹ŠŽ‰…„„‡ˆ‰‰ˆ‰ŠŠ‹ŽŽŽ’’‘Œ†ƒ€€†˜˜˜——•”•——•—™—‘›—’˜ž œŸŸšž˜ œ˜˜™ŸŸžœ—“Šˆ‰ˆ‡„‚zurqroorwyuuuogjsxy|‚‚‚‚‚‚‚‚~~{yyy}…‰Œ’’Ž‹‹ŒŒŒ‹†}vv~†ŽŒ‰†‰ŽŒŠˆˆˆ‰‰Š‰ˆ‡‡€snrvy~ˆ‹Œ‘‹ˆ…„††…}pikxxxxyzzz{{{{||||||{{~~~~~~~|}~~~~}||{|}}|zzz{{{{||||||~~~~~~~~}}||}}||}}~€‚‚‚‚€€€€xndgy‡Ž‘“••Ž‰Œ’“‘Ž‹†z~…‡ˆ‰ŠŠ‰ŒŽ’’‘’‘‘‘“–˜™˜˜–••—™˜—™œ™’››žž¡ ¢Ÿ¡Ÿ¡œŸ›š›¡Ÿ ™œœ˜“Š‡ˆˆ‡†„~{z{zxqllmknstmhkpw……‚€€‚‚‚‚‚‚€~{yzz{‚…‰Œ’’‹‹ŒŒŒ‹…}wy€ˆŽŒ‰ˆŠŽŒŠˆ‰‰‰‰Š‰ˆ†€xprtv}‡ŒŒ‹Šˆƒ€€€}zshgjyyxyyzzz{{{{||||}}}}~~~~~~}}~~~~~~||{{}}{{zz||}}}}}}}}|}}||}~~}}}}||||||}}€€€€€€€€€€~|qd_fw}{|‚‰’‘Œ’”“‘ŽŒˆƒ|y€„ˆ‰ŠŠ‰Š‹ŒŽ‘‘‘‘’“’‘’“›¡ŸšŽŒ•šš˜š˜—˜››š™š™—   ŸŸŸ ž”— ¡¢Ÿœšœ¢¥¥žœ›—’‰‡†……†„ƒƒƒ}xnbafknqrpjfjuƒˆ†‚‚‚‚‚‚‚‚}|{|~„‡ŠŒ“’‘ŒŒŒŒŒ‰‚{xz€ˆŒŒ‰ˆŠŽŒ‹ŠŠŠŠŠ‰‰ˆ‚vrtuvy…ƒ‚~{vqnooomlfeflzzyz{|||}}}}||||}}}}}}~~~~}}||}}||||{{||||||{||{z|}}}}}}||||}}~~€€€€~~€€€~zshb`ehjknz„‘’Ž‹‹””’‹‹ˆ„‚orz‚‡‰Š‰‹ŒŒŽ‘‘‘‘“”“‘‘‘•¨¦‘Š›¦§¢›˜˜››š˜˜šœ›¡¡ ”› ¡šŸ› Ÿž›ž¡£¢ ž›—‘Œ‰ˆ‡…„„‚‚€~}ytqnicbglornhen|€€‚‚‚‚‚‚‚~}}€‚…‡ŠŒ““‘ŒŒŒŒŒŒ‰zx}ƒŠŽŒ‰‰ŒŽŒ‹ŠŠŠ‹‹‹Š„wqtvutvspnjihhfghhhgfecehzzyz{|}}||}}||||}}}}}}€€€€€€€€~}}~~}}||||{{{{zz{{{{||}}}}}}}}|~€€€€€€€€€€~~}~~~|{vmfabdehin{ˆ’’Œ‰Ž‘”—”Ž‹ŒŒˆ„ƒ‚tjlw†‰ŠŒŒ‹‹’“““““••’’‘“™¡¤’‹œ­®©¥——šœœ›š›žŸ ˜šœœœ˜˜šœŸŸŸœœ £¡žœ›—‘ˆ‡††„ƒ‚€~{vux|yla^bjoojfkuyz{~€‚‚‚ƒƒƒƒ€€‚ƒ…‡ŠŒ”“‘ŽŒŒŒŒŒŒ†~yz~…‹Œ‹‰ŠŽ‹Š‹‹ŒŒ‹‡}stvsonieccdehilnoponkhhffzzyz{|}}}}}}||||}}}}}}€€€€€€€€~}}~~}}}}}}}}{{{{{{||||}}}}}}}}|~€€€€€€€€€€~~~}~~~|ukeehfeefgo|‰‘Ž‹‹’”—–”’ŽŠˆ†ƒ}trv|‚‰Š‹ŒŽ“””•”“”””’’’•›¡™¢«§¢ žš™˜›œœœœœ˜—¢Ÿ›™šœ›™œœ›™››™œžž›˜•’Ž‹‰‡††„ƒ„€~|zvx{€ync^`hmkgmy€€€‚‚‚ƒƒƒƒ€€‚ƒ†‰ŠŒ”“‘ŽŒŒŒŒŒ‹…~y{€‡Œ‹Š‹ŽŽ‹ŠŒŒŒŒ‰€tsrligdedehlouy}~€€xqlmlnn{{{{{}}}~~}}}}}}|||~~~~~~~}~€€€€€€€€€~~~~~~~~~}{||||{{||||}}}}}}}}}}€€€€€€€€€€~~~~~~~xofbehddedgp{‰Œ‰Œ‘“–˜–•”’ŽŠŠ‡{utzƒ‹ŒŽŽ’“”–•”“”•”•““”—ž¨«¦ž›˜››™™œžžžœ››–£§¥¡žžžœšš™–•™˜˜šœ›™—’ŽŒ‹‰‡†…„ƒƒ€}yyy|}wkb]blmlmt{‚‚‚‚ƒƒƒƒƒƒƒƒ…‡‰Š‘“““ŽŒ‹ŒŒŒŠ‚|{{ˆ‘Œ‹ŽŒŒŒŒŒŒ„vnlhgdghkkntzƒ…‡ƒ…†‚zrmoqvx{{{{{}}}~~}}}}~~~~|~~~~~~~~€€€€€€€€€€€€~~~~~~~~~}{||||{{{{{{||}}}}}}}}€€€€€€€€€€~~~~~~|xpfeffgggccir€Œ‰‹”—™—–––“‘‘ŽŠ†€vtz„’‘Ž‘’“”––•‘‘‘”–””•–™ ¡˜“”—––—šž›š››Ÿ¤¤¡žœœ›š™˜••™™˜šš˜”Œ‹‰ˆ†…„ƒƒƒ‚€~~~€€€€€}xqe^elqroqu|‚ƒ‚‚ƒƒƒƒ„„ƒ‚ƒ…‡‰Š’““ŽŒ‹ŒŒŒˆ|{{ƒ‰Ž‘Œ‹ŽŽŒŒŒŒ‹†xnkikkmmqv|„Š‰†††~rnnt{…||{}|}}~}}}}~~~~~~}~~~}~€€€~~~~~~}}}}|z||||||{{z{||||}}|}~~}€€€€€€€€~}}}}}yshdfgikkibbjs~ˆ‡‡Œ‘”—˜˜˜™™—•Œ‰…|y|„“‘‘’“““•”‘Ž’•––•“—˜š—’•””•–šžŸ›˜•››¢¢¡ž›———˜š™˜—–˜™˜™˜••“‹‰‰ˆ†…„ƒ‚~||}€‚€€€zqcfjoojelxƒ‚€~ƒ„‚„„‚‚€‚‚…††ˆ‹Œ‘’’ŽŒ‹‹‡€zz„Š‘Œ‹‘ŒŒŒŠ}mifhmqrv~†Œ‘’’‘‰ˆ‡ƒyqnrx~„…zzz{|}}~~~}}}}~~~~~€€€€€€€€€€}}|z{{{{zzzz|||||||||}~~€€€~~~~~~~}}}|zshccfilmkgbbit„…‡’”–˜š™™šš˜–ŽŽ‹Š‰‚{~†‘‘‘‘’““’““ŽŒŽ’••“’’”˜—•”””•–˜››—••—›žœ›™–••–——˜˜–•––—••”‘‰‰ˆ‡†…„ƒ‚€}{z{}€€‚€zurqrogjvƒ†„‚„„ƒ„„‚‚ƒƒ…†‡‰Š‹‘’‘ŽŒ‹Œ‰…}|{€‡‹‘Œ‹ŒŒŒ‹pffhkty~…Œ‘’’’‘‰‡†~tpps{‚…‡{{||}~}~~~~~~~~~~~|~€€€€€€€€€€€€€€€}}}}|zzzzzyyzz{{{{||}}~~~~€€€€}}}|||}}}}{uicaehmqpnibcluƒ„‰“••–™›ššš™—•‘Ž‹‰†ƒ~…’“Ž‹ŠŠ‰‹ŒŽ‘”““’’••“““”–˜˜™˜—•’’“•š›šš™š—–•——™˜˜˜˜–•”•“‘‰ˆˆ††…„ƒ€~|{y{{|€‚ƒƒƒƒ‚€}~}{{{urw}„†ƒ€€‚„„ƒƒ‚‚„„†††ˆŠ‹Ž’ŽŒŒŒŒŒ‡|{|‚ˆ‘Œ‘ŽŒŒŒˆuhfknrz…‹‘’“““‘‘‰ˆ„yqqsy…ˆ‡||}}{|}~~~~~~~}}~~~~~~~~€€€€€€€€€€€€€€€}}}}|zzz{{{{{{||{{{{z|~~~~}}}}~~~}}}}}zrjddcekpsqngbcir|„‰”—–—™›šš™—•’ŽŽŒ…}z~‚ˆŽŽ‘ŽŒŠ†‚€‚…‡‘‘““““”—ž¢ –“”’‘“”——˜˜—šž›˜—˜™›š›˜•“”“Œ‰ˆ‡††…‚~|{z{{|€‚ƒƒƒƒ‚‚€€€‚ƒ‚}x~…ywx€„„„„ƒƒ„…†††ˆŠ‹ŽŒŒŒŒ‹…€|{|‚ˆŽ‘‘ŽŽŒŒŠzlfinr{‡‘‘’““““‘ŽŠ‡…uprt|ƒ‡‰‰}}}}}}~~~~~~}}||}}||~~€€€€€€€€€€€€€€€~~}}{{{{yzzzz{{||||{{{|~~~~~}}|}€€€€}|ztjddeeiossqlfaelx„…‰•˜—™››››—•“ŽŒˆxnu|†‹ŒŒ‰‡„€~{|ƒ‰ŠŒ‘’‘•—§¬¦™”‘‘“•—˜———˜››™™šœ››œž›˜•””’‰‡‡‡………ƒ‚~||{{|}€‚ƒƒƒƒ‚‚‚ƒƒ‡‡y|‚z{}ƒ……„„ƒƒ……††‡‰‰‹ŽŒŒŒ‹„~}}€„Š‘‘‘’’Œ‹~mdfknu„“““””••”‘Œˆ†…{rnqxˆ‰‰‰~~~~~~~~~~~~}}||||||}}~€€€€€€€€€€€€€€€~~}|{{{{yzzzz{{||||{{{|}}}}}}}}}}~~}}}{ukdcegimqttpkhgip|…††‹•˜™›››š™˜•’ŽŒ‹ŠŠŠ|giu||~€…‡‰ŠŠ‡„€|{|ƒ†‰ŠŒŽ‘”œ§«¬©£›•’’‘’•–—•••–™™™™šœ›š›œ›˜”“‘‹ˆ‡‡‡………ƒ‚~}}}}}~€‚ƒƒƒƒ‚‚‚‚ƒ„‡‰ˆ…€‚‚~{„……„„ƒƒ……†††ˆ‰‹ŽŒŒŒ‰ƒ~~…‹‘‘‘’’‹€qjiilr’“””””••”‘Œˆ‡€uoqv{„ˆ‰ŠŠ~~~~~~~~||}||||||~€€€€€€€€€€€€€~~}|}|{{{z{{{{zz{{{{{{||zz||}}~~~~~}|ulcaehlnqvwsnjghlsˆˆ‡–™™œœ›š˜—•“Š‰‰‹‚l`lvvxwx|ƒ†‡††…‚€~‚‚†ˆ‰‹ŽŽ’¨ª¥¢žš•“•”‘‘”˜™—™›š—˜˜–•“’‰‡‡‡ˆˆ†„ƒ~~}}~ƒƒƒƒƒ‚‚„…‡ˆ†„‚„€yx{~‚„„ƒƒƒƒ„†……†ˆ‰ŠŒŽŽŒŒŒˆƒ€‚ˆ’‘‘‘‘‘‘ŽŒŠ…ykjklr{‹’””“”••••“Š‡†|spty€†ŠŠŠŒ~~~~~~~~~~}|||||~€€€€€€€€€€€€€€€€€€~}}|||{z{{{{zz{{{{{{||}}||}}}~~~}wmd`dhknsvxwqlhgks{„Œ‰†Œ•˜—šœ›š˜—–”†‚…ˆ†‚qacpvwwx|‚„…„…„„„‚ƒƒƒ„†ˆŠŒŽ“™œœ™—“Ž‰ˆ‰‹ŽŽ”•–˜›š˜•””’Ž‹ˆ‡‡†‡‡†„ƒ€ƒƒƒƒƒ‚‚‚‚‚„††…„ƒƒ}tsw|„„ƒƒƒƒ„†‡‡†ˆ‰ŠŒŽŽŽŽŒˆƒ„‰Ž‘‘‘‘‘‘‘‘ŽŒ‡{lklmpxƒŽ”“““”••••“‰†‚xqrv{‡ŠŠŠŒ~~~}|||{}}||}}|||}~~€€€€€€€€~~}|}}{{z||{zzzz{{{|}}}}}}}}|}~~}}~}zshbbhkmsyz|wqlihnt{‡ŽŒ‡ˆ•—™š˜–•“‘‰†ƒƒ~vf`mtwxz~ƒ…„…„„„ƒƒƒƒƒƒ„†‰ŠŽ’”—˜—”“‰ƒ„†‰Œ‹ŠŠŒ”“—˜™–““’ŒŒŠ‰‡‡ˆˆ††††„‚€~~€‚‚ƒƒ„„ƒƒƒƒƒƒ„„…„„{totzƒƒƒ‚„„…†††‡‰ŒŒŒŽŽŽŽŽŽ‹†„‚‚„ˆ’’’’’’‘ŽŽ‰€qkonnw””””••••••’‰…|trtw}…ŠŠŠŠŠ€€~~~}}}}}||||}}|||}~~€€€€€€~~}}~~}|||{{z|{zzz{{{{{|||}}}}}}|}~€€{tkcafikqwyzytmihlpw{…‹…‡’•˜™š™–•””’Šƒƒ~yk`m~€ƒƒ……„„„ƒƒƒƒƒƒ„†‡‰‹ŒŽŽ’”““‘Œˆƒ‚ƒ…ˆŠ‹‰Š‹Ž’”•”‘ŒŠ‹‹‰ˆ‡‡ˆˆ‡‡‡‡„ƒ€€‚‚ƒƒƒƒƒƒƒƒƒƒƒƒƒ„„ƒƒ|tkchuƒƒƒ„„……††‰‹ŽŽŒŽŽŽŽŽ‹ˆ…‚ƒ„†‹Ž‘’’’’’’‘†vlknps|ˆ‘•”””••••••’ˆ„xqrvz€ˆŠ‹‹ŒŒ€€~~~~~~||{{{{||||||||}~~~~||~~|}||||||zz{{{{{{||{{|||}}}}}~~~~zpgbeilpw{||yunihnuxz…Ž‹†…ˆ’•™˜•”“““’Ž‹ˆ†ƒ€~q`i€‚‚ƒƒ……ƒƒƒƒƒƒƒƒ…†‡ˆŠŠŠŠŒ‘‘Œ†ƒ‚‚‚„‰ŠŠ‰‰Š‹‘‹‰‰‡ˆˆˆ‡‡ˆˆ‡‡‡‡†…ƒ€€‚‚ƒƒƒƒƒƒƒƒƒƒƒƒƒ‚‚ƒƒƒxslb[gzƒƒƒ„…†††‰‹ŒŽŒŽŽŽ‹†‚‚ƒ†‰‘’’’’’‘’’‘Špjkptzƒ“”•””””••–”“Žˆ‚vqsw}‚‰‹‹€€~~~~||}|{{{{{{|||||||}~~~~~~~~~~~~~~}}|}}}}}||{{{{||||||{{{{{|}}}}~~~~wlbchjnty{}{yuqmmnmjm~Ž†…ˆ‹’•”‘‘‘‰††…wee{„„ƒƒƒ„„„„ƒƒ††……„„ƒƒƒ…†‡‰‰‰Š‹‹ŽŒ‰…ƒ‚‚‚ƒ†‡ˆˆˆ‡‰Š‹ŠŠ‰‡††‡ˆˆˆ‡‡ˆˆˆˆˆˆ‡†…ƒ€€‚ƒƒƒƒƒƒƒƒƒƒƒƒƒƒ‚‚ƒ}wqlcRPgz€‚„……†††ˆŠŠ‹ŒŽŽŽŽŒˆƒ‚ƒ…‡‹‘’’’’’‘’’‘†unmnqu}‡‘”•”””””••–”’Žˆursx~„‰Œ‹€€~~|~~~~{{{{{{{|||||||}}}~~~~~~~~~~~~||}}||}}||||||{{{{||||||}}~~~|vkegikov{}}}{wspplc_i‚‘‡ƒ…‹Ž’ŽŽ’Ž‰ˆ‡…‚zkew„ˆ†„„……††††‡‡††††„„ƒ…‡‡ˆˆˆ‰ŠŠ‹Œˆ„‚‚€ƒƒ„…††ˆ‰ˆˆ††…„„†ˆˆ‰‰ˆˆ‡‡ˆˆˆˆ‰ˆ††…ƒƒƒƒƒƒƒƒƒƒƒ‚‚‚ƒ‚ƒƒƒƒ‚~vmbOLZp€ƒ…††††‡ˆ‰‹ŒŒ‹ŽŽŽŠ‡ƒƒ„‡ŠŽ‘’’’’’’‘’’’Œ}olnpt{‚‹“••”••••–––“‘Œ‡|ssu{ˆŠ‹ŒŒ~~~~}|}|{|{{{{{{|||||||}}}~~~~€€~~}}||}}}}}}||||||{{{{|||||}}}~~}{vnhjkmsx}~{{zxuspg^_mƒ‘‡ƒ†Œ‘ŒŒ‹ŒŽ’Š‡…{mbqƒŠˆ‡‡ˆˆˆˆˆˆ‰‰ˆˆˆˆ††…†‡‡ˆˆˆ‰ŠŠŠŠŒŽŒˆ„‚‚€€€‚„††‡ˆˆˆ†„„…‡‰‰‰‰‡ˆˆ‡‡‡‡‡‡‡‡††…„„„„„„„ƒƒƒƒ‚~zwv{€‚ƒƒ‚‚‚€zrnotz~‚„ƒ…††††‡ˆ‰‹ŒŒ‹ŽŽŒˆ„ƒƒ„‡ŠŽ‘’’’’’’’“’Žƒsmnprw~†Ž“••”••••–––“Š„xssv|…ˆ‹ŒŽŽ~~~~}|||{{{{{{{{||{{{{|}}}}}}}}}~~}}}}}}}}}}||||||{{||{{}}|}||}}~~|ztpknmpw|~~}}zwsld]_n…†„‡‘‹Š‹ŒŒŽ“‘ˆ…‚|tpgg‰‹ˆ‰‰‰‰‰ˆˆŠŠ‰‰ˆˆ††……‡‡‡‡‡‡‰‰ŠŠ‹ŒŠ†„‚€€€€ƒ„††‡‡‡†…†ˆ‰Šˆ‡ˆ††ˆ‡‡††††………†‡‡……„„„„„„…„ujcgqzƒƒ‚‚€~|||~{}‚‚…†……††‡ˆˆ‹ŒŒŒŒŒ‹†ƒƒƒ…‡ŠŽ‘’’’’’’’”’{omops{‚Š’“”•”•••––––“Štqsv}†ŠŒŽŽ~~~~}|{{z{{{{{{{||{{{{|}}}}}}}}}~~~~}}}}}}}}}}}}||||||{{||{{{{z|||}}~~{ytpmnory|~€}zwpgZXfu‚‰‰…ƒ†ŒŠŠŠŠŠ‹’’‹ˆ„{rl`e|†ŠŠŠŠŠŠŠ‰‰ŠŠ‰‰‰‰ˆˆ‡‡‡‡††‡‡ˆˆˆ‰ŠŒŒ‹ˆ††„‚€€‚„††‡‡‡†‡‡ˆŠ‰‡…„„„…††††††………†…………„„„„„„„‚|qc^]eoz€€}yx|~||~ƒ…†‡‡††‡ˆŠŒŒŒŒŒŒ‹ˆƒƒƒ…†‰ŒŽ‘’’’’’’’”Žƒrllnpv}„‹“”•”•••–––•’Œ†{ssuz‡‹ŽŽŽ}}}}||||}}||{{zz{{{{{{zz{{}}||}}|}}}}~~~~~~~~~~~~}}}}}}}}}}||{{zz{{zzzyyz||z||||yplmknry€€~€€~zsk]Z]js}‡‹‡ƒ„‰ŽŒŠ‰Š‰‰‰‹ŒŽ‰‡…ƒ{unbo‹‹‹ŒŒŠŠŠŠ‰‰ˆˆˆˆ‰‡ˆˆ††‡‡ˆ‹‹‰‰ŠŠ‹ŒŒŒŠ‰‡…ƒ‚€‚‚„††‡‡‡‡‡ˆ‰Š‰„€}ƒ„„……†††…†…„„ƒƒƒ„……†…„ƒ|qe^Y\emt{}zyyy{~}|~‚„„…†‡‡‡ˆ‰‹ŽŒŠ†„‚……ˆŒ‘‘’’’’’’”‘‡znnlmqx€‡Ž’•••”•••–––”‹„wsru}„ŠŠŽŽ‹}}}}{{||}}||{{zz{{{{{{|||||||||||}}}}~~~~~~~~~~~~~~}}}}}}}}}}}}||||{{||zyyz{{yyz{yunkkjjnx|~€{tkb[\aemx…‰…„ŒŽ‰ˆˆˆˆˆ‰‹‹Š‡††‡†ƒ‚€}~‚‡‰‰ŠŠˆˆ‰ˆ‰‰ˆˆˆˆ‰‡ˆˆ††‡‡ˆŠŠ‰‰‰‰Š‹‹ŒŒ‹Š‰‡„ƒ‚‚„††‡‡‡‡‡ˆ‰‰„~ywz€‚€}~~ƒ„…†…„„ƒƒƒ„ƒƒƒƒƒƒ}re^\]`ipwyzzyvvx{|{z}„…„†‡‡‡ˆ‰ŒŠ‡…ƒ„†‡ŠŒ‘‘’’’’’’’Œ~qmnmqu|Š’•••”•••–––”Štstx†‹ŽŽŠ„}{{{{{{y{{{{{{zzzzzz||{{}}}}}}zz}}}}}}}}~~~~~~~~~~~~}}}}}}}}}~~~~~}}||}}}}{zy{zywvxywrlggghmu{~ypiedcecags‚ˆ†„Ž“‰ˆˆ†††‡Š‰‡ˆˆ‡ˆ‰‹Š‡‡††‡‡ˆˆ‡‡‡†ˆ‡‡‡‡‡ˆˆ‡‡†††‡ˆ‰‹Š‰‰ˆ‰‰‰‹‹Š‰†…………†‡ˆ‡‡‡‡ˆ‰‡‚yvv{}yyy|„…‡†„„ƒƒƒƒƒƒ€€~{tib`_^fmqtx|{zxx{{|{~„…„…†ˆ‡‰ŠŽŽŒŠ‰†ƒ‚„‡ŠŒ‘‘‘““““““’ˆynnnou{€…“••””””•–••’Žˆ~uuvyˆŒŽŽŽŽ‹„|}{{{{{y{{{{{{{zzzzzzzz{{{{||{{}}}}}}}}}}~~~~~~~~~~||}}}}}}}}}~~~~~}}||}}||z{{zzyvuvvuqjfcfghowxphdejlgb`bk}ˆ‡€‚•‰ˆ‰‡††„‡‰Š‰‰ŠŒŒ‹Š‡‡‡‡‡‡‡†…‡†††††……†††††‡Š‹‹Œ‹Š‰Š‹‹‹‹‹‹Š‰‰‡†††‡‡ˆ‡‡‡‡ˆ‰‡{vw}zwx|~‚ƒ……„„„ƒƒƒƒƒƒ}{tmheeb``_`aiq{{tnmqtxy~‚„†…†ˆ‡‰ŠŽŽŒŠ‡ƒ‚„†‰‹‘’’““““““ƒrmopqx}ƒˆŽ’••””””•–••‘†{tuu{ƒŠŒŽ‹„xn{{yyzzzzzzyyzzyyyyzzzz{{{{{{{{{{}}}}}}}}}}}}}}}}}}||}}}}}}||~€€}}}}}}||{zzzyyyyvvtsrmgabchehryzridhnsrqh`^f}ŽŽƒ‹”ˆˆ‰‰…„„„†‰‹‹‹’’Ž‹ŒŠˆ†††††………………„„……†††††‡‰ŠŽŒŒŒ‹‹‹‰Š‰Šˆ‡‡‡‡ˆˆˆˆ‡‡ˆ‡†|z|~‚|z{~ƒƒ„…ƒƒ„ƒ„ƒƒƒ‚‚€zkRFN\eca`a``eluwrnhb][dou~ƒ„‡ˆ†‰‹ŽŽŒ‹‡…‚ƒ„‡ŠŒŽ‘‘““““’‘‹|qnppuy†‹Ž‘“••””””••”“‹‚ywwy†‰ŒŽ‹†zok{{{{zzyyyyyyzyyyyyyyyyzz{{{{{{{{}}}}}}}}}}}}}}}}}}||||||}}~~~~~}}~~}}||{zzzyyxxwwtspkebcgiihjswrklqx|{wqhch€‘’‡‡Žˆˆ‰‰‡†‚„†‰‰Œ‘“”“Œˆ‡††††………………„„„„„„„„†‡‰ŠŽŽŽŽŽŽŒŠ‰‰‰Š‡‡ˆˆ‰ˆˆˆˆˆˆ‡†~}€€}|~ƒƒƒ„„ƒ‚ƒƒƒƒƒ‚‚~ueYX`egebabeecdfllhd^YUOU]^fr€†ˆˆ‰‹ŽŽŒŒ‰†„‚ƒ„‰‹‘’““““““…wqsruy}€‡‘“••””””••”’‡|vwwz€‡ŠŒŽ‡|rmk{{zzyyyyyyzzxxwwxxyyxxzz{|||||{{}}}}}}||}}}}}}}}}}|||||||~}}}}}}~~~~~|}|{yxxyyyyxwurohcadjmlgekrqpru{€€{rmq‚”ŠƒƒŠŒˆ†ˆˆ‡†„‚ƒ…‡‡‹’””’Œ‰††…††‡‡††……„„ƒƒ„„ƒƒ„†ˆŠŽŽŽ‘‘Ž‹‹ˆˆ‡ˆ†‡ˆˆ‰‰ˆˆˆ‡…‚‚‚ƒ‚€€ƒƒ‚‚~{~€‚€€‚‚}wqs}|vnidcgkjeacdfeaXSONTSOQdy„…ˆŠ‹ŽŽŒ‰†‚ƒ„„‡ŠŒ‘“’““’““‚uttty|~‚ŠŽ‘’”””””••••”‘‡|wxx{ƒ‡‰Œ‰€tmmnzzyyxxyyyyyyxwyyyyyyyyzzz{||||}}}}}}}}~~~~~~}}~~}}|||||||~}}~~~~~~~~~|}|{yzzzzzzxwvtokfchnrrojkqqompy‚€ztv‚™’„†‹‰ˆˆˆ‡†…„‚ƒ……‡Š’”’’‰…„………‡‡‡‡……„„ƒƒ„„ƒƒ„††ˆˆŠŒŽŽ’’“‘ŽŠˆ……„…†ˆ‰‰ˆˆˆ‡„ƒƒƒ„„ƒ€yrrw|€€|tporw{{{||€ƒwogcdhpojdb`_ZSKGFF@KJLWer~†‰‹ŒŒ‰†ƒ‚ƒ…‡‹‘‘“’““’“’‰|tssty}‚Š‘’”””””••••”‘‹‚yvyy}…‹‹ˆ‚xpmpsyyyywwwwxxwyxxyyzzzzxyzz{{||||}}}}}}~~}}}}||||{{}}||||||}}~~}|}|{{{{||||zxxwvsnjgfjqturnkmnnihr}‚‚|wxƒ—“…}‚ˆ‰‰‰‰‰ˆ…„ƒƒ…†„‡‰Š’‘Ž†}ƒ……††‡‡‡‡††„ƒ‚‚ƒƒ„„„…‡ˆŠŒŽ‘’‘’““‘Š‡†„ƒ‡ˆˆˆˆ‡†††……‡„zpjgggjpuuqnjjnpsqpsx|ƒ}sjbbadnpleb\YTL@:68=EC@HUfu€†‰Š‹‹Š‰„€‚ƒ…‡ŠŒ‘’’’’“““”Ž„vqrtv{~~ƒŠ‘“”””””””••“’Šwvyy†ŒŠvonquvxxwwwwwwxxwyxxyyyyyyxyzzzzzz||||}}}}~~}}}}||||{{}}||||||}}~~}|||{{{{{||||zxxwurnjeehotutpkjjjdcmz€€zvv€•’ˆ}|‚†ˆ‰‰‰ˆ‡……‡‰‡†††ˆ‹ŽŽ‹ƒrcn}‚„……††……††„ƒ‚‚ƒƒƒƒƒ„†‡ˆ‰Š‹Ž‘‘’”“Ž‹‰†|vy„…‡‡†††„…vliigefginturmhcdghgis|€ukgcabjrqjc]ZUOIB<>GMNRWPMcq}†‰‹‹‰†‚€ƒ†‰‹‘’’’’”””’‹~ustvx}~~‚‘“”””””””••’Žˆ}wxy{‡‹‹„{qmnty|wwvvwwwwwwwwwwyyxxyyzzzzzyzz{{||}}}}}}}}}}}{{{{{||}}{{}}}}}}~|zzyyy||||{{{{{yxvspkdcenswxuplkjgcjw€ytuŒ’“‹‚~~„ˆˆˆ‰‰‡‡ˆ‹‡……†ˆŠ‰Š„vfXYs~‚„„ƒ„……†…ƒ‚‚‚‚‚ƒ„……‡ˆˆŠŽ‘‘‘““‘Žˆ€srv|ƒ‡†‡†ˆ…‚yqoppljijjmtvvnieb`_`fs}ƒ„„‚xmhebcmzzrkd`]YVZ\ZYYTY_H,@_t„‹Šˆ…€€ƒ„‡ŠŽ’’‘’”””’ˆyppruz|}~„‘’“””””“•••’…|wxy|‚ˆŠˆ}toonu}uuvvwwwwwwwwwwwwxxyyzzzzzxyy{{||}}}}}}|||||}}}||{{{{}}}}}}€€~zwvuux{{{|{{{{{{zvsolfcbhnrwvtpkjgcet}~xvsvŒ’“Ž‡}†‡‡‰‰‰‰‹‘‘Œˆ‚~}{|zujaTN[y€„„ƒ„………ƒƒ€‚‚‚ƒƒƒ…†‡‰Ž‘‘‘ŽŠƒxqssy‚…†„~wustvwupnklswwvrnjfffkv‚ƒƒƒ}rlfbfszxsked`^]^cfe_^_Y=,1ATi|„†ƒ„…‰ŒŽ’’’”••”‘„xqqruz|}~„‘’“””””“•••Œƒyvyz~ƒˆŠƒxqpqu|‚ttvvwwwwvvxxwwvvwwyyzzzzzzyyz{||||{|}{}|}}}}}}||||||}}}}}~~€~~~}{wsqsvz|~|}||{z{yyvrmgbcjosuvtroljdaiqropsvƒ’’Š‚}…‡ˆˆˆˆŠŽ“””’‹ƒyoinqlf`TKLc{‚„„„„…ƒƒƒ‚‚‚ƒ„†‡ˆ‹ŒŒŽ‹Š‰‰‡‡ˆˆ‰„vnnruy|~€‚€|yxtu}‚€vpnoquvuutqpnnqv~‚ƒƒƒ{rld_cpwwtoiccbbcgjlkd[M:8FOZpƒˆˆˆ‹‹ˆˆŽŽ’’’“••”€rooovz~}€‡’‘’“””””””•“‰zwxy†‹…ztpqrx‚‡„vvvvvvwwxxxxwwxxyyyyzzzzzzzz{|{{||~~}|}|}}|{||}}||||}}}}}~~€€€|zwsqqsw{|~~~~|{zyxvrmecfnqvxxwvpmkf_biiimrxƒ’’‹……‡ˆˆ‡ˆ‹––—“Ž‡}nggkid^VOGMl|………„………„ƒ‚‚ƒ„‡ˆˆ‡††……ƒ„„ƒ„…ƒ‚{tqruyzyyzywyx{€‚…ƒzqorvyxwwwvsqqtzƒƒƒ}smfbht{{uqjhhgeddccb^TD:?Xw‡‘‘Œ‰„‚ƒ‡‹Ž’’’“““”~rqoov|}€‰’‘’“””””””•“ˆyyyz€†…}ursuwˆ‰ƒuuvvuuuvwwxxxxxxyyyyyyyz||||{|||~}~~||}||||{{{{{{{|||||||}€€€~{wrqqty}~€|{wvttqoiefjpuvxyxvtqokghjmlosz…’‘Š„‡ˆˆˆŠ”˜™—“’‹ƒulihhc[RNHEPu……………„…ƒƒ‚€€€€€€ƒ„†‡††ˆ†……„„…†„‚ƒƒzvruxzyz{yyzx|…‡‚zspsz|zywwxvssw}€‚ƒ…ƒ|tkednx|ytqmllhbbcb_a`TKHPi†“˜™–ˆxuxxwz…Œ‘‘’““””{spoqx~~‹“’“”””””•••“…~{zy{ƒvrquvzƒŒ‰ƒuuvvuuuvwwxxxxxxwwyyyyyz{{{{{|||}|||||}|{|{{{{{{{{{{||||~€€€~{wrqprx{|{vtokighihfeinsvwvxxyxurprtuwqnqx‚‘’”’Œ„„‡ˆˆŠŒ‘•™š™”“Š€vnhdb^WPKCCXy†………„…ƒƒ‚ƒ‚„……†‡‡‡‡‡†……†…„„„‚}wtwyy{{||{z}ƒ…‚ysqv}~}|zzyxuvz}‚ƒ„yqkefowysnklmmjebcfcbaZSPXp‹™Ÿž€zzwtrnlv‡‘‘’““””ˆxqppry~|€‹“’“”””””••”‘‹„|zzy{ytrsw{Š‹†€uuuuuuuvwwwxxxwwxxxxxxyyzzyyz{{z{{{{{{|z{{z|||{{{{||{}~~}~~~~|ytnnov{zwqid`_^\]`chntuxxxxy{xwspty||sosx€Œ“””’Ž…€‚ˆŠŠŠ”™š™—”Œ…unjfa[SLG@Db{„…„„„ƒƒƒƒ‚‚ƒƒ‚ƒ‚„„†††††…††††‡†‡‡……„„ƒƒ|vuxyzz~|{}~wppv€‚‚€|zwwy~ƒƒƒuokeht|ztnihjjmgdefdab_YX_tŠš Ÿ‹yuqlfcr‰’‘‘‘’“””“ˆxoppry}}}ƒŒ‘””””””””••“Šƒ{yzx{}ztrsvx€„Œ‰ttuuuuuvwwwxxxwwwwxxxxyyzzyyyzzy{{{{{{|z{{z|||{{{{||{}~~}~~€€~|vqnorxwsjeaceb_^_elrvxxxxxy{ywtqsy|{rnrv€’””•“Œ…„‡‰ŒŒ’–—™˜–’‘ŽŠ‡€|xqh_YQG@<Ghzƒ„‚‚ƒƒƒƒƒƒ„……„ƒƒ…††‡‡‡‡‡‡ˆŠ‰‰‰‰ˆ†„„‚‚|yy{{{~|{}€€}zxrpqxƒƒ„„ƒ€~zxz~ƒƒƒ~toicht|zulhgimkhhihfdb___ds‡•œšŠ…yphdb^buˆ‘‘‘’“””…wqrsu{}}„Ž‘””””””””••“Š€{{zxxxvqsuy†‹‰†ttuuuuuvxxyyyywwxxxxyyyyzzzzzz{|{{{{{{{{{{{{{{{{||||||~~}~€~ztqpptuofdhmpmfdfnsvyyxxyyzzyxtstx|zroqu{‡‘””–‘‡†ˆ‹Ž’”•—•“‘‹‰ˆ…‚}tjaZWME?CRp|ƒ‚ƒƒƒ‚ƒ…†††„ƒ„‡‰‰Šˆˆˆ‰ŒŽŒ‹Šˆ‡‡†…‚‚‚~{||||~|~€€|yurpqz„„ƒƒ‚‚~|~€ƒ…„|smgcju}|wplhklkmnnkgeca`bdp~–•‰…‚xnd^]\[dzŽ’‘‘’“””ursrt|~~†’””””””“•–•“…}{}}xuussux|‚Š‰‡…‚€vvvvuuuvwwxxwwwwxxxxyyyyzzzz{{{|{{{{{{{{{{{{{{{{}}||||}}€€€}uqmloqnhimuzyrkinuwyyxxyyyy{yvttwzyspqrwˆŒ’–—“ŠŒ‘““”•”’Šˆ‡‡†ypg^YVOIDFTr€ƒƒƒƒƒƒƒ…†ˆˆ‡…‡‰Š‰‹‰‰‹ŽŒŠ‰‡†………‚‚ƒ|||||~}|~‚|uqps~„††…„‚‚‚‚‚‚‚„†ƒzrlcdlx}|xtplkknooomkkheddflq}ˆŒ‰…‚}ujb_`^\i‘‘’“””spont|~~†‘””””””“•“•’Ž…~|~~xsqqrtx€ˆŠŠ‡…stuutuuvuuvwwwxxyyyyxxyyyyzz{{{{zz{{{{||{{{{{{{{||||||}}|€€€~tmikliggrz|ywtruzzyxyyyyzzzzyxuuxxuqqrw€…‡‘——“Ž‘’“”“‘ŽŒ‰‡†…„ƒ€zreZXYRNIL\w‚„‚‚‚ƒ„‚„…ˆ‹Š‰‰‰‰‹‹‹ŽŒŠ††…„†ƒƒƒ}||||}|}ƒƒ€{tqss}…†‡ˆ†…ƒƒƒ……†‡††‚wplghr{~|xxupomlmpnmopnjhilmms|ƒ„„€~xrh_`bbaasŒ’‘“””“‹|roqqv~€}…“••••••“•••’‹ƒ}{~}xqossu|‚‰Šˆ‡†~stuuvvvvvvwxyyxxyyyyxxyyyyyyzzzzzz{{zz{{{{{{{{{{||||~~}}~~€€€€€~yokkgcaeow}|{zzz{{zyyyzzzzzzzyvvxytpnqw}‚…•——“ŒŽ‘“”“‘‹ˆ††…„ƒƒƒr_UTWWTR[gyƒƒ‚€ƒ†ŒŽ‹Š‹ŒŽŽ’”’‹‡„…„„„„„„ƒ~~}|{„„€{urqt}‚…†‡‡‡…ƒƒ„„†‡††}rmifjs}|yxxvtponnrsrqpqpnpsttwx|€}yzwoe`_bdb`l‚‘’“””“‹|rooow~}…‘”••••••“•””‘Šƒ}}~zuqoquy€†ˆˆ‡‡†~rsttuuwwwwvxyywwxxxxwwxxxyyyzzzzzzzzzzzz||{{{{{{{{{}~~~~~~~~~~~€|wqlgb^_isz~~~}|{{{yyy{{zz{{{ywvvwuros|‚ˆ–•”“ŽŽ‘’””’Œ‰ˆ…„…„„„†‡ƒyfWVZ\\Y_k|‚ƒ†ŒŽŽ‹‹‹’”“‹ˆ†……„ƒ……………ƒ~~}~|zz„„€}vqpwƒ†‡‡ˆˆˆ„‚‚………‚ynmjflw}}{ywwxsqppstrpqrqpquxxtpsuussojc^^begfiw‰‘”’‰zrqppx~|†“•••••••••“‘‹‚~~~vsnort{„ˆˆˆˆ‰†‚oqtttuvwwwvxwwwwxxxxwwxxwyyyzzzzzzzz{zzz{{{{{{{{}}{}~~~~~~~~€€€€€~yrkfa^dpz~~~}|zzz{zz{{zz{{{yywwxyyy}€ƒ†Š”–”‘ŽŒŒŽ‘’””’Ž‹‰ˆ‡†„„„„†‡††}rcZ[^_`fr}€„†ŒŽ‘’‹ˆˆˆ‰ˆ‡‡ˆ‡………ƒ€}{z„„~wqpv~„…†‡ˆˆˆ…ƒ‚‚ƒƒƒ|qlljhpy|yxyyzxvtqtvtnmlkjjnppnlllmmnolia\]cghho}…Š‹‹„xqpppx~~‡‘••••••••••“‡~{tpnosw€†ˆˆˆˆ‰†‚oqrssvwvwwyyyyyyxxxxxxyyyyzzzzzzyyyyyzzyzzyy{{||}}|||}~~~~~~€€€€€€€€~xpkfdhpz}~}}{yz{{{{{||{{{{{zxxw{|~„…‡…†Œ’–”‘Œ‹Š‰Œ‘‹ˆ‡………ƒƒ‚„…†……ƒ‚wl^X]bkt{€ƒ††‹’‘‘‘Ž‹ˆ‡ˆ‰‹ŒŠˆ††…ƒƒ‚~{yz~ƒ‚zrlkmr{„…‡‡‡‡…„€|smkmkikoqvyz{}}}}|xyxumf_]]]_ehgfegjmpmkgd`_ahijmsy|€ƒƒ}pppoqx~}~‰’••••••••••“Œƒ~~~yropqt|ƒ‡‡ˆ‰Š‰†‚noprruwvxxyyyyyyxxxxxxxxxxyyzzzzzz{{yzzyyyyy{{||}}|||}~~~~~~~~~~€€€€€€{zuqprx~~}|{z{{{{{{{{{{{{{zxxy|€‚‚‚~„Œ’“‘Œˆ†…„…†‡‡ˆ‡†ƒ‚‚‚‚‚„…†…††‡…„wja`ky}}€‚ƒ…†‡ŠŒŽŒŠŠ‡‰‰ŠŒŠ‡……ƒƒƒ‚~{yz~ƒ‚|qicacdht~„†††‡……‚€vljkjiehlkjlorwy}€}yvrle\VTTTV[dhjmnppqnmiea`cfhiighlqvvrmllmoy€~Š’••••••••••“‹‚~}vqpqsv}„†‡ˆ‰Š‰†‚mmopqttuvwwyyyyyyywwxxxxwwxxyyzzyyyy{{{{{{{{||{{||}}}}}}}}||}}~~~~~~€€~~|||}}|}|||{z||}}|{{|||||||yz|€…„‚}{y…’‘Œˆ…„ƒƒƒƒ…†ƒ‚‚‚‚‚„„†……†††††ƒ|y{}}~„…‡†ˆŠŽŒŒ‹ŠŠ‹‹‹ŒŽŽ‰‡……ƒ‚‚‚€zyy~~ticbcbabkv††‡‡‡‡…}rhghiiejllgecbeipvvrmhc^WROPSY_lv{zzzxxspkedbcddefebbbfhhhhhknw~}€Œ”••••••••••‘Š{sqqsuy„†‡‰‰ŠŠ‡ƒ€mmopprstvwwyyyyyyywwxxyyyyxxwwxxzz{{{{{{{{{{||||||}}}}}}}}}}}}}}~~~~~~~~€€€€~}||{zzz{{|}}|||||{z{||}„†„‚|zz~€ˆ‘Ž‰…ƒƒƒ„„„……„ƒƒƒƒ„…†………††‡‡‡…„…ƒ‚€}ƒ„…‡ŠŒŽŽŒŠŠŠŠŠŠŒŽ‡ƒƒ„†„‚‚‚}|~{pjjiieb`cm|ƒ…†……†‡ƒ{skjjhhfhiiigeecdbccdcb`]\YYZ^hy„……ƒƒ}|wsppokikmopmkigdacccccgqxzy~‹”••••••••••‡}||xruusu{‚†‡‡‰Š‹‹†~mmnoqrsuvwyyyyyyyyxxxy{{yyyyzz{{{{zz{{zzzzzz||||||||||||}}}}}}}}~~}}{{}{}}}~}|}}|{zz||{{{{||||}}||}}{|…†„~|||}ŠŽŒ‡„„„…„……‡†………„„†‡††††‡‰‰‡…„‚~{~‚ƒ„†ˆŠŒ‘ŽŽŒŠ‰‰‰‹‹‹ŒŽŠ„~€„…ƒƒƒ„ƒ‚‚€~ysrqpnlhaacp||{z…‚xnjlkgfhjijihggebbbbabccefediv„Ž’Œ‡‚€~{xvvvtooty~}{ytnhdeddeekoru‹••––––••••”Ž„}zzwrssux{‚†‡†‡ŠŒ‹‡ƒnnnopqrsvwyyyyyyyyxxxyyyyyyyzz{{{{||||{{{{||||||||||{{{{||||}}}}||}}}}}{||}~~~}|}}|{zz||{{||||||||||}}~ƒ…†ƒ€~|z}‚‹ŽŠ‡……††‡‡‰‡‡††……‡†„„„†‡‰‰‡…„‚~|~€‚„„‡ˆŠŽŽŽ‹‹‹ŒŒŒŒˆƒ{}‚…ƒƒƒ‚‚ƒ}xtvxwtstoe`_flihims{{vomnmkggfefgecbcbddfdbagnsv{‚˜œœ‘†ƒ€}}|€€ywz…‡ˆ†„}umkigeefjlq{ˆ”••””••••”‚|{ytrssuy~…‡…~~†‹‹‡nonopqrswxzzyyyyyyyyzzzzyyyyzz{{||||{z{{{{||||||{{{{{{{{{|||||||}}}}{{{{|||||}}}{{}}||||||||||||{{||||~~€~„†„ƒ€~{|€†‹‹‹‰†……‡‰Šˆ††††„„……………†‡‰‰ˆ††}~ƒƒ……ˆŠŒŽŽŽŽ‘’‘‘ŒŒŒ‹ŒŒ‹‡{€‚ƒ„„ƒ€€zqptvrptyvnfaaded`bflqolmnnjkiidcddddccddfhhedmw|‚—š•ˆƒ…‡ƒ}~†Ž‰€€†Š‹ŠŠ„}vrpkhefhiis‰•”“”••••”‹zzvssssvz…ˆ†{z†ŠŒ†lnnooqrsvwwxyyyyyyzzzzzzyyyyzz||~~~~}{{{{{||||||{{{{zzzz{|||||||{{{{{{{{zz|||}||{{{{||||||||||}}||}}||~~€€„…ƒ€€~‚†‡ˆ‡†…„…ˆŠˆ†…„„„„„…………†‡‰‰ˆ†ƒ€€ƒ„…†‰‹ŒŽŠˆŒŽ““”“’‘Ž‹‹ŒŒ‹‰{€‚ƒ„„ƒ{snoqroptx{ulbaddeeffegiklkklpssoigfddddeeegmun_YcwŠ“Š…€„…„‚„šŸ˜’‰„ƒ‚…Š‹ŠŠˆƒ‚}ytnkjjggny‚Š‘“”••••’ˆ{yxussrsw|‚‡‡‚}€ˆŒŒ†nnnnnpqrvxyxzzyyzz{{{{{{{{||}}}}~~}||||||||{{{{{{{{zz{{z|}}|{|||||{{{zzz{{{}}{{}}{{{{||||||}}~~}}}}}~€‚€ƒ„ƒƒ‚ƒ‚€€€„„„…‚€‚…††„„…„……„„„„‡‡ˆˆ…‚€ƒ„‚ƒƒ„‡‰ŒŽŽ‹‰ˆŠŽ’“”•”‘ŽŒŒ‹ŽŒ†€ƒ„…„€|}unklooorvyyuleehijjecccegfdejnvupjfefeebbcbejjcWIVuŠ„†‡‚€‹˜ ŸŸžš“‹†……ˆˆ††‡†€}zvsnlhjr{€‡‘“••–•…{xtsttsuz†‡†~}…ŠŽŒ‡ƒƒnnnnnpqrtvwyyyyyzz{{{{{{{{||}}}}~~}||||||||||}}||{{{{{{z|{{z{{{{{{zyyzzz{{{zz{{{{||||||{{{{||||}}}}}}}~€‚ƒ€‚„……„„„‚‚‚„„ƒ„„€„„„„„„……„„„„„„ƒ‚‚ƒƒƒ„ƒƒ„†ˆ‹ŒŽŒ‹ŒŒŒŽ’“”•”“’Œ†ƒƒ„†„€{zxrlklmlnqvyysmhgikmponjihgfedfhjkkgggfeca_]][]]ZTRXe„ƒ…‹ˆ‰˜ ¢¢ŸŸžžœ”‰…‡‡‡‡‰‰„€{yvqmiosw}„ŠŽ“•””Œwvtsttsv{‚‡ˆz‰ŒŽŒˆ„„oonnnpqsvvwxyyyyzzzz{{|||||||}~~~~~~~~|{{{{{||}}||||{||{{{||{{{{{{{{zzzzzzzzzzzz{{{{|||||z{{||||~}||}}}~€ƒƒ„ƒ‚…‡†††ƒƒ„…ƒ„…ˆˆ„ƒ„„ƒ„……„ƒ„„„„…ƒ‚€ƒƒƒ……„…†‰ŠŒŽŽ‘’””””“’’ˆ…„……wrolnppolmmty{snkhhlppuwupolhfcccbcghijihhie]ZXYYXY_aev‡‡„‡ˆ‰ˆ‹— ¢ ŸŸŸŸŸž›–‘ŒŒ‹‰‡‰ˆ†ƒƒƒ€{zwplprty~†Œ“•’‹~wutssssx‡ˆƒ|}†ŠŽŽŒ‡…ƒoonnnpqsvvwxyyyyzzzz{{{{{{||}~~~~~~~~|{{{{{||||||||{||{{{{{zzzzzzzzzzzzzzzzzzzzzz{{{{{{{yzz{{||~~}}}}}~€ƒ„…ƒ‚€€‚‡ˆˆ‡„‚ƒ„…†…‡‡‡†„„ƒ„………„„„„„ƒ‚‚‚ƒƒ……„…‡ˆ‰ŒŽ‘‘’’’””••”“’‘‘‘“’ŽŠ†„„‚{snopqpmiiiowxrmihinqtvutsqokebaaacdglopqrsrjeddb`agilvƒ‹ŒŽŽŒ‰“¢Ÿž  žž–Œˆ„…†ˆˆˆ…~€ƒƒ~wnrvttv|ƒ‹‘“‘Š}ussqssvz€…†|ƒˆŒŽŽ‹†„ppoonpqtvvwxxyxxyyyy{{{{|{}}~~~}|||}|{{{}}||}}}}zzzyyyyyxxxxzzzzzzyyzzzzzzzzyyz{zz{{{{z|||}}~~~~}€ƒ…‡‡†‚‚‚„‡ˆ‡ƒ‚ƒ‚…††‡‡††„ƒƒ„……††„ƒ„„ƒ‚ƒ………ƒ…†ˆ‹ŒŽ’‘’’’‘‘‘‘’’“”••••••’’’’’ŽŽŠ†„|sqrtspnihgnyxrkgcgpssstsqomjedbbacehmqrsvtutropmllonqz„Ž˜¡¤¢¡    Ÿ Ÿ™Š‚ƒ†‰‰ˆ‡…zw}~€~zty|vurv|„Š‰ztuttttx|‚ƒ|ˆŽŽ‹†…ppppnpqtvvwxxyyyyyzz{{{{{~~~~~~~~}}||}|{zz}}||}}}}||zyyyyyxxxxwwxxyyyyzzzzzzzzzzz{{{{{{{z|||~~}‚…‡‡†……ƒƒƒ„……„‚ƒ††…‡†…„ƒƒ„……„„„ƒ„„„…………†ˆ‹‘’’’‘’‘‘‘‘‘’“•••••–””••’‘Š†zqstuusqnhejsuoieclruvutsomkfdcbdegkmoqstwvtrqsvtssuwvx€Š’“œ¤¦¤¢¡¡¡  Ÿ–†€€‚†‰Š‰†‚vnr{~€€{z…‚yvuu}…ŠŒ…ystuuuv|€…€|†‹ŽŽŽ’Œ†…ppoonrsuwwwwwwxzzzzzz{}}~~~~~~~~|}}||||||||}}}}}{zyyyywyyxxxxxxxxyyzzyyyyz|{{{{{{||{{{{||}~~~}}~~€‚…ˆˆˆ‡‡†…„ƒƒ„„ƒƒ„††††††……„„„„„ƒƒ„‚ƒƒ…‡††††ˆ‰Œ‘‘‘‘‘’““••–––•••’‘‹…{tsyxusuphfkqqlgdentwxvuqokjgedefhlqqrrruuqpnpw{{xvvvspr}Š‘–Ÿ¥¥¥£¢¢¢¡¡™‡€€€€„‰‰Š‰„vjiu~}|ƒŠ‰€ywxz†‰‚zuvvvux|€€|~‡ŠŽŽŽ‘”…ƒppppqqsuuuwwwwwxyyzzz{||}~}}€|}}||||||||}}}}{zzyyyywwwxxxxxxxxyyyyyyyyyz{{{{{{||{{{{||}~~~~~„ˆˆˆˆˆˆˆ†…ƒ‚‚ƒ…‡‰‰‡†††……„„„„„ƒ‚ƒ‚ƒ„†‡†‡‡ˆ‰ŒŽŽŽŽ‘’““••–––––•“‘‘‘‘’‘‹‚{xyxxwwrljptrmjdgqvwzzwrpiiifeeinvywuuusrmhgkry{vsttpmmtƒŽ‘™¢¥¥¥£¢¢¢¢Œ€€€€€€…‰Š‰†qgm{€€}{„Œˆ€xsu{…vtwuuvyy{z€†ŠŒŒŽ’‘‹„‚ppqqprqttuxwxxvwxx{{{||}}}}}}~~~€€|}}~~||{{||}}}}{{{{zzywxxwwvvwwwyyyxxyyzz{{{{||||{{||}}}}}}~~~~~€…ˆ‰‰‰‹‹ˆ…‚€„ˆŠŠ‡‡‡‡†††„‚ƒƒƒƒƒ„…‡†ˆˆ‰‰‰ŠŽŽŽŽ‘‘Ž‘‘‘’“””––––••”“““““““’Ž†€zvwyzvonpsqmhflvxuxxtqmjiiggflq|}xxuronidbluxutrrrnkq€‹”™¢¥¦¥¤¤£  “ƒ€€€€€€…ŒŒˆ‡siky€€~z‚“Œ‡€yx{€|uvwuvvxwz†‹ŽŽŽ’•‡~xqqqqrsttttutvvvwxxyyz{|}}}}}}}}}~~~~~~~~}}||||}}}}}}}}{{{{zzywxxxxxxxxwyyyxxyyzzzz{{||||||||}}}}}}~~~~}‚…‰ŠŠ‹ŒŒŒŠ‡…ƒ‚ƒ…‡‡‡ˆˆˆˆ‡†ƒƒƒƒƒ„††ˆ‰Š‹ŒŽŽ‹ŒŽŽ‘’‘Ž‘’‘’““””––––••–”””””””“‘‘Ž‹„}~}wrpqsplhfpzzxyxuojjllllklpwz{yvurrpkfelttstsssoor|†Ž”›£¦¦¥¤¥¤¢›ˆ‚€€€€€€€†ŽŽ†‚|qgju~€~z€“Šƒ~{}€xsuvuvwy{†Š‹ŽŽŒ‹Šƒyqnrrqrssttstuuwwwxyyzzz{||||}}||}~~~~~}}}}}}||{{}}}}~~}}{{|z{{yyxxyyzzzzyxyyxxxxyyyyzz{{{{z{{{{|}}}}}~~~~~€†‹ŒŒŽŽŒŠ‰‡…„…ƒ„„…ˆˆ‰ŠŠŠˆ‡‡…ƒƒ…†‡ŠŠ‘‘ŽŽŒŒŽŽ‘’“’’‘’’“““““””•–––––•••••••••““’’ˆ†€vqqrrolhgs~z{zvrmmmpooonkmorstxtssolklpsqtutrrssy…Ž”›¢¦¦¦¤¤¥¢„€€€€€€ƒ„‹Œ…€zrmnw}}z}Š“‹†}€}xuvvwwx‚‡‰‰„…‰‰‡ytmigkqqqrsstttuuvwwwxyyyyxyzzzzzz{{{{{{{{}}}}}}||}}~~~~~~}}||}|{{zzyyyyzzzzzyyyxxxxyyzzzz{{{{z{{{{|}}}}}~~~~}ƒŠŒŒŽŠ‰‰ˆ†…ƒƒ„†‡ˆ‹‹Šˆˆ†…„…†‡‡ˆ‹““‘‘‘ŒŒŒŒŽ‘’““’’‘’’’“””““””•–––––•••••••••””““”“Šxrrrqnkgfs}~~zussstrrqpljjjjkopqqqqplloqtutuussw‚‹‘š¢¥§§¥¥¤œˆ‚€€€€€€€…†ƒ€zrmntz~~z}‰’‘ˆƒ‚€}xuvvvv{‚ˆŠ‡}vtxwpjdbcejnrrssrrttttvvwwwwyyxxwwxxyzyyzzy{zzz{||}}~~}}}~~~~}}}{yzzzzxxxxzzzzzzzzyyyyyyz{{{||||||||{|}}}}~~€€~~€ƒˆŒŽ‘’‘ŽŒ‹‰Šˆ†……„…††ˆˆ‡†…‚ƒ„†…†…ˆŒ‘’’‘‘‘‹‹ŒŽ‘‘“”•“’‘‘’‘“““””••””–––––••”••••”””””””“‡€zvuupnjgdp€„€}|zuttuutqswtomhgfgjmmmpnmlnrvtustuw~…Š˜¡¥¨§¥¥¢”…€€€€€€€€€€€€~wolquz}y{‡‘’Ž‹…‚zvuuuux~†ŠŠvnkligfebbeimuuttttttttttuuuuvvwwwwwwwwxxyyxzzz{|||}}|||~}}~~~~}}}|zzzzzzzyyzzzzyyzzyyyyyyz{{{||||||||{|}}}}~~~~‚‡ŒŽ‘’’‘Ž‹ˆ‡†‡††…†††††‡†ƒƒ„………‚ƒ‰Ž’’‘‹Œ‹ŒŽ‘““”•”“‘‘’‘“““””••––•••••”””••••”””””““‘Š|{|‚xrjfs‚†‚}zwuuuttromu~{wpkgefggilljjkmpuvvwx}„ˆ‹Ž–œ£¥§§¦¢„€€€€€€€€€€€„„ƒ{sqsy{x{†ŽŒ‰†‚~wtuuuwz‡†xqponoqrsrrtxzttttttttssuuuuttvvwwwwwwwwvwwwwwyy{|||}}||||}}~~~~}}}{{{zzzzzzzzyyyyyyzzzzzz{{{{{{{{{{z{|||}~~~~}}|†‹‘‘””‘‹ˆ‡‡‡‡ˆˆˆˆˆ‡ˆ…„ƒ‚…‰‡‡†‡ŠŽŽŽŽŒŽŽ‘’”””–••“’‘‘’’”””––••””••””””““••”””””“‘‹ƒ|~…ˆŠ‰ˆ„you€ƒ{xuuuwvtrmhn{ƒ‚{snjc``dfgiljknpruwz€…‰Œ”š £¦¦¦ŸŽƒ€€€€€€€‚‚ˆ”Žƒysqvyvu|‚}}~€|vvvuuwz€„‚wprtwwwz|~‚……‡„ttssttttttuuttttuuuuuuuuvvwxxxxxxxz{{{{{|||||}|}~~}}}{{{zzzzzzzzyyyyyyzzzzzz{{{{{{{{{{z{|||}}}}}~~~~}}~€†Œ‹‰‰‰‰‰ŠŠŠŠŠŠ‰ƒ‚‚„‡‰‰‰ˆŠ‹ŒŒŽ‘“””•––—•’‘‘’’”””””””““””“““’““““’’’’“‘Œ…€ƒˆ‹‹‹Ž‹‡ƒ††„yustuwvsmgfo|}xpdbbabcehikmoqs|„‡‹Œ—¢¥¦¦Ÿƒ€€€€€€€ƒ†„ƒ˜›”Œ‚{ttqnkjkhiiinstsvvuuy{€ztsuwz{~ƒˆ‹Œ‰‡„‚ttssrsttuuuuuuvvuuttstuuuwwwvvwwxxyyzz{{{{||||}}}~~~~~~~~||{{{zyyy{{{{zzzzz{zz{{{{|z{{{{{|{{||||~~}}}}}}~}ƒˆŒŽŒŠˆŠŠŠŠ‹Š‰Š‰…„ƒ„‡‰‹‹‹‰ŒŽ‰‰ŠŒ‘‘“”––––––”“‘‘““””•”““’’““““““‘‘‘‘‘‘‘‘‘Š…„…ŠŽŽŽŽ‹‰‡‚|z{yxtqlhehozysjhgc``afgghimr{€…‡ŒŒ”š ¤§§¡’„€€€€ƒ„„†‹‘ˆyqlifebaa__bgmpqrtuvx~}vuvvx~„‡‹ŽŒŠ…‚zttssrsttuuuuuuttttsssttutvvvvvwwxxyyzz{{{{||||}}}~~~~~~||{{{zy{{{{{{zz{{{|{{|||||{{{{{{|||||||~~~~}}}}}€„‰‹ŽŠŠˆŠŠŠŠ‹Šˆˆ†ƒ‚ƒ††‡ˆˆ‰‹ŽŽ‹Š‘’‘‘““••––——•”““““““““’‘‘‘‘‘‘‘‘‘‹ˆ…ˆŒŽŽŽŽŒ‹‰ˆˆ‰‡†„|umjhhmttnkjnokjiiggffghkrx}‚†Š‹Œ‘—Ÿ£¥£‘†ƒƒ‚~~~||{xxwvtooifedccb`]\_`cgmpsuuxz{ww{ƒˆ‹ŒŽŽŠˆ…‚€ssttttttuuuuttsssssstuuvvvvvvvvvvvxxyyyz{{{{{{{|}}~~~~~}}{z{{zzzz{{zz{{z{{{||{{{|||{{{}||}}{{||~~~~}}|~‚„†‰‹ŽŽŠ‰‰‰ŠŠŠŠŠŠŠ‡…‚ƒ„…„…‡ˆ‰ŒŽ’‘ŒŒŒŽ‘’’‘‘‘’”•••——––”“’‘‘‘’’‘‘‘Ž‹ˆˆŠŽŽŽŽŽŽŽŽŒŒŒŒ‹ŠŠ‰‰Š‡„|tpqqomjmrssqtrnjgeddhmrv|€…ˆ‰’œ¡Ÿ—†€}}|zyyzyxvuttsqolhgfeddcceffbaaadgkntw{}ƒ‡‹Ž‰‰‰†…ƒ‚ƒrrssttttuuuuttttssssttuvvvvvwwwwxxyyyyyz{{{{{{{|}}~~~~~}}}|||{{{{{{{{||{|||||{{||||}}{}||||{{{{~~~~}}|~ƒ…ˆ‰ŠŒŽŽ‹Š‰ŠŠŠŠŠŠŠ‰†ƒ‚‚„‡ˆ‡‡†‡ŠŒŒŽ’““’‘’”•••––––•”‘ŽŽŒŒŽŽŽŽŽŽŽŽŽŽŒŠ‰ŠŒŽŽŽŽŽŽŽ‹ŠŠŠŠ‰ˆˆ†‡†„…‚~€‚‚ƒ‚{wrjgddfinrwz}„ˆŒŽŒ†€|yyxzyyzzzz{{xywvtrpliidcacefhhgfdddefhlu‚‡Š‹Ž‹ŠŠ‰‡††…ƒ„ssssssssttutssttssrsrsttvvwwwwwwxxyyzz{{{{||zzz|}}~~~~}}}}~~}|||||||{{}|||||||{{||}}~~}}}}}}||||~~~~}|~‚…‡‰Š‹ŒŽŒ‹ŠŠŠŠ‰‰ŠŠ‰‡ƒ‚†Š‹‡†‡‰‹‹ŒŒŽŽŽŽ’“’‘’“••””–•••’ŽŒ‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŒŠ‰Š‹ŽŽ‹‹‰‰‰ˆˆˆˆˆŠŠ‰Š‰ŠŒŒŠ‰††…„~unhddfijlory|{zyxxxxyxx{}~€€€‚ƒƒƒ}yvuspliea`cgghjjigfcccfkv‰‹ŒŽŽŒ‹‹Šˆˆ‡‡……ttttuuuuvvutttttssrsuuvwwwwwxxxxxxyyyyyy{{|||||}}}~~~~}}}}}}|{{{||||}}}|||||||||||}}~~}}}}}}||||~~~~~}}‚„‡ˆŠŠ‹ŒŽ‹ŠŠŠŠ‰‰‡ˆ†ƒ€ƒ†‡ŠŽŠ††‡ˆŠ‹ŽŽŽŽŽŽ’“’‘‘’“”•–••••“‘Œ‹‹Š‰‰‰‰‰‰ŠŠŠŠŠŠŠŠŠŠ‹‹Š‰ˆŠ‹‹‹‹‹‹‹‹‹‹ŒŒŽŽŒŒŠ‰ˆˆˆˆˆˆŠŠŠŒŽŽŽŽ‰ƒzoigghihhklnoqvvxxy{}€‡Œ‘“’Œ‹Œ‹†~zwwurpnkjieeimoomkifccedem|†ŠŒŽŽŽŒ‹ŠŠŠ‰‰‡‡ssttuuuuuuutttttssrtuvwwwwwwxyzzzzyyzzzz{{|||||}|~~~}}}|}}||||}}}}}}||||{{}~~~~~}}}}}{{{{{||||{{{|{}€ƒ…‡‰Š‹ŒŽŽŠ‰‰‰‰ŠŠˆ…ƒ~~ƒ†‡†ˆ‹ŒŒ‰††‡‹ŽŽŽŽŽ’’“’‘‘“”””””“‘ŒŠˆ‡ˆ†‡‡‡‡ˆˆ‰‰‰‰ˆˆˆˆˆ‰Šˆˆˆˆ‰‰‰‰‰‰‰‰‰‰ŠŽŽŽŽŽŽŒŒŒŠŠ‰ˆˆ‰‰‰‰‹‹ŒŽŽŽŽŒ…{phjiijllggjmossw|‚Œ’–˜››˜“‘’ˆ~yxxyywyyvuojjlmqqookjfcddbep€‰ŽŽŽ‹ŠŠŠ‰‰ˆˆuuuuuuuuuuutttttsstuvvwxxxyyxyzz{{zzzzzz{{|||||}|~~~~~}|}}||||}}}}}}||||||}~~~~~}}}}}{{{{{||||{{{|~‚…‡‰‰‹ŒŽŽŽŽŒŠ‰‰‰‰ˆ‡…|}‡ˆˆˆˆ‰‹ŒŒ‰ˆˆŠ‹ŒŒ’’“’‘‘’“”””““‘ŒŠ‰ˆ‡†…………††‡‡‡‡ˆˆˆˆˆ‰ˆ‡‡‡‡ˆˆˆˆˆˆˆˆˆ‰Š‹‹ŒŒŽŽŽŽŒŒŒŠŠ‰ŠŠ‰‰‰‰‹‹ŠŒŽ‹Š…{rlihillheeghlqu~†Œ’’““”’‘‰…„‚ƒ…†‹ŒŠ…}tppoqrrpppnjgddcbfrƒŽŽ‹ŠŠŠ‰‰ŠŠvvuuvvuuvvvutssstttvxwyzzyzz{{{{||{{{{zz{{zz{{}}}}~~}||||}}}}}}}}||||}}~~~~~}||||{{{{|||||||||}…ˆ‰‹‹Œ‹‰‰‰‰‡‚~{~…‹‹Š‰ˆŠŠ‹Œ‹‰ˆˆ‰‰Š’‘‘‘‘’’’’“‘‘‘‘‘‘’““’‘‘‘ŽŒŒŠ‰ˆ‡†„ƒƒƒ„…††††„†ˆˆˆˆˆˆ‡†‡‡ˆ‰‰ˆ‰‰‰‰‰‰ŠŠ‹ŒŒŒŒ‹Š‰‰‰‰‰‰ˆŠ‰‹ŽŠˆ„zqkfgjmkjfcffgjnrv{…‡‹‹ŽŒŒŒŽŽŽ‘‘‹‚wpmrvyyuqponjgffecix…‘ŽŒ‹ŠŠŠŠŠŠŠuuuuuuuuvvvutssstttvwxzz{zyyzzzz||||{{zz{{{{||}}}}~~~}||||}}}}}}}}~~||}}}}}}}}|{||{{||}}|||||||}‚†‰‹ŒŽŒ‰Š‰‰‰†{z{€„‰ŒŒŠ‰ˆ‰ŠŽŽ‹‰ˆˆˆŠŒ‘‘‘’““’‘’‘‘‘‘‘’’ŽŒŒŠ‰ˆˆ†‡†„„„…††……„†‡‡‡‡‡‡†………ƒ…‡‡‡‡ˆˆˆˆˆˆŠŒ‹‹ŒŒ‹‹Œ‹ŠŠ‰‰‰‰‰‰ˆŠ‹ŒŽŽŽ‹Š††‚zpjijmqpnfcccdehhimr{€„ˆŠŒŒŒŽŽŽ‘‘Œ†|rmmt}}ytpnljihffgmx…ŒŒ‹ŠŠŠŠŠŠŠttvuttttvvvussrrsuvvwyz{||||}}}}}}}}||||}}}}}}~~~~~~~~~~}}}}{{||}}}}}}~~}}}|}~~~}|}|||||{|||||||{~…ˆŠŒŽ‹Š‰‰ˆ‡ywy~ˆŠŠŒŒŠˆˆˆŠŒ‰‡‡ˆ‰‹Ž’““””’‘’‘‘‘Œ‹ˆ‡ˆ‡†‡‡…†………„„……††‡‡†††„„‚‚„‡‡‡ˆ‡‡‡‡‡ˆ‰Š‹‹‰‹‹‹Œ‹Š‰‰‰‰‰‰‰ŠŠŠŠ‹ŽŽ‹‰ˆˆ‡‡}qffgorokffcbdfdacehow…‰‹Ž‘’’’‚xpnrzƒ„yqlknnligghnx‚ŠŽŒ‹‰‰‰‰‰‰wwvuvvvvvvuvttsstvwwwyz{||}}~~}}}}}}}}||}}}}}}~~~~~~~~~~}}}}||||}}}}}}~~€€}|{}~~|||{{{zz{|||||||{~ƒ†‰‹ŽŽŽŒŠ‰‰ˆ†yx{†ŒŽ‹Œ‹‰ˆ‰‹ŽŠˆŠ‹‹ŒŽ‘“”•–”’ŽŽŽŽŽŽŽŒ‹Š‰‰ˆˆ‰ˆ‡†………†††††††††††„„‚‚ƒ„†‡‡‡‡‡‡ˆˆˆ‰‰‰‹‹‹‹ŠŠ‰‰‰‰‰‰‰‰‰‰‰Š‹ŒŒŒ‹ŠŠŠŠ‡€uhehmqtqkfa`dikjfdejr~†‰‹‹ŒŒŽ’‘‘‡wppw€……xnklpqpkhhjmuƒŠŒŒ‹‰‰‰‰‰‰wwxxwwwwwwvvvvuutuvwxxz{}~~|}}}}||}}||}}}}}}~~~~~~~~~~}}||}}}}|}~~~~~~~~}}||}|}|{{{zyxyzz{}}||}€„ˆ‹ŽŽ‘‹‰‰‡‚zw{‚‡ŒŽŽŒŒ‹Šˆ‰‹ŽŽŠ‰‰‰Š‹Ž‘’”•—˜•“‘ŽŽŽŽŒŒŽŽ‹‹ŠŠ‰‰ˆ‡††……‡‡††††††‡‡…„‚~€‚„†‡‡ˆˆ‡ˆˆˆ‰‰ŠŠ‹‹‰‰‰‰ŠŠ‰‰ˆˆˆˆˆˆ‰ŠŠŠ‹‹‹‹ŠŠŠŠŠŠ‹‰‚whdfkqsqlfeimsvurnqv~‡ŠŒŒŒŒŽ‘‘‘Ž‰‚|vqt{ƒ††~tmkptytmiijlt~‡Š‹‹Š‰ŠŠŠŠxxxxwwwwwwvvwwwwvwyz{{{|}~~~~}}||}}}}}}}}}}~~~~~~~~}}~~}}}}|}~~~~~~}}~~}||{zzzyxwxyz{||||}€…‰‹ŒŽ‘Ž‹ŠŠŠ‡yxzˆŒŒŒŒ‹‹ŠŠ‹Ž‘‹‰‰‰Š‘“’”•–——”“’‘ŽŽŽŽŒŒŒŒ‹‹ŒŽŽŒŒ‹‹Š‰‡‡‡‡‡‡††††††‡‡†…ƒ€~€‚…†‡ˆˆ‡ˆˆˆ‰‰‰‰‰‰‰‰‰‰ˆˆ‰‰ˆˆˆˆˆˆˆ‰ˆˆ‰‰‰‰ŠŠŠŠŠŠŠ‹Š†zngefnvxsmhjovƒ……‡‰‹Ž‘’’’‘Œ‡wppx€„ƒyrllovzwpjhgglv…‡‰‰ŠŠŠŠxxwwwuwwwwwwxxxxvwz{|~}~~~~~}}~~}|||}}~~~~~~~~~~~~~~~~}~~~~~}}}}}}}}|{{{{yyyxxxwyzz{{||‚†‰‹Œ‘‘‘Œ‹Šˆ‚xuz‡ŒŒŒ‹ŽŽ‹Š‰ˆŠŽ‹ˆˆ‰Œ‘‘“”•••••““ŽŽŽŒ‹‹ŠŠ‹ŒŽŽŽŒŠŠ‰ˆˆ†††††††††‡„ƒ}|~††ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰ˆˆˆˆ‡‡‡‡‡‡ˆˆˆˆ‰‰‰‰‰‰ŠŠŠŠ†~ujcdny|xsnjmv~†‹Œ‘’““’‘ŽŒ‰„wppv~‚‚€}wrqpuy{xqjggehq~…‰‰‰‰‹‹xxxxyxxxwwwwxxyywxz{|~}~~~~~}}~~}|||}}}}}}~~~~~~~~}|}}~~~}}}}}}}}|{{xxwwxwwwvxzz{{||‚‡ŠŒŽŽŒ‹ˆ„|uv}„‰ŒŒŒ‹ŽŽŒŠˆ‡ˆŽŒ‹Š‹Œ’““““”””•–•”‘ŽŒŒŒŠŠ‹ŒŒŒŽŽŽŒŒŠ‰‰ˆ‡‡‡‡††††††„‚z|ƒ…ˆˆˆˆ‰‰‰‰‰‰ˆˆˆˆˆˆˆˆ‰‰ˆˆˆˆ‡‡‡‡‡‡ˆˆˆˆ‡‡ˆˆ‰‰ˆˆˆˆ‰ˆ…{nbajx~|tljmt}…Š‘’“”“‘ŽŒ‰…zspt{„€}yxsruy{voiecchuˆ‰‰‰‰‰zzzzyxxxxxwwxxyyzyy{{|~~}€€~~}}}}}}}}}}||}~€€~~~~}}}}}}}}}|||{zzyxxwuxxwwxyxz{|„ˆ‹ŒŽŽŽ‹†|wx|ˆŒŽŽŒŒŽŽŽ‹Š‰‰‹ŽŒ‹Œ’“”“““””••••“‘’’‘ŽŽŽŽŒ‹‹‹Š‹ŽŽŽŒ‹Š‰‰ˆˆˆˆ††…†‡‡‡‡†„€}{|‚„‡‡‰‰‰‰‰‰ˆˆˆˆˆ‰‰‰‰ŠŠ‰‰‡‡††††††††††‡‡‡‡ˆˆˆˆ‰‰ŠŠŠ‡{j^\fu|{uoons}…ŠŒ“•”•’ŽŒŠ†wrry~„ƒ‚€€|xtvxwrjfebem}†ˆ‰‡ˆˆzzzzyxxxxxxxyyzzzyz{{|~~}€€~~}}}}}}}}}}}~~~~~~~}}}}}}}}~~~~|}||zyyyxxwuvvvvvwxzz{~ƒˆ‹ŒŽŽŽŽ‹…~uvz€…ŠŒŒŒŒŒ‹Œ‹ŠŠŒŽ‘‘Ž’“”“““““””””’‘’“’‘ŽŽŽŒŒŒŒŽŒŠŠŠ‰ˆˆˆ‡‡††…†‡‡‡‡‡†ƒ€~€ƒ…‡‰‰‰‰‰‰ˆˆˆˆˆˆˆ‰‰ˆˆˆˆ‡‡††††††‡‡‡‡‡‡‡‡ˆˆˆˆ‰‰ŠŠŠŠ‡~n_\^gq{|vpns}„‹’”–——–“‘ŒŠ†ƒ{uru{€‚‚ƒ‡†‚zwwxxrkjgejw‡ˆ†‡‡{{yyxxxxyyyyyyzzz|||}}}}}~~}}}}}}~~}}€~~€€~~~~~}}}|||||||{zywxxwuuvvuuvvxyy{~‚‡ŠŒŒŒŒ‰ŠŒˆ‚xuyƒ‡ŠŒŒŒ‹Š‹ŒŽŽŒ‹ŒŒ’““‘‘’“”“““““’““‘’’‘‘‘ŽŒ‹‹‰ˆŠ‰‡‡‡†„„……†‡††‡††„‚€€€‚‚†ˆ‰‰ˆˆˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡†‡‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆ‰‰‰ŠŠŠ‰ŠŒŠ}h^YZcu}zuqnt}†“”—˜—–”’‹ˆ„}vrru{‚„‡ŒŠ€xvxvsomiefq{…†‡††{{yyxxxxyyzz{{zz{|}}}}}}}€€}}€~~~~~~~~~}}}||||||{zzywxwvuuvvuuvwwxxz}†‰‹Œ‹‰ˆˆ‰ŠŒˆ~vx}„‡ˆŠ‹ŒŒŒŒ‹ŽŽŽŽŒŒŽ’‘‘’’“““““’‘’’ŽŽ’’‘‘‘‘‘ŽŽŽŽŽŒ‹‹Š‰‡††‡‡‡†„„……„†††‡††……„ƒ‚‚‚„‡ˆˆˆˆˆˆˆˆ‡‡‡‡ˆˆˆˆ‡‡‡†‡‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆ‰‰‰ŠŠŠ‰Š‹ŒŠ{h\WXct}~ytor}†‘•˜——–”’ŽŒ‰‰ƒysmov{}€†ŒŽ‹„|wvuqnkgfis~„„„„€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€
\ No newline at end of file
diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc
index a6e5718..b691743 100644
--- a/media/tools/player_x11/player_x11.cc
+++ b/media/tools/player_x11/player_x11.cc
@@ -121,7 +121,8 @@
   collection->SetVideoRenderer(video_renderer.Pass());
 
   ScopedVector<media::AudioDecoder> audio_decoders;
-  audio_decoders.push_back(new media::FFmpegAudioDecoder(task_runner));
+  audio_decoders.push_back(new media::FFmpegAudioDecoder(task_runner,
+                                                         media::LogCB()));
   media::AudioParameters out_params(
       media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
       media::CHANNEL_LAYOUT_STEREO,
diff --git a/media/video/capture/android/video_capture_device_factory_android.cc b/media/video/capture/android/video_capture_device_factory_android.cc
index a473cb9..e9a806a 100644
--- a/media/video/capture/android/video_capture_device_factory_android.cc
+++ b/media/video/capture/android/video_capture_device_factory_android.cc
@@ -22,7 +22,8 @@
 
   JNIEnv* env = AttachCurrentThread();
 
-  int num_cameras = Java_ChromiumCameraInfo_getNumberOfCameras(env);
+  int num_cameras = Java_ChromiumCameraInfo_getNumberOfCameras(
+      env, base::android::GetApplicationContext());
   DVLOG(1) << "VideoCaptureDevice::GetDeviceNames: num_cameras=" << num_cameras;
   if (num_cameras <= 0)
     return;
diff --git a/media/video/capture/mac/avfoundation_glue.mm b/media/video/capture/mac/avfoundation_glue.mm
index a228986..afc92d1 100644
--- a/media/video/capture/mac/avfoundation_glue.mm
+++ b/media/video/capture/mac/avfoundation_glue.mm
@@ -108,11 +108,13 @@
 bool AVFoundationGlue::IsAVFoundationSupported() {
   // DeviceMonitorMac will initialize this static bool from the main UI thread
   // once, during Chrome startup so this construction is thread safe.
+  // Use AVFoundation if possible, enabled, and QTKit is not explicitly forced.
+  static CommandLine* command_line = CommandLine::ForCurrentProcess();
   static bool is_av_foundation_supported = base::mac::IsOSLionOrLater() &&
-      (CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableAVFoundation) ||
-          base::FieldTrialList::FindFullName("AVFoundationMacVideoCapture")
-              == "Enabled") && [AVFoundationBundle() load];
+      ((command_line->HasSwitch(switches::kEnableAVFoundation) &&
+      !command_line->HasSwitch(switches::kForceQTKit)) ||
+      base::FieldTrialList::FindFullName("AVFoundationMacVideoCapture")
+          == "Enabled") && [AVFoundationBundle() load];
   return is_av_foundation_supported;
 }
 
diff --git a/media/video_capture_android_jni_headers.target.darwin-arm.mk b/media/video_capture_android_jni_headers.target.darwin-arm.mk
index 0d058de..16facb0 100644
--- a/media/video_capture_android_jni_headers.target.darwin-arm.mk
+++ b/media/video_capture_android_jni_headers.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_video_capture_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/VideoCapture.java', 'base/android/java/src/org/chromium/media/VideoCaptureFactory.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +66,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -148,7 +149,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/media/video_capture_android_jni_headers.target.darwin-arm64.mk b/media/video_capture_android_jni_headers.target.darwin-arm64.mk
index a0e7c2a..58e2d44 100644
--- a/media/video_capture_android_jni_headers.target.darwin-arm64.mk
+++ b/media/video_capture_android_jni_headers.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_video_capture_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/VideoCapture.java', 'base/android/java/src/org/chromium/media/VideoCaptureFactory.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/video_capture_android_jni_headers.target.darwin-mips.mk b/media/video_capture_android_jni_headers.target.darwin-mips.mk
index 8f398df..91661bd 100644
--- a/media/video_capture_android_jni_headers.target.darwin-mips.mk
+++ b/media/video_capture_android_jni_headers.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_video_capture_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/VideoCapture.java', 'base/android/java/src/org/chromium/media/VideoCaptureFactory.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/video_capture_android_jni_headers.target.darwin-x86.mk b/media/video_capture_android_jni_headers.target.darwin-x86.mk
index 610d539..06d6b7a 100644
--- a/media/video_capture_android_jni_headers.target.darwin-x86.mk
+++ b/media/video_capture_android_jni_headers.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_video_capture_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/VideoCapture.java', 'base/android/java/src/org/chromium/media/VideoCaptureFactory.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +68,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +151,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/video_capture_android_jni_headers.target.darwin-x86_64.mk b/media/video_capture_android_jni_headers.target.darwin-x86_64.mk
index 16887bc..12bad0a 100644
--- a/media/video_capture_android_jni_headers.target.darwin-x86_64.mk
+++ b/media/video_capture_android_jni_headers.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_video_capture_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/VideoCapture.java', 'base/android/java/src/org/chromium/media/VideoCaptureFactory.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +68,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +151,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/video_capture_android_jni_headers.target.linux-arm.mk b/media/video_capture_android_jni_headers.target.linux-arm.mk
index 0d058de..16facb0 100644
--- a/media/video_capture_android_jni_headers.target.linux-arm.mk
+++ b/media/video_capture_android_jni_headers.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_video_capture_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/VideoCapture.java', 'base/android/java/src/org/chromium/media/VideoCaptureFactory.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -64,7 +66,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -148,7 +149,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/media/video_capture_android_jni_headers.target.linux-arm64.mk b/media/video_capture_android_jni_headers.target.linux-arm64.mk
index a0e7c2a..58e2d44 100644
--- a/media/video_capture_android_jni_headers.target.linux-arm64.mk
+++ b/media/video_capture_android_jni_headers.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_video_capture_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/VideoCapture.java', 'base/android/java/src/org/chromium/media/VideoCaptureFactory.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/video_capture_android_jni_headers.target.linux-mips.mk b/media/video_capture_android_jni_headers.target.linux-mips.mk
index 8f398df..91661bd 100644
--- a/media/video_capture_android_jni_headers.target.linux-mips.mk
+++ b/media/video_capture_android_jni_headers.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_video_capture_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/VideoCapture.java', 'base/android/java/src/org/chromium/media/VideoCaptureFactory.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/media/video_capture_android_jni_headers.target.linux-x86.mk b/media/video_capture_android_jni_headers.target.linux-x86.mk
index 610d539..06d6b7a 100644
--- a/media/video_capture_android_jni_headers.target.linux-x86.mk
+++ b/media/video_capture_android_jni_headers.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_video_capture_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/VideoCapture.java', 'base/android/java/src/org/chromium/media/VideoCaptureFactory.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +68,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +151,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/media/video_capture_android_jni_headers.target.linux-x86_64.mk b/media/video_capture_android_jni_headers.target.linux-x86_64.mk
index 16887bc..12bad0a 100644
--- a/media/video_capture_android_jni_headers.target.linux-x86_64.mk
+++ b/media/video_capture_android_jni_headers.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "media_media_gyp_video_capture_android_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/media/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['base/android/java/src/org/chromium/media/VideoCapture.java', 'base/android/java/src/org/chromium/media/VideoCaptureFactory.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/media/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCapture_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/media/jni/VideoCaptureFactory_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +68,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +151,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/apps/js/mojo_runner_delegate.cc b/mojo/apps/js/mojo_runner_delegate.cc
index 94500c2..59e9d7c 100644
--- a/mojo/apps/js/mojo_runner_delegate.cc
+++ b/mojo/apps/js/mojo_runner_delegate.cc
@@ -42,7 +42,7 @@
   CHECK(gin::ConvertFromV8(isolate, module, &start));
 
   v8::Handle<v8::Value> args[] = {
-      gin::ConvertToV8(isolate, mojo::Handle(pipe)) };
+      gin::ConvertToV8(isolate, Handle(pipe)) };
   runner->Call(start, runner->global(), 1, args);
 }
 
@@ -54,8 +54,8 @@
   AddBuiltinModule(gin::TimerModule::kName, gin::TimerModule::GetModule);
   AddBuiltinModule(js::Core::kModuleName, js::Core::GetModule);
   AddBuiltinModule(js::Support::kModuleName, js::Support::GetModule);
-  AddBuiltinModule(js::Unicode::kModuleName,js::Unicode::GetModule);
-  AddBuiltinModule(js::gl::kModuleName, mojo::js::gl::GetModule);
+  AddBuiltinModule(js::Unicode::kModuleName, js::Unicode::GetModule);
+  AddBuiltinModule(js::gl::kModuleName, js::gl::GetModule);
   AddBuiltinModule(MonotonicClock::kModuleName, MonotonicClock::GetModule);
   AddBuiltinModule(Threading::kModuleName, Threading::GetModule);
 }
diff --git a/mojo/apps/js/test/js_to_cpp.mojom b/mojo/apps/js/test/js_to_cpp.mojom
new file mode 100644
index 0000000..a432eb8
--- /dev/null
+++ b/mojo/apps/js/test/js_to_cpp.mojom
@@ -0,0 +1,42 @@
+module js_to_cpp {
+
+// This struct encompasses all of the basic types, so that they
+// may be sent from C++ to JS and back for validation.
+struct EchoArgs {
+  int64 si64;
+  int32 si32;
+  int16 si16;
+  int8  si8;
+  uint64 ui64;
+  uint32 ui32;
+  uint16 ui16;
+  uint8  ui8;
+  float float_val;
+  float float_inf;
+  float float_nan;
+  double double_val;
+  double double_inf;
+  double double_nan;
+  string name;
+  string[] string_array;
+  handle<message_pipe> message_handle;
+  handle<data_pipe_consumer> data_handle;
+};
+
+[Peer=JsSide]
+interface CppSide {
+  StartTest();  // Sent for all tests to notify that the JS side is now ready.
+  TestFinished();  // Sent in echo / bit-flip tests to indicate end.
+  PingResponse();
+  EchoResponse(EchoArgs arg1, EchoArgs arg2);
+  BitFlipResponse(EchoArgs arg);
+};
+
+[Peer=CppSide]
+interface JsSide {
+  Ping();
+  Echo(int32 numIterations, EchoArgs arg);
+  BitFlip(EchoArgs arg);
+};
+
+}
diff --git a/mojo/apps/js/test/js_to_cpp_unittest.cc b/mojo/apps/js/test/js_to_cpp_unittest.cc
index 3b19142..a0df09a 100644
--- a/mojo/apps/js/test/js_to_cpp_unittest.cc
+++ b/mojo/apps/js/test/js_to_cpp_unittest.cc
@@ -9,74 +9,263 @@
 #include "base/strings/utf_string_conversions.h"
 #include "gin/public/isolate_holder.h"
 #include "mojo/apps/js/mojo_runner_delegate.h"
+#include "mojo/apps/js/test/js_to_cpp.mojom.h"
 #include "mojo/common/common_type_converters.h"
 #include "mojo/common/test/test_utils.h"
+#include "mojo/public/cpp/bindings/allocation_scope.h"
 #include "mojo/public/cpp/bindings/remote_ptr.h"
 #include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/system/core.h"
 #include "mojo/public/cpp/system/macros.h"
-#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
 namespace js {
 namespace {
 
+// Negative numbers with different values in each byte, the last of
+// which can survive promotion to double and back.
+const int8  kExpectedInt8Value = -65;
+const int16 kExpectedInt16Value = -16961;
+const int32 kExpectedInt32Value = -1145258561;
+const int64 kExpectedInt64Value = -77263311946305LL;
+
+// Positive numbers with different values in each byte, the last of
+// which can survive promotion to double and back.
+const uint8  kExpectedUInt8Value = 65;
+const uint16 kExpectedUInt16Value = 16961;
+const uint32 kExpectedUInt32Value = 1145258561;
+const uint64 kExpectedUInt64Value = 77263311946305LL;
+
+// Double/float values, including special case constants.
+const double kExpectedDoubleVal = 3.14159265358979323846;
+const double kExpectedDoubleInf = std::numeric_limits<double>::infinity();
+const double kExpectedDoubleNan = std::numeric_limits<double>::quiet_NaN();
+const float kExpectedFloatVal = static_cast<float>(kExpectedDoubleVal);
+const float kExpectedFloatInf = std::numeric_limits<float>::infinity();
+const float kExpectedFloatNan = std::numeric_limits<float>::quiet_NaN();
+
+// NaN has the property that it is not equal to itself.
+#define EXPECT_NAN(x) EXPECT_NE(x, x)
+
+bool IsRunningOnIsolatedBot() {
+  // TODO(yzshen): Remove this check once isolated tests are supported on the
+  // Chromium waterfall. (http://crbug.com/351214)
+  const base::FilePath test_file_path(
+      test::GetFilePathForJSResource(
+          "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom"));
+  if (!base::PathExists(test_file_path)) {
+    LOG(WARNING) << "Mojom binding files don't exist. Skipping the test.";
+    return true;
+  }
+  return false;
+}
+
+// NOTE: Callers will need to have established an AllocationScope, or you're
+// gonna have a bad time.
+js_to_cpp::EchoArgs BuildSampleEchoArgs() {
+    js_to_cpp::EchoArgs::Builder builder;
+    builder.set_si64(kExpectedInt64Value);
+    builder.set_si32(kExpectedInt32Value);
+    builder.set_si16(kExpectedInt16Value);
+    builder.set_si8(kExpectedInt8Value);
+    builder.set_ui64(kExpectedUInt64Value);
+    builder.set_ui32(kExpectedUInt32Value);
+    builder.set_ui16(kExpectedUInt16Value);
+    builder.set_ui8(kExpectedUInt8Value);
+    builder.set_float_val(kExpectedFloatVal);
+    builder.set_float_inf(kExpectedFloatInf);
+    builder.set_float_nan(kExpectedFloatNan);
+    builder.set_double_val(kExpectedDoubleVal);
+    builder.set_double_inf(kExpectedDoubleInf);
+    builder.set_double_nan(kExpectedDoubleNan);
+    builder.set_name("coming");
+    mojo::Array<mojo::String>::Builder string_array(3);
+    string_array[0] = "one";
+    string_array[1] = "two";
+    string_array[2] = "three";
+    builder.set_string_array(string_array.Finish());
+    return builder.Finish();
+}
+
+void CheckSampleEchoArgs(const js_to_cpp::EchoArgs& arg) {
+    EXPECT_EQ(kExpectedInt64Value, arg.si64());
+    EXPECT_EQ(kExpectedInt32Value, arg.si32());
+    EXPECT_EQ(kExpectedInt16Value, arg.si16());
+    EXPECT_EQ(kExpectedInt8Value, arg.si8());
+    EXPECT_EQ(kExpectedUInt64Value, arg.ui64());
+    EXPECT_EQ(kExpectedUInt32Value, arg.ui32());
+    EXPECT_EQ(kExpectedUInt16Value, arg.ui16());
+    EXPECT_EQ(kExpectedUInt8Value, arg.ui8());
+    EXPECT_EQ(kExpectedFloatVal, arg.float_val());
+    EXPECT_EQ(kExpectedFloatInf, arg.float_inf());
+    EXPECT_NAN(arg.float_nan());
+    EXPECT_EQ(kExpectedDoubleVal, arg.double_val());
+    EXPECT_EQ(kExpectedDoubleInf, arg.double_inf());
+    EXPECT_NAN(arg.double_nan());
+    EXPECT_EQ(std::string("coming"), arg.name().To<std::string>());
+    EXPECT_EQ(std::string("one"), arg.string_array()[0].To<std::string>());
+    EXPECT_EQ(std::string("two"), arg.string_array()[1].To<std::string>());
+    EXPECT_EQ(std::string("three"), arg.string_array()[2].To<std::string>());
+}
+
 // Base Provider implementation class. It's expected that tests subclass and
 // override the appropriate Provider functions. When test is done quit the
 // run_loop().
-class ProviderConnection : public sample::Provider {
+class CppSideConnection : public js_to_cpp::CppSide {
  public:
-  ProviderConnection() : run_loop_(NULL), client_(NULL) {
+  CppSideConnection() : run_loop_(NULL), client_(NULL) {
   }
-  virtual ~ProviderConnection() {}
+  virtual ~CppSideConnection() {}
 
   void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
   base::RunLoop* run_loop() { return run_loop_; }
 
-  void set_client(sample::ProviderClient* client) { client_ = client; }
-  sample::ProviderClient* client() { return client_; }
+  void set_client(js_to_cpp::JsSide* client) { client_ = client; }
+  js_to_cpp::JsSide* client() { return client_; }
 
-  // sample::Provider:
-  virtual void EchoString(const String& a,
-                          const Callback<void(String)>& callback) OVERRIDE {
+  // js_to_cpp::CppSide:
+  virtual void StartTest() OVERRIDE {
     NOTREACHED();
   }
-  virtual void EchoStrings(
-      const String& a,
-      const String& b,
-      const Callback<void(String, String)>& callback) OVERRIDE {
+
+  virtual void TestFinished() OVERRIDE {
     NOTREACHED();
   }
-  virtual void EchoMessagePipeHandle(
-      ScopedMessagePipeHandle a,
-      const Callback<void(ScopedMessagePipeHandle)>& callback) OVERRIDE {
+
+  virtual void PingResponse() OVERRIDE {
     NOTREACHED();
   }
-  virtual void EchoEnum(sample::Enum a,
-                        const Callback<void(sample::Enum)>& callback)
-      OVERRIDE {
+
+  virtual void EchoResponse(const js_to_cpp::EchoArgs& arg1,
+                            const js_to_cpp::EchoArgs& arg2) OVERRIDE {
     NOTREACHED();
   }
 
+  virtual void BitFlipResponse(const js_to_cpp::EchoArgs& arg1) OVERRIDE {
+    NOTREACHED();
+  }
+
+ protected:
+  base::RunLoop* run_loop_;
+  js_to_cpp::JsSide* client_;
+
+ private:
+  Environment environment;
+  DISALLOW_COPY_AND_ASSIGN(CppSideConnection);
+};
+
+// Trivial test to verify a message sent from JS is received.
+class PingCppSideConnection : public CppSideConnection {
+ public:
+  explicit PingCppSideConnection() : got_message_(false) {}
+  virtual ~PingCppSideConnection() {}
+
+  // js_to_cpp::CppSide:
+  virtual void StartTest() OVERRIDE {
+    client_->Ping();
+  }
+
+  virtual void PingResponse() OVERRIDE {
+    got_message_ = true;
+    run_loop()->Quit();
+  }
+
+  bool DidSucceed() {
+    return got_message_;
+  }
+
  private:
-  base::RunLoop* run_loop_;
-  sample::ProviderClient* client_;
-
-  DISALLOW_COPY_AND_ASSIGN(ProviderConnection);
+  bool got_message_;
+  DISALLOW_COPY_AND_ASSIGN(PingCppSideConnection);
 };
 
+// Test that parameters are passed with correct values.
+class EchoCppSideConnection : public CppSideConnection {
+ public:
+  explicit EchoCppSideConnection() :
+      message_count_(0),
+      termination_seen_(false) {
+  }
+  virtual ~EchoCppSideConnection() {}
+
+  // js_to_cpp::CppSide:
+  virtual void StartTest() OVERRIDE {
+    AllocationScope scope;
+    client_->Echo(kExpectedMessageCount, BuildSampleEchoArgs());
+  }
+
+  virtual void EchoResponse(const js_to_cpp::EchoArgs& arg1,
+                            const js_to_cpp::EchoArgs& arg2) OVERRIDE {
+    message_count_ += 1;
+    CheckSampleEchoArgs(arg1);
+    EXPECT_EQ(-1, arg2.si64());
+    EXPECT_EQ(-1, arg2.si32());
+    EXPECT_EQ(-1, arg2.si16());
+    EXPECT_EQ(-1, arg2.si8());
+    EXPECT_EQ(std::string("going"), arg2.name().To<std::string>());
+  }
+
+  virtual void TestFinished() OVERRIDE {
+    termination_seen_ = true;
+    run_loop()->Quit();
+  }
+
+  bool DidSucceed() {
+    return termination_seen_ && message_count_ == kExpectedMessageCount;
+  }
+
+ private:
+  static const int kExpectedMessageCount = 100;
+  int message_count_;
+  bool termination_seen_;
+  DISALLOW_COPY_AND_ASSIGN(EchoCppSideConnection);
+};
+
+// Test that corrupted messages don't wreak havoc.
+class BitFlipCppSideConnection : public CppSideConnection {
+ public:
+  explicit BitFlipCppSideConnection() : termination_seen_(false) {}
+  virtual ~BitFlipCppSideConnection() {}
+
+  // js_to_cpp::CppSide:
+  virtual void StartTest() OVERRIDE {
+    AllocationScope scope;
+    client_->BitFlip(BuildSampleEchoArgs());
+  }
+
+  virtual void BitFlipResponse(const js_to_cpp::EchoArgs& arg1) OVERRIDE {
+    // TODO(tsepez): How to check, may be corrupt in various ways.
+  }
+
+  virtual void TestFinished() OVERRIDE {
+    termination_seen_ = true;
+    run_loop()->Quit();
+  }
+
+  bool DidSucceed() {
+    return termination_seen_;
+  }
+
+ private:
+  bool termination_seen_;
+  DISALLOW_COPY_AND_ASSIGN(BitFlipCppSideConnection);
+};
+
+}  // namespace
+
 class JsToCppTest : public testing::Test {
  public:
   JsToCppTest() {}
 
-  void RunTest(const std::string& test, ProviderConnection* provider) {
-    provider->set_run_loop(&run_loop_);
-    InterfacePipe<sample::Provider, sample::ProviderClient> pipe;
-    RemotePtr<sample::ProviderClient> provider_client;
-    provider_client.reset(pipe.handle_to_peer.Pass(), provider);
-
-    provider->set_client(provider_client.get());
+  void RunTest(const std::string& test, CppSideConnection* cpp_side) {
+    cpp_side->set_run_loop(&run_loop_);
+    InterfacePipe<js_to_cpp::CppSide, js_to_cpp::JsSide> pipe;
+    RemotePtr<js_to_cpp::JsSide> js_side;
+    js_side.reset(pipe.handle_to_peer.Pass(), cpp_side);
+    js_side.router_for_testing()->
+        set_enforce_errors_from_incoming_receiver(false);
+    cpp_side->set_client(js_side.get());
 
     gin::IsolateHolder instance(gin::IsolateHolder::kStrictMode);
     apps::MojoRunnerDelegate delegate;
@@ -88,51 +277,39 @@
   }
 
  private:
-  Environment environment;
   base::MessageLoop loop;
   base::RunLoop run_loop_;
 
   DISALLOW_COPY_AND_ASSIGN(JsToCppTest);
 };
 
-// Trivial test to verify a message sent from JS is received.
-class FromJsProviderConnection : public ProviderConnection {
- public:
-  explicit FromJsProviderConnection() {}
-  virtual ~FromJsProviderConnection() {
-  }
-
-  const base::string16& echo_string() const { return echo_string_; }
-
-  // Provider:
-  virtual void EchoString(const String& a,
-                          const Callback<void(String)>& callback) OVERRIDE {
-    echo_string_ = a.To<base::string16>();
-    run_loop()->Quit();
-  }
-
- private:
-  base::string16 echo_string_;
-
-  DISALLOW_COPY_AND_ASSIGN(FromJsProviderConnection);
-};
-
-TEST_F(JsToCppTest, FromJS) {
-  // TODO(yzshen): Remove this check once isolated tests are supported on the
-  // Chromium waterfall. (http://crbug.com/351214)
-  const base::FilePath test_file_path(
-      test::GetFilePathForJSResource(
-          "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom"));
-  if (!base::PathExists(test_file_path)) {
-    LOG(WARNING) << "Mojom binding files don't exist. Skipping the test.";
+TEST_F(JsToCppTest, Ping) {
+  if (IsRunningOnIsolatedBot())
     return;
-  }
 
-  FromJsProviderConnection provider;
-  RunTest("mojo/apps/js/test/js_to_cpp_unittest", &provider);
-  EXPECT_EQ("message", base::UTF16ToASCII(provider.echo_string()));
+  PingCppSideConnection cpp_side_connection;
+  RunTest("mojo/apps/js/test/js_to_cpp_unittest", &cpp_side_connection);
+  EXPECT_TRUE(cpp_side_connection.DidSucceed());
 }
 
-}  // namespace
+TEST_F(JsToCppTest, Echo) {
+  if (IsRunningOnIsolatedBot())
+    return;
+
+  EchoCppSideConnection cpp_side_connection;
+  RunTest("mojo/apps/js/test/js_to_cpp_unittest", &cpp_side_connection);
+  EXPECT_TRUE(cpp_side_connection.DidSucceed());
+}
+
+// TODO(tsepez): Disabled due to http://crbug.com/366797.
+TEST_F(JsToCppTest, DISABLED_BitFlip) {
+  if (IsRunningOnIsolatedBot())
+    return;
+
+  BitFlipCppSideConnection cpp_side_connection;
+  RunTest("mojo/apps/js/test/js_to_cpp_unittest", &cpp_side_connection);
+  EXPECT_TRUE(cpp_side_connection.DidSucceed());
+}
+
 }  // namespace js
 }  // namespace mojo
diff --git a/mojo/apps/js/test/js_to_cpp_unittest.js b/mojo/apps/js/test/js_to_cpp_unittest.js
index 45bb411..49393f5 100644
--- a/mojo/apps/js/test/js_to_cpp_unittest.js
+++ b/mojo/apps/js/test/js_to_cpp_unittest.js
@@ -3,21 +3,116 @@
 // found in the LICENSE file.
 
 define("mojo/apps/js/test/js_to_cpp_unittest", [
-    'mojo/public/js/bindings/connection',
-    "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom",
-], function(connector, provider) {
-  var connection;
+    "mojo/apps/js/test/js_to_cpp.mojom",
+    "mojo/public/js/bindings/connection",
+    "mojo/public/js/bindings/connector",
+    "mojo/public/js/bindings/core",
+], function (jsToCpp, connection, connector, core) {
+  var retainedConnection;
+  var BAD_VALUE = 13;
+  var DATA_PIPE_PARAMS = {
+    flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
+    elementNumBytes: 1,
+    capacityNumBytes: 64
+  };
 
-  function ProviderClientConnection(provider) {
-    this.provider_ = provider;
-    provider.echoString("message");
+  function JsSideConnection(cppSide) {
+    this.cppSide_ = cppSide;
+    cppSide.startTest();
   }
 
-  ProviderClientConnection.prototype =
-    Object.create(provider.ProviderClientStub.prototype);
+  JsSideConnection.prototype = Object.create(jsToCpp.JsSideStub.prototype);
+
+  JsSideConnection.prototype.ping = function (arg) {
+    this.cppSide_.pingResponse();
+  };
+
+  JsSideConnection.prototype.echo = function (numIterations, arg) {
+    var arg2;
+    var data_pipe1;
+    var data_pipe2;
+    var i;
+    var message_pipe1;
+    var message_pipe2;
+
+    // Ensure expected negative values are negative.
+    if (arg.si64 > 0)
+      arg.si64 = BAD_VALUE;
+
+    if (arg.si32 > 0)
+      arg.si32 = BAD_VALUE;
+
+    if (arg.si16 > 0)
+      arg.si16 = BAD_VALUE;
+
+    if (arg.si8 > 0)
+      arg.si8 = BAD_VALUE;
+
+    for (i = 0; i < numIterations; ++i) {
+      data_pipe1 = core.createDataPipe(DATA_PIPE_PARAMS);
+      data_pipe2 = core.createDataPipe(DATA_PIPE_PARAMS);
+      message_pipe1 = core.createMessagePipe();
+      message_pipe2 = core.createMessagePipe();
+
+      arg.data_handle = data_pipe1.consumerHandle;
+      arg.message_handle = message_pipe1.handle1;
+
+      arg2 = new jsToCpp.EchoArgs();
+      arg2.si64 = -1;
+      arg2.si32 = -1;
+      arg2.si16 = -1;
+      arg2.si8 = -1;
+      arg2.name = "going";
+      arg2.data_handle = data_pipe2.consumerHandle;
+      arg2.message_handle = message_pipe2.handle1;
+
+      this.cppSide_.echoResponse(arg, arg2);
+
+      core.close(data_pipe1.producerHandle);
+      core.close(data_pipe2.producerHandle);
+      core.close(message_pipe1.handle0);
+      core.close(message_pipe2.handle0);
+    }
+    this.cppSide_.testFinished();
+  };
+
+  JsSideConnection.prototype.bitFlip = function (arg) {
+    var iteration = 0;
+    var data_pipe;
+    var message_pipe;
+    var stopSignalled = false;
+    var proto = connector.Connector.prototype;
+    proto.realAccept = proto.accept;
+    proto.accept = function (message) {
+      var offset = iteration / 8;
+      var mask;
+      var value;
+      if (offset < message.buffer.arrayBuffer.byteLength) {
+        mask = 1 << (iteration % 8);
+        value = message.buffer.dataView.getUint8(offset) ^ mask;
+        message.buffer.dataView.setUint8(offset, value);
+        return this.realAccept(message);
+      }
+      stopSignalled = true;
+      return false;
+    };
+    while (!stopSignalled) {
+      data_pipe = core.createDataPipe(DATA_PIPE_PARAMS);
+      message_pipe = core.createMessagePipe();
+      arg.data_handle = data_pipe.consumerHandle;
+      arg.message_handle = message_pipe.handle1;
+      this.cppSide_.bitFlipResponse(arg);
+      core.close(data_pipe.producerHandle);
+      core.close(message_pipe.handle0);
+      iteration += 1;
+    }
+    proto.accept = proto.realAccept;
+    proto.realAccept = null;
+    this.cppSide_.testFinished();
+  };
 
   return function(handle) {
-    connection = new connector.Connection(handle, ProviderClientConnection,
-                                          provider.ProviderProxy);
+    retainedConnection = new connection.Connection(handle, JsSideConnection,
+                                                   jsToCpp.CppSideProxy);
   };
 });
diff --git a/mojo/aura/DEPS b/mojo/aura/DEPS
new file mode 100644
index 0000000..698be88
--- /dev/null
+++ b/mojo/aura/DEPS
@@ -0,0 +1,9 @@
+include_rules = [
+  "+cc",
+  "+ui/aura",
+  "+ui/compositor",
+  "+ui/events",
+  "+ui/gfx",
+  "+ui/gl",
+  "+webkit/common/gpu",
+]
diff --git a/mojo/aura/context_factory_mojo.cc b/mojo/aura/context_factory_mojo.cc
new file mode 100644
index 0000000..1dbca80
--- /dev/null
+++ b/mojo/aura/context_factory_mojo.cc
@@ -0,0 +1,66 @@
+// 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.
+
+#include "mojo/aura/context_factory_mojo.h"
+
+#include "cc/output/output_surface.h"
+#include "mojo/aura/window_tree_host_mojo.h"
+#include "mojo/cc/context_provider_mojo.h"
+#include "ui/compositor/reflector.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_surface.h"
+#include "webkit/common/gpu/context_provider_in_process.h"
+#include "webkit/common/gpu/grcontext_for_webgraphicscontext3d.h"
+#include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
+
+namespace mojo {
+
+ContextFactoryMojo::ContextFactoryMojo(ScopedMessagePipeHandle gles2_handle)
+    : gles2_handle_(gles2_handle.Pass()) {
+}
+
+ContextFactoryMojo::~ContextFactoryMojo() {
+}
+
+scoped_ptr<cc::OutputSurface> ContextFactoryMojo::CreateOutputSurface(
+    ui::Compositor* compositor, bool software_fallback) {
+  return make_scoped_ptr(new cc::OutputSurface(
+                             new ContextProviderMojo(gles2_handle_.Pass())));
+}
+
+scoped_refptr<ui::Reflector> ContextFactoryMojo::CreateReflector(
+    ui::Compositor* mirroed_compositor,
+    ui::Layer* mirroring_layer) {
+  return NULL;
+}
+
+void ContextFactoryMojo::RemoveReflector(
+    scoped_refptr<ui::Reflector> reflector) {
+}
+
+scoped_refptr<cc::ContextProvider>
+ContextFactoryMojo::SharedMainThreadContextProvider() {
+  if (!shared_main_thread_contexts_ ||
+      shared_main_thread_contexts_->DestroyedOnMainThread()) {
+    bool lose_context_when_out_of_memory = false;
+    shared_main_thread_contexts_ =
+        webkit::gpu::ContextProviderInProcess::CreateOffscreen(
+            lose_context_when_out_of_memory);
+    if (shared_main_thread_contexts_ &&
+        !shared_main_thread_contexts_->BindToCurrentThread())
+      shared_main_thread_contexts_ = NULL;
+  }
+  return shared_main_thread_contexts_;
+}
+
+void ContextFactoryMojo::RemoveCompositor(ui::Compositor* compositor) {
+}
+
+bool ContextFactoryMojo::DoesCreateTestContexts() { return false; }
+
+cc::SharedBitmapManager* ContextFactoryMojo::GetSharedBitmapManager() {
+  return NULL;
+}
+
+}  // namespace mojo
diff --git a/mojo/aura/context_factory_mojo.h b/mojo/aura/context_factory_mojo.h
new file mode 100644
index 0000000..a842428
--- /dev/null
+++ b/mojo/aura/context_factory_mojo.h
@@ -0,0 +1,51 @@
+// Copyright 2013 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.
+
+#ifndef MOJO_AURA_CONTEXT_FACTORY_MOJO_H_
+#define MOJO_AURA_CONTEXT_FACTORY_MOJO_H_
+
+#include "mojo/public/cpp/system/core.h"
+#include "ui/compositor/compositor.h"
+
+namespace webkit {
+namespace gpu {
+class ContextProviderInProcess;
+}
+}
+
+namespace mojo {
+
+// The default factory that creates in-process contexts.
+class ContextFactoryMojo : public ui::ContextFactory {
+ public:
+  explicit ContextFactoryMojo(ScopedMessagePipeHandle gles2_handle);
+  virtual ~ContextFactoryMojo();
+
+  // ContextFactory implementation
+  virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(
+      ui::Compositor* compositor, bool software_fallback) OVERRIDE;
+
+  virtual scoped_refptr<ui::Reflector> CreateReflector(
+      ui::Compositor* compositor,
+      ui::Layer* layer) OVERRIDE;
+  virtual void RemoveReflector(scoped_refptr<ui::Reflector> reflector) OVERRIDE;
+
+  virtual scoped_refptr<cc::ContextProvider>
+      SharedMainThreadContextProvider() OVERRIDE;
+  virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE;
+  virtual bool DoesCreateTestContexts() OVERRIDE;
+  virtual cc::SharedBitmapManager* GetSharedBitmapManager() OVERRIDE;
+
+ private:
+  scoped_refptr<webkit::gpu::ContextProviderInProcess>
+      shared_main_thread_contexts_;
+
+  ScopedMessagePipeHandle gles2_handle_;
+
+  DISALLOW_COPY_AND_ASSIGN(ContextFactoryMojo);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_AURA_CONTEXT_FACTORY_MOJO_H_
diff --git a/mojo/aura/screen_mojo.cc b/mojo/aura/screen_mojo.cc
new file mode 100644
index 0000000..b07c320
--- /dev/null
+++ b/mojo/aura/screen_mojo.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 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.
+
+#include "mojo/aura/screen_mojo.h"
+
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/rect_conversions.h"
+
+namespace mojo {
+
+// static
+ScreenMojo* ScreenMojo::Create() {
+  return new ScreenMojo(gfx::Rect(0, 0, 800, 600));
+}
+
+ScreenMojo::~ScreenMojo() {
+}
+
+bool ScreenMojo::IsDIPEnabled() {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+gfx::Point ScreenMojo::GetCursorScreenPoint() {
+  NOTIMPLEMENTED();
+  return gfx::Point();
+}
+
+gfx::NativeWindow ScreenMojo::GetWindowUnderCursor() {
+  return GetWindowAtScreenPoint(GetCursorScreenPoint());
+}
+
+gfx::NativeWindow ScreenMojo::GetWindowAtScreenPoint(const gfx::Point& point) {
+  NOTIMPLEMENTED();
+  return NULL;
+}
+
+int ScreenMojo::GetNumDisplays() const {
+  return 1;
+}
+
+std::vector<gfx::Display> ScreenMojo::GetAllDisplays() const {
+  return std::vector<gfx::Display>(1, display_);
+}
+
+gfx::Display ScreenMojo::GetDisplayNearestWindow(
+    gfx::NativeWindow window) const {
+  return display_;
+}
+
+gfx::Display ScreenMojo::GetDisplayNearestPoint(const gfx::Point& point) const {
+  return display_;
+}
+
+gfx::Display ScreenMojo::GetDisplayMatching(const gfx::Rect& match_rect) const {
+  return display_;
+}
+
+gfx::Display ScreenMojo::GetPrimaryDisplay() const {
+  return display_;
+}
+
+void ScreenMojo::AddObserver(gfx::DisplayObserver* observer) {
+}
+
+void ScreenMojo::RemoveObserver(gfx::DisplayObserver* observer) {
+}
+
+ScreenMojo::ScreenMojo(const gfx::Rect& screen_bounds) {
+  static int64 synthesized_display_id = 2000;
+  display_.set_id(synthesized_display_id++);
+  display_.SetScaleAndBounds(1.0f, screen_bounds);
+}
+
+}  // namespace mojo
diff --git a/mojo/aura/screen_mojo.h b/mojo/aura/screen_mojo.h
new file mode 100644
index 0000000..ad50c1c
--- /dev/null
+++ b/mojo/aura/screen_mojo.h
@@ -0,0 +1,54 @@
+// Copyright (c) 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.
+
+#ifndef MOJO_AURA_SCREEN_MOJO_H_
+#define MOJO_AURA_SCREEN_MOJO_H_
+
+#include "base/compiler_specific.h"
+#include "ui/gfx/display.h"
+#include "ui/gfx/screen.h"
+
+namespace gfx {
+class Rect;
+class Transform;
+}
+
+namespace mojo {
+
+// A minimal implementation of gfx::Screen for mojo.
+class ScreenMojo : public gfx::Screen {
+ public:
+  static ScreenMojo* Create();
+  virtual ~ScreenMojo();
+
+ protected:
+  // gfx::Screen overrides:
+  virtual bool IsDIPEnabled() OVERRIDE;
+  virtual gfx::Point GetCursorScreenPoint() OVERRIDE;
+  virtual gfx::NativeWindow GetWindowUnderCursor() OVERRIDE;
+  virtual gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point)
+      OVERRIDE;
+  virtual int GetNumDisplays() const OVERRIDE;
+  virtual std::vector<gfx::Display> GetAllDisplays() const OVERRIDE;
+  virtual gfx::Display GetDisplayNearestWindow(
+      gfx::NativeView view) const OVERRIDE;
+  virtual gfx::Display GetDisplayNearestPoint(
+      const gfx::Point& point) const OVERRIDE;
+  virtual gfx::Display GetDisplayMatching(
+      const gfx::Rect& match_rect) const OVERRIDE;
+  virtual gfx::Display GetPrimaryDisplay() const OVERRIDE;
+  virtual void AddObserver(gfx::DisplayObserver* observer) OVERRIDE;
+  virtual void RemoveObserver(gfx::DisplayObserver* observer) OVERRIDE;
+
+ private:
+  explicit ScreenMojo(const gfx::Rect& screen_bounds);
+
+  gfx::Display display_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScreenMojo);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_AURA_SCREEN_MOJO_H_
diff --git a/mojo/aura/window_tree_host_mojo.cc b/mojo/aura/window_tree_host_mojo.cc
new file mode 100644
index 0000000..b623bbd
--- /dev/null
+++ b/mojo/aura/window_tree_host_mojo.cc
@@ -0,0 +1,178 @@
+// Copyright (c) 2013 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.
+
+#include "mojo/aura/window_tree_host_mojo.h"
+
+#include "mojo/aura/context_factory_mojo.h"
+#include "mojo/public/c/gles2/gles2.h"
+#include "mojo/public/cpp/bindings/allocation_scope.h"
+#include "mojo/services/native_viewport/geometry_conversions.h"
+#include "ui/aura/env.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_event_dispatcher.h"
+#include "ui/compositor/compositor.h"
+#include "ui/events/event.h"
+#include "ui/events/event_constants.h"
+#include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/rect.h"
+
+namespace mojo {
+
+// static
+mojo::ContextFactoryMojo* WindowTreeHostMojo::context_factory_ = NULL;
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowTreeHostMojo, public:
+
+WindowTreeHostMojo::WindowTreeHostMojo(
+    ScopedNativeViewportHandle viewport_handle,
+    const gfx::Rect& bounds,
+    const base::Callback<void()>& compositor_created_callback)
+    : native_viewport_(viewport_handle.Pass(), this),
+      compositor_created_callback_(compositor_created_callback),
+      bounds_(bounds) {
+  AllocationScope scope;
+  native_viewport_->Create(bounds);
+
+  ScopedMessagePipeHandle gles2_handle, gles2_client_handle;
+  CreateMessagePipe(&gles2_handle, &gles2_client_handle);
+
+  // The ContextFactory must exist before any Compositors are created.
+  if (context_factory_) {
+    ui::ContextFactory::SetInstance(NULL);
+    delete context_factory_;
+    context_factory_ = NULL;
+  }
+  context_factory_ = new ContextFactoryMojo(gles2_handle.Pass());
+  ui::ContextFactory::SetInstance(context_factory_);
+  CHECK(context_factory_) << "No GL bindings.";
+
+  native_viewport_->CreateGLES2Context(gles2_client_handle.Pass());
+}
+
+WindowTreeHostMojo::~WindowTreeHostMojo() {
+  DestroyCompositor();
+  DestroyDispatcher();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowTreeHostMojo, aura::WindowTreeHost implementation:
+
+ui::EventSource* WindowTreeHostMojo::GetEventSource() {
+  return this;
+}
+
+gfx::AcceleratedWidget WindowTreeHostMojo::GetAcceleratedWidget() {
+  NOTIMPLEMENTED() << "GetAcceleratedWidget";
+  return gfx::kNullAcceleratedWidget;
+}
+
+void WindowTreeHostMojo::Show() {
+  window()->Show();
+  native_viewport_->Show();
+}
+
+void WindowTreeHostMojo::Hide() {
+  native_viewport_->Hide();
+  window()->Hide();
+}
+
+gfx::Rect WindowTreeHostMojo::GetBounds() const {
+  return bounds_;
+}
+
+void WindowTreeHostMojo::SetBounds(const gfx::Rect& bounds) {
+  AllocationScope scope;
+  native_viewport_->SetBounds(bounds);
+}
+
+gfx::Point WindowTreeHostMojo::GetLocationOnNativeScreen() const {
+  return gfx::Point(0, 0);
+}
+
+void WindowTreeHostMojo::SetCapture() {
+  NOTIMPLEMENTED();
+}
+
+void WindowTreeHostMojo::ReleaseCapture() {
+  NOTIMPLEMENTED();
+}
+
+void WindowTreeHostMojo::PostNativeEvent(
+    const base::NativeEvent& native_event) {
+  NOTIMPLEMENTED();
+}
+
+void WindowTreeHostMojo::OnDeviceScaleFactorChanged(float device_scale_factor) {
+  NOTIMPLEMENTED();
+}
+
+void WindowTreeHostMojo::SetCursorNative(gfx::NativeCursor cursor) {
+  NOTIMPLEMENTED();
+}
+
+void WindowTreeHostMojo::MoveCursorToNative(const gfx::Point& location) {
+  NOTIMPLEMENTED();
+}
+
+void WindowTreeHostMojo::OnCursorVisibilityChangedNative(bool show) {
+  NOTIMPLEMENTED();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowTreeHostMojo, ui::EventSource implementation:
+
+ui::EventProcessor* WindowTreeHostMojo::GetEventProcessor() {
+  return dispatcher();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WindowTreeHostMojo, NativeViewportClient implementation:
+
+void WindowTreeHostMojo::OnCreated() {
+  CreateCompositor(GetAcceleratedWidget());
+  compositor_created_callback_.Run();
+}
+
+void WindowTreeHostMojo::OnBoundsChanged(const Rect& bounds) {
+  bounds_ = gfx::Rect(bounds.position().x(), bounds.position().y(),
+                      bounds.size().width(), bounds.size().height());
+  window()->SetBounds(gfx::Rect(bounds_.size()));
+  OnHostResized(bounds_.size());
+}
+
+void WindowTreeHostMojo::OnDestroyed() {
+  base::MessageLoop::current()->Quit();
+}
+
+void WindowTreeHostMojo::OnEvent(const Event& event,
+                                 const mojo::Callback<void()>& callback) {
+  switch (event.action()) {
+    case ui::ET_MOUSE_PRESSED:
+    case ui::ET_MOUSE_DRAGGED:
+    case ui::ET_MOUSE_RELEASED:
+    case ui::ET_MOUSE_MOVED:
+    case ui::ET_MOUSE_ENTERED:
+    case ui::ET_MOUSE_EXITED: {
+      gfx::Point location(event.location().x(), event.location().y());
+      ui::MouseEvent ev(static_cast<ui::EventType>(event.action()), location,
+                        location, event.flags(), 0);
+      SendEventToProcessor(&ev);
+      break;
+    }
+    case ui::ET_KEY_PRESSED:
+    case ui::ET_KEY_RELEASED: {
+      ui::KeyEvent ev(
+          static_cast<ui::EventType>(event.action()),
+          static_cast<ui::KeyboardCode>(event.key_data().key_code()),
+          event.flags(), event.key_data().is_char());
+      SendEventToProcessor(&ev);
+      break;
+    }
+    // TODO(beng): touch, etc.
+  }
+  callback.Run();
+};
+
+}  // namespace mojo
diff --git a/mojo/aura/window_tree_host_mojo.h b/mojo/aura/window_tree_host_mojo.h
new file mode 100644
index 0000000..c53e884
--- /dev/null
+++ b/mojo/aura/window_tree_host_mojo.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2013 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.
+
+#ifndef MOJO_AURA_WINDOW_TREE_HOST_MOJO_H_
+#define MOJO_AURA_WINDOW_TREE_HOST_MOJO_H_
+
+#include "base/bind.h"
+#include "mojo/public/cpp/bindings/error_handler.h"
+#include "mojo/public/cpp/bindings/remote_ptr.h"
+#include "mojo/services/native_viewport/native_viewport.mojom.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/events/event_source.h"
+#include "ui/gfx/rect.h"
+
+namespace ui {
+class ContextFactory;
+}
+
+namespace mojo {
+
+class ContextFactoryMojo;
+
+class WindowTreeHostMojo : public aura::WindowTreeHost,
+                           public ui::EventSource,
+                           public NativeViewportClient {
+ public:
+  WindowTreeHostMojo(ScopedNativeViewportHandle viewport_handle,
+                     const gfx::Rect& bounds,
+                     const base::Callback<void()>& compositor_created_callback);
+  virtual ~WindowTreeHostMojo();
+
+  gfx::Rect bounds() const { return bounds_; }
+
+ private:
+  // WindowTreeHost:
+  virtual ui::EventSource* GetEventSource() OVERRIDE;
+  virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
+  virtual void Show() OVERRIDE;
+  virtual void Hide() OVERRIDE;
+  virtual gfx::Rect GetBounds() const OVERRIDE;
+  virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE;
+  virtual gfx::Point GetLocationOnNativeScreen() const OVERRIDE;
+  virtual void SetCapture() OVERRIDE;
+  virtual void ReleaseCapture() OVERRIDE;
+  virtual void PostNativeEvent(const base::NativeEvent& native_event) OVERRIDE;
+  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
+  virtual void SetCursorNative(gfx::NativeCursor cursor) OVERRIDE;
+  virtual void MoveCursorToNative(const gfx::Point& location) OVERRIDE;
+  virtual void OnCursorVisibilityChangedNative(bool show) OVERRIDE;
+
+  // ui::EventSource:
+  virtual ui::EventProcessor* GetEventProcessor() OVERRIDE;
+
+  // Overridden from NativeViewportClient:
+  virtual void OnCreated() OVERRIDE;
+  virtual void OnDestroyed() OVERRIDE;
+  virtual void OnBoundsChanged(const Rect& bounds) OVERRIDE;
+  virtual void OnEvent(const Event& event,
+                       const mojo::Callback<void()>& callback) OVERRIDE;
+
+  static ContextFactoryMojo* context_factory_;
+
+  RemotePtr<NativeViewport> native_viewport_;
+  base::Callback<void()> compositor_created_callback_;
+
+  gfx::Rect bounds_;
+
+  DISALLOW_COPY_AND_ASSIGN(WindowTreeHostMojo);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_AURA_WINDOW_TREE_HOST_MOJO_H_
diff --git a/mojo/bindings/js/core.cc b/mojo/bindings/js/core.cc
index 855637b..dd46594 100644
--- a/mojo/bindings/js/core.cc
+++ b/mojo/bindings/js/core.cc
@@ -73,7 +73,7 @@
   // release them here.
   if (rv == MOJO_RESULT_OK) {
     for (size_t i = 0; i < handles.size(); ++i)
-      mojo::Handle _ MOJO_ALLOW_UNUSED = handles[i]->release();
+      ignore_result(handles[i]->release());
   }
   return rv;
 }
diff --git a/mojo/cc/DEPS b/mojo/cc/DEPS
new file mode 100644
index 0000000..1d0b887
--- /dev/null
+++ b/mojo/cc/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+cc",
+]
diff --git a/mojo/cc/context_provider_mojo.cc b/mojo/cc/context_provider_mojo.cc
new file mode 100644
index 0000000..8a759fd
--- /dev/null
+++ b/mojo/cc/context_provider_mojo.cc
@@ -0,0 +1,56 @@
+// 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.
+
+#include "mojo/cc/context_provider_mojo.h"
+
+#include "base/logging.h"
+
+namespace mojo {
+
+ContextProviderMojo::ContextProviderMojo(ScopedMessagePipeHandle gl_pipe)
+    : gl_pipe_(gl_pipe.Pass()) {}
+
+bool ContextProviderMojo::BindToCurrentThread() {
+  DCHECK(gl_pipe_.is_valid());
+  context_ = MojoGLES2CreateContext(
+      gl_pipe_.release().value(), &ContextLostThunk, NULL, this);
+  return !!context_;
+}
+
+gpu::gles2::GLES2Interface* ContextProviderMojo::ContextGL() {
+  if (!context_)
+    return NULL;
+  return static_cast<gpu::gles2::GLES2Interface*>(
+      MojoGLES2GetGLES2Interface(context_));
+}
+
+gpu::ContextSupport* ContextProviderMojo::ContextSupport() {
+  if (!context_)
+    return NULL;
+  return static_cast<gpu::ContextSupport*>(
+      MojoGLES2GetContextSupport(context_));
+}
+
+class GrContext* ContextProviderMojo::GrContext() { return NULL; }
+
+cc::ContextProvider::Capabilities ContextProviderMojo::ContextCapabilities() {
+  return capabilities_;
+}
+
+bool ContextProviderMojo::IsContextLost() { return !context_; }
+bool ContextProviderMojo::DestroyedOnMainThread() { return !context_; }
+
+ContextProviderMojo::~ContextProviderMojo() {
+  if (context_)
+    MojoGLES2DestroyContext(context_);
+}
+
+void ContextProviderMojo::ContextLost() {
+  if (context_) {
+    MojoGLES2DestroyContext(context_);
+    context_ = NULL;
+  }
+}
+
+}  // namespace mojo
diff --git a/mojo/cc/context_provider_mojo.h b/mojo/cc/context_provider_mojo.h
new file mode 100644
index 0000000..5ddc7c1
--- /dev/null
+++ b/mojo/cc/context_provider_mojo.h
@@ -0,0 +1,51 @@
+// 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.
+
+#ifndef MOJO_CC_CONTEXT_PROVIDER_MOJO_H_
+#define MOJO_CC_CONTEXT_PROVIDER_MOJO_H_
+
+#include "cc/output/context_provider.h"
+#include "mojo/public/c/gles2/gles2.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+
+class ContextProviderMojo : public cc::ContextProvider {
+ public:
+  explicit ContextProviderMojo(ScopedMessagePipeHandle gl_pipe);
+
+  // cc::ContextProvider implementation.
+  virtual bool BindToCurrentThread() OVERRIDE;
+  virtual gpu::gles2::GLES2Interface* ContextGL() OVERRIDE;
+  virtual gpu::ContextSupport* ContextSupport() OVERRIDE;
+  virtual class GrContext* GrContext() OVERRIDE;
+  virtual Capabilities ContextCapabilities() OVERRIDE;
+  virtual bool IsContextLost() OVERRIDE;
+  virtual void VerifyContexts() OVERRIDE {}
+  virtual void DeleteCachedResources() OVERRIDE {}
+  virtual bool DestroyedOnMainThread() OVERRIDE;
+  virtual void SetLostContextCallback(
+      const LostContextCallback& lost_context_callback) OVERRIDE {}
+  virtual void SetMemoryPolicyChangedCallback(
+      const MemoryPolicyChangedCallback& memory_policy_changed_callback)
+      OVERRIDE {}
+
+ protected:
+  friend class base::RefCountedThreadSafe<ContextProviderMojo>;
+  virtual ~ContextProviderMojo();
+
+ private:
+  static void ContextLostThunk(void* closure) {
+    static_cast<ContextProviderMojo*>(closure)->ContextLost();
+  }
+  void ContextLost();
+
+  cc::ContextProvider::Capabilities capabilities_;
+  ScopedMessagePipeHandle gl_pipe_;
+  MojoGLES2Context context_;
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_CC_CONTEXT_PROVIDER_MOJO_H_
diff --git a/mojo/common/test/test_support_impl.cc b/mojo/common/test/test_support_impl.cc
index 54c3376..ce9e7ac 100644
--- a/mojo/common/test/test_support_impl.cc
+++ b/mojo/common/test/test_support_impl.cc
@@ -4,10 +4,38 @@
 
 #include "mojo/common/test/test_support_impl.h"
 
+#include <stdlib.h>
+#include <string.h>
+
+#include "base/file_util.h"
+#include "base/files/file_enumerator.h"
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
 #include "base/test/perf_log.h"
 
 namespace mojo {
 namespace test {
+namespace {
+
+base::FilePath ResolveSourceRootRelativePath(const char* relative_path) {
+  base::FilePath path;
+  if (!PathService::Get(base::DIR_SOURCE_ROOT, &path))
+    return base::FilePath();
+
+  std::vector<std::string> components;
+  base::SplitString(relative_path, '/', &components);
+
+  for (size_t i = 0; i < components.size(); ++i) {
+    if (!components[i].empty())
+      path = path.AppendASCII(components[i]);
+  }
+
+  return path;
+}
+
+}  // namespace
 
 TestSupportImpl::TestSupportImpl() {
 }
@@ -21,5 +49,24 @@
   base::LogPerfResult(test_name, value, units);
 }
 
+FILE* TestSupportImpl::OpenSourceRootRelativeFile(const char* relative_path) {
+  return base::OpenFile(ResolveSourceRootRelativePath(relative_path), "rb");
+}
+
+char** TestSupportImpl::EnumerateSourceRootRelativeDirectory(
+    const char* relative_path) {
+  std::vector<std::string> names;
+  base::FileEnumerator e(ResolveSourceRootRelativePath(relative_path), false,
+                         base::FileEnumerator::FILES);
+  for (base::FilePath name = e.Next(); !name.empty(); name = e.Next())
+    names.push_back(name.BaseName().AsUTF8Unsafe());
+
+  // |names.size() + 1| for null terminator.
+  char** rv = static_cast<char**>(calloc(names.size() + 1, sizeof(char*)));
+  for (size_t i = 0; i < names.size(); ++i)
+    rv[i] = base::strdup(names[i].c_str());
+  return rv;
+}
+
 }  // namespace test
 }  // namespace mojo
diff --git a/mojo/common/test/test_support_impl.h b/mojo/common/test/test_support_impl.h
index ca3f58a..c752b57 100644
--- a/mojo/common/test/test_support_impl.h
+++ b/mojo/common/test/test_support_impl.h
@@ -19,6 +19,9 @@
   virtual void LogPerfResult(const char* test_name,
                              double value,
                              const char* units) OVERRIDE;
+  virtual FILE* OpenSourceRootRelativeFile(const char* relative_path) OVERRIDE;
+  virtual char** EnumerateSourceRootRelativeDirectory(const char* relative_path)
+      OVERRIDE;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TestSupportImpl);
diff --git a/mojo/dbus/DEPS b/mojo/dbus/DEPS
new file mode 100644
index 0000000..0abf683
--- /dev/null
+++ b/mojo/dbus/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+  "+base",
+  "+dbus",
+]
diff --git a/mojo/dbus/dbus_external_service.cc b/mojo/dbus/dbus_external_service.cc
new file mode 100644
index 0000000..3a13cf7
--- /dev/null
+++ b/mojo/dbus/dbus_external_service.cc
@@ -0,0 +1,95 @@
+// 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.
+
+#include "mojo/dbus/dbus_external_service.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "dbus/bus.h"
+#include "dbus/exported_object.h"
+#include "dbus/file_descriptor.h"
+#include "dbus/message.h"
+#include "dbus/object_path.h"
+#include "mojo/common/channel_init.h"
+#include "mojo/public/cpp/bindings/error_handler.h"
+#include "mojo/public/cpp/bindings/remote_ptr.h"
+#include "mojo/public/cpp/shell/application.h"
+#include "mojo/public/interfaces/shell/shell.mojom.h"
+#include "mojo/shell/external_service.mojom.h"
+
+namespace mojo {
+
+DBusExternalServiceBase::DBusExternalServiceBase(
+    const std::string& service_name)
+    : service_name_(service_name),
+      exported_object_(NULL) {
+}
+DBusExternalServiceBase::~DBusExternalServiceBase() {}
+
+void DBusExternalServiceBase::Start() {
+  InitializeDBus();
+  ExportMethods();
+  TakeDBusServiceOwnership();
+  DVLOG(1) << "External service started";
+}
+
+void DBusExternalServiceBase::OnError() {
+  Disconnect();
+}
+
+void DBusExternalServiceBase::ConnectChannel(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender sender) {
+  dbus::MessageReader reader(method_call);
+  dbus::FileDescriptor wrapped_fd;
+  if (!reader.PopFileDescriptor(&wrapped_fd)) {
+    sender.Run(
+        dbus::ErrorResponse::FromMethodCall(
+            method_call,
+            "org.chromium.Mojo.BadHandle",
+            "Invalid FD.").PassAs<dbus::Response>());
+    return;
+  }
+  wrapped_fd.CheckValidity();
+  channel_init_.reset(new mojo::common::ChannelInit);
+  mojo::ScopedMessagePipeHandle message_pipe =
+      channel_init_->Init(wrapped_fd.TakeValue(),
+                          base::MessageLoopProxy::current());
+  CHECK(message_pipe.is_valid());
+
+  Connect(mojo::ScopedExternalServiceHostHandle::From(message_pipe.Pass()));
+  sender.Run(dbus::Response::FromMethodCall(method_call));
+}
+
+void DBusExternalServiceBase::ExportMethods() {
+  CHECK(exported_object_);
+  CHECK(exported_object_->ExportMethodAndBlock(
+      kMojoDBusInterface, kMojoDBusConnectMethod,
+      base::Bind(&DBusExternalServiceBase::ConnectChannel,
+                 base::Unretained(this))));
+}
+
+void DBusExternalServiceBase::InitializeDBus() {
+  CHECK(!bus_);
+  dbus::Bus::Options options;
+  options.bus_type = dbus::Bus::SESSION;
+  bus_ = new dbus::Bus(options);
+  CHECK(bus_->Connect());
+  CHECK(bus_->SetUpAsyncOperations());
+
+  exported_object_ =
+      bus_->GetExportedObject(dbus::ObjectPath(kMojoDBusImplPath));
+}
+
+void DBusExternalServiceBase::TakeDBusServiceOwnership() {
+  CHECK(bus_->RequestOwnershipAndBlock(
+      service_name_,
+      dbus::Bus::REQUIRE_PRIMARY_ALLOW_REPLACEMENT))
+      << "Unable to take ownership of " << service_name_;
+}
+
+}  // namespace mojo
diff --git a/mojo/dbus/dbus_external_service.h b/mojo/dbus/dbus_external_service.h
new file mode 100644
index 0000000..1a33c4c
--- /dev/null
+++ b/mojo/dbus/dbus_external_service.h
@@ -0,0 +1,85 @@
+// 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.
+
+#include "base/memory/scoped_ptr.h"
+#include "dbus/bus.h"
+#include "dbus/exported_object.h"
+#include "dbus/message.h"
+#include "dbus/object_path.h"
+#include "mojo/common/channel_init.h"
+#include "mojo/public/cpp/bindings/interface.h"
+#include "mojo/public/cpp/bindings/remote_ptr.h"
+#include "mojo/public/cpp/shell/application.h"
+#include "mojo/public/interfaces/shell/shell.mojom.h"
+#include "mojo/shell/external_service.mojom.h"
+
+namespace mojo {
+const char kMojoDBusImplPath[] = "/org/chromium/MojoImpl";
+const char kMojoDBusInterface[] = "org.chromium.Mojo";
+const char kMojoDBusConnectMethod[] = "ConnectChannel";
+
+class DBusExternalServiceBase : public mojo::ErrorHandler {
+ public:
+  explicit DBusExternalServiceBase(const std::string& service_name);
+  virtual ~DBusExternalServiceBase();
+
+  void Start();
+
+ protected:
+  // TODO(cmasone): Enable multiple peers to connect/disconnect
+  virtual void Connect(ScopedExternalServiceHostHandle client_handle) = 0;
+  virtual void Disconnect() = 0;
+
+ private:
+  virtual void OnError() OVERRIDE;
+
+  // Implementation of org.chromium.Mojo.ConnectChannel, exported over DBus.
+  // Takes a file descriptor and uses it to create a MessagePipe that is then
+  // hooked to a RemotePtr<mojo::ExternalServiceHost>.
+  void ConnectChannel(dbus::MethodCall* method_call,
+                      dbus::ExportedObject::ResponseSender sender);
+
+  void ExportMethods();
+  void InitializeDBus();
+  void TakeDBusServiceOwnership();
+
+  const std::string service_name_;
+  scoped_refptr<dbus::Bus> bus_;
+  dbus::ExportedObject* exported_object_;  // Owned by bus_;
+  scoped_ptr<mojo::common::ChannelInit> channel_init_;
+  DISALLOW_COPY_AND_ASSIGN(DBusExternalServiceBase);
+};
+
+template <class ServiceImpl>
+class DBusExternalService : public DBusExternalServiceBase,
+                            public mojo::ExternalService {
+ public:
+  explicit DBusExternalService(const std::string& service_name)
+      : DBusExternalServiceBase(service_name) {
+  }
+  virtual ~DBusExternalService() {}
+
+ protected:
+  virtual void Connect(ScopedExternalServiceHostHandle client_handle) OVERRIDE {
+    external_service_host_.reset(client_handle.Pass(), this, this);
+  }
+
+  virtual void Disconnect() OVERRIDE {
+    app_.reset();
+    external_service_host_.reset();
+  }
+
+ private:
+  virtual void Activate(mojo::ScopedMessagePipeHandle client_handle) OVERRIDE {
+    mojo::ScopedShellHandle shell_handle(
+        mojo::ShellHandle(client_handle.release().value()));
+    app_.reset(new mojo::Application(shell_handle.Pass()));
+    app_->AddServiceConnector(new mojo::ServiceConnector<ServiceImpl>());
+  }
+
+  mojo::RemotePtr<mojo::ExternalServiceHost> external_service_host_;
+  scoped_ptr<mojo::Application> app_;
+};
+
+}  // namespace mojo
diff --git a/mojo/embedder/embedder.cc b/mojo/embedder/embedder.cc
index e8c6e8e..16de202 100644
--- a/mojo/embedder/embedder.cc
+++ b/mojo/embedder/embedder.cc
@@ -11,6 +11,7 @@
 #include "mojo/system/channel.h"
 #include "mojo/system/core.h"
 #include "mojo/system/entrypoints.h"
+#include "mojo/system/message_in_transit.h"
 #include "mojo/system/message_pipe.h"
 #include "mojo/system/message_pipe_dispatcher.h"
 #include "mojo/system/raw_channel.h"
@@ -18,39 +19,66 @@
 namespace mojo {
 namespace embedder {
 
-void Init() {
-  system::entrypoints::SetCore(new system::Core());
-}
-
+// This is defined here (instead of a header file), since it's opaque to the
+// outside world. But we need to define it before our (internal-only) functions
+// that use it.
 struct ChannelInfo {
+  explicit ChannelInfo(scoped_refptr<system::Channel> channel)
+      : channel(channel) {}
+  ~ChannelInfo() {}
+
   scoped_refptr<system::Channel> channel;
 };
 
-static void CreateChannelOnIOThread(
+namespace {
+
+// Helper for |CreateChannelOnIOThread()|. (Note: May return null for some
+// failures.)
+scoped_refptr<system::Channel> MakeChannel(
+    ScopedPlatformHandle platform_handle,
+    scoped_refptr<system::MessagePipe> message_pipe) {
+  DCHECK(platform_handle.is_valid());
+
+  // Create and initialize a |system::Channel|.
+  scoped_refptr<system::Channel> channel = new system::Channel();
+  if (!channel->Init(system::RawChannel::Create(platform_handle.Pass()))) {
+    // This is very unusual (e.g., maybe |platform_handle| was invalid or we
+    // reached some system resource limit).
+    LOG(ERROR) << "Channel::Init() failed";
+    // Return null, since |Shutdown()| shouldn't be called in this case.
+    return scoped_refptr<system::Channel>();
+  }
+  // Once |Init()| has succeeded, we have to return |channel| (since
+  // |Shutdown()| will have to be called on it).
+
+  // Attach the message pipe endpoint.
+  system::MessageInTransit::EndpointId endpoint_id =
+      channel->AttachMessagePipeEndpoint(message_pipe, 1);
+  if (endpoint_id == system::MessageInTransit::kInvalidEndpointId) {
+    // This means that, e.g., the other endpoint of the message pipe was closed
+    // first. But it's not necessarily an error per se.
+    DVLOG(2) << "Channel::AttachMessagePipeEndpoint() failed";
+    return channel;
+  }
+  CHECK_EQ(endpoint_id, system::Channel::kBootstrapEndpointId);
+
+  if (!channel->RunMessagePipeEndpoint(system::Channel::kBootstrapEndpointId,
+                                       system::Channel::kBootstrapEndpointId)) {
+    // Currently, there's no reason for this to fail.
+    NOTREACHED() << "Channel::RunMessagePipeEndpoint() failed";
+    return channel;
+  }
+
+  return channel;
+}
+
+void CreateChannelOnIOThread(
     ScopedPlatformHandle platform_handle,
     scoped_refptr<system::MessagePipe> message_pipe,
     DidCreateChannelCallback callback,
     scoped_refptr<base::TaskRunner> callback_thread_task_runner) {
-  CHECK(platform_handle.is_valid());
-
-  scoped_ptr<ChannelInfo> channel_info(new ChannelInfo);
-
-  // Create and initialize a |system::Channel|.
-  channel_info->channel = new system::Channel();
-  bool success = channel_info->channel->Init(
-      system::RawChannel::Create(platform_handle.Pass()));
-  DCHECK(success);
-
-  // Attach the message pipe endpoint.
-  system::MessageInTransit::EndpointId endpoint_id =
-      channel_info->channel->AttachMessagePipeEndpoint(message_pipe, 1);
-  // We shouldn't get |kInvalidEndpointId| here -- since |CreateChannel()| is
-  // responsible for the local endpoint, and won't close it.
-  DCHECK_EQ(endpoint_id, system::Channel::kBootstrapEndpointId);
-  success = channel_info->channel->RunMessagePipeEndpoint(
-      system::Channel::kBootstrapEndpointId,
-      system::Channel::kBootstrapEndpointId);
-  DCHECK(success);  // This shouldn't fail.
+  scoped_ptr<ChannelInfo> channel_info(
+      new ChannelInfo(MakeChannel(platform_handle.Pass(), message_pipe)));
 
   // Hand the channel back to the embedder.
   if (callback_thread_task_runner) {
@@ -62,6 +90,12 @@
   }
 }
 
+}  // namespace
+
+void Init() {
+  system::entrypoints::SetCore(new system::Core());
+}
+
 ScopedMessagePipeHandle CreateChannel(
     ScopedPlatformHandle platform_handle,
     scoped_refptr<base::TaskRunner> io_thread_task_runner,
@@ -91,7 +125,11 @@
 
 void DestroyChannelOnIOThread(ChannelInfo* channel_info) {
   DCHECK(channel_info);
-  DCHECK(channel_info->channel.get());
+  if (!channel_info->channel) {
+    // Presumably, |Init()| on the channel failed.
+    return;
+  }
+
   channel_info->channel->Shutdown();
   delete channel_info;
 }
diff --git a/mojo/embedder/platform_channel_pair_posix_unittest.cc b/mojo/embedder/platform_channel_pair_posix_unittest.cc
index 7b09e31..17fb3bc 100644
--- a/mojo/embedder/platform_channel_pair_posix_unittest.cc
+++ b/mojo/embedder/platform_channel_pair_posix_unittest.cc
@@ -5,12 +5,18 @@
 #include "mojo/embedder/platform_channel_pair.h"
 
 #include <errno.h>
+#include <poll.h>
 #include <signal.h>
+#include <stdio.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <unistd.h>
 
+#include <vector>
+
+#include "base/file_util.h"
+#include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "mojo/embedder/platform_channel_utils_posix.h"
@@ -21,6 +27,23 @@
 namespace embedder {
 namespace {
 
+ScopedPlatformHandle PlatformHandleFromFILE(FILE* fp) {
+  CHECK(fp);
+  return ScopedPlatformHandle(PlatformHandle(dup(fileno(fp))));
+}
+
+FILE* FILEFromPlatformHandle(ScopedPlatformHandle h, const char* mode) {
+  CHECK(h.is_valid());
+  return fdopen(h.release().fd, mode);
+}
+
+void WaitReadable(PlatformHandle h) {
+  struct pollfd pfds = {};
+  pfds.fd = h.fd;
+  pfds.events = POLLIN;
+  CHECK_EQ(poll(&pfds, 1, -1), 1);
+}
+
 class PlatformChannelPairPosixTest : public testing::Test {
  public:
   PlatformChannelPairPosixTest() {}
@@ -46,7 +69,6 @@
 
 TEST_F(PlatformChannelPairPosixTest, NoSigPipe) {
   PlatformChannelPair channel_pair;
-
   ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
   ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
 
@@ -88,6 +110,130 @@
     PLOG(WARNING) << "write (expected EPIPE)";
 }
 
+TEST_F(PlatformChannelPairPosixTest, SendReceiveData) {
+  PlatformChannelPair channel_pair;
+  ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
+  ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
+
+  for (size_t i = 0; i < 10; i++) {
+    std::string send_string(1 << i, 'A' + i);
+
+    EXPECT_EQ(static_cast<ssize_t>(send_string.size()),
+              PlatformChannelWrite(server_handle.get(), send_string.data(),
+                                   send_string.size()));
+
+    WaitReadable(client_handle.get());
+
+    char buf[10000] = {};
+    scoped_ptr<PlatformHandleVector> received_handles;
+    ssize_t result = PlatformChannelRecvmsg(client_handle.get(), buf,
+                                            sizeof(buf), &received_handles);
+    EXPECT_EQ(static_cast<ssize_t>(send_string.size()), result);
+    EXPECT_EQ(send_string, std::string(buf, static_cast<size_t>(result)));
+    EXPECT_FALSE(received_handles);
+  }
+}
+
+TEST_F(PlatformChannelPairPosixTest, SendReceiveFDs) {
+  PlatformChannelPair channel_pair;
+  ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
+  ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
+
+  for (size_t i = 1; i < kPlatformChannelMaxNumHandles; i++) {
+    // Make |i| files, with the j-th file consisting of j copies of the digit i.
+    PlatformHandleVector platform_handles;
+    for (size_t j = 1; j <= i; j++) {
+      base::FilePath ignored;
+      FILE* fp = base::CreateAndOpenTemporaryFile(&ignored);
+      ASSERT_TRUE(fp);
+      platform_handles.push_back(PlatformHandleFromFILE(fp).release());
+      ASSERT_TRUE(platform_handles.back().is_valid());
+      fwrite(std::string(j, '0' + i).data(), 1, j, fp);
+      fclose(fp);
+    }
+
+    // Send the FDs.
+    EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(),
+                                           &platform_handles[0],
+                                           platform_handles.size()));
+
+    WaitReadable(client_handle.get());
+
+    char buf[100] = { 'a' };
+    scoped_ptr<PlatformHandleVector> received_handles;
+    EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf),
+                                        &received_handles));
+    EXPECT_EQ('\0', buf[0]);
+    ASSERT_TRUE(received_handles);
+    EXPECT_EQ(i, received_handles->size());
+
+    for (size_t j = 0; j < received_handles->size(); j++) {
+      FILE* fp = FILEFromPlatformHandle(
+          ScopedPlatformHandle((*received_handles)[j]), "rb");
+      (*received_handles)[j] = PlatformHandle();
+      ASSERT_TRUE(fp);
+      rewind(fp);
+      char read_buf[100];
+      size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp);
+      fclose(fp);
+      EXPECT_EQ(j + 1, bytes_read);
+      EXPECT_EQ(std::string(j + 1, '0' + i), std::string(read_buf, bytes_read));
+    }
+  }
+}
+
+TEST_F(PlatformChannelPairPosixTest, AppendReceivedFDs) {
+  PlatformChannelPair channel_pair;
+  ScopedPlatformHandle server_handle = channel_pair.PassServerHandle().Pass();
+  ScopedPlatformHandle client_handle = channel_pair.PassClientHandle().Pass();
+
+  const std::string file_contents("hello world");
+
+  {
+    base::FilePath ignored;
+    FILE* fp = base::CreateAndOpenTemporaryFile(&ignored);
+    ASSERT_TRUE(fp);
+    PlatformHandleVector platform_handles;
+    platform_handles.push_back(PlatformHandleFromFILE(fp).release());
+    ASSERT_TRUE(platform_handles.back().is_valid());
+    fwrite(file_contents.data(), 1, file_contents.size(), fp);
+    fclose(fp);
+
+    // Send the FD.
+    EXPECT_TRUE(PlatformChannelSendHandles(server_handle.get(),
+                                           &platform_handles[0],
+                                           platform_handles.size()));
+  }
+
+  WaitReadable(client_handle.get());
+
+  // Start with an invalid handle in the vector.
+  scoped_ptr<PlatformHandleVector> handles(new PlatformHandleVector());
+  handles->push_back(PlatformHandle());
+
+  char buf[100] = { 'a' };
+  EXPECT_EQ(1, PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf),
+                                      &handles));
+  EXPECT_EQ('\0', buf[0]);
+  ASSERT_TRUE(handles);
+  ASSERT_EQ(2u, handles->size());
+  EXPECT_FALSE((*handles)[0].is_valid());
+  EXPECT_TRUE((*handles)[1].is_valid());
+
+  {
+    FILE* fp = FILEFromPlatformHandle(ScopedPlatformHandle((*handles)[1]),
+                                      "rb");
+    (*handles)[1] = PlatformHandle();
+    ASSERT_TRUE(fp);
+    rewind(fp);
+    char read_buf[100];
+    size_t bytes_read = fread(read_buf, 1, sizeof(read_buf), fp);
+    fclose(fp);
+    EXPECT_EQ(file_contents.size(), bytes_read);
+    EXPECT_EQ(file_contents, std::string(read_buf, bytes_read));
+  }
+}
+
 }  // namespace
 }  // namespace embedder
 }  // namespace mojo
diff --git a/mojo/embedder/platform_channel_utils_posix.cc b/mojo/embedder/platform_channel_utils_posix.cc
index f0e0538..4a3a916 100644
--- a/mojo/embedder/platform_channel_utils_posix.cc
+++ b/mojo/embedder/platform_channel_utils_posix.cc
@@ -8,6 +8,7 @@
 #include <sys/uio.h>
 #include <unistd.h>
 
+#include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
 #include "build/build_config.h"
 
@@ -36,13 +37,20 @@
 //    - Linux: 0.81 s, 0.77 s, 0.87 s, 0.89 s, 1.31 s, 1.22 s
 //    - Mac: 2.21 s, 2.91 s, 2.98 s, 3.08 s, 3.59 s, 4.74 s
 
+// Flags to use with calling |send()| or |sendmsg()| (see above).
+#if defined(OS_MACOSX)
+const int kSendFlags = 0;
+#else
+const int kSendFlags = MSG_NOSIGNAL;
+#endif
+
 ssize_t PlatformChannelWrite(PlatformHandle h,
                              const void* bytes,
                              size_t num_bytes) {
 #if defined(OS_MACOSX)
   return HANDLE_EINTR(write(h.fd, bytes, num_bytes));
 #else
-  return send(h.fd, bytes, num_bytes, MSG_NOSIGNAL);
+  return send(h.fd, bytes, num_bytes, kSendFlags);
 #endif
 }
 
@@ -55,9 +63,90 @@
   struct msghdr msg = {};
   msg.msg_iov = iov;
   msg.msg_iovlen = num_iov;
-  return HANDLE_EINTR(sendmsg(h.fd, &msg, MSG_NOSIGNAL));
+  return HANDLE_EINTR(sendmsg(h.fd, &msg, kSendFlags));
 #endif
 }
 
+bool PlatformChannelSendHandles(PlatformHandle h,
+                                PlatformHandle* handles,
+                                size_t num_handles) {
+  DCHECK(handles);
+  DCHECK_GT(num_handles, 0u);
+  DCHECK_LE(num_handles, kPlatformChannelMaxNumHandles);
+
+  // Note: |sendmsg()| fails on Mac if we don't write at least one character.
+  struct iovec iov = { const_cast<char*>(""), 1 };
+  char cmsg_buf[CMSG_SPACE(kPlatformChannelMaxNumHandles * sizeof(int))];
+  struct msghdr msg = {};
+  msg.msg_iov = &iov;
+  msg.msg_iovlen = 1;
+  msg.msg_control = cmsg_buf;
+  msg.msg_controllen = CMSG_LEN(num_handles * sizeof(int));
+  struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
+  cmsg->cmsg_level = SOL_SOCKET;
+  cmsg->cmsg_type = SCM_RIGHTS;
+  cmsg->cmsg_len = CMSG_LEN(num_handles * sizeof(int));
+  for (size_t i = 0; i < num_handles; i++) {
+    DCHECK(handles[i].is_valid());
+    reinterpret_cast<int*>(CMSG_DATA(cmsg))[i] = handles[i].fd;
+  }
+
+  ssize_t result = HANDLE_EINTR(sendmsg(h.fd, &msg, kSendFlags));
+  if (result < 1) {
+    DCHECK_EQ(result, -1);
+    return false;
+  }
+
+  for (size_t i = 0; i < num_handles; i++)
+    handles[i].CloseIfNecessary();
+  return true;
+}
+
+ssize_t PlatformChannelRecvmsg(PlatformHandle h,
+                               void* buf,
+                               size_t num_bytes,
+                               scoped_ptr<PlatformHandleVector>* handles) {
+  DCHECK(buf);
+  DCHECK_GT(num_bytes, 0u);
+  DCHECK(handles);
+
+  struct iovec iov = { buf, num_bytes };
+  char cmsg_buf[CMSG_SPACE(kPlatformChannelMaxNumHandles * sizeof(int))];
+  struct msghdr msg = {};
+  msg.msg_iov = &iov;
+  msg.msg_iovlen = 1;
+  msg.msg_control = cmsg_buf;
+  msg.msg_controllen = sizeof(cmsg_buf);
+
+  ssize_t result = HANDLE_EINTR(recvmsg(h.fd, &msg, MSG_DONTWAIT));
+  if (result < 0)
+    return result;
+
+  // Success; no control messages.
+  if (msg.msg_controllen == 0)
+    return result;
+
+  DCHECK(!(msg.msg_flags & MSG_CTRUNC));
+
+  for (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
+       cmsg;
+       cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
+      size_t payload_length = cmsg->cmsg_len - CMSG_LEN(0);
+      DCHECK_EQ(payload_length % sizeof(int), 0u);
+      size_t num_fds = payload_length / sizeof(int);
+      const int* fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
+      for (size_t i = 0; i < num_fds; i++) {
+        if (!*handles)
+          (*handles).reset(new PlatformHandleVector());
+        (*handles)->push_back(PlatformHandle(fds[i]));
+        DCHECK((*handles)->back().is_valid());
+      }
+    }
+  }
+
+  return result;
+}
+
 }  // namespace embedder
 }  // namespace mojo
diff --git a/mojo/embedder/platform_channel_utils_posix.h b/mojo/embedder/platform_channel_utils_posix.h
index 7ec5fa5..6cfb988 100644
--- a/mojo/embedder/platform_channel_utils_posix.h
+++ b/mojo/embedder/platform_channel_utils_posix.h
@@ -8,6 +8,9 @@
 #include <stddef.h>
 #include <sys/types.h>  // For |ssize_t|.
 
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
 #include "mojo/embedder/platform_handle.h"
 #include "mojo/system/system_impl_export.h"
 
@@ -16,6 +19,14 @@
 namespace mojo {
 namespace embedder {
 
+// The maximum number of handles that can be sent "at once" using
+// |PlatformChannelSendHandles()|.
+// TODO(vtl): This number is taken from ipc/file_descriptor_set_posix.h:
+// |FileDescriptorSet::kMaxDescriptorsPerMessage|. Where does it come from?
+const size_t kPlatformChannelMaxNumHandles = 7;
+
+typedef std::vector<PlatformHandle> PlatformHandleVector;
+
 // Use these to write to a socket created using |PlatformChannelPair| (or
 // equivalent). These are like |write()| and |writev()|, but handle |EINTR| and
 // never raise |SIGPIPE|. (Note: On Mac, the suppression of |SIGPIPE| is set up
@@ -27,6 +38,26 @@
                                                       struct iovec* iov,
                                                       size_t num_iov);
 
+// Sends |PlatformHandle|s (i.e., file descriptors) over the Unix domain socket
+// (e.g., created using PlatformChannelPair|). (These will be sent in a single
+// message having one null byte of data and one control message header with all
+// the file descriptors.) All of the handles must be valid, and there must be at
+// most |kPlatformChannelMaxNumHandles| (and at least one handle). Returns true
+// on success, in which case it closes all the handles.
+MOJO_SYSTEM_IMPL_EXPORT bool PlatformChannelSendHandles(PlatformHandle h,
+                                                        PlatformHandle* handles,
+                                                        size_t num_handles);
+
+// Wrapper around |recvmsg()|, which will extract any attached file descriptors
+// (in the control message) to |PlatformHandle|s. (This also handles |EINTR|.)
+// If |*handles| is null and handles are received, a vector will be allocated;
+// otherwise, any handles received will be appended to the existing vector.
+MOJO_SYSTEM_IMPL_EXPORT ssize_t PlatformChannelRecvmsg(
+    PlatformHandle h,
+    void* buf,
+    size_t num_bytes,
+    scoped_ptr<PlatformHandleVector>* handles);
+
 }  // namespace embedder
 }  // namespace mojo
 
diff --git a/mojo/examples/aura_demo/DEPS b/mojo/examples/aura_demo/DEPS
index 57bf26c..ebcc248 100644
--- a/mojo/examples/aura_demo/DEPS
+++ b/mojo/examples/aura_demo/DEPS
@@ -1,11 +1,5 @@
 include_rules = [
-  "+cc",
-  "+gpu/command_buffer/client",
   "+ui/aura",
   "+ui/base/hit_test.h",
-  "+ui/compositor",
-  "+ui/events",
   "+ui/gfx",
-  "+ui/gl",
-  "+webkit/common/gpu",
 ]
diff --git a/mojo/examples/aura_demo/aura_demo.cc b/mojo/examples/aura_demo/aura_demo.cc
index f54d213..14f00f5 100644
--- a/mojo/examples/aura_demo/aura_demo.cc
+++ b/mojo/examples/aura_demo/aura_demo.cc
@@ -8,8 +8,8 @@
 #include "base/at_exit.h"
 #include "base/command_line.h"
 #include "base/message_loop/message_loop.h"
-#include "mojo/examples/aura_demo/demo_screen.h"
-#include "mojo/examples/aura_demo/window_tree_host_mojo.h"
+#include "mojo/aura/screen_mojo.h"
+#include "mojo/aura/window_tree_host_mojo.h"
 #include "mojo/public/cpp/bindings/allocation_scope.h"
 #include "mojo/public/cpp/gles2/gles2.h"
 #include "mojo/public/cpp/shell/application.h"
@@ -114,7 +114,7 @@
 class AuraDemo : public Application {
  public:
   explicit AuraDemo(MojoHandle shell_handle) : Application(shell_handle) {
-    screen_.reset(DemoScreen::Create());
+    screen_.reset(ScreenMojo::Create());
     gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
 
     InterfacePipe<NativeViewport, AnyInterface> pipe;
@@ -159,7 +159,7 @@
     window_tree_host_->Show();
   }
 
-  scoped_ptr<DemoScreen> screen_;
+  scoped_ptr<ScreenMojo> screen_;
 
   scoped_ptr<DemoWindowTreeClient> window_tree_client_;
 
@@ -187,7 +187,7 @@
   // TODO(beng): This crashes in a DCHECK on X11 because this thread's
   //             MessageLoop is not of TYPE_UI. I think we need a way to build
   //             Aura that doesn't define platform-specific stuff.
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
   mojo::examples::AuraDemo app(shell_handle);
   loop.Run();
 
diff --git a/mojo/examples/aura_demo/demo_context_factory.cc b/mojo/examples/aura_demo/demo_context_factory.cc
deleted file mode 100644
index 0652217..0000000
--- a/mojo/examples/aura_demo/demo_context_factory.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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.
-
-#include "mojo/examples/aura_demo/demo_context_factory.h"
-
-#include "cc/output/output_surface.h"
-#include "mojo/examples/aura_demo/window_tree_host_mojo.h"
-#include "mojo/examples/compositor_app/mojo_context_provider.h"
-#include "ui/compositor/reflector.h"
-#include "ui/gl/gl_implementation.h"
-#include "ui/gl/gl_surface.h"
-#include "webkit/common/gpu/context_provider_in_process.h"
-#include "webkit/common/gpu/grcontext_for_webgraphicscontext3d.h"
-#include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
-
-namespace mojo {
-namespace examples {
-
-DemoContextFactory::DemoContextFactory(WindowTreeHostMojo* rwhm) : rwhm_(rwhm) {
-}
-
-DemoContextFactory::~DemoContextFactory() {
-}
-
-bool DemoContextFactory::Initialize() {
-  if (!gfx::GLSurface::InitializeOneOff() ||
-      gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
-    LOG(ERROR) << "Could not load the GL bindings";
-    return false;
-  }
-  return true;
-}
-
-scoped_ptr<cc::OutputSurface> DemoContextFactory::CreateOutputSurface(
-    ui::Compositor* compositor, bool software_fallback) {
-  return make_scoped_ptr(new cc::OutputSurface(
-      new MojoContextProvider(rwhm_->TakeGLES2PipeHandle())));
-}
-
-scoped_refptr<ui::Reflector> DemoContextFactory::CreateReflector(
-    ui::Compositor* mirroed_compositor,
-    ui::Layer* mirroring_layer) {
-  return NULL;
-}
-
-void DemoContextFactory::RemoveReflector(
-    scoped_refptr<ui::Reflector> reflector) {
-}
-
-scoped_refptr<cc::ContextProvider>
-DemoContextFactory::SharedMainThreadContextProvider() {
-  if (!shared_main_thread_contexts_ ||
-      shared_main_thread_contexts_->DestroyedOnMainThread()) {
-    bool lose_context_when_out_of_memory = false;
-    shared_main_thread_contexts_ =
-        webkit::gpu::ContextProviderInProcess::CreateOffscreen(
-            lose_context_when_out_of_memory);
-    if (shared_main_thread_contexts_ &&
-        !shared_main_thread_contexts_->BindToCurrentThread())
-      shared_main_thread_contexts_ = NULL;
-  }
-  return shared_main_thread_contexts_;
-}
-
-void DemoContextFactory::RemoveCompositor(ui::Compositor* compositor) {
-}
-
-bool DemoContextFactory::DoesCreateTestContexts() { return false; }
-
-}  // namespace examples
-}  // namespace mojo
-
diff --git a/mojo/examples/aura_demo/demo_context_factory.h b/mojo/examples/aura_demo/demo_context_factory.h
deleted file mode 100644
index f4d07ca..0000000
--- a/mojo/examples/aura_demo/demo_context_factory.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef MOJO_EXAMPLES_AURA_DEMO_DEMO_CONTEXT_FACTORY_H_
-#define MOJO_EXAMPLES_AURA_DEMO_DEMO_CONTEXT_FACTORY_H_
-
-#include "ui/compositor/compositor.h"
-
-namespace webkit {
-namespace gpu {
-class ContextProviderInProcess;
-}
-}
-
-namespace mojo {
-namespace examples {
-
-class WindowTreeHostMojo;
-
-// The default factory that creates in-process contexts.
-class DemoContextFactory : public ui::ContextFactory {
- public:
-  explicit DemoContextFactory(WindowTreeHostMojo* rwhm);
-  virtual ~DemoContextFactory();
-
-  // ContextFactory implementation
-  virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(
-      ui::Compositor* compositor, bool software_fallback) OVERRIDE;
-
-  virtual scoped_refptr<ui::Reflector> CreateReflector(
-      ui::Compositor* compositor,
-      ui::Layer* layer) OVERRIDE;
-  virtual void RemoveReflector(scoped_refptr<ui::Reflector> reflector) OVERRIDE;
-
-  virtual scoped_refptr<cc::ContextProvider>
-      SharedMainThreadContextProvider() OVERRIDE;
-  virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE;
-  virtual bool DoesCreateTestContexts() OVERRIDE;
-
-  bool Initialize();
-
- private:
-  scoped_refptr<webkit::gpu::ContextProviderInProcess>
-      shared_main_thread_contexts_;
-
-  WindowTreeHostMojo* rwhm_;
-
-  DISALLOW_COPY_AND_ASSIGN(DemoContextFactory);
-};
-
-}  // namespace examples
-}  // namespace mojo
-
-#endif  // MOJO_EXAMPLES_AURA_DEMO_DEMO_CONTEXT_FACTORY_H_
diff --git a/mojo/examples/aura_demo/demo_screen.cc b/mojo/examples/aura_demo/demo_screen.cc
deleted file mode 100644
index bc66286..0000000
--- a/mojo/examples/aura_demo/demo_screen.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 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.
-
-#include "mojo/examples/aura_demo/demo_screen.h"
-
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/rect_conversions.h"
-
-namespace mojo {
-namespace examples {
-
-// static
-DemoScreen* DemoScreen::Create() {
-  return new DemoScreen(gfx::Rect(0, 0, 800, 600));
-}
-
-DemoScreen::~DemoScreen() {
-}
-
-bool DemoScreen::IsDIPEnabled() {
-  NOTIMPLEMENTED();
-  return true;
-}
-
-gfx::Point DemoScreen::GetCursorScreenPoint() {
-  NOTIMPLEMENTED();
-  return gfx::Point();
-}
-
-gfx::NativeWindow DemoScreen::GetWindowUnderCursor() {
-  return GetWindowAtScreenPoint(GetCursorScreenPoint());
-}
-
-gfx::NativeWindow DemoScreen::GetWindowAtScreenPoint(const gfx::Point& point) {
-  NOTIMPLEMENTED();
-  return NULL;
-}
-
-int DemoScreen::GetNumDisplays() const {
-  return 1;
-}
-
-std::vector<gfx::Display> DemoScreen::GetAllDisplays() const {
-  return std::vector<gfx::Display>(1, display_);
-}
-
-gfx::Display DemoScreen::GetDisplayNearestWindow(
-    gfx::NativeWindow window) const {
-  return display_;
-}
-
-gfx::Display DemoScreen::GetDisplayNearestPoint(const gfx::Point& point) const {
-  return display_;
-}
-
-gfx::Display DemoScreen::GetDisplayMatching(const gfx::Rect& match_rect) const {
-  return display_;
-}
-
-gfx::Display DemoScreen::GetPrimaryDisplay() const {
-  return display_;
-}
-
-void DemoScreen::AddObserver(gfx::DisplayObserver* observer) {
-}
-
-void DemoScreen::RemoveObserver(gfx::DisplayObserver* observer) {
-}
-
-DemoScreen::DemoScreen(const gfx::Rect& screen_bounds) {
-  static int64 synthesized_display_id = 2000;
-  display_.set_id(synthesized_display_id++);
-  display_.SetScaleAndBounds(1.0f, screen_bounds);
-}
-
-}  // namespace examples
-}  // namespace mojo
diff --git a/mojo/examples/aura_demo/demo_screen.h b/mojo/examples/aura_demo/demo_screen.h
deleted file mode 100644
index 43db5f4..0000000
--- a/mojo/examples/aura_demo/demo_screen.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 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.
-
-#ifndef MOJO_EXAMPLES_AURA_DEMO_DEMO_SCREEN_H_
-#define MOJO_EXAMPLES_AURA_DEMO_DEMO_SCREEN_H_
-
-#include "base/compiler_specific.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/screen.h"
-
-namespace gfx {
-class Rect;
-class Transform;
-}
-
-namespace mojo {
-namespace examples {
-
-// A minimal, testing Aura implementation of gfx::Screen.
-class DemoScreen : public gfx::Screen {
- public:
-  static DemoScreen* Create();
-  virtual ~DemoScreen();
-
- protected:
-  // gfx::Screen overrides:
-  virtual bool IsDIPEnabled() OVERRIDE;
-  virtual gfx::Point GetCursorScreenPoint() OVERRIDE;
-  virtual gfx::NativeWindow GetWindowUnderCursor() OVERRIDE;
-  virtual gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point)
-      OVERRIDE;
-  virtual int GetNumDisplays() const OVERRIDE;
-  virtual std::vector<gfx::Display> GetAllDisplays() const OVERRIDE;
-  virtual gfx::Display GetDisplayNearestWindow(
-      gfx::NativeView view) const OVERRIDE;
-  virtual gfx::Display GetDisplayNearestPoint(
-      const gfx::Point& point) const OVERRIDE;
-  virtual gfx::Display GetDisplayMatching(
-      const gfx::Rect& match_rect) const OVERRIDE;
-  virtual gfx::Display GetPrimaryDisplay() const OVERRIDE;
-  virtual void AddObserver(gfx::DisplayObserver* observer) OVERRIDE;
-  virtual void RemoveObserver(gfx::DisplayObserver* observer) OVERRIDE;
-
- private:
-  explicit DemoScreen(const gfx::Rect& screen_bounds);
-
-  gfx::Display display_;
-
-  DISALLOW_COPY_AND_ASSIGN(DemoScreen);
-};
-
-}  // namespace examples
-}  // namespace mojo
-
-#endif  // MOJO_EXAMPLES_AURA_DEMO_DEMO_SCREEN_H_
diff --git a/mojo/examples/aura_demo/window_tree_host_mojo.cc b/mojo/examples/aura_demo/window_tree_host_mojo.cc
deleted file mode 100644
index c598dce..0000000
--- a/mojo/examples/aura_demo/window_tree_host_mojo.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2013 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.
-
-#include "mojo/examples/aura_demo/window_tree_host_mojo.h"
-
-#include "mojo/examples/aura_demo/demo_context_factory.h"
-#include "mojo/public/c/gles2/gles2.h"
-#include "mojo/public/cpp/bindings/allocation_scope.h"
-#include "mojo/services/native_viewport/geometry_conversions.h"
-#include "ui/aura/env.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/compositor/compositor.h"
-#include "ui/events/event.h"
-#include "ui/events/event_constants.h"
-#include "ui/gfx/geometry/insets.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace mojo {
-namespace examples {
-
-// static
-ui::ContextFactory* WindowTreeHostMojo::context_factory_ = NULL;
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowTreeHostMojo, public:
-
-WindowTreeHostMojo::WindowTreeHostMojo(
-    ScopedNativeViewportHandle viewport_handle,
-    const gfx::Rect& bounds,
-    const base::Callback<void()>& compositor_created_callback)
-    : native_viewport_(viewport_handle.Pass(), this),
-      compositor_created_callback_(compositor_created_callback),
-      bounds_(bounds) {
-  AllocationScope scope;
-  native_viewport_->Create(bounds);
-
-  ScopedMessagePipeHandle gles2_client_handle;
-  CreateMessagePipe(&gles2_handle_, &gles2_client_handle);
-
-  // The ContextFactory must exist before any Compositors are created.
-  if (!context_factory_) {
-    scoped_ptr<DemoContextFactory> cf(new DemoContextFactory(this));
-    if (cf->Initialize())
-      context_factory_ = cf.release();
-    ui::ContextFactory::SetInstance(context_factory_);
-  }
-  CHECK(context_factory_) << "No GL bindings.";
-
-  native_viewport_->CreateGLES2Context(gles2_client_handle.Pass());
-}
-
-WindowTreeHostMojo::~WindowTreeHostMojo() {}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowTreeHostMojo, aura::WindowTreeHost implementation:
-
-ui::EventSource* WindowTreeHostMojo::GetEventSource() {
-  return this;
-}
-
-gfx::AcceleratedWidget WindowTreeHostMojo::GetAcceleratedWidget() {
-  NOTIMPLEMENTED() << "GetAcceleratedWidget";
-  return gfx::kNullAcceleratedWidget;
-}
-
-void WindowTreeHostMojo::Show() {
-  window()->Show();
-  native_viewport_->Show();
-}
-
-void WindowTreeHostMojo::Hide() {
-  native_viewport_->Hide();
-  window()->Hide();
-}
-
-gfx::Rect WindowTreeHostMojo::GetBounds() const {
-  return bounds_;
-}
-
-void WindowTreeHostMojo::SetBounds(const gfx::Rect& bounds) {
-  AllocationScope scope;
-  native_viewport_->SetBounds(bounds);
-}
-
-gfx::Point WindowTreeHostMojo::GetLocationOnNativeScreen() const {
-  return gfx::Point(0, 0);
-}
-
-void WindowTreeHostMojo::SetCapture() {
-  NOTIMPLEMENTED();
-}
-
-void WindowTreeHostMojo::ReleaseCapture() {
-  NOTIMPLEMENTED();
-}
-
-void WindowTreeHostMojo::PostNativeEvent(
-    const base::NativeEvent& native_event) {
-  NOTIMPLEMENTED();
-}
-
-void WindowTreeHostMojo::OnDeviceScaleFactorChanged(float device_scale_factor) {
-  NOTIMPLEMENTED();
-}
-
-void WindowTreeHostMojo::SetCursorNative(gfx::NativeCursor cursor) {
-  NOTIMPLEMENTED();
-}
-
-void WindowTreeHostMojo::MoveCursorToNative(const gfx::Point& location) {
-  NOTIMPLEMENTED();
-}
-
-void WindowTreeHostMojo::OnCursorVisibilityChangedNative(bool show) {
-  NOTIMPLEMENTED();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowTreeHostMojo, ui::EventSource implementation:
-
-ui::EventProcessor* WindowTreeHostMojo::GetEventProcessor() {
-  return dispatcher();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowTreeHostMojo, NativeViewportClient implementation:
-
-void WindowTreeHostMojo::OnCreated() {
-  CreateCompositor(GetAcceleratedWidget());
-  compositor_created_callback_.Run();
-}
-
-void WindowTreeHostMojo::OnBoundsChanged(const Rect& bounds) {
-  bounds_ = gfx::Rect(bounds.position().x(), bounds.position().y(),
-                      bounds.size().width(), bounds.size().height());
-  window()->SetBounds(gfx::Rect(bounds_.size()));
-  OnHostResized(bounds_.size());
-}
-
-void WindowTreeHostMojo::OnDestroyed() {
-  base::MessageLoop::current()->Quit();
-}
-
-void WindowTreeHostMojo::OnEvent(const Event& event,
-                                 const mojo::Callback<void()>& callback) {
-  switch (event.action()) {
-    case ui::ET_MOUSE_PRESSED:
-    case ui::ET_MOUSE_DRAGGED:
-    case ui::ET_MOUSE_RELEASED:
-    case ui::ET_MOUSE_MOVED:
-    case ui::ET_MOUSE_ENTERED:
-    case ui::ET_MOUSE_EXITED: {
-      gfx::Point location(event.location().x(), event.location().y());
-      ui::MouseEvent ev(static_cast<ui::EventType>(event.action()), location,
-                        location, event.flags(), 0);
-      SendEventToProcessor(&ev);
-      break;
-    }
-    case ui::ET_KEY_PRESSED:
-    case ui::ET_KEY_RELEASED: {
-      ui::KeyEvent ev(
-          static_cast<ui::EventType>(event.action()),
-          static_cast<ui::KeyboardCode>(event.key_data().key_code()),
-          event.flags(), event.key_data().is_char());
-      SendEventToProcessor(&ev);
-      break;
-    }
-    // TODO(beng): touch, etc.
-  }
-  callback.Run();
-};
-
-}  // namespace examples
-}  // namespace mojo
diff --git a/mojo/examples/aura_demo/window_tree_host_mojo.h b/mojo/examples/aura_demo/window_tree_host_mojo.h
deleted file mode 100644
index 3514d1e..0000000
--- a/mojo/examples/aura_demo/window_tree_host_mojo.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2013 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.
-
-#ifndef MOJO_EXAMPLES_AURA_DEMO_WINDOW_TREE_HOST_MOJO_H_
-#define MOJO_EXAMPLES_AURA_DEMO_WINDOW_TREE_HOST_MOJO_H_
-
-#include "base/bind.h"
-#include "mojo/public/cpp/bindings/remote_ptr.h"
-#include "mojo/services/native_viewport/native_viewport.mojom.h"
-#include "ui/aura/window_tree_host.h"
-#include "ui/events/event_source.h"
-#include "ui/gfx/rect.h"
-
-namespace ui {
-class ContextFactory;
-}
-
-namespace mojo {
-namespace examples {
-
-class WindowTreeHostMojo : public aura::WindowTreeHost,
-                           public ui::EventSource,
-                           public NativeViewportClient {
- public:
-  WindowTreeHostMojo(ScopedNativeViewportHandle viewport_handle,
-                     const gfx::Rect& bounds,
-                     const base::Callback<void()>& compositor_created_callback);
-  virtual ~WindowTreeHostMojo();
-
-  gfx::Rect bounds() const { return bounds_; }
-  ScopedMessagePipeHandle TakeGLES2PipeHandle() { return gles2_handle_.Pass(); }
-
- private:
-  // WindowTreeHost:
-  virtual ui::EventSource* GetEventSource() OVERRIDE;
-  virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
-  virtual void Show() OVERRIDE;
-  virtual void Hide() OVERRIDE;
-  virtual gfx::Rect GetBounds() const OVERRIDE;
-  virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE;
-  virtual gfx::Point GetLocationOnNativeScreen() const OVERRIDE;
-  virtual void SetCapture() OVERRIDE;
-  virtual void ReleaseCapture() OVERRIDE;
-  virtual void PostNativeEvent(const base::NativeEvent& native_event) OVERRIDE;
-  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
-  virtual void SetCursorNative(gfx::NativeCursor cursor) OVERRIDE;
-  virtual void MoveCursorToNative(const gfx::Point& location) OVERRIDE;
-  virtual void OnCursorVisibilityChangedNative(bool show) OVERRIDE;
-
-  // ui::EventSource:
-  virtual ui::EventProcessor* GetEventProcessor() OVERRIDE;
-
-  // Overridden from NativeViewportClient:
-  virtual void OnCreated() OVERRIDE;
-  virtual void OnDestroyed() OVERRIDE;
-  virtual void OnBoundsChanged(const Rect& bounds) OVERRIDE;
-  virtual void OnEvent(const Event& event,
-                       const mojo::Callback<void()>& callback) OVERRIDE;
-
-  static ui::ContextFactory* context_factory_;
-
-  ScopedMessagePipeHandle gles2_handle_;
-  RemotePtr<NativeViewport> native_viewport_;
-  base::Callback<void()> compositor_created_callback_;
-
-  gfx::Rect bounds_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowTreeHostMojo);
-};
-
-}  // namespace examples
-}  // namespace mojo
-
-#endif  // MOJO_EXAMPLES_AURA_DEMO_WINDOW_TREE_HOST_MOJO_H_
diff --git a/mojo/examples/compositor_app/compositor_host.cc b/mojo/examples/compositor_app/compositor_host.cc
index 87534ed..7c7e701 100644
--- a/mojo/examples/compositor_app/compositor_host.cc
+++ b/mojo/examples/compositor_app/compositor_host.cc
@@ -9,7 +9,7 @@
 #include "cc/output/context_provider.h"
 #include "cc/output/output_surface.h"
 #include "cc/trees/layer_tree_host.h"
-#include "mojo/examples/compositor_app/mojo_context_provider.h"
+#include "mojo/cc/context_provider_mojo.h"
 
 namespace mojo {
 namespace examples {
@@ -73,7 +73,7 @@
 scoped_ptr<cc::OutputSurface> CompositorHost::CreateOutputSurface(
     bool fallback) {
   return make_scoped_ptr(
-      new cc::OutputSurface(new MojoContextProvider(gl_pipe_.Pass())));
+      new cc::OutputSurface(new ContextProviderMojo(gl_pipe_.Pass())));
 }
 
 void CompositorHost::DidInitializeOutputSurface() {
diff --git a/mojo/examples/compositor_app/mojo_context_provider.cc b/mojo/examples/compositor_app/mojo_context_provider.cc
deleted file mode 100644
index 3b52d1e..0000000
--- a/mojo/examples/compositor_app/mojo_context_provider.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.
-
-#include "mojo/examples/compositor_app/mojo_context_provider.h"
-
-#include "base/logging.h"
-
-namespace mojo {
-namespace examples {
-
-MojoContextProvider::MojoContextProvider(ScopedMessagePipeHandle gl_pipe)
-    : gl_pipe_(gl_pipe.Pass()) {}
-
-bool MojoContextProvider::BindToCurrentThread() {
-  DCHECK(gl_pipe_.is_valid());
-  context_ = MojoGLES2CreateContext(
-      gl_pipe_.release().value(), &ContextLostThunk, NULL, this);
-  return !!context_;
-}
-
-gpu::gles2::GLES2Interface* MojoContextProvider::ContextGL() {
-  if (!context_)
-    return NULL;
-  return static_cast<gpu::gles2::GLES2Interface*>(
-      MojoGLES2GetGLES2Interface(context_));
-}
-
-gpu::ContextSupport* MojoContextProvider::ContextSupport() {
-  if (!context_)
-    return NULL;
-  return static_cast<gpu::ContextSupport*>(
-      MojoGLES2GetContextSupport(context_));
-}
-
-class GrContext* MojoContextProvider::GrContext() { return NULL; }
-
-cc::ContextProvider::Capabilities MojoContextProvider::ContextCapabilities() {
-  return capabilities_;
-}
-
-bool MojoContextProvider::IsContextLost() { return !context_; }
-bool MojoContextProvider::DestroyedOnMainThread() { return !context_; }
-
-MojoContextProvider::~MojoContextProvider() {
-  if (context_)
-    MojoGLES2DestroyContext(context_);
-}
-
-void MojoContextProvider::ContextLost() {
-  if (context_) {
-    MojoGLES2DestroyContext(context_);
-    context_ = NULL;
-  }
-}
-
-}  // namespace examples
-}  // namespace mojo
diff --git a/mojo/examples/compositor_app/mojo_context_provider.h b/mojo/examples/compositor_app/mojo_context_provider.h
deleted file mode 100644
index bcee248..0000000
--- a/mojo/examples/compositor_app/mojo_context_provider.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.
-
-#include "cc/output/context_provider.h"
-#include "mojo/public/c/gles2/gles2.h"
-#include "mojo/public/cpp/system/core.h"
-
-namespace mojo {
-namespace examples {
-
-class MojoContextProvider : public cc::ContextProvider {
- public:
-  explicit MojoContextProvider(ScopedMessagePipeHandle gl_pipe);
-
-  // cc::ContextProvider implementation.
-  virtual bool BindToCurrentThread() OVERRIDE;
-  virtual gpu::gles2::GLES2Interface* ContextGL() OVERRIDE;
-  virtual gpu::ContextSupport* ContextSupport() OVERRIDE;
-  virtual class GrContext* GrContext() OVERRIDE;
-  virtual Capabilities ContextCapabilities() OVERRIDE;
-  virtual bool IsContextLost() OVERRIDE;
-  virtual void VerifyContexts() OVERRIDE {}
-  virtual void DeleteCachedResources() OVERRIDE {}
-  virtual bool DestroyedOnMainThread() OVERRIDE;
-  virtual void SetLostContextCallback(
-      const LostContextCallback& lost_context_callback) OVERRIDE {}
-  virtual void SetMemoryPolicyChangedCallback(
-      const MemoryPolicyChangedCallback& memory_policy_changed_callback)
-      OVERRIDE {}
-
- protected:
-  friend class base::RefCountedThreadSafe<MojoContextProvider>;
-  virtual ~MojoContextProvider();
-
- private:
-  static void ContextLostThunk(void* closure) {
-    static_cast<MojoContextProvider*>(closure)->ContextLost();
-  }
-  void ContextLost();
-
-  cc::ContextProvider::Capabilities capabilities_;
-  ScopedMessagePipeHandle gl_pipe_;
-  MojoGLES2Context context_;
-};
-
-}  // namespace examples
-}  // namespace mojo
diff --git a/mojo/examples/launcher/launcher.cc b/mojo/examples/launcher/launcher.cc
index 042a7bd..a02effc 100644
--- a/mojo/examples/launcher/launcher.cc
+++ b/mojo/examples/launcher/launcher.cc
@@ -12,8 +12,8 @@
 #include "base/macros.h"
 #include "base/message_loop/message_loop.h"
 #include "base/path_service.h"
-#include "mojo/examples/aura_demo/demo_screen.h"
-#include "mojo/examples/aura_demo/window_tree_host_mojo.h"
+#include "mojo/aura/screen_mojo.h"
+#include "mojo/aura/window_tree_host_mojo.h"
 #include "mojo/examples/launcher/launcher.mojom.h"
 #include "mojo/public/cpp/bindings/allocation_scope.h"
 #include "mojo/public/cpp/bindings/remote_ptr.h"
@@ -67,6 +67,7 @@
       : root_(root),
         input_method_(ui::CreateInputMethod(this,
                                             gfx::kNullAcceleratedWidget)) {
+    ui::InitializeInputMethod();
     input_method_->Init(true);
     root_->AddPreTargetHandler(this);
     root_->SetProperty(aura::client::kRootWindowInputMethodKey,
@@ -196,7 +197,7 @@
       : Application(shell_handle),
         launcher_controller_(this),
         pending_show_(false) {
-    screen_.reset(DemoScreen::Create());
+    screen_.reset(ScreenMojo::Create());
     gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
 
     InterfacePipe<NativeViewport, AnyInterface> pipe;
@@ -260,7 +261,7 @@
     }
   }
 
-  scoped_ptr<DemoScreen> screen_;
+  scoped_ptr<ScreenMojo> screen_;
   scoped_ptr<LauncherWindowTreeClient> window_tree_client_;
   scoped_ptr<aura::client::FocusClient> focus_client_;
   scoped_ptr<aura::client::DefaultCaptureClient> capture_client_;
@@ -295,7 +296,7 @@
   // TODO(beng): This crashes in a DCHECK on X11 because this thread's
   //             MessageLoop is not of TYPE_UI. I think we need a way to build
   //             Aura that doesn't define platform-specific stuff.
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
   mojo::examples::LauncherImpl launcher(shell_handle);
   loop.Run();
 
diff --git a/mojo/examples/pepper_container_app/resource_creation_impl.cc b/mojo/examples/pepper_container_app/resource_creation_impl.cc
index cfb0679..004b845 100644
--- a/mojo/examples/pepper_container_app/resource_creation_impl.cc
+++ b/mojo/examples/pepper_container_app/resource_creation_impl.cc
@@ -211,6 +211,12 @@
   return 0;
 }
 
+PP_Resource ResourceCreationImpl::CreateMediaStreamVideoTrack(
+    PP_Instance instance) {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
 PP_Resource ResourceCreationImpl::CreateNetAddressFromIPv4Address(
     PP_Instance instance,
     const PP_NetAddress_IPv4* ipv4_addr) {
@@ -380,7 +386,7 @@
   return 0;
 }
 
-PP_Resource ResourceCreationImpl::CreateVideoDecoder(
+PP_Resource ResourceCreationImpl::CreateVideoDecoderDev(
     PP_Instance instance,
     PP_Resource context3d_id,
     PP_VideoDecoder_Profile profile) {
diff --git a/mojo/examples/pepper_container_app/resource_creation_impl.h b/mojo/examples/pepper_container_app/resource_creation_impl.h
index de1760e..8ad5727 100644
--- a/mojo/examples/pepper_container_app/resource_creation_impl.h
+++ b/mojo/examples/pepper_container_app/resource_creation_impl.h
@@ -111,6 +111,8 @@
                                             PP_ImageDataFormat format,
                                             const PP_Size* size,
                                             PP_Bool init_to_zero) OVERRIDE;
+  virtual PP_Resource CreateMediaStreamVideoTrack(
+      PP_Instance instance) OVERRIDE;
   virtual PP_Resource CreateNetAddressFromIPv4Address(
       PP_Instance instance,
       const PP_NetAddress_IPv4* ipv4_addr) OVERRIDE;
@@ -158,7 +160,7 @@
                                       PP_Bool vertical) OVERRIDE;
   virtual PP_Resource CreateTalk(PP_Instance instance) OVERRIDE;
   virtual PP_Resource CreateVideoCapture(PP_Instance instance) OVERRIDE;
-  virtual PP_Resource CreateVideoDecoder(
+  virtual PP_Resource CreateVideoDecoderDev(
       PP_Instance instance,
       PP_Resource context3d_id,
       PP_VideoDecoder_Profile profile) OVERRIDE;
diff --git a/mojo/gles2/command_buffer_client_impl.cc b/mojo/gles2/command_buffer_client_impl.cc
index ca5f967..8beef82 100644
--- a/mojo/gles2/command_buffer_client_impl.cc
+++ b/mojo/gles2/command_buffer_client_impl.cc
@@ -164,6 +164,7 @@
     size_t width,
     size_t height,
     unsigned internalformat,
+    unsigned usage,
     int32* id) {
   // TODO(piman)
   NOTIMPLEMENTED();
diff --git a/mojo/gles2/command_buffer_client_impl.h b/mojo/gles2/command_buffer_client_impl.h
index 0b08714..c867e4d 100644
--- a/mojo/gles2/command_buffer_client_impl.h
+++ b/mojo/gles2/command_buffer_client_impl.h
@@ -9,9 +9,9 @@
 
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
+#include "gpu/command_buffer/client/gpu_control.h"
 #include "gpu/command_buffer/common/command_buffer.h"
 #include "gpu/command_buffer/common/command_buffer_shared.h"
-#include "gpu/command_buffer/common/gpu_control.h"
 #include "mojo/public/cpp/bindings/error_handler.h"
 #include "mojo/public/cpp/bindings/remote_ptr.h"
 #include "mojo/services/gles2/command_buffer.mojom.h"
@@ -63,6 +63,7 @@
   virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(size_t width,
                                                       size_t height,
                                                       unsigned internalformat,
+                                                      unsigned usage,
                                                       int32* id) OVERRIDE;
   virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
   virtual uint32 InsertSyncPoint() OVERRIDE;
diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp
index 82589cf..8eea547 100644
--- a/mojo/mojo.gyp
+++ b/mojo/mojo.gyp
@@ -54,6 +54,8 @@
         'mojo_system_impl',
         'mojo_system_unittests',
         'mojo_utility',
+        'mojo_view_manager_lib',
+        'mojo_view_manager_lib_unittests',
       ],
       'conditions': [
         ['use_aura==1', {
@@ -192,6 +194,8 @@
         'system/shared_buffer_dispatcher.h',
         'system/simple_dispatcher.cc',
         'system/simple_dispatcher.h',
+        'system/transport_data.cc',
+        'system/transport_data.h',
         'system/waiter.cc',
         'system/waiter.h',
         'system/waiter_list.cc',
@@ -409,6 +413,8 @@
         'mojo_system_impl',
       ],
       'sources': [
+        'service_manager/background_service_loader.cc',
+        'service_manager/background_service_loader.h',
         'service_manager/service_loader.h',
         'service_manager/service_manager.cc',
         'service_manager/service_manager.h',
@@ -498,6 +504,8 @@
         'shell/test_child_process.h',
         'shell/url_request_context_getter.cc',
         'shell/url_request_context_getter.h',
+        'shell/view_manager_loader.cc',
+        'shell/view_manager_loader.h',
       ],
       'conditions': [
         ['OS=="linux"', {
@@ -510,9 +518,15 @@
           'dependencies': [
             # These are only necessary as long as we hard code use of ViewManager.
             '../skia/skia.gyp:skia',
+            'mojo_gles2',
             'mojo_shell_client',
             'mojo_view_manager',
           ],
+        }, {  # use_aura==0
+          'sources!': [
+            'shell/view_manager_loader.cc',
+            'shell/view_manager_loader.h',
+          ],
         }],
       ],
     },
@@ -628,6 +642,21 @@
         'tools/message_generator.cc',
       ],
     },
+    {
+      'target_name': 'mojo_cc_support',
+      'type': 'static_library',
+      'dependencies': [
+        '../base/base.gyp:base',
+        '../cc/cc.gyp:cc',
+        '../skia/skia.gyp:skia',
+        '../gpu/gpu.gyp:gles2_implementation',
+        'mojo_gles2',
+      ],
+      'sources': [
+        'cc/context_provider_mojo.cc',
+        'cc/context_provider_mojo.h',
+      ],
+    },
   ],
   'conditions': [
     ['OS=="android"', {
@@ -777,6 +806,27 @@
         }
       ],
     }],
+    ['OS=="linux"', {
+      'targets': [
+        {
+          'target_name': 'mojo_dbus_service',
+          'type': 'static_library',
+          'dependencies': [
+            '../base/base.gyp:base',
+            '../build/linux/system.gyp:dbus',
+            '../dbus/dbus.gyp:dbus',
+            'mojo_common_lib',
+            'mojo_external_service_bindings',
+            'mojo_shell_client',
+            'mojo_system_impl',
+          ],
+          'sources': [
+            'dbus/dbus_external_service.h',
+            'dbus/dbus_external_service.cc',
+          ],
+        },
+      ],
+    }],
     ['test_isolation_mode != "noop"', {
       'targets': [
         {
@@ -795,5 +845,33 @@
         },
       ],
     }],
+    ['use_aura==1', {
+      'targets': [
+        {
+          'target_name': 'mojo_aura_support',
+          'type': 'static_library',
+          'dependencies': [
+            '../cc/cc.gyp:cc',
+            '../ui/aura/aura.gyp:aura',
+            '../ui/events/events.gyp:events',
+            '../ui/events/events.gyp:events_base',
+            '../ui/compositor/compositor.gyp:compositor',
+            '../ui/gl/gl.gyp:gl',
+            '../webkit/common/gpu/webkit_gpu.gyp:webkit_gpu',
+            'mojo_cc_support',
+            'mojo_gles2',
+            'mojo_native_viewport_bindings',
+          ],
+          'sources': [
+            'aura/context_factory_mojo.cc',
+            'aura/context_factory_mojo.h',
+            'aura/screen_mojo.cc',
+            'aura/screen_mojo.h',
+            'aura/window_tree_host_mojo.cc',
+            'aura/window_tree_host_mojo.h',
+          ],
+        },
+      ],
+    }],
   ],
 }
diff --git a/mojo/mojo_apps.gypi b/mojo/mojo_apps.gypi
index fe8d65e..364e0aa 100644
--- a/mojo/mojo_apps.gypi
+++ b/mojo/mojo_apps.gypi
@@ -37,10 +37,28 @@
       ],
     },
     {
+      'target_name': 'mojo_apps_js_bindings',
+      'type': 'static_library',
+      'sources': [
+        'apps/js/test/js_to_cpp.mojom',
+      ],
+      'variables': {
+        'mojom_base_output_dir': 'mojo',
+      },
+      'includes': [ 'public/tools/bindings/mojom_bindings_generator.gypi' ],
+      'export_dependent_settings': [
+        'mojo_cpp_bindings',
+      ],
+      'dependencies': [
+        'mojo_cpp_bindings',
+      ],
+    },
+    {
       'target_name': 'mojo_apps_js_unittests',
       'type': 'executable',
       'dependencies': [
         '../gin/gin.gyp:gin_test',
+        'mojo_apps_js_bindings',
         'mojo_common_lib',
         'mojo_common_test_support',
         'mojo_js_lib',
diff --git a/mojo/mojo_common_lib.target.darwin-arm.mk b/mojo/mojo_common_lib.target.darwin-arm.mk
index 5da4730..e6c7012 100644
--- a/mojo/mojo_common_lib.target.darwin-arm.mk
+++ b/mojo/mojo_common_lib.target.darwin-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +133,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_common_lib.target.darwin-x86.mk b/mojo/mojo_common_lib.target.darwin-x86.mk
index 9f98c20..52803b4 100644
--- a/mojo/mojo_common_lib.target.darwin-x86.mk
+++ b/mojo/mojo_common_lib.target.darwin-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_common_lib.target.darwin-x86_64.mk b/mojo/mojo_common_lib.target.darwin-x86_64.mk
index 2c4b38e..336a28b 100644
--- a/mojo/mojo_common_lib.target.darwin-x86_64.mk
+++ b/mojo/mojo_common_lib.target.darwin-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_common_lib.target.linux-arm.mk b/mojo/mojo_common_lib.target.linux-arm.mk
index 5da4730..e6c7012 100644
--- a/mojo/mojo_common_lib.target.linux-arm.mk
+++ b/mojo/mojo_common_lib.target.linux-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +133,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_common_lib.target.linux-x86.mk b/mojo/mojo_common_lib.target.linux-x86.mk
index 9f98c20..52803b4 100644
--- a/mojo/mojo_common_lib.target.linux-x86.mk
+++ b/mojo/mojo_common_lib.target.linux-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_common_lib.target.linux-x86_64.mk b/mojo/mojo_common_lib.target.linux-x86_64.mk
index 2c4b38e..336a28b 100644
--- a/mojo/mojo_common_lib.target.linux-x86_64.mk
+++ b/mojo/mojo_common_lib.target.linux-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_cpp_bindings.target.darwin-arm.mk b/mojo/mojo_cpp_bindings.target.darwin-arm.mk
index 6671242..0aa2a86 100644
--- a/mojo/mojo_cpp_bindings.target.darwin-arm.mk
+++ b/mojo/mojo_cpp_bindings.target.darwin-arm.mk
@@ -33,6 +33,7 @@
 	mojo/public/cpp/bindings/lib/interface.cc \
 	mojo/public/cpp/bindings/lib/message.cc \
 	mojo/public/cpp/bindings/lib/message_builder.cc \
+	mojo/public/cpp/bindings/lib/message_header_validator.cc \
 	mojo/public/cpp/bindings/lib/message_queue.cc \
 	mojo/public/cpp/bindings/lib/router.cc \
 	mojo/public/cpp/bindings/lib/scratch_buffer.cc \
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_cpp_bindings.target.darwin-arm64.mk b/mojo/mojo_cpp_bindings.target.darwin-arm64.mk
index b0bf9b5..73d6fad 100644
--- a/mojo/mojo_cpp_bindings.target.darwin-arm64.mk
+++ b/mojo/mojo_cpp_bindings.target.darwin-arm64.mk
@@ -33,6 +33,7 @@
 	mojo/public/cpp/bindings/lib/interface.cc \
 	mojo/public/cpp/bindings/lib/message.cc \
 	mojo/public/cpp/bindings/lib/message_builder.cc \
+	mojo/public/cpp/bindings/lib/message_header_validator.cc \
 	mojo/public/cpp/bindings/lib/message_queue.cc \
 	mojo/public/cpp/bindings/lib/router.cc \
 	mojo/public/cpp/bindings/lib/scratch_buffer.cc \
diff --git a/mojo/mojo_cpp_bindings.target.darwin-mips.mk b/mojo/mojo_cpp_bindings.target.darwin-mips.mk
index 19ccc92..1164197 100644
--- a/mojo/mojo_cpp_bindings.target.darwin-mips.mk
+++ b/mojo/mojo_cpp_bindings.target.darwin-mips.mk
@@ -33,6 +33,7 @@
 	mojo/public/cpp/bindings/lib/interface.cc \
 	mojo/public/cpp/bindings/lib/message.cc \
 	mojo/public/cpp/bindings/lib/message_builder.cc \
+	mojo/public/cpp/bindings/lib/message_header_validator.cc \
 	mojo/public/cpp/bindings/lib/message_queue.cc \
 	mojo/public/cpp/bindings/lib/router.cc \
 	mojo/public/cpp/bindings/lib/scratch_buffer.cc \
diff --git a/mojo/mojo_cpp_bindings.target.darwin-x86.mk b/mojo/mojo_cpp_bindings.target.darwin-x86.mk
index a182dfd..5efa9fe 100644
--- a/mojo/mojo_cpp_bindings.target.darwin-x86.mk
+++ b/mojo/mojo_cpp_bindings.target.darwin-x86.mk
@@ -33,6 +33,7 @@
 	mojo/public/cpp/bindings/lib/interface.cc \
 	mojo/public/cpp/bindings/lib/message.cc \
 	mojo/public/cpp/bindings/lib/message_builder.cc \
+	mojo/public/cpp/bindings/lib/message_header_validator.cc \
 	mojo/public/cpp/bindings/lib/message_queue.cc \
 	mojo/public/cpp/bindings/lib/router.cc \
 	mojo/public/cpp/bindings/lib/scratch_buffer.cc \
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_cpp_bindings.target.darwin-x86_64.mk b/mojo/mojo_cpp_bindings.target.darwin-x86_64.mk
index ca01d54..6f7c8c9 100644
--- a/mojo/mojo_cpp_bindings.target.darwin-x86_64.mk
+++ b/mojo/mojo_cpp_bindings.target.darwin-x86_64.mk
@@ -33,6 +33,7 @@
 	mojo/public/cpp/bindings/lib/interface.cc \
 	mojo/public/cpp/bindings/lib/message.cc \
 	mojo/public/cpp/bindings/lib/message_builder.cc \
+	mojo/public/cpp/bindings/lib/message_header_validator.cc \
 	mojo/public/cpp/bindings/lib/message_queue.cc \
 	mojo/public/cpp/bindings/lib/router.cc \
 	mojo/public/cpp/bindings/lib/scratch_buffer.cc \
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_cpp_bindings.target.linux-arm.mk b/mojo/mojo_cpp_bindings.target.linux-arm.mk
index 6671242..0aa2a86 100644
--- a/mojo/mojo_cpp_bindings.target.linux-arm.mk
+++ b/mojo/mojo_cpp_bindings.target.linux-arm.mk
@@ -33,6 +33,7 @@
 	mojo/public/cpp/bindings/lib/interface.cc \
 	mojo/public/cpp/bindings/lib/message.cc \
 	mojo/public/cpp/bindings/lib/message_builder.cc \
+	mojo/public/cpp/bindings/lib/message_header_validator.cc \
 	mojo/public/cpp/bindings/lib/message_queue.cc \
 	mojo/public/cpp/bindings/lib/router.cc \
 	mojo/public/cpp/bindings/lib/scratch_buffer.cc \
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_cpp_bindings.target.linux-arm64.mk b/mojo/mojo_cpp_bindings.target.linux-arm64.mk
index b0bf9b5..73d6fad 100644
--- a/mojo/mojo_cpp_bindings.target.linux-arm64.mk
+++ b/mojo/mojo_cpp_bindings.target.linux-arm64.mk
@@ -33,6 +33,7 @@
 	mojo/public/cpp/bindings/lib/interface.cc \
 	mojo/public/cpp/bindings/lib/message.cc \
 	mojo/public/cpp/bindings/lib/message_builder.cc \
+	mojo/public/cpp/bindings/lib/message_header_validator.cc \
 	mojo/public/cpp/bindings/lib/message_queue.cc \
 	mojo/public/cpp/bindings/lib/router.cc \
 	mojo/public/cpp/bindings/lib/scratch_buffer.cc \
diff --git a/mojo/mojo_cpp_bindings.target.linux-mips.mk b/mojo/mojo_cpp_bindings.target.linux-mips.mk
index 19ccc92..1164197 100644
--- a/mojo/mojo_cpp_bindings.target.linux-mips.mk
+++ b/mojo/mojo_cpp_bindings.target.linux-mips.mk
@@ -33,6 +33,7 @@
 	mojo/public/cpp/bindings/lib/interface.cc \
 	mojo/public/cpp/bindings/lib/message.cc \
 	mojo/public/cpp/bindings/lib/message_builder.cc \
+	mojo/public/cpp/bindings/lib/message_header_validator.cc \
 	mojo/public/cpp/bindings/lib/message_queue.cc \
 	mojo/public/cpp/bindings/lib/router.cc \
 	mojo/public/cpp/bindings/lib/scratch_buffer.cc \
diff --git a/mojo/mojo_cpp_bindings.target.linux-x86.mk b/mojo/mojo_cpp_bindings.target.linux-x86.mk
index a182dfd..5efa9fe 100644
--- a/mojo/mojo_cpp_bindings.target.linux-x86.mk
+++ b/mojo/mojo_cpp_bindings.target.linux-x86.mk
@@ -33,6 +33,7 @@
 	mojo/public/cpp/bindings/lib/interface.cc \
 	mojo/public/cpp/bindings/lib/message.cc \
 	mojo/public/cpp/bindings/lib/message_builder.cc \
+	mojo/public/cpp/bindings/lib/message_header_validator.cc \
 	mojo/public/cpp/bindings/lib/message_queue.cc \
 	mojo/public/cpp/bindings/lib/router.cc \
 	mojo/public/cpp/bindings/lib/scratch_buffer.cc \
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_cpp_bindings.target.linux-x86_64.mk b/mojo/mojo_cpp_bindings.target.linux-x86_64.mk
index ca01d54..6f7c8c9 100644
--- a/mojo/mojo_cpp_bindings.target.linux-x86_64.mk
+++ b/mojo/mojo_cpp_bindings.target.linux-x86_64.mk
@@ -33,6 +33,7 @@
 	mojo/public/cpp/bindings/lib/interface.cc \
 	mojo/public/cpp/bindings/lib/message.cc \
 	mojo/public/cpp/bindings/lib/message_builder.cc \
+	mojo/public/cpp/bindings/lib/message_header_validator.cc \
 	mojo/public/cpp/bindings/lib/message_queue.cc \
 	mojo/public/cpp/bindings/lib/router.cc \
 	mojo/public/cpp/bindings/lib/scratch_buffer.cc \
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_environment_chromium.target.darwin-arm.mk b/mojo/mojo_environment_chromium.target.darwin-arm.mk
index b7e5624..0cc9c65 100644
--- a/mojo/mojo_environment_chromium.target.darwin-arm.mk
+++ b/mojo/mojo_environment_chromium.target.darwin-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_environment_chromium.target.darwin-x86.mk b/mojo/mojo_environment_chromium.target.darwin-x86.mk
index 435cc4c..4297acd 100644
--- a/mojo/mojo_environment_chromium.target.darwin-x86.mk
+++ b/mojo/mojo_environment_chromium.target.darwin-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_environment_chromium.target.darwin-x86_64.mk b/mojo/mojo_environment_chromium.target.darwin-x86_64.mk
index 8062f99..a6e4482 100644
--- a/mojo/mojo_environment_chromium.target.darwin-x86_64.mk
+++ b/mojo/mojo_environment_chromium.target.darwin-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_environment_chromium.target.linux-arm.mk b/mojo/mojo_environment_chromium.target.linux-arm.mk
index b7e5624..0cc9c65 100644
--- a/mojo/mojo_environment_chromium.target.linux-arm.mk
+++ b/mojo/mojo_environment_chromium.target.linux-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_environment_chromium.target.linux-x86.mk b/mojo/mojo_environment_chromium.target.linux-x86.mk
index 435cc4c..4297acd 100644
--- a/mojo/mojo_environment_chromium.target.linux-x86.mk
+++ b/mojo/mojo_environment_chromium.target.linux-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_environment_chromium.target.linux-x86_64.mk b/mojo/mojo_environment_chromium.target.linux-x86_64.mk
index 8062f99..a6e4482 100644
--- a/mojo/mojo_environment_chromium.target.linux-x86_64.mk
+++ b/mojo/mojo_environment_chromium.target.linux-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_environment_chromium_impl.target.darwin-arm.mk b/mojo/mojo_environment_chromium_impl.target.darwin-arm.mk
index 9b04cb4..5ed6823 100644
--- a/mojo/mojo_environment_chromium_impl.target.darwin-arm.mk
+++ b/mojo/mojo_environment_chromium_impl.target.darwin-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_environment_chromium_impl.target.darwin-x86.mk b/mojo/mojo_environment_chromium_impl.target.darwin-x86.mk
index 0ce4334..9c201d1 100644
--- a/mojo/mojo_environment_chromium_impl.target.darwin-x86.mk
+++ b/mojo/mojo_environment_chromium_impl.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_environment_chromium_impl.target.darwin-x86_64.mk b/mojo/mojo_environment_chromium_impl.target.darwin-x86_64.mk
index be57920..0ffdb9f 100644
--- a/mojo/mojo_environment_chromium_impl.target.darwin-x86_64.mk
+++ b/mojo/mojo_environment_chromium_impl.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_environment_chromium_impl.target.linux-arm.mk b/mojo/mojo_environment_chromium_impl.target.linux-arm.mk
index 9b04cb4..5ed6823 100644
--- a/mojo/mojo_environment_chromium_impl.target.linux-arm.mk
+++ b/mojo/mojo_environment_chromium_impl.target.linux-arm.mk
@@ -42,7 +42,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_environment_chromium_impl.target.linux-x86.mk b/mojo/mojo_environment_chromium_impl.target.linux-x86.mk
index 0ce4334..9c201d1 100644
--- a/mojo/mojo_environment_chromium_impl.target.linux-x86.mk
+++ b/mojo/mojo_environment_chromium_impl.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_environment_chromium_impl.target.linux-x86_64.mk b/mojo/mojo_environment_chromium_impl.target.linux-x86_64.mk
index be57920..0ffdb9f 100644
--- a/mojo/mojo_environment_chromium_impl.target.linux-x86_64.mk
+++ b/mojo/mojo_environment_chromium_impl.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_examples.gypi b/mojo/mojo_examples.gypi
index 79a3242..6b49474 100644
--- a/mojo/mojo_examples.gypi
+++ b/mojo/mojo_examples.gypi
@@ -35,21 +35,6 @@
       'includes': [ 'build/package_app.gypi' ],
     },
     {
-      'target_name': 'mojo_compositor_support',
-      'type': 'static_library',
-      'dependencies': [
-        '../base/base.gyp:base',
-        '../cc/cc.gyp:cc',
-        '../skia/skia.gyp:skia',
-        '../gpu/gpu.gyp:gles2_implementation',
-        'mojo_gles2',
-      ],
-      'sources': [
-        'examples/compositor_app/mojo_context_provider.cc',
-        'examples/compositor_app/mojo_context_provider.h',
-      ],
-    },
-    {
       'target_name': 'mojo_compositor_app',
       'type': 'shared_library',
       'dependencies': [
@@ -57,8 +42,8 @@
         '../cc/cc.gyp:cc',
         '../ui/gfx/gfx.gyp:gfx',
         '../ui/gfx/gfx.gyp:gfx_geometry',
+        'mojo_cc_support',
         'mojo_common_lib',
-        'mojo_compositor_support',
         'mojo_environment_chromium',
         'mojo_gles2',
         'mojo_native_viewport_bindings',
@@ -176,30 +161,6 @@
     ['use_aura==1', {
       'targets': [
         {
-          'target_name': 'mojo_aura_demo_support',
-          'type': 'static_library',
-          'dependencies': [
-            '../cc/cc.gyp:cc',
-            '../ui/aura/aura.gyp:aura',
-            '../ui/events/events.gyp:events',
-            '../ui/events/events.gyp:events_base',
-            '../ui/compositor/compositor.gyp:compositor',
-            '../ui/gl/gl.gyp:gl',
-            '../webkit/common/gpu/webkit_gpu.gyp:webkit_gpu',
-            'mojo_compositor_support',
-            'mojo_gles2',
-            'mojo_native_viewport_bindings',
-          ],
-          'sources': [
-            'examples/aura_demo/demo_context_factory.cc',
-            'examples/aura_demo/demo_context_factory.h',
-            'examples/aura_demo/demo_screen.cc',
-            'examples/aura_demo/demo_screen.h',
-            'examples/aura_demo/window_tree_host_mojo.cc',
-            'examples/aura_demo/window_tree_host_mojo.h',
-          ],
-        },
-        {
           'target_name': 'mojo_aura_demo',
           'type': 'shared_library',
           'dependencies': [
@@ -208,7 +169,8 @@
             '../ui/base/ui_base.gyp:ui_base',
             '../ui/gfx/gfx.gyp:gfx',
             '../ui/gfx/gfx.gyp:gfx_geometry',
-            'mojo_aura_demo_support',
+            'mojo_aura_support',
+            'mojo_cc_support',
             'mojo_common_lib',
             'mojo_environment_chromium',
             'mojo_gles2',
@@ -249,6 +211,7 @@
           'dependencies': [
             '../base/base.gyp:base',
             '../base/base.gyp:base_i18n',
+            '../base/base.gyp:test_support_base',
             '../ui/aura/aura.gyp:aura',
             '../ui/aura/aura.gyp:aura_test_support',
             '../ui/base/ui_base.gyp:ui_base',
@@ -257,7 +220,7 @@
             '../ui/views/views.gyp:views',
             '../ui/wm/wm.gyp:wm',
             '../url/url.gyp:url_lib',
-            'mojo_aura_demo_support',
+            'mojo_aura_support',
             'mojo_common_lib',
             'mojo_environment_chromium',
             'mojo_gles2',
@@ -281,6 +244,7 @@
           'type': 'shared_library',
           'dependencies': [
             '../base/base.gyp:base',
+            '../skia/skia.gyp:skia',
             '../ui/gfx/gfx.gyp:gfx',
             '../ui/gfx/gfx.gyp:gfx_geometry',
             '../ui/gl/gl.gyp:gl',
diff --git a/mojo/mojo_js_bindings.target.darwin-arm.mk b/mojo/mojo_js_bindings.target.darwin-arm.mk
index 0965c17..4fe1dba 100644
--- a/mojo/mojo_js_bindings.target.darwin-arm.mk
+++ b/mojo/mojo_js_bindings.target.darwin-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -126,7 +125,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_js_bindings.target.darwin-x86.mk b/mojo/mojo_js_bindings.target.darwin-x86.mk
index d135135..2fffbbe 100644
--- a/mojo/mojo_js_bindings.target.darwin-x86.mk
+++ b/mojo/mojo_js_bindings.target.darwin-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_js_bindings.target.darwin-x86_64.mk b/mojo/mojo_js_bindings.target.darwin-x86_64.mk
index 9f5abb9..677459e 100644
--- a/mojo/mojo_js_bindings.target.darwin-x86_64.mk
+++ b/mojo/mojo_js_bindings.target.darwin-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_js_bindings.target.linux-arm.mk b/mojo/mojo_js_bindings.target.linux-arm.mk
index 0965c17..4fe1dba 100644
--- a/mojo/mojo_js_bindings.target.linux-arm.mk
+++ b/mojo/mojo_js_bindings.target.linux-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -126,7 +125,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_js_bindings.target.linux-x86.mk b/mojo/mojo_js_bindings.target.linux-x86.mk
index d135135..2fffbbe 100644
--- a/mojo/mojo_js_bindings.target.linux-x86.mk
+++ b/mojo/mojo_js_bindings.target.linux-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_js_bindings.target.linux-x86_64.mk b/mojo/mojo_js_bindings.target.linux-x86_64.mk
index 9f5abb9..677459e 100644
--- a/mojo/mojo_js_bindings.target.linux-x86_64.mk
+++ b/mojo/mojo_js_bindings.target.linux-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_js_bindings_lib.target.darwin-arm.mk b/mojo/mojo_js_bindings_lib.target.darwin-arm.mk
index 447aa89..bcd203b 100644
--- a/mojo/mojo_js_bindings_lib.target.darwin-arm.mk
+++ b/mojo/mojo_js_bindings_lib.target.darwin-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -136,7 +135,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_js_bindings_lib.target.darwin-x86.mk b/mojo/mojo_js_bindings_lib.target.darwin-x86.mk
index d5cf56f..5a07c5f 100644
--- a/mojo/mojo_js_bindings_lib.target.darwin-x86.mk
+++ b/mojo/mojo_js_bindings_lib.target.darwin-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_js_bindings_lib.target.darwin-x86_64.mk b/mojo/mojo_js_bindings_lib.target.darwin-x86_64.mk
index 8252f69..876eadb 100644
--- a/mojo/mojo_js_bindings_lib.target.darwin-x86_64.mk
+++ b/mojo/mojo_js_bindings_lib.target.darwin-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_js_bindings_lib.target.linux-arm.mk b/mojo/mojo_js_bindings_lib.target.linux-arm.mk
index 447aa89..bcd203b 100644
--- a/mojo/mojo_js_bindings_lib.target.linux-arm.mk
+++ b/mojo/mojo_js_bindings_lib.target.linux-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -136,7 +135,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_js_bindings_lib.target.linux-x86.mk b/mojo/mojo_js_bindings_lib.target.linux-x86.mk
index d5cf56f..5a07c5f 100644
--- a/mojo/mojo_js_bindings_lib.target.linux-x86.mk
+++ b/mojo/mojo_js_bindings_lib.target.linux-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_js_bindings_lib.target.linux-x86_64.mk b/mojo/mojo_js_bindings_lib.target.linux-x86_64.mk
index 8252f69..876eadb 100644
--- a/mojo/mojo_js_bindings_lib.target.linux-x86_64.mk
+++ b/mojo/mojo_js_bindings_lib.target.linux-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_public.gypi b/mojo/mojo_public.gypi
index 8f124e7..f3a8a1d 100644
--- a/mojo/mojo_public.gypi
+++ b/mojo/mojo_public.gypi
@@ -107,6 +107,7 @@
         'mojo_test_support',
       ],
       'sources': [
+        'public/cpp/test_support/lib/test_support.cc',
         'public/cpp/test_support/lib/test_utils.cc',
         'public/cpp/test_support/test_utils.h',
       ],
@@ -134,6 +135,7 @@
         'public/cpp/bindings/tests/router_unittest.cc',
         'public/cpp/bindings/tests/sample_service_unittest.cc',
         'public/cpp/bindings/tests/type_conversion_unittest.cc',
+        'public/cpp/bindings/tests/validation_unittest.cc',
       ],
     },
     {
@@ -243,6 +245,8 @@
         'public/cpp/bindings/lib/message.cc',
         'public/cpp/bindings/lib/message_builder.cc',
         'public/cpp/bindings/lib/message_builder.h',
+        'public/cpp/bindings/lib/message_header_validator.cc',
+        'public/cpp/bindings/lib/message_header_validator.h',
         'public/cpp/bindings/lib/message_internal.h',
         'public/cpp/bindings/lib/message_queue.cc',
         'public/cpp/bindings/lib/message_queue.h',
diff --git a/mojo/mojo_service_manager.target.darwin-arm.mk b/mojo/mojo_service_manager.target.darwin-arm.mk
index b90703c..6c535d6 100644
--- a/mojo/mojo_service_manager.target.darwin-arm.mk
+++ b/mojo/mojo_service_manager.target.darwin-arm.mk
@@ -25,6 +25,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	mojo/service_manager/background_service_loader.cc \
 	mojo/service_manager/service_manager.cc
 
 
@@ -42,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +134,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_service_manager.target.darwin-arm64.mk b/mojo/mojo_service_manager.target.darwin-arm64.mk
index 4cfd157..36e7ac6 100644
--- a/mojo/mojo_service_manager.target.darwin-arm64.mk
+++ b/mojo/mojo_service_manager.target.darwin-arm64.mk
@@ -25,6 +25,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	mojo/service_manager/background_service_loader.cc \
 	mojo/service_manager/service_manager.cc
 
 
diff --git a/mojo/mojo_service_manager.target.darwin-mips.mk b/mojo/mojo_service_manager.target.darwin-mips.mk
index 3fe9c82..7c30f6c 100644
--- a/mojo/mojo_service_manager.target.darwin-mips.mk
+++ b/mojo/mojo_service_manager.target.darwin-mips.mk
@@ -25,6 +25,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	mojo/service_manager/background_service_loader.cc \
 	mojo/service_manager/service_manager.cc
 
 
diff --git a/mojo/mojo_service_manager.target.darwin-x86.mk b/mojo/mojo_service_manager.target.darwin-x86.mk
index d953c97..0f91646 100644
--- a/mojo/mojo_service_manager.target.darwin-x86.mk
+++ b/mojo/mojo_service_manager.target.darwin-x86.mk
@@ -25,6 +25,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	mojo/service_manager/background_service_loader.cc \
 	mojo/service_manager/service_manager.cc
 
 
@@ -44,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -135,7 +135,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_service_manager.target.darwin-x86_64.mk b/mojo/mojo_service_manager.target.darwin-x86_64.mk
index 4868f83..3ff3dc8 100644
--- a/mojo/mojo_service_manager.target.darwin-x86_64.mk
+++ b/mojo/mojo_service_manager.target.darwin-x86_64.mk
@@ -25,6 +25,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	mojo/service_manager/background_service_loader.cc \
 	mojo/service_manager/service_manager.cc
 
 
@@ -44,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +136,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_service_manager.target.linux-arm.mk b/mojo/mojo_service_manager.target.linux-arm.mk
index b90703c..6c535d6 100644
--- a/mojo/mojo_service_manager.target.linux-arm.mk
+++ b/mojo/mojo_service_manager.target.linux-arm.mk
@@ -25,6 +25,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	mojo/service_manager/background_service_loader.cc \
 	mojo/service_manager/service_manager.cc
 
 
@@ -42,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +134,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_service_manager.target.linux-arm64.mk b/mojo/mojo_service_manager.target.linux-arm64.mk
index 4cfd157..36e7ac6 100644
--- a/mojo/mojo_service_manager.target.linux-arm64.mk
+++ b/mojo/mojo_service_manager.target.linux-arm64.mk
@@ -25,6 +25,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	mojo/service_manager/background_service_loader.cc \
 	mojo/service_manager/service_manager.cc
 
 
diff --git a/mojo/mojo_service_manager.target.linux-mips.mk b/mojo/mojo_service_manager.target.linux-mips.mk
index 3fe9c82..7c30f6c 100644
--- a/mojo/mojo_service_manager.target.linux-mips.mk
+++ b/mojo/mojo_service_manager.target.linux-mips.mk
@@ -25,6 +25,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	mojo/service_manager/background_service_loader.cc \
 	mojo/service_manager/service_manager.cc
 
 
diff --git a/mojo/mojo_service_manager.target.linux-x86.mk b/mojo/mojo_service_manager.target.linux-x86.mk
index d953c97..0f91646 100644
--- a/mojo/mojo_service_manager.target.linux-x86.mk
+++ b/mojo/mojo_service_manager.target.linux-x86.mk
@@ -25,6 +25,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	mojo/service_manager/background_service_loader.cc \
 	mojo/service_manager/service_manager.cc
 
 
@@ -44,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -135,7 +135,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_service_manager.target.linux-x86_64.mk b/mojo/mojo_service_manager.target.linux-x86_64.mk
index 4868f83..3ff3dc8 100644
--- a/mojo/mojo_service_manager.target.linux-x86_64.mk
+++ b/mojo/mojo_service_manager.target.linux-x86_64.mk
@@ -25,6 +25,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	mojo/service_manager/background_service_loader.cc \
 	mojo/service_manager/service_manager.cc
 
 
@@ -44,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +136,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_services.gypi b/mojo/mojo_services.gypi
index 73f5793..217a0a1 100644
--- a/mojo/mojo_services.gypi
+++ b/mojo/mojo_services.gypi
@@ -119,6 +119,13 @@
       ],
     },
     {
+      'target_name': 'mojo_view_manager_common',
+      'type': 'static_library',
+      'sources': [
+        'services/public/cpp/view_manager/view_manager_types.h',
+      ],
+    },
+    {
       'target_name': 'mojo_view_manager_bindings',
       'type': 'static_library',
       'sources': [
@@ -140,7 +147,9 @@
       'type': 'static_library',
       'dependencies': [
         '../base/base.gyp:base',
+        'mojo_shell_bindings',
         'mojo_view_manager_bindings',
+        'mojo_view_manager_common',
       ],
       'sources': [
         'services/public/cpp/view_manager/lib/view.cc',
@@ -156,6 +165,7 @@
         'services/public/cpp/view_manager/lib/view_tree_node_private.h',
         'services/public/cpp/view_manager/view.h',
         'services/public/cpp/view_manager/view_manager.h',
+        'services/public/cpp/view_manager/view_manager_types.h',
         'services/public/cpp/view_manager/view_tree_host.h',
         'services/public/cpp/view_manager/view_tree_node.h',
         'services/public/cpp/view_manager/view_tree_node_observer.h',
@@ -169,7 +179,8 @@
         '../base/base.gyp:test_support_base',
         '../testing/gtest.gyp:gtest',
         'mojo_environment_chromium',
-        'mojo_run_all_unittests',
+        'mojo_shell_test_support',
+        'mojo_view_manager_bindings',
         'mojo_view_manager_lib',
       ],
       'sources': [
@@ -178,6 +189,17 @@
         'services/public/cpp/view_manager/tests/view_tree_host_unittest.cc',
         'services/public/cpp/view_manager/tests/view_tree_node_unittest.cc',
       ],
+      'conditions': [
+        ['use_aura==1', {
+          'dependencies': [
+            'mojo_view_manager_run_unittests'
+          ],
+        }, {  # use_aura==0
+          'dependencies': [
+            'mojo_run_all_unittests',
+          ],
+        }]
+      ],
     },
   ],
   'conditions': [
@@ -190,25 +212,32 @@
             '../base/base.gyp:base',
             '../skia/skia.gyp:skia',
             '../ui/aura/aura.gyp:aura',
+            '../ui/base/ui_base.gyp:ui_base',
+            '../ui/gfx/gfx.gyp:gfx',
             '../ui/gfx/gfx.gyp:gfx_geometry',
+            'mojo_aura_support',
             'mojo_common_lib',
             'mojo_environment_chromium',
+            'mojo_gles2',
             'mojo_launcher_bindings',
             'mojo_native_viewport_bindings',
             'mojo_shell_client',
             'mojo_system_impl',
             'mojo_view_manager_bindings',
+            'mojo_view_manager_common',
           ],
           'sources': [
             'services/view_manager/ids.h',
+            'services/view_manager/main.cc',
             'services/view_manager/node.cc',
             'services/view_manager/node.h',
             'services/view_manager/node_delegate.h',
             'services/view_manager/root_node_manager.cc',
             'services/view_manager/root_node_manager.h',
+            'services/view_manager/root_view_manager.cc',
+            'services/view_manager/root_view_manager.h',
             'services/view_manager/view.cc',
             'services/view_manager/view.h',
-            'services/view_manager/view_manager.cc',
             'services/view_manager/view_manager_connection.cc',
             'services/view_manager/view_manager_connection.h',
             'services/view_manager/view_manager_export.h',
@@ -218,19 +247,36 @@
           ],
         },
         {
+          'target_name': 'mojo_view_manager_run_unittests',
+          'type': 'static_library',
+          'dependencies': [
+            '../base/base.gyp:base',
+            '../base/base.gyp:test_support_base',
+            '../ui/gl/gl.gyp:gl',
+          ],
+          'sources': [
+            'services/public/cpp/view_manager/lib/view_manager_test_suite.cc',
+            'services/public/cpp/view_manager/lib/view_manager_test_suite.h',
+            'services/public/cpp/view_manager/lib/view_manager_unittests.cc',
+          ],
+        },
+        {
           'target_name': 'mojo_view_manager_unittests',
           'type': 'executable',
           'dependencies': [
             '../base/base.gyp:base',
-            '../base/base.gyp:run_all_unittests',
+            '../base/base.gyp:test_support_base',
             '../skia/skia.gyp:skia',
             '../testing/gtest.gyp:gtest',
             '../ui/aura/aura.gyp:aura',
+            '../ui/gl/gl.gyp:gl',
             'mojo_environment_chromium',
             'mojo_shell_client',
             'mojo_shell_test_support',
             'mojo_system_impl',
             'mojo_view_manager_bindings',
+            'mojo_view_manager_common',
+            'mojo_view_manager_run_unittests',
           ],
           'sources': [
             'services/view_manager/view_manager_connection_unittest.cc',
@@ -254,10 +300,10 @@
             '../base/base.gyp:base',
             '../build/linux/system.gyp:dbus',
             '../dbus/dbus.gyp:dbus',
-            'mojo_external_service_bindings',
             'mojo_common_lib',
-            'mojo_environment_chromium',
+            'mojo_dbus_service',
             'mojo_echo_bindings',
+            'mojo_environment_chromium',
             'mojo_shell_client',
             'mojo_system_impl',
           ],
diff --git a/mojo/mojo_shell_bindings.target.darwin-arm.mk b/mojo/mojo_shell_bindings.target.darwin-arm.mk
index 31dacd7..7ac73c4 100644
--- a/mojo/mojo_shell_bindings.target.darwin-arm.mk
+++ b/mojo/mojo_shell_bindings.target.darwin-arm.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -152,7 +152,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_shell_bindings.target.darwin-arm64.mk b/mojo/mojo_shell_bindings.target.darwin-arm64.mk
index 4027458..548935f 100644
--- a/mojo/mojo_shell_bindings.target.darwin-arm64.mk
+++ b/mojo/mojo_shell_bindings.target.darwin-arm64.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/mojo/mojo_shell_bindings.target.darwin-mips.mk b/mojo/mojo_shell_bindings.target.darwin-mips.mk
index 8638255..9201520 100644
--- a/mojo/mojo_shell_bindings.target.darwin-mips.mk
+++ b/mojo/mojo_shell_bindings.target.darwin-mips.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/mojo/mojo_shell_bindings.target.darwin-x86.mk b/mojo/mojo_shell_bindings.target.darwin-x86.mk
index 7a33300..ae85195 100644
--- a/mojo/mojo_shell_bindings.target.darwin-x86.mk
+++ b/mojo/mojo_shell_bindings.target.darwin-x86.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,7 +69,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +154,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_shell_bindings.target.darwin-x86_64.mk b/mojo/mojo_shell_bindings.target.darwin-x86_64.mk
index d5929ca..418bac4 100644
--- a/mojo/mojo_shell_bindings.target.darwin-x86_64.mk
+++ b/mojo/mojo_shell_bindings.target.darwin-x86_64.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,7 +69,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +154,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_shell_bindings.target.linux-arm.mk b/mojo/mojo_shell_bindings.target.linux-arm.mk
index 31dacd7..7ac73c4 100644
--- a/mojo/mojo_shell_bindings.target.linux-arm.mk
+++ b/mojo/mojo_shell_bindings.target.linux-arm.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,7 +67,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -152,7 +152,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_shell_bindings.target.linux-arm64.mk b/mojo/mojo_shell_bindings.target.linux-arm64.mk
index 4027458..548935f 100644
--- a/mojo/mojo_shell_bindings.target.linux-arm64.mk
+++ b/mojo/mojo_shell_bindings.target.linux-arm64.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/mojo/mojo_shell_bindings.target.linux-mips.mk b/mojo/mojo_shell_bindings.target.linux-mips.mk
index 8638255..9201520 100644
--- a/mojo/mojo_shell_bindings.target.linux-mips.mk
+++ b/mojo/mojo_shell_bindings.target.linux-mips.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/mojo/mojo_shell_bindings.target.linux-x86.mk b/mojo/mojo_shell_bindings.target.linux-x86.mk
index 7a33300..ae85195 100644
--- a/mojo/mojo_shell_bindings.target.linux-x86.mk
+++ b/mojo/mojo_shell_bindings.target.linux-x86.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,7 +69,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +154,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_shell_bindings.target.linux-x86_64.mk b/mojo/mojo_shell_bindings.target.linux-x86_64.mk
index d5929ca..418bac4 100644
--- a/mojo/mojo_shell_bindings.target.linux-x86_64.mk
+++ b/mojo/mojo_shell_bindings.target.linux-x86_64.mk
@@ -15,8 +15,9 @@
 
 
 ### Generated for rule "mojo_mojo_gyp_mojo_shell_bindings_target_Generate_C___source_files_from_mojom_files":
-# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', '%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
+# "{'inputs': ['../mojo/public/tools/bindings/mojom_bindings_generator.py', '../mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/enum_traits.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_builder_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_destructor.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl', '../mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl', '../mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '../mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '../mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '../mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '../mojo/public/tools/bindings/generators/mojom_js_generator.py', '../mojo/public/tools/bindings/pylib/mojom/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/error.py', '../mojo/public/tools/bindings/pylib/mojom/generate/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/generate/data.py', '../mojo/public/tools/bindings/pylib/mojom/generate/generator.py', '../mojo/public/tools/bindings/pylib/mojom/generate/module.py', '../mojo/public/tools/bindings/pylib/mojom/generate/pack.py', '../mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py', '../mojo/public/tools/bindings/pylib/mojom/parse/__init__.py', '../mojo/public/tools/bindings/pylib/mojom/parse/ast.py', '../mojo/public/tools/bindings/pylib/mojom/parse/lexer.py', '../mojo/public/tools/bindings/pylib/mojom/parse/parser.py', '../mojo/public/tools/bindings/pylib/mojom/parse/translate.py'], 'process_outputs_as_sources': '1', 'extension': 'mojom', 'outputs': ['$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.cc', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.h', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom.js', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom-internal.h'], 'variables': {'mojom_bindings_generator': '../mojo/public/tools/bindings/mojom_bindings_generator.py'}, 'rule_name': 'Generate C++ source files from mojom files', 'rule_sources': ['public/interfaces/shell/shell.mojom'], 'action': ['python', '../mojo/public/tools/bindings/mojom_bindings_generator.py', './%(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom', '--use_chromium_bundled_pylibs', '-d', '..', '-o', '$(gyp_shared_intermediate_dir)/mojo/%(INPUT_DIRNAME)s'], 'message': 'Generating Mojo bindings from %(INPUT_DIRNAME)s/%(INPUT_ROOT)s.mojom'}":
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/mojo/public/interfaces/shell/shell.mojom.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -68,7 +69,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +154,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_system_impl.target.darwin-arm.mk b/mojo/mojo_system_impl.target.darwin-arm.mk
index cea7e95..b91205b 100644
--- a/mojo/mojo_system_impl.target.darwin-arm.mk
+++ b/mojo/mojo_system_impl.target.darwin-arm.mk
@@ -53,6 +53,7 @@
 	mojo/system/raw_shared_buffer_posix.cc \
 	mojo/system/shared_buffer_dispatcher.cc \
 	mojo/system/simple_dispatcher.cc \
+	mojo/system/transport_data.cc \
 	mojo/system/waiter.cc \
 	mojo/system/waiter_list.cc \
 	mojo/embedder/test_embedder.cc
@@ -72,7 +73,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -161,7 +161,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_system_impl.target.darwin-arm64.mk b/mojo/mojo_system_impl.target.darwin-arm64.mk
index 7fb16fb..8b865ee 100644
--- a/mojo/mojo_system_impl.target.darwin-arm64.mk
+++ b/mojo/mojo_system_impl.target.darwin-arm64.mk
@@ -53,6 +53,7 @@
 	mojo/system/raw_shared_buffer_posix.cc \
 	mojo/system/shared_buffer_dispatcher.cc \
 	mojo/system/simple_dispatcher.cc \
+	mojo/system/transport_data.cc \
 	mojo/system/waiter.cc \
 	mojo/system/waiter_list.cc \
 	mojo/embedder/test_embedder.cc
diff --git a/mojo/mojo_system_impl.target.darwin-mips.mk b/mojo/mojo_system_impl.target.darwin-mips.mk
index a1cb2a9..51d3ae1 100644
--- a/mojo/mojo_system_impl.target.darwin-mips.mk
+++ b/mojo/mojo_system_impl.target.darwin-mips.mk
@@ -53,6 +53,7 @@
 	mojo/system/raw_shared_buffer_posix.cc \
 	mojo/system/shared_buffer_dispatcher.cc \
 	mojo/system/simple_dispatcher.cc \
+	mojo/system/transport_data.cc \
 	mojo/system/waiter.cc \
 	mojo/system/waiter_list.cc \
 	mojo/embedder/test_embedder.cc
diff --git a/mojo/mojo_system_impl.target.darwin-x86.mk b/mojo/mojo_system_impl.target.darwin-x86.mk
index c78af2f..de78fea 100644
--- a/mojo/mojo_system_impl.target.darwin-x86.mk
+++ b/mojo/mojo_system_impl.target.darwin-x86.mk
@@ -53,6 +53,7 @@
 	mojo/system/raw_shared_buffer_posix.cc \
 	mojo/system/shared_buffer_dispatcher.cc \
 	mojo/system/simple_dispatcher.cc \
+	mojo/system/transport_data.cc \
 	mojo/system/waiter.cc \
 	mojo/system/waiter_list.cc \
 	mojo/embedder/test_embedder.cc
@@ -74,7 +75,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -163,7 +163,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_system_impl.target.darwin-x86_64.mk b/mojo/mojo_system_impl.target.darwin-x86_64.mk
index a9bc33b..77b93b9 100644
--- a/mojo/mojo_system_impl.target.darwin-x86_64.mk
+++ b/mojo/mojo_system_impl.target.darwin-x86_64.mk
@@ -53,6 +53,7 @@
 	mojo/system/raw_shared_buffer_posix.cc \
 	mojo/system/shared_buffer_dispatcher.cc \
 	mojo/system/simple_dispatcher.cc \
+	mojo/system/transport_data.cc \
 	mojo/system/waiter.cc \
 	mojo/system/waiter_list.cc \
 	mojo/embedder/test_embedder.cc
@@ -74,7 +75,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -163,7 +163,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_system_impl.target.linux-arm.mk b/mojo/mojo_system_impl.target.linux-arm.mk
index cea7e95..b91205b 100644
--- a/mojo/mojo_system_impl.target.linux-arm.mk
+++ b/mojo/mojo_system_impl.target.linux-arm.mk
@@ -53,6 +53,7 @@
 	mojo/system/raw_shared_buffer_posix.cc \
 	mojo/system/shared_buffer_dispatcher.cc \
 	mojo/system/simple_dispatcher.cc \
+	mojo/system/transport_data.cc \
 	mojo/system/waiter.cc \
 	mojo/system/waiter_list.cc \
 	mojo/embedder/test_embedder.cc
@@ -72,7 +73,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -161,7 +161,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/mojo/mojo_system_impl.target.linux-arm64.mk b/mojo/mojo_system_impl.target.linux-arm64.mk
index 7fb16fb..8b865ee 100644
--- a/mojo/mojo_system_impl.target.linux-arm64.mk
+++ b/mojo/mojo_system_impl.target.linux-arm64.mk
@@ -53,6 +53,7 @@
 	mojo/system/raw_shared_buffer_posix.cc \
 	mojo/system/shared_buffer_dispatcher.cc \
 	mojo/system/simple_dispatcher.cc \
+	mojo/system/transport_data.cc \
 	mojo/system/waiter.cc \
 	mojo/system/waiter_list.cc \
 	mojo/embedder/test_embedder.cc
diff --git a/mojo/mojo_system_impl.target.linux-mips.mk b/mojo/mojo_system_impl.target.linux-mips.mk
index a1cb2a9..51d3ae1 100644
--- a/mojo/mojo_system_impl.target.linux-mips.mk
+++ b/mojo/mojo_system_impl.target.linux-mips.mk
@@ -53,6 +53,7 @@
 	mojo/system/raw_shared_buffer_posix.cc \
 	mojo/system/shared_buffer_dispatcher.cc \
 	mojo/system/simple_dispatcher.cc \
+	mojo/system/transport_data.cc \
 	mojo/system/waiter.cc \
 	mojo/system/waiter_list.cc \
 	mojo/embedder/test_embedder.cc
diff --git a/mojo/mojo_system_impl.target.linux-x86.mk b/mojo/mojo_system_impl.target.linux-x86.mk
index c78af2f..de78fea 100644
--- a/mojo/mojo_system_impl.target.linux-x86.mk
+++ b/mojo/mojo_system_impl.target.linux-x86.mk
@@ -53,6 +53,7 @@
 	mojo/system/raw_shared_buffer_posix.cc \
 	mojo/system/shared_buffer_dispatcher.cc \
 	mojo/system/simple_dispatcher.cc \
+	mojo/system/transport_data.cc \
 	mojo/system/waiter.cc \
 	mojo/system/waiter_list.cc \
 	mojo/embedder/test_embedder.cc
@@ -74,7 +75,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -163,7 +163,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/mojo_system_impl.target.linux-x86_64.mk b/mojo/mojo_system_impl.target.linux-x86_64.mk
index a9bc33b..77b93b9 100644
--- a/mojo/mojo_system_impl.target.linux-x86_64.mk
+++ b/mojo/mojo_system_impl.target.linux-x86_64.mk
@@ -53,6 +53,7 @@
 	mojo/system/raw_shared_buffer_posix.cc \
 	mojo/system/shared_buffer_dispatcher.cc \
 	mojo/system/simple_dispatcher.cc \
+	mojo/system/transport_data.cc \
 	mojo/system/waiter.cc \
 	mojo/system/waiter_list.cc \
 	mojo/embedder/test_embedder.cc
@@ -74,7 +75,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -163,7 +163,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/mojo/public/c/gles2/gles2_call_visitor_autogen.h b/mojo/public/c/gles2/gles2_call_visitor_autogen.h
index 64adecf..72494c5 100644
--- a/mojo/public/c/gles2/gles2_call_visitor_autogen.h
+++ b/mojo/public/c/gles2/gles2_call_visitor_autogen.h
@@ -177,25 +177,25 @@
                GLint level),
               (target, attachment, textarget, texture, level))
 VISIT_GL_CALL(FrontFace, void, (GLenum mode), (mode))
-VISIT_GL_CALL(GenBuffers, void, (GLsizei n, GLuint* buffers), (n, buffers))
+VISIT_GL_CALL(GenBuffers, void, (GLsizei n, GLuint * buffers), (n, buffers))
 VISIT_GL_CALL(GenerateMipmap, void, (GLenum target), (target))
 VISIT_GL_CALL(GenFramebuffers,
               void,
-              (GLsizei n, GLuint* framebuffers),
+              (GLsizei n, GLuint * framebuffers),
               (n, framebuffers))
 VISIT_GL_CALL(GenRenderbuffers,
               void,
-              (GLsizei n, GLuint* renderbuffers),
+              (GLsizei n, GLuint * renderbuffers),
               (n, renderbuffers))
-VISIT_GL_CALL(GenTextures, void, (GLsizei n, GLuint* textures), (n, textures))
+VISIT_GL_CALL(GenTextures, void, (GLsizei n, GLuint * textures), (n, textures))
 VISIT_GL_CALL(GetActiveAttrib,
               void,
               (GLuint program,
                GLuint index,
                GLsizei bufsize,
-               GLsizei* length,
-               GLint* size,
-               GLenum* type,
+               GLsizei * length,
+               GLint * size,
+               GLenum * type,
                char* name),
               (program, index, bufsize, length, size, type, name))
 VISIT_GL_CALL(GetActiveUniform,
@@ -203,15 +203,15 @@
               (GLuint program,
                GLuint index,
                GLsizei bufsize,
-               GLsizei* length,
-               GLint* size,
-               GLenum* type,
+               GLsizei * length,
+               GLint * size,
+               GLenum * type,
                char* name),
               (program, index, bufsize, length, size, type, name))
 VISIT_GL_CALL(
     GetAttachedShaders,
     void,
-    (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders),
+    (GLuint program, GLsizei maxcount, GLsizei * count, GLuint * shaders),
     (program, maxcount, count, shaders))
 VISIT_GL_CALL(GetAttribLocation,
               GLint,
@@ -219,64 +219,71 @@
               (program, name))
 VISIT_GL_CALL(GetBooleanv,
               void,
-              (GLenum pname, GLboolean* params),
+              (GLenum pname, GLboolean * params),
               (pname, params))
 VISIT_GL_CALL(GetBufferParameteriv,
               void,
-              (GLenum target, GLenum pname, GLint* params),
+              (GLenum target, GLenum pname, GLint * params),
               (target, pname, params))
 VISIT_GL_CALL(GetError, GLenum, (), ())
-VISIT_GL_CALL(GetFloatv, void, (GLenum pname, GLfloat* params), (pname, params))
+VISIT_GL_CALL(GetFloatv,
+              void,
+              (GLenum pname, GLfloat * params),
+              (pname, params))
 VISIT_GL_CALL(GetFramebufferAttachmentParameteriv,
               void,
-              (GLenum target, GLenum attachment, GLenum pname, GLint* params),
+              (GLenum target, GLenum attachment, GLenum pname, GLint * params),
               (target, attachment, pname, params))
-VISIT_GL_CALL(GetIntegerv, void, (GLenum pname, GLint* params), (pname, params))
+VISIT_GL_CALL(GetIntegerv,
+              void,
+              (GLenum pname, GLint * params),
+              (pname, params))
 VISIT_GL_CALL(GetProgramiv,
               void,
-              (GLuint program, GLenum pname, GLint* params),
+              (GLuint program, GLenum pname, GLint * params),
               (program, pname, params))
-VISIT_GL_CALL(GetProgramInfoLog,
-              void,
-              (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog),
-              (program, bufsize, length, infolog))
+VISIT_GL_CALL(
+    GetProgramInfoLog,
+    void,
+    (GLuint program, GLsizei bufsize, GLsizei * length, char* infolog),
+    (program, bufsize, length, infolog))
 VISIT_GL_CALL(GetRenderbufferParameteriv,
               void,
-              (GLenum target, GLenum pname, GLint* params),
+              (GLenum target, GLenum pname, GLint * params),
               (target, pname, params))
 VISIT_GL_CALL(GetShaderiv,
               void,
-              (GLuint shader, GLenum pname, GLint* params),
+              (GLuint shader, GLenum pname, GLint * params),
               (shader, pname, params))
 VISIT_GL_CALL(GetShaderInfoLog,
               void,
-              (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog),
+              (GLuint shader, GLsizei bufsize, GLsizei * length, char* infolog),
               (shader, bufsize, length, infolog))
 VISIT_GL_CALL(
     GetShaderPrecisionFormat,
     void,
-    (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision),
+    (GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision),
     (shadertype, precisiontype, range, precision))
 VISIT_GL_CALL(GetShaderSource,
               void,
-              (GLuint shader, GLsizei bufsize, GLsizei* length, char* source),
+              (GLuint shader, GLsizei bufsize, GLsizei * length, char* source),
               (shader, bufsize, length, source))
 VISIT_GL_CALL(GetString, const GLubyte*, (GLenum name), (name))
 VISIT_GL_CALL(GetTexParameterfv,
               void,
-              (GLenum target, GLenum pname, GLfloat* params),
+              (GLenum target, GLenum pname, GLfloat * params),
               (target, pname, params))
 VISIT_GL_CALL(GetTexParameteriv,
               void,
-              (GLenum target, GLenum pname, GLint* params),
+              (GLenum target, GLenum pname, GLint * params),
               (target, pname, params))
 VISIT_GL_CALL(GetUniformfv,
               void,
-              (GLuint program, GLint location, GLfloat* params),
+              (GLuint program, GLint location, GLfloat * params),
               (program, location, params))
 VISIT_GL_CALL(GetUniformiv,
               void,
-              (GLuint program, GLint location, GLint* params),
+              (GLuint program, GLint location, GLint * params),
               (program, location, params))
 VISIT_GL_CALL(GetUniformLocation,
               GLint,
@@ -284,11 +291,11 @@
               (program, name))
 VISIT_GL_CALL(GetVertexAttribfv,
               void,
-              (GLuint index, GLenum pname, GLfloat* params),
+              (GLuint index, GLenum pname, GLfloat * params),
               (index, pname, params))
 VISIT_GL_CALL(GetVertexAttribiv,
               void,
-              (GLuint index, GLenum pname, GLint* params),
+              (GLuint index, GLenum pname, GLint * params),
               (index, pname, params))
 VISIT_GL_CALL(GetVertexAttribPointerv,
               void,
diff --git a/mojo/public/c/system/macros.h b/mojo/public/c/system/macros.h
index 4be0249..322c3be 100644
--- a/mojo/public/c/system/macros.h
+++ b/mojo/public/c/system/macros.h
@@ -27,8 +27,10 @@
 #endif
 
 // This macro is currently C++-only, but we want to use it in the C core.h.
-#ifdef __cplusplus
 // Used to assert things at compile time.
+#if __cplusplus >= 201103L
+#define MOJO_COMPILE_ASSERT(expr, msg) static_assert(expr, #msg)
+#elif defined(__cplusplus)
 namespace mojo { template <bool> struct CompileAssert {}; }
 #define MOJO_COMPILE_ASSERT(expr, msg) \
     typedef ::mojo::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
diff --git a/mojo/public/c/test_support/test_support.h b/mojo/public/c/test_support/test_support.h
index f854647..2b686b2 100644
--- a/mojo/public/c/test_support/test_support.h
+++ b/mojo/public/c/test_support/test_support.h
@@ -7,6 +7,8 @@
 
 // Note: This header should be compilable as C.
 
+#include <stdio.h>
+
 #include "mojo/public/c/test_support/test_support_export.h"
 
 #ifdef __cplusplus
@@ -18,6 +20,27 @@
     double value,
     const char* units);
 
+// Opens a "/"-delimited file path relative to the source root.
+MOJO_TEST_SUPPORT_EXPORT FILE* MojoTestSupportOpenSourceRootRelativeFile(
+    const char* source_root_relative_path);
+
+// Enumerates a "/"-delimited directory path relative to the source root.
+// Returns only regular files. The return value is a heap-allocated array of
+// heap-allocated strings. Each must be free'd separately.
+//
+// The return value is built like so:
+//
+//   char** rv = (char**) calloc(N + 1, sizeof(char*));
+//   rv[0] = strdup("a");
+//   rv[1] = strdup("b");
+//   rv[2] = strdup("c");
+//   ...
+//   rv[N] = NULL;
+//
+MOJO_TEST_SUPPORT_EXPORT
+char** MojoTestSupportEnumerateSourceRootRelativeDirectory(
+    const char* source_root_relative_path);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/mojo/public/cpp/bindings/lib/bindings_serialization.cc b/mojo/public/cpp/bindings/lib/bindings_serialization.cc
index fc574d7..5e60c65 100644
--- a/mojo/public/cpp/bindings/lib/bindings_serialization.cc
+++ b/mojo/public/cpp/bindings/lib/bindings_serialization.cc
@@ -11,9 +11,22 @@
 namespace mojo {
 namespace internal {
 
-size_t Align(size_t size) {
+namespace {
+
+template<typename T>
+T AlignImpl(T t) {
   const size_t kAlignment = 8;
-  return size + (kAlignment - (size % kAlignment)) % kAlignment;
+  return t + (kAlignment - (t % kAlignment)) % kAlignment;
+}
+
+}  // namespace
+
+size_t Align(size_t size) {
+  return AlignImpl(size);
+}
+
+char* AlignPointer(char* ptr) {
+  return reinterpret_cast<char*>(AlignImpl(reinterpret_cast<uintptr_t>(ptr)));
 }
 
 void EncodePointer(const void* ptr, uint64_t* offset) {
diff --git a/mojo/public/cpp/bindings/lib/bindings_serialization.h b/mojo/public/cpp/bindings/lib/bindings_serialization.h
index a860b14..818d693 100644
--- a/mojo/public/cpp/bindings/lib/bindings_serialization.h
+++ b/mojo/public/cpp/bindings/lib/bindings_serialization.h
@@ -14,6 +14,7 @@
 namespace internal {
 
 size_t Align(size_t size);
+char* AlignPointer(char* ptr);
 
 // Pointers are encoded as relative offsets. The offsets are relative to the
 // address of where the offset value is stored, such that the pointer may be
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc
index 319631c..aa6c45e 100644
--- a/mojo/public/cpp/bindings/lib/connector.cc
+++ b/mojo/public/cpp/bindings/lib/connector.cc
@@ -22,7 +22,8 @@
       incoming_receiver_(NULL),
       async_wait_id_(0),
       error_(false),
-      drop_writes_(false) {
+      drop_writes_(false),
+      enforce_errors_from_incoming_receiver_(true) {
   // Even though we don't have an incoming receiver, we still want to monitor
   // the message pipe to know if is closed or encounters an error.
   WaitToReadMore();
@@ -112,14 +113,15 @@
 
 void Connector::ReadMore() {
   while (true) {
-    MojoResult rv;
-
-    rv = ReadAndDispatchMessage(message_pipe_.get(), incoming_receiver_, NULL);
+    bool receiver_result = false;
+    MojoResult rv =  ReadAndDispatchMessage(
+        message_pipe_.get(), incoming_receiver_, &receiver_result);
     if (rv == MOJO_RESULT_SHOULD_WAIT) {
       WaitToReadMore();
       break;
     }
-    if (rv != MOJO_RESULT_OK) {
+    if (rv != MOJO_RESULT_OK ||
+        (enforce_errors_from_incoming_receiver_ && !receiver_result)) {
       error_ = true;
       break;
     }
diff --git a/mojo/public/cpp/bindings/lib/connector.h b/mojo/public/cpp/bindings/lib/connector.h
index 21107d5..f32a170 100644
--- a/mojo/public/cpp/bindings/lib/connector.h
+++ b/mojo/public/cpp/bindings/lib/connector.h
@@ -36,6 +36,13 @@
     incoming_receiver_ = receiver;
   }
 
+  // Errors from incoming receivers will force the connector into an error
+  // state, where no more messages will be processed. This method is used
+  // during testing to prevent that from happening.
+  void set_enforce_errors_from_incoming_receiver(bool enforce) {
+    enforce_errors_from_incoming_receiver_ = enforce;
+  }
+
   // Sets the error handler to receive notifications when an error is
   // encountered while reading from the pipe or waiting to read from the pipe.
   void set_error_handler(ErrorHandler* error_handler) {
@@ -70,6 +77,7 @@
   MojoAsyncWaitID async_wait_id_;
   bool error_;
   bool drop_writes_;
+  bool enforce_errors_from_incoming_receiver_;
 
   MOJO_DISALLOW_COPY_AND_ASSIGN(Connector);
 };
diff --git a/mojo/public/cpp/bindings/lib/message.cc b/mojo/public/cpp/bindings/lib/message.cc
index 8ec188e..1db071f 100644
--- a/mojo/public/cpp/bindings/lib/message.cc
+++ b/mojo/public/cpp/bindings/lib/message.cc
@@ -9,6 +9,8 @@
 
 #include <algorithm>
 
+#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
+
 namespace mojo {
 
 Message::Message()
@@ -73,9 +75,8 @@
                       &num_handles,
                       MOJO_READ_MESSAGE_FLAG_NONE);
   if (receiver && rv == MOJO_RESULT_OK) {
-    bool result = receiver->Accept(&message);
-    if (receiver_result)
-      *receiver_result = result;
+    *receiver_result =
+        internal::MessageHeaderValidator(receiver).Accept(&message);
   }
 
   return rv;
diff --git a/mojo/public/cpp/bindings/lib/message_header_validator.cc b/mojo/public/cpp/bindings/lib/message_header_validator.cc
new file mode 100644
index 0000000..a5151cf
--- /dev/null
+++ b/mojo/public/cpp/bindings/lib/message_header_validator.cc
@@ -0,0 +1,82 @@
+// 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.
+
+#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
+
+#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
+
+namespace mojo {
+namespace internal {
+namespace {
+
+bool IsValidMessageHeader(const internal::MessageHeader* header) {
+  // NOTE: Our goal is to preserve support for future extension of the message
+  // header. If we encounter fields we do not understand, we must ignore them.
+
+  // Validate num_bytes:
+
+  if (header->num_bytes < sizeof(internal::MessageHeader))
+    return false;
+  if (internal::Align(header->num_bytes) != header->num_bytes)
+    return false;
+
+  // Validate num_fields:
+
+  if (header->num_fields < 2)
+    return false;
+  if (header->num_fields == 2) {
+    if (header->num_bytes != sizeof(internal::MessageHeader))
+      return false;
+  } else if (header->num_fields == 3) {
+    if (header->num_bytes != sizeof(internal::MessageHeaderWithRequestID))
+      return false;
+  } else if (header->num_fields > 3) {
+    if (header->num_bytes < sizeof(internal::MessageHeaderWithRequestID))
+      return false;
+  }
+
+  // Validate flags (allow unknown bits):
+
+  // These flags require a RequestID.
+  if (header->num_fields < 3 &&
+        ((header->flags & internal::kMessageExpectsResponse) ||
+         (header->flags & internal::kMessageIsResponse)))
+    return false;
+
+  // These flags are mutually exclusive.
+  if ((header->flags & internal::kMessageExpectsResponse) &&
+      (header->flags & internal::kMessageIsResponse))
+    return false;
+
+  return true;
+}
+
+}  // namespace
+
+MessageHeaderValidator::MessageHeaderValidator(MessageReceiver* next)
+    : next_(next) {
+  assert(next);
+}
+
+bool MessageHeaderValidator::Accept(Message* message) {
+  // Make sure the message header isn't truncated before we start to read it.
+  if (message->data_num_bytes() < sizeof(internal::MessageHeader) ||
+      message->data_num_bytes() < message->header()->num_bytes) {
+    return false;
+  }
+
+  if (!IsValidMessageHeader(message->header()))
+    return false;
+
+  return next_->Accept(message);
+}
+
+bool MessageHeaderValidator::AcceptWithResponder(Message* message,
+                                                 MessageReceiver* responder) {
+  assert(false);  // Not reached!
+  return false;
+}
+
+}  // namespace internal
+}  // namespace mojo
diff --git a/mojo/public/cpp/bindings/lib/message_header_validator.h b/mojo/public/cpp/bindings/lib/message_header_validator.h
new file mode 100644
index 0000000..d7877fb
--- /dev/null
+++ b/mojo/public/cpp/bindings/lib/message_header_validator.h
@@ -0,0 +1,23 @@
+// 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.
+
+#include "mojo/public/cpp/bindings/message.h"
+
+namespace mojo {
+namespace internal {
+
+class MessageHeaderValidator : public MessageReceiver {
+ public:
+  explicit MessageHeaderValidator(MessageReceiver* next);
+
+  virtual bool Accept(Message* message) MOJO_OVERRIDE;
+  virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder)
+      MOJO_OVERRIDE;
+
+ private:
+  MessageReceiver* next_;
+};
+
+}  // namespace internal
+}  // namespace mojo
diff --git a/mojo/public/cpp/bindings/lib/router.cc b/mojo/public/cpp/bindings/lib/router.cc
index 31676bd..ec68bba 100644
--- a/mojo/public/cpp/bindings/lib/router.cc
+++ b/mojo/public/cpp/bindings/lib/router.cc
@@ -125,8 +125,9 @@
     }
     MessageReceiver* responder = it->second;
     responders_.erase(it);
-    responder->Accept(message);
+    bool ok = responder->Accept(message);
     delete responder;
+    return ok;
   } else {
     if (incoming_receiver_)
       return incoming_receiver_->Accept(message);
diff --git a/mojo/public/cpp/bindings/lib/router.h b/mojo/public/cpp/bindings/lib/router.h
index 31c05f6..08c184e 100644
--- a/mojo/public/cpp/bindings/lib/router.h
+++ b/mojo/public/cpp/bindings/lib/router.h
@@ -32,6 +32,13 @@
     connector_.set_error_handler(error_handler);
   }
 
+  // Errors from incoming receivers will force the router's connector into an
+  // error state, where no more messages will be processed. This method is used
+  // during testing to prevent that from happening.
+  void set_enforce_errors_from_incoming_receiver(bool enforce) {
+    connector_.set_enforce_errors_from_incoming_receiver(enforce);
+  }
+
   // Returns true if an error was encountered while reading from the pipe or
   // waiting to read from the pipe.
   bool encountered_error() const { return connector_.encountered_error(); }
diff --git a/mojo/public/cpp/bindings/lib/scratch_buffer.cc b/mojo/public/cpp/bindings/lib/scratch_buffer.cc
index 9d23dcb..c7f507b 100644
--- a/mojo/public/cpp/bindings/lib/scratch_buffer.cc
+++ b/mojo/public/cpp/bindings/lib/scratch_buffer.cc
@@ -25,7 +25,7 @@
 ScratchBuffer::ScratchBuffer()
     : overflow_(NULL) {
   fixed_.next = NULL;
-  fixed_.cursor = fixed_data_;
+  fixed_.cursor = internal::AlignPointer(fixed_data_);
   fixed_.end = fixed_data_ + kMinSegmentSize;
 }
 
@@ -80,11 +80,12 @@
     return false;
 
   // Ensure segment buffer is aligned.
-  size_t segment_size = internal::Align(sizeof(Segment)) + delta;
-  Segment* segment = static_cast<Segment*>(malloc(segment_size));
+  size_t padded_segment_size = internal::Align(sizeof(Segment));
+  Segment* segment = static_cast<Segment*>(
+      malloc(padded_segment_size + delta));
   if (segment) {
     segment->next = overflow_;
-    segment->cursor = reinterpret_cast<char*>(segment + 1);
+    segment->cursor = reinterpret_cast<char*>(segment) + padded_segment_size;
     segment->end = segment->cursor + delta;
     overflow_ = segment;
     return true;
diff --git a/mojo/public/cpp/bindings/message.h b/mojo/public/cpp/bindings/message.h
index 58001c6..5653f05 100644
--- a/mojo/public/cpp/bindings/message.h
+++ b/mojo/public/cpp/bindings/message.h
@@ -83,7 +83,7 @@
   // The receiver may mutate the given message.  Returns true if the message
   // was accepted and false otherwise, indicating that the message was invalid
   // or malformed.
-  virtual bool Accept(Message* message) = 0;
+  virtual bool Accept(Message* message) MOJO_WARN_UNUSED_RESULT = 0;
 
   // A variant on Accept that registers a MessageReceiver (known as the
   // responder) to handle the response message generated from the given
@@ -94,8 +94,8 @@
   // |responder| and will delete it after calling |responder->Accept| or upon
   // its own destruction.
   //
-  virtual bool AcceptWithResponder(Message* message,
-                                   MessageReceiver* responder) = 0;
+  virtual bool AcceptWithResponder(
+      Message* message, MessageReceiver* responder) MOJO_WARN_UNUSED_RESULT = 0;
 };
 
 // Read a single message from the pipe and dispatch to the given receiver.  The
diff --git a/mojo/public/cpp/bindings/remote_ptr.h b/mojo/public/cpp/bindings/remote_ptr.h
index 63ee719..e1b9a5b 100644
--- a/mojo/public/cpp/bindings/remote_ptr.h
+++ b/mojo/public/cpp/bindings/remote_ptr.h
@@ -86,6 +86,7 @@
   // Move-only constructor and operator=.
   RemotePtr(RValue other) : state_(other.object->release()) {}
   RemotePtr& operator=(RValue other) {
+    delete state_;
     state_ = other.object->release();
     return *this;
   }
@@ -126,6 +127,10 @@
     return state_->router.encountered_error();
   }
 
+  internal::Router* router_for_testing() {
+    return &state_->router;
+  }
+
  private:
   struct State {
     State(ScopedMessagePipeHandle message_pipe, typename S::_Peer* peer,
diff --git a/mojo/public/cpp/bindings/tests/buffer_unittest.cc b/mojo/public/cpp/bindings/tests/buffer_unittest.cc
index 7ef7520..e96b406 100644
--- a/mojo/public/cpp/bindings/tests/buffer_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/buffer_unittest.cc
@@ -53,6 +53,23 @@
   EXPECT_TRUE(!overflow);
 }
 
+TEST(ScratchBufferTest, Alignment) {
+  Environment env;
+
+  internal::ScratchBuffer buf;
+  // Test that small allocations on the stack are aligned properly.
+  void* small = buf.Allocate(1);
+  EXPECT_EQ(0, reinterpret_cast<ptrdiff_t>(small) % 8);
+  small = buf.Allocate(2);
+  EXPECT_EQ(0, reinterpret_cast<ptrdiff_t>(small) % 8);
+
+  // Test that large allocations on the heap are aligned properly.
+  void* large = buf.Allocate(10*1024);
+  EXPECT_EQ(0, reinterpret_cast<ptrdiff_t>(large) % 8);
+  large = buf.Allocate(100*1024);
+  EXPECT_EQ(0, reinterpret_cast<ptrdiff_t>(large) % 8);
+}
+
 // Tests that Buffer::current() returns the correct value.
 TEST(ScratchBufferTest, Stacked) {
   Environment env;
@@ -104,7 +121,7 @@
 
     ptr = buf.Allocate(8);
     ASSERT_TRUE(ptr);
-    void* buf_ptr = buf.Leak();
+    buf_ptr = buf.Leak();
 
     // The buffer should point to the first element allocated.
     // TODO(mpcomplete): Is this a reasonable expectation?
diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc
new file mode 100644
index 0000000..e3504db
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/validation_unittest.cc
@@ -0,0 +1,134 @@
+// 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.
+
+#include <stdio.h>
+
+#include <algorithm>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
+#include "mojo/public/cpp/test_support/test_support.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace test {
+namespace {
+
+std::vector<std::string> GetMatchingTests(const std::vector<std::string>& names,
+                                          const std::string& prefix) {
+  const std::string suffix = ".data";
+  std::vector<std::string> tests;
+  for (size_t i = 0; i < names.size(); ++i) {
+    if (names[i].size() >= suffix.size() &&
+        names[i].substr(0, prefix.size()) == prefix &&
+        names[i].substr(names[i].size() - suffix.size()) == suffix)
+      tests.push_back(names[i].substr(0, names[i].size() - suffix.size()));
+  }
+  return tests;
+}
+
+bool ReadDataFile(const std::string& path, std::vector<uint8_t>* result) {
+  FILE* fp = OpenSourceRootRelativeFile(path.c_str());
+  if (!fp) {
+    ADD_FAILURE() << "File not found: " << path;
+    return false;
+  }
+  for (;;) {
+    unsigned int value;
+    int rv = fscanf(fp, "%x", &value);
+    if (rv != 1)
+      break;
+    result->push_back(static_cast<uint8_t>(value & 0xFF));
+  }
+  bool error = ferror(fp);
+  fclose(fp);
+  return !error;
+}
+
+bool ReadResultFile(const std::string& path, std::string* result) {
+  FILE* fp = OpenSourceRootRelativeFile(path.c_str());
+  if (!fp)
+    return false;
+  fseek(fp, 0, SEEK_END);
+  size_t size = static_cast<size_t>(ftell(fp));
+  if (size == 0) {
+    // Result files should never be empty.
+    fclose(fp);
+    return false;
+  }
+  fseek(fp, 0, SEEK_SET);
+  result->resize(size);
+  size_t size_read = fread(&result->at(0), 1, size, fp);
+  fclose(fp);
+  if (size != size_read)
+    return false;
+  // Result files are new-line delimited text files. Remove any CRs.
+  result->erase(std::remove(result->begin(), result->end(), '\r'),
+                result->end());
+  return true;
+}
+
+std::string GetPath(const std::string& root, const std::string& suffix) {
+  return "mojo/public/interfaces/bindings/tests/data/" + root + suffix;
+}
+
+void RunValidationTest(const std::string& root, std::string (*func)(Message*)) {
+  std::vector<uint8_t> data;
+  ASSERT_TRUE(ReadDataFile(GetPath(root, ".data"), &data));
+
+  std::string expected;
+  ASSERT_TRUE(ReadResultFile(GetPath(root, ".expected"), &expected));
+
+  Message message;
+  message.AllocUninitializedData(static_cast<uint32_t>(data.size()));
+  if (!data.empty())
+    memcpy(message.mutable_data(), &data[0], data.size());
+
+  std::string result = func(&message);
+  EXPECT_EQ(expected, result) << "failed test: " << root;
+}
+
+class DummyMessageReceiver : public MessageReceiver {
+ public:
+  virtual bool Accept(Message* message) MOJO_OVERRIDE {
+    return true;  // Any message is OK.
+  }
+  virtual bool AcceptWithResponder(Message* message,
+                                   MessageReceiver* responder) MOJO_OVERRIDE {
+    assert(false);
+    return false;
+  }
+};
+
+std::string DumpMessageHeader(Message* message) {
+  DummyMessageReceiver not_reached_receiver;
+  internal::MessageHeaderValidator validator(&not_reached_receiver);
+  bool rv = validator.Accept(message);
+  if (!rv)
+    return "ERROR\n";
+
+  std::ostringstream os;
+  os << "num_bytes: " << message->header()->num_bytes << "\n"
+     << "num_fields: " << message->header()->num_fields << "\n"
+     << "name: " << message->header()->name << "\n"
+     << "flags: " << message->header()->flags << "\n";
+  return os.str();
+}
+
+TEST(ValidationTest, TestAll) {
+  std::vector<std::string> names =
+      EnumerateSourceRootRelativeDirectory(GetPath("", ""));
+
+  std::vector<std::string> header_tests =
+      GetMatchingTests(names, "validate_header_");
+
+  for (size_t i = 0; i < header_tests.size(); ++i)
+    RunValidationTest(header_tests[i], &DumpMessageHeader);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace mojo
diff --git a/mojo/public/cpp/test_support/lib/test_support.cc b/mojo/public/cpp/test_support/lib/test_support.cc
new file mode 100644
index 0000000..55a3dcc
--- /dev/null
+++ b/mojo/public/cpp/test_support/lib/test_support.cc
@@ -0,0 +1,26 @@
+// 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.
+
+#include "mojo/public/cpp/test_support/test_support.h"
+
+#include <stdlib.h>
+
+namespace mojo {
+namespace test {
+
+std::vector<std::string> EnumerateSourceRootRelativeDirectory(
+    const std::string& relative_path) {
+  char** names = MojoTestSupportEnumerateSourceRootRelativeDirectory(
+      relative_path.c_str());
+  std::vector<std::string> results;
+  for (char** ptr = names; *ptr != NULL; ++ptr) {
+    results.push_back(*ptr);
+    free(*ptr);
+  }
+  free(names);
+  return results;
+}
+
+}  // namespace test
+}  // namespace mojo
diff --git a/mojo/public/cpp/test_support/test_support.h b/mojo/public/cpp/test_support/test_support.h
index d0a8eb8..eb4d4be 100644
--- a/mojo/public/cpp/test_support/test_support.h
+++ b/mojo/public/cpp/test_support/test_support.h
@@ -5,6 +5,9 @@
 #ifndef MOJO_PUBLIC_CPP_TEST_SUPPORT_TEST_SUPPORT_H_
 #define MOJO_PUBLIC_CPP_TEST_SUPPORT_TEST_SUPPORT_H_
 
+#include <string>
+#include <vector>
+
 #include "mojo/public/c/test_support/test_support.h"
 
 namespace mojo {
@@ -16,6 +19,15 @@
   MojoTestSupportLogPerfResult(test_name, value, units);
 }
 
+// Opens text file relative to the source root for reading.
+inline FILE* OpenSourceRootRelativeFile(const std::string& relative_path) {
+  return MojoTestSupportOpenSourceRootRelativeFile(relative_path.c_str());
+}
+
+// Returns the list of regular files in a directory relative to the source root.
+std::vector<std::string> EnumerateSourceRootRelativeDirectory(
+    const std::string& relative_path);
+
 }  // namespace test
 }  // namespace mojo
 
diff --git a/chrome/browser/resources/web_dev_style/__init__.py b/mojo/public/interfaces/bindings/tests/data/validate_header_bad_empty.data
similarity index 100%
copy from chrome/browser/resources/web_dev_style/__init__.py
copy to mojo/public/interfaces/bindings/tests/data/validate_header_bad_empty.data
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_empty.expected b/mojo/public/interfaces/bindings/tests/data/validate_header_bad_empty.expected
new file mode 100644
index 0000000..5df7507
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validate_header_bad_empty.expected
@@ -0,0 +1 @@
+ERROR
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.data b/mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.data
new file mode 100644
index 0000000..21e7fbc
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.data
@@ -0,0 +1 @@
+0x00
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.expected b/mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.expected
new file mode 100644
index 0000000..5df7507
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.expected
@@ -0,0 +1 @@
+ERROR
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.data b/mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.data
new file mode 100644
index 0000000..f2ee827
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.data
@@ -0,0 +1,4 @@
+0x00 0x00 0x00 0x00
+0x00 0x00 0x00 0x00
+0x00 0x00 0x00 0x00
+0x00 0x00 0x00 0x00
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.expected b/mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.expected
new file mode 100644
index 0000000..5df7507
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.expected
@@ -0,0 +1 @@
+ERROR
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.data b/mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.data
new file mode 100644
index 0000000..c37c569
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.data
@@ -0,0 +1,4 @@
+0x10 0x00 0x00 0x00
+0x02 0x00 0x00 0x00
+0x00 0x00 0x00 0x00
+0x00 0x00 0x00 0x00
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.expected b/mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.expected
new file mode 100644
index 0000000..c29d2ad
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.expected
@@ -0,0 +1,4 @@
+num_bytes: 16
+num_fields: 2
+name: 0
+flags: 0
diff --git a/mojo/public/interfaces/bindings/tests/math_calculator.mojom b/mojo/public/interfaces/bindings/tests/math_calculator.mojom
index b38a8e2..e4a1c94 100644
--- a/mojo/public/interfaces/bindings/tests/math_calculator.mojom
+++ b/mojo/public/interfaces/bindings/tests/math_calculator.mojom
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+[JavaPackage="org.chromium.mojo.bindings.test"]
 module math {
 
 [Peer=CalculatorUI]
diff --git a/mojo/public/interfaces/bindings/tests/sample_factory.mojom b/mojo/public/interfaces/bindings/tests/sample_factory.mojom
index 00ab1ef..bad466f 100644
--- a/mojo/public/interfaces/bindings/tests/sample_factory.mojom
+++ b/mojo/public/interfaces/bindings/tests/sample_factory.mojom
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+[JavaPackage="org.chromium.mojo.bindings.test"]
 module sample {
 
 // This sample shows how handles to MessagePipes can be sent as both parameters
diff --git a/mojo/public/interfaces/bindings/tests/sample_import.mojom b/mojo/public/interfaces/bindings/tests/sample_import.mojom
index d68c5bf..61f7b9c 100644
--- a/mojo/public/interfaces/bindings/tests/sample_import.mojom
+++ b/mojo/public/interfaces/bindings/tests/sample_import.mojom
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+[JavaPackage="org.chromium.mojo.bindings.test"]
 module imported {
 
 // This sample just defines some types that are imported into
diff --git a/mojo/public/interfaces/bindings/tests/sample_import2.mojom b/mojo/public/interfaces/bindings/tests/sample_import2.mojom
index e5fd72d..1c5ec39 100644
--- a/mojo/public/interfaces/bindings/tests/sample_import2.mojom
+++ b/mojo/public/interfaces/bindings/tests/sample_import2.mojom
@@ -4,6 +4,7 @@
 
 import "sample_import.mojom"
 
+[JavaPackage="org.chromium.mojo.bindings.test"]
 module imported {
 
 // This sample adds more types and constants to the "imported" namespace,
diff --git a/mojo/public/interfaces/bindings/tests/sample_interfaces.mojom b/mojo/public/interfaces/bindings/tests/sample_interfaces.mojom
index 7c20b30..462e3cd 100644
--- a/mojo/public/interfaces/bindings/tests/sample_interfaces.mojom
+++ b/mojo/public/interfaces/bindings/tests/sample_interfaces.mojom
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+[JavaPackage="org.chromium.mojo.bindings.test",
+ Foo = "hello world"]
 module sample {
 
 enum Enum {
diff --git a/mojo/public/interfaces/bindings/tests/sample_service.mojom b/mojo/public/interfaces/bindings/tests/sample_service.mojom
index 04893a4..0336998 100644
--- a/mojo/public/interfaces/bindings/tests/sample_service.mojom
+++ b/mojo/public/interfaces/bindings/tests/sample_service.mojom
@@ -5,6 +5,7 @@
 import "sample_import.mojom"
 import "sample_import2.mojom"
 
+[JavaPackage="org.chromium.mojo.bindings.test"]
 module sample {
 
 struct Bar {
diff --git a/mojo/public/interfaces/bindings/tests/test_structs.mojom b/mojo/public/interfaces/bindings/tests/test_structs.mojom
index c205e84..168771e 100644
--- a/mojo/public/interfaces/bindings/tests/test_structs.mojom
+++ b/mojo/public/interfaces/bindings/tests/test_structs.mojom
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+[JavaPackage="org.chromium.mojo.bindings.test"]
 module test_structs {
 
 struct Rect {
diff --git a/mojo/public/java/src/org/chromium/mojo/system/SharedBufferHandle.java b/mojo/public/java/src/org/chromium/mojo/system/SharedBufferHandle.java
index 908db9e..89ae0d3 100644
--- a/mojo/public/java/src/org/chromium/mojo/system/SharedBufferHandle.java
+++ b/mojo/public/java/src/org/chromium/mojo/system/SharedBufferHandle.java
@@ -91,7 +91,7 @@
     }
 
     /**
-     * TODO(qsr): Insert description here.
+     * Flags for the shared buffer map operation.
      */
     public static class MapFlags extends Flags<MapFlags> {
         private static final int FLAG_NONE = 0;
diff --git a/mojo/public/java/src/org/chromium/mojo/system/UntypedHandle.java b/mojo/public/java/src/org/chromium/mojo/system/UntypedHandle.java
index 63b5f7c..4e9990f 100644
--- a/mojo/public/java/src/org/chromium/mojo/system/UntypedHandle.java
+++ b/mojo/public/java/src/org/chromium/mojo/system/UntypedHandle.java
@@ -4,37 +4,35 @@
 
 package org.chromium.mojo.system;
 
+import org.chromium.mojo.system.DataPipe.ConsumerHandle;
+import org.chromium.mojo.system.DataPipe.ProducerHandle;
 
 /**
- * TODO(qsr): Insert description here.
+ * A mojo handle of unknown type. This handle can be typed by using one of its methods, which will
+ * return a handle of the requested type and invalidate this object. No validation is made when the
+ * conversion operation is called.
  */
 public interface UntypedHandle extends Handle {
 
     /**
-     * TODO(qsr):
-     *
-     * @return TODO(qsr)
+     * Returns the underlying handle, as a {@link MessagePipeHandle}, invalidating this
+     * representation.
      */
     public MessagePipeHandle toMessagePipeHandle();
 
     /**
-     * TODO(qsr):
-     *
-     * @return TODO(qsr)
+     * Returns the underlying handle, as a {@link ConsumerHandle}, invalidating this representation.
      */
-    public DataPipe.ConsumerHandle toDataPipeConsumerHandle();
+    public ConsumerHandle toDataPipeConsumerHandle();
 
     /**
-     * TODO(qsr):
-     *
-     * @return TODO(qsr)
+     * Returns the underlying handle, as a {@link ProducerHandle}, invalidating this representation.
      */
-    public DataPipe.ProducerHandle toDataPipeProducerHandle();
+    public ProducerHandle toDataPipeProducerHandle();
 
     /**
-     * TODO(qsr):
-     *
-     * @return TODO(qsr)
+     * Returns the underlying handle, as a {@link SharedBufferHandle}, invalidating this
+     * representation.
      */
     public SharedBufferHandle toSharedBufferHandle();
 
diff --git a/mojo/public/tests/test_support_private.cc b/mojo/public/tests/test_support_private.cc
index d7d02e8..fa5ead4 100644
--- a/mojo/public/tests/test_support_private.cc
+++ b/mojo/public/tests/test_support_private.cc
@@ -5,8 +5,8 @@
 #include "mojo/public/tests/test_support_private.h"
 
 #include <assert.h>
-#include <stddef.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 static mojo::test::TestSupport* g_test_support = NULL;
 
@@ -21,6 +21,26 @@
     printf("[no test runner]\t%s\t%g\t%s\n", test_name, value, units);
 }
 
+FILE* MojoTestSupportOpenSourceRootRelativeFile(const char* relative_path) {
+  if (g_test_support)
+    return g_test_support->OpenSourceRootRelativeFile(relative_path);
+  printf("[no test runner]\n");
+  return NULL;
+}
+
+char** MojoTestSupportEnumerateSourceRootRelativeDirectory(
+    const char* relative_path) {
+  if (g_test_support)
+    return g_test_support->EnumerateSourceRootRelativeDirectory(relative_path);
+
+  printf("[no test runner]\n");
+
+  // Return empty list:
+  char** rv = static_cast<char**>(calloc(1, sizeof(char*)));
+  rv[0] = NULL;
+  return rv;
+}
+
 }  // extern "C"
 
 namespace mojo {
diff --git a/mojo/public/tests/test_support_private.h b/mojo/public/tests/test_support_private.h
index 3674fec..29983ca 100644
--- a/mojo/public/tests/test_support_private.h
+++ b/mojo/public/tests/test_support_private.h
@@ -5,6 +5,8 @@
 #ifndef MOJO_PUBLIC_TESTS_TEST_SUPPORT_PRIVATE_H_
 #define MOJO_PUBLIC_TESTS_TEST_SUPPORT_PRIVATE_H_
 
+#include <stdio.h>
+
 #include "mojo/public/c/test_support/test_support.h"
 
 namespace mojo {
@@ -23,6 +25,9 @@
   virtual void LogPerfResult(const char* test_name,
                              double value,
                              const char* units) = 0;
+  virtual FILE* OpenSourceRootRelativeFile(const char* relative_path) = 0;
+  virtual char** EnumerateSourceRootRelativeDirectory(
+      const char* relative_path) = 0;
 };
 
 }  // namespace test
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
index 4910463..7a03023 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -114,7 +114,9 @@
   if (!receiver_->AcceptWithResponder(&message, responder))
     delete responder;
 {%- else %}
-  receiver_->Accept(&message);
+  bool ok MOJO_ALLOW_UNUSED = receiver_->Accept(&message);
+  // This return value may be ignored as !ok implies the Connector has
+  // encountered an error, which will be visible through other means.
 {%- endif %}
 }
 {%- endfor %}
@@ -153,7 +155,10 @@
   mojo::internal::ResponseMessageBuilder builder(
       {{message_name}}, payload_size, request_id_);
   {{build_message(params_name, method.response_parameters)}}
-  responder_->Accept(&message);
+  bool ok MOJO_ALLOW_UNUSED = responder_->Accept(&message);
+  // TODO(darin): !ok returned here indicates a malformed message, and that may
+  // be good reason to close the connection. However, we don't have a way to do
+  // that from here. We should add a way.
   delete responder_;
   responder_ = NULL;
 }
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
index 4e423aa..0108335 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
@@ -25,10 +25,10 @@
 {%-   for method in interface.methods %}
 {%-     set method_name = "k%s_%s_Name"|format(interface.name, method.name) %}
 const uint32_t {{method_name}} = {{method.ordinal}};
-{%      set struct = interface|struct_from_method(method) %}
+{%      set struct = method|struct_from_method %}
 {%-     include "params_definition.tmpl" %}
 {%-     if method.response_parameters != None %}
-{%-       set struct = interface|response_struct_from_method(method) %}
+{%-       set struct = method|response_struct_from_method %}
 {%-       include "params_definition.tmpl" %}
 {%-     endif %}
 {%-   endfor %}
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.gypi b/mojo/public/tools/bindings/mojom_bindings_generator.gypi
index 7d25ed1..4aa05f7 100644
--- a/mojo/public/tools/bindings/mojom_bindings_generator.gypi
+++ b/mojo/public/tools/bindings/mojom_bindings_generator.gypi
@@ -62,7 +62,7 @@
       ],
       'action': [
         'python', '<@(mojom_bindings_generator)',
-        '<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).mojom',
+        './<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).mojom',
         '--use_chromium_bundled_pylibs',
         '-d', '<(DEPTH)',
         '-o', '<(SHARED_INTERMEDIATE_DIR)/<(mojom_base_output_dir)/<(RULE_INPUT_DIRNAME)',
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/data.py b/mojo/public/tools/bindings/pylib/mojom/generate/data.py
index 513b50b..1f2f808 100644
--- a/mojo/public/tools/bindings/pylib/mojom/generate/data.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/data.py
@@ -132,6 +132,7 @@
 def StructFromData(module, data):
   struct = mojom.Struct(module=module)
   struct.name = data['name']
+  struct.attributes = data['attributes']
   struct.spec = 'x:' + module.namespace + '.' + struct.name
   module.kinds[struct.spec] = struct
   struct.enums = map(lambda enum:
@@ -207,9 +208,7 @@
   return data
 
 def MethodFromData(module, data, interface):
-  method = mojom.Method()
-  method.name = data['name']
-  method.ordinal = data.get('ordinal')
+  method = mojom.Method(interface, data['name'], ordinal=data.get('ordinal'))
   method.default = data.get('default')
   method.parameters = map(lambda parameter:
       ParameterFromData(module, parameter, interface), data['parameters'])
@@ -284,6 +283,7 @@
 
   module.name = data['name']
   module.namespace = data['namespace']
+  module.attributes = data['attributes']
   # Imports must come first, because they add to module.kinds which is used
   # by by the others.
   module.imports = map(
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/generator.py b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
index f063ad8..709aa2a 100644
--- a/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
@@ -10,25 +10,25 @@
 import module as mojom
 import pack
 
-def GetStructFromMethod(interface, method):
+def GetStructFromMethod(method):
   """Converts a method's parameters into the fields of a struct."""
-  params_class = "%s_%s_Params" % (interface.name, method.name)
-  struct = mojom.Struct(params_class, module=interface.module)
+  params_class = "%s_%s_Params" % (method.interface.name, method.name)
+  struct = mojom.Struct(params_class, module=method.interface.module)
   for param in method.parameters:
     struct.AddField(param.name, param.kind, param.ordinal)
   struct.packed = pack.PackedStruct(struct)
   return struct
 
-def GetResponseStructFromMethod(interface, method):
+def GetResponseStructFromMethod(method):
   """Converts a method's response_parameters into the fields of a struct."""
-  params_class = "%s_%s_ResponseParams" % (interface.name, method.name)
-  struct = mojom.Struct(params_class, module=interface.module)
+  params_class = "%s_%s_ResponseParams" % (method.interface.name, method.name)
+  struct = mojom.Struct(params_class, module=method.interface.module)
   for param in method.response_parameters:
     struct.AddField(param.name, param.kind, param.ordinal)
   struct.packed = pack.PackedStruct(struct)
   return struct
 
-def GetStructInfo(exported, struct):
+def GetDataHeader(exported, struct):
   struct.packed = pack.PackedStruct(struct)
   struct.bytes = pack.GetByteLayout(struct.packed)
   struct.exported = exported
@@ -80,13 +80,13 @@
     result = []
     for interface in self.module.interfaces:
       for method in interface.methods:
-        result.append(GetStructFromMethod(interface, method))
+        result.append(GetStructFromMethod(method))
         if method.response_parameters != None:
-          result.append(GetResponseStructFromMethod(interface, method))
-    return map(partial(GetStructInfo, False), result)
+          result.append(GetResponseStructFromMethod(method))
+    return map(partial(GetDataHeader, False), result)
 
   def GetStructs(self):
-    return map(partial(GetStructInfo, True), self.module.structs)
+    return map(partial(GetDataHeader, True), self.module.structs)
 
   def Write(self, contents, filename):
     if self.output_dir is None:
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/module.py b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
index 9d04add..4abe690 100644
--- a/mojo/public/tools/bindings/pylib/mojom/generate/module.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
@@ -118,7 +118,8 @@
 
 
 class Method(object):
-  def __init__(self, name=None, ordinal=None):
+  def __init__(self, interface, name, ordinal=None):
+    self.interface = interface
     self.name = name
     self.ordinal = ordinal
     self.parameters = []
@@ -150,7 +151,7 @@
     self.methods = []
 
   def AddMethod(self, name, ordinal=None):
-    method = Method(name, ordinal)
+    method = Method(self, name, ordinal=ordinal)
     self.methods.append(method)
     return method
 
diff --git a/mojo/public/tools/bindings/pylib/mojom/parse/parser.py b/mojo/public/tools/bindings/pylib/mojom/parse/parser.py
old mode 100755
new mode 100644
index e75b28a..9dd6e07
--- a/mojo/public/tools/bindings/pylib/mojom/parse/parser.py
+++ b/mojo/public/tools/bindings/pylib/mojom/parse/parser.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # 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.
@@ -80,7 +79,7 @@
       # Generator expects a module. If one wasn't specified insert one with an
       # empty name.
       if p[1][0] != 'MODULE':
-        p[0] = [('MODULE', '', p[1])]
+        p[0] = [('MODULE', '', [], p[1])]
       else:
         p[0] = [p[1]]
 
@@ -90,8 +89,8 @@
     p[0] = ('IMPORT', eval(p[2]))
 
   def p_module(self, p):
-    """module : MODULE identifier LBRACE definitions RBRACE"""
-    p[0] = ('MODULE', p[2], p[4])
+    """module : attribute_section MODULE identifier LBRACE definitions RBRACE"""
+    p[0] = ('MODULE', p[3], p[1], p[5])
 
   def p_definitions(self, p):
     """definitions : definition definitions
@@ -360,24 +359,3 @@
 
   tree = yacc.parse(source)
   return tree
-
-
-def main(argv):
-  if len(argv) < 2:
-    print "usage: %s filename" % argv[0]
-    return 0
-
-  for filename in argv[1:]:
-    with open(filename) as f:
-      print "%s:" % filename
-      try:
-        print Parse(f.read(), filename)
-      except ParseError, e:
-        print e
-        return 1
-
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(main(sys.argv))
diff --git a/mojo/public/tools/bindings/pylib/mojom/parse/translate.py b/mojo/public/tools/bindings/pylib/mojom/parse/translate.py
old mode 100755
new mode 100644
index 6060c83..2300cb6
--- a/mojo/public/tools/bindings/pylib/mojom/parse/translate.py
+++ b/mojo/public/tools/bindings/pylib/mojom/parse/translate.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # 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.
@@ -6,18 +5,15 @@
 """Translates parse tree to Mojom IR."""
 
 
-import os.path
-import sys
-
 import ast
 
 
-def MapTree(func, tree, name):
+def _MapTree(func, tree, name):
   if not tree:
     return []
   return [func(subtree) for subtree in tree if subtree[0] == name]
 
-def MapKind(kind):
+def _MapKind(kind):
   map_to_kind = { 'bool': 'b',
                   'int8': 'i8',
                   'int16': 'i16',
@@ -36,12 +32,18 @@
                   'handle<message_pipe>': 'h:m',
                   'handle<shared_buffer>': 'h:s'}
   if kind.endswith('[]'):
-    return 'a:' + MapKind(kind[0:len(kind)-2])
+    return 'a:' + _MapKind(kind[0:len(kind)-2])
   if kind in map_to_kind:
     return map_to_kind[kind]
   return 'x:' + kind
 
-def GetAttribute(attributes, name):
+def _MapAttributes(attributes):
+  if not attributes:
+    return {}
+  return dict([(attribute[1], attribute[2])
+               for attribute in attributes if attribute[0] == 'ATTRIBUTE'])
+
+def _GetAttribute(attributes, name):
   out = None
   if attributes:
     for attribute in attributes:
@@ -49,97 +51,82 @@
         out = attribute[2]
   return out
 
-def MapField(tree):
+def _MapField(tree):
   assert type(tree[3]) is ast.Ordinal
   return {'name': tree[2],
-          'kind': MapKind(tree[1]),
+          'kind': _MapKind(tree[1]),
           'ordinal': tree[3].value,
           'default': tree[4]}
 
-def MapParameter(tree):
+def _MapParameter(tree):
   assert type(tree[3]) is ast.Ordinal
   return {'name': tree[2],
-          'kind': MapKind(tree[1]),
+          'kind': _MapKind(tree[1]),
           'ordinal': tree[3].value}
 
-def MapMethod(tree):
+def _MapMethod(tree):
   assert type(tree[3]) is ast.Ordinal
   method = {'name': tree[1],
-            'parameters': MapTree(MapParameter, tree[2], 'PARAM'),
+            'parameters': _MapTree(_MapParameter, tree[2], 'PARAM'),
             'ordinal': tree[3].value}
   if tree[4] != None:
-    method['response_parameters'] = MapTree(MapParameter, tree[4], 'PARAM')
+    method['response_parameters'] = _MapTree(_MapParameter, tree[4], 'PARAM')
   return method
 
-def MapEnumField(tree):
+def _MapEnumField(tree):
   return {'name': tree[1],
           'value': tree[2]}
 
-def MapStruct(tree):
+def _MapStruct(tree):
   struct = {}
   struct['name'] = tree[1]
-  # TODO(darin): Add support for |attributes|
-  #struct['attributes'] = MapAttributes(tree[2])
-  struct['fields'] = MapTree(MapField, tree[3], 'FIELD')
-  struct['enums'] = MapTree(MapEnum, tree[3], 'ENUM')
+  struct['attributes'] = _MapAttributes(tree[2])
+  struct['fields'] = _MapTree(_MapField, tree[3], 'FIELD')
+  struct['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM')
   return struct
 
-def MapInterface(tree):
+def _MapInterface(tree):
   interface = {}
   interface['name'] = tree[1]
-  interface['peer'] = GetAttribute(tree[2], 'Peer')
-  interface['methods'] = MapTree(MapMethod, tree[3], 'METHOD')
-  interface['enums'] = MapTree(MapEnum, tree[3], 'ENUM')
+  interface['peer'] = _GetAttribute(tree[2], 'Peer')
+  interface['methods'] = _MapTree(_MapMethod, tree[3], 'METHOD')
+  interface['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM')
   return interface
 
-def MapEnum(tree):
+def _MapEnum(tree):
   enum = {}
   enum['name'] = tree[1]
-  enum['fields'] = MapTree(MapEnumField, tree[2], 'ENUM_FIELD')
+  enum['fields'] = _MapTree(_MapEnumField, tree[2], 'ENUM_FIELD')
   return enum
 
-def MapModule(tree, name):
+def _MapModule(tree, name):
   mojom = {}
   mojom['name'] = name
   mojom['namespace'] = tree[1]
-  mojom['structs'] = MapTree(MapStruct, tree[2], 'STRUCT')
-  mojom['interfaces'] = MapTree(MapInterface, tree[2], 'INTERFACE')
-  mojom['enums'] = MapTree(MapEnum, tree[2], 'ENUM')
+  mojom['attributes'] = _MapAttributes(tree[2])
+  mojom['structs'] = _MapTree(_MapStruct, tree[3], 'STRUCT')
+  mojom['interfaces'] = _MapTree(_MapInterface, tree[3], 'INTERFACE')
+  mojom['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM')
   return mojom
 
-def MapImport(tree):
+def _MapImport(tree):
   import_item = {}
   import_item['filename'] = tree[1]
   return import_item
 
 
-class MojomBuilder():
+class _MojomBuilder(object):
   def __init__(self):
     self.mojom = {}
 
   def Build(self, tree, name):
-    modules = [MapModule(item, name)
-        for item in tree if item[0] == 'MODULE']
+    modules = [_MapModule(item, name) for item in tree if item[0] == 'MODULE']
     if len(modules) != 1:
       raise Exception('A mojom file must contain exactly 1 module.')
     self.mojom = modules[0]
-    self.mojom['imports'] = MapTree(MapImport, tree, 'IMPORT')
+    self.mojom['imports'] = _MapTree(_MapImport, tree, 'IMPORT')
     return self.mojom
 
 
 def Translate(tree, name):
-  return MojomBuilder().Build(tree, name)
-
-
-def Main():
-  if len(sys.argv) < 2:
-    print("usage: %s filename" % (sys.argv[0]))
-    sys.exit(1)
-  tree = eval(open(sys.argv[1]).read())
-  name = os.path.splitext(os.path.basename(sys.argv[1]))[0]
-  result = Translate(tree, name)
-  print(result)
-
-
-if __name__ == '__main__':
-  Main()
+  return _MojomBuilder().Build(tree, name)
diff --git a/mojo/public/tools/bindings/pylib/mojom_tests/parse/run_parser.py b/mojo/public/tools/bindings/pylib/mojom_tests/parse/run_parser.py
new file mode 100755
index 0000000..edca7e1
--- /dev/null
+++ b/mojo/public/tools/bindings/pylib/mojom_tests/parse/run_parser.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+# 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.
+
+"""Simple testing utility to just run the mojom parser."""
+
+
+import os.path
+import sys
+
+sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
+                                os.path.pardir, os.path.pardir))
+
+# Disable lint check for finding modules:
+# pylint: disable=F0401
+
+from mojom.parse.parser import Parse, ParseError
+
+
+def main(argv):
+  if len(argv) < 2:
+    print "usage: %s filename" % argv[0]
+    return 0
+
+  for filename in argv[1:]:
+    with open(filename) as f:
+      print "%s:" % filename
+      try:
+        print Parse(f.read(), filename)
+      except ParseError, e:
+        print e
+        return 1
+
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/mojo/public/tools/bindings/pylib/mojom_tests/parse/run_translate.py b/mojo/public/tools/bindings/pylib/mojom_tests/parse/run_translate.py
new file mode 100755
index 0000000..833af62
--- /dev/null
+++ b/mojo/public/tools/bindings/pylib/mojom_tests/parse/run_translate.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+# 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.
+
+"""Simple testing utility to just run the mojom translate stage."""
+
+
+import os.path
+import sys
+
+sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
+                                os.path.pardir, os.path.pardir))
+
+# Disable lint check for finding modules:
+# pylint: disable=F0401
+
+from mojom.parse.parser import Parse
+from mojom.parse.translate import Translate
+
+
+def main(argv):
+  if len(argv) < 2:
+    print "usage: %s filename" % sys.argv[0]
+    return 1
+
+  for filename in argv[1:]:
+    with open(filename) as f:
+      print "%s:" % filename
+      print Translate(Parse(f.read(), filename),
+                      os.path.splitext(os.path.basename(filename))[0])
+
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/mojo/service_manager/background_service_loader.cc b/mojo/service_manager/background_service_loader.cc
new file mode 100644
index 0000000..ba365b0
--- /dev/null
+++ b/mojo/service_manager/background_service_loader.cc
@@ -0,0 +1,94 @@
+// 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.
+
+#include "mojo/service_manager/background_service_loader.h"
+
+#include "base/bind.h"
+#include "mojo/service_manager/service_manager.h"
+
+namespace mojo {
+
+class BackgroundServiceLoader::BackgroundLoader {
+ public:
+  explicit BackgroundLoader(ServiceLoader* loader) : loader_(loader) {}
+  ~BackgroundLoader() {}
+
+  void LoadService(ServiceManager* manager,
+                   const GURL& url,
+                   ScopedShellHandle shell_handle) {
+    loader_->LoadService(manager, url, shell_handle.Pass());
+  }
+
+  void OnServiceError(ServiceManager* manager, const GURL& url) {
+    loader_->OnServiceError(manager, url);
+  }
+
+ private:
+  ServiceLoader* loader_;  // Owned by BackgroundServiceLoader
+
+  DISALLOW_COPY_AND_ASSIGN(BackgroundLoader);
+};
+
+BackgroundServiceLoader::BackgroundServiceLoader(
+    scoped_ptr<ServiceLoader> real_loader,
+    const char* thread_name)
+    : loader_(real_loader.Pass()),
+      thread_(thread_name),
+      background_loader_(NULL) {
+}
+
+BackgroundServiceLoader::~BackgroundServiceLoader() {
+  if (thread_.IsRunning()) {
+    thread_.message_loop()->PostTask(
+        FROM_HERE,
+        base::Bind(&BackgroundServiceLoader::ShutdownOnBackgroundThread,
+                   base::Unretained(this)));
+  }
+  thread_.Stop();
+}
+
+void BackgroundServiceLoader::LoadService(ServiceManager* manager,
+                                          const GURL& url,
+                                          ScopedShellHandle service_handle) {
+  if (!thread_.IsRunning())
+    thread_.Start();
+  thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&BackgroundServiceLoader::LoadServiceOnBackgroundThread,
+                 base::Unretained(this), manager, url,
+                 base::Owned(new ScopedShellHandle(service_handle.Pass()))));
+}
+
+void BackgroundServiceLoader::OnServiceError(ServiceManager* manager,
+                                             const GURL& url) {
+  if (!thread_.IsRunning())
+    thread_.Start();
+  thread_.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&BackgroundServiceLoader::OnServiceErrorOnBackgroundThread,
+                 base::Unretained(this), manager, url));
+}
+
+void BackgroundServiceLoader::LoadServiceOnBackgroundThread(
+    ServiceManager* manager,
+    const GURL& url,
+    ScopedShellHandle* shell_handle) {
+  if (!background_loader_)
+    background_loader_ = new BackgroundLoader(loader_.get());
+  background_loader_->LoadService(manager, url, shell_handle->Pass());
+}
+
+void BackgroundServiceLoader::OnServiceErrorOnBackgroundThread(
+    ServiceManager* manager,
+    const GURL& url) {
+  if (!background_loader_)
+    background_loader_ = new BackgroundLoader(loader_.get());
+  background_loader_->OnServiceError(manager, url);
+}
+
+void BackgroundServiceLoader::ShutdownOnBackgroundThread() {
+  delete background_loader_;
+}
+
+}  // namespace mojo
diff --git a/mojo/service_manager/background_service_loader.h b/mojo/service_manager/background_service_loader.h
new file mode 100644
index 0000000..b505941
--- /dev/null
+++ b/mojo/service_manager/background_service_loader.h
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef MOJO_SERVICE_MANAGER_BACKGROUND_SERVICE_LOADER_H_
+#define MOJO_SERVICE_MANAGER_BACKGROUND_SERVICE_LOADER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread.h"
+#include "mojo/service_manager/service_loader.h"
+
+namespace mojo {
+
+class ServiceManager;
+
+// ServiceLoader implementation that creates a background thread and issues load
+// requests there.
+class MOJO_SERVICE_MANAGER_EXPORT BackgroundServiceLoader
+    : public ServiceLoader {
+ public:
+  BackgroundServiceLoader(scoped_ptr<ServiceLoader> real_loader,
+                          const char* thread_name);
+  virtual ~BackgroundServiceLoader();
+
+  // ServiceLoader overrides:
+  virtual void LoadService(ServiceManager* manager,
+                           const GURL& url,
+                           ScopedShellHandle service_handle) OVERRIDE;
+  virtual void OnServiceError(ServiceManager* manager,
+                              const GURL& url) OVERRIDE;
+
+ private:
+  class BackgroundLoader;
+
+  // These functions are exected on the background thread. They call through
+  // to |background_loader_| to do the actual loading.
+  // TODO: having this code take a |manager| is fragile (as ServiceManager isn't
+  // thread safe).
+  void LoadServiceOnBackgroundThread(ServiceManager* manager,
+                                     const GURL& url,
+                                     ScopedShellHandle* shell_handle);
+  void OnServiceErrorOnBackgroundThread(ServiceManager* manager,
+                                        const GURL& url);
+  void ShutdownOnBackgroundThread();
+
+  scoped_ptr<ServiceLoader> loader_;
+  base::Thread thread_;
+
+  // Lives on |thread_|. Trivial interface that calls through to |loader_|.
+  BackgroundLoader* background_loader_;
+
+  DISALLOW_COPY_AND_ASSIGN(BackgroundServiceLoader);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_SERVICE_MANAGER_BACKGROUND_SERVICE_LOADER_H_
diff --git a/mojo/service_manager/service_loader.h b/mojo/service_manager/service_loader.h
index 42b593e..7567ad3 100644
--- a/mojo/service_manager/service_loader.h
+++ b/mojo/service_manager/service_loader.h
@@ -17,7 +17,7 @@
 // specific url.
 class MOJO_SERVICE_MANAGER_EXPORT ServiceLoader {
  public:
-  virtual ~ServiceLoader() {};
+  virtual ~ServiceLoader() {}
   virtual void LoadService(ServiceManager* manager,
                            const GURL& url,
                            ScopedShellHandle service_handle) = 0;
diff --git a/mojo/service_manager/service_manager.h b/mojo/service_manager/service_manager.h
index ae41127..1e3fcbd 100644
--- a/mojo/service_manager/service_manager.h
+++ b/mojo/service_manager/service_manager.h
@@ -8,7 +8,6 @@
 #include <map>
 
 #include "base/basictypes.h"
-#include "base/callback.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/scoped_ptr.h"
 #include "mojo/public/interfaces/shell/shell.mojom.h"
diff --git a/mojo/services/dbus_echo/DEPS b/mojo/services/dbus_echo/DEPS
index 7260d76..35a7b6c 100644
--- a/mojo/services/dbus_echo/DEPS
+++ b/mojo/services/dbus_echo/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
-  "+dbus",
+  "+base",
+  "+mojo/dbus",
   "+mojo/embedder",
 ]
diff --git a/mojo/services/dbus_echo/dbus_echo_service.cc b/mojo/services/dbus_echo/dbus_echo_service.cc
index 993a613..70762f6 100644
--- a/mojo/services/dbus_echo/dbus_echo_service.cc
+++ b/mojo/services/dbus_echo/dbus_echo_service.cc
@@ -3,29 +3,20 @@
 // found in the LICENSE file.
 
 #include "base/at_exit.h"
-#include "base/bind.h"
 #include "base/callback.h"
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_proxy.h"
 #include "base/run_loop.h"
-#include "dbus/bus.h"
-#include "dbus/exported_object.h"
-#include "dbus/file_descriptor.h"
-#include "dbus/message.h"
-#include "dbus/object_path.h"
 #include "mojo/common/channel_init.h"
+#include "mojo/dbus/dbus_external_service.h"
 #include "mojo/embedder/embedder.h"
 #include "mojo/public/cpp/bindings/interface.h"
-#include "mojo/public/cpp/bindings/remote_ptr.h"
 #include "mojo/public/cpp/environment/environment.h"
-#include "mojo/public/cpp/shell/application.h"
-#include "mojo/public/interfaces/shell/shell.mojom.h"
 #include "mojo/services/dbus_echo/echo.mojom.h"
-#include "mojo/shell/external_service.mojom.h"
 
+namespace {
 class EchoServiceImpl : public mojo::ServiceConnection<mojo::EchoService,
                                                        EchoServiceImpl> {
  public:
@@ -41,105 +32,8 @@
   }
 };
 
-
-class DBusEchoService : public mojo::ExternalService {
- public:
-  static const char kMojoImplPath[];
-  static const char kMojoInterface[];
-  static const char kServiceName[];
-
-  DBusEchoService() : exported_object_(NULL) {
-  }
-  ~DBusEchoService() {}
-
-  void Start() {
-    InitializeDBus();
-    ExportMethods();
-    TakeDBusServiceOwnership();
-    DVLOG(1) << "Echo service started";
-  }
-
- private:
-  // TODO(cmasone): Use a Delegate pattern to allow the ConnectChannel
-  // code to be shared among all Mojo services that wish to be
-  // connected to over DBus.
-  virtual void Activate(mojo::ScopedMessagePipeHandle client_handle) OVERRIDE {
-    mojo::ScopedShellHandle shell_handle(
-        mojo::ShellHandle(client_handle.release().value()));
-    app_.reset(new mojo::Application(shell_handle.Pass()));
-    app_->AddServiceConnector(new mojo::ServiceConnector<EchoServiceImpl>());
-  }
-
-  // Implementation of org.chromium.Mojo.ConnectChannel, exported over DBus.
-  // Takes a file descriptor and uses it to create a MessagePipe that is then
-  // hooked to a RemotePtr<mojo::ExternalServiceHost>.
-  void ConnectChannel(dbus::MethodCall* method_call,
-                      dbus::ExportedObject::ResponseSender sender) {
-    dbus::MessageReader reader(method_call);
-    dbus::FileDescriptor wrapped_fd;
-    if (!reader.PopFileDescriptor(&wrapped_fd)) {
-      sender.Run(
-          dbus::ErrorResponse::FromMethodCall(
-              method_call,
-              "org.chromium.Mojo.BadHandle",
-              "Invalid FD.").PassAs<dbus::Response>());
-      return;
-    }
-    wrapped_fd.CheckValidity();
-    channel_init_.reset(new mojo::common::ChannelInit);
-    mojo::ScopedMessagePipeHandle message_pipe =
-        channel_init_->Init(wrapped_fd.TakeValue(),
-                            base::MessageLoopProxy::current());
-    CHECK(message_pipe.is_valid());
-
-    // TODO(cmasone): Figure out how to correctly clean up the channel when
-    // the peer disappears. Passing an ErrorHandler when constructing the
-    // RemotePtr<> below didn't seem to work. OnError wasn't called.
-    external_service_host_.reset(
-        mojo::ScopedExternalServiceHostHandle::From(message_pipe.Pass()),
-        this);
-
-    sender.Run(dbus::Response::FromMethodCall(method_call));
-  }
-
-  void ExportMethods() {
-    CHECK(exported_object_);
-    CHECK(exported_object_->ExportMethodAndBlock(
-        kMojoInterface, "ConnectChannel",
-        base::Bind(&DBusEchoService::ConnectChannel,
-                   base::Unretained(this))));
-  }
-
-  void InitializeDBus() {
-    CHECK(!bus_);
-    dbus::Bus::Options options;
-    options.bus_type = dbus::Bus::SESSION;
-    bus_ = new dbus::Bus(options);
-    CHECK(bus_->Connect());
-    CHECK(bus_->SetUpAsyncOperations());
-
-    exported_object_ = bus_->GetExportedObject(dbus::ObjectPath(kMojoImplPath));
-  }
-
-  void TakeDBusServiceOwnership() {
-    CHECK(bus_->RequestOwnershipAndBlock(
-        kServiceName,
-        dbus::Bus::REQUIRE_PRIMARY_ALLOW_REPLACEMENT))
-        << "Unable to take ownership of " << kServiceName;
-  }
-
-  scoped_refptr<dbus::Bus> bus_;
-  dbus::ExportedObject* exported_object_;  // Owned by bus_;
-  scoped_ptr<mojo::common::ChannelInit> channel_init_;
-  mojo::RemotePtr<mojo::ExternalServiceHost> external_service_host_;
-  scoped_ptr<mojo::Application> app_;
-};
-
-// TODO(cmasone): Figure out where these "well-known" names should be defined
-// so they can be shared with DBusServiceLoader and such.
-const char DBusEchoService::kMojoImplPath[] = "/org/chromium/MojoImpl";
-const char DBusEchoService::kMojoInterface[] = "org.chromium.Mojo";
-const char DBusEchoService::kServiceName[] = "org.chromium.EchoService";
+const char kServiceName[] = "org.chromium.EchoService";
+}  // anonymous namespace
 
 int main(int argc, char** argv) {
   base::AtExitManager exit_manager;
@@ -159,7 +53,7 @@
   base::MessageLoopForIO message_loop;
   base::RunLoop run_loop;
 
-  DBusEchoService echo_service;
+  mojo::DBusExternalService<EchoServiceImpl> echo_service(kServiceName);
   echo_service.Start();
 
   run_loop.Run();
diff --git a/mojo/services/gles2/command_buffer_impl.cc b/mojo/services/gles2/command_buffer_impl.cc
index 09a1877..bbeb393 100644
--- a/mojo/services/gles2/command_buffer_impl.cc
+++ b/mojo/services/gles2/command_buffer_impl.cc
@@ -53,7 +53,13 @@
                                      const gfx::Size& size)
     : client_(client.Pass(), this), widget_(widget), size_(size) {}
 
-CommandBufferImpl::~CommandBufferImpl() { client_->DidDestroy(); }
+CommandBufferImpl::~CommandBufferImpl() {
+  client_->DidDestroy();
+  if (decoder_.get()) {
+    bool have_context = decoder_->MakeCurrent();
+    decoder_->Destroy(have_context);
+  }
+}
 
 void CommandBufferImpl::Initialize(
     ScopedCommandBufferSyncClientHandle sync_client,
@@ -112,11 +118,7 @@
     return false;
 
   gpu_control_.reset(
-      new gpu::GpuControlService(context_group->image_manager(),
-                                 NULL,
-                                 context_group->mailbox_manager(),
-                                 NULL,
-                                 decoder_->GetCapabilities()));
+      new gpu::GpuControlService(context_group->image_manager(), NULL));
 
   command_buffer_->SetPutOffsetChangeCallback(base::Bind(
       &gpu::GpuScheduler::PutChanged, base::Unretained(scheduler_.get())));
diff --git a/mojo/services/native_viewport/native_viewport_service.cc b/mojo/services/native_viewport/native_viewport_service.cc
index 5625aa1..9585ae7 100644
--- a/mojo/services/native_viewport/native_viewport_service.cc
+++ b/mojo/services/native_viewport/native_viewport_service.cc
@@ -36,7 +36,11 @@
   NativeViewportImpl()
       : widget_(gfx::kNullAcceleratedWidget),
         waiting_for_event_ack_(false) {}
-  virtual ~NativeViewportImpl() {}
+  virtual ~NativeViewportImpl() {
+    // Destroy the NativeViewport early on as it may call us back during
+    // destruction and we want to be in a known state.
+    native_viewport_.reset();
+  }
 
   virtual void Create(const Rect& bounds) OVERRIDE {
     native_viewport_ =
diff --git a/mojo/services/native_viewport/native_viewport_x11.cc b/mojo/services/native_viewport/native_viewport_x11.cc
index be7d1cd..50397b8 100644
--- a/mojo/services/native_viewport/native_viewport_x11.cc
+++ b/mojo/services/native_viewport/native_viewport_x11.cc
@@ -53,8 +53,9 @@
     atom_wm_delete_window_ = XInternAtom(display, "WM_DELETE_WINDOW", 1);
     XSetWMProtocols(display, window_, &atom_wm_delete_window_, 1);
 
-    // Assumes there is only one instance per process.
-    event_source_ = ui::PlatformEventSource::CreateDefault();
+    event_source_.reset(ui::PlatformEventSource::GetInstance());
+    if (!event_source_.get())
+      event_source_ = ui::PlatformEventSource::CreateDefault();
     ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
 
     delegate_->OnAcceleratedWidgetAvailable(window_);
diff --git a/mojo/services/public/cpp/view_manager/lib/DEPS b/mojo/services/public/cpp/view_manager/lib/DEPS
new file mode 100644
index 0000000..2661b64
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/DEPS
@@ -0,0 +1,5 @@
+specific_include_rules = {
+  "view_manager_test_suite.cc": [
+    "+ui/gl",
+  ],
+}
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager.cc b/mojo/services/public/cpp/view_manager/lib/view_manager.cc
index 7fd82e7..4603abc 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager.cc
@@ -1,20 +1,24 @@
 // 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.
-

-#include "mojo/services/public/cpp/view_manager/view_manager.h"

-

-#include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"

-

-namespace mojo {

-namespace services {

-namespace view_manager {

-

-ViewManager::ViewManager(Shell* shell)

-    : shell_(shell),

-      synchronizer_(new ViewManagerSynchronizer(this)) {}

-ViewManager::~ViewManager() {}

-

-}  // namespace view_manager

-}  // namespace services

-}  // namespace mojo

+
+#include "mojo/services/public/cpp/view_manager/view_manager.h"
+
+#include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+ViewManager::ViewManager(Shell* shell)
+    : shell_(shell) {}
+
+ViewManager::~ViewManager() {}
+
+void ViewManager::Init() {
+  synchronizer_.reset(new ViewManagerSynchronizer(this));
+}
+
+}  // namespace view_manager
+}  // namespace services
+}  // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_private.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_private.cc
index e3272c3..bcd4542 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_private.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_private.cc
@@ -12,6 +12,10 @@
     : manager_(manager) {}
 ViewManagerPrivate::~ViewManagerPrivate() {}
 
+void ViewManagerPrivate::SetRoot(ViewTreeNode* root) {
+  manager_->tree_.reset(root);
+}
+
 }  // namespace view_manager
 }  // namespace services
 }  // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_private.h b/mojo/services/public/cpp/view_manager/lib/view_manager_private.h
index 071404b..cad72ec 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_private.h
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_private.h
@@ -6,6 +6,7 @@
 #define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_MANAGER_PRIVATE_H_
 
 #include "base/basictypes.h"
+#include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
 #include "mojo/services/public/cpp/view_manager/view_manager.h"
 
 namespace mojo {
@@ -24,6 +25,11 @@
   }
   Shell* shell() { return manager_->shell_; }
 
+  void SetRoot(ViewTreeNode* root);
+
+  // Returns true if the ViewManager's synchronizer is connected to the service.
+  bool connected() { return manager_->synchronizer_->connected(); }
+
  private:
   ViewManager* manager_;
 
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
index 5fe22b4..1f82fd8 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
@@ -6,14 +6,22 @@
 
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "mojo/public/cpp/bindings/allocation_scope.h"
 #include "mojo/public/interfaces/shell/shell.mojom.h"
 #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
+#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
+#include "mojo/services/public/cpp/view_manager/util.h"
 
 namespace mojo {
 namespace services {
 namespace view_manager {
 
+TransportNodeId MakeTransportNodeId(uint16_t connection_id,
+                                    uint16_t local_node_id) {
+  return (connection_id << 16) | local_node_id;
+}
+
 class ViewManagerTransaction {
  public:
   virtual ~ViewManagerTransaction() {}
@@ -36,8 +44,9 @@
 
  protected:
   enum TransactionType {
-    // Node creation.
+    // Node creation and destruction.
     TYPE_CREATE_VIEW_TREE_NODE,
+    TYPE_DESTROY_VIEW_TREE_NODE,
     // Modifications to the hierarchy (addition of or removal of nodes from a
     // parent.)
     TYPE_HIERARCHY
@@ -60,10 +69,6 @@
 
   IViewManager* service() { return synchronizer_->service_.get(); }
 
-  uint32_t MakeTransportId(uint16_t id) {
-    return (synchronizer_->connection_id_ << 16) | id;
-  }
-
  private:
   const TransactionType transaction_type_;
   const uint32_t change_id_;
@@ -73,8 +78,7 @@
   DISALLOW_COPY_AND_ASSIGN(ViewManagerTransaction);
 };
 
-class CreateViewTreeNodeTransaction
-    : public ViewManagerTransaction {
+class CreateViewTreeNodeTransaction : public ViewManagerTransaction {
  public:
   CreateViewTreeNodeTransaction(uint16_t node_id,
                                 ViewManagerSynchronizer* synchronizer)
@@ -90,7 +94,6 @@
         base::Bind(&ViewManagerTransaction::OnActionCompleted,
                    base::Unretained(this)));
   }
-
   virtual void DoActionCompleted(bool success) OVERRIDE {
     // TODO(beng): Failure means we tried to create with an extant id for this
     //             connection. Figure out what to do.
@@ -101,6 +104,31 @@
   DISALLOW_COPY_AND_ASSIGN(CreateViewTreeNodeTransaction);
 };
 
+class DestroyViewTreeNodeTransaction : public ViewManagerTransaction {
+ public:
+  DestroyViewTreeNodeTransaction(TransportNodeId node_id,
+                                 ViewManagerSynchronizer* synchronizer)
+      : ViewManagerTransaction(TYPE_DESTROY_VIEW_TREE_NODE, synchronizer),
+        node_id_(node_id) {}
+  virtual ~DestroyViewTreeNodeTransaction() {}
+
+ private:
+  // Overridden from ViewManagerTransaction:
+  virtual void DoCommit() OVERRIDE {
+    service()->DeleteNode(
+        node_id_,
+        change_id(),
+        base::Bind(&ViewManagerTransaction::OnActionCompleted,
+                   base::Unretained(this)));
+  }
+  virtual void DoActionCompleted(bool success) OVERRIDE {
+    // TODO(beng): recovery?
+  }
+
+  TransportNodeId node_id_;
+  DISALLOW_COPY_AND_ASSIGN(DestroyViewTreeNodeTransaction);
+};
+
 class HierarchyTransaction : public ViewManagerTransaction {
  public:
   enum HierarchyChangeType {
@@ -108,8 +136,8 @@
     TYPE_REMOVE
   };
   HierarchyTransaction(HierarchyChangeType hierarchy_change_type,
-                       uint16_t child_id,
-                       uint16_t parent_id,
+                       TransportNodeId child_id,
+                       TransportNodeId parent_id,
                        ViewManagerSynchronizer* synchronizer)
       : ViewManagerTransaction(TYPE_HIERARCHY, synchronizer),
         hierarchy_change_type_(hierarchy_change_type),
@@ -123,15 +151,15 @@
     switch (hierarchy_change_type_) {
       case TYPE_ADD:
         service()->AddNode(
-            MakeTransportId(parent_id_),
-            MakeTransportId(child_id_),
+            parent_id_,
+            child_id_,
             change_id(),
             base::Bind(&ViewManagerTransaction::OnActionCompleted,
                        base::Unretained(this)));
         break;
       case TYPE_REMOVE:
         service()->RemoveNodeFromParent(
-            MakeTransportId(child_id_),
+            child_id_,
             change_id(),
             base::Bind(&ViewManagerTransaction::OnActionCompleted,
                        base::Unretained(this)));
@@ -145,8 +173,8 @@
   }
 
   const HierarchyChangeType hierarchy_change_type_;
-  const uint16_t child_id_;
-  const uint16_t parent_id_;
+  const TransportNodeId child_id_;
+  const TransportNodeId parent_id_;
 
   DISALLOW_COPY_AND_ASSIGN(HierarchyTransaction);
 };
@@ -155,27 +183,47 @@
     : view_manager_(view_manager),
       connected_(false),
       connection_id_(0),
-      next_id_(0),
-      next_change_id_(0) {
+      next_id_(1),
+      next_change_id_(0),
+      init_loop_(NULL) {
   InterfacePipe<services::view_manager::IViewManager, AnyInterface>
       view_manager_pipe;
   AllocationScope scope;
+  MessagePipeHandle client_handle = view_manager_pipe.handle_to_peer.get();
   ViewManagerPrivate(view_manager_).shell()->Connect(
       "mojo:mojo_view_manager", view_manager_pipe.handle_to_peer.Pass());
   service_.reset(view_manager_pipe.handle_to_self.Pass(), this);
+  service_->GetNodeTree(
+      1,
+      base::Bind(&ViewManagerSynchronizer::OnRootTreeReceived,
+                 base::Unretained(this)));
+  base::RunLoop loop;
+  init_loop_ = &loop;
+  init_loop_->Run();
+  init_loop_ = NULL;
 }
 
 ViewManagerSynchronizer::~ViewManagerSynchronizer() {
 }
 
-uint16_t ViewManagerSynchronizer::CreateViewTreeNode() {
-  uint16_t id = next_id_++;
+TransportNodeId ViewManagerSynchronizer::CreateViewTreeNode() {
+  DCHECK(connected_);
+  uint16_t id = ++next_id_;
   pending_transactions_.push_back(new CreateViewTreeNodeTransaction(id, this));
   ScheduleSync();
-  return id;
+  return MakeTransportNodeId(connection_id_, id);
 }
 
-void ViewManagerSynchronizer::AddChild(uint16_t child_id, uint16_t parent_id) {
+void ViewManagerSynchronizer::DestroyViewTreeNode(TransportNodeId node_id) {
+  DCHECK(connected_);
+  pending_transactions_.push_back(
+      new DestroyViewTreeNodeTransaction(node_id, this));
+  ScheduleSync();
+}
+
+void ViewManagerSynchronizer::AddChild(TransportNodeId child_id,
+                                       TransportNodeId parent_id) {
+  DCHECK(connected_);
   pending_transactions_.push_back(
       new HierarchyTransaction(HierarchyTransaction::TYPE_ADD,
                                child_id,
@@ -184,8 +232,9 @@
   ScheduleSync();
 }
 
-void ViewManagerSynchronizer::RemoveChild(uint16_t child_id,
-                                          uint16_t parent_id) {
+void ViewManagerSynchronizer::RemoveChild(TransportNodeId child_id,
+                                          TransportNodeId parent_id) {
+  DCHECK(connected_);
   pending_transactions_.push_back(
       new HierarchyTransaction(HierarchyTransaction::TYPE_REMOVE,
                                child_id,
@@ -203,12 +252,29 @@
   ScheduleSync();
 }
 
-void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node,
-                                                     uint32_t new_parent,
-                                                     uint32_t old_parent,
+void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node_id,
+                                                     uint32_t new_parent_id,
+                                                     uint32_t old_parent_id,
                                                      uint32_t change_id) {
   if (change_id == 0) {
-    // TODO(beng): Apply changes from another client.
+    ViewTreeNode* new_parent =
+        view_manager_->tree()->GetChildById(new_parent_id);
+    ViewTreeNode* old_parent =
+        view_manager_->tree()->GetChildById(old_parent_id);
+    ViewTreeNode* node = NULL;
+    if (old_parent) {
+      // Existing node, mapped in this connection's tree.
+      // TODO(beng): verify this is actually true.
+      node = view_manager_->tree()->GetChildById(node_id);
+      DCHECK_EQ(node->parent(), old_parent);
+    } else {
+      // New node, originating from another connection.
+      node = new ViewTreeNode;
+      ViewTreeNodePrivate private_node(node);
+      private_node.set_view_manager(view_manager_);
+      private_node.set_id(node_id);
+    }
+    ViewTreeNodePrivate(new_parent).LocalAddChild(node);
   }
 }
 
@@ -256,6 +322,35 @@
   pending_transactions_.erase(pending_transactions_.begin());
 }
 
+void ViewManagerSynchronizer::OnRootTreeReceived(
+    const Array<INode>& nodes) {
+  std::vector<ViewTreeNode*> parents;
+  ViewTreeNode* root = NULL;
+  ViewTreeNode* last_node = NULL;
+  for (size_t i = 0; i < nodes.size(); ++i) {
+    if (last_node && nodes[i].parent_id() == last_node->id()) {
+      parents.push_back(last_node);
+    } else if (!parents.empty()) {
+      while (parents.back()->id() != nodes[i].parent_id())
+        parents.pop_back();
+    }
+    // We don't use the ctor that takes a ViewManager here, since it will call
+    // back to the service and attempt to create a new node.
+    ViewTreeNode* node = new ViewTreeNode;
+    ViewTreeNodePrivate private_node(node);
+    private_node.set_view_manager(view_manager_);
+    private_node.set_id(nodes[i].node_id());
+    if (!parents.empty())
+      ViewTreeNodePrivate(parents.back()).LocalAddChild(node);
+    if (!last_node)
+      root = node;
+    last_node = node;
+  }
+  ViewManagerPrivate(view_manager_).SetRoot(root);
+  if (init_loop_)
+    init_loop_->Quit();
+}
+
 }  // namespace view_manager
 }  // namespace services
 }  // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h
index 54da430..f161516 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h
@@ -8,8 +8,13 @@
 #include "base/basictypes.h"
 #include "base/memory/scoped_vector.h"
 #include "mojo/public/cpp/bindings/remote_ptr.h"
+#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
 
+namespace base {
+class RunLoop;
+}
+
 namespace mojo {
 namespace services {
 namespace view_manager {
@@ -23,11 +28,18 @@
   explicit ViewManagerSynchronizer(ViewManager* view_manager);
   virtual ~ViewManagerSynchronizer();
 
+  bool connected() const { return connected_; }
+
   // API exposed to the node implementation that pushes local changes to the
   // service.
-  uint16_t CreateViewTreeNode();
-  void AddChild(uint16_t child_id, uint16_t parent_id);
-  void RemoveChild(uint16_t child_id, uint16_t parent_id);
+  TransportNodeId CreateViewTreeNode();
+  void DestroyViewTreeNode(TransportNodeId node_id);
+
+  // These methods take TransportIds. For views owned by the current connection,
+  // the connection id high word can be zero. In all cases, the TransportId 0x1
+  // refers to the root node.
+  void AddChild(TransportNodeId child_id, TransportNodeId parent_id);
+  void RemoveChild(TransportNodeId child_id, TransportNodeId parent_id);
 
  private:
   friend class ViewManagerTransaction;
@@ -35,14 +47,14 @@
 
   // Overridden from IViewManagerClient:
   virtual void OnConnectionEstablished(uint16 connection_id) OVERRIDE;
-  virtual void OnNodeHierarchyChanged(uint32 node,
-                                      uint32 new_parent,
-                                      uint32 old_parent,
+  virtual void OnNodeHierarchyChanged(uint32 node_id,
+                                      uint32 new_parent_id,
+                                      uint32 old_parent_id,
                                       uint32 change_id) OVERRIDE;
-  virtual void OnNodeViewReplaced(uint32_t node,

-                                  uint32_t new_view_id,

-                                  uint32_t old_view_id,

-                                  uint32_t change_id) OVERRIDE;

+  virtual void OnNodeViewReplaced(uint32_t node,
+                                  uint32_t new_view_id,
+                                  uint32_t old_view_id,
+                                  uint32_t change_id) OVERRIDE;
 
   // Called to schedule a sync of the client model with the service after a
   // return to the message loop.
@@ -62,6 +74,8 @@
   // front of the queue.
   void RemoveFromPendingQueue(ViewManagerTransaction* transaction);
 
+  void OnRootTreeReceived(const Array<INode>& data);
+
   ViewManager* view_manager_;
   bool connected_;
   uint16_t connection_id_;
@@ -70,6 +84,10 @@
 
   Transactions pending_transactions_;
 
+  // Non-NULL while blocking on the connection to |service_| during
+  // construction.
+  base::RunLoop* init_loop_;
+
   RemotePtr<IViewManager> service_;
 
   DISALLOW_COPY_AND_ASSIGN(ViewManagerSynchronizer);
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.cc
new file mode 100644
index 0000000..fdd4efd
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.cc
@@ -0,0 +1,26 @@
+// 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.
+
+#include "mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.h"
+
+#include "ui/gl/gl_surface.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+ViewManagerTestSuite::ViewManagerTestSuite(int argc, char** argv)
+    : TestSuite(argc, argv) {}
+
+ViewManagerTestSuite::~ViewManagerTestSuite() {
+}
+
+void ViewManagerTestSuite::Initialize() {
+  base::TestSuite::Initialize();
+  gfx::GLSurface::InitializeOneOffForTests();
+}
+
+}  // namespace view_manager
+}  // namespace services
+}  // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.h b/mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.h
new file mode 100644
index 0000000..5fea707
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.h
@@ -0,0 +1,30 @@
+// 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.
+
+#ifndef MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_MANAGER_TEST_SUITE_H_
+#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_MANAGER_TEST_SUITE_H_
+
+#include "base/test/test_suite.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class ViewManagerTestSuite : public base::TestSuite {
+ public:
+  ViewManagerTestSuite(int argc, char** argv);
+  virtual ~ViewManagerTestSuite();
+
+ protected:
+  virtual void Initialize() OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ViewManagerTestSuite);
+};
+
+}  // namespace view_manager
+}  // namespace services
+}  // namespace mojo
+
+#endif  // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_MANAGER_TEST_SUITE_H_
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_unittests.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_unittests.cc
new file mode 100644
index 0000000..03f7919
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_unittests.cc
@@ -0,0 +1,14 @@
+// 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.
+
+#include "base/bind.h"
+#include "base/test/launcher/unit_test_launcher.h"
+#include "mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.h"
+
+int main(int argc, char** argv) {
+  mojo::services::view_manager::ViewManagerTestSuite test_suite(argc, argv);
+
+  return base::LaunchUnitTests(
+      argc, argv, base::Bind(&TestSuite::Run, base::Unretained(&test_suite)));
+}
diff --git a/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc b/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
index d695ed4..33d90a9 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
@@ -118,6 +118,8 @@
   if (parent_)
     parent_->RemoveChild(this);
 
+  if (manager_)
+    ViewManagerPrivate(manager_).synchronizer()->DestroyViewTreeNode(id_);
 }
 
 void ViewTreeNode::AddObserver(ViewTreeNodeObserver* observer) {
@@ -129,19 +131,15 @@
 }
 
 void ViewTreeNode::AddChild(ViewTreeNode* child) {
-  ScopedTreeNotifier notifier(child, child->parent(), this);
-  if (child->parent())
-    RemoveChildImpl(child, &child->parent_->children_);
-  children_.push_back(child);
-  child->parent_ = this;
-  ViewManagerPrivate(manager_).synchronizer()->AddChild(child->id(), id_);
+  LocalAddChild(child);
+  if (manager_)
+    ViewManagerPrivate(manager_).synchronizer()->AddChild(child->id(), id_);
 }
 
 void ViewTreeNode::RemoveChild(ViewTreeNode* child) {
-  DCHECK_EQ(this, child->parent());
-  ScopedTreeNotifier(child, this, NULL);
-  RemoveChildImpl(child, &children_);
-  ViewManagerPrivate(manager_).synchronizer()->RemoveChild(child->id(), id_);
+  LocalRemoveChild(child);
+  if (manager_)
+    ViewManagerPrivate(manager_).synchronizer()->RemoveChild(child->id(), id_);
 }
 
 bool ViewTreeNode::Contains(ViewTreeNode* child) const {
@@ -152,6 +150,36 @@
   return false;
 }
 
+ViewTreeNode* ViewTreeNode::GetChildById(TransportNodeId id) {
+  if (id == id_)
+    return this;
+  // TODO(beng): this could be improved depending on how we decide to own nodes.
+  Children::const_iterator it = children_.begin();
+  for (; it != children_.end(); ++it) {
+    ViewTreeNode* node = (*it)->GetChildById(id);
+    if (node)
+      return node;
+  }
+  return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ViewTreeNode, private:
+
+void ViewTreeNode::LocalAddChild(ViewTreeNode* child) {
+  ScopedTreeNotifier notifier(child, child->parent(), this);
+  if (child->parent())
+    RemoveChildImpl(child, &child->parent_->children_);
+  children_.push_back(child);
+  child->parent_ = this;
+}
+
+void ViewTreeNode::LocalRemoveChild(ViewTreeNode* child) {
+  DCHECK_EQ(this, child->parent());
+  ScopedTreeNotifier(child, this, NULL);
+  RemoveChildImpl(child, &children_);
+}
+
 }  // namespace view_manager
 }  // namespace services
 }  // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h b/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h
index 33be9f0..366dbd8 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h
+++ b/mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h
@@ -24,6 +24,17 @@
 
   void ClearParent() { node_->parent_ = NULL; }
 
+  void set_id(TransportNodeId id) { node_->id_ = id; }
+
+  ViewManager* view_manager() { return node_->manager_; }
+  void set_view_manager(ViewManager* manager) {
+    node_->manager_ = manager;
+  }
+
+  void LocalAddChild(ViewTreeNode* child) {
+    node_->LocalAddChild(child);
+  }
+
  private:
   ViewTreeNode* node_;
 
diff --git a/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
index e69de29..94dfe1f 100644
--- a/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
+++ b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
@@ -0,0 +1,208 @@
+// 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.
+
+#include "mojo/services/public/cpp/view_manager/view_manager.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
+#include "mojo/services/public/cpp/view_manager/util.h"
+#include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h"
+#include "mojo/shell/shell_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+base::RunLoop* current_run_loop = NULL;
+
+void DoRunLoop() {
+  base::RunLoop run_loop;
+  current_run_loop = &run_loop;
+  current_run_loop->Run();
+  current_run_loop = NULL;
+}
+
+void QuitRunLoop() {
+  current_run_loop->Quit();
+}
+
+// ViewManager -----------------------------------------------------------------
+
+class ViewManagerTest : public testing::Test {
+ public:
+  ViewManagerTest() : commit_count_(0) {}
+
+ protected:
+  ViewManager* view_manager_1() { return view_manager_1_.get(); }
+  ViewManager* view_manager_2() { return view_manager_2_.get(); }
+
+  scoped_ptr<ViewTreeNode> CreateNodeInParent(ViewTreeNode* parent) {
+    ViewManager* parent_manager = ViewTreeNodePrivate(parent).view_manager();
+    scoped_ptr<ViewTreeNode> node(new ViewTreeNode(parent_manager));
+    parent->AddChild(node.get());
+    return node.Pass();
+  }
+
+ private:
+  // Overridden from testing::Test:
+  virtual void SetUp() OVERRIDE {
+    test_helper_.Init();
+    view_manager_1_.reset(new ViewManager(test_helper_.shell()));
+    view_manager_2_.reset(new ViewManager(test_helper_.shell()));
+    view_manager_1_->Init();
+    view_manager_2_->Init();
+  }
+
+  base::MessageLoop loop_;
+  shell::ShellTestHelper test_helper_;
+  scoped_ptr<ViewManager> view_manager_1_;
+  scoped_ptr<ViewManager> view_manager_2_;
+  int commit_count_;
+
+  DISALLOW_COPY_AND_ASSIGN(ViewManagerTest);
+};
+
+// Base class for helpers that quit the current runloop after a specific tree
+// change is observed by a view manager.
+class TreeObserverBase : public ViewTreeNodeObserver {
+ public:
+  explicit TreeObserverBase(ViewManager* view_manager)
+      : view_manager_(view_manager) {
+    view_manager_->tree()->AddObserver(this);
+  }
+  virtual ~TreeObserverBase() {
+    view_manager_->tree()->RemoveObserver(this);
+  }
+
+ protected:
+  virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) = 0;
+
+  ViewManager* view_manager() { return view_manager_; }
+
+ private:
+  // Overridden from ViewTreeNodeObserver:
+  virtual void OnTreeChange(const TreeChangeParams& params) OVERRIDE {
+    if (params.phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
+      return;
+    if (ShouldQuitRunLoop(params))
+      QuitRunLoop();
+  }
+
+  ViewManager* view_manager_;
+  DISALLOW_COPY_AND_ASSIGN(TreeObserverBase);
+};
+
+// Spins a runloop until the tree beginning at |root| has |tree_size| nodes
+// (including |root|).
+class TreeSizeMatchesWaiter : public TreeObserverBase {
+ public:
+  TreeSizeMatchesWaiter(ViewManager* view_manager, size_t tree_size)
+      : TreeObserverBase(view_manager),
+        tree_size_(tree_size) {
+    DoRunLoop();
+  }
+  virtual ~TreeSizeMatchesWaiter() {}
+
+ private:
+  // Overridden from TreeObserverBase:
+  virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE {
+    return CountNodes(view_manager()->tree()) == tree_size_;
+  }
+
+  size_t CountNodes(ViewTreeNode* node) const {
+    size_t count = 1;
+    ViewTreeNode::Children::const_iterator it = node->children().begin();
+    for (; it != node->children().end(); ++it)
+      count += CountNodes(*it);
+    return count;
+  }
+
+  size_t tree_size_;
+  DISALLOW_COPY_AND_ASSIGN(TreeSizeMatchesWaiter);
+};
+
+
+class HierarchyChanged_NodeCreatedObserver : public TreeObserverBase {
+ public:
+  explicit HierarchyChanged_NodeCreatedObserver(ViewManager* view_manager)
+      : TreeObserverBase(view_manager) {}
+  virtual ~HierarchyChanged_NodeCreatedObserver() {}
+
+ private:
+  // Overridden from TreeObserverBase:
+  virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE {
+    return params.receiver == view_manager()->tree() &&
+        !params.old_parent &&
+        params.new_parent == view_manager()->tree();
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(HierarchyChanged_NodeCreatedObserver);
+};
+
+TEST_F(ViewManagerTest, HierarchyChanged_NodeCreated) {
+  HierarchyChanged_NodeCreatedObserver observer(view_manager_2());
+  scoped_ptr<ViewTreeNode> node1(new ViewTreeNode(view_manager_1()));
+  view_manager_1()->tree()->AddChild(node1.get());
+  DoRunLoop();
+
+  EXPECT_EQ(view_manager_2()->tree()->children().front()->id(), node1->id());
+}
+
+// Quits the current runloop when the root is notified about a node moved from
+// |old_parent_id| to |new_parent_id|.
+class HierarchyChanged_NodeMovedObserver : public TreeObserverBase {
+ public:
+  HierarchyChanged_NodeMovedObserver(ViewManager* view_manager,
+                                     TransportNodeId old_parent_id,
+                                     TransportNodeId new_parent_id)
+      : TreeObserverBase(view_manager),
+        old_parent_id_(old_parent_id),
+        new_parent_id_(new_parent_id) {}
+  virtual ~HierarchyChanged_NodeMovedObserver() {}
+
+ private:
+  // Overridden from TreeObserverBase:
+  virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE {
+    return params.receiver == view_manager()->tree() &&
+        params.old_parent->id() == old_parent_id_&&
+        params.new_parent->id() == new_parent_id_;
+  }
+
+  TransportNodeId old_parent_id_;
+  TransportNodeId new_parent_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(HierarchyChanged_NodeMovedObserver);
+};
+
+TEST_F(ViewManagerTest, HierarchyChanged_NodeMoved) {
+  scoped_ptr<ViewTreeNode> node1(CreateNodeInParent(view_manager_1()->tree()));
+  scoped_ptr<ViewTreeNode> node2(CreateNodeInParent(view_manager_1()->tree()));
+  scoped_ptr<ViewTreeNode> node21(CreateNodeInParent(node2.get()));
+  TreeSizeMatchesWaiter waiter(view_manager_2(), 4);
+
+  HierarchyChanged_NodeMovedObserver observer(view_manager_2(),
+                                              node2->id(),
+                                              node1->id());
+
+  node1->AddChild(node21.get());
+  DoRunLoop();
+
+  ViewTreeNode* tree2 = view_manager_2()->tree();
+
+  EXPECT_EQ(tree2->children().size(), 2u);
+  ViewTreeNode* tree2_node1 = tree2->GetChildById(node1->id());
+  EXPECT_EQ(tree2_node1->children().size(), 1u);
+  ViewTreeNode* tree2_node2 = tree2->GetChildById(node2->id());
+  EXPECT_TRUE(tree2_node2->children().empty());
+  ViewTreeNode* tree2_node21 = tree2->GetChildById(node21->id());
+  EXPECT_EQ(tree2_node21->parent(), tree2_node1);
+}
+
+// TODO(beng): node destruction
+
+}  // namespace view_manager
+}  // namespace services
+}  // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc
index 54349ee..3425044 100644
--- a/mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc
+++ b/mojo/services/public/cpp/view_manager/tests/view_tree_node_unittest.cc
@@ -5,6 +5,7 @@
 #include "mojo/services/public/cpp/view_manager/view_tree_node.h"
 
 #include "base/logging.h"
+#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
 #include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -57,6 +58,21 @@
   EXPECT_TRUE(v1.Contains(v111));
 }
 
+TEST_F(ViewTreeNodeTest, GetChildById) {
+  ViewTreeNode v1;
+  ViewTreeNodePrivate(&v1).set_id(1);
+  ViewTreeNode v11;
+  ViewTreeNodePrivate(&v11).set_id(11);
+  v1.AddChild(&v11);
+  ViewTreeNode v111;
+  ViewTreeNodePrivate(&v111).set_id(111);
+  v11.AddChild(&v111);
+
+  // Find direct & indirect descendents.
+  EXPECT_EQ(&v11, v1.GetChildById(v11.id()));
+  EXPECT_EQ(&v111, v1.GetChildById(v111.id()));
+}
+
 // ViewTreeNodeObserver --------------------------------------------------------
 
 typedef testing::Test ViewTreeNodeObserverTest;
diff --git a/mojo/services/public/cpp/view_manager/util.h b/mojo/services/public/cpp/view_manager/util.h
new file mode 100644
index 0000000..569bf08
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/util.h
@@ -0,0 +1,26 @@
+// 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.
+
+#ifndef MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_UTIL_H_
+#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_UTIL_H_
+
+#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+inline uint16_t HiWord(uint32_t id) {
+  return static_cast<uint16_t>((id >> 16) & 0xFFFF);
+}
+
+inline uint16_t LoWord(uint32_t id) {
+  return static_cast<uint16_t>(id & 0xFFFF);
+}
+
+}  // namespace view_manager
+}  // namespace services
+}  // namespace mojo
+
+#endif  // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_UTIL_H_
diff --git a/mojo/services/public/cpp/view_manager/view_manager.h b/mojo/services/public/cpp/view_manager/view_manager.h
index fb492ec..629a933 100644
--- a/mojo/services/public/cpp/view_manager/view_manager.h
+++ b/mojo/services/public/cpp/view_manager/view_manager.h
@@ -7,6 +7,8 @@
 
 #include "base/basictypes.h"
 #include "base/memory/scoped_ptr.h"
+#include "mojo/public/cpp/bindings/callback.h"
+#include "mojo/services/public/cpp/view_manager/view_tree_node.h"
 
 namespace mojo {
 class Shell;
@@ -14,6 +16,7 @@
 namespace view_manager {
 
 class ViewManagerSynchronizer;
+class ViewTreeNode;
 
 // Approximately encapsulates the View Manager service.
 // Owns a synchronizer that keeps a client model in sync with the service.
@@ -25,11 +28,25 @@
   explicit ViewManager(Shell* shell);
   ~ViewManager();
 
+  // Connects to the View Manager service. This method must be called before
+  // using any other View Manager lib class or function.
+  // Blocks on establishing the connection and subsequently receiving a node
+  // tree from the service.
+  // TODO(beng): blocking is currently achieved by running a nested runloop,
+  //             which will dispatch all messages on all pipes while blocking.
+  //             we should instead wait on the client pipe receiving a
+  //             connection established message.
+  // TODO(beng): this method could optionally not block if supplied a callback.
+  void Init();
+
+  ViewTreeNode* tree() { return tree_.get(); }
+
  private:
   friend class ViewManagerPrivate;
 
   Shell* shell_;
   scoped_ptr<ViewManagerSynchronizer> synchronizer_;
+  scoped_ptr<ViewTreeNode> tree_;
 
   DISALLOW_COPY_AND_ASSIGN(ViewManager);
 };
diff --git a/mojo/services/public/cpp/view_manager/view_manager_types.h b/mojo/services/public/cpp/view_manager/view_manager_types.h
new file mode 100644
index 0000000..328b2ea
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/view_manager_types.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_MANAGER_TYPES_H_
+#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_MANAGER_TYPES_H_
+
+#include "base/basictypes.h"
+
+// Typedefs for the transport types. These typedefs match that of the mojom
+// file, see it for specifics.
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+typedef uint32_t TransportChangeId;
+typedef uint16_t TransportConnectionId;
+typedef uint32_t TransportNodeId;
+typedef uint32_t TransportViewId;
+
+// These types are used in two cases:
+// 1. when a connection is creating a node/view. In this case the connection id
+//    from the current connection is used, so no need to explicitly specific it.
+// 2. When the connection id is stored along side this.
+typedef uint16_t TransportConnectionSpecificNodeId;
+typedef uint16_t TransportConnectionSpecificViewId;
+
+}  // namespace view_manager
+}  // namespace services
+}  // namespace mojo
+
+#endif  // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_MANAGER_TYPES_H_
diff --git a/mojo/services/public/cpp/view_manager/view_tree_node.h b/mojo/services/public/cpp/view_manager/view_tree_node.h
index d187c66..280aaf8 100644
--- a/mojo/services/public/cpp/view_manager/view_tree_node.h
+++ b/mojo/services/public/cpp/view_manager/view_tree_node.h
@@ -9,6 +9,7 @@
 
 #include "base/basictypes.h"
 #include "base/observer_list.h"
+#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
 
 namespace mojo {
 namespace services {
@@ -26,7 +27,7 @@
   ~ViewTreeNode();
 
   // Configuration.
-  uint16_t id() const { return id_; }
+  TransportNodeId id() const { return id_; }
   void set_owned_by_parent(bool owned_by_parent) {
     owned_by_parent_ = owned_by_parent;
   }
@@ -45,11 +46,16 @@
 
   bool Contains(ViewTreeNode* child) const;
 
+  ViewTreeNode* GetChildById(TransportNodeId id);
+
  private:
   friend class ViewTreeNodePrivate;
 
+  void LocalAddChild(ViewTreeNode* child);
+  void LocalRemoveChild(ViewTreeNode* child);
+
   ViewManager* manager_;
-  uint16_t id_;
+  TransportNodeId id_;
   bool owned_by_parent_;
   ViewTreeNode* parent_;
   Children children_;
diff --git a/mojo/services/public/interfaces/view_manager/view_manager.mojom b/mojo/services/public/interfaces/view_manager/view_manager.mojom
index 173fa31..1636a6a 100644
--- a/mojo/services/public/interfaces/view_manager/view_manager.mojom
+++ b/mojo/services/public/interfaces/view_manager/view_manager.mojom
@@ -53,6 +53,11 @@
 
   // Sets the view a node is showing.
   SetView(uint32 node_id, uint32 view_id, uint32 change_id) => (bool success);
+
+  // Shows the specified image (png encoded) in the specified view.
+  SetViewContents(uint32 view_id,
+                  handle<shared_buffer> buffer,
+                  uint32 buffer_size);
 };
 
 [Peer=IViewManager]
diff --git a/mojo/services/view_manager/DEPS b/mojo/services/view_manager/DEPS
index 05af088..248384f 100644
--- a/mojo/services/view_manager/DEPS
+++ b/mojo/services/view_manager/DEPS
@@ -1,6 +1,11 @@
 include_rules = [
+  "+mojo/aura",
   "+mojo/services",
+  "+third_party/skia",
   "+ui/aura",
+  "+ui/base/cursor/cursor.h",
+  "+ui/base/hit_test.h",
   "+ui/events",
   "+ui/gfx",
+  "+ui/gl",
 ]
diff --git a/mojo/services/view_manager/ids.h b/mojo/services/view_manager/ids.h
index 11ffc35..66efba3 100644
--- a/mojo/services/view_manager/ids.h
+++ b/mojo/services/view_manager/ids.h
@@ -5,17 +5,18 @@
 #ifndef MOJO_SERVICES_VIEW_MANAGER_IDS_H_
 #define MOJO_SERVICES_VIEW_MANAGER_IDS_H_
 
+#include "mojo/services/public/cpp/view_manager/util.h"
+#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
 #include "mojo/services/view_manager/view_manager_export.h"
 
 namespace mojo {
 namespace services {
 namespace view_manager {
 
-typedef uint32_t ChangeId;
-
 // Adds a bit of type safety to node ids.
 struct MOJO_VIEW_MANAGER_EXPORT NodeId {
-  NodeId(uint16_t connection_id, uint16_t node_id)
+  NodeId(TransportConnectionId connection_id,
+         TransportConnectionSpecificNodeId node_id)
       : connection_id(connection_id),
         node_id(node_id) {}
   NodeId() : connection_id(0), node_id(0) {}
@@ -29,13 +30,14 @@
     return !(*this == other);
   }
 
-  uint16_t connection_id;
-  uint16_t node_id;
+  TransportConnectionId connection_id;
+  TransportConnectionSpecificNodeId node_id;
 };
 
 // Adds a bit of type safety to view ids.
 struct MOJO_VIEW_MANAGER_EXPORT ViewId {
-  ViewId(uint16_t connection_id, uint16_t view_id)
+  ViewId(TransportConnectionId connection_id,
+         TransportConnectionSpecificViewId view_id)
       : connection_id(connection_id),
         view_id(view_id) {}
   ViewId() : connection_id(0), view_id(0) {}
@@ -49,32 +51,24 @@
     return !(*this == other);
   }
 
-  uint16_t connection_id;
-  uint16_t view_id;
+  TransportConnectionId connection_id;
+  TransportConnectionSpecificViewId view_id;
 };
 
 // Functions for converting to/from structs and transport values.
-inline uint16_t FirstIdFromTransportId(uint32_t id) {
-  return static_cast<uint16_t>((id >> 16) & 0xFFFF);
+inline NodeId NodeIdFromTransportId(TransportNodeId id) {
+  return NodeId(HiWord(id), LoWord(id));
 }
 
-inline uint16_t SecondIdFromTransportId(uint32_t id) {
-  return static_cast<uint16_t>(id & 0xFFFF);
-}
-
-inline NodeId NodeIdFromTransportId(uint32_t id) {
-  return NodeId(FirstIdFromTransportId(id), SecondIdFromTransportId(id));
-}
-
-inline uint32_t NodeIdToTransportId(const NodeId& id) {
+inline TransportNodeId NodeIdToTransportId(const NodeId& id) {
   return (id.connection_id << 16) | id.node_id;
 }
 
-inline ViewId ViewIdFromTransportId(uint32_t id) {
-  return ViewId(FirstIdFromTransportId(id), SecondIdFromTransportId(id));
+inline ViewId ViewIdFromTransportId(TransportViewId id) {
+  return ViewId(HiWord(id), LoWord(id));
 }
 
-inline uint32_t ViewIdToTransportId(const ViewId& id) {
+inline TransportViewId ViewIdToTransportId(const ViewId& id) {
   return (id.connection_id << 16) | id.view_id;
 }
 
diff --git a/mojo/services/view_manager/main.cc b/mojo/services/view_manager/main.cc
new file mode 100644
index 0000000..1fd4528
--- /dev/null
+++ b/mojo/services/view_manager/main.cc
@@ -0,0 +1,36 @@
+// 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.
+
+#include "base/at_exit.h"
+#include "base/command_line.h"
+#include "base/message_loop/message_loop.h"
+#include "mojo/public/cpp/shell/application.h"
+#include "mojo/services/view_manager/root_node_manager.h"
+#include "mojo/services/view_manager/view_manager_connection.h"
+
+#if defined(WIN32)
+#if !defined(CDECL)
+#define CDECL __cdecl)
+#endif
+#define VIEW_MANAGER_EXPORT __declspec(dllexport)
+#else
+#define CDECL
+#define VIEW_MANAGER_EXPORT __attribute__((visibility("default")))
+#endif
+
+extern "C" VIEW_MANAGER_EXPORT MojoResult CDECL MojoMain(
+    MojoHandle shell_handle) {
+  CommandLine::Init(0, NULL);
+  base::AtExitManager at_exit;
+  base::MessageLoop loop;
+  mojo::Application app(shell_handle);
+  mojo::services::view_manager::RootNodeManager root_node_manager(app.shell());
+  app.AddServiceConnector(new mojo::ServiceConnector
+                          <mojo::services::view_manager::ViewManagerConnection,
+                           mojo::services::view_manager::RootNodeManager>(
+                               &root_node_manager));
+  loop.Run();
+
+  return MOJO_RESULT_OK;
+}
diff --git a/mojo/services/view_manager/node.cc b/mojo/services/view_manager/node.cc
index e2436da..5f5af51 100644
--- a/mojo/services/view_manager/node.cc
+++ b/mojo/services/view_manager/node.cc
@@ -7,6 +7,11 @@
 #include "mojo/services/view_manager/node_delegate.h"
 #include "mojo/services/view_manager/view.h"
 #include "ui/aura/window_property.h"
+#include "ui/base/cursor/cursor.h"
+#include "ui/base/hit_test.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/native_widget_types.h"
 
 DECLARE_WINDOW_PROPERTY_TYPE(mojo::services::view_manager::Node*);
 
@@ -20,11 +25,15 @@
     : delegate_(delegate),
       id_(id),
       view_(NULL),
-      window_(NULL) {
+      window_(this) {
   DCHECK(delegate);  // Must provide a delegate.
   window_.set_owned_by_parent(false);
   window_.AddObserver(this);
   window_.SetProperty(kNodeKey, this);
+  window_.Init(aura::WINDOW_LAYER_TEXTURED);
+
+  // TODO(sky): this likely needs to be false and add a visibility API.
+  window_.Show();
 }
 
 Node::~Node() {
@@ -80,14 +89,73 @@
   if (params.target != &window_ || params.receiver != &window_)
     return;
   NodeId new_parent_id;
-  if (params.new_parent)
+  if (params.new_parent && params.new_parent->GetProperty(kNodeKey))
     new_parent_id = params.new_parent->GetProperty(kNodeKey)->id();
   NodeId old_parent_id;
-  if (params.old_parent)
+  if (params.old_parent && params.old_parent->GetProperty(kNodeKey))
     old_parent_id = params.old_parent->GetProperty(kNodeKey)->id();
   delegate_->OnNodeHierarchyChanged(id_, new_parent_id, old_parent_id);
 }
 
+gfx::Size Node::GetMinimumSize() const {
+  return gfx::Size();
+}
+
+gfx::Size Node::GetMaximumSize() const {
+  return gfx::Size();
+}
+
+void Node::OnBoundsChanged(const gfx::Rect& old_bounds,
+                           const gfx::Rect& new_bounds) {
+}
+
+gfx::NativeCursor Node::GetCursor(const gfx::Point& point) {
+  return gfx::kNullCursor;
+}
+
+int Node::GetNonClientComponent(const gfx::Point& point) const {
+  return HTCAPTION;
+}
+
+bool Node::ShouldDescendIntoChildForEventHandling(
+    aura::Window* child,
+    const gfx::Point& location) {
+  return true;
+}
+
+bool Node::CanFocus() {
+  return true;
+}
+
+void Node::OnCaptureLost() {
+}
+
+void Node::OnPaint(gfx::Canvas* canvas) {
+  if (view_) {
+    canvas->DrawImageInt(
+        gfx::ImageSkia::CreateFrom1xBitmap(view_->bitmap()), 0, 0);
+  }
+}
+
+void Node::OnDeviceScaleFactorChanged(float device_scale_factor) {
+}
+
+void Node::OnWindowDestroying(aura::Window* window) {
+}
+
+void Node::OnWindowDestroyed(aura::Window* window) {
+}
+
+void Node::OnWindowTargetVisibilityChanged(bool visible) {
+}
+
+bool Node::HasHitTestMask() const {
+  return false;
+}
+
+void Node::GetHitTestMask(gfx::Path* mask) const {
+}
+
 }  // namespace view_manager
 }  // namespace services
 }  // namespace mojo
diff --git a/mojo/services/view_manager/node.h b/mojo/services/view_manager/node.h
index ed68874..d1b65ae 100644
--- a/mojo/services/view_manager/node.h
+++ b/mojo/services/view_manager/node.h
@@ -11,6 +11,7 @@
 #include "mojo/services/view_manager/ids.h"
 #include "mojo/services/view_manager/view_manager_export.h"
 #include "ui/aura/window.h"
+#include "ui/aura/window_delegate.h"
 #include "ui/aura/window_observer.h"
 
 namespace mojo {
@@ -21,7 +22,9 @@
 class View;
 
 // Represents a node in the graph. Delegate is informed of interesting events.
-class MOJO_VIEW_MANAGER_EXPORT Node : public aura::WindowObserver {
+class MOJO_VIEW_MANAGER_EXPORT Node
+    : public aura::WindowObserver,
+      public aura::WindowDelegate {
  public:
   Node(NodeDelegate* delegate, const NodeId& id);
   virtual ~Node();
@@ -34,6 +37,8 @@
   void Add(Node* child);
   void Remove(Node* child);
 
+  aura::Window* window() { return &window_; }
+
   Node* GetParent();
 
   std::vector<Node*> GetChildren();
@@ -47,6 +52,26 @@
   virtual void OnWindowHierarchyChanged(
       const aura::WindowObserver::HierarchyChangeParams& params) OVERRIDE;
 
+  // WindowDelegate overrides:
+  virtual gfx::Size GetMinimumSize() const OVERRIDE;
+  virtual gfx::Size GetMaximumSize() const OVERRIDE;
+  virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
+                               const gfx::Rect& new_bounds) OVERRIDE;
+  virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE;
+  virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE;
+  virtual bool ShouldDescendIntoChildForEventHandling(
+      aura::Window* child,
+      const gfx::Point& location) OVERRIDE;
+  virtual bool CanFocus() OVERRIDE;
+  virtual void OnCaptureLost() OVERRIDE;
+  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
+  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
+  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
+  virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
+  virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE;
+  virtual bool HasHitTestMask() const OVERRIDE;
+  virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE;
+
   NodeDelegate* delegate_;
   const NodeId id_;
 
diff --git a/mojo/services/view_manager/root_node_manager.cc b/mojo/services/view_manager/root_node_manager.cc
index 6c2bf6d..529306d 100644
--- a/mojo/services/view_manager/root_node_manager.cc
+++ b/mojo/services/view_manager/root_node_manager.cc
@@ -6,6 +6,7 @@
 
 #include "base/logging.h"
 #include "mojo/services/view_manager/view_manager_connection.h"
+#include "ui/aura/env.h"
 
 namespace mojo {
 namespace services {
@@ -13,13 +14,21 @@
 namespace {
 
 // Id for the root node.
-const uint16_t kRootId = 1;
+const TransportConnectionSpecificNodeId kRootId = 1;
 
 }  // namespace
 
+RootNodeManager::Context::Context() {
+  // Pass in false as native viewport creates the PlatformEventSource.
+  aura::Env::CreateInstance(false);
+}
+
+RootNodeManager::Context::~Context() {
+}
+
 RootNodeManager::ScopedChange::ScopedChange(ViewManagerConnection* connection,
                                             RootNodeManager* root,
-                                            ChangeId change_id)
+                                            TransportChangeId change_id)
     : root_(root) {
   root_->PrepareForChange(connection, change_id);
 }
@@ -28,16 +37,19 @@
   root_->FinishChange();
 }
 
-RootNodeManager::RootNodeManager()
+RootNodeManager::RootNodeManager(Shell* shell)
     : next_connection_id_(1),
+      root_view_manager_(shell, this),
       root_(this, NodeId(0, kRootId)) {
 }
 
 RootNodeManager::~RootNodeManager() {
+  // All the connections should have been destroyed.
+  DCHECK(connection_map_.empty());
 }
 
-uint16_t RootNodeManager::GetAndAdvanceNextConnectionId() {
-  const uint16_t id = next_connection_id_++;
+TransportConnectionId RootNodeManager::GetAndAdvanceNextConnectionId() {
+  const TransportConnectionId id = next_connection_id_++;
   DCHECK_LT(id, next_connection_id_);
   return id;
 }
@@ -51,7 +63,8 @@
   connection_map_.erase(connection->id());
 }
 
-ViewManagerConnection* RootNodeManager::GetConnection(uint16_t connection_id) {
+ViewManagerConnection* RootNodeManager::GetConnection(
+    TransportConnectionId connection_id) {
   ConnectionMap::iterator i = connection_map_.find(connection_id);
   return i == connection_map_.end() ? NULL : i->second;
 }
@@ -73,7 +86,8 @@
                                                  const NodeId& old_parent) {
   for (ConnectionMap::iterator i = connection_map_.begin();
        i != connection_map_.end(); ++i) {
-    const ChangeId change_id = (change_ && i->first == change_->connection_id) ?
+    const TransportChangeId change_id =
+        (change_ && i->first == change_->connection_id) ?
         change_->change_id : 0;
     i->second->NotifyNodeHierarchyChanged(
         node, new_parent, old_parent, change_id);
@@ -81,12 +95,13 @@
 }
 
 void RootNodeManager::NotifyNodeViewReplaced(const NodeId& node,
-                                            const ViewId& new_view_id,
-                                            const ViewId& old_view_id) {
+                                             const ViewId& new_view_id,
+                                             const ViewId& old_view_id) {
   // TODO(sky): make a macro for this.
   for (ConnectionMap::iterator i = connection_map_.begin();
        i != connection_map_.end(); ++i) {
-    const ChangeId change_id = (change_ && i->first == change_->connection_id) ?
+    const TransportChangeId change_id =
+        (change_ && i->first == change_->connection_id) ?
         change_->change_id : 0;
     i->second->NotifyNodeViewReplaced(node, new_view_id, old_view_id,
                                       change_id);
@@ -94,7 +109,7 @@
 }
 
 void RootNodeManager::PrepareForChange(ViewManagerConnection* connection,
-                                       ChangeId change_id) {
+                                       TransportChangeId change_id) {
   DCHECK(!change_.get());  // Should only ever have one change in flight.
   change_.reset(new Change(connection->id(), change_id));
 }
@@ -104,24 +119,11 @@
   change_.reset();
 }
 
-void RootNodeManager::OnCreated() {
-}
-
-void RootNodeManager::OnDestroyed() {
-}
-
-void RootNodeManager::OnBoundsChanged(const Rect& bounds) {
-}
-
-void RootNodeManager::OnEvent(const Event& event,
-                              const mojo::Callback<void()>& callback) {
-  callback.Run();
-}
-
 void RootNodeManager::OnNodeHierarchyChanged(const NodeId& node,
                                              const NodeId& new_parent,
                                              const NodeId& old_parent) {
-  NotifyNodeHierarchyChanged(node, new_parent, old_parent);
+  if (!root_view_manager_.in_setup())
+    NotifyNodeHierarchyChanged(node, new_parent, old_parent);
 }
 
 void RootNodeManager::OnNodeViewReplaced(const NodeId& node,
diff --git a/mojo/services/view_manager/root_node_manager.h b/mojo/services/view_manager/root_node_manager.h
index f9d1d97..91aa8e7 100644
--- a/mojo/services/view_manager/root_node_manager.h
+++ b/mojo/services/view_manager/root_node_manager.h
@@ -8,12 +8,16 @@
 #include <map>
 
 #include "base/basictypes.h"
-#include "mojo/services/native_viewport/native_viewport.mojom.h"
+#include "mojo/services/view_manager/ids.h"
 #include "mojo/services/view_manager/node.h"
 #include "mojo/services/view_manager/node_delegate.h"
+#include "mojo/services/view_manager/root_view_manager.h"
 #include "mojo/services/view_manager/view_manager_export.h"
 
 namespace mojo {
+
+class Shell;
+
 namespace services {
 namespace view_manager {
 
@@ -22,9 +26,7 @@
 
 // RootNodeManager is responsible for managing the set of ViewManagerConnections
 // as well as providing the root of the node hierarchy.
-class MOJO_VIEW_MANAGER_EXPORT RootNodeManager
-    : public NativeViewportClient,
-      public NodeDelegate {
+class MOJO_VIEW_MANAGER_EXPORT RootNodeManager : public NodeDelegate {
  public:
   // Create when a ViewManagerConnection is about to make a change. Ensures
   // clients are notified of the correct change id.
@@ -32,7 +34,7 @@
    public:
     ScopedChange(ViewManagerConnection* connection,
                  RootNodeManager* root,
-                 ChangeId change_id);
+                 TransportChangeId change_id);
     ~ScopedChange();
 
    private:
@@ -41,17 +43,17 @@
     DISALLOW_COPY_AND_ASSIGN(ScopedChange);
   };
 
-  RootNodeManager();
+  explicit RootNodeManager(Shell* shell);
   virtual ~RootNodeManager();
 
   // Returns the id for the next ViewManagerConnection.
-  uint16_t GetAndAdvanceNextConnectionId();
+  TransportConnectionId GetAndAdvanceNextConnectionId();
 
   void AddConnection(ViewManagerConnection* connection);
   void RemoveConnection(ViewManagerConnection* connection);
 
   // Returns the connection by id.
-  ViewManagerConnection* GetConnection(uint16_t connection_id);
+  ViewManagerConnection* GetConnection(TransportConnectionId connection_id);
 
   // Returns the Node identified by |id|.
   Node* GetNode(const NodeId& id);
@@ -59,6 +61,8 @@
   // Returns the View identified by |id|.
   View* GetView(const ViewId& id);
 
+  Node* root() { return &root_; }
+
   // These functions trivially delegate to all ViewManagerConnections, which in
   // term notify their clients.
   void NotifyNodeHierarchyChanged(const NodeId& node,
@@ -69,18 +73,24 @@
                               const ViewId& old_view_id);
 
  private:
+  // Used to setup any static state needed by RootNodeManager.
+  struct Context {
+    Context();
+    ~Context();
+  };
+
   // Tracks a change.
   struct Change {
-    Change(int32_t connection_id, ChangeId change_id)
+    Change(TransportConnectionId connection_id, TransportChangeId change_id)
         : connection_id(connection_id),
           change_id(change_id) {
     }
 
-    int32_t connection_id;
-    ChangeId change_id;
+    TransportConnectionId connection_id;
+    TransportChangeId change_id;
   };
 
-  typedef std::map<uint16_t, ViewManagerConnection*> ConnectionMap;
+  typedef std::map<TransportConnectionId, ViewManagerConnection*> ConnectionMap;
 
   // Invoked when a particular connection is about to make a change. Records
   // the |change_id| so that it can be supplied to the clients by way of
@@ -88,18 +98,12 @@
   // Changes should never nest, meaning each PrepareForChange() must be
   // balanced with a call to FinishChange() with no PrepareForChange()
   // in between.
-  void PrepareForChange(ViewManagerConnection* connection, ChangeId change_id);
+  void PrepareForChange(ViewManagerConnection* connection,
+                        TransportChangeId change_id);
 
   // Balances a call to PrepareForChange().
   void FinishChange();
 
-  // Overridden from NativeViewportClient:
-  virtual void OnCreated() OVERRIDE;
-  virtual void OnDestroyed() OVERRIDE;
-  virtual void OnBoundsChanged(const Rect& bounds) OVERRIDE;
-  virtual void OnEvent(const Event& event,
-                       const mojo::Callback<void()>& callback) OVERRIDE;
-
   // Overriden from NodeDelegate:
   virtual void OnNodeHierarchyChanged(const NodeId& node,
                                       const NodeId& new_parent,
@@ -108,18 +112,22 @@
                                   const ViewId& new_view_id,
                                   const ViewId& old_view_id) OVERRIDE;
 
+  Context context_;
+
   // ID to use for next ViewManagerConnection.
-  uint16_t next_connection_id_;
+  TransportConnectionId next_connection_id_;
 
   // Set of ViewManagerConnections.
   ConnectionMap connection_map_;
 
-  // Root node.
-  Node root_;
-
   // If non-null we're processing a change.
   scoped_ptr<Change> change_;
 
+  RootViewManager root_view_manager_;
+
+  // Root node.
+  Node root_;
+
   DISALLOW_COPY_AND_ASSIGN(RootNodeManager);
 };
 
diff --git a/mojo/services/view_manager/root_view_manager.cc b/mojo/services/view_manager/root_view_manager.cc
new file mode 100644
index 0000000..791d1b9
--- /dev/null
+++ b/mojo/services/view_manager/root_view_manager.cc
@@ -0,0 +1,90 @@
+// 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.
+
+#include "mojo/services/view_manager/root_view_manager.h"
+
+#include "base/auto_reset.h"
+#include "mojo/aura/screen_mojo.h"
+#include "mojo/aura/window_tree_host_mojo.h"
+#include "mojo/public/cpp/bindings/allocation_scope.h"
+#include "mojo/public/interfaces/shell/shell.mojom.h"
+#include "mojo/services/view_manager/root_node_manager.h"
+#include "ui/aura/client/default_capture_client.h"
+#include "ui/aura/client/window_tree_client.h"
+#include "ui/aura/window.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class WindowTreeClientImpl : public aura::client::WindowTreeClient {
+ public:
+  explicit WindowTreeClientImpl(aura::Window* window) : window_(window) {
+    aura::client::SetWindowTreeClient(window_, this);
+  }
+
+  virtual ~WindowTreeClientImpl() {
+    aura::client::SetWindowTreeClient(window_, NULL);
+  }
+
+  // Overridden from aura::client::WindowTreeClient:
+  virtual aura::Window* GetDefaultParent(aura::Window* context,
+                                         aura::Window* window,
+                                         const gfx::Rect& bounds) OVERRIDE {
+    if (!capture_client_) {
+      capture_client_.reset(
+          new aura::client::DefaultCaptureClient(window_->GetRootWindow()));
+    }
+    return window_;
+  }
+
+ private:
+  aura::Window* window_;
+
+  scoped_ptr<aura::client::DefaultCaptureClient> capture_client_;
+
+  DISALLOW_COPY_AND_ASSIGN(WindowTreeClientImpl);
+};
+
+RootViewManager::RootViewManager(Shell* shell, RootNodeManager* root_node)
+    : shell_(shell),
+      root_node_manager_(root_node),
+      in_setup_(false) {
+  screen_.reset(ScreenMojo::Create());
+  gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
+  InterfacePipe<NativeViewport, AnyInterface> pipe;
+  mojo::AllocationScope scope;
+  shell_->Connect("mojo:mojo_native_viewport_service",
+                  pipe.handle_to_peer.Pass());
+  window_tree_host_.reset(new WindowTreeHostMojo(
+        pipe.handle_to_self.Pass(),
+        gfx::Rect(800, 600),
+        base::Bind(&RootViewManager::OnCompositorCreated,
+                   base::Unretained(this))));
+}
+
+RootViewManager::~RootViewManager() {
+  window_tree_client_.reset();
+  window_tree_host_.reset();
+  gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, NULL);
+}
+
+void RootViewManager::OnCompositorCreated() {
+  base::AutoReset<bool> resetter(&in_setup_, true);
+  window_tree_host_->InitHost();
+
+  aura::Window* root = root_node_manager_->root()->window();
+  window_tree_host_->window()->AddChild(root);
+  root->SetBounds(gfx::Rect(window_tree_host_->window()->bounds().size()));
+  root_node_manager_->root()->window()->Show();
+
+  window_tree_client_.reset(
+      new WindowTreeClientImpl(window_tree_host_->window()));
+
+  window_tree_host_->Show();
+}
+
+}  // namespace view_manager
+}  // namespace services
+}  // namespace mojo
diff --git a/mojo/services/view_manager/root_view_manager.h b/mojo/services/view_manager/root_view_manager.h
new file mode 100644
index 0000000..049faa8
--- /dev/null
+++ b/mojo/services/view_manager/root_view_manager.h
@@ -0,0 +1,66 @@
+// 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.
+
+#ifndef MOJO_SERVICES_VIEW_MANAGER_ROOT_VIEW_MANAGER_H_
+#define MOJO_SERVICES_VIEW_MANAGER_ROOT_VIEW_MANAGER_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "mojo/public/cpp/gles2/gles2.h"
+#include "mojo/services/view_manager/view_manager_export.h"
+
+namespace aura {
+namespace client {
+class WindowTreeClient;
+}
+class WindowTreeHost;
+}
+
+namespace gfx {
+class Screen;
+}
+
+namespace mojo {
+
+class Shell;
+
+namespace services {
+namespace view_manager {
+
+class RootNodeManager;
+
+// RootViewManager binds the root node to an actual display.
+class MOJO_VIEW_MANAGER_EXPORT RootViewManager {
+ public:
+  RootViewManager(Shell* shell, RootNodeManager* root_node);
+  virtual ~RootViewManager();
+
+  // See description above field for details.
+  bool in_setup() const { return in_setup_; }
+
+ private:
+  void OnCompositorCreated();
+
+  Shell* shell_;
+  RootNodeManager* root_node_manager_;
+
+  GLES2Initializer gles_initializer_;
+
+  // Returns true if adding the root node's window to |window_tree_host_|.
+  bool in_setup_;
+
+  scoped_ptr<gfx::Screen> screen_;
+  scoped_ptr<aura::WindowTreeHost> window_tree_host_;
+  scoped_ptr<aura::client::WindowTreeClient> window_tree_client_;
+
+  DISALLOW_COPY_AND_ASSIGN(RootViewManager);
+};
+
+}  // namespace view_manager
+}  // namespace services
+}  // namespace mojo
+
+#endif  // MOJO_SERVICES_VIEW_MANAGER_ROOT_VIEW_MANAGER_H_
diff --git a/mojo/services/view_manager/view.cc b/mojo/services/view_manager/view.cc
index 0e9fc13..18c98d1 100644
--- a/mojo/services/view_manager/view.cc
+++ b/mojo/services/view_manager/view.cc
@@ -15,6 +15,14 @@
 View::~View() {
 }
 
+void View::SetBitmap(const SkBitmap& bitmap) {
+  bitmap_ = bitmap;
+  if (node_) {
+    node_->window()->SchedulePaintInRect(
+        gfx::Rect(node_->window()->bounds().size()));
+  }
+}
+
 }  // namespace view_manager
 }  // namespace services
 }  // namespace mojo
diff --git a/mojo/services/view_manager/view.h b/mojo/services/view_manager/view.h
index 83251c0..32b7e03 100644
--- a/mojo/services/view_manager/view.h
+++ b/mojo/services/view_manager/view.h
@@ -10,6 +10,7 @@
 #include "base/logging.h"
 #include "mojo/services/view_manager/ids.h"
 #include "mojo/services/view_manager/view_manager_export.h"
+#include "third_party/skia/include/core/SkBitmap.h"
 
 namespace mojo {
 namespace services {
@@ -27,6 +28,9 @@
 
   Node* node() { return node_; }
 
+  void SetBitmap(const SkBitmap& contents);
+  const SkBitmap& bitmap() const { return bitmap_; }
+
  private:
   // Node is responsible for maintaining |node_|.
   friend class Node;
@@ -35,6 +39,7 @@
 
   const ViewId id_;
   Node* node_;
+  SkBitmap bitmap_;
 
   DISALLOW_COPY_AND_ASSIGN(View);
 };
diff --git a/mojo/services/view_manager/view_manager.cc b/mojo/services/view_manager/view_manager.cc
deleted file mode 100644
index e2e09f5..0000000
--- a/mojo/services/view_manager/view_manager.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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.
-
-#include "base/message_loop/message_loop.h"
-#include "mojo/public/cpp/shell/application.h"
-#include "mojo/services/view_manager/root_node_manager.h"
-#include "mojo/services/view_manager/view_manager_connection.h"
-
-#if defined(WIN32)
-#if !defined(CDECL)
-#define CDECL __cdecl)
-#endif
-#define VIEW_MANAGER_EXPORT __declspec(dllexport)
-#else
-#define CDECL
-#define VIEW_MANAGER_EXPORT __attribute__((visibility("default")))
-#endif
-
-extern "C" VIEW_MANAGER_EXPORT MojoResult CDECL MojoMain(
-    MojoHandle shell_handle) {
-  base::MessageLoop loop;
-  mojo::Application app(shell_handle);
-  mojo::services::view_manager::RootNodeManager root_node_manager;
-  app.AddServiceConnector(new mojo::ServiceConnector
-                          <mojo::services::view_manager::ViewManagerConnection,
-                           mojo::services::view_manager::RootNodeManager>(
-                               &root_node_manager));
-  loop.Run();
-
-  return MOJO_RESULT_OK;
-}
diff --git a/mojo/services/view_manager/view_manager_connection.cc b/mojo/services/view_manager/view_manager_connection.cc
index 0fe51e7..b11badd 100644
--- a/mojo/services/view_manager/view_manager_connection.cc
+++ b/mojo/services/view_manager/view_manager_connection.cc
@@ -9,6 +9,8 @@
 #include "mojo/services/view_manager/node.h"
 #include "mojo/services/view_manager/root_node_manager.h"
 #include "mojo/services/view_manager/view.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/codec/png_codec.h"
 
 namespace mojo {
 namespace services {
@@ -109,17 +111,18 @@
     const NodeId& node,
     const NodeId& new_parent,
     const NodeId& old_parent,
-    ChangeId change_id) {
+    TransportChangeId change_id) {
   client()->OnNodeHierarchyChanged(NodeIdToTransportId(node),
                                    NodeIdToTransportId(new_parent),
                                    NodeIdToTransportId(old_parent),
                                    change_id);
 }
 
-void ViewManagerConnection::NotifyNodeViewReplaced(const NodeId& node,
-                                                   const ViewId& new_view_id,
-                                                   const ViewId& old_view_id,
-                                                   ChangeId change_id) {
+void ViewManagerConnection::NotifyNodeViewReplaced(
+    const NodeId& node,
+    const ViewId& new_view_id,
+    const ViewId& old_view_id,
+    TransportChangeId change_id) {
   client()->OnNodeViewReplaced(NodeIdToTransportId(node),
                                ViewIdToTransportId(new_view_id),
                                ViewIdToTransportId(old_view_id),
@@ -128,7 +131,7 @@
 
 bool ViewManagerConnection::DeleteNodeImpl(ViewManagerConnection* source,
                                            const NodeId& node_id,
-                                           ChangeId change_id) {
+                                           TransportChangeId change_id) {
   DCHECK_EQ(node_id.connection_id, id_);
   Node* node = GetNode(node_id);
   if (!node)
@@ -147,7 +150,7 @@
 
 bool ViewManagerConnection::DeleteViewImpl(ViewManagerConnection* source,
                                            const ViewId& view_id,
-                                           ChangeId change_id) {
+                                           TransportChangeId change_id) {
   DCHECK_EQ(view_id.connection_id, id_);
   View* view = GetView(view_id);
   if (!view)
@@ -162,7 +165,7 @@
 
 bool ViewManagerConnection::SetViewImpl(const NodeId& node_id,
                                         const ViewId& view_id,
-                                        ChangeId change_id) {
+                                        TransportChangeId change_id) {
   Node* node = GetNode(node_id);
   if (!node)
     return false;
@@ -175,7 +178,7 @@
 }
 
 void ViewManagerConnection::CreateNode(
-    uint16_t node_id,
+    TransportConnectionSpecificNodeId node_id,
     const Callback<void(bool)>& callback) {
   // Negative values are reserved.
   if (node_map_.find(node_id) != node_map_.end()) {
@@ -187,8 +190,8 @@
 }
 
 void ViewManagerConnection::DeleteNode(
-    uint32_t transport_node_id,
-    ChangeId change_id,
+    TransportNodeId transport_node_id,
+    TransportChangeId change_id,
     const Callback<void(bool)>& callback) {
   const NodeId node_id(NodeIdFromTransportId(transport_node_id));
   ViewManagerConnection* connection = context()->GetConnection(
@@ -198,9 +201,9 @@
 }
 
 void ViewManagerConnection::AddNode(
-    uint32_t parent_id,
-    uint32_t child_id,
-    ChangeId change_id,
+    TransportNodeId parent_id,
+    TransportNodeId child_id,
+    TransportChangeId change_id,
     const Callback<void(bool)>& callback) {
   Node* parent = GetNode(NodeIdFromTransportId(parent_id));
   Node* child = GetNode(NodeIdFromTransportId(child_id));
@@ -213,9 +216,9 @@
 }
 
 void ViewManagerConnection::RemoveNodeFromParent(
-      uint32_t node_id,
-      ChangeId change_id,
-      const Callback<void(bool)>& callback) {
+    TransportNodeId node_id,
+    TransportChangeId change_id,
+    const Callback<void(bool)>& callback) {
   Node* node = GetNode(NodeIdFromTransportId(node_id));
   const bool success = (node && node->GetParent());
   if (success) {
@@ -226,7 +229,7 @@
 }
 
 void ViewManagerConnection::GetNodeTree(
-    uint32_t node_id,
+    TransportNodeId node_id,
     const Callback<void(Array<INode>)>& callback) {
   AllocationScope allocation_scope;
   Node* node = GetNode(NodeIdFromTransportId(node_id));
@@ -239,7 +242,7 @@
 }
 
 void ViewManagerConnection::CreateView(
-    uint16_t view_id,
+    TransportConnectionSpecificViewId view_id,
     const Callback<void(bool)>& callback) {
   if (view_map_.count(view_id)) {
     callback.Run(false);
@@ -250,8 +253,8 @@
 }
 
 void ViewManagerConnection::DeleteView(
-    uint32_t transport_view_id,
-    ChangeId change_id,
+    TransportViewId transport_view_id,
+    TransportChangeId change_id,
     const Callback<void(bool)>& callback) {
   const ViewId view_id(ViewIdFromTransportId(transport_view_id));
   ViewManagerConnection* connection = context()->GetConnection(
@@ -261,15 +264,34 @@
 }
 
 void ViewManagerConnection::SetView(
-    uint32_t transport_node_id,
-    uint32_t transport_view_id,
-    ChangeId change_id,
+    TransportNodeId transport_node_id,
+    TransportViewId transport_view_id,
+    TransportChangeId change_id,
     const Callback<void(bool)>& callback) {
   const NodeId node_id(NodeIdFromTransportId(transport_node_id));
   callback.Run(SetViewImpl(node_id, ViewIdFromTransportId(transport_view_id),
                            change_id));
 }
 
+void ViewManagerConnection::SetViewContents(
+    TransportViewId view_id,
+    ScopedSharedBufferHandle buffer,
+    uint32_t buffer_size) {
+  View* view = GetView(ViewIdFromTransportId(view_id));
+  if (!view)
+    return;
+  void* handle_data;
+  if (MapBuffer(buffer.get(), 0, buffer_size, &handle_data,
+                MOJO_MAP_BUFFER_FLAG_NONE) != MOJO_RESULT_OK) {
+    return;
+  }
+  SkBitmap bitmap;
+  gfx::PNGCodec::Decode(static_cast<const unsigned char*>(handle_data),
+                        buffer_size, &bitmap);
+  view->SetBitmap(bitmap);
+  UnmapBuffer(handle_data);
+}
+
 void ViewManagerConnection::OnNodeHierarchyChanged(const NodeId& node,
                                                    const NodeId& new_parent,
                                                    const NodeId& old_parent) {
diff --git a/mojo/services/view_manager/view_manager_connection.h b/mojo/services/view_manager/view_manager_connection.h
index 91f56b3..ebb7a25 100644
--- a/mojo/services/view_manager/view_manager_connection.h
+++ b/mojo/services/view_manager/view_manager_connection.h
@@ -31,7 +31,7 @@
   ViewManagerConnection();
   virtual ~ViewManagerConnection();
 
-  uint16_t id() const { return id_; }
+  TransportConnectionId id() const { return id_; }
 
   // Invoked from Service when connection is established.
   void Initialize(
@@ -48,59 +48,62 @@
   void NotifyNodeHierarchyChanged(const NodeId& node,
                                   const NodeId& new_parent,
                                   const NodeId& old_parent,
-                                  ChangeId change_id);
+                                  TransportChangeId change_id);
   void NotifyNodeViewReplaced(const NodeId& node,
                               const ViewId& new_view_id,
                               const ViewId& old_view_id,
-                              ChangeId change_id);
+                              TransportChangeId change_id);
 
  private:
-  typedef std::map<uint16_t, Node*> NodeMap;
-  typedef std::map<uint16_t, View*> ViewMap;
+  typedef std::map<TransportConnectionSpecificNodeId, Node*> NodeMap;
+  typedef std::map<TransportConnectionSpecificViewId, View*> ViewMap;
 
   // Deletes a node owned by this connection. Returns true on success. |source|
   // is the connection that originated the change.
   bool DeleteNodeImpl(ViewManagerConnection* source,
                       const NodeId& node_id,
-                      ChangeId change_id);
+                      TransportChangeId change_id);
 
   // Deletes a view owned by this connection. Returns true on success. |source|
   // is the connection that originated the change.
   bool DeleteViewImpl(ViewManagerConnection* source,
                       const ViewId& view_id,
-                      ChangeId change_id);
+                      TransportChangeId change_id);
 
   // Sets the view associated with a node.
   bool SetViewImpl(const NodeId& node_id,
                    const ViewId& view_id,
-                   ChangeId change_id);
+                   TransportChangeId change_id);
 
   // Overridden from IViewManager:
-  virtual void CreateNode(uint16_t node_id,
+  virtual void CreateNode(TransportConnectionSpecificNodeId node_id,
                           const Callback<void(bool)>& callback) OVERRIDE;
-  virtual void DeleteNode(uint32_t transport_node_id,
-                          ChangeId change_id,
+  virtual void DeleteNode(TransportNodeId transport_node_id,
+                          TransportChangeId change_id,
                           const Callback<void(bool)>& callback) OVERRIDE;
-  virtual void AddNode(uint32_t parent_id,
-                       uint32_t child_id,
-                       ChangeId change_id,
+  virtual void AddNode(TransportNodeId parent_id,
+                       TransportNodeId child_id,
+                       TransportChangeId change_id,
                        const Callback<void(bool)>& callback) OVERRIDE;
   virtual void RemoveNodeFromParent(
-      uint32_t node_id,
-      ChangeId change_id,
+      TransportNodeId node_id,
+      TransportChangeId change_id,
       const Callback<void(bool)>& callback) OVERRIDE;
   virtual void GetNodeTree(
-      uint32_t node_id,
+      TransportNodeId node_id,
       const Callback<void(Array<INode>)>& callback) OVERRIDE;
-  virtual void CreateView(uint16_t view_id,
+  virtual void CreateView(TransportConnectionSpecificViewId view_id,
                           const Callback<void(bool)>& callback) OVERRIDE;
-  virtual void DeleteView(uint32_t transport_view_id,
-                          ChangeId change_id,
+  virtual void DeleteView(TransportViewId transport_view_id,
+                          TransportChangeId change_id,
                           const Callback<void(bool)>& callback) OVERRIDE;
-  virtual void SetView(uint32_t transport_node_id,
-                       uint32_t transport_view_id,
-                       ChangeId change_id,
+  virtual void SetView(TransportNodeId transport_node_id,
+                       TransportViewId transport_view_id,
+                       TransportChangeId change_id,
                        const Callback<void(bool)>& callback) OVERRIDE;
+  virtual void SetViewContents(TransportViewId view_id,
+                               ScopedSharedBufferHandle buffer,
+                               uint32_t buffer_size) OVERRIDE;
 
   // Overridden from NodeDelegate:
   virtual void OnNodeHierarchyChanged(const NodeId& node,
@@ -112,7 +115,7 @@
 
   // Id of this connection as assigned by RootNodeManager. Assigned in
   // Initialize().
-  uint16_t id_;
+  TransportConnectionId id_;
 
   NodeMap node_map_;
 
diff --git a/mojo/services/view_manager/view_manager_connection_unittest.cc b/mojo/services/view_manager/view_manager_connection_unittest.cc
index d656a43..dea435b 100644
--- a/mojo/services/view_manager/view_manager_connection_unittest.cc
+++ b/mojo/services/view_manager/view_manager_connection_unittest.cc
@@ -12,6 +12,8 @@
 #include "base/strings/stringprintf.h"
 #include "mojo/public/cpp/bindings/allocation_scope.h"
 #include "mojo/public/cpp/environment/environment.h"
+#include "mojo/services/public/cpp/view_manager/util.h"
+#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
 #include "mojo/shell/shell_test_helper.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -24,17 +26,6 @@
 
 base::RunLoop* current_run_loop = NULL;
 
-// TODO(sky): remove and include a common header.
-typedef uint32_t ChangeId;
-
-uint16_t FirstIdFromTransportId(uint32_t id) {
-  return static_cast<uint16_t>((id >> 16) & 0xFFFF);
-}
-
-uint16_t SecondIdFromTransportId(uint32_t id) {
-  return static_cast<uint16_t>(id & 0xFFFF);
-}
-
 // Sets |current_run_loop| and runs it. It is expected that someone else quits
 // the loop.
 void DoRunLoop() {
@@ -45,10 +36,9 @@
 }
 
 // Converts |id| into a string.
-std::string NodeIdToString(uint32_t id) {
+std::string NodeIdToString(TransportNodeId id) {
   return (id == 0) ? "null" :
-      base::StringPrintf("%d,%d", FirstIdFromTransportId(id),
-                         SecondIdFromTransportId(id));
+      base::StringPrintf("%d,%d", HiWord(id), LoWord(id));
 }
 
 // Boolean callback. Sets |result_cache| to the value of |result| and quits
@@ -66,9 +56,9 @@
                               NodeIdToString(view_id).c_str());
   }
 
-  uint32_t parent_id;
-  uint32_t node_id;
-  uint32_t view_id;
+  TransportNodeId parent_id;
+  TransportNodeId node_id;
+  TransportNodeId view_id;
 };
 
 // Callback that results in a vector of INodes. The INodes are converted to
@@ -86,18 +76,21 @@
 }
 
 // Creates an id used for transport from the specified parameters.
-uint32_t CreateNodeId(uint16_t connection_id, uint16_t node_id) {
+TransportNodeId CreateNodeId(TransportConnectionId connection_id,
+                             TransportConnectionSpecificNodeId node_id) {
   return (connection_id << 16) | node_id;
 }
 
 // Creates an id used for transport from the specified parameters.
-uint32_t CreateViewId(uint16_t connection_id, uint16_t view_id) {
+TransportViewId CreateViewId(TransportConnectionId connection_id,
+                             TransportConnectionSpecificViewId view_id) {
   return (connection_id << 16) | view_id;
 }
 
 // Creates a node with the specified id. Returns true on success. Blocks until
 // we get back result from server.
-bool CreateNode(IViewManager* view_manager, uint16_t id) {
+bool CreateNode(IViewManager* view_manager,
+                TransportConnectionSpecificNodeId id) {
   bool result = false;
   view_manager->CreateNode(id, base::Bind(&BooleanCallback, &result));
   DoRunLoop();
@@ -108,8 +101,8 @@
 
 // Deletes a node, blocking until done.
 bool DeleteNode(IViewManager* view_manager,
-                uint32_t node_id,
-                ChangeId change_id) {
+                TransportNodeId node_id,
+                TransportChangeId change_id) {
   bool result = false;
   view_manager->DeleteNode(node_id, change_id,
                            base::Bind(&BooleanCallback, &result));
@@ -119,9 +112,9 @@
 
 // Adds a node, blocking until done.
 bool AddNode(IViewManager* view_manager,
-             uint32_t parent,
-             uint32_t child,
-             ChangeId change_id) {
+             TransportNodeId parent,
+             TransportNodeId child,
+             TransportChangeId change_id) {
   bool result = false;
   view_manager->AddNode(parent, child, change_id,
                         base::Bind(&BooleanCallback, &result));
@@ -131,8 +124,8 @@
 
 // Removes a node, blocking until done.
 bool RemoveNodeFromParent(IViewManager* view_manager,
-                          uint32_t node_id,
-                          ChangeId change_id) {
+                          TransportNodeId node_id,
+                          TransportChangeId change_id) {
   bool result = false;
   view_manager->RemoveNodeFromParent(node_id, change_id,
                                      base::Bind(&BooleanCallback, &result));
@@ -141,7 +134,7 @@
 }
 
 void GetNodeTree(IViewManager* view_manager,
-                 uint32_t node_id,
+                 TransportNodeId node_id,
                  std::vector<TestNode>* nodes) {
   view_manager->GetNodeTree(node_id, base::Bind(&INodesCallback, nodes));
   DoRunLoop();
@@ -149,7 +142,8 @@
 
 // Creates a view with the specified id. Returns true on success. Blocks until
 // we get back result from server.
-bool CreateView(IViewManager* view_manager, uint16_t id) {
+bool CreateView(IViewManager* view_manager,
+                TransportConnectionSpecificViewId id) {
   bool result = false;
   view_manager->CreateView(id, base::Bind(&BooleanCallback, &result));
   DoRunLoop();
@@ -159,9 +153,9 @@
 // Sets a view on the specified node. Returns true on success. Blocks until we
 // get back result from server.
 bool SetView(IViewManager* view_manager,
-             uint32_t node_id,
-             uint32_t view_id,
-             ChangeId change_id) {
+             TransportNodeId node_id,
+             TransportViewId view_id,
+             TransportChangeId change_id) {
   bool result = false;
   view_manager->SetView(node_id, view_id, change_id,
                         base::Bind(&BooleanCallback, &result));
@@ -177,7 +171,7 @@
  public:
   ViewManagerClientImpl() : id_(0), quit_count_(0) {}
 
-  uint16_t id() const { return id_; }
+  TransportConnectionId id() const { return id_; }
 
   Changes GetAndClearChanges() {
     Changes changes;
@@ -199,15 +193,16 @@
 
  private:
   // IViewManagerClient overrides:
-  virtual void OnConnectionEstablished(uint16_t connection_id) OVERRIDE {
+  virtual void OnConnectionEstablished(
+      TransportConnectionId connection_id) OVERRIDE {
     id_ = connection_id;
     if (current_run_loop)
       current_run_loop->Quit();
   }
-  virtual void OnNodeHierarchyChanged(uint32_t node,
-                                      uint32_t new_parent,
-                                      uint32_t old_parent,
-                                      ChangeId change_id) OVERRIDE {
+  virtual void OnNodeHierarchyChanged(TransportNodeId node,
+                                      TransportNodeId new_parent,
+                                      TransportNodeId old_parent,
+                                      TransportChangeId change_id) OVERRIDE {
     changes_.push_back(
         base::StringPrintf(
             "change_id=%d node=%s new_parent=%s old_parent=%s",
@@ -216,10 +211,10 @@
             NodeIdToString(old_parent).c_str()));
     QuitIfNecessary();
   }
-  virtual void OnNodeViewReplaced(uint32_t node,
-                                  uint32_t new_view_id,
-                                  uint32_t old_view_id,
-                                  ChangeId change_id) OVERRIDE {
+  virtual void OnNodeViewReplaced(TransportNodeId node,
+                                  TransportViewId new_view_id,
+                                  TransportViewId old_view_id,
+                                  TransportChangeId change_id) OVERRIDE {
     changes_.push_back(
         base::StringPrintf(
             "change_id=%d node=%s new_view=%s old_view=%s",
@@ -234,7 +229,7 @@
       current_run_loop->Quit();
   }
 
-  uint16_t id_;
+  TransportConnectionId id_;
 
   // Used to determine when/if to quit the run loop.
   size_t quit_count_;
diff --git a/mojo/shell/context.cc b/mojo/shell/context.cc
index 86f06c3..9879a17 100644
--- a/mojo/shell/context.cc
+++ b/mojo/shell/context.cc
@@ -11,6 +11,7 @@
 #include "mojo/embedder/embedder.h"
 #include "mojo/gles2/gles2_support_impl.h"
 #include "mojo/public/cpp/shell/application.h"
+#include "mojo/service_manager/background_service_loader.h"
 #include "mojo/service_manager/service_loader.h"
 #include "mojo/service_manager/service_manager.h"
 #include "mojo/services/native_viewport/native_viewport_service.h"
@@ -26,8 +27,7 @@
 #endif  // defined(OS_LINUX)
 
 #if defined(USE_AURA)
-#include "mojo/services/view_manager/root_node_manager.h"
-#include "mojo/services/view_manager/view_manager_connection.h"
+#include "mojo/shell/view_manager_loader.h"
 #endif
 
 namespace mojo {
@@ -51,35 +51,6 @@
 
 static base::LazyInstance<Setup> setup = LAZY_INSTANCE_INITIALIZER;
 
-#if defined(USE_AURA)
-class ViewManagerLoader : public ServiceLoader {
- public:
-  ViewManagerLoader() {}
-  virtual ~ViewManagerLoader() {}
-
- private:
-  virtual void LoadService(ServiceManager* manager,
-                           const GURL& url,
-                           ScopedShellHandle shell_handle) OVERRIDE {
-    scoped_ptr<Application> app(new Application(shell_handle.Pass()));
-    app->AddServiceConnector(
-        new ServiceConnector<services::view_manager::ViewManagerConnection,
-                             services::view_manager::RootNodeManager>(
-                                 &root_node_manager_));
-    apps_.push_back(app.release());
-  }
-
-  virtual void OnServiceError(ServiceManager* manager,
-                              const GURL& url) OVERRIDE {
-  }
-
-  services::view_manager::RootNodeManager root_node_manager_;
-  ScopedVector<Application> apps_;
-
-  DISALLOW_COPY_AND_ASSIGN(ViewManagerLoader);
-};
-#endif
-
 }  // namespace
 
 class Context::NativeViewportServiceLoader : public ServiceLoader {
@@ -122,8 +93,14 @@
   service_manager_.set_default_loader(
       scoped_ptr<ServiceLoader>(
           new DynamicServiceLoader(this, runner_factory.Pass())));
+  // The native viewport service synchronously waits for certain messages. If we
+  // don't run it on its own thread we can easily deadlock. Long term native
+  // viewport should run its own process so that this isn't an issue.
   service_manager_.SetLoaderForURL(
-      scoped_ptr<ServiceLoader>(new NativeViewportServiceLoader(this)),
+      scoped_ptr<ServiceLoader>(
+          new BackgroundServiceLoader(
+              scoped_ptr<ServiceLoader>(new NativeViewportServiceLoader(this)),
+              "native_viewport")),
       GURL("mojo:mojo_native_viewport_service"));
 #if defined(USE_AURA)
   // TODO(sky): need a better way to find this. It shouldn't be linked in.
@@ -145,6 +122,14 @@
 }
 
 Context::~Context() {
+  // mojo_view_manager uses native_viewport. Destroy mojo_view_manager first so
+  // that there aren't shutdown ordering issues. Once native viewport service is
+  // moved into its own process this can likely be nuked.
+#if defined(USE_AURA)
+  service_manager_.SetLoaderForURL(
+      scoped_ptr<ServiceLoader>(),
+      GURL("mojo:mojo_view_manager"));
+#endif
   service_manager_.set_default_loader(scoped_ptr<ServiceLoader>());
 }
 
diff --git a/mojo/shell/dbus_service_loader_linux.cc b/mojo/shell/dbus_service_loader_linux.cc
index a476d25..6485496 100644
--- a/mojo/shell/dbus_service_loader_linux.cc
+++ b/mojo/shell/dbus_service_loader_linux.cc
@@ -17,6 +17,7 @@
 #include "dbus/object_path.h"
 #include "dbus/object_proxy.h"
 #include "mojo/common/channel_init.h"
+#include "mojo/dbus/dbus_external_service.h"
 #include "mojo/embedder/platform_channel_pair.h"
 #include "mojo/public/cpp/bindings/allocation_scope.h"
 #include "mojo/public/cpp/bindings/interface.h"
@@ -94,7 +95,7 @@
     service_dbus_proxy_ =
         bus_->GetObjectProxy(service_name, dbus::ObjectPath(object_path));
 
-    dbus::MethodCall call("org.chromium.Mojo", "ConnectChannel");
+    dbus::MethodCall call(kMojoDBusInterface, kMojoDBusConnectMethod);
     dbus::MessageWriter writer(&call);
     writer.AppendFileDescriptor(*client_fd.get());
 
diff --git a/mojo/shell/shell_test_helper.cc b/mojo/shell/shell_test_helper.cc
index c530140..e8f4bea 100644
--- a/mojo/shell/shell_test_helper.cc
+++ b/mojo/shell/shell_test_helper.cc
@@ -49,7 +49,7 @@
 };
 
 ShellTestHelper::ShellTestHelper()
-    : shell_thread_("Test Shell Thread"),
+    : shell_thread_("shell_test_helper"),
       state_(NULL) {
   CommandLine::Init(0, NULL);
   mojo::shell::InitializeLogging();
diff --git a/mojo/shell/view_manager_loader.cc b/mojo/shell/view_manager_loader.cc
new file mode 100644
index 0000000..a3d0cbd
--- /dev/null
+++ b/mojo/shell/view_manager_loader.cc
@@ -0,0 +1,40 @@
+// 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.
+
+#include "mojo/shell/view_manager_loader.h"
+
+#include "mojo/public/cpp/shell/application.h"
+#include "mojo/services/view_manager/root_node_manager.h"
+#include "mojo/services/view_manager/view_manager_connection.h"
+
+namespace mojo {
+namespace shell {
+
+ViewManagerLoader::ViewManagerLoader() {
+}
+
+ViewManagerLoader::~ViewManagerLoader() {
+}
+
+void ViewManagerLoader::LoadService(ServiceManager* manager,
+                                    const GURL& url,
+                                    ScopedShellHandle shell_handle) {
+  scoped_ptr<Application> app(new Application(shell_handle.Pass()));
+  if (!root_node_manager_.get()) {
+    root_node_manager_.reset(
+        new services::view_manager::RootNodeManager(app->shell()));
+  }
+  app->AddServiceConnector(
+      new ServiceConnector<services::view_manager::ViewManagerConnection,
+                           services::view_manager::RootNodeManager>(
+                               root_node_manager_.get()));
+  apps_.push_back(app.release());
+}
+
+void ViewManagerLoader::OnServiceError(ServiceManager* manager,
+                                       const GURL& url) {
+}
+
+}  // namespace shell
+}  // namespace mojo
diff --git a/mojo/shell/view_manager_loader.h b/mojo/shell/view_manager_loader.h
new file mode 100644
index 0000000..021f2a4
--- /dev/null
+++ b/mojo/shell/view_manager_loader.h
@@ -0,0 +1,46 @@
+// 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.
+
+#ifndef MOJO_SHELL_VIEW_MANAGER_LOADER_H_
+#define MOJO_SHELL_VIEW_MANAGER_LOADER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "mojo/service_manager/service_loader.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+class RootNodeManager;
+}
+}
+
+class Application;
+
+namespace shell {
+
+// ServiceLoader responsible for creating connections to the ViewManager.
+class ViewManagerLoader : public ServiceLoader {
+ public:
+  ViewManagerLoader();
+  virtual ~ViewManagerLoader();
+
+ private:
+  // ServiceLoader overrides:
+  virtual void LoadService(ServiceManager* manager,
+                           const GURL& url,
+                           ScopedShellHandle shell_handle) OVERRIDE;
+  virtual void OnServiceError(ServiceManager* manager,
+                              const GURL& url) OVERRIDE;
+
+  scoped_ptr<services::view_manager::RootNodeManager> root_node_manager_;
+  ScopedVector<Application> apps_;
+
+  DISALLOW_COPY_AND_ASSIGN(ViewManagerLoader);
+};
+
+}  // namespace shell
+}  // namespace mojo
+
+#endif  // MOJO_SHELL_VIEW_MANAGER_LOADER_H_
diff --git a/mojo/system/channel.cc b/mojo/system/channel.cc
index ca65284..7446cb9 100644
--- a/mojo/system/channel.cc
+++ b/mojo/system/channel.cc
@@ -12,6 +12,7 @@
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
 #include "mojo/system/message_pipe_endpoint.h"
+#include "mojo/system/transport_data.h"
 
 namespace mojo {
 namespace system {
@@ -347,10 +348,17 @@
     return;
   }
 
-  // We need to duplicate the message, because |EnqueueMessage()| will take
-  // ownership of it.
+  // We need to duplicate the message (data), because |EnqueueMessage()| will
+  // take ownership of it.
   scoped_ptr<MessageInTransit> message(new MessageInTransit(message_view));
-  message->DeserializeDispatchers(this);
+  if (message_view.transport_data_buffer_size() > 0) {
+    DCHECK(message_view.transport_data_buffer());
+    message->SetDispatchers(
+        TransportData::DeserializeDispatchersFromBuffer(
+            message_view.transport_data_buffer(),
+            message_view.transport_data_buffer_size(),
+            this));
+  }
   MojoResult result = endpoint_info.message_pipe->EnqueueMessage(
       MessagePipe::GetPeerPort(endpoint_info.port), message.Pass());
   if (result != MOJO_RESULT_OK) {
@@ -458,7 +466,7 @@
   DVLOG(2) << "Sending channel control message: subtype " << subtype
            << ", local ID " << local_id << ", remote ID " << remote_id;
   scoped_ptr<MessageInTransit> message(new MessageInTransit(
-      MessageInTransit::kTypeChannel, subtype, 0, 0, NULL));
+      MessageInTransit::kTypeChannel, subtype, 0, NULL));
   message->set_source_id(local_id);
   message->set_destination_id(remote_id);
   return WriteMessage(message.Pass());
diff --git a/mojo/system/core.cc b/mojo/system/core.cc
index dd8fb57..49f0a9c 100644
--- a/mojo/system/core.cc
+++ b/mojo/system/core.cc
@@ -269,7 +269,7 @@
   if (!num_handles || *num_handles == 0)
     return dispatcher->ReadMessage(bytes, num_bytes, NULL, num_handles, flags);
 
-  std::vector<scoped_refptr<Dispatcher> > dispatchers;
+  DispatcherVector dispatchers;
   MojoResult rv = dispatcher->ReadMessage(bytes, num_bytes,
                                           &dispatchers, num_handles,
                                           flags);
@@ -537,7 +537,7 @@
                                   MojoDeadline deadline) {
   DCHECK_GT(num_handles, 0u);
 
-  std::vector<scoped_refptr<Dispatcher> > dispatchers;
+  DispatcherVector dispatchers;
   dispatchers.reserve(num_handles);
   for (uint32_t i = 0; i < num_handles; i++) {
     scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handles[i]);
diff --git a/mojo/system/core_test_base.cc b/mojo/system/core_test_base.cc
index 29c3c5c..e4efe45 100644
--- a/mojo/system/core_test_base.cc
+++ b/mojo/system/core_test_base.cc
@@ -68,7 +68,7 @@
   virtual MojoResult ReadMessageImplNoLock(
       void* bytes,
       uint32_t* num_bytes,
-      std::vector<scoped_refptr<Dispatcher> >* /*dispatchers*/,
+      DispatcherVector* /*dispatchers*/,
       uint32_t* /*num_dispatchers*/,
       MojoReadMessageFlags /*flags*/) OVERRIDE {
     info_->IncrementReadMessageCallCount();
diff --git a/mojo/system/dispatcher.cc b/mojo/system/dispatcher.cc
index 8b0d71f..16735fc 100644
--- a/mojo/system/dispatcher.cc
+++ b/mojo/system/dispatcher.cc
@@ -40,7 +40,7 @@
 }
 
 // static
-void Dispatcher::MessageInTransitAccess::StartSerialize(
+void Dispatcher::TransportDataAccess::StartSerialize(
     Dispatcher* dispatcher,
     Channel* channel,
     size_t* max_size,
@@ -50,7 +50,7 @@
 }
 
 // static
-bool Dispatcher::MessageInTransitAccess::EndSerializeAndClose(
+bool Dispatcher::TransportDataAccess::EndSerializeAndClose(
     Dispatcher* dispatcher,
     Channel* channel,
     void* destination,
@@ -62,7 +62,7 @@
 }
 
 // static
-scoped_refptr<Dispatcher> Dispatcher::MessageInTransitAccess::Deserialize(
+scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize(
     Channel* channel,
     int32_t type,
     const void* source,
@@ -108,11 +108,10 @@
   return WriteMessageImplNoLock(bytes, num_bytes, transports, flags);
 }
 
-MojoResult Dispatcher::ReadMessage(
-    void* bytes,
-    uint32_t* num_bytes,
-    std::vector<scoped_refptr<Dispatcher> >* dispatchers,
-    uint32_t* num_dispatchers,
+MojoResult Dispatcher::ReadMessage(void* bytes,
+                                   uint32_t* num_bytes,
+                                   DispatcherVector* dispatchers,
+                                   uint32_t* num_dispatchers,
     MojoReadMessageFlags flags) {
   DCHECK(!num_dispatchers || *num_dispatchers == 0 ||
          (dispatchers && dispatchers->empty()));
@@ -256,12 +255,11 @@
   return MOJO_RESULT_INVALID_ARGUMENT;
 }
 
-MojoResult Dispatcher::ReadMessageImplNoLock(
-    void* /*bytes*/,
-    uint32_t* /*num_bytes*/,
-    std::vector<scoped_refptr<Dispatcher> >* /*dispatchers*/,
-    uint32_t* /*num_dispatchers*/,
-    MojoReadMessageFlags /*flags*/) {
+MojoResult Dispatcher::ReadMessageImplNoLock(void* /*bytes*/,
+                                             uint32_t* /*num_bytes*/,
+                                             DispatcherVector* /*dispatchers*/,
+                                             uint32_t* /*num_dispatchers*/,
+                                             MojoReadMessageFlags /*flags*/) {
   lock_.AssertAcquired();
   DCHECK(!is_closed_);
   // By default, not supported. Only needed for message pipe dispatchers.
diff --git a/mojo/system/dispatcher.h b/mojo/system/dispatcher.h
index 504e33a..4e9e13f 100644
--- a/mojo/system/dispatcher.h
+++ b/mojo/system/dispatcher.h
@@ -27,11 +27,13 @@
 class DispatcherTransport;
 class HandleTable;
 class LocalMessagePipeEndpoint;
-class MessageInTransit;
 class ProxyMessagePipeEndpoint;
 class RawSharedBufferMapping;
+class TransportData;
 class Waiter;
 
+typedef std::vector<scoped_refptr<Dispatcher> > DispatcherVector;
+
 namespace test {
 
 // Test helper. We need to declare it here so we can friend it.
@@ -77,12 +79,11 @@
   // |dispatchers| must be non-null but empty, if |num_dispatchers| is non-null
   // and nonzero. On success, it will be set to the dispatchers to be received
   // (and assigned handles) as part of the message.
-  MojoResult ReadMessage(
-      void* bytes,
-      uint32_t* num_bytes,
-      std::vector<scoped_refptr<Dispatcher> >* dispatchers,
-      uint32_t* num_dispatchers,
-      MojoReadMessageFlags flags);
+  MojoResult ReadMessage(void* bytes,
+                         uint32_t* num_bytes,
+                         DispatcherVector* dispatchers,
+                         uint32_t* num_dispatchers,
+                         MojoReadMessageFlags flags);
   MojoResult WriteData(const void* elements,
                        uint32_t* elements_num_bytes,
                        MojoWriteDataFlags flags);
@@ -146,18 +147,19 @@
     static DispatcherTransport TryStartTransport(Dispatcher* dispatcher);
   };
 
-  // A |MessageInTransit| may serialize dispatchers that are attached to it to a
-  // given |Channel| and then (probably in a different process) deserialize.
+  // A |TransportData| may serialize dispatchers that are given to it (and which
+  // were previously attached to the |MessageInTransit| that is creating it) to
+  // a given |Channel| and then (probably in a different process) deserialize.
   // Note that the |MessageInTransit| "owns" (i.e., has the only ref to) these
   // dispatchers, so there are no locking issues. (There's no lock ordering
   // issue, and in fact no need to take dispatcher locks at all.)
   // TODO(vtl): Consider making another wrapper similar to |DispatcherTransport|
   // (but with an owning, unique reference), and having
   // |CreateEquivalentDispatcherAndCloseImplNoLock()| return that wrapper (and
-  // |MessageInTransit| only holding on to such wrappers).
-  class MessageInTransitAccess {
+  // |MessageInTransit|, etc. only holding on to such wrappers).
+  class TransportDataAccess {
    private:
-    friend class MessageInTransit;
+    friend class TransportData;
 
     // Serialization API. These functions may only be called on such
     // dispatchers. (|channel| is the |Channel| to which the dispatcher is to be
@@ -204,12 +206,11 @@
       uint32_t num_bytes,
       std::vector<DispatcherTransport>* transports,
       MojoWriteMessageFlags flags);
-  virtual MojoResult ReadMessageImplNoLock(
-      void* bytes,
-      uint32_t* num_bytes,
-      std::vector<scoped_refptr<Dispatcher> >* dispatchers,
-      uint32_t* num_dispatchers,
-      MojoReadMessageFlags flags);
+  virtual MojoResult ReadMessageImplNoLock(void* bytes,
+                                           uint32_t* num_bytes,
+                                           DispatcherVector* dispatchers,
+                                           uint32_t* num_dispatchers,
+                                           MojoReadMessageFlags flags);
   virtual MojoResult WriteDataImplNoLock(const void* elements,
                                          uint32_t* num_bytes,
                                          MojoWriteDataFlags flags);
@@ -286,16 +287,16 @@
   scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseNoLock();
 
   // API to serialize dispatchers to a |Channel|, exposed to only
-  // |MessageInTransit| (via |MessageInTransitAccess|). They may only be called
-  // on a dispatcher attached to a |MessageInTransit| (and in particular not in
+  // |TransportData| (via |TransportData|). They may only be called on a
+  // dispatcher attached to a |MessageInTransit| (and in particular not in
   // |CoreImpl|'s handle table).
   //
   // Starts the serialization. Returns (via the two "out" parameters) the
   // maximum amount of space that may be needed to serialize this dispatcher to
   // the given |Channel| (no more than
-  // |MessageInTransit::kMaxSerializedDispatcherSize|) and the maximum number of
+  // |TransportData::kMaxSerializedDispatcherSize|) and the maximum number of
   // |PlatformHandle|s that may need to be attached (no more than
-  // |MessageInTransit::kMaxSerializedDispatcherPlatformHandles|). If this
+  // |TransportData::kMaxSerializedDispatcherPlatformHandles|). If this
   // dispatcher cannot be serialized to the given |Channel|, |*max_size| and
   // |*max_platform_handles| should be set to zero. A call to this method will
   // ALWAYS be followed by a call to |EndSerializeAndClose()| (even if this
diff --git a/mojo/system/handle_table.cc b/mojo/system/handle_table.cc
index b863e81..dd5a5f4 100644
--- a/mojo/system/handle_table.cc
+++ b/mojo/system/handle_table.cc
@@ -76,9 +76,8 @@
                         AddDispatcherNoSizeCheck(dispatcher1));
 }
 
-bool HandleTable::AddDispatcherVector(
-    const std::vector<scoped_refptr<Dispatcher> >& dispatchers,
-    MojoHandle* handles) {
+bool HandleTable::AddDispatcherVector(const DispatcherVector& dispatchers,
+                                      MojoHandle* handles) {
   DCHECK_LE(dispatchers.size(), kMaxMessageNumHandles);
   DCHECK(handles);
   // TODO(vtl): |std::numeric_limits<size_t>::max()| isn't a compile-time
diff --git a/mojo/system/handle_table.h b/mojo/system/handle_table.h
index 408fae2..96f7aba 100644
--- a/mojo/system/handle_table.h
+++ b/mojo/system/handle_table.h
@@ -21,6 +21,8 @@
 class Dispatcher;
 class DispatcherTransport;
 
+typedef std::vector<scoped_refptr<Dispatcher> > DispatcherVector;
+
 // Test-only function (defined/used in embedder/test_embedder.cc). Declared here
 // so it can be friended.
 namespace internal {
@@ -74,9 +76,8 @@
   // of the dispatchers may be invalid (null). Returns true on success and false
   // on failure (if the handle table is full), in which case it leaves
   // |handles[...]| untouched (and all dispatchers unadded).
-  bool AddDispatcherVector(
-      const std::vector<scoped_refptr<Dispatcher> >& dispatchers,
-      MojoHandle* handles);
+  bool AddDispatcherVector(const DispatcherVector& dispatchers,
+                           MojoHandle* handles);
 
   // Tries to mark the given handles as busy and start transport on them (i.e.,
   // take their dispatcher locks); |transports| must be sized to contain
diff --git a/mojo/system/local_message_pipe_endpoint.cc b/mojo/system/local_message_pipe_endpoint.cc
index b5b6bd0..606ffa9 100644
--- a/mojo/system/local_message_pipe_endpoint.cc
+++ b/mojo/system/local_message_pipe_endpoint.cc
@@ -70,11 +70,11 @@
   waiter_list_.CancelAllWaiters();
 }
 
-MojoResult LocalMessagePipeEndpoint::ReadMessage(
-    void* bytes, uint32_t* num_bytes,
-    std::vector<scoped_refptr<Dispatcher> >* dispatchers,
-    uint32_t* num_dispatchers,
-    MojoReadMessageFlags flags) {
+MojoResult LocalMessagePipeEndpoint::ReadMessage(void* bytes,
+                                                 uint32_t* num_bytes,
+                                                 DispatcherVector* dispatchers,
+                                                 uint32_t* num_dispatchers,
+                                                 MojoReadMessageFlags flags) {
   DCHECK(is_open_);
   DCHECK(!dispatchers || dispatchers->empty());
 
@@ -97,8 +97,7 @@
   else
     enough_space = false;
 
-  if (std::vector<scoped_refptr<Dispatcher> >* queued_dispatchers =
-          message->dispatchers()) {
+  if (DispatcherVector* queued_dispatchers = message->dispatchers()) {
     if (num_dispatchers)
       *num_dispatchers = static_cast<uint32_t>(queued_dispatchers->size());
     if (enough_space) {
diff --git a/mojo/system/local_message_pipe_endpoint.h b/mojo/system/local_message_pipe_endpoint.h
index 963188f..d30f54b 100644
--- a/mojo/system/local_message_pipe_endpoint.h
+++ b/mojo/system/local_message_pipe_endpoint.h
@@ -31,11 +31,11 @@
   // implement/override these:
   virtual void Close() OVERRIDE;
   virtual void CancelAllWaiters() OVERRIDE;
-  virtual MojoResult ReadMessage(
-      void* bytes, uint32_t* num_bytes,
-      std::vector<scoped_refptr<Dispatcher> >* dispatchers,
-      uint32_t* num_dispatchers,
-      MojoReadMessageFlags flags) OVERRIDE;
+  virtual MojoResult ReadMessage(void* bytes,
+                                 uint32_t* num_bytes,
+                                 DispatcherVector* dispatchers,
+                                 uint32_t* num_dispatchers,
+                                 MojoReadMessageFlags flags) OVERRIDE;
   virtual MojoResult AddWaiter(Waiter* waiter,
                                MojoWaitFlags flags,
                                MojoResult wake_result) OVERRIDE;
diff --git a/mojo/system/message_in_transit.cc b/mojo/system/message_in_transit.cc
index c15d862..3235a75 100644
--- a/mojo/system/message_in_transit.cc
+++ b/mojo/system/message_in_transit.cc
@@ -6,12 +6,10 @@
 
 #include <string.h>
 
-#include <new>
-
 #include "base/compiler_specific.h"
 #include "base/logging.h"
-#include "base/memory/aligned_memory.h"
 #include "mojo/system/constants.h"
+#include "mojo/system/transport_data.h"
 
 namespace mojo {
 namespace system {
@@ -33,10 +31,6 @@
 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId
     MessageInTransit::kInvalidEndpointId;
 STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment;
-STATIC_CONST_MEMBER_DEFINITION const size_t
-    MessageInTransit::kMaxSerializedDispatcherSize;
-STATIC_CONST_MEMBER_DEFINITION const size_t
-    MessageInTransit::kMaxSerializedDispatcherPlatformHandles;
 
 struct MessageInTransit::PrivateStructForCompileAsserts {
   // The size of |Header| must be a multiple of the alignment.
@@ -52,26 +46,8 @@
   // size is a multiple of the alignment.
   COMPILE_ASSERT(kMaxMessageNumBytes % kMessageAlignment == 0,
                  kMessageAlignment_not_a_multiple_of_alignment);
-
-  // The maximum serialized dispatcher size must be a multiple of the alignment.
-  COMPILE_ASSERT(kMaxSerializedDispatcherSize % kMessageAlignment == 0,
-                 kMaxSerializedDispatcherSize_not_a_multiple_of_alignment);
-
-  // The size of |HandleTableEntry| must be a multiple of the alignment.
-  COMPILE_ASSERT(sizeof(HandleTableEntry) % kMessageAlignment == 0,
-                 sizeof_MessageInTransit_HandleTableEntry_invalid);
 };
 
-// For each attached (Mojo) handle, there'll be a handle table entry and
-// serialized dispatcher data.
-// static
-const size_t MessageInTransit::kMaxSecondaryBufferSize = kMaxMessageNumHandles *
-    (sizeof(HandleTableEntry) + kMaxSerializedDispatcherSize);
-
-// static
-const size_t MessageInTransit::kMaxPlatformHandles =
-    kMaxMessageNumHandles * kMaxSerializedDispatcherPlatformHandles;
-
 MessageInTransit::View::View(size_t message_size, const void* buffer)
     : buffer_(buffer) {
   size_t next_message_size = 0;
@@ -90,11 +66,13 @@
     return false;
   }
 
-  if (const char* secondary_buffer_error_message =
-          ValidateSecondaryBuffer(num_handles(), secondary_buffer(),
-                                  secondary_buffer_size())) {
-    *error_message = secondary_buffer_error_message;
-    return false;
+  if (transport_data_buffer_size() > 0) {
+    const char* e = TransportData::ValidateBuffer(transport_data_buffer(),
+                                                  transport_data_buffer_size());
+    if (e) {
+      *error_message = e;
+      return false;
+    }
   }
 
   return true;
@@ -103,14 +81,11 @@
 MessageInTransit::MessageInTransit(Type type,
                                    Subtype subtype,
                                    uint32_t num_bytes,
-                                   uint32_t num_handles,
                                    const void* bytes)
     : main_buffer_size_(RoundUpMessageAlignment(sizeof(Header) + num_bytes)),
-      main_buffer_(base::AlignedAlloc(main_buffer_size_, kMessageAlignment)),
-      secondary_buffer_size_(0),
-      secondary_buffer_(NULL) {
+      main_buffer_(static_cast<char*>(base::AlignedAlloc(main_buffer_size_,
+                                                         kMessageAlignment))) {
   DCHECK_LE(num_bytes, kMaxMessageNumBytes);
-  DCHECK_LE(num_handles, kMaxMessageNumHandles);
 
   // |total_size| is updated below, from the other values.
   header()->type = type;
@@ -118,9 +93,9 @@
   header()->source_id = kInvalidEndpointId;
   header()->destination_id = kInvalidEndpointId;
   header()->num_bytes = num_bytes;
-  header()->num_handles = num_handles;
-  // Note: If dispatchers are subsequently attached (in particular, if
-  // |num_handles| is nonzero), then |total_size| will have to be adjusted.
+  header()->unused = 0;
+  // Note: If dispatchers are subsequently attached, then |total_size| will have
+  // to be adjusted.
   UpdateTotalSize();
 
   if (bytes) {
@@ -132,30 +107,19 @@
   }
 }
 
-// TODO(vtl): Do I really want/need to copy the secondary buffer here, or should
-// I just create (deserialize) the dispatchers right away?
 MessageInTransit::MessageInTransit(const View& message_view)
     : main_buffer_size_(message_view.main_buffer_size()),
-      main_buffer_(base::AlignedAlloc(main_buffer_size_, kMessageAlignment)),
-      secondary_buffer_size_(message_view.secondary_buffer_size()),
-      secondary_buffer_(secondary_buffer_size_ ?
-                            base::AlignedAlloc(secondary_buffer_size_,
-                                               kMessageAlignment) : NULL) {
+      main_buffer_(static_cast<char*>(base::AlignedAlloc(main_buffer_size_,
+                                                         kMessageAlignment))) {
   DCHECK_GE(main_buffer_size_, sizeof(Header));
   DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u);
 
-  memcpy(main_buffer_, message_view.main_buffer(), main_buffer_size_);
-  memcpy(secondary_buffer_, message_view.secondary_buffer(),
-         secondary_buffer_size_);
-
+  memcpy(main_buffer_.get(), message_view.main_buffer(), main_buffer_size_);
   DCHECK_EQ(main_buffer_size_,
             RoundUpMessageAlignment(sizeof(Header) + num_bytes()));
 }
 
 MessageInTransit::~MessageInTransit() {
-  base::AlignedFree(main_buffer_);
-  base::AlignedFree(secondary_buffer_);  // Okay if null.
-
   if (dispatchers_) {
     for (size_t i = 0; i < dispatchers_->size(); i++) {
       if (!(*dispatchers_)[i])
@@ -165,20 +129,6 @@
       (*dispatchers_)[i]->Close();
     }
   }
-
-  if (platform_handles_) {
-    for (size_t i = 0; i < platform_handles_->size(); i++)
-      (*platform_handles_)[i].CloseIfNecessary();
-  }
-
-#ifndef NDEBUG
-  main_buffer_size_ = 0;
-  main_buffer_ = NULL;
-  secondary_buffer_size_ = 0;
-  secondary_buffer_ = NULL;
-  dispatchers_.reset();
-  platform_handles_.reset();
-#endif
 }
 
 // static
@@ -202,7 +152,7 @@
 }
 
 void MessageInTransit::SetDispatchers(
-    scoped_ptr<std::vector<scoped_refptr<Dispatcher> > > dispatchers) {
+    scoped_ptr<DispatcherVector> dispatchers) {
   DCHECK(dispatchers);
   DCHECK(!dispatchers_);
 
@@ -215,198 +165,24 @@
 
 void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) {
   DCHECK(channel);
-  DCHECK(!secondary_buffer_);
-  CHECK_EQ(num_handles(),
-           dispatchers_ ? dispatchers_->size() : static_cast<size_t>(0));
+  DCHECK(!transport_data_);
 
-  if (!num_handles())
+  if (!dispatchers_ || !dispatchers_->size())
     return;
 
-  // The offset to the start of the (Mojo) handle table.
-  // TODO(vtl): Add a header to the secondary buffer.
-  const size_t handle_table_start_offset = 0;
-  // The offset to the start of the serialized dispatcher data.
-  const size_t serialized_dispatcher_start_offset =
-      handle_table_start_offset + num_handles() * sizeof(HandleTableEntry);
-  // The size of the secondary buffer we'll add to this as we go along).
-  size_t size = serialized_dispatcher_start_offset;
-  size_t num_platform_handles = 0;
-#if DCHECK_IS_ON
-  std::vector<size_t> all_max_sizes(num_handles());
-  std::vector<size_t> all_max_platform_handles(num_handles());
-#endif
-  for (size_t i = 0; i < num_handles(); i++) {
-    if (Dispatcher* dispatcher = (*dispatchers_)[i].get()) {
-      size_t max_size = 0;
-      size_t max_platform_handles = 0;
-      Dispatcher::MessageInTransitAccess::StartSerialize(
-              dispatcher, channel, &max_size, &max_platform_handles);
+  transport_data_.reset(new TransportData(dispatchers_.Pass(), channel));
 
-      DCHECK_LE(max_size, kMaxSerializedDispatcherSize);
-      size += RoundUpMessageAlignment(max_size);
-      DCHECK_LE(size, kMaxSecondaryBufferSize);
-
-      DCHECK_LE(max_platform_handles,
-                kMaxSerializedDispatcherPlatformHandles);
-      num_platform_handles += max_platform_handles;
-      DCHECK_LE(num_platform_handles, kMaxPlatformHandles);
-
-#if DCHECK_IS_ON
-      all_max_sizes[i] = max_size;
-      all_max_platform_handles[i] = max_platform_handles;
-#endif
-    }
-  }
-
-  secondary_buffer_ = base::AlignedAlloc(size, kMessageAlignment);
-  secondary_buffer_size_ = static_cast<uint32_t>(size);
-  // Entirely clear out the secondary buffer, since then we won't have to worry
-  // about clearing padding or unused space (e.g., if a dispatcher fails to
-  // serialize).
-  memset(secondary_buffer_, 0, size);
-
-  if (num_platform_handles > 0) {
-    DCHECK(!platform_handles_);
-    platform_handles_.reset(new std::vector<embedder::PlatformHandle>());
-  }
-
-  HandleTableEntry* handle_table = reinterpret_cast<HandleTableEntry*>(
-      static_cast<char*>(secondary_buffer_) + handle_table_start_offset);
-  size_t current_offset = serialized_dispatcher_start_offset;
-  for (size_t i = 0; i < num_handles(); i++) {
-    Dispatcher* dispatcher = (*dispatchers_)[i].get();
-    if (!dispatcher) {
-      COMPILE_ASSERT(Dispatcher::kTypeUnknown == 0,
-                     value_of_Dispatcher_kTypeUnknown_must_be_zero);
-      continue;
-    }
-
-#if DCHECK_IS_ON
-    size_t old_platform_handles_size =
-        platform_handles_ ? platform_handles_->size() : 0;
-#endif
-
-    void* destination = static_cast<char*>(secondary_buffer_) + current_offset;
-    size_t actual_size = 0;
-    if (Dispatcher::MessageInTransitAccess::EndSerializeAndClose(
-            dispatcher, channel, destination, &actual_size,
-            platform_handles_.get())) {
-      handle_table[i].type = static_cast<int32_t>(dispatcher->GetType());
-      handle_table[i].offset = static_cast<uint32_t>(current_offset);
-      handle_table[i].size = static_cast<uint32_t>(actual_size);
-
-#if DCHECK_IS_ON
-      DCHECK_LE(actual_size, all_max_sizes[i]);
-      DCHECK_LE(platform_handles_ ? (platform_handles_->size() -
-                                         old_platform_handles_size) : 0,
-                all_max_platform_handles[i]);
-#endif
-    } else {
-      // Nothing to do on failure, since |secondary_buffer_| was cleared, and
-      // |kTypeUnknown| is zero. The handle was simply closed.
-      LOG(ERROR) << "Failed to serialize handle to remote message pipe";
-    }
-
-    current_offset += RoundUpMessageAlignment(actual_size);
-    DCHECK_LE(current_offset, size);
-    DCHECK_LE(platform_handles_ ? platform_handles_->size() : 0,
-              num_platform_handles);
-  }
-
+  // Update the sizes in the message header.
   UpdateTotalSize();
 }
 
-// Note: The message's secondary buffer should have been checked by calling
-// |View::IsValid()| (on the |View|) first.
-void MessageInTransit::DeserializeDispatchers(Channel* channel) {
-  DCHECK(!dispatchers_);
-
-  // Already checked by |View::IsValid()|:
-  DCHECK_LE(num_handles(), kMaxMessageNumHandles);
-
-  if (!num_handles())
-    return;
-
-  dispatchers_.reset(
-      new std::vector<scoped_refptr<Dispatcher> >(num_handles()));
-
-  size_t handle_table_size = num_handles() * sizeof(HandleTableEntry);
-  // Already checked by |View::IsValid()|:
-  DCHECK_LE(handle_table_size, secondary_buffer_size_);
-
-  const HandleTableEntry* handle_table =
-      static_cast<const HandleTableEntry*>(secondary_buffer_);
-  for (size_t i = 0; i < num_handles(); i++) {
-    size_t offset = handle_table[i].offset;
-    size_t size = handle_table[i].size;
-    // Already checked by |View::IsValid()|:
-    DCHECK_EQ(offset % kMessageAlignment, 0u);
-    DCHECK_LE(offset, secondary_buffer_size_);
-    DCHECK_LE(offset + size, secondary_buffer_size_);
-
-    const void* source = static_cast<const char*>(secondary_buffer_) + offset;
-    (*dispatchers_)[i] = Dispatcher::MessageInTransitAccess::Deserialize(
-        channel, handle_table[i].type, source, size);
-  }
-}
-
-// Validates the secondary buffer. Returns null on success, or a human-readable
-// error message on error.
-// static
-const char* MessageInTransit::ValidateSecondaryBuffer(
-    size_t num_handles,
-    const void* secondary_buffer,
-    size_t secondary_buffer_size) {
-  // Always make sure that the secondary buffer size is sane (even if we have no
-  // handles); if it's not, someone's messing with us.
-  if (secondary_buffer_size > kMaxSecondaryBufferSize)
-    return "Message secondary buffer too large";
-
-  // Fast-path for the common case (no handles => no secondary buffer).
-  if (num_handles == 0) {
-    // We shouldn't have a secondary buffer in this case.
-    if (secondary_buffer_size > 0)
-      return "Message has no handles attached, but secondary buffer present";
-    return NULL;
-  }
-
-  // Sanity-check |num_handles| (before multiplying it against anything).
-  if (num_handles > kMaxMessageNumHandles)
-    return "Message handle payload too large";
-
-  if (secondary_buffer_size < num_handles * sizeof(HandleTableEntry))
-    return "Message secondary buffer too small";
-
-  DCHECK(secondary_buffer);
-  const HandleTableEntry* handle_table =
-      static_cast<const HandleTableEntry*>(secondary_buffer);
-
-  static const char kInvalidSerializedDispatcher[] =
-      "Message contains invalid serialized dispatcher";
-  for (size_t i = 0; i < num_handles; i++) {
-    size_t offset = handle_table[i].offset;
-    if (offset % kMessageAlignment != 0)
-      return kInvalidSerializedDispatcher;
-
-    size_t size = handle_table[i].size;
-    if (size > kMaxSerializedDispatcherSize || size > secondary_buffer_size)
-      return kInvalidSerializedDispatcher;
-
-    // Note: This is an overflow-safe check for |offset + size >
-    // secondary_buffer_size()| (we know that |size <= secondary_buffer_size()|
-    // from the previous check).
-    if (offset > secondary_buffer_size - size)
-      return kInvalidSerializedDispatcher;
-  }
-
-  return NULL;
-}
-
 void MessageInTransit::UpdateTotalSize() {
   DCHECK_EQ(main_buffer_size_ % kMessageAlignment, 0u);
-  DCHECK_EQ(secondary_buffer_size_ % kMessageAlignment, 0u);
-  header()->total_size =
-      static_cast<uint32_t>(main_buffer_size_ + secondary_buffer_size_);
+  header()->total_size = static_cast<uint32_t>(main_buffer_size_);
+  if (transport_data_) {
+    header()->total_size +=
+        static_cast<uint32_t>(transport_data_->buffer_size());
+  }
 }
 
 }  // namespace system
diff --git a/mojo/system/message_in_transit.h b/mojo/system/message_in_transit.h
index 4018dd6..38c38d4 100644
--- a/mojo/system/message_in_transit.h
+++ b/mojo/system/message_in_transit.h
@@ -5,13 +5,14 @@
 #ifndef MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_
 #define MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_
 
+#include <stddef.h>
 #include <stdint.h>
 
 #include <vector>
 
 #include "base/macros.h"
+#include "base/memory/aligned_memory.h"
 #include "base/memory/scoped_ptr.h"
-#include "mojo/embedder/platform_handle.h"
 #include "mojo/system/dispatcher.h"
 #include "mojo/system/system_impl_export.h"
 
@@ -19,13 +20,14 @@
 namespace system {
 
 class Channel;
+class TransportData;
 
 // This class is used to represent data in transit. It is thread-unsafe.
 //
 // |MessageInTransit| buffers:
 //
 // A |MessageInTransit| can be serialized by writing the main buffer and then,
-// if it has one, the secondary buffer. Both buffers are
+// if it has one, the transport data buffer. Both buffers are
 // |kMessageAlignment|-byte aligned and a multiple of |kMessageAlignment| bytes
 // in size.
 //
@@ -35,11 +37,8 @@
 // |kMessageAlignment|-byte aligned), and then any padding needed to make the
 // main buffer a multiple of |kMessageAlignment| bytes in size.
 //
-// The secondary buffer consists first of a table of |HandleTableEntry|s (each
-// of which is already a multiple of |kMessageAlignment| in size), followed by
-// data needed for the |HandleTableEntry|s: A |HandleTableEntry| consists of an
-// offset (in bytes, relative to the start of the secondary buffer; we guarantee
-// that it's a multiple of |kMessageAlignment|), and a size (in bytes).
+// See |TransportData| for a description of the (serialized) transport data
+// buffer.
 class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit {
  public:
   typedef uint16_t Type;
@@ -68,14 +67,6 @@
   // quantity (which must be a power of 2).
   static const size_t kMessageAlignment = 8;
 
-  // The maximum size of a single serialized dispatcher. This must be a multiple
-  // of |kMessageAlignment|.
-  static const size_t kMaxSerializedDispatcherSize = 10000;
-
-  // The maximum number of platform handles to attach for a single serialized
-  // dispatcher.
-  static const size_t kMaxSerializedDispatcherPlatformHandles = 2;
-
   // Forward-declare |Header| so that |View| can use it:
  private:
   struct Header;
@@ -89,12 +80,10 @@
     // |buffer| should be |kMessageAlignment|-byte aligned.
     View(size_t message_size, const void* buffer);
 
-    // Checks the following things versus pre-determined limits:
-    //   - |num_bytes()| and |main_buffer_size()|,
-    //   - |num_handles()| and |secondary_buffer_size()|,
-    //   - the entries in the handle entry table (that the sizes and offsets are
-    //     valid).
-    // Note: It does not check the serialized dispatcher data itself.
+    // Checks that the given |View| appears to be for a valid message, within
+    // predetermined limits (e.g., |num_bytes()| and |main_buffer_size()|, that
+    // |transport_data_buffer()|/|transport_data_buffer_size()| is for valid
+    // transport data -- see |TransportData::ValidateBuffer()|).
     //
     // It returns true (and leaves |error_message| alone) if this object appears
     // to be a valid message (according to the above) and false, pointing
@@ -107,11 +96,11 @@
     size_t main_buffer_size() const {
       return RoundUpMessageAlignment(sizeof(Header) + header()->num_bytes);
     }
-    const void* secondary_buffer() const {
+    const void* transport_data_buffer() const {
       return (total_size() > main_buffer_size()) ?
           static_cast<const char*>(buffer_) + main_buffer_size() : NULL;
     }
-    size_t secondary_buffer_size() const {
+    size_t transport_data_buffer_size() const {
       return total_size() - main_buffer_size();
     }
     size_t total_size() const { return header()->total_size; }
@@ -119,7 +108,6 @@
     const void* bytes() const {
       return static_cast<const char*>(buffer_) + sizeof(Header);
     }
-    uint32_t num_handles() const { return header()->num_handles; }
     Type type() const { return header()->type; }
     Subtype subtype() const { return header()->subtype; }
     EndpointId source_id() const { return header()->source_id; }
@@ -140,7 +128,6 @@
   MessageInTransit(Type type,
                    Subtype subtype,
                    uint32_t num_bytes,
-                   uint32_t num_handles,
                    const void* bytes);
   // Constructs a |MessageInTransit| from a |View|.
   explicit MessageInTransit(const View& message_view);
@@ -162,8 +149,7 @@
   // not be referenced from anywhere else (in particular, not from the handle
   // table), i.e., each dispatcher must have a reference count of 1. This
   // message must not already have dispatchers.
-  void SetDispatchers(
-      scoped_ptr<std::vector<scoped_refptr<Dispatcher> > > dispatchers);
+  void SetDispatchers(scoped_ptr<DispatcherVector> dispatchers);
 
   // Serializes any dispatchers to the secondary buffer. This message must not
   // already have a secondary buffer (so this must only be called once). The
@@ -171,19 +157,12 @@
   // stays alive through the call.
   void SerializeAndCloseDispatchers(Channel* channel);
 
-  // Deserializes any dispatchers from the secondary buffer. This message must
-  // not have any dispatchers attached.
-  // TODO(vtl): Having to copy the secondary buffer (in the constructor from a
-  // |View|) is suboptimal. Maybe this should just be done in the constructor?
-  void DeserializeDispatchers(Channel* channel);
-
   // Gets the main buffer and its size (in number of bytes), respectively.
-  const void* main_buffer() const { return main_buffer_; }
+  const void* main_buffer() const { return main_buffer_.get(); }
   size_t main_buffer_size() const { return main_buffer_size_; }
 
-  // Gets the secondary buffer and its size (in number of bytes), respectively.
-  const void* secondary_buffer() const { return secondary_buffer_; }
-  size_t secondary_buffer_size() const { return secondary_buffer_size_; }
+  // Gets the transport data buffer (if any).
+  const TransportData* transport_data() const { return transport_data_.get(); }
 
   // Gets the total size of the message (see comment in |Header|, below).
   size_t total_size() const { return header()->total_size; }
@@ -192,12 +171,8 @@
   uint32_t num_bytes() const { return header()->num_bytes; }
 
   // Gets the message data (of size |num_bytes()| bytes).
-  const void* bytes() const {
-    return static_cast<const char*>(main_buffer_) + sizeof(Header);
-  }
-  void* bytes() { return static_cast<char*>(main_buffer_) + sizeof(Header); }
-
-  uint32_t num_handles() const { return header()->num_handles; }
+  const void* bytes() const { return main_buffer_.get() + sizeof(Header); }
+  void* bytes() { return main_buffer_.get() + sizeof(Header); }
 
   Type type() const { return header()->type; }
   Subtype subtype() const { return header()->subtype; }
@@ -212,34 +187,20 @@
   // Gets the dispatchers attached to this message; this may return null if
   // there are none. Note that the caller may mutate the set of dispatchers
   // (e.g., take ownership of all the dispatchers, leaving the vector empty).
-  std::vector<scoped_refptr<Dispatcher> >* dispatchers() {
-    return dispatchers_.get();
-  }
+  DispatcherVector* dispatchers() { return dispatchers_.get(); }
 
   // Returns true if this message has dispatchers attached.
   bool has_dispatchers() const {
     return dispatchers_ && !dispatchers_->empty();
   }
 
-  // Gets the platform-specific handles attached to this message; this may
-  // return null if there are none. Note that the caller may mutate the set of
-  // platform-specific handles.
-  std::vector<embedder::PlatformHandle>* platform_handles() {
-    return platform_handles_.get();
-  }
-
-  // Returns true if this message has platform-specific handles attached.
-  bool has_platform_handles() const {
-    return platform_handles_ && !platform_handles_->empty();
-  }
-
   // Rounds |n| up to a multiple of |kMessageAlignment|.
   static inline size_t RoundUpMessageAlignment(size_t n) {
     return (n + kMessageAlignment - 1) & ~(kMessageAlignment - 1);
   }
 
  private:
-  // To allow us to make assertions about |Header| in the .cc file.
+  // To allow us to make compile-assertions about |Header| in the .cc file.
   struct PrivateStructForCompileAsserts;
 
   // Header for the data (main buffer). Must be a multiple of
@@ -257,53 +218,26 @@
     EndpointId destination_id;  // 4 bytes.
     // Size of actual message data.
     uint32_t num_bytes;
-    // Number of handles "attached".
-    uint32_t num_handles;
-  };
-
-  struct HandleTableEntry {
-    int32_t type;  // From |Dispatcher::Type| (|kTypeUnknown| for "invalid").
-    uint32_t offset;  // Relative to the start of the secondary buffer.
-    uint32_t size;  // (Not including any padding.)
     uint32_t unused;
   };
 
-  // The maximum possible size of a valid secondary buffer.
-  static const size_t kMaxSecondaryBufferSize;
-
-  // The maximum total number of platform handles that may be attached.
-  static const size_t kMaxPlatformHandles;
-
-  // Validates the secondary buffer. Returns null on success, or a
-  // human-readable error message (meant for logging/debugging) on error.
-  static const char* ValidateSecondaryBuffer(size_t num_handles,
-                                             const void* secondary_buffer,
-                                             size_t secondary_buffer_size);
-
   const Header* header() const {
-    return static_cast<const Header*>(main_buffer_);
+    return reinterpret_cast<const Header*>(main_buffer_.get());
   }
-  Header* header() { return static_cast<Header*>(main_buffer_); }
+  Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); }
 
   void UpdateTotalSize();
 
-  size_t main_buffer_size_;
-  void* main_buffer_;
+  const size_t main_buffer_size_;
+  const scoped_ptr<char, base::AlignedFreeDeleter> main_buffer_;  // Never null.
 
-  size_t secondary_buffer_size_;
-  void* secondary_buffer_;  // May be null.
+  scoped_ptr<TransportData> transport_data_;  // May be null.
 
   // Any dispatchers that may be attached to this message. These dispatchers
   // should be "owned" by this message, i.e., have a ref count of exactly 1. (We
   // allow a dispatcher entry to be null, in case it couldn't be duplicated for
   // some reason.)
-  scoped_ptr<std::vector<scoped_refptr<Dispatcher> > > dispatchers_;
-
-  // Any platform-specific handles attached to this message (for inter-process
-  // transport). The vector (if any) owns the handles that it contains (and is
-  // responsible for closing them).
-  // TODO(vtl): With C++11, change it to a vector of |ScopedPlatformHandles|.
-  scoped_ptr<std::vector<embedder::PlatformHandle> > platform_handles_;
+  scoped_ptr<DispatcherVector> dispatchers_;
 
   DISALLOW_COPY_AND_ASSIGN(MessageInTransit);
 };
diff --git a/mojo/system/message_pipe.cc b/mojo/system/message_pipe.cc
index e154064..1df6527 100644
--- a/mojo/system/message_pipe.cc
+++ b/mojo/system/message_pipe.cc
@@ -72,24 +72,22 @@
     std::vector<DispatcherTransport>* transports,
     MojoWriteMessageFlags flags) {
   DCHECK(port == 0 || port == 1);
-  uint32_t num_handles =
-      transports ? static_cast<uint32_t>(transports->size()) : 0;
   return EnqueueMessageInternal(
       GetPeerPort(port),
       make_scoped_ptr(new MessageInTransit(
           MessageInTransit::kTypeMessagePipeEndpoint,
           MessageInTransit::kSubtypeMessagePipeEndpointData,
-          num_bytes, num_handles, bytes)),
+          num_bytes,
+          bytes)),
       transports);
 }
 
-MojoResult MessagePipe::ReadMessage(
-    unsigned port,
-    void* bytes,
-    uint32_t* num_bytes,
-    std::vector<scoped_refptr<Dispatcher> >* dispatchers,
-    uint32_t* num_dispatchers,
-    MojoReadMessageFlags flags) {
+MojoResult MessagePipe::ReadMessage(unsigned port,
+                                    void* bytes,
+                                    uint32_t* num_bytes,
+                                    DispatcherVector* dispatchers,
+                                    uint32_t* num_dispatchers,
+                                    MojoReadMessageFlags flags) {
   DCHECK(port == 0 || port == 1);
 
   base::AutoLock locker(lock_);
@@ -226,9 +224,6 @@
       return result;
   }
 
-  if (message->has_dispatchers())
-    DCHECK_EQ(message->dispatchers()->size(), message->num_handles());
-
   // The endpoint's |EnqueueMessage()| may not report failure.
   endpoints_[port]->EnqueueMessage(message.Pass());
   return MOJO_RESULT_OK;
@@ -239,7 +234,6 @@
     MessageInTransit* message,
     std::vector<DispatcherTransport>* transports) {
   DCHECK(!message->has_dispatchers());
-  DCHECK_EQ(transports->size(), message->num_handles());
 
   // You're not allowed to send either handle to a message pipe over the message
   // pipe, so check for this. (The case of trying to write a handle to itself is
@@ -264,8 +258,7 @@
 
   // Clone the dispatchers and attach them to the message. (This must be done as
   // a separate loop, since we want to leave the dispatchers alone on failure.)
-  scoped_ptr<std::vector<scoped_refptr<Dispatcher> > >
-      dispatchers(new std::vector<scoped_refptr<Dispatcher> >());
+  scoped_ptr<DispatcherVector> dispatchers(new DispatcherVector());
   dispatchers->reserve(transports->size());
   for (size_t i = 0; i < transports->size(); i++) {
     if ((*transports)[i].is_valid()) {
diff --git a/mojo/system/message_pipe.h b/mojo/system/message_pipe.h
index 7fef65b..10668da 100644
--- a/mojo/system/message_pipe.h
+++ b/mojo/system/message_pipe.h
@@ -58,7 +58,7 @@
   MojoResult ReadMessage(unsigned port,
                          void* bytes,
                          uint32_t* num_bytes,
-                         std::vector<scoped_refptr<Dispatcher> >* dispatchers,
+                         DispatcherVector* dispatchers,
                          uint32_t* num_dispatchers,
                          MojoReadMessageFlags flags);
   MojoResult AddWaiter(unsigned port,
diff --git a/mojo/system/message_pipe_dispatcher.cc b/mojo/system/message_pipe_dispatcher.cc
index fc626ef..6d82583 100644
--- a/mojo/system/message_pipe_dispatcher.cc
+++ b/mojo/system/message_pipe_dispatcher.cc
@@ -162,7 +162,7 @@
 MojoResult MessagePipeDispatcher::ReadMessageImplNoLock(
     void* bytes,
     uint32_t* num_bytes,
-    std::vector<scoped_refptr<Dispatcher> >* dispatchers,
+    DispatcherVector* dispatchers,
     uint32_t* num_dispatchers,
     MojoReadMessageFlags flags) {
   lock().AssertAcquired();
diff --git a/mojo/system/message_pipe_dispatcher.h b/mojo/system/message_pipe_dispatcher.h
index 9b1b3fa..3dc1547 100644
--- a/mojo/system/message_pipe_dispatcher.h
+++ b/mojo/system/message_pipe_dispatcher.h
@@ -66,12 +66,11 @@
       uint32_t num_bytes,
       std::vector<DispatcherTransport>* transports,
       MojoWriteMessageFlags flags) OVERRIDE;
-  virtual MojoResult ReadMessageImplNoLock(
-      void* bytes,
-      uint32_t* num_bytes,
-      std::vector<scoped_refptr<Dispatcher> >* dispatchers,
-      uint32_t* num_dispatchers,
-      MojoReadMessageFlags flags) OVERRIDE;
+  virtual MojoResult ReadMessageImplNoLock(void* bytes,
+                                           uint32_t* num_bytes,
+                                           DispatcherVector* dispatchers,
+                                           uint32_t* num_dispatchers,
+                                           MojoReadMessageFlags flags) OVERRIDE;
   virtual MojoResult AddWaiterImplNoLock(Waiter* waiter,
                                          MojoWaitFlags flags,
                                          MojoResult wake_result) OVERRIDE;
diff --git a/mojo/system/message_pipe_endpoint.cc b/mojo/system/message_pipe_endpoint.cc
index a1a7be3..128313e 100644
--- a/mojo/system/message_pipe_endpoint.cc
+++ b/mojo/system/message_pipe_endpoint.cc
@@ -18,11 +18,11 @@
   NOTREACHED();
 }
 
-MojoResult MessagePipeEndpoint::ReadMessage(
-    void* /*bytes*/, uint32_t* /*num_bytes*/,
-    std::vector<scoped_refptr<Dispatcher> >* /*dispatchers*/,
-    uint32_t* /*num_dispatchers*/,
-    MojoReadMessageFlags /*flags*/) {
+MojoResult MessagePipeEndpoint::ReadMessage(void* /*bytes*/,
+                                            uint32_t* /*num_bytes*/,
+                                            DispatcherVector* /*dispatchers*/,
+                                            uint32_t* /*num_dispatchers*/,
+                                            MojoReadMessageFlags /*flags*/) {
   NOTREACHED();
   return MOJO_RESULT_INTERNAL;
 }
diff --git a/mojo/system/message_pipe_endpoint.h b/mojo/system/message_pipe_endpoint.h
index d14c58a..46a67e1 100644
--- a/mojo/system/message_pipe_endpoint.h
+++ b/mojo/system/message_pipe_endpoint.h
@@ -60,11 +60,11 @@
   // operation involves both endpoints.
   virtual void Close();
   virtual void CancelAllWaiters();
-  virtual MojoResult ReadMessage(
-      void* bytes, uint32_t* num_bytes,
-      std::vector<scoped_refptr<Dispatcher> >* dispatchers,
-      uint32_t* num_dispatchers,
-      MojoReadMessageFlags flags);
+  virtual MojoResult ReadMessage(void* bytes,
+                                 uint32_t* num_bytes,
+                                 DispatcherVector* dispatchers,
+                                 uint32_t* num_dispatchers,
+                                 MojoReadMessageFlags flags);
   virtual MojoResult AddWaiter(Waiter* waiter,
                                MojoWaitFlags flags,
                                MojoResult wake_result);
diff --git a/mojo/system/raw_channel.cc b/mojo/system/raw_channel.cc
index 92b9a3d..27a8c28 100644
--- a/mojo/system/raw_channel.cc
+++ b/mojo/system/raw_channel.cc
@@ -14,6 +14,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/stl_util.h"
 #include "mojo/system/message_in_transit.h"
+#include "mojo/system/transport_data.h"
 
 namespace mojo {
 namespace system {
@@ -40,12 +41,17 @@
 void RawChannel::WriteBuffer::GetBuffers(std::vector<Buffer>* buffers) const {
   buffers->clear();
 
-  size_t bytes_to_write = GetTotalBytesToWrite();
-  if (bytes_to_write == 0)
+  if (message_queue_.empty())
     return;
 
   MessageInTransit* message = message_queue_.front();
-  if (!message->secondary_buffer_size()) {
+  DCHECK_LT(offset_, message->total_size());
+  size_t bytes_to_write = message->total_size() - offset_;
+
+  size_t transport_data_buffer_size = message->transport_data() ?
+      message->transport_data()->buffer_size() : 0;
+
+  if (!transport_data_buffer_size) {
     // Only write from the main buffer.
     DCHECK_LT(offset_, message->main_buffer_size());
     DCHECK_LE(bytes_to_write, message->main_buffer_size());
@@ -57,12 +63,12 @@
   }
 
   if (offset_ >= message->main_buffer_size()) {
-    // Only write from the secondary buffer.
+    // Only write from the transport data buffer.
     DCHECK_LT(offset_ - message->main_buffer_size(),
-              message->secondary_buffer_size());
-    DCHECK_LE(bytes_to_write, message->secondary_buffer_size());
+              transport_data_buffer_size);
+    DCHECK_LE(bytes_to_write, transport_data_buffer_size);
     Buffer buffer = {
-        static_cast<const char*>(message->secondary_buffer()) +
+        static_cast<const char*>(message->transport_data()->buffer()) +
             (offset_ - message->main_buffer_size()),
         bytes_to_write};
     buffers->push_back(buffer);
@@ -71,26 +77,19 @@
 
   // Write from both buffers.
   DCHECK_EQ(bytes_to_write, message->main_buffer_size() - offset_ +
-                                message->secondary_buffer_size());
+                                transport_data_buffer_size);
   Buffer buffer1 = {
-      static_cast<const char*>(message->main_buffer()) + offset_,
-      message->main_buffer_size() - offset_};
+    static_cast<const char*>(message->main_buffer()) + offset_,
+    message->main_buffer_size() - offset_
+  };
   buffers->push_back(buffer1);
   Buffer buffer2 = {
-      static_cast<const char*>(message->secondary_buffer()),
-      message->secondary_buffer_size()};
+    static_cast<const char*>(message->transport_data()->buffer()),
+    transport_data_buffer_size
+  };
   buffers->push_back(buffer2);
 }
 
-size_t RawChannel::WriteBuffer::GetTotalBytesToWrite() const {
-  if (message_queue_.empty())
-    return 0;
-
-  MessageInTransit* message = message_queue_.front();
-  DCHECK_LT(offset_, message->total_size());
-  return message->total_size() - offset_;
-}
-
 RawChannel::RawChannel()
     : message_loop_for_io_(NULL),
       delegate_(NULL),
@@ -159,7 +158,8 @@
   DCHECK(message);
 
   // TODO(vtl)
-  if (message->has_platform_handles()) {
+  if (message->transport_data() &&
+      message->transport_data()->has_platform_handles()) {
     NOTIMPLEMENTED();
     return false;
   }
@@ -346,23 +346,25 @@
   DCHECK(!write_buffer_->message_queue_.empty());
 
   if (result) {
-    if (bytes_written < write_buffer_->GetTotalBytesToWrite()) {
-      // Partial (or no) write.
-      write_buffer_->offset_ += bytes_written;
-    } else {
+    write_buffer_->offset_ += bytes_written;
+
+    MessageInTransit* message = write_buffer_->message_queue_.front();
+    if (write_buffer_->offset_ >= message->total_size()) {
       // Complete write.
-      DCHECK_EQ(bytes_written, write_buffer_->GetTotalBytesToWrite());
-      delete write_buffer_->message_queue_.front();
+      DCHECK_EQ(write_buffer_->offset_, message->total_size());
       write_buffer_->message_queue_.pop_front();
+      delete message;
       write_buffer_->offset_ = 0;
+
+      if (write_buffer_->message_queue_.empty())
+        return true;
     }
 
-    if (write_buffer_->message_queue_.empty())
-      return true;
-
     // Schedule the next write.
-    if (ScheduleWriteNoLock() == IO_PENDING)
+    IOResult io_result = ScheduleWriteNoLock();
+    if (io_result == IO_PENDING)
       return true;
+    DCHECK_EQ(io_result, IO_FAILED);
   }
 
   write_stopped_ = true;
diff --git a/mojo/system/raw_channel.h b/mojo/system/raw_channel.h
index 607a776..7f78a76 100644
--- a/mojo/system/raw_channel.h
+++ b/mojo/system/raw_channel.h
@@ -134,9 +134,11 @@
     WriteBuffer();
     ~WriteBuffer();
 
+    // Gets buffers to be written. These buffers will always come from the front
+    // of |message_queue_|. Once they are completely written, the front
+    // |MessageInTransit| should be popped (and destroyed); this is done in
+    // |OnWriteCompletedNoLock()|.
     void GetBuffers(std::vector<Buffer>* buffers) const;
-    // Returns the total size of all buffers returned by |GetBuffers()|.
-    size_t GetTotalBytesToWrite() const;
 
    private:
     friend class RawChannel;
diff --git a/mojo/system/raw_channel_posix.cc b/mojo/system/raw_channel_posix.cc
index cebbc9d..973e3c8 100644
--- a/mojo/system/raw_channel_posix.cc
+++ b/mojo/system/raw_channel_posix.cc
@@ -18,7 +18,6 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop/message_loop.h"
-#include "base/posix/eintr_wrapper.h"
 #include "base/synchronization/lock.h"
 #include "mojo/embedder/platform_channel_utils_posix.h"
 #include "mojo/embedder/platform_handle.h"
@@ -102,16 +101,33 @@
   size_t bytes_to_read = 0;
   read_buffer()->GetBuffer(&buffer, &bytes_to_read);
 
-  ssize_t read_result = HANDLE_EINTR(read(fd_.get().fd, buffer, bytes_to_read));
-
+  scoped_ptr<embedder::PlatformHandleVector> handles;
+  ssize_t read_result = embedder::PlatformChannelRecvmsg(fd_.get(),
+                                                         buffer,
+                                                         bytes_to_read,
+                                                         &handles);
   if (read_result > 0) {
     *bytes_read = static_cast<size_t>(read_result);
     return IO_SUCCEEDED;
   }
 
+  if (handles) {
+    if (read_result != 1) {
+      LOG(WARNING) << "Invalid control message with handles";
+      return IO_FAILED;
+    }
+
+    // TODO(vtl): Implement this ("buffer" received handles). For now, just drop
+    // them on the floor. (Discard this message entirely.)
+    NOTIMPLEMENTED();
+    for (size_t i = 0; i < handles->size(); i++)
+      (*handles)[i].CloseIfNecessary();
+    return ScheduleRead();
+  }
+
   // |read_result == 0| means "end of file".
   if (read_result == 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) {
-    PLOG_IF(ERROR, read_result != 0) << "read";
+    PLOG_IF(ERROR, read_result != 0) << "recvmsg";
 
     // Make sure that |OnFileCanReadWithoutBlocking()| won't be called again.
     read_watcher_.reset();
diff --git a/mojo/system/raw_channel_unittest.cc b/mojo/system/raw_channel_unittest.cc
index 22c52e7..a5b8cb4 100644
--- a/mojo/system/raw_channel_unittest.cc
+++ b/mojo/system/raw_channel_unittest.cc
@@ -40,7 +40,7 @@
   return make_scoped_ptr(
       new MessageInTransit(MessageInTransit::kTypeMessagePipeEndpoint,
                            MessageInTransit::kSubtypeMessagePipeEndpointData,
-                           num_bytes, 0, bytes.empty() ? NULL : &bytes[0]));
+                           num_bytes, bytes.empty() ? NULL : &bytes[0]));
 }
 
 bool CheckMessageData(const void* bytes, uint32_t num_bytes) {
diff --git a/mojo/system/remote_message_pipe_unittest.cc b/mojo/system/remote_message_pipe_unittest.cc
index 7deb252..e62c747 100644
--- a/mojo/system/remote_message_pipe_unittest.cc
+++ b/mojo/system/remote_message_pipe_unittest.cc
@@ -483,7 +483,7 @@
   // Read from MP 1, port 1.
   char read_buffer[100] = { 0 };
   uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
-  std::vector<scoped_refptr<Dispatcher> > read_dispatchers;
+  DispatcherVector read_dispatchers;
   uint32_t read_num_dispatchers = 10;  // Maximum to get.
   EXPECT_EQ(MOJO_RESULT_OK,
             mp1->ReadMessage(1, read_buffer, &read_buffer_size,
diff --git a/mojo/system/transport_data.cc b/mojo/system/transport_data.cc
new file mode 100644
index 0000000..789393f
--- /dev/null
+++ b/mojo/system/transport_data.cc
@@ -0,0 +1,255 @@
+// 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.
+
+#include "mojo/system/transport_data.h"
+
+#include <string.h>
+
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "mojo/system/constants.h"
+#include "mojo/system/message_in_transit.h"
+
+namespace mojo {
+namespace system {
+
+STATIC_CONST_MEMBER_DEFINITION const size_t
+    TransportData::kMaxSerializedDispatcherSize;
+STATIC_CONST_MEMBER_DEFINITION const size_t
+    TransportData::kMaxSerializedDispatcherPlatformHandles;
+
+// In additional to the header, for each attached (Mojo) handle there'll be a
+// handle table entry and serialized dispatcher data.
+// static
+const size_t TransportData::kMaxBufferSize =
+    sizeof(Header) + kMaxMessageNumHandles * (sizeof(HandleTableEntry) +
+                                              kMaxSerializedDispatcherSize);
+
+// static
+const size_t TransportData::kMaxPlatformHandles =
+    kMaxMessageNumHandles * kMaxSerializedDispatcherPlatformHandles;
+
+struct TransportData::PrivateStructForCompileAsserts {
+  // The size of |Header| must be a multiple of the alignment.
+  COMPILE_ASSERT(sizeof(Header) % MessageInTransit::kMessageAlignment == 0,
+                 sizeof_MessageInTransit_Header_invalid);
+
+  // The maximum serialized dispatcher size must be a multiple of the alignment.
+  COMPILE_ASSERT(kMaxSerializedDispatcherSize %
+                     MessageInTransit::kMessageAlignment == 0,
+                 kMaxSerializedDispatcherSize_not_a_multiple_of_alignment);
+
+  // The size of |HandleTableEntry| must be a multiple of the alignment.
+  COMPILE_ASSERT(sizeof(HandleTableEntry) %
+                     MessageInTransit::kMessageAlignment == 0,
+                 sizeof_MessageInTransit_HandleTableEntry_invalid);
+};
+
+TransportData::TransportData(scoped_ptr<DispatcherVector> dispatchers,
+                             Channel* channel)
+    : buffer_size_(0) {
+  DCHECK(dispatchers);
+  DCHECK(channel);
+
+  const size_t num_handles = dispatchers->size();
+  DCHECK_GT(num_handles, 0u);
+
+  // The offset to the start of the (Mojo) handle table.
+  const size_t handle_table_start_offset = sizeof(Header);
+  // The offset to the start of the serialized dispatcher data.
+  const size_t serialized_dispatcher_start_offset =
+      handle_table_start_offset + num_handles * sizeof(HandleTableEntry);
+  // The estimated size of the secondary buffer. We compute this estimate below.
+  // It must be at least as big as the (eventual) actual size.
+  size_t estimated_size = serialized_dispatcher_start_offset;
+  size_t num_platform_handles = 0;
+#if DCHECK_IS_ON
+  std::vector<size_t> all_max_sizes(num_handles);
+  std::vector<size_t> all_max_platform_handles(num_handles);
+#endif
+  for (size_t i = 0; i < num_handles; i++) {
+    if (Dispatcher* dispatcher = (*dispatchers)[i].get()) {
+      size_t max_size = 0;
+      size_t max_platform_handles = 0;
+      Dispatcher::TransportDataAccess::StartSerialize(
+              dispatcher, channel, &max_size, &max_platform_handles);
+
+      DCHECK_LE(max_size, kMaxSerializedDispatcherSize);
+      estimated_size += MessageInTransit::RoundUpMessageAlignment(max_size);
+      DCHECK_LE(estimated_size, kMaxBufferSize);
+
+      DCHECK_LE(max_platform_handles,
+                kMaxSerializedDispatcherPlatformHandles);
+      num_platform_handles += max_platform_handles;
+      DCHECK_LE(num_platform_handles, kMaxPlatformHandles);
+
+#if DCHECK_IS_ON
+      all_max_sizes[i] = max_size;
+      all_max_platform_handles[i] = max_platform_handles;
+#endif
+    }
+  }
+
+  buffer_.reset(static_cast<char*>(
+      base::AlignedAlloc(estimated_size, MessageInTransit::kMessageAlignment)));
+  // Entirely clear out the secondary buffer, since then we won't have to worry
+  // about clearing padding or unused space (e.g., if a dispatcher fails to
+  // serialize).
+  memset(buffer_.get(), 0, estimated_size);
+
+  if (num_platform_handles > 0) {
+    DCHECK(!platform_handles_);
+    platform_handles_.reset(new std::vector<embedder::PlatformHandle>());
+  }
+
+  Header* header = reinterpret_cast<Header*>(buffer_.get());
+  header->num_handles = static_cast<uint32_t>(num_handles);
+  // TODO(vtl): platform_handle_table_offset and num_platform_handles
+  // (Okay to not set |unused| since we cleared the entire buffer.)
+
+  HandleTableEntry* handle_table = reinterpret_cast<HandleTableEntry*>(
+      buffer_.get() + handle_table_start_offset);
+  size_t current_offset = serialized_dispatcher_start_offset;
+  for (size_t i = 0; i < num_handles; i++) {
+    Dispatcher* dispatcher = (*dispatchers)[i].get();
+    if (!dispatcher) {
+      COMPILE_ASSERT(Dispatcher::kTypeUnknown == 0,
+                     value_of_Dispatcher_kTypeUnknown_must_be_zero);
+      continue;
+    }
+
+#if DCHECK_IS_ON
+    size_t old_platform_handles_size =
+        platform_handles_ ? platform_handles_->size() : 0;
+#endif
+
+    void* destination = buffer_.get() + current_offset;
+    size_t actual_size = 0;
+    if (Dispatcher::TransportDataAccess::EndSerializeAndClose(
+            dispatcher, channel, destination, &actual_size,
+            platform_handles_.get())) {
+      handle_table[i].type = static_cast<int32_t>(dispatcher->GetType());
+      handle_table[i].offset = static_cast<uint32_t>(current_offset);
+      handle_table[i].size = static_cast<uint32_t>(actual_size);
+      // (Okay to not set |unused| since we cleared the entire buffer.)
+
+#if DCHECK_IS_ON
+      DCHECK_LE(actual_size, all_max_sizes[i]);
+      DCHECK_LE(platform_handles_ ? (platform_handles_->size() -
+                                         old_platform_handles_size) : 0,
+                all_max_platform_handles[i]);
+#endif
+    } else {
+      // Nothing to do on failure, since |buffer_| was cleared, and
+      // |kTypeUnknown| is zero. The handle was simply closed.
+      LOG(ERROR) << "Failed to serialize handle to remote message pipe";
+    }
+
+    current_offset += MessageInTransit::RoundUpMessageAlignment(actual_size);
+    DCHECK_LE(current_offset, estimated_size);
+    DCHECK_LE(platform_handles_ ? platform_handles_->size() : 0,
+              num_platform_handles);
+  }
+
+  // There's no aligned realloc, so it's no good way to release unused space (if
+  // we overshot our estimated space requirements).
+  buffer_size_ = current_offset;
+
+  // |dispatchers_| will be destroyed as it goes out of scope.
+}
+
+TransportData::~TransportData() {
+  if (platform_handles_) {
+    for (size_t i = 0; i < platform_handles_->size(); i++)
+      (*platform_handles_)[i].CloseIfNecessary();
+  }
+}
+
+// static
+const char* TransportData::ValidateBuffer(const void* buffer,
+                                          size_t buffer_size) {
+  DCHECK(buffer);
+  DCHECK_GT(buffer_size, 0u);
+
+  // Always make sure that the buffer size is sane; if it's not, someone's
+  // messing with us.
+  if (buffer_size < sizeof(Header) || buffer_size > kMaxBufferSize ||
+      buffer_size % MessageInTransit::kMessageAlignment != 0)
+    return "Invalid message secondary buffer size";
+
+  const Header* header = static_cast<const Header*>(buffer);
+  const size_t num_handles = header->num_handles;
+  if (num_handles == 0)
+    return "Message has no handles attached, but secondary buffer present";
+
+  // Sanity-check |num_handles| (before multiplying it against anything).
+  if (num_handles > kMaxMessageNumHandles)
+    return "Message handle payload too large";
+
+  if (buffer_size < sizeof(Header) + num_handles * sizeof(HandleTableEntry))
+    return "Message secondary buffer too small";
+
+  // TODO(vtl): Check |platform_handle_table_offset| and |num_platform_handles|
+  // once they're used.
+  if (header->platform_handle_table_offset != 0 ||
+      header->num_platform_handles != 0)
+    return "Bad message secondary buffer header values";
+
+  const HandleTableEntry* handle_table =
+      reinterpret_cast<const HandleTableEntry*>(
+          static_cast<const char*>(buffer) + sizeof(Header));
+  static const char kInvalidSerializedDispatcher[] =
+      "Message contains invalid serialized dispatcher";
+  for (size_t i = 0; i < num_handles; i++) {
+    size_t offset = handle_table[i].offset;
+    if (offset % MessageInTransit::kMessageAlignment != 0)
+      return kInvalidSerializedDispatcher;
+
+    size_t size = handle_table[i].size;
+    if (size > kMaxSerializedDispatcherSize || size > buffer_size)
+      return kInvalidSerializedDispatcher;
+
+    // Note: This is an overflow-safe check for |offset + size > buffer_size|
+    // (we know that |size <= buffer_size| from the previous check).
+    if (offset > buffer_size - size)
+      return kInvalidSerializedDispatcher;
+  }
+
+  return NULL;
+}
+
+// static
+scoped_ptr<DispatcherVector> TransportData::DeserializeDispatchersFromBuffer(
+    const void* buffer,
+    size_t buffer_size,
+    Channel* channel) {
+  DCHECK(buffer);
+  DCHECK_GT(buffer_size, 0u);
+  DCHECK(channel);
+
+  const Header* header = static_cast<const Header*>(buffer);
+  const size_t num_handles = header->num_handles;
+  scoped_ptr<DispatcherVector> dispatchers(new DispatcherVector(num_handles));
+
+  const HandleTableEntry* handle_table =
+      reinterpret_cast<const HandleTableEntry*>(
+          static_cast<const char*>(buffer) + sizeof(Header));
+  for (size_t i = 0; i < num_handles; i++) {
+    size_t offset = handle_table[i].offset;
+    size_t size = handle_table[i].size;
+    // Should already have been checked by |ValidateBuffer()|:
+    DCHECK_EQ(offset % MessageInTransit::kMessageAlignment, 0u);
+    DCHECK_LE(offset, buffer_size);
+    DCHECK_LE(offset + size, buffer_size);
+
+    const void* source = static_cast<const char*>(buffer) + offset;
+    (*dispatchers)[i] = Dispatcher::TransportDataAccess::Deserialize(
+        channel, handle_table[i].type, source, size);
+  }
+
+  return dispatchers.Pass();
+}
+
+}  // namespace system
+}  // namespace mojo
diff --git a/mojo/system/transport_data.h b/mojo/system/transport_data.h
new file mode 100644
index 0000000..569ff8e
--- /dev/null
+++ b/mojo/system/transport_data.h
@@ -0,0 +1,161 @@
+// 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.
+
+#ifndef MOJO_SYSTEM_TRANSPORT_DATA_H_
+#define MOJO_SYSTEM_TRANSPORT_DATA_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/aligned_memory.h"
+#include "base/memory/scoped_ptr.h"
+#include "mojo/embedder/platform_handle.h"
+#include "mojo/system/dispatcher.h"
+#include "mojo/system/system_impl_export.h"
+
+namespace mojo {
+namespace system {
+
+// This class is used by |MessageInTransit| to represent handles (|Dispatcher|s)
+// in various stages of serialization.
+//
+// The stages are:
+//   - Before reaching |TransportData|: Turn |DispatcherTransport|s into
+//     |Dispatcher|s that are "owned" by (and attached to) a |MessageInTransit|.
+//     This invalidates the handles in the space of the sending application
+//     (and, e.g., if another thread is waiting on such a handle, it'll be
+//     notified of this invalidation).
+//   - Serialize these dispatchers into the |TransportData|: First, for each
+//     attached dispatcher, there's an entry in the |TransportData|'s "handle
+//     table", which points to a segment of (dispatcher-type-dependent) data.
+//   - During the serialization of the dispatchers, |PlatformHandle|s may be
+//     detached from the dispatchers and attached to the |TransportData|.
+//   - Before sending the |MessageInTransit|, including its main buffer and the
+//     |TransportData|'s buffer, the |Channel| sends any |PlatformHandle|s (in a
+//     platform-, and possibly sandobx-situation-, specific way) first. In doing
+//     so, it appends a "platform handle table" to the |TransportData|
+//     containing information about how to deserialize these |PlatformHandle|s.
+//   - Finally, at this point, to send the |MessageInTransit|, there only
+//     remains "inert" data: the |MessageInTransit|'s main buffer and data from
+//     the |TransportData|, consisting of the "handle table" (one entry for each
+//     attached dispatcher), dispatcher-type-specific data (one segment for each
+//     entry in the "handle table"), and the "platform handle table" (one entry
+//     for each attached |PlatformHandle|).
+//
+// To receive a message (|MessageInTransit|), the "reverse" happens:
+//   - On POSIX, receive and buffer |PlatformHandle|s (i.e., FDs), which were
+//     sent before the "inert" data.
+//   - Receive the "inert" data from the |MessageInTransit|. Examine its
+//     "platform handle table". On POSIX, match its entries with the buffered
+//     |PlatformHandle|s, which were previously received. On Windows, do what's
+//     necessary to obtain |PlatformHandle|s (e.g.: i. if the sender is fully
+//     trusted and able to duplicate handle into the receiver, then just pick
+//     out the |HANDLE| value; ii. if the receiver is fully trusted and able to
+//     duplicate handles from the receiver, do the |DuplicateHandle()|; iii.
+//     otherwise, talk to a broker to get handles). Reattach all the
+//     |PlatformHandle|s to the |MessageInTransit|.
+//   - For each entry in the "handle table", use serialized dispatcher data to
+//     reconstitute a dispatcher, taking ownership of associated
+//     |PlatformHandle|s (and detaching them). Attach these dispatchers to the
+//     |MessageInTransit|.
+//   - At this point, the |MessageInTransit| consists of its main buffer
+//     (primarily the data payload) and the attached dispatchers; the
+//     |TransportData| can be discarded.
+//   - When |MojoReadMessage()| is to give data to the application, attach the
+//     dispatchers to the (global, "core") handle table, getting handles; give
+//     the application the data payload and these handles.
+//
+// TODO(vtl): Everything above involving |PlatformHandle|s.
+class MOJO_SYSTEM_IMPL_EXPORT TransportData {
+ public:
+  // The maximum size of a single serialized dispatcher. This must be a multiple
+  // of |kMessageAlignment|.
+  static const size_t kMaxSerializedDispatcherSize = 10000;
+
+  // The maximum number of platform handles to attach for a single serialized
+  // dispatcher.
+  static const size_t kMaxSerializedDispatcherPlatformHandles = 2;
+
+  TransportData(scoped_ptr<DispatcherVector> dispatchers, Channel* channel);
+  ~TransportData();
+
+  const void* buffer() const { return buffer_.get(); }
+  size_t buffer_size() const { return buffer_size_; }
+
+  // Gets attached platform-specific handles; this may return null if there are
+  // none. Note that the caller may mutate the set of platform-specific handles.
+  std::vector<embedder::PlatformHandle>* platform_handles() {
+    return platform_handles_.get();
+  }
+
+  // Returns true if there are platform-specific handles attached.
+  bool has_platform_handles() const {
+    return platform_handles_ && !platform_handles_->empty();
+  }
+
+  // Receive-side functions:
+
+  // Checks if the given buffer (from the "wire") looks like a valid
+  // |TransportData| buffer. (Should only be called if |buffer_size| is
+  // nonzero.) Returns null if valid, and a pointer to a human-readable error
+  // message (for debug/logging purposes) on error. Note: This checks the
+  // validity of the handle table entries (i.e., does range checking), but does
+  // not check that the validity of the actual serialized dispatcher
+  // information.
+  static const char* ValidateBuffer(const void* buffer, size_t buffer_size);
+
+  // Deserializes dispatchers from the given (serialized) transport data buffer
+  // (typically from a |MessageInTransit::View|). |buffer| should be non-null
+  // and |buffer_size| should be nonzero.
+  static scoped_ptr<DispatcherVector> DeserializeDispatchersFromBuffer(
+      const void* buffer,
+      size_t buffer_size,
+      Channel* channel);
+
+ private:
+  // To allow us to make compile-assertions about |Header|, etc. in the .cc
+  // file.
+  struct PrivateStructForCompileAsserts;
+
+  // Header for the "secondary buffer"/"transport data". Must be a multiple of
+  // |MessageInTransit::kMessageAlignment| in size. Must be POD.
+  struct Header {
+    uint32_t num_handles;
+    // TODO(vtl): Not used yet:
+    uint32_t platform_handle_table_offset;
+    uint32_t num_platform_handles;
+    uint32_t unused;
+  };
+
+  struct HandleTableEntry {
+    int32_t type;  // From |Dispatcher::Type| (|kTypeUnknown| for "invalid").
+    uint32_t offset;  // Relative to the start of the "secondary buffer".
+    uint32_t size;  // (Not including any padding.)
+    uint32_t unused;
+  };
+
+  // The maximum possible size of a valid transport data buffer.
+  static const size_t kMaxBufferSize;
+
+  // The maximum total number of platform handles that may be attached.
+  static const size_t kMaxPlatformHandles;
+
+  size_t buffer_size_;
+  scoped_ptr<char, base::AlignedFreeDeleter> buffer_;  // Never null.
+
+  // Any platform-specific handles attached to this message (for inter-process
+  // transport). The vector (if any) owns the handles that it contains (and is
+  // responsible for closing them).
+  // TODO(vtl): With C++11, change it to a vector of |ScopedPlatformHandles|.
+  scoped_ptr<std::vector<embedder::PlatformHandle> > platform_handles_;
+
+  DISALLOW_COPY_AND_ASSIGN(TransportData);
+};
+
+}  // namespace system
+}  // namespace mojo
+
+#endif  // MOJO_SYSTEM_TRANSPORT_DATA_H_
diff --git a/native_client_sdk/doc_generated/devguide/coding/application-structure.html b/native_client_sdk/doc_generated/devguide/coding/application-structure.html
index 083b73a..a11581f 100644
--- a/native_client_sdk/doc_generated/devguide/coding/application-structure.html
+++ b/native_client_sdk/doc_generated/devguide/coding/application-structure.html
@@ -74,9 +74,10 @@
 manifest file and a Native Client manifest file.</p>
 <p>A <strong>Chrome Web Store manifest file</strong> is a file with information about a web
 application that is published in the Chrome Web Store. This file, named
-<code>manifest.json</code>, is required for applications that are published in the Chrome
-Web Store. For more information about this file see <a class="reference internal" href="/native-client/devguide/distributing.html"><em>Distributing Your
-Application</em></a>.  and the <a class="reference external" href="http://code.google.com/chrome/extensions/manifest.html">Chrome Web Store manifest file format</a>.</p>
+<code>manifest.json</code>, is required for applications that are published in the
+Chrome Web Store. For more information about this file see <a class="reference internal" href="/native-client/devguide/distributing.html"><em>Distributing
+Your Application</em></a>.  and the <a class="reference external" href="/extensions/manifest">Chrome Web Store manifest file
+format</a>.</p>
 <p>A <strong>Native Client manifest file</strong> is a file that specifies which Native Client
 module (executable) to load. For PNaCl it specifies a single portable
 executable; otherwise it specifies one for each of the supported end-user
diff --git a/native_client_sdk/doc_generated/devguide/coding/message-system.html b/native_client_sdk/doc_generated/devguide/coding/message-system.html
index 87f84b3..ef09cdf 100644
--- a/native_client_sdk/doc_generated/devguide/coding/message-system.html
+++ b/native_client_sdk/doc_generated/devguide/coding/message-system.html
@@ -58,7 +58,7 @@
 <p>Native Client modules and JavaScript communicate by sending messages to each
 other. The most basic form of a message is a string.  Messages support many
 JavaScript types, including ints, arrays, array buffers, and dictionaries (see
-<a class="reference external" href="h/native-client/pepper_stable/cpp/classpp_1_1_var">pp::Var</a>,
+<a class="reference external" href="/native-client/pepper_stable/cpp/classpp_1_1_var">pp::Var</a>,
 <a class="reference external" href="/native-client/pepper_stable/cpp/classpp_1_1_var_array_buffer">pp:VarArrayBuffer</a>, and the
 general <a class="reference external" href="/native-client/pepper_stable/c/struct_p_p_b___messaging__1__0">messaging system documentation</a>).  It&#8217;s up to
 you to decide on the type of message and define how to process the messages on
diff --git a/native_client_sdk/doc_generated/reference/pnacl-bitcode-abi.html b/native_client_sdk/doc_generated/reference/pnacl-bitcode-abi.html
index 246154a..a46683a 100644
--- a/native_client_sdk/doc_generated/reference/pnacl-bitcode-abi.html
+++ b/native_client_sdk/doc_generated/reference/pnacl-bitcode-abi.html
@@ -24,31 +24,32 @@
 <li><p class="first"><a class="reference internal" href="#type-system" id="id15">Type System</a></p>
 <ul class="small-gap">
 <li><a class="reference internal" href="#scalar-types" id="id16">Scalar types</a></li>
-<li><a class="reference internal" href="#array-and-struct-types" id="id17">Array and struct types</a></li>
-<li><a class="reference internal" href="#pointer-types" id="id18">Pointer types</a></li>
-<li><a class="reference internal" href="#undefined-values" id="id19">Undefined Values</a></li>
-<li><a class="reference internal" href="#constant-expressions" id="id20">Constant Expressions</a></li>
+<li><a class="reference internal" href="#vector-types" id="id17">Vector types</a></li>
+<li><a class="reference internal" href="#array-and-struct-types" id="id18">Array and struct types</a></li>
+<li><a class="reference internal" href="#pointer-types" id="id19">Pointer types</a></li>
+<li><a class="reference internal" href="#undefined-values" id="id20">Undefined Values</a></li>
+<li><a class="reference internal" href="#constant-expressions" id="id21">Constant Expressions</a></li>
 </ul>
 </li>
-<li><p class="first"><a class="reference internal" href="#other-values" id="id21">Other Values</a></p>
+<li><p class="first"><a class="reference internal" href="#other-values" id="id22">Other Values</a></p>
 <ul class="small-gap">
-<li><a class="reference internal" href="#metadata-nodes-and-metadata-strings" id="id22">Metadata Nodes and Metadata Strings</a></li>
+<li><a class="reference internal" href="#metadata-nodes-and-metadata-strings" id="id23">Metadata Nodes and Metadata Strings</a></li>
 </ul>
 </li>
-<li><a class="reference internal" href="#intrinsic-global-variables" id="id23">Intrinsic Global Variables</a></li>
-<li><a class="reference internal" href="#errno-and-errors-in-arithmetic-instructions" id="id24">Errno and errors in arithmetic instructions</a></li>
-<li><p class="first"><a class="reference internal" href="#instruction-reference" id="id25">Instruction Reference</a></p>
+<li><a class="reference internal" href="#intrinsic-global-variables" id="id24">Intrinsic Global Variables</a></li>
+<li><a class="reference internal" href="#errno-and-errors-in-arithmetic-instructions" id="id25">Errno and errors in arithmetic instructions</a></li>
+<li><p class="first"><a class="reference internal" href="#instruction-reference" id="id26">Instruction Reference</a></p>
 <ul class="small-gap">
-<li><a class="reference internal" href="#list-of-allowed-instructions" id="id26">List of allowed instructions</a></li>
-<li><a class="reference internal" href="#alloca" id="id27"><code>alloca</code></a></li>
+<li><a class="reference internal" href="#list-of-allowed-instructions" id="id27">List of allowed instructions</a></li>
+<li><a class="reference internal" href="#alloca" id="id28"><code>alloca</code></a></li>
 </ul>
 </li>
-<li><p class="first"><a class="reference internal" href="#intrinsic-functions" id="id28">Intrinsic Functions</a></p>
+<li><p class="first"><a class="reference internal" href="#intrinsic-functions" id="id29">Intrinsic Functions</a></p>
 <ul class="small-gap">
-<li><a class="reference internal" href="#list-of-allowed-intrinsics" id="id29">List of allowed intrinsics</a></li>
-<li><a class="reference internal" href="#thread-pointer-related-intrinsics" id="id30">Thread pointer related intrinsics</a></li>
-<li><a class="reference internal" href="#setjmp-and-longjmp" id="id31">Setjmp and Longjmp</a></li>
-<li><a class="reference internal" href="#atomic-intrinsics" id="id32">Atomic intrinsics</a></li>
+<li><a class="reference internal" href="#list-of-allowed-intrinsics" id="id30">List of allowed intrinsics</a></li>
+<li><a class="reference internal" href="#thread-pointer-related-intrinsics" id="id31">Thread pointer related intrinsics</a></li>
+<li><a class="reference internal" href="#setjmp-and-longjmp" id="id32">Setjmp and Longjmp</a></li>
+<li><a class="reference internal" href="#atomic-intrinsics" id="id33">Atomic intrinsics</a></li>
 </ul>
 </li>
 </ul>
@@ -182,6 +183,16 @@
 </ul>
 </li>
 </ul>
+</section><section id="vector-types">
+<h3 id="vector-types">Vector types</h3>
+<p>The only vector types allowed are:</p>
+<ul class="small-gap">
+<li>128-bit vectors integers of elements size i8, i16, i32.</li>
+<li>128-bit vectors of float elements.</li>
+<li>Vectors of i1 type with element counts corresponding to the allowed
+element counts listed previously (their width is therefore not
+128-bits).</li>
+</ul>
 </section><section id="array-and-struct-types">
 <h3 id="array-and-struct-types">Array and struct types</h3>
 <p>Array and struct types are only allowed in
@@ -308,6 +319,8 @@
 <li><code>select</code></li>
 <li><code>call</code></li>
 <li><code>unreachable</code></li>
+<li><code>insertelement</code></li>
+<li><code>extractelement</code></li>
 </ul>
 </section><section id="alloca">
 <span id="bitcode-allocainst"></span><h3 id="alloca"><span id="bitcode-allocainst"></span><code>alloca</code></h3>
diff --git a/native_client_sdk/doc_generated/reference/pnacl-c-cpp-language-support.html b/native_client_sdk/doc_generated/reference/pnacl-c-cpp-language-support.html
index 5fc75ec..512c063 100644
--- a/native_client_sdk/doc_generated/reference/pnacl-c-cpp-language-support.html
+++ b/native_client_sdk/doc_generated/reference/pnacl-c-cpp-language-support.html
@@ -203,7 +203,8 @@
 new compiler intrinsics.</p>
 <p>Vector types can be used through the <code>vector_size</code> attribute:</p>
 <pre class="prettyprint">
-typedef int v4s __attribute__((vector_size(16)));
+#define VECTOR_BYTES 16
+typedef int v4s __attribute__((vector_size(VECTOR_BYTES)));
 v4s a = {1,2,3,4};
 v4s b = {5,6,7,8};
 v4s c, d, e;
@@ -312,7 +313,39 @@
   std::cout &lt;&lt; std::endl;
 }
 </pre>
-<p>Vector shuffles are currently unsupported but will be added soon.</p>
+<p>Vector shuffles (often called permutation or swizzle) operations are
+supported through <code>__builtin_shufflevector</code>. The builtin has two
+vector arguments of the same element type, followed by a list of
+constant integers that specify the element indices of the first two
+vectors that should be extracted and returned in a new vector. These
+element indices are numbered sequentially starting with the first
+vector, continuing into the second vector. Thus, if <code>vec1</code> is a
+4-element vector, index <code>5</code> would refer to the second element of
+<code>vec2</code>. An index of <code>-1</code> can be used to indicate that the
+corresponding element in the returned vector is a don’t care and can be
+optimized by the backend.</p>
+<p>The result of <code>__builtin_shufflevector</code> is a vector with the same
+element type as <code>vec1</code> / <code>vec2</code> but that has an element count equal
+to the number of indices specified.</p>
+<pre class="prettyprint">
+// identity operation - return 4-element vector v1.
+__builtin_shufflevector(v1, v1, 0, 1, 2, 3)
+
+// &quot;Splat&quot; element 0 of V1 into a 4-element result.
+__builtin_shufflevector(V1, V1, 0, 0, 0, 0)
+
+// Reverse 4-element vector V1.
+__builtin_shufflevector(V1, V1, 3, 2, 1, 0)
+
+// Concatenate every other element of 4-element vectors V1 and V2.
+__builtin_shufflevector(V1, V2, 0, 2, 4, 6)
+
+// Concatenate every other element of 8-element vectors V1 and V2.
+__builtin_shufflevector(V1, V2, 0, 2, 4, 6, 8, 10, 12, 14)
+
+// Shuffle v1 with some elements being undefined
+__builtin_shufflevector(v1, v1, 3, -1, 1, -1)
+</pre>
 </section><section id="auto-vectorization">
 <h3 id="auto-vectorization">Auto-Vectorization</h3>
 <p>Auto-vectorization is currently not enabled for Portable Native Client,
diff --git a/native_client_sdk/src/build_tools/build_sdk.py b/native_client_sdk/src/build_tools/build_sdk.py
index d06c7e6..b8a674f 100755
--- a/native_client_sdk/src/build_tools/build_sdk.py
+++ b/native_client_sdk/src/build_tools/build_sdk.py
@@ -49,7 +49,12 @@
 import getos
 import oshelpers
 
-CYGTAR = os.path.join(NACL_DIR, 'build', 'cygtar.py')
+BUILD_DIR = os.path.join(NACL_DIR, 'build')
+NACL_TOOLCHAIN_DIR = os.path.join(NACL_DIR, 'toolchain')
+NACL_TOOLCHAINTARS_DIR = os.path.join(NACL_TOOLCHAIN_DIR, '.tars')
+
+CYGTAR = os.path.join(BUILD_DIR, 'cygtar.py')
+PKGVER = os.path.join(BUILD_DIR, 'package_version', 'package_version.py')
 
 NACLPORTS_URL = 'https://naclports.googlecode.com/svn/trunk/src'
 NACLPORTS_REV = 1226
@@ -58,29 +63,14 @@
 
 options = None
 
-
-def GetGlibcToolchain():
-  tcdir = os.path.join(NACL_DIR, 'toolchain', '.tars')
-  tcname = 'toolchain_%s_x86.tar.bz2' % getos.GetPlatform()
-  return os.path.join(tcdir, tcname)
-
-
-def GetNewlibToolchain():
-  tcdir = os.path.join(NACL_DIR, 'toolchain', '.tars')
-  tcname = 'naclsdk_%s_x86.tgz' % getos.GetPlatform()
-  return os.path.join(tcdir, tcname)
-
-
-def GetBionicToolchain():
-  tcdir = os.path.join(NACL_DIR, 'toolchain', '.tars')
-  tcname = 'naclsdk_%s_arm_bionic.tgz' % getos.GetPlatform()
-  return os.path.join(tcdir, tcname)
-
-
-def GetPNaClToolchain():
-  tcdir = os.path.join(NACL_DIR, 'toolchain', '.tars')
-  tcname = 'naclsdk_pnacl_%s_x86.tgz' % getos.GetPlatform()
-  return os.path.join(tcdir, tcname)
+  # Map of: ToolchainName: (PackageName, SDKDir).
+TOOLCHAIN_PACKAGE_MAP = {
+    'newlib': ('nacl_x86_newlib', '%(platform)s_x86_newlib'),
+    'bionic': ('nacl_arm_bionic', '%(platform)s_arm_bionic'),
+    'arm': ('nacl_arm_newlib', '%(platform)s_arm_newlib'),
+    'glibc': ('nacl_x86_glibc', '%(platform)s_x86_glibc'),
+    'pnacl': ('pnacl_newlib', '%(platform)s_pnacl')
+    }
 
 
 def GetToolchainNaClInclude(tcname, tcpath, arch):
@@ -131,8 +121,14 @@
 
 
 def GetGypToolchainLib(tcname, xarch):
-  tcpath = os.path.join(GetGypGenDir(xarch), 'sdk', 'toolchain',
-                        GetToolchainDirName(tcname, xarch))
+  if xarch == 'arm':
+    toolchain = xarch
+  else:
+    toolchain = tcname
+
+  tcpath = os.path.join(GetGypGenDir(xarch), 'sdk',
+                        '%s_x86' % getos.GetPlatform(),
+                        TOOLCHAIN_PACKAGE_MAP[toolchain][0])
   return GetToolchainNaClLib(tcname, tcpath, xarch)
 
 
@@ -149,12 +145,12 @@
 
 
 def BuildStepDownloadToolchains(toolchains):
-  buildbot_common.BuildStep('Running download_toolchains.py')
-  download_script = os.path.join('build', 'download_toolchains.py')
-  args = [sys.executable, download_script, '--no-arm-trusted',
-          '--arm-untrusted', '--keep']
+  buildbot_common.BuildStep('Running package_version.py')
+  args = [sys.executable, PKGVER, '--exclude', 'arm_trusted']
   if 'bionic' in toolchains:
-    args.append('--allow-bionic')
+    build_platform = '%s_x86' % getos.GetPlatform()
+    args.extend(['--append', os.path.join(build_platform, 'nacl_arm_bionic')])
+  args.append('sync')
   buildbot_common.Run(args, cwd=NACL_DIR)
 
 
@@ -199,66 +195,39 @@
 def BuildStepUntarToolchains(pepperdir, toolchains):
   buildbot_common.BuildStep('Untar Toolchains')
   platform = getos.GetPlatform()
+  build_platform = '%s_x86' % platform
   tmpdir = os.path.join(OUT_DIR, 'tc_temp')
   buildbot_common.RemoveDir(tmpdir)
   buildbot_common.MakeDir(tmpdir)
 
-  if 'newlib' in toolchains:
-    # Untar the newlib toolchains
-    tarfile = GetNewlibToolchain()
-    buildbot_common.Run([sys.executable, CYGTAR, '-C', tmpdir, '-xf', tarfile],
-                        cwd=NACL_DIR)
+  # Create a list of extract packages tuples, the first part should be
+  # "$PACKAGE_TARGET/$PACKAGE". The second part should be the destination
+  # directory relative to pepperdir/toolchain.
+  extract_packages = []
+  for toolchain in toolchains:
+    toolchain_map = TOOLCHAIN_PACKAGE_MAP.get(toolchain, None)
+    if toolchain_map:
+      package_name, tcname = toolchain_map
+      package_tuple = (os.path.join(build_platform, package_name),
+                       tcname % {'platform': platform})
+      extract_packages.append(package_tuple)
 
-    # Then rename/move it to the pepper toolchain directory
-    srcdir = os.path.join(tmpdir, 'sdk', 'nacl-sdk')
-    tcname = platform + '_x86_newlib'
-    newlibdir = os.path.join(pepperdir, 'toolchain', tcname)
-    buildbot_common.Move(srcdir, newlibdir)
+  if extract_packages:
+    # Extract all of the packages into the temp directory.
+    package_names = [package_tuple[0] for package_tuple in extract_packages]
+    buildbot_common.Run([sys.executable, PKGVER,
+                           '--packages', ','.join(package_names),
+                           '--tar-dir', NACL_TOOLCHAINTARS_DIR,
+                           '--dest-dir', tmpdir,
+                           'extract'])
 
-  if 'bionic' in toolchains:
-    # Untar the bionic toolchains
-    tarfile = GetBionicToolchain()
-    tcname = platform + '_arm_bionic'
-    buildbot_common.Run([sys.executable, CYGTAR, '-C', tmpdir, '-xf', tarfile],
-                        cwd=NACL_DIR)
-    srcdir = os.path.join(tmpdir, tcname)
-    bionicdir = os.path.join(pepperdir, 'toolchain', tcname)
-    buildbot_common.Move(srcdir, bionicdir)
+    # Move all the packages we extracted to the correct destination.
+    for package_name, dest_dir in extract_packages:
+      full_src_dir = os.path.join(tmpdir, package_name)
+      full_dst_dir = os.path.join(pepperdir, 'toolchain', dest_dir)
+      buildbot_common.Move(full_src_dir, full_dst_dir)
 
-  if 'arm' in toolchains:
-    # Copy the existing arm toolchain from native_client tree
-    tcname = platform + '_arm_newlib'
-    arm_toolchain = os.path.join(NACL_DIR, 'toolchain', '%s_x86' % platform,
-                                 'nacl_arm_newlib' )
-    arm_toolchain_sdk = os.path.join(pepperdir, 'toolchain', tcname)
-    buildbot_common.CopyDir(arm_toolchain, arm_toolchain_sdk)
-
-  if 'glibc' in toolchains:
-    # Untar the glibc toolchains
-    tarfile = GetGlibcToolchain()
-    tcname = platform + '_x86_glibc'
-    buildbot_common.Run([sys.executable, CYGTAR, '-C', tmpdir, '-xf', tarfile],
-                        cwd=NACL_DIR)
-
-    # Then rename/move it to the pepper toolchain directory
-    srcdir = os.path.join(tmpdir, 'toolchain', platform + '_x86')
-    glibcdir = os.path.join(pepperdir, 'toolchain', tcname)
-    buildbot_common.Move(srcdir, glibcdir)
-
-  # Untar the pnacl toolchains
-  if 'pnacl' in toolchains:
-    tmpdir = os.path.join(tmpdir, 'pnacl')
-    buildbot_common.RemoveDir(tmpdir)
-    buildbot_common.MakeDir(tmpdir)
-    tarfile = GetPNaClToolchain()
-    tcname = platform + '_pnacl'
-    buildbot_common.Run([sys.executable, CYGTAR, '-C', tmpdir, '-xf', tarfile],
-                        cwd=NACL_DIR)
-
-    # Then rename/move it to the pepper toolchain directory
-    pnacldir = os.path.join(pepperdir, 'toolchain', tcname)
-    buildbot_common.Move(tmpdir, pnacldir)
-
+  # Cleanup the temporary directory we are no longer using.
   buildbot_common.RemoveDir(tmpdir)
 
 
@@ -533,7 +502,7 @@
   out_dir = MakeNinjaRelPath(rel_out_dir)
   gyp_file = os.path.join(SRC_DIR, 'ppapi', 'native_client', 'src',
                           'untrusted', 'pnacl_irt_shim', 'pnacl_irt_shim.gyp')
-  targets = ['pnacl_irt_shim_aot']
+  targets = ['shim_aot']
   GypNinjaBuild(target_arch, gyp_py, gyp_file, targets, out_dir, False)
 
 
@@ -940,9 +909,12 @@
     options.bionic = True
     toolchain_build = os.path.join(options.nacl_tree_path, 'toolchain_build')
     print 'WARNING: Building bionic toolchain from NaCl checkout.'
-    print 'This option builds bionic in a NativeClient checkout and uses the'
-    print 'results instead of downloading a toolchain from the builder.'
-    print 'This may result in a NaCl SDK that can not run on ToT chrome.'
+    print 'This option builds bionic from the sources currently in the'
+    print 'provided NativeClient checkout, and the results instead of '
+    print 'downloading a toolchain from the builder. This may result in a'
+    print 'NaCl SDK that can not run on ToT chrome.'
+    print 'NOTE:  To clobber you will need to run toolchain_build_bionic.py'
+    print 'directly from the NativeClient checkout.'
     print ''
     response = raw_input("Type 'y' and hit enter to continue.\n")
     if response != 'y' and response != 'Y':
@@ -951,7 +923,7 @@
 
     # Get head version of NativeClient tree
     buildbot_common.BuildStep('Build bionic toolchain.')
-    buildbot_common.Run([sys.executable, 'toolchain_build_bionic.py'],
+    buildbot_common.Run([sys.executable, 'toolchain_build_bionic.py', '-f'],
                         cwd=toolchain_build)
   else:
     toolchain_build = None
@@ -1061,4 +1033,3 @@
     sys.exit(main(sys.argv))
   except KeyboardInterrupt:
     buildbot_common.ErrorExit('build_sdk: interrupted')
-
diff --git a/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json b/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json
index 68b6bf5..6f48141 100644
--- a/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json
+++ b/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json
@@ -249,22 +249,88 @@
       "version": 31
     },
     {
-      "archives": [],
-      "description": "Chrome 32 bundle, revision xxxxx",
+      "archives": [
+        {
+          "checksum": {
+            "sha1": "1cde8464f0c22d8016e7b5510d0842338b752bdc"
+          },
+          "host_os": "all",
+          "size": 73165335,
+          "url": "https://commondatastorage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/32.0.1700.107/naclports.tar.bz2"
+        },
+        {
+          "checksum": {
+            "sha1": "1b42e24e4406dc7ef7466461214de22b3c426e6e"
+          },
+          "host_os": "linux",
+          "size": 284112979,
+          "url": "https://commondatastorage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/32.0.1700.107/naclsdk_linux.tar.bz2"
+        },
+        {
+          "checksum": {
+            "sha1": "e8f22dcc253f4b5b1d3727dd4bdb435d5192202d"
+          },
+          "host_os": "mac",
+          "size": 250355709,
+          "url": "https://commondatastorage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/32.0.1700.107/naclsdk_mac.tar.bz2"
+        },
+        {
+          "checksum": {
+            "sha1": "4231ab60ced3db505ff6a5543e7965639ea5a15a"
+          },
+          "host_os": "win",
+          "size": 269032445,
+          "url": "https://commondatastorage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/32.0.1700.107/naclsdk_win.tar.bz2"
+        }
+      ],
+      "description": "Chrome 32 bundle. Chrome revision: 248368. NaCl revision: 12321",
       "name": "pepper_32",
       "recommended": "no",
       "repath": "pepper_32",
-      "revision": 0,
+      "revision": 248368,
       "stability": "post_stable",
       "version": 32
     },
     {
-      "archives": [],
-      "description": "Chrome 33 bundle, revision xxxxx",
+      "archives": [
+        {
+          "checksum": {
+            "sha1": "8e3e394d7269bab454361cd2eccd44f719de7039"
+          },
+          "host_os": "all",
+          "size": 73455859,
+          "url": "https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/33.0.1750.117/naclports.tar.bz2"
+        },
+        {
+          "checksum": {
+            "sha1": "6e883b9e76cc803db5d579933de070d3b707f1eb"
+          },
+          "host_os": "linux",
+          "size": 301049823,
+          "url": "https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/33.0.1750.117/naclsdk_linux.tar.bz2"
+        },
+        {
+          "checksum": {
+            "sha1": "0e47e9b841dfb5f75bdcdd1ebf0b501ab094a806"
+          },
+          "host_os": "mac",
+          "size": 261626911,
+          "url": "https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/33.0.1750.117/naclsdk_mac.tar.bz2"
+        },
+        {
+          "checksum": {
+            "sha1": "d9a34b8b19990273f97aa22559ed82d569ef751c"
+          },
+          "host_os": "win",
+          "size": 279181683,
+          "url": "https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/33.0.1750.117/naclsdk_win.tar.bz2"
+        }
+      ],
+      "description": "Chrome 33 bundle. Chrome revision: 252094. NaCl revision: 12558",
       "name": "pepper_33",
       "recommended": "no",
       "repath": "pepper_33",
-      "revision": 0,
+      "revision": 252094,
       "stability": "post_stable",
       "version": 33
     },
@@ -280,6 +346,16 @@
     },
     {
       "archives": [],
+      "description": "Chrome 35 bundle, revision xxxxx",
+      "name": "pepper_35",
+      "recommended": "no",
+      "repath": "pepper_35",
+      "revision": 0,
+      "stability": "post_stable",
+      "version": 35
+    },
+    {
+      "archives": [],
       "description": "Chrome Canary",
       "name": "pepper_canary",
       "recommended": "no",
diff --git a/native_client_sdk/src/doc/reference/pnacl-bitcode-abi.rst b/native_client_sdk/src/doc/reference/pnacl-bitcode-abi.rst
index 0f2740f..1ffe5bf 100644
--- a/native_client_sdk/src/doc/reference/pnacl-bitcode-abi.rst
+++ b/native_client_sdk/src/doc/reference/pnacl-bitcode-abi.rst
@@ -198,6 +198,17 @@
   * The only integer sizes allowed for function arguments and function return
     values are i32 and i64.
 
+Vector types
+------------
+
+The only vector types allowed are:
+
+* 128-bit vectors integers of elements size i8, i16, i32.
+* 128-bit vectors of float elements.
+* Vectors of i1 type with element counts corresponding to the allowed
+  element counts listed previously (their width is therefore not
+  128-bits).
+
 Array and struct types
 ----------------------
 
@@ -369,6 +380,8 @@
 * ``select``
 * ``call``
 * ``unreachable``
+* ``insertelement``
+* ``extractelement``
 
 .. _bitcode_allocainst:
 
diff --git a/native_client_sdk/src/doc/reference/pnacl-c-cpp-language-support.rst b/native_client_sdk/src/doc/reference/pnacl-c-cpp-language-support.rst
index 46610fc..3bece15 100644
--- a/native_client_sdk/src/doc/reference/pnacl-c-cpp-language-support.rst
+++ b/native_client_sdk/src/doc/reference/pnacl-c-cpp-language-support.rst
@@ -227,7 +227,8 @@
 
 .. naclcode::
 
-  typedef int v4s __attribute__((vector_size(16)));
+  #define VECTOR_BYTES 16
+  typedef int v4s __attribute__((vector_size(VECTOR_BYTES)));
   v4s a = {1,2,3,4};
   v4s b = {5,6,7,8};
   v4s c, d, e;
@@ -313,7 +314,41 @@
     std::cout << std::endl;
   }
 
-Vector shuffles are currently unsupported but will be added soon.
+Vector shuffles (often called permutation or swizzle) operations are
+supported through ``__builtin_shufflevector``. The builtin has two
+vector arguments of the same element type, followed by a list of
+constant integers that specify the element indices of the first two
+vectors that should be extracted and returned in a new vector. These
+element indices are numbered sequentially starting with the first
+vector, continuing into the second vector. Thus, if ``vec1`` is a
+4-element vector, index ``5`` would refer to the second element of
+``vec2``. An index of ``-1`` can be used to indicate that the
+corresponding element in the returned vector is a don’t care and can be
+optimized by the backend.
+
+The result of ``__builtin_shufflevector`` is a vector with the same
+element type as ``vec1`` / ``vec2`` but that has an element count equal
+to the number of indices specified.
+
+.. naclcode::
+
+  // identity operation - return 4-element vector v1.
+  __builtin_shufflevector(v1, v1, 0, 1, 2, 3)
+
+  // "Splat" element 0 of V1 into a 4-element result.
+  __builtin_shufflevector(V1, V1, 0, 0, 0, 0)
+
+  // Reverse 4-element vector V1.
+  __builtin_shufflevector(V1, V1, 3, 2, 1, 0)
+
+  // Concatenate every other element of 4-element vectors V1 and V2.
+  __builtin_shufflevector(V1, V2, 0, 2, 4, 6)
+
+  // Concatenate every other element of 8-element vectors V1 and V2.
+  __builtin_shufflevector(V1, V2, 0, 2, 4, 6, 8, 10, 12, 14)
+
+  // Shuffle v1 with some elements being undefined
+  __builtin_shufflevector(v1, v1, 3, -1, 1, -1)
 
 Auto-Vectorization
 ------------------
diff --git a/native_client_sdk/src/examples/api/socket/index.html b/native_client_sdk/src/examples/api/socket/index.html
index eefe5eb..277f4e0 100644
--- a/native_client_sdk/src/examples/api/socket/index.html
+++ b/native_client_sdk/src/examples/api/socket/index.html
@@ -23,7 +23,7 @@
      First set a server address in the form of 'hostname:port', then push the
      "Connect" button to establish a connection.<br>
      "Send" button sends the message of the text area to the the remote host.
-     Any data recieved back will be output to the status log.<br>
+     Any data received back will be output to the status log.<br>
      For example, try connecting to a TCP echo server that will reply with
      whatever bytes you send, or connect to a web server and send a GET
      request.<br>
diff --git a/native_client_sdk/src/examples/demo/nacl_io/example.js b/native_client_sdk/src/examples/demo/nacl_io/example.js
index 2b5b516..1a13580 100644
--- a/native_client_sdk/src/examples/demo/nacl_io/example.js
+++ b/native_client_sdk/src/examples/demo/nacl_io/example.js
@@ -6,6 +6,10 @@
   common.hideModule();
 }
 
+function $(id) {
+  return document.getElementById(id);
+}
+
 // Called by the common.js module.
 function domContentLoaded(name, tc, config, width, height) {
   navigator.webkitPersistentStorage.requestQuota(1024 * 1024,
@@ -76,273 +80,223 @@
 var dirhandle_map = {};
 
 function fopen(e) {
-  var filename = document.getElementById('fopenFilename').value;
-  var access = document.getElementById('fopenMode').value;
-  nacl_module.postMessage(makeCall('fopen', filename, access));
-}
+  var filename = $('fopenFilename').value;
+  var access = $('fopenMode').value;
+  postCall('fopen', filename, access, function(filename, filehandle) {
+    filehandle_map[filehandle] = filename;
 
-function fopenResult(filename, filehandle) {
-  filehandle_map[filehandle] = filename;
-
-  addNameToSelectElements('.file-handle', filehandle, filename);
-  common.logMessage('File ' + filename + ' opened successfully.');
+    addNameToSelectElements('.file-handle', filehandle, filename);
+    common.logMessage('File ' + filename + ' opened successfully.');
+  });
 }
 
 function fclose(e) {
-  var filehandle = document.getElementById('fcloseHandle').value;
-  nacl_module.postMessage(makeCall('fclose', filehandle));
-}
-
-function fcloseResult(filehandle) {
-  var filename = filehandle_map[filehandle];
-  removeNameFromSelectElements('.file-handle', filehandle, filename);
-  common.logMessage('File ' + filename + ' closed successfully.');
+  var filehandle = parseInt($('fcloseHandle').value, 10);
+  postCall('fclose', filehandle, function(filehandle) {
+    var filename = filehandle_map[filehandle];
+    removeNameFromSelectElements('.file-handle', filehandle, filename);
+    common.logMessage('File ' + filename + ' closed successfully.');
+  });
 }
 
 function fread(e) {
-  var filehandle = document.getElementById('freadHandle').value;
-  var numBytes = document.getElementById('freadBytes').value;
-  nacl_module.postMessage(makeCall('fread', filehandle, numBytes));
-}
-
-function freadResult(filehandle, data) {
-  var filename = filehandle_map[filehandle];
-  common.logMessage('Read "' + data + '" from file ' + filename + '.');
+  var filehandle = parseInt($('freadHandle').value, 10);
+  var numBytes = parseInt($('freadBytes').value, 10);
+  postCall('fread', filehandle, numBytes, function(filehandle, data) {
+    var filename = filehandle_map[filehandle];
+    common.logMessage('Read "' + data + '" from file ' + filename + '.');
+  });
 }
 
 function fwrite(e) {
-  var filehandle = document.getElementById('fwriteHandle').value;
-  var data = document.getElementById('fwriteData').value;
-  nacl_module.postMessage(makeCall('fwrite', filehandle, data));
-}
-
-function fwriteResult(filehandle, bytes_written) {
-  var filename = filehandle_map[filehandle];
-  common.logMessage('Wrote ' + bytes_written + ' bytes to file ' + filename +
-      '.');
+  var filehandle = parseInt($('fwriteHandle').value, 10);
+  var data = $('fwriteData').value;
+  postCall('fwrite', filehandle, data, function(filehandle, bytesWritten) {
+    var filename = filehandle_map[filehandle];
+    common.logMessage('Wrote ' + bytesWritten + ' bytes to file ' + filename +
+        '.');
+  });
 }
 
 function fseek(e) {
-  var filehandle = document.getElementById('fseekHandle').value;
-  var offset = document.getElementById('fseekOffset').value;
-  var whence = document.getElementById('fseekWhence').value;
-  nacl_module.postMessage(makeCall('fseek', filehandle, offset, whence));
-}
-
-function fseekResult(filehandle, filepos) {
-  var filename = filehandle_map[filehandle];
-  common.logMessage('Seeked to location ' + filepos + ' in file ' + filename +
-      '.');
+  var filehandle = parseInt($('fseekHandle').value, 10);
+  var offset = parseInt($('fseekOffset').value, 10);
+  var whence = parseInt($('fseekWhence').value, 10);
+  postCall('fseek', filehandle, offset, whence, function(filehandle, filepos) {
+    var filename = filehandle_map[filehandle];
+    common.logMessage('Seeked to location ' + filepos + ' in file ' + filename +
+        '.');
+  });
 }
 
 function fflush(e) {
-  var filehandle = document.getElementById('fflushHandle').value;
-  nacl_module.postMessage(makeCall('fflush', filehandle));
-}
-
-function fflushResult(filehandle, filepos) {
-  var filename = filehandle_map[filehandle];
-  common.logMessage('flushed ' + filename + '.');
+  var filehandle = parseInt($('fflushHandle').value, 10);
+  postCall('fflush', filehandle, function(filehandle, filepos) {
+    var filename = filehandle_map[filehandle];
+    common.logMessage('flushed ' + filename + '.');
+  });
 }
 
 function stat(e) {
-  var filename = document.getElementById('statFilename').value;
-  nacl_module.postMessage(makeCall('stat', filename));
-}
-
-function statResult(filename, size) {
-  common.logMessage('File ' + filename + ' has size ' + size + '.');
+  var filename = $('statFilename').value;
+  postCall('stat', filename, function(filename, size) {
+    common.logMessage('File ' + filename + ' has size ' + size + '.');
+  });
 }
 
 function opendir(e) {
-  var dirname = document.getElementById('opendirDirname').value;
-  nacl_module.postMessage(makeCall('opendir', dirname));
-}
+  var dirname = $('opendirDirname').value;
+  postCall('opendir', dirname, function(dirname, dirhandle) {
+    dirhandle_map[dirhandle] = dirname;
 
-function opendirResult(dirname, dirhandle) {
-  dirhandle_map[dirhandle] = dirname;
-
-  addNameToSelectElements('.dir-handle', dirhandle, dirname);
-  common.logMessage('Directory ' + dirname + ' opened successfully.');
+    addNameToSelectElements('.dir-handle', dirhandle, dirname);
+    common.logMessage('Directory ' + dirname + ' opened successfully.');
+  });
 }
 
 function readdir(e) {
-  var dirhandle = document.getElementById('readdirHandle').value;
-  nacl_module.postMessage(makeCall('readdir', dirhandle));
-}
-
-function readdirResult(dirhandle, ino, name) {
-  var dirname = dirhandle_map[dirhandle];
-  if (ino === '') {
-    common.logMessage('End of directory.');
-  } else {
-    common.logMessage('Read entry ("' + name + '", ino = ' + ino +
-                      ') from directory ' + dirname + '.');
-  }
+  var dirhandle = parseInt($('readdirHandle').value, 10);
+  postCall('readdir', dirhandle, function(dirhandle, ino, name) {
+    var dirname = dirhandle_map[dirhandle];
+    if (ino === undefined) {
+      common.logMessage('End of directory.');
+    } else {
+      common.logMessage('Read entry ("' + name + '", ino = ' + ino +
+                        ') from directory ' + dirname + '.');
+    }
+  });
 }
 
 function closedir(e) {
-  var dirhandle = document.getElementById('closedirHandle').value;
-  nacl_module.postMessage(makeCall('closedir', dirhandle));
-}
+  var dirhandle = parseInt($('closedirHandle').value, 10);
+  postCall('closedir', dirhandle, function(dirhandle) {
+    var dirname = dirhandle_map[dirhandle];
+    delete dirhandle_map[dirhandle];
 
-function closedirResult(dirhandle) {
-  var dirname = dirhandle_map[dirhandle];
-  delete dirhandle_map[dirhandle];
-
-  removeNameFromSelectElements('.dir-handle', dirhandle, dirname);
-  common.logMessage('Directory ' + dirname + ' closed successfully.');
+    removeNameFromSelectElements('.dir-handle', dirhandle, dirname);
+    common.logMessage('Directory ' + dirname + ' closed successfully.');
+  });
 }
 
 function mkdir(e) {
-  var dirname = document.getElementById('mkdirDirname').value;
-  var mode = document.getElementById('mkdirMode').value;
-  nacl_module.postMessage(makeCall('mkdir', dirname, mode));
-}
-
-function mkdirResult(dirname) {
-  common.logMessage('Directory ' + dirname + ' created successfully.');
+  var dirname = $('mkdirDirname').value;
+  var mode = parseInt($('mkdirMode').value, 10);
+  postCall('mkdir', dirname, mode, function(dirname) {
+    common.logMessage('Directory ' + dirname + ' created successfully.');
+  });
 }
 
 function rmdir(e) {
-  var dirname = document.getElementById('rmdirDirname').value;
-  nacl_module.postMessage(makeCall('rmdir', dirname));
-}
-
-function rmdirResult(dirname) {
-  common.logMessage('Directory ' + dirname + ' removed successfully.');
+  var dirname = $('rmdirDirname').value;
+  postCall('rmdir', dirname, function(dirname) {
+    common.logMessage('Directory ' + dirname + ' removed successfully.');
+  });
 }
 
 function chdir(e) {
-  var dirname = document.getElementById('chdirDirname').value;
-  nacl_module.postMessage(makeCall('chdir', dirname));
-}
-
-function chdirResult(dirname) {
-  common.logMessage('Changed directory to: ' + dirname + '.');
+  var dirname = $('chdirDirname').value;
+  postCall('chdir', dirname, function(dirname) {
+    common.logMessage('Changed directory to: ' + dirname + '.');
+  });
 }
 
 function getcwd(e) {
-  nacl_module.postMessage(makeCall('getcwd'));
-}
-
-function getcwdResult(dirname) {
-  common.logMessage('getcwd: ' + dirname + '.');
+  postCall('getcwd', function(dirname) {
+    common.logMessage('getcwd: ' + dirname + '.');
+  });
 }
 
 function getaddrinfo(e) {
-  var name = document.getElementById('getaddrinfoName').value;
-  var family = document.getElementById('getaddrinfoFamily').value;
-  nacl_module.postMessage(makeCall('getaddrinfo', name, family));
-}
-
-function getaddrinfoResult(name, addr_type) {
-  common.logMessage('getaddrinfo returned successfully');
-  common.logMessage('ai_cannonname = ' + name + '.');
-  var count = 1;
-  for (var i = 1; i < arguments.length; i+=2) {
-    var msg = 'Address number ' + count + ' = ' + arguments[i] +
-              ' (' + arguments[i+1] + ')';
-    common.logMessage(msg);
-    count += 1;
-  }
+  var name = $('getaddrinfoName').value;
+  var family = $('getaddrinfoFamily').value;
+  postCall('getaddrinfo', name, family, function(name, addrType) {
+    common.logMessage('getaddrinfo returned successfully');
+    common.logMessage('ai_cannonname = ' + name + '.');
+    var count = 1;
+    for (var i = 1; i < arguments.length; i+=2) {
+      var msg = 'Address number ' + count + ' = ' + arguments[i] +
+                ' (' + arguments[i+1] + ')';
+      common.logMessage(msg);
+      count += 1;
+    }
+  });
 }
 
 function gethostbyname(e) {
-  var name = document.getElementById('gethostbynameName').value;
-  nacl_module.postMessage(makeCall('gethostbyname', name));
-}
-
-function gethostbynameResult(name, addr_type) {
-  common.logMessage('gethostbyname returned successfully');
-  common.logMessage('h_name = ' + name + '.');
-  common.logMessage('h_addr_type = ' + addr_type + '.');
-  for (var i = 2; i < arguments.length; i++) {
-    common.logMessage('Address number ' + (i-1) + ' = ' + arguments[i] + '.');
-  }
+  var name = $('gethostbynameName').value;
+  postCall('gethostbyname', name, function(name, addrType) {
+    common.logMessage('gethostbyname returned successfully');
+    common.logMessage('h_name = ' + name + '.');
+    common.logMessage('h_addr_type = ' + addrType + '.');
+    for (var i = 2; i < arguments.length; i++) {
+      common.logMessage('Address number ' + (i-1) + ' = ' + arguments[i] + '.');
+    }
+  });
 }
 
 function connect(e) {
-  var host = document.getElementById('connectHost').value;
-  var port = document.getElementById('connectPort').value;
-  nacl_module.postMessage(makeCall('connect', host, port));
-}
-
-function connectResult(sockhandle) {
-  common.logMessage('connected');
-  addNameToSelectElements('.sock-handle', sockhandle, '[socket]');
+  var host = $('connectHost').value;
+  var port = parseInt($('connectPort').value, 10);
+  postCall('connect', host, port, function(sockhandle) {
+    common.logMessage('connected');
+    addNameToSelectElements('.sock-handle', sockhandle, '[socket]');
+  });
 }
 
 function recv(e) {
-  var handle = document.getElementById('recvHandle').value;
-  var bufferSize = document.getElementById('recvBufferSize').value;
-  nacl_module.postMessage(makeCall('recv', handle, bufferSize));
-}
-
-function recvResult(messageLen, message) {
-  common.logMessage("received " + messageLen + ' bytes: ' + message);
+  var handle = parseInt($('recvHandle').value, 10);
+  var bufferSize = parseInt($('recvBufferSize').value, 10);
+  postCall('recv', handle, bufferSize, function(messageLen, message) {
+    common.logMessage("received " + messageLen + ' bytes: ' + message);
+  });
 }
 
 function send(e) {
-  var handle = document.getElementById('sendHandle').value;
-  var message = document.getElementById('sendMessage').value;
-  nacl_module.postMessage(makeCall('send', handle, message));
-}
-
-function sendResult(sentBytes) {
-  common.logMessage("sent bytes: " + sentBytes);
+  var handle = parseInt($('sendHandle').value, 10);
+  var message = $('sendMessage').value;
+  postCall('send', handle, message, function(sentBytes) {
+    common.logMessage("sent bytes: " + sentBytes);
+  });
 }
 
 function close(e) {
-  var handle = document.getElementById('closeHandle').value;
-  nacl_module.postMessage(makeCall('close', handle));
+  var handle = parseInt($('closeHandle').value, 10);
+  postCall('close', handle, function(sock) {
+    removeNameFromSelectElements('.sock-handle', sock, "[socket]");
+    common.logMessage("closed socket: " + sock);
+  });
 }
 
-function closeResult(sock) {
-  removeNameFromSelectElements('.sock-handle', sock, "[socket]");
-  common.logMessage("closed socket: " + sock);
-}
+var funcToCallback = {};
 
-/**
- * Return true when |s| starts with the string |prefix|.
- *
- * @param {string} s The string to search.
- * @param {string} prefix The prefix to search for in |s|.
- * @return {boolean} Whether |s| starts with |prefix|.
- */
-function startsWith(s, prefix) {
-  // indexOf would search the entire string, lastIndexOf(p, 0) only checks at
-  // the first index. See: http://stackoverflow.com/a/4579228
-  return s.lastIndexOf(prefix, 0) === 0;
-}
+function postCall(func) {
+  var callback = arguments[arguments.length - 1];
+  funcToCallback[func] = callback;
 
-function makeCall(func) {
-  var message = func;
-  for (var i = 1; i < arguments.length; ++i) {
-    message += '\1' + arguments[i];
-  }
-
-  return message;
+  nacl_module.postMessage({
+    cmd: func,
+    args: Array.prototype.slice.call(arguments, 1, -1)
+  });
 }
 
 // Called by the common.js module.
 function handleMessage(message_event) {
-  var msg = message_event.data;
-  if (startsWith(msg, 'Error:')) {
-    common.logMessage(msg);
+  var data = message_event.data;
+  if ((typeof(data) === 'string' || data instanceof String)) {
+    common.logMessage(data);
   } else {
     // Result from a function call.
-    var params = msg.split('\1');
-    var funcName = params[0];
-    var funcResultName = funcName + 'Result';
-    var resultFunc = window[funcResultName];
+    var params = data.args;
+    var funcName = data.cmd;
+    var callback = funcToCallback[funcName];
 
-    if (!resultFunc) {
+    if (!callback) {
       common.logMessage('Error: Bad message ' + funcName +
                         ' received from NaCl module.');
       return;
     }
 
-    resultFunc.apply(null, params.slice(1));
+    delete funcToCallback[funcName];
+    callback.apply(null, params);
   }
 }
diff --git a/native_client_sdk/src/examples/demo/nacl_io/handlers.c b/native_client_sdk/src/examples/demo/nacl_io/handlers.c
index ae40d2d..4fef350 100644
--- a/native_client_sdk/src/examples/demo/nacl_io/handlers.c
+++ b/native_client_sdk/src/examples/demo/nacl_io/handlers.c
@@ -25,6 +25,7 @@
 
 #define MAX_OPEN_FILES 10
 #define MAX_OPEN_DIRS 10
+#define MAX_PARAMS 4
 
 #if defined(WIN32)
 #define stat _stat
@@ -43,6 +44,13 @@
 static void* g_OpenDirs[MAX_OPEN_DIRS];
 
 /**
+ * A collection of the most recently allocated parameter strings. This makes
+ * the Handle* functions below easier to write because they don't have to
+ * manually deallocate the strings they're using.
+ */
+static char* g_ParamStrings[MAX_PARAMS];
+
+/**
  * Add |object| to |map| and return the index it was added at.
  * @param[in] map The map to add the object to.
  * @param[in] max_map_size The maximum map size.
@@ -74,43 +82,6 @@
 }
 
 /**
- * Get the object from |map| at index |i|.
- * @param[in] map The map to access.
- * @param[in] max_map_size The size of the map.
- * @param[in] i The index to access.
- * @return the object at |map|. This will be NULL if there is no object at |i|.
- */
-static void* GetFromMap(void** map, int max_map_size, int i) {
-  assert(i >= 0 && i < max_map_size);
-  return map[i];
-}
-
-/**
- * Get an object given a string |s| containing the index.
- * @param[in] map The map to access.
- * @param[in] max_map_size The size of the map.
- * @param[in] s The string containing the object index.
- * @param[out] index The index of the object as an int.
- * @return The object, or NULL if the index is invalid.
- */
-static void* GetFromIndexString(void** map,
-                                int max_map_size,
-                                const char* s,
-                                int* index) {
-  char* endptr;
-  int result = strtol(s, &endptr, 10);
-  if (endptr != s + strlen(s)) {
-    /* Garbage at the end of the number...? */
-    return NULL;
-  }
-
-  if (index)
-    *index = result;
-
-  return GetFromMap(map, max_map_size, result);
-}
-
-/**
  * Add the file to the g_OpenFiles map.
  * @param[in] file The file to add to g_OpenFiles.
  * @return int The index of the FILE in g_OpenFiles, or -1 if there are too many
@@ -128,17 +99,6 @@
   RemoveFromMap((void**)g_OpenFiles, MAX_OPEN_FILES, i);
 }
 
-/**
- * Get a file, given a string containing the index.
- * @param[in] s The string containing the file index.
- * @param[out] file_index The index of this file.
- * @return The FILE* for this file, or NULL if the index is invalid.
- */
-static FILE* GetFileFromIndexString(const char* s, int* file_index) {
-  return (FILE*)GetFromIndexString(
-      (void**)g_OpenFiles, MAX_OPEN_FILES, s, file_index);
-}
-
 /* Win32 doesn't support DIR/opendir/readdir/closedir. */
 #if !defined(WIN32)
 /**
@@ -158,18 +118,289 @@
 static void RemoveDirFromMap(int i) {
   RemoveFromMap((void**)g_OpenDirs, MAX_OPEN_DIRS, i);
 }
+#endif
 
 /**
- * Get a dir, given a string containing the index.
- * @param[in] s The string containing the dir index.
- * @param[out] dir_index The index of this dir.
- * @return The DIR* for this dir, or NULL if the index is invalid.
+ * Get the number of parameters.
+ * @param[in] params The parameter array.
+ * @return uint32_t The number of parameters in the array.
  */
-static DIR* GetDirFromIndexString(const char* s, int* dir_index) {
-  return (DIR*)GetFromIndexString(
-      (void**)g_OpenDirs, MAX_OPEN_DIRS, s, dir_index);
+static uint32_t GetNumParams(struct PP_Var params) {
+  return g_ppb_var_array->GetLength(params);
 }
-#endif
+
+/**
+ * Get a parameter at |index| as a string.
+ * @param[in] params The parameter array.
+ * @param[in] index The index in |params| to get.
+ * @param[out] out_string The output string.
+ * @param[out] out_string_len The length of the output string.
+ * @param[out] out_error An error message, if this operation failed.
+ * @return int 0 if successful, otherwise 1.
+ */
+static int GetParamString(struct PP_Var params,
+                          uint32_t index,
+                          char** out_string,
+                          uint32_t* out_string_len,
+                          const char** out_error) {
+  if (index >= MAX_PARAMS) {
+    *out_error = PrintfToNewString("Param index %u >= MAX_PARAMS (%d)",
+                                   index, MAX_PARAMS);
+    return 1;
+  }
+
+  struct PP_Var value = g_ppb_var_array->Get(params, index);
+  if (value.type != PP_VARTYPE_STRING) {
+    *out_error =
+        PrintfToNewString("Expected param at index %d to be a string", index);
+    return 1;
+  }
+
+  uint32_t length;
+  const char* var_str = g_ppb_var->VarToUtf8(value, &length);
+
+  char* string = (char*)malloc(length + 1);
+  memcpy(string, var_str, length);
+  string[length] = 0;
+
+  /* Put the allocated string in g_ParamStrings. This keeps us from leaking
+   * each parameter string, without having to do manual cleanup in every
+   * Handle* function below.
+   */
+  free(g_ParamStrings[index]);
+  g_ParamStrings[index] = string;
+
+
+  *out_string = string;
+  *out_string_len = length;
+  return 0;
+}
+
+/**
+ * Get a parameter at |index| as a FILE*.
+ * @param[in] params The parameter array.
+ * @param[in] index The index in |params| to get.
+ * @param[out] out_file The output FILE*.
+ * @param[out] out_file_index The index of the output FILE* in g_OpenFiles.
+ * @param[out] out_error An error message, if this operation failed.
+ * @return int 0 if successful, otherwise 1.
+ */
+static int GetParamFile(struct PP_Var params,
+                        uint32_t index,
+                        FILE** out_file,
+                        int32_t* out_file_index,
+                        const char** out_error) {
+  struct PP_Var value = g_ppb_var_array->Get(params, index);
+  if (value.type != PP_VARTYPE_INT32) {
+    *out_error =
+        PrintfToNewString("Expected param at index %d to be an int32", index);
+    return 1;
+  }
+
+  int32_t file_index = value.value.as_int;
+  if (file_index < 0 || file_index >= MAX_OPEN_FILES) {
+    *out_error = PrintfToNewString("File index %d is out range", file_index);
+    return 1;
+  }
+
+  if (g_OpenFiles[file_index] == NULL) {
+    *out_error = PrintfToNewString("File index %d is not open", file_index);
+    return 1;
+  }
+
+  *out_file = g_OpenFiles[file_index];
+  *out_file_index = file_index;
+  return 0;
+}
+
+/**
+ * Get a parameter at |index| as a DIR*.
+ * @param[in] params The parameter array.
+ * @param[in] index The index in |params| to get.
+ * @param[out] out_file The output DIR*.
+ * @param[out] out_file_index The index of the output DIR* in g_OpenDirs.
+ * @param[out] out_error An error message, if this operation failed.
+ * @return int 0 if successful, otherwise 1.
+ */
+static int GetParamDir(struct PP_Var params,
+                       uint32_t index,
+                       DIR** out_dir,
+                       int32_t* out_dir_index,
+                       const char** out_error) {
+  struct PP_Var value = g_ppb_var_array->Get(params, index);
+  if (value.type != PP_VARTYPE_INT32) {
+    *out_error =
+        PrintfToNewString("Expected param at index %d to be an int32", index);
+    return 1;
+  }
+
+  int32_t dir_index = value.value.as_int;
+  if (dir_index < 0 || dir_index >= MAX_OPEN_DIRS) {
+    *out_error = PrintfToNewString("Dir at index %d is out range", dir_index);
+    return 1;
+  }
+
+  if (g_OpenDirs[dir_index] == NULL) {
+    *out_error = PrintfToNewString("Dir index %d is not open", dir_index);
+    return 1;
+  }
+
+  *out_dir = g_OpenDirs[dir_index];
+  *out_dir_index = dir_index;
+  return 0;
+}
+
+/**
+ * Get a parameter at |index| as an int.
+ * @param[in] params The parameter array.
+ * @param[in] index The index in |params| to get.
+ * @param[out] out_file The output int32_t.
+ * @param[out] out_error An error message, if this operation failed.
+ * @return int 0 if successful, otherwise 1.
+ */
+static int GetParamInt(struct PP_Var params,
+                       uint32_t index,
+                       int32_t* out_int,
+                       const char** out_error) {
+  struct PP_Var value = g_ppb_var_array->Get(params, index);
+  if (value.type != PP_VARTYPE_INT32) {
+    *out_error =
+        PrintfToNewString("Expected param at index %d to be an int32", index);
+    return 1;
+  }
+
+  *out_int = value.value.as_int;
+  return 0;
+}
+
+/**
+ * Create a response PP_Var to send back to JavaScript.
+ * @param[out] response_var The response PP_Var.
+ * @param[in] cmd The name of the function that is being executed.
+ * @param[out] out_error An error message, if this call failed.
+ */
+static void CreateResponse(struct PP_Var* response_var,
+                           const char* cmd,
+                           const char** out_error) {
+  PP_Bool result;
+
+  struct PP_Var dict_var = g_ppb_var_dictionary->Create();
+  struct PP_Var cmd_key = CStrToVar("cmd");
+  struct PP_Var cmd_value = CStrToVar(cmd);
+
+  result = g_ppb_var_dictionary->Set(dict_var, cmd_key, cmd_value);
+  g_ppb_var->Release(cmd_key);
+  g_ppb_var->Release(cmd_value);
+
+  if (!result) {
+    g_ppb_var->Release(dict_var);
+    *out_error =
+        PrintfToNewString("Unable to set \"cmd\" key in result dictionary");
+    return;
+  }
+
+  struct PP_Var args_key = CStrToVar("args");
+  struct PP_Var args_value = g_ppb_var_array->Create();
+  result = g_ppb_var_dictionary->Set(dict_var, args_key, args_value);
+  g_ppb_var->Release(args_key);
+  g_ppb_var->Release(args_value);
+
+  if (!result) {
+    g_ppb_var->Release(dict_var);
+    *out_error =
+        PrintfToNewString("Unable to set \"args\" key in result dictionary");
+    return;
+  }
+
+  *response_var = dict_var;
+}
+
+/**
+ * Append a PP_Var to the response dictionary.
+ * @param[in,out] response_var The response PP_var.
+ * @param[in] value The value to add to the response args.
+ * @param[out] out_error An error message, if this call failed.
+ */
+static void AppendResponseVar(struct PP_Var* response_var,
+                              struct PP_Var value,
+                              const char** out_error) {
+  struct PP_Var args_value = GetDictVar(*response_var, "args");
+  uint32_t args_length = g_ppb_var_array->GetLength(args_value);
+  PP_Bool result = g_ppb_var_array->Set(args_value, args_length, value);
+  if (!result) {
+    // Release the dictionary that was there before.
+    g_ppb_var->Release(*response_var);
+
+    // Return an error message instead.
+    *response_var = PP_MakeUndefined();
+    *out_error = PrintfToNewString("Unable to append value to result");
+    return;
+  }
+}
+
+/**
+ * Append an int to the response dictionary.
+ * @param[in,out] response_var The response PP_var.
+ * @param[in] value The value to add to the response args.
+ * @param[out] out_error An error message, if this call failed.
+ */
+static void AppendResponseInt(struct PP_Var* response_var,
+                              int32_t value,
+                              const char** out_error) {
+  AppendResponseVar(response_var, PP_MakeInt32(value), out_error);
+}
+
+/**
+ * Append a string to the response dictionary.
+ * @param[in,out] response_var The response PP_var.
+ * @param[in] value The value to add to the response args.
+ * @param[out] out_error An error message, if this call failed.
+ */
+static void AppendResponseString(struct PP_Var* response_var,
+                                 const char* value,
+                                 const char** out_error) {
+  struct PP_Var value_var = CStrToVar(value);
+  AppendResponseVar(response_var, value_var, out_error);
+  g_ppb_var->Release(value_var);
+}
+
+#define CHECK_PARAM_COUNT(name, expected)                                   \
+  if (GetNumParams(params) != expected) {                                   \
+    *out_error = PrintfToNewString(#name " takes " #expected " parameters." \
+                                   " Got %d", GetNumParams(params));        \
+    return 1;                                                               \
+  }
+
+#define PARAM_STRING(index, var)                                    \
+  char* var;                                                        \
+  uint32_t var##_len;                                               \
+  if (GetParamString(params, index, &var, &var##_len, out_error)) { \
+    return 1;                                                       \
+  }
+
+#define PARAM_FILE(index, var)                                      \
+  FILE* var;                                                        \
+  int32_t var##_index;                                              \
+  if (GetParamFile(params, index, &var, &var##_index, out_error)) { \
+    return 1;                                                       \
+  }
+
+#define PARAM_DIR(index, var)                                      \
+  DIR* var;                                                        \
+  int32_t var##_index;                                             \
+  if (GetParamDir(params, index, &var, &var##_index, out_error)) { \
+    return 1;                                                      \
+  }
+
+#define PARAM_INT(index, var)                        \
+  int32_t var;                                       \
+  if (GetParamInt(params, index, &var, out_error)) { \
+    return 1;                                        \
+  }
+
+#define CREATE_RESPONSE(name) CreateResponse(output, #name, out_error)
+#define RESPONSE_STRING(var) AppendResponseString(output, var, out_error)
+#define RESPONSE_INT(var) AppendResponseInt(output, var, out_error)
 
 /**
  * Handle a call to fopen() made by JavaScript.
@@ -177,45 +408,36 @@
  * fopen expects 2 parameters:
  *   0: the path of the file to open
  *   1: the mode string
- * on success, fopen returns a result in |output| separated by \1:
+ * on success, fopen returns a result in |output|:
  *   0: "fopen"
  *   1: the filename opened
  *   2: the file index
- * on failure, fopen returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on failure, fopen returns an error string in |out_error|.
  */
-int HandleFopen(int num_params, char** params, char** output) {
-  FILE* file;
-  int file_index;
-  const char* filename;
-  const char* mode;
+int HandleFopen(struct PP_Var params,
+                struct PP_Var* output,
+                const char** out_error) {
+  CHECK_PARAM_COUNT(fopen, 2);
+  PARAM_STRING(0, filename);
+  PARAM_STRING(1, mode);
 
-  if (num_params != 2) {
-    *output = PrintfToNewString("fopen takes 2 parameters.");
+  FILE* file = fopen(filename, mode);
+
+  if (!file) {
+    *out_error = PrintfToNewString("fopen returned a NULL FILE*");
     return 1;
   }
 
-  filename = params[0];
-  mode = params[1];
-
-  file = fopen(filename, mode);
-  if (!file) {
-    *output = PrintfToNewString("fopen returned a NULL FILE*.");
-    return 2;
-  }
-
-  file_index = AddFileToMap(file);
+  int file_index = AddFileToMap(file);
   if (file_index == -1) {
-    *output = PrintfToNewString(
-        "Example only allows %d open file handles.", MAX_OPEN_FILES);
-    return 3;
+    *out_error = PrintfToNewString("Example only allows %d open file handles",
+                                   MAX_OPEN_FILES);
+    return 1;
   }
 
-  *output = PrintfToNewString("fopen\1%s\1%d", filename, file_index);
+  CREATE_RESPONSE(fopen);
+  RESPONSE_STRING(filename);
+  RESPONSE_INT(file_index);
   return 0;
 }
 
@@ -225,50 +447,29 @@
  * fwrite expects 2 parameters:
  *   0: The index of the file (which is mapped to a FILE*)
  *   1: A string to write to the file
- * on success, fwrite returns a result in |output| separated by \1:
+ * on success, fwrite returns a result in |output|:
  *   0: "fwrite"
  *   1: the file index
  *   2: the number of bytes written
- * on failure, fwrite returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on failure, fwrite returns an error string in |out_error|.
  */
-int HandleFwrite(int num_params, char** params, char** output) {
-  FILE* file;
-  const char* file_index_string;
-  const char* data;
-  size_t data_len;
-  size_t bytes_written;
+int HandleFwrite(struct PP_Var params,
+                 struct PP_Var* output,
+                 const char** out_error) {
+  CHECK_PARAM_COUNT(fwrite, 2);
+  PARAM_FILE(0, file);
+  PARAM_STRING(1, data);
 
-  if (num_params != 2) {
-    *output = PrintfToNewString("fwrite takes 2 parameters.");
+  size_t bytes_written = fwrite(data, 1, data_len, file);
+  if (ferror(file)) {
+    *out_error = PrintfToNewString("Wrote %d bytes, but ferror() returns true",
+                                   bytes_written);
     return 1;
   }
 
-  file_index_string = params[0];
-  file = GetFileFromIndexString(file_index_string, NULL);
-  data = params[1];
-  data_len = strlen(data);
-
-  if (!file) {
-    *output =
-        PrintfToNewString("Unknown file handle %s.", file_index_string);
-    return 2;
-  }
-
-  bytes_written = fwrite(data, 1, data_len, file);
-
-  if (ferror(file)) {
-    *output = PrintfToNewString(
-        "Wrote %d bytes, but ferror() returns true.", bytes_written);
-    return 3;
-  }
-
-  *output =
-      PrintfToNewString("fwrite\1%s\1%d", file_index_string, bytes_written);
+  CREATE_RESPONSE(fwrite);
+  RESPONSE_INT(file_index);
+  RESPONSE_INT(bytes_written);
   return 0;
 }
 
@@ -278,50 +479,33 @@
  * fread expects 2 parameters:
  *   0: The index of the file (which is mapped to a FILE*)
  *   1: The number of bytes to read from the file.
- * on success, fread returns a result in |output| separated by \1:
+ * on success, fread returns a result in |output|:
  *   0: "fread"
  *   1: the file index
  *   2: the data read from the file
- * on failure, fread returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on failure, fread returns an error string in |out_error|.
  */
-int HandleFread(int num_params, char** params, char** output) {
-  FILE* file;
-  const char* file_index_string;
-  char* buffer;
-  size_t data_len;
-  size_t bytes_read;
+int HandleFread(struct PP_Var params,
+                struct PP_Var* output,
+                const char** out_error) {
+  CHECK_PARAM_COUNT(fread, 2);
+  PARAM_FILE(0, file);
+  PARAM_INT(1, data_len);
 
-  if (num_params != 2) {
-    *output = PrintfToNewString("fread takes 2 parameters.");
-    return 1;
-  }
-
-  file_index_string = params[0];
-  file = GetFileFromIndexString(file_index_string, NULL);
-  data_len = strtol(params[1], NULL, 10);
-
-  if (!file) {
-    *output =
-        PrintfToNewString("Unknown file handle %s.", file_index_string);
-    return 2;
-  }
-
-  buffer = (char*)malloc(data_len + 1);
-  bytes_read = fread(buffer, 1, data_len, file);
+  char* buffer = (char*)malloc(data_len + 1);
+  size_t bytes_read = fread(buffer, 1, data_len, file);
   buffer[bytes_read] = 0;
 
   if (ferror(file)) {
-    *output = PrintfToNewString(
-        "Read %d bytes, but ferror() returns true.", bytes_read);
-    return 3;
+    *out_error = PrintfToNewString("Read %d bytes, but ferror() returns true",
+                                   bytes_read);
+    free(buffer);
+    return 1;
   }
 
-  *output = PrintfToNewString("fread\1%s\1%s", file_index_string, buffer);
+  CREATE_RESPONSE(fread);
+  RESPONSE_INT(file_index);
+  RESPONSE_STRING(buffer);
   free(buffer);
   return 0;
 }
@@ -336,54 +520,36 @@
  *      whence = 0: seek from the beginning of the file
  *      whence = 1: seek from the current file position
  *      whence = 2: seek from the end of the file
- * on success, fseek returns a result in |output| separated by \1:
+ * on success, fseek returns a result in |output|:
  *   0: "fseek"
  *   1: the file index
  *   2: The new file position
- * on failure, fseek returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on failure, fseek returns an error string in |out_error|.
  */
-int HandleFseek(int num_params, char** params, char** output) {
-  FILE* file;
-  const char* file_index_string;
-  long offset;
-  int whence;
-  int result;
+int HandleFseek(struct PP_Var params,
+                struct PP_Var* output,
+                const char** out_error) {
+  CHECK_PARAM_COUNT(fseek, 3);
+  PARAM_FILE(0, file);
+  PARAM_INT(1, offset);
+  PARAM_INT(2, whence);
 
-  if (num_params != 3) {
-    *output = PrintfToNewString("fseek takes 3 parameters.");
-    return 1;
-  }
-
-  file_index_string = params[0];
-  file = GetFileFromIndexString(file_index_string, NULL);
-  offset = strtol(params[1], NULL, 10);
-  whence = strtol(params[2], NULL, 10);
-
-  if (!file) {
-    *output =
-        PrintfToNewString("Unknown file handle %s.", file_index_string);
-    return 2;
-  }
-
-  result = fseek(file, offset, whence);
+  int result = fseek(file, offset, whence);
   if (result) {
-    *output = PrintfToNewString("fseek returned error %d.", result);
-    return 3;
+    *out_error = PrintfToNewString("fseek returned error %d", result);
+    return 1;
   }
 
   offset = ftell(file);
   if (offset < 0) {
-    *output = PrintfToNewString(
-        "fseek succeeded, but ftell returned error %ld.", offset);
-    return 4;
+    *out_error = PrintfToNewString(
+        "fseek succeeded, but ftell returned error %d", offset);
+    return 1;
   }
 
-  *output = PrintfToNewString("fseek\1%s\1%ld", file_index_string, offset);
+  CREATE_RESPONSE(fseek);
+  RESPONSE_INT(file_index);
+  RESPONSE_INT(offset);
   return 0;
 }
 
@@ -392,37 +558,21 @@
  *
  * fflush expects 1 parameters:
  *   0: The index of the file (which is mapped to a FILE*)
- * on success, fflush returns a result in |output| separated by \1:
+ * on success, fflush returns a result in |output|:
  *   0: "fflush"
  *   1: the file index
- * on failure, fflush returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on failure, fflush returns an error string in |out_error|.
  */
-int HandleFflush(int num_params, char** params, char** output) {
-  FILE* file;
-  const char* file_index_string;
-
-  if (num_params != 1) {
-    *output = PrintfToNewString("fflush takes 3 parameters.");
-    return 1;
-  }
-
-  file_index_string = params[0];
-  file = GetFileFromIndexString(file_index_string, NULL);
-
-  if (!file) {
-    *output =
-        PrintfToNewString("Unknown file handle %s.", file_index_string);
-    return 2;
-  }
+int HandleFflush(struct PP_Var params,
+                 struct PP_Var* output,
+                 const char** out_error) {
+  CHECK_PARAM_COUNT(fflush, 1);
+  PARAM_FILE(0, file);
 
   fflush(file);
 
-  *output = PrintfToNewString("fflush\1%s", file_index_string);
+  CREATE_RESPONSE(fflush);
+  RESPONSE_INT(file_index);
   return 0;
 }
 
@@ -431,44 +581,27 @@
  *
  * fclose expects 1 parameter:
  *   0: The index of the file (which is mapped to a FILE*)
- * on success, fclose returns a result in |output| separated by \1:
+ * on success, fclose returns a result in |output|:
  *   0: "fclose"
  *   1: the file index
- * on failure, fclose returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on failure, fclose returns an error string in |out_error|.
  */
-int HandleFclose(int num_params, char** params, char** output) {
-  FILE* file;
-  int file_index;
-  const char* file_index_string;
-  int result;
+int HandleFclose(struct PP_Var params,
+                 struct PP_Var* output,
+                 const char** out_error) {
+  CHECK_PARAM_COUNT(fclose, 1);
+  PARAM_FILE(0, file);
 
-  if (num_params != 1) {
-    *output = PrintfToNewString("fclose takes 1 parameters.");
-    return 1;
-  }
-
-  file_index_string = params[0];
-  file = GetFileFromIndexString(file_index_string, &file_index);
-  if (!file) {
-    *output =
-        PrintfToNewString("Unknown file handle %s.", file_index_string);
-    return 2;
-  }
-
-  result = fclose(file);
+  int result = fclose(file);
   if (result) {
-    *output = PrintfToNewString("fclose returned error %d.", result);
-    return 3;
+    *out_error = PrintfToNewString("fclose returned error %d", result);
+    return 1;
   }
 
   RemoveFileFromMap(file_index);
 
-  *output = PrintfToNewString("fclose\1%s", file_index_string);
+  CREATE_RESPONSE(fclose);
+  RESPONSE_INT(file_index);
   return 0;
 }
 
@@ -477,37 +610,30 @@
  *
  * stat expects 1 parameter:
  *   0: The name of the file
- * on success, stat returns a result in |output| separated by \1:
+ * on success, stat returns a result in |output|:
  *   0: "stat"
  *   1: the file name
  *   2: the size of the file
- * on failure, stat returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on failure, stat returns an error string in |out_error|.
  */
-int HandleStat(int num_params, char** params, char** output) {
-  const char* filename;
-  int result;
-  struct stat buf;
+int HandleStat(struct PP_Var params,
+               struct PP_Var* output,
+               const char** out_error) {
+  CHECK_PARAM_COUNT(stat, 1);
+  PARAM_STRING(0, filename);
 
-  if (num_params != 1) {
-    *output = PrintfToNewString("stat takes 1 parameter.");
+  struct stat buf;
+  memset(&buf, 0, sizeof(buf));
+  int result = stat(filename, &buf);
+
+  if (result == -1) {
+    *out_error = PrintfToNewString("stat returned error %d", errno);
     return 1;
   }
 
-  filename = params[0];
-
-  memset(&buf, 0, sizeof(buf));
-  result = stat(filename, &buf);
-  if (result == -1) {
-    *output = PrintfToNewString("stat returned error %d.", errno);
-    return 2;
-  }
-
-  *output = PrintfToNewString("stat\1%s\1%lld", filename, buf.st_size);
+  CREATE_RESPONSE(stat);
+  RESPONSE_STRING(filename);
+  RESPONSE_INT(buf.st_size);
   return 0;
 }
 
@@ -516,47 +642,39 @@
  *
  * opendir expects 1 parameter:
  *   0: The name of the directory
- * on success, opendir returns a result in |output| separated by \1:
+ * on success, opendir returns a result in |output|:
  *   0: "opendir"
  *   1: the directory name
  *   2: the index of the directory
- * on failure, opendir returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on failure, opendir returns an error string in |out_error|.
  */
-int HandleOpendir(int num_params, char** params, char** output) {
+int HandleOpendir(struct PP_Var params,
+                  struct PP_Var* output,
+                  const char** out_error) {
 #if defined(WIN32)
-  *output = PrintfToNewString("Win32 does not support opendir.");
+  *out_error = PrintfToNewString("Win32 does not support opendir");
   return 1;
 #else
-  DIR* dir;
-  int dir_index;
-  const char* dirname;
+  CHECK_PARAM_COUNT(opendir, 1);
+  PARAM_STRING(0, dirname);
 
-  if (num_params != 1) {
-    *output = PrintfToNewString("opendir takes 1 parameter.");
+  DIR* dir = opendir(dirname);
+
+  if (!dir) {
+    *out_error = PrintfToNewString("opendir returned a NULL DIR*");
     return 1;
   }
 
-  dirname = params[0];
-
-  dir = opendir(dirname);
-  if (!dir) {
-    *output = PrintfToNewString("opendir returned a NULL DIR*.");
-    return 2;
-  }
-
-  dir_index = AddDirToMap(dir);
+  int dir_index = AddDirToMap(dir);
   if (dir_index == -1) {
-    *output = PrintfToNewString(
-        "Example only allows %d open dir handles.", MAX_OPEN_DIRS);
-    return 3;
+    *out_error = PrintfToNewString("Example only allows %d open dir handles",
+                                   MAX_OPEN_DIRS);
+    return 1;
   }
 
-  *output = PrintfToNewString("opendir\1%s\1%d", dirname, dir_index);
+  CREATE_RESPONSE(opendir);
+  RESPONSE_STRING(dirname);
+  RESPONSE_INT(dir_index);
   return 0;
 #endif
 }
@@ -566,47 +684,32 @@
  *
  * readdir expects 1 parameter:
  *   0: The index of the directory (which is mapped to a DIR*)
- * on success, opendir returns a result in |output| separated by \1:
+ * on success, opendir returns a result in |output|:
  *   0: "readdir"
  *   1: the inode number of the entry
  *   2: the name of the entry
- * on failure, readdir returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * if there are no more entries, |output| contains:
+ *   0: "readdir"
+ * on failure, readdir returns an error string in |out_error|.
  */
-int HandleReaddir(int num_params, char** params, char** output) {
+int HandleReaddir(struct PP_Var params,
+                  struct PP_Var* output,
+                  const char** out_error) {
 #if defined(WIN32)
-  *output = PrintfToNewString("Win32 does not support readdir.");
+  *out_error = PrintfToNewString("Win32 does not support readdir");
   return 1;
 #else
-  DIR* dir;
-  const char* dir_index_string;
-  struct dirent* entry;
+  CHECK_PARAM_COUNT(readdir, 1);
+  PARAM_DIR(0, dir);
 
-  if (num_params != 1) {
-    *output = PrintfToNewString("readdir takes 1 parameter.");
-    return 1;
-  }
+  struct dirent* entry = readdir(dir);
 
-  dir_index_string = params[0];
-  dir = GetDirFromIndexString(dir_index_string, NULL);
-
-  if (!dir) {
-    *output = PrintfToNewString("Unknown dir handle %s.", dir_index_string);
-    return 2;
-  }
-
-  entry = readdir(dir);
+  CREATE_RESPONSE(readdir);
+  RESPONSE_INT(dir_index);
   if (entry != NULL) {
-    *output = PrintfToNewString(
-        "readdir\1%s\1%lld\1%s", dir_index_string, entry->d_ino, entry->d_name);
-  } else {
-    *output = PrintfToNewString("readdir\1%s\1\1", dir_index_string);
+    RESPONSE_INT(entry->d_ino);
+    RESPONSE_STRING(entry->d_name);
   }
-
   return 0;
 #endif
 }
@@ -616,48 +719,31 @@
  *
  * closedir expects 1 parameter:
  *   0: The index of the directory (which is mapped to a DIR*)
- * on success, closedir returns a result in |output| separated by \1:
+ * on success, closedir returns a result in |output|:
  *   0: "closedir"
  *   1: the name of the directory
- * on failure, closedir returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on failure, closedir returns an error string in |out_error|.
  */
-int HandleClosedir(int num_params, char** params, char** output) {
+int HandleClosedir(struct PP_Var params,
+                   struct PP_Var* output,
+                   const char** out_error) {
 #if defined(WIN32)
-  *output = PrintfToNewString("Win32 does not support closedir.");
+  *out_error = PrintfToNewString("Win32 does not support closedir");
   return 1;
 #else
-  DIR* dir;
-  int dir_index;
-  const char* dir_index_string;
-  int result;
+  CHECK_PARAM_COUNT(closedir, 1);
+  PARAM_DIR(0, dir);
 
-  if (num_params != 1) {
-    *output = PrintfToNewString("closedir takes 1 parameters.");
-    return 1;
-  }
-
-  dir_index_string = params[0];
-  dir = GetDirFromIndexString(dir_index_string, &dir_index);
-  if (!dir) {
-    *output = PrintfToNewString("Unknown dir handle %s.",
-                                dir_index_string);
-    return 2;
-  }
-
-  result = closedir(dir);
+  int result = closedir(dir);
   if (result) {
-    *output = PrintfToNewString("closedir returned error %d.", result);
-    return 3;
+    *out_error = PrintfToNewString("closedir returned error %d", result);
+    return 1;
   }
 
   RemoveDirFromMap(dir_index);
 
-  *output = PrintfToNewString("closedir\1%s", dir_index_string);
+  CREATE_RESPONSE(closedir);
+  RESPONSE_INT(dir_index);
   return 0;
 #endif
 }
@@ -668,36 +754,27 @@
  * mkdir expects 1 parameter:
  *   0: The name of the directory
  *   1: The mode to use for the new directory, in octal.
- * on success, mkdir returns a result in |output| separated by \1:
+ * on success, mkdir returns a result in |output|:
  *   0: "mkdir"
  *   1: the name of the directory
- * on failure, mkdir returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on failure, mkdir returns an error string in |out_error|.
  */
-int HandleMkdir(int num_params, char** params, char** output) {
-  const char* dirname;
-  int result;
-  int mode;
+int HandleMkdir(struct PP_Var params,
+                struct PP_Var* output,
+                const char** out_error) {
+  CHECK_PARAM_COUNT(mkdir, 2);
+  PARAM_STRING(0, dirname);
+  PARAM_INT(1, mode);
 
-  if (num_params != 2) {
-    *output = PrintfToNewString("mkdir takes 2 parameters.");
+  int result = mkdir(dirname, mode);
+
+  if (result != 0) {
+    *out_error = PrintfToNewString("mkdir returned error: %d", errno);
     return 1;
   }
 
-  dirname = params[0];
-  mode = strtol(params[1], NULL, 8);
-
-  result = mkdir(dirname, mode);
-  if (result != 0) {
-    *output = PrintfToNewString("mkdir returned error: %d", errno);
-    return 2;
-  }
-
-  *output = PrintfToNewString("mkdir\1%s", dirname);
+  CREATE_RESPONSE(mkdir);
+  RESPONSE_STRING(dirname);
   return 0;
 }
 
@@ -706,26 +783,26 @@
  *
  * rmdir expects 1 parameter:
  *   0: The name of the directory to remove
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on success, rmdir returns a result in |output|:
+ *   0: "rmdir"
+ *   1: the name of the directory
+ * on failure, rmdir returns an error string in |out_error|.
  */
-int HandleRmdir(int num_params, char** params, char** output) {
-  if (num_params != 1) {
-    *output = PrintfToNewString("rmdir takes 1 parameter.");
+int HandleRmdir(struct PP_Var params,
+                struct PP_Var* output,
+                const char** out_error) {
+  CHECK_PARAM_COUNT(rmdir, 1);
+  PARAM_STRING(0, dirname);
+
+  int result = rmdir(dirname);
+
+  if (result != 0) {
+    *out_error = PrintfToNewString("rmdir returned error: %d", errno);
     return 1;
   }
 
-  const char* dirname = params[0];
-  int result = rmdir(dirname);
-  if (result != 0) {
-    *output = PrintfToNewString("rmdir returned error: %d", errno);
-    return 2;
-  }
-
-  *output = PrintfToNewString("rmdir\1%s", dirname);
+  CREATE_RESPONSE(rmdir);
+  RESPONSE_STRING(dirname);
   return 0;
 }
 
@@ -734,26 +811,26 @@
  *
  * chdir expects 1 parameter:
  *   0: The name of the directory
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on success, chdir returns a result in |output|:
+ *   0: "chdir"
+ *   1: the name of the directory
+ * on failure, chdir returns an error string in |out_error|.
  */
-int HandleChdir(int num_params, char** params, char** output) {
-  if (num_params != 1) {
-    *output = PrintfToNewString("chdir takes 1 parameter.");
+int HandleChdir(struct PP_Var params,
+                struct PP_Var* output,
+                const char** out_error) {
+  CHECK_PARAM_COUNT(chdir, 1);
+  PARAM_STRING(0, dirname);
+
+  int result = chdir(dirname);
+
+  if (result != 0) {
+    *out_error = PrintfToNewString("chdir returned error: %d", errno);
     return 1;
   }
 
-  const char* dirname = params[0];
-  int result = chdir(dirname);
-  if (result != 0) {
-    *output = PrintfToNewString("chdir returned error: %d", errno);
-    return 2;
-  }
-
-  *output = PrintfToNewString("chdir\1%s", dirname);
+  CREATE_RESPONSE(chdir);
+  RESPONSE_STRING(dirname);
   return 0;
 }
 
@@ -761,42 +838,47 @@
  * Handle a call to getcwd() made by JavaScript.
  *
  * getcwd expects 0 parameters.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on success, getcwd returns a result in |output|:
+ *   0: "getcwd"
+ *   1: the current working directory
+ * on failure, getcwd returns an error string in |out_error|.
  */
-int HandleGetcwd(int num_params, char** params, char** output) {
-  if (num_params != 0) {
-    *output = PrintfToNewString("getcwd takes 0 parameters.");
-    return 1;
-  }
+int HandleGetcwd(struct PP_Var params,
+                 struct PP_Var* output,
+                 const char** out_error) {
+  CHECK_PARAM_COUNT(getcwd, 0);
 
   char cwd[PATH_MAX];
   char* result = getcwd(cwd, PATH_MAX);
   if (result == NULL) {
-    *output = PrintfToNewString("getcwd returned error: %d", errno);
+    *out_error = PrintfToNewString("getcwd returned error: %d", errno);
     return 1;
   }
 
-  *output = PrintfToNewString("getcwd\1%s", cwd);
+  CREATE_RESPONSE(getcwd);
+  RESPONSE_STRING(cwd);
   return 0;
 }
 
-int HandleGetaddrinfo(int num_params, char** params, char** output) {
-  int output_len;
-  int current_pos;
+/**
+ * Handle a call to getaddrinfo() made by JavaScript.
+ *
+ * getaddrinfo expects 1 parameter:
+ *   0: The name of the host to look up.
+ * on success, getaddrinfo returns a result in |output|:
+ *   0: "getaddrinfo"
+ *   1: The canonical name
+ *   2*n+2: Host name
+ *   2*n+3: Address type (either "AF_INET" or "AF_INET6")
+ * on failure, getaddrinfo returns an error string in |out_error|.
+ */
+int HandleGetaddrinfo(struct PP_Var params,
+                      struct PP_Var* output,
+                      const char** out_error) {
+  CHECK_PARAM_COUNT(getaddrinfo, 2);
+  PARAM_STRING(0, name);
+  PARAM_STRING(1, family);
 
-  if (num_params != 2) {
-    *output = PrintfToNewString("getaddrinfo takes 2 parameters.");
-    return 1;
-  }
-
-  const char* name = params[0];
-  const char* family = params[1];
-
-  struct addrinfo *ai;
   struct addrinfo hints;
   memset(&hints, 0, sizeof(hints));
   hints.ai_flags = AI_CANONNAME;
@@ -807,57 +889,38 @@
   else if (!strcmp(family, "AF_UNSPEC"))
     hints.ai_family = AF_UNSPEC;
   else {
-    *output = PrintfToNewString("getaddrinfo uknown family: %s", family);
+    *out_error = PrintfToNewString("getaddrinfo uknown family: %s", family);
     return 1;
   }
 
+  struct addrinfo* ai;
   int rtn = getaddrinfo(name, NULL, &hints, &ai);
   if (rtn != 0) {
-    *output = PrintfToNewString("getaddrinfo failed, error is \"%s\"",
-                                gai_strerror(rtn));
+    *out_error = PrintfToNewString("getaddrinfo failed, error is \"%s\"",
+                                   gai_strerror(rtn));
     return 2;
   }
 
-
-  output_len = strlen("getaddrinfo") + strlen(ai->ai_canonname) + 3;
-
-  struct addrinfo *current = ai;
+  CREATE_RESPONSE(getaddrinfo);
+  RESPONSE_STRING(ai->ai_canonname);
+  struct addrinfo* current = ai;
   while (current) {
-    output_len += 2 + INET6_ADDRSTRLEN + strlen("AF_INET6");
-    current = current->ai_next;
-  }
-
-  char* out = (char*)calloc(output_len, 1);
-  if (!out) {
-    *output = PrintfToNewString("out of memory.");
-    return 3;
-  }
-
-  snprintf(out, output_len, "getaddrinfo\1%s", ai->ai_canonname);
-
-  current_pos = strlen(out);
-  current = ai;
-  while (current) {
-    out[current_pos] = '\1';
-    current_pos++;
-    const char* tmp = NULL;
+    char addr_str[INET6_ADDRSTRLEN];
     if (ai->ai_family == AF_INET6) {
       struct sockaddr_in6* in6 = (struct sockaddr_in6*)current->ai_addr;
-      tmp = inet_ntop(ai->ai_family, &in6->sin6_addr.s6_addr,
-                      out+current_pos, output_len-current_pos);
+      inet_ntop(
+          ai->ai_family, &in6->sin6_addr.s6_addr, addr_str, sizeof(addr_str));
     } else if (ai->ai_family == AF_INET) {
       struct sockaddr_in* in = (struct sockaddr_in*)current->ai_addr;
-      tmp = inet_ntop(ai->ai_family, &in->sin_addr,
-                      out+current_pos, output_len-current_pos);
+      inet_ntop(ai->ai_family, &in->sin_addr, addr_str, sizeof(addr_str));
     }
-    current_pos += strlen(tmp);
 
-    const char* addr_type = ai->ai_family == AF_INET ? "AF_INET" : "AF_INET6";
-    current_pos += sprintf(out + current_pos, "\1%s", addr_type);
+    RESPONSE_STRING(addr_str);
+    RESPONSE_STRING(ai->ai_family == AF_INET ? "AF_INET" : "AF_INET6");
+
     current = current->ai_next;
   }
 
-  *output = out;
   freeaddrinfo(ai);
   return 0;
 }
@@ -867,76 +930,40 @@
  *
  * gethostbyname expects 1 parameter:
  *   0: The name of the host to look up.
- * on success, gethostbyname returns a result in |output| separated by \1:
+ * on success, gethostbyname returns a result in |output|:
  *   0: "gethostbyname"
  *   1: Host name
  *   2: Address type (either "AF_INET" or "AF_INET6")
- *   3. The first address.
+ *   3: The first address.
  *   4+ The second, third, etc. addresses.
- * on failure, gethostbyname returns an error string in |output|.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on failure, gethostbyname returns an error string in |out_error|.
  */
-int HandleGethostbyname(int num_params, char** params, char** output) {
-  struct hostent* info;
-  struct in_addr **addr_list;
-  const char* addr_type;
-  const char* name;
-  char inet6_addr_str[INET6_ADDRSTRLEN];
-  int non_variable_len, output_len;
-  int current_pos;
-  int i;
+int HandleGethostbyname(struct PP_Var params,
+                        struct PP_Var* output,
+                        const char** out_error) {
+  CHECK_PARAM_COUNT(gethostbyname, 1);
+  PARAM_STRING(0, name);
 
-  if (num_params != 1) {
-    *output = PrintfToNewString("gethostbyname takes 1 parameter.");
+  struct hostent* info = gethostbyname(name);
+  if (!info) {
+    *out_error = PrintfToNewString("gethostbyname failed, error is \"%s\"",
+                                   hstrerror(h_errno));
     return 1;
   }
 
-  name = params[0];
+  CREATE_RESPONSE(gethostbyname);
+  RESPONSE_STRING(info->h_name);
+  RESPONSE_STRING(info->h_addrtype == AF_INET ? "AF_INET" : "AF_INET6");
 
-  info = gethostbyname(name);
-  if (!info) {
-    *output = PrintfToNewString("gethostbyname failed, error is \"%s\"",
-                                hstrerror(h_errno));
-    return 2;
-  }
-
-  addr_type = info->h_addrtype == AF_INET ? "AF_INET" : "AF_INET6";
-
-  non_variable_len = strlen("gethostbyname") + 1
-    + strlen(info->h_name) + 1 + strlen(addr_type);
-  output_len = non_variable_len;
-
-  addr_list = (struct in_addr **)info->h_addr_list;
-  for (i = 0; addr_list[i] != NULL; i++) {
-    output_len += 1; // for the divider
-    if (info->h_addrtype == AF_INET) {
-      output_len += strlen(inet_ntoa(*addr_list[i]));
-    } else { // IPv6
-      inet_ntop(AF_INET6, addr_list[i], inet6_addr_str, INET6_ADDRSTRLEN);
-      output_len += strlen(inet6_addr_str);
-    }
-  }
-
-  *output = (char*) calloc(output_len + 1, 1);
-  if (!*output) {
-    *output = PrintfToNewString("out of memory.");
-    return 3;
-  }
-  snprintf(*output, non_variable_len + 1, "gethostbyname\1%s\1%s",
-           info->h_name, addr_type);
-
-  current_pos = non_variable_len;
+  struct in_addr** addr_list = (struct in_addr**)info->h_addr_list;
+  int i;
   for (i = 0; addr_list[i] != NULL; i++) {
     if (info->h_addrtype == AF_INET) {
-      current_pos += sprintf(*output + current_pos,
-                             "\1%s", inet_ntoa(*addr_list[i]));
-    } else { // IPv6
-      inet_ntop(AF_INET6, addr_list[i], inet6_addr_str, INET6_ADDRSTRLEN);
-      sprintf(*output + current_pos, "\1%s", inet6_addr_str);
+      RESPONSE_STRING(inet_ntoa(*addr_list[i]));
+    } else {  // IPv6
+      char addr_str[INET6_ADDRSTRLEN];
+      inet_ntop(AF_INET6, addr_list[i], addr_str, sizeof(addr_str));
+      RESPONSE_STRING(addr_str);
     }
   }
   return 0;
@@ -945,106 +972,103 @@
 /**
  * Handle a call to connect() made by JavaScript.
  *
- * This call expects 2 parameters:
+ * connect expects 2 parameters:
  *   0: The hostname to connect to.
  *   1: The port number to connect to.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on success, connect returns a result in |output|:
+ *   0: "connect"
+ *   1: The socket file descriptor.
+ * on failure, connect returns an error string in |out_error|.
  */
-int HandleConnect(int num_params, char** params, char** output) {
-  if (num_params != 2) {
-    *output = PrintfToNewString("connect takes 2 parameters.");
+int HandleConnect(struct PP_Var params,
+                  struct PP_Var* output,
+                  const char** out_error) {
+  CHECK_PARAM_COUNT(connect, 2);
+  PARAM_STRING(0, hostname);
+  PARAM_INT(1, port);
+
+  // Lookup host
+  struct hostent* hostent = gethostbyname(hostname);
+  if (hostent == NULL) {
+    *out_error = PrintfToNewString("gethostbyname() returned error: %d", errno);
     return 1;
   }
 
   struct sockaddr_in addr;
   socklen_t addrlen = sizeof(addr);
-  const char* hostname = params[0];
-  int port = strtol(params[1], NULL, 10);
-
-  // Lookup host
-  struct hostent* hostent = gethostbyname(hostname);
-  if (hostent == NULL) {
-    *output = PrintfToNewString("gethostbyname() returned error: %d", errno);
-    return 1;
-  }
-
   addr.sin_family = AF_INET;
   addr.sin_port = htons(port);
   memcpy(&addr.sin_addr.s_addr, hostent->h_addr_list[0], hostent->h_length);
 
   int sock = socket(AF_INET, SOCK_STREAM, 0);
   if (sock < 0) {
-    *output = PrintfToNewString("socket() failed: %s", strerror(errno));
+    *out_error = PrintfToNewString("socket() failed: %s", strerror(errno));
     return 1;
   }
 
   int result = connect(sock, (struct sockaddr*)&addr, addrlen);
   if (result != 0) {
-    *output = PrintfToNewString("connect() failed: %s", strerror(errno));
+    *out_error = PrintfToNewString("connect() failed: %s", strerror(errno));
     close(sock);
     return 1;
   }
 
-  *output = PrintfToNewString("connect\1%d", sock);
+  CREATE_RESPONSE(connect);
+  RESPONSE_INT(sock);
   return 0;
 }
 
 /**
  * Handle a call to send() made by JavaScript.
  *
- * This call expects 2 parameters:
+ * send expects 2 parameters:
  *   0: The socket file descriptor to send using.
  *   1: The NULL terminated string to send.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on success, send returns a result in |output|:
+ *   0: "send"
+ *   1: The number of bytes sent.
+ * on failure, send returns an error string in |out_error|.
  */
-int HandleSend(int num_params, char** params, char** output) {
-  if (num_params != 2) {
-    *output = PrintfToNewString("send takes 2 parameters.");
-    return 1;
-  }
+int HandleSend(struct PP_Var params,
+               struct PP_Var* output,
+               const char** out_error) {
+  CHECK_PARAM_COUNT(send, 2);
+  PARAM_INT(0, sock);
+  PARAM_STRING(1, buffer);
 
-  int sock = strtol(params[0], NULL, 10);
-  const char* buffer = params[1];
   int result = send(sock, buffer, strlen(buffer), 0);
   if (result <= 0) {
-    *output = PrintfToNewString("send failed: %s", strerror(errno));
+    *out_error = PrintfToNewString("send failed: %s", strerror(errno));
     return 1;
   }
 
-  *output = PrintfToNewString("send\1%d", result);
+  CREATE_RESPONSE(send);
+  RESPONSE_INT(result);
   return 0;
 }
 
 /**
  * Handle a call to recv() made by JavaScript.
  *
- * This call expects 2 parameters:
+ * recv expects 2 parameters:
  *   0: The socket file descriptor to recv from.
  *   1: The size of the buffer to pass to recv.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on success, send returns a result in |output|:
+ *   0: "recv"
+ *   1: The number of bytes received.
+ *   2: The data received.
+ * on failure, recv returns an error string in |out_error|.
  */
-int HandleRecv(int num_params, char** params, char** output) {
-  if (num_params != 2) {
-    *output = PrintfToNewString("recv takes 2 parameters.");
-    return 1;
-  }
+int HandleRecv(struct PP_Var params,
+               struct PP_Var* output,
+               const char** out_error) {
+  CHECK_PARAM_COUNT(recv, 2);
+  PARAM_INT(0, sock);
+  PARAM_INT(1, buffersize);
 
-  int sock = strtol(params[0], NULL, 10);
-  int buffersize = strtol(params[1], NULL, 10);
   if (buffersize < 0 || buffersize > 65 * 1024) {
-    *output = PrintfToNewString("recv buffersize must be between 0 and 65k.");
+    *out_error =
+        PrintfToNewString("recv buffersize must be between 0 and 65k.");
     return 1;
   }
 
@@ -1052,38 +1076,39 @@
   memset(buffer, 0, buffersize);
   int result = recv(sock, buffer, buffersize, 0);
   if (result <= 0) {
-    *output = PrintfToNewString("recv failed: %s", strerror(errno));
-    return 2;
+    *out_error = PrintfToNewString("recv failed: %s", strerror(errno));
+    return 1;
   }
 
-  *output = PrintfToNewString("recv\1%d\1%s", result, buffer);
+  CREATE_RESPONSE(recv);
+  RESPONSE_INT(result);
+  RESPONSE_STRING(buffer);
   return 0;
 }
 
 /**
  * Handle a call to close() made by JavaScript.
  *
- * This call expects 1 parameters:
+ * close expects 1 parameters:
  *   0: The socket file descriptor to close.
- *
- * @param[in] num_params The number of params in |params|.
- * @param[in] params An array of strings, parameters to this function.
- * @param[out] output A string to write informational function output to.
- * @return An errorcode; 0 means success, anything else is a failure.
+ * on success, close returns a result in |output|:
+ *   0: "close"
+ *   1: The socket file descriptor closed.
+ * on failure, close returns an error string in |out_error|.
  */
-int HandleClose(int num_params, char** params, char** output) {
-  if (num_params != 1) {
-    *output = PrintfToNewString("close takes 1 parameters.");
+int HandleClose(struct PP_Var params,
+                struct PP_Var* output,
+                const char** out_error) {
+  CHECK_PARAM_COUNT(close, 1);
+  PARAM_INT(0, sock);
+
+  int result = close(sock);
+  if (result != 0) {
+    *out_error = PrintfToNewString("close returned error: %d", errno);
     return 1;
   }
 
-  int sock = strtol(params[0], NULL, 10);
-  int result = close(sock);
-  if (result != 0) {
-    *output = PrintfToNewString("close returned error: %d", errno);
-    return 2;
-  }
-
-  *output = PrintfToNewString("close\1%d", sock);
+  CREATE_RESPONSE(close);
+  RESPONSE_INT(sock);
   return 0;
 }
diff --git a/native_client_sdk/src/examples/demo/nacl_io/handlers.h b/native_client_sdk/src/examples/demo/nacl_io/handlers.h
index 02d3dfd..532914f 100644
--- a/native_client_sdk/src/examples/demo/nacl_io/handlers.h
+++ b/native_client_sdk/src/examples/demo/nacl_io/handlers.h
@@ -5,32 +5,37 @@
 #ifndef HANDLERS_H_
 #define HANDLERS_H_
 
-#define MAX_PARAMS 4
+#include "ppapi/c/pp_var.h"
 
-typedef int (*HandleFunc)(int num_params, char** params, char** output);
+typedef int (*HandleFunc)(struct PP_Var params,
+                          struct PP_Var* out_var,
+                          const char** error);
 
-int HandleFopen(int num_params, char** params, char** output);
-int HandleFwrite(int num_params, char** params, char** output);
-int HandleFread(int num_params, char** params, char** output);
-int HandleFseek(int num_params, char** params, char** output);
-int HandleFclose(int num_params, char** params, char** output);
-int HandleFflush(int num_params, char** params, char** output);
-int HandleStat(int num_params, char** params, char** output);
+int HandleFopen(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleFwrite(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleFread(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleFseek(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleFclose(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleFflush(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleStat(struct PP_Var params, struct PP_Var* out, const char** error);
 
-int HandleOpendir(int num_params, char** params, char** output);
-int HandleReaddir(int num_params, char** params, char** output);
-int HandleClosedir(int num_params, char** params, char** output);
+int HandleOpendir(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleReaddir(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleClosedir(struct PP_Var params, struct PP_Var* out,
+                   const char** error);
 
-int HandleMkdir(int num_params, char** params, char** output);
-int HandleRmdir(int num_params, char** params, char** output);
-int HandleChdir(int num_params, char** params, char** output);
-int HandleGetcwd(int num_params, char** params, char** output);
+int HandleMkdir(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleRmdir(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleChdir(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleGetcwd(struct PP_Var params, struct PP_Var* out, const char** error);
 
-int HandleGetaddrinfo(int num_params, char** params, char** output);
-int HandleGethostbyname(int num_params, char** params, char** output);
-int HandleConnect(int num_params, char** params, char** output);
-int HandleSend(int num_params, char** params, char** output);
-int HandleRecv(int num_params, char** params, char** output);
-int HandleClose(int num_params, char** params, char** output);
+int HandleGetaddrinfo(struct PP_Var params, struct PP_Var* out,
+                      const char** error);
+int HandleGethostbyname(struct PP_Var params, struct PP_Var* out,
+                        const char** error);
+int HandleConnect(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleSend(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleRecv(struct PP_Var params, struct PP_Var* out, const char** error);
+int HandleClose(struct PP_Var params, struct PP_Var* out, const char** error);
 
 #endif /* HANDLERS_H_ */
diff --git a/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c b/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c
index 66b2591..6a08cd2 100644
--- a/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c
+++ b/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c
@@ -18,6 +18,8 @@
 #include "ppapi/c/ppb_instance.h"
 #include "ppapi/c/ppb_messaging.h"
 #include "ppapi/c/ppb_var.h"
+#include "ppapi/c/ppb_var_array.h"
+#include "ppapi/c/ppb_var_dictionary.h"
 #include "ppapi/c/ppp.h"
 #include "ppapi/c/ppp_instance.h"
 #include "ppapi/c/ppp_messaging.h"
@@ -26,8 +28,6 @@
 #include "handlers.h"
 #include "queue.h"
 
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-
 #if defined(WIN32)
 #define va_copy(d, s) ((d) = (s))
 #endif
@@ -37,33 +37,35 @@
   HandleFunc function;
 } FuncNameMapping;
 
-static PP_Instance g_instance = 0;
-static PPB_GetInterface get_browser_interface = NULL;
-static PPB_Messaging* ppb_messaging_interface = NULL;
-static PPB_Var* ppb_var_interface = NULL;
+PP_Instance g_instance = 0;
+PPB_GetInterface g_get_browser_interface = NULL;
+PPB_Messaging* g_ppb_messaging = NULL;
+PPB_Var* g_ppb_var = NULL;
+PPB_VarArray* g_ppb_var_array = NULL;
+PPB_VarDictionary* g_ppb_var_dictionary = NULL;
 
 static FuncNameMapping g_function_map[] = {
-  { "fopen", HandleFopen },
-  { "fwrite", HandleFwrite },
-  { "fread", HandleFread },
-  { "fseek", HandleFseek },
-  { "fclose", HandleFclose },
-  { "fflush", HandleFflush },
-  { "stat", HandleStat },
-  { "opendir", HandleOpendir },
-  { "readdir", HandleReaddir },
-  { "closedir", HandleClosedir },
-  { "mkdir", HandleMkdir },
-  { "rmdir", HandleRmdir },
-  { "chdir", HandleChdir },
-  { "getcwd", HandleGetcwd },
-  { "getaddrinfo", HandleGetaddrinfo },
-  { "gethostbyname", HandleGethostbyname },
-  { "connect", HandleConnect },
-  { "send", HandleSend },
-  { "recv", HandleRecv },
-  { "close", HandleClose },
-  { NULL, NULL },
+    {"fopen", HandleFopen},
+    {"fwrite", HandleFwrite},
+    {"fread", HandleFread},
+    {"fseek", HandleFseek},
+    {"fclose", HandleFclose},
+    {"fflush", HandleFflush},
+    {"stat", HandleStat},
+    {"opendir", HandleOpendir},
+    {"readdir", HandleReaddir},
+    {"closedir", HandleClosedir},
+    {"mkdir", HandleMkdir},
+    {"rmdir", HandleRmdir},
+    {"chdir", HandleChdir},
+    {"getcwd", HandleGetcwd},
+    {"getaddrinfo", HandleGetaddrinfo},
+    {"gethostbyname", HandleGethostbyname},
+    {"connect", HandleConnect},
+    {"send", HandleSend},
+    {"recv", HandleRecv},
+    {"close", HandleClose},
+    {NULL, NULL},
 };
 
 /** A handle to the thread the handles messages. */
@@ -75,10 +77,7 @@
  * @return A new PP_Var with the contents of |str|.
  */
 struct PP_Var CStrToVar(const char* str) {
-  if (ppb_var_interface != NULL) {
-    return ppb_var_interface->VarFromUtf8(str, strlen(str));
-  }
-  return PP_MakeUndefined();
+  return g_ppb_var->VarFromUtf8(str, strlen(str));
 }
 
 /**
@@ -125,22 +124,18 @@
  * @return A new PP_Var.
  */
 struct PP_Var PrintfToVar(const char* format, ...) {
-  if (ppb_var_interface != NULL) {
-    char* string;
-    va_list args;
-    struct PP_Var var;
+  char* string;
+  va_list args;
+  struct PP_Var var;
 
-    va_start(args, format);
-    string = VprintfToNewString(format, args);
-    va_end(args);
+  va_start(args, format);
+  string = VprintfToNewString(format, args);
+  va_end(args);
 
-    var = ppb_var_interface->VarFromUtf8(string, strlen(string));
-    free(string);
+  var = g_ppb_var->VarFromUtf8(string, strlen(string));
+  free(string);
 
-    return var;
-  }
-
-  return PP_MakeUndefined();
+  return var;
 }
 
 /**
@@ -150,73 +145,77 @@
  * @param[in] length The length of |buffer|.
  * @return The number of characters written.
  */
-uint32_t VarToCStr(struct PP_Var var, char* buffer, uint32_t length) {
-  if (ppb_var_interface != NULL) {
-    uint32_t var_length;
-    const char* str = ppb_var_interface->VarToUtf8(var, &var_length);
-    /* str is NOT NULL-terminated. Copy using memcpy. */
-    uint32_t min_length = MIN(var_length, length - 1);
-    memcpy(buffer, str, min_length);
-    buffer[min_length] = 0;
-
-    return min_length;
+const char* VarToCStr(struct PP_Var var) {
+  uint32_t length;
+  const char* str = g_ppb_var->VarToUtf8(var, &length);
+  if (str == NULL) {
+    return NULL;
   }
 
-  return 0;
+  /* str is NOT NULL-terminated. Copy using memcpy. */
+  char* new_str = (char*)malloc(length + 1);
+  memcpy(new_str, str, length);
+  new_str[length] = 0;
+  return new_str;
+}
+
+/**
+ * Get a value from a Dictionary, given a string key.
+ * @param[in] dict The dictionary to look in.
+ * @param[in] key The key to look up.
+ * @return PP_Var The value at |key| in the |dict|. If the key doesn't exist,
+ *     return a PP_Var with the undefined value.
+ */
+struct PP_Var GetDictVar(struct PP_Var dict, const char* key) {
+  struct PP_Var key_var = CStrToVar(key);
+  struct PP_Var value = g_ppb_var_dictionary->Get(dict, key_var);
+  g_ppb_var->Release(key_var);
+  return value;
+}
+
+/**
+ * Send a newly-created PP_Var to JavaScript, then release it.
+ * @param[in] var The PP_Var to send.
+ */
+static void PostMessageVar(struct PP_Var var) {
+  g_ppb_messaging->PostMessage(g_instance, var);
+  g_ppb_var->Release(var);
 }
 
 /**
  * Given a message from JavaScript, parse it for functions and parameters.
  *
  * The format of the message is:
- *   function, param1, param2, param3, etc.
- * where each element is separated by the \1 character.
+ * {
+ *  "cmd": <function name>,
+ *  "args": [<arg0>, <arg1>, ...]
+ * }
  *
- * e.g.
- *   "function\1first parameter\1second parameter"
- *
- * How to use:
- *   char* function;
- *   char* params[4];
- *   int num_params = ParseMessage(msg, &function, &params, 4);
- *
- * @param[in, out] message The message to parse. This string is modified
- *     in-place.
+ * @param[in] message The message to parse.
  * @param[out] out_function The function name.
- * @param[out] out_params An array of strings, one for each parameter parsed.
- * @param[in] max_params The maximum number of parameters to parse.
- * @return The number of parameters parsed.
+ * @param[out] out_params A PP_Var array.
+ * @return 0 if successful, otherwise 1.
  */
-static size_t ParseMessage(char* message,
-                           char** out_function,
-                           char** out_params,
-                           size_t max_params) {
-  char* separator;
-  char* param_start;
-  size_t num_params = 0;
-
-  /* Parse the message: function\1param1\1param2\1param3,... */
-  *out_function = &message[0];
-
-  separator = strchr(message, 1);
-  if (!separator) {
-    return num_params;
+static int ParseMessage(struct PP_Var message,
+                        const char** out_function,
+                        struct PP_Var* out_params) {
+  if (message.type != PP_VARTYPE_DICTIONARY) {
+    return 1;
   }
 
-  *separator = 0; /* NULL-terminate function. */
-
-  while (separator && num_params < max_params) {
-    param_start = separator + 1;
-    separator = strchr(param_start, 1);
-    if (separator) {
-      *separator = 0;
-      out_params[num_params++] = param_start;
-    }
+  struct PP_Var cmd_value = GetDictVar(message, "cmd");
+  *out_function = VarToCStr(cmd_value);
+  g_ppb_var->Release(cmd_value);
+  if (cmd_value.type != PP_VARTYPE_STRING) {
+    return 1;
   }
 
-  out_params[num_params++] = param_start;
+  *out_params = GetDictVar(message, "args");
+  if (out_params->type != PP_VARTYPE_ARRAY) {
+    return 1;
+  }
 
-  return num_params;
+  return 0;
 }
 
 /**
@@ -240,49 +239,44 @@
  *
  * @param[in] message The message to parse and handle.
  */
-static void HandleMessage(char* message) {
-  char* function_name;
-  char* params[MAX_PARAMS];
-  size_t num_params;
-  char* output = NULL;
-  int result;
-  HandleFunc function;
+static void HandleMessage(struct PP_Var message) {
+  const char* function_name;
+  struct PP_Var params;
+  if (ParseMessage(message, &function_name, &params)) {
+    PostMessageVar(CStrToVar("Error: Unable to parse message"));
+    return;
+  }
 
-  num_params = ParseMessage(message, &function_name, &params[0], MAX_PARAMS);
-
-  function = GetFunctionByName(function_name);
+  HandleFunc function = GetFunctionByName(function_name);
   if (!function) {
     /* Function name wasn't found. Error. */
-    ppb_messaging_interface->PostMessage(
-        g_instance,
+    PostMessageVar(
         PrintfToVar("Error: Unknown function \"%s\"", function_name));
     return;
   }
 
   /* Function name was found, call it. */
-  result = (*function)(num_params, &params[0], &output);
+  struct PP_Var result_var;
+  const char* error;
+  int result = (*function)(params, &result_var, &error);
   if (result != 0) {
     /* Error. */
     struct PP_Var var;
-    if (output != NULL) {
-      var = PrintfToVar("Error: \"%s\" failed: %d: %s.", function_name,
-                        result, output);
-      free(output);
+    if (error != NULL) {
+      var = PrintfToVar("Error: \"%s\" failed: %s.", function_name, error);
+      free((void*)error);
     } else {
-      var = PrintfToVar(
-          "Error: \"%s\" failed: %d.", function_name, result);
+      var = PrintfToVar("Error: \"%s\" failed.", function_name);
     }
 
     /* Post the error to JavaScript, so the user can see it. */
-    ppb_messaging_interface->PostMessage(g_instance, var);
+    PostMessageVar(var);
     return;
   }
 
-  if (output != NULL) {
-    /* Function returned an output string. Send it to JavaScript. */
-    ppb_messaging_interface->PostMessage(g_instance, CStrToVar(output));
-    free(output);
-  }
+  /* Function returned an output dictionary. Send it to JavaScript. */
+  PostMessageVar(result_var);
+  g_ppb_var->Release(result_var);
 }
 
 /**
@@ -292,9 +286,9 @@
  */
 void* HandleMessageThread(void* user_data) {
   while (1) {
-    char* message = DequeueMessage();
+    struct PP_Var message = DequeueMessage();
     HandleMessage(message);
-    free(message);
+    g_ppb_var->Release(message);
   }
 }
 
@@ -303,7 +297,7 @@
                                   const char* argn[],
                                   const char* argv[]) {
   g_instance = instance;
-  nacl_io_init_ppapi(instance, get_browser_interface);
+  nacl_io_init_ppapi(instance, g_get_browser_interface);
 
   // By default, nacl_io mounts / to pass through to the original NaCl
   // filesystem (which doesn't do much). Let's remount it to a memfs
@@ -329,12 +323,15 @@
   return PP_TRUE;
 }
 
-static void Instance_DidDestroy(PP_Instance instance) {}
+static void Instance_DidDestroy(PP_Instance instance) {
+}
 
 static void Instance_DidChangeView(PP_Instance instance,
-                                   PP_Resource view_resource) {}
+                                   PP_Resource view_resource) {
+}
 
-static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {}
+static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {
+}
 
 static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance,
                                            PP_Resource url_loader) {
@@ -344,42 +341,50 @@
 
 static void Messaging_HandleMessage(PP_Instance instance,
                                     struct PP_Var message) {
-  char buffer[1024];
-  VarToCStr(message, &buffer[0], 1024);
-  if (!EnqueueMessage(strdup(buffer))) {
-    struct PP_Var var;
-    var = PrintfToVar(
-        "Warning: dropped message \"%s\" because the queue was full.", buffer);
-    ppb_messaging_interface->PostMessage(g_instance, var);
+  g_ppb_var->AddRef(message);
+  if (!EnqueueMessage(message)) {
+    g_ppb_var->Release(message);
+    PostMessageVar(
+        PrintfToVar("Warning: dropped message because the queue was full."));
   }
 }
 
+#define GET_INTERFACE(var, type, name)            \
+  var = (type*)(get_browser(name));               \
+  if (!var) {                                     \
+    printf("Unable to get interface " name "\n"); \
+    return PP_ERROR_FAILED;                       \
+  }
+
 PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id,
                                        PPB_GetInterface get_browser) {
-  get_browser_interface = get_browser;
-  ppb_messaging_interface =
-      (PPB_Messaging*)(get_browser(PPB_MESSAGING_INTERFACE));
-  ppb_var_interface = (PPB_Var*)(get_browser(PPB_VAR_INTERFACE));
+  g_get_browser_interface = get_browser;
+  GET_INTERFACE(g_ppb_messaging, PPB_Messaging, PPB_MESSAGING_INTERFACE);
+  GET_INTERFACE(g_ppb_var, PPB_Var, PPB_VAR_INTERFACE);
+  GET_INTERFACE(g_ppb_var_array, PPB_VarArray, PPB_VAR_ARRAY_INTERFACE);
+  GET_INTERFACE(
+      g_ppb_var_dictionary, PPB_VarDictionary, PPB_VAR_DICTIONARY_INTERFACE);
   return PP_OK;
 }
 
 PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
   if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) {
     static PPP_Instance instance_interface = {
-      &Instance_DidCreate,
-      &Instance_DidDestroy,
-      &Instance_DidChangeView,
-      &Instance_DidChangeFocus,
-      &Instance_HandleDocumentLoad,
+        &Instance_DidCreate,
+        &Instance_DidDestroy,
+        &Instance_DidChangeView,
+        &Instance_DidChangeFocus,
+        &Instance_HandleDocumentLoad,
     };
     return &instance_interface;
   } else if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) {
     static PPP_Messaging messaging_interface = {
-      &Messaging_HandleMessage,
+        &Messaging_HandleMessage,
     };
     return &messaging_interface;
   }
   return NULL;
 }
 
-PP_EXPORT void PPP_ShutdownModule() {}
+PP_EXPORT void PPP_ShutdownModule() {
+}
diff --git a/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.h b/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.h
index b507110..7cdcf45 100644
--- a/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.h
+++ b/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.h
@@ -6,13 +6,22 @@
 #define NACL_IO_DEMO_H_
 
 #include <stdarg.h>
+#include "ppapi/c/pp_instance.h"
 #include "ppapi/c/pp_var.h"
+#include "ppapi/c/ppb_var.h"
+#include "ppapi/c/ppb_var_array.h"
+#include "ppapi/c/ppb_var_dictionary.h"
 #include "sdk_util/macros.h"  // for PRINTF_LIKE
 
 struct PP_Var CStrToVar(const char* str);
 char* VprintfToNewString(const char* format, va_list args) PRINTF_LIKE(1, 0);
 char* PrintfToNewString(const char* format, ...) PRINTF_LIKE(1, 2);
 struct PP_Var PrintfToVar(const char* format, ...) PRINTF_LIKE(1, 2);
-uint32_t VarToCStr(struct PP_Var var, char* buffer, uint32_t length);
+struct PP_Var GetDictVar(struct PP_Var var, const char* key);
+
+extern PP_Instance g_instance;
+extern PPB_Var* g_ppb_var;
+extern PPB_VarArray* g_ppb_var_array;
+extern PPB_VarDictionary* g_ppb_var_dictionary;
 
 #endif /* NACL_IO_DEMO_H_ */
diff --git a/native_client_sdk/src/examples/demo/nacl_io/queue.c b/native_client_sdk/src/examples/demo/nacl_io/queue.c
index ab96440..043ee55 100644
--- a/native_client_sdk/src/examples/demo/nacl_io/queue.c
+++ b/native_client_sdk/src/examples/demo/nacl_io/queue.c
@@ -8,6 +8,8 @@
 #include <pthread.h>
 #include <stdlib.h>
 
+#include "ppapi/c/pp_var.h"
+
 #define MAX_QUEUE_SIZE 16
 
 /** A mutex that guards |g_queue|. */
@@ -27,7 +29,7 @@
  *   all elements in the g_queue are valid.
  * If g_queue_start == g_queue_end, and g_queue_size == 0:
  *   No elements are valid. */
-static char* g_queue[MAX_QUEUE_SIZE];
+static struct PP_Var g_queue[MAX_QUEUE_SIZE];
 
 /** The index of the head of the queue. */
 static int g_queue_start = 0;
@@ -63,14 +65,13 @@
  * NOTE: this function assumes g_queue_mutex is _NOT_ held.
  * @param[in] message The message to enqueue.
  * @return non-zero if the message was added to the queue. */
-int EnqueueMessage(char* message) {
+int EnqueueMessage(struct PP_Var message) {
   pthread_mutex_lock(&g_queue_mutex);
 
   /* We shouldn't block the main thread waiting for the queue to not be full,
    * so just drop the message. */
   if (IsQueueFull()) {
     pthread_mutex_unlock(&g_queue_mutex);
-    free(message);
     return 0;
   }
 
@@ -92,8 +93,8 @@
  *
  * NOTE: this function assumes g_queue_mutex is _NOT_ held.
  * @return The message at the head of the queue. */
-char* DequeueMessage() {
-  char* message = NULL;
+struct PP_Var DequeueMessage() {
+  struct PP_Var message;
 
   pthread_mutex_lock(&g_queue_mutex);
 
diff --git a/native_client_sdk/src/examples/demo/nacl_io/queue.h b/native_client_sdk/src/examples/demo/nacl_io/queue.h
index c7aff06..69226be 100644
--- a/native_client_sdk/src/examples/demo/nacl_io/queue.h
+++ b/native_client_sdk/src/examples/demo/nacl_io/queue.h
@@ -6,6 +6,8 @@
 #ifndef QUEUE_H_
 #define QUEUE_H_
 
+#include "ppapi/c/pp_var.h"
+
 /* This file implements a single-producer/single-consumer queue, using a mutex
  * and a condition variable.
  *
@@ -24,7 +26,7 @@
  * devices. */
 
 void InitializeMessageQueue();
-int EnqueueMessage(char* message);
-char* DequeueMessage();
+int EnqueueMessage(struct PP_Var message);
+struct PP_Var DequeueMessage();
 
 #endif /* QUEUE_H_ */
diff --git a/native_client_sdk/src/examples/tutorial/using_ppapi_simple/example.js b/native_client_sdk/src/examples/tutorial/using_ppapi_simple/example.js
index 03b9a4e..6f02afd 100644
--- a/native_client_sdk/src/examples/tutorial/using_ppapi_simple/example.js
+++ b/native_client_sdk/src/examples/tutorial/using_ppapi_simple/example.js
@@ -13,7 +13,7 @@
 // - exit message (prefixed with PS_EXIT_MESSAGE)
 function handleMessage(message) {
   if (message.data.indexOf("exit:") == 0) {
-    // When we recieve the exit message we post an empty reply back to
+    // When we receive the exit message we post an empty reply back to
     // confirm, at which point the module will exit.
     message.srcElement.postMessage({"exit" : ""});
   } else if (message.data.indexOf("tty:") == 0) {
diff --git a/native_client_sdk/src/libraries/nacl_io/fusefs/fuse_fs.cc b/native_client_sdk/src/libraries/nacl_io/fusefs/fuse_fs.cc
index d251d91..5eaf8e1 100644
--- a/native_client_sdk/src/libraries/nacl_io/fusefs/fuse_fs.cc
+++ b/native_client_sdk/src/libraries/nacl_io/fusefs/fuse_fs.cc
@@ -257,7 +257,7 @@
   return ENOSYS;
 }
 
-Error FuseFsNode::GetSize(size_t* out_size) {
+Error FuseFsNode::GetSize(off_t* out_size) {
   struct stat statbuf;
   Error error = GetStat(&statbuf);
   if (error)
diff --git a/native_client_sdk/src/libraries/nacl_io/fusefs/fuse_fs.h b/native_client_sdk/src/libraries/nacl_io/fusefs/fuse_fs.h
index 707fcae..2c41e3f 100644
--- a/native_client_sdk/src/libraries/nacl_io/fusefs/fuse_fs.h
+++ b/native_client_sdk/src/libraries/nacl_io/fusefs/fuse_fs.h
@@ -53,7 +53,7 @@
   virtual Error Tcgetattr(struct termios* termios_p);
   virtual Error Tcsetattr(int optional_actions,
                           const struct termios* termios_p);
-  virtual Error GetSize(size_t* out_size);
+  virtual Error GetSize(off_t* out_size);
 
  protected:
   struct fuse_operations* fuse_ops_;
diff --git a/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs_node.cc b/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs_node.cc
index 31a1d3c..1f0e843 100644
--- a/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs_node.cc
+++ b/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs_node.cc
@@ -229,7 +229,7 @@
 
 int Html5FsNode::GetType() { return fileio_resource_ ? S_IFREG : S_IFDIR; }
 
-Error Html5FsNode::GetSize(size_t* out_size) {
+Error Html5FsNode::GetSize(off_t* out_size) {
   *out_size = 0;
 
   if (IsaDir())
@@ -243,7 +243,7 @@
   if (result != PP_OK)
     return PPErrorToErrno(result);
 
-  *out_size = static_cast<size_t>(info.size);
+  *out_size = info.size;
   return 0;
 }
 
diff --git a/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs_node.h b/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs_node.h
index 7339aac..f6555f9 100644
--- a/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs_node.h
+++ b/native_client_sdk/src/libraries/nacl_io/html5fs/html5_fs_node.h
@@ -34,7 +34,7 @@
                       int* out_bytes);
 
   virtual int GetType();
-  virtual Error GetSize(size_t* out_size);
+  virtual Error GetSize(off_t* out_size);
   virtual bool IsaDir();
   virtual bool IsaFile();
 
diff --git a/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs.cc b/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs.cc
index f5f8089..ee5e5f3 100644
--- a/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs.cc
+++ b/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs.cc
@@ -390,7 +390,7 @@
   if (error)
     return error;
 
-  size_t size;
+  off_t size;
   error = manifest_node->GetSize(&size);
   if (error)
     return error;
diff --git a/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs_node.cc b/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs_node.cc
index b02c0af..6a4815b 100644
--- a/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs_node.cc
+++ b/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs_node.cc
@@ -83,30 +83,30 @@
   return result;
 }
 
-bool ParseContentLength(const StringMap_t& headers, size_t* content_length) {
+bool ParseContentLength(const StringMap_t& headers, off_t* content_length) {
   StringMap_t::const_iterator iter = headers.find("Content-Length");
   if (iter == headers.end())
     return false;
 
-  *content_length = strtoul(iter->second.c_str(), NULL, 10);
+  *content_length = strtoull(iter->second.c_str(), NULL, 10);
   return true;
 }
 
 bool ParseContentRange(const StringMap_t& headers,
-                       size_t* read_start,
-                       size_t* read_end,
-                       size_t* entity_length) {
+                       off_t* read_start,
+                       off_t* read_end,
+                       off_t* entity_length) {
   StringMap_t::const_iterator iter = headers.find("Content-Range");
   if (iter == headers.end())
     return false;
 
   // The key should look like "bytes ##-##/##" or "bytes ##-##/*". The last
   // value is the entity length, which can potentially be * (i.e. unknown).
-  size_t read_start_int;
-  size_t read_end_int;
-  size_t entity_length_int;
+  off_t read_start_int;
+  off_t read_end_int;
+  off_t entity_length_int;
   int result = sscanf(iter->second.c_str(),
-                      "bytes %" SCNuS "-%" SCNuS "/%" SCNuS,
+                      "bytes %" SCNi64 "-%" SCNi64 "/%" SCNi64,
                       &read_start_int,
                       &read_end_int,
                       &entity_length_int);
@@ -198,7 +198,7 @@
   return EACCES;
 }
 
-Error HttpFsNode::GetSize(size_t* out_size) {
+Error HttpFsNode::GetSize(off_t* out_size) {
   *out_size = 0;
 
   // TODO(binji): This value should be cached properly; i.e. obey the caching
@@ -244,7 +244,7 @@
     if (error)
       return error;
 
-    size_t entity_length;
+    off_t entity_length;
     if (ParseContentLength(response_headers, &entity_length)) {
       SetCachedSize(static_cast<off_t>(entity_length));
     } else if (cache_content_) {
@@ -258,7 +258,7 @@
       // "Content-Length" header. Read the entire entity, and throw it away.
       // Don't use DownloadToCache, as that will still allocate enough memory
       // for the entire entity.
-      int bytes_read;
+      off_t bytes_read;
       error = DownloadToTemp(&bytes_read);
       if (error)
         return error;
@@ -367,7 +367,7 @@
   if (error)
     return error;
 
-  size_t content_length = 0;
+  off_t content_length = 0;
   if (ParseContentLength(response_headers, &content_length)) {
     cached_data_.resize(content_length);
     int real_size;
@@ -395,7 +395,7 @@
                                        int count,
                                        int* out_bytes) {
   *out_bytes = 0;
-  size_t size = cached_data_.size();
+  off_t size = cached_data_.size();
 
   if (attr.offs + count > size)
     count = size - attr.offs;
@@ -410,7 +410,7 @@
 
 Error HttpFsNode::DownloadPartial(const HandleAttr& attr,
                                   void* buf,
-                                  size_t count,
+                                  off_t count,
                                   int* out_bytes) {
   *out_bytes = 0;
 
@@ -420,7 +420,7 @@
   // Range request is inclusive: 0-99 returns 100 bytes.
   snprintf(&buffer[0],
            sizeof(buffer),
-           "bytes=%" PRIuS "-%" PRIuS,
+           "bytes=%" PRIi64 "-%" PRIi64,
            attr.offs,
            attr.offs + count - 1);
   headers["Range"] = buffer;
@@ -447,10 +447,10 @@
     return error;
   }
 
-  size_t read_start = 0;
+  off_t read_start = 0;
   if (statuscode == STATUSCODE_OK) {
     // No partial result, read everything starting from the part we care about.
-    size_t content_length;
+    off_t content_length;
     if (ParseContentLength(response_headers, &content_length)) {
       if (attr.offs >= content_length)
         return EINVAL;
@@ -462,8 +462,8 @@
     }
   } else if (statuscode == STATUSCODE_PARTIAL_CONTENT) {
     // Determine from the headers where we are reading.
-    size_t read_end;
-    size_t entity_length;
+    off_t read_end;
+    off_t entity_length;
     if (ParseContentRange(
             response_headers, &read_start, &read_end, &entity_length)) {
       if (read_start > attr.offs || read_start > read_end) {
@@ -501,7 +501,7 @@
   return ReadResponseToBuffer(loader, buf, count, out_bytes);
 }
 
-Error HttpFsNode::DownloadToTemp(int* out_bytes) {
+Error HttpFsNode::DownloadToTemp(off_t* out_bytes) {
   StringMap_t headers;
   ScopedResource loader(filesystem_->ppapi());
   ScopedResource request(filesystem_->ppapi());
@@ -518,7 +518,7 @@
   if (error)
     return error;
 
-  size_t content_length = 0;
+  off_t content_length = 0;
   if (ParseContentLength(response_headers, &content_length)) {
     *out_bytes = content_length;
     return 0;
@@ -528,7 +528,7 @@
 }
 
 Error HttpFsNode::ReadEntireResponseToTemp(const ScopedResource& loader,
-                                           int* out_bytes) {
+                                           off_t* out_bytes) {
   *out_bytes = 0;
 
   const int kBytesToRead = MAX_READ_BUFFER_SIZE;
diff --git a/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs_node.h b/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs_node.h
index d63ce0b..a779995 100644
--- a/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs_node.h
+++ b/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs_node.h
@@ -34,7 +34,7 @@
                       const void* buf,
                       size_t count,
                       int* out_bytes);
-  virtual Error GetSize(size_t* out_size);
+  virtual Error GetSize(off_t* out_size);
 
   void SetCachedSize(off_t size);
   void SetMode(int mode);
@@ -61,13 +61,14 @@
                              int* out_bytes);
   Error DownloadPartial(const HandleAttr& attr,
                         void* buf,
-                        size_t count,
+                        off_t count,
                         int* out_bytes);
 
-  Error DownloadToTemp(int* out_bytes);
+  Error DownloadToTemp(off_t* out_bytes);
 
   // Read as much as possible from |loader|, using |buffer_| as a scratch area.
-  Error ReadEntireResponseToTemp(const ScopedResource& loader, int* out_bytes);
+  Error ReadEntireResponseToTemp(const ScopedResource& loader,
+                                 off_t* out_bytes);
   // Read as much as possible from |loader|, storing the result in
   // |cached_data_|.
   Error ReadEntireResponseToCache(const ScopedResource& loader, int* out_bytes);
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_handle.cc b/native_client_sdk/src/libraries/nacl_io/kernel_handle.cc
index 8f56e67..9ad4605 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_handle.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_handle.cc
@@ -54,8 +54,8 @@
 Error KernelHandle::Seek(off_t offset, int whence, off_t* out_offset) {
   // By default, don't move the offset.
   *out_offset = offset;
-  ssize_t base;
-  size_t node_size;
+  off_t base;
+  off_t node_size;
 
   AUTO_LOCK(handle_lock_);
   Error error = node_->GetSize(&node_size);
@@ -79,7 +79,7 @@
   if (base + offset < 0)
     return EINVAL;
 
-  size_t new_offset = base + offset;
+  off_t new_offset = base + offset;
 
   // Seeking past the end of the file will zero out the space between the old
   // end and the new end.
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_handle.h b/native_client_sdk/src/libraries/nacl_io/kernel_handle.h
index 5f6fc5c..d385eb3 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_handle.h
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_handle.h
@@ -31,7 +31,7 @@
   HandleAttr() : offs(0), flags(0) {}
   bool IsBlocking() const { return !(flags & O_NONBLOCK); }
 
-  size_t offs;
+  off_t offs;
   int flags;
 };
 
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc
index ce4f170..35bf3fc 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc
@@ -26,6 +26,7 @@
 
 struct KernelInterceptState {
   KernelProxy* kp;
+  PepperInterface* ppapi;
   bool kp_owned;
 };
 
@@ -41,6 +42,7 @@
     return 1;
   s_saved_state = s_state;
   s_state.kp = NULL;
+  s_state.ppapi = NULL;
   s_state.kp_owned = false;
   return 0;
 }
@@ -56,9 +58,12 @@
   if (s_state.kp != NULL)
     return 1;
   PepperInterface* ppapi = NULL;
-  if (instance && get_browser_interface)
+  if (instance && get_browser_interface) {
     ppapi = new RealPepperInterface(instance, get_browser_interface);
-  return ki_init_interface(kp, ppapi);
+    s_state.ppapi = ppapi;
+  }
+  int rtn = ki_init_interface(kp, ppapi);
+  return rtn;
 }
 
 int ki_init_interface(void* kp, void* pepper_interface) {
@@ -92,17 +97,20 @@
 
   // If we are going to delete the KernelProxy don't do it
   // until we've swapped it out.
-  KernelProxy* delete_kp = s_state.kp_owned ? s_state.kp : NULL;
+  KernelInterceptState state_to_delete = s_state;
 
   // Swap out the KernelProxy. This will normally reset the
   // proxy to NULL, aside from in test code that has called
   // ki_push_state_for_testing().
   s_state = s_saved_state;
   s_saved_state.kp = NULL;
+  s_saved_state.ppapi = NULL;
   s_saved_state.kp_owned = false;
 
-  if (delete_kp)
-    delete delete_kp;
+  if (state_to_delete.kp_owned)
+    delete state_to_delete.kp;
+
+  delete state_to_delete.ppapi;
 }
 
 nacl_io::KernelProxy* ki_get_proxy() {
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h
index 9b72f58..65d269b 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h
@@ -55,8 +55,7 @@
 
 /*
  * ki_init_interface() is a variant of ki_init() that can be called with
- * a PepperInterface object.  The ownership of this object then passes
- * to nacl_io and it will be deleted on ki_uninit().
+ * a PepperInterface object.
  */
 int ki_init_interface(void* kernel_proxy, void* pepper_interface);
 
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
index 0cd8c10..65265ba 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
@@ -63,8 +63,6 @@
        ++i) {
     delete i->second;
   }
-
-  delete ppapi_;
 }
 
 Error KernelProxy::Init(PepperInterface* ppapi) {
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
index 1cb1cc2..89b8f19 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
@@ -46,7 +46,6 @@
   KernelProxy();
   virtual ~KernelProxy();
 
-  // Takes ownership of |ppapi|.
   // |ppapi| may be NULL. If so, no filesystem that uses pepper calls can be
   // mounted.
   virtual Error Init(PepperInterface* ppapi);
diff --git a/native_client_sdk/src/libraries/nacl_io/node.cc b/native_client_sdk/src/libraries/nacl_io/node.cc
index b8876ed..fc30867 100644
--- a/native_client_sdk/src/libraries/nacl_io/node.cc
+++ b/native_client_sdk/src/libraries/nacl_io/node.cc
@@ -165,7 +165,7 @@
 
 int Node::GetMode() { return stat_.st_mode & ~S_IFMT; }
 
-Error Node::GetSize(size_t* out_size) {
+Error Node::GetSize(off_t* out_size) {
   *out_size = stat_.st_size;
   return 0;
 }
diff --git a/native_client_sdk/src/libraries/nacl_io/node.h b/native_client_sdk/src/libraries/nacl_io/node.h
index 4e4420c..70d0940 100644
--- a/native_client_sdk/src/libraries/nacl_io/node.h
+++ b/native_client_sdk/src/libraries/nacl_io/node.h
@@ -94,7 +94,7 @@
   virtual int GetType();
   virtual void SetType(int type);
   // Assume that |out_size| is non-NULL.
-  virtual Error GetSize(size_t* out_size);
+  virtual Error GetSize(off_t* out_size);
   // Returns 0 if node is a TTY
   virtual Error Isatty();
 
diff --git a/native_client_sdk/src/libraries/nacl_io/osinttypes.h b/native_client_sdk/src/libraries/nacl_io/osinttypes.h
index 1c907a3..491922c 100644
--- a/native_client_sdk/src/libraries/nacl_io/osinttypes.h
+++ b/native_client_sdk/src/libraries/nacl_io/osinttypes.h
@@ -19,6 +19,9 @@
 
 #else
 
+#if !defined(__STDC_FORMAT_MACROS)
+#define __STDC_FORMAT_MACROS 1
+#endif
 #include <inttypes.h>
 
 #if !defined(PRIuS)
diff --git a/native_client_sdk/src/libraries/ppapi/library.dsc b/native_client_sdk/src/libraries/ppapi/library.dsc
index 919f1f6..7f96b9b 100644
--- a/native_client_sdk/src/libraries/ppapi/library.dsc
+++ b/native_client_sdk/src/libraries/ppapi/library.dsc
@@ -59,9 +59,11 @@
         'ppb_var_array.h',
         'ppb_var_dictionary.h',
         'ppb_var.h',
+        'ppb_video_decoder.h',
         'ppb_video_frame.h',
         'ppb_view.h',
         'ppb_websocket.h',
+        'pp_codecs.h',
         'pp_completion_callback.h',
         'pp_directory_entry.h',
         'pp_errors.h',
diff --git a/native_client_sdk/src/libraries/ppapi_cpp/library.dsc b/native_client_sdk/src/libraries/ppapi_cpp/library.dsc
index b0d13ff..60abc3f 100644
--- a/native_client_sdk/src/libraries/ppapi_cpp/library.dsc
+++ b/native_client_sdk/src/libraries/ppapi_cpp/library.dsc
@@ -55,6 +55,7 @@
         'var_array.cc',
         'var.cc',
         'var_dictionary.cc',
+        'video_decoder.cc',
         'video_frame.cc',
         'view.cc',
         'websocket.cc',
@@ -138,6 +139,7 @@
         'var_array.h',
         'var_dictionary.h',
         'var.h',
+        'video_decoder.h',
         'video_frame.h',
         'view.h',
         'websocket.h',
diff --git a/native_client_sdk/src/libraries/ppapi_stub/library.dsc b/native_client_sdk/src/libraries/ppapi_stub/library.dsc
new file mode 100644
index 0000000..fcb15cf
--- /dev/null
+++ b/native_client_sdk/src/libraries/ppapi_stub/library.dsc
@@ -0,0 +1,19 @@
+{
+  'TOOLS': ['bionic'],
+  'SEARCH': [
+      '.',
+  ],
+  'TARGETS': [
+    {
+      'NAME' : 'ppapi_stub',
+      'TYPE' : 'lib',
+      'SOURCES' : [
+        'main.c',
+        'ppapi_main.c',
+      ],
+    }
+  ],
+  'DEST': 'src',
+  'NAME': 'ppapi_stub',
+}
+
diff --git a/native_client_sdk/src/libraries/ppapi_stub/main.c b/native_client_sdk/src/libraries/ppapi_stub/main.c
new file mode 100644
index 0000000..c1428bc
--- /dev/null
+++ b/native_client_sdk/src/libraries/ppapi_stub/main.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * An application that doesn't define its own main but links in -lppapi
+ * gets this one.  A plugin may instead have its own main that calls
+ * PpapiPluginMain (or PpapiPluginStart) after doing some other setup.
+ */
+
+int PpapiPluginMain();
+
+int main(void) {
+  return PpapiPluginMain();
+}
diff --git a/native_client_sdk/src/libraries/ppapi_stub/ppapi_main.c b/native_client_sdk/src/libraries/ppapi_stub/ppapi_main.c
new file mode 100644
index 0000000..be540b6
--- /dev/null
+++ b/native_client_sdk/src/libraries/ppapi_stub/ppapi_main.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#include <pthread.h>
+
+#include "irt_syscalls.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/ppp.h"
+
+struct PP_StartFunctions {
+  int32_t (*PPP_InitializeModule)(PP_Module module_id,
+                                  PPB_GetInterface get_browser_interface);
+  void (*PPP_ShutdownModule)();
+  const void* (*PPP_GetInterface)(const char* interface_name);
+};
+
+struct PP_ThreadFunctions {
+  /*
+   * This is a cut-down version of pthread_create()/pthread_join().
+   * We omit thread creation attributes and the thread's return value.
+   *
+   * We use uintptr_t as the thread ID type because pthread_t is not
+   * part of the stable ABI; a user thread library might choose an
+   * arbitrary size for its own pthread_t.
+   */
+  int (*thread_create)(uintptr_t* tid,
+                       void (*func)(void* thread_argument),
+                       void* thread_argument);
+  int (*thread_join)(uintptr_t tid);
+};
+
+#define NACL_IRT_PPAPIHOOK_v0_1 "nacl-irt-ppapihook-0.1"
+struct nacl_irt_ppapihook {
+  int (*ppapi_start)(const struct PP_StartFunctions*);
+  void (*ppapi_register_thread_creator)(const struct PP_ThreadFunctions*);
+};
+
+
+static int thread_create(uintptr_t *tid,
+                         void (*func)(void *thread_argument),
+                         void *thread_argument) {
+  /*
+   * We know that newlib and glibc use a small pthread_t type, so we
+   * do not need to wrap pthread_t values.
+   */
+  return pthread_create((pthread_t *) tid, NULL,
+                        (void *(*)(void *thread_argument)) func,
+                        thread_argument);
+}
+
+static int thread_join(uintptr_t tid) {
+  return pthread_join((pthread_t) tid, NULL);
+}
+
+/*
+ * These are dangling references to functions that the application must define.
+ */
+static const struct PP_StartFunctions ppapi_app_start_callbacks = {
+  PPP_InitializeModule,
+  PPP_ShutdownModule,
+  PPP_GetInterface
+};
+
+const static struct PP_ThreadFunctions thread_funcs = {
+  thread_create,
+  thread_join
+};
+
+static void fatal_error(const char *message) {
+  write(2, message, strlen(message));
+  _exit(127);
+}
+
+/*
+ * We cannot tell at link time whether the application uses PPB_Audio,
+ * because of the way that PPAPI is defined via runtime interface
+ * query rather than a set of static functions.  This means that we
+ * register the audio thread functions unconditionally.  This adds the
+ * small overhead of pulling in pthread_create() even if the
+ * application does not use PPB_Audio or libpthread.
+ *
+ * If an application developer wants to avoid that cost, they can
+ * override this function with an empty definition.
+ */
+void __nacl_register_thread_creator(const struct nacl_irt_ppapihook *hooks) {
+  hooks->ppapi_register_thread_creator(&thread_funcs);
+}
+
+int PpapiPluginStart(const struct PP_StartFunctions *funcs) {
+  struct nacl_irt_ppapihook hooks;
+  if (sizeof(hooks) != __nacl_irt_query(NACL_IRT_PPAPIHOOK_v0_1,
+                                        &hooks, sizeof(hooks))) {
+    fatal_error("PpapiPluginStart: PPAPI hooks not found\n");
+  }
+
+  __nacl_register_thread_creator(&hooks);
+  return hooks.ppapi_start(funcs);
+}
+
+
+/*
+ * The application's main (or the one supplied in this library) calls this
+ * to start the PPAPI world.
+ */
+int PpapiPluginMain(void) {
+  return PpapiPluginStart(&ppapi_app_start_callbacks);
+}
diff --git a/native_client_sdk/src/test_all.py b/native_client_sdk/src/test_all.py
index c91e64e..9f468b4 100755
--- a/native_client_sdk/src/test_all.py
+++ b/native_client_sdk/src/test_all.py
@@ -4,14 +4,30 @@
 # found in the LICENSE file.
 
 import os
+import subprocess
 import sys
 import unittest
 
 # add tools folder to sys.path
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-sys.path.append(os.path.join(SCRIPT_DIR, 'tools', 'tests'))
-sys.path.append(os.path.join(SCRIPT_DIR, 'tools', 'lib', 'tests'))
-sys.path.append(os.path.join(SCRIPT_DIR, 'build_tools', 'tests'))
+TOOLS_DIR = os.path.join(SCRIPT_DIR, 'tools')
+BUILD_TOOLS_DIR = os.path.join(SCRIPT_DIR, 'build_tools')
+
+sys.path.append(TOOLS_DIR)
+sys.path.append(os.path.join(TOOLS_DIR, 'tests'))
+sys.path.append(os.path.join(TOOLS_DIR, 'lib', 'tests'))
+sys.path.append(BUILD_TOOLS_DIR)
+sys.path.append(os.path.join(BUILD_TOOLS_DIR, 'tests'))
+
+import build_paths
+
+PKG_VER_DIR = os.path.join(build_paths.NACL_DIR, 'build', 'package_version')
+TAR_DIR = os.path.join(build_paths.NACL_DIR, 'toolchain', '.tars')
+
+PKG_VER = os.path.join(PKG_VER_DIR, 'package_version.py')
+
+EXTRACT_PACKAGES = ['nacl_x86_glibc']
+TOOLCHAIN_OUT = os.path.join(build_paths.OUT_DIR, 'sdk_tests', 'toolchain')
 
 TEST_MODULES = [
     'create_html_test',
@@ -35,7 +51,17 @@
     'verify_ppapi_test',
 ]
 
+def ExtractToolchains():
+  subprocess.check_output([sys.executable, PKG_VER,
+                           '--packages', ','.join(EXTRACT_PACKAGES),
+                           '--tar-dir', TAR_DIR,
+                           '--dest-dir', TOOLCHAIN_OUT,
+                           'extract'])
+
 def main():
+  # Some of the unit tests use parts of toolchains. Extract to TOOLCHAIN_OUT.
+  ExtractToolchains()
+
   suite = unittest.TestSuite()
   for module_name in TEST_MODULES:
     module = __import__(module_name)
diff --git a/native_client_sdk/src/tests/nacl_io_test/dev_fs_for_testing.h b/native_client_sdk/src/tests/nacl_io_test/dev_fs_for_testing.h
index 86fc52b..a898a12 100644
--- a/native_client_sdk/src/tests/nacl_io_test/dev_fs_for_testing.h
+++ b/native_client_sdk/src/tests/nacl_io_test/dev_fs_for_testing.h
@@ -14,15 +14,13 @@
 
 class DevFsForTesting : public nacl_io::DevFs {
  public:
-  DevFsForTesting() {
+  explicit DevFsForTesting(nacl_io::PepperInterface* ppapi) {
     nacl_io::FsInitArgs args(1);
-    args.ppapi = &pepper_;
+    args.ppapi = ppapi;
     Init(args);
   }
 
   int num_nodes() { return (int)inode_pool_.size(); }
- private:
-  FakePepperInterface pepper_;
 };
 
 #endif  // TESTS_NACL_IO_TEST_DEV_FS_FOR_TESTING_H_
diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface_url_loader.cc b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface_url_loader.cc
index 7e5e382..fe56637 100644
--- a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface_url_loader.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface_url_loader.cc
@@ -12,9 +12,12 @@
 
 #include "gtest/gtest.h"
 
+#include "nacl_io/osinttypes.h"
+
 namespace {
 
-bool GetHeaderValue(const std::string& headers, const std::string& key,
+bool GetHeaderValue(const std::string& headers,
+                    const std::string& key,
                     std::string* out_value) {
   out_value->clear();
 
@@ -71,11 +74,11 @@
   static const char* classname() { return "FakeURLLoaderResource"; }
 
   FakeResourceManager* manager;  // Weak reference.
-  FakeURLLoaderServer* server;  // Weak reference.
-  FakeURLLoaderEntity* entity;  // Weak reference.
+  FakeURLLoaderServer* server;   // Weak reference.
+  FakeURLLoaderEntity* entity;   // Weak reference.
   PP_Resource response;
-  size_t read_offset;
-  size_t read_end;
+  off_t read_offset;
+  off_t read_end;
 };
 
 class FakeURLRequestInfoResource : public FakeResource {
@@ -119,7 +122,7 @@
 void HandleContentLength(FakeURLLoaderResource* loader,
                          FakeURLResponseInfoResource* response,
                          FakeURLLoaderEntity* entity) {
-  size_t content_length = entity->body().size();
+  off_t content_length = entity->size();
   if (!loader->server->send_content_length())
     return;
 
@@ -142,14 +145,14 @@
     return;
 
   // We don't support all range requests, just bytes=<num>-<num>
-  unsigned lo;
-  unsigned hi;
-  if (sscanf(range.c_str(), "bytes=%u-%u", &lo, &hi) != 2) {
+  off_t lo;
+  off_t hi;
+  if (sscanf(range.c_str(), "bytes=%" SCNi64 "-%" SCNi64, &lo, &hi) != 2) {
     // Couldn't parse the range value.
     return;
   }
 
-  size_t content_length = entity->body().size();
+  off_t content_length = entity->size();
   if (lo > content_length) {
     // Trying to start reading past the end of the entity is
     // unsatisfiable.
@@ -174,7 +177,8 @@
 
   // Also add a "Content-Range" response header.
   std::ostringstream ss;
-  ss << "Content-Range: " << lo << "-" << hi << "/" << content_length << "\n";
+  ss << "Content-Range: bytes " << lo << "-" << hi << "/" << content_length
+     << "\n";
   response->headers += ss.str();
 
   response->status_code = 206;  // Partial content
@@ -183,10 +187,59 @@
 }  // namespace
 
 FakeURLLoaderEntity::FakeURLLoaderEntity(const std::string& body)
-    : body_(body) {}
+    : body_(body), size_(body_.size()), repeat_(false) {
+}
+
+// Rather than specifying the entire file, specify a string to repeat, and the
+// full length. This lets us test extremely large files without having to store
+// them in memory.
+FakeURLLoaderEntity::FakeURLLoaderEntity(const std::string& to_repeat,
+                                         off_t size)
+    : body_(to_repeat), size_(size), repeat_(true) {
+}
+
+size_t FakeURLLoaderEntity::Read(void* buffer, size_t count, off_t offset) {
+  off_t max_read_count =
+      std::max<off_t>(std::min<off_t>(size_ - offset, 0xffffffff), 0);
+  size_t bytes_to_read = std::min(count, static_cast<size_t>(max_read_count));
+
+  if (repeat_) {
+    size_t src_size = body_.size();
+    char* dst = static_cast<char*>(buffer);
+    const char* src = body_.data();
+    size_t bytes_left = bytes_to_read;
+
+    size_t src_offset = static_cast<size_t>(offset % src_size);
+    if (src_offset != 0) {
+      // Copy enough to align.
+      size_t bytes_to_copy = std::min(bytes_left, src_size - src_offset);
+      memcpy(dst, src + src_offset, bytes_to_copy);
+      dst += bytes_to_copy;
+      bytes_left -= bytes_to_copy;
+    }
+
+    // Copy the body N times.
+    for (size_t i = bytes_left / src_size; i > 0; --i) {
+      memcpy(dst, src, src_size);
+      dst += src_size;
+      bytes_left -= src_size;
+    }
+
+    // Copy the rest of the bytes, < src_size.
+    if (bytes_left > 0) {
+      assert(bytes_left < src_size);
+      memcpy(dst, src, bytes_left);
+    }
+  } else {
+    memcpy(buffer, &body_.data()[offset], bytes_to_read);
+  }
+
+  return bytes_to_read;
+}
 
 FakeURLLoaderServer::FakeURLLoaderServer()
-    : max_read_size_(0), send_content_length_(false), allow_partial_(false) {}
+    : max_read_size_(0), send_content_length_(false), allow_partial_(false) {
+}
 
 void FakeURLLoaderServer::Clear() {
   entity_map_.clear();
@@ -212,6 +265,27 @@
   return true;
 }
 
+bool FakeURLLoaderServer::AddEntity(const std::string& url,
+                                    const std::string& body,
+                                    off_t size,
+                                    FakeURLLoaderEntity** out_entity) {
+  EntityMap::iterator iter = entity_map_.find(url);
+  if (iter != entity_map_.end()) {
+    if (out_entity)
+      *out_entity = NULL;
+    return false;
+  }
+
+  FakeURLLoaderEntity entity(body, size);
+  std::pair<EntityMap::iterator, bool> result =
+      entity_map_.insert(EntityMap::value_type(url, entity));
+
+  EXPECT_EQ(true, result.second);
+  if (out_entity)
+    *out_entity = &result.first->second;
+  return true;
+}
+
 bool FakeURLLoaderServer::AddError(const std::string& url,
                                    int http_status_code) {
   ErrorMap::iterator iter = error_map_.find(url);
@@ -238,7 +312,8 @@
 
 FakeURLLoaderInterface::FakeURLLoaderInterface(
     FakeCoreInterface* core_interface)
-    : core_interface_(core_interface) {}
+    : core_interface_(core_interface) {
+}
 
 PP_Resource FakeURLLoaderInterface::Create(PP_Instance instance) {
   FakeInstanceResource* instance_resource =
@@ -311,7 +386,7 @@
   }
 
   if (entity != NULL) {
-    size_t content_length = entity->body().size();
+    off_t content_length = entity->size();
     loader_resource->read_end = content_length;
     HandleContentLength(loader_resource, response_resource, entity);
     HandlePartial(loader_resource, request_resource, response_resource, entity);
@@ -346,22 +421,18 @@
     // TODO(binji): figure out the correct error here.
     return PP_ERROR_FAILED;
 
-  const std::string& body = loader_resource->entity->body();
-  size_t offset = loader_resource->read_offset;
-  // Never read more than is available.
-  size_t max_readable = std::max<size_t>(0, body.length() - offset);
-  size_t server_max_read_size = loader_resource->server->max_read_size();
   // Allow the test to specify how much the "server" should send in each call
   // to ReadResponseBody. A max_read_size of 0 means read as much as the
   // buffer will allow.
+  size_t server_max_read_size = loader_resource->server->max_read_size();
   if (server_max_read_size != 0)
-    max_readable = std::min(max_readable, server_max_read_size);
+    bytes_to_read = std::min<int32_t>(bytes_to_read, server_max_read_size);
 
-  bytes_to_read = std::min(static_cast<size_t>(bytes_to_read), max_readable);
-  memcpy(buffer, &body.data()[offset], bytes_to_read);
-  loader_resource->read_offset += bytes_to_read;
+  size_t bytes_read = loader_resource->entity->Read(
+      buffer, bytes_to_read, loader_resource->read_offset);
+  loader_resource->read_offset += bytes_read;
 
-  return RunCompletionCallback(&callback, bytes_to_read);
+  return RunCompletionCallback(&callback, bytes_read);
 }
 
 void FakeURLLoaderInterface::Close(PP_Resource loader) {
@@ -381,7 +452,8 @@
 FakeURLRequestInfoInterface::FakeURLRequestInfoInterface(
     FakeCoreInterface* core_interface,
     FakeVarInterface* var_interface)
-    : core_interface_(core_interface), var_interface_(var_interface) {}
+    : core_interface_(core_interface), var_interface_(var_interface) {
+}
 
 PP_Resource FakeURLRequestInfoInterface::Create(PP_Instance instance) {
   FakeInstanceResource* instance_resource =
@@ -466,7 +538,8 @@
 FakeURLResponseInfoInterface::FakeURLResponseInfoInterface(
     FakeCoreInterface* core_interface,
     FakeVarInterface* var_interface)
-    : core_interface_(core_interface), var_interface_(var_interface) {}
+    : core_interface_(core_interface), var_interface_(var_interface) {
+}
 
 PP_Var FakeURLResponseInfoInterface::GetProperty(
     PP_Resource response,
diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface_url_loader.h b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface_url_loader.h
index 5068f2d..e333f8b 100644
--- a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface_url_loader.h
+++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface_url_loader.h
@@ -18,11 +18,17 @@
 class FakeURLLoaderEntity {
  public:
   explicit FakeURLLoaderEntity(const std::string& body);
+  FakeURLLoaderEntity(const std::string& to_repeat, off_t size);
 
   const std::string& body() const { return body_; }
+  off_t size() { return size_; }
+
+  size_t Read(void* buffer, size_t count, off_t offset);
 
  private:
   std::string body_;
+  off_t size_;
+  bool repeat_;
 };
 
 class FakeURLLoaderServer {
@@ -33,6 +39,10 @@
   bool AddEntity(const std::string& url,
                  const std::string& body,
                  FakeURLLoaderEntity** out_entity);
+  bool AddEntity(const std::string& url,
+                 const std::string& body,
+                 off_t size,
+                 FakeURLLoaderEntity** out_entity);
   bool AddError(const std::string& url,
                 int http_status_code);
   FakeURLLoaderEntity* GetEntity(const std::string& url);
diff --git a/native_client_sdk/src/tests/nacl_io_test/filesystem_test.cc b/native_client_sdk/src/tests/nacl_io_test/filesystem_test.cc
index 1e6ece1..6089b01 100644
--- a/native_client_sdk/src/tests/nacl_io_test/filesystem_test.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/filesystem_test.cc
@@ -40,7 +40,7 @@
   ScopedNode root;
   ScopedNode result_node;
 
-  size_t result_size = 0;
+  off_t result_size = 0;
   int result_bytes = 0;
   char buf1[1024];
 
@@ -270,7 +270,8 @@
 
 TEST(FilesystemTest, DevAccess) {
   // Should not be able to open non-existent file.
-  DevFsForTesting fs;
+  FakePepperInterface pepper;
+  DevFsForTesting fs(&pepper);
   ScopedNode invalid_node, valid_node;
   ASSERT_EQ(ENOENT, fs.Access(Path("/foo"), F_OK));
   // Creating non-existent file should return EACCES
@@ -290,7 +291,8 @@
 }
 
 TEST(FilesystemTest, DevNull) {
-  DevFsForTesting fs;
+  FakePepperInterface pepper;
+  DevFsForTesting fs(&pepper);
   ScopedNode dev_null;
   int result_bytes = 0;
 
@@ -313,7 +315,8 @@
 }
 
 TEST(FilesystemTest, DevZero) {
-  DevFsForTesting fs;
+  FakePepperInterface pepper;
+  DevFsForTesting fs(&pepper);
   ScopedNode dev_zero;
   int result_bytes = 0;
 
@@ -343,7 +346,8 @@
 
 // Disabled due to intermittent failures on linux: http://crbug.com/257257
 TEST(FilesystemTest, DISABLED_DevUrandom) {
-  DevFsForTesting fs;
+  FakePepperInterface pepper;
+  DevFsForTesting fs(&pepper);
   ScopedNode dev_urandom;
   int result_bytes = 0;
 
diff --git a/native_client_sdk/src/tests/nacl_io_test/host_resolver_test.cc b/native_client_sdk/src/tests/nacl_io_test/host_resolver_test.cc
index 642ffd1..b5810c0 100644
--- a/native_client_sdk/src/tests/nacl_io_test/host_resolver_test.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/host_resolver_test.cc
@@ -35,19 +35,18 @@
 
 class FakeHostResolverTest : public ::testing::Test {
  public:
-  FakeHostResolverTest() : pepper_(NULL), fake_resolver_(NULL) {}
+  FakeHostResolverTest() : fake_resolver_(NULL) {}
 
   void SetUp() {
-    pepper_ = new FakePepperInterface();
     fake_resolver_ = static_cast<FakeHostResolverInterface*>(
-        pepper_->GetHostResolverInterface());
+        pepper_.GetHostResolverInterface());
 
     // Seed the fake resolver with some data
     fake_resolver_->fake_hostname = FAKE_HOSTNAME;
     AddFakeAddress(AF_INET);
 
     ASSERT_EQ(0, ki_push_state_for_testing());
-    ASSERT_EQ(0, ki_init_interface(NULL, pepper_));
+    ASSERT_EQ(0, ki_init_interface(NULL, &pepper_));
   }
 
   void AddFakeAddress(int family) {
@@ -72,11 +71,10 @@
 
   void TearDown() {
     ki_uninit();
-    pepper_ = NULL;
   }
 
  protected:
-  FakePepperInterface* pepper_;
+  FakePepperInterface pepper_;
   FakeHostResolverInterface* fake_resolver_;
 };
 
diff --git a/native_client_sdk/src/tests/nacl_io_test/html5_fs_test.cc b/native_client_sdk/src/tests/nacl_io_test/html5_fs_test.cc
index 3acbaa8..8ea7c07 100644
--- a/native_client_sdk/src/tests/nacl_io_test/html5_fs_test.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/html5_fs_test.cc
@@ -223,7 +223,7 @@
   ASSERT_EQ(0, fs->Open(path, O_CREAT, &node));
 
   // Check that the file still has data.
-  size_t size;
+  off_t size;
   EXPECT_EQ(0, node->GetSize(&size));
   EXPECT_EQ(strlen(contents), size);
 
@@ -359,7 +359,7 @@
   EXPECT_EQ(modified_time, statbuf.st_mtime);
 
   // Test Get* and Isa* methods.
-  size_t size;
+  off_t size;
   EXPECT_EQ(0, node->GetSize(&size));
   EXPECT_EQ(strlen(contents), size);
   EXPECT_FALSE(node->IsaDir());
diff --git a/native_client_sdk/src/tests/nacl_io_test/http_fs_test.cc b/native_client_sdk/src/tests/nacl_io_test/http_fs_test.cc
index 1168d68..4b9a4f2 100644
--- a/native_client_sdk/src/tests/nacl_io_test/http_fs_test.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/http_fs_test.cc
@@ -71,6 +71,11 @@
 
 HttpFsTest::HttpFsTest() : fs_(MakeStringMap(GetParam()), &ppapi_) {}
 
+class HttpFsLargeFileTest : public HttpFsTest {
+ public:
+  HttpFsLargeFileTest() {}
+};
+
 }  // namespace
 
 TEST_P(HttpFsTest, Access) {
@@ -200,6 +205,71 @@
                       (uint32_t)kStringMapParamCacheStat,
                       (uint32_t)kStringMapParamCacheContentStat));
 
+TEST_P(HttpFsLargeFileTest, ReadPartial) {
+  const char contents[] = "0123456789abcdefg";
+  off_t size = 0x110000000ll;
+  ASSERT_TRUE(
+      ppapi_.server_template()->AddEntity("file", contents, size, NULL));
+  ppapi_.server_template()->set_send_content_length(true);
+  ppapi_.server_template()->set_allow_partial(true);
+
+  int result_bytes = 0;
+
+  char buf[10];
+  memset(&buf[0], 0, sizeof(buf));
+
+  ScopedNode node;
+  ASSERT_EQ(0, fs_.Open(Path("/file"), O_RDONLY, &node));
+  HandleAttr attr;
+  EXPECT_EQ(0, node->Read(attr, buf, sizeof(buf) - 1, &result_bytes));
+  EXPECT_EQ(sizeof(buf) - 1, result_bytes);
+  EXPECT_STREQ("012345678", &buf[0]);
+
+  // Read is clamped when reading past the end of the file.
+  attr.offs = size - 7;
+  ASSERT_EQ(0, node->Read(attr, buf, sizeof(buf) - 1, &result_bytes));
+  ASSERT_EQ(strlen("abcdefg"), result_bytes);
+  buf[result_bytes] = 0;
+  EXPECT_STREQ("abcdefg", &buf[0]);
+
+  // Read nothing when starting past the end of the file.
+  attr.offs = size + 100;
+  EXPECT_EQ(0, node->Read(attr, &buf[0], sizeof(buf), &result_bytes));
+  EXPECT_EQ(0, result_bytes);
+}
+
+TEST_P(HttpFsLargeFileTest, GetStat) {
+  const char contents[] = "contents";
+  off_t size = 0x110000000ll;
+  ASSERT_TRUE(
+      ppapi_.server_template()->AddEntity("file", contents, size, NULL));
+  // TODO(binji): If the server doesn't send the content length, this operation
+  // will be incredibly slow; it will attempt to read all of the data from the
+  // server to find the file length. Can we do anything smarter?
+  ppapi_.server_template()->set_send_content_length(true);
+
+  ScopedNode node;
+  ASSERT_EQ(0, fs_.Open(Path("/file"), O_RDONLY, &node));
+
+  struct stat statbuf;
+  EXPECT_EQ(0, node->GetStat(&statbuf));
+  EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,
+            statbuf.st_mode);
+  EXPECT_EQ(size, statbuf.st_size);
+  // These are not currently set.
+  EXPECT_EQ(0, statbuf.st_atime);
+  EXPECT_EQ(0, statbuf.st_ctime);
+  EXPECT_EQ(0, statbuf.st_mtime);
+}
+
+// Instantiate the large file tests, only when cache content is off.
+// TODO(binji): make cache content smarter, so it doesn't try to cache enormous
+// files. See http://crbug.com/369279.
+INSTANTIATE_TEST_CASE_P(Default,
+                        HttpFsLargeFileTest,
+                        ::testing::Values((uint32_t)kStringMapParamCacheNone,
+                                          (uint32_t)kStringMapParamCacheStat));
+
 TEST(HttpFsDirTest, Mkdir) {
   StringMap_t args;
   HttpFsForTesting fs(args, NULL);
@@ -254,7 +324,7 @@
 
 TEST(HttpFsDirTest, ParseManifest) {
   StringMap_t args;
-  size_t result_size = 0;
+  off_t result_size = 0;
 
   HttpFsForTesting fs(args, NULL);
 
diff --git a/native_client_sdk/src/tests/nacl_io_test/jspipe_test.cc b/native_client_sdk/src/tests/nacl_io_test/jspipe_test.cc
index 63872be..b14bf18 100644
--- a/native_client_sdk/src/tests/nacl_io_test/jspipe_test.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/jspipe_test.cc
@@ -27,6 +27,8 @@
 
 class JSPipeTest : public ::testing::Test {
  public:
+  JSPipeTest() : fs_(&pepper_) {}
+
   void SetUp() {
     ASSERT_EQ(0, ki_push_state_for_testing());
     ASSERT_EQ(0, ki_init(&kp_));
@@ -40,6 +42,7 @@
 
  protected:
   KernelProxy kp_;
+  FakePepperInterface pepper_;
   DevFsForTesting fs_;
   ScopedNode pipe_dev_;
 };
diff --git a/native_client_sdk/src/tests/nacl_io_test/kernel_wrap_test.cc b/native_client_sdk/src/tests/nacl_io_test/kernel_wrap_test.cc
index bbfa600..72d89d9 100644
--- a/native_client_sdk/src/tests/nacl_io_test/kernel_wrap_test.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/kernel_wrap_test.cc
@@ -15,6 +15,7 @@
 #include "mock_kernel_proxy.h"
 #include "nacl_io/kernel_intercept.h"
 #include "nacl_io/kernel_wrap.h"
+#include "nacl_io/kernel_wrap_real.h"
 #include "nacl_io/osmman.h"
 #include "nacl_io/ossocket.h"
 #include "nacl_io/ostermios.h"
@@ -30,7 +31,9 @@
 using namespace nacl_io;
 
 using ::testing::_;
+using ::testing::AnyNumber;
 using ::testing::DoAll;
+using ::testing::Invoke;
 using ::testing::Return;
 using ::testing::StrEq;
 
@@ -121,6 +124,13 @@
 
     ASSERT_EQ(0, ki_push_state_for_testing());
     ASSERT_EQ(0, ki_init(&mock));
+
+    // We allow write to be called any number of times, and it forwards to
+    // _real_write. This prevents an infinite loop writing output if there is a
+    // failure.
+    ON_CALL(mock, write(_, _, _))
+        .WillByDefault(Invoke(this, &KernelWrapTest::DefaultWrite));
+    EXPECT_CALL(mock, write(_, _, _)).Times(AnyNumber());
   }
 
   void TearDown() {
@@ -129,8 +139,19 @@
     ki_uninit();
   }
 
-
   MockKernelProxy mock;
+
+ private:
+  ssize_t DefaultWrite(int fd, const void* buf, size_t count) {
+   assert(fd <= 2);
+   size_t nwrote;
+   int rtn = _real_write(fd, buf, count, &nwrote);
+   if (rtn != 0) {
+     errno = rtn;
+     return -1;
+   }
+   return nwrote;
+  }
 };
 
 }  // namespace
diff --git a/native_client_sdk/src/tests/nacl_io_test/mem_fs_node_test.cc b/native_client_sdk/src/tests/nacl_io_test/mem_fs_node_test.cc
index d6d8c18..dc521c6 100644
--- a/native_client_sdk/src/tests/nacl_io_test/mem_fs_node_test.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/mem_fs_node_test.cc
@@ -68,7 +68,7 @@
 TEST(MemFsNodeTest, File) {
   MemFsNodeForTesting file;
   ScopedNode result_node;
-  size_t result_size = 0;
+  off_t result_size = 0;
   int result_bytes = 0;
 
   EXPECT_EQ(0, file.Init(0));
@@ -120,7 +120,7 @@
 
 TEST(MemFsNodeTest, FTruncate) {
   MemFsNodeForTesting file;
-  size_t result_size = 0;
+  off_t result_size = 0;
   int result_bytes = 0;
 
   char data[1024];
@@ -197,7 +197,7 @@
   s_alloc_num = 0;
   DirNodeForTesting root;
   ScopedNode result_node;
-  size_t result_size = 0;
+  off_t result_size = 0;
   int result_bytes = 0;
 
   root.Init(0);
diff --git a/native_client_sdk/src/tests/nacl_io_test/mock_node.h b/native_client_sdk/src/tests/nacl_io_test/mock_node.h
index 8286e3a..307ee2e 100644
--- a/native_client_sdk/src/tests/nacl_io_test/mock_node.h
+++ b/native_client_sdk/src/tests/nacl_io_test/mock_node.h
@@ -32,7 +32,7 @@
   MOCK_METHOD0(GetLinks, int());
   MOCK_METHOD0(GetMode, int());
   MOCK_METHOD0(GetType, int());
-  MOCK_METHOD1(GetSize, Error(size_t*));
+  MOCK_METHOD1(GetSize, Error(off_t*));
   MOCK_METHOD0(IsaDir, bool());
   MOCK_METHOD0(IsaFile, bool());
   MOCK_METHOD0(Isatty, Error());
diff --git a/native_client_sdk/src/tests/nacl_io_test/tty_test.cc b/native_client_sdk/src/tests/nacl_io_test/tty_test.cc
index de9e978..d54fa96 100644
--- a/native_client_sdk/src/tests/nacl_io_test/tty_test.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/tty_test.cc
@@ -24,31 +24,44 @@
 
 namespace {
 
-class TtyTest : public ::testing::Test {
+class TtyNodeTest : public ::testing::Test {
  public:
+  TtyNodeTest() : fs_(&pepper_) {}
+
   void SetUp() {
-    ASSERT_EQ(0, ki_push_state_for_testing());
-    ASSERT_EQ(0, ki_init(&kp_));
     ASSERT_EQ(0, fs_.Access(Path("/tty"), R_OK | W_OK));
     ASSERT_EQ(EACCES, fs_.Access(Path("/tty"), X_OK));
     ASSERT_EQ(0, fs_.Open(Path("/tty"), O_RDWR, &dev_tty_));
     ASSERT_NE(NULL_NODE, dev_tty_.get());
   }
 
-  void TearDown() { ki_uninit(); }
-
  protected:
-  KernelProxy kp_;
+  FakePepperInterface pepper_;
   DevFsForTesting fs_;
   ScopedNode dev_tty_;
 };
 
-TEST_F(TtyTest, InvalidIoctl) {
+class TtyTest : public ::testing::Test {
+ public:
+  void SetUp() {
+    ASSERT_EQ(0, ki_push_state_for_testing());
+    ASSERT_EQ(0, ki_init(&kp_));
+  }
+
+  void TearDown() {
+    ki_uninit();
+  }
+
+ protected:
+  KernelProxy kp_;
+};
+
+TEST_F(TtyNodeTest, InvalidIoctl) {
   // 123 is not a valid ioctl request.
   EXPECT_EQ(EINVAL, dev_tty_->Ioctl(123));
 }
 
-TEST_F(TtyTest, TtyInput) {
+TEST_F(TtyNodeTest, TtyInput) {
   // Now let's try sending some data over.
   // First we create the message.
   std::string message("hello, how are you?\n");
@@ -99,7 +112,7 @@
   return count;
 }
 
-TEST_F(TtyTest, TtyOutput) {
+TEST_F(TtyNodeTest, TtyOutput) {
   // When no handler is registered then all writes should return EIO
   int bytes_written = 10;
   const char* message = "hello\n";
@@ -238,28 +251,29 @@
   ASSERT_EQ(0, IsReadable(tty_fd));
 }
 
-static int g_recieved_signal;
+static int g_received_signal;
 
-static void sighandler(int sig) { g_recieved_signal = sig; }
+static void sighandler(int sig) { g_received_signal = sig; }
 
 TEST_F(TtyTest, WindowSize) {
   // Get current window size
   struct winsize old_winsize = {0};
-  ASSERT_EQ(0, dev_tty_->Ioctl(TIOCGWINSZ, &old_winsize));
+  int tty_fd = ki_open("/dev/tty", O_RDONLY);
+  ASSERT_EQ(0, ki_ioctl_wrapper(tty_fd, TIOCGWINSZ, &old_winsize));
 
   // Install signal handler
   sighandler_t new_handler = sighandler;
   sighandler_t old_handler = ki_signal(SIGWINCH, new_handler);
   ASSERT_NE(SIG_ERR, old_handler) << "signal return error: " << errno;
 
-  g_recieved_signal = 0;
+  g_received_signal = 0;
 
   // Set a new windows size
   struct winsize winsize;
   winsize.ws_col = 100;
   winsize.ws_row = 200;
-  EXPECT_EQ(0, dev_tty_->Ioctl(TIOCSWINSZ, &winsize));
-  EXPECT_EQ(SIGWINCH, g_recieved_signal);
+  EXPECT_EQ(0, ki_ioctl_wrapper(tty_fd, TIOCSWINSZ, &winsize));
+  EXPECT_EQ(SIGWINCH, g_received_signal);
 
   // Restore old signal handler
   EXPECT_EQ(new_handler, ki_signal(SIGWINCH, old_handler));
@@ -267,12 +281,12 @@
   // Verify new window size can be queried correctly.
   winsize.ws_col = 0;
   winsize.ws_row = 0;
-  EXPECT_EQ(0, dev_tty_->Ioctl(TIOCGWINSZ, &winsize));
+  EXPECT_EQ(0, ki_ioctl_wrapper(tty_fd, TIOCGWINSZ, &winsize));
   EXPECT_EQ(100, winsize.ws_col);
   EXPECT_EQ(200, winsize.ws_row);
 
   // Restore original windows size.
-  EXPECT_EQ(0, dev_tty_->Ioctl(TIOCSWINSZ, &old_winsize));
+  EXPECT_EQ(0, ki_ioctl_wrapper(tty_fd, TIOCSWINSZ, &old_winsize));
 }
 
 /*
@@ -343,7 +357,7 @@
   FD_SET(tty_fd, &errorfds);
 
   pthread_t resize_thread;
-  pthread_create(&resize_thread, NULL, input_thread_main, &dev_tty_);
+  pthread_create(&resize_thread, NULL, input_thread_main, NULL);
 
   struct timeval timeout;
   timeout.tv_sec = 20;
diff --git a/native_client_sdk/src/tools/common.mk b/native_client_sdk/src/tools/common.mk
index df2939d..e09f3e5 100644
--- a/native_client_sdk/src/tools/common.mk
+++ b/native_client_sdk/src/tools/common.mk
@@ -36,7 +36,6 @@
 NACL_CONFIG := python $(NACL_SDK_ROOT)/tools/nacl_config.py
 FIXDEPS := python $(NACL_SDK_ROOT)/tools/fix_deps.py -c
 OSNAME := $(shell $(GETOS))
-GDB_PATH := $(shell $(NACL_CONFIG) -t $(TOOLCHAIN) --tool=gdb)
 
 
 #
@@ -479,6 +478,7 @@
 NULL :=
 SPACE := $(NULL) # one space after NULL is required
 CHROME_PATH_ESCAPE := $(subst $(SPACE),\ ,$(CHROME_PATH))
+GDB_PATH := $(shell $(NACL_CONFIG) -t $(TOOLCHAIN) --tool=gdb)
 
 .PHONY: check_for_chrome
 check_for_chrome:
diff --git a/native_client_sdk/src/tools/lib/tests/get_shared_deps_test.py b/native_client_sdk/src/tools/lib/tests/get_shared_deps_test.py
index a023c18..2f35f78 100755
--- a/native_client_sdk/src/tools/lib/tests/get_shared_deps_test.py
+++ b/native_client_sdk/src/tools/lib/tests/get_shared_deps_test.py
@@ -14,13 +14,18 @@
 LIB_DIR = os.path.dirname(SCRIPT_DIR)
 TOOLS_DIR = os.path.dirname(LIB_DIR)
 DATA_DIR = os.path.join(SCRIPT_DIR, 'data')
-CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(TOOLS_DIR)))
 
 sys.path.append(LIB_DIR)
 sys.path.append(TOOLS_DIR)
 
-import getos
+import build_paths
 import get_shared_deps
+import getos
+
+TOOLCHAIN_OUT = os.path.join(build_paths.OUT_DIR, 'sdk_tests', 'toolchain')
+NACL_X86_GLIBC_TOOLCHAIN = os.path.join(TOOLCHAIN_OUT,
+                                        '%s_x86' % getos.GetPlatform(),
+                                        'nacl_x86_glibc')
 
 
 def StripDependencies(deps):
@@ -42,9 +47,7 @@
 class TestGetNeeded(unittest.TestCase):
   def setUp(self):
     self.tempdir = None
-    toolchain = os.path.join(CHROME_SRC, 'native_client', 'toolchain')
-    self.toolchain = os.path.join(toolchain, '%s_x86' % getos.GetPlatform(),
-                                  'nacl_x86_glibc')
+    self.toolchain = NACL_X86_GLIBC_TOOLCHAIN
     self.objdump = os.path.join(self.toolchain, 'bin', 'i686-nacl-objdump')
     if os.name == 'nt':
       self.objdump += '.exe'
diff --git a/native_client_sdk/src/tools/tests/create_nmf_test.py b/native_client_sdk/src/tools/tests/create_nmf_test.py
index da09dd2..86a89a2 100755
--- a/native_client_sdk/src/tools/tests/create_nmf_test.py
+++ b/native_client_sdk/src/tools/tests/create_nmf_test.py
@@ -15,16 +15,21 @@
 TOOLS_DIR = os.path.dirname(SCRIPT_DIR)
 DATA_DIR = os.path.join(TOOLS_DIR, 'lib', 'tests', 'data')
 CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(TOOLS_DIR)))
-MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock")
+MOCK_DIR = os.path.join(CHROME_SRC, 'third_party', 'pymock')
 
 # For the mock library
 sys.path.append(MOCK_DIR)
 sys.path.append(TOOLS_DIR)
 
+import build_paths
 import create_nmf
 import getos
 import mock
 
+TOOLCHAIN_OUT = os.path.join(build_paths.OUT_DIR, 'sdk_tests', 'toolchain')
+NACL_X86_GLIBC_TOOLCHAIN = os.path.join(TOOLCHAIN_OUT,
+                                        '%s_x86' % getos.GetPlatform(),
+                                        'nacl_x86_glibc')
 
 PosixRelPath = create_nmf.PosixRelPath
 
@@ -83,9 +88,7 @@
 
   def setUp(self):
     self.tempdir = None
-    toolchain = os.path.join(CHROME_SRC, 'native_client', 'toolchain')
-    self.toolchain = os.path.join(toolchain, '%s_x86' % getos.GetPlatform(),
-                                  'nacl_x86_glibc')
+    self.toolchain = NACL_X86_GLIBC_TOOLCHAIN
     self.objdump = os.path.join(self.toolchain, 'bin', 'i686-nacl-objdump')
     if os.name == 'nt':
       self.objdump += '.exe'
diff --git a/native_client_sdk/src/web/manifest.html b/native_client_sdk/src/web/manifest.html
index 7da5a3f..4b6a075 100644
--- a/native_client_sdk/src/web/manifest.html
+++ b/native_client_sdk/src/web/manifest.html
@@ -45,6 +45,18 @@
     td a {
       padding: 3px;
     }
+
+    #log > span {
+      display: block;
+    }
+
+    #log > span.highlight {
+      font-weight: bold;
+    }
+
+    #log > span.missing {
+      color: #f00;
+    }
   </style>
   <body>
     <h1>NaCl SDK Manifest Viewer</h1>
@@ -55,8 +67,8 @@
       </tbody>
     </table>
     <h2>Most recent upload log:</h2>
-    <pre id="log">
-    </pre>
+    <div id="log">
+    </div>
     <script type="application/javascript">
       function loadText(url, callback) {
         var xhr = new XMLHttpRequest();
@@ -66,7 +78,7 @@
             if (xhr.status == 200) {
               callback(xhr.responseText);
             } else {
-              alert("Failed to load: error " + xhr.status);
+              console.log("Failed to load "+url+": error " + xhr.status);
             }
           }
         }
@@ -96,49 +108,145 @@
         // Create the column headers.
         var tr = document.createElement('tr');
         var columns = [
-          'name', 'version', 'revision', 'win', 'mac', 'linux', 'all'
+          'name', 'version', 'revision', 'trunk_revision', 'chrome_version', 'win', 'mac', 'linux', 'all'
         ];
-        for (var i = 0; i < columns.length; ++i) {
+        columns.forEach(function(column) {
           var td = document.createElement('td');
-          var text = document.createTextNode(columns[i]);
+          var text = document.createTextNode(column);
           td.appendChild(text);
           tr.appendChild(td);
-        }
+        });
         columnsElm.appendChild(tr);
 
-        var platforms = ['win', 'mac', 'linux', 'all'];
-
-        for (var i = 0; i < data.length; ++i) {
+        data.forEach(function(row) {
           var tr = document.createElement('tr');
-          for (var j = 0; j < columns.length; ++j) {
+          columns.forEach(function(column) {
             var td = document.createElement('td');
-            var node;
-            if (platforms.indexOf(columns[j]) != -1) {
-              var archives = data[i].archives;
-              for (var k = 0; k < archives.length; ++k) {
-                if (columns[j] == archives[k].host_os) {
-                  var url = archives[k].url;
-                  var lastSlash = url.lastIndexOf('/');
-                  var nextDot = url.indexOf('.', lastSlash);
-                  name = url.substr(lastSlash + 1, nextDot - lastSlash - 1);
-                  node = document.createElement('a');
-                  node.setAttribute('href', url);
-                  node.appendChild(document.createTextNode(name));
-                  td.appendChild(node);
-                }
-              }
-            } else {
-              node = document.createTextNode(data[i][columns[j]]);
+            var node = makeCell(row, column);
+            if (node) {
               td.appendChild(node);
             }
             tr.appendChild(td);
-          }
+          });
           rowsElm.appendChild(tr);
+        });
+      }
+
+      function makeCell(row, column) {
+        var platforms = ['win', 'mac', 'linux', 'all'];
+
+        if (platforms.indexOf(column) !== -1) {
+          return makePlatformCell(row, column);
+        } else if (column === 'trunk_revision') {
+          return makeTrunkRevisionCell(row);
+        } else if (column === 'chrome_version') {
+          return makeChromeVersionCell(row);
+        } else {
+          return document.createTextNode(row[column]);
         }
       }
 
+      function makePlatformCell(row, column) {
+        var archives = row.archives;
+        for (var k = 0; k < archives.length; ++k) {
+          if (column !== archives[k].host_os) {
+            continue;
+          }
+
+          // Convert the URL to a short name:
+          // https://.../36.0.1974.2/naclsdk_linux.tar.bz2 -> naclsdk_linux
+          var url = archives[k].url;
+          var lastSlash = url.lastIndexOf('/');
+          var nextDot = url.indexOf('.', lastSlash);
+          var name = url.substr(lastSlash + 1, nextDot - lastSlash - 1);
+
+          var node = document.createElement('a');
+          node.setAttribute('href', url);
+          node.appendChild(document.createTextNode(name));
+          return node;
+        }
+        return null;
+      }
+
+      function makeTrunkRevisionCell(row) {
+        var url = row.archives[0].url;
+        var version = versionFromUrl(url);
+        if (version) {
+          var node = document.createTextNode('');
+          baseTrunkRevisionFromVersion(version, function(node) {
+            return function(revision) {
+              node.textContent = revision;
+            };
+          }(node));
+          return node;
+        }
+        return null;
+      }
+
+      function makeChromeVersionCell(row) {
+        var url = row.archives[0].url;
+        var version = versionFromUrl(url);
+        if (version) {
+          return document.createTextNode(version);
+        }
+        return null;
+      }
+
+      function versionFromUrl(url) {
+        // Extract the Chrome version from an archive URL.
+        // It should look something like:
+        // https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/36.0.1974.2/naclsdk_win.tar.bz2
+        var lastSlash = url.lastIndexOf('/');
+        var penultimateSlash = url.lastIndexOf('/', lastSlash - 1);
+        // The version is between these two slashes.
+        var version = url.substr(penultimateSlash + 1,
+                                 lastSlash - penultimateSlash - 1);
+        // It is a chrome version if it matches one of these regexes:
+        if (/trunk\.\d+/.test(version)) {
+          // Trunk version.
+          return version;
+        } else if (/\d+\.\d+\.\d+\.\d+/.test(version)) {
+          // Branch version.
+          return version;
+        } else {
+          // Not a version.
+          return null;
+        }
+      }
+
+      function baseTrunkRevisionFromVersion(version, callback) {
+        if (version.indexOf('trunk', 0) === 0) {
+          callback(version.substr(6));  // Skip "trunk."
+        } else {
+          revisionFromVersion(baseTrunkVersionFromVersion(version), callback);
+        }
+      }
+
+      function baseTrunkVersionFromVersion(version) {
+        var lastDot = version.lastIndexOf('.');
+        return version.substr(0, lastDot) + '.0';
+      }
+
+      function revisionFromVersion(version, callback) {
+        var url = 'http://omahaproxy.appspot.com/revision.json?version='+version;
+        loadJson(url, function(data) {
+          callback(data.chromium_revision);
+        });
+      }
+
       function displayLog(text) {
-        document.getElementById('log').textContent = text;
+        var lines = text.split('\n');
+        var logEl = document.getElementById('log');
+        lines.forEach(function (line) {
+          var spanEl = document.createElement('span');
+          spanEl.textContent = line;
+          if (line.indexOf('>>>', 0) === 0) {
+            spanEl.classList.add('highlight');
+          } else if (line.indexOf('Missing archives') !== -1) {
+            spanEl.classList.add('missing');
+          }
+          logEl.appendChild(spanEl);
+        });
       }
 
       loadJson('naclsdk_manifest2.json', display);
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 6ee299a..a6760e4 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -37,6 +37,11 @@
 use_v8_in_net = false  # TODO(brettw)!is_ios
 enable_built_in_dns = !is_ios
 
+declare_args() {

+  # Disables support for file URLs.  File URL support requires use of icu.

+  disable_file_support = false

+}

+
 enable_ftp_support = !is_ios
 
 config("net_config") {
@@ -44,6 +49,9 @@
   if (posix_avoid_mmap) {
     defines += [ "POSIX_AVOID_MMAP" ]
   }
+  if (disable_file_support) {
+    defines += [ "DISABLE_FILE_SUPPORT" ]
+  }
 }
 
 # Disables Windows warning about size to int truncations.
@@ -108,6 +116,19 @@
     }
   }
 
+  if (disable_file_support) {
+    sources -= [
+      "base/directory_lister.cc",
+      "base/directory_lister.h",
+      "url_request/url_request_file_dir_job.cc",
+      "url_request/url_request_file_dir_job.h",
+      "url_request/url_request_file_job.cc",
+      "url_request/url_request_file_job.h",
+      "url_request/file_protocol_handler.cc",
+      "url_request/file_protocol_handler.h",
+    ]
+  }
+
   if (!enable_ftp_support) {
     sources -= [
       "ftp/ftp_auth_cache.cc",
diff --git a/net/base/file_stream.cc b/net/base/file_stream.cc
index d96bebb..bf56a49 100644
--- a/net/base/file_stream.cc
+++ b/net/base/file_stream.cc
@@ -13,12 +13,6 @@
     : context_(new Context(task_runner)) {
 }
 
-FileStream::FileStream(base::PlatformFile file,
-                       int flags,
-                       const scoped_refptr<base::TaskRunner>& task_runner)
-    : context_(new Context(base::File(file), task_runner)) {
-}
-
 FileStream::FileStream(base::File file,
                        const scoped_refptr<base::TaskRunner>& task_runner)
     : context_(new Context(file.Pass(), task_runner)) {
diff --git a/net/base/file_stream.h b/net/base/file_stream.h
index 850c78f..57011b7 100644
--- a/net/base/file_stream.h
+++ b/net/base/file_stream.h
@@ -11,14 +11,13 @@
 #define NET_BASE_FILE_STREAM_H_
 
 #include "base/files/file.h"
-#include "base/platform_file.h"
-#include "base/task_runner.h"
 #include "net/base/completion_callback.h"
 #include "net/base/file_stream_whence.h"
 #include "net/base/net_export.h"
 
 namespace base {
 class FilePath;
+class TaskRunner;
 }
 
 namespace net {
@@ -31,20 +30,8 @@
   // Uses |task_runner| for asynchronous operations.
   explicit FileStream(const scoped_refptr<base::TaskRunner>& task_runner);
 
-  // Construct a FileStream with an existing file handle and opening flags.
-  // |file| is valid file handle.
-  // |flags| is a bitfield of base::PlatformFileFlags when the file handle was
-  // opened.
+  // Construct a FileStream with an existing valid |file|.
   // Uses |task_runner| for asynchronous operations.
-  // Note: the new FileStream object takes ownership of the PlatformFile and
-  // will close it on destruction.
-  // This constructor is deprecated.
-  // TODO(rvargas): remove all references to PlatformFile.
-  FileStream(base::PlatformFile file,
-             int flags,
-             const scoped_refptr<base::TaskRunner>& task_runner);
-
-  // Non-deprecated version of the previous constructor.
   FileStream(base::File file,
              const scoped_refptr<base::TaskRunner>& task_runner);
 
@@ -58,7 +45,7 @@
   //
   // Once the operation is done, |callback| will be run on the thread where
   // Open() was called, with the result code. open_flags is a bitfield of
-  // base::PlatformFileFlags.
+  // base::File::Flags.
   //
   // If the file stream is not closed manually, the underlying file will be
   // automatically closed when FileStream is destructed in an asynchronous
@@ -91,7 +78,7 @@
   // copied, 0 if at end-of-file, or an error code if the operation could
   // not be performed.
   //
-  // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null
+  // The file must be opened with FLAG_ASYNC, and a non-null
   // callback must be passed to this method. If the read could not
   // complete synchronously, then ERR_IO_PENDING is returned, and the
   // callback will be run on the thread where Read() was called, when the
@@ -114,7 +101,7 @@
   // bytes written, or an error code if the operation could not be
   // performed.
   //
-  // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null
+  // The file must be opened with FLAG_ASYNC, and a non-null
   // callback must be passed to this method. If the write could not
   // complete synchronously, then ERR_IO_PENDING is returned, and the
   // callback will be run on the thread where Write() was called when
@@ -138,7 +125,7 @@
   // not have to be called, it just forces one to happen at the time of
   // calling.
   //
-  // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null
+  // The file must be opened with FLAG_ASYNC, and a non-null
   // callback must be passed to this method. If the write could not
   // complete synchronously, then ERR_IO_PENDING is returned, and the
   // callback will be run on the thread where Flush() was called when
@@ -154,7 +141,7 @@
   // This method should not be called if the stream was opened READ_ONLY.
   virtual int Flush(const CompletionCallback& callback);
 
-  // Returns the underlying platform file for testing.
+  // Returns the underlying file for testing.
   const base::File& GetFileForTesting() const;
 
  private:
diff --git a/net/base/file_stream_context.cc b/net/base/file_stream_context.cc
index 13467ec..fbfe536 100644
--- a/net/base/file_stream_context.cc
+++ b/net/base/file_stream_context.cc
@@ -4,8 +4,10 @@
 
 #include "net/base/file_stream_context.h"
 
+#include "base/files/file_path.h"
 #include "base/location.h"
 #include "base/message_loop/message_loop_proxy.h"
+#include "base/task_runner.h"
 #include "base/task_runner_util.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
@@ -182,10 +184,10 @@
 
 void FileStream::Context::OnOpenCompleted(const CompletionCallback& callback,
                                           OpenResult open_result) {
-  if (open_result.file.IsValid() && !orphaned_) {
-    file_ = open_result.file.Pass();
+  file_ = open_result.file.Pass();
+  if (file_.IsValid() && !orphaned_)
     OnAsyncFileOpened();
-  }
+
   OnAsyncCompleted(IntToInt64(callback), open_result.error_code);
 }
 
diff --git a/net/base/file_stream_context_posix.cc b/net/base/file_stream_context_posix.cc
index ecf9285..9f3d060 100644
--- a/net/base/file_stream_context_posix.cc
+++ b/net/base/file_stream_context_posix.cc
@@ -22,6 +22,7 @@
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
 #include "base/posix/eintr_wrapper.h"
+#include "base/task_runner.h"
 #include "base/task_runner_util.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
diff --git a/net/base/file_stream_context_win.cc b/net/base/file_stream_context_win.cc
index 2477535..e906b6b 100644
--- a/net/base/file_stream_context_win.cc
+++ b/net/base/file_stream_context_win.cc
@@ -9,7 +9,7 @@
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
-#include "base/task_runner_util.h"
+#include "base/task_runner.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 
diff --git a/net/base/file_stream_unittest.cc b/net/base/file_stream_unittest.cc
index a5555d7..292b0d2 100644
--- a/net/base/file_stream_unittest.cc
+++ b/net/base/file_stream_unittest.cc
@@ -14,6 +14,8 @@
 #include "base/run_loop.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/test/test_timeouts.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "base/threading/thread_restrictions.h"
 #include "net/base/capturing_net_log.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
@@ -757,8 +759,11 @@
 }
 
 TEST_F(FileStreamTest, AsyncOpenAndDelete) {
-  scoped_ptr<FileStream> stream(
-      new FileStream(base::MessageLoopProxy::current()));
+  scoped_refptr<base::SequencedWorkerPool> pool(
+      new base::SequencedWorkerPool(1, "StreamTest"));
+
+  bool prev = base::ThreadRestrictions::SetIOAllowed(false);
+  scoped_ptr<FileStream> stream(new FileStream(pool.get()));
   int flags = base::File::FLAG_OPEN | base::File::FLAG_WRITE |
               base::File::FLAG_ASYNC;
   TestCompletionCallback open_callback;
@@ -768,9 +773,20 @@
   // Delete the stream without waiting for the open operation to be
   // complete. Should be safe.
   stream.reset();
+
+  // Force an operation through the pool.
+  scoped_ptr<FileStream> stream2(new FileStream(pool.get()));
+  TestCompletionCallback open_callback2;
+  rv = stream2->Open(temp_file_path(), flags, open_callback2.callback());
+  EXPECT_EQ(OK, open_callback2.GetResult(rv));
+  stream2.reset();
+
+  pool->Shutdown();
+
   // open_callback won't be called.
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(open_callback.have_result());
+  base::ThreadRestrictions::SetIOAllowed(prev);
 }
 
 // Verify that async Write() errors are mapped correctly.
diff --git a/net/base/filename_util.cc b/net/base/filename_util.cc
index ed4831d..ff8a071 100644
--- a/net/base/filename_util.cc
+++ b/net/base/filename_util.cc
@@ -72,7 +72,7 @@
 
   // The URL's path should be escaped UTF-8, but may not be.
   std::string decoded_filename = unescaped_url_filename;
-  if (!IsStringUTF8(decoded_filename)) {
+  if (!base::IsStringUTF8(decoded_filename)) {
     // TODO(jshin): this is probably not robust enough. To be sure, we need
     // encoding detection.
     base::string16 utf16_output;
@@ -180,12 +180,6 @@
   if ((ignore_extension || extension.empty()) && !mime_type.empty()) {
     base::FilePath::StringType preferred_mime_extension;
     std::vector<base::FilePath::StringType> all_mime_extensions;
-    // The GetPreferredExtensionForMimeType call will end up going to disk.  Do
-    // this on another thread to avoid slowing the IO thread.
-    // http://crbug.com/61827
-    // TODO(asanka): Remove this ScopedAllowIO once all callers have switched
-    // over to IO safe threads.
-    base::ThreadRestrictions::ScopedAllowIO allow_io;
     net::GetPreferredExtensionForMimeType(mime_type, &preferred_mime_extension);
     net::GetExtensionsForMimeType(mime_type, &all_mime_extensions);
     // If the existing extension is in the list of valid extensions for the
@@ -311,7 +305,7 @@
       UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);
 
 #if defined(OS_WIN)
-  if (IsStringUTF8(path)) {
+  if (base::IsStringUTF8(path)) {
     file_path_str.assign(base::UTF8ToWide(path));
     // We used to try too hard and see if |path| made up entirely of
     // the 1st 256 characters in the Unicode was a zero-extended UTF-16.
diff --git a/net/base/filename_util_unittest.cc b/net/base/filename_util_unittest.cc
index 701e772..0bd2250 100644
--- a/net/base/filename_util_unittest.cc
+++ b/net/base/filename_util_unittest.cc
@@ -511,7 +511,7 @@
     },
     { // Now that we use src/url's ExtractFileName, this case falls back to
       // the hostname. If this behavior is not desirable, we'd better change
-      // ExtractFileName (in url_parse).
+      // ExtractFileName (in url_parse.cc).
       __LINE__,
       "http://www.google.com/path/",
       "",
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc
index fdb16fd..b501273 100644
--- a/net/base/mime_util.cc
+++ b/net/base/mime_util.cc
@@ -158,6 +158,7 @@
   { "image/tiff", "tiff,tif" },
   { "image/x-xbitmap", "xbm" },
   { "image/svg+xml", "svg,svgz" },
+  { "image/x-png", "png"},
   { "message/rfc822", "eml" },
   { "text/plain", "txt,text" },
   { "text/html", "ehtml" },
@@ -260,7 +261,8 @@
   "image/bmp",
   "image/vnd.microsoft.icon",    // ico
   "image/x-icon",    // ico
-  "image/x-xbitmap"  // xbm
+  "image/x-xbitmap",  // xbm
+  "image/x-png"
 };
 
 // A list of media types: http://en.wikipedia.org/wiki/Internet_media_type
@@ -650,7 +652,7 @@
 bool MimeUtil::IsMimeType(const std::string& type_string) const {
   // MIME types are always ASCII and case-insensitive (at least, the top-level
   // and secondary types we care about).
-  if (!IsStringASCII(type_string))
+  if (!base::IsStringASCII(type_string))
     return false;
 
   if (type_string == "*/*" || type_string == "*")
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index 422f02f..5b3d65e 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -960,14 +960,14 @@
 }
 
 NetworkInterface::NetworkInterface()
-    : type(NETWORK_INTERFACE_UNKNOWN),
+    : type(NetworkChangeNotifier::CONNECTION_UNKNOWN),
       network_prefix(0) {
 }
 
 NetworkInterface::NetworkInterface(const std::string& name,
                                    const std::string& friendly_name,
                                    uint32 interface_index,
-                                   NetworkInterfaceType type,
+                                   NetworkChangeNotifier::ConnectionType type,
                                    const IPAddressNumber& address,
                                    size_t network_prefix)
     : name(name),
diff --git a/net/base/net_util.h b/net/base/net_util.h
index 5556f5e..d83744f 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -24,6 +24,7 @@
 #include "net/base/address_family.h"
 #include "net/base/escape.h"
 #include "net/base/net_export.h"
+#include "net/base/network_change_notifier.h"
 
 class GURL;
 
@@ -429,15 +430,6 @@
 // machine.
 NET_EXPORT_PRIVATE bool IsLocalhost(const std::string& host);
 
-// Category of network interface types.
-enum NetworkInterfaceType {
-  NETWORK_INTERFACE_UNKNOWN,
-  NETWORK_INTERFACE_ETHERNET,
-  NETWORK_INTERFACE_WIFI,
-  NETWORK_INTERFACE_CELLULAR,
-  NETWORK_INTERFACE_VPN
-};
-
 // struct that is used by GetNetworkList() to represent a network
 // interface.
 struct NET_EXPORT NetworkInterface {
@@ -445,7 +437,7 @@
   NetworkInterface(const std::string& name,
                    const std::string& friendly_name,
                    uint32 interface_index,
-                   NetworkInterfaceType type,
+                   NetworkChangeNotifier::ConnectionType type,
                    const IPAddressNumber& address,
                    size_t network_prefix);
   ~NetworkInterface();
@@ -453,7 +445,7 @@
   std::string name;
   std::string friendly_name;  // Same as |name| on non-Windows.
   uint32 interface_index;  // Always 0 on Android.
-  NetworkInterfaceType type;
+  NetworkChangeNotifier::ConnectionType type;
   IPAddressNumber address;
   size_t network_prefix;
 };
diff --git a/net/base/net_util_posix.cc b/net/base/net_util_posix.cc
index ec30c04..315e9ed 100644
--- a/net/base/net_util_posix.cc
+++ b/net/base/net_util_posix.cc
@@ -25,6 +25,7 @@
 #endif
 
 #if defined(OS_MACOSX) && !defined(OS_IOS)
+#include <net/if_media.h>
 #include <netinet/in_var.h>
 #include <sys/ioctl.h>
 #endif
@@ -83,6 +84,34 @@
 
 #endif
 
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+
+NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(
+    int addr_family, const std::string& interface_name) {
+  NetworkChangeNotifier::ConnectionType type =
+      NetworkChangeNotifier::CONNECTION_UNKNOWN;
+
+  struct ifmediareq ifmr = {};
+  strncpy(ifmr.ifm_name, interface_name.c_str(), sizeof(ifmr.ifm_name) - 1);
+
+  int s = socket(addr_family, SOCK_DGRAM, 0);
+  if (s == -1) {
+    return type;
+  }
+
+  if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1) {
+    if (ifmr.ifm_current & IFM_IEEE80211) {
+      type = NetworkChangeNotifier::CONNECTION_WIFI;
+    } else if (ifmr.ifm_current & IFM_ETHER) {
+      type = NetworkChangeNotifier::CONNECTION_ETHERNET;
+    }
+  }
+  close(s);
+  return type;
+}
+
+#endif
+
 }  // namespace
 
 bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
@@ -111,7 +140,8 @@
     CHECK(base::StringToUint(network_tokenizer.token(), &index));
 
     networks->push_back(
-        NetworkInterface(name, name, index, NETWORK_INTERFACE_UNKNOWN,
+        NetworkInterface(name, name, index,
+                         NetworkChangeNotifier::CONNECTION_UNKNOWN,
                          address, network_prefix));
   }
   return true;
@@ -182,6 +212,8 @@
     }
 
     NetworkInterfaceInfo network_info;
+    NetworkChangeNotifier::ConnectionType connection_type =
+        NetworkChangeNotifier::CONNECTION_UNKNOWN;
 #if defined(OS_MACOSX) && !defined(OS_IOS)
     // Check if this is a temporary address. Currently this is only supported
     // on Mac.
@@ -196,6 +228,8 @@
         network_info.permanent = !(ifr.ifr_ifru.ifru_flags & IN6_IFF_TEMPORARY);
       }
     }
+
+    connection_type = GetNetworkInterfaceType(addr->sa_family, name);
 #endif
 
     IPEndPoint address;
@@ -212,8 +246,8 @@
         }
       }
       network_info.interface = NetworkInterface(
-          name, name, if_nametoindex(name.c_str()), NETWORK_INTERFACE_UNKNOWN,
-          address.address(), net_mask);
+          name, name, if_nametoindex(name.c_str()),
+          connection_type, address.address(), net_mask);
 
       network_infos.push_back(NetworkInterfaceInfo(network_info));
     }
diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc
index 1bed2d8..ebc3307 100644
--- a/net/base/net_util_unittest.cc
+++ b/net/base/net_util_unittest.cc
@@ -1804,6 +1804,9 @@
       EXPECT_LT(it->interface_index, 1u << 24u);  // Must fit 0.x.x.x.
       EXPECT_NE(it->interface_index, 0u);  // 0 means to use default.
     }
+    if (it->type == NetworkChangeNotifier::CONNECTION_WIFI) {
+      EXPECT_NE(WIFI_PHY_LAYER_PROTOCOL_NONE, GetWifiPHYLayerProtocol());
+    }
 #elif !defined(OS_ANDROID)
     char name[IF_NAMESIZE];
     EXPECT_TRUE(if_indextoname(it->interface_index, name));
diff --git a/net/base/net_util_win.cc b/net/base/net_util_win.cc
index 16cd98e..c3d9f3b 100644
--- a/net/base/net_util_win.cc
+++ b/net/base/net_util_win.cc
@@ -24,6 +24,8 @@
 #include "net/base/net_errors.h"
 #include "url/gurl.h"
 
+namespace net {
+
 namespace {
 
 struct WlanApi {
@@ -81,9 +83,20 @@
   bool initialized;
 };
 
-}  // namespace
+// Converts Windows defined types to NetworkInterfaceType.
+NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) {
+  NetworkChangeNotifier::ConnectionType type =
+      NetworkChangeNotifier::CONNECTION_UNKNOWN;
+  if (ifType == IF_TYPE_ETHERNET_CSMACD) {
+    type = NetworkChangeNotifier::CONNECTION_ETHERNET;
+  } else if (ifType == IF_TYPE_IEEE80211) {
+    type = NetworkChangeNotifier::CONNECTION_WIFI;
+  }
+  // TODO(mallinath) - Cellular?
+  return type;
+}
 
-namespace net {
+}  // namespace
 
 bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
   // GetAdaptersAddresses() may require IO operations.
@@ -173,15 +186,17 @@
               ipv6_valid_lifetime = address->ValidLifetime;
               ipv6_address.reset(new NetworkInterface(adapter->AdapterName,
                                  base::SysWideToNativeMB(adapter->FriendlyName),
-                                 index, NETWORK_INTERFACE_UNKNOWN,
-                                 endpoint.address(), net_prefix));
+                                 index,
+                                 GetNetworkInterfaceType(adapter->IfType),
+                                 endpoint.address(),
+                                 net_prefix));
               continue;
             }
           }
           networks->push_back(
               NetworkInterface(adapter->AdapterName,
                                base::SysWideToNativeMB(adapter->FriendlyName),
-                               index, NETWORK_INTERFACE_UNKNOWN,
+                               index, GetNetworkInterfaceType(adapter->IfType),
                                endpoint.address(), net_prefix));
         }
       }
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc
index 638964a..11f9d36 100644
--- a/net/base/network_change_notifier.cc
+++ b/net/base/network_change_notifier.cc
@@ -14,6 +14,12 @@
 #include "net/url_request/url_request.h"
 #include "url/gurl.h"
 
+#if defined(OS_ANDROID)
+#include "base/metrics/sparse_histogram.h"
+#include "base/strings/string_number_conversions.h"
+#include "net/android/network_library.h"
+#endif
+
 #if defined(OS_WIN)
 #include "net/base/network_change_notifier_win.h"
 #elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
@@ -228,6 +234,24 @@
     } else {
       UMA_HISTOGRAM_MEDIUM_TIMES("NCN.OfflineChange", state_duration);
     }
+
+#if defined(OS_ANDROID)
+    // On a connection type change to 2/3/4G, log the network operator MCC/MNC.
+    // Log zero in other cases.
+    unsigned mcc_mnc = 0;
+    if (type == NetworkChangeNotifier::CONNECTION_2G ||
+        type == NetworkChangeNotifier::CONNECTION_3G ||
+        type == NetworkChangeNotifier::CONNECTION_4G) {
+      // Log zero if not perfectly converted.
+      if (!base::StringToUint(
+          net::android::GetTelephonyNetworkOperator(), &mcc_mnc)) {
+        mcc_mnc = 0;
+      }
+    }
+    UMA_HISTOGRAM_SPARSE_SLOWLY(
+        "NCN.NetworkOperatorMCCMNC_ConnectionChange", mcc_mnc);
+#endif
+
     UMA_HISTOGRAM_MEDIUM_TIMES(
         "NCN.IPAddressChangeToConnectionTypeChange",
         now - last_ip_address_change_);
diff --git a/net/base/registry_controlled_domains/effective_tld_names.cc b/net/base/registry_controlled_domains/effective_tld_names.cc
index 441d606..167682b 100644
--- a/net/base/registry_controlled_domains/effective_tld_names.cc
+++ b/net/base/registry_controlled_domains/effective_tld_names.cc
@@ -42,12 +42,12 @@
   int type;  // flags: 1: exception, 2: wildcard, 4: private
 };
 
-#define TOTAL_KEYWORDS 6522
+#define TOTAL_KEYWORDS 6566
 #define MIN_WORD_LENGTH 2
 #define MAX_WORD_LENGTH 43
-#define MIN_HASH_VALUE 18
-#define MAX_HASH_VALUE 223338
-/* maximum key range = 223321, duplicates = 0 */
+#define MIN_HASH_VALUE 10
+#define MAX_HASH_VALUE 198331
+/* maximum key range = 198322, duplicates = 0 */
 
 class Perfect_Hash
 {
@@ -62,35 +62,35 @@
 {
   static const unsigned int asso_values[] =
     {
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339,   2144,    308,    515,     20,  33566,
-           2,      5,      2,     11,      5,      2,      2,      2,      2,    191,
-        5644,      5,  57548,      2,    107,      5,      2,      2,      2,      2,
-           2, 223339, 223339,     14,     50,     20,     47,     44,     41,     17,
-          32,     29,     26, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339,    641,   2345,  11152,
-          35,     11,  53921,  17246,   3698,   1892,    128,   2558,   2951,   1529,
-        1979,     92,    170,   3263,    929,    113,    875,   1157,   7577,   4472,
-       13832,   4055,   1313,      5,      2,  15359,    227,  46949,     11,   2039,
-          23,    311,      8,    730,  33626,     38,      1,  37090,   4004,  17663,
-       47324,  21097,   6116,  10481,   6233,     80,   9398,    128, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339, 223339,
-      223339
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332,    334,    111,      3,    257,   8209,
+           2,      5,      7,      3,      2,      6,      3,      2,      2,     39,
+       43951,      3,  19098,      2,      4,      4,      3,      2,      2,      2,
+           2, 198332, 198332,      6,     18,      8,     16,     15,     14,      7,
+          13,     12,     10, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332,    195,    669,  24515,
+          18,      5,  26367,   4694,   1637,    593,    414,   1597,   1016,    447,
+         810,     30,     44,    908,    261,     10,    225,    327,   1053,   2031,
+        4217,   2980,    342,      3,      2,    720,     64,  15313,      5,   1476,
+           9,     82,      4,  31721,   8176,     11,  24421,  51919,   3250,   3990,
+       13982,  46526,   6247,   9761,   3320,    122,   2782,    129, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332, 198332,
+      198332
     };
   register int hval = len;
 
@@ -234,6566 +234,6614 @@
     char stringpool_str0[sizeof("be")];
     char stringpool_str1[sizeof("ke")];
     char stringpool_str2[sizeof("ge")];
-    char stringpool_str3[sizeof("ie")];
-    char stringpool_str4[sizeof("cd")];
-    char stringpool_str5[sizeof("bd")];
-    char stringpool_str6[sizeof("gd")];
-    char stringpool_str7[sizeof("ne")];
-    char stringpool_str8[sizeof("id")];
-    char stringpool_str9[sizeof("net")];
-    char stringpool_str10[sizeof("co")];
-    char stringpool_str11[sizeof("bo")];
-    char stringpool_str12[sizeof("com")];
-    char stringpool_str13[sizeof("gov")];
-    char stringpool_str14[sizeof("io")];
-    char stringpool_str15[sizeof("bs")];
-    char stringpool_str16[sizeof("gs")];
-    char stringpool_str17[sizeof("no")];
-    char stringpool_str18[sizeof("bj")];
-    char stringpool_str19[sizeof("is")];
-    char stringpool_str20[sizeof("kp")];
-    char stringpool_str21[sizeof("gp")];
-    char stringpool_str22[sizeof("net.sl")];
-    char stringpool_str23[sizeof("net.st")];
-    char stringpool_str24[sizeof("net.ec")];
-    char stringpool_str25[sizeof("np")];
-    char stringpool_str26[sizeof("com.sl")];
+    char stringpool_str3[sizeof("bs")];
+    char stringpool_str4[sizeof("ie")];
+    char stringpool_str5[sizeof("gs")];
+    char stringpool_str6[sizeof("ne")];
+    char stringpool_str7[sizeof("is")];
+    char stringpool_str8[sizeof("cd")];
+    char stringpool_str9[sizeof("bd")];
+    char stringpool_str10[sizeof("gd")];
+    char stringpool_str11[sizeof("net")];
+    char stringpool_str12[sizeof("id")];
+    char stringpool_str13[sizeof("co")];
+    char stringpool_str14[sizeof("bo")];
+    char stringpool_str15[sizeof("com")];
+    char stringpool_str16[sizeof("io")];
+    char stringpool_str17[sizeof("gov")];
+    char stringpool_str18[sizeof("no")];
+    char stringpool_str19[sizeof("net.sl")];
+    char stringpool_str20[sizeof("net.st")];
+    char stringpool_str21[sizeof("net.ec")];
+    char stringpool_str22[sizeof("kp")];
+    char stringpool_str23[sizeof("gp")];
+    char stringpool_str24[sizeof("net.sc")];
+    char stringpool_str25[sizeof("com.sl")];
+    char stringpool_str26[sizeof("np")];
     char stringpool_str27[sizeof("com.st")];
     char stringpool_str28[sizeof("com.ec")];
-    char stringpool_str29[sizeof("gov.sx")];
-    char stringpool_str30[sizeof("gov.sl")];
-    char stringpool_str31[sizeof("ee")];
-    char stringpool_str32[sizeof("gov.st")];
-    char stringpool_str33[sizeof("gov.ec")];
-    char stringpool_str34[sizeof("net.pl")];
-    char stringpool_str35[sizeof("net.pk")];
-    char stringpool_str36[sizeof("net.pt")];
-    char stringpool_str37[sizeof("net.pr")];
-    char stringpool_str38[sizeof("com.pl")];
-    char stringpool_str39[sizeof("com.pk")];
-    char stringpool_str40[sizeof("com.pt")];
-    char stringpool_str41[sizeof("gon.pk")];
-    char stringpool_str42[sizeof("gov.pl")];
-    char stringpool_str43[sizeof("gov.pk")];
-    char stringpool_str44[sizeof("gov.pt")];
-    char stringpool_str45[sizeof("com.pr")];
-    char stringpool_str46[sizeof("net.sc")];
-    char stringpool_str47[sizeof("gsm.pl")];
-    char stringpool_str48[sizeof("gov.pr")];
-    char stringpool_str49[sizeof("nom.pl")];
-    char stringpool_str50[sizeof("gda.pl")];
-    char stringpool_str51[sizeof("je")];
-    char stringpool_str52[sizeof("gop")];
-    char stringpool_str53[sizeof("com.sc")];
-    char stringpool_str54[sizeof("gent")];
-    char stringpool_str55[sizeof("es")];
-    char stringpool_str56[sizeof("gov.sc")];
-    char stringpool_str57[sizeof("center")];
-    char stringpool_str58[sizeof("jo")];
-    char stringpool_str59[sizeof("gob.ec")];
+    char stringpool_str29[sizeof("gov.sl")];
+    char stringpool_str30[sizeof("gov.st")];
+    char stringpool_str31[sizeof("gov.ec")];
+    char stringpool_str32[sizeof("com.sc")];
+    char stringpool_str33[sizeof("gov.sc")];
+    char stringpool_str34[sizeof("ee")];
+    char stringpool_str35[sizeof("gsm.pl")];
+    char stringpool_str36[sizeof("es")];
+    char stringpool_str37[sizeof("net.pl")];
+    char stringpool_str38[sizeof("net.pk")];
+    char stringpool_str39[sizeof("net.pt")];
+    char stringpool_str40[sizeof("net.pr")];
+    char stringpool_str41[sizeof("je")];
+    char stringpool_str42[sizeof("com.pl")];
+    char stringpool_str43[sizeof("com.pk")];
+    char stringpool_str44[sizeof("com.pt")];
+    char stringpool_str45[sizeof("gon.pk")];
+    char stringpool_str46[sizeof("gov.pl")];
+    char stringpool_str47[sizeof("gov.pk")];
+    char stringpool_str48[sizeof("gov.pt")];
+    char stringpool_str49[sizeof("com.pr")];
+    char stringpool_str50[sizeof("gent")];
+    char stringpool_str51[sizeof("nom.pl")];
+    char stringpool_str52[sizeof("gov.pr")];
+    char stringpool_str53[sizeof("gop")];
+    char stringpool_str54[sizeof("gob.ec")];
+    char stringpool_str55[sizeof("gda.pl")];
+    char stringpool_str56[sizeof("center")];
+    char stringpool_str57[sizeof("jo")];
+    char stringpool_str58[sizeof("com.sn")];
+    char stringpool_str59[sizeof("jp")];
     char stringpool_str60[sizeof("com.es")];
-    char stringpool_str61[sizeof("com.sn")];
-    char stringpool_str62[sizeof("gob.pk")];
-    char stringpool_str63[sizeof("nom.es")];
-    char stringpool_str64[sizeof("net.pn")];
-    char stringpool_str65[sizeof("jp")];
-    char stringpool_str66[sizeof("gop.pk")];
-    char stringpool_str67[sizeof("gov.pn")];
-    char stringpool_str68[sizeof("net.ps")];
-    char stringpool_str69[sizeof("est.pr")];
-    char stringpool_str70[sizeof("edu")];
+    char stringpool_str61[sizeof("gob.pk")];
+    char stringpool_str62[sizeof("nom.es")];
+    char stringpool_str63[sizeof("net.pn")];
+    char stringpool_str64[sizeof("est.pr")];
+    char stringpool_str65[sizeof("gop.pk")];
+    char stringpool_str66[sizeof("gov.pn")];
+    char stringpool_str67[sizeof("net.ps")];
+    char stringpool_str68[sizeof("condos")];
+    char stringpool_str69[sizeof("edu")];
+    char stringpool_str70[sizeof("jobs")];
     char stringpool_str71[sizeof("com.ps")];
-    char stringpool_str72[sizeof("jobs")];
-    char stringpool_str73[sizeof("gov.ps")];
-    char stringpool_str74[sizeof("gob.es")];
-    char stringpool_str75[sizeof("condos")];
-    char stringpool_str76[sizeof("ca")];
-    char stringpool_str77[sizeof("ba")];
-    char stringpool_str78[sizeof("ga")];
-    char stringpool_str79[sizeof("bar")];
-    char stringpool_str80[sizeof("cat")];
-    char stringpool_str81[sizeof("na")];
-    char stringpool_str82[sizeof("edu.sl")];
-    char stringpool_str83[sizeof("edu.st")];
-    char stringpool_str84[sizeof("edu.ec")];
-    char stringpool_str85[sizeof("net.al")];
-    char stringpool_str86[sizeof("net.ar")];
-    char stringpool_str87[sizeof("com.al")];
-    char stringpool_str88[sizeof("edu.pl")];
-    char stringpool_str89[sizeof("edu.pk")];
-    char stringpool_str90[sizeof("edu.pt")];
-    char stringpool_str91[sizeof("gov.al")];
-    char stringpool_str92[sizeof("za")];
-    char stringpool_str93[sizeof("com.ar")];
-    char stringpool_str94[sizeof("edu.pr")];
-    char stringpool_str95[sizeof("new")];
-    char stringpool_str96[sizeof("com.aw")];
-    char stringpool_str97[sizeof("edu.sc")];
-    char stringpool_str98[sizeof("cab")];
-    char stringpool_str99[sizeof("net.ac")];
-    char stringpool_str100[sizeof("ls")];
-    char stringpool_str101[sizeof("com.ac")];
+    char stringpool_str72[sizeof("gov.ps")];
+    char stringpool_str73[sizeof("gob.es")];
+    char stringpool_str74[sizeof("edu.sl")];
+    char stringpool_str75[sizeof("edu.st")];
+    char stringpool_str76[sizeof("edu.ec")];
+    char stringpool_str77[sizeof("edu.sc")];
+    char stringpool_str78[sizeof("ca")];
+    char stringpool_str79[sizeof("ba")];
+    char stringpool_str80[sizeof("ga")];
+    char stringpool_str81[sizeof("bar")];
+    char stringpool_str82[sizeof("na")];
+    char stringpool_str83[sizeof("cat")];
+    char stringpool_str84[sizeof("edu.pl")];
+    char stringpool_str85[sizeof("edu.pk")];
+    char stringpool_str86[sizeof("edu.pt")];
+    char stringpool_str87[sizeof("edu.pr")];
+    char stringpool_str88[sizeof("cards")];
+    char stringpool_str89[sizeof("bt")];
+    char stringpool_str90[sizeof("net.al")];
+    char stringpool_str91[sizeof("gt")];
+    char stringpool_str92[sizeof("it")];
+    char stringpool_str93[sizeof("net.ar")];
+    char stringpool_str94[sizeof("net.ac")];
+    char stringpool_str95[sizeof("com.al")];
+    char stringpool_str96[sizeof("cab")];
+    char stringpool_str97[sizeof("gov.al")];
+    char stringpool_str98[sizeof("edu.sn")];
+    char stringpool_str99[sizeof("com.ar")];
+    char stringpool_str100[sizeof("com.ac")];
+    char stringpool_str101[sizeof("com.aw")];
     char stringpool_str102[sizeof("gov.ac")];
-    char stringpool_str103[sizeof("bt")];
-    char stringpool_str104[sizeof("cards")];
-    char stringpool_str105[sizeof("gt")];
-    char stringpool_str106[sizeof("eat")];
-    char stringpool_str107[sizeof("it")];
-    char stringpool_str108[sizeof("edu.es")];
-    char stringpool_str109[sizeof("edu.sn")];
-    char stringpool_str110[sizeof("cr")];
-    char stringpool_str111[sizeof("br")];
-    char stringpool_str112[sizeof("kr")];
-    char stringpool_str113[sizeof("gr")];
-    char stringpool_str114[sizeof("gob.ar")];
-    char stringpool_str115[sizeof("net.an")];
-    char stringpool_str116[sizeof("ir")];
-    char stringpool_str117[sizeof("net.tt")];
-    char stringpool_str118[sizeof("nr")];
-    char stringpool_str119[sizeof("com.an")];
+    char stringpool_str103[sizeof("edu.es")];
+    char stringpool_str104[sizeof("net.tt")];
+    char stringpool_str105[sizeof("cr")];
+    char stringpool_str106[sizeof("br")];
+    char stringpool_str107[sizeof("kr")];
+    char stringpool_str108[sizeof("gr")];
+    char stringpool_str109[sizeof("net.sd")];
+    char stringpool_str110[sizeof("net.tw")];
+    char stringpool_str111[sizeof("eat")];
+    char stringpool_str112[sizeof("ir")];
+    char stringpool_str113[sizeof("com.tt")];
+    char stringpool_str114[sizeof("nr")];
+    char stringpool_str115[sizeof("gov.tl")];
+    char stringpool_str116[sizeof("idv.tw")];
+    char stringpool_str117[sizeof("gov.tt")];
+    char stringpool_str118[sizeof("com.sd")];
+    char stringpool_str119[sizeof("com.tw")];
     char stringpool_str120[sizeof("edu.pn")];
-    char stringpool_str121[sizeof("idv.tw")];
-    char stringpool_str122[sizeof("com.tt")];
-    char stringpool_str123[sizeof("net.tw")];
-    char stringpool_str124[sizeof("gov.tl")];
-    char stringpool_str125[sizeof("gov.tt")];
-    char stringpool_str126[sizeof("com.tw")];
-    char stringpool_str127[sizeof("gov.tw")];
-    char stringpool_str128[sizeof("net.rw")];
-    char stringpool_str129[sizeof("edu.ps")];
-    char stringpool_str130[sizeof("net.sd")];
-    char stringpool_str131[sizeof("gov.as")];
+    char stringpool_str121[sizeof("gov.sd")];
+    char stringpool_str122[sizeof("gov.tw")];
+    char stringpool_str123[sizeof("kred")];
+    char stringpool_str124[sizeof("et")];
+    char stringpool_str125[sizeof("gob.ar")];
+    char stringpool_str126[sizeof("net.an")];
+    char stringpool_str127[sizeof("edu.ps")];
+    char stringpool_str128[sizeof("com.an")];
+    char stringpool_str129[sizeof("net.sb")];
+    char stringpool_str130[sizeof("net.rw")];
+    char stringpool_str131[sizeof("com.sb")];
     char stringpool_str132[sizeof("com.rw")];
-    char stringpool_str133[sizeof("gov.rw")];
-    char stringpool_str134[sizeof("com.sd")];
-    char stringpool_str135[sizeof("zone")];
-    char stringpool_str136[sizeof("et")];
-    char stringpool_str137[sizeof("gov.sd")];
-    char stringpool_str138[sizeof("net.sb")];
-    char stringpool_str139[sizeof("com.sb")];
-    char stringpool_str140[sizeof("er")];
-    char stringpool_str141[sizeof("cu")];
-    char stringpool_str142[sizeof("gov.sb")];
-    char stringpool_str143[sizeof("kred")];
-    char stringpool_str144[sizeof("gu")];
-    char stringpool_str145[sizeof("net.tn")];
-    char stringpool_str146[sizeof("guru")];
-    char stringpool_str147[sizeof("nu")];
-    char stringpool_str148[sizeof("com.tn")];
-    char stringpool_str149[sizeof("gov.tn")];
-    char stringpool_str150[sizeof("edu.al")];
-    char stringpool_str151[sizeof("edu.ar")];
-    char stringpool_str152[sizeof("london")];
-    char stringpool_str153[sizeof("com.ee")];
-    char stringpool_str154[sizeof("gov.ee")];
-    char stringpool_str155[sizeof("com.de")];
-    char stringpool_str156[sizeof("cz")];
-    char stringpool_str157[sizeof("bz")];
-    char stringpool_str158[sizeof("kz")];
-    char stringpool_str159[sizeof("ae")];
-    char stringpool_str160[sizeof("edu.ac")];
-    char stringpool_str161[sizeof("ad")];
-    char stringpool_str162[sizeof("nz")];
-    char stringpool_str163[sizeof("gov.rs")];
-    char stringpool_str164[sizeof("net.je")];
-    char stringpool_str165[sizeof("la")];
-    char stringpool_str166[sizeof("eu")];
-    char stringpool_str167[sizeof("cpa.pro")];
-    char stringpool_str168[sizeof("ao")];
-    char stringpool_str169[sizeof("net.pe")];
-    char stringpool_str170[sizeof("as")];
-    char stringpool_str171[sizeof("com.pe")];
-    char stringpool_str172[sizeof("edu.an")];
-    char stringpool_str173[sizeof("net.au")];
-    char stringpool_str174[sizeof("edu.tt")];
-    char stringpool_str175[sizeof("nom.pe")];
-    char stringpool_str176[sizeof("com.au")];
-    char stringpool_str177[sizeof("land")];
-    char stringpool_str178[sizeof("gov.au")];
-    char stringpool_str179[sizeof("edu.tw")];
-    char stringpool_str180[sizeof("jet.uk")];
-    char stringpool_str181[sizeof("om")];
-    char stringpool_str182[sizeof("cm")];
-    char stringpool_str183[sizeof("bm")];
-    char stringpool_str184[sizeof("km")];
-    char stringpool_str185[sizeof("gm")];
-    char stringpool_str186[sizeof("edu.rw")];
-    char stringpool_str187[sizeof("im")];
-    char stringpool_str188[sizeof("name")];
-    char stringpool_str189[sizeof("aero")];
-    char stringpool_str190[sizeof("career")];
-    char stringpool_str191[sizeof("edu.sd")];
-    char stringpool_str192[sizeof("lt")];
-    char stringpool_str193[sizeof("gob.pe")];
-    char stringpool_str194[sizeof("net.mx")];
-    char stringpool_str195[sizeof("net.ml")];
-    char stringpool_str196[sizeof("net.mk")];
-    char stringpool_str197[sizeof("net.mt")];
-    char stringpool_str198[sizeof("edu.sb")];
-    char stringpool_str199[sizeof("nsn.us")];
-    char stringpool_str200[sizeof("gouv.km")];
-    char stringpool_str201[sizeof("com.mx")];
-    char stringpool_str202[sizeof("com.ml")];
-    char stringpool_str203[sizeof("com.mk")];
-    char stringpool_str204[sizeof("com.mt")];
-    char stringpool_str205[sizeof("net.mw")];
-    char stringpool_str206[sizeof("gov.ml")];
-    char stringpool_str207[sizeof("gov.mk")];
-    char stringpool_str208[sizeof("zm")];
-    char stringpool_str209[sizeof("lr")];
-    char stringpool_str210[sizeof("nom.ad")];
-    char stringpool_str211[sizeof("gov.mr")];
-    char stringpool_str212[sizeof("com.mw")];
-    char stringpool_str213[sizeof("gov.mw")];
-    char stringpool_str214[sizeof("nrw")];
-    char stringpool_str215[sizeof("isa.us")];
-    char stringpool_str216[sizeof("net.ru")];
-    char stringpool_str217[sizeof("edu.ee")];
-    char stringpool_str218[sizeof("com.ru")];
-    char stringpool_str219[sizeof("gov.ru")];
-    char stringpool_str220[sizeof("bar.pro")];
-    char stringpool_str221[sizeof("c.la")];
-    char stringpool_str222[sizeof("nov.ru")];
-    char stringpool_str223[sizeof("gob.mx")];
-    char stringpool_str224[sizeof("nat.tn")];
-    char stringpool_str225[sizeof("edu.rs")];
-    char stringpool_str226[sizeof("jm")];
-    char stringpool_str227[sizeof("krd")];
-    char stringpool_str228[sizeof("gov.mn")];
-    char stringpool_str229[sizeof("net.ae")];
-    char stringpool_str230[sizeof("lu")];
-    char stringpool_str231[sizeof("ci")];
-    char stringpool_str232[sizeof("bi")];
-    char stringpool_str233[sizeof("biz")];
-    char stringpool_str234[sizeof("ki")];
-    char stringpool_str235[sizeof("gi")];
-    char stringpool_str236[sizeof("kim")];
-    char stringpool_str237[sizeof("edu.pe")];
-    char stringpool_str238[sizeof("gov.ae")];
-    char stringpool_str239[sizeof("net.ms")];
-    char stringpool_str240[sizeof("ni")];
-    char stringpool_str241[sizeof("com.ms")];
-    char stringpool_str242[sizeof("edu.au")];
-    char stringpool_str243[sizeof("gov.ms")];
-    char stringpool_str244[sizeof("gal")];
-    char stringpool_str245[sizeof("cn")];
-    char stringpool_str246[sizeof("bn")];
-    char stringpool_str247[sizeof("kn")];
-    char stringpool_str248[sizeof("gn")];
-    char stringpool_str249[sizeof("net.ir")];
-    char stringpool_str250[sizeof("in")];
-    char stringpool_str251[sizeof("gallery")];
-    char stringpool_str252[sizeof("codes")];
-    char stringpool_str253[sizeof("lapy.pl")];
-    char stringpool_str254[sizeof("gov.it")];
-    char stringpool_str255[sizeof("int")];
-    char stringpool_str256[sizeof("gov.ir")];
-    char stringpool_str257[sizeof("krym.ua")];
-    char stringpool_str258[sizeof("biz.pl")];
-    char stringpool_str259[sizeof("biz.pk")];
-    char stringpool_str260[sizeof("net.nr")];
-    char stringpool_str261[sizeof("org")];
-    char stringpool_str262[sizeof("biz.pr")];
-    char stringpool_str263[sizeof("com.nr")];
-    char stringpool_str264[sizeof("edu.mx")];
-    char stringpool_str265[sizeof("edu.ml")];
-    char stringpool_str266[sizeof("edu.mk")];
-    char stringpool_str267[sizeof("edu.mt")];
-    char stringpool_str268[sizeof("gov.nr")];
-    char stringpool_str269[sizeof("name.na")];
-    char stringpool_str270[sizeof("edu.mw")];
-    char stringpool_str271[sizeof("gen.in")];
-    char stringpool_str272[sizeof("berlin")];
-    char stringpool_str273[sizeof("beer")];
-    char stringpool_str274[sizeof("horse")];
-    char stringpool_str275[sizeof("at")];
-    char stringpool_str276[sizeof("com.re")];
-    char stringpool_str277[sizeof("net.in")];
-    char stringpool_str278[sizeof("org.sl")];
-    char stringpool_str279[sizeof("int.pt")];
-    char stringpool_str280[sizeof("org.st")];
-    char stringpool_str281[sizeof("org.ec")];
-    char stringpool_str282[sizeof("name.ng")];
-    char stringpool_str283[sizeof("nom.re")];
-    char stringpool_str284[sizeof("gov.in")];
-    char stringpool_str285[sizeof("edu.ru")];
-    char stringpool_str286[sizeof("ar")];
-    char stringpool_str287[sizeof("nsw.au")];
-    char stringpool_str288[sizeof("org.pl")];
-    char stringpool_str289[sizeof("net.tj")];
-    char stringpool_str290[sizeof("org.pk")];
-    char stringpool_str291[sizeof("org.pt")];
-    char stringpool_str292[sizeof("net.is")];
-    char stringpool_str293[sizeof("org.pr")];
-    char stringpool_str294[sizeof("com.tj")];
-    char stringpool_str295[sizeof("gov.tj")];
-    char stringpool_str296[sizeof("com.is")];
-    char stringpool_str297[sizeof("org.sc")];
-    char stringpool_str298[sizeof("gov.is")];
-    char stringpool_str299[sizeof("gos.pk")];
-    char stringpool_str300[sizeof("edu.mn")];
-    char stringpool_str301[sizeof("net.mu")];
-    char stringpool_str302[sizeof("bb")];
-    char stringpool_str303[sizeof("gb")];
-    char stringpool_str304[sizeof("kaufen")];
-    char stringpool_str305[sizeof("com.mu")];
-    char stringpool_str306[sizeof("best")];
-    char stringpool_str307[sizeof("atm.pl")];
-    char stringpool_str308[sizeof("gov.mu")];
-    char stringpool_str309[sizeof("org.es")];
-    char stringpool_str310[sizeof("edu.ms")];
-    char stringpool_str311[sizeof("net.bt")];
-    char stringpool_str312[sizeof("org.sn")];
-    char stringpool_str313[sizeof("art.pl")];
-    char stringpool_str314[sizeof("net.br")];
-    char stringpool_str315[sizeof("com.bt")];
-    char stringpool_str316[sizeof("au")];
-    char stringpool_str317[sizeof("gov.bt")];
-    char stringpool_str318[sizeof("com.br")];
-    char stringpool_str319[sizeof("house")];
-    char stringpool_str320[sizeof("edu.it")];
-    char stringpool_str321[sizeof("gov.br")];
-    char stringpool_str322[sizeof("org.pn")];
-    char stringpool_str323[sizeof("nom.br")];
-    char stringpool_str324[sizeof("b.br")];
-    char stringpool_str325[sizeof("not.br")];
-    char stringpool_str326[sizeof("nel.uk")];
-    char stringpool_str327[sizeof("biz.at")];
-    char stringpool_str328[sizeof("cam.it")];
-    char stringpool_str329[sizeof("ck")];
-    char stringpool_str330[sizeof("estate")];
-    char stringpool_str331[sizeof("org.ps")];
-    char stringpool_str332[sizeof("edu.nr")];
-    char stringpool_str333[sizeof("nara.jp")];
-    char stringpool_str334[sizeof("odda.no")];
-    char stringpool_str335[sizeof("jur.pro")];
-    char stringpool_str336[sizeof("art.sn")];
-    char stringpool_str337[sizeof("li")];
-    char stringpool_str338[sizeof("az")];
-    char stringpool_str339[sizeof("jar.ru")];
-    char stringpool_str340[sizeof("arpa")];
-    char stringpool_str341[sizeof("com.kp")];
-    char stringpool_str342[sizeof("gov.kp")];
-    char stringpool_str343[sizeof("int.ar")];
-    char stringpool_str344[sizeof("edu.in")];
-    char stringpool_str345[sizeof("bayern")];
-    char stringpool_str346[sizeof("bodo.no")];
-    char stringpool_str347[sizeof("lom.it")];
-    char stringpool_str348[sizeof("net.bs")];
-    char stringpool_str349[sizeof("org.al")];
-    char stringpool_str350[sizeof("org.ar")];
-    char stringpool_str351[sizeof("com.bs")];
-    char stringpool_str352[sizeof("net.me")];
-    char stringpool_str353[sizeof("edu.tj")];
-    char stringpool_str354[sizeof("gov.bs")];
-    char stringpool_str355[sizeof("edu.is")];
-    char stringpool_str356[sizeof("biz.tt")];
-    char stringpool_str357[sizeof("jor.br")];
-    char stringpool_str358[sizeof("gouv.rw")];
-    char stringpool_str359[sizeof("komforb.se")];
-    char stringpool_str360[sizeof("consulado.st")];
-    char stringpool_str361[sizeof("gov.me")];
-    char stringpool_str362[sizeof("asn.au")];
-    char stringpool_str363[sizeof("bid")];
-    char stringpool_str364[sizeof("autos")];
-    char stringpool_str365[sizeof("am")];
-    char stringpool_str366[sizeof("net.id")];
-    char stringpool_str367[sizeof("org.ac")];
-    char stringpool_str368[sizeof("casa")];
-    char stringpool_str369[sizeof("limo")];
-    char stringpool_str370[sizeof("how")];
-    char stringpool_str371[sizeof("net.kn")];
-    char stringpool_str372[sizeof("kobe.jp")];
-    char stringpool_str373[sizeof("gov.kn")];
-    char stringpool_str374[sizeof("ht")];
-    char stringpool_str375[sizeof("int.tt")];
-    char stringpool_str376[sizeof("cremona.it")];
-    char stringpool_str377[sizeof("edu.bt")];
-    char stringpool_str378[sizeof("here")];
-    char stringpool_str379[sizeof("esp.br")];
-    char stringpool_str380[sizeof("edu.br")];
-    char stringpool_str381[sizeof("cl")];
-    char stringpool_str382[sizeof("gl")];
-    char stringpool_str383[sizeof("org.an")];
-    char stringpool_str384[sizeof("hr")];
-    char stringpool_str385[sizeof("il")];
-    char stringpool_str386[sizeof("org.tt")];
-    char stringpool_str387[sizeof("nl")];
-    char stringpool_str388[sizeof("int.rw")];
-    char stringpool_str389[sizeof("org.tw")];
-    char stringpool_str390[sizeof("haus")];
-    char stringpool_str391[sizeof("net.lk")];
-    char stringpool_str392[sizeof("name.pr")];
-    char stringpool_str393[sizeof("net.lr")];
-    char stringpool_str394[sizeof("com.lk")];
-    char stringpool_str395[sizeof("lb")];
-    char stringpool_str396[sizeof("gov.lk")];
-    char stringpool_str397[sizeof("gov.lt")];
-    char stringpool_str398[sizeof("com.lr")];
-    char stringpool_str399[sizeof("org.sd")];
-    char stringpool_str400[sizeof("gift")];
-    char stringpool_str401[sizeof("gov.lr")];
-    char stringpool_str402[sizeof("isla.pr")];
-    char stringpool_str403[sizeof("info")];
-    char stringpool_str404[sizeof("oslo.no")];
-    char stringpool_str405[sizeof("homes")];
-    char stringpool_str406[sizeof("auto.pl")];
-    char stringpool_str407[sizeof("org.sb")];
-    char stringpool_str408[sizeof("net.lc")];
-    char stringpool_str409[sizeof("edu.kp")];
-    char stringpool_str410[sizeof("name.eg")];
-    char stringpool_str411[sizeof("ing")];
-    char stringpool_str412[sizeof("game.tw")];
-    char stringpool_str413[sizeof("gov.ie")];
-    char stringpool_str414[sizeof("com.lc")];
-    char stringpool_str415[sizeof("gov.lc")];
-    char stringpool_str416[sizeof("glass")];
-    char stringpool_str417[sizeof("hu")];
-    char stringpool_str418[sizeof("org.tn")];
-    char stringpool_str419[sizeof("ai")];
-    char stringpool_str420[sizeof("o.se")];
-    char stringpool_str421[sizeof("c.se")];
-    char stringpool_str422[sizeof("b.se")];
-    char stringpool_str423[sizeof("k.se")];
-    char stringpool_str424[sizeof("law.pro")];
-    char stringpool_str425[sizeof("g.se")];
-    char stringpool_str426[sizeof("edu.bs")];
-    char stringpool_str427[sizeof("i.se")];
-    char stringpool_str428[sizeof("n.se")];
-    char stringpool_str429[sizeof("org.ee")];
-    char stringpool_str430[sizeof("edu.me")];
-    char stringpool_str431[sizeof("gq")];
-    char stringpool_str432[sizeof("laz.it")];
-    char stringpool_str433[sizeof("iq")];
-    char stringpool_str434[sizeof("lk")];
-    char stringpool_str435[sizeof("an")];
-    char stringpool_str436[sizeof("onl")];
-    char stringpool_str437[sizeof("coffee")];
-    char stringpool_str438[sizeof("ntr.br")];
-    char stringpool_str439[sizeof("x.se")];
-    char stringpool_str440[sizeof("ip6.arpa")];
-    char stringpool_str441[sizeof("org.rs")];
-    char stringpool_str442[sizeof("z.se")];
-    char stringpool_str443[sizeof("net.bb")];
-    char stringpool_str444[sizeof("org.se")];
-    char stringpool_str445[sizeof("edu.kn")];
-    char stringpool_str446[sizeof("org.je")];
-    char stringpool_str447[sizeof("com.bb")];
-    char stringpool_str448[sizeof("gov.bb")];
-    char stringpool_str449[sizeof("name.tj")];
-    char stringpool_str450[sizeof("org.pe")];
-    char stringpool_str451[sizeof("eus")];
-    char stringpool_str452[sizeof("etne.no")];
-    char stringpool_str453[sizeof("e.se")];
-    char stringpool_str454[sizeof("info.la")];
-    char stringpool_str455[sizeof("net.sa")];
-    char stringpool_str456[sizeof("org.au")];
-    char stringpool_str457[sizeof("lund.no")];
-    char stringpool_str458[sizeof("biz.mw")];
-    char stringpool_str459[sizeof("com.sa")];
-    char stringpool_str460[sizeof("gov.sa")];
-    char stringpool_str461[sizeof("brussels")];
-    char stringpool_str462[sizeof("net.pa")];
-    char stringpool_str463[sizeof("info.pl")];
-    char stringpool_str464[sizeof("lebesby.no")];
-    char stringpool_str465[sizeof("edu.lk")];
-    char stringpool_str466[sizeof("com.pa")];
-    char stringpool_str467[sizeof("arts.ro")];
-    char stringpool_str468[sizeof("edu.lr")];
-    char stringpool_str469[sizeof("hm")];
-    char stringpool_str470[sizeof("bir.ru")];
-    char stringpool_str471[sizeof("nom.pa")];
-    char stringpool_str472[sizeof("grue.no")];
-    char stringpool_str473[sizeof("int.mw")];
-    char stringpool_str474[sizeof("org.mx")];
-    char stringpool_str475[sizeof("org.ml")];
-    char stringpool_str476[sizeof("org.mk")];
-    char stringpool_str477[sizeof("org.mt")];
-    char stringpool_str478[sizeof("arts.co")];
-    char stringpool_str479[sizeof("edu.lc")];
-    char stringpool_str480[sizeof("org.mw")];
-    char stringpool_str481[sizeof("emr.it")];
-    char stringpool_str482[sizeof("info.na")];
-    char stringpool_str483[sizeof("int.ru")];
-    char stringpool_str484[sizeof("ch")];
-    char stringpool_str485[sizeof("bh")];
-    char stringpool_str486[sizeof("kh")];
-    char stringpool_str487[sizeof("gh")];
-    char stringpool_str488[sizeof("gob.pa")];
-    char stringpool_str489[sizeof("adm.br")];
-    char stringpool_str490[sizeof("adv.br")];
-    char stringpool_str491[sizeof("org.ru")];
-    char stringpool_str492[sizeof("nesseby.no")];
-    char stringpool_str493[sizeof("idv.hk")];
-    char stringpool_str494[sizeof("net.hk")];
-    char stringpool_str495[sizeof("net.ht")];
-    char stringpool_str496[sizeof("com.hk")];
-    char stringpool_str497[sizeof("com.ht")];
-    char stringpool_str498[sizeof("kiev.ua")];
-    char stringpool_str499[sizeof("gov.hk")];
-    char stringpool_str500[sizeof("oita.jp")];
-    char stringpool_str501[sizeof("com.hr")];
-    char stringpool_str502[sizeof("org.mn")];
-    char stringpool_str503[sizeof("edu.bb")];
-    char stringpool_str504[sizeof("cal.it")];
-    char stringpool_str505[sizeof("caa.aero")];
-    char stringpool_str506[sizeof("arna.no")];
-    char stringpool_str507[sizeof("org.ae")];
-    char stringpool_str508[sizeof("biz.nr")];
-    char stringpool_str509[sizeof("gouv.bj")];
-    char stringpool_str510[sizeof("cmw.ru")];
-    char stringpool_str511[sizeof("org.ms")];
-    char stringpool_str512[sizeof("link")];
-    char stringpool_str513[sizeof("name.qa")];
-    char stringpool_str514[sizeof("l.se")];
-    char stringpool_str515[sizeof("edu.sa")];
-    char stringpool_str516[sizeof("net.lb")];
-    char stringpool_str517[sizeof("lib.ee")];
-    char stringpool_str518[sizeof("com.lb")];
-    char stringpool_str519[sizeof("gov.lb")];
-    char stringpool_str520[sizeof("net.hn")];
-    char stringpool_str521[sizeof("org.ir")];
-    char stringpool_str522[sizeof("net.iq")];
-    char stringpool_str523[sizeof("edu.pa")];
-    char stringpool_str524[sizeof("hn")];
-    char stringpool_str525[sizeof("com.hn")];
-    char stringpool_str526[sizeof("com.iq")];
-    char stringpool_str527[sizeof("ind.tn")];
-    char stringpool_str528[sizeof("gov.iq")];
-    char stringpool_str529[sizeof("cy")];
-    char stringpool_str530[sizeof("by")];
-    char stringpool_str531[sizeof("ky")];
-    char stringpool_str532[sizeof("gy")];
-    char stringpool_str533[sizeof("biz.tj")];
-    char stringpool_str534[sizeof("org.nr")];
-    char stringpool_str535[sizeof("imb.br")];
-    char stringpool_str536[sizeof("name.jo")];
-    char stringpool_str537[sizeof("net.dz")];
-    char stringpool_str538[sizeof("grp.lk")];
-    char stringpool_str539[sizeof("xyz")];
-    char stringpool_str540[sizeof("blue")];
-    char stringpool_str541[sizeof("com.dz")];
-    char stringpool_str542[sizeof("cheap")];
-    char stringpool_str543[sizeof("gov.dz")];
-    char stringpool_str544[sizeof("asso.km")];
-    char stringpool_str545[sizeof("gob.hn")];
-    char stringpool_str546[sizeof("org.in")];
-    char stringpool_str547[sizeof("int.tj")];
-    char stringpool_str548[sizeof("int.is")];
-    char stringpool_str549[sizeof("al")];
-    char stringpool_str550[sizeof("nkz.ru")];
-    char stringpool_str551[sizeof("leg.br")];
-    char stringpool_str552[sizeof("cim.br")];
-    char stringpool_str553[sizeof("org.tj")];
-    char stringpool_str554[sizeof("edu.hk")];
-    char stringpool_str555[sizeof("edu.ht")];
-    char stringpool_str556[sizeof("org.is")];
-    char stringpool_str557[sizeof("aid.pl")];
-    char stringpool_str558[sizeof("gok.pk")];
-    char stringpool_str559[sizeof("norddal.no")];
-    char stringpool_str560[sizeof("org.mu")];
-    char stringpool_str561[sizeof("info.bb")];
-    char stringpool_str562[sizeof("emp.br")];
-    char stringpool_str563[sizeof("info.ro")];
-    char stringpool_str564[sizeof("gjesdal.no")];
-    char stringpool_str565[sizeof("life")];
-    char stringpool_str566[sizeof("cnt.br")];
-    char stringpool_str567[sizeof("irc.pl")];
-    char stringpool_str568[sizeof("inf.mk")];
-    char stringpool_str569[sizeof("lel.br")];
-    char stringpool_str570[sizeof("org.bt")];
-    char stringpool_str571[sizeof("info.co")];
-    char stringpool_str572[sizeof("edu.lb")];
-    char stringpool_str573[sizeof("org.br")];
-    char stringpool_str574[sizeof("cw")];
-    char stringpool_str575[sizeof("bw")];
-    char stringpool_str576[sizeof("org.bw")];
-    char stringpool_str577[sizeof("kw")];
-    char stringpool_str578[sizeof("gw")];
-    char stringpool_str579[sizeof("eng.pro")];
-    char stringpool_str580[sizeof("net.ua")];
-    char stringpool_str581[sizeof("nara.nara.jp")];
-    char stringpool_str582[sizeof("edu.hn")];
-    char stringpool_str583[sizeof("edu.iq")];
-    char stringpool_str584[sizeof("gouv.ci")];
-    char stringpool_str585[sizeof("gifu.jp")];
-    char stringpool_str586[sizeof("com.ua")];
-    char stringpool_str587[sizeof("a.se")];
-    char stringpool_str588[sizeof("gov.ua")];
-    char stringpool_str589[sizeof("net.eg")];
-    char stringpool_str590[sizeof("aq")];
-    char stringpool_str591[sizeof("info.pr")];
-    char stringpool_str592[sizeof("com.eg")];
-    char stringpool_str593[sizeof("bas.it")];
-    char stringpool_str594[sizeof("hk")];
-    char stringpool_str595[sizeof("zw")];
-    char stringpool_str596[sizeof("gov.eg")];
-    char stringpool_str597[sizeof("aip.ee")];
-    char stringpool_str598[sizeof("edu.dz")];
-    char stringpool_str599[sizeof("art.br")];
-    char stringpool_str600[sizeof("qa")];
-    char stringpool_str601[sizeof("org.kp")];
-    char stringpool_str602[sizeof("net.sg")];
-    char stringpool_str603[sizeof("biz.id")];
-    char stringpool_str604[sizeof("com.sg")];
-    char stringpool_str605[sizeof("gov.sg")];
-    char stringpool_str606[sizeof("arts.nf")];
-    char stringpool_str607[sizeof("net.az")];
-    char stringpool_str608[sizeof("org.bs")];
-    char stringpool_str609[sizeof("com.az")];
-    char stringpool_str610[sizeof("gov.az")];
-    char stringpool_str611[sizeof("net.ai")];
-    char stringpool_str612[sizeof("org.me")];
-    char stringpool_str613[sizeof("ly")];
-    char stringpool_str614[sizeof("info.nr")];
-    char stringpool_str615[sizeof("com.ai")];
-    char stringpool_str616[sizeof("aure.no")];
-    char stringpool_str617[sizeof("bmd.br")];
-    char stringpool_str618[sizeof("net.ws")];
-    char stringpool_str619[sizeof("net.ma")];
-    char stringpool_str620[sizeof("org.kn")];
-    char stringpool_str621[sizeof("com.ws")];
-    char stringpool_str622[sizeof("gov.ws")];
-    char stringpool_str623[sizeof("gov.ma")];
-    char stringpool_str624[sizeof("int.lk")];
-    char stringpool_str625[sizeof("edu.ua")];
-    char stringpool_str626[sizeof("gouv.sn")];
-    char stringpool_str627[sizeof("i.ph")];
-    char stringpool_str628[sizeof("org.lk")];
-    char stringpool_str629[sizeof("gjerstad.no")];
-    char stringpool_str630[sizeof("ind.in")];
-    char stringpool_str631[sizeof("edu.eg")];
-    char stringpool_str632[sizeof("org.lr")];
-    char stringpool_str633[sizeof("gausdal.no")];
-    char stringpool_str634[sizeof("org.lc")];
-    char stringpool_str635[sizeof("edu.sg")];
-    char stringpool_str636[sizeof("cbg.ru")];
-    char stringpool_str637[sizeof("belluno.it")];
-    char stringpool_str638[sizeof("biz.bb")];
-    char stringpool_str639[sizeof("net.ag")];
-    char stringpool_str640[sizeof("com.ag")];
-    char stringpool_str641[sizeof("edu.az")];
-    char stringpool_str642[sizeof("net.uz")];
-    char stringpool_str643[sizeof("kms.ru")];
-    char stringpool_str644[sizeof("inf.br")];
-    char stringpool_str645[sizeof("nom.ag")];
-    char stringpool_str646[sizeof("h.se")];
-    char stringpool_str647[sizeof("com.uz")];
-    char stringpool_str648[sizeof("ind.br")];
-    char stringpool_str649[sizeof("notteroy.no")];
-    char stringpool_str650[sizeof("com.na")];
-    char stringpool_str651[sizeof("ens.tn")];
-    char stringpool_str652[sizeof("org.ls")];
-    char stringpool_str653[sizeof("edu.ws")];
-    char stringpool_str654[sizeof("org.bb")];
-    char stringpool_str655[sizeof("education")];
-    char stringpool_str656[sizeof("khv.ru")];
-    char stringpool_str657[sizeof("jobs.tt")];
-    char stringpool_str658[sizeof("info.pk")];
-    char stringpool_str659[sizeof("educator.aero")];
-    char stringpool_str660[sizeof("org.sa")];
-    char stringpool_str661[sizeof("ltd.lk")];
-    char stringpool_str662[sizeof("cng.br")];
-    char stringpool_str663[sizeof("org.pa")];
-    char stringpool_str664[sizeof("info.nf")];
-    char stringpool_str665[sizeof("abr.it")];
-    char stringpool_str666[sizeof("intl.tn")];
-    char stringpool_str667[sizeof("conf.lv")];
-    char stringpool_str668[sizeof("its.me")];
-    char stringpool_str669[sizeof("jolster.no")];
-    char stringpool_str670[sizeof("build")];
-    char stringpool_str671[sizeof("neustar")];
-    char stringpool_str672[sizeof("lig.it")];
-    char stringpool_str673[sizeof("net.ba")];
-    char stringpool_str674[sizeof("aremark.no")];
-    char stringpool_str675[sizeof("com.ba")];
-    char stringpool_str676[sizeof("camera")];
-    char stringpool_str677[sizeof("bd.se")];
-    char stringpool_str678[sizeof("gov.ba")];
-    char stringpool_str679[sizeof("com.ug")];
-    char stringpool_str680[sizeof("eng.br")];
-    char stringpool_str681[sizeof("co.me")];
-    char stringpool_str682[sizeof("guide")];
-    char stringpool_str683[sizeof("aw")];
-    char stringpool_str684[sizeof("hole.no")];
-    char stringpool_str685[sizeof("org.hk")];
-    char stringpool_str686[sizeof("org.ht")];
-    char stringpool_str687[sizeof("nome.pt")];
-    char stringpool_str688[sizeof("ne.us")];
-    char stringpool_str689[sizeof("id.us")];
-    char stringpool_str690[sizeof("nd.us")];
-    char stringpool_str691[sizeof("co.ls")];
-    char stringpool_str692[sizeof("co.us")];
-    char stringpool_str693[sizeof("nsk.ru")];
-    char stringpool_str694[sizeof("eun.eg")];
-    char stringpool_str695[sizeof("jus.br")];
-    char stringpool_str696[sizeof("ks.us")];
-    char stringpool_str697[sizeof("kommune.no")];
-    char stringpool_str698[sizeof("ouda.nara.jp")];
-    char stringpool_str699[sizeof("co.ae")];
-    char stringpool_str700[sizeof("alta.no")];
-    char stringpool_str701[sizeof("nj.us")];
-    char stringpool_str702[sizeof("org.lb")];
-    char stringpool_str703[sizeof("art.ht")];
-    char stringpool_str704[sizeof("co.ao")];
-    char stringpool_str705[sizeof("org.hn")];
-    char stringpool_str706[sizeof("org.iq")];
-    char stringpool_str707[sizeof("caserta.it")];
-    char stringpool_str708[sizeof("ink")];
-    char stringpool_str709[sizeof("asia")];
-    char stringpool_str710[sizeof("etnedal.no")];
-    char stringpool_str711[sizeof("nic.tr")];
-    char stringpool_str712[sizeof("com.mg")];
-    char stringpool_str713[sizeof("joyo.kyoto.jp")];
-    char stringpool_str714[sizeof("gov.mg")];
-    char stringpool_str715[sizeof("org.dz")];
-    char stringpool_str716[sizeof("nom.mg")];
-    char stringpool_str717[sizeof("ed.ao")];
-    char stringpool_str718[sizeof("co.tj")];
-    char stringpool_str719[sizeof("go.tj")];
-    char stringpool_str720[sizeof("edu.ba")];
-    char stringpool_str721[sizeof("nls.uk")];
-    char stringpool_str722[sizeof("org.sz")];
-    char stringpool_str723[sizeof("us")];
-    char stringpool_str724[sizeof("lier.no")];
-    char stringpool_str725[sizeof("net.la")];
-    char stringpool_str726[sizeof("art.dz")];
-    char stringpool_str727[sizeof("com.la")];
-    char stringpool_str728[sizeof("kamo.kyoto.jp")];
-    char stringpool_str729[sizeof("od.ua")];
-    char stringpool_str730[sizeof("gov.la")];
-    char stringpool_str731[sizeof("enterprises")];
-    char stringpool_str732[sizeof("ws")];
-    char stringpool_str733[sizeof("name.tt")];
-    char stringpool_str734[sizeof("aero.tt")];
-    char stringpool_str735[sizeof("nic.uk")];
-    char stringpool_str736[sizeof("info.ki")];
-    char stringpool_str737[sizeof("co.ma")];
-    char stringpool_str738[sizeof("co.ua")];
-    char stringpool_str739[sizeof("ca.us")];
-    char stringpool_str740[sizeof("ks.ua")];
-    char stringpool_str741[sizeof("ga.us")];
-    char stringpool_str742[sizeof("net.bz")];
-    char stringpool_str743[sizeof("ia.us")];
-    char stringpool_str744[sizeof("leka.no")];
-    char stringpool_str745[sizeof("kazo.saitama.jp")];
-    char stringpool_str746[sizeof("com.bz")];
-    char stringpool_str747[sizeof("asso.bj")];
-    char stringpool_str748[sizeof("livorno.it")];
-    char stringpool_str749[sizeof("gov.bz")];
-    char stringpool_str750[sizeof("co.ve")];
-    char stringpool_str751[sizeof("com.bi")];
-    char stringpool_str752[sizeof("org.ua")];
-    char stringpool_str753[sizeof("org.hu")];
-    char stringpool_str754[sizeof("club")];
-    char stringpool_str755[sizeof("net.ng")];
-    char stringpool_str756[sizeof("black")];
-    char stringpool_str757[sizeof("biz.az")];
-    char stringpool_str758[sizeof("com.ng")];
-    char stringpool_str759[sizeof("gov.ng")];
-    char stringpool_str760[sizeof("org.eg")];
-    char stringpool_str761[sizeof("edu.mg")];
-    char stringpool_str762[sizeof("zp.ua")];
-    char stringpool_str763[sizeof("elverum.no")];
-    char stringpool_str764[sizeof("web.pk")];
-    char stringpool_str765[sizeof("ing.pa")];
-    char stringpool_str766[sizeof("net.qa")];
-    char stringpool_str767[sizeof("zlg.br")];
-    char stringpool_str768[sizeof("ninja")];
-    char stringpool_str769[sizeof("com.qa")];
-    char stringpool_str770[sizeof("co.st")];
-    char stringpool_str771[sizeof("net.kz")];
-    char stringpool_str772[sizeof("ct.us")];
-    char stringpool_str773[sizeof("gov.qa")];
-    char stringpool_str774[sizeof("gose.nara.jp")];
-    char stringpool_str775[sizeof("com.kz")];
-    char stringpool_str776[sizeof("int.az")];
-    char stringpool_str777[sizeof("org.sg")];
-    char stringpool_str778[sizeof("gov.kz")];
-    char stringpool_str779[sizeof("holdings")];
-    char stringpool_str780[sizeof("info.tn")];
-    char stringpool_str781[sizeof("net.ki")];
-    char stringpool_str782[sizeof("or.us")];
-    char stringpool_str783[sizeof("is-an-actor.com")];
-    char stringpool_str784[sizeof("nysa.pl")];
-    char stringpool_str785[sizeof("com.ki")];
-    char stringpool_str786[sizeof("gov.ki")];
-    char stringpool_str787[sizeof("lacaixa")];
-    char stringpool_str788[sizeof("org.az")];
-    char stringpool_str789[sizeof("etc.br")];
-    char stringpool_str790[sizeof("ua")];
-    char stringpool_str791[sizeof("co.at")];
-    char stringpool_str792[sizeof("lillesand.no")];
-    char stringpool_str793[sizeof("org.ai")];
-    char stringpool_str794[sizeof("edu.la")];
-    char stringpool_str795[sizeof("it.ao")];
-    char stringpool_str796[sizeof("bike")];
-    char stringpool_str797[sizeof("org.ws")];
-    char stringpool_str798[sizeof("org.ma")];
-    char stringpool_str799[sizeof("co.mu")];
-    char stringpool_str800[sizeof("community")];
-    char stringpool_str801[sizeof("naustdal.no")];
-    char stringpool_str802[sizeof("co.tt")];
-    char stringpool_str803[sizeof("edu.bz")];
-    char stringpool_str804[sizeof("gu.us")];
-    char stringpool_str805[sizeof("edu.bi")];
-    char stringpool_str806[sizeof("leasing.aero")];
-    char stringpool_str807[sizeof("id.au")];
-    char stringpool_str808[sizeof("edu.ng")];
-    char stringpool_str809[sizeof("co.uz")];
-    char stringpool_str810[sizeof("asso.ci")];
-    char stringpool_str811[sizeof("co.sz")];
-    char stringpool_str812[sizeof("askvoll.no")];
-    char stringpool_str813[sizeof("edu.qa")];
-    char stringpool_str814[sizeof("net.kg")];
-    char stringpool_str815[sizeof("hemsedal.no")];
-    char stringpool_str816[sizeof("com.kg")];
-    char stringpool_str817[sizeof("la.us")];
-    char stringpool_str818[sizeof("edu.kz")];
-    char stringpool_str819[sizeof("gov.kg")];
-    char stringpool_str820[sizeof("kustanai.ru")];
-    char stringpool_str821[sizeof("wed")];
-    char stringpool_str822[sizeof("as.us")];
-    char stringpool_str823[sizeof("edu.ki")];
-    char stringpool_str824[sizeof("bryansk.ru")];
-    char stringpool_str825[sizeof("org.ag")];
-    char stringpool_str826[sizeof("cr.ua")];
-    char stringpool_str827[sizeof("kr.ua")];
-    char stringpool_str828[sizeof("org.uz")];
-    char stringpool_str829[sizeof("hamburg")];
-    char stringpool_str830[sizeof("zt.ua")];
-    char stringpool_str831[sizeof("nittedal.no")];
-    char stringpool_str832[sizeof("co.ca")];
-    char stringpool_str833[sizeof("ne.tz")];
-    char stringpool_str834[sizeof("nic.in")];
-    char stringpool_str835[sizeof("nm.us")];
-    char stringpool_str836[sizeof("org.na")];
-    char stringpool_str837[sizeof("kizu.kyoto.jp")];
-    char stringpool_str838[sizeof("nyc")];
-    char stringpool_str839[sizeof("co.tz")];
-    char stringpool_str840[sizeof("ns.ca")];
-    char stringpool_str841[sizeof("go.tz")];
-    char stringpool_str842[sizeof("nic.tj")];
-    char stringpool_str843[sizeof("elk.pl")];
-    char stringpool_str844[sizeof("cupcake.is")];
-    char stringpool_str845[sizeof("uz")];
-    char stringpool_str846[sizeof("co.om")];
-    char stringpool_str847[sizeof("kita.kyoto.jp")];
-    char stringpool_str848[sizeof("cv")];
-    char stringpool_str849[sizeof("co.tm")];
-    char stringpool_str850[sizeof("bv")];
-    char stringpool_str851[sizeof("co.cr")];
-    char stringpool_str852[sizeof("go.cr")];
-    char stringpool_str853[sizeof("edu.kg")];
-    char stringpool_str854[sizeof("or.at")];
-    char stringpool_str855[sizeof("work")];
-    char stringpool_str856[sizeof("notodden.no")];
-    char stringpool_str857[sizeof("oyer.no")];
-    char stringpool_str858[sizeof("embaixada.st")];
-    char stringpool_str859[sizeof("org.ba")];
-    char stringpool_str860[sizeof("org.ug")];
-    char stringpool_str861[sizeof("asso.re")];
-    char stringpool_str862[sizeof("or.mu")];
-    char stringpool_str863[sizeof("gs.oslo.no")];
-    char stringpool_str864[sizeof("works")];
-    char stringpool_str865[sizeof("ed.cr")];
-    char stringpool_str866[sizeof("in.us")];
-    char stringpool_str867[sizeof("net.vc")];
-    char stringpool_str868[sizeof("waw.pl")];
-    char stringpool_str869[sizeof("nhk")];
-    char stringpool_str870[sizeof("com.vc")];
-    char stringpool_str871[sizeof("qsl.br")];
-    char stringpool_str872[sizeof("gov.vc")];
-    char stringpool_str873[sizeof("udm.ru")];
-    char stringpool_str874[sizeof("km.ua")];
-    char stringpool_str875[sizeof("kautokeino.no")];
-    char stringpool_str876[sizeof("kawasaki.jp")];
-    char stringpool_str877[sizeof("com.pf")];
-    char stringpool_str878[sizeof("wme")];
-    char stringpool_str879[sizeof("net.vn")];
-    char stringpool_str880[sizeof("nt.au")];
-    char stringpool_str881[sizeof("co.rs")];
-    char stringpool_str882[sizeof("kanmaki.nara.jp")];
-    char stringpool_str883[sizeof("info.tt")];
-    char stringpool_str884[sizeof("lt.ua")];
-    char stringpool_str885[sizeof("com.vn")];
-    char stringpool_str886[sizeof("gov.vn")];
-    char stringpool_str887[sizeof("ne.kr")];
-    char stringpool_str888[sizeof("eti.br")];
-    char stringpool_str889[sizeof("co.kr")];
-    char stringpool_str890[sizeof("go.kr")];
-    char stringpool_str891[sizeof("ar.us")];
-    char stringpool_str892[sizeof("istmein.de")];
-    char stringpool_str893[sizeof("o.bg")];
-    char stringpool_str894[sizeof("c.bg")];
-    char stringpool_str895[sizeof("b.bg")];
-    char stringpool_str896[sizeof("k.bg")];
-    char stringpool_str897[sizeof("g.bg")];
-    char stringpool_str898[sizeof("0.bg")];
-    char stringpool_str899[sizeof("6.bg")];
-    char stringpool_str900[sizeof("2.bg")];
-    char stringpool_str901[sizeof("i.bg")];
-    char stringpool_str902[sizeof("9.bg")];
-    char stringpool_str903[sizeof("8.bg")];
-    char stringpool_str904[sizeof("7.bg")];
-    char stringpool_str905[sizeof("ando.nara.jp")];
-    char stringpool_str906[sizeof("n.bg")];
-    char stringpool_str907[sizeof("org.mg")];
-    char stringpool_str908[sizeof("5.bg")];
-    char stringpool_str909[sizeof("4.bg")];
-    char stringpool_str910[sizeof("3.bg")];
-    char stringpool_str911[sizeof("1.bg")];
-    char stringpool_str912[sizeof("nt.ca")];
-    char stringpool_str913[sizeof("x.bg")];
-    char stringpool_str914[sizeof("is-leet.com")];
-    char stringpool_str915[sizeof("club.tw")];
-    char stringpool_str916[sizeof("grimstad.no")];
-    char stringpool_str917[sizeof("z.bg")];
-    char stringpool_str918[sizeof("or.tz")];
-    char stringpool_str919[sizeof("es.kr")];
-    char stringpool_str920[sizeof("xn--p1ai")];
-    char stringpool_str921[sizeof("int.la")];
-    char stringpool_str922[sizeof("edu.vc")];
-    char stringpool_str923[sizeof("cn.ua")];
-    char stringpool_str924[sizeof("e.bg")];
-    char stringpool_str925[sizeof("oz.au")];
-    char stringpool_str926[sizeof("in.ua")];
-    char stringpool_str927[sizeof("net.af")];
-    char stringpool_str928[sizeof("lv")];
-    char stringpool_str929[sizeof("org.la")];
-    char stringpool_str930[sizeof("nagasaki.jp")];
-    char stringpool_str931[sizeof("com.af")];
-    char stringpool_str932[sizeof("ok.us")];
-    char stringpool_str933[sizeof("edu.pf")];
-    char stringpool_str934[sizeof("gov.af")];
-    char stringpool_str935[sizeof("co.vi")];
-    char stringpool_str936[sizeof("j.bg")];
-    char stringpool_str937[sizeof("edu.vn")];
-    char stringpool_str938[sizeof("az.us")];
-    char stringpool_str939[sizeof("nu.ca")];
-    char stringpool_str940[sizeof("catania.it")];
-    char stringpool_str941[sizeof("or.cr")];
-    char stringpool_str942[sizeof("org.bz")];
-    char stringpool_str943[sizeof("org.bi")];
-    char stringpool_str944[sizeof("biz.ki")];
-    char stringpool_str945[sizeof("org.ng")];
-    char stringpool_str946[sizeof("co.ci")];
-    char stringpool_str947[sizeof("go.ci")];
-    char stringpool_str948[sizeof("asso.gp")];
-    char stringpool_str949[sizeof("gd.cn")];
-    char stringpool_str950[sizeof("web.tj")];
-    char stringpool_str951[sizeof("org.qa")];
-    char stringpool_str952[sizeof("is-a-doctor.com")];
-    char stringpool_str953[sizeof("org.kz")];
-    char stringpool_str954[sizeof("quebec")];
-    char stringpool_str955[sizeof("uk")];
-    char stringpool_str956[sizeof("gs.cn")];
-    char stringpool_str957[sizeof("lipetsk.ru")];
-    char stringpool_str958[sizeof("bj.cn")];
-    char stringpool_str959[sizeof("nt.ro")];
-    char stringpool_str960[sizeof("kotoura.tottori.jp")];
-    char stringpool_str961[sizeof("org.ki")];
-    char stringpool_str962[sizeof("ed.ci")];
-    char stringpool_str963[sizeof("karasjok.no")];
-    char stringpool_str964[sizeof("il.us")];
-    char stringpool_str965[sizeof("otsuka")];
-    char stringpool_str966[sizeof("nordre-land.no")];
-    char stringpool_str967[sizeof("xj.cn")];
-    char stringpool_str968[sizeof("l.bg")];
-    char stringpool_str969[sizeof("edu.af")];
-    char stringpool_str970[sizeof("zj.cn")];
-    char stringpool_str971[sizeof("net.ve")];
-    char stringpool_str972[sizeof("or.kr")];
-    char stringpool_str973[sizeof("com.ve")];
-    char stringpool_str974[sizeof("gov.ve")];
-    char stringpool_str975[sizeof("ck.ua")];
-    char stringpool_str976[sizeof("builders")];
-    char stringpool_str977[sizeof("bzh")];
-    char stringpool_str978[sizeof("enebakk.no")];
-    char stringpool_str979[sizeof("js.cn")];
-    char stringpool_str980[sizeof("navuotna.no")];
-    char stringpool_str981[sizeof("nissedal.no")];
-    char stringpool_str982[sizeof("in-addr.arpa")];
-    char stringpool_str983[sizeof("novosibirsk.ru")];
-    char stringpool_str984[sizeof("balestrand.no")];
-    char stringpool_str985[sizeof("berg.no")];
-    char stringpool_str986[sizeof("nyc.mn")];
-    char stringpool_str987[sizeof("badaddja.no")];
-    char stringpool_str988[sizeof("org.kg")];
-    char stringpool_str989[sizeof("careers")];
-    char stringpool_str990[sizeof("kvam.no")];
-    char stringpool_str991[sizeof("como.it")];
-    char stringpool_str992[sizeof("web.id")];
-    char stringpool_str993[sizeof("on.ca")];
-    char stringpool_str994[sizeof("imperia.it")];
-    char stringpool_str995[sizeof("qld.au")];
-    char stringpool_str996[sizeof("edu.ve")];
-    char stringpool_str997[sizeof("is-a-player.com")];
-    char stringpool_str998[sizeof("u.se")];
-    char stringpool_str999[sizeof("a.bg")];
-    char stringpool_str1000[sizeof("web.lk")];
-    char stringpool_str1001[sizeof("nagoya")];
-    char stringpool_str1002[sizeof("or.ci")];
-    char stringpool_str1003[sizeof("ye")];
-    char stringpool_str1004[sizeof("koge.tottori.jp")];
-    char stringpool_str1005[sizeof("w.se")];
-    char stringpool_str1006[sizeof("bielawa.pl")];
-    char stringpool_str1007[sizeof("oh.us")];
-    char stringpool_str1008[sizeof("nh.us")];
-    char stringpool_str1009[sizeof("college")];
-    char stringpool_str1010[sizeof("nb.ca")];
-    char stringpool_str1011[sizeof("nesodden.no")];
-    char stringpool_str1012[sizeof("co.cl")];
-    char stringpool_str1013[sizeof("international")];
-    char stringpool_str1014[sizeof("net.nf")];
-    char stringpool_str1015[sizeof("ak.us")];
-    char stringpool_str1016[sizeof("co.ba")];
-    char stringpool_str1017[sizeof("koto.tokyo.jp")];
-    char stringpool_str1018[sizeof("com.nf")];
-    char stringpool_str1019[sizeof("hi.us")];
-    char stringpool_str1020[sizeof("biz.vn")];
-    char stringpool_str1021[sizeof("ingatlan.hu")];
-    char stringpool_str1022[sizeof("umb.it")];
-    char stringpool_str1023[sizeof("buryatia.ru")];
-    char stringpool_str1024[sizeof("co.th")];
-    char stringpool_str1025[sizeof("go.th")];
-    char stringpool_str1026[sizeof("id.ly")];
-    char stringpool_str1027[sizeof("org.vc")];
-    char stringpool_str1028[sizeof("in.rs")];
-    char stringpool_str1029[sizeof("co.je")];
-    char stringpool_str1030[sizeof("ky.us")];
-    char stringpool_str1031[sizeof("int.vn")];
-    char stringpool_str1032[sizeof("org.pf")];
-    char stringpool_str1033[sizeof("ny.us")];
-    char stringpool_str1034[sizeof("gz.cn")];
-    char stringpool_str1035[sizeof("isernia.it")];
-    char stringpool_str1036[sizeof("org.vn")];
-    char stringpool_str1037[sizeof("ostroda.pl")];
-    char stringpool_str1038[sizeof("ne.jp")];
-    char stringpool_str1039[sizeof("xz.cn")];
-    char stringpool_str1040[sizeof("co.jp")];
-    char stringpool_str1041[sizeof("irkutsk.ru")];
-    char stringpool_str1042[sizeof("go.jp")];
-    char stringpool_str1043[sizeof("kh.ua")];
-    char stringpool_str1044[sizeof("hjelmeland.no")];
-    char stringpool_str1045[sizeof("al.us")];
-    char stringpool_str1046[sizeof("katsuragi.nara.jp")];
-    char stringpool_str1047[sizeof("hs.kr")];
-    char stringpool_str1048[sizeof("gov.bf")];
-    char stringpool_str1049[sizeof("lezajsk.pl")];
-    char stringpool_str1050[sizeof("h.bg")];
-    char stringpool_str1051[sizeof("nm.cn")];
-    char stringpool_str1052[sizeof("ed.jp")];
-    char stringpool_str1053[sizeof("uy")];
-    char stringpool_str1054[sizeof("urn.arpa")];
-    char stringpool_str1055[sizeof("gouv.fr")];
-    char stringpool_str1056[sizeof("engerdal.no")];
-    char stringpool_str1057[sizeof("nl.ca")];
-    char stringpool_str1058[sizeof("hjartdal.no")];
-    char stringpool_str1059[sizeof("co.mw")];
-    char stringpool_str1060[sizeof("catanzaro.it")];
-    char stringpool_str1061[sizeof("ivgu.no")];
-    char stringpool_str1062[sizeof("andasuolo.no")];
-    char stringpool_str1063[sizeof("yt")];
-    char stringpool_str1064[sizeof("kragero.no")];
-    char stringpool_str1065[sizeof("ostrowwlkp.pl")];
-    char stringpool_str1066[sizeof("org.af")];
-    char stringpool_str1067[sizeof("liguria.it")];
-    char stringpool_str1068[sizeof("kyiv.ua")];
-    char stringpool_str1069[sizeof("karelia.ru")];
-    char stringpool_str1070[sizeof("wtc")];
-    char stringpool_str1071[sizeof("getmyip.com")];
-    char stringpool_str1072[sizeof("ostre-toten.no")];
-    char stringpool_str1073[sizeof("ve")];
-    char stringpool_str1074[sizeof("newmexico.museum")];
-    char stringpool_str1075[sizeof("cosenza.it")];
-    char stringpool_str1076[sizeof("or.th")];
-    char stringpool_str1077[sizeof("he.cn")];
-    char stringpool_str1078[sizeof("birkenes.no")];
-    char stringpool_str1079[sizeof("kirkenes.no")];
-    char stringpool_str1080[sizeof("xn--nnx388a")];
-    char stringpool_str1081[sizeof("holtalen.no")];
-    char stringpool_str1082[sizeof("or.jp")];
-    char stringpool_str1083[sizeof("gr.jp")];
-    char stringpool_str1084[sizeof("voto")];
-    char stringpool_str1085[sizeof("izumisano.osaka.jp")];
-    char stringpool_str1086[sizeof("org.ve")];
-    char stringpool_str1087[sizeof("ab.ca")];
-    char stringpool_str1088[sizeof("co.bi")];
-    char stringpool_str1089[sizeof("nordreisa.no")];
-    char stringpool_str1090[sizeof("kameoka.kyoto.jp")];
-    char stringpool_str1091[sizeof("xn--l1acc")];
-    char stringpool_str1092[sizeof("entertainment.aero")];
-    char stringpool_str1093[sizeof("kitchen")];
-    char stringpool_str1094[sizeof("goto.nagasaki.jp")];
-    char stringpool_str1095[sizeof("city.sapporo.jp")];
-    char stringpool_str1096[sizeof("va")];
-    char stringpool_str1097[sizeof("karasjohka.no")];
-    char stringpool_str1098[sizeof("info.at")];
-    char stringpool_str1099[sizeof("cc")];
-    char stringpool_str1100[sizeof("bl.uk")];
-    char stringpool_str1101[sizeof("kamo.niigata.jp")];
-    char stringpool_str1102[sizeof("nc")];
-    char stringpool_str1103[sizeof("enna.it")];
-    char stringpool_str1104[sizeof("ad.jp")];
-    char stringpool_str1105[sizeof("ha.cn")];
-    char stringpool_str1106[sizeof("nedre-eiker.no")];
-    char stringpool_str1107[sizeof("ln.cn")];
-    char stringpool_str1108[sizeof("net.cw")];
-    char stringpool_str1109[sizeof("gov.cx")];
-    char stringpool_str1110[sizeof("gov.cl")];
-    char stringpool_str1111[sizeof("ozu.kumamoto.jp")];
-    char stringpool_str1112[sizeof("com.cw")];
-    char stringpool_str1113[sizeof("ibaraki.jp")];
-    char stringpool_str1114[sizeof("co.hu")];
-    char stringpool_str1115[sizeof("ec")];
-    char stringpool_str1116[sizeof("kita.tokyo.jp")];
-    char stringpool_str1117[sizeof("notaires.km")];
-    char stringpool_str1118[sizeof("gob.cl")];
-    char stringpool_str1119[sizeof("abruzzo.it")];
-    char stringpool_str1120[sizeof("hino.tottori.jp")];
-    char stringpool_str1121[sizeof("net.cn")];
-    char stringpool_str1122[sizeof("kids.us")];
-    char stringpool_str1123[sizeof("vote")];
-    char stringpool_str1124[sizeof("com.cn")];
-    char stringpool_str1125[sizeof("gov.cn")];
-    char stringpool_str1126[sizeof("watch")];
-    char stringpool_str1127[sizeof("astrakhan.ru")];
-    char stringpool_str1128[sizeof("cagliari.it")];
-    char stringpool_str1129[sizeof("barcelona.museum")];
-    char stringpool_str1130[sizeof("unsa.ba")];
-    char stringpool_str1131[sizeof("vu")];
-    char stringpool_str1132[sizeof("in.th")];
-    char stringpool_str1133[sizeof("gjemnes.no")];
-    char stringpool_str1134[sizeof("koto.shiga.jp")];
-    char stringpool_str1135[sizeof("net.vi")];
-    char stringpool_str1136[sizeof("or.bi")];
-    char stringpool_str1137[sizeof("com.vi")];
-    char stringpool_str1138[sizeof("edu.cw")];
-    char stringpool_str1139[sizeof("jl.cn")];
-    char stringpool_str1140[sizeof("cq.cn")];
-    char stringpool_str1141[sizeof("kicks-ass.net")];
-    char stringpool_str1142[sizeof("archi")];
-    char stringpool_str1143[sizeof("carraramassa.it")];
-    char stringpool_str1144[sizeof("lc")];
-    char stringpool_str1145[sizeof("gildeskal.no")];
-    char stringpool_str1146[sizeof("city.sendai.jp")];
-    char stringpool_str1147[sizeof("vegas")];
-    char stringpool_str1148[sizeof("xn--j1amh")];
-    char stringpool_str1149[sizeof("education.museum")];
-    char stringpool_str1150[sizeof("edu.cn")];
-    char stringpool_str1151[sizeof("net.cu")];
-    char stringpool_str1152[sizeof("carrara-massa.it")];
-    char stringpool_str1153[sizeof("journal.aero")];
-    char stringpool_str1154[sizeof("com.cu")];
-    char stringpool_str1155[sizeof("gov.cu")];
-    char stringpool_str1156[sizeof("za.org")];
-    char stringpool_str1157[sizeof("nordkapp.no")];
-    char stringpool_str1158[sizeof("q.bg")];
-    char stringpool_str1159[sizeof("gov.cd")];
-    char stringpool_str1160[sizeof("is-a-techie.com")];
-    char stringpool_str1161[sizeof("lorenskog.no")];
-    char stringpool_str1162[sizeof("gamo.shiga.jp")];
-    char stringpool_str1163[sizeof("gets-it.net")];
-    char stringpool_str1164[sizeof("namsskogan.no")];
-    char stringpool_str1165[sizeof("co.rw")];
-    char stringpool_str1166[sizeof("itayanagi.aomori.jp")];
-    char stringpool_str1167[sizeof("kodaira.tokyo.jp")];
-    char stringpool_str1168[sizeof("budapest")];
-    char stringpool_str1169[sizeof("nagaokakyo.kyoto.jp")];
-    char stringpool_str1170[sizeof("chukotka.ru")];
-    char stringpool_str1171[sizeof("vi")];
-    char stringpool_str1172[sizeof("iz.hr")];
-    char stringpool_str1173[sizeof("ven.it")];
-    char stringpool_str1174[sizeof("vn")];
-    char stringpool_str1175[sizeof("edu.cu")];
-    char stringpool_str1176[sizeof("ac")];
-    char stringpool_str1177[sizeof("hi.cn")];
-    char stringpool_str1178[sizeof("vda.it")];
-    char stringpool_str1179[sizeof("gorlice.pl")];
-    char stringpool_str1180[sizeof("belgorod.ru")];
-    char stringpool_str1181[sizeof("hn.cn")];
-    char stringpool_str1182[sizeof("ae.org")];
-    char stringpool_str1183[sizeof("y.se")];
-    char stringpool_str1184[sizeof("wa.us")];
-    char stringpool_str1185[sizeof("am.br")];
-    char stringpool_str1186[sizeof("kuroishi.aomori.jp")];
-    char stringpool_str1187[sizeof("asso.fr")];
-    char stringpool_str1188[sizeof("ut.us")];
-    char stringpool_str1189[sizeof("ise.mie.jp")];
-    char stringpool_str1190[sizeof("grajewo.pl")];
-    char stringpool_str1191[sizeof("kartuzy.pl")];
-    char stringpool_str1192[sizeof("beskidy.pl")];
-    char stringpool_str1193[sizeof("xn--55qx5d")];
-    char stringpool_str1194[sizeof("vet.br")];
-    char stringpool_str1195[sizeof("homebuilt.aero")];
-    char stringpool_str1196[sizeof("lucania.it")];
-    char stringpool_str1197[sizeof("xn--d1acj3b")];
-    char stringpool_str1198[sizeof("charter.aero")];
-    char stringpool_str1199[sizeof("hb.cn")];
-    char stringpool_str1200[sizeof("airline.aero")];
-    char stringpool_str1201[sizeof("aerobatic.aero")];
-    char stringpool_str1202[sizeof("xn--kpry57d")];
-    char stringpool_str1203[sizeof("bjerkreim.no")];
-    char stringpool_str1204[sizeof("vrn.ru")];
-    char stringpool_str1205[sizeof("calabria.it")];
-    char stringpool_str1206[sizeof("chuvashia.ru")];
-    char stringpool_str1207[sizeof("hk.cn")];
-    char stringpool_str1208[sizeof("holmestrand.no")];
-    char stringpool_str1209[sizeof("org.cw")];
-    char stringpool_str1210[sizeof("id.lv")];
-    char stringpool_str1211[sizeof("vega.no")];
-    char stringpool_str1212[sizeof("nv.us")];
-    char stringpool_str1213[sizeof("osakasayama.osaka.jp")];
-    char stringpool_str1214[sizeof("kicks-ass.org")];
-    char stringpool_str1215[sizeof("vodka")];
-    char stringpool_str1216[sizeof("hino.tokyo.jp")];
-    char stringpool_str1217[sizeof("org.cn")];
-    char stringpool_str1218[sizeof("co.bw")];
-    char stringpool_str1219[sizeof("community.museum")];
-    char stringpool_str1220[sizeof("catering")];
-    char stringpool_str1221[sizeof("gv.ao")];
-    char stringpool_str1222[sizeof("arakawa.tokyo.jp")];
-    char stringpool_str1223[sizeof("ohda.shimane.jp")];
-    char stringpool_str1224[sizeof("hl.cn")];
-    char stringpool_str1225[sizeof("chuo.tokyo.jp")];
-    char stringpool_str1226[sizeof("ah.cn")];
-    char stringpool_str1227[sizeof("oygarden.no")];
-    char stringpool_str1228[sizeof("actor")];
-    char stringpool_str1229[sizeof("kashiba.nara.jp")];
-    char stringpool_str1230[sizeof("aircraft.aero")];
-    char stringpool_str1231[sizeof("aca.pro")];
-    char stringpool_str1232[sizeof("gliding.aero")];
-    char stringpool_str1233[sizeof("ina.nagano.jp")];
-    char stringpool_str1234[sizeof("uz.ua")];
-    char stringpool_str1235[sizeof("org.vi")];
-    char stringpool_str1236[sizeof("ecn.br")];
-    char stringpool_str1237[sizeof("levanger.no")];
-    char stringpool_str1238[sizeof("nord-fron.no")];
-    char stringpool_str1239[sizeof("cx")];
-    char stringpool_str1240[sizeof("wa.au")];
-    char stringpool_str1241[sizeof("act.au")];
-    char stringpool_str1242[sizeof("cv.ua")];
-    char stringpool_str1243[sizeof("kv.ua")];
-    char stringpool_str1244[sizeof("wi.us")];
-    char stringpool_str1245[sizeof("vaga.no")];
-    char stringpool_str1246[sizeof("jaworzno.pl")];
-    char stringpool_str1247[sizeof("kalmykia.ru")];
-    char stringpool_str1248[sizeof("itabashi.tokyo.jp")];
-    char stringpool_str1249[sizeof("org.cu")];
-    char stringpool_str1250[sizeof("ikaruga.nara.jp")];
-    char stringpool_str1251[sizeof("eidsberg.no")];
-    char stringpool_str1252[sizeof("net.sh")];
-    char stringpool_str1253[sizeof("com.sh")];
-    char stringpool_str1254[sizeof("gov.sh")];
-    char stringpool_str1255[sizeof("net.ph")];
-    char stringpool_str1256[sizeof("club.aero")];
-    char stringpool_str1257[sizeof("xn--mgb2ddes")];
-    char stringpool_str1258[sizeof("city.nagoya.jp")];
-    char stringpool_str1259[sizeof("is-gone.com")];
-    char stringpool_str1260[sizeof("voss.no")];
-    char stringpool_str1261[sizeof("com.ph")];
-    char stringpool_str1262[sizeof("gov.ph")];
-    char stringpool_str1263[sizeof("noda.iwate.jp")];
-    char stringpool_str1264[sizeof("xn--4gbrim")];
-    char stringpool_str1265[sizeof("oji.nara.jp")];
-    char stringpool_str1266[sizeof("u.bg")];
-    char stringpool_str1267[sizeof("koga.ibaraki.jp")];
-    char stringpool_str1268[sizeof("guitars")];
-    char stringpool_str1269[sizeof("hokksund.no")];
-    char stringpool_str1270[sizeof("otsu.shiga.jp")];
-    char stringpool_str1271[sizeof("gv.at")];
-    char stringpool_str1272[sizeof("narviika.no")];
-    char stringpool_str1273[sizeof("w.bg")];
-    char stringpool_str1274[sizeof("arakawa.saitama.jp")];
-    char stringpool_str1275[sizeof("kota.aichi.jp")];
-    char stringpool_str1276[sizeof("kamoenai.hokkaido.jp")];
-    char stringpool_str1277[sizeof("lavangen.no")];
-    char stringpool_str1278[sizeof("kvalsund.no")];
-    char stringpool_str1279[sizeof("kisosaki.mie.jp")];
-    char stringpool_str1280[sizeof("nalchik.ru")];
-    char stringpool_str1281[sizeof("wang")];
-    char stringpool_str1282[sizeof("konyvelo.hu")];
-    char stringpool_str1283[sizeof("akrehamn.no")];
-    char stringpool_str1284[sizeof("edu.ph")];
-    char stringpool_str1285[sizeof("lviv.ua")];
-    char stringpool_str1286[sizeof("hara.nagano.jp")];
-    char stringpool_str1287[sizeof("lv.ua")];
-    char stringpool_str1288[sizeof("astronomy.museum")];
-    char stringpool_str1289[sizeof("villas")];
-    char stringpool_str1290[sizeof("uri.arpa")];
-    char stringpool_str1291[sizeof("kurotaki.nara.jp")];
-    char stringpool_str1292[sizeof("kawakami.nara.jp")];
-    char stringpool_str1293[sizeof("ostroleka.pl")];
-    char stringpool_str1294[sizeof("xn--slat-5na.no")];
-    char stringpool_str1295[sizeof("iida.nagano.jp")];
-    char stringpool_str1296[sizeof("kuzbass.ru")];
-    char stringpool_str1297[sizeof("jessheim.no")];
-    char stringpool_str1298[sizeof("inf.cu")];
-    char stringpool_str1299[sizeof("net.th")];
-    char stringpool_str1300[sizeof("homeunix.net")];
-    char stringpool_str1301[sizeof("gallery.museum")];
-    char stringpool_str1302[sizeof("ina.ibaraki.jp")];
-    char stringpool_str1303[sizeof("caravan")];
-    char stringpool_str1304[sizeof("vercelli.it")];
-    char stringpool_str1305[sizeof("kitaakita.akita.jp")];
-    char stringpool_str1306[sizeof("nes.akershus.no")];
-    char stringpool_str1307[sizeof("udmurtia.ru")];
-    char stringpool_str1308[sizeof("alessandria.it")];
-    char stringpool_str1309[sizeof("kamaishi.iwate.jp")];
-    char stringpool_str1310[sizeof("caltanissetta.it")];
-    char stringpool_str1311[sizeof("ibaraki.osaka.jp")];
-    char stringpool_str1312[sizeof("xn--rdal-poa.no")];
-    char stringpool_str1313[sizeof("gyeonggi.kr")];
-    char stringpool_str1314[sizeof("better-than.tv")];
-    char stringpool_str1315[sizeof("koza.wakayama.jp")];
-    char stringpool_str1316[sizeof("ax")];
-    char stringpool_str1317[sizeof("ovh")];
-    char stringpool_str1318[sizeof("web.ve")];
-    char stringpool_str1319[sizeof("koya.wakayama.jp")];
-    char stringpool_str1320[sizeof("hoyanger.no")];
-    char stringpool_str1321[sizeof("educational.museum")];
-    char stringpool_str1322[sizeof("axa")];
-    char stringpool_str1323[sizeof("omasvuotna.no")];
-    char stringpool_str1324[sizeof("net.ci")];
-    char stringpool_str1325[sizeof("yono.saitama.jp")];
-    char stringpool_str1326[sizeof("com.ci")];
-    char stringpool_str1327[sizeof("asakuchi.okayama.jp")];
-    char stringpool_str1328[sizeof("itakura.gunma.jp")];
-    char stringpool_str1329[sizeof("gobo.wakayama.jp")];
-    char stringpool_str1330[sizeof("de")];
-    char stringpool_str1331[sizeof("ceo")];
-    char stringpool_str1332[sizeof("joso.ibaraki.jp")];
-    char stringpool_str1333[sizeof("do")];
-    char stringpool_str1334[sizeof("boo")];
-    char stringpool_str1335[sizeof("cool")];
-    char stringpool_str1336[sizeof("net.dm")];
-    char stringpool_str1337[sizeof("dj")];
-    char stringpool_str1338[sizeof("com.dm")];
-    char stringpool_str1339[sizeof("gov.dm")];
-    char stringpool_str1340[sizeof("brussel.museum")];
-    char stringpool_str1341[sizeof("net.om")];
-    char stringpool_str1342[sizeof("cechire.com")];
-    char stringpool_str1343[sizeof("kin.okinawa.jp")];
-    char stringpool_str1344[sizeof("com.om")];
-    char stringpool_str1345[sizeof("gov.om")];
-    char stringpool_str1346[sizeof("communication.museum")];
-    char stringpool_str1347[sizeof("iwatsuki.saitama.jp")];
-    char stringpool_str1348[sizeof("chelyabinsk.ru")];
-    char stringpool_str1349[sizeof("jeju.kr")];
-    char stringpool_str1350[sizeof("koka.shiga.jp")];
-    char stringpool_str1351[sizeof("communications.museum")];
-    char stringpool_str1352[sizeof("isesaki.gunma.jp")];
-    char stringpool_str1353[sizeof("catering.aero")];
-    char stringpool_str1354[sizeof("newyork.museum")];
-    char stringpool_str1355[sizeof("naturalsciences.museum")];
-    char stringpool_str1356[sizeof("edu.ci")];
-    char stringpool_str1357[sizeof("iris.arpa")];
-    char stringpool_str1358[sizeof("uda.nara.jp")];
-    char stringpool_str1359[sizeof("kiso.nagano.jp")];
-    char stringpool_str1360[sizeof("aknoluokta.no")];
-    char stringpool_str1361[sizeof("edu.dm")];
-    char stringpool_str1362[sizeof("web.nf")];
-    char stringpool_str1363[sizeof("kawajima.saitama.jp")];
-    char stringpool_str1364[sizeof("edu.om")];
-    char stringpool_str1365[sizeof("bearalvahki.no")];
-    char stringpool_str1366[sizeof("day")];
-    char stringpool_str1367[sizeof("org.sh")];
-    char stringpool_str1368[sizeof("hirosaki.aomori.jp")];
-    char stringpool_str1369[sizeof("americana.museum")];
-    char stringpool_str1370[sizeof("wy.us")];
-    char stringpool_str1371[sizeof("kasaoka.okayama.jp")];
-    char stringpool_str1372[sizeof("org.ph")];
-    char stringpool_str1373[sizeof("expert")];
-    char stringpool_str1374[sizeof("nobeoka.miyazaki.jp")];
-    char stringpool_str1375[sizeof("kira.aichi.jp")];
-    char stringpool_str1376[sizeof("kameyama.mie.jp")];
-    char stringpool_str1377[sizeof("amakusa.kumamoto.jp")];
-    char stringpool_str1378[sizeof("lugansk.ua")];
-    char stringpool_str1379[sizeof("cleaning")];
-    char stringpool_str1380[sizeof("xn--skjk-soa.no")];
-    char stringpool_str1381[sizeof("qh.cn")];
-    char stringpool_str1382[sizeof("net.bh")];
-    char stringpool_str1383[sizeof("norfolk.museum")];
-    char stringpool_str1384[sizeof("com.bh")];
-    char stringpool_str1385[sizeof("oristano.it")];
-    char stringpool_str1386[sizeof("gov.bh")];
-    char stringpool_str1387[sizeof("net.tm")];
-    char stringpool_str1388[sizeof("artdeco.museum")];
-    char stringpool_str1389[sizeof("uozu.toyama.jp")];
-    char stringpool_str1390[sizeof("com.tm")];
-    char stringpool_str1391[sizeof("gov.tm")];
-    char stringpool_str1392[sizeof("valle-aosta.it")];
-    char stringpool_str1393[sizeof("nom.tm")];
-    char stringpool_str1394[sizeof("xn--ngbc5azd")];
-    char stringpool_str1395[sizeof("lyngdal.no")];
-    char stringpool_str1396[sizeof("kiwi")];
-    char stringpool_str1397[sizeof("cesenaforli.it")];
-    char stringpool_str1398[sizeof("eisenbahn.museum")];
-    char stringpool_str1399[sizeof("gniezno.pl")];
-    char stringpool_str1400[sizeof("ventures")];
-    char stringpool_str1401[sizeof("xn--snes-poa.no")];
-    char stringpool_str1402[sizeof("kristiansand.no")];
-    char stringpool_str1403[sizeof("country")];
-    char stringpool_str1404[sizeof("dz")];
-    char stringpool_str1405[sizeof("koganei.tokyo.jp")];
-    char stringpool_str1406[sizeof("hazu.aichi.jp")];
-    char stringpool_str1407[sizeof("edu.bh")];
-    char stringpool_str1408[sizeof("chtr.k12.ma.us")];
-    char stringpool_str1409[sizeof("jefferson.museum")];
-    char stringpool_str1410[sizeof("edu.tm")];
-    char stringpool_str1411[sizeof("viajes")];
-    char stringpool_str1412[sizeof("name.hr")];
-    char stringpool_str1413[sizeof("dm")];
-    char stringpool_str1414[sizeof("va.us")];
-    char stringpool_str1415[sizeof("valleeaoste.it")];
-    char stringpool_str1416[sizeof("co.lc")];
-    char stringpool_str1417[sizeof("gouv.ml")];
-    char stringpool_str1418[sizeof("dad")];
-    char stringpool_str1419[sizeof("dance")];
-    char stringpool_str1420[sizeof("hyllestad.no")];
-    char stringpool_str1421[sizeof("nc.us")];
-    char stringpool_str1422[sizeof("vic.au")];
-    char stringpool_str1423[sizeof("casadelamoneda.museum")];
-    char stringpool_str1424[sizeof("osen.no")];
-    char stringpool_str1425[sizeof("bargains")];
-    char stringpool_str1426[sizeof("nakhodka.ru")];
-    char stringpool_str1427[sizeof("dabur")];
-    char stringpool_str1428[sizeof("katsushika.tokyo.jp")];
-    char stringpool_str1429[sizeof("vt.us")];
-    char stringpool_str1430[sizeof("kristiansund.no")];
-    char stringpool_str1431[sizeof("ina.saitama.jp")];
-    char stringpool_str1432[sizeof("univ.sn")];
-    char stringpool_str1433[sizeof("name.my")];
-    char stringpool_str1434[sizeof("int.ci")];
-    char stringpool_str1435[sizeof("valledaosta.it")];
-    char stringpool_str1436[sizeof("cg")];
-    char stringpool_str1437[sizeof("bg")];
-    char stringpool_str1438[sizeof("kg")];
-    char stringpool_str1439[sizeof("gg")];
-    char stringpool_str1440[sizeof("ng")];
-    char stringpool_str1441[sizeof("benevento.it")];
-    char stringpool_str1442[sizeof("org.ci")];
-    char stringpool_str1443[sizeof("isa.kagoshima.jp")];
-    char stringpool_str1444[sizeof("workinggroup.aero")];
-    char stringpool_str1445[sizeof("net.im")];
-    char stringpool_str1446[sizeof("net.gt")];
-    char stringpool_str1447[sizeof("net.gp")];
-    char stringpool_str1448[sizeof("yazu.tottori.jp")];
-    char stringpool_str1449[sizeof("net.gr")];
-    char stringpool_str1450[sizeof("com.im")];
-    char stringpool_str1451[sizeof("com.gt")];
-    char stringpool_str1452[sizeof("com.gp")];
-    char stringpool_str1453[sizeof("co.gy")];
-    char stringpool_str1454[sizeof("com.gr")];
-    char stringpool_str1455[sizeof("kuzumaki.iwate.jp")];
-    char stringpool_str1456[sizeof("gov.gr")];
-    char stringpool_str1457[sizeof("bialystok.pl")];
-    char stringpool_str1458[sizeof("codespot.com")];
-    char stringpool_str1459[sizeof("y.bg")];
-    char stringpool_str1460[sizeof("eg")];
-    char stringpool_str1461[sizeof("org.dm")];
-    char stringpool_str1462[sizeof("judaica.museum")];
-    char stringpool_str1463[sizeof("us.org")];
-    char stringpool_str1464[sizeof("kitakami.iwate.jp")];
-    char stringpool_str1465[sizeof("gob.gt")];
-    char stringpool_str1466[sizeof("americanart.museum")];
-    char stringpool_str1467[sizeof("org.om")];
-    char stringpool_str1468[sizeof("net.gn")];
-    char stringpool_str1469[sizeof("dnp")];
-    char stringpool_str1470[sizeof("ascolipiceno.it")];
-    char stringpool_str1471[sizeof("com.gn")];
-    char stringpool_str1472[sizeof("viterbo.it")];
-    char stringpool_str1473[sizeof("gov.gn")];
-    char stringpool_str1474[sizeof("omi.nagano.jp")];
-    char stringpool_str1475[sizeof("naka.ibaraki.jp")];
-    char stringpool_str1476[sizeof("re")];
-    char stringpool_str1477[sizeof("ren")];
-    char stringpool_str1478[sizeof("xn--yer-zna.no")];
-    char stringpool_str1479[sizeof("ro")];
-    char stringpool_str1480[sizeof("odo.br")];
-    char stringpool_str1481[sizeof("rs")];
-    char stringpool_str1482[sizeof("net.bm")];
-    char stringpool_str1483[sizeof("jewelry.museum")];
-    char stringpool_str1484[sizeof("com.bm")];
-    char stringpool_str1485[sizeof("gov.bm")];
-    char stringpool_str1486[sizeof("edu.gt")];
-    char stringpool_str1487[sizeof("brescia.it")];
-    char stringpool_str1488[sizeof("edu.gp")];
-    char stringpool_str1489[sizeof("land-4-sale.us")];
-    char stringpool_str1490[sizeof("edu.gr")];
-    char stringpool_str1491[sizeof("gran.no")];
-    char stringpool_str1492[sizeof("championship.aero")];
-    char stringpool_str1493[sizeof("jelenia-gora.pl")];
-    char stringpool_str1494[sizeof("niigata.jp")];
-    char stringpool_str1495[sizeof("dk")];
-    char stringpool_str1496[sizeof("xn--mli-tla.no")];
-    char stringpool_str1497[sizeof("chel.ru")];
-    char stringpool_str1498[sizeof("orkanger.no")];
-    char stringpool_str1499[sizeof("is-a-painter.com")];
-    char stringpool_str1500[sizeof("com.km")];
-    char stringpool_str1501[sizeof("gov.km")];
-    char stringpool_str1502[sizeof("edu.gn")];
-    char stringpool_str1503[sizeof("nom.km")];
-    char stringpool_str1504[sizeof("bo.telemark.no")];
-    char stringpool_str1505[sizeof("naturalhistory.museum")];
-    char stringpool_str1506[sizeof("kitaura.miyazaki.jp")];
-    char stringpool_str1507[sizeof("usa.oita.jp")];
-    char stringpool_str1508[sizeof("ac.me")];
-    char stringpool_str1509[sizeof("kawanehon.shizuoka.jp")];
-    char stringpool_str1510[sizeof("vi.us")];
-    char stringpool_str1511[sizeof("ac.se")];
-    char stringpool_str1512[sizeof("australia.museum")];
-    char stringpool_str1513[sizeof("xn--rland-uua.no")];
-    char stringpool_str1514[sizeof("assassination.museum")];
-    char stringpool_str1515[sizeof("xn--uc0ay4a.hk")];
-    char stringpool_str1516[sizeof("ggee")];
-    char stringpool_str1517[sizeof("kashiwara.osaka.jp")];
-    char stringpool_str1518[sizeof("org.bh")];
-    char stringpool_str1519[sizeof("k-uralsk.ru")];
-    char stringpool_str1520[sizeof("edu.bm")];
-    char stringpool_str1521[sizeof("ac.ae")];
-    char stringpool_str1522[sizeof("venezia.it")];
-    char stringpool_str1523[sizeof("lancashire.museum")];
-    char stringpool_str1524[sizeof("org.tm")];
-    char stringpool_str1525[sizeof("chiyoda.tokyo.jp")];
-    char stringpool_str1526[sizeof("xn--mely-ira.no")];
-    char stringpool_str1527[sizeof("babia-gora.pl")];
-    char stringpool_str1528[sizeof("bc.ca")];
-    char stringpool_str1529[sizeof("gc.ca")];
-    char stringpool_str1530[sizeof("convent.museum")];
-    char stringpool_str1531[sizeof("xn--80adxhks")];
-    char stringpool_str1532[sizeof("net.ge")];
-    char stringpool_str1533[sizeof("edu.km")];
-    char stringpool_str1534[sizeof("xn--asky-ira.no")];
-    char stringpool_str1535[sizeof("is-a-cpa.com")];
-    char stringpool_str1536[sizeof("com.ge")];
-    char stringpool_str1537[sizeof("khakassia.ru")];
-    char stringpool_str1538[sizeof("gov.ge")];
-    char stringpool_str1539[sizeof("v.bg")];
-    char stringpool_str1540[sizeof("ac.tj")];
-    char stringpool_str1541[sizeof("ag")];
-    char stringpool_str1542[sizeof("d.se")];
-    char stringpool_str1543[sizeof("atlanta.museum")];
-    char stringpool_str1544[sizeof("red")];
-    char stringpool_str1545[sizeof("kongsberg.no")];
-    char stringpool_str1546[sizeof("nuremberg.museum")];
-    char stringpool_str1547[sizeof("email")];
-    char stringpool_str1548[sizeof("conf.au")];
-    char stringpool_str1549[sizeof("is-an-actress.com")];
-    char stringpool_str1550[sizeof("ac.ma")];
-    char stringpool_str1551[sizeof("vn.ua")];
-    char stringpool_str1552[sizeof("os.hedmark.no")];
-    char stringpool_str1553[sizeof("chernigov.ua")];
-    char stringpool_str1554[sizeof("info.tz")];
-    char stringpool_str1555[sizeof("warszawa.pl")];
-    char stringpool_str1556[sizeof("ru")];
-    char stringpool_str1557[sizeof("yaroslavl.ru")];
-    char stringpool_str1558[sizeof("kviteseid.no")];
-    char stringpool_str1559[sizeof("budejju.no")];
-    char stringpool_str1560[sizeof("ueda.nagano.jp")];
-    char stringpool_str1561[sizeof("nichinan.tottori.jp")];
-    char stringpool_str1562[sizeof("yachts")];
-    char stringpool_str1563[sizeof("edu.ge")];
-    char stringpool_str1564[sizeof("cooking")];
-    char stringpool_str1565[sizeof("xn--wgbl6a")];
-    char stringpool_str1566[sizeof("omsk.ru")];
-    char stringpool_str1567[sizeof("hanamaki.iwate.jp")];
-    char stringpool_str1568[sizeof("kawahara.tottori.jp")];
-    char stringpool_str1569[sizeof("illustration.museum")];
-    char stringpool_str1570[sizeof("report")];
-    char stringpool_str1571[sizeof("leksvik.no")];
-    char stringpool_str1572[sizeof("ac.at")];
-    char stringpool_str1573[sizeof("rel.pl")];
-    char stringpool_str1574[sizeof("yk.ca")];
-    char stringpool_str1575[sizeof("isleofman.museum")];
-    char stringpool_str1576[sizeof("name.mk")];
-    char stringpool_str1577[sizeof("agro.pl")];
-    char stringpool_str1578[sizeof("xn--od0aq3b.hk")];
-    char stringpool_str1579[sizeof("ac.mu")];
-    char stringpool_str1580[sizeof("history.museum")];
-    char stringpool_str1581[sizeof("vaksdal.no")];
-    char stringpool_str1582[sizeof("neat-url.com")];
-    char stringpool_str1583[sizeof("aya.miyazaki.jp")];
-    char stringpool_str1584[sizeof("org.im")];
-    char stringpool_str1585[sizeof("org.gt")];
-    char stringpool_str1586[sizeof("org.gp")];
-    char stringpool_str1587[sizeof("bungotakada.oita.jp")];
-    char stringpool_str1588[sizeof("amur.ru")];
-    char stringpool_str1589[sizeof("org.gr")];
-    char stringpool_str1590[sizeof("kishiwada.osaka.jp")];
-    char stringpool_str1591[sizeof("ac.sz")];
-    char stringpool_str1592[sizeof("amli.no")];
-    char stringpool_str1593[sizeof("giessen.museum")];
-    char stringpool_str1594[sizeof("childrens.museum")];
-    char stringpool_str1595[sizeof("hiranai.aomori.jp")];
-    char stringpool_str1596[sizeof("kagamino.okayama.jp")];
-    char stringpool_str1597[sizeof("joshkar-ola.ru")];
-    char stringpool_str1598[sizeof("org.gn")];
-    char stringpool_str1599[sizeof("wv.us")];
-    char stringpool_str1600[sizeof("kunstunddesign.museum")];
-    char stringpool_str1601[sizeof("co.id")];
-    char stringpool_str1602[sizeof("go.id")];
-    char stringpool_str1603[sizeof("nsw.edu.au")];
-    char stringpool_str1604[sizeof("bio.br")];
-    char stringpool_str1605[sizeof("rodeo")];
-    char stringpool_str1606[sizeof("wada.nagano.jp")];
-    char stringpool_str1607[sizeof("ac.tz")];
-    char stringpool_str1608[sizeof("bajddar.no")];
-    char stringpool_str1609[sizeof("gouv.ht")];
-    char stringpool_str1610[sizeof("hashikami.aomori.jp")];
-    char stringpool_str1611[sizeof("carrier.museum")];
-    char stringpool_str1612[sizeof("org.bm")];
-    char stringpool_str1613[sizeof("lincoln.museum")];
-    char stringpool_str1614[sizeof("bashkiria.ru")];
-    char stringpool_str1615[sizeof("noda.chiba.jp")];
-    char stringpool_str1616[sizeof("xn--55qx5d.hk")];
-    char stringpool_str1617[sizeof("ato.br")];
-    char stringpool_str1618[sizeof("yn.cn")];
-    char stringpool_str1619[sizeof("xn--lcvr32d.hk")];
-    char stringpool_str1620[sizeof("xn--45q11c")];
-    char stringpool_str1621[sizeof("rana.no")];
-    char stringpool_str1622[sizeof("is-an-artist.com")];
-    char stringpool_str1623[sizeof("ac.cr")];
-    char stringpool_str1624[sizeof("amot.no")];
-    char stringpool_str1625[sizeof("repair")];
-    char stringpool_str1626[sizeof("org.km")];
-    char stringpool_str1627[sizeof("construction")];
-    char stringpool_str1628[sizeof("rest")];
-    char stringpool_str1629[sizeof("birdart.museum")];
-    char stringpool_str1630[sizeof("ibaraki.ibaraki.jp")];
-    char stringpool_str1631[sizeof("certification.aero")];
-    char stringpool_str1632[sizeof("historisches.museum")];
-    char stringpool_str1633[sizeof("blackfriday")];
-    char stringpool_str1634[sizeof("xn--lgrd-poac.no")];
-    char stringpool_str1635[sizeof("imakane.hokkaido.jp")];
-    char stringpool_str1636[sizeof("ami.ibaraki.jp")];
-    char stringpool_str1637[sizeof("lighting")];
-    char stringpool_str1638[sizeof("hamburg.museum")];
-    char stringpool_str1639[sizeof("vang.no")];
-    char stringpool_str1640[sizeof("xn--6qq986b3xl")];
-    char stringpool_str1641[sizeof("ind.gt")];
-    char stringpool_str1642[sizeof("asso.dz")];
-    char stringpool_str1643[sizeof("kai.yamanashi.jp")];
-    char stringpool_str1644[sizeof("xn--3e0b707e")];
-    char stringpool_str1645[sizeof("ac.rs")];
-    char stringpool_str1646[sizeof("kumejima.okinawa.jp")];
-    char stringpool_str1647[sizeof("xn--zfr164b")];
-    char stringpool_str1648[sizeof("nonoichi.ishikawa.jp")];
-    char stringpool_str1649[sizeof("kembuchi.hokkaido.jp")];
-    char stringpool_str1650[sizeof("nuernberg.museum")];
-    char stringpool_str1651[sizeof("ac.kr")];
-    char stringpool_str1652[sizeof("ce.it")];
-    char stringpool_str1653[sizeof("ge.it")];
-    char stringpool_str1654[sizeof("asaminami.hiroshima.jp")];
-    char stringpool_str1655[sizeof("xn--lury-ira.no")];
-    char stringpool_str1656[sizeof("vallee-aoste.it")];
-    char stringpool_str1657[sizeof("or.id")];
-    char stringpool_str1658[sizeof("co.it")];
-    char stringpool_str1659[sizeof("bo.it")];
-    char stringpool_str1660[sizeof("go.it")];
-    char stringpool_str1661[sizeof("id.ir")];
-    char stringpool_str1662[sizeof("cs.it")];
-    char stringpool_str1663[sizeof("bs.it")];
-    char stringpool_str1664[sizeof("omaezaki.shizuoka.jp")];
-    char stringpool_str1665[sizeof("rep.kp")];
-    char stringpool_str1666[sizeof("no.it")];
-    char stringpool_str1667[sizeof("is.it")];
-    char stringpool_str1668[sizeof("xn--srfold-bya.no")];
-    char stringpool_str1669[sizeof("name.az")];
-    char stringpool_str1670[sizeof("org.ge")];
-    char stringpool_str1671[sizeof("co.ir")];
-    char stringpool_str1672[sizeof("ggf.br")];
-    char stringpool_str1673[sizeof("info.au")];
-    char stringpool_str1674[sizeof("hatoyama.saitama.jp")];
-    char stringpool_str1675[sizeof("collection.museum")];
-    char stringpool_str1676[sizeof("culture.museum")];
-    char stringpool_str1677[sizeof("kashiwa.chiba.jp")];
-    char stringpool_str1678[sizeof("holiday")];
-    char stringpool_str1679[sizeof("oyamazaki.kyoto.jp")];
-    char stringpool_str1680[sizeof("oshu.iwate.jp")];
-    char stringpool_str1681[sizeof("khmelnytskyi.ua")];
-    char stringpool_str1682[sizeof("noshiro.akita.jp")];
-    char stringpool_str1683[sizeof("birthplace.museum")];
-    char stringpool_str1684[sizeof("bologna.it")];
-    char stringpool_str1685[sizeof("hinohara.tokyo.jp")];
-    char stringpool_str1686[sizeof("kamchatka.ru")];
-    char stringpool_str1687[sizeof("is-a-lawyer.com")];
-    char stringpool_str1688[sizeof("gjerdrum.no")];
-    char stringpool_str1689[sizeof("valled-aosta.it")];
-    char stringpool_str1690[sizeof("ac.vn")];
-    char stringpool_str1691[sizeof("yakutia.ru")];
-    char stringpool_str1692[sizeof("is-a-llama.com")];
-    char stringpool_str1693[sizeof("gorizia.it")];
-    char stringpool_str1694[sizeof("r.se")];
-    char stringpool_str1695[sizeof("dagestan.ru")];
-    char stringpool_str1696[sizeof("okegawa.saitama.jp")];
-    char stringpool_str1697[sizeof("ath.cx")];
-    char stringpool_str1698[sizeof("ac.ci")];
-    char stringpool_str1699[sizeof("agr.br")];
-    char stringpool_str1700[sizeof("logistics.aero")];
-    char stringpool_str1701[sizeof("info.sd")];
-    char stringpool_str1702[sizeof("ontario.museum")];
-    char stringpool_str1703[sizeof("bokn.no")];
-    char stringpool_str1704[sizeof("ca.it")];
-    char stringpool_str1705[sizeof("ba.it")];
-    char stringpool_str1706[sizeof("norilsk.ru")];
-    char stringpool_str1707[sizeof("chiyoda.gunma.jp")];
-    char stringpool_str1708[sizeof("ac.cn")];
-    char stringpool_str1709[sizeof("na.it")];
-    char stringpool_str1710[sizeof("christmas")];
-    char stringpool_str1711[sizeof("rnu.tn")];
-    char stringpool_str1712[sizeof("xn--osyro-wua.no")];
-    char stringpool_str1713[sizeof("le.it")];
-    char stringpool_str1714[sizeof("co.im")];
-    char stringpool_str1715[sizeof("kitadaito.okinawa.jp")];
-    char stringpool_str1716[sizeof("assn.lk")];
-    char stringpool_str1717[sizeof("td")];
-    char stringpool_str1718[sizeof("de.us")];
-    char stringpool_str1719[sizeof("chernihiv.ua")];
-    char stringpool_str1720[sizeof("lo.it")];
-    char stringpool_str1721[sizeof("to")];
-    char stringpool_str1722[sizeof("co.no")];
-    char stringpool_str1723[sizeof("xn--nry-yla5g.no")];
-    char stringpool_str1724[sizeof("tj")];
-    char stringpool_str1725[sizeof("ot.it")];
-    char stringpool_str1726[sizeof("ct.it")];
-    char stringpool_str1727[sizeof("bt.it")];
-    char stringpool_str1728[sizeof("tp")];
-    char stringpool_str1729[sizeof("or.it")];
-    char stringpool_str1730[sizeof("cr.it")];
-    char stringpool_str1731[sizeof("name.mv")];
-    char stringpool_str1732[sizeof("br.it")];
-    char stringpool_str1733[sizeof("aero.mv")];
-    char stringpool_str1734[sizeof("kr.it")];
-    char stringpool_str1735[sizeof("gr.it")];
-    char stringpool_str1736[sizeof("aurland.no")];
-    char stringpool_str1737[sizeof("ac.ru")];
-    char stringpool_str1738[sizeof("ac.be")];
-    char stringpool_str1739[sizeof("vacations")];
-    char stringpool_str1740[sizeof("ass.km")];
-    char stringpool_str1741[sizeof("com.gi")];
-    char stringpool_str1742[sizeof("is-a-rockstar.com")];
-    char stringpool_str1743[sizeof("gov.gi")];
-    char stringpool_str1744[sizeof("operaunite.com")];
-    char stringpool_str1745[sizeof("izhevsk.ru")];
-    char stringpool_str1746[sizeof("kawanishi.nara.jp")];
-    char stringpool_str1747[sizeof("jp.net")];
-    char stringpool_str1748[sizeof("barlettatraniandria.it")];
-    char stringpool_str1749[sizeof("xn--90a3ac")];
-    char stringpool_str1750[sizeof("nu.it")];
-    char stringpool_str1751[sizeof("co.in")];
-    char stringpool_str1752[sizeof("iki.nagasaki.jp")];
-    char stringpool_str1753[sizeof("leirvik.no")];
-    char stringpool_str1754[sizeof("rost.no")];
-    char stringpool_str1755[sizeof("rade.no")];
-    char stringpool_str1756[sizeof("xn--tn0ag.hk")];
-    char stringpool_str1757[sizeof("vc")];
-    char stringpool_str1758[sizeof("watarai.mie.jp")];
-    char stringpool_str1759[sizeof("cz.it")];
-    char stringpool_str1760[sizeof("bz.it")];
-    char stringpool_str1761[sizeof("globo")];
-    char stringpool_str1762[sizeof("iamallama.com")];
-    char stringpool_str1763[sizeof("eigersund.no")];
-    char stringpool_str1764[sizeof("info.ht")];
-    char stringpool_str1765[sizeof("vestre-toten.no")];
-    char stringpool_str1766[sizeof("co.na")];
-    char stringpool_str1767[sizeof("xn--45brj9c")];
-    char stringpool_str1768[sizeof("walbrzych.pl")];
-    char stringpool_str1769[sizeof("wakayama.jp")];
-    char stringpool_str1770[sizeof("ao.it")];
-    char stringpool_str1771[sizeof("urakawa.hokkaido.jp")];
-    char stringpool_str1772[sizeof("akabira.hokkaido.jp")];
-    char stringpool_str1773[sizeof("za.net")];
-    char stringpool_str1774[sizeof("net.gg")];
-    char stringpool_str1775[sizeof("arendal.no")];
-    char stringpool_str1776[sizeof("dp.ua")];
-    char stringpool_str1777[sizeof("ap.it")];
-    char stringpool_str1778[sizeof("res.in")];
-    char stringpool_str1779[sizeof("akiruno.tokyo.jp")];
-    char stringpool_str1780[sizeof("xn--s9brj9c")];
-    char stringpool_str1781[sizeof("edu.gi")];
-    char stringpool_str1782[sizeof("im.it")];
-    char stringpool_str1783[sizeof("xn--troms-zua.no")];
-    char stringpool_str1784[sizeof("okayama.jp")];
-    char stringpool_str1785[sizeof("lt.it")];
-    char stringpool_str1786[sizeof("tt")];
-    char stringpool_str1787[sizeof("kunstsammlung.museum")];
-    char stringpool_str1788[sizeof("nt.no")];
-    char stringpool_str1789[sizeof("tr")];
-    char stringpool_str1790[sizeof("val-d-aosta.it")];
-    char stringpool_str1791[sizeof("info.az")];
-    char stringpool_str1792[sizeof("zhytomyr.ua")];
-    char stringpool_str1793[sizeof("ac.th")];
-    char stringpool_str1794[sizeof("rw")];
-    char stringpool_str1795[sizeof("crotone.it")];
-    char stringpool_str1796[sizeof("no.com")];
-    char stringpool_str1797[sizeof("augustow.pl")];
-    char stringpool_str1798[sizeof("koshigaya.saitama.jp")];
-    char stringpool_str1799[sizeof("gateway.museum")];
-    char stringpool_str1800[sizeof("kokubunji.tokyo.jp")];
-    char stringpool_str1801[sizeof("xn--wcvs22d.hk")];
-    char stringpool_str1802[sizeof("isehara.kanagawa.jp")];
-    char stringpool_str1803[sizeof("rnd.ru")];
-    char stringpool_str1804[sizeof("katsuragi.wakayama.jp")];
-    char stringpool_str1805[sizeof("lu.it")];
-    char stringpool_str1806[sizeof("trade")];
-    char stringpool_str1807[sizeof("ci.it")];
-    char stringpool_str1808[sizeof("gyeongnam.kr")];
-    char stringpool_str1809[sizeof("bi.it")];
-    char stringpool_str1810[sizeof("americanantiques.museum")];
-    char stringpool_str1811[sizeof("bu.no")];
-    char stringpool_str1812[sizeof("ca.na")];
-    char stringpool_str1813[sizeof("asso.ht")];
-    char stringpool_str1814[sizeof("oishida.yamagata.jp")];
-    char stringpool_str1815[sizeof("hirakata.osaka.jp")];
-    char stringpool_str1816[sizeof("xn--trany-yua.no")];
-    char stringpool_str1817[sizeof("erotika.hu")];
-    char stringpool_str1818[sizeof("cn.it")];
-    char stringpool_str1819[sizeof("ac.jp")];
-    char stringpool_str1820[sizeof("bn.it")];
-    char stringpool_str1821[sizeof("qc.ca")];
-    char stringpool_str1822[sizeof("gx.cn")];
-    char stringpool_str1823[sizeof("tz")];
-    char stringpool_str1824[sizeof("tel")];
-    char stringpool_str1825[sizeof("nx.cn")];
-    char stringpool_str1826[sizeof("erotica.hu")];
-    char stringpool_str1827[sizeof("rocks")];
-    char stringpool_str1828[sizeof("abo.pa")];
-    char stringpool_str1829[sizeof("city.kawasaki.jp")];
-    char stringpool_str1830[sizeof("xn--trna-woa.no")];
-    char stringpool_str1831[sizeof("xn--unjrga-rta.no")];
-    char stringpool_str1832[sizeof("at.it")];
-    char stringpool_str1833[sizeof("en.it")];
-    char stringpool_str1834[sizeof("or.na")];
-    char stringpool_str1835[sizeof("ac.mw")];
-    char stringpool_str1836[sizeof("ar.it")];
-    char stringpool_str1837[sizeof("www.ck")];
-    char stringpool_str1838[sizeof("tm")];
-    char stringpool_str1839[sizeof("aosta-valley.it")];
-    char stringpool_str1840[sizeof("nagahama.shiga.jp")];
-    char stringpool_str1841[sizeof("valleaosta.it")];
-    char stringpool_str1842[sizeof("yoshino.nara.jp")];
-    char stringpool_str1843[sizeof("jx.cn")];
-    char stringpool_str1844[sizeof("cb.it")];
-    char stringpool_str1845[sizeof("rel.ht")];
-    char stringpool_str1846[sizeof("xn--snsa-roa.no")];
-    char stringpool_str1847[sizeof("worse-than.tv")];
-    char stringpool_str1848[sizeof("avellino.it")];
-    char stringpool_str1849[sizeof("jevnaker.no")];
-    char stringpool_str1850[sizeof("rns.tn")];
-    char stringpool_str1851[sizeof("za.com")];
-    char stringpool_str1852[sizeof("city.kitakyushu.jp")];
-    char stringpool_str1853[sizeof("cologne")];
-    char stringpool_str1854[sizeof("uki.kumamoto.jp")];
-    char stringpool_str1855[sizeof("info.mv")];
-    char stringpool_str1856[sizeof("chuo.chiba.jp")];
-    char stringpool_str1857[sizeof("res.aero")];
-    char stringpool_str1858[sizeof("eu.int")];
-    char stringpool_str1859[sizeof("journalism.museum")];
-    char stringpool_str1860[sizeof("tom.ru")];
-    char stringpool_str1861[sizeof("travel")];
-    char stringpool_str1862[sizeof("ujitawara.kyoto.jp")];
-    char stringpool_str1863[sizeof("cherkasy.ua")];
-    char stringpool_str1864[sizeof("nikolaev.ua")];
-    char stringpool_str1865[sizeof("tur.ar")];
-    char stringpool_str1866[sizeof("xn--yfro4i67o")];
-    char stringpool_str1867[sizeof("ne.ug")];
-    char stringpool_str1868[sizeof("ravenna.it")];
-    char stringpool_str1869[sizeof("br.com")];
-    char stringpool_str1870[sizeof("kr.com")];
-    char stringpool_str1871[sizeof("gr.com")];
-    char stringpool_str1872[sizeof("li.it")];
-    char stringpool_str1873[sizeof("co.ug")];
-    char stringpool_str1874[sizeof("go.ug")];
-    char stringpool_str1875[sizeof("drammen.no")];
-    char stringpool_str1876[sizeof("overhalla.no")];
-    char stringpool_str1877[sizeof("aa.no")];
-    char stringpool_str1878[sizeof("tn")];
-    char stringpool_str1879[sizeof("okinawa")];
-    char stringpool_str1880[sizeof("kushiro.hokkaido.jp")];
-    char stringpool_str1881[sizeof("ureshino.mie.jp")];
-    char stringpool_str1882[sizeof("og.ao")];
-    char stringpool_str1883[sizeof("co.ag")];
-    char stringpool_str1884[sizeof("gushikami.okinawa.jp")];
-    char stringpool_str1885[sizeof("inashiki.ibaraki.jp")];
-    char stringpool_str1886[sizeof("lillehammer.no")];
-    char stringpool_str1887[sizeof("verbania.it")];
-    char stringpool_str1888[sizeof("consulting")];
-    char stringpool_str1889[sizeof("tips")];
-    char stringpool_str1890[sizeof("yokohama")];
-    char stringpool_str1891[sizeof("kami.kochi.jp")];
-    char stringpool_str1892[sizeof("davvesiida.no")];
-    char stringpool_str1893[sizeof("gotemba.shizuoka.jp")];
-    char stringpool_str1894[sizeof("xn--muost-0qa.no")];
-    char stringpool_str1895[sizeof("kiyosato.hokkaido.jp")];
-    char stringpool_str1896[sizeof("dni.us")];
-    char stringpool_str1897[sizeof("hatsukaichi.hiroshima.jp")];
-    char stringpool_str1898[sizeof("coldwar.museum")];
-    char stringpool_str1899[sizeof("cl.it")];
-    char stringpool_str1900[sizeof("bl.it")];
-    char stringpool_str1901[sizeof("rec.br")];
-    char stringpool_str1902[sizeof("xn--mxtq1m.hk")];
-    char stringpool_str1903[sizeof("dnsdojo.net")];
-    char stringpool_str1904[sizeof("bari.it")];
-    char stringpool_str1905[sizeof("webcam")];
-    char stringpool_str1906[sizeof("capebreton.museum")];
-    char stringpool_str1907[sizeof("ug")];
-    char stringpool_str1908[sizeof("british.museum")];
-    char stringpool_str1909[sizeof("unbi.ba")];
-    char stringpool_str1910[sizeof("tana.no")];
-    char stringpool_str1911[sizeof("gb.net")];
-    char stringpool_str1912[sizeof("org.gi")];
-    char stringpool_str1913[sizeof("eu.com")];
-    char stringpool_str1914[sizeof("d.bg")];
-    char stringpool_str1915[sizeof("yasu.shiga.jp")];
-    char stringpool_str1916[sizeof("wolomin.pl")];
-    char stringpool_str1917[sizeof("uno")];
-    char stringpool_str1918[sizeof("ikusaka.nagano.jp")];
-    char stringpool_str1919[sizeof("rnrt.tn")];
-    char stringpool_str1920[sizeof("cherkassy.ua")];
-    char stringpool_str1921[sizeof("is-an-accountant.com")];
-    char stringpool_str1922[sizeof("khmelnitskiy.ua")];
-    char stringpool_str1923[sizeof("naturalhistorymuseum.museum")];
-    char stringpool_str1924[sizeof("barletta-trani-andria.it")];
-    char stringpool_str1925[sizeof("wien")];
-    char stringpool_str1926[sizeof("chesapeakebay.museum")];
-    char stringpool_str1927[sizeof("kumenan.okayama.jp")];
-    char stringpool_str1928[sizeof("dn.ua")];
-    char stringpool_str1929[sizeof("an.it")];
-    char stringpool_str1930[sizeof("kafjord.no")];
-    char stringpool_str1931[sizeof("in.na")];
-    char stringpool_str1932[sizeof("tk")];
-    char stringpool_str1933[sizeof("gs.jan-mayen.no")];
-    char stringpool_str1934[sizeof("chernivtsi.ua")];
-    char stringpool_str1935[sizeof("audnedaln.no")];
-    char stringpool_str1936[sizeof("nishitosa.kochi.jp")];
-    char stringpool_str1937[sizeof("nord-aurdal.no")];
-    char stringpool_str1938[sizeof("hachijo.tokyo.jp")];
-    char stringpool_str1939[sizeof("alesund.no")];
-    char stringpool_str1940[sizeof("taa.it")];
-    char stringpool_str1941[sizeof("lucerne.museum")];
-    char stringpool_str1942[sizeof("ha.no")];
-    char stringpool_str1943[sizeof("org.gg")];
-    char stringpool_str1944[sizeof("la-spezia.it")];
-    char stringpool_str1945[sizeof("or.ug")];
-    char stringpool_str1946[sizeof("ltd.gi")];
-    char stringpool_str1947[sizeof("vevelstad.no")];
-    char stringpool_str1948[sizeof("wroc.pl")];
-    char stringpool_str1949[sizeof("kagoshima.jp")];
-    char stringpool_str1950[sizeof("cruises")];
-    char stringpool_str1951[sizeof("oi.kanagawa.jp")];
-    char stringpool_str1952[sizeof("dnsdojo.com")];
-    char stringpool_str1953[sizeof("cn.com")];
-    char stringpool_str1954[sizeof("bygland.no")];
-    char stringpool_str1955[sizeof("tl")];
-    char stringpool_str1956[sizeof("ol.no")];
-    char stringpool_str1957[sizeof("co.nl")];
-    char stringpool_str1958[sizeof("ch.it")];
-    char stringpool_str1959[sizeof("vicenza.it")];
-    char stringpool_str1960[sizeof("kosa.kumamoto.jp")];
-    char stringpool_str1961[sizeof("yokohama.jp")];
-    char stringpool_str1962[sizeof("is-lost.org")];
-    char stringpool_str1963[sizeof("nl.no")];
-    char stringpool_str1964[sizeof("is-very-good.org")];
-    char stringpool_str1965[sizeof("asti.it")];
-    char stringpool_str1966[sizeof("xn--rskog-uua.no")];
-    char stringpool_str1967[sizeof("in-the-band.net")];
-    char stringpool_str1968[sizeof("hu.net")];
-    char stringpool_str1969[sizeof("dontexist.net")];
-    char stringpool_str1970[sizeof("vestnes.no")];
-    char stringpool_str1971[sizeof("ar.com")];
-    char stringpool_str1972[sizeof("lg.ua")];
-    char stringpool_str1973[sizeof("arao.kumamoto.jp")];
-    char stringpool_str1974[sizeof("t.se")];
-    char stringpool_str1975[sizeof("xn--ygbi2ammx")];
-    char stringpool_str1976[sizeof("kanazawa.ishikawa.jp")];
-    char stringpool_str1977[sizeof("is-found.org")];
-    char stringpool_str1978[sizeof("is-a-socialist.com")];
-    char stringpool_str1979[sizeof("gb.com")];
-    char stringpool_str1980[sizeof("lodi.it")];
-    char stringpool_str1981[sizeof("xn--55qx5d.cn")];
-    char stringpool_str1982[sizeof("events")];
-    char stringpool_str1983[sizeof("xn--mgbaam7a8h")];
-    char stringpool_str1984[sizeof("xn--vard-jra.no")];
-    char stringpool_str1985[sizeof("bergamo")];
-    char stringpool_str1986[sizeof("ibestad.no")];
-    char stringpool_str1987[sizeof("geelvinck.museum")];
-    char stringpool_str1988[sizeof("al.it")];
-    char stringpool_str1989[sizeof("ac.rw")];
-    char stringpool_str1990[sizeof("kuki.saitama.jp")];
-    char stringpool_str1991[sizeof("tur.br")];
-    char stringpool_str1992[sizeof("xn--mjndalen-64a.no")];
-    char stringpool_str1993[sizeof("hm.no")];
-    char stringpool_str1994[sizeof("amusement.aero")];
-    char stringpool_str1995[sizeof("xn--mk0axi.hk")];
-    char stringpool_str1996[sizeof("tra.kp")];
-    char stringpool_str1997[sizeof("homeunix.com")];
-    char stringpool_str1998[sizeof("akishima.tokyo.jp")];
-    char stringpool_str1999[sizeof("game-server.cc")];
-    char stringpool_str2000[sizeof("azure-mobile.net")];
-    char stringpool_str2001[sizeof("yatsuka.shimane.jp")];
-    char stringpool_str2002[sizeof("western.museum")];
-    char stringpool_str2003[sizeof("th")];
-    char stringpool_str2004[sizeof("harstad.no")];
-    char stringpool_str2005[sizeof("rendalen.no")];
-    char stringpool_str2006[sizeof("xn--lt-liac.no")];
-    char stringpool_str2007[sizeof("architecture.museum")];
-    char stringpool_str2008[sizeof("xn--vg-yiab.no")];
-    char stringpool_str2009[sizeof("vald-aosta.it")];
-    char stringpool_str2010[sizeof("aq.it")];
-    char stringpool_str2011[sizeof("kutchan.hokkaido.jp")];
-    char stringpool_str2012[sizeof("xn--seral-lra.no")];
-    char stringpool_str2013[sizeof("noto.ishikawa.jp")];
-    char stringpool_str2014[sizeof("nieruchomosci.pl")];
-    char stringpool_str2015[sizeof("vindafjord.no")];
-    char stringpool_str2016[sizeof("czeladz.pl")];
-    char stringpool_str2017[sizeof("home.dyndns.org")];
-    char stringpool_str2018[sizeof("oga.akita.jp")];
-    char stringpool_str2019[sizeof("broke-it.net")];
-    char stringpool_str2020[sizeof("tos.it")];
-    char stringpool_str2021[sizeof("likescandy.com")];
-    char stringpool_str2022[sizeof("kg.kr")];
-    char stringpool_str2023[sizeof("tas.au")];
-    char stringpool_str2024[sizeof("whaling.museum")];
-    char stringpool_str2025[sizeof("chitose.hokkaido.jp")];
-    char stringpool_str2026[sizeof("gyeongbuk.kr")];
-    char stringpool_str2027[sizeof("is-a-candidate.org")];
-    char stringpool_str2028[sizeof("hu.com")];
-    char stringpool_str2029[sizeof("tmp.br")];
-    char stringpool_str2030[sizeof("kharkiv.ua")];
-    char stringpool_str2031[sizeof("broadcast.museum")];
-    char stringpool_str2032[sizeof("test.tj")];
-    char stringpool_str2033[sizeof("ri.us")];
-    char stringpool_str2034[sizeof("domains")];
-    char stringpool_str2035[sizeof("trd.br")];
-    char stringpool_str2036[sizeof("arboretum.museum")];
-    char stringpool_str2037[sizeof("time.no")];
-    char stringpool_str2038[sizeof("tokyo")];
-    char stringpool_str2039[sizeof("al.no")];
-    char stringpool_str2040[sizeof("xn--rde-ula.no")];
-    char stringpool_str2041[sizeof("khabarovsk.ru")];
-    char stringpool_str2042[sizeof("xn--p1acf")];
-    char stringpool_str2043[sizeof("xn--h2brj9c")];
-    char stringpool_str2044[sizeof("oumu.hokkaido.jp")];
-    char stringpool_str2045[sizeof("xn--kprw13d")];
-    char stringpool_str2046[sizeof("game-host.org")];
-    char stringpool_str2047[sizeof("xn--msy-ula0h.no")];
-    char stringpool_str2048[sizeof("grosseto.it")];
-    char stringpool_str2049[sizeof("oppegard.no")];
-    char stringpool_str2050[sizeof("castres.museum")];
-    char stringpool_str2051[sizeof("re.kr")];
-    char stringpool_str2052[sizeof("tw")];
-    char stringpool_str2053[sizeof("nannestad.no")];
-    char stringpool_str2054[sizeof("omi.niigata.jp")];
-    char stringpool_str2055[sizeof("yura.wakayama.jp")];
-    char stringpool_str2056[sizeof("nirasaki.yamanashi.jp")];
-    char stringpool_str2057[sizeof("eastafrica.museum")];
-    char stringpool_str2058[sizeof("onagawa.miyagi.jp")];
-    char stringpool_str2059[sizeof("opoczno.pl")];
-    char stringpool_str2060[sizeof("yamanashi.jp")];
-    char stringpool_str2061[sizeof("xn--mlatvuopmi-s4a.no")];
-    char stringpool_str2062[sizeof("herokuapp.com")];
-    char stringpool_str2063[sizeof("kui.hiroshima.jp")];
-    char stringpool_str2064[sizeof("imageandsound.museum")];
-    char stringpool_str2065[sizeof("r.bg")];
-    char stringpool_str2066[sizeof("omigawa.chiba.jp")];
-    char stringpool_str2067[sizeof("narusawa.yamanashi.jp")];
-    char stringpool_str2068[sizeof("kamioka.akita.jp")];
-    char stringpool_str2069[sizeof("xn--drbak-wua.no")];
-    char stringpool_str2070[sizeof("dontexist.org")];
-    char stringpool_str2071[sizeof("kanagawa.jp")];
-    char stringpool_str2072[sizeof("xn--zf0ao64a.tw")];
-    char stringpool_str2073[sizeof("cincinnati.museum")];
-    char stringpool_str2074[sizeof("abashiri.hokkaido.jp")];
-    char stringpool_str2075[sizeof("bato.tochigi.jp")];
-    char stringpool_str2076[sizeof("nowaruda.pl")];
-    char stringpool_str2077[sizeof("azumino.nagano.jp")];
-    char stringpool_str2078[sizeof("uzhgorod.ua")];
-    char stringpool_str2079[sizeof("association.aero")];
-    char stringpool_str2080[sizeof("chikusei.ibaraki.jp")];
-    char stringpool_str2081[sizeof("hiroshima.jp")];
-    char stringpool_str2082[sizeof("wiki")];
-    char stringpool_str2083[sizeof("legnica.pl")];
-    char stringpool_str2084[sizeof("repbody.aero")];
-    char stringpool_str2085[sizeof("hl.no")];
-    char stringpool_str2086[sizeof("ah.no")];
-    char stringpool_str2087[sizeof("xn--klbu-woa.no")];
-    char stringpool_str2088[sizeof("historisch.museum")];
-    char stringpool_str2089[sizeof("rentals")];
-    char stringpool_str2090[sizeof("arai.shizuoka.jp")];
-    char stringpool_str2091[sizeof("xn--kranghke-b0a.no")];
-    char stringpool_str2092[sizeof("grandrapids.museum")];
-    char stringpool_str2093[sizeof("egersund.no")];
-    char stringpool_str2094[sizeof("today")];
-    char stringpool_str2095[sizeof("okinawa.jp")];
-    char stringpool_str2096[sizeof("taranto.it")];
-    char stringpool_str2097[sizeof("wakkanai.hokkaido.jp")];
-    char stringpool_str2098[sizeof("engineer.aero")];
-    char stringpool_str2099[sizeof("nanmoku.gunma.jp")];
-    char stringpool_str2100[sizeof("aso.kumamoto.jp")];
-    char stringpool_str2101[sizeof("ud.it")];
-    char stringpool_str2102[sizeof("is-very-sweet.org")];
-    char stringpool_str2103[sizeof("vladikavkaz.ru")];
-    char stringpool_str2104[sizeof("iveland.no")];
-    char stringpool_str2105[sizeof("xn--czr694b")];
-    char stringpool_str2106[sizeof("kaga.ishikawa.jp")];
-    char stringpool_str2107[sizeof("toscana.it")];
-    char stringpool_str2108[sizeof("xn--j6w193g")];
-    char stringpool_str2109[sizeof("lombardy.it")];
-    char stringpool_str2110[sizeof("gov.cm")];
-    char stringpool_str2111[sizeof("qld.edu.au")];
-    char stringpool_str2112[sizeof("is-a-teacher.com")];
-    char stringpool_str2113[sizeof("obihiro.hokkaido.jp")];
-    char stringpool_str2114[sizeof("xn--sknit-yqa.no")];
-    char stringpool_str2115[sizeof("defense.tn")];
-    char stringpool_str2116[sizeof("roma.it")];
-    char stringpool_str2117[sizeof("tenkawa.nara.jp")];
-    char stringpool_str2118[sizeof("xn--vry-yla5g.no")];
-    char stringpool_str2119[sizeof("horokanai.hokkaido.jp")];
-    char stringpool_str2120[sizeof("xn--b-5ga.nordland.no")];
-    char stringpool_str2121[sizeof("kunisaki.oita.jp")];
-    char stringpool_str2122[sizeof("osakikamijima.hiroshima.jp")];
-    char stringpool_str2123[sizeof("historical.museum")];
-    char stringpool_str2124[sizeof("tsk.ru")];
-    char stringpool_str2125[sizeof("xn--risr-ira.no")];
-    char stringpool_str2126[sizeof("orenburg.ru")];
-    char stringpool_str2127[sizeof("xn--vgan-qoa.no")];
-    char stringpool_str2128[sizeof("kikonai.hokkaido.jp")];
-    char stringpool_str2129[sizeof("est-a-la-masion.com")];
-    char stringpool_str2130[sizeof("beauxarts.museum")];
-    char stringpool_str2131[sizeof("oregontrail.museum")];
-    char stringpool_str2132[sizeof("delmenhorst.museum")];
-    char stringpool_str2133[sizeof("xn--linds-pra.no")];
-    char stringpool_str2134[sizeof("uscountryestate.museum")];
-    char stringpool_str2135[sizeof("xn--b-5ga.telemark.no")];
-    char stringpool_str2136[sizeof("cheltenham.museum")];
-    char stringpool_str2137[sizeof("ota.gunma.jp")];
-    char stringpool_str2138[sizeof("ora.gunma.jp")];
-    char stringpool_str2139[sizeof("haugesund.no")];
-    char stringpool_str2140[sizeof("xn--uc0atv.hk")];
-    char stringpool_str2141[sizeof("bieszczady.pl")];
-    char stringpool_str2142[sizeof("xn--c1avg")];
-    char stringpool_str2143[sizeof("rich")];
-    char stringpool_str2144[sizeof("koebenhavn.museum")];
-    char stringpool_str2145[sizeof("rs.ba")];
-    char stringpool_str2146[sizeof("xn--kput3i")];
-    char stringpool_str2147[sizeof("te.ua")];
-    char stringpool_str2148[sizeof("klodzko.pl")];
-    char stringpool_str2149[sizeof("dyndns-home.com")];
-    char stringpool_str2150[sizeof("iwakura.aichi.jp")];
-    char stringpool_str2151[sizeof("rome.it")];
-    char stringpool_str2152[sizeof("is-a-bookkeeper.com")];
-    char stringpool_str2153[sizeof("treviso.it")];
-    char stringpool_str2154[sizeof("lombardia.it")];
-    char stringpool_str2155[sizeof("cahcesuolo.no")];
-    char stringpool_str2156[sizeof("historicalsociety.museum")];
-    char stringpool_str2157[sizeof("yekaterinburg.ru")];
-    char stringpool_str2158[sizeof("azurewebsites.net")];
-    char stringpool_str2159[sizeof("tuscany.it")];
-    char stringpool_str2160[sizeof("brumunddal.no")];
-    char stringpool_str2161[sizeof("ac.gn")];
-    char stringpool_str2162[sizeof("vestvagoy.no")];
-    char stringpool_str2163[sizeof("vg")];
-    char stringpool_str2164[sizeof("nasu.tochigi.jp")];
-    char stringpool_str2165[sizeof("does-it.net")];
-    char stringpool_str2166[sizeof("austrheim.no")];
-    char stringpool_str2167[sizeof("contemporary.museum")];
-    char stringpool_str2168[sizeof("tottori.jp")];
-    char stringpool_str2169[sizeof("lg.jp")];
-    char stringpool_str2170[sizeof("veterinaire.km")];
-    char stringpool_str2171[sizeof("toda.saitama.jp")];
-    char stringpool_str2172[sizeof("us.na")];
-    char stringpool_str2173[sizeof("himi.toyama.jp")];
-    char stringpool_str2174[sizeof("nagareyama.chiba.jp")];
-    char stringpool_str2175[sizeof("xn--sandy-yua.no")];
-    char stringpool_str2176[sizeof("democrat")];
-    char stringpool_str2177[sizeof("ws.na")];
-    char stringpool_str2178[sizeof("virtuel.museum")];
-    char stringpool_str2179[sizeof("chicago.museum")];
-    char stringpool_str2180[sizeof("academy")];
-    char stringpool_str2181[sizeof("realestate.pl")];
-    char stringpool_str2182[sizeof("emergency.aero")];
-    char stringpool_str2183[sizeof("komi.ru")];
-    char stringpool_str2184[sizeof("express.aero")];
-    char stringpool_str2185[sizeof("ryukyu")];
-    char stringpool_str2186[sizeof("donetsk.ua")];
-    char stringpool_str2187[sizeof("unjarga.no")];
-    char stringpool_str2188[sizeof("us.com")];
-    char stringpool_str2189[sizeof("nagaoka.niigata.jp")];
-    char stringpool_str2190[sizeof("blog.br")];
-    char stringpool_str2191[sizeof("tm.se")];
-    char stringpool_str2192[sizeof("ginowan.okinawa.jp")];
-    char stringpool_str2193[sizeof("xn--risa-5na.no")];
-    char stringpool_str2194[sizeof("val-daosta.it")];
-    char stringpool_str2195[sizeof("kure.hiroshima.jp")];
-    char stringpool_str2196[sizeof("homelinux.net")];
-    char stringpool_str2197[sizeof("trading.aero")];
-    char stringpool_str2198[sizeof("okutama.tokyo.jp")];
-    char stringpool_str2199[sizeof("cloudapp.net")];
-    char stringpool_str2200[sizeof("vao.it")];
-    char stringpool_str2201[sizeof("ogi.saga.jp")];
-    char stringpool_str2202[sizeof("wiki.br")];
-    char stringpool_str2203[sizeof("lodingen.no")];
-    char stringpool_str2204[sizeof("doesntexist.com")];
-    char stringpool_str2205[sizeof("ruhr")];
-    char stringpool_str2206[sizeof("ooshika.nagano.jp")];
-    char stringpool_str2207[sizeof("association.museum")];
-    char stringpool_str2208[sizeof("vision")];
-    char stringpool_str2209[sizeof("business")];
-    char stringpool_str2210[sizeof("blogspot.de")];
-    char stringpool_str2211[sizeof("tv")];
-    char stringpool_str2212[sizeof("yoshida.saitama.jp")];
-    char stringpool_str2213[sizeof("blogspot.se")];
-    char stringpool_str2214[sizeof("isen.kagoshima.jp")];
-    char stringpool_str2215[sizeof("news.hu")];
-    char stringpool_str2216[sizeof("tn.us")];
-    char stringpool_str2217[sizeof("british-library.uk")];
-    char stringpool_str2218[sizeof("yawatahama.ehime.jp")];
-    char stringpool_str2219[sizeof("torsken.no")];
-    char stringpool_str2220[sizeof("blogspot.jp")];
-    char stringpool_str2221[sizeof("andriabarlettatrani.it")];
-    char stringpool_str2222[sizeof("haga.tochigi.jp")];
-    char stringpool_str2223[sizeof("zama.kanagawa.jp")];
-    char stringpool_str2224[sizeof("hakusan.ishikawa.jp")];
-    char stringpool_str2225[sizeof("herokussl.com")];
-    char stringpool_str2226[sizeof("eco.br")];
-    char stringpool_str2227[sizeof("t.bg")];
-    char stringpool_str2228[sizeof("niikappu.hokkaido.jp")];
-    char stringpool_str2229[sizeof("voyage")];
-    char stringpool_str2230[sizeof("ama.shimane.jp")];
-    char stringpool_str2231[sizeof("tara.saga.jp")];
-    char stringpool_str2232[sizeof("xn--sr-aurdal-l8a.no")];
-    char stringpool_str2233[sizeof("av.it")];
-    char stringpool_str2234[sizeof("nichinan.miyazaki.jp")];
-    char stringpool_str2235[sizeof("nishinoshima.shimane.jp")];
-    char stringpool_str2236[sizeof("cranbrook.museum")];
-    char stringpool_str2237[sizeof("nakamura.kochi.jp")];
-    char stringpool_str2238[sizeof("volkenkunde.museum")];
-    char stringpool_str2239[sizeof("zhitomir.ua")];
-    char stringpool_str2240[sizeof("is-an-entertainer.com")];
-    char stringpool_str2241[sizeof("est-a-la-maison.com")];
-    char stringpool_str2242[sizeof("ogasawara.tokyo.jp")];
-    char stringpool_str2243[sizeof("blogspot.td")];
-    char stringpool_str2244[sizeof("blogspot.re")];
-    char stringpool_str2245[sizeof("tourism.tn")];
-    char stringpool_str2246[sizeof("kinokawa.wakayama.jp")];
-    char stringpool_str2247[sizeof("blogspot.ro")];
-    char stringpool_str2248[sizeof("blogspot.pt")];
-    char stringpool_str2249[sizeof("katagami.akita.jp")];
-    char stringpool_str2250[sizeof("kashihara.nara.jp")];
-    char stringpool_str2251[sizeof("bolt.hu")];
-    char stringpool_str2252[sizeof("uk.net")];
-    char stringpool_str2253[sizeof("homedns.org")];
-    char stringpool_str2254[sizeof("indianmarket.museum")];
-    char stringpool_str2255[sizeof("xn--lns-qla.museum")];
-    char stringpool_str2256[sizeof("tj.cn")];
-    char stringpool_str2257[sizeof("xn--mgbab2bd")];
-    char stringpool_str2258[sizeof("yotsukaido.chiba.jp")];
-    char stringpool_str2259[sizeof("at-band-camp.net")];
-    char stringpool_str2260[sizeof("olbiatempio.it")];
-    char stringpool_str2261[sizeof("kamiichi.toyama.jp")];
-    char stringpool_str2262[sizeof("randaberg.no")];
-    char stringpool_str2263[sizeof("andria-trani-barletta.it")];
-    char stringpool_str2264[sizeof("city.hu")];
-    char stringpool_str2265[sizeof("xn--wgbh1c")];
-    char stringpool_str2266[sizeof("kamijima.ehime.jp")];
-    char stringpool_str2267[sizeof("tadaoka.osaka.jp")];
-    char stringpool_str2268[sizeof("volgograd.ru")];
-    char stringpool_str2269[sizeof("kitayama.wakayama.jp")];
-    char stringpool_str2270[sizeof("homelinux.org")];
-    char stringpool_str2271[sizeof("kasumigaura.ibaraki.jp")];
-    char stringpool_str2272[sizeof("kyotango.kyoto.jp")];
-    char stringpool_str2273[sizeof("xn--s-1fa.no")];
-    char stringpool_str2274[sizeof("neyagawa.osaka.jp")];
-    char stringpool_str2275[sizeof("hachirogata.akita.jp")];
-    char stringpool_str2276[sizeof("kobayashi.miyazaki.jp")];
-    char stringpool_str2277[sizeof("iwaizumi.iwate.jp")];
-    char stringpool_str2278[sizeof("virtual.museum")];
-    char stringpool_str2279[sizeof("halloffame.museum")];
-    char stringpool_str2280[sizeof("kudoyama.wakayama.jp")];
-    char stringpool_str2281[sizeof("homeunix.org")];
-    char stringpool_str2282[sizeof("toyo.kochi.jp")];
-    char stringpool_str2283[sizeof("kusatsu.gunma.jp")];
-    char stringpool_str2284[sizeof("izu.shizuoka.jp")];
-    char stringpool_str2285[sizeof("kamisato.saitama.jp")];
-    char stringpool_str2286[sizeof("xn--karmy-yua.no")];
-    char stringpool_str2287[sizeof("kawakita.ishikawa.jp")];
-    char stringpool_str2288[sizeof("yatsushiro.kumamoto.jp")];
-    char stringpool_str2289[sizeof("kawaminami.miyazaki.jp")];
-    char stringpool_str2290[sizeof("naie.hokkaido.jp")];
-    char stringpool_str2291[sizeof("tm.fr")];
-    char stringpool_str2292[sizeof("hayakawa.yamanashi.jp")];
-    char stringpool_str2293[sizeof("tm.ro")];
-    char stringpool_str2294[sizeof("embetsu.hokkaido.jp")];
-    char stringpool_str2295[sizeof("hokkaido.jp")];
-    char stringpool_str2296[sizeof("xn--unup4y")];
-    char stringpool_str2297[sizeof("dielddanuorri.no")];
-    char stringpool_str2298[sizeof("anan.nagano.jp")];
-    char stringpool_str2299[sizeof("rec.nf")];
-    char stringpool_str2300[sizeof("riik.ee")];
-    char stringpool_str2301[sizeof("blogspot.ie")];
-    char stringpool_str2302[sizeof("okuizumo.shimane.jp")];
-    char stringpool_str2303[sizeof("xn--hery-ira.nordland.no")];
-    char stringpool_str2304[sizeof("tosu.saga.jp")];
-    char stringpool_str2305[sizeof("indiana.museum")];
-    char stringpool_str2306[sizeof("co.gg")];
-    char stringpool_str2307[sizeof("giehtavuoatna.no")];
-    char stringpool_str2308[sizeof("blogspot.no")];
-    char stringpool_str2309[sizeof("uk.com")];
-    char stringpool_str2310[sizeof("himeshima.oita.jp")];
-    char stringpool_str2311[sizeof("est-le-patron.com")];
-    char stringpool_str2312[sizeof("ve.it")];
-    char stringpool_str2313[sizeof("dnsalias.net")];
-    char stringpool_str2314[sizeof("is-a-nurse.com")];
-    char stringpool_str2315[sizeof("voting")];
-    char stringpool_str2316[sizeof("dynalias.net")];
-    char stringpool_str2317[sizeof("haibara.shizuoka.jp")];
-    char stringpool_str2318[sizeof("denmark.museum")];
-    char stringpool_str2319[sizeof("vs.it")];
-    char stringpool_str2320[sizeof("komatsu.ishikawa.jp")];
-    char stringpool_str2321[sizeof("blogspot.be")];
-    char stringpool_str2322[sizeof("hamatama.saga.jp")];
-    char stringpool_str2323[sizeof("aoki.nagano.jp")];
-    char stringpool_str2324[sizeof("church")];
-    char stringpool_str2325[sizeof("info.hu")];
-    char stringpool_str2326[sizeof("blogspot.mr")];
-    char stringpool_str2327[sizeof("blogspot.bj")];
-    char stringpool_str2328[sizeof("tm.km")];
-    char stringpool_str2329[sizeof("turystyka.pl")];
-    char stringpool_str2330[sizeof("lavagis.no")];
-    char stringpool_str2331[sizeof("dellogliastra.it")];
-    char stringpool_str2332[sizeof("is-a-student.com")];
-    char stringpool_str2333[sizeof("com.gh")];
-    char stringpool_str2334[sizeof("gov.gh")];
-    char stringpool_str2335[sizeof("hamamatsu.shizuoka.jp")];
-    char stringpool_str2336[sizeof("vennesla.no")];
-    char stringpool_str2337[sizeof("blogspot.dk")];
-    char stringpool_str2338[sizeof("naka.hiroshima.jp")];
-    char stringpool_str2339[sizeof("tama.tokyo.jp")];
-    char stringpool_str2340[sizeof("xn--stjrdalshalsen-sqb.no")];
-    char stringpool_str2341[sizeof("act.edu.au")];
-    char stringpool_str2342[sizeof("desi")];
-    char stringpool_str2343[sizeof("xn--krjohka-hwab49j.no")];
-    char stringpool_str2344[sizeof("blogspot.sk")];
-    char stringpool_str2345[sizeof("lajolla.museum")];
-    char stringpool_str2346[sizeof("ueno.gunma.jp")];
-    char stringpool_str2347[sizeof("blogspot.it")];
-    char stringpool_str2348[sizeof("anjo.aichi.jp")];
-    char stringpool_str2349[sizeof("uryu.hokkaido.jp")];
-    char stringpool_str2350[sizeof("ushuaia.museum")];
-    char stringpool_str2351[sizeof("kimobetsu.hokkaido.jp")];
-    char stringpool_str2352[sizeof("nishikatsura.yamanashi.jp")];
-    char stringpool_str2353[sizeof("va.it")];
-    char stringpool_str2354[sizeof("rv.ua")];
-    char stringpool_str2355[sizeof("bv.nl")];
-    char stringpool_str2356[sizeof("barreau.bj")];
-    char stringpool_str2357[sizeof("directory")];
-    char stringpool_str2358[sizeof("edu.gh")];
-    char stringpool_str2359[sizeof("hobby-site.com")];
-    char stringpool_str2360[sizeof("gs.svalbard.no")];
-    char stringpool_str2361[sizeof("vt.it")];
-    char stringpool_str2362[sizeof("tottori.tottori.jp")];
-    char stringpool_str2363[sizeof("kamikawa.saitama.jp")];
-    char stringpool_str2364[sizeof("ascoli-piceno.it")];
-    char stringpool_str2365[sizeof("yao.osaka.jp")];
-    char stringpool_str2366[sizeof("okayama.okayama.jp")];
-    char stringpool_str2367[sizeof("vr.it")];
-    char stringpool_str2368[sizeof("contemporaryart.museum")];
-    char stringpool_str2369[sizeof("agdenes.no")];
-    char stringpool_str2370[sizeof("bydgoszcz.pl")];
-    char stringpool_str2371[sizeof("xn--czru2d")];
-    char stringpool_str2372[sizeof("isshiki.aichi.jp")];
-    char stringpool_str2373[sizeof("ishikawa.jp")];
-    char stringpool_str2374[sizeof("aibetsu.hokkaido.jp")];
-    char stringpool_str2375[sizeof("is-very-bad.org")];
-    char stringpool_str2376[sizeof("is-a-personaltrainer.com")];
-    char stringpool_str2377[sizeof("kumagaya.saitama.jp")];
-    char stringpool_str2378[sizeof("tsuruta.aomori.jp")];
-    char stringpool_str2379[sizeof("nesoddtangen.no")];
-    char stringpool_str2380[sizeof("ac.id")];
-    char stringpool_str2381[sizeof("is-a-landscaper.com")];
-    char stringpool_str2382[sizeof("zentsuji.kagawa.jp")];
-    char stringpool_str2383[sizeof("granvin.no")];
-    char stringpool_str2384[sizeof("zaporizhzhia.ua")];
-    char stringpool_str2385[sizeof("uto.kumamoto.jp")];
-    char stringpool_str2386[sizeof("yabu.hyogo.jp")];
-    char stringpool_str2387[sizeof("vologda.ru")];
-    char stringpool_str2388[sizeof("indianapolis.museum")];
-    char stringpool_str2389[sizeof("tobe.ehime.jp")];
-    char stringpool_str2390[sizeof("kitakata.miyazaki.jp")];
-    char stringpool_str2391[sizeof("blogspot.kr")];
-    char stringpool_str2392[sizeof("yasuoka.nagano.jp")];
-    char stringpool_str2393[sizeof("tonsberg.no")];
-    char stringpool_str2394[sizeof("tosa.kochi.jp")];
-    char stringpool_str2395[sizeof("chichibu.saitama.jp")];
-    char stringpool_str2396[sizeof("uy.com")];
-    char stringpool_str2397[sizeof("va.no")];
-    char stringpool_str2398[sizeof("higashiosaka.osaka.jp")];
-    char stringpool_str2399[sizeof("lc.it")];
-    char stringpool_str2400[sizeof("tc")];
-    char stringpool_str2401[sizeof("oiso.kanagawa.jp")];
-    char stringpool_str2402[sizeof("nnov.ru")];
-    char stringpool_str2403[sizeof("dc.us")];
-    char stringpool_str2404[sizeof("oe.yamagata.jp")];
-    char stringpool_str2405[sizeof("habikino.osaka.jp")];
-    char stringpool_str2406[sizeof("xn--rros-gra.no")];
-    char stringpool_str2407[sizeof("is-into-cars.com")];
-    char stringpool_str2408[sizeof("tatarstan.ru")];
-    char stringpool_str2409[sizeof("blogspot.in")];
-    char stringpool_str2410[sizeof("toga.toyama.jp")];
-    char stringpool_str2411[sizeof("tourism.pl")];
-    char stringpool_str2412[sizeof("trieste.it")];
-    char stringpool_str2413[sizeof("vi.it")];
-    char stringpool_str2414[sizeof("karuizawa.nagano.jp")];
-    char stringpool_str2415[sizeof("cc.na")];
-    char stringpool_str2416[sizeof("ngo.pl")];
-    char stringpool_str2417[sizeof("xn--l-1fa.no")];
-    char stringpool_str2418[sizeof("geology.museum")];
-    char stringpool_str2419[sizeof("kobierzyce.pl")];
-    char stringpool_str2420[sizeof("ac.ir")];
-    char stringpool_str2421[sizeof("aogashima.tokyo.jp")];
-    char stringpool_str2422[sizeof("is-a-knight.org")];
-    char stringpool_str2423[sizeof("dyndns-mail.com")];
-    char stringpool_str2424[sizeof("newhampshire.museum")];
-    char stringpool_str2425[sizeof("exposed")];
-    char stringpool_str2426[sizeof("zoology.museum")];
-    char stringpool_str2427[sizeof("edogawa.tokyo.jp")];
-    char stringpool_str2428[sizeof("kawakami.nagano.jp")];
-    char stringpool_str2429[sizeof("taku.saga.jp")];
-    char stringpool_str2430[sizeof("org.gh")];
-    char stringpool_str2431[sizeof("vb.it")];
-    char stringpool_str2432[sizeof("izumozaki.niigata.jp")];
-    char stringpool_str2433[sizeof("rakkestad.no")];
-    char stringpool_str2434[sizeof("xn--nqv7f")];
-    char stringpool_str2435[sizeof("gyokuto.kumamoto.jp")];
-    char stringpool_str2436[sizeof("clothing")];
-    char stringpool_str2437[sizeof("is-very-nice.org")];
-    char stringpool_str2438[sizeof("nakaniikawa.toyama.jp")];
-    char stringpool_str2439[sizeof("zao.miyagi.jp")];
-    char stringpool_str2440[sizeof("urayasu.chiba.jp")];
-    char stringpool_str2441[sizeof("amsterdam.museum")];
-    char stringpool_str2442[sizeof("go.dyndns.org")];
-    char stringpool_str2443[sizeof("civilaviation.aero")];
-    char stringpool_str2444[sizeof("ac.im")];
-    char stringpool_str2445[sizeof("namegawa.saitama.jp")];
-    char stringpool_str2446[sizeof("blogspot.hu")];
-    char stringpool_str2447[sizeof("utashinai.hokkaido.jp")];
-    char stringpool_str2448[sizeof("hatogaya.saitama.jp")];
-    char stringpool_str2449[sizeof("nozawaonsen.nagano.jp")];
-    char stringpool_str2450[sizeof("blogspot.nl")];
-    char stringpool_str2451[sizeof("xn--h-2fa.no")];
-    char stringpool_str2452[sizeof("xn--3ds443g")];
-    char stringpool_str2453[sizeof("me")];
-    char stringpool_str2454[sizeof("menu")];
-    char stringpool_str2455[sizeof("md")];
-    char stringpool_str2456[sizeof("honbetsu.hokkaido.jp")];
-    char stringpool_str2457[sizeof("xn--andy-ira.no")];
-    char stringpool_str2458[sizeof("kommunalforbund.se")];
-    char stringpool_str2459[sizeof("mo")];
-    char stringpool_str2460[sizeof("mov")];
-    char stringpool_str2461[sizeof("ms")];
-    char stringpool_str2462[sizeof("xn--bievt-0qa.no")];
-    char stringpool_str2463[sizeof("mp")];
-    char stringpool_str2464[sizeof("chiropractic.museum")];
-    char stringpool_str2465[sizeof("voronezh.ru")];
-    char stringpool_str2466[sizeof("k12.ec")];
-    char stringpool_str2467[sizeof("moe")];
-    char stringpool_str2468[sizeof("com.sv")];
-    char stringpool_str2469[sizeof("xn--mgbx4cd0ab")];
-    char stringpool_str2470[sizeof("ena.gifu.jp")];
-    char stringpool_str2471[sizeof("xn--6frz82g")];
-    char stringpool_str2472[sizeof("tm.hu")];
-    char stringpool_str2473[sizeof("xn--ciqpn.hk")];
-    char stringpool_str2474[sizeof("ac.in")];
-    char stringpool_str2475[sizeof("kumiyama.kyoto.jp")];
-    char stringpool_str2476[sizeof("blogspot.tw")];
-    char stringpool_str2477[sizeof("xn--smla-hra.no")];
-    char stringpool_str2478[sizeof("xn--ses554g")];
-    char stringpool_str2479[sizeof("kitahiroshima.hokkaido.jp")];
-    char stringpool_str2480[sizeof("gob.sv")];
-    char stringpool_str2481[sizeof("higashiizu.shizuoka.jp")];
-    char stringpool_str2482[sizeof("mormon")];
-    char stringpool_str2483[sizeof("tsu.mie.jp")];
-    char stringpool_str2484[sizeof("meet")];
-    char stringpool_str2485[sizeof("nachikatsuura.wakayama.jp")];
-    char stringpool_str2486[sizeof("boleslawiec.pl")];
-    char stringpool_str2487[sizeof("kurashiki.okayama.jp")];
-    char stringpool_str2488[sizeof("tw.cn")];
-    char stringpool_str2489[sizeof("royrvik.no")];
-    char stringpool_str2490[sizeof("namerikawa.toyama.jp")];
-    char stringpool_str2491[sizeof("nishiawakura.okayama.jp")];
-    char stringpool_str2492[sizeof("nosegawa.nara.jp")];
-    char stringpool_str2493[sizeof("abu.yamaguchi.jp")];
-    char stringpool_str2494[sizeof("ma")];
-    char stringpool_str2495[sizeof("dontexist.com")];
-    char stringpool_str2496[sizeof("isa-geek.net")];
-    char stringpool_str2497[sizeof("kitaaiki.nagano.jp")];
-    char stringpool_str2498[sizeof("tono.iwate.jp")];
-    char stringpool_str2499[sizeof("edu.sv")];
-    char stringpool_str2500[sizeof("omitama.ibaraki.jp")];
-    char stringpool_str2501[sizeof("alto-adige.it")];
-    char stringpool_str2502[sizeof("england.museum")];
-    char stringpool_str2503[sizeof("tv.sd")];
-    char stringpool_str2504[sizeof("vic.edu.au")];
-    char stringpool_str2505[sizeof("openair.museum")];
-    char stringpool_str2506[sizeof("godo.gifu.jp")];
-    char stringpool_str2507[sizeof("is-a-hunter.com")];
-    char stringpool_str2508[sizeof("mt")];
-    char stringpool_str2509[sizeof("meme")];
-    char stringpool_str2510[sizeof("xn--kfjord-iua.no")];
-    char stringpool_str2511[sizeof("evenassi.no")];
-    char stringpool_str2512[sizeof("mr")];
-    char stringpool_str2513[sizeof("higashiyoshino.nara.jp")];
-    char stringpool_str2514[sizeof("cesena-forli.it")];
-    char stringpool_str2515[sizeof("roan.no")];
-    char stringpool_str2516[sizeof("med.ec")];
-    char stringpool_str2517[sizeof("med.pl")];
-    char stringpool_str2518[sizeof("tananger.no")];
-    char stringpool_str2519[sizeof("mu")];
-    char stringpool_str2520[sizeof("alstahaug.no")];
-    char stringpool_str2521[sizeof("tone.ibaraki.jp")];
-    char stringpool_str2522[sizeof("moda")];
-    char stringpool_str2523[sizeof("uenohara.yamanashi.jp")];
-    char stringpool_str2524[sizeof("otofuke.hokkaido.jp")];
-    char stringpool_str2525[sizeof("blogspot.hk")];
-    char stringpool_str2526[sizeof("qpon")];
-    char stringpool_str2527[sizeof("kashima.kumamoto.jp")];
-    char stringpool_str2528[sizeof("rio")];
-    char stringpool_str2529[sizeof("emilia-romagna.it")];
-    char stringpool_str2530[sizeof("mz")];
-    char stringpool_str2531[sizeof("kchr.ru")];
-    char stringpool_str2532[sizeof("namsos.no")];
-    char stringpool_str2533[sizeof("is-an-anarchist.com")];
-    char stringpool_str2534[sizeof("council.aero")];
-    char stringpool_str2535[sizeof("inagawa.hyogo.jp")];
-    char stringpool_str2536[sizeof("oppdal.no")];
-    char stringpool_str2537[sizeof("jondal.no")];
-    char stringpool_str2538[sizeof("nankoku.kochi.jp")];
-    char stringpool_str2539[sizeof("dudinka.ru")];
-    char stringpool_str2540[sizeof("kitanakagusuku.okinawa.jp")];
-    char stringpool_str2541[sizeof("mm")];
-    char stringpool_str2542[sizeof("kyuragi.saga.jp")];
-    char stringpool_str2543[sizeof("blogdns.net")];
-    char stringpool_str2544[sizeof("net.mv")];
-    char stringpool_str2545[sizeof("tawaramoto.nara.jp")];
-    char stringpool_str2546[sizeof("com.mv")];
-    char stringpool_str2547[sizeof("toyoura.hokkaido.jp")];
-    char stringpool_str2548[sizeof("xn--uc0atv.tw")];
-    char stringpool_str2549[sizeof("gov.mv")];
-    char stringpool_str2550[sizeof("is-into-cartoons.com")];
-    char stringpool_str2551[sizeof("lerdal.no")];
-    char stringpool_str2552[sizeof("nisshin.aichi.jp")];
-    char stringpool_str2553[sizeof("ac.ug")];
-    char stringpool_str2554[sizeof("village.museum")];
-    char stringpool_str2555[sizeof("asakawa.fukushima.jp")];
-    char stringpool_str2556[sizeof("gaular.no")];
-    char stringpool_str2557[sizeof("xn--dnna-gra.no")];
-    char stringpool_str2558[sizeof("livinghistory.museum")];
-    char stringpool_str2559[sizeof("yoka.hyogo.jp")];
-    char stringpool_str2560[sizeof("yonabaru.okinawa.jp")];
-    char stringpool_str2561[sizeof("costume.museum")];
-    char stringpool_str2562[sizeof("med.sd")];
-    char stringpool_str2563[sizeof("divtasvuodna.no")];
-    char stringpool_str2564[sizeof("mn")];
-    char stringpool_str2565[sizeof("ngo.lk")];
-    char stringpool_str2566[sizeof("xn--rholt-mra.no")];
-    char stringpool_str2567[sizeof("idrett.no")];
-    char stringpool_str2568[sizeof("med.pro")];
-    char stringpool_str2569[sizeof("zaporizhzhe.ua")];
-    char stringpool_str2570[sizeof("notogawa.shiga.jp")];
-    char stringpool_str2571[sizeof("edu.mv")];
-    char stringpool_str2572[sizeof("med.ee")];
-    char stringpool_str2573[sizeof("haebaru.okinawa.jp")];
-    char stringpool_str2574[sizeof("katsuura.chiba.jp")];
-    char stringpool_str2575[sizeof("mie.jp")];
-    char stringpool_str2576[sizeof("diamonds")];
-    char stringpool_str2577[sizeof("takaoka.toyama.jp")];
-    char stringpool_str2578[sizeof("network")];
-    char stringpool_str2579[sizeof("rankoshi.hokkaido.jp")];
-    char stringpool_str2580[sizeof("mod.uk")];
-    char stringpool_str2581[sizeof("komatsushima.tokushima.jp")];
-    char stringpool_str2582[sizeof("britishcolumbia.museum")];
-    char stringpool_str2583[sizeof("org.sv")];
-    char stringpool_str2584[sizeof("brindisi.it")];
-    char stringpool_str2585[sizeof("ham-radio-op.net")];
-    char stringpool_str2586[sizeof("namikata.ehime.jp")];
-    char stringpool_str2587[sizeof("xn--vler-qoa.hedmark.no")];
-    char stringpool_str2588[sizeof("blogdns.com")];
-    char stringpool_str2589[sizeof("tv.tz")];
-    char stringpool_str2590[sizeof("gifu.gifu.jp")];
-    char stringpool_str2591[sizeof("nesset.no")];
-    char stringpool_str2592[sizeof("lardal.no")];
-    char stringpool_str2593[sizeof("xn--hpmir-xqa.no")];
-    char stringpool_str2594[sizeof("chattanooga.museum")];
-    char stringpool_str2595[sizeof("nagasaki.nagasaki.jp")];
-    char stringpool_str2596[sizeof("goshiki.hyogo.jp")];
-    char stringpool_str2597[sizeof("xn--brnnysund-m8ac.no")];
-    char stringpool_str2598[sizeof("g12.br")];
-    char stringpool_str2599[sizeof("higashiizumo.shimane.jp")];
-    char stringpool_str2600[sizeof("naples.it")];
-    char stringpool_str2601[sizeof("washingtondc.museum")];
-    char stringpool_str2602[sizeof("mk")];
-    char stringpool_str2603[sizeof("mar.it")];
-    char stringpool_str2604[sizeof("judygarland.museum")];
-    char stringpool_str2605[sizeof("iglesiascarbonia.it")];
-    char stringpool_str2606[sizeof("hobby-site.org")];
-    char stringpool_str2607[sizeof("andriatranibarletta.it")];
-    char stringpool_str2608[sizeof("dating")];
-    char stringpool_str2609[sizeof("xn--q9jyb4c")];
-    char stringpool_str2610[sizeof("is-a-democrat.com")];
-    char stringpool_str2611[sizeof("kuromatsunai.hokkaido.jp")];
-    char stringpool_str2612[sizeof("xn--lten-gra.no")];
-    char stringpool_str2613[sizeof("luxe")];
-    char stringpool_str2614[sizeof("kashima.ibaraki.jp")];
-    char stringpool_str2615[sizeof("takaishi.osaka.jp")];
-    char stringpool_str2616[sizeof("hiraizumi.iwate.jp")];
-    char stringpool_str2617[sizeof("carboniaiglesias.it")];
-    char stringpool_str2618[sizeof("bindal.no")];
-    char stringpool_str2619[sizeof("nishihara.kumamoto.jp")];
-    char stringpool_str2620[sizeof("horten.no")];
-    char stringpool_str2621[sizeof("alabama.museum")];
-    char stringpool_str2622[sizeof("vladimir.ru")];
-    char stringpool_str2623[sizeof("ml")];
-    char stringpool_str2624[sizeof("karatsu.saga.jp")];
-    char stringpool_str2625[sizeof("toyonaka.osaka.jp")];
-    char stringpool_str2626[sizeof("tuva.ru")];
-    char stringpool_str2627[sizeof("togo.aichi.jp")];
-    char stringpool_str2628[sizeof("tsaritsyn.ru")];
-    char stringpool_str2629[sizeof("ethnology.museum")];
-    char stringpool_str2630[sizeof("net.lv")];
-    char stringpool_str2631[sizeof("mat.br")];
-    char stringpool_str2632[sizeof("tools")];
-    char stringpool_str2633[sizeof("com.lv")];
-    char stringpool_str2634[sizeof("ushistory.museum")];
-    char stringpool_str2635[sizeof("gov.lv")];
-    char stringpool_str2636[sizeof("motorcycles")];
-    char stringpool_str2637[sizeof("jewishart.museum")];
-    char stringpool_str2638[sizeof("os.hordaland.no")];
-    char stringpool_str2639[sizeof("habmer.no")];
-    char stringpool_str2640[sizeof("kamikawa.hyogo.jp")];
-    char stringpool_str2641[sizeof("beardu.no")];
-    char stringpool_str2642[sizeof("xn--hcesuolo-7ya35b.no")];
-    char stringpool_str2643[sizeof("teledata.mz")];
-    char stringpool_str2644[sizeof("moscow")];
-    char stringpool_str2645[sizeof("mil")];
-    char stringpool_str2646[sizeof("m.se")];
-    char stringpool_str2647[sizeof("mq")];
-    char stringpool_str2648[sizeof("hayashima.okayama.jp")];
-    char stringpool_str2649[sizeof("narashino.chiba.jp")];
-    char stringpool_str2650[sizeof("tsukuba.ibaraki.jp")];
-    char stringpool_str2651[sizeof("mol.it")];
-    char stringpool_str2652[sizeof("med.br")];
-    char stringpool_str2653[sizeof("xn--od0alg.hk")];
-    char stringpool_str2654[sizeof("mil.st")];
-    char stringpool_str2655[sizeof("mil.ec")];
-    char stringpool_str2656[sizeof("higashiyama.kyoto.jp")];
-    char stringpool_str2657[sizeof("asahikawa.hokkaido.jp")];
-    char stringpool_str2658[sizeof("mil.pl")];
-    char stringpool_str2659[sizeof("xn--rady-ira.no")];
-    char stringpool_str2660[sizeof("xn--bidr-5nac.no")];
-    char stringpool_str2661[sizeof("gov.nc.tr")];
-    char stringpool_str2662[sizeof("biz.mv")];
-    char stringpool_str2663[sizeof("kamikawa.hokkaido.jp")];
-    char stringpool_str2664[sizeof("okinoshima.shimane.jp")];
-    char stringpool_str2665[sizeof("iwakuni.yamaguchi.jp")];
-    char stringpool_str2666[sizeof("pe")];
-    char stringpool_str2667[sizeof("etajima.hiroshima.jp")];
-    char stringpool_str2668[sizeof("gamvik.no")];
-    char stringpool_str2669[sizeof("localhistory.museum")];
-    char stringpool_str2670[sizeof("kawasaki.miyagi.jp")];
-    char stringpool_str2671[sizeof("valle-daosta.it")];
-    char stringpool_str2672[sizeof("narvik.no")];
-    char stringpool_str2673[sizeof("edu.lv")];
-    char stringpool_str2674[sizeof("kazimierz-dolny.pl")];
-    char stringpool_str2675[sizeof("qc.com")];
-    char stringpool_str2676[sizeof("int.mv")];
-    char stringpool_str2677[sizeof("ps")];
-    char stringpool_str2678[sizeof("lenvik.no")];
-    char stringpool_str2679[sizeof("bievat.no")];
-    char stringpool_str2680[sizeof("is-into-games.com")];
-    char stringpool_str2681[sizeof("moss.no")];
-    char stringpool_str2682[sizeof("org.mv")];
-    char stringpool_str2683[sizeof("net.sy")];
-    char stringpool_str2684[sizeof("xn--brum-voa.no")];
-    char stringpool_str2685[sizeof("com.sy")];
-    char stringpool_str2686[sizeof("gov.sy")];
-    char stringpool_str2687[sizeof("mh")];
-    char stringpool_str2688[sizeof("kunneppu.hokkaido.jp")];
-    char stringpool_str2689[sizeof("net.py")];
-    char stringpool_str2690[sizeof("higashi.okinawa.jp")];
-    char stringpool_str2691[sizeof("kitahata.saga.jp")];
-    char stringpool_str2692[sizeof("com.py")];
-    char stringpool_str2693[sizeof("kamikitayama.nara.jp")];
-    char stringpool_str2694[sizeof("gov.py")];
-    char stringpool_str2695[sizeof("de.com")];
-    char stringpool_str2696[sizeof("tondabayashi.osaka.jp")];
-    char stringpool_str2697[sizeof("hadsel.no")];
-    char stringpool_str2698[sizeof("mil.al")];
-    char stringpool_str2699[sizeof("mil.ar")];
-    char stringpool_str2700[sizeof("miami")];
-    char stringpool_str2701[sizeof("lindas.no")];
-    char stringpool_str2702[sizeof("mil.ac")];
-    char stringpool_str2703[sizeof("og.it")];
-    char stringpool_str2704[sizeof("bg.it")];
-    char stringpool_str2705[sizeof("test.ru")];
-    char stringpool_str2706[sizeof("higashiyamato.tokyo.jp")];
-    char stringpool_str2707[sizeof("tv.bo")];
-    char stringpool_str2708[sizeof("my")];
-    char stringpool_str2709[sizeof("balsan.it")];
-    char stringpool_str2710[sizeof("wroclaw.pl")];
-    char stringpool_str2711[sizeof("pa")];
-    char stringpool_str2712[sizeof("onomichi.hiroshima.jp")];
-    char stringpool_str2713[sizeof("mil.tw")];
-    char stringpool_str2714[sizeof("edu.sy")];
-    char stringpool_str2715[sizeof("koga.fukuoka.jp")];
-    char stringpool_str2716[sizeof("hurdal.no")];
-    char stringpool_str2717[sizeof("mil.rw")];
-    char stringpool_str2718[sizeof("gotdns.com")];
-    char stringpool_str2719[sizeof("edu.py")];
-    char stringpool_str2720[sizeof("larvik.no")];
-    char stringpool_str2721[sizeof("xn--vegrshei-c0a.no")];
-    char stringpool_str2722[sizeof("xn--54b7fta0cc")];
-    char stringpool_str2723[sizeof("tula.ru")];
-    char stringpool_str2724[sizeof("dr.na")];
-    char stringpool_str2725[sizeof("kuriyama.hokkaido.jp")];
-    char stringpool_str2726[sizeof("med.sa")];
-    char stringpool_str2727[sizeof("nishiarita.saga.jp")];
-    char stringpool_str2728[sizeof("pt")];
-    char stringpool_str2729[sizeof("med.pa")];
-    char stringpool_str2730[sizeof("tjeldsund.no")];
-    char stringpool_str2731[sizeof("asn.lv")];
-    char stringpool_str2732[sizeof("pr")];
-    char stringpool_str2733[sizeof("re.it")];
-    char stringpool_str2734[sizeof("aseral.no")];
-    char stringpool_str2735[sizeof("mw")];
-    char stringpool_str2736[sizeof("nishihara.okinawa.jp")];
-    char stringpool_str2737[sizeof("luster.no")];
-    char stringpool_str2738[sizeof("ro.it")];
-    char stringpool_str2739[sizeof("equipment")];
-    char stringpool_str2740[sizeof("mil.pe")];
-    char stringpool_str2741[sizeof("parts")];
-    char stringpool_str2742[sizeof("halden.no")];
-    char stringpool_str2743[sizeof("rennesoy.no")];
-    char stringpool_str2744[sizeof("hida.gifu.jp")];
-    char stringpool_str2745[sizeof("yamashina.kyoto.jp")];
-    char stringpool_str2746[sizeof("aga.niigata.jp")];
-    char stringpool_str2747[sizeof("buzz")];
-    char stringpool_str2748[sizeof("med.ht")];
-    char stringpool_str2749[sizeof("okinawa.okinawa.jp")];
-    char stringpool_str2750[sizeof("akkeshi.hokkaido.jp")];
-    char stringpool_str2751[sizeof("jetzt")];
-    char stringpool_str2752[sizeof("net.uy")];
-    char stringpool_str2753[sizeof("tg")];
-    char stringpool_str2754[sizeof("com.uy")];
-    char stringpool_str2755[sizeof("yamagata.jp")];
-    char stringpool_str2756[sizeof("is-certified.com")];
-    char stringpool_str2757[sizeof("vv.it")];
-    char stringpool_str2758[sizeof("pub")];
-    char stringpool_str2759[sizeof("nakasatsunai.hokkaido.jp")];
-    char stringpool_str2760[sizeof("homelinux.com")];
-    char stringpool_str2761[sizeof("dyndns-pics.com")];
-    char stringpool_str2762[sizeof("university.museum")];
-    char stringpool_str2763[sizeof("mil.ru")];
-    char stringpool_str2764[sizeof("tv.br")];
-    char stringpool_str2765[sizeof("vinnica.ua")];
-    char stringpool_str2766[sizeof("xn--rlingen-mxa.no")];
-    char stringpool_str2767[sizeof("nomi.ishikawa.jp")];
-    char stringpool_str2768[sizeof("yoshida.shizuoka.jp")];
-    char stringpool_str2769[sizeof("xn--bjddar-pta.no")];
-    char stringpool_str2770[sizeof("xn--brnny-wuac.no")];
-    char stringpool_str2771[sizeof("pm")];
-    char stringpool_str2772[sizeof("mil.ae")];
-    char stringpool_str2773[sizeof("ra.it")];
-    char stringpool_str2774[sizeof("hapmir.no")];
-    char stringpool_str2775[sizeof("loabat.no")];
-    char stringpool_str2776[sizeof("tvedestrand.no")];
-    char stringpool_str2777[sizeof("org.lv")];
-    char stringpool_str2778[sizeof("inuyama.aichi.jp")];
-    char stringpool_str2779[sizeof("net.my")];
-    char stringpool_str2780[sizeof("dlugoleka.pl")];
-    char stringpool_str2781[sizeof("com.my")];
-    char stringpool_str2782[sizeof("gov.my")];
-    char stringpool_str2783[sizeof("name.vn")];
-    char stringpool_str2784[sizeof("vlog.br")];
-    char stringpool_str2785[sizeof("dyndns-ip.com")];
-    char stringpool_str2786[sizeof("xn--lrenskog-54a.no")];
-    char stringpool_str2787[sizeof("anamizu.ishikawa.jp")];
-    char stringpool_str2788[sizeof("xn--krdsherad-m8a.no")];
-    char stringpool_str2789[sizeof("edu.uy")];
-    char stringpool_str2790[sizeof("teo.br")];
-    char stringpool_str2791[sizeof("alvdal.no")];
-    char stringpool_str2792[sizeof("ube.yamaguchi.jp")];
-    char stringpool_str2793[sizeof("valle-d-aosta.it")];
-    char stringpool_str2794[sizeof("ag.it")];
-    char stringpool_str2795[sizeof("detroit.museum")];
-    char stringpool_str2796[sizeof("wakayama.wakayama.jp")];
-    char stringpool_str2797[sizeof("mil.in")];
-    char stringpool_str2798[sizeof("is-a-conservative.com")];
-    char stringpool_str2799[sizeof("krodsherad.no")];
-    char stringpool_str2800[sizeof("is-a-blogger.com")];
-    char stringpool_str2801[sizeof("mil.tj")];
-    char stringpool_str2802[sizeof("kagoshima.kagoshima.jp")];
-    char stringpool_str2803[sizeof("karikatur.museum")];
-    char stringpool_str2804[sizeof("pn")];
-    char stringpool_str2805[sizeof("maison")];
-    char stringpool_str2806[sizeof("orland.no")];
-    char stringpool_str2807[sizeof("reviews")];
-    char stringpool_str2808[sizeof("mail.pl")];
-    char stringpool_str2809[sizeof("desa.id")];
-    char stringpool_str2810[sizeof("mus.br")];
-    char stringpool_str2811[sizeof("edu.my")];
-    char stringpool_str2812[sizeof("mil.br")];
-    char stringpool_str2813[sizeof("kamakura.kanagawa.jp")];
-    char stringpool_str2814[sizeof("equipment.aero")];
-    char stringpool_str2815[sizeof("cloudcontrolled.com")];
-    char stringpool_str2816[sizeof("org.sy")];
-    char stringpool_str2817[sizeof("davvenjarga.no")];
-    char stringpool_str2818[sizeof("org.py")];
-    char stringpool_str2819[sizeof("novara.it")];
-    char stringpool_str2820[sizeof("messina.it")];
-    char stringpool_str2821[sizeof("meraker.no")];
-    char stringpool_str2822[sizeof("me.us")];
-    char stringpool_str2823[sizeof("mil.kr")];
-    char stringpool_str2824[sizeof("tm.mc")];
-    char stringpool_str2825[sizeof("md.us")];
-    char stringpool_str2826[sizeof("anan.tokushima.jp")];
-    char stringpool_str2827[sizeof("msk.ru")];
-    char stringpool_str2828[sizeof("mo.us")];
-    char stringpool_str2829[sizeof("ms.us")];
-    char stringpool_str2830[sizeof("chikujo.fukuoka.jp")];
-    char stringpool_str2831[sizeof("xn--cg4bki")];
-    char stringpool_str2832[sizeof("post")];
-    char stringpool_str2833[sizeof("childrensgarden.museum")];
-    char stringpool_str2834[sizeof("com.by")];
-    char stringpool_str2835[sizeof("rm.it")];
-    char stringpool_str2836[sizeof("gov.by")];
-    char stringpool_str2837[sizeof("kouhoku.saga.jp")];
-    char stringpool_str2838[sizeof("us-east-1.amazonaws.com")];
-    char stringpool_str2839[sizeof("orkdal.no")];
-    char stringpool_str2840[sizeof("iwamizawa.hokkaido.jp")];
-    char stringpool_str2841[sizeof("gub.uy")];
-    char stringpool_str2842[sizeof("mil.id")];
-    char stringpool_str2843[sizeof("yoshikawa.saitama.jp")];
-    char stringpool_str2844[sizeof("ptz.ru")];
-    char stringpool_str2845[sizeof("pk")];
-    char stringpool_str2846[sizeof("beiarn.no")];
-    char stringpool_str2847[sizeof("onga.fukuoka.jp")];
-    char stringpool_str2848[sizeof("nishiwaki.hyogo.jp")];
-    char stringpool_str2849[sizeof("baghdad.museum")];
-    char stringpool_str2850[sizeof("net.ky")];
-    char stringpool_str2851[sizeof("baidar.no")];
-    char stringpool_str2852[sizeof("ullensvang.no")];
-    char stringpool_str2853[sizeof("com.ky")];
-    char stringpool_str2854[sizeof("kushima.miyazaki.jp")];
-    char stringpool_str2855[sizeof("gov.ky")];
-    char stringpool_str2856[sizeof("ro.com")];
-    char stringpool_str2857[sizeof("tinn.no")];
-    char stringpool_str2858[sizeof("kawatana.nagasaki.jp")];
-    char stringpool_str2859[sizeof("xn--55qw42g")];
-    char stringpool_str2860[sizeof("ri.it")];
-    char stringpool_str2861[sizeof("xn--lrdal-sra.no")];
-    char stringpool_str2862[sizeof("chijiwa.nagasaki.jp")];
-    char stringpool_str2863[sizeof("xn--leagaviika-52b.no")];
-    char stringpool_str2864[sizeof("bergbau.museum")];
-    char stringpool_str2865[sizeof("kounosu.saitama.jp")];
-    char stringpool_str2866[sizeof("aeroclub.aero")];
-    char stringpool_str2867[sizeof("emiliaromagna.it")];
-    char stringpool_str2868[sizeof("rn.it")];
-    char stringpool_str2869[sizeof("berlevag.no")];
-    char stringpool_str2870[sizeof("xn--80aswg")];
-    char stringpool_str2871[sizeof("higashimatsuyama.saitama.jp")];
-    char stringpool_str2872[sizeof("ma.us")];
-    char stringpool_str2873[sizeof("pl")];
-    char stringpool_str2874[sizeof("praxi")];
-    char stringpool_str2875[sizeof("is-a-hard-worker.com")];
-    char stringpool_str2876[sizeof("naturbruksgymn.se")];
-    char stringpool_str2877[sizeof("namegata.ibaraki.jp")];
-    char stringpool_str2878[sizeof("eiheiji.fukui.jp")];
-    char stringpool_str2879[sizeof("esan.hokkaido.jp")];
-    char stringpool_str2880[sizeof("net.ly")];
-    char stringpool_str2881[sizeof("kashiwazaki.niigata.jp")];
-    char stringpool_str2882[sizeof("is-a-republican.com")];
-    char stringpool_str2883[sizeof("nogi.tochigi.jp")];
-    char stringpool_str2884[sizeof("com.ly")];
-    char stringpool_str2885[sizeof("gov.ly")];
-    char stringpool_str2886[sizeof("hareid.no")];
-    char stringpool_str2887[sizeof("biei.hokkaido.jp")];
-    char stringpool_str2888[sizeof("edu.ky")];
-    char stringpool_str2889[sizeof("mt.us")];
-    char stringpool_str2890[sizeof("moareke.no")];
-    char stringpool_str2891[sizeof("pink")];
-    char stringpool_str2892[sizeof("info.vn")];
-    char stringpool_str2893[sizeof("p.se")];
-    char stringpool_str2894[sizeof("org.uy")];
-    char stringpool_str2895[sizeof("rockart.museum")];
-    char stringpool_str2896[sizeof("malselv.no")];
-    char stringpool_str2897[sizeof("rawa-maz.pl")];
-    char stringpool_str2898[sizeof("cloudcontrolapp.com")];
-    char stringpool_str2899[sizeof("blogspot.ca")];
-    char stringpool_str2900[sizeof("lebork.pl")];
-    char stringpool_str2901[sizeof("okagaki.fukuoka.jp")];
-    char stringpool_str2902[sizeof("kaneyama.yamagata.jp")];
-    char stringpool_str2903[sizeof("jeonbuk.kr")];
-    char stringpool_str2904[sizeof("pmn.it")];
-    char stringpool_str2905[sizeof("nishikata.tochigi.jp")];
-    char stringpool_str2906[sizeof("chuo.fukuoka.jp")];
-    char stringpool_str2907[sizeof("edu.ly")];
-    char stringpool_str2908[sizeof("elb.amazonaws.com")];
-    char stringpool_str2909[sizeof("kotohira.kagawa.jp")];
-    char stringpool_str2910[sizeof("toyosato.shiga.jp")];
-    char stringpool_str2911[sizeof("yamanakako.yamanashi.jp")];
-    char stringpool_str2912[sizeof("is-a-designer.com")];
-    char stringpool_str2913[sizeof("zoological.museum")];
-    char stringpool_str2914[sizeof("rahkkeravju.no")];
-    char stringpool_str2915[sizeof("betainabox.com")];
-    char stringpool_str2916[sizeof("dnsdojo.org")];
-    char stringpool_str2917[sizeof("tx.us")];
-    char stringpool_str2918[sizeof("org.my")];
-    char stringpool_str2919[sizeof("info.ve")];
-    char stringpool_str2920[sizeof("dnsalias.com")];
-    char stringpool_str2921[sizeof("mil.hn")];
-    char stringpool_str2922[sizeof("amagasaki.hyogo.jp")];
-    char stringpool_str2923[sizeof("mil.iq")];
-    char stringpool_str2924[sizeof("niigata.niigata.jp")];
-    char stringpool_str2925[sizeof("ph")];
-    char stringpool_str2926[sizeof("ppg.br")];
-    char stringpool_str2927[sizeof("decorativearts.museum")];
-    char stringpool_str2928[sizeof("dynalias.com")];
-    char stringpool_str2929[sizeof("doomdns.com")];
-    char stringpool_str2930[sizeof("krakow.pl")];
-    char stringpool_str2931[sizeof("ru.com")];
-    char stringpool_str2932[sizeof("jeonnam.kr")];
-    char stringpool_str2933[sizeof("pila.pl")];
-    char stringpool_str2934[sizeof("me.tz")];
-    char stringpool_str2935[sizeof("academy.museum")];
-    char stringpool_str2936[sizeof("xn--krehamn-dxa.no")];
-    char stringpool_str2937[sizeof("trustee.museum")];
-    char stringpool_str2938[sizeof("kuroiso.tochigi.jp")];
-    char stringpool_str2939[sizeof("kakegawa.shizuoka.jp")];
-    char stringpool_str2940[sizeof("watchandclock.museum")];
-    char stringpool_str2941[sizeof("blogspot.cz")];
-    char stringpool_str2942[sizeof("tsubata.ishikawa.jp")];
-    char stringpool_str2943[sizeof("py")];
-    char stringpool_str2944[sizeof("yuu.yamaguchi.jp")];
-    char stringpool_str2945[sizeof("theater.museum")];
-    char stringpool_str2946[sizeof("hasvik.no")];
-    char stringpool_str2947[sizeof("yuki.ibaraki.jp")];
-    char stringpool_str2948[sizeof("dyndns-free.com")];
-    char stringpool_str2949[sizeof("mv")];
-    char stringpool_str2950[sizeof("nakijin.okinawa.jp")];
-    char stringpool_str2951[sizeof("date.hokkaido.jp")];
-    char stringpool_str2952[sizeof("algard.no")];
-    char stringpool_str2953[sizeof("mi.us")];
-    char stringpool_str2954[sizeof("dyndns-work.com")];
-    char stringpool_str2955[sizeof("pug.it")];
-    char stringpool_str2956[sizeof("mil.eg")];
-    char stringpool_str2957[sizeof("ochi.kochi.jp")];
-    char stringpool_str2958[sizeof("mn.us")];
-    char stringpool_str2959[sizeof("blogspot.com")];
-    char stringpool_str2960[sizeof("kikugawa.shizuoka.jp")];
-    char stringpool_str2961[sizeof("xn--vads-jra.no")];
-    char stringpool_str2962[sizeof("te.it")];
-    char stringpool_str2963[sizeof("bahccavuotna.no")];
-    char stringpool_str2964[sizeof("mil.az")];
-    char stringpool_str2965[sizeof("tochigi.jp")];
-    char stringpool_str2966[sizeof("to.it")];
-    char stringpool_str2967[sizeof("veterinaire.fr")];
-    char stringpool_str2968[sizeof("xn--od0alg.cn")];
-    char stringpool_str2969[sizeof("pw")];
-    char stringpool_str2970[sizeof("ts.it")];
-    char stringpool_str2971[sizeof("nantan.kyoto.jp")];
-    char stringpool_str2972[sizeof("blogspot.co.nz")];
-    char stringpool_str2973[sizeof("tp.it")];
-    char stringpool_str2974[sizeof("yamanashi.yamanashi.jp")];
-    char stringpool_str2975[sizeof("ms.kr")];
-    char stringpool_str2976[sizeof("bergen.no")];
-    char stringpool_str2977[sizeof("m.bg")];
-    char stringpool_str2978[sizeof("per.sg")];
-    char stringpool_str2979[sizeof("rl.no")];
-    char stringpool_str2980[sizeof("mil.tz")];
-    char stringpool_str2981[sizeof("kuji.iwate.jp")];
-    char stringpool_str2982[sizeof("org.ky")];
-    char stringpool_str2983[sizeof("lierne.no")];
-    char stringpool_str2984[sizeof("ishikari.hokkaido.jp")];
-    char stringpool_str2985[sizeof("ninomiya.kanagawa.jp")];
-    char stringpool_str2986[sizeof("tienda")];
-    char stringpool_str2987[sizeof("katashina.gunma.jp")];
-    char stringpool_str2988[sizeof("yusuhara.kochi.jp")];
-    char stringpool_str2989[sizeof("izunokuni.shizuoka.jp")];
-    char stringpool_str2990[sizeof("pub.sa")];
-    char stringpool_str2991[sizeof("kamiizumi.saitama.jp")];
-    char stringpool_str2992[sizeof("bolzano.it")];
-    char stringpool_str2993[sizeof("bamble.no")];
-    char stringpool_str2994[sizeof("kakogawa.hyogo.jp")];
-    char stringpool_str2995[sizeof("alaheadju.no")];
-    char stringpool_str2996[sizeof("mango")];
-    char stringpool_str2997[sizeof("archaeology.museum")];
-    char stringpool_str2998[sizeof("vc.it")];
-    char stringpool_str2999[sizeof("andebu.no")];
-    char stringpool_str3000[sizeof("blogspot.com.es")];
-    char stringpool_str3001[sizeof("ta.it")];
-    char stringpool_str3002[sizeof("md.ci")];
-    char stringpool_str3003[sizeof("org.ly")];
-    char stringpool_str3004[sizeof("nakagawa.hokkaido.jp")];
-    char stringpool_str3005[sizeof("is-a-guru.com")];
-    char stringpool_str3006[sizeof("xn--bearalvhki-y4a.no")];
-    char stringpool_str3007[sizeof("kimitsu.chiba.jp")];
-    char stringpool_str3008[sizeof("pol.ht")];
-    char stringpool_str3009[sizeof("dyndns-wiki.com")];
-    char stringpool_str3010[sizeof("crew.aero")];
-    char stringpool_str3011[sizeof("xn--vhquv")];
-    char stringpool_str3012[sizeof("pics")];
-    char stringpool_str3013[sizeof("mo.cn")];
-    char stringpool_str3014[sizeof("pescara.it")];
-    char stringpool_str3015[sizeof("github.io")];
-    char stringpool_str3016[sizeof("marketing")];
-    char stringpool_str3017[sizeof("tr.it")];
-    char stringpool_str3018[sizeof("takasago.hyogo.jp")];
-    char stringpool_str3019[sizeof("xn--mgbayh7gpa")];
-    char stringpool_str3020[sizeof("xn--80ao21a")];
-    char stringpool_str3021[sizeof("mil.ba")];
-    char stringpool_str3022[sizeof("kozagawa.wakayama.jp")];
-    char stringpool_str3023[sizeof("mk.ua")];
-    char stringpool_str3024[sizeof("tas.edu.au")];
-    char stringpool_str3025[sizeof("pol.dz")];
-    char stringpool_str3026[sizeof("ishikawa.okinawa.jp")];
-    char stringpool_str3027[sizeof("yonaguni.okinawa.jp")];
-    char stringpool_str3028[sizeof("nishinomiya.hyogo.jp")];
-    char stringpool_str3029[sizeof("ringebu.no")];
-    char stringpool_str3030[sizeof("e12.ve")];
-    char stringpool_str3031[sizeof("xn--bdddj-mrabd.no")];
-    char stringpool_str3032[sizeof("chikugo.fukuoka.jp")];
-    char stringpool_str3033[sizeof("orskog.no")];
-    char stringpool_str3034[sizeof("ide.kyoto.jp")];
-    char stringpool_str3035[sizeof("oirase.aomori.jp")];
-    char stringpool_str3036[sizeof("mil.mg")];
-    char stringpool_str3037[sizeof("psc.br")];
-    char stringpool_str3038[sizeof("massacarrara.it")];
-    char stringpool_str3039[sizeof("chungnam.kr")];
-    char stringpool_str3040[sizeof("modalen.no")];
-    char stringpool_str3041[sizeof("yoro.gifu.jp")];
-    char stringpool_str3042[sizeof("pp.se")];
-    char stringpool_str3043[sizeof("tt.im")];
-    char stringpool_str3044[sizeof("napoli.it")];
-    char stringpool_str3045[sizeof("andria-barletta-trani.it")];
-    char stringpool_str3046[sizeof("biella.it")];
-    char stringpool_str3047[sizeof("kamisunagawa.hokkaido.jp")];
-    char stringpool_str3048[sizeof("tr.no")];
-    char stringpool_str3049[sizeof("hornindal.no")];
-    char stringpool_str3050[sizeof("tateyama.toyama.jp")];
-    char stringpool_str3051[sizeof("jinsekikogen.hiroshima.jp")];
-    char stringpool_str3052[sizeof("mb.ca")];
-    char stringpool_str3053[sizeof("ivano-frankivsk.ua")];
-    char stringpool_str3054[sizeof("is-a-anarchist.com")];
-    char stringpool_str3055[sizeof("publ.pt")];
-    char stringpool_str3056[sizeof("partners")];
-    char stringpool_str3057[sizeof("miyazaki.jp")];
-    char stringpool_str3058[sizeof("higashikawa.hokkaido.jp")];
-    char stringpool_str3059[sizeof("blogspot.co.il")];
-    char stringpool_str3060[sizeof("mil.ng")];
-    char stringpool_str3061[sizeof("kiyokawa.kanagawa.jp")];
-    char stringpool_str3062[sizeof("per.la")];
-    char stringpool_str3063[sizeof("kadogawa.miyazaki.jp")];
-    char stringpool_str3064[sizeof("xn--btsfjord-9za.no")];
-    char stringpool_str3065[sizeof("ogliastra.it")];
-    char stringpool_str3066[sizeof("mil.qa")];
-    char stringpool_str3067[sizeof("kawanishi.hyogo.jp")];
-    char stringpool_str3068[sizeof("ternopil.ua")];
-    char stringpool_str3069[sizeof("blogspot.co.at")];
-    char stringpool_str3070[sizeof("mil.kz")];
-    char stringpool_str3071[sizeof("railway.museum")];
-    char stringpool_str3072[sizeof("tn.it")];
-    char stringpool_str3073[sizeof("blogspot.ch")];
-    char stringpool_str3074[sizeof("kuchinotsu.nagasaki.jp")];
-    char stringpool_str3075[sizeof("blogspot.com.ar")];
-    char stringpool_str3076[sizeof("kijo.miyazaki.jp")];
-    char stringpool_str3077[sizeof("pa.us")];
-    char stringpool_str3078[sizeof("tsurugashima.saitama.jp")];
-    char stringpool_str3079[sizeof("rishiri.hokkaido.jp")];
-    char stringpool_str3080[sizeof("pp.ua")];
-    char stringpool_str3081[sizeof("hvaler.no")];
-    char stringpool_str3082[sizeof("dgca.aero")];
-    char stringpool_str3083[sizeof("kitagawa.miyazaki.jp")];
-    char stringpool_str3084[sizeof("mp.br")];
-    char stringpool_str3085[sizeof("priv.pl")];
-    char stringpool_str3086[sizeof("xn--sandnessjen-ogb.no")];
-    char stringpool_str3087[sizeof("pri.ee")];
-    char stringpool_str3088[sizeof("agrinet.tn")];
-    char stringpool_str3089[sizeof("recipes")];
-    char stringpool_str3090[sizeof("kushimoto.wakayama.jp")];
-    char stringpool_str3091[sizeof("blogspot.com.au")];
-    char stringpool_str3092[sizeof("tm.no")];
-    char stringpool_str3093[sizeof("xn--lesund-hua.no")];
-    char stringpool_str3094[sizeof("pr.us")];
-    char stringpool_str3095[sizeof("omihachiman.shiga.jp")];
-    char stringpool_str3096[sizeof("civilisation.museum")];
-    char stringpool_str3097[sizeof("nakayama.yamagata.jp")];
-    char stringpool_str3098[sizeof("googleapis.com")];
-    char stringpool_str3099[sizeof("mil.kg")];
-    char stringpool_str3100[sizeof("owariasahi.aichi.jp")];
-    char stringpool_str3101[sizeof("magadan.ru")];
-    char stringpool_str3102[sizeof("vinnytsia.ua")];
-    char stringpool_str3103[sizeof("yashiro.hyogo.jp")];
-    char stringpool_str3104[sizeof("blogspot.mx")];
-    char stringpool_str3105[sizeof("lewismiller.museum")];
-    char stringpool_str3106[sizeof("hitachi.ibaraki.jp")];
-    char stringpool_str3107[sizeof("tatsuno.nagano.jp")];
-    char stringpool_str3108[sizeof("psi.br")];
-    char stringpool_str3109[sizeof("potenza")];
-    char stringpool_str3110[sizeof("e164.arpa")];
-    char stringpool_str3111[sizeof("trainer.aero")];
-    char stringpool_str3112[sizeof("niki.hokkaido.jp")];
-    char stringpool_str3113[sizeof("nishinoomote.kagoshima.jp")];
-    char stringpool_str3114[sizeof("kanonji.kagawa.jp")];
-    char stringpool_str3115[sizeof("isa-geek.com")];
-    char stringpool_str3116[sizeof("hanamigawa.chiba.jp")];
-    char stringpool_str3117[sizeof("kopervik.no")];
-    char stringpool_str3118[sizeof("pe.ca")];
-    char stringpool_str3119[sizeof("kikuchi.kumamoto.jp")];
-    char stringpool_str3120[sizeof("pp.az")];
-    char stringpool_str3121[sizeof("varggat.no")];
-    char stringpool_str3122[sizeof("takahagi.ibaraki.jp")];
-    char stringpool_str3123[sizeof("xn--zf0avx.hk")];
-    char stringpool_str3124[sizeof("moskenes.no")];
-    char stringpool_str3125[sizeof("xn--vrggt-xqad.no")];
-    char stringpool_str3126[sizeof("karasuyama.tochigi.jp")];
-    char stringpool_str3127[sizeof("muko.kyoto.jp")];
-    char stringpool_str3128[sizeof("mil.vc")];
-    char stringpool_str3129[sizeof("whoswho")];
-    char stringpool_str3130[sizeof("nishimera.miyazaki.jp")];
-    char stringpool_str3131[sizeof("gonohe.aomori.jp")];
-    char stringpool_str3132[sizeof("tako.chiba.jp")];
-    char stringpool_str3133[sizeof("ine.kyoto.jp")];
-    char stringpool_str3134[sizeof("aridagawa.wakayama.jp")];
-    char stringpool_str3135[sizeof("priv.no")];
-    char stringpool_str3136[sizeof("leangaviika.no")];
-    char stringpool_str3137[sizeof("mc")];
-    char stringpool_str3138[sizeof("kaho.fukuoka.jp")];
-    char stringpool_str3139[sizeof("kawanishi.yamagata.jp")];
-    char stringpool_str3140[sizeof("austevoll.no")];
-    char stringpool_str3141[sizeof("bo.nordland.no")];
-    char stringpool_str3142[sizeof("ito.shizuoka.jp")];
-    char stringpool_str3143[sizeof("rhcloud.com")];
-    char stringpool_str3144[sizeof("lib.ok.us")];
-    char stringpool_str3145[sizeof("lib.or.us")];
-    char stringpool_str3146[sizeof("prd.mg")];
-    char stringpool_str3147[sizeof("lib.dc.us")];
-    char stringpool_str3148[sizeof("kitagawa.kochi.jp")];
-    char stringpool_str3149[sizeof("pe.kr")];
-    char stringpool_str3150[sizeof("tver.ru")];
-    char stringpool_str3151[sizeof("lib.pr.us")];
-    char stringpool_str3152[sizeof("mosjoen.no")];
-    char stringpool_str3153[sizeof("naturhistorisches.museum")];
-    char stringpool_str3154[sizeof("lib.sc.us")];
-    char stringpool_str3155[sizeof("tanohata.iwate.jp")];
-    char stringpool_str3156[sizeof("is-a-photographer.com")];
-    char stringpool_str3157[sizeof("verdal.no")];
-    char stringpool_str3158[sizeof("doesntexist.org")];
-    char stringpool_str3159[sizeof("p.bg")];
-    char stringpool_str3160[sizeof("kamishihoro.hokkaido.jp")];
-    char stringpool_str3161[sizeof("mi.th")];
-    char stringpool_str3162[sizeof("kashima.saga.jp")];
-    char stringpool_str3163[sizeof("blogspot.com.br")];
-    char stringpool_str3164[sizeof("hashimoto.wakayama.jp")];
-    char stringpool_str3165[sizeof("xn--rhqv96g")];
-    char stringpool_str3166[sizeof("k12.vi")];
-    char stringpool_str3167[sizeof("pb.ao")];
-    char stringpool_str3168[sizeof("togakushi.nagano.jp")];
-    char stringpool_str3169[sizeof("nabari.mie.jp")];
-    char stringpool_str3170[sizeof("lib.al.us")];
-    char stringpool_str3171[sizeof("lib.ak.us")];
-    char stringpool_str3172[sizeof("lib.ar.us")];
-    char stringpool_str3173[sizeof("tm.mg")];
-    char stringpool_str3174[sizeof("xn--srum-gra.no")];
-    char stringpool_str3175[sizeof("matsubara.osaka.jp")];
-    char stringpool_str3176[sizeof("mil.ve")];
-    char stringpool_str3177[sizeof("kusatsu.shiga.jp")];
-    char stringpool_str3178[sizeof("achi.nagano.jp")];
-    char stringpool_str3179[sizeof("tsukigata.hokkaido.jp")];
-    char stringpool_str3180[sizeof("lib.tx.us")];
-    char stringpool_str3181[sizeof("toya.hokkaido.jp")];
-    char stringpool_str3182[sizeof("ebiz.tw")];
-    char stringpool_str3183[sizeof("lib.as.us")];
-    char stringpool_str3184[sizeof("lib.sd.us")];
-    char stringpool_str3185[sizeof("kiyose.tokyo.jp")];
-    char stringpool_str3186[sizeof("kadoma.osaka.jp")];
-    char stringpool_str3187[sizeof("chikuhoku.nagano.jp")];
-    char stringpool_str3188[sizeof("yomitan.okinawa.jp")];
-    char stringpool_str3189[sizeof("lib.tn.us")];
-    char stringpool_str3190[sizeof("genova.it")];
-    char stringpool_str3191[sizeof("chikuma.nagano.jp")];
-    char stringpool_str3192[sizeof("blogspot.sg")];
-    char stringpool_str3193[sizeof("lib.ut.us")];
-    char stringpool_str3194[sizeof("aomori.aomori.jp")];
-    char stringpool_str3195[sizeof("lib.de.us")];
-    char stringpool_str3196[sizeof("aomori.jp")];
-    char stringpool_str3197[sizeof("nationalheritage.museum")];
-    char stringpool_str3198[sizeof("troandin.no")];
-    char stringpool_str3199[sizeof("resistance.museum")];
-    char stringpool_str3200[sizeof("xn--aroport-bya.ci")];
-    char stringpool_str3201[sizeof("xn--gjvik-wua.no")];
-    char stringpool_str3202[sizeof("ebetsu.hokkaido.jp")];
-    char stringpool_str3203[sizeof("pp.ru")];
-    char stringpool_str3204[sizeof("yoshimi.saitama.jp")];
-    char stringpool_str3205[sizeof("toyoake.aichi.jp")];
-    char stringpool_str3206[sizeof("toyooka.hyogo.jp")];
-    char stringpool_str3207[sizeof("matta-varjjat.no")];
-    char stringpool_str3208[sizeof("dnsalias.org")];
-    char stringpool_str3209[sizeof("ralingen.no")];
-    char stringpool_str3210[sizeof("dynalias.org")];
-    char stringpool_str3211[sizeof("pl.ua")];
-    char stringpool_str3212[sizeof("xn--czrw28b.tw")];
-    char stringpool_str3213[sizeof("hirogawa.wakayama.jp")];
-    char stringpool_str3214[sizeof("lib.mt.us")];
-    char stringpool_str3215[sizeof("dyndns-at-home.com")];
-    char stringpool_str3216[sizeof("transport.museum")];
-    char stringpool_str3217[sizeof("modelling.aero")];
-    char stringpool_str3218[sizeof("lyngen.no")];
-    char stringpool_str3219[sizeof("is-a-soxfan.org")];
-    char stringpool_str3220[sizeof("aostavalley.it")];
-    char stringpool_str3221[sizeof("kasugai.aichi.jp")];
-    char stringpool_str3222[sizeof("port.fr")];
-    char stringpool_str3223[sizeof("amursk.ru")];
-    char stringpool_str3224[sizeof("lib.mn.us")];
-    char stringpool_str3225[sizeof("kayabe.hokkaido.jp")];
-    char stringpool_str3226[sizeof("ngo.ph")];
-    char stringpool_str3227[sizeof("lib.ms.us")];
-    char stringpool_str3228[sizeof("per.nf")];
-    char stringpool_str3229[sizeof("higashihiroshima.hiroshima.jp")];
-    char stringpool_str3230[sizeof("kuwana.mie.jp")];
-    char stringpool_str3231[sizeof("lib.il.us")];
-    char stringpool_str3232[sizeof("center.museum")];
-    char stringpool_str3233[sizeof("tomi.nagano.jp")];
-    char stringpool_str3234[sizeof("blogspot.gr")];
-    char stringpool_str3235[sizeof("elblag.pl")];
-    char stringpool_str3236[sizeof("ancona.it")];
-    char stringpool_str3237[sizeof("lib.nc.us")];
-    char stringpool_str3238[sizeof("lib.in.us")];
-    char stringpool_str3239[sizeof("tatebayashi.gunma.jp")];
-    char stringpool_str3240[sizeof("tomioka.gunma.jp")];
-    char stringpool_str3241[sizeof("pistoia.it")];
-    char stringpool_str3242[sizeof("fo")];
-    char stringpool_str3243[sizeof("odessa.ua")];
-    char stringpool_str3244[sizeof("net.do")];
-    char stringpool_str3245[sizeof("fj")];
-    char stringpool_str3246[sizeof("katori.chiba.jp")];
-    char stringpool_str3247[sizeof("tokushima.jp")];
-    char stringpool_str3248[sizeof("com.do")];
-    char stringpool_str3249[sizeof("toyohashi.aichi.jp")];
-    char stringpool_str3250[sizeof("gov.do")];
-    char stringpool_str3251[sizeof("net.so")];
-    char stringpool_str3252[sizeof("kouyama.kagoshima.jp")];
-    char stringpool_str3253[sizeof("net.jo")];
-    char stringpool_str3254[sizeof("com.so")];
-    char stringpool_str3255[sizeof("kyotamba.kyoto.jp")];
-    char stringpool_str3256[sizeof("com.jo")];
-    char stringpool_str3257[sizeof("gov.jo")];
-    char stringpool_str3258[sizeof("ryugasaki.ibaraki.jp")];
-    char stringpool_str3259[sizeof("tsukumi.oita.jp")];
-    char stringpool_str3260[sizeof("lib.md.us")];
-    char stringpool_str3261[sizeof("nationalfirearms.museum")];
-    char stringpool_str3262[sizeof("verran.no")];
-    char stringpool_str3263[sizeof("gob.do")];
-    char stringpool_str3264[sizeof("hamada.shimane.jp")];
-    char stringpool_str3265[sizeof("yame.fukuoka.jp")];
-    char stringpool_str3266[sizeof("koshimizu.hokkaido.jp")];
-    char stringpool_str3267[sizeof("iwafune.tochigi.jp")];
-    char stringpool_str3268[sizeof("kunigami.okinawa.jp")];
-    char stringpool_str3269[sizeof("se")];
-    char stringpool_str3270[sizeof("blogspot.cv")];
-    char stringpool_str3271[sizeof("sd")];
-    char stringpool_str3272[sizeof("nagara.chiba.jp")];
-    char stringpool_str3273[sizeof("garden.museum")];
-    char stringpool_str3274[sizeof("so")];
-    char stringpool_str3275[sizeof("sj")];
-    char stringpool_str3276[sizeof("soy")];
-    char stringpool_str3277[sizeof("mx")];
-    char stringpool_str3278[sizeof("lib.me.us")];
-    char stringpool_str3279[sizeof("xxx")];
-    char stringpool_str3280[sizeof("edu.do")];
-    char stringpool_str3281[sizeof("xn--bmlo-gra.no")];
-    char stringpool_str3282[sizeof("lib.id.us")];
-    char stringpool_str3283[sizeof("camp")];
-    char stringpool_str3284[sizeof("farm")];
-    char stringpool_str3285[sizeof("watch-and-clock.museum")];
-    char stringpool_str3286[sizeof("nishigo.fukushima.jp")];
-    char stringpool_str3287[sizeof("london.museum")];
-    char stringpool_str3288[sizeof("kani.gifu.jp")];
-    char stringpool_str3289[sizeof("edu.jo")];
-    char stringpool_str3290[sizeof("malbork.pl")];
-    char stringpool_str3291[sizeof("lib.nd.us")];
-    char stringpool_str3292[sizeof("chigasaki.kanagawa.jp")];
-    char stringpool_str3293[sizeof("lib.ks.us")];
-    char stringpool_str3294[sizeof("yonezawa.yamagata.jp")];
-    char stringpool_str3295[sizeof("mobi")];
-    char stringpool_str3296[sizeof("trogstad.no")];
-    char stringpool_str3297[sizeof("hitachinaka.ibaraki.jp")];
-    char stringpool_str3298[sizeof("numata.hokkaido.jp")];
-    char stringpool_str3299[sizeof("taka.hyogo.jp")];
-    char stringpool_str3300[sizeof("hinode.tokyo.jp")];
-    char stringpool_str3301[sizeof("fam.pk")];
-    char stringpool_str3302[sizeof("tsurugi.ishikawa.jp")];
-    char stringpool_str3303[sizeof("dyndns-at-work.com")];
-    char stringpool_str3304[sizeof("monash")];
-    char stringpool_str3305[sizeof("fr")];
-    char stringpool_str3306[sizeof("adygeya.ru")];
-    char stringpool_str3307[sizeof("net.to")];
-    char stringpool_str3308[sizeof("company")];
-    char stringpool_str3309[sizeof("com.to")];
-    char stringpool_str3310[sizeof("wegrow.pl")];
-    char stringpool_str3311[sizeof("gov.to")];
-    char stringpool_str3312[sizeof("higashitsuno.kochi.jp")];
-    char stringpool_str3313[sizeof("lib.ne.us")];
-    char stringpool_str3314[sizeof("sa")];
-    char stringpool_str3315[sizeof("com.ro")];
-    char stringpool_str3316[sizeof("wielun.pl")];
-    char stringpool_str3317[sizeof("mil.cl")];
-    char stringpool_str3318[sizeof("nom.ro")];
-    char stringpool_str3319[sizeof("kozaki.chiba.jp")];
-    char stringpool_str3320[sizeof("rikuzentakata.iwate.jp")];
-    char stringpool_str3321[sizeof("numazu.shizuoka.jp")];
-    char stringpool_str3322[sizeof("hasama.oita.jp")];
-    char stringpool_str3323[sizeof("lib.nj.us")];
-    char stringpool_str3324[sizeof("varese.it")];
-    char stringpool_str3325[sizeof("st")];
-    char stringpool_str3326[sizeof("landes.museum")];
-    char stringpool_str3327[sizeof("mil.cn")];
-    char stringpool_str3328[sizeof("yoshinogari.saga.jp")];
-    char stringpool_str3329[sizeof("sr")];
-    char stringpool_str3330[sizeof("lib.pa.us")];
-    char stringpool_str3331[sizeof("kawazu.shizuoka.jp")];
-    char stringpool_str3332[sizeof("mobi.na")];
-    char stringpool_str3333[sizeof("baikal.ru")];
-    char stringpool_str3334[sizeof("groundhandling.aero")];
-    char stringpool_str3335[sizeof("porsangu.no")];
-    char stringpool_str3336[sizeof("mobi.ng")];
-    char stringpool_str3337[sizeof("gujo.gifu.jp")];
-    char stringpool_str3338[sizeof("edu.to")];
-    char stringpool_str3339[sizeof("karlsoy.no")];
-    char stringpool_str3340[sizeof("fm")];
-    char stringpool_str3341[sizeof("su")];
-    char stringpool_str3342[sizeof("teshikaga.hokkaido.jp")];
-    char stringpool_str3343[sizeof("rennebu.no")];
-    char stringpool_str3344[sizeof("mito.ibaraki.jp")];
-    char stringpool_str3345[sizeof("berlin.museum")];
-    char stringpool_str3346[sizeof("net.mo")];
-    char stringpool_str3347[sizeof("com.mo")];
-    char stringpool_str3348[sizeof("gov.mo")];
-    char stringpool_str3349[sizeof("kaszuby.pl")];
-    char stringpool_str3350[sizeof("nishiizu.shizuoka.jp")];
-    char stringpool_str3351[sizeof("sz")];
-    char stringpool_str3352[sizeof("tatsuno.hyogo.jp")];
-    char stringpool_str3353[sizeof("matsudo.chiba.jp")];
-    char stringpool_str3354[sizeof("kesennuma.miyagi.jp")];
-    char stringpool_str3355[sizeof("yamagata.ibaraki.jp")];
-    char stringpool_str3356[sizeof("nagoya.jp")];
-    char stringpool_str3357[sizeof("higashi.fukuoka.jp")];
-    char stringpool_str3358[sizeof("hekinan.aichi.jp")];
-    char stringpool_str3359[sizeof("murmansk.ru")];
-    char stringpool_str3360[sizeof("heguri.nara.jp")];
-    char stringpool_str3361[sizeof("motorcycle.museum")];
-    char stringpool_str3362[sizeof("chieti.it")];
-    char stringpool_str3363[sizeof("fi")];
-    char stringpool_str3364[sizeof("sm")];
-    char stringpool_str3365[sizeof("jogasz.hu")];
-    char stringpool_str3366[sizeof("higashiomi.shiga.jp")];
-    char stringpool_str3367[sizeof("langevag.no")];
-    char stringpool_str3368[sizeof("higashiura.aichi.jp")];
-    char stringpool_str3369[sizeof("higashisumiyoshi.osaka.jp")];
-    char stringpool_str3370[sizeof("com.io")];
-    char stringpool_str3371[sizeof("training")];
-    char stringpool_str3372[sizeof("estate.museum")];
-    char stringpool_str3373[sizeof("assabu.hokkaido.jp")];
-    char stringpool_str3374[sizeof("fin.ec")];
-    char stringpool_str3375[sizeof("kurobe.toyama.jp")];
-    char stringpool_str3376[sizeof("divttasvuotna.no")];
-    char stringpool_str3377[sizeof("tv.it")];
-    char stringpool_str3378[sizeof("yokaichiba.chiba.jp")];
-    char stringpool_str3379[sizeof("edu.mo")];
-    char stringpool_str3380[sizeof("org.do")];
-    char stringpool_str3381[sizeof("kagawa.jp")];
-    char stringpool_str3382[sizeof("paderborn.museum")];
-    char stringpool_str3383[sizeof("trentino.it")];
-    char stringpool_str3384[sizeof("org.so")];
-    char stringpool_str3385[sizeof("boston.museum")];
-    char stringpool_str3386[sizeof("rc.it")];
-    char stringpool_str3387[sizeof("org.jo")];
-    char stringpool_str3388[sizeof("toei.aichi.jp")];
-    char stringpool_str3389[sizeof("nakagawa.tokushima.jp")];
-    char stringpool_str3390[sizeof("nature.museum")];
-    char stringpool_str3391[sizeof("e-burg.ru")];
-    char stringpool_str3392[sizeof("si")];
-    char stringpool_str3393[sizeof("dreamhosters.com")];
-    char stringpool_str3394[sizeof("kujukuri.chiba.jp")];
-    char stringpool_str3395[sizeof("karate.museum")];
-    char stringpool_str3396[sizeof("art.do")];
-    char stringpool_str3397[sizeof("sn")];
-    char stringpool_str3398[sizeof("hamura.tokyo.jp")];
-    char stringpool_str3399[sizeof("spb.ru")];
-    char stringpool_str3400[sizeof("brasil.museum")];
-    char stringpool_str3401[sizeof("labour.museum")];
-    char stringpool_str3402[sizeof("mini")];
-    char stringpool_str3403[sizeof("fed.us")];
-    char stringpool_str3404[sizeof("net.bo")];
-    char stringpool_str3405[sizeof("bauern.museum")];
-    char stringpool_str3406[sizeof("com.bo")];
-    char stringpool_str3407[sizeof("gov.bo")];
-    char stringpool_str3408[sizeof("fot.br")];
-    char stringpool_str3409[sizeof("fst.br")];
-    char stringpool_str3410[sizeof("lib.az.us")];
-    char stringpool_str3411[sizeof("olkusz.pl")];
-    char stringpool_str3412[sizeof("fk")];
-    char stringpool_str3413[sizeof("toyokawa.aichi.jp")];
-    char stringpool_str3414[sizeof("sumy.ua")];
-    char stringpool_str3415[sizeof("gob.bo")];
-    char stringpool_str3416[sizeof("osteroy.no")];
-    char stringpool_str3417[sizeof("kongsvinger.no")];
-    char stringpool_str3418[sizeof("lib.ma.us")];
-    char stringpool_str3419[sizeof("sos.pl")];
-    char stringpool_str3420[sizeof("sb")];
-    char stringpool_str3421[sizeof("tv.im")];
-    char stringpool_str3422[sizeof("isa-geek.org")];
-    char stringpool_str3423[sizeof("xn--9dbhblg6di.museum")];
-    char stringpool_str3424[sizeof("crafts.museum")];
-    char stringpool_str3425[sizeof("lom.no")];
-    char stringpool_str3426[sizeof("lib.ri.us")];
-    char stringpool_str3427[sizeof("solar")];
-    char stringpool_str3428[sizeof("christiansburg.museum")];
-    char stringpool_str3429[sizeof("tobetsu.hokkaido.jp")];
-    char stringpool_str3430[sizeof("umbria.it")];
-    char stringpool_str3431[sizeof("stv.ru")];
-    char stringpool_str3432[sizeof("edu.bo")];
-    char stringpool_str3433[sizeof("kofu.yamanashi.jp")];
-    char stringpool_str3434[sizeof("sk")];
-    char stringpool_str3435[sizeof("sar.it")];
-    char stringpool_str3436[sizeof("accident-prevention.aero")];
-    char stringpool_str3437[sizeof("jorpeland.no")];
-    char stringpool_str3438[sizeof("org.to")];
-    char stringpool_str3439[sizeof("kitami.hokkaido.jp")];
-    char stringpool_str3440[sizeof("tabayama.yamanashi.jp")];
-    char stringpool_str3441[sizeof("fin.tn")];
-    char stringpool_str3442[sizeof("org.ro")];
-    char stringpool_str3443[sizeof("lib.ia.us")];
-    char stringpool_str3444[sizeof("far.br")];
-    char stringpool_str3445[sizeof("takazaki.miyazaki.jp")];
-    char stringpool_str3446[sizeof("mragowo.pl")];
-    char stringpool_str3447[sizeof("med.om")];
-    char stringpool_str3448[sizeof("pisa.it")];
-    char stringpool_str3449[sizeof("celtic.museum")];
-    char stringpool_str3450[sizeof("sund.no")];
-    char stringpool_str3451[sizeof("stat.no")];
-    char stringpool_str3452[sizeof("firm.ro")];
-    char stringpool_str3453[sizeof("fie.ee")];
-    char stringpool_str3454[sizeof("f.se")];
-    char stringpool_str3455[sizeof("firm.co")];
-    char stringpool_str3456[sizeof("xn--aurskog-hland-jnb.no")];
-    char stringpool_str3457[sizeof("urausu.hokkaido.jp")];
-    char stringpool_str3458[sizeof("sl")];
-    char stringpool_str3459[sizeof("luzern.museum")];
-    char stringpool_str3460[sizeof("blogspot.co.uk")];
-    char stringpool_str3461[sizeof("tv.na")];
-    char stringpool_str3462[sizeof("louvre.museum")];
-    char stringpool_str3463[sizeof("gol.no")];
-    char stringpool_str3464[sizeof("sola.no")];
-    char stringpool_str3465[sizeof("kaizuka.osaka.jp")];
-    char stringpool_str3466[sizeof("lib.mi.us")];
-    char stringpool_str3467[sizeof("warmia.pl")];
-    char stringpool_str3468[sizeof("tsushima.aichi.jp")];
-    char stringpool_str3469[sizeof("cieszyn.pl")];
-    char stringpool_str3470[sizeof("xn--ggaviika-8ya47h.no")];
-    char stringpool_str3471[sizeof("higashimurayama.tokyo.jp")];
-    char stringpool_str3472[sizeof("esashi.hokkaido.jp")];
-    char stringpool_str3473[sizeof("ketrzyn.pl")];
-    char stringpool_str3474[sizeof("xn--trgstad-r1a.no")];
-    char stringpool_str3475[sizeof("canada.museum")];
-    char stringpool_str3476[sizeof("s.se")];
-    char stringpool_str3477[sizeof("org.mo")];
-    char stringpool_str3478[sizeof("yokosuka.kanagawa.jp")];
-    char stringpool_str3479[sizeof("xn--rst-0na.no")];
-    char stringpool_str3480[sizeof("tsuyama.okayama.jp")];
-    char stringpool_str3481[sizeof("srv.br")];
-    char stringpool_str3482[sizeof("circus.museum")];
-    char stringpool_str3483[sizeof("xn--smna-gra.no")];
-    char stringpool_str3484[sizeof("hellas.museum")];
-    char stringpool_str3485[sizeof("xn--pgbs0dh")];
-    char stringpool_str3486[sizeof("takatsuki.osaka.jp")];
-    char stringpool_str3487[sizeof("mine.nu")];
-    char stringpool_str3488[sizeof("edunet.tn")];
-    char stringpool_str3489[sizeof("mil.sh")];
-    char stringpool_str3490[sizeof("tsugaru.aomori.jp")];
-    char stringpool_str3491[sizeof("is-a-linux-user.org")];
-    char stringpool_str3492[sizeof("verona.it")];
-    char stringpool_str3493[sizeof("ayagawa.kagawa.jp")];
-    char stringpool_str3494[sizeof("mil.ph")];
-    char stringpool_str3495[sizeof("bifuka.hokkaido.jp")];
-    char stringpool_str3496[sizeof("mg")];
-    char stringpool_str3497[sizeof("kurgan.ru")];
-    char stringpool_str3498[sizeof("kitagata.saga.jp")];
-    char stringpool_str3499[sizeof("snz.ru")];
-    char stringpool_str3500[sizeof("sh")];
-    char stringpool_str3501[sizeof("saga.jp")];
-    char stringpool_str3502[sizeof("lib.la.us")];
-    char stringpool_str3503[sizeof("sec.ps")];
-    char stringpool_str3504[sizeof("lunner.no")];
-    char stringpool_str3505[sizeof("xn--rdy-0nab.no")];
-    char stringpool_str3506[sizeof("kosaka.akita.jp")];
-    char stringpool_str3507[sizeof("ferrara.it")];
-    char stringpool_str3508[sizeof("kvinesdal.no")];
-    char stringpool_str3509[sizeof("odawara.kanagawa.jp")];
-    char stringpool_str3510[sizeof("priv.at")];
-    char stringpool_str3511[sizeof("perm.ru")];
-    char stringpool_str3512[sizeof("firm.nf")];
-    char stringpool_str3513[sizeof("atsuma.hokkaido.jp")];
-    char stringpool_str3514[sizeof("ohtawara.tochigi.jp")];
-    char stringpool_str3515[sizeof("int.bo")];
-    char stringpool_str3516[sizeof("wassamu.hokkaido.jp")];
-    char stringpool_str3517[sizeof("sy")];
-    char stringpool_str3518[sizeof("org.bo")];
-    char stringpool_str3519[sizeof("sula.no")];
-    char stringpool_str3520[sizeof("hamaroy.no")];
-    char stringpool_str3521[sizeof("hasuda.saitama.jp")];
-    char stringpool_str3522[sizeof("futbol")];
-    char stringpool_str3523[sizeof("xn--sr-odal-q1a.no")];
-    char stringpool_str3524[sizeof("moroyama.saitama.jp")];
-    char stringpool_str3525[sizeof("arq.br")];
-    char stringpool_str3526[sizeof("hemnes.no")];
-    char stringpool_str3527[sizeof("civilization.museum")];
-    char stringpool_str3528[sizeof("kamiamakusa.kumamoto.jp")];
-    char stringpool_str3529[sizeof("gangaviika.no")];
-    char stringpool_str3530[sizeof("georgia.museum")];
-    char stringpool_str3531[sizeof("paris")];
-    char stringpool_str3532[sizeof("nt.edu.au")];
-    char stringpool_str3533[sizeof("higashichichibu.saitama.jp")];
-    char stringpool_str3534[sizeof("marburg.museum")];
-    char stringpool_str3535[sizeof("laquila.it")];
-    char stringpool_str3536[sizeof("fusa.no")];
-    char stringpool_str3537[sizeof("iwanuma.miyagi.jp")];
-    char stringpool_str3538[sizeof("tamamura.gunma.jp")];
-    char stringpool_str3539[sizeof("tsumagoi.gunma.jp")];
-    char stringpool_str3540[sizeof("mizusawa.iwate.jp")];
-    char stringpool_str3541[sizeof("kvinnherad.no")];
-    char stringpool_str3542[sizeof("xn--givuotna-8ya.no")];
-    char stringpool_str3543[sizeof("tateshina.nagano.jp")];
-    char stringpool_str3544[sizeof("fhv.se")];
-    char stringpool_str3545[sizeof("hof.no")];
-    char stringpool_str3546[sizeof("gjovik.no")];
-    char stringpool_str3547[sizeof("stranda.no")];
-    char stringpool_str3548[sizeof("eid.no")];
-    char stringpool_str3549[sizeof("chikuho.fukuoka.jp")];
-    char stringpool_str3550[sizeof("computer")];
-    char stringpool_str3551[sizeof("noheji.aomori.jp")];
-    char stringpool_str3552[sizeof("ashibetsu.hokkaido.jp")];
-    char stringpool_str3553[sizeof("williamsburg.museum")];
-    char stringpool_str3554[sizeof("xn--lhppi-xqa.no")];
-    char stringpool_str3555[sizeof("crimea.ua")];
-    char stringpool_str3556[sizeof("city.yokohama.jp")];
-    char stringpool_str3557[sizeof("fnd.br")];
-    char stringpool_str3558[sizeof("control.aero")];
-    char stringpool_str3559[sizeof("hiratsuka.kanagawa.jp")];
-    char stringpool_str3560[sizeof("deatnu.no")];
-    char stringpool_str3561[sizeof("red.sv")];
-    char stringpool_str3562[sizeof("hol.no")];
-    char stringpool_str3563[sizeof("inderoy.no")];
-    char stringpool_str3564[sizeof("nagasu.kumamoto.jp")];
-    char stringpool_str3565[sizeof("lib.vt.us")];
-    char stringpool_str3566[sizeof("wazuka.kyoto.jp")];
-    char stringpool_str3567[sizeof("folldal.no")];
-    char stringpool_str3568[sizeof("bjarkoy.no")];
-    char stringpool_str3569[sizeof("mobi.tt")];
-    char stringpool_str3570[sizeof("adachi.tokyo.jp")];
-    char stringpool_str3571[sizeof("lib.wa.us")];
-    char stringpool_str3572[sizeof("lib.hi.us")];
-    char stringpool_str3573[sizeof("vossevangen.no")];
-    char stringpool_str3574[sizeof("blogdns.org")];
-    char stringpool_str3575[sizeof("tsuruga.fukui.jp")];
-    char stringpool_str3576[sizeof("mobi.gp")];
-    char stringpool_str3577[sizeof("xn--3bst00m")];
-    char stringpool_str3578[sizeof("macerata.it")];
-    char stringpool_str3579[sizeof("voagat.no")];
-    char stringpool_str3580[sizeof("pvt.k12.ma.us")];
-    char stringpool_str3581[sizeof("pomorze.pl")];
-    char stringpool_str3582[sizeof("takehara.hiroshima.jp")];
-    char stringpool_str3583[sizeof("hitachiomiya.ibaraki.jp")];
-    char stringpool_str3584[sizeof("ota.tokyo.jp")];
-    char stringpool_str3585[sizeof("xn--stjrdal-s1a.no")];
-    char stringpool_str3586[sizeof("rikubetsu.hokkaido.jp")];
-    char stringpool_str3587[sizeof("kouzushima.tokyo.jp")];
-    char stringpool_str3588[sizeof("stavern.no")];
-    char stringpool_str3589[sizeof("tsubetsu.hokkaido.jp")];
-    char stringpool_str3590[sizeof("mil.tm")];
-    char stringpool_str3591[sizeof("hidaka.hokkaido.jp")];
-    char stringpool_str3592[sizeof("sd.us")];
-    char stringpool_str3593[sizeof("chuo.yamanashi.jp")];
-    char stringpool_str3594[sizeof("slattum.no")];
-    char stringpool_str3595[sizeof("royken.no")];
-    char stringpool_str3596[sizeof("matsuda.kanagawa.jp")];
-    char stringpool_str3597[sizeof("matsuzaki.shizuoka.jp")];
-    char stringpool_str3598[sizeof("uji.kyoto.jp")];
-    char stringpool_str3599[sizeof("servebbs.net")];
-    char stringpool_str3600[sizeof("mari-el.ru")];
-    char stringpool_str3601[sizeof("austin.museum")];
-    char stringpool_str3602[sizeof("lib.wi.us")];
-    char stringpool_str3603[sizeof("kamagaya.chiba.jp")];
-    char stringpool_str3604[sizeof("pro")];
-    char stringpool_str3605[sizeof("web.do")];
-    char stringpool_str3606[sizeof("eidskog.no")];
-    char stringpool_str3607[sizeof("xn--sknland-fxa.no")];
-    char stringpool_str3608[sizeof("higashiyodogawa.osaka.jp")];
-    char stringpool_str3609[sizeof("prod")];
-    char stringpool_str3610[sizeof("castle.museum")];
-    char stringpool_str3611[sizeof("gliwice.pl")];
-    char stringpool_str3612[sizeof("pro.ec")];
-    char stringpool_str3613[sizeof("hanggliding.aero")];
-    char stringpool_str3614[sizeof("ome.tokyo.jp")];
-    char stringpool_str3615[sizeof("pro.pr")];
-    char stringpool_str3616[sizeof("gotdns.org")];
-    char stringpool_str3617[sizeof("soc.lk")];
-    char stringpool_str3618[sizeof("podhale.pl")];
-    char stringpool_str3619[sizeof("national-library-scotland.uk")];
-    char stringpool_str3620[sizeof("saltdal.no")];
-    char stringpool_str3621[sizeof("plumbing")];
-    char stringpool_str3622[sizeof("salerno.it")];
-    char stringpool_str3623[sizeof("slg.br")];
-    char stringpool_str3624[sizeof("dyndns-blog.com")];
-    char stringpool_str3625[sizeof("wakasa.tottori.jp")];
-    char stringpool_str3626[sizeof("murakami.niigata.jp")];
-    char stringpool_str3627[sizeof("xn--dyry-ira.no")];
-    char stringpool_str3628[sizeof("campobasso.it")];
-    char stringpool_str3629[sizeof("moseushi.hokkaido.jp")];
-    char stringpool_str3630[sizeof("cf")];
-    char stringpool_str3631[sizeof("bf")];
-    char stringpool_str3632[sizeof("gf")];
-    char stringpool_str3633[sizeof("ifm")];
-    char stringpool_str3634[sizeof("cinema.museum")];
-    char stringpool_str3635[sizeof("nf")];
-    char stringpool_str3636[sizeof("machida.tokyo.jp")];
-    char stringpool_str3637[sizeof("gdansk.pl")];
-    char stringpool_str3638[sizeof("me.it")];
-    char stringpool_str3639[sizeof("takahama.aichi.jp")];
-    char stringpool_str3640[sizeof("higashi.fukushima.jp")];
-    char stringpool_str3641[sizeof("com.fr")];
-    char stringpool_str3642[sizeof("flakstad.no")];
-    char stringpool_str3643[sizeof("mo.it")];
-    char stringpool_str3644[sizeof("aejrie.no")];
-    char stringpool_str3645[sizeof("vanylven.no")];
-    char stringpool_str3646[sizeof("nom.fr")];
-    char stringpool_str3647[sizeof("ms.it")];
-    char stringpool_str3648[sizeof("mil.gt")];
-    char stringpool_str3649[sizeof("aizumi.tokushima.jp")];
-    char stringpool_str3650[sizeof("oksnes.no")];
-    char stringpool_str3651[sizeof("rindal.no")];
-    char stringpool_str3652[sizeof("toshima.tokyo.jp")];
-    char stringpool_str3653[sizeof("nishiazai.shiga.jp")];
-    char stringpool_str3654[sizeof("nishikawa.yamagata.jp")];
-    char stringpool_str3655[sizeof("aioi.hyogo.jp")];
-    char stringpool_str3656[sizeof("museum")];
-    char stringpool_str3657[sizeof("pro.tt")];
-    char stringpool_str3658[sizeof("hidaka.saitama.jp")];
-    char stringpool_str3659[sizeof("pg")];
-    char stringpool_str3660[sizeof("sic.it")];
-    char stringpool_str3661[sizeof("trolley.museum")];
-    char stringpool_str3662[sizeof("net.gy")];
-    char stringpool_str3663[sizeof("com.gy")];
-    char stringpool_str3664[sizeof("marketplace.aero")];
-    char stringpool_str3665[sizeof("nakagawa.nagano.jp")];
-    char stringpool_str3666[sizeof("omotego.fukushima.jp")];
-    char stringpool_str3667[sizeof("sld.pa")];
-    char stringpool_str3668[sizeof("services")];
-    char stringpool_str3669[sizeof("hitachiota.ibaraki.jp")];
-    char stringpool_str3670[sizeof("co.pn")];
-    char stringpool_str3671[sizeof("writesthisblog.com")];
-    char stringpool_str3672[sizeof("gokase.miyazaki.jp")];
-    char stringpool_str3673[sizeof("kamogawa.chiba.jp")];
-    char stringpool_str3674[sizeof("kannami.shizuoka.jp")];
-    char stringpool_str3675[sizeof("mil.km")];
-    char stringpool_str3676[sizeof("mo-i-rana.no")];
-    char stringpool_str3677[sizeof("yugawara.kanagawa.jp")];
-    char stringpool_str3678[sizeof("yawata.kyoto.jp")];
-    char stringpool_str3679[sizeof("ichikawa.hyogo.jp")];
-    char stringpool_str3680[sizeof("mt.it")];
-    char stringpool_str3681[sizeof("joboji.iwate.jp")];
-    char stringpool_str3682[sizeof("sv")];
-    char stringpool_str3683[sizeof("sa.au")];
-    char stringpool_str3684[sizeof("sondrio.it")];
-    char stringpool_str3685[sizeof("kanegasaki.iwate.jp")];
-    char stringpool_str3686[sizeof("health.vn")];
-    char stringpool_str3687[sizeof("sohu")];
-    char stringpool_str3688[sizeof("f.bg")];
-    char stringpool_str3689[sizeof("eidfjord.no")];
-    char stringpool_str3690[sizeof("quebec.museum")];
-    char stringpool_str3691[sizeof("muroran.hokkaido.jp")];
-    char stringpool_str3692[sizeof("suzuki")];
-    char stringpool_str3693[sizeof("monticello.museum")];
-    char stringpool_str3694[sizeof("sm.ua")];
-    char stringpool_str3695[sizeof("elburg.museum")];
-    char stringpool_str3696[sizeof("xn--hgebostad-g3a.no")];
-    char stringpool_str3697[sizeof("sassari.it")];
-    char stringpool_str3698[sizeof("af")];
-    char stringpool_str3699[sizeof("mil.ge")];
-    char stringpool_str3700[sizeof("rg.it")];
-    char stringpool_str3701[sizeof("kumamoto.jp")];
-    char stringpool_str3702[sizeof("tranibarlettaandria.it")];
-    char stringpool_str3703[sizeof("trentino-stirol.it")];
-    char stringpool_str3704[sizeof("konskowola.pl")];
-    char stringpool_str3705[sizeof("yamakita.kanagawa.jp")];
-    char stringpool_str3706[sizeof("takahashi.okayama.jp")];
-    char stringpool_str3707[sizeof("numata.gunma.jp")];
-    char stringpool_str3708[sizeof("latina.it")];
-    char stringpool_str3709[sizeof("oregon.museum")];
-    char stringpool_str3710[sizeof("fish")];
-    char stringpool_str3711[sizeof("naoshima.kagawa.jp")];
-    char stringpool_str3712[sizeof("s.bg")];
-    char stringpool_str3713[sizeof("sauherad.no")];
-    char stringpool_str3714[sizeof("kostroma.ru")];
-    char stringpool_str3715[sizeof("sa.cr")];
-    char stringpool_str3716[sizeof("xn--hylandet-54a.no")];
-    char stringpool_str3717[sizeof("appspot.com")];
-    char stringpool_str3718[sizeof("campidanomedio.it")];
-    char stringpool_str3719[sizeof("fukuoka.jp")];
-    char stringpool_str3720[sizeof("solutions")];
-    char stringpool_str3721[sizeof("takasaki.gunma.jp")];
-    char stringpool_str3722[sizeof("kemerovo.ru")];
-    char stringpool_str3723[sizeof("fj.cn")];
-    char stringpool_str3724[sizeof("co.pl")];
-    char stringpool_str3725[sizeof("trani-andria-barletta.it")];
-    char stringpool_str3726[sizeof("mr.no")];
-    char stringpool_str3727[sizeof("lib.va.us")];
-    char stringpool_str3728[sizeof("fl.us")];
-    char stringpool_str3729[sizeof("ishigaki.okinawa.jp")];
-    char stringpool_str3730[sizeof("fareast.ru")];
-    char stringpool_str3731[sizeof("uslivinghistory.museum")];
-    char stringpool_str3732[sizeof("preservation.museum")];
-    char stringpool_str3733[sizeof("nakagusuku.okinawa.jp")];
-    char stringpool_str3734[sizeof("matsushige.tokushima.jp")];
-    char stringpool_str3735[sizeof("pro.br")];
-    char stringpool_str3736[sizeof("fuel.aero")];
-    char stringpool_str3737[sizeof("midsund.no")];
-    char stringpool_str3738[sizeof("archaeological.museum")];
-    char stringpool_str3739[sizeof("mi.it")];
-    char stringpool_str3740[sizeof("plo.ps")];
-    char stringpool_str3741[sizeof("sd.cn")];
-    char stringpool_str3742[sizeof("hawaii.museum")];
-    char stringpool_str3743[sizeof("usarts.museum")];
-    char stringpool_str3744[sizeof("mod.gi")];
-    char stringpool_str3745[sizeof("mn.it")];
-    char stringpool_str3746[sizeof("sb.ua")];
-    char stringpool_str3747[sizeof("lib.ct.us")];
-    char stringpool_str3748[sizeof("trentinosudtirol.it")];
-    char stringpool_str3749[sizeof("prof.pr")];
-    char stringpool_str3750[sizeof("kumatori.osaka.jp")];
-    char stringpool_str3751[sizeof("sondre-land.no")];
-    char stringpool_str3752[sizeof("missile.museum")];
-    char stringpool_str3753[sizeof("miho.ibaraki.jp")];
-    char stringpool_str3754[sizeof("mashiki.kumamoto.jp")];
-    char stringpool_str3755[sizeof("kunohe.iwate.jp")];
-    char stringpool_str3756[sizeof("sells-for-u.com")];
-    char stringpool_str3757[sizeof("sells-it.net")];
-    char stringpool_str3758[sizeof("oamishirasato.chiba.jp")];
-    char stringpool_str3759[sizeof("mb.it")];
-    char stringpool_str3760[sizeof("fh.se")];
-    char stringpool_str3761[sizeof("fi.cr")];
-    char stringpool_str3762[sizeof("vladivostok.ru")];
-    char stringpool_str3763[sizeof("mima.tokushima.jp")];
-    char stringpool_str3764[sizeof("oita.oita.jp")];
-    char stringpool_str3765[sizeof("iglesias-carbonia.it")];
-    char stringpool_str3766[sizeof("lib.vi.us")];
-    char stringpool_str3767[sizeof("firm.in")];
-    char stringpool_str3768[sizeof("trentino-s-tirol.it")];
-    char stringpool_str3769[sizeof("photo")];
-    char stringpool_str3770[sizeof("tachikawa.tokyo.jp")];
-    char stringpool_str3771[sizeof("alaska.museum")];
-    char stringpool_str3772[sizeof("saga.saga.jp")];
-    char stringpool_str3773[sizeof("kiyosu.aichi.jp")];
-    char stringpool_str3774[sizeof("trentinostirol.it")];
-    char stringpool_str3775[sizeof("krasnoyarsk.ru")];
-    char stringpool_str3776[sizeof("gwangju.kr")];
-    char stringpool_str3777[sizeof("usui.fukuoka.jp")];
-    char stringpool_str3778[sizeof("midtre-gauldal.no")];
-    char stringpool_str3779[sizeof("dyn-o-saur.com")];
-    char stringpool_str3780[sizeof("corporation.museum")];
-    char stringpool_str3781[sizeof("tokashiki.okinawa.jp")];
-    char stringpool_str3782[sizeof("photos")];
-    char stringpool_str3783[sizeof("prd.km")];
-    char stringpool_str3784[sizeof("warabi.saitama.jp")];
-    char stringpool_str3785[sizeof("ninohe.iwate.jp")];
-    char stringpool_str3786[sizeof("services.aero")];
-    char stringpool_str3787[sizeof("kawachinagano.osaka.jp")];
-    char stringpool_str3788[sizeof("kawaba.gunma.jp")];
-    char stringpool_str3789[sizeof("hikawa.shimane.jp")];
-    char stringpool_str3790[sizeof("television.museum")];
-    char stringpool_str3791[sizeof("fyresdal.no")];
-    char stringpool_str3792[sizeof("otoineppu.hokkaido.jp")];
-    char stringpool_str3793[sizeof("campania.it")];
-    char stringpool_str3794[sizeof("pro.ht")];
-    char stringpool_str3795[sizeof("sk.ca")];
-    char stringpool_str3796[sizeof("ne.pw")];
-    char stringpool_str3797[sizeof("is-saved.org")];
-    char stringpool_str3798[sizeof("webhop.biz")];
-    char stringpool_str3799[sizeof("co.pw")];
-    char stringpool_str3800[sizeof("go.pw")];
-    char stringpool_str3801[sizeof("my.id")];
-    char stringpool_str3802[sizeof("soka.saitama.jp")];
-    char stringpool_str3803[sizeof("student.aero")];
-    char stringpool_str3804[sizeof("takamatsu.kagawa.jp")];
-    char stringpool_str3805[sizeof("trentino-suedtirol.it")];
-    char stringpool_str3806[sizeof("oizumi.gunma.jp")];
-    char stringpool_str3807[sizeof("ed.pw")];
-    char stringpool_str3808[sizeof("evenes.no")];
-    char stringpool_str3809[sizeof("pe.it")];
-    char stringpool_str3810[sizeof("yachimata.chiba.jp")];
-    char stringpool_str3811[sizeof("johana.toyama.jp")];
-    char stringpool_str3812[sizeof("pd.it")];
-    char stringpool_str3813[sizeof("doomdns.org")];
-    char stringpool_str3814[sizeof("po.it")];
-    char stringpool_str3815[sizeof("kusu.oita.jp")];
-    char stringpool_str3816[sizeof("xn--i1b6b1a6a2e")];
-    char stringpool_str3817[sizeof("trentinoaadige.it")];
-    char stringpool_str3818[sizeof("trentino-sudtirol.it")];
-    char stringpool_str3819[sizeof("fvg.it")];
-    char stringpool_str3820[sizeof("yamada.toyama.jp")];
-    char stringpool_str3821[sizeof("fishing")];
-    char stringpool_str3822[sizeof("trentino-sud-tirol.it")];
-    char stringpool_str3823[sizeof("wa.edu.au")];
-    char stringpool_str3824[sizeof("joetsu.niigata.jp")];
-    char stringpool_str3825[sizeof("ragusa.it")];
-    char stringpool_str3826[sizeof("trysil.no")];
-    char stringpool_str3827[sizeof("sn.cn")];
-    char stringpool_str3828[sizeof("trentinos-tirol.it")];
-    char stringpool_str3829[sizeof("mykolaiv.ua")];
-    char stringpool_str3830[sizeof("or.pw")];
-    char stringpool_str3831[sizeof("rollag.no")];
-    char stringpool_str3832[sizeof("pro.az")];
-    char stringpool_str3833[sizeof("trentinosuedtirol.it")];
-    char stringpool_str3834[sizeof("pruszkow.pl")];
-    char stringpool_str3835[sizeof("trentinosued-tirol.it")];
-    char stringpool_str3836[sizeof("pa.it")];
-    char stringpool_str3837[sizeof("date.fukushima.jp")];
-    char stringpool_str3838[sizeof("midatlantic.museum")];
-    char stringpool_str3839[sizeof("nago.okinawa.jp")];
-    char stringpool_str3840[sizeof("asso.nc")];
-    char stringpool_str3841[sizeof("net.co")];
-    char stringpool_str3842[sizeof("hannan.osaka.jp")];
-    char stringpool_str3843[sizeof("onna.okinawa.jp")];
-    char stringpool_str3844[sizeof("sor-odal.no")];
-    char stringpool_str3845[sizeof("com.co")];
-    char stringpool_str3846[sizeof("gov.co")];
-    char stringpool_str3847[sizeof("siellak.no")];
-    char stringpool_str3848[sizeof("nom.co")];
-    char stringpool_str3849[sizeof("kalisz.pl")];
-    char stringpool_str3850[sizeof("fredrikstad.no")];
-    char stringpool_str3851[sizeof("fm.br")];
-    char stringpool_str3852[sizeof("pt.it")];
-    char stringpool_str3853[sizeof("fhsk.se")];
-    char stringpool_str3854[sizeof("chungbuk.kr")];
-    char stringpool_str3855[sizeof("pr.it")];
-    char stringpool_str3856[sizeof("industries")];
-    char stringpool_str3857[sizeof("miyashiro.saitama.jp")];
-    char stringpool_str3858[sizeof("hita.oita.jp")];
-    char stringpool_str3859[sizeof("bremanger.no")];
-    char stringpool_str3860[sizeof("sc")];
-    char stringpool_str3861[sizeof("agrigento.it")];
-    char stringpool_str3862[sizeof("spydeberg.no")];
-    char stringpool_str3863[sizeof("info.ec")];
-    char stringpool_str3864[sizeof("homeftp.net")];
-    char stringpool_str3865[sizeof("pu.it")];
-    char stringpool_str3866[sizeof("minamata.kumamoto.jp")];
-    char stringpool_str3867[sizeof("pro.na")];
-    char stringpool_str3868[sizeof("scb")];
-    char stringpool_str3869[sizeof("airport.aero")];
-    char stringpool_str3870[sizeof("palermo.it")];
-    char stringpool_str3871[sizeof("edu.co")];
-    char stringpool_str3872[sizeof("gratangen.no")];
-    char stringpool_str3873[sizeof("lib.oh.us")];
-    char stringpool_str3874[sizeof("travel.tt")];
-    char stringpool_str3875[sizeof("pz.it")];
-    char stringpool_str3876[sizeof("jpn.com")];
-    char stringpool_str3877[sizeof("sevastopol.ua")];
-    char stringpool_str3878[sizeof("sardinia.it")];
-    char stringpool_str3879[sizeof("minami-alps.yamanashi.jp")];
-    char stringpool_str3880[sizeof("trani-barletta-andria.it")];
-    char stringpool_str3881[sizeof("xn--1qqw23a")];
-    char stringpool_str3882[sizeof("yokote.akita.jp")];
-    char stringpool_str3883[sizeof("nagatoro.saitama.jp")];
-    char stringpool_str3884[sizeof("medecin.km")];
-    char stringpool_str3885[sizeof("sebastopol.ua")];
-    char stringpool_str3886[sizeof("kami.miyagi.jp")];
-    char stringpool_str3887[sizeof("gdynia.pl")];
-    char stringpool_str3888[sizeof("mashike.hokkaido.jp")];
-    char stringpool_str3889[sizeof("takaharu.miyazaki.jp")];
-    char stringpool_str3890[sizeof("limanowa.pl")];
-    char stringpool_str3891[sizeof("tynset.no")];
-    char stringpool_str3892[sizeof("philately.museum")];
-    char stringpool_str3893[sizeof("kasamatsu.gifu.jp")];
-    char stringpool_str3894[sizeof("unazuki.toyama.jp")];
-    char stringpool_str3895[sizeof("annaka.gunma.jp")];
-    char stringpool_str3896[sizeof("lib.ca.us")];
-    char stringpool_str3897[sizeof("www.ro")];
-    char stringpool_str3898[sizeof("pi.it")];
-    char stringpool_str3899[sizeof("ballangen.no")];
-    char stringpool_str3900[sizeof("batsfjord.no")];
-    char stringpool_str3901[sizeof("xn--avery-yua.no")];
-    char stringpool_str3902[sizeof("sado.niigata.jp")];
-    char stringpool_str3903[sizeof("pn.it")];
-    char stringpool_str3904[sizeof("campidano-medio.it")];
-    char stringpool_str3905[sizeof("trentino-sued-tirol.it")];
-    char stringpool_str3906[sizeof("ivanovo.ru")];
-    char stringpool_str3907[sizeof("sandnes.no")];
-    char stringpool_str3908[sizeof("off.ai")];
-    char stringpool_str3909[sizeof("zachpomor.pl")];
-    char stringpool_str3910[sizeof("xn--czrs0t")];
-    char stringpool_str3911[sizeof("sh.cn")];
-    char stringpool_str3912[sizeof("suedtirol.it")];
-    char stringpool_str3913[sizeof("otsuki.yamanashi.jp")];
-    char stringpool_str3914[sizeof("saarland")];
-    char stringpool_str3915[sizeof("magnitka.ru")];
-    char stringpool_str3916[sizeof("aerodrome.aero")];
-    char stringpool_str3917[sizeof("kvafjord.no")];
-    char stringpool_str3918[sizeof("yokoze.saitama.jp")];
-    char stringpool_str3919[sizeof("is-a-musician.com")];
-    char stringpool_str3920[sizeof("mediocampidano.it")];
-    char stringpool_str3921[sizeof("miyazaki.miyazaki.jp")];
-    char stringpool_str3922[sizeof("aquila.it")];
-    char stringpool_str3923[sizeof("minamiyamashiro.kyoto.jp")];
-    char stringpool_str3924[sizeof("sortland.no")];
-    char stringpool_str3925[sizeof("narita.chiba.jp")];
-    char stringpool_str3926[sizeof("agematsu.nagano.jp")];
-    char stringpool_str3927[sizeof("takayama.gunma.jp")];
-    char stringpool_str3928[sizeof("gojome.akita.jp")];
-    char stringpool_str3929[sizeof("perugia.it")];
-    char stringpool_str3930[sizeof("sandefjord.no")];
-    char stringpool_str3931[sizeof("tsuchiura.ibaraki.jp")];
-    char stringpool_str3932[sizeof("usenet.pl")];
-    char stringpool_str3933[sizeof("setouchi.okayama.jp")];
-    char stringpool_str3934[sizeof("xn--ldingen-q1a.no")];
-    char stringpool_str3935[sizeof("int.co")];
-    char stringpool_str3936[sizeof("kvitsoy.no")];
-    char stringpool_str3937[sizeof("wf")];
-    char stringpool_str3938[sizeof("timekeeping.museum")];
-    char stringpool_str3939[sizeof("kasama.ibaraki.jp")];
-    char stringpool_str3940[sizeof("trentinosud-tirol.it")];
-    char stringpool_str3941[sizeof("org.co")];
-    char stringpool_str3942[sizeof("if.ua")];
-    char stringpool_str3943[sizeof("inazawa.aichi.jp")];
-    char stringpool_str3944[sizeof("onjuku.chiba.jp")];
-    char stringpool_str3945[sizeof("gemological.museum")];
-    char stringpool_str3946[sizeof("is-a-financialadvisor.com")];
-    char stringpool_str3947[sizeof("agriculture.museum")];
-    char stringpool_str3948[sizeof("tamatsukuri.ibaraki.jp")];
-    char stringpool_str3949[sizeof("tokushima.tokushima.jp")];
-    char stringpool_str3950[sizeof("farmstead.museum")];
-    char stringpool_str3951[sizeof("uchihara.ibaraki.jp")];
-    char stringpool_str3952[sizeof("tsushima.nagasaki.jp")];
-    char stringpool_str3953[sizeof("komaki.aichi.jp")];
-    char stringpool_str3954[sizeof("aurskog-holand.no")];
-    char stringpool_str3955[sizeof("xn--ygarden-p1a.no")];
-    char stringpool_str3956[sizeof("lib.nh.us")];
-    char stringpool_str3957[sizeof("balsfjord.no")];
-    char stringpool_str3958[sizeof("mibu.tochigi.jp")];
-    char stringpool_str3959[sizeof("is-a-celticsfan.org")];
-    char stringpool_str3960[sizeof("colonialwilliamsburg.museum")];
-    char stringpool_str3961[sizeof("exhibition.museum")];
-    char stringpool_str3962[sizeof("utsira.no")];
-    char stringpool_str3963[sizeof("contractors")];
-    char stringpool_str3964[sizeof("kisarazu.chiba.jp")];
-    char stringpool_str3965[sizeof("exeter.museum")];
-    char stringpool_str3966[sizeof("firenze.it")];
-    char stringpool_str3967[sizeof("xn--rmskog-bya.no")];
-    char stringpool_str3968[sizeof("xn--io0a7i")];
-    char stringpool_str3969[sizeof("flesberg.no")];
-    char stringpool_str3970[sizeof("dyndns.tv")];
-    char stringpool_str3971[sizeof("conference.aero")];
-    char stringpool_str3972[sizeof("sowa.ibaraki.jp")];
-    char stringpool_str3973[sizeof("nerima.tokyo.jp")];
-    char stringpool_str3974[sizeof("suwa.nagano.jp")];
-    char stringpool_str3975[sizeof("flekkefjord.no")];
-    char stringpool_str3976[sizeof("sx")];
-    char stringpool_str3977[sizeof("nf.ca")];
-    char stringpool_str3978[sizeof("xn--mgbbh1a71e")];
-    char stringpool_str3979[sizeof("bomlo.no")];
-    char stringpool_str3980[sizeof("pro.vn")];
-    char stringpool_str3981[sizeof("pyatigorsk.ru")];
-    char stringpool_str3982[sizeof("takayama.nagano.jp")];
-    char stringpool_str3983[sizeof("travel.pl")];
-    char stringpool_str3984[sizeof("piacenza.it")];
-    char stringpool_str3985[sizeof("minamiboso.chiba.jp")];
-    char stringpool_str3986[sizeof("nanporo.hokkaido.jp")];
-    char stringpool_str3987[sizeof("sardegna.it")];
-    char stringpool_str3988[sizeof("filatelia.museum")];
-    char stringpool_str3989[sizeof("czest.pl")];
-    char stringpool_str3990[sizeof("greta.fr")];
-    char stringpool_str3991[sizeof("higashikagura.hokkaido.jp")];
-    char stringpool_str3992[sizeof("productions")];
-    char stringpool_str3993[sizeof("seto.aichi.jp")];
-    char stringpool_str3994[sizeof("matsukawa.nagano.jp")];
-    char stringpool_str3995[sizeof("bialowieza.pl")];
-    char stringpool_str3996[sizeof("bahcavuotna.no")];
-    char stringpool_str3997[sizeof("vantaa.museum")];
-    char stringpool_str3998[sizeof("toon.ehime.jp")];
-    char stringpool_str3999[sizeof("eidsvoll.no")];
-    char stringpool_str4000[sizeof("kagami.kochi.jp")];
-    char stringpool_str4001[sizeof("yanaizu.fukushima.jp")];
-    char stringpool_str4002[sizeof("echizen.fukui.jp")];
-    char stringpool_str4003[sizeof("kokonoe.oita.jp")];
-    char stringpool_str4004[sizeof("vyatka.ru")];
-    char stringpool_str4005[sizeof("suwalki.pl")];
-    char stringpool_str4006[sizeof("stuttgart.museum")];
-    char stringpool_str4007[sizeof("kanzaki.saga.jp")];
-    char stringpool_str4008[sizeof("webhop.org")];
-    char stringpool_str4009[sizeof("tateyama.chiba.jp")];
-    char stringpool_str4010[sizeof("lib.nm.us")];
-    char stringpool_str4011[sizeof("notaires.fr")];
-    char stringpool_str4012[sizeof("takikawa.hokkaido.jp")];
-    char stringpool_str4013[sizeof("minnesota.museum")];
-    char stringpool_str4014[sizeof("mari.ru")];
-    char stringpool_str4015[sizeof("salangen.no")];
-    char stringpool_str4016[sizeof("foo")];
-    char stringpool_str4017[sizeof("coop")];
-    char stringpool_str4018[sizeof("tysvar.no")];
-    char stringpool_str4019[sizeof("minamiizu.shizuoka.jp")];
-    char stringpool_str4020[sizeof("motoyama.kochi.jp")];
-    char stringpool_str4021[sizeof("kahoku.ishikawa.jp")];
-    char stringpool_str4022[sizeof("genoa.it")];
-    char stringpool_str4023[sizeof("portlligat.museum")];
-    char stringpool_str4024[sizeof("priv.me")];
-    char stringpool_str4025[sizeof("nakadomari.aomori.jp")];
-    char stringpool_str4026[sizeof("miyoshi.saitama.jp")];
-    char stringpool_str4027[sizeof("traniandriabarletta.it")];
-    char stringpool_str4028[sizeof("ostrowiec.pl")];
-    char stringpool_str4029[sizeof("vaapste.no")];
-    char stringpool_str4030[sizeof("coop.py")];
-    char stringpool_str4031[sizeof("hammerfest.no")];
-    char stringpool_str4032[sizeof("bruxelles.museum")];
-    char stringpool_str4033[sizeof("sakhalin.ru")];
-    char stringpool_str4034[sizeof("lib.gu.us")];
-    char stringpool_str4035[sizeof("sakurai.nara.jp")];
-    char stringpool_str4036[sizeof("xn--gmqw5a.hk")];
-    char stringpool_str4037[sizeof("zamami.okinawa.jp")];
-    char stringpool_str4038[sizeof("geisei.kochi.jp")];
-    char stringpool_str4039[sizeof("coop.km")];
-    char stringpool_str4040[sizeof("raholt.no")];
-    char stringpool_str4041[sizeof("bardu.no")];
-    char stringpool_str4042[sizeof("siedlce.pl")];
-    char stringpool_str4043[sizeof("yamagata.nagano.jp")];
-    char stringpool_str4044[sizeof("laspezia.it")];
-    char stringpool_str4045[sizeof("kitamoto.saitama.jp")];
-    char stringpool_str4046[sizeof("moka.tochigi.jp")];
-    char stringpool_str4047[sizeof("ginoza.okinawa.jp")];
-    char stringpool_str4048[sizeof("brunel.museum")];
-    char stringpool_str4049[sizeof("matsumoto.nagano.jp")];
-    char stringpool_str4050[sizeof("higashiagatsuma.gunma.jp")];
-    char stringpool_str4051[sizeof("xn--ryrvik-bya.no")];
-    char stringpool_str4052[sizeof("toyotsu.fukuoka.jp")];
-    char stringpool_str4053[sizeof("pvt.ge")];
-    char stringpool_str4054[sizeof("kirovograd.ua")];
-    char stringpool_str4055[sizeof("oxford.museum")];
-    char stringpool_str4056[sizeof("musashino.tokyo.jp")];
-    char stringpool_str4057[sizeof("barum.no")];
-    char stringpool_str4058[sizeof("koenig.ru")];
-    char stringpool_str4059[sizeof("servebbs.com")];
-    char stringpool_str4060[sizeof("kitakyushu.jp")];
-    char stringpool_str4061[sizeof("health.museum")];
-    char stringpool_str4062[sizeof("herad.no")];
-    char stringpool_str4063[sizeof("gaivuotna.no")];
-    char stringpool_str4064[sizeof("zagan.pl")];
-    char stringpool_str4065[sizeof("frei.no")];
-    char stringpool_str4066[sizeof("kanuma.tochigi.jp")];
-    char stringpool_str4067[sizeof("is-uberleet.com")];
-    char stringpool_str4068[sizeof("shimane.jp")];
-    char stringpool_str4069[sizeof("shacknet.nu")];
-    char stringpool_str4070[sizeof("sor-aurdal.no")];
-    char stringpool_str4071[sizeof("kudamatsu.yamaguchi.jp")];
-    char stringpool_str4072[sizeof("is-with-theband.com")];
-    char stringpool_str4073[sizeof("yamada.iwate.jp")];
-    char stringpool_str4074[sizeof("mobi.tz")];
-    char stringpool_str4075[sizeof("asnes.no")];
-    char stringpool_str4076[sizeof("brussels.museum")];
-    char stringpool_str4077[sizeof("kibichuo.okayama.jp")];
-    char stringpool_str4078[sizeof("xn--hmmrfeasta-s4ac.no")];
-    char stringpool_str4079[sizeof("lindesnes.no")];
-    char stringpool_str4080[sizeof("ono.hyogo.jp")];
-    char stringpool_str4081[sizeof("iiyama.nagano.jp")];
-    char stringpool_str4082[sizeof("galsa.no")];
-    char stringpool_str4083[sizeof("okazaki.aichi.jp")];
-    char stringpool_str4084[sizeof("kaluga.ru")];
-    char stringpool_str4085[sizeof("genkai.saga.jp")];
-    char stringpool_str4086[sizeof("saku.nagano.jp")];
-    char stringpool_str4087[sizeof("cuneo.it")];
-    char stringpool_str4088[sizeof("otsuki.kochi.jp")];
-    char stringpool_str4089[sizeof("adult.ht")];
-    char stringpool_str4090[sizeof("iizuna.nagano.jp")];
-    char stringpool_str4091[sizeof("daisen.akita.jp")];
-    char stringpool_str4092[sizeof("matsubushi.saitama.jp")];
-    char stringpool_str4093[sizeof("obu.aichi.jp")];
-    char stringpool_str4094[sizeof("leikanger.no")];
-    char stringpool_str4095[sizeof("kadena.okinawa.jp")];
-    char stringpool_str4096[sizeof("balat.no")];
-    char stringpool_str4097[sizeof("himeji.hyogo.jp")];
-    char stringpool_str4098[sizeof("indian.museum")];
-    char stringpool_str4099[sizeof("naklo.pl")];
-    char stringpool_str4100[sizeof("xn--lgbbat1ad8j")];
-    char stringpool_str4101[sizeof("ichikawamisato.yamanashi.jp")];
-    char stringpool_str4102[sizeof("southwest.museum")];
-    char stringpool_str4103[sizeof("salvadordali.museum")];
-    char stringpool_str4104[sizeof("gunma.jp")];
-    char stringpool_str4105[sizeof("palmsprings.museum")];
-    char stringpool_str4106[sizeof("ama.aichi.jp")];
-    char stringpool_str4107[sizeof("sc.us")];
-    char stringpool_str4108[sizeof("natori.miyagi.jp")];
-    char stringpool_str4109[sizeof("biratori.hokkaido.jp")];
-    char stringpool_str4110[sizeof("immobilien")];
-    char stringpool_str4111[sizeof("chosei.chiba.jp")];
-    char stringpool_str4112[sizeof("santacruz.museum")];
-    char stringpool_str4113[sizeof("incheon.kr")];
-    char stringpool_str4114[sizeof("svalbard.no")];
-    char stringpool_str4115[sizeof("aogaki.hyogo.jp")];
-    char stringpool_str4116[sizeof("glogow.pl")];
-    char stringpool_str4117[sizeof("fuso.aichi.jp")];
-    char stringpool_str4118[sizeof("xn--sr-varanger-ggb.no")];
-    char stringpool_str4119[sizeof("naha.okinawa.jp")];
-    char stringpool_str4120[sizeof("osaka.jp")];
-    char stringpool_str4121[sizeof("web.co")];
-    char stringpool_str4122[sizeof("dep.no")];
-    char stringpool_str4123[sizeof("sg")];
-    char stringpool_str4124[sizeof("hirara.okinawa.jp")];
-    char stringpool_str4125[sizeof("bozen.it")];
-    char stringpool_str4126[sizeof("kiyama.saga.jp")];
-    char stringpool_str4127[sizeof("larsson.museum")];
-    char stringpool_str4128[sizeof("dallas.museum")];
-    char stringpool_str4129[sizeof("zarow.pl")];
-    char stringpool_str4130[sizeof("loten.no")];
-    char stringpool_str4131[sizeof("urasoe.okinawa.jp")];
-    char stringpool_str4132[sizeof("planetarium.museum")];
-    char stringpool_str4133[sizeof("towada.aomori.jp")];
-    char stringpool_str4134[sizeof("hamar.no")];
-    char stringpool_str4135[sizeof("coop.br")];
-    char stringpool_str4136[sizeof("soni.nara.jp")];
-    char stringpool_str4137[sizeof("rifu.miyagi.jp")];
-    char stringpool_str4138[sizeof("yoichi.hokkaido.jp")];
-    char stringpool_str4139[sizeof("orsta.no")];
-    char stringpool_str4140[sizeof("kherson.ua")];
-    char stringpool_str4141[sizeof("chambagri.fr")];
-    char stringpool_str4142[sizeof("newspaper.museum")];
-    char stringpool_str4143[sizeof("consultant.aero")];
-    char stringpool_str4144[sizeof("busan.kr")];
-    char stringpool_str4145[sizeof("pv.it")];
-    char stringpool_str4146[sizeof("bytom.pl")];
-    char stringpool_str4147[sizeof("iki.fi")];
-    char stringpool_str4148[sizeof("xn--fl-zia.no")];
-    char stringpool_str4149[sizeof("hidaka.kochi.jp")];
-    char stringpool_str4150[sizeof("tanabe.kyoto.jp")];
-    char stringpool_str4151[sizeof("mc.it")];
-    char stringpool_str4152[sizeof("social")];
-    char stringpool_str4153[sizeof("fuefuki.yamanashi.jp")];
-    char stringpool_str4154[sizeof("newport.museum")];
-    char stringpool_str4155[sizeof("fuossko.no")];
-    char stringpool_str4156[sizeof("mombetsu.hokkaido.jp")];
-    char stringpool_str4157[sizeof("lib.ga.us")];
-    char stringpool_str4158[sizeof("toho.fukuoka.jp")];
-    char stringpool_str4159[sizeof("vik.no")];
-    char stringpool_str4160[sizeof("haram.no")];
-    char stringpool_str4161[sizeof("maebashi.gunma.jp")];
-    char stringpool_str4162[sizeof("aoste.it")];
-    char stringpool_str4163[sizeof("ako.hyogo.jp")];
-    char stringpool_str4164[sizeof("tozsde.hu")];
-    char stringpool_str4165[sizeof("higashimatsushima.miyagi.jp")];
-    char stringpool_str4166[sizeof("cultural.museum")];
-    char stringpool_str4167[sizeof("tobishima.aichi.jp")];
-    char stringpool_str4168[sizeof("bungoono.oita.jp")];
-    char stringpool_str4169[sizeof("namdalseid.no")];
-    char stringpool_str4170[sizeof("toyama.jp")];
-    char stringpool_str4171[sizeof("tosashimizu.kochi.jp")];
-    char stringpool_str4172[sizeof("discovery.museum")];
-    char stringpool_str4173[sizeof("halsa.no")];
-    char stringpool_str4174[sizeof("chihayaakasaka.osaka.jp")];
-    char stringpool_str4175[sizeof("odate.akita.jp")];
-    char stringpool_str4176[sizeof("ac.pa")];
-    char stringpool_str4177[sizeof("hurum.no")];
-    char stringpool_str4178[sizeof("hammarfeasta.no")];
-    char stringpool_str4179[sizeof("sc.tz")];
-    char stringpool_str4180[sizeof("shakotan.hokkaido.jp")];
-    char stringpool_str4181[sizeof("yufu.oita.jp")];
-    char stringpool_str4182[sizeof("kumamoto.kumamoto.jp")];
-    char stringpool_str4183[sizeof("yamazoe.nara.jp")];
-    char stringpool_str4184[sizeof("journalist.aero")];
-    char stringpool_str4185[sizeof("forsand.no")];
-    char stringpool_str4186[sizeof("leirfjord.no")];
-    char stringpool_str4187[sizeof("minakami.gunma.jp")];
-    char stringpool_str4188[sizeof("naroy.no")];
-    char stringpool_str4189[sizeof("ac.pr")];
-    char stringpool_str4190[sizeof("handson.museum")];
-    char stringpool_str4191[sizeof("sorreisa.no")];
-    char stringpool_str4192[sizeof("aosta.it")];
-    char stringpool_str4193[sizeof("dazaifu.fukuoka.jp")];
-    char stringpool_str4194[sizeof("bristol.museum")];
-    char stringpool_str4195[sizeof("naamesjevuemie.no")];
-    char stringpool_str4196[sizeof("giske.no")];
-    char stringpool_str4197[sizeof("wodzislaw.pl")];
-    char stringpool_str4198[sizeof("minamifurano.hokkaido.jp")];
-    char stringpool_str4199[sizeof("jerusalem.museum")];
-    char stringpool_str4200[sizeof("berkeley.museum")];
-    char stringpool_str4201[sizeof("obanazawa.yamagata.jp")];
-    char stringpool_str4202[sizeof("gulen.no")];
-    char stringpool_str4203[sizeof("aarborte.no")];
-    char stringpool_str4204[sizeof("fetsund.no")];
-    char stringpool_str4205[sizeof("sc.kr")];
-    char stringpool_str4206[sizeof("kakuda.miyagi.jp")];
-    char stringpool_str4207[sizeof("nagawa.nagano.jp")];
-    char stringpool_str4208[sizeof("xn--mot-tla.no")];
-    char stringpool_str4209[sizeof("xn--hobl-ira.no")];
-    char stringpool_str4210[sizeof("a.prod.fastly.net")];
-    char stringpool_str4211[sizeof("hobol.no")];
-    char stringpool_str4212[sizeof("tome.miyagi.jp")];
-    char stringpool_str4213[sizeof("mitsuke.niigata.jp")];
-    char stringpool_str4214[sizeof("kita.osaka.jp")];
-    char stringpool_str4215[sizeof("hotel.lk")];
-    char stringpool_str4216[sizeof("lecce.it")];
-    char stringpool_str4217[sizeof("sorfold.no")];
-    char stringpool_str4218[sizeof("insurance.aero")];
-    char stringpool_str4219[sizeof("kainan.tokushima.jp")];
-    char stringpool_str4220[sizeof("yamagata.yamagata.jp")];
-    char stringpool_str4221[sizeof("online.museum")];
-    char stringpool_str4222[sizeof("is-a-cubicle-slave.com")];
-    char stringpool_str4223[sizeof("lecco.it")];
-    char stringpool_str4224[sizeof("akashi.hyogo.jp")];
-    char stringpool_str4225[sizeof("serveftp.net")];
-    char stringpool_str4226[sizeof("takatsuki.shiga.jp")];
-    char stringpool_str4227[sizeof("cartoonart.museum")];
-    char stringpool_str4228[sizeof("togane.chiba.jp")];
-    char stringpool_str4229[sizeof("xn--fiqz9s")];
-    char stringpool_str4230[sizeof("of.by")];
-    char stringpool_str4231[sizeof("iwanai.hokkaido.jp")];
-    char stringpool_str4232[sizeof("sandnessjoen.no")];
-    char stringpool_str4233[sizeof("from-la.net")];
-    char stringpool_str4234[sizeof("ogawara.miyagi.jp")];
-    char stringpool_str4235[sizeof("farsund.no")];
-    char stringpool_str4236[sizeof("omachi.nagano.jp")];
-    char stringpool_str4237[sizeof("tyumen.ru")];
-    char stringpool_str4238[sizeof("hachioji.tokyo.jp")];
-    char stringpool_str4239[sizeof("morotsuka.miyazaki.jp")];
-    char stringpool_str4240[sizeof("uonuma.niigata.jp")];
-    char stringpool_str4241[sizeof("itoigawa.niigata.jp")];
-    char stringpool_str4242[sizeof("sc.cn")];
-    char stringpool_str4243[sizeof("american.museum")];
-    char stringpool_str4244[sizeof("creation.museum")];
-    char stringpool_str4245[sizeof("myphotos.cc")];
-    char stringpool_str4246[sizeof("from-ny.net")];
-    char stringpool_str4247[sizeof("minamioguni.kumamoto.jp")];
-    char stringpool_str4248[sizeof("xn--sr-fron-q1a.no")];
-    char stringpool_str4249[sizeof("southcarolina.museum")];
-    char stringpool_str4250[sizeof("luroy.no")];
-    char stringpool_str4251[sizeof("coop.tt")];
-    char stringpool_str4252[sizeof("iide.yamagata.jp")];
-    char stringpool_str4253[sizeof("skedsmo.no")];
-    char stringpool_str4254[sizeof("sch.uk")];
-    char stringpool_str4255[sizeof("iwate.jp")];
-    char stringpool_str4256[sizeof("miyoshi.hiroshima.jp")];
-    char stringpool_str4257[sizeof("ryokami.saitama.jp")];
-    char stringpool_str4258[sizeof("ardal.no")];
-    char stringpool_str4259[sizeof("ashikaga.tochigi.jp")];
-    char stringpool_str4260[sizeof("fe.it")];
-    char stringpool_str4261[sizeof("gangwon.kr")];
-    char stringpool_str4262[sizeof("starnberg.museum")];
-    char stringpool_str4263[sizeof("shoes")];
-    char stringpool_str4264[sizeof("ustka.pl")];
-    char stringpool_str4265[sizeof("miyoshi.tokushima.jp")];
-    char stringpool_str4266[sizeof("sci.eg")];
-    char stringpool_str4267[sizeof("teaches-yoga.com")];
-    char stringpool_str4268[sizeof("xn--flor-jra.no")];
-    char stringpool_str4269[sizeof("nebraska.museum")];
-    char stringpool_str4270[sizeof("firm.ht")];
-    char stringpool_str4271[sizeof("matsushima.miyagi.jp")];
-    char stringpool_str4272[sizeof("nose.osaka.jp")];
-    char stringpool_str4273[sizeof("philadelphia.museum")];
-    char stringpool_str4274[sizeof("simbirsk.ru")];
-    char stringpool_str4275[sizeof("helsinki.museum")];
-    char stringpool_str4276[sizeof("gs.aa.no")];
-    char stringpool_str4277[sizeof("from-ky.com")];
-    char stringpool_str4278[sizeof("from-tx.com")];
-    char stringpool_str4279[sizeof("hagebostad.no")];
-    char stringpool_str4280[sizeof("from-wy.com")];
-    char stringpool_str4281[sizeof("from-pa.com")];
-    char stringpool_str4282[sizeof("hitra.no")];
-    char stringpool_str4283[sizeof("ambulance.aero")];
-    char stringpool_str4284[sizeof("from-wa.com")];
-    char stringpool_str4285[sizeof("yawara.ibaraki.jp")];
-    char stringpool_str4286[sizeof("gs.st.no")];
-    char stringpool_str4287[sizeof("nahari.kochi.jp")];
-    char stringpool_str4288[sizeof("gs.mr.no")];
-    char stringpool_str4289[sizeof("from-ca.com")];
-    char stringpool_str4290[sizeof("xn--fiqs8s")];
-    char stringpool_str4291[sizeof("fineart.museum")];
-    char stringpool_str4292[sizeof("so.it")];
-    char stringpool_str4293[sizeof("annefrank.museum")];
-    char stringpool_str4294[sizeof("computerhistory.museum")];
-    char stringpool_str4295[sizeof("ss.it")];
-    char stringpool_str4296[sizeof("jan-mayen.no")];
-    char stringpool_str4297[sizeof("tamayu.shimane.jp")];
-    char stringpool_str4298[sizeof("koryo.nara.jp")];
-    char stringpool_str4299[sizeof("sp.it")];
-    char stringpool_str4300[sizeof("kamisu.ibaraki.jp")];
-    char stringpool_str4301[sizeof("assisi.museum")];
-    char stringpool_str4302[sizeof("sch.ae")];
-    char stringpool_str4303[sizeof("misconfused.org")];
-    char stringpool_str4304[sizeof("mil.gh")];
-    char stringpool_str4305[sizeof("tamaki.mie.jp")];
-    char stringpool_str4306[sizeof("from-co.net")];
-    char stringpool_str4307[sizeof("sunndal.no")];
-    char stringpool_str4308[sizeof("xn--io0a7i.hk")];
-    char stringpool_str4309[sizeof("from-nm.com")];
-    char stringpool_str4310[sizeof("trentino-aadige.it")];
-    char stringpool_str4311[sizeof("sch.ir")];
-    char stringpool_str4312[sizeof("dyndns.biz")];
-    char stringpool_str4313[sizeof("asmatart.museum")];
-    char stringpool_str4314[sizeof("hembygdsforbund.museum")];
-    char stringpool_str4315[sizeof("gs.tr.no")];
-    char stringpool_str4316[sizeof("hotel.tz")];
-    char stringpool_str4317[sizeof("omachi.saga.jp")];
-    char stringpool_str4318[sizeof("sogndal.no")];
-    char stringpool_str4319[sizeof("choshi.chiba.jp")];
-    char stringpool_str4320[sizeof("hiraya.nagano.jp")];
-    char stringpool_str4321[sizeof("farmers.museum")];
-    char stringpool_str4322[sizeof("romskog.no")];
-    char stringpool_str4323[sizeof("gs.va.no")];
-    char stringpool_str4324[sizeof("kharkov.ua")];
-    char stringpool_str4325[sizeof("isahaya.nagasaki.jp")];
-    char stringpool_str4326[sizeof("stjordal.no")];
-    char stringpool_str4327[sizeof("nanto.toyama.jp")];
-    char stringpool_str4328[sizeof("fr.it")];
-    char stringpool_str4329[sizeof("sosa.chiba.jp")];
-    char stringpool_str4330[sizeof("matsuura.nagasaki.jp")];
-    char stringpool_str4331[sizeof("asker.no")];
-    char stringpool_str4332[sizeof("hikone.shiga.jp")];
-    char stringpool_str4333[sizeof("sa.it")];
-    char stringpool_str4334[sizeof("ariake.saga.jp")];
-    char stringpool_str4335[sizeof("wake.okayama.jp")];
-    char stringpool_str4336[sizeof("se.net")];
-    char stringpool_str4337[sizeof("lucca.it")];
-    char stringpool_str4338[sizeof("air-traffic-control.aero")];
-    char stringpool_str4339[sizeof("klabu.no")];
-    char stringpool_str4340[sizeof("lesja.no")];
-    char stringpool_str4341[sizeof("rishirifuji.hokkaido.jp")];
-    char stringpool_str4342[sizeof("singles")];
-    char stringpool_str4343[sizeof("artcenter.museum")];
-    char stringpool_str4344[sizeof("hikimi.shimane.jp")];
-    char stringpool_str4345[sizeof("ookuwa.nagano.jp")];
-    char stringpool_str4346[sizeof("moriyama.shiga.jp")];
-    char stringpool_str4347[sizeof("gs.tm.no")];
-    char stringpool_str4348[sizeof("pc.it")];
-    char stringpool_str4349[sizeof("chiryu.aichi.jp")];
-    char stringpool_str4350[sizeof("sr.it")];
-    char stringpool_str4351[sizeof("tomari.hokkaido.jp")];
-    char stringpool_str4352[sizeof("snillfjord.no")];
-    char stringpool_str4353[sizeof("folkebibl.no")];
-    char stringpool_str4354[sizeof("konan.aichi.jp")];
-    char stringpool_str4355[sizeof("servebbs.org")];
-    char stringpool_str4356[sizeof("chuo.osaka.jp")];
-    char stringpool_str4357[sizeof("from-pr.com")];
-    char stringpool_str4358[sizeof("oshima.tokyo.jp")];
-    char stringpool_str4359[sizeof("chernovtsy.ua")];
-    char stringpool_str4360[sizeof("xn--kvfjord-nxa.no")];
-    char stringpool_str4361[sizeof("rec.ro")];
-    char stringpool_str4362[sizeof("sch.id")];
-    char stringpool_str4363[sizeof("fm.it")];
-    char stringpool_str4364[sizeof("pro.om")];
-    char stringpool_str4365[sizeof("city.kobe.jp")];
-    char stringpool_str4366[sizeof("takahata.yamagata.jp")];
-    char stringpool_str4367[sizeof("savannahga.museum")];
-    char stringpool_str4368[sizeof("naumburg.museum")];
-    char stringpool_str4369[sizeof("mandal.no")];
-    char stringpool_str4370[sizeof("matsumoto.kagoshima.jp")];
-    char stringpool_str4371[sizeof("lowicz.pl")];
-    char stringpool_str4372[sizeof("mino.gifu.jp")];
-    char stringpool_str4373[sizeof("xn--80asehdb")];
-    char stringpool_str4374[sizeof("hakuba.nagano.jp")];
-    char stringpool_str4375[sizeof("sch.lk")];
-    char stringpool_str4376[sizeof("takasu.hokkaido.jp")];
-    char stringpool_str4377[sizeof("kazan.ru")];
-    char stringpool_str4378[sizeof("upow.gov.pl")];
-    char stringpool_str4379[sizeof("culturalcenter.museum")];
-    char stringpool_str4380[sizeof("columbia.museum")];
-    char stringpool_str4381[sizeof("mx.na")];
-    char stringpool_str4382[sizeof("xn--fiq64b")];
-    char stringpool_str4383[sizeof("tattoo")];
-    char stringpool_str4384[sizeof("bykle.no")];
-    char stringpool_str4385[sizeof("yachiyo.chiba.jp")];
-    char stringpool_str4386[sizeof("taishin.fukushima.jp")];
-    char stringpool_str4387[sizeof("fi.it")];
-    char stringpool_str4388[sizeof("xn--vgsy-qoa0j.no")];
-    char stringpool_str4389[sizeof("shriram")];
-    char stringpool_str4390[sizeof("taketa.oita.jp")];
-    char stringpool_str4391[sizeof("st.no")];
-    char stringpool_str4392[sizeof("living.museum")];
-    char stringpool_str4393[sizeof("zakopane.pl")];
-    char stringpool_str4394[sizeof("from-nj.com")];
-    char stringpool_str4395[sizeof("kuju.oita.jp")];
-    char stringpool_str4396[sizeof("games.hu")];
-    char stringpool_str4397[sizeof("svelvik.no")];
-    char stringpool_str4398[sizeof("se.com")];
-    char stringpool_str4399[sizeof("santabarbara.museum")];
-    char stringpool_str4400[sizeof("drobak.no")];
-    char stringpool_str4401[sizeof("ruovat.no")];
-    char stringpool_str4402[sizeof("sch.sa")];
-    char stringpool_str4403[sizeof("gs.fm.no")];
-    char stringpool_str4404[sizeof("asuke.aichi.jp")];
-    char stringpool_str4405[sizeof("nakagyo.kyoto.jp")];
-    char stringpool_str4406[sizeof("marker.no")];
-    char stringpool_str4407[sizeof("otake.hiroshima.jp")];
-    char stringpool_str4408[sizeof("kraanghke.no")];
-    char stringpool_str4409[sizeof("yatomi.aichi.jp")];
-    char stringpool_str4410[sizeof("andoy.no")];
-    char stringpool_str4411[sizeof("surnadal.no")];
-    char stringpool_str4412[sizeof("meldal.no")];
-    char stringpool_str4413[sizeof("si.it")];
-    char stringpool_str4414[sizeof("fm.no")];
-    char stringpool_str4415[sizeof("cci.fr")];
-    char stringpool_str4416[sizeof("karumai.iwate.jp")];
-    char stringpool_str4417[sizeof("xn--jrpeland-54a.no")];
-    char stringpool_str4418[sizeof("yasuda.kochi.jp")];
-    char stringpool_str4419[sizeof("yachiyo.ibaraki.jp")];
-    char stringpool_str4420[sizeof("altoadige.it")];
-    char stringpool_str4421[sizeof("stordal.no")];
-    char stringpool_str4422[sizeof("sx.cn")];
-    char stringpool_str4423[sizeof("kuban.ru")];
-    char stringpool_str4424[sizeof("kurate.fukuoka.jp")];
-    char stringpool_str4425[sizeof("handa.aichi.jp")];
-    char stringpool_str4426[sizeof("lukow.pl")];
-    char stringpool_str4427[sizeof("mantova.it")];
-    char stringpool_str4428[sizeof("maibara.shiga.jp")];
-    char stringpool_str4429[sizeof("nanae.hokkaido.jp")];
-    char stringpool_str4430[sizeof("gs.ol.no")];
-    char stringpool_str4431[sizeof("stalowa-wola.pl")];
-    char stringpool_str4432[sizeof("takashima.shiga.jp")];
-    char stringpool_str4433[sizeof("eastcoast.museum")];
-    char stringpool_str4434[sizeof("sa.com")];
-    char stringpool_str4435[sizeof("kamikoani.akita.jp")];
-    char stringpool_str4436[sizeof("sayo.hyogo.jp")];
-    char stringpool_str4437[sizeof("kursk.ru")];
-    char stringpool_str4438[sizeof("oystre-slidre.no")];
-    char stringpool_str4439[sizeof("izumiotsu.osaka.jp")];
-    char stringpool_str4440[sizeof("dyndns.ws")];
-    char stringpool_str4441[sizeof("sells-for-less.com")];
-    char stringpool_str4442[sizeof("aukra.no")];
-    char stringpool_str4443[sizeof("kasukabe.saitama.jp")];
-    char stringpool_str4444[sizeof("neues.museum")];
-    char stringpool_str4445[sizeof("cadaques.museum")];
-    char stringpool_str4446[sizeof("toyama.toyama.jp")];
-    char stringpool_str4447[sizeof("kurume.fukuoka.jp")];
-    char stringpool_str4448[sizeof("nore-og-uvdal.no")];
-    char stringpool_str4449[sizeof("from-nh.com")];
-    char stringpool_str4450[sizeof("jamal.ru")];
-    char stringpool_str4451[sizeof("xn--vestvgy-ixa6o.no")];
-    char stringpool_str4452[sizeof("xn--mgberp4a5d4ar")];
-    char stringpool_str4453[sizeof("tsuwano.shimane.jp")];
-    char stringpool_str4454[sizeof("watari.miyagi.jp")];
-    char stringpool_str4455[sizeof("fukusaki.hyogo.jp")];
-    char stringpool_str4456[sizeof("oryol.ru")];
-    char stringpool_str4457[sizeof("karpacz.pl")];
-    char stringpool_str4458[sizeof("mugi.tokushima.jp")];
-    char stringpool_str4459[sizeof("from-ri.com")];
-    char stringpool_str4460[sizeof("from-wi.com")];
-    char stringpool_str4461[sizeof("guernsey.museum")];
-    char stringpool_str4462[sizeof("shirako.chiba.jp")];
-    char stringpool_str4463[sizeof("gloppen.no")];
-    char stringpool_str4464[sizeof("minamiminowa.nagano.jp")];
-    char stringpool_str4465[sizeof("kosuge.yamanashi.jp")];
-    char stringpool_str4466[sizeof("tsubame.niigata.jp")];
-    char stringpool_str4467[sizeof("gs.ah.no")];
-    char stringpool_str4468[sizeof("hokuryu.hokkaido.jp")];
-    char stringpool_str4469[sizeof("space-to-rent.com")];
-    char stringpool_str4470[sizeof("fylkesbibl.no")];
-    char stringpool_str4471[sizeof("botanical.museum")];
-    char stringpool_str4472[sizeof("baseball.museum")];
-    char stringpool_str4473[sizeof("kanan.osaka.jp")];
-    char stringpool_str4474[sizeof("askoy.no")];
-    char stringpool_str4475[sizeof("ehime.jp")];
-    char stringpool_str4476[sizeof("seljord.no")];
-    char stringpool_str4477[sizeof("shiksha")];
-    char stringpool_str4478[sizeof("akaiwa.okayama.jp")];
-    char stringpool_str4479[sizeof("from-tn.com")];
-    char stringpool_str4480[sizeof("funahashi.toyama.jp")];
-    char stringpool_str4481[sizeof("porsgrunn.no")];
-    char stringpool_str4482[sizeof("from-al.com")];
-    char stringpool_str4483[sizeof("sokndal.no")];
-    char stringpool_str4484[sizeof("kunst.museum")];
-    char stringpool_str4485[sizeof("bible.museum")];
-    char stringpool_str4486[sizeof("bjugn.no")];
-    char stringpool_str4487[sizeof("tokigawa.saitama.jp")];
-    char stringpool_str4488[sizeof("tonami.toyama.jp")];
-    char stringpool_str4489[sizeof("kawai.nara.jp")];
-    char stringpool_str4490[sizeof("koeln.museum")];
-    char stringpool_str4491[sizeof("kanoya.kagoshima.jp")];
-    char stringpool_str4492[sizeof("nanbu.tottori.jp")];
-    char stringpool_str4493[sizeof("furubira.hokkaido.jp")];
-    char stringpool_str4494[sizeof("inami.toyama.jp")];
-    char stringpool_str4495[sizeof("nasushiobara.tochigi.jp")];
-    char stringpool_str4496[sizeof("is-a-geek.net")];
-    char stringpool_str4497[sizeof("keisen.fukuoka.jp")];
-    char stringpool_str4498[sizeof("sibenik.museum")];
-    char stringpool_str4499[sizeof("gs.bu.no")];
-    char stringpool_str4500[sizeof("entomology.museum")];
-    char stringpool_str4501[sizeof("priv.hu")];
-    char stringpool_str4502[sizeof("hattfjelldal.no")];
-    char stringpool_str4503[sizeof("philadelphiaarea.museum")];
-    char stringpool_str4504[sizeof("arteducation.museum")];
-    char stringpool_str4505[sizeof("spiegel")];
-    char stringpool_str4506[sizeof("house.museum")];
-    char stringpool_str4507[sizeof("ikeda.osaka.jp")];
-    char stringpool_str4508[sizeof("arkhangelsk.ru")];
-    char stringpool_str4509[sizeof("xn--mgba3a4f16a")];
-    char stringpool_str4510[sizeof("ikata.ehime.jp")];
-    char stringpool_str4511[sizeof("izumi.osaka.jp")];
-    char stringpool_str4512[sizeof("from-ne.com")];
-    char stringpool_str4513[sizeof("venice.it")];
-    char stringpool_str4514[sizeof("minamiaiki.nagano.jp")];
-    char stringpool_str4515[sizeof("trentinoa-adige.it")];
-    char stringpool_str4516[sizeof("honjo.akita.jp")];
-    char stringpool_str4517[sizeof("labor.museum")];
-    char stringpool_str4518[sizeof("xn--mgba3a4fra")];
-    char stringpool_str4519[sizeof("taxi.br")];
-    char stringpool_str4520[sizeof("akita.jp")];
-    char stringpool_str4521[sizeof("from-ia.com")];
-    char stringpool_str4522[sizeof("from-wv.com")];
-    char stringpool_str4523[sizeof("karmoy.no")];
-    char stringpool_str4524[sizeof("from-il.com")];
-    char stringpool_str4525[sizeof("ichikawa.chiba.jp")];
-    char stringpool_str4526[sizeof("gs.rl.no")];
-    char stringpool_str4527[sizeof("meland.no")];
-    char stringpool_str4528[sizeof("sherbrooke.museum")];
-    char stringpool_str4529[sizeof("from-nv.com")];
-    char stringpool_str4530[sizeof("trentino-a-adige.it")];
-    char stringpool_str4531[sizeof("csiro.au")];
-    char stringpool_str4532[sizeof("hasami.nagasaki.jp")];
-    char stringpool_str4533[sizeof("children.museum")];
-    char stringpool_str4534[sizeof("scientist.aero")];
-    char stringpool_str4535[sizeof("from-ar.com")];
-    char stringpool_str4536[sizeof("mil.mv")];
-    char stringpool_str4537[sizeof("nogata.fukuoka.jp")];
-    char stringpool_str4538[sizeof("saitama.jp")];
-    char stringpool_str4539[sizeof("malvik.no")];
-    char stringpool_str4540[sizeof("honai.ehime.jp")];
-    char stringpool_str4541[sizeof("vegarshei.no")];
-    char stringpool_str4542[sizeof("glass.museum")];
-    char stringpool_str4543[sizeof("from-ga.com")];
-    char stringpool_str4544[sizeof("kochi.jp")];
-    char stringpool_str4545[sizeof("oketo.hokkaido.jp")];
-    char stringpool_str4546[sizeof("from-de.com")];
-    char stringpool_str4547[sizeof("from-ct.com")];
-    char stringpool_str4548[sizeof("kawara.fukuoka.jp")];
-    char stringpool_str4549[sizeof("nagi.okayama.jp")];
-    char stringpool_str4550[sizeof("mosvik.no")];
-    char stringpool_str4551[sizeof("toki.gifu.jp")];
-    char stringpool_str4552[sizeof("vardo.no")];
-    char stringpool_str4553[sizeof("fortmissoula.museum")];
-    char stringpool_str4554[sizeof("xn--tjme-hra.no")];
-    char stringpool_str4555[sizeof("xn--frya-hra.no")];
-    char stringpool_str4556[sizeof("xn--xhq521b")];
-    char stringpool_str4557[sizeof("boutique")];
-    char stringpool_str4558[sizeof("russia.museum")];
-    char stringpool_str4559[sizeof("ikeda.hokkaido.jp")];
-    char stringpool_str4560[sizeof("historichouses.museum")];
-    char stringpool_str4561[sizeof("sch.ng")];
-    char stringpool_str4562[sizeof("automotive.museum")];
-    char stringpool_str4563[sizeof("xn--io0a7i.cn")];
-    char stringpool_str4564[sizeof("noboribetsu.hokkaido.jp")];
-    char stringpool_str4565[sizeof("sch.qa")];
-    char stringpool_str4566[sizeof("medecin.fr")];
-    char stringpool_str4567[sizeof("komae.tokyo.jp")];
-    char stringpool_str4568[sizeof("altai.ru")];
-    char stringpool_str4569[sizeof("shimabara.nagasaki.jp")];
-    char stringpool_str4570[sizeof("naval.museum")];
-    char stringpool_str4571[sizeof("tomisato.chiba.jp")];
-    char stringpool_str4572[sizeof("ichihara.chiba.jp")];
-    char stringpool_str4573[sizeof("is-a-geek.org")];
-    char stringpool_str4574[sizeof("freemasonry.museum")];
-    char stringpool_str4575[sizeof("gs.hm.no")];
-    char stringpool_str4576[sizeof("from-ut.com")];
-    char stringpool_str4577[sizeof("foundation")];
-    char stringpool_str4578[sizeof("sasayama.hyogo.jp")];
-    char stringpool_str4579[sizeof("from-ak.com")];
-    char stringpool_str4580[sizeof("xn--nvuotna-hwa.no")];
-    char stringpool_str4581[sizeof("shirosato.ibaraki.jp")];
-    char stringpool_str4582[sizeof("xn--hnefoss-q1a.no")];
-    char stringpool_str4583[sizeof("xn--snase-nra.no")];
-    char stringpool_str4584[sizeof("nord-odal.no")];
-    char stringpool_str4585[sizeof("kahoku.yamagata.jp")];
-    char stringpool_str4586[sizeof("ulsan.kr")];
-    char stringpool_str4587[sizeof("natuurwetenschappen.museum")];
-    char stringpool_str4588[sizeof("dyndns.org")];
-    char stringpool_str4589[sizeof("iitate.fukushima.jp")];
-    char stringpool_str4590[sizeof("hidaka.wakayama.jp")];
-    char stringpool_str4591[sizeof("north.museum")];
-    char stringpool_str4592[sizeof("miyoshi.aichi.jp")];
-    char stringpool_str4593[sizeof("ambulance.museum")];
-    char stringpool_str4594[sizeof("is-a-caterer.com")];
-    char stringpool_str4595[sizeof("dell-ogliastra.it")];
-    char stringpool_str4596[sizeof("ohkura.yamagata.jp")];
-    char stringpool_str4597[sizeof("obuse.nagano.jp")];
-    char stringpool_str4598[sizeof("usgarden.museum")];
-    char stringpool_str4599[sizeof("suzu.ishikawa.jp")];
-    char stringpool_str4600[sizeof("santafe.museum")];
-    char stringpool_str4601[sizeof("ohi.fukui.jp")];
-    char stringpool_str4602[sizeof("vadso.no")];
-    char stringpool_str4603[sizeof("presse.ci")];
-    char stringpool_str4604[sizeof("bibai.hokkaido.jp")];
-    char stringpool_str4605[sizeof("botanicgarden.museum")];
-    char stringpool_str4606[sizeof("otaru.hokkaido.jp")];
-    char stringpool_str4607[sizeof("ainan.ehime.jp")];
-    char stringpool_str4608[sizeof("sano.tochigi.jp")];
-    char stringpool_str4609[sizeof("flights")];
-    char stringpool_str4610[sizeof("kaita.hiroshima.jp")];
-    char stringpool_str4611[sizeof("taishi.osaka.jp")];
-    char stringpool_str4612[sizeof("yahaba.iwate.jp")];
-    char stringpool_str4613[sizeof("asso.mc")];
-    char stringpool_str4614[sizeof("hiroo.hokkaido.jp")];
-    char stringpool_str4615[sizeof("oharu.aichi.jp")];
-    char stringpool_str4616[sizeof("tonosho.kagawa.jp")];
-    char stringpool_str4617[sizeof("lakas.hu")];
-    char stringpool_str4618[sizeof("xn--tysvr-vra.no")];
-    char stringpool_str4619[sizeof("mil.lv")];
-    char stringpool_str4620[sizeof("itoman.okinawa.jp")];
-    char stringpool_str4621[sizeof("valle.no")];
-    char stringpool_str4622[sizeof("can.museum")];
-    char stringpool_str4623[sizeof("shimane.shimane.jp")];
-    char stringpool_str4624[sizeof("textile.museum")];
-    char stringpool_str4625[sizeof("luxury")];
-    char stringpool_str4626[sizeof("nishiokoppe.hokkaido.jp")];
-    char stringpool_str4627[sizeof("heroy.nordland.no")];
-    char stringpool_str4628[sizeof("volda.no")];
-    char stringpool_str4629[sizeof("kiryu.gunma.jp")];
-    char stringpool_str4630[sizeof("oskol.ru")];
-    char stringpool_str4631[sizeof("drangedal.no")];
-    char stringpool_str4632[sizeof("hotel.hu")];
-    char stringpool_str4633[sizeof("okaya.nagano.jp")];
-    char stringpool_str4634[sizeof("aisai.aichi.jp")];
-    char stringpool_str4635[sizeof("amber.museum")];
-    char stringpool_str4636[sizeof("epilepsy.museum")];
-    char stringpool_str4637[sizeof("trentino-altoadige.it")];
-    char stringpool_str4638[sizeof("nakanoto.ishikawa.jp")];
-    char stringpool_str4639[sizeof("ayabe.kyoto.jp")];
-    char stringpool_str4640[sizeof("marnardal.no")];
-    char stringpool_str4641[sizeof("sera.hiroshima.jp")];
-    char stringpool_str4642[sizeof("ikeda.nagano.jp")];
-    char stringpool_str4643[sizeof("minamimaki.nagano.jp")];
-    char stringpool_str4644[sizeof("ullensaker.no")];
-    char stringpool_str4645[sizeof("usuki.oita.jp")];
-    char stringpool_str4646[sizeof("kanra.gunma.jp")];
-    char stringpool_str4647[sizeof("murayama.yamagata.jp")];
-    char stringpool_str4648[sizeof("pittsburgh.museum")];
-    char stringpool_str4649[sizeof("florist")];
-    char stringpool_str4650[sizeof("fukushima.jp")];
-    char stringpool_str4651[sizeof("beeldengeluid.museum")];
-    char stringpool_str4652[sizeof("mil.sy")];
-    char stringpool_str4653[sizeof("mil.py")];
-    char stringpool_str4654[sizeof("mielec.pl")];
-    char stringpool_str4655[sizeof("sanfrancisco.museum")];
-    char stringpool_str4656[sizeof("baths.museum")];
-    char stringpool_str4657[sizeof("scot")];
-    char stringpool_str4658[sizeof("iizuka.fukuoka.jp")];
-    char stringpool_str4659[sizeof("belau.pw")];
-    char stringpool_str4660[sizeof("gs.hl.no")];
-    char stringpool_str4661[sizeof("burghof.museum")];
-    char stringpool_str4662[sizeof("yuza.yamagata.jp")];
-    char stringpool_str4663[sizeof("matera.it")];
-    char stringpool_str4664[sizeof("mochizuki.nagano.jp")];
-    char stringpool_str4665[sizeof("skedsmokorset.no")];
-    char stringpool_str4666[sizeof("bandai.fukushima.jp")];
-    char stringpool_str4667[sizeof("newjersey.museum")];
-    char stringpool_str4668[sizeof("rimini.it")];
-    char stringpool_str4669[sizeof("valdaosta.it")];
-    char stringpool_str4670[sizeof("nes.buskerud.no")];
-    char stringpool_str4671[sizeof("oseto.nagasaki.jp")];
-    char stringpool_str4672[sizeof("xn--rsta-fra.no")];
-    char stringpool_str4673[sizeof("vefsn.no")];
-    char stringpool_str4674[sizeof("trapani.it")];
-    char stringpool_str4675[sizeof("chiba.jp")];
-    char stringpool_str4676[sizeof("yuzawa.niigata.jp")];
-    char stringpool_str4677[sizeof("yamatotakada.nara.jp")];
-    char stringpool_str4678[sizeof("siracusa.it")];
-    char stringpool_str4679[sizeof("yasugi.shimane.jp")];
-    char stringpool_str4680[sizeof("akita.akita.jp")];
-    char stringpool_str4681[sizeof("odesa.ua")];
-    char stringpool_str4682[sizeof("oyabe.toyama.jp")];
-    char stringpool_str4683[sizeof("otaki.nagano.jp")];
-    char stringpool_str4684[sizeof("oceanographic.museum")];
-    char stringpool_str4685[sizeof("nrw.museum")];
-    char stringpool_str4686[sizeof("tromsa.no")];
-    char stringpool_str4687[sizeof("xn--mgba3a4f16a.ir")];
-    char stringpool_str4688[sizeof("med.ly")];
-    char stringpool_str4689[sizeof("yamatokoriyama.nara.jp")];
-    char stringpool_str4690[sizeof("hitoyoshi.kumamoto.jp")];
-    char stringpool_str4691[sizeof("shikabe.hokkaido.jp")];
-    char stringpool_str4692[sizeof("laakesvuemie.no")];
-    char stringpool_str4693[sizeof("pg.it")];
-    char stringpool_str4694[sizeof("sshn.se")];
-    char stringpool_str4695[sizeof("xn--mgba3a4fra.ir")];
-    char stringpool_str4696[sizeof("melhus.no")];
-    char stringpool_str4697[sizeof("yasaka.nagano.jp")];
-    char stringpool_str4698[sizeof("shibata.miyagi.jp")];
-    char stringpool_str4699[sizeof("tochigi.tochigi.jp")];
-    char stringpool_str4700[sizeof("opole.pl")];
-    char stringpool_str4701[sizeof("erimo.hokkaido.jp")];
-    char stringpool_str4702[sizeof("daejeon.kr")];
-    char stringpool_str4703[sizeof("trondheim.no")];
-    char stringpool_str4704[sizeof("spjelkavik.no")];
-    char stringpool_str4705[sizeof("sicilia.it")];
-    char stringpool_str4706[sizeof("from-in.com")];
-    char stringpool_str4707[sizeof("kepno.pl")];
-    char stringpool_str4708[sizeof("cyber.museum")];
-    char stringpool_str4709[sizeof("marche.it")];
-    char stringpool_str4710[sizeof("project.museum")];
-    char stringpool_str4711[sizeof("xn--kvnangen-k0a.no")];
-    char stringpool_str4712[sizeof("ozu.ehime.jp")];
-    char stringpool_str4713[sizeof("xn--fjord-lra.no")];
-    char stringpool_str4714[sizeof("ovre-eiker.no")];
-    char stringpool_str4715[sizeof("inatsuki.fukuoka.jp")];
-    char stringpool_str4716[sizeof("tadotsu.kagawa.jp")];
-    char stringpool_str4717[sizeof("tf")];
-    char stringpool_str4718[sizeof("of.no")];
-    char stringpool_str4719[sizeof("asahi.toyama.jp")];
-    char stringpool_str4720[sizeof("shimoji.okinawa.jp")];
-    char stringpool_str4721[sizeof("suginami.tokyo.jp")];
-    char stringpool_str4722[sizeof("mil.uy")];
-    char stringpool_str4723[sizeof("mutsuzawa.chiba.jp")];
-    char stringpool_str4724[sizeof("konin.pl")];
-    char stringpool_str4725[sizeof("art.museum")];
-    char stringpool_str4726[sizeof("from-ks.com")];
-    char stringpool_str4727[sizeof("institute")];
-    char stringpool_str4728[sizeof("aichi.jp")];
-    char stringpool_str4729[sizeof("miki.hyogo.jp")];
-    char stringpool_str4730[sizeof("jewish.museum")];
-    char stringpool_str4731[sizeof("from-fl.com")];
-    char stringpool_str4732[sizeof("flog.br")];
-    char stringpool_str4733[sizeof("xn--slt-elab.no")];
-    char stringpool_str4734[sizeof("minamidaito.okinawa.jp")];
-    char stringpool_str4735[sizeof("sv.it")];
-    char stringpool_str4736[sizeof("otari.nagano.jp")];
-    char stringpool_str4737[sizeof("trentinoalto-adige.it")];
-    char stringpool_str4738[sizeof("likes-pie.com")];
-    char stringpool_str4739[sizeof("windmill.museum")];
-    char stringpool_str4740[sizeof("basel.museum")];
-    char stringpool_str4741[sizeof("chita.ru")];
-    char stringpool_str4742[sizeof("vagan.no")];
-    char stringpool_str4743[sizeof("kariya.aichi.jp")];
-    char stringpool_str4744[sizeof("rzeszow.pl")];
-    char stringpool_str4745[sizeof("mil.my")];
-    char stringpool_str4746[sizeof("mordovia.ru")];
-    char stringpool_str4747[sizeof("chita.aichi.jp")];
-    char stringpool_str4748[sizeof("avoues.fr")];
-    char stringpool_str4749[sizeof("iruma.saitama.jp")];
-    char stringpool_str4750[sizeof("photography")];
-    char stringpool_str4751[sizeof("xn--frna-woa.no")];
-    char stringpool_str4752[sizeof("omaha.museum")];
-    char stringpool_str4753[sizeof("modena.it")];
-    char stringpool_str4754[sizeof("stargard.pl")];
-    char stringpool_str4755[sizeof("semboku.akita.jp")];
-    char stringpool_str4756[sizeof("shichinohe.aomori.jp")];
-    char stringpool_str4757[sizeof("kinko.kagoshima.jp")];
-    char stringpool_str4758[sizeof("shimokitayama.nara.jp")];
-    char stringpool_str4759[sizeof("medical.museum")];
-    char stringpool_str4760[sizeof("k12.ok.us")];
-    char stringpool_str4761[sizeof("k12.or.us")];
-    char stringpool_str4762[sizeof("hachinohe.aomori.jp")];
-    char stringpool_str4763[sizeof("kutno.pl")];
-    char stringpool_str4764[sizeof("k12.dc.us")];
-    char stringpool_str4765[sizeof("trentino-alto-adige.it")];
-    char stringpool_str4766[sizeof("k12.pr.us")];
-    char stringpool_str4767[sizeof("homeftp.org")];
-    char stringpool_str4768[sizeof("izumi.kagoshima.jp")];
-    char stringpool_str4769[sizeof("k12.sc.us")];
-    char stringpool_str4770[sizeof("phoenix.museum")];
-    char stringpool_str4771[sizeof("kirov.ru")];
-    char stringpool_str4772[sizeof("kaisei.kanagawa.jp")];
-    char stringpool_str4773[sizeof("bus.museum")];
-    char stringpool_str4774[sizeof("sobetsu.hokkaido.jp")];
-    char stringpool_str4775[sizeof("iheya.okinawa.jp")];
-    char stringpool_str4776[sizeof("air.museum")];
-    char stringpool_str4777[sizeof("nakama.fukuoka.jp")];
-    char stringpool_str4778[sizeof("cymru.museum")];
-    char stringpool_str4779[sizeof("interactive.museum")];
-    char stringpool_str4780[sizeof("kiwa.mie.jp")];
-    char stringpool_str4781[sizeof("satosho.okayama.jp")];
-    char stringpool_str4782[sizeof("vlaanderen")];
-    char stringpool_str4783[sizeof("mil.by")];
-    char stringpool_str4784[sizeof("shimoda.shizuoka.jp")];
-    char stringpool_str4785[sizeof("airguard.museum")];
-    char stringpool_str4786[sizeof("harima.hyogo.jp")];
-    char stringpool_str4787[sizeof("national.museum")];
-    char stringpool_str4788[sizeof("k12.al.us")];
-    char stringpool_str4789[sizeof("k12.ak.us")];
-    char stringpool_str4790[sizeof("k12.ar.us")];
-    char stringpool_str4791[sizeof("varoy.no")];
-    char stringpool_str4792[sizeof("kasuya.fukuoka.jp")];
-    char stringpool_str4793[sizeof("nanjo.okinawa.jp")];
-    char stringpool_str4794[sizeof("setagaya.tokyo.jp")];
-    char stringpool_str4795[sizeof("dvrdns.org")];
-    char stringpool_str4796[sizeof("yokawa.hyogo.jp")];
-    char stringpool_str4797[sizeof("chonan.chiba.jp")];
-    char stringpool_str4798[sizeof("presse.ml")];
-    char stringpool_str4799[sizeof("vestre-slidre.no")];
-    char stringpool_str4800[sizeof("gorge.museum")];
-    char stringpool_str4801[sizeof("k12.tx.us")];
-    char stringpool_str4802[sizeof("wakuya.miyagi.jp")];
-    char stringpool_str4803[sizeof("building.museum")];
-    char stringpool_str4804[sizeof("oceanographique.museum")];
-    char stringpool_str4805[sizeof("rubtsovsk.ru")];
-    char stringpool_str4806[sizeof("k12.as.us")];
-    char stringpool_str4807[sizeof("systems")];
-    char stringpool_str4808[sizeof("maintenance.aero")];
-    char stringpool_str4809[sizeof("fukumitsu.toyama.jp")];
-    char stringpool_str4810[sizeof("loyalist.museum")];
-    char stringpool_str4811[sizeof("tysnes.no")];
-    char stringpool_str4812[sizeof("inami.wakayama.jp")];
-    char stringpool_str4813[sizeof("is-a-nascarfan.com")];
-    char stringpool_str4814[sizeof("trentinoaltoadige.it")];
-    char stringpool_str4815[sizeof("taxi.aero")];
-    char stringpool_str4816[sizeof("avocat.fr")];
-    char stringpool_str4817[sizeof("szex.hu")];
-    char stringpool_str4818[sizeof("is-a-therapist.com")];
-    char stringpool_str4819[sizeof("obama.nagasaki.jp")];
-    char stringpool_str4820[sizeof("hichiso.gifu.jp")];
-    char stringpool_str4821[sizeof("k12.tn.us")];
-    char stringpool_str4822[sizeof("shimada.shizuoka.jp")];
-    char stringpool_str4823[sizeof("kyonan.chiba.jp")];
-    char stringpool_str4824[sizeof("shitara.aichi.jp")];
-    char stringpool_str4825[sizeof("k12.ut.us")];
-    char stringpool_str4826[sizeof("shibecha.hokkaido.jp")];
-    char stringpool_str4827[sizeof("kawagoe.mie.jp")];
-    char stringpool_str4828[sizeof("k12.de.us")];
-    char stringpool_str4829[sizeof("hakone.kanagawa.jp")];
-    char stringpool_str4830[sizeof("togitsu.nagasaki.jp")];
-    char stringpool_str4831[sizeof("tohnosho.chiba.jp")];
-    char stringpool_str4832[sizeof("luxembourg.museum")];
-    char stringpool_str4833[sizeof("lazio.it")];
-    char stringpool_str4834[sizeof("hongo.hiroshima.jp")];
-    char stringpool_str4835[sizeof("xn--mgb9awbf")];
-    char stringpool_str4836[sizeof("hirata.fukushima.jp")];
-    char stringpool_str4837[sizeof("lubin.pl")];
-    char stringpool_str4838[sizeof("badajoz.museum")];
-    char stringpool_str4839[sizeof("asaka.saitama.jp")];
-    char stringpool_str4840[sizeof("and.museum")];
-    char stringpool_str4841[sizeof("undersea.museum")];
-    char stringpool_str4842[sizeof("ibigawa.gifu.jp")];
-    char stringpool_str4843[sizeof("xn--mgbc0a9azcg")];
-    char stringpool_str4844[sizeof("amami.kagoshima.jp")];
-    char stringpool_str4845[sizeof("k12.mt.us")];
-    char stringpool_str4846[sizeof("friuliv-giulia.it")];
-    char stringpool_str4847[sizeof("shiroishi.saga.jp")];
-    char stringpool_str4848[sizeof("nanbu.yamanashi.jp")];
-    char stringpool_str4849[sizeof("bryne.no")];
-    char stringpool_str4850[sizeof("farmequipment.museum")];
-    char stringpool_str4851[sizeof("grane.no")];
-    char stringpool_str4852[sizeof("friuli-vgiulia.it")];
-    char stringpool_str4853[sizeof("skanland.no")];
-    char stringpool_str4854[sizeof("society.museum")];
-    char stringpool_str4855[sizeof("tomobe.ibaraki.jp")];
-    char stringpool_str4856[sizeof("iwade.wakayama.jp")];
-    char stringpool_str4857[sizeof("hanyu.saitama.jp")];
-    char stringpool_str4858[sizeof("hakata.fukuoka.jp")];
-    char stringpool_str4859[sizeof("k12.mn.us")];
-    char stringpool_str4860[sizeof("xn--blt-elab.no")];
-    char stringpool_str4861[sizeof("miyazu.kyoto.jp")];
-    char stringpool_str4862[sizeof("rybnik.pl")];
-    char stringpool_str4863[sizeof("otago.museum")];
-    char stringpool_str4864[sizeof("is-slick.com")];
-    char stringpool_str4865[sizeof("k12.ms.us")];
-    char stringpool_str4866[sizeof("stor-elvdal.no")];
-    char stringpool_str4867[sizeof("smolensk.ru")];
-    char stringpool_str4868[sizeof("k12.il.us")];
-    char stringpool_str4869[sizeof("brandywinevalley.museum")];
-    char stringpool_str4870[sizeof("oki.fukuoka.jp")];
-    char stringpool_str4871[sizeof("fukuyama.hiroshima.jp")];
-    char stringpool_str4872[sizeof("bizen.okayama.jp")];
-    char stringpool_str4873[sizeof("matsue.shimane.jp")];
-    char stringpool_str4874[sizeof("seranishi.hiroshima.jp")];
-    char stringpool_str4875[sizeof("hoylandet.no")];
-    char stringpool_str4876[sizeof("otaki.saitama.jp")];
-    char stringpool_str4877[sizeof("k12.nc.us")];
-    char stringpool_str4878[sizeof("k12.in.us")];
-    char stringpool_str4879[sizeof("ichikai.tochigi.jp")];
-    char stringpool_str4880[sizeof("xn--bod-2na.no")];
-    char stringpool_str4881[sizeof("presse.km")];
-    char stringpool_str4882[sizeof("yakage.okayama.jp")];
-    char stringpool_str4883[sizeof("jamison.museum")];
-    char stringpool_str4884[sizeof("xn--ksnes-uua.no")];
-    char stringpool_str4885[sizeof("wales.museum")];
-    char stringpool_str4886[sizeof("atami.shizuoka.jp")];
-    char stringpool_str4887[sizeof("kochi.kochi.jp")];
-    char stringpool_str4888[sizeof("ibara.okayama.jp")];
-    char stringpool_str4889[sizeof("k12.md.us")];
-    char stringpool_str4890[sizeof("kosai.shizuoka.jp")];
-    char stringpool_str4891[sizeof("film.hu")];
-    char stringpool_str4892[sizeof("miasta.pl")];
-    char stringpool_str4893[sizeof("yokoshibahikari.chiba.jp")];
-    char stringpool_str4894[sizeof("tm.pl")];
-    char stringpool_str4895[sizeof("toyone.aichi.jp")];
-    char stringpool_str4896[sizeof("kariwa.niigata.jp")];
-    char stringpool_str4897[sizeof("lutsk.ua")];
-    char stringpool_str4898[sizeof("kasuga.hyogo.jp")];
-    char stringpool_str4899[sizeof("omura.nagasaki.jp")];
-    char stringpool_str4900[sizeof("asahi.nagano.jp")];
-    char stringpool_str4901[sizeof("nishi.osaka.jp")];
-    char stringpool_str4902[sizeof("k12.me.us")];
-    char stringpool_str4903[sizeof("hemne.no")];
-    char stringpool_str4904[sizeof("fc.it")];
-    char stringpool_str4905[sizeof("k12.id.us")];
-    char stringpool_str4906[sizeof("dovre.no")];
-    char stringpool_str4907[sizeof("mitsue.nara.jp")];
-    char stringpool_str4908[sizeof("saka.hiroshima.jp")];
-    char stringpool_str4909[sizeof("columbus.museum")];
-    char stringpool_str4910[sizeof("bedzin.pl")];
-    char stringpool_str4911[sizeof("pisz.pl")];
-    char stringpool_str4912[sizeof("obira.hokkaido.jp")];
-    char stringpool_str4913[sizeof("from.hr")];
-    char stringpool_str4914[sizeof("k12.nd.us")];
-    char stringpool_str4915[sizeof("k12.ks.us")];
-    char stringpool_str4916[sizeof("plantation.museum")];
-    char stringpool_str4917[sizeof("izumizaki.fukushima.jp")];
-    char stringpool_str4918[sizeof("friulivgiulia.it")];
-    char stringpool_str4919[sizeof("vgs.no")];
-    char stringpool_str4920[sizeof("elvendrell.museum")];
-    char stringpool_str4921[sizeof("saitama.saitama.jp")];
-    char stringpool_str4922[sizeof("compute.amazonaws.com")];
-    char stringpool_str4923[sizeof("hofu.yamaguchi.jp")];
-    char stringpool_str4924[sizeof("compute-1.amazonaws.com")];
-    char stringpool_str4925[sizeof("uchinada.ishikawa.jp")];
-    char stringpool_str4926[sizeof("civilwar.museum")];
-    char stringpool_str4927[sizeof("k12.ne.us")];
-    char stringpool_str4928[sizeof("harvestcelebration.museum")];
-    char stringpool_str4929[sizeof("exchange.aero")];
-    char stringpool_str4930[sizeof("marylhurst.museum")];
-    char stringpool_str4931[sizeof("k12.nj.us")];
-    char stringpool_str4932[sizeof("rec.co")];
-    char stringpool_str4933[sizeof("stjordalshalsen.no")];
-    char stringpool_str4934[sizeof("nesna.no")];
-    char stringpool_str4935[sizeof("roros.no")];
-    char stringpool_str4936[sizeof("mishima.shizuoka.jp")];
-    char stringpool_str4937[sizeof("xn--bjarky-fya.no")];
-    char stringpool_str4938[sizeof("consulting.aero")];
-    char stringpool_str4939[sizeof("k12.pa.us")];
-    char stringpool_str4940[sizeof("obama.fukui.jp")];
-    char stringpool_str4941[sizeof("tysfjord.no")];
-    char stringpool_str4942[sizeof("usa.museum")];
-    char stringpool_str4943[sizeof("toyota.aichi.jp")];
-    char stringpool_str4944[sizeof("minamitane.kagoshima.jp")];
-    char stringpool_str4945[sizeof("b.ssl.fastly.net")];
-    char stringpool_str4946[sizeof("frogans")];
-    char stringpool_str4947[sizeof("higashikagawa.kagawa.jp")];
-    char stringpool_str4948[sizeof("wakasa.fukui.jp")];
-    char stringpool_str4949[sizeof("aland.fi")];
-    char stringpool_str4950[sizeof("research.aero")];
-    char stringpool_str4951[sizeof("kawagoe.saitama.jp")];
-    char stringpool_str4952[sizeof("hanawa.fukushima.jp")];
-    char stringpool_str4953[sizeof("coop.mw")];
-    char stringpool_str4954[sizeof("romsa.no")];
-    char stringpool_str4955[sizeof("aviation.museum")];
-    char stringpool_str4956[sizeof("puglia.it")];
-    char stringpool_str4957[sizeof("mobara.chiba.jp")];
-    char stringpool_str4958[sizeof("yamal.ru")];
-    char stringpool_str4959[sizeof("xn--o3cw4h")];
-    char stringpool_str4960[sizeof("iwata.shizuoka.jp")];
-    char stringpool_str4961[sizeof("otama.fukushima.jp")];
-    char stringpool_str4962[sizeof("ikeda.fukui.jp")];
-    char stringpool_str4963[sizeof("omuta.fukuoka.jp")];
-    char stringpool_str4964[sizeof("evje-og-hornnes.no")];
-    char stringpool_str4965[sizeof("steiermark.museum")];
-    char stringpool_str4966[sizeof("uruma.okinawa.jp")];
-    char stringpool_str4967[sizeof("nakanojo.gunma.jp")];
-    char stringpool_str4968[sizeof("bando.ibaraki.jp")];
-    char stringpool_str4969[sizeof("war.museum")];
-    char stringpool_str4970[sizeof("oguchi.aichi.jp")];
-    char stringpool_str4971[sizeof("abira.hokkaido.jp")];
-    char stringpool_str4972[sizeof("finland.museum")];
-    char stringpool_str4973[sizeof("soo.kagoshima.jp")];
-    char stringpool_str4974[sizeof("honjo.saitama.jp")];
-    char stringpool_str4975[sizeof("tarumizu.kagoshima.jp")];
-    char stringpool_str4976[sizeof("is-by.us")];
-    char stringpool_str4977[sizeof("miyama.mie.jp")];
-    char stringpool_str4978[sizeof("yamada.fukuoka.jp")];
-    char stringpool_str4979[sizeof("xn--fiq228c5hs")];
-    char stringpool_str4980[sizeof("tokuyama.yamaguchi.jp")];
-    char stringpool_str4981[sizeof("is-a-chef.net")];
-    char stringpool_str4982[sizeof("koshu.yamanashi.jp")];
-    char stringpool_str4983[sizeof("takarazuka.hyogo.jp")];
-    char stringpool_str4984[sizeof("is-a-patsfan.org")];
-    char stringpool_str4985[sizeof("miyake.nara.jp")];
-    char stringpool_str4986[sizeof("xn--skierv-uta.no")];
-    char stringpool_str4987[sizeof("schlesisches.museum")];
-    char stringpool_str4988[sizeof("mashiko.tochigi.jp")];
-    char stringpool_str4989[sizeof("qld.gov.au")];
-    char stringpool_str4990[sizeof("radom.pl")];
-    char stringpool_str4991[sizeof("arida.wakayama.jp")];
-    char stringpool_str4992[sizeof("nyc.museum")];
-    char stringpool_str4993[sizeof("rauma.no")];
-    char stringpool_str4994[sizeof("omiya.saitama.jp")];
-    char stringpool_str4995[sizeof("yamaga.kumamoto.jp")];
-    char stringpool_str4996[sizeof("humanities.museum")];
-    char stringpool_str4997[sizeof("xn--loabt-0qa.no")];
-    char stringpool_str4998[sizeof("nuoro.it")];
-    char stringpool_str4999[sizeof("k12.az.us")];
-    char stringpool_str5000[sizeof("kolobrzeg.pl")];
-    char stringpool_str5001[sizeof("lib.nv.us")];
-    char stringpool_str5002[sizeof("xn--koluokta-7ya57h.no")];
-    char stringpool_str5003[sizeof("shimamoto.osaka.jp")];
-    char stringpool_str5004[sizeof("kvanangen.no")];
-    char stringpool_str5005[sizeof("xn--jlster-bya.no")];
-    char stringpool_str5006[sizeof("misasa.tottori.jp")];
-    char stringpool_str5007[sizeof("kunitomi.miyazaki.jp")];
-    char stringpool_str5008[sizeof("k12.ma.us")];
-    char stringpool_str5009[sizeof("a.ssl.fastly.net")];
-    char stringpool_str5010[sizeof("groks-this.info")];
-    char stringpool_str5011[sizeof("k12.ri.us")];
-    char stringpool_str5012[sizeof("podzone.net")];
-    char stringpool_str5013[sizeof("masuda.shimane.jp")];
-    char stringpool_str5014[sizeof("buzen.fukuoka.jp")];
-    char stringpool_str5015[sizeof("reklam.hu")];
-    char stringpool_str5016[sizeof("k12.ia.us")];
-    char stringpool_str5017[sizeof("kanie.aichi.jp")];
-    char stringpool_str5018[sizeof("eu-west-1.compute.amazonaws.com")];
-    char stringpool_str5019[sizeof("artgallery.museum")];
-    char stringpool_str5020[sizeof("sexy")];
-    char stringpool_str5021[sizeof("kawaguchi.saitama.jp")];
-    char stringpool_str5022[sizeof("losangeles.museum")];
-    char stringpool_str5023[sizeof("minami.kyoto.jp")];
-    char stringpool_str5024[sizeof("coop.ht")];
-    char stringpool_str5025[sizeof("kakinoki.shimane.jp")];
-    char stringpool_str5026[sizeof("donostia.museum")];
-    char stringpool_str5027[sizeof("fjaler.no")];
-    char stringpool_str5028[sizeof("assedic.fr")];
-    char stringpool_str5029[sizeof("baltimore.museum")];
-    char stringpool_str5030[sizeof("monza-brianza.it")];
-    char stringpool_str5031[sizeof("imari.saga.jp")];
-    char stringpool_str5032[sizeof("heroy.more-og-romsdal.no")];
-    char stringpool_str5033[sizeof("sex.pl")];
-    char stringpool_str5034[sizeof("paragliding.aero")];
-    char stringpool_str5035[sizeof("gmina.pl")];
-    char stringpool_str5036[sizeof("is-a-geek.com")];
-    char stringpool_str5037[sizeof("niimi.okayama.jp")];
-    char stringpool_str5038[sizeof("itako.ibaraki.jp")];
-    char stringpool_str5039[sizeof("bronnoy.no")];
-    char stringpool_str5040[sizeof("xn--nttery-byae.no")];
-    char stringpool_str5041[sizeof("k12.mi.us")];
-    char stringpool_str5042[sizeof("okuma.fukushima.jp")];
-    char stringpool_str5043[sizeof("sc.ug")];
-    char stringpool_str5044[sizeof("is-a-chef.org")];
-    char stringpool_str5045[sizeof("uhren.museum")];
-    char stringpool_str5046[sizeof("oarai.ibaraki.jp")];
-    char stringpool_str5047[sizeof("xn--gmq050i.hk")];
-    char stringpool_str5048[sizeof("xn--laheadju-7ya.no")];
-    char stringpool_str5049[sizeof("hakodate.hokkaido.jp")];
-    char stringpool_str5050[sizeof("chocolate.museum")];
-    char stringpool_str5051[sizeof("is-an-engineer.com")];
-    char stringpool_str5052[sizeof("yaese.okinawa.jp")];
-    char stringpool_str5053[sizeof("photography.museum")];
-    char stringpool_str5054[sizeof("askim.no")];
-    char stringpool_str5055[sizeof("hyuga.miyazaki.jp")];
-    char stringpool_str5056[sizeof("poltava.ua")];
-    char stringpool_str5057[sizeof("k12.la.us")];
-    char stringpool_str5058[sizeof("mitane.akita.jp")];
-    char stringpool_str5059[sizeof("ulm.museum")];
-    char stringpool_str5060[sizeof("video.hu")];
-    char stringpool_str5061[sizeof("aikawa.kanagawa.jp")];
-    char stringpool_str5062[sizeof("shijonawate.osaka.jp")];
-    char stringpool_str5063[sizeof("umaji.kochi.jp")];
-    char stringpool_str5064[sizeof("averoy.no")];
-    char stringpool_str5065[sizeof("froland.no")];
-    char stringpool_str5066[sizeof("takatori.nara.jp")];
-    char stringpool_str5067[sizeof("coop.mv")];
-    char stringpool_str5068[sizeof("kyoto.jp")];
-    char stringpool_str5069[sizeof("serveftp.org")];
-    char stringpool_str5070[sizeof("musashimurayama.tokyo.jp")];
-    char stringpool_str5071[sizeof("monzaebrianza.it")];
-    char stringpool_str5072[sizeof("agency")];
-    char stringpool_str5073[sizeof("ono.fukui.jp")];
-    char stringpool_str5074[sizeof("hizen.saga.jp")];
-    char stringpool_str5075[sizeof("funabashi.chiba.jp")];
-    char stringpool_str5076[sizeof("meeres.museum")];
-    char stringpool_str5077[sizeof("science.museum")];
-    char stringpool_str5078[sizeof("vdonsk.ru")];
-    char stringpool_str5079[sizeof("xn--finny-yua.no")];
-    char stringpool_str5080[sizeof("sakaiminato.tottori.jp")];
-    char stringpool_str5081[sizeof("toyotomi.hokkaido.jp")];
-    char stringpool_str5082[sizeof("artsandcrafts.museum")];
-    char stringpool_str5083[sizeof("youth.museum")];
-    char stringpool_str5084[sizeof("sciencehistory.museum")];
-    char stringpool_str5085[sizeof("umi.fukuoka.jp")];
-    char stringpool_str5086[sizeof("midori.chiba.jp")];
-    char stringpool_str5087[sizeof("from-ma.com")];
-    char stringpool_str5088[sizeof("gs.nt.no")];
-    char stringpool_str5089[sizeof("florida.museum")];
-    char stringpool_str5090[sizeof("nakamichi.yamanashi.jp")];
-    char stringpool_str5091[sizeof("tarama.okinawa.jp")];
-    char stringpool_str5092[sizeof("sologne.museum")];
-    char stringpool_str5093[sizeof("xn--xkc2dl3a5ee0h")];
-    char stringpool_str5094[sizeof("medizinhistorisches.museum")];
-    char stringpool_str5095[sizeof("kiho.mie.jp")];
-    char stringpool_str5096[sizeof("modern.museum")];
-    char stringpool_str5097[sizeof("viking.museum")];
-    char stringpool_str5098[sizeof("versailles.museum")];
-    char stringpool_str5099[sizeof("on-the-web.tv")];
-    char stringpool_str5100[sizeof("osaki.miyagi.jp")];
-    char stringpool_str5101[sizeof("arita.saga.jp")];
-    char stringpool_str5102[sizeof("togura.nagano.jp")];
-    char stringpool_str5103[sizeof("moscow.museum")];
-    char stringpool_str5104[sizeof("matsuyama.ehime.jp")];
-    char stringpool_str5105[sizeof("monzabrianza.it")];
-    char stringpool_str5106[sizeof("rissa.no")];
-    char stringpool_str5107[sizeof("chikushino.fukuoka.jp")];
-    char stringpool_str5108[sizeof("hirokawa.fukuoka.jp")];
-    char stringpool_str5109[sizeof("k12.vt.us")];
-    char stringpool_str5110[sizeof("vagsoy.no")];
-    char stringpool_str5111[sizeof("swinoujscie.pl")];
-    char stringpool_str5112[sizeof("plc.ly")];
-    char stringpool_str5113[sizeof("ikeda.gifu.jp")];
-    char stringpool_str5114[sizeof("durham.museum")];
-    char stringpool_str5115[sizeof("xn--hery-ira.xn--mre-og-romsdal-qqb.no")];
-    char stringpool_str5116[sizeof("olbia-tempio.it")];
-    char stringpool_str5117[sizeof("k12.wa.us")];
-    char stringpool_str5118[sizeof("ushiku.ibaraki.jp")];
-    char stringpool_str5119[sizeof("blogspot.fr")];
-    char stringpool_str5120[sizeof("kainan.wakayama.jp")];
-    char stringpool_str5121[sizeof("ichiba.tokushima.jp")];
-    char stringpool_str5122[sizeof("ogata.akita.jp")];
-    char stringpool_str5123[sizeof("rieti.it")];
-    char stringpool_str5124[sizeof("mosreg.ru")];
-    char stringpool_str5125[sizeof("nanyo.yamagata.jp")];
-    char stringpool_str5126[sizeof("misaki.osaka.jp")];
-    char stringpool_str5127[sizeof("risor.no")];
-    char stringpool_str5128[sizeof("minamiawaji.hyogo.jp")];
-    char stringpool_str5129[sizeof("sirdal.no")];
-    char stringpool_str5130[sizeof("mil.do")];
-    char stringpool_str5131[sizeof("from-mo.com")];
-    char stringpool_str5132[sizeof("shimonita.gunma.jp")];
-    char stringpool_str5133[sizeof("zgrad.ru")];
-    char stringpool_str5134[sizeof("lib.ny.us")];
-    char stringpool_str5135[sizeof("inagi.tokyo.jp")];
-    char stringpool_str5136[sizeof("mil.jo")];
-    char stringpool_str5137[sizeof("rodoy.no")];
-    char stringpool_str5138[sizeof("mitaka.tokyo.jp")];
-    char stringpool_str5139[sizeof("ginan.gifu.jp")];
-    char stringpool_str5140[sizeof("miners.museum")];
-    char stringpool_str5141[sizeof("yuasa.wakayama.jp")];
-    char stringpool_str5142[sizeof("kawai.iwate.jp")];
-    char stringpool_str5143[sizeof("kunitachi.tokyo.jp")];
-    char stringpool_str5144[sizeof("iwama.ibaraki.jp")];
-    char stringpool_str5145[sizeof("museet.museum")];
-    char stringpool_str5146[sizeof("xn--holtlen-hxa.no")];
-    char stringpool_str5147[sizeof("k12.wi.us")];
-    char stringpool_str5148[sizeof("tonaki.okinawa.jp")];
-    char stringpool_str5149[sizeof("from-hi.com")];
-    char stringpool_str5150[sizeof("starachowice.pl")];
-    char stringpool_str5151[sizeof("suldal.no")];
-    char stringpool_str5152[sizeof("nanao.ishikawa.jp")];
-    char stringpool_str5153[sizeof("vibovalentia.it")];
-    char stringpool_str5154[sizeof("raisa.no")];
-    char stringpool_str5155[sizeof("kamitonda.wakayama.jp")];
-    char stringpool_str5156[sizeof("blogspot.fi")];
-    char stringpool_str5157[sizeof("schoenbrunn.museum")];
-    char stringpool_str5158[sizeof("lib.ky.us")];
-    char stringpool_str5159[sizeof("daegu.kr")];
-    char stringpool_str5160[sizeof("radoy.no")];
-    char stringpool_str5161[sizeof("steigen.no")];
-    char stringpool_str5162[sizeof("portal.museum")];
-    char stringpool_str5163[sizeof("fg.it")];
-    char stringpool_str5164[sizeof("yuzhno-sakhalinsk.ru")];
-    char stringpool_str5165[sizeof("padova.it")];
-    char stringpool_str5166[sizeof("tsukiyono.gunma.jp")];
-    char stringpool_str5167[sizeof("tagami.niigata.jp")];
-    char stringpool_str5168[sizeof("muosat.no")];
-    char stringpool_str5169[sizeof("unzen.nagasaki.jp")];
-    char stringpool_str5170[sizeof("mil.to")];
-    char stringpool_str5171[sizeof("snaase.no")];
-    char stringpool_str5172[sizeof("dyroy.no")];
-    char stringpool_str5173[sizeof("shimokawa.hokkaido.jp")];
-    char stringpool_str5174[sizeof("otoyo.kochi.jp")];
-    char stringpool_str5175[sizeof("yamaguchi.jp")];
-    char stringpool_str5176[sizeof("act.gov.au")];
-    char stringpool_str5177[sizeof("misawa.aomori.jp")];
-    char stringpool_str5178[sizeof("xn--merker-kua.no")];
-    char stringpool_str5179[sizeof("itami.hyogo.jp")];
-    char stringpool_str5180[sizeof("turek.pl")];
-    char stringpool_str5181[sizeof("anthropology.museum")];
-    char stringpool_str5182[sizeof("gamagori.aichi.jp")];
-    char stringpool_str5183[sizeof("shobara.hiroshima.jp")];
-    char stringpool_str5184[sizeof("basilicata.it")];
-    char stringpool_str5185[sizeof("sigdal.no")];
-    char stringpool_str5186[sizeof("molise.it")];
-    char stringpool_str5187[sizeof("foundation.museum")];
-    char stringpool_str5188[sizeof("minamiuonuma.niigata.jp")];
-    char stringpool_str5189[sizeof("from-nd.com")];
-    char stringpool_str5190[sizeof("issmarterthanyou.com")];
-    char stringpool_str5191[sizeof("saotome.st")];
-    char stringpool_str5192[sizeof("gs.nl.no")];
-    char stringpool_str5193[sizeof("strand.no")];
-    char stringpool_str5194[sizeof("from-sd.com")];
-    char stringpool_str5195[sizeof("muncie.museum")];
-    char stringpool_str5196[sizeof("ashiya.hyogo.jp")];
-    char stringpool_str5197[sizeof("xn--h1aegh.museum")];
-    char stringpool_str5198[sizeof("sciencesnaturelles.museum")];
-    char stringpool_str5199[sizeof("xn--ystre-slidre-ujb.no")];
-    char stringpool_str5200[sizeof("owani.aomori.jp")];
-    char stringpool_str5201[sizeof("cloudfront.net")];
-    char stringpool_str5202[sizeof("mikasa.hokkaido.jp")];
-    char stringpool_str5203[sizeof("sex.hu")];
-    char stringpool_str5204[sizeof("kamifurano.hokkaido.jp")];
-    char stringpool_str5205[sizeof("solund.no")];
-    char stringpool_str5206[sizeof("krokstadelva.no")];
-    char stringpool_str5207[sizeof("fauske.no")];
-    char stringpool_str5208[sizeof("vf.no")];
-    char stringpool_str5209[sizeof("from-az.net")];
-    char stringpool_str5210[sizeof("iwate.iwate.jp")];
-    char stringpool_str5211[sizeof("shibata.niigata.jp")];
-    char stringpool_str5212[sizeof("2000.hu")];
-    char stringpool_str5213[sizeof("depot.museum")];
-    char stringpool_str5214[sizeof("kaneyama.fukushima.jp")];
-    char stringpool_str5215[sizeof("intelligence.museum")];
-    char stringpool_str5216[sizeof("hisayama.fukuoka.jp")];
-    char stringpool_str5217[sizeof("yabuki.fukushima.jp")];
-    char stringpool_str5218[sizeof("antiques.museum")];
-    char stringpool_str5219[sizeof("iwaki.fukushima.jp")];
-    char stringpool_str5220[sizeof("palana.ru")];
-    char stringpool_str5221[sizeof("workshop.museum")];
-    char stringpool_str5222[sizeof("us-west-1.compute.amazonaws.com")];
-    char stringpool_str5223[sizeof("us-west-2.compute.amazonaws.com")];
-    char stringpool_str5224[sizeof("xn--vre-eiker-k8a.no")];
-    char stringpool_str5225[sizeof("botany.museum")];
-    char stringpool_str5226[sizeof("dolls.museum")];
-    char stringpool_str5227[sizeof("mil.no")];
-    char stringpool_str5228[sizeof("aquarium.museum")];
-    char stringpool_str5229[sizeof("technology")];
-    char stringpool_str5230[sizeof("nyuzen.toyama.jp")];
-    char stringpool_str5231[sizeof("xn--oppegrd-ixa.no")];
-    char stringpool_str5232[sizeof("fuji.shizuoka.jp")];
-    char stringpool_str5233[sizeof("tomigusuku.okinawa.jp")];
-    char stringpool_str5234[sizeof("from-mi.com")];
-    char stringpool_str5235[sizeof("sunagawa.hokkaido.jp")];
-    char stringpool_str5236[sizeof("hiji.oita.jp")];
-    char stringpool_str5237[sizeof("essex.museum")];
-    char stringpool_str5238[sizeof("for-the.biz")];
-    char stringpool_str5239[sizeof("soundandvision.museum")];
-    char stringpool_str5240[sizeof("yalta.ua")];
-    char stringpool_str5241[sizeof("vestby.no")];
-    char stringpool_str5242[sizeof("mil.bo")];
-    char stringpool_str5243[sizeof("from-mn.com")];
-    char stringpool_str5244[sizeof("ikoma.nara.jp")];
-    char stringpool_str5245[sizeof("nango.fukushima.jp")];
-    char stringpool_str5246[sizeof("posts-and-telecommunications.museum")];
-    char stringpool_str5247[sizeof("fukushima.hokkaido.jp")];
-    char stringpool_str5248[sizeof("ouchi.saga.jp")];
-    char stringpool_str5249[sizeof("taketomi.okinawa.jp")];
-    char stringpool_str5250[sizeof("lib.wy.us")];
-    char stringpool_str5251[sizeof("madrid.museum")];
-    char stringpool_str5252[sizeof("tomakomai.hokkaido.jp")];
-    char stringpool_str5253[sizeof("wajiki.tokushima.jp")];
-    char stringpool_str5254[sizeof("ulvik.no")];
-    char stringpool_str5255[sizeof("naganohara.gunma.jp")];
-    char stringpool_str5256[sizeof("niyodogawa.kochi.jp")];
-    char stringpool_str5257[sizeof("is-very-evil.org")];
-    char stringpool_str5258[sizeof("k12.va.us")];
-    char stringpool_str5259[sizeof("minami.tokushima.jp")];
-    char stringpool_str5260[sizeof("shiojiri.nagano.jp")];
-    char stringpool_str5261[sizeof("xn--xkc2al3hye2a")];
-    char stringpool_str5262[sizeof("xn--mgberp4a5d4a87g")];
-    char stringpool_str5263[sizeof("nagai.yamagata.jp")];
-    char stringpool_str5264[sizeof("mincom.tn")];
-    char stringpool_str5265[sizeof("kasai.hyogo.jp")];
-    char stringpool_str5266[sizeof("asahi.ibaraki.jp")];
-    char stringpool_str5267[sizeof("huissier-justice.fr")];
-    char stringpool_str5268[sizeof("clinton.museum")];
-    char stringpool_str5269[sizeof("yurihonjo.akita.jp")];
-    char stringpool_str5270[sizeof("public.museum")];
-    char stringpool_str5271[sizeof("shishikui.tokushima.jp")];
-    char stringpool_str5272[sizeof("oto.fukuoka.jp")];
-    char stringpool_str5273[sizeof("k12.ct.us")];
-    char stringpool_str5274[sizeof("yusui.kagoshima.jp")];
-    char stringpool_str5275[sizeof("usculture.museum")];
-    char stringpool_str5276[sizeof("selfip.com")];
-    char stringpool_str5277[sizeof("shibetsu.hokkaido.jp")];
-    char stringpool_str5278[sizeof("takamori.kumamoto.jp")];
-    char stringpool_str5279[sizeof("nishi.fukuoka.jp")];
-    char stringpool_str5280[sizeof("abeno.osaka.jp")];
-    char stringpool_str5281[sizeof("coal.museum")];
-    char stringpool_str5282[sizeof("kanna.gunma.jp")];
-    char stringpool_str5283[sizeof("turen.tn")];
-    char stringpool_str5284[sizeof("oyodo.nara.jp")];
-    char stringpool_str5285[sizeof("tahara.aichi.jp")];
-    char stringpool_str5286[sizeof("virginia.museum")];
-    char stringpool_str5287[sizeof("shinjuku.tokyo.jp")];
-    char stringpool_str5288[sizeof("k12.vi.us")];
-    char stringpool_str5289[sizeof("saigawa.fukuoka.jp")];
-    char stringpool_str5290[sizeof("agrar.hu")];
-    char stringpool_str5291[sizeof("kawamata.fukushima.jp")];
-    char stringpool_str5292[sizeof("from-mt.com")];
-    char stringpool_str5293[sizeof("fitjar.no")];
-    char stringpool_str5294[sizeof("mihama.mie.jp")];
-    char stringpool_str5295[sizeof("sekikawa.niigata.jp")];
-    char stringpool_str5296[sizeof("shimamaki.hokkaido.jp")];
-    char stringpool_str5297[sizeof("tanabe.wakayama.jp")];
-    char stringpool_str5298[sizeof("tokke.no")];
-    char stringpool_str5299[sizeof("ftpaccess.cc")];
-    char stringpool_str5300[sizeof("volyn.ua")];
-    char stringpool_str5301[sizeof("wlocl.pl")];
-    char stringpool_str5302[sizeof("udine.it")];
-    char stringpool_str5303[sizeof("tokyo.jp")];
-    char stringpool_str5304[sizeof("furukawa.miyagi.jp")];
-    char stringpool_str5305[sizeof("fujioka.gunma.jp")];
-    char stringpool_str5306[sizeof("settsu.osaka.jp")];
-    char stringpool_str5307[sizeof("gosen.niigata.jp")];
-    char stringpool_str5308[sizeof("shimizu.hokkaido.jp")];
-    char stringpool_str5309[sizeof("vic.gov.au")];
-    char stringpool_str5310[sizeof("cody.museum")];
-    char stringpool_str5311[sizeof("ojiya.niigata.jp")];
-    char stringpool_str5312[sizeof("iraq.museum")];
-    char stringpool_str5313[sizeof("museum.no")];
-    char stringpool_str5314[sizeof("chikuzen.fukuoka.jp")];
-    char stringpool_str5315[sizeof("pilots.museum")];
-    char stringpool_str5316[sizeof("shikama.miyagi.jp")];
-    char stringpool_str5317[sizeof("thruhere.net")];
-    char stringpool_str5318[sizeof("sannohe.aomori.jp")];
-    char stringpool_str5319[sizeof("utazas.hu")];
-    char stringpool_str5320[sizeof("scrapping.cc")];
-    char stringpool_str5321[sizeof("experts-comptables.fr")];
-    char stringpool_str5322[sizeof("mypets.ws")];
-    char stringpool_str5323[sizeof("higashinaruse.akita.jp")];
-    char stringpool_str5324[sizeof("ddr.museum")];
-    char stringpool_str5325[sizeof("sor-varanger.no")];
-    char stringpool_str5326[sizeof("savona.it")];
-    char stringpool_str5327[sizeof("other.nf")];
-    char stringpool_str5328[sizeof("yorkshire.museum")];
-    char stringpool_str5329[sizeof("lans.museum")];
-    char stringpool_str5330[sizeof("ozora.hokkaido.jp")];
-    char stringpool_str5331[sizeof("yugawa.fukushima.jp")];
-    char stringpool_str5332[sizeof("hashima.gifu.jp")];
-    char stringpool_str5333[sizeof("is-a-liberal.com")];
-    char stringpool_str5334[sizeof("vlaanderen.museum")];
-    char stringpool_str5335[sizeof("pro.mv")];
-    char stringpool_str5336[sizeof("otobe.hokkaido.jp")];
-    char stringpool_str5337[sizeof("heimatunduhren.museum")];
-    char stringpool_str5338[sizeof("komono.mie.jp")];
-    char stringpool_str5339[sizeof("global.prod.fastly.net")];
-    char stringpool_str5340[sizeof("toride.ibaraki.jp")];
-    char stringpool_str5341[sizeof("soma.fukushima.jp")];
-    char stringpool_str5342[sizeof("daito.osaka.jp")];
-    char stringpool_str5343[sizeof("from-id.com")];
-    char stringpool_str5344[sizeof("minobu.yamanashi.jp")];
-    char stringpool_str5345[sizeof("rebun.hokkaido.jp")];
-    char stringpool_str5346[sizeof("copenhagen.museum")];
-    char stringpool_str5347[sizeof("recreation.aero")];
-    char stringpool_str5348[sizeof("ringsaker.no")];
-    char stringpool_str5349[sizeof("scienceandindustry.museum")];
-    char stringpool_str5350[sizeof("mimata.miyazaki.jp")];
-    char stringpool_str5351[sizeof("kitakata.fukushima.jp")];
-    char stringpool_str5352[sizeof("mukawa.hokkaido.jp")];
-    char stringpool_str5353[sizeof("taishi.hyogo.jp")];
-    char stringpool_str5354[sizeof("katano.osaka.jp")];
-    char stringpool_str5355[sizeof("izena.okinawa.jp")];
-    char stringpool_str5356[sizeof("cc.me.us")];
-    char stringpool_str5357[sizeof("panama.museum")];
-    char stringpool_str5358[sizeof("mifune.kumamoto.jp")];
-    char stringpool_str5359[sizeof("cc.md.us")];
-    char stringpool_str5360[sizeof("kurogi.fukuoka.jp")];
-    char stringpool_str5361[sizeof("cc.sd.us")];
-    char stringpool_str5362[sizeof("samukawa.kanagawa.jp")];
-    char stringpool_str5363[sizeof("cc.mo.us")];
-    char stringpool_str5364[sizeof("cc.ms.us")];
-    char stringpool_str5365[sizeof("cc.de.us")];
-    char stringpool_str5366[sizeof("kagamiishi.fukushima.jp")];
-    char stringpool_str5367[sizeof("xn--mgbtf8fl")];
-    char stringpool_str5368[sizeof("mihama.chiba.jp")];
-    char stringpool_str5369[sizeof("arts.museum")];
-    char stringpool_str5370[sizeof("siljan.no")];
-    char stringpool_str5371[sizeof("tingvoll.no")];
-    char stringpool_str5372[sizeof("reggio-calabria.it")];
-    char stringpool_str5373[sizeof("cc.as.us")];
-    char stringpool_str5374[sizeof("kunimi.fukushima.jp")];
-    char stringpool_str5375[sizeof("ringerike.no")];
-    char stringpool_str5376[sizeof("itano.tokushima.jp")];
-    char stringpool_str5377[sizeof("xn--nqv7fs00ema")];
-    char stringpool_str5378[sizeof("malopolska.pl")];
-    char stringpool_str5379[sizeof("fukagawa.hokkaido.jp")];
-    char stringpool_str5380[sizeof("misaki.okayama.jp")];
-    char stringpool_str5381[sizeof("kasuga.fukuoka.jp")];
-    char stringpool_str5382[sizeof("k12.oh.us")];
-    char stringpool_str5383[sizeof("saintlouis.museum")];
-    char stringpool_str5384[sizeof("kumano.mie.jp")];
-    char stringpool_str5385[sizeof("cc.ma.us")];
-    char stringpool_str5386[sizeof("cc.la.us")];
-    char stringpool_str5387[sizeof("ebino.miyazaki.jp")];
-    char stringpool_str5388[sizeof("kamitsue.oita.jp")];
-    char stringpool_str5389[sizeof("bale.museum")];
-    char stringpool_str5390[sizeof("reggioemilia.it")];
-    char stringpool_str5391[sizeof("kids.museum")];
-    char stringpool_str5392[sizeof("xn--ogbpf8fl")];
-    char stringpool_str5393[sizeof("stpetersburg.museum")];
-    char stringpool_str5394[sizeof("museum.om")];
-    char stringpool_str5395[sizeof("cc.mt.us")];
-    char stringpool_str5396[sizeof("cc.ut.us")];
-    char stringpool_str5397[sizeof("is-a-chef.com")];
-    char stringpool_str5398[sizeof("olsztyn.pl")];
-    char stringpool_str5399[sizeof("tomsk.ru")];
-    char stringpool_str5400[sizeof("glas.museum")];
-    char stringpool_str5401[sizeof("cc.co.us")];
-    char stringpool_str5402[sizeof("museum.tt")];
-    char stringpool_str5403[sizeof("k12.ca.us")];
-    char stringpool_str5404[sizeof("wajima.ishikawa.jp")];
-    char stringpool_str5405[sizeof("cc.ar.us")];
-    char stringpool_str5406[sizeof("tydal.no")];
-    char stringpool_str5407[sizeof("nemuro.hokkaido.jp")];
-    char stringpool_str5408[sizeof("bill.museum")];
-    char stringpool_str5409[sizeof("cc.or.us")];
-    char stringpool_str5410[sizeof("tozawa.yamagata.jp")];
-    char stringpool_str5411[sizeof("xn--davvenjrga-y4a.no")];
-    char stringpool_str5412[sizeof("scienceandhistory.museum")];
-    char stringpool_str5413[sizeof("nagano.jp")];
-    char stringpool_str5414[sizeof("konan.shiga.jp")];
-    char stringpool_str5415[sizeof("cambridge.museum")];
-    char stringpool_str5416[sizeof("kawanabe.kagoshima.jp")];
-    char stringpool_str5417[sizeof("presse.fr")];
-    char stringpool_str5418[sizeof("usdecorativearts.museum")];
-    char stringpool_str5419[sizeof("komvux.se")];
-    char stringpool_str5420[sizeof("targi.pl")];
-    char stringpool_str5421[sizeof("shiranuka.hokkaido.jp")];
-    char stringpool_str5422[sizeof("cc.va.us")];
-    char stringpool_str5423[sizeof("futtsu.chiba.jp")];
-    char stringpool_str5424[sizeof("cc.ks.us")];
-    char stringpool_str5425[sizeof("from-ms.com")];
-    char stringpool_str5426[sizeof("franziskaner.museum")];
-    char stringpool_str5427[sizeof("skierva.no")];
-    char stringpool_str5428[sizeof("cc.az.us")];
-    char stringpool_str5429[sizeof("oyama.tochigi.jp")];
-    char stringpool_str5430[sizeof("ohira.miyagi.jp")];
-    char stringpool_str5431[sizeof("cc.ca.us")];
-    char stringpool_str5432[sizeof("cc.vt.us")];
-    char stringpool_str5433[sizeof("takko.aomori.jp")];
-    char stringpool_str5434[sizeof("clock.museum")];
-    char stringpool_str5435[sizeof("xn--hbmer-xqa.no")];
-    char stringpool_str5436[sizeof("asahi.yamagata.jp")];
-    char stringpool_str5437[sizeof("mihara.hiroshima.jp")];
-    char stringpool_str5438[sizeof("powiat.pl")];
-    char stringpool_str5439[sizeof("botanicalgarden.museum")];
-    char stringpool_str5440[sizeof("guovdageaidnu.no")];
-    char stringpool_str5441[sizeof("radio.br")];
-    char stringpool_str5442[sizeof("is-a-libertarian.com")];
-    char stringpool_str5443[sizeof("cc.ct.us")];
-    char stringpool_str5444[sizeof("rochester.museum")];
-    char stringpool_str5445[sizeof("xn--mtta-vrjjat-k7af.no")];
-    char stringpool_str5446[sizeof("cc.mi.us")];
-    char stringpool_str5447[sizeof("pf")];
-    char stringpool_str5448[sizeof("iijima.nagano.jp")];
-    char stringpool_str5449[sizeof("cc.mn.us")];
-    char stringpool_str5450[sizeof("boldlygoingnowhere.org")];
-    char stringpool_str5451[sizeof("nayoro.hokkaido.jp")];
-    char stringpool_str5452[sizeof("nyny.museum")];
-    char stringpool_str5453[sizeof("asago.hyogo.jp")];
-    char stringpool_str5454[sizeof("shirataka.yamagata.jp")];
-    char stringpool_str5455[sizeof("bushey.museum")];
-    char stringpool_str5456[sizeof("mishima.fukushima.jp")];
-    char stringpool_str5457[sizeof("shikatsu.aichi.jp")];
-    char stringpool_str5458[sizeof("shinichi.hiroshima.jp")];
-    char stringpool_str5459[sizeof("cc.tn.us")];
-    char stringpool_str5460[sizeof("is-a-bruinsfan.org")];
-    char stringpool_str5461[sizeof("fujiidera.osaka.jp")];
-    char stringpool_str5462[sizeof("xn--sgne-gra.no")];
-    char stringpool_str5463[sizeof("malatvuopmi.no")];
-    char stringpool_str5464[sizeof("rygge.no")];
-    char stringpool_str5465[sizeof("hyogo.jp")];
-    char stringpool_str5466[sizeof("midori.gunma.jp")];
-    char stringpool_str5467[sizeof("k12.nh.us")];
-    char stringpool_str5468[sizeof("sendai.jp")];
-    char stringpool_str5469[sizeof("xn--mgbqly7cvafr")];
-    char stringpool_str5470[sizeof("bronnoysund.no")];
-    char stringpool_str5471[sizeof("suli.hu")];
-    char stringpool_str5472[sizeof("friuli-v-giulia.it")];
-    char stringpool_str5473[sizeof("cc.vi.us")];
-    char stringpool_str5474[sizeof("carbonia-iglesias.it")];
-    char stringpool_str5475[sizeof("tolga.no")];
-    char stringpool_str5476[sizeof("hanno.saitama.jp")];
-    char stringpool_str5477[sizeof("poznan.pl")];
-    char stringpool_str5478[sizeof("cc.ak.us")];
-    char stringpool_str5479[sizeof("fujisato.akita.jp")];
-    char stringpool_str5480[sizeof("cc.ok.us")];
-    char stringpool_str5481[sizeof("olecko.pl")];
-    char stringpool_str5482[sizeof("stockholm.museum")];
-    char stringpool_str5483[sizeof("akune.kagoshima.jp")];
-    char stringpool_str5484[sizeof("fuoisku.no")];
-    char stringpool_str5485[sizeof("sagamihara.kanagawa.jp")];
-    char stringpool_str5486[sizeof("otsuchi.iwate.jp")];
-    char stringpool_str5487[sizeof("s3.amazonaws.com")];
-    char stringpool_str5488[sizeof("hakui.ishikawa.jp")];
-    char stringpool_str5489[sizeof("trust.museum")];
-    char stringpool_str5490[sizeof("fujisawa.iwate.jp")];
-    char stringpool_str5491[sizeof("nishiaizu.fukushima.jp")];
-    char stringpool_str5492[sizeof("is-into-anime.com")];
-    char stringpool_str5493[sizeof("cc.al.us")];
-    char stringpool_str5494[sizeof("sayama.osaka.jp")];
-    char stringpool_str5495[sizeof("6bone.pl")];
-    char stringpool_str5496[sizeof("atsugi.kanagawa.jp")];
-    char stringpool_str5497[sizeof("choyo.kumamoto.jp")];
-    char stringpool_str5498[sizeof("namie.fukushima.jp")];
-    char stringpool_str5499[sizeof("kakamigahara.gifu.jp")];
-    char stringpool_str5500[sizeof("minamisanriku.miyagi.jp")];
-    char stringpool_str5501[sizeof("donna.no")];
-    char stringpool_str5502[sizeof("marine.ru")];
-    char stringpool_str5503[sizeof("ono.fukushima.jp")];
-    char stringpool_str5504[sizeof("coloradoplateau.museum")];
-    char stringpool_str5505[sizeof("fujimino.saitama.jp")];
-    char stringpool_str5506[sizeof("tenri.nara.jp")];
-    char stringpool_str5507[sizeof("nakatsugawa.gifu.jp")];
-    char stringpool_str5508[sizeof("kazuno.akita.jp")];
-    char stringpool_str5509[sizeof("kamigori.hyogo.jp")];
-    char stringpool_str5510[sizeof("iyo.ehime.jp")];
-    char stringpool_str5511[sizeof("xn--krager-gya.no")];
-    char stringpool_str5512[sizeof("wanouchi.gifu.jp")];
-    char stringpool_str5513[sizeof("shirahama.wakayama.jp")];
-    char stringpool_str5514[sizeof("shimogo.fukushima.jp")];
-    char stringpool_str5515[sizeof("prd.fr")];
-    char stringpool_str5516[sizeof("um.gov.pl")];
-    char stringpool_str5517[sizeof("xn--bhcavuotna-s4a.no")];
-    char stringpool_str5518[sizeof("cc.oh.us")];
-    char stringpool_str5519[sizeof("kosei.shiga.jp")];
-    char stringpool_str5520[sizeof("cc.ri.us")];
-    char stringpool_str5521[sizeof("k12.nm.us")];
-    char stringpool_str5522[sizeof("xn--hyanger-q1a.no")];
-    char stringpool_str5523[sizeof("cc.fl.us")];
-    char stringpool_str5524[sizeof("nikko.tochigi.jp")];
-    char stringpool_str5525[sizeof("haboro.hokkaido.jp")];
-    char stringpool_str5526[sizeof("readmyblog.org")];
-    char stringpool_str5527[sizeof("lib.mo.us")];
-    char stringpool_str5528[sizeof("yoshioka.gunma.jp")];
-    char stringpool_str5529[sizeof("wloclawek.pl")];
-    char stringpool_str5530[sizeof("motobu.okinawa.jp")];
-    char stringpool_str5531[sizeof("homeip.net")];
-    char stringpool_str5532[sizeof("hagi.yamaguchi.jp")];
-    char stringpool_str5533[sizeof("vikna.no")];
-    char stringpool_str5534[sizeof("yamamoto.miyagi.jp")];
-    char stringpool_str5535[sizeof("yamatsuri.fukushima.jp")];
-    char stringpool_str5536[sizeof("skydiving.aero")];
-    char stringpool_str5537[sizeof("kumano.hiroshima.jp")];
-    char stringpool_str5538[sizeof("samara.ru")];
-    char stringpool_str5539[sizeof("anpachi.gifu.jp")];
-    char stringpool_str5540[sizeof("tajiri.osaka.jp")];
-    char stringpool_str5541[sizeof("k12.gu.us")];
-    char stringpool_str5542[sizeof("tokai.aichi.jp")];
-    char stringpool_str5543[sizeof("blogspot.cf")];
-    char stringpool_str5544[sizeof("suzuka.mie.jp")];
-    char stringpool_str5545[sizeof("chofu.tokyo.jp")];
-    char stringpool_str5546[sizeof("tsunan.niigata.jp")];
-    char stringpool_str5547[sizeof("happou.akita.jp")];
-    char stringpool_str5548[sizeof("awaji.hyogo.jp")];
-    char stringpool_str5549[sizeof("sakuragawa.ibaraki.jp")];
-    char stringpool_str5550[sizeof("naruto.tokushima.jp")];
-    char stringpool_str5551[sizeof("encyclopedic.museum")];
-    char stringpool_str5552[sizeof("lahppi.no")];
-    char stringpool_str5553[sizeof("aizumisato.fukushima.jp")];
-    char stringpool_str5554[sizeof("shimotsuma.ibaraki.jp")];
-    char stringpool_str5555[sizeof("chino.nagano.jp")];
-    char stringpool_str5556[sizeof("airtraffic.aero")];
-    char stringpool_str5557[sizeof("veneto.it")];
-    char stringpool_str5558[sizeof("xn--gecrj9c")];
-    char stringpool_str5559[sizeof("is-a-bulls-fan.com")];
-    char stringpool_str5560[sizeof("aizuwakamatsu.fukushima.jp")];
-    char stringpool_str5561[sizeof("juif.museum")];
-    char stringpool_str5562[sizeof("museum.mv")];
-    char stringpool_str5563[sizeof("minamiashigara.kanagawa.jp")];
-    char stringpool_str5564[sizeof("kyotanabe.kyoto.jp")];
-    char stringpool_str5565[sizeof("torahime.shiga.jp")];
-    char stringpool_str5566[sizeof("cc.ky.us")];
-    char stringpool_str5567[sizeof("googlecode.com")];
-    char stringpool_str5568[sizeof("air-surveillance.aero")];
-    char stringpool_str5569[sizeof("yukuhashi.fukuoka.jp")];
-    char stringpool_str5570[sizeof("dynathome.net")];
-    char stringpool_str5571[sizeof("zgora.pl")];
-    char stringpool_str5572[sizeof("porsanger.no")];
-    char stringpool_str5573[sizeof("xn--mlselv-iua.no")];
-    char stringpool_str5574[sizeof("hikari.yamaguchi.jp")];
-    char stringpool_str5575[sizeof("zgorzelec.pl")];
-    char stringpool_str5576[sizeof("dinosaur.museum")];
-    char stringpool_str5577[sizeof("starostwo.gov.pl")];
-    char stringpool_str5578[sizeof("jgora.pl")];
-    char stringpool_str5579[sizeof("tsukui.kanagawa.jp")];
-    char stringpool_str5580[sizeof("hioki.kagoshima.jp")];
-    char stringpool_str5581[sizeof("toba.mie.jp")];
-    char stringpool_str5582[sizeof("fukuchiyama.kyoto.jp")];
-    char stringpool_str5583[sizeof("mil.co")];
-    char stringpool_str5584[sizeof("ukiha.fukuoka.jp")];
-    char stringpool_str5585[sizeof("touch.museum")];
-    char stringpool_str5586[sizeof("shimizu.shizuoka.jp")];
-    char stringpool_str5587[sizeof("kasahara.gifu.jp")];
-    char stringpool_str5588[sizeof("design.museum")];
-    char stringpool_str5589[sizeof("frankfurt.museum")];
-    char stringpool_str5590[sizeof("ogimi.okinawa.jp")];
-    char stringpool_str5591[sizeof("saroma.hokkaido.jp")];
-    char stringpool_str5592[sizeof("sa-east-1.compute.amazonaws.com")];
-    char stringpool_str5593[sizeof("piedmont.it")];
-    char stringpool_str5594[sizeof("cc.hi.us")];
-    char stringpool_str5595[sizeof("syzran.ru")];
-    char stringpool_str5596[sizeof("pordenone.it")];
-    char stringpool_str5597[sizeof("miyada.nagano.jp")];
-    char stringpool_str5598[sizeof("embroidery.museum")];
-    char stringpool_str5599[sizeof("foggia.it")];
-    char stringpool_str5600[sizeof("szczecin.pl")];
-    char stringpool_str5601[sizeof("lanbib.se")];
-    char stringpool_str5602[sizeof("nakatane.kagoshima.jp")];
-    char stringpool_str5603[sizeof("shimosuwa.nagano.jp")];
-    char stringpool_str5604[sizeof("uw.gov.pl")];
-    char stringpool_str5605[sizeof("bunkyo.tokyo.jp")];
-    char stringpool_str5606[sizeof("fet.no")];
-    char stringpool_str5607[sizeof("valley.museum")];
-    char stringpool_str5608[sizeof("taira.toyama.jp")];
-    char stringpool_str5609[sizeof("tas.gov.au")];
-    char stringpool_str5610[sizeof("doshi.yamanashi.jp")];
-    char stringpool_str5611[sizeof("makurazaki.kagoshima.jp")];
-    char stringpool_str5612[sizeof("tychy.pl")];
-    char stringpool_str5613[sizeof("molde.no")];
-    char stringpool_str5614[sizeof("withgoogle.com")];
-    char stringpool_str5615[sizeof("k12.ga.us")];
-    char stringpool_str5616[sizeof("tado.mie.jp")];
-    char stringpool_str5617[sizeof("nakano.tokyo.jp")];
-    char stringpool_str5618[sizeof("hokuto.hokkaido.jp")];
-    char stringpool_str5619[sizeof("ltd.co.im")];
-    char stringpool_str5620[sizeof("sayama.saitama.jp")];
-    char stringpool_str5621[sizeof("miyagi.jp")];
-    char stringpool_str5622[sizeof("fujieda.shizuoka.jp")];
-    char stringpool_str5623[sizeof("olawa.pl")];
-    char stringpool_str5624[sizeof("takata.fukuoka.jp")];
-    char stringpool_str5625[sizeof("ilawa.pl")];
-    char stringpool_str5626[sizeof("fujikawa.shizuoka.jp")];
-    char stringpool_str5627[sizeof("ashiya.fukuoka.jp")];
-    char stringpool_str5628[sizeof("rotorcraft.aero")];
-    char stringpool_str5629[sizeof("miyota.nagano.jp")];
-    char stringpool_str5630[sizeof("forgot.his.name")];
-    char stringpool_str5631[sizeof("ohira.tochigi.jp")];
-    char stringpool_str5632[sizeof("shiroishi.miyagi.jp")];
-    char stringpool_str5633[sizeof("tsuru.yamanashi.jp")];
-    char stringpool_str5634[sizeof("shinshiro.aichi.jp")];
-    char stringpool_str5635[sizeof("modum.no")];
-    char stringpool_str5636[sizeof("osoyro.no")];
-    char stringpool_str5637[sizeof("tagawa.fukuoka.jp")];
-    char stringpool_str5638[sizeof("koori.fukushima.jp")];
-    char stringpool_str5639[sizeof("cc.ga.us")];
-    char stringpool_str5640[sizeof("kaminoyama.yamagata.jp")];
-    char stringpool_str5641[sizeof("wa.gov.au")];
-    char stringpool_str5642[sizeof("sakura.chiba.jp")];
-    char stringpool_str5643[sizeof("murata.miyagi.jp")];
-    char stringpool_str5644[sizeof("szkola.pl")];
-    char stringpool_str5645[sizeof("tjome.no")];
-    char stringpool_str5646[sizeof("sel.no")];
-    char stringpool_str5647[sizeof("montreal.museum")];
-    char stringpool_str5648[sizeof("navigation.aero")];
-    char stringpool_str5649[sizeof("yoita.niigata.jp")];
-    char stringpool_str5650[sizeof("shibukawa.gunma.jp")];
-    char stringpool_str5651[sizeof("lomza.pl")];
-    char stringpool_str5652[sizeof("cc.gu.us")];
-    char stringpool_str5653[sizeof("york.museum")];
-    char stringpool_str5654[sizeof("selfip.biz")];
-    char stringpool_str5655[sizeof("aisho.shiga.jp")];
-    char stringpool_str5656[sizeof("palace.museum")];
-    char stringpool_str5657[sizeof("author.aero")];
-    char stringpool_str5658[sizeof("dominic.ua")];
-    char stringpool_str5659[sizeof("koriyama.fukushima.jp")];
-    char stringpool_str5660[sizeof("technology.museum")];
-    char stringpool_str5661[sizeof("utsunomiya.tochigi.jp")];
-    char stringpool_str5662[sizeof("podzone.org")];
-    char stringpool_str5663[sizeof("s3-ap-southeast-2.amazonaws.com")];
-    char stringpool_str5664[sizeof("pomorskie.pl")];
-    char stringpool_str5665[sizeof("sld.do")];
-    char stringpool_str5666[sizeof("onojo.fukuoka.jp")];
-    char stringpool_str5667[sizeof("misugi.mie.jp")];
-    char stringpool_str5668[sizeof("press.ma")];
-    char stringpool_str5669[sizeof("dyndns-server.com")];
-    char stringpool_str5670[sizeof("seki.gifu.jp")];
-    char stringpool_str5671[sizeof("tohma.hokkaido.jp")];
-    char stringpool_str5672[sizeof("taiki.hokkaido.jp")];
-    char stringpool_str5673[sizeof("perso.ht")];
-    char stringpool_str5674[sizeof("surgut.ru")];
-    char stringpool_str5675[sizeof("utah.museum")];
-    char stringpool_str5676[sizeof("merseine.nu")];
-    char stringpool_str5677[sizeof("fosnes.no")];
-    char stringpool_str5678[sizeof("sweden.museum")];
-    char stringpool_str5679[sizeof("monza-e-della-brianza.it")];
-    char stringpool_str5680[sizeof("nakagawa.fukuoka.jp")];
-    char stringpool_str5681[sizeof("kamimine.saga.jp")];
-    char stringpool_str5682[sizeof("przeworsk.pl")];
-    char stringpool_str5683[sizeof("sa.edu.au")];
-    char stringpool_str5684[sizeof("lib.fl.us")];
-    char stringpool_str5685[sizeof("webhop.info")];
-    char stringpool_str5686[sizeof("higashikurume.tokyo.jp")];
-    char stringpool_str5687[sizeof("yorii.saitama.jp")];
-    char stringpool_str5688[sizeof("fla.no")];
-    char stringpool_str5689[sizeof("taito.tokyo.jp")];
-    char stringpool_str5690[sizeof("trana.no")];
-    char stringpool_str5691[sizeof("shimofusa.chiba.jp")];
-    char stringpool_str5692[sizeof("takanezawa.tochigi.jp")];
-    char stringpool_str5693[sizeof("z-1.compute-1.amazonaws.com")];
-    char stringpool_str5694[sizeof("mansion.museum")];
-    char stringpool_str5695[sizeof("riodejaneiro.museum")];
-    char stringpool_str5696[sizeof("perso.tn")];
-    char stringpool_str5697[sizeof("z-2.compute-1.amazonaws.com")];
-    char stringpool_str5698[sizeof("ashoro.hokkaido.jp")];
-    char stringpool_str5699[sizeof("kawaue.gifu.jp")];
-    char stringpool_str5700[sizeof("matsusaka.mie.jp")];
-    char stringpool_str5701[sizeof("sapporo.jp")];
-    char stringpool_str5702[sizeof("webhop.net")];
-    char stringpool_str5703[sizeof("mutsu.aomori.jp")];
-    char stringpool_str5704[sizeof("groks-the.info")];
-    char stringpool_str5705[sizeof("square.museum")];
-    char stringpool_str5706[sizeof("podlasie.pl")];
-    char stringpool_str5707[sizeof("ranzan.saitama.jp")];
-    char stringpool_str5708[sizeof("turin.it")];
-    char stringpool_str5709[sizeof("bihoro.hokkaido.jp")];
-    char stringpool_str5710[sizeof("nikaho.akita.jp")];
-    char stringpool_str5711[sizeof("tambov.ru")];
-    char stringpool_str5712[sizeof("terni.it")];
-    char stringpool_str5713[sizeof("parma.it")];
-    char stringpool_str5714[sizeof("maizuru.kyoto.jp")];
-    char stringpool_str5715[sizeof("county.museum")];
-    char stringpool_str5716[sizeof("szczytno.pl")];
-    char stringpool_str5717[sizeof("minowa.nagano.jp")];
-    char stringpool_str5718[sizeof("from-md.com")];
-    char stringpool_str5719[sizeof("prato.it")];
-    char stringpool_str5720[sizeof("meloy.no")];
-    char stringpool_str5721[sizeof("cc.sc.us")];
-    char stringpool_str5722[sizeof("support")];
-    char stringpool_str5723[sizeof("polkowice.pl")];
-    char stringpool_str5724[sizeof("honjyo.akita.jp")];
-    char stringpool_str5725[sizeof("cc.dc.us")];
-    char stringpool_str5726[sizeof("kitashiobara.fukushima.jp")];
-    char stringpool_str5727[sizeof("memorial.museum")];
-    char stringpool_str5728[sizeof("magazine.aero")];
-    char stringpool_str5729[sizeof("bilbao.museum")];
-    char stringpool_str5730[sizeof("ogaki.gifu.jp")];
-    char stringpool_str5731[sizeof("skodje.no")];
-    char stringpool_str5732[sizeof("suisse.museum")];
-    char stringpool_str5733[sizeof("milan.it")];
-    char stringpool_str5734[sizeof("tomiya.miyagi.jp")];
-    char stringpool_str5735[sizeof("xn--bhccavuotna-k7a.no")];
-    char stringpool_str5736[sizeof("missoula.museum")];
-    char stringpool_str5737[sizeof("monmouth.museum")];
-    char stringpool_str5738[sizeof("parachuting.aero")];
-    char stringpool_str5739[sizeof("padua.it")];
-    char stringpool_str5740[sizeof("ryazan.ru")];
-    char stringpool_str5741[sizeof("skanit.no")];
-    char stringpool_str5742[sizeof("ayase.kanagawa.jp")];
-    char stringpool_str5743[sizeof("piemonte.it")];
-    char stringpool_str5744[sizeof("maniwa.okayama.jp")];
-    char stringpool_str5745[sizeof("stavropol.ru")];
-    char stringpool_str5746[sizeof("takamori.nagano.jp")];
-    char stringpool_str5747[sizeof("ulan-ude.ru")];
-    char stringpool_str5748[sizeof("shinagawa.tokyo.jp")];
-    char stringpool_str5749[sizeof("from-va.com")];
-    char stringpool_str5750[sizeof("frosta.no")];
-    char stringpool_str5751[sizeof("yaita.tochigi.jp")];
-    char stringpool_str5752[sizeof("freight.aero")];
-    char stringpool_str5753[sizeof("massa-carrara.it")];
-    char stringpool_str5754[sizeof("usantiques.museum")];
-    char stringpool_str5755[sizeof("masoy.no")];
-    char stringpool_str5756[sizeof("fhs.no")];
-    char stringpool_str5757[sizeof("mihama.aichi.jp")];
-    char stringpool_str5758[sizeof("tachiarai.fukuoka.jp")];
-    char stringpool_str5759[sizeof("mihara.kochi.jp")];
-    char stringpool_str5760[sizeof("tenei.fukushima.jp")];
-    char stringpool_str5761[sizeof("saratov.ru")];
-    char stringpool_str5762[sizeof("shisui.chiba.jp")];
-    char stringpool_str5763[sizeof("telekommunikation.museum")];
-    char stringpool_str5764[sizeof("yamanouchi.nagano.jp")];
-    char stringpool_str5765[sizeof("snoasa.no")];
-    char stringpool_str5766[sizeof("anthro.museum")];
-    char stringpool_str5767[sizeof("ikawa.akita.jp")];
-    char stringpool_str5768[sizeof("mining.museum")];
-    char stringpool_str5769[sizeof("ichinomiya.aichi.jp")];
-    char stringpool_str5770[sizeof("kisofukushima.nagano.jp")];
-    char stringpool_str5771[sizeof("tainai.niigata.jp")];
-    char stringpool_str5772[sizeof("bern.museum")];
-    char stringpool_str5773[sizeof("nakai.kanagawa.jp")];
-    char stringpool_str5774[sizeof("school.na")];
-    char stringpool_str5775[sizeof("parliament.uk")];
-    char stringpool_str5776[sizeof("stokke.no")];
-    char stringpool_str5777[sizeof("bonn.museum")];
-    char stringpool_str5778[sizeof("perso.sn")];
-    char stringpool_str5779[sizeof("takanabe.miyazaki.jp")];
-    char stringpool_str5780[sizeof("ichinomiya.chiba.jp")];
-    char stringpool_str5781[sizeof("selfip.org")];
-    char stringpool_str5782[sizeof("sennan.osaka.jp")];
-    char stringpool_str5783[sizeof("shinshinotsu.hokkaido.jp")];
-    char stringpool_str5784[sizeof("shiroi.chiba.jp")];
-    char stringpool_str5785[sizeof("lib.co.us")];
-    char stringpool_str5786[sizeof("cc.id.us")];
-    char stringpool_str5787[sizeof("hirono.iwate.jp")];
-    char stringpool_str5788[sizeof("plants.museum")];
-    char stringpool_str5789[sizeof("fukaya.saitama.jp")];
-    char stringpool_str5790[sizeof("sarpsborg.no")];
-    char stringpool_str5791[sizeof("cc.tx.us")];
-    char stringpool_str5792[sizeof("fujikawa.yamanashi.jp")];
-    char stringpool_str5793[sizeof("ski.no")];
-    char stringpool_str5794[sizeof("from-me.org")];
-    char stringpool_str5795[sizeof("nativeamerican.museum")];
-    char stringpool_str5796[sizeof("komagane.nagano.jp")];
-    char stringpool_str5797[sizeof("tokoname.aichi.jp")];
-    char stringpool_str5798[sizeof("xn--sndre-land-0cb.no")];
-    char stringpool_str5799[sizeof("cc.ia.us")];
-    char stringpool_str5800[sizeof("tarui.gifu.jp")];
-    char stringpool_str5801[sizeof("museum.mw")];
-    char stringpool_str5802[sizeof("xn--srreisa-q1a.no")];
-    char stringpool_str5803[sizeof("takahama.fukui.jp")];
-    char stringpool_str5804[sizeof("yakumo.shimane.jp")];
-    char stringpool_str5805[sizeof("maryland.museum")];
-    char stringpool_str5806[sizeof("pc.pl")];
-    char stringpool_str5807[sizeof("higashine.yamagata.jp")];
-    char stringpool_str5808[sizeof("takagi.nagano.jp")];
-    char stringpool_str5809[sizeof("presidio.museum")];
-    char stringpool_str5810[sizeof("skjervoy.no")];
-    char stringpool_str5811[sizeof("yanagawa.fukuoka.jp")];
-    char stringpool_str5812[sizeof("hokuto.yamanashi.jp")];
-    char stringpool_str5813[sizeof("tendo.yamagata.jp")];
-    char stringpool_str5814[sizeof("tsuno.miyazaki.jp")];
-    char stringpool_str5815[sizeof("ishinomaki.miyagi.jp")];
-    char stringpool_str5816[sizeof("xn--gls-elac.no")];
-    char stringpool_str5817[sizeof("pesaro-urbino.it")];
-    char stringpool_str5818[sizeof("cc.ne.us")];
-    char stringpool_str5819[sizeof("cc.nd.us")];
-    char stringpool_str5820[sizeof("artanddesign.museum")];
-    char stringpool_str5821[sizeof("cc.nj.us")];
-    char stringpool_str5822[sizeof("teramo.it")];
-    char stringpool_str5823[sizeof("funagata.yamagata.jp")];
-    char stringpool_str5824[sizeof("tabuse.yamaguchi.jp")];
-    char stringpool_str5825[sizeof("yakumo.hokkaido.jp")];
-    char stringpool_str5826[sizeof("komoro.nagano.jp")];
-    char stringpool_str5827[sizeof("cc.in.us")];
-    char stringpool_str5828[sizeof("ap-southeast-2.compute.amazonaws.com")];
-    char stringpool_str5829[sizeof("taiji.wakayama.jp")];
-    char stringpool_str5830[sizeof("sodegaura.chiba.jp")];
-    char stringpool_str5831[sizeof("roma.museum")];
-    char stringpool_str5832[sizeof("afjord.no")];
-    char stringpool_str5833[sizeof("miyakonojo.miyazaki.jp")];
-    char stringpool_str5834[sizeof("tsuruoka.yamagata.jp")];
-    char stringpool_str5835[sizeof("dyndns-web.com")];
-    char stringpool_str5836[sizeof("tcm.museum")];
-    char stringpool_str5837[sizeof("paroch.k12.ma.us")];
-    char stringpool_str5838[sizeof("ishikawa.fukushima.jp")];
-    char stringpool_str5839[sizeof("zushi.kanagawa.jp")];
-    char stringpool_str5840[sizeof("okawa.kochi.jp")];
-    char stringpool_str5841[sizeof("katsuyama.fukui.jp")];
-    char stringpool_str5842[sizeof("tsuno.kochi.jp")];
-    char stringpool_str5843[sizeof("tamakawa.fukushima.jp")];
-    char stringpool_str5844[sizeof("from-vt.com")];
-    char stringpool_str5845[sizeof("is-not-certified.com")];
-    char stringpool_str5846[sizeof("cc.il.us")];
-    char stringpool_str5847[sizeof("cc.nm.us")];
-    char stringpool_str5848[sizeof("uvic.museum")];
-    char stringpool_str5849[sizeof("sch.ly")];
-    char stringpool_str5850[sizeof("sakegawa.yamagata.jp")];
-    char stringpool_str5851[sizeof("tokai.ibaraki.jp")];
-    char stringpool_str5852[sizeof("shibuya.tokyo.jp")];
-    char stringpool_str5853[sizeof("githubusercontent.com")];
-    char stringpool_str5854[sizeof("microlight.aero")];
-    char stringpool_str5855[sizeof("ogose.saitama.jp")];
-    char stringpool_str5856[sizeof("mesaverde.museum")];
-    char stringpool_str5857[sizeof("aeroport.fr")];
-    char stringpool_str5858[sizeof("ogano.saitama.jp")];
-    char stringpool_str5859[sizeof("stavanger.no")];
-    char stringpool_str5860[sizeof("fujishiro.ibaraki.jp")];
-    char stringpool_str5861[sizeof("kihoku.ehime.jp")];
-    char stringpool_str5862[sizeof("axis.museum")];
-    char stringpool_str5863[sizeof("miasa.nagano.jp")];
-    char stringpool_str5864[sizeof("pasadena.museum")];
-    char stringpool_str5865[sizeof("fukuchi.fukuoka.jp")];
-    char stringpool_str5866[sizeof("portland.museum")];
-    char stringpool_str5867[sizeof("miyama.fukuoka.jp")];
-    char stringpool_str5868[sizeof("rovno.ua")];
-    char stringpool_str5869[sizeof("daigo.ibaraki.jp")];
-    char stringpool_str5870[sizeof("xn--eveni-0qa01ga.no")];
-    char stringpool_str5871[sizeof("press.museum")];
-    char stringpool_str5872[sizeof("toyota.yamaguchi.jp")];
-    char stringpool_str5873[sizeof("supplies")];
-    char stringpool_str5874[sizeof("blogsite.org")];
-    char stringpool_str5875[sizeof("minoh.osaka.jp")];
-    char stringpool_str5876[sizeof("moriya.ibaraki.jp")];
-    char stringpool_str5877[sizeof("money.museum")];
-    char stringpool_str5878[sizeof("show.aero")];
-    char stringpool_str5879[sizeof("yamato.kumamoto.jp")];
-    char stringpool_str5880[sizeof("nagano.nagano.jp")];
-    char stringpool_str5881[sizeof("tamba.hyogo.jp")];
-    char stringpool_str5882[sizeof("minami.fukuoka.jp")];
-    char stringpool_str5883[sizeof("niepce.museum")];
-    char stringpool_str5884[sizeof("flatanger.no")];
-    char stringpool_str5885[sizeof("aguni.okinawa.jp")];
-    char stringpool_str5886[sizeof("oshima.yamaguchi.jp")];
-    char stringpool_str5887[sizeof("management")];
-    char stringpool_str5888[sizeof("sopot.pl")];
-    char stringpool_str5889[sizeof("oguni.kumamoto.jp")];
-    char stringpool_str5890[sizeof("sumida.tokyo.jp")];
-    char stringpool_str5891[sizeof("ritto.shiga.jp")];
-    char stringpool_str5892[sizeof("mad.museum")];
-    char stringpool_str5893[sizeof("cc.nh.us")];
-    char stringpool_str5894[sizeof("forde.no")];
-    char stringpool_str5895[sizeof("media.pl")];
-    char stringpool_str5896[sizeof("tsuiki.fukuoka.jp")];
-    char stringpool_str5897[sizeof("okoppe.hokkaido.jp")];
-    char stringpool_str5898[sizeof("prochowice.pl")];
-    char stringpool_str5899[sizeof("cc.ny.us")];
-    char stringpool_str5900[sizeof("casino.hu")];
-    char stringpool_str5901[sizeof("tranoy.no")];
-    char stringpool_str5902[sizeof("broker.aero")];
-    char stringpool_str5903[sizeof("shinkamigoto.nagasaki.jp")];
-    char stringpool_str5904[sizeof("mikawa.yamagata.jp")];
-    char stringpool_str5905[sizeof("rivne.ua")];
-    char stringpool_str5906[sizeof("ug.gov.pl")];
-    char stringpool_str5907[sizeof("fermo.it")];
-    char stringpool_str5908[sizeof("yashio.saitama.jp")];
-    char stringpool_str5909[sizeof("shiogama.miyagi.jp")];
-    char stringpool_str5910[sizeof("morioka.iwate.jp")];
-    char stringpool_str5911[sizeof("paleo.museum")];
-    char stringpool_str5912[sizeof("science-fiction.museum")];
-    char stringpool_str5913[sizeof("xn--gildeskl-g0a.no")];
-    char stringpool_str5914[sizeof("fortworth.museum")];
-    char stringpool_str5915[sizeof("loppa.no")];
-    char stringpool_str5916[sizeof("dyndns.info")];
-    char stringpool_str5917[sizeof("toyono.osaka.jp")];
-    char stringpool_str5918[sizeof("feedback")];
-    char stringpool_str5919[sizeof("michigan.museum")];
-    char stringpool_str5920[sizeof("historyofscience.museum")];
-    char stringpool_str5921[sizeof("grong.no")];
-    char stringpool_str5922[sizeof("barrel-of-knowledge.info")];
-    char stringpool_str5923[sizeof("sanok.pl")];
-    char stringpool_str5924[sizeof("sorum.no")];
-    char stringpool_str5925[sizeof("eniwa.hokkaido.jp")];
-    char stringpool_str5926[sizeof("tree.museum")];
-    char stringpool_str5927[sizeof("sauda.no")];
-    char stringpool_str5928[sizeof("tank.museum")];
-    char stringpool_str5929[sizeof("stuff-4-sale.us")];
-    char stringpool_str5930[sizeof("mihama.wakayama.jp")];
-    char stringpool_str5931[sizeof("ujiie.tochigi.jp")];
-    char stringpool_str5932[sizeof("pubol.museum")];
-    char stringpool_str5933[sizeof("tokamachi.niigata.jp")];
-    char stringpool_str5934[sizeof("nakano.nagano.jp")];
-    char stringpool_str5935[sizeof("graphics")];
-    char stringpool_str5936[sizeof("bahn.museum")];
-    char stringpool_str5937[sizeof("sor-fron.no")];
-    char stringpool_str5938[sizeof("seirou.niigata.jp")];
-    char stringpool_str5939[sizeof("mazury.pl")];
-    char stringpool_str5940[sizeof("tranby.no")];
-    char stringpool_str5941[sizeof("time.museum")];
-    char stringpool_str5942[sizeof("nishio.aichi.jp")];
-    char stringpool_str5943[sizeof("snasa.no")];
-    char stringpool_str5944[sizeof("suzaka.nagano.jp")];
-    char stringpool_str5945[sizeof("fjell.no")];
-    char stringpool_str5946[sizeof("stryn.no")];
-    char stringpool_str5947[sizeof("klepp.no")];
-    char stringpool_str5948[sizeof("kitagata.gifu.jp")];
-    char stringpool_str5949[sizeof("engine.aero")];
-    char stringpool_str5950[sizeof("kumakogen.ehime.jp")];
-    char stringpool_str5951[sizeof("salat.no")];
-    char stringpool_str5952[sizeof("k12.nv.us")];
-    char stringpool_str5953[sizeof("for-our.info")];
-    char stringpool_str5954[sizeof("sandiego.museum")];
-    char stringpool_str5955[sizeof("stathelle.no")];
-    char stringpool_str5956[sizeof("imizu.toyama.jp")];
-    char stringpool_str5957[sizeof("sklep.pl")];
-    char stringpool_str5958[sizeof("forlicesena.it")];
-    char stringpool_str5959[sizeof("susaki.kochi.jp")];
-    char stringpool_str5960[sizeof("shimotsuke.tochigi.jp")];
-    char stringpool_str5961[sizeof("minamiechizen.fukui.jp")];
-    char stringpool_str5962[sizeof("seaport.museum")];
-    char stringpool_str5963[sizeof("computer.museum")];
-    char stringpool_str5964[sizeof("cc.nv.us")];
-    char stringpool_str5965[sizeof("fundacio.museum")];
-    char stringpool_str5966[sizeof("mizumaki.fukuoka.jp")];
-    char stringpool_str5967[sizeof("fuettertdasnetz.de")];
-    char stringpool_str5968[sizeof("slask.pl")];
-    char stringpool_str5969[sizeof("mazowsze.pl")];
-    char stringpool_str5970[sizeof("higashishirakawa.gifu.jp")];
-    char stringpool_str5971[sizeof("est-mon-blogueur.com")];
-    char stringpool_str5972[sizeof("chizu.tottori.jp")];
-    char stringpool_str5973[sizeof("beppu.oita.jp")];
-    char stringpool_str5974[sizeof("tarnobrzeg.pl")];
-    char stringpool_str5975[sizeof("hirado.nagasaki.jp")];
-    char stringpool_str5976[sizeof("shichikashuku.miyagi.jp")];
-    char stringpool_str5977[sizeof("stjohn.museum")];
-    char stringpool_str5978[sizeof("school.museum")];
-    char stringpool_str5979[sizeof("shirakawa.gifu.jp")];
-    char stringpool_str5980[sizeof("mihama.fukui.jp")];
-    char stringpool_str5981[sizeof("fedje.no")];
-    char stringpool_str5982[sizeof("skaun.no")];
-    char stringpool_str5983[sizeof("taki.mie.jp")];
-    char stringpool_str5984[sizeof("government.aero")];
-    char stringpool_str5985[sizeof("trader.aero")];
-    char stringpool_str5986[sizeof("sch.jo")];
-    char stringpool_str5987[sizeof("toyako.hokkaido.jp")];
-    char stringpool_str5988[sizeof("yonago.tottori.jp")];
-    char stringpool_str5989[sizeof("ogori.fukuoka.jp")];
-    char stringpool_str5990[sizeof("maritimo.museum")];
-    char stringpool_str5991[sizeof("xn--kvitsy-fya.no")];
-    char stringpool_str5992[sizeof("servegame.org")];
-    char stringpool_str5993[sizeof("inawashiro.fukushima.jp")];
-    char stringpool_str5994[sizeof("station.museum")];
-    char stringpool_str5995[sizeof("horology.museum")];
-    char stringpool_str5996[sizeof("okawa.fukuoka.jp")];
-    char stringpool_str5997[sizeof("software.aero")];
-    char stringpool_str5998[sizeof("selje.no")];
-    char stringpool_str5999[sizeof("miharu.fukushima.jp")];
-    char stringpool_str6000[sizeof("settlers.museum")];
-    char stringpool_str6001[sizeof("shop.pl")];
-    char stringpool_str6002[sizeof("motegi.tochigi.jp")];
-    char stringpool_str6003[sizeof("pavia.it")];
-    char stringpool_str6004[sizeof("moriyoshi.akita.jp")];
-    char stringpool_str6005[sizeof("ryuoh.shiga.jp")];
-    char stringpool_str6006[sizeof("selbu.no")];
-    char stringpool_str6007[sizeof("sakura.tochigi.jp")];
-    char stringpool_str6008[sizeof("muenster.museum")];
-    char stringpool_str6009[sizeof("marumori.miyagi.jp")];
-    char stringpool_str6010[sizeof("sakawa.kochi.jp")];
-    char stringpool_str6011[sizeof("vibo-valentia.it")];
-    char stringpool_str6012[sizeof("xn--berlevg-jxa.no")];
-    char stringpool_str6013[sizeof("aki.kochi.jp")];
-    char stringpool_str6014[sizeof("fujisawa.kanagawa.jp")];
-    char stringpool_str6015[sizeof("tokorozawa.saitama.jp")];
-    char stringpool_str6016[sizeof("figueres.museum")];
-    char stringpool_str6017[sizeof("xn--rennesy-v1a.no")];
-    char stringpool_str6018[sizeof("k12.ny.us")];
-    char stringpool_str6019[sizeof("songdalen.no")];
-    char stringpool_str6020[sizeof("honefoss.no")];
-    char stringpool_str6021[sizeof("urawa.saitama.jp")];
-    char stringpool_str6022[sizeof("pskov.ru")];
-    char stringpool_str6023[sizeof("k12.ky.us")];
-    char stringpool_str6024[sizeof("sakaki.nagano.jp")];
-    char stringpool_str6025[sizeof("tsuga.tochigi.jp")];
-    char stringpool_str6026[sizeof("cc.nc.us")];
-    char stringpool_str6027[sizeof("federation.aero")];
-    char stringpool_str6028[sizeof("finearts.museum")];
-    char stringpool_str6029[sizeof("from-or.com")];
-    char stringpool_str6030[sizeof("manchester.museum")];
-    char stringpool_str6031[sizeof("stange.no")];
-    char stringpool_str6032[sizeof("tamano.okayama.jp")];
-    char stringpool_str6033[sizeof("forum.hu")];
-    char stringpool_str6034[sizeof("sumita.iwate.jp")];
-    char stringpool_str6035[sizeof("medio-campidano.it")];
-    char stringpool_str6036[sizeof("fukui.jp")];
-    char stringpool_str6037[sizeof("from-ok.com")];
-    char stringpool_str6038[sizeof("media.hu")];
-    char stringpool_str6039[sizeof("s3-sa-east-1.amazonaws.com")];
-    char stringpool_str6040[sizeof("force.museum")];
-    char stringpool_str6041[sizeof("agano.niigata.jp")];
-    char stringpool_str6042[sizeof("uchinomi.kagawa.jp")];
-    char stringpool_str6043[sizeof("from-oh.com")];
-    char stringpool_str6044[sizeof("sakyo.kyoto.jp")];
-    char stringpool_str6045[sizeof("shiraoka.saitama.jp")];
-    char stringpool_str6046[sizeof("military.museum")];
-    char stringpool_str6047[sizeof("munakata.fukuoka.jp")];
-    char stringpool_str6048[sizeof("k12.wy.us")];
-    char stringpool_str6049[sizeof("makinohara.shizuoka.jp")];
-    char stringpool_str6050[sizeof("space.museum")];
-    char stringpool_str6051[sizeof("production.aero")];
-    char stringpool_str6052[sizeof("miyawaka.fukuoka.jp")];
-    char stringpool_str6053[sizeof("shinanomachi.nagano.jp")];
-    char stringpool_str6054[sizeof("sakata.yamagata.jp")];
-    char stringpool_str6055[sizeof("utazu.kagawa.jp")];
-    char stringpool_str6056[sizeof("state.museum")];
-    char stringpool_str6057[sizeof("xn--ryken-vua.no")];
-    char stringpool_str6058[sizeof("takayama.gifu.jp")];
-    char stringpool_str6059[sizeof("tanagura.fukushima.jp")];
-    char stringpool_str6060[sizeof("oguni.yamagata.jp")];
-    char stringpool_str6061[sizeof("niiza.saitama.jp")];
-    char stringpool_str6062[sizeof("inabe.mie.jp")];
-    char stringpool_str6063[sizeof("field.museum")];
-    char stringpool_str6064[sizeof("matsumae.hokkaido.jp")];
-    char stringpool_str6065[sizeof("media.museum")];
-    char stringpool_str6066[sizeof("mytis.ru")];
-    char stringpool_str6067[sizeof("soja.okayama.jp")];
-    char stringpool_str6068[sizeof("stalbans.museum")];
-    char stringpool_str6069[sizeof("xn--nmesjevuemie-tcba.no")];
-    char stringpool_str6070[sizeof("leitungsen.de")];
-    char stringpool_str6071[sizeof("dali.museum")];
-    char stringpool_str6072[sizeof("stadt.museum")];
-    char stringpool_str6073[sizeof("skien.no")];
-    char stringpool_str6074[sizeof("tromso.no")];
-    char stringpool_str6075[sizeof("horonobe.hokkaido.jp")];
-    char stringpool_str6076[sizeof("xn--skjervy-v1a.no")];
-    char stringpool_str6077[sizeof("passenger-association.aero")];
-    char stringpool_str6078[sizeof("ebina.kanagawa.jp")];
-    char stringpool_str6079[sizeof("iron.museum")];
-    char stringpool_str6080[sizeof("sanuki.kagawa.jp")];
-    char stringpool_str6081[sizeof("seika.kyoto.jp")];
-    char stringpool_str6082[sizeof("torino.it")];
-    char stringpool_str6083[sizeof("steam.museum")];
-    char stringpool_str6084[sizeof("kyowa.akita.jp")];
-    char stringpool_str6085[sizeof("morimachi.shizuoka.jp")];
-    char stringpool_str6086[sizeof("tgory.pl")];
-    char stringpool_str6087[sizeof("settlement.museum")];
-    char stringpool_str6088[sizeof("sandoy.no")];
-    char stringpool_str6089[sizeof("corvette.museum")];
-    char stringpool_str6090[sizeof("sannan.hyogo.jp")];
-    char stringpool_str6091[sizeof("sue.fukuoka.jp")];
-    char stringpool_str6092[sizeof("yamagata.gifu.jp")];
-    char stringpool_str6093[sizeof("nagiso.nagano.jp")];
-    char stringpool_str6094[sizeof("works.aero")];
-    char stringpool_str6095[sizeof("hadano.kanagawa.jp")];
-    char stringpool_str6096[sizeof("pesarourbino.it")];
-    char stringpool_str6097[sizeof("pulawy.pl")];
-    char stringpool_str6098[sizeof("seiyo.ehime.jp")];
-    char stringpool_str6099[sizeof("saiki.oita.jp")];
-    char stringpool_str6100[sizeof("xn--fzc2c9e2c")];
-    char stringpool_str6101[sizeof("saikai.nagasaki.jp")];
-    char stringpool_str6102[sizeof("s3-ap-northeast-1.amazonaws.com")];
-    char stringpool_str6103[sizeof("shimoichi.nara.jp")];
-    char stringpool_str6104[sizeof("shikaoi.hokkaido.jp")];
-    char stringpool_str6105[sizeof("cargo.aero")];
-    char stringpool_str6106[sizeof("saito.miyazaki.jp")];
-    char stringpool_str6107[sizeof("kaminokawa.tochigi.jp")];
-    char stringpool_str6108[sizeof("coastaldefence.museum")];
-    char stringpool_str6109[sizeof("trento.it")];
-    char stringpool_str6110[sizeof("asahi.mie.jp")];
-    char stringpool_str6111[sizeof("spy.museum")];
-    char stringpool_str6112[sizeof("oshino.yamanashi.jp")];
-    char stringpool_str6113[sizeof("salem.museum")];
-    char stringpool_str6114[sizeof("paris.museum")];
-    char stringpool_str6115[sizeof("shiraoi.hokkaido.jp")];
-    char stringpool_str6116[sizeof("gs.sf.no")];
-    char stringpool_str6117[sizeof("samnanger.no")];
-    char stringpool_str6118[sizeof("for-better.biz")];
-    char stringpool_str6119[sizeof("milano.it")];
-    char stringpool_str6120[sizeof("moma.museum")];
-    char stringpool_str6121[sizeof("shioya.tochigi.jp")];
-    char stringpool_str6122[sizeof("gs.of.no")];
-    char stringpool_str6123[sizeof("katowice.pl")];
-    char stringpool_str6124[sizeof("fukudomi.saga.jp")];
-    char stringpool_str6125[sizeof("xn--vler-qoa.xn--stfold-9xa.no")];
-    char stringpool_str6126[sizeof("fribourg.museum")];
-    char stringpool_str6127[sizeof("shizukuishi.iwate.jp")];
-    char stringpool_str6128[sizeof("sykkylven.no")];
-    char stringpool_str6129[sizeof("manx.museum")];
-    char stringpool_str6130[sizeof("s3-us-gov-west-1.amazonaws.com")];
-    char stringpool_str6131[sizeof("xn--langevg-jxa.no")];
-    char stringpool_str6132[sizeof("gs.vf.no")];
-    char stringpool_str6133[sizeof("surgeonshall.museum")];
-    char stringpool_str6134[sizeof("from-nc.com")];
-    char stringpool_str6135[sizeof("from-sc.com")];
-    char stringpool_str6136[sizeof("suita.osaka.jp")];
-    char stringpool_str6137[sizeof("isumi.chiba.jp")];
-    char stringpool_str6138[sizeof("manno.kagawa.jp")];
-    char stringpool_str6139[sizeof("hirono.fukushima.jp")];
-    char stringpool_str6140[sizeof("daiwa.hiroshima.jp")];
-    char stringpool_str6141[sizeof("satte.saitama.jp")];
-    char stringpool_str6142[sizeof("ogawa.nagano.jp")];
-    char stringpool_str6143[sizeof("sakai.osaka.jp")];
-    char stringpool_str6144[sizeof("yaotsu.gifu.jp")];
-    char stringpool_str6145[sizeof("steinkjer.no")];
-    char stringpool_str6146[sizeof("xn--porsgu-sta26f.no")];
-    char stringpool_str6147[sizeof("swidnica.pl")];
-    char stringpool_str6148[sizeof("sf.no")];
-    char stringpool_str6149[sizeof("from-dc.com")];
-    char stringpool_str6150[sizeof("skoczow.pl")];
-    char stringpool_str6151[sizeof("po.gov.pl")];
-    char stringpool_str6152[sizeof("arezzo.it")];
-    char stringpool_str6153[sizeof("sakae.nagano.jp")];
-    char stringpool_str6154[sizeof("semine.miyagi.jp")];
-    char stringpool_str6155[sizeof("futaba.fukushima.jp")];
-    char stringpool_str6156[sizeof("kyowa.hokkaido.jp")];
-    char stringpool_str6157[sizeof("knowsitall.info")];
-    char stringpool_str6158[sizeof("fukuroi.shizuoka.jp")];
-    char stringpool_str6159[sizeof("minato.osaka.jp")];
-    char stringpool_str6160[sizeof("mizunami.gifu.jp")];
-    char stringpool_str6161[sizeof("sande.more-og-romsdal.no")];
-    char stringpool_str6162[sizeof("mielno.pl")];
-    char stringpool_str6163[sizeof("scrapper-site.net")];
-    char stringpool_str6164[sizeof("shell.museum")];
-    char stringpool_str6165[sizeof("futsu.nagasaki.jp")];
-    char stringpool_str6166[sizeof("pa.gov.pl")];
-    char stringpool_str6167[sizeof("chippubetsu.hokkaido.jp")];
-    char stringpool_str6168[sizeof("shoo.okayama.jp")];
-    char stringpool_str6169[sizeof("fussa.tokyo.jp")];
-    char stringpool_str6170[sizeof("sango.nara.jp")];
-    char stringpool_str6171[sizeof("cc.wa.us")];
-    char stringpool_str6172[sizeof("frosinone.it")];
-    char stringpool_str6173[sizeof("ino.kochi.jp")];
-    char stringpool_str6174[sizeof("inzai.chiba.jp")];
-    char stringpool_str6175[sizeof("minokamo.gifu.jp")];
-    char stringpool_str6176[sizeof("otaki.chiba.jp")];
-    char stringpool_str6177[sizeof("mill.museum")];
-    char stringpool_str6178[sizeof("fujikawaguchiko.yamanashi.jp")];
-    char stringpool_str6179[sizeof("texas.museum")];
-    char stringpool_str6180[sizeof("muika.niigata.jp")];
-    char stringpool_str6181[sizeof("shiiba.miyazaki.jp")];
-    char stringpool_str6182[sizeof("shari.hokkaido.jp")];
-    char stringpool_str6183[sizeof("mitou.yamaguchi.jp")];
-    char stringpool_str6184[sizeof("simple-url.com")];
-    char stringpool_str6185[sizeof("fuchu.toyama.jp")];
-    char stringpool_str6186[sizeof("fuchu.hiroshima.jp")];
-    char stringpool_str6187[sizeof("k12.mo.us")];
-    char stringpool_str6188[sizeof("mjondalen.no")];
-    char stringpool_str6189[sizeof("town.museum")];
-    char stringpool_str6190[sizeof("storfjord.no")];
-    char stringpool_str6191[sizeof("sabae.fukui.jp")];
-    char stringpool_str6192[sizeof("somna.no")];
-    char stringpool_str6193[sizeof("saijo.ehime.jp")];
-    char stringpool_str6194[sizeof("store.ro")];
-    char stringpool_str6195[sizeof("cc.wi.us")];
-    char stringpool_str6196[sizeof("imabari.ehime.jp")];
-    char stringpool_str6197[sizeof("fujimi.saitama.jp")];
-    char stringpool_str6198[sizeof("yamato.kanagawa.jp")];
-    char stringpool_str6199[sizeof("froya.no")];
-    char stringpool_str6200[sizeof("sogne.no")];
-    char stringpool_str6201[sizeof("frana.no")];
-    char stringpool_str6202[sizeof("soeda.fukuoka.jp")];
-    char stringpool_str6203[sizeof("meguro.tokyo.jp")];
-    char stringpool_str6204[sizeof("shimodate.ibaraki.jp")];
-    char stringpool_str6205[sizeof("graz.museum")];
-    char stringpool_str6206[sizeof("ogawa.saitama.jp")];
-    char stringpool_str6207[sizeof("sosnowiec.pl")];
-    char stringpool_str6208[sizeof("seoul.kr")];
-    char stringpool_str6209[sizeof("wallonie.museum")];
-    char stringpool_str6210[sizeof("histoire.museum")];
-    char stringpool_str6211[sizeof("ballooning.aero")];
-    char stringpool_str6212[sizeof("smola.no")];
-    char stringpool_str6213[sizeof("mbone.pl")];
-    char stringpool_str6214[sizeof("minato.tokyo.jp")];
-    char stringpool_str6215[sizeof("juedisches.museum")];
-    char stringpool_str6216[sizeof("shiga.jp")];
-    char stringpool_str6217[sizeof("agents.aero")];
-    char stringpool_str6218[sizeof("westfalen.museum")];
-    char stringpool_str6219[sizeof("union.aero")];
-    char stringpool_str6220[sizeof("schokoladen.museum")];
-    char stringpool_str6221[sizeof("stord.no")];
-    char stringpool_str6222[sizeof("misato.shimane.jp")];
-    char stringpool_str6223[sizeof("yaizu.shizuoka.jp")];
-    char stringpool_str6224[sizeof("linz.museum")];
-    char stringpool_str6225[sizeof("cc.wy.us")];
-    char stringpool_str6226[sizeof("tempio-olbia.it")];
-    char stringpool_str6227[sizeof("kimino.wakayama.jp")];
-    char stringpool_str6228[sizeof("yamato.fukushima.jp")];
-    char stringpool_str6229[sizeof("endofinternet.net")];
-    char stringpool_str6230[sizeof("siena.it")];
-    char stringpool_str6231[sizeof("gotsu.shimane.jp")];
-    char stringpool_str6232[sizeof("stuff-4-sale.org")];
-    char stringpool_str6233[sizeof("ski.museum")];
-    char stringpool_str6234[sizeof("xn--moreke-jua.no")];
-    char stringpool_str6235[sizeof("asahi.chiba.jp")];
-    char stringpool_str6236[sizeof("skjak.no")];
-    char stringpool_str6237[sizeof("izumo.shimane.jp")];
-    char stringpool_str6238[sizeof("swiebodzin.pl")];
-    char stringpool_str6239[sizeof("xn--node")];
-    char stringpool_str6240[sizeof("mamurogawa.yamagata.jp")];
-    char stringpool_str6241[sizeof("minano.saitama.jp")];
-    char stringpool_str6242[sizeof("moriguchi.osaka.jp")];
-    char stringpool_str6243[sizeof("group.aero")];
-    char stringpool_str6244[sizeof("global.ssl.fastly.net")];
-    char stringpool_str6245[sizeof("floro.no")];
-    char stringpool_str6246[sizeof("sarufutsu.hokkaido.jp")];
-    char stringpool_str6247[sizeof("accident-investigation.aero")];
-    char stringpool_str6248[sizeof("tagajo.miyagi.jp")];
-    char stringpool_str6249[sizeof("flanders.museum")];
-    char stringpool_str6250[sizeof("mizuho.tokyo.jp")];
-    char stringpool_str6251[sizeof("principe.st")];
-    char stringpool_str6252[sizeof("misato.akita.jp")];
-    char stringpool_str6253[sizeof("here-for-more.info")];
-    char stringpool_str6254[sizeof("xn--mosjen-eya.no")];
-    char stringpool_str6255[sizeof("flora.no")];
-    char stringpool_str6256[sizeof("misato.saitama.jp")];
-    char stringpool_str6257[sizeof("shiriuchi.hokkaido.jp")];
-    char stringpool_str6258[sizeof("abiko.chiba.jp")];
-    char stringpool_str6259[sizeof("fuchu.tokyo.jp")];
-    char stringpool_str6260[sizeof("egyptian.museum")];
-    char stringpool_str6261[sizeof("xn--fpcrj9c3d")];
-    char stringpool_str6262[sizeof("k12.fl.us")];
-    char stringpool_str6263[sizeof("freiburg.museum")];
-    char stringpool_str6264[sizeof("s3-website-us-west-2.amazonaws.com")];
-    char stringpool_str6265[sizeof("urbinopesaro.it")];
-    char stringpool_str6266[sizeof("sveio.no")];
-    char stringpool_str6267[sizeof("fukui.fukui.jp")];
-    char stringpool_str6268[sizeof("sakai.fukui.jp")];
-    char stringpool_str6269[sizeof("cc.wv.us")];
-    char stringpool_str6270[sizeof("motosu.gifu.jp")];
-    char stringpool_str6271[sizeof("torino.museum")];
-    char stringpool_str6272[sizeof("sciences.museum")];
-    char stringpool_str6273[sizeof("ogawa.ibaraki.jp")];
-    char stringpool_str6274[sizeof("railroad.museum")];
-    char stringpool_str6275[sizeof("rovigo.it")];
-    char stringpool_str6276[sizeof("music.museum")];
-    char stringpool_str6277[sizeof("sanda.hyogo.jp")];
-    char stringpool_str6278[sizeof("chirurgiens-dentistes.fr")];
-    char stringpool_str6279[sizeof("friulivegiulia.it")];
-    char stringpool_str6280[sizeof("california.museum")];
-    char stringpool_str6281[sizeof("jfk.museum")];
-    char stringpool_str6282[sizeof("is-a-green.com")];
-    char stringpool_str6283[sizeof("xn--ostery-fya.no")];
-    char stringpool_str6284[sizeof("nagato.yamaguchi.jp")];
-    char stringpool_str6285[sizeof("s3-ap-southeast-1.amazonaws.com")];
-    char stringpool_str6286[sizeof("fudai.iwate.jp")];
-    char stringpool_str6287[sizeof("s3-us-west-2.amazonaws.com")];
-    char stringpool_str6288[sizeof("seihi.nagasaki.jp")];
-    char stringpool_str6289[sizeof("store.st")];
-    char stringpool_str6290[sizeof("shop.ht")];
-    char stringpool_str6291[sizeof("schweiz.museum")];
-    char stringpool_str6292[sizeof("urbino-pesaro.it")];
-    char stringpool_str6293[sizeof("sagae.yamagata.jp")];
-    char stringpool_str6294[sizeof("environment.museum")];
-    char stringpool_str6295[sizeof("wildlife.museum")];
-    char stringpool_str6296[sizeof("shiki.saitama.jp")];
-    char stringpool_str6297[sizeof("ofunato.iwate.jp")];
-    char stringpool_str6298[sizeof("sciencecenter.museum")];
-    char stringpool_str6299[sizeof("lebtimnetz.de")];
-    char stringpool_str6300[sizeof("sciencecenters.museum")];
-    char stringpool_str6301[sizeof("so.gov.pl")];
-    char stringpool_str6302[sizeof("nakatombetsu.hokkaido.jp")];
-    char stringpool_str6303[sizeof("topology.museum")];
-    char stringpool_str6304[sizeof("sakai.ibaraki.jp")];
-    char stringpool_str6305[sizeof("monza.it")];
-    char stringpool_str6306[sizeof("xn--mgbqly7c0a67fbc")];
-    char stringpool_str6307[sizeof("sport.hu")];
-    char stringpool_str6308[sizeof("sr.gov.pl")];
-    char stringpool_str6309[sizeof("countryestate.museum")];
-    char stringpool_str6310[sizeof("rokunohe.aomori.jp")];
-    char stringpool_str6311[sizeof("s3-website-ap-southeast-2.amazonaws.com")];
-    char stringpool_str6312[sizeof("grozny.ru")];
-    char stringpool_str6313[sizeof("tochio.niigata.jp")];
-    char stringpool_str6314[sizeof("yokkaichi.mie.jp")];
-    char stringpool_str6315[sizeof("frogn.no")];
-    char stringpool_str6316[sizeof("k12.co.us")];
-    char stringpool_str6317[sizeof("hamatonbetsu.hokkaido.jp")];
-    char stringpool_str6318[sizeof("heritage.museum")];
-    char stringpool_str6319[sizeof("surrey.museum")];
-    char stringpool_str6320[sizeof("miura.kanagawa.jp")];
-    char stringpool_str6321[sizeof("valer.ostfold.no")];
-    char stringpool_str6322[sizeof("skole.museum")];
-    char stringpool_str6323[sizeof("suifu.ibaraki.jp")];
-    char stringpool_str6324[sizeof("store.bb")];
-    char stringpool_str6325[sizeof("tempioolbia.it")];
-    char stringpool_str6326[sizeof("farm.museum")];
-    char stringpool_str6327[sizeof("sanjo.niigata.jp")];
-    char stringpool_str6328[sizeof("mitake.gifu.jp")];
-    char stringpool_str6329[sizeof("satx.museum")];
-    char stringpool_str6330[sizeof("miyako.iwate.jp")];
-    char stringpool_str6331[sizeof("finnoy.no")];
-    char stringpool_str6332[sizeof("brand.se")];
-    char stringpool_str6333[sizeof("supply")];
-    char stringpool_str6334[sizeof("shikokuchuo.ehime.jp")];
-    char stringpool_str6335[sizeof("slupsk.pl")];
-    char stringpool_str6336[sizeof("unnan.shimane.jp")];
-    char stringpool_str6337[sizeof("yosemite.museum")];
-    char stringpool_str6338[sizeof("shintomi.miyazaki.jp")];
-    char stringpool_str6339[sizeof("tomika.gifu.jp")];
-    char stringpool_str6340[sizeof("cc.pa.us")];
-    char stringpool_str6341[sizeof("valer.hedmark.no")];
-    char stringpool_str6342[sizeof("masaki.ehime.jp")];
-    char stringpool_str6343[sizeof("seiro.niigata.jp")];
-    char stringpool_str6344[sizeof("cc.pr.us")];
-    char stringpool_str6345[sizeof("yahiko.niigata.jp")];
-    char stringpool_str6346[sizeof("research.museum")];
-    char stringpool_str6347[sizeof("plc.co.im")];
-    char stringpool_str6348[sizeof("muroto.kochi.jp")];
-    char stringpool_str6349[sizeof("film.museum")];
-    char stringpool_str6350[sizeof("myoko.niigata.jp")];
-    char stringpool_str6351[sizeof("fujinomiya.shizuoka.jp")];
-    char stringpool_str6352[sizeof("shiso.hyogo.jp")];
-    char stringpool_str6353[sizeof("aizubange.fukushima.jp")];
-    char stringpool_str6354[sizeof("marugame.kagawa.jp")];
-    char stringpool_str6355[sizeof("fujimi.nagano.jp")];
-    char stringpool_str6356[sizeof("saves-the-whales.com")];
-    char stringpool_str6357[sizeof("endoftheinternet.org")];
-    char stringpool_str6358[sizeof("sa.gov.au")];
-    char stringpool_str6359[sizeof("ap-southeast-1.compute.amazonaws.com")];
-    char stringpool_str6360[sizeof("silk.museum")];
-    char stringpool_str6361[sizeof("muenchen.museum")];
-    char stringpool_str6362[sizeof("sasaguri.fukuoka.jp")];
-    char stringpool_str6363[sizeof("akagi.shimane.jp")];
-    char stringpool_str6364[sizeof("furano.hokkaido.jp")];
-    char stringpool_str6365[sizeof("xn--tnsberg-q1a.no")];
-    char stringpool_str6366[sizeof("selfip.info")];
-    char stringpool_str6367[sizeof("design.aero")];
-    char stringpool_str6368[sizeof("delaware.museum")];
-    char stringpool_str6369[sizeof("sejny.pl")];
-    char stringpool_str6370[sizeof("furniture.museum")];
-    char stringpool_str6371[sizeof("selfip.net")];
-    char stringpool_str6372[sizeof("taiwa.miyagi.jp")];
-    char stringpool_str6373[sizeof("xn--stre-toten-zcb.no")];
-    char stringpool_str6374[sizeof("reggiocalabria.it")];
-    char stringpool_str6375[sizeof("shika.ishikawa.jp")];
-    char stringpool_str6376[sizeof("penza.ru")];
-    char stringpool_str6377[sizeof("sicily.it")];
-    char stringpool_str6378[sizeof("shop.hu")];
-    char stringpool_str6379[sizeof("shintoku.hokkaido.jp")];
-    char stringpool_str6380[sizeof("fukushima.fukushima.jp")];
-    char stringpool_str6381[sizeof("taiki.mie.jp")];
-    char stringpool_str6382[sizeof("francaise.museum")];
-    char stringpool_str6383[sizeof("yamanobe.yamagata.jp")];
-    char stringpool_str6384[sizeof("endofinternet.org")];
-    char stringpool_str6385[sizeof("shirakawa.fukushima.jp")];
-    char stringpool_str6386[sizeof("sakado.saitama.jp")];
-    char stringpool_str6387[sizeof("meiwa.gunma.jp")];
-    char stringpool_str6388[sizeof("niihama.ehime.jp")];
-    char stringpool_str6389[sizeof("database.museum")];
-    char stringpool_str6390[sizeof("skiptvet.no")];
-    char stringpool_str6391[sizeof("reggio-emilia.it")];
-    char stringpool_str6392[sizeof("scotland.museum")];
-    char stringpool_str6393[sizeof("takino.hyogo.jp")];
-    char stringpool_str6394[sizeof("store.nf")];
-    char stringpool_str6395[sizeof("shingu.hyogo.jp")];
-    char stringpool_str6396[sizeof("misato.miyagi.jp")];
-    char stringpool_str6397[sizeof("masfjorden.no")];
-    char stringpool_str6398[sizeof("susono.shizuoka.jp")];
-    char stringpool_str6399[sizeof("barrell-of-knowledge.info")];
-    char stringpool_str6400[sizeof("office-on-the.net")];
-    char stringpool_str6401[sizeof("friulive-giulia.it")];
-    char stringpool_str6402[sizeof("friuli-vegiulia.it")];
-    char stringpool_str6403[sizeof("dyndns-remote.com")];
-    char stringpool_str6404[sizeof("xn--indery-fya.no")];
-    char stringpool_str6405[sizeof("shizuoka.jp")];
-    char stringpool_str6406[sizeof("sumoto.kumamoto.jp")];
-    char stringpool_str6407[sizeof("plaza.museum")];
-    char stringpool_str6408[sizeof("museumvereniging.museum")];
-    char stringpool_str6409[sizeof("mansions.museum")];
-    char stringpool_str6410[sizeof("samegawa.fukushima.jp")];
-    char stringpool_str6411[sizeof("ichinohe.iwate.jp")];
-    char stringpool_str6412[sizeof("shonai.yamagata.jp")];
-    char stringpool_str6413[sizeof("misato.wakayama.jp")];
-    char stringpool_str6414[sizeof("family.museum")];
-    char stringpool_str6415[sizeof("uwajima.ehime.jp")];
-    char stringpool_str6416[sizeof("shunan.yamaguchi.jp")];
-    char stringpool_str6417[sizeof("udono.mie.jp")];
-    char stringpool_str6418[sizeof("press.aero")];
-    char stringpool_str6419[sizeof("elasticbeanstalk.com")];
-    char stringpool_str6420[sizeof("fujiyoshida.yamanashi.jp")];
-    char stringpool_str6421[sizeof("tajimi.gifu.jp")];
-    char stringpool_str6422[sizeof("friuli-veneziagiulia.it")];
-    char stringpool_str6423[sizeof("mitoyo.kagawa.jp")];
-    char stringpool_str6424[sizeof("shingu.wakayama.jp")];
-    char stringpool_str6425[sizeof("sukagawa.fukushima.jp")];
-    char stringpool_str6426[sizeof("sydney.museum")];
-    char stringpool_str6427[sizeof("forgot.her.name")];
-    char stringpool_str6428[sizeof("satsumasendai.kagoshima.jp")];
-    char stringpool_str6429[sizeof("sumoto.hyogo.jp")];
-    char stringpool_str6430[sizeof("miyako.fukuoka.jp")];
-    char stringpool_str6431[sizeof("friuliveneziagiulia.it")];
-    char stringpool_str6432[sizeof("mallorca.museum")];
-    char stringpool_str6433[sizeof("matsuno.ehime.jp")];
-    char stringpool_str6434[sizeof("shonai.fukuoka.jp")];
-    char stringpool_str6435[sizeof("friuli-venezia-giulia.it")];
-    char stringpool_str6436[sizeof("ap-northeast-1.compute.amazonaws.com")];
-    char stringpool_str6437[sizeof("pilot.aero")];
-    char stringpool_str6438[sizeof("friulivenezia-giulia.it")];
-    char stringpool_str6439[sizeof("salzburg.museum")];
-    char stringpool_str6440[sizeof("xn--frde-gra.no")];
-    char stringpool_str6441[sizeof("sugito.saitama.jp")];
-    char stringpool_str6442[sizeof("friuli-ve-giulia.it")];
-    char stringpool_str6443[sizeof("shingu.fukuoka.jp")];
-    char stringpool_str6444[sizeof("sukumo.kochi.jp")];
-    char stringpool_str6445[sizeof("shimonoseki.yamaguchi.jp")];
-    char stringpool_str6446[sizeof("shizuoka.shizuoka.jp")];
-    char stringpool_str6447[sizeof("pippu.hokkaido.jp")];
-    char stringpool_str6448[sizeof("flight.aero")];
-    char stringpool_str6449[sizeof("minamiise.mie.jp")];
-    char stringpool_str6450[sizeof("press.se")];
-    char stringpool_str6451[sizeof("traeumtgerade.de")];
-    char stringpool_str6452[sizeof("frog.museum")];
-    char stringpool_str6453[sizeof("xn--clchc0ea0b2g2a9gcd")];
-    char stringpool_str6454[sizeof("xn--comunicaes-v6a2o.museum")];
-    char stringpool_str6455[sizeof("shinjo.nara.jp")];
-    char stringpool_str6456[sizeof("us-gov-west-1.compute.amazonaws.com")];
-    char stringpool_str6457[sizeof("shinonsen.hyogo.jp")];
-    char stringpool_str6458[sizeof("parti.se")];
-    char stringpool_str6459[sizeof("properties")];
-    char stringpool_str6460[sizeof("sakuho.nagano.jp")];
-    char stringpool_str6461[sizeof("s3-website-us-east-1.amazonaws.com")];
-    char stringpool_str6462[sizeof("s3-website-sa-east-1.amazonaws.com")];
-    char stringpool_str6463[sizeof("for-some.biz")];
-    char stringpool_str6464[sizeof("media.aero")];
-    char stringpool_str6465[sizeof("monzaedellabrianza.it")];
-    char stringpool_str6466[sizeof("environmentalconservation.museum")];
-    char stringpool_str6467[sizeof("s3-fips-us-gov-west-1.amazonaws.com")];
-    char stringpool_str6468[sizeof("sasebo.nagasaki.jp")];
-    char stringpool_str6469[sizeof("for-more.biz")];
-    char stringpool_str6470[sizeof("svizzera.museum")];
-    char stringpool_str6471[sizeof("pharmaciens.km")];
-    char stringpool_str6472[sizeof("bellevue.museum")];
-    char stringpool_str6473[sizeof("mulhouse.museum")];
-    char stringpool_str6474[sizeof("pharmacy.museum")];
-    char stringpool_str6475[sizeof("shinjo.okayama.jp")];
-    char stringpool_str6476[sizeof("s3-website-us-west-1.amazonaws.com")];
-    char stringpool_str6477[sizeof("forli-cesena.it")];
-    char stringpool_str6478[sizeof("sekigahara.gifu.jp")];
-    char stringpool_str6479[sizeof("s3-us-west-1.amazonaws.com")];
-    char stringpool_str6480[sizeof("ichinoseki.iwate.jp")];
-    char stringpool_str6481[sizeof("maritime.museum")];
-    char stringpool_str6482[sizeof("s3-website-ap-southeast-1.amazonaws.com")];
-    char stringpool_str6483[sizeof("s3-eu-west-1.amazonaws.com")];
-    char stringpool_str6484[sizeof("isteingeek.de")];
-    char stringpool_str6485[sizeof("shinto.gunma.jp")];
-    char stringpool_str6486[sizeof("shima.mie.jp")];
-    char stringpool_str6487[sizeof("stateofdelaware.museum")];
-    char stringpool_str6488[sizeof("s3-website-eu-west-1.amazonaws.com")];
-    char stringpool_str6489[sizeof("s3-website-ap-northeast-1.amazonaws.com")];
-    char stringpool_str6490[sizeof("takinoue.hokkaido.jp")];
-    char stringpool_str6491[sizeof("museumcenter.museum")];
-    char stringpool_str6492[sizeof("shiwa.iwate.jp")];
-    char stringpool_str6493[sizeof("showa.gunma.jp")];
-    char stringpool_str6494[sizeof("sakae.chiba.jp")];
-    char stringpool_str6495[sizeof("sellsyourhome.org")];
-    char stringpool_str6496[sizeof("furudono.fukushima.jp")];
-    char stringpool_str6497[sizeof("showa.yamanashi.jp")];
-    char stringpool_str6498[sizeof("dyndns-office.com")];
-    char stringpool_str6499[sizeof("shingo.aomori.jp")];
-    char stringpool_str6500[sizeof("saskatchewan.museum")];
-    char stringpool_str6501[sizeof("buyshouses.net")];
-    char stringpool_str6502[sizeof("showa.fukushima.jp")];
-    char stringpool_str6503[sizeof("safety.aero")];
-    char stringpool_str6504[sizeof("florence.it")];
-    char stringpool_str6505[sizeof("shinjo.yamagata.jp")];
-    char stringpool_str6506[sizeof("pacific.museum")];
-    char stringpool_str6507[sizeof("dnepropetrovsk.ua")];
-    char stringpool_str6508[sizeof("uchiko.ehime.jp")];
-    char stringpool_str6509[sizeof("sanagochi.tokushima.jp")];
-    char stringpool_str6510[sizeof("meiwa.mie.jp")];
-    char stringpool_str6511[sizeof("sakahogi.gifu.jp")];
-    char stringpool_str6512[sizeof("dnipropetrovsk.ua")];
-    char stringpool_str6513[sizeof("isa-hockeynut.com")];
-    char stringpool_str6514[sizeof("s3-website-us-gov-west-1.amazonaws.com")];
-    char stringpool_str6515[sizeof("xn--rhkkervju-01af.no")];
-    char stringpool_str6516[sizeof("geometre-expert.fr")];
-    char stringpool_str6517[sizeof("shinyoshitomi.fukuoka.jp")];
-    char stringpool_str6518[sizeof("xn--correios-e-telecomunicaes-ghc29a.museum")];
-    char stringpool_str6519[sizeof("sande.xn--mre-og-romsdal-qqb.no")];
-    char stringpool_str6520[sizeof("pharmacien.fr")];
-    char stringpool_str6521[sizeof("sande.vestfold.no")];
+    char stringpool_str133[sizeof("gov.sb")];
+    char stringpool_str134[sizeof("gov.rw")];
+    char stringpool_str135[sizeof("net.tn")];
+    char stringpool_str136[sizeof("gov.as")];
+    char stringpool_str137[sizeof("za")];
+    char stringpool_str138[sizeof("er")];
+    char stringpool_str139[sizeof("cu")];
+    char stringpool_str140[sizeof("com.tn")];
+    char stringpool_str141[sizeof("gu")];
+    char stringpool_str142[sizeof("gov.tn")];
+    char stringpool_str143[sizeof("nu")];
+    char stringpool_str144[sizeof("guru")];
+    char stringpool_str145[sizeof("cz")];
+    char stringpool_str146[sizeof("bz")];
+    char stringpool_str147[sizeof("kz")];
+    char stringpool_str148[sizeof("ae")];
+    char stringpool_str149[sizeof("as")];
+    char stringpool_str150[sizeof("nz")];
+    char stringpool_str151[sizeof("ad")];
+    char stringpool_str152[sizeof("edu.al")];
+    char stringpool_str153[sizeof("ao")];
+    char stringpool_str154[sizeof("com.ee")];
+    char stringpool_str155[sizeof("edu.ar")];
+    char stringpool_str156[sizeof("edu.ac")];
+    char stringpool_str157[sizeof("gov.ee")];
+    char stringpool_str158[sizeof("com.de")];
+    char stringpool_str159[sizeof("zone")];
+    char stringpool_str160[sizeof("gov.rs")];
+    char stringpool_str161[sizeof("eu")];
+    char stringpool_str162[sizeof("cpa.pro")];
+    char stringpool_str163[sizeof("edu.tt")];
+    char stringpool_str164[sizeof("net.pe")];
+    char stringpool_str165[sizeof("edu.sd")];
+    char stringpool_str166[sizeof("edu.tw")];
+    char stringpool_str167[sizeof("com.pe")];
+    char stringpool_str168[sizeof("bj")];
+    char stringpool_str169[sizeof("aero")];
+    char stringpool_str170[sizeof("nom.pe")];
+    char stringpool_str171[sizeof("edu.an")];
+    char stringpool_str172[sizeof("jet.uk")];
+    char stringpool_str173[sizeof("name")];
+    char stringpool_str174[sizeof("nsn.us")];
+    char stringpool_str175[sizeof("edu.sb")];
+    char stringpool_str176[sizeof("edu.rw")];
+    char stringpool_str177[sizeof("career")];
+    char stringpool_str178[sizeof("cm")];
+    char stringpool_str179[sizeof("bm")];
+    char stringpool_str180[sizeof("km")];
+    char stringpool_str181[sizeof("gm")];
+    char stringpool_str182[sizeof("im")];
+    char stringpool_str183[sizeof("gob.pe")];
+    char stringpool_str184[sizeof("isa.us")];
+    char stringpool_str185[sizeof("nom.ad")];
+    char stringpool_str186[sizeof("net.ml")];
+    char stringpool_str187[sizeof("net.mk")];
+    char stringpool_str188[sizeof("net.mt")];
+    char stringpool_str189[sizeof("net.mw")];
+    char stringpool_str190[sizeof("com.ml")];
+    char stringpool_str191[sizeof("com.mk")];
+    char stringpool_str192[sizeof("com.mt")];
+    char stringpool_str193[sizeof("gov.ml")];
+    char stringpool_str194[sizeof("gov.mk")];
+    char stringpool_str195[sizeof("com.mw")];
+    char stringpool_str196[sizeof("c.la")];
+    char stringpool_str197[sizeof("gov.mr")];
+    char stringpool_str198[sizeof("edu.ee")];
+    char stringpool_str199[sizeof("gov.mw")];
+    char stringpool_str200[sizeof("nat.tn")];
+    char stringpool_str201[sizeof("edu.rs")];
+    char stringpool_str202[sizeof("bar.pro")];
+    char stringpool_str203[sizeof("krd")];
+    char stringpool_str204[sizeof("jm")];
+    char stringpool_str205[sizeof("codes")];
+    char stringpool_str206[sizeof("edu.pe")];
+    char stringpool_str207[sizeof("gal")];
+    char stringpool_str208[sizeof("net.ae")];
+    char stringpool_str209[sizeof("gov.mn")];
+    char stringpool_str210[sizeof("net.ms")];
+    char stringpool_str211[sizeof("gallery")];
+    char stringpool_str212[sizeof("at")];
+    char stringpool_str213[sizeof("gov.ae")];
+    char stringpool_str214[sizeof("com.ms")];
+    char stringpool_str215[sizeof("gov.ms")];
+    char stringpool_str216[sizeof("zm")];
+    char stringpool_str217[sizeof("ci")];
+    char stringpool_str218[sizeof("bi")];
+    char stringpool_str219[sizeof("ki")];
+    char stringpool_str220[sizeof("gi")];
+    char stringpool_str221[sizeof("net.tj")];
+    char stringpool_str222[sizeof("kim")];
+    char stringpool_str223[sizeof("ar")];
+    char stringpool_str224[sizeof("ni")];
+    char stringpool_str225[sizeof("com.tj")];
+    char stringpool_str226[sizeof("gov.tj")];
+    char stringpool_str227[sizeof("edu.ml")];
+    char stringpool_str228[sizeof("edu.mk")];
+    char stringpool_str229[sizeof("edu.mt")];
+    char stringpool_str230[sizeof("atm.pl")];
+    char stringpool_str231[sizeof("edu.mw")];
+    char stringpool_str232[sizeof("com.re")];
+    char stringpool_str233[sizeof("name.na")];
+    char stringpool_str234[sizeof("net.ir")];
+    char stringpool_str235[sizeof("nom.re")];
+    char stringpool_str236[sizeof("gov.it")];
+    char stringpool_str237[sizeof("gov.ir")];
+    char stringpool_str238[sizeof("komforb.se")];
+    char stringpool_str239[sizeof("art.pl")];
+    char stringpool_str240[sizeof("au")];
+    char stringpool_str241[sizeof("bb")];
+    char stringpool_str242[sizeof("gb")];
+    char stringpool_str243[sizeof("gen.in")];
+    char stringpool_str244[sizeof("berlin")];
+    char stringpool_str245[sizeof("kaufen")];
+    char stringpool_str246[sizeof("edu.mn")];
+    char stringpool_str247[sizeof("estate")];
+    char stringpool_str248[sizeof("az")];
+    char stringpool_str249[sizeof("net.in")];
+    char stringpool_str250[sizeof("art.sn")];
+    char stringpool_str251[sizeof("nel.uk")];
+    char stringpool_str252[sizeof("edu.ms")];
+    char stringpool_str253[sizeof("gov.in")];
+    char stringpool_str254[sizeof("net.bt")];
+    char stringpool_str255[sizeof("net.is")];
+    char stringpool_str256[sizeof("net.br")];
+    char stringpool_str257[sizeof("arpa")];
+    char stringpool_str258[sizeof("com.bt")];
+    char stringpool_str259[sizeof("com.is")];
+    char stringpool_str260[sizeof("gov.bt")];
+    char stringpool_str261[sizeof("com.br")];
+    char stringpool_str262[sizeof("gov.is")];
+    char stringpool_str263[sizeof("nara.jp")];
+    char stringpool_str264[sizeof("gov.br")];
+    char stringpool_str265[sizeof("de")];
+    char stringpool_str266[sizeof("ceo")];
+    char stringpool_str267[sizeof("nom.br")];
+    char stringpool_str268[sizeof("not.br")];
+    char stringpool_str269[sizeof("jur.pro")];
+    char stringpool_str270[sizeof("edu.tj")];
+    char stringpool_str271[sizeof("do")];
+    char stringpool_str272[sizeof("boo")];
+    char stringpool_str273[sizeof("autos")];
+    char stringpool_str274[sizeof("cool")];
+    char stringpool_str275[sizeof("bayern")];
+    char stringpool_str276[sizeof("edu.it")];
+    char stringpool_str277[sizeof("net.dm")];
+    char stringpool_str278[sizeof("kobe.jp")];
+    char stringpool_str279[sizeof("net.je")];
+    char stringpool_str280[sizeof("com.dm")];
+    char stringpool_str281[sizeof("net.om")];
+    char stringpool_str282[sizeof("net.bs")];
+    char stringpool_str283[sizeof("gov.dm")];
+    char stringpool_str284[sizeof("am")];
+    char stringpool_str285[sizeof("com.om")];
+    char stringpool_str286[sizeof("com.bs")];
+    char stringpool_str287[sizeof("consulado.st")];
+    char stringpool_str288[sizeof("gov.om")];
+    char stringpool_str289[sizeof("gov.bs")];
+    char stringpool_str290[sizeof("bodo.no")];
+    char stringpool_str291[sizeof("jor.br")];
+    char stringpool_str292[sizeof("cam.it")];
+    char stringpool_str293[sizeof("net.me")];
+    char stringpool_str294[sizeof("cn")];
+    char stringpool_str295[sizeof("bn")];
+    char stringpool_str296[sizeof("kn")];
+    char stringpool_str297[sizeof("gn")];
+    char stringpool_str298[sizeof("in")];
+    char stringpool_str299[sizeof("gov.me")];
+    char stringpool_str300[sizeof("esp.br")];
+    char stringpool_str301[sizeof("edu.in")];
+    char stringpool_str302[sizeof("int")];
+    char stringpool_str303[sizeof("gives")];
+    char stringpool_str304[sizeof("edu.bt")];
+    char stringpool_str305[sizeof("edu.is")];
+    char stringpool_str306[sizeof("edu.br")];
+    char stringpool_str307[sizeof("net.id")];
+    char stringpool_str308[sizeof("net.nr")];
+    char stringpool_str309[sizeof("isla.pr")];
+    char stringpool_str310[sizeof("bid")];
+    char stringpool_str311[sizeof("com.nr")];
+    char stringpool_str312[sizeof("gov.nr")];
+    char stringpool_str313[sizeof("name.pr")];
+    char stringpool_str314[sizeof("int.pt")];
+    char stringpool_str315[sizeof("game.tw")];
+    char stringpool_str316[sizeof("auto.pl")];
+    char stringpool_str317[sizeof("gift")];
+    char stringpool_str318[sizeof("edu.dm")];
+    char stringpool_str319[sizeof("gq")];
+    char stringpool_str320[sizeof("iq")];
+    char stringpool_str321[sizeof("coffee")];
+    char stringpool_str322[sizeof("edu.om")];
+    char stringpool_str323[sizeof("edu.bs")];
+    char stringpool_str324[sizeof("ntr.br")];
+    char stringpool_str325[sizeof("day")];
+    char stringpool_str326[sizeof("ai")];
+    char stringpool_str327[sizeof("edu.me")];
+    char stringpool_str328[sizeof("ip6.arpa")];
+    char stringpool_str329[sizeof("net.sa")];
+    char stringpool_str330[sizeof("brussels")];
+    char stringpool_str331[sizeof("etne.no")];
+    char stringpool_str332[sizeof("com.sa")];
+    char stringpool_str333[sizeof("net.bb")];
+    char stringpool_str334[sizeof("gov.sa")];
+    char stringpool_str335[sizeof("gov.ie")];
+    char stringpool_str336[sizeof("com.bb")];
+    char stringpool_str337[sizeof("gov.bb")];
+    char stringpool_str338[sizeof("net.tm")];
+    char stringpool_str339[sizeof("net.pa")];
+    char stringpool_str340[sizeof("com.tm")];
+    char stringpool_str341[sizeof("edu.nr")];
+    char stringpool_str342[sizeof("gov.tm")];
+    char stringpool_str343[sizeof("com.pa")];
+    char stringpool_str344[sizeof("nom.tm")];
+    char stringpool_str345[sizeof("name.tj")];
+    char stringpool_str346[sizeof("nom.pa")];
+    char stringpool_str347[sizeof("arts.ro")];
+    char stringpool_str348[sizeof("arts.co")];
+    char stringpool_str349[sizeof("grue.no")];
+    char stringpool_str350[sizeof("cl")];
+    char stringpool_str351[sizeof("gl")];
+    char stringpool_str352[sizeof("il")];
+    char stringpool_str353[sizeof("nl")];
+    char stringpool_str354[sizeof("name.ng")];
+    char stringpool_str355[sizeof("cremona.it")];
+    char stringpool_str356[sizeof("gob.pa")];
+    char stringpool_str357[sizeof("int.ar")];
+    char stringpool_str358[sizeof("adm.br")];
+    char stringpool_str359[sizeof("adv.br")];
+    char stringpool_str360[sizeof("net.lk")];
+    char stringpool_str361[sizeof("cv")];
+    char stringpool_str362[sizeof("bv")];
+    char stringpool_str363[sizeof("net.lr")];
+    char stringpool_str364[sizeof("net.lc")];
+    char stringpool_str365[sizeof("com.lk")];
+    char stringpool_str366[sizeof("dz")];
+    char stringpool_str367[sizeof("int.tt")];
+    char stringpool_str368[sizeof("gov.lk")];
+    char stringpool_str369[sizeof("gov.lt")];
+    char stringpool_str370[sizeof("com.lr")];
+    char stringpool_str371[sizeof("com.lc")];
+    char stringpool_str372[sizeof("gov.lr")];
+    char stringpool_str373[sizeof("gov.lc")];
+    char stringpool_str374[sizeof("glass")];
+    char stringpool_str375[sizeof("country")];
+    char stringpool_str376[sizeof("norddal.no")];
+    char stringpool_str377[sizeof("edu.sa")];
+    char stringpool_str378[sizeof("arna.no")];
+    char stringpool_str379[sizeof("net.vc")];
+    char stringpool_str380[sizeof("edu.bb")];
+    char stringpool_str381[sizeof("com.vc")];
+    char stringpool_str382[sizeof("int.rw")];
+    char stringpool_str383[sizeof("gov.vc")];
+    char stringpool_str384[sizeof("info")];
+    char stringpool_str385[sizeof("edu.tm")];
+    char stringpool_str386[sizeof("emr.it")];
+    char stringpool_str387[sizeof("edu.pa")];
+    char stringpool_str388[sizeof("caa.aero")];
+    char stringpool_str389[sizeof("dj")];
+    char stringpool_str390[sizeof("com.pf")];
+    char stringpool_str391[sizeof("cal.it")];
+    char stringpool_str392[sizeof("ing")];
+    char stringpool_str393[sizeof("net.vn")];
+    char stringpool_str394[sizeof("an")];
+    char stringpool_str395[sizeof("name.jo")];
+    char stringpool_str396[sizeof("com.vn")];
+    char stringpool_str397[sizeof("gov.vn")];
+    char stringpool_str398[sizeof("dm")];
+    char stringpool_str399[sizeof("dad")];
+    char stringpool_str400[sizeof("imb.br")];
+    char stringpool_str401[sizeof("dance")];
+    char stringpool_str402[sizeof("edu.lk")];
+    char stringpool_str403[sizeof("edu.lr")];
+    char stringpool_str404[sizeof("edu.lc")];
+    char stringpool_str405[sizeof("c.bg")];
+    char stringpool_str406[sizeof("b.bg")];
+    char stringpool_str407[sizeof("k.bg")];
+    char stringpool_str408[sizeof("g.bg")];
+    char stringpool_str409[sizeof("0.bg")];
+    char stringpool_str410[sizeof("6.bg")];
+    char stringpool_str411[sizeof("2.bg")];
+    char stringpool_str412[sizeof("i.bg")];
+    char stringpool_str413[sizeof("9.bg")];
+    char stringpool_str414[sizeof("n.bg")];
+    char stringpool_str415[sizeof("8.bg")];
+    char stringpool_str416[sizeof("7.bg")];
+    char stringpool_str417[sizeof("5.bg")];
+    char stringpool_str418[sizeof("4.bg")];
+    char stringpool_str419[sizeof("3.bg")];
+    char stringpool_str420[sizeof("dabur")];
+    char stringpool_str421[sizeof("1.bg")];
+    char stringpool_str422[sizeof("irc.pl")];
+    char stringpool_str423[sizeof("edu.vc")];
+    char stringpool_str424[sizeof("info.la")];
+    char stringpool_str425[sizeof("aid.pl")];
+    char stringpool_str426[sizeof("aq")];
+    char stringpool_str427[sizeof("info.pl")];
+    char stringpool_str428[sizeof("emp.br")];
+    char stringpool_str429[sizeof("net.ua")];
+    char stringpool_str430[sizeof("edu.pf")];
+    char stringpool_str431[sizeof("name.my")];
+    char stringpool_str432[sizeof("e.bg")];
+    char stringpool_str433[sizeof("com.ua")];
+    char stringpool_str434[sizeof("net.af")];
+    char stringpool_str435[sizeof("gov.ua")];
+    char stringpool_str436[sizeof("cim.br")];
+    char stringpool_str437[sizeof("edu.vn")];
+    char stringpool_str438[sizeof("com.af")];
+    char stringpool_str439[sizeof("name.eg")];
+    char stringpool_str440[sizeof("j.bg")];
+    char stringpool_str441[sizeof("int.mw")];
+    char stringpool_str442[sizeof("gov.af")];
+    char stringpool_str443[sizeof("gifu.jp")];
+    char stringpool_str444[sizeof("art.br")];
+    char stringpool_str445[sizeof("info.na")];
+    char stringpool_str446[sizeof("net.lb")];
+    char stringpool_str447[sizeof("bio")];
+    char stringpool_str448[sizeof("gausdal.no")];
+    char stringpool_str449[sizeof("com.lb")];
+    char stringpool_str450[sizeof("gov.lb")];
+    char stringpool_str451[sizeof("blue")];
+    char stringpool_str452[sizeof("x.bg")];
+    char stringpool_str453[sizeof("aip.ee")];
+    char stringpool_str454[sizeof("z.bg")];
+    char stringpool_str455[sizeof("aure.no")];
+    char stringpool_str456[sizeof("net.im")];
+    char stringpool_str457[sizeof("com.im")];
+    char stringpool_str458[sizeof("grp.lk")];
+    char stringpool_str459[sizeof("al")];
+    char stringpool_str460[sizeof("ind.tn")];
+    char stringpool_str461[sizeof("net.ma")];
+    char stringpool_str462[sizeof("arts.nf")];
+    char stringpool_str463[sizeof("bmd.br")];
+    char stringpool_str464[sizeof("bzh")];
+    char stringpool_str465[sizeof("gov.ma")];
+    char stringpool_str466[sizeof("int.tj")];
+    char stringpool_str467[sizeof("edu.ua")];
+    char stringpool_str468[sizeof("net.ve")];
+    char stringpool_str469[sizeof("jolster.no")];
+    char stringpool_str470[sizeof("educator.aero")];
+    char stringpool_str471[sizeof("edu.af")];
+    char stringpool_str472[sizeof("net.bm")];
+    char stringpool_str473[sizeof("com.ve")];
+    char stringpool_str474[sizeof("gov.ve")];
+    char stringpool_str475[sizeof("com.bm")];
+    char stringpool_str476[sizeof("gov.bm")];
+    char stringpool_str477[sizeof("edu.lb")];
+    char stringpool_str478[sizeof("gran.no")];
+    char stringpool_str479[sizeof("gjesdal.no")];
+    char stringpool_str480[sizeof("info.bb")];
+    char stringpool_str481[sizeof("info.ro")];
+    char stringpool_str482[sizeof("info.co")];
+    char stringpool_str483[sizeof("beer")];
+    char stringpool_str484[sizeof("careers")];
+    char stringpool_str485[sizeof("inf.mk")];
+    char stringpool_str486[sizeof("cnt.br")];
+    char stringpool_str487[sizeof("berg.no")];
+    char stringpool_str488[sizeof("int.is")];
+    char stringpool_str489[sizeof("eng.pro")];
+    char stringpool_str490[sizeof("horse")];
+    char stringpool_str491[sizeof("kvam.no")];
+    char stringpool_str492[sizeof("etnedal.no")];
+    char stringpool_str493[sizeof("edu.ve")];
+    char stringpool_str494[sizeof("a.bg")];
+    char stringpool_str495[sizeof("info.pr")];
+    char stringpool_str496[sizeof("edu.bm")];
+    char stringpool_str497[sizeof("gos.pk")];
+    char stringpool_str498[sizeof("best")];
+    char stringpool_str499[sizeof("neustar")];
+    char stringpool_str500[sizeof("dnp")];
+    char stringpool_str501[sizeof("camera")];
+    char stringpool_str502[sizeof("ck")];
+    char stringpool_str503[sizeof("notteroy.no")];
+    char stringpool_str504[sizeof("house")];
+    char stringpool_str505[sizeof("net.ba")];
+    char stringpool_str506[sizeof("info.nr")];
+    char stringpool_str507[sizeof("com.ba")];
+    char stringpool_str508[sizeof("abr.it")];
+    char stringpool_str509[sizeof("gov.ba")];
+    char stringpool_str510[sizeof("b.br")];
+    char stringpool_str511[sizeof("ch")];
+    char stringpool_str512[sizeof("bh")];
+    char stringpool_str513[sizeof("kh")];
+    char stringpool_str514[sizeof("gh")];
+    char stringpool_str515[sizeof("com.kp")];
+    char stringpool_str516[sizeof("gov.kp")];
+    char stringpool_str517[sizeof("belluno.it")];
+    char stringpool_str518[sizeof("net.hk")];
+    char stringpool_str519[sizeof("net.ht")];
+    char stringpool_str520[sizeof("idv.hk")];
+    char stringpool_str521[sizeof("com.hk")];
+    char stringpool_str522[sizeof("com.ht")];
+    char stringpool_str523[sizeof("gov.hk")];
+    char stringpool_str524[sizeof("com.hr")];
+    char stringpool_str525[sizeof("net.kn")];
+    char stringpool_str526[sizeof("kragero.no")];
+    char stringpool_str527[sizeof("aremark.no")];
+    char stringpool_str528[sizeof("ht")];
+    char stringpool_str529[sizeof("nara.nara.jp")];
+    char stringpool_str530[sizeof("gov.kn")];
+    char stringpool_str531[sizeof("here")];
+    char stringpool_str532[sizeof("casa")];
+    char stringpool_str533[sizeof("education")];
+    char stringpool_str534[sizeof("inf.br")];
+    char stringpool_str535[sizeof("net.hn")];
+    char stringpool_str536[sizeof("hr")];
+    char stringpool_str537[sizeof("cheap")];
+    char stringpool_str538[sizeof("com.hn")];
+    char stringpool_str539[sizeof("ind.in")];
+    char stringpool_str540[sizeof("homes")];
+    char stringpool_str541[sizeof("edu.ba")];
+    char stringpool_str542[sizeof("nic.tr")];
+    char stringpool_str543[sizeof("com.na")];
+    char stringpool_str544[sizeof("haus")];
+    char stringpool_str545[sizeof("ind.br")];
+    char stringpool_str546[sizeof("gov.bf")];
+    char stringpool_str547[sizeof("edu.kp")];
+    char stringpool_str548[sizeof("gob.hn")];
+    char stringpool_str549[sizeof("hu")];
+    char stringpool_str550[sizeof("edu.hk")];
+    char stringpool_str551[sizeof("edu.ht")];
+    char stringpool_str552[sizeof("c.se")];
+    char stringpool_str553[sizeof("b.se")];
+    char stringpool_str554[sizeof("k.se")];
+    char stringpool_str555[sizeof("g.se")];
+    char stringpool_str556[sizeof("i.se")];
+    char stringpool_str557[sizeof("cng.br")];
+    char stringpool_str558[sizeof("n.se")];
+    char stringpool_str559[sizeof("edu.kn")];
+    char stringpool_str560[sizeof("ivgu.no")];
+    char stringpool_str561[sizeof("nesseby.no")];
+    char stringpool_str562[sizeof("net.qa")];
+    char stringpool_str563[sizeof("nic.uk")];
+    char stringpool_str564[sizeof("alta.no")];
+    char stringpool_str565[sizeof("int.lk")];
+    char stringpool_str566[sizeof("com.qa")];
+    char stringpool_str567[sizeof("intl.tn")];
+    char stringpool_str568[sizeof("gov.qa")];
+    char stringpool_str569[sizeof("eus")];
+    char stringpool_str570[sizeof("edu.hn")];
+    char stringpool_str571[sizeof("e.se")];
+    char stringpool_str572[sizeof("info.nf")];
+    char stringpool_str573[sizeof("etc.br")];
+    char stringpool_str574[sizeof("eng.br")];
+    char stringpool_str575[sizeof("net.nf")];
+    char stringpool_str576[sizeof("com.nf")];
+    char stringpool_str577[sizeof("hm")];
+    char stringpool_str578[sizeof("d.bg")];
+    char stringpool_str579[sizeof("x.se")];
+    char stringpool_str580[sizeof("z.se")];
+    char stringpool_str581[sizeof("info.tz")];
+    char stringpool_str582[sizeof("int.vn")];
+    char stringpool_str583[sizeof("net.la")];
+    char stringpool_str584[sizeof("com.la")];
+    char stringpool_str585[sizeof("gov.la")];
+    char stringpool_str586[sizeof("ato.br")];
+    char stringpool_str587[sizeof("edu.qa")];
+    char stringpool_str588[sizeof("bio.br")];
+    char stringpool_str589[sizeof("club")];
+    char stringpool_str590[sizeof("amot.no")];
+    char stringpool_str591[sizeof("cw")];
+    char stringpool_str592[sizeof("bw")];
+    char stringpool_str593[sizeof("kw")];
+    char stringpool_str594[sizeof("gw")];
+    char stringpool_str595[sizeof("info.pk")];
+    char stringpool_str596[sizeof("name.qa")];
+    char stringpool_str597[sizeof("asso.km")];
+    char stringpool_str598[sizeof("naustdal.no")];
+    char stringpool_str599[sizeof("net.eg")];
+    char stringpool_str600[sizeof("net.sg")];
+    char stringpool_str601[sizeof("hiv")];
+    char stringpool_str602[sizeof("com.eg")];
+    char stringpool_str603[sizeof("name.mk")];
+    char stringpool_str604[sizeof("gov.eg")];
+    char stringpool_str605[sizeof("com.sg")];
+    char stringpool_str606[sizeof("nic.tj")];
+    char stringpool_str607[sizeof("gov.sg")];
+    char stringpool_str608[sizeof("edu.la")];
+    char stringpool_str609[sizeof("net.iq")];
+    char stringpool_str610[sizeof("ing.pa")];
+    char stringpool_str611[sizeof("com.iq")];
+    char stringpool_str612[sizeof("gov.iq")];
+    char stringpool_str613[sizeof("community")];
+    char stringpool_str614[sizeof("dagestan.ru")];
+    char stringpool_str615[sizeof("info.tn")];
+    char stringpool_str616[sizeof("kommune.no")];
+    char stringpool_str617[sizeof("net.ws")];
+    char stringpool_str618[sizeof("joyo.kyoto.jp")];
+    char stringpool_str619[sizeof("com.ws")];
+    char stringpool_str620[sizeof("a.se")];
+    char stringpool_str621[sizeof("zlg.br")];
+    char stringpool_str622[sizeof("events")];
+    char stringpool_str623[sizeof("gov.ws")];
+    char stringpool_str624[sizeof("zw")];
+    char stringpool_str625[sizeof("cooking")];
+    char stringpool_str626[sizeof("nic.in")];
+    char stringpool_str627[sizeof("is-a-doctor.com")];
+    char stringpool_str628[sizeof("name.az")];
+    char stringpool_str629[sizeof("is-an-actor.com")];
+    char stringpool_str630[sizeof("edu.eg")];
+    char stringpool_str631[sizeof("edu.sg")];
+    char stringpool_str632[sizeof("i.ph")];
+    char stringpool_str633[sizeof("kamo.kyoto.jp")];
+    char stringpool_str634[sizeof("edu.iq")];
+    char stringpool_str635[sizeof("nittedal.no")];
+    char stringpool_str636[sizeof("info.ki")];
+    char stringpool_str637[sizeof("net.ag")];
+    char stringpool_str638[sizeof("art.ht")];
+    char stringpool_str639[sizeof("com.ag")];
+    char stringpool_str640[sizeof("nom.ag")];
+    char stringpool_str641[sizeof("bas.it")];
+    char stringpool_str642[sizeof("edu.ws")];
+    char stringpool_str643[sizeof("hn")];
+    char stringpool_str644[sizeof("belgorod.ru")];
+    char stringpool_str645[sizeof("jobs.tt")];
+    char stringpool_str646[sizeof("dk")];
+    char stringpool_str647[sizeof("com.km")];
+    char stringpool_str648[sizeof("arendal.no")];
+    char stringpool_str649[sizeof("gov.km")];
+    char stringpool_str650[sizeof("enterprises")];
+    char stringpool_str651[sizeof("is-a-player.com")];
+    char stringpool_str652[sizeof("nom.km")];
+    char stringpool_str653[sizeof("bryansk.ru")];
+    char stringpool_str654[sizeof("aw")];
+    char stringpool_str655[sizeof("guide")];
+    char stringpool_str656[sizeof("build")];
+    char stringpool_str657[sizeof("budapest")];
+    char stringpool_str658[sizeof("com.ug")];
+    char stringpool_str659[sizeof("nome.pt")];
+    char stringpool_str660[sizeof("asia")];
+    char stringpool_str661[sizeof("eun.eg")];
+    char stringpool_str662[sizeof("club.tw")];
+    char stringpool_str663[sizeof("edu.km")];
+    char stringpool_str664[sizeof("its.me")];
+    char stringpool_str665[sizeof("domains")];
+    char stringpool_str666[sizeof("hole.no")];
+    char stringpool_str667[sizeof("com.mg")];
+    char stringpool_str668[sizeof("gov.mg")];
+    char stringpool_str669[sizeof("nom.mg")];
+    char stringpool_str670[sizeof("d.se")];
+    char stringpool_str671[sizeof("aero.tt")];
+    char stringpool_str672[sizeof("jus.br")];
+    char stringpool_str673[sizeof("kanmaki.nara.jp")];
+    char stringpool_str674[sizeof("name.tt")];
+    char stringpool_str675[sizeof("kita.kyoto.jp")];
+    char stringpool_str676[sizeof("ens.tn")];
+    char stringpool_str677[sizeof("edu.mg")];
+    char stringpool_str678[sizeof("in-addr.arpa")];
+    char stringpool_str679[sizeof("erotika.hu")];
+    char stringpool_str680[sizeof("navuotna.no")];
+    char stringpool_str681[sizeof("erotica.hu")];
+    char stringpool_str682[sizeof("globo")];
+    char stringpool_str683[sizeof("h.bg")];
+    char stringpool_str684[sizeof("abo.pa")];
+    char stringpool_str685[sizeof("gjemnes.no")];
+    char stringpool_str686[sizeof("badaddja.no")];
+    char stringpool_str687[sizeof("asso.bj")];
+    char stringpool_str688[sizeof("karasjok.no")];
+    char stringpool_str689[sizeof("kotoura.tottori.jp")];
+    char stringpool_str690[sizeof("int.la")];
+    char stringpool_str691[sizeof("drammen.no")];
+    char stringpool_str692[sizeof("bielawa.pl")];
+    char stringpool_str693[sizeof("ye")];
+    char stringpool_str694[sizeof("gjerstad.no")];
+    char stringpool_str695[sizeof("balestrand.no")];
+    char stringpool_str696[sizeof("nord-fron.no")];
+    char stringpool_str697[sizeof("caserta.it")];
+    char stringpool_str698[sizeof("nls.uk")];
+    char stringpool_str699[sizeof("info.az")];
+    char stringpool_str700[sizeof("degree")];
+    char stringpool_str701[sizeof("enebakk.no")];
+    char stringpool_str702[sizeof("net.ng")];
+    char stringpool_str703[sizeof("notodden.no")];
+    char stringpool_str704[sizeof("com.ng")];
+    char stringpool_str705[sizeof("gov.ng")];
+    char stringpool_str706[sizeof("bergamo.it")];
+    char stringpool_str707[sizeof("black")];
+    char stringpool_str708[sizeof("cupcake.is")];
+    char stringpool_str709[sizeof("ando.nara.jp")];
+    char stringpool_str710[sizeof("is-leet.com")];
+    char stringpool_str711[sizeof("asso.dz")];
+    char stringpool_str712[sizeof("koge.tottori.jp")];
+    char stringpool_str713[sizeof("cy")];
+    char stringpool_str714[sizeof("by")];
+    char stringpool_str715[sizeof("ky")];
+    char stringpool_str716[sizeof("gy")];
+    char stringpool_str717[sizeof("eti.br")];
+    char stringpool_str718[sizeof("yt")];
+    char stringpool_str719[sizeof("edu.ng")];
+    char stringpool_str720[sizeof("nordre-land.no")];
+    char stringpool_str721[sizeof("asso.ci")];
+    char stringpool_str722[sizeof("hemsedal.no")];
+    char stringpool_str723[sizeof("gok.pk")];
+    char stringpool_str724[sizeof("hk")];
+    char stringpool_str725[sizeof("doomdns.com")];
+    char stringpool_str726[sizeof("caravan")];
+    char stringpool_str727[sizeof("zhytomyr.ua")];
+    char stringpool_str728[sizeof("holdings")];
+    char stringpool_str729[sizeof("kustanai.ru")];
+    char stringpool_str730[sizeof("gose.nara.jp")];
+    char stringpool_str731[sizeof("grimstad.no")];
+    char stringpool_str732[sizeof("nagasaki.jp")];
+    char stringpool_str733[sizeof("net.ai")];
+    char stringpool_str734[sizeof("com.ai")];
+    char stringpool_str735[sizeof("gallery.museum")];
+    char stringpool_str736[sizeof("engerdal.no")];
+    char stringpool_str737[sizeof("info.tt")];
+    char stringpool_str738[sizeof("builders")];
+    char stringpool_str739[sizeof("h.se")];
+    char stringpool_str740[sizeof("net.dz")];
+    char stringpool_str741[sizeof("com.dz")];
+    char stringpool_str742[sizeof("gov.dz")];
+    char stringpool_str743[sizeof("koto.tokyo.jp")];
+    char stringpool_str744[sizeof("ws")];
+    char stringpool_str745[sizeof("barcelona.museum")];
+    char stringpool_str746[sizeof("audnedaln.no")];
+    char stringpool_str747[sizeof("hamburg")];
+    char stringpool_str748[sizeof("is-gone.com")];
+    char stringpool_str749[sizeof("donetsk.ua")];
+    char stringpool_str750[sizeof("asso.fr")];
+    char stringpool_str751[sizeof("brussel.museum")];
+    char stringpool_str752[sizeof("blogspot.se")];
+    char stringpool_str753[sizeof("web.pk")];
+    char stringpool_str754[sizeof("blogspot.de")];
+    char stringpool_str755[sizeof("czeladz.pl")];
+    char stringpool_str756[sizeof("edu.dz")];
+    char stringpool_str757[sizeof("ingatlan.hu")];
+    char stringpool_str758[sizeof("qa")];
+    char stringpool_str759[sizeof("crotone.it")];
+    char stringpool_str760[sizeof("conf.lv")];
+    char stringpool_str761[sizeof("assn.lk")];
+    char stringpool_str762[sizeof("net.az")];
+    char stringpool_str763[sizeof("kautokeino.no")];
+    char stringpool_str764[sizeof("com.az")];
+    char stringpool_str765[sizeof("gov.az")];
+    char stringpool_str766[sizeof("blog.br")];
+    char stringpool_str767[sizeof("jevnaker.no")];
+    char stringpool_str768[sizeof("nordreisa.no")];
+    char stringpool_str769[sizeof("broadcast.museum")];
+    char stringpool_str770[sizeof("artdeco.museum")];
+    char stringpool_str771[sizeof("wed")];
+    char stringpool_str772[sizeof("kicks-ass.net")];
+    char stringpool_str773[sizeof("cagliari.it")];
+    char stringpool_str774[sizeof("net.uz")];
+    char stringpool_str775[sizeof("edu.az")];
+    char stringpool_str776[sizeof("education.museum")];
+    char stringpool_str777[sizeof("com.uz")];
+    char stringpool_str778[sizeof("international")];
+    char stringpool_str779[sizeof("nissedal.no")];
+    char stringpool_str780[sizeof("karasjohka.no")];
+    char stringpool_str781[sizeof("blogspot.td")];
+    char stringpool_str782[sizeof("asso.re")];
+    char stringpool_str783[sizeof("net.kg")];
+    char stringpool_str784[sizeof("com.kg")];
+    char stringpool_str785[sizeof("blogspot.re")];
+    char stringpool_str786[sizeof("gov.kg")];
+    char stringpool_str787[sizeof("blogspot.pt")];
+    char stringpool_str788[sizeof("jefferson.museum")];
+    char stringpool_str789[sizeof("com.bi")];
+    char stringpool_str790[sizeof("blogspot.ro")];
+    char stringpool_str791[sizeof("work")];
+    char stringpool_str792[sizeof("cash")];
+    char stringpool_str793[sizeof("guitars")];
+    char stringpool_str794[sizeof("works")];
+    char stringpool_str795[sizeof("birkenes.no")];
+    char stringpool_str796[sizeof("kirkenes.no")];
+    char stringpool_str797[sizeof("broke-it.net")];
+    char stringpool_str798[sizeof("kitchen")];
+    char stringpool_str799[sizeof("wtf")];
+    char stringpool_str800[sizeof("calabria.it")];
+    char stringpool_str801[sizeof("wme")];
+    char stringpool_str802[sizeof("ninja")];
+    char stringpool_str803[sizeof("better-than.tv")];
+    char stringpool_str804[sizeof("edu.kg")];
+    char stringpool_str805[sizeof("ink")];
+    char stringpool_str806[sizeof("bike")];
+    char stringpool_str807[sizeof("aircraft.aero")];
+    char stringpool_str808[sizeof("edu.bi")];
+    char stringpool_str809[sizeof("benevento.it")];
+    char stringpool_str810[sizeof("kita.tokyo.jp")];
+    char stringpool_str811[sizeof("blogspot.jp")];
+    char stringpool_str812[sizeof("norfolk.museum")];
+    char stringpool_str813[sizeof("art.dz")];
+    char stringpool_str814[sizeof("nyc")];
+    char stringpool_str815[sizeof("is-a-techie.com")];
+    char stringpool_str816[sizeof("dnsdojo.net")];
+    char stringpool_str817[sizeof("izhevsk.ru")];
+    char stringpool_str818[sizeof("gildeskal.no")];
+    char stringpool_str819[sizeof("web.tj")];
+    char stringpool_str820[sizeof("istmein.de")];
+    char stringpool_str821[sizeof("net.bz")];
+    char stringpool_str822[sizeof("com.bz")];
+    char stringpool_str823[sizeof("amusement.aero")];
+    char stringpool_str824[sizeof("gov.bz")];
+    char stringpool_str825[sizeof("dni.us")];
+    char stringpool_str826[sizeof("y.bg")];
+    char stringpool_str827[sizeof("re")];
+    char stringpool_str828[sizeof("ren")];
+    char stringpool_str829[sizeof("rs")];
+    char stringpool_str830[sizeof("judaica.museum")];
+    char stringpool_str831[sizeof("blogspot.ie")];
+    char stringpool_str832[sizeof("community.museum")];
+    char stringpool_str833[sizeof("ro")];
+    char stringpool_str834[sizeof("entertainment.aero")];
+    char stringpool_str835[sizeof("asso.gp")];
+    char stringpool_str836[sizeof("college")];
+    char stringpool_str837[sizeof("net.vi")];
+    char stringpool_str838[sizeof("com.vi")];
+    char stringpool_str839[sizeof("blogspot.be")];
+    char stringpool_str840[sizeof("edu.bz")];
+    char stringpool_str841[sizeof("elk.pl")];
+    char stringpool_str842[sizeof("blogspot.mr")];
+    char stringpool_str843[sizeof("archi")];
+    char stringpool_str844[sizeof("ass.km")];
+    char stringpool_str845[sizeof("dnsdojo.com")];
+    char stringpool_str846[sizeof("info.at")];
+    char stringpool_str847[sizeof("bokn.no")];
+    char stringpool_str848[sizeof("chukotka.ru")];
+    char stringpool_str849[sizeof("web.id")];
+    char stringpool_str850[sizeof("blogdns.net")];
+    char stringpool_str851[sizeof("hiphop")];
+    char stringpool_str852[sizeof("airline.aero")];
+    char stringpool_str853[sizeof("gorlice.pl")];
+    char stringpool_str854[sizeof("cx")];
+    char stringpool_str855[sizeof("blogspot.it")];
+    char stringpool_str856[sizeof("aero.mv")];
+    char stringpool_str857[sizeof("grosseto.it")];
+    char stringpool_str858[sizeof("blogspot.no")];
+    char stringpool_str859[sizeof("name.mv")];
+    char stringpool_str860[sizeof("red")];
+    char stringpool_str861[sizeof("net.sh")];
+    char stringpool_str862[sizeof("com.sh")];
+    char stringpool_str863[sizeof("gov.sh")];
+    char stringpool_str864[sizeof("int.az")];
+    char stringpool_str865[sizeof("qsl.br")];
+    char stringpool_str866[sizeof("klodzko.pl")];
+    char stringpool_str867[sizeof("net.ph")];
+    char stringpool_str868[sizeof("com.ph")];
+    char stringpool_str869[sizeof("gov.ph")];
+    char stringpool_str870[sizeof("isleofman.museum")];
+    char stringpool_str871[sizeof("ru")];
+    char stringpool_str872[sizeof("nesodden.no")];
+    char stringpool_str873[sizeof("nordkapp.no")];
+    char stringpool_str874[sizeof("arakawa.saitama.jp")];
+    char stringpool_str875[sizeof("kicks-ass.org")];
+    char stringpool_str876[sizeof("rel.pl")];
+    char stringpool_str877[sizeof("report")];
+    char stringpool_str878[sizeof("web.lk")];
+    char stringpool_str879[sizeof("journal.aero")];
+    char stringpool_str880[sizeof("izumisano.osaka.jp")];
+    char stringpool_str881[sizeof("hjelmeland.no")];
+    char stringpool_str882[sizeof("denmark.museum")];
+    char stringpool_str883[sizeof("caltanissetta.it")];
+    char stringpool_str884[sizeof("nyc.mn")];
+    char stringpool_str885[sizeof("carraramassa.it")];
+    char stringpool_str886[sizeof("edu.ph")];
+    char stringpool_str887[sizeof("blogdns.com")];
+    char stringpool_str888[sizeof("evenassi.no")];
+    char stringpool_str889[sizeof("atlanta.museum")];
+    char stringpool_str890[sizeof("wtc")];
+    char stringpool_str891[sizeof("q.bg")];
+    char stringpool_str892[sizeof("grandrapids.museum")];
+    char stringpool_str893[sizeof("net.th")];
+    char stringpool_str894[sizeof("nagoya")];
+    char stringpool_str895[sizeof("blogspot.bj")];
+    char stringpool_str896[sizeof("quebec")];
+    char stringpool_str897[sizeof("hino.tottori.jp")];
+    char stringpool_str898[sizeof("katsuragi.nara.jp")];
+    char stringpool_str899[sizeof("giessen.museum")];
+    char stringpool_str900[sizeof("w.bg")];
+    char stringpool_str901[sizeof("rodeo")];
+    char stringpool_str902[sizeof("webcam")];
+    char stringpool_str903[sizeof("ax")];
+    char stringpool_str904[sizeof("wang")];
+    char stringpool_str905[sizeof("jeonnam.kr")];
+    char stringpool_str906[sizeof("beskidy.pl")];
+    char stringpool_str907[sizeof("namsskogan.no")];
+    char stringpool_str908[sizeof("axa")];
+    char stringpool_str909[sizeof("y.se")];
+    char stringpool_str910[sizeof("kamo.niigata.jp")];
+    char stringpool_str911[sizeof("dielddanuorri.no")];
+    char stringpool_str912[sizeof("net.ki")];
+    char stringpool_str913[sizeof("notaires.km")];
+    char stringpool_str914[sizeof("com.ki")];
+    char stringpool_str915[sizeof("gov.ki")];
+    char stringpool_str916[sizeof("nhk")];
+    char stringpool_str917[sizeof("cloudapp.net")];
+    char stringpool_str918[sizeof("wien")];
+    char stringpool_str919[sizeof("holtalen.no")];
+    char stringpool_str920[sizeof("carrara-massa.it")];
+    char stringpool_str921[sizeof("imperia.it")];
+    char stringpool_str922[sizeof("nysa.pl")];
+    char stringpool_str923[sizeof("rana.no")];
+    char stringpool_str924[sizeof("nannestad.no")];
+    char stringpool_str925[sizeof("cg")];
+    char stringpool_str926[sizeof("bg")];
+    char stringpool_str927[sizeof("kg")];
+    char stringpool_str928[sizeof("gg")];
+    char stringpool_str929[sizeof("communication.museum")];
+    char stringpool_str930[sizeof("ng")];
+    char stringpool_str931[sizeof("catania.it")];
+    char stringpool_str932[sizeof("repair")];
+    char stringpool_str933[sizeof("communications.museum")];
+    char stringpool_str934[sizeof("wroc.pl")];
+    char stringpool_str935[sizeof("irkutsk.ru")];
+    char stringpool_str936[sizeof("club.aero")];
+    char stringpool_str937[sizeof("net.gt")];
+    char stringpool_str938[sizeof("net.gp")];
+    char stringpool_str939[sizeof("net.gr")];
+    char stringpool_str940[sizeof("qpon")];
+    char stringpool_str941[sizeof("eidsberg.no")];
+    char stringpool_str942[sizeof("com.gt")];
+    char stringpool_str943[sizeof("com.gp")];
+    char stringpool_str944[sizeof("com.gr")];
+    char stringpool_str945[sizeof("edu.ki")];
+    char stringpool_str946[sizeof("gov.gr")];
+    char stringpool_str947[sizeof("jeju.kr")];
+    char stringpool_str948[sizeof("web.ve")];
+    char stringpool_str949[sizeof("eg")];
+    char stringpool_str950[sizeof("k-uralsk.ru")];
+    char stringpool_str951[sizeof("alessandria.it")];
+    char stringpool_str952[sizeof("kota.aichi.jp")];
+    char stringpool_str953[sizeof("gob.gt")];
+    char stringpool_str954[sizeof("net.gn")];
+    char stringpool_str955[sizeof("karelia.ru")];
+    char stringpool_str956[sizeof("naturalsciences.museum")];
+    char stringpool_str957[sizeof("com.gn")];
+    char stringpool_str958[sizeof("gov.gn")];
+    char stringpool_str959[sizeof("blogspot.in")];
+    char stringpool_str960[sizeof("aerobatic.aero")];
+    char stringpool_str961[sizeof("expert")];
+    char stringpool_str962[sizeof("defense.tn")];
+    char stringpool_str963[sizeof("edu.gt")];
+    char stringpool_str964[sizeof("edu.gp")];
+    char stringpool_str965[sizeof("edu.gr")];
+    char stringpool_str966[sizeof("net.kz")];
+    char stringpool_str967[sizeof("com.kz")];
+    char stringpool_str968[sizeof("gov.kz")];
+    char stringpool_str969[sizeof("cranbrook.museum")];
+    char stringpool_str970[sizeof("net.bh")];
+    char stringpool_str971[sizeof("info.mv")];
+    char stringpool_str972[sizeof("com.bh")];
+    char stringpool_str973[sizeof("edu.gn")];
+    char stringpool_str974[sizeof("gov.bh")];
+    char stringpool_str975[sizeof("ggee")];
+    char stringpool_str976[sizeof("nagaokakyo.kyoto.jp")];
+    char stringpool_str977[sizeof("certification.aero")];
+    char stringpool_str978[sizeof("educational.museum")];
+    char stringpool_str979[sizeof("chuo.tokyo.jp")];
+    char stringpool_str980[sizeof("charter.aero")];
+    char stringpool_str981[sizeof("blogspot.sk")];
+    char stringpool_str982[sizeof("edu.kz")];
+    char stringpool_str983[sizeof("blogspot.dk")];
+    char stringpool_str984[sizeof("ag")];
+    char stringpool_str985[sizeof("astrakhan.ru")];
+    char stringpool_str986[sizeof("ibaraki.jp")];
+    char stringpool_str987[sizeof("net.ge")];
+    char stringpool_str988[sizeof("edu.bh")];
+    char stringpool_str989[sizeof("com.ge")];
+    char stringpool_str990[sizeof("gov.ge")];
+    char stringpool_str991[sizeof("delmenhorst.museum")];
+    char stringpool_str992[sizeof("chtr.k12.ma.us")];
+    char stringpool_str993[sizeof("bungotakada.oita.jp")];
+    char stringpool_str994[sizeof("name.hr")];
+    char stringpool_str995[sizeof("gliding.aero")];
+    char stringpool_str996[sizeof("rade.no")];
+    char stringpool_str997[sizeof("w.se")];
+    char stringpool_str998[sizeof("khakassia.ru")];
+    char stringpool_str999[sizeof("yono.saitama.jp")];
+    char stringpool_str1000[sizeof("ina.nagano.jp")];
+    char stringpool_str1001[sizeof("hjartdal.no")];
+    char stringpool_str1002[sizeof("rnu.tn")];
+    char stringpool_str1003[sizeof("edu.ge")];
+    char stringpool_str1004[sizeof("r.bg")];
+    char stringpool_str1005[sizeof("roan.no")];
+    char stringpool_str1006[sizeof("como.it")];
+    char stringpool_str1007[sizeof("blogspot.nl")];
+    char stringpool_str1008[sizeof("web.nf")];
+    char stringpool_str1009[sizeof("iris.arpa")];
+    char stringpool_str1010[sizeof("kuroishi.aomori.jp")];
+    char stringpool_str1011[sizeof("astronomy.museum")];
+    char stringpool_str1012[sizeof("agro.pl")];
+    char stringpool_str1013[sizeof("amakusa.kumamoto.jp")];
+    char stringpool_str1014[sizeof("blogspot.kr")];
+    char stringpool_str1015[sizeof("nedre-eiker.no")];
+    char stringpool_str1016[sizeof("kurotaki.nara.jp")];
+    char stringpool_str1017[sizeof("rocks")];
+    char stringpool_str1018[sizeof("rio")];
+    char stringpool_str1019[sizeof("catanzaro.it")];
+    char stringpool_str1020[sizeof("kira.aichi.jp")];
+    char stringpool_str1021[sizeof("rentals")];
+    char stringpool_str1022[sizeof("hino.tokyo.jp")];
+    char stringpool_str1023[sizeof("kameoka.kyoto.jp")];
+    char stringpool_str1024[sizeof("blogspot.hu")];
+    char stringpool_str1025[sizeof("culture.museum")];
+    char stringpool_str1026[sizeof("goto.nagasaki.jp")];
+    char stringpool_str1027[sizeof("watch")];
+    char stringpool_str1028[sizeof("ngo")];
+    char stringpool_str1029[sizeof("itakura.gunma.jp")];
+    char stringpool_str1030[sizeof("birthplace.museum")];
+    char stringpool_str1031[sizeof("geology.museum")];
+    char stringpool_str1032[sizeof("ngo.pl")];
+    char stringpool_str1033[sizeof("grajewo.pl")];
+    char stringpool_str1034[sizeof("americana.museum")];
+    char stringpool_str1035[sizeof("birdart.museum")];
+    char stringpool_str1036[sizeof("abruzzo.it")];
+    char stringpool_str1037[sizeof("rest")];
+    char stringpool_str1038[sizeof("niigata.jp")];
+    char stringpool_str1039[sizeof("bargains")];
+    char stringpool_str1040[sizeof("koto.shiga.jp")];
+    char stringpool_str1041[sizeof("rec.br")];
+    char stringpool_str1042[sizeof("carrier.museum")];
+    char stringpool_str1043[sizeof("novosibirsk.ru")];
+    char stringpool_str1044[sizeof("conf.au")];
+    char stringpool_str1045[sizeof("kongsberg.no")];
+    char stringpool_str1046[sizeof("ggf.br")];
+    char stringpool_str1047[sizeof("zoology.museum")];
+    char stringpool_str1048[sizeof("akrehamn.no")];
+    char stringpool_str1049[sizeof("gets-it.net")];
+    char stringpool_str1050[sizeof("capital")];
+    char stringpool_str1051[sizeof("holmestrand.no")];
+    char stringpool_str1052[sizeof("blogspot.tw")];
+    char stringpool_str1053[sizeof("rep.kp")];
+    char stringpool_str1054[sizeof("gniezno.pl")];
+    char stringpool_str1055[sizeof("cechire.com")];
+    char stringpool_str1056[sizeof("aurland.no")];
+    char stringpool_str1057[sizeof("illustration.museum")];
+    char stringpool_str1058[sizeof("agr.br")];
+    char stringpool_str1059[sizeof("isesaki.gunma.jp")];
+    char stringpool_str1060[sizeof("kashiba.nara.jp")];
+    char stringpool_str1061[sizeof("gamo.shiga.jp")];
+    char stringpool_str1062[sizeof("bajddar.no")];
+    char stringpool_str1063[sizeof("rehab")];
+    char stringpool_str1064[sizeof("email")];
+    char stringpool_str1065[sizeof("ind.gt")];
+    char stringpool_str1066[sizeof("amli.no")];
+    char stringpool_str1067[sizeof("kartuzy.pl")];
+    char stringpool_str1068[sizeof("kisosaki.mie.jp")];
+    char stringpool_str1069[sizeof("r.se")];
+    char stringpool_str1070[sizeof("kalmykia.ru")];
+    char stringpool_str1071[sizeof("budejju.no")];
+    char stringpool_str1072[sizeof("bologna.it")];
+    char stringpool_str1073[sizeof("alabama.museum")];
+    char stringpool_str1074[sizeof("is-a-lawyer.com")];
+    char stringpool_str1075[sizeof("rnrt.tn")];
+    char stringpool_str1076[sizeof("contemporary.museum")];
+    char stringpool_str1077[sizeof("babia-gora.pl")];
+    char stringpool_str1078[sizeof("bieszczady.pl")];
+    char stringpool_str1079[sizeof("ravenna.it")];
+    char stringpool_str1080[sizeof("cruises")];
+    char stringpool_str1081[sizeof("isernia.it")];
+    char stringpool_str1082[sizeof("eisenbahn.museum")];
+    char stringpool_str1083[sizeof("rel.ht")];
+    char stringpool_str1084[sizeof("chel.ru")];
+    char stringpool_str1085[sizeof("hamburg.museum")];
+    char stringpool_str1086[sizeof("info.sd")];
+    char stringpool_str1087[sizeof("kobierzyce.pl")];
+    char stringpool_str1088[sizeof("iida.nagano.jp")];
+    char stringpool_str1089[sizeof("rost.no")];
+    char stringpool_str1090[sizeof("rw")];
+    char stringpool_str1091[sizeof("granvin.no")];
+    char stringpool_str1092[sizeof("gateway.museum")];
+    char stringpool_str1093[sizeof("reise")];
+    char stringpool_str1094[sizeof("enna.it")];
+    char stringpool_str1095[sizeof("castres.museum")];
+    char stringpool_str1096[sizeof("yao.osaka.jp")];
+    char stringpool_str1097[sizeof("iveland.no")];
+    char stringpool_str1098[sizeof("collection.museum")];
+    char stringpool_str1099[sizeof("reisen")];
+    char stringpool_str1100[sizeof("americanart.museum")];
+    char stringpool_str1101[sizeof("res.in")];
+    char stringpool_str1102[sizeof("kitaakita.akita.jp")];
+    char stringpool_str1103[sizeof("ina.saitama.jp")];
+    char stringpool_str1104[sizeof("zhitomir.ua")];
+    char stringpool_str1105[sizeof("repbody.aero")];
+    char stringpool_str1106[sizeof("jessheim.no")];
+    char stringpool_str1107[sizeof("catering")];
+    char stringpool_str1108[sizeof("noda.iwate.jp")];
+    char stringpool_str1109[sizeof("yachts")];
+    char stringpool_str1110[sizeof("ethnology.museum")];
+    char stringpool_str1111[sizeof("assassination.museum")];
+    char stringpool_str1112[sizeof("us")];
+    char stringpool_str1113[sizeof("rennesoy.no")];
+    char stringpool_str1114[sizeof("yaroslavl.ru")];
+    char stringpool_str1115[sizeof("itabashi.tokyo.jp")];
+    char stringpool_str1116[sizeof("kviteseid.no")];
+    char stringpool_str1117[sizeof("construction")];
+    char stringpool_str1118[sizeof("casadelamoneda.museum")];
+    char stringpool_str1119[sizeof("coldwar.museum")];
+    char stringpool_str1120[sizeof("bydgoszcz.pl")];
+    char stringpool_str1121[sizeof("history.museum")];
+    char stringpool_str1122[sizeof("kin.okinawa.jp")];
+    char stringpool_str1123[sizeof("info.au")];
+    char stringpool_str1124[sizeof("dellogliastra.it")];
+    char stringpool_str1125[sizeof("ina.ibaraki.jp")];
+    char stringpool_str1126[sizeof("diamonds")];
+    char stringpool_str1127[sizeof("res.aero")];
+    char stringpool_str1128[sizeof("does-it.net")];
+    char stringpool_str1129[sizeof("isen.kagoshima.jp")];
+    char stringpool_str1130[sizeof("nes.akershus.no")];
+    char stringpool_str1131[sizeof("capebreton.museum")];
+    char stringpool_str1132[sizeof("australia.museum")];
+    char stringpool_str1133[sizeof("desi")];
+    char stringpool_str1134[sizeof("cincinnati.museum")];
+    char stringpool_str1135[sizeof("eastafrica.museum")];
+    char stringpool_str1136[sizeof("hirosaki.aomori.jp")];
+    char stringpool_str1137[sizeof("ua")];
+    char stringpool_str1138[sizeof("cesenaforli.it")];
+    char stringpool_str1139[sizeof("ngo.lk")];
+    char stringpool_str1140[sizeof("imageandsound.museum")];
+    char stringpool_str1141[sizeof("cosenza.it")];
+    char stringpool_str1142[sizeof("nuremberg.museum")];
+    char stringpool_str1143[sizeof("kamoenai.hokkaido.jp")];
+    char stringpool_str1144[sizeof("getmyip.com")];
+    char stringpool_str1145[sizeof("ibaraki.osaka.jp")];
+    char stringpool_str1146[sizeof("norilsk.ru")];
+    char stringpool_str1147[sizeof("kodaira.tokyo.jp")];
+    char stringpool_str1148[sizeof("nichinan.tottori.jp")];
+    char stringpool_str1149[sizeof("alesund.no")];
+    char stringpool_str1150[sizeof("kameyama.mie.jp")];
+    char stringpool_str1151[sizeof("augustow.pl")];
+    char stringpool_str1152[sizeof("dyndns-home.com")];
+    char stringpool_str1153[sizeof("rns.tn")];
+    char stringpool_str1154[sizeof("nalchik.ru")];
+    char stringpool_str1155[sizeof("uz")];
+    char stringpool_str1156[sizeof("ibestad.no")];
+    char stringpool_str1157[sizeof("blogspot.hk")];
+    char stringpool_str1158[sizeof("ikaruga.nara.jp")];
+    char stringpool_str1159[sizeof("asakuchi.okayama.jp")];
+    char stringpool_str1160[sizeof("kamaishi.iwate.jp")];
+    char stringpool_str1161[sizeof("amur.ru")];
+    char stringpool_str1162[sizeof("dudinka.ru")];
+    char stringpool_str1163[sizeof("rendalen.no")];
+    char stringpool_str1164[sizeof("catering.aero")];
+    char stringpool_str1165[sizeof("ise.mie.jp")];
+    char stringpool_str1166[sizeof("is-a-candidate.org")];
+    char stringpool_str1167[sizeof("net.gg")];
+    char stringpool_str1168[sizeof("arakawa.tokyo.jp")];
+    char stringpool_str1169[sizeof("eigersund.no")];
+    char stringpool_str1170[sizeof("rec.nf")];
+    char stringpool_str1171[sizeof("koya.wakayama.jp")];
+    char stringpool_str1172[sizeof("christmas")];
+    char stringpool_str1173[sizeof("hara.nagano.jp")];
+    char stringpool_str1174[sizeof("cologne")];
+    char stringpool_str1175[sizeof("gobo.wakayama.jp")];
+    char stringpool_str1176[sizeof("ruhr")];
+    char stringpool_str1177[sizeof("warszawa.pl")];
+    char stringpool_str1178[sizeof("hoyanger.no")];
+    char stringpool_str1179[sizeof("journalism.museum")];
+    char stringpool_str1180[sizeof("nord-aurdal.no")];
+    char stringpool_str1181[sizeof("costume.museum")];
+    char stringpool_str1182[sizeof("holiday")];
+    char stringpool_str1183[sizeof("anan.nagano.jp")];
+    char stringpool_str1184[sizeof("digital")];
+    char stringpool_str1185[sizeof("koga.ibaraki.jp")];
+    char stringpool_str1186[sizeof("arboretum.museum")];
+    char stringpool_str1187[sizeof("isa.kagoshima.jp")];
+    char stringpool_str1188[sizeof("homeunix.net")];
+    char stringpool_str1189[sizeof("avellino.it")];
+    char stringpool_str1190[sizeof("contemporaryart.museum")];
+    char stringpool_str1191[sizeof("is-lost.org")];
+    char stringpool_str1192[sizeof("hiranai.aomori.jp")];
+    char stringpool_str1193[sizeof("cheltenham.museum")];
+    char stringpool_str1194[sizeof("kiso.nagano.jp")];
+    char stringpool_str1195[sizeof("gotemba.shizuoka.jp")];
+    char stringpool_str1196[sizeof("cahcesuolo.no")];
+    char stringpool_str1197[sizeof("british.museum")];
+    char stringpool_str1198[sizeof("workinggroup.aero")];
+    char stringpool_str1199[sizeof("kanagawa.jp")];
+    char stringpool_str1200[sizeof("bjerkreim.no")];
+    char stringpool_str1201[sizeof("umb.it")];
+    char stringpool_str1202[sizeof("kitakami.iwate.jp")];
+    char stringpool_str1203[sizeof("naturalhistory.museum")];
+    char stringpool_str1204[sizeof("yamanashi.jp")];
+    char stringpool_str1205[sizeof("urn.arpa")];
+    char stringpool_str1206[sizeof("dlugoleka.pl")];
+    char stringpool_str1207[sizeof("cleaning")];
+    char stringpool_str1208[sizeof("kamchatka.ru")];
+    char stringpool_str1209[sizeof("ascolipiceno.it")];
+    char stringpool_str1210[sizeof("kami.kochi.jp")];
+    char stringpool_str1211[sizeof("azumino.nagano.jp")];
+    char stringpool_str1212[sizeof("u.bg")];
+    char stringpool_str1213[sizeof("doesntexist.com")];
+    char stringpool_str1214[sizeof("info.ht")];
+    char stringpool_str1215[sizeof("childrens.museum")];
+    char stringpool_str1216[sizeof("americanantiques.museum")];
+    char stringpool_str1217[sizeof("rich")];
+    char stringpool_str1218[sizeof("consulting")];
+    char stringpool_str1219[sizeof("nakhodka.ru")];
+    char stringpool_str1220[sizeof("cherkasy.ua")];
+    char stringpool_str1221[sizeof("harstad.no")];
+    char stringpool_str1222[sizeof("halloffame.museum")];
+    char stringpool_str1223[sizeof("bato.tochigi.jp")];
+    char stringpool_str1224[sizeof("doomdns.org")];
+    char stringpool_str1225[sizeof("divtasvuodna.no")];
+    char stringpool_str1226[sizeof("edogawa.tokyo.jp")];
+    char stringpool_str1227[sizeof("kristiansand.no")];
+    char stringpool_str1228[sizeof("ikusaka.nagano.jp")];
+    char stringpool_str1229[sizeof("barletta-trani-andria.it")];
+    char stringpool_str1230[sizeof("com.gi")];
+    char stringpool_str1231[sizeof("gov.gi")];
+    char stringpool_str1232[sizeof("realestate.pl")];
+    char stringpool_str1233[sizeof("kunstsammlung.museum")];
+    char stringpool_str1234[sizeof("jelenia-gora.pl")];
+    char stringpool_str1235[sizeof("uno")];
+    char stringpool_str1236[sizeof("agdenes.no")];
+    char stringpool_str1237[sizeof("kristiansund.no")];
+    char stringpool_str1238[sizeof("gjerdrum.no")];
+    char stringpool_str1239[sizeof("kunneppu.hokkaido.jp")];
+    char stringpool_str1240[sizeof("arao.kumamoto.jp")];
+    char stringpool_str1241[sizeof("game-host.org")];
+    char stringpool_str1242[sizeof("uk")];
+    char stringpool_str1243[sizeof("edu.gi")];
+    char stringpool_str1244[sizeof("homedns.org")];
+    char stringpool_str1245[sizeof("blackfriday")];
+    char stringpool_str1246[sizeof("kagoshima.jp")];
+    char stringpool_str1247[sizeof("cherkassy.ua")];
+    char stringpool_str1248[sizeof("geelvinck.museum")];
+    char stringpool_str1249[sizeof("nobeoka.miyazaki.jp")];
+    char stringpool_str1250[sizeof("express.aero")];
+    char stringpool_str1251[sizeof("barlettatraniandria.it")];
+    char stringpool_str1252[sizeof("beauxarts.museum")];
+    char stringpool_str1253[sizeof("bialystok.pl")];
+    char stringpool_str1254[sizeof("zaporizhzhia.ua")];
+    char stringpool_str1255[sizeof("dating")];
+    char stringpool_str1256[sizeof("championship.aero")];
+    char stringpool_str1257[sizeof("zaporizhzhe.ua")];
+    char stringpool_str1258[sizeof("hanamaki.iwate.jp")];
+    char stringpool_str1259[sizeof("equipment")];
+    char stringpool_str1260[sizeof("home.dyndns.org")];
+    char stringpool_str1261[sizeof("chelyabinsk.ru")];
+    char stringpool_str1262[sizeof("u.se")];
+    char stringpool_str1263[sizeof("blogspot.mx")];
+    char stringpool_str1264[sizeof("zoological.museum")];
+    char stringpool_str1265[sizeof("nuernberg.museum")];
+    char stringpool_str1266[sizeof("chesapeakebay.museum")];
+    char stringpool_str1267[sizeof("brumunddal.no")];
+    char stringpool_str1268[sizeof("haugesund.no")];
+    char stringpool_str1269[sizeof("blogspot.sg")];
+    char stringpool_str1270[sizeof("koganei.tokyo.jp")];
+    char stringpool_str1271[sizeof("asaminami.hiroshima.jp")];
+    char stringpool_str1272[sizeof("historisches.museum")];
+    char stringpool_str1273[sizeof("anan.tokushima.jp")];
+    char stringpool_str1274[sizeof("me")];
+    char stringpool_str1275[sizeof("ms")];
+    char stringpool_str1276[sizeof("menu")];
+    char stringpool_str1277[sizeof("md")];
+    char stringpool_str1278[sizeof("kashiwara.osaka.jp")];
+    char stringpool_str1279[sizeof("mo")];
+    char stringpool_str1280[sizeof("kafjord.no")];
+    char stringpool_str1281[sizeof("mov")];
+    char stringpool_str1282[sizeof("nagaoka.niigata.jp")];
+    char stringpool_str1283[sizeof("moe")];
+    char stringpool_str1284[sizeof("mp")];
+    char stringpool_str1285[sizeof("com.sv")];
+    char stringpool_str1286[sizeof("k12.ec")];
+    char stringpool_str1287[sizeof("indiana.museum")];
+    char stringpool_str1288[sizeof("gorizia.it")];
+    char stringpool_str1289[sizeof("asso.ht")];
+    char stringpool_str1290[sizeof("gob.sv")];
+    char stringpool_str1291[sizeof("meet")];
+    char stringpool_str1292[sizeof("joshkar-ola.ru")];
+    char stringpool_str1293[sizeof("joso.ibaraki.jp")];
+    char stringpool_str1294[sizeof("architecture.museum")];
+    char stringpool_str1295[sizeof("kounosu.saitama.jp")];
+    char stringpool_str1296[sizeof("gyokuto.kumamoto.jp")];
+    char stringpool_str1297[sizeof("brindisi.it")];
+    char stringpool_str1298[sizeof("mormon")];
+    char stringpool_str1299[sizeof("yatsuka.shimane.jp")];
+    char stringpool_str1300[sizeof("bearalvahki.no")];
+    char stringpool_str1301[sizeof("ami.ibaraki.jp")];
+    char stringpool_str1302[sizeof("khabarovsk.ru")];
+    char stringpool_str1303[sizeof("bygland.no")];
+    char stringpool_str1304[sizeof("at-band-camp.net")];
+    char stringpool_str1305[sizeof("dnsalias.net")];
+    char stringpool_str1306[sizeof("edu.sv")];
+    char stringpool_str1307[sizeof("blogspot.gr")];
+    char stringpool_str1308[sizeof("ma")];
+    char stringpool_str1309[sizeof("ibaraki.ibaraki.jp")];
+    char stringpool_str1310[sizeof("equipment.aero")];
+    char stringpool_str1311[sizeof("yoshino.nara.jp")];
+    char stringpool_str1312[sizeof("mt")];
+    char stringpool_str1313[sizeof("meme")];
+    char stringpool_str1314[sizeof("mr")];
+    char stringpool_str1315[sizeof("imakane.hokkaido.jp")];
+    char stringpool_str1316[sizeof("business")];
+    char stringpool_str1317[sizeof("med.ec")];
+    char stringpool_str1318[sizeof("western.museum")];
+    char stringpool_str1319[sizeof("kasaoka.okayama.jp")];
+    char stringpool_str1320[sizeof("hinohara.tokyo.jp")];
+    char stringpool_str1321[sizeof("nagahama.shiga.jp")];
+    char stringpool_str1322[sizeof("med.pl")];
+    char stringpool_str1323[sizeof("kashiwa.chiba.jp")];
+    char stringpool_str1324[sizeof("mu")];
+    char stringpool_str1325[sizeof("moda")];
+    char stringpool_str1326[sizeof("mz")];
+    char stringpool_str1327[sizeof("krodsherad.no")];
+    char stringpool_str1328[sizeof("koka.shiga.jp")];
+    char stringpool_str1329[sizeof("kagamino.okayama.jp")];
+    char stringpool_str1330[sizeof("koebenhavn.museum")];
+    char stringpool_str1331[sizeof("hyllestad.no")];
+    char stringpool_str1332[sizeof("kitaura.miyazaki.jp")];
+    char stringpool_str1333[sizeof("dyndns-mail.com")];
+    char stringpool_str1334[sizeof("kommunalforbund.se")];
+    char stringpool_str1335[sizeof("komi.ru")];
+    char stringpool_str1336[sizeof("kishiwada.osaka.jp")];
+    char stringpool_str1337[sizeof("gyeonggi.kr")];
+    char stringpool_str1338[sizeof("jondal.no")];
+    char stringpool_str1339[sizeof("namsos.no")];
+    char stringpool_str1340[sizeof("mm")];
+    char stringpool_str1341[sizeof("emergency.aero")];
+    char stringpool_str1342[sizeof("net.mv")];
+    char stringpool_str1343[sizeof("dnsdojo.org")];
+    char stringpool_str1344[sizeof("com.mv")];
+    char stringpool_str1345[sizeof("gov.mv")];
+    char stringpool_str1346[sizeof("med.sd")];
+    char stringpool_str1347[sizeof("kosa.kumamoto.jp")];
+    char stringpool_str1348[sizeof("kashima.kumamoto.jp")];
+    char stringpool_str1349[sizeof("neyagawa.osaka.jp")];
+    char stringpool_str1350[sizeof("engineer.aero")];
+    char stringpool_str1351[sizeof("whaling.museum")];
+    char stringpool_str1352[sizeof("market")];
+    char stringpool_str1353[sizeof("noshiro.akita.jp")];
+    char stringpool_str1354[sizeof("wroclaw.pl")];
+    char stringpool_str1355[sizeof("med.pro")];
+    char stringpool_str1356[sizeof("idrett.no")];
+    char stringpool_str1357[sizeof("gaular.no")];
+    char stringpool_str1358[sizeof("med.ee")];
+    char stringpool_str1359[sizeof("edu.mv")];
+    char stringpool_str1360[sizeof("kunisaki.oita.jp")];
+    char stringpool_str1361[sizeof("historical.museum")];
+    char stringpool_str1362[sizeof("mod.uk")];
+    char stringpool_str1363[sizeof("kamioka.akita.jp")];
+    char stringpool_str1364[sizeof("zao.miyagi.jp")];
+    char stringpool_str1365[sizeof("udmurtia.ru")];
+    char stringpool_str1366[sizeof("england.museum")];
+    char stringpool_str1367[sizeof("williamhill")];
+    char stringpool_str1368[sizeof("esan.hokkaido.jp")];
+    char stringpool_str1369[sizeof("hatoyama.saitama.jp")];
+    char stringpool_str1370[sizeof("randaberg.no")];
+    char stringpool_str1371[sizeof("g12.br")];
+    char stringpool_str1372[sizeof("wada.nagano.jp")];
+    char stringpool_str1373[sizeof("watarai.mie.jp")];
+    char stringpool_str1374[sizeof("kitadaito.okinawa.jp")];
+    char stringpool_str1375[sizeof("nanmoku.gunma.jp")];
+    char stringpool_str1376[sizeof("blogdns.org")];
+    char stringpool_str1377[sizeof("naturalhistorymuseum.museum")];
+    char stringpool_str1378[sizeof("com.gh")];
+    char stringpool_str1379[sizeof("gov.gh")];
+    char stringpool_str1380[sizeof("unsa.ba")];
+    char stringpool_str1381[sizeof("kembuchi.hokkaido.jp")];
+    char stringpool_str1382[sizeof("historisch.museum")];
+    char stringpool_str1383[sizeof("mar.it")];
+    char stringpool_str1384[sizeof("mn")];
+    char stringpool_str1385[sizeof("clothing")];
+    char stringpool_str1386[sizeof("bolt.hu")];
+    char stringpool_str1387[sizeof("nasu.tochigi.jp")];
+    char stringpool_str1388[sizeof("izu.shizuoka.jp")];
+    char stringpool_str1389[sizeof("riik.ee")];
+    char stringpool_str1390[sizeof("dynalias.net")];
+    char stringpool_str1391[sizeof("motorcycles")];
+    char stringpool_str1392[sizeof("network")];
+    char stringpool_str1393[sizeof("mat.br")];
+    char stringpool_str1394[sizeof("edu.gh")];
+    char stringpool_str1395[sizeof("dgca.aero")];
+    char stringpool_str1396[sizeof("mq")];
+    char stringpool_str1397[sizeof("chicago.museum")];
+    char stringpool_str1398[sizeof("bindal.no")];
+    char stringpool_str1399[sizeof("mil")];
+    char stringpool_str1400[sizeof("kannami.shizuoka.jp")];
+    char stringpool_str1401[sizeof("yokohama")];
+    char stringpool_str1402[sizeof("med.br")];
+    char stringpool_str1403[sizeof("mil.st")];
+    char stringpool_str1404[sizeof("mil.ec")];
+    char stringpool_str1405[sizeof("isehara.kanagawa.jp")];
+    char stringpool_str1406[sizeof("mol.it")];
+    char stringpool_str1407[sizeof("mil.pl")];
+    char stringpool_str1408[sizeof("ml")];
+    char stringpool_str1409[sizeof("roma.it")];
+    char stringpool_str1410[sizeof("med.om")];
+    char stringpool_str1411[sizeof("kumagaya.saitama.jp")];
+    char stringpool_str1412[sizeof("date.hokkaido.jp")];
+    char stringpool_str1413[sizeof("mie.jp")];
+    char stringpool_str1414[sizeof("khmelnytskyi.ua")];
+    char stringpool_str1415[sizeof("akabira.hokkaido.jp")];
+    char stringpool_str1416[sizeof("net.lv")];
+    char stringpool_str1417[sizeof("uy")];
+    char stringpool_str1418[sizeof("mv")];
+    char stringpool_str1419[sizeof("com.lv")];
+    char stringpool_str1420[sizeof("gov.lv")];
+    char stringpool_str1421[sizeof("rennebu.no")];
+    char stringpool_str1422[sizeof("ishikawa.jp")];
+    char stringpool_str1423[sizeof("reviews")];
+    char stringpool_str1424[sizeof("mil.al")];
+    char stringpool_str1425[sizeof("naples.it")];
+    char stringpool_str1426[sizeof("mil.ar")];
+    char stringpool_str1427[sizeof("mil.ac")];
+    char stringpool_str1428[sizeof("mil.tw")];
+    char stringpool_str1429[sizeof("hirakata.osaka.jp")];
+    char stringpool_str1430[sizeof("edu.lv")];
+    char stringpool_str1431[sizeof("med.sa")];
+    char stringpool_str1432[sizeof("divttasvuotna.no")];
+    char stringpool_str1433[sizeof("kiyosato.hokkaido.jp")];
+    char stringpool_str1434[sizeof("zama.kanagawa.jp")];
+    char stringpool_str1435[sizeof("rome.it")];
+    char stringpool_str1436[sizeof("haga.tochigi.jp")];
+    char stringpool_str1437[sizeof("m.bg")];
+    char stringpool_str1438[sizeof("mil.rw")];
+    char stringpool_str1439[sizeof("miami")];
+    char stringpool_str1440[sizeof("med.pa")];
+    char stringpool_str1441[sizeof("gov.nc.tr")];
+    char stringpool_str1442[sizeof("katsushika.tokyo.jp")];
+    char stringpool_str1443[sizeof("bergen.no")];
+    char stringpool_str1444[sizeof("uri.arpa")];
+    char stringpool_str1445[sizeof("hiroshima.jp")];
+    char stringpool_str1446[sizeof("exposed")];
+    char stringpool_str1447[sizeof("int.mv")];
+    char stringpool_str1448[sizeof("mango")];
+    char stringpool_str1449[sizeof("edunet.tn")];
+    char stringpool_str1450[sizeof("uda.nara.jp")];
+    char stringpool_str1451[sizeof("mil.pe")];
+    char stringpool_str1452[sizeof("iki.nagasaki.jp")];
+    char stringpool_str1453[sizeof("bergbau.museum")];
+    char stringpool_str1454[sizeof("yakutia.ru")];
+    char stringpool_str1455[sizeof("uzhgorod.ua")];
+    char stringpool_str1456[sizeof("bari.it")];
+    char stringpool_str1457[sizeof("ito.shizuoka.jp")];
+    char stringpool_str1458[sizeof("asn.lv")];
+    char stringpool_str1459[sizeof("koshigaya.saitama.jp")];
+    char stringpool_str1460[sizeof("yokohama.jp")];
+    char stringpool_str1461[sizeof("namegawa.saitama.jp")];
+    char stringpool_str1462[sizeof("hashikami.aomori.jp")];
+    char stringpool_str1463[sizeof("name.vn")];
+    char stringpool_str1464[sizeof("mil.ae")];
+    char stringpool_str1465[sizeof("info.hu")];
+    char stringpool_str1466[sizeof("hornindal.no")];
+    char stringpool_str1467[sizeof("e12.ve")];
+    char stringpool_str1468[sizeof("gotdns.com")];
+    char stringpool_str1469[sizeof("mil.tj")];
+    char stringpool_str1470[sizeof("indianmarket.museum")];
+    char stringpool_str1471[sizeof("ngo.ph")];
+    char stringpool_str1472[sizeof("kai.yamanashi.jp")];
+    char stringpool_str1473[sizeof("asti.it")];
+    char stringpool_str1474[sizeof("hamatama.saga.jp")];
+    char stringpool_str1475[sizeof("indianapolis.museum")];
+    char stringpool_str1476[sizeof("hatsukaichi.hiroshima.jp")];
+    char stringpool_str1477[sizeof("balsan.it")];
+    char stringpool_str1478[sizeof("ve")];
+    char stringpool_str1479[sizeof("kanazawa.ishikawa.jp")];
+    char stringpool_str1480[sizeof("kutchan.hokkaido.jp")];
+    char stringpool_str1481[sizeof("mk")];
+    char stringpool_str1482[sizeof("nikolaev.ua")];
+    char stringpool_str1483[sizeof("mil.in")];
+    char stringpool_str1484[sizeof("vet")];
+    char stringpool_str1485[sizeof("kure.hiroshima.jp")];
+    char stringpool_str1486[sizeof("kuki.saitama.jp")];
+    char stringpool_str1487[sizeof("etajima.hiroshima.jp")];
+    char stringpool_str1488[sizeof("mil.br")];
+    char stringpool_str1489[sizeof("nesset.no")];
+    char stringpool_str1490[sizeof("katagami.akita.jp")];
+    char stringpool_str1491[sizeof("mh")];
+    char stringpool_str1492[sizeof("decorativearts.museum")];
+    char stringpool_str1493[sizeof("godo.gifu.jp")];
+    char stringpool_str1494[sizeof("worse-than.tv")];
+    char stringpool_str1495[sizeof("yura.wakayama.jp")];
+    char stringpool_str1496[sizeof("alvdal.no")];
+    char stringpool_str1497[sizeof("naka.ibaraki.jp")];
+    char stringpool_str1498[sizeof("voto")];
+    char stringpool_str1499[sizeof("andriabarlettatrani.it")];
+    char stringpool_str1500[sizeof("chungnam.kr")];
+    char stringpool_str1501[sizeof("kumenan.okayama.jp")];
+    char stringpool_str1502[sizeof("detroit.museum")];
+    char stringpool_str1503[sizeof("kumejima.okinawa.jp")];
+    char stringpool_str1504[sizeof("mil.id")];
+    char stringpool_str1505[sizeof("yasu.shiga.jp")];
+    char stringpool_str1506[sizeof("niikappu.hokkaido.jp")];
+    char stringpool_str1507[sizeof("horten.no")];
+    char stringpool_str1508[sizeof("gyeongbuk.kr")];
+    char stringpool_str1509[sizeof("va")];
+    char stringpool_str1510[sizeof("kamisato.saitama.jp")];
+    char stringpool_str1511[sizeof("nonoichi.ishikawa.jp")];
+    char stringpool_str1512[sizeof("qld.edu.au")];
+    char stringpool_str1513[sizeof("moscow")];
+    char stringpool_str1514[sizeof("m.se")];
+    char stringpool_str1515[sizeof("habmer.no")];
+    char stringpool_str1516[sizeof("kashima.ibaraki.jp")];
+    char stringpool_str1517[sizeof("wolomin.pl")];
+    char stringpool_str1518[sizeof("vote")];
+    char stringpool_str1519[sizeof("desa.id")];
+    char stringpool_str1520[sizeof("chernigov.ua")];
+    char stringpool_str1521[sizeof("kyotango.kyoto.jp")];
+    char stringpool_str1522[sizeof("mil.tm")];
+    char stringpool_str1523[sizeof("walbrzych.pl")];
+    char stringpool_str1524[sizeof("himi.toyama.jp")];
+    char stringpool_str1525[sizeof("vu")];
+    char stringpool_str1526[sizeof("med.ht")];
+    char stringpool_str1527[sizeof("is-a-hunter.com")];
+    char stringpool_str1528[sizeof("anjo.aichi.jp")];
+    char stringpool_str1529[sizeof("ama.shimane.jp")];
+    char stringpool_str1530[sizeof("moss.no")];
+    char stringpool_str1531[sizeof("vegas")];
+    char stringpool_str1532[sizeof("koga.fukuoka.jp")];
+    char stringpool_str1533[sizeof("rockart.museum")];
+    char stringpool_str1534[sizeof("yatsushiro.kumamoto.jp")];
+    char stringpool_str1535[sizeof("mil.vc")];
+    char stringpool_str1536[sizeof("ringebu.no")];
+    char stringpool_str1537[sizeof("dyndns-free.com")];
+    char stringpool_str1538[sizeof("mw")];
+    char stringpool_str1539[sizeof("novara.it")];
+    char stringpool_str1540[sizeof("evenes.no")];
+    char stringpool_str1541[sizeof("khmelnitskiy.ua")];
+    char stringpool_str1542[sizeof("honbetsu.hokkaido.jp")];
+    char stringpool_str1543[sizeof("hadsel.no")];
+    char stringpool_str1544[sizeof("krakow.pl")];
+    char stringpool_str1545[sizeof("arai.shizuoka.jp")];
+    char stringpool_str1546[sizeof("gyeongnam.kr")];
+    char stringpool_str1547[sizeof("yasuoka.nagano.jp")];
+    char stringpool_str1548[sizeof("narusawa.yamanashi.jp")];
+    char stringpool_str1549[sizeof("yoshida.saitama.jp")];
+    char stringpool_str1550[sizeof("hurdal.no")];
+    char stringpool_str1551[sizeof("info.vn")];
+    char stringpool_str1552[sizeof("gifu.gifu.jp")];
+    char stringpool_str1553[sizeof("aya.miyazaki.jp")];
+    char stringpool_str1554[sizeof("aseral.no")];
+    char stringpool_str1555[sizeof("noto.ishikawa.jp")];
+    char stringpool_str1556[sizeof("vi")];
+    char stringpool_str1557[sizeof("gdansk.pl")];
+    char stringpool_str1558[sizeof("ven.it")];
+    char stringpool_str1559[sizeof("halden.no")];
+    char stringpool_str1560[sizeof("is-a-knight.org")];
+    char stringpool_str1561[sizeof("bashkiria.ru")];
+    char stringpool_str1562[sizeof("ivano-frankivsk.ua")];
+    char stringpool_str1563[sizeof("vda.it")];
+    char stringpool_str1564[sizeof("kushiro.hokkaido.jp")];
+    char stringpool_str1565[sizeof("royrvik.no")];
+    char stringpool_str1566[sizeof("nishitosa.kochi.jp")];
+    char stringpool_str1567[sizeof("andria-trani-barletta.it")];
+    char stringpool_str1568[sizeof("amsterdam.museum")];
+    char stringpool_str1569[sizeof("vet.br")];
+    char stringpool_str1570[sizeof("alto-adige.it")];
+    char stringpool_str1571[sizeof("kamikawa.saitama.jp")];
+    char stringpool_str1572[sizeof("mil.ve")];
+    char stringpool_str1573[sizeof("algard.no")];
+    char stringpool_str1574[sizeof("maison")];
+    char stringpool_str1575[sizeof("yabu.hyogo.jp")];
+    char stringpool_str1576[sizeof("naie.hokkaido.jp")];
+    char stringpool_str1577[sizeof("austrheim.no")];
+    char stringpool_str1578[sizeof("recipes")];
+    char stringpool_str1579[sizeof("meraker.no")];
+    char stringpool_str1580[sizeof("mail.pl")];
+    char stringpool_str1581[sizeof("karatsu.saga.jp")];
+    char stringpool_str1582[sizeof("hatogaya.saitama.jp")];
+    char stringpool_str1583[sizeof("vn")];
+    char stringpool_str1584[sizeof("katsuragi.wakayama.jp")];
+    char stringpool_str1585[sizeof("vega.no")];
+    char stringpool_str1586[sizeof("hemnes.no")];
+    char stringpool_str1587[sizeof("vodka")];
+    char stringpool_str1588[sizeof("ivanovo.ru")];
+    char stringpool_str1589[sizeof("hapmir.no")];
+    char stringpool_str1590[sizeof("mus.br")];
+    char stringpool_str1591[sizeof("kvinesdal.no")];
+    char stringpool_str1592[sizeof("mil.ba")];
+    char stringpool_str1593[sizeof("ena.gifu.jp")];
+    char stringpool_str1594[sizeof("beiarn.no")];
+    char stringpool_str1595[sizeof("berlevag.no")];
+    char stringpool_str1596[sizeof("giehtavuoatna.no")];
+    char stringpool_str1597[sizeof("mil.kr")];
+    char stringpool_str1598[sizeof("baidar.no")];
+    char stringpool_str1599[sizeof("yekaterinburg.ru")];
+    char stringpool_str1600[sizeof("bamble.no")];
+    char stringpool_str1601[sizeof("vaga.no")];
+    char stringpool_str1602[sizeof("kimobetsu.hokkaido.jp")];
+    char stringpool_str1603[sizeof("kaga.ishikawa.jp")];
+    char stringpool_str1604[sizeof("mil.hn")];
+    char stringpool_str1605[sizeof("chattanooga.museum")];
+    char stringpool_str1606[sizeof("kashima.saga.jp")];
+    char stringpool_str1607[sizeof("modalen.no")];
+    char stringpool_str1608[sizeof("chikuma.nagano.jp")];
+    char stringpool_str1609[sizeof("baghdad.museum")];
+    char stringpool_str1610[sizeof("kusatsu.gunma.jp")];
+    char stringpool_str1611[sizeof("himeshima.oita.jp")];
+    char stringpool_str1612[sizeof("emilia-romagna.it")];
+    char stringpool_str1613[sizeof("hvaler.no")];
+    char stringpool_str1614[sizeof("kijo.miyazaki.jp")];
+    char stringpool_str1615[sizeof("nantan.kyoto.jp")];
+    char stringpool_str1616[sizeof("nosegawa.nara.jp")];
+    char stringpool_str1617[sizeof("nesoddtangen.no")];
+    char stringpool_str1618[sizeof("chikusei.ibaraki.jp")];
+    char stringpool_str1619[sizeof("nirasaki.yamanashi.jp")];
+    char stringpool_str1620[sizeof("magadan.ru")];
+    char stringpool_str1621[sizeof("kyotamba.kyoto.jp")];
+    char stringpool_str1622[sizeof("kurgan.ru")];
+    char stringpool_str1623[sizeof("mil.qa")];
+    char stringpool_str1624[sizeof("ug")];
+    char stringpool_str1625[sizeof("v.bg")];
+    char stringpool_str1626[sizeof("villas")];
+    char stringpool_str1627[sizeof("carboniaiglesias.it")];
+    char stringpool_str1628[sizeof("messina.it")];
+    char stringpool_str1629[sizeof("genova.it")];
+    char stringpool_str1630[sizeof("alstahaug.no")];
+    char stringpool_str1631[sizeof("hareid.no")];
+    char stringpool_str1632[sizeof("embetsu.hokkaido.jp")];
+    char stringpool_str1633[sizeof("info.ve")];
+    char stringpool_str1634[sizeof("ginowan.okinawa.jp")];
+    char stringpool_str1635[sizeof("kamiamakusa.kumamoto.jp")];
+    char stringpool_str1636[sizeof("inagawa.hyogo.jp")];
+    char stringpool_str1637[sizeof("aosta-valley.it")];
+    char stringpool_str1638[sizeof("kaho.fukuoka.jp")];
+    char stringpool_str1639[sizeof("kobayashi.miyazaki.jp")];
+    char stringpool_str1640[sizeof("yonabaru.okinawa.jp")];
+    char stringpool_str1641[sizeof("haibara.shizuoka.jp")];
+    char stringpool_str1642[sizeof("drobak.no")];
+    char stringpool_str1643[sizeof("izunokuni.shizuoka.jp")];
+    char stringpool_str1644[sizeof("wiki")];
+    char stringpool_str1645[sizeof("kashihara.nara.jp")];
+    char stringpool_str1646[sizeof("homeunix.org")];
+    char stringpool_str1647[sizeof("cesena-forli.it")];
+    char stringpool_str1648[sizeof("inashiki.ibaraki.jp")];
+    char stringpool_str1649[sizeof("mil.eg")];
+    char stringpool_str1650[sizeof("my")];
+    char stringpool_str1651[sizeof("crew.aero")];
+    char stringpool_str1652[sizeof("mil.iq")];
+    char stringpool_str1653[sizeof("e164.arpa")];
+    char stringpool_str1654[sizeof("chitose.hokkaido.jp")];
+    char stringpool_str1655[sizeof("iwanuma.miyagi.jp")];
+    char stringpool_str1656[sizeof("museum")];
+    char stringpool_str1657[sizeof("rakkestad.no")];
+    char stringpool_str1658[sizeof("vao.it")];
+    char stringpool_str1659[sizeof("komatsu.ishikawa.jp")];
+    char stringpool_str1660[sizeof("groundhandling.aero")];
+    char stringpool_str1661[sizeof("vercelli.it")];
+    char stringpool_str1662[sizeof("center.museum")];
+    char stringpool_str1663[sizeof("hachijo.tokyo.jp")];
+    char stringpool_str1664[sizeof("nishinoshima.shimane.jp")];
+    char stringpool_str1665[sizeof("notogawa.shiga.jp")];
+    char stringpool_str1666[sizeof("marketing")];
+    char stringpool_str1667[sizeof("moareke.no")];
+    char stringpool_str1668[sizeof("mil.km")];
+    char stringpool_str1669[sizeof("motorcycle.museum")];
+    char stringpool_str1670[sizeof("murmansk.ru")];
+    char stringpool_str1671[sizeof("aibetsu.hokkaido.jp")];
+    char stringpool_str1672[sizeof("vang.no")];
+    char stringpool_str1673[sizeof("rahkkeravju.no")];
+    char stringpool_str1674[sizeof("biella.it")];
+    char stringpool_str1675[sizeof("niigata.niigata.jp")];
+    char stringpool_str1676[sizeof("kui.hiroshima.jp")];
+    char stringpool_str1677[sizeof("garden.museum")];
+    char stringpool_str1678[sizeof("chuo.fukuoka.jp")];
+    char stringpool_str1679[sizeof("asakawa.fukushima.jp")];
+    char stringpool_str1680[sizeof("massacarrara.it")];
+    char stringpool_str1681[sizeof("mil.mg")];
+    char stringpool_str1682[sizeof("dyndns-work.com")];
+    char stringpool_str1683[sizeof("chernihiv.ua")];
+    char stringpool_str1684[sizeof("wakayama.jp")];
+    char stringpool_str1685[sizeof("hamamatsu.shizuoka.jp")];
+    char stringpool_str1686[sizeof("amursk.ru")];
+    char stringpool_str1687[sizeof("kopervik.no")];
+    char stringpool_str1688[sizeof("gushikami.okinawa.jp")];
+    char stringpool_str1689[sizeof("ueda.nagano.jp")];
+    char stringpool_str1690[sizeof("akiruno.tokyo.jp")];
+    char stringpool_str1691[sizeof("unbi.ba")];
+    char stringpool_str1692[sizeof("voss.no")];
+    char stringpool_str1693[sizeof("mragowo.pl")];
+    char stringpool_str1694[sizeof("miyazaki.jp")];
+    char stringpool_str1695[sizeof("valle-aosta.it")];
+    char stringpool_str1696[sizeof("malselv.no")];
+    char stringpool_str1697[sizeof("yoshimi.saitama.jp")];
+    char stringpool_str1698[sizeof("yamagata.jp")];
+    char stringpool_str1699[sizeof("wiki.br")];
+    char stringpool_str1700[sizeof("gdynia.pl")];
+    char stringpool_str1701[sizeof("railway.museum")];
+    char stringpool_str1702[sizeof("eiheiji.fukui.jp")];
+    char stringpool_str1703[sizeof("hida.gifu.jp")];
+    char stringpool_str1704[sizeof("horokanai.hokkaido.jp")];
+    char stringpool_str1705[sizeof("github.io")];
+    char stringpool_str1706[sizeof("berlin.museum")];
+    char stringpool_str1707[sizeof("valleeaoste.it")];
+    char stringpool_str1708[sizeof("estate.museum")];
+    char stringpool_str1709[sizeof("karikatur.museum")];
+    char stringpool_str1710[sizeof("nogi.tochigi.jp")];
+    char stringpool_str1711[sizeof("homelinux.net")];
+    char stringpool_str1712[sizeof("historicalsociety.museum")];
+    char stringpool_str1713[sizeof("mil.ng")];
+    char stringpool_str1714[sizeof("kharkiv.ua")];
+    char stringpool_str1715[sizeof("doesntexist.org")];
+    char stringpool_str1716[sizeof("valledaosta.it")];
+    char stringpool_str1717[sizeof("e-burg.ru")];
+    char stringpool_str1718[sizeof("viterbo.it")];
+    char stringpool_str1719[sizeof("karate.museum")];
+    char stringpool_str1720[sizeof("nature.museum")];
+    char stringpool_str1721[sizeof("baikal.ru")];
+    char stringpool_str1722[sizeof("kitahata.saga.jp")];
+    char stringpool_str1723[sizeof("ventures")];
+    char stringpool_str1724[sizeof("bauern.museum")];
+    char stringpool_str1725[sizeof("nagasaki.nagasaki.jp")];
+    char stringpool_str1726[sizeof("kikonai.hokkaido.jp")];
+    char stringpool_str1727[sizeof("magnitka.ru")];
+    char stringpool_str1728[sizeof("hobby-site.org")];
+    char stringpool_str1729[sizeof("abashiri.hokkaido.jp")];
+    char stringpool_str1730[sizeof("akishima.tokyo.jp")];
+    char stringpool_str1731[sizeof("vennesla.no")];
+    char stringpool_str1732[sizeof("brasil.museum")];
+    char stringpool_str1733[sizeof("kvinnherad.no")];
+    char stringpool_str1734[sizeof("chichibu.saitama.jp")];
+    char stringpool_str1735[sizeof("chernivtsi.ua")];
+    char stringpool_str1736[sizeof("crafts.museum")];
+    char stringpool_str1737[sizeof("kamijima.ehime.jp")];
+    char stringpool_str1738[sizeof("kamiichi.toyama.jp")];
+    char stringpool_str1739[sizeof("hachirogata.akita.jp")];
+    char stringpool_str1740[sizeof("kouhoku.saga.jp")];
+    char stringpool_str1741[sizeof("resistance.museum")];
+    char stringpool_str1742[sizeof("whoswho")];
+    char stringpool_str1743[sizeof("iglesiascarbonia.it")];
+    char stringpool_str1744[sizeof("nichinan.miyazaki.jp")];
+    char stringpool_str1745[sizeof("k12.vi")];
+    char stringpool_str1746[sizeof("celtic.museum")];
+    char stringpool_str1747[sizeof("dnsalias.org")];
+    char stringpool_str1748[sizeof("civilaviation.aero")];
+    char stringpool_str1749[sizeof("dyndns-wiki.com")];
+    char stringpool_str1750[sizeof("brunel.museum")];
+    char stringpool_str1751[sizeof("komatsushima.tokushima.jp")];
+    char stringpool_str1752[sizeof("kasumigaura.ibaraki.jp")];
+    char stringpool_str1753[sizeof("rankoshi.hokkaido.jp")];
+    char stringpool_str1754[sizeof("yoro.gifu.jp")];
+    char stringpool_str1755[sizeof("mx")];
+    char stringpool_str1756[sizeof("canada.museum")];
+    char stringpool_str1757[sizeof("malbork.pl")];
+    char stringpool_str1758[sizeof("glogow.pl")];
+    char stringpool_str1759[sizeof("kongsvinger.no")];
+    char stringpool_str1760[sizeof("date.fukushima.jp")];
+    char stringpool_str1761[sizeof("aogashima.tokyo.jp")];
+    char stringpool_str1762[sizeof("red.sv")];
+    char stringpool_str1763[sizeof("naka.hiroshima.jp")];
+    char stringpool_str1764[sizeof("mobi")];
+    char stringpool_str1765[sizeof("usa.oita.jp")];
+    char stringpool_str1766[sizeof("monash")];
+    char stringpool_str1767[sizeof("nagara.chiba.jp")];
+    char stringpool_str1768[sizeof("circus.museum")];
+    char stringpool_str1769[sizeof("xxx")];
+    char stringpool_str1770[sizeof("austevoll.no")];
+    char stringpool_str1771[sizeof("higashiyoshino.nara.jp")];
+    char stringpool_str1772[sizeof("emiliaromagna.it")];
+    char stringpool_str1773[sizeof("higashiosaka.osaka.jp")];
+    char stringpool_str1774[sizeof("mil.az")];
+    char stringpool_str1775[sizeof("georgia.museum")];
+    char stringpool_str1776[sizeof("naturbruksgymn.se")];
+    char stringpool_str1777[sizeof("katashina.gunma.jp")];
+    char stringpool_str1778[sizeof("mil.tz")];
+    char stringpool_str1779[sizeof("alaheadju.no")];
+    char stringpool_str1780[sizeof("mobi.na")];
+    char stringpool_str1781[sizeof("koenig.ru")];
+    char stringpool_str1782[sizeof("aoki.nagano.jp")];
+    char stringpool_str1783[sizeof("vallee-aoste.it")];
+    char stringpool_str1784[sizeof("british-library.uk")];
+    char stringpool_str1785[sizeof("marburg.museum")];
+    char stringpool_str1786[sizeof("andriatranibarletta.it")];
+    char stringpool_str1787[sizeof("homelinux.org")];
+    char stringpool_str1788[sizeof("gonohe.aomori.jp")];
+    char stringpool_str1789[sizeof("kushima.miyazaki.jp")];
+    char stringpool_str1790[sizeof("royken.no")];
+    char stringpool_str1791[sizeof("minnesota.museum")];
+    char stringpool_str1792[sizeof("koshimizu.hokkaido.jp")];
+    char stringpool_str1793[sizeof("nishimera.miyazaki.jp")];
+    char stringpool_str1794[sizeof("mil.kg")];
+    char stringpool_str1795[sizeof("modelling.aero")];
+    char stringpool_str1796[sizeof("valled-aosta.it")];
+    char stringpool_str1797[sizeof("dallas.museum")];
+    char stringpool_str1798[sizeof("ancona.it")];
+    char stringpool_str1799[sizeof("moskenes.no")];
+    char stringpool_str1800[sizeof("higashiizu.shizuoka.jp")];
+    char stringpool_str1801[sizeof("kadoma.osaka.jp")];
+    char stringpool_str1802[sizeof("urakawa.hokkaido.jp")];
+    char stringpool_str1803[sizeof("uscountryestate.museum")];
+    char stringpool_str1804[sizeof("kitaaiki.nagano.jp")];
+    char stringpool_str1805[sizeof("media")];
+    char stringpool_str1806[sizeof("mg")];
+    char stringpool_str1807[sizeof("matsubara.osaka.jp")];
+    char stringpool_str1808[sizeof("biei.hokkaido.jp")];
+    char stringpool_str1809[sizeof("voronezh.ru")];
+    char stringpool_str1810[sizeof("boston.museum")];
+    char stringpool_str1811[sizeof("elblag.pl")];
+    char stringpool_str1812[sizeof("yame.fukuoka.jp")];
+    char stringpool_str1813[sizeof("kuromatsunai.hokkaido.jp")];
+    char stringpool_str1814[sizeof("vinnica.ua")];
+    char stringpool_str1815[sizeof("dynalias.org")];
+    char stringpool_str1816[sizeof("izumozaki.niigata.jp")];
+    char stringpool_str1817[sizeof("mini")];
+    char stringpool_str1818[sizeof("is-a-linux-user.org")];
+    char stringpool_str1819[sizeof("mobi.ng")];
+    char stringpool_str1820[sizeof("kinokawa.wakayama.jp")];
+    char stringpool_str1821[sizeof("rindal.no")];
+    char stringpool_str1822[sizeof("ryokami.saitama.jp")];
+    char stringpool_str1823[sizeof("vindafjord.no")];
+    char stringpool_str1824[sizeof("nishiarita.saga.jp")];
+    char stringpool_str1825[sizeof("crimea.ua")];
+    char stringpool_str1826[sizeof("hakusan.ishikawa.jp")];
+    char stringpool_str1827[sizeof("ushuaia.museum")];
+    char stringpool_str1828[sizeof("namegata.ibaraki.jp")];
+    char stringpool_str1829[sizeof("higashiizumo.shimane.jp")];
+    char stringpool_str1830[sizeof("hokkaido.jp")];
+    char stringpool_str1831[sizeof("wakkanai.hokkaido.jp")];
+    char stringpool_str1832[sizeof("gangaviika.no")];
+    char stringpool_str1833[sizeof("vlog.br")];
+    char stringpool_str1834[sizeof("childrensgarden.museum")];
+    char stringpool_str1835[sizeof("valleaosta.it")];
+    char stringpool_str1836[sizeof("namikata.ehime.jp")];
+    char stringpool_str1837[sizeof("napoli.it")];
+    char stringpool_str1838[sizeof("mobi.tz")];
+    char stringpool_str1839[sizeof("yoka.hyogo.jp")];
+    char stringpool_str1840[sizeof("gwangju.kr")];
+    char stringpool_str1841[sizeof("karuizawa.nagano.jp")];
+    char stringpool_str1842[sizeof("hellas.museum")];
+    char stringpool_str1843[sizeof("mil.sh")];
+    char stringpool_str1844[sizeof("aioi.hyogo.jp")];
+    char stringpool_str1845[sizeof("nationalheritage.museum")];
+    char stringpool_str1846[sizeof("hayakawa.yamanashi.jp")];
+    char stringpool_str1847[sizeof("matsudo.chiba.jp")];
+    char stringpool_str1848[sizeof("mil.ph")];
+    char stringpool_str1849[sizeof("mine.nu")];
+    char stringpool_str1850[sizeof("cinema.museum")];
+    char stringpool_str1851[sizeof("yoshida.shizuoka.jp")];
+    char stringpool_str1852[sizeof("verbania.it")];
+    char stringpool_str1853[sizeof("viajes")];
+    char stringpool_str1854[sizeof("higashimatsuyama.saitama.jp")];
+    char stringpool_str1855[sizeof("habikino.osaka.jp")];
+    char stringpool_str1856[sizeof("muko.kyoto.jp")];
+    char stringpool_str1857[sizeof("kimitsu.chiba.jp")];
+    char stringpool_str1858[sizeof("drangedal.no")];
+    char stringpool_str1859[sizeof("hamada.shimane.jp")];
+    char stringpool_str1860[sizeof("kanonji.kagawa.jp")];
+    char stringpool_str1861[sizeof("haebaru.okinawa.jp")];
+    char stringpool_str1862[sizeof("civilization.museum")];
+    char stringpool_str1863[sizeof("kyuragi.saga.jp")];
+    char stringpool_str1864[sizeof("agrinet.tn")];
+    char stringpool_str1865[sizeof("vestnes.no")];
+    char stringpool_str1866[sizeof("hannan.osaka.jp")];
+    char stringpool_str1867[sizeof("vald-aosta.it")];
+    char stringpool_str1868[sizeof("jogasz.hu")];
+    char stringpool_str1869[sizeof("ureshino.mie.jp")];
+    char stringpool_str1870[sizeof("nationalfirearms.museum")];
+    char stringpool_str1871[sizeof("mari-el.ru")];
+    char stringpool_str1872[sizeof("kamikawa.hokkaido.jp")];
+    char stringpool_str1873[sizeof("kitanakagusuku.okinawa.jp")];
+    char stringpool_str1874[sizeof("amagasaki.hyogo.jp")];
+    char stringpool_str1875[sizeof("unjarga.no")];
+    char stringpool_str1876[sizeof("nishikatsura.yamanashi.jp")];
+    char stringpool_str1877[sizeof("asahikawa.hokkaido.jp")];
+    char stringpool_str1878[sizeof("kushimoto.wakayama.jp")];
+    char stringpool_str1879[sizeof("vladimir.ru")];
+    char stringpool_str1880[sizeof("virtuel.museum")];
+    char stringpool_str1881[sizeof("mil.gt")];
+    char stringpool_str1882[sizeof("kitakata.miyazaki.jp")];
+    char stringpool_str1883[sizeof("kurashiki.okayama.jp")];
+    char stringpool_str1884[sizeof("monticello.museum")];
+    char stringpool_str1885[sizeof("civilisation.museum")];
+    char stringpool_str1886[sizeof("wielun.pl")];
+    char stringpool_str1887[sizeof("kani.gifu.jp")];
+    char stringpool_str1888[sizeof("gotdns.org")];
+    char stringpool_str1889[sizeof("mil.kz")];
+    char stringpool_str1890[sizeof("vaksdal.no")];
+    char stringpool_str1891[sizeof("nishihara.kumamoto.jp")];
+    char stringpool_str1892[sizeof("venezia.it")];
+    char stringpool_str1893[sizeof("se")];
+    char stringpool_str1894[sizeof("mosjoen.no")];
+    char stringpool_str1895[sizeof("sd")];
+    char stringpool_str1896[sizeof("so")];
+    char stringpool_str1897[sizeof("soy")];
+    char stringpool_str1898[sizeof("ushistory.museum")];
+    char stringpool_str1899[sizeof("ishikawa.okinawa.jp")];
+    char stringpool_str1900[sizeof("goshiki.hyogo.jp")];
+    char stringpool_str1901[sizeof("chonan.chiba.jp")];
+    char stringpool_str1902[sizeof("gujo.gifu.jp")];
+    char stringpool_str1903[sizeof("ralingen.no")];
+    char stringpool_str1904[sizeof("austin.museum")];
+    char stringpool_str1905[sizeof("engineering")];
+    char stringpool_str1906[sizeof("mil.ge")];
+    char stringpool_str1907[sizeof("kitayama.wakayama.jp")];
+    char stringpool_str1908[sizeof("kudoyama.wakayama.jp")];
+    char stringpool_str1909[sizeof("sa")];
+    char stringpool_str1910[sizeof("midsund.no")];
+    char stringpool_str1911[sizeof("yoshikawa.saitama.jp")];
+    char stringpool_str1912[sizeof("macerata.it")];
+    char stringpool_str1913[sizeof("st")];
+    char stringpool_str1914[sizeof("nishikata.tochigi.jp")];
+    char stringpool_str1915[sizeof("higashi.okinawa.jp")];
+    char stringpool_str1916[sizeof("kagawa.jp")];
+    char stringpool_str1917[sizeof("ishikari.hokkaido.jp")];
+    char stringpool_str1918[sizeof("sr")];
+    char stringpool_str1919[sizeof("katori.chiba.jp")];
+    char stringpool_str1920[sizeof("jinsekikogen.hiroshima.jp")];
+    char stringpool_str1921[sizeof("su")];
+    char stringpool_str1922[sizeof("chikujo.fukuoka.jp")];
+    char stringpool_str1923[sizeof("higashiyama.kyoto.jp")];
+    char stringpool_str1924[sizeof("sz")];
+    char stringpool_str1925[sizeof("kami.miyagi.jp")];
+    char stringpool_str1926[sizeof("castle.museum")];
+    char stringpool_str1927[sizeof("aomori.aomori.jp")];
+    char stringpool_str1928[sizeof("numata.gunma.jp")];
+    char stringpool_str1929[sizeof("namerikawa.toyama.jp")];
+    char stringpool_str1930[sizeof("kagoshima.kagoshima.jp")];
+    char stringpool_str1931[sizeof("aga.niigata.jp")];
+    char stringpool_str1932[sizeof("virtual.museum")];
+    char stringpool_str1933[sizeof("ragusa.it")];
+    char stringpool_str1934[sizeof("sj")];
+    char stringpool_str1935[sizeof("aomori.jp")];
+    char stringpool_str1936[sizeof("daisen.akita.jp")];
+    char stringpool_str1937[sizeof("kashiwazaki.niigata.jp")];
+    char stringpool_str1938[sizeof("nabari.mie.jp")];
+    char stringpool_str1939[sizeof("sm")];
+    char stringpool_str1940[sizeof("nachikatsuura.wakayama.jp")];
+    char stringpool_str1941[sizeof("vestre-toten.no")];
+    char stringpool_str1942[sizeof("nishiizu.shizuoka.jp")];
+    char stringpool_str1943[sizeof("matsumoto.nagano.jp")];
+    char stringpool_str1944[sizeof("vg")];
+    char stringpool_str1945[sizeof("mo-i-rana.no")];
+    char stringpool_str1946[sizeof("nomi.ishikawa.jp")];
+    char stringpool_str1947[sizeof("chungbuk.kr")];
+    char stringpool_str1948[sizeof("volkenkunde.museum")];
+    char stringpool_str1949[sizeof("kuchinotsu.nagasaki.jp")];
+    char stringpool_str1950[sizeof("kayabe.hokkaido.jp")];
+    char stringpool_str1951[sizeof("yamashina.kyoto.jp")];
+    char stringpool_str1952[sizeof("archaeology.museum")];
+    char stringpool_str1953[sizeof("si")];
+    char stringpool_str1954[sizeof("uryu.hokkaido.jp")];
+    char stringpool_str1955[sizeof("is-a-soxfan.org")];
+    char stringpool_str1956[sizeof("warmia.pl")];
+    char stringpool_str1957[sizeof("raholt.no")];
+    char stringpool_str1958[sizeof("mobi.tt")];
+    char stringpool_str1959[sizeof("mobi.gp")];
+    char stringpool_str1960[sizeof("matta-varjjat.no")];
+    char stringpool_str1961[sizeof("vacations")];
+    char stringpool_str1962[sizeof("kuji.iwate.jp")];
+    char stringpool_str1963[sizeof("sb")];
+    char stringpool_str1964[sizeof("nishiawakura.okayama.jp")];
+    char stringpool_str1965[sizeof("elburg.museum")];
+    char stringpool_str1966[sizeof("solar")];
+    char stringpool_str1967[sizeof("kiyose.tokyo.jp")];
+    char stringpool_str1968[sizeof("kumiyama.kyoto.jp")];
+    char stringpool_str1969[sizeof("rifu.miyagi.jp")];
+    char stringpool_str1970[sizeof("wegrow.pl")];
+    char stringpool_str1971[sizeof("vevelstad.no")];
+    char stringpool_str1972[sizeof("stat.no")];
+    char stringpool_str1973[sizeof("sund.no")];
+    char stringpool_str1974[sizeof("kusatsu.shiga.jp")];
+    char stringpool_str1975[sizeof("sar.it")];
+    char stringpool_str1976[sizeof("sn")];
+    char stringpool_str1977[sizeof("numata.hokkaido.jp")];
+    char stringpool_str1978[sizeof("kamikawa.hyogo.jp")];
+    char stringpool_str1979[sizeof("sola.no")];
+    char stringpool_str1980[sizeof("kurobe.toyama.jp")];
+    char stringpool_str1981[sizeof("kuriyama.hokkaido.jp")];
+    char stringpool_str1982[sizeof("voyage")];
+    char stringpool_str1983[sizeof("rollag.no")];
+    char stringpool_str1984[sizeof("kamikitayama.nara.jp")];
+    char stringpool_str1985[sizeof("yamanashi.yamanashi.jp")];
+    char stringpool_str1986[sizeof("srv.br")];
+    char stringpool_str1987[sizeof("volgograd.ru")];
+    char stringpool_str1988[sizeof("aostavalley.it")];
+    char stringpool_str1989[sizeof("christiansburg.museum")];
+    char stringpool_str1990[sizeof("sl")];
+    char stringpool_str1991[sizeof("kakegawa.shizuoka.jp")];
+    char stringpool_str1992[sizeof("saga.jp")];
+    char stringpool_str1993[sizeof("sec.ps")];
+    char stringpool_str1994[sizeof("sv")];
+    char stringpool_str1995[sizeof("vestvagoy.no")];
+    char stringpool_str1996[sizeof("nishiazai.shiga.jp")];
+    char stringpool_str1997[sizeof("sohu")];
+    char stringpool_str1998[sizeof("hashimoto.wakayama.jp")];
+    char stringpool_str1999[sizeof("is-saved.org")];
+    char stringpool_str2000[sizeof("mima.tokushima.jp")];
+    char stringpool_str2001[sizeof("ryugasaki.ibaraki.jp")];
+    char stringpool_str2002[sizeof("kitagata.saga.jp")];
+    char stringpool_str2003[sizeof("avoues.fr")];
+    char stringpool_str2004[sizeof("sula.no")];
+    char stringpool_str2005[sizeof("alaska.museum")];
+    char stringpool_str2006[sizeof("kadogawa.miyazaki.jp")];
+    char stringpool_str2007[sizeof("discovery.museum")];
+    char stringpool_str2008[sizeof("agematsu.nagano.jp")];
+    char stringpool_str2009[sizeof("missile.museum")];
+    char stringpool_str2010[sizeof("ueno.gunma.jp")];
+    char stringpool_str2011[sizeof("kiyokawa.kanagawa.jp")];
+    char stringpool_str2012[sizeof("higashiyamato.tokyo.jp")];
+    char stringpool_str2013[sizeof("kikugawa.shizuoka.jp")];
+    char stringpool_str2014[sizeof("dyndns.tv")];
+    char stringpool_str2015[sizeof("s.bg")];
+    char stringpool_str2016[sizeof("nagoya.jp")];
+    char stringpool_str2017[sizeof("kaneyama.yamagata.jp")];
+    char stringpool_str2018[sizeof("durham.museum")];
+    char stringpool_str2019[sizeof("ujitawara.kyoto.jp")];
+    char stringpool_str2020[sizeof("aejrie.no")];
+    char stringpool_str2021[sizeof("hayashima.okayama.jp")];
+    char stringpool_str2022[sizeof("chikuhoku.nagano.jp")];
+    char stringpool_str2023[sizeof("kitagawa.miyazaki.jp")];
+    char stringpool_str2024[sizeof("kanegasaki.iwate.jp")];
+    char stringpool_str2025[sizeof("fo")];
+    char stringpool_str2026[sizeof("nakasatsunai.hokkaido.jp")];
+    char stringpool_str2027[sizeof("net.so")];
+    char stringpool_str2028[sizeof("net.do")];
+    char stringpool_str2029[sizeof("com.so")];
+    char stringpool_str2030[sizeof("noheji.aomori.jp")];
+    char stringpool_str2031[sizeof("com.do")];
+    char stringpool_str2032[sizeof("gov.do")];
+    char stringpool_str2033[sizeof("stranda.no")];
+    char stringpool_str2034[sizeof("hasama.oita.jp")];
+    char stringpool_str2035[sizeof("gliwice.pl")];
+    char stringpool_str2036[sizeof("gob.do")];
+    char stringpool_str2037[sizeof("rishiri.hokkaido.jp")];
+    char stringpool_str2038[sizeof("kaluga.ru")];
+    char stringpool_str2039[sizeof("moroyama.saitama.jp")];
+    char stringpool_str2040[sizeof("kyonan.chiba.jp")];
+    char stringpool_str2041[sizeof("kosaka.akita.jp")];
+    char stringpool_str2042[sizeof("hanggliding.aero")];
+    char stringpool_str2043[sizeof("vladikavkaz.ru")];
+    char stringpool_str2044[sizeof("mito.ibaraki.jp")];
+    char stringpool_str2045[sizeof("vologda.ru")];
+    char stringpool_str2046[sizeof("yonezawa.yamagata.jp")];
+    char stringpool_str2047[sizeof("avocat.fr")];
+    char stringpool_str2048[sizeof("edu.do")];
+    char stringpool_str2049[sizeof("yamanakako.yamanashi.jp")];
+    char stringpool_str2050[sizeof("fan")];
+    char stringpool_str2051[sizeof("camp")];
+    char stringpool_str2052[sizeof("farm")];
+    char stringpool_str2053[sizeof("sos.pl")];
+    char stringpool_str2054[sizeof("nakagawa.hokkaido.jp")];
+    char stringpool_str2055[sizeof("fam.pk")];
+    char stringpool_str2056[sizeof("net.to")];
+    char stringpool_str2057[sizeof("fr")];
+    char stringpool_str2058[sizeof("sk")];
+    char stringpool_str2059[sizeof("com.to")];
+    char stringpool_str2060[sizeof("gov.to")];
+    char stringpool_str2061[sizeof("chijiwa.nagasaki.jp")];
+    char stringpool_str2062[sizeof("nishihara.okinawa.jp")];
+    char stringpool_str2063[sizeof("yomitan.okinawa.jp")];
+    char stringpool_str2064[sizeof("karlsoy.no")];
+    char stringpool_str2065[sizeof("kitahiroshima.hokkaido.jp")];
+    char stringpool_str2066[sizeof("company")];
+    char stringpool_str2067[sizeof("com.ro")];
+    char stringpool_str2068[sizeof("sh")];
+    char stringpool_str2069[sizeof("hiraizumi.iwate.jp")];
+    char stringpool_str2070[sizeof("exeter.museum")];
+    char stringpool_str2071[sizeof("nom.ro")];
+    char stringpool_str2072[sizeof("saltdal.no")];
+    char stringpool_str2073[sizeof("dvrdns.org")];
+    char stringpool_str2074[sizeof("bahcavuotna.no")];
+    char stringpool_str2075[sizeof("kotohira.kagawa.jp")];
+    char stringpool_str2076[sizeof("edu.to")];
+    char stringpool_str2077[sizeof("fj")];
+    char stringpool_str2078[sizeof("ayagawa.kagawa.jp")];
+    char stringpool_str2079[sizeof("ashibetsu.hokkaido.jp")];
+    char stringpool_str2080[sizeof("ninomiya.kanagawa.jp")];
+    char stringpool_str2081[sizeof("quebec.museum")];
+    char stringpool_str2082[sizeof("net.jo")];
+    char stringpool_str2083[sizeof("fm")];
+    char stringpool_str2084[sizeof("yamagata.ibaraki.jp")];
+    char stringpool_str2085[sizeof("com.jo")];
+    char stringpool_str2086[sizeof("gov.jo")];
+    char stringpool_str2087[sizeof("hasuda.saitama.jp")];
+    char stringpool_str2088[sizeof("net.mo")];
+    char stringpool_str2089[sizeof("s.se")];
+    char stringpool_str2090[sizeof("com.mo")];
+    char stringpool_str2091[sizeof("gov.mo")];
+    char stringpool_str2092[sizeof("matsuda.kanagawa.jp")];
+    char stringpool_str2093[sizeof("kesennuma.miyagi.jp")];
+    char stringpool_str2094[sizeof("wassamu.hokkaido.jp")];
+    char stringpool_str2095[sizeof("niki.hokkaido.jp")];
+    char stringpool_str2096[sizeof("kunigami.okinawa.jp")];
+    char stringpool_str2097[sizeof("edu.jo")];
+    char stringpool_str2098[sizeof("fi")];
+    char stringpool_str2099[sizeof("higashiomi.shiga.jp")];
+    char stringpool_str2100[sizeof("anamizu.ishikawa.jp")];
+    char stringpool_str2101[sizeof("fin.ec")];
+    char stringpool_str2102[sizeof("edu.mo")];
+    char stringpool_str2103[sizeof("kamishihoro.hokkaido.jp")];
+    char stringpool_str2104[sizeof("soc.lk")];
+    char stringpool_str2105[sizeof("com.io")];
+    char stringpool_str2106[sizeof("art.do")];
+    char stringpool_str2107[sizeof("salerno.it")];
+    char stringpool_str2108[sizeof("fed.us")];
+    char stringpool_str2109[sizeof("chikugo.fukuoka.jp")];
+    char stringpool_str2110[sizeof("slg.br")];
+    char stringpool_str2111[sizeof("net.bo")];
+    char stringpool_str2112[sizeof("fst.br")];
+    char stringpool_str2113[sizeof("com.bo")];
+    char stringpool_str2114[sizeof("gov.bo")];
+    char stringpool_str2115[sizeof("fot.br")];
+    char stringpool_str2116[sizeof("chieti.it")];
+    char stringpool_str2117[sizeof("sunndal.no")];
+    char stringpool_str2118[sizeof("foo")];
+    char stringpool_str2119[sizeof("coop")];
+    char stringpool_str2120[sizeof("gob.bo")];
+    char stringpool_str2121[sizeof("marnardal.no")];
+    char stringpool_str2122[sizeof("kamiizumi.saitama.jp")];
+    char stringpool_str2123[sizeof("sogndal.no")];
+    char stringpool_str2124[sizeof("sic.it")];
+    char stringpool_str2125[sizeof("kunohe.iwate.jp")];
+    char stringpool_str2126[sizeof("akkeshi.hokkaido.jp")];
+    char stringpool_str2127[sizeof("chosei.chiba.jp")];
+    char stringpool_str2128[sizeof("nishinoomote.kagoshima.jp")];
+    char stringpool_str2129[sizeof("kainan.tokushima.jp")];
+    char stringpool_str2130[sizeof("hinode.tokyo.jp")];
+    char stringpool_str2131[sizeof("vision")];
+    char stringpool_str2132[sizeof("mod.gi")];
+    char stringpool_str2133[sizeof("edu.bo")];
+    char stringpool_str2134[sizeof("mibu.tochigi.jp")];
+    char stringpool_str2135[sizeof("heguri.nara.jp")];
+    char stringpool_str2136[sizeof("coop.py")];
+    char stringpool_str2137[sizeof("far.br")];
+    char stringpool_str2138[sizeof("fin.tn")];
+    char stringpool_str2139[sizeof("vicenza.it")];
+    char stringpool_str2140[sizeof("sld.pa")];
+    char stringpool_str2141[sizeof("nakagawa.tokushima.jp")];
+    char stringpool_str2142[sizeof("coop.km")];
+    char stringpool_str2143[sizeof("health.vn")];
+    char stringpool_str2144[sizeof("naoshima.kagawa.jp")];
+    char stringpool_str2145[sizeof("nishiwaki.hyogo.jp")];
+    char stringpool_str2146[sizeof("mediocampidano.it")];
+    char stringpool_str2147[sizeof("fie.ee")];
+    char stringpool_str2148[sizeof("sells-for-u.com")];
+    char stringpool_str2149[sizeof("yashiro.hyogo.jp")];
+    char stringpool_str2150[sizeof("midtre-gauldal.no")];
+    char stringpool_str2151[sizeof("chigasaki.kanagawa.jp")];
+    char stringpool_str2152[sizeof("firm.ro")];
+    char stringpool_str2153[sizeof("firm.co")];
+    char stringpool_str2154[sizeof("narita.chiba.jp")];
+    char stringpool_str2155[sizeof("murakami.niigata.jp")];
+    char stringpool_str2156[sizeof("muroran.hokkaido.jp")];
+    char stringpool_str2157[sizeof("ninohe.iwate.jp")];
+    char stringpool_str2158[sizeof("johana.toyama.jp")];
+    char stringpool_str2159[sizeof("yoshinogari.saga.jp")];
+    char stringpool_str2160[sizeof("aquila.it")];
+    char stringpool_str2161[sizeof("sandnes.no")];
+    char stringpool_str2162[sizeof("jorpeland.no")];
+    char stringpool_str2163[sizeof("gojome.akita.jp")];
+    char stringpool_str2164[sizeof("agrigento.it")];
+    char stringpool_str2165[sizeof("miyashiro.saitama.jp")];
+    char stringpool_str2166[sizeof("gol.no")];
+    char stringpool_str2167[sizeof("hamura.tokyo.jp")];
+    char stringpool_str2168[sizeof("miho.ibaraki.jp")];
+    char stringpool_str2169[sizeof("f.bg")];
+    char stringpool_str2170[sizeof("annaka.gunma.jp")];
+    char stringpool_str2171[sizeof("usenet.pl")];
+    char stringpool_str2172[sizeof("rikuzentakata.iwate.jp")];
+    char stringpool_str2173[sizeof("shoes")];
+    char stringpool_str2174[sizeof("hidaka.saitama.jp")];
+    char stringpool_str2175[sizeof("futbol")];
+    char stringpool_str2176[sizeof("arq.br")];
+    char stringpool_str2177[sizeof("bifuka.hokkaido.jp")];
+    char stringpool_str2178[sizeof("itoigawa.niigata.jp")];
+    char stringpool_str2179[sizeof("iwamizawa.hokkaido.jp")];
+    char stringpool_str2180[sizeof("skedsmo.no")];
+    char stringpool_str2181[sizeof("atsuma.hokkaido.jp")];
+    char stringpool_str2182[sizeof("firm.nf")];
+    char stringpool_str2183[sizeof("control.aero")];
+    char stringpool_str2184[sizeof("fuossko.no")];
+    char stringpool_str2185[sizeof("folldal.no")];
+    char stringpool_str2186[sizeof("vic.edu.au")];
+    char stringpool_str2187[sizeof("sells-it.net")];
+    char stringpool_str2188[sizeof("sandefjord.no")];
+    char stringpool_str2189[sizeof("kakogawa.hyogo.jp")];
+    char stringpool_str2190[sizeof("coop.br")];
+    char stringpool_str2191[sizeof("surnadal.no")];
+    char stringpool_str2192[sizeof("indian.museum")];
+    char stringpool_str2193[sizeof("int.bo")];
+    char stringpool_str2194[sizeof("nakaniikawa.toyama.jp")];
+    char stringpool_str2195[sizeof("vinnytsia.ua")];
+    char stringpool_str2196[sizeof("voting")];
+    char stringpool_str2197[sizeof("mandal.no")];
+    char stringpool_str2198[sizeof("fk")];
+    char stringpool_str2199[sizeof("dep.no")];
+    char stringpool_str2200[sizeof("from-la.net")];
+    char stringpool_str2201[sizeof("higashihiroshima.hiroshima.jp")];
+    char stringpool_str2202[sizeof("mari.ru")];
+    char stringpool_str2203[sizeof("mombetsu.hokkaido.jp")];
+    char stringpool_str2204[sizeof("yuki.ibaraki.jp")];
+    char stringpool_str2205[sizeof("higashikawa.hokkaido.jp")];
+    char stringpool_str2206[sizeof("inderoy.no")];
+    char stringpool_str2207[sizeof("sy")];
+    char stringpool_str2208[sizeof("from-ny.net")];
+    char stringpool_str2209[sizeof("valle-daosta.it")];
+    char stringpool_str2210[sizeof("sondre-land.no")];
+    char stringpool_str2211[sizeof("meldal.no")];
+    char stringpool_str2212[sizeof("marker.no")];
+    char stringpool_str2213[sizeof("eid.no")];
+    char stringpool_str2214[sizeof("higashi.fukuoka.jp")];
+    char stringpool_str2215[sizeof("fnd.br")];
+    char stringpool_str2216[sizeof("itoman.okinawa.jp")];
+    char stringpool_str2217[sizeof("veterinaire.km")];
+    char stringpool_str2218[sizeof("matsumoto.kagoshima.jp")];
+    char stringpool_str2219[sizeof("f.se")];
+    char stringpool_str2220[sizeof("from-ky.com")];
+    char stringpool_str2221[sizeof("from-tx.com")];
+    char stringpool_str2222[sizeof("from-wy.com")];
+    char stringpool_str2223[sizeof("mashiki.kumamoto.jp")];
+    char stringpool_str2224[sizeof("from-pa.com")];
+    char stringpool_str2225[sizeof("from-ca.com")];
+    char stringpool_str2226[sizeof("from-wa.com")];
+    char stringpool_str2227[sizeof("from-co.net")];
+    char stringpool_str2228[sizeof("sauherad.no")];
+    char stringpool_str2229[sizeof("health.museum")];
+    char stringpool_str2230[sizeof("miyoshi.saitama.jp")];
+    char stringpool_str2231[sizeof("village.museum")];
+    char stringpool_str2232[sizeof("minamata.kumamoto.jp")];
+    char stringpool_str2233[sizeof("coop.mw")];
+    char stringpool_str2234[sizeof("from-nm.com")];
+    char stringpool_str2235[sizeof("iiyama.nagano.jp")];
+    char stringpool_str2236[sizeof("dyndns.ws")];
+    char stringpool_str2237[sizeof("fvg.it")];
+    char stringpool_str2238[sizeof("fhv.se")];
+    char stringpool_str2239[sizeof("mantova.it")];
+    char stringpool_str2240[sizeof("computer")];
+    char stringpool_str2241[sizeof("campobasso.it")];
+    char stringpool_str2242[sizeof("joboji.iwate.jp")];
+    char stringpool_str2243[sizeof("kitami.hokkaido.jp")];
+    char stringpool_str2244[sizeof("sardinia.it")];
+    char stringpool_str2245[sizeof("hamaroy.no")];
+    char stringpool_str2246[sizeof("ishigaki.okinawa.jp")];
+    char stringpool_str2247[sizeof("student.aero")];
+    char stringpool_str2248[sizeof("kasamatsu.gifu.jp")];
+    char stringpool_str2249[sizeof("siellak.no")];
+    char stringpool_str2250[sizeof("sevastopol.ua")];
+    char stringpool_str2251[sizeof("yamada.toyama.jp")];
+    char stringpool_str2252[sizeof("stordal.no")];
+    char stringpool_str2253[sizeof("sebastopol.ua")];
+    char stringpool_str2254[sizeof("from-pr.com")];
+    char stringpool_str2255[sizeof("sassari.it")];
+    char stringpool_str2256[sizeof("fail")];
+    char stringpool_str2257[sizeof("dyndns.org")];
+    char stringpool_str2258[sizeof("kalisz.pl")];
+    char stringpool_str2259[sizeof("flakstad.no")];
+    char stringpool_str2260[sizeof("fusa.no")];
+    char stringpool_str2261[sizeof("misconfused.org")];
+    char stringpool_str2262[sizeof("gripe")];
+    char stringpool_str2263[sizeof("nishigo.fukushima.jp")];
+    char stringpool_str2264[sizeof("matsubushi.saitama.jp")];
+    char stringpool_str2265[sizeof("nakagawa.nagano.jp")];
+    char stringpool_str2266[sizeof("saga.saga.jp")];
+    char stringpool_str2267[sizeof("from-nj.com")];
+    char stringpool_str2268[sizeof("hirogawa.wakayama.jp")];
+    char stringpool_str2269[sizeof("valle-d-aosta.it")];
+    char stringpool_str2270[sizeof("ferrara.it")];
+    char stringpool_str2271[sizeof("rikubetsu.hokkaido.jp")];
+    char stringpool_str2272[sizeof("yamada.iwate.jp")];
+    char stringpool_str2273[sizeof("wakasa.tottori.jp")];
+    char stringpool_str2274[sizeof("machida.tokyo.jp")];
+    char stringpool_str2275[sizeof("muosat.no")];
+    char stringpool_str2276[sizeof("aridagawa.wakayama.jp")];
+    char stringpool_str2277[sizeof("k12.sc.us")];
+    char stringpool_str2278[sizeof("choshi.chiba.jp")];
+    char stringpool_str2279[sizeof("mil.mv")];
+    char stringpool_str2280[sizeof("k12.dc.us")];
+    char stringpool_str2281[sizeof("k12.ok.us")];
+    char stringpool_str2282[sizeof("santacruz.museum")];
+    char stringpool_str2283[sizeof("k12.or.us")];
+    char stringpool_str2284[sizeof("reklam.hu")];
+    char stringpool_str2285[sizeof("kiyama.saga.jp")];
+    char stringpool_str2286[sizeof("k12.pr.us")];
+    char stringpool_str2287[sizeof("ginoza.okinawa.jp")];
+    char stringpool_str2288[sizeof("fitness")];
+    char stringpool_str2289[sizeof("sortland.no")];
+    char stringpool_str2290[sizeof("yokote.akita.jp")];
+    char stringpool_str2291[sizeof("saotome.st")];
+    char stringpool_str2292[sizeof("svalbard.no")];
+    char stringpool_str2293[sizeof("hof.no")];
+    char stringpool_str2294[sizeof("from-ma.com")];
+    char stringpool_str2295[sizeof("smolensk.ru")];
+    char stringpool_str2296[sizeof("meland.no")];
+    char stringpool_str2297[sizeof("bronnoy.no")];
+    char stringpool_str2298[sizeof("rybnik.pl")];
+    char stringpool_str2299[sizeof("k12.al.us")];
+    char stringpool_str2300[sizeof("k12.ak.us")];
+    char stringpool_str2301[sizeof("k12.ar.us")];
+    char stringpool_str2302[sizeof("hol.no")];
+    char stringpool_str2303[sizeof("uenohara.yamanashi.jp")];
+    char stringpool_str2304[sizeof("k12.as.us")];
+    char stringpool_str2305[sizeof("higashisumiyoshi.osaka.jp")];
+    char stringpool_str2306[sizeof("matsukawa.nagano.jp")];
+    char stringpool_str2307[sizeof("k12.tn.us")];
+    char stringpool_str2308[sizeof("esashi.hokkaido.jp")];
+    char stringpool_str2309[sizeof("nakayama.yamagata.jp")];
+    char stringpool_str2310[sizeof("mil.gh")];
+    char stringpool_str2311[sizeof("singles")];
+    char stringpool_str2312[sizeof("moseushi.hokkaido.jp")];
+    char stringpool_str2313[sizeof("k12.ut.us")];
+    char stringpool_str2314[sizeof("from-tn.com")];
+    char stringpool_str2315[sizeof("k12.de.us")];
+    char stringpool_str2316[sizeof("ullensvang.no")];
+    char stringpool_str2317[sizeof("from-al.com")];
+    char stringpool_str2318[sizeof("solutions")];
+    char stringpool_str2319[sizeof("from-mo.com")];
+    char stringpool_str2320[sizeof("eidfjord.no")];
+    char stringpool_str2321[sizeof("hiratsuka.kanagawa.jp")];
+    char stringpool_str2322[sizeof("hidaka.hokkaido.jp")];
+    char stringpool_str2323[sizeof("from-ri.com")];
+    char stringpool_str2324[sizeof("from-wi.com")];
+    char stringpool_str2325[sizeof("k12.mt.us")];
+    char stringpool_str2326[sizeof("sondrio.it")];
+    char stringpool_str2327[sizeof("chikuho.fukuoka.jp")];
+    char stringpool_str2328[sizeof("from-ks.com")];
+    char stringpool_str2329[sizeof("sx")];
+    char stringpool_str2330[sizeof("coop.tt")];
+    char stringpool_str2331[sizeof("from-fl.com")];
+    char stringpool_str2332[sizeof("k12.mn.us")];
+    char stringpool_str2333[sizeof("matsushige.tokushima.jp")];
+    char stringpool_str2334[sizeof("yokoze.saitama.jp")];
+    char stringpool_str2335[sizeof("nakijin.okinawa.jp")];
+    char stringpool_str2336[sizeof("k12.ms.us")];
+    char stringpool_str2337[sizeof("kadena.okinawa.jp")];
+    char stringpool_str2338[sizeof("verdal.no")];
+    char stringpool_str2339[sizeof("campidanomedio.it")];
+    char stringpool_str2340[sizeof("campania.it")];
+    char stringpool_str2341[sizeof("k12.il.us")];
+    char stringpool_str2342[sizeof("mil.lv")];
+    char stringpool_str2343[sizeof("higashi.fukushima.jp")];
+    char stringpool_str2344[sizeof("mino.gifu.jp")];
+    char stringpool_str2345[sizeof("eidskog.no")];
+    char stringpool_str2346[sizeof("kvafjord.no")];
+    char stringpool_str2347[sizeof("mitsuke.niigata.jp")];
+    char stringpool_str2348[sizeof("appspot.com")];
+    char stringpool_str2349[sizeof("mincom.tn")];
+    char stringpool_str2350[sizeof("mielec.pl")];
+    char stringpool_str2351[sizeof("fuel.aero")];
+    char stringpool_str2352[sizeof("k12.in.us")];
+    char stringpool_str2353[sizeof("from-ar.com")];
+    char stringpool_str2354[sizeof("karpacz.pl")];
+    char stringpool_str2355[sizeof("k12.md.us")];
+    char stringpool_str2356[sizeof("yugawara.kanagawa.jp")];
+    char stringpool_str2357[sizeof("fareast.ru")];
+    char stringpool_str2358[sizeof("webhop.org")];
+    char stringpool_str2359[sizeof("gloppen.no")];
+    char stringpool_str2360[sizeof("higashiyodogawa.osaka.jp")];
+    char stringpool_str2361[sizeof("nishinomiya.hyogo.jp")];
+    char stringpool_str2362[sizeof("kostroma.ru")];
+    char stringpool_str2363[sizeof("k12.me.us")];
+    char stringpool_str2364[sizeof("saarland")];
+    char stringpool_str2365[sizeof("from-az.net")];
+    char stringpool_str2366[sizeof("k12.id.us")];
+    char stringpool_str2367[sizeof("k12.nc.us")];
+    char stringpool_str2368[sizeof("russia.museum")];
+    char stringpool_str2369[sizeof("spydeberg.no")];
+    char stringpool_str2370[sizeof("kvitsoy.no")];
+    char stringpool_str2371[sizeof("moka.tochigi.jp")];
+    char stringpool_str2372[sizeof("a.prod.fastly.net")];
+    char stringpool_str2373[sizeof("konskowola.pl")];
+    char stringpool_str2374[sizeof("eidsvoll.no")];
+    char stringpool_str2375[sizeof("sardegna.it")];
+    char stringpool_str2376[sizeof("kurate.fukuoka.jp")];
+    char stringpool_str2377[sizeof("frogans")];
+    char stringpool_str2378[sizeof("matsuzaki.shizuoka.jp")];
+    char stringpool_str2379[sizeof("k12.pa.us")];
+    char stringpool_str2380[sizeof("umbria.it")];
+    char stringpool_str2381[sizeof("sg")];
+    char stringpool_str2382[sizeof("kumamoto.jp")];
+    char stringpool_str2383[sizeof("kumatori.osaka.jp")];
+    char stringpool_str2384[sizeof("web.do")];
+    char stringpool_str2385[sizeof("mordovia.ru")];
+    char stringpool_str2386[sizeof("varggat.no")];
+    char stringpool_str2387[sizeof("matera.it")];
+    char stringpool_str2388[sizeof("sokndal.no")];
+    char stringpool_str2389[sizeof("seto.aichi.jp")];
+    char stringpool_str2390[sizeof("k12.nd.us")];
+    char stringpool_str2391[sizeof("nagawa.nagano.jp")];
+    char stringpool_str2392[sizeof("simbirsk.ru")];
+    char stringpool_str2393[sizeof("from-mn.com")];
+    char stringpool_str2394[sizeof("k12.vt.us")];
+    char stringpool_str2395[sizeof("campidano-medio.it")];
+    char stringpool_str2396[sizeof("minami-alps.yamanashi.jp")];
+    char stringpool_str2397[sizeof("from-nh.com")];
+    char stringpool_str2398[sizeof("flog.br")];
+    char stringpool_str2399[sizeof("kurume.fukuoka.jp")];
+    char stringpool_str2400[sizeof("sado.niigata.jp")];
+    char stringpool_str2401[sizeof("from-ne.com")];
+    char stringpool_str2402[sizeof("k12.ne.us")];
+    char stringpool_str2403[sizeof("from-ak.com")];
+    char stringpool_str2404[sizeof("k12.nj.us")];
+    char stringpool_str2405[sizeof("from-mi.com")];
+    char stringpool_str2406[sizeof("saitama.jp")];
+    char stringpool_str2407[sizeof("stuttgart.museum")];
+    char stringpool_str2408[sizeof("bjarkoy.no")];
+    char stringpool_str2409[sizeof("from-ms.com")];
+    char stringpool_str2410[sizeof("financial")];
+    char stringpool_str2411[sizeof("hikawa.shimane.jp")];
+    char stringpool_str2412[sizeof("exhibition.museum")];
+    char stringpool_str2413[sizeof("warabi.saitama.jp")];
+    char stringpool_str2414[sizeof("adachi.tokyo.jp")];
+    char stringpool_str2415[sizeof("utashinai.hokkaido.jp")];
+    char stringpool_str2416[sizeof("from-de.com")];
+    char stringpool_str2417[sizeof("maebashi.gunma.jp")];
+    char stringpool_str2418[sizeof("nagatoro.saitama.jp")];
+    char stringpool_str2419[sizeof("corporation.museum")];
+    char stringpool_str2420[sizeof("k12.ma.us")];
+    char stringpool_str2421[sizeof("yamagata.nagano.jp")];
+    char stringpool_str2422[sizeof("sorfold.no")];
+    char stringpool_str2423[sizeof("hirara.okinawa.jp")];
+    char stringpool_str2424[sizeof("krasnoyarsk.ru")];
+    char stringpool_str2425[sizeof("from-ct.com")];
+    char stringpool_str2426[sizeof("from-ga.com")];
+    char stringpool_str2427[sizeof("siedlce.pl")];
+    char stringpool_str2428[sizeof("minakami.gunma.jp")];
+    char stringpool_str2429[sizeof("k12.ia.us")];
+    char stringpool_str2430[sizeof("skedsmokorset.no")];
+    char stringpool_str2431[sizeof("k12.nm.us")];
+    char stringpool_str2432[sizeof("iwanai.hokkaido.jp")];
+    char stringpool_str2433[sizeof("farmers.museum")];
+    char stringpool_str2434[sizeof("nogata.fukuoka.jp")];
+    char stringpool_str2435[sizeof("miyoshi.hiroshima.jp")];
+    char stringpool_str2436[sizeof("melhus.no")];
+    char stringpool_str2437[sizeof("nerima.tokyo.jp")];
+    char stringpool_str2438[sizeof("kirovograd.ua")];
+    char stringpool_str2439[sizeof("genkai.saga.jp")];
+    char stringpool_str2440[sizeof("higashiagatsuma.gunma.jp")];
+    char stringpool_str2441[sizeof("suedtirol.it")];
+    char stringpool_str2442[sizeof("soka.saitama.jp")];
+    char stringpool_str2443[sizeof("airport.aero")];
+    char stringpool_str2444[sizeof("miyazaki.miyazaki.jp")];
+    char stringpool_str2445[sizeof("usarts.museum")];
+    char stringpool_str2446[sizeof("mugi.tokushima.jp")];
+    char stringpool_str2447[sizeof("social")];
+    char stringpool_str2448[sizeof("voagat.no")];
+    char stringpool_str2449[sizeof("modena.it")];
+    char stringpool_str2450[sizeof("yahaba.iwate.jp")];
+    char stringpool_str2451[sizeof("k12.ks.us")];
+    char stringpool_str2452[sizeof("fish")];
+    char stringpool_str2453[sizeof("kemerovo.ru")];
+    char stringpool_str2454[sizeof("varese.it")];
+    char stringpool_str2455[sizeof("morotsuka.miyazaki.jp")];
+    char stringpool_str2456[sizeof("iitate.fukushima.jp")];
+    char stringpool_str2457[sizeof("miasta.pl")];
+    char stringpool_str2458[sizeof("museum.no")];
+    char stringpool_str2459[sizeof("marche.it")];
+    char stringpool_str2460[sizeof("minamiizu.shizuoka.jp")];
+    char stringpool_str2461[sizeof("dell-ogliastra.it")];
+    char stringpool_str2462[sizeof("badajoz.museum")];
+    char stringpool_str2463[sizeof("k12.la.us")];
+    char stringpool_str2464[sizeof("zamami.okinawa.jp")];
+    char stringpool_str2465[sizeof("k12.va.us")];
+    char stringpool_str2466[sizeof("soni.nara.jp")];
+    char stringpool_str2467[sizeof("aogaki.hyogo.jp")];
+    char stringpool_str2468[sizeof("mykolaiv.ua")];
+    char stringpool_str2469[sizeof("farmstead.museum")];
+    char stringpool_str2470[sizeof("bungoono.oita.jp")];
+    char stringpool_str2471[sizeof("gokase.miyazaki.jp")];
+    char stringpool_str2472[sizeof("verran.no")];
+    char stringpool_str2473[sizeof("nishikawa.yamagata.jp")];
+    char stringpool_str2474[sizeof("santafe.museum")];
+    char stringpool_str2475[sizeof("keisen.fukuoka.jp")];
+    char stringpool_str2476[sizeof("kusu.oita.jp")];
+    char stringpool_str2477[sizeof("mashike.hokkaido.jp")];
+    char stringpool_str2478[sizeof("cartoonart.museum")];
+    char stringpool_str2479[sizeof("higashimurayama.tokyo.jp")];
+    char stringpool_str2480[sizeof("filatelia.museum")];
+    char stringpool_str2481[sizeof("mishima.shizuoka.jp")];
+    char stringpool_str2482[sizeof("coop.mv")];
+    char stringpool_str2483[sizeof("from-mt.com")];
+    char stringpool_str2484[sizeof("zachpomor.pl")];
+    char stringpool_str2485[sizeof("sandnessjoen.no")];
+    char stringpool_str2486[sizeof("southwest.museum")];
+    char stringpool_str2487[sizeof("firm.in")];
+    char stringpool_str2488[sizeof("salangen.no")];
+    char stringpool_str2489[sizeof("matsue.shimane.jp")];
+    char stringpool_str2490[sizeof("maibara.shiga.jp")];
+    char stringpool_str2491[sizeof("savannahga.museum")];
+    char stringpool_str2492[sizeof("svelvik.no")];
+    char stringpool_str2493[sizeof("setouchi.okayama.jp")];
+    char stringpool_str2494[sizeof("minamioguni.kumamoto.jp")];
+    char stringpool_str2495[sizeof("skanland.no")];
+    char stringpool_str2496[sizeof("wakayama.wakayama.jp")];
+    char stringpool_str2497[sizeof("miyoshi.tokushima.jp")];
+    char stringpool_str2498[sizeof("himeji.hyogo.jp")];
+    char stringpool_str2499[sizeof("fyresdal.no")];
+    char stringpool_str2500[sizeof("bronnoysund.no")];
+    char stringpool_str2501[sizeof("museum.tt")];
+    char stringpool_str2502[sizeof("bomlo.no")];
+    char stringpool_str2503[sizeof("from-wv.com")];
+    char stringpool_str2504[sizeof("from-ia.com")];
+    char stringpool_str2505[sizeof("hita.oita.jp")];
+    char stringpool_str2506[sizeof("from-il.com")];
+    char stringpool_str2507[sizeof("czest.pl")];
+    char stringpool_str2508[sizeof("flesberg.no")];
+    char stringpool_str2509[sizeof("nago.okinawa.jp")];
+    char stringpool_str2510[sizeof("nore-og-uvdal.no")];
+    char stringpool_str2511[sizeof("from-nv.com")];
+    char stringpool_str2512[sizeof("mobara.chiba.jp")];
+    char stringpool_str2513[sizeof("frei.no")];
+    char stringpool_str2514[sizeof("colonialwilliamsburg.museum")];
+    char stringpool_str2515[sizeof("modern.museum")];
+    char stringpool_str2516[sizeof("greta.fr")];
+    char stringpool_str2517[sizeof("assisi.museum")];
+    char stringpool_str2518[sizeof("stjordal.no")];
+    char stringpool_str2519[sizeof("usui.fukuoka.jp")];
+    char stringpool_str2520[sizeof("systems")];
+    char stringpool_str2521[sizeof("musashino.tokyo.jp")];
+    char stringpool_str2522[sizeof("museum.om")];
+    char stringpool_str2523[sizeof("fukuoka.jp")];
+    char stringpool_str2524[sizeof("ariake.saga.jp")];
+    char stringpool_str2525[sizeof("saitama.saitama.jp")];
+    char stringpool_str2526[sizeof("foundation")];
+    char stringpool_str2527[sizeof("forsand.no")];
+    char stringpool_str2528[sizeof("kepno.pl")];
+    char stringpool_str2529[sizeof("snillfjord.no")];
+    char stringpool_str2530[sizeof("kita.osaka.jp")];
+    char stringpool_str2531[sizeof("rec.ro")];
+    char stringpool_str2532[sizeof("fishing")];
+    char stringpool_str2533[sizeof("fetsund.no")];
+    char stringpool_str2534[sizeof("sakurai.nara.jp")];
+    char stringpool_str2535[sizeof("verona.it")];
+    char stringpool_str2536[sizeof("vdonsk.ru")];
+    char stringpool_str2537[sizeof("gemological.museum")];
+    char stringpool_str2538[sizeof("stor-elvdal.no")];
+    char stringpool_str2539[sizeof("bristol.museum")];
+    char stringpool_str2540[sizeof("mitsue.nara.jp")];
+    char stringpool_str2541[sizeof("miners.museum")];
+    char stringpool_str2542[sizeof("veterinaire.fr")];
+    char stringpool_str2543[sizeof("handson.museum")];
+    char stringpool_str2544[sizeof("fredrikstad.no")];
+    char stringpool_str2545[sizeof("bardu.no")];
+    char stringpool_str2546[sizeof("fhsk.se")];
+    char stringpool_str2547[sizeof("kherson.ua")];
+    char stringpool_str2548[sizeof("asnes.no")];
+    char stringpool_str2549[sizeof("kutno.pl")];
+    char stringpool_str2550[sizeof("k12.wa.us")];
+    char stringpool_str2551[sizeof("southcarolina.museum")];
+    char stringpool_str2552[sizeof("farsund.no")];
+    char stringpool_str2553[sizeof("shacknet.nu")];
+    char stringpool_str2554[sizeof("upow.gov.pl")];
+    char stringpool_str2555[sizeof("kosuge.yamanashi.jp")];
+    char stringpool_str2556[sizeof("barum.no")];
+    char stringpool_str2557[sizeof("genoa.it")];
+    char stringpool_str2558[sizeof("gangwon.kr")];
+    char stringpool_str2559[sizeof("galsa.no")];
+    char stringpool_str2560[sizeof("balat.no")];
+    char stringpool_str2561[sizeof("naha.okinawa.jp")];
+    char stringpool_str2562[sizeof("yamaga.kumamoto.jp")];
+    char stringpool_str2563[sizeof("muncie.museum")];
+    char stringpool_str2564[sizeof("stalowa-wola.pl")];
+    char stringpool_str2565[sizeof("k12.ri.us")];
+    char stringpool_str2566[sizeof("from.hr")];
+    char stringpool_str2567[sizeof("aurskog-holand.no")];
+    char stringpool_str2568[sizeof("akashi.hyogo.jp")];
+    char stringpool_str2569[sizeof("meeres.museum")];
+    char stringpool_str2570[sizeof("gunma.jp")];
+    char stringpool_str2571[sizeof("from-in.com")];
+    char stringpool_str2572[sizeof("sakhalin.ru")];
+    char stringpool_str2573[sizeof("cuneo.it")];
+    char stringpool_str2574[sizeof("fineart.museum")];
+    char stringpool_str2575[sizeof("kitamoto.saitama.jp")];
+    char stringpool_str2576[sizeof("sorreisa.no")];
+    char stringpool_str2577[sizeof("bryne.no")];
+    char stringpool_str2578[sizeof("shriram")];
+    char stringpool_str2579[sizeof("miyama.mie.jp")];
+    char stringpool_str2580[sizeof("zagan.pl")];
+    char stringpool_str2581[sizeof("grane.no")];
+    char stringpool_str2582[sizeof("k12.mi.us")];
+    char stringpool_str2583[sizeof("k12.az.us")];
+    char stringpool_str2584[sizeof("kanoya.kagoshima.jp")];
+    char stringpool_str2585[sizeof("shimane.jp")];
+    char stringpool_str2586[sizeof("moscow.museum")];
+    char stringpool_str2587[sizeof("minamifurano.hokkaido.jp")];
+    char stringpool_str2588[sizeof("hikone.shiga.jp")];
+    char stringpool_str2589[sizeof("florist")];
+    char stringpool_str2590[sizeof("hiraya.nagano.jp")];
+    char stringpool_str2591[sizeof("hagebostad.no")];
+    char stringpool_str2592[sizeof("incheon.kr")];
+    char stringpool_str2593[sizeof("yamakita.kanagawa.jp")];
+    char stringpool_str2594[sizeof("flekkefjord.no")];
+    char stringpool_str2595[sizeof("saintlouis.museum")];
+    char stringpool_str2596[sizeof("froland.no")];
+    char stringpool_str2597[sizeof("spiegel")];
+    char stringpool_str2598[sizeof("mitane.akita.jp")];
+    char stringpool_str2599[sizeof("yufu.oita.jp")];
+    char stringpool_str2600[sizeof("daejeon.kr")];
+    char stringpool_str2601[sizeof("romskog.no")];
+    char stringpool_str2602[sizeof("museet.museum")];
+    char stringpool_str2603[sizeof("misasa.tottori.jp")];
+    char stringpool_str2604[sizeof("hakuba.nagano.jp")];
+    char stringpool_str2605[sizeof("yamazoe.nara.jp")];
+    char stringpool_str2606[sizeof("yamagata.yamagata.jp")];
+    char stringpool_str2607[sizeof("sherbrooke.museum")];
+    char stringpool_str2608[sizeof("nanporo.hokkaido.jp")];
+    char stringpool_str2609[sizeof("neues.museum")];
+    char stringpool_str2610[sizeof("nose.osaka.jp")];
+    char stringpool_str2611[sizeof("rimini.it")];
+    char stringpool_str2612[sizeof("hembygdsforbund.museum")];
+    char stringpool_str2613[sizeof("hirata.fukushima.jp")];
+    char stringpool_str2614[sizeof("fuefuki.yamanashi.jp")];
+    char stringpool_str2615[sizeof("sano.tochigi.jp")];
+    char stringpool_str2616[sizeof("chuo.osaka.jp")];
+    char stringpool_str2617[sizeof("burghof.museum")];
+    char stringpool_str2618[sizeof("herad.no")];
+    char stringpool_str2619[sizeof("harima.hyogo.jp")];
+    char stringpool_str2620[sizeof("utsira.no")];
+    char stringpool_str2621[sizeof("kasuga.hyogo.jp")];
+    char stringpool_str2622[sizeof("yamada.fukuoka.jp")];
+    char stringpool_str2623[sizeof("masuda.shimane.jp")];
+    char stringpool_str2624[sizeof("6bone.pl")];
+    char stringpool_str2625[sizeof("moriyama.shiga.jp")];
+    char stringpool_str2626[sizeof("bandai.fukushima.jp")];
+    char stringpool_str2627[sizeof("adult.ht")];
+    char stringpool_str2628[sizeof("kuban.ru")];
+    char stringpool_str2629[sizeof("yanaizu.fukushima.jp")];
+    char stringpool_str2630[sizeof("higashikagura.hokkaido.jp")];
+    char stringpool_str2631[sizeof("donna.no")];
+    char stringpool_str2632[sizeof("sayo.hyogo.jp")];
+    char stringpool_str2633[sizeof("k12.vi.us")];
+    char stringpool_str2634[sizeof("gulen.no")];
+    char stringpool_str2635[sizeof("kunst.museum")];
+    char stringpool_str2636[sizeof("shakotan.hokkaido.jp")];
+    char stringpool_str2637[sizeof("society.museum")];
+    char stringpool_str2638[sizeof("rishirifuji.hokkaido.jp")];
+    char stringpool_str2639[sizeof("natori.miyagi.jp")];
+    char stringpool_str2640[sizeof("jamal.ru")];
+    char stringpool_str2641[sizeof("minamiyamashiro.kyoto.jp")];
+    char stringpool_str2642[sizeof("matsushima.miyagi.jp")];
+    char stringpool_str2643[sizeof("soo.kagoshima.jp")];
+    char stringpool_str2644[sizeof("bible.museum")];
+    char stringpool_str2645[sizeof("fuso.aichi.jp")];
+    char stringpool_str2646[sizeof("miyake.nara.jp")];
+    char stringpool_str2647[sizeof("from-nd.com")];
+    char stringpool_str2648[sizeof("from-sd.com")];
+    char stringpool_str2649[sizeof("k12.oh.us")];
+    char stringpool_str2650[sizeof("starnberg.museum")];
+    char stringpool_str2651[sizeof("mihama.chiba.jp")];
+    char stringpool_str2652[sizeof("ardal.no")];
+    char stringpool_str2653[sizeof("zarow.pl")];
+    char stringpool_str2654[sizeof("florida.museum")];
+    char stringpool_str2655[sizeof("hamar.no")];
+    char stringpool_str2656[sizeof("molise.it")];
+    char stringpool_str2657[sizeof("koeln.museum")];
+    char stringpool_str2658[sizeof("mihama.mie.jp")];
+    char stringpool_str2659[sizeof("sibenik.museum")];
+    char stringpool_str2660[sizeof("flights")];
+    char stringpool_str2661[sizeof("seljord.no")];
+    char stringpool_str2662[sizeof("vossevangen.no")];
+    char stringpool_str2663[sizeof("nakadomari.aomori.jp")];
+    char stringpool_str2664[sizeof("madrid.museum")];
+    char stringpool_str2665[sizeof("minamiaiki.nagano.jp")];
+    char stringpool_str2666[sizeof("games.hu")];
+    char stringpool_str2667[sizeof("kirov.ru")];
+    char stringpool_str2668[sizeof("sex.pl")];
+    char stringpool_str2669[sizeof("haram.no")];
+    char stringpool_str2670[sizeof("daegu.kr")];
+    char stringpool_str2671[sizeof("yasaka.nagano.jp")];
+    char stringpool_str2672[sizeof("aland.fi")];
+    char stringpool_str2673[sizeof("shiksha")];
+    char stringpool_str2674[sizeof("saku.nagano.jp")];
+    char stringpool_str2675[sizeof("hemne.no")];
+    char stringpool_str2676[sizeof("halsa.no")];
+    char stringpool_str2677[sizeof("firm.ht")];
+    char stringpool_str2678[sizeof("glass.museum")];
+    char stringpool_str2679[sizeof("rzeszow.pl")];
+    char stringpool_str2680[sizeof("depot.museum")];
+    char stringpool_str2681[sizeof("nakama.fukuoka.jp")];
+    char stringpool_str2682[sizeof("dovre.no")];
+    char stringpool_str2683[sizeof("gorge.museum")];
+    char stringpool_str2684[sizeof("museum.mv")];
+    char stringpool_str2685[sizeof("minamiminowa.nagano.jp")];
+    char stringpool_str2686[sizeof("dolls.museum")];
+    char stringpool_str2687[sizeof("hurum.no")];
+    char stringpool_str2688[sizeof("klabu.no")];
+    char stringpool_str2689[sizeof("from-hi.com")];
+    char stringpool_str2690[sizeof("kokonoe.oita.jp")];
+    char stringpool_str2691[sizeof("vantaa.museum")];
+    char stringpool_str2692[sizeof("aoste.it")];
+    char stringpool_str2693[sizeof("mifune.kumamoto.jp")];
+    char stringpool_str2694[sizeof("shimamoto.osaka.jp")];
+    char stringpool_str2695[sizeof("kakuda.miyagi.jp")];
+    char stringpool_str2696[sizeof("design.museum")];
+    char stringpool_str2697[sizeof("bjugn.no")];
+    char stringpool_str2698[sizeof("funahashi.toyama.jp")];
+    char stringpool_str2699[sizeof("global.prod.fastly.net")];
+    char stringpool_str2700[sizeof("kursk.ru")];
+    char stringpool_str2701[sizeof("soundandvision.museum")];
+    char stringpool_str2702[sizeof("coop.ht")];
+    char stringpool_str2703[sizeof("nesna.no")];
+    char stringpool_str2704[sizeof("minamimaki.nagano.jp")];
+    char stringpool_str2705[sizeof("mosreg.ru")];
+    char stringpool_str2706[sizeof("nord-odal.no")];
+    char stringpool_str2707[sizeof("giske.no")];
+    char stringpool_str2708[sizeof("naval.museum")];
+    char stringpool_str2709[sizeof("firenze.it")];
+    char stringpool_str2710[sizeof("vladivostok.ru")];
+    char stringpool_str2711[sizeof("altai.ru")];
+    char stringpool_str2712[sizeof("amber.museum")];
+    char stringpool_str2713[sizeof("from-md.com")];
+    char stringpool_str2714[sizeof("kuju.oita.jp")];
+    char stringpool_str2715[sizeof("minami.kyoto.jp")];
+    char stringpool_str2716[sizeof("aosta.it")];
+    char stringpool_str2717[sizeof("kumamoto.kumamoto.jp")];
+    char stringpool_str2718[sizeof("busan.kr")];
+    char stringpool_str2719[sizeof("kariwa.niigata.jp")];
+    char stringpool_str2720[sizeof("iwate.jp")];
+    char stringpool_str2721[sizeof("biratori.hokkaido.jp")];
+    char stringpool_str2722[sizeof("shobara.hiroshima.jp")];
+    char stringpool_str2723[sizeof("hobol.no")];
+    char stringpool_str2724[sizeof("stargard.pl")];
+    char stringpool_str2725[sizeof("k12.wi.us")];
+    char stringpool_str2726[sizeof("k12.nh.us")];
+    char stringpool_str2727[sizeof("urasoe.okinawa.jp")];
+    char stringpool_str2728[sizeof("naklo.pl")];
+    char stringpool_str2729[sizeof("foundation.museum")];
+    char stringpool_str2730[sizeof("house.museum")];
+    char stringpool_str2731[sizeof("izumiotsu.osaka.jp")];
+    char stringpool_str2732[sizeof("sakaiminato.tottori.jp")];
+    char stringpool_str2733[sizeof("uonuma.niigata.jp")];
+    char stringpool_str2734[sizeof("clinton.museum")];
+    char stringpool_str2735[sizeof("szex.hu")];
+    char stringpool_str2736[sizeof("hotel.lk")];
+    char stringpool_str2737[sizeof("gmina.pl")];
+    char stringpool_str2738[sizeof("hanawa.fukushima.jp")];
+    char stringpool_str2739[sizeof("mihara.hiroshima.jp")];
+    char stringpool_str2740[sizeof("kainan.wakayama.jp")];
+    char stringpool_str2741[sizeof("north.museum")];
+    char stringpool_str2742[sizeof("yoichi.hokkaido.jp")];
+    char stringpool_str2743[sizeof("marine.ru")];
+    char stringpool_str2744[sizeof("nuoro.it")];
+    char stringpool_str2745[sizeof("yasugi.shimane.jp")];
+    char stringpool_str2746[sizeof("higashimatsushima.miyagi.jp")];
+    char stringpool_str2747[sizeof("bytom.pl")];
+    char stringpool_str2748[sizeof("sirdal.no")];
+    char stringpool_str2749[sizeof("midori.chiba.jp")];
+    char stringpool_str2750[sizeof("setagaya.tokyo.jp")];
+    char stringpool_str2751[sizeof("nanto.toyama.jp")];
+    char stringpool_str2752[sizeof("yokawa.hyogo.jp")];
+    char stringpool_str2753[sizeof("suldal.no")];
+    char stringpool_str2754[sizeof("sannohe.aomori.jp")];
+    char stringpool_str2755[sizeof("steiermark.museum")];
+    char stringpool_str2756[sizeof("sera.hiroshima.jp")];
+    char stringpool_str2757[sizeof("kasuya.fukuoka.jp")];
+    char stringpool_str2758[sizeof("fortmissoula.museum")];
+    char stringpool_str2759[sizeof("nagi.okayama.jp")];
+    char stringpool_str2760[sizeof("naroy.no")];
+    char stringpool_str2761[sizeof("k12.ga.us")];
+    char stringpool_str2762[sizeof("murayama.yamagata.jp")];
+    char stringpool_str2763[sizeof("akaiwa.okayama.jp")];
+    char stringpool_str2764[sizeof("jamison.museum")];
+    char stringpool_str2765[sizeof("automotive.museum")];
+    char stringpool_str2766[sizeof("sigdal.no")];
+    char stringpool_str2767[sizeof("miki.hyogo.jp")];
+    char stringpool_str2768[sizeof("baths.museum")];
+    char stringpool_str2769[sizeof("sologne.museum")];
+    char stringpool_str2770[sizeof("semboku.akita.jp")];
+    char stringpool_str2771[sizeof("snaase.no")];
+    char stringpool_str2772[sizeof("finland.museum")];
+    char stringpool_str2773[sizeof("hakata.fukuoka.jp")];
+    char stringpool_str2774[sizeof("malatvuopmi.no")];
+    char stringpool_str2775[sizeof("hikimi.shimane.jp")];
+    char stringpool_str2776[sizeof("strand.no")];
+    char stringpool_str2777[sizeof("freemasonry.museum")];
+    char stringpool_str2778[sizeof("solund.no")];
+    char stringpool_str2779[sizeof("csiro.au")];
+    char stringpool_str2780[sizeof("computerhistory.museum")];
+    char stringpool_str2781[sizeof("shirako.chiba.jp")];
+    char stringpool_str2782[sizeof("uslivinghistory.museum")];
+    char stringpool_str2783[sizeof("hitra.no")];
+    char stringpool_str2784[sizeof("entomology.museum")];
+    char stringpool_str2785[sizeof("suginami.tokyo.jp")];
+    char stringpool_str2786[sizeof("hasami.nagasaki.jp")];
+    char stringpool_str2787[sizeof("asker.no")];
+    char stringpool_str2788[sizeof("ashiya.hyogo.jp")];
+    char stringpool_str2789[sizeof("misawa.aomori.jp")];
+    char stringpool_str2790[sizeof("hotel.tz")];
+    char stringpool_str2791[sizeof("iruma.saitama.jp")];
+    char stringpool_str2792[sizeof("selfip.com")];
+    char stringpool_str2793[sizeof("from-me.org")];
+    char stringpool_str2794[sizeof("kochi.jp")];
+    char stringpool_str2795[sizeof("belau.pw")];
+    char stringpool_str2796[sizeof("fjaler.no")];
+    char stringpool_str2797[sizeof("kanna.gunma.jp")];
+    char stringpool_str2798[sizeof("basel.museum")];
+    char stringpool_str2799[sizeof("roros.no")];
+    char stringpool_str2800[sizeof("shimoda.shizuoka.jp")];
+    char stringpool_str2801[sizeof("hachioji.tokyo.jp")];
+    char stringpool_str2802[sizeof("ehime.jp")];
+    char stringpool_str2803[sizeof("mishima.fukushima.jp")];
+    char stringpool_str2804[sizeof("inami.toyama.jp")];
+    char stringpool_str2805[sizeof("asaka.saitama.jp")];
+    char stringpool_str2806[sizeof("kyoto.jp")];
+    char stringpool_str2807[sizeof("romsa.no")];
+    char stringpool_str2808[sizeof("kharkov.ua")];
+    char stringpool_str2809[sizeof("kaisei.kanagawa.jp")];
+    char stringpool_str2810[sizeof("asuke.aichi.jp")];
+    char stringpool_str2811[sizeof("shimada.shizuoka.jp")];
+    char stringpool_str2812[sizeof("sicilia.it")];
+    char stringpool_str2813[sizeof("wakasa.fukui.jp")];
+    char stringpool_str2814[sizeof("mypets.ws")];
+    char stringpool_str2815[sizeof("stockholm.museum")];
+    char stringpool_str2816[sizeof("chita.ru")];
+    char stringpool_str2817[sizeof("konan.aichi.jp")];
+    char stringpool_str2818[sizeof("steigen.no")];
+    char stringpool_str2819[sizeof("evje-og-hornnes.no")];
+    char stringpool_str2820[sizeof("minamidaito.okinawa.jp")];
+    char stringpool_str2821[sizeof("mil.do")];
+    char stringpool_str2822[sizeof("nanbu.tottori.jp")];
+    char stringpool_str2823[sizeof("gov.sx")];
+    char stringpool_str2824[sizeof("museum.mw")];
+    char stringpool_str2825[sizeof("hotel.hu")];
+    char stringpool_str2826[sizeof("andoy.no")];
+    char stringpool_str2827[sizeof("cc")];
+    char stringpool_str2828[sizeof("radom.pl")];
+    char stringpool_str2829[sizeof("stjordalshalsen.no")];
+    char stringpool_str2830[sizeof("rauma.no")];
+    char stringpool_str2831[sizeof("sobetsu.hokkaido.jp")];
+    char stringpool_str2832[sizeof("shimane.shimane.jp")];
+    char stringpool_str2833[sizeof("spjelkavik.no")];
+    char stringpool_str2834[sizeof("yamal.ru")];
+    char stringpool_str2835[sizeof("nc")];
+    char stringpool_str2836[sizeof("net.cw")];
+    char stringpool_str2837[sizeof("gov.cl")];
+    char stringpool_str2838[sizeof("com.cw")];
+    char stringpool_str2839[sizeof("ec")];
+    char stringpool_str2840[sizeof("gob.cl")];
+    char stringpool_str2841[sizeof("net.cn")];
+    char stringpool_str2842[sizeof("com.cn")];
+    char stringpool_str2843[sizeof("konin.pl")];
+    char stringpool_str2844[sizeof("gov.cn")];
+    char stringpool_str2845[sizeof("navy")];
+    char stringpool_str2846[sizeof("vyatka.ru")];
+    char stringpool_str2847[sizeof("hidaka.wakayama.jp")];
+    char stringpool_str2848[sizeof("mil.to")];
+    char stringpool_str2849[sizeof("samara.ru")];
+    char stringpool_str2850[sizeof("rubtsovsk.ru")];
+    char stringpool_str2851[sizeof("edu.cw")];
+    char stringpool_str2852[sizeof("akita.jp")];
+    char stringpool_str2853[sizeof("cyber.museum")];
+    char stringpool_str2854[sizeof("yugawa.fukushima.jp")];
+    char stringpool_str2855[sizeof("shimabara.nagasaki.jp")];
+    char stringpool_str2856[sizeof("yamatotakada.nara.jp")];
+    char stringpool_str2857[sizeof("edu.cn")];
+    char stringpool_str2858[sizeof("snoasa.no")];
+    char stringpool_str2859[sizeof("gov.cd")];
+    char stringpool_str2860[sizeof("film.hu")];
+    char stringpool_str2861[sizeof("clock.museum")];
+    char stringpool_str2862[sizeof("from-id.com")];
+    char stringpool_str2863[sizeof("izumi.osaka.jp")];
+    char stringpool_str2864[sizeof("atami.shizuoka.jp")];
+    char stringpool_str2865[sizeof("mil.jo")];
+    char stringpool_str2866[sizeof("ikoma.nara.jp")];
+    char stringpool_str2867[sizeof("ac")];
+    char stringpool_str2868[sizeof("kanan.osaka.jp")];
+    char stringpool_str2869[sizeof("om")];
+    char stringpool_str2870[sizeof("kanra.gunma.jp")];
+    char stringpool_str2871[sizeof("fuoisku.no")];
+    char stringpool_str2872[sizeof("net.mx")];
+    char stringpool_str2873[sizeof("shirosato.ibaraki.jp")];
+    char stringpool_str2874[sizeof("com.mx")];
+    char stringpool_str2875[sizeof("savona.it")];
+    char stringpool_str2876[sizeof("hakone.kanagawa.jp")];
+    char stringpool_str2877[sizeof("aichi.jp")];
+    char stringpool_str2878[sizeof("gob.mx")];
+    char stringpool_str2879[sizeof("surgut.ru")];
+    char stringpool_str2880[sizeof("miyada.nagano.jp")];
+    char stringpool_str2881[sizeof("kasuga.fukuoka.jp")];
+    char stringpool_str2882[sizeof("mitaka.tokyo.jp")];
+    char stringpool_str2883[sizeof("mochizuki.nagano.jp")];
+    char stringpool_str2884[sizeof("org")];
+    char stringpool_str2885[sizeof("nanae.hokkaido.jp")];
+    char stringpool_str2886[sizeof("biz")];
+    char stringpool_str2887[sizeof("org.sl")];
+    char stringpool_str2888[sizeof("army")];
+    char stringpool_str2889[sizeof("org.st")];
+    char stringpool_str2890[sizeof("org.ec")];
+    char stringpool_str2891[sizeof("org.sc")];
+    char stringpool_str2892[sizeof("edu.mx")];
+    char stringpool_str2893[sizeof("franziskaner.museum")];
+    char stringpool_str2894[sizeof("org.pl")];
+    char stringpool_str2895[sizeof("org.pk")];
+    char stringpool_str2896[sizeof("org.pt")];
+    char stringpool_str2897[sizeof("org.pr")];
+    char stringpool_str2898[sizeof("biz.pl")];
+    char stringpool_str2899[sizeof("biz.pk")];
+    char stringpool_str2900[sizeof("biz.pr")];
+    char stringpool_str2901[sizeof("org.sn")];
+    char stringpool_str2902[sizeof("mil.bo")];
+    char stringpool_str2903[sizeof("org.es")];
+    char stringpool_str2904[sizeof("watari.miyagi.jp")];
+    char stringpool_str2905[sizeof("kamikoani.akita.jp")];
+    char stringpool_str2906[sizeof("org.pn")];
+    char stringpool_str2907[sizeof("org.ps")];
+    char stringpool_str2908[sizeof("midori.gunma.jp")];
+    char stringpool_str2909[sizeof("minami.tokushima.jp")];
+    char stringpool_str2910[sizeof("odda.no")];
+    char stringpool_str2911[sizeof("actor")];
+    char stringpool_str2912[sizeof("aca.pro")];
+    char stringpool_str2913[sizeof("miyota.nagano.jp")];
+    char stringpool_str2914[sizeof("org.al")];
+    char stringpool_str2915[sizeof("skanit.no")];
+    char stringpool_str2916[sizeof("org.ar")];
+    char stringpool_str2917[sizeof("org.ac")];
+    char stringpool_str2918[sizeof("biz.at")];
+    char stringpool_str2919[sizeof("chiba.jp")];
+    char stringpool_str2920[sizeof("mil.no")];
+    char stringpool_str2921[sizeof("org.tt")];
+    char stringpool_str2922[sizeof("yakage.okayama.jp")];
+    char stringpool_str2923[sizeof("org.sd")];
+    char stringpool_str2924[sizeof("org.tw")];
+    char stringpool_str2925[sizeof("biz.tt")];
+    char stringpool_str2926[sizeof("ecn.br")];
+    char stringpool_str2927[sizeof("org.an")];
+    char stringpool_str2928[sizeof("wake.okayama.jp")];
+    char stringpool_str2929[sizeof("oslo.no")];
+    char stringpool_str2930[sizeof("gov.cm")];
+    char stringpool_str2931[sizeof("org.sb")];
+    char stringpool_str2932[sizeof("wales.museum")];
+    char stringpool_str2933[sizeof("org.tn")];
+    char stringpool_str2934[sizeof("from-va.com")];
+    char stringpool_str2935[sizeof("soma.fukushima.jp")];
+    char stringpool_str2936[sizeof("skodje.no")];
+    char stringpool_str2937[sizeof("org.ee")];
+    char stringpool_str2938[sizeof("org.se")];
+    char stringpool_str2939[sizeof("org.rs")];
+    char stringpool_str2940[sizeof("zgrad.ru")];
+    char stringpool_str2941[sizeof("aukra.no")];
+    char stringpool_str2942[sizeof("org.pe")];
+    char stringpool_str2943[sizeof("minamiuonuma.niigata.jp")];
+    char stringpool_str2944[sizeof("handa.aichi.jp")];
+    char stringpool_str2945[sizeof("frankfurt.museum")];
+    char stringpool_str2946[sizeof("satosho.okayama.jp")];
+    char stringpool_str2947[sizeof("org.ml")];
+    char stringpool_str2948[sizeof("org.mk")];
+    char stringpool_str2949[sizeof("org.mt")];
+    char stringpool_str2950[sizeof("org.mw")];
+    char stringpool_str2951[sizeof("biz.mw")];
+    char stringpool_str2952[sizeof("stokke.no")];
+    char stringpool_str2953[sizeof("org.mn")];
+    char stringpool_str2954[sizeof("oita.jp")];
+    char stringpool_str2955[sizeof("org.ae")];
+    char stringpool_str2956[sizeof("org.ms")];
+    char stringpool_str2957[sizeof("minamitane.kagoshima.jp")];
+    char stringpool_str2958[sizeof("ong")];
+    char stringpool_str2959[sizeof("shimoji.okinawa.jp")];
+    char stringpool_str2960[sizeof("onl")];
+    char stringpool_str2961[sizeof("abeno.osaka.jp")];
+    char stringpool_str2962[sizeof("org.tj")];
+    char stringpool_str2963[sizeof("biz.tj")];
+    char stringpool_str2964[sizeof("osen.no")];
+    char stringpool_str2965[sizeof("org.ir")];
+    char stringpool_str2966[sizeof("iijima.nagano.jp")];
+    char stringpool_str2967[sizeof("academy")];
+    char stringpool_str2968[sizeof("ikeda.osaka.jp")];
+    char stringpool_str2969[sizeof("o.bg")];
+    char stringpool_str2970[sizeof("ikeda.nagano.jp")];
+    char stringpool_str2971[sizeof("democrat")];
+    char stringpool_str2972[sizeof("org.in")];
+    char stringpool_str2973[sizeof("org.bt")];
+    char stringpool_str2974[sizeof("org.is")];
+    char stringpool_str2975[sizeof("org.br")];
+    char stringpool_str2976[sizeof("org.bw")];
+    char stringpool_str2977[sizeof("rieti.it")];
+    char stringpool_str2978[sizeof("frosta.no")];
+    char stringpool_str2979[sizeof("seranishi.hiroshima.jp")];
+    char stringpool_str2980[sizeof("ainan.ehime.jp")];
+    char stringpool_str2981[sizeof("org.dm")];
+    char stringpool_str2982[sizeof("org.je")];
+    char stringpool_str2983[sizeof("org.om")];
+    char stringpool_str2984[sizeof("org.bs")];
+    char stringpool_str2985[sizeof("hanno.saitama.jp")];
+    char stringpool_str2986[sizeof("kurogi.fukuoka.jp")];
+    char stringpool_str2987[sizeof("org.me")];
+    char stringpool_str2988[sizeof("kosai.shizuoka.jp")];
+    char stringpool_str2989[sizeof("shikabe.hokkaido.jp")];
+    char stringpool_str2990[sizeof("misaki.osaka.jp")];
+    char stringpool_str2991[sizeof("fauske.no")];
+    char stringpool_str2992[sizeof("farmequipment.museum")];
+    char stringpool_str2993[sizeof("youth.museum")];
+    char stringpool_str2994[sizeof("shimamaki.hokkaido.jp")];
+    char stringpool_str2995[sizeof("asahi.toyama.jp")];
+    char stringpool_str2996[sizeof("org.nr")];
+    char stringpool_str2997[sizeof("biz.id")];
+    char stringpool_str2998[sizeof("biz.nr")];
+    char stringpool_str2999[sizeof("odo.br")];
+    char stringpool_str3000[sizeof("reggio-calabria.it")];
+    char stringpool_str3001[sizeof("ikata.ehime.jp")];
+    char stringpool_str3002[sizeof("wlocl.pl")];
+    char stringpool_str3003[sizeof("yabuki.fukushima.jp")];
+    char stringpool_str3004[sizeof("sennan.osaka.jp")];
+    char stringpool_str3005[sizeof("fosnes.no")];
+    char stringpool_str3006[sizeof("fukushima.jp")];
+    char stringpool_str3007[sizeof("org.sa")];
+    char stringpool_str3008[sizeof("org.bb")];
+    char stringpool_str3009[sizeof("biz.bb")];
+    char stringpool_str3010[sizeof("org.tm")];
+    char stringpool_str3011[sizeof("org.pa")];
+    char stringpool_str3012[sizeof("aikawa.kanagawa.jp")];
+    char stringpool_str3013[sizeof("eco.br")];
+    char stringpool_str3014[sizeof("mikasa.hokkaido.jp")];
+    char stringpool_str3015[sizeof("cymru.museum")];
+    char stringpool_str3016[sizeof("iwata.shizuoka.jp")];
+    char stringpool_str3017[sizeof("furubira.hokkaido.jp")];
+    char stringpool_str3018[sizeof("bykle.no")];
+    char stringpool_str3019[sizeof("org.lk")];
+    char stringpool_str3020[sizeof("bibai.hokkaido.jp")];
+    char stringpool_str3021[sizeof("org.lr")];
+    char stringpool_str3022[sizeof("org.lc")];
+    char stringpool_str3023[sizeof("org.vc")];
+    char stringpool_str3024[sizeof("makurazaki.kagoshima.jp")];
+    char stringpool_str3025[sizeof("honai.ehime.jp")];
+    char stringpool_str3026[sizeof("org.pf")];
+    char stringpool_str3027[sizeof("org.ls")];
+    char stringpool_str3028[sizeof("codespot.com")];
+    char stringpool_str3029[sizeof("is-a-cpa.com")];
+    char stringpool_str3030[sizeof("org.vn")];
+    char stringpool_str3031[sizeof("biz.vn")];
+    char stringpool_str3032[sizeof("shimonita.gunma.jp")];
+    char stringpool_str3033[sizeof("shimokitayama.nara.jp")];
+    char stringpool_str3034[sizeof("shibata.miyagi.jp")];
+    char stringpool_str3035[sizeof("malopolska.pl")];
+    char stringpool_str3036[sizeof("o.se")];
+    char stringpool_str3037[sizeof("org.ua")];
+    char stringpool_str3038[sizeof("nanbu.yamanashi.jp")];
+    char stringpool_str3039[sizeof("org.af")];
+    char stringpool_str3040[sizeof("ikeda.fukui.jp")];
+    char stringpool_str3041[sizeof("kunimi.fukushima.jp")];
+    char stringpool_str3042[sizeof("org.lb")];
+    char stringpool_str3043[sizeof("rissa.no")];
+    char stringpool_str3044[sizeof("shikama.miyagi.jp")];
+    char stringpool_str3045[sizeof("org.im")];
+    char stringpool_str3046[sizeof("ebino.miyazaki.jp")];
+    char stringpool_str3047[sizeof("mimata.miyazaki.jp")];
+    char stringpool_str3048[sizeof("shichinohe.aomori.jp")];
+    char stringpool_str3049[sizeof("izena.okinawa.jp")];
+    char stringpool_str3050[sizeof("yamatokoriyama.nara.jp")];
+    char stringpool_str3051[sizeof("skierva.no")];
+    char stringpool_str3052[sizeof("shibata.niigata.jp")];
+    char stringpool_str3053[sizeof("ustka.pl")];
+    char stringpool_str3054[sizeof("cf")];
+    char stringpool_str3055[sizeof("bf")];
+    char stringpool_str3056[sizeof("org.ma")];
+    char stringpool_str3057[sizeof("gf")];
+    char stringpool_str3058[sizeof("nf")];
+    char stringpool_str3059[sizeof("shibetsu.hokkaido.jp")];
+    char stringpool_str3060[sizeof("ifm")];
+    char stringpool_str3061[sizeof("org.ve")];
+    char stringpool_str3062[sizeof("is-a-painter.com")];
+    char stringpool_str3063[sizeof("org.bm")];
+    char stringpool_str3064[sizeof("com.fr")];
+    char stringpool_str3065[sizeof("nom.fr")];
+    char stringpool_str3066[sizeof("saka.hiroshima.jp")];
+    char stringpool_str3067[sizeof("askoy.no")];
+    char stringpool_str3068[sizeof("risor.no")];
+    char stringpool_str3069[sizeof("siljan.no")];
+    char stringpool_str3070[sizeof("grong.no")];
+    char stringpool_str3071[sizeof("raisa.no")];
+    char stringpool_str3072[sizeof("kinko.kagoshima.jp")];
+    char stringpool_str3073[sizeof("ouda.nara.jp")];
+    char stringpool_str3074[sizeof("sayama.osaka.jp")];
+    char stringpool_str3075[sizeof("ovh")];
+    char stringpool_str3076[sizeof("shibecha.hokkaido.jp")];
+    char stringpool_str3077[sizeof("izumi.kagoshima.jp")];
+    char stringpool_str3078[sizeof("higashikagawa.kagawa.jp")];
+    char stringpool_str3079[sizeof("ayabe.kyoto.jp")];
+    char stringpool_str3080[sizeof("ikeda.hokkaido.jp")];
+    char stringpool_str3081[sizeof("aisai.aichi.jp")];
+    char stringpool_str3082[sizeof("org.ba")];
+    char stringpool_str3083[sizeof("org.kp")];
+    char stringpool_str3084[sizeof("imari.saga.jp")];
+    char stringpool_str3085[sizeof("org.hk")];
+    char stringpool_str3086[sizeof("org.ht")];
+    char stringpool_str3087[sizeof("embaixada.st")];
+    char stringpool_str3088[sizeof("nango.fukushima.jp")];
+    char stringpool_str3089[sizeof("sunagawa.hokkaido.jp")];
+    char stringpool_str3090[sizeof("org.kn")];
+    char stringpool_str3091[sizeof("directory")];
+    char stringpool_str3092[sizeof("k12.nv.us")];
+    char stringpool_str3093[sizeof("af")];
+    char stringpool_str3094[sizeof("org.hn")];
+    char stringpool_str3095[sizeof("hyogo.jp")];
+    char stringpool_str3096[sizeof("jgora.pl")];
+    char stringpool_str3097[sizeof("org.na")];
+    char stringpool_str3098[sizeof("zgora.pl")];
+    char stringpool_str3099[sizeof("reggioemilia.it")];
+    char stringpool_str3100[sizeof("dyroy.no")];
+    char stringpool_str3101[sizeof("itano.tokushima.jp")];
+    char stringpool_str3102[sizeof("asahi.nagano.jp")];
+    char stringpool_str3103[sizeof("org.qa")];
+    char stringpool_str3104[sizeof("heroy.nordland.no")];
+    char stringpool_str3105[sizeof("square.museum")];
+    char stringpool_str3106[sizeof("saigawa.fukuoka.jp")];
+    char stringpool_str3107[sizeof("hitoyoshi.kumamoto.jp")];
+    char stringpool_str3108[sizeof("daito.osaka.jp")];
+    char stringpool_str3109[sizeof("chernovtsy.ua")];
+    char stringpool_str3110[sizeof("is-an-actress.com")];
+    char stringpool_str3111[sizeof("hiroo.hokkaido.jp")];
+    char stringpool_str3112[sizeof("shiroishi.saga.jp")];
+    char stringpool_str3113[sizeof("org.la")];
+    char stringpool_str3114[sizeof("kaita.hiroshima.jp")];
+    char stringpool_str3115[sizeof("amami.kagoshima.jp")];
+    char stringpool_str3116[sizeof("kazo.saitama.jp")];
+    char stringpool_str3117[sizeof("akita.akita.jp")];
+    char stringpool_str3118[sizeof("kizu.kyoto.jp")];
+    char stringpool_str3119[sizeof("shinichi.hiroshima.jp")];
+    char stringpool_str3120[sizeof("arita.saga.jp")];
+    char stringpool_str3121[sizeof("minowa.nagano.jp")];
+    char stringpool_str3122[sizeof("vaapste.no")];
+    char stringpool_str3123[sizeof("hongo.hiroshima.jp")];
+    char stringpool_str3124[sizeof("komae.tokyo.jp")];
+    char stringpool_str3125[sizeof("org.eg")];
+    char stringpool_str3126[sizeof("org.sg")];
+    char stringpool_str3127[sizeof("mining.museum")];
+    char stringpool_str3128[sizeof("naganohara.gunma.jp")];
+    char stringpool_str3129[sizeof("org.iq")];
+    char stringpool_str3130[sizeof("agrar.hu")];
+    char stringpool_str3131[sizeof("komono.mie.jp")];
+    char stringpool_str3132[sizeof("is-an-artist.com")];
+    char stringpool_str3133[sizeof("org.ws")];
+    char stringpool_str3134[sizeof("erimo.hokkaido.jp")];
+    char stringpool_str3135[sizeof("minamiawaji.hyogo.jp")];
+    char stringpool_str3136[sizeof("foggia.it")];
+    char stringpool_str3137[sizeof("nishiokoppe.hokkaido.jp")];
+    char stringpool_str3138[sizeof("sasayama.hyogo.jp")];
+    char stringpool_str3139[sizeof("essex.museum")];
+    char stringpool_str3140[sizeof("ashiya.fukuoka.jp")];
+    char stringpool_str3141[sizeof("miyagi.jp")];
+    char stringpool_str3142[sizeof("show.aero")];
+    char stringpool_str3143[sizeof("buryatia.ru")];
+    char stringpool_str3144[sizeof("org.ag")];
+    char stringpool_str3145[sizeof("honjo.akita.jp")];
+    char stringpool_str3146[sizeof("nakanojo.gunma.jp")];
+    char stringpool_str3147[sizeof("is-a-llama.com")];
+    char stringpool_str3148[sizeof("sayama.saitama.jp")];
+    char stringpool_str3149[sizeof("is-a-rockstar.com")];
+    char stringpool_str3150[sizeof("katano.osaka.jp")];
+    char stringpool_str3151[sizeof("org.km")];
+    char stringpool_str3152[sizeof("sweden.museum")];
+    char stringpool_str3153[sizeof("kuzbass.ru")];
+    char stringpool_str3154[sizeof("from-vt.com")];
+    char stringpool_str3155[sizeof("org.ug")];
+    char stringpool_str3156[sizeof("rodoy.no")];
+    char stringpool_str3157[sizeof("kumano.mie.jp")];
+    char stringpool_str3158[sizeof("fitjar.no")];
+    char stringpool_str3159[sizeof("shinshiro.aichi.jp")];
+    char stringpool_str3160[sizeof("skydiving.aero")];
+    char stringpool_str3161[sizeof("suli.hu")];
+    char stringpool_str3162[sizeof("nagano.jp")];
+    char stringpool_str3163[sizeof("musashimurayama.tokyo.jp")];
+    char stringpool_str3164[sizeof("chita.aichi.jp")];
+    char stringpool_str3165[sizeof("fukumitsu.toyama.jp")];
+    char stringpool_str3166[sizeof("is-by.us")];
+    char stringpool_str3167[sizeof("org.mg")];
+    char stringpool_str3168[sizeof("xyz")];
+    char stringpool_str3169[sizeof("net.ci")];
+    char stringpool_str3170[sizeof("inami.wakayama.jp")];
+    char stringpool_str3171[sizeof("kochi.kochi.jp")];
+    char stringpool_str3172[sizeof("com.ci")];
+    char stringpool_str3173[sizeof("radoy.no")];
+    char stringpool_str3174[sizeof("yalta.ua")];
+    char stringpool_str3175[sizeof("edu.ci")];
+    char stringpool_str3176[sizeof("fukusaki.hyogo.jp")];
+    char stringpool_str3177[sizeof("minamisanriku.miyagi.jp")];
+    char stringpool_str3178[sizeof("forgot.his.name")];
+    char stringpool_str3179[sizeof("mukawa.hokkaido.jp")];
+    char stringpool_str3180[sizeof("radio.br")];
+    char stringpool_str3181[sizeof("ginan.gifu.jp")];
+    char stringpool_str3182[sizeof("city.sapporo.jp")];
+    char stringpool_str3183[sizeof("org.ng")];
+    char stringpool_str3184[sizeof("mansion.museum")];
+    char stringpool_str3185[sizeof("honjo.saitama.jp")];
+    char stringpool_str3186[sizeof("miyama.fukuoka.jp")];
+    char stringpool_str3187[sizeof("konyvelo.hu")];
+    char stringpool_str3188[sizeof("sendai.jp")];
+    char stringpool_str3189[sizeof("2000.hu")];
+    char stringpool_str3190[sizeof("info.ec")];
+    char stringpool_str3191[sizeof("suisse.museum")];
+    char stringpool_str3192[sizeof("nagai.yamagata.jp")];
+    char stringpool_str3193[sizeof("kanie.aichi.jp")];
+    char stringpool_str3194[sizeof("murata.miyagi.jp")];
+    char stringpool_str3195[sizeof("opoczno.pl")];
+    char stringpool_str3196[sizeof("askim.no")];
+    char stringpool_str3197[sizeof("yaese.okinawa.jp")];
+    char stringpool_str3198[sizeof("dontexist.net")];
+    char stringpool_str3199[sizeof("blogspot.ca")];
+    char stringpool_str3200[sizeof("ostroda.pl")];
+    char stringpool_str3201[sizeof("batsfjord.no")];
+    char stringpool_str3202[sizeof("mihama.fukui.jp")];
+    char stringpool_str3203[sizeof("iwade.wakayama.jp")];
+    char stringpool_str3204[sizeof("org.ai")];
+    char stringpool_str3205[sizeof("koori.fukushima.jp")];
+    char stringpool_str3206[sizeof("ikeda.gifu.jp")];
+    char stringpool_str3207[sizeof("selfip.org")];
+    char stringpool_str3208[sizeof("industries")];
+    char stringpool_str3209[sizeof("chino.nagano.jp")];
+    char stringpool_str3210[sizeof("iamallama.com")];
+    char stringpool_str3211[sizeof("aerodrome.aero")];
+    char stringpool_str3212[sizeof("blogspot.cz")];
+    char stringpool_str3213[sizeof("stange.no")];
+    char stringpool_str3214[sizeof("org.sz")];
+    char stringpool_str3215[sizeof("akune.kagoshima.jp")];
+    char stringpool_str3216[sizeof("org.dz")];
+    char stringpool_str3217[sizeof("bremanger.no")];
+    char stringpool_str3218[sizeof("academy.museum")];
+    char stringpool_str3219[sizeof("nanjo.okinawa.jp")];
+    char stringpool_str3220[sizeof("ibara.okayama.jp")];
+    char stringpool_str3221[sizeof("contractors")];
+    char stringpool_str3222[sizeof("int.ci")];
+    char stringpool_str3223[sizeof("iwaki.fukushima.jp")];
+    char stringpool_str3224[sizeof("homeftp.net")];
+    char stringpool_str3225[sizeof("blogspot.com")];
+    char stringpool_str3226[sizeof("shimokawa.hokkaido.jp")];
+    char stringpool_str3227[sizeof("gratangen.no")];
+    char stringpool_str3228[sizeof("rygge.no")];
+    char stringpool_str3229[sizeof("ostrowwlkp.pl")];
+    char stringpool_str3230[sizeof("blogspot.com.es")];
+    char stringpool_str3231[sizeof("itami.hyogo.jp")];
+    char stringpool_str3232[sizeof("kumano.hiroshima.jp")];
+    char stringpool_str3233[sizeof("blogspot.co.nz")];
+    char stringpool_str3234[sizeof("asso.nc")];
+    char stringpool_str3235[sizeof("brescia.it")];
+    char stringpool_str3236[sizeof("org.az")];
+    char stringpool_str3237[sizeof("biz.az")];
+    char stringpool_str3238[sizeof("b.ssl.fastly.net")];
+    char stringpool_str3239[sizeof("balsfjord.no")];
+    char stringpool_str3240[sizeof("nishi.osaka.jp")];
+    char stringpool_str3241[sizeof("hiji.oita.jp")];
+    char stringpool_str3242[sizeof("qld.gov.au")];
+    char stringpool_str3243[sizeof("kunitomi.miyazaki.jp")];
+    char stringpool_str3244[sizeof("anthropology.museum")];
+    char stringpool_str3245[sizeof("ballangen.no")];
+    char stringpool_str3246[sizeof("is-a-socialist.com")];
+    char stringpool_str3247[sizeof("bilbao.museum")];
+    char stringpool_str3248[sizeof("org.uz")];
+    char stringpool_str3249[sizeof("nanao.ishikawa.jp")];
+    char stringpool_str3250[sizeof("shijonawate.osaka.jp")];
+    char stringpool_str3251[sizeof("fujioka.gunma.jp")];
+    char stringpool_str3252[sizeof("hyuga.miyazaki.jp")];
+    char stringpool_str3253[sizeof("molde.no")];
+    char stringpool_str3254[sizeof("noda.chiba.jp")];
+    char stringpool_str3255[sizeof("otsuka")];
+    char stringpool_str3256[sizeof("org.kg")];
+    char stringpool_str3257[sizeof("org.bi")];
+    char stringpool_str3258[sizeof("samukawa.kanagawa.jp")];
+    char stringpool_str3259[sizeof("naruto.tokushima.jp")];
+    char stringpool_str3260[sizeof("wakuya.miyagi.jp")];
+    char stringpool_str3261[sizeof("koshu.yamanashi.jp")];
+    char stringpool_str3262[sizeof("nakanoto.ishikawa.jp")];
+    char stringpool_str3263[sizeof("konan.shiga.jp")];
+    char stringpool_str3264[sizeof("rovno.ua")];
+    char stringpool_str3265[sizeof("atsugi.kanagawa.jp")];
+    char stringpool_str3266[sizeof("valdaosta.it")];
+    char stringpool_str3267[sizeof("misugi.mie.jp")];
+    char stringpool_str3268[sizeof("is-an-accountant.com")];
+    char stringpool_str3269[sizeof("a.ssl.fastly.net")];
+    char stringpool_str3270[sizeof("blogspot.com.ar")];
+    char stringpool_str3271[sizeof("szkola.pl")];
+    char stringpool_str3272[sizeof("bialowieza.pl")];
+    char stringpool_str3273[sizeof("dontexist.org")];
+    char stringpool_str3274[sizeof("nemuro.hokkaido.jp")];
+    char stringpool_str3275[sizeof("saroma.hokkaido.jp")];
+    char stringpool_str3276[sizeof("brussels.museum")];
+    char stringpool_str3277[sizeof("bruxelles.museum")];
+    char stringpool_str3278[sizeof("arida.wakayama.jp")];
+    char stringpool_str3279[sizeof("blogspot.com.au")];
+    char stringpool_str3280[sizeof("org.bz")];
+    char stringpool_str3281[sizeof("blogspot.co.at")];
+    char stringpool_str3282[sizeof("modum.no")];
+    char stringpool_str3283[sizeof("blogspot.cv")];
+    char stringpool_str3284[sizeof("ilawa.pl")];
+    char stringpool_str3285[sizeof("okinawa")];
+    char stringpool_str3286[sizeof("usuki.oita.jp")];
+    char stringpool_str3287[sizeof("heroy.more-og-romsdal.no")];
+    char stringpool_str3288[sizeof("friuli-vgiulia.it")];
+    char stringpool_str3289[sizeof("asago.hyogo.jp")];
+    char stringpool_str3290[sizeof("conference.aero")];
+    char stringpool_str3291[sizeof("is-uberleet.com")];
+    char stringpool_str3292[sizeof("org.vi")];
+    char stringpool_str3293[sizeof("sakura.chiba.jp")];
+    char stringpool_str3294[sizeof("misaki.okayama.jp")];
+    char stringpool_str3295[sizeof("asso.mc")];
+    char stringpool_str3296[sizeof("nayoro.hokkaido.jp")];
+    char stringpool_str3297[sizeof("niimi.okayama.jp")];
+    char stringpool_str3298[sizeof("iwate.iwate.jp")];
+    char stringpool_str3299[sizeof("notaires.fr")];
+    char stringpool_str3300[sizeof("fukuyama.hiroshima.jp")];
+    char stringpool_str3301[sizeof("org.sh")];
+    char stringpool_str3302[sizeof("namdalseid.no")];
+    char stringpool_str3303[sizeof("hioki.kagoshima.jp")];
+    char stringpool_str3304[sizeof("org.ph")];
+    char stringpool_str3305[sizeof("cloudcontrolled.com")];
+    char stringpool_str3306[sizeof("rivne.ua")];
+    char stringpool_str3307[sizeof("ostre-toten.no")];
+    char stringpool_str3308[sizeof("oyer.no")];
+    char stringpool_str3309[sizeof("blogspot.com.br")];
+    char stringpool_str3310[sizeof("council.aero")];
+    char stringpool_str3311[sizeof("minamiashigara.kanagawa.jp")];
+    char stringpool_str3312[sizeof("kakinoki.shimane.jp")];
+    char stringpool_str3313[sizeof("yuasa.wakayama.jp")];
+    char stringpool_str3314[sizeof("city.sendai.jp")];
+    char stringpool_str3315[sizeof("game-server.cc")];
+    char stringpool_str3316[sizeof("wajiki.tokushima.jp")];
+    char stringpool_str3317[sizeof("inagi.tokyo.jp")];
+    char stringpool_str3318[sizeof("wajima.ishikawa.jp")];
+    char stringpool_str3319[sizeof("vik.no")];
+    char stringpool_str3320[sizeof("udine.it")];
+    char stringpool_str3321[sizeof("abira.hokkaido.jp")];
+    char stringpool_str3322[sizeof("fuji.shizuoka.jp")];
+    char stringpool_str3323[sizeof("osakasayama.osaka.jp")];
+    char stringpool_str3324[sizeof("kamitonda.wakayama.jp")];
+    char stringpool_str3325[sizeof("cultural.museum")];
+    char stringpool_str3326[sizeof("blogspot.co.il")];
+    char stringpool_str3327[sizeof("ulsan.kr")];
+    char stringpool_str3328[sizeof("azure-mobile.net")];
+    char stringpool_str3329[sizeof("sannan.hyogo.jp")];
+    char stringpool_str3330[sizeof("sekikawa.niigata.jp")];
+    char stringpool_str3331[sizeof("in-the-band.net")];
+    char stringpool_str3332[sizeof("blogspot.ch")];
+    char stringpool_str3333[sizeof("cloudcontrolapp.com")];
+    char stringpool_str3334[sizeof("org.ki")];
+    char stringpool_str3335[sizeof("biz.ki")];
+    char stringpool_str3336[sizeof("rebun.hokkaido.jp")];
+    char stringpool_str3337[sizeof("itayanagi.aomori.jp")];
+    char stringpool_str3338[sizeof("googleapis.com")];
+    char stringpool_str3339[sizeof("oristano.it")];
+    char stringpool_str3340[sizeof("shiojiri.nagano.jp")];
+    char stringpool_str3341[sizeof("is-a-student.com")];
+    char stringpool_str3342[sizeof("doshi.yamanashi.jp")];
+    char stringpool_str3343[sizeof("nishi.fukuoka.jp")];
+    char stringpool_str3344[sizeof("is-a-teacher.com")];
+    char stringpool_str3345[sizeof("wf")];
+    char stringpool_str3346[sizeof("org.gt")];
+    char stringpool_str3347[sizeof("org.gp")];
+    char stringpool_str3348[sizeof("org.gr")];
+    char stringpool_str3349[sizeof("furukawa.miyagi.jp")];
+    char stringpool_str3350[sizeof("shishikui.tokushima.jp")];
+    char stringpool_str3351[sizeof("fujisawa.iwate.jp")];
+    char stringpool_str3352[sizeof("gosen.niigata.jp")];
+    char stringpool_str3353[sizeof("maniwa.okayama.jp")];
+    char stringpool_str3354[sizeof("org.gn")];
+    char stringpool_str3355[sizeof("asahi.yamagata.jp")];
+    char stringpool_str3356[sizeof("yazu.tottori.jp")];
+    char stringpool_str3357[sizeof("namie.fukushima.jp")];
+    char stringpool_str3358[sizeof("friuliv-giulia.it")];
+    char stringpool_str3359[sizeof("kvanangen.no")];
+    char stringpool_str3360[sizeof("mbone.pl")];
+    char stringpool_str3361[sizeof("org.kz")];
+    char stringpool_str3362[sizeof("kasai.hyogo.jp")];
+    char stringpool_str3363[sizeof("org.bh")];
+    char stringpool_str3364[sizeof("skjervoy.no")];
+    char stringpool_str3365[sizeof("is-a-bookkeeper.com")];
+    char stringpool_str3366[sizeof("minami.fukuoka.jp")];
+    char stringpool_str3367[sizeof("is-a-conservative.com")];
+    char stringpool_str3368[sizeof("chofu.tokyo.jp")];
+    char stringpool_str3369[sizeof("anthro.museum")];
+    char stringpool_str3370[sizeof("blogspot.fr")];
+    char stringpool_str3371[sizeof("org.ge")];
+    char stringpool_str3372[sizeof("oji.nara.jp")];
+    char stringpool_str3373[sizeof("vardo.no")];
+    char stringpool_str3374[sizeof("chuo.chiba.jp")];
+    char stringpool_str3375[sizeof("hammerfest.no")];
+    char stringpool_str3376[sizeof("is-a-nurse.com")];
+    char stringpool_str3377[sizeof("nagareyama.chiba.jp")];
+    char stringpool_str3378[sizeof("jerusalem.museum")];
+    char stringpool_str3379[sizeof("asmatart.museum")];
+    char stringpool_str3380[sizeof("uhren.museum")];
+    char stringpool_str3381[sizeof("kosei.shiga.jp")];
+    char stringpool_str3382[sizeof("yurihonjo.akita.jp")];
+    char stringpool_str3383[sizeof("starostwo.gov.pl")];
+    char stringpool_str3384[sizeof("mutsu.aomori.jp")];
+    char stringpool_str3385[sizeof("shibukawa.gunma.jp")];
+    char stringpool_str3386[sizeof("friulivgiulia.it")];
+    char stringpool_str3387[sizeof("berkeley.museum")];
+    char stringpool_str3388[sizeof("consultant.aero")];
+    char stringpool_str3389[sizeof("vadso.no")];
+    char stringpool_str3390[sizeof("act.edu.au")];
+    char stringpool_str3391[sizeof("ashoro.hokkaido.jp")];
+    char stringpool_str3392[sizeof("valle.no")];
+    char stringpool_str3393[sizeof("blogspot.fi")];
+    char stringpool_str3394[sizeof("volda.no")];
+    char stringpool_str3395[sizeof("kiho.mie.jp")];
+    char stringpool_str3396[sizeof("fujiidera.osaka.jp")];
+    char stringpool_str3397[sizeof("milan.it")];
+    char stringpool_str3398[sizeof("ambulance.aero")];
+    char stringpool_str3399[sizeof("okegawa.saitama.jp")];
+    char stringpool_str3400[sizeof("ostroleka.pl")];
+    char stringpool_str3401[sizeof("donostia.museum")];
+    char stringpool_str3402[sizeof("sel.no")];
+    char stringpool_str3403[sizeof("baltimore.museum")];
+    char stringpool_str3404[sizeof("shinagawa.tokyo.jp")];
+    char stringpool_str3405[sizeof("elb.amazonaws.com")];
+    char stringpool_str3406[sizeof("shinshinotsu.hokkaido.jp")];
+    char stringpool_str3407[sizeof("fujisato.akita.jp")];
+    char stringpool_str3408[sizeof("bihoro.hokkaido.jp")];
+    char stringpool_str3409[sizeof("fujieda.shizuoka.jp")];
+    char stringpool_str3410[sizeof("sld.do")];
+    char stringpool_str3411[sizeof("shimogo.fukushima.jp")];
+    char stringpool_str3412[sizeof("haboro.hokkaido.jp")];
+    char stringpool_str3413[sizeof("okinawa.jp")];
+    char stringpool_str3414[sizeof("seki.gifu.jp")];
+    char stringpool_str3415[sizeof("columbia.museum")];
+    char stringpool_str3416[sizeof("yusui.kagoshima.jp")];
+    char stringpool_str3417[sizeof("blogspot.co.uk")];
+    char stringpool_str3418[sizeof("annefrank.museum")];
+    char stringpool_str3419[sizeof("aarborte.no")];
+    char stringpool_str3420[sizeof("oygarden.no")];
+    char stringpool_str3421[sizeof("hazu.aichi.jp")];
+    char stringpool_str3422[sizeof("hammarfeasta.no")];
+    char stringpool_str3423[sizeof("yamato.kumamoto.jp")];
+    char stringpool_str3424[sizeof("chambagri.fr")];
+    char stringpool_str3425[sizeof("azurewebsites.net")];
+    char stringpool_str3426[sizeof("krokstadelva.no")];
+    char stringpool_str3427[sizeof("is-an-entertainer.com")];
+    char stringpool_str3428[sizeof("ohda.shimane.jp")];
+    char stringpool_str3429[sizeof("vefsn.no")];
+    char stringpool_str3430[sizeof("american.museum")];
+    char stringpool_str3431[sizeof("yotsukaido.chiba.jp")];
+    char stringpool_str3432[sizeof("komoro.nagano.jp")];
+    char stringpool_str3433[sizeof("culturalcenter.museum")];
+    char stringpool_str3434[sizeof("is-into-cars.com")];
+    char stringpool_str3435[sizeof("mikawa.yamagata.jp")];
+    char stringpool_str3436[sizeof("cloudfront.net")];
+    char stringpool_str3437[sizeof("yorii.saitama.jp")];
+    char stringpool_str3438[sizeof("fukagawa.hokkaido.jp")];
+    char stringpool_str3439[sizeof("mihama.wakayama.jp")];
+    char stringpool_str3440[sizeof("fujimino.saitama.jp")];
+    char stringpool_str3441[sizeof("kolobrzeg.pl")];
+    char stringpool_str3442[sizeof("omsk.ru")];
+    char stringpool_str3443[sizeof("nieruchomosci.pl")];
+    char stringpool_str3444[sizeof("kuzumaki.iwate.jp")];
+    char stringpool_str3445[sizeof("shiranuka.hokkaido.jp")];
+    char stringpool_str3446[sizeof("insurance.aero")];
+    char stringpool_str3447[sizeof("homeunix.com")];
+    char stringpool_str3448[sizeof("yoshioka.gunma.jp")];
+    char stringpool_str3449[sizeof("fukushima.hokkaido.jp")];
+    char stringpool_str3450[sizeof("iwakura.aichi.jp")];
+    char stringpool_str3451[sizeof("vagan.no")];
+    char stringpool_str3452[sizeof("koza.wakayama.jp")];
+    char stringpool_str3453[sizeof("omi.nagano.jp")];
+    char stringpool_str3454[sizeof("shirataka.yamagata.jp")];
+    char stringpool_str3455[sizeof("nebraska.museum")];
+    char stringpool_str3456[sizeof("shimosuwa.nagano.jp")];
+    char stringpool_str3457[sizeof("artcenter.museum")];
+    char stringpool_str3458[sizeof("journalist.aero")];
+    char stringpool_str3459[sizeof("chocolate.museum")];
+    char stringpool_str3460[sizeof("is-a-personaltrainer.com")];
+    char stringpool_str3461[sizeof("dyndns-pics.com")];
+    char stringpool_str3462[sizeof("naamesjevuemie.no")];
+    char stringpool_str3463[sizeof("openair.museum")];
+    char stringpool_str3464[sizeof("oshu.iwate.jp")];
+    char stringpool_str3465[sizeof("kchr.ru")];
+    char stringpool_str3466[sizeof("yamamoto.miyagi.jp")];
+    char stringpool_str3467[sizeof("stjohn.museum")];
+    char stringpool_str3468[sizeof("shimizu.hokkaido.jp")];
+    char stringpool_str3469[sizeof("ontario.museum")];
+    char stringpool_str3470[sizeof("fet.no")];
+    char stringpool_str3471[sizeof("epilepsy.museum")];
+    char stringpool_str3472[sizeof("airguard.museum")];
+    char stringpool_str3473[sizeof("sapporo.jp")];
+    char stringpool_str3474[sizeof("aguni.okinawa.jp")];
+    char stringpool_str3475[sizeof("sagamihara.kanagawa.jp")];
+    char stringpool_str3476[sizeof("groks-this.info")];
+    char stringpool_str3477[sizeof("oppegard.no")];
+    char stringpool_str3478[sizeof("otsu.shiga.jp")];
+    char stringpool_str3479[sizeof("overhalla.no")];
+    char stringpool_str3480[sizeof("meloy.no")];
+    char stringpool_str3481[sizeof("viking.museum")];
+    char stringpool_str3482[sizeof("helsinki.museum")];
+    char stringpool_str3483[sizeof("dyndns-ip.com")];
+    char stringpool_str3484[sizeof("shisui.chiba.jp")];
+    char stringpool_str3485[sizeof("freight.aero")];
+    char stringpool_str3486[sizeof("ls")];
+    char stringpool_str3487[sizeof("new")];
+    char stringpool_str3488[sizeof("org.gg")];
+    char stringpool_str3489[sizeof("barreau.bj")];
+    char stringpool_str3490[sizeof("creation.museum")];
+    char stringpool_str3491[sizeof("shiroishi.miyagi.jp")];
+    char stringpool_str3492[sizeof("support")];
+    char stringpool_str3493[sizeof("lease")];
+    char stringpool_str3494[sizeof("dreamhosters.com")];
+    char stringpool_str3495[sizeof("friuli-v-giulia.it")];
+    char stringpool_str3496[sizeof("immobilien")];
+    char stringpool_str3497[sizeof("shop.pl")];
+    char stringpool_str3498[sizeof("altoadige.it")];
+    char stringpool_str3499[sizeof("boleslawiec.pl")];
+    char stringpool_str3500[sizeof("city.nagoya.jp")];
+    char stringpool_str3501[sizeof("london")];
+    char stringpool_str3502[sizeof("uruma.okinawa.jp")];
+    char stringpool_str3503[sizeof("casino.hu")];
+    char stringpool_str3504[sizeof("baseball.museum")];
+    char stringpool_str3505[sizeof("la")];
+    char stringpool_str3506[sizeof("land")];
+    char stringpool_str3507[sizeof("church")];
+    char stringpool_str3508[sizeof("nagano.nagano.jp")];
+    char stringpool_str3509[sizeof("oga.akita.jp")];
+    char stringpool_str3510[sizeof("lt")];
+    char stringpool_str3511[sizeof("net.au")];
+    char stringpool_str3512[sizeof("ama.aichi.jp")];
+    char stringpool_str3513[sizeof("ambulance.museum")];
+    char stringpool_str3514[sizeof("com.au")];
+    char stringpool_str3515[sizeof("nikaho.akita.jp")];
+    char stringpool_str3516[sizeof("gov.au")];
+    char stringpool_str3517[sizeof("shimizu.shizuoka.jp")];
+    char stringpool_str3518[sizeof("lr")];
+    char stringpool_str3519[sizeof("nrw")];
+    char stringpool_str3520[sizeof("hirono.iwate.jp")];
+    char stringpool_str3521[sizeof("gouv.km")];
+    char stringpool_str3522[sizeof("net.ru")];
+    char stringpool_str3523[sizeof("com.ru")];
+    char stringpool_str3524[sizeof("gov.ru")];
+    char stringpool_str3525[sizeof("nov.ru")];
+    char stringpool_str3526[sizeof("lu")];
+    char stringpool_str3527[sizeof("vgs.no")];
+    char stringpool_str3528[sizeof("kamigori.hyogo.jp")];
+    char stringpool_str3529[sizeof("association.aero")];
+    char stringpool_str3530[sizeof("edu.au")];
+    char stringpool_str3531[sizeof("krym.ua")];
+    char stringpool_str3532[sizeof("shinkamigoto.nagasaki.jp")];
+    char stringpool_str3533[sizeof("edu.ru")];
+    char stringpool_str3534[sizeof("is-into-cartoons.com")];
+    char stringpool_str3535[sizeof("net.mu")];
+    char stringpool_str3536[sizeof("com.mu")];
+    char stringpool_str3537[sizeof("oregontrail.museum")];
+    char stringpool_str3538[sizeof("gov.mu")];
+    char stringpool_str3539[sizeof("jar.ru")];
+    char stringpool_str3540[sizeof("asn.au")];
+    char stringpool_str3541[sizeof("aisho.shiga.jp")];
+    char stringpool_str3542[sizeof("dnsalias.com")];
+    char stringpool_str3543[sizeof("gouv.rw")];
+    char stringpool_str3544[sizeof("li")];
+    char stringpool_str3545[sizeof("yoita.niigata.jp")];
+    char stringpool_str3546[sizeof("lebesby.no")];
+    char stringpool_str3547[sizeof("omigawa.chiba.jp")];
+    char stringpool_str3548[sizeof("lom.it")];
+    char stringpool_str3549[sizeof("hobby-site.com")];
+    char stringpool_str3550[sizeof("is-a-blogger.com")];
+    char stringpool_str3551[sizeof("limo")];
+    char stringpool_str3552[sizeof("lb")];
+    char stringpool_str3553[sizeof("karumai.iwate.jp")];
+    char stringpool_str3554[sizeof("media.pl")];
+    char stringpool_str3555[sizeof("interactive.museum")];
+    char stringpool_str3556[sizeof("is-a-republican.com")];
+    char stringpool_str3557[sizeof("yamanouchi.nagano.jp")];
+    char stringpool_str3558[sizeof("coal.museum")];
+    char stringpool_str3559[sizeof("fla.no")];
+    char stringpool_str3560[sizeof("lund.no")];
+    char stringpool_str3561[sizeof("ritto.shiga.jp")];
+    char stringpool_str3562[sizeof("kaminoyama.yamagata.jp")];
+    char stringpool_str3563[sizeof("fujikawa.shizuoka.jp")];
+    char stringpool_str3564[sizeof("omaezaki.shizuoka.jp")];
+    char stringpool_str3565[sizeof("bir.ru")];
+    char stringpool_str3566[sizeof("yakumo.shimane.jp")];
+    char stringpool_str3567[sizeof("money.museum")];
+    char stringpool_str3568[sizeof("video.hu")];
+    char stringpool_str3569[sizeof("bunkyo.tokyo.jp")];
+    char stringpool_str3570[sizeof("guernsey.museum")];
+    char stringpool_str3571[sizeof("sarpsborg.no")];
+    char stringpool_str3572[sizeof("link")];
+    char stringpool_str3573[sizeof("gouv.bj")];
+    char stringpool_str3574[sizeof("zakopane.pl")];
+    char stringpool_str3575[sizeof("okutama.tokyo.jp")];
+    char stringpool_str3576[sizeof("org.gi")];
+    char stringpool_str3577[sizeof("mc")];
+    char stringpool_str3578[sizeof("lib.ee")];
+    char stringpool_str3579[sizeof("gouv.ml")];
+    char stringpool_str3580[sizeof("iraq.museum")];
+    char stringpool_str3581[sizeof("ikawa.akita.jp")];
+    char stringpool_str3582[sizeof("leg.br")];
+    char stringpool_str3583[sizeof("is-a-geek.net")];
+    char stringpool_str3584[sizeof("lel.br")];
+    char stringpool_str3585[sizeof("life")];
+    char stringpool_str3586[sizeof("lv")];
+    char stringpool_str3587[sizeof("from-or.com")];
+    char stringpool_str3588[sizeof("oumu.hokkaido.jp")];
+    char stringpool_str3589[sizeof("int.ru")];
+    char stringpool_str3590[sizeof("miasa.nagano.jp")];
+    char stringpool_str3591[sizeof("chiyoda.gunma.jp")];
+    char stringpool_str3592[sizeof("city.kawasaki.jp")];
+    char stringpool_str3593[sizeof("boutique")];
+    char stringpool_str3594[sizeof("natuurwetenschappen.museum")];
+    char stringpool_str3595[sizeof("shiroi.chiba.jp")];
+    char stringpool_str3596[sizeof("omitama.ibaraki.jp")];
+    char stringpool_str3597[sizeof("beeldengeluid.museum")];
+    char stringpool_str3598[sizeof("elvendrell.museum")];
+    char stringpool_str3599[sizeof("l.bg")];
+    char stringpool_str3600[sizeof("national.museum")];
+    char stringpool_str3601[sizeof("gouv.sn")];
+    char stringpool_str3602[sizeof("masoy.no")];
+    char stringpool_str3603[sizeof("gouv.ci")];
+    char stringpool_str3604[sizeof("cbg.ru")];
+    char stringpool_str3605[sizeof("shirahama.wakayama.jp")];
+    char stringpool_str3606[sizeof("dynalias.com")];
+    char stringpool_str3607[sizeof("iki.fi")];
+    char stringpool_str3608[sizeof("nankoku.kochi.jp")];
+    char stringpool_str3609[sizeof("nakano.tokyo.jp")];
+    char stringpool_str3610[sizeof("agano.niigata.jp")];
+    char stringpool_str3611[sizeof("oppdal.no")];
+    char stringpool_str3612[sizeof("association.museum")];
+    char stringpool_str3613[sizeof("arts.museum")];
+    char stringpool_str3614[sizeof("orkanger.no")];
+    char stringpool_str3615[sizeof("varoy.no")];
+    char stringpool_str3616[sizeof("nikko.tochigi.jp")];
+    char stringpool_str3617[sizeof("hattfjelldal.no")];
+    char stringpool_str3618[sizeof("is-into-games.com")];
+    char stringpool_str3619[sizeof("saratov.ru")];
+    char stringpool_str3620[sizeof("is-certified.com")];
+    char stringpool_str3621[sizeof("bahccavuotna.no")];
+    char stringpool_str3622[sizeof("kasukabe.saitama.jp")];
+    char stringpool_str3623[sizeof("chiropractic.museum")];
+    char stringpool_str3624[sizeof("yonago.tottori.jp")];
+    char stringpool_str3625[sizeof("sumida.tokyo.jp")];
+    char stringpool_str3626[sizeof("kraanghke.no")];
+    char stringpool_str3627[sizeof("homeftp.org")];
+    char stringpool_str3628[sizeof("ulvik.no")];
+    char stringpool_str3629[sizeof("bern.museum")];
+    char stringpool_str3630[sizeof("bonn.museum")];
+    char stringpool_str3631[sizeof("bale.museum")];
+    char stringpool_str3632[sizeof("org.sv")];
+    char stringpool_str3633[sizeof("ascoli-piceno.it")];
+    char stringpool_str3634[sizeof("is-a-guru.com")];
+    char stringpool_str3635[sizeof("how")];
+    char stringpool_str3636[sizeof("ltd.lk")];
+    char stringpool_str3637[sizeof("lig.it")];
+    char stringpool_str3638[sizeof("from-ok.com")];
+    char stringpool_str3639[sizeof("botanical.museum")];
+    char stringpool_str3640[sizeof("kids.museum")];
+    char stringpool_str3641[sizeof("children.museum")];
+    char stringpool_str3642[sizeof("hokuto.hokkaido.jp")];
+    char stringpool_str3643[sizeof("lk")];
+    char stringpool_str3644[sizeof("gouv.fr")];
+    char stringpool_str3645[sizeof("bill.museum")];
+    char stringpool_str3646[sizeof("otofuke.hokkaido.jp")];
+    char stringpool_str3647[sizeof("oishida.yamagata.jp")];
+    char stringpool_str3648[sizeof("research.aero")];
+    char stringpool_str3649[sizeof("is-a-patsfan.org")];
+    char stringpool_str3650[sizeof("ibigawa.gifu.jp")];
+    char stringpool_str3651[sizeof("sumita.iwate.jp")];
+    char stringpool_str3652[sizeof("elverum.no")];
+    char stringpool_str3653[sizeof("columbus.museum")];
+    char stringpool_str3654[sizeof("k12.mo.us")];
+    char stringpool_str3655[sizeof("glas.museum")];
+    char stringpool_str3656[sizeof("britishcolumbia.museum")];
+    char stringpool_str3657[sizeof("l.se")];
+    char stringpool_str3658[sizeof("is-a-geek.org")];
+    char stringpool_str3659[sizeof("awaji.hyogo.jp")];
+    char stringpool_str3660[sizeof("isshiki.aichi.jp")];
+    char stringpool_str3661[sizeof("hakui.ishikawa.jp")];
+    char stringpool_str3662[sizeof("is-a-designer.com")];
+    char stringpool_str3663[sizeof("city.hu")];
+    char stringpool_str3664[sizeof("livorno.it")];
+    char stringpool_str3665[sizeof("ogi.saga.jp")];
+    char stringpool_str3666[sizeof("khv.ru")];
+    char stringpool_str3667[sizeof("mil.cl")];
+    char stringpool_str3668[sizeof("org.mv")];
+    char stringpool_str3669[sizeof("biz.mv")];
+    char stringpool_str3670[sizeof("artgallery.museum")];
+    char stringpool_str3671[sizeof("mil.cn")];
+    char stringpool_str3672[sizeof("narashino.chiba.jp")];
+    char stringpool_str3673[sizeof("historichouses.museum")];
+    char stringpool_str3674[sizeof("ski.no")];
+    char stringpool_str3675[sizeof("ishinomaki.miyagi.jp")];
+    char stringpool_str3676[sizeof("kids.us")];
+    char stringpool_str3677[sizeof("lillesand.no")];
+    char stringpool_str3678[sizeof("dyndns-at-home.com")];
+    char stringpool_str3679[sizeof("station.museum")];
+    char stringpool_str3680[sizeof("civilwar.museum")];
+    char stringpool_str3681[sizeof("leasing.aero")];
+    char stringpool_str3682[sizeof("institute")];
+    char stringpool_str3683[sizeof("kms.ru")];
+    char stringpool_str3684[sizeof("sopot.pl")];
+    char stringpool_str3685[sizeof("org.gh")];
+    char stringpool_str3686[sizeof("chiyoda.tokyo.jp")];
+    char stringpool_str3687[sizeof("onagawa.miyagi.jp")];
+    char stringpool_str3688[sizeof("from-oh.com")];
+    char stringpool_str3689[sizeof("ayase.kanagawa.jp")];
+    char stringpool_str3690[sizeof("media.museum")];
+    char stringpool_str3691[sizeof("seaport.museum")];
+    char stringpool_str3692[sizeof("lipetsk.ru")];
+    char stringpool_str3693[sizeof("is-a-hard-worker.com")];
+    char stringpool_str3694[sizeof("yashio.saitama.jp")];
+    char stringpool_str3695[sizeof("hoylandet.no")];
+    char stringpool_str3696[sizeof("iron.museum")];
+    char stringpool_str3697[sizeof("kuroiso.tochigi.jp")];
+    char stringpool_str3698[sizeof("honjyo.akita.jp")];
+    char stringpool_str3699[sizeof("funagata.yamagata.jp")];
+    char stringpool_str3700[sizeof("sakegawa.yamagata.jp")];
+    char stringpool_str3701[sizeof("hokuto.yamanashi.jp")];
+    char stringpool_str3702[sizeof("org.lv")];
+    char stringpool_str3703[sizeof("manno.kagawa.jp")];
+    char stringpool_str3704[sizeof("milano.it")];
+    char stringpool_str3705[sizeof("lier.no")];
+    char stringpool_str3706[sizeof("fukaya.saitama.jp")];
+    char stringpool_str3707[sizeof("umaji.kochi.jp")];
+    char stringpool_str3708[sizeof("exchange")];
+    char stringpool_str3709[sizeof("vc")];
+    char stringpool_str3710[sizeof("minoh.osaka.jp")];
+    char stringpool_str3711[sizeof("iwakuni.yamaguchi.jp")];
+    char stringpool_str3712[sizeof("vikna.no")];
+    char stringpool_str3713[sizeof("artsandcrafts.museum")];
+    char stringpool_str3714[sizeof("ooshika.nagano.jp")];
+    char stringpool_str3715[sizeof("ebina.kanagawa.jp")];
+    char stringpool_str3716[sizeof("is-a-chef.net")];
+    char stringpool_str3717[sizeof("orland.no")];
+    char stringpool_str3718[sizeof("bahn.museum")];
+    char stringpool_str3719[sizeof("yaita.tochigi.jp")];
+    char stringpool_str3720[sizeof("dinosaur.museum")];
+    char stringpool_str3721[sizeof("mielno.pl")];
+    char stringpool_str3722[sizeof("veneto.it")];
+    char stringpool_str3723[sizeof("skoczow.pl")];
+    char stringpool_str3724[sizeof("uozu.toyama.jp")];
+    char stringpool_str3725[sizeof("nakai.kanagawa.jp")];
+    char stringpool_str3726[sizeof("consulting.aero")];
+    char stringpool_str3727[sizeof("sauda.no")];
+    char stringpool_str3728[sizeof("sorum.no")];
+    char stringpool_str3729[sizeof("riodejaneiro.museum")];
+    char stringpool_str3730[sizeof("botanicgarden.museum")];
+    char stringpool_str3731[sizeof("fhs.no")];
+    char stringpool_str3732[sizeof("sakata.yamagata.jp")];
+    char stringpool_str3733[sizeof("onomichi.hiroshima.jp")];
+    char stringpool_str3734[sizeof("kawasaki.jp")];
+    char stringpool_str3735[sizeof("kvalsund.no")];
+    char stringpool_str3736[sizeof("nakano.nagano.jp")];
+    char stringpool_str3737[sizeof("shiogama.miyagi.jp")];
+    char stringpool_str3738[sizeof("media.hu")];
+    char stringpool_str3739[sizeof("olbiatempio.it")];
+    char stringpool_str3740[sizeof("fujishiro.ibaraki.jp")];
+    char stringpool_str3741[sizeof("hirado.nagasaki.jp")];
+    char stringpool_str3742[sizeof("ly")];
+    char stringpool_str3743[sizeof("ringsaker.no")];
+    char stringpool_str3744[sizeof("exchange.aero")];
+    char stringpool_str3745[sizeof("kyowa.akita.jp")];
+    char stringpool_str3746[sizeof("abu.yamaguchi.jp")];
+    char stringpool_str3747[sizeof("city.kitakyushu.jp")];
+    char stringpool_str3748[sizeof("salat.no")];
+    char stringpool_str3749[sizeof("osakikamijima.hiroshima.jp")];
+    char stringpool_str3750[sizeof("andasuolo.no")];
+    char stringpool_str3751[sizeof("aviation.museum")];
+    char stringpool_str3752[sizeof("shoo.okayama.jp")];
+    char stringpool_str3753[sizeof("dyndns-at-work.com")];
+    char stringpool_str3754[sizeof("somna.no")];
+    char stringpool_str3755[sizeof("nsk.ru")];
+    char stringpool_str3756[sizeof("yakumo.hokkaido.jp")];
+    char stringpool_str3757[sizeof("ringerike.no")];
+    char stringpool_str3758[sizeof("judygarland.museum")];
+    char stringpool_str3759[sizeof("ogasawara.tokyo.jp")];
+    char stringpool_str3760[sizeof("la-spezia.it")];
+    char stringpool_str3761[sizeof("snasa.no")];
+    char stringpool_str3762[sizeof("kouyama.kagoshima.jp")];
+    char stringpool_str3763[sizeof("hachinohe.aomori.jp")];
+    char stringpool_str3764[sizeof("sogne.no")];
+    char stringpool_str3765[sizeof("is-a-photographer.com")];
+    char stringpool_str3766[sizeof("is-a-chef.org")];
+    char stringpool_str3767[sizeof("dyndns-blog.com")];
+    char stringpool_str3768[sizeof("arkhangelsk.ru")];
+    char stringpool_str3769[sizeof("kitagawa.kochi.jp")];
+    char stringpool_str3770[sizeof("askvoll.no")];
+    char stringpool_str3771[sizeof("juif.museum")];
+    char stringpool_str3772[sizeof("leka.no")];
+    char stringpool_str3773[sizeof("andria-barletta-trani.it")];
+    char stringpool_str3774[sizeof("achi.nagano.jp")];
+    char stringpool_str3775[sizeof("shirakawa.gifu.jp")];
+    char stringpool_str3776[sizeof("naturhistorisches.museum")];
+    char stringpool_str3777[sizeof("zushi.kanagawa.jp")];
+    char stringpool_str3778[sizeof("okinoshima.shimane.jp")];
+    char stringpool_str3779[sizeof("vic.gov.au")];
+    char stringpool_str3780[sizeof("zgorzelec.pl")];
+    char stringpool_str3781[sizeof("waw.pl")];
+    char stringpool_str3782[sizeof("minato.osaka.jp")];
+    char stringpool_str3783[sizeof("nagiso.nagano.jp")];
+    char stringpool_str3784[sizeof("odessa.ua")];
+    char stringpool_str3785[sizeof("legnica.pl")];
+    char stringpool_str3786[sizeof("davvesiida.no")];
+    char stringpool_str3787[sizeof("hichiso.gifu.jp")];
+    char stringpool_str3788[sizeof("onga.fukuoka.jp")];
+    char stringpool_str3789[sizeof("lugansk.ua")];
+    char stringpool_str3790[sizeof("washingtondc.museum")];
+    char stringpool_str3791[sizeof("sanok.pl")];
+    char stringpool_str3792[sizeof("smola.no")];
+    char stringpool_str3793[sizeof("forde.no")];
+    char stringpool_str3794[sizeof("nozawaonsen.nagano.jp")];
+    char stringpool_str3795[sizeof("marumori.miyagi.jp")];
+    char stringpool_str3796[sizeof("marketplace.aero")];
+    char stringpool_str3797[sizeof("experts-comptables.fr")];
+    char stringpool_str3798[sizeof("okinawa.okinawa.jp")];
+    char stringpool_str3799[sizeof("watchandclock.museum")];
+    char stringpool_str3800[sizeof("space.museum")];
+    char stringpool_str3801[sizeof("state.museum")];
+    char stringpool_str3802[sizeof("supplies")];
+    char stringpool_str3803[sizeof("oiso.kanagawa.jp")];
+    char stringpool_str3804[sizeof("futaba.fukushima.jp")];
+    char stringpool_str3805[sizeof("york.museum")];
+    char stringpool_str3806[sizeof("selbu.no")];
+    char stringpool_str3807[sizeof("land-4-sale.us")];
+    char stringpool_str3808[sizeof("seoul.kr")];
+    char stringpool_str3809[sizeof("stadt.museum")];
+    char stringpool_str3810[sizeof("fujikawa.yamanashi.jp")];
+    char stringpool_str3811[sizeof("jewelry.museum")];
+    char stringpool_str3812[sizeof("obihiro.hokkaido.jp")];
+    char stringpool_str3813[sizeof("sklep.pl")];
+    char stringpool_str3814[sizeof("daiwa.hiroshima.jp")];
+    char stringpool_str3815[sizeof("windmill.museum")];
+    char stringpool_str3816[sizeof("miyakonojo.miyazaki.jp")];
+    char stringpool_str3817[sizeof("noboribetsu.hokkaido.jp")];
+    char stringpool_str3818[sizeof("fermo.it")];
+    char stringpool_str3819[sizeof("building.museum")];
+    char stringpool_str3820[sizeof("mytis.ru")];
+    char stringpool_str3821[sizeof("store.ro")];
+    char stringpool_str3822[sizeof("hashima.gifu.jp")];
+    char stringpool_str3823[sizeof("steam.museum")];
+    char stringpool_str3824[sizeof("fortworth.museum")];
+    char stringpool_str3825[sizeof("siena.it")];
+    char stringpool_str3826[sizeof("jeonbuk.kr")];
+    char stringpool_str3827[sizeof("nisshin.aichi.jp")];
+    char stringpool_str3828[sizeof("eniwa.hokkaido.jp")];
+    char stringpool_str3829[sizeof("discount")];
+    char stringpool_str3830[sizeof("yusuhara.kochi.jp")];
+    char stringpool_str3831[sizeof("oirase.aomori.jp")];
+    char stringpool_str3832[sizeof("moriyoshi.akita.jp")];
+    char stringpool_str3833[sizeof("wloclawek.pl")];
+    char stringpool_str3834[sizeof("homelinux.com")];
+    char stringpool_str3835[sizeof("orkdal.no")];
+    char stringpool_str3836[sizeof("lincoln.museum")];
+    char stringpool_str3837[sizeof("slask.pl")];
+    char stringpool_str3838[sizeof("omi.niigata.jp")];
+    char stringpool_str3839[sizeof("surgeonshall.museum")];
+    char stringpool_str3840[sizeof("is-a-bruinsfan.org")];
+    char stringpool_str3841[sizeof("homebuilt.aero")];
+    char stringpool_str3842[sizeof("lorenskog.no")];
+    char stringpool_str3843[sizeof("yachimata.chiba.jp")];
+    char stringpool_str3844[sizeof("assedic.fr")];
+    char stringpool_str3845[sizeof("dominic.ua")];
+    char stringpool_str3846[sizeof("salem.museum")];
+    char stringpool_str3847[sizeof("klepp.no")];
+    char stringpool_str3848[sizeof("qld.au")];
+    char stringpool_str3849[sizeof("shonai.yamagata.jp")];
+    char stringpool_str3850[sizeof("stord.no")];
+    char stringpool_str3851[sizeof("skaun.no")];
+    char stringpool_str3852[sizeof("roma.museum")];
+    char stringpool_str3853[sizeof("convent.museum")];
+    char stringpool_str3854[sizeof("kiwi")];
+    char stringpool_str3855[sizeof("liguria.it")];
+    char stringpool_str3856[sizeof("ryuoh.shiga.jp")];
+    char stringpool_str3857[sizeof("hirono.fukushima.jp")];
+    char stringpool_str3858[sizeof("frana.no")];
+    char stringpool_str3859[sizeof("groks-the.info")];
+    char stringpool_str3860[sizeof("oksnes.no")];
+    char stringpool_str3861[sizeof("copenhagen.museum")];
+    char stringpool_str3862[sizeof("minano.saitama.jp")];
+    char stringpool_str3863[sizeof("aso.kumamoto.jp")];
+    char stringpool_str3864[sizeof("yorkshire.museum")];
+    char stringpool_str3865[sizeof("iyo.ehime.jp")];
+    char stringpool_str3866[sizeof("misato.shimane.jp")];
+    char stringpool_str3867[sizeof("kasugai.aichi.jp")];
+    char stringpool_str3868[sizeof("usgarden.museum")];
+    char stringpool_str3869[sizeof("lyngdal.no")];
+    char stringpool_str3870[sizeof("fjell.no")];
+    char stringpool_str3871[sizeof("force.museum")];
+    char stringpool_str3872[sizeof("sanuki.kagawa.jp")];
+    char stringpool_str3873[sizeof("soja.okayama.jp")];
+    char stringpool_str3874[sizeof("kyowa.hokkaido.jp")];
+    char stringpool_str3875[sizeof("midatlantic.museum")];
+    char stringpool_str3876[sizeof("orskog.no")];
+    char stringpool_str3877[sizeof("hitachi.ibaraki.jp")];
+    char stringpool_str3878[sizeof("yamato.fukushima.jp")];
+    char stringpool_str3879[sizeof("humanities.museum")];
+    char stringpool_str3880[sizeof("broker.aero")];
+    char stringpool_str3881[sizeof("dynathome.net")];
+    char stringpool_str3882[sizeof("store.st")];
+    char stringpool_str3883[sizeof("lancashire.museum")];
+    char stringpool_str3884[sizeof("yuu.yamaguchi.jp")];
+    char stringpool_str3885[sizeof("saikai.nagasaki.jp")];
+    char stringpool_str3886[sizeof("fujisawa.kanagawa.jp")];
+    char stringpool_str3887[sizeof("higashiura.aichi.jp")];
+    char stringpool_str3888[sizeof("kikuchi.kumamoto.jp")];
+    char stringpool_str3889[sizeof("sakaki.nagano.jp")];
+    char stringpool_str3890[sizeof("workshop.museum")];
+    char stringpool_str3891[sizeof("rnd.ru")];
+    char stringpool_str3892[sizeof("ukiha.fukuoka.jp")];
+    char stringpool_str3893[sizeof("oregon.museum")];
+    char stringpool_str3894[sizeof("chuvashia.ru")];
+    char stringpool_str3895[sizeof("accident-prevention.aero")];
+    char stringpool_str3896[sizeof("levanger.no")];
+    char stringpool_str3897[sizeof("field.museum")];
+    char stringpool_str3898[sizeof("homeip.net")];
+    char stringpool_str3899[sizeof("hadano.kanagawa.jp")];
+    char stringpool_str3900[sizeof("nsw.edu.au")];
+    char stringpool_str3901[sizeof("rovigo.it")];
+    char stringpool_str3902[sizeof("misato.akita.jp")];
+    char stringpool_str3903[sizeof("iwafune.tochigi.jp")];
+    char stringpool_str3904[sizeof("rotorcraft.aero")];
+    char stringpool_str3905[sizeof("coloradoplateau.museum")];
+    char stringpool_str3906[sizeof("montreal.museum")];
+    char stringpool_str3907[sizeof("lavangen.no")];
+    char stringpool_str3908[sizeof("izumizaki.fukushima.jp")];
+    char stringpool_str3909[sizeof("rochester.museum")];
+    char stringpool_str3910[sizeof("ullensaker.no")];
+    char stringpool_str3911[sizeof("selje.no")];
+    char stringpool_str3912[sizeof("williamsburg.museum")];
+    char stringpool_str3913[sizeof("hirokawa.fukuoka.jp")];
+    char stringpool_str3914[sizeof("kamitsue.oita.jp")];
+    char stringpool_str3915[sizeof("carbonia-iglesias.it")];
+    char stringpool_str3916[sizeof("kawakami.nara.jp")];
+    char stringpool_str3917[sizeof("beppu.oita.jp")];
+    char stringpool_str3918[sizeof("lucania.it")];
+    char stringpool_str3919[sizeof("skole.museum")];
+    char stringpool_str3920[sizeof("aknoluokta.no")];
+    char stringpool_str3921[sizeof("misato.saitama.jp")];
+    char stringpool_str3922[sizeof("forum.hu")];
+    char stringpool_str3923[sizeof("recreation.aero")];
+    char stringpool_str3924[sizeof("aquarium.museum")];
+    char stringpool_str3925[sizeof("sango.nara.jp")];
+    char stringpool_str3926[sizeof("jaworzno.pl")];
+    char stringpool_str3927[sizeof("ogliastra.it")];
+    char stringpool_str3928[sizeof("nnov.ru")];
+    char stringpool_str3929[sizeof("satte.saitama.jp")];
+    char stringpool_str3930[sizeof("yamato.kanagawa.jp")];
+    char stringpool_str3931[sizeof("semine.miyagi.jp")];
+    char stringpool_str3932[sizeof("iwatsuki.saitama.jp")];
+    char stringpool_str3933[sizeof("okagaki.fukuoka.jp")];
+    char stringpool_str3934[sizeof("meguro.tokyo.jp")];
+    char stringpool_str3935[sizeof("kawahara.tottori.jp")];
+    char stringpool_str3936[sizeof("mitou.yamaguchi.jp")];
+    char stringpool_str3937[sizeof("lucerne.museum")];
+    char stringpool_str3938[sizeof("narviika.no")];
+    char stringpool_str3939[sizeof("kaneyama.fukushima.jp")];
+    char stringpool_str3940[sizeof("shell.museum")];
+    char stringpool_str3941[sizeof("dali.museum")];
+    char stringpool_str3942[sizeof("oyamazaki.kyoto.jp")];
+    char stringpool_str3943[sizeof("hanamigawa.chiba.jp")];
+    char stringpool_str3944[sizeof("logistics.aero")];
+    char stringpool_str3945[sizeof("shonai.fukuoka.jp")];
+    char stringpool_str3946[sizeof("newhampshire.museum")];
+    char stringpool_str3947[sizeof("kunstunddesign.museum")];
+    char stringpool_str3948[sizeof("archaeological.museum")];
+    char stringpool_str3949[sizeof("minato.tokyo.jp")];
+    char stringpool_str3950[sizeof("shop.ht")];
+    char stringpool_str3951[sizeof("kunitachi.tokyo.jp")];
+    char stringpool_str3952[sizeof("is-found.org")];
+    char stringpool_str3953[sizeof("dyndns.biz")];
+    char stringpool_str3954[sizeof("rawa-maz.pl")];
+    char stringpool_str3955[sizeof("undersea.museum")];
+    char stringpool_str3956[sizeof("sport.hu")];
+    char stringpool_str3957[sizeof("gouv.ht")];
+    char stringpool_str3958[sizeof("frogn.no")];
+    char stringpool_str3959[sizeof("udm.ru")];
+    char stringpool_str3960[sizeof("urawa.saitama.jp")];
+    char stringpool_str3961[sizeof("muika.niigata.jp")];
+    char stringpool_str3962[sizeof("author.aero")];
+    char stringpool_str3963[sizeof("hokksund.no")];
+    char stringpool_str3964[sizeof("mjondalen.no")];
+    char stringpool_str3965[sizeof("chikushino.fukuoka.jp")];
+    char stringpool_str3966[sizeof("higashitsuno.kochi.jp")];
+    char stringpool_str3967[sizeof("basilicata.it")];
+    char stringpool_str3968[sizeof("sc")];
+    char stringpool_str3969[sizeof("otoineppu.hokkaido.jp")];
+    char stringpool_str3970[sizeof("sca")];
+    char stringpool_str3971[sizeof("scb")];
+    char stringpool_str3972[sizeof("medecin.km")];
+    char stringpool_str3973[sizeof("makinohara.shizuoka.jp")];
+    char stringpool_str3974[sizeof("kasahara.gifu.jp")];
+    char stringpool_str3975[sizeof("omotego.fukushima.jp")];
+    char stringpool_str3976[sizeof("matsusaka.mie.jp")];
+    char stringpool_str3977[sizeof("floro.no")];
+    char stringpool_str3978[sizeof("fedje.no")];
+    char stringpool_str3979[sizeof("kawajima.saitama.jp")];
+    char stringpool_str3980[sizeof("is-very-good.org")];
+    char stringpool_str3981[sizeof("shiraoka.saitama.jp")];
+    char stringpool_str3982[sizeof("kitakata.fukushima.jp")];
+    char stringpool_str3983[sizeof("sande.more-og-romsdal.no")];
+    char stringpool_str3984[sizeof("skien.no")];
+    char stringpool_str3985[sizeof("sabae.fukui.jp")];
+    char stringpool_str3986[sizeof("lombardy.it")];
+    char stringpool_str3987[sizeof("flora.no")];
+    char stringpool_str3988[sizeof("is-a-celticsfan.org")];
+    char stringpool_str3989[sizeof("muenster.museum")];
+    char stringpool_str3990[sizeof("higashinaruse.akita.jp")];
+    char stringpool_str3991[sizeof("mizusawa.iwate.jp")];
+    char stringpool_str3992[sizeof("seika.kyoto.jp")];
+    char stringpool_str3993[sizeof("saiki.oita.jp")];
+    char stringpool_str3994[sizeof("maintenance.aero")];
+    char stringpool_str3995[sizeof("us-east-1.amazonaws.com")];
+    char stringpool_str3996[sizeof("davvenjarga.no")];
+    char stringpool_str3997[sizeof("webhop.biz")];
+    char stringpool_str3998[sizeof("cambridge.museum")];
+    char stringpool_str3999[sizeof("lillehammer.no")];
+    char stringpool_str4000[sizeof("hitachinaka.ibaraki.jp")];
+    char stringpool_str4001[sizeof("higashichichibu.saitama.jp")];
+    char stringpool_str4002[sizeof("axis.museum")];
+    char stringpool_str4003[sizeof("botanicalgarden.museum")];
+    char stringpool_str4004[sizeof("shichikashuku.miyagi.jp")];
+    char stringpool_str4005[sizeof("kasama.ibaraki.jp")];
+    char stringpool_str4006[sizeof("heimatunduhren.museum")];
+    char stringpool_str4007[sizeof("saito.miyazaki.jp")];
+    char stringpool_str4008[sizeof("blogsite.org")];
+    char stringpool_str4009[sizeof("soeda.fukuoka.jp")];
+    char stringpool_str4010[sizeof("fujimi.saitama.jp")];
+    char stringpool_str4011[sizeof("wanouchi.gifu.jp")];
+    char stringpool_str4012[sizeof("scot")];
+    char stringpool_str4013[sizeof("nishiaizu.fukushima.jp")];
+    char stringpool_str4014[sizeof("sveio.no")];
+    char stringpool_str4015[sizeof("kagamiishi.fukushima.jp")];
+    char stringpool_str4016[sizeof("shiga.jp")];
+    char stringpool_str4017[sizeof("echizen.fukui.jp")];
+    char stringpool_str4018[sizeof("massa-carrara.it")];
+    char stringpool_str4019[sizeof("myoko.niigata.jp")];
+    char stringpool_str4020[sizeof("miyako.iwate.jp")];
+    char stringpool_str4021[sizeof("lombardia.it")];
+    char stringpool_str4022[sizeof("yamatsuri.fukushima.jp")];
+    char stringpool_str4023[sizeof("merseine.nu")];
+    char stringpool_str4024[sizeof("is-very-sweet.org")];
+    char stringpool_str4025[sizeof("urayasu.chiba.jp")];
+    char stringpool_str4026[sizeof("leksvik.no")];
+    char stringpool_str4027[sizeof("dyndns.info")];
+    char stringpool_str4028[sizeof("fukui.jp")];
+    char stringpool_str4029[sizeof("mesaverde.museum")];
+    char stringpool_str4030[sizeof("kanuma.tochigi.jp")];
+    char stringpool_str4031[sizeof("hekinan.aichi.jp")];
+    char stringpool_str4032[sizeof("kawanishi.nara.jp")];
+    char stringpool_str4033[sizeof("kazimierz-dolny.pl")];
+    char stringpool_str4034[sizeof("odawara.kanagawa.jp")];
+    char stringpool_str4035[sizeof("egersund.no")];
+    char stringpool_str4036[sizeof("hakodate.hokkaido.jp")];
+    char stringpool_str4037[sizeof("mamurogawa.yamagata.jp")];
+    char stringpool_str4038[sizeof("afjord.no")];
+    char stringpool_str4039[sizeof("is-with-theband.com")];
+    char stringpool_str4040[sizeof("minamiboso.chiba.jp")];
+    char stringpool_str4041[sizeof("vegarshei.no")];
+    char stringpool_str4042[sizeof("kozaki.chiba.jp")];
+    char stringpool_str4043[sizeof("shiiba.miyazaki.jp")];
+    char stringpool_str4044[sizeof("magazine.aero")];
+    char stringpool_str4045[sizeof("net.co")];
+    char stringpool_str4046[sizeof("com.co")];
+    char stringpool_str4047[sizeof("gov.co")];
+    char stringpool_str4048[sizeof("nom.co")];
+    char stringpool_str4049[sizeof("sch.uk")];
+    char stringpool_str4050[sizeof("ltd.gi")];
+    char stringpool_str4051[sizeof("memorial.museum")];
+    char stringpool_str4052[sizeof("lajolla.museum")];
+    char stringpool_str4053[sizeof("hisayama.fukuoka.jp")];
+    char stringpool_str4054[sizeof("slupsk.pl")];
+    char stringpool_str4055[sizeof("edu.co")];
+    char stringpool_str4056[sizeof("jpn.com")];
+    char stringpool_str4057[sizeof("kozagawa.wakayama.jp")];
+    char stringpool_str4058[sizeof("kawanehon.shizuoka.jp")];
+    char stringpool_str4059[sizeof("national-library-scotland.uk")];
+    char stringpool_str4060[sizeof("sch.ae")];
+    char stringpool_str4061[sizeof("management")];
+    char stringpool_str4062[sizeof("leirvik.no")];
+    char stringpool_str4063[sizeof("sch.ir")];
+    char stringpool_str4064[sizeof("shop.hu")];
+    char stringpool_str4065[sizeof("ichikawa.hyogo.jp")];
+    char stringpool_str4066[sizeof("lerdal.no")];
+    char stringpool_str4067[sizeof("shikaoi.hokkaido.jp")];
+    char stringpool_str4068[sizeof("webhop.net")];
+    char stringpool_str4069[sizeof("usantiques.museum")];
+    char stringpool_str4070[sizeof("news.hu")];
+    char stringpool_str4071[sizeof("navigation.aero")];
+    char stringpool_str4072[sizeof("osteroy.no")];
+    char stringpool_str4073[sizeof("org.so")];
+    char stringpool_str4074[sizeof("org.do")];
+    char stringpool_str4075[sizeof("writesthisblog.com")];
+    char stringpool_str4076[sizeof("sch.id")];
+    char stringpool_str4077[sizeof("yahiko.niigata.jp")];
+    char stringpool_str4078[sizeof("lardal.no")];
+    char stringpool_str4079[sizeof("suita.osaka.jp")];
+    char stringpool_str4080[sizeof("lighting")];
+    char stringpool_str4081[sizeof("luxe")];
+    char stringpool_str4082[sizeof("sch.sa")];
+    char stringpool_str4083[sizeof("kagami.kochi.jp")];
+    char stringpool_str4084[sizeof("webhop.info")];
+    char stringpool_str4085[sizeof("org.to")];
+    char stringpool_str4086[sizeof("fukudomi.saga.jp")];
+    char stringpool_str4087[sizeof("sch.lk")];
+    char stringpool_str4088[sizeof("org.ro")];
+    char stringpool_str4089[sizeof("dazaifu.fukuoka.jp")];
+    char stringpool_str4090[sizeof("ube.yamaguchi.jp")];
+    char stringpool_str4091[sizeof("oxford.museum")];
+    char stringpool_str4092[sizeof("artanddesign.museum")];
+    char stringpool_str4093[sizeof("int.co")];
+    char stringpool_str4094[sizeof("moma.museum")];
+    char stringpool_str4095[sizeof("usculture.museum")];
+    char stringpool_str4096[sizeof("vibovalentia.it")];
+    char stringpool_str4097[sizeof("kimino.wakayama.jp")];
+    char stringpool_str4098[sizeof("vlaanderen")];
+    char stringpool_str4099[sizeof("org.jo")];
+    char stringpool_str4100[sizeof("komagane.nagano.jp")];
+    char stringpool_str4101[sizeof("lavagis.no")];
+    char stringpool_str4102[sizeof("wazuka.kyoto.jp")];
+    char stringpool_str4103[sizeof("org.mo")];
+    char stringpool_str4104[sizeof("medical.museum")];
+    char stringpool_str4105[sizeof("swiebodzin.pl")];
+    char stringpool_str4106[sizeof("motoyama.kochi.jp")];
+    char stringpool_str4107[sizeof("manx.museum")];
+    char stringpool_str4108[sizeof("gamvik.no")];
+    char stringpool_str4109[sizeof("bievat.no")];
+    char stringpool_str4110[sizeof("narvik.no")];
+    char stringpool_str4111[sizeof("futsu.nagasaki.jp")];
+    char stringpool_str4112[sizeof("lindas.no")];
+    char stringpool_str4113[sizeof("schule")];
+    char stringpool_str4114[sizeof("utah.museum")];
+    char stringpool_str4115[sizeof("org.bo")];
+    char stringpool_str4116[sizeof("omihachiman.shiga.jp")];
+    char stringpool_str4117[sizeof("chikuzen.fukuoka.jp")];
+    char stringpool_str4118[sizeof("manchester.museum")];
+    char stringpool_str4119[sizeof("sakae.nagano.jp")];
+    char stringpool_str4120[sizeof("nahari.kochi.jp")];
+    char stringpool_str4121[sizeof("ashikaga.tochigi.jp")];
+    char stringpool_str4122[sizeof("vestre-slidre.no")];
+    char stringpool_str4123[sizeof("lunner.no")];
+    char stringpool_str4124[sizeof("mil.ru")];
+    char stringpool_str4125[sizeof("store.nf")];
+    char stringpool_str4126[sizeof("komaki.aichi.jp")];
+    char stringpool_str4127[sizeof("loabat.no")];
+    char stringpool_str4128[sizeof("hitachiomiya.ibaraki.jp")];
+    char stringpool_str4129[sizeof("miura.kanagawa.jp")];
+    char stringpool_str4130[sizeof("olkusz.pl")];
+    char stringpool_str4131[sizeof("yukuhashi.fukuoka.jp")];
+    char stringpool_str4132[sizeof("kamimine.saga.jp")];
+    char stringpool_str4133[sizeof("sagae.yamagata.jp")];
+    char stringpool_str4134[sizeof("lodi.it")];
+    char stringpool_str4135[sizeof("shiraoi.hokkaido.jp")];
+    char stringpool_str4136[sizeof("hidaka.kochi.jp")];
+    char stringpool_str4137[sizeof("sch.qa")];
+    char stringpool_str4138[sizeof("yanagawa.fukuoka.jp")];
+    char stringpool_str4139[sizeof("kibichuo.okayama.jp")];
+    char stringpool_str4140[sizeof("sejny.pl")];
+    char stringpool_str4141[sizeof("fukuroi.shizuoka.jp")];
+    char stringpool_str4142[sizeof("shintoku.hokkaido.jp")];
+    char stringpool_str4143[sizeof("yawatahama.ehime.jp")];
+    char stringpool_str4144[sizeof("skjak.no")];
+    char stringpool_str4145[sizeof("santabarbara.museum")];
+    char stringpool_str4146[sizeof("embroidery.museum")];
+    char stringpool_str4147[sizeof("geisei.kochi.jp")];
+    char stringpool_str4148[sizeof("matsumae.hokkaido.jp")];
+    char stringpool_str4149[sizeof("mill.museum")];
+    char stringpool_str4150[sizeof("beardu.no")];
+    char stringpool_str4151[sizeof("kakamigahara.gifu.jp")];
+    char stringpool_str4152[sizeof("meiwa.gunma.jp")];
+    char stringpool_str4153[sizeof("lodingen.no")];
+    char stringpool_str4154[sizeof("nakagawa.fukuoka.jp")];
+    char stringpool_str4155[sizeof("sakai.osaka.jp")];
+    char stringpool_str4156[sizeof("agents.aero")];
+    char stringpool_str4157[sizeof("ishikawa.fukushima.jp")];
+    char stringpool_str4158[sizeof("microlight.aero")];
+    char stringpool_str4159[sizeof("nakatane.kagoshima.jp")];
+    char stringpool_str4160[sizeof("deatnu.no")];
+    char stringpool_str4161[sizeof("lebork.pl")];
+    char stringpool_str4162[sizeof("koriyama.fukushima.jp")];
+    char stringpool_str4163[sizeof("virginia.museum")];
+    char stringpool_str4164[sizeof("sells-for-less.com")];
+    char stringpool_str4165[sizeof("aizumi.tokushima.jp")];
+    char stringpool_str4166[sizeof("fuchu.toyama.jp")];
+    char stringpool_str4167[sizeof("gjovik.no")];
+    char stringpool_str4168[sizeof("limited")];
+    char stringpool_str4169[sizeof("yasuda.kochi.jp")];
+    char stringpool_str4170[sizeof("lib.sc.us")];
+    char stringpool_str4171[sizeof("lib.dc.us")];
+    char stringpool_str4172[sizeof("lib.ok.us")];
+    char stringpool_str4173[sizeof("lib.or.us")];
+    char stringpool_str4174[sizeof("nakatsugawa.gifu.jp")];
+    char stringpool_str4175[sizeof("lib.pr.us")];
+    char stringpool_str4176[sizeof("luster.no")];
+    char stringpool_str4177[sizeof("univ.sn")];
+    char stringpool_str4178[sizeof("shiki.saitama.jp")];
+    char stringpool_str4179[sizeof("kudamatsu.yamaguchi.jp")];
+    char stringpool_str4180[sizeof("sanda.hyogo.jp")];
+    char stringpool_str4181[sizeof("iizuna.nagano.jp")];
+    char stringpool_str4182[sizeof("ota.tokyo.jp")];
+    char stringpool_str4183[sizeof("vrn.ru")];
+    char stringpool_str4184[sizeof("uvic.museum")];
+    char stringpool_str4185[sizeof("ujiie.tochigi.jp")];
+    char stringpool_str4186[sizeof("medecin.fr")];
+    char stringpool_str4187[sizeof("lib.al.us")];
+    char stringpool_str4188[sizeof("lib.ak.us")];
+    char stringpool_str4189[sizeof("lib.ar.us")];
+    char stringpool_str4190[sizeof("lib.sd.us")];
+    char stringpool_str4191[sizeof("ryukyu")];
+    char stringpool_str4192[sizeof("engine.aero")];
+    char stringpool_str4193[sizeof("lib.as.us")];
+    char stringpool_str4194[sizeof("lib.tn.us")];
+    char stringpool_str4195[sizeof("nakamichi.yamanashi.jp")];
+    char stringpool_str4196[sizeof("online.museum")];
+    char stringpool_str4197[sizeof("sumoto.kumamoto.jp")];
+    char stringpool_str4198[sizeof("lib.ut.us")];
+    char stringpool_str4199[sizeof("ome.tokyo.jp")];
+    char stringpool_str4200[sizeof("lib.de.us")];
+    char stringpool_str4201[sizeof("versailles.museum")];
+    char stringpool_str4202[sizeof("k12.ct.us")];
+    char stringpool_str4203[sizeof("sakai.fukui.jp")];
+    char stringpool_str4204[sizeof("kitagata.gifu.jp")];
+    char stringpool_str4205[sizeof("morioka.iwate.jp")];
+    char stringpool_str4206[sizeof("lib.mt.us")];
+    char stringpool_str4207[sizeof("andebu.no")];
+    char stringpool_str4208[sizeof("michigan.museum")];
+    char stringpool_str4209[sizeof("k12.tx.us")];
+    char stringpool_str4210[sizeof("lib.mn.us")];
+    char stringpool_str4211[sizeof("shintomi.miyazaki.jp")];
+    char stringpool_str4212[sizeof("lib.ms.us")];
+    char stringpool_str4213[sizeof("sch.ng")];
+    char stringpool_str4214[sizeof("lib.il.us")];
+    char stringpool_str4215[sizeof("shari.hokkaido.jp")];
+    char stringpool_str4216[sizeof("miyoshi.aichi.jp")];
+    char stringpool_str4217[sizeof("jewishart.museum")];
+    char stringpool_str4218[sizeof("lib.in.us")];
+    char stringpool_str4219[sizeof("lib.md.us")];
+    char stringpool_str4220[sizeof("iwaizumi.iwate.jp")];
+    char stringpool_str4221[sizeof("sci.eg")];
+    char stringpool_str4222[sizeof("lib.me.us")];
+    char stringpool_str4223[sizeof("lib.id.us")];
+    char stringpool_str4224[sizeof("lib.nc.us")];
+    char stringpool_str4225[sizeof("higashikurume.tokyo.jp")];
+    char stringpool_str4226[sizeof("kawakami.nagano.jp")];
+    char stringpool_str4227[sizeof("fujimi.nagano.jp")];
+    char stringpool_str4228[sizeof("zentsuji.kagawa.jp")];
+    char stringpool_str4229[sizeof("uto.kumamoto.jp")];
+    char stringpool_str4230[sizeof("lib.pa.us")];
+    char stringpool_str4231[sizeof("lib.nd.us")];
+    char stringpool_str4232[sizeof("stuff-4-sale.us")];
+    char stringpool_str4233[sizeof("samnanger.no")];
+    char stringpool_str4234[sizeof("lib.vt.us")];
+    char stringpool_str4235[sizeof("yatomi.aichi.jp")];
+    char stringpool_str4236[sizeof("lib.ne.us")];
+    char stringpool_str4237[sizeof("lib.nj.us")];
+    char stringpool_str4238[sizeof("space-to-rent.com")];
+    char stringpool_str4239[sizeof("ichikawamisato.yamanashi.jp")];
+    char stringpool_str4240[sizeof("aeroport.fr")];
+    char stringpool_str4241[sizeof("military.museum")];
+    char stringpool_str4242[sizeof("oita.oita.jp")];
+    char stringpool_str4243[sizeof("london.museum")];
+    char stringpool_str4244[sizeof("vlaanderen.museum")];
+    char stringpool_str4245[sizeof("k12.ca.us")];
+    char stringpool_str4246[sizeof("sanfrancisco.museum")];
+    char stringpool_str4247[sizeof("msk.ru")];
+    char stringpool_str4248[sizeof("saijo.ehime.jp")];
+    char stringpool_str4249[sizeof("vic.au")];
+    char stringpool_str4250[sizeof("web.co")];
+    char stringpool_str4251[sizeof("lib.ma.us")];
+    char stringpool_str4252[sizeof("lierne.no")];
+    char stringpool_str4253[sizeof("folkebibl.no")];
+    char stringpool_str4254[sizeof("landes.museum")];
+    char stringpool_str4255[sizeof("kokubunji.tokyo.jp")];
+    char stringpool_str4256[sizeof("suzuki")];
+    char stringpool_str4257[sizeof("fuchu.hiroshima.jp")];
+    char stringpool_str4258[sizeof("lib.ia.us")];
+    char stringpool_str4259[sizeof("songdalen.no")];
+    char stringpool_str4260[sizeof("lib.nm.us")];
+    char stringpool_str4261[sizeof("miyako.fukuoka.jp")];
+    char stringpool_str4262[sizeof("rhcloud.com")];
+    char stringpool_str4263[sizeof("scientist.aero")];
+    char stringpool_str4264[sizeof("sandiego.museum")];
+    char stringpool_str4265[sizeof("fudai.iwate.jp")];
+    char stringpool_str4266[sizeof("lib.ks.us")];
+    char stringpool_str4267[sizeof("seihi.nagasaki.jp")];
+    char stringpool_str4268[sizeof("from-nc.com")];
+    char stringpool_str4269[sizeof("from-sc.com")];
+    char stringpool_str4270[sizeof("labour.museum")];
+    char stringpool_str4271[sizeof("medio-campidano.it")];
+    char stringpool_str4272[sizeof("langevag.no")];
+    char stringpool_str4273[sizeof("fukui.fukui.jp")];
+    char stringpool_str4274[sizeof("from-dc.com")];
+    char stringpool_str4275[sizeof("hasvik.no")];
+    char stringpool_str4276[sizeof("lib.la.us")];
+    char stringpool_str4277[sizeof("lib.va.us")];
+    char stringpool_str4278[sizeof("sosa.chiba.jp")];
+    char stringpool_str4279[sizeof("maritimo.museum")];
+    char stringpool_str4280[sizeof("leangaviika.no")];
+    char stringpool_str4281[sizeof("settlers.museum")];
+    char stringpool_str4282[sizeof("ks.us")];
+    char stringpool_str4283[sizeof("ne.us")];
+    char stringpool_str4284[sizeof("bd.se")];
+    char stringpool_str4285[sizeof("co.me")];
+    char stringpool_str4286[sizeof("id.us")];
+    char stringpool_str4287[sizeof("nd.us")];
+    char stringpool_str4288[sizeof("co.ls")];
+    char stringpool_str4289[sizeof("co.us")];
+    char stringpool_str4290[sizeof("knowsitall.info")];
+    char stringpool_str4291[sizeof("uchihara.ibaraki.jp")];
+    char stringpool_str4292[sizeof("kawatana.nagasaki.jp")];
+    char stringpool_str4293[sizeof("co.ae")];
+    char stringpool_str4294[sizeof("co.ao")];
+    char stringpool_str4295[sizeof("k12.fl.us")];
+    char stringpool_str4296[sizeof("stathelle.no")];
+    char stringpool_str4297[sizeof("ed.ao")];
+    char stringpool_str4298[sizeof("lyngen.no")];
+    char stringpool_str4299[sizeof("eastcoast.museum")];
+    char stringpool_str4300[sizeof("misato.miyagi.jp")];
+    char stringpool_str4301[sizeof("schlesisches.museum")];
+    char stringpool_str4302[sizeof("skiptvet.no")];
+    char stringpool_str4303[sizeof("livinghistory.museum")];
+    char stringpool_str4304[sizeof("ca.us")];
+    char stringpool_str4305[sizeof("ks.ua")];
+    char stringpool_str4306[sizeof("ga.us")];
+    char stringpool_str4307[sizeof("ia.us")];
+    char stringpool_str4308[sizeof("co.ma")];
+    char stringpool_str4309[sizeof("co.ua")];
+    char stringpool_str4310[sizeof("ct.us")];
+    char stringpool_str4311[sizeof("co.st")];
+    char stringpool_str4312[sizeof("sakado.saitama.jp")];
+    char stringpool_str4313[sizeof("co.at")];
+    char stringpool_str4314[sizeof("it.ao")];
+    char stringpool_str4315[sizeof("higashine.yamagata.jp")];
+    char stringpool_str4316[sizeof("inawashiro.fukushima.jp")];
+    char stringpool_str4317[sizeof("fussa.tokyo.jp")];
+    char stringpool_str4318[sizeof("sumoto.hyogo.jp")];
+    char stringpool_str4319[sizeof("co.tt")];
+    char stringpool_str4320[sizeof("ichiba.tokushima.jp")];
+    char stringpool_str4321[sizeof("gu.us")];
+    char stringpool_str4322[sizeof("feedback")];
+    char stringpool_str4323[sizeof("co.mu")];
+    char stringpool_str4324[sizeof("as.us")];
+    char stringpool_str4325[sizeof("zp.ua")];
+    char stringpool_str4326[sizeof("co.uz")];
+    char stringpool_str4327[sizeof("co.sz")];
+    char stringpool_str4328[sizeof("storfjord.no")];
+    char stringpool_str4329[sizeof("id.au")];
+    char stringpool_str4330[sizeof("localhistory.museum")];
+    char stringpool_str4331[sizeof("gs.oslo.no")];
+    char stringpool_str4332[sizeof("obanazawa.yamagata.jp")];
+    char stringpool_str4333[sizeof("sanjo.niigata.jp")];
+    char stringpool_str4334[sizeof("nj.us")];
+    char stringpool_str4335[sizeof("ne.tz")];
+    char stringpool_str4336[sizeof("co.tz")];
+    char stringpool_str4337[sizeof("go.tz")];
+    char stringpool_str4338[sizeof("cr.ua")];
+    char stringpool_str4339[sizeof("kr.ua")];
+    char stringpool_str4340[sizeof("schoenbrunn.museum")];
+    char stringpool_str4341[sizeof("nm.us")];
+    char stringpool_str4342[sizeof("ns.ca")];
+    char stringpool_str4343[sizeof("co.ca")];
+    char stringpool_str4344[sizeof("flatanger.no")];
+    char stringpool_str4345[sizeof("software.aero")];
+    char stringpool_str4346[sizeof("co.tj")];
+    char stringpool_str4347[sizeof("go.tj")];
+    char stringpool_str4348[sizeof("co.om")];
+    char stringpool_str4349[sizeof("settlement.museum")];
+    char stringpool_str4350[sizeof("zt.ua")];
+    char stringpool_str4351[sizeof("co.cr")];
+    char stringpool_str4352[sizeof("go.cr")];
+    char stringpool_str4353[sizeof("co.tm")];
+    char stringpool_str4354[sizeof("frosinone.it")];
+    char stringpool_str4355[sizeof("ed.cr")];
+    char stringpool_str4356[sizeof("nagasu.kumamoto.jp")];
+    char stringpool_str4357[sizeof("nt.au")];
+    char stringpool_str4358[sizeof("ar.us")];
+    char stringpool_str4359[sizeof("ne.kr")];
+    char stringpool_str4360[sizeof("co.kr")];
+    char stringpool_str4361[sizeof("go.kr")];
+    char stringpool_str4362[sizeof("km.ua")];
+    char stringpool_str4363[sizeof("yamagata.gifu.jp")];
+    char stringpool_str4364[sizeof("es.kr")];
+    char stringpool_str4365[sizeof("nt.ca")];
+    char stringpool_str4366[sizeof("az.us")];
+    char stringpool_str4367[sizeof("kawasaki.miyagi.jp")];
+    char stringpool_str4368[sizeof("susono.shizuoka.jp")];
+    char stringpool_str4369[sizeof("de.us")];
+    char stringpool_str4370[sizeof("kuwana.mie.jp")];
+    char stringpool_str4371[sizeof("oshima.tokyo.jp")];
+    char stringpool_str4372[sizeof("minokamo.gifu.jp")];
+    char stringpool_str4373[sizeof("seiro.niigata.jp")];
+    char stringpool_str4374[sizeof("co.no")];
+    char stringpool_str4375[sizeof("rec.co")];
+    char stringpool_str4376[sizeof("nu.ca")];
+    char stringpool_str4377[sizeof("opole.pl")];
+    char stringpool_str4378[sizeof("in.us")];
+    char stringpool_str4379[sizeof("lib.wa.us")];
+    char stringpool_str4380[sizeof("jp.net")];
+    char stringpool_str4381[sizeof("kariya.aichi.jp")];
+    char stringpool_str4382[sizeof("sosnowiec.pl")];
+    char stringpool_str4383[sizeof("co.ci")];
+    char stringpool_str4384[sizeof("go.ci")];
+    char stringpool_str4385[sizeof("onna.okinawa.jp")];
+    char stringpool_str4386[sizeof("fundacio.museum")];
+    char stringpool_str4387[sizeof("otsuki.yamanashi.jp")];
+    char stringpool_str4388[sizeof("ed.ci")];
+    char stringpool_str4389[sizeof("stalbans.museum")];
+    char stringpool_str4390[sizeof("co.na")];
+    char stringpool_str4391[sizeof("dp.ua")];
+    char stringpool_str4392[sizeof("ogawara.miyagi.jp")];
+    char stringpool_str4393[sizeof("nt.no")];
+    char stringpool_str4394[sizeof("cn.ua")];
+    char stringpool_str4395[sizeof("in.ua")];
+    char stringpool_str4396[sizeof("il.us")];
+    char stringpool_str4397[sizeof("miyawaka.fukuoka.jp")];
+    char stringpool_str4398[sizeof("co.com")];
+    char stringpool_str4399[sizeof("no.com")];
+    char stringpool_str4400[sizeof("za.net")];
+    char stringpool_str4401[sizeof("omachi.nagano.jp")];
+    char stringpool_str4402[sizeof("nv.us")];
+    char stringpool_str4403[sizeof("bu.no")];
+    char stringpool_str4404[sizeof("id.lv")];
+    char stringpool_str4405[sizeof("gs.cn")];
+    char stringpool_str4406[sizeof("fuettertdasnetz.de")];
+    char stringpool_str4407[sizeof("gd.cn")];
+    char stringpool_str4408[sizeof("ca.na")];
+    char stringpool_str4409[sizeof("global.ssl.fastly.net")];
+    char stringpool_str4410[sizeof("gv.ao")];
+    char stringpool_str4411[sizeof("co.ba")];
+    char stringpool_str4412[sizeof("nb.ca")];
+    char stringpool_str4413[sizeof("furano.hokkaido.jp")];
+    char stringpool_str4414[sizeof("lib.ri.us")];
+    char stringpool_str4415[sizeof("js.cn")];
+    char stringpool_str4416[sizeof("marylhurst.museum")];
+    char stringpool_str4417[sizeof("mutsuzawa.chiba.jp")];
+    char stringpool_str4418[sizeof("numazu.shizuoka.jp")];
+    char stringpool_str4419[sizeof("barrel-of-knowledge.info")];
+    char stringpool_str4420[sizeof("mitoyo.kagawa.jp")];
+    char stringpool_str4421[sizeof("cv.ua")];
+    char stringpool_str4422[sizeof("kv.ua")];
+    char stringpool_str4423[sizeof("shinjo.nara.jp")];
+    char stringpool_str4424[sizeof("br.com")];
+    char stringpool_str4425[sizeof("kr.com")];
+    char stringpool_str4426[sizeof("gr.com")];
+    char stringpool_str4427[sizeof("iizuka.fukuoka.jp")];
+    char stringpool_str4428[sizeof("aa.no")];
+    char stringpool_str4429[sizeof("ruovat.no")];
+    char stringpool_str4430[sizeof("shiso.hyogo.jp")];
+    char stringpool_str4431[sizeof("co.cl")];
+    char stringpool_str4432[sizeof("computer.museum")];
+    char stringpool_str4433[sizeof("gv.at")];
+    char stringpool_str4434[sizeof("lib.mi.us")];
+    char stringpool_str4435[sizeof("za.com")];
+    char stringpool_str4436[sizeof("lib.az.us")];
+    char stringpool_str4437[sizeof("al.us")];
+    char stringpool_str4438[sizeof("eu.com")];
+    char stringpool_str4439[sizeof("gb.net")];
+    char stringpool_str4440[sizeof("minamiechizen.fukui.jp")];
+    char stringpool_str4441[sizeof("gz.cn")];
+    char stringpool_str4442[sizeof("xn--p1ai")];
+    char stringpool_str4443[sizeof("ab.ca")];
+    char stringpool_str4444[sizeof("nl.ca")];
+    char stringpool_str4445[sizeof("bj.cn")];
+    char stringpool_str4446[sizeof("osaka.jp")];
+    char stringpool_str4447[sizeof("co.rs")];
+    char stringpool_str4448[sizeof("uki.kumamoto.jp")];
+    char stringpool_str4449[sizeof("nm.cn")];
+    char stringpool_str4450[sizeof("co.bi")];
+    char stringpool_str4451[sizeof("xz.cn")];
+    char stringpool_str4452[sizeof("in.net")];
+    char stringpool_str4453[sizeof("munakata.fukuoka.jp")];
+    char stringpool_str4454[sizeof("za.bz")];
+    char stringpool_str4455[sizeof("omachi.saga.jp")];
+    char stringpool_str4456[sizeof("mashiko.tochigi.jp")];
+    char stringpool_str4457[sizeof("kamakura.kanagawa.jp")];
+    char stringpool_str4458[sizeof("honefoss.no")];
+    char stringpool_str4459[sizeof("xj.cn")];
+    char stringpool_str4460[sizeof("zj.cn")];
+    char stringpool_str4461[sizeof("ar.com")];
+    char stringpool_str4462[sizeof("fujinomiya.shizuoka.jp")];
+    char stringpool_str4463[sizeof("misato.wakayama.jp")];
+    char stringpool_str4464[sizeof("university")];
+    char stringpool_str4465[sizeof("ookuwa.nagano.jp")];
+    char stringpool_str4466[sizeof("nh.us")];
+    char stringpool_str4467[sizeof("gb.com")];
+    char stringpool_str4468[sizeof("higashishirakawa.gifu.jp")];
+    char stringpool_str4469[sizeof("dn.ua")];
+    char stringpool_str4470[sizeof("in.na")];
+    char stringpool_str4471[sizeof("de.com")];
+    char stringpool_str4472[sizeof("nt.ro")];
+    char stringpool_str4473[sizeof("co.th")];
+    char stringpool_str4474[sizeof("go.th")];
+    char stringpool_str4475[sizeof("co.nl")];
+    char stringpool_str4476[sizeof("nl.no")];
+    char stringpool_str4477[sizeof("ck.ua")];
+    char stringpool_str4478[sizeof("yuzawa.niigata.jp")];
+    char stringpool_str4479[sizeof("cn.com")];
+    char stringpool_str4480[sizeof("kh.ua")];
+    char stringpool_str4481[sizeof("kawaminami.miyazaki.jp")];
+    char stringpool_str4482[sizeof("ebetsu.hokkaido.jp")];
+    char stringpool_str4483[sizeof("dr.na")];
+    char stringpool_str4484[sizeof("yonaguni.okinawa.jp")];
+    char stringpool_str4485[sizeof("fuchu.tokyo.jp")];
+    char stringpool_str4486[sizeof("science.museum")];
+    char stringpool_str4487[sizeof("lib.vi.us")];
+    char stringpool_str4488[sizeof("ak.us")];
+    char stringpool_str4489[sizeof("am.br")];
+    char stringpool_str4490[sizeof("flanders.museum")];
+    char stringpool_str4491[sizeof("cq.cn")];
+    char stringpool_str4492[sizeof("bozen.it")];
+    char stringpool_str4493[sizeof("forlicesena.it")];
+    char stringpool_str4494[sizeof("kazan.ru")];
+    char stringpool_str4495[sizeof("fylkesbibl.no")];
+    char stringpool_str4496[sizeof("xn--l1acc")];
+    char stringpool_str4497[sizeof("xn--nnx388a")];
+    char stringpool_str4498[sizeof("co.mw")];
+    char stringpool_str4499[sizeof("hi.us")];
+    char stringpool_str4500[sizeof("hs.kr")];
+    char stringpool_str4501[sizeof("figueres.museum")];
+    char stringpool_str4502[sizeof("spb.ru")];
+    char stringpool_str4503[sizeof("al.no")];
+    char stringpool_str4504[sizeof("vanylven.no")];
+    char stringpool_str4505[sizeof("sugito.saitama.jp")];
+    char stringpool_str4506[sizeof("lib.oh.us")];
+    char stringpool_str4507[sizeof("jl.cn")];
+    char stringpool_str4508[sizeof("stv.ru")];
+    char stringpool_str4509[sizeof("yawata.kyoto.jp")];
+    char stringpool_str4510[sizeof("oryol.ru")];
+    char stringpool_str4511[sizeof("in.rs")];
+    char stringpool_str4512[sizeof("co.hu")];
+    char stringpool_str4513[sizeof("kawaba.gunma.jp")];
+    char stringpool_str4514[sizeof("shitara.aichi.jp")];
+    char stringpool_str4515[sizeof("ha.no")];
+    char stringpool_str4516[sizeof("ino.kochi.jp")];
+    char stringpool_str4517[sizeof("morimachi.shizuoka.jp")];
+    char stringpool_str4518[sizeof("ohkura.yamagata.jp")];
+    char stringpool_str4519[sizeof("lib.hi.us")];
+    char stringpool_str4520[sizeof("hu.net")];
+    char stringpool_str4521[sizeof("orsta.no")];
+    char stringpool_str4522[sizeof("in.th")];
+    char stringpool_str4523[sizeof("shika.ishikawa.jp")];
+    char stringpool_str4524[sizeof("kawakita.ishikawa.jp")];
+    char stringpool_str4525[sizeof("he.cn")];
+    char stringpool_str4526[sizeof("finearts.museum")];
+    char stringpool_str4527[sizeof("td")];
+    char stringpool_str4528[sizeof("to")];
+    char stringpool_str4529[sizeof("group.aero")];
+    char stringpool_str4530[sizeof("tp")];
+    char stringpool_str4531[sizeof("bl.uk")];
+    char stringpool_str4532[sizeof("toys")];
+    char stringpool_str4533[sizeof("sexy")];
+    char stringpool_str4534[sizeof("iz.hr")];
+    char stringpool_str4535[sizeof("horology.museum")];
+    char stringpool_str4536[sizeof("satx.museum")];
+    char stringpool_str4537[sizeof("hm.no")];
+    char stringpool_str4538[sizeof("za.org")];
+    char stringpool_str4539[sizeof("medizinhistorisches.museum")];
+    char stringpool_str4540[sizeof("ae.org")];
+    char stringpool_str4541[sizeof("ah.no")];
+    char stringpool_str4542[sizeof("ha.cn")];
+    char stringpool_str4543[sizeof("design.aero")];
+    char stringpool_str4544[sizeof("shinto.gunma.jp")];
+    char stringpool_str4545[sizeof("bv.nl")];
+    char stringpool_str4546[sizeof("tt")];
+    char stringpool_str4547[sizeof("xn--j1amh")];
+    char stringpool_str4548[sizeof("hu.com")];
+    char stringpool_str4549[sizeof("tr")];
+    char stringpool_str4550[sizeof("koryo.nara.jp")];
+    char stringpool_str4551[sizeof("cargo.aero")];
+    char stringpool_str4552[sizeof("latina.it")];
+    char stringpool_str4553[sizeof("graphics")];
+    char stringpool_str4554[sizeof("trade")];
+    char stringpool_str4555[sizeof("lib.wi.us")];
+    char stringpool_str4556[sizeof("tz")];
+    char stringpool_str4557[sizeof("tel")];
+    char stringpool_str4558[sizeof("lib.nh.us")];
+    char stringpool_str4559[sizeof("co.bw")];
+    char stringpool_str4560[sizeof("tj")];
+    char stringpool_str4561[sizeof("stavern.no")];
+    char stringpool_str4562[sizeof("ky.us")];
+    char stringpool_str4563[sizeof("ny.us")];
+    char stringpool_str4564[sizeof("id.ly")];
+    char stringpool_str4565[sizeof("otago.museum")];
+    char stringpool_str4566[sizeof("co.je")];
+    char stringpool_str4567[sizeof("tm")];
+    char stringpool_str4568[sizeof("stpetersburg.museum")];
+    char stringpool_str4569[sizeof("ne.jp")];
+    char stringpool_str4570[sizeof("ah.cn")];
+    char stringpool_str4571[sizeof("co.jp")];
+    char stringpool_str4572[sizeof("go.jp")];
+    char stringpool_str4573[sizeof("steinkjer.no")];
+    char stringpool_str4574[sizeof("ed.jp")];
+    char stringpool_str4575[sizeof("tur.ar")];
+    char stringpool_str4576[sizeof("hi.cn")];
+    char stringpool_str4577[sizeof("xn--rdal-poa.no")];
+    char stringpool_str4578[sizeof("hb.cn")];
+    char stringpool_str4579[sizeof("slattum.no")];
+    char stringpool_str4580[sizeof("joetsu.niigata.jp")];
+    char stringpool_str4581[sizeof("compute.amazonaws.com")];
+    char stringpool_str4582[sizeof("tips")];
+    char stringpool_str4583[sizeof("hl.no")];
+    char stringpool_str4584[sizeof("tana.no")];
+    char stringpool_str4585[sizeof("xn--kpry57d")];
+    char stringpool_str4586[sizeof("gr.jp")];
+    char stringpool_str4587[sizeof("federation.aero")];
+    char stringpool_str4588[sizeof("xn--slat-5na.no")];
+    char stringpool_str4589[sizeof("xn--d1acj3b")];
+    char stringpool_str4590[sizeof("servebbs.net")];
+    char stringpool_str4591[sizeof("odate.akita.jp")];
+    char stringpool_str4592[sizeof("tools")];
+    char stringpool_str4593[sizeof("kumakogen.ehime.jp")];
+    char stringpool_str4594[sizeof("hn.cn")];
+    char stringpool_str4595[sizeof("tn")];
+    char stringpool_str4596[sizeof("xn--zfr164b")];
+    char stringpool_str4597[sizeof("ad.jp")];
+    char stringpool_str4598[sizeof("taa.it")];
+    char stringpool_str4599[sizeof("shikatsu.aichi.jp")];
+    char stringpool_str4600[sizeof("compute-1.amazonaws.com")];
+    char stringpool_str4601[sizeof("funabashi.chiba.jp")];
+    char stringpool_str4602[sizeof("lib.ga.us")];
+    char stringpool_str4603[sizeof("xn--mgb2ddes")];
+    char stringpool_str4604[sizeof("wa.us")];
+    char stringpool_str4605[sizeof("co.rw")];
+    char stringpool_str4606[sizeof("hl.cn")];
+    char stringpool_str4607[sizeof("mihara.kochi.jp")];
+    char stringpool_str4608[sizeof("tl")];
+    char stringpool_str4609[sizeof("tur.br")];
+    char stringpool_str4610[sizeof("assabu.hokkaido.jp")];
+    char stringpool_str4611[sizeof("stuff-4-sale.org")];
+    char stringpool_str4612[sizeof("brand.se")];
+    char stringpool_str4613[sizeof("tv")];
+    char stringpool_str4614[sizeof("xn--skjk-soa.no")];
+    char stringpool_str4615[sizeof("silk.museum")];
+    char stringpool_str4616[sizeof("showa.gunma.jp")];
+    char stringpool_str4617[sizeof("tmp.br")];
+    char stringpool_str4618[sizeof("mihama.aichi.jp")];
+    char stringpool_str4619[sizeof("trd.br")];
+    char stringpool_str4620[sizeof("t.bg")];
+    char stringpool_str4621[sizeof("venice.it")];
+    char stringpool_str4622[sizeof("time.no")];
+    char stringpool_str4623[sizeof("wa.au")];
+    char stringpool_str4624[sizeof("xn--4gbrim")];
+    char stringpool_str4625[sizeof("xn--rland-uua.no")];
+    char stringpool_str4626[sizeof("wi.us")];
+    char stringpool_str4627[sizeof("lom.no")];
+    char stringpool_str4628[sizeof("kawanishi.hyogo.jp")];
+    char stringpool_str4629[sizeof("teo.br")];
+    char stringpool_str4630[sizeof("farm.museum")];
+    char stringpool_str4631[sizeof("starachowice.pl")];
+    char stringpool_str4632[sizeof("sciencesnaturelles.museum")];
+    char stringpool_str4633[sizeof("kawanishi.yamagata.jp")];
+    char stringpool_str4634[sizeof("university.museum")];
+    char stringpool_str4635[sizeof("co.gy")];
+    char stringpool_str4636[sizeof("gamagori.aichi.jp")];
+    char stringpool_str4637[sizeof("kamisunagawa.hokkaido.jp")];
+    char stringpool_str4638[sizeof("xn--mely-ira.no")];
+    char stringpool_str4639[sizeof("xn--snes-poa.no")];
+    char stringpool_str4640[sizeof("hk.cn")];
+    char stringpool_str4641[sizeof("tk")];
+    char stringpool_str4642[sizeof("xn--55qx5d")];
+    char stringpool_str4643[sizeof("th")];
+    char stringpool_str4644[sizeof("xn--snsa-roa.no")];
+    char stringpool_str4645[sizeof("services")];
+    char stringpool_str4646[sizeof("ws.na")];
+    char stringpool_str4647[sizeof("xn--mli-tla.no")];
+    char stringpool_str4648[sizeof("co.id")];
+    char stringpool_str4649[sizeof("go.id")];
+    char stringpool_str4650[sizeof("hawaii.museum")];
+    char stringpool_str4651[sizeof("tenkawa.nara.jp")];
+    char stringpool_str4652[sizeof("inabe.mie.jp")];
+    char stringpool_str4653[sizeof("tinn.no")];
+    char stringpool_str4654[sizeof("shinjo.okayama.jp")];
+    char stringpool_str4655[sizeof("omaha.museum")];
+    char stringpool_str4656[sizeof("t.se")];
+    char stringpool_str4657[sizeof("wv.us")];
+    char stringpool_str4658[sizeof("kiryu.gunma.jp")];
+    char stringpool_str4659[sizeof("xn--ngbc5azd")];
+    char stringpool_str4660[sizeof("xn--asky-ira.no")];
+    char stringpool_str4661[sizeof("ce.it")];
+    char stringpool_str4662[sizeof("ge.it")];
+    char stringpool_str4663[sizeof("cs.it")];
+    char stringpool_str4664[sizeof("bs.it")];
+    char stringpool_str4665[sizeof("is.it")];
+    char stringpool_str4666[sizeof("tra.kp")];
+    char stringpool_str4667[sizeof("co.it")];
+    char stringpool_str4668[sizeof("bo.it")];
+    char stringpool_str4669[sizeof("go.it")];
+    char stringpool_str4670[sizeof("no.it")];
+    char stringpool_str4671[sizeof("id.ir")];
+    char stringpool_str4672[sizeof("co.ir")];
+    char stringpool_str4673[sizeof("taranto.it")];
+    char stringpool_str4674[sizeof("laquila.it")];
+    char stringpool_str4675[sizeof("xn--srfold-bya.no")];
+    char stringpool_str4676[sizeof("ri.us")];
+    char stringpool_str4677[sizeof("re.kr")];
+    char stringpool_str4678[sizeof("tw")];
+    char stringpool_str4679[sizeof("school.na")];
+    char stringpool_str4680[sizeof("bando.ibaraki.jp")];
+    char stringpool_str4681[sizeof("ca.it")];
+    char stringpool_str4682[sizeof("ba.it")];
+    char stringpool_str4683[sizeof("na.it")];
+    char stringpool_str4684[sizeof("yn.cn")];
+    char stringpool_str4685[sizeof("ct.it")];
+    char stringpool_str4686[sizeof("bt.it")];
+    char stringpool_str4687[sizeof("tos.it")];
+    char stringpool_str4688[sizeof("odesa.ua")];
+    char stringpool_str4689[sizeof("co.im")];
+    char stringpool_str4690[sizeof("test.tj")];
+    char stringpool_str4691[sizeof("cr.it")];
+    char stringpool_str4692[sizeof("br.it")];
+    char stringpool_str4693[sizeof("kr.it")];
+    char stringpool_str4694[sizeof("gr.it")];
+    char stringpool_str4695[sizeof("nakagusuku.okinawa.jp")];
+    char stringpool_str4696[sizeof("ne.ug")];
+    char stringpool_str4697[sizeof("film.museum")];
+    char stringpool_str4698[sizeof("co.ug")];
+    char stringpool_str4699[sizeof("go.ug")];
+    char stringpool_str4700[sizeof("services.aero")];
+    char stringpool_str4701[sizeof("co.ag")];
+    char stringpool_str4702[sizeof("nu.it")];
+    char stringpool_str4703[sizeof("cz.it")];
+    char stringpool_str4704[sizeof("bz.it")];
+    char stringpool_str4705[sizeof("selfip.biz")];
+    char stringpool_str4706[sizeof("ao.it")];
+    char stringpool_str4707[sizeof("tienda")];
+    char stringpool_str4708[sizeof("ap.it")];
+    char stringpool_str4709[sizeof("yk.ca")];
+    char stringpool_str4710[sizeof("xn--uc0ay4a.hk")];
+    char stringpool_str4711[sizeof("aki.kochi.jp")];
+    char stringpool_str4712[sizeof("im.it")];
+    char stringpool_str4713[sizeof("act.gov.au")];
+    char stringpool_str4714[sizeof("s3-ap-southeast-2.amazonaws.com")];
+    char stringpool_str4715[sizeof("trading.aero")];
+    char stringpool_str4716[sizeof("ballooning.aero")];
+    char stringpool_str4717[sizeof("mil.co")];
+    char stringpool_str4718[sizeof("suzu.ishikawa.jp")];
+    char stringpool_str4719[sizeof("at.it")];
+    char stringpool_str4720[sizeof("otaki.saitama.jp")];
+    char stringpool_str4721[sizeof("oskol.ru")];
+    char stringpool_str4722[sizeof("gov.cx")];
+    char stringpool_str4723[sizeof("itako.ibaraki.jp")];
+    char stringpool_str4724[sizeof("ro.com")];
+    char stringpool_str4725[sizeof("ci.it")];
+    char stringpool_str4726[sizeof("bi.it")];
+    char stringpool_str4727[sizeof("ar.it")];
+    char stringpool_str4728[sizeof("obuse.nagano.jp")];
+    char stringpool_str4729[sizeof("co.in")];
+    char stringpool_str4730[sizeof("shingo.aomori.jp")];
+    char stringpool_str4731[sizeof("vibo-valentia.it")];
+    char stringpool_str4732[sizeof("xn--vard-jra.no")];
+    char stringpool_str4733[sizeof("rs.ba")];
+    char stringpool_str4734[sizeof("cb.it")];
+    char stringpool_str4735[sizeof("xn--troms-zua.no")];
+    char stringpool_str4736[sizeof("xn--od0aq3b.hk")];
+    char stringpool_str4737[sizeof("sasebo.nagasaki.jp")];
+    char stringpool_str4738[sizeof("owani.aomori.jp")];
+    char stringpool_str4739[sizeof("toda.saitama.jp")];
+    char stringpool_str4740[sizeof("sciencehistory.museum")];
+    char stringpool_str4741[sizeof("rv.ua")];
+    char stringpool_str4742[sizeof("cn.it")];
+    char stringpool_str4743[sizeof("bn.it")];
+    char stringpool_str4744[sizeof("toscana.it")];
+    char stringpool_str4745[sizeof("bo.telemark.no")];
+    char stringpool_str4746[sizeof("works.aero")];
+    char stringpool_str4747[sizeof("gx.cn")];
+    char stringpool_str4748[sizeof("nx.cn")];
+    char stringpool_str4749[sizeof("kg.kr")];
+    char stringpool_str4750[sizeof("en.it")];
+    char stringpool_str4751[sizeof("ru.com")];
+    char stringpool_str4752[sizeof("ternopil.ua")];
+    char stringpool_str4753[sizeof("malvik.no")];
+    char stringpool_str4754[sizeof("jx.cn")];
+    char stringpool_str4755[sizeof("sakuho.nagano.jp")];
+    char stringpool_str4756[sizeof("tottori.jp")];
+    char stringpool_str4757[sizeof("eu.int")];
+    char stringpool_str4758[sizeof("xn--smla-hra.no")];
+    char stringpool_str4759[sizeof("cl.it")];
+    char stringpool_str4760[sizeof("bl.it")];
+    char stringpool_str4761[sizeof("xn--osyro-wua.no")];
+    char stringpool_str4762[sizeof("otaki.nagano.jp")];
+    char stringpool_str4763[sizeof("shimotsuma.ibaraki.jp")];
+    char stringpool_str4764[sizeof("trogstad.no")];
+    char stringpool_str4765[sizeof("oseto.nagasaki.jp")];
+    char stringpool_str4766[sizeof("furniture.museum")];
+    char stringpool_str4767[sizeof("otake.hiroshima.jp")];
+    char stringpool_str4768[sizeof("mitake.gifu.jp")];
+    char stringpool_str4769[sizeof("torsken.no")];
+    char stringpool_str4770[sizeof("tuscany.it")];
+    char stringpool_str4771[sizeof("asahi.mie.jp")];
+    char stringpool_str4772[sizeof("xn--zf0ao64a.tw")];
+    char stringpool_str4773[sizeof("showa.yamanashi.jp")];
+    char stringpool_str4774[sizeof("org.cw")];
+    char stringpool_str4775[sizeof("an.it")];
+    char stringpool_str4776[sizeof("luxembourg.museum")];
+    char stringpool_str4777[sizeof("org.cn")];
+    char stringpool_str4778[sizeof("xn--rde-ula.no")];
+    char stringpool_str4779[sizeof("xn--msy-ula0h.no")];
+    char stringpool_str4780[sizeof("xn--wgbl6a")];
+    char stringpool_str4781[sizeof("aq.it")];
+    char stringpool_str4782[sizeof("toyo.kochi.jp")];
+    char stringpool_str4783[sizeof("xn--lgrd-poac.no")];
+    char stringpool_str4784[sizeof("xn--unjrga-rta.no")];
+    char stringpool_str4785[sizeof("xn--p1acf")];
+    char stringpool_str4786[sizeof("rl.no")];
+    char stringpool_str4787[sizeof("co.gg")];
+    char stringpool_str4788[sizeof("al.it")];
+    char stringpool_str4789[sizeof("railroad.museum")];
+    char stringpool_str4790[sizeof("obama.fukui.jp")];
+    char stringpool_str4791[sizeof("fujiyoshida.yamanashi.jp")];
+    char stringpool_str4792[sizeof("frog.museum")];
+    char stringpool_str4793[sizeof("hanyu.saitama.jp")];
+    char stringpool_str4794[sizeof("horonobe.hokkaido.jp")];
+    char stringpool_str4795[sizeof("av.it")];
+    char stringpool_str4796[sizeof("isumi.chiba.jp")];
+    char stringpool_str4797[sizeof("california.museum")];
+    char stringpool_str4798[sizeof("today")];
+    char stringpool_str4799[sizeof("xn--yer-zna.no")];
+    char stringpool_str4800[sizeof("tara.saga.jp")];
+    char stringpool_str4801[sizeof("org.mx")];
+    char stringpool_str4802[sizeof("shimodate.ibaraki.jp")];
+    char stringpool_str4803[sizeof("qh.cn")];
+    char stringpool_str4804[sizeof("gotsu.shimane.jp")];
+    char stringpool_str4805[sizeof("shimoichi.nara.jp")];
+    char stringpool_str4806[sizeof("xn--seral-lra.no")];
+    char stringpool_str4807[sizeof("swidnica.pl")];
+    char stringpool_str4808[sizeof("xn--trna-woa.no")];
+    char stringpool_str4809[sizeof("tama.tokyo.jp")];
+    char stringpool_str4810[sizeof("tourism.tn")];
+    char stringpool_str4811[sizeof("xn--yfro4i67o")];
+    char stringpool_str4812[sizeof("tottori.tottori.jp")];
+    char stringpool_str4813[sizeof("xn--nry-yla5g.no")];
+    char stringpool_str4814[sizeof("izumo.shimane.jp")];
+    char stringpool_str4815[sizeof("ch.it")];
+    char stringpool_str4816[sizeof("yokosuka.kanagawa.jp")];
+    char stringpool_str4817[sizeof("suwalki.pl")];
+    char stringpool_str4818[sizeof("transport.museum")];
+    char stringpool_str4819[sizeof("xn--vg-yiab.no")];
+    char stringpool_str4820[sizeof("showa.fukushima.jp")];
+    char stringpool_str4821[sizeof("xn--uc0atv.hk")];
+    char stringpool_str4822[sizeof("selfip.net")];
+    char stringpool_str4823[sizeof("xn--vgan-qoa.no")];
+    char stringpool_str4824[sizeof("tadaoka.osaka.jp")];
+    char stringpool_str4825[sizeof("omuta.fukuoka.jp")];
+    char stringpool_str4826[sizeof("choyo.kumamoto.jp")];
+    char stringpool_str4827[sizeof("obama.nagasaki.jp")];
+    char stringpool_str4828[sizeof("otama.fukushima.jp")];
+    char stringpool_str4829[sizeof("xn--vry-yla5g.no")];
+    char stringpool_str4830[sizeof("wy.us")];
+    char stringpool_str4831[sizeof("mosvik.no")];
+    char stringpool_str4832[sizeof("selfip.info")];
+    char stringpool_str4833[sizeof("salvadordali.museum")];
+    char stringpool_str4834[sizeof("shinjo.yamagata.jp")];
+    char stringpool_str4835[sizeof("xn--sr-aurdal-l8a.no")];
+    char stringpool_str4836[sizeof("marugame.kagawa.jp")];
+    char stringpool_str4837[sizeof("uchinada.ishikawa.jp")];
+    char stringpool_str4838[sizeof("xn--rskog-uua.no")];
+    char stringpool_str4839[sizeof("tonsberg.no")];
+    char stringpool_str4840[sizeof("xn--j6w193g")];
+    char stringpool_str4841[sizeof("xn--mjndalen-64a.no")];
+    char stringpool_str4842[sizeof("ut.us")];
+    char stringpool_str4843[sizeof("troandin.no")];
+    char stringpool_str4844[sizeof("oyodo.nara.jp")];
+    char stringpool_str4845[sizeof("tatarstan.ru")];
+    char stringpool_str4846[sizeof("tsukumi.oita.jp")];
+    char stringpool_str4847[sizeof("ath.cx")];
+    char stringpool_str4848[sizeof("otari.nagano.jp")];
+    char stringpool_str4849[sizeof("limanowa.pl")];
+    char stringpool_str4850[sizeof("niyodogawa.kochi.jp")];
+    char stringpool_str4851[sizeof("living.museum")];
+    char stringpool_str4852[sizeof("iwama.ibaraki.jp")];
+    char stringpool_str4853[sizeof("xn--lns-qla.museum")];
+    char stringpool_str4854[sizeof("toga.toyama.jp")];
+    char stringpool_str4855[sizeof("uz.ua")];
+    char stringpool_str4856[sizeof("buzen.fukuoka.jp")];
+    char stringpool_str4857[sizeof("serveftp.net")];
+    char stringpool_str4858[sizeof("tourism.pl")];
+    char stringpool_str4859[sizeof("tsaritsyn.ru")];
+    char stringpool_str4860[sizeof("matsuura.nagasaki.jp")];
+    char stringpool_str4861[sizeof("kahoku.ishikawa.jp")];
+    char stringpool_str4862[sizeof("xn--klbu-woa.no")];
+    char stringpool_str4863[sizeof("tsuruta.aomori.jp")];
+    char stringpool_str4864[sizeof("xn--trany-yua.no")];
+    char stringpool_str4865[sizeof("larsson.museum")];
+    char stringpool_str4866[sizeof("scienceandindustry.museum")];
+    char stringpool_str4867[sizeof("kawara.fukuoka.jp")];
+    char stringpool_str4868[sizeof("lib.nv.us")];
+    char stringpool_str4869[sizeof("kahoku.yamagata.jp")];
+    char stringpool_str4870[sizeof("xn--tn0ag.hk")];
+    char stringpool_str4871[sizeof("school.museum")];
+    char stringpool_str4872[sizeof("from-ut.com")];
+    char stringpool_str4873[sizeof("other.nf")];
+    char stringpool_str4874[sizeof("oketo.hokkaido.jp")];
+    char stringpool_str4875[sizeof("xn--3ds443g")];
+    char stringpool_str4876[sizeof("xn--55qx5d.hk")];
+    char stringpool_str4877[sizeof("xn--drbak-wua.no")];
+    char stringpool_str4878[sizeof("xn--6frz82g")];
+    char stringpool_str4879[sizeof("xn--ses554g")];
+    char stringpool_str4880[sizeof("otobe.hokkaido.jp")];
+    char stringpool_str4881[sizeof("xn--mgbaam7a8h")];
+    char stringpool_str4882[sizeof("xn--mlatvuopmi-s4a.no")];
+    char stringpool_str4883[sizeof("tosa.kochi.jp")];
+    char stringpool_str4884[sizeof("xn--kprw13d")];
+    char stringpool_str4885[sizeof("us.na")];
+    char stringpool_str4886[sizeof("tosu.saga.jp")];
+    char stringpool_str4887[sizeof("masaki.ehime.jp")];
+    char stringpool_str4888[sizeof("oyabe.toyama.jp")];
+    char stringpool_str4889[sizeof("suwa.nagano.jp")];
+    char stringpool_str4890[sizeof("xn--80adxhks")];
+    char stringpool_str4891[sizeof("servebbs.org")];
+    char stringpool_str4892[sizeof("miyazu.kyoto.jp")];
+    char stringpool_str4893[sizeof("tg")];
+    char stringpool_str4894[sizeof("us.com")];
+    char stringpool_str4895[sizeof("xn--kfjord-iua.no")];
+    char stringpool_str4896[sizeof("otaru.hokkaido.jp")];
+    char stringpool_str4897[sizeof("xn--risr-ira.no")];
+    char stringpool_str4898[sizeof("tuva.ru")];
+    char stringpool_str4899[sizeof("osaki.miyagi.jp")];
+    char stringpool_str4900[sizeof("xn--s-1fa.no")];
+    char stringpool_str4901[sizeof("hikari.yamaguchi.jp")];
+    char stringpool_str4902[sizeof("egyptian.museum")];
+    char stringpool_str4903[sizeof("xn--lcvr32d.hk")];
+    char stringpool_str4904[sizeof("xn--6qq986b3xl")];
+    char stringpool_str4905[sizeof("trieste.it")];
+    char stringpool_str4906[sizeof("iheya.okinawa.jp")];
+    char stringpool_str4907[sizeof("asahi.ibaraki.jp")];
+    char stringpool_str4908[sizeof("tvedestrand.no")];
+    char stringpool_str4909[sizeof("nanyo.yamagata.jp")];
+    char stringpool_str4910[sizeof("oharu.aichi.jp")];
+    char stringpool_str4911[sizeof("reggiocalabria.it")];
+    char stringpool_str4912[sizeof("museumvereniging.museum")];
+    char stringpool_str4913[sizeof("jewish.museum")];
+    char stringpool_str4914[sizeof("is-a-landscaper.com")];
+    char stringpool_str4915[sizeof("trolley.museum")];
+    char stringpool_str4916[sizeof("teledata.mz")];
+    char stringpool_str4917[sizeof("omura.nagasaki.jp")];
+    char stringpool_str4918[sizeof("tobe.ehime.jp")];
+    char stringpool_str4919[sizeof("urausu.hokkaido.jp")];
+    char stringpool_str4920[sizeof("bo.nordland.no")];
+    char stringpool_str4921[sizeof("scienceandhistory.museum")];
+    char stringpool_str4922[sizeof("tula.ru")];
+    char stringpool_str4923[sizeof("hizen.saga.jp")];
+    char stringpool_str4924[sizeof("togo.aichi.jp")];
+    char stringpool_str4925[sizeof("okuma.fukushima.jp")];
+    char stringpool_str4926[sizeof("xn--kput3i")];
+    char stringpool_str4927[sizeof("trustee.museum")];
+    char stringpool_str4928[sizeof("theater.museum")];
+    char stringpool_str4929[sizeof("newport.museum")];
+    char stringpool_str4930[sizeof("xn--rros-gra.no")];
+    char stringpool_str4931[sizeof("environment.museum")];
+    char stringpool_str4932[sizeof("xn--risa-5na.no")];
+    char stringpool_str4933[sizeof("toyonaka.osaka.jp")];
+    char stringpool_str4934[sizeof("xn--uc0atv.tw")];
+    char stringpool_str4935[sizeof("xn--b-5ga.nordland.no")];
+    char stringpool_str4936[sizeof("ozora.hokkaido.jp")];
+    char stringpool_str4937[sizeof("pe")];
+    char stringpool_str4938[sizeof("ps")];
+    char stringpool_str4939[sizeof("net.sy")];
+    char stringpool_str4940[sizeof("bizen.okayama.jp")];
+    char stringpool_str4941[sizeof("com.sy")];
+    char stringpool_str4942[sizeof("shimofusa.chiba.jp")];
+    char stringpool_str4943[sizeof("gov.sy")];
+    char stringpool_str4944[sizeof("net.py")];
+    char stringpool_str4945[sizeof("niepce.museum")];
+    char stringpool_str4946[sizeof("com.py")];
+    char stringpool_str4947[sizeof("gov.py")];
+    char stringpool_str4948[sizeof("edu.sy")];
+    char stringpool_str4949[sizeof("asahi.chiba.jp")];
+    char stringpool_str4950[sizeof("tananger.no")];
+    char stringpool_str4951[sizeof("pa")];
+    char stringpool_str4952[sizeof("suzuka.mie.jp")];
+    char stringpool_str4953[sizeof("kazuno.akita.jp")];
+    char stringpool_str4954[sizeof("edu.py")];
+    char stringpool_str4955[sizeof("xn--stjrdalshalsen-sqb.no")];
+    char stringpool_str4956[sizeof("pt")];
+    char stringpool_str4957[sizeof("me.us")];
+    char stringpool_str4958[sizeof("ogata.akita.jp")];
+    char stringpool_str4959[sizeof("ms.us")];
+    char stringpool_str4960[sizeof("md.us")];
+    char stringpool_str4961[sizeof("xn--b-5ga.telemark.no")];
+    char stringpool_str4962[sizeof("mo.us")];
+    char stringpool_str4963[sizeof("pr")];
+    char stringpool_str4964[sizeof("olecko.pl")];
+    char stringpool_str4965[sizeof("parts")];
+    char stringpool_str4966[sizeof("xn--andy-ira.no")];
+    char stringpool_str4967[sizeof("jetzt")];
+    char stringpool_str4968[sizeof("tjeldsund.no")];
+    char stringpool_str4969[sizeof("xn--l-1fa.no")];
+    char stringpool_str4970[sizeof("net.uy")];
+    char stringpool_str4971[sizeof("com.uy")];
+    char stringpool_str4972[sizeof("pub")];
+    char stringpool_str4973[sizeof("moriya.ibaraki.jp")];
+    char stringpool_str4974[sizeof("dontexist.com")];
+    char stringpool_str4975[sizeof("xn--linds-pra.no")];
+    char stringpool_str4976[sizeof("ma.us")];
+    char stringpool_str4977[sizeof("pm")];
+    char stringpool_str4978[sizeof("mt.us")];
+    char stringpool_str4979[sizeof("xn--sandy-yua.no")];
+    char stringpool_str4980[sizeof("ouchi.saga.jp")];
+    char stringpool_str4981[sizeof("daigo.ibaraki.jp")];
+    char stringpool_str4982[sizeof("re.it")];
+    char stringpool_str4983[sizeof("xn--mk0axi.hk")];
+    char stringpool_str4984[sizeof("syzran.ru")];
+    char stringpool_str4985[sizeof("net.my")];
+    char stringpool_str4986[sizeof("usdecorativearts.museum")];
+    char stringpool_str4987[sizeof("com.my")];
+    char stringpool_str4988[sizeof("sowa.ibaraki.jp")];
+    char stringpool_str4989[sizeof("gov.my")];
+    char stringpool_str4990[sizeof("ro.it")];
+    char stringpool_str4991[sizeof("edu.uy")];
+    char stringpool_str4992[sizeof("test.ru")];
+    char stringpool_str4993[sizeof("xn--sknit-yqa.no")];
+    char stringpool_str4994[sizeof("sakuragawa.ibaraki.jp")];
+    char stringpool_str4995[sizeof("tono.iwate.jp")];
+    char stringpool_str4996[sizeof("xn--bmlo-gra.no")];
+    char stringpool_str4997[sizeof("trentino.it")];
+    char stringpool_str4998[sizeof("xn--wcvs22d.hk")];
+    char stringpool_str4999[sizeof("org.ci")];
+    char stringpool_str5000[sizeof("abiko.chiba.jp")];
+    char stringpool_str5001[sizeof("uk.net")];
+    char stringpool_str5002[sizeof("reggio-emilia.it")];
+    char stringpool_str5003[sizeof("edu.my")];
+    char stringpool_str5004[sizeof("tsukuba.ibaraki.jp")];
+    char stringpool_str5005[sizeof("me.tz")];
+    char stringpool_str5006[sizeof("us.org")];
+    char stringpool_str5007[sizeof("ra.it")];
+    char stringpool_str5008[sizeof("xn--lesund-hua.no")];
+    char stringpool_str5009[sizeof("gub.uy")];
+    char stringpool_str5010[sizeof("com.by")];
+    char stringpool_str5011[sizeof("gov.by")];
+    char stringpool_str5012[sizeof("www.ro")];
+    char stringpool_str5013[sizeof("is-a-caterer.com")];
+    char stringpool_str5014[sizeof("xn--dnna-gra.no")];
+    char stringpool_str5015[sizeof("toyoura.hokkaido.jp")];
+    char stringpool_str5016[sizeof("toon.ehime.jp")];
+    char stringpool_str5017[sizeof("isa-geek.net")];
+    char stringpool_str5018[sizeof("pn")];
+    char stringpool_str5019[sizeof("mi.us")];
+    char stringpool_str5020[sizeof("ms.kr")];
+    char stringpool_str5021[sizeof("taku.saga.jp")];
+    char stringpool_str5022[sizeof("uk.com")];
+    char stringpool_str5023[sizeof("praxi")];
+    char stringpool_str5024[sizeof("rm.it")];
+    char stringpool_str5025[sizeof("xn--hery-ira.nordland.no")];
+    char stringpool_str5026[sizeof("loten.no")];
+    char stringpool_str5027[sizeof("pink")];
+    char stringpool_str5028[sizeof("xn--brum-voa.no")];
+    char stringpool_str5029[sizeof("xn--h-2fa.no")];
+    char stringpool_str5030[sizeof("pro")];
+    char stringpool_str5031[sizeof("tondabayashi.osaka.jp")];
+    char stringpool_str5032[sizeof("prod")];
+    char stringpool_str5033[sizeof("pro.ec")];
+    char stringpool_str5034[sizeof("cci.fr")];
+    char stringpool_str5035[sizeof("pl")];
+    char stringpool_str5036[sizeof("mn.us")];
+    char stringpool_str5037[sizeof("shikokuchuo.ehime.jp")];
+    char stringpool_str5038[sizeof("pro.pr")];
+    char stringpool_str5039[sizeof("net.ly")];
+    char stringpool_str5040[sizeof("pmn.it")];
+    char stringpool_str5041[sizeof("ppg.br")];
+    char stringpool_str5042[sizeof("com.ly")];
+    char stringpool_str5043[sizeof("ri.it")];
+    char stringpool_str5044[sizeof("gov.ly")];
+    char stringpool_str5045[sizeof("md.ci")];
+    char stringpool_str5046[sizeof("tranibarlettaandria.it")];
+    char stringpool_str5047[sizeof("shiwa.iwate.jp")];
+    char stringpool_str5048[sizeof("pila.pl")];
+    char stringpool_str5049[sizeof("okayama.jp")];
+    char stringpool_str5050[sizeof("trani-andria-barletta.it")];
+    char stringpool_str5051[sizeof("bg.it")];
+    char stringpool_str5052[sizeof("edu.ly")];
+    char stringpool_str5053[sizeof("xn--rholt-mra.no")];
+    char stringpool_str5054[sizeof("sodegaura.chiba.jp")];
+    char stringpool_str5055[sizeof("p.bg")];
+    char stringpool_str5056[sizeof("pro.tt")];
+    char stringpool_str5057[sizeof("mr.no")];
+    char stringpool_str5058[sizeof("xn--rady-ira.no")];
+    char stringpool_str5059[sizeof("tatsuno.nagano.jp")];
+    char stringpool_str5060[sizeof("akagi.shimane.jp")];
+    char stringpool_str5061[sizeof("pug.it")];
+    char stringpool_str5062[sizeof("rn.it")];
+    char stringpool_str5063[sizeof("ogose.saitama.jp")];
+    char stringpool_str5064[sizeof("pub.sa")];
+    char stringpool_str5065[sizeof("mo.cn")];
+    char stringpool_str5066[sizeof("ogano.saitama.jp")];
+    char stringpool_str5067[sizeof("rokunohe.aomori.jp")];
+    char stringpool_str5068[sizeof("mb.ca")];
+    char stringpool_str5069[sizeof("gaivuotna.no")];
+    char stringpool_str5070[sizeof("tsu.mie.jp")];
+    char stringpool_str5071[sizeof("mp.br")];
+    char stringpool_str5072[sizeof("xn--smna-gra.no")];
+    char stringpool_str5073[sizeof("lecce.it")];
+    char stringpool_str5074[sizeof("mansions.museum")];
+    char stringpool_str5075[sizeof("lecco.it")];
+    char stringpool_str5076[sizeof("satsumasendai.kagoshima.jp")];
+    char stringpool_str5077[sizeof("olawa.pl")];
+    char stringpool_str5078[sizeof("tver.ru")];
+    char stringpool_str5079[sizeof("xn--80ao21a")];
+    char stringpool_str5080[sizeof("ham-radio-op.net")];
+    char stringpool_str5081[sizeof("tone.ibaraki.jp")];
+    char stringpool_str5082[sizeof("xn--bjddar-pta.no")];
+    char stringpool_str5083[sizeof("xn--unup4y")];
+    char stringpool_str5084[sizeof("pics")];
+    char stringpool_str5085[sizeof("ag.it")];
+    char stringpool_str5086[sizeof("withgoogle.com")];
+    char stringpool_str5087[sizeof("bolzano.it")];
+    char stringpool_str5088[sizeof("trainer.aero")];
+    char stringpool_str5089[sizeof("labor.museum")];
+    char stringpool_str5090[sizeof("xn--vhquv")];
+    char stringpool_str5091[sizeof("post")];
+    char stringpool_str5092[sizeof("pk")];
+    char stringpool_str5093[sizeof("psc.br")];
+    char stringpool_str5094[sizeof("port.fr")];
+    char stringpool_str5095[sizeof("net.ky")];
+    char stringpool_str5096[sizeof("obira.hokkaido.jp")];
+    char stringpool_str5097[sizeof("ph")];
+    char stringpool_str5098[sizeof("com.ky")];
+    char stringpool_str5099[sizeof("gov.ky")];
+    char stringpool_str5100[sizeof("is-a-democrat.com")];
+    char stringpool_str5101[sizeof("pro.br")];
+    char stringpool_str5102[sizeof("gs.jan-mayen.no")];
+    char stringpool_str5103[sizeof("sykkylven.no")];
+    char stringpool_str5104[sizeof("xn--vads-jra.no")];
+    char stringpool_str5105[sizeof("xn--kranghke-b0a.no")];
+    char stringpool_str5106[sizeof("tas.edu.au")];
+    char stringpool_str5107[sizeof("pro.om")];
+    char stringpool_str5108[sizeof("prof.pr")];
+    char stringpool_str5109[sizeof("edu.ky")];
+    char stringpool_str5110[sizeof("adygeya.ru")];
+    char stringpool_str5111[sizeof("xn--lten-gra.no")];
+    char stringpool_str5112[sizeof("p.se")];
+    char stringpool_str5113[sizeof("xn--od0alg.hk")];
+    char stringpool_str5114[sizeof("plo.ps")];
+    char stringpool_str5115[sizeof("per.nf")];
+    char stringpool_str5116[sizeof("shimotsuke.tochigi.jp")];
+    char stringpool_str5117[sizeof("is-an-anarchist.com")];
+    char stringpool_str5118[sizeof("samegawa.fukushima.jp")];
+    char stringpool_str5119[sizeof("swinoujscie.pl")];
+    char stringpool_str5120[sizeof("lucca.it")];
+    char stringpool_str5121[sizeof("per.la")];
+    char stringpool_str5122[sizeof("oguni.kumamoto.jp")];
+    char stringpool_str5123[sizeof("partners")];
+    char stringpool_str5124[sizeof("forgot.her.name")];
+    char stringpool_str5125[sizeof("va.us")];
+    char stringpool_str5126[sizeof("mk.ua")];
+    char stringpool_str5127[sizeof("onojo.fukuoka.jp")];
+    char stringpool_str5128[sizeof("pol.ht")];
+    char stringpool_str5129[sizeof("trani-barletta-andria.it")];
+    char stringpool_str5130[sizeof("pw")];
+    char stringpool_str5131[sizeof("vt.us")];
+    char stringpool_str5132[sizeof("per.sg")];
+    char stringpool_str5133[sizeof("xn--lrdal-sra.no")];
+    char stringpool_str5134[sizeof("xn--vler-qoa.hedmark.no")];
+    char stringpool_str5135[sizeof("xn--leagaviika-52b.no")];
+    char stringpool_str5136[sizeof("pro.vn")];
+    char stringpool_str5137[sizeof("go.dyndns.org")];
+    char stringpool_str5138[sizeof("airforce")];
+    char stringpool_str5139[sizeof("xn--55qw42g")];
+    char stringpool_str5140[sizeof("xn--80aswg")];
+    char stringpool_str5141[sizeof("schweiz.museum")];
+    char stringpool_str5142[sizeof("xn--hpmir-xqa.no")];
+    char stringpool_str5143[sizeof("k12.gu.us")];
+    char stringpool_str5144[sizeof("xn--karmy-yua.no")];
+    char stringpool_str5145[sizeof("is-a-nascarfan.com")];
+    char stringpool_str5146[sizeof("aeroclub.aero")];
+    char stringpool_str5147[sizeof("uy.com")];
+    char stringpool_str5148[sizeof("off.ai")];
+    char stringpool_str5149[sizeof("government.aero")];
+    char stringpool_str5150[sizeof("udono.mie.jp")];
+    char stringpool_str5151[sizeof("motegi.tochigi.jp")];
+    char stringpool_str5152[sizeof("toyosato.shiga.jp")];
+    char stringpool_str5153[sizeof("blogspot.cf")];
+    char stringpool_str5154[sizeof("vi.us")];
+    char stringpool_str5155[sizeof("masfjorden.no")];
+    char stringpool_str5156[sizeof("photo")];
+    char stringpool_str5157[sizeof("tsubata.ishikawa.jp")];
+    char stringpool_str5158[sizeof("xn--ygbi2ammx")];
+    char stringpool_str5159[sizeof("yuzhno-sakhalinsk.ru")];
+    char stringpool_str5160[sizeof("shinanomachi.nagano.jp")];
+    char stringpool_str5161[sizeof("mi.th")];
+    char stringpool_str5162[sizeof("publ.pt")];
+    char stringpool_str5163[sizeof("xn--krdsherad-m8a.no")];
+    char stringpool_str5164[sizeof("tsugaru.aomori.jp")];
+    char stringpool_str5165[sizeof("takaishi.osaka.jp")];
+    char stringpool_str5166[sizeof("photos")];
+    char stringpool_str5167[sizeof("laspezia.it")];
+    char stringpool_str5168[sizeof("pescara.it")];
+    char stringpool_str5169[sizeof("ostrowiec.pl")];
+    char stringpool_str5170[sizeof("porsangu.no")];
+    char stringpool_str5171[sizeof("pro.ht")];
+    char stringpool_str5172[sizeof("pri.ee")];
+    char stringpool_str5173[sizeof("palermo.it")];
+    char stringpool_str5174[sizeof("trentino-stirol.it")];
+    char stringpool_str5175[sizeof("xn--krjohka-hwab49j.no")];
+    char stringpool_str5176[sizeof("pro.na")];
+    char stringpool_str5177[sizeof("betainabox.com")];
+    char stringpool_str5178[sizeof("psi.br")];
+    char stringpool_str5179[sizeof("va.no")];
+    char stringpool_str5180[sizeof("ud.it")];
+    char stringpool_str5181[sizeof("toya.hokkaido.jp")];
+    char stringpool_str5182[sizeof("inuyama.aichi.jp")];
+    char stringpool_str5183[sizeof("googlecode.com")];
+    char stringpool_str5184[sizeof("serveftp.org")];
+    char stringpool_str5185[sizeof("vn.ua")];
+    char stringpool_str5186[sizeof("prd.km")];
+    char stringpool_str5187[sizeof("ide.kyoto.jp")];
+    char stringpool_str5188[sizeof("tochigi.jp")];
+    char stringpool_str5189[sizeof("urbinopesaro.it")];
+    char stringpool_str5190[sizeof("is-a-therapist.com")];
+    char stringpool_str5191[sizeof("xn--btsfjord-9za.no")];
+    char stringpool_str5192[sizeof("kawai.nara.jp")];
+    char stringpool_str5193[sizeof("xn--nqv7f")];
+    char stringpool_str5194[sizeof("py")];
+    char stringpool_str5195[sizeof("s3-sa-east-1.amazonaws.com")];
+    char stringpool_str5196[sizeof("takaoka.toyama.jp")];
+    char stringpool_str5197[sizeof("prd.mg")];
+    char stringpool_str5198[sizeof("traniandriabarletta.it")];
+    char stringpool_str5199[sizeof("toyohashi.aichi.jp")];
+    char stringpool_str5200[sizeof("tsurugashima.saitama.jp")];
+    char stringpool_str5201[sizeof("trentinostirol.it")];
+    char stringpool_str5202[sizeof("fukuchiyama.kyoto.jp")];
+    char stringpool_str5203[sizeof("trentino-s-tirol.it")];
+    char stringpool_str5204[sizeof("trentinos-tirol.it")];
+    char stringpool_str5205[sizeof("piacenza.it")];
+    char stringpool_str5206[sizeof("trentinosudtirol.it")];
+    char stringpool_str5207[sizeof("ebiz.tw")];
+    char stringpool_str5208[sizeof("luroy.no")];
+    char stringpool_str5209[sizeof("shinjuku.tokyo.jp")];
+    char stringpool_str5210[sizeof("trentino-suedtirol.it")];
+    char stringpool_str5211[sizeof("xn--rlingen-mxa.no")];
+    char stringpool_str5212[sizeof("xn--rmskog-bya.no")];
+    char stringpool_str5213[sizeof("is-a-anarchist.com")];
+    char stringpool_str5214[sizeof("sch.jo")];
+    char stringpool_str5215[sizeof("tomioka.gunma.jp")];
+    char stringpool_str5216[sizeof("trentino-sudtirol.it")];
+    char stringpool_str5217[sizeof("trentino-sud-tirol.it")];
+    char stringpool_str5218[sizeof("paderborn.museum")];
+    char stringpool_str5219[sizeof("tsubetsu.hokkaido.jp")];
+    char stringpool_str5220[sizeof("xn--bidr-5nac.no")];
+    char stringpool_str5221[sizeof("minobu.yamanashi.jp")];
+    char stringpool_str5222[sizeof("trentinosuedtirol.it")];
+    char stringpool_str5223[sizeof("trentinosued-tirol.it")];
+    char stringpool_str5224[sizeof("xn--lrenskog-54a.no")];
+    char stringpool_str5225[sizeof("toei.aichi.jp")];
+    char stringpool_str5226[sizeof("xn--vrggt-xqad.no")];
+    char stringpool_str5227[sizeof("xn--bdddj-mrabd.no")];
+    char stringpool_str5228[sizeof("xn--3bst00m")];
+    char stringpool_str5229[sizeof("union.aero")];
+    char stringpool_str5230[sizeof("xn--hcesuolo-7ya35b.no")];
+    char stringpool_str5231[sizeof("sex.hu")];
+    char stringpool_str5232[sizeof("trentino-sued-tirol.it")];
+    char stringpool_str5233[sizeof("ine.kyoto.jp")];
+    char stringpool_str5234[sizeof("pol.dz")];
+    char stringpool_str5235[sizeof("toyooka.hyogo.jp")];
+    char stringpool_str5236[sizeof("ohira.miyagi.jp")];
+    char stringpool_str5237[sizeof("trysil.no")];
+    char stringpool_str5238[sizeof("xn--bievt-0qa.no")];
+    char stringpool_str5239[sizeof("okoppe.hokkaido.jp")];
+    char stringpool_str5240[sizeof("pictures")];
+    char stringpool_str5241[sizeof("yamanobe.yamagata.jp")];
+    char stringpool_str5242[sizeof("cieszyn.pl")];
+    char stringpool_str5243[sizeof("trentinoaadige.it")];
+    char stringpool_str5244[sizeof("val-d-aosta.it")];
+    char stringpool_str5245[sizeof("trentinosud-tirol.it")];
+    char stringpool_str5246[sizeof("tanohata.iwate.jp")];
+    char stringpool_str5247[sizeof("tatebayashi.gunma.jp")];
+    char stringpool_str5248[sizeof("shirakawa.fukushima.jp")];
+    char stringpool_str5249[sizeof("television.museum")];
+    char stringpool_str5250[sizeof("xn--mgbayh7gpa")];
+    char stringpool_str5251[sizeof("urbino-pesaro.it")];
+    char stringpool_str5252[sizeof("tomi.nagano.jp")];
+    char stringpool_str5253[sizeof("s3-ap-northeast-1.amazonaws.com")];
+    char stringpool_str5254[sizeof("xn--sandnessjen-ogb.no")];
+    char stringpool_str5255[sizeof("shinonsen.hyogo.jp")];
+    char stringpool_str5256[sizeof("ovre-eiker.no")];
+    char stringpool_str5257[sizeof("xn--zf0avx.hk")];
+    char stringpool_str5258[sizeof("xn--trgstad-r1a.no")];
+    char stringpool_str5259[sizeof("friulivegiulia.it")];
+    char stringpool_str5260[sizeof("xn--srum-gra.no")];
+    char stringpool_str5261[sizeof("associates")];
+    char stringpool_str5262[sizeof("kaszuby.pl")];
+    char stringpool_str5263[sizeof("lc")];
+    char stringpool_str5264[sizeof("mex.com")];
+    char stringpool_str5265[sizeof("xn--rdy-0nab.no")];
+    char stringpool_str5266[sizeof("net.cu")];
+    char stringpool_str5267[sizeof("pvt.k12.ma.us")];
+    char stringpool_str5268[sizeof("perm.ru")];
+    char stringpool_str5269[sizeof("com.cu")];
+    char stringpool_str5270[sizeof("gov.cu")];
+    char stringpool_str5271[sizeof("trondheim.no")];
+    char stringpool_str5272[sizeof("obu.aichi.jp")];
+    char stringpool_str5273[sizeof("tatsuno.hyogo.jp")];
+    char stringpool_str5274[sizeof("paris")];
+    char stringpool_str5275[sizeof("pro.az")];
+    char stringpool_str5276[sizeof("xn--rhqv96g")];
+    char stringpool_str5277[sizeof("countryestate.museum")];
+    char stringpool_str5278[sizeof("xn--krehamn-dxa.no")];
+    char stringpool_str5279[sizeof("edu.cu")];
+    char stringpool_str5280[sizeof("tsukigata.hokkaido.jp")];
+    char stringpool_str5281[sizeof("xn--bearalvhki-y4a.no")];
+    char stringpool_str5282[sizeof("xn--sr-odal-q1a.no")];
+    char stringpool_str5283[sizeof("lesja.no")];
+    char stringpool_str5284[sizeof("is-slick.com")];
+    char stringpool_str5285[sizeof("is-a-musician.com")];
+    char stringpool_str5286[sizeof("sakura.tochigi.jp")];
+    char stringpool_str5287[sizeof("ogaki.gifu.jp")];
+    char stringpool_str5288[sizeof("coastaldefence.museum")];
+    char stringpool_str5289[sizeof("suzaka.nagano.jp")];
+    char stringpool_str5290[sizeof("nishio.aichi.jp")];
+    char stringpool_str5291[sizeof("motobu.okinawa.jp")];
+    char stringpool_str5292[sizeof("xn--stjrdal-s1a.no")];
+    char stringpool_str5293[sizeof("lapy.pl")];
+    char stringpool_str5294[sizeof("productions")];
+    char stringpool_str5295[sizeof("kofu.yamanashi.jp")];
+    char stringpool_str5296[sizeof("me.it")];
+    char stringpool_str5297[sizeof("ms.it")];
+    char stringpool_str5298[sizeof("ketrzyn.pl")];
+    char stringpool_str5299[sizeof("flight.aero")];
+    char stringpool_str5300[sizeof("mo.it")];
+    char stringpool_str5301[sizeof("pg")];
+    char stringpool_str5302[sizeof("sakawa.kochi.jp")];
+    char stringpool_str5303[sizeof("net.gy")];
+    char stringpool_str5304[sizeof("com.gy")];
+    char stringpool_str5305[sizeof("isa-geek.org")];
+    char stringpool_str5306[sizeof("lubin.pl")];
+    char stringpool_str5307[sizeof("lukow.pl")];
+    char stringpool_str5308[sizeof("tateyama.toyama.jp")];
+    char stringpool_str5309[sizeof("tome.miyagi.jp")];
+    char stringpool_str5310[sizeof("lakas.hu")];
+    char stringpool_str5311[sizeof("tromsa.no")];
+    char stringpool_str5312[sizeof("oyama.tochigi.jp")];
+    char stringpool_str5313[sizeof("kawagoe.saitama.jp")];
+    char stringpool_str5314[sizeof("settsu.osaka.jp")];
+    char stringpool_str5315[sizeof("sukagawa.fukushima.jp")];
+    char stringpool_str5316[sizeof("kawagoe.mie.jp")];
+    char stringpool_str5317[sizeof("act.au")];
+    char stringpool_str5318[sizeof("mt.it")];
+    char stringpool_str5319[sizeof("xn--rst-0na.no")];
+    char stringpool_str5320[sizeof("ogimi.okinawa.jp")];
+    char stringpool_str5321[sizeof("tokushima.jp")];
+    char stringpool_str5322[sizeof("juedisches.museum")];
+    char stringpool_str5323[sizeof("ogori.fukuoka.jp")];
+    char stringpool_str5324[sizeof("susaki.kochi.jp")];
+    char stringpool_str5325[sizeof("potenza.it")];
+    char stringpool_str5326[sizeof("org.au")];
+    char stringpool_str5327[sizeof("laz.it")];
+    char stringpool_str5328[sizeof("tsumagoi.gunma.jp")];
+    char stringpool_str5329[sizeof("toshima.tokyo.jp")];
+    char stringpool_str5330[sizeof("planetarium.museum")];
+    char stringpool_str5331[sizeof("is-a-geek.com")];
+    char stringpool_str5332[sizeof("fukushima.fukushima.jp")];
+    char stringpool_str5333[sizeof("org.ru")];
+    char stringpool_str5334[sizeof("tobetsu.hokkaido.jp")];
+    char stringpool_str5335[sizeof("s3-ap-southeast-1.amazonaws.com")];
+    char stringpool_str5336[sizeof("rg.it")];
+    char stringpool_str5337[sizeof("xn--pgbs0dh")];
+    char stringpool_str5338[sizeof("kisarazu.chiba.jp")];
+    char stringpool_str5339[sizeof("cody.museum")];
+    char stringpool_str5340[sizeof("mi.it")];
+    char stringpool_str5341[sizeof("org.mu")];
+    char stringpool_str5342[sizeof("val-daosta.it")];
+    char stringpool_str5343[sizeof("ochi.kochi.jp")];
+    char stringpool_str5344[sizeof("taka.hyogo.jp")];
+    char stringpool_str5345[sizeof("mb.it")];
+    char stringpool_str5346[sizeof("mx.na")];
+    char stringpool_str5347[sizeof("tateshina.nagano.jp")];
+    char stringpool_str5348[sizeof("oguni.yamagata.jp")];
+    char stringpool_str5349[sizeof("inf.cu")];
+    char stringpool_str5350[sizeof("is-an-engineer.com")];
+    char stringpool_str5351[sizeof("training")];
+    char stringpool_str5352[sizeof("mn.it")];
+    char stringpool_str5353[sizeof("s3-us-gov-west-1.amazonaws.com")];
+    char stringpool_str5354[sizeof("unzen.nagasaki.jp")];
+    char stringpool_str5355[sizeof("toho.fukuoka.jp")];
+    char stringpool_str5356[sizeof("unnan.shimane.jp")];
+    char stringpool_str5357[sizeof("k12.co.us")];
+    char stringpool_str5358[sizeof("takahagi.ibaraki.jp")];
+    char stringpool_str5359[sizeof("s3-website-us-west-2.amazonaws.com")];
+    char stringpool_str5360[sizeof("kaizuka.osaka.jp")];
+    char stringpool_str5361[sizeof("lib.mo.us")];
+    char stringpool_str5362[sizeof("lutsk.ua")];
+    char stringpool_str5363[sizeof("tsubame.niigata.jp")];
+    char stringpool_str5364[sizeof("fukuchi.fukuoka.jp")];
+    char stringpool_str5365[sizeof("pistoia.it")];
+    char stringpool_str5366[sizeof("xn--gmqw5a.hk")];
+    char stringpool_str5367[sizeof("tynset.no")];
+    char stringpool_str5368[sizeof("ozu.ehime.jp")];
+    char stringpool_str5369[sizeof("dyndns-server.com")];
+    char stringpool_str5370[sizeof("lacaixa")];
+    char stringpool_str5371[sizeof("database.museum")];
+    char stringpool_str5372[sizeof("neat-url.com")];
+    char stringpool_str5373[sizeof("sd.us")];
+    char stringpool_str5374[sizeof("intelligence.museum")];
+    char stringpool_str5375[sizeof("pvt.ge")];
+    char stringpool_str5376[sizeof("podhale.pl")];
+    char stringpool_str5377[sizeof("nkz.ru")];
+    char stringpool_str5378[sizeof("takasago.hyogo.jp")];
+    char stringpool_str5379[sizeof("friuli-vegiulia.it")];
+    char stringpool_str5380[sizeof("utsunomiya.tochigi.jp")];
+    char stringpool_str5381[sizeof("tanabe.kyoto.jp")];
+    char stringpool_str5382[sizeof("is-a-financialadvisor.com")];
+    char stringpool_str5383[sizeof("chuo.yamanashi.jp")];
+    char stringpool_str5384[sizeof("okayama.okayama.jp")];
+    char stringpool_str5385[sizeof("tsurugi.ishikawa.jp")];
+    char stringpool_str5386[sizeof("ve.it")];
+    char stringpool_str5387[sizeof("pruszkow.pl")];
+    char stringpool_str5388[sizeof("vs.it")];
+    char stringpool_str5389[sizeof("xn--sknland-fxa.no")];
+    char stringpool_str5390[sizeof("futtsu.chiba.jp")];
+    char stringpool_str5391[sizeof("trentino-aadige.it")];
+    char stringpool_str5392[sizeof("va.it")];
+    char stringpool_str5393[sizeof("org.hu")];
+    char stringpool_str5394[sizeof("vt.it")];
+    char stringpool_str5395[sizeof("okawa.kochi.jp")];
+    char stringpool_str5396[sizeof("media.aero")];
+    char stringpool_str5397[sizeof("tsuruga.fukui.jp")];
+    char stringpool_str5398[sizeof("vr.it")];
+    char stringpool_str5399[sizeof("sa.au")];
+    char stringpool_str5400[sizeof("here-for-more.info")];
+    char stringpool_str5401[sizeof("s3-website-ap-southeast-2.amazonaws.com")];
+    char stringpool_str5402[sizeof("kamagaya.chiba.jp")];
+    char stringpool_str5403[sizeof("xn--lhppi-xqa.no")];
+    char stringpool_str5404[sizeof("is-a-chef.com")];
+    char stringpool_str5405[sizeof("sm.ua")];
+    char stringpool_str5406[sizeof("imabari.ehime.jp")];
+    char stringpool_str5407[sizeof("sa.cr")];
+    char stringpool_str5408[sizeof("se.net")];
+    char stringpool_str5409[sizeof("oystre-slidre.no")];
+    char stringpool_str5410[sizeof("delaware.museum")];
+    char stringpool_str5411[sizeof("toyama.jp")];
+    char stringpool_str5412[sizeof("xn--gjvik-wua.no")];
+    char stringpool_str5413[sizeof("simple-url.com")];
+    char stringpool_str5414[sizeof("ako.hyogo.jp")];
+    char stringpool_str5415[sizeof("vi.it")];
+    char stringpool_str5416[sizeof("trentino-a-adige.it")];
+    char stringpool_str5417[sizeof("teshikaga.hokkaido.jp")];
+    char stringpool_str5418[sizeof("sb.ua")];
+    char stringpool_str5419[sizeof("togane.chiba.jp")];
+    char stringpool_str5420[sizeof("vb.it")];
+    char stringpool_str5421[sizeof("tamatsukuri.ibaraki.jp")];
+    char stringpool_str5422[sizeof("friulive-giulia.it")];
+    char stringpool_str5423[sizeof("ohira.tochigi.jp")];
+    char stringpool_str5424[sizeof("takatsuki.osaka.jp")];
+    char stringpool_str5425[sizeof("st.no")];
+    char stringpool_str5426[sizeof("kamogawa.chiba.jp")];
+    char stringpool_str5427[sizeof("tyumen.ru")];
+    char stringpool_str5428[sizeof("trentinoa-adige.it")];
+    char stringpool_str5429[sizeof("se.com")];
+    char stringpool_str5430[sizeof("is-not-certified.com")];
+    char stringpool_str5431[sizeof("portlligat.museum")];
+    char stringpool_str5432[sizeof("sd.cn")];
+    char stringpool_str5433[sizeof("nagato.yamaguchi.jp")];
+    char stringpool_str5434[sizeof("valer.ostfold.no")];
+    char stringpool_str5435[sizeof("katowice.pl")];
+    char stringpool_str5436[sizeof("pomorze.pl")];
+    char stringpool_str5437[sizeof("is-a-bulls-fan.com")];
+    char stringpool_str5438[sizeof("kanzaki.saga.jp")];
+    char stringpool_str5439[sizeof("sa.com")];
+    char stringpool_str5440[sizeof("newmexico.museum")];
+    char stringpool_str5441[sizeof("pisa.it")];
+    char stringpool_str5442[sizeof("watch-and-clock.museum")];
+    char stringpool_str5443[sizeof("preservation.museum")];
+    char stringpool_str5444[sizeof("vv.it")];
+    char stringpool_str5445[sizeof("plumbing")];
+    char stringpool_str5446[sizeof("xn--1qqw23a")];
+    char stringpool_str5447[sizeof("wallonie.museum")];
+    char stringpool_str5448[sizeof("takasaki.gunma.jp")];
+    char stringpool_str5449[sizeof("my.id")];
+    char stringpool_str5450[sizeof("volyn.ua")];
+    char stringpool_str5451[sizeof("airtraffic.aero")];
+    char stringpool_str5452[sizeof("okawa.fukuoka.jp")];
+    char stringpool_str5453[sizeof("lezajsk.pl")];
+    char stringpool_str5454[sizeof("kaminokawa.tochigi.jp")];
+    char stringpool_str5455[sizeof("is-into-anime.com")];
+    char stringpool_str5456[sizeof("omasvuotna.no")];
+    char stringpool_str5457[sizeof("takehara.hiroshima.jp")];
+    char stringpool_str5458[sizeof("stryn.no")];
+    char stringpool_str5459[sizeof("tabayama.yamanashi.jp")];
+    char stringpool_str5460[sizeof("sor-odal.no")];
+    char stringpool_str5461[sizeof("kawai.iwate.jp")];
+    char stringpool_str5462[sizeof("lahppi.no")];
+    char stringpool_str5463[sizeof("shunan.yamaguchi.jp")];
+    char stringpool_str5464[sizeof("xn--ldingen-q1a.no")];
+    char stringpool_str5465[sizeof("newyork.museum")];
+    char stringpool_str5466[sizeof("friuli-ve-giulia.it")];
+    char stringpool_str5467[sizeof("textile.museum")];
+    char stringpool_str5468[sizeof("trentino-altoadige.it")];
+    char stringpool_str5469[sizeof("shioya.tochigi.jp")];
+    char stringpool_str5470[sizeof("timekeeping.museum")];
+    char stringpool_str5471[sizeof("sn.cn")];
+    char stringpool_str5472[sizeof("taxi.br")];
+    char stringpool_str5473[sizeof("nyny.museum")];
+    char stringpool_str5474[sizeof("music.museum")];
+    char stringpool_str5475[sizeof("sk.ca")];
+    char stringpool_str5476[sizeof("oshino.yamanashi.jp")];
+    char stringpool_str5477[sizeof("palmsprings.museum")];
+    char stringpool_str5478[sizeof("store.bb")];
+    char stringpool_str5479[sizeof("trentino-alto-adige.it")];
+    char stringpool_str5480[sizeof("tysnes.no")];
+    char stringpool_str5481[sizeof("schokoladen.museum")];
+    char stringpool_str5482[sizeof("co.pn")];
+    char stringpool_str5483[sizeof("philately.museum")];
+    char stringpool_str5484[sizeof("tachikawa.tokyo.jp")];
+    char stringpool_str5485[sizeof("miharu.fukushima.jp")];
+    char stringpool_str5486[sizeof("trentinoalto-adige.it")];
+    char stringpool_str5487[sizeof("happou.akita.jp")];
+    char stringpool_str5488[sizeof("takazaki.miyazaki.jp")];
+    char stringpool_str5489[sizeof("xn--vgsy-qoa0j.no")];
+    char stringpool_str5490[sizeof("perugia.it")];
+    char stringpool_str5491[sizeof("tsuwano.shimane.jp")];
+    char stringpool_str5492[sizeof("fl.us")];
+    char stringpool_str5493[sizeof("co.pl")];
+    char stringpool_str5494[sizeof("orenburg.ru")];
+    char stringpool_str5495[sizeof("fi.cr")];
+    char stringpool_str5496[sizeof("friuli-veneziagiulia.it")];
+    char stringpool_str5497[sizeof("anpachi.gifu.jp")];
+    char stringpool_str5498[sizeof("owariasahi.aichi.jp")];
+    char stringpool_str5499[sizeof("yokaichiba.chiba.jp")];
+    char stringpool_str5500[sizeof("karmoy.no")];
+    char stringpool_str5501[sizeof("ozu.kumamoto.jp")];
+    char stringpool_str5502[sizeof("fm.no")];
+    char stringpool_str5503[sizeof("westfalen.museum")];
+    char stringpool_str5504[sizeof("kyotanabe.kyoto.jp")];
+    char stringpool_str5505[sizeof("toyotsu.fukuoka.jp")];
+    char stringpool_str5506[sizeof("plantation.museum")];
+    char stringpool_str5507[sizeof("trentinoaltoadige.it")];
+    char stringpool_str5508[sizeof("xn--avery-yua.no")];
+    char stringpool_str5509[sizeof("project.museum")];
+    char stringpool_str5510[sizeof("muroto.kochi.jp")];
+    char stringpool_str5511[sizeof("olbia-tempio.it")];
+    char stringpool_str5512[sizeof("sh.cn")];
+    char stringpool_str5513[sizeof("issmarterthanyou.com")];
+    char stringpool_str5514[sizeof("iglesias-carbonia.it")];
+    char stringpool_str5515[sizeof("xn--sr-fron-q1a.no")];
+    char stringpool_str5516[sizeof("endofinternet.net")];
+    char stringpool_str5517[sizeof("friuli-venezia-giulia.it")];
+    char stringpool_str5518[sizeof("valer.hedmark.no")];
+    char stringpool_str5519[sizeof("fj.cn")];
+    char stringpool_str5520[sizeof("research.museum")];
+    char stringpool_str5521[sizeof("ogawa.saitama.jp")];
+    char stringpool_str5522[sizeof("lindesnes.no")];
+    char stringpool_str5523[sizeof("fm.br")];
+    char stringpool_str5524[sizeof("fh.se")];
+    char stringpool_str5525[sizeof("takamatsu.kagawa.jp")];
+    char stringpool_str5526[sizeof("friuliveneziagiulia.it")];
+    char stringpool_str5527[sizeof("phoenix.museum")];
+    char stringpool_str5528[sizeof("froya.no")];
+    char stringpool_str5529[sizeof("kitakyushu.jp")];
+    char stringpool_str5530[sizeof("iide.yamagata.jp")];
+    char stringpool_str5531[sizeof("newspaper.museum")];
+    char stringpool_str5532[sizeof("kouzushima.tokyo.jp")];
+    char stringpool_str5533[sizeof("kiwa.mie.jp")];
+    char stringpool_str5534[sizeof("mil.sy")];
+    char stringpool_str5535[sizeof("mil.py")];
+    char stringpool_str5536[sizeof("hitachiota.ibaraki.jp")];
+    char stringpool_str5537[sizeof("brandywinevalley.museum")];
+    char stringpool_str5538[sizeof("takahashi.okayama.jp")];
+    char stringpool_str5539[sizeof("pyatigorsk.ru")];
+    char stringpool_str5540[sizeof("presse.ci")];
+    char stringpool_str5541[sizeof("on-the-web.tv")];
+    char stringpool_str5542[sizeof("dyndns-web.com")];
+    char stringpool_str5543[sizeof("tobishima.aichi.jp")];
+    char stringpool_str5544[sizeof("histoire.museum")];
+    char stringpool_str5545[sizeof("friulivenezia-giulia.it")];
+    char stringpool_str5546[sizeof("can.museum")];
+    char stringpool_str5547[sizeof("tsushima.nagasaki.jp")];
+    char stringpool_str5548[sizeof("ne.pw")];
+    char stringpool_str5549[sizeof("takarazuka.hyogo.jp")];
+    char stringpool_str5550[sizeof("co.pw")];
+    char stringpool_str5551[sizeof("go.pw")];
+    char stringpool_str5552[sizeof("ogawa.nagano.jp")];
+    char stringpool_str5553[sizeof("mil.uy")];
+    char stringpool_str5554[sizeof("ed.pw")];
+    char stringpool_str5555[sizeof("med.ly")];
+    char stringpool_str5556[sizeof("xn--ygarden-p1a.no")];
+    char stringpool_str5557[sizeof("toyama.toyama.jp")];
+    char stringpool_str5558[sizeof("tokushima.tokushima.jp")];
+    char stringpool_str5559[sizeof("mil.my")];
+    char stringpool_str5560[sizeof("pro.mv")];
+    char stringpool_str5561[sizeof("huissier-justice.fr")];
+    char stringpool_str5562[sizeof("nativeamerican.museum")];
+    char stringpool_str5563[sizeof("heritage.museum")];
+    char stringpool_str5564[sizeof("niihama.ehime.jp")];
+    char stringpool_str5565[sizeof("www.ck")];
+    char stringpool_str5566[sizeof("tsuchiura.ibaraki.jp")];
+    char stringpool_str5567[sizeof("takaharu.miyazaki.jp")];
+    char stringpool_str5568[sizeof("mil.by")];
+    char stringpool_str5569[sizeof("art.museum")];
+    char stringpool_str5570[sizeof("sekigahara.gifu.jp")];
+    char stringpool_str5571[sizeof("is-very-bad.org")];
+    char stringpool_str5572[sizeof("takayama.gunma.jp")];
+    char stringpool_str5573[sizeof("taxi.aero")];
+    char stringpool_str5574[sizeof("ddr.museum")];
+    char stringpool_str5575[sizeof("ohtawara.tochigi.jp")];
+    char stringpool_str5576[sizeof("porsgrunn.no")];
+    char stringpool_str5577[sizeof("taketa.oita.jp")];
+    char stringpool_str5578[sizeof("tarumizu.kagoshima.jp")];
+    char stringpool_str5579[sizeof("xn--gmq050i.hk")];
+    char stringpool_str5580[sizeof("presse.ml")];
+    char stringpool_str5581[sizeof("poltava.ua")];
+    char stringpool_str5582[sizeof("air.museum")];
+    char stringpool_str5583[sizeof("is-very-nice.org")];
+    char stringpool_str5584[sizeof("herokussl.com")];
+    char stringpool_str5585[sizeof("xn--io0a7i")];
+    char stringpool_str5586[sizeof("leikanger.no")];
+    char stringpool_str5587[sizeof("takayama.nagano.jp")];
+    char stringpool_str5588[sizeof("tattoo")];
+    char stringpool_str5589[sizeof("xn--givuotna-8ya.no")];
+    char stringpool_str5590[sizeof("herokuapp.com")];
+    char stringpool_str5591[sizeof("tonosho.kagawa.jp")];
+    char stringpool_str5592[sizeof("tokashiki.okinawa.jp")];
+    char stringpool_str5593[sizeof("tamaki.mie.jp")];
+    char stringpool_str5594[sizeof("wodzislaw.pl")];
+    char stringpool_str5595[sizeof("ss.it")];
+    char stringpool_str5596[sizeof("xn--ggaviika-8ya47h.no")];
+    char stringpool_str5597[sizeof("so.it")];
+    char stringpool_str5598[sizeof("bedzin.pl")];
+    char stringpool_str5599[sizeof("sp.it")];
+    char stringpool_str5600[sizeof("xn--sr-varanger-ggb.no")];
+    char stringpool_str5601[sizeof("stateofdelaware.museum")];
+    char stringpool_str5602[sizeof("xn--xhq521b")];
+    char stringpool_str5603[sizeof("chirurgiens-dentistes.fr")];
+    char stringpool_str5604[sizeof("and.museum")];
+    char stringpool_str5605[sizeof("isahaya.nagasaki.jp")];
+    char stringpool_str5606[sizeof("sa.it")];
+    char stringpool_str5607[sizeof("presse.km")];
+    char stringpool_str5608[sizeof("uchinomi.kagawa.jp")];
+    char stringpool_str5609[sizeof("naumburg.museum")];
+    char stringpool_str5610[sizeof("sr.it")];
+    char stringpool_str5611[sizeof("tadotsu.kagawa.jp")];
+    char stringpool_str5612[sizeof("stavropol.ru")];
+    char stringpool_str5613[sizeof("pittsburgh.museum")];
+    char stringpool_str5614[sizeof("myphotos.cc")];
+    char stringpool_str5615[sizeof("tsunan.niigata.jp")];
+    char stringpool_str5616[sizeof("yachiyo.chiba.jp")];
+    char stringpool_str5617[sizeof("bus.museum")];
+    char stringpool_str5618[sizeof("tokigawa.saitama.jp")];
+    char stringpool_str5619[sizeof("cadaques.museum")];
+    char stringpool_str5620[sizeof("dnepropetrovsk.ua")];
+    char stringpool_str5621[sizeof("photography")];
+    char stringpool_str5622[sizeof("xn--kvfjord-nxa.no")];
+    char stringpool_str5623[sizeof("arteducation.museum")];
+    char stringpool_str5624[sizeof("si.it")];
+    char stringpool_str5625[sizeof("xn--hnefoss-q1a.no")];
+    char stringpool_str5626[sizeof("philadelphia.museum")];
+    char stringpool_str5627[sizeof("puglia.it")];
+    char stringpool_str5628[sizeof("averoy.no")];
+    char stringpool_str5629[sizeof("tomari.hokkaido.jp")];
+    char stringpool_str5630[sizeof("mazowsze.pl")];
+    char stringpool_str5631[sizeof("takikawa.hokkaido.jp")];
+    char stringpool_str5632[sizeof("endoftheinternet.org")];
+    char stringpool_str5633[sizeof("wildlife.museum")];
+    char stringpool_str5634[sizeof("leirfjord.no")];
+    char stringpool_str5635[sizeof("kitashiobara.fukushima.jp")];
+    char stringpool_str5636[sizeof("sx.cn")];
+    char stringpool_str5637[sizeof("toki.gifu.jp")];
+    char stringpool_str5638[sizeof("togura.nagano.jp")];
+    char stringpool_str5639[sizeof("takatsuki.shiga.jp")];
+    char stringpool_str5640[sizeof("padova.it")];
+    char stringpool_str5641[sizeof("uji.kyoto.jp")];
+    char stringpool_str5642[sizeof("sv.it")];
+    char stringpool_str5643[sizeof("portal.museum")];
+    char stringpool_str5644[sizeof("tonami.toyama.jp")];
+    char stringpool_str5645[sizeof("palana.ru")];
+    char stringpool_str5646[sizeof("oamishirasato.chiba.jp")];
+    char stringpool_str5647[sizeof("xn--vestvgy-ixa6o.no")];
+    char stringpool_str5648[sizeof("maryland.museum")];
+    char stringpool_str5649[sizeof("xn--nvuotna-hwa.no")];
+    char stringpool_str5650[sizeof("nsw.au")];
+    char stringpool_str5651[sizeof("yachiyo.ibaraki.jp")];
+    char stringpool_str5652[sizeof("likescandy.com")];
+    char stringpool_str5653[sizeof("monza-brianza.it")];
+    char stringpool_str5654[sizeof("fe.it")];
+    char stringpool_str5655[sizeof("mallorca.museum")];
+    char stringpool_str5656[sizeof("nes.buskerud.no")];
+    char stringpool_str5657[sizeof("aizumisato.fukushima.jp")];
+    char stringpool_str5658[sizeof("mizuho.tokyo.jp")];
+    char stringpool_str5659[sizeof("chihayaakasaka.osaka.jp")];
+    char stringpool_str5660[sizeof("sakyo.kyoto.jp")];
+    char stringpool_str5661[sizeof("togitsu.nagasaki.jp")];
+    char stringpool_str5662[sizeof("s3-fips-us-gov-west-1.amazonaws.com")];
+    char stringpool_str5663[sizeof("law.pro")];
+    char stringpool_str5664[sizeof("s3-website-us-east-1.amazonaws.com")];
+    char stringpool_str5665[sizeof("fr.it")];
+    char stringpool_str5666[sizeof("tarama.okinawa.jp")];
+    char stringpool_str5667[sizeof("monzaebrianza.it")];
+    char stringpool_str5668[sizeof("botany.museum")];
+    char stringpool_str5669[sizeof("trapani.it")];
+    char stringpool_str5670[sizeof("ota.gunma.jp")];
+    char stringpool_str5671[sizeof("s3-website-sa-east-1.amazonaws.com")];
+    char stringpool_str5672[sizeof("ora.gunma.jp")];
+    char stringpool_str5673[sizeof("takashima.shiga.jp")];
+    char stringpool_str5674[sizeof("public.museum")];
+    char stringpool_str5675[sizeof("fm.it")];
+    char stringpool_str5676[sizeof("cmw.ru")];
+    char stringpool_str5677[sizeof("monzabrianza.it")];
+    char stringpool_str5678[sizeof("kiev.ua")];
+    char stringpool_str5679[sizeof("county.museum")];
+    char stringpool_str5680[sizeof("philadelphiaarea.museum")];
+    char stringpool_str5681[sizeof("gs.st.no")];
+    char stringpool_str5682[sizeof("gs.aa.no")];
+    char stringpool_str5683[sizeof("aizuwakamatsu.fukushima.jp")];
+    char stringpool_str5684[sizeof("yosemite.museum")];
+    char stringpool_str5685[sizeof("gs.mr.no")];
+    char stringpool_str5686[sizeof("fi.it")];
+    char stringpool_str5687[sizeof("nakamura.kochi.jp")];
+    char stringpool_str5688[sizeof("taishi.osaka.jp")];
+    char stringpool_str5689[sizeof("xn--hobl-ira.no")];
+    char stringpool_str5690[sizeof("shima.mie.jp")];
+    char stringpool_str5691[sizeof("lans.museum")];
+    char stringpool_str5692[sizeof("gs.tr.no")];
+    char stringpool_str5693[sizeof("newjersey.museum")];
+    char stringpool_str5694[sizeof("seiyo.ehime.jp")];
+    char stringpool_str5695[sizeof("pilots.museum")];
+    char stringpool_str5696[sizeof("seirou.niigata.jp")];
+    char stringpool_str5697[sizeof("xn--mot-tla.no")];
+    char stringpool_str5698[sizeof("gs.tm.no")];
+    char stringpool_str5699[sizeof("guovdageaidnu.no")];
+    char stringpool_str5700[sizeof("war.museum")];
+    char stringpool_str5701[sizeof("endofinternet.org")];
+    char stringpool_str5702[sizeof("laakesvuemie.no")];
+    char stringpool_str5703[sizeof("furudono.fukushima.jp")];
+    char stringpool_str5704[sizeof("panama.museum")];
+    char stringpool_str5705[sizeof("yokkaichi.mie.jp")];
+    char stringpool_str5706[sizeof("gs.fm.no")];
+    char stringpool_str5707[sizeof("org.co")];
+    char stringpool_str5708[sizeof("xn--io0a7i.hk")];
+    char stringpool_str5709[sizeof("paragliding.aero")];
+    char stringpool_str5710[sizeof("taishin.fukushima.jp")];
+    char stringpool_str5711[sizeof("xn--kvnangen-k0a.no")];
+    char stringpool_str5712[sizeof("dnipropetrovsk.ua")];
+    char stringpool_str5713[sizeof("gs.nt.no")];
+    char stringpool_str5714[sizeof("nakagyo.kyoto.jp")];
+    char stringpool_str5715[sizeof("photography.museum")];
+    char stringpool_str5716[sizeof("nyc.museum")];
+    char stringpool_str5717[sizeof("nasushiobara.tochigi.jp")];
+    char stringpool_str5718[sizeof("matsuno.ehime.jp")];
+    char stringpool_str5719[sizeof("africa.com")];
+    char stringpool_str5720[sizeof("meiwa.mie.jp")];
+    char stringpool_str5721[sizeof("gs.ol.no")];
+    char stringpool_str5722[sizeof("tambov.ru")];
+    char stringpool_str5723[sizeof("loyalist.museum")];
+    char stringpool_str5724[sizeof("takahata.yamagata.jp")];
+    char stringpool_str5725[sizeof("plants.museum")];
+    char stringpool_str5726[sizeof("gs.bu.no")];
+    char stringpool_str5727[sizeof("matsuyama.ehime.jp")];
+    char stringpool_str5728[sizeof("suifu.ibaraki.jp")];
+    char stringpool_str5729[sizeof("presse.fr")];
+    char stringpool_str5730[sizeof("unazuki.toyama.jp")];
+    char stringpool_str5731[sizeof("fujikawaguchiko.yamanashi.jp")];
+    char stringpool_str5732[sizeof("inatsuki.fukuoka.jp")];
+    char stringpool_str5733[sizeof("oizumi.gunma.jp")];
+    char stringpool_str5734[sizeof("gs.ah.no")];
+    char stringpool_str5735[sizeof("gs.nl.no")];
+    char stringpool_str5736[sizeof("tagami.niigata.jp")];
+    char stringpool_str5737[sizeof("s3-website-us-west-1.amazonaws.com")];
+    char stringpool_str5738[sizeof("tingvoll.no")];
+    char stringpool_str5739[sizeof("barrell-of-knowledge.info")];
+    char stringpool_str5740[sizeof("is-very-evil.org")];
+    char stringpool_str5741[sizeof("museumcenter.museum")];
+    char stringpool_str5742[sizeof("ichikai.tochigi.jp")];
+    char stringpool_str5743[sizeof("sakai.ibaraki.jp")];
+    char stringpool_str5744[sizeof("xn--hery-ira.xn--mre-og-romsdal-qqb.no")];
+    char stringpool_str5745[sizeof("sakae.chiba.jp")];
+    char stringpool_str5746[sizeof("s3-website-eu-west-1.amazonaws.com")];
+    char stringpool_str5747[sizeof("lib.ct.us")];
+    char stringpool_str5748[sizeof("eu-west-1.compute.amazonaws.com")];
+    char stringpool_str5749[sizeof("readmyblog.org")];
+    char stringpool_str5750[sizeof("gs.hm.no")];
+    char stringpool_str5751[sizeof("lib.tx.us")];
+    char stringpool_str5752[sizeof("gs.rl.no")];
+    char stringpool_str5753[sizeof("hokuryu.hokkaido.jp")];
+    char stringpool_str5754[sizeof("karasuyama.tochigi.jp")];
+    char stringpool_str5755[sizeof("wa.gov.au")];
+    char stringpool_str5756[sizeof("s3-website-ap-southeast-1.amazonaws.com")];
+    char stringpool_str5757[sizeof("sor-varanger.no")];
+    char stringpool_str5758[sizeof("sanagochi.tokushima.jp")];
+    char stringpool_str5759[sizeof("xn--bod-2na.no")];
+    char stringpool_str5760[sizeof("losangeles.museum")];
+    char stringpool_str5761[sizeof("bushey.museum")];
+    char stringpool_str5762[sizeof("tonaki.okinawa.jp")];
+    char stringpool_str5763[sizeof("bellevue.museum")];
+    char stringpool_str5764[sizeof("gs.hl.no")];
+    char stringpool_str5765[sizeof("okuizumo.shimane.jp")];
+    char stringpool_str5766[sizeof("harvestcelebration.museum")];
+    char stringpool_str5767[sizeof("otsuki.kochi.jp")];
+    char stringpool_str5768[sizeof("lib.ca.us")];
+    char stringpool_str5769[sizeof("loppa.no")];
+    char stringpool_str5770[sizeof("usa.museum")];
+    char stringpool_str5771[sizeof("yamaguchi.jp")];
+    char stringpool_str5772[sizeof("s3-website-ap-northeast-1.amazonaws.com")];
+    char stringpool_str5773[sizeof("tanabe.wakayama.jp")];
+    char stringpool_str5774[sizeof("mizumaki.fukuoka.jp")];
+    char stringpool_str5775[sizeof("muenchen.museum")];
+    char stringpool_str5776[sizeof("tjome.no")];
+    char stringpool_str5777[sizeof("tagawa.fukuoka.jp")];
+    char stringpool_str5778[sizeof("taishi.hyogo.jp")];
+    char stringpool_str5779[sizeof("trana.no")];
+    char stringpool_str5780[sizeof("antiques.museum")];
+    char stringpool_str5781[sizeof("tainai.niigata.jp")];
+    char stringpool_str5782[sizeof("targi.pl")];
+    char stringpool_str5783[sizeof("minamiise.mie.jp")];
+    char stringpool_str5784[sizeof("ranzan.saitama.jp")];
+    char stringpool_str5785[sizeof("tolga.no")];
+    char stringpool_str5786[sizeof("tysfjord.no")];
+    char stringpool_str5787[sizeof("lib.fl.us")];
+    char stringpool_str5788[sizeof("turek.pl")];
+    char stringpool_str5789[sizeof("luzern.museum")];
+    char stringpool_str5790[sizeof("sakahogi.gifu.jp")];
+    char stringpool_str5791[sizeof("terni.it")];
+    char stringpool_str5792[sizeof("trust.museum")];
+    char stringpool_str5793[sizeof("toyotomi.hokkaido.jp")];
+    char stringpool_str5794[sizeof("ulm.museum")];
+    char stringpool_str5795[sizeof("fg.it")];
+    char stringpool_str5796[sizeof("ryazan.ru")];
+    char stringpool_str5797[sizeof("lanbib.se")];
+    char stringpool_str5798[sizeof("nc.us")];
+    char stringpool_str5799[sizeof("accident-investigation.aero")];
+    char stringpool_str5800[sizeof("co.lc")];
+    char stringpool_str5801[sizeof("nyuzen.toyama.jp")];
+    char stringpool_str5802[sizeof("takatori.nara.jp")];
+    char stringpool_str5803[sizeof("utazas.hu")];
+    char stringpool_str5804[sizeof("takata.fukuoka.jp")];
+    char stringpool_str5805[sizeof("kyiv.ua")];
+    char stringpool_str5806[sizeof("od.ua")];
+    char stringpool_str5807[sizeof("uwajima.ehime.jp")];
+    char stringpool_str5808[sizeof("tomsk.ru")];
+    char stringpool_str5809[sizeof("or.us")];
+    char stringpool_str5810[sizeof("mizunami.gifu.jp")];
+    char stringpool_str5811[sizeof("scrapper-site.net")];
+    char stringpool_str5812[sizeof("ac.me")];
+    char stringpool_str5813[sizeof("ac.se")];
+    char stringpool_str5814[sizeof("kawamata.fukushima.jp")];
+    char stringpool_str5815[sizeof("ac.ae")];
+    char stringpool_str5816[sizeof("or.at")];
+    char stringpool_str5817[sizeof("kiyosu.aichi.jp")];
+    char stringpool_str5818[sizeof("bc.ca")];
+    char stringpool_str5819[sizeof("gc.ca")];
+    char stringpool_str5820[sizeof("or.mu")];
+    char stringpool_str5821[sizeof("ac.ma")];
+    char stringpool_str5822[sizeof("turen.tn")];
+    char stringpool_str5823[sizeof("or.tz")];
+    char stringpool_str5824[sizeof("ac.at")];
+    char stringpool_str5825[sizeof("oz.au")];
+    char stringpool_str5826[sizeof("monza-e-della-brianza.it")];
+    char stringpool_str5827[sizeof("ac.mu")];
+    char stringpool_str5828[sizeof("shingu.hyogo.jp")];
+    char stringpool_str5829[sizeof("or.cr")];
+    char stringpool_str5830[sizeof("ac.sz")];
+    char stringpool_str5831[sizeof("dc.us")];
+    char stringpool_str5832[sizeof("agriculture.museum")];
+    char stringpool_str5833[sizeof("ac.tz")];
+    char stringpool_str5834[sizeof("or.kr")];
+    char stringpool_str5835[sizeof("szczecin.pl")];
+    char stringpool_str5836[sizeof("ac.tj")];
+    char stringpool_str5837[sizeof("ac.cr")];
+    char stringpool_str5838[sizeof("tajiri.osaka.jp")];
+    char stringpool_str5839[sizeof("tsukui.kanagawa.jp")];
+    char stringpool_str5840[sizeof("cc.na")];
+    char stringpool_str5841[sizeof("ac.kr")];
+    char stringpool_str5842[sizeof("um.gov.pl")];
+    char stringpool_str5843[sizeof("or.ci")];
+    char stringpool_str5844[sizeof("sukumo.kochi.jp")];
+    char stringpool_str5845[sizeof("or.na")];
+    char stringpool_str5846[sizeof("boldlygoingnowhere.org")];
+    char stringpool_str5847[sizeof("on.ca")];
+    char stringpool_str5848[sizeof("ac.ci")];
+    char stringpool_str5849[sizeof("xn--45q11c")];
+    char stringpool_str5850[sizeof("ac.be")];
+    char stringpool_str5851[sizeof("mad.museum")];
+    char stringpool_str5852[sizeof("touch.museum")];
+    char stringpool_str5853[sizeof("xn--holtlen-hxa.no")];
+    char stringpool_str5854[sizeof("ac.cn")];
+    char stringpool_str5855[sizeof("tokke.no")];
+    char stringpool_str5856[sizeof("yokoshibahikari.chiba.jp")];
+    char stringpool_str5857[sizeof("kamifurano.hokkaido.jp")];
+    char stringpool_str5858[sizeof("ok.us")];
+    char stringpool_str5859[sizeof("oh.us")];
+    char stringpool_str5860[sizeof("xn--3e0b707e")];
+    char stringpool_str5861[sizeof("kawanabe.kagoshima.jp")];
+    char stringpool_str5862[sizeof("scotland.museum")];
+    char stringpool_str5863[sizeof("or.bi")];
+    char stringpool_str5864[sizeof("ol.no")];
+    char stringpool_str5865[sizeof("xn--90a3ac")];
+    char stringpool_str5866[sizeof("maritime.museum")];
+    char stringpool_str5867[sizeof("oceanographic.museum")];
+    char stringpool_str5868[sizeof("tsuno.miyazaki.jp")];
+    char stringpool_str5869[sizeof("nowaruda.pl")];
+    char stringpool_str5870[sizeof("technology")];
+    char stringpool_str5871[sizeof("ac.rs")];
+    char stringpool_str5872[sizeof("or.th")];
+    char stringpool_str5873[sizeof("piedmont.it")];
+    char stringpool_str5874[sizeof("k12.ny.us")];
+    char stringpool_str5875[sizeof("tomakomai.hokkaido.jp")];
+    char stringpool_str5876[sizeof("monmouth.museum")];
+    char stringpool_str5877[sizeof("if.ua")];
+    char stringpool_str5878[sizeof("ac.th")];
+    char stringpool_str5879[sizeof("vagsoy.no")];
+    char stringpool_str5880[sizeof("oguchi.aichi.jp")];
+    char stringpool_str5881[sizeof("sumy.ua")];
+    char stringpool_str5882[sizeof("takamori.kumamoto.jp")];
+    char stringpool_str5883[sizeof("ac.ru")];
+    char stringpool_str5884[sizeof("missoula.museum")];
+    char stringpool_str5885[sizeof("ac.gn")];
+    char stringpool_str5886[sizeof("forli-cesena.it")];
+    char stringpool_str5887[sizeof("oceanographique.museum")];
+    char stringpool_str5888[sizeof("nf.ca")];
+    char stringpool_str5889[sizeof("ac.mw")];
+    char stringpool_str5890[sizeof("kawachinagano.osaka.jp")];
+    char stringpool_str5891[sizeof("tydal.no")];
+    char stringpool_str5892[sizeof("xn--koluokta-7ya57h.no")];
+    char stringpool_str5893[sizeof("s3-us-west-2.amazonaws.com")];
+    char stringpool_str5894[sizeof("tenri.nara.jp")];
+    char stringpool_str5895[sizeof("shinyoshitomi.fukuoka.jp")];
+    char stringpool_str5896[sizeof("tc")];
+    char stringpool_str5897[sizeof("uw.gov.pl")];
+    char stringpool_str5898[sizeof("xn--45brj9c")];
+    char stringpool_str5899[sizeof("xn--s9brj9c")];
+    char stringpool_str5900[sizeof("tromso.no")];
+    char stringpool_str5901[sizeof("taketomi.okinawa.jp")];
+    char stringpool_str5902[sizeof("snz.ru")];
+    char stringpool_str5903[sizeof("servebbs.com")];
+    char stringpool_str5904[sizeof("k12.ky.us")];
+    char stringpool_str5905[sizeof("francaise.museum")];
+    char stringpool_str5906[sizeof("teramo.it")];
+    char stringpool_str5907[sizeof("tsuno.kochi.jp")];
+    char stringpool_str5908[sizeof("kawaue.gifu.jp")];
+    char stringpool_str5909[sizeof("sciences.museum")];
+    char stringpool_str5910[sizeof("takko.aomori.jp")];
+    char stringpool_str5911[sizeof("prochowice.pl")];
+    char stringpool_str5912[sizeof("gs.svalbard.no")];
+    char stringpool_str5913[sizeof("or.jp")];
+    char stringpool_str5914[sizeof("k12.wy.us")];
+    char stringpool_str5915[sizeof("xn--eveni-0qa01ga.no")];
+    char stringpool_str5916[sizeof("kihoku.ehime.jp")];
+    char stringpool_str5917[sizeof("ulan-ude.ru")];
+    char stringpool_str5918[sizeof("maizuru.kyoto.jp")];
+    char stringpool_str5919[sizeof("ac.jp")];
+    char stringpool_str5920[sizeof("yawara.ibaraki.jp")];
+    char stringpool_str5921[sizeof("s3-website-us-gov-west-1.amazonaws.com")];
+    char stringpool_str5922[sizeof("xn--lt-liac.no")];
+    char stringpool_str5923[sizeof("trento.it")];
+    char stringpool_str5924[sizeof("sande.xn--mre-og-romsdal-qqb.no")];
+    char stringpool_str5925[sizeof("press.ma")];
+    char stringpool_str5926[sizeof("est-a-la-masion.com")];
+    char stringpool_str5927[sizeof("kamisu.ibaraki.jp")];
+    char stringpool_str5928[sizeof("perso.sn")];
+    char stringpool_str5929[sizeof("florence.it")];
+    char stringpool_str5930[sizeof("szczytno.pl")];
+    char stringpool_str5931[sizeof("qc.ca")];
+    char stringpool_str5932[sizeof("tas.gov.au")];
+    char stringpool_str5933[sizeof("vestby.no")];
+    char stringpool_str5934[sizeof("us-west-1.compute.amazonaws.com")];
+    char stringpool_str5935[sizeof("us-west-2.compute.amazonaws.com")];
+    char stringpool_str5936[sizeof("umi.fukuoka.jp")];
+    char stringpool_str5937[sizeof("ac.rw")];
+    char stringpool_str5938[sizeof("turin.it")];
+    char stringpool_str5939[sizeof("lenvik.no")];
+    char stringpool_str5940[sizeof("sciencecenter.museum")];
+    char stringpool_str5941[sizeof("sciencecenters.museum")];
+    char stringpool_str5942[sizeof("z-1.compute-1.amazonaws.com")];
+    char stringpool_str5943[sizeof("z-2.compute-1.amazonaws.com")];
+    char stringpool_str5944[sizeof("sa-east-1.compute.amazonaws.com")];
+    char stringpool_str5945[sizeof("est-a-la-maison.com")];
+    char stringpool_str5946[sizeof("shingu.fukuoka.jp")];
+    char stringpool_str5947[sizeof("larvik.no")];
+    char stringpool_str5948[sizeof("xn--mxtq1m")];
+    char stringpool_str5949[sizeof("tohma.hokkaido.jp")];
+    char stringpool_str5950[sizeof("lewismiller.museum")];
+    char stringpool_str5951[sizeof("takagi.nagano.jp")];
+    char stringpool_str5952[sizeof("technology.museum")];
+    char stringpool_str5953[sizeof("xn--h2brj9c")];
+    char stringpool_str5954[sizeof("tenei.fukushima.jp")];
+    char stringpool_str5955[sizeof("qc.com")];
+    char stringpool_str5956[sizeof("parma.it")];
+    char stringpool_str5957[sizeof("prato.it")];
+    char stringpool_str5958[sizeof("xn--55qx5d.cn")];
+    char stringpool_str5959[sizeof("or.id")];
+    char stringpool_str5960[sizeof("est-le-patron.com")];
+    char stringpool_str5961[sizeof("tf")];
+    char stringpool_str5962[sizeof("telekommunikation.museum")];
+    char stringpool_str5963[sizeof("jan-mayen.no")];
+    char stringpool_str5964[sizeof("tomiya.miyagi.jp")];
+    char stringpool_str5965[sizeof("perso.ht")];
+    char stringpool_str5966[sizeof("padua.it")];
+    char stringpool_str5967[sizeof("ot.it")];
+    char stringpool_str5968[sizeof("ac.id")];
+    char stringpool_str5969[sizeof("or.it")];
+    char stringpool_str5970[sizeof("kisofukushima.nagano.jp")];
+    char stringpool_str5971[sizeof("tsuiki.fukuoka.jp")];
+    char stringpool_str5972[sizeof("perso.tn")];
+    char stringpool_str5973[sizeof("xn--c1avg")];
+    char stringpool_str5974[sizeof("xn--fl-zia.no")];
+    char stringpool_str5975[sizeof("og.ao")];
+    char stringpool_str5976[sizeof("tsuru.yamanashi.jp")];
+    char stringpool_str5977[sizeof("taira.toyama.jp")];
+    char stringpool_str5978[sizeof("xn--mgbab2bd")];
+    char stringpool_str5979[sizeof("ac.ir")];
+    char stringpool_str5980[sizeof("or.ug")];
+    char stringpool_str5981[sizeof("tendo.yamagata.jp")];
+    char stringpool_str5982[sizeof("pesaro-urbino.it")];
+    char stringpool_str5983[sizeof("xn--flor-jra.no")];
+    char stringpool_str5984[sizeof("siracusa.it")];
+    char stringpool_str5985[sizeof("press.museum")];
+    char stringpool_str5986[sizeof("osoyro.no")];
+    char stringpool_str5987[sizeof("valley.museum")];
+    char stringpool_str5988[sizeof("ac.im")];
+    char stringpool_str5989[sizeof("ac.ug")];
+    char stringpool_str5990[sizeof("onjuku.chiba.jp")];
+    char stringpool_str5991[sizeof("oarai.ibaraki.jp")];
+    char stringpool_str5992[sizeof("toyono.osaka.jp")];
+    char stringpool_str5993[sizeof("xn--czr694b")];
+    char stringpool_str5994[sizeof("tarui.gifu.jp")];
+    char stringpool_str5995[sizeof("tokai.aichi.jp")];
+    char stringpool_str5996[sizeof("ug.gov.pl")];
+    char stringpool_str5997[sizeof("otoyo.kochi.jp")];
+    char stringpool_str5998[sizeof("ac.in")];
+    char stringpool_str5999[sizeof("xn--80asehdb")];
+    char stringpool_str6000[sizeof("paleo.museum")];
+    char stringpool_str6001[sizeof("os.hedmark.no")];
+    char stringpool_str6002[sizeof("stavanger.no")];
+    char stringpool_str6003[sizeof("tokyo")];
+    char stringpool_str6004[sizeof("oshima.yamaguchi.jp")];
+    char stringpool_str6005[sizeof("tokorozawa.saitama.jp")];
+    char stringpool_str6006[sizeof("takamori.nagano.jp")];
+    char stringpool_str6007[sizeof("xn--czru2d")];
+    char stringpool_str6008[sizeof("xn--wgbh1c")];
+    char stringpool_str6009[sizeof("saskatchewan.museum")];
+    char stringpool_str6010[sizeof("turystyka.pl")];
+    char stringpool_str6011[sizeof("ichinomiya.chiba.jp")];
+    char stringpool_str6012[sizeof("yaotsu.gifu.jp")];
+    char stringpool_str6013[sizeof("saves-the-whales.com")];
+    char stringpool_str6014[sizeof("sandoy.no")];
+    char stringpool_str6015[sizeof("taiki.hokkaido.jp")];
+    char stringpool_str6016[sizeof("xn--jrpeland-54a.no")];
+    char stringpool_str6017[sizeof("okaya.nagano.jp")];
+    char stringpool_str6018[sizeof("xn--brnnysund-m8ac.no")];
+    char stringpool_str6019[sizeof("xn--fiqz9s")];
+    char stringpool_str6020[sizeof("xn--mgberp4a5d4ar")];
+    char stringpool_str6021[sizeof("shingu.wakayama.jp")];
+    char stringpool_str6022[sizeof("pubol.museum")];
+    char stringpool_str6023[sizeof("xn--snase-nra.no")];
+    char stringpool_str6024[sizeof("otaki.chiba.jp")];
+    char stringpool_str6025[sizeof("xn--fiqs8s")];
+    char stringpool_str6026[sizeof("xn--54b7fta0cc")];
+    char stringpool_str6027[sizeof("xn--mgba3a4f16a")];
+    char stringpool_str6028[sizeof("xn--mgba3a4fra")];
+    char stringpool_str6029[sizeof("omiya.saitama.jp")];
+    char stringpool_str6030[sizeof("xn--tjme-hra.no")];
+    char stringpool_str6031[sizeof("ichinomiya.aichi.jp")];
+    char stringpool_str6032[sizeof("inzai.chiba.jp")];
+    char stringpool_str6033[sizeof("tychy.pl")];
+    char stringpool_str6034[sizeof("xn--frya-hra.no")];
+    char stringpool_str6035[sizeof("spy.museum")];
+    char stringpool_str6036[sizeof("xn--fjord-lra.no")];
+    char stringpool_str6037[sizeof("xn--fiq64b")];
+    char stringpool_str6038[sizeof("xn--vegrshei-c0a.no")];
+    char stringpool_str6039[sizeof("xn--mxtq1m.hk")];
+    char stringpool_str6040[sizeof("toba.mie.jp")];
+    char stringpool_str6041[sizeof("louvre.museum")];
+    char stringpool_str6042[sizeof("tamba.hyogo.jp")];
+    char stringpool_str6043[sizeof("tsuruoka.yamagata.jp")];
+    char stringpool_str6044[sizeof("xn--skierv-uta.no")];
+    char stringpool_str6045[sizeof("buyshouses.net")];
+    char stringpool_str6046[sizeof("xn--od0alg.cn")];
+    char stringpool_str6047[sizeof("co.ve")];
+    char stringpool_str6048[sizeof("xn--brnny-wuac.no")];
+    char stringpool_str6049[sizeof("tado.mie.jp")];
+    char stringpool_str6050[sizeof("xn--rsta-fra.no")];
+    char stringpool_str6051[sizeof("taito.tokyo.jp")];
+    char stringpool_str6052[sizeof("xn--mgba3a4f16a.ir")];
+    char stringpool_str6053[sizeof("xn--mgba3a4fra.ir")];
+    char stringpool_str6054[sizeof("dyn-o-saur.com")];
+    char stringpool_str6055[sizeof("xn--jlster-bya.no")];
+    char stringpool_str6056[sizeof("torino.it")];
+    char stringpool_str6057[sizeof("oi.kanagawa.jp")];
+    char stringpool_str6058[sizeof("la.us")];
+    char stringpool_str6059[sizeof("hamatonbetsu.hokkaido.jp")];
+    char stringpool_str6060[sizeof("tgory.pl")];
+    char stringpool_str6061[sizeof("texas.museum")];
+    char stringpool_str6062[sizeof("xn--frna-woa.no")];
+    char stringpool_str6063[sizeof("lt.ua")];
+    char stringpool_str6064[sizeof("xn--slt-elab.no")];
+    char stringpool_str6065[sizeof("science-fiction.museum")];
+    char stringpool_str6066[sizeof("co.vi")];
+    char stringpool_str6067[sizeof("chiryu.aichi.jp")];
+    char stringpool_str6068[sizeof("shibuya.tokyo.jp")];
+    char stringpool_str6069[sizeof("pskov.ru")];
+    char stringpool_str6070[sizeof("xn--mgbx4cd0ab")];
+    char stringpool_str6071[sizeof("nakatombetsu.hokkaido.jp")];
+    char stringpool_str6072[sizeof("buzz")];
+    char stringpool_str6073[sizeof("isa-geek.com")];
+    char stringpool_str6074[sizeof("xn--ksnes-uua.no")];
+    char stringpool_str6075[sizeof("kawazu.shizuoka.jp")];
+    char stringpool_str6076[sizeof("so.gov.pl")];
+    char stringpool_str6077[sizeof("toyako.hokkaido.jp")];
+    char stringpool_str6078[sizeof("xn--blt-elab.no")];
+    char stringpool_str6079[sizeof("city.kobe.jp")];
+    char stringpool_str6080[sizeof("finnoy.no")];
+    char stringpool_str6081[sizeof("toyoake.aichi.jp")];
+    char stringpool_str6082[sizeof("rc.it")];
+    char stringpool_str6083[sizeof("lv.ua")];
+    char stringpool_str6084[sizeof("xn--ciqpn.hk")];
+    char stringpool_str6085[sizeof("org.sy")];
+    char stringpool_str6086[sizeof("pavia.it")];
+    char stringpool_str6087[sizeof("tsuga.tochigi.jp")];
+    char stringpool_str6088[sizeof("org.py")];
+    char stringpool_str6089[sizeof("servegame.org")];
+    char stringpool_str6090[sizeof("sr.gov.pl")];
+    char stringpool_str6091[sizeof("tamano.okayama.jp")];
+    char stringpool_str6092[sizeof("arezzo.it")];
+    char stringpool_str6093[sizeof("xn--mgb9awbf")];
+    char stringpool_str6094[sizeof("xn--o3cw4h")];
+    char stringpool_str6095[sizeof("toyokawa.aichi.jp")];
+    char stringpool_str6096[sizeof("org.uy")];
+    char stringpool_str6097[sizeof("sa.gov.au")];
+    char stringpool_str6098[sizeof("org.my")];
+    char stringpool_str6099[sizeof("xn--mlselv-iua.no")];
+    char stringpool_str6100[sizeof("og.it")];
+    char stringpool_str6101[sizeof("paris.museum")];
+    char stringpool_str6102[sizeof("ln.cn")];
+    char stringpool_str6103[sizeof("imizu.toyama.jp")];
+    char stringpool_str6104[sizeof("ichinohe.iwate.jp")];
+    char stringpool_str6105[sizeof("xn--merker-kua.no")];
+    char stringpool_str6106[sizeof("sue.fukuoka.jp")];
+    char stringpool_str6107[sizeof("thruhere.net")];
+    char stringpool_str6108[sizeof("org.ly")];
+    char stringpool_str6109[sizeof("tako.chiba.jp")];
+    char stringpool_str6110[sizeof("niiza.saitama.jp")];
+    char stringpool_str6111[sizeof("torino.museum")];
+    char stringpool_str6112[sizeof("os.hordaland.no")];
+    char stringpool_str6113[sizeof("xn--bjarky-fya.no")];
+    char stringpool_str6114[sizeof("xn--9dbhblg6di.museum")];
+    char stringpool_str6115[sizeof("lib.gu.us")];
+    char stringpool_str6116[sizeof("pf")];
+    char stringpool_str6117[sizeof("taiji.wakayama.jp")];
+    char stringpool_str6118[sizeof("org.ky")];
+    char stringpool_str6119[sizeof("tom.ru")];
+    char stringpool_str6120[sizeof("travel")];
+    char stringpool_str6121[sizeof("xn--h1aegh.museum")];
+    char stringpool_str6122[sizeof("xn--xkc2dl3a5ee0h")];
+    char stringpool_str6123[sizeof("ojiya.niigata.jp")];
+    char stringpool_str6124[sizeof("tsuyama.okayama.jp")];
+    char stringpool_str6125[sizeof("ski.museum")];
+    char stringpool_str6126[sizeof("motosu.gifu.jp")];
+    char stringpool_str6127[sizeof("xn--hmmrfeasta-s4ac.no")];
+    char stringpool_str6128[sizeof("is-a-liberal.com")];
+    char stringpool_str6129[sizeof("prd.fr")];
+    char stringpool_str6130[sizeof("chizu.tottori.jp")];
+    char stringpool_str6131[sizeof("surrey.museum")];
+    char stringpool_str6132[sizeof("xn--mgberp4a5d4a87g")];
+    char stringpool_str6133[sizeof("town")];
+    char stringpool_str6134[sizeof("tsushima.aichi.jp")];
+    char stringpool_str6135[sizeof("s3-us-west-1.amazonaws.com")];
+    char stringpool_str6136[sizeof("xn--i1b6b1a6a2e")];
+    char stringpool_str6137[sizeof("xn--oppegrd-ixa.no")];
+    char stringpool_str6138[sizeof("xn--xkc2al3hye2a")];
+    char stringpool_str6139[sizeof("xn--vre-eiker-k8a.no")];
+    char stringpool_str6140[sizeof("moriguchi.osaka.jp")];
+    char stringpool_str6141[sizeof("tree.museum")];
+    char stringpool_str6142[sizeof("tank.museum")];
+    char stringpool_str6143[sizeof("pordenone.it")];
+    char stringpool_str6144[sizeof("xn--nttery-byae.no")];
+    char stringpool_str6145[sizeof("s3-eu-west-1.amazonaws.com")];
+    char stringpool_str6146[sizeof("tarnobrzeg.pl")];
+    char stringpool_str6147[sizeof("is-a-libertarian.com")];
+    char stringpool_str6148[sizeof("time.museum")];
+    char stringpool_str6149[sizeof("xn--mgbtf8fl")];
+    char stringpool_str6150[sizeof("porsanger.no")];
+    char stringpool_str6151[sizeof("xn--ogbpf8fl")];
+    char stringpool_str6152[sizeof("takahama.aichi.jp")];
+    char stringpool_str6153[sizeof("treviso.it")];
+    char stringpool_str6154[sizeof("tas.au")];
+    char stringpool_str6155[sizeof("le.it")];
+    char stringpool_str6156[sizeof("lo.it")];
+    char stringpool_str6157[sizeof("fribourg.museum")];
+    char stringpool_str6158[sizeof("teaches-yoga.com")];
+    char stringpool_str6159[sizeof("xn--hbmer-xqa.no")];
+    char stringpool_str6160[sizeof("lt.it")];
+    char stringpool_str6161[sizeof("xn--lury-ira.no")];
+    char stringpool_str6162[sizeof("xn--sgne-gra.no")];
+    char stringpool_str6163[sizeof("xn--czrw28b.tw")];
+    char stringpool_str6164[sizeof("shimonoseki.yamaguchi.jp")];
+    char stringpool_str6165[sizeof("lu.it")];
+    char stringpool_str6166[sizeof("xn--laheadju-7ya.no")];
+    char stringpool_str6167[sizeof("shizukuishi.iwate.jp")];
+    char stringpool_str6168[sizeof("lg.ua")];
+    char stringpool_str6169[sizeof("tochio.niigata.jp")];
+    char stringpool_str6170[sizeof("environmentalconservation.museum")];
+    char stringpool_str6171[sizeof("li.it")];
+    char stringpool_str6172[sizeof("monza.it")];
+    char stringpool_str6173[sizeof("tempio-olbia.it")];
+    char stringpool_str6174[sizeof("xn--finny-yua.no")];
+    char stringpool_str6175[sizeof("ushiku.ibaraki.jp")];
+    char stringpool_str6176[sizeof("vf.no")];
+    char stringpool_str6177[sizeof("ichinoseki.iwate.jp")];
+    char stringpool_str6178[sizeof("yaizu.shizuoka.jp")];
+    char stringpool_str6179[sizeof("xn--mgbbh1a71e")];
+    char stringpool_str6180[sizeof("podlasie.pl")];
+    char stringpool_str6181[sizeof("lazio.it")];
+    char stringpool_str6182[sizeof("xn--muost-0qa.no")];
+    char stringpool_str6183[sizeof("mc.it")];
+    char stringpool_str6184[sizeof("sydney.museum")];
+    char stringpool_str6185[sizeof("tagajo.miyagi.jp")];
+    char stringpool_str6186[sizeof("pomorskie.pl")];
+    char stringpool_str6187[sizeof("xn--ystre-slidre-ujb.no")];
+    char stringpool_str6188[sizeof("tozsde.hu")];
+    char stringpool_str6189[sizeof("xn--bhcavuotna-s4a.no")];
+    char stringpool_str6190[sizeof("org.cu")];
+    char stringpool_str6191[sizeof("polkowice.pl")];
+    char stringpool_str6192[sizeof("xn--krager-gya.no")];
+    char stringpool_str6193[sizeof("sarufutsu.hokkaido.jp")];
+    char stringpool_str6194[sizeof("xn--mtta-vrjjat-k7af.no")];
+    char stringpool_str6195[sizeof("inazawa.aichi.jp")];
+    char stringpool_str6196[sizeof("xn--hgebostad-g3a.no")];
+    char stringpool_str6197[sizeof("is-a-green.com")];
+    char stringpool_str6198[sizeof("ltd.co.im")];
+    char stringpool_str6199[sizeof("tsk.ru")];
+    char stringpool_str6200[sizeof("sicily.it")];
+    char stringpool_str6201[sizeof("xn--czrs0t")];
+    char stringpool_str6202[sizeof("lib.co.us")];
+    char stringpool_str6203[sizeof("parliament.uk")];
+    char stringpool_str6204[sizeof("piemonte.it")];
+    char stringpool_str6205[sizeof("ofunato.iwate.jp")];
+    char stringpool_str6206[sizeof("city.yokohama.jp")];
+    char stringpool_str6207[sizeof("presidio.museum")];
+    char stringpool_str6208[sizeof("ono.hyogo.jp")];
+    char stringpool_str6209[sizeof("freiburg.museum")];
+    char stringpool_str6210[sizeof("isteingeek.de")];
+    char stringpool_str6211[sizeof("agency")];
+    char stringpool_str6212[sizeof("xn--srreisa-q1a.no")];
+    char stringpool_str6213[sizeof("xn--lgbbat1ad8j")];
+    char stringpool_str6214[sizeof("torahime.shiga.jp")];
+    char stringpool_str6215[sizeof("trader.aero")];
+    char stringpool_str6216[sizeof("xn--nqv7fs00ema")];
+    char stringpool_str6217[sizeof("sc.us")];
+    char stringpool_str6218[sizeof("taki.mie.jp")];
+    char stringpool_str6219[sizeof("supply")];
+    char stringpool_str6220[sizeof("is-a-cubicle-slave.com")];
+    char stringpool_str6221[sizeof("vc.it")];
+    char stringpool_str6222[sizeof("xn--bhccavuotna-k7a.no")];
+    char stringpool_str6223[sizeof("tawaramoto.nara.jp")];
+    char stringpool_str6224[sizeof("portland.museum")];
+    char stringpool_str6225[sizeof("sc.tz")];
+    char stringpool_str6226[sizeof("taiwa.miyagi.jp")];
+    char stringpool_str6227[sizeof("air-traffic-control.aero")];
+    char stringpool_str6228[sizeof("sc.kr")];
+    char stringpool_str6229[sizeof("tamakawa.fukushima.jp")];
+    char stringpool_str6230[sizeof("tachiarai.fukuoka.jp")];
+    char stringpool_str6231[sizeof("chippubetsu.hokkaido.jp")];
+    char stringpool_str6232[sizeof("katsuyama.fukui.jp")];
+    char stringpool_str6233[sizeof("lg.jp")];
+    char stringpool_str6234[sizeof("dyndns-remote.com")];
+    char stringpool_str6235[sizeof("pasadena.museum")];
+    char stringpool_str6236[sizeof("sc.cn")];
+    char stringpool_str6237[sizeof("production.aero")];
+    char stringpool_str6238[sizeof("takahama.fukui.jp")];
+    char stringpool_str6239[sizeof("tomobe.ibaraki.jp")];
+    char stringpool_str6240[sizeof("tosashimizu.kochi.jp")];
+    char stringpool_str6241[sizeof("utazu.kagawa.jp")];
+    char stringpool_str6242[sizeof("family.museum")];
+    char stringpool_str6243[sizeof("toyota.aichi.jp")];
+    char stringpool_str6244[sizeof("toyone.aichi.jp")];
+    char stringpool_str6245[sizeof("ac.pa")];
+    char stringpool_str6246[sizeof("ac.pr")];
+    char stringpool_str6247[sizeof("takino.hyogo.jp")];
+    char stringpool_str6248[sizeof("sasaguri.fukuoka.jp")];
+    char stringpool_str6249[sizeof("shiriuchi.hokkaido.jp")];
+    char stringpool_str6250[sizeof("graz.museum")];
+    char stringpool_str6251[sizeof("operaunite.com")];
+    char stringpool_str6252[sizeof("xn--davvenjrga-y4a.no")];
+    char stringpool_str6253[sizeof("sf.no")];
+    char stringpool_str6254[sizeof("xn--mgbc0a9azcg")];
+    char stringpool_str6255[sizeof("githubusercontent.com")];
+    char stringpool_str6256[sizeof("katsuura.chiba.jp")];
+    char stringpool_str6257[sizeof("ichikawa.chiba.jp")];
+    char stringpool_str6258[sizeof("ichihara.chiba.jp")];
+    char stringpool_str6259[sizeof("geometre-expert.fr")];
+    char stringpool_str6260[sizeof("sor-fron.no")];
+    char stringpool_str6261[sizeof("tahara.aichi.jp")];
+    char stringpool_str6262[sizeof("otsuchi.iwate.jp")];
+    char stringpool_str6263[sizeof("takanabe.miyazaki.jp")];
+    char stringpool_str6264[sizeof("ogawa.ibaraki.jp")];
+    char stringpool_str6265[sizeof("tochigi.tochigi.jp")];
+    char stringpool_str6266[sizeof("or.pw")];
+    char stringpool_str6267[sizeof("priv.pl")];
+    char stringpool_str6268[sizeof("nt.edu.au")];
+    char stringpool_str6269[sizeof("xn--berlevg-jxa.no")];
+    char stringpool_str6270[sizeof("tokamachi.niigata.jp")];
+    char stringpool_str6271[sizeof("priv.no")];
+    char stringpool_str6272[sizeof("hofu.yamaguchi.jp")];
+    char stringpool_str6273[sizeof("togakushi.nagano.jp")];
+    char stringpool_str6274[sizeof("xn--io0a7i.cn")];
+    char stringpool_str6275[sizeof("ono.fukui.jp")];
+    char stringpool_str6276[sizeof("historyofscience.museum")];
+    char stringpool_str6277[sizeof("poznan.pl")];
+    char stringpool_str6278[sizeof("toride.ibaraki.jp")];
+    char stringpool_str6279[sizeof("sc.ug")];
+    char stringpool_str6280[sizeof("shizuoka.jp")];
+    char stringpool_str6281[sizeof("tamamura.gunma.jp")];
+    char stringpool_str6282[sizeof("s3.amazonaws.com")];
+    char stringpool_str6283[sizeof("travel.tt")];
+    char stringpool_str6284[sizeof("xn--kvitsy-fya.no")];
+    char stringpool_str6285[sizeof("yuza.yamagata.jp")];
+    char stringpool_str6286[sizeof("aizubange.fukushima.jp")];
+    char stringpool_str6287[sizeof("xn--skjervy-v1a.no")];
+    char stringpool_str6288[sizeof("xn--rennesy-v1a.no")];
+    char stringpool_str6289[sizeof("lebtimnetz.de")];
+    char stringpool_str6290[sizeof("takayama.gifu.jp")];
+    char stringpool_str6291[sizeof("likes-pie.com")];
+    char stringpool_str6292[sizeof("xn--gildeskl-g0a.no")];
+    char stringpool_str6293[sizeof("xn--vler-qoa.xn--stfold-9xa.no")];
+    char stringpool_str6294[sizeof("corvette.museum")];
+    char stringpool_str6295[sizeof("travel.pl")];
+    char stringpool_str6296[sizeof("fc.it")];
+    char stringpool_str6297[sizeof("priv.me")];
+    char stringpool_str6298[sizeof("leitungsen.de")];
+    char stringpool_str6299[sizeof("palace.museum")];
+    char stringpool_str6300[sizeof("xn--langevg-jxa.no")];
+    char stringpool_str6301[sizeof("oto.fukuoka.jp")];
+    char stringpool_str6302[sizeof("priv.at")];
+    char stringpool_str6303[sizeof("ohi.fukui.jp")];
+    char stringpool_str6304[sizeof("xn--loabt-0qa.no")];
+    char stringpool_str6305[sizeof("xn--aurskog-hland-jnb.no")];
+    char stringpool_str6306[sizeof("wa.edu.au")];
+    char stringpool_str6307[sizeof("uchiko.ehime.jp")];
+    char stringpool_str6308[sizeof("takanezawa.tochigi.jp")];
+    char stringpool_str6309[sizeof("towada.aomori.jp")];
+    char stringpool_str6310[sizeof("tabuse.yamaguchi.jp")];
+    char stringpool_str6311[sizeof("ono.fukushima.jp")];
+    char stringpool_str6312[sizeof("tozawa.yamagata.jp")];
+    char stringpool_str6313[sizeof("gs.sf.no")];
+    char stringpool_str6314[sizeof("scrapping.cc")];
+    char stringpool_str6315[sizeof("gs.of.no")];
+    char stringpool_str6316[sizeof("jfk.museum")];
+    char stringpool_str6317[sizeof("kujukuri.chiba.jp")];
+    char stringpool_str6318[sizeof("te.ua")];
+    char stringpool_str6319[sizeof("toyota.yamaguchi.jp")];
+    char stringpool_str6320[sizeof("tokuyama.yamaguchi.jp")];
+    char stringpool_str6321[sizeof("for-better.biz")];
+    char stringpool_str6322[sizeof("for-the.biz")];
+    char stringpool_str6323[sizeof("sande.vestfold.no")];
+    char stringpool_str6324[sizeof("tm.se")];
+    char stringpool_str6325[sizeof("xn--porsgu-sta26f.no")];
+    char stringpool_str6326[sizeof("hagi.yamaguchi.jp")];
+    char stringpool_str6327[sizeof("tysvar.no")];
+    char stringpool_str6328[sizeof("tn.us")];
+    char stringpool_str6329[sizeof("komvux.se")];
+    char stringpool_str6330[sizeof("xn--moreke-jua.no")];
+    char stringpool_str6331[sizeof("ftpaccess.cc")];
+    char stringpool_str6332[sizeof("tr.no")];
+    char stringpool_str6333[sizeof("tm.fr")];
+    char stringpool_str6334[sizeof("tv.sd")];
+    char stringpool_str6335[sizeof("oki.fukuoka.jp")];
+    char stringpool_str6336[sizeof("shizuoka.shizuoka.jp")];
+    char stringpool_str6337[sizeof("tm.no")];
+    char stringpool_str6338[sizeof("topology.museum")];
+    char stringpool_str6339[sizeof("tm.km")];
+    char stringpool_str6340[sizeof("paroch.k12.ma.us")];
+    char stringpool_str6341[sizeof("tv.tz")];
+    char stringpool_str6342[sizeof("tj.cn")];
+    char stringpool_str6343[sizeof("tomika.gifu.jp")];
+    char stringpool_str6344[sizeof("cc.me.us")];
+    char stringpool_str6345[sizeof("cc.ms.us")];
+    char stringpool_str6346[sizeof("cc.de.us")];
+    char stringpool_str6347[sizeof("cc.md.us")];
+    char stringpool_str6348[sizeof("cc.sd.us")];
+    char stringpool_str6349[sizeof("cc.mo.us")];
+    char stringpool_str6350[sizeof("cc.as.us")];
+    char stringpool_str6351[sizeof("xn--node")];
+    char stringpool_str6352[sizeof("cc.ma.us")];
+    char stringpool_str6353[sizeof("cc.la.us")];
+    char stringpool_str6354[sizeof("cc.mt.us")];
+    char stringpool_str6355[sizeof("cc.ut.us")];
+    char stringpool_str6356[sizeof("cc.co.us")];
+    char stringpool_str6357[sizeof("cc.ar.us")];
+    char stringpool_str6358[sizeof("cc.or.us")];
+    char stringpool_str6359[sizeof("tamayu.shimane.jp")];
+    char stringpool_str6360[sizeof("xn--mosjen-eya.no")];
+    char stringpool_str6361[sizeof("cc.ks.us")];
+    char stringpool_str6362[sizeof("cc.az.us")];
+    char stringpool_str6363[sizeof("luxury")];
+    char stringpool_str6364[sizeof("tm.ro")];
+    char stringpool_str6365[sizeof("parachuting.aero")];
+    char stringpool_str6366[sizeof("tv.na")];
+    char stringpool_str6367[sizeof("cc.ca.us")];
+    char stringpool_str6368[sizeof("tv.bo")];
+    char stringpool_str6369[sizeof("sch.ly")];
+    char stringpool_str6370[sizeof("cc.ct.us")];
+    char stringpool_str6371[sizeof("cc.mi.us")];
+    char stringpool_str6372[sizeof("tv.br")];
+    char stringpool_str6373[sizeof("cc.ne.us")];
+    char stringpool_str6374[sizeof("cc.nd.us")];
+    char stringpool_str6375[sizeof("cc.mn.us")];
+    char stringpool_str6376[sizeof("sor-aurdal.no")];
+    char stringpool_str6377[sizeof("cc.tn.us")];
+    char stringpool_str6378[sizeof("pippu.hokkaido.jp")];
+    char stringpool_str6379[sizeof("cc.al.us")];
+    char stringpool_str6380[sizeof("nrw.museum")];
+    char stringpool_str6381[sizeof("cc.nj.us")];
+    char stringpool_str6382[sizeof("cc.nm.us")];
+    char stringpool_str6383[sizeof("cc.ga.us")];
+    char stringpool_str6384[sizeof("tm.hu")];
+    char stringpool_str6385[sizeof("cc.fl.us")];
+    char stringpool_str6386[sizeof("cc.gu.us")];
+    char stringpool_str6387[sizeof("tw.cn")];
+    char stringpool_str6388[sizeof("cc.ak.us")];
+    char stringpool_str6389[sizeof("cc.ok.us")];
+    char stringpool_str6390[sizeof("cc.oh.us")];
+    char stringpool_str6391[sizeof("cc.nv.us")];
+    char stringpool_str6392[sizeof("cc.ri.us")];
+    char stringpool_str6393[sizeof("ap-northeast-1.compute.amazonaws.com")];
+    char stringpool_str6394[sizeof("cc.nh.us")];
+    char stringpool_str6395[sizeof("tokyo.jp")];
+    char stringpool_str6396[sizeof("priv.hu")];
+    char stringpool_str6397[sizeof("mazury.pl")];
+    char stringpool_str6398[sizeof("lib.ny.us")];
+    char stringpool_str6399[sizeof("cc.hi.us")];
+    char stringpool_str6400[sizeof("tx.us")];
+    char stringpool_str6401[sizeof("takasu.hokkaido.jp")];
+    char stringpool_str6402[sizeof("te.it")];
+    char stringpool_str6403[sizeof("ts.it")];
+    char stringpool_str6404[sizeof("to.it")];
+    char stringpool_str6405[sizeof("tp.it")];
+    char stringpool_str6406[sizeof("ta.it")];
+    char stringpool_str6407[sizeof("tr.it")];
+    char stringpool_str6408[sizeof("cc.ky.us")];
+    char stringpool_str6409[sizeof("tt.im")];
+    char stringpool_str6410[sizeof("lib.ky.us")];
+    char stringpool_str6411[sizeof("of.no")];
+    char stringpool_str6412[sizeof("tm.mg")];
+    char stringpool_str6413[sizeof("xn--q9jyb4c")];
+    char stringpool_str6414[sizeof("cc.ny.us")];
+    char stringpool_str6415[sizeof("tn.it")];
+    char stringpool_str6416[sizeof("lib.wy.us")];
+    char stringpool_str6417[sizeof("pp.se")];
+    char stringpool_str6418[sizeof("gs.va.no")];
+    char stringpool_str6419[sizeof("tv.it")];
+    char stringpool_str6420[sizeof("pa.us")];
+    char stringpool_str6421[sizeof("pp.ua")];
+    char stringpool_str6422[sizeof("pr.us")];
+    char stringpool_str6423[sizeof("taiki.mie.jp")];
+    char stringpool_str6424[sizeof("tv.im")];
+    char stringpool_str6425[sizeof("tomigusuku.okinawa.jp")];
+    char stringpool_str6426[sizeof("cc.id.us")];
+    char stringpool_str6427[sizeof("pp.az")];
+    char stringpool_str6428[sizeof("cc.tx.us")];
+    char stringpool_str6429[sizeof("pe.ca")];
+    char stringpool_str6430[sizeof("cc.ia.us")];
+    char stringpool_str6431[sizeof("pe.kr")];
+    char stringpool_str6432[sizeof("pb.ao")];
+    char stringpool_str6433[sizeof("przeworsk.pl")];
+    char stringpool_str6434[sizeof("cc.in.us")];
+    char stringpool_str6435[sizeof("properties")];
+    char stringpool_str6436[sizeof("pl.ua")];
+    char stringpool_str6437[sizeof("monzaedellabrianza.it")];
+    char stringpool_str6438[sizeof("cc.il.us")];
+    char stringpool_str6439[sizeof("tajimi.gifu.jp")];
+    char stringpool_str6440[sizeof("xn--cg4bki")];
+    char stringpool_str6441[sizeof("powiat.pl")];
+    char stringpool_str6442[sizeof("pp.ru")];
+    char stringpool_str6443[sizeof("press.aero")];
+    char stringpool_str6444[sizeof("mulhouse.museum")];
+    char stringpool_str6445[sizeof("kawaguchi.saitama.jp")];
+    char stringpool_str6446[sizeof("oe.yamagata.jp")];
+    char stringpool_str6447[sizeof("lviv.ua")];
+    char stringpool_str6448[sizeof("tokai.ibaraki.jp")];
+    char stringpool_str6449[sizeof("svizzera.museum")];
+    char stringpool_str6450[sizeof("of.by")];
+    char stringpool_str6451[sizeof("pilot.aero")];
+    char stringpool_str6452[sizeof("press.se")];
+    char stringpool_str6453[sizeof("parti.se")];
+    char stringpool_str6454[sizeof("xn--dyry-ira.no")];
+    char stringpool_str6455[sizeof("xn--fiq228c5hs")];
+    char stringpool_str6456[sizeof("pesarourbino.it")];
+    char stringpool_str6457[sizeof("sa.edu.au")];
+    char stringpool_str6458[sizeof("xn--aroport-bya.ci")];
+    char stringpool_str6459[sizeof("pe.it")];
+    char stringpool_str6460[sizeof("pd.it")];
+    char stringpool_str6461[sizeof("po.it")];
+    char stringpool_str6462[sizeof("cc.wa.us")];
+    char stringpool_str6463[sizeof("pa.it")];
+    char stringpool_str6464[sizeof("pt.it")];
+    char stringpool_str6465[sizeof("pr.it")];
+    char stringpool_str6466[sizeof("pu.it")];
+    char stringpool_str6467[sizeof("pz.it")];
+    char stringpool_str6468[sizeof("xn--hylandet-54a.no")];
+    char stringpool_str6469[sizeof("cc.wi.us")];
+    char stringpool_str6470[sizeof("pi.it")];
+    char stringpool_str6471[sizeof("xn--fzc2c9e2c")];
+    char stringpool_str6472[sizeof("pn.it")];
+    char stringpool_str6473[sizeof("sellsyourhome.org")];
+    char stringpool_str6474[sizeof("cc.wv.us")];
+    char stringpool_str6475[sizeof("ac.vn")];
+    char stringpool_str6476[sizeof("pv.it")];
+    char stringpool_str6477[sizeof("tohnosho.chiba.jp")];
+    char stringpool_str6478[sizeof("us-gov-west-1.compute.amazonaws.com")];
+    char stringpool_str6479[sizeof("safety.aero")];
+    char stringpool_str6480[sizeof("xn--gecrj9c")];
+    char stringpool_str6481[sizeof("for-some.biz")];
+    char stringpool_str6482[sizeof("plc.co.im")];
+    char stringpool_str6483[sizeof("cc.wy.us")];
+    char stringpool_str6484[sizeof("for-more.biz")];
+    char stringpool_str6485[sizeof("lomza.pl")];
+    char stringpool_str6486[sizeof("xn--tysvr-vra.no")];
+    char stringpool_str6487[sizeof("tateyama.chiba.jp")];
+    char stringpool_str6488[sizeof("xn--gls-elac.no")];
+    char stringpool_str6489[sizeof("xn--ryrvik-bya.no")];
+    char stringpool_str6490[sizeof("xn--sndre-land-0cb.no")];
+    char stringpool_str6491[sizeof("xn--mgbqly7cvafr")];
+    char stringpool_str6492[sizeof("tempioolbia.it")];
+    char stringpool_str6493[sizeof("xn--ostery-fya.no")];
+    char stringpool_str6494[sizeof("lc.it")];
+    char stringpool_str6495[sizeof("tokoname.aichi.jp")];
+    char stringpool_str6496[sizeof("encyclopedic.museum")];
+    char stringpool_str6497[sizeof("pg.it")];
+    char stringpool_str6498[sizeof("lowicz.pl")];
+    char stringpool_str6499[sizeof("traeumtgerade.de")];
+    char stringpool_str6500[sizeof("xn--nmesjevuemie-tcba.no")];
+    char stringpool_str6501[sizeof("tomisato.chiba.jp")];
+    char stringpool_str6502[sizeof("pisz.pl")];
+    char stringpool_str6503[sizeof("podzone.net")];
+    char stringpool_str6504[sizeof("tsukiyono.gunma.jp")];
+    char stringpool_str6505[sizeof("takinoue.hokkaido.jp")];
+    char stringpool_str6506[sizeof("plc.ly")];
+    char stringpool_str6507[sizeof("tm.pl")];
+    char stringpool_str6508[sizeof("cc.pa.us")];
+    char stringpool_str6509[sizeof("cc.pr.us")];
+    char stringpool_str6510[sizeof("okazaki.aichi.jp")];
+    char stringpool_str6511[sizeof("tranoy.no")];
+    char stringpool_str6512[sizeof("xn--indery-fya.no")];
+    char stringpool_str6513[sizeof("outsystemscloud.com")];
+    char stringpool_str6514[sizeof("tranby.no")];
+    char stringpool_str6515[sizeof("xn--frde-gra.no")];
+    char stringpool_str6516[sizeof("ptz.ru")];
+    char stringpool_str6517[sizeof("passenger-association.aero")];
+    char stringpool_str6518[sizeof("principe.st")];
+    char stringpool_str6519[sizeof("posts-and-telecommunications.museum")];
+    char stringpool_str6520[sizeof("office-on-the.net")];
+    char stringpool_str6521[sizeof("xn--hyanger-q1a.no")];
+    char stringpool_str6522[sizeof("elasticbeanstalk.com")];
+    char stringpool_str6523[sizeof("podzone.org")];
+    char stringpool_str6524[sizeof("pharmacy.museum")];
+    char stringpool_str6525[sizeof("town.museum")];
+    char stringpool_str6526[sizeof("pharmaciens.km")];
+    char stringpool_str6527[sizeof("xn--tnsberg-q1a.no")];
+    char stringpool_str6528[sizeof("dyndns-office.com")];
+    char stringpool_str6529[sizeof("po.gov.pl")];
+    char stringpool_str6530[sizeof("pa.gov.pl")];
+    char stringpool_str6531[sizeof("grozny.ru")];
+    char stringpool_str6532[sizeof("tm.mc")];
+    char stringpool_str6533[sizeof("pacific.museum")];
+    char stringpool_str6534[sizeof("pulawy.pl")];
+    char stringpool_str6535[sizeof("cc.sc.us")];
+    char stringpool_str6536[sizeof("cc.dc.us")];
+    char stringpool_str6537[sizeof("linz.museum")];
+    char stringpool_str6538[sizeof("xn--rhkkervju-01af.no")];
+    char stringpool_str6539[sizeof("ap-southeast-2.compute.amazonaws.com")];
+    char stringpool_str6540[sizeof("tanagura.fukushima.jp")];
+    char stringpool_str6541[sizeof("cc.nc.us")];
+    char stringpool_str6542[sizeof("est-mon-blogueur.com")];
+    char stringpool_str6543[sizeof("for-our.info")];
+    char stringpool_str6544[sizeof("gs.vf.no")];
+    char stringpool_str6545[sizeof("xn--fpcrj9c3d")];
+    char stringpool_str6546[sizeof("cc.va.us")];
+    char stringpool_str6547[sizeof("cc.vt.us")];
+    char stringpool_str6548[sizeof("cc.vi.us")];
+    char stringpool_str6549[sizeof("penza.ru")];
+    char stringpool_str6550[sizeof("pc.it")];
+    char stringpool_str6551[sizeof("ap-southeast-1.compute.amazonaws.com")];
+    char stringpool_str6552[sizeof("xn--stre-toten-zcb.no")];
+    char stringpool_str6553[sizeof("plaza.museum")];
+    char stringpool_str6554[sizeof("xn--ryken-vua.no")];
+    char stringpool_str6555[sizeof("salzburg.museum")];
+    char stringpool_str6556[sizeof("tcm.museum")];
+    char stringpool_str6557[sizeof("olsztyn.pl")];
+    char stringpool_str6558[sizeof("air-surveillance.aero")];
+    char stringpool_str6559[sizeof("xn--mgbqly7c0a67fbc")];
+    char stringpool_str6560[sizeof("pc.pl")];
+    char stringpool_str6561[sizeof("pharmacien.fr")];
+    char stringpool_str6562[sizeof("xn--clchc0ea0b2g2a9gcd")];
+    char stringpool_str6563[sizeof("xn--comunicaes-v6a2o.museum")];
+    char stringpool_str6564[sizeof("isa-hockeynut.com")];
+    char stringpool_str6565[sizeof("xn--correios-e-telecomunicaes-ghc29a.museum")];
   };
 static const struct stringpool_t stringpool_contents =
   {
     "be",
     "ke",
     "ge",
+    "bs",
     "ie",
+    "gs",
+    "ne",
+    "is",
     "cd",
     "bd",
     "gd",
-    "ne",
-    "id",
     "net",
+    "id",
     "co",
     "bo",
     "com",
-    "gov",
     "io",
-    "bs",
-    "gs",
+    "gov",
     "no",
-    "bj",
-    "is",
-    "kp",
-    "gp",
     "net.sl",
     "net.st",
     "net.ec",
-    "np",
+    "kp",
+    "gp",
+    "net.sc",
     "com.sl",
+    "np",
     "com.st",
     "com.ec",
-    "gov.sx",
     "gov.sl",
-    "ee",
     "gov.st",
     "gov.ec",
+    "com.sc",
+    "gov.sc",
+    "ee",
+    "gsm.pl",
+    "es",
     "net.pl",
     "net.pk",
     "net.pt",
     "net.pr",
+    "je",
     "com.pl",
     "com.pk",
     "com.pt",
@@ -6802,854 +6850,361 @@
     "gov.pk",
     "gov.pt",
     "com.pr",
-    "net.sc",
-    "gsm.pl",
-    "gov.pr",
-    "nom.pl",
-    "gda.pl",
-    "je",
-    "gop",
-    "com.sc",
     "gent",
-    "es",
-    "gov.sc",
+    "nom.pl",
+    "gov.pr",
+    "gop",
+    "gob.ec",
+    "gda.pl",
     "center",
     "jo",
-    "gob.ec",
-    "com.es",
     "com.sn",
+    "jp",
+    "com.es",
     "gob.pk",
     "nom.es",
     "net.pn",
-    "jp",
+    "est.pr",
     "gop.pk",
     "gov.pn",
     "net.ps",
-    "est.pr",
+    "condos",
     "edu",
-    "com.ps",
     "jobs",
+    "com.ps",
     "gov.ps",
     "gob.es",
-    "condos",
+    "edu.sl",
+    "edu.st",
+    "edu.ec",
+    "edu.sc",
     "ca",
     "ba",
     "ga",
     "bar",
-    "cat",
     "na",
-    "edu.sl",
-    "edu.st",
-    "edu.ec",
-    "net.al",
-    "net.ar",
-    "com.al",
+    "cat",
     "edu.pl",
     "edu.pk",
     "edu.pt",
-    "gov.al",
-    "za",
-    "com.ar",
     "edu.pr",
-    "new",
-    "com.aw",
-    "edu.sc",
-    "cab",
-    "net.ac",
-    "ls",
-    "com.ac",
-    "gov.ac",
-    "bt",
     "cards",
+    "bt",
+    "net.al",
     "gt",
-    "eat",
     "it",
-    "edu.es",
+    "net.ar",
+    "net.ac",
+    "com.al",
+    "cab",
+    "gov.al",
     "edu.sn",
+    "com.ar",
+    "com.ac",
+    "com.aw",
+    "gov.ac",
+    "edu.es",
+    "net.tt",
     "cr",
     "br",
     "kr",
     "gr",
+    "net.sd",
+    "net.tw",
+    "eat",
+    "ir",
+    "com.tt",
+    "nr",
+    "gov.tl",
+    "idv.tw",
+    "gov.tt",
+    "com.sd",
+    "com.tw",
+    "edu.pn",
+    "gov.sd",
+    "gov.tw",
+    "kred",
+    "et",
     "gob.ar",
     "net.an",
-    "ir",
-    "net.tt",
-    "nr",
-    "com.an",
-    "edu.pn",
-    "idv.tw",
-    "com.tt",
-    "net.tw",
-    "gov.tl",
-    "gov.tt",
-    "com.tw",
-    "gov.tw",
-    "net.rw",
     "edu.ps",
-    "net.sd",
-    "gov.as",
-    "com.rw",
-    "gov.rw",
-    "com.sd",
-    "zone",
-    "et",
-    "gov.sd",
+    "com.an",
     "net.sb",
+    "net.rw",
     "com.sb",
+    "com.rw",
+    "gov.sb",
+    "gov.rw",
+    "net.tn",
+    "gov.as",
+    "za",
     "er",
     "cu",
-    "gov.sb",
-    "kred",
-    "gu",
-    "net.tn",
-    "guru",
-    "nu",
     "com.tn",
+    "gu",
     "gov.tn",
-    "edu.al",
-    "edu.ar",
-    "london",
-    "com.ee",
-    "gov.ee",
-    "com.de",
+    "nu",
+    "guru",
     "cz",
     "bz",
     "kz",
     "ae",
-    "edu.ac",
-    "ad",
+    "as",
     "nz",
+    "ad",
+    "edu.al",
+    "ao",
+    "com.ee",
+    "edu.ar",
+    "edu.ac",
+    "gov.ee",
+    "com.de",
+    "zone",
     "gov.rs",
-    "net.je",
-    "la",
     "eu",
     "cpa.pro",
-    "ao",
-    "net.pe",
-    "as",
-    "com.pe",
-    "edu.an",
-    "net.au",
     "edu.tt",
-    "nom.pe",
-    "com.au",
-    "land",
-    "gov.au",
+    "net.pe",
+    "edu.sd",
     "edu.tw",
+    "com.pe",
+    "bj",
+    "aero",
+    "nom.pe",
+    "edu.an",
     "jet.uk",
-    "om",
+    "name",
+    "nsn.us",
+    "edu.sb",
+    "edu.rw",
+    "career",
     "cm",
     "bm",
     "km",
     "gm",
-    "edu.rw",
     "im",
-    "name",
-    "aero",
-    "career",
-    "edu.sd",
-    "lt",
     "gob.pe",
-    "net.mx",
+    "isa.us",
+    "nom.ad",
     "net.ml",
     "net.mk",
     "net.mt",
-    "edu.sb",
-    "nsn.us",
-    "gouv.km",
-    "com.mx",
+    "net.mw",
     "com.ml",
     "com.mk",
     "com.mt",
-    "net.mw",
     "gov.ml",
     "gov.mk",
-    "zm",
-    "lr",
-    "nom.ad",
-    "gov.mr",
     "com.mw",
-    "gov.mw",
-    "nrw",
-    "isa.us",
-    "net.ru",
-    "edu.ee",
-    "com.ru",
-    "gov.ru",
-    "bar.pro",
     "c.la",
-    "nov.ru",
-    "gob.mx",
+    "gov.mr",
+    "edu.ee",
+    "gov.mw",
     "nat.tn",
     "edu.rs",
-    "jm",
+    "bar.pro",
     "krd",
-    "gov.mn",
+    "jm",
+    "codes",
+    "edu.pe",
+    "gal",
     "net.ae",
-    "lu",
+    "gov.mn",
+    "net.ms",
+    "gallery",
+    "at",
+    "gov.ae",
+    "com.ms",
+    "gov.ms",
+    "zm",
     "ci",
     "bi",
-    "biz",
     "ki",
     "gi",
+    "net.tj",
     "kim",
-    "edu.pe",
-    "gov.ae",
-    "net.ms",
+    "ar",
     "ni",
-    "com.ms",
-    "edu.au",
-    "gov.ms",
-    "gal",
+    "com.tj",
+    "gov.tj",
+    "edu.ml",
+    "edu.mk",
+    "edu.mt",
+    "atm.pl",
+    "edu.mw",
+    "com.re",
+    "name.na",
+    "net.ir",
+    "nom.re",
+    "gov.it",
+    "gov.ir",
+    "komforb.se",
+    "art.pl",
+    "au",
+    "bb",
+    "gb",
+    "gen.in",
+    "berlin",
+    "kaufen",
+    "edu.mn",
+    "estate",
+    "az",
+    "net.in",
+    "art.sn",
+    "nel.uk",
+    "edu.ms",
+    "gov.in",
+    "net.bt",
+    "net.is",
+    "net.br",
+    "arpa",
+    "com.bt",
+    "com.is",
+    "gov.bt",
+    "com.br",
+    "gov.is",
+    "nara.jp",
+    "gov.br",
+    "de",
+    "ceo",
+    "nom.br",
+    "not.br",
+    "jur.pro",
+    "edu.tj",
+    "do",
+    "boo",
+    "autos",
+    "cool",
+    "bayern",
+    "edu.it",
+    "net.dm",
+    "kobe.jp",
+    "net.je",
+    "com.dm",
+    "net.om",
+    "net.bs",
+    "gov.dm",
+    "am",
+    "com.om",
+    "com.bs",
+    "consulado.st",
+    "gov.om",
+    "gov.bs",
+    "bodo.no",
+    "jor.br",
+    "cam.it",
+    "net.me",
     "cn",
     "bn",
     "kn",
     "gn",
-    "net.ir",
     "in",
-    "gallery",
-    "codes",
-    "lapy.pl",
-    "gov.it",
-    "int",
-    "gov.ir",
-    "krym.ua",
-    "biz.pl",
-    "biz.pk",
-    "net.nr",
-    "org",
-    "biz.pr",
-    "com.nr",
-    "edu.mx",
-    "edu.ml",
-    "edu.mk",
-    "edu.mt",
-    "gov.nr",
-    "name.na",
-    "edu.mw",
-    "gen.in",
-    "berlin",
-    "beer",
-    "horse",
-    "at",
-    "com.re",
-    "net.in",
-    "org.sl",
-    "int.pt",
-    "org.st",
-    "org.ec",
-    "name.ng",
-    "nom.re",
-    "gov.in",
-    "edu.ru",
-    "ar",
-    "nsw.au",
-    "org.pl",
-    "net.tj",
-    "org.pk",
-    "org.pt",
-    "net.is",
-    "org.pr",
-    "com.tj",
-    "gov.tj",
-    "com.is",
-    "org.sc",
-    "gov.is",
-    "gos.pk",
-    "edu.mn",
-    "net.mu",
-    "bb",
-    "gb",
-    "kaufen",
-    "com.mu",
-    "best",
-    "atm.pl",
-    "gov.mu",
-    "org.es",
-    "edu.ms",
-    "net.bt",
-    "org.sn",
-    "art.pl",
-    "net.br",
-    "com.bt",
-    "au",
-    "gov.bt",
-    "com.br",
-    "house",
-    "edu.it",
-    "gov.br",
-    "org.pn",
-    "nom.br",
-    "b.br",
-    "not.br",
-    "nel.uk",
-    "biz.at",
-    "cam.it",
-    "ck",
-    "estate",
-    "org.ps",
-    "edu.nr",
-    "nara.jp",
-    "odda.no",
-    "jur.pro",
-    "art.sn",
-    "li",
-    "az",
-    "jar.ru",
-    "arpa",
-    "com.kp",
-    "gov.kp",
-    "int.ar",
-    "edu.in",
-    "bayern",
-    "bodo.no",
-    "lom.it",
-    "net.bs",
-    "org.al",
-    "org.ar",
-    "com.bs",
-    "net.me",
-    "edu.tj",
-    "gov.bs",
-    "edu.is",
-    "biz.tt",
-    "jor.br",
-    "gouv.rw",
-    "komforb.se",
-    "consulado.st",
     "gov.me",
-    "asn.au",
-    "bid",
-    "autos",
-    "am",
-    "net.id",
-    "org.ac",
-    "casa",
-    "limo",
-    "how",
-    "net.kn",
-    "kobe.jp",
-    "gov.kn",
-    "ht",
-    "int.tt",
-    "cremona.it",
-    "edu.bt",
-    "here",
     "esp.br",
+    "edu.in",
+    "int",
+    "gives",
+    "edu.bt",
+    "edu.is",
     "edu.br",
+    "net.id",
+    "net.nr",
+    "isla.pr",
+    "bid",
+    "com.nr",
+    "gov.nr",
+    "name.pr",
+    "int.pt",
+    "game.tw",
+    "auto.pl",
+    "gift",
+    "edu.dm",
+    "gq",
+    "iq",
+    "coffee",
+    "edu.om",
+    "edu.bs",
+    "ntr.br",
+    "day",
+    "ai",
+    "edu.me",
+    "ip6.arpa",
+    "net.sa",
+    "brussels",
+    "etne.no",
+    "com.sa",
+    "net.bb",
+    "gov.sa",
+    "gov.ie",
+    "com.bb",
+    "gov.bb",
+    "net.tm",
+    "net.pa",
+    "com.tm",
+    "edu.nr",
+    "gov.tm",
+    "com.pa",
+    "nom.tm",
+    "name.tj",
+    "nom.pa",
+    "arts.ro",
+    "arts.co",
+    "grue.no",
     "cl",
     "gl",
-    "org.an",
-    "hr",
     "il",
-    "org.tt",
     "nl",
-    "int.rw",
-    "org.tw",
-    "haus",
+    "name.ng",
+    "cremona.it",
+    "gob.pa",
+    "int.ar",
+    "adm.br",
+    "adv.br",
     "net.lk",
-    "name.pr",
+    "cv",
+    "bv",
     "net.lr",
+    "net.lc",
     "com.lk",
-    "lb",
+    "dz",
+    "int.tt",
     "gov.lk",
     "gov.lt",
     "com.lr",
-    "org.sd",
-    "gift",
-    "gov.lr",
-    "isla.pr",
-    "info",
-    "oslo.no",
-    "homes",
-    "auto.pl",
-    "org.sb",
-    "net.lc",
-    "edu.kp",
-    "name.eg",
-    "ing",
-    "game.tw",
-    "gov.ie",
     "com.lc",
+    "gov.lr",
     "gov.lc",
     "glass",
-    "hu",
-    "org.tn",
-    "ai",
-    "o.se",
-    "c.se",
-    "b.se",
-    "k.se",
-    "law.pro",
-    "g.se",
-    "edu.bs",
-    "i.se",
-    "n.se",
-    "org.ee",
-    "edu.me",
-    "gq",
-    "laz.it",
-    "iq",
-    "lk",
-    "an",
-    "onl",
-    "coffee",
-    "ntr.br",
-    "x.se",
-    "ip6.arpa",
-    "org.rs",
-    "z.se",
-    "net.bb",
-    "org.se",
-    "edu.kn",
-    "org.je",
-    "com.bb",
-    "gov.bb",
-    "name.tj",
-    "org.pe",
-    "eus",
-    "etne.no",
-    "e.se",
-    "info.la",
-    "net.sa",
-    "org.au",
-    "lund.no",
-    "biz.mw",
-    "com.sa",
-    "gov.sa",
-    "brussels",
-    "net.pa",
-    "info.pl",
-    "lebesby.no",
-    "edu.lk",
-    "com.pa",
-    "arts.ro",
-    "edu.lr",
-    "hm",
-    "bir.ru",
-    "nom.pa",
-    "grue.no",
-    "int.mw",
-    "org.mx",
-    "org.ml",
-    "org.mk",
-    "org.mt",
-    "arts.co",
-    "edu.lc",
-    "org.mw",
-    "emr.it",
-    "info.na",
-    "int.ru",
-    "ch",
-    "bh",
-    "kh",
-    "gh",
-    "gob.pa",
-    "adm.br",
-    "adv.br",
-    "org.ru",
-    "nesseby.no",
-    "idv.hk",
-    "net.hk",
-    "net.ht",
-    "com.hk",
-    "com.ht",
-    "kiev.ua",
-    "gov.hk",
-    "oita.jp",
-    "com.hr",
-    "org.mn",
-    "edu.bb",
-    "cal.it",
-    "caa.aero",
-    "arna.no",
-    "org.ae",
-    "biz.nr",
-    "gouv.bj",
-    "cmw.ru",
-    "org.ms",
-    "link",
-    "name.qa",
-    "l.se",
-    "edu.sa",
-    "net.lb",
-    "lib.ee",
-    "com.lb",
-    "gov.lb",
-    "net.hn",
-    "org.ir",
-    "net.iq",
-    "edu.pa",
-    "hn",
-    "com.hn",
-    "com.iq",
-    "ind.tn",
-    "gov.iq",
-    "cy",
-    "by",
-    "ky",
-    "gy",
-    "biz.tj",
-    "org.nr",
-    "imb.br",
-    "name.jo",
-    "net.dz",
-    "grp.lk",
-    "xyz",
-    "blue",
-    "com.dz",
-    "cheap",
-    "gov.dz",
-    "asso.km",
-    "gob.hn",
-    "org.in",
-    "int.tj",
-    "int.is",
-    "al",
-    "nkz.ru",
-    "leg.br",
-    "cim.br",
-    "org.tj",
-    "edu.hk",
-    "edu.ht",
-    "org.is",
-    "aid.pl",
-    "gok.pk",
+    "country",
     "norddal.no",
-    "org.mu",
-    "info.bb",
-    "emp.br",
-    "info.ro",
-    "gjesdal.no",
-    "life",
-    "cnt.br",
-    "irc.pl",
-    "inf.mk",
-    "lel.br",
-    "org.bt",
-    "info.co",
-    "edu.lb",
-    "org.br",
-    "cw",
-    "bw",
-    "org.bw",
-    "kw",
-    "gw",
-    "eng.pro",
-    "net.ua",
-    "nara.nara.jp",
-    "edu.hn",
-    "edu.iq",
-    "gouv.ci",
-    "gifu.jp",
-    "com.ua",
-    "a.se",
-    "gov.ua",
-    "net.eg",
-    "aq",
-    "info.pr",
-    "com.eg",
-    "bas.it",
-    "hk",
-    "zw",
-    "gov.eg",
-    "aip.ee",
-    "edu.dz",
-    "art.br",
-    "qa",
-    "org.kp",
-    "net.sg",
-    "biz.id",
-    "com.sg",
-    "gov.sg",
-    "arts.nf",
-    "net.az",
-    "org.bs",
-    "com.az",
-    "gov.az",
-    "net.ai",
-    "org.me",
-    "ly",
-    "info.nr",
-    "com.ai",
-    "aure.no",
-    "bmd.br",
-    "net.ws",
-    "net.ma",
-    "org.kn",
-    "com.ws",
-    "gov.ws",
-    "gov.ma",
-    "int.lk",
-    "edu.ua",
-    "gouv.sn",
-    "i.ph",
-    "org.lk",
-    "gjerstad.no",
-    "ind.in",
-    "edu.eg",
-    "org.lr",
-    "gausdal.no",
-    "org.lc",
-    "edu.sg",
-    "cbg.ru",
-    "belluno.it",
-    "biz.bb",
-    "net.ag",
-    "com.ag",
-    "edu.az",
-    "net.uz",
-    "kms.ru",
-    "inf.br",
-    "nom.ag",
-    "h.se",
-    "com.uz",
-    "ind.br",
-    "notteroy.no",
-    "com.na",
-    "ens.tn",
-    "org.ls",
-    "edu.ws",
-    "org.bb",
-    "education",
-    "khv.ru",
-    "jobs.tt",
-    "info.pk",
-    "educator.aero",
-    "org.sa",
-    "ltd.lk",
-    "cng.br",
-    "org.pa",
-    "info.nf",
-    "abr.it",
-    "intl.tn",
-    "conf.lv",
-    "its.me",
-    "jolster.no",
-    "build",
-    "neustar",
-    "lig.it",
-    "net.ba",
-    "aremark.no",
-    "com.ba",
-    "camera",
-    "bd.se",
-    "gov.ba",
-    "com.ug",
-    "eng.br",
-    "co.me",
-    "guide",
-    "aw",
-    "hole.no",
-    "org.hk",
-    "org.ht",
-    "nome.pt",
-    "ne.us",
-    "id.us",
-    "nd.us",
-    "co.ls",
-    "co.us",
-    "nsk.ru",
-    "eun.eg",
-    "jus.br",
-    "ks.us",
-    "kommune.no",
-    "ouda.nara.jp",
-    "co.ae",
-    "alta.no",
-    "nj.us",
-    "org.lb",
-    "art.ht",
-    "co.ao",
-    "org.hn",
-    "org.iq",
-    "caserta.it",
-    "ink",
-    "asia",
-    "etnedal.no",
-    "nic.tr",
-    "com.mg",
-    "joyo.kyoto.jp",
-    "gov.mg",
-    "org.dz",
-    "nom.mg",
-    "ed.ao",
-    "co.tj",
-    "go.tj",
-    "edu.ba",
-    "nls.uk",
-    "org.sz",
-    "us",
-    "lier.no",
-    "net.la",
-    "art.dz",
-    "com.la",
-    "kamo.kyoto.jp",
-    "od.ua",
-    "gov.la",
-    "enterprises",
-    "ws",
-    "name.tt",
-    "aero.tt",
-    "nic.uk",
-    "info.ki",
-    "co.ma",
-    "co.ua",
-    "ca.us",
-    "ks.ua",
-    "ga.us",
-    "net.bz",
-    "ia.us",
-    "leka.no",
-    "kazo.saitama.jp",
-    "com.bz",
-    "asso.bj",
-    "livorno.it",
-    "gov.bz",
-    "co.ve",
-    "com.bi",
-    "org.ua",
-    "org.hu",
-    "club",
-    "net.ng",
-    "black",
-    "biz.az",
-    "com.ng",
-    "gov.ng",
-    "org.eg",
-    "edu.mg",
-    "zp.ua",
-    "elverum.no",
-    "web.pk",
-    "ing.pa",
-    "net.qa",
-    "zlg.br",
-    "ninja",
-    "com.qa",
-    "co.st",
-    "net.kz",
-    "ct.us",
-    "gov.qa",
-    "gose.nara.jp",
-    "com.kz",
-    "int.az",
-    "org.sg",
-    "gov.kz",
-    "holdings",
-    "info.tn",
-    "net.ki",
-    "or.us",
-    "is-an-actor.com",
-    "nysa.pl",
-    "com.ki",
-    "gov.ki",
-    "lacaixa",
-    "org.az",
-    "etc.br",
-    "ua",
-    "co.at",
-    "lillesand.no",
-    "org.ai",
-    "edu.la",
-    "it.ao",
-    "bike",
-    "org.ws",
-    "org.ma",
-    "co.mu",
-    "community",
-    "naustdal.no",
-    "co.tt",
-    "edu.bz",
-    "gu.us",
-    "edu.bi",
-    "leasing.aero",
-    "id.au",
-    "edu.ng",
-    "co.uz",
-    "asso.ci",
-    "co.sz",
-    "askvoll.no",
-    "edu.qa",
-    "net.kg",
-    "hemsedal.no",
-    "com.kg",
-    "la.us",
-    "edu.kz",
-    "gov.kg",
-    "kustanai.ru",
-    "wed",
-    "as.us",
-    "edu.ki",
-    "bryansk.ru",
-    "org.ag",
-    "cr.ua",
-    "kr.ua",
-    "org.uz",
-    "hamburg",
-    "zt.ua",
-    "nittedal.no",
-    "co.ca",
-    "ne.tz",
-    "nic.in",
-    "nm.us",
-    "org.na",
-    "kizu.kyoto.jp",
-    "nyc",
-    "co.tz",
-    "ns.ca",
-    "go.tz",
-    "nic.tj",
-    "elk.pl",
-    "cupcake.is",
-    "uz",
-    "co.om",
-    "kita.kyoto.jp",
-    "cv",
-    "co.tm",
-    "bv",
-    "co.cr",
-    "go.cr",
-    "edu.kg",
-    "or.at",
-    "work",
-    "notodden.no",
-    "oyer.no",
-    "embaixada.st",
-    "org.ba",
-    "org.ug",
-    "asso.re",
-    "or.mu",
-    "gs.oslo.no",
-    "works",
-    "ed.cr",
-    "in.us",
+    "edu.sa",
+    "arna.no",
     "net.vc",
-    "waw.pl",
-    "nhk",
+    "edu.bb",
     "com.vc",
-    "qsl.br",
+    "int.rw",
     "gov.vc",
-    "udm.ru",
-    "km.ua",
-    "kautokeino.no",
-    "kawasaki.jp",
+    "info",
+    "edu.tm",
+    "emr.it",
+    "edu.pa",
+    "caa.aero",
+    "dj",
     "com.pf",
-    "wme",
+    "cal.it",
+    "ing",
     "net.vn",
-    "nt.au",
-    "co.rs",
-    "kanmaki.nara.jp",
-    "info.tt",
-    "lt.ua",
+    "an",
+    "name.jo",
     "com.vn",
     "gov.vn",
-    "ne.kr",
-    "eti.br",
-    "co.kr",
-    "go.kr",
-    "ar.us",
-    "istmein.de",
-    "o.bg",
+    "dm",
+    "dad",
+    "imb.br",
+    "dance",
+    "edu.lk",
+    "edu.lr",
+    "edu.lc",
     "c.bg",
     "b.bg",
     "k.bg",
@@ -7659,5625 +7214,6158 @@
     "2.bg",
     "i.bg",
     "9.bg",
+    "n.bg",
     "8.bg",
     "7.bg",
-    "ando.nara.jp",
-    "n.bg",
-    "org.mg",
     "5.bg",
     "4.bg",
     "3.bg",
+    "dabur",
     "1.bg",
-    "nt.ca",
-    "x.bg",
-    "is-leet.com",
-    "club.tw",
-    "grimstad.no",
-    "z.bg",
-    "or.tz",
-    "es.kr",
-    "xn--p1ai",
-    "int.la",
+    "irc.pl",
     "edu.vc",
-    "cn.ua",
-    "e.bg",
-    "oz.au",
-    "in.ua",
-    "net.af",
-    "lv",
-    "org.la",
-    "nagasaki.jp",
-    "com.af",
-    "ok.us",
+    "info.la",
+    "aid.pl",
+    "aq",
+    "info.pl",
+    "emp.br",
+    "net.ua",
     "edu.pf",
-    "gov.af",
-    "co.vi",
-    "j.bg",
+    "name.my",
+    "e.bg",
+    "com.ua",
+    "net.af",
+    "gov.ua",
+    "cim.br",
     "edu.vn",
-    "az.us",
-    "nu.ca",
-    "catania.it",
-    "or.cr",
-    "org.bz",
-    "org.bi",
-    "biz.ki",
-    "org.ng",
-    "co.ci",
-    "go.ci",
-    "asso.gp",
-    "gd.cn",
-    "web.tj",
-    "org.qa",
-    "is-a-doctor.com",
-    "org.kz",
-    "quebec",
-    "uk",
-    "gs.cn",
-    "lipetsk.ru",
-    "bj.cn",
-    "nt.ro",
-    "kotoura.tottori.jp",
-    "org.ki",
-    "ed.ci",
-    "karasjok.no",
-    "il.us",
-    "otsuka",
-    "nordre-land.no",
-    "xj.cn",
-    "l.bg",
-    "edu.af",
-    "zj.cn",
+    "com.af",
+    "name.eg",
+    "j.bg",
+    "int.mw",
+    "gov.af",
+    "gifu.jp",
+    "art.br",
+    "info.na",
+    "net.lb",
+    "bio",
+    "gausdal.no",
+    "com.lb",
+    "gov.lb",
+    "blue",
+    "x.bg",
+    "aip.ee",
+    "z.bg",
+    "aure.no",
+    "net.im",
+    "com.im",
+    "grp.lk",
+    "al",
+    "ind.tn",
+    "net.ma",
+    "arts.nf",
+    "bmd.br",
+    "bzh",
+    "gov.ma",
+    "int.tj",
+    "edu.ua",
     "net.ve",
-    "or.kr",
+    "jolster.no",
+    "educator.aero",
+    "edu.af",
+    "net.bm",
     "com.ve",
     "gov.ve",
-    "ck.ua",
-    "builders",
-    "bzh",
-    "enebakk.no",
-    "js.cn",
-    "navuotna.no",
-    "nissedal.no",
-    "in-addr.arpa",
-    "novosibirsk.ru",
-    "balestrand.no",
-    "berg.no",
-    "nyc.mn",
-    "badaddja.no",
-    "org.kg",
+    "com.bm",
+    "gov.bm",
+    "edu.lb",
+    "gran.no",
+    "gjesdal.no",
+    "info.bb",
+    "info.ro",
+    "info.co",
+    "beer",
     "careers",
+    "inf.mk",
+    "cnt.br",
+    "berg.no",
+    "int.is",
+    "eng.pro",
+    "horse",
     "kvam.no",
-    "como.it",
-    "web.id",
-    "on.ca",
-    "imperia.it",
-    "qld.au",
+    "etnedal.no",
     "edu.ve",
-    "is-a-player.com",
-    "u.se",
     "a.bg",
-    "web.lk",
-    "nagoya",
-    "or.ci",
-    "ye",
-    "koge.tottori.jp",
-    "w.se",
-    "bielawa.pl",
-    "oh.us",
-    "nh.us",
-    "college",
-    "nb.ca",
-    "nesodden.no",
-    "co.cl",
-    "international",
-    "net.nf",
-    "ak.us",
-    "co.ba",
-    "koto.tokyo.jp",
-    "com.nf",
-    "hi.us",
-    "biz.vn",
-    "ingatlan.hu",
-    "umb.it",
-    "buryatia.ru",
-    "co.th",
-    "go.th",
-    "id.ly",
-    "org.vc",
-    "in.rs",
-    "co.je",
-    "ky.us",
-    "int.vn",
-    "org.pf",
-    "ny.us",
-    "gz.cn",
-    "isernia.it",
-    "org.vn",
-    "ostroda.pl",
-    "ne.jp",
-    "xz.cn",
-    "co.jp",
-    "irkutsk.ru",
-    "go.jp",
-    "kh.ua",
-    "hjelmeland.no",
-    "al.us",
-    "katsuragi.nara.jp",
-    "hs.kr",
-    "gov.bf",
-    "lezajsk.pl",
-    "h.bg",
-    "nm.cn",
-    "ed.jp",
-    "uy",
-    "urn.arpa",
-    "gouv.fr",
-    "engerdal.no",
-    "nl.ca",
-    "hjartdal.no",
-    "co.mw",
-    "catanzaro.it",
-    "ivgu.no",
-    "andasuolo.no",
-    "yt",
+    "info.pr",
+    "edu.bm",
+    "gos.pk",
+    "best",
+    "neustar",
+    "dnp",
+    "camera",
+    "ck",
+    "notteroy.no",
+    "house",
+    "net.ba",
+    "info.nr",
+    "com.ba",
+    "abr.it",
+    "gov.ba",
+    "b.br",
+    "ch",
+    "bh",
+    "kh",
+    "gh",
+    "com.kp",
+    "gov.kp",
+    "belluno.it",
+    "net.hk",
+    "net.ht",
+    "idv.hk",
+    "com.hk",
+    "com.ht",
+    "gov.hk",
+    "com.hr",
+    "net.kn",
     "kragero.no",
-    "ostrowwlkp.pl",
-    "org.af",
-    "liguria.it",
-    "kyiv.ua",
-    "karelia.ru",
-    "wtc",
-    "getmyip.com",
-    "ostre-toten.no",
-    "ve",
-    "newmexico.museum",
-    "cosenza.it",
-    "or.th",
-    "he.cn",
+    "aremark.no",
+    "ht",
+    "nara.nara.jp",
+    "gov.kn",
+    "here",
+    "casa",
+    "education",
+    "inf.br",
+    "net.hn",
+    "hr",
+    "cheap",
+    "com.hn",
+    "ind.in",
+    "homes",
+    "edu.ba",
+    "nic.tr",
+    "com.na",
+    "haus",
+    "ind.br",
+    "gov.bf",
+    "edu.kp",
+    "gob.hn",
+    "hu",
+    "edu.hk",
+    "edu.ht",
+    "c.se",
+    "b.se",
+    "k.se",
+    "g.se",
+    "i.se",
+    "cng.br",
+    "n.se",
+    "edu.kn",
+    "ivgu.no",
+    "nesseby.no",
+    "net.qa",
+    "nic.uk",
+    "alta.no",
+    "int.lk",
+    "com.qa",
+    "intl.tn",
+    "gov.qa",
+    "eus",
+    "edu.hn",
+    "e.se",
+    "info.nf",
+    "etc.br",
+    "eng.br",
+    "net.nf",
+    "com.nf",
+    "hm",
+    "d.bg",
+    "x.se",
+    "z.se",
+    "info.tz",
+    "int.vn",
+    "net.la",
+    "com.la",
+    "gov.la",
+    "ato.br",
+    "edu.qa",
+    "bio.br",
+    "club",
+    "amot.no",
+    "cw",
+    "bw",
+    "kw",
+    "gw",
+    "info.pk",
+    "name.qa",
+    "asso.km",
+    "naustdal.no",
+    "net.eg",
+    "net.sg",
+    "hiv",
+    "com.eg",
+    "name.mk",
+    "gov.eg",
+    "com.sg",
+    "nic.tj",
+    "gov.sg",
+    "edu.la",
+    "net.iq",
+    "ing.pa",
+    "com.iq",
+    "gov.iq",
+    "community",
+    "dagestan.ru",
+    "info.tn",
+    "kommune.no",
+    "net.ws",
+    "joyo.kyoto.jp",
+    "com.ws",
+    "a.se",
+    "zlg.br",
+    "events",
+    "gov.ws",
+    "zw",
+    "cooking",
+    "nic.in",
+    "is-a-doctor.com",
+    "name.az",
+    "is-an-actor.com",
+    "edu.eg",
+    "edu.sg",
+    "i.ph",
+    "kamo.kyoto.jp",
+    "edu.iq",
+    "nittedal.no",
+    "info.ki",
+    "net.ag",
+    "art.ht",
+    "com.ag",
+    "nom.ag",
+    "bas.it",
+    "edu.ws",
+    "hn",
+    "belgorod.ru",
+    "jobs.tt",
+    "dk",
+    "com.km",
+    "arendal.no",
+    "gov.km",
+    "enterprises",
+    "is-a-player.com",
+    "nom.km",
+    "bryansk.ru",
+    "aw",
+    "guide",
+    "build",
+    "budapest",
+    "com.ug",
+    "nome.pt",
+    "asia",
+    "eun.eg",
+    "club.tw",
+    "edu.km",
+    "its.me",
+    "domains",
+    "hole.no",
+    "com.mg",
+    "gov.mg",
+    "nom.mg",
+    "d.se",
+    "aero.tt",
+    "jus.br",
+    "kanmaki.nara.jp",
+    "name.tt",
+    "kita.kyoto.jp",
+    "ens.tn",
+    "edu.mg",
+    "in-addr.arpa",
+    "erotika.hu",
+    "navuotna.no",
+    "erotica.hu",
+    "globo",
+    "h.bg",
+    "abo.pa",
+    "gjemnes.no",
+    "badaddja.no",
+    "asso.bj",
+    "karasjok.no",
+    "kotoura.tottori.jp",
+    "int.la",
+    "drammen.no",
+    "bielawa.pl",
+    "ye",
+    "gjerstad.no",
+    "balestrand.no",
+    "nord-fron.no",
+    "caserta.it",
+    "nls.uk",
+    "info.az",
+    "degree",
+    "enebakk.no",
+    "net.ng",
+    "notodden.no",
+    "com.ng",
+    "gov.ng",
+    "bergamo.it",
+    "black",
+    "cupcake.is",
+    "ando.nara.jp",
+    "is-leet.com",
+    "asso.dz",
+    "koge.tottori.jp",
+    "cy",
+    "by",
+    "ky",
+    "gy",
+    "eti.br",
+    "yt",
+    "edu.ng",
+    "nordre-land.no",
+    "asso.ci",
+    "hemsedal.no",
+    "gok.pk",
+    "hk",
+    "doomdns.com",
+    "caravan",
+    "zhytomyr.ua",
+    "holdings",
+    "kustanai.ru",
+    "gose.nara.jp",
+    "grimstad.no",
+    "nagasaki.jp",
+    "net.ai",
+    "com.ai",
+    "gallery.museum",
+    "engerdal.no",
+    "info.tt",
+    "builders",
+    "h.se",
+    "net.dz",
+    "com.dz",
+    "gov.dz",
+    "koto.tokyo.jp",
+    "ws",
+    "barcelona.museum",
+    "audnedaln.no",
+    "hamburg",
+    "is-gone.com",
+    "donetsk.ua",
+    "asso.fr",
+    "brussel.museum",
+    "blogspot.se",
+    "web.pk",
+    "blogspot.de",
+    "czeladz.pl",
+    "edu.dz",
+    "ingatlan.hu",
+    "qa",
+    "crotone.it",
+    "conf.lv",
+    "assn.lk",
+    "net.az",
+    "kautokeino.no",
+    "com.az",
+    "gov.az",
+    "blog.br",
+    "jevnaker.no",
+    "nordreisa.no",
+    "broadcast.museum",
+    "artdeco.museum",
+    "wed",
+    "kicks-ass.net",
+    "cagliari.it",
+    "net.uz",
+    "edu.az",
+    "education.museum",
+    "com.uz",
+    "international",
+    "nissedal.no",
+    "karasjohka.no",
+    "blogspot.td",
+    "asso.re",
+    "net.kg",
+    "com.kg",
+    "blogspot.re",
+    "gov.kg",
+    "blogspot.pt",
+    "jefferson.museum",
+    "com.bi",
+    "blogspot.ro",
+    "work",
+    "cash",
+    "guitars",
+    "works",
     "birkenes.no",
     "kirkenes.no",
-    "xn--nnx388a",
-    "holtalen.no",
-    "or.jp",
-    "gr.jp",
-    "voto",
-    "izumisano.osaka.jp",
-    "org.ve",
-    "ab.ca",
-    "co.bi",
-    "nordreisa.no",
-    "kameoka.kyoto.jp",
-    "xn--l1acc",
-    "entertainment.aero",
+    "broke-it.net",
     "kitchen",
-    "goto.nagasaki.jp",
-    "city.sapporo.jp",
-    "va",
-    "karasjohka.no",
-    "info.at",
-    "cc",
-    "bl.uk",
-    "kamo.niigata.jp",
-    "nc",
-    "enna.it",
-    "ad.jp",
-    "ha.cn",
-    "nedre-eiker.no",
-    "ln.cn",
-    "net.cw",
-    "gov.cx",
-    "gov.cl",
-    "ozu.kumamoto.jp",
-    "com.cw",
-    "ibaraki.jp",
-    "co.hu",
-    "ec",
-    "kita.tokyo.jp",
-    "notaires.km",
-    "gob.cl",
-    "abruzzo.it",
-    "hino.tottori.jp",
-    "net.cn",
-    "kids.us",
-    "vote",
-    "com.cn",
-    "gov.cn",
-    "watch",
-    "astrakhan.ru",
-    "cagliari.it",
-    "barcelona.museum",
-    "unsa.ba",
-    "vu",
-    "in.th",
-    "gjemnes.no",
-    "koto.shiga.jp",
-    "net.vi",
-    "or.bi",
-    "com.vi",
-    "edu.cw",
-    "jl.cn",
-    "cq.cn",
-    "kicks-ass.net",
-    "archi",
-    "carraramassa.it",
-    "lc",
-    "gildeskal.no",
-    "city.sendai.jp",
-    "vegas",
-    "xn--j1amh",
-    "education.museum",
-    "edu.cn",
-    "net.cu",
-    "carrara-massa.it",
-    "journal.aero",
-    "com.cu",
-    "gov.cu",
-    "za.org",
-    "nordkapp.no",
-    "q.bg",
-    "gov.cd",
-    "is-a-techie.com",
-    "lorenskog.no",
-    "gamo.shiga.jp",
-    "gets-it.net",
-    "namsskogan.no",
-    "co.rw",
-    "itayanagi.aomori.jp",
-    "kodaira.tokyo.jp",
-    "budapest",
-    "nagaokakyo.kyoto.jp",
-    "chukotka.ru",
-    "vi",
-    "iz.hr",
-    "ven.it",
-    "vn",
-    "edu.cu",
-    "ac",
-    "hi.cn",
-    "vda.it",
-    "gorlice.pl",
-    "belgorod.ru",
-    "hn.cn",
-    "ae.org",
-    "y.se",
-    "wa.us",
-    "am.br",
-    "kuroishi.aomori.jp",
-    "asso.fr",
-    "ut.us",
-    "ise.mie.jp",
-    "grajewo.pl",
-    "kartuzy.pl",
-    "beskidy.pl",
-    "xn--55qx5d",
-    "vet.br",
-    "homebuilt.aero",
-    "lucania.it",
-    "xn--d1acj3b",
-    "charter.aero",
-    "hb.cn",
-    "airline.aero",
-    "aerobatic.aero",
-    "xn--kpry57d",
-    "bjerkreim.no",
-    "vrn.ru",
+    "wtf",
     "calabria.it",
-    "chuvashia.ru",
-    "hk.cn",
-    "holmestrand.no",
-    "org.cw",
-    "id.lv",
-    "vega.no",
-    "nv.us",
-    "osakasayama.osaka.jp",
-    "kicks-ass.org",
-    "vodka",
-    "hino.tokyo.jp",
-    "org.cn",
-    "co.bw",
-    "community.museum",
-    "catering",
-    "gv.ao",
-    "arakawa.tokyo.jp",
-    "ohda.shimane.jp",
-    "hl.cn",
-    "chuo.tokyo.jp",
-    "ah.cn",
-    "oygarden.no",
-    "actor",
-    "kashiba.nara.jp",
+    "wme",
+    "ninja",
+    "better-than.tv",
+    "edu.kg",
+    "ink",
+    "bike",
     "aircraft.aero",
-    "aca.pro",
-    "gliding.aero",
-    "ina.nagano.jp",
-    "uz.ua",
-    "org.vi",
-    "ecn.br",
-    "levanger.no",
-    "nord-fron.no",
+    "edu.bi",
+    "benevento.it",
+    "kita.tokyo.jp",
+    "blogspot.jp",
+    "norfolk.museum",
+    "art.dz",
+    "nyc",
+    "is-a-techie.com",
+    "dnsdojo.net",
+    "izhevsk.ru",
+    "gildeskal.no",
+    "web.tj",
+    "istmein.de",
+    "net.bz",
+    "com.bz",
+    "amusement.aero",
+    "gov.bz",
+    "dni.us",
+    "y.bg",
+    "re",
+    "ren",
+    "rs",
+    "judaica.museum",
+    "blogspot.ie",
+    "community.museum",
+    "ro",
+    "entertainment.aero",
+    "asso.gp",
+    "college",
+    "net.vi",
+    "com.vi",
+    "blogspot.be",
+    "edu.bz",
+    "elk.pl",
+    "blogspot.mr",
+    "archi",
+    "ass.km",
+    "dnsdojo.com",
+    "info.at",
+    "bokn.no",
+    "chukotka.ru",
+    "web.id",
+    "blogdns.net",
+    "hiphop",
+    "airline.aero",
+    "gorlice.pl",
     "cx",
-    "wa.au",
-    "act.au",
-    "cv.ua",
-    "kv.ua",
-    "wi.us",
-    "vaga.no",
-    "jaworzno.pl",
-    "kalmykia.ru",
-    "itabashi.tokyo.jp",
-    "org.cu",
-    "ikaruga.nara.jp",
-    "eidsberg.no",
+    "blogspot.it",
+    "aero.mv",
+    "grosseto.it",
+    "blogspot.no",
+    "name.mv",
+    "red",
     "net.sh",
     "com.sh",
     "gov.sh",
+    "int.az",
+    "qsl.br",
+    "klodzko.pl",
     "net.ph",
-    "club.aero",
-    "xn--mgb2ddes",
-    "city.nagoya.jp",
-    "is-gone.com",
-    "voss.no",
     "com.ph",
     "gov.ph",
-    "noda.iwate.jp",
-    "xn--4gbrim",
-    "oji.nara.jp",
-    "u.bg",
-    "koga.ibaraki.jp",
-    "guitars",
-    "hokksund.no",
-    "otsu.shiga.jp",
-    "gv.at",
-    "narviika.no",
-    "w.bg",
+    "isleofman.museum",
+    "ru",
+    "nesodden.no",
+    "nordkapp.no",
     "arakawa.saitama.jp",
-    "kota.aichi.jp",
-    "kamoenai.hokkaido.jp",
-    "lavangen.no",
-    "kvalsund.no",
-    "kisosaki.mie.jp",
-    "nalchik.ru",
-    "wang",
-    "konyvelo.hu",
-    "akrehamn.no",
-    "edu.ph",
-    "lviv.ua",
-    "hara.nagano.jp",
-    "lv.ua",
-    "astronomy.museum",
-    "villas",
-    "uri.arpa",
-    "kurotaki.nara.jp",
-    "kawakami.nara.jp",
-    "ostroleka.pl",
-    "xn--slat-5na.no",
-    "iida.nagano.jp",
-    "kuzbass.ru",
-    "jessheim.no",
-    "inf.cu",
-    "net.th",
-    "homeunix.net",
-    "gallery.museum",
-    "ina.ibaraki.jp",
-    "caravan",
-    "vercelli.it",
-    "kitaakita.akita.jp",
-    "nes.akershus.no",
-    "udmurtia.ru",
-    "alessandria.it",
-    "kamaishi.iwate.jp",
+    "kicks-ass.org",
+    "rel.pl",
+    "report",
+    "web.lk",
+    "journal.aero",
+    "izumisano.osaka.jp",
+    "hjelmeland.no",
+    "denmark.museum",
     "caltanissetta.it",
-    "ibaraki.osaka.jp",
-    "xn--rdal-poa.no",
-    "gyeonggi.kr",
-    "better-than.tv",
-    "koza.wakayama.jp",
+    "nyc.mn",
+    "carraramassa.it",
+    "edu.ph",
+    "blogdns.com",
+    "evenassi.no",
+    "atlanta.museum",
+    "wtc",
+    "q.bg",
+    "grandrapids.museum",
+    "net.th",
+    "nagoya",
+    "blogspot.bj",
+    "quebec",
+    "hino.tottori.jp",
+    "katsuragi.nara.jp",
+    "giessen.museum",
+    "w.bg",
+    "rodeo",
+    "webcam",
     "ax",
-    "ovh",
-    "web.ve",
-    "koya.wakayama.jp",
-    "hoyanger.no",
-    "educational.museum",
+    "wang",
+    "jeonnam.kr",
+    "beskidy.pl",
+    "namsskogan.no",
     "axa",
-    "omasvuotna.no",
-    "net.ci",
-    "yono.saitama.jp",
-    "com.ci",
-    "asakuchi.okayama.jp",
-    "itakura.gunma.jp",
-    "gobo.wakayama.jp",
-    "de",
-    "ceo",
-    "joso.ibaraki.jp",
-    "do",
-    "boo",
-    "cool",
-    "net.dm",
-    "dj",
-    "com.dm",
-    "gov.dm",
-    "brussel.museum",
-    "net.om",
-    "cechire.com",
-    "kin.okinawa.jp",
-    "com.om",
-    "gov.om",
-    "communication.museum",
-    "iwatsuki.saitama.jp",
-    "chelyabinsk.ru",
-    "jeju.kr",
-    "koka.shiga.jp",
-    "communications.museum",
-    "isesaki.gunma.jp",
-    "catering.aero",
-    "newyork.museum",
-    "naturalsciences.museum",
-    "edu.ci",
-    "iris.arpa",
-    "uda.nara.jp",
-    "kiso.nagano.jp",
-    "aknoluokta.no",
-    "edu.dm",
-    "web.nf",
-    "kawajima.saitama.jp",
-    "edu.om",
-    "bearalvahki.no",
-    "day",
-    "org.sh",
-    "hirosaki.aomori.jp",
-    "americana.museum",
-    "wy.us",
-    "kasaoka.okayama.jp",
-    "org.ph",
-    "expert",
-    "nobeoka.miyazaki.jp",
-    "kira.aichi.jp",
-    "kameyama.mie.jp",
-    "amakusa.kumamoto.jp",
-    "lugansk.ua",
-    "cleaning",
-    "xn--skjk-soa.no",
-    "qh.cn",
-    "net.bh",
-    "norfolk.museum",
-    "com.bh",
-    "oristano.it",
-    "gov.bh",
-    "net.tm",
-    "artdeco.museum",
-    "uozu.toyama.jp",
-    "com.tm",
-    "gov.tm",
-    "valle-aosta.it",
-    "nom.tm",
-    "xn--ngbc5azd",
-    "lyngdal.no",
-    "kiwi",
-    "cesenaforli.it",
-    "eisenbahn.museum",
-    "gniezno.pl",
-    "ventures",
-    "xn--snes-poa.no",
-    "kristiansand.no",
-    "country",
-    "dz",
-    "koganei.tokyo.jp",
-    "hazu.aichi.jp",
-    "edu.bh",
-    "chtr.k12.ma.us",
-    "jefferson.museum",
-    "edu.tm",
-    "viajes",
-    "name.hr",
-    "dm",
-    "va.us",
-    "valleeaoste.it",
-    "co.lc",
-    "gouv.ml",
-    "dad",
-    "dance",
-    "hyllestad.no",
-    "nc.us",
-    "vic.au",
-    "casadelamoneda.museum",
-    "osen.no",
-    "bargains",
-    "nakhodka.ru",
-    "dabur",
-    "katsushika.tokyo.jp",
-    "vt.us",
-    "kristiansund.no",
-    "ina.saitama.jp",
-    "univ.sn",
-    "name.my",
-    "int.ci",
-    "valledaosta.it",
+    "y.se",
+    "kamo.niigata.jp",
+    "dielddanuorri.no",
+    "net.ki",
+    "notaires.km",
+    "com.ki",
+    "gov.ki",
+    "nhk",
+    "cloudapp.net",
+    "wien",
+    "holtalen.no",
+    "carrara-massa.it",
+    "imperia.it",
+    "nysa.pl",
+    "rana.no",
+    "nannestad.no",
     "cg",
     "bg",
     "kg",
     "gg",
+    "communication.museum",
     "ng",
-    "benevento.it",
-    "org.ci",
-    "isa.kagoshima.jp",
-    "workinggroup.aero",
-    "net.im",
+    "catania.it",
+    "repair",
+    "communications.museum",
+    "wroc.pl",
+    "irkutsk.ru",
+    "club.aero",
     "net.gt",
     "net.gp",
-    "yazu.tottori.jp",
     "net.gr",
-    "com.im",
+    "qpon",
+    "eidsberg.no",
     "com.gt",
     "com.gp",
-    "co.gy",
     "com.gr",
-    "kuzumaki.iwate.jp",
+    "edu.ki",
     "gov.gr",
-    "bialystok.pl",
-    "codespot.com",
-    "y.bg",
+    "jeju.kr",
+    "web.ve",
     "eg",
-    "org.dm",
-    "judaica.museum",
-    "us.org",
-    "kitakami.iwate.jp",
-    "gob.gt",
-    "americanart.museum",
-    "org.om",
-    "net.gn",
-    "dnp",
-    "ascolipiceno.it",
-    "com.gn",
-    "viterbo.it",
-    "gov.gn",
-    "omi.nagano.jp",
-    "naka.ibaraki.jp",
-    "re",
-    "ren",
-    "xn--yer-zna.no",
-    "ro",
-    "odo.br",
-    "rs",
-    "net.bm",
-    "jewelry.museum",
-    "com.bm",
-    "gov.bm",
-    "edu.gt",
-    "brescia.it",
-    "edu.gp",
-    "land-4-sale.us",
-    "edu.gr",
-    "gran.no",
-    "championship.aero",
-    "jelenia-gora.pl",
-    "niigata.jp",
-    "dk",
-    "xn--mli-tla.no",
-    "chel.ru",
-    "orkanger.no",
-    "is-a-painter.com",
-    "com.km",
-    "gov.km",
-    "edu.gn",
-    "nom.km",
-    "bo.telemark.no",
-    "naturalhistory.museum",
-    "kitaura.miyazaki.jp",
-    "usa.oita.jp",
-    "ac.me",
-    "kawanehon.shizuoka.jp",
-    "vi.us",
-    "ac.se",
-    "australia.museum",
-    "xn--rland-uua.no",
-    "assassination.museum",
-    "xn--uc0ay4a.hk",
-    "ggee",
-    "kashiwara.osaka.jp",
-    "org.bh",
     "k-uralsk.ru",
-    "edu.bm",
-    "ac.ae",
-    "venezia.it",
-    "lancashire.museum",
-    "org.tm",
-    "chiyoda.tokyo.jp",
-    "xn--mely-ira.no",
-    "babia-gora.pl",
-    "bc.ca",
-    "gc.ca",
-    "convent.museum",
-    "xn--80adxhks",
-    "net.ge",
-    "edu.km",
-    "xn--asky-ira.no",
-    "is-a-cpa.com",
-    "com.ge",
-    "khakassia.ru",
-    "gov.ge",
-    "v.bg",
-    "ac.tj",
-    "ag",
-    "d.se",
-    "atlanta.museum",
-    "red",
-    "kongsberg.no",
-    "nuremberg.museum",
-    "email",
-    "conf.au",
-    "is-an-actress.com",
-    "ac.ma",
-    "vn.ua",
-    "os.hedmark.no",
-    "chernigov.ua",
-    "info.tz",
-    "warszawa.pl",
-    "ru",
-    "yaroslavl.ru",
-    "kviteseid.no",
-    "budejju.no",
-    "ueda.nagano.jp",
-    "nichinan.tottori.jp",
-    "yachts",
-    "edu.ge",
-    "cooking",
-    "xn--wgbl6a",
-    "omsk.ru",
-    "hanamaki.iwate.jp",
-    "kawahara.tottori.jp",
-    "illustration.museum",
-    "report",
-    "leksvik.no",
-    "ac.at",
-    "rel.pl",
-    "yk.ca",
-    "isleofman.museum",
-    "name.mk",
-    "agro.pl",
-    "xn--od0aq3b.hk",
-    "ac.mu",
-    "history.museum",
-    "vaksdal.no",
-    "neat-url.com",
-    "aya.miyazaki.jp",
-    "org.im",
-    "org.gt",
-    "org.gp",
-    "bungotakada.oita.jp",
-    "amur.ru",
-    "org.gr",
-    "kishiwada.osaka.jp",
-    "ac.sz",
-    "amli.no",
-    "giessen.museum",
-    "childrens.museum",
-    "hiranai.aomori.jp",
-    "kagamino.okayama.jp",
-    "joshkar-ola.ru",
-    "org.gn",
-    "wv.us",
-    "kunstunddesign.museum",
-    "co.id",
-    "go.id",
-    "nsw.edu.au",
-    "bio.br",
-    "rodeo",
-    "wada.nagano.jp",
-    "ac.tz",
-    "bajddar.no",
-    "gouv.ht",
-    "hashikami.aomori.jp",
-    "carrier.museum",
-    "org.bm",
-    "lincoln.museum",
-    "bashkiria.ru",
-    "noda.chiba.jp",
-    "xn--55qx5d.hk",
-    "ato.br",
-    "yn.cn",
-    "xn--lcvr32d.hk",
-    "xn--45q11c",
-    "rana.no",
-    "is-an-artist.com",
-    "ac.cr",
-    "amot.no",
-    "repair",
-    "org.km",
-    "construction",
-    "rest",
-    "birdart.museum",
-    "ibaraki.ibaraki.jp",
-    "certification.aero",
-    "historisches.museum",
-    "blackfriday",
-    "xn--lgrd-poac.no",
-    "imakane.hokkaido.jp",
-    "ami.ibaraki.jp",
-    "lighting",
-    "hamburg.museum",
-    "vang.no",
-    "xn--6qq986b3xl",
-    "ind.gt",
-    "asso.dz",
-    "kai.yamanashi.jp",
-    "xn--3e0b707e",
-    "ac.rs",
-    "kumejima.okinawa.jp",
-    "xn--zfr164b",
-    "nonoichi.ishikawa.jp",
-    "kembuchi.hokkaido.jp",
-    "nuernberg.museum",
-    "ac.kr",
-    "ce.it",
-    "ge.it",
-    "asaminami.hiroshima.jp",
-    "xn--lury-ira.no",
-    "vallee-aoste.it",
-    "or.id",
-    "co.it",
-    "bo.it",
-    "go.it",
-    "id.ir",
-    "cs.it",
-    "bs.it",
-    "omaezaki.shizuoka.jp",
-    "rep.kp",
-    "no.it",
-    "is.it",
-    "xn--srfold-bya.no",
-    "name.az",
-    "org.ge",
-    "co.ir",
-    "ggf.br",
-    "info.au",
-    "hatoyama.saitama.jp",
-    "collection.museum",
-    "culture.museum",
-    "kashiwa.chiba.jp",
-    "holiday",
-    "oyamazaki.kyoto.jp",
-    "oshu.iwate.jp",
-    "khmelnytskyi.ua",
-    "noshiro.akita.jp",
-    "birthplace.museum",
-    "bologna.it",
-    "hinohara.tokyo.jp",
-    "kamchatka.ru",
-    "is-a-lawyer.com",
-    "gjerdrum.no",
-    "valled-aosta.it",
-    "ac.vn",
-    "yakutia.ru",
-    "is-a-llama.com",
-    "gorizia.it",
-    "r.se",
-    "dagestan.ru",
-    "okegawa.saitama.jp",
-    "ath.cx",
-    "ac.ci",
-    "agr.br",
-    "logistics.aero",
-    "info.sd",
-    "ontario.museum",
-    "bokn.no",
-    "ca.it",
-    "ba.it",
-    "norilsk.ru",
-    "chiyoda.gunma.jp",
-    "ac.cn",
-    "na.it",
-    "christmas",
-    "rnu.tn",
-    "xn--osyro-wua.no",
-    "le.it",
-    "co.im",
-    "kitadaito.okinawa.jp",
-    "assn.lk",
-    "td",
-    "de.us",
-    "chernihiv.ua",
-    "lo.it",
-    "to",
-    "co.no",
-    "xn--nry-yla5g.no",
-    "tj",
-    "ot.it",
-    "ct.it",
-    "bt.it",
-    "tp",
-    "or.it",
-    "cr.it",
-    "name.mv",
-    "br.it",
-    "aero.mv",
-    "kr.it",
-    "gr.it",
-    "aurland.no",
-    "ac.ru",
-    "ac.be",
-    "vacations",
-    "ass.km",
-    "com.gi",
-    "is-a-rockstar.com",
-    "gov.gi",
-    "operaunite.com",
-    "izhevsk.ru",
-    "kawanishi.nara.jp",
-    "jp.net",
-    "barlettatraniandria.it",
-    "xn--90a3ac",
-    "nu.it",
-    "co.in",
-    "iki.nagasaki.jp",
-    "leirvik.no",
-    "rost.no",
-    "rade.no",
-    "xn--tn0ag.hk",
-    "vc",
-    "watarai.mie.jp",
-    "cz.it",
-    "bz.it",
-    "globo",
-    "iamallama.com",
-    "eigersund.no",
-    "info.ht",
-    "vestre-toten.no",
-    "co.na",
-    "xn--45brj9c",
-    "walbrzych.pl",
-    "wakayama.jp",
-    "ao.it",
-    "urakawa.hokkaido.jp",
-    "akabira.hokkaido.jp",
-    "za.net",
-    "net.gg",
-    "arendal.no",
-    "dp.ua",
-    "ap.it",
-    "res.in",
-    "akiruno.tokyo.jp",
-    "xn--s9brj9c",
-    "edu.gi",
-    "im.it",
-    "xn--troms-zua.no",
-    "okayama.jp",
-    "lt.it",
-    "tt",
-    "kunstsammlung.museum",
-    "nt.no",
-    "tr",
-    "val-d-aosta.it",
-    "info.az",
-    "zhytomyr.ua",
-    "ac.th",
-    "rw",
-    "crotone.it",
-    "no.com",
-    "augustow.pl",
-    "koshigaya.saitama.jp",
-    "gateway.museum",
-    "kokubunji.tokyo.jp",
-    "xn--wcvs22d.hk",
-    "isehara.kanagawa.jp",
-    "rnd.ru",
-    "katsuragi.wakayama.jp",
-    "lu.it",
-    "trade",
-    "ci.it",
-    "gyeongnam.kr",
-    "bi.it",
-    "americanantiques.museum",
-    "bu.no",
-    "ca.na",
-    "asso.ht",
-    "oishida.yamagata.jp",
-    "hirakata.osaka.jp",
-    "xn--trany-yua.no",
-    "erotika.hu",
-    "cn.it",
-    "ac.jp",
-    "bn.it",
-    "qc.ca",
-    "gx.cn",
-    "tz",
-    "tel",
-    "nx.cn",
-    "erotica.hu",
-    "rocks",
-    "abo.pa",
-    "city.kawasaki.jp",
-    "xn--trna-woa.no",
-    "xn--unjrga-rta.no",
-    "at.it",
-    "en.it",
-    "or.na",
-    "ac.mw",
-    "ar.it",
-    "www.ck",
-    "tm",
-    "aosta-valley.it",
-    "nagahama.shiga.jp",
-    "valleaosta.it",
-    "yoshino.nara.jp",
-    "jx.cn",
-    "cb.it",
-    "rel.ht",
-    "xn--snsa-roa.no",
-    "worse-than.tv",
-    "avellino.it",
-    "jevnaker.no",
-    "rns.tn",
-    "za.com",
-    "city.kitakyushu.jp",
-    "cologne",
-    "uki.kumamoto.jp",
-    "info.mv",
-    "chuo.chiba.jp",
-    "res.aero",
-    "eu.int",
-    "journalism.museum",
-    "tom.ru",
-    "travel",
-    "ujitawara.kyoto.jp",
-    "cherkasy.ua",
-    "nikolaev.ua",
-    "tur.ar",
-    "xn--yfro4i67o",
-    "ne.ug",
-    "ravenna.it",
-    "br.com",
-    "kr.com",
-    "gr.com",
-    "li.it",
-    "co.ug",
-    "go.ug",
-    "drammen.no",
-    "overhalla.no",
-    "aa.no",
-    "tn",
-    "okinawa",
-    "kushiro.hokkaido.jp",
-    "ureshino.mie.jp",
-    "og.ao",
-    "co.ag",
-    "gushikami.okinawa.jp",
-    "inashiki.ibaraki.jp",
-    "lillehammer.no",
-    "verbania.it",
-    "consulting",
-    "tips",
-    "yokohama",
-    "kami.kochi.jp",
-    "davvesiida.no",
-    "gotemba.shizuoka.jp",
-    "xn--muost-0qa.no",
-    "kiyosato.hokkaido.jp",
-    "dni.us",
-    "hatsukaichi.hiroshima.jp",
-    "coldwar.museum",
-    "cl.it",
-    "bl.it",
-    "rec.br",
-    "xn--mxtq1m.hk",
-    "dnsdojo.net",
-    "bari.it",
-    "webcam",
-    "capebreton.museum",
-    "ug",
-    "british.museum",
-    "unbi.ba",
-    "tana.no",
-    "gb.net",
-    "org.gi",
-    "eu.com",
-    "d.bg",
-    "yasu.shiga.jp",
-    "wolomin.pl",
-    "uno",
-    "ikusaka.nagano.jp",
-    "rnrt.tn",
-    "cherkassy.ua",
-    "is-an-accountant.com",
-    "khmelnitskiy.ua",
-    "naturalhistorymuseum.museum",
-    "barletta-trani-andria.it",
-    "wien",
-    "chesapeakebay.museum",
-    "kumenan.okayama.jp",
-    "dn.ua",
-    "an.it",
-    "kafjord.no",
-    "in.na",
-    "tk",
-    "gs.jan-mayen.no",
-    "chernivtsi.ua",
-    "audnedaln.no",
-    "nishitosa.kochi.jp",
-    "nord-aurdal.no",
-    "hachijo.tokyo.jp",
-    "alesund.no",
-    "taa.it",
-    "lucerne.museum",
-    "ha.no",
-    "org.gg",
-    "la-spezia.it",
-    "or.ug",
-    "ltd.gi",
-    "vevelstad.no",
-    "wroc.pl",
-    "kagoshima.jp",
-    "cruises",
-    "oi.kanagawa.jp",
-    "dnsdojo.com",
-    "cn.com",
-    "bygland.no",
-    "tl",
-    "ol.no",
-    "co.nl",
-    "ch.it",
-    "vicenza.it",
-    "kosa.kumamoto.jp",
-    "yokohama.jp",
-    "is-lost.org",
-    "nl.no",
-    "is-very-good.org",
-    "asti.it",
-    "xn--rskog-uua.no",
-    "in-the-band.net",
-    "hu.net",
-    "dontexist.net",
-    "vestnes.no",
-    "ar.com",
-    "lg.ua",
-    "arao.kumamoto.jp",
-    "t.se",
-    "xn--ygbi2ammx",
-    "kanazawa.ishikawa.jp",
-    "is-found.org",
-    "is-a-socialist.com",
-    "gb.com",
-    "lodi.it",
-    "xn--55qx5d.cn",
-    "events",
-    "xn--mgbaam7a8h",
-    "xn--vard-jra.no",
-    "bergamo",
-    "ibestad.no",
-    "geelvinck.museum",
-    "al.it",
-    "ac.rw",
-    "kuki.saitama.jp",
-    "tur.br",
-    "xn--mjndalen-64a.no",
-    "hm.no",
-    "amusement.aero",
-    "xn--mk0axi.hk",
-    "tra.kp",
-    "homeunix.com",
-    "akishima.tokyo.jp",
-    "game-server.cc",
-    "azure-mobile.net",
-    "yatsuka.shimane.jp",
-    "western.museum",
-    "th",
-    "harstad.no",
-    "rendalen.no",
-    "xn--lt-liac.no",
-    "architecture.museum",
-    "xn--vg-yiab.no",
-    "vald-aosta.it",
-    "aq.it",
-    "kutchan.hokkaido.jp",
-    "xn--seral-lra.no",
-    "noto.ishikawa.jp",
-    "nieruchomosci.pl",
-    "vindafjord.no",
-    "czeladz.pl",
-    "home.dyndns.org",
-    "oga.akita.jp",
-    "broke-it.net",
-    "tos.it",
-    "likescandy.com",
-    "kg.kr",
-    "tas.au",
-    "whaling.museum",
-    "chitose.hokkaido.jp",
-    "gyeongbuk.kr",
-    "is-a-candidate.org",
-    "hu.com",
-    "tmp.br",
-    "kharkiv.ua",
-    "broadcast.museum",
-    "test.tj",
-    "ri.us",
-    "domains",
-    "trd.br",
-    "arboretum.museum",
-    "time.no",
-    "tokyo",
-    "al.no",
-    "xn--rde-ula.no",
-    "khabarovsk.ru",
-    "xn--p1acf",
-    "xn--h2brj9c",
-    "oumu.hokkaido.jp",
-    "xn--kprw13d",
-    "game-host.org",
-    "xn--msy-ula0h.no",
-    "grosseto.it",
-    "oppegard.no",
-    "castres.museum",
-    "re.kr",
-    "tw",
-    "nannestad.no",
-    "omi.niigata.jp",
-    "yura.wakayama.jp",
-    "nirasaki.yamanashi.jp",
-    "eastafrica.museum",
-    "onagawa.miyagi.jp",
-    "opoczno.pl",
-    "yamanashi.jp",
-    "xn--mlatvuopmi-s4a.no",
-    "herokuapp.com",
-    "kui.hiroshima.jp",
-    "imageandsound.museum",
-    "r.bg",
-    "omigawa.chiba.jp",
-    "narusawa.yamanashi.jp",
-    "kamioka.akita.jp",
-    "xn--drbak-wua.no",
-    "dontexist.org",
-    "kanagawa.jp",
-    "xn--zf0ao64a.tw",
-    "cincinnati.museum",
-    "abashiri.hokkaido.jp",
-    "bato.tochigi.jp",
-    "nowaruda.pl",
-    "azumino.nagano.jp",
-    "uzhgorod.ua",
-    "association.aero",
-    "chikusei.ibaraki.jp",
-    "hiroshima.jp",
-    "wiki",
-    "legnica.pl",
-    "repbody.aero",
-    "hl.no",
-    "ah.no",
-    "xn--klbu-woa.no",
-    "historisch.museum",
-    "rentals",
-    "arai.shizuoka.jp",
-    "xn--kranghke-b0a.no",
-    "grandrapids.museum",
-    "egersund.no",
-    "today",
-    "okinawa.jp",
-    "taranto.it",
-    "wakkanai.hokkaido.jp",
-    "engineer.aero",
-    "nanmoku.gunma.jp",
-    "aso.kumamoto.jp",
-    "ud.it",
-    "is-very-sweet.org",
-    "vladikavkaz.ru",
-    "iveland.no",
-    "xn--czr694b",
-    "kaga.ishikawa.jp",
-    "toscana.it",
-    "xn--j6w193g",
-    "lombardy.it",
-    "gov.cm",
-    "qld.edu.au",
-    "is-a-teacher.com",
-    "obihiro.hokkaido.jp",
-    "xn--sknit-yqa.no",
-    "defense.tn",
-    "roma.it",
-    "tenkawa.nara.jp",
-    "xn--vry-yla5g.no",
-    "horokanai.hokkaido.jp",
-    "xn--b-5ga.nordland.no",
-    "kunisaki.oita.jp",
-    "osakikamijima.hiroshima.jp",
-    "historical.museum",
-    "tsk.ru",
-    "xn--risr-ira.no",
-    "orenburg.ru",
-    "xn--vgan-qoa.no",
-    "kikonai.hokkaido.jp",
-    "est-a-la-masion.com",
-    "beauxarts.museum",
-    "oregontrail.museum",
-    "delmenhorst.museum",
-    "xn--linds-pra.no",
-    "uscountryestate.museum",
-    "xn--b-5ga.telemark.no",
-    "cheltenham.museum",
-    "ota.gunma.jp",
-    "ora.gunma.jp",
-    "haugesund.no",
-    "xn--uc0atv.hk",
-    "bieszczady.pl",
-    "xn--c1avg",
-    "rich",
-    "koebenhavn.museum",
-    "rs.ba",
-    "xn--kput3i",
-    "te.ua",
-    "klodzko.pl",
-    "dyndns-home.com",
-    "iwakura.aichi.jp",
-    "rome.it",
-    "is-a-bookkeeper.com",
-    "treviso.it",
-    "lombardia.it",
-    "cahcesuolo.no",
-    "historicalsociety.museum",
-    "yekaterinburg.ru",
-    "azurewebsites.net",
-    "tuscany.it",
-    "brumunddal.no",
-    "ac.gn",
-    "vestvagoy.no",
-    "vg",
-    "nasu.tochigi.jp",
-    "does-it.net",
-    "austrheim.no",
-    "contemporary.museum",
-    "tottori.jp",
-    "lg.jp",
-    "veterinaire.km",
-    "toda.saitama.jp",
-    "us.na",
-    "himi.toyama.jp",
-    "nagareyama.chiba.jp",
-    "xn--sandy-yua.no",
-    "democrat",
-    "ws.na",
-    "virtuel.museum",
-    "chicago.museum",
-    "academy",
-    "realestate.pl",
-    "emergency.aero",
-    "komi.ru",
-    "express.aero",
-    "ryukyu",
-    "donetsk.ua",
-    "unjarga.no",
-    "us.com",
-    "nagaoka.niigata.jp",
-    "blog.br",
-    "tm.se",
-    "ginowan.okinawa.jp",
-    "xn--risa-5na.no",
-    "val-daosta.it",
-    "kure.hiroshima.jp",
-    "homelinux.net",
-    "trading.aero",
-    "okutama.tokyo.jp",
-    "cloudapp.net",
-    "vao.it",
-    "ogi.saga.jp",
-    "wiki.br",
-    "lodingen.no",
-    "doesntexist.com",
-    "ruhr",
-    "ooshika.nagano.jp",
-    "association.museum",
-    "vision",
-    "business",
-    "blogspot.de",
-    "tv",
-    "yoshida.saitama.jp",
-    "blogspot.se",
-    "isen.kagoshima.jp",
-    "news.hu",
-    "tn.us",
-    "british-library.uk",
-    "yawatahama.ehime.jp",
-    "torsken.no",
-    "blogspot.jp",
-    "andriabarlettatrani.it",
-    "haga.tochigi.jp",
-    "zama.kanagawa.jp",
-    "hakusan.ishikawa.jp",
-    "herokussl.com",
-    "eco.br",
-    "t.bg",
-    "niikappu.hokkaido.jp",
-    "voyage",
-    "ama.shimane.jp",
-    "tara.saga.jp",
-    "xn--sr-aurdal-l8a.no",
-    "av.it",
-    "nichinan.miyazaki.jp",
-    "nishinoshima.shimane.jp",
-    "cranbrook.museum",
-    "nakamura.kochi.jp",
-    "volkenkunde.museum",
-    "zhitomir.ua",
-    "is-an-entertainer.com",
-    "est-a-la-maison.com",
-    "ogasawara.tokyo.jp",
-    "blogspot.td",
-    "blogspot.re",
-    "tourism.tn",
-    "kinokawa.wakayama.jp",
-    "blogspot.ro",
-    "blogspot.pt",
-    "katagami.akita.jp",
-    "kashihara.nara.jp",
-    "bolt.hu",
-    "uk.net",
-    "homedns.org",
-    "indianmarket.museum",
-    "xn--lns-qla.museum",
-    "tj.cn",
-    "xn--mgbab2bd",
-    "yotsukaido.chiba.jp",
-    "at-band-camp.net",
-    "olbiatempio.it",
-    "kamiichi.toyama.jp",
-    "randaberg.no",
-    "andria-trani-barletta.it",
-    "city.hu",
-    "xn--wgbh1c",
-    "kamijima.ehime.jp",
-    "tadaoka.osaka.jp",
-    "volgograd.ru",
-    "kitayama.wakayama.jp",
-    "homelinux.org",
-    "kasumigaura.ibaraki.jp",
-    "kyotango.kyoto.jp",
-    "xn--s-1fa.no",
-    "neyagawa.osaka.jp",
-    "hachirogata.akita.jp",
-    "kobayashi.miyazaki.jp",
-    "iwaizumi.iwate.jp",
-    "virtual.museum",
-    "halloffame.museum",
-    "kudoyama.wakayama.jp",
-    "homeunix.org",
-    "toyo.kochi.jp",
-    "kusatsu.gunma.jp",
-    "izu.shizuoka.jp",
-    "kamisato.saitama.jp",
-    "xn--karmy-yua.no",
-    "kawakita.ishikawa.jp",
-    "yatsushiro.kumamoto.jp",
-    "kawaminami.miyazaki.jp",
-    "naie.hokkaido.jp",
-    "tm.fr",
-    "hayakawa.yamanashi.jp",
-    "tm.ro",
-    "embetsu.hokkaido.jp",
-    "hokkaido.jp",
-    "xn--unup4y",
-    "dielddanuorri.no",
-    "anan.nagano.jp",
-    "rec.nf",
-    "riik.ee",
-    "blogspot.ie",
-    "okuizumo.shimane.jp",
-    "xn--hery-ira.nordland.no",
-    "tosu.saga.jp",
-    "indiana.museum",
-    "co.gg",
-    "giehtavuoatna.no",
-    "blogspot.no",
-    "uk.com",
-    "himeshima.oita.jp",
-    "est-le-patron.com",
-    "ve.it",
-    "dnsalias.net",
-    "is-a-nurse.com",
-    "voting",
-    "dynalias.net",
-    "haibara.shizuoka.jp",
-    "denmark.museum",
-    "vs.it",
-    "komatsu.ishikawa.jp",
-    "blogspot.be",
-    "hamatama.saga.jp",
-    "aoki.nagano.jp",
-    "church",
-    "info.hu",
-    "blogspot.mr",
-    "blogspot.bj",
-    "tm.km",
-    "turystyka.pl",
-    "lavagis.no",
-    "dellogliastra.it",
-    "is-a-student.com",
-    "com.gh",
-    "gov.gh",
-    "hamamatsu.shizuoka.jp",
-    "vennesla.no",
-    "blogspot.dk",
-    "naka.hiroshima.jp",
-    "tama.tokyo.jp",
-    "xn--stjrdalshalsen-sqb.no",
-    "act.edu.au",
-    "desi",
-    "xn--krjohka-hwab49j.no",
-    "blogspot.sk",
-    "lajolla.museum",
-    "ueno.gunma.jp",
-    "blogspot.it",
-    "anjo.aichi.jp",
-    "uryu.hokkaido.jp",
-    "ushuaia.museum",
-    "kimobetsu.hokkaido.jp",
-    "nishikatsura.yamanashi.jp",
-    "va.it",
-    "rv.ua",
-    "bv.nl",
-    "barreau.bj",
-    "directory",
-    "edu.gh",
-    "hobby-site.com",
-    "gs.svalbard.no",
-    "vt.it",
-    "tottori.tottori.jp",
-    "kamikawa.saitama.jp",
-    "ascoli-piceno.it",
-    "yao.osaka.jp",
-    "okayama.okayama.jp",
-    "vr.it",
-    "contemporaryart.museum",
-    "agdenes.no",
-    "bydgoszcz.pl",
-    "xn--czru2d",
-    "isshiki.aichi.jp",
-    "ishikawa.jp",
-    "aibetsu.hokkaido.jp",
-    "is-very-bad.org",
-    "is-a-personaltrainer.com",
-    "kumagaya.saitama.jp",
-    "tsuruta.aomori.jp",
-    "nesoddtangen.no",
-    "ac.id",
-    "is-a-landscaper.com",
-    "zentsuji.kagawa.jp",
-    "granvin.no",
-    "zaporizhzhia.ua",
-    "uto.kumamoto.jp",
-    "yabu.hyogo.jp",
-    "vologda.ru",
-    "indianapolis.museum",
-    "tobe.ehime.jp",
-    "kitakata.miyazaki.jp",
-    "blogspot.kr",
-    "yasuoka.nagano.jp",
-    "tonsberg.no",
-    "tosa.kochi.jp",
-    "chichibu.saitama.jp",
-    "uy.com",
-    "va.no",
-    "higashiosaka.osaka.jp",
-    "lc.it",
-    "tc",
-    "oiso.kanagawa.jp",
-    "nnov.ru",
-    "dc.us",
-    "oe.yamagata.jp",
-    "habikino.osaka.jp",
-    "xn--rros-gra.no",
-    "is-into-cars.com",
-    "tatarstan.ru",
+    "alessandria.it",
+    "kota.aichi.jp",
+    "gob.gt",
+    "net.gn",
+    "karelia.ru",
+    "naturalsciences.museum",
+    "com.gn",
+    "gov.gn",
     "blogspot.in",
-    "toga.toyama.jp",
-    "tourism.pl",
-    "trieste.it",
-    "vi.it",
-    "karuizawa.nagano.jp",
-    "cc.na",
-    "ngo.pl",
-    "xn--l-1fa.no",
-    "geology.museum",
-    "kobierzyce.pl",
-    "ac.ir",
-    "aogashima.tokyo.jp",
-    "is-a-knight.org",
-    "dyndns-mail.com",
-    "newhampshire.museum",
-    "exposed",
-    "zoology.museum",
-    "edogawa.tokyo.jp",
-    "kawakami.nagano.jp",
-    "taku.saga.jp",
-    "org.gh",
-    "vb.it",
-    "izumozaki.niigata.jp",
-    "rakkestad.no",
-    "xn--nqv7f",
-    "gyokuto.kumamoto.jp",
-    "clothing",
-    "is-very-nice.org",
-    "nakaniikawa.toyama.jp",
-    "zao.miyagi.jp",
-    "urayasu.chiba.jp",
-    "amsterdam.museum",
-    "go.dyndns.org",
-    "civilaviation.aero",
-    "ac.im",
-    "namegawa.saitama.jp",
-    "blogspot.hu",
-    "utashinai.hokkaido.jp",
-    "hatogaya.saitama.jp",
-    "nozawaonsen.nagano.jp",
+    "aerobatic.aero",
+    "expert",
+    "defense.tn",
+    "edu.gt",
+    "edu.gp",
+    "edu.gr",
+    "net.kz",
+    "com.kz",
+    "gov.kz",
+    "cranbrook.museum",
+    "net.bh",
+    "info.mv",
+    "com.bh",
+    "edu.gn",
+    "gov.bh",
+    "ggee",
+    "nagaokakyo.kyoto.jp",
+    "certification.aero",
+    "educational.museum",
+    "chuo.tokyo.jp",
+    "charter.aero",
+    "blogspot.sk",
+    "edu.kz",
+    "blogspot.dk",
+    "ag",
+    "astrakhan.ru",
+    "ibaraki.jp",
+    "net.ge",
+    "edu.bh",
+    "com.ge",
+    "gov.ge",
+    "delmenhorst.museum",
+    "chtr.k12.ma.us",
+    "bungotakada.oita.jp",
+    "name.hr",
+    "gliding.aero",
+    "rade.no",
+    "w.se",
+    "khakassia.ru",
+    "yono.saitama.jp",
+    "ina.nagano.jp",
+    "hjartdal.no",
+    "rnu.tn",
+    "edu.ge",
+    "r.bg",
+    "roan.no",
+    "como.it",
     "blogspot.nl",
-    "xn--h-2fa.no",
-    "xn--3ds443g",
+    "web.nf",
+    "iris.arpa",
+    "kuroishi.aomori.jp",
+    "astronomy.museum",
+    "agro.pl",
+    "amakusa.kumamoto.jp",
+    "blogspot.kr",
+    "nedre-eiker.no",
+    "kurotaki.nara.jp",
+    "rocks",
+    "rio",
+    "catanzaro.it",
+    "kira.aichi.jp",
+    "rentals",
+    "hino.tokyo.jp",
+    "kameoka.kyoto.jp",
+    "blogspot.hu",
+    "culture.museum",
+    "goto.nagasaki.jp",
+    "watch",
+    "ngo",
+    "itakura.gunma.jp",
+    "birthplace.museum",
+    "geology.museum",
+    "ngo.pl",
+    "grajewo.pl",
+    "americana.museum",
+    "birdart.museum",
+    "abruzzo.it",
+    "rest",
+    "niigata.jp",
+    "bargains",
+    "koto.shiga.jp",
+    "rec.br",
+    "carrier.museum",
+    "novosibirsk.ru",
+    "conf.au",
+    "kongsberg.no",
+    "ggf.br",
+    "zoology.museum",
+    "akrehamn.no",
+    "gets-it.net",
+    "capital",
+    "holmestrand.no",
+    "blogspot.tw",
+    "rep.kp",
+    "gniezno.pl",
+    "cechire.com",
+    "aurland.no",
+    "illustration.museum",
+    "agr.br",
+    "isesaki.gunma.jp",
+    "kashiba.nara.jp",
+    "gamo.shiga.jp",
+    "bajddar.no",
+    "rehab",
+    "email",
+    "ind.gt",
+    "amli.no",
+    "kartuzy.pl",
+    "kisosaki.mie.jp",
+    "r.se",
+    "kalmykia.ru",
+    "budejju.no",
+    "bologna.it",
+    "alabama.museum",
+    "is-a-lawyer.com",
+    "rnrt.tn",
+    "contemporary.museum",
+    "babia-gora.pl",
+    "bieszczady.pl",
+    "ravenna.it",
+    "cruises",
+    "isernia.it",
+    "eisenbahn.museum",
+    "rel.ht",
+    "chel.ru",
+    "hamburg.museum",
+    "info.sd",
+    "kobierzyce.pl",
+    "iida.nagano.jp",
+    "rost.no",
+    "rw",
+    "granvin.no",
+    "gateway.museum",
+    "reise",
+    "enna.it",
+    "castres.museum",
+    "yao.osaka.jp",
+    "iveland.no",
+    "collection.museum",
+    "reisen",
+    "americanart.museum",
+    "res.in",
+    "kitaakita.akita.jp",
+    "ina.saitama.jp",
+    "zhitomir.ua",
+    "repbody.aero",
+    "jessheim.no",
+    "catering",
+    "noda.iwate.jp",
+    "yachts",
+    "ethnology.museum",
+    "assassination.museum",
+    "us",
+    "rennesoy.no",
+    "yaroslavl.ru",
+    "itabashi.tokyo.jp",
+    "kviteseid.no",
+    "construction",
+    "casadelamoneda.museum",
+    "coldwar.museum",
+    "bydgoszcz.pl",
+    "history.museum",
+    "kin.okinawa.jp",
+    "info.au",
+    "dellogliastra.it",
+    "ina.ibaraki.jp",
+    "diamonds",
+    "res.aero",
+    "does-it.net",
+    "isen.kagoshima.jp",
+    "nes.akershus.no",
+    "capebreton.museum",
+    "australia.museum",
+    "desi",
+    "cincinnati.museum",
+    "eastafrica.museum",
+    "hirosaki.aomori.jp",
+    "ua",
+    "cesenaforli.it",
+    "ngo.lk",
+    "imageandsound.museum",
+    "cosenza.it",
+    "nuremberg.museum",
+    "kamoenai.hokkaido.jp",
+    "getmyip.com",
+    "ibaraki.osaka.jp",
+    "norilsk.ru",
+    "kodaira.tokyo.jp",
+    "nichinan.tottori.jp",
+    "alesund.no",
+    "kameyama.mie.jp",
+    "augustow.pl",
+    "dyndns-home.com",
+    "rns.tn",
+    "nalchik.ru",
+    "uz",
+    "ibestad.no",
+    "blogspot.hk",
+    "ikaruga.nara.jp",
+    "asakuchi.okayama.jp",
+    "kamaishi.iwate.jp",
+    "amur.ru",
+    "dudinka.ru",
+    "rendalen.no",
+    "catering.aero",
+    "ise.mie.jp",
+    "is-a-candidate.org",
+    "net.gg",
+    "arakawa.tokyo.jp",
+    "eigersund.no",
+    "rec.nf",
+    "koya.wakayama.jp",
+    "christmas",
+    "hara.nagano.jp",
+    "cologne",
+    "gobo.wakayama.jp",
+    "ruhr",
+    "warszawa.pl",
+    "hoyanger.no",
+    "journalism.museum",
+    "nord-aurdal.no",
+    "costume.museum",
+    "holiday",
+    "anan.nagano.jp",
+    "digital",
+    "koga.ibaraki.jp",
+    "arboretum.museum",
+    "isa.kagoshima.jp",
+    "homeunix.net",
+    "avellino.it",
+    "contemporaryart.museum",
+    "is-lost.org",
+    "hiranai.aomori.jp",
+    "cheltenham.museum",
+    "kiso.nagano.jp",
+    "gotemba.shizuoka.jp",
+    "cahcesuolo.no",
+    "british.museum",
+    "workinggroup.aero",
+    "kanagawa.jp",
+    "bjerkreim.no",
+    "umb.it",
+    "kitakami.iwate.jp",
+    "naturalhistory.museum",
+    "yamanashi.jp",
+    "urn.arpa",
+    "dlugoleka.pl",
+    "cleaning",
+    "kamchatka.ru",
+    "ascolipiceno.it",
+    "kami.kochi.jp",
+    "azumino.nagano.jp",
+    "u.bg",
+    "doesntexist.com",
+    "info.ht",
+    "childrens.museum",
+    "americanantiques.museum",
+    "rich",
+    "consulting",
+    "nakhodka.ru",
+    "cherkasy.ua",
+    "harstad.no",
+    "halloffame.museum",
+    "bato.tochigi.jp",
+    "doomdns.org",
+    "divtasvuodna.no",
+    "edogawa.tokyo.jp",
+    "kristiansand.no",
+    "ikusaka.nagano.jp",
+    "barletta-trani-andria.it",
+    "com.gi",
+    "gov.gi",
+    "realestate.pl",
+    "kunstsammlung.museum",
+    "jelenia-gora.pl",
+    "uno",
+    "agdenes.no",
+    "kristiansund.no",
+    "gjerdrum.no",
+    "kunneppu.hokkaido.jp",
+    "arao.kumamoto.jp",
+    "game-host.org",
+    "uk",
+    "edu.gi",
+    "homedns.org",
+    "blackfriday",
+    "kagoshima.jp",
+    "cherkassy.ua",
+    "geelvinck.museum",
+    "nobeoka.miyazaki.jp",
+    "express.aero",
+    "barlettatraniandria.it",
+    "beauxarts.museum",
+    "bialystok.pl",
+    "zaporizhzhia.ua",
+    "dating",
+    "championship.aero",
+    "zaporizhzhe.ua",
+    "hanamaki.iwate.jp",
+    "equipment",
+    "home.dyndns.org",
+    "chelyabinsk.ru",
+    "u.se",
+    "blogspot.mx",
+    "zoological.museum",
+    "nuernberg.museum",
+    "chesapeakebay.museum",
+    "brumunddal.no",
+    "haugesund.no",
+    "blogspot.sg",
+    "koganei.tokyo.jp",
+    "asaminami.hiroshima.jp",
+    "historisches.museum",
+    "anan.tokushima.jp",
     "me",
+    "ms",
     "menu",
     "md",
-    "honbetsu.hokkaido.jp",
-    "xn--andy-ira.no",
-    "kommunalforbund.se",
+    "kashiwara.osaka.jp",
     "mo",
+    "kafjord.no",
     "mov",
-    "ms",
-    "xn--bievt-0qa.no",
-    "mp",
-    "chiropractic.museum",
-    "voronezh.ru",
-    "k12.ec",
+    "nagaoka.niigata.jp",
     "moe",
+    "mp",
     "com.sv",
-    "xn--mgbx4cd0ab",
-    "ena.gifu.jp",
-    "xn--6frz82g",
-    "tm.hu",
-    "xn--ciqpn.hk",
-    "ac.in",
-    "kumiyama.kyoto.jp",
-    "blogspot.tw",
-    "xn--smla-hra.no",
-    "xn--ses554g",
-    "kitahiroshima.hokkaido.jp",
+    "k12.ec",
+    "indiana.museum",
+    "gorizia.it",
+    "asso.ht",
     "gob.sv",
-    "higashiizu.shizuoka.jp",
-    "mormon",
-    "tsu.mie.jp",
     "meet",
-    "nachikatsuura.wakayama.jp",
-    "boleslawiec.pl",
-    "kurashiki.okayama.jp",
-    "tw.cn",
-    "royrvik.no",
-    "namerikawa.toyama.jp",
-    "nishiawakura.okayama.jp",
-    "nosegawa.nara.jp",
-    "abu.yamaguchi.jp",
-    "ma",
-    "dontexist.com",
-    "isa-geek.net",
-    "kitaaiki.nagano.jp",
-    "tono.iwate.jp",
+    "joshkar-ola.ru",
+    "joso.ibaraki.jp",
+    "architecture.museum",
+    "kounosu.saitama.jp",
+    "gyokuto.kumamoto.jp",
+    "brindisi.it",
+    "mormon",
+    "yatsuka.shimane.jp",
+    "bearalvahki.no",
+    "ami.ibaraki.jp",
+    "khabarovsk.ru",
+    "bygland.no",
+    "at-band-camp.net",
+    "dnsalias.net",
     "edu.sv",
-    "omitama.ibaraki.jp",
-    "alto-adige.it",
-    "england.museum",
-    "tv.sd",
-    "vic.edu.au",
-    "openair.museum",
-    "godo.gifu.jp",
-    "is-a-hunter.com",
+    "blogspot.gr",
+    "ma",
+    "ibaraki.ibaraki.jp",
+    "equipment.aero",
+    "yoshino.nara.jp",
     "mt",
     "meme",
-    "xn--kfjord-iua.no",
-    "evenassi.no",
     "mr",
-    "higashiyoshino.nara.jp",
-    "cesena-forli.it",
-    "roan.no",
+    "imakane.hokkaido.jp",
+    "business",
     "med.ec",
+    "western.museum",
+    "kasaoka.okayama.jp",
+    "hinohara.tokyo.jp",
+    "nagahama.shiga.jp",
     "med.pl",
-    "tananger.no",
+    "kashiwa.chiba.jp",
     "mu",
-    "alstahaug.no",
-    "tone.ibaraki.jp",
     "moda",
-    "uenohara.yamanashi.jp",
-    "otofuke.hokkaido.jp",
-    "blogspot.hk",
-    "qpon",
-    "kashima.kumamoto.jp",
-    "rio",
-    "emilia-romagna.it",
     "mz",
-    "kchr.ru",
-    "namsos.no",
-    "is-an-anarchist.com",
-    "council.aero",
-    "inagawa.hyogo.jp",
-    "oppdal.no",
+    "krodsherad.no",
+    "koka.shiga.jp",
+    "kagamino.okayama.jp",
+    "koebenhavn.museum",
+    "hyllestad.no",
+    "kitaura.miyazaki.jp",
+    "dyndns-mail.com",
+    "kommunalforbund.se",
+    "komi.ru",
+    "kishiwada.osaka.jp",
+    "gyeonggi.kr",
     "jondal.no",
-    "nankoku.kochi.jp",
-    "dudinka.ru",
-    "kitanakagusuku.okinawa.jp",
+    "namsos.no",
     "mm",
-    "kyuragi.saga.jp",
-    "blogdns.net",
+    "emergency.aero",
     "net.mv",
-    "tawaramoto.nara.jp",
+    "dnsdojo.org",
     "com.mv",
-    "toyoura.hokkaido.jp",
-    "xn--uc0atv.tw",
     "gov.mv",
-    "is-into-cartoons.com",
-    "lerdal.no",
-    "nisshin.aichi.jp",
-    "ac.ug",
-    "village.museum",
-    "asakawa.fukushima.jp",
-    "gaular.no",
-    "xn--dnna-gra.no",
-    "livinghistory.museum",
-    "yoka.hyogo.jp",
-    "yonabaru.okinawa.jp",
-    "costume.museum",
     "med.sd",
-    "divtasvuodna.no",
-    "mn",
-    "ngo.lk",
-    "xn--rholt-mra.no",
-    "idrett.no",
+    "kosa.kumamoto.jp",
+    "kashima.kumamoto.jp",
+    "neyagawa.osaka.jp",
+    "engineer.aero",
+    "whaling.museum",
+    "market",
+    "noshiro.akita.jp",
+    "wroclaw.pl",
     "med.pro",
-    "zaporizhzhe.ua",
-    "notogawa.shiga.jp",
-    "edu.mv",
+    "idrett.no",
+    "gaular.no",
     "med.ee",
-    "haebaru.okinawa.jp",
-    "katsuura.chiba.jp",
-    "mie.jp",
-    "diamonds",
-    "takaoka.toyama.jp",
-    "network",
-    "rankoshi.hokkaido.jp",
+    "edu.mv",
+    "kunisaki.oita.jp",
+    "historical.museum",
     "mod.uk",
-    "komatsushima.tokushima.jp",
-    "britishcolumbia.museum",
-    "org.sv",
-    "brindisi.it",
-    "ham-radio-op.net",
-    "namikata.ehime.jp",
-    "xn--vler-qoa.hedmark.no",
-    "blogdns.com",
-    "tv.tz",
-    "gifu.gifu.jp",
-    "nesset.no",
-    "lardal.no",
-    "xn--hpmir-xqa.no",
-    "chattanooga.museum",
-    "nagasaki.nagasaki.jp",
-    "goshiki.hyogo.jp",
-    "xn--brnnysund-m8ac.no",
+    "kamioka.akita.jp",
+    "zao.miyagi.jp",
+    "udmurtia.ru",
+    "england.museum",
+    "williamhill",
+    "esan.hokkaido.jp",
+    "hatoyama.saitama.jp",
+    "randaberg.no",
     "g12.br",
-    "higashiizumo.shimane.jp",
-    "naples.it",
-    "washingtondc.museum",
-    "mk",
+    "wada.nagano.jp",
+    "watarai.mie.jp",
+    "kitadaito.okinawa.jp",
+    "nanmoku.gunma.jp",
+    "blogdns.org",
+    "naturalhistorymuseum.museum",
+    "com.gh",
+    "gov.gh",
+    "unsa.ba",
+    "kembuchi.hokkaido.jp",
+    "historisch.museum",
     "mar.it",
-    "judygarland.museum",
-    "iglesiascarbonia.it",
-    "hobby-site.org",
-    "andriatranibarletta.it",
-    "dating",
-    "xn--q9jyb4c",
-    "is-a-democrat.com",
-    "kuromatsunai.hokkaido.jp",
-    "xn--lten-gra.no",
-    "luxe",
-    "kashima.ibaraki.jp",
-    "takaishi.osaka.jp",
-    "hiraizumi.iwate.jp",
-    "carboniaiglesias.it",
-    "bindal.no",
-    "nishihara.kumamoto.jp",
-    "horten.no",
-    "alabama.museum",
-    "vladimir.ru",
-    "ml",
-    "karatsu.saga.jp",
-    "toyonaka.osaka.jp",
-    "tuva.ru",
-    "togo.aichi.jp",
-    "tsaritsyn.ru",
-    "ethnology.museum",
-    "net.lv",
-    "mat.br",
-    "tools",
-    "com.lv",
-    "ushistory.museum",
-    "gov.lv",
+    "mn",
+    "clothing",
+    "bolt.hu",
+    "nasu.tochigi.jp",
+    "izu.shizuoka.jp",
+    "riik.ee",
+    "dynalias.net",
     "motorcycles",
-    "jewishart.museum",
-    "os.hordaland.no",
-    "habmer.no",
-    "kamikawa.hyogo.jp",
-    "beardu.no",
-    "xn--hcesuolo-7ya35b.no",
-    "teledata.mz",
-    "moscow",
-    "mil",
-    "m.se",
+    "network",
+    "mat.br",
+    "edu.gh",
+    "dgca.aero",
     "mq",
-    "hayashima.okayama.jp",
-    "narashino.chiba.jp",
-    "tsukuba.ibaraki.jp",
-    "mol.it",
+    "chicago.museum",
+    "bindal.no",
+    "mil",
+    "kannami.shizuoka.jp",
+    "yokohama",
     "med.br",
-    "xn--od0alg.hk",
     "mil.st",
     "mil.ec",
-    "higashiyama.kyoto.jp",
-    "asahikawa.hokkaido.jp",
+    "isehara.kanagawa.jp",
+    "mol.it",
     "mil.pl",
-    "xn--rady-ira.no",
-    "xn--bidr-5nac.no",
-    "gov.nc.tr",
-    "biz.mv",
-    "kamikawa.hokkaido.jp",
-    "okinoshima.shimane.jp",
-    "iwakuni.yamaguchi.jp",
-    "pe",
-    "etajima.hiroshima.jp",
-    "gamvik.no",
-    "localhistory.museum",
-    "kawasaki.miyagi.jp",
-    "valle-daosta.it",
-    "narvik.no",
-    "edu.lv",
-    "kazimierz-dolny.pl",
-    "qc.com",
-    "int.mv",
-    "ps",
-    "lenvik.no",
-    "bievat.no",
-    "is-into-games.com",
-    "moss.no",
-    "org.mv",
-    "net.sy",
-    "xn--brum-voa.no",
-    "com.sy",
-    "gov.sy",
-    "mh",
-    "kunneppu.hokkaido.jp",
-    "net.py",
-    "higashi.okinawa.jp",
-    "kitahata.saga.jp",
-    "com.py",
-    "kamikitayama.nara.jp",
-    "gov.py",
-    "de.com",
-    "tondabayashi.osaka.jp",
-    "hadsel.no",
-    "mil.al",
-    "mil.ar",
-    "miami",
-    "lindas.no",
-    "mil.ac",
-    "og.it",
-    "bg.it",
-    "test.ru",
-    "higashiyamato.tokyo.jp",
-    "tv.bo",
-    "my",
-    "balsan.it",
-    "wroclaw.pl",
-    "pa",
-    "onomichi.hiroshima.jp",
-    "mil.tw",
-    "edu.sy",
-    "koga.fukuoka.jp",
-    "hurdal.no",
-    "mil.rw",
-    "gotdns.com",
-    "edu.py",
-    "larvik.no",
-    "xn--vegrshei-c0a.no",
-    "xn--54b7fta0cc",
-    "tula.ru",
-    "dr.na",
-    "kuriyama.hokkaido.jp",
-    "med.sa",
-    "nishiarita.saga.jp",
-    "pt",
-    "med.pa",
-    "tjeldsund.no",
-    "asn.lv",
-    "pr",
-    "re.it",
-    "aseral.no",
-    "mw",
-    "nishihara.okinawa.jp",
-    "luster.no",
-    "ro.it",
-    "equipment",
-    "mil.pe",
-    "parts",
-    "halden.no",
-    "rennesoy.no",
-    "hida.gifu.jp",
-    "yamashina.kyoto.jp",
-    "aga.niigata.jp",
-    "buzz",
-    "med.ht",
-    "okinawa.okinawa.jp",
-    "akkeshi.hokkaido.jp",
-    "jetzt",
-    "net.uy",
-    "tg",
-    "com.uy",
-    "yamagata.jp",
-    "is-certified.com",
-    "vv.it",
-    "pub",
-    "nakasatsunai.hokkaido.jp",
-    "homelinux.com",
-    "dyndns-pics.com",
-    "university.museum",
-    "mil.ru",
-    "tv.br",
-    "vinnica.ua",
-    "xn--rlingen-mxa.no",
-    "nomi.ishikawa.jp",
-    "yoshida.shizuoka.jp",
-    "xn--bjddar-pta.no",
-    "xn--brnny-wuac.no",
-    "pm",
-    "mil.ae",
-    "ra.it",
-    "hapmir.no",
-    "loabat.no",
-    "tvedestrand.no",
-    "org.lv",
-    "inuyama.aichi.jp",
-    "net.my",
-    "dlugoleka.pl",
-    "com.my",
-    "gov.my",
-    "name.vn",
-    "vlog.br",
-    "dyndns-ip.com",
-    "xn--lrenskog-54a.no",
-    "anamizu.ishikawa.jp",
-    "xn--krdsherad-m8a.no",
-    "edu.uy",
-    "teo.br",
-    "alvdal.no",
-    "ube.yamaguchi.jp",
-    "valle-d-aosta.it",
-    "ag.it",
-    "detroit.museum",
-    "wakayama.wakayama.jp",
-    "mil.in",
-    "is-a-conservative.com",
-    "krodsherad.no",
-    "is-a-blogger.com",
-    "mil.tj",
-    "kagoshima.kagoshima.jp",
-    "karikatur.museum",
-    "pn",
-    "maison",
-    "orland.no",
-    "reviews",
-    "mail.pl",
-    "desa.id",
-    "mus.br",
-    "edu.my",
-    "mil.br",
-    "kamakura.kanagawa.jp",
-    "equipment.aero",
-    "cloudcontrolled.com",
-    "org.sy",
-    "davvenjarga.no",
-    "org.py",
-    "novara.it",
-    "messina.it",
-    "meraker.no",
-    "me.us",
-    "mil.kr",
-    "tm.mc",
-    "md.us",
-    "anan.tokushima.jp",
-    "msk.ru",
-    "mo.us",
-    "ms.us",
-    "chikujo.fukuoka.jp",
-    "xn--cg4bki",
-    "post",
-    "childrensgarden.museum",
-    "com.by",
-    "rm.it",
-    "gov.by",
-    "kouhoku.saga.jp",
-    "us-east-1.amazonaws.com",
-    "orkdal.no",
-    "iwamizawa.hokkaido.jp",
-    "gub.uy",
-    "mil.id",
-    "yoshikawa.saitama.jp",
-    "ptz.ru",
-    "pk",
-    "beiarn.no",
-    "onga.fukuoka.jp",
-    "nishiwaki.hyogo.jp",
-    "baghdad.museum",
-    "net.ky",
-    "baidar.no",
-    "ullensvang.no",
-    "com.ky",
-    "kushima.miyazaki.jp",
-    "gov.ky",
-    "ro.com",
-    "tinn.no",
-    "kawatana.nagasaki.jp",
-    "xn--55qw42g",
-    "ri.it",
-    "xn--lrdal-sra.no",
-    "chijiwa.nagasaki.jp",
-    "xn--leagaviika-52b.no",
-    "bergbau.museum",
-    "kounosu.saitama.jp",
-    "aeroclub.aero",
-    "emiliaromagna.it",
-    "rn.it",
-    "berlevag.no",
-    "xn--80aswg",
-    "higashimatsuyama.saitama.jp",
-    "ma.us",
-    "pl",
-    "praxi",
-    "is-a-hard-worker.com",
-    "naturbruksgymn.se",
-    "namegata.ibaraki.jp",
-    "eiheiji.fukui.jp",
-    "esan.hokkaido.jp",
-    "net.ly",
-    "kashiwazaki.niigata.jp",
-    "is-a-republican.com",
-    "nogi.tochigi.jp",
-    "com.ly",
-    "gov.ly",
-    "hareid.no",
-    "biei.hokkaido.jp",
-    "edu.ky",
-    "mt.us",
-    "moareke.no",
-    "pink",
-    "info.vn",
-    "p.se",
-    "org.uy",
-    "rockart.museum",
-    "malselv.no",
-    "rawa-maz.pl",
-    "cloudcontrolapp.com",
-    "blogspot.ca",
-    "lebork.pl",
-    "okagaki.fukuoka.jp",
-    "kaneyama.yamagata.jp",
-    "jeonbuk.kr",
-    "pmn.it",
-    "nishikata.tochigi.jp",
-    "chuo.fukuoka.jp",
-    "edu.ly",
-    "elb.amazonaws.com",
-    "kotohira.kagawa.jp",
-    "toyosato.shiga.jp",
-    "yamanakako.yamanashi.jp",
-    "is-a-designer.com",
-    "zoological.museum",
-    "rahkkeravju.no",
-    "betainabox.com",
-    "dnsdojo.org",
-    "tx.us",
-    "org.my",
-    "info.ve",
-    "dnsalias.com",
-    "mil.hn",
-    "amagasaki.hyogo.jp",
-    "mil.iq",
-    "niigata.niigata.jp",
-    "ph",
-    "ppg.br",
-    "decorativearts.museum",
-    "dynalias.com",
-    "doomdns.com",
-    "krakow.pl",
-    "ru.com",
-    "jeonnam.kr",
-    "pila.pl",
-    "me.tz",
-    "academy.museum",
-    "xn--krehamn-dxa.no",
-    "trustee.museum",
-    "kuroiso.tochigi.jp",
-    "kakegawa.shizuoka.jp",
-    "watchandclock.museum",
-    "blogspot.cz",
-    "tsubata.ishikawa.jp",
-    "py",
-    "yuu.yamaguchi.jp",
-    "theater.museum",
-    "hasvik.no",
-    "yuki.ibaraki.jp",
-    "dyndns-free.com",
-    "mv",
-    "nakijin.okinawa.jp",
+    "ml",
+    "roma.it",
+    "med.om",
+    "kumagaya.saitama.jp",
     "date.hokkaido.jp",
-    "algard.no",
-    "mi.us",
-    "dyndns-work.com",
-    "pug.it",
-    "mil.eg",
-    "ochi.kochi.jp",
-    "mn.us",
-    "blogspot.com",
-    "kikugawa.shizuoka.jp",
-    "xn--vads-jra.no",
-    "te.it",
-    "bahccavuotna.no",
-    "mil.az",
-    "tochigi.jp",
-    "to.it",
-    "veterinaire.fr",
-    "xn--od0alg.cn",
-    "pw",
-    "ts.it",
-    "nantan.kyoto.jp",
-    "blogspot.co.nz",
-    "tp.it",
-    "yamanashi.yamanashi.jp",
-    "ms.kr",
-    "bergen.no",
+    "mie.jp",
+    "khmelnytskyi.ua",
+    "akabira.hokkaido.jp",
+    "net.lv",
+    "uy",
+    "mv",
+    "com.lv",
+    "gov.lv",
+    "rennebu.no",
+    "ishikawa.jp",
+    "reviews",
+    "mil.al",
+    "naples.it",
+    "mil.ar",
+    "mil.ac",
+    "mil.tw",
+    "hirakata.osaka.jp",
+    "edu.lv",
+    "med.sa",
+    "divttasvuotna.no",
+    "kiyosato.hokkaido.jp",
+    "zama.kanagawa.jp",
+    "rome.it",
+    "haga.tochigi.jp",
     "m.bg",
-    "per.sg",
-    "rl.no",
-    "mil.tz",
-    "kuji.iwate.jp",
-    "org.ky",
-    "lierne.no",
-    "ishikari.hokkaido.jp",
-    "ninomiya.kanagawa.jp",
-    "tienda",
-    "katashina.gunma.jp",
-    "yusuhara.kochi.jp",
-    "izunokuni.shizuoka.jp",
-    "pub.sa",
-    "kamiizumi.saitama.jp",
-    "bolzano.it",
-    "bamble.no",
-    "kakogawa.hyogo.jp",
-    "alaheadju.no",
+    "mil.rw",
+    "miami",
+    "med.pa",
+    "gov.nc.tr",
+    "katsushika.tokyo.jp",
+    "bergen.no",
+    "uri.arpa",
+    "hiroshima.jp",
+    "exposed",
+    "int.mv",
     "mango",
-    "archaeology.museum",
-    "vc.it",
-    "andebu.no",
-    "blogspot.com.es",
-    "ta.it",
-    "md.ci",
-    "org.ly",
-    "nakagawa.hokkaido.jp",
-    "is-a-guru.com",
-    "xn--bearalvhki-y4a.no",
-    "kimitsu.chiba.jp",
-    "pol.ht",
-    "dyndns-wiki.com",
-    "crew.aero",
-    "xn--vhquv",
-    "pics",
-    "mo.cn",
-    "pescara.it",
-    "github.io",
-    "marketing",
-    "tr.it",
-    "takasago.hyogo.jp",
-    "xn--mgbayh7gpa",
-    "xn--80ao21a",
-    "mil.ba",
-    "kozagawa.wakayama.jp",
-    "mk.ua",
-    "tas.edu.au",
-    "pol.dz",
-    "ishikawa.okinawa.jp",
-    "yonaguni.okinawa.jp",
-    "nishinomiya.hyogo.jp",
-    "ringebu.no",
-    "e12.ve",
-    "xn--bdddj-mrabd.no",
-    "chikugo.fukuoka.jp",
-    "orskog.no",
-    "ide.kyoto.jp",
-    "oirase.aomori.jp",
-    "mil.mg",
-    "psc.br",
-    "massacarrara.it",
-    "chungnam.kr",
-    "modalen.no",
-    "yoro.gifu.jp",
-    "pp.se",
-    "tt.im",
-    "napoli.it",
-    "andria-barletta-trani.it",
-    "biella.it",
-    "kamisunagawa.hokkaido.jp",
-    "tr.no",
-    "hornindal.no",
-    "tateyama.toyama.jp",
-    "jinsekikogen.hiroshima.jp",
-    "mb.ca",
-    "ivano-frankivsk.ua",
-    "is-a-anarchist.com",
-    "publ.pt",
-    "partners",
-    "miyazaki.jp",
-    "higashikawa.hokkaido.jp",
-    "blogspot.co.il",
-    "mil.ng",
-    "kiyokawa.kanagawa.jp",
-    "per.la",
-    "kadogawa.miyazaki.jp",
-    "xn--btsfjord-9za.no",
-    "ogliastra.it",
-    "mil.qa",
-    "kawanishi.hyogo.jp",
-    "ternopil.ua",
-    "blogspot.co.at",
-    "mil.kz",
-    "railway.museum",
-    "tn.it",
-    "blogspot.ch",
-    "kuchinotsu.nagasaki.jp",
-    "blogspot.com.ar",
-    "kijo.miyazaki.jp",
-    "pa.us",
-    "tsurugashima.saitama.jp",
-    "rishiri.hokkaido.jp",
-    "pp.ua",
-    "hvaler.no",
-    "dgca.aero",
-    "kitagawa.miyazaki.jp",
-    "mp.br",
-    "priv.pl",
-    "xn--sandnessjen-ogb.no",
-    "pri.ee",
-    "agrinet.tn",
-    "recipes",
-    "kushimoto.wakayama.jp",
-    "blogspot.com.au",
-    "tm.no",
-    "xn--lesund-hua.no",
-    "pr.us",
-    "omihachiman.shiga.jp",
-    "civilisation.museum",
-    "nakayama.yamagata.jp",
-    "googleapis.com",
-    "mil.kg",
-    "owariasahi.aichi.jp",
-    "magadan.ru",
-    "vinnytsia.ua",
-    "yashiro.hyogo.jp",
-    "blogspot.mx",
-    "lewismiller.museum",
-    "hitachi.ibaraki.jp",
-    "tatsuno.nagano.jp",
-    "psi.br",
-    "potenza",
-    "e164.arpa",
-    "trainer.aero",
-    "niki.hokkaido.jp",
-    "nishinoomote.kagoshima.jp",
-    "kanonji.kagawa.jp",
-    "isa-geek.com",
-    "hanamigawa.chiba.jp",
-    "kopervik.no",
-    "pe.ca",
-    "kikuchi.kumamoto.jp",
-    "pp.az",
-    "varggat.no",
-    "takahagi.ibaraki.jp",
-    "xn--zf0avx.hk",
-    "moskenes.no",
-    "xn--vrggt-xqad.no",
-    "karasuyama.tochigi.jp",
-    "muko.kyoto.jp",
-    "mil.vc",
-    "whoswho",
-    "nishimera.miyazaki.jp",
-    "gonohe.aomori.jp",
-    "tako.chiba.jp",
-    "ine.kyoto.jp",
-    "aridagawa.wakayama.jp",
-    "priv.no",
-    "leangaviika.no",
-    "mc",
-    "kaho.fukuoka.jp",
-    "kawanishi.yamagata.jp",
-    "austevoll.no",
-    "bo.nordland.no",
+    "edunet.tn",
+    "uda.nara.jp",
+    "mil.pe",
+    "iki.nagasaki.jp",
+    "bergbau.museum",
+    "yakutia.ru",
+    "uzhgorod.ua",
+    "bari.it",
     "ito.shizuoka.jp",
-    "rhcloud.com",
-    "lib.ok.us",
-    "lib.or.us",
-    "prd.mg",
-    "lib.dc.us",
-    "kitagawa.kochi.jp",
-    "pe.kr",
-    "tver.ru",
-    "lib.pr.us",
-    "mosjoen.no",
-    "naturhistorisches.museum",
-    "lib.sc.us",
-    "tanohata.iwate.jp",
-    "is-a-photographer.com",
-    "verdal.no",
-    "doesntexist.org",
-    "p.bg",
-    "kamishihoro.hokkaido.jp",
-    "mi.th",
-    "kashima.saga.jp",
-    "blogspot.com.br",
-    "hashimoto.wakayama.jp",
-    "xn--rhqv96g",
-    "k12.vi",
-    "pb.ao",
-    "togakushi.nagano.jp",
-    "nabari.mie.jp",
-    "lib.al.us",
-    "lib.ak.us",
-    "lib.ar.us",
-    "tm.mg",
-    "xn--srum-gra.no",
-    "matsubara.osaka.jp",
-    "mil.ve",
-    "kusatsu.shiga.jp",
-    "achi.nagano.jp",
-    "tsukigata.hokkaido.jp",
-    "lib.tx.us",
-    "toya.hokkaido.jp",
-    "ebiz.tw",
-    "lib.as.us",
-    "lib.sd.us",
-    "kiyose.tokyo.jp",
-    "kadoma.osaka.jp",
-    "chikuhoku.nagano.jp",
-    "yomitan.okinawa.jp",
-    "lib.tn.us",
-    "genova.it",
-    "chikuma.nagano.jp",
-    "blogspot.sg",
-    "lib.ut.us",
-    "aomori.aomori.jp",
-    "lib.de.us",
-    "aomori.jp",
-    "nationalheritage.museum",
-    "troandin.no",
-    "resistance.museum",
-    "xn--aroport-bya.ci",
-    "xn--gjvik-wua.no",
-    "ebetsu.hokkaido.jp",
-    "pp.ru",
-    "yoshimi.saitama.jp",
-    "toyoake.aichi.jp",
-    "toyooka.hyogo.jp",
-    "matta-varjjat.no",
-    "dnsalias.org",
-    "ralingen.no",
-    "dynalias.org",
-    "pl.ua",
-    "xn--czrw28b.tw",
-    "hirogawa.wakayama.jp",
-    "lib.mt.us",
-    "dyndns-at-home.com",
-    "transport.museum",
-    "modelling.aero",
-    "lyngen.no",
-    "is-a-soxfan.org",
-    "aostavalley.it",
-    "kasugai.aichi.jp",
-    "port.fr",
-    "amursk.ru",
-    "lib.mn.us",
-    "kayabe.hokkaido.jp",
+    "asn.lv",
+    "koshigaya.saitama.jp",
+    "yokohama.jp",
+    "namegawa.saitama.jp",
+    "hashikami.aomori.jp",
+    "name.vn",
+    "mil.ae",
+    "info.hu",
+    "hornindal.no",
+    "e12.ve",
+    "gotdns.com",
+    "mil.tj",
+    "indianmarket.museum",
     "ngo.ph",
-    "lib.ms.us",
-    "per.nf",
-    "higashihiroshima.hiroshima.jp",
-    "kuwana.mie.jp",
-    "lib.il.us",
-    "center.museum",
-    "tomi.nagano.jp",
-    "blogspot.gr",
-    "elblag.pl",
-    "ancona.it",
-    "lib.nc.us",
-    "lib.in.us",
-    "tatebayashi.gunma.jp",
-    "tomioka.gunma.jp",
-    "pistoia.it",
-    "fo",
-    "odessa.ua",
-    "net.do",
-    "fj",
-    "katori.chiba.jp",
-    "tokushima.jp",
-    "com.do",
-    "toyohashi.aichi.jp",
-    "gov.do",
-    "net.so",
-    "kouyama.kagoshima.jp",
-    "net.jo",
-    "com.so",
+    "kai.yamanashi.jp",
+    "asti.it",
+    "hamatama.saga.jp",
+    "indianapolis.museum",
+    "hatsukaichi.hiroshima.jp",
+    "balsan.it",
+    "ve",
+    "kanazawa.ishikawa.jp",
+    "kutchan.hokkaido.jp",
+    "mk",
+    "nikolaev.ua",
+    "mil.in",
+    "vet",
+    "kure.hiroshima.jp",
+    "kuki.saitama.jp",
+    "etajima.hiroshima.jp",
+    "mil.br",
+    "nesset.no",
+    "katagami.akita.jp",
+    "mh",
+    "decorativearts.museum",
+    "godo.gifu.jp",
+    "worse-than.tv",
+    "yura.wakayama.jp",
+    "alvdal.no",
+    "naka.ibaraki.jp",
+    "voto",
+    "andriabarlettatrani.it",
+    "chungnam.kr",
+    "kumenan.okayama.jp",
+    "detroit.museum",
+    "kumejima.okinawa.jp",
+    "mil.id",
+    "yasu.shiga.jp",
+    "niikappu.hokkaido.jp",
+    "horten.no",
+    "gyeongbuk.kr",
+    "va",
+    "kamisato.saitama.jp",
+    "nonoichi.ishikawa.jp",
+    "qld.edu.au",
+    "moscow",
+    "m.se",
+    "habmer.no",
+    "kashima.ibaraki.jp",
+    "wolomin.pl",
+    "vote",
+    "desa.id",
+    "chernigov.ua",
+    "kyotango.kyoto.jp",
+    "mil.tm",
+    "walbrzych.pl",
+    "himi.toyama.jp",
+    "vu",
+    "med.ht",
+    "is-a-hunter.com",
+    "anjo.aichi.jp",
+    "ama.shimane.jp",
+    "moss.no",
+    "vegas",
+    "koga.fukuoka.jp",
+    "rockart.museum",
+    "yatsushiro.kumamoto.jp",
+    "mil.vc",
+    "ringebu.no",
+    "dyndns-free.com",
+    "mw",
+    "novara.it",
+    "evenes.no",
+    "khmelnitskiy.ua",
+    "honbetsu.hokkaido.jp",
+    "hadsel.no",
+    "krakow.pl",
+    "arai.shizuoka.jp",
+    "gyeongnam.kr",
+    "yasuoka.nagano.jp",
+    "narusawa.yamanashi.jp",
+    "yoshida.saitama.jp",
+    "hurdal.no",
+    "info.vn",
+    "gifu.gifu.jp",
+    "aya.miyazaki.jp",
+    "aseral.no",
+    "noto.ishikawa.jp",
+    "vi",
+    "gdansk.pl",
+    "ven.it",
+    "halden.no",
+    "is-a-knight.org",
+    "bashkiria.ru",
+    "ivano-frankivsk.ua",
+    "vda.it",
+    "kushiro.hokkaido.jp",
+    "royrvik.no",
+    "nishitosa.kochi.jp",
+    "andria-trani-barletta.it",
+    "amsterdam.museum",
+    "vet.br",
+    "alto-adige.it",
+    "kamikawa.saitama.jp",
+    "mil.ve",
+    "algard.no",
+    "maison",
+    "yabu.hyogo.jp",
+    "naie.hokkaido.jp",
+    "austrheim.no",
+    "recipes",
+    "meraker.no",
+    "mail.pl",
+    "karatsu.saga.jp",
+    "hatogaya.saitama.jp",
+    "vn",
+    "katsuragi.wakayama.jp",
+    "vega.no",
+    "hemnes.no",
+    "vodka",
+    "ivanovo.ru",
+    "hapmir.no",
+    "mus.br",
+    "kvinesdal.no",
+    "mil.ba",
+    "ena.gifu.jp",
+    "beiarn.no",
+    "berlevag.no",
+    "giehtavuoatna.no",
+    "mil.kr",
+    "baidar.no",
+    "yekaterinburg.ru",
+    "bamble.no",
+    "vaga.no",
+    "kimobetsu.hokkaido.jp",
+    "kaga.ishikawa.jp",
+    "mil.hn",
+    "chattanooga.museum",
+    "kashima.saga.jp",
+    "modalen.no",
+    "chikuma.nagano.jp",
+    "baghdad.museum",
+    "kusatsu.gunma.jp",
+    "himeshima.oita.jp",
+    "emilia-romagna.it",
+    "hvaler.no",
+    "kijo.miyazaki.jp",
+    "nantan.kyoto.jp",
+    "nosegawa.nara.jp",
+    "nesoddtangen.no",
+    "chikusei.ibaraki.jp",
+    "nirasaki.yamanashi.jp",
+    "magadan.ru",
     "kyotamba.kyoto.jp",
-    "com.jo",
-    "gov.jo",
-    "ryugasaki.ibaraki.jp",
-    "tsukumi.oita.jp",
-    "lib.md.us",
-    "nationalfirearms.museum",
-    "verran.no",
-    "gob.do",
-    "hamada.shimane.jp",
-    "yame.fukuoka.jp",
-    "koshimizu.hokkaido.jp",
-    "iwafune.tochigi.jp",
-    "kunigami.okinawa.jp",
-    "se",
-    "blogspot.cv",
-    "sd",
-    "nagara.chiba.jp",
+    "kurgan.ru",
+    "mil.qa",
+    "ug",
+    "v.bg",
+    "villas",
+    "carboniaiglesias.it",
+    "messina.it",
+    "genova.it",
+    "alstahaug.no",
+    "hareid.no",
+    "embetsu.hokkaido.jp",
+    "info.ve",
+    "ginowan.okinawa.jp",
+    "kamiamakusa.kumamoto.jp",
+    "inagawa.hyogo.jp",
+    "aosta-valley.it",
+    "kaho.fukuoka.jp",
+    "kobayashi.miyazaki.jp",
+    "yonabaru.okinawa.jp",
+    "haibara.shizuoka.jp",
+    "drobak.no",
+    "izunokuni.shizuoka.jp",
+    "wiki",
+    "kashihara.nara.jp",
+    "homeunix.org",
+    "cesena-forli.it",
+    "inashiki.ibaraki.jp",
+    "mil.eg",
+    "my",
+    "crew.aero",
+    "mil.iq",
+    "e164.arpa",
+    "chitose.hokkaido.jp",
+    "iwanuma.miyagi.jp",
+    "museum",
+    "rakkestad.no",
+    "vao.it",
+    "komatsu.ishikawa.jp",
+    "groundhandling.aero",
+    "vercelli.it",
+    "center.museum",
+    "hachijo.tokyo.jp",
+    "nishinoshima.shimane.jp",
+    "notogawa.shiga.jp",
+    "marketing",
+    "moareke.no",
+    "mil.km",
+    "motorcycle.museum",
+    "murmansk.ru",
+    "aibetsu.hokkaido.jp",
+    "vang.no",
+    "rahkkeravju.no",
+    "biella.it",
+    "niigata.niigata.jp",
+    "kui.hiroshima.jp",
     "garden.museum",
-    "so",
-    "sj",
-    "soy",
+    "chuo.fukuoka.jp",
+    "asakawa.fukushima.jp",
+    "massacarrara.it",
+    "mil.mg",
+    "dyndns-work.com",
+    "chernihiv.ua",
+    "wakayama.jp",
+    "hamamatsu.shizuoka.jp",
+    "amursk.ru",
+    "kopervik.no",
+    "gushikami.okinawa.jp",
+    "ueda.nagano.jp",
+    "akiruno.tokyo.jp",
+    "unbi.ba",
+    "voss.no",
+    "mragowo.pl",
+    "miyazaki.jp",
+    "valle-aosta.it",
+    "malselv.no",
+    "yoshimi.saitama.jp",
+    "yamagata.jp",
+    "wiki.br",
+    "gdynia.pl",
+    "railway.museum",
+    "eiheiji.fukui.jp",
+    "hida.gifu.jp",
+    "horokanai.hokkaido.jp",
+    "github.io",
+    "berlin.museum",
+    "valleeaoste.it",
+    "estate.museum",
+    "karikatur.museum",
+    "nogi.tochigi.jp",
+    "homelinux.net",
+    "historicalsociety.museum",
+    "mil.ng",
+    "kharkiv.ua",
+    "doesntexist.org",
+    "valledaosta.it",
+    "e-burg.ru",
+    "viterbo.it",
+    "karate.museum",
+    "nature.museum",
+    "baikal.ru",
+    "kitahata.saga.jp",
+    "ventures",
+    "bauern.museum",
+    "nagasaki.nagasaki.jp",
+    "kikonai.hokkaido.jp",
+    "magnitka.ru",
+    "hobby-site.org",
+    "abashiri.hokkaido.jp",
+    "akishima.tokyo.jp",
+    "vennesla.no",
+    "brasil.museum",
+    "kvinnherad.no",
+    "chichibu.saitama.jp",
+    "chernivtsi.ua",
+    "crafts.museum",
+    "kamijima.ehime.jp",
+    "kamiichi.toyama.jp",
+    "hachirogata.akita.jp",
+    "kouhoku.saga.jp",
+    "resistance.museum",
+    "whoswho",
+    "iglesiascarbonia.it",
+    "nichinan.miyazaki.jp",
+    "k12.vi",
+    "celtic.museum",
+    "dnsalias.org",
+    "civilaviation.aero",
+    "dyndns-wiki.com",
+    "brunel.museum",
+    "komatsushima.tokushima.jp",
+    "kasumigaura.ibaraki.jp",
+    "rankoshi.hokkaido.jp",
+    "yoro.gifu.jp",
     "mx",
-    "lib.me.us",
+    "canada.museum",
+    "malbork.pl",
+    "glogow.pl",
+    "kongsvinger.no",
+    "date.fukushima.jp",
+    "aogashima.tokyo.jp",
+    "red.sv",
+    "naka.hiroshima.jp",
+    "mobi",
+    "usa.oita.jp",
+    "monash",
+    "nagara.chiba.jp",
+    "circus.museum",
     "xxx",
+    "austevoll.no",
+    "higashiyoshino.nara.jp",
+    "emiliaromagna.it",
+    "higashiosaka.osaka.jp",
+    "mil.az",
+    "georgia.museum",
+    "naturbruksgymn.se",
+    "katashina.gunma.jp",
+    "mil.tz",
+    "alaheadju.no",
+    "mobi.na",
+    "koenig.ru",
+    "aoki.nagano.jp",
+    "vallee-aoste.it",
+    "british-library.uk",
+    "marburg.museum",
+    "andriatranibarletta.it",
+    "homelinux.org",
+    "gonohe.aomori.jp",
+    "kushima.miyazaki.jp",
+    "royken.no",
+    "minnesota.museum",
+    "koshimizu.hokkaido.jp",
+    "nishimera.miyazaki.jp",
+    "mil.kg",
+    "modelling.aero",
+    "valled-aosta.it",
+    "dallas.museum",
+    "ancona.it",
+    "moskenes.no",
+    "higashiizu.shizuoka.jp",
+    "kadoma.osaka.jp",
+    "urakawa.hokkaido.jp",
+    "uscountryestate.museum",
+    "kitaaiki.nagano.jp",
+    "media",
+    "mg",
+    "matsubara.osaka.jp",
+    "biei.hokkaido.jp",
+    "voronezh.ru",
+    "boston.museum",
+    "elblag.pl",
+    "yame.fukuoka.jp",
+    "kuromatsunai.hokkaido.jp",
+    "vinnica.ua",
+    "dynalias.org",
+    "izumozaki.niigata.jp",
+    "mini",
+    "is-a-linux-user.org",
+    "mobi.ng",
+    "kinokawa.wakayama.jp",
+    "rindal.no",
+    "ryokami.saitama.jp",
+    "vindafjord.no",
+    "nishiarita.saga.jp",
+    "crimea.ua",
+    "hakusan.ishikawa.jp",
+    "ushuaia.museum",
+    "namegata.ibaraki.jp",
+    "higashiizumo.shimane.jp",
+    "hokkaido.jp",
+    "wakkanai.hokkaido.jp",
+    "gangaviika.no",
+    "vlog.br",
+    "childrensgarden.museum",
+    "valleaosta.it",
+    "namikata.ehime.jp",
+    "napoli.it",
+    "mobi.tz",
+    "yoka.hyogo.jp",
+    "gwangju.kr",
+    "karuizawa.nagano.jp",
+    "hellas.museum",
+    "mil.sh",
+    "aioi.hyogo.jp",
+    "nationalheritage.museum",
+    "hayakawa.yamanashi.jp",
+    "matsudo.chiba.jp",
+    "mil.ph",
+    "mine.nu",
+    "cinema.museum",
+    "yoshida.shizuoka.jp",
+    "verbania.it",
+    "viajes",
+    "higashimatsuyama.saitama.jp",
+    "habikino.osaka.jp",
+    "muko.kyoto.jp",
+    "kimitsu.chiba.jp",
+    "drangedal.no",
+    "hamada.shimane.jp",
+    "kanonji.kagawa.jp",
+    "haebaru.okinawa.jp",
+    "civilization.museum",
+    "kyuragi.saga.jp",
+    "agrinet.tn",
+    "vestnes.no",
+    "hannan.osaka.jp",
+    "vald-aosta.it",
+    "jogasz.hu",
+    "ureshino.mie.jp",
+    "nationalfirearms.museum",
+    "mari-el.ru",
+    "kamikawa.hokkaido.jp",
+    "kitanakagusuku.okinawa.jp",
+    "amagasaki.hyogo.jp",
+    "unjarga.no",
+    "nishikatsura.yamanashi.jp",
+    "asahikawa.hokkaido.jp",
+    "kushimoto.wakayama.jp",
+    "vladimir.ru",
+    "virtuel.museum",
+    "mil.gt",
+    "kitakata.miyazaki.jp",
+    "kurashiki.okayama.jp",
+    "monticello.museum",
+    "civilisation.museum",
+    "wielun.pl",
+    "kani.gifu.jp",
+    "gotdns.org",
+    "mil.kz",
+    "vaksdal.no",
+    "nishihara.kumamoto.jp",
+    "venezia.it",
+    "se",
+    "mosjoen.no",
+    "sd",
+    "so",
+    "soy",
+    "ushistory.museum",
+    "ishikawa.okinawa.jp",
+    "goshiki.hyogo.jp",
+    "chonan.chiba.jp",
+    "gujo.gifu.jp",
+    "ralingen.no",
+    "austin.museum",
+    "engineering",
+    "mil.ge",
+    "kitayama.wakayama.jp",
+    "kudoyama.wakayama.jp",
+    "sa",
+    "midsund.no",
+    "yoshikawa.saitama.jp",
+    "macerata.it",
+    "st",
+    "nishikata.tochigi.jp",
+    "higashi.okinawa.jp",
+    "kagawa.jp",
+    "ishikari.hokkaido.jp",
+    "sr",
+    "katori.chiba.jp",
+    "jinsekikogen.hiroshima.jp",
+    "su",
+    "chikujo.fukuoka.jp",
+    "higashiyama.kyoto.jp",
+    "sz",
+    "kami.miyagi.jp",
+    "castle.museum",
+    "aomori.aomori.jp",
+    "numata.gunma.jp",
+    "namerikawa.toyama.jp",
+    "kagoshima.kagoshima.jp",
+    "aga.niigata.jp",
+    "virtual.museum",
+    "ragusa.it",
+    "sj",
+    "aomori.jp",
+    "daisen.akita.jp",
+    "kashiwazaki.niigata.jp",
+    "nabari.mie.jp",
+    "sm",
+    "nachikatsuura.wakayama.jp",
+    "vestre-toten.no",
+    "nishiizu.shizuoka.jp",
+    "matsumoto.nagano.jp",
+    "vg",
+    "mo-i-rana.no",
+    "nomi.ishikawa.jp",
+    "chungbuk.kr",
+    "volkenkunde.museum",
+    "kuchinotsu.nagasaki.jp",
+    "kayabe.hokkaido.jp",
+    "yamashina.kyoto.jp",
+    "archaeology.museum",
+    "si",
+    "uryu.hokkaido.jp",
+    "is-a-soxfan.org",
+    "warmia.pl",
+    "raholt.no",
+    "mobi.tt",
+    "mobi.gp",
+    "matta-varjjat.no",
+    "vacations",
+    "kuji.iwate.jp",
+    "sb",
+    "nishiawakura.okayama.jp",
+    "elburg.museum",
+    "solar",
+    "kiyose.tokyo.jp",
+    "kumiyama.kyoto.jp",
+    "rifu.miyagi.jp",
+    "wegrow.pl",
+    "vevelstad.no",
+    "stat.no",
+    "sund.no",
+    "kusatsu.shiga.jp",
+    "sar.it",
+    "sn",
+    "numata.hokkaido.jp",
+    "kamikawa.hyogo.jp",
+    "sola.no",
+    "kurobe.toyama.jp",
+    "kuriyama.hokkaido.jp",
+    "voyage",
+    "rollag.no",
+    "kamikitayama.nara.jp",
+    "yamanashi.yamanashi.jp",
+    "srv.br",
+    "volgograd.ru",
+    "aostavalley.it",
+    "christiansburg.museum",
+    "sl",
+    "kakegawa.shizuoka.jp",
+    "saga.jp",
+    "sec.ps",
+    "sv",
+    "vestvagoy.no",
+    "nishiazai.shiga.jp",
+    "sohu",
+    "hashimoto.wakayama.jp",
+    "is-saved.org",
+    "mima.tokushima.jp",
+    "ryugasaki.ibaraki.jp",
+    "kitagata.saga.jp",
+    "avoues.fr",
+    "sula.no",
+    "alaska.museum",
+    "kadogawa.miyazaki.jp",
+    "discovery.museum",
+    "agematsu.nagano.jp",
+    "missile.museum",
+    "ueno.gunma.jp",
+    "kiyokawa.kanagawa.jp",
+    "higashiyamato.tokyo.jp",
+    "kikugawa.shizuoka.jp",
+    "dyndns.tv",
+    "s.bg",
+    "nagoya.jp",
+    "kaneyama.yamagata.jp",
+    "durham.museum",
+    "ujitawara.kyoto.jp",
+    "aejrie.no",
+    "hayashima.okayama.jp",
+    "chikuhoku.nagano.jp",
+    "kitagawa.miyazaki.jp",
+    "kanegasaki.iwate.jp",
+    "fo",
+    "nakasatsunai.hokkaido.jp",
+    "net.so",
+    "net.do",
+    "com.so",
+    "noheji.aomori.jp",
+    "com.do",
+    "gov.do",
+    "stranda.no",
+    "hasama.oita.jp",
+    "gliwice.pl",
+    "gob.do",
+    "rishiri.hokkaido.jp",
+    "kaluga.ru",
+    "moroyama.saitama.jp",
+    "kyonan.chiba.jp",
+    "kosaka.akita.jp",
+    "hanggliding.aero",
+    "vladikavkaz.ru",
+    "mito.ibaraki.jp",
+    "vologda.ru",
+    "yonezawa.yamagata.jp",
+    "avocat.fr",
     "edu.do",
-    "xn--bmlo-gra.no",
-    "lib.id.us",
+    "yamanakako.yamanashi.jp",
+    "fan",
     "camp",
     "farm",
-    "watch-and-clock.museum",
-    "nishigo.fukushima.jp",
-    "london.museum",
-    "kani.gifu.jp",
-    "edu.jo",
-    "malbork.pl",
-    "lib.nd.us",
-    "chigasaki.kanagawa.jp",
-    "lib.ks.us",
-    "yonezawa.yamagata.jp",
-    "mobi",
-    "trogstad.no",
-    "hitachinaka.ibaraki.jp",
-    "numata.hokkaido.jp",
-    "taka.hyogo.jp",
-    "hinode.tokyo.jp",
+    "sos.pl",
+    "nakagawa.hokkaido.jp",
     "fam.pk",
-    "tsurugi.ishikawa.jp",
-    "dyndns-at-work.com",
-    "monash",
-    "fr",
-    "adygeya.ru",
     "net.to",
-    "company",
+    "fr",
+    "sk",
     "com.to",
-    "wegrow.pl",
     "gov.to",
-    "higashitsuno.kochi.jp",
-    "lib.ne.us",
-    "sa",
-    "com.ro",
-    "wielun.pl",
-    "mil.cl",
-    "nom.ro",
-    "kozaki.chiba.jp",
-    "rikuzentakata.iwate.jp",
-    "numazu.shizuoka.jp",
-    "hasama.oita.jp",
-    "lib.nj.us",
-    "varese.it",
-    "st",
-    "landes.museum",
-    "mil.cn",
-    "yoshinogari.saga.jp",
-    "sr",
-    "lib.pa.us",
-    "kawazu.shizuoka.jp",
-    "mobi.na",
-    "baikal.ru",
-    "groundhandling.aero",
-    "porsangu.no",
-    "mobi.ng",
-    "gujo.gifu.jp",
-    "edu.to",
+    "chijiwa.nagasaki.jp",
+    "nishihara.okinawa.jp",
+    "yomitan.okinawa.jp",
     "karlsoy.no",
+    "kitahiroshima.hokkaido.jp",
+    "company",
+    "com.ro",
+    "sh",
+    "hiraizumi.iwate.jp",
+    "exeter.museum",
+    "nom.ro",
+    "saltdal.no",
+    "dvrdns.org",
+    "bahcavuotna.no",
+    "kotohira.kagawa.jp",
+    "edu.to",
+    "fj",
+    "ayagawa.kagawa.jp",
+    "ashibetsu.hokkaido.jp",
+    "ninomiya.kanagawa.jp",
+    "quebec.museum",
+    "net.jo",
     "fm",
-    "su",
-    "teshikaga.hokkaido.jp",
-    "rennebu.no",
-    "mito.ibaraki.jp",
-    "berlin.museum",
+    "yamagata.ibaraki.jp",
+    "com.jo",
+    "gov.jo",
+    "hasuda.saitama.jp",
     "net.mo",
+    "s.se",
     "com.mo",
     "gov.mo",
-    "kaszuby.pl",
-    "nishiizu.shizuoka.jp",
-    "sz",
-    "tatsuno.hyogo.jp",
-    "matsudo.chiba.jp",
+    "matsuda.kanagawa.jp",
     "kesennuma.miyagi.jp",
-    "yamagata.ibaraki.jp",
-    "nagoya.jp",
-    "higashi.fukuoka.jp",
-    "hekinan.aichi.jp",
-    "murmansk.ru",
-    "heguri.nara.jp",
-    "motorcycle.museum",
-    "chieti.it",
+    "wassamu.hokkaido.jp",
+    "niki.hokkaido.jp",
+    "kunigami.okinawa.jp",
+    "edu.jo",
     "fi",
-    "sm",
-    "jogasz.hu",
     "higashiomi.shiga.jp",
-    "langevag.no",
-    "higashiura.aichi.jp",
-    "higashisumiyoshi.osaka.jp",
-    "com.io",
-    "training",
-    "estate.museum",
-    "assabu.hokkaido.jp",
+    "anamizu.ishikawa.jp",
     "fin.ec",
-    "kurobe.toyama.jp",
-    "divttasvuotna.no",
-    "tv.it",
-    "yokaichiba.chiba.jp",
     "edu.mo",
-    "org.do",
-    "kagawa.jp",
-    "paderborn.museum",
-    "trentino.it",
-    "org.so",
-    "boston.museum",
-    "rc.it",
-    "org.jo",
-    "toei.aichi.jp",
-    "nakagawa.tokushima.jp",
-    "nature.museum",
-    "e-burg.ru",
-    "si",
-    "dreamhosters.com",
-    "kujukuri.chiba.jp",
-    "karate.museum",
+    "kamishihoro.hokkaido.jp",
+    "soc.lk",
+    "com.io",
     "art.do",
-    "sn",
-    "hamura.tokyo.jp",
-    "spb.ru",
-    "brasil.museum",
-    "labour.museum",
-    "mini",
+    "salerno.it",
     "fed.us",
+    "chikugo.fukuoka.jp",
+    "slg.br",
     "net.bo",
-    "bauern.museum",
+    "fst.br",
     "com.bo",
     "gov.bo",
     "fot.br",
-    "fst.br",
-    "lib.az.us",
-    "olkusz.pl",
-    "fk",
-    "toyokawa.aichi.jp",
-    "sumy.ua",
-    "gob.bo",
-    "osteroy.no",
-    "kongsvinger.no",
-    "lib.ma.us",
-    "sos.pl",
-    "sb",
-    "tv.im",
-    "isa-geek.org",
-    "xn--9dbhblg6di.museum",
-    "crafts.museum",
-    "lom.no",
-    "lib.ri.us",
-    "solar",
-    "christiansburg.museum",
-    "tobetsu.hokkaido.jp",
-    "umbria.it",
-    "stv.ru",
-    "edu.bo",
-    "kofu.yamanashi.jp",
-    "sk",
-    "sar.it",
-    "accident-prevention.aero",
-    "jorpeland.no",
-    "org.to",
-    "kitami.hokkaido.jp",
-    "tabayama.yamanashi.jp",
-    "fin.tn",
-    "org.ro",
-    "lib.ia.us",
-    "far.br",
-    "takazaki.miyazaki.jp",
-    "mragowo.pl",
-    "med.om",
-    "pisa.it",
-    "celtic.museum",
-    "sund.no",
-    "stat.no",
-    "firm.ro",
-    "fie.ee",
-    "f.se",
-    "firm.co",
-    "xn--aurskog-hland-jnb.no",
-    "urausu.hokkaido.jp",
-    "sl",
-    "luzern.museum",
-    "blogspot.co.uk",
-    "tv.na",
-    "louvre.museum",
-    "gol.no",
-    "sola.no",
-    "kaizuka.osaka.jp",
-    "lib.mi.us",
-    "warmia.pl",
-    "tsushima.aichi.jp",
-    "cieszyn.pl",
-    "xn--ggaviika-8ya47h.no",
-    "higashimurayama.tokyo.jp",
-    "esashi.hokkaido.jp",
-    "ketrzyn.pl",
-    "xn--trgstad-r1a.no",
-    "canada.museum",
-    "s.se",
-    "org.mo",
-    "yokosuka.kanagawa.jp",
-    "xn--rst-0na.no",
-    "tsuyama.okayama.jp",
-    "srv.br",
-    "circus.museum",
-    "xn--smna-gra.no",
-    "hellas.museum",
-    "xn--pgbs0dh",
-    "takatsuki.osaka.jp",
-    "mine.nu",
-    "edunet.tn",
-    "mil.sh",
-    "tsugaru.aomori.jp",
-    "is-a-linux-user.org",
-    "verona.it",
-    "ayagawa.kagawa.jp",
-    "mil.ph",
-    "bifuka.hokkaido.jp",
-    "mg",
-    "kurgan.ru",
-    "kitagata.saga.jp",
-    "snz.ru",
-    "sh",
-    "saga.jp",
-    "lib.la.us",
-    "sec.ps",
-    "lunner.no",
-    "xn--rdy-0nab.no",
-    "kosaka.akita.jp",
-    "ferrara.it",
-    "kvinesdal.no",
-    "odawara.kanagawa.jp",
-    "priv.at",
-    "perm.ru",
-    "firm.nf",
-    "atsuma.hokkaido.jp",
-    "ohtawara.tochigi.jp",
-    "int.bo",
-    "wassamu.hokkaido.jp",
-    "sy",
-    "org.bo",
-    "sula.no",
-    "hamaroy.no",
-    "hasuda.saitama.jp",
-    "futbol",
-    "xn--sr-odal-q1a.no",
-    "moroyama.saitama.jp",
-    "arq.br",
-    "hemnes.no",
-    "civilization.museum",
-    "kamiamakusa.kumamoto.jp",
-    "gangaviika.no",
-    "georgia.museum",
-    "paris",
-    "nt.edu.au",
-    "higashichichibu.saitama.jp",
-    "marburg.museum",
-    "laquila.it",
-    "fusa.no",
-    "iwanuma.miyagi.jp",
-    "tamamura.gunma.jp",
-    "tsumagoi.gunma.jp",
-    "mizusawa.iwate.jp",
-    "kvinnherad.no",
-    "xn--givuotna-8ya.no",
-    "tateshina.nagano.jp",
-    "fhv.se",
-    "hof.no",
-    "gjovik.no",
-    "stranda.no",
-    "eid.no",
-    "chikuho.fukuoka.jp",
-    "computer",
-    "noheji.aomori.jp",
-    "ashibetsu.hokkaido.jp",
-    "williamsburg.museum",
-    "xn--lhppi-xqa.no",
-    "crimea.ua",
-    "city.yokohama.jp",
-    "fnd.br",
-    "control.aero",
-    "hiratsuka.kanagawa.jp",
-    "deatnu.no",
-    "red.sv",
-    "hol.no",
-    "inderoy.no",
-    "nagasu.kumamoto.jp",
-    "lib.vt.us",
-    "wazuka.kyoto.jp",
-    "folldal.no",
-    "bjarkoy.no",
-    "mobi.tt",
-    "adachi.tokyo.jp",
-    "lib.wa.us",
-    "lib.hi.us",
-    "vossevangen.no",
-    "blogdns.org",
-    "tsuruga.fukui.jp",
-    "mobi.gp",
-    "xn--3bst00m",
-    "macerata.it",
-    "voagat.no",
-    "pvt.k12.ma.us",
-    "pomorze.pl",
-    "takehara.hiroshima.jp",
-    "hitachiomiya.ibaraki.jp",
-    "ota.tokyo.jp",
-    "xn--stjrdal-s1a.no",
-    "rikubetsu.hokkaido.jp",
-    "kouzushima.tokyo.jp",
-    "stavern.no",
-    "tsubetsu.hokkaido.jp",
-    "mil.tm",
-    "hidaka.hokkaido.jp",
-    "sd.us",
-    "chuo.yamanashi.jp",
-    "slattum.no",
-    "royken.no",
-    "matsuda.kanagawa.jp",
-    "matsuzaki.shizuoka.jp",
-    "uji.kyoto.jp",
-    "servebbs.net",
-    "mari-el.ru",
-    "austin.museum",
-    "lib.wi.us",
-    "kamagaya.chiba.jp",
-    "pro",
-    "web.do",
-    "eidskog.no",
-    "xn--sknland-fxa.no",
-    "higashiyodogawa.osaka.jp",
-    "prod",
-    "castle.museum",
-    "gliwice.pl",
-    "pro.ec",
-    "hanggliding.aero",
-    "ome.tokyo.jp",
-    "pro.pr",
-    "gotdns.org",
-    "soc.lk",
-    "podhale.pl",
-    "national-library-scotland.uk",
-    "saltdal.no",
-    "plumbing",
-    "salerno.it",
-    "slg.br",
-    "dyndns-blog.com",
-    "wakasa.tottori.jp",
-    "murakami.niigata.jp",
-    "xn--dyry-ira.no",
-    "campobasso.it",
-    "moseushi.hokkaido.jp",
-    "cf",
-    "bf",
-    "gf",
-    "ifm",
-    "cinema.museum",
-    "nf",
-    "machida.tokyo.jp",
-    "gdansk.pl",
-    "me.it",
-    "takahama.aichi.jp",
-    "higashi.fukushima.jp",
-    "com.fr",
-    "flakstad.no",
-    "mo.it",
-    "aejrie.no",
-    "vanylven.no",
-    "nom.fr",
-    "ms.it",
-    "mil.gt",
-    "aizumi.tokushima.jp",
-    "oksnes.no",
-    "rindal.no",
-    "toshima.tokyo.jp",
-    "nishiazai.shiga.jp",
-    "nishikawa.yamagata.jp",
-    "aioi.hyogo.jp",
-    "museum",
-    "pro.tt",
-    "hidaka.saitama.jp",
-    "pg",
-    "sic.it",
-    "trolley.museum",
-    "net.gy",
-    "com.gy",
-    "marketplace.aero",
-    "nakagawa.nagano.jp",
-    "omotego.fukushima.jp",
-    "sld.pa",
-    "services",
-    "hitachiota.ibaraki.jp",
-    "co.pn",
-    "writesthisblog.com",
-    "gokase.miyazaki.jp",
-    "kamogawa.chiba.jp",
-    "kannami.shizuoka.jp",
-    "mil.km",
-    "mo-i-rana.no",
-    "yugawara.kanagawa.jp",
-    "yawata.kyoto.jp",
-    "ichikawa.hyogo.jp",
-    "mt.it",
-    "joboji.iwate.jp",
-    "sv",
-    "sa.au",
-    "sondrio.it",
-    "kanegasaki.iwate.jp",
-    "health.vn",
-    "sohu",
-    "f.bg",
-    "eidfjord.no",
-    "quebec.museum",
-    "muroran.hokkaido.jp",
-    "suzuki",
-    "monticello.museum",
-    "sm.ua",
-    "elburg.museum",
-    "xn--hgebostad-g3a.no",
-    "sassari.it",
-    "af",
-    "mil.ge",
-    "rg.it",
-    "kumamoto.jp",
-    "tranibarlettaandria.it",
-    "trentino-stirol.it",
-    "konskowola.pl",
-    "yamakita.kanagawa.jp",
-    "takahashi.okayama.jp",
-    "numata.gunma.jp",
-    "latina.it",
-    "oregon.museum",
-    "fish",
-    "naoshima.kagawa.jp",
-    "s.bg",
-    "sauherad.no",
-    "kostroma.ru",
-    "sa.cr",
-    "xn--hylandet-54a.no",
-    "appspot.com",
-    "campidanomedio.it",
-    "fukuoka.jp",
-    "solutions",
-    "takasaki.gunma.jp",
-    "kemerovo.ru",
-    "fj.cn",
-    "co.pl",
-    "trani-andria-barletta.it",
-    "mr.no",
-    "lib.va.us",
-    "fl.us",
-    "ishigaki.okinawa.jp",
-    "fareast.ru",
-    "uslivinghistory.museum",
-    "preservation.museum",
-    "nakagusuku.okinawa.jp",
-    "matsushige.tokushima.jp",
-    "pro.br",
-    "fuel.aero",
-    "midsund.no",
-    "archaeological.museum",
-    "mi.it",
-    "plo.ps",
-    "sd.cn",
-    "hawaii.museum",
-    "usarts.museum",
-    "mod.gi",
-    "mn.it",
-    "sb.ua",
-    "lib.ct.us",
-    "trentinosudtirol.it",
-    "prof.pr",
-    "kumatori.osaka.jp",
-    "sondre-land.no",
-    "missile.museum",
-    "miho.ibaraki.jp",
-    "mashiki.kumamoto.jp",
-    "kunohe.iwate.jp",
-    "sells-for-u.com",
-    "sells-it.net",
-    "oamishirasato.chiba.jp",
-    "mb.it",
-    "fh.se",
-    "fi.cr",
-    "vladivostok.ru",
-    "mima.tokushima.jp",
-    "oita.oita.jp",
-    "iglesias-carbonia.it",
-    "lib.vi.us",
-    "firm.in",
-    "trentino-s-tirol.it",
-    "photo",
-    "tachikawa.tokyo.jp",
-    "alaska.museum",
-    "saga.saga.jp",
-    "kiyosu.aichi.jp",
-    "trentinostirol.it",
-    "krasnoyarsk.ru",
-    "gwangju.kr",
-    "usui.fukuoka.jp",
-    "midtre-gauldal.no",
-    "dyn-o-saur.com",
-    "corporation.museum",
-    "tokashiki.okinawa.jp",
-    "photos",
-    "prd.km",
-    "warabi.saitama.jp",
-    "ninohe.iwate.jp",
-    "services.aero",
-    "kawachinagano.osaka.jp",
-    "kawaba.gunma.jp",
-    "hikawa.shimane.jp",
-    "television.museum",
-    "fyresdal.no",
-    "otoineppu.hokkaido.jp",
-    "campania.it",
-    "pro.ht",
-    "sk.ca",
-    "ne.pw",
-    "is-saved.org",
-    "webhop.biz",
-    "co.pw",
-    "go.pw",
-    "my.id",
-    "soka.saitama.jp",
-    "student.aero",
-    "takamatsu.kagawa.jp",
-    "trentino-suedtirol.it",
-    "oizumi.gunma.jp",
-    "ed.pw",
-    "evenes.no",
-    "pe.it",
-    "yachimata.chiba.jp",
-    "johana.toyama.jp",
-    "pd.it",
-    "doomdns.org",
-    "po.it",
-    "kusu.oita.jp",
-    "xn--i1b6b1a6a2e",
-    "trentinoaadige.it",
-    "trentino-sudtirol.it",
-    "fvg.it",
-    "yamada.toyama.jp",
-    "fishing",
-    "trentino-sud-tirol.it",
-    "wa.edu.au",
-    "joetsu.niigata.jp",
-    "ragusa.it",
-    "trysil.no",
-    "sn.cn",
-    "trentinos-tirol.it",
-    "mykolaiv.ua",
-    "or.pw",
-    "rollag.no",
-    "pro.az",
-    "trentinosuedtirol.it",
-    "pruszkow.pl",
-    "trentinosued-tirol.it",
-    "pa.it",
-    "date.fukushima.jp",
-    "midatlantic.museum",
-    "nago.okinawa.jp",
-    "asso.nc",
-    "net.co",
-    "hannan.osaka.jp",
-    "onna.okinawa.jp",
-    "sor-odal.no",
-    "com.co",
-    "gov.co",
-    "siellak.no",
-    "nom.co",
-    "kalisz.pl",
-    "fredrikstad.no",
-    "fm.br",
-    "pt.it",
-    "fhsk.se",
-    "chungbuk.kr",
-    "pr.it",
-    "industries",
-    "miyashiro.saitama.jp",
-    "hita.oita.jp",
-    "bremanger.no",
-    "sc",
-    "agrigento.it",
-    "spydeberg.no",
-    "info.ec",
-    "homeftp.net",
-    "pu.it",
-    "minamata.kumamoto.jp",
-    "pro.na",
-    "scb",
-    "airport.aero",
-    "palermo.it",
-    "edu.co",
-    "gratangen.no",
-    "lib.oh.us",
-    "travel.tt",
-    "pz.it",
-    "jpn.com",
-    "sevastopol.ua",
-    "sardinia.it",
-    "minami-alps.yamanashi.jp",
-    "trani-barletta-andria.it",
-    "xn--1qqw23a",
-    "yokote.akita.jp",
-    "nagatoro.saitama.jp",
-    "medecin.km",
-    "sebastopol.ua",
-    "kami.miyagi.jp",
-    "gdynia.pl",
-    "mashike.hokkaido.jp",
-    "takaharu.miyazaki.jp",
-    "limanowa.pl",
-    "tynset.no",
-    "philately.museum",
-    "kasamatsu.gifu.jp",
-    "unazuki.toyama.jp",
-    "annaka.gunma.jp",
-    "lib.ca.us",
-    "www.ro",
-    "pi.it",
-    "ballangen.no",
-    "batsfjord.no",
-    "xn--avery-yua.no",
-    "sado.niigata.jp",
-    "pn.it",
-    "campidano-medio.it",
-    "trentino-sued-tirol.it",
-    "ivanovo.ru",
-    "sandnes.no",
-    "off.ai",
-    "zachpomor.pl",
-    "xn--czrs0t",
-    "sh.cn",
-    "suedtirol.it",
-    "otsuki.yamanashi.jp",
-    "saarland",
-    "magnitka.ru",
-    "aerodrome.aero",
-    "kvafjord.no",
-    "yokoze.saitama.jp",
-    "is-a-musician.com",
-    "mediocampidano.it",
-    "miyazaki.miyazaki.jp",
-    "aquila.it",
-    "minamiyamashiro.kyoto.jp",
-    "sortland.no",
-    "narita.chiba.jp",
-    "agematsu.nagano.jp",
-    "takayama.gunma.jp",
-    "gojome.akita.jp",
-    "perugia.it",
-    "sandefjord.no",
-    "tsuchiura.ibaraki.jp",
-    "usenet.pl",
-    "setouchi.okayama.jp",
-    "xn--ldingen-q1a.no",
-    "int.co",
-    "kvitsoy.no",
-    "wf",
-    "timekeeping.museum",
-    "kasama.ibaraki.jp",
-    "trentinosud-tirol.it",
-    "org.co",
-    "if.ua",
-    "inazawa.aichi.jp",
-    "onjuku.chiba.jp",
-    "gemological.museum",
-    "is-a-financialadvisor.com",
-    "agriculture.museum",
-    "tamatsukuri.ibaraki.jp",
-    "tokushima.tokushima.jp",
-    "farmstead.museum",
-    "uchihara.ibaraki.jp",
-    "tsushima.nagasaki.jp",
-    "komaki.aichi.jp",
-    "aurskog-holand.no",
-    "xn--ygarden-p1a.no",
-    "lib.nh.us",
-    "balsfjord.no",
-    "mibu.tochigi.jp",
-    "is-a-celticsfan.org",
-    "colonialwilliamsburg.museum",
-    "exhibition.museum",
-    "utsira.no",
-    "contractors",
-    "kisarazu.chiba.jp",
-    "exeter.museum",
-    "firenze.it",
-    "xn--rmskog-bya.no",
-    "xn--io0a7i",
-    "flesberg.no",
-    "dyndns.tv",
-    "conference.aero",
-    "sowa.ibaraki.jp",
-    "nerima.tokyo.jp",
-    "suwa.nagano.jp",
-    "flekkefjord.no",
-    "sx",
-    "nf.ca",
-    "xn--mgbbh1a71e",
-    "bomlo.no",
-    "pro.vn",
-    "pyatigorsk.ru",
-    "takayama.nagano.jp",
-    "travel.pl",
-    "piacenza.it",
-    "minamiboso.chiba.jp",
-    "nanporo.hokkaido.jp",
-    "sardegna.it",
-    "filatelia.museum",
-    "czest.pl",
-    "greta.fr",
-    "higashikagura.hokkaido.jp",
-    "productions",
-    "seto.aichi.jp",
-    "matsukawa.nagano.jp",
-    "bialowieza.pl",
-    "bahcavuotna.no",
-    "vantaa.museum",
-    "toon.ehime.jp",
-    "eidsvoll.no",
-    "kagami.kochi.jp",
-    "yanaizu.fukushima.jp",
-    "echizen.fukui.jp",
-    "kokonoe.oita.jp",
-    "vyatka.ru",
-    "suwalki.pl",
-    "stuttgart.museum",
-    "kanzaki.saga.jp",
-    "webhop.org",
-    "tateyama.chiba.jp",
-    "lib.nm.us",
-    "notaires.fr",
-    "takikawa.hokkaido.jp",
-    "minnesota.museum",
-    "mari.ru",
-    "salangen.no",
+    "chieti.it",
+    "sunndal.no",
     "foo",
     "coop",
-    "tysvar.no",
-    "minamiizu.shizuoka.jp",
-    "motoyama.kochi.jp",
-    "kahoku.ishikawa.jp",
-    "genoa.it",
-    "portlligat.museum",
-    "priv.me",
-    "nakadomari.aomori.jp",
-    "miyoshi.saitama.jp",
-    "traniandriabarletta.it",
-    "ostrowiec.pl",
-    "vaapste.no",
-    "coop.py",
-    "hammerfest.no",
-    "bruxelles.museum",
-    "sakhalin.ru",
-    "lib.gu.us",
-    "sakurai.nara.jp",
-    "xn--gmqw5a.hk",
-    "zamami.okinawa.jp",
-    "geisei.kochi.jp",
-    "coop.km",
-    "raholt.no",
-    "bardu.no",
-    "siedlce.pl",
-    "yamagata.nagano.jp",
-    "laspezia.it",
-    "kitamoto.saitama.jp",
-    "moka.tochigi.jp",
-    "ginoza.okinawa.jp",
-    "brunel.museum",
-    "matsumoto.nagano.jp",
-    "higashiagatsuma.gunma.jp",
-    "xn--ryrvik-bya.no",
-    "toyotsu.fukuoka.jp",
-    "pvt.ge",
-    "kirovograd.ua",
-    "oxford.museum",
-    "musashino.tokyo.jp",
-    "barum.no",
-    "koenig.ru",
-    "servebbs.com",
-    "kitakyushu.jp",
-    "health.museum",
-    "herad.no",
-    "gaivuotna.no",
-    "zagan.pl",
-    "frei.no",
-    "kanuma.tochigi.jp",
-    "is-uberleet.com",
-    "shimane.jp",
-    "shacknet.nu",
-    "sor-aurdal.no",
-    "kudamatsu.yamaguchi.jp",
-    "is-with-theband.com",
-    "yamada.iwate.jp",
-    "mobi.tz",
-    "asnes.no",
-    "brussels.museum",
-    "kibichuo.okayama.jp",
-    "xn--hmmrfeasta-s4ac.no",
-    "lindesnes.no",
-    "ono.hyogo.jp",
-    "iiyama.nagano.jp",
-    "galsa.no",
-    "okazaki.aichi.jp",
-    "kaluga.ru",
-    "genkai.saga.jp",
-    "saku.nagano.jp",
-    "cuneo.it",
-    "otsuki.kochi.jp",
-    "adult.ht",
-    "iizuna.nagano.jp",
-    "daisen.akita.jp",
-    "matsubushi.saitama.jp",
-    "obu.aichi.jp",
-    "leikanger.no",
-    "kadena.okinawa.jp",
-    "balat.no",
-    "himeji.hyogo.jp",
-    "indian.museum",
-    "naklo.pl",
-    "xn--lgbbat1ad8j",
-    "ichikawamisato.yamanashi.jp",
-    "southwest.museum",
-    "salvadordali.museum",
-    "gunma.jp",
-    "palmsprings.museum",
-    "ama.aichi.jp",
-    "sc.us",
-    "natori.miyagi.jp",
-    "biratori.hokkaido.jp",
-    "immobilien",
+    "gob.bo",
+    "marnardal.no",
+    "kamiizumi.saitama.jp",
+    "sogndal.no",
+    "sic.it",
+    "kunohe.iwate.jp",
+    "akkeshi.hokkaido.jp",
     "chosei.chiba.jp",
-    "santacruz.museum",
-    "incheon.kr",
-    "svalbard.no",
-    "aogaki.hyogo.jp",
-    "glogow.pl",
-    "fuso.aichi.jp",
-    "xn--sr-varanger-ggb.no",
-    "naha.okinawa.jp",
-    "osaka.jp",
-    "web.co",
-    "dep.no",
-    "sg",
-    "hirara.okinawa.jp",
-    "bozen.it",
-    "kiyama.saga.jp",
-    "larsson.museum",
-    "dallas.museum",
-    "zarow.pl",
-    "loten.no",
-    "urasoe.okinawa.jp",
-    "planetarium.museum",
-    "towada.aomori.jp",
-    "hamar.no",
-    "coop.br",
-    "soni.nara.jp",
-    "rifu.miyagi.jp",
-    "yoichi.hokkaido.jp",
-    "orsta.no",
-    "kherson.ua",
-    "chambagri.fr",
-    "newspaper.museum",
-    "consultant.aero",
-    "busan.kr",
-    "pv.it",
-    "bytom.pl",
-    "iki.fi",
-    "xn--fl-zia.no",
-    "hidaka.kochi.jp",
-    "tanabe.kyoto.jp",
-    "mc.it",
-    "social",
-    "fuefuki.yamanashi.jp",
-    "newport.museum",
-    "fuossko.no",
-    "mombetsu.hokkaido.jp",
-    "lib.ga.us",
-    "toho.fukuoka.jp",
-    "vik.no",
-    "haram.no",
-    "maebashi.gunma.jp",
-    "aoste.it",
-    "ako.hyogo.jp",
-    "tozsde.hu",
-    "higashimatsushima.miyagi.jp",
-    "cultural.museum",
-    "tobishima.aichi.jp",
-    "bungoono.oita.jp",
-    "namdalseid.no",
-    "toyama.jp",
-    "tosashimizu.kochi.jp",
-    "discovery.museum",
-    "halsa.no",
-    "chihayaakasaka.osaka.jp",
-    "odate.akita.jp",
-    "ac.pa",
-    "hurum.no",
-    "hammarfeasta.no",
-    "sc.tz",
-    "shakotan.hokkaido.jp",
-    "yufu.oita.jp",
-    "kumamoto.kumamoto.jp",
-    "yamazoe.nara.jp",
-    "journalist.aero",
-    "forsand.no",
-    "leirfjord.no",
-    "minakami.gunma.jp",
-    "naroy.no",
-    "ac.pr",
-    "handson.museum",
-    "sorreisa.no",
-    "aosta.it",
-    "dazaifu.fukuoka.jp",
-    "bristol.museum",
-    "naamesjevuemie.no",
-    "giske.no",
-    "wodzislaw.pl",
-    "minamifurano.hokkaido.jp",
-    "jerusalem.museum",
-    "berkeley.museum",
-    "obanazawa.yamagata.jp",
-    "gulen.no",
-    "aarborte.no",
-    "fetsund.no",
-    "sc.kr",
-    "kakuda.miyagi.jp",
-    "nagawa.nagano.jp",
-    "xn--mot-tla.no",
-    "xn--hobl-ira.no",
-    "a.prod.fastly.net",
-    "hobol.no",
-    "tome.miyagi.jp",
-    "mitsuke.niigata.jp",
-    "kita.osaka.jp",
-    "hotel.lk",
-    "lecce.it",
-    "sorfold.no",
-    "insurance.aero",
+    "nishinoomote.kagoshima.jp",
     "kainan.tokushima.jp",
-    "yamagata.yamagata.jp",
-    "online.museum",
-    "is-a-cubicle-slave.com",
-    "lecco.it",
-    "akashi.hyogo.jp",
-    "serveftp.net",
-    "takatsuki.shiga.jp",
-    "cartoonart.museum",
-    "togane.chiba.jp",
-    "xn--fiqz9s",
-    "of.by",
-    "iwanai.hokkaido.jp",
-    "sandnessjoen.no",
-    "from-la.net",
-    "ogawara.miyagi.jp",
-    "farsund.no",
-    "omachi.nagano.jp",
-    "tyumen.ru",
-    "hachioji.tokyo.jp",
-    "morotsuka.miyazaki.jp",
-    "uonuma.niigata.jp",
-    "itoigawa.niigata.jp",
-    "sc.cn",
-    "american.museum",
-    "creation.museum",
-    "myphotos.cc",
-    "from-ny.net",
-    "minamioguni.kumamoto.jp",
-    "xn--sr-fron-q1a.no",
-    "southcarolina.museum",
-    "luroy.no",
-    "coop.tt",
-    "iide.yamagata.jp",
-    "skedsmo.no",
-    "sch.uk",
-    "iwate.jp",
-    "miyoshi.hiroshima.jp",
-    "ryokami.saitama.jp",
-    "ardal.no",
-    "ashikaga.tochigi.jp",
-    "fe.it",
-    "gangwon.kr",
-    "starnberg.museum",
+    "hinode.tokyo.jp",
+    "vision",
+    "mod.gi",
+    "edu.bo",
+    "mibu.tochigi.jp",
+    "heguri.nara.jp",
+    "coop.py",
+    "far.br",
+    "fin.tn",
+    "vicenza.it",
+    "sld.pa",
+    "nakagawa.tokushima.jp",
+    "coop.km",
+    "health.vn",
+    "naoshima.kagawa.jp",
+    "nishiwaki.hyogo.jp",
+    "mediocampidano.it",
+    "fie.ee",
+    "sells-for-u.com",
+    "yashiro.hyogo.jp",
+    "midtre-gauldal.no",
+    "chigasaki.kanagawa.jp",
+    "firm.ro",
+    "firm.co",
+    "narita.chiba.jp",
+    "murakami.niigata.jp",
+    "muroran.hokkaido.jp",
+    "ninohe.iwate.jp",
+    "johana.toyama.jp",
+    "yoshinogari.saga.jp",
+    "aquila.it",
+    "sandnes.no",
+    "jorpeland.no",
+    "gojome.akita.jp",
+    "agrigento.it",
+    "miyashiro.saitama.jp",
+    "gol.no",
+    "hamura.tokyo.jp",
+    "miho.ibaraki.jp",
+    "f.bg",
+    "annaka.gunma.jp",
+    "usenet.pl",
+    "rikuzentakata.iwate.jp",
     "shoes",
-    "ustka.pl",
-    "miyoshi.tokushima.jp",
-    "sci.eg",
-    "teaches-yoga.com",
-    "xn--flor-jra.no",
-    "nebraska.museum",
-    "firm.ht",
-    "matsushima.miyagi.jp",
-    "nose.osaka.jp",
-    "philadelphia.museum",
-    "simbirsk.ru",
-    "helsinki.museum",
-    "gs.aa.no",
+    "hidaka.saitama.jp",
+    "futbol",
+    "arq.br",
+    "bifuka.hokkaido.jp",
+    "itoigawa.niigata.jp",
+    "iwamizawa.hokkaido.jp",
+    "skedsmo.no",
+    "atsuma.hokkaido.jp",
+    "firm.nf",
+    "control.aero",
+    "fuossko.no",
+    "folldal.no",
+    "vic.edu.au",
+    "sells-it.net",
+    "sandefjord.no",
+    "kakogawa.hyogo.jp",
+    "coop.br",
+    "surnadal.no",
+    "indian.museum",
+    "int.bo",
+    "nakaniikawa.toyama.jp",
+    "vinnytsia.ua",
+    "voting",
+    "mandal.no",
+    "fk",
+    "dep.no",
+    "from-la.net",
+    "higashihiroshima.hiroshima.jp",
+    "mari.ru",
+    "mombetsu.hokkaido.jp",
+    "yuki.ibaraki.jp",
+    "higashikawa.hokkaido.jp",
+    "inderoy.no",
+    "sy",
+    "from-ny.net",
+    "valle-daosta.it",
+    "sondre-land.no",
+    "meldal.no",
+    "marker.no",
+    "eid.no",
+    "higashi.fukuoka.jp",
+    "fnd.br",
+    "itoman.okinawa.jp",
+    "veterinaire.km",
+    "matsumoto.kagoshima.jp",
+    "f.se",
     "from-ky.com",
     "from-tx.com",
-    "hagebostad.no",
     "from-wy.com",
+    "mashiki.kumamoto.jp",
     "from-pa.com",
-    "hitra.no",
-    "ambulance.aero",
-    "from-wa.com",
-    "yawara.ibaraki.jp",
-    "gs.st.no",
-    "nahari.kochi.jp",
-    "gs.mr.no",
     "from-ca.com",
-    "xn--fiqs8s",
-    "fineart.museum",
-    "so.it",
-    "annefrank.museum",
-    "computerhistory.museum",
-    "ss.it",
-    "jan-mayen.no",
-    "tamayu.shimane.jp",
-    "koryo.nara.jp",
-    "sp.it",
-    "kamisu.ibaraki.jp",
-    "assisi.museum",
-    "sch.ae",
-    "misconfused.org",
-    "mil.gh",
-    "tamaki.mie.jp",
+    "from-wa.com",
     "from-co.net",
-    "sunndal.no",
-    "xn--io0a7i.hk",
+    "sauherad.no",
+    "health.museum",
+    "miyoshi.saitama.jp",
+    "village.museum",
+    "minamata.kumamoto.jp",
+    "coop.mw",
     "from-nm.com",
-    "trentino-aadige.it",
-    "sch.ir",
-    "dyndns.biz",
-    "asmatart.museum",
-    "hembygdsforbund.museum",
-    "gs.tr.no",
-    "hotel.tz",
-    "omachi.saga.jp",
-    "sogndal.no",
-    "choshi.chiba.jp",
-    "hiraya.nagano.jp",
-    "farmers.museum",
-    "romskog.no",
-    "gs.va.no",
-    "kharkov.ua",
-    "isahaya.nagasaki.jp",
-    "stjordal.no",
-    "nanto.toyama.jp",
-    "fr.it",
-    "sosa.chiba.jp",
-    "matsuura.nagasaki.jp",
-    "asker.no",
-    "hikone.shiga.jp",
-    "sa.it",
-    "ariake.saga.jp",
-    "wake.okayama.jp",
-    "se.net",
-    "lucca.it",
-    "air-traffic-control.aero",
-    "klabu.no",
-    "lesja.no",
-    "rishirifuji.hokkaido.jp",
-    "singles",
-    "artcenter.museum",
-    "hikimi.shimane.jp",
-    "ookuwa.nagano.jp",
-    "moriyama.shiga.jp",
-    "gs.tm.no",
-    "pc.it",
-    "chiryu.aichi.jp",
-    "sr.it",
-    "tomari.hokkaido.jp",
-    "snillfjord.no",
-    "folkebibl.no",
-    "konan.aichi.jp",
-    "servebbs.org",
-    "chuo.osaka.jp",
-    "from-pr.com",
-    "oshima.tokyo.jp",
-    "chernovtsy.ua",
-    "xn--kvfjord-nxa.no",
-    "rec.ro",
-    "sch.id",
-    "fm.it",
-    "pro.om",
-    "city.kobe.jp",
-    "takahata.yamagata.jp",
-    "savannahga.museum",
-    "naumburg.museum",
-    "mandal.no",
-    "matsumoto.kagoshima.jp",
-    "lowicz.pl",
-    "mino.gifu.jp",
-    "xn--80asehdb",
-    "hakuba.nagano.jp",
-    "sch.lk",
-    "takasu.hokkaido.jp",
-    "kazan.ru",
-    "upow.gov.pl",
-    "culturalcenter.museum",
-    "columbia.museum",
-    "mx.na",
-    "xn--fiq64b",
-    "tattoo",
-    "bykle.no",
-    "yachiyo.chiba.jp",
-    "taishin.fukushima.jp",
-    "fi.it",
-    "xn--vgsy-qoa0j.no",
-    "shriram",
-    "taketa.oita.jp",
-    "st.no",
-    "living.museum",
-    "zakopane.pl",
-    "from-nj.com",
-    "kuju.oita.jp",
-    "games.hu",
-    "svelvik.no",
-    "se.com",
-    "santabarbara.museum",
-    "drobak.no",
-    "ruovat.no",
-    "sch.sa",
-    "gs.fm.no",
-    "asuke.aichi.jp",
-    "nakagyo.kyoto.jp",
-    "marker.no",
-    "otake.hiroshima.jp",
-    "kraanghke.no",
-    "yatomi.aichi.jp",
-    "andoy.no",
-    "surnadal.no",
-    "meldal.no",
-    "si.it",
-    "fm.no",
-    "cci.fr",
-    "karumai.iwate.jp",
-    "xn--jrpeland-54a.no",
-    "yasuda.kochi.jp",
-    "yachiyo.ibaraki.jp",
-    "altoadige.it",
-    "stordal.no",
-    "sx.cn",
-    "kuban.ru",
-    "kurate.fukuoka.jp",
-    "handa.aichi.jp",
-    "lukow.pl",
-    "mantova.it",
-    "maibara.shiga.jp",
-    "nanae.hokkaido.jp",
-    "gs.ol.no",
-    "stalowa-wola.pl",
-    "takashima.shiga.jp",
-    "eastcoast.museum",
-    "sa.com",
-    "kamikoani.akita.jp",
-    "sayo.hyogo.jp",
-    "kursk.ru",
-    "oystre-slidre.no",
-    "izumiotsu.osaka.jp",
+    "iiyama.nagano.jp",
     "dyndns.ws",
-    "sells-for-less.com",
-    "aukra.no",
-    "kasukabe.saitama.jp",
-    "neues.museum",
-    "cadaques.museum",
-    "toyama.toyama.jp",
-    "kurume.fukuoka.jp",
-    "nore-og-uvdal.no",
-    "from-nh.com",
-    "jamal.ru",
-    "xn--vestvgy-ixa6o.no",
-    "xn--mgberp4a5d4ar",
-    "tsuwano.shimane.jp",
-    "watari.miyagi.jp",
-    "fukusaki.hyogo.jp",
-    "oryol.ru",
-    "karpacz.pl",
-    "mugi.tokushima.jp",
-    "from-ri.com",
-    "from-wi.com",
-    "guernsey.museum",
-    "shirako.chiba.jp",
-    "gloppen.no",
-    "minamiminowa.nagano.jp",
-    "kosuge.yamanashi.jp",
-    "tsubame.niigata.jp",
-    "gs.ah.no",
-    "hokuryu.hokkaido.jp",
-    "space-to-rent.com",
-    "fylkesbibl.no",
-    "botanical.museum",
-    "baseball.museum",
-    "kanan.osaka.jp",
-    "askoy.no",
-    "ehime.jp",
-    "seljord.no",
-    "shiksha",
-    "akaiwa.okayama.jp",
-    "from-tn.com",
-    "funahashi.toyama.jp",
-    "porsgrunn.no",
-    "from-al.com",
-    "sokndal.no",
-    "kunst.museum",
-    "bible.museum",
-    "bjugn.no",
-    "tokigawa.saitama.jp",
-    "tonami.toyama.jp",
-    "kawai.nara.jp",
-    "koeln.museum",
-    "kanoya.kagoshima.jp",
-    "nanbu.tottori.jp",
-    "furubira.hokkaido.jp",
-    "inami.toyama.jp",
-    "nasushiobara.tochigi.jp",
-    "is-a-geek.net",
-    "keisen.fukuoka.jp",
-    "sibenik.museum",
-    "gs.bu.no",
-    "entomology.museum",
-    "priv.hu",
-    "hattfjelldal.no",
-    "philadelphiaarea.museum",
-    "arteducation.museum",
-    "spiegel",
-    "house.museum",
-    "ikeda.osaka.jp",
-    "arkhangelsk.ru",
-    "xn--mgba3a4f16a",
-    "ikata.ehime.jp",
-    "izumi.osaka.jp",
-    "from-ne.com",
-    "venice.it",
-    "minamiaiki.nagano.jp",
-    "trentinoa-adige.it",
-    "honjo.akita.jp",
-    "labor.museum",
-    "xn--mgba3a4fra",
-    "taxi.br",
-    "akita.jp",
-    "from-ia.com",
-    "from-wv.com",
-    "karmoy.no",
-    "from-il.com",
-    "ichikawa.chiba.jp",
-    "gs.rl.no",
-    "meland.no",
-    "sherbrooke.museum",
-    "from-nv.com",
-    "trentino-a-adige.it",
-    "csiro.au",
-    "hasami.nagasaki.jp",
-    "children.museum",
-    "scientist.aero",
-    "from-ar.com",
-    "mil.mv",
-    "nogata.fukuoka.jp",
-    "saitama.jp",
-    "malvik.no",
-    "honai.ehime.jp",
-    "vegarshei.no",
-    "glass.museum",
-    "from-ga.com",
-    "kochi.jp",
-    "oketo.hokkaido.jp",
-    "from-de.com",
-    "from-ct.com",
-    "kawara.fukuoka.jp",
-    "nagi.okayama.jp",
-    "mosvik.no",
-    "toki.gifu.jp",
-    "vardo.no",
-    "fortmissoula.museum",
-    "xn--tjme-hra.no",
-    "xn--frya-hra.no",
-    "xn--xhq521b",
-    "boutique",
-    "russia.museum",
-    "ikeda.hokkaido.jp",
-    "historichouses.museum",
-    "sch.ng",
-    "automotive.museum",
-    "xn--io0a7i.cn",
-    "noboribetsu.hokkaido.jp",
-    "sch.qa",
-    "medecin.fr",
-    "komae.tokyo.jp",
-    "altai.ru",
-    "shimabara.nagasaki.jp",
-    "naval.museum",
-    "tomisato.chiba.jp",
-    "ichihara.chiba.jp",
-    "is-a-geek.org",
-    "freemasonry.museum",
-    "gs.hm.no",
-    "from-ut.com",
-    "foundation",
-    "sasayama.hyogo.jp",
-    "from-ak.com",
-    "xn--nvuotna-hwa.no",
-    "shirosato.ibaraki.jp",
-    "xn--hnefoss-q1a.no",
-    "xn--snase-nra.no",
-    "nord-odal.no",
-    "kahoku.yamagata.jp",
-    "ulsan.kr",
-    "natuurwetenschappen.museum",
+    "fvg.it",
+    "fhv.se",
+    "mantova.it",
+    "computer",
+    "campobasso.it",
+    "joboji.iwate.jp",
+    "kitami.hokkaido.jp",
+    "sardinia.it",
+    "hamaroy.no",
+    "ishigaki.okinawa.jp",
+    "student.aero",
+    "kasamatsu.gifu.jp",
+    "siellak.no",
+    "sevastopol.ua",
+    "yamada.toyama.jp",
+    "stordal.no",
+    "sebastopol.ua",
+    "from-pr.com",
+    "sassari.it",
+    "fail",
     "dyndns.org",
-    "iitate.fukushima.jp",
-    "hidaka.wakayama.jp",
-    "north.museum",
-    "miyoshi.aichi.jp",
-    "ambulance.museum",
-    "is-a-caterer.com",
-    "dell-ogliastra.it",
-    "ohkura.yamagata.jp",
-    "obuse.nagano.jp",
-    "usgarden.museum",
-    "suzu.ishikawa.jp",
-    "santafe.museum",
-    "ohi.fukui.jp",
-    "vadso.no",
-    "presse.ci",
-    "bibai.hokkaido.jp",
-    "botanicgarden.museum",
-    "otaru.hokkaido.jp",
-    "ainan.ehime.jp",
-    "sano.tochigi.jp",
-    "flights",
-    "kaita.hiroshima.jp",
-    "taishi.osaka.jp",
-    "yahaba.iwate.jp",
-    "asso.mc",
-    "hiroo.hokkaido.jp",
-    "oharu.aichi.jp",
-    "tonosho.kagawa.jp",
-    "lakas.hu",
-    "xn--tysvr-vra.no",
-    "mil.lv",
-    "itoman.okinawa.jp",
-    "valle.no",
-    "can.museum",
-    "shimane.shimane.jp",
-    "textile.museum",
-    "luxury",
-    "nishiokoppe.hokkaido.jp",
-    "heroy.nordland.no",
-    "volda.no",
-    "kiryu.gunma.jp",
-    "oskol.ru",
-    "drangedal.no",
-    "hotel.hu",
-    "okaya.nagano.jp",
-    "aisai.aichi.jp",
-    "amber.museum",
-    "epilepsy.museum",
-    "trentino-altoadige.it",
-    "nakanoto.ishikawa.jp",
-    "ayabe.kyoto.jp",
-    "marnardal.no",
-    "sera.hiroshima.jp",
-    "ikeda.nagano.jp",
-    "minamimaki.nagano.jp",
-    "ullensaker.no",
-    "usuki.oita.jp",
-    "kanra.gunma.jp",
-    "murayama.yamagata.jp",
-    "pittsburgh.museum",
-    "florist",
-    "fukushima.jp",
-    "beeldengeluid.museum",
-    "mil.sy",
-    "mil.py",
-    "mielec.pl",
-    "sanfrancisco.museum",
-    "baths.museum",
-    "scot",
-    "iizuka.fukuoka.jp",
-    "belau.pw",
-    "gs.hl.no",
-    "burghof.museum",
-    "yuza.yamagata.jp",
-    "matera.it",
-    "mochizuki.nagano.jp",
-    "skedsmokorset.no",
-    "bandai.fukushima.jp",
-    "newjersey.museum",
-    "rimini.it",
-    "valdaosta.it",
-    "nes.buskerud.no",
-    "oseto.nagasaki.jp",
-    "xn--rsta-fra.no",
-    "vefsn.no",
-    "trapani.it",
-    "chiba.jp",
-    "yuzawa.niigata.jp",
-    "yamatotakada.nara.jp",
-    "siracusa.it",
-    "yasugi.shimane.jp",
-    "akita.akita.jp",
-    "odesa.ua",
-    "oyabe.toyama.jp",
-    "otaki.nagano.jp",
-    "oceanographic.museum",
-    "nrw.museum",
-    "tromsa.no",
-    "xn--mgba3a4f16a.ir",
-    "med.ly",
-    "yamatokoriyama.nara.jp",
-    "hitoyoshi.kumamoto.jp",
-    "shikabe.hokkaido.jp",
-    "laakesvuemie.no",
-    "pg.it",
-    "sshn.se",
-    "xn--mgba3a4fra.ir",
-    "melhus.no",
-    "yasaka.nagano.jp",
-    "shibata.miyagi.jp",
-    "tochigi.tochigi.jp",
-    "opole.pl",
-    "erimo.hokkaido.jp",
-    "daejeon.kr",
-    "trondheim.no",
-    "spjelkavik.no",
-    "sicilia.it",
-    "from-in.com",
-    "kepno.pl",
-    "cyber.museum",
-    "marche.it",
-    "project.museum",
-    "xn--kvnangen-k0a.no",
-    "ozu.ehime.jp",
-    "xn--fjord-lra.no",
-    "ovre-eiker.no",
-    "inatsuki.fukuoka.jp",
-    "tadotsu.kagawa.jp",
-    "tf",
-    "of.no",
-    "asahi.toyama.jp",
-    "shimoji.okinawa.jp",
-    "suginami.tokyo.jp",
-    "mil.uy",
-    "mutsuzawa.chiba.jp",
-    "konin.pl",
-    "art.museum",
-    "from-ks.com",
-    "institute",
-    "aichi.jp",
-    "miki.hyogo.jp",
-    "jewish.museum",
-    "from-fl.com",
-    "flog.br",
-    "xn--slt-elab.no",
-    "minamidaito.okinawa.jp",
-    "sv.it",
-    "otari.nagano.jp",
-    "trentinoalto-adige.it",
-    "likes-pie.com",
-    "windmill.museum",
-    "basel.museum",
-    "chita.ru",
-    "vagan.no",
-    "kariya.aichi.jp",
-    "rzeszow.pl",
-    "mil.my",
-    "mordovia.ru",
-    "chita.aichi.jp",
-    "avoues.fr",
-    "iruma.saitama.jp",
-    "photography",
-    "xn--frna-woa.no",
-    "omaha.museum",
-    "modena.it",
-    "stargard.pl",
-    "semboku.akita.jp",
-    "shichinohe.aomori.jp",
-    "kinko.kagoshima.jp",
-    "shimokitayama.nara.jp",
-    "medical.museum",
-    "k12.ok.us",
-    "k12.or.us",
-    "hachinohe.aomori.jp",
-    "kutno.pl",
-    "k12.dc.us",
-    "trentino-alto-adige.it",
-    "k12.pr.us",
-    "homeftp.org",
-    "izumi.kagoshima.jp",
+    "kalisz.pl",
+    "flakstad.no",
+    "fusa.no",
+    "misconfused.org",
+    "gripe",
+    "nishigo.fukushima.jp",
+    "matsubushi.saitama.jp",
+    "nakagawa.nagano.jp",
+    "saga.saga.jp",
+    "from-nj.com",
+    "hirogawa.wakayama.jp",
+    "valle-d-aosta.it",
+    "ferrara.it",
+    "rikubetsu.hokkaido.jp",
+    "yamada.iwate.jp",
+    "wakasa.tottori.jp",
+    "machida.tokyo.jp",
+    "muosat.no",
+    "aridagawa.wakayama.jp",
     "k12.sc.us",
-    "phoenix.museum",
-    "kirov.ru",
-    "kaisei.kanagawa.jp",
-    "bus.museum",
-    "sobetsu.hokkaido.jp",
-    "iheya.okinawa.jp",
-    "air.museum",
-    "nakama.fukuoka.jp",
-    "cymru.museum",
-    "interactive.museum",
-    "kiwa.mie.jp",
-    "satosho.okayama.jp",
-    "vlaanderen",
-    "mil.by",
-    "shimoda.shizuoka.jp",
-    "airguard.museum",
-    "harima.hyogo.jp",
-    "national.museum",
+    "choshi.chiba.jp",
+    "mil.mv",
+    "k12.dc.us",
+    "k12.ok.us",
+    "santacruz.museum",
+    "k12.or.us",
+    "reklam.hu",
+    "kiyama.saga.jp",
+    "k12.pr.us",
+    "ginoza.okinawa.jp",
+    "fitness",
+    "sortland.no",
+    "yokote.akita.jp",
+    "saotome.st",
+    "svalbard.no",
+    "hof.no",
+    "from-ma.com",
+    "smolensk.ru",
+    "meland.no",
+    "bronnoy.no",
+    "rybnik.pl",
     "k12.al.us",
     "k12.ak.us",
     "k12.ar.us",
-    "varoy.no",
-    "kasuya.fukuoka.jp",
-    "nanjo.okinawa.jp",
-    "setagaya.tokyo.jp",
-    "dvrdns.org",
-    "yokawa.hyogo.jp",
-    "chonan.chiba.jp",
-    "presse.ml",
-    "vestre-slidre.no",
-    "gorge.museum",
-    "k12.tx.us",
-    "wakuya.miyagi.jp",
-    "building.museum",
-    "oceanographique.museum",
-    "rubtsovsk.ru",
+    "hol.no",
+    "uenohara.yamanashi.jp",
     "k12.as.us",
-    "systems",
-    "maintenance.aero",
-    "fukumitsu.toyama.jp",
-    "loyalist.museum",
-    "tysnes.no",
-    "inami.wakayama.jp",
-    "is-a-nascarfan.com",
-    "trentinoaltoadige.it",
-    "taxi.aero",
-    "avocat.fr",
-    "szex.hu",
-    "is-a-therapist.com",
-    "obama.nagasaki.jp",
-    "hichiso.gifu.jp",
+    "higashisumiyoshi.osaka.jp",
+    "matsukawa.nagano.jp",
     "k12.tn.us",
-    "shimada.shizuoka.jp",
-    "kyonan.chiba.jp",
-    "shitara.aichi.jp",
+    "esashi.hokkaido.jp",
+    "nakayama.yamagata.jp",
+    "mil.gh",
+    "singles",
+    "moseushi.hokkaido.jp",
     "k12.ut.us",
-    "shibecha.hokkaido.jp",
-    "kawagoe.mie.jp",
+    "from-tn.com",
     "k12.de.us",
-    "hakone.kanagawa.jp",
-    "togitsu.nagasaki.jp",
-    "tohnosho.chiba.jp",
-    "luxembourg.museum",
-    "lazio.it",
-    "hongo.hiroshima.jp",
-    "xn--mgb9awbf",
-    "hirata.fukushima.jp",
-    "lubin.pl",
-    "badajoz.museum",
-    "asaka.saitama.jp",
-    "and.museum",
-    "undersea.museum",
-    "ibigawa.gifu.jp",
-    "xn--mgbc0a9azcg",
-    "amami.kagoshima.jp",
-    "k12.mt.us",
-    "friuliv-giulia.it",
-    "shiroishi.saga.jp",
-    "nanbu.yamanashi.jp",
-    "bryne.no",
-    "farmequipment.museum",
-    "grane.no",
-    "friuli-vgiulia.it",
-    "skanland.no",
-    "society.museum",
-    "tomobe.ibaraki.jp",
-    "iwade.wakayama.jp",
-    "hanyu.saitama.jp",
-    "hakata.fukuoka.jp",
-    "k12.mn.us",
-    "xn--blt-elab.no",
-    "miyazu.kyoto.jp",
-    "rybnik.pl",
-    "otago.museum",
-    "is-slick.com",
-    "k12.ms.us",
-    "stor-elvdal.no",
-    "smolensk.ru",
-    "k12.il.us",
-    "brandywinevalley.museum",
-    "oki.fukuoka.jp",
-    "fukuyama.hiroshima.jp",
-    "bizen.okayama.jp",
-    "matsue.shimane.jp",
-    "seranishi.hiroshima.jp",
-    "hoylandet.no",
-    "otaki.saitama.jp",
-    "k12.nc.us",
-    "k12.in.us",
-    "ichikai.tochigi.jp",
-    "xn--bod-2na.no",
-    "presse.km",
-    "yakage.okayama.jp",
-    "jamison.museum",
-    "xn--ksnes-uua.no",
-    "wales.museum",
-    "atami.shizuoka.jp",
-    "kochi.kochi.jp",
-    "ibara.okayama.jp",
-    "k12.md.us",
-    "kosai.shizuoka.jp",
-    "film.hu",
-    "miasta.pl",
-    "yokoshibahikari.chiba.jp",
-    "tm.pl",
-    "toyone.aichi.jp",
-    "kariwa.niigata.jp",
-    "lutsk.ua",
-    "kasuga.hyogo.jp",
-    "omura.nagasaki.jp",
-    "asahi.nagano.jp",
-    "nishi.osaka.jp",
-    "k12.me.us",
-    "hemne.no",
-    "fc.it",
-    "k12.id.us",
-    "dovre.no",
-    "mitsue.nara.jp",
-    "saka.hiroshima.jp",
-    "columbus.museum",
-    "bedzin.pl",
-    "pisz.pl",
-    "obira.hokkaido.jp",
-    "from.hr",
-    "k12.nd.us",
-    "k12.ks.us",
-    "plantation.museum",
-    "izumizaki.fukushima.jp",
-    "friulivgiulia.it",
-    "vgs.no",
-    "elvendrell.museum",
-    "saitama.saitama.jp",
-    "compute.amazonaws.com",
-    "hofu.yamaguchi.jp",
-    "compute-1.amazonaws.com",
-    "uchinada.ishikawa.jp",
-    "civilwar.museum",
-    "k12.ne.us",
-    "harvestcelebration.museum",
-    "exchange.aero",
-    "marylhurst.museum",
-    "k12.nj.us",
-    "rec.co",
-    "stjordalshalsen.no",
-    "nesna.no",
-    "roros.no",
-    "mishima.shizuoka.jp",
-    "xn--bjarky-fya.no",
-    "consulting.aero",
-    "k12.pa.us",
-    "obama.fukui.jp",
-    "tysfjord.no",
-    "usa.museum",
-    "toyota.aichi.jp",
-    "minamitane.kagoshima.jp",
-    "b.ssl.fastly.net",
-    "frogans",
-    "higashikagawa.kagawa.jp",
-    "wakasa.fukui.jp",
-    "aland.fi",
-    "research.aero",
-    "kawagoe.saitama.jp",
-    "hanawa.fukushima.jp",
-    "coop.mw",
-    "romsa.no",
-    "aviation.museum",
-    "puglia.it",
-    "mobara.chiba.jp",
-    "yamal.ru",
-    "xn--o3cw4h",
-    "iwata.shizuoka.jp",
-    "otama.fukushima.jp",
-    "ikeda.fukui.jp",
-    "omuta.fukuoka.jp",
-    "evje-og-hornnes.no",
-    "steiermark.museum",
-    "uruma.okinawa.jp",
-    "nakanojo.gunma.jp",
-    "bando.ibaraki.jp",
-    "war.museum",
-    "oguchi.aichi.jp",
-    "abira.hokkaido.jp",
-    "finland.museum",
-    "soo.kagoshima.jp",
-    "honjo.saitama.jp",
-    "tarumizu.kagoshima.jp",
-    "is-by.us",
-    "miyama.mie.jp",
-    "yamada.fukuoka.jp",
-    "xn--fiq228c5hs",
-    "tokuyama.yamaguchi.jp",
-    "is-a-chef.net",
-    "koshu.yamanashi.jp",
-    "takarazuka.hyogo.jp",
-    "is-a-patsfan.org",
-    "miyake.nara.jp",
-    "xn--skierv-uta.no",
-    "schlesisches.museum",
-    "mashiko.tochigi.jp",
-    "qld.gov.au",
-    "radom.pl",
-    "arida.wakayama.jp",
-    "nyc.museum",
-    "rauma.no",
-    "omiya.saitama.jp",
-    "yamaga.kumamoto.jp",
-    "humanities.museum",
-    "xn--loabt-0qa.no",
-    "nuoro.it",
-    "k12.az.us",
-    "kolobrzeg.pl",
-    "lib.nv.us",
-    "xn--koluokta-7ya57h.no",
-    "shimamoto.osaka.jp",
-    "kvanangen.no",
-    "xn--jlster-bya.no",
-    "misasa.tottori.jp",
-    "kunitomi.miyazaki.jp",
-    "k12.ma.us",
-    "a.ssl.fastly.net",
-    "groks-this.info",
-    "k12.ri.us",
-    "podzone.net",
-    "masuda.shimane.jp",
-    "buzen.fukuoka.jp",
-    "reklam.hu",
-    "k12.ia.us",
-    "kanie.aichi.jp",
-    "eu-west-1.compute.amazonaws.com",
-    "artgallery.museum",
-    "sexy",
-    "kawaguchi.saitama.jp",
-    "losangeles.museum",
-    "minami.kyoto.jp",
-    "coop.ht",
-    "kakinoki.shimane.jp",
-    "donostia.museum",
-    "fjaler.no",
-    "assedic.fr",
-    "baltimore.museum",
-    "monza-brianza.it",
-    "imari.saga.jp",
-    "heroy.more-og-romsdal.no",
-    "sex.pl",
-    "paragliding.aero",
-    "gmina.pl",
-    "is-a-geek.com",
-    "niimi.okayama.jp",
-    "itako.ibaraki.jp",
-    "bronnoy.no",
-    "xn--nttery-byae.no",
-    "k12.mi.us",
-    "okuma.fukushima.jp",
-    "sc.ug",
-    "is-a-chef.org",
-    "uhren.museum",
-    "oarai.ibaraki.jp",
-    "xn--gmq050i.hk",
-    "xn--laheadju-7ya.no",
-    "hakodate.hokkaido.jp",
-    "chocolate.museum",
-    "is-an-engineer.com",
-    "yaese.okinawa.jp",
-    "photography.museum",
-    "askim.no",
-    "hyuga.miyazaki.jp",
-    "poltava.ua",
-    "k12.la.us",
-    "mitane.akita.jp",
-    "ulm.museum",
-    "video.hu",
-    "aikawa.kanagawa.jp",
-    "shijonawate.osaka.jp",
-    "umaji.kochi.jp",
-    "averoy.no",
-    "froland.no",
-    "takatori.nara.jp",
-    "coop.mv",
-    "kyoto.jp",
-    "serveftp.org",
-    "musashimurayama.tokyo.jp",
-    "monzaebrianza.it",
-    "agency",
-    "ono.fukui.jp",
-    "hizen.saga.jp",
-    "funabashi.chiba.jp",
-    "meeres.museum",
-    "science.museum",
-    "vdonsk.ru",
-    "xn--finny-yua.no",
-    "sakaiminato.tottori.jp",
-    "toyotomi.hokkaido.jp",
-    "artsandcrafts.museum",
-    "youth.museum",
-    "sciencehistory.museum",
-    "umi.fukuoka.jp",
-    "midori.chiba.jp",
-    "from-ma.com",
-    "gs.nt.no",
-    "florida.museum",
-    "nakamichi.yamanashi.jp",
-    "tarama.okinawa.jp",
-    "sologne.museum",
-    "xn--xkc2dl3a5ee0h",
-    "medizinhistorisches.museum",
-    "kiho.mie.jp",
-    "modern.museum",
-    "viking.museum",
-    "versailles.museum",
-    "on-the-web.tv",
-    "osaki.miyagi.jp",
-    "arita.saga.jp",
-    "togura.nagano.jp",
-    "moscow.museum",
-    "matsuyama.ehime.jp",
-    "monzabrianza.it",
-    "rissa.no",
-    "chikushino.fukuoka.jp",
-    "hirokawa.fukuoka.jp",
-    "k12.vt.us",
-    "vagsoy.no",
-    "swinoujscie.pl",
-    "plc.ly",
-    "ikeda.gifu.jp",
-    "durham.museum",
-    "xn--hery-ira.xn--mre-og-romsdal-qqb.no",
-    "olbia-tempio.it",
-    "k12.wa.us",
-    "ushiku.ibaraki.jp",
-    "blogspot.fr",
-    "kainan.wakayama.jp",
-    "ichiba.tokushima.jp",
-    "ogata.akita.jp",
-    "rieti.it",
-    "mosreg.ru",
-    "nanyo.yamagata.jp",
-    "misaki.osaka.jp",
-    "risor.no",
-    "minamiawaji.hyogo.jp",
-    "sirdal.no",
-    "mil.do",
+    "ullensvang.no",
+    "from-al.com",
+    "solutions",
     "from-mo.com",
-    "shimonita.gunma.jp",
-    "zgrad.ru",
-    "lib.ny.us",
-    "inagi.tokyo.jp",
-    "mil.jo",
-    "rodoy.no",
-    "mitaka.tokyo.jp",
-    "ginan.gifu.jp",
-    "miners.museum",
-    "yuasa.wakayama.jp",
-    "kawai.iwate.jp",
-    "kunitachi.tokyo.jp",
-    "iwama.ibaraki.jp",
-    "museet.museum",
-    "xn--holtlen-hxa.no",
-    "k12.wi.us",
-    "tonaki.okinawa.jp",
-    "from-hi.com",
-    "starachowice.pl",
-    "suldal.no",
-    "nanao.ishikawa.jp",
-    "vibovalentia.it",
-    "raisa.no",
-    "kamitonda.wakayama.jp",
-    "blogspot.fi",
-    "schoenbrunn.museum",
-    "lib.ky.us",
-    "daegu.kr",
-    "radoy.no",
-    "steigen.no",
-    "portal.museum",
-    "fg.it",
-    "yuzhno-sakhalinsk.ru",
-    "padova.it",
-    "tsukiyono.gunma.jp",
-    "tagami.niigata.jp",
-    "muosat.no",
-    "unzen.nagasaki.jp",
-    "mil.to",
-    "snaase.no",
-    "dyroy.no",
-    "shimokawa.hokkaido.jp",
-    "otoyo.kochi.jp",
-    "yamaguchi.jp",
-    "act.gov.au",
-    "misawa.aomori.jp",
-    "xn--merker-kua.no",
-    "itami.hyogo.jp",
-    "turek.pl",
-    "anthropology.museum",
-    "gamagori.aichi.jp",
-    "shobara.hiroshima.jp",
-    "basilicata.it",
-    "sigdal.no",
-    "molise.it",
-    "foundation.museum",
-    "minamiuonuma.niigata.jp",
-    "from-nd.com",
-    "issmarterthanyou.com",
-    "saotome.st",
-    "gs.nl.no",
-    "strand.no",
-    "from-sd.com",
-    "muncie.museum",
-    "ashiya.hyogo.jp",
-    "xn--h1aegh.museum",
-    "sciencesnaturelles.museum",
-    "xn--ystre-slidre-ujb.no",
-    "owani.aomori.jp",
-    "cloudfront.net",
-    "mikasa.hokkaido.jp",
-    "sex.hu",
-    "kamifurano.hokkaido.jp",
-    "solund.no",
-    "krokstadelva.no",
-    "fauske.no",
-    "vf.no",
-    "from-az.net",
-    "iwate.iwate.jp",
-    "shibata.niigata.jp",
-    "2000.hu",
-    "depot.museum",
-    "kaneyama.fukushima.jp",
-    "intelligence.museum",
-    "hisayama.fukuoka.jp",
-    "yabuki.fukushima.jp",
-    "antiques.museum",
-    "iwaki.fukushima.jp",
-    "palana.ru",
-    "workshop.museum",
-    "us-west-1.compute.amazonaws.com",
-    "us-west-2.compute.amazonaws.com",
-    "xn--vre-eiker-k8a.no",
-    "botany.museum",
-    "dolls.museum",
-    "mil.no",
-    "aquarium.museum",
-    "technology",
-    "nyuzen.toyama.jp",
-    "xn--oppegrd-ixa.no",
-    "fuji.shizuoka.jp",
-    "tomigusuku.okinawa.jp",
-    "from-mi.com",
-    "sunagawa.hokkaido.jp",
-    "hiji.oita.jp",
-    "essex.museum",
-    "for-the.biz",
-    "soundandvision.museum",
-    "yalta.ua",
-    "vestby.no",
-    "mil.bo",
-    "from-mn.com",
-    "ikoma.nara.jp",
-    "nango.fukushima.jp",
-    "posts-and-telecommunications.museum",
-    "fukushima.hokkaido.jp",
-    "ouchi.saga.jp",
-    "taketomi.okinawa.jp",
-    "lib.wy.us",
-    "madrid.museum",
-    "tomakomai.hokkaido.jp",
-    "wajiki.tokushima.jp",
-    "ulvik.no",
-    "naganohara.gunma.jp",
-    "niyodogawa.kochi.jp",
-    "is-very-evil.org",
-    "k12.va.us",
-    "minami.tokushima.jp",
-    "shiojiri.nagano.jp",
-    "xn--xkc2al3hye2a",
-    "xn--mgberp4a5d4a87g",
-    "nagai.yamagata.jp",
+    "eidfjord.no",
+    "hiratsuka.kanagawa.jp",
+    "hidaka.hokkaido.jp",
+    "from-ri.com",
+    "from-wi.com",
+    "k12.mt.us",
+    "sondrio.it",
+    "chikuho.fukuoka.jp",
+    "from-ks.com",
+    "sx",
+    "coop.tt",
+    "from-fl.com",
+    "k12.mn.us",
+    "matsushige.tokushima.jp",
+    "yokoze.saitama.jp",
+    "nakijin.okinawa.jp",
+    "k12.ms.us",
+    "kadena.okinawa.jp",
+    "verdal.no",
+    "campidanomedio.it",
+    "campania.it",
+    "k12.il.us",
+    "mil.lv",
+    "higashi.fukushima.jp",
+    "mino.gifu.jp",
+    "eidskog.no",
+    "kvafjord.no",
+    "mitsuke.niigata.jp",
+    "appspot.com",
     "mincom.tn",
-    "kasai.hyogo.jp",
-    "asahi.ibaraki.jp",
-    "huissier-justice.fr",
-    "clinton.museum",
-    "yurihonjo.akita.jp",
-    "public.museum",
-    "shishikui.tokushima.jp",
-    "oto.fukuoka.jp",
-    "k12.ct.us",
-    "yusui.kagoshima.jp",
-    "usculture.museum",
-    "selfip.com",
-    "shibetsu.hokkaido.jp",
-    "takamori.kumamoto.jp",
-    "nishi.fukuoka.jp",
-    "abeno.osaka.jp",
-    "coal.museum",
-    "kanna.gunma.jp",
-    "turen.tn",
-    "oyodo.nara.jp",
-    "tahara.aichi.jp",
-    "virginia.museum",
-    "shinjuku.tokyo.jp",
-    "k12.vi.us",
-    "saigawa.fukuoka.jp",
-    "agrar.hu",
-    "kawamata.fukushima.jp",
-    "from-mt.com",
-    "fitjar.no",
-    "mihama.mie.jp",
-    "sekikawa.niigata.jp",
-    "shimamaki.hokkaido.jp",
-    "tanabe.wakayama.jp",
-    "tokke.no",
-    "ftpaccess.cc",
-    "volyn.ua",
-    "wlocl.pl",
-    "udine.it",
-    "tokyo.jp",
-    "furukawa.miyagi.jp",
-    "fujioka.gunma.jp",
-    "settsu.osaka.jp",
-    "gosen.niigata.jp",
-    "shimizu.hokkaido.jp",
-    "vic.gov.au",
-    "cody.museum",
-    "ojiya.niigata.jp",
-    "iraq.museum",
-    "museum.no",
-    "chikuzen.fukuoka.jp",
-    "pilots.museum",
-    "shikama.miyagi.jp",
-    "thruhere.net",
-    "sannohe.aomori.jp",
-    "utazas.hu",
-    "scrapping.cc",
-    "experts-comptables.fr",
-    "mypets.ws",
-    "higashinaruse.akita.jp",
-    "ddr.museum",
-    "sor-varanger.no",
-    "savona.it",
-    "other.nf",
-    "yorkshire.museum",
-    "lans.museum",
-    "ozora.hokkaido.jp",
-    "yugawa.fukushima.jp",
-    "hashima.gifu.jp",
-    "is-a-liberal.com",
-    "vlaanderen.museum",
-    "pro.mv",
-    "otobe.hokkaido.jp",
-    "heimatunduhren.museum",
-    "komono.mie.jp",
-    "global.prod.fastly.net",
-    "toride.ibaraki.jp",
-    "soma.fukushima.jp",
-    "daito.osaka.jp",
-    "from-id.com",
-    "minobu.yamanashi.jp",
-    "rebun.hokkaido.jp",
-    "copenhagen.museum",
-    "recreation.aero",
-    "ringsaker.no",
-    "scienceandindustry.museum",
-    "mimata.miyazaki.jp",
-    "kitakata.fukushima.jp",
-    "mukawa.hokkaido.jp",
-    "taishi.hyogo.jp",
-    "katano.osaka.jp",
-    "izena.okinawa.jp",
-    "cc.me.us",
-    "panama.museum",
-    "mifune.kumamoto.jp",
-    "cc.md.us",
-    "kurogi.fukuoka.jp",
-    "cc.sd.us",
-    "samukawa.kanagawa.jp",
-    "cc.mo.us",
-    "cc.ms.us",
-    "cc.de.us",
-    "kagamiishi.fukushima.jp",
-    "xn--mgbtf8fl",
-    "mihama.chiba.jp",
-    "arts.museum",
-    "siljan.no",
-    "tingvoll.no",
-    "reggio-calabria.it",
-    "cc.as.us",
-    "kunimi.fukushima.jp",
-    "ringerike.no",
-    "itano.tokushima.jp",
-    "xn--nqv7fs00ema",
-    "malopolska.pl",
-    "fukagawa.hokkaido.jp",
-    "misaki.okayama.jp",
-    "kasuga.fukuoka.jp",
-    "k12.oh.us",
-    "saintlouis.museum",
-    "kumano.mie.jp",
-    "cc.ma.us",
-    "cc.la.us",
-    "ebino.miyazaki.jp",
-    "kamitsue.oita.jp",
-    "bale.museum",
-    "reggioemilia.it",
-    "kids.museum",
-    "xn--ogbpf8fl",
-    "stpetersburg.museum",
-    "museum.om",
-    "cc.mt.us",
-    "cc.ut.us",
-    "is-a-chef.com",
-    "olsztyn.pl",
-    "tomsk.ru",
-    "glas.museum",
-    "cc.co.us",
-    "museum.tt",
-    "k12.ca.us",
-    "wajima.ishikawa.jp",
-    "cc.ar.us",
-    "tydal.no",
-    "nemuro.hokkaido.jp",
-    "bill.museum",
-    "cc.or.us",
-    "tozawa.yamagata.jp",
-    "xn--davvenjrga-y4a.no",
-    "scienceandhistory.museum",
-    "nagano.jp",
-    "konan.shiga.jp",
-    "cambridge.museum",
-    "kawanabe.kagoshima.jp",
-    "presse.fr",
-    "usdecorativearts.museum",
-    "komvux.se",
-    "targi.pl",
-    "shiranuka.hokkaido.jp",
-    "cc.va.us",
-    "futtsu.chiba.jp",
-    "cc.ks.us",
+    "mielec.pl",
+    "fuel.aero",
+    "k12.in.us",
+    "from-ar.com",
+    "karpacz.pl",
+    "k12.md.us",
+    "yugawara.kanagawa.jp",
+    "fareast.ru",
+    "webhop.org",
+    "gloppen.no",
+    "higashiyodogawa.osaka.jp",
+    "nishinomiya.hyogo.jp",
+    "kostroma.ru",
+    "k12.me.us",
+    "saarland",
+    "from-az.net",
+    "k12.id.us",
+    "k12.nc.us",
+    "russia.museum",
+    "spydeberg.no",
+    "kvitsoy.no",
+    "moka.tochigi.jp",
+    "a.prod.fastly.net",
+    "konskowola.pl",
+    "eidsvoll.no",
+    "sardegna.it",
+    "kurate.fukuoka.jp",
+    "frogans",
+    "matsuzaki.shizuoka.jp",
+    "k12.pa.us",
+    "umbria.it",
+    "sg",
+    "kumamoto.jp",
+    "kumatori.osaka.jp",
+    "web.do",
+    "mordovia.ru",
+    "varggat.no",
+    "matera.it",
+    "sokndal.no",
+    "seto.aichi.jp",
+    "k12.nd.us",
+    "nagawa.nagano.jp",
+    "simbirsk.ru",
+    "from-mn.com",
+    "k12.vt.us",
+    "campidano-medio.it",
+    "minami-alps.yamanashi.jp",
+    "from-nh.com",
+    "flog.br",
+    "kurume.fukuoka.jp",
+    "sado.niigata.jp",
+    "from-ne.com",
+    "k12.ne.us",
+    "from-ak.com",
+    "k12.nj.us",
+    "from-mi.com",
+    "saitama.jp",
+    "stuttgart.museum",
+    "bjarkoy.no",
     "from-ms.com",
-    "franziskaner.museum",
-    "skierva.no",
-    "cc.az.us",
-    "oyama.tochigi.jp",
-    "ohira.miyagi.jp",
-    "cc.ca.us",
-    "cc.vt.us",
-    "takko.aomori.jp",
-    "clock.museum",
-    "xn--hbmer-xqa.no",
-    "asahi.yamagata.jp",
-    "mihara.hiroshima.jp",
-    "powiat.pl",
-    "botanicalgarden.museum",
-    "guovdageaidnu.no",
-    "radio.br",
-    "is-a-libertarian.com",
-    "cc.ct.us",
-    "rochester.museum",
-    "xn--mtta-vrjjat-k7af.no",
-    "cc.mi.us",
-    "pf",
-    "iijima.nagano.jp",
-    "cc.mn.us",
-    "boldlygoingnowhere.org",
-    "nayoro.hokkaido.jp",
-    "nyny.museum",
-    "asago.hyogo.jp",
-    "shirataka.yamagata.jp",
-    "bushey.museum",
-    "mishima.fukushima.jp",
-    "shikatsu.aichi.jp",
-    "shinichi.hiroshima.jp",
-    "cc.tn.us",
-    "is-a-bruinsfan.org",
-    "fujiidera.osaka.jp",
-    "xn--sgne-gra.no",
-    "malatvuopmi.no",
-    "rygge.no",
-    "hyogo.jp",
-    "midori.gunma.jp",
-    "k12.nh.us",
-    "sendai.jp",
-    "xn--mgbqly7cvafr",
-    "bronnoysund.no",
-    "suli.hu",
-    "friuli-v-giulia.it",
-    "cc.vi.us",
-    "carbonia-iglesias.it",
-    "tolga.no",
-    "hanno.saitama.jp",
-    "poznan.pl",
-    "cc.ak.us",
-    "fujisato.akita.jp",
-    "cc.ok.us",
-    "olecko.pl",
-    "stockholm.museum",
-    "akune.kagoshima.jp",
-    "fuoisku.no",
-    "sagamihara.kanagawa.jp",
-    "otsuchi.iwate.jp",
-    "s3.amazonaws.com",
-    "hakui.ishikawa.jp",
-    "trust.museum",
-    "fujisawa.iwate.jp",
-    "nishiaizu.fukushima.jp",
-    "is-into-anime.com",
-    "cc.al.us",
-    "sayama.osaka.jp",
-    "6bone.pl",
-    "atsugi.kanagawa.jp",
-    "choyo.kumamoto.jp",
-    "namie.fukushima.jp",
-    "kakamigahara.gifu.jp",
-    "minamisanriku.miyagi.jp",
-    "donna.no",
-    "marine.ru",
-    "ono.fukushima.jp",
-    "coloradoplateau.museum",
-    "fujimino.saitama.jp",
-    "tenri.nara.jp",
-    "nakatsugawa.gifu.jp",
-    "kazuno.akita.jp",
-    "kamigori.hyogo.jp",
-    "iyo.ehime.jp",
-    "xn--krager-gya.no",
-    "wanouchi.gifu.jp",
-    "shirahama.wakayama.jp",
-    "shimogo.fukushima.jp",
-    "prd.fr",
-    "um.gov.pl",
-    "xn--bhcavuotna-s4a.no",
-    "cc.oh.us",
-    "kosei.shiga.jp",
-    "cc.ri.us",
+    "financial",
+    "hikawa.shimane.jp",
+    "exhibition.museum",
+    "warabi.saitama.jp",
+    "adachi.tokyo.jp",
+    "utashinai.hokkaido.jp",
+    "from-de.com",
+    "maebashi.gunma.jp",
+    "nagatoro.saitama.jp",
+    "corporation.museum",
+    "k12.ma.us",
+    "yamagata.nagano.jp",
+    "sorfold.no",
+    "hirara.okinawa.jp",
+    "krasnoyarsk.ru",
+    "from-ct.com",
+    "from-ga.com",
+    "siedlce.pl",
+    "minakami.gunma.jp",
+    "k12.ia.us",
+    "skedsmokorset.no",
     "k12.nm.us",
-    "xn--hyanger-q1a.no",
-    "cc.fl.us",
-    "nikko.tochigi.jp",
-    "haboro.hokkaido.jp",
-    "readmyblog.org",
-    "lib.mo.us",
-    "yoshioka.gunma.jp",
-    "wloclawek.pl",
-    "motobu.okinawa.jp",
-    "homeip.net",
-    "hagi.yamaguchi.jp",
-    "vikna.no",
-    "yamamoto.miyagi.jp",
-    "yamatsuri.fukushima.jp",
-    "skydiving.aero",
-    "kumano.hiroshima.jp",
-    "samara.ru",
-    "anpachi.gifu.jp",
-    "tajiri.osaka.jp",
-    "k12.gu.us",
-    "tokai.aichi.jp",
-    "blogspot.cf",
-    "suzuka.mie.jp",
-    "chofu.tokyo.jp",
-    "tsunan.niigata.jp",
-    "happou.akita.jp",
-    "awaji.hyogo.jp",
-    "sakuragawa.ibaraki.jp",
-    "naruto.tokushima.jp",
-    "encyclopedic.museum",
-    "lahppi.no",
-    "aizumisato.fukushima.jp",
-    "shimotsuma.ibaraki.jp",
-    "chino.nagano.jp",
-    "airtraffic.aero",
-    "veneto.it",
-    "xn--gecrj9c",
-    "is-a-bulls-fan.com",
-    "aizuwakamatsu.fukushima.jp",
-    "juif.museum",
+    "iwanai.hokkaido.jp",
+    "farmers.museum",
+    "nogata.fukuoka.jp",
+    "miyoshi.hiroshima.jp",
+    "melhus.no",
+    "nerima.tokyo.jp",
+    "kirovograd.ua",
+    "genkai.saga.jp",
+    "higashiagatsuma.gunma.jp",
+    "suedtirol.it",
+    "soka.saitama.jp",
+    "airport.aero",
+    "miyazaki.miyazaki.jp",
+    "usarts.museum",
+    "mugi.tokushima.jp",
+    "social",
+    "voagat.no",
+    "modena.it",
+    "yahaba.iwate.jp",
+    "k12.ks.us",
+    "fish",
+    "kemerovo.ru",
+    "varese.it",
+    "morotsuka.miyazaki.jp",
+    "iitate.fukushima.jp",
+    "miasta.pl",
+    "museum.no",
+    "marche.it",
+    "minamiizu.shizuoka.jp",
+    "dell-ogliastra.it",
+    "badajoz.museum",
+    "k12.la.us",
+    "zamami.okinawa.jp",
+    "k12.va.us",
+    "soni.nara.jp",
+    "aogaki.hyogo.jp",
+    "mykolaiv.ua",
+    "farmstead.museum",
+    "bungoono.oita.jp",
+    "gokase.miyazaki.jp",
+    "verran.no",
+    "nishikawa.yamagata.jp",
+    "santafe.museum",
+    "keisen.fukuoka.jp",
+    "kusu.oita.jp",
+    "mashike.hokkaido.jp",
+    "cartoonart.museum",
+    "higashimurayama.tokyo.jp",
+    "filatelia.museum",
+    "mishima.shizuoka.jp",
+    "coop.mv",
+    "from-mt.com",
+    "zachpomor.pl",
+    "sandnessjoen.no",
+    "southwest.museum",
+    "firm.in",
+    "salangen.no",
+    "matsue.shimane.jp",
+    "maibara.shiga.jp",
+    "savannahga.museum",
+    "svelvik.no",
+    "setouchi.okayama.jp",
+    "minamioguni.kumamoto.jp",
+    "skanland.no",
+    "wakayama.wakayama.jp",
+    "miyoshi.tokushima.jp",
+    "himeji.hyogo.jp",
+    "fyresdal.no",
+    "bronnoysund.no",
+    "museum.tt",
+    "bomlo.no",
+    "from-wv.com",
+    "from-ia.com",
+    "hita.oita.jp",
+    "from-il.com",
+    "czest.pl",
+    "flesberg.no",
+    "nago.okinawa.jp",
+    "nore-og-uvdal.no",
+    "from-nv.com",
+    "mobara.chiba.jp",
+    "frei.no",
+    "colonialwilliamsburg.museum",
+    "modern.museum",
+    "greta.fr",
+    "assisi.museum",
+    "stjordal.no",
+    "usui.fukuoka.jp",
+    "systems",
+    "musashino.tokyo.jp",
+    "museum.om",
+    "fukuoka.jp",
+    "ariake.saga.jp",
+    "saitama.saitama.jp",
+    "foundation",
+    "forsand.no",
+    "kepno.pl",
+    "snillfjord.no",
+    "kita.osaka.jp",
+    "rec.ro",
+    "fishing",
+    "fetsund.no",
+    "sakurai.nara.jp",
+    "verona.it",
+    "vdonsk.ru",
+    "gemological.museum",
+    "stor-elvdal.no",
+    "bristol.museum",
+    "mitsue.nara.jp",
+    "miners.museum",
+    "veterinaire.fr",
+    "handson.museum",
+    "fredrikstad.no",
+    "bardu.no",
+    "fhsk.se",
+    "kherson.ua",
+    "asnes.no",
+    "kutno.pl",
+    "k12.wa.us",
+    "southcarolina.museum",
+    "farsund.no",
+    "shacknet.nu",
+    "upow.gov.pl",
+    "kosuge.yamanashi.jp",
+    "barum.no",
+    "genoa.it",
+    "gangwon.kr",
+    "galsa.no",
+    "balat.no",
+    "naha.okinawa.jp",
+    "yamaga.kumamoto.jp",
+    "muncie.museum",
+    "stalowa-wola.pl",
+    "k12.ri.us",
+    "from.hr",
+    "aurskog-holand.no",
+    "akashi.hyogo.jp",
+    "meeres.museum",
+    "gunma.jp",
+    "from-in.com",
+    "sakhalin.ru",
+    "cuneo.it",
+    "fineart.museum",
+    "kitamoto.saitama.jp",
+    "sorreisa.no",
+    "bryne.no",
+    "shriram",
+    "miyama.mie.jp",
+    "zagan.pl",
+    "grane.no",
+    "k12.mi.us",
+    "k12.az.us",
+    "kanoya.kagoshima.jp",
+    "shimane.jp",
+    "moscow.museum",
+    "minamifurano.hokkaido.jp",
+    "hikone.shiga.jp",
+    "florist",
+    "hiraya.nagano.jp",
+    "hagebostad.no",
+    "incheon.kr",
+    "yamakita.kanagawa.jp",
+    "flekkefjord.no",
+    "saintlouis.museum",
+    "froland.no",
+    "spiegel",
+    "mitane.akita.jp",
+    "yufu.oita.jp",
+    "daejeon.kr",
+    "romskog.no",
+    "museet.museum",
+    "misasa.tottori.jp",
+    "hakuba.nagano.jp",
+    "yamazoe.nara.jp",
+    "yamagata.yamagata.jp",
+    "sherbrooke.museum",
+    "nanporo.hokkaido.jp",
+    "neues.museum",
+    "nose.osaka.jp",
+    "rimini.it",
+    "hembygdsforbund.museum",
+    "hirata.fukushima.jp",
+    "fuefuki.yamanashi.jp",
+    "sano.tochigi.jp",
+    "chuo.osaka.jp",
+    "burghof.museum",
+    "herad.no",
+    "harima.hyogo.jp",
+    "utsira.no",
+    "kasuga.hyogo.jp",
+    "yamada.fukuoka.jp",
+    "masuda.shimane.jp",
+    "6bone.pl",
+    "moriyama.shiga.jp",
+    "bandai.fukushima.jp",
+    "adult.ht",
+    "kuban.ru",
+    "yanaizu.fukushima.jp",
+    "higashikagura.hokkaido.jp",
+    "donna.no",
+    "sayo.hyogo.jp",
+    "k12.vi.us",
+    "gulen.no",
+    "kunst.museum",
+    "shakotan.hokkaido.jp",
+    "society.museum",
+    "rishirifuji.hokkaido.jp",
+    "natori.miyagi.jp",
+    "jamal.ru",
+    "minamiyamashiro.kyoto.jp",
+    "matsushima.miyagi.jp",
+    "soo.kagoshima.jp",
+    "bible.museum",
+    "fuso.aichi.jp",
+    "miyake.nara.jp",
+    "from-nd.com",
+    "from-sd.com",
+    "k12.oh.us",
+    "starnberg.museum",
+    "mihama.chiba.jp",
+    "ardal.no",
+    "zarow.pl",
+    "florida.museum",
+    "hamar.no",
+    "molise.it",
+    "koeln.museum",
+    "mihama.mie.jp",
+    "sibenik.museum",
+    "flights",
+    "seljord.no",
+    "vossevangen.no",
+    "nakadomari.aomori.jp",
+    "madrid.museum",
+    "minamiaiki.nagano.jp",
+    "games.hu",
+    "kirov.ru",
+    "sex.pl",
+    "haram.no",
+    "daegu.kr",
+    "yasaka.nagano.jp",
+    "aland.fi",
+    "shiksha",
+    "saku.nagano.jp",
+    "hemne.no",
+    "halsa.no",
+    "firm.ht",
+    "glass.museum",
+    "rzeszow.pl",
+    "depot.museum",
+    "nakama.fukuoka.jp",
+    "dovre.no",
+    "gorge.museum",
     "museum.mv",
-    "minamiashigara.kanagawa.jp",
-    "kyotanabe.kyoto.jp",
-    "torahime.shiga.jp",
-    "cc.ky.us",
-    "googlecode.com",
-    "air-surveillance.aero",
-    "yukuhashi.fukuoka.jp",
-    "dynathome.net",
-    "zgora.pl",
-    "porsanger.no",
-    "xn--mlselv-iua.no",
-    "hikari.yamaguchi.jp",
-    "zgorzelec.pl",
-    "dinosaur.museum",
-    "starostwo.gov.pl",
-    "jgora.pl",
-    "tsukui.kanagawa.jp",
-    "hioki.kagoshima.jp",
-    "toba.mie.jp",
-    "fukuchiyama.kyoto.jp",
-    "mil.co",
-    "ukiha.fukuoka.jp",
-    "touch.museum",
-    "shimizu.shizuoka.jp",
-    "kasahara.gifu.jp",
+    "minamiminowa.nagano.jp",
+    "dolls.museum",
+    "hurum.no",
+    "klabu.no",
+    "from-hi.com",
+    "kokonoe.oita.jp",
+    "vantaa.museum",
+    "aoste.it",
+    "mifune.kumamoto.jp",
+    "shimamoto.osaka.jp",
+    "kakuda.miyagi.jp",
     "design.museum",
-    "frankfurt.museum",
-    "ogimi.okinawa.jp",
-    "saroma.hokkaido.jp",
-    "sa-east-1.compute.amazonaws.com",
-    "piedmont.it",
-    "cc.hi.us",
-    "syzran.ru",
-    "pordenone.it",
-    "miyada.nagano.jp",
-    "embroidery.museum",
-    "foggia.it",
-    "szczecin.pl",
-    "lanbib.se",
-    "nakatane.kagoshima.jp",
-    "shimosuwa.nagano.jp",
-    "uw.gov.pl",
-    "bunkyo.tokyo.jp",
-    "fet.no",
-    "valley.museum",
-    "taira.toyama.jp",
-    "tas.gov.au",
-    "doshi.yamanashi.jp",
-    "makurazaki.kagoshima.jp",
-    "tychy.pl",
-    "molde.no",
-    "withgoogle.com",
-    "k12.ga.us",
-    "tado.mie.jp",
-    "nakano.tokyo.jp",
-    "hokuto.hokkaido.jp",
-    "ltd.co.im",
-    "sayama.saitama.jp",
-    "miyagi.jp",
-    "fujieda.shizuoka.jp",
-    "olawa.pl",
-    "takata.fukuoka.jp",
-    "ilawa.pl",
-    "fujikawa.shizuoka.jp",
-    "ashiya.fukuoka.jp",
-    "rotorcraft.aero",
-    "miyota.nagano.jp",
-    "forgot.his.name",
-    "ohira.tochigi.jp",
-    "shiroishi.miyagi.jp",
-    "tsuru.yamanashi.jp",
-    "shinshiro.aichi.jp",
-    "modum.no",
-    "osoyro.no",
-    "tagawa.fukuoka.jp",
-    "koori.fukushima.jp",
-    "cc.ga.us",
-    "kaminoyama.yamagata.jp",
-    "wa.gov.au",
-    "sakura.chiba.jp",
-    "murata.miyagi.jp",
-    "szkola.pl",
-    "tjome.no",
-    "sel.no",
-    "montreal.museum",
-    "navigation.aero",
-    "yoita.niigata.jp",
-    "shibukawa.gunma.jp",
-    "lomza.pl",
-    "cc.gu.us",
-    "york.museum",
-    "selfip.biz",
-    "aisho.shiga.jp",
-    "palace.museum",
-    "author.aero",
-    "dominic.ua",
-    "koriyama.fukushima.jp",
-    "technology.museum",
-    "utsunomiya.tochigi.jp",
-    "podzone.org",
-    "s3-ap-southeast-2.amazonaws.com",
-    "pomorskie.pl",
-    "sld.do",
-    "onojo.fukuoka.jp",
-    "misugi.mie.jp",
-    "press.ma",
-    "dyndns-server.com",
-    "seki.gifu.jp",
-    "tohma.hokkaido.jp",
-    "taiki.hokkaido.jp",
-    "perso.ht",
-    "surgut.ru",
-    "utah.museum",
-    "merseine.nu",
-    "fosnes.no",
-    "sweden.museum",
-    "monza-e-della-brianza.it",
-    "nakagawa.fukuoka.jp",
-    "kamimine.saga.jp",
-    "przeworsk.pl",
-    "sa.edu.au",
-    "lib.fl.us",
-    "webhop.info",
-    "higashikurume.tokyo.jp",
-    "yorii.saitama.jp",
-    "fla.no",
-    "taito.tokyo.jp",
-    "trana.no",
-    "shimofusa.chiba.jp",
-    "takanezawa.tochigi.jp",
-    "z-1.compute-1.amazonaws.com",
-    "mansion.museum",
-    "riodejaneiro.museum",
-    "perso.tn",
-    "z-2.compute-1.amazonaws.com",
-    "ashoro.hokkaido.jp",
-    "kawaue.gifu.jp",
-    "matsusaka.mie.jp",
-    "sapporo.jp",
-    "webhop.net",
-    "mutsu.aomori.jp",
-    "groks-the.info",
-    "square.museum",
-    "podlasie.pl",
-    "ranzan.saitama.jp",
-    "turin.it",
-    "bihoro.hokkaido.jp",
-    "nikaho.akita.jp",
-    "tambov.ru",
-    "terni.it",
-    "parma.it",
-    "maizuru.kyoto.jp",
-    "county.museum",
-    "szczytno.pl",
-    "minowa.nagano.jp",
+    "bjugn.no",
+    "funahashi.toyama.jp",
+    "global.prod.fastly.net",
+    "kursk.ru",
+    "soundandvision.museum",
+    "coop.ht",
+    "nesna.no",
+    "minamimaki.nagano.jp",
+    "mosreg.ru",
+    "nord-odal.no",
+    "giske.no",
+    "naval.museum",
+    "firenze.it",
+    "vladivostok.ru",
+    "altai.ru",
+    "amber.museum",
     "from-md.com",
-    "prato.it",
-    "meloy.no",
-    "cc.sc.us",
-    "support",
-    "polkowice.pl",
-    "honjyo.akita.jp",
-    "cc.dc.us",
-    "kitashiobara.fukushima.jp",
-    "memorial.museum",
-    "magazine.aero",
-    "bilbao.museum",
-    "ogaki.gifu.jp",
-    "skodje.no",
-    "suisse.museum",
-    "milan.it",
-    "tomiya.miyagi.jp",
-    "xn--bhccavuotna-k7a.no",
-    "missoula.museum",
-    "monmouth.museum",
-    "parachuting.aero",
-    "padua.it",
-    "ryazan.ru",
-    "skanit.no",
-    "ayase.kanagawa.jp",
-    "piemonte.it",
-    "maniwa.okayama.jp",
-    "stavropol.ru",
-    "takamori.nagano.jp",
-    "ulan-ude.ru",
-    "shinagawa.tokyo.jp",
-    "from-va.com",
-    "frosta.no",
-    "yaita.tochigi.jp",
-    "freight.aero",
-    "massa-carrara.it",
-    "usantiques.museum",
-    "masoy.no",
-    "fhs.no",
-    "mihama.aichi.jp",
-    "tachiarai.fukuoka.jp",
-    "mihara.kochi.jp",
-    "tenei.fukushima.jp",
-    "saratov.ru",
-    "shisui.chiba.jp",
-    "telekommunikation.museum",
-    "yamanouchi.nagano.jp",
-    "snoasa.no",
-    "anthro.museum",
-    "ikawa.akita.jp",
-    "mining.museum",
-    "ichinomiya.aichi.jp",
-    "kisofukushima.nagano.jp",
-    "tainai.niigata.jp",
-    "bern.museum",
-    "nakai.kanagawa.jp",
-    "school.na",
-    "parliament.uk",
-    "stokke.no",
-    "bonn.museum",
-    "perso.sn",
-    "takanabe.miyazaki.jp",
-    "ichinomiya.chiba.jp",
-    "selfip.org",
-    "sennan.osaka.jp",
-    "shinshinotsu.hokkaido.jp",
-    "shiroi.chiba.jp",
-    "lib.co.us",
-    "cc.id.us",
-    "hirono.iwate.jp",
-    "plants.museum",
-    "fukaya.saitama.jp",
-    "sarpsborg.no",
-    "cc.tx.us",
-    "fujikawa.yamanashi.jp",
-    "ski.no",
+    "kuju.oita.jp",
+    "minami.kyoto.jp",
+    "aosta.it",
+    "kumamoto.kumamoto.jp",
+    "busan.kr",
+    "kariwa.niigata.jp",
+    "iwate.jp",
+    "biratori.hokkaido.jp",
+    "shobara.hiroshima.jp",
+    "hobol.no",
+    "stargard.pl",
+    "k12.wi.us",
+    "k12.nh.us",
+    "urasoe.okinawa.jp",
+    "naklo.pl",
+    "foundation.museum",
+    "house.museum",
+    "izumiotsu.osaka.jp",
+    "sakaiminato.tottori.jp",
+    "uonuma.niigata.jp",
+    "clinton.museum",
+    "szex.hu",
+    "hotel.lk",
+    "gmina.pl",
+    "hanawa.fukushima.jp",
+    "mihara.hiroshima.jp",
+    "kainan.wakayama.jp",
+    "north.museum",
+    "yoichi.hokkaido.jp",
+    "marine.ru",
+    "nuoro.it",
+    "yasugi.shimane.jp",
+    "higashimatsushima.miyagi.jp",
+    "bytom.pl",
+    "sirdal.no",
+    "midori.chiba.jp",
+    "setagaya.tokyo.jp",
+    "nanto.toyama.jp",
+    "yokawa.hyogo.jp",
+    "suldal.no",
+    "sannohe.aomori.jp",
+    "steiermark.museum",
+    "sera.hiroshima.jp",
+    "kasuya.fukuoka.jp",
+    "fortmissoula.museum",
+    "nagi.okayama.jp",
+    "naroy.no",
+    "k12.ga.us",
+    "murayama.yamagata.jp",
+    "akaiwa.okayama.jp",
+    "jamison.museum",
+    "automotive.museum",
+    "sigdal.no",
+    "miki.hyogo.jp",
+    "baths.museum",
+    "sologne.museum",
+    "semboku.akita.jp",
+    "snaase.no",
+    "finland.museum",
+    "hakata.fukuoka.jp",
+    "malatvuopmi.no",
+    "hikimi.shimane.jp",
+    "strand.no",
+    "freemasonry.museum",
+    "solund.no",
+    "csiro.au",
+    "computerhistory.museum",
+    "shirako.chiba.jp",
+    "uslivinghistory.museum",
+    "hitra.no",
+    "entomology.museum",
+    "suginami.tokyo.jp",
+    "hasami.nagasaki.jp",
+    "asker.no",
+    "ashiya.hyogo.jp",
+    "misawa.aomori.jp",
+    "hotel.tz",
+    "iruma.saitama.jp",
+    "selfip.com",
     "from-me.org",
-    "nativeamerican.museum",
-    "komagane.nagano.jp",
-    "tokoname.aichi.jp",
-    "xn--sndre-land-0cb.no",
-    "cc.ia.us",
-    "tarui.gifu.jp",
+    "kochi.jp",
+    "belau.pw",
+    "fjaler.no",
+    "kanna.gunma.jp",
+    "basel.museum",
+    "roros.no",
+    "shimoda.shizuoka.jp",
+    "hachioji.tokyo.jp",
+    "ehime.jp",
+    "mishima.fukushima.jp",
+    "inami.toyama.jp",
+    "asaka.saitama.jp",
+    "kyoto.jp",
+    "romsa.no",
+    "kharkov.ua",
+    "kaisei.kanagawa.jp",
+    "asuke.aichi.jp",
+    "shimada.shizuoka.jp",
+    "sicilia.it",
+    "wakasa.fukui.jp",
+    "mypets.ws",
+    "stockholm.museum",
+    "chita.ru",
+    "konan.aichi.jp",
+    "steigen.no",
+    "evje-og-hornnes.no",
+    "minamidaito.okinawa.jp",
+    "mil.do",
+    "nanbu.tottori.jp",
+    "gov.sx",
     "museum.mw",
-    "xn--srreisa-q1a.no",
-    "takahama.fukui.jp",
-    "yakumo.shimane.jp",
-    "maryland.museum",
-    "pc.pl",
-    "higashine.yamagata.jp",
-    "takagi.nagano.jp",
-    "presidio.museum",
-    "skjervoy.no",
-    "yanagawa.fukuoka.jp",
-    "hokuto.yamanashi.jp",
-    "tendo.yamagata.jp",
-    "tsuno.miyazaki.jp",
-    "ishinomaki.miyagi.jp",
-    "xn--gls-elac.no",
-    "pesaro-urbino.it",
-    "cc.ne.us",
-    "cc.nd.us",
-    "artanddesign.museum",
-    "cc.nj.us",
-    "teramo.it",
-    "funagata.yamagata.jp",
-    "tabuse.yamaguchi.jp",
-    "yakumo.hokkaido.jp",
-    "komoro.nagano.jp",
-    "cc.in.us",
-    "ap-southeast-2.compute.amazonaws.com",
-    "taiji.wakayama.jp",
-    "sodegaura.chiba.jp",
-    "roma.museum",
-    "afjord.no",
-    "miyakonojo.miyazaki.jp",
-    "tsuruoka.yamagata.jp",
-    "dyndns-web.com",
-    "tcm.museum",
-    "paroch.k12.ma.us",
-    "ishikawa.fukushima.jp",
-    "zushi.kanagawa.jp",
-    "okawa.kochi.jp",
-    "katsuyama.fukui.jp",
-    "tsuno.kochi.jp",
-    "tamakawa.fukushima.jp",
-    "from-vt.com",
-    "is-not-certified.com",
-    "cc.il.us",
-    "cc.nm.us",
-    "uvic.museum",
-    "sch.ly",
-    "sakegawa.yamagata.jp",
-    "tokai.ibaraki.jp",
-    "shibuya.tokyo.jp",
-    "githubusercontent.com",
-    "microlight.aero",
-    "ogose.saitama.jp",
-    "mesaverde.museum",
-    "aeroport.fr",
-    "ogano.saitama.jp",
-    "stavanger.no",
-    "fujishiro.ibaraki.jp",
-    "kihoku.ehime.jp",
-    "axis.museum",
-    "miasa.nagano.jp",
-    "pasadena.museum",
-    "fukuchi.fukuoka.jp",
-    "portland.museum",
-    "miyama.fukuoka.jp",
-    "rovno.ua",
-    "daigo.ibaraki.jp",
-    "xn--eveni-0qa01ga.no",
-    "press.museum",
-    "toyota.yamaguchi.jp",
-    "supplies",
-    "blogsite.org",
-    "minoh.osaka.jp",
-    "moriya.ibaraki.jp",
-    "money.museum",
-    "show.aero",
-    "yamato.kumamoto.jp",
-    "nagano.nagano.jp",
-    "tamba.hyogo.jp",
-    "minami.fukuoka.jp",
-    "niepce.museum",
-    "flatanger.no",
-    "aguni.okinawa.jp",
-    "oshima.yamaguchi.jp",
-    "management",
-    "sopot.pl",
-    "oguni.kumamoto.jp",
-    "sumida.tokyo.jp",
-    "ritto.shiga.jp",
-    "mad.museum",
-    "cc.nh.us",
-    "forde.no",
-    "media.pl",
-    "tsuiki.fukuoka.jp",
-    "okoppe.hokkaido.jp",
-    "prochowice.pl",
-    "cc.ny.us",
-    "casino.hu",
-    "tranoy.no",
-    "broker.aero",
-    "shinkamigoto.nagasaki.jp",
-    "mikawa.yamagata.jp",
-    "rivne.ua",
-    "ug.gov.pl",
-    "fermo.it",
-    "yashio.saitama.jp",
-    "shiogama.miyagi.jp",
-    "morioka.iwate.jp",
-    "paleo.museum",
-    "science-fiction.museum",
-    "xn--gildeskl-g0a.no",
-    "fortworth.museum",
-    "loppa.no",
-    "dyndns.info",
-    "toyono.osaka.jp",
-    "feedback",
-    "michigan.museum",
-    "historyofscience.museum",
+    "hotel.hu",
+    "andoy.no",
+    "cc",
+    "radom.pl",
+    "stjordalshalsen.no",
+    "rauma.no",
+    "sobetsu.hokkaido.jp",
+    "shimane.shimane.jp",
+    "spjelkavik.no",
+    "yamal.ru",
+    "nc",
+    "net.cw",
+    "gov.cl",
+    "com.cw",
+    "ec",
+    "gob.cl",
+    "net.cn",
+    "com.cn",
+    "konin.pl",
+    "gov.cn",
+    "navy",
+    "vyatka.ru",
+    "hidaka.wakayama.jp",
+    "mil.to",
+    "samara.ru",
+    "rubtsovsk.ru",
+    "edu.cw",
+    "akita.jp",
+    "cyber.museum",
+    "yugawa.fukushima.jp",
+    "shimabara.nagasaki.jp",
+    "yamatotakada.nara.jp",
+    "edu.cn",
+    "snoasa.no",
+    "gov.cd",
+    "film.hu",
+    "clock.museum",
+    "from-id.com",
+    "izumi.osaka.jp",
+    "atami.shizuoka.jp",
+    "mil.jo",
+    "ikoma.nara.jp",
+    "ac",
+    "kanan.osaka.jp",
+    "om",
+    "kanra.gunma.jp",
+    "fuoisku.no",
+    "net.mx",
+    "shirosato.ibaraki.jp",
+    "com.mx",
+    "savona.it",
+    "hakone.kanagawa.jp",
+    "aichi.jp",
+    "gob.mx",
+    "surgut.ru",
+    "miyada.nagano.jp",
+    "kasuga.fukuoka.jp",
+    "mitaka.tokyo.jp",
+    "mochizuki.nagano.jp",
+    "org",
+    "nanae.hokkaido.jp",
+    "biz",
+    "org.sl",
+    "army",
+    "org.st",
+    "org.ec",
+    "org.sc",
+    "edu.mx",
+    "franziskaner.museum",
+    "org.pl",
+    "org.pk",
+    "org.pt",
+    "org.pr",
+    "biz.pl",
+    "biz.pk",
+    "biz.pr",
+    "org.sn",
+    "mil.bo",
+    "org.es",
+    "watari.miyagi.jp",
+    "kamikoani.akita.jp",
+    "org.pn",
+    "org.ps",
+    "midori.gunma.jp",
+    "minami.tokushima.jp",
+    "odda.no",
+    "actor",
+    "aca.pro",
+    "miyota.nagano.jp",
+    "org.al",
+    "skanit.no",
+    "org.ar",
+    "org.ac",
+    "biz.at",
+    "chiba.jp",
+    "mil.no",
+    "org.tt",
+    "yakage.okayama.jp",
+    "org.sd",
+    "org.tw",
+    "biz.tt",
+    "ecn.br",
+    "org.an",
+    "wake.okayama.jp",
+    "oslo.no",
+    "gov.cm",
+    "org.sb",
+    "wales.museum",
+    "org.tn",
+    "from-va.com",
+    "soma.fukushima.jp",
+    "skodje.no",
+    "org.ee",
+    "org.se",
+    "org.rs",
+    "zgrad.ru",
+    "aukra.no",
+    "org.pe",
+    "minamiuonuma.niigata.jp",
+    "handa.aichi.jp",
+    "frankfurt.museum",
+    "satosho.okayama.jp",
+    "org.ml",
+    "org.mk",
+    "org.mt",
+    "org.mw",
+    "biz.mw",
+    "stokke.no",
+    "org.mn",
+    "oita.jp",
+    "org.ae",
+    "org.ms",
+    "minamitane.kagoshima.jp",
+    "ong",
+    "shimoji.okinawa.jp",
+    "onl",
+    "abeno.osaka.jp",
+    "org.tj",
+    "biz.tj",
+    "osen.no",
+    "org.ir",
+    "iijima.nagano.jp",
+    "academy",
+    "ikeda.osaka.jp",
+    "o.bg",
+    "ikeda.nagano.jp",
+    "democrat",
+    "org.in",
+    "org.bt",
+    "org.is",
+    "org.br",
+    "org.bw",
+    "rieti.it",
+    "frosta.no",
+    "seranishi.hiroshima.jp",
+    "ainan.ehime.jp",
+    "org.dm",
+    "org.je",
+    "org.om",
+    "org.bs",
+    "hanno.saitama.jp",
+    "kurogi.fukuoka.jp",
+    "org.me",
+    "kosai.shizuoka.jp",
+    "shikabe.hokkaido.jp",
+    "misaki.osaka.jp",
+    "fauske.no",
+    "farmequipment.museum",
+    "youth.museum",
+    "shimamaki.hokkaido.jp",
+    "asahi.toyama.jp",
+    "org.nr",
+    "biz.id",
+    "biz.nr",
+    "odo.br",
+    "reggio-calabria.it",
+    "ikata.ehime.jp",
+    "wlocl.pl",
+    "yabuki.fukushima.jp",
+    "sennan.osaka.jp",
+    "fosnes.no",
+    "fukushima.jp",
+    "org.sa",
+    "org.bb",
+    "biz.bb",
+    "org.tm",
+    "org.pa",
+    "aikawa.kanagawa.jp",
+    "eco.br",
+    "mikasa.hokkaido.jp",
+    "cymru.museum",
+    "iwata.shizuoka.jp",
+    "furubira.hokkaido.jp",
+    "bykle.no",
+    "org.lk",
+    "bibai.hokkaido.jp",
+    "org.lr",
+    "org.lc",
+    "org.vc",
+    "makurazaki.kagoshima.jp",
+    "honai.ehime.jp",
+    "org.pf",
+    "org.ls",
+    "codespot.com",
+    "is-a-cpa.com",
+    "org.vn",
+    "biz.vn",
+    "shimonita.gunma.jp",
+    "shimokitayama.nara.jp",
+    "shibata.miyagi.jp",
+    "malopolska.pl",
+    "o.se",
+    "org.ua",
+    "nanbu.yamanashi.jp",
+    "org.af",
+    "ikeda.fukui.jp",
+    "kunimi.fukushima.jp",
+    "org.lb",
+    "rissa.no",
+    "shikama.miyagi.jp",
+    "org.im",
+    "ebino.miyazaki.jp",
+    "mimata.miyazaki.jp",
+    "shichinohe.aomori.jp",
+    "izena.okinawa.jp",
+    "yamatokoriyama.nara.jp",
+    "skierva.no",
+    "shibata.niigata.jp",
+    "ustka.pl",
+    "cf",
+    "bf",
+    "org.ma",
+    "gf",
+    "nf",
+    "shibetsu.hokkaido.jp",
+    "ifm",
+    "org.ve",
+    "is-a-painter.com",
+    "org.bm",
+    "com.fr",
+    "nom.fr",
+    "saka.hiroshima.jp",
+    "askoy.no",
+    "risor.no",
+    "siljan.no",
     "grong.no",
-    "barrel-of-knowledge.info",
-    "sanok.pl",
-    "sorum.no",
-    "eniwa.hokkaido.jp",
-    "tree.museum",
-    "sauda.no",
-    "tank.museum",
-    "stuff-4-sale.us",
-    "mihama.wakayama.jp",
-    "ujiie.tochigi.jp",
-    "pubol.museum",
-    "tokamachi.niigata.jp",
-    "nakano.nagano.jp",
-    "graphics",
-    "bahn.museum",
-    "sor-fron.no",
-    "seirou.niigata.jp",
-    "mazury.pl",
-    "tranby.no",
-    "time.museum",
-    "nishio.aichi.jp",
-    "snasa.no",
-    "suzaka.nagano.jp",
-    "fjell.no",
-    "stryn.no",
-    "klepp.no",
-    "kitagata.gifu.jp",
-    "engine.aero",
-    "kumakogen.ehime.jp",
-    "salat.no",
+    "raisa.no",
+    "kinko.kagoshima.jp",
+    "ouda.nara.jp",
+    "sayama.osaka.jp",
+    "ovh",
+    "shibecha.hokkaido.jp",
+    "izumi.kagoshima.jp",
+    "higashikagawa.kagawa.jp",
+    "ayabe.kyoto.jp",
+    "ikeda.hokkaido.jp",
+    "aisai.aichi.jp",
+    "org.ba",
+    "org.kp",
+    "imari.saga.jp",
+    "org.hk",
+    "org.ht",
+    "embaixada.st",
+    "nango.fukushima.jp",
+    "sunagawa.hokkaido.jp",
+    "org.kn",
+    "directory",
     "k12.nv.us",
-    "for-our.info",
-    "sandiego.museum",
-    "stathelle.no",
-    "imizu.toyama.jp",
-    "sklep.pl",
-    "forlicesena.it",
-    "susaki.kochi.jp",
-    "shimotsuke.tochigi.jp",
-    "minamiechizen.fukui.jp",
-    "seaport.museum",
-    "computer.museum",
-    "cc.nv.us",
-    "fundacio.museum",
-    "mizumaki.fukuoka.jp",
-    "fuettertdasnetz.de",
-    "slask.pl",
-    "mazowsze.pl",
-    "higashishirakawa.gifu.jp",
-    "est-mon-blogueur.com",
-    "chizu.tottori.jp",
-    "beppu.oita.jp",
-    "tarnobrzeg.pl",
-    "hirado.nagasaki.jp",
-    "shichikashuku.miyagi.jp",
-    "stjohn.museum",
-    "school.museum",
-    "shirakawa.gifu.jp",
+    "af",
+    "org.hn",
+    "hyogo.jp",
+    "jgora.pl",
+    "org.na",
+    "zgora.pl",
+    "reggioemilia.it",
+    "dyroy.no",
+    "itano.tokushima.jp",
+    "asahi.nagano.jp",
+    "org.qa",
+    "heroy.nordland.no",
+    "square.museum",
+    "saigawa.fukuoka.jp",
+    "hitoyoshi.kumamoto.jp",
+    "daito.osaka.jp",
+    "chernovtsy.ua",
+    "is-an-actress.com",
+    "hiroo.hokkaido.jp",
+    "shiroishi.saga.jp",
+    "org.la",
+    "kaita.hiroshima.jp",
+    "amami.kagoshima.jp",
+    "kazo.saitama.jp",
+    "akita.akita.jp",
+    "kizu.kyoto.jp",
+    "shinichi.hiroshima.jp",
+    "arita.saga.jp",
+    "minowa.nagano.jp",
+    "vaapste.no",
+    "hongo.hiroshima.jp",
+    "komae.tokyo.jp",
+    "org.eg",
+    "org.sg",
+    "mining.museum",
+    "naganohara.gunma.jp",
+    "org.iq",
+    "agrar.hu",
+    "komono.mie.jp",
+    "is-an-artist.com",
+    "org.ws",
+    "erimo.hokkaido.jp",
+    "minamiawaji.hyogo.jp",
+    "foggia.it",
+    "nishiokoppe.hokkaido.jp",
+    "sasayama.hyogo.jp",
+    "essex.museum",
+    "ashiya.fukuoka.jp",
+    "miyagi.jp",
+    "show.aero",
+    "buryatia.ru",
+    "org.ag",
+    "honjo.akita.jp",
+    "nakanojo.gunma.jp",
+    "is-a-llama.com",
+    "sayama.saitama.jp",
+    "is-a-rockstar.com",
+    "katano.osaka.jp",
+    "org.km",
+    "sweden.museum",
+    "kuzbass.ru",
+    "from-vt.com",
+    "org.ug",
+    "rodoy.no",
+    "kumano.mie.jp",
+    "fitjar.no",
+    "shinshiro.aichi.jp",
+    "skydiving.aero",
+    "suli.hu",
+    "nagano.jp",
+    "musashimurayama.tokyo.jp",
+    "chita.aichi.jp",
+    "fukumitsu.toyama.jp",
+    "is-by.us",
+    "org.mg",
+    "xyz",
+    "net.ci",
+    "inami.wakayama.jp",
+    "kochi.kochi.jp",
+    "com.ci",
+    "radoy.no",
+    "yalta.ua",
+    "edu.ci",
+    "fukusaki.hyogo.jp",
+    "minamisanriku.miyagi.jp",
+    "forgot.his.name",
+    "mukawa.hokkaido.jp",
+    "radio.br",
+    "ginan.gifu.jp",
+    "city.sapporo.jp",
+    "org.ng",
+    "mansion.museum",
+    "honjo.saitama.jp",
+    "miyama.fukuoka.jp",
+    "konyvelo.hu",
+    "sendai.jp",
+    "2000.hu",
+    "info.ec",
+    "suisse.museum",
+    "nagai.yamagata.jp",
+    "kanie.aichi.jp",
+    "murata.miyagi.jp",
+    "opoczno.pl",
+    "askim.no",
+    "yaese.okinawa.jp",
+    "dontexist.net",
+    "blogspot.ca",
+    "ostroda.pl",
+    "batsfjord.no",
     "mihama.fukui.jp",
-    "fedje.no",
-    "skaun.no",
-    "taki.mie.jp",
-    "government.aero",
-    "trader.aero",
-    "sch.jo",
-    "toyako.hokkaido.jp",
-    "yonago.tottori.jp",
-    "ogori.fukuoka.jp",
-    "maritimo.museum",
-    "xn--kvitsy-fya.no",
-    "servegame.org",
-    "inawashiro.fukushima.jp",
-    "station.museum",
-    "horology.museum",
-    "okawa.fukuoka.jp",
-    "software.aero",
-    "selje.no",
-    "miharu.fukushima.jp",
-    "settlers.museum",
-    "shop.pl",
-    "motegi.tochigi.jp",
-    "pavia.it",
-    "moriyoshi.akita.jp",
-    "ryuoh.shiga.jp",
-    "selbu.no",
-    "sakura.tochigi.jp",
-    "muenster.museum",
-    "marumori.miyagi.jp",
-    "sakawa.kochi.jp",
-    "vibo-valentia.it",
-    "xn--berlevg-jxa.no",
-    "aki.kochi.jp",
-    "fujisawa.kanagawa.jp",
-    "tokorozawa.saitama.jp",
-    "figueres.museum",
-    "xn--rennesy-v1a.no",
-    "k12.ny.us",
-    "songdalen.no",
-    "honefoss.no",
-    "urawa.saitama.jp",
-    "pskov.ru",
-    "k12.ky.us",
-    "sakaki.nagano.jp",
-    "tsuga.tochigi.jp",
-    "cc.nc.us",
-    "federation.aero",
-    "finearts.museum",
-    "from-or.com",
-    "manchester.museum",
+    "iwade.wakayama.jp",
+    "org.ai",
+    "koori.fukushima.jp",
+    "ikeda.gifu.jp",
+    "selfip.org",
+    "industries",
+    "chino.nagano.jp",
+    "iamallama.com",
+    "aerodrome.aero",
+    "blogspot.cz",
     "stange.no",
-    "tamano.okayama.jp",
-    "forum.hu",
-    "sumita.iwate.jp",
-    "medio-campidano.it",
-    "fukui.jp",
-    "from-ok.com",
-    "media.hu",
-    "s3-sa-east-1.amazonaws.com",
-    "force.museum",
-    "agano.niigata.jp",
-    "uchinomi.kagawa.jp",
-    "from-oh.com",
-    "sakyo.kyoto.jp",
-    "shiraoka.saitama.jp",
-    "military.museum",
-    "munakata.fukuoka.jp",
-    "k12.wy.us",
-    "makinohara.shizuoka.jp",
-    "space.museum",
-    "production.aero",
-    "miyawaka.fukuoka.jp",
-    "shinanomachi.nagano.jp",
-    "sakata.yamagata.jp",
-    "utazu.kagawa.jp",
-    "state.museum",
-    "xn--ryken-vua.no",
-    "takayama.gifu.jp",
-    "tanagura.fukushima.jp",
-    "oguni.yamagata.jp",
-    "niiza.saitama.jp",
-    "inabe.mie.jp",
-    "field.museum",
-    "matsumae.hokkaido.jp",
-    "media.museum",
-    "mytis.ru",
-    "soja.okayama.jp",
-    "stalbans.museum",
-    "xn--nmesjevuemie-tcba.no",
-    "leitungsen.de",
-    "dali.museum",
-    "stadt.museum",
-    "skien.no",
-    "tromso.no",
-    "horonobe.hokkaido.jp",
-    "xn--skjervy-v1a.no",
-    "passenger-association.aero",
-    "ebina.kanagawa.jp",
-    "iron.museum",
-    "sanuki.kagawa.jp",
-    "seika.kyoto.jp",
-    "torino.it",
-    "steam.museum",
-    "kyowa.akita.jp",
-    "morimachi.shizuoka.jp",
-    "tgory.pl",
-    "settlement.museum",
-    "sandoy.no",
-    "corvette.museum",
+    "org.sz",
+    "akune.kagoshima.jp",
+    "org.dz",
+    "bremanger.no",
+    "academy.museum",
+    "nanjo.okinawa.jp",
+    "ibara.okayama.jp",
+    "contractors",
+    "int.ci",
+    "iwaki.fukushima.jp",
+    "homeftp.net",
+    "blogspot.com",
+    "shimokawa.hokkaido.jp",
+    "gratangen.no",
+    "rygge.no",
+    "ostrowwlkp.pl",
+    "blogspot.com.es",
+    "itami.hyogo.jp",
+    "kumano.hiroshima.jp",
+    "blogspot.co.nz",
+    "asso.nc",
+    "brescia.it",
+    "org.az",
+    "biz.az",
+    "b.ssl.fastly.net",
+    "balsfjord.no",
+    "nishi.osaka.jp",
+    "hiji.oita.jp",
+    "qld.gov.au",
+    "kunitomi.miyazaki.jp",
+    "anthropology.museum",
+    "ballangen.no",
+    "is-a-socialist.com",
+    "bilbao.museum",
+    "org.uz",
+    "nanao.ishikawa.jp",
+    "shijonawate.osaka.jp",
+    "fujioka.gunma.jp",
+    "hyuga.miyazaki.jp",
+    "molde.no",
+    "noda.chiba.jp",
+    "otsuka",
+    "org.kg",
+    "org.bi",
+    "samukawa.kanagawa.jp",
+    "naruto.tokushima.jp",
+    "wakuya.miyagi.jp",
+    "koshu.yamanashi.jp",
+    "nakanoto.ishikawa.jp",
+    "konan.shiga.jp",
+    "rovno.ua",
+    "atsugi.kanagawa.jp",
+    "valdaosta.it",
+    "misugi.mie.jp",
+    "is-an-accountant.com",
+    "a.ssl.fastly.net",
+    "blogspot.com.ar",
+    "szkola.pl",
+    "bialowieza.pl",
+    "dontexist.org",
+    "nemuro.hokkaido.jp",
+    "saroma.hokkaido.jp",
+    "brussels.museum",
+    "bruxelles.museum",
+    "arida.wakayama.jp",
+    "blogspot.com.au",
+    "org.bz",
+    "blogspot.co.at",
+    "modum.no",
+    "blogspot.cv",
+    "ilawa.pl",
+    "okinawa",
+    "usuki.oita.jp",
+    "heroy.more-og-romsdal.no",
+    "friuli-vgiulia.it",
+    "asago.hyogo.jp",
+    "conference.aero",
+    "is-uberleet.com",
+    "org.vi",
+    "sakura.chiba.jp",
+    "misaki.okayama.jp",
+    "asso.mc",
+    "nayoro.hokkaido.jp",
+    "niimi.okayama.jp",
+    "iwate.iwate.jp",
+    "notaires.fr",
+    "fukuyama.hiroshima.jp",
+    "org.sh",
+    "namdalseid.no",
+    "hioki.kagoshima.jp",
+    "org.ph",
+    "cloudcontrolled.com",
+    "rivne.ua",
+    "ostre-toten.no",
+    "oyer.no",
+    "blogspot.com.br",
+    "council.aero",
+    "minamiashigara.kanagawa.jp",
+    "kakinoki.shimane.jp",
+    "yuasa.wakayama.jp",
+    "city.sendai.jp",
+    "game-server.cc",
+    "wajiki.tokushima.jp",
+    "inagi.tokyo.jp",
+    "wajima.ishikawa.jp",
+    "vik.no",
+    "udine.it",
+    "abira.hokkaido.jp",
+    "fuji.shizuoka.jp",
+    "osakasayama.osaka.jp",
+    "kamitonda.wakayama.jp",
+    "cultural.museum",
+    "blogspot.co.il",
+    "ulsan.kr",
+    "azure-mobile.net",
     "sannan.hyogo.jp",
-    "sue.fukuoka.jp",
-    "yamagata.gifu.jp",
-    "nagiso.nagano.jp",
-    "works.aero",
-    "hadano.kanagawa.jp",
-    "pesarourbino.it",
-    "pulawy.pl",
-    "seiyo.ehime.jp",
-    "saiki.oita.jp",
-    "xn--fzc2c9e2c",
-    "saikai.nagasaki.jp",
-    "s3-ap-northeast-1.amazonaws.com",
-    "shimoichi.nara.jp",
-    "shikaoi.hokkaido.jp",
-    "cargo.aero",
-    "saito.miyazaki.jp",
-    "kaminokawa.tochigi.jp",
-    "coastaldefence.museum",
-    "trento.it",
-    "asahi.mie.jp",
-    "spy.museum",
-    "oshino.yamanashi.jp",
-    "salem.museum",
-    "paris.museum",
-    "shiraoi.hokkaido.jp",
-    "gs.sf.no",
-    "samnanger.no",
-    "for-better.biz",
+    "sekikawa.niigata.jp",
+    "in-the-band.net",
+    "blogspot.ch",
+    "cloudcontrolapp.com",
+    "org.ki",
+    "biz.ki",
+    "rebun.hokkaido.jp",
+    "itayanagi.aomori.jp",
+    "googleapis.com",
+    "oristano.it",
+    "shiojiri.nagano.jp",
+    "is-a-student.com",
+    "doshi.yamanashi.jp",
+    "nishi.fukuoka.jp",
+    "is-a-teacher.com",
+    "wf",
+    "org.gt",
+    "org.gp",
+    "org.gr",
+    "furukawa.miyagi.jp",
+    "shishikui.tokushima.jp",
+    "fujisawa.iwate.jp",
+    "gosen.niigata.jp",
+    "maniwa.okayama.jp",
+    "org.gn",
+    "asahi.yamagata.jp",
+    "yazu.tottori.jp",
+    "namie.fukushima.jp",
+    "friuliv-giulia.it",
+    "kvanangen.no",
+    "mbone.pl",
+    "org.kz",
+    "kasai.hyogo.jp",
+    "org.bh",
+    "skjervoy.no",
+    "is-a-bookkeeper.com",
+    "minami.fukuoka.jp",
+    "is-a-conservative.com",
+    "chofu.tokyo.jp",
+    "anthro.museum",
+    "blogspot.fr",
+    "org.ge",
+    "oji.nara.jp",
+    "vardo.no",
+    "chuo.chiba.jp",
+    "hammerfest.no",
+    "is-a-nurse.com",
+    "nagareyama.chiba.jp",
+    "jerusalem.museum",
+    "asmatart.museum",
+    "uhren.museum",
+    "kosei.shiga.jp",
+    "yurihonjo.akita.jp",
+    "starostwo.gov.pl",
+    "mutsu.aomori.jp",
+    "shibukawa.gunma.jp",
+    "friulivgiulia.it",
+    "berkeley.museum",
+    "consultant.aero",
+    "vadso.no",
+    "act.edu.au",
+    "ashoro.hokkaido.jp",
+    "valle.no",
+    "blogspot.fi",
+    "volda.no",
+    "kiho.mie.jp",
+    "fujiidera.osaka.jp",
+    "milan.it",
+    "ambulance.aero",
+    "okegawa.saitama.jp",
+    "ostroleka.pl",
+    "donostia.museum",
+    "sel.no",
+    "baltimore.museum",
+    "shinagawa.tokyo.jp",
+    "elb.amazonaws.com",
+    "shinshinotsu.hokkaido.jp",
+    "fujisato.akita.jp",
+    "bihoro.hokkaido.jp",
+    "fujieda.shizuoka.jp",
+    "sld.do",
+    "shimogo.fukushima.jp",
+    "haboro.hokkaido.jp",
+    "okinawa.jp",
+    "seki.gifu.jp",
+    "columbia.museum",
+    "yusui.kagoshima.jp",
+    "blogspot.co.uk",
+    "annefrank.museum",
+    "aarborte.no",
+    "oygarden.no",
+    "hazu.aichi.jp",
+    "hammarfeasta.no",
+    "yamato.kumamoto.jp",
+    "chambagri.fr",
+    "azurewebsites.net",
+    "krokstadelva.no",
+    "is-an-entertainer.com",
+    "ohda.shimane.jp",
+    "vefsn.no",
+    "american.museum",
+    "yotsukaido.chiba.jp",
+    "komoro.nagano.jp",
+    "culturalcenter.museum",
+    "is-into-cars.com",
+    "mikawa.yamagata.jp",
+    "cloudfront.net",
+    "yorii.saitama.jp",
+    "fukagawa.hokkaido.jp",
+    "mihama.wakayama.jp",
+    "fujimino.saitama.jp",
+    "kolobrzeg.pl",
+    "omsk.ru",
+    "nieruchomosci.pl",
+    "kuzumaki.iwate.jp",
+    "shiranuka.hokkaido.jp",
+    "insurance.aero",
+    "homeunix.com",
+    "yoshioka.gunma.jp",
+    "fukushima.hokkaido.jp",
+    "iwakura.aichi.jp",
+    "vagan.no",
+    "koza.wakayama.jp",
+    "omi.nagano.jp",
+    "shirataka.yamagata.jp",
+    "nebraska.museum",
+    "shimosuwa.nagano.jp",
+    "artcenter.museum",
+    "journalist.aero",
+    "chocolate.museum",
+    "is-a-personaltrainer.com",
+    "dyndns-pics.com",
+    "naamesjevuemie.no",
+    "openair.museum",
+    "oshu.iwate.jp",
+    "kchr.ru",
+    "yamamoto.miyagi.jp",
+    "stjohn.museum",
+    "shimizu.hokkaido.jp",
+    "ontario.museum",
+    "fet.no",
+    "epilepsy.museum",
+    "airguard.museum",
+    "sapporo.jp",
+    "aguni.okinawa.jp",
+    "sagamihara.kanagawa.jp",
+    "groks-this.info",
+    "oppegard.no",
+    "otsu.shiga.jp",
+    "overhalla.no",
+    "meloy.no",
+    "viking.museum",
+    "helsinki.museum",
+    "dyndns-ip.com",
+    "shisui.chiba.jp",
+    "freight.aero",
+    "ls",
+    "new",
+    "org.gg",
+    "barreau.bj",
+    "creation.museum",
+    "shiroishi.miyagi.jp",
+    "support",
+    "lease",
+    "dreamhosters.com",
+    "friuli-v-giulia.it",
+    "immobilien",
+    "shop.pl",
+    "altoadige.it",
+    "boleslawiec.pl",
+    "city.nagoya.jp",
+    "london",
+    "uruma.okinawa.jp",
+    "casino.hu",
+    "baseball.museum",
+    "la",
+    "land",
+    "church",
+    "nagano.nagano.jp",
+    "oga.akita.jp",
+    "lt",
+    "net.au",
+    "ama.aichi.jp",
+    "ambulance.museum",
+    "com.au",
+    "nikaho.akita.jp",
+    "gov.au",
+    "shimizu.shizuoka.jp",
+    "lr",
+    "nrw",
+    "hirono.iwate.jp",
+    "gouv.km",
+    "net.ru",
+    "com.ru",
+    "gov.ru",
+    "nov.ru",
+    "lu",
+    "vgs.no",
+    "kamigori.hyogo.jp",
+    "association.aero",
+    "edu.au",
+    "krym.ua",
+    "shinkamigoto.nagasaki.jp",
+    "edu.ru",
+    "is-into-cartoons.com",
+    "net.mu",
+    "com.mu",
+    "oregontrail.museum",
+    "gov.mu",
+    "jar.ru",
+    "asn.au",
+    "aisho.shiga.jp",
+    "dnsalias.com",
+    "gouv.rw",
+    "li",
+    "yoita.niigata.jp",
+    "lebesby.no",
+    "omigawa.chiba.jp",
+    "lom.it",
+    "hobby-site.com",
+    "is-a-blogger.com",
+    "limo",
+    "lb",
+    "karumai.iwate.jp",
+    "media.pl",
+    "interactive.museum",
+    "is-a-republican.com",
+    "yamanouchi.nagano.jp",
+    "coal.museum",
+    "fla.no",
+    "lund.no",
+    "ritto.shiga.jp",
+    "kaminoyama.yamagata.jp",
+    "fujikawa.shizuoka.jp",
+    "omaezaki.shizuoka.jp",
+    "bir.ru",
+    "yakumo.shimane.jp",
+    "money.museum",
+    "video.hu",
+    "bunkyo.tokyo.jp",
+    "guernsey.museum",
+    "sarpsborg.no",
+    "link",
+    "gouv.bj",
+    "zakopane.pl",
+    "okutama.tokyo.jp",
+    "org.gi",
+    "mc",
+    "lib.ee",
+    "gouv.ml",
+    "iraq.museum",
+    "ikawa.akita.jp",
+    "leg.br",
+    "is-a-geek.net",
+    "lel.br",
+    "life",
+    "lv",
+    "from-or.com",
+    "oumu.hokkaido.jp",
+    "int.ru",
+    "miasa.nagano.jp",
+    "chiyoda.gunma.jp",
+    "city.kawasaki.jp",
+    "boutique",
+    "natuurwetenschappen.museum",
+    "shiroi.chiba.jp",
+    "omitama.ibaraki.jp",
+    "beeldengeluid.museum",
+    "elvendrell.museum",
+    "l.bg",
+    "national.museum",
+    "gouv.sn",
+    "masoy.no",
+    "gouv.ci",
+    "cbg.ru",
+    "shirahama.wakayama.jp",
+    "dynalias.com",
+    "iki.fi",
+    "nankoku.kochi.jp",
+    "nakano.tokyo.jp",
+    "agano.niigata.jp",
+    "oppdal.no",
+    "association.museum",
+    "arts.museum",
+    "orkanger.no",
+    "varoy.no",
+    "nikko.tochigi.jp",
+    "hattfjelldal.no",
+    "is-into-games.com",
+    "saratov.ru",
+    "is-certified.com",
+    "bahccavuotna.no",
+    "kasukabe.saitama.jp",
+    "chiropractic.museum",
+    "yonago.tottori.jp",
+    "sumida.tokyo.jp",
+    "kraanghke.no",
+    "homeftp.org",
+    "ulvik.no",
+    "bern.museum",
+    "bonn.museum",
+    "bale.museum",
+    "org.sv",
+    "ascoli-piceno.it",
+    "is-a-guru.com",
+    "how",
+    "ltd.lk",
+    "lig.it",
+    "from-ok.com",
+    "botanical.museum",
+    "kids.museum",
+    "children.museum",
+    "hokuto.hokkaido.jp",
+    "lk",
+    "gouv.fr",
+    "bill.museum",
+    "otofuke.hokkaido.jp",
+    "oishida.yamagata.jp",
+    "research.aero",
+    "is-a-patsfan.org",
+    "ibigawa.gifu.jp",
+    "sumita.iwate.jp",
+    "elverum.no",
+    "columbus.museum",
+    "k12.mo.us",
+    "glas.museum",
+    "britishcolumbia.museum",
+    "l.se",
+    "is-a-geek.org",
+    "awaji.hyogo.jp",
+    "isshiki.aichi.jp",
+    "hakui.ishikawa.jp",
+    "is-a-designer.com",
+    "city.hu",
+    "livorno.it",
+    "ogi.saga.jp",
+    "khv.ru",
+    "mil.cl",
+    "org.mv",
+    "biz.mv",
+    "artgallery.museum",
+    "mil.cn",
+    "narashino.chiba.jp",
+    "historichouses.museum",
+    "ski.no",
+    "ishinomaki.miyagi.jp",
+    "kids.us",
+    "lillesand.no",
+    "dyndns-at-home.com",
+    "station.museum",
+    "civilwar.museum",
+    "leasing.aero",
+    "institute",
+    "kms.ru",
+    "sopot.pl",
+    "org.gh",
+    "chiyoda.tokyo.jp",
+    "onagawa.miyagi.jp",
+    "from-oh.com",
+    "ayase.kanagawa.jp",
+    "media.museum",
+    "seaport.museum",
+    "lipetsk.ru",
+    "is-a-hard-worker.com",
+    "yashio.saitama.jp",
+    "hoylandet.no",
+    "iron.museum",
+    "kuroiso.tochigi.jp",
+    "honjyo.akita.jp",
+    "funagata.yamagata.jp",
+    "sakegawa.yamagata.jp",
+    "hokuto.yamanashi.jp",
+    "org.lv",
+    "manno.kagawa.jp",
     "milano.it",
-    "moma.museum",
-    "shioya.tochigi.jp",
-    "gs.of.no",
-    "katowice.pl",
-    "fukudomi.saga.jp",
-    "xn--vler-qoa.xn--stfold-9xa.no",
-    "fribourg.museum",
-    "shizukuishi.iwate.jp",
-    "sykkylven.no",
-    "manx.museum",
-    "s3-us-gov-west-1.amazonaws.com",
-    "xn--langevg-jxa.no",
-    "gs.vf.no",
+    "lier.no",
+    "fukaya.saitama.jp",
+    "umaji.kochi.jp",
+    "exchange",
+    "vc",
+    "minoh.osaka.jp",
+    "iwakuni.yamaguchi.jp",
+    "vikna.no",
+    "artsandcrafts.museum",
+    "ooshika.nagano.jp",
+    "ebina.kanagawa.jp",
+    "is-a-chef.net",
+    "orland.no",
+    "bahn.museum",
+    "yaita.tochigi.jp",
+    "dinosaur.museum",
+    "mielno.pl",
+    "veneto.it",
+    "skoczow.pl",
+    "uozu.toyama.jp",
+    "nakai.kanagawa.jp",
+    "consulting.aero",
+    "sauda.no",
+    "sorum.no",
+    "riodejaneiro.museum",
+    "botanicgarden.museum",
+    "fhs.no",
+    "sakata.yamagata.jp",
+    "onomichi.hiroshima.jp",
+    "kawasaki.jp",
+    "kvalsund.no",
+    "nakano.nagano.jp",
+    "shiogama.miyagi.jp",
+    "media.hu",
+    "olbiatempio.it",
+    "fujishiro.ibaraki.jp",
+    "hirado.nagasaki.jp",
+    "ly",
+    "ringsaker.no",
+    "exchange.aero",
+    "kyowa.akita.jp",
+    "abu.yamaguchi.jp",
+    "city.kitakyushu.jp",
+    "salat.no",
+    "osakikamijima.hiroshima.jp",
+    "andasuolo.no",
+    "aviation.museum",
+    "shoo.okayama.jp",
+    "dyndns-at-work.com",
+    "somna.no",
+    "nsk.ru",
+    "yakumo.hokkaido.jp",
+    "ringerike.no",
+    "judygarland.museum",
+    "ogasawara.tokyo.jp",
+    "la-spezia.it",
+    "snasa.no",
+    "kouyama.kagoshima.jp",
+    "hachinohe.aomori.jp",
+    "sogne.no",
+    "is-a-photographer.com",
+    "is-a-chef.org",
+    "dyndns-blog.com",
+    "arkhangelsk.ru",
+    "kitagawa.kochi.jp",
+    "askvoll.no",
+    "juif.museum",
+    "leka.no",
+    "andria-barletta-trani.it",
+    "achi.nagano.jp",
+    "shirakawa.gifu.jp",
+    "naturhistorisches.museum",
+    "zushi.kanagawa.jp",
+    "okinoshima.shimane.jp",
+    "vic.gov.au",
+    "zgorzelec.pl",
+    "waw.pl",
+    "minato.osaka.jp",
+    "nagiso.nagano.jp",
+    "odessa.ua",
+    "legnica.pl",
+    "davvesiida.no",
+    "hichiso.gifu.jp",
+    "onga.fukuoka.jp",
+    "lugansk.ua",
+    "washingtondc.museum",
+    "sanok.pl",
+    "smola.no",
+    "forde.no",
+    "nozawaonsen.nagano.jp",
+    "marumori.miyagi.jp",
+    "marketplace.aero",
+    "experts-comptables.fr",
+    "okinawa.okinawa.jp",
+    "watchandclock.museum",
+    "space.museum",
+    "state.museum",
+    "supplies",
+    "oiso.kanagawa.jp",
+    "futaba.fukushima.jp",
+    "york.museum",
+    "selbu.no",
+    "land-4-sale.us",
+    "seoul.kr",
+    "stadt.museum",
+    "fujikawa.yamanashi.jp",
+    "jewelry.museum",
+    "obihiro.hokkaido.jp",
+    "sklep.pl",
+    "daiwa.hiroshima.jp",
+    "windmill.museum",
+    "miyakonojo.miyazaki.jp",
+    "noboribetsu.hokkaido.jp",
+    "fermo.it",
+    "building.museum",
+    "mytis.ru",
+    "store.ro",
+    "hashima.gifu.jp",
+    "steam.museum",
+    "fortworth.museum",
+    "siena.it",
+    "jeonbuk.kr",
+    "nisshin.aichi.jp",
+    "eniwa.hokkaido.jp",
+    "discount",
+    "yusuhara.kochi.jp",
+    "oirase.aomori.jp",
+    "moriyoshi.akita.jp",
+    "wloclawek.pl",
+    "homelinux.com",
+    "orkdal.no",
+    "lincoln.museum",
+    "slask.pl",
+    "omi.niigata.jp",
     "surgeonshall.museum",
+    "is-a-bruinsfan.org",
+    "homebuilt.aero",
+    "lorenskog.no",
+    "yachimata.chiba.jp",
+    "assedic.fr",
+    "dominic.ua",
+    "salem.museum",
+    "klepp.no",
+    "qld.au",
+    "shonai.yamagata.jp",
+    "stord.no",
+    "skaun.no",
+    "roma.museum",
+    "convent.museum",
+    "kiwi",
+    "liguria.it",
+    "ryuoh.shiga.jp",
+    "hirono.fukushima.jp",
+    "frana.no",
+    "groks-the.info",
+    "oksnes.no",
+    "copenhagen.museum",
+    "minano.saitama.jp",
+    "aso.kumamoto.jp",
+    "yorkshire.museum",
+    "iyo.ehime.jp",
+    "misato.shimane.jp",
+    "kasugai.aichi.jp",
+    "usgarden.museum",
+    "lyngdal.no",
+    "fjell.no",
+    "force.museum",
+    "sanuki.kagawa.jp",
+    "soja.okayama.jp",
+    "kyowa.hokkaido.jp",
+    "midatlantic.museum",
+    "orskog.no",
+    "hitachi.ibaraki.jp",
+    "yamato.fukushima.jp",
+    "humanities.museum",
+    "broker.aero",
+    "dynathome.net",
+    "store.st",
+    "lancashire.museum",
+    "yuu.yamaguchi.jp",
+    "saikai.nagasaki.jp",
+    "fujisawa.kanagawa.jp",
+    "higashiura.aichi.jp",
+    "kikuchi.kumamoto.jp",
+    "sakaki.nagano.jp",
+    "workshop.museum",
+    "rnd.ru",
+    "ukiha.fukuoka.jp",
+    "oregon.museum",
+    "chuvashia.ru",
+    "accident-prevention.aero",
+    "levanger.no",
+    "field.museum",
+    "homeip.net",
+    "hadano.kanagawa.jp",
+    "nsw.edu.au",
+    "rovigo.it",
+    "misato.akita.jp",
+    "iwafune.tochigi.jp",
+    "rotorcraft.aero",
+    "coloradoplateau.museum",
+    "montreal.museum",
+    "lavangen.no",
+    "izumizaki.fukushima.jp",
+    "rochester.museum",
+    "ullensaker.no",
+    "selje.no",
+    "williamsburg.museum",
+    "hirokawa.fukuoka.jp",
+    "kamitsue.oita.jp",
+    "carbonia-iglesias.it",
+    "kawakami.nara.jp",
+    "beppu.oita.jp",
+    "lucania.it",
+    "skole.museum",
+    "aknoluokta.no",
+    "misato.saitama.jp",
+    "forum.hu",
+    "recreation.aero",
+    "aquarium.museum",
+    "sango.nara.jp",
+    "jaworzno.pl",
+    "ogliastra.it",
+    "nnov.ru",
+    "satte.saitama.jp",
+    "yamato.kanagawa.jp",
+    "semine.miyagi.jp",
+    "iwatsuki.saitama.jp",
+    "okagaki.fukuoka.jp",
+    "meguro.tokyo.jp",
+    "kawahara.tottori.jp",
+    "mitou.yamaguchi.jp",
+    "lucerne.museum",
+    "narviika.no",
+    "kaneyama.fukushima.jp",
+    "shell.museum",
+    "dali.museum",
+    "oyamazaki.kyoto.jp",
+    "hanamigawa.chiba.jp",
+    "logistics.aero",
+    "shonai.fukuoka.jp",
+    "newhampshire.museum",
+    "kunstunddesign.museum",
+    "archaeological.museum",
+    "minato.tokyo.jp",
+    "shop.ht",
+    "kunitachi.tokyo.jp",
+    "is-found.org",
+    "dyndns.biz",
+    "rawa-maz.pl",
+    "undersea.museum",
+    "sport.hu",
+    "gouv.ht",
+    "frogn.no",
+    "udm.ru",
+    "urawa.saitama.jp",
+    "muika.niigata.jp",
+    "author.aero",
+    "hokksund.no",
+    "mjondalen.no",
+    "chikushino.fukuoka.jp",
+    "higashitsuno.kochi.jp",
+    "basilicata.it",
+    "sc",
+    "otoineppu.hokkaido.jp",
+    "sca",
+    "scb",
+    "medecin.km",
+    "makinohara.shizuoka.jp",
+    "kasahara.gifu.jp",
+    "omotego.fukushima.jp",
+    "matsusaka.mie.jp",
+    "floro.no",
+    "fedje.no",
+    "kawajima.saitama.jp",
+    "is-very-good.org",
+    "shiraoka.saitama.jp",
+    "kitakata.fukushima.jp",
+    "sande.more-og-romsdal.no",
+    "skien.no",
+    "sabae.fukui.jp",
+    "lombardy.it",
+    "flora.no",
+    "is-a-celticsfan.org",
+    "muenster.museum",
+    "higashinaruse.akita.jp",
+    "mizusawa.iwate.jp",
+    "seika.kyoto.jp",
+    "saiki.oita.jp",
+    "maintenance.aero",
+    "us-east-1.amazonaws.com",
+    "davvenjarga.no",
+    "webhop.biz",
+    "cambridge.museum",
+    "lillehammer.no",
+    "hitachinaka.ibaraki.jp",
+    "higashichichibu.saitama.jp",
+    "axis.museum",
+    "botanicalgarden.museum",
+    "shichikashuku.miyagi.jp",
+    "kasama.ibaraki.jp",
+    "heimatunduhren.museum",
+    "saito.miyazaki.jp",
+    "blogsite.org",
+    "soeda.fukuoka.jp",
+    "fujimi.saitama.jp",
+    "wanouchi.gifu.jp",
+    "scot",
+    "nishiaizu.fukushima.jp",
+    "sveio.no",
+    "kagamiishi.fukushima.jp",
+    "shiga.jp",
+    "echizen.fukui.jp",
+    "massa-carrara.it",
+    "myoko.niigata.jp",
+    "miyako.iwate.jp",
+    "lombardia.it",
+    "yamatsuri.fukushima.jp",
+    "merseine.nu",
+    "is-very-sweet.org",
+    "urayasu.chiba.jp",
+    "leksvik.no",
+    "dyndns.info",
+    "fukui.jp",
+    "mesaverde.museum",
+    "kanuma.tochigi.jp",
+    "hekinan.aichi.jp",
+    "kawanishi.nara.jp",
+    "kazimierz-dolny.pl",
+    "odawara.kanagawa.jp",
+    "egersund.no",
+    "hakodate.hokkaido.jp",
+    "mamurogawa.yamagata.jp",
+    "afjord.no",
+    "is-with-theband.com",
+    "minamiboso.chiba.jp",
+    "vegarshei.no",
+    "kozaki.chiba.jp",
+    "shiiba.miyazaki.jp",
+    "magazine.aero",
+    "net.co",
+    "com.co",
+    "gov.co",
+    "nom.co",
+    "sch.uk",
+    "ltd.gi",
+    "memorial.museum",
+    "lajolla.museum",
+    "hisayama.fukuoka.jp",
+    "slupsk.pl",
+    "edu.co",
+    "jpn.com",
+    "kozagawa.wakayama.jp",
+    "kawanehon.shizuoka.jp",
+    "national-library-scotland.uk",
+    "sch.ae",
+    "management",
+    "leirvik.no",
+    "sch.ir",
+    "shop.hu",
+    "ichikawa.hyogo.jp",
+    "lerdal.no",
+    "shikaoi.hokkaido.jp",
+    "webhop.net",
+    "usantiques.museum",
+    "news.hu",
+    "navigation.aero",
+    "osteroy.no",
+    "org.so",
+    "org.do",
+    "writesthisblog.com",
+    "sch.id",
+    "yahiko.niigata.jp",
+    "lardal.no",
+    "suita.osaka.jp",
+    "lighting",
+    "luxe",
+    "sch.sa",
+    "kagami.kochi.jp",
+    "webhop.info",
+    "org.to",
+    "fukudomi.saga.jp",
+    "sch.lk",
+    "org.ro",
+    "dazaifu.fukuoka.jp",
+    "ube.yamaguchi.jp",
+    "oxford.museum",
+    "artanddesign.museum",
+    "int.co",
+    "moma.museum",
+    "usculture.museum",
+    "vibovalentia.it",
+    "kimino.wakayama.jp",
+    "vlaanderen",
+    "org.jo",
+    "komagane.nagano.jp",
+    "lavagis.no",
+    "wazuka.kyoto.jp",
+    "org.mo",
+    "medical.museum",
+    "swiebodzin.pl",
+    "motoyama.kochi.jp",
+    "manx.museum",
+    "gamvik.no",
+    "bievat.no",
+    "narvik.no",
+    "futsu.nagasaki.jp",
+    "lindas.no",
+    "schule",
+    "utah.museum",
+    "org.bo",
+    "omihachiman.shiga.jp",
+    "chikuzen.fukuoka.jp",
+    "manchester.museum",
+    "sakae.nagano.jp",
+    "nahari.kochi.jp",
+    "ashikaga.tochigi.jp",
+    "vestre-slidre.no",
+    "lunner.no",
+    "mil.ru",
+    "store.nf",
+    "komaki.aichi.jp",
+    "loabat.no",
+    "hitachiomiya.ibaraki.jp",
+    "miura.kanagawa.jp",
+    "olkusz.pl",
+    "yukuhashi.fukuoka.jp",
+    "kamimine.saga.jp",
+    "sagae.yamagata.jp",
+    "lodi.it",
+    "shiraoi.hokkaido.jp",
+    "hidaka.kochi.jp",
+    "sch.qa",
+    "yanagawa.fukuoka.jp",
+    "kibichuo.okayama.jp",
+    "sejny.pl",
+    "fukuroi.shizuoka.jp",
+    "shintoku.hokkaido.jp",
+    "yawatahama.ehime.jp",
+    "skjak.no",
+    "santabarbara.museum",
+    "embroidery.museum",
+    "geisei.kochi.jp",
+    "matsumae.hokkaido.jp",
+    "mill.museum",
+    "beardu.no",
+    "kakamigahara.gifu.jp",
+    "meiwa.gunma.jp",
+    "lodingen.no",
+    "nakagawa.fukuoka.jp",
+    "sakai.osaka.jp",
+    "agents.aero",
+    "ishikawa.fukushima.jp",
+    "microlight.aero",
+    "nakatane.kagoshima.jp",
+    "deatnu.no",
+    "lebork.pl",
+    "koriyama.fukushima.jp",
+    "virginia.museum",
+    "sells-for-less.com",
+    "aizumi.tokushima.jp",
+    "fuchu.toyama.jp",
+    "gjovik.no",
+    "limited",
+    "yasuda.kochi.jp",
+    "lib.sc.us",
+    "lib.dc.us",
+    "lib.ok.us",
+    "lib.or.us",
+    "nakatsugawa.gifu.jp",
+    "lib.pr.us",
+    "luster.no",
+    "univ.sn",
+    "shiki.saitama.jp",
+    "kudamatsu.yamaguchi.jp",
+    "sanda.hyogo.jp",
+    "iizuna.nagano.jp",
+    "ota.tokyo.jp",
+    "vrn.ru",
+    "uvic.museum",
+    "ujiie.tochigi.jp",
+    "medecin.fr",
+    "lib.al.us",
+    "lib.ak.us",
+    "lib.ar.us",
+    "lib.sd.us",
+    "ryukyu",
+    "engine.aero",
+    "lib.as.us",
+    "lib.tn.us",
+    "nakamichi.yamanashi.jp",
+    "online.museum",
+    "sumoto.kumamoto.jp",
+    "lib.ut.us",
+    "ome.tokyo.jp",
+    "lib.de.us",
+    "versailles.museum",
+    "k12.ct.us",
+    "sakai.fukui.jp",
+    "kitagata.gifu.jp",
+    "morioka.iwate.jp",
+    "lib.mt.us",
+    "andebu.no",
+    "michigan.museum",
+    "k12.tx.us",
+    "lib.mn.us",
+    "shintomi.miyazaki.jp",
+    "lib.ms.us",
+    "sch.ng",
+    "lib.il.us",
+    "shari.hokkaido.jp",
+    "miyoshi.aichi.jp",
+    "jewishart.museum",
+    "lib.in.us",
+    "lib.md.us",
+    "iwaizumi.iwate.jp",
+    "sci.eg",
+    "lib.me.us",
+    "lib.id.us",
+    "lib.nc.us",
+    "higashikurume.tokyo.jp",
+    "kawakami.nagano.jp",
+    "fujimi.nagano.jp",
+    "zentsuji.kagawa.jp",
+    "uto.kumamoto.jp",
+    "lib.pa.us",
+    "lib.nd.us",
+    "stuff-4-sale.us",
+    "samnanger.no",
+    "lib.vt.us",
+    "yatomi.aichi.jp",
+    "lib.ne.us",
+    "lib.nj.us",
+    "space-to-rent.com",
+    "ichikawamisato.yamanashi.jp",
+    "aeroport.fr",
+    "military.museum",
+    "oita.oita.jp",
+    "london.museum",
+    "vlaanderen.museum",
+    "k12.ca.us",
+    "sanfrancisco.museum",
+    "msk.ru",
+    "saijo.ehime.jp",
+    "vic.au",
+    "web.co",
+    "lib.ma.us",
+    "lierne.no",
+    "folkebibl.no",
+    "landes.museum",
+    "kokubunji.tokyo.jp",
+    "suzuki",
+    "fuchu.hiroshima.jp",
+    "lib.ia.us",
+    "songdalen.no",
+    "lib.nm.us",
+    "miyako.fukuoka.jp",
+    "rhcloud.com",
+    "scientist.aero",
+    "sandiego.museum",
+    "fudai.iwate.jp",
+    "lib.ks.us",
+    "seihi.nagasaki.jp",
     "from-nc.com",
     "from-sc.com",
-    "suita.osaka.jp",
-    "isumi.chiba.jp",
-    "manno.kagawa.jp",
-    "hirono.fukushima.jp",
-    "daiwa.hiroshima.jp",
-    "satte.saitama.jp",
-    "ogawa.nagano.jp",
-    "sakai.osaka.jp",
-    "yaotsu.gifu.jp",
-    "steinkjer.no",
-    "xn--porsgu-sta26f.no",
-    "swidnica.pl",
-    "sf.no",
-    "from-dc.com",
-    "skoczow.pl",
-    "po.gov.pl",
-    "arezzo.it",
-    "sakae.nagano.jp",
-    "semine.miyagi.jp",
-    "futaba.fukushima.jp",
-    "kyowa.hokkaido.jp",
-    "knowsitall.info",
-    "fukuroi.shizuoka.jp",
-    "minato.osaka.jp",
-    "mizunami.gifu.jp",
-    "sande.more-og-romsdal.no",
-    "mielno.pl",
-    "scrapper-site.net",
-    "shell.museum",
-    "futsu.nagasaki.jp",
-    "pa.gov.pl",
-    "chippubetsu.hokkaido.jp",
-    "shoo.okayama.jp",
-    "fussa.tokyo.jp",
-    "sango.nara.jp",
-    "cc.wa.us",
-    "frosinone.it",
-    "ino.kochi.jp",
-    "inzai.chiba.jp",
-    "minokamo.gifu.jp",
-    "otaki.chiba.jp",
-    "mill.museum",
-    "fujikawaguchiko.yamanashi.jp",
-    "texas.museum",
-    "muika.niigata.jp",
-    "shiiba.miyazaki.jp",
-    "shari.hokkaido.jp",
-    "mitou.yamaguchi.jp",
-    "simple-url.com",
-    "fuchu.toyama.jp",
-    "fuchu.hiroshima.jp",
-    "k12.mo.us",
-    "mjondalen.no",
-    "town.museum",
-    "storfjord.no",
-    "sabae.fukui.jp",
-    "somna.no",
-    "saijo.ehime.jp",
-    "store.ro",
-    "cc.wi.us",
-    "imabari.ehime.jp",
-    "fujimi.saitama.jp",
-    "yamato.kanagawa.jp",
-    "froya.no",
-    "sogne.no",
-    "frana.no",
-    "soeda.fukuoka.jp",
-    "meguro.tokyo.jp",
-    "shimodate.ibaraki.jp",
-    "graz.museum",
-    "ogawa.saitama.jp",
-    "sosnowiec.pl",
-    "seoul.kr",
-    "wallonie.museum",
-    "histoire.museum",
-    "ballooning.aero",
-    "smola.no",
-    "mbone.pl",
-    "minato.tokyo.jp",
-    "juedisches.museum",
-    "shiga.jp",
-    "agents.aero",
-    "westfalen.museum",
-    "union.aero",
-    "schokoladen.museum",
-    "stord.no",
-    "misato.shimane.jp",
-    "yaizu.shizuoka.jp",
-    "linz.museum",
-    "cc.wy.us",
-    "tempio-olbia.it",
-    "kimino.wakayama.jp",
-    "yamato.fukushima.jp",
-    "endofinternet.net",
-    "siena.it",
-    "gotsu.shimane.jp",
-    "stuff-4-sale.org",
-    "ski.museum",
-    "xn--moreke-jua.no",
-    "asahi.chiba.jp",
-    "skjak.no",
-    "izumo.shimane.jp",
-    "swiebodzin.pl",
-    "xn--node",
-    "mamurogawa.yamagata.jp",
-    "minano.saitama.jp",
-    "moriguchi.osaka.jp",
-    "group.aero",
-    "global.ssl.fastly.net",
-    "floro.no",
-    "sarufutsu.hokkaido.jp",
-    "accident-investigation.aero",
-    "tagajo.miyagi.jp",
-    "flanders.museum",
-    "mizuho.tokyo.jp",
-    "principe.st",
-    "misato.akita.jp",
-    "here-for-more.info",
-    "xn--mosjen-eya.no",
-    "flora.no",
-    "misato.saitama.jp",
-    "shiriuchi.hokkaido.jp",
-    "abiko.chiba.jp",
-    "fuchu.tokyo.jp",
-    "egyptian.museum",
-    "xn--fpcrj9c3d",
-    "k12.fl.us",
-    "freiburg.museum",
-    "s3-website-us-west-2.amazonaws.com",
-    "urbinopesaro.it",
-    "sveio.no",
+    "labour.museum",
+    "medio-campidano.it",
+    "langevag.no",
     "fukui.fukui.jp",
-    "sakai.fukui.jp",
-    "cc.wv.us",
-    "motosu.gifu.jp",
-    "torino.museum",
-    "sciences.museum",
-    "ogawa.ibaraki.jp",
-    "railroad.museum",
-    "rovigo.it",
-    "music.museum",
-    "sanda.hyogo.jp",
-    "chirurgiens-dentistes.fr",
-    "friulivegiulia.it",
-    "california.museum",
-    "jfk.museum",
-    "is-a-green.com",
-    "xn--ostery-fya.no",
-    "nagato.yamaguchi.jp",
-    "s3-ap-southeast-1.amazonaws.com",
-    "fudai.iwate.jp",
-    "s3-us-west-2.amazonaws.com",
-    "seihi.nagasaki.jp",
-    "store.st",
-    "shop.ht",
-    "schweiz.museum",
-    "urbino-pesaro.it",
-    "sagae.yamagata.jp",
-    "environment.museum",
-    "wildlife.museum",
-    "shiki.saitama.jp",
-    "ofunato.iwate.jp",
-    "sciencecenter.museum",
-    "lebtimnetz.de",
-    "sciencecenters.museum",
-    "so.gov.pl",
-    "nakatombetsu.hokkaido.jp",
-    "topology.museum",
-    "sakai.ibaraki.jp",
-    "monza.it",
-    "xn--mgbqly7c0a67fbc",
-    "sport.hu",
-    "sr.gov.pl",
-    "countryestate.museum",
-    "rokunohe.aomori.jp",
-    "s3-website-ap-southeast-2.amazonaws.com",
-    "grozny.ru",
-    "tochio.niigata.jp",
-    "yokkaichi.mie.jp",
-    "frogn.no",
-    "k12.co.us",
-    "hamatonbetsu.hokkaido.jp",
-    "heritage.museum",
-    "surrey.museum",
-    "miura.kanagawa.jp",
-    "valer.ostfold.no",
-    "skole.museum",
-    "suifu.ibaraki.jp",
-    "store.bb",
-    "tempioolbia.it",
-    "farm.museum",
-    "sanjo.niigata.jp",
-    "mitake.gifu.jp",
-    "satx.museum",
-    "miyako.iwate.jp",
-    "finnoy.no",
-    "brand.se",
-    "supply",
-    "shikokuchuo.ehime.jp",
-    "slupsk.pl",
-    "unnan.shimane.jp",
-    "yosemite.museum",
-    "shintomi.miyazaki.jp",
-    "tomika.gifu.jp",
-    "cc.pa.us",
-    "valer.hedmark.no",
-    "masaki.ehime.jp",
-    "seiro.niigata.jp",
-    "cc.pr.us",
-    "yahiko.niigata.jp",
-    "research.museum",
-    "plc.co.im",
-    "muroto.kochi.jp",
-    "film.museum",
-    "myoko.niigata.jp",
-    "fujinomiya.shizuoka.jp",
-    "shiso.hyogo.jp",
-    "aizubange.fukushima.jp",
-    "marugame.kagawa.jp",
-    "fujimi.nagano.jp",
-    "saves-the-whales.com",
-    "endoftheinternet.org",
-    "sa.gov.au",
-    "ap-southeast-1.compute.amazonaws.com",
-    "silk.museum",
-    "muenchen.museum",
-    "sasaguri.fukuoka.jp",
-    "akagi.shimane.jp",
-    "furano.hokkaido.jp",
-    "xn--tnsberg-q1a.no",
-    "selfip.info",
-    "design.aero",
-    "delaware.museum",
-    "sejny.pl",
-    "furniture.museum",
-    "selfip.net",
-    "taiwa.miyagi.jp",
-    "xn--stre-toten-zcb.no",
-    "reggiocalabria.it",
-    "shika.ishikawa.jp",
-    "penza.ru",
-    "sicily.it",
-    "shop.hu",
-    "shintoku.hokkaido.jp",
-    "fukushima.fukushima.jp",
-    "taiki.mie.jp",
-    "francaise.museum",
-    "yamanobe.yamagata.jp",
-    "endofinternet.org",
-    "shirakawa.fukushima.jp",
-    "sakado.saitama.jp",
-    "meiwa.gunma.jp",
-    "niihama.ehime.jp",
-    "database.museum",
-    "skiptvet.no",
-    "reggio-emilia.it",
-    "scotland.museum",
-    "takino.hyogo.jp",
-    "store.nf",
-    "shingu.hyogo.jp",
+    "from-dc.com",
+    "hasvik.no",
+    "lib.la.us",
+    "lib.va.us",
+    "sosa.chiba.jp",
+    "maritimo.museum",
+    "leangaviika.no",
+    "settlers.museum",
+    "ks.us",
+    "ne.us",
+    "bd.se",
+    "co.me",
+    "id.us",
+    "nd.us",
+    "co.ls",
+    "co.us",
+    "knowsitall.info",
+    "uchihara.ibaraki.jp",
+    "kawatana.nagasaki.jp",
+    "co.ae",
+    "co.ao",
+    "k12.fl.us",
+    "stathelle.no",
+    "ed.ao",
+    "lyngen.no",
+    "eastcoast.museum",
     "misato.miyagi.jp",
-    "masfjorden.no",
-    "susono.shizuoka.jp",
-    "barrell-of-knowledge.info",
-    "office-on-the.net",
-    "friulive-giulia.it",
-    "friuli-vegiulia.it",
-    "dyndns-remote.com",
-    "xn--indery-fya.no",
-    "shizuoka.jp",
-    "sumoto.kumamoto.jp",
-    "plaza.museum",
-    "museumvereniging.museum",
-    "mansions.museum",
-    "samegawa.fukushima.jp",
-    "ichinohe.iwate.jp",
-    "shonai.yamagata.jp",
-    "misato.wakayama.jp",
-    "family.museum",
-    "uwajima.ehime.jp",
-    "shunan.yamaguchi.jp",
-    "udono.mie.jp",
-    "press.aero",
-    "elasticbeanstalk.com",
-    "fujiyoshida.yamanashi.jp",
-    "tajimi.gifu.jp",
-    "friuli-veneziagiulia.it",
-    "mitoyo.kagawa.jp",
-    "shingu.wakayama.jp",
-    "sukagawa.fukushima.jp",
-    "sydney.museum",
-    "forgot.her.name",
-    "satsumasendai.kagoshima.jp",
+    "schlesisches.museum",
+    "skiptvet.no",
+    "livinghistory.museum",
+    "ca.us",
+    "ks.ua",
+    "ga.us",
+    "ia.us",
+    "co.ma",
+    "co.ua",
+    "ct.us",
+    "co.st",
+    "sakado.saitama.jp",
+    "co.at",
+    "it.ao",
+    "higashine.yamagata.jp",
+    "inawashiro.fukushima.jp",
+    "fussa.tokyo.jp",
     "sumoto.hyogo.jp",
-    "miyako.fukuoka.jp",
-    "friuliveneziagiulia.it",
-    "mallorca.museum",
-    "matsuno.ehime.jp",
-    "shonai.fukuoka.jp",
-    "friuli-venezia-giulia.it",
-    "ap-northeast-1.compute.amazonaws.com",
-    "pilot.aero",
-    "friulivenezia-giulia.it",
-    "salzburg.museum",
-    "xn--frde-gra.no",
+    "co.tt",
+    "ichiba.tokushima.jp",
+    "gu.us",
+    "feedback",
+    "co.mu",
+    "as.us",
+    "zp.ua",
+    "co.uz",
+    "co.sz",
+    "storfjord.no",
+    "id.au",
+    "localhistory.museum",
+    "gs.oslo.no",
+    "obanazawa.yamagata.jp",
+    "sanjo.niigata.jp",
+    "nj.us",
+    "ne.tz",
+    "co.tz",
+    "go.tz",
+    "cr.ua",
+    "kr.ua",
+    "schoenbrunn.museum",
+    "nm.us",
+    "ns.ca",
+    "co.ca",
+    "flatanger.no",
+    "software.aero",
+    "co.tj",
+    "go.tj",
+    "co.om",
+    "settlement.museum",
+    "zt.ua",
+    "co.cr",
+    "go.cr",
+    "co.tm",
+    "frosinone.it",
+    "ed.cr",
+    "nagasu.kumamoto.jp",
+    "nt.au",
+    "ar.us",
+    "ne.kr",
+    "co.kr",
+    "go.kr",
+    "km.ua",
+    "yamagata.gifu.jp",
+    "es.kr",
+    "nt.ca",
+    "az.us",
+    "kawasaki.miyagi.jp",
+    "susono.shizuoka.jp",
+    "de.us",
+    "kuwana.mie.jp",
+    "oshima.tokyo.jp",
+    "minokamo.gifu.jp",
+    "seiro.niigata.jp",
+    "co.no",
+    "rec.co",
+    "nu.ca",
+    "opole.pl",
+    "in.us",
+    "lib.wa.us",
+    "jp.net",
+    "kariya.aichi.jp",
+    "sosnowiec.pl",
+    "co.ci",
+    "go.ci",
+    "onna.okinawa.jp",
+    "fundacio.museum",
+    "otsuki.yamanashi.jp",
+    "ed.ci",
+    "stalbans.museum",
+    "co.na",
+    "dp.ua",
+    "ogawara.miyagi.jp",
+    "nt.no",
+    "cn.ua",
+    "in.ua",
+    "il.us",
+    "miyawaka.fukuoka.jp",
+    "co.com",
+    "no.com",
+    "za.net",
+    "omachi.nagano.jp",
+    "nv.us",
+    "bu.no",
+    "id.lv",
+    "gs.cn",
+    "fuettertdasnetz.de",
+    "gd.cn",
+    "ca.na",
+    "global.ssl.fastly.net",
+    "gv.ao",
+    "co.ba",
+    "nb.ca",
+    "furano.hokkaido.jp",
+    "lib.ri.us",
+    "js.cn",
+    "marylhurst.museum",
+    "mutsuzawa.chiba.jp",
+    "numazu.shizuoka.jp",
+    "barrel-of-knowledge.info",
+    "mitoyo.kagawa.jp",
+    "cv.ua",
+    "kv.ua",
+    "shinjo.nara.jp",
+    "br.com",
+    "kr.com",
+    "gr.com",
+    "iizuka.fukuoka.jp",
+    "aa.no",
+    "ruovat.no",
+    "shiso.hyogo.jp",
+    "co.cl",
+    "computer.museum",
+    "gv.at",
+    "lib.mi.us",
+    "za.com",
+    "lib.az.us",
+    "al.us",
+    "eu.com",
+    "gb.net",
+    "minamiechizen.fukui.jp",
+    "gz.cn",
+    "xn--p1ai",
+    "ab.ca",
+    "nl.ca",
+    "bj.cn",
+    "osaka.jp",
+    "co.rs",
+    "uki.kumamoto.jp",
+    "nm.cn",
+    "co.bi",
+    "xz.cn",
+    "in.net",
+    "munakata.fukuoka.jp",
+    "za.bz",
+    "omachi.saga.jp",
+    "mashiko.tochigi.jp",
+    "kamakura.kanagawa.jp",
+    "honefoss.no",
+    "xj.cn",
+    "zj.cn",
+    "ar.com",
+    "fujinomiya.shizuoka.jp",
+    "misato.wakayama.jp",
+    "university",
+    "ookuwa.nagano.jp",
+    "nh.us",
+    "gb.com",
+    "higashishirakawa.gifu.jp",
+    "dn.ua",
+    "in.na",
+    "de.com",
+    "nt.ro",
+    "co.th",
+    "go.th",
+    "co.nl",
+    "nl.no",
+    "ck.ua",
+    "yuzawa.niigata.jp",
+    "cn.com",
+    "kh.ua",
+    "kawaminami.miyazaki.jp",
+    "ebetsu.hokkaido.jp",
+    "dr.na",
+    "yonaguni.okinawa.jp",
+    "fuchu.tokyo.jp",
+    "science.museum",
+    "lib.vi.us",
+    "ak.us",
+    "am.br",
+    "flanders.museum",
+    "cq.cn",
+    "bozen.it",
+    "forlicesena.it",
+    "kazan.ru",
+    "fylkesbibl.no",
+    "xn--l1acc",
+    "xn--nnx388a",
+    "co.mw",
+    "hi.us",
+    "hs.kr",
+    "figueres.museum",
+    "spb.ru",
+    "al.no",
+    "vanylven.no",
     "sugito.saitama.jp",
-    "friuli-ve-giulia.it",
-    "shingu.fukuoka.jp",
-    "sukumo.kochi.jp",
-    "shimonoseki.yamaguchi.jp",
-    "shizuoka.shizuoka.jp",
-    "pippu.hokkaido.jp",
-    "flight.aero",
-    "minamiise.mie.jp",
-    "press.se",
-    "traeumtgerade.de",
+    "lib.oh.us",
+    "jl.cn",
+    "stv.ru",
+    "yawata.kyoto.jp",
+    "oryol.ru",
+    "in.rs",
+    "co.hu",
+    "kawaba.gunma.jp",
+    "shitara.aichi.jp",
+    "ha.no",
+    "ino.kochi.jp",
+    "morimachi.shizuoka.jp",
+    "ohkura.yamagata.jp",
+    "lib.hi.us",
+    "hu.net",
+    "orsta.no",
+    "in.th",
+    "shika.ishikawa.jp",
+    "kawakita.ishikawa.jp",
+    "he.cn",
+    "finearts.museum",
+    "td",
+    "to",
+    "group.aero",
+    "tp",
+    "bl.uk",
+    "toys",
+    "sexy",
+    "iz.hr",
+    "horology.museum",
+    "satx.museum",
+    "hm.no",
+    "za.org",
+    "medizinhistorisches.museum",
+    "ae.org",
+    "ah.no",
+    "ha.cn",
+    "design.aero",
+    "shinto.gunma.jp",
+    "bv.nl",
+    "tt",
+    "xn--j1amh",
+    "hu.com",
+    "tr",
+    "koryo.nara.jp",
+    "cargo.aero",
+    "latina.it",
+    "graphics",
+    "trade",
+    "lib.wi.us",
+    "tz",
+    "tel",
+    "lib.nh.us",
+    "co.bw",
+    "tj",
+    "stavern.no",
+    "ky.us",
+    "ny.us",
+    "id.ly",
+    "otago.museum",
+    "co.je",
+    "tm",
+    "stpetersburg.museum",
+    "ne.jp",
+    "ah.cn",
+    "co.jp",
+    "go.jp",
+    "steinkjer.no",
+    "ed.jp",
+    "tur.ar",
+    "hi.cn",
+    "xn--rdal-poa.no",
+    "hb.cn",
+    "slattum.no",
+    "joetsu.niigata.jp",
+    "compute.amazonaws.com",
+    "tips",
+    "hl.no",
+    "tana.no",
+    "xn--kpry57d",
+    "gr.jp",
+    "federation.aero",
+    "xn--slat-5na.no",
+    "xn--d1acj3b",
+    "servebbs.net",
+    "odate.akita.jp",
+    "tools",
+    "kumakogen.ehime.jp",
+    "hn.cn",
+    "tn",
+    "xn--zfr164b",
+    "ad.jp",
+    "taa.it",
+    "shikatsu.aichi.jp",
+    "compute-1.amazonaws.com",
+    "funabashi.chiba.jp",
+    "lib.ga.us",
+    "xn--mgb2ddes",
+    "wa.us",
+    "co.rw",
+    "hl.cn",
+    "mihara.kochi.jp",
+    "tl",
+    "tur.br",
+    "assabu.hokkaido.jp",
+    "stuff-4-sale.org",
+    "brand.se",
+    "tv",
+    "xn--skjk-soa.no",
+    "silk.museum",
+    "showa.gunma.jp",
+    "tmp.br",
+    "mihama.aichi.jp",
+    "trd.br",
+    "t.bg",
+    "venice.it",
+    "time.no",
+    "wa.au",
+    "xn--4gbrim",
+    "xn--rland-uua.no",
+    "wi.us",
+    "lom.no",
+    "kawanishi.hyogo.jp",
+    "teo.br",
+    "farm.museum",
+    "starachowice.pl",
+    "sciencesnaturelles.museum",
+    "kawanishi.yamagata.jp",
+    "university.museum",
+    "co.gy",
+    "gamagori.aichi.jp",
+    "kamisunagawa.hokkaido.jp",
+    "xn--mely-ira.no",
+    "xn--snes-poa.no",
+    "hk.cn",
+    "tk",
+    "xn--55qx5d",
+    "th",
+    "xn--snsa-roa.no",
+    "services",
+    "ws.na",
+    "xn--mli-tla.no",
+    "co.id",
+    "go.id",
+    "hawaii.museum",
+    "tenkawa.nara.jp",
+    "inabe.mie.jp",
+    "tinn.no",
+    "shinjo.okayama.jp",
+    "omaha.museum",
+    "t.se",
+    "wv.us",
+    "kiryu.gunma.jp",
+    "xn--ngbc5azd",
+    "xn--asky-ira.no",
+    "ce.it",
+    "ge.it",
+    "cs.it",
+    "bs.it",
+    "is.it",
+    "tra.kp",
+    "co.it",
+    "bo.it",
+    "go.it",
+    "no.it",
+    "id.ir",
+    "co.ir",
+    "taranto.it",
+    "laquila.it",
+    "xn--srfold-bya.no",
+    "ri.us",
+    "re.kr",
+    "tw",
+    "school.na",
+    "bando.ibaraki.jp",
+    "ca.it",
+    "ba.it",
+    "na.it",
+    "yn.cn",
+    "ct.it",
+    "bt.it",
+    "tos.it",
+    "odesa.ua",
+    "co.im",
+    "test.tj",
+    "cr.it",
+    "br.it",
+    "kr.it",
+    "gr.it",
+    "nakagusuku.okinawa.jp",
+    "ne.ug",
+    "film.museum",
+    "co.ug",
+    "go.ug",
+    "services.aero",
+    "co.ag",
+    "nu.it",
+    "cz.it",
+    "bz.it",
+    "selfip.biz",
+    "ao.it",
+    "tienda",
+    "ap.it",
+    "yk.ca",
+    "xn--uc0ay4a.hk",
+    "aki.kochi.jp",
+    "im.it",
+    "act.gov.au",
+    "s3-ap-southeast-2.amazonaws.com",
+    "trading.aero",
+    "ballooning.aero",
+    "mil.co",
+    "suzu.ishikawa.jp",
+    "at.it",
+    "otaki.saitama.jp",
+    "oskol.ru",
+    "gov.cx",
+    "itako.ibaraki.jp",
+    "ro.com",
+    "ci.it",
+    "bi.it",
+    "ar.it",
+    "obuse.nagano.jp",
+    "co.in",
+    "shingo.aomori.jp",
+    "vibo-valentia.it",
+    "xn--vard-jra.no",
+    "rs.ba",
+    "cb.it",
+    "xn--troms-zua.no",
+    "xn--od0aq3b.hk",
+    "sasebo.nagasaki.jp",
+    "owani.aomori.jp",
+    "toda.saitama.jp",
+    "sciencehistory.museum",
+    "rv.ua",
+    "cn.it",
+    "bn.it",
+    "toscana.it",
+    "bo.telemark.no",
+    "works.aero",
+    "gx.cn",
+    "nx.cn",
+    "kg.kr",
+    "en.it",
+    "ru.com",
+    "ternopil.ua",
+    "malvik.no",
+    "jx.cn",
+    "sakuho.nagano.jp",
+    "tottori.jp",
+    "eu.int",
+    "xn--smla-hra.no",
+    "cl.it",
+    "bl.it",
+    "xn--osyro-wua.no",
+    "otaki.nagano.jp",
+    "shimotsuma.ibaraki.jp",
+    "trogstad.no",
+    "oseto.nagasaki.jp",
+    "furniture.museum",
+    "otake.hiroshima.jp",
+    "mitake.gifu.jp",
+    "torsken.no",
+    "tuscany.it",
+    "asahi.mie.jp",
+    "xn--zf0ao64a.tw",
+    "showa.yamanashi.jp",
+    "org.cw",
+    "an.it",
+    "luxembourg.museum",
+    "org.cn",
+    "xn--rde-ula.no",
+    "xn--msy-ula0h.no",
+    "xn--wgbl6a",
+    "aq.it",
+    "toyo.kochi.jp",
+    "xn--lgrd-poac.no",
+    "xn--unjrga-rta.no",
+    "xn--p1acf",
+    "rl.no",
+    "co.gg",
+    "al.it",
+    "railroad.museum",
+    "obama.fukui.jp",
+    "fujiyoshida.yamanashi.jp",
     "frog.museum",
+    "hanyu.saitama.jp",
+    "horonobe.hokkaido.jp",
+    "av.it",
+    "isumi.chiba.jp",
+    "california.museum",
+    "today",
+    "xn--yer-zna.no",
+    "tara.saga.jp",
+    "org.mx",
+    "shimodate.ibaraki.jp",
+    "qh.cn",
+    "gotsu.shimane.jp",
+    "shimoichi.nara.jp",
+    "xn--seral-lra.no",
+    "swidnica.pl",
+    "xn--trna-woa.no",
+    "tama.tokyo.jp",
+    "tourism.tn",
+    "xn--yfro4i67o",
+    "tottori.tottori.jp",
+    "xn--nry-yla5g.no",
+    "izumo.shimane.jp",
+    "ch.it",
+    "yokosuka.kanagawa.jp",
+    "suwalki.pl",
+    "transport.museum",
+    "xn--vg-yiab.no",
+    "showa.fukushima.jp",
+    "xn--uc0atv.hk",
+    "selfip.net",
+    "xn--vgan-qoa.no",
+    "tadaoka.osaka.jp",
+    "omuta.fukuoka.jp",
+    "choyo.kumamoto.jp",
+    "obama.nagasaki.jp",
+    "otama.fukushima.jp",
+    "xn--vry-yla5g.no",
+    "wy.us",
+    "mosvik.no",
+    "selfip.info",
+    "salvadordali.museum",
+    "shinjo.yamagata.jp",
+    "xn--sr-aurdal-l8a.no",
+    "marugame.kagawa.jp",
+    "uchinada.ishikawa.jp",
+    "xn--rskog-uua.no",
+    "tonsberg.no",
+    "xn--j6w193g",
+    "xn--mjndalen-64a.no",
+    "ut.us",
+    "troandin.no",
+    "oyodo.nara.jp",
+    "tatarstan.ru",
+    "tsukumi.oita.jp",
+    "ath.cx",
+    "otari.nagano.jp",
+    "limanowa.pl",
+    "niyodogawa.kochi.jp",
+    "living.museum",
+    "iwama.ibaraki.jp",
+    "xn--lns-qla.museum",
+    "toga.toyama.jp",
+    "uz.ua",
+    "buzen.fukuoka.jp",
+    "serveftp.net",
+    "tourism.pl",
+    "tsaritsyn.ru",
+    "matsuura.nagasaki.jp",
+    "kahoku.ishikawa.jp",
+    "xn--klbu-woa.no",
+    "tsuruta.aomori.jp",
+    "xn--trany-yua.no",
+    "larsson.museum",
+    "scienceandindustry.museum",
+    "kawara.fukuoka.jp",
+    "lib.nv.us",
+    "kahoku.yamagata.jp",
+    "xn--tn0ag.hk",
+    "school.museum",
+    "from-ut.com",
+    "other.nf",
+    "oketo.hokkaido.jp",
+    "xn--3ds443g",
+    "xn--55qx5d.hk",
+    "xn--drbak-wua.no",
+    "xn--6frz82g",
+    "xn--ses554g",
+    "otobe.hokkaido.jp",
+    "xn--mgbaam7a8h",
+    "xn--mlatvuopmi-s4a.no",
+    "tosa.kochi.jp",
+    "xn--kprw13d",
+    "us.na",
+    "tosu.saga.jp",
+    "masaki.ehime.jp",
+    "oyabe.toyama.jp",
+    "suwa.nagano.jp",
+    "xn--80adxhks",
+    "servebbs.org",
+    "miyazu.kyoto.jp",
+    "tg",
+    "us.com",
+    "xn--kfjord-iua.no",
+    "otaru.hokkaido.jp",
+    "xn--risr-ira.no",
+    "tuva.ru",
+    "osaki.miyagi.jp",
+    "xn--s-1fa.no",
+    "hikari.yamaguchi.jp",
+    "egyptian.museum",
+    "xn--lcvr32d.hk",
+    "xn--6qq986b3xl",
+    "trieste.it",
+    "iheya.okinawa.jp",
+    "asahi.ibaraki.jp",
+    "tvedestrand.no",
+    "nanyo.yamagata.jp",
+    "oharu.aichi.jp",
+    "reggiocalabria.it",
+    "museumvereniging.museum",
+    "jewish.museum",
+    "is-a-landscaper.com",
+    "trolley.museum",
+    "teledata.mz",
+    "omura.nagasaki.jp",
+    "tobe.ehime.jp",
+    "urausu.hokkaido.jp",
+    "bo.nordland.no",
+    "scienceandhistory.museum",
+    "tula.ru",
+    "hizen.saga.jp",
+    "togo.aichi.jp",
+    "okuma.fukushima.jp",
+    "xn--kput3i",
+    "trustee.museum",
+    "theater.museum",
+    "newport.museum",
+    "xn--rros-gra.no",
+    "environment.museum",
+    "xn--risa-5na.no",
+    "toyonaka.osaka.jp",
+    "xn--uc0atv.tw",
+    "xn--b-5ga.nordland.no",
+    "ozora.hokkaido.jp",
+    "pe",
+    "ps",
+    "net.sy",
+    "bizen.okayama.jp",
+    "com.sy",
+    "shimofusa.chiba.jp",
+    "gov.sy",
+    "net.py",
+    "niepce.museum",
+    "com.py",
+    "gov.py",
+    "edu.sy",
+    "asahi.chiba.jp",
+    "tananger.no",
+    "pa",
+    "suzuka.mie.jp",
+    "kazuno.akita.jp",
+    "edu.py",
+    "xn--stjrdalshalsen-sqb.no",
+    "pt",
+    "me.us",
+    "ogata.akita.jp",
+    "ms.us",
+    "md.us",
+    "xn--b-5ga.telemark.no",
+    "mo.us",
+    "pr",
+    "olecko.pl",
+    "parts",
+    "xn--andy-ira.no",
+    "jetzt",
+    "tjeldsund.no",
+    "xn--l-1fa.no",
+    "net.uy",
+    "com.uy",
+    "pub",
+    "moriya.ibaraki.jp",
+    "dontexist.com",
+    "xn--linds-pra.no",
+    "ma.us",
+    "pm",
+    "mt.us",
+    "xn--sandy-yua.no",
+    "ouchi.saga.jp",
+    "daigo.ibaraki.jp",
+    "re.it",
+    "xn--mk0axi.hk",
+    "syzran.ru",
+    "net.my",
+    "usdecorativearts.museum",
+    "com.my",
+    "sowa.ibaraki.jp",
+    "gov.my",
+    "ro.it",
+    "edu.uy",
+    "test.ru",
+    "xn--sknit-yqa.no",
+    "sakuragawa.ibaraki.jp",
+    "tono.iwate.jp",
+    "xn--bmlo-gra.no",
+    "trentino.it",
+    "xn--wcvs22d.hk",
+    "org.ci",
+    "abiko.chiba.jp",
+    "uk.net",
+    "reggio-emilia.it",
+    "edu.my",
+    "tsukuba.ibaraki.jp",
+    "me.tz",
+    "us.org",
+    "ra.it",
+    "xn--lesund-hua.no",
+    "gub.uy",
+    "com.by",
+    "gov.by",
+    "www.ro",
+    "is-a-caterer.com",
+    "xn--dnna-gra.no",
+    "toyoura.hokkaido.jp",
+    "toon.ehime.jp",
+    "isa-geek.net",
+    "pn",
+    "mi.us",
+    "ms.kr",
+    "taku.saga.jp",
+    "uk.com",
+    "praxi",
+    "rm.it",
+    "xn--hery-ira.nordland.no",
+    "loten.no",
+    "pink",
+    "xn--brum-voa.no",
+    "xn--h-2fa.no",
+    "pro",
+    "tondabayashi.osaka.jp",
+    "prod",
+    "pro.ec",
+    "cci.fr",
+    "pl",
+    "mn.us",
+    "shikokuchuo.ehime.jp",
+    "pro.pr",
+    "net.ly",
+    "pmn.it",
+    "ppg.br",
+    "com.ly",
+    "ri.it",
+    "gov.ly",
+    "md.ci",
+    "tranibarlettaandria.it",
+    "shiwa.iwate.jp",
+    "pila.pl",
+    "okayama.jp",
+    "trani-andria-barletta.it",
+    "bg.it",
+    "edu.ly",
+    "xn--rholt-mra.no",
+    "sodegaura.chiba.jp",
+    "p.bg",
+    "pro.tt",
+    "mr.no",
+    "xn--rady-ira.no",
+    "tatsuno.nagano.jp",
+    "akagi.shimane.jp",
+    "pug.it",
+    "rn.it",
+    "ogose.saitama.jp",
+    "pub.sa",
+    "mo.cn",
+    "ogano.saitama.jp",
+    "rokunohe.aomori.jp",
+    "mb.ca",
+    "gaivuotna.no",
+    "tsu.mie.jp",
+    "mp.br",
+    "xn--smna-gra.no",
+    "lecce.it",
+    "mansions.museum",
+    "lecco.it",
+    "satsumasendai.kagoshima.jp",
+    "olawa.pl",
+    "tver.ru",
+    "xn--80ao21a",
+    "ham-radio-op.net",
+    "tone.ibaraki.jp",
+    "xn--bjddar-pta.no",
+    "xn--unup4y",
+    "pics",
+    "ag.it",
+    "withgoogle.com",
+    "bolzano.it",
+    "trainer.aero",
+    "labor.museum",
+    "xn--vhquv",
+    "post",
+    "pk",
+    "psc.br",
+    "port.fr",
+    "net.ky",
+    "obira.hokkaido.jp",
+    "ph",
+    "com.ky",
+    "gov.ky",
+    "is-a-democrat.com",
+    "pro.br",
+    "gs.jan-mayen.no",
+    "sykkylven.no",
+    "xn--vads-jra.no",
+    "xn--kranghke-b0a.no",
+    "tas.edu.au",
+    "pro.om",
+    "prof.pr",
+    "edu.ky",
+    "adygeya.ru",
+    "xn--lten-gra.no",
+    "p.se",
+    "xn--od0alg.hk",
+    "plo.ps",
+    "per.nf",
+    "shimotsuke.tochigi.jp",
+    "is-an-anarchist.com",
+    "samegawa.fukushima.jp",
+    "swinoujscie.pl",
+    "lucca.it",
+    "per.la",
+    "oguni.kumamoto.jp",
+    "partners",
+    "forgot.her.name",
+    "va.us",
+    "mk.ua",
+    "onojo.fukuoka.jp",
+    "pol.ht",
+    "trani-barletta-andria.it",
+    "pw",
+    "vt.us",
+    "per.sg",
+    "xn--lrdal-sra.no",
+    "xn--vler-qoa.hedmark.no",
+    "xn--leagaviika-52b.no",
+    "pro.vn",
+    "go.dyndns.org",
+    "airforce",
+    "xn--55qw42g",
+    "xn--80aswg",
+    "schweiz.museum",
+    "xn--hpmir-xqa.no",
+    "k12.gu.us",
+    "xn--karmy-yua.no",
+    "is-a-nascarfan.com",
+    "aeroclub.aero",
+    "uy.com",
+    "off.ai",
+    "government.aero",
+    "udono.mie.jp",
+    "motegi.tochigi.jp",
+    "toyosato.shiga.jp",
+    "blogspot.cf",
+    "vi.us",
+    "masfjorden.no",
+    "photo",
+    "tsubata.ishikawa.jp",
+    "xn--ygbi2ammx",
+    "yuzhno-sakhalinsk.ru",
+    "shinanomachi.nagano.jp",
+    "mi.th",
+    "publ.pt",
+    "xn--krdsherad-m8a.no",
+    "tsugaru.aomori.jp",
+    "takaishi.osaka.jp",
+    "photos",
+    "laspezia.it",
+    "pescara.it",
+    "ostrowiec.pl",
+    "porsangu.no",
+    "pro.ht",
+    "pri.ee",
+    "palermo.it",
+    "trentino-stirol.it",
+    "xn--krjohka-hwab49j.no",
+    "pro.na",
+    "betainabox.com",
+    "psi.br",
+    "va.no",
+    "ud.it",
+    "toya.hokkaido.jp",
+    "inuyama.aichi.jp",
+    "googlecode.com",
+    "serveftp.org",
+    "vn.ua",
+    "prd.km",
+    "ide.kyoto.jp",
+    "tochigi.jp",
+    "urbinopesaro.it",
+    "is-a-therapist.com",
+    "xn--btsfjord-9za.no",
+    "kawai.nara.jp",
+    "xn--nqv7f",
+    "py",
+    "s3-sa-east-1.amazonaws.com",
+    "takaoka.toyama.jp",
+    "prd.mg",
+    "traniandriabarletta.it",
+    "toyohashi.aichi.jp",
+    "tsurugashima.saitama.jp",
+    "trentinostirol.it",
+    "fukuchiyama.kyoto.jp",
+    "trentino-s-tirol.it",
+    "trentinos-tirol.it",
+    "piacenza.it",
+    "trentinosudtirol.it",
+    "ebiz.tw",
+    "luroy.no",
+    "shinjuku.tokyo.jp",
+    "trentino-suedtirol.it",
+    "xn--rlingen-mxa.no",
+    "xn--rmskog-bya.no",
+    "is-a-anarchist.com",
+    "sch.jo",
+    "tomioka.gunma.jp",
+    "trentino-sudtirol.it",
+    "trentino-sud-tirol.it",
+    "paderborn.museum",
+    "tsubetsu.hokkaido.jp",
+    "xn--bidr-5nac.no",
+    "minobu.yamanashi.jp",
+    "trentinosuedtirol.it",
+    "trentinosued-tirol.it",
+    "xn--lrenskog-54a.no",
+    "toei.aichi.jp",
+    "xn--vrggt-xqad.no",
+    "xn--bdddj-mrabd.no",
+    "xn--3bst00m",
+    "union.aero",
+    "xn--hcesuolo-7ya35b.no",
+    "sex.hu",
+    "trentino-sued-tirol.it",
+    "ine.kyoto.jp",
+    "pol.dz",
+    "toyooka.hyogo.jp",
+    "ohira.miyagi.jp",
+    "trysil.no",
+    "xn--bievt-0qa.no",
+    "okoppe.hokkaido.jp",
+    "pictures",
+    "yamanobe.yamagata.jp",
+    "cieszyn.pl",
+    "trentinoaadige.it",
+    "val-d-aosta.it",
+    "trentinosud-tirol.it",
+    "tanohata.iwate.jp",
+    "tatebayashi.gunma.jp",
+    "shirakawa.fukushima.jp",
+    "television.museum",
+    "xn--mgbayh7gpa",
+    "urbino-pesaro.it",
+    "tomi.nagano.jp",
+    "s3-ap-northeast-1.amazonaws.com",
+    "xn--sandnessjen-ogb.no",
+    "shinonsen.hyogo.jp",
+    "ovre-eiker.no",
+    "xn--zf0avx.hk",
+    "xn--trgstad-r1a.no",
+    "friulivegiulia.it",
+    "xn--srum-gra.no",
+    "associates",
+    "kaszuby.pl",
+    "lc",
+    "mex.com",
+    "xn--rdy-0nab.no",
+    "net.cu",
+    "pvt.k12.ma.us",
+    "perm.ru",
+    "com.cu",
+    "gov.cu",
+    "trondheim.no",
+    "obu.aichi.jp",
+    "tatsuno.hyogo.jp",
+    "paris",
+    "pro.az",
+    "xn--rhqv96g",
+    "countryestate.museum",
+    "xn--krehamn-dxa.no",
+    "edu.cu",
+    "tsukigata.hokkaido.jp",
+    "xn--bearalvhki-y4a.no",
+    "xn--sr-odal-q1a.no",
+    "lesja.no",
+    "is-slick.com",
+    "is-a-musician.com",
+    "sakura.tochigi.jp",
+    "ogaki.gifu.jp",
+    "coastaldefence.museum",
+    "suzaka.nagano.jp",
+    "nishio.aichi.jp",
+    "motobu.okinawa.jp",
+    "xn--stjrdal-s1a.no",
+    "lapy.pl",
+    "productions",
+    "kofu.yamanashi.jp",
+    "me.it",
+    "ms.it",
+    "ketrzyn.pl",
+    "flight.aero",
+    "mo.it",
+    "pg",
+    "sakawa.kochi.jp",
+    "net.gy",
+    "com.gy",
+    "isa-geek.org",
+    "lubin.pl",
+    "lukow.pl",
+    "tateyama.toyama.jp",
+    "tome.miyagi.jp",
+    "lakas.hu",
+    "tromsa.no",
+    "oyama.tochigi.jp",
+    "kawagoe.saitama.jp",
+    "settsu.osaka.jp",
+    "sukagawa.fukushima.jp",
+    "kawagoe.mie.jp",
+    "act.au",
+    "mt.it",
+    "xn--rst-0na.no",
+    "ogimi.okinawa.jp",
+    "tokushima.jp",
+    "juedisches.museum",
+    "ogori.fukuoka.jp",
+    "susaki.kochi.jp",
+    "potenza.it",
+    "org.au",
+    "laz.it",
+    "tsumagoi.gunma.jp",
+    "toshima.tokyo.jp",
+    "planetarium.museum",
+    "is-a-geek.com",
+    "fukushima.fukushima.jp",
+    "org.ru",
+    "tobetsu.hokkaido.jp",
+    "s3-ap-southeast-1.amazonaws.com",
+    "rg.it",
+    "xn--pgbs0dh",
+    "kisarazu.chiba.jp",
+    "cody.museum",
+    "mi.it",
+    "org.mu",
+    "val-daosta.it",
+    "ochi.kochi.jp",
+    "taka.hyogo.jp",
+    "mb.it",
+    "mx.na",
+    "tateshina.nagano.jp",
+    "oguni.yamagata.jp",
+    "inf.cu",
+    "is-an-engineer.com",
+    "training",
+    "mn.it",
+    "s3-us-gov-west-1.amazonaws.com",
+    "unzen.nagasaki.jp",
+    "toho.fukuoka.jp",
+    "unnan.shimane.jp",
+    "k12.co.us",
+    "takahagi.ibaraki.jp",
+    "s3-website-us-west-2.amazonaws.com",
+    "kaizuka.osaka.jp",
+    "lib.mo.us",
+    "lutsk.ua",
+    "tsubame.niigata.jp",
+    "fukuchi.fukuoka.jp",
+    "pistoia.it",
+    "xn--gmqw5a.hk",
+    "tynset.no",
+    "ozu.ehime.jp",
+    "dyndns-server.com",
+    "lacaixa",
+    "database.museum",
+    "neat-url.com",
+    "sd.us",
+    "intelligence.museum",
+    "pvt.ge",
+    "podhale.pl",
+    "nkz.ru",
+    "takasago.hyogo.jp",
+    "friuli-vegiulia.it",
+    "utsunomiya.tochigi.jp",
+    "tanabe.kyoto.jp",
+    "is-a-financialadvisor.com",
+    "chuo.yamanashi.jp",
+    "okayama.okayama.jp",
+    "tsurugi.ishikawa.jp",
+    "ve.it",
+    "pruszkow.pl",
+    "vs.it",
+    "xn--sknland-fxa.no",
+    "futtsu.chiba.jp",
+    "trentino-aadige.it",
+    "va.it",
+    "org.hu",
+    "vt.it",
+    "okawa.kochi.jp",
+    "media.aero",
+    "tsuruga.fukui.jp",
+    "vr.it",
+    "sa.au",
+    "here-for-more.info",
+    "s3-website-ap-southeast-2.amazonaws.com",
+    "kamagaya.chiba.jp",
+    "xn--lhppi-xqa.no",
+    "is-a-chef.com",
+    "sm.ua",
+    "imabari.ehime.jp",
+    "sa.cr",
+    "se.net",
+    "oystre-slidre.no",
+    "delaware.museum",
+    "toyama.jp",
+    "xn--gjvik-wua.no",
+    "simple-url.com",
+    "ako.hyogo.jp",
+    "vi.it",
+    "trentino-a-adige.it",
+    "teshikaga.hokkaido.jp",
+    "sb.ua",
+    "togane.chiba.jp",
+    "vb.it",
+    "tamatsukuri.ibaraki.jp",
+    "friulive-giulia.it",
+    "ohira.tochigi.jp",
+    "takatsuki.osaka.jp",
+    "st.no",
+    "kamogawa.chiba.jp",
+    "tyumen.ru",
+    "trentinoa-adige.it",
+    "se.com",
+    "is-not-certified.com",
+    "portlligat.museum",
+    "sd.cn",
+    "nagato.yamaguchi.jp",
+    "valer.ostfold.no",
+    "katowice.pl",
+    "pomorze.pl",
+    "is-a-bulls-fan.com",
+    "kanzaki.saga.jp",
+    "sa.com",
+    "newmexico.museum",
+    "pisa.it",
+    "watch-and-clock.museum",
+    "preservation.museum",
+    "vv.it",
+    "plumbing",
+    "xn--1qqw23a",
+    "wallonie.museum",
+    "takasaki.gunma.jp",
+    "my.id",
+    "volyn.ua",
+    "airtraffic.aero",
+    "okawa.fukuoka.jp",
+    "lezajsk.pl",
+    "kaminokawa.tochigi.jp",
+    "is-into-anime.com",
+    "omasvuotna.no",
+    "takehara.hiroshima.jp",
+    "stryn.no",
+    "tabayama.yamanashi.jp",
+    "sor-odal.no",
+    "kawai.iwate.jp",
+    "lahppi.no",
+    "shunan.yamaguchi.jp",
+    "xn--ldingen-q1a.no",
+    "newyork.museum",
+    "friuli-ve-giulia.it",
+    "textile.museum",
+    "trentino-altoadige.it",
+    "shioya.tochigi.jp",
+    "timekeeping.museum",
+    "sn.cn",
+    "taxi.br",
+    "nyny.museum",
+    "music.museum",
+    "sk.ca",
+    "oshino.yamanashi.jp",
+    "palmsprings.museum",
+    "store.bb",
+    "trentino-alto-adige.it",
+    "tysnes.no",
+    "schokoladen.museum",
+    "co.pn",
+    "philately.museum",
+    "tachikawa.tokyo.jp",
+    "miharu.fukushima.jp",
+    "trentinoalto-adige.it",
+    "happou.akita.jp",
+    "takazaki.miyazaki.jp",
+    "xn--vgsy-qoa0j.no",
+    "perugia.it",
+    "tsuwano.shimane.jp",
+    "fl.us",
+    "co.pl",
+    "orenburg.ru",
+    "fi.cr",
+    "friuli-veneziagiulia.it",
+    "anpachi.gifu.jp",
+    "owariasahi.aichi.jp",
+    "yokaichiba.chiba.jp",
+    "karmoy.no",
+    "ozu.kumamoto.jp",
+    "fm.no",
+    "westfalen.museum",
+    "kyotanabe.kyoto.jp",
+    "toyotsu.fukuoka.jp",
+    "plantation.museum",
+    "trentinoaltoadige.it",
+    "xn--avery-yua.no",
+    "project.museum",
+    "muroto.kochi.jp",
+    "olbia-tempio.it",
+    "sh.cn",
+    "issmarterthanyou.com",
+    "iglesias-carbonia.it",
+    "xn--sr-fron-q1a.no",
+    "endofinternet.net",
+    "friuli-venezia-giulia.it",
+    "valer.hedmark.no",
+    "fj.cn",
+    "research.museum",
+    "ogawa.saitama.jp",
+    "lindesnes.no",
+    "fm.br",
+    "fh.se",
+    "takamatsu.kagawa.jp",
+    "friuliveneziagiulia.it",
+    "phoenix.museum",
+    "froya.no",
+    "kitakyushu.jp",
+    "iide.yamagata.jp",
+    "newspaper.museum",
+    "kouzushima.tokyo.jp",
+    "kiwa.mie.jp",
+    "mil.sy",
+    "mil.py",
+    "hitachiota.ibaraki.jp",
+    "brandywinevalley.museum",
+    "takahashi.okayama.jp",
+    "pyatigorsk.ru",
+    "presse.ci",
+    "on-the-web.tv",
+    "dyndns-web.com",
+    "tobishima.aichi.jp",
+    "histoire.museum",
+    "friulivenezia-giulia.it",
+    "can.museum",
+    "tsushima.nagasaki.jp",
+    "ne.pw",
+    "takarazuka.hyogo.jp",
+    "co.pw",
+    "go.pw",
+    "ogawa.nagano.jp",
+    "mil.uy",
+    "ed.pw",
+    "med.ly",
+    "xn--ygarden-p1a.no",
+    "toyama.toyama.jp",
+    "tokushima.tokushima.jp",
+    "mil.my",
+    "pro.mv",
+    "huissier-justice.fr",
+    "nativeamerican.museum",
+    "heritage.museum",
+    "niihama.ehime.jp",
+    "www.ck",
+    "tsuchiura.ibaraki.jp",
+    "takaharu.miyazaki.jp",
+    "mil.by",
+    "art.museum",
+    "sekigahara.gifu.jp",
+    "is-very-bad.org",
+    "takayama.gunma.jp",
+    "taxi.aero",
+    "ddr.museum",
+    "ohtawara.tochigi.jp",
+    "porsgrunn.no",
+    "taketa.oita.jp",
+    "tarumizu.kagoshima.jp",
+    "xn--gmq050i.hk",
+    "presse.ml",
+    "poltava.ua",
+    "air.museum",
+    "is-very-nice.org",
+    "herokussl.com",
+    "xn--io0a7i",
+    "leikanger.no",
+    "takayama.nagano.jp",
+    "tattoo",
+    "xn--givuotna-8ya.no",
+    "herokuapp.com",
+    "tonosho.kagawa.jp",
+    "tokashiki.okinawa.jp",
+    "tamaki.mie.jp",
+    "wodzislaw.pl",
+    "ss.it",
+    "xn--ggaviika-8ya47h.no",
+    "so.it",
+    "bedzin.pl",
+    "sp.it",
+    "xn--sr-varanger-ggb.no",
+    "stateofdelaware.museum",
+    "xn--xhq521b",
+    "chirurgiens-dentistes.fr",
+    "and.museum",
+    "isahaya.nagasaki.jp",
+    "sa.it",
+    "presse.km",
+    "uchinomi.kagawa.jp",
+    "naumburg.museum",
+    "sr.it",
+    "tadotsu.kagawa.jp",
+    "stavropol.ru",
+    "pittsburgh.museum",
+    "myphotos.cc",
+    "tsunan.niigata.jp",
+    "yachiyo.chiba.jp",
+    "bus.museum",
+    "tokigawa.saitama.jp",
+    "cadaques.museum",
+    "dnepropetrovsk.ua",
+    "photography",
+    "xn--kvfjord-nxa.no",
+    "arteducation.museum",
+    "si.it",
+    "xn--hnefoss-q1a.no",
+    "philadelphia.museum",
+    "puglia.it",
+    "averoy.no",
+    "tomari.hokkaido.jp",
+    "mazowsze.pl",
+    "takikawa.hokkaido.jp",
+    "endoftheinternet.org",
+    "wildlife.museum",
+    "leirfjord.no",
+    "kitashiobara.fukushima.jp",
+    "sx.cn",
+    "toki.gifu.jp",
+    "togura.nagano.jp",
+    "takatsuki.shiga.jp",
+    "padova.it",
+    "uji.kyoto.jp",
+    "sv.it",
+    "portal.museum",
+    "tonami.toyama.jp",
+    "palana.ru",
+    "oamishirasato.chiba.jp",
+    "xn--vestvgy-ixa6o.no",
+    "maryland.museum",
+    "xn--nvuotna-hwa.no",
+    "nsw.au",
+    "yachiyo.ibaraki.jp",
+    "likescandy.com",
+    "monza-brianza.it",
+    "fe.it",
+    "mallorca.museum",
+    "nes.buskerud.no",
+    "aizumisato.fukushima.jp",
+    "mizuho.tokyo.jp",
+    "chihayaakasaka.osaka.jp",
+    "sakyo.kyoto.jp",
+    "togitsu.nagasaki.jp",
+    "s3-fips-us-gov-west-1.amazonaws.com",
+    "law.pro",
+    "s3-website-us-east-1.amazonaws.com",
+    "fr.it",
+    "tarama.okinawa.jp",
+    "monzaebrianza.it",
+    "botany.museum",
+    "trapani.it",
+    "ota.gunma.jp",
+    "s3-website-sa-east-1.amazonaws.com",
+    "ora.gunma.jp",
+    "takashima.shiga.jp",
+    "public.museum",
+    "fm.it",
+    "cmw.ru",
+    "monzabrianza.it",
+    "kiev.ua",
+    "county.museum",
+    "philadelphiaarea.museum",
+    "gs.st.no",
+    "gs.aa.no",
+    "aizuwakamatsu.fukushima.jp",
+    "yosemite.museum",
+    "gs.mr.no",
+    "fi.it",
+    "nakamura.kochi.jp",
+    "taishi.osaka.jp",
+    "xn--hobl-ira.no",
+    "shima.mie.jp",
+    "lans.museum",
+    "gs.tr.no",
+    "newjersey.museum",
+    "seiyo.ehime.jp",
+    "pilots.museum",
+    "seirou.niigata.jp",
+    "xn--mot-tla.no",
+    "gs.tm.no",
+    "guovdageaidnu.no",
+    "war.museum",
+    "endofinternet.org",
+    "laakesvuemie.no",
+    "furudono.fukushima.jp",
+    "panama.museum",
+    "yokkaichi.mie.jp",
+    "gs.fm.no",
+    "org.co",
+    "xn--io0a7i.hk",
+    "paragliding.aero",
+    "taishin.fukushima.jp",
+    "xn--kvnangen-k0a.no",
+    "dnipropetrovsk.ua",
+    "gs.nt.no",
+    "nakagyo.kyoto.jp",
+    "photography.museum",
+    "nyc.museum",
+    "nasushiobara.tochigi.jp",
+    "matsuno.ehime.jp",
+    "africa.com",
+    "meiwa.mie.jp",
+    "gs.ol.no",
+    "tambov.ru",
+    "loyalist.museum",
+    "takahata.yamagata.jp",
+    "plants.museum",
+    "gs.bu.no",
+    "matsuyama.ehime.jp",
+    "suifu.ibaraki.jp",
+    "presse.fr",
+    "unazuki.toyama.jp",
+    "fujikawaguchiko.yamanashi.jp",
+    "inatsuki.fukuoka.jp",
+    "oizumi.gunma.jp",
+    "gs.ah.no",
+    "gs.nl.no",
+    "tagami.niigata.jp",
+    "s3-website-us-west-1.amazonaws.com",
+    "tingvoll.no",
+    "barrell-of-knowledge.info",
+    "is-very-evil.org",
+    "museumcenter.museum",
+    "ichikai.tochigi.jp",
+    "sakai.ibaraki.jp",
+    "xn--hery-ira.xn--mre-og-romsdal-qqb.no",
+    "sakae.chiba.jp",
+    "s3-website-eu-west-1.amazonaws.com",
+    "lib.ct.us",
+    "eu-west-1.compute.amazonaws.com",
+    "readmyblog.org",
+    "gs.hm.no",
+    "lib.tx.us",
+    "gs.rl.no",
+    "hokuryu.hokkaido.jp",
+    "karasuyama.tochigi.jp",
+    "wa.gov.au",
+    "s3-website-ap-southeast-1.amazonaws.com",
+    "sor-varanger.no",
+    "sanagochi.tokushima.jp",
+    "xn--bod-2na.no",
+    "losangeles.museum",
+    "bushey.museum",
+    "tonaki.okinawa.jp",
+    "bellevue.museum",
+    "gs.hl.no",
+    "okuizumo.shimane.jp",
+    "harvestcelebration.museum",
+    "otsuki.kochi.jp",
+    "lib.ca.us",
+    "loppa.no",
+    "usa.museum",
+    "yamaguchi.jp",
+    "s3-website-ap-northeast-1.amazonaws.com",
+    "tanabe.wakayama.jp",
+    "mizumaki.fukuoka.jp",
+    "muenchen.museum",
+    "tjome.no",
+    "tagawa.fukuoka.jp",
+    "taishi.hyogo.jp",
+    "trana.no",
+    "antiques.museum",
+    "tainai.niigata.jp",
+    "targi.pl",
+    "minamiise.mie.jp",
+    "ranzan.saitama.jp",
+    "tolga.no",
+    "tysfjord.no",
+    "lib.fl.us",
+    "turek.pl",
+    "luzern.museum",
+    "sakahogi.gifu.jp",
+    "terni.it",
+    "trust.museum",
+    "toyotomi.hokkaido.jp",
+    "ulm.museum",
+    "fg.it",
+    "ryazan.ru",
+    "lanbib.se",
+    "nc.us",
+    "accident-investigation.aero",
+    "co.lc",
+    "nyuzen.toyama.jp",
+    "takatori.nara.jp",
+    "utazas.hu",
+    "takata.fukuoka.jp",
+    "kyiv.ua",
+    "od.ua",
+    "uwajima.ehime.jp",
+    "tomsk.ru",
+    "or.us",
+    "mizunami.gifu.jp",
+    "scrapper-site.net",
+    "ac.me",
+    "ac.se",
+    "kawamata.fukushima.jp",
+    "ac.ae",
+    "or.at",
+    "kiyosu.aichi.jp",
+    "bc.ca",
+    "gc.ca",
+    "or.mu",
+    "ac.ma",
+    "turen.tn",
+    "or.tz",
+    "ac.at",
+    "oz.au",
+    "monza-e-della-brianza.it",
+    "ac.mu",
+    "shingu.hyogo.jp",
+    "or.cr",
+    "ac.sz",
+    "dc.us",
+    "agriculture.museum",
+    "ac.tz",
+    "or.kr",
+    "szczecin.pl",
+    "ac.tj",
+    "ac.cr",
+    "tajiri.osaka.jp",
+    "tsukui.kanagawa.jp",
+    "cc.na",
+    "ac.kr",
+    "um.gov.pl",
+    "or.ci",
+    "sukumo.kochi.jp",
+    "or.na",
+    "boldlygoingnowhere.org",
+    "on.ca",
+    "ac.ci",
+    "xn--45q11c",
+    "ac.be",
+    "mad.museum",
+    "touch.museum",
+    "xn--holtlen-hxa.no",
+    "ac.cn",
+    "tokke.no",
+    "yokoshibahikari.chiba.jp",
+    "kamifurano.hokkaido.jp",
+    "ok.us",
+    "oh.us",
+    "xn--3e0b707e",
+    "kawanabe.kagoshima.jp",
+    "scotland.museum",
+    "or.bi",
+    "ol.no",
+    "xn--90a3ac",
+    "maritime.museum",
+    "oceanographic.museum",
+    "tsuno.miyazaki.jp",
+    "nowaruda.pl",
+    "technology",
+    "ac.rs",
+    "or.th",
+    "piedmont.it",
+    "k12.ny.us",
+    "tomakomai.hokkaido.jp",
+    "monmouth.museum",
+    "if.ua",
+    "ac.th",
+    "vagsoy.no",
+    "oguchi.aichi.jp",
+    "sumy.ua",
+    "takamori.kumamoto.jp",
+    "ac.ru",
+    "missoula.museum",
+    "ac.gn",
+    "forli-cesena.it",
+    "oceanographique.museum",
+    "nf.ca",
+    "ac.mw",
+    "kawachinagano.osaka.jp",
+    "tydal.no",
+    "xn--koluokta-7ya57h.no",
+    "s3-us-west-2.amazonaws.com",
+    "tenri.nara.jp",
+    "shinyoshitomi.fukuoka.jp",
+    "tc",
+    "uw.gov.pl",
+    "xn--45brj9c",
+    "xn--s9brj9c",
+    "tromso.no",
+    "taketomi.okinawa.jp",
+    "snz.ru",
+    "servebbs.com",
+    "k12.ky.us",
+    "francaise.museum",
+    "teramo.it",
+    "tsuno.kochi.jp",
+    "kawaue.gifu.jp",
+    "sciences.museum",
+    "takko.aomori.jp",
+    "prochowice.pl",
+    "gs.svalbard.no",
+    "or.jp",
+    "k12.wy.us",
+    "xn--eveni-0qa01ga.no",
+    "kihoku.ehime.jp",
+    "ulan-ude.ru",
+    "maizuru.kyoto.jp",
+    "ac.jp",
+    "yawara.ibaraki.jp",
+    "s3-website-us-gov-west-1.amazonaws.com",
+    "xn--lt-liac.no",
+    "trento.it",
+    "sande.xn--mre-og-romsdal-qqb.no",
+    "press.ma",
+    "est-a-la-masion.com",
+    "kamisu.ibaraki.jp",
+    "perso.sn",
+    "florence.it",
+    "szczytno.pl",
+    "qc.ca",
+    "tas.gov.au",
+    "vestby.no",
+    "us-west-1.compute.amazonaws.com",
+    "us-west-2.compute.amazonaws.com",
+    "umi.fukuoka.jp",
+    "ac.rw",
+    "turin.it",
+    "lenvik.no",
+    "sciencecenter.museum",
+    "sciencecenters.museum",
+    "z-1.compute-1.amazonaws.com",
+    "z-2.compute-1.amazonaws.com",
+    "sa-east-1.compute.amazonaws.com",
+    "est-a-la-maison.com",
+    "shingu.fukuoka.jp",
+    "larvik.no",
+    "xn--mxtq1m",
+    "tohma.hokkaido.jp",
+    "lewismiller.museum",
+    "takagi.nagano.jp",
+    "technology.museum",
+    "xn--h2brj9c",
+    "tenei.fukushima.jp",
+    "qc.com",
+    "parma.it",
+    "prato.it",
+    "xn--55qx5d.cn",
+    "or.id",
+    "est-le-patron.com",
+    "tf",
+    "telekommunikation.museum",
+    "jan-mayen.no",
+    "tomiya.miyagi.jp",
+    "perso.ht",
+    "padua.it",
+    "ot.it",
+    "ac.id",
+    "or.it",
+    "kisofukushima.nagano.jp",
+    "tsuiki.fukuoka.jp",
+    "perso.tn",
+    "xn--c1avg",
+    "xn--fl-zia.no",
+    "og.ao",
+    "tsuru.yamanashi.jp",
+    "taira.toyama.jp",
+    "xn--mgbab2bd",
+    "ac.ir",
+    "or.ug",
+    "tendo.yamagata.jp",
+    "pesaro-urbino.it",
+    "xn--flor-jra.no",
+    "siracusa.it",
+    "press.museum",
+    "osoyro.no",
+    "valley.museum",
+    "ac.im",
+    "ac.ug",
+    "onjuku.chiba.jp",
+    "oarai.ibaraki.jp",
+    "toyono.osaka.jp",
+    "xn--czr694b",
+    "tarui.gifu.jp",
+    "tokai.aichi.jp",
+    "ug.gov.pl",
+    "otoyo.kochi.jp",
+    "ac.in",
+    "xn--80asehdb",
+    "paleo.museum",
+    "os.hedmark.no",
+    "stavanger.no",
+    "tokyo",
+    "oshima.yamaguchi.jp",
+    "tokorozawa.saitama.jp",
+    "takamori.nagano.jp",
+    "xn--czru2d",
+    "xn--wgbh1c",
+    "saskatchewan.museum",
+    "turystyka.pl",
+    "ichinomiya.chiba.jp",
+    "yaotsu.gifu.jp",
+    "saves-the-whales.com",
+    "sandoy.no",
+    "taiki.hokkaido.jp",
+    "xn--jrpeland-54a.no",
+    "okaya.nagano.jp",
+    "xn--brnnysund-m8ac.no",
+    "xn--fiqz9s",
+    "xn--mgberp4a5d4ar",
+    "shingu.wakayama.jp",
+    "pubol.museum",
+    "xn--snase-nra.no",
+    "otaki.chiba.jp",
+    "xn--fiqs8s",
+    "xn--54b7fta0cc",
+    "xn--mgba3a4f16a",
+    "xn--mgba3a4fra",
+    "omiya.saitama.jp",
+    "xn--tjme-hra.no",
+    "ichinomiya.aichi.jp",
+    "inzai.chiba.jp",
+    "tychy.pl",
+    "xn--frya-hra.no",
+    "spy.museum",
+    "xn--fjord-lra.no",
+    "xn--fiq64b",
+    "xn--vegrshei-c0a.no",
+    "xn--mxtq1m.hk",
+    "toba.mie.jp",
+    "louvre.museum",
+    "tamba.hyogo.jp",
+    "tsuruoka.yamagata.jp",
+    "xn--skierv-uta.no",
+    "buyshouses.net",
+    "xn--od0alg.cn",
+    "co.ve",
+    "xn--brnny-wuac.no",
+    "tado.mie.jp",
+    "xn--rsta-fra.no",
+    "taito.tokyo.jp",
+    "xn--mgba3a4f16a.ir",
+    "xn--mgba3a4fra.ir",
+    "dyn-o-saur.com",
+    "xn--jlster-bya.no",
+    "torino.it",
+    "oi.kanagawa.jp",
+    "la.us",
+    "hamatonbetsu.hokkaido.jp",
+    "tgory.pl",
+    "texas.museum",
+    "xn--frna-woa.no",
+    "lt.ua",
+    "xn--slt-elab.no",
+    "science-fiction.museum",
+    "co.vi",
+    "chiryu.aichi.jp",
+    "shibuya.tokyo.jp",
+    "pskov.ru",
+    "xn--mgbx4cd0ab",
+    "nakatombetsu.hokkaido.jp",
+    "buzz",
+    "isa-geek.com",
+    "xn--ksnes-uua.no",
+    "kawazu.shizuoka.jp",
+    "so.gov.pl",
+    "toyako.hokkaido.jp",
+    "xn--blt-elab.no",
+    "city.kobe.jp",
+    "finnoy.no",
+    "toyoake.aichi.jp",
+    "rc.it",
+    "lv.ua",
+    "xn--ciqpn.hk",
+    "org.sy",
+    "pavia.it",
+    "tsuga.tochigi.jp",
+    "org.py",
+    "servegame.org",
+    "sr.gov.pl",
+    "tamano.okayama.jp",
+    "arezzo.it",
+    "xn--mgb9awbf",
+    "xn--o3cw4h",
+    "toyokawa.aichi.jp",
+    "org.uy",
+    "sa.gov.au",
+    "org.my",
+    "xn--mlselv-iua.no",
+    "og.it",
+    "paris.museum",
+    "ln.cn",
+    "imizu.toyama.jp",
+    "ichinohe.iwate.jp",
+    "xn--merker-kua.no",
+    "sue.fukuoka.jp",
+    "thruhere.net",
+    "org.ly",
+    "tako.chiba.jp",
+    "niiza.saitama.jp",
+    "torino.museum",
+    "os.hordaland.no",
+    "xn--bjarky-fya.no",
+    "xn--9dbhblg6di.museum",
+    "lib.gu.us",
+    "pf",
+    "taiji.wakayama.jp",
+    "org.ky",
+    "tom.ru",
+    "travel",
+    "xn--h1aegh.museum",
+    "xn--xkc2dl3a5ee0h",
+    "ojiya.niigata.jp",
+    "tsuyama.okayama.jp",
+    "ski.museum",
+    "motosu.gifu.jp",
+    "xn--hmmrfeasta-s4ac.no",
+    "is-a-liberal.com",
+    "prd.fr",
+    "chizu.tottori.jp",
+    "surrey.museum",
+    "xn--mgberp4a5d4a87g",
+    "town",
+    "tsushima.aichi.jp",
+    "s3-us-west-1.amazonaws.com",
+    "xn--i1b6b1a6a2e",
+    "xn--oppegrd-ixa.no",
+    "xn--xkc2al3hye2a",
+    "xn--vre-eiker-k8a.no",
+    "moriguchi.osaka.jp",
+    "tree.museum",
+    "tank.museum",
+    "pordenone.it",
+    "xn--nttery-byae.no",
+    "s3-eu-west-1.amazonaws.com",
+    "tarnobrzeg.pl",
+    "is-a-libertarian.com",
+    "time.museum",
+    "xn--mgbtf8fl",
+    "porsanger.no",
+    "xn--ogbpf8fl",
+    "takahama.aichi.jp",
+    "treviso.it",
+    "tas.au",
+    "le.it",
+    "lo.it",
+    "fribourg.museum",
+    "teaches-yoga.com",
+    "xn--hbmer-xqa.no",
+    "lt.it",
+    "xn--lury-ira.no",
+    "xn--sgne-gra.no",
+    "xn--czrw28b.tw",
+    "shimonoseki.yamaguchi.jp",
+    "lu.it",
+    "xn--laheadju-7ya.no",
+    "shizukuishi.iwate.jp",
+    "lg.ua",
+    "tochio.niigata.jp",
+    "environmentalconservation.museum",
+    "li.it",
+    "monza.it",
+    "tempio-olbia.it",
+    "xn--finny-yua.no",
+    "ushiku.ibaraki.jp",
+    "vf.no",
+    "ichinoseki.iwate.jp",
+    "yaizu.shizuoka.jp",
+    "xn--mgbbh1a71e",
+    "podlasie.pl",
+    "lazio.it",
+    "xn--muost-0qa.no",
+    "mc.it",
+    "sydney.museum",
+    "tagajo.miyagi.jp",
+    "pomorskie.pl",
+    "xn--ystre-slidre-ujb.no",
+    "tozsde.hu",
+    "xn--bhcavuotna-s4a.no",
+    "org.cu",
+    "polkowice.pl",
+    "xn--krager-gya.no",
+    "sarufutsu.hokkaido.jp",
+    "xn--mtta-vrjjat-k7af.no",
+    "inazawa.aichi.jp",
+    "xn--hgebostad-g3a.no",
+    "is-a-green.com",
+    "ltd.co.im",
+    "tsk.ru",
+    "sicily.it",
+    "xn--czrs0t",
+    "lib.co.us",
+    "parliament.uk",
+    "piemonte.it",
+    "ofunato.iwate.jp",
+    "city.yokohama.jp",
+    "presidio.museum",
+    "ono.hyogo.jp",
+    "freiburg.museum",
+    "isteingeek.de",
+    "agency",
+    "xn--srreisa-q1a.no",
+    "xn--lgbbat1ad8j",
+    "torahime.shiga.jp",
+    "trader.aero",
+    "xn--nqv7fs00ema",
+    "sc.us",
+    "taki.mie.jp",
+    "supply",
+    "is-a-cubicle-slave.com",
+    "vc.it",
+    "xn--bhccavuotna-k7a.no",
+    "tawaramoto.nara.jp",
+    "portland.museum",
+    "sc.tz",
+    "taiwa.miyagi.jp",
+    "air-traffic-control.aero",
+    "sc.kr",
+    "tamakawa.fukushima.jp",
+    "tachiarai.fukuoka.jp",
+    "chippubetsu.hokkaido.jp",
+    "katsuyama.fukui.jp",
+    "lg.jp",
+    "dyndns-remote.com",
+    "pasadena.museum",
+    "sc.cn",
+    "production.aero",
+    "takahama.fukui.jp",
+    "tomobe.ibaraki.jp",
+    "tosashimizu.kochi.jp",
+    "utazu.kagawa.jp",
+    "family.museum",
+    "toyota.aichi.jp",
+    "toyone.aichi.jp",
+    "ac.pa",
+    "ac.pr",
+    "takino.hyogo.jp",
+    "sasaguri.fukuoka.jp",
+    "shiriuchi.hokkaido.jp",
+    "graz.museum",
+    "operaunite.com",
+    "xn--davvenjrga-y4a.no",
+    "sf.no",
+    "xn--mgbc0a9azcg",
+    "githubusercontent.com",
+    "katsuura.chiba.jp",
+    "ichikawa.chiba.jp",
+    "ichihara.chiba.jp",
+    "geometre-expert.fr",
+    "sor-fron.no",
+    "tahara.aichi.jp",
+    "otsuchi.iwate.jp",
+    "takanabe.miyazaki.jp",
+    "ogawa.ibaraki.jp",
+    "tochigi.tochigi.jp",
+    "or.pw",
+    "priv.pl",
+    "nt.edu.au",
+    "xn--berlevg-jxa.no",
+    "tokamachi.niigata.jp",
+    "priv.no",
+    "hofu.yamaguchi.jp",
+    "togakushi.nagano.jp",
+    "xn--io0a7i.cn",
+    "ono.fukui.jp",
+    "historyofscience.museum",
+    "poznan.pl",
+    "toride.ibaraki.jp",
+    "sc.ug",
+    "shizuoka.jp",
+    "tamamura.gunma.jp",
+    "s3.amazonaws.com",
+    "travel.tt",
+    "xn--kvitsy-fya.no",
+    "yuza.yamagata.jp",
+    "aizubange.fukushima.jp",
+    "xn--skjervy-v1a.no",
+    "xn--rennesy-v1a.no",
+    "lebtimnetz.de",
+    "takayama.gifu.jp",
+    "likes-pie.com",
+    "xn--gildeskl-g0a.no",
+    "xn--vler-qoa.xn--stfold-9xa.no",
+    "corvette.museum",
+    "travel.pl",
+    "fc.it",
+    "priv.me",
+    "leitungsen.de",
+    "palace.museum",
+    "xn--langevg-jxa.no",
+    "oto.fukuoka.jp",
+    "priv.at",
+    "ohi.fukui.jp",
+    "xn--loabt-0qa.no",
+    "xn--aurskog-hland-jnb.no",
+    "wa.edu.au",
+    "uchiko.ehime.jp",
+    "takanezawa.tochigi.jp",
+    "towada.aomori.jp",
+    "tabuse.yamaguchi.jp",
+    "ono.fukushima.jp",
+    "tozawa.yamagata.jp",
+    "gs.sf.no",
+    "scrapping.cc",
+    "gs.of.no",
+    "jfk.museum",
+    "kujukuri.chiba.jp",
+    "te.ua",
+    "toyota.yamaguchi.jp",
+    "tokuyama.yamaguchi.jp",
+    "for-better.biz",
+    "for-the.biz",
+    "sande.vestfold.no",
+    "tm.se",
+    "xn--porsgu-sta26f.no",
+    "hagi.yamaguchi.jp",
+    "tysvar.no",
+    "tn.us",
+    "komvux.se",
+    "xn--moreke-jua.no",
+    "ftpaccess.cc",
+    "tr.no",
+    "tm.fr",
+    "tv.sd",
+    "oki.fukuoka.jp",
+    "shizuoka.shizuoka.jp",
+    "tm.no",
+    "topology.museum",
+    "tm.km",
+    "paroch.k12.ma.us",
+    "tv.tz",
+    "tj.cn",
+    "tomika.gifu.jp",
+    "cc.me.us",
+    "cc.ms.us",
+    "cc.de.us",
+    "cc.md.us",
+    "cc.sd.us",
+    "cc.mo.us",
+    "cc.as.us",
+    "xn--node",
+    "cc.ma.us",
+    "cc.la.us",
+    "cc.mt.us",
+    "cc.ut.us",
+    "cc.co.us",
+    "cc.ar.us",
+    "cc.or.us",
+    "tamayu.shimane.jp",
+    "xn--mosjen-eya.no",
+    "cc.ks.us",
+    "cc.az.us",
+    "luxury",
+    "tm.ro",
+    "parachuting.aero",
+    "tv.na",
+    "cc.ca.us",
+    "tv.bo",
+    "sch.ly",
+    "cc.ct.us",
+    "cc.mi.us",
+    "tv.br",
+    "cc.ne.us",
+    "cc.nd.us",
+    "cc.mn.us",
+    "sor-aurdal.no",
+    "cc.tn.us",
+    "pippu.hokkaido.jp",
+    "cc.al.us",
+    "nrw.museum",
+    "cc.nj.us",
+    "cc.nm.us",
+    "cc.ga.us",
+    "tm.hu",
+    "cc.fl.us",
+    "cc.gu.us",
+    "tw.cn",
+    "cc.ak.us",
+    "cc.ok.us",
+    "cc.oh.us",
+    "cc.nv.us",
+    "cc.ri.us",
+    "ap-northeast-1.compute.amazonaws.com",
+    "cc.nh.us",
+    "tokyo.jp",
+    "priv.hu",
+    "mazury.pl",
+    "lib.ny.us",
+    "cc.hi.us",
+    "tx.us",
+    "takasu.hokkaido.jp",
+    "te.it",
+    "ts.it",
+    "to.it",
+    "tp.it",
+    "ta.it",
+    "tr.it",
+    "cc.ky.us",
+    "tt.im",
+    "lib.ky.us",
+    "of.no",
+    "tm.mg",
+    "xn--q9jyb4c",
+    "cc.ny.us",
+    "tn.it",
+    "lib.wy.us",
+    "pp.se",
+    "gs.va.no",
+    "tv.it",
+    "pa.us",
+    "pp.ua",
+    "pr.us",
+    "taiki.mie.jp",
+    "tv.im",
+    "tomigusuku.okinawa.jp",
+    "cc.id.us",
+    "pp.az",
+    "cc.tx.us",
+    "pe.ca",
+    "cc.ia.us",
+    "pe.kr",
+    "pb.ao",
+    "przeworsk.pl",
+    "cc.in.us",
+    "properties",
+    "pl.ua",
+    "monzaedellabrianza.it",
+    "cc.il.us",
+    "tajimi.gifu.jp",
+    "xn--cg4bki",
+    "powiat.pl",
+    "pp.ru",
+    "press.aero",
+    "mulhouse.museum",
+    "kawaguchi.saitama.jp",
+    "oe.yamagata.jp",
+    "lviv.ua",
+    "tokai.ibaraki.jp",
+    "svizzera.museum",
+    "of.by",
+    "pilot.aero",
+    "press.se",
+    "parti.se",
+    "xn--dyry-ira.no",
+    "xn--fiq228c5hs",
+    "pesarourbino.it",
+    "sa.edu.au",
+    "xn--aroport-bya.ci",
+    "pe.it",
+    "pd.it",
+    "po.it",
+    "cc.wa.us",
+    "pa.it",
+    "pt.it",
+    "pr.it",
+    "pu.it",
+    "pz.it",
+    "xn--hylandet-54a.no",
+    "cc.wi.us",
+    "pi.it",
+    "xn--fzc2c9e2c",
+    "pn.it",
+    "sellsyourhome.org",
+    "cc.wv.us",
+    "ac.vn",
+    "pv.it",
+    "tohnosho.chiba.jp",
+    "us-gov-west-1.compute.amazonaws.com",
+    "safety.aero",
+    "xn--gecrj9c",
+    "for-some.biz",
+    "plc.co.im",
+    "cc.wy.us",
+    "for-more.biz",
+    "lomza.pl",
+    "xn--tysvr-vra.no",
+    "tateyama.chiba.jp",
+    "xn--gls-elac.no",
+    "xn--ryrvik-bya.no",
+    "xn--sndre-land-0cb.no",
+    "xn--mgbqly7cvafr",
+    "tempioolbia.it",
+    "xn--ostery-fya.no",
+    "lc.it",
+    "tokoname.aichi.jp",
+    "encyclopedic.museum",
+    "pg.it",
+    "lowicz.pl",
+    "traeumtgerade.de",
+    "xn--nmesjevuemie-tcba.no",
+    "tomisato.chiba.jp",
+    "pisz.pl",
+    "podzone.net",
+    "tsukiyono.gunma.jp",
+    "takinoue.hokkaido.jp",
+    "plc.ly",
+    "tm.pl",
+    "cc.pa.us",
+    "cc.pr.us",
+    "okazaki.aichi.jp",
+    "tranoy.no",
+    "xn--indery-fya.no",
+    "outsystemscloud.com",
+    "tranby.no",
+    "xn--frde-gra.no",
+    "ptz.ru",
+    "passenger-association.aero",
+    "principe.st",
+    "posts-and-telecommunications.museum",
+    "office-on-the.net",
+    "xn--hyanger-q1a.no",
+    "elasticbeanstalk.com",
+    "podzone.org",
+    "pharmacy.museum",
+    "town.museum",
+    "pharmaciens.km",
+    "xn--tnsberg-q1a.no",
+    "dyndns-office.com",
+    "po.gov.pl",
+    "pa.gov.pl",
+    "grozny.ru",
+    "tm.mc",
+    "pacific.museum",
+    "pulawy.pl",
+    "cc.sc.us",
+    "cc.dc.us",
+    "linz.museum",
+    "xn--rhkkervju-01af.no",
+    "ap-southeast-2.compute.amazonaws.com",
+    "tanagura.fukushima.jp",
+    "cc.nc.us",
+    "est-mon-blogueur.com",
+    "for-our.info",
+    "gs.vf.no",
+    "xn--fpcrj9c3d",
+    "cc.va.us",
+    "cc.vt.us",
+    "cc.vi.us",
+    "penza.ru",
+    "pc.it",
+    "ap-southeast-1.compute.amazonaws.com",
+    "xn--stre-toten-zcb.no",
+    "plaza.museum",
+    "xn--ryken-vua.no",
+    "salzburg.museum",
+    "tcm.museum",
+    "olsztyn.pl",
+    "air-surveillance.aero",
+    "xn--mgbqly7c0a67fbc",
+    "pc.pl",
+    "pharmacien.fr",
     "xn--clchc0ea0b2g2a9gcd",
     "xn--comunicaes-v6a2o.museum",
-    "shinjo.nara.jp",
-    "us-gov-west-1.compute.amazonaws.com",
-    "shinonsen.hyogo.jp",
-    "parti.se",
-    "properties",
-    "sakuho.nagano.jp",
-    "s3-website-us-east-1.amazonaws.com",
-    "s3-website-sa-east-1.amazonaws.com",
-    "for-some.biz",
-    "media.aero",
-    "monzaedellabrianza.it",
-    "environmentalconservation.museum",
-    "s3-fips-us-gov-west-1.amazonaws.com",
-    "sasebo.nagasaki.jp",
-    "for-more.biz",
-    "svizzera.museum",
-    "pharmaciens.km",
-    "bellevue.museum",
-    "mulhouse.museum",
-    "pharmacy.museum",
-    "shinjo.okayama.jp",
-    "s3-website-us-west-1.amazonaws.com",
-    "forli-cesena.it",
-    "sekigahara.gifu.jp",
-    "s3-us-west-1.amazonaws.com",
-    "ichinoseki.iwate.jp",
-    "maritime.museum",
-    "s3-website-ap-southeast-1.amazonaws.com",
-    "s3-eu-west-1.amazonaws.com",
-    "isteingeek.de",
-    "shinto.gunma.jp",
-    "shima.mie.jp",
-    "stateofdelaware.museum",
-    "s3-website-eu-west-1.amazonaws.com",
-    "s3-website-ap-northeast-1.amazonaws.com",
-    "takinoue.hokkaido.jp",
-    "museumcenter.museum",
-    "shiwa.iwate.jp",
-    "showa.gunma.jp",
-    "sakae.chiba.jp",
-    "sellsyourhome.org",
-    "furudono.fukushima.jp",
-    "showa.yamanashi.jp",
-    "dyndns-office.com",
-    "shingo.aomori.jp",
-    "saskatchewan.museum",
-    "buyshouses.net",
-    "showa.fukushima.jp",
-    "safety.aero",
-    "florence.it",
-    "shinjo.yamagata.jp",
-    "pacific.museum",
-    "dnepropetrovsk.ua",
-    "uchiko.ehime.jp",
-    "sanagochi.tokushima.jp",
-    "meiwa.mie.jp",
-    "sakahogi.gifu.jp",
-    "dnipropetrovsk.ua",
     "isa-hockeynut.com",
-    "s3-website-us-gov-west-1.amazonaws.com",
-    "xn--rhkkervju-01af.no",
-    "geometre-expert.fr",
-    "shinyoshitomi.fukuoka.jp",
-    "xn--correios-e-telecomunicaes-ghc29a.museum",
-    "sande.xn--mre-og-romsdal-qqb.no",
-    "pharmacien.fr",
-    "sande.vestfold.no"
+    "xn--correios-e-telecomunicaes-ghc29a.museum"
   };
 #define stringpool ((const char *) &stringpool_contents)
 const struct DomainRule *
@@ -13285,17147 +13373,15510 @@
 {
   static const struct DomainRule wordlist[] =
     {
-#line 428 "effective_tld_names.gperf"
+#line 432 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str0, 0},
-#line 2883 "effective_tld_names.gperf"
+#line 2905 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1, 2},
-#line 1760 "effective_tld_names.gperf"
+#line 1777 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str2, 0},
-#line 2334 "effective_tld_names.gperf"
+#line 610 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str3, 0},
-#line 747 "effective_tld_names.gperf"
+#line 2355 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str4, 0},
-#line 426 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5, 2},
-#line 1755 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6, 0},
-#line 3883 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str7, 0},
-#line 2324 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str8, 0},
-#line 3903 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str9, 0},
-#line 866 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str10, 0},
-#line 558 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str11, 0},
-#line 931 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str12, 0},
-#line 1870 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, 0},
-#line 2463 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str14, 0},
-#line 605 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, 0},
-#line 2007 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str16, 0},
-#line 4094 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, 0},
-#line 499 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str18, 0},
-#line 2473 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, 0},
-#line 3034 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str20, 0},
-#line 1982 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str21, 0},
-#line 3998 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, 0},
-#line 4000 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str23, 0},
-#line 3931 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str24, 0},
-#line 4147 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str25, 2},
-#line 1034 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str26, 0},
-#line 1037 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, 0},
-#line 962 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str28, 0},
-#line 1967 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str29, 0},
-#line 1965 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str30, 0},
-#line 1388 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str31, 0},
-#line 1966 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str32, 0},
-#line 1899 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, 0},
-#line 3983 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, 0},
-#line 3982 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str35, 0},
-#line 3987 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str36, 0},
-#line 3985 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str37, 0},
-#line 1018 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str38, 0},
-#line 1017 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str39, 0},
-#line 1021 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str40, 0},
-#line 1844 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str41, 0},
-#line 1949 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str42, 0},
-#line 1948 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str43, 0},
-#line 1953 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str44, 0},
-#line 1019 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str45, 0},
-#line 3994 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str46, 0},
-#line 2030 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str47, 0},
-#line 1951 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str48, 0},
-#line 4114 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str49, 0},
-#line 1757 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str50, 0},
-#line 2624 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str51, 0},
-#line 1848 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str52, 0},
-#line 1030 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str53, 0},
-#line 1769 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str54, 0},
-#line 1445 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str55, 0},
-#line 1961 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str56, 0},
-#line 751 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str57, 0},
-#line 2643 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str58, 0},
-#line 1829 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str59, 0},
-#line 965 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str60, 0},
-#line 1035 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str61, 0},
-#line 1836 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str62, 0},
-#line 4108 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str63, 0},
-#line 3984 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str64, 0},
-#line 2660 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str65, 0},
-#line 1849 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str66, 0},
-#line 1950 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str67, 0},
-#line 3986 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str68, 0},
-#line 1455 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str69, 0},
-#line 1273 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str70, 0},
-#line 1020 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str71, 0},
-#line 2645 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str72, 0},
-#line 1952 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str73, 0},
-#line 1830 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str74, 0},
-#line 1066 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str75, 0},
-#line 641 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str76, 0},
-#line 379 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str77, 0},
-#line 1731 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str78, 0},
-#line 402 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str79, 0},
-#line 682 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str80, 0},
-#line 3754 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str81, 0},
-#line 1367 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str82, 0},
-#line 1369 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str83, 0},
-#line 1299 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str84, 0},
-#line 3909 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str85, 0},
+#line 2026 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5, 0},
 #line 3911 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str86, 0},
-#line 936 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str87, 0},
-#line 1352 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str88, 0},
-#line 1351 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str89, 0},
-#line 1356 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str90, 0},
-#line 1874 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str91, 0},
-#line 6507 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str92, 2},
-#line 938 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str93, 0},
-#line 1354 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str94, 0},
-#line 4020 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str95, 0},
-#line 940 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str96, 0},
-#line 1364 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str97, 0},
-#line 646 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str98, 0},
-#line 3904 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str99, 0},
-#line 3288 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str100, 0},
-#line 932 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str101, 0},
-#line 1871 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str102, 0},
-#line 607 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str103, 0},
-#line 668 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str104, 0},
-#line 2031 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str105, 0},
-#line 1258 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str106, 0},
-#line 2575 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str107, 0},
-#line 1302 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str108, 0},
-#line 1368 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str109, 0},
-#line 1101 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str110, 0},
-#line 579 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str111, 0},
-#line 3035 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str112, 0},
-#line 1984 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str113, 0},
-#line 1825 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str114, 0},
-#line 3910 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str115, 0},
-#line 2466 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str116, 0},
-#line 4007 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str117, 0},
-#line 4148 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str118, 0},
-#line 937 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str119, 0},
-#line 1353 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str120, 0},
-#line 2333 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str121, 0},
-#line 1044 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str122, 0},
-#line 4008 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str123, 0},
-#line 1970 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str124, 0},
-#line 1974 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str125, 0},
-#line 1045 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str126, 0},
-#line 1975 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str127, 0},
-#line 3991 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str128, 0},
-#line 1355 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str129, 0},
-#line 3995 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str130, 0},
-#line 1875 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str131, 0},
-#line 1027 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str132, 0},
-#line 1958 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str133, 0},
-#line 1031 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str134, 0},
-#line 6529 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str135, 0},
-#line 1458 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str136, 2},
-#line 1962 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str137, 0},
-#line 3993 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str138, 0},
-#line 1029 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str139, 0},
-#line 1441 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str140, 2},
-#line 1116 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str141, 0},
-#line 1960 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str142, 0},
-#line 3044 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str143, 0},
-#line 2032 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str144, 2},
-#line 4005 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str145, 0},
-#line 2042 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str146, 0},
-#line 4162 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str147, 0},
-#line 1042 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str148, 0},
-#line 1972 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str149, 0},
-#line 1276 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str150, 0},
-#line 1278 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str151, 0},
-#line 3278 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str152, 0},
-#line 963 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str153, 0},
-#line 1900 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str154, 0},
-#line 958 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str155, 4},
-#line 1129 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str156, 0},
-#line 635 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str157, 0},
-#line 3127 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str158, 0},
-#line 88 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str159, 0},
-#line 1274 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str160, 0},
-#line 81 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str161, 0},
-#line 4180 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str162, 2},
-#line 1956 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str163, 0},
-#line 3949 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str164, 0},
-#line 3130 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str165, 0},
-#line 1465 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str166, 0},
-#line 1099 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str167, 0},
-#line 214 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str168, 0},
-#line 3980 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str169, 0},
-#line 276 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str170, 0},
-#line 1014 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str171, 0},
-#line 1277 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str172, 0},
-#line 3912 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str173, 0},
-#line 1375 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str174, 0},
-#line 4113 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str175, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6, 0},
+#line 2495 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str7, 0},
+#line 754 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str8, 0},
+#line 430 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str9, 2},
+#line 1772 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str10, 0},
+#line 3931 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str11, 0},
+#line 2345 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str12, 0},
+#line 873 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, 0},
+#line 563 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str14, 0},
 #line 939 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str176, 0},
-#line 3142 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str177, 0},
-#line 1876 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str178, 0},
-#line 1376 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str179, 0},
-#line 2632 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str180, 1},
-#line 4271 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str181, 0},
-#line 858 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str182, 0},
-#line 554 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str183, 0},
-#line 2966 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str184, 0},
-#line 1809 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str185, 0},
-#line 1361 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str186, 0},
-#line 2363 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str187, 0},
-#line 3810 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str188, 0},
-#line 91 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str189, 0},
-#line 669 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str190, 0},
-#line 1365 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str191, 0},
-#line 3289 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str192, 0},
-#line 1835 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str193, 0},
-#line 3973 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str194, 0},
-#line 3966 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str195, 0},
-#line 3965 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str196, 0},
-#line 3969 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str197, 0},
-#line 1363 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str198, 0},
-#line 4153 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str199, 0},
-#line 1866 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str200, 0},
-#line 1006 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str201, 0},
-#line 999 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str202, 0},
-#line 998 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str203, 0},
-#line 1002 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str204, 0},
-#line 3972 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str205, 0},
-#line 1934 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str206, 0},
-#line 1933 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str207, 0},
-#line 6528 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str208, 2},
-#line 3287 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str209, 0},
-#line 4104 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str210, 0},
-#line 1937 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str211, 0},
-#line 1005 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str212, 0},
-#line 1941 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str213, 0},
-#line 4149 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str214, 0},
-#line 2555 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str215, 0},
-#line 3990 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str216, 0},
-#line 1300 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str217, 0},
-#line 1026 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str218, 0},
-#line 1957 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str219, 0},
-#line 403 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str220, 0},
-#line 639 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str221, 4},
-#line 4142 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str222, 0},
-#line 1833 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str223, 0},
-#line 3859 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str224, 0},
-#line 1359 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str225, 0},
-#line 2642 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str226, 2},
-#line 3043 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str227, 0},
-#line 1935 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str228, 0},
-#line 3905 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str229, 0},
-#line 3295 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str230, 0},
-#line 824 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str231, 0},
-#line 459 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str232, 0},
-#line 483 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str233, 0},
-#line 2902 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str234, 0},
-#line 1780 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str235, 0},
-#line 2915 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str236, 0},
-#line 1348 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str237, 0},
-#line 1872 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str238, 0},
-#line 3968 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str239, 0},
-#line 4037 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str240, 2},
-#line 1001 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str241, 0},
-#line 1279 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str242, 0},
-#line 1938 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str243, 0},
-#line 1734 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str244, 0},
-#line 860 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str245, 0},
-#line 556 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str246, 2},
-#line 2969 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str247, 0},
-#line 1811 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str248, 0},
-#line 3947 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str249, 0},
-#line 2373 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str250, 0},
-#line 1735 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str251, 0},
-#line 919 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str252, 0},
-#line 3147 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str253, 0},
-#line 1913 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str254, 0},
-#line 2440 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str255, 0},
-#line 1911 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str256, 0},
-#line 3049 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str257, 0},
-#line 493 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str258, 0},
-#line 492 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str259, 0},
-#line 3977 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str260, 0},
-#line 4329 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str261, 0},
-#line 494 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str262, 0},
-#line 1011 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str263, 0},
-#line 1342 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str264, 0},
-#line 1335 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str265, 0},
-#line 1334 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str266, 0},
-#line 1339 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str267, 0},
-#line 1945 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str268, 0},
-#line 3818 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str269, 0},
-#line 1341 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str270, 0},
-#line 1765 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str271, 0},
-#line 448 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str272, 0},
-#line 434 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str273, 0},
-#line 2279 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str274, 0},
-#line 330 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str275, 0},
-#line 1024 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str276, 0},
-#line 3945 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str277, 0},
-#line 4437 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str278, 0},
-#line 2451 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str279, 0},
-#line 4440 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str280, 0},
-#line 4359 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str281, 0},
-#line 3819 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str282, 0},
-#line 4115 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str283, 0},
-#line 1909 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str284, 0},
-#line 1360 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str285, 0},
-#line 234 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str286, 0},
-#line 4154 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str287, 0},
-#line 4420 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str288, 0},
-#line 4003 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str289, 0},
-#line 4419 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str290, 0},
-#line 4424 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str291, 0},
-#line 3948 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str292, 0},
-#line 4422 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str293, 0},
-#line 1040 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str294, 0},
-#line 1969 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str295, 0},
-#line 982 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str296, 0},
-#line 4432 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str297, 0},
-#line 1912 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str298, 0},
-#line 1853 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str299, 0},
-#line 1336 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str300, 0},
-#line 3970 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str301, 0},
-#line 424 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str302, 0},
-#line 1751 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str303, 0},
-#line 2850 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str304, 0},
-#line 1003 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str305, 0},
-#line 452 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str306, 0},
-#line 336 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str307, 0},
-#line 1939 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str308, 0},
-#line 4362 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str309, 0},
-#line 1338 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str310, 0},
-#line 3921 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str311, 0},
-#line 4438 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str312, 0},
-#line 264 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str313, 0},
-#line 3919 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str314, 0},
-#line 950 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str315, 0},
-#line 340 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str316, 0},
-#line 1886 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str317, 0},
-#line 948 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str318, 0},
-#line 2284 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str319, 0},
-#line 1316 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str320, 0},
-#line 1884 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str321, 0},
-#line 4421 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str322, 0},
-#line 4106 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str323, 0},
-#line 376 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str324, 0},
-#line 4135 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str325, 0},
-#line 3893 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str326, 1},
-#line 484 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str327, 4},
-#line 654 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str328, 0},
-#line 843 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str329, 2},
-#line 1456 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str330, 0},
-#line 4423 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str331, 0},
-#line 1345 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str332, 0},
-#line 3848 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str333, 0},
-#line 4198 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str334, 0},
-#line 2668 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str335, 0},
-#line 265 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str336, 0},
-#line 3187 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str337, 0},
-#line 370 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str338, 0},
-#line 2622 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str339, 0},
-#line 257 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str340, 0},
-#line 987 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str341, 0},
-#line 1919 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str342, 0},
-#line 2441 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str343, 0},
-#line 1313 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str344, 0},
-#line 423 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str345, 0},
-#line 562 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str346, 0},
-#line 3273 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str347, 0},
-#line 3920 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str348, 0},
-#line 4335 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str349, 0},
-#line 4337 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str350, 0},
-#line 949 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str351, 0},
-#line 3964 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str352, 0},
-#line 1372 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str353, 0},
-#line 1885 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str354, 0},
-#line 1315 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str355, 0},
-#line 496 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str356, 0},
-#line 2652 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str357, 0},
-#line 1868 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str358, 0},
-#line 2994 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str359, 0},
-#line 1071 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str360, 0},
-#line 1931 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str361, 0},
-#line 304 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str362, 0},
-#line 465 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str363, 0},
-#line 354 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str364, 0},
-#line 171 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str365, 0},
-#line 3943 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str366, 0},
-#line 4330 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str367, 0},
-#line 676 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str368, 0},
-#line 3255 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str369, 0},
-#line 2286 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str370, 0},
-#line 3953 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str371, 0},
-#line 2972 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str372, 2},
-#line 1918 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str373, 0},
-#line 2291 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str374, 0},
-#line 2455 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str375, 0},
-#line 1107 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str376, 0},
-#line 1289 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str377, 0},
-#line 2142 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str378, 0},
-#line 1449 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str379, 0},
-#line 1287 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str380, 0},
-#line 845 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str381, 0},
-#line 1798 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str382, 0},
-#line 4336 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str383, 0},
-#line 2289 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str384, 0},
-#line 2359 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str385, 2},
-#line 4448 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str386, 0},
-#line 4087 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str387, 0},
-#line 2453 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str388, 0},
-#line 4449 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str389, 0},
-#line 2123 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str390, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, 0},
+#line 2485 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str16, 0},
+#line 1888 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, 0},
+#line 4123 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str18, 0},
+#line 4026 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, 0},
+#line 4028 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str20, 0},
 #line 3959 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str391, 0},
-#line 3820 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str392, 0},
-#line 3960 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str393, 0},
-#line 993 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str394, 0},
-#line 3159 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str395, 0},
-#line 1925 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str396, 0},
-#line 1927 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str397, 0},
-#line 994 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str398, 0},
-#line 4433 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str399, 0},
-#line 1783 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str400, 0},
-#line 1926 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str401, 0},
-#line 2568 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str402, 0},
-#line 2408 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str403, 0},
-#line 4479 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str404, 0},
-#line 2264 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str405, 0},
-#line 352 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str406, 0},
-#line 4431 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str407, 0},
-#line 3958 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str408, 0},
-#line 1322 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str409, 0},
-#line 3812 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str410, 0},
-#line 2433 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str411, 0},
-#line 1741 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str412, 0},
-#line 1908 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str413, 0},
-#line 992 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str414, 0},
-#line 1924 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str415, 0},
-#line 1800 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str416, 0},
-#line 2292 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str417, 0},
-#line 4446 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str418, 0},
-#line 117 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str419, 0},
-#line 4182 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str420, 0},
-#line 640 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str421, 0},
-#line 377 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str422, 0},
-#line 2673 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str423, 0},
-#line 3156 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str424, 0},
-#line 1729 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str425, 0},
-#line 1288 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str426, 0},
-#line 2305 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str427, 0},
-#line 3753 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str428, 0},
-#line 4360 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str429, 0},
-#line 1332 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str430, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str21, 0},
+#line 3056 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, 0},
+#line 2000 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str23, 0},
+#line 4022 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str24, 0},
+#line 1042 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str25, 0},
+#line 4176 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str26, 2},
+#line 1045 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, 0},
+#line 970 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str28, 0},
 #line 1983 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str431, 0},
-#line 3157 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str432, 0},
-#line 2465 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str433, 0},
-#line 3265 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str434, 0},
-#line 192 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str435, 0},
-#line 4293 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str436, 0},
-#line 922 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str437, 0},
-#line 4161 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str438, 0},
-#line 6102 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str439, 0},
-#line 2464 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str440, 0},
-#line 4428 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str441, 0},
-#line 6506 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str442, 0},
-#line 3915 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str443, 0},
-#line 4434 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str444, 0},
-#line 1321 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str445, 0},
-#line 4380 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str446, 0},
-#line 943 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str447, 0},
-#line 1879 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str448, 0},
-#line 3822 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str449, 0},
-#line 4416 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str450, 0},
-#line 1470 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str451, 0},
-#line 1463 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str452, 0},
-#line 1253 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str453, 0},
-#line 2418 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str454, 0},
-#line 3992 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str455, 0},
-#line 4338 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str456, 0},
-#line 3303 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str457, 0},
-#line 490 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str458, 0},
-#line 1028 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str459, 0},
-#line 1959 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str460, 0},
-#line 600 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str461, 0},
-#line 3979 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str462, 0},
-#line 2424 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str463, 0},
-#line 3165 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str464, 0},
-#line 1328 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str465, 0},
-#line 1013 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str466, 0},
-#line 274 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str467, 0},
-#line 1329 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str468, 0},
-#line 2235 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str469, 0},
-#line 478 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str470, 0},
-#line 4112 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str471, 0},
-#line 2006 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str472, 0},
-#line 2450 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str473, 0},
-#line 4409 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str474, 0},
-#line 4401 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str475, 0},
-#line 4400 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str476, 0},
-#line 4405 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str477, 0},
-#line 271 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str478, 0},
-#line 1327 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str479, 0},
-#line 4408 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str480, 0},
-#line 1416 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str481, 0},
-#line 2420 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str482, 0},
-#line 2452 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str483, 0},
-#line 759 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str484, 0},
-#line 458 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str485, 0},
-#line 2892 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str486, 2},
-#line 1779 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str487, 0},
-#line 1834 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str488, 0},
-#line 84 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str489, 0},
-#line 86 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str490, 0},
-#line 4429 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str491, 0},
-#line 3901 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str492, 0},
-#line 2332 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str493, 0},
-#line 3940 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str494, 0},
-#line 3942 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str495, 0},
-#line 975 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str496, 0},
-#line 978 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str497, 0},
-#line 2908 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str498, 0},
-#line 1907 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str499, 0},
-#line 4239 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str500, 0},
-#line 977 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str501, 0},
-#line 4402 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str502, 0},
-#line 1282 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str503, 0},
-#line 650 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str504, 0},
-#line 645 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str505, 0},
-#line 256 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str506, 0},
-#line 4331 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str507, 0},
-#line 491 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str508, 0},
-#line 1862 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str509, 0},
-#line 859 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str510, 0},
-#line 4404 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str511, 0},
-#line 3259 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str512, 0},
-#line 3821 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str513, 0},
-#line 3129 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str514, 0},
-#line 1362 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str515, 0},
-#line 3957 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str516, 0},
-#line 3199 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str517, 0},
-#line 991 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str518, 0},
-#line 1923 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str519, 0},
-#line 3941 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str520, 0},
-#line 4378 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str521, 0},
-#line 3946 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str522, 0},
-#line 1347 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str523, 0},
-#line 2237 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str524, 0},
-#line 976 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str525, 0},
-#line 981 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str526, 0},
-#line 2397 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str527, 0},
-#line 1910 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str528, 0},
-#line 1126 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str529, 2},
-#line 630 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str530, 0},
-#line 3116 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str531, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str29, 0},
+#line 1984 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str30, 0},
+#line 1917 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str31, 0},
+#line 1038 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str32, 0},
+#line 1979 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, 0},
+#line 1399 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, 0},
 #line 2049 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str532, 0},
-#line 495 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str533, 0},
-#line 4413 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str534, 0},
-#line 2369 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str535, 0},
-#line 3814 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str536, 0},
-#line 3930 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str537, 0},
-#line 2005 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str538, 0},
-#line 6386 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str539, 0},
-#line 553 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str540, 0},
-#line 961 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str541, 0},
-#line 765 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str542, 0},
-#line 1898 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str543, 0},
-#line 320 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str544, 0},
-#line 1832 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str545, 0},
-#line 4376 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str546, 0},
-#line 2454 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str547, 0},
-#line 2446 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str548, 0},
-#line 154 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str549, 0},
-#line 4086 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str550, 0},
-#line 3170 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str551, 0},
-#line 827 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str552, 0},
-#line 4444 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str553, 0},
-#line 1310 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str554, 0},
-#line 1312 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str555, 0},
-#line 4379 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str556, 0},
-#line 120 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str557, 0},
-#line 1841 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str558, 0},
-#line 4124 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str559, 0},
-#line 4406 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str560, 0},
-#line 2412 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str561, 0},
-#line 1415 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str562, 0},
-#line 2426 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str563, 0},
-#line 1796 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str564, 0},
-#line 3246 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str565, 0},
-#line 865 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str566, 0},
-#line 2468 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str567, 0},
-#line 2407 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str568, 0},
-#line 3178 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str569, 0},
-#line 4348 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str570, 0},
-#line 2413 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str571, 0},
-#line 1326 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str572, 0},
-#line 4346 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str573, 0},
-#line 1124 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str574, 0},
-#line 629 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str575, 0},
-#line 4349 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str576, 0},
-#line 3115 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str577, 2},
-#line 2046 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str578, 0},
-#line 1425 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str579, 0},
-#line 4009 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str580, 0},
-#line 3849 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str581, 0},
-#line 1311 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str582, 0},
-#line 1314 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str583, 0},
-#line 1863 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str584, 0},
-#line 1785 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str585, 0},
-#line 1046 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str586, 0},
-#line 28 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str587, 0},
-#line 1976 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str588, 0},
-#line 3932 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str589, 0},
-#line 230 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str590, 0},
-#line 2425 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str591, 0},
-#line 964 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str592, 0},
-#line 414 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str593, 0},
-#line 2231 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str594, 0},
-#line 6535 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str595, 2},
-#line 1901 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str596, 0},
-#line 124 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str597, 0},
-#line 1298 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str598, 0},
-#line 259 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str599, 0},
-#line 4721 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str600, 0},
-#line 4386 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str601, 0},
-#line 3996 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str602, 0},
-#line 487 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str603, 0},
-#line 1032 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str604, 0},
-#line 1963 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str605, 0},
-#line 273 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str606, 0},
-#line 3913 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str607, 0},
-#line 4347 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str608, 0},
-#line 941 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str609, 0},
-#line 1877 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str610, 0},
-#line 3908 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str611, 0},
-#line 4398 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str612, 0},
-#line 3315 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str613, 0},
-#line 2422 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str614, 0},
-#line 935 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str615, 0},
-#line 344 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str616, 0},
-#line 555 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str617, 0},
-#line 4016 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str618, 0},
-#line 3963 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str619, 0},
-#line 4385 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str620, 0},
-#line 1054 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str621, 0},
-#line 1980 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str622, 0},
-#line 1930 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str623, 0},
-#line 2448 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str624, 0},
-#line 1377 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str625, 0},
-#line 1869 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str626, 0},
-#line 2304 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str627, 0},
-#line 4392 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str628, 0},
-#line 1795 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str629, 0},
-#line 2396 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str630, 0},
-#line 1301 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str631, 0},
-#line 4393 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str632, 0},
-#line 1750 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str633, 0},
-#line 4391 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str634, 0},
-#line 1366 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str635, 0},
-#line 688 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str636, 0},
-#line 439 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str637, 0},
-#line 486 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str638, 0},
-#line 3907 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str639, 0},
-#line 934 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str640, 0},
-#line 1280 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str641, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str35, 0},
+#line 1457 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str36, 0},
 #line 4011 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str642, 0},
-#line 2968 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str643, 0},
-#line 2405 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str644, 0},
-#line 4105 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str645, 0},
-#line 2056 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str646, 0},
-#line 1049 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str647, 0},
-#line 2394 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str648, 0},
-#line 4141 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str649, 0},
-#line 1008 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str650, 0},
-#line 1432 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str651, 0},
-#line 4394 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str652, 0},
-#line 1382 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str653, 0},
-#line 4341 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str654, 0},
-#line 1383 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str655, 0},
-#line 2901 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str656, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str37, 0},
+#line 4010 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str38, 0},
+#line 4015 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str39, 0},
+#line 4013 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str40, 0},
 #line 2646 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str657, 0},
-#line 2423 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str658, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str41, 0},
+#line 1026 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str42, 0},
+#line 1025 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str43, 0},
+#line 1029 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str44, 0},
+#line 1862 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str45, 0},
+#line 1967 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str46, 0},
+#line 1966 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str47, 0},
+#line 1971 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str48, 0},
+#line 1027 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str49, 0},
+#line 1786 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str50, 0},
+#line 4143 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str51, 0},
+#line 1969 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str52, 0},
+#line 1866 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str53, 0},
+#line 1847 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str54, 0},
+#line 1774 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str55, 0},
+#line 758 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str56, 0},
+#line 2665 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str57, 0},
+#line 1043 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str58, 0},
+#line 2682 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str59, 0},
+#line 973 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str60, 0},
+#line 1854 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str61, 0},
+#line 4137 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str62, 0},
+#line 4012 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str63, 0},
+#line 1467 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str64, 0},
+#line 1867 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str65, 0},
+#line 1968 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str66, 0},
+#line 4014 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str67, 0},
+#line 1074 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str68, 0},
+#line 1284 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str69, 0},
+#line 2667 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str70, 0},
+#line 1028 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str71, 0},
+#line 1970 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str72, 0},
+#line 1848 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str73, 0},
+#line 1378 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str74, 0},
+#line 1380 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str75, 0},
+#line 1310 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str76, 0},
+#line 1375 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str77, 0},
+#line 646 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str78, 0},
+#line 383 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str79, 0},
+#line 1748 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str80, 0},
+#line 406 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str81, 0},
+#line 3781 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str82, 0},
+#line 689 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str83, 0},
+#line 1363 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str84, 0},
+#line 1362 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str85, 0},
+#line 1367 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str86, 0},
+#line 1365 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str87, 0},
+#line 674 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str88, 0},
+#line 612 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str89, 0},
+#line 3937 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str90, 0},
+#line 2050 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str91, 0},
+#line 2597 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str92, 0},
+#line 3939 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str93, 0},
+#line 3932 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str94, 0},
+#line 944 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str95, 0},
+#line 651 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str96, 0},
+#line 1892 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str97, 0},
+#line 1379 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str98, 0},
+#line 946 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str99, 0},
+#line 940 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str100, 0},
+#line 948 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str101, 0},
+#line 1889 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str102, 0},
+#line 1313 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str103, 0},
+#line 4035 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str104, 0},
+#line 1109 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str105, 0},
+#line 584 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str106, 0},
+#line 3057 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str107, 0},
+#line 2002 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str108, 0},
+#line 4023 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str109, 0},
+#line 4036 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str110, 0},
+#line 1269 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str111, 0},
+#line 2488 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str112, 0},
+#line 1052 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str113, 0},
+#line 4177 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str114, 0},
+#line 1988 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str115, 0},
+#line 2354 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str116, 0},
+#line 1992 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str117, 0},
+#line 1039 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str118, 0},
+#line 1053 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str119, 0},
+#line 1364 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str120, 0},
+#line 1980 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str121, 0},
+#line 1993 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str122, 0},
+#line 3066 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str123, 0},
+#line 1470 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str124, 2},
+#line 1843 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str125, 0},
+#line 3938 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str126, 0},
+#line 1366 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str127, 0},
+#line 945 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str128, 0},
+#line 4021 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str129, 0},
+#line 4019 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str130, 0},
+#line 1037 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str131, 0},
+#line 1035 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str132, 0},
+#line 1978 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str133, 0},
+#line 1976 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str134, 0},
+#line 4033 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str135, 0},
+#line 1893 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str136, 0},
+#line 6550 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str137, 2},
+#line 1453 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str138, 2},
+#line 1124 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str139, 0},
+#line 1050 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str140, 0},
+#line 2051 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str141, 2},
+#line 1990 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str142, 0},
+#line 4191 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str143, 0},
+#line 2061 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str144, 0},
+#line 1137 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str145, 0},
+#line 640 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str146, 0},
+#line 3149 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str147, 0},
+#line 88 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str148, 0},
+#line 279 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str149, 0},
+#line 4209 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str150, 2},
+#line 81 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str151, 0},
+#line 1287 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str152, 0},
+#line 216 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str153, 0},
+#line 971 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str154, 0},
+#line 1289 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str155, 0},
+#line 1285 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str156, 0},
+#line 1918 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str157, 0},
+#line 966 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str158, 4},
+#line 6573 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str159, 0},
+#line 1974 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str160, 0},
+#line 1477 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str161, 0},
+#line 1107 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str162, 0},
 #line 1386 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str163, 0},
+#line 4008 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str164, 0},
+#line 1376 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str165, 0},
+#line 1387 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str166, 0},
+#line 1022 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str167, 0},
+#line 504 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str168, 0},
+#line 91 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str169, 0},
+#line 4142 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str170, 0},
+#line 1288 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str171, 0},
+#line 2654 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str172, 1},
+#line 3837 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str173, 0},
+#line 4182 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str174, 0},
+#line 1374 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str175, 0},
+#line 1372 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str176, 0},
+#line 675 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str177, 0},
+#line 865 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str178, 0},
+#line 559 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str179, 0},
+#line 2988 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str180, 0},
+#line 1827 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str181, 0},
+#line 2384 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str182, 0},
+#line 1853 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str183, 0},
+#line 2577 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str184, 0},
+#line 4133 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str185, 0},
+#line 3994 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str186, 0},
+#line 3993 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str187, 0},
+#line 3997 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str188, 0},
+#line 4000 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str189, 0},
+#line 1007 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str190, 0},
+#line 1006 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str191, 0},
+#line 1010 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str192, 0},
+#line 1952 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str193, 0},
+#line 1951 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str194, 0},
+#line 1013 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str195, 0},
+#line 644 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str196, 4},
+#line 1955 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str197, 0},
+#line 1311 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str198, 0},
+#line 1959 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str199, 0},
+#line 3886 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str200, 0},
+#line 1370 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str201, 0},
+#line 407 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str202, 0},
+#line 3065 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str203, 0},
+#line 2664 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str204, 2},
+#line 927 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str205, 0},
+#line 1359 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str206, 0},
+#line 1751 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str207, 0},
+#line 3933 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str208, 0},
+#line 1953 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str209, 0},
+#line 3996 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str210, 0},
+#line 1752 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str211, 0},
+#line 334 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str212, 0},
+#line 1890 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str213, 0},
+#line 1009 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str214, 0},
+#line 1956 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str215, 0},
+#line 6572 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str216, 2},
+#line 831 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str217, 0},
+#line 463 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str218, 0},
+#line 2924 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str219, 0},
+#line 1797 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str220, 0},
+#line 4031 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str221, 0},
+#line 2937 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str222, 0},
+#line 236 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str223, 0},
+#line 4066 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str224, 2},
+#line 1048 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str225, 0},
+#line 1987 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str226, 0},
+#line 1346 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str227, 0},
+#line 1345 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str228, 0},
+#line 1350 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str229, 0},
+#line 340 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str230, 0},
+#line 1352 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str231, 0},
+#line 1032 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str232, 0},
+#line 3845 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str233, 0},
+#line 3975 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str234, 0},
+#line 4144 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str235, 0},
+#line 1931 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str236, 0},
+#line 1929 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str237, 0},
+#line 3016 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str238, 0},
+#line 267 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str239, 0},
+#line 344 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str240, 0},
+#line 428 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str241, 0},
+#line 1768 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str242, 0},
+#line 1782 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str243, 0},
+#line 452 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str244, 0},
+#line 2872 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str245, 0},
+#line 1347 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str246, 0},
+#line 1468 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str247, 0},
+#line 374 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str248, 0},
+#line 3973 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str249, 0},
+#line 268 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str250, 0},
+#line 3921 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str251, 1},
+#line 1349 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str252, 0},
+#line 1927 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str253, 0},
+#line 3949 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str254, 0},
+#line 3976 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str255, 0},
+#line 3947 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str256, 0},
+#line 260 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str257, 0},
+#line 958 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str258, 0},
+#line 990 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str259, 0},
+#line 1904 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str260, 0},
+#line 956 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str261, 0},
+#line 1930 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str262, 0},
+#line 3875 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str263, 0},
+#line 1902 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str264, 0},
+#line 1165 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str265, 0},
+#line 760 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str266, 0},
+#line 4135 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str267, 0},
+#line 4164 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str268, 0},
+#line 2690 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str269, 0},
+#line 1383 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str270, 0},
+#line 1210 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str271, 0},
+#line 576 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str272, 0},
+#line 358 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str273, 0},
+#line 1089 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str274, 0},
+#line 427 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str275, 0},
+#line 1327 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str276, 0},
+#line 3956 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str277, 0},
+#line 2994 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str278, 2},
+#line 3977 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str279, 0},
+#line 967 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str280, 0},
+#line 4006 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str281, 0},
+#line 3948 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str282, 0},
+#line 1914 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str283, 0},
+#line 173 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str284, 0},
+#line 1020 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str285, 0},
+#line 957 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str286, 0},
+#line 1079 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str287, 0},
+#line 1964 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str288, 0},
+#line 1903 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str289, 0},
+#line 567 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str290, 0},
+#line 2674 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str291, 0},
+#line 659 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str292, 0},
+#line 3992 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str293, 0},
+#line 867 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str294, 0},
+#line 561 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str295, 2},
+#line 2991 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str296, 0},
+#line 1829 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str297, 0},
+#line 2394 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str298, 0},
+#line 1949 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str299, 0},
+#line 1461 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str300, 0},
+#line 1324 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str301, 0},
+#line 2462 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str302, 0},
+#line 1810 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str303, 0},
+#line 1300 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str304, 0},
+#line 1326 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str305, 0},
+#line 1298 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str306, 0},
+#line 3971 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str307, 0},
+#line 4005 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str308, 0},
+#line 2590 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str309, 0},
+#line 469 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str310, 0},
+#line 1019 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str311, 0},
+#line 1963 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str312, 0},
+#line 3847 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str313, 0},
+#line 2473 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str314, 0},
+#line 1758 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str315, 0},
+#line 356 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str316, 0},
+#line 1800 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str317, 0},
+#line 1307 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str318, 0},
+#line 2001 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str319, 0},
+#line 2487 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str320, 0},
+#line 930 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str321, 0},
+#line 1357 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str322, 0},
+#line 1299 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str323, 0},
+#line 4190 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str324, 0},
+#line 1161 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str325, 0},
+#line 118 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str326, 0},
+#line 1343 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str327, 0},
+#line 2486 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str328, 0},
+#line 4020 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str329, 0},
+#line 605 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str330, 0},
+#line 1475 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str331, 0},
+#line 1036 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str332, 0},
+#line 3943 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str333, 0},
+#line 1977 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str334, 0},
+#line 1926 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str335, 0},
+#line 951 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str336, 0},
+#line 1897 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str337, 0},
+#line 4032 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str338, 0},
+#line 4007 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str339, 0},
+#line 1049 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str340, 0},
+#line 1356 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str341, 0},
+#line 1989 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str342, 0},
+#line 1021 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str343, 0},
+#line 4146 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str344, 0},
+#line 3849 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str345, 0},
+#line 4141 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str346, 0},
+#line 277 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str347, 0},
+#line 274 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str348, 0},
+#line 2025 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str349, 0},
+#line 852 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str350, 0},
+#line 1816 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str351, 0},
+#line 2380 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str352, 2},
+#line 4116 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str353, 0},
+#line 3846 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str354, 0},
+#line 1115 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str355, 0},
+#line 1852 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str356, 0},
+#line 2463 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str357, 0},
+#line 84 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str358, 0},
+#line 86 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str359, 0},
+#line 3987 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str360, 0},
+#line 1130 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str361, 0},
+#line 632 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str362, 0},
+#line 3988 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str363, 0},
+#line 3986 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str364, 0},
+#line 1001 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str365, 0},
+#line 1261 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str366, 0},
+#line 2477 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str367, 0},
+#line 1943 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str368, 0},
+#line 1945 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str369, 0},
+#line 1002 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str370, 0},
+#line 1000 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str371, 0},
+#line 1944 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str372, 0},
+#line 1942 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str373, 0},
+#line 1818 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str374, 0},
+#line 1104 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str375, 0},
+#line 4153 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str376, 0},
+#line 1373 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str377, 0},
+#line 259 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str378, 0},
+#line 4040 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str379, 0},
+#line 1293 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str380, 0},
+#line 1058 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str381, 0},
+#line 2475 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str382, 0},
+#line 1995 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str383, 0},
+#line 2430 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str384, 0},
+#line 1384 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str385, 0},
+#line 1427 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str386, 0},
+#line 1358 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str387, 0},
+#line 650 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str388, 0},
+#line 1195 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str389, 0},
+#line 1023 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str390, 0},
+#line 655 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str391, 0},
+#line 2455 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str392, 0},
+#line 4043 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str393, 0},
+#line 194 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str394, 0},
+#line 3841 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str395, 0},
+#line 1061 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str396, 0},
+#line 1997 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str397, 0},
+#line 1198 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str398, 0},
+#line 1144 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str399, 0},
+#line 2390 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str400, 0},
+#line 1154 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str401, 0},
+#line 1339 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str402, 0},
+#line 1340 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str403, 0},
+#line 1338 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str404, 0},
+#line 643 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str405, 0},
+#line 379 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str406, 0},
+#line 2694 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str407, 0},
+#line 1745 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str408, 0},
+#line 14 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str409, 0},
+#line 21 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str410, 0},
+#line 16 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str411, 0},
+#line 2324 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str412, 0},
+#line 25 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str413, 0},
+#line 3779 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str414, 0},
+#line 24 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str415, 0},
+#line 23 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str416, 0},
+#line 20 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str417, 0},
+#line 19 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str418, 0},
+#line 18 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str419, 0},
+#line 1143 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str420, 0},
+#line 15 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str421, 0},
+#line 2490 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str422, 0},
+#line 1390 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str423, 0},
+#line 2440 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str424, 0},
+#line 121 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str425, 0},
+#line 232 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str426, 0},
+#line 2446 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str427, 0},
+#line 1426 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str428, 0},
+#line 4037 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str429, 0},
+#line 1360 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str430, 0},
+#line 3844 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str431, 0},
+#line 1263 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str432, 0},
+#line 1054 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str433, 0},
+#line 3934 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str434, 0},
+#line 1994 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str435, 0},
+#line 834 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str436, 0},
+#line 1392 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str437, 0},
+#line 941 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str438, 0},
+#line 3839 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str439, 0},
+#line 2640 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str440, 0},
+#line 2472 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str441, 0},
+#line 1891 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str442, 0},
+#line 1802 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str443, 0},
+#line 262 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str444, 0},
+#line 2442 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str445, 0},
+#line 3985 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str446, 0},
+#line 481 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str447, 0},
+#line 1767 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str448, 0},
+#line 999 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str449, 0},
+#line 1941 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str450, 0},
+#line 558 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str451, 0},
+#line 6143 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str452, 0},
+#line 125 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str453, 0},
+#line 6548 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str454, 0},
+#line 348 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str455, 0},
+#line 3972 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str456, 0},
+#line 987 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str457, 0},
+#line 2024 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str458, 0},
+#line 156 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str459, 0},
+#line 2419 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str460, 0},
+#line 3991 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str461, 0},
+#line 276 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str462, 0},
+#line 560 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str463, 0},
+#line 642 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str464, 0},
+#line 1948 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str465, 0},
+#line 2476 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str466, 0},
+#line 1388 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str467, 0},
+#line 4041 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str468, 0},
+#line 2672 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str469, 0},
+#line 1397 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str470, 0},
+#line 1286 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str471, 0},
+#line 3945 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str472, 0},
+#line 1059 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str473, 0},
+#line 1996 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str474, 0},
+#line 954 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str475, 0},
+#line 1900 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str476, 0},
+#line 1337 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str477, 0},
+#line 2007 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str478, 0},
+#line 1814 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str479, 0},
+#line 2434 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str480, 0},
+#line 2448 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str481, 0},
+#line 2435 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str482, 0},
+#line 438 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str483, 0},
+#line 676 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str484, 0},
+#line 2429 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str485, 0},
+#line 872 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str486, 0},
+#line 446 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str487, 0},
+#line 2468 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str488, 0},
+#line 1436 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str489, 0},
+#line 2300 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str490, 0},
+#line 3131 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str491, 0},
+#line 1476 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str492, 0},
+#line 1391 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str493, 0},
+#line 26 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str494, 0},
+#line 2447 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str495, 0},
+#line 1296 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str496, 0},
+#line 1871 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str497, 0},
+#line 456 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str498, 0},
+#line 4047 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str499, 0},
+#line 1203 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str500, 0},
+#line 661 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str501, 0},
+#line 850 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str502, 2},
+#line 4170 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str503, 0},
+#line 2305 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str504, 0},
+#line 3942 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str505, 0},
+#line 2444 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str506, 0},
+#line 950 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str507, 0},
+#line 38 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str508, 0},
+#line 1896 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str509, 0},
+#line 380 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str510, 0},
+#line 766 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str511, 0},
+#line 462 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str512, 0},
+#line 2914 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str513, 2},
+#line 1796 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str514, 0},
+#line 995 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str515, 0},
+#line 1937 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str516, 0},
+#line 443 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str517, 0},
+#line 3968 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str518, 0},
+#line 3970 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str519, 0},
+#line 2353 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str520, 0},
+#line 983 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str521, 0},
+#line 986 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str522, 0},
+#line 1925 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str523, 0},
+#line 985 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str524, 0},
+#line 3981 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str525, 0},
+#line 3062 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str526, 0},
+#line 250 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str527, 0},
+#line 2312 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str528, 0},
+#line 3876 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str529, 0},
+#line 1936 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str530, 0},
+#line 2161 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str531, 0},
+#line 682 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str532, 0},
+#line 1394 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str533, 0},
+#line 2427 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str534, 0},
+#line 3969 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str535, 0},
+#line 2310 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str536, 0},
+#line 772 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str537, 0},
+#line 984 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str538, 0},
+#line 2418 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str539, 0},
+#line 2285 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str540, 0},
+#line 1292 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str541, 0},
+#line 4069 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str542, 1},
+#line 1016 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str543, 0},
+#line 2142 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str544, 0},
+#line 2416 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str545, 0},
+#line 1898 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str546, 0},
+#line 1333 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str547, 0},
+#line 1850 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str548, 0},
+#line 2313 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str549, 0},
+#line 1321 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str550, 0},
+#line 1323 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str551, 0},
+#line 645 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str552, 0},
+#line 381 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str553, 0},
+#line 2695 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str554, 0},
+#line 1746 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str555, 0},
+#line 2326 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str556, 0},
+#line 871 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str557, 0},
+#line 3780 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str558, 0},
+#line 1332 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str559, 0},
+#line 2612 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str560, 0},
+#line 3929 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str561, 0},
+#line 4017 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str562, 0},
+#line 4070 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str563, 1},
+#line 168 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str564, 0},
+#line 2470 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str565, 0},
+#line 1031 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str566, 0},
+#line 2482 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str567, 0},
+#line 1973 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str568, 0},
+#line 1482 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str569, 0},
+#line 1322 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str570, 0},
+#line 1264 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str571, 0},
+#line 2443 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str572, 0},
+#line 1472 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str573, 0},
+#line 1435 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str574, 0},
+#line 4003 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str575, 0},
+#line 1017 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str576, 0},
+#line 2256 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str577, 0},
+#line 1141 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str578, 0},
+#line 6144 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str579, 0},
+#line 6549 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str580, 0},
+#line 2452 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str581, 0},
+#line 2478 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str582, 0},
+#line 3984 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str583, 0},
+#line 998 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str584, 0},
+#line 1940 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str585, 0},
+#line 341 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str586, 0},
+#line 1369 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str587, 0},
+#line 482 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str588, 0},
+#line 862 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str589, 0},
+#line 189 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str590, 0},
+#line 1132 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str591, 0},
+#line 634 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str592, 0},
+#line 3137 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str593, 2},
+#line 2065 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str594, 0},
+#line 2445 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str595, 0},
+#line 3848 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str596, 0},
+#line 323 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str597, 0},
+#line 3901 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str598, 0},
+#line 3960 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str599, 0},
+#line 4024 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str600, 0},
+#line 2248 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str601, 0},
+#line 972 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str602, 0},
+#line 3842 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str603, 0},
+#line 1919 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str604, 0},
+#line 1040 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str605, 0},
+#line 4068 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str606, 0},
+#line 1981 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str607, 0},
+#line 1336 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str608, 0},
+#line 3974 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str609, 0},
+#line 2456 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str610, 0},
+#line 989 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str611, 0},
+#line 1928 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str612, 0},
+#line 1065 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str613, 0},
+#line 1147 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str614, 0},
+#line 2450 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str615, 0},
+#line 3019 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str616, 0},
+#line 4044 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str617, 0},
+#line 2681 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str618, 0},
+#line 1062 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str619, 0},
+#line 28 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str620, 0},
+#line 6571 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str621, 0},
+#line 1485 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str622, 0},
+#line 1998 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str623, 0},
+#line 6579 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str624, 2},
+#line 1088 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str625, 0},
+#line 4067 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str626, 0},
+#line 2512 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str627, 4},
+#line 3838 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str628, 0},
+#line 2545 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str629, 4},
+#line 1312 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str630, 0},
+#line 1377 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str631, 0},
+#line 2325 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str632, 0},
+#line 2807 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str633, 0},
+#line 1325 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str634, 0},
+#line 4112 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str635, 0},
+#line 2439 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str636, 0},
+#line 3935 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str637, 0},
+#line 265 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str638, 0},
+#line 942 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str639, 0},
+#line 4134 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str640, 0},
+#line 418 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str641, 0},
+#line 1393 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str642, 0},
+#line 2258 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str643, 0},
+#line 441 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str644, 0},
+#line 2668 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str645, 0},
+#line 1196 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str646, 0},
+#line 994 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str647, 0},
+#line 251 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str648, 0},
+#line 1935 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str649, 0},
+#line 1445 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str650, 0},
+#line 2535 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str651, 4},
+#line 4139 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str652, 0},
+#line 608 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str653, 0},
+#line 365 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str654, 0},
+#line 2055 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str655, 0},
+#line 617 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str656, 0},
+#line 615 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str657, 0},
+#line 1055 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str658, 0},
+#line 4147 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str659, 0},
-#line 4430 "effective_tld_names.gperf"
+#line 301 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str660, 0},
-#line 3294 "effective_tld_names.gperf"
+#line 1481 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str661, 0},
 #line 864 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str662, 0},
-#line 4415 "effective_tld_names.gperf"
+#line 1331 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str663, 0},
-#line 2421 "effective_tld_names.gperf"
+#line 2608 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str664, 0},
-#line 38 "effective_tld_names.gperf"
+#line 1215 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str665, 0},
-#line 2460 "effective_tld_names.gperf"
+#line 2272 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str666, 0},
-#line 1068 "effective_tld_names.gperf"
+#line 1005 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str667, 0},
-#line 2586 "effective_tld_names.gperf"
+#line 1950 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str668, 0},
-#line 2650 "effective_tld_names.gperf"
+#line 4140 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str669, 0},
-#line 612 "effective_tld_names.gperf"
+#line 1142 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str670, 0},
-#line 4019 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str671, 0},
-#line 3247 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str672, 0},
-#line 3914 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str673, 0},
-#line 248 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str674, 0},
-#line 942 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str675, 0},
-#line 656 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str676, 0},
-#line 427 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str677, 0},
-#line 1878 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str678, 0},
-#line 1047 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str679, 0},
-#line 1424 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str680, 0},
-#line 892 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str681, 0},
-#line 2036 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str682, 0},
-#line 361 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str683, 0},
-#line 2251 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str684, 0},
-#line 4371 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str685, 0},
-#line 4373 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str686, 0},
-#line 4118 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str687, 0},
-#line 3889 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str688, 0},
-#line 2329 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str689, 0},
-#line 3882 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str690, 0},
-#line 890 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str691, 0},
-#line 913 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str692, 0},
-#line 4152 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str693, 0},
-#line 1469 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str694, 0},
-#line 2669 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str695, 0},
-#line 3051 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str696, 0},
-#line 2997 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str697, 0},
-#line 4510 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str698, 0},
-#line 867 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str699, 0},
-#line 166 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str700, 0},
-#line 4085 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str701, 0},
-#line 4390 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str702, 0},
-#line 262 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str703, 0},
-#line 869 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str704, 0},
-#line 4372 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str705, 0},
-#line 4377 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str706, 0},
-#line 678 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str707, 0},
-#line 2436 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str708, 0},
-#line 298 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str709, 0},
-#line 1464 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str710, 0},
-#line 4040 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str711, 1},
-#line 997 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str712, 0},
-#line 2659 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str713, 0},
-#line 1932 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str714, 0},
-#line 4358 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str715, 0},
-#line 4111 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str716, 0},
-#line 1267 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str717, 0},
-#line 907 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str718, 0},
-#line 1822 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str719, 0},
-#line 1281 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str720, 0},
-#line 4090 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str721, 1},
-#line 4443 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str722, 0},
-#line 5852 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str723, 0},
-#line 3244 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str724, 0},
-#line 3956 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str725, 0},
-#line 261 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str726, 0},
-#line 990 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str727, 0},
-#line 2785 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str728, 0},
-#line 4195 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str729, 0},
-#line 1922 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str730, 0},
-#line 1433 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str731, 0},
-#line 6094 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str732, 0},
-#line 3823 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str733, 0},
 #line 93 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str734, 0},
-#line 4041 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str735, 1},
-#line 2417 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str736, 0},
-#line 891 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str737, 0},
-#line 911 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str738, 0},
-#line 644 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str739, 0},
-#line 3050 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str740, 0},
-#line 1732 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str741, 0},
-#line 3922 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str742, 0},
-#line 2306 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str743, 0},
-#line 3176 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str744, 0},
-#line 2880 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str745, 0},
-#line 952 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str746, 0},
-#line 314 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str747, 0},
-#line 3264 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str748, 0},
-#line 1888 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str749, 0},
-#line 915 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str750, 0},
-#line 945 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str751, 0},
-#line 4450 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str752, 0},
-#line 4374 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str753, 0},
-#line 855 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str754, 0},
-#line 3976 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str755, 0},
-#line 506 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str756, 0},
-#line 485 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str757, 0},
-#line 1010 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str758, 0},
-#line 1944 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str759, 0},
-#line 4361 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str760, 0},
-#line 1333 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str761, 0},
-#line 6532 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str762, 0},
-#line 1407 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str763, 0},
-#line 6056 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str764, 0},
-#line 2434 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str765, 0},
-#line 3989 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str766, 0},
-#line 6527 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str767, 0},
-#line 4056 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str768, 0},
-#line 1023 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str769, 0},
-#line 904 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str770, 0},
-#line 3955 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str771, 0},
-#line 1115 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str772, 0},
-#line 1955 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str773, 0},
-#line 1854 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str774, 0},
-#line 989 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str775, 0},
-#line 2442 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str776, 0},
-#line 4435 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str777, 0},
-#line 1921 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str778, 0},
-#line 2250 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str779, 0},
-#line 2428 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str780, 0},
-#line 3952 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str781, 0},
-#line 4324 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str782, 0},
-#line 2523 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str783, 4},
-#line 4178 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str784, 0},
-#line 985 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str785, 0},
-#line 1916 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str786, 0},
-#line 3136 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str787, 0},
-#line 4339 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str788, 0},
-#line 1460 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str789, 0},
-#line 5789 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str790, 0},
-#line 870 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str791, 0},
-#line 3253 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str792, 0},
-#line 4334 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str793, 0},
-#line 1325 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str794, 0},
-#line 2576 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str795, 0},
-#line 473 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str796, 0},
-#line 4458 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str797, 0},
-#line 4397 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str798, 0},
-#line 893 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str799, 0},
-#line 1057 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str800, 0},
-#line 3874 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str801, 0},
-#line 909 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str802, 0},
-#line 1290 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str803, 0},
-#line 2033 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str804, 0},
-#line 1284 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str805, 0},
-#line 3164 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str806, 0},
-#line 2325 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str807, 0},
-#line 1344 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str808, 0},
-#line 914 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str809, 0},
-#line 315 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str810, 0},
-#line 905 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str811, 0},
-#line 302 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str812, 0},
-#line 1358 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str813, 0},
-#line 3951 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str814, 0},
-#line 2140 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str815, 0},
-#line 984 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str816, 0},
-#line 3132 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str817, 0},
-#line 1324 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str818, 0},
-#line 1915 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str819, 0},
-#line 3099 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str820, 0},
-#line 6064 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str821, 0},
-#line 277 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str822, 0},
-#line 1319 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str823, 0},
-#line 603 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str824, 0},
-#line 4333 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str825, 0},
-#line 1103 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str826, 0},
-#line 3038 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str827, 0},
-#line 4453 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str828, 0},
-#line 2089 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str829, 0},
-#line 6533 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str830, 0},
-#line 4083 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str831, 0},
-#line 874 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str832, 4},
-#line 3887 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str833, 0},
-#line 4038 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str834, 0},
-#line 4092 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str835, 0},
-#line 4411 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str836, 0},
-#line 2962 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str837, 0},
-#line 4174 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str838, 0},
-#line 910 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str839, 0},
-#line 4151 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str840, 0},
-#line 1823 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str841, 0},
-#line 4039 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str842, 0},
-#line 1405 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str843, 0},
-#line 1121 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str844, 4},
-#line 5889 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str845, 0},
-#line 898 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str846, 0},
-#line 2932 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str847, 0},
-#line 1122 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str848, 0},
-#line 908 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str849, 0},
-#line 627 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str850, 0},
-#line 877 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str851, 0},
-#line 1814 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str852, 0},
-#line 1318 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str853, 0},
-#line 4310 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str854, 0},
-#line 6085 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str855, 0},
-#line 4139 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str856, 0},
-#line 4521 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str857, 0},
-#line 1409 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str858, 0},
-#line 4340 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str859, 0},
-#line 4451 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str860, 0},
-#line 323 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str861, 0},
-#line 4318 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str862, 0},
-#line 2021 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str863, 0},
-#line 6087 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str864, 0},
-#line 1269 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str865, 0},
-#line 2380 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str866, 0},
-#line 4012 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str867, 0},
-#line 6049 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str868, 0},
-#line 4036 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str869, 0},
-#line 1050 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str870, 0},
-#line 4729 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str871, 0},
-#line 1977 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str872, 0},
-#line 5798 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str873, 0},
-#line 2967 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str874, 0},
-#line 2851 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str875, 0},
-#line 2872 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str876, 2},
-#line 1015 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str877, 0},
-#line 6082 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str878, 0},
-#line 4015 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str879, 0},
-#line 4156 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str880, 0},
-#line 902 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str881, 0},
-#line 2797 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str882, 0},
-#line 2429 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str883, 0},
-#line 3291 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str884, 0},
-#line 1053 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str885, 0},
-#line 1979 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str886, 0},
-#line 3885 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str887, 0},
-#line 1462 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str888, 0},
-#line 888 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str889, 0},
-#line 1819 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str890, 0},
-#line 237 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str891, 0},
-#line 2573 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str892, 4},
-#line 4181 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str893, 0},
-#line 638 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str894, 0},
-#line 375 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str895, 0},
-#line 2672 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str896, 0},
-#line 1728 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str897, 0},
-#line 14 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str898, 0},
-#line 21 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str899, 0},
-#line 16 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str900, 0},
-#line 2303 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str901, 0},
-#line 25 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str902, 0},
-#line 24 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str903, 0},
-#line 23 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str904, 0},
-#line 201 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str905, 0},
-#line 3752 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str906, 0},
-#line 4399 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str907, 0},
-#line 20 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str908, 0},
-#line 19 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str909, 0},
-#line 18 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str910, 0},
-#line 15 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str911, 0},
-#line 4157 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str912, 0},
-#line 6101 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str913, 0},
-#line 2537 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str914, 4},
-#line 857 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str915, 0},
-#line 1997 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str916, 0},
-#line 6505 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str917, 0},
-#line 4322 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str918, 0},
-#line 1446 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str919, 0},
-#line 6292 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str920, 0},
-#line 2447 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str921, 0},
-#line 1379 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str922, 0},
-#line 863 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str923, 0},
-#line 1252 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str924, 0},
-#line 4525 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str925, 0},
-#line 2379 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str926, 0},
-#line 3906 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str927, 0},
-#line 3312 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str928, 0},
-#line 4389 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str929, 0},
-#line 3768 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str930, 0},
-#line 933 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str931, 0},
-#line 4244 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str932, 0},
-#line 1349 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str933, 0},
-#line 1873 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str934, 0},
-#line 916 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str935, 0},
-#line 2618 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str936, 0},
-#line 1381 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str937, 0},
-#line 371 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str938, 0},
-#line 4163 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str939, 0},
-#line 683 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str940, 0},
-#line 4313 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str941, 0},
-#line 4350 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str942, 0},
-#line 4343 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str943, 0},
-#line 488 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str944, 0},
-#line 4412 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str945, 0},
-#line 875 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str946, 0},
-#line 1813 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str947, 0},
-#line 318 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str948, 0},
-#line 1756 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str949, 0},
-#line 6057 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str950, 0},
-#line 4426 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str951, 0},
-#line 2490 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str952, 4},
-#line 4388 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str953, 0},
-#line 4730 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str954, 0},
-#line 5810 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str955, 2},
-#line 2011 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str956, 0},
-#line 3261 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str957, 0},
-#line 500 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str958, 0},
-#line 4160 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str959, 0},
-#line 3025 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str960, 0},
-#line 4383 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str961, 0},
-#line 1268 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str962, 0},
-#line 2806 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str963, 0},
-#line 2360 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str964, 0},
-#line 4506 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str965, 0},
-#line 4126 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str966, 0},
-#line 6103 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str967, 0},
-#line 3128 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str968, 0},
-#line 1275 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str969, 0},
-#line 6526 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str970, 0},
-#line 4013 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str971, 0},
-#line 4317 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str972, 0},
-#line 1051 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str973, 0},
-#line 1978 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str974, 0},
-#line 844 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str975, 0},
-#line 613 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str976, 0},
-#line 637 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str977, 0},
-#line 1423 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str978, 0},
-#line 2663 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str979, 0},
-#line 3877 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str980, 0},
-#line 4081 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str981, 0},
-#line 2374 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str982, 0},
-#line 4144 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str983, 0},
-#line 393 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str984, 0},
-#line 442 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str985, 0},
-#line 4175 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str986, 4},
-#line 382 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str987, 0},
-#line 4382 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str988, 0},
-#line 670 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str989, 0},
-#line 3109 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str990, 0},
-#line 1059 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str991, 0},
-#line 6053 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str992, 0},
-#line 4289 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str993, 0},
-#line 2372 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str994, 0},
-#line 4725 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str995, 0},
-#line 1380 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str996, 0},
-#line 2513 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str997, 4},
-#line 5788 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str998, 0},
-#line 26 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str999, 0},
-#line 6054 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1000, 0},
-#line 3777 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1001, 0},
-#line 4312 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1002, 0},
-#line 6452 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1003, 2},
-#line 2984 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1004, 0},
-#line 6018 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1005, 0},
-#line 467 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1006, 0},
-#line 4227 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1007, 0},
-#line 4035 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1008, 0},
-#line 925 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1009, 0},
-#line 3879 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1010, 0},
-#line 3899 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1011, 0},
-#line 876 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1012, 0},
-#line 2459 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1013, 0},
-#line 3975 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1014, 0},
-#line 139 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1015, 0},
-#line 871 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1016, 0},
-#line 3023 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1017, 0},
-#line 1009 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1018, 0},
-#line 2150 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1019, 0},
-#line 497 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1020, 0},
-#line 2435 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1021, 0},
-#line 5823 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1022, 0},
-#line 619 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1023, 0},
-#line 906 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1024, 0},
-#line 1821 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1025, 0},
-#line 2328 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1026, 0},
-#line 4454 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1027, 0},
-#line 2377 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1028, 0},
-#line 886 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1029, 0},
-#line 3117 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1030, 0},
-#line 2456 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1031, 0},
-#line 4417 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1032, 0},
-#line 4173 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1033, 0},
-#line 2054 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1034, 0},
-#line 2560 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1035, 0},
-#line 4457 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1036, 0},
-#line 4483 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1037, 0},
-#line 3884 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1038, 0},
-#line 6387 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1039, 0},
-#line 887 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1040, 0},
-#line 2470 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1041, 0},
-#line 1818 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1042, 0},
-#line 2893 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1043, 0},
-#line 2230 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1044, 0},
-#line 157 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1045, 0},
-#line 2845 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1046, 0},
-#line 2290 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1047, 0},
-#line 1880 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1048, 0},
-#line 3184 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1049, 0},
-#line 2055 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1050, 0},
-#line 4091 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1051, 0},
-#line 1270 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1052, 0},
-#line 5887 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1053, 0},
-#line 5849 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1054, 0},
-#line 1864 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1055, 0},
-#line 1426 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1056, 0},
-#line 4088 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1057, 0},
-#line 2229 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1058, 0},
-#line 894 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1059, 0},
-#line 684 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1060, 0},
-#line 2590 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1061, 0},
-#line 199 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1062, 0},
-#line 6488 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1063, 0},
-#line 3040 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1064, 0},
-#line 4486 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1065, 0},
-#line 4332 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1066, 0},
-#line 3249 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1067, 0},
-#line 3118 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1068, 0},
-#line 2810 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1069, 0},
-#line 6096 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1070, 0},
-#line 1773 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1071, 4},
-#line 4482 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1072, 0},
-#line 5933 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1073, 0},
-#line 4023 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1074, 0},
-#line 1093 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1075, 0},
-#line 4321 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1076, 0},
-#line 2129 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1077, 0},
-#line 481 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1078, 0},
-#line 2923 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1079, 0},
-#line 6276 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1080, 0},
-#line 2254 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1081, 0},
-#line 4316 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1082, 0},
-#line 1987 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1083, 0},
-#line 6007 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1084, 0},
-#line 2613 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1085, 0},
-#line 4455 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1086, 0},
-#line 32 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1087, 0},
-#line 872 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1088, 0},
-#line 4127 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1089, 0},
-#line 2760 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1090, 0},
-#line 6225 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1091, 0},
-#line 1434 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1092, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str671, 0},
+#line 2691 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str672, 0},
+#line 2819 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str673, 0},
+#line 3850 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str674, 0},
 #line 2954 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1093, 0},
-#line 1860 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1094, 0},
-#line 836 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1095, 1},
-#line 5893 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1096, 0},
-#line 2805 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1097, 0},
-#line 2409 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1098, 4},
-#line 689 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1099, 0},
-#line 505 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1100, 1},
-#line 2786 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1101, 0},
-#line 3880 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1102, 0},
-#line 1431 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1103, 0},
-#line 82 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1104, 0},
-#line 2057 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1105, 0},
-#line 3892 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1106, 0},
-#line 3266 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1107, 0},
-#line 3927 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1108, 0},
-#line 1895 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1109, 0},
-#line 1890 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1110, 0},
-#line 4528 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1111, 0},
-#line 957 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1112, 0},
-#line 2310 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1113, 0},
-#line 880 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1114, 0},
-#line 1263 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1115, 0},
-#line 2934 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1116, 0},
-#line 4137 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1117, 0},
-#line 1827 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1118, 0},
-#line 39 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1119, 0},
-#line 2193 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1120, 0},
-#line 3924 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1121, 0},
-#line 2907 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1122, 0},
-#line 6005 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1123, 0},
-#line 954 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1124, 0},
-#line 1892 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1125, 0},
-#line 6046 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1126, 0},
-#line 327 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1127, 0},
-#line 648 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1128, 0},
-#line 404 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1129, 0},
-#line 5835 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1130, 0},
-#line 6014 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1131, 0},
-#line 2378 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1132, 0},
-#line 1793 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1133, 0},
-#line 3022 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1134, 0},
-#line 4014 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1135, 0},
-#line 4311 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1136, 0},
-#line 1052 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1137, 0},
-#line 1295 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1138, 0},
-#line 2641 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1139, 0},
-#line 1100 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1140, 0},
-#line 2904 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1141, 4},
-#line 245 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1142, 0},
-#line 673 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1143, 0},
-#line 3160 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1144, 0},
-#line 1786 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1145, 0},
-#line 837 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1146, 1},
-#line 5938 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1147, 0},
-#line 6204 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1148, 0},
-#line 1384 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1149, 0},
-#line 1292 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1150, 0},
-#line 3926 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1151, 0},
-#line 672 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1152, 0},
-#line 2656 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1153, 0},
-#line 956 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1154, 0},
-#line 1894 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1155, 0},
-#line 6510 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1156, 4},
-#line 4125 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1157, 0},
-#line 4720 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1158, 0},
-#line 1889 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1159, 0},
-#line 2520 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1160, 4},
-#line 3281 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1161, 0},
-#line 1743 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1162, 0},
-#line 1774 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1163, 4},
-#line 3831 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1164, 0},
-#line 903 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1165, 0},
-#line 2582 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1166, 0},
-#line 2976 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1167, 0},
-#line 610 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1168, 0},
-#line 3765 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1169, 0},
-#line 814 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1170, 0},
-#line 5963 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1171, 0},
-#line 2606 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1172, 0},
-#line 5939 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1173, 0},
-#line 5993 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1174, 0},
-#line 1294 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1175, 0},
-#line 41 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1176, 0},
-#line 2149 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1177, 0},
-#line 5931 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1178, 0},
-#line 1852 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1179, 0},
-#line 437 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1180, 0},
-#line 2238 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1181, 0},
-#line 89 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1182, 4},
-#line 6389 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1183, 0},
-#line 6022 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1184, 0},
-#line 172 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1185, 0},
-#line 3088 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1186, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str675, 0},
+#line 1444 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str676, 0},
+#line 1344 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str677, 0},
+#line 2395 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str678, 0},
+#line 1456 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str679, 0},
+#line 3904 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str680, 0},
+#line 1455 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str681, 0},
+#line 1824 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str682, 0},
+#line 2074 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str683, 0},
+#line 37 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str684, 0},
+#line 1811 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str685, 0},
+#line 386 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str686, 0},
 #line 317 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1187, 0},
-#line 5876 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1188, 0},
-#line 2557 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1189, 0},
-#line 1988 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1190, 0},
-#line 2817 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1191, 0},
-#line 451 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1192, 0},
-#line 6113 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1193, 0},
-#line 5956 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1194, 0},
-#line 2256 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1195, 0},
-#line 3298 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1196, 0},
-#line 6157 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1197, 0},
-#line 763 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1198, 0},
-#line 2128 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1199, 0},
-#line 130 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1200, 0},
-#line 94 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1201, 0},
-#line 6213 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1202, 0},
-#line 502 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1203, 0},
-#line 6010 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1204, 0},
-#line 651 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1205, 0},
-#line 823 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1206, 0},
-#line 2232 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1207, 0},
-#line 2253 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1208, 0},
-#line 4355 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1209, 0},
-#line 2327 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1210, 0},
-#line 5936 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1211, 0},
-#line 4171 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1212, 0},
-#line 4469 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1213, 0},
-#line 2905 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1214, 4},
-#line 5996 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1215, 0},
-#line 2192 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1216, 0},
-#line 4352 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1217, 0},
-#line 873 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1218, 0},
-#line 1058 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1219, 0},
-#line 685 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1220, 0},
-#line 2044 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1221, 0},
-#line 240 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1222, 0},
-#line 4229 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1223, 0},
-#line 2233 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1224, 0},
-#line 820 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1225, 0},
-#line 115 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1226, 0},
-#line 4522 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1227, 0},
-#line 80 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1228, 0},
-#line 2825 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1229, 0},
-#line 128 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1230, 0},
-#line 71 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1231, 0},
-#line 1802 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1232, 0},
-#line 2382 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1233, 0},
-#line 5890 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1234, 0},
-#line 4456 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1235, 0},
-#line 1265 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1236, 0},
-#line 3182 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1237, 0},
-#line 4122 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1238, 0},
-#line 1125 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1239, 0},
-#line 6019 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1240, 0},
-#line 77 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1241, 0},
-#line 1123 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1242, 0},
-#line 3106 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1243, 0},
-#line 6071 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1244, 0},
-#line 5900 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1245, 0},
-#line 2623 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1246, 0},
-#line 2754 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1247, 0},
-#line 2577 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1248, 0},
-#line 4354 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1249, 0},
-#line 2347 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1250, 0},
-#line 1395 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1251, 0},
-#line 3997 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1252, 0},
-#line 1033 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1253, 0},
-#line 1964 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1254, 0},
-#line 3981 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1255, 0},
-#line 856 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1256, 0},
-#line 6245 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1257, 0},
-#line 835 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1258, 1},
-#line 2532 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1259, 4},
-#line 6003 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1260, 0},
-#line 1016 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1261, 0},
-#line 1947 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1262, 0},
-#line 4100 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1263, 0},
-#line 6110 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1264, 0},
-#line 4242 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1265, 0},
-#line 5787 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1266, 0},
-#line 2982 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1267, 0},
-#line 2037 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1268, 0},
-#line 2245 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1269, 0},
-#line 4504 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1270, 0},
-#line 2045 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1271, 0},
-#line 3855 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1272, 0},
-#line 6017 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1273, 0},
-#line 239 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1274, 0},
-#line 3021 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1275, 0},
-#line 2787 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1276, 0},
-#line 3155 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1277, 0},
-#line 3108 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1278, 0},
-#line 2931 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1279, 0},
-#line 3808 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1280, 0},
-#line 6036 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1281, 0},
-#line 3007 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1282, 0},
-#line 152 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1283, 0},
-#line 1350 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1284, 0},
-#line 3314 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1285, 0},
-#line 2105 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1286, 0},
-#line 3313 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1287, 0},
-#line 328 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1288, 0},
-#line 5978 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1289, 0},
-#line 5848 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1290, 0},
-#line 3091 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1291, 0},
-#line 2862 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1292, 0},
-#line 4484 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1293, 0},
-#line 6327 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1294, 0},
-#line 2340 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1295, 0},
-#line 3104 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1296, 0},
-#line 2631 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1297, 0},
-#line 2406 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1298, 0},
-#line 4002 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1299, 0},
-#line 2266 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1300, 4},
-#line 1736 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1301, 0},
-#line 2381 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1302, 0},
-#line 665 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1303, 0},
-#line 5946 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1304, 0},
-#line 2936 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1305, 0},
-#line 3896 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1306, 0},
-#line 5799 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1307, 0},
-#line 162 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1308, 0},
-#line 2757 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1309, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str687, 0},
+#line 2828 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str688, 0},
+#line 3047 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str689, 0},
+#line 2469 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str690, 0},
+#line 1229 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str691, 0},
+#line 471 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str692, 0},
+#line 6495 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str693, 2},
+#line 1813 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str694, 0},
+#line 397 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str695, 0},
+#line 4151 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str696, 0},
+#line 684 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str697, 0},
+#line 4119 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str698, 1},
+#line 2433 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str699, 0},
+#line 1171 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str700, 0},
+#line 1434 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str701, 0},
+#line 4004 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str702, 0},
+#line 4168 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str703, 0},
+#line 1018 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str704, 0},
+#line 1962 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str705, 0},
+#line 447 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str706, 0},
+#line 511 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str707, 0},
+#line 1129 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str708, 4},
+#line 203 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str709, 0},
+#line 2559 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str710, 4},
+#line 319 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str711, 0},
+#line 3006 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str712, 0},
+#line 1134 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str713, 2},
+#line 635 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str714, 0},
+#line 3138 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str715, 0},
+#line 2068 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str716, 0},
+#line 1474 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str717, 0},
+#line 6531 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str718, 0},
+#line 1355 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str719, 0},
+#line 4155 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str720, 0},
+#line 318 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str721, 0},
+#line 2159 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str722, 0},
+#line 1859 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str723, 0},
+#line 2252 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str724, 0},
+#line 1223 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str725, 4},
+#line 671 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str726, 0},
+#line 6569 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str727, 0},
+#line 2271 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str728, 0},
+#line 3121 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str729, 0},
+#line 1872 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str730, 0},
+#line 2015 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str731, 0},
+#line 3795 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str732, 0},
+#line 3936 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str733, 0},
+#line 943 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str734, 0},
+#line 1753 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str735, 0},
+#line 1437 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str736, 0},
+#line 2451 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str737, 0},
+#line 618 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str738, 0},
+#line 2075 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str739, 0},
+#line 3958 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str740, 0},
+#line 969 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str741, 0},
+#line 1916 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str742, 0},
+#line 3045 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str743, 0},
+#line 6135 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str744, 0},
+#line 408 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str745, 0},
+#line 345 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str746, 0},
+#line 2108 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str747, 0},
+#line 2554 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str748, 4},
+#line 1217 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str749, 0},
+#line 320 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str750, 0},
+#line 604 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str751, 0},
+#line 553 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str752, 4},
+#line 6096 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str753, 0},
+#line 534 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str754, 4},
+#line 1139 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str755, 0},
+#line 1309 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str756, 0},
+#line 2457 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str757, 0},
+#line 4753 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str758, 0},
+#line 1118 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str759, 0},
+#line 1076 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str760, 0},
+#line 316 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str761, 0},
+#line 3941 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str762, 0},
+#line 2873 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str763, 0},
+#line 949 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str764, 0},
+#line 1895 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str765, 0},
+#line 513 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str766, 0},
+#line 2656 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str767, 0},
+#line 4156 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str768, 0},
+#line 597 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str769, 0},
+#line 271 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str770, 0},
+#line 6104 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str771, 0},
+#line 2926 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str772, 4},
 #line 653 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1310, 0},
-#line 2311 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1311, 0},
-#line 6297 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1312, 0},
-#line 2051 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1313, 0},
-#line 454 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1314, 4},
-#line 3031 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1315, 0},
-#line 363 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1316, 0},
-#line 4513 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1317, 0},
-#line 6058 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1318, 0},
-#line 3030 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1319, 0},
-#line 2287 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1320, 0},
-#line 1385 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1321, 0},
-#line 364 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1322, 0},
-#line 4276 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1323, 0},
-#line 3923 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1324, 0},
-#line 6473 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1325, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str773, 0},
+#line 4039 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str774, 0},
+#line 1291 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str775, 0},
+#line 1395 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str776, 0},
+#line 1057 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str777, 0},
+#line 2481 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str778, 0},
+#line 4110 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str779, 0},
+#line 2827 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str780, 0},
+#line 556 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str781, 4},
+#line 326 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str782, 0},
+#line 3979 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str783, 0},
+#line 992 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str784, 0},
+#line 551 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str785, 4},
+#line 1933 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str786, 0},
+#line 550 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str787, 4},
+#line 2647 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str788, 0},
 #line 953 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1326, 0},
-#line 288 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1327, 0},
-#line 2579 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1328, 0},
-#line 1838 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1329, 0},
-#line 1157 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1330, 0},
-#line 753 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1331, 0},
-#line 2655 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1332, 0},
-#line 1199 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1333, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str789, 0},
+#line 552 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str790, 4},
+#line 6126 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str791, 0},
+#line 685 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str792, 0},
+#line 2056 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str793, 0},
+#line 6128 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str794, 0},
+#line 486 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str795, 0},
+#line 2945 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str796, 0},
+#line 598 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str797, 4},
+#line 2976 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str798, 0},
+#line 6138 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str799, 0},
+#line 656 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str800, 0},
+#line 6123 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str801, 0},
+#line 4085 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str802, 0},
+#line 458 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str803, 4},
+#line 1329 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str804, 0},
+#line 2458 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str805, 0},
+#line 477 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str806, 0},
+#line 129 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str807, 0},
+#line 1295 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str808, 0},
+#line 444 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str809, 0},
+#line 2956 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str810, 0},
+#line 544 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str811, 4},
+#line 4158 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str812, 0},
+#line 264 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str813, 0},
+#line 4203 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str814, 0},
+#line 2542 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str815, 4},
+#line 1208 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str816, 4},
+#line 2630 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str817, 0},
+#line 1803 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str818, 0},
+#line 6097 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str819, 0},
+#line 2595 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str820, 4},
+#line 3950 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str821, 0},
+#line 960 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str822, 0},
+#line 193 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str823, 0},
+#line 1906 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str824, 0},
+#line 1201 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str825, 0},
+#line 6431 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str826, 0},
+#line 4787 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str827, 0},
+#line 4811 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str828, 0},
+#line 4880 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str829, 0},
+#line 2686 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str830, 0},
+#line 541 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str831, 4},
+#line 1066 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str832, 0},
+#line 4857 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str833, 0},
+#line 1446 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str834, 0},
+#line 321 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str835, 0},
+#line 933 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str836, 0},
+#line 4042 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str837, 0},
+#line 1060 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str838, 0},
+#line 518 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str839, 4},
+#line 1301 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str840, 0},
+#line 1416 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str841, 0},
+#line 546 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str842, 4},
+#line 247 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str843, 0},
+#line 311 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str844, 0},
+#line 1207 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str845, 4},
+#line 2431 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str846, 4},
+#line 568 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str847, 0},
+#line 821 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str848, 0},
+#line 6093 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str849, 0},
+#line 515 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str850, 4},
+#line 2216 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str851, 0},
+#line 132 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str852, 0},
+#line 1870 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str853, 0},
+#line 1133 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str854, 0},
+#line 543 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str855, 4},
+#line 92 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str856, 0},
+#line 2020 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str857, 0},
+#line 549 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str858, 4},
+#line 3843 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str859, 0},
+#line 4799 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str860, 0},
+#line 4025 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str861, 0},
+#line 1041 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str862, 0},
+#line 1982 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str863, 0},
+#line 2464 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str864, 0},
+#line 4761 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str865, 0},
+#line 2987 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str866, 0},
+#line 4009 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str867, 0},
+#line 1024 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str868, 0},
+#line 1965 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str869, 0},
+#line 2591 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str870, 0},
+#line 4882 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str871, 0},
+#line 3927 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str872, 0},
+#line 4154 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str873, 0},
+#line 241 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str874, 0},
+#line 2927 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str875, 4},
+#line 4810 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str876, 0},
+#line 4819 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str877, 0},
+#line 6094 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str878, 0},
+#line 2678 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str879, 0},
+#line 2635 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str880, 0},
+#line 2251 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str881, 0},
+#line 1177 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str882, 0},
+#line 658 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str883, 0},
+#line 4204 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str884, 4},
+#line 679 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str885, 0},
+#line 1361 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str886, 0},
+#line 514 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str887, 4},
+#line 1483 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str888, 0},
+#line 339 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str889, 0},
+#line 6137 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str890, 0},
+#line 4752 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str891, 0},
+#line 2008 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str892, 0},
+#line 4030 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str893, 0},
+#line 3804 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str894, 0},
+#line 519 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str895, 4},
+#line 4762 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str896, 0},
+#line 2212 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str897, 0},
+#line 2867 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str898, 0},
+#line 1799 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str899, 0},
+#line 6057 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str900, 0},
+#line 4864 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str901, 0},
+#line 6099 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str902, 0},
+#line 367 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str903, 0},
+#line 6076 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str904, 0},
+#line 2651 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str905, 0},
+#line 455 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str906, 0},
+#line 3858 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str907, 0},
+#line 368 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str908, 0},
+#line 6432 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str909, 0},
+#line 2808 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str910, 0},
+#line 1187 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str911, 0},
+#line 3980 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str912, 0},
+#line 4166 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str913, 0},
+#line 993 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str914, 0},
+#line 1934 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str915, 0},
+#line 4065 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str916, 0},
+#line 858 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str917, 4},
+#line 6113 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str918, 0},
+#line 2275 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str919, 0},
+#line 678 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str920, 0},
+#line 2393 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str921, 0},
+#line 4207 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str922, 0},
+#line 4779 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str923, 0},
+#line 3867 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str924, 0},
+#line 765 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str925, 0},
+#line 460 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str926, 0},
+#line 2912 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str927, 0},
+#line 1793 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str928, 0},
+#line 1063 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str929, 0},
+#line 4059 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str930, 0},
+#line 690 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str931, 0},
+#line 4817 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str932, 0},
+#line 1064 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str933, 0},
+#line 6133 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str934, 0},
+#line 2492 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str935, 0},
+#line 863 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str936, 0},
+#line 3966 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str937, 0},
+#line 3964 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str938, 0},
+#line 3965 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str939, 0},
+#line 4760 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str940, 0},
+#line 1406 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str941, 0},
+#line 981 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str942, 0},
+#line 979 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str943, 0},
+#line 980 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str944, 0},
+#line 1330 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str945, 0},
+#line 1924 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str946, 0},
+#line 2648 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str947, 0},
+#line 6098 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str948, 0},
+#line 1400 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str949, 0},
+#line 2693 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str950, 0},
+#line 164 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str951, 0},
+#line 3043 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str952, 0},
+#line 1849 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str953, 0},
+#line 3963 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str954, 0},
+#line 2832 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str955, 0},
+#line 3895 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str956, 0},
+#line 978 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str957, 0},
+#line 1923 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str958, 0},
+#line 542 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str959, 4},
+#line 94 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str960, 0},
+#line 1491 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str961, 0},
+#line 1170 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str962, 0},
+#line 1320 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str963, 0},
+#line 1318 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str964, 0},
+#line 1319 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str965, 0},
+#line 3983 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str966, 0},
+#line 997 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str967, 0},
+#line 1939 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str968, 0},
+#line 1113 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str969, 0},
+#line 3944 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str970, 0},
+#line 2441 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str971, 0},
+#line 952 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str972, 0},
+#line 1317 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str973, 0},
+#line 1899 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str974, 0},
+#line 1794 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str975, 0},
+#line 3792 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str976, 0},
+#line 761 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str977, 0},
+#line 1396 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str978, 0},
+#line 827 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str979, 0},
+#line 770 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str980, 0},
+#line 555 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str981, 4},
+#line 1335 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str982, 0},
+#line 535 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str983, 4},
+#line 101 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str984, 0},
+#line 331 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str985, 0},
+#line 2331 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str986, 0},
+#line 3961 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str987, 0},
+#line 1294 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str988, 0},
+#line 975 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str989, 0},
+#line 1920 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str990, 0},
+#line 1175 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str991, 0},
+#line 820 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str992, 0},
+#line 621 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str993, 0},
+#line 3840 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str994, 0},
+#line 1820 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str995, 0},
+#line 4767 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str996, 0},
+#line 6058 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str997, 0},
+#line 2917 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str998, 0},
+#line 6516 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str999, 0},
+#line 2404 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1000, 0},
+#line 2250 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1001, 0},
+#line 4856 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1002, 0},
+#line 1314 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1003, 0},
+#line 4764 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1004, 0},
+#line 4860 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1005, 0},
+#line 1067 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1006, 0},
+#line 548 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1007, 4},
+#line 6095 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1008, 0},
+#line 2491 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1009, 0},
+#line 3110 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1010, 0},
+#line 332 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1011, 0},
+#line 114 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1012, 0},
+#line 178 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1013, 0},
+#line 545 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1014, 4},
+#line 3920 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1015, 0},
+#line 3113 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1016, 0},
+#line 4863 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1017, 0},
+#line 4842 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1018, 0},
+#line 691 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1019, 0},
+#line 2944 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1020, 0},
+#line 4815 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1021, 0},
+#line 2211 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1022, 0},
+#line 2782 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1023, 0},
+#line 540 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1024, 4},
+#line 1127 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1025, 0},
+#line 1878 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1026, 0},
+#line 6086 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1027, 0},
+#line 4060 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1028, 0},
+#line 2601 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1029, 0},
+#line 487 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1030, 0},
+#line 1787 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1031, 0},
+#line 4063 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1032, 0},
+#line 2006 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1033, 0},
+#line 184 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1034, 0},
+#line 485 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1035, 0},
+#line 39 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1036, 0},
+#line 4825 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1037, 0},
+#line 4075 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1038, 0},
+#line 410 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1039, 0},
+#line 3044 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1040, 0},
+#line 4793 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1041, 0},
+#line 680 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1042, 0},
+#line 4173 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1043, 0},
+#line 1075 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1044, 0},
+#line 3025 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1045, 0},
+#line 1795 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1046, 0},
+#line 6575 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1047, 0},
+#line 154 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1048, 0},
+#line 1791 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1049, 4},
+#line 670 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1050, 0},
+#line 2274 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1051, 0},
+#line 557 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1052, 4},
+#line 4816 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1053, 0},
+#line 1830 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1054, 0},
+#line 756 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1055, 4},
+#line 349 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1056, 0},
+#line 2383 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1057, 0},
+#line 109 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1058, 0},
+#line 2583 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1059, 0},
+#line 2847 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1060, 0},
+#line 1760 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1061, 0},
+#line 394 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1062, 0},
+#line 4805 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1063, 0},
+#line 1419 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1064, 0},
+#line 2417 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1065, 0},
+#line 188 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1066, 0},
+#line 2839 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1067, 0},
+#line 2953 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1068, 0},
+#line 4765 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1069, 0},
+#line 2776 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1070, 0},
+#line 616 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1071, 0},
 #line 571 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1334, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1072, 0},
+#line 160 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1073, 0},
+#line 2523 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1074, 4},
+#line 4854 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1075, 0},
+#line 1083 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1076, 0},
+#line 385 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1077, 0},
+#line 473 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1078, 0},
+#line 4784 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1079, 0},
+#line 1119 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1080, 0},
+#line 2582 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1081, 0},
+#line 1411 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1082, 0},
+#line 4809 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1083, 0},
+#line 773 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1084, 0},
+#line 2109 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1085, 0},
+#line 2449 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1086, 0},
+#line 2995 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1087, 0},
+#line 2361 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1088, 0},
+#line 4874 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1089, 0},
+#line 4889 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1090, 0},
+#line 2010 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1091, 0},
+#line 1765 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1092, 0},
+#line 4806 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1093, 0},
+#line 1443 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1094, 0},
+#line 688 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1095, 0},
+#line 6478 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1096, 0},
+#line 2611 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1097, 0},
+#line 932 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1098, 0},
+#line 4807 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1099, 0},
+#line 186 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1100, 0},
+#line 4821 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1101, 0},
+#line 2958 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1102, 0},
+#line 2405 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1103, 0},
+#line 6568 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1104, 0},
+#line 4818 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1105, 0},
+#line 2653 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1106, 0},
+#line 692 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1107, 0},
+#line 4129 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1108, 0},
+#line 6438 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1109, 0},
+#line 1473 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1110, 0},
+#line 313 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1111, 0},
+#line 5891 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1112, 0},
+#line 4814 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1113, 0},
+#line 6480 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1114, 0},
+#line 2599 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1115, 0},
+#line 3135 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1116, 0},
+#line 1078 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1117, 0},
+#line 683 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1118, 0},
+#line 931 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1119, 0},
+#line 636 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1120, 0},
+#line 2239 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1121, 0},
+#line 2941 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1122, 0},
+#line 2432 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1123, 0},
+#line 1174 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1124, 0},
+#line 2403 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1125, 0},
+#line 1186 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1126, 0},
+#line 4820 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1127, 0},
+#line 1211 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1128, 4},
+#line 2581 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1129, 0},
+#line 3924 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1130, 0},
+#line 669 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1131, 0},
+#line 353 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1132, 0},
+#line 1181 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1133, 0},
+#line 835 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1134, 0},
+#line 1267 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1135, 0},
+#line 2230 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1136, 0},
+#line 5827 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1137, 0},
+#line 763 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1138, 0},
+#line 4061 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1139, 0},
+#line 2387 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1140, 0},
+#line 1101 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1141, 0},
+#line 4199 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1142, 0},
+#line 2809 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1143, 0},
+#line 1790 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1144, 4},
+#line 2332 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1145, 0},
+#line 4159 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1146, 0},
+#line 2998 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1147, 0},
+#line 4072 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1148, 0},
+#line 165 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1149, 0},
+#line 2783 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1150, 0},
+#line 346 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1151, 0},
+#line 1245 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1152, 4},
+#line 4855 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1153, 0},
+#line 3835 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1154, 0},
+#line 5928 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1155, 0},
+#line 2333 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1156, 0},
+#line 539 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1157, 4},
+#line 2368 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1158, 0},
+#line 291 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1159, 0},
+#line 2779 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1160, 0},
+#line 191 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1161, 0},
+#line 1233 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1162, 0},
+#line 4812 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1163, 0},
+#line 693 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1164, 0},
+#line 2579 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1165, 0},
+#line 2501 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1166, 4},
+#line 3962 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1167, 0},
+#line 242 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1168, 0},
+#line 1409 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1169, 0},
+#line 4795 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1170, 0},
+#line 3052 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1171, 0},
+#line 819 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1172, 0},
+#line 2124 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1173, 0},
+#line 934 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1174, 0},
+#line 1856 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1175, 0},
+#line 4885 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1176, 0},
+#line 6081 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1177, 0},
+#line 2308 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1178, 0},
+#line 2679 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1179, 0},
+#line 4150 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1180, 0},
+#line 1102 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1181, 0},
+#line 2273 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1182, 0},
+#line 197 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1183, 0},
+#line 1188 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1184, 0},
+#line 3004 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1185, 0},
+#line 244 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1186, 0},
+#line 2576 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1187, 0},
+#line 2287 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1188, 4},
+#line 360 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1189, 0},
+#line 1084 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1190, 0},
+#line 2560 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1191, 4},
+#line 2220 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1192, 0},
+#line 774 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1193, 0},
+#line 2951 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1194, 0},
+#line 1877 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1195, 0},
+#line 654 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1196, 0},
+#line 595 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1197, 0},
+#line 6127 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1198, 0},
+#line 2811 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1199, 0},
+#line 507 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1200, 0},
+#line 5861 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1201, 0},
+#line 2966 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1202, 0},
+#line 3893 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1203, 0},
+#line 6463 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1204, 0},
+#line 5888 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1205, 0},
+#line 1197 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1206, 0},
+#line 854 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1207, 0},
+#line 2781 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1208, 0},
+#line 294 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1209, 0},
+#line 2784 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1210, 0},
+#line 376 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1211, 0},
+#line 5825 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1212, 0},
+#line 1212 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1213, 4},
+#line 2437 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1214, 0},
+#line 799 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1215, 0},
+#line 185 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1216, 0},
+#line 4831 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1217, 0},
 #line 1081 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1218, 0},
+#line 3832 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1219, 0},
+#line 777 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1220, 0},
+#line 2128 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1221, 0},
+#line 2099 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1222, 0},
+#line 424 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1223, 0},
+#line 1224 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1224, 4},
+#line 1193 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1225, 0},
+#line 1283 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1226, 0},
+#line 3067 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1227, 0},
+#line 2379 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1228, 0},
+#line 412 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1229, 0},
+#line 977 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1230, 0},
+#line 1922 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1231, 0},
+#line 4791 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1232, 0},
+#line 3101 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1233, 0},
+#line 2649 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1234, 0},
+#line 5873 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1235, 0},
+#line 105 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1236, 0},
+#line 3068 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1237, 0},
+#line 1812 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1238, 0},
+#line 3098 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1239, 0},
+#line 243 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1240, 0},
+#line 1756 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1241, 4},
+#line 5848 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1242, 2},
+#line 1316 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1243, 0},
+#line 2278 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1244, 4},
+#line 512 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1245, 0},
+#line 2759 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1246, 0},
+#line 776 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1247, 0},
+#line 1779 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1248, 0},
+#line 4126 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1249, 0},
+#line 1494 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1250, 0},
+#line 413 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1251, 0},
+#line 435 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1252, 0},
+#line 466 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1253, 0},
+#line 6562 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1254, 0},
+#line 1158 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1255, 0},
+#line 769 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1256, 0},
+#line 6561 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1257, 0},
+#line 2113 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1258, 0},
+#line 1451 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1259, 0},
+#line 2276 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1260, 4},
+#line 775 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1261, 0},
+#line 5826 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1262, 0},
+#line 547 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1263, 4},
+#line 6574 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1264, 0},
+#line 4194 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1265, 0},
+#line 782 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1266, 0},
+#line 602 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1267, 0},
+#line 2141 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1268, 0},
+#line 554 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1269, 4},
+#line 3005 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1270, 0},
+#line 292 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1271, 0},
+#line 2238 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1272, 0},
+#line 198 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1273, 0},
+#line 3433 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1274, 0},
+#line 3727 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1275, 0},
+#line 3470 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1276, 0},
+#line 3430 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1277, 0},
+#line 2853 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1278, 0},
+#line 3656 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1279, 0},
+#line 2753 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1280, 0},
+#line 3720 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1281, 0},
+#line 3791 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1282, 0},
+#line 3678 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1283, 0},
+#line 3721 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1284, 0},
+#line 1046 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1285, 0},
+#line 2706 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1286, 0},
+#line 2422 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1287, 0},
+#line 1869 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1288, 0},
+#line 322 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1289, 0},
+#line 1855 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1290, 0},
+#line 3460 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1291, 0},
+#line 2676 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1292, 0},
+#line 2677 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1293, 0},
+#line 248 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1294, 0},
+#line 3049 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1295, 0},
+#line 2072 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1296, 0},
+#line 592 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1297, 0},
+#line 3703 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1298, 0},
+#line 6489 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1299, 0},
+#line 433 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1300, 0},
+#line 187 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1301, 0},
+#line 2916 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1302, 0},
+#line 637 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1303, 0},
+#line 335 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1304, 4},
+#line 1205 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1305, 4},
+#line 1381 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1306, 0},
+#line 538 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1307, 4},
+#line 3344 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1308, 0},
+#line 2330 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1309, 0},
+#line 1452 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1310, 0},
+#line 6526 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1311, 0},
+#line 3732 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1312, 0},
+#line 3468 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1313, 0},
+#line 3724 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1314, 0},
+#line 2388 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1315, 0},
+#line 628 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1316, 0},
+#line 3438 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1317, 0},
+#line 6106 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1318, 0},
+#line 2846 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1319, 0},
+#line 2214 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1320, 0},
+#line 3786 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1321, 0},
+#line 3444 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1322, 0},
+#line 2852 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1323, 0},
+#line 3735 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1324, 0},
+#line 3672 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1325, 0},
+#line 3778 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1326, 2},
+#line 3069 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1327, 0},
+#line 3007 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1328, 0},
+#line 2757 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1329, 0},
+#line 2999 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1330, 0},
+#line 2321 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1331, 0},
+#line 2974 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1332, 0},
+#line 1247 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1333, 4},
+#line 3018 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1334, 0},
+#line 3017 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1335, 0},
-#line 3928 "effective_tld_names.gperf"
+#line 2950 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1336, 0},
-#line 1184 "effective_tld_names.gperf"
+#line 2070 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1337, 0},
-#line 959 "effective_tld_names.gperf"
+#line 2673 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1338, 0},
-#line 1896 "effective_tld_names.gperf"
+#line 3857 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1339, 0},
-#line 599 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1340, 0},
-#line 3978 "effective_tld_names.gperf"
+#line 3652 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1340, 2},
+#line 1423 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1341, 0},
-#line 749 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1342, 4},
-#line 2919 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1343, 0},
+#line 3999 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1342, 0},
+#line 1209 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1343, 4},
 #line 1012 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1344, 0},
-#line 1946 "effective_tld_names.gperf"
+#line 1958 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1345, 0},
-#line 1055 "effective_tld_names.gperf"
+#line 3447 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1346, 0},
-#line 2604 "effective_tld_names.gperf"
+#line 3034 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1347, 0},
-#line 768 "effective_tld_names.gperf"
+#line 2850 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1348, 0},
-#line 2626 "effective_tld_names.gperf"
+#line 4056 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str1349, 0},
-#line 2985 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1350, 0},
-#line 1056 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1351, 0},
-#line 2561 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1352, 0},
-#line 686 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1353, 0},
-#line 4027 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1354, 0},
-#line 3868 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1355, 0},
-#line 1291 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1356, 0},
-#line 2469 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1357, 0},
-#line 5796 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1358, 0},
-#line 2929 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1359, 0},
-#line 150 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1360, 0},
-#line 1296 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1361, 0},
-#line 6055 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1362, 0},
-#line 2860 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1363, 0},
-#line 1346 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1364, 0},
-#line 429 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1365, 0},
-#line 1153 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1366, 0},
-#line 4436 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1367, 0},
-#line 2210 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1368, 0},
-#line 182 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1369, 0},
-#line 6100 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1370, 0},
-#line 2824 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1371, 0},
-#line 4418 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1372, 0},
-#line 1478 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1373, 0},
-#line 4097 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1374, 0},
-#line 2922 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1375, 0},
-#line 2761 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1376, 0},
-#line 176 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1377, 0},
-#line 3301 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1378, 0},
-#line 847 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1379, 0},
-#line 6324 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1380, 0},
-#line 4724 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1381, 0},
-#line 3916 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1382, 0},
-#line 4129 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1383, 0},
-#line 944 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1384, 0},
-#line 4459 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1385, 0},
-#line 1881 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1386, 0},
-#line 4004 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1387, 0},
-#line 268 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1388, 0},
-#line 5838 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1389, 0},
-#line 1041 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1390, 0},
-#line 1971 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1391, 0},
-#line 5910 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1392, 0},
-#line 4117 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1393, 0},
-#line 6274 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1394, 0},
-#line 3316 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1395, 0},
-#line 2956 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1396, 0},
-#line 756 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1397, 0},
-#line 1400 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1398, 0},
-#line 1812 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1399, 0},
-#line 5944 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1400, 0},
-#line 6333 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1401, 0},
-#line 3045 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1402, 0},
-#line 1096 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1403, 0},
-#line 1250 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1404, 0},
-#line 2983 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1405, 0},
-#line 2127 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1406, 0},
-#line 1283 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1407, 0},
-#line 813 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1408, 0},
-#line 2625 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1409, 0},
-#line 1373 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1410, 0},
-#line 5966 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1411, 0},
-#line 3813 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1412, 0},
-#line 1187 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1413, 0},
-#line 5896 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1414, 0},
-#line 5918 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1415, 0},
-#line 889 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1416, 0},
-#line 1867 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1417, 0},
-#line 1136 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1418, 0},
-#line 1146 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1419, 0},
-#line 2300 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1420, 0},
-#line 3881 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1421, 0},
-#line 5969 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1422, 0},
-#line 677 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1423, 0},
-#line 4472 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1424, 0},
-#line 406 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1425, 0},
-#line 3805 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1426, 0},
-#line 1135 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1427, 0},
-#line 2847 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1428, 0},
-#line 6013 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1429, 0},
-#line 3046 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1430, 0},
-#line 2383 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1431, 0},
-#line 5830 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1432, 0},
-#line 3817 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1433, 0},
-#line 2444 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1434, 0},
-#line 5916 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1435, 0},
-#line 758 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1436, 0},
-#line 456 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1437, 0},
-#line 2890 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1438, 0},
-#line 1776 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1439, 0},
-#line 4031 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1440, 0},
-#line 440 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1441, 0},
-#line 4351 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1442, 0},
-#line 2554 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1443, 0},
-#line 6086 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1444, 0},
-#line 3944 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1445, 0},
-#line 3938 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1446, 0},
-#line 3936 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1447, 0},
-#line 6451 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1448, 0},
-#line 3937 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1449, 0},
-#line 979 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1450, 0},
-#line 973 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1451, 0},
-#line 971 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1452, 0},
-#line 879 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1453, 0},
-#line 972 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1454, 0},
-#line 3105 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1455, 0},
-#line 1906 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1456, 0},
-#line 462 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1457, 0},
-#line 920 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1458, 4},
-#line 6388 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1459, 0},
-#line 1389 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1460, 0},
-#line 4356 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1461, 0},
-#line 2664 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1462, 0},
-#line 5859 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1463, 4},
-#line 2944 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1464, 0},
-#line 1831 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1465, 0},
-#line 184 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1466, 0},
-#line 4414 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1467, 0},
-#line 3935 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1468, 0},
-#line 1192 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1469, 0},
-#line 291 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1470, 0},
-#line 970 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1471, 0},
-#line 5986 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1472, 0},
-#line 1905 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1473, 0},
-#line 4278 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1474, 0},
-#line 3783 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1475, 0},
-#line 4755 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1476, 0},
-#line 4776 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1477, 0},
-#line 6377 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1478, 0},
-#line 4822 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1479, 0},
-#line 4201 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1480, 0},
-#line 4845 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1481, 0},
-#line 3917 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1482, 0},
-#line 2635 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1483, 0},
-#line 946 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1484, 0},
-#line 1882 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1485, 0},
-#line 1309 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1486, 0},
-#line 586 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1487, 0},
-#line 1307 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1488, 0},
-#line 3143 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1489, 4},
-#line 1308 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1490, 0},
-#line 1989 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1491, 0},
-#line 762 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1492, 0},
-#line 2627 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1493, 0},
-#line 4046 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1494, 0},
-#line 1185 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1495, 0},
-#line 6265 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1496, 0},
-#line 766 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1497, 0},
-#line 4460 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1498, 0},
-#line 2509 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1499, 4},
-#line 986 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1500, 0},
-#line 1917 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1501, 0},
-#line 1306 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1502, 0},
-#line 4110 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1503, 0},
-#line 561 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1504, 0},
-#line 3866 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1505, 0},
-#line 2952 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1506, 0},
-#line 5861 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1507, 0},
-#line 56 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1508, 0},
-#line 2867 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1509, 0},
-#line 5965 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1510, 0},
-#line 64 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1511, 0},
-#line 349 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1512, 0},
-#line 6306 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1513, 0},
-#line 310 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1514, 0},
-#line 6355 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1515, 0},
-#line 1777 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1516, 0},
-#line 2831 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1517, 0},
-#line 4342 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1518, 0},
-#line 2671 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1519, 0},
-#line 1285 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1520, 0},
-#line 42 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1521, 0},
-#line 5941 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1522, 0},
-#line 3141 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1523, 0},
-#line 4445 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1524, 0},
-#line 803 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1525, 0},
-#line 6243 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1526, 0},
-#line 381 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1527, 0},
-#line 425 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1528, 0},
-#line 1754 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1529, 0},
-#line 1079 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1530, 0},
-#line 6118 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1531, 0},
-#line 3933 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1532, 0},
-#line 1320 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1533, 0},
-#line 6126 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1534, 0},
-#line 2486 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1535, 4},
-#line 967 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1536, 0},
-#line 2895 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1537, 0},
-#line 1902 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1538, 0},
-#line 5892 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1539, 0},
-#line 67 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1540, 0},
-#line 100 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1541, 0},
-#line 1134 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1542, 0},
-#line 335 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1543, 0},
-#line 4767 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1544, 0},
-#line 3003 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1545, 0},
-#line 4170 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1546, 0},
-#line 1408 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1547, 0},
-#line 1067 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1548, 0},
-#line 2524 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1549, 4},
-#line 55 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1550, 0},
-#line 5994 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1551, 0},
-#line 4466 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1552, 0},
-#line 771 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1553, 0},
-#line 2430 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1554, 0},
-#line 6041 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1555, 0},
-#line 4847 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1556, 0},
-#line 6437 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1557, 0},
-#line 3113 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1558, 0},
-#line 611 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1559, 0},
-#line 5801 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1560, 0},
-#line 4043 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1561, 0},
-#line 6395 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1562, 0},
-#line 1303 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1563, 0},
-#line 1080 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1564, 0},
-#line 6373 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1565, 0},
-#line 4285 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1566, 0},
-#line 2094 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1567, 0},
-#line 2857 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1568, 0},
-#line 2362 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1569, 0},
-#line 4784 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1570, 0},
-#line 3177 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1571, 0},
-#line 43 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1572, 0},
-#line 4775 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1573, 0},
-#line 6454 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1574, 0},
-#line 2569 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1575, 0},
-#line 3815 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1576, 0},
-#line 113 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1577, 0},
-#line 6286 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1578, 0},
-#line 57 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1579, 0},
-#line 2219 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1580, 0},
-#line 5903 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1581, 0},
-#line 3890 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1582, 4},
-#line 366 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1583, 0},
-#line 4375 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1584, 0},
-#line 4370 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1585, 0},
-#line 4368 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1586, 0},
-#line 616 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1587, 0},
-#line 189 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1588, 0},
-#line 4369 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1589, 0},
-#line 2928 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1590, 0},
-#line 65 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1591, 0},
-#line 186 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1592, 0},
-#line 1782 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1593, 0},
-#line 792 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1594, 0},
-#line 2200 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1595, 0},
-#line 2735 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1596, 0},
-#line 2654 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1597, 0},
-#line 4367 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1598, 0},
-#line 6097 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1599, 0},
-#line 3080 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1600, 0},
-#line 881 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1601, 0},
-#line 1816 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1602, 0},
-#line 4155 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1603, 0},
-#line 477 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1604, 0},
-#line 4829 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1605, 0},
-#line 6023 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1606, 0},
-#line 68 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1607, 0},
-#line 390 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1608, 0},
-#line 1865 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1609, 0},
-#line 2113 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1610, 0},
-#line 674 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1611, 0},
-#line 4344 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1612, 0},
-#line 3256 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1613, 0},
-#line 417 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1614, 0},
-#line 4099 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1615, 0},
-#line 6115 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1616, 0},
-#line 337 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1617, 0},
-#line 6455 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1618, 0},
-#line 6228 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1619, 0},
-#line 6109 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1620, 0},
-#line 4747 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1621, 0},
-#line 2526 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1622, 4},
-#line 47 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1623, 0},
-#line 187 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1624, 0},
-#line 4782 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1625, 0},
-#line 4384 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1626, 0},
-#line 1070 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1627, 0},
-#line 4790 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1628, 0},
-#line 480 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1629, 0},
-#line 2309 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1630, 0},
-#line 754 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1631, 0},
-#line 2218 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1632, 0},
-#line 507 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1633, 0},
-#line 6233 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1634, 0},
-#line 2367 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1635, 0},
-#line 185 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1636, 0},
-#line 3248 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1637, 0},
-#line 2090 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1638, 0},
-#line 5920 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1639, 0},
-#line 6117 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1640, 0},
-#line 2395 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1641, 0},
-#line 316 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1642, 0},
-#line 2742 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1643, 0},
-#line 6107 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1644, 0},
-#line 61 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1645, 0},
-#line 3068 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1646, 0},
-#line 6384 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1647, 0},
-#line 4120 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1648, 0},
-#line 2885 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1649, 0},
-#line 4165 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1650, 0},
-#line 54 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1651, 0},
-#line 748 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1652, 0},
-#line 1761 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1653, 0},
-#line 289 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1654, 0},
-#line 6242 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1655, 0},
-#line 5917 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1656, 0},
-#line 4314 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1657, 0},
-#line 885 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1658, 0},
-#line 559 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1659, 0},
-#line 1817 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1660, 0},
-#line 2326 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1661, 0},
-#line 1112 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1662, 0},
-#line 606 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1663, 0},
-#line 4274 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1664, 0},
-#line 4781 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1665, 0},
-#line 4096 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1666, 0},
-#line 2549 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1667, 0},
-#line 6339 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1668, 0},
-#line 3811 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1669, 0},
-#line 4363 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1670, 0},
-#line 884 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1671, 0},
-#line 1778 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1672, 0},
-#line 2410 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1673, 0},
-#line 2119 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1674, 0},
-#line 924 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1675, 0},
-#line 1119 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1676, 0},
-#line 2830 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1677, 0},
-#line 2252 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1678, 0},
-#line 4520 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1679, 0},
-#line 4477 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1680, 0},
-#line 2900 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1681, 0},
-#line 4134 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1682, 0},
-#line 482 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1683, 0},
-#line 566 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1684, 0},
-#line 2195 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1685, 0},
-#line 2759 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1686, 0},
-#line 2501 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1687, 4},
-#line 1794 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1688, 0},
-#line 5915 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1689, 0},
-#line 70 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1690, 0},
-#line 6404 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1691, 0},
-#line 2505 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1692, 4},
-#line 1851 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1693, 0},
-#line 4733 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1694, 0},
-#line 1139 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1695, 0},
-#line 4252 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1696, 0},
-#line 334 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1697, 4},
-#line 45 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1698, 0},
-#line 108 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1699, 0},
-#line 3272 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1700, 0},
-#line 2427 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1701, 0},
-#line 4301 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1702, 0},
-#line 563 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1703, 0},
-#line 642 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1704, 0},
-#line 380 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1705, 0},
-#line 4130 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1706, 0},
-#line 802 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1707, 0},
-#line 46 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1708, 0},
-#line 3755 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1709, 0},
-#line 812 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1710, 0},
-#line 4821 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1711, 0},
-#line 6290 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1712, 0},
-#line 3162 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1713, 0},
-#line 882 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1714, 0},
-#line 2937 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1715, 0},
-#line 313 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1716, 0},
-#line 5512 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1717, 0},
-#line 1159 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1718, 0},
-#line 772 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1719, 0},
-#line 3267 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1720, 0},
-#line 5570 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1721, 0},
-#line 897 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1722, 4},
-#line 6280 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1723, 0},
-#line 5550 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1724, 0},
-#line 4487 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1725, 0},
-#line 1114 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1726, 0},
-#line 608 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1727, 0},
-#line 5666 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1728, 0},
-#line 4315 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1729, 0},
-#line 1102 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1730, 0},
-#line 3816 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1731, 0},
-#line 581 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1732, 0},
-#line 92 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1733, 0},
-#line 3037 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1734, 0},
-#line 1986 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1735, 0},
-#line 345 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1736, 0},
-#line 62 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1737, 0},
-#line 44 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1738, 0},
-#line 5898 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1739, 0},
-#line 308 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1740, 0},
-#line 969 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1741, 0},
-#line 2515 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1742, 4},
-#line 1904 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1743, 0},
-#line 4305 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1744, 4},
-#line 2608 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1745, 0},
-#line 2869 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1746, 0},
-#line 2661 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1747, 4},
-#line 409 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1748, 0},
-#line 6122 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1749, 0},
-#line 4164 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1750, 0},
-#line 883 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1751, 0},
-#line 2356 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1752, 0},
-#line 3174 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1753, 0},
-#line 4839 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1754, 0},
-#line 4735 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1755, 0},
-#line 6346 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1756, 0},
-#line 5929 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1757, 0},
-#line 6044 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1758, 0},
-#line 1130 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1759, 0},
-#line 636 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1760, 0},
-#line 1806 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1761, 0},
-#line 2307 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1762, 4},
-#line 1398 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1763, 0},
-#line 2415 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1764, 0},
-#line 5954 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1765, 0},
-#line 895 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1766, 0},
-#line 6108 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1767, 0},
-#line 6033 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1768, 0},
-#line 6028 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1769, 0},
-#line 215 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1770, 0},
-#line 5840 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1771, 0},
-#line 140 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1772, 0},
-#line 6509 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1773, 4},
-#line 3934 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1774, 0},
-#line 249 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1775, 0},
-#line 1216 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1776, 0},
-#line 228 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1777, 0},
-#line 4786 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1778, 0},
-#line 145 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1779, 0},
-#line 6316 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1780, 0},
-#line 1305 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1781, 0},
-#line 2364 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1782, 0},
-#line 6351 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1783, 0},
-#line 4249 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1784, 0},
-#line 3290 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1785, 0},
-#line 5755 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1786, 0},
-#line 3079 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1787, 0},
-#line 4159 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1788, 0},
-#line 5668 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1789, 2},
-#line 5904 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1790, 0},
-#line 2411 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1791, 0},
-#line 6525 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1792, 0},
-#line 66 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1793, 0},
-#line 4854 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1794, 0},
-#line 1110 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1795, 0},
-#line 4095 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1796, 4},
-#line 342 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1797, 0},
-#line 3016 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1798, 0},
-#line 1748 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1799, 0},
-#line 2987 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1800, 0},
-#line 6371 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1801, 0},
-#line 2558 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1802, 0},
-#line 4818 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1803, 0},
-#line 2846 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1804, 0},
-#line 3296 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1805, 0},
-#line 5672 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1806, 0},
-#line 825 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1807, 0},
-#line 2052 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1808, 0},
-#line 460 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1809, 0},
-#line 183 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1810, 0},
-#line 609 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1811, 0},
-#line 643 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1812, 0},
-#line 319 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1813, 0},
-#line 4237 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1814, 0},
-#line 2199 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1815, 0},
-#line 6348 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1816, 0},
-#line 1444 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1817, 0},
-#line 862 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1818, 0},
-#line 53 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1819, 0},
-#line 557 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1820, 0},
-#line 4722 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1821, 0},
-#line 2048 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1822, 0},
-#line 5786 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1823, 0},
-#line 5518 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1824, 0},
-#line 4172 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1825, 0},
-#line 1443 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1826, 0},
-#line 4828 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1827, 0},
-#line 37 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1828, 0},
-#line 832 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1829, 1},
-#line 6350 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1830, 0},
-#line 6356 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1831, 0},
-#line 332 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1832, 0},
-#line 1417 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1833, 0},
-#line 4319 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1834, 0},
-#line 58 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1835, 0},
-#line 236 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1836, 0},
-#line 6098 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1837, 1},
-#line 5556 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1838, 0},
-#line 221 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1839, 0},
-#line 3759 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1840, 0},
-#line 5914 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1841, 0},
-#line 6483 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1842, 0},
-#line 2670 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1843, 0},
-#line 687 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1844, 0},
-#line 4774 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1845, 0},
-#line 6334 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1846, 0},
-#line 6090 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1847, 4},
-#line 356 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1848, 0},
-#line 2634 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1849, 0},
-#line 4820 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1850, 0},
-#line 6508 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1851, 4},
-#line 833 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1852, 1},
-#line 926 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1853, 0},
-#line 5813 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1854, 0},
-#line 2419 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1855, 0},
-#line 817 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1856, 0},
-#line 4785 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1857, 0},
-#line 1468 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1858, 0},
-#line 2657 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1859, 0},
-#line 5606 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1860, 0},
-#line 5687 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1861, 0},
-#line 5809 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1862, 0},
-#line 770 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1863, 0},
-#line 4055 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1864, 0},
-#line 5758 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1865, 0},
-#line 6378 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1866, 0},
-#line 3888 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1867, 0},
-#line 4752 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1868, 0},
-#line 580 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1869, 4},
-#line 3036 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1870, 4},
-#line 1985 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1871, 4},
-#line 3188 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1872, 0},
-#line 912 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1873, 0},
-#line 1824 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1874, 0},
-#line 1218 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1875, 0},
-#line 4512 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1876, 0},
-#line 30 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1877, 0},
-#line 5567 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1878, 0},
-#line 4255 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1879, 0},
-#line 3098 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1880, 0},
-#line 5847 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1881, 0},
-#line 4208 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1882, 0},
-#line 868 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1883, 0},
-#line 2043 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1884, 0},
-#line 2389 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1885, 0},
-#line 3252 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1886, 0},
-#line 5945 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1887, 0},
-#line 1073 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1888, 0},
-#line 5549 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1889, 0},
-#line 6462 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1890, 0},
-#line 2762 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1891, 0},
-#line 1152 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1892, 0},
-#line 1859 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1893, 0},
-#line 6272 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1894, 0},
-#line 2959 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1895, 0},
-#line 1190 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1896, 0},
-#line 2120 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1897, 0},
-#line 923 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1898, 0},
-#line 846 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1899, 0},
-#line 504 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1900, 0},
-#line 4761 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1901, 0},
-#line 6273 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1902, 0},
-#line 1197 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1903, 4},
-#line 407 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1904, 0},
-#line 6059 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1905, 0},
-#line 664 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1906, 0},
-#line 5804 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1907, 0},
-#line 590 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1908, 0},
-#line 5827 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1909, 0},
-#line 5482 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1910, 0},
-#line 1753 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1911, 4},
-#line 4366 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1912, 0},
-#line 1467 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1913, 4},
-#line 1133 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1914, 0},
-#line 6441 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1915, 0},
-#line 6084 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1916, 0},
-#line 5834 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1917, 0},
-#line 2358 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1918, 0},
-#line 4819 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1919, 0},
-#line 769 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1920, 0},
-#line 2522 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1921, 4},
-#line 2899 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1922, 0},
-#line 3867 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1923, 0},
-#line 408 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1924, 0},
-#line 6073 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1925, 0},
-#line 775 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1926, 0},
-#line 3069 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1927, 0},
-#line 1188 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1928, 0},
-#line 193 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1929, 0},
-#line 2731 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1930, 0},
-#line 2376 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1931, 0},
-#line 5554 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1932, 0},
-#line 2015 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1933, 0},
-#line 773 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1934, 0},
-#line 341 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1935, 0},
-#line 4079 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1936, 0},
-#line 4121 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1937, 0},
-#line 2062 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1938, 0},
-#line 163 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1939, 0},
-#line 5411 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1940, 0},
-#line 3300 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1941, 0},
-#line 2058 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1942, 0},
-#line 4364 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1943, 0},
-#line 3131 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1944, 0},
-#line 4323 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1945, 0},
-#line 3293 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1946, 0},
-#line 5959 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1947, 0},
-#line 6092 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1948, 0},
-#line 2737 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1949, 0},
-#line 1111 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1950, 0},
-#line 4235 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1951, 0},
-#line 1196 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1952, 4},
-#line 861 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1953, 4},
-#line 632 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1954, 0},
-#line 5555 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1955, 0},
-#line 4264 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1956, 0},
-#line 896 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1957, 4},
-#line 760 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1958, 0},
-#line 5972 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1959, 0},
-#line 3012 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1960, 0},
-#line 6463 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1961, 2},
-#line 2538 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1962, 4},
-#line 4089 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1963, 0},
-#line 2545 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1964, 4},
-#line 326 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1965, 0},
-#line 6310 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1966, 0},
-#line 2375 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1967, 4},
-#line 2294 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1968, 4},
-#line 1210 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1969, 4},
-#line 5952 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1970, 0},
-#line 235 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1971, 4},
-#line 3186 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1972, 0},
-#line 241 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1973, 0},
-#line 5409 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1974, 0},
-#line 6380 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1975, 0},
-#line 2791 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1976, 0},
-#line 2531 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1977, 4},
-#line 2516 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1978, 4},
-#line 1752 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1979, 4},
-#line 3270 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1980, 0},
-#line 6114 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1981, 0},
-#line 1473 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1982, 0},
-#line 6251 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1983, 0},
-#line 6359 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1984, 0},
-#line 443 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1985, 0},
-#line 2312 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1986, 0},
-#line 1762 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1987, 0},
-#line 155 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1988, 0},
-#line 63 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1989, 0},
-#line 3060 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1990, 0},
-#line 5759 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1991, 0},
-#line 6262 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1992, 0},
-#line 2236 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1993, 0},
-#line 191 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1994, 0},
-#line 6263 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1995, 0},
-#line 5671 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1996, 0},
-#line 2265 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1997, 4},
-#line 146 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1998, 0},
-#line 1740 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1999, 4},
-#line 373 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2000, 4},
-#line 6446 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2001, 0},
-#line 6066 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2002, 0},
-#line 5540 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2003, 0},
-#line 2109 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2004, 0},
-#line 4777 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2005, 0},
-#line 6240 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2006, 0},
-#line 246 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2007, 0},
-#line 6362 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2008, 0},
-#line 5906 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2009, 0},
-#line 231 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2010, 0},
-#line 3101 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2011, 0},
-#line 6319 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2012, 0},
-#line 4138 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2013, 0},
-#line 4045 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2014, 0},
-#line 5979 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2015, 0},
-#line 1131 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2016, 0},
-#line 2255 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2017, 4},
-#line 4210 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2018, 0},
-#line 593 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2019, 4},
-#line 5633 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2020, 0},
-#line 3251 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2021, 4},
-#line 2891 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2022, 0},
-#line 5496 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2023, 0},
-#line 6069 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2024, 0},
-#line 801 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2025, 0},
-#line 2050 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2026, 0},
-#line 2479 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2027, 4},
-#line 2293 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2028, 4},
-#line 5566 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2029, 0},
-#line 2896 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2030, 0},
-#line 592 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2031, 0},
-#line 5534 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2032, 0},
-#line 4795 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2033, 0},
-#line 1204 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2034, 0},
-#line 5690 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2035, 0},
-#line 242 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2036, 0},
-#line 5545 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2037, 0},
-#line 5603 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2038, 0},
-#line 156 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2039, 0},
-#line 6298 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2040, 0},
-#line 2894 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2041, 0},
-#line 6291 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2042, 0},
-#line 6186 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2043, 0},
-#line 4511 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2044, 0},
-#line 6212 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2045, 0},
-#line 1739 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2046, 4},
-#line 6270 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2047, 0},
-#line 2001 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2048, 0},
-#line 4309 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2049, 0},
-#line 681 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2050, 0},
-#line 4757 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2051, 0},
-#line 5776 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2052, 0},
-#line 3840 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2053, 0},
-#line 4279 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2054, 0},
-#line 6495 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2055, 0},
-#line 4059 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2056, 0},
-#line 1256 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2057, 0},
-#line 4290 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2058, 0},
-#line 4306 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2059, 0},
-#line 6420 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2060, 0},
-#line 6264 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2061, 0},
-#line 2145 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2062, 4},
-#line 3056 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2063, 0},
-#line 2366 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2064, 0},
-#line 4732 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2065, 0},
-#line 4280 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2066, 0},
-#line 3853 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2067, 0},
-#line 2778 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2068, 0},
-#line 6160 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2069, 0},
-#line 1211 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2070, 4},
-#line 2789 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2071, 0},
-#line 6382 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2072, 0},
-#line 828 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2073, 0},
-#line 33 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2074, 0},
-#line 420 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2075, 0},
-#line 4145 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2076, 0},
-#line 372 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2077, 0},
-#line 5891 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2078, 0},
-#line 324 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2079, 0},
-#line 788 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2080, 0},
-#line 2211 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2081, 0},
-#line 6074 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2082, 0},
-#line 3171 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2083, 0},
-#line 4783 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2084, 0},
-#line 2234 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2085, 0},
-#line 116 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2086, 0},
-#line 6210 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2087, 0},
-#line 2217 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2088, 0},
-#line 4780 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2089, 0},
-#line 238 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2090, 0},
-#line 6216 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2091, 0},
-#line 1990 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2092, 0},
-#line 1390 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2093, 0},
-#line 5580 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2094, 0},
-#line 4256 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2095, 0},
-#line 5491 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2096, 0},
-#line 6031 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2097, 0},
-#line 1428 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2098, 0},
-#line 3839 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2099, 0},
-#line 307 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2100, 0},
-#line 5795 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2101, 0},
-#line 2547 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2102, 4},
-#line 5989 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2103, 0},
-#line 2589 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2104, 0},
-#line 6153 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2105, 0},
-#line 2732 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2106, 0},
-#line 5636 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2107, 0},
-#line 6205 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2108, 0},
-#line 3276 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2109, 0},
-#line 1891 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2110, 0},
-#line 4726 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2111, 0},
-#line 2519 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2112, 4},
-#line 4188 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2113, 0},
-#line 6325 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2114, 0},
-#line 1162 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2115, 0},
-#line 4833 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2116, 0},
-#line 5526 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2117, 0},
-#line 6370 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2118, 0},
-#line 2276 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2119, 0},
-#line 6129 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2120, 0},
-#line 3073 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2121, 0},
-#line 4471 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2122, 0},
-#line 2214 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2123, 0},
-#line 5727 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2124, 0},
-#line 6305 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2125, 0},
-#line 4328 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2126, 0},
-#line 6363 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2127, 0},
-#line 2912 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2128, 0},
-#line 1452 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2129, 4},
-#line 431 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2130, 0},
-#line 4327 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2131, 0},
-#line 1166 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2132, 0},
-#line 6235 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2133, 0},
-#line 5864 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2134, 0},
-#line 6130 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2135, 0},
-#line 767 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2136, 0},
-#line 4488 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2137, 0},
-#line 4325 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2138, 0},
-#line 2122 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2139, 0},
-#line 6353 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2140, 0},
-#line 469 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2141, 0},
-#line 6147 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2142, 0},
-#line 4796 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2143, 0},
-#line 2977 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2144, 0},
-#line 4846 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2145, 0},
-#line 6214 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2146, 0},
-#line 5514 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2147, 0},
-#line 2965 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2148, 0},
-#line 1234 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2149, 4},
-#line 2596 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2150, 0},
-#line 4835 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2151, 0},
-#line 2476 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2152, 4},
-#line 5714 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2153, 0},
-#line 3275 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2154, 0},
-#line 649 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2155, 0},
-#line 2215 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2156, 0},
-#line 6453 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2157, 0},
-#line 374 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2158, 4},
-#line 5764 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2159, 0},
-#line 597 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2160, 0},
-#line 48 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2161, 0},
-#line 5955 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2162, 0},
-#line 5961 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2163, 0},
-#line 3857 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2164, 0},
-#line 1200 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2165, 4},
-#line 350 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2166, 0},
-#line 1075 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2167, 0},
-#line 5639 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2168, 0},
-#line 3185 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2169, 0},
-#line 5958 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2170, 0},
-#line 5579 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2171, 0},
-#line 5858 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2172, 0},
-#line 2191 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2173, 0},
-#line 3767 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2174, 0},
-#line 6318 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2175, 0},
-#line 1167 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2176, 0},
-#line 6095 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2177, 0},
-#line 5984 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2178, 0},
-#line 777 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2179, 0},
-#line 72 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2180, 0},
-#line 4759 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2181, 0},
-#line 1412 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2182, 0},
-#line 2995 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2183, 0},
-#line 1481 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2184, 0},
-#line 4860 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2185, 0},
-#line 1206 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2186, 0},
-#line 5832 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2187, 0},
-#line 5857 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2188, 4},
-#line 3764 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2189, 0},
-#line 508 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2190, 0},
-#line 5565 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2191, 0},
-#line 1788 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2192, 0},
-#line 6304 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2193, 0},
-#line 5905 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2194, 0},
-#line 3083 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2195, 0},
-#line 2262 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2196, 4},
-#line 5674 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2197, 0},
-#line 4263 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2198, 0},
-#line 851 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2199, 4},
-#line 5923 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2200, 0},
-#line 4219 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2201, 0},
-#line 6075 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2202, 0},
-#line 3271 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2203, 0},
-#line 1201 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2204, 4},
-#line 4850 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2205, 0},
-#line 4303 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2206, 0},
-#line 325 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2207, 0},
-#line 5985 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2208, 0},
-#line 623 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2209, 0},
-#line 529 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2210, 4},
-#line 5766 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2211, 0},
-#line 6479 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2212, 0},
-#line 548 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2213, 4},
-#line 2559 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2214, 0},
-#line 4025 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2215, 0},
-#line 5569 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2216, 0},
-#line 589 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2217, 1},
-#line 6450 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2218, 0},
-#line 5632 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2219, 0},
-#line 539 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2220, 4},
-#line 205 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2221, 0},
-#line 2069 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2222, 0},
-#line 6514 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2223, 0},
-#line 2078 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2224, 0},
-#line 2146 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2225, 4},
-#line 1266 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2226, 0},
-#line 5408 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2227, 0},
-#line 4049 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2228, 0},
-#line 6008 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2229, 0},
-#line 174 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2230, 0},
-#line 5489 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2231, 0},
-#line 6335 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2232, 0},
-#line 355 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2233, 0},
-#line 4042 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2234, 0},
-#line 4076 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2235, 0},
-#line 1105 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2236, 0},
-#line 3794 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2237, 0},
-#line 5999 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2238, 0},
-#line 6524 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2239, 0},
-#line 2528 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2240, 4},
-#line 1451 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2241, 4},
-#line 4213 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2242, 0},
-#line 551 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2243, 4},
-#line 546 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2244, 4},
-#line 5643 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2245, 0},
-#line 2921 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2246, 0},
-#line 547 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2247, 4},
-#line 545 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2248, 4},
-#line 2840 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2249, 0},
-#line 2826 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2250, 0},
-#line 567 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2251, 0},
-#line 5812 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2252, 4},
-#line 2257 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2253, 4},
-#line 2402 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2254, 0},
-#line 6236 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2255, 0},
-#line 5551 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2256, 0},
-#line 6252 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2257, 0},
-#line 6486 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2258, 0},
-#line 331 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2259, 4},
-#line 4267 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2260, 0},
-#line 2767 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2261, 0},
-#line 4748 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2262, 0},
-#line 204 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2263, 0},
-#line 831 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2264, 0},
-#line 6372 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2265, 0},
-#line 2769 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2266, 0},
-#line 5416 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2267, 0},
-#line 5998 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2268, 0},
-#line 2953 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2269, 0},
-#line 2263 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2270, 4},
-#line 2837 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2271, 0},
-#line 3122 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2272, 0},
-#line 6315 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2273, 0},
-#line 4028 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2274, 0},
-#line 2065 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2275, 0},
-#line 2971 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2276, 0},
-#line 2593 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2277, 0},
-#line 5983 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2278, 0},
-#line 2080 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2279, 0},
-#line 3055 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2280, 0},
-#line 2267 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2281, 4},
-#line 5650 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2282, 0},
-#line 3094 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2283, 0},
-#line 2609 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2284, 0},
-#line 2779 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2285, 0},
-#line 6208 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2286, 0},
-#line 2863 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2287, 0},
-#line 6447 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2288, 0},
-#line 2865 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2289, 0},
-#line 3781 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2290, 0},
-#line 5557 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2291, 0},
-#line 2125 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2292, 0},
-#line 5564 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2293, 0},
-#line 1410 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2294, 0},
-#line 2244 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2295, 0},
-#line 6357 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2296, 0},
-#line 1178 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2297, 0},
-#line 195 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2298, 0},
-#line 4763 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2299, 0},
-#line 4799 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2300, 0},
-#line 536 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2301, 4},
-#line 4261 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2302, 0},
-#line 6189 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2303, 0},
-#line 5638 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2304, 0},
-#line 2400 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2305, 0},
-#line 878 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2306, 0},
-#line 1781 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2307, 0},
-#line 544 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2308, 4},
-#line 5811 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2309, 4},
-#line 2190 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2310, 0},
-#line 1453 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2311, 4},
-#line 5934 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2312, 0},
-#line 1194 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2313, 4},
-#line 2508 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2314, 4},
-#line 6006 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2315, 0},
-#line 1227 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2316, 4},
-#line 2072 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2317, 0},
-#line 1168 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2318, 0},
-#line 6011 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2319, 0},
-#line 2992 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2320, 0},
-#line 513 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2321, 4},
-#line 2087 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2322, 0},
-#line 218 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2323, 0},
-#line 822 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2324, 0},
-#line 2416 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2325, 0},
-#line 541 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2326, 4},
-#line 514 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2327, 4},
-#line 5559 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2328, 0},
-#line 5763 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2329, 0},
-#line 3154 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2330, 0},
-#line 1165 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2331, 0},
-#line 2518 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2332, 4},
-#line 968 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2333, 0},
-#line 1903 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2334, 0},
-#line 2084 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2335, 0},
-#line 5943 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2336, 0},
-#line 530 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2337, 4},
-#line 3782 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2338, 0},
-#line 5473 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2339, 0},
-#line 6343 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2340, 0},
-#line 78 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2341, 0},
-#line 1172 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2342, 0},
-#line 6219 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2343, 0},
-#line 550 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2344, 4},
-#line 3138 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2345, 0},
-#line 5802 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2346, 0},
-#line 538 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2347, 4},
-#line 207 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2348, 0},
-#line 5851 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2349, 0},
-#line 5871 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2350, 0},
-#line 2918 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2351, 0},
-#line 4071 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2352, 0},
-#line 5894 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2353, 0},
-#line 4853 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2354, 0},
-#line 628 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2355, 0},
-#line 410 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2356, 0},
-#line 1180 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2357, 0},
-#line 1304 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2358, 0},
-#line 2239 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2359, 4},
-#line 2025 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2360, 0},
-#line 6012 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2361, 0},
-#line 5640 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2362, 0},
-#line 2772 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2363, 0},
-#line 290 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2364, 0},
-#line 6435 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2365, 0},
-#line 4250 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2366, 0},
-#line 6009 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2367, 0},
-#line 1076 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2368, 0},
-#line 104 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2369, 0},
-#line 631 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2370, 0},
-#line 6155 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2371, 0},
-#line 2570 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2372, 0},
-#line 2565 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2373, 0},
-#line 118 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2374, 0},
-#line 2543 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2375, 4},
-#line 2511 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2376, 4},
-#line 3061 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2377, 0},
-#line 5750 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2378, 0},
-#line 3900 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2379, 0},
-#line 49 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2380, 0},
-#line 2500 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2381, 4},
-#line 6520 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2382, 0},
-#line 1992 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2383, 0},
-#line 6518 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2384, 0},
-#line 5881 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2385, 0},
-#line 6390 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2386, 0},
-#line 6000 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2387, 0},
-#line 2401 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2388, 0},
-#line 5573 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2389, 0},
-#line 2946 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2390, 0},
-#line 540 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2391, 4},
-#line 6444 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2392, 0},
-#line 5624 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2393, 0},
-#line 5634 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2394, 0},
-#line 778 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2395, 0},
-#line 5888 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2396, 4},
-#line 5895 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2397, 0},
-#line 2175 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2398, 0},
-#line 3161 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2399, 0},
-#line 5510 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2400, 0},
-#line 4238 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2401, 0},
-#line 4093 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2402, 0},
-#line 1155 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2403, 0},
-#line 4202 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2404, 0},
-#line 2059 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2405, 0},
-#line 6309 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2406, 0},
-#line 2534 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2407, 4},
-#line 5499 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2408, 0},
-#line 537 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2409, 4},
-#line 5582 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2410, 0},
-#line 5642 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2411, 0},
-#line 5715 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2412, 0},
-#line 5964 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2413, 0},
-#line 2818 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2414, 0},
-#line 719 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2415, 0},
-#line 4034 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2416, 0},
-#line 6224 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2417, 0},
-#line 1770 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2418, 0},
-#line 2973 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2419, 0},
-#line 52 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2420, 0},
-#line 217 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2421, 0},
-#line 2499 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2422, 4},
-#line 1236 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2423, 4},
-#line 4021 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2424, 0},
-#line 1480 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2425, 0},
-#line 6531 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2426, 0},
-#line 1272 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2427, 0},
-#line 2861 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2428, 0},
-#line 5472 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2429, 0},
-#line 4365 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2430, 0},
-#line 5928 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2431, 0},
-#line 2616 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2432, 0},
-#line 4745 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2433, 0},
-#line 6278 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2434, 0},
-#line 2053 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2435, 0},
-#line 850 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2436, 0},
-#line 2546 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2437, 4},
-#line 3795 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2438, 0},
-#line 6516 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2439, 0},
-#line 5844 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2440, 0},
-#line 188 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2441, 0},
-#line 1815 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2442, 4},
-#line 839 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2443, 0},
-#line 50 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2444, 0},
-#line 3826 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2445, 0},
-#line 535 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2446, 4},
-#line 5878 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2447, 0},
-#line 2118 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2448, 0},
-#line 4146 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2449, 0},
-#line 543 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2450, 4},
-#line 6184 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2451, 0},
-#line 6106 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2452, 0},
-#line 3408 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2453, 0},
-#line 3444 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2454, 0},
-#line 3405 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2455, 0},
-#line 2269 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2456, 0},
-#line 6124 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2457, 0},
-#line 2996 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2458, 0},
-#line 3629 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2459, 0},
-#line 3693 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2460, 0},
-#line 3700 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2461, 0},
-#line 6137 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2462, 0},
-#line 3694 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2463, 0},
-#line 796 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2464, 0},
-#line 6002 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2465, 0},
-#line 2684 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2466, 0},
-#line 3651 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2467, 0},
-#line 1038 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2468, 0},
-#line 6261 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2469, 0},
-#line 1418 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2470, 0},
-#line 6116 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2471, 0},
-#line 5558 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2472, 0},
-#line 6149 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2473, 0},
-#line 51 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2474, 0},
-#line 3070 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2475, 0},
-#line 552 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2476, 4},
-#line 6329 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2477, 0},
-#line 6320 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2478, 0},
-#line 2943 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2479, 0},
-#line 1837 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2480, 0},
-#line 2163 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2481, 0},
-#line 3676 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2482, 0},
-#line 5728 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2483, 0},
-#line 3434 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2484, 0},
-#line 3758 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2485, 0},
-#line 565 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2486, 0},
-#line 3081 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2487, 0},
-#line 5777 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2488, 0},
-#line 4844 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2489, 0},
-#line 3827 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2490, 0},
-#line 4064 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2491, 0},
-#line 4133 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2492, 0},
-#line 40 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2493, 0},
-#line 3320 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2494, 0},
-#line 1209 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2495, 4},
-#line 2551 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2496, 4},
-#line 2935 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2497, 0},
-#line 5622 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2498, 0},
-#line 1370 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2499, 0},
-#line 4282 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2500, 0},
-#line 168 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2501, 0},
-#line 1429 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2502, 0},
-#line 5772 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2503, 0},
-#line 5970 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2504, 0},
-#line 4304 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2505, 0},
-#line 1839 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2506, 0},
-#line 2498 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2507, 4},
-#line 3705 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2508, 0},
-#line 3442 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2509, 0},
-#line 6209 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2510, 0},
-#line 1471 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2511, 0},
-#line 3697 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2512, 0},
-#line 2183 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2513, 0},
-#line 755 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2514, 0},
-#line 4825 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2515, 0},
-#line 3413 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2516, 0},
-#line 3419 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2517, 0},
-#line 5486 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2518, 0},
-#line 3708 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2519, 0},
-#line 165 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2520, 0},
-#line 5621 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2521, 0},
-#line 3645 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2522, 0},
-#line 5803 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2523, 0},
-#line 4501 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2524, 0},
-#line 534 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2525, 4},
-#line 4728 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2526, 0},
-#line 2828 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2527, 0},
-#line 4807 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2528, 0},
-#line 1413 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2529, 0},
-#line 3751 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2530, 2},
-#line 2882 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2531, 0},
-#line 3830 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2532, 0},
-#line 2525 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2533, 4},
-#line 1095 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2534, 0},
-#line 2385 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2535, 0},
-#line 4308 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2536, 0},
-#line 2651 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2537, 0},
-#line 3838 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2538, 0},
-#line 1222 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2539, 0},
-#line 2950 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2540, 0},
-#line 3625 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2541, 2},
-#line 3126 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2542, 0},
-#line 510 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2543, 4},
-#line 3971 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2544, 0},
-#line 5507 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2545, 0},
-#line 1004 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2546, 0},
-#line 5663 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2547, 0},
-#line 6354 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2548, 0},
-#line 1940 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2549, 0},
-#line 2535 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2550, 4},
-#line 3180 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2551, 0},
-#line 4082 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2552, 0},
-#line 69 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2553, 0},
-#line 5977 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2554, 0},
-#line 287 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2555, 0},
-#line 1749 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2556, 0},
-#line 6159 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2557, 0},
-#line 3263 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2558, 0},
-#line 6458 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2559, 0},
-#line 6469 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2560, 0},
-#line 1094 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2561, 0},
-#line 3422 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2562, 0},
-#line 1182 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2563, 0},
-#line 3626 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2564, 0},
-#line 4032 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2565, 0},
-#line 6302 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2566, 0},
-#line 2331 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2567, 0},
-#line 3420 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2568, 0},
-#line 6517 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2569, 0},
-#line 4140 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2570, 0},
-#line 1340 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2571, 0},
-#line 3414 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2572, 0},
-#line 2068 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2573, 0},
-#line 2848 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2574, 0},
-#line 3465 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2575, 0},
-#line 1177 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2576, 0},
-#line 5449 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2577, 0},
-#line 4017 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2578, 0},
-#line 4749 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2579, 0},
-#line 3644 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2580, 1},
-#line 2993 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2581, 0},
-#line 591 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2582, 0},
-#line 4441 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2583, 0},
-#line 587 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2584, 0},
-#line 2082 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2585, 4},
-#line 3829 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2586, 0},
-#line 6366 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2587, 0},
-#line 509 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2588, 4},
-#line 5773 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2589, 0},
-#line 1784 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2590, 0},
-#line 3902 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2591, 0},
-#line 3149 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2592, 0},
-#line 6196 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2593, 0},
-#line 764 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2594, 0},
-#line 3769 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2595, 0},
-#line 1856 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2596, 0},
-#line 6144 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2597, 0},
-#line 1730 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2598, 0},
-#line 2164 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2599, 0},
-#line 3846 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2600, 0},
-#line 6042 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2601, 0},
-#line 3622 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2602, 0},
-#line 3354 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2603, 0},
-#line 2665 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2604, 0},
-#line 2338 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2605, 0},
-#line 2240 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2606, 4},
-#line 206 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2607, 0},
-#line 1150 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2608, 0},
-#line 6295 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2609, 0},
-#line 2488 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2610, 4},
-#line 3090 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2611, 0},
-#line 6241 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2612, 0},
-#line 3308 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2613, 0},
-#line 2827 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2614, 0},
-#line 5443 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2615, 0},
-#line 2198 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2616, 0},
-#line 667 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2617, 0},
-#line 476 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2618, 0},
-#line 4067 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2619, 0},
-#line 2280 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2620, 0},
-#line 158 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2621, 0},
-#line 5990 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2622, 0},
-#line 3624 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2623, 0},
-#line 2809 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2624, 0},
-#line 5654 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2625, 0},
-#line 5765 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2626, 0},
-#line 5586 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2627, 0},
-#line 5726 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2628, 0},
-#line 1461 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2629, 0},
-#line 3961 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2630, 0},
-#line 3379 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2631, 0},
-#line 5625 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2632, 0},
-#line 995 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2633, 0},
-#line 5870 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2634, 0},
-#line 1928 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2635, 0},
-#line 3690 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2636, 0},
-#line 2637 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2637, 0},
-#line 4467 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2638, 0},
-#line 2060 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2639, 0},
-#line 2771 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2640, 0},
-#line 430 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2641, 0},
-#line 6188 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2642, 0},
-#line 5519 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2643, 1},
-#line 3679 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2644, 0},
-#line 3481 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2645, 0},
-#line 3319 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2646, 0},
-#line 3696 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2647, 0},
-#line 2126 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2648, 0},
-#line 3850 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2649, 0},
-#line 5738 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2650, 0},
-#line 3653 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2651, 0},
-#line 3412 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2652, 0},
-#line 6285 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2653, 0},
-#line 3523 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2654, 0},
-#line 3495 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2655, 0},
-#line 2180 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2656, 0},
-#line 285 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2657, 0},
-#line 3517 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2658, 0},
-#line 6296 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2659, 0},
-#line 6136 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2660, 0},
-#line 1943 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2661, 0},
-#line 489 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2662, 0},
-#line 2770 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2663, 0},
-#line 4258 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2664, 0},
-#line 2595 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2665, 0},
-#line 4562 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2666, 0},
-#line 1459 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2667, 0},
-#line 1744 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2668, 0},
-#line 3269 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2669, 0},
-#line 2873 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2670, 0},
-#line 5912 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2671, 0},
-#line 3856 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2672, 0},
-#line 1330 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2673, 0},
-#line 2879 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2674, 0},
-#line 4723 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2675, 4},
-#line 2449 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2676, 0},
-#line 4697 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2677, 0},
-#line 3179 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2678, 0},
-#line 470 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2679, 0},
-#line 2536 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2680, 4},
-#line 3685 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2681, 0},
-#line 4407 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2682, 0},
-#line 4001 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2683, 0},
-#line 6145 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2684, 0},
-#line 1039 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2685, 0},
-#line 1968 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2686, 0},
-#line 3450 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2687, 0},
-#line 3076 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2688, 0},
-#line 3988 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2689, 0},
-#line 2159 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2690, 0},
-#line 2942 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2691, 0},
-#line 1022 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2692, 0},
-#line 2773 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2693, 0},
-#line 1954 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2694, 0},
-#line 1158 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2695, 4},
-#line 5620 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2696, 0},
-#line 2067 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2697, 0},
-#line 3484 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2698, 0},
-#line 3485 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2699, 0},
-#line 3454 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2700, 0},
-#line 3257 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2701, 0},
-#line 3482 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2702, 0},
-#line 4209 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2703, 0},
-#line 457 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2704, 0},
-#line 5533 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2705, 0},
-#line 2181 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2706, 0},
-#line 5767 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2707, 0},
-#line 3744 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2708, 0},
-#line 396 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2709, 0},
-#line 6093 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2710, 0},
-#line 4531 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2711, 0},
-#line 4300 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2712, 0},
-#line 3528 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2713, 0},
-#line 1371 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2714, 0},
-#line 2981 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2715, 0},
-#line 2297 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2716, 0},
-#line 3521 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2717, 0},
-#line 1857 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2718, 4},
-#line 1357 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2719, 0},
-#line 3151 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2720, 0},
-#line 6360 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2721, 0},
-#line 6111 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2722, 0},
-#line 5757 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2723, 0},
-#line 1217 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2724, 0},
-#line 3085 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2725, 0},
-#line 3421 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2726, 0},
-#line 4063 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2727, 0},
-#line 4701 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2728, 0},
-#line 3418 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2729, 0},
-#line 5552 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2730, 0},
-#line 305 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2731, 0},
-#line 4652 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2732, 0},
-#line 4756 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2733, 0},
-#line 292 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2734, 0},
-#line 3741 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2735, 0},
-#line 4068 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2736, 0},
-#line 3306 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2737, 0},
-#line 4824 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2738, 0},
 #line 1439 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2739, 0},
-#line 3515 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2740, 0},
-#line 4554 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2741, 0},
-#line 2079 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2742, 0},
-#line 4779 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2743, 0},
-#line 2152 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2744, 0},
-#line 6424 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2745, 0},
-#line 102 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2746, 0},
-#line 626 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2747, 0},
-#line 3415 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2748, 0},
-#line 4257 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2749, 0},
-#line 149 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2750, 0},
-#line 2633 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2751, 0},
-#line 4010 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2752, 0},
-#line 5538 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2753, 0},
-#line 1048 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2754, 0},
-#line 6412 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2755, 0},
-#line 2530 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2756, 4},
-#line 6015 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2757, 0},
-#line 4705 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2758, 0},
-#line 3800 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2759, 0},
-#line 2261 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2760, 4},
-#line 1238 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2761, 4},
-#line 5831 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2762, 0},
-#line 3520 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2763, 0},
-#line 5768 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2764, 0},
-#line 5980 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2765, 0},
-#line 6307 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2766, 0},
-#line 4119 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2767, 0},
-#line 6480 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2768, 0},
-#line 6139 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2769, 0},
-#line 6143 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2770, 0},
-#line 4618 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2771, 0},
-#line 3483 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2772, 0},
-#line 4734 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2773, 0},
-#line 2103 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2774, 0},
-#line 3268 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2775, 0},
-#line 5774 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2776, 0},
-#line 4395 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2777, 0},
-#line 2461 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2778, 0},
-#line 3974 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2779, 0},
-#line 1186 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2780, 0},
-#line 1007 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2781, 0},
-#line 1942 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2782, 0},
-#line 3824 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2783, 0},
-#line 5992 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2784, 0},
-#line 1235 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2785, 4},
-#line 6239 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2786, 0},
-#line 194 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2787, 0},
-#line 6217 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2788, 0},
-#line 1378 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2789, 0},
-#line 5528 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2790, 0},
-#line 170 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2791, 0},
-#line 5790 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2792, 0},
-#line 5911 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2793, 0},
-#line 101 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2794, 0},
-#line 1175 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2795, 0},
-#line 6029 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2796, 0},
-#line 3502 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2797, 0},
-#line 2485 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2798, 4},
-#line 3047 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2799, 0},
-#line 2475 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2800, 4},
-#line 3525 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2801, 0},
-#line 2738 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2802, 0},
-#line 2811 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2803, 0},
-#line 4620 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2804, 0},
-#line 3333 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2805, 0},
-#line 4462 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2806, 0},
-#line 4791 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2807, 0},
-#line 3331 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2808, 0},
-#line 1171 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2809, 0},
-#line 3725 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2810, 0},
-#line 1343 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2811, 0},
-#line 3489 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2812, 0},
-#line 2758 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2813, 0},
-#line 1440 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2814, 0},
-#line 853 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2815, 4},
-#line 4442 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2816, 0},
-#line 1151 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2817, 0},
-#line 4425 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2818, 0},
-#line 4143 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2819, 0},
-#line 3448 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2820, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1350, 0},
+#line 6109 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1351, 0},
+#line 3387 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1352, 0},
+#line 4163 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1353, 0},
+#line 6134 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1354, 0},
 #line 3445 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2821, 0},
-#line 3411 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2822, 0},
-#line 3507 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2823, 0},
-#line 5560 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2824, 0},
-#line 3407 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2825, 0},
-#line 196 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2826, 0},
-#line 3704 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2827, 0},
-#line 3633 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2828, 0},
-#line 3703 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2829, 0},
-#line 786 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2830, 0},
-#line 6148 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2831, 0},
-#line 4642 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2832, 0},
-#line 793 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2833, 0},
-#line 951 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2834, 0},
-#line 4816 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2835, 0},
-#line 1887 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2836, 0},
-#line 3026 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2837, 0},
-#line 5853 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2838, 4},
-#line 4461 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2839, 0},
-#line 2598 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2840, 0},
-#line 2034 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2841, 0},
-#line 3501 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2842, 0},
-#line 6481 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2843, 0},
-#line 4703 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2844, 0},
-#line 4607 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2845, 0},
-#line 435 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2846, 0},
-#line 4291 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2847, 0},
-#line 4080 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2848, 0},
-#line 384 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2849, 0},
-#line 3954 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2850, 0},
-#line 388 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2851, 0},
-#line 5817 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2852, 0},
-#line 988 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2853, 0},
-#line 3096 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2854, 0},
-#line 1920 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2855, 0},
-#line 4823 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2856, 4},
-#line 5548 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2857, 0},
-#line 2874 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2858, 0},
-#line 6112 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2859, 0},
-#line 4794 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2860, 0},
-#line 6238 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2861, 0},
-#line 782 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2862, 0},
-#line 6230 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2863, 0},
-#line 444 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2864, 0},
-#line 3027 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2865, 0},
-#line 95 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2866, 0},
-#line 1414 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2867, 0},
-#line 4817 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2868, 0},
-#line 447 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2869, 0},
-#line 6121 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2870, 0},
-#line 2170 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2871, 0},
-#line 3321 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2872, 0},
-#line 4608 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2873, 0},
-#line 4656 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2874, 0},
-#line 2497 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2875, 4},
-#line 3869 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2876, 0},
-#line 3825 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2877, 0},
-#line 1399 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2878, 0},
-#line 1447 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2879, 0},
-#line 3962 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2880, 0},
-#line 2832 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2881, 0},
-#line 2514 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2882, 4},
-#line 4102 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2883, 0},
-#line 996 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2884, 0},
-#line 1929 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2885, 0},
-#line 2107 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2886, 0},
-#line 466 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2887, 0},
-#line 1323 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2888, 0},
-#line 3707 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2889, 0},
-#line 3634 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2890, 0},
-#line 4601 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2891, 0},
-#line 2432 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2892, 0},
-#line 4530 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2893, 0},
-#line 4452 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2894, 0},
-#line 4827 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2895, 0},
-#line 3341 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2896, 0},
-#line 4753 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2897, 0},
-#line 852 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2898, 4},
-#line 515 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2899, 4},
-#line 3166 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2900, 0},
-#line 4245 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2901, 0},
-#line 2794 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2902, 0},
-#line 2628 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2903, 0},
-#line 4619 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2904, 0},
-#line 4070 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2905, 0},
-#line 818 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2906, 0},
-#line 1331 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2907, 0},
-#line 1402 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2908, 4},
-#line 3024 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2909, 0},
-#line 5658 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2910, 0},
-#line 6419 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2911, 0},
-#line 2489 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2912, 4},
-#line 6530 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2913, 0},
-#line 4740 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2914, 0},
-#line 453 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2915, 4},
-#line 1198 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2916, 4},
-#line 5778 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2917, 0},
-#line 4410 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2918, 0},
-#line 2431 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2919, 0},
-#line 1193 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2920, 4},
-#line 3500 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2921, 0},
-#line 175 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2922, 0},
-#line 3503 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2923, 0},
-#line 4047 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2924, 0},
-#line 4581 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2925, 0},
-#line 4651 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2926, 0},
-#line 1161 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2927, 0},
-#line 1226 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2928, 4},
-#line 1212 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2929, 4},
-#line 3041 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2930, 0},
-#line 4848 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2931, 4},
-#line 2629 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2932, 0},
-#line 4598 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2933, 0},
-#line 3410 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2934, 0},
-#line 73 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2935, 0},
-#line 6218 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2936, 0},
-#line 5723 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2937, 0},
-#line 3089 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2938, 0},
-#line 2749 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2939, 0},
-#line 6048 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2940, 0},
-#line 528 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2941, 4},
-#line 5730 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2942, 0},
-#line 4717 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2943, 0},
-#line 6499 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2944, 0},
-#line 5541 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2945, 0},
-#line 2117 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2946, 0},
-#line 6493 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2947, 0},
-#line 1233 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2948, 4},
-#line 3740 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2949, 0},
-#line 3806 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2950, 0},
-#line 1149 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2951, 0},
-#line 164 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2952, 0},
-#line 3453 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2953, 0},
-#line 1243 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2954, 4},
-#line 4710 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2955, 0},
-#line 3496 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2956, 0},
-#line 4194 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2957, 0},
-#line 3628 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2958, 0},
-#line 522 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2959, 4},
-#line 2914 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2960, 0},
-#line 6358 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2961, 0},
-#line 5513 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2962, 0},
-#line 386 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2963, 0},
-#line 3486 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2964, 0},
-#line 5576 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2965, 0},
-#line 5571 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2966, 0},
-#line 5957 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2967, 0},
-#line 6284 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2968, 0},
-#line 4716 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2969, 0},
-#line 5725 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2970, 0},
-#line 3842 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2971, 0},
-#line 520 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2972, 4},
-#line 5667 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2973, 0},
-#line 6421 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2974, 0},
-#line 3702 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2975, 0},
-#line 445 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2976, 0},
-#line 3318 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2977, 0},
-#line 4569 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2978, 0},
-#line 4815 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2979, 0},
-#line 3529 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2980, 0},
-#line 3057 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2981, 0},
-#line 4387 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2982, 0},
-#line 3245 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2983, 0},
-#line 2563 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2984, 0},
-#line 4058 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2985, 0},
-#line 5543 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2986, 0},
-#line 2842 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2987, 0},
-#line 6497 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2988, 0},
-#line 2617 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2989, 0},
-#line 4706 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2990, 0},
-#line 2768 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2991, 0},
-#line 568 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2992, 0},
-#line 399 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2993, 0},
-#line 2751 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2994, 0},
-#line 159 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2995, 0},
-#line 3347 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2996, 0},
-#line 244 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2997, 0},
-#line 5930 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2998, 0},
-#line 200 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2999, 0},
-#line 526 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3000, 4},
-#line 5410 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3001, 0},
-#line 3406 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3002, 0},
-#line 4396 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3003, 0},
-#line 3786 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3004, 0},
-#line 2496 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3005, 4},
-#line 6132 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3006, 0},
-#line 2917 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3007, 0},
-#line 4629 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3008, 0},
-#line 1242 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3009, 4},
-#line 1108 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3010, 0},
-#line 6365 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3011, 0},
-#line 4595 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3012, 0},
-#line 3631 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3013, 0},
-#line 4577 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3014, 0},
-#line 1791 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3015, 4},
-#line 3363 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3016, 0},
-#line 5669 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3017, 0},
-#line 5451 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3018, 0},
-#line 6253 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3019, 0},
-#line 6119 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3020, 0},
-#line 3487 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3021, 0},
-#line 3032 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3022, 0},
-#line 3623 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3023, 0},
-#line 5497 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3024, 0},
-#line 4628 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3025, 0},
-#line 2566 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3026, 0},
-#line 6471 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3027, 0},
-#line 4074 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3028, 0},
-#line 4804 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3029, 0},
-#line 1254 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3030, 0},
-#line 6131 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3031, 0},
-#line 783 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3032, 0},
-#line 4463 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3033, 0},
-#line 2330 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3034, 0},
-#line 4236 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3035, 0},
-#line 3510 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3036, 0},
-#line 4698 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3037, 0},
-#line 3377 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3038, 0},
-#line 816 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3039, 0},
-#line 3646 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3040, 0},
-#line 6477 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3041, 0},
-#line 4649 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3042, 0},
-#line 5756 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3043, 0},
-#line 3847 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3044, 0},
-#line 203 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3045, 0},
-#line 468 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3046, 0},
-#line 2782 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3047, 0},
-#line 5670 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3048, 0},
-#line 2275 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3049, 0},
-#line 5503 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3050, 0},
-#line 2640 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3051, 0},
-#line 3400 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3052, 0},
-#line 2587 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3053, 0},
-#line 2474 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3054, 4},
-#line 4707 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3055, 0},
-#line 4553 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3056, 0},
-#line 3609 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3057, 0},
-#line 2167 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3058, 0},
-#line 519 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3059, 4},
-#line 3513 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3060, 0},
-#line 2958 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3061, 0},
-#line 4567 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3062, 0},
-#line 2729 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3063, 0},
-#line 6146 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3064, 0},
-#line 4221 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3065, 0},
-#line 3519 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3066, 0},
-#line 2868 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3067, 0},
-#line 5531 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3068, 0},
-#line 518 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3069, 4},
-#line 3508 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3070, 0},
-#line 4743 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3071, 0},
-#line 5568 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3072, 0},
-#line 517 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3073, 4},
-#line 3053 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3074, 0},
-#line 523 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3075, 4},
-#line 2911 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3076, 0},
-#line 4534 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3077, 0},
-#line 5747 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3078, 0},
-#line 4809 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3079, 0},
-#line 4650 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3080, 0},
-#line 2299 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3081, 0},
-#line 1176 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3082, 0},
-#line 2941 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3083, 0},
-#line 3695 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3084, 0},
-#line 4676 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3085, 0},
-#line 6317 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3086, 0},
-#line 4670 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3087, 0},
-#line 112 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3088, 0},
-#line 4765 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3089, 0},
-#line 3097 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3090, 0},
-#line 524 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3091, 4},
-#line 5562 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3092, 0},
-#line 6231 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3093, 0},
-#line 4654 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3094, 0},
-#line 4281 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3095, 0},
-#line 840 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3096, 0},
-#line 3804 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3097, 0},
-#line 1846 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3098, 4},
-#line 3505 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3099, 0},
-#line 4516 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3100, 0},
-#line 3327 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3101, 0},
-#line 5981 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3102, 0},
-#line 6440 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3103, 0},
-#line 542 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3104, 4},
-#line 3183 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3105, 0},
-#line 2222 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3106, 0},
-#line 5505 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3107, 0},
-#line 4699 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3108, 0},
-#line 4644 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3109, 0},
-#line 1255 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3110, 0},
-#line 5676 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3111, 0},
-#line 4053 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3112, 0},
-#line 4075 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3113, 0},
-#line 2800 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3114, 0},
-#line 2550 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3115, 4},
-#line 2095 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3116, 0},
-#line 3009 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3117, 0},
-#line 4563 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3118, 0},
-#line 2913 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3119, 0},
-#line 4647 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3120, 0},
-#line 5926 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3121, 0},
-#line 5437 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3122, 0},
-#line 6383 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3123, 0},
-#line 3683 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3124, 0},
-#line 6369 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3125, 0},
-#line 2807 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3126, 0},
-#line 3714 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3127, 0},
-#line 3531 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3128, 0},
-#line 6070 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3129, 0},
-#line 4073 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3130, 0},
-#line 1845 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3131, 0},
-#line 5471 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3132, 0},
-#line 2404 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3133, 0},
-#line 253 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3134, 0},
-#line 4675 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3135, 0},
-#line 3163 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3136, 0},
-#line 3403 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3137, 0},
-#line 2739 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3138, 0},
-#line 2870 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3139, 0},
-#line 347 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3140, 0},
-#line 560 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3141, 0},
-#line 2583 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3142, 0},
-#line 4793 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3143, 4},
-#line 3228 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3144, 0},
-#line 3229 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3145, 0},
-#line 4659 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3146, 0},
-#line 3197 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3147, 0},
-#line 2940 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3148, 0},
-#line 4565 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3149, 0},
-#line 5775 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3150, 0},
-#line 3231 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3151, 0},
-#line 3682 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3152, 0},
-#line 3871 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3153, 0},
-#line 3233 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3154, 0},
-#line 5488 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3155, 0},
-#line 2512 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3156, 4},
-#line 5947 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3157, 0},
-#line 1202 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3158, 4},
-#line 4529 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3159, 0},
-#line 2780 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3160, 0},
-#line 3452 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3161, 0},
-#line 2829 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3162, 0},
-#line 525 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3163, 4},
-#line 2115 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3164, 0},
-#line 6303 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3165, 0},
-#line 2722 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3166, 0},
-#line 4558 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3167, 0},
-#line 5583 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3168, 0},
-#line 3757 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3169, 0},
-#line 3190 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3170, 0},
-#line 3189 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3171, 0},
-#line 3191 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3172, 0},
-#line 5561 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3173, 0},
-#line 6341 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3174, 0},
-#line 3381 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3175, 0},
-#line 3532 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3176, 0},
-#line 3095 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3177, 0},
-#line 76 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3178, 0},
-#line 5736 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3179, 0},
-#line 3236 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3180, 0},
-#line 5646 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3181, 0},
-#line 1262 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3182, 0},
-#line 3192 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3183, 0},
-#line 3234 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3184, 0},
-#line 2960 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3185, 0},
-#line 2730 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3186, 0},
-#line 785 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3187, 0},
-#line 6468 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3188, 0},
-#line 3235 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3189, 0},
-#line 1768 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3190, 0},
-#line 787 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3191, 0},
-#line 549 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3192, 4},
-#line 3237 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3193, 0},
-#line 219 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3194, 0},
-#line 3198 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3195, 0},
-#line 220 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3196, 0},
-#line 3863 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3197, 0},
-#line 5716 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3198, 0},
-#line 4789 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3199, 0},
-#line 6125 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3200, 0},
-#line 6180 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3201, 0},
-#line 1259 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3202, 0},
-#line 4648 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3203, 0},
-#line 6482 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3204, 0},
-#line 5651 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3205, 0},
-#line 5657 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3206, 0},
-#line 3397 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3207, 0},
-#line 1195 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3208, 4},
-#line 4746 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3209, 0},
-#line 1228 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3210, 4},
-#line 4609 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3211, 0},
-#line 6156 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3212, 0},
-#line 2205 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3213, 0},
-#line 3218 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3214, 0},
-#line 1230 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3215, 4},
-#line 5685 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3216, 0},
-#line 3647 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3217, 0},
-#line 3317 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3218, 0},
-#line 2517 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3219, 4},
-#line 223 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3220, 0},
-#line 2835 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3221, 0},
-#line 4638 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3222, 0},
-#line 190 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3223, 0},
-#line 3215 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3224, 0},
-#line 2877 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3225, 0},
-#line 4033 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3226, 0},
-#line 3217 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3227, 0},
-#line 4568 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3228, 0},
-#line 2162 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3229, 0},
-#line 3103 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3230, 0},
-#line 3206 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3231, 0},
-#line 752 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3232, 0},
-#line 5610 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3233, 0},
-#line 533 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3234, 4},
-#line 1403 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3235, 0},
-#line 197 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3236, 0},
-#line 3219 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3237, 0},
-#line 3207 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3238, 0},
-#line 5500 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3239, 0},
-#line 5613 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3240, 0},
-#line 4604 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3241, 0},
-#line 1559 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3242, 0},
-#line 4200 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3243, 0},
-#line 3929 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3244, 0},
-#line 1534 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3245, 2},
-#line 2843 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3246, 0},
-#line 5600 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3247, 0},
-#line 960 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3248, 0},
-#line 5652 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3249, 0},
-#line 1897 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3250, 0},
-#line 3999 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3251, 0},
-#line 3028 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3252, 0},
-#line 3950 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3253, 0},
-#line 1036 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3254, 0},
-#line 3120 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3255, 0},
-#line 983 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3256, 0},
-#line 1914 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3257, 0},
-#line 4859 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3258, 0},
-#line 5740 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3259, 0},
-#line 3212 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3260, 0},
-#line 3862 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3261, 0},
-#line 5949 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3262, 0},
-#line 1828 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3263, 0},
-#line 2083 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3264, 0},
-#line 6432 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3265, 0},
-#line 3017 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3266, 0},
-#line 2592 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3267, 0},
-#line 3071 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3268, 0},
-#line 5030 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3269, 0},
-#line 527 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3270, 4},
-#line 5027 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3271, 0},
-#line 3766 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3272, 0},
-#line 1747 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3273, 0},
-#line 5245 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3274, 0},
-#line 5207 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3275, 0},
-#line 5289 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3276, 0},
-#line 3742 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3277, 0},
-#line 3213 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3278, 0},
-#line 6385 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3279, 0},
-#line 1297 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3280, 0},
-#line 6141 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3281, 0},
-#line 3205 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3282, 0},
-#line 657 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3283, 0},
-#line 1488 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3284, 0},
-#line 6047 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3285, 0},
-#line 4066 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3286, 0},
-#line 3279 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3287, 0},
-#line 2795 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3288, 0},
-#line 1317 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3289, 0},
-#line 3338 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3290, 0},
-#line 3220 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3291, 0},
-#line 780 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3292, 0},
-#line 3208 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3293, 0},
-#line 6472 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3294, 0},
-#line 3636 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3295, 0},
-#line 5717 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3296, 0},
-#line 2223 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3297, 0},
-#line 4167 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3298, 0},
-#line 5435 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3299, 0},
-#line 2194 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3300, 0},
-#line 1484 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3301, 0},
-#line 5748 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3302, 0},
-#line 1231 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3303, 4},
-#line 3658 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3304, 0},
-#line 1583 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3305, 0},
-#line 87 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3306, 0},
-#line 4006 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3307, 0},
-#line 1060 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3308, 0},
-#line 1043 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3309, 0},
-#line 6065 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3310, 0},
-#line 1973 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3311, 0},
-#line 2178 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3312, 0},
-#line 3221 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3313, 0},
-#line 4884 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3314, 0},
-#line 1025 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3315, 0},
-#line 6072 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3316, 0},
-#line 3491 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3317, 0},
-#line 4116 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3318, 0},
-#line 3033 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3319, 0},
-#line 4801 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3320, 0},
-#line 4168 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3321, 0},
-#line 2111 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3322, 0},
-#line 3223 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3323, 0},
-#line 5925 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3324, 0},
-#line 5306 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3325, 0},
-#line 3144 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3326, 0},
-#line 3492 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3327, 0},
-#line 6484 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3328, 0},
-#line 5300 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3329, 0},
-#line 3230 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3330, 0},
-#line 2876 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3331, 0},
-#line 3638 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3332, 0},
-#line 389 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3333, 0},
-#line 2002 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3334, 0},
-#line 4636 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3335, 0},
-#line 3639 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3336, 0},
-#line 2038 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3337, 0},
-#line 1374 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3338, 0},
-#line 2814 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3339, 0},
-#line 1554 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3340, 0},
-#line 5350 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3341, 0},
-#line 5532 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3342, 0},
-#line 4778 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3343, 0},
-#line 3593 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3344, 0},
-#line 449 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3345, 0},
-#line 3967 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3346, 0},
-#line 1000 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3347, 0},
-#line 1936 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3348, 0},
-#line 2839 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3349, 0},
-#line 4069 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3350, 0},
-#line 5403 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3351, 0},
-#line 5504 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3352, 0},
-#line 3384 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3353, 0},
-#line 2888 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3354, 0},
-#line 6411 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3355, 0},
-#line 3778 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3356, 2},
-#line 2157 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3357, 0},
-#line 2134 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3358, 0},
-#line 3722 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3359, 0},
-#line 2132 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3360, 0},
-#line 3689 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3361, 0},
-#line 779 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3362, 0},
-#line 1510 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3363, 0},
-#line 5234 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3364, 0},
-#line 2648 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3365, 0},
-#line 2174 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3366, 0},
-#line 3145 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3367, 0},
-#line 2179 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3368, 0},
-#line 2177 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3369, 0},
-#line 980 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3370, 0},
-#line 5677 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3371, 0},
-#line 1457 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3372, 0},
-#line 309 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3373, 0},
-#line 1519 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3374, 0},
-#line 3086 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3375, 0},
-#line 1183 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3376, 0},
-#line 5770 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3377, 0},
-#line 6459 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3378, 0},
-#line 1337 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3379, 0},
-#line 4357 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3380, 0},
-#line 2736 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3381, 0},
-#line 4536 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3382, 0},
-#line 5702 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3383, 0},
-#line 4439 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3384, 0},
-#line 572 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3385, 0},
-#line 4754 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3386, 0},
-#line 4381 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3387, 0},
-#line 5581 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3388, 0},
-#line 3788 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3389, 0},
-#line 3870 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3390, 0},
-#line 1251 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3391, 0},
-#line 5190 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3392, 0},
-#line 1220 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3393, 4},
-#line 3059 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3394, 0},
-#line 2808 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3395, 0},
-#line 260 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3396, 0},
-#line 5238 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3397, 0},
-#line 2093 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3398, 0},
-#line 5293 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3399, 0},
-#line 584 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3400, 0},
-#line 3135 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3401, 0},
-#line 3567 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3402, 0},
-#line 1497 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3403, 0},
-#line 3918 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3404, 0},
-#line 422 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3405, 0},
-#line 947 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3406, 0},
-#line 1883 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3407, 0},
-#line 1580 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3408, 0},
-#line 1667 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3409, 0},
-#line 3193 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3410, 0},
-#line 4269 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3411, 0},
-#line 1538 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3412, 2},
-#line 5653 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3413, 0},
-#line 5367 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3414, 0},
-#line 1826 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3415, 0},
-#line 4481 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3416, 0},
-#line 3004 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3417, 0},
-#line 3211 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3418, 0},
-#line 5282 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3419, 0},
-#line 4987 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3420, 0},
-#line 5769 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3421, 0},
-#line 2552 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3422, 4},
-#line 6123 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3423, 0},
-#line 1104 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3424, 0},
-#line 3274 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3425, 0},
-#line 3232 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3426, 0},
-#line 5262 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3427, 0},
-#line 811 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3428, 0},
-#line 5574 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3429, 0},
-#line 5824 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3430, 0},
-#line 5349 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3431, 0},
-#line 1286 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3432, 0},
-#line 2980 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3433, 0},
-#line 5208 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3434, 0},
-#line 4963 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3435, 0},
-#line 75 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3436, 0},
-#line 2653 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3437, 0},
-#line 4447 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3438, 0},
-#line 2948 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3439, 0},
-#line 5412 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3440, 0},
-#line 1520 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3441, 0},
-#line 4427 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3442, 0},
-#line 3204 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3443, 0},
-#line 1486 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3444, 0},
-#line 5462 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3445, 0},
-#line 3699 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3446, 0},
-#line 3417 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3447, 0},
-#line 4603 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3448, 0},
-#line 750 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3449, 0},
-#line 5369 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3450, 0},
-#line 5316 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3451, 0},
-#line 1530 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3452, 0},
-#line 1513 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3453, 0},
-#line 1483 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3454, 0},
-#line 1526 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3455, 0},
-#line 6127 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3456, 0},
-#line 5842 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3457, 0},
-#line 5227 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3458, 0},
-#line 3311 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3459, 0},
-#line 521 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3460, 4},
-#line 5771 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3461, 0},
-#line 3284 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3462, 0},
-#line 1843 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3463, 0},
-#line 5261 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3464, 0},
-#line 2747 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3465, 0},
-#line 3214 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3466, 0},
-#line 6040 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3467, 0},
-#line 5751 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3468, 0},
-#line 826 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3469, 0},
-#line 6177 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3470, 0},
-#line 2171 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3471, 0},
-#line 1448 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3472, 0},
-#line 2889 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3473, 0},
-#line 6349 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3474, 0},
-#line 663 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3475, 0},
-#line 4864 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3476, 0},
-#line 4403 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3477, 0},
-#line 6465 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3478, 0},
-#line 6311 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3479, 0},
-#line 5754 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3480, 0},
-#line 5303 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3481, 0},
-#line 830 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3482, 0},
-#line 6330 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3483, 0},
-#line 2135 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3484, 0},
-#line 6293 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3485, 0},
-#line 5457 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3486, 0},
-#line 3565 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3487, 4},
-#line 1387 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3488, 0},
-#line 3522 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3489, 0},
-#line 5734 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3490, 0},
-#line 2504 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3491, 4},
-#line 5948 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3492, 0},
-#line 368 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3493, 0},
-#line 3516 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3494, 0},
-#line 471 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3495, 0},
-#line 3449 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3496, 0},
-#line 3084 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3497, 0},
-#line 2939 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3498, 0},
-#line 5244 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3499, 0},
-#line 5085 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3500, 0},
-#line 4896 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3501, 0},
-#line 3210 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3502, 0},
-#line 5035 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3503, 0},
-#line 3304 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3504, 0},
-#line 6299 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3505, 0},
-#line 3014 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3506, 0},
-#line 1502 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3507, 0},
-#line 3111 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3508, 0},
-#line 4197 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3509, 0},
-#line 4672 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3510, 4},
-#line 4570 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3511, 0},
-#line 1529 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3512, 0},
-#line 339 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3513, 0},
-#line 4234 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3514, 0},
-#line 2443 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3515, 0},
-#line 6043 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3516, 0},
-#line 5398 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3517, 0},
-#line 4345 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3518, 0},
-#line 5360 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3519, 0},
-#line 2086 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3520, 0},
-#line 2116 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3521, 0},
-#line 1722 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3522, 0},
-#line 6337 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3523, 0},
-#line 3678 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3524, 0},
-#line 258 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3525, 0},
-#line 2139 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3526, 0},
-#line 841 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3527, 0},
-#line 2764 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3528, 0},
-#line 1745 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3529, 0},
-#line 1772 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3530, 0},
-#line 4547 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3531, 0},
-#line 4158 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3532, 0},
-#line 2161 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3533, 0},
-#line 3355 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3534, 0},
-#line 3148 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3535, 0},
-#line 1718 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3536, 0},
-#line 2600 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3537, 0},
-#line 5476 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3538, 0},
-#line 5741 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3539, 0},
-#line 3620 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3540, 0},
-#line 3112 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3541, 0},
-#line 6179 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3542, 0},
-#line 5501 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3543, 0},
-#line 1509 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3544, 0},
-#line 2242 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3545, 0},
-#line 1797 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3546, 0},
-#line 5343 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3547, 0},
-#line 1393 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3548, 0},
-#line 784 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3549, 0},
-#line 1063 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3550, 0},
-#line 4103 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3551, 0},
-#line 293 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3552, 0},
-#line 6077 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3553, 0},
-#line 6234 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3554, 0},
-#line 1109 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3555, 0},
-#line 838 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3556, 1},
-#line 1558 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3557, 0},
-#line 1078 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3558, 0},
-#line 2203 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3559, 0},
-#line 1160 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3560, 0},
-#line 4768 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3561, 0},
-#line 2249 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3562, 0},
-#line 2398 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3563, 0},
-#line 3770 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3564, 0},
-#line 3240 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3565, 0},
-#line 6050 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3566, 0},
-#line 1562 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3567, 0},
-#line 501 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3568, 0},
-#line 3640 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3569, 0},
-#line 83 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3570, 0},
-#line 3241 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3571, 0},
-#line 3203 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3572, 0},
-#line 6004 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3573, 0},
-#line 511 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3574, 4},
-#line 5746 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3575, 0},
-#line 3637 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3576, 0},
-#line 6105 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3577, 0},
-#line 3322 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3578, 0},
-#line 5995 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3579, 0},
-#line 4715 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3580, 0},
-#line 4633 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3581, 0},
-#line 5463 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3582, 0},
-#line 2224 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3583, 0},
-#line 4489 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3584, 0},
-#line 6342 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3585, 0},
-#line 4800 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3586, 0},
-#line 3029 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3587, 0},
-#line 5322 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3588, 0},
-#line 5731 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3589, 0},
-#line 3526 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3590, 0},
-#line 2153 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3591, 0},
-#line 5029 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3592, 0},
-#line 821 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3593, 0},
-#line 5229 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3594, 0},
-#line 4843 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3595, 0},
-#line 3383 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3596, 0},
-#line 3396 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3597, 0},
-#line 5807 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3598, 0},
-#line 5066 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3599, 4},
-#line 3357 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3600, 0},
-#line 348 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3601, 0},
-#line 3242 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3602, 0},
-#line 2756 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3603, 0},
-#line 4677 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3604, 0},
-#line 6052 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3605, 0},
-#line 1396 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3606, 0},
-#line 6326 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3607, 0},
-#line 2182 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3608, 0},
-#line 4689 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3609, 0},
-#line 680 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3610, 0},
-#line 1803 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3611, 0},
-#line 4680 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3612, 0},
-#line 2099 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3613, 0},
-#line 4277 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3614, 0},
-#line 4685 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3615, 0},
-#line 1858 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3616, 4},
-#line 5249 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3617, 0},
-#line 4624 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3618, 0},
-#line 3860 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3619, 1},
-#line 4933 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3620, 0},
-#line 4617 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3621, 0},
-#line 4932 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3622, 0},
-#line 5232 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3623, 0},
-#line 1232 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3624, 4},
-#line 6027 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3625, 0},
-#line 3719 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3626, 0},
-#line 6161 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3627, 0},
-#line 661 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3628, 0},
-#line 3681 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3629, 0},
-#line 757 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3630, 0},
-#line 455 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3631, 0},
-#line 1775 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3632, 0},
-#line 2336 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3633, 0},
-#line 829 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3634, 0},
-#line 4029 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3635, 0},
-#line 3323 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3636, 0},
-#line 1758 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3637, 0},
-#line 3409 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3638, 0},
-#line 5438 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3639, 0},
-#line 2158 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3640, 0},
-#line 966 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3641, 0},
-#line 1541 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3642, 0},
-#line 3632 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3643, 0},
-#line 90 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3644, 0},
-#line 5922 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3645, 0},
-#line 4109 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3646, 0},
-#line 3701 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3647, 0},
-#line 3499 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3648, 0},
-#line 136 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3649, 0},
-#line 4260 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3650, 0},
-#line 4803 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3651, 0},
-#line 5637 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3652, 0},
-#line 4065 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3653, 0},
-#line 4072 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3654, 0},
-#line 123 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3655, 0},
-#line 3729 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3656, 0},
-#line 4686 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3657, 0},
-#line 2155 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3658, 0},
-#line 4579 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3659, 2},
-#line 5193 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3660, 0},
-#line 5718 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3661, 0},
-#line 3939 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3662, 0},
-#line 974 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3663, 0},
-#line 3364 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3664, 0},
-#line 3787 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3665, 0},
-#line 4284 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3666, 0},
-#line 5231 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3667, 0},
-#line 5071 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3668, 0},
-#line 2225 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3669, 0},
-#line 900 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3670, 0},
-#line 6091 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3671, 4},
-#line 1842 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3672, 0},
-#line 2788 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3673, 0},
-#line 2799 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3674, 0},
-#line 3506 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3675, 0},
-#line 3630 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3676, 0},
-#line 6492 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3677, 0},
-#line 6449 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3678, 0},
-#line 2318 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3679, 0},
-#line 3706 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3680, 0},
-#line 2644 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3681, 0},
-#line 5386 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3682, 0},
-#line 4886 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3683, 0},
-#line 5269 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3684, 0},
-#line 2792 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3685, 0},
-#line 2131 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3686, 0},
-#line 5257 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3687, 0},
-#line 1482 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3688, 0},
-#line 1394 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3689, 0},
-#line 4731 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3690, 0},
-#line 3723 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3691, 0},
-#line 5385 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3692, 0},
-#line 3661 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3693, 0},
-#line 5235 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3694, 0},
-#line 1404 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3695, 0},
-#line 6191 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3696, 0},
-#line 4974 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3697, 0},
-#line 98 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3698, 0},
-#line 3497 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3699, 0},
-#line 4792 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3700, 0},
-#line 3063 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3701, 0},
-#line 5683 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3702, 0},
-#line 5697 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3703, 0},
-#line 3006 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3704, 0},
-#line 6416 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3705, 0},
-#line 5441 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3706, 0},
-#line 4166 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3707, 0},
-#line 3153 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3708, 0},
-#line 4326 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3709, 0},
-#line 1531 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3710, 0},
-#line 3845 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3711, 0},
-#line 4863 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3712, 0},
-#line 4980 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3713, 0},
-#line 3019 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3714, 0},
-#line 4888 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3715, 0},
-#line 6198 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3716, 0},
-#line 229 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3717, 4},
-#line 660 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3718, 0},
-#line 1700 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3719, 0},
-#line 5265 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3720, 0},
-#line 5452 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3721, 0},
-#line 2886 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3722, 0},
-#line 1535 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3723, 0},
-#line 899 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3724, 4},
-#line 5680 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3725, 0},
-#line 3698 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3726, 0},
-#line 3238 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3727, 0},
-#line 1539 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3728, 0},
-#line 2562 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3729, 0},
-#line 1487 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3730, 0},
-#line 5872 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3731, 0},
-#line 4660 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3732, 0},
-#line 3789 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3733, 0},
-#line 3392 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3734, 0},
-#line 4679 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3735, 0},
-#line 1674 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3736, 0},
-#line 3463 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3737, 0},
-#line 243 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3738, 0},
-#line 3451 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3739, 0},
-#line 4616 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3740, 0},
-#line 5028 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3741, 0},
-#line 2124 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3742, 0},
-#line 5863 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3743, 0},
-#line 3643 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3744, 0},
-#line 3627 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3745, 0},
-#line 4988 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3746, 0},
-#line 3196 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3747, 0},
-#line 5710 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3748, 0},
-#line 4692 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3749, 0},
-#line 3067 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3750, 0},
-#line 5268 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3751, 0},
-#line 3587 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3752, 0},
-#line 3477 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3753, 0},
-#line 3373 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3754, 0},
-#line 3077 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3755, 0},
-#line 5055 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3756, 4},
-#line 5056 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3757, 4},
-#line 4183 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3758, 0},
-#line 3401 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3759, 0},
-#line 1506 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3760, 0},
-#line 1511 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3761, 0},
-#line 5991 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3762, 0},
-#line 3537 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3763, 0},
-#line 4240 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3764, 0},
-#line 2337 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3765, 0},
-#line 3239 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3766, 0},
-#line 1528 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3767, 0},
-#line 5696 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3768, 0},
-#line 4589 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3769, 0},
-#line 5415 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3770, 0},
-#line 161 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3771, 0},
-#line 4897 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3772, 0},
-#line 2961 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3773, 0},
-#line 5708 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3774, 0},
-#line 3042 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3775, 0},
-#line 2047 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3776, 0},
-#line 5874 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3777, 0},
-#line 3464 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3778, 0},
-#line 1225 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3779, 4},
-#line 1091 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3780, 0},
-#line 5594 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3781, 0},
-#line 4592 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3782, 0},
-#line 4658 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3783, 0},
-#line 6039 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3784, 0},
-#line 4057 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3785, 0},
-#line 5072 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3786, 0},
-#line 2853 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3787, 0},
-#line 2852 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3788, 0},
-#line 2186 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3789, 0},
-#line 5521 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3790, 0},
-#line 1727 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3791, 0},
-#line 4502 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3792, 0},
-#line 658 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3793, 0},
-#line 4681 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3794, 0},
-#line 5209 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3795, 0},
-#line 3886 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3796, 0},
-#line 2540 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3797, 4},
-#line 6060 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3798, 4},
-#line 901 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3799, 0},
-#line 1820 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3800, 0},
-#line 3745 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3801, 0},
-#line 5259 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3802, 0},
-#line 5345 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3803, 0},
-#line 5444 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3804, 0},
-#line 5701 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3805, 0},
-#line 4241 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3806, 0},
-#line 1271 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3807, 0},
-#line 1472 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3808, 0},
-#line 4564 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3809, 0},
-#line 6392 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3810, 0},
-#line 2649 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3811, 0},
-#line 4561 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3812, 0},
-#line 1213 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3813, 4},
-#line 4623 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3814, 0},
-#line 3100 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3815, 0},
-#line 6199 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3816, 0},
-#line 5704 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3817, 0},
-#line 5699 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3818, 0},
-#line 1725 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3819, 0},
-#line 6408 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3820, 0},
-#line 1532 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3821, 0},
-#line 5698 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3822, 0},
-#line 6020 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3823, 0},
-#line 2647 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3824, 0},
-#line 4739 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3825, 0},
-#line 5724 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3826, 0},
-#line 5239 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3827, 0},
-#line 5707 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3828, 0},
-#line 3746 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3829, 0},
-#line 4320 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3830, 0},
-#line 4832 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3831, 0},
-#line 4678 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3832, 0},
-#line 5712 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3833, 0},
-#line 4695 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3834, 0},
-#line 5711 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3835, 0},
-#line 4533 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3836, 0},
-#line 1148 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3837, 0},
-#line 3460 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3838, 0},
-#line 3776 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3839, 0},
-#line 322 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3840, 0},
-#line 3925 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3841, 0},
-#line 2100 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3842, 0},
-#line 4295 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3843, 0},
-#line 5276 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3844, 0},
-#line 955 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3845, 0},
-#line 1893 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3846, 0},
-#line 5197 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3847, 0},
-#line 4107 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3848, 0},
-#line 2753 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3849, 0},
-#line 1589 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3850, 0},
-#line 1555 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3851, 0},
-#line 4702 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3852, 0},
-#line 1508 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3853, 0},
-#line 815 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3854, 0},
-#line 4653 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3855, 0},
-#line 2403 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3856, 0},
-#line 3607 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3857, 0},
-#line 2221 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3858, 0},
-#line 585 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3859, 0},
-#line 4989 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3860, 0},
-#line 111 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3861, 0},
-#line 5298 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3862, 0},
-#line 2414 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3863, 0},
-#line 2258 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3864, 4},
-#line 4704 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3865, 0},
-#line 3540 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3866, 0},
-#line 4683 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3867, 0},
-#line 4995 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3868, 0},
-#line 131 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3869, 0},
-#line 4542 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3870, 0},
-#line 1293 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3871, 0},
-#line 1994 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3872, 0},
-#line 3227 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3873, 0},
-#line 5689 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3874, 0},
-#line 4719 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3875, 0},
-#line 2662 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3876, 4},
-#line 5079 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3877, 0},
-#line 4966 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3878, 0},
-#line 3541 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3879, 0},
-#line 5681 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3880, 0},
-#line 6104 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3881, 0},
-#line 6466 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3882, 0},
-#line 3772 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3883, 0},
-#line 3424 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3884, 0},
-#line 5034 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3885, 0},
-#line 2763 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3886, 0},
-#line 1759 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3887, 0},
-#line 3372 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3888, 0},
-#line 5440 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3889, 0},
-#line 3254 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3890, 0},
-#line 5781 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3891, 0},
-#line 4587 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3892, 0},
-#line 2823 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3893, 0},
-#line 5826 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3894, 0},
-#line 208 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3895, 0},
-#line 3194 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3896, 0},
-#line 6099 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3897, 0},
-#line 4593 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3898, 0},
-#line 394 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3899, 0},
-#line 421 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3900, 0},
-#line 6128 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3901, 0},
-#line 4894 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3902, 0},
-#line 4621 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3903, 0},
-#line 659 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3904, 0},
-#line 5700 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3905, 0},
-#line 2588 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3906, 0},
-#line 4947 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3907, 0},
-#line 4205 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3908, 0},
-#line 6511 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3909, 0},
-#line 6154 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3910, 0},
-#line 5086 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3911, 0},
-#line 5352 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3912, 0},
-#line 4508 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3913, 0},
-#line 4892 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3914, 0},
-#line 3329 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3915, 0},
-#line 96 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3916, 0},
-#line 3107 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3917, 0},
-#line 6467 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3918, 0},
-#line 2506 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3919, 4},
-#line 3431 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3920, 0},
-#line 3610 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3921, 0},
-#line 233 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3922, 0},
-#line 3560 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3923, 0},
-#line 5280 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3924, 0},
-#line 3851 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3925, 0},
-#line 105 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3926, 0},
-#line 5460 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3927, 0},
-#line 1840 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3928, 0},
-#line 4574 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3929, 0},
-#line 4945 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3930, 0},
-#line 5732 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3931, 0},
-#line 5867 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3932, 0},
-#line 5075 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3933, 0},
-#line 6229 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3934, 0},
-#line 2445 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3935, 0},
-#line 3114 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3936, 0},
-#line 6068 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3937, 0},
-#line 5546 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3938, 0},
-#line 2822 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3939, 0},
-#line 5709 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3940, 0},
-#line 4353 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3941, 0},
-#line 2335 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3942, 0},
-#line 2392 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3943, 0},
-#line 4292 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3944, 0},
-#line 1764 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3945, 0},
-#line 2491 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3946, 4},
-#line 110 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3947, 0},
-#line 5478 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3948, 0},
-#line 5601 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3949, 0},
-#line 1492 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3950, 0},
-#line 5791 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3951, 0},
-#line 5752 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3952, 0},
-#line 2991 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3953, 0},
-#line 346 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3954, 0},
-#line 6379 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3955, 0},
-#line 3222 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3956, 0},
-#line 397 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3957, 0},
-#line 3457 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3958, 0},
-#line 2481 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3959, 4},
-#line 927 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3960, 0},
-#line 1477 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3961, 0},
-#line 5882 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3962, 0},
-#line 1077 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3963, 0},
-#line 2927 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3964, 0},
-#line 1476 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3965, 0},
-#line 1525 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3966, 0},
-#line 6308 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3967, 0},
-#line 6201 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3968, 0},
-#line 1545 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3969, 0},
-#line 1247 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3970, 4},
-#line 1069 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3971, 0},
-#line 5288 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3972, 0},
-#line 3895 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3973, 0},
-#line 5380 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3974, 0},
-#line 1544 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3975, 0},
-#line 5396 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3976, 0},
-#line 4030 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3977, 0},
-#line 6254 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3978, 0},
-#line 569 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3979, 0},
-#line 4687 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3980, 0},
-#line 4718 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3981, 0},
-#line 5461 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3982, 0},
-#line 5688 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3983, 0},
-#line 4594 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3984, 0},
-#line 3548 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3985, 0},
-#line 3841 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3986, 0},
-#line 4965 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3987, 0},
-#line 1516 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3988, 0},
-#line 1132 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3989, 0},
-#line 1996 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3990, 0},
-#line 2166 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3991, 0},
-#line 4691 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3992, 0},
-#line 5074 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3993, 0},
-#line 3386 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3994, 0},
-#line 461 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3995, 0},
-#line 385 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3996, 0},
-#line 5921 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3997, 0},
-#line 5626 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3998, 0},
-#line 1397 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3999, 0},
-#line 2733 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4000, 0},
-#line 6434 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4001, 0},
-#line 1264 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4002, 0},
-#line 2986 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4003, 0},
-#line 6016 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4004, 0},
-#line 5381 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4005, 0},
-#line 5348 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4006, 0},
-#line 2804 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4007, 0},
-#line 6063 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4008, 4},
-#line 5502 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4009, 0},
-#line 3224 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4010, 0},
-#line 4136 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4011, 0},
-#line 5467 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4012, 0},
-#line 3569 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4013, 0},
-#line 3358 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4014, 0},
-#line 4929 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4015, 0},
-#line 1563 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4016, 0},
-#line 1082 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4017, 0},
-#line 5784 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4018, 0},
-#line 3553 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4019, 0},
-#line 3692 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4020, 0},
-#line 2740 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4021, 0},
-#line 1767 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4022, 0},
-#line 4641 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4023, 0},
-#line 4674 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4024, 0},
-#line 3784 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4025, 0},
-#line 3614 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4026, 0},
-#line 5682 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4027, 0},
-#line 4485 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4028, 0},
-#line 5897 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4029, 0},
-#line 1088 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4030, 0},
-#line 2092 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4031, 0},
-#line 602 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4032, 0},
-#line 4921 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4033, 0},
-#line 3202 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4034, 0},
-#line 4927 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4035, 0},
-#line 6183 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4036, 0},
-#line 6515 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4037, 0},
-#line 1763 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4038, 0},
-#line 1085 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4039, 0},
-#line 4741 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4040, 0},
-#line 405 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4041, 0},
-#line 5196 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4042, 0},
-#line 6413 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4043, 0},
-#line 3152 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4044, 0},
-#line 2949 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4045, 0},
-#line 3652 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4046, 0},
-#line 1789 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4047, 0},
-#line 598 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4048, 0},
-#line 3389 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4049, 0},
-#line 2160 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4050, 0},
-#line 6314 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4051, 0},
-#line 5662 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4052, 0},
-#line 4714 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4053, 0},
-#line 2925 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4054, 0},
-#line 4517 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4055, 0},
-#line 3727 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4056, 0},
-#line 413 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4057, 0},
-#line 2979 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4058, 0},
-#line 5065 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4059, 4},
-#line 2947 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4060, 2},
-#line 2130 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4061, 0},
-#line 2141 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4062, 0},
-#line 1733 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4063, 0},
-#line 6512 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4064, 0},
-#line 1591 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4065, 0},
-#line 2803 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4066, 0},
-#line 2542 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4067, 4},
-#line 5116 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4068, 0},
-#line 5087 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4069, 4},
-#line 5274 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4070, 0},
-#line 3054 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4071, 0},
-#line 2548 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4072, 4},
-#line 6407 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4073, 0},
-#line 3641 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4074, 0},
-#line 306 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4075, 0},
-#line 601 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4076, 0},
-#line 2903 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4077, 0},
-#line 6192 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4078, 0},
-#line 3258 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4079, 0},
-#line 4298 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4080, 0},
-#line 2344 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4081, 0},
-#line 1737 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4082, 0},
-#line 4251 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4083, 0},
-#line 2755 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4084, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1355, 0},
+#line 2352 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1356, 0},
 #line 1766 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4085, 0},
-#line 4922 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4086, 0},
-#line 1120 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4087, 0},
-#line 4507 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4088, 0},
-#line 85 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4089, 0},
-#line 2346 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4090, 0},
-#line 1141 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4091, 0},
-#line 3382 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4092, 0},
-#line 4190 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4093, 0},
-#line 3172 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4094, 0},
-#line 2728 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4095, 0},
-#line 391 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4096, 0},
-#line 2189 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4097, 0},
-#line 2399 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4098, 0},
-#line 3807 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4099, 0},
-#line 6232 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4100, 0},
-#line 2319 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4101, 0},
-#line 5287 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4102, 0},
-#line 4934 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4103, 0},
-#line 2040 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4104, 0},
-#line 4543 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4105, 0},
-#line 173 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4106, 0},
-#line 4994 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4107, 0},
-#line 3865 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4108, 0},
-#line 479 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4109, 0},
-#line 2371 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4110, 0},
-#line 808 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4111, 0},
-#line 4958 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4112, 0},
-#line 2393 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4113, 0},
-#line 5388 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4114, 0},
-#line 216 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4115, 0},
-#line 1807 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4116, 0},
-#line 1719 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4117, 0},
-#line 6338 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4118, 0},
-#line 3779 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4119, 0},
-#line 4468 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4120, 0},
-#line 6051 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4121, 0},
-#line 1169 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4122, 0},
-#line 5084 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4123, 0},
-#line 2201 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4124, 0},
-#line 578 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4125, 0},
-#line 2957 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4126, 0},
-#line 3150 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4127, 0},
-#line 1145 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4128, 0},
-#line 6519 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4129, 0},
-#line 3283 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4130, 0},
-#line 5841 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4131, 0},
-#line 4610 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4132, 0},
-#line 5644 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4133, 0},
-#line 2085 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4134, 0},
-#line 1083 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4135, 0},
-#line 5271 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4136, 0},
-#line 4798 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4137, 0},
-#line 6456 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4138, 0},
-#line 4464 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4139, 0},
-#line 2898 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4140, 0},
-#line 761 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4141, 0},
-#line 4026 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4142, 0},
-#line 1072 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4143, 0},
-#line 621 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4144, 0},
-#line 4713 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4145, 0},
-#line 634 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4146, 0},
-#line 2355 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4147, 4},
-#line 6169 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4148, 0},
-#line 2154 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4149, 0},
-#line 5483 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4150, 0},
-#line 3404 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4151, 0},
-#line 5250 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4152, 0},
-#line 1673 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4153, 0},
-#line 4024 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4154, 0},
-#line 1712 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4155, 0},
-#line 3657 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4156, 0},
-#line 3201 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4157, 0},
-#line 5590 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4158, 0},
-#line 5974 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4159, 0},
-#line 2106 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4160, 0},
-#line 3326 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4161, 0},
-#line 224 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4162, 0},
-#line 151 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4163, 0},
-#line 5665 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4164, 0},
-#line 2169 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4165, 0},
-#line 1117 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4166, 0},
-#line 5575 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4167, 0},
-#line 615 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4168, 0},
-#line 3809 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4169, 0},
-#line 5648 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4170, 0},
-#line 5635 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4171, 0},
-#line 1181 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4172, 0},
-#line 2081 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4173, 0},
-#line 781 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4174, 0},
-#line 4196 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4175, 0},
-#line 59 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4176, 0},
-#line 2298 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4177, 0},
-#line 2091 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4178, 0},
-#line 4992 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4179, 0},
-#line 5088 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4180, 0},
-#line 6490 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4181, 0},
-#line 3064 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4182, 0},
-#line 6431 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4183, 0},
-#line 2658 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4184, 0},
-#line 1575 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4185, 0},
-#line 3173 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4186, 0},
-#line 3539 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4187, 0},
-#line 3852 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4188, 0},
-#line 60 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4189, 0},
-#line 2098 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4190, 0},
-#line 5279 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4191, 0},
-#line 222 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4192, 0},
-#line 1154 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4193, 0},
-#line 588 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4194, 0},
-#line 3756 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4195, 0},
-#line 1790 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4196, 0},
-#line 6083 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4197, 0},
-#line 3551 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4198, 0},
-#line 2630 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4199, 0},
-#line 446 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4200, 0},
-#line 4187 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4201, 0},
-#line 2039 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4202, 0},
-#line 31 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4203, 0},
-#line 1504 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4204, 0},
-#line 4991 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4205, 0},
-#line 2752 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4206, 0},
-#line 3773 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4207, 0},
-#line 6269 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4208, 0},
-#line 6194 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4209, 0},
-#line 27 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4210, 4},
-#line 2241 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4211, 0},
-#line 5609 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4212, 0},
-#line 3597 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4213, 0},
-#line 2933 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4214, 0},
-#line 2282 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4215, 0},
-#line 3168 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4216, 0},
-#line 5278 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4217, 0},
-#line 2439 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4218, 0},
-#line 2743 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4219, 0},
-#line 6414 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4220, 0},
-#line 4294 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4221, 0},
-#line 2487 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4222, 4},
-#line 3169 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4223, 0},
-#line 143 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4224, 0},
-#line 5068 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4225, 4},
-#line 5458 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4226, 0},
-#line 675 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4227, 0},
-#line 5584 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4228, 0},
-#line 6167 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4229, 0},
-#line 4203 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4230, 0},
-#line 2599 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4231, 0},
-#line 4948 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4232, 0},
-#line 1629 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4233, 4},
-#line 4218 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4234, 0},
-#line 1493 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4235, 0},
-#line 4272 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4236, 0},
-#line 5785 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4237, 0},
-#line 2064 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4238, 0},
-#line 3677 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4239, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1357, 0},
+#line 3439 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1358, 0},
+#line 1351 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1359, 0},
+#line 3095 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1360, 0},
+#line 2234 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1361, 0},
+#line 3671 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1362, 1},
+#line 2800 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1363, 0},
+#line 6560 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1364, 0},
 #line 5837 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4240, 0},
-#line 2584 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4241, 0},
-#line 4990 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4242, 0},
-#line 181 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4243, 0},
-#line 1106 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4244, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1365, 0},
+#line 1441 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1366, 0},
+#line 6117 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1367, 0},
+#line 1459 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1368, 0},
+#line 2138 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1369, 0},
+#line 4780 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1370, 0},
+#line 1747 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1371, 0},
+#line 6063 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1372, 0},
+#line 6084 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1373, 0},
+#line 2959 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1374, 0},
+#line 3866 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1375, 0},
+#line 516 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1376, 4},
+#line 3894 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1377, 0},
+#line 976 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1378, 0},
+#line 1921 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1379, 0},
+#line 5874 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1380, 0},
+#line 2907 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1381, 0},
+#line 2237 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1382, 0},
+#line 3378 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1383, 0},
+#line 3653 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1384, 0},
+#line 857 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1385, 0},
+#line 572 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1386, 0},
+#line 3884 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1387, 0},
+#line 2631 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1388, 0},
+#line 4834 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1389, 0},
+#line 1238 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1390, 4},
+#line 3717 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1391, 0},
+#line 4045 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1392, 0},
+#line 3404 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1393, 0},
+#line 1315 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1394, 0},
+#line 1185 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1395, 0},
+#line 3723 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1396, 0},
+#line 784 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1397, 0},
+#line 480 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1398, 0},
+#line 3508 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1399, 0},
+#line 2821 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1400, 0},
+#line 6505 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1401, 0},
+#line 3437 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1402, 0},
+#line 3550 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1403, 0},
+#line 3522 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1404, 0},
+#line 2580 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1405, 0},
+#line 3680 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1406, 0},
+#line 3544 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1407, 0},
+#line 3651 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1408, 0},
+#line 4868 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1409, 0},
+#line 3442 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1410, 0},
+#line 3083 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1411, 0},
+#line 1157 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1412, 0},
+#line 3492 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1413, 0},
+#line 2922 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1414, 0},
+#line 142 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1415, 0},
+#line 3989 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1416, 0},
+#line 5926 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1417, 0},
+#line 3767 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1418, 0},
+#line 1003 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1419, 0},
+#line 1946 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1420, 0},
+#line 4813 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1421, 0},
+#line 2587 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1422, 0},
+#line 4826 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1423, 0},
+#line 3511 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1424, 0},
+#line 3873 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1425, 0},
+#line 3512 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1426, 0},
+#line 3509 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1427, 0},
+#line 3555 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1428, 0},
+#line 2219 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1429, 0},
+#line 1341 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1430, 0},
+#line 3446 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1431, 0},
+#line 1194 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1432, 0},
+#line 2981 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1433, 0},
+#line 6558 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1434, 0},
+#line 4870 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1435, 0},
+#line 2088 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1436, 0},
+#line 3342 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1437, 0},
+#line 3548 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1438, 0},
+#line 3481 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1439, 0},
+#line 3443 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1440, 0},
+#line 1961 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1441, 0},
+#line 2869 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1442, 0},
+#line 449 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1443, 0},
+#line 5887 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1444, 0},
+#line 2231 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1445, 0},
+#line 1493 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1446, 0},
+#line 2471 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1447, 0},
+#line 3371 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1448, 0},
+#line 1398 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1449, 0},
+#line 5834 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1450, 0},
+#line 3542 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1451, 0},
+#line 2377 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1452, 0},
+#line 448 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1453, 0},
+#line 6447 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1454, 0},
+#line 5930 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1455, 0},
+#line 411 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1456, 0},
+#line 2605 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1457, 0},
+#line 308 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1458, 0},
+#line 3038 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1459, 0},
+#line 6506 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1460, 2},
+#line 3853 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1461, 0},
+#line 2132 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1462, 0},
+#line 3851 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1463, 0},
+#line 3510 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1464, 0},
+#line 2438 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1465, 0},
+#line 2296 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1466, 0},
+#line 1265 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1467, 0},
+#line 1875 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1468, 4},
+#line 3552 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1469, 0},
+#line 2424 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1470, 0},
+#line 4062 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1471, 0},
+#line 2764 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1472, 0},
+#line 330 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1473, 0},
+#line 2106 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1474, 0},
+#line 2423 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1475, 0},
+#line 2139 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1476, 0},
+#line 400 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1477, 0},
+#line 5972 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1478, 0},
+#line 2813 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1479, 0},
+#line 3123 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1480, 0},
+#line 3649 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1481, 0},
+#line 4084 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1482, 0},
+#line 3529 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1483, 0},
+#line 5995 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1484, 0},
+#line 3105 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1485, 0},
+#line 3082 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1486, 0},
+#line 1471 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1487, 0},
+#line 3516 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1488, 0},
+#line 3930 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1489, 0},
+#line 2862 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1490, 0},
+#line 3477 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1491, 0},
+#line 1169 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1492, 0},
+#line 1857 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1493, 0},
+#line 6131 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1494, 4},
+#line 6538 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1495, 0},
+#line 172 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1496, 0},
+#line 3810 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1497, 0},
+#line 6047 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1498, 0},
+#line 207 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1499, 0},
+#line 823 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1500, 0},
+#line 3091 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1501, 0},
+#line 1184 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1502, 0},
+#line 3090 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1503, 0},
+#line 3528 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1504, 0},
+#line 6484 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1505, 0},
+#line 4078 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1506, 0},
+#line 2301 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1507, 0},
+#line 2069 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1508, 0},
+#line 5932 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1509, 0},
+#line 2801 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1510, 0},
+#line 4149 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1511, 0},
+#line 4758 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1512, 0},
+#line 3706 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1513, 0},
+#line 3343 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1514, 0},
+#line 2079 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1515, 0},
+#line 2849 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1516, 0},
+#line 6125 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1517, 0},
+#line 6045 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1518, 0},
+#line 1180 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1519, 0},
+#line 778 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1520, 0},
+#line 3144 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1521, 0},
+#line 3553 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1522, 0},
+#line 6073 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1523, 0},
+#line 2210 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1524, 0},
+#line 6054 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1525, 0},
+#line 3440 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1526, 0},
+#line 2520 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1527, 4},
+#line 209 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1528, 0},
+#line 176 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1529, 0},
+#line 3712 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1530, 0},
+#line 5977 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1531, 0},
+#line 3003 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1532, 0},
+#line 4862 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1533, 0},
+#line 6490 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1534, 0},
+#line 3558 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1535, 0},
+#line 4839 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1536, 0},
+#line 1244 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1537, 4},
+#line 3768 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1538, 0},
+#line 4172 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1539, 0},
+#line 1484 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1540, 0},
+#line 2921 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1541, 0},
+#line 2290 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1542, 0},
+#line 2086 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1543, 0},
+#line 3063 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1544, 0},
+#line 240 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1545, 0},
+#line 2071 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1546, 0},
+#line 6487 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1547, 0},
+#line 3880 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1548, 0},
+#line 6522 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1549, 0},
+#line 2318 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1550, 0},
+#line 2454 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1551, 0},
+#line 1801 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1552, 0},
+#line 370 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1553, 0},
+#line 295 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1554, 0},
+#line 4167 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1555, 0},
+#line 6003 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1556, 0},
+#line 1775 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1557, 0},
+#line 5978 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1558, 0},
+#line 2098 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1559, 0},
+#line 2521 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1560, 4},
+#line 421 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1561, 0},
+#line 2609 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1562, 0},
+#line 5970 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1563, 0},
+#line 3120 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1564, 0},
+#line 4879 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1565, 0},
+#line 4108 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1566, 0},
+#line 206 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1567, 0},
+#line 190 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1568, 0},
+#line 5996 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1569, 0},
+#line 170 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1570, 0},
+#line 2794 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1571, 0},
+#line 3559 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1572, 0},
+#line 166 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1573, 0},
+#line 3357 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1574, 0},
+#line 6433 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1575, 0},
+#line 3808 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1576, 0},
+#line 354 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1577, 0},
+#line 4797 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1578, 0},
+#line 3471 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1579, 0},
+#line 3355 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1580, 0},
+#line 2831 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1581, 0},
+#line 2137 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1582, 0},
+#line 6033 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1583, 0},
+#line 2868 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1584, 0},
+#line 5975 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1585, 0},
+#line 2158 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1586, 0},
+#line 6036 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1587, 0},
+#line 2610 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1588, 0},
+#line 2122 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1589, 0},
+#line 3752 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1590, 0},
+#line 3133 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1591, 0},
+#line 3514 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1592, 0},
+#line 1429 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1593, 0},
+#line 439 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1594, 0},
+#line 451 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1595, 0},
+#line 1798 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1596, 0},
+#line 3534 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1597, 0},
+#line 392 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1598, 0},
+#line 6496 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1599, 0},
+#line 403 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1600, 0},
+#line 5939 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1601, 0},
+#line 2940 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1602, 0},
+#line 2754 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1603, 0},
+#line 3527 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1604, 0},
+#line 771 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1605, 0},
+#line 2851 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1606, 0},
+#line 3673 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1607, 0},
+#line 794 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1608, 0},
+#line 388 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1609, 0},
+#line 3116 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1610, 0},
+#line 2209 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1611, 0},
+#line 1424 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1612, 0},
+#line 2320 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1613, 0},
+#line 2933 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1614, 0},
+#line 3869 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1615, 0},
+#line 4162 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1616, 0},
+#line 3928 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1617, 0},
+#line 795 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1618, 0},
+#line 4088 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1619, 0},
+#line 3351 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1620, 0},
+#line 3142 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1621, 0},
+#line 3106 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1622, 0},
+#line 3546 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1623, 0},
+#line 5842 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1624, 0},
+#line 5931 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1625, 0},
+#line 6018 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1626, 0},
+#line 673 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1627, 0},
+#line 3474 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1628, 0},
+#line 1785 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1629, 0},
+#line 167 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1630, 0},
+#line 2126 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1631, 0},
+#line 1421 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1632, 0},
+#line 2453 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1633, 0},
+#line 1805 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1634, 0},
+#line 2786 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1635, 0},
+#line 2407 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1636, 0},
+#line 223 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1637, 0},
+#line 2761 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1638, 0},
+#line 2993 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1639, 0},
+#line 6512 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1640, 0},
+#line 2091 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1641, 0},
+#line 1232 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1642, 0},
+#line 2639 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1643, 0},
+#line 6114 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1644, 0},
+#line 2848 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1645, 0},
+#line 2288 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1646, 4},
+#line 762 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1647, 0},
+#line 2411 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1648, 0},
+#line 3523 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1649, 0},
+#line 3771 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1650, 0},
+#line 1116 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1651, 0},
+#line 3530 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1652, 0},
+#line 1266 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1653, 0},
+#line 808 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1654, 0},
+#line 2622 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1655, 0},
+#line 3756 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1656, 0},
+#line 4777 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1657, 0},
+#line 5962 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1658, 0},
+#line 3014 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1659, 0},
+#line 2021 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1660, 0},
+#line 5985 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1661, 0},
+#line 759 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1662, 0},
+#line 2081 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1663, 0},
+#line 4105 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1664, 0},
+#line 4169 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1665, 0},
+#line 3388 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1666, 0},
+#line 3661 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1667, 0},
+#line 3533 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1668, 0},
+#line 3716 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1669, 0},
 #line 3749 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4245, 4},
-#line 1645 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4246, 4},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1670, 0},
+#line 119 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1671, 0},
+#line 5959 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1672, 0},
+#line 4772 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1673, 0},
+#line 472 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1674, 0},
+#line 4076 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1675, 0},
+#line 3078 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1676, 0},
+#line 1764 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1677, 0},
+#line 825 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1678, 0},
+#line 290 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1679, 0},
+#line 3402 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1680, 0},
+#line 3537 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1681, 0},
+#line 1254 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1682, 4},
+#line 779 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1683, 0},
+#line 6068 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1684, 0},
+#line 2103 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1685, 0},
+#line 192 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1686, 0},
+#line 3031 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1687, 0},
+#line 2062 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1688, 0},
+#line 5839 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1689, 0},
+#line 147 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1690, 0},
+#line 5865 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1691, 0},
+#line 6043 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1692, 0},
+#line 3726 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1693, 0},
+#line 3636 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1694, 0},
+#line 5949 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1695, 0},
+#line 3365 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1696, 0},
+#line 6525 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1697, 0},
+#line 6455 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1698, 0},
+#line 6115 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1699, 0},
+#line 1776 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1700, 0},
+#line 4775 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1701, 0},
+#line 1410 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1702, 0},
+#line 2171 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1703, 0},
+#line 2297 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1704, 0},
+#line 1808 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1705, 4},
+#line 453 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1706, 0},
+#line 5957 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1707, 0},
+#line 1469 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1708, 0},
+#line 2833 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1709, 0},
+#line 4131 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1710, 0},
+#line 2283 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1711, 4},
+#line 2235 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1712, 0},
+#line 3540 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1713, 0},
+#line 2918 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1714, 0},
+#line 1213 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1715, 4},
+#line 5955 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1716, 0},
+#line 1262 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1717, 0},
+#line 6026 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1718, 0},
+#line 2830 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1719, 0},
+#line 3897 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1720, 0},
+#line 393 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1721, 0},
+#line 2964 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1722, 0},
+#line 5983 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1723, 0},
+#line 426 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1724, 0},
+#line 3796 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1725, 0},
+#line 2934 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1726, 0},
+#line 3353 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1727, 0},
+#line 2261 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1728, 4},
+#line 33 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1729, 0},
+#line 148 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1730, 0},
+#line 5982 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1731, 0},
+#line 589 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1732, 0},
+#line 3134 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1733, 0},
+#line 785 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1734, 0},
+#line 780 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1735, 0},
+#line 1112 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1736, 0},
+#line 2791 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1737, 0},
+#line 2789 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1738, 0},
+#line 2084 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1739, 0},
+#line 3048 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1740, 0},
+#line 4824 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1741, 0},
+#line 6110 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1742, 0},
+#line 2359 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1743, 0},
+#line 4071 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1744, 0},
+#line 2744 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1745, 0},
+#line 757 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1746, 0},
+#line 1206 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1747, 4},
+#line 846 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1748, 0},
+#line 1253 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1749, 4},
+#line 603 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1750, 0},
+#line 3015 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1751, 0},
+#line 2859 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1752, 0},
+#line 4781 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1753, 0},
+#line 6520 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1754, 0},
+#line 3769 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1755, 0},
+#line 668 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1756, 0},
+#line 3362 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1757, 0},
+#line 1825 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1758, 0},
+#line 3026 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1759, 0},
+#line 1156 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1760, 0},
+#line 219 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1761, 0},
+#line 4800 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1762, 0},
+#line 3809 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1763, 0},
+#line 3663 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1764, 0},
+#line 5900 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1765, 0},
+#line 3685 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1766, 0},
+#line 3793 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1767, 0},
+#line 837 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1768, 0},
+#line 6428 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1769, 0},
+#line 351 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1770, 0},
+#line 2202 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1771, 0},
+#line 1425 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1772, 0},
+#line 2194 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1773, 0},
+#line 3513 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1774, 0},
+#line 1789 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1775, 0},
+#line 3896 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1776, 0},
+#line 2864 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1777, 0},
 #line 3556 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4247, 0},
-#line 6336 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4248, 0},
-#line 5286 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4249, 0},
-#line 3305 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4250, 0},
-#line 1089 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4251, 0},
-#line 2341 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4252, 0},
-#line 5213 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4253, 0},
-#line 5005 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4254, 2},
-#line 2603 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4255, 0},
-#line 3613 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4256, 0},
-#line 4858 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4257, 0},
-#line 247 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4258, 0},
-#line 294 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4259, 0},
-#line 1496 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4260, 0},
-#line 1746 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4261, 0},
-#line 5314 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4262, 0},
-#line 5177 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4263, 0},
-#line 5873 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4264, 0},
-#line 3615 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4265, 0},
-#line 5012 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4266, 0},
-#line 5515 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4267, 4},
-#line 6170 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4268, 0},
-#line 3891 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4269, 0},
-#line 1527 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4270, 0},
-#line 3393 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4271, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1778, 0},
+#line 161 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1779, 0},
+#line 3665 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1780, 0},
+#line 3001 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1781, 0},
+#line 220 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1782, 0},
+#line 5956 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1783, 0},
+#line 594 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1784, 1},
+#line 3379 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1785, 0},
+#line 208 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1786, 0},
+#line 2284 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1787, 4},
+#line 1863 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1788, 0},
+#line 3118 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1789, 0},
+#line 4878 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1790, 0},
+#line 3596 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1791, 0},
+#line 3039 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1792, 0},
+#line 4102 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1793, 0},
+#line 3532 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1794, 0},
+#line 3674 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1795, 0},
+#line 5954 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1796, 0},
+#line 1153 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1797, 0},
+#line 199 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1798, 0},
+#line 3710 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1799, 0},
+#line 2182 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1800, 0},
+#line 2752 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1801, 0},
+#line 5879 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1802, 0},
+#line 5903 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1803, 0},
+#line 2957 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1804, 0},
+#line 3450 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1805, 0},
+#line 3476 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1806, 0},
+#line 3406 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1807, 0},
+#line 470 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1808, 0},
+#line 6042 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1809, 0},
+#line 577 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1810, 0},
+#line 1414 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1811, 0},
+#line 6475 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1812, 0},
+#line 3112 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1813, 0},
+#line 6020 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1814, 0},
+#line 1239 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1815, 4},
+#line 2638 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1816, 0},
+#line 3594 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1817, 0},
+#line 2526 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1818, 4},
+#line 3666 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1819, 0},
+#line 2943 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1820, 0},
+#line 4838 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1821, 0},
+#line 4893 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1822, 0},
+#line 6019 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1823, 0},
+#line 4092 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1824, 0},
+#line 1117 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1825, 0},
+#line 2097 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1826, 0},
+#line 5910 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1827, 0},
+#line 3852 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1828, 0},
+#line 2183 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1829, 0},
+#line 2265 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1830, 0},
+#line 6071 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1831, 0},
+#line 1762 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1832, 0},
+#line 6032 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1833, 0},
+#line 800 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1834, 0},
+#line 5953 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1835, 0},
+#line 3856 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1836, 0},
+#line 3874 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1837, 0},
+#line 3668 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1838, 0},
+#line 6501 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1839, 0},
+#line 2066 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1840, 0},
+#line 2840 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1841, 0},
+#line 2154 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1842, 0},
+#line 3549 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1843, 0},
+#line 124 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1844, 0},
+#line 3890 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1845, 0},
+#line 2144 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1846, 0},
+#line 3409 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1847, 0},
+#line 3543 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1848, 0},
+#line 3592 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1849, 4},
+#line 836 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1850, 0},
+#line 6523 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1851, 0},
+#line 5984 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1852, 0},
+#line 6006 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1853, 0},
+#line 2189 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1854, 0},
+#line 2078 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1855, 0},
+#line 3741 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1856, 0},
+#line 2939 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1857, 0},
+#line 1230 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1858, 0},
+#line 2102 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1859, 0},
+#line 2822 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1860, 0},
+#line 2087 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1861, 0},
+#line 848 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1862, 0},
+#line 3148 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1863, 0},
+#line 113 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1864, 0},
+#line 5991 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1865, 0},
+#line 2119 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1866, 0},
+#line 5945 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1867, 0},
+#line 2670 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1868, 0},
+#line 5886 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1869, 0},
+#line 3889 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1870, 0},
+#line 3381 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1871, 0},
+#line 2792 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1872, 0},
+#line 2972 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1873, 0},
+#line 177 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1874, 0},
+#line 5871 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1875, 0},
+#line 4100 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1876, 0},
+#line 288 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1877, 0},
+#line 3119 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1878, 0},
+#line 6030 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1879, 0},
+#line 6024 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1880, 0},
+#line 3526 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1881, 0},
+#line 2968 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1882, 0},
+#line 3103 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1883, 0},
+#line 3688 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1884, 0},
+#line 847 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1885, 0},
+#line 6112 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1886, 0},
+#line 2817 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1887, 0},
+#line 1876 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1888, 4},
+#line 3535 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1889, 0},
+#line 5942 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1890, 0},
+#line 4096 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1891, 0},
+#line 5980 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1892, 0},
+#line 5067 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1893, 0},
+#line 3709 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1894, 0},
+#line 5064 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1895, 0},
+#line 5282 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1896, 0},
+#line 5326 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1897, 0},
+#line 5909 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1898, 0},
+#line 2588 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1899, 0},
+#line 1874 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1900, 0},
+#line 814 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1901, 0},
+#line 2057 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1902, 0},
+#line 4778 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1903, 0},
+#line 352 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1904, 0},
+#line 1440 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1905, 0},
+#line 3524 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1906, 0},
+#line 2975 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1907, 0},
+#line 3077 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1908, 0},
+#line 4919 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1909, 0},
+#line 3490 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1910, 0},
+#line 6524 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1911, 0},
+#line 3346 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1912, 0},
+#line 5342 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1913, 0},
+#line 4099 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1914, 0},
+#line 2178 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1915, 0},
+#line 2758 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1916, 0},
+#line 2585 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1917, 0},
+#line 5337 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1918, 0},
+#line 2865 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1919, 0},
+#line 2662 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1920, 0},
+#line 5386 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1921, 0},
+#line 793 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1922, 0},
+#line 2199 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1923, 0},
+#line 5439 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1924, 0},
+#line 2785 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1925, 0},
+#line 687 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1926, 0},
+#line 221 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1927, 0},
+#line 4195 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1928, 0},
+#line 3854 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1929, 0},
+#line 2760 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1930, 0},
+#line 103 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1931, 0},
+#line 6023 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1932, 0},
+#line 4771 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1933, 0},
+#line 5244 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1934, 0},
+#line 222 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1935, 0},
+#line 1149 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1936, 0},
+#line 2854 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1937, 0},
+#line 3784 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1938, 0},
+#line 5271 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1939, 0},
+#line 3785 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1940, 0},
+#line 5993 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1941, 0},
+#line 4098 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1942, 0},
+#line 3414 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1943, 0},
+#line 6001 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1944, 0},
+#line 3657 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1945, 0},
+#line 4148 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1946, 0},
+#line 822 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1947, 0},
+#line 6039 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1948, 0},
+#line 3075 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1949, 0},
+#line 2899 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1950, 0},
+#line 6467 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1951, 0},
+#line 246 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1952, 0},
+#line 5227 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1953, 0},
+#line 5890 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1954, 0},
+#line 2539 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1955, 4},
+#line 6080 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1956, 0},
+#line 4773 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1957, 0},
+#line 3667 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1958, 0},
+#line 3664 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1959, 0},
+#line 3422 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1960, 0},
+#line 5937 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1961, 0},
+#line 3079 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1962, 0},
+#line 5022 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1963, 0},
+#line 4093 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1964, 0},
+#line 1415 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1965, 0},
+#line 5299 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1966, 0},
+#line 2982 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1967, 0},
+#line 3092 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1968, 0},
+#line 4833 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1969, 0},
+#line 6105 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1970, 0},
+#line 5999 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1971, 0},
+#line 5352 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1972, 0},
+#line 5405 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1973, 0},
+#line 3117 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1974, 0},
+#line 4998 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1975, 0},
+#line 5275 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1976, 0},
+#line 4196 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1977, 0},
+#line 2793 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1978, 0},
+#line 5298 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1979, 0},
+#line 3108 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1980, 0},
+#line 3107 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1981, 0},
+#line 6048 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1982, 0},
+#line 4867 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1983, 0},
+#line 2795 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1984, 0},
+#line 6464 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1985, 0},
+#line 5340 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1986, 0},
+#line 6038 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1987, 0},
+#line 225 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1988, 0},
+#line 818 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1989, 0},
+#line 5264 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1990, 0},
+#line 2771 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1991, 0},
+#line 4931 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1992, 0},
+#line 5072 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1993, 0},
+#line 5422 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1994, 0},
+#line 5994 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1995, 0},
+#line 4094 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1996, 0},
+#line 5294 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1997, 0},
+#line 2134 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1998, 0},
+#line 2562 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str1999, 4},
+#line 3564 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2000, 0},
+#line 4894 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2001, 0},
+#line 2961 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2002, 0},
+#line 364 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2003, 0},
+#line 5396 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2004, 0},
+#line 163 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2005, 0},
+#line 2751 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2006, 0},
+#line 1192 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2007, 0},
+#line 106 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2008, 0},
+#line 3614 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2009, 0},
+#line 5840 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2010, 0},
+#line 2980 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2011, 0},
+#line 2200 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2012, 0},
+#line 2936 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2013, 0},
+#line 1258 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2014, 4},
+#line 4898 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2015, 0},
+#line 3805 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2016, 2},
+#line 2816 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2017, 0},
+#line 1234 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2018, 0},
+#line 5847 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2019, 0},
+#line 90 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2020, 0},
+#line 2145 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2021, 0},
+#line 792 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2022, 0},
+#line 2963 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2023, 0},
+#line 2814 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2024, 0},
+#line 1576 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2025, 0},
+#line 3827 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2026, 0},
+#line 4027 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2027, 0},
+#line 3957 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2028, 0},
+#line 1044 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2029, 0},
 #line 4132 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4272, 0},
-#line 4585 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4273, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2030, 0},
+#line 968 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2031, 0},
+#line 1915 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2032, 0},
+#line 5379 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2033, 0},
+#line 2130 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2034, 0},
+#line 1821 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2035, 0},
+#line 1846 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2036, 0},
+#line 4844 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2037, 0},
+#line 2777 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2038, 0},
+#line 3705 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2039, 0},
+#line 3141 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2040, 0},
+#line 3036 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2041, 0},
+#line 2118 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2042, 0},
+#line 6029 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2043, 0},
+#line 3620 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2044, 0},
+#line 6040 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2045, 0},
+#line 6515 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2046, 0},
+#line 363 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2047, 0},
+#line 1308 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2048, 0},
+#line 6462 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2049, 0},
+#line 1500 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2050, 0},
+#line 662 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2051, 0},
+#line 1503 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2052, 0},
+#line 5319 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2053, 0},
+#line 3813 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2054, 0},
+#line 1498 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2055, 0},
+#line 4034 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2056, 0},
+#line 1600 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2057, 0},
+#line 5245 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2058, 0},
+#line 1051 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2059, 0},
+#line 1991 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2060, 0},
+#line 789 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2061, 0},
+#line 4097 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2062, 0},
+#line 6511 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2063, 0},
+#line 2836 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2064, 0},
+#line 2965 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2065, 0},
+#line 1068 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2066, 0},
+#line 1033 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2067, 0},
+#line 5122 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2068, 0},
+#line 2218 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2069, 0},
+#line 1489 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2070, 0},
+#line 4145 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2071, 0},
+#line 4968 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2072, 0},
+#line 1235 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2073, 4},
+#line 389 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2074, 0},
+#line 3046 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2075, 0},
+#line 1385 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2076, 0},
+#line 1551 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2077, 2},
+#line 372 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2078, 0},
+#line 296 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2079, 0},
+#line 4087 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2080, 0},
+#line 4763 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2081, 0},
+#line 3978 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2082, 0},
+#line 1571 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2083, 0},
+#line 6454 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2084, 0},
+#line 991 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2085, 0},
+#line 1932 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2086, 0},
+#line 2135 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2087, 0},
+#line 3995 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2088, 0},
+#line 4899 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2089, 0},
+#line 1008 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2090, 0},
+#line 1954 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2091, 0},
+#line 3408 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2092, 0},
+#line 2910 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2093, 0},
+#line 6083 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2094, 0},
+#line 4082 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2095, 0},
+#line 3093 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2096, 0},
+#line 1328 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2097, 0},
+#line 1525 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2098, 0},
+#line 2193 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2099, 0},
+#line 196 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2100, 0},
+#line 1534 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2101, 0},
+#line 1348 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2102, 0},
+#line 2802 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2103, 0},
+#line 5286 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2104, 0},
+#line 988 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2105, 0},
+#line 263 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2106, 0},
+#line 4967 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2107, 0},
+#line 1512 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2108, 0},
+#line 790 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2109, 0},
+#line 5269 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2110, 0},
+#line 3946 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2111, 0},
+#line 1684 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2112, 0},
+#line 955 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2113, 0},
+#line 1901 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2114, 0},
+#line 1597 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2115, 0},
+#line 786 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2116, 0},
+#line 5406 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2117, 0},
+#line 1580 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2118, 0},
+#line 1090 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2119, 0},
+#line 1844 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2120, 0},
+#line 3390 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2121, 0},
+#line 2790 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2122, 0},
+#line 5292 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2123, 0},
+#line 5230 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2124, 0},
+#line 3099 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2125, 0},
+#line 151 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2126, 0},
+#line 815 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2127, 0},
+#line 4104 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2128, 0},
+#line 2765 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2129, 0},
+#line 2213 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2130, 0},
+#line 6025 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2131, 0},
+#line 3670 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2132, 0},
+#line 1297 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2133, 0},
+#line 3484 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2134, 0},
+#line 2151 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2135, 0},
+#line 1096 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2136, 0},
+#line 1501 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2137, 0},
+#line 1535 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2138, 0},
+#line 6012 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2139, 0},
+#line 5268 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2140, 0},
+#line 3815 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2141, 0},
+#line 1093 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2142, 0},
+#line 2150 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2143, 0},
+#line 3872 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2144, 0},
+#line 4109 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2145, 0},
+#line 3457 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2146, 0},
+#line 1528 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2147, 0},
+#line 5092 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2148, 4},
+#line 6483 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2149, 0},
+#line 3491 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2150, 0},
+#line 787 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2151, 0},
+#line 1546 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2152, 0},
+#line 1542 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2153, 0},
+#line 3878 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2154, 0},
+#line 3746 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2155, 0},
+#line 3750 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2156, 0},
+#line 4086 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2157, 0},
+#line 2671 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2158, 0},
+#line 6527 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2159, 0},
+#line 235 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2160, 0},
+#line 4982 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2161, 0},
+#line 2675 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2162, 0},
+#line 1858 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2163, 0},
+#line 112 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2164, 0},
+#line 3634 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2165, 0},
+#line 1861 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2166, 0},
+#line 2112 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2167, 0},
+#line 3504 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2168, 0},
+#line 1495 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2169, 0},
+#line 210 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2170, 0},
+#line 5906 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2171, 0},
+#line 4836 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2172, 0},
+#line 5214 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2173, 0},
+#line 2174 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2174, 0},
+#line 1739 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2175, 0},
+#line 261 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2176, 0},
+#line 475 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2177, 0},
+#line 2606 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2178, 0},
+#line 2620 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2179, 0},
+#line 5250 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2180, 0},
+#line 343 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2181, 0},
+#line 1545 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2182, 0},
+#line 1086 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2183, 0},
+#line 1729 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2184, 0},
+#line 1579 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2185, 0},
+#line 6010 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2186, 0},
+#line 5093 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2187, 4},
+#line 4980 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2188, 0},
+#line 2773 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2189, 0},
+#line 1091 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2190, 0},
+#line 5412 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2191, 0},
+#line 2421 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2192, 0},
+#line 2465 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2193, 0},
+#line 3822 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2194, 0},
+#line 6021 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2195, 0},
+#line 6046 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2196, 0},
+#line 3370 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2197, 0},
+#line 1555 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2198, 2},
+#line 1178 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2199, 0},
+#line 1646 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2200, 4},
+#line 2181 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2201, 0},
+#line 3382 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2202, 0},
+#line 3684 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2203, 0},
+#line 6536 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2204, 0},
+#line 2186 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2205, 0},
+#line 2420 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2206, 0},
+#line 5434 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2207, 0},
+#line 1662 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2208, 4},
+#line 5951 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2209, 0},
+#line 5305 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2210, 0},
+#line 3465 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2211, 0},
+#line 3386 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2212, 0},
+#line 1404 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2213, 0},
+#line 2176 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2214, 0},
+#line 1575 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2215, 0},
+#line 2607 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2216, 0},
+#line 5998 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2217, 0},
+#line 3413 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2218, 0},
+#line 1496 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2219, 0},
+#line 1645 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2220, 4},
+#line 1672 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2221, 4},
+#line 1679 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2222, 4},
+#line 3398 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2223, 0},
+#line 1666 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2224, 4},
+#line 1632 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2225, 4},
+#line 1676 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2226, 4},
+#line 1633 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2227, 4},
+#line 5015 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2228, 0},
+#line 2149 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2229, 0},
+#line 3641 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2230, 0},
+#line 6017 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2231, 0},
+#line 3567 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2232, 0},
+#line 1095 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2233, 0},
+#line 1660 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2234, 4},
+#line 2365 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2235, 0},
+#line 1259 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2236, 4},
+#line 1742 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2237, 0},
+#line 1524 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2238, 0},
+#line 3376 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2239, 0},
+#line 1071 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2240, 0},
+#line 666 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2241, 0},
+#line 2666 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2242, 0},
+#line 2970 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2243, 0},
+#line 5001 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2244, 0},
+#line 2105 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2245, 0},
+#line 2584 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2246, 0},
+#line 5381 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2247, 0},
+#line 2845 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2248, 0},
+#line 5234 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2249, 0},
+#line 5116 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2250, 0},
+#line 6451 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2251, 0},
+#line 5371 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2252, 0},
+#line 5071 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2253, 0},
+#line 1667 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2254, 4},
+#line 5009 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2255, 0},
+#line 1497 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2256, 0},
+#line 1257 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2257, 4},
+#line 2775 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2258, 0},
+#line 1558 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2259, 0},
+#line 1735 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2260, 0},
+#line 3611 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2261, 4},
+#line 2016 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2262, 0},
+#line 4095 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2263, 0},
+#line 3407 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2264, 0},
+#line 3814 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2265, 0},
+#line 4932 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2266, 0},
+#line 1659 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2267, 4},
+#line 2225 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2268, 0},
+#line 5950 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2269, 0},
+#line 1517 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2270, 0},
+#line 4835 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2271, 0},
+#line 6450 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2272, 0},
+#line 6067 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2273, 0},
+#line 3347 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2274, 0},
+#line 3745 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2275, 0},
+#line 255 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2276, 0},
+#line 2739 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2277, 0},
+#line 816 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2278, 0},
+#line 3538 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2279, 0},
+#line 2704 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2280, 0},
+#line 2734 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2281, 0},
+#line 4993 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2282, 0},
+#line 2735 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2283, 0},
+#line 4808 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2284, 0},
+#line 2979 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2285, 0},
+#line 2737 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2286, 0},
+#line 1806 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2287, 0},
+#line 1550 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2288, 0},
+#line 5317 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2289, 0},
+#line 6509 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2290, 0},
+#line 4996 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2291, 0},
+#line 5424 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2292, 0},
+#line 2263 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2293, 0},
+#line 1647 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2294, 4},
+#line 5274 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2295, 0},
+#line 3464 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2296, 0},
+#line 600 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2297, 0},
+#line 4891 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2298, 0},
+#line 2697 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2299, 0},
+#line 2696 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2300, 0},
+#line 2698 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2301, 0},
+#line 2270 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2302, 0},
+#line 5841 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2303, 0},
+#line 2699 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2304, 0},
+#line 2196 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2305, 0},
+#line 3411 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2306, 0},
+#line 2740 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2307, 0},
+#line 1460 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2308, 0},
+#line 3831 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2309, 0},
+#line 3525 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2310, 0},
+#line 5241 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2311, 0},
+#line 3708 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2312, 0},
+#line 2742 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2313, 0},
+#line 1671 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2314, 4},
+#line 2705 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2315, 0},
+#line 5855 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2316, 0},
+#line 1629 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2317, 4},
+#line 5302 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2318, 0},
+#line 1652 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2319, 4},
+#line 1405 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2320, 0},
+#line 2223 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2321, 0},
+#line 2172 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2322, 0},
+#line 1668 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2323, 4},
+#line 1677 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2324, 4},
+#line 2724 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2325, 0},
+#line 5306 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2326, 0},
+#line 791 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2327, 0},
+#line 1644 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2328, 4},
+#line 5432 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2329, 0},
+#line 1097 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2330, 0},
+#line 1637 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2331, 4},
+#line 2721 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2332, 0},
+#line 3417 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2333, 0},
+#line 6510 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2334, 0},
+#line 3833 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2335, 0},
+#line 2723 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2336, 0},
+#line 2750 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2337, 0},
+#line 5986 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2338, 0},
+#line 665 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2339, 0},
+#line 663 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2340, 0},
+#line 2712 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2341, 0},
+#line 3536 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2342, 0},
+#line 2177 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2343, 0},
+#line 3597 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2344, 0},
+#line 1407 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2345, 0},
+#line 3129 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2346, 0},
+#line 3624 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2347, 0},
+#line 231 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2348, 4},
+#line 3591 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2349, 0},
+#line 3493 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2350, 0},
+#line 1691 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2351, 0},
+#line 2713 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2352, 0},
+#line 1630 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2353, 4},
+#line 2838 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2354, 0},
+#line 2718 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2355, 0},
+#line 6535 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2356, 0},
+#line 1502 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2357, 0},
+#line 6103 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2358, 4},
+#line 1826 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2359, 0},
+#line 2201 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2360, 0},
+#line 4103 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2361, 0},
+#line 3041 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2362, 0},
+#line 2719 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2363, 0},
+#line 4927 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2364, 0},
+#line 1631 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2365, 4},
+#line 2711 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2366, 0},
+#line 2725 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2367, 0},
+#line 4887 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2368, 0},
+#line 5335 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2369, 0},
+#line 3136 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2370, 0},
+#line 3679 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2371, 0},
+#line 27 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2372, 4},
+#line 3028 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2373, 0},
+#line 1408 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2374, 0},
+#line 5000 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2375, 0},
+#line 3104 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2376, 0},
+#line 1625 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2377, 0},
+#line 3421 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2378, 0},
+#line 2736 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2379, 0},
+#line 5862 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2380, 0},
+#line 5121 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2381, 0},
+#line 3085 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2382, 0},
+#line 3089 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2383, 0},
+#line 6092 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2384, 0},
+#line 3696 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2385, 0},
+#line 5965 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2386, 0},
+#line 3405 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2387, 0},
+#line 5297 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2388, 0},
+#line 5111 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2389, 0},
+#line 2726 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2390, 0},
+#line 3800 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2391, 0},
+#line 5239 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2392, 0},
+#line 1651 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2393, 4},
+#line 2746 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2394, 0},
+#line 664 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2395, 0},
+#line 3568 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2396, 0},
+#line 1658 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2397, 4},
+#line 1565 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2398, 0},
+#line 3115 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2399, 0},
+#line 4929 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2400, 0},
+#line 1657 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2401, 4},
+#line 2727 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2402, 0},
+#line 1628 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2403, 4},
+#line 2729 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2404, 0},
+#line 1650 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2405, 4},
+#line 4940 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2406, 0},
+#line 5384 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2407, 0},
+#line 506 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2408, 0},
+#line 1653 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2409, 4},
+#line 1536 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2410, 0},
+#line 2205 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2411, 0},
+#line 1490 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2412, 0},
+#line 6079 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2413, 0},
+#line 83 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2414, 0},
+#line 5917 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2415, 0},
+#line 1636 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2416, 4},
+#line 3350 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2417, 0},
+#line 3799 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2418, 0},
+#line 1099 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2419, 0},
+#line 2717 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2420, 0},
+#line 6456 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2421, 0},
+#line 5315 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2422, 0},
+#line 2221 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2423, 0},
+#line 3064 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2424, 0},
+#line 1634 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2425, 4},
+#line 1638 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2426, 4},
+#line 5233 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2427, 0},
+#line 3566 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2428, 0},
+#line 2710 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2429, 0},
+#line 5251 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2430, 0},
+#line 2730 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2431, 0},
+#line 2621 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2432, 0},
+#line 1506 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2433, 0},
+#line 4130 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2434, 0},
+#line 3640 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2435, 0},
+#line 3466 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2436, 0},
+#line 3923 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2437, 0},
+#line 2947 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2438, 0},
+#line 1783 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2439, 0},
+#line 2179 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2440, 0},
+#line 5388 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2441, 0},
+#line 5296 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2442, 0},
+#line 133 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2443, 0},
+#line 3637 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2444, 0},
+#line 5902 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2445, 0},
+#line 3738 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2446, 0},
+#line 5287 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2447, 0},
+#line 6035 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2448, 0},
+#line 3675 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2449, 0},
+#line 6440 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2450, 0},
+#line 2714 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2451, 0},
+#line 1547 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2452, 0},
+#line 2908 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2453, 0},
+#line 5964 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2454, 0},
+#line 3704 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2455, 0},
+#line 2364 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2456, 0},
+#line 3483 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2457, 0},
+#line 3759 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2458, 0},
+#line 3380 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2459, 0},
+#line 3580 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2460, 0},
+#line 1173 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2461, 0},
+#line 387 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2462, 0},
+#line 2716 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2463, 0},
+#line 6559 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2464, 0},
+#line 2743 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2465, 0},
+#line 5308 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2466, 0},
+#line 218 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2467, 0},
+#line 3773 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2468, 0},
+#line 1507 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2469, 0},
+#line 620 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2470, 0},
+#line 1860 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2471, 0},
+#line 5988 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2472, 0},
+#line 4101 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2473, 0},
+#line 4994 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2474, 0},
+#line 2906 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2475, 0},
+#line 3122 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2476, 0},
+#line 3397 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2477, 0},
+#line 681 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2478, 0},
+#line 2190 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2479, 0},
+#line 1531 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2480, 0},
+#line 3613 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2481, 0},
+#line 1094 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2482, 0},
+#line 1654 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2483, 4},
+#line 6555 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2484, 0},
+#line 4983 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2485, 0},
+#line 5324 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2486, 0},
+#line 1544 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2487, 0},
+#line 4964 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2488, 0},
+#line 3410 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2489, 0},
+#line 3354 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2490, 0},
+#line 5016 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2491, 0},
+#line 5426 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2492, 0},
+#line 5112 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2493, 0},
+#line 3583 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2494, 0},
+#line 5248 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2495, 0},
+#line 6069 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2496, 0},
+#line 3642 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2497, 0},
+#line 2208 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2498, 0},
+#line 1744 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2499, 0},
+#line 601 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2500, 0},
+#line 3761 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2501, 0},
+#line 574 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2502, 0},
+#line 1678 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2503, 4},
+#line 1640 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2504, 4},
+#line 2241 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2505, 0},
+#line 1642 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2506, 4},
+#line 1140 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2507, 0},
+#line 1562 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2508, 0},
+#line 3803 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2509, 0},
+#line 4157 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2510, 0},
+#line 1661 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2511, 4},
+#line 3662 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2512, 0},
+#line 1608 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2513, 0},
+#line 935 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2514, 0},
+#line 3676 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2515, 0},
+#line 2014 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2516, 0},
+#line 315 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2517, 0},
+#line 5365 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2518, 0},
+#line 5913 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2519, 0},
+#line 5437 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2520, 0},
+#line 3754 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2521, 0},
+#line 3760 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2522, 0},
+#line 1717 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2523, 0},
+#line 253 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2524, 0},
+#line 4941 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2525, 0},
+#line 1598 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2526, 0},
+#line 1592 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2527, 0},
+#line 2909 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2528, 0},
+#line 5279 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2529, 0},
+#line 2955 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2530, 0},
+#line 4796 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2531, 0},
+#line 1548 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2532, 0},
+#line 1519 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2533, 0},
+#line 4962 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2534, 0},
+#line 5987 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2535, 0},
+#line 5971 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2536, 0},
+#line 1781 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2537, 0},
+#line 5369 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2538, 0},
+#line 593 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2539, 0},
+#line 3623 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2540, 0},
+#line 3593 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2541, 0},
+#line 5997 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2542, 0},
+#line 2117 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2543, 0},
+#line 1606 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2544, 0},
+#line 409 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2545, 0},
+#line 1523 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2546, 0},
+#line 2920 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2547, 0},
+#line 309 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2548, 0},
+#line 3124 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2549, 0},
+#line 2747 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2550, 0},
+#line 5323 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2551, 0},
+#line 1508 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2552, 0},
+#line 5124 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2553, 4},
+#line 5878 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2554, 0},
+#line 3042 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2555, 0},
+#line 417 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2556, 0},
+#line 1784 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2557, 0},
+#line 1763 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2558, 0},
+#line 1754 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2559, 0},
+#line 395 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2560, 0},
+#line 3806 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2561, 0},
+#line 6452 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2562, 0},
+#line 3744 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2563, 0},
+#line 5346 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2564, 0},
+#line 2738 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2565, 0},
+#line 1680 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2566, 0},
+#line 350 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2567, 0},
+#line 145 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2568, 0},
+#line 3459 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2569, 0},
+#line 2059 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2570, 0},
+#line 1643 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2571, 4},
+#line 4956 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2572, 0},
+#line 1128 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2573, 0},
+#line 1537 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2574, 0},
+#line 2971 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2575, 0},
+#line 5316 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2576, 0},
+#line 609 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2577, 0},
+#line 5225 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2578, 0},
+#line 3633 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2579, 0},
+#line 6556 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2580, 0},
+#line 2009 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2581, 0},
+#line 2720 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2582, 0},
+#line 2700 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2583, 0},
+#line 2823 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2584, 0},
+#line 5153 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2585, 0},
+#line 3707 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2586, 0},
+#line 3578 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2587, 0},
+#line 2207 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2588, 0},
+#line 1569 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2589, 0},
+#line 2224 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2590, 0},
+#line 2089 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2591, 0},
+#line 2415 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2592, 0},
+#line 6459 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2593, 0},
+#line 1561 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2594, 0},
+#line 4939 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2595, 0},
+#line 1627 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2596, 0},
+#line 5331 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2597, 0},
+#line 3619 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2598, 0},
+#line 6533 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2599, 0},
+#line 1146 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2600, 0},
+#line 4872 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2601, 0},
+#line 3755 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2602, 0},
+#line 3604 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2603, 0},
+#line 2095 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2604, 0},
+#line 6474 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2605, 0},
+#line 6457 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2606, 0},
+#line 5128 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2607, 0},
+#line 3868 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2608, 0},
+#line 4046 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2609, 0},
+#line 4161 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2610, 0},
+#line 4837 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2611, 0},
+#line 2156 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2612, 0},
+#line 2222 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2613, 0},
+#line 1690 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2614, 0},
+#line 4990 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2615, 0},
+#line 826 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2616, 0},
+#line 623 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2617, 0},
+#line 2160 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2618, 0},
+#line 2127 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2619, 0},
+#line 5921 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2620, 0},
+#line 2856 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2621, 0},
+#line 6449 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2622, 0},
+#line 3403 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2623, 0},
+#line 22 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2624, 0},
+#line 3701 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2625, 0},
+#line 404 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2626, 0},
+#line 85 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2627, 0},
+#line 3074 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2628, 0},
+#line 6477 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2629, 0},
+#line 2185 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2630, 0},
+#line 1218 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2631, 0},
+#line 5021 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2632, 0},
+#line 2745 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2633, 0},
+#line 2058 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2634, 0},
+#line 3100 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2635, 0},
+#line 5125 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2636, 0},
+#line 5288 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2637, 0},
+#line 4845 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2638, 0},
+#line 3892 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2639, 0},
+#line 2641 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2640, 0},
+#line 3587 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2641, 0},
+#line 3418 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2642, 0},
+#line 5309 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2643, 0},
+#line 468 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2644, 0},
+#line 1736 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2645, 0},
+#line 3628 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2646, 0},
+#line 1656 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2647, 4},
+#line 1670 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2648, 4},
+#line 2733 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2649, 0},
+#line 5350 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2650, 0},
+#line 3497 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2651, 0},
+#line 249 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2652, 0},
+#line 6563 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2653, 0},
+#line 1568 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2654, 0},
+#line 2104 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2655, 0},
+#line 3682 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2656, 0},
+#line 3000 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2657, 0},
+#line 3499 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2658, 0},
+#line 5229 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2659, 0},
+#line 1564 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2660, 0},
+#line 5090 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2661, 0},
+#line 6044 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2662, 0},
+#line 3811 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2663, 0},
+#line 3349 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2664, 0},
+#line 3572 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2665, 0},
+#line 1759 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2666, 0},
+#line 2946 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2667, 0},
+#line 5118 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2668, 0},
+#line 2125 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2669, 0},
+#line 1145 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2670, 0},
+#line 6481 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2671, 0},
+#line 162 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2672, 0},
+#line 5147 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2673, 0},
+#line 4957 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2674, 0},
+#line 2157 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2675, 0},
+#line 2100 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2676, 0},
+#line 1543 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2677, 0},
+#line 1819 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2678, 0},
+#line 4897 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2679, 0},
+#line 1179 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2680, 0},
+#line 3819 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2681, 0},
+#line 1226 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2682, 0},
+#line 1868 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2683, 0},
+#line 3757 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2684, 0},
+#line 3582 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2685, 0},
+#line 1214 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2686, 0},
+#line 2319 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2687, 0},
+#line 2985 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2688, 0},
+#line 1639 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2689, 4},
+#line 3008 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2690, 0},
+#line 5960 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2691, 0},
+#line 226 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2692, 0},
+#line 3495 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2693, 0},
+#line 5152 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2694, 0},
+#line 2774 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2695, 0},
+#line 1183 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2696, 0},
+#line 508 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2697, 0},
+#line 1726 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2698, 0},
+#line 1822 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2699, 4},
+#line 3114 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2700, 0},
+#line 5322 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2701, 0},
+#line 1092 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2702, 0},
+#line 3926 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2703, 0},
+#line 3581 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2704, 0},
+#line 3711 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2705, 0},
+#line 4152 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2706, 0},
+#line 1807 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2707, 0},
+#line 3902 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2708, 0},
+#line 1541 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2709, 0},
+#line 6031 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2710, 0},
+#line 169 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2711, 0},
+#line 180 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2712, 0},
+#line 1648 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2713, 4},
+#line 3080 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2714, 0},
+#line 3570 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2715, 0},
+#line 224 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2716, 0},
+#line 3086 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2717, 0},
+#line 626 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2718, 0},
+#line 2834 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2719, 0},
+#line 2625 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2720, 0},
+#line 484 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2721, 0},
+#line 5213 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2722, 0},
+#line 2262 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2723, 0},
+#line 5349 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2724, 0},
+#line 2748 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2725, 0},
+#line 2728 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2726, 0},
+#line 5880 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2727, 0},
+#line 3834 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2728, 0},
+#line 1599 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2729, 0},
+#line 2306 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2730, 0},
+#line 2634 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2731, 0},
+#line 4951 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2732, 0},
+#line 5876 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2733, 0},
+#line 855 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2734, 0},
+#line 5442 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2735, 0},
+#line 2303 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2736, 0},
+#line 1828 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2737, 0},
+#line 2115 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2738, 0},
+#line 3501 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2739, 0},
+#line 2766 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2740, 0},
+#line 4160 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2741, 0},
+#line 6499 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2742, 0},
+#line 3383 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2743, 0},
+#line 4198 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2744, 0},
+#line 6486 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2745, 0},
+#line 2188 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2746, 0},
+#line 639 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2747, 0},
+#line 5243 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2748, 0},
+#line 3488 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2749, 0},
+#line 5110 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2750, 0},
+#line 3870 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2751, 0},
+#line 6503 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2752, 0},
+#line 5397 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2753, 0},
+#line 4989 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2754, 0},
+#line 5361 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2755, 0},
+#line 5100 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2756, 0},
+#line 2860 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2757, 0},
+#line 1593 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2758, 0},
+#line 3801 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2759, 0},
+#line 3879 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2760, 0},
+#line 2708 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2761, 0},
+#line 3748 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2762, 0},
+#line 144 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2763, 0},
+#line 2642 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2764, 0},
+#line 357 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2765, 0},
+#line 5236 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2766, 0},
+#line 3507 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2767, 0},
+#line 423 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2768, 0},
+#line 5300 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2769, 0},
+#line 5095 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2770, 0},
+#line 5277 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2771, 0},
+#line 1539 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2772, 0},
+#line 2092 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2773, 0},
+#line 3361 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2774, 0},
+#line 2206 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2775, 0},
+#line 5378 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2776, 0},
+#line 1607 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2777, 0},
+#line 5301 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2778, 0},
+#line 1121 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2779, 1},
+#line 1073 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2780, 0},
+#line 5195 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2781, 0},
+#line 5911 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2782, 0},
+#line 2247 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2783, 0},
+#line 1447 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2784, 0},
+#line 5389 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2785, 0},
+#line 2131 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2786, 0},
+#line 302 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2787, 0},
+#line 299 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2788, 0},
+#line 3610 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2789, 0},
+#line 2304 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2790, 0},
+#line 2494 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2791, 0},
+#line 5085 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2792, 4},
+#line 1649 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2793, 4},
+#line 2996 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2794, 0},
+#line 440 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2795, 0},
+#line 1553 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2796, 0},
+#line 2820 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2797, 0},
+#line 420 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2798, 0},
+#line 4873 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2799, 0},
+#line 5157 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2800, 0},
+#line 2083 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2801, 0},
+#line 1403 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2802, 0},
+#line 3612 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2803, 0},
+#line 2409 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2804, 0},
+#line 289 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2805, 0},
+#line 3145 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2806, 0},
+#line 4871 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2807, 0},
+#line 2919 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2808, 0},
+#line 2767 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2809, 0},
+#line 333 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2810, 0},
+#line 5150 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2811, 0},
+#line 5231 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2812, 0},
+#line 6066 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2813, 0},
+#line 3775 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2814, 4},
+#line 5367 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2815, 0},
+#line 807 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2816, 0},
+#line 3023 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2817, 0},
+#line 5362 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2818, 0},
+#line 1486 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2819, 0},
+#line 3576 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2820, 0},
+#line 3521 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2821, 0},
+#line 3861 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2822, 0},
+#line 1985 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2823, 0},
+#line 3758 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2824, 0},
+#line 2302 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2825, 0},
+#line 204 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2826, 0},
+#line 696 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2827, 0},
+#line 4769 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2828, 0},
+#line 5366 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2829, 0},
+#line 4783 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2830, 0},
+#line 5285 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2831, 0},
+#line 5154 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2832, 0},
+#line 5332 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2833, 0},
+#line 6460 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2834, 0},
+#line 3908 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2835, 0},
+#line 3955 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2836, 0},
+#line 1908 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2837, 0},
+#line 965 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2838, 0},
+#line 1274 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2839, 0},
+#line 1845 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2840, 0},
+#line 3952 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2841, 0},
+#line 962 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2842, 0},
+#line 3027 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2843, 0},
+#line 1910 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2844, 0},
+#line 3905 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2845, 0},
+#line 6056 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2846, 0},
+#line 2175 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2847, 0},
+#line 3554 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2848, 0},
+#line 4971 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2849, 0},
+#line 4884 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2850, 0},
+#line 1306 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2851, 0},
+#line 150 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2852, 0},
+#line 1135 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2853, 0},
+#line 6534 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2854, 0},
+#line 5149 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2855, 0},
+#line 6472 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2856, 0},
+#line 1303 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2857, 0},
+#line 5280 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2858, 0},
+#line 1907 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2859, 0},
+#line 1532 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2860, 0},
+#line 856 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2861, 0},
+#line 1641 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2862, 4},
+#line 2633 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2863, 0},
+#line 337 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2864, 0},
+#line 3531 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2865, 0},
+#line 2378 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2866, 0},
+#line 41 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2867, 0},
+#line 2812 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2868, 0},
+#line 4300 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2869, 0},
+#line 2824 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2870, 0},
+#line 1728 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2871, 0},
+#line 4001 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2872, 0},
+#line 5204 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2873, 0},
+#line 1014 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2874, 0},
+#line 5018 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2875, 0},
+#line 2094 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2876, 0},
+#line 120 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2877, 0},
+#line 1851 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2878, 0},
+#line 5411 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2879, 0},
+#line 3626 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2880, 0},
+#line 2855 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2881, 0},
+#line 3617 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2882, 0},
+#line 3669 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2883, 0},
+#line 4359 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2884, 0},
+#line 3859 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2885, 0},
+#line 488 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2886, 0},
+#line 4467 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2887, 0},
+#line 258 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2888, 0},
+#line 4470 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2889, 0},
+#line 4389 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2890, 0},
+#line 4462 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2891, 0},
+#line 1353 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2892, 0},
+#line 1605 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2893, 0},
+#line 4450 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2894, 0},
+#line 4449 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2895, 0},
+#line 4454 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2896, 0},
+#line 4452 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2897, 0},
+#line 498 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2898, 0},
+#line 497 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2899, 0},
+#line 499 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2900, 0},
+#line 4468 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2901, 0},
+#line 3515 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2902, 0},
+#line 4392 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2903, 0},
+#line 6085 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2904, 0},
+#line 2796 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2905, 0},
+#line 4451 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2906, 0},
+#line 4453 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2907, 0},
+#line 3489 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2908, 0},
+#line 3571 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2909, 0},
+#line 4227 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2910, 0},
+#line 80 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2911, 0},
+#line 71 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2912, 0},
+#line 3643 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2913, 0},
+#line 4365 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2914, 0},
+#line 5247 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2915, 0},
+#line 4367 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2916, 0},
+#line 4360 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2917, 0},
+#line 489 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2918, 4},
+#line 783 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2919, 0},
+#line 3541 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2920, 0},
+#line 4478 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2921, 0},
+#line 6444 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2922, 0},
+#line 4463 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2923, 0},
+#line 4479 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2924, 0},
+#line 501 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2925, 0},
+#line 1276 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2926, 0},
+#line 4366 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2927, 0},
+#line 6070 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2928, 0},
+#line 4509 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2929, 0},
+#line 1909 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2930, 0},
+#line 4461 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2931, 0},
+#line 6074 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2932, 0},
+#line 4476 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2933, 0},
+#line 1674 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2934, 4},
+#line 5303 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2935, 0},
+#line 5261 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2936, 0},
+#line 4390 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2937, 0},
+#line 4464 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2938, 0},
+#line 4458 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2939, 0},
+#line 6567 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2940, 0},
+#line 347 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2941, 0},
+#line 4446 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2942, 0},
+#line 3586 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2943, 0},
+#line 2116 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2944, 0},
+#line 1604 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2945, 0},
+#line 5010 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2946, 0},
+#line 4431 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2947, 0},
+#line 4430 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2948, 0},
+#line 4435 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2949, 0},
+#line 4438 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2950, 0},
+#line 495 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2951, 0},
+#line 5368 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2952, 0},
+#line 4432 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2953, 0},
+#line 4268 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2954, 0},
+#line 4361 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2955, 0},
+#line 4434 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2956, 0},
+#line 3585 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2957, 0},
+#line 4320 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2958, 0},
+#line 5162 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2959, 0},
+#line 4323 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2960, 0},
+#line 34 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2961, 0},
+#line 4474 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2962, 0},
+#line 500 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2963, 0},
+#line 4502 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2964, 0},
+#line 4408 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2965, 0},
+#line 2363 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2966, 0},
+#line 72 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2967, 0},
+#line 2375 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2968, 0},
+#line 4210 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2969, 0},
+#line 2374 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2970, 0},
+#line 1176 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2971, 0},
+#line 4406 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2972, 0},
+#line 4378 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2973, 0},
+#line 4409 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2974, 0},
+#line 4376 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2975, 0},
+#line 4379 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2976, 0},
+#line 4832 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2977, 0},
+#line 1682 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2978, 0},
+#line 5101 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2979, 0},
+#line 123 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2980, 0},
+#line 4386 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2981, 0},
+#line 4410 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2982, 0},
+#line 4444 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2983, 0},
+#line 4377 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2984, 0},
+#line 2120 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2985, 0},
+#line 3109 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2986, 0},
+#line 4428 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2987, 0},
+#line 3035 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2988, 0},
+#line 5141 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2989, 0},
+#line 3603 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2990, 0},
+#line 1509 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2991, 0},
+#line 1505 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2992, 0},
+#line 6530 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2993, 0},
+#line 5151 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2994, 0},
+#line 286 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2995, 0},
+#line 4443 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2996, 0},
+#line 492 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2997, 0},
+#line 496 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2998, 0},
+#line 4230 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str2999, 0},
+#line 4801 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3000, 0},
+#line 2369 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3001, 0},
+#line 6121 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3002, 0},
+#line 6434 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3003, 0},
+#line 5098 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3004, 0},
+#line 1596 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3005, 0},
+#line 1722 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3006, 0},
+#line 4460 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3007, 0},
+#line 4371 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3008, 0},
+#line 491 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3009, 0},
+#line 4475 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3010, 0},
+#line 4445 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3011, 0},
+#line 122 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3012, 0},
+#line 1277 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3013, 0},
+#line 3505 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3014, 0},
+#line 1136 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3015, 0},
+#line 2623 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3016, 0},
+#line 1732 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3017, 0},
+#line 638 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3018, 0},
+#line 4422 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3019, 0},
+#line 467 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3020, 0},
+#line 4423 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3021, 0},
+#line 4421 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3022, 0},
+#line 4484 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3023, 0},
+#line 3360 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3024, 0},
+#line 2289 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3025, 0},
+#line 4447 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3026, 0},
+#line 4424 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3027, 0},
+#line 928 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3028, 4},
+#line 2508 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3029, 4},
+#line 4487 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3030, 0},
+#line 502 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3031, 0},
+#line 5165 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3032, 0},
+#line 5164 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3033, 0},
+#line 5129 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3034, 0},
+#line 3364 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3035, 0},
+#line 4211 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3036, 0},
+#line 4480 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3037, 0},
+#line 3862 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3038, 0},
+#line 4362 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3039, 0},
+#line 2371 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3040, 0},
+#line 3094 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3041, 0},
+#line 4420 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3042, 0},
+#line 4847 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3043, 0},
+#line 5142 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3044, 0},
+#line 4405 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3045, 0},
+#line 1272 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3046, 0},
+#line 3565 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3047, 0},
+#line 5136 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3048, 0},
+#line 2629 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3049, 0},
+#line 6471 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3050, 0},
+#line 5255 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3051, 0},
+#line 5130 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3052, 0},
+#line 5912 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3053, 0},
+#line 764 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3054, 0},
+#line 459 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3055, 0},
+#line 4427 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3056, 0},
+#line 1792 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3057, 0},
+#line 4057 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3058, 0},
+#line 5132 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3059, 0},
+#line 2357 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3060, 0},
+#line 4485 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3061, 0},
+#line 2531 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3062, 4},
+#line 4374 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3063, 0},
+#line 974 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3064, 0},
+#line 4138 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3065, 0},
+#line 4943 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3066, 0},
+#line 304 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3067, 0},
+#line 4846 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3068, 0},
+#line 5237 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3069, 0},
+#line 2019 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3070, 0},
+#line 4776 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3071, 0},
+#line 2942 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3072, 0},
+#line 4540 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3073, 0},
+#line 5019 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3074, 0},
+#line 4544 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3075, 0},
+#line 5131 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3076, 0},
+#line 2632 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3077, 0},
+#line 2184 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3078, 0},
+#line 371 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3079, 0},
+#line 2373 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3080, 0},
+#line 135 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3081, 0},
+#line 4370 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3082, 0},
+#line 4416 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3083, 0},
+#line 2389 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3084, 0},
+#line 4401 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3085, 0},
+#line 4403 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3086, 0},
+#line 1420 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3087, 0},
+#line 3863 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3088, 0},
+#line 5404 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3089, 0},
+#line 4415 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3090, 0},
+#line 1190 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3091, 0},
+#line 2731 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3092, 0},
+#line 98 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3093, 0},
+#line 4402 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3094, 0},
+#line 2322 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3095, 0},
+#line 2661 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3096, 0},
+#line 4441 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3097, 0},
+#line 6565 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3098, 0},
+#line 4804 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3099, 0},
+#line 1260 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3100, 0},
+#line 2603 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3101, 0},
+#line 285 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3102, 0},
+#line 4456 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3103, 0},
+#line 2167 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3104, 0},
+#line 5336 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3105, 0},
+#line 4935 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3106, 0},
+#line 2246 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3107, 0},
+#line 1150 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3108, 0},
+#line 781 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3109, 0},
+#line 2546 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3110, 4},
+#line 2229 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3111, 0},
+#line 5203 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3112, 0},
+#line 4419 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3113, 0},
+#line 2768 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3114, 0},
+#line 179 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3115, 0},
+#line 2902 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3116, 0},
+#line 149 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3117, 0},
+#line 2984 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3118, 0},
+#line 5176 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3119, 0},
+#line 256 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3120, 0},
+#line 3601 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3121, 0},
+#line 5936 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3122, 0},
+#line 2292 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3123, 0},
+#line 3011 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3124, 0},
+#line 4391 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3125, 0},
+#line 4465 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3126, 0},
+#line 3595 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3127, 0},
+#line 3790 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3128, 0},
+#line 4407 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3129, 0},
+#line 110 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3130, 0},
+#line 3020 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3131, 0},
+#line 2548 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3132, 4},
+#line 4488 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3133, 0},
+#line 1454 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3134, 0},
+#line 3574 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3135, 0},
+#line 1577 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3136, 0},
+#line 4107 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3137, 0},
+#line 5006 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3138, 0},
+#line 1462 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3139, 0},
+#line 298 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3140, 0},
+#line 3627 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3141, 0},
+#line 5221 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3142, 0},
+#line 624 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3143, 0},
+#line 4363 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3144, 0},
+#line 2293 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3145, 0},
+#line 3825 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3146, 0},
+#line 2527 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3147, 4},
+#line 5020 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3148, 0},
+#line 2537 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3149, 4},
+#line 2863 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3150, 0},
+#line 4414 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3151, 0},
+#line 5428 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3152, 0},
+#line 3126 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3153, 0},
+#line 1675 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3154, 4},
+#line 4481 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3155, 0},
+#line 4865 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3156, 0},
+#line 3088 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3157, 0},
+#line 1549 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3158, 0},
+#line 5184 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3159, 0},
+#line 5263 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3160, 0},
+#line 5398 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3161, 0},
+#line 3788 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3162, 0},
+#line 3753 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3163, 0},
+#line 806 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3164, 0},
+#line 1716 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3165, 0},
+#line 2551 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3166, 4},
+#line 4429 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3167, 0},
+#line 6429 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3168, 0},
+#line 3951 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3169, 0},
+#line 2410 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3170, 0},
+#line 2997 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3171, 0},
+#line 961 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3172, 0},
+#line 4770 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3173, 0},
+#line 6448 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3174, 0},
+#line 1302 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3175, 0},
+#line 1719 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3176, 0},
+#line 3584 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3177, 0},
+#line 1589 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3178, 4},
+#line 3740 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3179, 0},
+#line 4768 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3180, 0},
+#line 1804 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3181, 0},
+#line 843 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3182, 1},
+#line 4442 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3183, 0},
+#line 3374 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3184, 0},
+#line 2294 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3185, 0},
+#line 3632 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3186, 0},
+#line 3029 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3187, 0},
+#line 5097 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3188, 2},
+#line 17 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3189, 0},
+#line 2436 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3190, 0},
+#line 5392 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3191, 0},
+#line 3787 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3192, 0},
+#line 2818 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3193, 0},
+#line 3747 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3194, 0},
+#line 4336 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3195, 0},
+#line 303 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3196, 0},
+#line 6439 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3197, 0},
+#line 1221 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3198, 4},
+#line 520 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3199, 4},
+#line 4513 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3200, 0},
+#line 425 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3201, 0},
+#line 3498 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3202, 0},
+#line 2613 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3203, 0},
+#line 4364 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3204, 0},
+#line 3030 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3205, 0},
+#line 2372 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3206, 0},
+#line 5088 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3207, 4},
+#line 2425 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3208, 0},
+#line 801 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3209, 0},
+#line 2328 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3210, 4},
+#line 96 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3211, 0},
+#line 533 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3212, 4},
+#line 5347 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3213, 0},
+#line 4473 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3214, 0},
+#line 155 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3215, 0},
+#line 4388 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3216, 0},
+#line 590 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3217, 0},
+#line 73 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3218, 0},
+#line 3864 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3219, 0},
+#line 2329 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3220, 0},
+#line 1085 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3221, 0},
+#line 2466 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3222, 0},
+#line 2616 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3223, 0},
+#line 2279 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3224, 4},
+#line 527 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3225, 4},
+#line 5163 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3226, 0},
+#line 2012 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3227, 0},
+#line 4892 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3228, 0},
+#line 4516 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3229, 0},
+#line 531 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3230, 4},
+#line 2602 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3231, 0},
+#line 3087 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3232, 0},
+#line 525 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3233, 4},
+#line 325 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3234, 0},
+#line 591 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3235, 0},
+#line 4369 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3236, 0},
+#line 490 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3237, 0},
+#line 382 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3238, 4},
+#line 401 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3239, 0},
+#line 4090 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3240, 0},
+#line 2203 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3241, 0},
+#line 4759 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3242, 0},
+#line 3097 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3243, 0},
+#line 214 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3244, 0},
+#line 398 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3245, 0},
+#line 2538 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3246, 4},
+#line 478 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3247, 0},
+#line 4483 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3248, 0},
+#line 3860 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3249, 0},
+#line 5139 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3250, 0},
+#line 1703 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3251, 0},
+#line 2323 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3252, 0},
+#line 3681 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3253, 0},
+#line 4128 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3254, 0},
+#line 4536 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3255, 0},
+#line 4412 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3256, 0},
+#line 4373 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3257, 0},
+#line 4974 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3258, 0},
+#line 3881 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3259, 0},
+#line 6072 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3260, 0},
+#line 3040 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3261, 0},
+#line 3826 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3262, 0},
+#line 3024 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3263, 0},
+#line 4877 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3264, 0},
+#line 342 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3265, 0},
+#line 5946 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3266, 0},
+#line 3616 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3267, 0},
+#line 2544 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3268, 4},
+#line 29 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3269, 4},
+#line 528 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3270, 4},
+#line 5443 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3271, 0},
+#line 465 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3272, 0},
+#line 1222 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3273, 4},
+#line 3922 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3274, 0},
+#line 5002 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3275, 0},
+#line 606 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3276, 0},
+#line 607 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3277, 0},
+#line 254 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3278, 0},
+#line 529 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3279, 4},
+#line 4380 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3280, 0},
+#line 523 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3281, 4},
+#line 3677 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3282, 0},
+#line 532 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3283, 4},
+#line 2382 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3284, 0},
+#line 4284 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3285, 0},
+#line 5914 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3286, 0},
+#line 2166 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3287, 0},
+#line 1617 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3288, 0},
+#line 281 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3289, 0},
+#line 1077 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3290, 0},
+#line 2564 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3291, 4},
+#line 4486 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3292, 0},
+#line 4959 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3293, 0},
+#line 3602 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3294, 0},
+#line 324 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3295, 0},
+#line 3906 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3296, 0},
+#line 4079 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3297, 0},
+#line 2624 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3298, 0},
+#line 4165 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3299, 0},
+#line 1723 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3300, 0},
+#line 4466 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3301, 0},
+#line 3836 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3302, 0},
+#line 2215 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3303, 0},
+#line 4448 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3304, 0},
+#line 860 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3305, 4},
+#line 4849 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3306, 0},
+#line 4512 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3307, 0},
+#line 4552 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3308, 0},
+#line 530 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3309, 4},
+#line 1103 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3310, 0},
+#line 3573 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3311, 0},
+#line 2772 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3312, 0},
+#line 6532 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3313, 0},
+#line 844 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3314, 1},
+#line 1757 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3315, 4},
+#line 6064 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3316, 0},
+#line 2408 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3317, 0},
+#line 6065 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3318, 0},
+#line 6014 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3319, 0},
+#line 5835 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3320, 0},
+#line 36 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3321, 0},
+#line 1693 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3322, 0},
+#line 4499 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3323, 0},
+#line 2805 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3324, 0},
+#line 1125 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3325, 0},
+#line 524 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3326, 4},
+#line 5857 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3327, 0},
+#line 377 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3328, 4},
+#line 4988 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3329, 0},
+#line 5081 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3330, 0},
+#line 2396 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3331, 4},
+#line 522 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3332, 4},
+#line 859 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3333, 4},
+#line 4413 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3334, 0},
+#line 493 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3335, 0},
+#line 4792 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3336, 0},
+#line 2604 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3337, 0},
+#line 1864 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3338, 4},
+#line 4489 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3339, 0},
+#line 5190 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3340, 0},
+#line 2540 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3341, 4},
+#line 1225 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3342, 0},
+#line 4089 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3343, 0},
+#line 2541 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3344, 4},
+#line 6108 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3345, 0},
+#line 4400 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3346, 0},
+#line 4398 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3347, 0},
+#line 4399 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3348, 0},
+#line 1734 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3349, 0},
+#line 5205 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3350, 0},
+#line 1705 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3351, 0},
+#line 1873 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3352, 0},
+#line 3372 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3353, 0},
+#line 4397 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3354, 0},
+#line 287 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3355, 0},
+#line 6494 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3356, 0},
+#line 3855 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3357, 0},
+#line 1618 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3358, 0},
+#line 3132 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3359, 0},
+#line 3427 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3360, 0},
+#line 4418 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3361, 0},
+#line 2843 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3362, 0},
+#line 4372 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3363, 0},
+#line 5258 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3364, 0},
+#line 2498 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3365, 4},
+#line 3569 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3366, 0},
+#line 2507 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3367, 4},
+#line 813 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3368, 0},
+#line 213 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3369, 0},
+#line 537 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3370, 4},
+#line 4393 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3371, 0},
+#line 4271 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3372, 0},
+#line 5963 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3373, 0},
+#line 824 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3374, 0},
+#line 2111 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3375, 0},
+#line 2530 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3376, 4},
+#line 3794 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3377, 0},
+#line 2652 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3378, 0},
+#line 306 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3379, 0},
+#line 5844 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3380, 0},
+#line 3037 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3381, 0},
+#line 6539 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3382, 0},
+#line 5351 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3383, 0},
+#line 3765 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3384, 0},
+#line 5133 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3385, 0},
+#line 1623 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3386, 0},
+#line 450 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3387, 0},
+#line 1080 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3388, 0},
+#line 5938 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3389, 0},
+#line 78 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3390, 0},
+#line 300 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3391, 0},
+#line 5952 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3392, 0},
+#line 536 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3393, 4},
+#line 6037 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3394, 0},
+#line 2931 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3395, 0},
+#line 1695 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3396, 0},
+#line 3560 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3397, 0},
+#line 181 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3398, 0},
+#line 4281 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3399, 0},
+#line 4514 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3400, 0},
+#line 1219 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3401, 0},
+#line 5082 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3402, 0},
+#line 402 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3403, 0},
+#line 5170 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3404, 0},
+#line 1413 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3405, 4},
+#line 5183 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3406, 0},
+#line 1704 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3407, 0},
+#line 476 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3408, 0},
+#line 1694 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3409, 0},
+#line 5267 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3410, 0},
+#line 5160 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3411, 0},
+#line 2080 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3412, 0},
+#line 4285 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3413, 0},
+#line 5079 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3414, 0},
+#line 937 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3415, 0},
+#line 6541 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3416, 0},
+#line 526 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3417, 4},
+#line 211 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3418, 0},
+#line 31 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3419, 0},
+#line 4553 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3420, 0},
+#line 2146 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3421, 0},
+#line 2110 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3422, 0},
+#line 6470 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3423, 0},
+#line 768 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3424, 0},
+#line 378 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3425, 4},
+#line 3070 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3426, 0},
+#line 2550 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3427, 4},
+#line 4258 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3428, 0},
+#line 5974 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3429, 0},
+#line 183 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3430, 0},
+#line 6529 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3431, 0},
+#line 3021 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3432, 0},
+#line 1126 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3433, 0},
+#line 2556 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3434, 4},
+#line 3506 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3435, 0},
+#line 861 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3436, 4},
+#line 6517 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3437, 0},
+#line 1709 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3438, 0},
+#line 3500 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3439, 0},
+#line 1701 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3440, 0},
+#line 3010 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3441, 0},
+#line 4314 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3442, 0},
+#line 4074 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3443, 0},
+#line 3127 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3444, 0},
+#line 5196 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3445, 0},
+#line 2461 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3446, 0},
+#line 2286 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3447, 4},
+#line 6528 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3448, 0},
+#line 1721 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3449, 0},
+#line 2618 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3450, 0},
+#line 5940 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3451, 0},
+#line 3053 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3452, 0},
+#line 4307 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3453, 0},
+#line 5199 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3454, 0},
+#line 3919 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3455, 0},
+#line 5167 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3456, 0},
+#line 270 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3457, 0},
+#line 2680 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3458, 0},
+#line 812 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3459, 0},
+#line 2533 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3460, 4},
+#line 1249 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3461, 4},
+#line 3783 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3462, 0},
+#line 4334 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3463, 0},
+#line 4507 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3464, 0},
+#line 2904 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3465, 0},
+#line 6461 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3466, 0},
+#line 5364 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3467, 0},
+#line 5155 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3468, 0},
+#line 4331 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3469, 0},
+#line 1518 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3470, 0},
+#line 1450 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3471, 0},
+#line 131 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3472, 0},
+#line 4997 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3473, 2},
+#line 115 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3474, 0},
+#line 4934 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3475, 0},
+#line 2018 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3476, 4},
+#line 4339 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3477, 0},
+#line 4534 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3478, 0},
+#line 4543 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3479, 0},
+#line 3467 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3480, 0},
+#line 6015 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3481, 0},
+#line 2155 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3482, 0},
+#line 1246 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3483, 4},
+#line 5207 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3484, 0},
+#line 1610 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3485, 0},
+#line 3312 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3486, 0},
+#line 4048 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3487, 0},
+#line 4394 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3488, 0},
+#line 414 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3489, 0},
+#line 1114 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3490, 0},
 #line 5202 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4274, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3491, 0},
+#line 5409 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3492, 0},
+#line 3186 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3493, 0},
+#line 1231 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3494, 4},
+#line 1612 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3495, 0},
+#line 2392 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3496, 0},
+#line 5220 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3497, 0},
+#line 171 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3498, 0},
+#line 570 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3499, 0},
+#line 842 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3500, 1},
+#line 3302 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3501, 0},
+#line 5889 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3502, 0},
+#line 686 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3503, 0},
+#line 419 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3504, 0},
+#line 3152 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3505, 0},
+#line 3164 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3506, 0},
+#line 829 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3507, 0},
+#line 3789 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3508, 0},
+#line 4239 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3509, 0},
+#line 3313 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3510, 0},
+#line 3940 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3511, 0},
+#line 175 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3512, 0},
+#line 182 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3513, 0},
+#line 947 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3514, 0},
+#line 4081 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3515, 0},
+#line 1894 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3516, 0},
+#line 5156 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3517, 0},
+#line 3311 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3518, 0},
+#line 4178 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3519, 0},
+#line 2228 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3520, 0},
+#line 1884 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3521, 0},
+#line 4018 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3522, 0},
+#line 1034 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3523, 0},
+#line 1975 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3524, 0},
+#line 4171 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3525, 0},
+#line 3319 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3526, 0},
+#line 6002 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3527, 0},
+#line 2788 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3528, 0},
+#line 328 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3529, 0},
+#line 1290 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3530, 0},
+#line 3071 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3531, 0},
+#line 5181 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3532, 0},
+#line 1371 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3533, 0},
+#line 2557 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3534, 4},
+#line 3998 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3535, 0},
+#line 1011 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3536, 0},
+#line 4357 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3537, 0},
+#line 1957 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3538, 0},
+#line 2644 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3539, 0},
+#line 307 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3540, 0},
+#line 136 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3541, 0},
+#line 1204 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3542, 4},
+#line 1886 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3543, 0},
+#line 3210 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3544, 0},
+#line 6500 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3545, 0},
+#line 3188 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3546, 0},
+#line 4309 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3547, 0},
+#line 3297 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3548, 0},
+#line 2260 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3549, 4},
+#line 2497 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3550, 4},
+#line 3279 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3551, 0},
+#line 3181 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3552, 0},
+#line 2841 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3553, 0},
+#line 3454 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3554, 0},
+#line 2480 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3555, 0},
+#line 2536 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3556, 4},
+#line 6466 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3557, 0},
+#line 925 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3558, 0},
+#line 1557 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3559, 0},
+#line 3327 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3560, 0},
+#line 4848 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3561, 0},
+#line 2799 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3562, 0},
+#line 1696 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3563, 0},
+#line 4303 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3564, 0},
+#line 483 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3565, 0},
+#line 6446 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3566, 0},
+#line 3686 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3567, 0},
+#line 6013 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3568, 0},
+#line 622 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3569, 0},
+#line 2054 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3570, 0},
+#line 5003 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3571, 0},
+#line 3283 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3572, 0},
+#line 1880 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3573, 0},
+#line 6557 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3574, 0},
+#line 4292 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3575, 0},
+#line 4396 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3576, 0},
+#line 3428 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3577, 0},
+#line 3222 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3578, 0},
+#line 1885 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3579, 0},
+#line 2489 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3580, 0},
+#line 2370 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3581, 0},
+#line 3193 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3582, 0},
+#line 2515 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3583, 4},
+#line 3201 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3584, 0},
+#line 3269 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3585, 0},
+#line 3336 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3586, 0},
+#line 1665 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3587, 4},
+#line 4541 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3588, 0},
+#line 2474 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3589, 0},
+#line 3482 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3590, 0},
+#line 809 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3591, 0},
+#line 839 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3592, 1},
+#line 582 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3593, 0},
+#line 3899 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3594, 0},
+#line 5201 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3595, 0},
+#line 4311 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3596, 0},
+#line 437 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3597, 0},
+#line 1417 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3598, 0},
+#line 3150 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3599, 0},
+#line 3888 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3600, 0},
+#line 1887 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3601, 0},
+#line 3400 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3602, 0},
+#line 1881 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3603, 0},
+#line 695 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3604, 0},
+#line 5192 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3605, 0},
+#line 1237 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3606, 4},
+#line 2376 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3607, 4},
+#line 3865 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3608, 0},
+#line 3824 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3609, 0},
+#line 104 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3610, 0},
+#line 4338 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3611, 0},
+#line 329 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3612, 0},
+#line 275 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3613, 0},
+#line 4490 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3614, 0},
+#line 5966 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3615, 0},
+#line 4083 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3616, 0},
+#line 2140 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3617, 0},
+#line 2558 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3618, 4},
+#line 4999 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3619, 0},
+#line 2552 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3620, 4},
+#line 390 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3621, 0},
+#line 2858 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3622, 0},
+#line 803 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3623, 0},
+#line 6513 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3624, 0},
+#line 5399 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3625, 0},
+#line 3061 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3626, 0},
+#line 2280 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3627, 4},
+#line 5858 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3628, 0},
+#line 454 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3629, 0},
+#line 575 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3630, 0},
+#line 396 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3631, 0},
+#line 4471 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3632, 0},
+#line 293 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3633, 0},
+#line 2518 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3634, 4},
+#line 2307 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3635, 0},
+#line 3318 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3636, 0},
+#line 3270 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3637, 0},
+#line 1664 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3638, 4},
+#line 578 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3639, 0},
+#line 2928 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3640, 0},
+#line 798 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3641, 0},
+#line 2268 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3642, 0},
+#line 3289 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3643, 0},
+#line 1882 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3644, 0},
+#line 479 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3645, 0},
+#line 4531 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3646, 0},
+#line 4266 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3647, 0},
+#line 4822 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3648, 0},
+#line 2532 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3649, 4},
+#line 2334 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3650, 0},
+#line 5400 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3651, 0},
+#line 1418 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3652, 0},
+#line 938 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3653, 0},
+#line 2722 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3654, 0},
+#line 1817 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3655, 0},
+#line 596 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3656, 0},
+#line 3151 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3657, 0},
+#line 2516 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3658, 4},
+#line 366 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3659, 0},
+#line 2592 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3660, 0},
+#line 2096 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3661, 0},
+#line 2511 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3662, 4},
+#line 838 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3663, 0},
+#line 3288 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3664, 0},
+#line 4248 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3665, 0},
+#line 2923 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3666, 0},
+#line 3518 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3667, 0},
+#line 4437 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3668, 0},
+#line 494 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3669, 0},
+#line 273 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3670, 0},
+#line 3519 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3671, 0},
+#line 3877 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3672, 0},
+#line 2236 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3673, 0},
+#line 5253 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3674, 0},
+#line 2589 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3675, 0},
+#line 2929 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3676, 0},
+#line 3276 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3677, 0},
+#line 1241 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3678, 4},
+#line 5356 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3679, 0},
+#line 849 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3680, 0},
+#line 3187 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3681, 0},
+#line 2460 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3682, 0},
+#line 2990 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3683, 0},
+#line 5310 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3684, 0},
+#line 4395 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3685, 0},
+#line 810 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3686, 0},
+#line 4319 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3687, 0},
+#line 1663 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3688, 4},
+#line 373 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3689, 0},
+#line 3453 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3690, 0},
+#line 5070 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3691, 0},
+#line 3285 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3692, 0},
+#line 2519 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3693, 4},
+#line 6482 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3694, 0},
+#line 2309 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3695, 0},
+#line 2493 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3696, 0},
+#line 3111 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3697, 0},
+#line 2295 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3698, 0},
+#line 1725 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3699, 0},
+#line 4955 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3700, 0},
+#line 2269 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3701, 0},
+#line 4425 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3702, 0},
+#line 3373 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3703, 0},
+#line 3561 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3704, 0},
+#line 3267 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3705, 0},
+#line 1710 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3706, 0},
+#line 5860 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3707, 0},
+#line 1487 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3708, 0},
+#line 5968 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3709, 0},
+#line 3599 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3710, 0},
+#line 2617 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3711, 0},
+#line 6016 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3712, 0},
+#line 278 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3713, 0},
+#line 4333 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3714, 0},
+#line 1271 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3715, 0},
+#line 2505 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3716, 4},
+#line 4492 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3717, 0},
+#line 391 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3718, 0},
+#line 6442 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3719, 0},
+#line 1189 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3720, 0},
+#line 3494 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3721, 0},
+#line 5979 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3722, 0},
+#line 5260 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3723, 0},
+#line 5877 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3724, 0},
+#line 3818 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3725, 0},
+#line 1082 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3726, 0},
+#line 5014 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3727, 0},
+#line 5318 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3728, 0},
+#line 4843 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3729, 0},
+#line 580 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3730, 0},
+#line 1522 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3731, 0},
+#line 4953 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3732, 0},
+#line 4330 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3733, 0},
+#line 2894 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3734, 2},
+#line 3130 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3735, 0},
+#line 3823 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3736, 0},
+#line 5189 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3737, 0},
+#line 3452 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3738, 0},
+#line 4296 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3739, 0},
+#line 1707 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3740, 0},
+#line 2217 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3741, 0},
+#line 3339 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3742, 0},
+#line 4841 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3743, 0},
+#line 1488 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3744, 0},
+#line 3146 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3745, 0},
+#line 40 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3746, 0},
+#line 840 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3747, 1},
+#line 4965 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3748, 0},
+#line 4501 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3749, 0},
+#line 201 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3750, 0},
+#line 362 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3751, 0},
+#line 5217 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3752, 0},
+#line 1242 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3753, 4},
+#line 5304 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3754, 0},
+#line 4181 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3755, 0},
+#line 6445 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3756, 0},
+#line 4840 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3757, 0},
+#line 2687 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3758, 0},
+#line 4242 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3759, 0},
+#line 3153 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3760, 0},
+#line 5278 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3761, 0},
+#line 3050 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3762, 0},
+#line 2082 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3763, 0},
+#line 5293 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3764, 0},
+#line 2534 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3765, 4},
+#line 2506 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3766, 4},
+#line 1243 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3767, 4},
+#line 257 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3768, 0},
+#line 2962 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3769, 0},
+#line 305 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3770, 0},
+#line 2689 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3771, 0},
+#line 3199 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3772, 0},
+#line 205 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3773, 0},
+#line 76 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3774, 0},
+#line 5194 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3775, 0},
+#line 3898 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3776, 0},
+#line 6578 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3777, 0},
+#line 4287 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3778, 0},
+#line 6011 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3779, 0},
+#line 6566 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3780, 0},
+#line 6089 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3781, 0},
+#line 3589 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3782, 0},
+#line 3802 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3783, 0},
+#line 4229 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3784, 0},
+#line 3194 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3785, 0},
+#line 1160 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3786, 0},
+#line 2170 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3787, 0},
+#line 4321 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3788, 0},
+#line 3325 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3789, 0},
+#line 6082 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3790, 0},
+#line 4991 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3791, 0},
+#line 5273 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3792, 0},
+#line 1587 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3793, 0},
+#line 4175 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3794, 0},
+#line 3392 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3795, 0},
+#line 3389 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3796, 0},
+#line 1492 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3797, 0},
+#line 4286 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3798, 0},
+#line 6088 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3799, 0},
+#line 5329 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3800, 0},
+#line 5353 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3801, 0},
+#line 5407 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3802, 0},
+#line 4267 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3803, 0},
+#line 1738 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3804, 0},
+#line 6518 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3805, 0},
+#line 5083 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3806, 0},
+#line 3165 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3807, 4},
+#line 5099 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3808, 0},
+#line 5344 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3809, 0},
+#line 1697 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3810, 0},
+#line 2657 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3811, 0},
+#line 4217 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3812, 0},
+#line 5259 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3813, 0},
+#line 1151 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3814, 0},
+#line 6119 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3815, 0},
+#line 3631 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3816, 0},
+#line 4127 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3817, 0},
+#line 1516 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3818, 0},
+#line 619 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3819, 0},
+#line 3777 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3820, 0},
+#line 5374 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3821, 0},
+#line 2133 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3822, 0},
+#line 5360 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3823, 0},
+#line 1594 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3824, 0},
+#line 5235 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3825, 0},
+#line 2650 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3826, 0},
+#line 4111 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3827, 0},
+#line 1442 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3828, 0},
+#line 1191 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3829, 0},
+#line 6540 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3830, 0},
+#line 4265 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3831, 0},
+#line 3702 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3832, 0},
+#line 6122 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3833, 0},
+#line 2282 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3834, 4},
+#line 4491 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3835, 0},
+#line 3280 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3836, 0},
+#line 5265 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3837, 0},
+#line 4308 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3838, 0},
+#line 5410 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3839, 0},
+#line 2499 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3840, 4},
+#line 2277 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3841, 0},
+#line 3305 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3842, 0},
+#line 6435 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3843, 0},
+#line 314 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3844, 0},
+#line 1216 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3845, 0},
+#line 4966 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3846, 0},
+#line 2986 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3847, 0},
+#line 4757 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3848, 0},
+#line 5216 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3849, 0},
+#line 5370 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3850, 0},
+#line 5249 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3851, 0},
+#line 4869 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3852, 0},
+#line 1087 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3853, 0},
+#line 2978 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3854, 0},
+#line 3272 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3855, 0},
+#line 4896 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3856, 0},
+#line 2227 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3857, 0},
+#line 1602 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3858, 0},
+#line 2017 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3859, 4},
+#line 4289 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3860, 0},
+#line 1098 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3861, 0},
+#line 3588 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3862, 0},
+#line 310 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3863, 0},
+#line 6519 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3864, 0},
+#line 2627 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3865, 0},
+#line 3608 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3866, 0},
+#line 2857 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3867, 0},
+#line 5907 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3868, 0},
+#line 3340 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3869, 0},
+#line 1554 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3870, 0},
+#line 1586 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3871, 0},
+#line 4995 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3872, 0},
+#line 5295 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3873, 0},
+#line 3147 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3874, 0},
+#line 3487 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3875, 0},
+#line 4493 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3876, 0},
+#line 2242 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3877, 0},
+#line 6468 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3878, 0},
+#line 2317 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3879, 0},
+#line 599 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3880, 0},
+#line 1240 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3881, 4},
+#line 5375 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3882, 0},
+#line 3163 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3883, 0},
+#line 6542 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3884, 0},
+#line 4937 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3885, 0},
+#line 1706 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3886, 0},
+#line 2198 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3887, 0},
+#line 2935 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3888, 0},
+#line 4952 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3889, 0},
+#line 6130 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3890, 0},
+#line 4853 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3891, 0},
+#line 5852 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3892, 0},
+#line 4356 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3893, 0},
+#line 830 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3894, 0},
+#line 75 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3895, 0},
+#line 3205 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3896, 0},
+#line 1529 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3897, 0},
+#line 2281 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3898, 4},
+#line 2085 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3899, 0},
+#line 4184 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3900, 0},
+#line 4876 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3901, 0},
+#line 3605 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3902, 0},
+#line 2614 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3903, 0},
+#line 4875 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3904, 0},
+#line 936 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3905, 0},
+#line 3689 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3906, 0},
+#line 3177 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3907, 0},
+#line 2636 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3908, 0},
+#line 4861 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3909, 0},
+#line 5854 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3910, 0},
+#line 5089 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3911, 0},
+#line 6118 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3912, 0},
+#line 2226 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3913, 0},
+#line 2806 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3914, 0},
+#line 672 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3915, 0},
+#line 2884 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3916, 0},
+#line 445 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3917, 0},
+#line 3322 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3918, 0},
+#line 5262 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3919, 0},
+#line 152 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3920, 0},
+#line 3607 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3921, 0},
+#line 1595 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3922, 0},
+#line 4798 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3923, 0},
+#line 234 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3924, 0},
+#line 4986 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3925, 0},
+#line 2645 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3926, 0},
+#line 4250 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3927, 0},
+#line 4122 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3928, 0},
+#line 5012 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3929, 0},
+#line 6469 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3930, 0},
+#line 5096 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3931, 0},
+#line 2626 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3932, 0},
+#line 4274 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3933, 0},
+#line 3461 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3934, 0},
+#line 2879 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3935, 0},
+#line 3621 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3936, 0},
+#line 3324 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3937, 0},
+#line 3882 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3938, 0},
+#line 2815 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3939, 0},
+#line 5127 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3940, 0},
+#line 1152 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3941, 0},
+#line 4551 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3942, 0},
+#line 2114 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3943, 0},
+#line 3296 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3944, 0},
+#line 5215 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3945, 0},
+#line 4049 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3946, 0},
+#line 3102 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3947, 0},
+#line 245 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3948, 0},
+#line 3590 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3949, 0},
+#line 5218 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3950, 0},
+#line 3096 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3951, 0},
+#line 2553 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3952, 4},
+#line 1255 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3953, 4},
+#line 4785 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3954, 0},
+#line 5866 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3955, 0},
+#line 5333 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3956, 0},
+#line 1883 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3957, 0},
+#line 1626 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3958, 0},
+#line 5836 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3959, 0},
+#line 5882 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3960, 0},
+#line 3739 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3961, 0},
+#line 355 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3962, 0},
+#line 2266 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3963, 0},
+#line 3648 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3964, 0},
+#line 796 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3965, 0},
+#line 2197 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3966, 0},
+#line 422 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3967, 0},
+#line 5024 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3968, 0},
+#line 4532 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3969, 0},
+#line 5030 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3970, 0},
+#line 5031 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3971, 0},
+#line 3449 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3972, 0},
+#line 3359 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3973, 0},
+#line 2842 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3974, 0},
+#line 4313 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3975, 0},
+#line 3416 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3976, 0},
+#line 1570 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3977, 0},
+#line 1514 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3978, 0},
+#line 2882 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3979, 0},
+#line 2567 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3980, 4},
+#line 5198 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3981, 0},
+#line 2967 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3982, 0},
+#line 4977 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3983, 0},
+#line 5254 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3984, 0},
+#line 4928 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3985, 0},
+#line 3300 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3986, 0},
+#line 1566 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3987, 0},
+#line 2503 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3988, 4},
+#line 3737 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3989, 0},
+#line 2191 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3990, 0},
+#line 3647 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3991, 0},
+#line 5074 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3992, 0},
+#line 4938 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3993, 0},
+#line 3356 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3994, 0},
+#line 5892 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3995, 4},
+#line 1159 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3996, 0},
+#line 6100 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3997, 4},
+#line 660 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3998, 0},
+#line 3275 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str3999, 0},
+#line 2243 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4000, 0},
+#line 2180 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4001, 0},
+#line 369 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4002, 0},
+#line 579 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4003, 0},
+#line 5135 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4004, 0},
+#line 2844 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4005, 0},
+#line 2152 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4006, 0},
+#line 4942 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4007, 0},
+#line 517 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4008, 4},
+#line 5290 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4009, 0},
+#line 1700 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4010, 0},
+#line 6077 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4011, 0},
+#line 5060 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4012, 0},
+#line 4091 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4013, 0},
+#line 5425 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4014, 0},
+#line 2756 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4015, 0},
+#line 5137 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4016, 0},
+#line 1275 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4017, 0},
+#line 3401 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4018, 0},
+#line 3774 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4019, 0},
+#line 3630 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4020, 0},
+#line 3299 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4021, 0},
+#line 6473 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4022, 0},
+#line 3472 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4023, 4},
+#line 2569 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4024, 4},
+#line 5883 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4025, 0},
+#line 3200 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4026, 0},
+#line 1256 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4027, 4},
+#line 1715 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4028, 0},
+#line 3473 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4029, 0},
+#line 2825 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4030, 0},
+#line 2153 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4031, 0},
+#line 2891 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4032, 0},
+#line 2901 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4033, 0},
+#line 4226 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4034, 0},
+#line 1401 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4035, 0},
+#line 2093 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4036, 0},
+#line 3367 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4037, 0},
+#line 99 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4038, 0},
+#line 2570 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4039, 4},
+#line 3575 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4040, 0},
+#line 5976 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4041, 0},
+#line 3055 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4042, 0},
+#line 5138 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4043, 0},
+#line 3352 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4044, 0},
+#line 3953 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4045, 0},
+#line 963 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4046, 0},
+#line 1911 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4047, 0},
+#line 4136 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4048, 0},
+#line 5041 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4049, 2},
+#line 3317 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4050, 0},
+#line 3469 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4051, 0},
+#line 3160 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4052, 0},
+#line 2232 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4053, 0},
+#line 5270 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4054, 0},
+#line 1304 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4055, 0},
+#line 2684 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4056, 4},
+#line 3054 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4057, 0},
+#line 2889 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4058, 0},
+#line 3887 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4059, 1},
+#line 5032 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4060, 0},
+#line 3368 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4061, 0},
+#line 3197 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4062, 0},
+#line 5034 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4063, 0},
+#line 5219 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4064, 0},
+#line 2339 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4065, 0},
+#line 3203 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4066, 0},
+#line 5143 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4067, 0},
+#line 6102 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4068, 4},
+#line 5901 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4069, 0},
+#line 4053 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4070, 0},
+#line 3903 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4071, 0},
+#line 4511 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4072, 0},
+#line 4469 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4073, 0},
+#line 4387 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4074, 0},
+#line 6132 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4075, 4},
+#line 5033 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4076, 0},
+#line 6441 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4077, 0},
+#line 3171 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4078, 0},
+#line 5393 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4079, 0},
+#line 3271 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4080, 0},
+#line 3332 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4081, 0},
+#line 5040 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4082, 0},
+#line 2755 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4083, 0},
+#line 6101 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4084, 4},
+#line 4477 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4085, 0},
+#line 1713 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4086, 0},
+#line 5036 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4087, 0},
+#line 4457 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4088, 0},
+#line 1162 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4089, 0},
+#line 5828 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4090, 0},
+#line 4548 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4091, 0},
+#line 269 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4092, 0},
+#line 2467 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4093, 0},
+#line 3683 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4094, 0},
+#line 5904 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4095, 0},
+#line 6008 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4096, 0},
+#line 2938 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4097, 0},
+#line 6027 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4098, 0},
+#line 4411 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4099, 0},
+#line 3012 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4100, 0},
+#line 3176 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4101, 0},
+#line 6090 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4102, 0},
+#line 4433 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4103, 0},
+#line 3455 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4104, 0},
+#line 5430 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4105, 0},
+#line 3719 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4106, 0},
+#line 3377 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4107, 0},
+#line 1761 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4108, 0},
+#line 474 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4109, 0},
+#line 3883 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4110, 0},
+#line 1740 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4111, 0},
+#line 3281 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4112, 0},
+#line 5047 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4113, 0},
+#line 5916 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4114, 0},
+#line 4375 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4115, 0},
+#line 4310 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4116, 0},
+#line 797 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4117, 0},
+#line 3369 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4118, 0},
+#line 4946 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4119, 0},
+#line 3807 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4120, 0},
+#line 297 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4121, 0},
+#line 5992 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4122, 0},
+#line 3328 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4123, 0},
+#line 3547 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4124, 0},
+#line 5373 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4125, 0},
+#line 3013 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4126, 0},
+#line 3292 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4127, 0},
+#line 2244 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4128, 0},
+#line 3625 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4129, 0},
+#line 4298 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4130, 0},
+#line 6537 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4131, 0},
+#line 2797 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4132, 0},
+#line 4933 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4133, 0},
+#line 3294 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4134, 0},
+#line 5197 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4135, 0},
+#line 2173 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4136, 0},
+#line 5039 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4137, 0},
+#line 6476 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4138, 0},
+#line 2925 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4139, 0},
+#line 5078 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4140, 0},
+#line 1718 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4141, 0},
+#line 5186 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4142, 0},
+#line 6493 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4143, 0},
+#line 5257 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4144, 0},
+#line 4992 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4145, 0},
+#line 1422 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4146, 0},
+#line 1780 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4147, 0},
+#line 3412 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4148, 0},
+#line 3563 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4149, 0},
+#line 434 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4150, 0},
+#line 2770 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4151, 0},
+#line 3462 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4152, 0},
+#line 3295 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4153, 0},
+#line 3812 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4154, 0},
+#line 4950 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4155, 0},
+#line 108 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4156, 0},
+#line 2586 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4157, 0},
+#line 3486 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4158, 0},
+#line 3828 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4159, 0},
+#line 1168 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4160, 0},
+#line 3189 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4161, 0},
+#line 3032 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4162, 0},
+#line 6022 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4163, 0},
+#line 5091 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4164, 4},
+#line 138 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4165, 0},
+#line 1688 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4166, 0},
+#line 1815 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4167, 0},
+#line 3278 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4168, 0},
+#line 6485 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4169, 0},
+#line 3256 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4170, 0},
+#line 3220 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4171, 0},
+#line 3251 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4172, 0},
+#line 3252 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4173, 0},
+#line 3830 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4174, 0},
+#line 3254 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4175, 0},
+#line 3330 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4176, 0},
+#line 5868 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4177, 0},
+#line 5145 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4178, 0},
+#line 3076 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4179, 0},
+#line 4976 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4180, 0},
+#line 2367 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4181, 0},
+#line 4519 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4182, 0},
+#line 6050 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4183, 0},
+#line 5923 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4184, 0},
+#line 5846 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4185, 0},
+#line 3448 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4186, 0},
+#line 3213 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4187, 0},
+#line 3212 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4188, 0},
+#line 3214 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4189, 0},
+#line 3257 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4190, 0},
+#line 4895 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4191, 0},
+#line 1438 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4192, 0},
+#line 3215 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4193, 0},
+#line 3258 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4194, 0},
+#line 3820 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4195, 0},
+#line 4324 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4196, 0},
+#line 5402 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4197, 0},
+#line 3260 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4198, 0},
+#line 4306 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4199, 0},
+#line 3221 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4200, 0},
+#line 5989 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4201, 0},
+#line 2703 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4202, 0},
+#line 4948 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4203, 0},
+#line 2960 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4204, 0},
+#line 3699 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4205, 0},
+#line 3241 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4206, 0},
+#line 202 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4207, 0},
+#line 3485 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4208, 0},
+#line 2741 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4209, 0},
+#line 3238 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4210, 0},
+#line 5187 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4211, 0},
+#line 3240 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4212, 0},
+#line 5038 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4213, 0},
+#line 3229 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4214, 0},
+#line 5126 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4215, 0},
+#line 3639 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4216, 0},
+#line 2659 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4217, 0},
+#line 3230 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4218, 0},
+#line 3235 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4219, 0},
+#line 2615 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4220, 0},
+#line 5049 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4221, 0},
+#line 3236 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4222, 0},
+#line 3228 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4223, 0},
+#line 3242 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4224, 0},
+#line 2187 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4225, 0},
+#line 2883 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4226, 0},
+#line 1699 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4227, 0},
+#line 6564 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4228, 0},
+#line 5920 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4229, 0},
+#line 3253 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4230, 0},
+#line 3243 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4231, 0},
+#line 5383 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4232, 4},
+#line 4973 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4233, 0},
+#line 3263 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4234, 0},
+#line 6488 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4235, 0},
+#line 3244 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4236, 0},
+#line 3246 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4237, 0},
+#line 5328 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4238, 4},
+#line 2340 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4239, 0},
+#line 97 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4240, 0},
+#line 3562 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4241, 0},
+#line 4269 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4242, 0},
+#line 3303 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4243, 0},
+#line 6028 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4244, 0},
+#line 2701 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4245, 0},
+#line 4985 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4246, 0},
+#line 3731 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4247, 0},
+#line 4936 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4248, 0},
+#line 6009 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4249, 0},
+#line 6091 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4250, 0},
+#line 3234 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4251, 0},
+#line 3268 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4252, 0},
+#line 1578 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4253, 0},
+#line 3166 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4254, 0},
+#line 3009 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4255, 0},
+#line 5421 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4256, 0},
+#line 1686 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4257, 0},
+#line 3227 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4258, 0},
+#line 5307 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4259, 0},
+#line 3247 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4260, 0},
+#line 3629 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4261, 0},
+#line 4828 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4262, 4},
+#line 5059 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4263, 0},
+#line 4981 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4264, 0},
+#line 1689 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4265, 0},
+#line 3231 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4266, 0},
+#line 5073 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4267, 0},
+#line 1655 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4268, 4},
+#line 1669 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4269, 4},
+#line 3157 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4270, 0},
+#line 3456 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4271, 0},
+#line 3167 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4272, 0},
+#line 1714 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4273, 0},
+#line 1635 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4274, 4},
 #line 2136 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str4275, 0},
-#line 2008 "effective_tld_names.gperf"
+#line 3233 "effective_tld_names.gperf"
       {(int)(long)&((struct stringpool_t *)0)->stringpool_str4276, 0},
-#line 1628 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4277, 4},
-#line 1655 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4278, 4},
-#line 2070 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4279, 0},
-#line 1662 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4280, 4},
-#line 1649 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4281, 4},
-#line 2227 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4282, 0},
-#line 179 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4283, 0},
-#line 1659 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4284, 4},
-#line 6448 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4285, 0},
-#line 2024 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4286, 0},
-#line 3780 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4287, 0},
-#line 2016 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4288, 0},
-#line 1615 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4289, 4},
-#line 6166 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4290, 0},
-#line 1521 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4291, 0},
-#line 5247 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4292, 0},
-#line 209 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4293, 0},
-#line 1065 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4294, 0},
-#line 5304 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4295, 0},
-#line 2621 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4296, 0},
-#line 5479 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4297, 0},
-#line 3011 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4298, 0},
-#line 5290 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4299, 0},
-#line 2781 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4300, 0},
-#line 312 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4301, 0},
-#line 4996 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4302, 0},
-#line 3584 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4303, 4},
-#line 3498 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4304, 0},
-#line 5475 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4305, 0},
-#line 1616 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4306, 4},
-#line 5370 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4307, 0},
-#line 6203 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4308, 0},
-#line 1643 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4309, 4},
-#line 5693 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4310, 0},
-#line 4998 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4311, 0},
-#line 1244 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4312, 4},
-#line 303 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4313, 0},
-#line 2137 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4314, 0},
-#line 2027 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4315, 0},
-#line 2283 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4316, 0},
-#line 4273 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4317, 0},
-#line 5255 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4318, 0},
-#line 809 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4319, 0},
-#line 2204 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4320, 0},
-#line 1491 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4321, 0},
-#line 4837 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4322, 0},
-#line 2028 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4323, 0},
-#line 2897 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4324, 0},
-#line 2556 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4325, 0},
-#line 5329 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4326, 0},
-#line 3843 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4327, 0},
-#line 1584 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4328, 0},
-#line 5283 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4329, 0},
-#line 3394 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4330, 0},
-#line 299 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4331, 0},
-#line 2188 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4332, 0},
-#line 4891 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4333, 0},
-#line 251 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4334, 0},
-#line 6030 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4335, 0},
-#line 5032 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4336, 4},
-#line 3299 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4337, 0},
-#line 126 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4338, 0},
-#line 2963 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4339, 0},
-#line 3181 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4340, 0},
-#line 4810 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4341, 0},
-#line 5204 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4342, 0},
-#line 267 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4343, 0},
-#line 2187 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4344, 0},
-#line 4302 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4345, 0},
-#line 3674 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4346, 0},
-#line 2026 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4347, 0},
-#line 4559 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4348, 0},
-#line 798 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4349, 0},
-#line 5302 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4350, 0},
-#line 5608 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4351, 0},
-#line 5242 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4352, 0},
-#line 1561 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4353, 0},
-#line 3001 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4354, 0},
-#line 5067 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4355, 4},
-#line 819 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4356, 0},
-#line 1650 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4357, 4},
-#line 4474 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4358, 0},
-#line 774 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4359, 0},
-#line 6221 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4360, 0},
-#line 4764 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4361, 0},
-#line 4997 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4362, 0},
-#line 1556 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4363, 0},
-#line 4684 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4364, 0},
-#line 834 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4365, 1},
-#line 5442 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4366, 0},
-#line 4981 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4367, 0},
-#line 3873 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4368, 0},
-#line 3346 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4369, 0},
-#line 3388 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4370, 0},
-#line 3285 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4371, 0},
-#line 3570 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4372, 0},
-#line 6120 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4373, 0},
-#line 2076 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4374, 0},
-#line 5000 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4375, 0},
-#line 5454 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4376, 0},
-#line 2878 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4377, 0},
-#line 5839 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4378, 0},
-#line 1118 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4379, 0},
-#line 929 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4380, 0},
-#line 3743 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4381, 0},
-#line 6165 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4382, 0},
-#line 5506 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4383, 0},
-#line 633 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4384, 0},
-#line 6393 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4385, 0},
-#line 5430 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4386, 0},
-#line 1512 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4387, 0},
-#line 6364 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4388, 0},
-#line 5188 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4389, 0},
-#line 5464 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4390, 0},
-#line 5307 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4391, 0},
-#line 3262 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4392, 0},
-#line 6513 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4393, 0},
-#line 1642 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4394, 4},
-#line 3058 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4395, 0},
-#line 1742 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4396, 0},
-#line 5390 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4397, 0},
-#line 5031 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4398, 4},
-#line 4957 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4399, 0},
-#line 1221 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4400, 0},
-#line 4851 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4401, 0},
-#line 5004 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4402, 0},
-#line 2012 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4403, 0},
-#line 329 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4404, 0},
-#line 3790 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4405, 0},
-#line 3362 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4406, 0},
-#line 4491 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4407, 0},
-#line 3039 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4408, 0},
-#line 6445 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4409, 0},
-#line 202 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4410, 0},
-#line 5376 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4411, 0},
-#line 3439 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4412, 0},
-#line 5191 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4413, 0},
-#line 1557 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4414, 0},
-#line 746 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4415, 0},
-#line 2819 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4416, 0},
-#line 6207 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4417, 0},
-#line 6442 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4418, 0},
-#line 6394 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4419, 0},
-#line 169 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4420, 0},
-#line 5335 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4421, 0},
-#line 5397 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4422, 0},
-#line 3052 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4423, 0},
-#line 3082 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4424, 0},
-#line 2097 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4425, 0},
-#line 3302 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4426, 0},
-#line 3352 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4427, 0},
-#line 3330 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4428, 0},
-#line 3832 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4429, 0},
-#line 2020 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4430, 0},
-#line 5310 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4431, 0},
-#line 5453 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4432, 0},
-#line 1257 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4433, 0},
-#line 4887 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4434, 4},
-#line 2774 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4435, 0},
-#line 4986 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4436, 0},
-#line 3092 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4437, 0},
-#line 4524 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4438, 0},
-#line 2612 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4439, 0},
-#line 1248 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4440, 4},
-#line 5054 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4441, 4},
-#line 343 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4442, 0},
-#line 2836 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4443, 0},
-#line 4018 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4444, 0},
-#line 647 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4445, 0},
-#line 5649 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4446, 0},
-#line 3093 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4447, 0},
-#line 4128 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4448, 0},
-#line 1641 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4449, 4},
-#line 2619 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4450, 0},
-#line 6361 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4451, 0},
-#line 6257 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4452, 0},
-#line 5753 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4453, 0},
-#line 6045 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4454, 0},
-#line 1702 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4455, 0},
-#line 4465 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4456, 0},
-#line 2816 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4457, 0},
-#line 3711 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4458, 0},
-#line 1651 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4459, 4},
-#line 1660 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4460, 4},
-#line 2035 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4461, 0},
-#line 5158 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4462, 0},
-#line 1808 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4463, 0},
-#line 3555 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4464, 0},
-#line 3020 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4465, 0},
-#line 5729 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4466, 0},
-#line 2009 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4467, 0},
-#line 2246 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4468, 0},
-#line 5291 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4469, 4},
-#line 1726 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4470, 0},
-#line 573 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4471, 0},
-#line 415 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4472, 0},
-#line 2790 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4473, 0},
-#line 301 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4474, 0},
-#line 1392 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4475, 0},
-#line 5053 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4476, 0},
-#line 5110 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4477, 0},
-#line 142 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4478, 0},
-#line 1654 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4479, 4},
-#line 1709 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4480, 0},
-#line 4637 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4481, 0},
-#line 1612 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4482, 4},
-#line 5260 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4483, 0},
-#line 3078 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4484, 0},
-#line 464 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4485, 0},
-#line 503 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4486, 0},
-#line 5596 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4487, 0},
-#line 5619 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4488, 0},
-#line 2859 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4489, 0},
-#line 2978 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4490, 0},
-#line 2801 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4491, 0},
-#line 3834 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4492, 0},
-#line 1715 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4493, 0},
-#line 2387 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4494, 0},
-#line 3858 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4495, 0},
-#line 2493 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4496, 4},
-#line 2884 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4497, 0},
-#line 5192 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4498, 0},
-#line 2010 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4499, 0},
-#line 1435 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4500, 0},
-#line 4673 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4501, 0},
-#line 2121 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4502, 0},
-#line 4586 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4503, 0},
-#line 269 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4504, 0},
-#line 5294 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4505, 0},
-#line 2285 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4506, 0},
-#line 2354 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4507, 0},
-#line 255 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4508, 0},
-#line 6247 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4509, 0},
-#line 2348 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4510, 0},
-#line 2611 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4511, 0},
-#line 1640 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4512, 4},
-#line 5942 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4513, 0},
-#line 3545 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4514, 0},
-#line 5703 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4515, 0},
-#line 2272 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4516, 0},
-#line 3134 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4517, 0},
-#line 6249 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4518, 0},
-#line 5509 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4519, 0},
-#line 148 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4520, 0},
-#line 1623 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4521, 4},
-#line 1661 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4522, 4},
-#line 2815 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4523, 0},
-#line 1625 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4524, 4},
-#line 2317 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4525, 0},
-#line 2022 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4526, 0},
-#line 3438 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4527, 0},
-#line 5091 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4528, 0},
-#line 1644 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4529, 4},
-#line 5692 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4530, 0},
-#line 1113 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4531, 1},
-#line 2112 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4532, 0},
-#line 791 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4533, 0},
-#line 5022 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4534, 0},
-#line 1613 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4535, 4},
-#line 3511 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4536, 0},
-#line 4101 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4537, 0},
-#line 4905 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4538, 0},
-#line 3342 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4539, 0},
-#line 2268 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4540, 0},
-#line 5937 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4541, 0},
-#line 1801 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4542, 0},
-#line 1621 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4543, 4},
-#line 2974 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4544, 0},
-#line 4253 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4545, 0},
-#line 1619 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4546, 4},
-#line 1617 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4547, 4},
-#line 2871 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4548, 0},
-#line 3774 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4549, 0},
-#line 3686 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4550, 0},
-#line 5595 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4551, 0},
-#line 5924 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4552, 0},
-#line 1576 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4553, 0},
-#line 6345 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4554, 0},
-#line 6174 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4555, 0},
-#line 6374 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4556, 0},
-#line 577 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4557, 0},
-#line 4852 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4558, 0},
-#line 2352 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4559, 0},
-#line 2216 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4560, 0},
-#line 5002 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4561, 0},
-#line 353 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4562, 0},
-#line 6202 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4563, 0},
-#line 4098 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4564, 0},
-#line 5003 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4565, 0},
-#line 3423 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4566, 0},
-#line 2989 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4567, 0},
-#line 167 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4568, 0},
-#line 5112 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4569, 0},
-#line 3875 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4570, 0},
-#line 5614 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4571, 0},
-#line 2315 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4572, 0},
-#line 2494 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4573, 4},
-#line 1590 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4574, 0},
-#line 2014 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4575, 0},
-#line 1656 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4576, 4},
-#line 1581 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4577, 0},
-#line 4971 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4578, 0},
-#line 1611 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4579, 4},
-#line 6282 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4580, 0},
-#line 5167 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4581, 0},
-#line 6193 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4582, 0},
-#line 6331 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4583, 0},
-#line 4123 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4584, 0},
-#line 2741 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4585, 0},
-#line 5819 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4586, 0},
-#line 3872 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4587, 0},
-#line 1246 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4588, 4},
-#line 2343 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4589, 0},
-#line 2156 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4590, 0},
-#line 4131 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4591, 0},
-#line 3612 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4592, 0},
-#line 180 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4593, 0},
-#line 2480 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4594, 4},
-#line 1164 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4595, 0},
-#line 4233 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4596, 0},
-#line 4191 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4597, 0},
-#line 5868 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4598, 0},
-#line 5383 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4599, 0},
-#line 4959 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4600, 0},
-#line 4230 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4601, 0},
-#line 5899 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4602, 0},
-#line 4666 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4603, 0},
-#line 463 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4604, 0},
-#line 575 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4605, 0},
-#line 4497 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4606, 0},
-#line 122 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4607, 0},
-#line 4955 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4608, 0},
-#line 1547 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4609, 0},
-#line 2746 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4610, 0},
-#line 5429 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4611, 0},
-#line 6397 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4612, 0},
-#line 321 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4613, 0},
-#line 2209 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4614, 0},
-#line 4228 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4615, 0},
-#line 5623 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4616, 0},
-#line 3139 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4617, 0},
-#line 6352 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4618, 0},
-#line 3509 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4619, 0},
-#line 2585 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4620, 0},
-#line 5913 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4621, 0},
-#line 662 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4622, 0},
-#line 5117 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4623, 0},
-#line 5536 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4624, 0},
-#line 3310 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4625, 0},
-#line 4078 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4626, 0},
-#line 2148 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4627, 0},
-#line 5997 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4628, 0},
-#line 2926 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4629, 0},
-#line 4478 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4630, 0},
-#line 1219 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4631, 0},
-#line 2281 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4632, 0},
-#line 4248 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4633, 0},
-#line 133 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4634, 0},
-#line 178 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4635, 0},
-#line 1438 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4636, 0},
-#line 5695 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4637, 0},
-#line 3799 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4638, 0},
-#line 367 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4639, 0},
-#line 3365 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4640, 0},
-#line 5063 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4641, 0},
-#line 2353 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4642, 0},
-#line 3554 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4643, 0},
-#line 5816 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4644, 0},
-#line 5875 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4645, 0},
-#line 2802 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4646, 0},
-#line 3721 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4647, 0},
-#line 4606 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4648, 0},
-#line 1552 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4649, 0},
-#line 1705 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4650, 0},
-#line 433 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4651, 0},
-#line 3524 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4652, 0},
-#line 3518 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4653, 0},
-#line 3466 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4654, 0},
-#line 4950 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4655, 0},
-#line 419 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4656, 0},
-#line 5023 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4657, 0},
-#line 2345 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4658, 0},
-#line 436 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4659, 0},
-#line 2013 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4660, 0},
-#line 618 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4661, 0},
-#line 6500 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4662, 0},
-#line 3380 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4663, 0},
-#line 3642 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4664, 0},
-#line 5214 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4665, 0},
-#line 400 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4666, 0},
-#line 4022 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4667, 0},
-#line 4802 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4668, 0},
-#line 5907 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4669, 0},
-#line 3897 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4670, 0},
-#line 4473 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4671, 0},
-#line 6312 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4672, 0},
-#line 5935 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4673, 0},
-#line 5686 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4674, 0},
-#line 776 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4675, 0},
-#line 6501 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4676, 0},
-#line 6429 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4677, 0},
-#line 5205 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4678, 0},
-#line 6443 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4679, 0},
-#line 147 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4680, 0},
-#line 4199 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4681, 0},
-#line 4518 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4682, 0},
-#line 4493 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4683, 0},
-#line 4192 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4684, 0},
-#line 4150 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4685, 0},
-#line 5719 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4686, 0},
-#line 6248 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4687, 0},
-#line 3416 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4688, 0},
-#line 6428 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4689, 0},
-#line 2226 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4690, 0},
-#line 5104 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4691, 0},
-#line 3133 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4692, 0},
-#line 4580 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4693, 0},
-#line 5305 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4694, 0},
-#line 6250 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4695, 0},
-#line 3440 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4696, 0},
-#line 6438 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4697, 0},
-#line 5092 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4698, 0},
-#line 5577 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4699, 0},
-#line 4307 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4700, 0},
-#line 1442 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4701, 0},
-#line 1138 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4702, 0},
-#line 5721 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4703, 0},
-#line 5295 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4704, 0},
-#line 5194 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4705, 0},
-#line 1626 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4706, 4},
-#line 2887 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4707, 0},
-#line 1127 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4708, 0},
-#line 3356 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4709, 0},
-#line 4693 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4710, 0},
-#line 6223 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4711, 0},
-#line 4527 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4712, 0},
-#line 6168 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4713, 0},
-#line 4514 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4714, 0},
-#line 2390 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4715, 0},
-#line 5418 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4716, 0},
-#line 5537 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4717, 0},
-#line 4204 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4718, 0},
-#line 283 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4719, 0},
-#line 5125 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4720, 0},
-#line 5353 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4721, 0},
-#line 3530 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4722, 0},
-#line 3739 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4723, 0},
-#line 3005 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4724, 0},
-#line 263 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4725, 0},
-#line 1627 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4726, 4},
-#line 2438 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4727, 0},
-#line 119 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4728, 0},
-#line 3480 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4729, 0},
-#line 2636 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4730, 0},
-#line 1620 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4731, 4},
-#line 1548 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4732, 0},
-#line 6328 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4733, 0},
-#line 3549 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4734, 0},
-#line 5387 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4735, 0},
-#line 4496 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4736, 0},
-#line 5705 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4737, 0},
-#line 3250 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4738, 4},
-#line 6078 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4739, 0},
-#line 416 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4740, 0},
-#line 800 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4741, 0},
-#line 5901 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4742, 0},
-#line 2813 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4743, 0},
-#line 4862 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4744, 0},
-#line 3512 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4745, 0},
-#line 3669 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4746, 0},
-#line 799 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4747, 0},
-#line 360 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4748, 0},
-#line 2472 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4749, 0},
-#line 4590 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4750, 0},
-#line 6173 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4751, 0},
-#line 4275 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4752, 0},
-#line 3648 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4753, 0},
-#line 5313 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4754, 0},
-#line 5058 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4755, 0},
-#line 5099 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4756, 0},
-#line 2920 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4757, 0},
-#line 5127 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4758, 0},
-#line 3429 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4759, 0},
-#line 2712 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4760, 0},
-#line 2713 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4761, 0},
-#line 2063 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4762, 0},
-#line 3102 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4763, 0},
-#line 2682 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4764, 0},
-#line 5694 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4765, 0},
-#line 2715 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4766, 0},
-#line 2259 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4767, 4},
-#line 2610 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4768, 0},
-#line 2717 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4769, 0},
-#line 4588 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4770, 0},
-#line 2924 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4771, 0},
-#line 2745 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4772, 0},
-#line 620 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4773, 0},
-#line 5248 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4774, 0},
-#line 2339 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4775, 0},
-#line 127 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4776, 0},
-#line 3792 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4777, 0},
-#line 1128 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4778, 0},
-#line 2458 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4779, 0},
-#line 2955 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4780, 0},
-#line 4975 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4781, 0},
-#line 5987 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4782, 0},
-#line 3490 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4783, 0},
-#line 5120 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4784, 0},
-#line 129 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4785, 0},
-#line 2108 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4786, 0},
-#line 3861 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4787, 0},
-#line 2675 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4788, 0},
-#line 2674 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4789, 0},
-#line 2676 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4790, 0},
-#line 5927 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4791, 0},
-#line 2838 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4792, 0},
-#line 3837 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4793, 0},
-#line 5073 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4794, 0},
-#line 1224 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4795, 4},
-#line 6460 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4796, 0},
-#line 807 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4797, 0},
-#line 4669 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4798, 0},
-#line 5953 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4799, 0},
-#line 1850 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4800, 0},
-#line 2719 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4801, 0},
-#line 6032 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4802, 0},
-#line 614 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4803, 0},
-#line 4193 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4804, 0},
-#line 4849 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4805, 0},
-#line 2677 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4806, 0},
-#line 5401 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4807, 0},
-#line 3332 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4808, 0},
-#line 1699 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4809, 0},
-#line 3286 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4810, 0},
-#line 5783 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4811, 0},
-#line 2388 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4812, 0},
-#line 2507 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4813, 4},
-#line 5706 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4814, 0},
-#line 5508 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4815, 0},
-#line 359 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4816, 0},
-#line 5406 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4817, 0},
-#line 2521 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4818, 4},
-#line 4186 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4819, 0},
-#line 2151 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4820, 0},
-#line 2718 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4821, 0},
-#line 5113 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4822, 0},
-#line 3119 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4823, 0},
-#line 5171 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4824, 0},
-#line 2720 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4825, 0},
-#line 5094 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4826, 0},
-#line 2854 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4827, 0},
-#line 2683 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4828, 0},
-#line 2075 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4829, 0},
-#line 5585 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4830, 0},
-#line 5589 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4831, 0},
-#line 3309 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4832, 0},
-#line 3158 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4833, 0},
-#line 2271 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4834, 0},
-#line 6246 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4835, 0},
-#line 2202 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4836, 0},
-#line 3297 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4837, 0},
-#line 383 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4838, 0},
-#line 286 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4839, 0},
-#line 198 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4840, 0},
-#line 5828 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4841, 0},
-#line 2313 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4842, 0},
-#line 6255 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4843, 0},
-#line 177 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4844, 0},
-#line 2702 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4845, 0},
-#line 1601 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4846, 0},
-#line 5166 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4847, 0},
-#line 3835 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4848, 0},
-#line 604 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4849, 0},
-#line 1490 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4850, 0},
-#line 1991 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4851, 0},
-#line 1600 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4852, 0},
-#line 5211 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4853, 0},
-#line 5251 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4854, 0},
-#line 5616 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4855, 0},
-#line 2591 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4856, 0},
-#line 2102 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4857, 0},
-#line 2073 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4858, 0},
-#line 2699 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4859, 0},
-#line 6140 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4860, 0},
-#line 3611 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4861, 0},
-#line 4856 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4862, 0},
-#line 4490 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4863, 0},
-#line 2541 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4864, 4},
-#line 2701 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4865, 0},
-#line 5333 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4866, 0},
-#line 5237 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4867, 0},
-#line 2690 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4868, 0},
-#line 583 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4869, 0},
-#line 4254 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4870, 0},
-#line 1706 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4871, 0},
-#line 498 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4872, 0},
-#line 3385 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4873, 0},
-#line 5064 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4874, 0},
-#line 2288 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4875, 0},
-#line 4494 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4876, 0},
-#line 2703 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4877, 0},
-#line 2691 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4878, 0},
-#line 2316 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4879, 0},
-#line 6142 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4880, 0},
-#line 4668 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4881, 0},
-#line 6401 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4882, 0},
-#line 2620 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4883, 0},
-#line 6220 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4884, 0},
-#line 6034 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4885, 0},
-#line 333 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4886, 0},
-#line 2975 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4887, 0},
-#line 2308 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4888, 0},
-#line 2696 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4889, 0},
-#line 3013 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4890, 0},
-#line 1517 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4891, 0},
-#line 3456 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4892, 0},
-#line 6464 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4893, 0},
-#line 5563 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4894, 0},
-#line 5655 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4895, 0},
-#line 2812 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4896, 0},
-#line 3307 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4897, 0},
-#line 2834 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4898, 0},
-#line 4286 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4899, 0},
-#line 282 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4900, 0},
-#line 4061 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4901, 0},
-#line 2697 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4902, 0},
-#line 2138 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4903, 0},
-#line 1495 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4904, 0},
-#line 2689 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4905, 0},
-#line 1215 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4906, 0},
-#line 3596 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4907, 0},
-#line 4908 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4908, 0},
-#line 930 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4909, 0},
-#line 432 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4910, 0},
-#line 4605 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4911, 0},
-#line 4189 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4912, 0},
-#line 1663 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4913, 0},
-#line 2704 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4914, 0},
-#line 2692 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4915, 0},
-#line 4611 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4916, 0},
-#line 2614 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4917, 0},
-#line 1606 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4918, 0},
-#line 5962 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4919, 0},
-#line 1406 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4920, 0},
-#line 4906 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4921, 0},
-#line 1062 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4922, 4},
-#line 2243 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4923, 0},
-#line 1061 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4924, 4},
-#line 5793 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4925, 0},
-#line 842 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4926, 0},
-#line 2705 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4927, 0},
-#line 2110 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4928, 0},
-#line 1475 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4929, 0},
-#line 3369 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4930, 0},
-#line 2707 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4931, 0},
-#line 4762 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4932, 0},
-#line 5330 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4933, 0},
-#line 3898 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4934, 0},
-#line 4838 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4935, 0},
-#line 3586 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4936, 0},
-#line 6138 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4937, 0},
-#line 1074 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4938, 0},
-#line 2714 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4939, 0},
-#line 4185 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4940, 0},
-#line 5782 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4941, 0},
-#line 5860 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4942, 0},
-#line 5659 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4943, 0},
-#line 3558 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4944, 0},
-#line 378 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4945, 4},
-#line 1608 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4946, 0},
-#line 2165 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4947, 0},
-#line 6026 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4948, 0},
-#line 160 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4949, 0},
-#line 4787 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4950, 0},
-#line 2855 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4951, 0},
-#line 2096 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4952, 0},
-#line 1087 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4953, 0},
-#line 4836 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4954, 0},
-#line 358 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4955, 0},
-#line 4711 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4956, 0},
-#line 3635 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4957, 0},
-#line 6417 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4958, 0},
-#line 6283 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4959, 0},
-#line 2601 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4960, 0},
-#line 4495 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4961, 0},
-#line 2350 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4962, 0},
-#line 4287 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4963, 0},
-#line 1474 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4964, 0},
-#line 5325 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4965, 0},
-#line 5850 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4966, 0},
-#line 3798 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4967, 0},
-#line 401 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4968, 0},
-#line 6038 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4969, 0},
-#line 4224 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4970, 0},
-#line 36 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4971, 0},
-#line 1523 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4972, 0},
-#line 5272 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4973, 0},
-#line 2273 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4974, 0},
-#line 5495 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4975, 0},
-#line 2529 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4976, 4},
-#line 3606 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4977, 0},
-#line 6406 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4978, 0},
-#line 6164 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4979, 0},
-#line 5602 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4980, 0},
-#line 2483 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4981, 4},
-#line 3018 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4982, 0},
-#line 5450 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4983, 0},
-#line 2510 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4984, 4},
-#line 3601 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4985, 0},
-#line 6322 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4986, 0},
-#line 5006 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4987, 0},
-#line 3374 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4988, 0},
-#line 4727 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4989, 0},
-#line 4737 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4990, 0},
-#line 252 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4991, 0},
-#line 4176 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4992, 0},
-#line 4751 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4993, 0},
-#line 4283 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4994, 0},
-#line 6409 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4995, 0},
-#line 2296 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4996, 0},
-#line 6237 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4997, 0},
-#line 4169 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4998, 0},
-#line 2678 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4999, 0},
-#line 2988 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5000, 0},
-#line 3225 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5001, 0},
-#line 6211 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5002, 0},
-#line 5115 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5003, 0},
-#line 3110 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5004, 0},
-#line 6206 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5005, 0},
-#line 3577 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5006, 0},
-#line 3075 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5007, 0},
-#line 2695 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5008, 0},
-#line 29 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5009, 4},
-#line 1999 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5010, 4},
-#line 2716 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5011, 0},
-#line 4626 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5012, 4},
-#line 3378 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5013, 0},
-#line 625 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5014, 0},
-#line 4773 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5015, 0},
-#line 2688 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5016, 0},
-#line 2796 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5017, 0},
-#line 1466 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5018, 4},
-#line 270 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5019, 0},
-#line 5082 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5020, 0},
-#line 2856 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5021, 0},
-#line 3282 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5022, 0},
-#line 3543 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5023, 0},
-#line 1084 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5024, 0},
-#line 2750 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5025, 0},
-#line 1208 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5026, 0},
-#line 1536 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5027, 0},
-#line 311 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5028, 0},
-#line 398 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5029, 0},
-#line 3663 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5030, 0},
-#line 2368 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5031, 0},
-#line 2147 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5032, 0},
-#line 5081 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5033, 0},
-#line 4546 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5034, 0},
-#line 1810 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5035, 0},
-#line 2492 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5036, 4},
-#line 4050 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5037, 0},
-#line 2578 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5038, 0},
-#line 595 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5039, 0},
-#line 6281 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5040, 0},
-#line 2698 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5041, 0},
-#line 4262 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5042, 0},
-#line 4993 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5043, 0},
-#line 2484 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5044, 4},
-#line 5806 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5045, 0},
-#line 4184 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5046, 0},
-#line 6182 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5047, 0},
-#line 6226 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5048, 0},
-#line 2074 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5049, 0},
-#line 805 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5050, 0},
-#line 2527 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5051, 4},
-#line 6396 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5052, 0},
-#line 4591 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5053, 0},
-#line 300 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5054, 0},
-#line 2302 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5055, 0},
-#line 4631 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5056, 0},
-#line 2694 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5057, 0},
-#line 3592 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5058, 0},
-#line 5818 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5059, 0},
-#line 5973 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5060, 0},
-#line 121 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5061, 0},
-#line 5102 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5062, 0},
-#line 5822 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5063, 0},
-#line 357 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5064, 0},
-#line 1610 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5065, 0},
-#line 5456 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5066, 0},
-#line 1086 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5067, 0},
-#line 3123 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5068, 0},
-#line 5069 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5069, 4},
-#line 3726 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5070, 0},
-#line 3667 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5071, 0},
-#line 106 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5072, 0},
-#line 4296 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5073, 0},
-#line 2228 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5074, 0},
-#line 1707 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5075, 0},
-#line 3433 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5076, 0},
-#line 5014 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5077, 0},
-#line 5932 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5078, 0},
-#line 6163 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5079, 0},
-#line 4916 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5080, 0},
-#line 5661 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5081, 0},
-#line 275 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5082, 0},
-#line 6487 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5083, 0},
-#line 5019 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5084, 0},
-#line 5825 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5085, 0},
-#line 3461 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5086, 0},
-#line 1630 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5087, 4},
-#line 2018 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5088, 0},
-#line 1551 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5089, 0},
-#line 3793 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5090, 0},
-#line 5490 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5091, 0},
-#line 5263 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5092, 0},
-#line 6376 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5093, 0},
-#line 3432 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5094, 0},
-#line 2909 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5095, 0},
-#line 3649 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5096, 0},
-#line 5975 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5097, 0},
-#line 5950 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5098, 0},
-#line 4288 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5099, 4},
-#line 4470 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5100, 0},
-#line 254 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5101, 0},
-#line 5587 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5102, 0},
-#line 3680 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5103, 0},
-#line 3395 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5104, 0},
-#line 3666 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5105, 0},
-#line 4812 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5106, 0},
-#line 789 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5107, 0},
-#line 2206 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5108, 0},
-#line 2724 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5109, 0},
-#line 5902 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5110, 0},
-#line 5395 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5111, 0},
-#line 4615 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5112, 0},
-#line 2351 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5113, 0},
-#line 1223 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5114, 0},
-#line 6190 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5115, 0},
-#line 4266 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5116, 0},
-#line 2725 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5117, 0},
-#line 5869 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5118, 0},
-#line 532 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5119, 4},
-#line 2744 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5120, 0},
-#line 2314 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5121, 0},
-#line 4214 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5122, 0},
-#line 4797 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5123, 0},
-#line 3684 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5124, 0},
-#line 3844 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5125, 0},
-#line 3576 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5126, 0},
-#line 4811 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5127, 0},
-#line 3547 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5128, 0},
-#line 5206 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5129, 0},
-#line 3494 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5130, 0},
-#line 1635 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5131, 4},
-#line 5128 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5132, 0},
-#line 6523 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5133, 0},
-#line 3226 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5134, 0},
-#line 2386 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5135, 0},
-#line 3504 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5136, 0},
-#line 4830 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5137, 0},
-#line 3590 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5138, 0},
-#line 1787 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5139, 0},
-#line 3566 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5140, 0},
-#line 6489 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5141, 0},
-#line 2858 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5142, 0},
-#line 3074 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5143, 0},
-#line 2597 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5144, 0},
-#line 3728 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5145, 0},
-#line 6195 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5146, 0},
-#line 2726 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5147, 0},
-#line 5618 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5148, 0},
-#line 1622 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5149, 4},
-#line 5312 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5150, 0},
-#line 5361 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5151, 0},
-#line 3833 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5152, 0},
-#line 5968 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5153, 0},
-#line 4744 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5154, 0},
-#line 2783 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5155, 0},
-#line 531 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5156, 4},
-#line 5007 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5157, 0},
-#line 3209 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5158, 0},
-#line 1137 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5159, 0},
-#line 4738 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5160, 0},
-#line 5326 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5161, 0},
-#line 4639 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5162, 0},
-#line 1505 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5163, 0},
-#line 6502 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5164, 0},
-#line 4537 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5165, 0},
-#line 5737 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5166, 0},
-#line 5420 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5167, 0},
-#line 3718 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5168, 0},
-#line 5836 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5169, 0},
-#line 3527 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5170, 0},
-#line 5240 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5171, 0},
-#line 1249 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5172, 0},
-#line 5126 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5173, 0},
-#line 4503 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5174, 0},
-#line 6415 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5175, 0},
-#line 79 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5176, 0},
-#line 3583 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5177, 0},
-#line 6244 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5178, 0},
-#line 2580 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5179, 0},
-#line 5760 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5180, 0},
-#line 212 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5181, 0},
-#line 1738 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5182, 0},
-#line 5176 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5183, 0},
-#line 418 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5184, 0},
-#line 5199 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5185, 0},
-#line 3655 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5186, 0},
-#line 1582 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5187, 0},
-#line 3559 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5188, 0},
-#line 1639 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5189, 4},
-#line 2571 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5190, 4},
-#line 4961 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5191, 0},
-#line 2017 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5192, 0},
-#line 5342 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5193, 0},
-#line 1653 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5194, 4},
-#line 3717 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5195, 0},
-#line 296 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5196, 0},
-#line 6185 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5197, 0},
-#line 5021 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5198, 0},
-#line 6381 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5199, 0},
-#line 4515 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5200, 0},
-#line 854 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5201, 4},
-#line 3478 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5202, 0},
-#line 5080 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5203, 0},
-#line 2765 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5204, 0},
-#line 5264 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5205, 0},
-#line 3048 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5206, 0},
-#line 1494 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5207, 0},
-#line 5960 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5208, 0},
-#line 1614 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5209, 4},
-#line 2602 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5210, 0},
-#line 5093 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5211, 0},
-#line 17 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5212, 0},
-#line 1170 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5213, 0},
-#line 2793 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5214, 0},
-#line 2457 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5215, 0},
-#line 2212 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5216, 0},
-#line 6391 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5217, 0},
-#line 213 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5218, 0},
-#line 2594 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5219, 0},
-#line 4540 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5220, 0},
-#line 6089 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5221, 0},
-#line 5855 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5222, 4},
-#line 5856 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5223, 4},
-#line 6368 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5224, 0},
-#line 576 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5225, 0},
-#line 1203 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5226, 0},
-#line 3514 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5227, 0},
-#line 232 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5228, 0},
-#line 5516 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5229, 0},
-#line 4179 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5230, 0},
-#line 6288 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5231, 0},
-#line 1676 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5232, 0},
-#line 5611 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5233, 0},
-#line 1633 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5234, 4},
-#line 5368 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5235, 0},
-#line 2184 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5236, 0},
-#line 1450 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5237, 0},
-#line 1568 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5238, 4},
-#line 5285 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5239, 0},
-#line 6405 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5240, 0},
-#line 5951 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5241, 0},
-#line 3488 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5242, 0},
-#line 1634 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5243, 4},
-#line 2357 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5244, 0},
-#line 3836 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5245, 0},
-#line 4643 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5246, 0},
-#line 1704 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5247, 0},
-#line 4509 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5248, 0},
-#line 5465 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5249, 0},
-#line 3243 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5250, 0},
-#line 3325 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5251, 0},
-#line 5607 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5252, 0},
-#line 6024 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5253, 0},
-#line 5820 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5254, 0},
-#line 3763 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5255, 0},
-#line 4084 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5256, 0},
-#line 2544 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5257, 4},
-#line 2721 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5258, 0},
-#line 3544 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5259, 0},
-#line 5153 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5260, 0},
-#line 6375 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5261, 0},
-#line 6256 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5262, 0},
-#line 3760 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5263, 0},
-#line 3564 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5264, 0},
-#line 2821 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5265, 0},
-#line 280 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5266, 0},
-#line 2295 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5267, 0},
-#line 848 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5268, 0},
-#line 6496 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5269, 0},
-#line 4708 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5270, 0},
-#line 5168 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5271, 0},
-#line 4499 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5272, 0},
-#line 2681 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5273, 0},
-#line 6498 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5274, 0},
-#line 5865 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5275, 0},
-#line 5048 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5276, 4},
-#line 5095 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5277, 0},
-#line 5445 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5278, 0},
-#line 4060 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5279, 0},
-#line 34 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5280, 0},
-#line 917 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5281, 0},
-#line 2798 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5282, 0},
-#line 5761 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5283, 0},
-#line 4523 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5284, 0},
-#line 5422 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5285, 0},
-#line 5982 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5286, 0},
-#line 5143 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5287, 0},
-#line 2723 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5288, 0},
-#line 4900 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5289, 0},
-#line 109 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5290, 0},
-#line 2864 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5291, 0},
-#line 1637 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5292, 4},
-#line 1533 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5293, 0},
-#line 3472 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5294, 0},
-#line 5044 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5295, 0},
-#line 5114 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5296, 0},
-#line 5484 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5297, 0},
-#line 5597 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5298, 0},
-#line 1668 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5299, 4},
-#line 6001 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5300, 0},
-#line 6080 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5301, 0},
-#line 5797 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5302, 0},
-#line 5604 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5303, 0},
-#line 1717 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5304, 0},
-#line 1686 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5305, 0},
-#line 5078 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5306, 0},
-#line 1855 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5307, 0},
-#line 5118 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5308, 0},
-#line 5971 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5309, 0},
-#line 921 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5310, 0},
-#line 4243 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5311, 0},
-#line 2467 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5312, 0},
-#line 3732 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5313, 0},
-#line 790 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5314, 0},
-#line 4600 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5315, 0},
-#line 5105 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5316, 0},
-#line 5542 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5317, 4},
-#line 4954 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5318, 0},
-#line 5879 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5319, 0},
-#line 5026 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5320, 4},
-#line 1479 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5321, 0},
-#line 3748 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5322, 4},
-#line 2172 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5323, 0},
-#line 1156 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5324, 0},
-#line 5277 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5325, 0},
-#line 4983 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5326, 0},
-#line 4498 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5327, 0},
-#line 6476 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5328, 0},
-#line 3146 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5329, 0},
-#line 4526 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5330, 0},
-#line 6491 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5331, 0},
-#line 2114 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5332, 0},
-#line 2502 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5333, 4},
-#line 5988 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5334, 0},
-#line 4682 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5335, 0},
-#line 4500 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5336, 0},
-#line 2133 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5337, 0},
-#line 2998 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5338, 0},
-#line 1804 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5339, 4},
-#line 5629 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5340, 0},
-#line 5266 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5341, 0},
-#line 1142 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5342, 0},
-#line 1624 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5343, 4},
-#line 3571 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5344, 0},
-#line 4760 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5345, 0},
-#line 1090 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5346, 0},
-#line 4766 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5347, 0},
-#line 4806 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5348, 0},
-#line 5016 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5349, 0},
-#line 3538 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5350, 0},
-#line 2945 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5351, 0},
-#line 3713 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5352, 0},
-#line 5428 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5353, 0},
-#line 2841 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5354, 0},
-#line 2607 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5355, 0},
-#line 713 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5356, 0},
-#line 4544 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5357, 0},
-#line 3468 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5358, 0},
-#line 712 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5359, 0},
-#line 3087 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5360, 0},
-#line 735 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5361, 0},
-#line 4939 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5362, 0},
-#line 716 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5363, 0},
-#line 717 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5364, 0},
-#line 699 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5365, 0},
-#line 2734 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5366, 0},
-#line 6260 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5367, 0},
-#line 3470 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5368, 0},
-#line 272 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5369, 0},
-#line 5200 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5370, 0},
-#line 5547 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5371, 0},
-#line 4769 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5372, 0},
-#line 693 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5373, 0},
-#line 3072 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5374, 0},
-#line 4805 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5375, 0},
-#line 2581 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5376, 0},
-#line 6279 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5377, 0},
-#line 3340 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5378, 0},
-#line 1692 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5379, 0},
-#line 3575 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5380, 0},
-#line 2833 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5381, 0},
-#line 2711 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5382, 0},
-#line 4904 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5383, 0},
-#line 3066 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5384, 0},
-#line 711 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5385, 0},
-#line 710 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5386, 0},
-#line 1261 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5387, 0},
-#line 2784 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5388, 0},
-#line 392 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5389, 0},
-#line 4772 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5390, 0},
-#line 2906 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5391, 0},
-#line 6287 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5392, 0},
-#line 5341 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5393, 0},
-#line 3733 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5394, 0},
-#line 718 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5395, 0},
-#line 738 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5396, 0},
-#line 2482 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5397, 4},
-#line 4270 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5398, 0},
-#line 5617 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5399, 0},
-#line 1799 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5400, 0},
-#line 696 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5401, 0},
-#line 3734 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5402, 0},
-#line 2679 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5403, 0},
-#line 6025 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5404, 0},
-#line 692 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5405, 0},
-#line 5780 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5406, 0},
-#line 3894 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5407, 0},
-#line 475 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5408, 0},
-#line 730 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5409, 0},
-#line 5664 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5410, 0},
-#line 6158 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5411, 0},
-#line 5015 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5412, 0},
-#line 3761 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5413, 0},
-#line 3002 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5414, 0},
-#line 655 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5415, 0},
-#line 2866 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5416, 0},
-#line 4667 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5417, 0},
-#line 5866 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5418, 0},
-#line 3000 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5419, 0},
-#line 5492 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5420, 0},
-#line 5159 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5421, 0},
-#line 739 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5422, 0},
-#line 1724 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5423, 0},
-#line 708 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5424, 0},
-#line 1636 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5425, 4},
-#line 1588 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5426, 0},
-#line 5218 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5427, 0},
-#line 694 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5428, 0},
-#line 4519 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5429, 0},
-#line 4231 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5430, 0},
-#line 695 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5431, 0},
-#line 741 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5432, 0},
-#line 5470 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5433, 0},
-#line 849 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5434, 0},
-#line 6187 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5435, 0},
-#line 284 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5436, 0},
-#line 3474 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5437, 0},
-#line 4645 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5438, 0},
-#line 574 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5439, 0},
-#line 2041 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5440, 0},
-#line 4736 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5441, 0},
-#line 2503 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5442, 4},
-#line 697 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5443, 0},
-#line 4826 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5444, 0},
-#line 6271 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5445, 0},
-#line 714 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5446, 0},
-#line 4578 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5447, 0},
-#line 2342 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5448, 0},
-#line 715 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5449, 0},
-#line 564 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5450, 4},
-#line 3878 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5451, 0},
-#line 4177 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5452, 0},
-#line 278 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5453, 0},
-#line 5162 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5454, 0},
-#line 622 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5455, 0},
-#line 3585 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5456, 0},
-#line 5107 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5457, 0},
-#line 5139 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5458, 0},
-#line 736 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5459, 0},
-#line 2477 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5460, 4},
-#line 1678 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5461, 0},
-#line 6321 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5462, 0},
-#line 3337 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5463, 0},
-#line 4857 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5464, 0},
-#line 2301 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5465, 0},
-#line 3462 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5466, 0},
-#line 2706 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5467, 0},
-#line 5060 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5468, 2},
-#line 6259 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5469, 0},
-#line 596 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5470, 0},
-#line 5362 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5471, 0},
-#line 1595 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5472, 0},
-#line 740 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5473, 0},
-#line 666 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5474, 0},
-#line 5605 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5475, 0},
-#line 2101 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5476, 0},
-#line 4646 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5477, 0},
-#line 690 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5478, 0},
-#line 1687 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5479, 0},
-#line 729 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5480, 0},
-#line 4268 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5481, 0},
-#line 5331 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5482, 0},
-#line 153 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5483, 0},
-#line 1711 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5484, 0},
-#line 4899 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5485, 0},
-#line 4505 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5486, 0},
-#line 4883 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5487, 4},
-#line 2077 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5488, 0},
-#line 5722 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5489, 0},
-#line 1688 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5490, 0},
-#line 4062 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5491, 0},
-#line 2533 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5492, 4},
-#line 691 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5493, 0},
-#line 4984 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5494, 0},
-#line 22 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5495, 0},
-#line 338 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5496, 0},
-#line 810 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5497, 0},
-#line 3828 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5498, 0},
-#line 2748 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5499, 0},
-#line 3557 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5500, 0},
-#line 1207 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5501, 0},
-#line 3359 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5502, 0},
-#line 4297 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5503, 0},
-#line 928 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5504, 0},
-#line 1684 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5505, 0},
-#line 5527 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5506, 0},
-#line 3803 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5507, 0},
-#line 2881 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5508, 0},
-#line 2766 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5509, 0},
-#line 2605 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5510, 0},
-#line 6215 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5511, 0},
-#line 6037 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5512, 0},
-#line 5155 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5513, 0},
-#line 5123 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5514, 0},
-#line 4657 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5515, 0},
-#line 5821 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5516, 0},
-#line 6134 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5517, 0},
-#line 728 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5518, 0},
-#line 3015 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5519, 0},
-#line 733 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5520, 0},
-#line 2708 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5521, 0},
-#line 6197 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5522, 0},
-#line 700 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5523, 0},
-#line 4054 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5524, 0},
-#line 2061 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5525, 0},
-#line 4758 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5526, 4},
-#line 3216 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5527, 0},
-#line 6485 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5528, 0},
-#line 6081 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5529, 0},
-#line 3688 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5530, 0},
-#line 2260 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5531, 4},
-#line 2071 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5532, 0},
-#line 5976 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5533, 0},
-#line 6418 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5534, 0},
-#line 6430 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5535, 0},
-#line 5226 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5536, 0},
-#line 3065 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5537, 0},
-#line 4936 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5538, 0},
-#line 210 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5539, 0},
-#line 5434 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5540, 0},
-#line 2687 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5541, 0},
-#line 5591 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5542, 0},
-#line 516 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5543, 4},
-#line 5384 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5544, 0},
-#line 806 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5545, 0},
-#line 5742 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5546, 0},
-#line 2104 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5547, 0},
-#line 362 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5548, 0},
-#line 4926 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5549, 0},
-#line 3854 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5550, 0},
-#line 1419 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5551, 0},
-#line 3137 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5552, 0},
-#line 137 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5553, 0},
-#line 5132 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5554, 0},
-#line 794 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5555, 0},
-#line 132 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5556, 0},
-#line 5940 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5557, 0},
-#line 6176 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5558, 0},
-#line 2478 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5559, 4},
-#line 138 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5560, 0},
-#line 2667 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5561, 0},
-#line 3730 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5562, 0},
-#line 3546 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5563, 0},
-#line 3121 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5564, 0},
-#line 5628 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5565, 0},
-#line 709 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5566, 0},
-#line 1847 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5567, 4},
-#line 125 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5568, 0},
-#line 6494 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5569, 0},
-#line 1229 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5570, 4},
-#line 6521 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5571, 0},
-#line 4635 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5572, 0},
-#line 6266 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5573, 0},
-#line 2185 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5574, 0},
-#line 6522 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5575, 0},
-#line 1179 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5576, 0},
-#line 5315 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5577, 0},
-#line 2639 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5578, 0},
-#line 5739 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5579, 0},
-#line 2196 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5580, 0},
-#line 5572 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5581, 0},
-#line 1695 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5582, 0},
-#line 3493 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5583, 0},
-#line 5814 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5584, 0},
-#line 5641 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5585, 0},
-#line 5119 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5586, 0},
-#line 2820 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5587, 0},
-#line 1174 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5588, 0},
-#line 1587 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5589, 0},
-#line 4220 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5590, 0},
-#line 4967 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5591, 0},
-#line 4885 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5592, 4},
-#line 4596 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5593, 0},
-#line 703 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5594, 0},
-#line 5402 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5595, 0},
-#line 4634 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5596, 0},
-#line 3599 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5597, 0},
-#line 1411 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5598, 0},
-#line 1560 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5599, 0},
-#line 5404 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5600, 0},
-#line 3140 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5601, 0},
-#line 3801 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5602, 0},
-#line 5130 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5603, 0},
-#line 5885 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5604, 0},
-#line 617 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5605, 0},
-#line 1503 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5606, 0},
-#line 5919 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5607, 0},
-#line 5427 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5608, 0},
-#line 5498 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5609, 0},
-#line 1214 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5610, 0},
-#line 3336 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5611, 0},
-#line 5779 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5612, 0},
-#line 3654 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5613, 0},
-#line 6079 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5614, 4},
-#line 2686 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5615, 0},
-#line 5417 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5616, 0},
-#line 3797 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5617, 0},
-#line 2247 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5618, 0},
-#line 3292 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5619, 0},
-#line 4985 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5620, 0},
-#line 3600 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5621, 0},
-#line 1677 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5622, 0},
-#line 4265 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5623, 0},
-#line 5455 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5624, 0},
-#line 2361 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5625, 0},
-#line 1679 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5626, 0},
-#line 295 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5627, 0},
-#line 4840 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5628, 0},
-#line 3616 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5629, 0},
-#line 1572 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5630, 4},
-#line 4232 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5631, 0},
-#line 5165 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5632, 0},
-#line 5745 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5633, 0},
-#line 5147 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5634, 0},
-#line 3650 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5635, 0},
-#line 4480 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5636, 0},
-#line 5421 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5637, 0},
-#line 3008 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5638, 0},
-#line 701 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5639, 0},
-#line 2777 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5640, 0},
-#line 6021 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5641, 0},
-#line 4924 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5642, 0},
-#line 3720 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5643, 0},
-#line 5407 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5644, 0},
-#line 5553 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5645, 0},
-#line 5045 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5646, 0},
-#line 3662 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5647, 0},
-#line 3876 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5648, 0},
-#line 6457 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5649, 0},
-#line 5096 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5650, 0},
-#line 3277 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5651, 0},
-#line 702 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5652, 0},
-#line 6475 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5653, 0},
-#line 5047 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5654, 4},
-#line 134 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5655, 0},
-#line 4539 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5656, 0},
-#line 351 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5657, 0},
-#line 1205 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5658, 0},
-#line 3010 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5659, 0},
-#line 5517 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5660, 0},
-#line 5883 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5661, 0},
-#line 4627 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5662, 4},
-#line 4867 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5663, 4},
-#line 4632 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5664, 0},
-#line 5230 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5665, 0},
-#line 4299 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5666, 0},
-#line 3589 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5667, 0},
-#line 4663 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5668, 0},
-#line 1240 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5669, 4},
-#line 5042 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5670, 0},
-#line 5588 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5671, 0},
-#line 5424 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5672, 0},
-#line 4571 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5673, 0},
-#line 5375 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5674, 0},
-#line 5877 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5675, 0},
-#line 3446 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5676, 4},
-#line 1579 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5677, 0},
-#line 5392 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5678, 0},
-#line 3664 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5679, 0},
-#line 3785 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5680, 0},
-#line 2775 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5681, 0},
-#line 4696 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5682, 0},
-#line 4889 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5683, 0},
-#line 3200 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5684, 0},
-#line 6061 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5685, 4},
-#line 2168 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5686, 0},
-#line 6474 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5687, 0},
-#line 1540 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5688, 0},
-#line 5431 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5689, 0},
-#line 5678 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5690, 0},
-#line 5122 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5691, 0},
-#line 5448 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5692, 0},
-#line 6503 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5693, 4},
-#line 3350 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5694, 0},
-#line 4808 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5695, 0},
-#line 4573 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5696, 0},
-#line 6504 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5697, 4},
-#line 297 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5698, 0},
-#line 2875 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5699, 0},
-#line 3391 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5700, 0},
-#line 4962 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5701, 2},
-#line 6062 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5702, 4},
-#line 3738 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5703, 0},
-#line 1998 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5704, 4},
-#line 5299 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5705, 0},
-#line 4625 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5706, 0},
-#line 4750 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5707, 0},
-#line 5762 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5708, 0},
-#line 472 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5709, 0},
-#line 4052 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5710, 0},
-#line 5481 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5711, 0},
-#line 5530 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5712, 0},
-#line 4550 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5713, 0},
-#line 3334 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5714, 0},
-#line 1098 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5715, 0},
-#line 5405 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5716, 0},
-#line 3574 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5717, 0},
-#line 1631 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5718, 4},
-#line 4655 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5719, 0},
-#line 3441 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5720, 0},
-#line 734 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5721, 0},
-#line 5373 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5722, 0},
-#line 4630 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5723, 0},
-#line 2274 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5724, 0},
-#line 698 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5725, 0},
-#line 2951 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5726, 0},
-#line 3443 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5727, 0},
-#line 3328 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5728, 0},
-#line 474 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5729, 0},
-#line 4211 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5730, 0},
-#line 5224 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5731, 0},
-#line 5356 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5732, 0},
-#line 3533 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5733, 0},
-#line 5615 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5734, 0},
-#line 6135 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5735, 0},
-#line 3588 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5736, 0},
-#line 3660 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5737, 0},
-#line 4545 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5738, 0},
-#line 4538 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5739, 0},
-#line 4855 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5740, 0},
-#line 5210 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5741, 0},
-#line 369 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5742, 0},
-#line 4597 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5743, 0},
-#line 3348 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5744, 0},
-#line 5323 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5745, 0},
-#line 5446 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5746, 0},
-#line 5815 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5747, 0},
-#line 5133 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5748, 0},
-#line 1657 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5749, 4},
-#line 1665 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5750, 0},
-#line 6399 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5751, 0},
-#line 1593 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5752, 0},
-#line 3376 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5753, 0},
-#line 5862 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5754, 0},
-#line 3375 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5755, 0},
-#line 1507 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5756, 0},
-#line 3469 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5757, 0},
-#line 5414 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5758, 0},
-#line 3475 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5759, 0},
-#line 5525 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5760, 0},
-#line 4964 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5761, 0},
-#line 5170 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5762, 0},
-#line 5520 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5763, 0},
-#line 6423 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5764, 0},
-#line 5243 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5765, 0},
-#line 211 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5766, 0},
-#line 2349 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5767, 0},
-#line 3568 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5768, 0},
-#line 2321 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5769, 0},
-#line 2930 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5770, 0},
-#line 5426 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5771, 0},
-#line 450 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5772, 0},
-#line 3791 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5773, 0},
-#line 5010 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5774, 0},
-#line 4549 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5775, 1},
-#line 5332 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5776, 0},
-#line 570 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5777, 0},
-#line 4572 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5778, 0},
-#line 5447 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5779, 0},
-#line 2322 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5780, 0},
-#line 5051 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5781, 4},
-#line 5061 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5782, 0},
-#line 5146 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5783, 0},
-#line 5164 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5784, 0},
-#line 3195 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5785, 0},
-#line 705 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5786, 0},
-#line 2208 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5787, 0},
-#line 4612 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5788, 0},
-#line 1693 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5789, 0},
-#line 4968 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5790, 0},
-#line 737 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5791, 0},
-#line 1680 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5792, 0},
-#line 5216 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5793, 0},
-#line 1632 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5794, 4},
-#line 3864 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5795, 0},
-#line 2990 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5796, 0},
-#line 5598 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5797, 0},
-#line 6332 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5798, 0},
-#line 704 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5799, 0},
-#line 5494 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5800, 0},
-#line 3731 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5801, 0},
-#line 6340 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5802, 0},
-#line 5439 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5803, 0},
-#line 6403 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5804, 0},
-#line 3368 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5805, 0},
-#line 4560 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5806, 0},
-#line 2173 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5807, 0},
-#line 5436 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5808, 0},
-#line 4661 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5809, 0},
-#line 5221 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5810, 0},
-#line 6433 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5811, 0},
-#line 2248 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5812, 0},
-#line 5524 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5813, 0},
-#line 5744 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5814, 0},
-#line 2567 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5815, 0},
-#line 6181 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5816, 0},
-#line 4575 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5817, 0},
-#line 722 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5818, 0},
-#line 721 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5819, 0},
-#line 266 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5820, 0},
-#line 724 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5821, 0},
-#line 5529 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5822, 0},
-#line 1708 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5823, 0},
-#line 5413 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5824, 0},
-#line 6402 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5825, 0},
-#line 2999 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5826, 0},
-#line 707 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5827, 0},
-#line 227 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5828, 4},
-#line 5423 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5829, 0},
-#line 5252 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5830, 0},
-#line 4834 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5831, 0},
-#line 99 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5832, 0},
-#line 3604 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5833, 0},
-#line 5749 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5834, 0},
-#line 1241 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5835, 4},
-#line 5511 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5836, 0},
-#line 4551 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5837, 0},
-#line 2564 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5838, 0},
-#line 6534 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5839, 0},
-#line 4247 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5840, 0},
-#line 2849 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5841, 0},
-#line 5743 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5842, 0},
-#line 5474 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5843, 0},
-#line 1658 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5844, 4},
-#line 2539 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5845, 4},
-#line 706 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5846, 0},
-#line 725 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5847, 0},
-#line 5884 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5848, 0},
-#line 5001 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5849, 0},
-#line 4920 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5850, 0},
-#line 5592 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5851, 0},
-#line 5097 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5852, 0},
-#line 1792 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5853, 4},
-#line 3459 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5854, 0},
-#line 4223 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5855, 0},
-#line 3447 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5856, 0},
-#line 97 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5857, 0},
-#line 4212 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5858, 0},
-#line 5321 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5859, 0},
-#line 1690 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5860, 0},
-#line 2910 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5861, 0},
-#line 365 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5862, 0},
-#line 3455 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5863, 0},
-#line 4555 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5864, 0},
-#line 1694 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5865, 0},
-#line 4640 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5866, 0},
-#line 3605 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5867, 0},
-#line 4842 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5868, 0},
-#line 1140 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5869, 0},
-#line 6162 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5870, 0},
-#line 4664 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5871, 0},
-#line 5660 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5872, 0},
-#line 5371 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5873, 0},
-#line 512 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5874, 4},
-#line 3572 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5875, 0},
-#line 3673 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5876, 0},
-#line 3659 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5877, 0},
-#line 5184 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5878, 0},
-#line 6427 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5879, 0},
-#line 3762 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5880, 0},
-#line 5480 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5881, 0},
-#line 3542 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5882, 0},
-#line 4044 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5883, 0},
-#line 1543 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5884, 0},
-#line 114 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5885, 0},
-#line 4475 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5886, 0},
-#line 3344 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5887, 0},
-#line 5273 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5888, 0},
-#line 4225 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5889, 0},
-#line 5363 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5890, 0},
-#line 4813 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5891, 0},
-#line 3324 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5892, 0},
-#line 723 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5893, 0},
-#line 1570 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5894, 0},
-#line 3428 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5895, 0},
-#line 5735 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5896, 0},
-#line 4259 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5897, 0},
-#line 4688 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5898, 0},
-#line 727 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5899, 0},
-#line 679 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5900, 0},
-#line 5684 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5901, 0},
-#line 594 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5902, 0},
-#line 5144 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5903, 0},
-#line 3479 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5904, 0},
-#line 4814 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5905, 0},
-#line 5805 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5906, 0},
-#line 1501 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5907, 0},
-#line 6439 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5908, 0},
-#line 5152 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5909, 0},
-#line 3672 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5910, 0},
-#line 4541 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5911, 0},
-#line 5013 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5912, 0},
-#line 6178 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5913, 0},
-#line 1577 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5914, 0},
-#line 3280 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5915, 0},
-#line 1245 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5916, 4},
-#line 5656 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5917, 0},
-#line 1500 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5918, 0},
-#line 3458 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5919, 0},
-#line 2220 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5920, 0},
-#line 2000 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5921, 0},
-#line 411 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5922, 4},
-#line 4956 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5923, 0},
-#line 5281 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5924, 0},
-#line 1430 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5925, 0},
-#line 5691 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5926, 0},
-#line 4979 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5927, 0},
-#line 5487 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5928, 0},
-#line 5347 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5929, 4},
-#line 3473 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5930, 0},
-#line 5808 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5931, 0},
-#line 4709 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5932, 0},
-#line 5593 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5933, 0},
-#line 3796 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5934, 0},
-#line 1993 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5935, 0},
-#line 387 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5936, 0},
-#line 5275 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5937, 0},
-#line 5039 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5938, 0},
-#line 3399 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5939, 0},
-#line 5679 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5940, 0},
-#line 5544 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5941, 0},
-#line 4077 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5942, 0},
-#line 5241 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5943, 0},
-#line 5382 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5944, 0},
-#line 1537 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5945, 0},
-#line 5344 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5946, 0},
-#line 2964 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5947, 0},
-#line 2938 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5948, 0},
-#line 1427 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5949, 0},
-#line 3062 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5950, 0},
-#line 4930 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5951, 0},
-#line 2709 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5952, 0},
-#line 1566 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5953, 4},
-#line 4946 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5954, 0},
-#line 5319 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5955, 0},
-#line 2370 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5956, 0},
-#line 5222 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5957, 0},
-#line 1574 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5958, 0},
-#line 5378 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5959, 0},
-#line 5131 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5960, 0},
-#line 3550 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5961, 0},
-#line 5033 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5962, 0},
-#line 1064 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5963, 0},
-#line 726 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5964, 0},
-#line 1710 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5965, 0},
-#line 3618 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5966, 0},
-#line 1675 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5967, 4},
-#line 5228 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5968, 0},
-#line 3398 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5969, 0},
-#line 2176 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5970, 0},
-#line 1454 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5971, 4},
-#line 804 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5972, 0},
-#line 441 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5973, 0},
-#line 5493 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5974, 0},
-#line 2197 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5975, 0},
-#line 5098 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5976, 0},
-#line 5328 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5977, 0},
-#line 5009 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5978, 0},
-#line 5157 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5979, 0},
-#line 3471 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5980, 0},
-#line 1499 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5981, 0},
-#line 5212 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5982, 0},
-#line 5466 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5983, 0},
-#line 1981 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5984, 0},
-#line 5673 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5985, 0},
-#line 4999 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5986, 0},
-#line 5647 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5987, 0},
-#line 6470 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5988, 0},
-#line 4222 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5989, 0},
-#line 3361 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5990, 0},
-#line 6222 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5991, 0},
-#line 5070 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5992, 4},
-#line 2391 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5993, 0},
+#line 3261 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4277, 0},
 #line 5320 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5994, 0},
-#line 2277 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5995, 0},
-#line 4246 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5996, 0},
-#line 5254 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5997, 0},
-#line 5052 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5998, 0},
-#line 3476 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5999, 0},
-#line 5077 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6000, 0},
-#line 5183 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6001, 0},
-#line 3687 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6002, 0},
-#line 4557 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6003, 0},
-#line 3675 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6004, 0},
-#line 4861 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6005, 0},
-#line 5046 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6006, 0},
-#line 4925 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6007, 0},
-#line 3710 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6008, 0},
-#line 3367 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6009, 0},
-#line 4919 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6010, 0},
-#line 5967 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6011, 0},
-#line 6133 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6012, 0},
-#line 144 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6013, 0},
-#line 1689 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6014, 0},
-#line 5599 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6015, 0},
-#line 1515 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6016, 0},
-#line 6300 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6017, 0},
-#line 2710 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6018, 0},
-#line 5270 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6019, 0},
-#line 2270 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6020, 0},
-#line 5843 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6021, 0},
-#line 4700 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6022, 0},
-#line 2693 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6023, 0},
-#line 4917 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6024, 0},
-#line 5733 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6025, 0},
-#line 720 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6026, 0},
-#line 1498 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6027, 0},
-#line 1522 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6028, 0},
-#line 1648 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6029, 4},
-#line 3345 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6030, 0},
-#line 5311 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6031, 0},
-#line 5477 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6032, 0},
-#line 1578 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6033, 0},
-#line 5364 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6034, 0},
-#line 3430 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6035, 0},
-#line 1698 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6036, 0},
-#line 1647 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6037, 4},
-#line 3426 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6038, 0},
-#line 4870 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6039, 4},
-#line 1569 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6040, 0},
-#line 103 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6041, 0},
-#line 5794 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6042, 0},
-#line 1646 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6043, 4},
-#line 4928 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6044, 0},
-#line 5161 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6045, 0},
-#line 3535 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6046, 0},
-#line 3716 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6047, 0},
-#line 2727 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6048, 0},
-#line 3335 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6049, 0},
-#line 5292 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6050, 0},
-#line 4690 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6051, 0},
-#line 3608 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6052, 0},
-#line 5134 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6053, 0},
-#line 4918 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6054, 0},
-#line 5880 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6055, 0},
-#line 5317 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6056, 0},
-#line 6313 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6057, 0},
-#line 5459 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6058, 0},
-#line 5485 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6059, 0},
-#line 4226 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6060, 0},
-#line 4051 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6061, 0},
-#line 2384 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6062, 0},
-#line 1514 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6063, 0},
-#line 3387 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6064, 0},
-#line 3427 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6065, 0},
-#line 3750 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6066, 0},
-#line 5258 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6067, 0},
-#line 5309 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6068, 0},
-#line 6275 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6069, 0},
-#line 3175 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6070, 4},
-#line 1144 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6071, 0},
-#line 5308 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6072, 0},
-#line 5217 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6073, 0},
-#line 5720 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6074, 0},
-#line 2278 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6075, 0},
-#line 6323 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6076, 0},
-#line 4556 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6077, 0},
-#line 1260 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6078, 0},
-#line 2471 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6079, 0},
-#line 4960 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6080, 0},
-#line 5037 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6081, 0},
-#line 5630 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6082, 0},
-#line 5324 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6083, 0},
-#line 3124 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6084, 0},
-#line 3671 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6085, 0},
-#line 5539 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6086, 0},
-#line 5076 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6087, 0},
-#line 4949 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6088, 0},
-#line 1092 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6089, 0},
-#line 4953 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6090, 0},
-#line 5351 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6091, 0},
-#line 6410 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6092, 0},
-#line 3775 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6093, 0},
-#line 6088 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6094, 0},
-#line 2066 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6095, 0},
-#line 4576 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6096, 0},
-#line 4712 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6097, 0},
-#line 5040 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6098, 0},
-#line 4903 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6099, 0},
-#line 6175 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6100, 0},
-#line 4902 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6101, 0},
-#line 4865 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6102, 4},
-#line 5124 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6103, 0},
-#line 5106 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6104, 0},
-#line 671 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6105, 0},
-#line 4907 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6106, 0},
-#line 2776 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6107, 0},
-#line 918 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6108, 0},
-#line 5713 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6109, 0},
-#line 281 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6110, 0},
-#line 5297 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6111, 0},
-#line 4476 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6112, 0},
-#line 4931 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6113, 0},
-#line 4548 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6114, 0},
-#line 5160 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6115, 0},
-#line 2023 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6116, 0},
-#line 4938 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6117, 0},
-#line 1564 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6118, 4},
-#line 3534 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6119, 0},
-#line 3656 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6120, 0},
-#line 5154 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6121, 0},
-#line 2019 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6122, 0},
-#line 2844 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6123, 0},
-#line 1696 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6124, 0},
-#line 6367 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6125, 0},
-#line 1594 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6126, 0},
-#line 5173 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6127, 0},
-#line 5400 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6128, 0},
-#line 3353 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6129, 0},
-#line 4871 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6130, 4},
-#line 6227 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6131, 0},
-#line 2029 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6132, 0},
-#line 5374 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6133, 0},
-#line 1638 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6134, 4},
-#line 1652 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6135, 4},
-#line 5357 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6136, 0},
-#line 2574 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6137, 0},
-#line 3349 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6138, 0},
-#line 2207 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6139, 0},
-#line 1143 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6140, 0},
-#line 4977 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6141, 0},
-#line 4216 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6142, 0},
-#line 4915 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6143, 0},
-#line 6436 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6144, 0},
-#line 5327 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6145, 0},
-#line 6294 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6146, 0},
-#line 5393 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6147, 0},
-#line 5083 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6148, 0},
-#line 1618 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6149, 4},
-#line 5223 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6150, 0},
-#line 4622 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6151, 0},
-#line 250 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6152, 0},
-#line 4911 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6153, 0},
-#line 5059 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6154, 0},
-#line 1721 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6155, 0},
-#line 3125 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6156, 0},
-#line 2970 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6157, 4},
-#line 1701 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6158, 0},
-#line 3562 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6159, 0},
-#line 3619 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6160, 0},
-#line 4942 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6161, 0},
-#line 3467 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6162, 0},
-#line 5025 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6163, 4},
-#line 5090 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6164, 0},
-#line 1723 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6165, 0},
-#line 4532 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6166, 0},
-#line 795 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6167, 0},
-#line 5180 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6168, 0},
-#line 1720 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6169, 0},
-#line 4951 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6170, 0},
-#line 742 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6171, 0},
-#line 1664 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6172, 0},
-#line 2437 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6173, 0},
-#line 2462 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6174, 0},
-#line 3573 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6175, 0},
-#line 4492 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6176, 0},
-#line 3536 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6177, 0},
-#line 1681 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6178, 0},
-#line 5535 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6179, 0},
-#line 3712 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6180, 0},
-#line 5101 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6181, 0},
-#line 5089 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6182, 0},
-#line 3594 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6183, 0},
-#line 5203 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6184, 4},
-#line 1671 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6185, 0},
-#line 1669 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6186, 0},
-#line 2700 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6187, 0},
-#line 3621 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6188, 0},
-#line 5645 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6189, 0},
-#line 5340 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6190, 0},
-#line 4893 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6191, 0},
-#line 5267 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6192, 0},
-#line 4901 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6193, 0},
-#line 5338 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6194, 0},
-#line 743 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6195, 0},
-#line 2365 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6196, 0},
-#line 1683 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6197, 0},
-#line 6426 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6198, 0},
-#line 1666 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6199, 0},
-#line 5256 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6200, 0},
-#line 1585 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6201, 0},
-#line 5253 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6202, 0},
-#line 3435 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6203, 0},
-#line 5121 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6204, 0},
-#line 1995 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6205, 0},
-#line 4217 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6206, 0},
-#line 5284 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6207, 0},
-#line 5062 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6208, 0},
-#line 6035 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6209, 0},
-#line 2213 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6210, 0},
-#line 395 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6211, 0},
-#line 5236 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6212, 0},
-#line 3402 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6213, 0},
-#line 3563 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6214, 0},
-#line 2666 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6215, 0},
-#line 5100 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6216, 0},
-#line 107 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6217, 0},
-#line 6067 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6218, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4278, 0},
+#line 3385 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4279, 0},
+#line 3185 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4280, 0},
+#line 5114 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4281, 0},
+#line 3073 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4282, 0},
+#line 3917 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4283, 0},
+#line 431 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4284, 0},
+#line 900 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4285, 0},
+#line 2350 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4286, 0},
+#line 3910 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4287, 0},
+#line 898 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4288, 0},
+#line 921 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4289, 0},
+#line 2992 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4290, 4},
 #line 5829 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6219, 0},
-#line 5008 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6220, 0},
-#line 5334 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6221, 0},
-#line 3581 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6222, 0},
-#line 6400 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6223, 0},
-#line 3260 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6224, 0},
-#line 745 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6225, 0},
-#line 5522 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6226, 0},
-#line 2916 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6227, 0},
-#line 6425 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6228, 0},
-#line 1420 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6229, 4},
-#line 5198 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6230, 0},
-#line 1861 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6231, 0},
-#line 5346 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6232, 4},
-#line 5215 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6233, 0},
-#line 6267 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6234, 0},
-#line 279 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6235, 0},
-#line 5220 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6236, 0},
-#line 2615 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6237, 0},
-#line 5394 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6238, 0},
-#line 6277 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6239, 0},
-#line 3343 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6240, 0},
-#line 3561 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6241, 0},
-#line 3670 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6242, 0},
-#line 2003 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6243, 0},
-#line 1805 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6244, 4},
-#line 1553 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6245, 0},
-#line 4969 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6246, 0},
-#line 74 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6247, 0},
-#line 5419 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6248, 0},
-#line 1542 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6249, 0},
-#line 3617 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6250, 0},
-#line 4671 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6251, 0},
-#line 3578 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6252, 0},
-#line 2143 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6253, 4},
-#line 6268 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6254, 0},
-#line 1549 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6255, 0},
-#line 3580 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6256, 0},
-#line 5163 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6257, 0},
-#line 35 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6258, 0},
-#line 1670 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6259, 0},
-#line 1391 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6260, 0},
-#line 6171 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6261, 0},
-#line 2685 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6262, 0},
-#line 1592 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6263, 0},
-#line 4882 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6264, 4},
-#line 5846 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6265, 0},
-#line 5389 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6266, 0},
-#line 1697 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6267, 0},
-#line 4913 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6268, 0},
-#line 744 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6269, 0},
-#line 3691 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6270, 0},
-#line 5631 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6271, 0},
-#line 5020 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6272, 0},
-#line 4215 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6273, 0},
-#line 4742 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6274, 0},
-#line 4841 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6275, 0},
-#line 3737 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6276, 0},
-#line 4941 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6277, 0},
-#line 797 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6278, 0},
-#line 1603 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6279, 0},
-#line 652 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6280, 0},
-#line 2638 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6281, 0},
-#line 2495 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6282, 4},
-#line 6289 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6283, 0},
-#line 3771 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6284, 0},
-#line 4866 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6285, 4},
-#line 1672 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6286, 0},
-#line 4873 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6287, 4},
-#line 5036 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6288, 0},
-#line 5339 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6289, 0},
-#line 5181 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6290, 0},
-#line 5011 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6291, 0},
-#line 5845 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6292, 0},
-#line 4898 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6293, 0},
-#line 1436 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6294, 0},
-#line 6076 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6295, 0},
-#line 5108 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6296, 0},
-#line 4207 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6297, 0},
-#line 5017 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6298, 0},
-#line 3167 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6299, 4},
-#line 5018 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6300, 0},
-#line 5246 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6301, 0},
-#line 3802 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6302, 0},
-#line 5627 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6303, 0},
-#line 4914 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6304, 0},
-#line 3665 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6305, 0},
-#line 6258 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6306, 0},
-#line 5296 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6307, 0},
-#line 5301 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6308, 0},
-#line 1097 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6309, 0},
-#line 4831 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6310, 0},
-#line 4876 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6311, 4},
-#line 2004 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6312, 0},
-#line 5578 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6313, 0},
-#line 6461 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6314, 0},
-#line 1609 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6315, 0},
-#line 2680 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6316, 0},
-#line 2088 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6317, 0},
-#line 2144 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6318, 0},
-#line 5377 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6319, 0},
-#line 3598 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6320, 0},
-#line 5909 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6321, 0},
-#line 5225 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6322, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4291, 0},
+#line 2896 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4292, 0},
+#line 874 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4293, 0},
+#line 876 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4294, 0},
+#line 2707 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4295, 0},
 #line 5355 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6323, 0},
-#line 5336 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6324, 0},
-#line 5523 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6325, 0},
-#line 1489 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6326, 0},
-#line 4952 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6327, 0},
-#line 3591 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6328, 0},
-#line 4978 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6329, 0},
-#line 3603 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6330, 0},
-#line 1524 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6331, 0},
-#line 582 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6332, 0},
-#line 5372 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6333, 0},
-#line 5109 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6334, 0},
-#line 5233 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6335, 0},
-#line 5833 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6336, 0},
-#line 6478 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6337, 0},
-#line 5150 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6338, 0},
-#line 5612 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6339, 0},
-#line 731 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6340, 0},
-#line 5908 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6341, 0},
-#line 3370 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6342, 0},
-#line 5038 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6343, 0},
-#line 732 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6344, 0},
-#line 6398 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6345, 0},
-#line 4788 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6346, 0},
-#line 4614 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6347, 0},
-#line 3724 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6348, 0},
-#line 1518 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6349, 0},
-#line 3747 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6350, 0},
-#line 1685 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6351, 0},
-#line 5169 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6352, 0},
-#line 135 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6353, 0},
-#line 3366 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6354, 0},
-#line 1682 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6355, 0},
-#line 4982 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6356, 4},
-#line 1422 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6357, 4},
-#line 4890 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6358, 0},
-#line 226 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6359, 4},
-#line 5201 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6360, 0},
-#line 3709 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6361, 0},
-#line 4970 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6362, 0},
-#line 141 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6363, 0},
-#line 1713 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6364, 0},
-#line 6347 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6365, 0},
-#line 5049 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6366, 4},
-#line 1173 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6367, 0},
-#line 1163 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6368, 0},
-#line 5041 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6369, 0},
-#line 1714 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6370, 0},
-#line 5050 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6371, 4},
-#line 5432 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6372, 0},
-#line 6344 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6373, 0},
-#line 4771 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6374, 0},
-#line 5103 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6375, 0},
-#line 4566 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6376, 0},
-#line 5195 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6377, 0},
-#line 5182 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6378, 0},
-#line 5149 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6379, 0},
-#line 1703 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6380, 0},
-#line 5425 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6381, 0},
-#line 1586 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6382, 0},
-#line 6422 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6383, 0},
-#line 1421 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6384, 4},
-#line 5156 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6385, 0},
-#line 4909 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6386, 0},
-#line 3436 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6387, 0},
-#line 4048 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6388, 0},
-#line 1147 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6389, 0},
-#line 5219 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6390, 0},
-#line 4770 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6391, 0},
-#line 5024 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6392, 0},
-#line 5468 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6393, 0},
-#line 5337 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6394, 0},
-#line 5137 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6395, 0},
-#line 3579 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6396, 0},
-#line 3371 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6397, 0},
-#line 5379 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6398, 0},
-#line 412 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6399, 4},
-#line 4206 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6400, 4},
-#line 1602 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6401, 0},
-#line 1597 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6402, 0},
-#line 1239 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6403, 4},
-#line 6200 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6404, 0},
-#line 5174 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6405, 0},
-#line 5366 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6406, 0},
-#line 4613 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6407, 0},
-#line 3736 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6408, 0},
-#line 3351 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6409, 0},
-#line 4937 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6410, 0},
-#line 2320 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6411, 0},
-#line 5179 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6412, 0},
-#line 3582 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6413, 0},
-#line 1485 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6414, 0},
-#line 5886 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6415, 0},
-#line 5189 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6416, 0},
-#line 5800 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6417, 0},
-#line 4662 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6418, 0},
-#line 1401 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6419, 4},
-#line 1691 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6420, 0},
-#line 5433 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6421, 0},
-#line 1599 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6422, 0},
-#line 3595 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6423, 0},
-#line 5138 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6424, 0},
-#line 5358 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6425, 0},
-#line 5399 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6426, 0},
-#line 1571 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6427, 4},
-#line 4976 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6428, 0},
-#line 5365 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6429, 0},
-#line 3602 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6430, 0},
-#line 1605 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6431, 0},
-#line 3339 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6432, 0},
-#line 3390 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6433, 0},
-#line 5178 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6434, 0},
-#line 1598 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6435, 0},
-#line 225 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6436, 4},
-#line 4599 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6437, 0},
-#line 1604 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6438, 0},
-#line 4935 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6439, 0},
-#line 6172 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6440, 0},
-#line 5354 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6441, 0},
-#line 1596 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6442, 0},
-#line 5136 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6443, 0},
-#line 5359 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6444, 0},
-#line 5129 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6445, 0},
-#line 5175 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6446, 0},
-#line 4602 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6447, 0},
-#line 1546 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6448, 0},
-#line 3552 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6449, 0},
-#line 4665 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6450, 0},
-#line 5675 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6451, 4},
-#line 1607 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6452, 0},
-#line 6150 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6453, 0},
-#line 6151 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6454, 0},
-#line 5140 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6455, 0},
-#line 5854 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6456, 4},
-#line 5145 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6457, 0},
-#line 4552 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6458, 0},
-#line 4694 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6459, 0},
-#line 4923 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6460, 0},
-#line 4879 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6461, 4},
-#line 4878 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6462, 4},
-#line 1567 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6463, 4},
-#line 3425 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6464, 0},
-#line 3668 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6465, 0},
-#line 1437 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6466, 0},
-#line 4869 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6467, 4},
-#line 4972 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6468, 0},
-#line 1565 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6469, 4},
-#line 5391 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6470, 0},
-#line 4583 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6471, 0},
-#line 438 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6472, 0},
-#line 3715 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6473, 0},
-#line 4584 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6474, 0},
-#line 5141 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6475, 0},
-#line 4881 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6476, 4},
-#line 1573 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6477, 0},
-#line 5043 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6478, 0},
-#line 4872 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6479, 4},
-#line 2323 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6480, 0},
-#line 3360 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6481, 0},
-#line 4875 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6482, 4},
-#line 4868 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6483, 4},
-#line 2572 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6484, 4},
-#line 5148 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6485, 0},
-#line 5111 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6486, 0},
-#line 5318 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6487, 0},
-#line 4877 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6488, 4},
-#line 4874 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6489, 4},
-#line 5469 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6490, 0},
-#line 3735 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6491, 0},
-#line 5172 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6492, 0},
-#line 5186 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6493, 0},
-#line 4910 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6494, 0},
-#line 5057 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6495, 4},
-#line 1716 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6496, 0},
-#line 5187 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6497, 0},
-#line 1237 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6498, 4},
-#line 5135 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6499, 0},
-#line 4973 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6500, 0},
-#line 624 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6501, 4},
-#line 5185 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6502, 0},
-#line 4895 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6503, 0},
-#line 1550 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6504, 0},
-#line 5142 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6505, 0},
-#line 4535 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6506, 0},
-#line 1189 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6507, 0},
-#line 5792 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6508, 0},
-#line 4940 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6509, 0},
-#line 3437 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6510, 0},
-#line 4912 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6511, 0},
-#line 1191 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6512, 0},
-#line 2553 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6513, 4},
-#line 4880 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6514, 4},
-#line 6301 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6515, 0},
-#line 1771 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6516, 0},
-#line 5151 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6517, 0},
-#line 6152 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6518, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4296, 0},
+#line 1278 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4297, 0},
+#line 3341 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4298, 0},
+#line 1268 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4299, 0},
+#line 3606 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4300, 0},
+#line 5042 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4301, 0},
+#line 5256 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4302, 0},
+#line 3287 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4303, 0},
+#line 649 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4304, 0},
+#line 3072 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4305, 0},
+#line 1749 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4306, 0},
+#line 2327 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4307, 0},
+#line 899 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4308, 0},
+#line 919 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4309, 0},
+#line 1123 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4310, 0},
+#line 912 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4311, 0},
 #line 4944 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6519, 0},
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4312, 0},
+#line 877 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4313, 0},
+#line 2598 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4314, 0},
+#line 2192 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4315, 0},
+#line 2413 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4316, 0},
+#line 1737 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4317, 0},
+#line 5401 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4318, 0},
+#line 917 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4319, 0},
+#line 2335 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4320, 0},
+#line 2052 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4321, 0},
+#line 1515 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4322, 0},
+#line 901 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4323, 0},
+#line 280 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4324, 0},
+#line 6576 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4325, 0},
+#line 922 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4326, 0},
+#line 913 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4327, 0},
+#line 5376 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4328, 0},
+#line 2346 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4329, 0},
+#line 3293 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4330, 0},
+#line 2040 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4331, 0},
+#line 4216 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4332, 0},
+#line 4987 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4333, 0},
+#line 4114 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4334, 0},
+#line 3915 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4335, 0},
+#line 918 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4336, 0},
+#line 1841 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4337, 0},
+#line 1111 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4338, 0},
+#line 3060 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4339, 0},
+#line 5043 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4340, 0},
+#line 4121 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4341, 0},
+#line 4180 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4342, 0},
+#line 881 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4343, 4},
+#line 1560 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4344, 0},
+#line 5291 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4345, 0},
+#line 915 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4346, 0},
+#line 1840 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4347, 0},
+#line 906 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4348, 0},
+#line 5113 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4349, 0},
+#line 6577 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4350, 0},
+#line 885 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4351, 0},
+#line 1832 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4352, 0},
+#line 916 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4353, 0},
+#line 1681 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4354, 0},
+#line 1280 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4355, 0},
+#line 3797 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4356, 0},
+#line 4185 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4357, 0},
+#line 239 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4358, 0},
+#line 3913 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4359, 0},
+#line 896 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4360, 0},
+#line 1837 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4361, 0},
+#line 2989 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4362, 0},
+#line 6453 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4363, 0},
+#line 1458 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4364, 0},
+#line 4186 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4365, 0},
+#line 375 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4366, 0},
+#line 2895 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4367, 0},
+#line 5415 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4368, 0},
+#line 1167 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4369, 0},
+#line 3125 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4370, 0},
+#line 4504 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4371, 0},
+#line 3600 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4372, 0},
+#line 5075 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4373, 0},
+#line 905 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4374, 4},
+#line 4794 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4375, 0},
+#line 4192 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4376, 0},
+#line 4337 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4377, 0},
+#line 2402 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4378, 0},
+#line 3264 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4379, 0},
+#line 2683 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4380, 4},
+#line 2835 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4381, 0},
+#line 5321 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4382, 0},
+#line 882 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4383, 0},
+#line 1831 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4384, 0},
+#line 4325 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4385, 0},
+#line 1727 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4386, 0},
+#line 4538 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4387, 0},
+#line 1279 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4388, 0},
+#line 5345 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4389, 0},
+#line 903 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4390, 0},
+#line 1227 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4391, 0},
+#line 4247 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4392, 0},
+#line 4188 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4393, 0},
+#line 870 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4394, 0},
+#line 2401 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4395, 0},
+#line 2381 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4396, 0},
+#line 3635 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4397, 0},
+#line 884 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4398, 4},
+#line 4124 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4399, 4},
+#line 6553 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4400, 4},
+#line 4301 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4401, 0},
+#line 4200 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4402, 0},
+#line 614 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4403, 0},
+#line 2348 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4404, 0},
+#line 2030 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4405, 0},
+#line 1692 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4406, 4},
+#line 1773 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4407, 0},
+#line 648 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4408, 0},
+#line 1823 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4409, 4},
+#line 2063 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4410, 0},
+#line 878 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4411, 0},
+#line 3907 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4412, 0},
+#line 1730 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4413, 0},
+#line 3255 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4414, 0},
+#line 2685 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4415, 0},
+#line 3394 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4416, 0},
+#line 3766 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4417, 0},
+#line 4197 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4418, 0},
+#line 415 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4419, 4},
+#line 3622 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4420, 0},
+#line 1131 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4421, 0},
+#line 3128 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4422, 0},
+#line 5177 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4423, 0},
+#line 585 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4424, 4},
+#line 3058 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4425, 4},
+#line 2003 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4426, 4},
+#line 2366 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4427, 0},
+#line 30 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4428, 0},
+#line 4886 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4429, 0},
+#line 5206 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4430, 0},
+#line 883 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4431, 0},
+#line 1072 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4432, 0},
+#line 2064 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4433, 0},
+#line 3237 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4434, 0},
+#line 6552 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4435, 4},
+#line 3216 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4436, 0},
+#line 159 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4437, 0},
+#line 1479 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4438, 4},
+#line 1770 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4439, 4},
+#line 3577 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4440, 0},
+#line 2073 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4441, 0},
+#line 6335 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4442, 0},
+#line 32 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4443, 0},
+#line 4117 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4444, 0},
+#line 505 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4445, 0},
+#line 4498 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4446, 0},
+#line 910 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4447, 0},
+#line 5851 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4448, 0},
+#line 4120 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4449, 0},
+#line 879 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4450, 0},
+#line 6430 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4451, 0},
+#line 2398 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4452, 4},
+#line 3743 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4453, 0},
+#line 6551 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4454, 4},
+#line 4302 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4455, 0},
+#line 3399 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4456, 0},
+#line 2780 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4457, 0},
+#line 2291 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4458, 0},
+#line 6145 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4459, 0},
+#line 6570 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4460, 0},
+#line 237 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4461, 4},
+#line 1702 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4462, 0},
+#line 3609 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4463, 0},
+#line 5869 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4464, 0},
+#line 4332 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4465, 0},
+#line 4064 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4466, 0},
+#line 1769 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4467, 4},
+#line 2195 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4468, 0},
+#line 1199 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4469, 0},
+#line 2397 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4470, 0},
+#line 1166 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4471, 4},
+#line 4189 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4472, 0},
+#line 914 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4473, 0},
+#line 1839 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4474, 0},
+#line 904 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4475, 4},
+#line 4118 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4476, 0},
+#line 851 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4477, 0},
+#line 6544 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4478, 0},
+#line 868 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4479, 4},
+#line 2915 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4480, 0},
+#line 2887 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4481, 0},
+#line 1270 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4482, 0},
+#line 1228 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4483, 0},
+#line 6514 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4484, 0},
+#line 1687 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4485, 0},
+#line 5051 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4486, 0},
+#line 3262 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4487, 0},
+#line 141 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4488, 0},
+#line 174 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4489, 0},
+#line 1559 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4490, 0},
+#line 1108 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4491, 0},
+#line 583 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4492, 0},
+#line 1591 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4493, 0},
+#line 2900 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4494, 0},
+#line 1743 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4495, 0},
+#line 6267 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4496, 0},
+#line 6319 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4497, 0},
+#line 902 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4498, 0},
+#line 2169 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4499, 0},
+#line 2311 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4500, 0},
+#line 1530 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4501, 0},
+#line 5330 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4502, 0},
+#line 158 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4503, 0},
+#line 5961 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4504, 0},
+#line 5390 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4505, 0},
+#line 3250 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4506, 0},
+#line 2663 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4507, 0},
+#line 5385 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4508, 0},
+#line 6492 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4509, 0},
+#line 4495 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4510, 0},
+#line 2399 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4511, 0},
+#line 888 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4512, 0},
+#line 2874 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4513, 0},
+#line 5208 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4514, 0},
+#line 2077 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4515, 0},
+#line 2459 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4516, 0},
+#line 3698 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4517, 0},
+#line 4262 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4518, 0},
+#line 3226 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4519, 0},
+#line 2315 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4520, 4},
+#line 4494 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4521, 0},
+#line 2400 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4522, 0},
+#line 5140 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4523, 0},
+#line 2885 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4524, 0},
+#line 2148 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4525, 0},
+#line 1538 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4526, 0},
+#line 5548 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4527, 0},
+#line 5606 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4528, 0},
+#line 2022 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4529, 0},
+#line 5704 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4530, 0},
+#line 510 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4531, 1},
+#line 5701 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4532, 0},
+#line 5119 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4533, 0},
+#line 2628 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4534, 0},
+#line 2298 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4535, 0},
+#line 5013 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4536, 0},
+#line 2257 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4537, 0},
+#line 6554 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4538, 4},
+#line 3458 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4539, 0},
+#line 89 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4540, 4},
+#line 117 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4541, 0},
+#line 2076 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4542, 0},
+#line 1182 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4543, 0},
+#line 5185 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4544, 0},
+#line 633 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4545, 0},
+#line 5793 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4546, 0},
+#line 6246 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4547, 0},
+#line 2314 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4548, 4},
+#line 5706 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4549, 2},
+#line 3033 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4550, 0},
+#line 677 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4551, 0},
+#line 3175 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4552, 0},
+#line 2011 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4553, 0},
+#line 5710 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4554, 0},
+#line 3265 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4555, 0},
+#line 5824 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4556, 0},
+#line 5554 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4557, 0},
+#line 3245 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4558, 0},
+#line 880 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4559, 0},
+#line 5586 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4560, 0},
+#line 5358 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4561, 0},
+#line 3139 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4562, 0},
+#line 4202 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4563, 0},
+#line 2349 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4564, 0},
+#line 4520 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4565, 0},
+#line 894 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4566, 0},
+#line 5592 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4567, 0},
+#line 5377 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4568, 0},
+#line 3912 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4569, 0},
+#line 116 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4570, 0},
+#line 895 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4571, 0},
+#line 1836 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4572, 0},
+#line 5363 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4573, 0},
+#line 1281 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4574, 0},
+#line 5796 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4575, 0},
+#line 2168 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4576, 0},
+#line 6340 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4577, 0},
+#line 2147 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4578, 0},
+#line 5266 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4579, 0},
+#line 2669 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4580, 0},
+#line 1070 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4581, 4},
+#line 5585 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4582, 0},
+#line 2255 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4583, 0},
+#line 5518 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4584, 0},
+#line 6255 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4585, 0},
+#line 2005 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4586, 0},
+#line 1513 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4587, 0},
+#line 6370 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4588, 0},
+#line 6199 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4589, 0},
+#line 5103 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4590, 4},
+#line 4225 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4591, 0},
+#line 5661 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4592, 0},
+#line 3084 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4593, 0},
+#line 2259 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4594, 0},
+#line 5603 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4595, 0},
+#line 6427 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4596, 0},
+#line 82 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4597, 0},
+#line 5447 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4598, 0},
+#line 5144 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4599, 0},
+#line 1069 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4600, 4},
+#line 1724 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4601, 0},
+#line 3224 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4602, 0},
+#line 6287 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4603, 0},
+#line 6062 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4604, 0},
+#line 911 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4605, 0},
+#line 2254 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4606, 0},
+#line 3502 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4607, 0},
+#line 5591 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4608, 0},
+#line 5797 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4609, 0},
+#line 312 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4610, 0},
+#line 5382 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4611, 4},
+#line 587 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4612, 0},
+#line 5804 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4613, 0},
+#line 6367 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4614, 0},
+#line 5238 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4615, 0},
+#line 5223 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4616, 0},
+#line 5602 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4617, 0},
+#line 3496 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4618, 0},
+#line 5728 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4619, 0},
+#line 5444 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4620, 0},
+#line 5981 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4621, 0},
+#line 5581 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4622, 0},
+#line 6059 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4623, 0},
+#line 6152 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4624, 0},
+#line 6349 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4625, 0},
+#line 6111 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4626, 0},
+#line 3298 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4627, 0},
+#line 2890 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4628, 0},
+#line 5564 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4629, 0},
+#line 1504 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4630, 0},
+#line 5348 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4631, 0},
+#line 5058 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4632, 0},
+#line 2892 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4633, 0},
+#line 5870 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4634, 0},
+#line 887 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4635, 0},
+#line 1755 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4636, 0},
+#line 2804 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4637, 0},
+#line 6285 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4638, 0},
+#line 6376 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4639, 0},
+#line 2253 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4640, 0},
+#line 5590 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4641, 0},
+#line 6155 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4642, 0},
+#line 5576 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4643, 0},
+#line 6377 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4644, 0},
+#line 5108 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4645, 0},
+#line 6136 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4646, 0},
+#line 6307 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4647, 0},
+#line 889 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4648, 0},
+#line 1834 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4649, 0},
+#line 2143 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4650, 0},
+#line 5562 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4651, 0},
+#line 2406 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4652, 0},
+#line 5584 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4653, 0},
+#line 5178 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4654, 0},
+#line 4304 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4655, 0},
+#line 5445 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4656, 0},
+#line 6139 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4657, 0},
+#line 2948 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4658, 0},
+#line 6317 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4659, 0},
+#line 6168 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4660, 0},
+#line 755 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4661, 0},
+#line 1778 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4662, 0},
+#line 1120 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4663, 0},
+#line 611 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4664, 0},
+#line 2571 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4665, 0},
+#line 5709 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4666, 0},
+#line 893 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4667, 0},
+#line 564 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4668, 0},
+#line 1835 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4669, 0},
+#line 4125 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4670, 0},
+#line 2347 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4671, 0},
+#line 892 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4672, 0},
+#line 5527 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4673, 0},
+#line 3170 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4674, 0},
+#line 6382 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4675, 0},
+#line 4830 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4676, 0},
+#line 4789 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4677, 0},
+#line 5814 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4678, 0},
+#line 5046 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4679, 0},
+#line 405 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4680, 0},
+#line 647 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4681, 0},
+#line 384 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4682, 0},
+#line 3782 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4683, 0},
+#line 6498 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4684, 0},
+#line 1122 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4685, 0},
+#line 613 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4686, 0},
+#line 5669 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4687, 0},
+#line 4228 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4688, 0},
+#line 890 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4689, 0},
+#line 5570 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4690, 0},
+#line 1110 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4691, 0},
+#line 586 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4692, 0},
+#line 3059 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4693, 0},
+#line 2004 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4694, 0},
+#line 3816 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4695, 0},
+#line 3916 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4696, 0},
+#line 1533 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4697, 0},
+#line 920 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4698, 0},
+#line 1842 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4699, 0},
+#line 5109 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4700, 0},
+#line 875 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4701, 0},
+#line 4193 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4702, 0},
+#line 1138 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4703, 0},
+#line 641 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4704, 0},
+#line 5084 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4705, 4},
+#line 217 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4706, 0},
+#line 5579 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4707, 0},
+#line 230 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4708, 0},
+#line 6497 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4709, 0},
+#line 6398 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4710, 0},
+#line 146 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4711, 0},
+#line 2385 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4712, 0},
+#line 79 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4713, 0},
+#line 4902 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4714, 4},
+#line 5712 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4715, 0},
+#line 399 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4716, 0},
+#line 3520 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4717, 0},
+#line 5419 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4718, 0},
+#line 336 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4719, 0},
+#line 4524 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4720, 0},
+#line 4508 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4721, 0},
+#line 1913 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4722, 0},
+#line 2600 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4723, 0},
+#line 4858 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4724, 4},
+#line 832 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4725, 0},
+#line 464 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4726, 0},
+#line 238 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4727, 0},
+#line 4220 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4728, 0},
+#line 891 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4729, 0},
+#line 5172 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4730, 0},
+#line 6007 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4731, 0},
+#line 6402 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4732, 0},
+#line 4881 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4733, 0},
+#line 694 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4734, 0},
+#line 6394 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4735, 0},
+#line 6329 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4736, 0},
+#line 5007 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4737, 0},
+#line 4546 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4738, 0},
+#line 5615 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4739, 0},
+#line 5056 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4740, 0},
+#line 4888 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4741, 0},
+#line 869 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4742, 0},
+#line 562 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4743, 0},
+#line 5672 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4744, 0},
+#line 566 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4745, 0},
+#line 6129 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4746, 0},
+#line 2067 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4747, 0},
+#line 4201 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4748, 0},
+#line 2913 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4749, 0},
+#line 1428 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4750, 0},
+#line 4883 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4751, 4},
+#line 5567 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4752, 0},
+#line 3366 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4753, 0},
+#line 2692 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4754, 0},
+#line 4958 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4755, 0},
+#line 5675 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4756, 0},
+#line 1480 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4757, 0},
+#line 6372 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4758, 0},
+#line 853 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4759, 0},
+#line 509 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4760, 0},
+#line 6333 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4761, 0},
+#line 4523 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4762, 0},
+#line 5169 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4763, 0},
+#line 5755 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4764, 0},
+#line 4503 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4765, 0},
+#line 1731 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4766, 0},
+#line 4521 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4767, 0},
+#line 3618 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4768, 0},
+#line 5668 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4769, 0},
+#line 5802 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4770, 0},
+#line 284 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4771, 0},
+#line 6425 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4772, 0},
+#line 5224 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4773, 0},
+#line 4385 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4774, 0},
+#line 195 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4775, 0},
+#line 3333 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4776, 0},
+#line 4382 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4777, 0},
+#line 6341 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4778, 0},
+#line 6312 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4779, 0},
+#line 6416 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4780, 0},
+#line 233 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4781, 0},
+#line 5687 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4782, 0},
+#line 6275 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4783, 0},
+#line 6399 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4784, 0},
+#line 6334 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4785, 0},
+#line 4850 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4786, 0},
+#line 886 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4787, 0},
+#line 157 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4788, 0},
+#line 4774 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4789, 0},
+#line 4214 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4790, 0},
+#line 1708 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4791, 0},
+#line 1624 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4792, 0},
+#line 2121 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4793, 0},
+#line 2299 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4794, 0},
+#line 359 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4795, 0},
+#line 2596 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4796, 0},
+#line 657 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4797, 0},
+#line 5616 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4798, 0},
+#line 6420 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4799, 0},
+#line 5525 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4800, 0},
+#line 4439 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4801, 0},
+#line 5158 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4802, 0},
+#line 4756 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4803, 0},
+#line 1879 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4804, 0},
+#line 5161 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4805, 0},
+#line 6362 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4806, 0},
+#line 5429 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4807, 0},
+#line 6393 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4808, 0},
+#line 5509 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4809, 0},
+#line 5679 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4810, 0},
+#line 6421 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4811, 0},
+#line 5676 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4812, 0},
+#line 6323 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4813, 0},
+#line 2637 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4814, 0},
+#line 767 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4815, 0},
+#line 6508 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4816, 0},
+#line 5417 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4817, 0},
+#line 5723 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4818, 0},
+#line 6405 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4819, 0},
+#line 5222 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4820, 0},
+#line 6396 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4821, 0},
+#line 5087 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4822, 4},
+#line 6406 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4823, 0},
+#line 5452 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4824, 0},
+#line 4316 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4825, 0},
+#line 817 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4826, 0},
+#line 4215 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4827, 0},
+#line 4525 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4828, 0},
+#line 6413 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4829, 0},
+#line 6142 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4830, 0},
+#line 3713 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4831, 0},
+#line 5086 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4832, 4},
+#line 4969 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4833, 0},
+#line 5179 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4834, 0},
+#line 6378 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4835, 0},
+#line 3391 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4836, 0},
+#line 5831 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4837, 0},
+#line 6353 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4838, 0},
+#line 5660 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4839, 0},
+#line 6247 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4840, 0},
+#line 6304 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4841, 0},
+#line 5915 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4842, 0},
+#line 5754 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4843, 0},
+#line 4554 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4844, 0},
+#line 5535 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4845, 0},
+#line 5778 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4846, 0},
+#line 338 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4847, 4},
+#line 4526 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4848, 0},
+#line 3277 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4849, 0},
+#line 4113 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4850, 0},
+#line 3286 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4851, 0},
+#line 2619 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4852, 0},
+#line 6278 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4853, 0},
+#line 5618 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4854, 0},
+#line 5929 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4855, 0},
+#line 630 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4856, 0},
+#line 5105 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4857, 4},
+#line 5678 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4858, 0},
+#line 5764 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4859, 0},
+#line 3419 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4860, 0},
+#line 2762 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4861, 0},
+#line 6252 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4862, 0},
+#line 5788 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4863, 0},
+#line 6391 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4864, 0},
+#line 3172 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4865, 0},
+#line 5053 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4866, 0},
+#line 2893 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4867, 0},
+#line 3248 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4868, 0},
+#line 2763 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4869, 0},
+#line 6389 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4870, 0},
+#line 5045 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4871, 0},
+#line 1673 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4872, 4},
+#line 4528 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4873, 0},
+#line 4282 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4874, 0},
+#line 6148 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4875, 0},
+#line 6157 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4876, 0},
+#line 6202 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4877, 0},
+#line 6158 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4878, 0},
+#line 6363 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4879, 0},
+#line 4530 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4880, 0},
+#line 6293 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4881, 0},
+#line 6306 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4882, 0},
+#line 5670 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4883, 0},
+#line 6254 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4884, 0},
+#line 5897 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4885, 0},
+#line 5674 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4886, 0},
+#line 3395 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4887, 0},
+#line 4549 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4888, 0},
+#line 5416 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4889, 0},
+#line 6160 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4890, 0},
+#line 5104 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4891, 4},
+#line 3638 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4892, 0},
+#line 5574 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4893, 0},
+#line 5896 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4894, 4},
+#line 6251 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4895, 0},
+#line 4527 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4896, 0},
+#line 6348 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4897, 0},
+#line 5803 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4898, 0},
+#line 4500 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4899, 0},
+#line 6358 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4900, 0},
+#line 2204 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4901, 0},
+#line 1402 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4902, 0},
+#line 6270 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4903, 0},
+#line 6159 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4904, 0},
+#line 5753 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4905, 0},
+#line 2360 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4906, 0},
+#line 283 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4907, 0},
+#line 5812 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4908, 0},
+#line 3871 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4909, 0},
+#line 4257 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4910, 0},
+#line 4803 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4911, 0},
+#line 3763 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4912, 0},
+#line 2658 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4913, 0},
+#line 2522 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4914, 4},
+#line 5756 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4915, 0},
+#line 5555 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4916, 1},
+#line 4315 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4917, 0},
+#line 5609 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4918, 0},
+#line 5881 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4919, 0},
+#line 565 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4920, 0},
+#line 5052 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4921, 0},
+#line 5795 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4922, 0},
+#line 2249 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4923, 0},
+#line 5622 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4924, 0},
+#line 4291 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4925, 0},
+#line 6256 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4926, 0},
+#line 5761 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4927, 0},
+#line 5577 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4928, 0},
+#line 4052 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4929, 0},
+#line 6352 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4930, 0},
+#line 1448 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4931, 0},
+#line 6347 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4932, 0},
+#line 5691 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4933, 0},
+#line 6397 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4934, 0},
+#line 6171 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4935, 0},
+#line 4557 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4936, 0},
+#line 4593 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4937, 0},
+#line 4729 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4938, 0},
+#line 4029 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4939, 0},
+#line 503 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4940, 0},
+#line 1047 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4941, 0},
+#line 5159 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4942, 0},
+#line 1986 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4943, 0},
+#line 4016 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4944, 0},
+#line 4073 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4945, 0},
+#line 1030 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4946, 0},
+#line 1972 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4947, 0},
+#line 1382 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4948, 0},
+#line 282 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4949, 0},
+#line 5522 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4950, 0},
+#line 4562 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4951, 0},
+#line 5420 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4952, 0},
+#line 2903 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4953, 0},
+#line 1368 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4954, 0},
+#line 6386 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4955, 0},
+#line 4733 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4956, 0},
+#line 3436 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4957, 0},
+#line 4243 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4958, 0},
+#line 3730 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4959, 0},
+#line 3432 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4960, 0},
+#line 6172 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4961, 0},
+#line 3660 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4962, 0},
+#line 4684 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4963, 0},
+#line 4297 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4964, 0},
+#line 4585 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4965, 0},
+#line 6166 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4966, 0},
+#line 2655 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4967, 0},
+#line 5588 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4968, 0},
+#line 6266 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4969, 0},
+#line 4038 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4970, 0},
+#line 1056 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4971, 0},
+#line 4737 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4972, 0},
+#line 3700 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4973, 0},
+#line 1220 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4974, 4},
+#line 6277 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4975, 0},
+#line 3345 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4976, 0},
+#line 4650 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4977, 0},
+#line 3734 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4978, 0},
+#line 6361 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4979, 0},
+#line 4539 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4980, 0},
+#line 1148 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4981, 0},
+#line 4788 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4982, 0},
+#line 6305 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4983, 0},
+#line 5438 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4984, 0},
+#line 4002 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4985, 0},
+#line 5905 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4986, 0},
+#line 1015 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4987, 0},
+#line 5325 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4988, 0},
+#line 1960 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4989, 0},
+#line 4859 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4990, 0},
+#line 1389 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4991, 0},
+#line 5569 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4992, 0},
+#line 6368 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4993, 0},
+#line 4961 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4994, 0},
+#line 5658 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4995, 0},
+#line 6183 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4996, 0},
+#line 5740 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4997, 0},
+#line 6414 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4998, 0},
+#line 4381 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str4999, 0},
+#line 35 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5000, 0},
+#line 5850 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5001, 4},
+#line 4802 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5002, 0},
+#line 1354 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5003, 0},
+#line 5776 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5004, 0},
+#line 3435 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5005, 0},
+#line 5898 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5006, 4},
+#line 4766 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5007, 0},
+#line 6273 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5008, 0},
+#line 2053 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5009, 0},
+#line 959 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5010, 0},
+#line 1905 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5011, 0},
+#line 6141 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5012, 0},
+#line 2502 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5013, 4},
+#line 6201 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5014, 0},
+#line 5700 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5015, 0},
+#line 5662 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5016, 0},
+#line 2573 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5017, 4},
+#line 4652 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5018, 0},
+#line 3480 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5019, 0},
+#line 3729 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5020, 0},
+#line 5508 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5021, 0},
+#line 5849 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5022, 4},
+#line 4688 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5023, 0},
+#line 4851 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5024, 0},
+#line 6231 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5025, 0},
+#line 3307 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5026, 0},
+#line 4633 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5027, 0},
+#line 6187 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5028, 0},
+#line 6226 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5029, 0},
+#line 4709 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5030, 0},
+#line 5656 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5031, 0},
+#line 4721 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5032, 0},
+#line 4712 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5033, 0},
+#line 753 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5034, 0},
+#line 4640 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5035, 0},
+#line 3655 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5036, 0},
+#line 5146 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5037, 0},
+#line 4717 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5038, 0},
+#line 3990 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5039, 0},
+#line 4651 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5040, 0},
+#line 4683 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5041, 0},
+#line 1004 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5042, 0},
+#line 4829 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5043, 0},
+#line 1947 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5044, 0},
+#line 3431 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5045, 0},
+#line 5721 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5046, 0},
+#line 5209 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5047, 0},
+#line 4630 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5048, 0},
+#line 4278 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5049, 0},
+#line 5718 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5050, 0},
+#line 461 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5051, 0},
+#line 1342 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5052, 0},
+#line 6345 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5053, 0},
+#line 5289 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5054, 0},
+#line 4560 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5055, 0},
+#line 4718 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5056, 0},
+#line 3725 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5057, 0},
+#line 6339 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5058, 0},
+#line 5541 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5059, 0},
+#line 143 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5060, 0},
+#line 4742 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5061, 0},
+#line 4852 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5062, 0},
+#line 4252 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5063, 0},
+#line 4738 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5064, 0},
+#line 3658 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5065, 0},
+#line 4241 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5066, 0},
+#line 4866 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5067, 0},
+#line 3425 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5068, 0},
+#line 1750 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5069, 0},
+#line 5766 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5070, 0},
+#line 3722 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5071, 0},
+#line 6373 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5072, 0},
+#line 3191 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5073, 0},
+#line 3375 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5074, 0},
+#line 3192 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5075, 0},
+#line 5011 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5076, 0},
+#line 4294 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5077, 0},
+#line 5813 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5078, 0},
+#line 6161 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5079, 0},
+#line 2101 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5080, 4},
+#line 5657 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5081, 0},
+#line 6181 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5082, 0},
+#line 6400 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5083, 0},
+#line 4626 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5084, 0},
+#line 102 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5085, 0},
+#line 6120 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5086, 4},
+#line 573 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5087, 0},
+#line 5714 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5088, 0},
+#line 3156 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5089, 0},
+#line 6408 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5090, 0},
+#line 4674 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5091, 0},
+#line 4639 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5092, 0},
+#line 4730 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5093, 0},
+#line 4670 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5094, 0},
+#line 3982 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5095, 0},
+#line 4218 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5096, 0},
+#line 4612 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5097, 0},
+#line 996 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5098, 0},
+#line 1938 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5099, 0},
+#line 2510 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5100, 4},
+#line 4711 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5101, 0},
+#line 2034 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5102, 0},
+#line 5436 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5103, 0},
+#line 6401 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5104, 0},
+#line 6258 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5105, 0},
+#line 5533 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5106, 0},
+#line 4716 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5107, 0},
+#line 4724 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5108, 0},
+#line 1334 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5109, 0},
+#line 87 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5110, 0},
+#line 6283 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5111, 0},
+#line 4561 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5112, 0},
+#line 6328 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5113, 0},
+#line 4648 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5114, 0},
+#line 4599 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5115, 0},
+#line 5168 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5116, 0},
+#line 2547 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5117, 4},
+#line 4972 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5118, 0},
+#line 5431 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5119, 0},
+#line 3323 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5120, 0},
+#line 4598 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5121, 0},
+#line 4254 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5122, 0},
+#line 4584 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5123, 0},
+#line 1588 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5124, 4},
+#line 5935 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5125, 0},
+#line 3650 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5126, 0},
+#line 4329 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5127, 0},
+#line 4661 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5128, 0},
+#line 5719 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5129, 0},
+#line 4748 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5130, 0},
+#line 6053 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5131, 0},
+#line 4600 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5132, 0},
+#line 6280 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5133, 0},
+#line 6409 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5134, 0},
+#line 6272 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5135, 0},
+#line 4719 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5136, 0},
+#line 1833 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5137, 4},
+#line 130 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5138, 0},
+#line 6154 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5139, 0},
+#line 6163 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5140, 0},
+#line 5048 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5141, 0},
+#line 6238 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5142, 0},
+#line 2709 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5143, 0},
+#line 6250 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5144, 0},
+#line 2529 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5145, 4},
+#line 95 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5146, 0},
+#line 5927 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5147, 4},
+#line 4234 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5148, 0},
+#line 1999 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5149, 0},
+#line 5838 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5150, 0},
+#line 3714 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5151, 0},
+#line 5695 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5152, 0},
+#line 521 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5153, 4},
+#line 6005 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5154, 0},
+#line 3396 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5155, 0},
+#line 4620 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5156, 0},
+#line 5768 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5157, 0},
+#line 6423 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5158, 0},
+#line 6545 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5159, 0},
+#line 5171 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5160, 0},
+#line 3479 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5161, 0},
+#line 4739 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5162, 0},
+#line 6259 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5163, 0},
+#line 5772 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5164, 0},
+#line 5479 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5165, 0},
+#line 4623 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5166, 0},
+#line 3174 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5167, 0},
+#line 4608 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5168, 0},
+#line 4515 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5169, 0},
+#line 4668 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5170, 0},
+#line 4713 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5171, 0},
+#line 4702 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5172, 0},
+#line 4573 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5173, 0},
+#line 5735 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5174, 0},
+#line 6261 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5175, 0},
+#line 4715 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5176, 0},
+#line 457 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5177, 4},
+#line 4731 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5178, 0},
+#line 5934 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5179, 0},
+#line 5833 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5180, 0},
+#line 5683 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5181, 0},
+#line 2483 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5182, 0},
+#line 1865 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5183, 4},
+#line 5106 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5184, 4},
+#line 6034 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5185, 0},
+#line 4690 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5186, 0},
+#line 2351 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5187, 0},
+#line 5612 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5188, 0},
+#line 5885 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5189, 0},
+#line 2543 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5190, 4},
+#line 6188 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5191, 0},
+#line 2881 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5192, 0},
+#line 6321 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5193, 0},
+#line 4749 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5194, 0},
+#line 4905 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5195, 4},
+#line 5485 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5196, 0},
+#line 4691 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5197, 0},
+#line 5720 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5198, 0},
+#line 5689 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5199, 0},
+#line 5785 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5200, 0},
+#line 5746 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5201, 0},
+#line 1712 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5202, 0},
+#line 5734 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5203, 0},
+#line 5745 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5204, 0},
+#line 4625 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5205, 0},
+#line 5748 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5206, 0},
+#line 1273 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5207, 0},
+#line 3329 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5208, 0},
+#line 5180 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5209, 0},
+#line 5739 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5210, 0},
+#line 6350 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5211, 0},
+#line 6351 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5212, 0},
+#line 2496 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5213, 4},
+#line 5035 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5214, 0},
+#line 5649 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5215, 0},
+#line 5737 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5216, 0},
+#line 5736 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5217, 0},
+#line 4567 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5218, 0},
+#line 5769 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5219, 0},
+#line 6178 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5220, 0},
+#line 3598 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5221, 0},
+#line 5750 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5222, 0},
+#line 5749 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5223, 0},
+#line 6281 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5224, 0},
+#line 5617 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5225, 0},
+#line 6412 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5226, 0},
+#line 6173 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5227, 0},
+#line 6147 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5228, 0},
+#line 5867 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5229, 0},
+#line 6230 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5230, 0},
+#line 5117 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5231, 0},
+#line 5738 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5232, 0},
+#line 2426 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5233, 0},
+#line 4660 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5234, 0},
+#line 5694 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5235, 0},
+#line 4260 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5236, 0},
+#line 5762 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5237, 0},
+#line 6179 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5238, 0},
+#line 4288 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5239, 0},
+#line 4627 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5240, 0},
+#line 6465 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5241, 0},
+#line 833 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5242, 0},
+#line 5742 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5243, 0},
+#line 5943 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5244, 0},
+#line 5747 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5245, 0},
+#line 5524 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5246, 0},
+#line 5536 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5247, 0},
+#line 5193 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5248, 0},
+#line 5557 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5249, 0},
+#line 6295 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5250, 0},
+#line 5884 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5251, 0},
+#line 5646 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5252, 0},
+#line 4900 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5253, 4},
+#line 6360 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5254, 0},
+#line 5182 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5255, 0},
+#line 4545 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5256, 0},
+#line 6426 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5257, 0},
+#line 6392 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5258, 0},
+#line 1620 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5259, 0},
+#line 6384 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5260, 0},
+#line 327 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5261, 0},
+#line 2861 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5262, 0},
+#line 3182 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5263, 0},
+#line 3475 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5264, 4},
+#line 6342 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5265, 0},
+#line 3954 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5266, 0},
+#line 4747 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5267, 0},
+#line 4601 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5268, 0},
+#line 964 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5269, 0},
+#line 1912 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5270, 0},
+#line 5759 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5271, 0},
+#line 4219 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5272, 0},
+#line 5540 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5273, 0},
+#line 4578 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5274, 0},
+#line 4710 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5275, 0},
+#line 6346 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5276, 0},
+#line 1105 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5277, 0},
+#line 6260 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5278, 0},
+#line 1305 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5279, 0},
+#line 5774 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5280, 0},
+#line 6174 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5281, 0},
+#line 6380 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5282, 0},
+#line 3204 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5283, 0},
+#line 2563 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5284, 4},
+#line 2528 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5285, 4},
+#line 4960 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5286, 0},
+#line 4240 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5287, 0},
+#line 926 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5288, 0},
+#line 5418 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5289, 0},
+#line 4106 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5290, 0},
+#line 3715 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5291, 0},
+#line 6385 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5292, 0},
+#line 3169 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5293, 0},
+#line 4723 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5294, 0},
+#line 3002 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5295, 0},
+#line 3434 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5296, 0},
+#line 3728 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5297, 0},
+#line 2911 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5298, 0},
+#line 1563 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5299, 0},
+#line 3659 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5300, 0},
+#line 4610 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5301, 2},
+#line 4954 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5302, 0},
+#line 3967 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5303, 0},
+#line 982 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5304, 0},
+#line 2574 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5305, 4},
+#line 3321 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5306, 0},
+#line 3326 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5307, 0},
+#line 5539 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5308, 0},
+#line 5645 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5309, 0},
+#line 3161 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5310, 0},
+#line 5757 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5311, 0},
+#line 4550 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5312, 0},
+#line 2877 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5313, 0},
+#line 5115 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5314, 0},
+#line 5394 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5315, 0},
+#line 2876 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5316, 0},
+#line 77 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5317, 0},
+#line 3733 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5318, 0},
+#line 6354 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5319, 0},
+#line 4249 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5320, 0},
+#line 5636 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5321, 0},
+#line 2688 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5322, 0},
+#line 4251 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5323, 0},
+#line 5414 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5324, 0},
+#line 4676 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5325, 0},
+#line 4368 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5326, 0},
+#line 3179 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5327, 0},
+#line 5779 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5328, 0},
+#line 5673 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5329, 0},
+#line 4642 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5330, 0},
+#line 2514 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5331, 4},
+#line 1720 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5332, 0},
+#line 4459 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5333, 0},
+#line 5610 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5334, 0},
+#line 4901 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5335, 4},
+#line 4827 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5336, 0},
+#line 6336 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5337, 0},
+#line 2949 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5338, 0},
+#line 929 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5339, 0},
+#line 3478 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5340, 0},
+#line 4436 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5341, 0},
+#line 5944 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5342, 0},
+#line 4223 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5343, 0},
+#line 5471 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5344, 0},
+#line 3426 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5345, 0},
+#line 3770 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5346, 0},
+#line 5537 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5347, 0},
+#line 4255 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5348, 0},
+#line 2428 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5349, 0},
+#line 2549 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5350, 4},
+#line 5715 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5351, 0},
+#line 3654 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5352, 0},
+#line 4906 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5353, 4},
+#line 5875 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5354, 0},
+#line 5626 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5355, 0},
+#line 5872 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5356, 0},
+#line 2702 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5357, 0},
+#line 5473 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5358, 0},
+#line 4917 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5359, 4},
+#line 2769 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5360, 0},
+#line 3239 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5361, 0},
+#line 3331 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5362, 0},
+#line 5767 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5363, 0},
+#line 1711 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5364, 0},
+#line 4636 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5365, 0},
+#line 6225 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5366, 0},
+#line 5819 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5367, 0},
+#line 4558 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5368, 0},
+#line 1251 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5369, 4},
+#line 3158 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5370, 0},
+#line 1155 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5371, 0},
+#line 3918 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5372, 4},
+#line 5066 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5373, 0},
+#line 2479 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5374, 0},
+#line 4746 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5375, 0},
+#line 4656 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5376, 0},
+#line 4115 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5377, 0},
+#line 5487 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5378, 0},
+#line 1614 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5379, 0},
+#line 5922 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5380, 0},
+#line 5519 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5381, 0},
+#line 2513 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5382, 4},
+#line 828 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5383, 0},
+#line 4279 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5384, 0},
+#line 5786 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5385, 0},
+#line 5973 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5386, 0},
+#line 4727 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5387, 0},
+#line 6051 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5388, 0},
+#line 6369 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5389, 0},
+#line 1741 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5390, 0},
+#line 5731 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5391, 0},
+#line 5933 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5392, 0},
+#line 4404 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5393, 0},
+#line 6052 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5394, 0},
+#line 4276 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5395, 0},
+#line 3451 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5396, 0},
+#line 5784 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5397, 0},
+#line 6049 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5398, 0},
+#line 4921 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5399, 0},
+#line 2162 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5400, 4},
+#line 4911 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5401, 4},
+#line 2778 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5402, 0},
+#line 6276 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5403, 0},
+#line 2504 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5404, 4},
+#line 5272 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5405, 0},
+#line 2386 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5406, 0},
+#line 4923 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5407, 0},
+#line 5069 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5408, 4},
+#line 4555 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5409, 0},
+#line 1172 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5410, 0},
+#line 5685 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5411, 0},
+#line 6222 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5412, 0},
+#line 5240 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5413, 4},
+#line 153 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5414, 0},
+#line 6004 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5415, 0},
+#line 5730 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5416, 0},
+#line 5568 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5417, 0},
+#line 5023 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5418, 0},
+#line 5620 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5419, 0},
+#line 5967 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5420, 0},
+#line 5514 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5421, 0},
+#line 1619 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5422, 0},
+#line 4261 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5423, 0},
+#line 5493 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5424, 0},
+#line 5343 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5425, 0},
+#line 2810 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5426, 0},
+#line 5823 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5427, 0},
+#line 5741 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5428, 0},
+#line 5068 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5429, 4},
+#line 2561 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5430, 4},
+#line 4673 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5431, 0},
+#line 5065 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5432, 0},
+#line 3798 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5433, 0},
+#line 5948 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5434, 0},
+#line 2866 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5435, 0},
+#line 4665 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5436, 0},
+#line 2500 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5437, 4},
+#line 2826 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5438, 0},
+#line 4922 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5439, 4},
+#line 4051 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5440, 0},
+#line 4635 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5441, 0},
+#line 6087 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5442, 0},
+#line 4692 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5443, 0},
+#line 6055 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5444, 0},
+#line 4649 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5445, 0},
+#line 6146 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5446, 0},
+#line 6075 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5447, 0},
+#line 5488 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5448, 0},
+#line 3772 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5449, 0},
+#line 6041 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5450, 0},
+#line 134 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5451, 0},
+#line 4275 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5452, 0},
+#line 3207 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5453, 0},
+#line 2798 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5454, 0},
+#line 2555 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5455, 4},
+#line 4305 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5456, 0},
+#line 5499 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5457, 0},
+#line 5380 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5458, 0},
+#line 5448 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5459, 0},
+#line 5313 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5460, 0},
+#line 2880 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5461, 0},
+#line 3159 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5462, 0},
+#line 5226 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5463, 0},
+#line 6271 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5464, 0},
+#line 4055 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5465, 0},
+#line 1613 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5466, 0},
+#line 5572 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5467, 0},
+#line 5733 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5468, 0},
+#line 5191 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5469, 0},
+#line 5582 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5470, 0},
+#line 5276 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5471, 0},
+#line 5545 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5472, 0},
+#line 4206 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5473, 0},
+#line 3764 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5474, 0},
+#line 5246 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5475, 0},
+#line 4506 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5476, 0},
+#line 4574 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5477, 0},
+#line 5372 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5478, 0},
+#line 5732 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5479, 0},
+#line 5821 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5480, 0},
+#line 5044 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5481, 0},
+#line 908 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5482, 0},
+#line 4618 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5483, 0},
+#line 5451 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5484, 0},
+#line 3503 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5485, 0},
+#line 5743 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5486, 0},
+#line 2123 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5487, 0},
+#line 5498 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5488, 0},
+#line 6407 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5489, 0},
+#line 4605 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5490, 0},
+#line 5791 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5491, 0},
+#line 1556 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5492, 0},
+#line 907 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5493, 4},
+#line 4358 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5494, 0},
+#line 1526 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5495, 0},
+#line 1616 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5496, 0},
+#line 212 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5497, 0},
+#line 4547 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5498, 0},
+#line 6502 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5499, 0},
+#line 2837 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5500, 0},
+#line 4559 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5501, 0},
+#line 1574 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5502, 0},
+#line 6107 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5503, 0},
+#line 3143 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5504, 0},
+#line 5699 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5505, 0},
+#line 4643 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5506, 0},
+#line 5744 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5507, 0},
+#line 6170 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5508, 0},
+#line 4725 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5509, 0},
+#line 3751 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5510, 0},
+#line 4295 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5511, 0},
+#line 5123 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5512, 0},
+#line 2593 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5513, 4},
+#line 2358 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5514, 0},
+#line 6379 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5515, 0},
+#line 1431 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5516, 4},
+#line 1615 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5517, 0},
+#line 5947 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5518, 0},
+#line 1552 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5519, 0},
+#line 4823 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5520, 0},
+#line 4246 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5521, 0},
+#line 3282 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5522, 0},
+#line 1572 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5523, 0},
+#line 1521 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5524, 0},
+#line 5480 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5525, 0},
+#line 1622 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5526, 0},
+#line 4619 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5527, 0},
+#line 1683 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5528, 0},
+#line 2969 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5529, 2},
+#line 2362 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5530, 0},
+#line 4054 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5531, 0},
+#line 3051 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5532, 0},
+#line 2977 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5533, 0},
+#line 3551 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5534, 0},
+#line 3545 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5535, 0},
+#line 2245 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5536, 0},
+#line 588 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5537, 0},
+#line 5477 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5538, 0},
+#line 4750 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5539, 0},
+#line 4698 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5540, 0},
+#line 4317 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5541, 4},
+#line 1252 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5542, 4},
+#line 5611 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5543, 0},
+#line 2233 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5544, 0},
+#line 1621 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5545, 0},
+#line 667 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5546, 0},
+#line 5790 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5547, 0},
+#line 3914 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5548, 0},
+#line 5486 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5549, 0},
+#line 909 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5550, 0},
+#line 1838 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5551, 0},
+#line 4245 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5552, 0},
+#line 3557 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5553, 0},
+#line 1282 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5554, 0},
+#line 3441 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5555, 0},
+#line 6422 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5556, 0},
+#line 5686 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5557, 0},
+#line 5637 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5558, 0},
+#line 3539 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5559, 0},
+#line 4714 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5560, 0},
+#line 2316 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5561, 0},
+#line 3891 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5562, 0},
+#line 2163 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5563, 0},
+#line 4077 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5564, 0},
+#line 6140 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5565, 1},
+#line 5770 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5566, 0},
+#line 5476 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5567, 0},
+#line 3517 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5568, 0},
+#line 266 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5569, 0},
+#line 5080 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5570, 0},
+#line 2565 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5571, 4},
+#line 5496 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5572, 0},
+#line 5544 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5573, 0},
+#line 1164 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5574, 0},
+#line 4263 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5575, 0},
+#line 4669 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5576, 0},
+#line 5500 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5577, 0},
+#line 5531 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5578, 0},
+#line 6224 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5579, 0},
+#line 4701 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5580, 0},
+#line 4663 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5581, 0},
+#line 128 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5582, 0},
+#line 2568 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5583, 4},
+#line 2165 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5584, 4},
+#line 6243 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5585, 0},
+#line 3195 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5586, 0},
+#line 5497 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5587, 0},
+#line 5542 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5588, 0},
+#line 6221 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5589, 0},
+#line 2164 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5590, 4},
+#line 5659 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5591, 0},
+#line 5630 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5592, 0},
+#line 5511 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5593, 0},
+#line 6124 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5594, 0},
+#line 5341 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5595, 0},
+#line 6219 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5596, 0},
+#line 5284 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5597, 0},
+#line 436 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5598, 0},
+#line 5327 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5599, 0},
+#line 6381 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5600, 0},
+#line 5354 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5601, 0},
+#line 6417 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5602, 0},
+#line 804 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5603, 0},
+#line 200 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5604, 0},
+#line 2578 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5605, 0},
+#line 4926 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5606, 0},
+#line 4700 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5607, 0},
+#line 5832 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5608, 0},
+#line 3900 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5609, 0},
+#line 5339 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5610, 0},
+#line 5454 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5611, 0},
+#line 5359 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5612, 0},
+#line 4638 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5613, 0},
+#line 3776 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5614, 4},
+#line 5780 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5615, 0},
+#line 6436 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5616, 0},
+#line 625 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5617, 0},
+#line 5632 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5618, 0},
+#line 652 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5619, 0},
+#line 1200 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5620, 0},
+#line 4621 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5621, 0},
+#line 6263 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5622, 0},
+#line 272 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5623, 0},
+#line 5228 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5624, 0},
+#line 6235 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5625, 0},
+#line 4616 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5626, 0},
+#line 4743 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5627, 0},
+#line 361 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5628, 0},
+#line 5644 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5629, 0},
+#line 3423 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5630, 0},
+#line 5503 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5631, 0},
+#line 1433 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5632, 4},
+#line 6116 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5633, 0},
+#line 3196 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5634, 0},
+#line 2973 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5635, 0},
+#line 5433 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5636, 0},
+#line 5631 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5637, 0},
+#line 5623 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5638, 0},
+#line 5494 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5639, 0},
+#line 4568 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5640, 0},
+#line 5845 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5641, 0},
+#line 5423 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5642, 0},
+#line 4671 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5643, 0},
+#line 5655 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5644, 0},
+#line 4571 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5645, 0},
+#line 4212 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5646, 0},
+#line 6404 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5647, 0},
+#line 3393 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5648, 0},
+#line 6325 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5649, 0},
+#line 4183 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5650, 0},
+#line 6437 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5651, 0},
+#line 3274 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5652, 4},
+#line 3690 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5653, 0},
+#line 1511 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5654, 0},
+#line 3363 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5655, 0},
+#line 3925 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5656, 0},
+#line 139 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5657, 0},
+#line 3644 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5658, 0},
+#line 788 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5659, 0},
+#line 4963 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5660, 0},
+#line 5621 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5661, 0},
+#line 4904 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5662, 4},
+#line 3178 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5663, 0},
+#line 4914 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5664, 4},
+#line 1601 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5665, 0},
+#line 5526 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5666, 0},
+#line 3694 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5667, 0},
+#line 581 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5668, 0},
+#line 5724 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5669, 0},
+#line 4518 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5670, 0},
+#line 4913 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5671, 4},
+#line 4355 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5672, 0},
+#line 5489 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5673, 0},
+#line 4740 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5674, 0},
+#line 1573 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5675, 0},
+#line 866 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5676, 0},
+#line 3693 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5677, 0},
+#line 2930 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5678, 0},
+#line 1106 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5679, 0},
+#line 4617 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5680, 0},
+#line 2043 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5681, 0},
+#line 2027 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5682, 0},
+#line 140 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5683, 0},
+#line 6521 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5684, 0},
+#line 2035 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5685, 0},
+#line 1527 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5686, 0},
+#line 3821 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5687, 0},
+#line 5465 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5688, 0},
+#line 6236 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5689, 0},
+#line 5148 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5690, 0},
+#line 3168 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5691, 0},
+#line 2046 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5692, 0},
+#line 4050 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5693, 0},
+#line 5077 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5694, 0},
+#line 4632 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5695, 0},
+#line 5076 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5696, 0},
+#line 6311 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5697, 0},
+#line 2045 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5698, 0},
+#line 2060 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5699, 0},
+#line 6078 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5700, 0},
+#line 1432 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5701, 4},
+#line 3155 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5702, 0},
+#line 1733 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5703, 0},
+#line 4575 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5704, 0},
+#line 6504 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5705, 0},
+#line 2031 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5706, 0},
+#line 4383 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5707, 0},
+#line 6245 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5708, 0},
+#line 4577 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5709, 0},
+#line 5466 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5710, 0},
+#line 6265 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5711, 0},
+#line 1202 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5712, 0},
+#line 2037 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5713, 0},
+#line 3817 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5714, 0},
+#line 4622 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5715, 0},
+#line 4205 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5716, 0},
+#line 3885 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5717, 0},
+#line 3415 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5718, 0},
+#line 100 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5719, 4},
+#line 3463 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5720, 0},
+#line 2039 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5721, 0},
+#line 5517 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5722, 0},
+#line 3310 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5723, 0},
+#line 5478 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5724, 0},
+#line 4644 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5725, 0},
+#line 2029 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5726, 0},
+#line 3420 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5727, 0},
+#line 5391 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5728, 0},
+#line 4699 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5729, 0},
+#line 5864 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5730, 0},
+#line 1698 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5731, 0},
+#line 2412 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5732, 0},
+#line 4270 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5733, 0},
+#line 2028 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5734, 0},
+#line 2036 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5735, 0},
+#line 5456 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5736, 0},
+#line 4916 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5737, 4},
+#line 5583 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5738, 0},
+#line 416 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5739, 4},
+#line 2566 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5740, 4},
+#line 3762 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5741, 0},
+#line 2337 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5742, 0},
+#line 4949 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5743, 0},
+#line 6232 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5744, 0},
+#line 4945 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5745, 0},
+#line 4912 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5746, 4},
+#line 3219 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5747, 0},
+#line 1478 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5748, 4},
+#line 4790 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5749, 4},
+#line 2033 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5750, 0},
+#line 3259 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5751, 0},
+#line 2041 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5752, 0},
+#line 2267 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5753, 0},
+#line 2829 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5754, 0},
+#line 6061 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5755, 0},
+#line 4910 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5756, 4},
+#line 5314 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5757, 0},
+#line 4975 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5758, 0},
+#line 6184 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5759, 0},
+#line 3306 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5760, 0},
+#line 627 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5761, 0},
+#line 5654 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5762, 0},
+#line 442 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5763, 0},
+#line 2032 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5764, 0},
+#line 4290 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5765, 0},
+#line 2129 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5766, 0},
+#line 4537 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5767, 0},
+#line 3217 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5768, 0},
+#line 3304 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5769, 0},
+#line 5899 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5770, 0},
+#line 6458 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5771, 0},
+#line 4909 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5772, 4},
+#line 5520 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5773, 0},
+#line 3645 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5774, 0},
+#line 3736 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5775, 0},
+#line 5589 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5776, 0},
+#line 5457 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5777, 0},
+#line 5464 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5778, 0},
+#line 5716 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5779, 0},
+#line 215 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5780, 0},
+#line 5462 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5781, 0},
+#line 5528 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5782, 0},
+#line 3579 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5783, 0},
+#line 4782 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5784, 0},
+#line 5641 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5785, 0},
+#line 5820 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5786, 0},
+#line 3223 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5787, 0},
+#line 5798 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5788, 0},
+#line 3335 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5789, 0},
+#line 4947 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5790, 0},
+#line 5566 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5791, 0},
+#line 5760 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5792, 0},
+#line 5698 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5793, 0},
+#line 5856 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5794, 0},
+#line 1520 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5795, 0},
+#line 4890 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5796, 0},
+#line 3162 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5797, 0},
+#line 3909 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5798, 0},
+#line 74 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5799, 0},
+#line 897 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5800, 0},
+#line 4208 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5801, 0},
+#line 5492 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5802, 0},
+#line 5918 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5803, 0},
+#line 5491 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5804, 0},
+#line 3140 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5805, 0},
+#line 4224 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5806, 0},
+#line 5925 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5807, 0},
+#line 5653 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5808, 0},
+#line 4354 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5809, 0},
+#line 3646 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5810, 0},
+#line 5062 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5811, 4},
+#line 56 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5812, 0},
+#line 64 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5813, 0},
+#line 2886 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5814, 0},
+#line 42 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5815, 0},
+#line 4340 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5816, 0},
+#line 2983 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5817, 0},
+#line 429 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5818, 0},
+#line 1771 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5819, 0},
+#line 4348 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5820, 0},
+#line 55 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5821, 0},
+#line 5799 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5822, 0},
+#line 4352 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5823, 0},
+#line 43 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5824, 0},
+#line 4556 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5825, 0},
+#line 3691 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5826, 0},
+#line 57 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5827, 0},
+#line 5174 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5828, 0},
+#line 4343 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5829, 0},
+#line 65 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5830, 0},
+#line 1163 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5831, 0},
+#line 111 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5832, 0},
+#line 68 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5833, 0},
+#line 4347 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5834, 0},
+#line 5440 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5835, 0},
+#line 67 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5836, 0},
+#line 47 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5837, 0},
+#line 5470 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5838, 0},
+#line 5777 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5839, 0},
+#line 726 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5840, 0},
+#line 54 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5841, 0},
+#line 5859 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5842, 0},
+#line 4342 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5843, 0},
+#line 5395 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5844, 0},
+#line 4349 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5845, 0},
+#line 569 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5846, 4},
+#line 4318 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5847, 0},
+#line 45 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5848, 0},
+#line 6151 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5849, 0},
+#line 44 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5850, 0},
+#line 3348 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5851, 0},
+#line 5677 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5852, 0},
+#line 6237 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5853, 0},
+#line 46 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5854, 0},
+#line 5633 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5855, 0},
+#line 6507 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5856, 0},
+#line 2787 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5857, 0},
+#line 4273 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5858, 0},
+#line 4256 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5859, 0},
+#line 6149 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5860, 0},
+#line 2888 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5861, 0},
+#line 5061 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5862, 0},
+#line 4341 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5863, 0},
+#line 4293 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5864, 0},
+#line 6164 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5865, 0},
+#line 3384 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5866, 0},
+#line 4221 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5867, 0},
+#line 5782 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5868, 0},
+#line 4174 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5869, 0},
+#line 5552 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5870, 0},
+#line 61 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5871, 0},
+#line 4351 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5872, 0},
+#line 4628 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5873, 0},
+#line 2732 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5874, 0},
+#line 5643 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5875, 0},
+#line 3687 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5876, 0},
+#line 2356 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5877, 0},
+#line 66 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5878, 0},
+#line 5941 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5879, 0},
+#line 4253 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5880, 0},
+#line 5403 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5881, 0},
+#line 5481 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5882, 0},
+#line 62 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5883, 0},
+#line 3615 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5884, 0},
+#line 48 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5885, 0},
+#line 1590 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5886, 0},
+#line 4222 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5887, 0},
+#line 4058 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5888, 0},
+#line 58 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5889, 0},
+#line 2875 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5890, 0},
+#line 5818 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5891, 0},
+#line 6253 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5892, 0},
+#line 4908 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5893, 4},
+#line 5563 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5894, 0},
+#line 5188 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5895, 0},
+#line 5546 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5896, 0},
+#line 5924 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5897, 0},
+#line 6150 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5898, 0},
+#line 6359 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5899, 0},
+#line 5758 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5900, 0},
+#line 5501 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5901, 0},
+#line 5281 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5902, 0},
+#line 5102 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5903, 4},
+#line 2715 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5904, 0},
+#line 1603 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5905, 0},
+#line 5565 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5906, 0},
+#line 5781 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5907, 0},
+#line 2897 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5908, 0},
+#line 5057 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5909, 0},
+#line 5506 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5910, 0},
+#line 4720 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5911, 0},
+#line 2044 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5912, 0},
+#line 4346 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5913, 0},
+#line 2749 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5914, 0},
+#line 6204 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5915, 0},
+#line 2932 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5916, 0},
+#line 5853 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5917, 0},
+#line 3358 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5918, 0},
+#line 53 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5919, 0},
+#line 6491 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5920, 0},
+#line 4915 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5921, 4},
+#line 6282 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5922, 0},
+#line 5751 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5923, 0},
+#line 4979 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5924, 0},
+#line 4695 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5925, 0},
+#line 1464 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5926, 4},
+#line 2803 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5927, 0},
+#line 4603 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5928, 0},
+#line 1567 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5929, 0},
+#line 5441 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5930, 0},
+#line 4754 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5931, 0},
+#line 5534 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5932, 0},
+#line 5990 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5933, 0},
+#line 5894 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5934, 4},
+#line 5895 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5935, 4},
+#line 5863 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5936, 0},
+#line 63 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5937, 0},
+#line 5800 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5938, 0},
+#line 3202 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5939, 0},
+#line 5054 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5940, 0},
+#line 5055 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5941, 0},
+#line 6546 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5942, 4},
+#line 6547 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5943, 4},
+#line 4920 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5944, 4},
+#line 1463 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5945, 4},
+#line 5173 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5946, 0},
+#line 3173 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5947, 0},
+#line 6315 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5948, 0},
+#line 5624 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5949, 0},
+#line 3206 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5950, 0},
+#line 5472 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5951, 0},
+#line 5553 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5952, 0},
+#line 6228 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5953, 0},
+#line 5561 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5954, 0},
+#line 4755 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5955, 4},
+#line 4581 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5956, 0},
+#line 4687 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5957, 0},
+#line 6156 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5958, 0},
+#line 4344 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5959, 0},
+#line 1465 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5960, 4},
+#line 5573 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5961, 0},
+#line 5556 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5962, 0},
+#line 2643 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5963, 0},
+#line 5651 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5964, 0},
+#line 4602 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5965, 0},
+#line 4569 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5966, 0},
+#line 4517 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5967, 0},
+#line 49 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5968, 0},
+#line 4345 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5969, 0},
+#line 2952 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5970, 0},
+#line 5773 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5971, 0},
+#line 4604 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5972, 0},
+#line 6189 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5973, 0},
+#line 6211 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5974, 0},
+#line 4237 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5975, 0},
+#line 5783 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5976, 0},
+#line 5463 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5977, 0},
+#line 6294 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5978, 0},
+#line 52 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5979, 0},
+#line 4353 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5980, 0},
+#line 5560 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5981, 0},
+#line 4606 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5982, 0},
+#line 6212 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5983, 0},
+#line 5242 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5984, 0},
+#line 4696 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5985, 0},
+#line 4510 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5986, 0},
+#line 5958 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5987, 0},
+#line 50 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5988, 0},
+#line 69 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5989, 0},
+#line 4322 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5990, 0},
+#line 4213 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5991, 0},
+#line 5693 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5992, 0},
+#line 6195 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5993, 0},
+#line 5530 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5994, 0},
+#line 5627 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5995, 0},
+#line 5843 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5996, 0},
+#line 4533 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5997, 0},
+#line 51 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5998, 0},
+#line 6162 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str5999, 0},
+#line 4572 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6000, 0},
+#line 4496 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6001, 0},
+#line 5357 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6002, 0},
+#line 5639 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6003, 0},
+#line 4505 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6004, 0},
+#line 5635 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6005, 0},
+#line 5482 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6006, 0},
+#line 6197 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6007, 0},
+#line 6415 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6008, 0},
+#line 5008 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6009, 0},
+#line 5801 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6010, 0},
+#line 2343 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6011, 0},
+#line 6479 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6012, 0},
+#line 5017 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6013, 4},
+#line 4984 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6014, 0},
+#line 5460 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6015, 0},
+#line 6249 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6016, 0},
+#line 4277 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6017, 0},
+#line 6186 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6018, 0},
+#line 6209 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6019, 0},
+#line 6299 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6020, 0},
+#line 5175 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6021, 0},
+#line 4741 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6022, 0},
+#line 6374 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6023, 0},
+#line 4522 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6024, 0},
+#line 6208 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6025, 0},
+#line 6153 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6026, 0},
+#line 6289 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6027, 0},
+#line 6291 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6028, 0},
+#line 4312 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6029, 0},
+#line 6388 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6030, 0},
+#line 2342 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6031, 0},
+#line 2484 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6032, 0},
+#line 5817 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6033, 0},
+#line 6216 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6034, 0},
+#line 5334 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6035, 0},
+#line 6210 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6036, 0},
+#line 6207 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6037, 0},
+#line 6403 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6038, 0},
+#line 6316 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6039, 0},
+#line 5608 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6040, 0},
+#line 3308 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6041, 0},
+#line 5516 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6042, 0},
+#line 5787 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6043, 0},
+#line 6365 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6044, 0},
+#line 629 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6045, 4},
+#line 6327 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6046, 0},
+#line 923 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6047, 0},
+#line 6185 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6048, 0},
+#line 5453 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6049, 0},
+#line 6355 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6050, 0},
+#line 5467 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6051, 0},
+#line 6290 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6052, 0},
+#line 6292 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6053, 0},
+#line 1236 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6054, 4},
+#line 6248 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6055, 0},
+#line 5666 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6056, 0},
+#line 4264 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6057, 0},
+#line 3154 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6058, 0},
+#line 2107 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6059, 0},
+#line 5575 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6060, 0},
+#line 5571 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6061, 0},
+#line 6215 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6062, 0},
+#line 3315 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6063, 0},
+#line 6371 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6064, 0},
+#line 5050 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6065, 0},
+#line 924 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6066, 0},
+#line 805 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6067, 0},
+#line 5134 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6068, 0},
+#line 4732 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6069, 0},
+#line 6303 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6070, 0},
+#line 3829 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6071, 0},
+#line 631 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6072, 0},
+#line 2572 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6073, 4},
+#line 6262 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6074, 0},
+#line 2898 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6075, 0},
+#line 5283 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6076, 0},
+#line 5684 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6077, 0},
+#line 6182 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6078, 0},
+#line 841 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6079, 1},
+#line 1540 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6080, 0},
+#line 5688 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6081, 0},
+#line 4786 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6082, 0},
+#line 3337 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6083, 0},
+#line 6191 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6084, 0},
+#line 4472 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6085, 0},
+#line 4588 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6086, 0},
+#line 5771 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6087, 0},
+#line 4455 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6088, 0},
+#line 5107 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6089, 4},
+#line 5338 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6090, 0},
+#line 5513 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6091, 0},
+#line 252 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6092, 0},
+#line 6288 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6093, 0},
+#line 6326 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6094, 0},
+#line 5690 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6095, 0},
+#line 4482 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6096, 0},
+#line 4925 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6097, 0},
+#line 4440 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6098, 0},
+#line 6308 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6099, 0},
+#line 4238 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6100, 0},
+#line 4579 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6101, 0},
+#line 3290 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6102, 0},
+#line 2391 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6103, 0},
+#line 2341 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6104, 0},
+#line 6286 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6105, 0},
+#line 5387 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6106, 0},
+#line 5578 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6107, 4},
+#line 4426 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6108, 0},
+#line 5507 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6109, 0},
+#line 4080 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6110, 0},
+#line 5667 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6111, 0},
+#line 4497 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6112, 0},
+#line 6180 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6113, 0},
+#line 6165 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6114, 0},
+#line 3225 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6115, 0},
+#line 4609 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6116, 0},
+#line 5459 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6117, 0},
+#line 4417 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6118, 0},
+#line 5642 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6119, 0},
+#line 5725 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6120, 0},
+#line 6227 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6121, 0},
+#line 6419 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6122, 0},
+#line 4272 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6123, 0},
+#line 5792 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6124, 0},
+#line 5252 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6125, 0},
+#line 3718 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6126, 0},
+#line 6234 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6127, 0},
+#line 2524 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6128, 4},
+#line 4689 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6129, 0},
+#line 811 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6130, 0},
+#line 5413 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6131, 0},
+#line 6298 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6132, 0},
+#line 5681 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6133, 0},
+#line 5789 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6134, 0},
+#line 4907 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6135, 4},
+#line 6241 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6136, 0},
+#line 6331 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6137, 0},
+#line 6418 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6138, 0},
+#line 6411 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6139, 0},
+#line 3697 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6140, 0},
+#line 5729 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6141, 0},
+#line 5523 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6142, 0},
+#line 4666 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6143, 0},
+#line 6324 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6144, 0},
+#line 4903 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6145, 4},
+#line 5529 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6146, 0},
+#line 2525 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6147, 4},
+#line 5580 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6148, 0},
+#line 6302 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6149, 0},
+#line 4667 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6150, 0},
+#line 6330 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6151, 0},
+#line 5474 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6152, 0},
+#line 5752 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6153, 0},
+#line 5532 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6154, 0},
+#line 3184 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6155, 0},
+#line 3291 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6156, 0},
+#line 1611 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6157, 0},
+#line 5551 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6158, 4},
+#line 6229 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6159, 0},
+#line 3314 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6160, 0},
+#line 6284 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6161, 0},
+#line 6364 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6162, 0},
+#line 6198 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6163, 0},
+#line 5166 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6164, 0},
+#line 3320 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6165, 0},
+#line 6268 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6166, 0},
+#line 5210 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6167, 0},
+#line 3209 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6168, 0},
+#line 5614 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6169, 0},
+#line 1449 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6170, 0},
+#line 3211 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6171, 0},
+#line 3692 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6172, 0},
+#line 5558 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6173, 0},
+#line 6205 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6174, 0},
+#line 5908 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6175, 0},
+#line 6000 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6176, 0},
+#line 2344 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6177, 0},
+#line 6443 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6178, 0},
+#line 6296 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6179, 0},
+#line 4657 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6180, 0},
+#line 3180 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6181, 0},
+#line 6314 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6182, 0},
+#line 3429 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6183, 0},
+#line 5435 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6184, 0},
+#line 5455 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6185, 0},
+#line 4664 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6186, 0},
+#line 6424 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6187, 0},
+#line 5703 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6188, 0},
+#line 6176 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6189, 0},
+#line 4384 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6190, 0},
+#line 4662 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6191, 0},
+#line 6257 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6192, 0},
+#line 5004 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6193, 0},
+#line 6313 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6194, 0},
+#line 2414 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6195, 0},
+#line 6233 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6196, 0},
+#line 2517 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6197, 4},
+#line 3316 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6198, 0},
+#line 5765 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6199, 0},
+#line 5232 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6200, 0},
+#line 6196 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6201, 0},
+#line 3218 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6202, 0},
+#line 4580 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6203, 1},
+#line 4629 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6204, 0},
+#line 4236 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6205, 0},
+#line 845 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6206, 1},
+#line 4693 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6207, 0},
+#line 4328 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6208, 0},
+#line 1609 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6209, 0},
+#line 2594 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6210, 4},
+#line 107 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6211, 0},
+#line 6383 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6212, 0},
+#line 6274 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6213, 0},
+#line 5664 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6214, 0},
+#line 5711 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6215, 0},
+#line 6322 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6216, 0},
+#line 5029 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6217, 0},
+#line 5502 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6218, 0},
+#line 5408 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6219, 0},
+#line 2509 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6220, 4},
+#line 5969 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6221, 0},
+#line 6177 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6222, 0},
+#line 5543 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6223, 0},
+#line 4672 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6224, 0},
+#line 5027 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6225, 0},
+#line 5468 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6226, 0},
+#line 127 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6227, 0},
+#line 5026 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6228, 0},
+#line 5510 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6229, 0},
+#line 5450 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6230, 0},
+#line 802 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6231, 0},
+#line 2871 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6232, 0},
+#line 3208 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6233, 0},
+#line 1250 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6234, 4},
+#line 4586 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6235, 0},
+#line 5025 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6236, 0},
+#line 4722 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6237, 0},
+#line 5475 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6238, 0},
+#line 5652 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6239, 0},
+#line 5671 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6240, 0},
+#line 5919 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6241, 0},
+#line 1499 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6242, 0},
+#line 5696 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6243, 0},
+#line 5692 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6244, 0},
+#line 59 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6245, 0},
+#line 60 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6246, 0},
+#line 5504 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6247, 0},
+#line 5005 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6248, 0},
+#line 5200 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6249, 0},
+#line 2013 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6250, 0},
+#line 4335 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6251, 4},
+#line 6200 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6252, 0},
+#line 5120 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6253, 0},
+#line 6297 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6254, 0},
+#line 1809 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6255, 4},
+#line 2870 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6256, 0},
+#line 2338 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6257, 0},
+#line 2336 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6258, 0},
+#line 1788 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6259, 0},
+#line 5312 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6260, 0},
+#line 5458 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6261, 0},
+#line 4535 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6262, 0},
+#line 5483 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6263, 0},
+#line 4244 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6264, 0},
+#line 5613 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6265, 0},
+#line 4350 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6266, 0},
+#line 4708 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6267, 0},
+#line 4187 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6268, 0},
+#line 6175 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6269, 0},
+#line 5629 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6270, 0},
+#line 4707 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6271, 0},
+#line 2264 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6272, 0},
+#line 5619 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6273, 0},
+#line 6244 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6274, 0},
+#line 4326 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6275, 0},
+#line 2240 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6276, 0},
+#line 4678 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6277, 0},
+#line 5665 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6278, 0},
+#line 5028 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6279, 0},
+#line 5211 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6280, 0},
+#line 5512 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6281, 0},
+#line 4918 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6282, 4},
+#line 5727 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6283, 0},
+#line 6264 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6284, 0},
+#line 6543 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6285, 0},
+#line 137 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6286, 0},
+#line 6366 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6287, 0},
+#line 6343 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6288, 0},
+#line 3190 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6289, 4},
+#line 5495 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6290, 0},
+#line 3273 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6291, 4},
+#line 6220 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6292, 0},
+#line 6410 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6293, 0},
+#line 1100 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6294, 0},
+#line 5726 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6295, 0},
+#line 1510 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6296, 0},
+#line 4706 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6297, 0},
+#line 3198 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6298, 4},
+#line 4570 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6299, 0},
+#line 6269 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6300, 0},
+#line 4529 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6301, 0},
+#line 4704 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6302, 4},
+#line 4259 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6303, 0},
+#line 6279 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6304, 0},
+#line 6169 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6305, 0},
+#line 6060 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6306, 0},
+#line 5830 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6307, 0},
+#line 5484 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6308, 0},
+#line 5680 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6309, 0},
+#line 5449 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6310, 0},
+#line 4327 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6311, 0},
+#line 5702 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6312, 0},
+#line 2042 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6313, 0},
+#line 5063 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6314, 4},
+#line 2038 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6315, 0},
+#line 2660 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6316, 0},
+#line 3081 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6317, 0},
+#line 5550 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6318, 0},
+#line 5697 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6319, 0},
+#line 5638 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6320, 0},
+#line 1581 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6321, 4},
+#line 1585 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6322, 4},
+#line 4978 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6323, 0},
+#line 5601 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6324, 0},
+#line 6337 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6325, 0},
+#line 2090 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6326, 0},
+#line 5822 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6327, 0},
+#line 5605 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6328, 0},
+#line 3022 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6329, 0},
+#line 6309 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6330, 0},
+#line 1685 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6331, 4},
+#line 5708 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6332, 0},
+#line 5593 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6333, 0},
+#line 5810 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6334, 0},
+#line 4283 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6335, 0},
+#line 5212 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6336, 0},
+#line 5598 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6337, 0},
+#line 5663 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6338, 0},
+#line 5595 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6339, 0},
 #line 4582 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6520, 0},
-#line 4943 "effective_tld_names.gperf"
-      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6521, 0}
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6340, 0},
+#line 5811 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6341, 0},
+#line 5587 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6342, 0},
+#line 5648 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6343, 0},
+#line 720 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6344, 0},
+#line 724 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6345, 0},
+#line 706 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6346, 0},
+#line 719 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6347, 0},
+#line 742 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6348, 0},
+#line 723 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6349, 0},
+#line 700 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6350, 0},
+#line 6320 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6351, 0},
+#line 718 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6352, 0},
+#line 717 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6353, 0},
+#line 725 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6354, 0},
+#line 745 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6355, 0},
+#line 703 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6356, 0},
+#line 699 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6357, 0},
+#line 737 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6358, 0},
+#line 5515 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6359, 0},
+#line 6310 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6360, 0},
+#line 715 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6361, 0},
+#line 701 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6362, 0},
+#line 3334 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6363, 0},
+#line 5600 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6364, 0},
+#line 4576 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6365, 0},
+#line 5809 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6366, 0},
+#line 702 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6367, 0},
+#line 5805 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6368, 0},
+#line 5037 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6369, 0},
+#line 704 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6370, 0},
+#line 721 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6371, 0},
+#line 5806 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6372, 0},
+#line 729 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6373, 0},
+#line 728 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6374, 0},
+#line 722 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6375, 0},
+#line 5311 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6376, 0},
+#line 743 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6377, 0},
+#line 4634 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6378, 0},
+#line 698 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6379, 0},
+#line 4179 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6380, 0},
+#line 731 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6381, 0},
+#line 732 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6382, 0},
+#line 708 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6383, 0},
+#line 5594 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6384, 0},
+#line 707 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6385, 0},
+#line 709 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6386, 0},
+#line 5815 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6387, 0},
+#line 697 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6388, 0},
+#line 736 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6389, 0},
+#line 735 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6390, 0},
+#line 733 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6391, 0},
+#line 740 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6392, 0},
+#line 227 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6393, 4},
+#line 730 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6394, 0},
+#line 5640 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6395, 0},
+#line 4705 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6396, 0},
+#line 3424 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6397, 0},
+#line 3249 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6398, 0},
+#line 710 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6399, 0},
+#line 5816 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6400, 0},
+#line 5490 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6401, 0},
+#line 5549 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6402, 0},
+#line 5763 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6403, 0},
+#line 5607 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6404, 0},
+#line 5705 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6405, 0},
+#line 5446 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6406, 0},
+#line 5707 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6407, 0},
+#line 716 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6408, 0},
+#line 5794 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6409, 0},
+#line 3232 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6410, 0},
+#line 4233 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6411, 0},
+#line 5597 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6412, 0},
+#line 6338 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6413, 0},
+#line 734 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6414, 0},
+#line 5604 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6415, 0},
+#line 3266 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6416, 0},
+#line 4681 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6417, 0},
+#line 2047 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6418, 0},
+#line 5808 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6419, 0},
+#line 4565 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6420, 0},
+#line 4682 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6421, 0},
+#line 4686 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6422, 0},
+#line 5461 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6423, 0},
+#line 5807 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6424, 0},
+#line 5647 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6425, 0},
+#line 712 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6426, 0},
+#line 4679 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6427, 0},
+#line 744 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6428, 0},
+#line 4594 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6429, 0},
+#line 711 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6430, 0},
+#line 4596 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6431, 0},
+#line 4589 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6432, 0},
+#line 4728 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6433, 0},
+#line 714 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6434, 0},
+#line 4726 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6435, 0},
+#line 4641 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6436, 0},
+#line 3695 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6437, 0},
+#line 713 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6438, 0},
+#line 5469 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6439, 0},
+#line 6190 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6440, 0},
+#line 4677 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6441, 0},
+#line 4680 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6442, 0},
+#line 4694 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6443, 0},
+#line 3742 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6444, 0},
+#line 2878 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6445, 0},
+#line 4231 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6446, 0},
+#line 3338 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6447, 0},
+#line 5628 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6448, 0},
+#line 5427 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6449, 0},
+#line 4232 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6450, 0},
+#line 4631 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6451, 0},
+#line 4697 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6452, 0},
+#line 4583 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6453, 0},
+#line 6203 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6454, 0},
+#line 6206 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6455, 0},
+#line 4607 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6456, 0},
+#line 4924 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6457, 0},
+#line 6167 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6458, 0},
+#line 4595 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6459, 0},
+#line 4592 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6460, 0},
+#line 4655 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6461, 0},
+#line 749 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6462, 0},
+#line 4564 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6463, 0},
+#line 4734 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6464, 0},
+#line 4685 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6465, 0},
+#line 4736 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6466, 0},
+#line 4751 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6467, 0},
+#line 6240 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6468, 0},
+#line 750 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6469, 0},
+#line 4624 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6470, 0},
+#line 6217 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6471, 0},
+#line 4653 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6472, 0},
+#line 5094 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6473, 4},
+#line 751 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6474, 0},
+#line 70 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6475, 0},
+#line 4745 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6476, 0},
+#line 5625 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6477, 0},
+#line 5893 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6478, 4},
+#line 4930 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6479, 0},
+#line 6218 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6480, 0},
+#line 1584 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6481, 4},
+#line 4646 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6482, 0},
+#line 752 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6483, 0},
+#line 1582 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6484, 4},
+#line 3301 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6485, 0},
+#line 6395 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6486, 0},
+#line 5538 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6487, 0},
+#line 6223 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6488, 0},
+#line 6357 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6489, 0},
+#line 6375 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6490, 0},
+#line 6301 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6491, 0},
+#line 5559 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6492, 0},
+#line 6332 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6493, 0},
+#line 3183 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6494, 0},
+#line 5634 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6495, 0},
+#line 1430 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6496, 0},
+#line 4611 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6497, 0},
+#line 3309 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6498, 0},
+#line 5713 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6499, 4},
+#line 6318 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6500, 0},
+#line 5650 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6501, 0},
+#line 4637 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6502, 0},
+#line 4658 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6503, 4},
+#line 5775 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6504, 0},
+#line 5505 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6505, 0},
+#line 4647 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6506, 0},
+#line 5599 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6507, 0},
+#line 738 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6508, 0},
+#line 739 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6509, 0},
+#line 4280 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6510, 0},
+#line 5722 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6511, 0},
+#line 6242 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6512, 0},
+#line 4542 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6513, 4},
+#line 5717 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6514, 0},
+#line 6214 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6515, 0},
+#line 4735 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6516, 0},
+#line 4587 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6517, 0},
+#line 4703 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6518, 0},
+#line 4675 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6519, 0},
+#line 4235 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6520, 4},
+#line 6239 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6521, 0},
+#line 1412 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6522, 4},
+#line 4659 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6523, 4},
+#line 4615 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6524, 0},
+#line 5682 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6525, 0},
+#line 4614 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6526, 0},
+#line 6390 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6527, 0},
+#line 1248 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6528, 4},
+#line 4654 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6529, 0},
+#line 4563 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6530, 0},
+#line 2023 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6531, 0},
+#line 5596 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6532, 0},
+#line 4566 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6533, 0},
+#line 4744 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6534, 0},
+#line 741 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6535, 0},
+#line 705 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6536, 0},
+#line 3284 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6537, 0},
+#line 6344 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6538, 0},
+#line 229 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6539, 4},
+#line 5521 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6540, 0},
+#line 727 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6541, 0},
+#line 1466 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6542, 4},
+#line 1583 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6543, 4},
+#line 2048 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6544, 0},
+#line 6213 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6545, 0},
+#line 746 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6546, 0},
+#line 748 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6547, 0},
+#line 747 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6548, 0},
+#line 4597 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6549, 0},
+#line 4590 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6550, 0},
+#line 228 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6551, 4},
+#line 6387 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6552, 0},
+#line 4645 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6553, 0},
+#line 6356 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6554, 0},
+#line 4970 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6555, 0},
+#line 5547 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6556, 0},
+#line 4299 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6557, 0},
+#line 126 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6558, 0},
+#line 6300 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6559, 0},
+#line 4591 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6560, 0},
+#line 4613 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6561, 0},
+#line 6192 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6562, 0},
+#line 6193 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6563, 0},
+#line 2575 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6564, 4},
+#line 6194 "effective_tld_names.gperf"
+      {(int)(long)&((struct stringpool_t *)0)->stringpool_str6565, 0}
     };
 
   static const short lookup[] =
     {
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,    0,    1,    2,   -1,   -1,    3,
+         4,    5,    6,   -1,   -1,    7,    8,    9,
+        -1,   10,   -1,   -1,   11,   12,   -1,   -1,
+        -1,   -1,   13,   14,   -1,   -1,   15,   -1,
+        -1,   16,   17,   18,   -1,   -1,   19,   -1,
+        20,   21,   22,   23,   -1,   -1,   24,   -1,
+        25,   26,   27,   28,   29,   -1,   30,   31,
+        32,   -1,   -1,   -1,   33,   -1,   -1,   34,
+        -1,   35,   -1,   -1,   36,   -1,   -1,   -1,
+        37,   38,   39,   -1,   -1,   -1,   -1,   40,
+        -1,   41,   42,   43,   44,   45,   46,   47,
+        48,   49,   50,   51,   -1,   52,   53,   54,
+        -1,   -1,   -1,   -1,   55,   -1,   -1,   56,
+        -1,   -1,   57,   -1,   -1,   -1,   58,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,    0,   -1,   -1,    1,   -1,   -1,
-         2,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,    3,   -1,   -1,    4,
-        -1,   -1,    5,   -1,   -1,   -1,   -1,   -1,
-         6,   -1,   -1,    7,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,    8,   -1,   -1,   -1,
+        59,   -1,   -1,   60,   -1,   -1,   -1,   61,
+        -1,   -1,   -1,   -1,   62,   -1,   63,   -1,
+        -1,   64,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   65,   66,   -1,   -1,   -1,
+        67,   -1,   68,   -1,   -1,   -1,   -1,   69,
+        -1,   70,   71,   -1,   -1,   -1,   72,   73,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,    9,   -1,   -1,   -1,   -1,
+        -1,   74,   -1,   75,   76,   -1,   -1,   -1,
+        -1,   77,   -1,   -1,   -1,   -1,   -1,   78,
+        79,   -1,   80,   -1,   -1,   -1,   81,   -1,
+        82,   83,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   84,   85,   86,   -1,   -1,
+        -1,   -1,   87,   88,   -1,   -1,   89,   90,
+        91,   -1,   -1,   -1,   92,   -1,   93,   94,
+        -1,   95,   -1,   -1,   96,   97,   -1,   98,
+        99,  100,  101,   -1,   -1,  102,   -1,   -1,
+        -1,   -1,   -1,   -1,  103,   -1,   -1,  104,
+        -1,  105,  106,  107,  108,  109,  110,  111,
+       112,  113,  114,  115,  116,  117,   -1,  118,
+       119,  120,   -1,  121,  122,   -1,   -1,   -1,
+        -1,  123,   -1,  124,  125,  126,   -1,   -1,
+        -1,   -1,   -1,  127,   -1,   -1,   -1,  128,
+        -1,  129,  130,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  131,  132,   -1,   -1,  133,
+       134,   -1,   -1,  135,   -1,  136,  137,  138,
+        -1,   -1,   -1,  139,   -1,  140,  141,   -1,
+        -1,  142,   -1,   -1,  143,   -1,   -1,   -1,
+        -1,  144,  145,  146,  147,  148,   -1,   -1,
+        -1,   -1,  149,  150,   -1,   -1,   -1,   -1,
+        -1,   -1,  151,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  152,   -1,   -1,   -1,  153,   -1,
+       154,  155,  156,   -1,  157,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  158,  159,  160,
+        -1,  161,   -1,   -1,   -1,   -1,   -1,   -1,
+       162,   -1,  163,   -1,   -1,  164,   -1,   -1,
+       165,  166,   -1,   -1,   -1,   -1,   -1,  167,
+        -1,   -1,   -1,  168,  169,   -1,   -1,   -1,
+       170,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       171,   -1,   -1,  172,   -1,   -1,  173,   -1,
+        -1,  174,   -1,   -1,  175,  176,   -1,  177,
+        -1,   -1,   -1,  178,  179,  180,  181,   -1,
+        -1,   -1,  182,  183,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  184,   -1,   -1,   -1,   -1,
+        -1,  185,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  186,  187,  188,   -1,   -1,
+        -1,   -1,   -1,   -1,  189,  190,  191,  192,
+        -1,  193,  194,   -1,   -1,   -1,  195,  196,
+       197,  198,  199,   -1,   -1,   -1,   -1,   -1,
+        -1,  200,   -1,   -1,  201,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  202,
+        -1,  203,   -1,  204,   -1,  205,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       206,  207,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  208,   -1,   -1,  209,
+        -1,   -1,   -1,  210,   -1,   -1,   -1,   -1,
+       211,  212,  213,   -1,   -1,  214,   -1,   -1,
+        -1,  215,  216,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        10,   -1,   -1,   11,   -1,   -1,   12,   -1,
+        -1,   -1,   -1,   -1,   -1,  217,  218,  219,
+       220,  221,   -1,  222,   -1,  223,  224,   -1,
+        -1,   -1,   -1,  225,   -1,   -1,   -1,  226,
+        -1,   -1,   -1,   -1,   -1,   -1,  227,  228,
+       229,  230,   -1,   -1,   -1,   -1,   -1,  231,
+       232,   -1,  233,   -1,  234,   -1,   -1,   -1,
+        -1,  235,   -1,   -1,   -1,  236,   -1,   -1,
+        -1,   -1,  237,  238,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   13,   -1,   -1,   14,   -1,   -1,
-        15,   -1,   -1,   -1,   -1,   -1,   16,   -1,
-        -1,   -1,   -1,   -1,   17,   -1,   -1,   18,
-        -1,   -1,   19,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  239,   -1,   -1,   -1,  240,
+        -1,   -1,  241,   -1,  242,   -1,  243,  244,
+        -1,   -1,   -1,  245,  246,  247,  248,   -1,
+        -1,   -1,   -1,  249,   -1,   -1,   -1,  250,
+        -1,  251,   -1,   -1,   -1,   -1,  252,   -1,
+        -1,  253,   -1,  254,   -1,  255,   -1,   -1,
+       256,   -1,   -1,  257,   -1,  258,   -1,  259,
+        -1,  260,  261,  262,   -1,  263,  264,  265,
+        -1,   -1,  266,  267,   -1,   -1,   -1,   -1,
+        -1,  268,  269,   -1,  270,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       271,   -1,   -1,   -1,  272,  273,   -1,  274,
+        -1,   -1,   -1,   -1,   -1,  275,   -1,   -1,
+        -1,   -1,  276,   -1,  277,  278,   -1,  279,
+        -1,   -1,   -1,   -1,   -1,   -1,  280,   -1,
+       281,  282,  283,   -1,   -1,   -1,   -1,  284,
+        -1,   -1,  285,  286,   -1,  287,  288,  289,
+        -1,  290,   -1,   -1,  291,   -1,  292,   -1,
+       293,   -1,   -1,   -1,   -1,   -1,  294,  295,
+       296,  297,   -1,   -1,   -1,  298,  299,   -1,
+        -1,  300,   -1,   -1,   -1,   -1,  301,  302,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  303,   -1,   -1,   -1,  304,   -1,
+       305,   -1,   -1,  306,  307,  308,   -1,  309,
+        -1,   -1,   -1,   -1,  310,   -1,   -1,  311,
+        -1,   -1,   -1,  312,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  313,  314,   -1,   -1,
+        -1,   -1,   -1,   -1,  315,   -1,   -1,  316,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   20,   -1,   -1,   21,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   22,   -1,
-        -1,   -1,   -1,   -1,   23,   -1,   -1,   24,
-        -1,   -1,   25,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   26,   -1,   -1,   -1,   -1,   -1,   27,
-        -1,   -1,   28,   -1,   29,   30,   -1,   -1,
-        31,   -1,   -1,   32,   -1,   -1,   33,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   34,
-        -1,   -1,   35,   -1,   -1,   36,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   37,   -1,   -1,   -1,
-        -1,   -1,   38,   -1,   -1,   39,   -1,   -1,
-        40,   -1,   -1,   41,   -1,   -1,   42,   -1,
-        -1,   43,   -1,   -1,   44,   -1,   -1,   45,
-        -1,   -1,   -1,   -1,   -1,   46,   -1,   -1,
-        47,   -1,   -1,   48,   -1,   -1,   49,   -1,
-        -1,   50,   -1,   -1,   51,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   52,   -1,   -1,
-        53,   -1,   -1,   54,   -1,   -1,   55,   -1,
-        -1,   -1,   -1,   -1,   56,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   57,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   58,   -1,   -1,
-        59,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        60,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   61,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   62,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   63,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        64,   -1,   -1,   65,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   66,   -1,   -1,   67,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   68,   -1,   -1,   69,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        70,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   71,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        72,   -1,   -1,   73,   -1,   -1,   74,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   75,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   76,   -1,   -1,
-        77,   -1,   -1,   -1,   -1,   -1,   78,   -1,
-        -1,   -1,   -1,   -1,   79,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   80,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   81,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   82,   -1,   -1,   -1,   -1,
-        -1,   83,   -1,   -1,   84,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   85,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   86,   -1,   -1,   -1,   -1,
-        -1,   87,   -1,   -1,   88,   -1,   -1,   89,
-        -1,   -1,   90,   -1,   -1,   91,   -1,   -1,
-        -1,   -1,   -1,   92,   -1,   -1,   93,   -1,
-        -1,   94,   -1,   -1,   -1,   -1,   95,   -1,
-        -1,   -1,   -1,   -1,   -1,   96,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   97,   -1,   -1,   -1,   -1,   -1,
-        98,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   99,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  100,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       101,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  102,   -1,   -1,   -1,
-        -1,   -1,  103,   -1,   -1,  104,   -1,   -1,
-       105,   -1,   -1,   -1,   -1,   -1,  106,   -1,
-        -1,   -1,   -1,   -1,  107,   -1,   -1,   -1,
-        -1,   -1,  108,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  109,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  110,   -1,   -1,
-       111,   -1,   -1,  112,   -1,   -1,  113,   -1,
-        -1,   -1,   -1,   -1,  114,   -1,   -1,  115,
-        -1,   -1,  116,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  117,   -1,
-        -1,  118,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  119,   -1,   -1,  120,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  121,   -1,
-        -1,  122,   -1,   -1,  123,   -1,   -1,  124,
-        -1,   -1,   -1,   -1,   -1,  125,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  126,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  127,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  128,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  129,   -1,   -1,   -1,   -1,   -1,  130,
-        -1,   -1,  131,   -1,   -1,  132,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  133,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  134,   -1,   -1,  135,   -1,   -1,
-       136,   -1,   -1,   -1,   -1,   -1,  137,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  138,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       139,   -1,   -1,   -1,   -1,   -1,  140,   -1,
-        -1,  141,   -1,   -1,  142,   -1,   -1,  143,
-        -1,   -1,  144,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  145,   -1,   -1,   -1,   -1,   -1,  146,
-        -1,   -1,   -1,   -1,   -1,  147,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  148,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       149,   -1,   -1,  150,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       151,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  152,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  153,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  154,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  155,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  156,   -1,   -1,
-       157,   -1,   -1,  158,   -1,   -1,  159,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  160,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  161,   -1,
-        -1,  162,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  163,   -1,   -1,   -1,   -1,   -1,
-       164,   -1,   -1,   -1,   -1,  165,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  166,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  167,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  168,
-        -1,   -1,  169,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  170,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  171,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  172,   -1,  173,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  174,   -1,   -1,   -1,   -1,
-        -1,  175,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  176,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  177,   -1,   -1,  178,   -1,   -1,
-        -1,  179,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  180,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  181,  182,   -1,   -1,
-       183,   -1,   -1,  184,   -1,   -1,  185,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  186,
-        -1,   -1,  187,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  188,   -1,   -1,  189,   -1,
-        -1,  190,   -1,   -1,  191,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  192,
-        -1,   -1,   -1,  193,   -1,  194,  195,   -1,
-        -1,  196,   -1,   -1,  197,   -1,   -1,   -1,
-        -1,   -1,  198,   -1,   -1,   -1,   -1,   -1,
-       199,   -1,  200,   -1,   -1,   -1,   -1,   -1,
-       201,  202,   -1,   -1,  203,   -1,   -1,  204,
-        -1,   -1,  205,   -1,   -1,  206,   -1,   -1,
-       207,   -1,   -1,  208,   -1,  209,  210,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  211,   -1,   -1,  212,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  213,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  214,   -1,   -1,   -1,
-        -1,   -1,   -1,  215,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  216,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       217,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  218,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  219,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  220,
-        -1,   -1,   -1,   -1,   -1,  221,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       222,   -1,   -1,   -1,   -1,   -1,  223,  224,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       225,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  226,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  227,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  228,   -1,
-        -1,  229,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  230,   -1,   -1,   -1,   -1,   -1,   -1,
-       231,   -1,   -1,  232,   -1,  233,  234,   -1,
-        -1,  235,   -1,   -1,  236,   -1,   -1,  237,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       238,   -1,   -1,  239,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  240,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  241,   -1,
-        -1,   -1,   -1,  242,   -1,   -1,   -1,   -1,
-        -1,   -1,  243,   -1,   -1,   -1,   -1,   -1,
-       244,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  245,
-        -1,   -1,  246,   -1,   -1,  247,   -1,   -1,
-       248,   -1,   -1,   -1,   -1,   -1,  249,   -1,
-        -1,   -1,   -1,   -1,  250,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  251,   -1,   -1,
-       252,  253,   -1,   -1,   -1,   -1,  254,   -1,
-        -1,   -1,   -1,   -1,  255,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  256,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  257,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  258,   -1,   -1,  259,  260,   -1,   -1,
-        -1,   -1,  261,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  262,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       263,   -1,  264,  265,   -1,   -1,  266,   -1,
-        -1,  267,   -1,   -1,  268,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       269,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  270,
-        -1,   -1,  271,   -1,   -1,  272,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  273,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  274,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  275,   -1,
-        -1,   -1,   -1,   -1,  276,   -1,   -1,   -1,
-        -1,   -1,  277,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  278,  279,   -1,
-        -1,   -1,   -1,  280,   -1,   -1,  281,   -1,
-        -1,   -1,   -1,   -1,   -1,  282,   -1,   -1,
-       283,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  284,   -1,  285,  286,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  287,
-        -1,   -1,   -1,   -1,   -1,   -1,  288,  289,
-        -1,  290,   -1,   -1,  291,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  292,   -1,
-        -1,   -1,   -1,  293,   -1,   -1,   -1,   -1,
-        -1,   -1,  294,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  295,   -1,
-        -1,  296,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  297,  298,   -1,   -1,
-       299,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  300,   -1,  301,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       302,   -1,   -1,   -1,   -1,   -1,  303,   -1,
-        -1,  304,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  305,  306,   -1,   -1,   -1,   -1,   -1,
-       307,   -1,   -1,   -1,   -1,  308,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  309,   -1,   -1,   -1,
-       310,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  311,   -1,  312,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       313,   -1,   -1,  314,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  315,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       316,   -1,   -1,  317,   -1,   -1,  318,   -1,
-        -1,  319,   -1,   -1,  320,   -1,   -1,   -1,
-        -1,   -1,  321,   -1,   -1,   -1,   -1,  322,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  323,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  324,   -1,
-        -1,   -1,   -1,   -1,  325,   -1,   -1,  326,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  327,  328,
-        -1,   -1,  329,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  330,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  331,   -1,   -1,   -1,   -1,
-        -1,   -1,  332,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  333,   -1,   -1,   -1,   -1,  334,   -1,
-        -1,   -1,   -1,   -1,   -1,  335,   -1,   -1,
-       336,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       337,   -1,   -1,   -1,  338,   -1,   -1,   -1,
-        -1,  339,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  340,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  341,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  342,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  343,   -1,   -1,  344,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  345,   -1,   -1,  346,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  347,  348,   -1,  349,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  350,   -1,   -1,   -1,  351,   -1,
-        -1,  352,   -1,   -1,  353,   -1,   -1,   -1,
-        -1,   -1,  354,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  355,   -1,   -1,   -1,   -1,
-       356,  357,   -1,  358,   -1,   -1,   -1,  359,
-        -1,   -1,  360,   -1,   -1,   -1,   -1,   -1,
-       361,   -1,  362,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  363,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  364,   -1,
-        -1,   -1,   -1,   -1,  365,   -1,   -1,   -1,
-        -1,   -1,  366,   -1,  367,   -1,   -1,   -1,
-       368,   -1,  369,   -1,   -1,   -1,   -1,   -1,
-       370,   -1,   -1,   -1,  371,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  372,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  373,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  374,   -1,   -1,  375,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       376,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  377,   -1,   -1,  378,   -1,   -1,   -1,
-        -1,   -1,  379,   -1,   -1,   -1,   -1,   -1,
-       380,   -1,   -1,  381,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  382,   -1,  383,   -1,
-        -1,   -1,  384,   -1,   -1,   -1,   -1,   -1,
-       385,   -1,   -1,   -1,   -1,  386,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  387,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  317,   -1,  318,
+        -1,   -1,   -1,  319,   -1,   -1,   -1,  320,
+        -1,   -1,  321,  322,  323,   -1,   -1,   -1,
+       324,  325,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  326,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  327,   -1,  328,   -1,   -1,
+       329,   -1,   -1,  330,   -1,   -1,   -1,  331,
+        -1,   -1,  332,   -1,  333,   -1,  334,   -1,
+       335,   -1,   -1,   -1,   -1,   -1,  336,   -1,
+        -1,   -1,  337,  338,   -1,   -1,   -1,   -1,
+        -1,   -1,  339,   -1,   -1,  340,   -1,   -1,
+       341,  342,   -1,   -1,  343,   -1,  344,   -1,
+        -1,   -1,   -1,  345,   -1,  346,   -1,   -1,
+        -1,  347,  348,   -1,   -1,   -1,   -1,   -1,
+       349,   -1,   -1,   -1,  350,   -1,   -1,  351,
+        -1,   -1,   -1,  352,   -1,  353,  354,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  355,
+       356,  357,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  358,  359,   -1,  360,   -1,   -1,
+        -1,  361,  362,  363,  364,   -1,   -1,  365,
+       366,   -1,  367,  368,  369,  370,  371,   -1,
+        -1,  372,  373,  374,   -1,  375,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  376,   -1,   -1,
+        -1,   -1,   -1,  377,  378,   -1,   -1,   -1,
+        -1,  379,   -1,   -1,   -1,   -1,   -1,  380,
+        -1,   -1,   -1,  381,   -1,  382,   -1,  383,
+       384,   -1,   -1,   -1,   -1,   -1,  385,   -1,
+        -1,   -1,  386,   -1,   -1,  387,   -1,   -1,
         -1,   -1,   -1,  388,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  389,   -1,   -1,   -1,   -1,
-        -1,   -1,  390,   -1,   -1,   -1,   -1,   -1,
+       389,   -1,   -1,   -1,   -1,  390,   -1,   -1,
+        -1,  391,   -1,   -1,   -1,  392,   -1,  393,
+        -1,   -1,  394,  395,   -1,   -1,   -1,   -1,
+        -1,  396,   -1,   -1,   -1,  397,   -1,   -1,
+        -1,  398,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  399,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  400,  401,   -1,   -1,   -1,
+       402,   -1,   -1,   -1,   -1,   -1,  403,  404,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  391,
-        -1,   -1,  392,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  393,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  394,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  395,  396,   -1,
-        -1,  397,   -1,   -1,  398,   -1,  399,   -1,
-        -1,   -1,   -1,   -1,   -1,  400,   -1,   -1,
-       401,   -1,   -1,   -1,   -1,   -1,  402,   -1,
-        -1,   -1,   -1,   -1,  403,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  404,   -1,   -1,
-        -1,  405,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  406,   -1,  407,   -1,   -1,   -1,
-        -1,   -1,   -1,  408,   -1,   -1,   -1,   -1,
-        -1,  409,   -1,   -1,   -1,   -1,   -1,  410,
-        -1,   -1,  411,   -1,   -1,   -1,   -1,   -1,
-       412,   -1,   -1,  413,   -1,   -1,  414,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  415,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  416,   -1,   -1,  417,   -1,
-       418,   -1,   -1,   -1,   -1,   -1,   -1,  419,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  420,  421,   -1,   -1,  422,
-        -1,   -1,  423,  424,   -1,  425,   -1,   -1,
-       426,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  427,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       428,   -1,  429,   -1,   -1,   -1,  430,   -1,
-        -1,   -1,   -1,   -1,  431,   -1,   -1,   -1,
-        -1,   -1,   -1,  432,   -1,   -1,   -1,   -1,
-       433,   -1,  434,   -1,   -1,   -1,  435,   -1,
-       436,   -1,   -1,   -1,  437,   -1,   -1,  438,
-        -1,   -1,  439,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  440,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  441,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  442,   -1,   -1,  443,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       444,  445,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  446,
-       447,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  448,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  449,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  450,  451,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  452,   -1,   -1,  453,   -1,   -1,
-       454,   -1,   -1,  455,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  456,   -1,   -1,
-        -1,  457,   -1,   -1,  458,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  459,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  405,  406,
+       407,  408,  409,  410,  411,  412,  413,  414,
+       415,  416,  417,  418,  419,  420,  421,   -1,
+        -1,  422,   -1,   -1,  423,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  424,   -1,
+        -1,   -1,   -1,  425,  426,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  427,  428,   -1,
+        -1,   -1,   -1,   -1,   -1,  429,  430,   -1,
+        -1,   -1,  431,   -1,  432,   -1,   -1,  433,
+        -1,   -1,  434,  435,   -1,  436,   -1,   -1,
+        -1,   -1,  437,   -1,  438,  439,  440,  441,
+       442,  443,   -1,  444,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  445,   -1,   -1,  446,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  447,
+       448,  449,   -1,   -1,   -1,  450,   -1,   -1,
+        -1,   -1,  451,   -1,   -1,   -1,  452,   -1,
+        -1,   -1,   -1,   -1,  453,  454,  455,   -1,
+        -1,   -1,   -1,  456,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  457,  458,   -1,
+       459,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,  460,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  461,   -1,   -1,
+        -1,   -1,   -1,   -1,  462,   -1,  463,   -1,
+        -1,  464,   -1,  465,  466,   -1,   -1,   -1,
+       467,   -1,   -1,   -1,   -1,   -1,  468,  469,
+       470,   -1,   -1,   -1,   -1,  471,   -1,  472,
+       473,   -1,   -1,   -1,  474,   -1,   -1,   -1,
+        -1,  475,   -1,   -1,   -1,  476,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  461,   -1,   -1,  462,   -1,   -1,   -1,
-        -1,   -1,  463,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  477,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  478,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  479,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  464,  465,   -1,   -1,  466,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  467,   -1,   -1,  468,   -1,
+        -1,   -1,   -1,   -1,  480,   -1,   -1,   -1,
+       481,  482,  483,   -1,   -1,  484,   -1,  485,
+        -1,   -1,   -1,   -1,  486,  487,   -1,   -1,
+       488,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  489,   -1,   -1,
+        -1,   -1,  490,   -1,  491,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  469,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  470,  471,   -1,   -1,   -1,   -1,
+        -1,  492,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  493,  494,   -1,   -1,   -1,  495,   -1,
+        -1,   -1,  496,   -1,   -1,   -1,   -1,  497,
+        -1,   -1,  498,   -1,   -1,   -1,  499,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  472,   -1,   -1,
-        -1,   -1,   -1,  473,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  500,   -1,   -1,
+       501,  502,   -1,  503,   -1,   -1,   -1,  504,
+        -1,   -1,   -1,  505,   -1,   -1,   -1,   -1,
+        -1,  506,   -1,   -1,   -1,  507,  508,   -1,
+        -1,  509,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  510,   -1,
+        -1,  511,  512,  513,  514,   -1,  515,   -1,
+        -1,   -1,  516,   -1,   -1,   -1,   -1,   -1,
+        -1,  517,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  474,  475,   -1,   -1,
-       476,   -1,   -1,  477,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  478,   -1,   -1,
-       479,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  518,  519,   -1,   -1,   -1,   -1,
+       520,   -1,   -1,   -1,  521,  522,   -1,   -1,
+       523,   -1,  524,   -1,   -1,   -1,   -1,  525,
+       526,   -1,   -1,   -1,   -1,   -1,  527,  528,
+        -1,   -1,   -1,   -1,  529,  530,   -1,   -1,
+        -1,   -1,   -1,  531,   -1,   -1,   -1,   -1,
+        -1,  532,   -1,  533,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  534,   -1,   -1,   -1,  535,
+        -1,   -1,   -1,  536,   -1,   -1,  537,   -1,
+        -1,  538,  539,   -1,   -1,  540,  541,   -1,
+        -1,   -1,   -1,  542,   -1,   -1,   -1,   -1,
+        -1,   -1,  543,   -1,   -1,   -1,  544,  545,
+        -1,   -1,  546,   -1,   -1,   -1,   -1,  547,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  480,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  481,   -1,
-        -1,  482,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  483,
-        -1,   -1,   -1,   -1,   -1,   -1,  484,   -1,
-        -1,  485,   -1,   -1,  486,   -1,   -1,  487,
-        -1,   -1,   -1,   -1,   -1,  488,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  548,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  489,   -1,   -1,  490,
+        -1,   -1,   -1,   -1,   -1,  549,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  550,  551,   -1,
+        -1,   -1,  552,  553,  554,  555,   -1,   -1,
+        -1,  556,  557,  558,   -1,   -1,   -1,   -1,
+        -1,   -1,  559,   -1,  560,   -1,   -1,   -1,
+        -1,   -1,  561,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  562,  563,   -1,   -1,  564,   -1,
+       565,   -1,   -1,   -1,  566,  567,   -1,   -1,
+       568,   -1,   -1,   -1,   -1,   -1,  569,   -1,
+        -1,   -1,  570,   -1,   -1,   -1,   -1,   -1,
+       571,   -1,   -1,  572,  573,   -1,   -1,   -1,
+       574,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  575,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  576,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  577,   -1,   -1,
+        -1,   -1,   -1,   -1,  578,   -1,   -1,   -1,
+        -1,   -1,  579,   -1,   -1,   -1,   -1,   -1,
+        -1,  580,   -1,   -1,   -1,   -1,  581,   -1,
+        -1,   -1,  582,   -1,   -1,   -1,  583,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  491,   -1,   -1,
-        -1,   -1,  492,   -1,   -1,   -1,   -1,   -1,
+       584,   -1,   -1,   -1,  585,   -1,  586,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  493,   -1,   -1,   -1,
-        -1,   -1,  494,   -1,   -1,  495,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  587,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  588,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  589,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  496,   -1,   -1,
-       497,   -1,   -1,   -1,   -1,   -1,   -1,  498,
-        -1,  499,   -1,  500,   -1,   -1,   -1,  501,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  590,  591,  592,  593,  594,   -1,
+        -1,  595,   -1,   -1,   -1,   -1,  596,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  502,   -1,
-        -1,   -1,  503,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  504,   -1,   -1,   -1,   -1,
-        -1,  505,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  506,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       507,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  508,
-        -1,   -1,   -1,   -1,   -1,  509,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  510,   -1,   -1,   -1,   -1,
-        -1,   -1,  511,   -1,   -1,  512,   -1,   -1,
-        -1,   -1,   -1,   -1,  513,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  514,   -1,   -1,   -1,
-       515,   -1,   -1,  516,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  517,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  518,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  519,   -1,   -1,   -1,   -1,   -1,
-       520,   -1,   -1,   -1,   -1,  521,  522,   -1,
-        -1,  523,   -1,   -1,  524,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  525,   -1,   -1,   -1,   -1,
-        -1,  526,   -1,   -1,  527,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  528,   -1,   -1,
-        -1,   -1,   -1,  529,   -1,   -1,  530,   -1,
-        -1,  531,   -1,   -1,  532,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  533,   -1,   -1,  534,  535,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  536,   -1,   -1,   -1,
-        -1,   -1,  537,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  538,   -1,
-        -1,   -1,   -1,  539,   -1,   -1,   -1,   -1,
-        -1,   -1,  540,   -1,   -1,  541,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  542,   -1,
-        -1,  543,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  544,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  545,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  546,   -1,   -1,   -1,   -1,   -1,   -1,
-       547,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  548,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  549,  550,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  551,  552,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  553,  554,
-        -1,   -1,  555,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  556,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  557,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       558,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  559,   -1,   -1,   -1,  560,   -1,  561,
-        -1,   -1,  562,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  563,   -1,   -1,  564,   -1,
-       565,   -1,   -1,   -1,   -1,   -1,   -1,  566,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  567,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  568,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  569,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  570,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  571,   -1,   -1,
-       572,   -1,  573,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  574,   -1,   -1,  575,
-        -1,  576,  577,   -1,   -1,  578,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  579,   -1,   -1,   -1,   -1,   -1,  580,
-        -1,   -1,  581,   -1,   -1,  582,   -1,   -1,
-        -1,   -1,   -1,  583,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  584,   -1,   -1,   -1,  585,
-        -1,   -1,  586,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  587,   -1,   -1,  588,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  589,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  590,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  591,   -1,   -1,   -1,   -1,
-        -1,  592,   -1,   -1,  593,   -1,   -1,  594,
-        -1,   -1,  595,   -1,   -1,  596,   -1,   -1,
-        -1,   -1,   -1,  597,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  598,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  599,   -1,   -1,  600,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  601,  602,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  603,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  604,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  605,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  606,   -1,   -1,   -1,   -1,   -1,
-       607,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  608,  609,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  610,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  611,   -1,   -1,   -1,   -1,
-       612,   -1,   -1,  613,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  614,   -1,   -1,  615,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  616,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  617,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  618,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  619,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  620,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  621,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  622,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  623,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       624,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  597,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  598,   -1,   -1,   -1,  599,   -1,
+        -1,   -1,   -1,  600,  601,   -1,   -1,   -1,
+       602,   -1,  603,   -1,  604,  605,   -1,   -1,
+       606,  607,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  608,   -1,   -1,   -1,   -1,   -1,  609,
+        -1,   -1,   -1,  610,   -1,   -1,   -1,   -1,
+        -1,  611,   -1,   -1,   -1,  612,   -1,   -1,
+        -1,   -1,  613,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  614,   -1,   -1,   -1,   -1,
+        -1,   -1,  615,   -1,  616,   -1,   -1,   -1,
+        -1,   -1,   -1,  617,   -1,   -1,  618,   -1,
+        -1,   -1,   -1,   -1,   -1,  619,  620,  621,
+       622,  623,  624,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,  625,   -1,   -1,   -1,
+        -1,   -1,  626,  627,  628,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  629,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  626,  627,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  628,  629,
-        -1,   -1,   -1,   -1,   -1,  630,   -1,   -1,
-        -1,   -1,   -1,  631,   -1,   -1,   -1,   -1,
-       632,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  630,   -1,   -1,   -1,   -1,  631,   -1,
+        -1,   -1,   -1,  632,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,  633,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  634,   -1,  635,  636,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  634,   -1,   -1,   -1,   -1,   -1,
-        -1,  635,   -1,   -1,   -1,   -1,  636,  637,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  638,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  639,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  637,   -1,  638,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  639,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,  640,
-        -1,   -1,   -1,   -1,   -1,  641,   -1,   -1,
+       641,   -1,   -1,   -1,   -1,   -1,  642,   -1,
+       643,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  642,   -1,  643,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       644,   -1,   -1,  645,   -1,   -1,   -1,   -1,
-        -1,  646,   -1,   -1,   -1,   -1,   -1,  647,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  648,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  649,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       650,   -1,   -1,   -1,   -1,   -1,  651,   -1,
-       652,   -1,   -1,   -1,   -1,   -1,   -1,  653,
-        -1,   -1,   -1,   -1,  654,  655,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       656,   -1,   -1,   -1,   -1,   -1,   -1,  657,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  658,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  644,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  645,  646,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  647,  648,   -1,   -1,  649,  650,   -1,
+        -1,  651,  652,  653,   -1,   -1,   -1,  654,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  655,
+        -1,   -1,   -1,  656,   -1,   -1,   -1,   -1,
+        -1,   -1,  657,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  658,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       659,   -1,  660,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  661,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  662,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  663,   -1,   -1,   -1,   -1,
-        -1,   -1,  664,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  659,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  660,
+        -1,   -1,   -1,   -1,   -1,   -1,  661,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  665,   -1,   -1,   -1,
+       662,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  663,   -1,   -1,  664,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  665,   -1,  666,   -1,   -1,   -1,
+        -1,   -1,  667,   -1,   -1,   -1,  668,   -1,
+        -1,   -1,   -1,  669,   -1,   -1,   -1,   -1,
+       670,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  671,   -1,   -1,  672,   -1,   -1,   -1,
+        -1,  673,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  674,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  675,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       666,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  667,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  668,   -1,   -1,  669,   -1,   -1,
+       676,   -1,   -1,  677,   -1,   -1,   -1,   -1,
+       678,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  679,   -1,   -1,   -1,   -1,  680,
+        -1,  681,   -1,   -1,  682,   -1,   -1,   -1,
+       683,   -1,   -1,   -1,  684,   -1,  685,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  686,   -1,  687,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  670,
-        -1,   -1,   -1,   -1,   -1,  671,   -1,   -1,
-        -1,   -1,  672,  673,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  674,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  675,   -1,
-        -1,  676,   -1,  677,   -1,   -1,   -1,   -1,
-        -1,   -1,  678,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  679,   -1,   -1,  680,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  681,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  682,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  683,   -1,   -1,  684,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  685,   -1,   -1,  686,   -1,   -1,   -1,
-       687,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,  688,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,  689,   -1,   -1,   -1,
+        -1,  690,   -1,   -1,   -1,   -1,   -1,   -1,
+       691,   -1,  692,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  690,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  691,   -1,   -1,
-       692,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  693,   -1,   -1,   -1,
-       694,   -1,   -1,   -1,   -1,   -1,  695,   -1,
-        -1,   -1,   -1,  696,   -1,   -1,   -1,   -1,
-        -1,   -1,  697,   -1,   -1,   -1,   -1,  698,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  699,   -1,   -1,   -1,
-       700,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       701,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  693,   -1,   -1,
+        -1,   -1,   -1,   -1,  694,   -1,   -1,   -1,
+        -1,  695,   -1,   -1,   -1,   -1,   -1,  696,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  697,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  698,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  699,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  702,   -1,   -1,   -1,  703,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  700,   -1,   -1,   -1,   -1,   -1,
+        -1,  701,   -1,  702,   -1,   -1,  703,   -1,
         -1,   -1,   -1,   -1,   -1,  704,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  705,
-        -1,   -1,   -1,   -1,   -1,  706,   -1,   -1,
+        -1,  705,   -1,   -1,   -1,   -1,  706,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  707,   -1,   -1,  708,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       709,   -1,   -1,   -1,   -1,   -1,  710,   -1,
+       707,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  708,   -1,
+        -1,   -1,  709,   -1,   -1,  710,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  711,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  712,
-        -1,   -1,  713,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  714,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  715,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  716,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  711,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  717,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  718,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  719,
-       720,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  721,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  722,
+       712,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       713,  714,  715,  716,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  717,
+        -1,  718,   -1,   -1,   -1,   -1,  719,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  720,   -1,
+        -1,   -1,   -1,   -1,  721,   -1,   -1,   -1,
+        -1,   -1,  722,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,  723,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  724,   -1,   -1,
+        -1,   -1,   -1,  724,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  725,   -1,   -1,   -1,
+        -1,   -1,  726,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  725,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  726,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  727,   -1,   -1,  728,
+        -1,   -1,   -1,   -1,   -1,  727,   -1,   -1,
+        -1,   -1,  728,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,  729,   -1,
-       730,   -1,   -1,  731,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  732,   -1,   -1,   -1,
-        -1,   -1,  733,   -1,   -1,  734,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  735,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  736,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  737,   -1,   -1,   -1,   -1,   -1,
-       738,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  739,   -1,   -1,
-        -1,   -1,   -1,  740,   -1,   -1,  741,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       742,   -1,  743,   -1,   -1,  744,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  745,
-        -1,   -1,   -1,  746,   -1,   -1,   -1,   -1,
-        -1,  747,   -1,   -1,   -1,   -1,  748,  749,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  750,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  730,  731,  732,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  751,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  752,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  753,   -1,
-        -1,   -1,   -1,  754,   -1,   -1,  755,   -1,
-        -1,   -1,   -1,   -1,  756,   -1,   -1,   -1,
+        -1,  733,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  734,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  735,  736,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  757,   -1,   -1,   -1,   -1,   -1,
-        -1,  758,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  759,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  737,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  738,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  739,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  740,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       741,   -1,   -1,   -1,  742,  743,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  744,   -1,   -1,   -1,
+       745,   -1,  746,  747,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  748,
+        -1,   -1,   -1,  749,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  750,  751,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       752,  753,   -1,   -1,   -1,   -1,   -1,   -1,
+       754,   -1,  755,   -1,   -1,   -1,   -1,   -1,
+        -1,  756,   -1,  757,   -1,   -1,   -1,  758,
+       759,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,  760,   -1,   -1,
-        -1,  761,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  762,   -1,   -1,  763,
-       764,   -1,   -1,  765,   -1,   -1,   -1,   -1,
-        -1,  766,   -1,   -1,   -1,   -1,   -1,  767,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  761,  762,
+        -1,   -1,   -1,   -1,   -1,  763,   -1,   -1,
+        -1,  764,   -1,   -1,   -1,  765,   -1,   -1,
+        -1,   -1,  766,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  767,   -1,
+        -1,   -1,   -1,   -1,   -1,  768,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  768,   -1,   -1,  769,   -1,   -1,   -1,
-        -1,  770,   -1,   -1,   -1,  771,   -1,  772,
-       773,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  774,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       775,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  776,   -1,  777,  778,   -1,   -1,  779,
-        -1,   -1,  780,   -1,   -1,   -1,   -1,   -1,
-       781,   -1,   -1,   -1,  782,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  783,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       784,   -1,   -1,  785,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  786,
-        -1,   -1,   -1,  787,   -1,   -1,   -1,  788,
-       789,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  790,
+        -1,   -1,   -1,  769,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  791,   -1,   -1,  792,
-        -1,   -1,  793,   -1,   -1,   -1,  794,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  795,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  796,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  770,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  771,   -1,   -1,
+        -1,   -1,  772,   -1,   -1,   -1,   -1,   -1,
+        -1,  773,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  774,   -1,   -1,   -1,   -1,
+        -1,   -1,  775,  776,   -1,  777,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       778,   -1,   -1,   -1,   -1,   -1,  779,   -1,
+        -1,   -1,   -1,  780,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  781,   -1,   -1,   -1,
+       782,   -1,   -1,   -1,   -1,   -1,  783,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       784,   -1,   -1,  785,  786,   -1,  787,   -1,
+        -1,   -1,   -1,   -1,   -1,  788,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  789,   -1,   -1,
+        -1,   -1,   -1,   -1,  790,  791,   -1,   -1,
+        -1,   -1,   -1,   -1,  792,  793,   -1,   -1,
+       794,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       795,  796,   -1,   -1,  797,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  797,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,  798,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  799,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  800,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  801,   -1,   -1,   -1,
-        -1,  802,   -1,   -1,   -1,  803,   -1,   -1,
-        -1,   -1,  804,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  799,   -1,   -1,
+        -1,   -1,  800,   -1,  801,   -1,   -1,   -1,
+        -1,   -1,  802,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       803,  804,  805,   -1,   -1,  806,   -1,   -1,
+        -1,   -1,   -1,  807,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  808,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  809,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  810,   -1,   -1,   -1,
+        -1,   -1,   -1,  811,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       805,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  812,   -1,   -1,   -1,
+        -1,  813,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  814,   -1,
+        -1,   -1,   -1,  815,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  806,
+        -1,   -1,   -1,  816,  817,   -1,  818,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  819,  820,   -1,   -1,   -1,   -1,   -1,
+        -1,  821,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  822,  823,   -1,   -1,  824,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  807,  808,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       809,   -1,   -1,   -1,   -1,   -1,   -1,  810,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  811,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  812,   -1,   -1,   -1,  813,   -1,
-        -1,  814,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  815,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  816,  817,   -1,   -1,
-        -1,   -1,  818,   -1,   -1,   -1,   -1,   -1,
-       819,   -1,   -1,   -1,   -1,   -1,  820,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       821,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  822,  823,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  824,   -1,
         -1,   -1,   -1,  825,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  826,   -1,   -1,
-        -1,   -1,   -1,  827,   -1,   -1,   -1,   -1,
+        -1,   -1,  826,   -1,   -1,  827,   -1,   -1,
+       828,   -1,  829,   -1,  830,   -1,   -1,  831,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  832,   -1,   -1,   -1,  833,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  828,   -1,   -1,   -1,  829,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  834,   -1,   -1,   -1,
+        -1,   -1,   -1,  835,   -1,   -1,   -1,   -1,
+        -1,  836,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  837,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  838,   -1,   -1,
+        -1,   -1,   -1,  839,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  840,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  841,   -1,  842,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  830,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  831,
-        -1,  832,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  833,  834,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  835,   -1,   -1,  836,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  843,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  837,   -1,   -1,   -1,  838,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  839,
-        -1,   -1,  840,   -1,   -1,   -1,   -1,   -1,
-       841,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  844,   -1,   -1,   -1,  845,   -1,
+        -1,   -1,   -1,   -1,   -1,  846,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       842,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       847,   -1,  848,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  849,   -1,   -1,   -1,
+        -1,  850,   -1,   -1,   -1,  851,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       843,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  844,   -1,   -1,   -1,   -1,   -1,  845,
+        -1,  852,   -1,   -1,  853,  854,   -1,   -1,
+        -1,   -1,   -1,  855,   -1,   -1,   -1,   -1,
+        -1,   -1,  856,   -1,   -1,   -1,   -1,  857,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  858,   -1,   -1,  859,   -1,   -1,   -1,
+        -1,   -1,   -1,  860,   -1,  861,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  862,
+        -1,   -1,   -1,  863,   -1,   -1,   -1,   -1,
+        -1,   -1,  864,   -1,   -1,   -1,   -1,   -1,
+        -1,  865,   -1,   -1,   -1,  866,   -1,  867,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  868,   -1,   -1,   -1,  869,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  870,   -1,  871,
+       872,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  873,   -1,   -1,
+        -1,   -1,  874,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  875,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       876,   -1,  877,   -1,   -1,  878,  879,   -1,
+        -1,  880,  881,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  882,   -1,   -1,  883,
+        -1,   -1,   -1,  884,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  885,   -1,
+        -1,   -1,  886,   -1,  887,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  888,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  889,   -1,
+       890,   -1,   -1,   -1,   -1,   -1,  891,   -1,
+        -1,   -1,  892,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  893,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  846,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  894,  895,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  896,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  897,   -1,   -1,
+        -1,  898,   -1,  899,  900,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  901,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  902,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  903,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  904,   -1,
+        -1,   -1,   -1,  905,   -1,   -1,   -1,  906,
+        -1,   -1,  907,   -1,   -1,   -1,   -1,   -1,
+       908,   -1,   -1,   -1,   -1,   -1,  909,  910,
+        -1,   -1,   -1,  911,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  912,   -1,   -1,   -1,   -1,
+       913,   -1,   -1,   -1,   -1,  914,   -1,   -1,
+        -1,  915,   -1,   -1,   -1,   -1,   -1,  916,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  847,   -1,   -1,   -1,   -1,
+        -1,  917,   -1,   -1,   -1,   -1,   -1,  918,
+       919,   -1,  920,   -1,   -1,   -1,   -1,   -1,
+       921,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       922,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  923,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  924,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  925,  926,  927,  928,   -1,  929,
+        -1,   -1,   -1,  930,   -1,   -1,  931,  932,
+        -1,   -1,  933,  934,   -1,   -1,   -1,   -1,
+        -1,  935,   -1,   -1,   -1,   -1,   -1,  936,
+        -1,   -1,   -1,   -1,  937,  938,   -1,   -1,
+        -1,  939,  940,   -1,   -1,  941,  942,  943,
+        -1,   -1,   -1,  944,   -1,   -1,  945,  946,
+        -1,   -1,   -1,   -1,  947,   -1,  948,   -1,
+       949,   -1,   -1,   -1,  950,   -1,   -1,   -1,
+        -1,   -1,  951,   -1,  952,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  953,   -1,   -1,   -1,   -1,   -1,
+       954,  955,   -1,   -1,   -1,   -1,  956,   -1,
+        -1,   -1,  957,   -1,   -1,   -1,  958,   -1,
+        -1,   -1,   -1,   -1,  959,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  960,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  848,   -1,  849,
-       850,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  961,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  962,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  851,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  852,   -1,   -1,   -1,  853,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  963,
+       964,   -1,   -1,   -1,  965,   -1,   -1,   -1,
+        -1,  966,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  967,   -1,   -1,   -1,  968,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       854,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  855,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  856,   -1,  857,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       858,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  859,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  860,
-       861,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  862,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  863,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  864,
-        -1,  865,   -1,   -1,  866,  867,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  868,   -1,   -1,   -1,   -1,
-        -1,   -1,  869,   -1,   -1,   -1,   -1,   -1,
-       870,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  871,   -1,   -1,  872,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  873,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  874,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       875,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       876,  877,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  878,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  879,
-        -1,  880,   -1,   -1,   -1,   -1,   -1,  881,
-       882,   -1,   -1,  883,   -1,   -1,   -1,  884,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  885,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  886,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  887,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  888,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  889,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  890,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  891,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  892,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  893,  894,   -1,   -1,
-       895,   -1,   -1,  896,   -1,   -1,  897,   -1,
-        -1,  898,   -1,   -1,  899,   -1,   -1,  900,
-        -1,   -1,  901,   -1,   -1,  902,   -1,   -1,
-       903,   -1,   -1,  904,   -1,   -1,  905,   -1,
-        -1,  906,   -1,  907,  908,   -1,   -1,  909,
-        -1,   -1,  910,   -1,   -1,  911,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  912,   -1,   -1,   -1,
-        -1,   -1,   -1,  913,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  914,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  915,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  916,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  917,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  918,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  919,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       920,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  921,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  922,   -1,   -1,   -1,   -1,  923,
-        -1,   -1,   -1,   -1,   -1,   -1,  924,   -1,
-        -1,   -1,  925,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  926,  927,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  928,   -1,   -1,
-       929,  930,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       931,  932,   -1,  933,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  934,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  935,   -1,   -1,
-        -1,   -1,  936,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  937,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  938,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  939,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,  940,   -1,   -1,   -1,  941,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  942,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  943,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  944,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  945,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  946,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  947,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       948,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  949,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  950,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       951,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  952,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  953,   -1,   -1,   -1,
-        -1,   -1,   -1,  954,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  955,   -1,   -1,   -1,
-        -1,  956,   -1,   -1,  957,   -1,   -1,   -1,
-        -1,   -1,  958,   -1,   -1,  959,  960,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  961,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  962,  963,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       964,   -1,   -1,   -1,   -1,   -1,  965,   -1,
-        -1,   -1,  966,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  967,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  968,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  969,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  970,   -1,   -1,
-        -1,  971,   -1,   -1,   -1,  972,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  973,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       974,   -1,  975,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  976,
+        -1,   -1,   -1,   -1,   -1,  969,   -1,   -1,
+       970,   -1,   -1,   -1,   -1,   -1,  971,   -1,
+        -1,   -1,  972,  973,   -1,   -1,  974,   -1,
+        -1,   -1,  975,  976,   -1,  977,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  977,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,  978,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  979,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  980,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       981,   -1,   -1,   -1,  982,   -1,   -1,   -1,
+       983,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  984,   -1,
+        -1,   -1,  985,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  986,   -1,   -1,  987,
+        -1,   -1,   -1,  988,   -1,   -1,   -1,   -1,
+        -1,  989,   -1,   -1,   -1,  990,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  991,
+        -1,   -1,   -1,  992,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  993,   -1,   -1,   -1,   -1,
+       994,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,  995,  996,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+       997,  998,   -1,   -1,   -1,   -1,   -1,  999,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1000,
+        -1,   -1,   -1,   -1,   -1, 1001,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1002,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1003,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1004,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1005,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1006,   -1,   -1,   -1,
+        -1,   -1,   -1, 1007,   -1,   -1,   -1,   -1,
+        -1, 1008, 1009,   -1,   -1,   -1, 1010,   -1,
+        -1, 1011,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1012, 1013,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1014,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1015,
+      1016,   -1,   -1,   -1,   -1, 1017,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  979,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       980,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  981,
-        -1,   -1,  982,   -1,   -1,   -1,   -1,   -1,
-       983,   -1,   -1,   -1,   -1,   -1,  984,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  985,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  986,   -1,   -1,  987,   -1,
-       988,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  989,   -1,   -1,  990,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       991,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-       992,   -1,   -1,   -1,   -1,   -1,   -1,  993,
-        -1,  994,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  995,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  996,   -1,
-        -1,  997,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  998,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  999,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1000,   -1,   -1,
-        -1,   -1,   -1, 1001,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1002,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1003,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1004,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1005,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1006, 1007,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1008,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1009,   -1, 1010,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1011,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1012,
-        -1,   -1,   -1,   -1,   -1,   -1, 1013,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1014,
-        -1, 1015,   -1,   -1,   -1,   -1,   -1, 1016,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1017,
         -1,   -1, 1018,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1019,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1020,   -1,   -1,   -1,   -1,
+      1021,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1022,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1023,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1024,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1019,   -1,   -1,
+        -1,   -1,   -1, 1025,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1020, 1021,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1022,   -1,
-        -1,   -1,   -1, 1023,   -1,   -1,   -1,   -1,
+      1026,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1024,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1025,   -1,   -1,   -1,   -1,   -1, 1026,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1027,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1028,   -1,   -1,   -1,   -1,
-        -1, 1029,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1030,   -1,   -1,   -1,   -1,   -1,   -1,
-      1031,   -1,   -1,   -1,   -1, 1032,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1033,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1034,   -1,   -1,   -1, 1035,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1036,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1037,   -1,   -1,
-        -1,   -1,   -1, 1038,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1039,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1040,   -1,   -1,   -1,   -1,   -1,   -1, 1041,
-        -1, 1042,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1043, 1044,   -1,   -1,
+        -1,   -1,   -1, 1027, 1028,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1029,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1045,   -1,   -1,   -1,   -1,   -1,
-        -1, 1046,   -1, 1047, 1048,   -1,   -1,   -1,
+      1030, 1031,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1032,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1033,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1034,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1049,   -1,   -1,
+        -1,   -1,   -1, 1035,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1036,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1050,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1037,   -1, 1038,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1039,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1040, 1041,   -1,
+        -1,   -1, 1042,   -1,   -1, 1043,   -1,   -1,
+        -1,   -1,   -1,   -1, 1044,   -1,   -1, 1045,
+        -1,   -1,   -1, 1046,   -1,   -1, 1047,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1048,   -1,   -1,   -1,   -1, 1049,
+      1050,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 1051,   -1,   -1,   -1,
+        -1, 1052,   -1,   -1,   -1,   -1, 1053,   -1,
+        -1,   -1,   -1, 1054,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1052,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1055,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1056,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1057,   -1,
+      1058,   -1, 1059,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1060,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1061,   -1, 1062,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1053,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1054,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1063,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1055,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1056,   -1,   -1,   -1,   -1,
-      1057, 1058,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1059,   -1,   -1,   -1,   -1,   -1,   -1,
-      1060,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1061,   -1,   -1,   -1,
+        -1,   -1,   -1, 1064,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1065,   -1,   -1,   -1, 1066,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1062,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1063,   -1,   -1, 1064,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1065,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1066,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1067,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1068,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1069,   -1,   -1, 1070,   -1,
+        -1,   -1, 1067, 1068,   -1,   -1, 1069,   -1,
+        -1,   -1,   -1,   -1,   -1, 1070,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1071,   -1,
+        -1,   -1,   -1, 1072,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1073,   -1,   -1,   -1, 1074,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1071,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1072,
-        -1,   -1,   -1,   -1,   -1,   -1, 1073,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1074,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1075,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1076,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1075,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1076,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 1077,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1078,   -1,   -1,
-      1079,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1078,   -1, 1079, 1080,
+        -1,   -1,   -1,   -1,   -1, 1081,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1082,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1083,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1084,   -1,   -1,   -1,
+        -1, 1085, 1086,   -1,   -1,   -1,   -1,   -1,
+        -1, 1087,   -1,   -1, 1088,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1089,   -1, 1090,
+        -1,   -1,   -1,   -1,   -1,   -1, 1091,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1092, 1093,   -1,   -1,
+        -1, 1094,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1095,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1096,   -1,   -1,   -1,   -1, 1097,   -1,   -1,
+        -1,   -1,   -1,   -1, 1098,   -1, 1099,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1100, 1101,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1102,   -1,   -1,   -1,   -1,   -1, 1103, 1104,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1080,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1081,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1082,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1083,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1084,   -1,   -1, 1085,   -1,
-      1086,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1087,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1088,   -1,   -1,   -1, 1089,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1090,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1091,   -1,   -1,   -1,
-        -1,   -1,   -1, 1092,   -1,   -1,   -1,   -1,
-        -1, 1093,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1094,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1095,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1096,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1097,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1098,   -1, 1099,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1100,   -1,   -1,   -1,   -1,
-        -1,   -1, 1101,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1102,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1103,   -1, 1104,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1105,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1105,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       1106,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1107,   -1,   -1,   -1,   -1,   -1,
-        -1, 1108,   -1, 1109, 1110,   -1,   -1,   -1,
+        -1, 1107, 1108,   -1,   -1, 1109,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1110,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1111,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1112,   -1, 1113,   -1,   -1,
+        -1, 1114,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1115,   -1,   -1, 1116,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1117,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1111, 1112,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1118,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1119,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1120,   -1,   -1,
+        -1, 1121,   -1,   -1,   -1,   -1, 1122,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1123,
+        -1,   -1, 1124,   -1,   -1,   -1,   -1, 1125,
+        -1,   -1,   -1,   -1,   -1,   -1, 1126,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1127,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1128,   -1,   -1,   -1,
+        -1, 1129,   -1,   -1,   -1, 1130,   -1, 1131,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1132,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1133,   -1,
+        -1,   -1,   -1,   -1,   -1, 1134,   -1,   -1,
+        -1,   -1,   -1,   -1, 1135,   -1,   -1,   -1,
+      1136,   -1,   -1,   -1, 1137,   -1, 1138,   -1,
+        -1,   -1,   -1,   -1,   -1, 1139,   -1,   -1,
+      1140,   -1,   -1,   -1,   -1,   -1,   -1, 1141,
+        -1, 1142,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1143,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1113,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1144, 1145,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1114,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1115,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1146,   -1,   -1,   -1, 1147,   -1,   -1,
+        -1,   -1, 1148,   -1,   -1,   -1,   -1, 1149,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1116,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1150,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1151,   -1,
+        -1,   -1,   -1, 1152,   -1,   -1, 1153,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1117,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1118,   -1,
+        -1,   -1, 1154,   -1,   -1,   -1,   -1, 1155,
+        -1,   -1,   -1,   -1,   -1, 1156,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1119,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1120,   -1, 1121,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1122, 1123,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1124,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1125,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1157,   -1,   -1,   -1,   -1,
+      1158,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1126,   -1,   -1,   -1,   -1,   -1, 1127,
-        -1,   -1, 1128,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1129,   -1,   -1,   -1,   -1,
+      1159,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1160,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1161,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1162,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1130,
+        -1,   -1,   -1,   -1,   -1, 1163,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1164,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1165, 1166,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1167,
+        -1,   -1,   -1,   -1,   -1, 1168,   -1, 1169,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1170,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1171,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1172,   -1,
+        -1, 1173,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1131,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1132,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1133,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1134,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1135,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1136,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1137,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1138,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1139,   -1,   -1, 1140,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1141,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1142,   -1,   -1,   -1,   -1,   -1,
-      1143,   -1,   -1,   -1, 1144,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1145,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1146,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1147,   -1,   -1,   -1,   -1, 1148,   -1,
-        -1,   -1, 1149,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1150,   -1, 1151,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1152,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1153,
-      1154,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1155,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1156,
-      1157,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1158,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1159,   -1,   -1,
-        -1,   -1,   -1,   -1, 1160,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1161,   -1,   -1,   -1,
-      1162,   -1,   -1, 1163,   -1,   -1, 1164,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1165,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1166,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1167,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1168,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1169,   -1,   -1,
-      1170,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1171,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1172,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1173,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1174,   -1,
-        -1,   -1, 1175, 1176,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1174,   -1,   -1,   -1, 1175,   -1,   -1,   -1,
+        -1,   -1, 1176,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       1177,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 1178,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1179,   -1,   -1,   -1,   -1, 1180,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1179,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1180,   -1, 1181,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1182,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1183,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1184,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1185, 1186,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1181,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1187,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1182,   -1,   -1,   -1,   -1,   -1,   -1, 1183,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1188,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1184,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1189,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1190,   -1,   -1,   -1,
+        -1, 1185,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1186,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1187,   -1,   -1,   -1,   -1,
+      1188,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1189,   -1,   -1,   -1,
+      1190,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 1191,   -1,   -1, 1192,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1193,
-        -1,   -1,   -1,   -1,   -1,   -1, 1194,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1195,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1196,   -1,   -1,
-        -1,   -1,   -1, 1197, 1198,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1193,   -1,
+        -1,   -1, 1194,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1199, 1200,   -1,
+        -1,   -1, 1195,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1201,   -1, 1202,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1196,   -1,   -1,   -1, 1197,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1198,
+        -1,   -1, 1199,   -1,   -1, 1200,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1201,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1202,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1203,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1204,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1205,   -1,   -1,   -1,
+      1206,   -1,   -1,   -1,   -1,   -1,   -1, 1207,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1208,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1209, 1210,   -1,   -1,   -1,
+        -1, 1211,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1212,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1213,   -1,
+        -1,   -1, 1214,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1203,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1215,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1204, 1205,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1216,   -1,   -1, 1217,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1218,
+        -1, 1219,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1220,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1206,   -1,   -1,   -1,   -1,   -1,
+        -1, 1221,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1222,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1223,   -1,
+        -1,   -1,   -1,   -1, 1224,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1207,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1225,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1226,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1227,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1228,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1229,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1208,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1209, 1210, 1211,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1212,   -1,   -1,   -1,   -1,   -1, 1213,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1214,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1215,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1216,   -1,   -1,   -1, 1217, 1218,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1219,   -1,   -1,   -1,   -1,   -1, 1220,   -1,
-        -1,   -1,   -1, 1221,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1222,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1223,   -1,   -1,
-        -1,   -1,   -1, 1224,   -1,   -1,   -1, 1225,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1226,   -1,   -1,   -1,   -1,   -1, 1227,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1230,   -1,
+        -1,   -1, 1231,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1228,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1229,   -1,
-        -1, 1230,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1231,   -1,   -1,   -1,   -1,
         -1,   -1, 1232,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1233,   -1,
+        -1,   -1,   -1, 1233,   -1,   -1, 1234,   -1,
+        -1,   -1,   -1,   -1, 1235,   -1,   -1,   -1,
+        -1, 1236,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1237,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1234,
-        -1,   -1, 1235,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1238,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1236,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1237,   -1,   -1,   -1,   -1,   -1,
-        -1, 1238,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1239,   -1,   -1,   -1, 1240,   -1,
+        -1,   -1,   -1,   -1, 1241,   -1, 1242, 1243,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1239,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1240,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1241,   -1,
-        -1,   -1,   -1,   -1,   -1, 1242,   -1,   -1,
-        -1,   -1,   -1, 1243,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1244,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1245,   -1, 1246,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1247,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1244,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1245, 1246,   -1, 1247,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 1248,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1249,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1249,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1250,   -1,   -1,
+        -1, 1251,   -1,   -1,   -1,   -1,   -1, 1252,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1253,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1254,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1255,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1256,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1250,   -1,
-        -1, 1251,   -1,   -1, 1252,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1253,
+      1257,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1258,   -1, 1259,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1254,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1260,   -1,   -1,   -1,
+        -1,   -1, 1261,   -1,   -1,   -1,   -1, 1262,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1255,   -1,   -1,
-      1256,   -1,   -1,   -1,   -1, 1257,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1258, 1259,
-        -1,   -1, 1260,   -1,   -1,   -1,   -1,   -1,
-      1261,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1262,   -1,   -1,   -1,
-        -1,   -1, 1263,   -1,   -1,   -1,   -1,   -1,
+        -1, 1263,   -1,   -1,   -1,   -1,   -1, 1264,
+        -1,   -1,   -1,   -1, 1265, 1266,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1267,   -1,   -1,
+        -1,   -1,   -1,   -1, 1268,   -1,   -1,   -1,
+        -1, 1269,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1270,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1264,
+        -1, 1271,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1265, 1266,
-        -1,   -1, 1267,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1268,
+        -1,   -1, 1272,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1269,   -1,   -1,
+        -1,   -1, 1273,   -1,   -1,   -1,   -1, 1274,
+        -1,   -1,   -1,   -1, 1275,   -1,   -1, 1276,
+        -1,   -1,   -1,   -1, 1277,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1278,   -1,
+      1279,   -1, 1280,   -1,   -1, 1281,   -1,   -1,
+        -1, 1282,   -1, 1283,   -1,   -1, 1284,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1285,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1286,   -1, 1287,   -1,   -1,   -1,   -1,
+        -1, 1288,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1289,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1290,   -1,   -1, 1291,   -1, 1292,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1293,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1294,   -1,   -1,   -1,   -1,
+      1295,   -1,   -1,   -1,   -1,   -1, 1296,   -1,
+      1297, 1298,   -1,   -1,   -1,   -1,   -1, 1299,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1270,
-        -1,   -1, 1271,   -1,   -1,   -1,   -1,   -1,
-      1272,   -1,   -1,   -1, 1273,   -1,   -1,   -1,
-        -1,   -1, 1274,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1275,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1276,   -1,
-        -1,   -1,   -1, 1277,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1278,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1279,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1280,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1281,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1282,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1283,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1284,   -1,   -1, 1285,   -1,   -1,
-        -1,   -1,   -1, 1286,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1287,   -1,   -1,
-        -1,   -1, 1288,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1289,   -1,   -1, 1290,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1291,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1292,   -1,   -1,   -1,   -1,
-        -1, 1293,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1294,   -1,   -1,
-        -1,   -1,   -1,   -1, 1295,   -1,   -1,   -1,
-        -1, 1296,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1297,   -1,
-        -1,   -1, 1298,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1299,   -1,
-        -1, 1300,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1301,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1302,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1303,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1304,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1305,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1306,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1307,   -1,   -1,   -1,   -1,   -1,   -1,
+      1300,   -1, 1301,   -1,   -1,   -1,   -1, 1302,
+        -1,   -1,   -1, 1303,   -1, 1304,   -1,   -1,
+      1305,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1306,
+        -1,   -1,   -1,   -1, 1307,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 1308,   -1,   -1,
-      1309,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1310,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1309,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1310,   -1,   -1, 1311,   -1,   -1,
+        -1,   -1,   -1, 1312,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1313,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1311,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1312,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1314,
+        -1,   -1, 1315,   -1,   -1,   -1, 1316,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1313,   -1,
-        -1, 1314,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1315,   -1,   -1,   -1,
-        -1,   -1,   -1, 1316,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1317, 1318,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1319,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1320,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1321,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1322, 1323,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1324,   -1,   -1,   -1,   -1,   -1,
-        -1, 1325,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1326,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1317,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1318,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1319,
+        -1, 1320,   -1,   -1,   -1,   -1,   -1,   -1,
+      1321, 1322,   -1,   -1,   -1,   -1, 1323,   -1,
+        -1, 1324,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1325,   -1,   -1,   -1,   -1,
+      1326,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 1327,   -1,
+        -1,   -1,   -1,   -1, 1328, 1329,   -1,   -1,
+        -1, 1330,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1331,   -1,   -1,   -1,
+        -1, 1332,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1333,   -1,   -1,   -1, 1334,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1328,   -1,   -1,   -1,   -1,
-        -1, 1329,   -1,   -1, 1330,   -1,   -1, 1331,
+        -1,   -1,   -1,   -1,   -1,   -1, 1335, 1336,
+      1337,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1338,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1339,   -1,
+        -1, 1340,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1341,   -1,   -1,   -1,   -1,
+        -1, 1342,   -1,   -1,   -1,   -1, 1343,   -1,
+        -1,   -1,   -1, 1344,   -1,   -1,   -1, 1345,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1346,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1347,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1332,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1333,   -1,   -1,
-        -1,   -1,   -1, 1334,   -1,   -1, 1335,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1336,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1337,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1338,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1339,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1340,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1341,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1342,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1343,   -1,   -1,   -1,   -1,
-        -1, 1344,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1345,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1346,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1347,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1348,   -1,
+        -1,   -1,   -1,   -1, 1348,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 1349,
+        -1,   -1,   -1, 1350,   -1,   -1,   -1,   -1,
+        -1,   -1, 1351,   -1,   -1, 1352,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1353,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1354, 1355,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1356,   -1,   -1, 1357,   -1, 1358,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1359, 1360,   -1,   -1,
+        -1,   -1, 1361,   -1,   -1,   -1, 1362,   -1,
+        -1,   -1,   -1, 1363,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1364,   -1,   -1,
+      1365,   -1, 1366,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1367,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1368,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1369,   -1, 1370,   -1,   -1,   -1,
+        -1, 1371,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1372,   -1,   -1,
+        -1,   -1, 1373,   -1,   -1,   -1,   -1, 1374,
+        -1,   -1, 1375,   -1, 1376,   -1,   -1,   -1,
+      1377,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1378,   -1,   -1,   -1, 1379,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1380,   -1,
+      1381,   -1,   -1, 1382,   -1,   -1, 1383,   -1,
+        -1,   -1,   -1,   -1, 1384,   -1, 1385,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1350,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1351,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1352,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1353,   -1,   -1,
-        -1, 1354,   -1, 1355,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1356,
-      1357,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1358,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1359,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1360,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1361,   -1,   -1, 1362,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1363,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1364,   -1,   -1, 1365,   -1,
-        -1, 1366,   -1, 1367, 1368,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1369,   -1,   -1,
-        -1,   -1, 1370,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1371,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1372,   -1,   -1,   -1,
-      1373,   -1,   -1,   -1,   -1,   -1, 1374,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1375,   -1,
-        -1, 1376,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1377,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1378,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1379,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1380,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1381, 1382,   -1,   -1,   -1,
-        -1,   -1, 1383,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1384,
-        -1, 1385,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1386,   -1,   -1,   -1,   -1,
+        -1, 1386,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 1387,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1388,   -1,
+        -1, 1388,   -1,   -1,   -1,   -1, 1389,   -1,
+      1390,   -1,   -1, 1391,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1389,   -1,   -1,   -1,
-      1390,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1391,   -1,   -1,   -1,
+        -1, 1392,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1393,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1394, 1395, 1396, 1397,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1392,   -1,   -1, 1393,   -1,   -1,   -1,
+        -1, 1398,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1394,   -1,   -1,
+        -1,   -1, 1399, 1400,   -1,   -1,   -1,   -1,
+        -1,   -1, 1401,   -1,   -1,   -1,   -1,   -1,
+        -1, 1402,   -1,   -1,   -1,   -1, 1403, 1404,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1395,
-        -1,   -1, 1396,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1397,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1398,   -1,
-        -1, 1399,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1400,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1401, 1402,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1403,
-        -1,   -1, 1404,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 1405,   -1,   -1,   -1,   -1,
+        -1,   -1, 1406,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1407,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1408,   -1, 1409,   -1,   -1,   -1,
+        -1, 1410,   -1,   -1, 1411, 1412,   -1, 1413,
+        -1,   -1,   -1,   -1,   -1, 1414,   -1, 1415,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1416,   -1,   -1, 1417,   -1, 1418,
+        -1,   -1,   -1,   -1, 1419,   -1,   -1,   -1,
+      1420,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1406,   -1,
+        -1, 1421,   -1,   -1,   -1, 1422,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1423,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1407,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1408,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1424,   -1, 1425,
+        -1,   -1,   -1,   -1, 1426, 1427,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1409,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1410,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1411,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1412,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1413,   -1, 1414,   -1,   -1,   -1,
-        -1,   -1,   -1, 1415, 1416,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1417,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1418,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1419,   -1,   -1,   -1,   -1,
-        -1, 1420,   -1,   -1,   -1,   -1,   -1,   -1,
-      1421,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1422, 1423,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1424,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1425,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1426,   -1,   -1,
-      1427,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 1428,   -1, 1429,   -1,
+        -1,   -1,   -1,   -1,   -1, 1430,   -1,   -1,
+        -1, 1431, 1432,   -1,   -1, 1433,   -1,   -1,
+      1434, 1435,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1436,   -1,   -1, 1437,   -1,   -1,   -1,
+      1438,   -1,   -1,   -1,   -1,   -1,   -1, 1439,
+        -1,   -1,   -1, 1440,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1430,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1431,   -1,   -1,   -1,
+        -1, 1441,   -1,   -1,   -1,   -1,   -1, 1442,
+        -1,   -1,   -1, 1443,   -1,   -1,   -1,   -1,
+        -1, 1444,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1445,   -1,   -1,   -1,   -1,   -1, 1446,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1447, 1448,   -1,   -1,
+        -1,   -1,   -1,   -1, 1449,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1450,   -1,   -1,   -1,
+        -1,   -1,   -1, 1451,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1432,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1452,
+        -1, 1453,   -1,   -1,   -1,   -1, 1454,   -1,
+      1455,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1456,   -1,   -1,
+        -1,   -1, 1457, 1458,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1459,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1460,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1461,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1433,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1434,   -1,   -1,   -1, 1435,
-        -1,   -1, 1436,   -1,   -1, 1437,   -1,   -1,
-      1438,   -1,   -1, 1439,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1440,   -1,
+        -1,   -1, 1462,   -1, 1463,   -1,   -1,   -1,
+        -1,   -1, 1464,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1465, 1466,   -1,   -1,
+        -1,   -1, 1467,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1468,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1469,
+        -1,   -1,   -1, 1470,   -1,   -1,   -1, 1471,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1441, 1442,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1443,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1472,   -1, 1473,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1444,   -1,   -1, 1445,   -1,
-        -1, 1446,   -1,   -1, 1447,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1448,   -1,   -1,   -1,
-      1449,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1450,   -1,   -1, 1451,   -1,   -1, 1452,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1453,
-        -1,   -1,   -1, 1454,   -1,   -1,   -1,   -1,
-      1455,   -1,   -1,   -1,   -1,   -1,   -1, 1456,
-        -1,   -1, 1457,   -1,   -1,   -1,   -1,   -1,
+      1474,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1475,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1458,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1476,   -1,   -1,   -1,   -1, 1477,
+      1478,   -1, 1479,   -1, 1480,   -1,   -1, 1481,
+      1482, 1483, 1484,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1485,   -1,
+        -1, 1486,   -1,   -1, 1487,   -1, 1488,   -1,
+        -1,   -1, 1489,   -1,   -1,   -1,   -1,   -1,
+      1490,   -1,   -1,   -1,   -1,   -1,   -1, 1491,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1492,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1493,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1494,
+        -1,   -1,   -1, 1495,   -1, 1496,   -1,   -1,
+        -1,   -1, 1497,   -1, 1498,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1499,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1459,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1460,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1500,   -1,   -1, 1501,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1461,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1462,   -1,
-        -1,   -1,   -1, 1463,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1464,   -1,   -1,   -1,   -1,
+      1502,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1503,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1504, 1505,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1506,   -1,   -1,   -1,
+        -1,   -1, 1507, 1508,   -1,   -1, 1509,   -1,
+        -1,   -1,   -1,   -1,   -1, 1510,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1465,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1466,   -1, 1467,   -1,   -1,
-        -1,   -1,   -1,   -1, 1468,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1469,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1470,   -1,   -1,   -1,   -1,   -1, 1471,
-        -1,   -1, 1472,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1473,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1474,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1475,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1476,   -1,   -1, 1477,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1478,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1479,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1480,   -1,
-        -1,   -1, 1481,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1482,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1483,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1484,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1485,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1486,   -1,
-      1487, 1488,   -1,   -1,   -1,   -1, 1489,   -1,
-        -1,   -1,   -1,   -1,   -1, 1490,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1491,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1492,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1493,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1494,   -1,   -1, 1495,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1496,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1497,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1498,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1499, 1500,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1501,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1502,   -1,   -1,   -1,   -1,   -1, 1503,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1504,   -1,   -1,   -1,   -1,   -1,   -1, 1505,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1506,
-        -1,   -1, 1507,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1508,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1509,   -1,   -1, 1510,
-        -1,   -1,   -1,   -1, 1511,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1512,
-        -1, 1513,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1514,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1511, 1512,   -1,   -1,   -1, 1513,   -1,
+      1514,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1515,   -1,   -1,   -1,   -1,   -1,
-        -1, 1516,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1517,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1518,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1515,
+        -1, 1516,   -1,   -1, 1517, 1518,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 1519,   -1,   -1,
-      1520,   -1,   -1,   -1,   -1,   -1,   -1, 1521,
-        -1,   -1,   -1,   -1, 1522,   -1,   -1,   -1,
-        -1, 1523,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1520,   -1,   -1,   -1,   -1,   -1,   -1,
+      1521,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1522,   -1,   -1,   -1,   -1,   -1,   -1,
+      1523,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 1524,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1525,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1526,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1527,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1528,   -1,   -1,   -1,   -1,   -1, 1529,   -1,
+        -1,   -1, 1525,   -1, 1526,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1527,   -1,   -1,   -1, 1528,   -1,
+        -1,   -1,   -1,   -1,   -1, 1529,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1530,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1531, 1532,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1530,
+        -1,   -1,   -1,   -1,   -1,   -1, 1533,   -1,
+        -1,   -1,   -1,   -1,   -1, 1534,   -1, 1535,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1536,   -1, 1537,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1538,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1539,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1540, 1541,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1542,
+      1543,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1544,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1531, 1532,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1533,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1534,   -1,   -1,
-      1535, 1536,   -1,   -1,   -1,   -1,   -1, 1537,
-        -1,   -1,   -1,   -1,   -1, 1538,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1539,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1540,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1541,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1542,   -1,   -1, 1543,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1544,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1545,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1546,   -1,
-        -1,   -1,   -1,   -1, 1547,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1548,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1545,   -1,   -1, 1546,   -1,   -1, 1547,
+        -1, 1548,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 1549,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1550,   -1,   -1, 1551,   -1,
+        -1, 1552,   -1,   -1,   -1, 1553,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1554,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1550, 1551,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1555,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1552,   -1, 1553,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1554,   -1,   -1, 1555,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1556,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1557,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1556,   -1,   -1, 1557,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 1558,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1559, 1560,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1561,   -1,   -1, 1562,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1563,
+        -1,   -1,   -1, 1564,   -1,   -1,   -1, 1565,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1566, 1567,   -1, 1568,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1559,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1560,   -1,   -1, 1561,   -1,   -1, 1562,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1569,   -1,
+        -1,   -1,   -1, 1570,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1563,   -1,   -1,   -1,   -1,
+      1571,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1572,   -1,   -1,   -1,
+        -1,   -1,   -1, 1573,   -1,   -1,   -1, 1574,
+      1575,   -1,   -1,   -1,   -1,   -1, 1576,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1577,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1578,
+        -1,   -1, 1579,   -1,   -1,   -1, 1580,   -1,
+      1581,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1582,   -1,   -1, 1583,   -1,   -1,
+        -1, 1584,   -1,   -1, 1585,   -1,   -1, 1586,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1587,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1564,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1565,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1566,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1567,   -1,
-      1568,   -1,   -1,   -1, 1569,   -1,   -1, 1570,
+        -1,   -1,   -1,   -1,   -1, 1588,   -1, 1589,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1590,   -1, 1591,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1571,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1572,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1573,   -1,   -1,   -1,   -1, 1574,
-        -1,   -1,   -1,   -1,   -1,   -1, 1575,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1576,   -1,   -1, 1577,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1578,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1579,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1580,   -1,   -1,
-        -1,   -1,   -1, 1581,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1582,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1583,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1584,   -1,   -1,
-      1585,   -1,   -1, 1586,   -1,   -1,   -1, 1587,
-        -1,   -1, 1588,   -1,   -1,   -1,   -1, 1589,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1590,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1591,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1592,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1593,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1594,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1592,   -1, 1593, 1594,   -1,   -1,   -1,
         -1,   -1, 1595,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1596,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1597,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1598,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1599,
+      1600,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1596,   -1,   -1,   -1,
-        -1,   -1, 1597,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1598,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1599,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1600,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 1601,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1602,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1603,
-        -1,   -1,   -1, 1604,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1602,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1603,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1605,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1604,   -1,   -1,
+      1605, 1606,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1607,   -1,   -1,   -1,   -1,
+      1608,   -1,   -1,   -1,   -1, 1609,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1610,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1611,   -1,   -1,
+      1612,   -1,   -1,   -1, 1613, 1614,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1615, 1616,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1617,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1618,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1619,   -1, 1620,   -1,
+      1621, 1622,   -1,   -1,   -1,   -1,   -1,   -1,
+      1623,   -1,   -1,   -1,   -1,   -1,   -1, 1624,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1625,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1626,   -1,
+        -1,   -1,   -1,   -1,   -1, 1627,   -1,   -1,
+        -1, 1628,   -1,   -1, 1629,   -1,   -1, 1630,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1631,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1632,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1606,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1633,
+      1634,   -1,   -1,   -1,   -1,   -1, 1635,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1636,
+        -1,   -1,   -1,   -1,   -1, 1637,   -1,   -1,
+      1638,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1639,   -1, 1640,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1641,
+        -1,   -1,   -1, 1642, 1643,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1607,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1608,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1609,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1610,   -1,   -1,   -1,
-        -1,   -1, 1611,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1612,   -1,   -1, 1613, 1614,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1615,   -1,   -1,   -1,   -1,   -1, 1616,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1617,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1618,   -1,
-        -1, 1619,   -1, 1620,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1621,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1622,   -1, 1623,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1624,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1625,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1626,
-      1627,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1628,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1629,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1630,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1631,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1632,   -1,   -1,
-        -1,   -1,   -1, 1633,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1634, 1635,
-        -1,   -1,   -1,   -1,   -1, 1636,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1637, 1638,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1639,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1640,   -1,   -1,   -1, 1641,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1642,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1643,   -1,   -1,
-        -1,   -1,   -1,   -1, 1644,   -1,   -1,   -1,
-        -1,   -1, 1645,   -1,   -1,   -1,   -1, 1646,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1647,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1644,   -1,   -1,   -1,   -1,   -1,
+      1645, 1646,   -1,   -1,   -1,   -1,   -1, 1647,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 1648,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1649,
-        -1,   -1, 1650,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1651,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1652,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1653,   -1,   -1,   -1,   -1,   -1,
-        -1, 1654,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1649,   -1, 1650,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1651,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1652,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1653,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1654,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1655,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1655,   -1,   -1,   -1,
+        -1, 1656,   -1,   -1,   -1,   -1, 1657,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1656,
-        -1,   -1,   -1,   -1,   -1,   -1, 1657,   -1,
-        -1,   -1, 1658,   -1,   -1, 1659,   -1,   -1,
-        -1,   -1,   -1, 1660,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1661,   -1,   -1, 1662,
-        -1,   -1, 1663,   -1,   -1, 1664,   -1,   -1,
-        -1, 1665,   -1,   -1,   -1,   -1, 1666,   -1,
-        -1,   -1,   -1,   -1, 1667,   -1,   -1, 1668,
-      1669,   -1,   -1,   -1,   -1, 1670,   -1,   -1,
-      1671,   -1,   -1,   -1,   -1,   -1,   -1, 1672,
-        -1,   -1, 1673,   -1,   -1, 1674,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1675,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1658,   -1,   -1,   -1,   -1, 1659,
+        -1,   -1,   -1,   -1,   -1, 1660,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1661,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1662,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1676,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1663,   -1, 1664,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1665,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1677,   -1,   -1,   -1,   -1,   -1, 1678,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1679,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1680,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1666,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1667,   -1,
+        -1,   -1,   -1,   -1,   -1, 1668,   -1, 1669,
+      1670,   -1,   -1,   -1,   -1,   -1, 1671,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1672,   -1,
+        -1, 1673,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1681,
-        -1,   -1,   -1,   -1,   -1, 1682,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1683,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1674,   -1, 1675,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1676,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1677,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1678,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1684,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1679,   -1,
+        -1,   -1, 1680,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1681,   -1,
+        -1, 1682, 1683,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1684,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 1685,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1686,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1687,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1688,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1689,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1690,
+        -1, 1686,   -1,   -1,   -1,   -1, 1687,   -1,
+        -1, 1688,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1689,   -1,
+      1690,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1691,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1692,   -1,   -1,   -1, 1693,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1694,   -1,   -1, 1695,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1696,   -1,   -1,   -1,
+        -1,   -1,   -1, 1691,   -1,   -1,   -1, 1692,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1697,   -1,   -1,   -1,   -1,   -1, 1698,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1699,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1693,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1694,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1695,   -1, 1696,   -1,
+        -1,   -1,   -1, 1697,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1698,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1700,   -1,   -1,   -1,
-      1701,   -1,   -1,   -1,   -1, 1702, 1703,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1704,
-        -1,   -1, 1705,   -1,   -1,   -1,   -1,   -1,
-        -1, 1706,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1707,   -1, 1708,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1709,   -1,   -1,   -1,   -1,
+      1699,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1700, 1701,   -1,   -1,
+        -1, 1702,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1710,
-        -1,   -1, 1711,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1703,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1712,
-        -1, 1713,   -1,   -1,   -1,   -1,   -1,   -1,
-      1714,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1715,   -1,   -1,   -1,   -1,   -1,
-      1716,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1717,   -1,
-        -1,   -1,   -1,   -1, 1718,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1704,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1705,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1706,   -1,
+        -1,   -1, 1707,   -1, 1708,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1709,   -1,   -1,
+      1710,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1711,   -1,   -1,   -1,   -1,   -1,   -1,
+      1712,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1713,   -1,   -1,   -1, 1714,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1715,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1719,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1720,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1721,
-        -1,   -1, 1722,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1716,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1723,
+        -1,   -1,   -1, 1717,   -1,   -1,   -1, 1718,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1719,   -1,   -1,
+        -1,   -1,   -1,   -1, 1720,   -1,   -1,   -1,
+        -1, 1721,   -1, 1722,   -1,   -1,   -1,   -1,
+      1723,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 1724,   -1,   -1,   -1,   -1,
-      1725, 1726,   -1,   -1, 1727,   -1,   -1,   -1,
+        -1,   -1, 1725,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1726,   -1,   -1,
+      1727,   -1,   -1, 1728,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1729,   -1,   -1,   -1,
+        -1,   -1, 1730,   -1,   -1,   -1,   -1,   -1,
+      1731,   -1,   -1,   -1,   -1,   -1,   -1, 1732,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1733,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1734,
+      1735,   -1,   -1,   -1, 1736, 1737,   -1,   -1,
+        -1, 1738,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1739,   -1,   -1,   -1,   -1,   -1,
+        -1, 1740,   -1,   -1,   -1,   -1, 1741,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1742,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1728,   -1,   -1,
+        -1,   -1,   -1,   -1, 1743,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1729, 1730,
-      1731,   -1, 1732, 1733,   -1, 1734,   -1,   -1,
-      1735,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1736, 1737,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1744,   -1,   -1, 1745,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1746,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1747,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1748,   -1, 1749,
+        -1,   -1,   -1,   -1,   -1,   -1, 1750,   -1,
+        -1,   -1,   -1,   -1, 1751,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1752,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1753,   -1,   -1,   -1,   -1,   -1,   -1, 1754,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1755,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1756, 1757,
+      1758, 1759,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1760,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1738,   -1, 1739,   -1,
-        -1, 1740,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1761,   -1,   -1,   -1,
+        -1,   -1,   -1, 1762,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1763,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1764,
+      1765,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1766,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1741,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1742,   -1,   -1,   -1, 1743,
-        -1,   -1, 1744,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1745,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1746,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1747,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1748, 1749,   -1,   -1,   -1, 1750,
-        -1,   -1, 1751,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1752,
-        -1,   -1,   -1,   -1, 1753,   -1,   -1,   -1,
-      1754,   -1,   -1, 1755,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1756,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1757,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1758,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1759,
-        -1,   -1, 1760,   -1,   -1,   -1,   -1,   -1,
-        -1, 1761,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1762,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1763,   -1,   -1,
-        -1,   -1,   -1, 1764,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1765,   -1, 1766,
-        -1, 1767,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1768,   -1,   -1, 1769,   -1,   -1,   -1,
-        -1, 1770,   -1,   -1,   -1,   -1,   -1,   -1,
-      1771,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1767,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1768,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1769,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1770,   -1,
+        -1,   -1,   -1,   -1, 1771,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 1772,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1773,   -1,   -1,
-        -1, 1774,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1775,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1773,
+        -1,   -1,   -1,   -1,   -1, 1774,   -1, 1775,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1776,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1777,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1776, 1777,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 1778,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1779,   -1,   -1,   -1, 1780,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1781,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1779,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1782,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1783,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1784,   -1,   -1,   -1,
+        -1,   -1,   -1, 1780,   -1, 1781,   -1,   -1,
+        -1,   -1, 1782,   -1,   -1,   -1,   -1, 1783,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1784,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1785,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1785,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1786,   -1,
-        -1,   -1, 1787,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1786,
+        -1,   -1,   -1, 1787, 1788,   -1, 1789,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1790,   -1,
+        -1,   -1,   -1,   -1, 1791,   -1,   -1, 1792,
+        -1, 1793,   -1,   -1, 1794,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1795,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1796,
+        -1,   -1,   -1,   -1,   -1,   -1, 1797,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1788,   -1,   -1,
+        -1, 1798,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1799,   -1,   -1,   -1,   -1,   -1,   -1,
+      1800,   -1,   -1,   -1, 1801,   -1, 1802,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1789,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1803,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1804,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1790, 1791,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1805,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1806, 1807,   -1,   -1,   -1,   -1,   -1, 1808,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1792,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1809,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1810,   -1,   -1,   -1, 1811,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1793,   -1,   -1,   -1,   -1,
+        -1, 1812,   -1, 1813,   -1,   -1, 1814,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1794,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1795,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1796,   -1,   -1,   -1, 1797,   -1,   -1,   -1,
-        -1,   -1, 1798,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1799,   -1,
-      1800,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1815,   -1,   -1,   -1, 1816,   -1,   -1,
+      1817,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1801,
-      1802,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1818,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1803, 1804, 1805,   -1,   -1,   -1, 1806,
-        -1,   -1, 1807, 1808,   -1, 1809, 1810,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1811,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1812,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1819,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1813,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1814, 1815,   -1,
-      1816,   -1,   -1,   -1, 1817,   -1,   -1,   -1,
-        -1, 1818,   -1, 1819, 1820,   -1,   -1,   -1,
+      1820,   -1,   -1,   -1, 1821,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1822,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1823,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1821,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1824,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1825,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1826,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1822,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1823,   -1,   -1,   -1,
+      1827,   -1,   -1, 1828,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1824,   -1,   -1, 1825,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1829,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1826,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1827,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1828,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1829,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1830,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1831,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1832,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1833,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1834,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1835,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1836,   -1,
-        -1,   -1,   -1, 1837,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1838,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1839,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1840,   -1,
+        -1,   -1,   -1,   -1,   -1, 1830,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1841,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1842,
-        -1,   -1,   -1,   -1, 1843,   -1,   -1, 1844,
-      1845,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1831,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1832,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1846,
-        -1,   -1,   -1, 1847,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1848,   -1,   -1, 1849,
+      1833,   -1, 1834,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1835,   -1,   -1,   -1, 1836,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1837,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1838,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1839,   -1,   -1,   -1,   -1,
+        -1, 1840,   -1, 1841,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1842,   -1,   -1,   -1,
+        -1,   -1,   -1, 1843,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1844,
+        -1, 1845,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1846,   -1,   -1,   -1,   -1,
+      1847,   -1,   -1,   -1,   -1, 1848,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1849,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1850,   -1,   -1,   -1,   -1, 1851,
+        -1,   -1,   -1,   -1,   -1,   -1, 1850,   -1,
+        -1,   -1, 1851,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1852,   -1,   -1,   -1, 1853,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1854,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1855,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1856, 1857,   -1, 1858,   -1,   -1,
-        -1,   -1,   -1,   -1, 1859,   -1,   -1,   -1,
-      1860,   -1,   -1, 1861,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1852,
+        -1, 1853,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1854,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1862,   -1,   -1,   -1,   -1,   -1, 1863,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1855,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1856,   -1,
+        -1,   -1,   -1, 1857,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1858,   -1, 1859,
+        -1,   -1,   -1,   -1,   -1,   -1, 1860,   -1,
+        -1,   -1,   -1, 1861,   -1,   -1,   -1,   -1,
+        -1,   -1, 1862,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1863,   -1,   -1,   -1,
       1864,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1865,   -1,   -1,   -1,   -1,
+        -1, 1866,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1867,   -1,   -1,   -1,   -1, 1868,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1865,   -1,   -1,   -1,
-        -1,   -1, 1866,   -1,   -1,   -1,   -1,   -1,
-      1867,   -1,   -1,   -1, 1868,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1869,   -1,   -1, 1870,
+        -1,   -1,   -1,   -1, 1869,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1870,   -1,   -1,   -1,
         -1,   -1, 1871,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1872,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1873,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1874,   -1,
+        -1,   -1,   -1, 1872,   -1,   -1,   -1, 1873,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1875,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1876,   -1,   -1,   -1,   -1,   -1, 1877,   -1,
+      1874,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1875,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1878,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1876,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1877,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1878,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1879,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1879,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1880,   -1,   -1,   -1,
+        -1,   -1, 1880,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1881,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1882, 1883,
-        -1,   -1,   -1, 1884,   -1,   -1,   -1,   -1,
+        -1,   -1, 1881,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1882,
+        -1,   -1, 1883,   -1,   -1,   -1,   -1, 1884,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 1885,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1886,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1886, 1887,
-        -1,   -1, 1888,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1889,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1890,   -1,   -1, 1891,   -1, 1892,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1893, 1894,   -1, 1895,   -1,   -1,   -1,   -1,
-        -1, 1896,   -1,   -1, 1897,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1898,   -1, 1899,   -1,   -1,
-      1900,   -1,   -1,   -1, 1901,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1902,   -1,
-      1903,   -1,   -1, 1904,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1905,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1906,   -1,
-        -1,   -1,   -1,   -1, 1907,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1908,   -1,   -1,
-      1909,   -1,   -1,   -1,   -1, 1910,   -1,   -1,
-      1911,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1912,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1913,   -1,
-        -1,   -1, 1914,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1915,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1916,   -1,   -1,   -1,   -1,
-        -1, 1917,   -1,   -1,   -1,   -1,   -1,   -1,
+      1887,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1888,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1889,
+        -1,   -1,   -1,   -1,   -1,   -1, 1890,   -1,
+        -1,   -1,   -1,   -1, 1891,   -1,   -1,   -1,
+        -1, 1892,   -1,   -1,   -1, 1893,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1894,   -1, 1895,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1896,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1897,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1898,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1899,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1918,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1919,   -1,
-        -1,   -1,   -1,   -1, 1920,   -1,   -1,   -1,
+        -1,   -1,   -1, 1900,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1901,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1902,   -1,   -1,   -1,   -1,
+        -1,   -1, 1903,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1904,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1905,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1906,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1907,   -1,   -1,   -1,   -1,   -1, 1908,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1909,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1910,   -1,   -1,
+      1911,   -1,   -1,   -1,   -1, 1912,   -1,   -1,
+        -1, 1913,   -1, 1914, 1915,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1916,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1917,   -1, 1918,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1919,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1920,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 1921,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1922,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1923,   -1,   -1,
-        -1,   -1,   -1, 1924,   -1,   -1,   -1,   -1,
-        -1, 1925,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1926,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1927,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1928,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1929, 1930,   -1, 1931,   -1,   -1,   -1,   -1,
-        -1, 1932,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1922,   -1,   -1,   -1, 1923,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1924,   -1,
+        -1,   -1, 1925,   -1,   -1,   -1,   -1, 1926,
+        -1,   -1,   -1, 1927,   -1,   -1,   -1,   -1,
+        -1, 1928,   -1,   -1,   -1,   -1,   -1,   -1,
+      1929,   -1,   -1, 1930,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1931,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1932,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1933,   -1,   -1,   -1,   -1,   -1,   -1,
-      1934,   -1,   -1, 1935,   -1,   -1,   -1,   -1,
-        -1, 1936,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1933,   -1,   -1,   -1,   -1, 1934,   -1,
+        -1,   -1,   -1, 1935,   -1,   -1,   -1, 1936,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1937,   -1,   -1, 1938,   -1,
+        -1, 1937,   -1, 1938,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1939,
+        -1,   -1,   -1, 1940,   -1,   -1, 1941,   -1,
+        -1, 1942,   -1,   -1, 1943,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1944,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1939,   -1, 1940,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1945,   -1,   -1,
+        -1, 1946,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1947,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1948,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1949,   -1, 1950,   -1,
+        -1,   -1,   -1,   -1, 1951,   -1,   -1,   -1,
+        -1, 1952,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1941,   -1,
-        -1,   -1,   -1,   -1, 1942,   -1,   -1,   -1,
+        -1, 1953,   -1, 1954,   -1,   -1,   -1, 1955,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1956,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1957,   -1,
+        -1,   -1,   -1,   -1, 1958,   -1,   -1,   -1,
+        -1,   -1, 1959,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1960,   -1, 1961,   -1,
+        -1,   -1,   -1,   -1,   -1, 1962,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1963,   -1,   -1,
+      1964, 1965,   -1,   -1,   -1,   -1,   -1,   -1,
+      1966,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1967,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1968,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1943,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1944,
-        -1, 1945,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1946,   -1,
+        -1,   -1,   -1, 1969,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1947,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1948,   -1,   -1, 1949,
+        -1,   -1,   -1,   -1,   -1,   -1, 1970,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 1971, 1972,   -1, 1973,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1950,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1951,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1952,   -1,
-        -1,   -1,   -1, 1953,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1954,   -1,   -1,
-        -1,   -1, 1955,   -1, 1956, 1957,   -1,   -1,
-      1958, 1959,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1960,   -1,   -1,   -1,   -1,   -1,
-      1961,   -1,   -1,   -1,   -1,   -1, 1962,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1963,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1964,   -1,   -1,   -1,
-        -1,   -1,   -1, 1965,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 1966,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1967,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1968,   -1,   -1, 1969,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1970,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      1971,   -1, 1972,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1973,   -1,
-        -1,   -1,   -1, 1974,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 1974,   -1,   -1,
         -1,   -1,   -1,   -1, 1975,   -1,   -1,   -1,
-        -1,   -1,   -1, 1976,   -1,   -1,   -1,   -1,
+        -1,   -1, 1976,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 1977,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 1977,   -1,
-        -1, 1978,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1979,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1978,   -1,
+        -1, 1979,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 1980,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1981,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 1980,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1981,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1982,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 1983,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1984,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1985,   -1,   -1,   -1,
+        -1, 1982,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1983,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1984, 1985,   -1,   -1,   -1,   -1, 1986,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 1986,   -1,   -1,
-        -1,   -1,   -1, 1987,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1988,   -1,   -1,   -1,
-        -1, 1989,   -1,   -1,   -1,   -1, 1990,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1987,
+        -1,   -1, 1988,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1991,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 1989,   -1,   -1,   -1,   -1,
+      1990, 1991,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 1992,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 1993,   -1,
+        -1,   -1,   -1,   -1,   -1, 1994,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 1993,   -1,   -1,   -1,
-      1994,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      1995,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1996,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1995,
-        -1,   -1, 1996,   -1,   -1, 1997, 1998,   -1,
+        -1, 1997,   -1,   -1,   -1,   -1, 1998,   -1,
+      1999,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2000,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 1999,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2000,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2001,   -1,
+        -1,   -1,   -1, 2001, 2002,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2003,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2004, 2005,   -1,   -1,   -1,   -1,
+        -1, 2006,   -1,   -1,   -1,   -1, 2007, 2008,
+        -1,   -1,   -1, 2009,   -1,   -1, 2010,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2011,   -1,
+        -1, 2012,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2013,   -1, 2014,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2015,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2002,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2003,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2004,
+      2016,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2017,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2005,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2006,   -1,   -1,
+        -1,   -1,   -1, 2018,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2007,   -1,
-      2008,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2009,
-        -1,   -1,   -1,   -1, 2010,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2011,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2012,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2013,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2014,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2015,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2016,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2017,   -1, 2018,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2019,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2020,   -1,   -1,   -1,   -1,
-      2021, 2022,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2019, 2020,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2021, 2022,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 2023,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2024,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2025,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2024,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2026,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2025,   -1,   -1, 2026,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 2027,   -1,   -1,
-        -1,   -1, 2028,   -1,   -1,   -1,   -1,   -1,
-      2029,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2028,   -1, 2029,
+        -1,   -1,   -1,   -1, 2030,   -1,   -1, 2031,
+        -1,   -1,   -1, 2032,   -1,   -1, 2033,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2030,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2031,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2034,
+        -1,   -1,   -1,   -1,   -1, 2035,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2032,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2033,   -1,   -1,
-        -1, 2034,   -1,   -1,   -1,   -1, 2035, 2036,
-        -1,   -1,   -1,   -1, 2037,   -1, 2038,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2039,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2040,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2036,   -1,   -1,   -1,   -1,
+        -1,   -1, 2037,   -1, 2038, 2039,   -1,   -1,
+        -1,   -1,   -1,   -1, 2040,   -1,   -1,   -1,
         -1,   -1, 2041,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2042,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2042,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2043, 2044,   -1,
+        -1,   -1,   -1,   -1, 2045,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2046,   -1,   -1,   -1,
+        -1, 2047,   -1,   -1,   -1,   -1,   -1,   -1,
+      2048,   -1, 2049,   -1,   -1,   -1,   -1,   -1,
+        -1, 2050,   -1,   -1,   -1, 2051,   -1, 2052,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2053,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2054,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2043,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2055,
+        -1,   -1,   -1,   -1, 2056,   -1,   -1,   -1,
+      2057,   -1,   -1,   -1,   -1, 2058, 2059,   -1,
+        -1,   -1, 2060, 2061,   -1,   -1, 2062,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2063,   -1,   -1, 2064,   -1,   -1,
+        -1,   -1,   -1, 2065,   -1,   -1,   -1,   -1,
+      2066,   -1, 2067,   -1,   -1, 2068,   -1, 2069,
+      2070,   -1,   -1, 2071,   -1,   -1, 2072,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2073,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2074,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2044,   -1,
-        -1, 2045,   -1,   -1,   -1, 2046,   -1,   -1,
+        -1,   -1,   -1, 2075,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2047,   -1,   -1,   -1,   -1,   -1,   -1, 2048,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2076,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2049,   -1,   -1,   -1, 2050,
+        -1, 2077, 2078,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2051,   -1,   -1,
-        -1,   -1,   -1, 2052,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2053,   -1,   -1,
+      2079,   -1, 2080, 2081,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2082, 2083,   -1,   -1,   -1,   -1,   -1,
+        -1, 2084,   -1, 2085,   -1,   -1,   -1, 2086,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2054,   -1,   -1,   -1, 2055,   -1,   -1,
+      2087,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2088,   -1,   -1,   -1, 2089,   -1,
+        -1,   -1,   -1,   -1, 2090,   -1,   -1,   -1,
+      2091,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2056,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2057,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2058,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2059,   -1,   -1,   -1, 2060,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2061,
-        -1, 2062,   -1, 2063,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2064,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2065,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2066,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2067,
-        -1,   -1, 2068,   -1, 2069,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2070,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2071,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2072,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2073,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2074,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2075, 2076,
-        -1, 2077,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2078,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2079,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2080,   -1,   -1,   -1,   -1,   -1, 2081,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2082,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2083, 2084,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2085,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2086,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2087,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2088,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2089,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2090,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2091,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2092,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2092,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 2093,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2094,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2095,   -1,   -1,
-        -1,   -1,   -1, 2096,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2097,   -1,   -1,
+        -1,   -1, 2094,   -1,   -1,   -1,   -1,   -1,
+        -1, 2095,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2096,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2097,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2098,   -1,   -1,   -1,
+        -1,   -1, 2099,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2100,   -1,
+        -1,   -1,   -1,   -1, 2101, 2102,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2103,   -1, 2104,   -1, 2105,   -1,
+      2106,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2107,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2098,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2108,   -1,   -1,
+        -1,   -1, 2109,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2110,   -1,   -1,   -1,
+      2111,   -1,   -1, 2112,   -1,   -1,   -1,   -1,
+        -1,   -1, 2113,   -1,   -1,   -1, 2114,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2115,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2099,   -1, 2100,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2101,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2102,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2103,   -1,   -1, 2104,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2105,   -1,   -1,   -1,   -1, 2106,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2107,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2108,   -1,   -1, 2109,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2110, 2111,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2112,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2113,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2114,   -1,   -1,   -1,   -1,   -1,
-        -1, 2115,   -1,   -1, 2116,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2117,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2118,   -1,   -1,
-        -1,   -1,   -1,   -1, 2119,   -1, 2120, 2121,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2116, 2117,   -1,   -1,   -1,
+        -1,   -1, 2118,   -1,   -1, 2119, 2120,   -1,
+        -1, 2121,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 2122,   -1,   -1,   -1,
+      2123, 2124,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2125,   -1,
+        -1, 2126, 2127,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2128, 2129,   -1,   -1,   -1, 2130,
+        -1,   -1,   -1, 2131,   -1,   -1, 2132,   -1,
+        -1,   -1,   -1, 2133,   -1,   -1,   -1,   -1,
+      2134,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2123,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2135,
+        -1,   -1,   -1,   -1,   -1,   -1, 2136,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2124,
-        -1,   -1,   -1, 2125,   -1,   -1,   -1,   -1,
-      2126,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2137,   -1,   -1,   -1,   -1,   -1, 2138,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2139,   -1,   -1, 2140,   -1,   -1, 2141,
+        -1,   -1,   -1,   -1,   -1,   -1, 2142,   -1,
+        -1,   -1,   -1, 2143, 2144,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2145, 2146,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2127,
-        -1,   -1,   -1, 2128, 2129,   -1, 2130,   -1,
-      2131,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2147,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2148,   -1, 2149, 2150,   -1,   -1,
+        -1, 2151,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2152, 2153,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2154,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2132,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2133,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2134,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2155,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2156,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2157,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2158,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2135,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2159,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2136,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2160,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2137,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2138,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2139,   -1, 2140,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2141,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2142,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2143,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2144,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2145,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2146,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2147,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2148,   -1,   -1, 2149,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2150,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2151,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2152,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2153,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2154,   -1,   -1,   -1, 2155,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2156,   -1,   -1, 2157,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2158,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2159,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2160,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2161,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2162,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2161, 2162,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 2163,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2164,   -1,   -1,   -1,
-        -1,   -1, 2165,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2164,   -1,   -1, 2165,   -1,
+        -1,   -1,   -1,   -1,   -1, 2166, 2167,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2166,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2168,   -1,   -1, 2169,   -1,   -1,
+        -1,   -1, 2170,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2167,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2168,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2169,   -1, 2170,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2171,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2172,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2173,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2171,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2172,   -1, 2173,   -1,   -1,   -1,   -1,
         -1,   -1, 2174,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2175,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2176,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2177,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2178,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2179,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2180,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2175,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2181,   -1,
+      2182,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2183,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2176,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2184, 2185,   -1,   -1,
+        -1, 2186,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2177, 2178,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2187,
+      2188,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2189,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2190,   -1, 2191,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2192,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2179,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2180,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2193,   -1,   -1, 2194,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2195,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2196,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2197,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2181,   -1,   -1, 2182,   -1,   -1,
-        -1,   -1,   -1, 2183,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2184,   -1,   -1,   -1,   -1, 2185,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2198,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2199,   -1,   -1, 2200,   -1,   -1,   -1,
+        -1,   -1,   -1, 2201,   -1,   -1,   -1,   -1,
+        -1, 2202,   -1,   -1, 2203,   -1, 2204,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2205,   -1,
+        -1,   -1, 2206,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2207,   -1,   -1,   -1,
+        -1,   -1, 2208,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2209,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2210,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2211,   -1,
+      2212,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2213,   -1,   -1,   -1, 2214,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2215,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2216,   -1,   -1,   -1,   -1,   -1, 2217,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2218,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2186,   -1,   -1,   -1,
-        -1,   -1, 2187,   -1,   -1,   -1,   -1,   -1,
+        -1, 2219,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2188, 2189,   -1,   -1,   -1,
+      2220,   -1, 2221,   -1,   -1,   -1,   -1,   -1,
+      2222,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2223, 2224,   -1,   -1,   -1,   -1, 2225,
+      2226,   -1,   -1,   -1,   -1,   -1,   -1, 2227,
+        -1,   -1,   -1,   -1,   -1, 2228,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2229,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2190,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2191,   -1,   -1,
+        -1,   -1, 2230,   -1,   -1,   -1,   -1, 2231,
+        -1,   -1, 2232,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2233,   -1, 2234,
+      2235,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2192,   -1,
+      2236,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2193,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2194,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2195,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2196,   -1, 2197,   -1,
-        -1, 2198, 2199,   -1,   -1,   -1,   -1,   -1,
-      2200,   -1,   -1,   -1,   -1, 2201,   -1,   -1,
+        -1,   -1,   -1, 2237, 2238,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2202,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2203, 2204,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2205,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2206,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2207,   -1,   -1,   -1,   -1,   -1,
-        -1, 2208,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2209,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2210,   -1, 2211,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2212,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2213,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2214,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2215,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2216,   -1,
-        -1,   -1,   -1, 2217,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2218,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2219,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2220,   -1,
-        -1,   -1,   -1,   -1, 2221,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2222,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2223,
-        -1,   -1, 2224,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2225,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2226,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2227, 2228,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2229,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2230,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2231,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2232,   -1,   -1, 2233,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2234,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2235,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2236,   -1,
-        -1,   -1,   -1,   -1,   -1, 2237,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2238,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2239,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2239,   -1,   -1, 2240,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2240,   -1,   -1,
         -1,   -1, 2241,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 2242,   -1,   -1,   -1,   -1,
-        -1,   -1, 2243,   -1,   -1,   -1,   -1,   -1,
+        -1, 2243,   -1,   -1,   -1,   -1, 2244, 2245,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2246,   -1, 2247,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2248,   -1,   -1,   -1,
+        -1,   -1,   -1, 2249,   -1,   -1, 2250,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2251,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2244,   -1,   -1,   -1,   -1, 2245,   -1,   -1,
+      2252,   -1,   -1,   -1,   -1,   -1, 2253,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2254,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2246,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2247,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2248,   -1,   -1, 2249,   -1,   -1,   -1,
-        -1,   -1, 2250,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2251,   -1, 2252,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2253,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2254,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 2255,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2256,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2256,   -1,
+        -1,   -1,   -1, 2257,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2257,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2258,
+      2259,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2260,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2261, 2262,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2263,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2258,   -1,   -1,   -1,   -1,
+      2264, 2265,   -1,   -1,   -1,   -1, 2266,   -1,
+        -1,   -1, 2267,   -1, 2268,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2269,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2259,   -1,   -1,   -1,   -1,
+        -1, 2270,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2260, 2261,   -1,   -1,
+        -1, 2271,   -1, 2272,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2262,   -1,   -1, 2263,   -1,   -1,   -1,
-        -1, 2264,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2265,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2266,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2267,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2268,   -1,   -1, 2269,   -1,   -1,
-      2270,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2271,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2272,
-        -1,   -1,   -1,   -1, 2273,   -1,   -1,   -1,
+        -1,   -1, 2273,   -1,   -1,   -1,   -1,   -1,
       2274,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2275,   -1,   -1,   -1,   -1,
+        -1, 2276,   -1,   -1,   -1,   -1,   -1,   -1,
+      2277,   -1, 2278,   -1,   -1,   -1,   -1, 2279,
+      2280,   -1,   -1,   -1,   -1, 2281,   -1,   -1,
+        -1,   -1, 2282, 2283,   -1, 2284,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2285,   -1,   -1,
+        -1, 2286,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2287,   -1,   -1, 2288,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2289, 2290,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2291,   -1, 2292,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2275,
-        -1,   -1,   -1,   -1,   -1, 2276,   -1, 2277,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2293,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2294,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2278,   -1,
+        -1,   -1,   -1,   -1, 2295,   -1, 2296,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2297, 2298,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2299, 2300,   -1,   -1,   -1,   -1,   -1,
+      2301,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2279,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2280,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2281,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2282,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2283,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2284,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2285,   -1, 2286,   -1,   -1, 2287,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2288,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2289,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2290,   -1,   -1,
-        -1, 2291,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2292,   -1,   -1,   -1, 2293,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2294,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2295,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2296,   -1,   -1,   -1,   -1,   -1,   -1,
-      2297,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2298,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2299,   -1,   -1,   -1,   -1,   -1, 2300,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2301,   -1,   -1,   -1,   -1,
-        -1,   -1, 2302,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2303,   -1,   -1, 2304,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2305,   -1,   -1,   -1,   -1, 2306,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2307,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2308,   -1,   -1,   -1,   -1,
-      2309,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2310,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2311,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2312,   -1,   -1,   -1,   -1,   -1,   -1, 2313,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2314,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2302,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2303,   -1,   -1,   -1,
+        -1, 2304,   -1,   -1,   -1, 2305,   -1, 2306,
+        -1,   -1,   -1,   -1,   -1, 2307,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2308,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2309,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2310,
+        -1, 2311,   -1, 2312,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2313,
+        -1,   -1,   -1, 2314,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 2315,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2316,   -1,
-        -1,   -1,   -1,   -1, 2317,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2316,   -1,   -1,   -1, 2317,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       2318,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2319,   -1,
+      2319,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2320,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2321,   -1,   -1,   -1,   -1,   -1, 2322,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2320,   -1,
+      2321,   -1,   -1, 2322, 2323,   -1, 2324, 2325,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2326,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2327,   -1,   -1,   -1,
+        -1,   -1,   -1, 2328,   -1,   -1,   -1,   -1,
+        -1, 2329,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2330,   -1,   -1,   -1, 2331,   -1,
+        -1,   -1,   -1, 2332,   -1, 2333,   -1,   -1,
+      2334,   -1, 2335,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2336,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2323,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2337,   -1, 2338,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2324,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2339,   -1,   -1,   -1,   -1,
+        -1, 2340,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2341,
+      2342,   -1,   -1,   -1,   -1, 2343,   -1,   -1,
+        -1, 2344,   -1,   -1, 2345,   -1,   -1, 2346,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2347,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2348, 2349,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2325,   -1,   -1, 2326,   -1,
+        -1,   -1, 2350,   -1, 2351, 2352, 2353,   -1,
+        -1,   -1,   -1, 2354,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2355,   -1,   -1,   -1,
+        -1, 2356,   -1,   -1, 2357,   -1,   -1,   -1,
+        -1,   -1, 2358,   -1,   -1,   -1, 2359,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2327,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2328,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2329,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2330,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2360,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2361,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2331,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2332,   -1,   -1,
-        -1,   -1,   -1,   -1, 2333,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2334,   -1,   -1,   -1,   -1,   -1, 2335,   -1,
-        -1, 2336,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2337,   -1,   -1,
-      2338,   -1, 2339,   -1,   -1, 2340,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2341,   -1,
-        -1,   -1,   -1,   -1,   -1, 2342,   -1,   -1,
+        -1, 2362,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2363,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2364,   -1,   -1,   -1, 2365,   -1, 2366,   -1,
+      2367,   -1,   -1,   -1, 2368,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2343,   -1,   -1,   -1,
-        -1,   -1,   -1, 2344,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2345,   -1,   -1,   -1,   -1,   -1,   -1,
+      2369,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2370,   -1,   -1,   -1,   -1, 2371,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2372,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2346,   -1,   -1, 2347,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2348,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2349,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2350,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2351,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2352,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2353,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2354,   -1,   -1, 2355,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2356,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2357, 2358,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2359,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2360,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2361,   -1,   -1,   -1,   -1,   -1, 2362, 2363,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2364,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2365,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2366, 2367,   -1,
-        -1,   -1,   -1,   -1,   -1, 2368,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2369,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2370,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2373,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2371,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2372,
-      2373,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       2374,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2375,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2375,   -1, 2376,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2377, 2378, 2379,   -1,   -1,   -1,
+        -1,   -1, 2380,   -1,   -1,   -1, 2381,   -1,
+        -1,   -1,   -1,   -1,   -1, 2382,   -1,   -1,
+        -1,   -1,   -1,   -1, 2383,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2376,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2377,   -1,
+        -1,   -1,   -1,   -1,   -1, 2384,   -1,   -1,
+        -1,   -1, 2385,   -1,   -1,   -1,   -1,   -1,
+      2386,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2387,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2388,   -1,   -1,
+        -1, 2389,   -1,   -1,   -1,   -1,   -1, 2390,
+      2391,   -1,   -1,   -1,   -1,   -1,   -1, 2392,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2393,
+        -1,   -1,   -1,   -1,   -1, 2394,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2378,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2379,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2380,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2381,   -1,
-        -1,   -1, 2382, 2383,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2384,   -1,
-      2385,   -1,   -1,   -1,   -1,   -1,   -1, 2386,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2387,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2388,   -1, 2389,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2390,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2391,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2392,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2393,   -1,   -1, 2394,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2395,   -1,   -1,   -1,
-        -1, 2396,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2397,   -1,
-        -1,   -1, 2398,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2399,   -1,
+      2395,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2396,   -1,   -1,
+      2397,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2398,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2399,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 2400,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2401,   -1,
-        -1,   -1,   -1,   -1, 2402,   -1,   -1,   -1,
+      2401,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2402,   -1,   -1,
         -1, 2403,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2404,   -1,   -1,
-      2405,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2404,   -1,   -1,   -1,
+        -1,   -1,   -1, 2405,   -1, 2406,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2407,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2406,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2407,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2408,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2409,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2410,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2411,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2412,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2413,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2408,   -1,   -1,   -1,
+      2409, 2410,   -1, 2411, 2412,   -1,   -1,   -1,
+      2413,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 2414,   -1,   -1,   -1,   -1,
+      2415,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -30433,2923 +28884,1970 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2415,   -1,   -1,   -1,   -1,
+        -1, 2416, 2417,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2416,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2417,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 2418,
+        -1,   -1,   -1, 2419,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2420,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2419, 2420,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2421,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2422,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2423,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2421,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2424,   -1,   -1, 2425,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2426,   -1,   -1,   -1,
+        -1,   -1,   -1, 2427,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2428,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2429,   -1,   -1, 2430,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2422,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2423,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2424,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2431,   -1,
+        -1, 2432,   -1, 2433, 2434, 2435,   -1, 2436,
+      2437,   -1,   -1,   -1,   -1,   -1,   -1, 2438,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2439,
+        -1,   -1,   -1, 2440,   -1, 2441,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2442,   -1, 2443,
+        -1,   -1, 2444, 2445,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2425,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2426,   -1,   -1,
+        -1,   -1,   -1, 2446,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2447,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2448,   -1,   -1,
+        -1, 2449,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2427,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2428,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2450,   -1,   -1, 2451,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2429,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2452,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2453,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2430,   -1,   -1,   -1,   -1,   -1, 2431,   -1,
+        -1,   -1, 2454,   -1,   -1,   -1,   -1,   -1,
+        -1, 2455,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2432,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2433,   -1,   -1,
+        -1, 2456, 2457,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2434,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2458,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2435,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2436, 2437,   -1, 2438,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2439,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2440,   -1,
-        -1,   -1, 2441,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2442,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2443,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2444,   -1,   -1,   -1,   -1,
-      2445,   -1,   -1, 2446,   -1,   -1,   -1,   -1,
-        -1, 2447,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2448,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2449,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2450,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2451,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2452,   -1,   -1,   -1, 2453,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2454,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2455,
-        -1,   -1,   -1,   -1,   -1, 2456,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2457,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2458,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2459,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2460,   -1,   -1,   -1,   -1,   -1,   -1,
+      2459,   -1,   -1,   -1,   -1,   -1,   -1, 2460,
         -1,   -1,   -1,   -1,   -1, 2461,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2462,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2463,   -1,
-      2464,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2465,   -1,   -1,   -1,   -1,   -1,
-      2466,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2467,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2468,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2462,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2463,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2469,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2464,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2470,   -1, 2471,   -1,   -1,   -1,   -1,
-      2472,   -1,   -1, 2473,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2465,   -1,   -1,
+        -1,   -1,   -1,   -1, 2466,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2467,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2474,   -1, 2475,
+        -1,   -1,   -1, 2468,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2476,
-        -1,   -1,   -1,   -1, 2477,   -1,   -1,   -1,
+        -1, 2469,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2478,   -1,   -1,   -1,   -1,   -1,
-        -1, 2479,   -1,   -1,   -1,   -1,   -1, 2480,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2470,   -1,   -1,   -1,   -1,   -1,   -1,
+      2471,   -1,   -1,   -1,   -1,   -1, 2472,   -1,
+        -1, 2473,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2474,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2475,   -1,   -1, 2476, 2477,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2478,   -1,   -1, 2479,   -1,   -1, 2480,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 2481,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2482,   -1,   -1,   -1,   -1,
+        -1,   -1, 2483,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2484,   -1,   -1,
+      2485,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2486, 2487,
+        -1,   -1,   -1,   -1,   -1, 2488, 2489,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2482,   -1,   -1,   -1,   -1, 2483,   -1,   -1,
-        -1, 2484,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2490,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2485,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2486,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2491,
+        -1,   -1,   -1,   -1, 2492,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2487,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2488,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2493,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2489,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2494,   -1,   -1,   -1, 2495,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2496,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2490,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2497,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2498,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2499,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2491,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2492,   -1,   -1,   -1,   -1,   -1,
+      2500,   -1,   -1, 2501,   -1,   -1,   -1, 2502,
+        -1,   -1, 2503,   -1,   -1,   -1,   -1,   -1,
+        -1, 2504,   -1, 2505,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2506,   -1, 2507,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2493,   -1,
-        -1,   -1,   -1,   -1,   -1, 2494,   -1,   -1,
+        -1,   -1, 2508,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2509,   -1,   -1,   -1,
+      2510,   -1,   -1,   -1,   -1,   -1,   -1, 2511,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2495,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2496, 2497,   -1, 2498,
-        -1,   -1,   -1, 2499,   -1, 2500,   -1,   -1,
+      2512,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2513,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2514, 2515,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2516,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2517,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2518,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2501,   -1,
-        -1, 2502,   -1,   -1,   -1, 2503,   -1,   -1,
-        -1,   -1, 2504,   -1,   -1,   -1,   -1, 2505,
+      2519, 2520,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2521,
+        -1,   -1,   -1, 2522,   -1,   -1,   -1,   -1,
+        -1, 2523,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2524,   -1, 2525,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2506,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2507,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2508,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2509,   -1,   -1,   -1,   -1, 2510,   -1,
-        -1,   -1, 2511,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2512,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2513,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2514,   -1,   -1, 2515,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2516,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2517,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2518,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2519,   -1,   -1, 2520,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2521,   -1,   -1,   -1, 2522,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2526,   -1,   -1, 2527,
+        -1,   -1, 2528,   -1,   -1,   -1,   -1,   -1,
+      2529,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2523,   -1,
-      2524,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2525,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2526,   -1,   -1,   -1,   -1,   -1, 2527,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2528,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2529,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 2530,   -1,   -1,
-        -1,   -1, 2531, 2532, 2533,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2534,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2535,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2536,
-        -1,   -1,   -1,   -1,   -1,   -1, 2537,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2531,   -1,
+        -1,   -1,   -1, 2532,   -1,   -1, 2533,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2534,   -1,   -1,   -1,   -1,   -1,
+      2535, 2536,   -1,   -1,   -1,   -1, 2537,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2538,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2539,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2540,   -1,   -1,   -1,   -1,
+      2541,   -1, 2542,   -1,   -1,   -1,   -1, 2543,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2544,   -1,   -1, 2545,   -1,
+        -1,   -1,   -1,   -1,   -1, 2546,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2547,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2538,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2539,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2548,
+        -1,   -1,   -1,   -1,   -1, 2549,   -1, 2550,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2540,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2551,   -1,   -1,
+      2552,   -1,   -1,   -1,   -1,   -1, 2553,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2554,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2555,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2556,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2557,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2541,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2558,   -1,   -1,
+        -1,   -1,   -1,   -1, 2559,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2542,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2543,   -1,   -1, 2544,   -1,
-        -1,   -1,   -1,   -1,   -1, 2545,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2546,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2547,   -1,   -1, 2548, 2549,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2560,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2561, 2562,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2550,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2551,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2563,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2552,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2553,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2554,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2555,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2556,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2557,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2558,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2559,   -1,   -1, 2560,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2561,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2562,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2563,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2564,
-        -1,   -1, 2565,   -1, 2566,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2567,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2564,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2565, 2566,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2567, 2568,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2569,
+      2570,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2568,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2569,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2570,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 2571,   -1,   -1,   -1,   -1,
-        -1, 2572,   -1,   -1, 2573,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2574,   -1,   -1,
+        -1, 2572,   -1, 2573,   -1, 2574, 2575,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2576,   -1,
+        -1,   -1, 2577,   -1,   -1, 2578,   -1, 2579,
+        -1,   -1,   -1,   -1, 2580,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2581,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2575,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2576,   -1,   -1,   -1,   -1, 2577, 2578,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2579,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2580,   -1,   -1, 2581,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 2582,
-        -1,   -1,   -1,   -1,   -1, 2583,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2583,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 2584,   -1,   -1,
+        -1,   -1, 2585,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2585,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2586,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2586,   -1,   -1,
         -1,   -1, 2587,   -1,   -1,   -1,   -1,   -1,
-        -1, 2588,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2588,   -1,   -1, 2589,   -1,
+        -1,   -1, 2590,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2591,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2589,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2590,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2591,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2592,
+        -1,   -1, 2592,   -1,   -1,   -1,   -1, 2593,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2593,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2594,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2594,
+        -1,   -1,   -1,   -1,   -1,   -1, 2595,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2596,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2597,   -1, 2598,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2599,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2595,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2596,   -1,
-        -1,   -1, 2597,   -1,   -1,   -1,   -1, 2598,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2599,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 2600,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2601,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2602,   -1,   -1,   -1,   -1,   -1,
+      2603,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2604,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2605,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2601,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2602,   -1,   -1, 2603,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2604,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2605,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 2606,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2607,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2607,   -1,   -1,
+        -1,   -1,   -1, 2608,   -1,   -1,   -1,   -1,
+      2609, 2610,   -1,   -1,   -1,   -1,   -1,   -1,
+      2611, 2612,   -1,   -1,   -1, 2613,   -1, 2614,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2608,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2615,   -1, 2616,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2609,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2610,   -1, 2611,   -1,
+      2617,   -1,   -1,   -1,   -1,   -1, 2618,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2619,   -1,
+        -1,   -1, 2620,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2612,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2621,
+        -1, 2622,   -1,   -1, 2623,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2613,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2624,   -1,   -1,   -1,
+        -1,   -1, 2625, 2626,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2627,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2628,   -1, 2629,   -1,   -1,
+        -1, 2630,   -1,   -1,   -1, 2631,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2614,
-        -1,   -1,   -1,   -1, 2615,   -1,   -1,   -1,
+        -1,   -1,   -1, 2632,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2633,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2634,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2635,   -1,   -1, 2636,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2616,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2617,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2618,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2619,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2620,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2621,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2622,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2623,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2624,   -1, 2625,   -1,   -1,   -1,
-        -1,   -1, 2626,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2627,   -1,   -1, 2628,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2629,   -1,
-        -1,   -1,   -1,   -1, 2630,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2631,   -1, 2632,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2633,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2634,   -1,   -1, 2635,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2636,
-        -1,   -1,   -1,   -1, 2637,   -1,   -1,   -1,
-        -1, 2638,   -1, 2639,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2637, 2638,   -1,   -1, 2639,   -1,   -1,
         -1,   -1, 2640,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2641,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2642,   -1,
+        -1,   -1,   -1,   -1, 2641, 2642,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2643,   -1,
+        -1,   -1,   -1, 2644,   -1,   -1,   -1,   -1,
+        -1, 2645,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2646,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2643,   -1,   -1,   -1,   -1,
+        -1, 2647,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2648,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2644,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2645,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2646,   -1,   -1,   -1,
+        -1,   -1,   -1, 2649,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2650, 2651,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2652,   -1,
+        -1,   -1,   -1, 2653,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2647,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2648,
+        -1,   -1,   -1,   -1,   -1,   -1, 2654,   -1,
+        -1,   -1,   -1,   -1,   -1, 2655,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2649,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2650,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2651,   -1,
-        -1, 2652,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2653,   -1,   -1,   -1,
-        -1,   -1,   -1, 2654,   -1,   -1, 2655,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 2656,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2657,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2658,   -1,
-      2659,   -1,   -1,   -1,   -1,   -1, 2660,   -1,
+        -1,   -1,   -1,   -1, 2657,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2661,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2662, 2663,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2658,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2659, 2660, 2661,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2662,   -1,
+        -1,   -1,   -1, 2663,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 2664,   -1,   -1,   -1,   -1,
-        -1, 2665,   -1,   -1,   -1,   -1,   -1, 2666,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2667,   -1,   -1,   -1,
-        -1, 2668,   -1,   -1,   -1,   -1,   -1, 2669,
-        -1,   -1, 2670,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2671,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2672,   -1,   -1,   -1,   -1,   -1,
-        -1, 2673,   -1, 2674,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2675,   -1,   -1,   -1,   -1, 2676,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2665,
+        -1,   -1, 2666,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2667,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2677,   -1, 2678,
+        -1,   -1, 2668,   -1,   -1,   -1,   -1,   -1,
+        -1, 2669,   -1,   -1,   -1,   -1,   -1, 2670,
+        -1,   -1,   -1,   -1,   -1,   -1, 2671, 2672,
+        -1,   -1,   -1,   -1, 2673,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2679,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2680,   -1,   -1,   -1,   -1,
+        -1,   -1, 2674, 2675,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2676,   -1,   -1,   -1, 2677,
+        -1, 2678,   -1,   -1,   -1, 2679,   -1,   -1,
+        -1, 2680,   -1,   -1, 2681, 2682,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2681,   -1, 2682,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2683, 2684,   -1,
+        -1,   -1, 2685,   -1, 2686, 2687,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2688,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2683,   -1,
-        -1,   -1,   -1,   -1, 2684,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2685,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2686, 2687,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2688,   -1,   -1,   -1,   -1, 2689,
-        -1,   -1,   -1,   -1,   -1,   -1, 2690,   -1,
-        -1, 2691,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2692, 2693,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2689,   -1, 2690,   -1,
+        -1,   -1,   -1,   -1, 2691,   -1,   -1,   -1,
+      2692,   -1,   -1,   -1, 2693,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 2694,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2695,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2695,   -1,   -1, 2696,   -1,   -1,
+        -1,   -1,   -1,   -1, 2697,   -1,   -1,   -1,
+      2698, 2699,   -1,   -1, 2700, 2701,   -1, 2702,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2696,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2697,   -1,   -1, 2698,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2699,   -1,   -1, 2700,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2701,   -1,
+        -1, 2703,   -1,   -1,   -1,   -1,   -1,   -1,
+      2704,   -1,   -1, 2705, 2706,   -1,   -1, 2707,
+        -1, 2708,   -1,   -1,   -1, 2709,   -1,   -1,
+      2710,   -1, 2711,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2712,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2713,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2702,   -1,   -1,   -1,
-        -1,   -1,   -1, 2703,   -1,   -1,   -1, 2704,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2705,   -1,   -1,   -1,
-        -1,   -1,   -1, 2706,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2707,   -1,
-        -1,   -1,   -1, 2708,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2709,   -1,
-        -1,   -1,   -1,   -1, 2710,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2711,   -1,   -1,
-      2712,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2713,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2714,   -1,   -1,   -1, 2715,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2716,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2714, 2715,   -1,   -1,   -1, 2716,   -1,
         -1, 2717,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2718,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2719,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2718,
-        -1,   -1,   -1,   -1, 2719,   -1, 2720,   -1,
+        -1,   -1, 2720,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2721,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2722,
-        -1,   -1,   -1, 2723,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2724,   -1,   -1,   -1, 2725,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2726,   -1,   -1, 2727,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2728,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2729,   -1,   -1,   -1,   -1, 2730,
-      2731,   -1,   -1,   -1,   -1, 2732,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2733,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2734,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2735,   -1,   -1, 2736,
-        -1,   -1,   -1,   -1, 2737,   -1,   -1, 2738,
-        -1,   -1,   -1,   -1,   -1,   -1, 2739,   -1,
+      2721,   -1,   -1, 2722,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2740,   -1, 2741,   -1,   -1,   -1,   -1,
+      2723,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2724,   -1,   -1,   -1,   -1,   -1, 2725,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2726,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2727,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2728,   -1,
+        -1,   -1,   -1, 2729,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2730,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2731,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2732,   -1,   -1,
+        -1, 2733,   -1,   -1, 2734,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2735,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2736,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2737, 2738,   -1,   -1,   -1,   -1,   -1,
+      2739,   -1,   -1,   -1,   -1,   -1, 2740,   -1,
+      2741,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 2742,   -1,   -1,
+        -1,   -1,   -1, 2743,   -1, 2744, 2745,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2743,   -1,   -1,   -1,
-        -1,   -1, 2744,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2745,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2746,   -1,   -1,   -1,   -1,   -1,
-        -1, 2747,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2748,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2749, 2750,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2751,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2752,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2753,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2754,   -1,   -1,
-        -1,   -1,   -1,   -1, 2755,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2756,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2746,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2757,   -1,
-        -1,   -1,   -1,   -1, 2758,   -1,   -1,   -1,
-        -1,   -1,   -1, 2759,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2747,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2748,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2749,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2760,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2750,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2761,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2751, 2752, 2753, 2754,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2755,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2756,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2757,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2758,   -1,
+        -1,   -1,   -1,   -1, 2759,   -1,   -1,   -1,
+        -1, 2760,   -1,   -1,   -1,   -1, 2761,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 2762,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2763,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2764,   -1, 2765,   -1,   -1,
+        -1,   -1,   -1, 2763,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2766,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2764,   -1,   -1,
+      2765, 2766,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 2767,   -1,   -1,
+        -1,   -1,   -1, 2768,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2768,   -1, 2769,
-        -1,   -1,   -1,   -1, 2770,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2771,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2772,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2773, 2774,   -1, 2775,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2776,   -1,   -1, 2777,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2778, 2779,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2780,
-        -1, 2781,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2782,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2783,   -1,   -1,   -1,   -1,
-        -1, 2784,   -1,   -1,   -1,   -1, 2785,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2786, 2787,   -1,
-        -1,   -1,   -1, 2788,   -1,   -1,   -1,   -1,
+        -1,   -1, 2769,   -1,   -1,   -1,   -1,   -1,
+        -1, 2770,   -1,   -1,   -1,   -1,   -1, 2771,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2789,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2790,   -1,
+        -1,   -1,   -1,   -1,   -1, 2772,   -1, 2773,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2791,   -1, 2792,   -1,   -1,   -1, 2793,
+      2774,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2775,   -1,   -1,   -1,   -1,   -1,   -1, 2776,
+        -1,   -1,   -1, 2777,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2778,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2779,   -1,
+      2780,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2781,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2782,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2783,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2784,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2785,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2786,
+        -1,   -1,   -1,   -1, 2787,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2788,   -1,   -1, 2789,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2790,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2791,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2792,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2793,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 2794,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2795,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2795,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2796,   -1,   -1,   -1,   -1,
-        -1, 2797,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2798,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2796,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2799,
-        -1,   -1,   -1,   -1, 2800,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2801,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2797,
+        -1,   -1,   -1,   -1,   -1,   -1, 2798,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2802,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2799,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2800,   -1, 2801,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2802,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 2803,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2804,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2805,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2806,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2804,   -1, 2805,   -1,   -1, 2806,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2807,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2807,   -1,   -1,   -1,   -1,
+        -1,   -1, 2808, 2809,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2808,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2810,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2809,   -1,   -1,   -1,   -1,
-        -1, 2810,   -1, 2811,   -1,   -1,   -1,   -1,
-        -1,   -1, 2812,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2811,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2812,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 2813,   -1,
+        -1,   -1,   -1,   -1, 2814,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2814,   -1,   -1,   -1,   -1, 2815,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2816,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2817,   -1, 2818,   -1,
-      2819,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2820,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2821,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2822,
+        -1, 2815,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2816, 2817,   -1, 2818,   -1,   -1, 2819,
+        -1, 2820,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2821,   -1,   -1,   -1,   -1,
+        -1,   -1, 2822,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 2823,
-        -1,   -1,   -1,   -1,   -1, 2824,   -1, 2825,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2824,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2825,   -1,   -1, 2826,   -1,   -1,   -1, 2827,
+      2828, 2829, 2830, 2831, 2832, 2833, 2834,   -1,
+      2835,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2826,   -1,
-      2827,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2836,   -1,   -1,   -1,   -1, 2837,   -1,   -1,
+        -1,   -1, 2838,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2839,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2828,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2840,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2841,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2842,
+        -1,   -1, 2843, 2844,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2845,   -1,   -1,   -1, 2846,
+        -1,   -1,   -1,   -1, 2847,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2829, 2830,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2831,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2832,   -1,   -1,   -1,   -1,   -1,   -1, 2833,
-        -1, 2834,   -1,   -1, 2835,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2836, 2837,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2838,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2839,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2840,
-        -1,   -1,   -1,   -1, 2841,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2842,   -1,   -1, 2843,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2844,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2845, 2846,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2847,
-        -1,   -1,   -1,   -1,   -1,   -1, 2848,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2848,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 2849,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2850, 2851,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2850, 2851,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2852,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2852,   -1,   -1,   -1,   -1, 2853,   -1,
-        -1,   -1,   -1,   -1,   -1, 2854,   -1,   -1,
-        -1,   -1, 2855,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2853,   -1, 2854,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2856,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2855, 2856,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2857,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2858,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2857,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2858,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 2859,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2860,   -1,   -1,   -1,   -1, 2861,
+        -1,   -1,   -1,   -1,   -1, 2862,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2860,
-        -1,   -1, 2861,   -1,   -1,   -1, 2862,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 2863,
-        -1,   -1,   -1, 2864,   -1,   -1, 2865,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2864, 2865,
+        -1, 2866,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2867,   -1,   -1,   -1,   -1,
+        -1,   -1, 2868,   -1,   -1,   -1, 2869,   -1,
+        -1,   -1,   -1, 2870,   -1,   -1,   -1,   -1,
+      2871,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2872,   -1,
+      2873,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2874,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2875,   -1,   -1,   -1,   -1, 2876,
+      2877,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2878,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2866,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2867,   -1, 2868, 2869,
-        -1, 2870,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2871,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2872,   -1,   -1,
-        -1,   -1,   -1, 2873,   -1,   -1, 2874,   -1,
-        -1,   -1,   -1,   -1, 2875,   -1,   -1,   -1,
+        -1,   -1,   -1, 2879,   -1,   -1,   -1,   -1,
+        -1,   -1, 2880,   -1, 2881,   -1, 2882,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2876,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2883, 2884,   -1,   -1,   -1,
+        -1,   -1, 2885,   -1, 2886,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2887, 2888,
+      2889, 2890,   -1,   -1,   -1,   -1, 2891,   -1,
+        -1, 2892,   -1,   -1,   -1, 2893,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2894, 2895, 2896,   -1,   -1,   -1,   -1, 2897,
+      2898, 2899,   -1,   -1,   -1,   -1,   -1, 2900,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2877,   -1,   -1, 2878,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2879,   -1, 2880,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2881,   -1,   -1,   -1,
-        -1, 2882,   -1,   -1,   -1, 2883,   -1, 2884,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2885,   -1,   -1,   -1,   -1,
-        -1,   -1, 2886,   -1,   -1, 2887,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2888,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2889,
-      2890,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2891,   -1,   -1,
-        -1,   -1,   -1,   -1, 2892,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2893,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2894,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2895,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2896,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2897,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2898,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2899,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2900,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2901,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2902,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2903,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2904,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2901,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2902,   -1,
+        -1, 2903,   -1,   -1,   -1,   -1, 2904,   -1,
         -1,   -1,   -1, 2905,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2906,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2907,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2908,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2909,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2910,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2911,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2906,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2907,   -1,   -1, 2908,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2909,
-        -1,   -1,   -1,   -1, 2910, 2911,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2912,   -1,   -1,   -1,   -1,   -1,   -1, 2913,
-        -1,   -1, 2914,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2915,   -1,   -1,   -1,   -1, 2916,
-        -1,   -1,   -1, 2917,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2918,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2919,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2912,   -1, 2913,   -1, 2914,
+        -1,   -1, 2915,   -1,   -1,   -1, 2916, 2917,
+        -1, 2918,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2919,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 2920,   -1,   -1,   -1, 2921,
-        -1,   -1, 2922,   -1,   -1, 2923,   -1,   -1,
+        -1,   -1,   -1,   -1, 2922, 2923, 2924, 2925,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2924,   -1,   -1,   -1,   -1, 2925,   -1,
         -1,   -1,   -1,   -1, 2926,   -1,   -1,   -1,
-      2927,   -1, 2928,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2929,   -1,   -1,   -1,   -1,   -1, 2930,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2931,   -1,   -1,   -1,   -1,   -1,
-        -1, 2932,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2927, 2928,   -1,
+      2929,   -1,   -1, 2930,   -1,   -1,   -1,   -1,
+        -1, 2931,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2932,
         -1,   -1,   -1, 2933,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2934,   -1,
+        -1,   -1,   -1,   -1,   -1, 2934,   -1,   -1,
+        -1,   -1,   -1,   -1, 2935,   -1, 2936,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 2937,   -1,
+        -1,   -1,   -1, 2938,   -1,   -1,   -1,   -1,
+        -1, 2939,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2940,   -1, 2941,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2942,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2943,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2935,   -1,   -1,   -1,   -1,   -1, 2936,
+        -1,   -1,   -1,   -1,   -1,   -1, 2944,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2937,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2938,
-        -1,   -1,   -1, 2939,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2940,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2941,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2942,   -1,   -1, 2943,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2944,
-        -1,   -1, 2945,   -1,   -1,   -1,   -1,   -1,
+        -1, 2945,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 2946,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2947,   -1,   -1,   -1,   -1,   -1, 2948,
-        -1,   -1,   -1,   -1,   -1, 2949,   -1,   -1,
-      2950,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2951,   -1,   -1,
-      2952,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2947, 2948, 2949,   -1,   -1,
+        -1,   -1,   -1,   -1, 2950,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2951, 2952,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2953,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2954,   -1,   -1, 2955,   -1,   -1,   -1,
+        -1,   -1,   -1, 2956,   -1,   -1,   -1,   -1,
+      2957,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2958,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2959,   -1,   -1,   -1,   -1,   -1,   -1,
+      2960,   -1,   -1,   -1,   -1,   -1, 2961,   -1,
+        -1, 2962,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2963,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2964,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2953,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2954,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2955,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2956,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2957,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2958,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2959,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2960,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 2961,   -1,
-      2962, 2963,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2964,
         -1,   -1,   -1,   -1, 2965,   -1,   -1,   -1,
+        -1,   -1,   -1, 2966,   -1,   -1,   -1, 2967,
+      2968, 2969,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2970,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 2971,   -1,   -1,
+        -1,   -1,   -1, 2972,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 2973,   -1, 2974,   -1,   -1,
+      2975,   -1, 2976,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2966,   -1, 2967,   -1,   -1,   -1, 2968,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2969,   -1, 2970,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 2971,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2972,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2973,
-        -1,   -1,   -1,   -1, 2974,   -1, 2975,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2976,
         -1,   -1,   -1,   -1,   -1, 2977,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2978,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 2979,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2980,
+        -1,   -1,   -1,   -1, 2981,   -1,   -1, 2982,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2978,   -1,   -1,   -1,
-        -1,   -1, 2979,   -1,   -1,   -1,   -1,   -1,
-        -1, 2980,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2981,   -1,   -1,   -1,   -1,   -1,
+      2983, 2984,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2985,   -1,   -1, 2986,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 2982, 2983,   -1,   -1,   -1, 2984,
-        -1,   -1, 2985,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2986,   -1,   -1,
-        -1,   -1,   -1,   -1, 2987,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2988, 2989,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 2990,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2987,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 2988,   -1, 2989,   -1,   -1,   -1, 2990,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 2991,
-        -1, 2992,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 2992,   -1,   -1,   -1,   -1,   -1,
+      2993,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      2994,   -1, 2995,   -1,   -1, 2996,   -1,   -1,
+        -1,   -1,   -1,   -1, 2997, 2998, 2999,   -1,
+        -1,   -1, 3000,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 2993,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2994,
-        -1,   -1, 2995,   -1,   -1,   -1,   -1,   -1,
+        -1, 3001,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3002,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3003, 3004,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3005,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3006,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 2996,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2997,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 2998,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      2999,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3000,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3001,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3002,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3003,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3004,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3005,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3006,   -1,   -1,   -1,   -1,   -1,   -1, 3007,
+      3007,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 3008,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3009,   -1,   -1,   -1,
+        -1,   -1,   -1, 3010,   -1,   -1,   -1,   -1,
+        -1,   -1, 3011,   -1,   -1, 3012,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3009,   -1,   -1, 3010,
-        -1,   -1,   -1,   -1, 3011,   -1,   -1,   -1,
+        -1,   -1, 3013,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3014,   -1,   -1,   -1, 3015,
+        -1, 3016, 3017,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3018,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3019, 3020,   -1,
+        -1,   -1,   -1, 3021, 3022,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3012,   -1,   -1, 3013,   -1,   -1,   -1,   -1,
+        -1, 3023,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3014,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3015,   -1,   -1,
-      3016,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3017,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3018,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3019,   -1,   -1, 3020,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3021,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3022,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3023,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3024,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3024,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 3025,   -1,   -1,   -1,   -1,   -1,   -1,
-      3026,   -1,   -1,   -1,   -1, 3027,   -1,   -1,
+        -1,   -1,   -1, 3026, 3027,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3028,   -1,   -1,   -1, 3029,   -1,   -1, 3030,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3031,
+        -1,   -1,   -1,   -1,   -1, 3032, 3033,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3034,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3028,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3029,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3035,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3036,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3030,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3031,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3037,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3032,   -1,   -1,
+      3038,   -1, 3039, 3040,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3033,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3034,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3035,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3036,   -1, 3037,   -1,   -1,
-        -1,   -1,   -1,   -1, 3038,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3039,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3040,   -1,   -1, 3041,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3041,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 3042,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3043,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3044,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3045,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3046,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3047,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3048,   -1,
+        -1, 3043, 3044,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3045,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3046,   -1,   -1,   -1,   -1,
+        -1, 3047,   -1,   -1, 3048,   -1,   -1,   -1,
         -1,   -1,   -1, 3049,   -1,   -1,   -1,   -1,
+        -1,   -1, 3050, 3051, 3052,   -1, 3053,   -1,
+        -1,   -1,   -1, 3054, 3055, 3056, 3057,   -1,
+        -1,   -1,   -1,   -1, 3058, 3059, 3060,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3050,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3061,   -1,
+        -1,   -1,   -1,   -1,   -1, 3062,   -1, 3063,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3064,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3065, 3066,   -1,
+        -1,   -1, 3067,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3068,   -1,   -1,   -1,   -1,   -1,
+      3069,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3070,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3071,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3051,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3052,   -1,
-        -1,   -1, 3053,   -1,   -1,   -1,   -1,   -1,
+        -1, 3072, 3073,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3054,   -1,   -1,   -1, 3055,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3056,   -1,   -1,
-        -1, 3057,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3058,   -1, 3059,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3060,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3061,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3062, 3063,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3064,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3065,   -1,   -1,   -1,   -1,   -1,   -1,
-      3066,   -1,   -1,   -1,   -1, 3067,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3068,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3069, 3070,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3071,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3072,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3073,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       3074,   -1, 3075,   -1,   -1,   -1,   -1,   -1,
-        -1, 3076,   -1,   -1,   -1, 3077,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3076,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3077,   -1,   -1,   -1,   -1, 3078,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3079,   -1, 3080,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3081,   -1,   -1, 3082,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3083,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3078,   -1,   -1,   -1,   -1,   -1,   -1,
-      3079,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3084,   -1,   -1,
+        -1,   -1, 3085, 3086,   -1,   -1,   -1, 3087,
+        -1,   -1,   -1,   -1, 3088,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3089,   -1,   -1, 3090,
+        -1,   -1,   -1,   -1, 3091,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3080,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3081,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3082,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3083,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3084,   -1, 3085,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3086,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3087, 3088,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3089,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3090,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3091,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 3092,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3093,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3093,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3094,
+      3095,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3096,   -1,   -1,   -1,   -1,   -1,
+      3097,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3094,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3095,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3096,   -1,   -1,   -1,
+        -1, 3098,   -1,   -1,   -1,   -1, 3099,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3100,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3097,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3098,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3099,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3100,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3101,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3101,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 3102,   -1,   -1,
+        -1,   -1, 3103, 3104,   -1,   -1,   -1,   -1,
+        -1, 3105,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3106, 3107,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3108,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3103,   -1,   -1, 3104,   -1,   -1,
-        -1,   -1,   -1,   -1, 3105,   -1,   -1,   -1,
+      3109,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3110,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3106,   -1,   -1, 3107,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3108,   -1,
+        -1, 3111, 3112,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3113,   -1,
+        -1,   -1, 3114,   -1, 3115, 3116,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3109,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3110,   -1,
-        -1,   -1,   -1, 3111, 3112,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3113,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3114,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3115,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3116,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3117,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3118,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3117,   -1,   -1,   -1,   -1,
+        -1, 3118,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 3119,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3120, 3121,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3122,
+        -1,   -1,   -1,   -1,   -1,   -1, 3123,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3124,   -1,   -1, 3125,   -1,
+        -1,   -1,   -1, 3126,   -1,   -1,   -1,   -1,
+        -1,   -1, 3127,   -1,   -1, 3128,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3129,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3130,   -1,
+        -1,   -1,   -1,   -1, 3131, 3132,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3133,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3134,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3120,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3121,   -1, 3122,   -1,   -1,   -1,   -1,   -1,
-      3123,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3135,   -1,   -1, 3136,
+      3137,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3138,   -1, 3139,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3140,   -1,   -1,   -1, 3141,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3142,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3143,   -1, 3144,   -1,   -1,   -1,
+        -1,   -1, 3145,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3146,   -1,   -1,
+        -1, 3147,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3148,   -1,
+        -1,   -1,   -1,   -1, 3149,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3150,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3124,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3125,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3126,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3127,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3128,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3129,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3130,   -1,   -1,   -1,   -1,   -1,
-      3131,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3132,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3133,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3134,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3135,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3136,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3137,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3138,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3139, 3140,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3141,
-        -1,   -1,   -1, 3142,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3143,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3144,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3145,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3146,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3147,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3148,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3149,   -1,   -1,   -1, 3150,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3151,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3152,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3153,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3151,
+        -1,   -1,   -1, 3152, 3153,   -1,   -1,   -1,
         -1,   -1, 3154,   -1,   -1,   -1,   -1,   -1,
-      3155,   -1,   -1, 3156,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3155,   -1,   -1,   -1,   -1,   -1,   -1, 3156,
+        -1, 3157,   -1,   -1,   -1,   -1,   -1, 3158,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3157,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3158,
+        -1, 3159,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3160,   -1,   -1, 3161,   -1,   -1, 3162,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3163,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3159,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3160,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3161,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3162,   -1, 3163,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3164,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3164,   -1, 3165, 3166,   -1,
+      3167,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3168,   -1,
+        -1, 3169, 3170,   -1, 3171,   -1,   -1,   -1,
+        -1,   -1,   -1, 3172,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3173,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3165,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3174,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3166,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3167,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3168,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3175, 3176,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3169,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3177,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3178,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3179,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3170,   -1,   -1, 3171,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3172,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3180,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3173,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3181,
+        -1, 3182,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3183,   -1,   -1,   -1,   -1,
+        -1, 3184,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3185,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3186,   -1,
+        -1, 3187,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3188,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3189,   -1,   -1,
+      3190,   -1,   -1, 3191,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3192,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3174,   -1,
-        -1,   -1,   -1,   -1,   -1, 3175,   -1,   -1,
-      3176,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3177,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3178,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3179,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3180,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3181,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3182,   -1,   -1,   -1,   -1,   -1,
-      3183,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3184,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3185,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3186,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3187,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3188,   -1, 3189,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3190,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3193,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3191,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3192,   -1, 3193,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 3194,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3195, 3196,   -1,   -1,   -1,   -1,   -1, 3197,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3198,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3199,   -1,   -1,   -1,   -1,   -1, 3200,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3201,   -1,   -1, 3202,
-        -1, 3203,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3204,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3205,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3206,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3207,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3208,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3195,   -1,   -1,   -1, 3196,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3209,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3210,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3197,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3198,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3199,
+        -1,   -1,   -1,   -1,   -1,   -1, 3200,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3211,   -1,   -1, 3212,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3213,
-        -1, 3214,   -1,   -1, 3215,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3216,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3217,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3201,   -1,   -1,   -1,
+        -1,   -1, 3202, 3203,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3204,   -1,   -1,   -1,   -1,   -1,   -1,
+      3205,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3206,   -1,
+        -1,   -1,   -1,   -1,   -1, 3207,   -1,   -1,
+        -1,   -1, 3208,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3209,   -1, 3210, 3211,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3218,
+        -1,   -1, 3212,   -1,   -1,   -1, 3213,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3214,   -1,
+      3215,   -1,   -1,   -1,   -1,   -1, 3216,   -1,
+        -1, 3217,   -1,   -1,   -1, 3218,   -1,   -1,
+        -1, 3219,   -1, 3220,   -1,   -1,   -1,   -1,
+        -1, 3221,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3219,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3220,   -1, 3221,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3222,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3222,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3223,   -1,
+        -1,   -1,   -1,   -1,   -1, 3224,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3223,
-        -1,   -1,   -1,   -1, 3224,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3225,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3226,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3227,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3228,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3229,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3230,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3225,   -1,   -1,   -1, 3226,   -1,
+        -1,   -1,   -1, 3227,   -1, 3228,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3229,   -1, 3230,
         -1,   -1,   -1,   -1,   -1,   -1, 3231,   -1,
+        -1,   -1, 3232,   -1,   -1,   -1,   -1,   -1,
+      3233, 3234,   -1,   -1,   -1,   -1,   -1,   -1,
+      3235,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3236,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3237,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3238,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3239,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3232,   -1,   -1,   -1,   -1,
-      3233,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3234,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3235,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3236,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3237,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3238,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3239,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 3240,   -1,   -1,   -1,   -1,
+      3241,   -1,   -1,   -1,   -1,   -1, 3242,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3243,   -1, 3244,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3241, 3242,   -1, 3243,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3245,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3246,   -1,   -1,   -1,   -1, 3247,
+        -1,   -1,   -1, 3248,   -1, 3249,   -1, 3250,
+        -1,   -1,   -1, 3251,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3252,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3253,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3244,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3245,
-        -1,   -1, 3246,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3247,   -1,   -1,   -1, 3248,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3249,   -1,
-        -1,   -1, 3250,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3254,   -1,   -1, 3255,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3256,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3257,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3258,   -1,
+        -1,   -1,   -1, 3259,   -1,   -1,   -1,   -1,
+      3260, 3261,   -1,   -1, 3262,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3263,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3251,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3252,   -1,   -1,   -1,   -1,   -1,   -1,
-      3253,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3254,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3255,   -1,   -1,
-        -1,   -1,   -1, 3256,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3257,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3258,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3259,   -1,
-        -1,   -1,   -1,   -1, 3260,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3261,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3262,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3263,   -1,   -1,   -1,
-        -1,   -1, 3264,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3265,   -1,   -1,   -1,   -1,
-        -1, 3266,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3264,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3267,   -1,   -1,   -1, 3268,   -1,
-        -1, 3269,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3270,   -1,   -1,
-        -1, 3271,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3265,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3266, 3267,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3268,   -1,   -1, 3269,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3272,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3273,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3274,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3270, 3271, 3272,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3275,   -1,
-        -1, 3276,   -1,   -1, 3277,   -1,   -1,   -1,
+      3273, 3274,   -1,   -1,   -1, 3275,   -1,   -1,
+        -1,   -1, 3276, 3277,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3278,   -1,   -1,
+        -1,   -1, 3279,   -1,   -1,   -1,   -1,   -1,
+        -1, 3280,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3278,   -1,
+        -1,   -1, 3281,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3282, 3283,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3284,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3285,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3286,
+        -1,   -1, 3287,   -1,   -1, 3288,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3279,   -1,   -1,
+        -1,   -1,   -1,   -1, 3289,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3290,   -1,   -1,   -1,
+        -1,   -1, 3291, 3292,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3280,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3293,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3281,   -1,   -1,   -1,   -1,   -1, 3282,
+      3294, 3295,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3283,   -1,   -1,   -1,   -1,   -1, 3284,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3285,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3286,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3287,   -1,   -1,   -1, 3288,
-        -1,   -1,   -1,   -1,   -1, 3289,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3290,   -1, 3291,   -1,
-        -1,   -1, 3292,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3293,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3294,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3295,   -1, 3296,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3297,   -1,   -1,
-        -1,   -1,   -1,   -1, 3298,   -1,   -1,   -1,
-        -1, 3299, 3300,   -1,   -1, 3301,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3302,   -1,   -1, 3303,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3304,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3305,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3306,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3307,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3308,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3309,   -1,
-        -1, 3310,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3311,   -1, 3312,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3313,   -1,   -1,   -1,   -1,   -1,   -1, 3314,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3315,   -1,   -1,   -1,
-        -1,   -1, 3316,   -1, 3317,   -1,   -1,   -1,
+        -1,   -1,   -1, 3296,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3297,   -1,
+        -1, 3298,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3318,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3299,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3300,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3301, 3302,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3319,   -1,   -1,   -1,   -1,
+        -1,   -1, 3303,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3320,   -1, 3321,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3322,
-        -1,   -1,   -1,   -1, 3323,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3304,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3305,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3324,   -1,   -1,   -1,   -1,   -1,
+      3306,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3307,   -1,
+        -1,   -1, 3308,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3309, 3310,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3311,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3312,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3325,   -1, 3326,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3327,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3313,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3314,   -1, 3315,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3328,   -1,   -1,   -1,   -1,   -1, 3329,
-        -1, 3330,   -1,   -1,   -1,   -1,   -1,   -1,
+      3316,   -1,   -1,   -1, 3317, 3318,   -1,   -1,
+        -1,   -1, 3319,   -1,   -1,   -1, 3320,   -1,
+        -1,   -1, 3321,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3322,   -1,   -1, 3323,   -1, 3324,   -1,
+        -1, 3325, 3326,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3331,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3327,
+        -1,   -1,   -1,   -1,   -1,   -1, 3328,   -1,
+        -1,   -1,   -1,   -1, 3329,   -1,   -1,   -1,
+        -1,   -1,   -1, 3330,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3331,
         -1, 3332,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3333,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3334,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3335,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3336,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3333,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3334,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3335,   -1,   -1,   -1, 3336,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 3337,
+      3338,   -1,   -1,   -1,   -1,   -1,   -1, 3339,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3340,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3338,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3341,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3342,
+      3343,   -1,   -1,   -1,   -1,   -1, 3344,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3345,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3339,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3340,   -1,   -1, 3341,   -1,   -1,   -1,   -1,
-      3342,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3343,   -1,   -1, 3344,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3345,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3346,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3347,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3348,   -1,   -1,   -1,   -1, 3349,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3350,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3346, 3347,   -1,   -1,
+        -1, 3348,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3349,   -1,   -1,   -1, 3350,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 3351,
+        -1,   -1,   -1,   -1, 3352,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3353,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3354, 3355,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3356,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3357,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3358,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3359,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3360,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3361,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3362,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3363,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3364,   -1,   -1,   -1,   -1,
+        -1, 3365,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3366, 3367,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3368,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3352,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3353,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3354,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3355,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3356,   -1,   -1, 3357,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3358,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3359,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3360,   -1,
-        -1,   -1,   -1,   -1, 3361,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3362,   -1,   -1,
-        -1,   -1,   -1, 3363,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3364,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3365,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3366,   -1,   -1,   -1,   -1, 3367,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3368,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 3369,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3370,
-        -1, 3371,   -1,   -1,   -1,   -1,   -1,   -1,
-      3372,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3373,   -1,
-        -1,   -1, 3374,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3375,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3376,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3377,   -1,
+        -1,   -1,   -1,   -1,   -1, 3370,   -1, 3371,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3372,
+        -1,   -1,   -1, 3373,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3374,   -1,   -1,   -1,   -1, 3375,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3376,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3377,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 3378,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3379,   -1,
+        -1, 3379,   -1,   -1,   -1,   -1,   -1, 3380,
+        -1,   -1,   -1,   -1,   -1, 3381,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3380,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3381,   -1, 3382,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3382,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 3383,   -1,   -1,   -1,   -1,   -1,
-      3384, 3385,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3386,   -1,   -1,   -1, 3387,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3388, 3389,   -1,   -1, 3390,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3391,
-        -1,   -1, 3392,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3393, 3394,   -1,   -1,   -1,   -1,
-        -1, 3395,   -1,   -1, 3396,   -1,   -1,   -1,
+        -1,   -1, 3384,   -1,   -1,   -1,   -1, 3385,
+        -1,   -1, 3386,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3397,   -1,   -1,   -1,   -1,   -1, 3398,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3399,   -1,
-        -1,   -1, 3400,   -1,   -1,   -1,   -1, 3401,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3402,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3403,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3404,   -1,   -1,   -1,   -1,   -1, 3405,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3406,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3407,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3387,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3388,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3389,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3390,   -1, 3391,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3392,   -1,   -1,   -1,
+        -1, 3393,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3394,   -1,   -1,   -1,
+      3395,   -1,   -1,   -1,   -1,   -1,   -1, 3396,
+        -1,   -1,   -1,   -1,   -1,   -1, 3397,   -1,
+        -1,   -1,   -1, 3398,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3399,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3400,   -1,   -1,
+        -1,   -1, 3401,   -1,   -1, 3402,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3403, 3404,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3405,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3406,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3407,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 3408,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3409,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3410,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3409,   -1,   -1,   -1,   -1, 3410,   -1,   -1,
+      3411,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3411,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 3412,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3413,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3413,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3414,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3415,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3416,   -1,   -1,   -1, 3417,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3418,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3419,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3420,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3421,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3422,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3423,   -1,   -1,   -1,
-        -1, 3424,   -1,   -1,   -1,   -1, 3425,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3414,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3426,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3415,   -1, 3416,   -1, 3417,   -1,
+        -1,   -1,   -1,   -1, 3418,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3427,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3428,   -1,   -1,   -1,   -1,
-      3429,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3430,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3431, 3432,   -1,
-      3433,   -1,   -1,   -1, 3434,   -1,   -1, 3435,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3436,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3437,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3438,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3439,   -1,   -1,
-        -1,   -1, 3440,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3441,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3442,   -1,   -1, 3443, 3444,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3419,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3445,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3420,   -1, 3421,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3422,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3423,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3424,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3425,   -1, 3426,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3427, 3428,
+        -1,   -1,   -1,   -1, 3429, 3430,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3431,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3432,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3433,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3434,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3435,   -1, 3436,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3437,   -1,
+        -1, 3438, 3439,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3440,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3441,   -1,   -1,   -1,   -1, 3442,   -1,
+        -1,   -1, 3443,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3444,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3445,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 3446,   -1,
-        -1,   -1,   -1,   -1, 3447,   -1,   -1,   -1,
-        -1, 3448,   -1,   -1,   -1, 3449,   -1,   -1,
+      3447, 3448,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3450,   -1,   -1,   -1,   -1,
-        -1, 3451,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3449,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3450,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3452,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3453,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3454,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3451,   -1,   -1,   -1,   -1,
+      3452,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3453,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3454,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 3455,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 3456,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3457,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3457,
         -1,   -1,   -1,   -1,   -1, 3458,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3459,   -1,   -1,
+      3460,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3459,   -1,   -1,   -1, 3460,   -1,
-        -1,   -1,   -1, 3461,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3461,   -1,   -1,   -1,   -1,   -1,   -1,
       3462,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3463,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3464,   -1, 3465,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3463,   -1,
+      3464,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3465,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3466, 3467,   -1,   -1,   -1, 3468,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3466, 3467,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3468,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3469,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3470,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3471,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3472,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3473,   -1,
-        -1, 3474,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3475,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3469,
+        -1,   -1,   -1, 3470,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3476,   -1,
+        -1,   -1, 3471,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3472,
+        -1,   -1,   -1,   -1, 3473,   -1, 3474,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3477,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3478,   -1,   -1, 3479,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3480,   -1,   -1,   -1,   -1,
-      3481,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3475, 3476,
+        -1,   -1,   -1,   -1,   -1,   -1, 3477,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3482,   -1, 3483,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3484,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3485,   -1,   -1,   -1,
+      3478,   -1,   -1,   -1,   -1,   -1, 3479,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3480,   -1,   -1,   -1, 3481,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3482,   -1,   -1,   -1,   -1,   -1, 3483,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3484,
+        -1,   -1,   -1, 3485,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 3486,   -1,   -1,
+        -1,   -1,   -1,   -1, 3487,   -1,   -1, 3488,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3489,
+        -1,   -1,   -1,   -1, 3490,   -1,   -1, 3491,
+        -1,   -1,   -1, 3492,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3493,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3487,   -1,   -1,   -1,   -1,   -1, 3488,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3489,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3490,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3491,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3492,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3493,   -1,   -1, 3494,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3495,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3496,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3497,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3498,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3494,
+      3495,   -1,   -1, 3496,   -1, 3497,   -1,   -1,
+        -1,   -1,   -1,   -1, 3498,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 3499,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       3500,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3501,   -1,   -1,   -1,   -1, 3502,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3501,
+        -1,   -1, 3502,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3503,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3504,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3505,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3503,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3504,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3505,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3506,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3507,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3508,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3509,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3510,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3511,   -1,   -1,   -1,
-      3512,   -1,   -1, 3513,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3514,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3515,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3516,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3517,   -1,   -1,
+        -1,   -1,   -1,   -1, 3506,   -1,   -1, 3507,
+      3508,   -1,   -1, 3509,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3510,   -1, 3511,   -1,
+      3512,   -1,   -1,   -1,   -1,   -1,   -1, 3513,
+      3514, 3515,   -1,   -1, 3516,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3517,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       3518,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3519,   -1,   -1,   -1,
+        -1,   -1, 3520, 3521,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3522,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3523,   -1,   -1,   -1, 3524,   -1,
+        -1,   -1,   -1,   -1, 3525,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3519,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3520,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3521,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3522,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3523,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3524,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3525,   -1,   -1, 3526,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3527,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3526,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3527,
         -1,   -1,   -1,   -1,   -1,   -1, 3528,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3529,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3529,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3530,   -1,   -1,   -1,   -1,
+        -1, 3530,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3531,   -1, 3532,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3531,
+        -1,   -1,   -1,   -1, 3532,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3533,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3533,   -1,   -1,
+        -1, 3534,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3534,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3535,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3536, 3537,   -1,   -1,
+      3538,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3535, 3536,   -1,   -1,   -1,   -1,   -1,
-      3537,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3538,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3539,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3539,   -1,   -1,   -1,   -1,   -1, 3540,
+        -1,   -1,   -1,   -1,   -1, 3541,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3540,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3541,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       3542,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3543,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3544,   -1,   -1,   -1,
+        -1,   -1, 3545,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3546,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3547,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3548,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3549,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3550,   -1,   -1,   -1,   -1,
+        -1, 3551,   -1,   -1,   -1,   -1,   -1,   -1,
+      3552,   -1,   -1,   -1,   -1,   -1,   -1, 3553,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3543,   -1,   -1,   -1,
-      3544,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3545,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3546,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3547,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3548,   -1,   -1,   -1,   -1,
+        -1, 3554,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3555,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3549,   -1,   -1,
-      3550,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3551,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3552,   -1, 3553,   -1,   -1,
-      3554,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3555,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3556,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3556,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 3557,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3558,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3559,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3558, 3559,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 3560,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3561,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3562,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3563,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3564,   -1,   -1,   -1,   -1,
-        -1, 3565,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3566,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3567,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3568,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3569,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3570,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3571,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3572,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3573,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3574,   -1,   -1,   -1,   -1, 3575,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3576,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3561,   -1,   -1,
+      3562,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3563,   -1,
+        -1,   -1,   -1,   -1,   -1, 3564,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3565,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3566,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3567,   -1, 3568,   -1,   -1,   -1, 3569,   -1,
+      3570,   -1,   -1,   -1,   -1, 3571,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3577,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3572,   -1,
+      3573,   -1,   -1,   -1,   -1, 3574,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3575,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3576, 3577,   -1,   -1,
         -1,   -1,   -1, 3578,   -1,   -1,   -1,   -1,
+        -1,   -1, 3579,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3579,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3580,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3581, 3582,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3583,   -1, 3584,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3580,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3581,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3582,   -1,   -1, 3583,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3584,   -1,   -1,
-        -1,   -1,   -1, 3585,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3586,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3587,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3585,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3586,   -1,   -1, 3587,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 3588,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3589,   -1,   -1,   -1,   -1,
+        -1,   -1, 3590,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3591,   -1, 3592,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3593,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3594,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3595,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3596,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3597,   -1,   -1,   -1,   -1, 3598,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3599, 3600,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3601,   -1,   -1, 3602,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3589,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3603,   -1,
+        -1,   -1,   -1,   -1,   -1, 3604, 3605,   -1,
+      3606, 3607,   -1,   -1,   -1,   -1,   -1,   -1,
+      3608,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3590,   -1,   -1,   -1,
+      3609,   -1, 3610,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3611,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3591,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3592,   -1,   -1,   -1,   -1,   -1, 3593,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3594,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3595,   -1,   -1,
-      3596,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3597,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3598,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3599,   -1,
-        -1,   -1, 3600,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3601,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3602,
-        -1, 3603,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3604,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3605,   -1,   -1,   -1,   -1,   -1, 3606,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3607,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3608,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3609,
-      3610,   -1,   -1,   -1,   -1,   -1, 3611,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3612,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3613,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3612,   -1,   -1,   -1,   -1, 3613,   -1,
       3614,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3615,
+        -1,   -1,   -1,   -1,   -1,   -1, 3616,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3615,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3616,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3617,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3618,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3619,   -1,   -1,   -1,
-      3620,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3621,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3622,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3623,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3624, 3625,   -1,
-        -1, 3626,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3627,   -1,   -1,   -1,
-        -1, 3628,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3617, 3618,   -1,   -1,   -1, 3619,   -1,
+        -1,   -1,   -1, 3620, 3621,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3622,   -1,   -1,
+        -1, 3623, 3624,   -1,   -1,   -1, 3625,   -1,
+        -1,   -1,   -1, 3626,   -1,   -1,   -1,   -1,
+      3627,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3628,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 3629,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3630,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3631,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3632,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3633,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3634,   -1,   -1,   -1, 3635,   -1,
+        -1,   -1,   -1, 3636,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3637,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3638,   -1,
+      3639,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3630,   -1,   -1,
-      3631,   -1,   -1,   -1,   -1,   -1, 3632,   -1,
+        -1,   -1,   -1,   -1, 3640,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3641,   -1,
+      3642,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3643,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3644,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3633,   -1,   -1,   -1,   -1,   -1, 3634,   -1,
-        -1, 3635,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3636,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3637,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3645,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3638,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3646, 3647,   -1, 3648,   -1,   -1,
+        -1,   -1,   -1, 3649,   -1, 3650,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3651,   -1,   -1,   -1,   -1,
+      3652,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3639,   -1,
-      3640,   -1,   -1,   -1,   -1,   -1, 3641,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3642,   -1,   -1,
-        -1,   -1, 3643,   -1,   -1,   -1,   -1,   -1,
-        -1, 3644,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3645, 3646,   -1,   -1,   -1,   -1, 3647,
-      3648,   -1, 3649,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3650,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3651,   -1,
-        -1,   -1,   -1, 3652,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3653,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3653,
         -1,   -1,   -1,   -1, 3654,   -1,   -1,   -1,
-        -1,   -1, 3655,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3656,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3655,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3656,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3657,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3658,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3659,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3660,   -1,
+        -1, 3657,   -1, 3658,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3659,   -1,   -1,   -1,   -1,
+        -1,   -1, 3660,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 3661,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3662,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3663,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3664,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3665,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3666,   -1,   -1,   -1,   -1,   -1,
+      3662, 3663,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3664,   -1, 3665,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3666, 3667,   -1,   -1,
+        -1, 3668,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3669,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3670,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3671, 3672,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3673,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3674,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3675,   -1, 3676,
+        -1,   -1, 3677,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3667,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3668,   -1,
-        -1,   -1,   -1, 3669,   -1,   -1,   -1, 3670,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3671,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3672,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3673,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3674,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3675,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3676,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3677,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 3678,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3679,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3680,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3679,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3680,   -1,
       3681,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3682,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3683,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3682,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3683,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3684, 3685, 3686,   -1,   -1,   -1,   -1, 3687,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3684,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3685,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3686,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3687,   -1,   -1,
-      3688,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3689,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3690,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3691,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3692,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3688,   -1,   -1,   -1,   -1,   -1, 3689,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3690,   -1,   -1,   -1, 3691, 3692,   -1,
         -1,   -1,   -1,   -1,   -1, 3693,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3694,
-      3695,   -1,   -1,   -1,   -1,   -1,   -1, 3696,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3697,   -1,   -1,   -1,   -1,   -1,
+        -1, 3694,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3695,   -1,   -1,   -1,   -1, 3696,
+      3697,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 3698,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3699,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3699,   -1,   -1,   -1,
+        -1,   -1,   -1, 3700,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3701,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3702,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3700,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3703,   -1,   -1, 3704,   -1,   -1,
+        -1,   -1,   -1, 3705,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3701,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3702,
-        -1,   -1, 3703,   -1,   -1,   -1,   -1,   -1,
-        -1, 3704,   -1,   -1, 3705,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3706,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3707,   -1,
-      3708,   -1,   -1,   -1,   -1,   -1, 3709,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3710,   -1,   -1,   -1,
+        -1,   -1,   -1, 3706,   -1,   -1,   -1, 3707,
+        -1,   -1,   -1,   -1, 3708,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3709,   -1,
+        -1,   -1,   -1, 3710,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 3711,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3712,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3713,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3712, 3713,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 3714,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3715,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3716,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3717,   -1,   -1,   -1,   -1,   -1,
+      3715,   -1, 3716,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3717, 3718,   -1,   -1, 3719,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3718,   -1,   -1,   -1,
-        -1,   -1, 3719,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3720,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3721,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3722,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3723,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3724,   -1,   -1,   -1,   -1,
-        -1, 3725,   -1,   -1,   -1,   -1,   -1, 3726,
+        -1,   -1,   -1, 3720,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3721,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3727,   -1,   -1,   -1,   -1,   -1, 3728,   -1,
+        -1,   -1, 3722,   -1,   -1,   -1, 3723,   -1,
+        -1, 3724,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3725,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3726,   -1, 3727,   -1,   -1,   -1, 3728,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3729,   -1,   -1,   -1,   -1,   -1, 3730,
+      3729,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3730, 3731,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3732,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3731,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3732,   -1,   -1,   -1,   -1,
         -1, 3733, 3734,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3735,   -1,   -1,
+        -1,   -1,   -1,   -1, 3735, 3736,   -1,   -1,
+        -1,   -1,   -1, 3737,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3738,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3739,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3736,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3737,   -1,   -1,   -1,   -1, 3738,   -1,
+      3740,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3739,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3740,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3741,   -1,   -1,   -1,
-        -1,   -1, 3742,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3743,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3744,
-        -1, 3745,   -1,   -1,   -1,   -1,   -1, 3746,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3747,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3748,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3749,   -1,   -1,   -1,   -1,   -1,
-        -1, 3750,   -1,   -1,   -1,   -1,   -1, 3751,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3752,   -1,   -1,   -1,   -1,
-        -1, 3753,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3754,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3755,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3741, 3742,
+        -1,   -1, 3743,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -33358,369 +30856,273 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3744,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3745,
+        -1,   -1,   -1,   -1, 3746,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3747,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3748,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3756,   -1,   -1,   -1,   -1,   -1,
+        -1, 3749,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3750,
+        -1,   -1,   -1,   -1,   -1, 3751,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3757,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3752,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3753,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3754,   -1,   -1,   -1,
+      3755,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3756,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3757,   -1,
+        -1,   -1,   -1, 3758,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3759,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3758,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3759,
-        -1,   -1, 3760,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3760,
         -1,   -1,   -1,   -1, 3761,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 3762,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3763,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3764,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3765,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3766,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3767,   -1, 3768,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3769,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3770,   -1,   -1,   -1,
+      3771, 3772,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3773,
+      3774, 3775,   -1,   -1,   -1,   -1,   -1, 3776,
+        -1,   -1,   -1,   -1,   -1, 3777,   -1,   -1,
+        -1,   -1,   -1, 3778,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3779,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3763,   -1, 3764,   -1,
-      3765,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3780,   -1,
+        -1,   -1,   -1, 3781,   -1,   -1, 3782,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3783,   -1,   -1,
+        -1,   -1,   -1,   -1, 3784,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3785,   -1,   -1,   -1, 3786,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3787,   -1,   -1, 3788,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3789,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3766,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3790,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3791,   -1, 3792,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3767,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3768,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3769,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3770,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3771,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3772,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3773,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3774,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3775,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3776,   -1,   -1,   -1,   -1,   -1,
-      3777,   -1,   -1,   -1,   -1,   -1, 3778,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3779,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3780,   -1, 3781,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3782,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3783,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3784,   -1,   -1, 3785,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3786,   -1,   -1,
-        -1,   -1, 3787,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3788,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3789,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3790,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3791,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3792,   -1,   -1,   -1, 3793,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3793,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 3794,
-        -1,   -1,   -1,   -1,   -1, 3795,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3796,
-      3797,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3795,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3798,   -1,
-        -1,   -1,   -1,   -1, 3799,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3800,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3801,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3802,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3803,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3804,
+        -1, 3796,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3797,   -1, 3798,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3799, 3800,   -1, 3801,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3802,   -1,   -1,   -1,   -1,   -1,   -1, 3803,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3804,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       3805,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3806,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3807,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3806,   -1,
+      3807,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3808,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3809,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3810,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3811,   -1,   -1,   -1, 3812,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3808,   -1,   -1,   -1,   -1,
+        -1, 3813,   -1,   -1, 3814,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3815,   -1,   -1,   -1,
+        -1,   -1, 3816,   -1,   -1,   -1, 3817,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3809, 3810,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3811,   -1,   -1,
-        -1, 3812,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3818,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3813,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3814,   -1, 3815, 3816,   -1,   -1,
+        -1,   -1, 3819,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3820,   -1,
+        -1,   -1,   -1,   -1,   -1, 3821,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3817,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3818,   -1,
-        -1,   -1, 3819,   -1,   -1, 3820,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3821,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3822,   -1,   -1,   -1,   -1,   -1,   -1,
+      3822,   -1,   -1,   -1,   -1,   -1,   -1, 3823,
+        -1,   -1,   -1,   -1,   -1,   -1, 3824,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3825,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3823,
-      3824,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3825,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3826,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3827,   -1,
+        -1,   -1,   -1,   -1,   -1, 3828,   -1,   -1,
+        -1,   -1,   -1,   -1, 3829,   -1,   -1, 3830,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3831,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3832,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3833, 3834,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3826,   -1,   -1,   -1,   -1,   -1,
+        -1, 3835,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3836,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3837,   -1,   -1,
+      3838,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3839,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3827,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3828,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3840,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3841,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3829,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3842,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3843,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3830,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3844,   -1, 3845,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3831,
+        -1,   -1, 3846,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3832,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3833,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3834,
-        -1,   -1, 3835,   -1,   -1,   -1,   -1, 3836,
-        -1, 3837,   -1,   -1,   -1,   -1, 3838,   -1,
-        -1,   -1,   -1,   -1,   -1, 3839,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3847,   -1,   -1,
+        -1,   -1,   -1,   -1, 3848,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3849,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3850,
+        -1, 3851,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3852,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3853,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3854,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3840,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3841,   -1,   -1,   -1, 3842,   -1, 3843,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3844,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3845,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3846,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3847,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3848,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3849,   -1,
-        -1, 3850,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3851,
-        -1, 3852,   -1, 3853,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3854,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3855,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3856,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3857,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3858,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3859,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3860,   -1,
-        -1,   -1, 3861,   -1,   -1, 3862,   -1,   -1,
+        -1,   -1,   -1,   -1, 3855,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3856, 3857,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3863,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3858,   -1,   -1,   -1,   -1,   -1,   -1,
+      3859,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3860,   -1,   -1,   -1, 3861,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3862,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3864,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3863,   -1,   -1,
+        -1,   -1,   -1,   -1, 3864,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3865,   -1, 3866,   -1,
+        -1, 3867,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3868,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3865,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3866,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3867,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3868,   -1,   -1,   -1,   -1,   -1,   -1,
-      3869,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3870,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3871,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3869,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3870,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3871,   -1,   -1, 3872,   -1,   -1, 3873,
+        -1,   -1,   -1,   -1, 3874,   -1,   -1, 3875,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3872,
-        -1,   -1,   -1,   -1, 3873,   -1, 3874,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3875,
-        -1,   -1,   -1,   -1,   -1,   -1, 3876,   -1,
+        -1,   -1,   -1,   -1,   -1, 3876,   -1,   -1,
         -1,   -1, 3877,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3878,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3879,   -1, 3880,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3881,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3882,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3883,
-        -1,   -1,   -1,   -1, 3884,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3885,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3886,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3887,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3888,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3889,   -1,   -1,   -1,   -1,   -1, 3890,   -1,
-        -1, 3891,   -1,   -1, 3892,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3893,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3894,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3895,
+        -1,   -1,   -1,   -1, 3878,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3879,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3880,
+        -1,   -1,   -1,   -1, 3881,   -1, 3882,   -1,
+        -1,   -1,   -1, 3883,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3884,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -33729,157 +31131,151 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3885,   -1,   -1, 3886,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3887,   -1,   -1,   -1,   -1,   -1,
+      3888,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3889,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3890,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3891,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3892,   -1,   -1,
+        -1,   -1,   -1,   -1, 3893,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3896,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3894,   -1,
+        -1, 3895,   -1,   -1, 3896,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 3897,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3898,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3899,   -1,   -1,   -1,
-        -1,   -1, 3900,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3901,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3898, 3899,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3900,   -1,   -1,   -1,   -1,   -1, 3901,
         -1,   -1, 3902,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 3903,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3904,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3905,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3904,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3905,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3906,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3906,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 3907,   -1,
-      3908,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3909,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3910,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3908,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3909,
+        -1,   -1, 3910,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3911,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3911, 3912,   -1, 3913,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3914,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3912, 3913,   -1,   -1,   -1, 3914,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 3915,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3916,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3916,   -1,   -1, 3917,   -1,   -1,
+        -1,   -1,   -1,   -1, 3918,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3917,   -1,   -1, 3918,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3919, 3920,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3921,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3922,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3919,   -1,
+        -1,   -1, 3923,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3920,   -1,   -1,   -1,
+        -1,   -1,   -1, 3924, 3925,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3926,
+        -1,   -1, 3927,   -1,   -1,   -1, 3928,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3921,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3922,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3923,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3924,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3925,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3926,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3927,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3928,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3929, 3930,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3929,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3930,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 3931,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3932,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3933,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3932,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3933,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3934,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3934,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3935,   -1,   -1,   -1, 3936,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3935,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3936,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 3937,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3938,   -1,   -1, 3939,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3940,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3941,
+        -1,   -1,   -1,   -1,   -1,   -1, 3938,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3939,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3940,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3942,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3943,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3941, 3942,   -1,   -1, 3943,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3944,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3945,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3946, 3947,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3944,   -1, 3945, 3946,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3947,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 3948,   -1,
-        -1,   -1,   -1,   -1, 3949,   -1,   -1,   -1,
-      3950,   -1, 3951,   -1,   -1,   -1,   -1,   -1,
-      3952,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3949,   -1, 3950,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3951,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3952,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3953,   -1,
+        -1,   -1,   -1, 3954,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3955,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -33888,49 +31284,27 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3956, 3957,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3958,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3953,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3954,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3955,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3956,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3957,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3958,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 3959,   -1,   -1,   -1,   -1,
+      3960,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3961,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3962,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3960,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3963,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3964,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3965,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3966,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -33940,141 +31314,84 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3961,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3962,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3963,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3964,   -1,
-      3965,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3966,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3967,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3968, 3969,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3970,
-        -1,   -1,   -1,   -1,   -1, 3971,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3972,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 3967,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 3968,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3969,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3973,   -1,
+        -1,   -1, 3970,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      3971,   -1, 3972,   -1,   -1,   -1,   -1, 3973,
         -1,   -1,   -1, 3974,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 3975,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3976,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3977,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3978,   -1, 3979,   -1,   -1,   -1,
-        -1, 3980,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3981,   -1,
-        -1, 3982,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3983,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3984,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 3985, 3986,   -1,
+        -1, 3975,   -1,   -1, 3976,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3977,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3978,   -1,
+      3979, 3980,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3981,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3982,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3983,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3984,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3985,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 3986,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3987,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3988,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 3987,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3988,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 3989,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3989,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 3990,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3991,
+        -1,   -1,   -1,   -1,   -1,   -1, 3992,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3993,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 3994,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 3995, 3996,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3991,   -1, 3992,   -1,   -1,   -1, 3993,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 3994,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3995,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      3996,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 3997,   -1,
+        -1,   -1,   -1,   -1,   -1, 3997,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       3998,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 3999,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4000,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4001,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4002, 4003,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 3999,
-        -1, 4000,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4001,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4002,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4003,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4004,   -1,   -1,   -1,   -1,
+        -1,   -1, 4005,   -1,   -1,   -1, 4006,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -34085,31 +31402,17 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4004,   -1, 4005,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4006,
+        -1, 4007,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4007,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4008,   -1,
+        -1,   -1,   -1,   -1, 4008,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4009,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4010,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4009,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4010,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4011,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4012,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4013,   -1,
+      4011,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -34118,29 +31421,29 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4014,   -1,   -1,   -1,   -1,   -1, 4015,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4012,
+        -1, 4013,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4014,   -1,
+        -1, 4015,   -1,   -1,   -1,   -1,   -1, 4016,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4017,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4016,   -1,   -1, 4017,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4018,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4018,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 4019,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4020,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -34148,349 +31451,288 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4020,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4021,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4022,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4023,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4024,   -1, 4025,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4026,   -1,   -1,   -1,   -1, 4027,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4021,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4022,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4023,   -1,
+        -1,   -1,   -1,   -1, 4024,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4025,   -1,   -1,   -1, 4026,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4027,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 4028,   -1,
+        -1,   -1,   -1,   -1,   -1, 4029,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4030,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4029,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4030,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4031,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4032,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4033,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4034,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4035,   -1,   -1,   -1,   -1, 4036, 4037,
+      4031, 4032, 4033,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4034,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4035,   -1,
+        -1,   -1,   -1, 4036,   -1, 4037,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       4038,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 4039,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4040,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4041,   -1,   -1,   -1,
+        -1,   -1, 4040,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4041,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4042,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4043,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4042,
+        -1,   -1,   -1,   -1, 4044,   -1, 4045,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4043,   -1, 4044,   -1,   -1,   -1, 4045,
-        -1,   -1,   -1,   -1,   -1, 4046,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4047,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4048,   -1,   -1,   -1,
+      4046,   -1,   -1,   -1, 4047,   -1,   -1,   -1,
+        -1, 4048,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4049, 4050,   -1,   -1,   -1,   -1,   -1,
+        -1, 4051,   -1,   -1,   -1,   -1, 4052,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4049,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4050,
-        -1,   -1,   -1, 4051,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4053,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4052,   -1,   -1,   -1,   -1,   -1,
-      4053,   -1,   -1,   -1, 4054,   -1,   -1,   -1,
+        -1,   -1,   -1, 4054,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4055,   -1,
+        -1, 4055,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4056,   -1,   -1, 4057,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4056,   -1,   -1,   -1,   -1,
+        -1, 4058,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4059,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4057,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4058, 4059,   -1,   -1,   -1,   -1,   -1,
         -1, 4060,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4061,   -1,   -1,   -1,   -1,   -1, 4062,
-        -1,   -1,   -1,   -1, 4063,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4064,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4065,   -1,
-        -1,   -1,   -1, 4066,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4067,   -1,   -1,
-        -1,   -1,   -1, 4068,   -1,   -1,   -1,   -1,
+        -1,   -1, 4061,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4069,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4062,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4070, 4071,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4072,   -1,   -1,
-        -1, 4073,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4074,   -1,   -1, 4075,   -1,   -1,
+        -1, 4063,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4076,   -1, 4077,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4064,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4065,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4066,   -1,
+        -1,   -1, 4067,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4068,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4069,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4070,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4071,   -1,   -1,   -1,   -1,
+        -1,   -1, 4072,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4078,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4079,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4073,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4074,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4075,   -1,   -1,
+        -1, 4076,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4080,   -1,   -1,   -1,   -1,
+      4077,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4078,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4079,   -1, 4080,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4081,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4081,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4082,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4083,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4082,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4083,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       4084,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 4085,   -1,   -1,   -1,
-        -1,   -1, 4086,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4086,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4087,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4088,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4087, 4088,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4089,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4089,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4090,   -1,   -1,   -1, 4091,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4090,   -1,   -1,
+        -1,   -1, 4091,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4092,   -1,   -1,   -1,   -1,
+        -1, 4093,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4094,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4095,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4096,   -1,   -1,   -1,   -1,
+        -1, 4097,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4092,   -1,   -1,
+      4098,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4099,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4100,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4101,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4102,   -1,   -1,
+        -1,   -1, 4103,   -1,   -1, 4104,   -1,   -1,
+        -1,   -1,   -1, 4105,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4106,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4107,   -1,   -1, 4108,   -1,   -1,   -1,
+        -1,   -1, 4109,   -1, 4110,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4093,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4094,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4111,   -1,   -1, 4112,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4113,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4095,   -1,
-        -1, 4096,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4097,
-        -1,   -1, 4098,   -1,   -1, 4099,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4114,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4100,
-        -1,   -1,   -1, 4101,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4102,   -1,
-        -1,   -1,   -1, 4103,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4104,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4105,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4106,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4107,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4108,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4109,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4110,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4111,   -1,   -1,   -1,   -1,
-        -1, 4112,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4113,   -1,   -1,
-        -1,   -1,   -1, 4114,   -1,   -1, 4115,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4116,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4117,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4118,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4119,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4120,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4121,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4122,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4115,   -1,   -1,   -1,   -1, 4116,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4117,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4118,
+        -1,   -1,   -1,   -1,   -1, 4119,   -1,   -1,
+        -1,   -1, 4120,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4121,   -1,   -1, 4122,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 4123,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4124,
+        -1,   -1,   -1,   -1,   -1,   -1, 4124,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4125,   -1,   -1,   -1,   -1,   -1,   -1, 4126,
-        -1, 4127,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4128,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4129,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4130,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4131,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4132,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4133,   -1,   -1,   -1,   -1, 4134,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4135,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4125,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4126,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4127,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4128,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4129,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4130,   -1,
+        -1, 4131,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4132,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4136,   -1,   -1,   -1,   -1,   -1, 4137,   -1,
-        -1,   -1,   -1,   -1, 4138,   -1, 4139,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4140,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4141,   -1,   -1,
+        -1,   -1,   -1,   -1, 4133,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4142,   -1,   -1,   -1,
-      4143,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4134,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4135, 4136,   -1,   -1,   -1,   -1,   -1, 4137,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4144,   -1,
+        -1, 4138,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4145,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4139,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4140,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4141,   -1, 4142,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4143,   -1,   -1,   -1,   -1,   -1,   -1, 4144,
+      4145,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 4146,   -1,   -1,
-      4147,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4147,   -1,   -1,
         -1, 4148,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4149,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4149,   -1,   -1,   -1,   -1,
         -1, 4150,   -1,   -1,   -1,   -1, 4151,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4152,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4152,   -1,   -1,   -1,   -1, 4153,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4154,   -1,   -1,   -1,   -1, 4155,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4156,   -1,   -1,   -1,
+      4157,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4158,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4159,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4160,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4161,
+        -1,   -1,   -1,   -1, 4162,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4153,   -1,
+        -1, 4163,   -1,   -1,   -1,   -1,   -1, 4164,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4165,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4154,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4166,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4167,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4155,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4156,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4168,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -34499,1021 +31741,725 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4157,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4158,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4159,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4160,   -1,   -1,   -1,   -1,
+        -1, 4169,   -1,   -1,   -1, 4170,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4171,   -1,   -1,
+        -1,   -1, 4172,   -1,   -1,   -1,   -1,   -1,
+      4173,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4174, 4175,   -1,
+      4176,   -1,   -1,   -1,   -1, 4177,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4178,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4179,   -1,   -1,   -1,
+        -1,   -1,   -1, 4180,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4161,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4162,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4163,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4164,   -1,   -1,   -1,   -1, 4165,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4166,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4167,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4168,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4169,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4170,   -1,   -1,   -1,   -1, 4171,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4172,   -1,   -1, 4173,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4174,   -1,   -1, 4175,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4176,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4177,   -1,   -1,
-        -1,   -1,   -1, 4178,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4179,   -1,   -1,
-        -1,   -1, 4180,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4181,   -1,
+        -1,   -1,   -1,   -1,   -1, 4181,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 4182,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4183,
+        -1, 4184,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4185,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4186,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4187, 4188,
+        -1,   -1,   -1,   -1,   -1, 4189,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4183,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4190,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4191, 4192,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4193,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4184,
+        -1,   -1, 4194,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4195,   -1,
+        -1,   -1,   -1,   -1, 4196,   -1,   -1, 4197,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4198,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4199,   -1,   -1,   -1,
+        -1,   -1, 4200,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4185,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4201,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4202,   -1,   -1,   -1,   -1,
+      4203,   -1,   -1,   -1,   -1,   -1,   -1, 4204,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4186,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4187,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4188,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4205,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4206,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4189,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4207,   -1,   -1, 4208,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4190,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4209,   -1,   -1,   -1,   -1,   -1,
+      4210,   -1,   -1,   -1,   -1,   -1, 4211,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4191,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4192,   -1,   -1,   -1,
+        -1,   -1, 4212,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4213,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4193,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4214,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4215,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4216,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4217,   -1, 4218,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4219,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4220,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4221,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4194,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4195,   -1,   -1,   -1,   -1,   -1, 4196,
-        -1, 4197,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4198,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4199,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4200,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4201,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4202,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4203,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4204,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4205,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4206,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4207,   -1,   -1,   -1,   -1, 4208,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4209, 4210,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4211,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4212,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4213,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4214,   -1,   -1, 4215,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4216,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4217,   -1,   -1,   -1,   -1,   -1, 4218,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4219,   -1,   -1,   -1,   -1,   -1, 4220,   -1,
-      4221,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4222,   -1,   -1,   -1,
-        -1, 4223,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4222,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4223,   -1, 4224,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4224,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4225,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4225,   -1,
+        -1,   -1,   -1,   -1,   -1, 4226,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4227,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4226,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4227,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4228,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4228,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4229,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4229,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 4230,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4231,   -1,   -1, 4232,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4233,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4234,
-        -1,   -1,   -1, 4235,   -1, 4236,   -1,   -1,
-      4237,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4238,   -1,   -1,
-      4239,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4240,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4241,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4242,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4231,   -1,   -1,   -1,
+        -1,   -1,   -1, 4232,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4233, 4234,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4235,   -1,
+        -1,   -1, 4236,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4237,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4238,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4239,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4240,   -1,   -1,
+        -1, 4241,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4242,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 4243,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4244,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4244,   -1,   -1,
+        -1,   -1,   -1, 4245,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4245,   -1, 4246,   -1,   -1,   -1,
+        -1,   -1,   -1, 4246,   -1, 4247,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4248,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4249,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4250,   -1,
+        -1,   -1,   -1,   -1, 4251,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4247,   -1,   -1,   -1,   -1, 4248, 4249,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4250,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4251,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 4252,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 4253,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4254,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4255,   -1,   -1, 4256,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4257,   -1,
-        -1, 4258,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4259,   -1,
-        -1,   -1,   -1,   -1, 4260,   -1,   -1,   -1,
-      4261,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4262,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4254,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4263,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4255,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4256,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4264,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4265,   -1,   -1,   -1,   -1,
+        -1, 4257,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4258,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4266,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4267, 4268,   -1,   -1,   -1, 4269,   -1,
-        -1, 4270,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4259,
+        -1,   -1,   -1, 4260,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4271,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4272,
-        -1,   -1,   -1,   -1, 4273,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4261,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4262,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4263,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4264,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4265,   -1,
+      4266,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4267,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4268,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4269,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4270,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4271,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4272,   -1, 4273,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 4274,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 4275,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4276,   -1,   -1,   -1, 4277,   -1,   -1,   -1,
-        -1,   -1, 4278,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4279,   -1,
+        -1,   -1,   -1,   -1,   -1, 4276,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4280,   -1,   -1,
-        -1,   -1,   -1, 4281,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4282,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4283,   -1,   -1,   -1,   -1,   -1, 4284,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4285, 4286,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4287,   -1,   -1,   -1,   -1,
+        -1,   -1, 4277,   -1, 4278,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4279,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4288,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4280,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4289,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4290,   -1,   -1,   -1, 4291,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4292, 4293,   -1,   -1,
-      4294,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4281,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4295,   -1,   -1, 4296,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4297,   -1,   -1,   -1,   -1,
-        -1,   -1, 4298,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4299,   -1, 4300,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4301,   -1, 4302, 4303,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4282,   -1, 4283,   -1,   -1,   -1,   -1, 4284,
+        -1,   -1,   -1, 4285,   -1, 4286,   -1, 4287,
+        -1, 4288, 4289,   -1,   -1,   -1,   -1,   -1,
+        -1, 4290,   -1,   -1,   -1,   -1,   -1,   -1,
+      4291,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4292,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4293,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4294,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4304,   -1, 4305,   -1,   -1,   -1,   -1,   -1,
-        -1, 4306,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4307,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4308,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4295,   -1,   -1,
+        -1,   -1, 4296,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4309,   -1, 4310,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4311,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4312, 4313,   -1,   -1,
-        -1,   -1,   -1, 4314,   -1, 4315,   -1,   -1,
+      4297,   -1,   -1,   -1,   -1, 4298,   -1,   -1,
+      4299,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4300,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4301,   -1,   -1,   -1,   -1,   -1, 4302,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4316,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4317,   -1,   -1,   -1, 4318,
-        -1,   -1, 4319,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4303,   -1,   -1, 4304,
+        -1, 4305, 4306,   -1,   -1,   -1, 4307,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4308,   -1, 4309,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4310,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4311,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4312,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4320,   -1,   -1,   -1,   -1,
+        -1, 4313,   -1,   -1,   -1,   -1,   -1,   -1,
+      4314,   -1,   -1,   -1,   -1,   -1, 4315,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4321,   -1,   -1,
+        -1,   -1, 4316,   -1,   -1, 4317,   -1,   -1,
+      4318,   -1,   -1,   -1,   -1,   -1,   -1, 4319,
+        -1,   -1,   -1,   -1,   -1, 4320, 4321,   -1,
+        -1,   -1, 4322,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4323,   -1,   -1,
+        -1,   -1, 4324,   -1,   -1,   -1,   -1,   -1,
+      4325,   -1,   -1,   -1,   -1,   -1, 4326,   -1,
+        -1,   -1,   -1, 4327,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4328,
+        -1,   -1, 4329,   -1,   -1,   -1,   -1,   -1,
+      4330,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4322,
-      4323,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4324,   -1,
+      4331,   -1,   -1, 4332,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4333,
+        -1,   -1,   -1, 4334, 4335,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4336,   -1,   -1, 4337,
+        -1,   -1, 4338,   -1, 4339,   -1,   -1,   -1,
+        -1,   -1, 4340,   -1, 4341,   -1,   -1,   -1,
+        -1, 4342,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4343,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4344,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4345,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4346,   -1,   -1, 4347,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4348,   -1,   -1,   -1,   -1,
+      4349,   -1,   -1,   -1,   -1, 4350, 4351,   -1,
+        -1, 4352,   -1,   -1,   -1, 4353,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4325,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4326,
-        -1,   -1, 4327,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4328,   -1,   -1, 4329,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4354,
+      4355, 4356,   -1, 4357,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4358,   -1, 4359,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4360,
+        -1,   -1, 4361,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4362,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4330,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4363,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4331,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4332,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4333, 4334,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4335,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4336,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4337,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4338,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4339,   -1,   -1,   -1,
-        -1, 4340,   -1,   -1,   -1,   -1,   -1,   -1,
-      4341,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4342,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4343,   -1,   -1, 4344,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4345,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4346,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4347, 4348,   -1,
-        -1,   -1,   -1,   -1,   -1, 4349,   -1,   -1,
-        -1, 4350,   -1,   -1, 4351,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4352,   -1,   -1,   -1,   -1, 4353,   -1,
-        -1,   -1,   -1,   -1,   -1, 4354,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4355,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4356,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4357,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4358,   -1,   -1,
-        -1, 4359,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4360,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4361,   -1,   -1,   -1,   -1, 4362,
-        -1,   -1, 4363,   -1,   -1,   -1,   -1,   -1,
-      4364,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4365,   -1,   -1,   -1, 4366,
-      4367,   -1, 4368,   -1,   -1,   -1, 4369,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4370,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4371,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4372,
-        -1,   -1,   -1,   -1, 4373,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4374,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4375,   -1,   -1,   -1,
+        -1, 4364,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4365,   -1,   -1,   -1,   -1,   -1, 4366,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4367,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4368,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4369,
+        -1,   -1, 4370,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4371,
+        -1,   -1,   -1, 4372,   -1,   -1, 4373,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4374,   -1, 4375,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 4376,   -1,
+        -1,   -1,   -1,   -1, 4377,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4377,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4378,   -1,   -1, 4379,   -1,
-        -1, 4380,   -1, 4381,   -1,   -1,   -1,   -1,
-        -1, 4382,   -1,   -1,   -1,   -1,   -1, 4383,
-      4384,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4385,   -1,   -1,   -1,   -1,   -1, 4386,
+        -1,   -1,   -1,   -1,   -1, 4378,   -1,   -1,
+        -1,   -1,   -1,   -1, 4379,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4380,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4381,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4382,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4383,   -1,   -1, 4384,   -1,   -1,
+        -1,   -1,   -1,   -1, 4385,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4386,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4387,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4388, 4389,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4390,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4391,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4387,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4392,   -1, 4393,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4388,   -1,   -1,   -1,   -1,
-        -1,   -1, 4389,   -1, 4390,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4394,
+        -1,   -1,   -1,   -1,   -1,   -1, 4395,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4396,   -1,   -1,   -1, 4397,
+      4398,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4399, 4400,   -1, 4401,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4402,   -1, 4403,   -1,   -1, 4404,
+        -1,   -1, 4405,   -1, 4406,   -1,   -1,   -1,
+        -1,   -1, 4407,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4408,   -1,   -1, 4409,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4391,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4392,   -1,   -1,   -1,
-        -1,   -1,   -1, 4393,   -1,   -1,   -1,   -1,
-        -1, 4394,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4395,   -1,   -1,
-      4396,   -1,   -1, 4397,   -1,   -1,   -1,   -1,
+      4410,   -1,   -1, 4411, 4412,   -1,   -1,   -1,
+      4413,   -1, 4414,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4415,
+        -1,   -1,   -1,   -1, 4416,   -1,   -1,   -1,
+        -1,   -1, 4417,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4398,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4399,   -1,   -1,
-        -1, 4400,   -1, 4401,   -1,   -1,   -1,   -1,
+      4418,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4419,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4420,   -1,   -1,   -1,   -1,
+        -1,   -1, 4421,   -1, 4422,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4423,   -1,   -1,   -1,   -1,
+      4424, 4425, 4426,   -1,   -1,   -1,   -1, 4427,
+        -1,   -1,   -1, 4428,   -1,   -1,   -1,   -1,
+        -1, 4429,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4430,   -1,   -1,   -1,
+        -1, 4431,   -1,   -1,   -1, 4432,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4402,   -1,   -1, 4403,   -1,   -1,   -1, 4404,
-        -1, 4405,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4406,   -1,
-      4407,   -1,   -1,   -1,   -1,   -1,   -1, 4408,
+        -1,   -1,   -1, 4433, 4434,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4435,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4436,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4409,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4410,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4437,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4411,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4412,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4413,   -1,   -1,   -1,
-        -1,   -1, 4414,   -1,   -1, 4415,   -1,   -1,
-        -1, 4416,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4417,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4418,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4419,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4420,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4421,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4422,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4423,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4424,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4425,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4426,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4427,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4428,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4429,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4430,
-      4431,   -1,   -1,   -1,   -1, 4432,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4433,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4434,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4435,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4436,   -1,   -1, 4437,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4438,   -1,   -1,   -1,   -1,   -1,   -1, 4439,
-        -1,   -1,   -1,   -1,   -1, 4440,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4441,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4438,
+      4439,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4440, 4441,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 4442,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4443,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4443,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4444,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4444,
         -1,   -1,   -1,   -1, 4445,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4446,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4447,   -1,   -1,   -1,   -1,   -1,
+      4448,   -1,   -1,   -1,   -1, 4449,   -1,   -1,
+        -1, 4450,   -1, 4451,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4452,   -1,   -1,   -1,   -1,   -1, 4453,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4446,   -1,   -1,   -1,   -1,   -1,
-        -1, 4447,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4448,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4449,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4450,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4451,   -1,   -1,   -1,   -1,   -1, 4452,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4453,   -1,   -1,   -1,
-      4454,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4455,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4456,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4457,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4458,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4454,   -1,   -1,   -1, 4455, 4456,
+        -1,   -1, 4457,   -1,   -1,   -1,   -1,   -1,
+        -1, 4458,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 4459,   -1,   -1,   -1,   -1,
+        -1,   -1, 4460, 4461,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4462,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4460,   -1,   -1, 4461,   -1,   -1,
-      4462,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4463,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4464,   -1,
-        -1,   -1,   -1,   -1, 4465,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4466,   -1,   -1,   -1,
+      4463,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4464,
+        -1,   -1, 4465,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4466,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4467,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4468,   -1,   -1,   -1,   -1,   -1, 4469,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4470,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4467,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4471,   -1,   -1,
+      4468,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4469,   -1,   -1,
+        -1,   -1, 4470,   -1,   -1, 4471,   -1,   -1,
+        -1,   -1, 4472,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4473,   -1,   -1, 4474,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4472,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4473,   -1,   -1,   -1,   -1,   -1,
-      4474,   -1,   -1,   -1,   -1,   -1, 4475,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4475,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 4476,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4477,   -1,   -1, 4478,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4477,   -1, 4478,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 4479,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 4480,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 4481,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       4482,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4483,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4483,   -1,   -1,   -1,
+        -1, 4484,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4485,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4486,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4484,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4487,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4485,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4488,   -1,   -1,
+        -1,   -1, 4489,   -1,   -1,   -1,   -1, 4490,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4486,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4487,   -1,   -1,
+        -1, 4491, 4492,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4493,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4494,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4488,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4495,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4496,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4497,   -1,   -1,   -1, 4498,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4489,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4499,
+        -1,   -1,   -1,   -1,   -1, 4500,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4490,   -1,   -1,   -1,
+      4501,   -1,   -1,   -1,   -1, 4502,   -1,   -1,
+      4503,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4491,   -1,   -1,   -1,   -1,   -1, 4492,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4504,   -1,   -1,   -1,
+        -1,   -1, 4505,   -1,   -1,   -1,   -1,   -1,
+      4506,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4507,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4493,
-        -1,   -1, 4494,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4495,   -1,   -1,   -1,   -1, 4496,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4497,   -1,   -1,   -1,   -1,
-        -1, 4498,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4499,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4500,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4501,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4502,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4503,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4508, 4509,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4510,   -1, 4511,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4504,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4505,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4506,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4507,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4512,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4513,   -1, 4514,   -1,   -1,   -1,   -1,   -1,
+        -1, 4515,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4516,
+        -1,   -1, 4517,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4508,   -1,
-      4509, 4510,   -1,   -1,   -1,   -1,   -1, 4511,
-        -1,   -1, 4512,   -1,   -1,   -1,   -1, 4513,
-      4514,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4515,   -1,   -1,   -1, 4516,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4518,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4519,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4520,   -1,   -1,   -1, 4521, 4522,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4523,   -1,
+        -1, 4524,   -1,   -1, 4525,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4517,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4518,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4519,   -1,   -1,
+      4526,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4527,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4528,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4529,
+        -1,   -1,   -1,   -1, 4530,   -1,   -1,   -1,
+      4531,   -1,   -1,   -1, 4532,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4533,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4534,
+        -1,   -1,   -1, 4535,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4536,   -1,
+        -1,   -1,   -1,   -1,   -1, 4537,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4538,   -1,   -1,
+        -1, 4539,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4540,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4541,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4520,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4521,
-        -1,   -1, 4522,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4542,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4523,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4543,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4544,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4545,   -1,   -1,   -1,
+        -1, 4546,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4547, 4548,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4524,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4549,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4525,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4526,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4550,   -1, 4551, 4552,   -1,   -1,   -1,   -1,
+        -1,   -1, 4553,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4554,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4555,   -1, 4556,   -1,
+        -1,   -1,   -1,   -1, 4557,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4558,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4527,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4559,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4560,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4528,   -1,   -1, 4529,
-        -1, 4530,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4561, 4562,   -1,   -1,   -1,   -1,   -1,
+        -1, 4563,   -1,   -1,   -1,   -1, 4564,   -1,
+        -1,   -1, 4565,   -1,   -1, 4566,   -1, 4567,
+        -1,   -1,   -1,   -1,   -1,   -1, 4568,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4569,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4570,   -1,
+        -1,   -1,   -1,   -1, 4571,   -1,   -1, 4572,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4531,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4532,
+        -1,   -1, 4573,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4574,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4575,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4576,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4577,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4533,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4534,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4535,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4536,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4537,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4538,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4539,   -1,   -1,   -1,
-        -1,   -1,   -1, 4540,   -1,   -1,   -1,   -1,
-        -1, 4541,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4542,   -1,   -1,
-      4543,   -1,   -1, 4544,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4545,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4546,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4547,   -1,
-      4548,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4549,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4550,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4551,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4552,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4553,   -1, 4554,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4555,   -1,   -1, 4556,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4557,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4558,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4559,   -1,   -1, 4560,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4561,   -1,   -1,   -1,   -1,
-        -1,   -1, 4562,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4563,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4564,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4565,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4566,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4567,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4568,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4569,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4570,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4571,   -1,   -1,
-      4572,   -1,   -1, 4573,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4574,   -1,   -1,   -1,   -1, 4575,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4576,
-      4577,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4578,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4579,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4580,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4581,   -1, 4582,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4583, 4584,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4585,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4586,
+        -1,   -1,   -1,   -1, 4578, 4579,   -1,   -1,
+        -1,   -1, 4580,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4581,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4582,   -1, 4583,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4587,   -1,
-        -1,   -1,   -1,   -1, 4588,   -1,   -1,   -1,
+        -1,   -1, 4584,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4589,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4585,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4586,   -1,
+        -1,   -1,   -1, 4587,   -1,   -1,   -1,   -1,
+      4588,   -1,   -1,   -1,   -1,   -1, 4589,   -1,
+      4590,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4591,   -1,   -1,   -1,   -1,   -1, 4592,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4593,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4594,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4590,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4595, 4596, 4597,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4598,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4599,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4591,   -1, 4592,
-        -1,   -1,   -1, 4593,   -1,   -1,   -1,   -1,
-      4594, 4595,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4600,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4596,
-        -1,   -1,   -1,   -1,   -1, 4597, 4598,   -1,
-      4599, 4600,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4601,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4601,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4602, 4603,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4602,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4603,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 4604,   -1,   -1,
-        -1,   -1,   -1, 4605,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4605,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4606,   -1,   -1,   -1, 4607,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4608,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4609,
-        -1,   -1,   -1,   -1,   -1, 4610,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4606,
+        -1,   -1,   -1,   -1,   -1, 4607,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4611,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4612,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4613,
+      4608, 4609, 4610,   -1, 4611,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4612,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4614,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4613,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4615,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4616,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4617,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4618,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4619,   -1,   -1, 4620,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4621,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4614,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -35523,459 +32469,357 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4622,   -1,   -1,   -1,   -1,
-        -1,   -1, 4623,   -1, 4624,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4625,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4615,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4626,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4627,   -1,   -1,   -1,   -1,
+        -1, 4616,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4617,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4618, 4619,
+        -1,   -1, 4620,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4628,   -1,   -1,
-        -1,   -1, 4629,   -1,   -1, 4630,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4631,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4632,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4633,
-        -1,   -1,   -1,   -1, 4634,   -1,   -1, 4635,
+        -1,   -1, 4621,   -1,   -1,   -1, 4622,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4636,   -1,   -1,   -1,   -1, 4637,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4623,   -1,   -1,   -1, 4624,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4625,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4626,   -1,   -1, 4627,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4628,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4629,   -1, 4630,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4631,
+        -1,   -1,   -1,   -1,   -1, 4632,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4633,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4634,   -1,
+        -1,   -1,   -1,   -1,   -1, 4635,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4636,   -1,   -1,   -1,   -1, 4637,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 4638,   -1,
-        -1, 4639,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4639,   -1,   -1,   -1, 4640,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4641,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4642,   -1,   -1, 4643,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4644,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4640,   -1,   -1,   -1,
+        -1,   -1, 4645,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4646,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4647,   -1, 4648,
+        -1,   -1, 4649,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4650,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4651,   -1,   -1,   -1,   -1,
+        -1,   -1, 4652,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4653,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4641,   -1,   -1,   -1,
-        -1,   -1, 4642,   -1,   -1,   -1,   -1,   -1,
-      4643,   -1,   -1, 4644,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4645,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4646,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4647,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4648,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4649,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4650,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4651,   -1, 4652,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4653,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 4654,
-        -1, 4655,   -1,   -1,   -1, 4656,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4655,
+        -1,   -1,   -1,   -1,   -1,   -1, 4656, 4657,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4657,   -1,
-        -1,   -1,   -1,   -1, 4658, 4659,   -1,   -1,
+        -1, 4658,   -1, 4659,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4660,   -1,   -1,   -1,
-      4661,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4662,   -1,   -1,   -1,
-        -1, 4663,   -1,   -1,   -1,   -1,   -1, 4664,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4665,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4666,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4667,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4668,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4669,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4660,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4670,   -1,   -1,   -1,   -1,
-        -1, 4671,   -1,   -1,   -1,   -1,   -1, 4672,
-        -1,   -1,   -1,   -1,   -1,   -1, 4673,   -1,
+        -1,   -1,   -1,   -1,   -1, 4661,   -1,   -1,
+      4662,   -1, 4663, 4664,   -1,   -1,   -1,   -1,
+        -1, 4665,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4666,   -1, 4667, 4668,
+        -1, 4669,   -1,   -1,   -1,   -1,   -1, 4670,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4671,   -1,   -1,
+        -1,   -1, 4672,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4673, 4674,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4674,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4675,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4676,
-        -1,   -1,   -1,   -1,   -1,   -1, 4677,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4675,
+        -1, 4676, 4677,   -1,   -1,   -1,   -1, 4678,
+        -1,   -1,   -1, 4679,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4680,   -1,
+        -1,   -1,   -1, 4681, 4682,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4683,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4684,   -1,   -1,   -1,   -1,
+        -1, 4685, 4686,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4687,   -1,
+        -1,   -1,   -1,   -1,   -1, 4688,   -1,   -1,
+        -1,   -1,   -1,   -1, 4689,   -1,   -1,   -1,
+        -1,   -1, 4690,   -1,   -1, 4691, 4692, 4693,
+      4694, 4695,   -1,   -1,   -1,   -1, 4696,   -1,
+        -1,   -1,   -1, 4697,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4698,   -1,
+        -1, 4699,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4700,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4678,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4679,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4680,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4681,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4682,   -1,   -1, 4683,
-        -1, 4684,   -1,   -1,   -1,   -1,   -1, 4685,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4686,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4687,   -1,   -1,   -1,
-        -1,   -1, 4688,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4689,   -1,   -1,   -1,   -1,   -1,
-      4690,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4691,
-        -1,   -1,   -1,   -1, 4692,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4693,   -1,   -1,   -1,
-        -1, 4694,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4695,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4696,
-        -1,   -1, 4697,   -1,   -1,   -1,   -1,   -1,
-      4698,   -1,   -1,   -1,   -1,   -1,   -1, 4699,
-      4700,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 4701,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4702,   -1,   -1,   -1,   -1,   -1, 4703, 4704,
+      4705,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4702,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4703,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4704,   -1,   -1,   -1,
+        -1,   -1, 4706,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4707,   -1,   -1,
+      4708,   -1,   -1,   -1,   -1,   -1,   -1, 4709,
+      4710,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4711,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4712,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4705,   -1,   -1, 4706,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4707,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4708,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4709,   -1, 4710,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4711,   -1,   -1, 4712,   -1,
         -1, 4713,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4714,   -1,   -1,   -1, 4715,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4716,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4714,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4715,
-        -1,   -1, 4716,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4717,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4717,   -1, 4718,   -1,
-      4719,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4718,   -1,   -1, 4719, 4720,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4721,   -1,   -1,   -1,   -1,   -1,   -1,
+      4722,   -1, 4723,   -1, 4724,   -1,   -1,   -1,
+        -1, 4725, 4726,   -1,   -1,   -1,   -1,   -1,
+        -1, 4727,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4728,   -1,   -1,   -1,   -1,   -1, 4729,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4720,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4730,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4731,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4732,   -1,
+        -1,   -1,   -1, 4733,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4734,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4721,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4722,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4723,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4724,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4725,
-        -1,   -1,   -1, 4726,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4727,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4728,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4729,   -1,   -1,   -1,   -1,
-      4730,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4731,   -1,   -1, 4732,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4733, 4734,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4735,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4735,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 4736,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 4737,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4738, 4739,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4738,   -1,   -1,   -1,   -1, 4739,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4740,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4740,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 4741,   -1,
-        -1, 4742,   -1, 4743,   -1,   -1,   -1,   -1,
-        -1,   -1, 4744,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4742, 4743,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4744,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4745,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4746,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4747,   -1,   -1,   -1,   -1,   -1, 4748,
+        -1, 4749,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4750,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4751,   -1,   -1,
+        -1,   -1, 4752,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4745,   -1,   -1,
-        -1,   -1,   -1,   -1, 4746,   -1,   -1,   -1,
+        -1,   -1, 4753,   -1,   -1,   -1, 4754,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4755,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4756,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4747,   -1,
-        -1, 4748,   -1,   -1, 4749,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4750,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4751,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4752,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4753,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4754,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4755,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4756,   -1,   -1, 4757,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4757,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 4758,   -1,   -1,
+      4759, 4760, 4761,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4762,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4763,
+        -1,   -1,   -1, 4764,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4765, 4766, 4767,   -1,
+        -1,   -1, 4768,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4769,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4770,
+        -1,   -1,   -1,   -1,   -1,   -1, 4771,   -1,
+        -1, 4772,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4773,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4774,   -1,   -1,   -1,   -1,   -1, 4775,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4759,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4760,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4761,   -1,   -1,   -1,
-        -1,   -1, 4762,   -1,   -1, 4763,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4764,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4765,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4766,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4767,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4768,   -1,   -1, 4769,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4770,   -1,   -1,   -1,
+      4776,   -1,   -1,   -1,   -1, 4777,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4778,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4779,   -1, 4780,
+      4781,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4782,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4783,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4771,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4772,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4773,
-        -1,   -1,   -1, 4774,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4775,   -1,   -1, 4776,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4777,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4778,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4779,   -1,
-        -1,   -1,   -1, 4780,   -1,   -1,   -1, 4781,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4782,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4783,   -1,   -1,
-        -1,   -1,   -1,   -1, 4784,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4784,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 4785,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       4786,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4787,   -1,   -1, 4788,   -1,   -1, 4789,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4787,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4790,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4788,   -1,   -1, 4789,
+        -1,   -1,   -1, 4790,   -1,   -1,   -1,   -1,
+      4791,   -1,   -1,   -1, 4792,   -1,   -1,   -1,
+      4793,   -1, 4794,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4795,   -1,   -1,   -1,   -1, 4796,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4791,   -1,   -1,   -1,
+        -1,   -1,   -1, 4797,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4792,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4793,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4794,   -1,   -1, 4795,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4796,
-        -1,   -1,   -1,   -1,   -1, 4797,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4798,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4798,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 4799,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4800,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4801,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4802,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4800,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4801,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4802,   -1,   -1,   -1,
         -1,   -1, 4803,   -1,   -1,   -1,   -1,   -1,
-        -1, 4804,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4805,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4806,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4807,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4808,   -1,
-        -1,   -1,   -1,   -1,   -1, 4809,   -1,   -1,
-        -1,   -1, 4810,   -1,   -1, 4811,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4812,   -1, 4813,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4814,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4804, 4805,
+        -1,   -1,   -1,   -1,   -1, 4806,   -1,   -1,
+        -1,   -1, 4807,   -1,   -1,   -1, 4808,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4809,   -1,   -1,   -1,   -1, 4810,
+        -1,   -1,   -1, 4811,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4812,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4813,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4814,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 4815,   -1,   -1,
-        -1, 4816,   -1,   -1,   -1,   -1,   -1, 4817,
+        -1,   -1,   -1,   -1, 4816,   -1, 4817,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4818,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4819,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4818,   -1,   -1, 4819,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4820,   -1,   -1,   -1,   -1,   -1, 4821,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4822,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4823,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4824,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4825,   -1,
-        -1,   -1,   -1,   -1, 4826,   -1,   -1,   -1,
-        -1, 4827,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4828,   -1,   -1, 4829,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4830,   -1,   -1,   -1,   -1,   -1,
-        -1, 4831,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4832,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4833,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4834,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4835,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4820,
+        -1,   -1, 4821,   -1,   -1,   -1,   -1, 4822,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4836,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4837,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4838,   -1,   -1,   -1,
-        -1,   -1, 4839,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4840,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4841,   -1,
+        -1,   -1,   -1,   -1, 4823,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4842,   -1,
+        -1,   -1,   -1,   -1, 4824,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4825, 4826,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4827,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4828,   -1,   -1,   -1,   -1,   -1,
+        -1, 4829,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4830,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4831,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4832,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4833,   -1,   -1,
+        -1, 4834,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4835,   -1,   -1,   -1, 4836,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4837,   -1,   -1, 4838, 4839,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4840,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4841,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4842,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4843, 4844,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -35984,869 +32828,478 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4843,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4844,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4845,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4846,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4845, 4846,
         -1,   -1,   -1,   -1,   -1, 4847,   -1,   -1,
+      4848, 4849,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4850,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4848,   -1,   -1,
-        -1,   -1,   -1, 4849,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4851,   -1,   -1,
+        -1, 4852,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4850,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4851,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4852,
-        -1,   -1, 4853,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4854,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4855,   -1,
-      4856,   -1, 4857,   -1,   -1,   -1, 4858,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4859,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4860,   -1,   -1,   -1,   -1,   -1, 4861,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4862,
-        -1,   -1,   -1,   -1, 4863,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4864,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4865,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4866,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4867,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4868,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4869,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4870,   -1,
+        -1,   -1,   -1,   -1,   -1, 4853,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4854,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4871,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4872,   -1,   -1,
+      4855,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4856,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4857,   -1,   -1,
+        -1,   -1, 4858,   -1,   -1,   -1,   -1, 4859,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4860,   -1,   -1, 4861,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4862,   -1,   -1,   -1,
+        -1,   -1,   -1, 4863,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4864,
+        -1,   -1,   -1,   -1,   -1,   -1, 4865,   -1,
+        -1,   -1,   -1,   -1,   -1, 4866,   -1,   -1,
+      4867,   -1,   -1, 4868,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4869,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4870,
+        -1,   -1,   -1, 4871,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4872,   -1, 4873,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4874,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4875,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4876,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4873,   -1,   -1, 4874,
-        -1,   -1,   -1,   -1,   -1, 4875,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4877,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4876,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4877,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       4878,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 4879,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4880,   -1,   -1,   -1,   -1,   -1,   -1,
+      4880,   -1,   -1,   -1, 4881,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4882,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4883,   -1,   -1,
+      4884,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4881,   -1,   -1,   -1, 4882,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4885,   -1,   -1,   -1,   -1,   -1, 4886,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4887,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4888,   -1,   -1,   -1,
+        -1,   -1,   -1, 4889,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4890,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4891,   -1,   -1,   -1,   -1,   -1, 4892,
+        -1,   -1,   -1,   -1,   -1,   -1, 4893,   -1,
+        -1, 4894,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4895,   -1,   -1,   -1,   -1,   -1,
+      4896,   -1,   -1,   -1, 4897, 4898,   -1,   -1,
+        -1,   -1,   -1,   -1, 4899,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4900,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4901,   -1, 4902,   -1,
+      4903,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4883,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4884,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4904,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4885,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4905,   -1,   -1,   -1,   -1, 4906,
+        -1,   -1,   -1,   -1, 4907,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4886,   -1,   -1, 4887,   -1,   -1,   -1,   -1,
-        -1, 4888,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4889,   -1,   -1,
-        -1,   -1,   -1, 4890,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4891,
-        -1,   -1, 4892,   -1,   -1,   -1,   -1,   -1,
-        -1, 4893,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4894,
+        -1, 4908,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4909,   -1,
+        -1,   -1,   -1, 4910,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4911,   -1,   -1, 4912,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4895,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4896,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4897,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4898,   -1, 4899,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4913,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4914,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4900,   -1,   -1, 4901,
+        -1,   -1,   -1,   -1, 4915,   -1,   -1, 4916,
+      4917,   -1,   -1,   -1,   -1,   -1,   -1, 4918,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4919,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4920,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4921,   -1,   -1,   -1,   -1,   -1,   -1, 4922,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4923,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4924,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4925,   -1,   -1,   -1, 4926,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4902,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4903,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4927,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4904,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4928,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4905,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4906,   -1,   -1, 4907,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4908,   -1,
-        -1,   -1,   -1,   -1, 4909,   -1,   -1,   -1,
-        -1, 4910,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4911,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4912, 4913,
+        -1,   -1,   -1,   -1,   -1, 4929,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4930,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4914,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4915,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4931,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4932, 4933,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4916,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4917,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4918,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4919,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4920,   -1,   -1,   -1,   -1,   -1,
-      4921,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4922,   -1, 4923,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4924,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4925,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4926,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4927,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4928,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4929,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4930,   -1,
-        -1,   -1,   -1,   -1,   -1, 4931,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4932,   -1,   -1,   -1, 4933,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4934,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4935,
-        -1,   -1,   -1,   -1,   -1, 4936,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4937, 4938,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4934,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4935,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4939,   -1, 4940,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4936,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4937,   -1,
+        -1,   -1,   -1, 4938,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4941,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4942,
+        -1,   -1,   -1, 4939,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4940, 4941, 4942,   -1,
         -1, 4943,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 4944,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4945, 4946,
+        -1,   -1,   -1, 4947,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4945,
-        -1,   -1, 4946,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4947,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4948,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4949,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4950,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4951,   -1,   -1,   -1, 4952,
-        -1,   -1,   -1,   -1,   -1, 4953,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4948,   -1,
+        -1,   -1,   -1,   -1, 4949, 4950,   -1,   -1,
+        -1,   -1,   -1,   -1, 4951,   -1,   -1,   -1,
+        -1,   -1,   -1, 4952,   -1,   -1,   -1,   -1,
+        -1,   -1, 4953,   -1,   -1,   -1,   -1,   -1,
+      4954,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4955, 4956,   -1,   -1,   -1,   -1, 4957,
+        -1,   -1, 4958,   -1, 4959,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4960,   -1,   -1,   -1,
+      4961,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4962,   -1,   -1,   -1,   -1,   -1, 4963,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4964,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4954,   -1,   -1,
-        -1,   -1,   -1, 4955,   -1,   -1,   -1,   -1,
-      4956,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      4965,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4957,   -1,   -1,   -1,   -1,   -1, 4958,
-        -1,   -1,   -1,   -1, 4959, 4960,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4961,   -1,   -1,
+        -1,   -1,   -1, 4966,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4967,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 4968,   -1,   -1,   -1,
+        -1,   -1, 4969,   -1,   -1,   -1,   -1,   -1,
+      4970,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4971,   -1,   -1, 4972,   -1,   -1,
+        -1,   -1,   -1,   -1, 4973,   -1,   -1,   -1,
+        -1,   -1,   -1, 4974,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4975,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 4976,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4962,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4963,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4964,   -1,   -1,   -1,   -1,   -1,   -1,
+      4977,   -1,   -1, 4978, 4979,   -1,   -1,   -1,
+        -1,   -1, 4980, 4981,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4982,   -1,   -1, 4983,   -1,   -1, 4984,
+      4985,   -1,   -1,   -1,   -1,   -1,   -1, 4986,
+        -1,   -1, 4987,   -1,   -1, 4988, 4989,   -1,
+        -1,   -1, 4990, 4991,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 4992,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 4993,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 4994,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4965,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4966,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 4995,   -1,
+      4996,   -1, 4997,   -1, 4998,   -1,   -1,   -1,
+        -1, 4999,   -1,   -1, 5000,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5001, 5002,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5003,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4967,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4968,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4969,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4970,   -1,   -1,   -1,   -1, 4971,   -1,
-        -1, 4972,   -1,   -1, 4973,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4974,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4975, 4976,   -1,   -1,   -1,
-        -1,   -1, 4977,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4978,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4979,   -1,   -1, 4980,   -1,
-        -1,   -1,   -1, 4981,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      4982,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4983, 4984,   -1,   -1,   -1,   -1,   -1,
-      4985,   -1,   -1,   -1,   -1, 4986,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4987,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 4988,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4989,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 4990,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4991,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 4992,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 4993,
-        -1,   -1,   -1,   -1,   -1,   -1, 4994,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4995,   -1,   -1,
-      4996,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 4997,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 4998,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 4999,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5000,   -1, 5001,   -1,   -1,
-      5002, 5003,   -1,   -1, 5004,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5005,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5004,   -1,   -1,   -1,   -1,   -1,
+        -1, 5005,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 5006,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 5007,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5008,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5008,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5009,
+      5010,   -1,   -1,   -1, 5011,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5012,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5013,   -1,   -1,   -1, 5014,   -1,   -1, 5015,
+        -1,   -1, 5016,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5009,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5010,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5011,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5012,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5013,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5014,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5015,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5016,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5017,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5018,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5017,   -1, 5018,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 5019,   -1,   -1,   -1,   -1,
+        -1, 5020,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5020,   -1,
-      5021,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5021,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5022,   -1,   -1,   -1,
+        -1,   -1,   -1, 5023,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5022,   -1,   -1,   -1,   -1,   -1,   -1, 5023,
+        -1,   -1,   -1, 5024,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5025,   -1, 5026,   -1,   -1,
+        -1,   -1,   -1,   -1, 5027,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5028,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5029,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5030,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5031, 5032,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5033,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5034,   -1,   -1,
+        -1, 5035,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5036,   -1,   -1, 5037,
+        -1,   -1, 5038,   -1,   -1,   -1,   -1,   -1,
+        -1, 5039,   -1,   -1,   -1,   -1, 5040,   -1,
+        -1, 5041,   -1, 5042,   -1, 5043,   -1, 5044,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5024,   -1,   -1,
-      5025,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5026,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5027,   -1,   -1,
-        -1,   -1,   -1, 5028,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5029,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5030,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5031,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5032,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5033,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5034,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5035,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5036,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5037,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5038,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5039,   -1, 5040,   -1,   -1,
-        -1, 5041,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5042,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5043,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5044,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5045,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5045,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 5046,   -1,   -1,
+        -1, 5047,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5047,   -1,   -1,
+        -1,   -1,   -1, 5048,   -1,   -1,   -1,   -1,
+      5049,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5048,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5050,   -1,   -1,   -1,   -1, 5051,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5049,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5050,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5051, 5052,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5053,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5054,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5052,   -1,   -1,   -1,
+        -1, 5053,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5054,   -1,   -1,   -1,
         -1,   -1,   -1, 5055,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5056,   -1,   -1,   -1,   -1,
+        -1,   -1, 5056,   -1,   -1,   -1,   -1, 5057,
+        -1, 5058,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5059,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5060,   -1, 5061,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5062,   -1,
+        -1,   -1,   -1,   -1, 5063,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5064,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5057,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5058,   -1,   -1,   -1,   -1, 5059,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5060,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5061,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5062,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5063,   -1,   -1,   -1,   -1, 5064,   -1,   -1,
         -1, 5065,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5066, 5067,   -1,   -1,   -1,   -1,
+        -1, 5068,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5066,
+        -1,   -1,   -1,   -1,   -1, 5069,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5067,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5070,   -1,   -1,   -1,   -1,
+        -1, 5071,   -1,   -1, 5072, 5073,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5068,   -1,   -1,
+        -1,   -1,   -1,   -1, 5074,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5075,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5069, 5070,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5071,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5072,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5073,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5074,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5075,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5076,   -1, 5077,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5078,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5079,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5080,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5081,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5082,   -1,
-        -1, 5083,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5084,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5085,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5076,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5077,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5078,   -1, 5079,   -1, 5080,   -1,   -1,
+        -1,   -1,   -1, 5081,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5082, 5083,
+        -1, 5084, 5085,   -1,   -1,   -1,   -1,   -1,
         -1, 5086,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5087,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5088,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5087,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5088,
-        -1,   -1,   -1, 5089,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5090,   -1, 5091,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5089,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5090, 5091,
         -1,   -1,   -1,   -1,   -1,   -1, 5092,   -1,
-        -1,   -1,   -1, 5093,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5093,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5094,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5095,   -1,
+        -1, 5096,   -1,   -1,   -1,   -1, 5097,   -1,
+      5098,   -1,   -1,   -1, 5099,   -1,   -1,   -1,
+        -1,   -1, 5100,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5094,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5095,   -1,   -1,   -1,   -1,
-        -1, 5096,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5097,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5098,   -1,
-        -1,   -1,   -1, 5099,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5100,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 5101,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5102,
-        -1,   -1,   -1, 5103,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5104,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5105,   -1,   -1,   -1,   -1,   -1,   -1, 5106,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5107,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5108,   -1,   -1,   -1,
-        -1,   -1, 5109,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5110,   -1,   -1,   -1,   -1,   -1, 5111,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5112,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5113,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5114,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5115,   -1,   -1, 5116,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5117, 5118,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5119,   -1,
-        -1,   -1,   -1,   -1, 5120,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5121,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5122,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5123,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5124,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5102,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5103,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5104,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5105,   -1,
+      5106,   -1,   -1, 5107,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5125,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5108,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5109,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5126,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5110,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5111,   -1,   -1,   -1,   -1,   -1,   -1, 5112,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5113,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5114,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5115,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5116,
+      5117,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5118,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5119,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5120, 5121,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5122,   -1, 5123,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5124,   -1,   -1,   -1, 5125,   -1,
+      5126, 5127,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5128,   -1,   -1,
+      5129,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5130,   -1,   -1,   -1, 5131,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5132,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5127,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5128,   -1,   -1, 5129,   -1,   -1,   -1,
-        -1,   -1, 5130,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5131,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5132,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5133,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5133,   -1,
         -1,   -1,   -1,   -1,   -1, 5134,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5135,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5136,
+        -1,   -1,   -1, 5135,   -1,   -1,   -1,   -1,
+        -1,   -1, 5136,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5137,   -1,   -1,   -1,   -1,   -1,   -1,
+      5138,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5139,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5140,   -1,   -1,
+        -1,   -1,   -1,   -1, 5141,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5137,   -1,   -1, 5138,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5139,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5140,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5141,   -1,   -1,   -1,   -1, 5142,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5142,
         -1,   -1,   -1, 5143,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5144,   -1,   -1,   -1,   -1,   -1,   -1, 5145,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5144,
+      5145,   -1, 5146,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5147,   -1, 5148,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5149,   -1,   -1,   -1,   -1, 5150,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5151,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5152,   -1,   -1,
+        -1,   -1,   -1, 5153,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5154,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -36854,240 +33307,161 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5146,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5147,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5148,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5149,   -1, 5150,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5151,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5152,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5153,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5154,   -1,   -1,
-        -1,   -1,   -1, 5155,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5155,   -1,   -1,   -1,
         -1, 5156,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 5157,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5158,
+      5159,   -1, 5160,   -1, 5161,   -1,   -1, 5162,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5158,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5159,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5160,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5161,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5162,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5163,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5164,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5165,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5166,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5167,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5168,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5169, 5170,   -1,   -1,   -1,   -1,   -1,
-      5171,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5172,   -1,   -1, 5173, 5174,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5175,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5176,   -1,   -1,   -1,   -1,   -1,
+      5163,   -1,   -1,   -1, 5164,   -1,   -1,   -1,
+        -1,   -1, 5165,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5166, 5167,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5168,
+        -1,   -1,   -1,   -1,   -1, 5169,   -1, 5170,
+        -1,   -1,   -1,   -1,   -1,   -1, 5171,   -1,
+      5172,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5177,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5178,   -1,
-        -1,   -1,   -1,   -1,   -1, 5179,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5173,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5180,   -1,   -1,   -1, 5181,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5182,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5183,   -1,   -1,   -1,
+      5174,   -1,   -1,   -1,   -1,   -1, 5175,   -1,
+        -1,   -1,   -1, 5176,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5177,   -1,   -1,   -1, 5178,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5179, 5180,
+        -1,   -1,   -1, 5181,   -1,   -1,   -1, 5182,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5184,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5183,
+        -1,   -1,   -1,   -1,   -1,   -1, 5184,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 5185,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5186,   -1,   -1,   -1,   -1,   -1, 5187,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5186,
+        -1, 5187,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 5188,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5189,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5190, 5191,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5192,   -1,   -1,   -1, 5193,
+      5189, 5190,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5191,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5194,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5192,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5193,   -1,
+        -1,   -1,   -1,   -1,   -1, 5194,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5195,
+        -1,   -1, 5196,   -1,   -1,   -1,   -1,   -1,
+      5197,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5195,   -1,
+        -1,   -1,   -1,   -1,   -1, 5198,   -1,   -1,
+        -1,   -1, 5199,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5200,   -1,   -1,   -1,   -1,   -1,
+      5201,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5202,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5203,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5196,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5197,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5204,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5205,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5198,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5199,   -1,   -1,
+        -1,   -1, 5206,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5207,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5208,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5200,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5201,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5202,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5203,   -1,   -1, 5204,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5205,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5206,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5207,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5208,   -1,
         -1,   -1,   -1,   -1,   -1, 5209,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5210,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5210,
+      5211,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5212,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5213,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5211,   -1,   -1,   -1,   -1,
-        -1, 5212,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5213,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5214,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5215,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5214,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5216,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5217,   -1,   -1,   -1,   -1,   -1,
+        -1, 5215,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5216,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5217,   -1,
+      5218,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5218, 5219,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5219,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5220,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5221,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5222,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5223,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5224,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5220, 5221,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5222,
-        -1,   -1, 5223, 5224,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5225,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5226,   -1,   -1, 5227,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5225,   -1,   -1,   -1,   -1,   -1,
-        -1, 5226,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5227,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5228,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5229,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5228,   -1,   -1, 5229,
+        -1,   -1,   -1,   -1,   -1,   -1, 5230,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5230,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5231,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5231,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 5232,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5233,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5234,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5233,   -1,   -1,   -1,   -1,   -1,   -1,
+      5234,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5235,   -1,   -1, 5236,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5237,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5238,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5239,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5240,   -1,   -1,
+        -1,   -1,   -1, 5235,   -1,   -1,   -1,   -1,
+      5236,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -37096,33 +33470,17 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5241,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5237,   -1,
+        -1,   -1,   -1,   -1,   -1, 5238,   -1,   -1,
+        -1,   -1, 5239,   -1, 5240,   -1,   -1, 5241,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       5242,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5243,   -1,   -1,   -1, 5244,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5245,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5243,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5244,   -1,   -1,
-      5245,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5246,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5247,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5248,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5249,   -1,
+        -1,   -1,   -1,   -1, 5246,   -1, 5247,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -37131,72 +33489,43 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5250,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5251,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5252,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5248,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5249, 5250,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5251,
+        -1, 5252,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5253,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5253,   -1,   -1, 5254,   -1,
+      5254,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5255,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5256,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5257,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5255,   -1,   -1,
+        -1,   -1,   -1, 5256,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5258,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5259,   -1,
+      5257,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5258,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5260,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5259,   -1,   -1,   -1,   -1,   -1,   -1, 5260,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 5261,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 5262,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5263,   -1,   -1, 5264,   -1,   -1, 5265,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5266,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5267, 5268,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5269,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5270,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5271,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5272,   -1,   -1,   -1,   -1,   -1,
-        -1, 5273,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5274,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5275,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -37209,171 +33538,103 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5263, 5264,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5276,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5277,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5265,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5266,   -1,
+      5267,   -1,   -1, 5268,   -1,   -1,   -1,   -1,
+      5269,   -1,   -1,   -1, 5270,   -1, 5271,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5272,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5273,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5274,
+        -1,   -1, 5275,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5276,   -1,   -1,
+      5277,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 5278,   -1,   -1,   -1,
+        -1, 5279,   -1,   -1,   -1,   -1,   -1, 5280,
+        -1,   -1, 5281,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5282,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5283,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5284,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5285,   -1,   -1,   -1,   -1,   -1, 5286,
+        -1, 5287,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5279,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5288,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5289,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5290,   -1,   -1,   -1, 5291,   -1,
+        -1,   -1,   -1,   -1,   -1, 5292,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5293,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5294,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5295,   -1, 5296,   -1,   -1,   -1,   -1,
+      5297,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5298, 5299,   -1,   -1, 5300,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5301,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5302,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5303,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5304,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5305,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5306,   -1,   -1,   -1, 5307,   -1,
+        -1,   -1,   -1,   -1, 5308,   -1,   -1, 5309,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5280,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5281,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5282,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5283,
-        -1,   -1, 5284,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5285,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5286,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5287,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5288,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5289,   -1,   -1,   -1,   -1,   -1,
-      5290,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5291,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5292,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5293,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5294,   -1,   -1,
-        -1,   -1,   -1, 5295,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5296,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5297,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5298, 5299,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5300,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5301,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5302,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5303,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5304,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5305,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5306,
-      5307,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5308,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5309,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5310,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5310,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 5311,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5312,
-        -1,   -1, 5313,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5312,   -1,
+        -1,   -1,   -1, 5313,   -1,   -1, 5314,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5314,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5315,
+        -1,   -1,   -1,   -1,   -1, 5315,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5316,   -1,   -1,   -1,   -1,   -1, 5317,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5318,
+        -1,   -1,   -1,   -1,   -1,   -1, 5319,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5320,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5316,   -1, 5317,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5318,   -1,   -1,
+        -1,   -1,   -1, 5321,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5322,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5323,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5319,   -1,   -1,   -1,   -1,   -1,   -1,
+      5324,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5325,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5320,   -1,   -1, 5321,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5322,   -1,   -1, 5323,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5324,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5325,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 5326,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5327,
+        -1,   -1, 5328,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5329,   -1,   -1,   -1,   -1, 5330, 5331, 5332,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5327,   -1,   -1,   -1, 5328,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5333,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -37381,179 +33642,156 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5329,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5330,   -1,   -1,
+        -1,   -1,   -1, 5334,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5331,   -1,   -1,
+        -1, 5335, 5336,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5337, 5338,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5339,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5340,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5341,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5332,   -1,   -1,   -1, 5333,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5334,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5335,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5336,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5337,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5338,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5339,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5340,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5341,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5342,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5343,   -1, 5344,   -1,   -1,   -1,
+        -1,   -1,   -1, 5342,   -1,   -1,   -1, 5343,
+      5344,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 5345,   -1,   -1,   -1,   -1,
-        -1, 5346,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5346,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 5347,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5348,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5349,   -1,   -1,
-        -1,   -1,   -1,   -1, 5350,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5351,
+        -1, 5348,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5349,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5352,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5353,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5354,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5355,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5356,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5357, 5358,   -1,   -1,   -1,   -1,
-        -1,   -1, 5359,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5360,   -1,   -1,   -1, 5361,
-        -1, 5362,   -1,   -1,   -1,   -1,   -1,   -1,
+      5350, 5351,   -1,   -1,   -1,   -1,   -1,   -1,
+      5352,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5353,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5354, 5355,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5356,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5357,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5358,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5359,   -1,   -1,
+      5360,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5361,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5362,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 5363,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5364,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5365,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5366,   -1, 5367,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5364,
+        -1,   -1,   -1,   -1,   -1,   -1, 5365,   -1,
+      5366,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5368,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5369,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5370,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5371,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5372,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5373,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5367,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5368,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5374,   -1,   -1, 5375,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5369,   -1,
+        -1,   -1,   -1, 5370, 5371,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5376,   -1, 5377,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5372,   -1,   -1,   -1,
+        -1,   -1, 5373,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5378,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5374,   -1,
+        -1,   -1,   -1, 5375, 5376,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5377,   -1,   -1,   -1,
+      5378,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5379,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5380,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5381,   -1,   -1,   -1, 5382,
+        -1,   -1,   -1, 5383,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5384,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5385,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5379,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5380,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5381,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5382,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5383,   -1,   -1,
-      5384,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5386,   -1,   -1,   -1,
+      5387, 5388,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5389,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5385,   -1,   -1, 5386,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5387,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5390,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5391,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5388,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -37561,22 +33799,19 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5389,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5390,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5391,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5392,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5393,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5392,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5393,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5394, 5395,   -1, 5396,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5394, 5395,   -1,   -1,   -1,   -1,   -1,
-      5396,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5397,   -1,   -1, 5398,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -37585,206 +33820,177 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5397,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5399,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5400,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5398,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5399,   -1,   -1,   -1, 5400,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 5401,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5402,   -1,
+        -1,   -1,   -1, 5402,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5403, 5404,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5403, 5404,
       5405,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5406,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5407,   -1,   -1, 5408,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5409,   -1,   -1, 5410,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5406,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5407,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5408,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5409,   -1,   -1,   -1,   -1, 5410,
         -1, 5411,   -1,   -1,   -1,   -1,   -1,   -1,
+      5412,   -1,   -1,   -1,   -1, 5413,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5414,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5415,   -1, 5416,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5417,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5418,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5419,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5420,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5421,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5422,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5423,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5424,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5425,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5426,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5427,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5428,   -1,
+        -1,   -1,   -1, 5429,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5430,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5412, 5413,   -1,   -1, 5414,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5415,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5416,   -1,   -1,   -1,   -1,   -1, 5417,
-        -1,   -1, 5418,   -1, 5419,   -1,   -1,   -1,
+        -1,   -1, 5431,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5432,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5433,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5434,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5435,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5436,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5437,
+        -1,   -1, 5438,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5439,   -1,   -1, 5440,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5441,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5420,   -1,   -1,   -1,   -1,   -1,   -1, 5421,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5422,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5423,   -1,   -1,   -1,   -1, 5424,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5425,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5426,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5427,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5428,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5429,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5430,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5431,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5432,   -1,   -1,   -1,   -1, 5433,
-        -1,   -1,   -1,   -1,   -1,   -1, 5434,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5435, 5436,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5437,   -1,   -1,   -1,
-      5438,   -1, 5439,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5440,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5441, 5442,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5443,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5442,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5443,
         -1,   -1,   -1,   -1, 5444,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5445,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5446,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5445,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5446,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5447,   -1,   -1,
+      5447,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       5448,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5449,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5449,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5450,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5450,   -1,   -1,   -1, 5451,   -1,
-      5452,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5451, 5452,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5453, 5454,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5453,   -1,   -1, 5454,
-        -1, 5455,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5455,   -1,   -1,   -1,   -1,
+      5456,   -1,   -1,   -1,   -1, 5457,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5456,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5457,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5458,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5458,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5459,   -1,   -1, 5460,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5461,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5462,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5463,   -1,
+        -1,   -1,   -1,   -1,   -1, 5464,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5459,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5460,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5461,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5462,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5465,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5466,   -1,
+        -1,   -1, 5467,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5463,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5464,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5465,   -1,
-        -1,   -1,   -1,   -1, 5466,   -1,   -1,   -1,
+      5468,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5469,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5467,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5468,   -1,
+        -1,   -1,   -1,   -1,   -1, 5470,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5469,   -1, 5470,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5471, 5472,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5473,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5471,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5472,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -37793,178 +33999,117 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5473,   -1,   -1,   -1,   -1,
+        -1,   -1, 5474,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5474,   -1,   -1,   -1,   -1, 5475,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5476,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5475,
+        -1, 5476,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5477,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5477,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5478,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5478,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 5479,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5480,   -1,
+        -1, 5480,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5481,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5482,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5483,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5484,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5485,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5481,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5482,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5486,   -1, 5487,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5483,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5484,   -1,   -1,   -1,
+        -1,   -1,   -1, 5488,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5489,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5485,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5490,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5486,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5487,   -1,
-      5488,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5489, 5490,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5491,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5491,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 5492,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5493,   -1,
+        -1,   -1,   -1,   -1,   -1, 5493,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5494,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5494,   -1,   -1,   -1,
+      5495,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5496,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5497,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5498,   -1,   -1,   -1,
+      5499,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5495,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5496,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5497,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5498,   -1,   -1,   -1,   -1,   -1, 5499,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5500,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5500,
         -1,   -1, 5501,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5502,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5503,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5504,
+        -1,   -1,   -1,   -1,   -1,   -1, 5505,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5506,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5507,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5502,
-      5503,   -1,   -1,   -1,   -1, 5504,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5505,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5506,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5507,
-        -1,   -1,   -1,   -1, 5508,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5508,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 5509,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5510,   -1,   -1,   -1,   -1,   -1,
+      5510,   -1,   -1,   -1,   -1,   -1,   -1, 5511,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5511,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5512,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5513,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5514,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5512,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5513,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5514,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5515,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5515,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 5516,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5517,   -1,
+        -1,   -1,   -1, 5517,   -1,   -1,   -1,   -1,
+        -1, 5518,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5518,   -1, 5519,   -1,   -1,   -1,
-      5520,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5519,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5521,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5520,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -37972,57 +34117,34 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5521,
         -1,   -1,   -1,   -1, 5522,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5523,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5524,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5525,   -1,
+      5526,   -1,   -1, 5527,   -1,   -1,   -1,   -1,
+      5528,   -1,   -1,   -1,   -1,   -1, 5529,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5530,
+        -1,   -1,   -1,   -1,   -1,   -1, 5531,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5523,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5532,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5533, 5534,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5524,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5525,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5526,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5527,   -1,
-        -1,   -1, 5528,   -1,   -1,   -1,   -1,   -1,
-      5529,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5530,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5531,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5532,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5533,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5534,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5535,   -1,   -1, 5536,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5535,   -1,   -1, 5536,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -38032,112 +34154,83 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5538,   -1,   -1,
+        -1,   -1,   -1, 5538,   -1,   -1, 5539,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5540,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5541,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5539,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5540,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5542,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5541,   -1,   -1, 5542,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5543,   -1,   -1,
-        -1,   -1,   -1, 5544,   -1,   -1,   -1, 5545,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5543, 5544,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5546,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5545,
+        -1,   -1,   -1,   -1, 5546,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5547,   -1,   -1,   -1, 5548,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5549,   -1, 5550,   -1,   -1, 5551,
+        -1,   -1,   -1, 5552,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5553,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5547,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5554,   -1,
+        -1,   -1, 5555,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5556,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5548,   -1,   -1,   -1,   -1, 5549,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5557,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5550,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5558,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5551,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5559,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5552,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5553,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5554,   -1,   -1,   -1,   -1,   -1,
-        -1, 5555,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5556,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5557, 5558,   -1,
-        -1,   -1,   -1,   -1,   -1, 5559,   -1,   -1,
-      5560,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5561,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5562,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5560,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5561,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5562,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       5563,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5564,
-        -1,   -1, 5565,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5564, 5565,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 5566,   -1,   -1,
-        -1, 5567,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5567,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5568,   -1,   -1,   -1,
+        -1, 5569,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5570,   -1, 5571,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5572,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -38145,71 +34238,20 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5568,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5569,   -1,   -1, 5570,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5571,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5572,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5573,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5573,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 5574,   -1,   -1,   -1,
-        -1,   -1,   -1, 5575,   -1,   -1,   -1,   -1,
-        -1, 5576,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5577,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5578,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5575,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5576,   -1,   -1,   -1,   -1,   -1,
+      5577,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5579,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5580,   -1, 5581,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5582,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5583,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5584,   -1,   -1,   -1,   -1, 5585,   -1,
-        -1,   -1, 5586,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5578,
+        -1, 5579,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -38218,30 +34260,34 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5580,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5581,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5587,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5588,   -1,   -1,
+        -1, 5582,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5583,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5584,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5589,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5585,   -1,   -1,   -1,
+      5586,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5587,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5588, 5589,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5590,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5590,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 5591,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5592,   -1,   -1,   -1, 5593,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -38251,190 +34297,138 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5592,   -1,
+      5594,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5593,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5594,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5595,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5596,
+        -1,   -1, 5597,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5598,   -1,   -1,   -1,   -1,   -1,
+      5599,   -1,   -1,   -1,   -1,   -1,   -1, 5600,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5601,   -1, 5602,   -1,   -1,
+        -1,   -1, 5603,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5604,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5605,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5595,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5606,
+        -1,   -1,   -1,   -1, 5607,   -1,   -1,   -1,
+      5608,   -1,   -1, 5609,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5596,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5610,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5611,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5597,   -1,   -1,
-      5598,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5599,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5600,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5601,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5602,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5603,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5604,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5605,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5606,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5607,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5608,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5609,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5610,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5612,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5611,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5612,   -1,   -1,   -1,
       5613,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5614,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5614,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5615,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5616,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5617,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5618,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5615,   -1,
+      5619,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5620,   -1,   -1,   -1, 5621,
+        -1, 5622,   -1,   -1,   -1, 5623,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5624,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5625,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5626,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5616, 5617,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5618,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5619,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5620,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5621,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5622,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5623,   -1,   -1,
-      5624,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5625,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5626,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 5627,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5628,   -1,   -1,   -1,   -1,   -1, 5629,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5630,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5628,   -1,   -1,   -1,   -1,   -1,
+      5629,   -1, 5630,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 5631,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5632,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5633,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5634,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5635,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5636,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5637,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5632,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5638,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5639,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5640,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -38443,345 +34437,164 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5641,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5642,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5643,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5644,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5645,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5633,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5646,
+        -1,   -1,   -1,   -1,   -1,   -1, 5647,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5648,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5649,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5650,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5651,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5652,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5653, 5654,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5655,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5634,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5656,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5657,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5658,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5635,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5636,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5637,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5638,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5639,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5640,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5641,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5642,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5643,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5644,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5645, 5646,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5647,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5648,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5649,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5650,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5651,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5652,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5653,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5654,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5655,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5656,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5657,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5659,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5658,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5659,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 5660,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5661,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5662,   -1,   -1,   -1,   -1,
+        -1, 5663,   -1,   -1,   -1,   -1,   -1,   -1,
+      5664,   -1,   -1,   -1, 5665,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5666,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5661,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5662,   -1,   -1,   -1, 5663,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5667,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5664,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5668,   -1,   -1,   -1,
+        -1, 5669,   -1,   -1,   -1,   -1, 5670,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5671,
+        -1,   -1, 5672,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5673,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5674,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5675,   -1,
+        -1, 5676,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5665,
+      5677,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5678,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5679,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5666,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5667,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5680,   -1,
+        -1,   -1, 5681,   -1,   -1,   -1,   -1, 5682,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5683,   -1,   -1,
+        -1, 5684,   -1,   -1,   -1,   -1,   -1, 5685,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5686,   -1,   -1,   -1,   -1,   -1,   -1, 5687,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5688,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5689,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5690,
+      5691,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5692,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5693,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5668,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5669,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5670,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5671,   -1,   -1,
-        -1,   -1,   -1, 5672,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5673, 5674,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5675,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5676,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5677,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5678,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5679, 5680,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5681,   -1,   -1,   -1, 5682,   -1,   -1,   -1,
-        -1,   -1, 5683, 5684,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5685,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5686,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5687,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5688,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5689,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5690,   -1,   -1,   -1,   -1,
-        -1, 5691,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5692,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5693,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5694,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5694,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 5695,   -1,
-        -1,   -1,   -1, 5696,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5697,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5698,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5699,
-      5700,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5696,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5701,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5702,   -1,   -1,
-        -1,   -1,   -1, 5703,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5697,   -1,   -1,   -1,   -1,
+        -1, 5698,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5699,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5700,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5704,   -1,   -1, 5705,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5701,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5702,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5706,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -38789,120 +34602,103 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5703,
+      5704,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5705,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5706,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5707,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5707,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5708,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5708,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5709,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5710,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5709,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5710,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 5711,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5712, 5713,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5714,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5715,   -1,   -1,   -1,   -1,
+      5716,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5712,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5717,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5713,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5718,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5719,   -1,   -1,   -1,   -1, 5720,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5721,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5722,
+        -1,   -1,   -1,   -1,   -1, 5723,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5714,   -1,   -1, 5715,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5716,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5717,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5718,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5719,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5724,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5720,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5721,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5722,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5725,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5723,   -1,
-        -1,   -1, 5724,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5726,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5725,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5726,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5727,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5727,   -1,   -1,   -1,   -1,   -1,
+      5728,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5728,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5729,   -1,   -1,   -1,   -1, 5730,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5731,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5729,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5730,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5731,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -38913,27 +34709,27 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5732,   -1,   -1, 5733,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5732,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5734,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5735,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5733,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5734,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5736,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5735,   -1, 5736,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -38946,15 +34742,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5738,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5739,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5738,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -38962,135 +34750,179 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5740,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5739,   -1,
+        -1,   -1,   -1, 5740,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5741,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5742,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5743, 5744,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5745,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5746,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5747,   -1,   -1,   -1, 5748,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5741,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5742,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5743,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5744,
+        -1,   -1,   -1,   -1, 5745,   -1, 5746,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5747,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5748,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 5749,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5750,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5751,   -1,   -1, 5752,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5753,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5750, 5751,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5752,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5753,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 5754,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 5755,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 5756,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5757,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5758,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5757,   -1,   -1, 5758,   -1,   -1,
+      5759,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5759,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5760,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5760,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5761,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5762,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5763,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5764,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5761,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5765,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5766,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5767,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5762,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5763,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5764,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5768,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5765,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5766,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39099,30 +34931,31 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5769,   -1,   -1,
+        -1,   -1,   -1,   -1, 5770,   -1,   -1,   -1,
+        -1,   -1, 5771,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5767,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5768,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5769,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5770,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5772,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5771,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5773,   -1, 5774,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5775,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39130,29 +34963,29 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5772,   -1,   -1,   -1,   -1,   -1,
-      5773,   -1, 5774,   -1,   -1, 5775,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5776,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5777,   -1, 5778,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5779,
+        -1,   -1,   -1,   -1,   -1, 5776,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5777,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5778,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5779,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5780,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39160,15 +34993,17 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5780,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5781,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5782,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5783,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39183,71 +35018,47 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5784,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5781,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5782,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5783,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5784,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5785,   -1,   -1,
-      5786,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5785,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5786,   -1,
         -1,   -1, 5787,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5788,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5788,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5789,   -1,
+      5789,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 5790,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5791,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5792,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5793,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5791,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5792,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5793,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 5794,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 5795,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39255,39 +35066,14 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5796,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5797,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5798,   -1,
+        -1,   -1,   -1, 5796,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5799,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5800,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5801,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5797,   -1,   -1,   -1,   -1,   -1,
+      5798,   -1,   -1,   -1, 5799,   -1,   -1,   -1,
+        -1,   -1, 5800,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5801,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39295,22 +35081,25 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 5803,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5804,   -1, 5805,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5804,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5805, 5806,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5807,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5808, 5809,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5810,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5806,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5811,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5807,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39322,235 +35111,129 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5812,   -1,   -1,   -1,
+        -1,   -1,   -1, 5813,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5814,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5808,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5815,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5809,   -1,   -1,   -1, 5810,
+        -1,   -1,   -1, 5816,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5817,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5818,   -1, 5819,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5811,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5820,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5812,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5821,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5813,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5814,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5815,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5816,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5817,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5818,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5819,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5820,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5821,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5822,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5823,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5822,   -1, 5823,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 5824,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5825,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5826,   -1,   -1,   -1,   -1,   -1, 5827,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5828,
+      5829,   -1,   -1,   -1, 5830,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5825,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5826,
-      5827,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5828,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5829,   -1,
+        -1,   -1,   -1,   -1,   -1, 5831,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5830,   -1,   -1,   -1,   -1,
-        -1,   -1, 5831,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5832,   -1,
+        -1, 5832,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5833,   -1,   -1,
+        -1, 5834,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5835,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5836,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5837,
+        -1, 5838,   -1,   -1,   -1,   -1, 5839,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5833,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5840,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5841,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5834,   -1,   -1,   -1,   -1,   -1, 5835,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5836,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5837,   -1, 5838,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5839,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5840,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5841,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5842,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5842,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 5843,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 5844,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5845,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5846,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5845,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5847,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5848,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5849,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5850,   -1,
+        -1,   -1,   -1,   -1,   -1, 5851,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5852,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5853,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39561,94 +35244,50 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5846,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5847,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5848,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5849,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5850,   -1,   -1,   -1, 5851,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5852,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5853,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 5854,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5855, 5856,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5855,   -1,   -1,
+        -1,   -1, 5856,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5857,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5858,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5859,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5857,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5860,   -1, 5861,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5862,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5858,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5859,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5863,   -1,   -1,   -1, 5864,
+        -1,   -1,   -1, 5865,   -1,   -1,   -1,   -1,
+      5866,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5860,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5867, 5868,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5869,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39656,89 +35295,15 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5861,
-      5862,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5863,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5864,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5865,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5866, 5867,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5868,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5869,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5870,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5870,   -1,
         -1,   -1,   -1, 5871,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5872,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5873,   -1,   -1, 5874,
+        -1,   -1,   -1,   -1,   -1, 5872,   -1, 5873,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39749,16 +35314,9 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5874,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5875,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5876,   -1,   -1,   -1,   -1,   -1,
+        -1, 5875,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39767,42 +35325,25 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5876,   -1,   -1, 5877, 5878, 5879,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5877,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5880,   -1, 5881,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5878,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5879,   -1,   -1, 5880,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5881,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5882,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5882,   -1,   -1,   -1,   -1,   -1,
       5883,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5884,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5884,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5885,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5885,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39812,139 +35353,101 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5886,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5887,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5888,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5886,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5887,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5889,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5888,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5890,   -1, 5891,   -1, 5892,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5893,   -1,   -1,
+      5894,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5889,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5895,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5890,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5891,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5892,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5893,   -1,
+        -1,   -1,   -1, 5896,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5897,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5898,
+        -1,   -1,   -1,   -1,   -1,   -1, 5899,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5894,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5895,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5896,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5900,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5897,   -1,   -1, 5898,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5899,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5900,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       5901,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5902,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5902,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5903,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5904,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5905,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5906,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5907,   -1,
+        -1,   -1, 5908,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5903,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5904,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5905,   -1, 5906,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5907,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5908,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5909,   -1,   -1,   -1,   -1,
+        -1,   -1, 5909,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 5910,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5911,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5911,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -39957,64 +35460,25 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5912,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5912,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 5913,   -1,
+        -1,   -1, 5914,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5915,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5916,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5917,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5918,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40024,73 +35488,53 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5914,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5919,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5915, 5916,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5920,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5921,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5917,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5918,   -1,   -1,   -1,   -1,   -1,
-      5919,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5922,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5923, 5924,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5925,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5920,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5921,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5922,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5923,   -1,
-        -1, 5924,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5925,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 5926,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5927,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5927,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 5928,   -1,   -1,
+      5929, 5930,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5931,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5932,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5933,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40098,75 +35542,19 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5934,   -1,
+        -1, 5935,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5936,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5929,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5930,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5931,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5932,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5933,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5934,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5935,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5936,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5937,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5937,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 5938,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5939,   -1,
+        -1, 5939,   -1, 5940,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5941,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5942,   -1, 5943,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40174,70 +35562,24 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5944,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5940,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5945,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5946,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5947,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5948,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5941,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5942,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5943,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5944, 5945,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5946, 5947,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5948,   -1,   -1, 5949,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5949,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40247,24 +35589,23 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 5950,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5951,   -1,   -1,   -1,   -1,   -1, 5952,   -1,
-        -1,   -1, 5953,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5951,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5954,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5952, 5953,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5955,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5954,   -1,   -1,   -1,   -1, 5955,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 5956,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5957,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5957,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40277,227 +35618,88 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 5959,   -1,   -1,   -1, 5960,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5959,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5960,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5961,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5961,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5962,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5963,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 5962,   -1,   -1,   -1,
+        -1,   -1,   -1, 5963,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 5964,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5965,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5965,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5966,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5966,   -1,
+        -1,   -1,   -1,   -1, 5967,   -1,   -1,   -1,
+      5968,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5967,   -1,   -1,
+      5969,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5970,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5971,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5972,
+      5973,   -1, 5974,   -1,   -1,   -1,   -1,   -1,
+        -1, 5975,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5968,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5969,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5976,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5977,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5970,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5971,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 5978, 5979,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5980,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5981,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5982,
+        -1, 5983,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5984,   -1,
+        -1,   -1,   -1,   -1, 5985,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5986,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 5987,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5972,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5973,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5974,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5975,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5976,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5977,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5978,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5979,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5980,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5981,   -1,   -1,   -1,   -1,   -1, 5982,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5983,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5984,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5985,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 5986,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5987,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5988,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5988,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 5989,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 5990,   -1,   -1,   -1,
+        -1,   -1,   -1, 5990,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40508,6 +35710,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5991,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40517,43 +35720,18 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5992,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 5991,   -1,   -1, 5992,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 5993,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 5994,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5995,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 5993,   -1,   -1,
+        -1,   -1,   -1,   -1, 5994, 5995,   -1,   -1,
         -1,   -1,   -1,   -1, 5996,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 5997,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5998,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      5999,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6000,   -1,   -1, 6001,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6002,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 5997,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40561,97 +35739,71 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      5998,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 5999,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6000,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6001,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6002,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6003,   -1,   -1,   -1,   -1,   -1, 6004,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6005,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6006,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6003,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6004,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6005,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6006,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 6007,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6008,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6009,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6010,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6008,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6009,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6010,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6011,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6011,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 6012,   -1,
+        -1,   -1,   -1, 6013,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6013,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6014,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6015,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6016,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40660,59 +35812,26 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6014,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6015,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6017,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6016,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6017,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6018,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6019,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6018,   -1,
-        -1,   -1,   -1,   -1,   -1, 6019,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6020,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6020,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 6021,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6022,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40720,6 +35839,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6023,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40728,8 +35848,10 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6024,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6025,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40743,7 +35865,9 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6026,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6027,   -1,   -1,   -1,   -1, 6028, 6029,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40752,115 +35876,18 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6022,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6023,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6030,   -1,   -1, 6031,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6032,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6033,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6024,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6025,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6026,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6027,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6028,   -1,   -1,   -1,   -1,   -1, 6029,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6030,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6031,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6032,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6034,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40868,25 +35895,25 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6033,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6034,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 6035,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6036,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6037,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6036,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6038,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40894,71 +35921,20 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6037,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6039,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6040,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6041,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6038,   -1,   -1,   -1,   -1, 6039,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6040,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6041,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6042,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6042,   -1,
+        -1,   -1,   -1,   -1,   -1, 6043,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40967,7 +35943,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6043,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -40983,76 +35958,54 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6045,   -1,   -1,   -1,   -1,   -1, 6046,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6047,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6048,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6049,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6045,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6046,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6047,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6048,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6049,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 6050,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6051,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6052,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6053,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6054,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6055,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6051,   -1,   -1,
+      6052,   -1,   -1,   -1,   -1, 6053,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6054, 6055,   -1,
         -1,   -1,   -1,   -1, 6056,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6057,   -1,   -1,   -1, 6058,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6057,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6058,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6059,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6060,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6059,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6060,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6061,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6062,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6061,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41067,47 +36020,21 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6063,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6062, 6063,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 6064,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6065,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6066,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6067,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6068,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6069,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6070,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6071,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6072,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6073,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41118,13 +36045,19 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6074,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6065,   -1,   -1,   -1, 6066,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6075,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6067,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6068,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41136,36 +36069,75 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6069,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6070,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6071,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6072,   -1,   -1,   -1,   -1,   -1,
+        -1, 6073,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6074,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6075,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 6076,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6077,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6077,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       6078,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6079,
+        -1,   -1,   -1,   -1,   -1, 6080,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6079,   -1,
+        -1,   -1, 6081,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6082,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6083,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6084,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6085,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6086, 6087, 6088,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6089,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6090,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41177,87 +36149,32 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6080,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6081,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6082,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6083,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6084,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6085,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6086,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6087,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6088,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6089,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6090,
         -1, 6091,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6092,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6093,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6094,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6095,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6092,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6096,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6093,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6097,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41265,60 +36182,28 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6098,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6094,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6099,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6095,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6096,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6100,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6097,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6098, 6099,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6100,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6101,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6102,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6101, 6102,   -1,
         -1, 6103,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41326,8 +36211,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6104,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6104,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41338,10 +36222,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6105,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6106,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6107,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41352,10 +36232,30 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6105,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6106,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6107,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 6108,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6109,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41365,18 +36265,21 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6109,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6110,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6110,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6111,   -1,   -1,   -1,   -1, 6112,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6113,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41384,18 +36287,19 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6111,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6114,   -1,   -1,   -1,   -1,
+      6115,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6116,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6112,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41403,10 +36307,10 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6113,   -1,   -1,   -1,   -1, 6114,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6117,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41417,137 +36321,91 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6115,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6116,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6118,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6119, 6120,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6117,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6118,   -1,   -1,   -1, 6119,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6121,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6122,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6123,   -1,   -1,   -1,
+        -1, 6124,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6120,   -1, 6121,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6122,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6123,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6124,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6125,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6125,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 6126,   -1,   -1,   -1,   -1,   -1,
-      6127,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6128,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6129,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6127,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6128,   -1,   -1,   -1,   -1,
+        -1,   -1, 6129,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6130,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6131,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6132,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6130,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6131,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6132,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6133,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6134,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6133,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6135,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6136,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6134,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41557,43 +36415,37 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6135,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6136,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6137,   -1,   -1,   -1,   -1,   -1,
-      6138,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6139,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6140,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6141,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6137,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6138,   -1,   -1, 6139,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6142,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6140,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6143,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6141,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6144,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6145,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6142,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41611,29 +36463,31 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6143,   -1,   -1,   -1,   -1,   -1, 6144,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6145,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6146,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6146,
+        -1,   -1,   -1,   -1, 6147,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6147,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6148,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6148,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6149,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6149,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41643,8 +36497,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6150,   -1,   -1,   -1,
-      6151,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41653,11 +36505,11 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6152,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6150,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6151,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6153,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41667,66 +36519,24 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6154,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6152,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6155,
+        -1,   -1, 6153,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6154,   -1, 6155,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1, 6156,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6157,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6158,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6159,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6157,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6160,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6161,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6162,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6163,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6164,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6165,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6166,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6167,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6168,   -1,   -1,
-        -1,   -1,   -1, 6169,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6158,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41740,15 +36550,54 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6159,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6160,   -1, 6161,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6162,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6163,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6164,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6165,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6166,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6167,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6168,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6169,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 6170,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       6171,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41756,51 +36605,29 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6172,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6173,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6172,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6173,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6174,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6175,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6174,   -1,   -1, 6175,   -1,   -1,
         -1,   -1, 6176,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6177,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6178,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6179,   -1,   -1, 6180,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41811,63 +36638,35 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6177,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6178,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6179,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6181,   -1,   -1,   -1,   -1, 6182,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6180,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6181,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6182,   -1,   -1, 6183,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6183,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       6184,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6185,   -1,   -1,   -1,
+      6185,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6186,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6186,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6187,
+      6187,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6188,   -1,   -1,   -1,   -1,
+      6189,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6188,   -1,   -1,   -1, 6189,   -1,
-        -1,   -1,   -1, 6190,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6190,   -1,
+        -1,   -1, 6191,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41878,90 +36677,27 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6191,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6192,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6193,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6194,   -1,   -1,   -1,   -1,
+      6192,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6195,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6193,   -1, 6194,   -1,   -1,   -1,   -1,   -1,
+      6195,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 6196,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6197,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6197,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
       6198,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6199,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6200,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6201,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6202,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6199,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41971,8 +36707,28 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6203,   -1,   -1,   -1,   -1,   -1,
-      6204,   -1, 6205,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6200,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6201,   -1, 6202,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6203,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41984,8 +36740,19 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6204,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6206,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6205,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6206,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -41995,9 +36762,8 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 6207,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6208,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6209,
+        -1, 6208,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42005,6 +36771,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6209,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42012,12 +36779,15 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6210,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6210,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6211,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6212,   -1,
+      6213,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42025,6 +36795,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6214,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42036,15 +36807,17 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6215,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6211,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6216,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6217,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42061,39 +36834,41 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6218,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6212,
+        -1,   -1,   -1, 6219,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6220,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6221,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6213,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6222,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6223,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6214,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6215,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6224,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6216,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6217,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6225,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42106,6 +36881,8 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6226,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6227,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42114,13 +36891,17 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6228,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6229,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6230,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6231,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42139,13 +36920,11 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6232,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6218,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6219,   -1,   -1,   -1,
-        -1, 6220,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42154,46 +36933,45 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6233,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6234,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6221,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6235,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6222,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6223,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6236, 6237,   -1,   -1,
+        -1, 6238,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6224,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6225,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6239,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6226,   -1,   -1,
-        -1, 6227,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6228,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6240,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42201,13 +36979,11 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6229,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6230,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42215,29 +36991,28 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6241,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6242,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6231,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6232,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6233,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42245,7 +37020,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6234,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42258,10 +37032,8 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6235,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6236,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42271,20 +37043,24 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6243,   -1,   -1,
+        -1, 6244,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6245,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6237,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6246,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6247,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42309,94 +37085,22 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6238,
+        -1,   -1, 6248,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6249,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6239,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6240,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6241,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6242,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6243,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6244,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6245,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6250,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6251,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6246,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6247,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6248,   -1,   -1,   -1, 6249,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42408,18 +37112,15 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6250,   -1,   -1,   -1,   -1, 6251,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6252,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6253,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42436,8 +37137,10 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6252,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6253,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42447,16 +37150,13 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6254,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6255,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6256,   -1, 6257,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42465,23 +37165,28 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6258,   -1,   -1,   -1,
+        -1,   -1,   -1, 6254,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6255,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6256,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6257,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6258,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6259,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42490,6 +37195,8 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6260,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6261,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42500,7 +37207,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6259,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42514,7 +37220,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6260,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6262,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42533,24 +37239,24 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6261,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6263,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6264,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6262,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6263,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6265,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6264,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6266,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42563,17 +37269,19 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6265,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6267,   -1,   -1,
+        -1,   -1,   -1, 6268,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6269,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6270,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6266,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42597,11 +37305,10 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6271,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6267,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6268,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42616,7 +37323,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6269,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42624,10 +37330,9 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6270,   -1,   -1,   -1,   -1,
+        -1,   -1, 6272,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6271,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42636,20 +37341,20 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6272,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6273,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6273,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6274,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42663,13 +37368,12 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6274,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6275,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6276,   -1,   -1,
+        -1,   -1,   -1,   -1, 6275,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6276,   -1,
         -1,   -1, 6277,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42691,20 +37395,16 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6278,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6279,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6280,   -1,   -1,
+        -1,   -1,   -1, 6278,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6279,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6280,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42731,22 +37431,18 @@
         -1,   -1,   -1,   -1,   -1, 6281,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6282,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6282,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 6283,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6284,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6285, 6286,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42754,63 +37450,9 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6284,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6285,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6286,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6287,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6288,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6287,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42818,21 +37460,11 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6288,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 6289,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6290,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6291,
+        -1, 6290,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42848,18 +37480,17 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6292,   -1,   -1, 6293,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6291,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6294,   -1,   -1,
+      6292,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42871,29 +37502,86 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6295,   -1,   -1, 6296,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6293,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6297,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6294,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6295,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6296,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6297,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 6298,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6299,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6300,   -1,   -1,
+        -1,   -1,   -1, 6299,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42923,6 +37611,19 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6300,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 6301,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42931,12 +37632,73 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6302,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6303,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6304,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6305,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6306,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6302,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42948,16 +37710,16 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6303,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6304,   -1,   -1,   -1,
+      6307,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6308,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42972,7 +37734,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6305,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -42986,7 +37747,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6306,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6309,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43004,6 +37765,8 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6310,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6311,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43015,27 +37778,24 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6307,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6312,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6308,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6309,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6310,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43048,18 +37808,32 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6311,   -1, 6312,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6313,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6313,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 6314,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6315,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6315,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6316,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6316,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43070,6 +37844,10 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6318,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6319,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43079,14 +37857,14 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6320,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6321,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6318,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6319,   -1,   -1,   -1,   -1,
+        -1,   -1, 6322,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43095,32 +37873,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6320,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6321,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6322,   -1,   -1,   -1,   -1, 6323,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6323,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 6324,
@@ -43129,12 +37882,15 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 6325,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6326,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43152,12 +37908,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6326,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6327,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43171,48 +37922,20 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6327,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1, 6328,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6329,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6330,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6329,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6331,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43222,20 +37945,22 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6330,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6332,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6333,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6334,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6335,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6331,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43243,163 +37968,12 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6336,   -1,   -1,   -1,   -1,   -1,   -1, 6337,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6332,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6333,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6334,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6335,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6336,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6337,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6338,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6339,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6338,   -1,   -1,   -1,   -1,   -1, 6339,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43423,61 +37997,33 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6341,   -1,   -1,   -1,   -1,   -1,
-      6342,   -1,   -1,   -1,   -1,   -1, 6343,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6341,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6342,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6343,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6344,   -1, 6345,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6346,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6344,
+        -1,   -1,   -1,   -1, 6345,   -1,   -1, 6346,
         -1,   -1,   -1,   -1, 6347,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6348,   -1,
+        -1,   -1,   -1, 6348,   -1,   -1,   -1,   -1,
+      6349,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6350,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6349,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6351,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43488,11 +38034,12 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6350,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6352, 6353,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6354,   -1, 6355,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43500,19 +38047,31 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6356,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6357,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6358,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6359, 6360,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6361,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6362,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6363,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6364,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6365, 6366,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6367, 6368,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6369,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6370,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43526,12 +38085,11 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6351,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6371,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6352,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43539,448 +38097,28 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6372,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6373,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6374,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6353,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6375,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6354,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6355,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6356,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6357,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6358,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6359,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6360,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6361,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6362,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6363,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6364,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6365,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6366,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6367,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6368,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6369,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6370,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6371,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6372,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6373,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6374,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6375,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6376,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6376,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -43993,30 +38131,32 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6378,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6378,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6379,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6380,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6379,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6380,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6381,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6382,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44027,7 +38167,9 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6383,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6384,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44036,10 +38178,12 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6385,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6386,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44058,12 +38202,12 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6381,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6387,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44072,11 +38216,14 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6388,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6389,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6390,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44085,6 +38232,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6391,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44092,7 +38240,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6382,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44106,7 +38253,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6383,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44123,163 +38269,12 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6384,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6385,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6386,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6387,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6388,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6389,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6390,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6391,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6392,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6392,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 6393,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44292,7 +38287,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6394,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44311,16 +38305,19 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6394,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6395,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6395,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1, 6396,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44330,30 +38327,34 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6397,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6398,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6399,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6397,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6400,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6401,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44374,11 +38375,13 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6402,   -1,   -1,   -1,   -1, 6403,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6404,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6405,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6398,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44395,6 +38398,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6406,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44403,270 +38407,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6399,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6400,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6401,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6402,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6403,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6404,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6405,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6406,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6407,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44675,7 +38416,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6407,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44690,6 +38430,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6409,   -1, 6410,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44704,47 +38445,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6409,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6410,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 6411,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44762,42 +38462,29 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1, 6412,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6413,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6414,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6415,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6413,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6416,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44813,11 +38500,13 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6417,   -1,   -1,
+        -1,   -1,   -1,   -1, 6418,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6414,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6419,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -44830,346 +38519,11 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6420,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6415,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6416,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6417,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6418,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6419,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6420,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6421,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6421,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45178,52 +38532,10 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6423,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6424,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6423,   -1,   -1,   -1,   -1, 6424,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6425,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6425,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45235,55 +38547,17 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6427,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6427,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 6428,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6429,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6429,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45295,6 +38569,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6431,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45311,16 +38586,15 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6432,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6431,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6432,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45350,6 +38624,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6433,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45364,110 +38639,13 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6434,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6435,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6433,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6434,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6435,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6436,   -1,   -1,   -1,
+        -1,   -1, 6436,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45487,11 +38665,13 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6438,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6439,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45530,11 +38710,13 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6440,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6441,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45542,7 +38724,9 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6442,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6443,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45573,6 +38757,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6444,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45584,283 +38769,13 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6438,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6439,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6440, 6441,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6442,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6443,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6444,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6445,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6445,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45877,6 +38792,20 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 6447,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45895,29 +38824,33 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6448,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6448,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6449,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6450,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6451,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6452,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -45991,14 +38924,13 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6453,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6449,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6450,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46020,7 +38952,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6451,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6454,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46032,6 +38964,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6455,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46058,12 +38991,9 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6452,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6453,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6454,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46082,11 +39012,14 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6456,   -1,   -1,
+      6457,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6458,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46116,206 +39049,10 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6459,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6460,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6455,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6456,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6457,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6458,
-        -1,   -1,   -1,   -1,   -1, 6459,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6460,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6461,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6461,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46323,7 +39060,6 @@
         -1,   -1,   -1, 6462,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6463,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46337,94 +39073,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6463,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1, 6464,   -1,
@@ -46432,6 +39081,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6465,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46439,7 +39089,9 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6466,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6467,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46447,178 +39099,9 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6465,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6466,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6467,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6468,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6468,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46629,7 +39112,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6470,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46640,6 +39122,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6470,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46647,6 +39130,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6471,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46654,7 +39138,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6471,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46665,14 +39148,15 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6472,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6472,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6473,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46680,22 +39164,23 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6474,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6473,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6474,   -1,   -1,   -1,   -1,   -1,   -1,
+      6475,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6476,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46732,7 +39217,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6475,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46746,7 +39230,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6476,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46782,7 +39265,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6477,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46792,11 +39274,13 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6477,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6478,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -46814,264 +39298,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6478,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6479,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6479,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47113,6 +39340,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6481,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47170,12 +39398,14 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6482,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6483,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47200,194 +39430,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6481,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6482,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6483,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6484,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6484,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47396,14 +39439,43 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1, 6485,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6486,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6486,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6487,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6487,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6488,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47434,20 +39506,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6488,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1, 6489,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47501,6 +39559,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6490,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47508,14 +39567,15 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6490,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6491,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6492,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47527,6 +39587,8 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6493,   -1,   -1,   -1,
+        -1,   -1, 6494,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47547,6 +39609,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6495,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47566,12 +39629,15 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6496,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6497,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6498,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47582,7 +39648,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6491,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6499,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47629,7 +39695,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6492,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47646,6 +39711,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6500,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47669,6 +39735,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6501,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47699,6 +39766,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6502,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47707,6 +39775,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6503,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47714,6 +39783,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6504,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47730,11 +39800,11 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6505,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6493,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47787,6 +39857,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6506,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47798,7 +39869,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6494,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47846,6 +39916,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6507,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47871,7 +39942,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1, 6495,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47879,6 +39949,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6508,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -47886,1538 +39957,8 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6496,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6497,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6498,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6499,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6500,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6501,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6502,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-      6503,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6504,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6505,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6506,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6507,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6508,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1, 6509,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6509,   -1,
+        -1,   -1,   -1,   -1,   -1, 6510,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -49428,7 +39969,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6510,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -49448,6 +39988,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6512,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -49479,6 +40020,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6513,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -49519,12 +40061,14 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6514,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6515,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -49534,6 +40078,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6516,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -49569,1750 +40114,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6512,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6513,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6514,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1, 6515,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1, 6516,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6517,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6517,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -51437,6 +40239,8256 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6519,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6520,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6521,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6522,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6523,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6524,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6525,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6526,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6527,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6528,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6529,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6530,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6531,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6532,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6533,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6534,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6535, 6536,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6537,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6538,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6539,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6540,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6541,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6542,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6543,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6544,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6545,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6546,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6547,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6548,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6549,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6550,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6551,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1, 6552,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6553,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1, 6554,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6555,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1, 6556,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1, 6557,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6558,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6559,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6560,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1, 6561,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6562,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1, 6563,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+      6564,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -52071,7 +49123,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1, 6519,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -52834,7 +49885,6 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1, 6520,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -54250,7 +51300,7 @@
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1, 6521
+        -1,   -1,   -1, 6565
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
@@ -54272,5 +51322,5 @@
     }
   return 0;
 }
-#line 6536 "effective_tld_names.gperf"
+#line 6580 "effective_tld_names.gperf"
 
diff --git a/net/base/registry_controlled_domains/effective_tld_names.dat b/net/base/registry_controlled_domains/effective_tld_names.dat
index 4518957..53287b9 100644
--- a/net/base/registry_controlled_domains/effective_tld_names.dat
+++ b/net/base/registry_controlled_domains/effective_tld_names.dat
@@ -1321,7 +1321,7 @@
 barlettatraniandria.it
 belluno.it
 benevento.it
-bergamo .it
+bergamo.it
 bg.it
 bi.it
 biella.it
@@ -1476,7 +1476,7 @@
 pn.it
 po.it
 pordenone.it
-potenza .it
+potenza.it
 pr.it
 prato.it
 pt.it
@@ -5737,7 +5737,7 @@
 info.sd
 
 // se : http://en.wikipedia.org/wiki/.se
-// Submitted by registry <Patrik.Wallstrom@iis.se> 2008-06-24
+// Submitted by registry <patrik.wallstrom@iis.se> 2014-03-18
 se
 a.se
 ac.se
@@ -5771,7 +5771,6 @@
 press.se
 r.se
 s.se
-sshn.se
 t.se
 tm.se
 u.se
@@ -7539,6 +7538,123 @@
 // rio : 2014-02-27 Empresa Municipal de Informática SA - IPLANRIO
 rio
 
+// cash : 2014-03-07 Delta Lake, LLC
+cash
+
+// gives : 2014-03-07 United TLD Holdco Ltd.
+gives
+
+// hiphop : 2014-03-07 Uniregistry, Corp.
+hiphop
+
+// degree : 2014-03-07 Puff House, LLC
+degree
+
+// digital : 2014-03-07 Dash Park, LLC
+digital
+
+// rehab : 2014-03-07 United TLD Holdco Ltd.
+rehab
+
+// wtf : 2014-03-07 Hidden Way, LLC
+wtf
+
+// financial : 2014-03-07 Just Cover, LLC
+financial
+
+// limited : 2014-03-07 Big Fest, LLC
+limited
+
+// discount : 2014-03-07 Holly Hill, LLC
+discount
+
+// fail : 2014-03-07 Atomic Pipe, LLC
+fail
+
+// vet : 2014-03-07 Wild Dale, LLC
+vet
+
+// ngo : 2014-03-07 Public Interest Registry
+ngo
+
+// fitness : 2014-03-07 Brice Orchard, LLC
+fitness
+
+// schule : 2014-03-07 Outer Moon, LLC
+schule
+
+// navy : 2014-03-07 United TLD Holdco Ltd.
+navy
+
+// bio : 2014-03-07 STARTING DOT LIMITED
+bio
+
+// ong : 2014-03-07 Public Interest Registry
+ong
+
+// town : 2014-03-07 Koko Moon, LLC
+town
+
+// toys : 2014-03-07 Pioneer Orchard, LLC
+toys
+
+// army : 2014-03-07 United TLD Holdco Ltd.
+army
+
+// engineering : 2014-03-07 Romeo Canyon
+engineering
+
+// capital : 2014-03-07 Delta Mill, LLC
+capital
+
+// exchange : 2014-03-07 Spring Falls, LLC
+exchange
+
+// fan : 2014-03-07 Goose Glen, LLC
+fan
+
+// market : 2014-03-07 Victor Way, LLC
+market
+
+// media : 2014-03-07 Grand Glen, LLC
+media
+
+// lease : 2014-03-07 Victor Trail, LLC
+lease
+
+// university : 2014-03-07 Little Station, LLC
+university
+
+// reisen : 2014-03-07 New Cypress, LLC
+reisen
+
+// airforce : 2014-03-07 United TLD Holdco Ltd.
+airforce
+
+// pictures : 2014-03-07 Foggy Sky, LLC
+pictures
+
+// gripe : 2014-03-07 Corn Sunset, LLC
+gripe
+
+// associates : 2014-03-07 Baxter Hill, LLC
+associates
+
+// xn--mxtq1m : 2014-03-07 Net-Chinese Co., Ltd.
+政府
+
+// williamhill : 2014-03-13 William Hill Organization Limited
+williamhill
+
+// hiv : 2014-03-13 dotHIV gemeinnuetziger e.V.
+hiv
+
+// sca : 2014-03-13 SVENSKA CELLULOSA AKTIEBOLAGET SCA (publ)
+sca
+
+// reise : 2014-03-13 dotreise GmbH
+reise
+
 
 // ===END ICANN DOMAINS===
 // ===BEGIN PRIVATE DOMAINS===
@@ -7608,12 +7724,12 @@
 eu.com
 gb.com
 gb.net
-gr.com
 hu.com
 hu.net
 jp.net
 jpn.com
 kr.com
+mex.com
 no.com
 qc.com
 ru.com
@@ -7623,10 +7739,30 @@
 uk.com
 uk.net
 us.com
-us.org
 uy.com
+za.bz
 za.com
 
+// Africa.com Web Solutions Ltd : https://registry.africa.com
+// Submitted by Gavin Brown <gavin.brown@centralnic.com> 2014-02-04
+africa.com
+
+// iDOT Services Limited : http://www.domain.gr.com
+// Submitted by Gavin Brown <gavin.brown@centralnic.com> 2014-02-04
+gr.com
+
+// Radix FZC : http://domains.in.net
+// Submitted by Gavin Brown <gavin.brown@centralnic.com> 2014-02-04
+in.net
+
+// US REGISTRY LLC : http://us.org
+// Submitted by Gavin Brown <gavin.brown@centralnic.com> 2014-02-04
+us.org
+
+// co.com Registry, LLC : https://registry.co.com
+// Submitted by Gavin Brown <gavin.brown@centralnic.com> 2014-02-04
+co.com
+
 // c.la : http://www.c.la/
 c.la
 
@@ -8026,6 +8162,10 @@
 // Submitted by Yngve Pettersen <yngve@opera.com> 2009-11-26
 operaunite.com
 
+// OutSystems
+// Submitted by Duarte Santos <domain-admin@outsystemscloud.com> 2014-03-11
+outsystemscloud.com
+
 // Red Hat, Inc. OpenShift : https://openshift.redhat.com/
 // Submitted by Tim Kramer <tkramer@rhcloud.com> 2012-10-24
 rhcloud.com
diff --git a/net/base/registry_controlled_domains/effective_tld_names.gperf b/net/base/registry_controlled_domains/effective_tld_names.gperf
index b3760cf..34eebf0 100644
--- a/net/base/registry_controlled_domains/effective_tld_names.gperf
+++ b/net/base/registry_controlled_domains/effective_tld_names.gperf
@@ -97,6 +97,7 @@
 aeroport.fr, 0
 af, 0
 afjord.no, 0
+africa.com, 4
 ag, 0
 ag.it, 0
 aga.niigata.jp, 0
@@ -126,6 +127,7 @@
 air-traffic-control.aero, 0
 air.museum, 0
 aircraft.aero, 0
+airforce, 0
 airguard.museum, 0
 airline.aero, 0
 airport.aero, 0
@@ -253,6 +255,7 @@
 aridagawa.wakayama.jp, 0
 arita.saga.jp, 0
 arkhangelsk.ru, 0
+army, 0
 arna.no, 0
 arpa, 0
 arq.br, 0
@@ -321,6 +324,7 @@
 asso.mc, 0
 asso.nc, 0
 asso.re, 0
+associates, 0
 association.aero, 0
 association.museum, 0
 asti.it, 0
@@ -440,7 +444,7 @@
 benevento.it, 0
 beppu.oita.jp, 0
 berg.no, 0
-bergamo, 0
+bergamo.it, 0
 bergbau.museum, 0
 bergen.no, 0
 berkeley.museum, 0
@@ -474,6 +478,7 @@
 bilbao.museum, 0
 bill.museum, 0
 bindal.no, 0
+bio, 0
 bio.br, 0
 bir.ru, 0
 biratori.hokkaido.jp, 0
@@ -662,6 +667,7 @@
 can.museum, 0
 canada.museum, 0
 capebreton.museum, 0
+capital, 0
 caravan, 0
 carbonia-iglesias.it, 0
 carboniaiglesias.it, 0
@@ -676,6 +682,7 @@
 casa, 0
 casadelamoneda.museum, 0
 caserta.it, 0
+cash, 0
 casino.hu, 0
 castle.museum, 0
 castres.museum, 0
@@ -874,6 +881,7 @@
 co.ca, 4
 co.ci, 0
 co.cl, 0
+co.com, 4
 co.cr, 0
 co.gg, 0
 co.gy, 0
@@ -1160,6 +1168,7 @@
 deatnu.no, 0
 decorativearts.museum, 0
 defense.tn, 0
+degree, 0
 delaware.museum, 0
 dell-ogliastra.it, 0
 dellogliastra.it, 0
@@ -1176,8 +1185,10 @@
 dgca.aero, 0
 diamonds, 0
 dielddanuorri.no, 0
+digital, 0
 dinosaur.museum, 0
 directory, 0
+discount, 0
 discovery.museum, 0
 divtasvuodna.no, 0
 divttasvuotna.no, 0
@@ -1426,6 +1437,7 @@
 engerdal.no, 0
 engine.aero, 0
 engineer.aero, 0
+engineering, 0
 england.museum, 0
 eniwa.hokkaido.jp, 0
 enna.it, 0
@@ -1472,6 +1484,7 @@
 evenes.no, 0
 events, 0
 evje-og-hornnes.no, 0
+exchange, 0
 exchange.aero, 0
 exeter.museum, 0
 exhibition.museum, 0
@@ -1481,8 +1494,10 @@
 express.aero, 0
 f.bg, 0
 f.se, 0
+fail, 0
 fam.pk, 0
 family.museum, 0
+fan, 0
 far.br, 0
 fareast.ru, 0
 farm, 0
@@ -1518,6 +1533,7 @@
 film.museum, 0
 fin.ec, 0
 fin.tn, 0
+financial, 0
 fineart.museum, 0
 finearts.museum, 0
 finland.museum, 0
@@ -1531,6 +1547,7 @@
 fish, 0
 fishing, 0
 fitjar.no, 0
+fitness, 0
 fj, 2
 fj.cn, 0
 fjaler.no, 0
@@ -1790,6 +1807,7 @@
 giske.no, 0
 github.io, 4
 githubusercontent.com, 4
+gives, 0
 gjemnes.no, 0
 gjerdrum.no, 0
 gjerstad.no, 0
@@ -1995,6 +2013,7 @@
 graz.museum, 0
 greta.fr, 0
 grimstad.no, 0
+gripe, 0
 groks-the.info, 4
 groks-this.info, 4
 grong.no, 0
@@ -2194,6 +2213,7 @@
 hinode.tokyo.jp, 0
 hinohara.tokyo.jp, 0
 hioki.kagoshima.jp, 0
+hiphop, 0
 hirado.nagasaki.jp, 0
 hiraizumi.iwate.jp, 0
 hirakata.osaka.jp, 0
@@ -2225,6 +2245,7 @@
 hitachiota.ibaraki.jp, 0
 hitoyoshi.kumamoto.jp, 0
 hitra.no, 0
+hiv, 0
 hizen.saga.jp, 0
 hjartdal.no, 0
 hjelmeland.no, 0
@@ -2374,6 +2395,7 @@
 in-addr.arpa, 0
 in-the-band.net, 4
 in.na, 0
+in.net, 4
 in.rs, 0
 in.th, 0
 in.ua, 0
@@ -3161,6 +3183,7 @@
 lc.it, 0
 le.it, 0
 leangaviika.no, 0
+lease, 0
 leasing.aero, 0
 lebesby.no, 0
 lebork.pl, 0
@@ -3252,6 +3275,7 @@
 lillehammer.no, 0
 lillesand.no, 0
 limanowa.pl, 0
+limited, 0
 limo, 0
 lincoln.museum, 0
 lindas.no, 0
@@ -3360,6 +3384,7 @@
 maritime.museum, 0
 maritimo.museum, 0
 marker.no, 0
+market, 0
 marketing, 0
 marketplace.aero, 0
 marnardal.no, 0
@@ -3422,6 +3447,7 @@
 med.sd, 0
 medecin.fr, 0
 medecin.km, 0
+media, 0
 media.aero, 0
 media.hu, 0
 media.museum, 0
@@ -3446,6 +3472,7 @@
 merseine.nu, 4
 mesaverde.museum, 0
 messina.it, 0
+mex.com, 4
 mg, 0
 mh, 0
 mi.it, 0
@@ -3875,6 +3902,7 @@
 naval.museum, 0
 navigation.aero, 0
 navuotna.no, 0
+navy, 0
 nayoro.hokkaido.jp, 0
 nb.ca, 0
 nc, 0
@@ -4029,6 +4057,7 @@
 nf, 0
 nf.ca, 0
 ng, 0
+ngo, 0
 ngo.lk, 0
 ngo.ph, 0
 ngo.pl, 0
@@ -4288,6 +4317,7 @@
 on-the-web.tv, 4
 on.ca, 0
 onagawa.miyagi.jp, 0
+ong, 0
 onga.fukuoka.jp, 0
 onjuku.chiba.jp, 0
 onl, 0
@@ -4509,6 +4539,7 @@
 ouchi.saga.jp, 0
 ouda.nara.jp, 0
 oumu.hokkaido.jp, 0
+outsystemscloud.com, 4
 overhalla.no, 0
 ovh, 0
 ovre-eiker.no, 0
@@ -4593,6 +4624,7 @@
 pi.it, 0
 piacenza.it, 0
 pics, 0
+pictures, 0
 piedmont.it, 0
 piemonte.it, 0
 pila.pl, 0
@@ -4641,7 +4673,7 @@
 portlligat.museum, 0
 post, 0
 posts-and-telecommunications.museum, 0
-potenza, 0
+potenza.it, 0
 powiat.pl, 0
 poznan.pl, 0
 pp.az, 0
@@ -4770,6 +4802,9 @@
 reggio-emilia.it, 0
 reggiocalabria.it, 0
 reggioemilia.it, 0
+rehab, 0
+reise, 0
+reisen, 0
 reklam.hu, 0
 rel.ht, 0
 rel.pl, 0
@@ -4992,6 +5027,7 @@
 sc.tz, 0
 sc.ug, 0
 sc.us, 0
+sca, 0
 scb, 0
 sch.ae, 0
 sch.id, 0
@@ -5008,6 +5044,7 @@
 schokoladen.museum, 0
 school.museum, 0
 school.na, 0
+schule, 0
 schweiz.museum, 0
 sci.eg, 0
 science-fiction.museum, 0
@@ -5302,7 +5339,6 @@
 sr.it, 0
 srv.br, 0
 ss.it, 0
-sshn.se, 0
 st, 0
 st.no, 0
 stadt.museum, 0
@@ -5642,6 +5678,7 @@
 tourism.pl, 0
 tourism.tn, 0
 towada.aomori.jp, 0
+town, 0
 town.museum, 0
 toya.hokkaido.jp, 0
 toyako.hokkaido.jp, 0
@@ -5661,6 +5698,7 @@
 toyotomi.hokkaido.jp, 0
 toyotsu.fukuoka.jp, 0
 toyoura.hokkaido.jp, 0
+toys, 0
 tozawa.yamagata.jp, 0
 tozsde.hu, 0
 tp, 0
@@ -5828,6 +5866,7 @@
 undersea.museum, 0
 union.aero, 0
 univ.sn, 0
+university, 0
 university.museum, 0
 unjarga.no, 0
 unnan.shimane.jp, 0
@@ -5953,6 +5992,7 @@
 vestre-slidre.no, 0
 vestre-toten.no, 0
 vestvagoy.no, 0
+vet, 0
 vet.br, 0
 veterinaire.fr, 0
 veterinaire.km, 0
@@ -6074,6 +6114,7 @@
 wiki, 0
 wiki.br, 0
 wildlife.museum, 0
+williamhill, 0
 williamsburg.museum, 0
 windmill.museum, 0
 withgoogle.com, 4
@@ -6094,6 +6135,7 @@
 ws, 0
 ws.na, 0
 wtc, 0
+wtf, 0
 wv.us, 0
 www.ck, 1
 www.ro, 0
@@ -6270,6 +6312,7 @@
 xn--msy-ula0h.no, 0
 xn--mtta-vrjjat-k7af.no, 0
 xn--muost-0qa.no, 0
+xn--mxtq1m, 0
 xn--mxtq1m.hk, 0
 xn--ngbc5azd, 0
 xn--nmesjevuemie-tcba.no, 0
@@ -6505,6 +6548,7 @@
 z.bg, 0
 z.se, 0
 za, 2
+za.bz, 4
 za.com, 4
 za.net, 4
 za.org, 4
diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc
index df70540..4dd7560 100644
--- a/net/cert/cert_verify_proc.cc
+++ b/net/cert/cert_verify_proc.cc
@@ -4,6 +4,7 @@
 
 #include "net/cert/cert_verify_proc.h"
 
+#include "base/basictypes.h"
 #include "base/metrics/histogram.h"
 #include "base/sha1.h"
 #include "base/strings/stringprintf.h"
@@ -341,6 +342,25 @@
     }
   }
 
+  // CloudFlare revoked all certificates issued prior to April 2nd, 2014. Thus
+  // all certificates where the CN ends with ".cloudflare.com" with a prior
+  // issuance date are rejected.
+  //
+  // The old certs had a lifetime of five years, so this can be removed April
+  // 2nd, 2019.
+  const std::string& cn = cert->subject().common_name;
+  static const char kCloudFlareCNSuffix[] = ".cloudflare.com";
+  // kCloudFlareEpoch is the base::Time internal value for midnight at the
+  // beginning of April 2nd, 2014, UTC.
+  static const int64 kCloudFlareEpoch = INT64_C(13040870400000000);
+  if (cn.size() > arraysize(kCloudFlareCNSuffix) - 1 &&
+      cn.compare(cn.size() - (arraysize(kCloudFlareCNSuffix) - 1),
+                 arraysize(kCloudFlareCNSuffix) - 1,
+                 kCloudFlareCNSuffix) == 0 &&
+      cert->valid_start() < base::Time::FromInternalValue(kCloudFlareEpoch)) {
+    return true;
+  }
+
   return false;
 }
 
diff --git a/net/cert/nss_cert_database.h b/net/cert/nss_cert_database.h
index 94f1f20..df52e58 100644
--- a/net/cert/nss_cert_database.h
+++ b/net/cert/nss_cert_database.h
@@ -211,9 +211,9 @@
   // thread on which this is called is the thread on which |observer| will be
   // called back with notifications.
   // NOTE: CertDatabase::AddObserver should be preferred. Observers registered
-  // here will only recieve notifications generated directly through the
+  // here will only receive notifications generated directly through the
   // NSSCertDatabase, but not those from the CertDatabase. The CertDatabase
-  // observers will recieve both.
+  // observers will receive both.
   void AddObserver(Observer* observer);
 
   // Unregisters |observer| from receiving notifications.  This must be called
diff --git a/net/cert_verify_status_android_java.target.darwin-arm.mk b/net/cert_verify_status_android_java.target.darwin-arm.mk
index d4b9c4e..07c90d4 100644
--- a/net/cert_verify_status_android_java.target.darwin-arm.mk
+++ b/net/cert_verify_status_android_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_cert_verify_status_android_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/cert_verify_status_android_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertVerifyStatusAndroid.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/cert_verify_status_android_java.target.darwin-arm64.mk b/net/cert_verify_status_android_java.target.darwin-arm64.mk
index a7e0e3f..48ff8d3 100644
--- a/net/cert_verify_status_android_java.target.darwin-arm64.mk
+++ b/net/cert_verify_status_android_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_cert_verify_status_android_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/cert_verify_status_android_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertVerifyStatusAndroid.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/cert_verify_status_android_java.target.darwin-mips.mk b/net/cert_verify_status_android_java.target.darwin-mips.mk
index 4eecf4a..e8c9b21 100644
--- a/net/cert_verify_status_android_java.target.darwin-mips.mk
+++ b/net/cert_verify_status_android_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_cert_verify_status_android_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/cert_verify_status_android_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertVerifyStatusAndroid.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/cert_verify_status_android_java.target.darwin-x86.mk b/net/cert_verify_status_android_java.target.darwin-x86.mk
index b30df07..049342d 100644
--- a/net/cert_verify_status_android_java.target.darwin-x86.mk
+++ b/net/cert_verify_status_android_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_cert_verify_status_android_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/cert_verify_status_android_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertVerifyStatusAndroid.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/cert_verify_status_android_java.target.darwin-x86_64.mk b/net/cert_verify_status_android_java.target.darwin-x86_64.mk
index 2f4972e..57a6b09 100644
--- a/net/cert_verify_status_android_java.target.darwin-x86_64.mk
+++ b/net/cert_verify_status_android_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_cert_verify_status_android_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/cert_verify_status_android_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertVerifyStatusAndroid.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/cert_verify_status_android_java.target.linux-arm.mk b/net/cert_verify_status_android_java.target.linux-arm.mk
index d4b9c4e..07c90d4 100644
--- a/net/cert_verify_status_android_java.target.linux-arm.mk
+++ b/net/cert_verify_status_android_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_cert_verify_status_android_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/cert_verify_status_android_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertVerifyStatusAndroid.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/cert_verify_status_android_java.target.linux-arm64.mk b/net/cert_verify_status_android_java.target.linux-arm64.mk
index a7e0e3f..48ff8d3 100644
--- a/net/cert_verify_status_android_java.target.linux-arm64.mk
+++ b/net/cert_verify_status_android_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_cert_verify_status_android_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/cert_verify_status_android_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertVerifyStatusAndroid.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/cert_verify_status_android_java.target.linux-mips.mk b/net/cert_verify_status_android_java.target.linux-mips.mk
index 4eecf4a..e8c9b21 100644
--- a/net/cert_verify_status_android_java.target.linux-mips.mk
+++ b/net/cert_verify_status_android_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_cert_verify_status_android_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/cert_verify_status_android_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertVerifyStatusAndroid.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/cert_verify_status_android_java.target.linux-x86.mk b/net/cert_verify_status_android_java.target.linux-x86.mk
index b30df07..049342d 100644
--- a/net/cert_verify_status_android_java.target.linux-x86.mk
+++ b/net/cert_verify_status_android_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_cert_verify_status_android_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/cert_verify_status_android_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertVerifyStatusAndroid.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/cert_verify_status_android_java.target.linux-x86_64.mk b/net/cert_verify_status_android_java.target.linux-x86_64.mk
index 2f4972e..57a6b09 100644
--- a/net/cert_verify_status_android_java.target.linux-x86_64.mk
+++ b/net/cert_verify_status_android_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_cert_verify_status_android_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/cert_verify_status_android_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertVerifyStatusAndroid.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertVerifyStatusAndroid.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/certificate_mime_types_java.target.darwin-arm.mk b/net/certificate_mime_types_java.target.darwin-arm.mk
index dc1d144..cc24e4a 100644
--- a/net/certificate_mime_types_java.target.darwin-arm.mk
+++ b/net/certificate_mime_types_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_certificate_mime_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/mime_util_certificate_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertificateMimeType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/certificate_mime_types_java.target.darwin-arm64.mk b/net/certificate_mime_types_java.target.darwin-arm64.mk
index ed714ff..3bd6d35 100644
--- a/net/certificate_mime_types_java.target.darwin-arm64.mk
+++ b/net/certificate_mime_types_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_certificate_mime_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/mime_util_certificate_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertificateMimeType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/certificate_mime_types_java.target.darwin-mips.mk b/net/certificate_mime_types_java.target.darwin-mips.mk
index 606d392..cf75dd8 100644
--- a/net/certificate_mime_types_java.target.darwin-mips.mk
+++ b/net/certificate_mime_types_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_certificate_mime_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/mime_util_certificate_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertificateMimeType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/certificate_mime_types_java.target.darwin-x86.mk b/net/certificate_mime_types_java.target.darwin-x86.mk
index e8fc2fc..a0404c5 100644
--- a/net/certificate_mime_types_java.target.darwin-x86.mk
+++ b/net/certificate_mime_types_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_certificate_mime_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/mime_util_certificate_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertificateMimeType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/certificate_mime_types_java.target.darwin-x86_64.mk b/net/certificate_mime_types_java.target.darwin-x86_64.mk
index 2e6db52..4f6eb82 100644
--- a/net/certificate_mime_types_java.target.darwin-x86_64.mk
+++ b/net/certificate_mime_types_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_certificate_mime_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/mime_util_certificate_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertificateMimeType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/certificate_mime_types_java.target.linux-arm.mk b/net/certificate_mime_types_java.target.linux-arm.mk
index dc1d144..cc24e4a 100644
--- a/net/certificate_mime_types_java.target.linux-arm.mk
+++ b/net/certificate_mime_types_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_certificate_mime_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/mime_util_certificate_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertificateMimeType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/certificate_mime_types_java.target.linux-arm64.mk b/net/certificate_mime_types_java.target.linux-arm64.mk
index ed714ff..3bd6d35 100644
--- a/net/certificate_mime_types_java.target.linux-arm64.mk
+++ b/net/certificate_mime_types_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_certificate_mime_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/mime_util_certificate_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertificateMimeType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/certificate_mime_types_java.target.linux-mips.mk b/net/certificate_mime_types_java.target.linux-mips.mk
index 606d392..cf75dd8 100644
--- a/net/certificate_mime_types_java.target.linux-mips.mk
+++ b/net/certificate_mime_types_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_certificate_mime_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/mime_util_certificate_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertificateMimeType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/certificate_mime_types_java.target.linux-x86.mk b/net/certificate_mime_types_java.target.linux-x86.mk
index e8fc2fc..a0404c5 100644
--- a/net/certificate_mime_types_java.target.linux-x86.mk
+++ b/net/certificate_mime_types_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_certificate_mime_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/mime_util_certificate_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertificateMimeType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/certificate_mime_types_java.target.linux-x86_64.mk b/net/certificate_mime_types_java.target.linux-x86_64.mk
index 2e6db52..4f6eb82 100644
--- a/net/certificate_mime_types_java.target.linux-x86_64.mk
+++ b/net/certificate_mime_types_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_certificate_mime_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/mime_util_certificate_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/CertificateMimeType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/CertificateMimeType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/dns/dns_config_service_win.cc b/net/dns/dns_config_service_win.cc
index 192ad7a..4d837f0 100644
--- a/net/dns/dns_config_service_win.cc
+++ b/net/dns/dns_config_service_win.cc
@@ -139,7 +139,7 @@
     return false;
 
   // Check if already ASCII.
-  if (IsStringASCII(widestr)) {
+  if (base::IsStringASCII(widestr)) {
     *domain = base::UTF16ToASCII(widestr);
     return true;
   }
@@ -155,7 +155,7 @@
   // copy. Since ASCII is a subset of UTF8 the following is equivalent).
   bool success = base::UTF16ToUTF8(punycode.data(), punycode.length(), domain);
   DCHECK(success);
-  DCHECK(IsStringASCII(*domain));
+  DCHECK(base::IsStringASCII(*domain));
   return success && !domain->empty();
 }
 
diff --git a/net/dns/mdns_client.h b/net/dns/mdns_client.h
index 67cc849..675f8de 100644
--- a/net/dns/mdns_client.h
+++ b/net/dns/mdns_client.h
@@ -27,7 +27,7 @@
 // time out after a reasonable number of seconds.
 class NET_EXPORT MDnsTransaction {
  public:
-  // Used to signify what type of result the transaction has recieved.
+  // Used to signify what type of result the transaction has received.
   enum Result {
     // Passed whenever a record is found.
     RESULT_RECORD,
diff --git a/net/dns/record_parsed.cc b/net/dns/record_parsed.cc
index 36ff129..4ae6ed2 100644
--- a/net/dns/record_parsed.cc
+++ b/net/dns/record_parsed.cc
@@ -53,7 +53,7 @@
       rdata = NsecRecordRdata::Create(record.rdata, *parser);
       break;
     default:
-      DVLOG(1) << "Unknown RData type for recieved record: " << record.type;
+      DVLOG(1) << "Unknown RData type for received record: " << record.type;
       return scoped_ptr<const RecordParsed>();
   }
 
diff --git a/net/ftp/ftp_network_transaction.cc b/net/ftp/ftp_network_transaction.cc
index 3455fc6..7820715 100644
--- a/net/ftp/ftp_network_transaction.cc
+++ b/net/ftp/ftp_network_transaction.cc
@@ -152,7 +152,7 @@
     return false;
 
   std::string line(response.lines[0]);
-  if (!IsStringASCII(line))
+  if (!base::IsStringASCII(line))
     return false;
   if (line.length() < 2)
     return false;
@@ -830,7 +830,7 @@
       // The response should be ASCII, which allows us to do case-insensitive
       // comparisons easily. If it is not ASCII, we leave the system type
       // as unknown.
-      if (IsStringASCII(line)) {
+      if (base::IsStringASCII(line)) {
         line = StringToLowerASCII(line);
 
         // Remove all whitespace, to correctly handle cases like fancy "V M S"
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc
index 8c7dc1e..f114f19 100644
--- a/net/http/http_cache.cc
+++ b/net/http/http_cache.cc
@@ -293,7 +293,8 @@
       mode_(NORMAL),
       quic_server_info_factory_(params.enable_quic_persist_server_info ?
           new QuicServerInfoFactoryAdaptor(this) : NULL),
-      network_layer_(new HttpNetworkLayer(new HttpNetworkSession(params))) {
+      network_layer_(new HttpNetworkLayer(new HttpNetworkSession(params))),
+      weak_factory_(this) {
   HttpNetworkSession* session = network_layer_->GetSession();
   session->quic_stream_factory()->set_quic_server_info_factory(
       quic_server_info_factory_.get());
@@ -308,7 +309,8 @@
       backend_factory_(backend_factory),
       building_backend_(false),
       mode_(NORMAL),
-      network_layer_(new HttpNetworkLayer(session)) {
+      network_layer_(new HttpNetworkLayer(session)),
+      weak_factory_(this) {
 }
 
 HttpCache::HttpCache(HttpTransactionFactory* network_layer,
@@ -318,10 +320,15 @@
       backend_factory_(backend_factory),
       building_backend_(false),
       mode_(NORMAL),
-      network_layer_(network_layer) {
+      network_layer_(network_layer),
+      weak_factory_(this) {
 }
 
 HttpCache::~HttpCache() {
+  // Transactions should see an invalid cache after this point; otherwise they
+  // could see an inconsistent object (half destroyed).
+  weak_factory_.InvalidateWeakPtrs();
+
   // If we have any active entries remaining, then we need to deactivate them.
   // We may have some pending calls to OnProcessPendingQueue, but since those
   // won't run (due to our destruction), we can simply ignore the corresponding
@@ -500,7 +507,7 @@
 
   pending_op->writer = item.release();
   pending_op->callback = base::Bind(&HttpCache::OnPendingOpComplete,
-                                    AsWeakPtr(), pending_op);
+                                    GetWeakPtr(), pending_op);
 
   int rv = backend_factory_->CreateBackend(net_log_, &pending_op->backend,
                                            pending_op->callback);
@@ -615,7 +622,7 @@
 
   pending_op->writer = item;
   pending_op->callback = base::Bind(&HttpCache::OnPendingOpComplete,
-                                    AsWeakPtr(), pending_op);
+                                    GetWeakPtr(), pending_op);
 
   int rv = disk_cache_->DoomEntry(key, pending_op->callback);
   if (rv != ERR_IO_PENDING) {
@@ -755,7 +762,7 @@
 
   pending_op->writer = item;
   pending_op->callback = base::Bind(&HttpCache::OnPendingOpComplete,
-                                    AsWeakPtr(), pending_op);
+                                    GetWeakPtr(), pending_op);
 
   int rv = disk_cache_->OpenEntry(key, &(pending_op->disk_entry),
                                   pending_op->callback);
@@ -784,7 +791,7 @@
 
   pending_op->writer = item;
   pending_op->callback = base::Bind(&HttpCache::OnPendingOpComplete,
-                                    AsWeakPtr(), pending_op);
+                                    GetWeakPtr(), pending_op);
 
   int rv = disk_cache_->CreateEntry(key, &(pending_op->disk_entry),
                                     pending_op->callback);
@@ -1010,7 +1017,7 @@
 
   base::MessageLoop::current()->PostTask(
       FROM_HERE,
-      base::Bind(&HttpCache::OnProcessPendingQueue, AsWeakPtr(), entry));
+      base::Bind(&HttpCache::OnProcessPendingQueue, GetWeakPtr(), entry));
 }
 
 void HttpCache::OnProcessPendingQueue(ActiveEntry* entry) {
@@ -1167,8 +1174,8 @@
 
     base::MessageLoop::current()->PostTask(
         FROM_HERE,
-        base::Bind(
-            &HttpCache::OnBackendCreated, AsWeakPtr(), result, pending_op));
+        base::Bind(&HttpCache::OnBackendCreated, GetWeakPtr(),
+                   result, pending_op));
   } else {
     building_backend_ = false;
     DeletePendingOp(pending_op);
diff --git a/net/http/http_cache.h b/net/http/http_cache.h
index dd9d0cd..8784c8a 100644
--- a/net/http/http_cache.h
+++ b/net/http/http_cache.h
@@ -60,7 +60,6 @@
 struct HttpRequestInfo;
 
 class NET_EXPORT HttpCache : public HttpTransactionFactory,
-                             public base::SupportsWeakPtr<HttpCache>,
                              NON_EXPORTED_BASE(public base::NonThreadSafe) {
  public:
   // The cache mode of operation.
@@ -195,6 +194,8 @@
   virtual HttpCache* GetCache() OVERRIDE;
   virtual HttpNetworkSession* GetSession() OVERRIDE;
 
+  base::WeakPtr<HttpCache> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
+
   // Resets the network layer to allow for tests that probe
   // network changes (e.g. host unreachable).  The old network layer is
   // returned to allow for filter patterns that only intercept
@@ -406,6 +407,8 @@
 
   scoped_ptr<PlaybackCacheMap> playback_cache_map_;
 
+  base::WeakPtrFactory<HttpCache> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(HttpCache);
 };
 
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index e2d46be..6481990 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -187,7 +187,7 @@
     : next_state_(STATE_NONE),
       request_(NULL),
       priority_(priority),
-      cache_(cache->AsWeakPtr()),
+      cache_(cache->GetWeakPtr()),
       entry_(NULL),
       new_entry_(NULL),
       new_response_(NULL),
diff --git a/net/http/http_content_disposition.cc b/net/http/http_content_disposition.cc
index 83098f4..3a1dede 100644
--- a/net/http/http_content_disposition.cc
+++ b/net/http/http_content_disposition.cc
@@ -86,9 +86,9 @@
   if (encoded_word.empty())
     return true;
 
-  if (!IsStringASCII(encoded_word)) {
+  if (!base::IsStringASCII(encoded_word)) {
     // Try UTF-8, referrer_charset and the native OS default charset in turn.
-    if (IsStringUTF8(encoded_word)) {
+    if (base::IsStringUTF8(encoded_word)) {
       *output = encoded_word;
     } else {
       base::string16 utf16_output;
@@ -191,7 +191,7 @@
   if (decoded_word != encoded_word)
     *parse_result_flags |=
         net::HttpContentDisposition::HAS_PERCENT_ENCODED_STRINGS;
-  if (IsStringUTF8(decoded_word)) {
+  if (base::IsStringUTF8(decoded_word)) {
     output->swap(decoded_word);
     return true;
     // We can try either the OS default charset or 'origin charset' here,
@@ -317,7 +317,7 @@
     return false;
 
   // RFC 5987 value should be ASCII-only.
-  if (!IsStringASCII(value)) {
+  if (!base::IsStringASCII(value)) {
     decoded->clear();
     return true;
   }
diff --git a/net/http/http_network_layer_unittest.cc b/net/http/http_network_layer_unittest.cc
index 06471b4..5e12895 100644
--- a/net/http/http_network_layer_unittest.cc
+++ b/net/http/http_network_layer_unittest.cc
@@ -108,7 +108,7 @@
   // Simulates a request through a proxy which returns a bypass, which is then
   // retried through a second proxy that doesn't bypass.
   // Checks that the expected requests were issued, the expected content was
-  // recieved, and the first proxy |bad_proxy| was marked as bad.
+  // received, and the first proxy |bad_proxy| was marked as bad.
   void TestProxyFallback(const std::string& bad_proxy) {
     MockRead data_reads[] = {
       MockRead("HTTP/1.1 200 OK\r\n"
diff --git a/net/http/http_security_headers_unittest.cc b/net/http/http_security_headers_unittest.cc
index 9aae8ae..b6fa4ef 100644
--- a/net/http/http_security_headers_unittest.cc
+++ b/net/http/http_security_headers_unittest.cc
@@ -501,13 +501,15 @@
 
 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) {
   TransportSecurityState state;
-  TransportSecurityState::DomainState domain_state;
+  TransportSecurityState::DomainState static_domain_state;
 
   // docs.google.com has preloaded pins.
+  const bool sni_enabled = true;
   std::string domain = "docs.google.com";
-  EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state));
-  EXPECT_GT(domain_state.static_spki_hashes.size(), 1UL);
-  HashValueVector saved_hashes = domain_state.static_spki_hashes;
+  EXPECT_TRUE(
+      state.GetStaticDomainState(domain, sni_enabled, &static_domain_state));
+  EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL);
+  HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes;
 
   // Add a header, which should only update the dynamic state.
   HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
@@ -522,49 +524,103 @@
   ssl_info.public_key_hashes.push_back(saved_hashes[0]);
   EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
 
-  // Expect the preloaded state to remain unchanged.
-  std::string canonicalized_host = TransportSecurityState::CanonicalizeHost(
-      domain);
-  TransportSecurityState::DomainState static_domain_state;
-  EXPECT_TRUE(state.GetStaticDomainState(canonicalized_host,
-                                         true,
-                                         &static_domain_state));
+  // Expect the static state to remain unchanged.
+  TransportSecurityState::DomainState new_static_domain_state;
+  EXPECT_TRUE(state.GetStaticDomainState(
+      domain, sni_enabled, &new_static_domain_state));
   for (size_t i = 0; i < saved_hashes.size(); ++i) {
-    EXPECT_TRUE(HashValuesEqual(
-        saved_hashes[i])(static_domain_state.static_spki_hashes[i]));
+    EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
+        new_static_domain_state.pkp.spki_hashes[i]));
   }
 
   // Expect the dynamic state to reflect the header.
   TransportSecurityState::DomainState dynamic_domain_state;
   EXPECT_TRUE(state.GetDynamicDomainState(domain, &dynamic_domain_state));
-  EXPECT_EQ(2UL, dynamic_domain_state.dynamic_spki_hashes.size());
+  EXPECT_EQ(2UL, dynamic_domain_state.pkp.spki_hashes.size());
 
-  HashValueVector::const_iterator hash = std::find_if(
-      dynamic_domain_state.dynamic_spki_hashes.begin(),
-      dynamic_domain_state.dynamic_spki_hashes.end(),
-      HashValuesEqual(good_hash));
-  EXPECT_NE(dynamic_domain_state.dynamic_spki_hashes.end(), hash);
+  HashValueVector::const_iterator hash =
+      std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(),
+                   dynamic_domain_state.pkp.spki_hashes.end(),
+                   HashValuesEqual(good_hash));
+  EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash);
 
-  hash = std::find_if(
-      dynamic_domain_state.dynamic_spki_hashes.begin(),
-      dynamic_domain_state.dynamic_spki_hashes.end(),
-      HashValuesEqual(backup_hash));
-  EXPECT_NE(dynamic_domain_state.dynamic_spki_hashes.end(), hash);
+  hash = std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(),
+                      dynamic_domain_state.pkp.spki_hashes.end(),
+                      HashValuesEqual(backup_hash));
+  EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash);
 
   // Expect the overall state to reflect the header, too.
-  EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state));
-  EXPECT_EQ(2UL, domain_state.dynamic_spki_hashes.size());
+  EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled));
+  HashValueVector hashes;
+  hashes.push_back(good_hash);
+  std::string failure_log;
+  EXPECT_TRUE(
+      state.CheckPublicKeyPins(domain, sni_enabled, hashes, &failure_log));
 
-  hash = std::find_if(domain_state.dynamic_spki_hashes.begin(),
-                      domain_state.dynamic_spki_hashes.end(),
+  TransportSecurityState::DomainState new_dynamic_domain_state;
+  EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state));
+  EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size());
+
+  hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
+                      new_dynamic_domain_state.pkp.spki_hashes.end(),
                       HashValuesEqual(good_hash));
-  EXPECT_NE(domain_state.dynamic_spki_hashes.end(), hash);
+  EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
 
-  hash = std::find_if(
-      domain_state.dynamic_spki_hashes.begin(),
-      domain_state.dynamic_spki_hashes.end(),
-      HashValuesEqual(backup_hash));
-  EXPECT_NE(domain_state.dynamic_spki_hashes.end(), hash);
+  hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
+                      new_dynamic_domain_state.pkp.spki_hashes.end(),
+                      HashValuesEqual(backup_hash));
+  EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
+}
+
+// Tests that when a static HSTS and a static HPKP entry are present, adding a
+// dynamic HSTS header does not clobber the static HPKP entry. Further, adding a
+// dynamic HPKP entry could not affect the HSTS entry for the site.
+TEST_F(HttpSecurityHeadersTest, NoClobberPins) {
+  TransportSecurityState state;
+  TransportSecurityState::DomainState domain_state;
+
+  // accounts.google.com has preloaded pins.
+  std::string domain = "accounts.google.com";
+
+  // Retrieve the DomainState as it is by default, including its known good
+  // pins.
+  const bool sni_enabled = true;
+  EXPECT_TRUE(state.GetStaticDomainState(domain, sni_enabled, &domain_state));
+  HashValueVector saved_hashes = domain_state.pkp.spki_hashes;
+  EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
+  EXPECT_TRUE(domain_state.HasPublicKeyPins());
+  EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
+  EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled));
+
+  // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given
+  // the original |saved_hashes|, indicating that the static PKP data is still
+  // configured for the domain.
+  EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000"));
+  EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
+  std::string failure_log;
+  EXPECT_TRUE(state.CheckPublicKeyPins(
+      domain, sni_enabled, saved_hashes, &failure_log));
+
+  // Add an HPKP header, which should only update the dynamic state.
+  HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
+  std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
+  std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
+  std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
+
+  // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
+  SSLInfo ssl_info;
+  ssl_info.public_key_hashes.push_back(good_hash);
+  ssl_info.public_key_hashes.push_back(saved_hashes[0]);
+  EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
+
+  EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
+  // HSTS should still be configured for this domain.
+  EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
+  EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
+  // The dynamic pins, which do not match |saved_hashes|, should take
+  // precedence over the static pins and cause the check to fail.
+  EXPECT_FALSE(state.CheckPublicKeyPins(
+      domain, sni_enabled, saved_hashes, &failure_log));
 }
 
 };    // namespace net
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc
index ed8f1da..8cd2de0 100644
--- a/net/http/http_stream_factory_impl_job.cc
+++ b/net/http/http_stream_factory_impl_job.cc
@@ -977,6 +977,14 @@
     return result;
   }
 
+  if (using_quic_) {
+    if (result < 0)
+      return result;
+    stream_ = quic_request_.ReleaseStream();
+    next_state_ = STATE_NONE;
+    return OK;
+  }
+
   if (!ssl_started && result < 0 && original_url_.get()) {
     HistogramBrokenAlternateProtocolLocation(
         BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB);
@@ -986,14 +994,6 @@
     return result;
   }
 
-  if (using_quic_) {
-    if (result < 0)
-      return result;
-    stream_ = quic_request_.ReleaseStream();
-    next_state_ = STATE_NONE;
-    return OK;
-  }
-
   if (result < 0 && !ssl_started)
     return ReconsiderProxyAfterError(result);
   establishing_tunnel_ = false;
diff --git a/net/http/http_transaction_unittest.cc b/net/http/http_transaction_unittest.cc
index eed3c4f..9480e61 100644
--- a/net/http/http_transaction_unittest.cc
+++ b/net/http/http_transaction_unittest.cc
@@ -285,6 +285,8 @@
                                  const net::CompletionCallback& callback) {
   int data_len = static_cast<int>(data_.size());
   int num = std::min(buf_len, data_len - data_cursor_);
+  if (test_mode_ & TEST_MODE_SLOW_READ)
+    num = std::min(num, 1);
   if (num) {
     memcpy(buf->data(), data_.data() + data_cursor_, num);
     data_cursor_ += num;
diff --git a/net/http/http_transaction_unittest.h b/net/http/http_transaction_unittest.h
index 5116f65..5f3d665 100644
--- a/net/http/http_transaction_unittest.h
+++ b/net/http/http_transaction_unittest.h
@@ -43,7 +43,8 @@
   TEST_MODE_SYNC_CACHE_WRITE  = 1 << 4,
   TEST_MODE_SYNC_ALL = (TEST_MODE_SYNC_NET_START | TEST_MODE_SYNC_NET_READ |
                         TEST_MODE_SYNC_CACHE_START | TEST_MODE_SYNC_CACHE_READ |
-                        TEST_MODE_SYNC_CACHE_WRITE)
+                        TEST_MODE_SYNC_CACHE_WRITE),
+  TEST_MODE_SLOW_READ = 1 << 5
 };
 
 typedef void (*MockTransactionHandler)(const net::HttpRequestInfo* request,
diff --git a/net/http/transport_security_persister.cc b/net/http/transport_security_persister.cc
index 04de296..7310b59 100644
--- a/net/http/transport_security_persister.cc
+++ b/net/http/transport_security_persister.cc
@@ -146,16 +146,18 @@
 
     base::DictionaryValue* serialized = new base::DictionaryValue;
     serialized->SetBoolean(kStsIncludeSubdomains,
-                           domain_state.sts_include_subdomains);
+                           domain_state.sts.include_subdomains);
     serialized->SetBoolean(kPkpIncludeSubdomains,
-                           domain_state.pkp_include_subdomains);
-    serialized->SetDouble(kStsObserved, domain_state.sts_observed.ToDoubleT());
-    serialized->SetDouble(kPkpObserved, domain_state.pkp_observed.ToDoubleT());
-    serialized->SetDouble(kExpiry, domain_state.upgrade_expiry.ToDoubleT());
+                           domain_state.pkp.include_subdomains);
+    serialized->SetDouble(kStsObserved,
+                          domain_state.sts.last_observed.ToDoubleT());
+    serialized->SetDouble(kPkpObserved,
+                          domain_state.pkp.last_observed.ToDoubleT());
+    serialized->SetDouble(kExpiry, domain_state.sts.expiry.ToDoubleT());
     serialized->SetDouble(kDynamicSPKIHashesExpiry,
-                          domain_state.dynamic_spki_hashes_expiry.ToDoubleT());
+                          domain_state.pkp.expiry.ToDoubleT());
 
-    switch (domain_state.upgrade_mode) {
+    switch (domain_state.sts.upgrade_mode) {
       case TransportSecurityState::DomainState::MODE_FORCE_HTTPS:
         serialized->SetString(kMode, kForceHTTPS);
         break;
@@ -168,9 +170,9 @@
         continue;
     }
 
-    if (now < domain_state.dynamic_spki_hashes_expiry) {
+    if (now < domain_state.pkp.expiry) {
       serialized->Set(kDynamicSPKIHashes,
-                      SPKIHashesToListValue(domain_state.dynamic_spki_hashes));
+                      SPKIHashesToListValue(domain_state.pkp.spki_hashes));
     }
 
     toplevel.Set(HashedDomainToExternalString(hostname), serialized);
@@ -221,14 +223,14 @@
     bool include_subdomains = false;
     bool parsed_include_subdomains = parsed->GetBoolean(kIncludeSubdomains,
                                                         &include_subdomains);
-    domain_state.sts_include_subdomains = include_subdomains;
-    domain_state.pkp_include_subdomains = include_subdomains;
+    domain_state.sts.include_subdomains = include_subdomains;
+    domain_state.pkp.include_subdomains = include_subdomains;
     if (parsed->GetBoolean(kStsIncludeSubdomains, &include_subdomains)) {
-      domain_state.sts_include_subdomains = include_subdomains;
+      domain_state.sts.include_subdomains = include_subdomains;
       parsed_include_subdomains = true;
     }
     if (parsed->GetBoolean(kPkpIncludeSubdomains, &include_subdomains)) {
-      domain_state.pkp_include_subdomains = include_subdomains;
+      domain_state.pkp.include_subdomains = include_subdomains;
       parsed_include_subdomains = true;
     }
 
@@ -245,14 +247,15 @@
                       &dynamic_spki_hashes_expiry);
 
     const base::ListValue* pins_list = NULL;
-    if (parsed->GetList(kDynamicSPKIHashes, &pins_list))
-      SPKIHashesFromListValue(*pins_list, &domain_state.dynamic_spki_hashes);
+    if (parsed->GetList(kDynamicSPKIHashes, &pins_list)) {
+      SPKIHashesFromListValue(*pins_list, &domain_state.pkp.spki_hashes);
+    }
 
     if (mode_string == kForceHTTPS || mode_string == kStrict) {
-      domain_state.upgrade_mode =
+      domain_state.sts.upgrade_mode =
           TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
     } else if (mode_string == kDefault || mode_string == kPinningOnly) {
-      domain_state.upgrade_mode =
+      domain_state.sts.upgrade_mode =
           TransportSecurityState::DomainState::MODE_DEFAULT;
     } else {
       LOG(WARNING) << "Unknown TransportSecurityState mode string "
@@ -261,34 +264,34 @@
       continue;
     }
 
-    domain_state.upgrade_expiry = base::Time::FromDoubleT(expiry);
-    domain_state.dynamic_spki_hashes_expiry =
+    domain_state.sts.expiry = base::Time::FromDoubleT(expiry);
+    domain_state.pkp.expiry =
         base::Time::FromDoubleT(dynamic_spki_hashes_expiry);
 
     double sts_observed;
     double pkp_observed;
     if (parsed->GetDouble(kStsObserved, &sts_observed)) {
-      domain_state.sts_observed = base::Time::FromDoubleT(sts_observed);
+      domain_state.sts.last_observed = base::Time::FromDoubleT(sts_observed);
     } else if (parsed->GetDouble(kCreated, &sts_observed)) {
       // kCreated is a legacy synonym for both kStsObserved and kPkpObserved.
-      domain_state.sts_observed = base::Time::FromDoubleT(sts_observed);
+      domain_state.sts.last_observed = base::Time::FromDoubleT(sts_observed);
     } else {
       // We're migrating an old entry with no observation date. Make sure we
       // write the new date back in a reasonable time frame.
       dirtied = true;
-      domain_state.sts_observed = base::Time::Now();
+      domain_state.sts.last_observed = base::Time::Now();
     }
     if (parsed->GetDouble(kPkpObserved, &pkp_observed)) {
-      domain_state.pkp_observed = base::Time::FromDoubleT(pkp_observed);
+      domain_state.pkp.last_observed = base::Time::FromDoubleT(pkp_observed);
     } else if (parsed->GetDouble(kCreated, &pkp_observed)) {
-      domain_state.pkp_observed = base::Time::FromDoubleT(pkp_observed);
+      domain_state.pkp.last_observed = base::Time::FromDoubleT(pkp_observed);
     } else {
       dirtied = true;
-      domain_state.pkp_observed = base::Time::Now();
+      domain_state.pkp.last_observed = base::Time::Now();
     }
 
-    if (domain_state.upgrade_expiry <= current_time &&
-        domain_state.dynamic_spki_hashes_expiry <= current_time) {
+    if (domain_state.sts.expiry <= current_time &&
+        domain_state.pkp.expiry <= current_time) {
       // Make sure we dirty the state if we drop an entry.
       dirtied = true;
       continue;
diff --git a/net/http/transport_security_persister_unittest.cc b/net/http/transport_security_persister_unittest.cc
index c7a8dc5..a30edae 100644
--- a/net/http/transport_security_persister_unittest.cc
+++ b/net/http/transport_security_persister_unittest.cc
@@ -57,7 +57,8 @@
   const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
   static const char kYahooDomain[] = "yahoo.com";
 
-  EXPECT_FALSE(state_.GetDomainState(kYahooDomain, true, &domain_state));
+  EXPECT_FALSE(state_.GetStaticDomainState(kYahooDomain, true, &domain_state));
+  EXPECT_FALSE(state_.GetDynamicDomainState(kYahooDomain, &domain_state));
 
   bool include_subdomains = true;
   state_.AddHSTS(kYahooDomain, expiry, include_subdomains);
@@ -67,20 +68,20 @@
   EXPECT_TRUE(persister_->SerializeData(&output));
   EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
 
-  EXPECT_TRUE(state_.GetDomainState(kYahooDomain, true, &domain_state));
-  EXPECT_EQ(domain_state.upgrade_mode,
+  EXPECT_TRUE(state_.GetDynamicDomainState(kYahooDomain, &domain_state));
+  EXPECT_EQ(domain_state.sts.upgrade_mode,
             TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
-  EXPECT_TRUE(state_.GetDomainState("foo.yahoo.com", true, &domain_state));
-  EXPECT_EQ(domain_state.upgrade_mode,
+  EXPECT_TRUE(state_.GetDynamicDomainState("foo.yahoo.com", &domain_state));
+  EXPECT_EQ(domain_state.sts.upgrade_mode,
             TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
-  EXPECT_TRUE(state_.GetDomainState("foo.bar.yahoo.com", true, &domain_state));
-  EXPECT_EQ(domain_state.upgrade_mode,
+  EXPECT_TRUE(state_.GetDynamicDomainState("foo.bar.yahoo.com", &domain_state));
+  EXPECT_EQ(domain_state.sts.upgrade_mode,
             TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
-  EXPECT_TRUE(state_.GetDomainState("foo.bar.baz.yahoo.com", true,
-                                   &domain_state));
-  EXPECT_EQ(domain_state.upgrade_mode,
+  EXPECT_TRUE(
+      state_.GetDynamicDomainState("foo.bar.baz.yahoo.com", &domain_state));
+  EXPECT_EQ(domain_state.sts.upgrade_mode,
             TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
-  EXPECT_FALSE(state_.GetDomainState("com", true, &domain_state));
+  EXPECT_FALSE(state_.GetStaticDomainState("com", true, &domain_state));
 }
 
 TEST_F(TransportSecurityPersisterTest, SerializeData3) {
@@ -166,14 +167,14 @@
 TEST_F(TransportSecurityPersisterTest, PublicKeyHashes) {
   TransportSecurityState::DomainState domain_state;
   static const char kTestDomain[] = "example.com";
-  EXPECT_FALSE(state_.GetDomainState(kTestDomain, false, &domain_state));
+  EXPECT_FALSE(state_.GetDynamicDomainState(kTestDomain, &domain_state));
   net::HashValueVector hashes;
   std::string failure_log;
   EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
 
   net::HashValue sha1(net::HASH_VALUE_SHA1);
   memset(sha1.data(), '1', sha1.size());
-  domain_state.dynamic_spki_hashes.push_back(sha1);
+  domain_state.pkp.spki_hashes.push_back(sha1);
 
   EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
 
@@ -187,15 +188,19 @@
   const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
   bool include_subdomains = false;
   state_.AddHSTS(kTestDomain, expiry, include_subdomains);
-  state_.AddHPKP(kTestDomain, expiry, include_subdomains,
-                 domain_state.dynamic_spki_hashes);
-  std::string ser;
-  EXPECT_TRUE(persister_->SerializeData(&ser));
+  state_.AddHPKP(
+      kTestDomain, expiry, include_subdomains, domain_state.pkp.spki_hashes);
+  std::string serialized;
+  EXPECT_TRUE(persister_->SerializeData(&serialized));
   bool dirty;
-  EXPECT_TRUE(persister_->LoadEntries(ser, &dirty));
-  EXPECT_TRUE(state_.GetDomainState(kTestDomain, false, &domain_state));
-  EXPECT_EQ(1u, domain_state.dynamic_spki_hashes.size());
-  EXPECT_EQ(sha1.tag, domain_state.dynamic_spki_hashes[0].tag);
-  EXPECT_EQ(0, memcmp(domain_state.dynamic_spki_hashes[0].data(), sha1.data(),
-                      sha1.size()));
+  EXPECT_TRUE(persister_->LoadEntries(serialized, &dirty));
+
+  TransportSecurityState::DomainState new_domain_state;
+  EXPECT_TRUE(state_.GetDynamicDomainState(kTestDomain, &new_domain_state));
+  EXPECT_EQ(1u, new_domain_state.pkp.spki_hashes.size());
+  EXPECT_EQ(sha1.tag, new_domain_state.pkp.spki_hashes[0].tag);
+  EXPECT_EQ(0,
+            memcmp(new_domain_state.pkp.spki_hashes[0].data(),
+                   sha1.data(),
+                   sha1.size()));
 }
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index 609c233..e967c65 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -95,6 +95,61 @@
 
 TransportSecurityState::Iterator::~Iterator() {}
 
+bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host,
+                                                    bool sni_enabled) {
+  DomainState state;
+  if (GetStaticDomainState(host, sni_enabled, &state))
+    return true;
+  return GetDynamicDomainState(host, &state);
+}
+
+bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host,
+                                                bool sni_enabled) {
+  DomainState dynamic_state;
+  if (GetDynamicDomainState(host, &dynamic_state))
+    return dynamic_state.ShouldUpgradeToSSL();
+
+  DomainState static_state;
+  if (GetStaticDomainState(host, sni_enabled, &static_state) &&
+      static_state.ShouldUpgradeToSSL()) {
+      return true;
+  }
+
+  return false;
+}
+
+bool TransportSecurityState::CheckPublicKeyPins(const std::string& host,
+                                                bool sni_enabled,
+                                                const HashValueVector& hashes,
+                                                std::string* failure_log) {
+  DomainState dynamic_state;
+  if (GetDynamicDomainState(host, &dynamic_state))
+    return dynamic_state.CheckPublicKeyPins(hashes, failure_log);
+
+  DomainState static_state;
+  if (GetStaticDomainState(host, sni_enabled, &static_state) &&
+      static_state.CheckPublicKeyPins(hashes, failure_log)) {
+      return true;
+  }
+
+  return false;
+}
+
+bool TransportSecurityState::HasPublicKeyPins(const std::string& host,
+                                              bool sni_enabled) {
+  DomainState dynamic_state;
+  if (GetDynamicDomainState(host, &dynamic_state))
+    return dynamic_state.HasPublicKeyPins();
+
+  DomainState static_state;
+  if (GetStaticDomainState(host, sni_enabled, &static_state)) {
+    if (static_state.HasPublicKeyPins())
+      return true;
+  }
+
+  return false;
+}
+
 void TransportSecurityState::SetDelegate(
     TransportSecurityState::Delegate* delegate) {
   DCHECK(CalledOnValidThread());
@@ -135,61 +190,6 @@
   return false;
 }
 
-bool TransportSecurityState::GetDomainState(const std::string& host,
-                                            bool sni_enabled,
-                                            DomainState* result) {
-  DCHECK(CalledOnValidThread());
-
-  DomainState state;
-  const std::string canonicalized_host = CanonicalizeHost(host);
-  if (canonicalized_host.empty())
-    return false;
-
-  bool has_preload = GetStaticDomainState(canonicalized_host, sni_enabled,
-                                          &state);
-  std::string canonicalized_preload = CanonicalizeHost(state.domain);
-  GetDynamicDomainState(host, &state);
-
-  base::Time current_time(base::Time::Now());
-
-  for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
-    std::string host_sub_chunk(&canonicalized_host[i],
-                               canonicalized_host.size() - i);
-    // Exact match of a preload always wins.
-    if (has_preload && host_sub_chunk == canonicalized_preload) {
-      *result = state;
-      return true;
-    }
-
-    DomainStateMap::iterator j =
-        enabled_hosts_.find(HashHost(host_sub_chunk));
-    if (j == enabled_hosts_.end())
-      continue;
-
-    if (current_time > j->second.upgrade_expiry &&
-        current_time > j->second.dynamic_spki_hashes_expiry) {
-      enabled_hosts_.erase(j);
-      DirtyNotify();
-      continue;
-    }
-
-    state = j->second;
-    state.domain = DNSDomainToString(host_sub_chunk);
-
-    // Succeed if we matched the domain exactly or if subdomain matches are
-    // allowed.
-    if (i == 0 || j->second.sts_include_subdomains ||
-        j->second.pkp_include_subdomains) {
-      *result = state;
-      return true;
-    }
-
-    return false;
-  }
-
-  return false;
-}
-
 void TransportSecurityState::ClearDynamicData() {
   DCHECK(CalledOnValidThread());
   enabled_hosts_.clear();
@@ -201,18 +201,20 @@
   bool dirtied = false;
   DomainStateMap::iterator i = enabled_hosts_.begin();
   while (i != enabled_hosts_.end()) {
-    if (i->second.sts_observed >= time && i->second.pkp_observed >= time) {
+    if (i->second.sts.last_observed >= time &&
+        i->second.pkp.last_observed >= time) {
       dirtied = true;
       enabled_hosts_.erase(i++);
       continue;
     }
 
-    if (i->second.sts_observed >= time) {
+    if (i->second.sts.last_observed >= time) {
       dirtied = true;
-      i->second.upgrade_mode = DomainState::MODE_DEFAULT;
-    } else if (i->second.pkp_observed >= time) {
+      i->second.sts.upgrade_mode = DomainState::MODE_DEFAULT;
+    } else if (i->second.pkp.last_observed >= time) {
       dirtied = true;
-      i->second.dynamic_spki_hashes.clear();
+      i->second.pkp.spki_hashes.clear();
+      i->second.pkp.expiry = base::Time();
     }
     ++i;
   }
@@ -555,22 +557,27 @@
       if (!entries[j].include_subdomains && i != 0) {
         *ret = false;
       } else {
-        out->sts_include_subdomains = entries[j].include_subdomains;
-        out->pkp_include_subdomains = entries[j].include_subdomains;
+        out->sts.include_subdomains = entries[j].include_subdomains;
+        out->sts.last_observed = base::GetBuildTime();
+        out->pkp.include_subdomains = entries[j].include_subdomains;
+        out->pkp.last_observed = base::GetBuildTime();
         *ret = true;
+        out->sts.upgrade_mode =
+            TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
         if (!entries[j].https_required)
-          out->upgrade_mode = TransportSecurityState::DomainState::MODE_DEFAULT;
+          out->sts.upgrade_mode =
+              TransportSecurityState::DomainState::MODE_DEFAULT;
         if (entries[j].pins.required_hashes) {
           const char* const* sha1_hash = entries[j].pins.required_hashes;
           while (*sha1_hash) {
-            AddHash(*sha1_hash, &out->static_spki_hashes);
+            AddHash(*sha1_hash, &out->pkp.spki_hashes);
             sha1_hash++;
           }
         }
         if (entries[j].pins.excluded_hashes) {
           const char* const* sha1_hash = entries[j].pins.excluded_hashes;
           while (*sha1_hash) {
-            AddHash(*sha1_hash, &out->bad_static_spki_hashes);
+            AddHash(*sha1_hash, &out->pkp.bad_spki_hashes);
             sha1_hash++;
           }
         }
@@ -618,14 +625,14 @@
   base::TimeDelta max_age;
   TransportSecurityState::DomainState domain_state;
   GetDynamicDomainState(host, &domain_state);
-  if (ParseHSTSHeader(value, &max_age, &domain_state.sts_include_subdomains)) {
+  if (ParseHSTSHeader(value, &max_age, &domain_state.sts.include_subdomains)) {
     // Handle max-age == 0
     if (max_age.InSeconds() == 0)
-      domain_state.upgrade_mode = DomainState::MODE_DEFAULT;
+      domain_state.sts.upgrade_mode = DomainState::MODE_DEFAULT;
     else
-      domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
-    domain_state.sts_observed = now;
-    domain_state.upgrade_expiry = now + max_age;
+      domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
+    domain_state.sts.last_observed = now;
+    domain_state.sts.expiry = now + max_age;
     EnableHost(host, domain_state);
     return true;
   }
@@ -641,12 +648,14 @@
   base::TimeDelta max_age;
   TransportSecurityState::DomainState domain_state;
   GetDynamicDomainState(host, &domain_state);
-  if (ParseHPKPHeader(value, ssl_info.public_key_hashes,
-                      &max_age, &domain_state.pkp_include_subdomains,
-                      &domain_state.dynamic_spki_hashes)) {
+  if (ParseHPKPHeader(value,
+                      ssl_info.public_key_hashes,
+                      &max_age,
+                      &domain_state.pkp.include_subdomains,
+                      &domain_state.pkp.spki_hashes)) {
     // TODO(palmer): http://crbug.com/243865 handle max-age == 0.
-    domain_state.pkp_observed = now;
-    domain_state.dynamic_spki_hashes_expiry = now + max_age;
+    domain_state.pkp.last_observed = now;
+    domain_state.pkp.expiry = now + max_age;
     EnableHost(host, domain_state);
     return true;
   }
@@ -667,10 +676,10 @@
   if (i != enabled_hosts_.end())
     domain_state = i->second;
 
-  domain_state.sts_observed = base::Time::Now();
-  domain_state.sts_include_subdomains = include_subdomains;
-  domain_state.upgrade_expiry = expiry;
-  domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
+  domain_state.sts.last_observed = base::Time::Now();
+  domain_state.sts.include_subdomains = include_subdomains;
+  domain_state.sts.expiry = expiry;
+  domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
   EnableHost(host, domain_state);
   return true;
 }
@@ -690,10 +699,10 @@
   if (i != enabled_hosts_.end())
     domain_state = i->second;
 
-  domain_state.pkp_observed = base::Time::Now();
-  domain_state.pkp_include_subdomains = include_subdomains;
-  domain_state.dynamic_spki_hashes_expiry = expiry;
-  domain_state.dynamic_spki_hashes = hashes;
+  domain_state.pkp.last_observed = base::Time::Now();
+  domain_state.pkp.include_subdomains = include_subdomains;
+  domain_state.pkp.expiry = expiry;
+  domain_state.pkp.spki_hashes = hashes;
   EnableHost(host, domain_state);
   return true;
 }
@@ -750,15 +759,16 @@
   return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
 }
 
-bool TransportSecurityState::GetStaticDomainState(
-    const std::string& canonicalized_host,
-    bool sni_enabled,
-    DomainState* out) {
+bool TransportSecurityState::GetStaticDomainState(const std::string& host,
+                                                  bool sni_enabled,
+                                                  DomainState* out) const {
   DCHECK(CalledOnValidThread());
 
-  out->upgrade_mode = DomainState::MODE_FORCE_HTTPS;
-  out->sts_include_subdomains = false;
-  out->pkp_include_subdomains = false;
+  const std::string canonicalized_host = CanonicalizeHost(host);
+
+  out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
+  out->sts.include_subdomains = false;
+  out->pkp.include_subdomains = false;
 
   const bool is_build_timely = IsBuildTimely();
 
@@ -802,8 +812,8 @@
     if (j == enabled_hosts_.end())
       continue;
 
-    if (current_time > j->second.upgrade_expiry &&
-        current_time > j->second.dynamic_spki_hashes_expiry) {
+    if (current_time > j->second.sts.expiry &&
+        current_time > j->second.pkp.expiry) {
       enabled_hosts_.erase(j);
       DirtyNotify();
       continue;
@@ -814,8 +824,8 @@
 
     // Succeed if we matched the domain exactly or if subdomain matches are
     // allowed.
-    if (i == 0 || j->second.sts_include_subdomains ||
-        j->second.pkp_include_subdomains) {
+    if (i == 0 || j->second.sts.include_subdomains ||
+        j->second.pkp.include_subdomains) {
       *result = state;
       return true;
     }
@@ -826,20 +836,16 @@
   return false;
 }
 
-
 void TransportSecurityState::AddOrUpdateEnabledHosts(
     const std::string& hashed_host, const DomainState& state) {
   DCHECK(CalledOnValidThread());
   enabled_hosts_[hashed_host] = state;
 }
 
-TransportSecurityState::DomainState::DomainState()
-    : upgrade_mode(MODE_DEFAULT),
-      sts_include_subdomains(false),
-      pkp_include_subdomains(false) {
-  base::Time now(base::Time::Now());
-  sts_observed = now;
-  pkp_observed = now;
+TransportSecurityState::DomainState::DomainState() {
+  sts.upgrade_mode = MODE_DEFAULT;
+  sts.include_subdomains = false;
+  pkp.include_subdomains = false;
 }
 
 TransportSecurityState::DomainState::~DomainState() {
@@ -851,37 +857,36 @@
   // production), that should never happen, but it's good to be defensive.
   // And, hashes *can* be empty in some test scenarios.
   if (hashes.empty()) {
-    *failure_log = "Rejecting empty public key chain for public-key-pinned "
-                   "domains: " + domain;
+    failure_log->append(
+        "Rejecting empty public key chain for public-key-pinned domains: " +
+        domain);
     return false;
   }
 
-  if (HashesIntersect(bad_static_spki_hashes, hashes)) {
-    *failure_log = "Rejecting public key chain for domain " + domain +
-                   ". Validated chain: " + HashesToBase64String(hashes) +
-                   ", matches one or more bad hashes: " +
-                   HashesToBase64String(bad_static_spki_hashes);
+  if (HashesIntersect(pkp.bad_spki_hashes, hashes)) {
+    failure_log->append("Rejecting public key chain for domain " + domain +
+                        ". Validated chain: " + HashesToBase64String(hashes) +
+                        ", matches one or more bad hashes: " +
+                        HashesToBase64String(pkp.bad_spki_hashes));
     return false;
   }
 
   // If there are no pins, then any valid chain is acceptable.
-  if (dynamic_spki_hashes.empty() && static_spki_hashes.empty())
+  if (pkp.spki_hashes.empty())
     return true;
 
-  if (HashesIntersect(dynamic_spki_hashes, hashes) ||
-      HashesIntersect(static_spki_hashes, hashes)) {
+  if (HashesIntersect(pkp.spki_hashes, hashes)) {
     return true;
   }
 
-  *failure_log = "Rejecting public key chain for domain " + domain +
-                 ". Validated chain: " + HashesToBase64String(hashes) +
-                 ", expected: " + HashesToBase64String(dynamic_spki_hashes) +
-                 " or: " + HashesToBase64String(static_spki_hashes);
+  failure_log->append("Rejecting public key chain for domain " + domain +
+                      ". Validated chain: " + HashesToBase64String(hashes) +
+                      ", expected: " + HashesToBase64String(pkp.spki_hashes));
   return false;
 }
 
 bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const {
-  return upgrade_mode == MODE_FORCE_HTTPS;
+  return sts.upgrade_mode == MODE_FORCE_HTTPS;
 }
 
 bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const {
@@ -889,9 +894,13 @@
 }
 
 bool TransportSecurityState::DomainState::HasPublicKeyPins() const {
-  return static_spki_hashes.size() > 0 ||
-         bad_static_spki_hashes.size() > 0 ||
-         dynamic_spki_hashes.size() > 0;
+  return pkp.spki_hashes.size() > 0 || pkp.bad_spki_hashes.size() > 0;
+}
+
+TransportSecurityState::DomainState::PKPState::PKPState() {
+}
+
+TransportSecurityState::DomainState::PKPState::~PKPState() {
 }
 
 }  // namespace
diff --git a/net/http/transport_security_state.h b/net/http/transport_security_state.h
index 82a3c45..3645937 100644
--- a/net/http/transport_security_state.h
+++ b/net/http/transport_security_state.h
@@ -61,6 +61,44 @@
     DomainState();
     ~DomainState();
 
+    struct STSState {
+      // The absolute time (UTC) when the |upgrade_mode| (and other state) was
+      // observed.
+      base::Time last_observed;
+
+      // The absolute time (UTC) when the |upgrade_mode|, if set to
+      // MODE_FORCE_HTTPS, downgrades to MODE_DEFAULT.
+      base::Time expiry;
+
+      UpgradeMode upgrade_mode;
+
+      // Are subdomains subject to this policy state?
+      bool include_subdomains;
+    };
+
+    struct PKPState {
+      PKPState();
+      ~PKPState();
+
+      // The absolute time (UTC) when the |spki_hashes| (and other state) were
+      // observed.
+      base::Time last_observed;
+
+      // The absolute time (UTC) when the |spki_hashes| expire.
+      base::Time expiry;
+
+      // Optional; hashes of pinned SubjectPublicKeyInfos.
+      HashValueVector spki_hashes;
+
+      // Optional; hashes of static known-bad SubjectPublicKeyInfos which MUST
+      // NOT intersect with the set of SPKIs in the TLS server's certificate
+      // chain.
+      HashValueVector bad_spki_hashes;
+
+      // Are subdomains subject to this policy state?
+      bool include_subdomains;
+    };
+
     // Takes a set of SubjectPublicKeyInfo |hashes| and returns true if:
     //   1) |bad_static_spki_hashes| does not intersect |hashes|; AND
     //   2) Both |static_spki_hashes| and |dynamic_spki_hashes| are empty
@@ -85,66 +123,21 @@
     // items.
     bool HasPublicKeyPins() const;
 
-    // ShouldUpgradeToSSL returns true iff, given the |mode| of this
-    // DomainState, HTTP requests should be internally redirected to HTTPS
-    // (also if the "ws" WebSocket request should be upgraded to "wss")
+    // ShouldUpgradeToSSL returns true iff HTTP requests should be internally
+    // redirected to HTTPS (also if WS should be upgraded to WSS).
     bool ShouldUpgradeToSSL() const;
 
     // ShouldSSLErrorsBeFatal returns true iff HTTPS errors should cause
-    // hard-fail behavior (e.g. if HSTS is set for the domain)
+    // hard-fail behavior (e.g. if HSTS is set for the domain).
     bool ShouldSSLErrorsBeFatal() const;
 
-    UpgradeMode upgrade_mode;
-
-    // The absolute time (UTC) when the |upgrade_mode| was observed.
-    //
-    // TODO(palmer): Perhaps static entries should have an "observed" time.
-    base::Time sts_observed;
-
-    // The absolute time (UTC) when the |dynamic_spki_hashes| (and other
-    // |dynamic_*| state) were observed.
-    //
-    // TODO(palmer): Perhaps static entries should have an "observed" time.
-    base::Time pkp_observed;
-
-    // The absolute time (UTC) when the |upgrade_mode|, if set to
-    // UPGRADE_ALWAYS, downgrades to UPGRADE_NEVER.
-    base::Time upgrade_expiry;
-
-    // Are subdomains subject to this DomainState, for the purposes of
-    // upgrading to HTTPS?
-    bool sts_include_subdomains;
-
-    // Are subdomains subject to this DomainState, for the purposes of
-    // Pin Validation?
-    bool pkp_include_subdomains;
-
-    // Optional; hashes of static pinned SubjectPublicKeyInfos. Unless both
-    // are empty, at least one of |static_spki_hashes| and
-    // |dynamic_spki_hashes| MUST intersect with the set of SPKIs in the TLS
-    // server's certificate chain.
-    //
-    // |dynamic_spki_hashes| take precedence over |static_spki_hashes|.
-    // That is, |IsChainOfPublicKeysPermitted| first checks dynamic pins and
-    // then checks static pins.
-    HashValueVector static_spki_hashes;
-
-    // Optional; hashes of dynamically pinned SubjectPublicKeyInfos.
-    HashValueVector dynamic_spki_hashes;
-
-    // The absolute time (UTC) when the |dynamic_spki_hashes| expire.
-    base::Time dynamic_spki_hashes_expiry;
-
-    // Optional; hashes of static known-bad SubjectPublicKeyInfos which
-    // MUST NOT intersect with the set of SPKIs in the TLS server's
-    // certificate chain.
-    HashValueVector bad_static_spki_hashes;
+    STSState sts;
+    PKPState pkp;
 
     // The following members are not valid when stored in |enabled_hosts_|:
 
     // The domain which matched during a search for this DomainState entry.
-    // Updated by |GetDomainState|, |GetDynamicDomainState|, and
-    // |GetStaticDomainState|.
+    // Updated by |GetDynamicDomainState| and |GetStaticDomainState|.
     std::string domain;
   };
 
@@ -163,6 +156,17 @@
     std::map<std::string, DomainState>::const_iterator end_;
   };
 
+  // These functions search for static and dynamic DomainStates, and invoke the
+  // functions of the same name on them. These functions are the primary public
+  // interface; direct access to DomainStates is best left to tests.
+  bool ShouldSSLErrorsBeFatal(const std::string& host, bool sni_enabled);
+  bool ShouldUpgradeToSSL(const std::string& host, bool sni_enabled);
+  bool CheckPublicKeyPins(const std::string& host,
+                          bool sni_enabled,
+                          const HashValueVector& hashes,
+                          std::string* failure_log);
+  bool HasPublicKeyPins(const std::string& host, bool sni_enabled);
+
   // Assign a |Delegate| for persisting the transport security state. If
   // |NULL|, state will not be persisted. The caller retains
   // ownership of |delegate|.
@@ -202,20 +206,31 @@
   // the Delegate (if any).
   bool DeleteDynamicDataForHost(const std::string& host);
 
-  // Returns true and updates |*result| iff there is a DomainState for
-  // |host|.
+  // Returns true and updates |*result| iff there is a static (built-in)
+  // DomainState for |host|.
   //
-  // If |sni_enabled| is true, searches the static pins defined for
-  // SNI-using hosts as well as the rest of the pins.
+  // If |sni_enabled| is true, searches the static pins defined for SNI-using
+  // hosts as well as the rest of the pins.
   //
-  // If |host| matches both an exact entry and is a subdomain of another
-  // entry, the exact match determines the return value.
+  // If |host| matches both an exact entry and is a subdomain of another entry,
+  // the exact match determines the return value.
   //
   // Note that this method is not const because it opportunistically removes
   // entries that have expired.
-  bool GetDomainState(const std::string& host,
-                      bool sni_enabled,
-                      DomainState* result);
+  bool GetStaticDomainState(const std::string& host,
+                            bool sni_enabled,
+                            DomainState* result) const;
+
+  // Returns true and updates |*result| iff there is a dynamic DomainState
+  // (learned from HSTS or HPKP headers, or set by the user, or other means) for
+  // |host|.
+  //
+  // If |host| matches both an exact entry and is a subdomain of another entry,
+  // the exact match determines the return value.
+  //
+  // Note that this method is not const because it opportunistically removes
+  // entries that have expired.
+  bool GetDynamicDomainState(const std::string& host, DomainState* result);
 
   // Processes an HSTS header value from the host, adding entries to
   // dynamic state if necessary.
@@ -289,39 +304,6 @@
   // the result.
   static std::string CanonicalizeHost(const std::string& hostname);
 
-  // Returns true and updates |*result| iff there is a static DomainState for
-  // |host|.
-  //
-  // |GetStaticDomainState| is identical to |GetDomainState| except that it
-  // searches only the statically-defined transport security state, ignoring
-  // all dynamically-added DomainStates.
-  //
-  // If |sni_enabled| is true, searches the static pins defined for
-  // SNI-using hosts as well as the rest of the pins.
-  //
-  // If |host| matches both an exact entry and is a subdomain of another
-  // entry, the exact match determines the return value.
-  //
-  // Note that this method is not const because it opportunistically removes
-  // entries that have expired.
-  bool GetStaticDomainState(const std::string& host,
-                            bool sni_enabled,
-                            DomainState* result);
-
-  // Returns true and updates |*result| iff there is a dynamic DomainState for
-  // |host|.
-  //
-  // |GetDynamicDomainState| is identical to |GetDomainState| except that it
-  // searches only the dynamically-added transport security state, ignoring
-  // all statically-defined DomainStates.
-  //
-  // If |host| matches both an exact entry and is a subdomain of another
-  // entry, the exact match determines the return value.
-  //
-  // Note that this method is not const because it opportunistically removes
-  // entries that have expired.
-  bool GetDynamicDomainState(const std::string& host, DomainState* result);
-
   // The set of hosts that have enabled TransportSecurity.
   DomainStateMap enabled_hosts_;
 
diff --git a/net/http/transport_security_state_static.h b/net/http/transport_security_state_static.h
index 48d09b0..3054a4d 100644
--- a/net/http/transport_security_state_static.h
+++ b/net/http/transport_security_state_static.h
@@ -952,6 +952,7 @@
   {17, true, "\003app\007manilla\003com", true, kNoPins, DOMAIN_NOT_PINNED },
   {16, true, "\012harvestapp\003com", true, kNoPins, DOMAIN_NOT_PINNED },
   {12, true, "\007anycoin\002me", true, kNoPins, DOMAIN_NOT_PINNED },
+  {14, true, "\010noexpect\003org", true, kNoPins, DOMAIN_NOT_PINNED },
 };
 static const size_t kNumPreloadedSTS = ARRAYSIZE_UNSAFE(kPreloadedSTS);
 
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json
index baae683..5e16d91 100644
--- a/net/http/transport_security_state_static.json
+++ b/net/http/transport_security_state_static.json
@@ -745,6 +745,7 @@
     { "name": "app.manilla.com", "include_subdomains": true, "mode": "force-https" },
     { "name": "harvestapp.com", "include_subdomains": true, "mode": "force-https" },
     { "name": "anycoin.me", "include_subdomains": true, "mode": "force-https" },
+    { "name": "noexpect.org", "include_subdomains": true, "mode": "force-https" },
 
     // Entries that are only valid if the client supports SNI.
     { "name": "gmail.com", "mode": "force-https", "pins": "google", "snionly": true },
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index dfcd50f..476ae94 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -46,10 +46,6 @@
   }
 
  protected:
-  std::string CanonicalizeHost(const std::string& host) {
-    return TransportSecurityState::CanonicalizeHost(host);
-  }
-
   bool GetStaticDomainState(TransportSecurityState* state,
                             const std::string& host,
                             bool sni_enabled,
@@ -70,10 +66,10 @@
   const base::Time current_time(base::Time::Now());
   const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
 
-  EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
+  EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
   bool include_subdomains = false;
   state.AddHSTS("yahoo.com", expiry, include_subdomains);
-  EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
+  EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
 }
 
 TEST_F(TransportSecurityStateTest, MatchesCase1) {
@@ -82,10 +78,10 @@
   const base::Time current_time(base::Time::Now());
   const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
 
-  EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
+  EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
   bool include_subdomains = false;
   state.AddHSTS("YAhoo.coM", expiry, include_subdomains);
-  EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
+  EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
 }
 
 TEST_F(TransportSecurityStateTest, MatchesCase2) {
@@ -94,10 +90,10 @@
   const base::Time current_time(base::Time::Now());
   const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
 
-  EXPECT_FALSE(state.GetDomainState("YAhoo.coM", true, &domain_state));
+  EXPECT_FALSE(state.GetDynamicDomainState("YAhoo.coM", &domain_state));
   bool include_subdomains = false;
   state.AddHSTS("yahoo.com", expiry, include_subdomains);
-  EXPECT_TRUE(state.GetDomainState("YAhoo.coM", true, &domain_state));
+  EXPECT_TRUE(state.GetDynamicDomainState("YAhoo.coM", &domain_state));
 }
 
 TEST_F(TransportSecurityStateTest, SubdomainMatches) {
@@ -106,15 +102,15 @@
   const base::Time current_time(base::Time::Now());
   const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
 
-  EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
+  EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
   bool include_subdomains = true;
   state.AddHSTS("yahoo.com", expiry, include_subdomains);
-  EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
-  EXPECT_TRUE(state.GetDomainState("foo.yahoo.com", true, &domain_state));
-  EXPECT_TRUE(state.GetDomainState("foo.bar.yahoo.com", true, &domain_state));
-  EXPECT_TRUE(state.GetDomainState("foo.bar.baz.yahoo.com", true,
-                                   &domain_state));
-  EXPECT_FALSE(state.GetDomainState("com", true, &domain_state));
+  EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
+  EXPECT_TRUE(state.GetDynamicDomainState("foo.yahoo.com", &domain_state));
+  EXPECT_TRUE(state.GetDynamicDomainState("foo.bar.yahoo.com", &domain_state));
+  EXPECT_TRUE(
+      state.GetDynamicDomainState("foo.bar.baz.yahoo.com", &domain_state));
+  EXPECT_FALSE(state.GetDynamicDomainState("com", &domain_state));
 }
 
 TEST_F(TransportSecurityStateTest, InvalidDomains) {
@@ -123,11 +119,12 @@
   const base::Time current_time(base::Time::Now());
   const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
 
-  EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
+  EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
   bool include_subdomains = true;
   state.AddHSTS("yahoo.com", expiry, include_subdomains);
-  EXPECT_TRUE(state.GetDomainState("www-.foo.yahoo.com", true, &domain_state));
-  EXPECT_TRUE(state.GetDomainState("2\x01.foo.yahoo.com", true, &domain_state));
+  EXPECT_TRUE(state.GetDynamicDomainState("www-.foo.yahoo.com", &domain_state));
+  EXPECT_TRUE(
+      state.GetDynamicDomainState("2\x01.foo.yahoo.com", &domain_state));
 }
 
 TEST_F(TransportSecurityStateTest, DeleteAllDynamicDataSince) {
@@ -137,14 +134,18 @@
   const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
   const base::Time older = current_time - base::TimeDelta::FromSeconds(1000);
 
-  EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
+  EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
   bool include_subdomains = false;
   state.AddHSTS("yahoo.com", expiry, include_subdomains);
 
   state.DeleteAllDynamicDataSince(expiry);
-  EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
+  EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
+  EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS,
+            domain_state.sts.upgrade_mode);
   state.DeleteAllDynamicDataSince(older);
-  EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
+  EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
+  EXPECT_EQ(TransportSecurityState::DomainState::MODE_DEFAULT,
+            domain_state.sts.upgrade_mode);
 }
 
 TEST_F(TransportSecurityStateTest, DeleteDynamicDataForHost) {
@@ -155,28 +156,28 @@
   bool include_subdomains = false;
   state.AddHSTS("yahoo.com", expiry, include_subdomains);
 
-  EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
-  EXPECT_FALSE(state.GetDomainState("example.com", true, &domain_state));
+  EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state));
+  EXPECT_FALSE(state.GetDynamicDomainState("example.com", &domain_state));
   EXPECT_TRUE(state.DeleteDynamicDataForHost("yahoo.com"));
-  EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
+  EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state));
 }
 
 TEST_F(TransportSecurityStateTest, IsPreloaded) {
-  const std::string paypal = CanonicalizeHost("paypal.com");
-  const std::string www_paypal = CanonicalizeHost("www.paypal.com");
-  const std::string foo_paypal = CanonicalizeHost("foo.paypal.com");
-  const std::string a_www_paypal = CanonicalizeHost("a.www.paypal.com");
-  const std::string abc_paypal = CanonicalizeHost("a.b.c.paypal.com");
-  const std::string example = CanonicalizeHost("example.com");
-  const std::string aypal = CanonicalizeHost("aypal.com");
+  const std::string paypal = "paypal.com";
+  const std::string www_paypal = "www.paypal.com";
+  const std::string foo_paypal = "foo.paypal.com";
+  const std::string a_www_paypal = "a.www.paypal.com";
+  const std::string abc_paypal = "a.b.c.paypal.com";
+  const std::string example = "example.com";
+  const std::string aypal = "aypal.com";
 
   TransportSecurityState state;
   TransportSecurityState::DomainState domain_state;
 
   EXPECT_TRUE(GetStaticDomainState(&state, paypal, true, &domain_state));
   EXPECT_TRUE(GetStaticDomainState(&state, www_paypal, true, &domain_state));
-  EXPECT_FALSE(domain_state.sts_include_subdomains);
-  EXPECT_FALSE(domain_state.pkp_include_subdomains);
+  EXPECT_FALSE(domain_state.sts.include_subdomains);
+  EXPECT_FALSE(domain_state.pkp.include_subdomains);
   EXPECT_FALSE(GetStaticDomainState(&state, a_www_paypal, true, &domain_state));
   EXPECT_FALSE(GetStaticDomainState(&state, abc_paypal, true, &domain_state));
   EXPECT_FALSE(GetStaticDomainState(&state, example, true, &domain_state));
@@ -189,48 +190,49 @@
 
   // The domain wasn't being set, leading to a blank string in the
   // chrome://net-internals/#hsts UI. So test that.
-  EXPECT_TRUE(state.GetDomainState("market.android.com", true, &domain_state));
+  EXPECT_TRUE(
+      state.GetStaticDomainState("market.android.com", true, &domain_state));
   EXPECT_EQ(domain_state.domain, "market.android.com");
-  EXPECT_TRUE(state.GetDomainState("sub.market.android.com", true,
-                                   &domain_state));
+  EXPECT_TRUE(state.GetStaticDomainState(
+      "sub.market.android.com", true, &domain_state));
   EXPECT_EQ(domain_state.domain, "market.android.com");
 }
 
-static bool ShouldRedirect(const char* hostname) {
+static bool StaticShouldRedirect(const char* hostname) {
   TransportSecurityState state;
   TransportSecurityState::DomainState domain_state;
-  return state.GetDomainState(hostname, true /* SNI ok */, &domain_state) &&
+  return state.GetStaticDomainState(
+             hostname, true /* SNI ok */, &domain_state) &&
          domain_state.ShouldUpgradeToSSL();
 }
 
-static bool HasState(const char* hostname) {
+static bool HasStaticState(const char* hostname) {
   TransportSecurityState state;
   TransportSecurityState::DomainState domain_state;
-  return state.GetDomainState(hostname, true /* SNI ok */, &domain_state);
+  return state.GetStaticDomainState(hostname, true /* SNI ok */, &domain_state);
 }
 
-static bool HasPublicKeyPins(const char* hostname, bool sni_enabled) {
+static bool HasStaticPublicKeyPins(const char* hostname, bool sni_enabled) {
   TransportSecurityState state;
   TransportSecurityState::DomainState domain_state;
-  if (!state.GetDomainState(hostname, sni_enabled, &domain_state))
+  if (!state.GetStaticDomainState(hostname, sni_enabled, &domain_state))
     return false;
 
   return domain_state.HasPublicKeyPins();
 }
 
-static bool HasPublicKeyPins(const char* hostname) {
-  return HasPublicKeyPins(hostname, true);
+static bool HasStaticPublicKeyPins(const char* hostname) {
+  return HasStaticPublicKeyPins(hostname, true);
 }
 
-static bool OnlyPinning(const char *hostname) {
+static bool OnlyPinningInStaticState(const char* hostname) {
   TransportSecurityState state;
   TransportSecurityState::DomainState domain_state;
-  if (!state.GetDomainState(hostname, true /* SNI ok */, &domain_state))
+  if (!state.GetStaticDomainState(hostname, true /* SNI ok */, &domain_state))
     return false;
 
-  return (domain_state.static_spki_hashes.size() > 0 ||
-          domain_state.bad_static_spki_hashes.size() > 0 ||
-          domain_state.dynamic_spki_hashes.size() > 0) &&
+  return (domain_state.pkp.spki_hashes.size() > 0 ||
+          domain_state.pkp.bad_spki_hashes.size() > 0) &&
          !domain_state.ShouldUpgradeToSSL();
 }
 
@@ -239,240 +241,245 @@
   TransportSecurityState::DomainState domain_state;
 
   // We do more extensive checks for the first domain.
-  EXPECT_TRUE(state.GetDomainState("www.paypal.com", true, &domain_state));
-  EXPECT_EQ(domain_state.upgrade_mode,
+  EXPECT_TRUE(
+      state.GetStaticDomainState("www.paypal.com", true, &domain_state));
+  EXPECT_EQ(domain_state.sts.upgrade_mode,
             TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
-  EXPECT_FALSE(domain_state.sts_include_subdomains);
-  EXPECT_FALSE(domain_state.pkp_include_subdomains);
+  EXPECT_FALSE(domain_state.sts.include_subdomains);
+  EXPECT_FALSE(domain_state.pkp.include_subdomains);
 
-  EXPECT_TRUE(HasState("paypal.com"));
-  EXPECT_FALSE(HasState("www2.paypal.com"));
-  EXPECT_FALSE(HasState("www2.paypal.com"));
+  EXPECT_TRUE(HasStaticState("paypal.com"));
+  EXPECT_FALSE(HasStaticState("www2.paypal.com"));
+  EXPECT_FALSE(HasStaticState("www2.paypal.com"));
 
   // Google hosts:
 
-  EXPECT_TRUE(ShouldRedirect("chrome.google.com"));
-  EXPECT_TRUE(ShouldRedirect("checkout.google.com"));
-  EXPECT_TRUE(ShouldRedirect("wallet.google.com"));
-  EXPECT_TRUE(ShouldRedirect("docs.google.com"));
-  EXPECT_TRUE(ShouldRedirect("sites.google.com"));
-  EXPECT_TRUE(ShouldRedirect("drive.google.com"));
-  EXPECT_TRUE(ShouldRedirect("spreadsheets.google.com"));
-  EXPECT_TRUE(ShouldRedirect("appengine.google.com"));
-  EXPECT_TRUE(ShouldRedirect("market.android.com"));
-  EXPECT_TRUE(ShouldRedirect("encrypted.google.com"));
-  EXPECT_TRUE(ShouldRedirect("accounts.google.com"));
-  EXPECT_TRUE(ShouldRedirect("profiles.google.com"));
-  EXPECT_TRUE(ShouldRedirect("mail.google.com"));
-  EXPECT_TRUE(ShouldRedirect("chatenabled.mail.google.com"));
-  EXPECT_TRUE(ShouldRedirect("talkgadget.google.com"));
-  EXPECT_TRUE(ShouldRedirect("hostedtalkgadget.google.com"));
-  EXPECT_TRUE(ShouldRedirect("talk.google.com"));
-  EXPECT_TRUE(ShouldRedirect("plus.google.com"));
-  EXPECT_TRUE(ShouldRedirect("groups.google.com"));
-  EXPECT_TRUE(ShouldRedirect("apis.google.com"));
-  EXPECT_FALSE(ShouldRedirect("chart.apis.google.com"));
-  EXPECT_TRUE(ShouldRedirect("ssl.google-analytics.com"));
-  EXPECT_TRUE(ShouldRedirect("gmail.com"));
-  EXPECT_TRUE(ShouldRedirect("www.gmail.com"));
-  EXPECT_TRUE(ShouldRedirect("googlemail.com"));
-  EXPECT_TRUE(ShouldRedirect("www.googlemail.com"));
-  EXPECT_TRUE(ShouldRedirect("googleplex.com"));
-  EXPECT_TRUE(ShouldRedirect("www.googleplex.com"));
-  EXPECT_FALSE(HasState("m.gmail.com"));
-  EXPECT_FALSE(HasState("m.googlemail.com"));
+  EXPECT_TRUE(StaticShouldRedirect("chrome.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("checkout.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("wallet.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("docs.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("sites.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("drive.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("spreadsheets.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("appengine.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("market.android.com"));
+  EXPECT_TRUE(StaticShouldRedirect("encrypted.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("accounts.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("profiles.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("mail.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("chatenabled.mail.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("talkgadget.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("hostedtalkgadget.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("talk.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("plus.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("groups.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("apis.google.com"));
+  EXPECT_FALSE(StaticShouldRedirect("chart.apis.google.com"));
+  EXPECT_TRUE(StaticShouldRedirect("ssl.google-analytics.com"));
+  EXPECT_TRUE(StaticShouldRedirect("gmail.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.gmail.com"));
+  EXPECT_TRUE(StaticShouldRedirect("googlemail.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.googlemail.com"));
+  EXPECT_TRUE(StaticShouldRedirect("googleplex.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.googleplex.com"));
+  EXPECT_FALSE(HasStaticState("m.gmail.com"));
+  EXPECT_FALSE(HasStaticState("m.googlemail.com"));
 
-  EXPECT_TRUE(OnlyPinning("www.google.com"));
-  EXPECT_TRUE(OnlyPinning("foo.google.com"));
-  EXPECT_TRUE(OnlyPinning("google.com"));
-  EXPECT_TRUE(OnlyPinning("www.youtube.com"));
-  EXPECT_TRUE(OnlyPinning("youtube.com"));
-  EXPECT_TRUE(OnlyPinning("i.ytimg.com"));
-  EXPECT_TRUE(OnlyPinning("ytimg.com"));
-  EXPECT_TRUE(OnlyPinning("googleusercontent.com"));
-  EXPECT_TRUE(OnlyPinning("www.googleusercontent.com"));
-  EXPECT_TRUE(OnlyPinning("www.google-analytics.com"));
-  EXPECT_TRUE(OnlyPinning("googleapis.com"));
-  EXPECT_TRUE(OnlyPinning("googleadservices.com"));
-  EXPECT_TRUE(OnlyPinning("googlecode.com"));
-  EXPECT_TRUE(OnlyPinning("appspot.com"));
-  EXPECT_TRUE(OnlyPinning("googlesyndication.com"));
-  EXPECT_TRUE(OnlyPinning("doubleclick.net"));
-  EXPECT_TRUE(OnlyPinning("googlegroups.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("www.google.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("foo.google.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("google.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("www.youtube.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("youtube.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("i.ytimg.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("ytimg.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("googleusercontent.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("www.googleusercontent.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("www.google-analytics.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("googleapis.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("googleadservices.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("googlecode.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("appspot.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("googlesyndication.com"));
+  EXPECT_TRUE(OnlyPinningInStaticState("doubleclick.net"));
+  EXPECT_TRUE(OnlyPinningInStaticState("googlegroups.com"));
 
   // Tests for domains that don't work without SNI.
-  EXPECT_FALSE(state.GetDomainState("gmail.com", false, &domain_state));
-  EXPECT_FALSE(state.GetDomainState("www.gmail.com", false, &domain_state));
-  EXPECT_FALSE(state.GetDomainState("m.gmail.com", false, &domain_state));
-  EXPECT_FALSE(state.GetDomainState("googlemail.com", false, &domain_state));
-  EXPECT_FALSE(state.GetDomainState("www.googlemail.com", false,
-                                    &domain_state));
-  EXPECT_FALSE(state.GetDomainState("m.googlemail.com", false, &domain_state));
+  EXPECT_FALSE(state.GetStaticDomainState("gmail.com", false, &domain_state));
+  EXPECT_FALSE(
+      state.GetStaticDomainState("www.gmail.com", false, &domain_state));
+  EXPECT_FALSE(state.GetStaticDomainState("m.gmail.com", false, &domain_state));
+  EXPECT_FALSE(
+      state.GetStaticDomainState("googlemail.com", false, &domain_state));
+  EXPECT_FALSE(
+      state.GetStaticDomainState("www.googlemail.com", false, &domain_state));
+  EXPECT_FALSE(
+      state.GetStaticDomainState("m.googlemail.com", false, &domain_state));
 
   // Other hosts:
 
-  EXPECT_TRUE(ShouldRedirect("aladdinschools.appspot.com"));
+  EXPECT_TRUE(StaticShouldRedirect("aladdinschools.appspot.com"));
 
-  EXPECT_TRUE(ShouldRedirect("ottospora.nl"));
-  EXPECT_TRUE(ShouldRedirect("www.ottospora.nl"));
+  EXPECT_TRUE(StaticShouldRedirect("ottospora.nl"));
+  EXPECT_TRUE(StaticShouldRedirect("www.ottospora.nl"));
 
-  EXPECT_TRUE(ShouldRedirect("www.paycheckrecords.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.paycheckrecords.com"));
 
-  EXPECT_TRUE(ShouldRedirect("lastpass.com"));
-  EXPECT_TRUE(ShouldRedirect("www.lastpass.com"));
-  EXPECT_FALSE(HasState("blog.lastpass.com"));
+  EXPECT_TRUE(StaticShouldRedirect("lastpass.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.lastpass.com"));
+  EXPECT_FALSE(HasStaticState("blog.lastpass.com"));
 
-  EXPECT_TRUE(ShouldRedirect("keyerror.com"));
-  EXPECT_TRUE(ShouldRedirect("www.keyerror.com"));
+  EXPECT_TRUE(StaticShouldRedirect("keyerror.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.keyerror.com"));
 
-  EXPECT_TRUE(ShouldRedirect("entropia.de"));
-  EXPECT_TRUE(ShouldRedirect("www.entropia.de"));
-  EXPECT_FALSE(HasState("foo.entropia.de"));
+  EXPECT_TRUE(StaticShouldRedirect("entropia.de"));
+  EXPECT_TRUE(StaticShouldRedirect("www.entropia.de"));
+  EXPECT_FALSE(HasStaticState("foo.entropia.de"));
 
-  EXPECT_TRUE(ShouldRedirect("www.elanex.biz"));
-  EXPECT_FALSE(HasState("elanex.biz"));
-  EXPECT_FALSE(HasState("foo.elanex.biz"));
+  EXPECT_TRUE(StaticShouldRedirect("www.elanex.biz"));
+  EXPECT_FALSE(HasStaticState("elanex.biz"));
+  EXPECT_FALSE(HasStaticState("foo.elanex.biz"));
 
-  EXPECT_TRUE(ShouldRedirect("sunshinepress.org"));
-  EXPECT_TRUE(ShouldRedirect("www.sunshinepress.org"));
-  EXPECT_TRUE(ShouldRedirect("a.b.sunshinepress.org"));
+  EXPECT_TRUE(StaticShouldRedirect("sunshinepress.org"));
+  EXPECT_TRUE(StaticShouldRedirect("www.sunshinepress.org"));
+  EXPECT_TRUE(StaticShouldRedirect("a.b.sunshinepress.org"));
 
-  EXPECT_TRUE(ShouldRedirect("www.noisebridge.net"));
-  EXPECT_FALSE(HasState("noisebridge.net"));
-  EXPECT_FALSE(HasState("foo.noisebridge.net"));
+  EXPECT_TRUE(StaticShouldRedirect("www.noisebridge.net"));
+  EXPECT_FALSE(HasStaticState("noisebridge.net"));
+  EXPECT_FALSE(HasStaticState("foo.noisebridge.net"));
 
-  EXPECT_TRUE(ShouldRedirect("neg9.org"));
-  EXPECT_FALSE(HasState("www.neg9.org"));
+  EXPECT_TRUE(StaticShouldRedirect("neg9.org"));
+  EXPECT_FALSE(HasStaticState("www.neg9.org"));
 
-  EXPECT_TRUE(ShouldRedirect("riseup.net"));
-  EXPECT_TRUE(ShouldRedirect("foo.riseup.net"));
+  EXPECT_TRUE(StaticShouldRedirect("riseup.net"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.riseup.net"));
 
-  EXPECT_TRUE(ShouldRedirect("factor.cc"));
-  EXPECT_FALSE(HasState("www.factor.cc"));
+  EXPECT_TRUE(StaticShouldRedirect("factor.cc"));
+  EXPECT_FALSE(HasStaticState("www.factor.cc"));
 
-  EXPECT_TRUE(ShouldRedirect("members.mayfirst.org"));
-  EXPECT_TRUE(ShouldRedirect("support.mayfirst.org"));
-  EXPECT_TRUE(ShouldRedirect("id.mayfirst.org"));
-  EXPECT_TRUE(ShouldRedirect("lists.mayfirst.org"));
-  EXPECT_FALSE(HasState("www.mayfirst.org"));
+  EXPECT_TRUE(StaticShouldRedirect("members.mayfirst.org"));
+  EXPECT_TRUE(StaticShouldRedirect("support.mayfirst.org"));
+  EXPECT_TRUE(StaticShouldRedirect("id.mayfirst.org"));
+  EXPECT_TRUE(StaticShouldRedirect("lists.mayfirst.org"));
+  EXPECT_FALSE(HasStaticState("www.mayfirst.org"));
 
-  EXPECT_TRUE(ShouldRedirect("romab.com"));
-  EXPECT_TRUE(ShouldRedirect("www.romab.com"));
-  EXPECT_TRUE(ShouldRedirect("foo.romab.com"));
+  EXPECT_TRUE(StaticShouldRedirect("romab.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.romab.com"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.romab.com"));
 
-  EXPECT_TRUE(ShouldRedirect("logentries.com"));
-  EXPECT_TRUE(ShouldRedirect("www.logentries.com"));
-  EXPECT_FALSE(HasState("foo.logentries.com"));
+  EXPECT_TRUE(StaticShouldRedirect("logentries.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.logentries.com"));
+  EXPECT_FALSE(HasStaticState("foo.logentries.com"));
 
-  EXPECT_TRUE(ShouldRedirect("stripe.com"));
-  EXPECT_TRUE(ShouldRedirect("foo.stripe.com"));
+  EXPECT_TRUE(StaticShouldRedirect("stripe.com"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.stripe.com"));
 
-  EXPECT_TRUE(ShouldRedirect("cloudsecurityalliance.org"));
-  EXPECT_TRUE(ShouldRedirect("foo.cloudsecurityalliance.org"));
+  EXPECT_TRUE(StaticShouldRedirect("cloudsecurityalliance.org"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.cloudsecurityalliance.org"));
 
-  EXPECT_TRUE(ShouldRedirect("login.sapo.pt"));
-  EXPECT_TRUE(ShouldRedirect("foo.login.sapo.pt"));
+  EXPECT_TRUE(StaticShouldRedirect("login.sapo.pt"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.login.sapo.pt"));
 
-  EXPECT_TRUE(ShouldRedirect("mattmccutchen.net"));
-  EXPECT_TRUE(ShouldRedirect("foo.mattmccutchen.net"));
+  EXPECT_TRUE(StaticShouldRedirect("mattmccutchen.net"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.mattmccutchen.net"));
 
-  EXPECT_TRUE(ShouldRedirect("betnet.fr"));
-  EXPECT_TRUE(ShouldRedirect("foo.betnet.fr"));
+  EXPECT_TRUE(StaticShouldRedirect("betnet.fr"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.betnet.fr"));
 
-  EXPECT_TRUE(ShouldRedirect("uprotect.it"));
-  EXPECT_TRUE(ShouldRedirect("foo.uprotect.it"));
+  EXPECT_TRUE(StaticShouldRedirect("uprotect.it"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.uprotect.it"));
 
-  EXPECT_TRUE(ShouldRedirect("squareup.com"));
-  EXPECT_FALSE(HasState("foo.squareup.com"));
+  EXPECT_TRUE(StaticShouldRedirect("squareup.com"));
+  EXPECT_FALSE(HasStaticState("foo.squareup.com"));
 
-  EXPECT_TRUE(ShouldRedirect("cert.se"));
-  EXPECT_TRUE(ShouldRedirect("foo.cert.se"));
+  EXPECT_TRUE(StaticShouldRedirect("cert.se"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.cert.se"));
 
-  EXPECT_TRUE(ShouldRedirect("crypto.is"));
-  EXPECT_TRUE(ShouldRedirect("foo.crypto.is"));
+  EXPECT_TRUE(StaticShouldRedirect("crypto.is"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.crypto.is"));
 
-  EXPECT_TRUE(ShouldRedirect("simon.butcher.name"));
-  EXPECT_TRUE(ShouldRedirect("foo.simon.butcher.name"));
+  EXPECT_TRUE(StaticShouldRedirect("simon.butcher.name"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.simon.butcher.name"));
 
-  EXPECT_TRUE(ShouldRedirect("linx.net"));
-  EXPECT_TRUE(ShouldRedirect("foo.linx.net"));
+  EXPECT_TRUE(StaticShouldRedirect("linx.net"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.linx.net"));
 
-  EXPECT_TRUE(ShouldRedirect("dropcam.com"));
-  EXPECT_TRUE(ShouldRedirect("www.dropcam.com"));
-  EXPECT_FALSE(HasState("foo.dropcam.com"));
+  EXPECT_TRUE(StaticShouldRedirect("dropcam.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.dropcam.com"));
+  EXPECT_FALSE(HasStaticState("foo.dropcam.com"));
 
-  EXPECT_TRUE(state.GetDomainState("torproject.org", false, &domain_state));
-  EXPECT_FALSE(domain_state.static_spki_hashes.empty());
-  EXPECT_TRUE(state.GetDomainState("www.torproject.org", false,
-                                   &domain_state));
-  EXPECT_FALSE(domain_state.static_spki_hashes.empty());
-  EXPECT_TRUE(state.GetDomainState("check.torproject.org", false,
-                                   &domain_state));
-  EXPECT_FALSE(domain_state.static_spki_hashes.empty());
-  EXPECT_TRUE(state.GetDomainState("blog.torproject.org", false,
-                                   &domain_state));
-  EXPECT_FALSE(domain_state.static_spki_hashes.empty());
-  EXPECT_TRUE(ShouldRedirect("ebanking.indovinabank.com.vn"));
-  EXPECT_TRUE(ShouldRedirect("foo.ebanking.indovinabank.com.vn"));
+  EXPECT_TRUE(
+      state.GetStaticDomainState("torproject.org", false, &domain_state));
+  EXPECT_FALSE(domain_state.pkp.spki_hashes.empty());
+  EXPECT_TRUE(
+      state.GetStaticDomainState("www.torproject.org", false, &domain_state));
+  EXPECT_FALSE(domain_state.pkp.spki_hashes.empty());
+  EXPECT_TRUE(
+      state.GetStaticDomainState("check.torproject.org", false, &domain_state));
+  EXPECT_FALSE(domain_state.pkp.spki_hashes.empty());
+  EXPECT_TRUE(
+      state.GetStaticDomainState("blog.torproject.org", false, &domain_state));
+  EXPECT_FALSE(domain_state.pkp.spki_hashes.empty());
+  EXPECT_TRUE(StaticShouldRedirect("ebanking.indovinabank.com.vn"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.ebanking.indovinabank.com.vn"));
 
-  EXPECT_TRUE(ShouldRedirect("epoxate.com"));
-  EXPECT_FALSE(HasState("foo.epoxate.com"));
+  EXPECT_TRUE(StaticShouldRedirect("epoxate.com"));
+  EXPECT_FALSE(HasStaticState("foo.epoxate.com"));
 
-  EXPECT_TRUE(HasPublicKeyPins("torproject.org"));
-  EXPECT_TRUE(HasPublicKeyPins("www.torproject.org"));
-  EXPECT_TRUE(HasPublicKeyPins("check.torproject.org"));
-  EXPECT_TRUE(HasPublicKeyPins("blog.torproject.org"));
-  EXPECT_FALSE(HasState("foo.torproject.org"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("torproject.org"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("www.torproject.org"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("check.torproject.org"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("blog.torproject.org"));
+  EXPECT_FALSE(HasStaticState("foo.torproject.org"));
 
-  EXPECT_TRUE(ShouldRedirect("www.moneybookers.com"));
-  EXPECT_FALSE(HasState("moneybookers.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.moneybookers.com"));
+  EXPECT_FALSE(HasStaticState("moneybookers.com"));
 
-  EXPECT_TRUE(ShouldRedirect("ledgerscope.net"));
-  EXPECT_TRUE(ShouldRedirect("www.ledgerscope.net"));
-  EXPECT_FALSE(HasState("status.ledgerscope.net"));
+  EXPECT_TRUE(StaticShouldRedirect("ledgerscope.net"));
+  EXPECT_TRUE(StaticShouldRedirect("www.ledgerscope.net"));
+  EXPECT_FALSE(HasStaticState("status.ledgerscope.net"));
 
-  EXPECT_TRUE(ShouldRedirect("foo.app.recurly.com"));
-  EXPECT_TRUE(ShouldRedirect("foo.api.recurly.com"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.app.recurly.com"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.api.recurly.com"));
 
-  EXPECT_TRUE(ShouldRedirect("greplin.com"));
-  EXPECT_TRUE(ShouldRedirect("www.greplin.com"));
-  EXPECT_FALSE(HasState("foo.greplin.com"));
+  EXPECT_TRUE(StaticShouldRedirect("greplin.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.greplin.com"));
+  EXPECT_FALSE(HasStaticState("foo.greplin.com"));
 
-  EXPECT_TRUE(ShouldRedirect("luneta.nearbuysystems.com"));
-  EXPECT_TRUE(ShouldRedirect("foo.luneta.nearbuysystems.com"));
+  EXPECT_TRUE(StaticShouldRedirect("luneta.nearbuysystems.com"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.luneta.nearbuysystems.com"));
 
-  EXPECT_TRUE(ShouldRedirect("ubertt.org"));
-  EXPECT_TRUE(ShouldRedirect("foo.ubertt.org"));
+  EXPECT_TRUE(StaticShouldRedirect("ubertt.org"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.ubertt.org"));
 
-  EXPECT_TRUE(ShouldRedirect("pixi.me"));
-  EXPECT_TRUE(ShouldRedirect("www.pixi.me"));
+  EXPECT_TRUE(StaticShouldRedirect("pixi.me"));
+  EXPECT_TRUE(StaticShouldRedirect("www.pixi.me"));
 
-  EXPECT_TRUE(ShouldRedirect("grepular.com"));
-  EXPECT_TRUE(ShouldRedirect("www.grepular.com"));
+  EXPECT_TRUE(StaticShouldRedirect("grepular.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.grepular.com"));
 
-  EXPECT_TRUE(ShouldRedirect("mydigipass.com"));
-  EXPECT_FALSE(ShouldRedirect("foo.mydigipass.com"));
-  EXPECT_TRUE(ShouldRedirect("www.mydigipass.com"));
-  EXPECT_FALSE(ShouldRedirect("foo.www.mydigipass.com"));
-  EXPECT_TRUE(ShouldRedirect("developer.mydigipass.com"));
-  EXPECT_FALSE(ShouldRedirect("foo.developer.mydigipass.com"));
-  EXPECT_TRUE(ShouldRedirect("www.developer.mydigipass.com"));
-  EXPECT_FALSE(ShouldRedirect("foo.www.developer.mydigipass.com"));
-  EXPECT_TRUE(ShouldRedirect("sandbox.mydigipass.com"));
-  EXPECT_FALSE(ShouldRedirect("foo.sandbox.mydigipass.com"));
-  EXPECT_TRUE(ShouldRedirect("www.sandbox.mydigipass.com"));
-  EXPECT_FALSE(ShouldRedirect("foo.www.sandbox.mydigipass.com"));
+  EXPECT_TRUE(StaticShouldRedirect("mydigipass.com"));
+  EXPECT_FALSE(StaticShouldRedirect("foo.mydigipass.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.mydigipass.com"));
+  EXPECT_FALSE(StaticShouldRedirect("foo.www.mydigipass.com"));
+  EXPECT_TRUE(StaticShouldRedirect("developer.mydigipass.com"));
+  EXPECT_FALSE(StaticShouldRedirect("foo.developer.mydigipass.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.developer.mydigipass.com"));
+  EXPECT_FALSE(StaticShouldRedirect("foo.www.developer.mydigipass.com"));
+  EXPECT_TRUE(StaticShouldRedirect("sandbox.mydigipass.com"));
+  EXPECT_FALSE(StaticShouldRedirect("foo.sandbox.mydigipass.com"));
+  EXPECT_TRUE(StaticShouldRedirect("www.sandbox.mydigipass.com"));
+  EXPECT_FALSE(StaticShouldRedirect("foo.www.sandbox.mydigipass.com"));
 
-  EXPECT_TRUE(ShouldRedirect("crypto.cat"));
-  EXPECT_FALSE(ShouldRedirect("foo.crypto.cat"));
+  EXPECT_TRUE(StaticShouldRedirect("crypto.cat"));
+  EXPECT_FALSE(StaticShouldRedirect("foo.crypto.cat"));
 
-  EXPECT_TRUE(ShouldRedirect("bigshinylock.minazo.net"));
-  EXPECT_TRUE(ShouldRedirect("foo.bigshinylock.minazo.net"));
+  EXPECT_TRUE(StaticShouldRedirect("bigshinylock.minazo.net"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.bigshinylock.minazo.net"));
 
-  EXPECT_TRUE(ShouldRedirect("crate.io"));
-  EXPECT_TRUE(ShouldRedirect("foo.crate.io"));
+  EXPECT_TRUE(StaticShouldRedirect("crate.io"));
+  EXPECT_TRUE(StaticShouldRedirect("foo.crate.io"));
 
-  EXPECT_TRUE(HasPublicKeyPins("www.twitter.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("www.twitter.com"));
 }
 
 TEST_F(TransportSecurityStateTest, LongNames) {
@@ -482,60 +489,62 @@
       "WaveletIdDomainAndBlipBlipid";
   TransportSecurityState::DomainState domain_state;
   // Just checks that we don't hit a NOTREACHED.
-  EXPECT_FALSE(state.GetDomainState(kLongName, true, &domain_state));
+  EXPECT_FALSE(state.GetStaticDomainState(kLongName, true, &domain_state));
+  EXPECT_FALSE(state.GetDynamicDomainState(kLongName, &domain_state));
 }
 
 TEST_F(TransportSecurityStateTest, BuiltinCertPins) {
   TransportSecurityState state;
   TransportSecurityState::DomainState domain_state;
 
-  EXPECT_TRUE(state.GetDomainState("chrome.google.com", true, &domain_state));
-  EXPECT_TRUE(HasPublicKeyPins("chrome.google.com"));
+  EXPECT_TRUE(
+      state.GetStaticDomainState("chrome.google.com", true, &domain_state));
+  EXPECT_TRUE(HasStaticPublicKeyPins("chrome.google.com"));
 
   HashValueVector hashes;
   std::string failure_log;
   // Checks that a built-in list does exist.
   EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
-  EXPECT_FALSE(HasPublicKeyPins("www.paypal.com"));
+  EXPECT_FALSE(HasStaticPublicKeyPins("www.paypal.com"));
 
-  EXPECT_TRUE(HasPublicKeyPins("docs.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("1.docs.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("sites.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("drive.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("spreadsheets.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("wallet.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("checkout.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("appengine.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("market.android.com"));
-  EXPECT_TRUE(HasPublicKeyPins("encrypted.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("accounts.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("profiles.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("mail.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("chatenabled.mail.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("talkgadget.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("hostedtalkgadget.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("talk.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("plus.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("groups.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("apis.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("docs.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("1.docs.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("sites.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("drive.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("spreadsheets.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("wallet.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("checkout.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("appengine.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("market.android.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("encrypted.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("accounts.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("profiles.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("mail.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("chatenabled.mail.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("talkgadget.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("hostedtalkgadget.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("talk.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("plus.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("groups.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("apis.google.com"));
 
-  EXPECT_TRUE(HasPublicKeyPins("ssl.gstatic.com"));
-  EXPECT_TRUE(HasPublicKeyPins("gstatic.com"));
-  EXPECT_TRUE(HasPublicKeyPins("www.gstatic.com"));
-  EXPECT_TRUE(HasPublicKeyPins("ssl.google-analytics.com"));
-  EXPECT_TRUE(HasPublicKeyPins("www.googleplex.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("ssl.gstatic.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("gstatic.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("www.gstatic.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("ssl.google-analytics.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("www.googleplex.com"));
 
   // Disabled in order to help track down pinning failures --agl
-  EXPECT_TRUE(HasPublicKeyPins("twitter.com"));
-  EXPECT_FALSE(HasPublicKeyPins("foo.twitter.com"));
-  EXPECT_TRUE(HasPublicKeyPins("www.twitter.com"));
-  EXPECT_TRUE(HasPublicKeyPins("api.twitter.com"));
-  EXPECT_TRUE(HasPublicKeyPins("oauth.twitter.com"));
-  EXPECT_TRUE(HasPublicKeyPins("mobile.twitter.com"));
-  EXPECT_TRUE(HasPublicKeyPins("dev.twitter.com"));
-  EXPECT_TRUE(HasPublicKeyPins("business.twitter.com"));
-  EXPECT_TRUE(HasPublicKeyPins("platform.twitter.com"));
-  EXPECT_TRUE(HasPublicKeyPins("si0.twimg.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("twitter.com"));
+  EXPECT_FALSE(HasStaticPublicKeyPins("foo.twitter.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("www.twitter.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("api.twitter.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("oauth.twitter.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("mobile.twitter.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("dev.twitter.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("business.twitter.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("platform.twitter.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("si0.twimg.com"));
 }
 
 static bool AddHash(const std::string& type_and_base64,
@@ -577,7 +586,8 @@
 
   TransportSecurityState state;
   TransportSecurityState::DomainState domain_state;
-  EXPECT_TRUE(state.GetDomainState("blog.torproject.org", true, &domain_state));
+  EXPECT_TRUE(
+      state.GetStaticDomainState("blog.torproject.org", true, &domain_state));
   EXPECT_TRUE(domain_state.HasPublicKeyPins());
 
   std::string failure_log;
@@ -589,43 +599,43 @@
   TransportSecurityState state;
   TransportSecurityState::DomainState domain_state;
 
-  EXPECT_FALSE(ShouldRedirect("www.google-analytics.com"));
+  EXPECT_FALSE(StaticShouldRedirect("www.google-analytics.com"));
 
-  EXPECT_FALSE(HasPublicKeyPins("www.google-analytics.com", false));
-  EXPECT_TRUE(HasPublicKeyPins("www.google-analytics.com"));
-  EXPECT_TRUE(HasPublicKeyPins("google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("www.google.com"));
-  EXPECT_TRUE(HasPublicKeyPins("mail-attachment.googleusercontent.com"));
-  EXPECT_TRUE(HasPublicKeyPins("www.youtube.com"));
-  EXPECT_TRUE(HasPublicKeyPins("i.ytimg.com"));
-  EXPECT_TRUE(HasPublicKeyPins("googleapis.com"));
-  EXPECT_TRUE(HasPublicKeyPins("ajax.googleapis.com"));
-  EXPECT_TRUE(HasPublicKeyPins("googleadservices.com"));
-  EXPECT_TRUE(HasPublicKeyPins("pagead2.googleadservices.com"));
-  EXPECT_TRUE(HasPublicKeyPins("googlecode.com"));
-  EXPECT_TRUE(HasPublicKeyPins("kibbles.googlecode.com"));
-  EXPECT_TRUE(HasPublicKeyPins("appspot.com"));
-  EXPECT_TRUE(HasPublicKeyPins("googlesyndication.com"));
-  EXPECT_TRUE(HasPublicKeyPins("doubleclick.net"));
-  EXPECT_TRUE(HasPublicKeyPins("ad.doubleclick.net"));
-  EXPECT_FALSE(HasPublicKeyPins("learn.doubleclick.net"));
-  EXPECT_TRUE(HasPublicKeyPins("a.googlegroups.com"));
-  EXPECT_FALSE(HasPublicKeyPins("a.googlegroups.com", false));
+  EXPECT_FALSE(HasStaticPublicKeyPins("www.google-analytics.com", false));
+  EXPECT_TRUE(HasStaticPublicKeyPins("www.google-analytics.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("www.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("mail-attachment.googleusercontent.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("www.youtube.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("i.ytimg.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("googleapis.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("ajax.googleapis.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("googleadservices.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("pagead2.googleadservices.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("googlecode.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("kibbles.googlecode.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("appspot.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("googlesyndication.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("doubleclick.net"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("ad.doubleclick.net"));
+  EXPECT_FALSE(HasStaticPublicKeyPins("learn.doubleclick.net"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("a.googlegroups.com"));
+  EXPECT_FALSE(HasStaticPublicKeyPins("a.googlegroups.com", false));
 }
 
 TEST_F(TransportSecurityStateTest, OverrideBuiltins) {
-  EXPECT_TRUE(HasPublicKeyPins("google.com"));
-  EXPECT_FALSE(ShouldRedirect("google.com"));
-  EXPECT_FALSE(ShouldRedirect("www.google.com"));
+  EXPECT_TRUE(HasStaticPublicKeyPins("google.com"));
+  EXPECT_FALSE(StaticShouldRedirect("google.com"));
+  EXPECT_FALSE(StaticShouldRedirect("www.google.com"));
 
   TransportSecurityState state;
   TransportSecurityState::DomainState domain_state;
   const base::Time current_time(base::Time::Now());
   const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
-  domain_state.upgrade_expiry = expiry;
+  domain_state.sts.expiry = expiry;
   EnableHost(&state, "www.google.com", domain_state);
 
-  EXPECT_TRUE(state.GetDomainState("www.google.com", true, &domain_state));
+  EXPECT_TRUE(state.GetDynamicDomainState("www.google.com", &domain_state));
 }
 
 TEST_F(TransportSecurityStateTest, GooglePinnedProperties) {
diff --git a/net/http_server.target.darwin-arm.mk b/net/http_server.target.darwin-arm.mk
index 007b194..03773e6 100644
--- a/net/http_server.target.darwin-arm.mk
+++ b/net/http_server.target.darwin-arm.mk
@@ -45,7 +45,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +133,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/http_server.target.darwin-x86.mk b/net/http_server.target.darwin-x86.mk
index a315ea6..88ef030 100644
--- a/net/http_server.target.darwin-x86.mk
+++ b/net/http_server.target.darwin-x86.mk
@@ -47,7 +47,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -135,7 +134,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/http_server.target.darwin-x86_64.mk b/net/http_server.target.darwin-x86_64.mk
index 1794fd2..2ba4402 100644
--- a/net/http_server.target.darwin-x86_64.mk
+++ b/net/http_server.target.darwin-x86_64.mk
@@ -47,7 +47,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/http_server.target.linux-arm.mk b/net/http_server.target.linux-arm.mk
index 007b194..03773e6 100644
--- a/net/http_server.target.linux-arm.mk
+++ b/net/http_server.target.linux-arm.mk
@@ -45,7 +45,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +133,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/http_server.target.linux-x86.mk b/net/http_server.target.linux-x86.mk
index a315ea6..88ef030 100644
--- a/net/http_server.target.linux-x86.mk
+++ b/net/http_server.target.linux-x86.mk
@@ -47,7 +47,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -135,7 +134,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/http_server.target.linux-x86_64.mk b/net/http_server.target.linux-x86_64.mk
index 1794fd2..2ba4402 100644
--- a/net/http_server.target.linux-x86_64.mk
+++ b/net/http_server.target.linux-x86_64.mk
@@ -47,7 +47,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net.gyp b/net/net.gyp
index 49519d4..559a7dc 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -128,6 +128,21 @@
             'disk_cache/blockfile/mapped_file_avoid_mmap_posix.cc',
           ],
         }],
+        ['disable_file_support==1', {
+          # TODO(mmenke):  Should probably get rid of the dependency on
+          # net_resources in this case (It's used in net_util, to format
+          # directory listings.  Also used outside of net/).
+          'sources!': [
+            'base/directory_lister.cc',
+            'base/directory_lister.h',
+            'url_request/url_request_file_dir_job.cc',
+            'url_request/url_request_file_dir_job.h',
+            'url_request/url_request_file_job.cc',
+            'url_request/url_request_file_job.h',
+            'url_request/file_protocol_handler.cc',
+            'url_request/file_protocol_handler.h',
+          ],
+        }],
         ['disable_ftp_support==1', {
           'sources/': [
             ['exclude', '^ftp/'],
@@ -208,7 +223,6 @@
           {  # else !use_openssl: remove the unneeded files
             'sources!': [
               'base/crypto_module_openssl.cc',
-              'base/keygen_handler_openssl.cc',
               'cert/ct_log_verifier_openssl.cc',
               'cert/ct_objects_extractor_openssl.cc',
               'cert/jwk_serializer_openssl.cc',
@@ -234,6 +248,7 @@
         ],
         [ 'use_openssl_certs == 0', {
             'sources!': [
+              'base/keygen_handler_openssl.cc',
               'base/openssl_private_key_store.h',
               'base/openssl_private_key_store_android.cc',
               'base/openssl_private_key_store_memory.cc',
@@ -533,8 +548,7 @@
         }],
         [ 'os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
@@ -595,6 +609,12 @@
               ['exclude', '^spdy/spdy_websocket_stream_unittest\\.cc$'],
             ],
         }],
+        ['disable_file_support==1', {
+          'sources!': [
+            'base/directory_lister_unittest.cc',
+            'url_request/url_request_file_job_unittest.cc',
+          ],
+        }],
         [ 'disable_ftp_support==1', {
             'sources/': [
               ['exclude', '^ftp/'],
@@ -887,8 +907,7 @@
         }],
         ['os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
@@ -1093,6 +1112,45 @@
           'msvs_disabled_warnings': [4267, ],
         },
         {
+          'target_name': 'hpack_example_generator',
+          'type': 'executable',
+          'dependencies': [
+            '../base/base.gyp:base',
+            'net',
+          ],
+          'sources': [
+            'spdy/fuzzing/hpack_example_generator.cc',
+          ],
+          # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+          'msvs_disabled_warnings': [4267, ],
+        },
+        {
+          'target_name': 'hpack_fuzz_mutator',
+          'type': 'executable',
+          'dependencies': [
+            '../base/base.gyp:base',
+            'net',
+          ],
+          'sources': [
+            'spdy/fuzzing/hpack_fuzz_mutator.cc',
+          ],
+          # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+          'msvs_disabled_warnings': [4267, ],
+        },
+        {
+          'target_name': 'hpack_fuzz_wrapper',
+          'type': 'executable',
+          'dependencies': [
+            '../base/base.gyp:base',
+            'net',
+          ],
+          'sources': [
+            'spdy/fuzzing/hpack_fuzz_wrapper.cc',
+          ],
+          # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+          'msvs_disabled_warnings': [4267, ],
+        },
+        {
           'target_name': 'net_watcher',
           'type': 'executable',
           'dependencies': [
@@ -1350,39 +1408,6 @@
             'tools/quic/quic_server_bin.cc',
           ],
         },
-        {
-          'target_name': 'hpack_example_generator',
-          'type': 'executable',
-          'dependencies': [
-            '../base/base.gyp:base',
-            'net',
-          ],
-          'sources': [
-            'spdy/fuzzing/hpack_example_generator.cc',
-          ],
-        },
-        {
-          'target_name': 'hpack_fuzz_mutator',
-          'type': 'executable',
-          'dependencies': [
-            '../base/base.gyp:base',
-            'net',
-          ],
-          'sources': [
-            'spdy/fuzzing/hpack_fuzz_mutator.cc',
-          ],
-        },
-        {
-          'target_name': 'hpack_fuzz_wrapper',
-          'type': 'executable',
-          'dependencies': [
-            '../base/base.gyp:base',
-            'net',
-          ],
-          'sources': [
-            'spdy/fuzzing/hpack_fuzz_wrapper.cc',
-          ],
-        }
       ]
     }],
     ['OS=="android"', {
diff --git a/net/net.target.darwin-arm.mk b/net/net.target.darwin-arm.mk
index 61b8f91..d412a08 100644
--- a/net/net.target.darwin-arm.mk
+++ b/net/net.target.darwin-arm.mk
@@ -535,7 +535,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -634,7 +633,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/net.target.darwin-x86.mk b/net/net.target.darwin-x86.mk
index 007a52e..1d828bf 100644
--- a/net/net.target.darwin-x86.mk
+++ b/net/net.target.darwin-x86.mk
@@ -537,7 +537,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -635,7 +634,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net.target.darwin-x86_64.mk b/net/net.target.darwin-x86_64.mk
index 0ae3040..0e93d41 100644
--- a/net/net.target.darwin-x86_64.mk
+++ b/net/net.target.darwin-x86_64.mk
@@ -537,7 +537,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -637,7 +636,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net.target.linux-arm.mk b/net/net.target.linux-arm.mk
index 61b8f91..d412a08 100644
--- a/net/net.target.linux-arm.mk
+++ b/net/net.target.linux-arm.mk
@@ -535,7 +535,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -634,7 +633,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/net.target.linux-x86.mk b/net/net.target.linux-x86.mk
index 007a52e..1d828bf 100644
--- a/net/net.target.linux-x86.mk
+++ b/net/net.target.linux-x86.mk
@@ -537,7 +537,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -635,7 +634,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net.target.linux-x86_64.mk b/net/net.target.linux-x86_64.mk
index 0ae3040..0e93d41 100644
--- a/net/net.target.linux-x86_64.mk
+++ b/net/net.target.linux-x86_64.mk
@@ -537,7 +537,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -637,7 +636,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net_errors_java.target.darwin-arm.mk b/net/net_errors_java.target.darwin-arm.mk
index d3ae6d1..ec36381 100644
--- a/net/net_errors_java.target.darwin-arm.mk
+++ b/net/net_errors_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_errors_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/net_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/NetError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/net_errors_java.target.darwin-arm64.mk b/net/net_errors_java.target.darwin-arm64.mk
index f24b187..60262c1 100644
--- a/net/net_errors_java.target.darwin-arm64.mk
+++ b/net/net_errors_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_errors_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/net_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/NetError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_errors_java.target.darwin-mips.mk b/net/net_errors_java.target.darwin-mips.mk
index 75f1921..7a75fcb 100644
--- a/net/net_errors_java.target.darwin-mips.mk
+++ b/net/net_errors_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_errors_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/net_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/NetError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_errors_java.target.darwin-x86.mk b/net/net_errors_java.target.darwin-x86.mk
index 568cae4..bf36a17 100644
--- a/net/net_errors_java.target.darwin-x86.mk
+++ b/net/net_errors_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_errors_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/net_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/NetError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net_errors_java.target.darwin-x86_64.mk b/net/net_errors_java.target.darwin-x86_64.mk
index 0a9f084..a9e8e07 100644
--- a/net/net_errors_java.target.darwin-x86_64.mk
+++ b/net/net_errors_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_errors_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/net_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/NetError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net_errors_java.target.linux-arm.mk b/net/net_errors_java.target.linux-arm.mk
index d3ae6d1..ec36381 100644
--- a/net/net_errors_java.target.linux-arm.mk
+++ b/net/net_errors_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_errors_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/net_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/NetError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/net_errors_java.target.linux-arm64.mk b/net/net_errors_java.target.linux-arm64.mk
index f24b187..60262c1 100644
--- a/net/net_errors_java.target.linux-arm64.mk
+++ b/net/net_errors_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_errors_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/net_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/NetError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_errors_java.target.linux-mips.mk b/net/net_errors_java.target.linux-mips.mk
index 75f1921..7a75fcb 100644
--- a/net/net_errors_java.target.linux-mips.mk
+++ b/net/net_errors_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_errors_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/net_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/NetError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_errors_java.target.linux-x86.mk b/net/net_errors_java.target.linux-x86.mk
index 568cae4..bf36a17 100644
--- a/net/net_errors_java.target.linux-x86.mk
+++ b/net/net_errors_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_errors_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/net_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/NetError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net_errors_java.target.linux-x86_64.mk b/net/net_errors_java.target.linux-x86_64.mk
index 0a9f084..a9e8e07 100644
--- a/net/net_errors_java.target.linux-x86_64.mk
+++ b/net/net_errors_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_errors_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'base/net_error_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/NetError.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/NetError.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net_jni_headers.target.darwin-arm.mk b/net/net_jni_headers.target.darwin-arm.mk
index 6e08995..71e72cb 100644
--- a/net/net_jni_headers.target.darwin-arm.mk
+++ b/net/net_jni_headers.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/net/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/net/AndroidCertVerifyResult.java', 'android/java/src/org/chromium/net/AndroidKeyStore.java', 'android/java/src/org/chromium/net/AndroidNetworkLibrary.java', 'android/java/src/org/chromium/net/AndroidPrivateKey.java', 'android/java/src/org/chromium/net/GURLUtils.java', 'android/java/src/org/chromium/net/NetworkChangeNotifier.java', 'android/java/src/org/chromium/net/ProxyChangeListener.java', 'android/java/src/org/chromium/net/X509Util.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/net/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,7 +132,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -208,7 +215,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/net_jni_headers.target.darwin-arm64.mk b/net/net_jni_headers.target.darwin-arm64.mk
index f0e9f2c..0f3985c 100644
--- a/net/net_jni_headers.target.darwin-arm64.mk
+++ b/net/net_jni_headers.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/net/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/net/AndroidCertVerifyResult.java', 'android/java/src/org/chromium/net/AndroidKeyStore.java', 'android/java/src/org/chromium/net/AndroidNetworkLibrary.java', 'android/java/src/org/chromium/net/AndroidPrivateKey.java', 'android/java/src/org/chromium/net/GURLUtils.java', 'android/java/src/org/chromium/net/NetworkChangeNotifier.java', 'android/java/src/org/chromium/net/ProxyChangeListener.java', 'android/java/src/org/chromium/net/X509Util.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/net/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_jni_headers.target.darwin-mips.mk b/net/net_jni_headers.target.darwin-mips.mk
index 56f3b11..8639db1 100644
--- a/net/net_jni_headers.target.darwin-mips.mk
+++ b/net/net_jni_headers.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/net/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/net/AndroidCertVerifyResult.java', 'android/java/src/org/chromium/net/AndroidKeyStore.java', 'android/java/src/org/chromium/net/AndroidNetworkLibrary.java', 'android/java/src/org/chromium/net/AndroidPrivateKey.java', 'android/java/src/org/chromium/net/GURLUtils.java', 'android/java/src/org/chromium/net/NetworkChangeNotifier.java', 'android/java/src/org/chromium/net/ProxyChangeListener.java', 'android/java/src/org/chromium/net/X509Util.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/net/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_jni_headers.target.darwin-x86.mk b/net/net_jni_headers.target.darwin-x86.mk
index 297d6db..75bee3c 100644
--- a/net/net_jni_headers.target.darwin-x86.mk
+++ b/net/net_jni_headers.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/net/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/net/AndroidCertVerifyResult.java', 'android/java/src/org/chromium/net/AndroidKeyStore.java', 'android/java/src/org/chromium/net/AndroidNetworkLibrary.java', 'android/java/src/org/chromium/net/AndroidPrivateKey.java', 'android/java/src/org/chromium/net/GURLUtils.java', 'android/java/src/org/chromium/net/NetworkChangeNotifier.java', 'android/java/src/org/chromium/net/ProxyChangeListener.java', 'android/java/src/org/chromium/net/X509Util.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/net/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -126,7 +134,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -210,7 +217,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net_jni_headers.target.darwin-x86_64.mk b/net/net_jni_headers.target.darwin-x86_64.mk
index c6d3d9b..071018c 100644
--- a/net/net_jni_headers.target.darwin-x86_64.mk
+++ b/net/net_jni_headers.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/net/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/net/AndroidCertVerifyResult.java', 'android/java/src/org/chromium/net/AndroidKeyStore.java', 'android/java/src/org/chromium/net/AndroidNetworkLibrary.java', 'android/java/src/org/chromium/net/AndroidPrivateKey.java', 'android/java/src/org/chromium/net/GURLUtils.java', 'android/java/src/org/chromium/net/NetworkChangeNotifier.java', 'android/java/src/org/chromium/net/ProxyChangeListener.java', 'android/java/src/org/chromium/net/X509Util.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/net/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -126,7 +134,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -210,7 +217,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net_jni_headers.target.linux-arm.mk b/net/net_jni_headers.target.linux-arm.mk
index 6e08995..71e72cb 100644
--- a/net/net_jni_headers.target.linux-arm.mk
+++ b/net/net_jni_headers.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/net/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/net/AndroidCertVerifyResult.java', 'android/java/src/org/chromium/net/AndroidKeyStore.java', 'android/java/src/org/chromium/net/AndroidNetworkLibrary.java', 'android/java/src/org/chromium/net/AndroidPrivateKey.java', 'android/java/src/org/chromium/net/GURLUtils.java', 'android/java/src/org/chromium/net/NetworkChangeNotifier.java', 'android/java/src/org/chromium/net/ProxyChangeListener.java', 'android/java/src/org/chromium/net/X509Util.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/net/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -124,7 +132,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -208,7 +215,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/net_jni_headers.target.linux-arm64.mk b/net/net_jni_headers.target.linux-arm64.mk
index f0e9f2c..0f3985c 100644
--- a/net/net_jni_headers.target.linux-arm64.mk
+++ b/net/net_jni_headers.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/net/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/net/AndroidCertVerifyResult.java', 'android/java/src/org/chromium/net/AndroidKeyStore.java', 'android/java/src/org/chromium/net/AndroidNetworkLibrary.java', 'android/java/src/org/chromium/net/AndroidPrivateKey.java', 'android/java/src/org/chromium/net/GURLUtils.java', 'android/java/src/org/chromium/net/NetworkChangeNotifier.java', 'android/java/src/org/chromium/net/ProxyChangeListener.java', 'android/java/src/org/chromium/net/X509Util.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/net/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_jni_headers.target.linux-mips.mk b/net/net_jni_headers.target.linux-mips.mk
index 56f3b11..8639db1 100644
--- a/net/net_jni_headers.target.linux-mips.mk
+++ b/net/net_jni_headers.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/net/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/net/AndroidCertVerifyResult.java', 'android/java/src/org/chromium/net/AndroidKeyStore.java', 'android/java/src/org/chromium/net/AndroidNetworkLibrary.java', 'android/java/src/org/chromium/net/AndroidPrivateKey.java', 'android/java/src/org/chromium/net/GURLUtils.java', 'android/java/src/org/chromium/net/NetworkChangeNotifier.java', 'android/java/src/org/chromium/net/ProxyChangeListener.java', 'android/java/src/org/chromium/net/X509Util.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/net/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_jni_headers.target.linux-x86.mk b/net/net_jni_headers.target.linux-x86.mk
index 297d6db..75bee3c 100644
--- a/net/net_jni_headers.target.linux-x86.mk
+++ b/net/net_jni_headers.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/net/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/net/AndroidCertVerifyResult.java', 'android/java/src/org/chromium/net/AndroidKeyStore.java', 'android/java/src/org/chromium/net/AndroidNetworkLibrary.java', 'android/java/src/org/chromium/net/AndroidPrivateKey.java', 'android/java/src/org/chromium/net/GURLUtils.java', 'android/java/src/org/chromium/net/NetworkChangeNotifier.java', 'android/java/src/org/chromium/net/ProxyChangeListener.java', 'android/java/src/org/chromium/net/X509Util.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/net/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -126,7 +134,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -210,7 +217,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net_jni_headers.target.linux-x86_64.mk b/net/net_jni_headers.target.linux-x86_64.mk
index c6d3d9b..071018c 100644
--- a/net/net_jni_headers.target.linux-x86_64.mk
+++ b/net/net_jni_headers.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_net_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/net/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/net/AndroidCertVerifyResult.java', 'android/java/src/org/chromium/net/AndroidKeyStore.java', 'android/java/src/org/chromium/net/AndroidNetworkLibrary.java', 'android/java/src/org/chromium/net/AndroidPrivateKey.java', 'android/java/src/org/chromium/net/GURLUtils.java', 'android/java/src/org/chromium/net/NetworkChangeNotifier.java', 'android/java/src/org/chromium/net/ProxyChangeListener.java', 'android/java/src/org/chromium/net/X509Util.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/net/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidCertVerifyResult_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidKeyStore_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidNetworkLibrary_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/AndroidPrivateKey_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/GURLUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/NetworkChangeNotifier_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/ProxyChangeListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,6 +81,7 @@
 
 
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/jni/X509Util_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -126,7 +134,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -210,7 +217,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/net_resources.target.darwin-arm.mk b/net/net_resources.target.darwin-arm.mk
index 33ebde2..0106e6f 100644
--- a/net/net_resources.target.darwin-arm.mk
+++ b/net/net_resources.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "net_resources":
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_resources.target.darwin-arm64.mk b/net/net_resources.target.darwin-arm64.mk
index 33ebde2..0106e6f 100644
--- a/net/net_resources.target.darwin-arm64.mk
+++ b/net/net_resources.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "net_resources":
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_resources.target.darwin-mips.mk b/net/net_resources.target.darwin-mips.mk
index 33ebde2..0106e6f 100644
--- a/net/net_resources.target.darwin-mips.mk
+++ b/net/net_resources.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "net_resources":
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_resources.target.darwin-x86.mk b/net/net_resources.target.darwin-x86.mk
index 33ebde2..0106e6f 100644
--- a/net/net_resources.target.darwin-x86.mk
+++ b/net/net_resources.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "net_resources":
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_resources.target.darwin-x86_64.mk b/net/net_resources.target.darwin-x86_64.mk
index 33ebde2..0106e6f 100644
--- a/net/net_resources.target.darwin-x86_64.mk
+++ b/net/net_resources.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "net_resources":
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_resources.target.linux-arm.mk b/net/net_resources.target.linux-arm.mk
index 33ebde2..0106e6f 100644
--- a/net/net_resources.target.linux-arm.mk
+++ b/net/net_resources.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "net_resources":
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_resources.target.linux-arm64.mk b/net/net_resources.target.linux-arm64.mk
index 33ebde2..0106e6f 100644
--- a/net/net_resources.target.linux-arm64.mk
+++ b/net/net_resources.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "net_resources":
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_resources.target.linux-mips.mk b/net/net_resources.target.linux-mips.mk
index 33ebde2..0106e6f 100644
--- a/net/net_resources.target.linux-mips.mk
+++ b/net/net_resources.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "net_resources":
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_resources.target.linux-x86.mk b/net/net_resources.target.linux-x86.mk
index 33ebde2..0106e6f 100644
--- a/net/net_resources.target.linux-x86.mk
+++ b/net/net_resources.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "net_resources":
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/net_resources.target.linux-x86_64.mk b/net/net_resources.target.linux-x86_64.mk
index 33ebde2..0106e6f 100644
--- a/net/net_resources.target.linux-x86_64.mk
+++ b/net/net_resources.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "net_resources":
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/net/grit/net_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/private_key_types_java.target.darwin-arm.mk b/net/private_key_types_java.target.darwin-arm.mk
index fae9f4e..0e2b386 100644
--- a/net/private_key_types_java.target.darwin-arm.mk
+++ b/net/private_key_types_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_private_key_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/private_key_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/PrivateKeyType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/private_key_types_java.target.darwin-arm64.mk b/net/private_key_types_java.target.darwin-arm64.mk
index e792cef..e2af744 100644
--- a/net/private_key_types_java.target.darwin-arm64.mk
+++ b/net/private_key_types_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_private_key_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/private_key_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/PrivateKeyType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/private_key_types_java.target.darwin-mips.mk b/net/private_key_types_java.target.darwin-mips.mk
index 9c28078..6e751a6 100644
--- a/net/private_key_types_java.target.darwin-mips.mk
+++ b/net/private_key_types_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_private_key_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/private_key_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/PrivateKeyType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/private_key_types_java.target.darwin-x86.mk b/net/private_key_types_java.target.darwin-x86.mk
index 76d8ae4..e688ae7 100644
--- a/net/private_key_types_java.target.darwin-x86.mk
+++ b/net/private_key_types_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_private_key_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/private_key_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/PrivateKeyType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/private_key_types_java.target.darwin-x86_64.mk b/net/private_key_types_java.target.darwin-x86_64.mk
index 1cd10c9..bac49d0 100644
--- a/net/private_key_types_java.target.darwin-x86_64.mk
+++ b/net/private_key_types_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_private_key_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/private_key_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/PrivateKeyType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/private_key_types_java.target.linux-arm.mk b/net/private_key_types_java.target.linux-arm.mk
index fae9f4e..0e2b386 100644
--- a/net/private_key_types_java.target.linux-arm.mk
+++ b/net/private_key_types_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_private_key_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/private_key_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/PrivateKeyType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/net/private_key_types_java.target.linux-arm64.mk b/net/private_key_types_java.target.linux-arm64.mk
index e792cef..e2af744 100644
--- a/net/private_key_types_java.target.linux-arm64.mk
+++ b/net/private_key_types_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_private_key_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/private_key_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/PrivateKeyType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/private_key_types_java.target.linux-mips.mk b/net/private_key_types_java.target.linux-mips.mk
index 9c28078..6e751a6 100644
--- a/net/private_key_types_java.target.linux-mips.mk
+++ b/net/private_key_types_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_private_key_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/private_key_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/PrivateKeyType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/net/private_key_types_java.target.linux-x86.mk b/net/private_key_types_java.target.linux-x86.mk
index 76d8ae4..e688ae7 100644
--- a/net/private_key_types_java.target.linux-x86.mk
+++ b/net/private_key_types_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_private_key_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/private_key_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/PrivateKeyType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/private_key_types_java.target.linux-x86_64.mk b/net/private_key_types_java.target.linux-x86_64.mk
index 1cd10c9..bac49d0 100644
--- a/net/private_key_types_java.target.linux-x86_64.mk
+++ b/net/private_key_types_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "net_net_gyp_private_key_types_java_target_generate_java_constants":
 # "{'inputs': ['../build/android/gyp/util/build_utils.py', '../build/android/gyp/gcc_preprocess.py', 'android/private_key_type_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['android/java/PrivateKeyType.template'], 'action': ['python', '../build/android/gyp/gcc_preprocess.py', '--include-path=..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/net/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/net/PrivateKeyType.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/net/proxy/proxy_config_service_linux.cc b/net/proxy/proxy_config_service_linux.cc
index a93567d..0e65b72 100644
--- a/net/proxy/proxy_config_service_linux.cc
+++ b/net/proxy/proxy_config_service_linux.cc
@@ -4,6 +4,15 @@
 
 #include "net/proxy/proxy_config_service_linux.h"
 
+// glib >=2.40 deprecate g_settings_list_schemas in favor of
+// g_settings_schema_source_list_schemas. This function is not available on
+// earlier versions that we still need to support (specifically, 2.32), so
+// disable the warning.
+// TODO(mgiuca): Remove this suppression when we drop support for Ubuntu 13.10
+// (saucy) and earlier. Update the code to use
+// g_settings_schema_source_list_schemas instead.
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
 #include <errno.h>
 #include <fcntl.h>
 #if defined(USE_GCONF)
@@ -39,9 +48,6 @@
 #include "url/url_canon.h"
 
 #if defined(USE_GIO)
-#if __clang__
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-#endif
 #include "library_loaders/libgio.h"
 #endif  // defined(USE_GIO)
 
diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc
index 9011875..0c08027 100644
--- a/net/proxy/proxy_resolver_v8.cc
+++ b/net/proxy/proxy_resolver_v8.cc
@@ -112,7 +112,7 @@
   // throughout this object's lifetime.
   V8ExternalASCIILiteral(const char* ascii, size_t length)
       : ascii_(ascii), length_(length) {
-    DCHECK(IsStringASCII(ascii));
+    DCHECK(base::IsStringASCII(ascii));
   }
 
   virtual const char* data() const OVERRIDE {
@@ -159,7 +159,7 @@
 // Converts an ASCII std::string to a V8 string.
 v8::Local<v8::String> ASCIIStringToV8String(v8::Isolate* isolate,
                                             const std::string& s) {
-  DCHECK(IsStringASCII(s));
+  DCHECK(base::IsStringASCII(s));
   return v8::String::NewFromUtf8(isolate, s.data(), v8::String::kNormalString,
                                  s.size());
 }
@@ -182,7 +182,7 @@
 // Converts an ASCII string literal to a V8 string.
 v8::Local<v8::String> ASCIILiteralToV8String(v8::Isolate* isolate,
                                              const char* ascii) {
-  DCHECK(IsStringASCII(ascii));
+  DCHECK(base::IsStringASCII(ascii));
   size_t length = strlen(ascii);
   if (length <= kMaxStringBytesForCopy)
     return v8::String::NewFromUtf8(isolate, ascii, v8::String::kNormalString,
@@ -218,7 +218,7 @@
   const base::string16 hostname_utf16 = V8StringToUTF16(args[0]->ToString());
 
   // If the hostname is already in ASCII, simply return it as is.
-  if (IsStringASCII(hostname_utf16)) {
+  if (base::IsStringASCII(hostname_utf16)) {
     *hostname = base::UTF16ToASCII(hostname_utf16);
     return true;
   }
@@ -238,7 +238,7 @@
                              punycode_output.length(),
                              hostname);
   DCHECK(success);
-  DCHECK(IsStringASCII(*hostname));
+  DCHECK(base::IsStringASCII(*hostname));
   return success;
 }
 
@@ -399,7 +399,7 @@
 
     base::string16 ret_str = V8StringToUTF16(ret->ToString());
 
-    if (!IsStringASCII(ret_str)) {
+    if (!base::IsStringASCII(ret_str)) {
       // TODO(eroman): Rather than failing when a wide string is returned, we
       //               could extend the parsing to handle IDNA hostnames by
       //               converting them to ASCII punycode.
@@ -661,7 +661,7 @@
     }
 
     std::string ip_address_list = V8StringToUTF8(args[0]->ToString());
-    if (!IsStringASCII(ip_address_list)) {
+    if (!base::IsStringASCII(ip_address_list)) {
       args.GetReturnValue().SetNull();
       return;
     }
@@ -686,12 +686,12 @@
     }
 
     std::string ip_address = V8StringToUTF8(args[0]->ToString());
-    if (!IsStringASCII(ip_address)) {
+    if (!base::IsStringASCII(ip_address)) {
       args.GetReturnValue().Set(false);
       return;
     }
     std::string ip_prefix = V8StringToUTF8(args[1]->ToString());
-    if (!IsStringASCII(ip_prefix)) {
+    if (!base::IsStringASCII(ip_prefix)) {
       args.GetReturnValue().Set(false);
       return;
     }
diff --git a/net/proxy/proxy_script_fetcher_impl_unittest.cc b/net/proxy/proxy_script_fetcher_impl_unittest.cc
index 53f7655..b902850 100644
--- a/net/proxy/proxy_script_fetcher_impl_unittest.cc
+++ b/net/proxy/proxy_script_fetcher_impl_unittest.cc
@@ -22,7 +22,6 @@
 #include "net/http/transport_security_state.h"
 #include "net/ssl/ssl_config_service_defaults.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
-#include "net/url_request/file_protocol_handler.h"
 #include "net/url_request/url_request_context_storage.h"
 #include "net/url_request/url_request_file_job.h"
 #include "net/url_request/url_request_job_factory_impl.h"
@@ -30,6 +29,10 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
+#if !defined(DISABLE_FILE_SUPPORT)
+#include "net/url_request/file_protocol_handler.h"
+#endif
+
 using base::ASCIIToUTF16;
 
 namespace net {
@@ -48,7 +51,8 @@
   base::string16 text;
 };
 
-// A non-mock URL request which can access http:// and file:// urls.
+// A non-mock URL request which can access http:// and file:// urls, in the case
+// the tests were built with file support.
 class RequestContext : public URLRequestContext {
  public:
   RequestContext() : storage_(this) {
@@ -73,8 +77,10 @@
     storage_.set_http_transaction_factory(new HttpCache(
         network_session.get(), HttpCache::DefaultBackend::InMemory(0)));
     URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl();
+#if !defined(DISABLE_FILE_SUPPORT)
     job_factory->SetProtocolHandler(
         "file", new FileProtocolHandler(base::MessageLoopProxy::current()));
+#endif
     storage_.set_job_factory(job_factory);
   }
 
@@ -199,6 +205,7 @@
   RequestContext context_;
 };
 
+#if !defined(DISABLE_FILE_SUPPORT)
 TEST_F(ProxyScriptFetcherImplTest, FileUrl) {
   ProxyScriptFetcherImpl pac_fetcher(&context_);
 
@@ -221,6 +228,7 @@
     EXPECT_EQ(ASCIIToUTF16("-pac.txt-\n"), text);
   }
 }
+#endif  // !defined(DISABLE_FILE_SUPPORT)
 
 // Note that all mime types are allowed for PAC file, to be consistent
 // with other browsers.
diff --git a/net/quic/congestion_control/fix_rate_sender.cc b/net/quic/congestion_control/fix_rate_sender.cc
index a5d750c..8027205 100644
--- a/net/quic/congestion_control/fix_rate_sender.cc
+++ b/net/quic/congestion_control/fix_rate_sender.cc
@@ -27,7 +27,6 @@
       max_segment_size_(kDefaultMaxPacketSize),
       fix_rate_leaky_bucket_(bitrate_),
       paced_sender_(bitrate_, max_segment_size_),
-      data_in_flight_(0),
       latest_rtt_(QuicTime::Delta::Zero()) {
   DVLOG(1) << "FixRateSender";
 }
@@ -51,44 +50,32 @@
   // Silently ignore invalid messages in release mode.
 }
 
-void FixRateSender::OnPacketAcked(
-    QuicPacketSequenceNumber /*acked_sequence_number*/,
-    QuicByteCount bytes_acked) {
-  DCHECK_GE(data_in_flight_, bytes_acked);
-  data_in_flight_ -= bytes_acked;
-}
-
-void FixRateSender::OnPacketLost(QuicPacketSequenceNumber /*sequence_number*/,
-                                 QuicTime /*ack_receive_time*/) {
-  // Ignore losses for fix rate sender.
+void FixRateSender::OnCongestionEvent(bool rtt_updated,
+                                      QuicByteCount bytes_in_flight,
+                                      const CongestionMap& acked_packets,
+                                      const CongestionMap& lost_packets) {
 }
 
 bool FixRateSender::OnPacketSent(
     QuicTime sent_time,
+    QuicByteCount /*bytes_in_flight*/,
     QuicPacketSequenceNumber /*sequence_number*/,
     QuicByteCount bytes,
     HasRetransmittableData /*has_retransmittable_data*/) {
   fix_rate_leaky_bucket_.Add(sent_time, bytes);
   paced_sender_.OnPacketSent(sent_time, bytes);
-  data_in_flight_ += bytes;
 
   return true;
 }
 
 void FixRateSender::OnRetransmissionTimeout(bool packets_retransmitted) { }
 
-void FixRateSender::OnPacketAbandoned(
-    QuicPacketSequenceNumber /*sequence_number*/,
-    QuicByteCount bytes_abandoned) {
-  DCHECK_GE(data_in_flight_, bytes_abandoned);
-  data_in_flight_ -= bytes_abandoned;
-}
-
 QuicTime::Delta FixRateSender::TimeUntilSend(
     QuicTime now,
+    QuicByteCount bytes_in_flight,
     HasRetransmittableData /*has_retransmittable_data*/) {
   if (CongestionWindow() > fix_rate_leaky_bucket_.BytesPending(now)) {
-    if (CongestionWindow() <= data_in_flight_) {
+    if (CongestionWindow() <= bytes_in_flight) {
       // We need an ack before we send more.
       return QuicTime::Delta::Infinite();
     }
@@ -113,8 +100,6 @@
   return bitrate_;
 }
 
-void FixRateSender::OnRttUpdated(QuicPacketSequenceNumber largest_observed) {
-}
 
 QuicTime::Delta FixRateSender::RetransmissionDelay() const {
   // TODO(pwestin): Calculate and return retransmission delay.
diff --git a/net/quic/congestion_control/fix_rate_sender.h b/net/quic/congestion_control/fix_rate_sender.h
index 093733b..6f85090 100644
--- a/net/quic/congestion_control/fix_rate_sender.h
+++ b/net/quic/congestion_control/fix_rate_sender.h
@@ -31,23 +31,22 @@
   virtual void OnIncomingQuicCongestionFeedbackFrame(
       const QuicCongestionFeedbackFrame& feedback,
       QuicTime feedback_receive_time) OVERRIDE;
-  virtual void OnPacketAcked(QuicPacketSequenceNumber acked_sequence_number,
-                             QuicByteCount acked_bytes) OVERRIDE;
-  virtual void OnPacketLost(QuicPacketSequenceNumber sequence_number,
-                            QuicTime ack_receive_time) OVERRIDE;
+  virtual void OnCongestionEvent(bool rtt_updated,
+                                 QuicByteCount bytes_in_flight,
+                                 const CongestionMap& acked_packets,
+                                 const CongestionMap& lost_packets) OVERRIDE;
   virtual bool OnPacketSent(
       QuicTime sent_time,
+      QuicByteCount bytes_in_flight,
       QuicPacketSequenceNumber sequence_number,
       QuicByteCount bytes,
       HasRetransmittableData has_retransmittable_data) OVERRIDE;
   virtual void OnRetransmissionTimeout(bool packets_retransmitted) OVERRIDE;
-  virtual void OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
-                                 QuicByteCount bytes_abandoned) OVERRIDE;
   virtual QuicTime::Delta TimeUntilSend(
       QuicTime now,
+      QuicByteCount bytes_in_flight,
       HasRetransmittableData has_retransmittable_data) OVERRIDE;
   virtual QuicBandwidth BandwidthEstimate() const OVERRIDE;
-  virtual void OnRttUpdated(QuicPacketSequenceNumber largest_observed) OVERRIDE;
   virtual QuicTime::Delta RetransmissionDelay() const OVERRIDE;
   virtual QuicByteCount GetCongestionWindow() const OVERRIDE;
   // End implementation of SendAlgorithmInterface.
@@ -60,7 +59,6 @@
   QuicByteCount max_segment_size_;
   LeakyBucket fix_rate_leaky_bucket_;
   PacedSender paced_sender_;
-  QuicByteCount data_in_flight_;
   QuicTime::Delta latest_rtt_;
 
   DISALLOW_COPY_AND_ASSIGN(FixRateSender);
diff --git a/net/quic/congestion_control/fix_rate_test.cc b/net/quic/congestion_control/fix_rate_test.cc
index 1ab48b8..e696823 100644
--- a/net/quic/congestion_control/fix_rate_test.cc
+++ b/net/quic/congestion_control/fix_rate_test.cc
@@ -17,6 +17,9 @@
 namespace net {
 namespace test {
 
+// bytes_in_flight is unused by FixRateSender's OnPacketSent.
+QuicByteCount kUnused = 0;
+
 class FixRateReceiverPeer : public FixRateReceiver {
  public:
   FixRateReceiverPeer()
@@ -60,26 +63,30 @@
   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback,  clock_.Now());
   EXPECT_EQ(300000, sender_->BandwidthEstimate().ToBytesPerSecond());
   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
+                                     0,
                                      HAS_RETRANSMITTABLE_DATA).IsZero());
 
-  sender_->OnPacketSent(clock_.Now(), 1, kDefaultMaxPacketSize,
+  sender_->OnPacketSent(clock_.Now(), kUnused, 1, kDefaultMaxPacketSize,
                         HAS_RETRANSMITTABLE_DATA);
   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
+                                     kDefaultMaxPacketSize,
                                      HAS_RETRANSMITTABLE_DATA).IsZero());
-  sender_->OnPacketSent(clock_.Now(), 2, kDefaultMaxPacketSize,
+  sender_->OnPacketSent(clock_.Now(), kUnused, 2, kDefaultMaxPacketSize,
                         HAS_RETRANSMITTABLE_DATA);
-  sender_->OnPacketSent(clock_.Now(), 3, 600,
+  sender_->OnPacketSent(clock_.Now(), kUnused, 3, 600,
                         HAS_RETRANSMITTABLE_DATA);
   EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
-      sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA));
+            sender_->TimeUntilSend(clock_.Now(),
+                                   kDefaultMaxPacketSize * 2 + 600,
+                                   HAS_RETRANSMITTABLE_DATA));
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2));
   EXPECT_EQ(QuicTime::Delta::Infinite(),
-            sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA));
+            sender_->TimeUntilSend(clock_.Now(),
+                                   kDefaultMaxPacketSize * 2 + 600,
+                                   HAS_RETRANSMITTABLE_DATA));
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8));
-  sender_->OnPacketAcked(1, kDefaultMaxPacketSize);
-  sender_->OnPacketAcked(2, kDefaultMaxPacketSize);
-  sender_->OnPacketAcked(3, 600);
   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
+                                     0,
                                      HAS_RETRANSMITTABLE_DATA).IsZero());
 }
 
@@ -95,18 +102,20 @@
   QuicPacketSequenceNumber sequence_number = 0;
   for (int i = 0; i < num_packets; i += 2) {
     EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
+                                       0,
                                        HAS_RETRANSMITTABLE_DATA).IsZero());
-    sender_->OnPacketSent(clock_.Now(), sequence_number++, packet_size,
+    sender_->OnPacketSent(clock_.Now(), kUnused, sequence_number++, packet_size,
                           HAS_RETRANSMITTABLE_DATA);
     EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
+                                       kDefaultMaxPacketSize,
                                        HAS_RETRANSMITTABLE_DATA).IsZero());
-    sender_->OnPacketSent(clock_.Now(), sequence_number++, packet_size,
+    sender_->OnPacketSent(clock_.Now(), kUnused, sequence_number++, packet_size,
                           HAS_RETRANSMITTABLE_DATA);
     QuicTime::Delta advance_time =
-        sender_->TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA);
+        sender_->TimeUntilSend(clock_.Now(),
+                               2 * kDefaultMaxPacketSize,
+                               HAS_RETRANSMITTABLE_DATA);
     clock_.AdvanceTime(advance_time);
-    sender_->OnPacketAcked(sequence_number - 1, packet_size);
-    sender_->OnPacketAcked(sequence_number - 2, packet_size);
     acc_advance_time = acc_advance_time.Add(advance_time);
   }
   EXPECT_EQ(num_packets * packet_size * 1000000 / bitrate.ToBytesPerSecond(),
diff --git a/net/quic/congestion_control/pacing_sender.cc b/net/quic/congestion_control/pacing_sender.cc
index fc24afe..c487d2a 100644
--- a/net/quic/congestion_control/pacing_sender.cc
+++ b/net/quic/congestion_control/pacing_sender.cc
@@ -12,7 +12,7 @@
       alarm_granularity_(alarm_granularity),
       next_packet_send_time_(QuicTime::Zero()),
       was_last_send_delayed_(false),
-      updated_rtt_(false) {
+      has_valid_rtt_(false) {
 }
 
 PacingSender::~PacingSender() {}
@@ -28,24 +28,25 @@
       feedback, feedback_receive_time);
 }
 
-void PacingSender::OnPacketAcked(
-    QuicPacketSequenceNumber acked_sequence_number,
-    QuicByteCount acked_bytes) {
-  sender_->OnPacketAcked(acked_sequence_number, acked_bytes);
-}
-
-void PacingSender::OnPacketLost(QuicPacketSequenceNumber sequence_number,
-                                QuicTime ack_receive_time) {
-  sender_->OnPacketLost(sequence_number, ack_receive_time);
+void PacingSender::OnCongestionEvent(bool rtt_updated,
+                                     QuicByteCount bytes_in_flight,
+                                     const CongestionMap& acked_packets,
+                                     const CongestionMap& lost_packets) {
+  if (rtt_updated) {
+    has_valid_rtt_ = true;
+  }
+  sender_->OnCongestionEvent(
+      rtt_updated, bytes_in_flight, acked_packets, lost_packets);
 }
 
 bool PacingSender::OnPacketSent(
     QuicTime sent_time,
+    QuicByteCount bytes_in_flight,
     QuicPacketSequenceNumber sequence_number,
     QuicByteCount bytes,
     HasRetransmittableData has_retransmittable_data) {
   // Only pace data packets once we have an updated RTT.
-  if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA && updated_rtt_) {
+  if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA && has_valid_rtt_) {
     // The next packet should be sent as soon as the current packets has
     // been transferred.  We pace at twice the rate of the underlying
     // sender's bandwidth estimate to help ensure that pacing doesn't become
@@ -55,25 +56,21 @@
         BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes);
     next_packet_send_time_ = next_packet_send_time_.Add(delay);
   }
-  return sender_->OnPacketSent(sent_time, sequence_number, bytes,
-                               has_retransmittable_data);
+  return sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number,
+                               bytes, has_retransmittable_data);
 }
 
 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) {
   sender_->OnRetransmissionTimeout(packets_retransmitted);
 }
 
-void PacingSender::OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
-                                     QuicByteCount abandoned_bytes) {
-  sender_->OnPacketAbandoned(sequence_number, abandoned_bytes);
-}
-
 QuicTime::Delta PacingSender::TimeUntilSend(
       QuicTime now,
+      QuicByteCount bytes_in_flight,
       HasRetransmittableData has_retransmittable_data) {
   QuicTime::Delta time_until_send =
-      sender_->TimeUntilSend(now, has_retransmittable_data);
-  if (!updated_rtt_) {
+      sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data);
+  if (!has_valid_rtt_) {
     // Don't pace if we don't have an updated RTT estimate.
     return time_until_send;
   }
@@ -117,11 +114,6 @@
   return sender_->BandwidthEstimate();
 }
 
-void PacingSender::OnRttUpdated(QuicPacketSequenceNumber largest_observed) {
-  updated_rtt_= true;
-  sender_->OnRttUpdated(largest_observed);
-}
-
 QuicTime::Delta PacingSender::RetransmissionDelay() const {
   return sender_->RetransmissionDelay();
 }
diff --git a/net/quic/congestion_control/pacing_sender.h b/net/quic/congestion_control/pacing_sender.h
index 4ce91c2..b1060ac 100644
--- a/net/quic/congestion_control/pacing_sender.h
+++ b/net/quic/congestion_control/pacing_sender.h
@@ -34,22 +34,21 @@
   virtual void OnIncomingQuicCongestionFeedbackFrame(
       const QuicCongestionFeedbackFrame& feedback,
       QuicTime feedback_receive_time) OVERRIDE;
-  virtual void OnPacketAcked(QuicPacketSequenceNumber acked_sequence_number,
-                             QuicByteCount acked_bytes) OVERRIDE;
-  virtual void OnPacketLost(QuicPacketSequenceNumber sequence_number,
-                            QuicTime ack_receive_time) OVERRIDE;
+  virtual void OnCongestionEvent(bool rtt_updated,
+                                 QuicByteCount bytes_in_flight,
+                                 const CongestionMap& acked_packets,
+                                 const CongestionMap& lost_packets) OVERRIDE;
   virtual bool OnPacketSent(QuicTime sent_time,
+                            QuicByteCount bytes_in_flight,
                             QuicPacketSequenceNumber sequence_number,
                             QuicByteCount bytes,
                             HasRetransmittableData is_retransmittable) OVERRIDE;
   virtual void OnRetransmissionTimeout(bool packets_retransmitted) OVERRIDE;
-  virtual void OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
-                                 QuicByteCount abandoned_bytes) OVERRIDE;
   virtual QuicTime::Delta TimeUntilSend(
       QuicTime now,
+      QuicByteCount bytes_in_flight,
       HasRetransmittableData has_retransmittable_data) OVERRIDE;
   virtual QuicBandwidth BandwidthEstimate() const OVERRIDE;
-  virtual void OnRttUpdated(QuicPacketSequenceNumber largest_observed) OVERRIDE;
   virtual QuicTime::Delta RetransmissionDelay() const OVERRIDE;
   virtual QuicByteCount GetCongestionWindow() const OVERRIDE;
 
@@ -58,7 +57,7 @@
   QuicTime::Delta alarm_granularity_;
   QuicTime next_packet_send_time_;  // When can the next packet be sent.
   bool was_last_send_delayed_;  // True when the last send was delayed.
-  bool updated_rtt_;  // True if we have at least one RTT update.
+  bool has_valid_rtt_;  // True if we have at least one RTT update.
 
   DISALLOW_COPY_AND_ASSIGN(PacingSender);
 };
diff --git a/net/quic/congestion_control/pacing_sender_test.cc b/net/quic/congestion_control/pacing_sender_test.cc
index 19e8e51..38e5d02 100644
--- a/net/quic/congestion_control/pacing_sender_test.cc
+++ b/net/quic/congestion_control/pacing_sender_test.cc
@@ -13,10 +13,13 @@
 
 using testing::Return;
 using testing::StrictMock;
+using testing::_;
 
 namespace net {
 namespace test {
 
+const QuicByteCount kBytesInFlight = 1024;
+
 class PacingSenderTest : public ::testing::Test {
  protected:
   PacingSenderTest()
@@ -36,19 +39,21 @@
     // In order for the packet to be sendable, the underlying sender must
     // permit it to be sent immediately.
     EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(),
+                                             kBytesInFlight,
                                              HAS_RETRANSMITTABLE_DATA))
         .WillOnce(Return(zero_time_));
     // Verify that the packet can be sent immediately.
     EXPECT_EQ(zero_time_,
               pacing_sender_->TimeUntilSend(clock_.Now(),
+                                            kBytesInFlight,
                                             HAS_RETRANSMITTABLE_DATA));
 
     // Actually send the packet.
     EXPECT_CALL(*mock_sender_,
-                OnPacketSent(clock_.Now(), sequence_number_, kMaxPacketSize,
-                             HAS_RETRANSMITTABLE_DATA));
-    pacing_sender_->OnPacketSent(clock_.Now(), sequence_number_++,
-                                 kMaxPacketSize,
+                OnPacketSent(clock_.Now(), kBytesInFlight, sequence_number_,
+                             kMaxPacketSize, HAS_RETRANSMITTABLE_DATA));
+    pacing_sender_->OnPacketSent(clock_.Now(), kBytesInFlight,
+                                 sequence_number_++, kMaxPacketSize,
                                  HAS_RETRANSMITTABLE_DATA);
   }
 
@@ -56,19 +61,21 @@
     // In order for the ack to be sendable, the underlying sender must
     // permit it to be sent immediately.
     EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(),
+                                             0,
                                              NO_RETRANSMITTABLE_DATA))
         .WillOnce(Return(zero_time_));
     // Verify that the ACK can be sent immediately.
     EXPECT_EQ(zero_time_,
               pacing_sender_->TimeUntilSend(clock_.Now(),
+                                            0,
                                             NO_RETRANSMITTABLE_DATA));
 
     // Actually send the packet.
     EXPECT_CALL(*mock_sender_,
-                OnPacketSent(clock_.Now(), sequence_number_, kMaxPacketSize,
-                             NO_RETRANSMITTABLE_DATA));
-    pacing_sender_->OnPacketSent(clock_.Now(), sequence_number_++,
-                                 kMaxPacketSize,
+                OnPacketSent(clock_.Now(), 0, sequence_number_,
+                             kMaxPacketSize, NO_RETRANSMITTABLE_DATA));
+    pacing_sender_->OnPacketSent(clock_.Now(), 0,
+                                 sequence_number_++, kMaxPacketSize,
                                  NO_RETRANSMITTABLE_DATA);
   }
 
@@ -76,12 +83,14 @@
     // In order for the packet to be sendable, the underlying sender must
     // permit it to be sent immediately.
     EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(),
+                                             kBytesInFlight,
                                              HAS_RETRANSMITTABLE_DATA))
         .WillOnce(Return(zero_time_));
     // Verify that the packet is delayed.
     EXPECT_EQ(delay.ToMicroseconds(),
               pacing_sender_->TimeUntilSend(
-                  clock_.Now(), HAS_RETRANSMITTABLE_DATA).ToMicroseconds());
+                  clock_.Now(), kBytesInFlight,
+                  HAS_RETRANSMITTABLE_DATA).ToMicroseconds());
   }
 
   const QuicTime::Delta zero_time_;
@@ -94,19 +103,23 @@
 
 TEST_F(PacingSenderTest, NoSend) {
   EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(),
+                                           kBytesInFlight,
                                            HAS_RETRANSMITTABLE_DATA))
       .WillOnce(Return(infinite_time_));
   EXPECT_EQ(infinite_time_,
             pacing_sender_->TimeUntilSend(clock_.Now(),
+                                          kBytesInFlight,
                                           HAS_RETRANSMITTABLE_DATA));
 }
 
 TEST_F(PacingSenderTest, SendNow) {
   EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(),
+                                           kBytesInFlight,
                                            HAS_RETRANSMITTABLE_DATA))
       .WillOnce(Return(zero_time_));
   EXPECT_EQ(zero_time_,
             pacing_sender_->TimeUntilSend(clock_.Now(),
+                                          kBytesInFlight,
                                           HAS_RETRANSMITTABLE_DATA));
 }
 
@@ -123,8 +136,9 @@
   }
 
   // Now update the RTT and verify that packets are actually paced.
-  EXPECT_CALL(*mock_sender_, OnRttUpdated(1));
-  pacing_sender_->OnRttUpdated(1);
+  EXPECT_CALL(*mock_sender_, OnCongestionEvent(true, kBytesInFlight, _, _));
+  SendAlgorithmInterface::CongestionMap empty_map;
+  pacing_sender_->OnCongestionEvent(true, kBytesInFlight, empty_map, empty_map);
 
   CheckPacketIsSentImmediately();
   CheckPacketIsSentImmediately();
diff --git a/net/quic/congestion_control/send_algorithm_interface.h b/net/quic/congestion_control/send_algorithm_interface.h
index c17417a..8412a04 100644
--- a/net/quic/congestion_control/send_algorithm_interface.h
+++ b/net/quic/congestion_control/send_algorithm_interface.h
@@ -25,6 +25,8 @@
 
 class NET_EXPORT_PRIVATE SendAlgorithmInterface {
  public:
+  typedef std::map<QuicPacketSequenceNumber, TransmissionInfo> CongestionMap;
+
   static SendAlgorithmInterface* Create(const QuicClock* clock,
                                         const RttStats* rtt_stats,
                                         CongestionFeedbackType type,
@@ -39,14 +41,15 @@
       const QuicCongestionFeedbackFrame& feedback,
       QuicTime feedback_receive_time) = 0;
 
-  // Called for each received ACK, with sequence number from remote peer.
-  virtual void OnPacketAcked(QuicPacketSequenceNumber acked_sequence_number,
-                             QuicByteCount acked_bytes) = 0;
-
-  // Indicates a loss event of one packet. |sequence_number| is the
-  // sequence number of the lost packet.
-  virtual void OnPacketLost(QuicPacketSequenceNumber sequence_number,
-                            QuicTime ack_receive_time) = 0;
+  // Indicates an update to the congestion state, caused either by an incoming
+  // ack or loss event timeout.  |rtt_updated| indicates whether a new
+  // latest_rtt sample has been taken, |byte_in_flight| the bytes in flight
+  // prior to the congestion event.  |acked_packets| and |lost_packets| are
+  // any packets considered acked or lost as a result of the congestion event.
+  virtual void OnCongestionEvent(bool rtt_updated,
+                                 QuicByteCount bytes_in_flight,
+                                 const CongestionMap& acked_packets,
+                                 const CongestionMap& lost_packets) = 0;
 
   // Inform that we sent x bytes to the wire, and if that was a retransmission.
   // Returns true if the packet should be tracked by the congestion manager,
@@ -54,6 +57,7 @@
   // that do not count outgoing ACK packets against the congestion window.
   // Note: this function must be called for every packet sent to the wire.
   virtual bool OnPacketSent(QuicTime sent_time,
+                            QuicByteCount bytes_in_flight,
                             QuicPacketSequenceNumber sequence_number,
                             QuicByteCount bytes,
                             HasRetransmittableData is_retransmittable) = 0;
@@ -62,24 +66,16 @@
   // nor OnPacketLost will be called for these packets.
   virtual void OnRetransmissionTimeout(bool packets_retransmitted) = 0;
 
-  // Called when a packet is timed out.
-  virtual void OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
-                                 QuicByteCount abandoned_bytes) = 0;
-
   // Calculate the time until we can send the next packet.
   virtual QuicTime::Delta TimeUntilSend(
       QuicTime now,
+      QuicByteCount bytes_in_flight,
       HasRetransmittableData has_retransmittable_data) = 0;
 
   // What's the current estimated bandwidth in bytes per second.
   // Returns 0 when it does not have an estimate.
   virtual QuicBandwidth BandwidthEstimate() const = 0;
 
-  // Notifies the send algorithm of a new rtt sample and |largest_observed|.
-  // TODO(ianswett): Now that the RTT is managed by RTTStats, it may be
-  // possible to remove this method.
-  virtual void OnRttUpdated(QuicPacketSequenceNumber largest_observed) = 0;
-
   // Get the send algorithm specific retransmission delay, called RTO in TCP,
   // Note 1: the caller is responsible for sanity checking this value.
   // Note 2: this will return zero if we don't have enough data for an estimate.
diff --git a/net/quic/congestion_control/tcp_cubic_sender.cc b/net/quic/congestion_control/tcp_cubic_sender.cc
index 7798a03..aaec6a4 100644
--- a/net/quic/congestion_control/tcp_cubic_sender.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender.cc
@@ -38,7 +38,6 @@
       reno_(reno),
       congestion_window_count_(0),
       receive_window_(kDefaultReceiveWindow),
-      bytes_in_flight_(0),
       prr_out_(0),
       prr_delivered_(0),
       ack_count_since_loss_(0),
@@ -74,23 +73,44 @@
   receive_window_ = feedback.tcp.receive_window;
 }
 
+void TcpCubicSender::OnCongestionEvent(
+    bool rtt_updated,
+    QuicByteCount bytes_in_flight,
+    const CongestionMap& acked_packets,
+    const CongestionMap& lost_packets) {
+  if (rtt_updated && InSlowStart() &&
+      hybrid_slow_start_.ShouldExitSlowStart(rtt_stats_->latest_rtt(),
+                                             rtt_stats_->min_rtt(),
+                                             congestion_window_)) {
+    slowstart_threshold_ = congestion_window_;
+  }
+  for (CongestionMap::const_iterator it = lost_packets.begin();
+       it != lost_packets.end(); ++it) {
+    OnPacketLost(it->first, bytes_in_flight);
+  }
+  for (CongestionMap::const_iterator it = acked_packets.begin();
+       it != acked_packets.end(); ++it) {
+    OnPacketAcked(it->first, it->second.bytes_sent, bytes_in_flight);
+  }
+}
+
 void TcpCubicSender::OnPacketAcked(
-    QuicPacketSequenceNumber acked_sequence_number, QuicByteCount acked_bytes) {
-  DCHECK_GE(bytes_in_flight_, acked_bytes);
-  bytes_in_flight_ -= acked_bytes;
+    QuicPacketSequenceNumber acked_sequence_number,
+    QuicByteCount acked_bytes,
+    QuicByteCount bytes_in_flight) {
   largest_acked_sequence_number_ = max(acked_sequence_number,
                                        largest_acked_sequence_number_);
   if (InRecovery()) {
     PrrOnPacketAcked(acked_bytes);
     return;
   }
-  MaybeIncreaseCwnd(acked_sequence_number);
+  MaybeIncreaseCwnd(acked_sequence_number, bytes_in_flight);
   // TODO(ianswett): Should this even be called when not in slow start?
   hybrid_slow_start_.OnPacketAcked(acked_sequence_number, InSlowStart());
 }
 
 void TcpCubicSender::OnPacketLost(QuicPacketSequenceNumber sequence_number,
-                                  QuicTime /*ack_receive_time*/) {
+                                  QuicByteCount bytes_in_flight) {
   // TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets
   // already sent should be treated as a single loss event, since it's expected.
   if (sequence_number <= largest_sent_at_last_cutback_) {
@@ -106,11 +126,8 @@
   if (InSlowStart()) {
     ++stats_->slowstart_packets_lost;
   }
-  PrrOnPacketLost();
+  PrrOnPacketLost(bytes_in_flight);
 
-  // In a normal TCP we would need to know the lowest missing packet to detect
-  // if we receive 3 missing packets. Here we get a missing packet for which we
-  // enter TCP Fast Retransmit immediately.
   if (reno_) {
     congestion_window_ = congestion_window_ >> 1;
   } else {
@@ -118,7 +135,7 @@
         cubic_.CongestionWindowAfterPacketLoss(congestion_window_);
   }
   slowstart_threshold_ = congestion_window_;
-  // Enforce TCP's minimimum congestion window of 2*MSS.
+  // Enforce TCP's minimum congestion window of 2*MSS.
   if (congestion_window_ < kMinimumCongestionWindow) {
     congestion_window_ = kMinimumCongestionWindow;
   }
@@ -131,6 +148,7 @@
 }
 
 bool TcpCubicSender::OnPacketSent(QuicTime /*sent_time*/,
+                                  QuicByteCount /*bytes_in_flight*/,
                                   QuicPacketSequenceNumber sequence_number,
                                   QuicByteCount bytes,
                                   HasRetransmittableData is_retransmittable) {
@@ -139,7 +157,6 @@
     return false;
   }
 
-  bytes_in_flight_ += bytes;
   prr_out_ += bytes;
   if (largest_sent_sequence_number_ < sequence_number) {
     // TODO(rch): Ensure that packets are really sent in order.
@@ -150,37 +167,23 @@
   return true;
 }
 
-void TcpCubicSender::OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
-                                       QuicByteCount abandoned_bytes) {
-  DCHECK_GE(bytes_in_flight_, abandoned_bytes);
-  bytes_in_flight_ -= abandoned_bytes;
-}
-
 QuicTime::Delta TcpCubicSender::TimeUntilSend(
     QuicTime /* now */,
+    QuicByteCount bytes_in_flight,
     HasRetransmittableData has_retransmittable_data) {
   if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
     // For TCP we can always send an ACK immediately.
-    // We also allow tail loss probes to be sent immediately, in keeping with
-    // tail loss probe (draft-dukkipati-tcpm-tcp-loss-probe-01).
     return QuicTime::Delta::Zero();
   }
   if (InRecovery()) {
-    return PrrTimeUntilSend();
+    return PrrTimeUntilSend(bytes_in_flight);
   }
-  if (AvailableSendWindow() > 0) {
+  if (SendWindow() > bytes_in_flight) {
     return QuicTime::Delta::Zero();
   }
   return QuicTime::Delta::Infinite();
 }
 
-QuicByteCount TcpCubicSender::AvailableSendWindow() {
-  if (bytes_in_flight_ > SendWindow()) {
-    return 0;
-  }
-  return SendWindow() - bytes_in_flight_;
-}
-
 QuicByteCount TcpCubicSender::SendWindow() {
   // What's the current send window in bytes.
   return min(receive_window_, GetCongestionWindow());
@@ -204,15 +207,18 @@
   return congestion_window_ * kMaxSegmentSize;
 }
 
-bool TcpCubicSender::IsCwndLimited() const {
+bool TcpCubicSender::IsCwndLimited(QuicByteCount bytes_in_flight) const {
   const QuicByteCount congestion_window_bytes = congestion_window_ *
       kMaxSegmentSize;
-  if (bytes_in_flight_ >= congestion_window_bytes) {
+  if (bytes_in_flight >= congestion_window_bytes) {
     return true;
   }
-  const QuicByteCount tcp_max_burst = kMaxBurstLength * kMaxSegmentSize;
-  const QuicByteCount left = congestion_window_bytes - bytes_in_flight_;
-  return left <= tcp_max_burst;
+  const QuicByteCount max_burst = kMaxBurstLength * kMaxSegmentSize;
+  const QuicByteCount available_bytes =
+      congestion_window_bytes - bytes_in_flight;
+  const bool slow_start_limited = InSlowStart() &&
+      bytes_in_flight >  congestion_window_bytes / 2;
+  return slow_start_limited || available_bytes <= max_burst;
 }
 
 bool TcpCubicSender::InRecovery() const {
@@ -223,9 +229,10 @@
 // Called when we receive an ack. Normal TCP tracks how many packets one ack
 // represents, but quic has a separate ack for each packet.
 void TcpCubicSender::MaybeIncreaseCwnd(
-    QuicPacketSequenceNumber acked_sequence_number) {
+    QuicPacketSequenceNumber acked_sequence_number,
+    QuicByteCount bytes_in_flight) {
   LOG_IF(DFATAL, InRecovery()) << "Never increase the CWND during recovery.";
-  if (!IsCwndLimited()) {
+  if (!IsCwndLimited(bytes_in_flight)) {
     // We don't update the congestion window unless we are close to using the
     // window we have available.
     return;
@@ -266,7 +273,6 @@
 }
 
 void TcpCubicSender::OnRetransmissionTimeout(bool packets_retransmitted) {
-  bytes_in_flight_ = 0;
   largest_sent_at_last_cutback_ = 0;
   if (packets_retransmitted) {
     cubic_.Reset();
@@ -275,27 +281,11 @@
   }
 }
 
-void TcpCubicSender::OnRttUpdated(
-    QuicPacketSequenceNumber /*largest_observed*/) {
-  if (InSlowStart() &&
-      hybrid_slow_start_.ShouldExitSlowStart(rtt_stats_->latest_rtt(),
-                                             rtt_stats_->min_rtt(),
-                                             congestion_window_)) {
-     slowstart_threshold_ = congestion_window_;
-  }
-}
-
-void TcpCubicSender::PrrOnPacketLost() {
+void TcpCubicSender::PrrOnPacketLost(QuicByteCount bytes_in_flight) {
   prr_out_ = 0;
-  bytes_in_flight_before_loss_ = bytes_in_flight_;
-  // Since all losses are triggered by an incoming ack currently, and acks are
-  // registered before losses by the SentPacketManager, initialize the variables
-  // as though one ack was received directly after the loss.  This is too low
-  // for stretch acks, but we expect missing packets to be immediately acked.
-  // This ensures 1 or 2 packets are immediately able to be sent, depending upon
-  // whether we're in PRR or PRR-SSRB mode.
-  prr_delivered_ = kMaxPacketSize;
-  ack_count_since_loss_ = 1;
+  bytes_in_flight_before_loss_ = bytes_in_flight;
+  prr_delivered_ = 0;
+  ack_count_since_loss_ = 0;
 }
 
 void TcpCubicSender::PrrOnPacketAcked(QuicByteCount acked_bytes) {
@@ -303,14 +293,19 @@
   ++ack_count_since_loss_;
 }
 
-QuicTime::Delta TcpCubicSender::PrrTimeUntilSend() {
+QuicTime::Delta TcpCubicSender::PrrTimeUntilSend(
+    QuicByteCount bytes_in_flight) {
   DCHECK(InRecovery());
-  if (AvailableSendWindow() > 0) {
+  // Return QuicTime::Zero In order to ensure limited transmit always works.
+  if (prr_out_ == 0) {
+    return QuicTime::Delta::Zero();
+  }
+  if (SendWindow() > bytes_in_flight) {
     // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead
     // of sending the entire available window. This prevents burst retransmits
     // when more packets are lost than the CWND reduction.
     //   limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS
-    if (prr_delivered_ + ack_count_since_loss_ * kMaxSegmentSize < prr_out_) {
+    if (prr_delivered_ + ack_count_since_loss_ * kMaxSegmentSize <= prr_out_) {
       return QuicTime::Delta::Infinite();
     }
     return QuicTime::Delta::Zero();
diff --git a/net/quic/congestion_control/tcp_cubic_sender.h b/net/quic/congestion_control/tcp_cubic_sender.h
index f2a8072..3327bda 100644
--- a/net/quic/congestion_control/tcp_cubic_sender.h
+++ b/net/quic/congestion_control/tcp_cubic_sender.h
@@ -47,22 +47,21 @@
   virtual void OnIncomingQuicCongestionFeedbackFrame(
       const QuicCongestionFeedbackFrame& feedback,
       QuicTime feedback_receive_time) OVERRIDE;
-  virtual void OnPacketAcked(QuicPacketSequenceNumber acked_sequence_number,
-                             QuicByteCount acked_bytes) OVERRIDE;
-  virtual void OnPacketLost(QuicPacketSequenceNumber largest_loss,
-                            QuicTime ack_receive_time) OVERRIDE;
+  virtual void OnCongestionEvent(bool rtt_updated,
+                                 QuicByteCount bytes_in_flight,
+                                 const CongestionMap& acked_packets,
+                                 const CongestionMap& lost_packets) OVERRIDE;
   virtual bool OnPacketSent(QuicTime sent_time,
+                            QuicByteCount bytes_in_flight,
                             QuicPacketSequenceNumber sequence_number,
                             QuicByteCount bytes,
                             HasRetransmittableData is_retransmittable) OVERRIDE;
   virtual void OnRetransmissionTimeout(bool packets_retransmitted) OVERRIDE;
-  virtual void OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
-                                 QuicByteCount abandoned_bytes) OVERRIDE;
   virtual QuicTime::Delta TimeUntilSend(
       QuicTime now,
+      QuicByteCount bytes_in_flight,
       HasRetransmittableData has_retransmittable_data) OVERRIDE;
   virtual QuicBandwidth BandwidthEstimate() const OVERRIDE;
-  virtual void OnRttUpdated(QuicPacketSequenceNumber largest_observed) OVERRIDE;
   virtual QuicTime::Delta RetransmissionDelay() const OVERRIDE;
   virtual QuicByteCount GetCongestionWindow() const OVERRIDE;
   // End implementation of SendAlgorithmInterface.
@@ -70,15 +69,22 @@
  private:
   friend class test::TcpCubicSenderPeer;
 
-  QuicByteCount AvailableSendWindow();
+  // TODO(ianswett): Remove these and migrate to OnCongestionEvent.
+  void OnPacketAcked(QuicPacketSequenceNumber acked_sequence_number,
+                     QuicByteCount acked_bytes,
+                     QuicByteCount bytes_in_flight);
+  void OnPacketLost(QuicPacketSequenceNumber largest_loss,
+                    QuicByteCount bytes_in_flight);
+
   QuicByteCount SendWindow();
-  void MaybeIncreaseCwnd(QuicPacketSequenceNumber acked_sequence_number);
-  bool IsCwndLimited() const;
+  void MaybeIncreaseCwnd(QuicPacketSequenceNumber acked_sequence_number,
+                         QuicByteCount bytes_in_flight);
+  bool IsCwndLimited(QuicByteCount bytes_in_flight) const;
   bool InRecovery() const;
   // Methods for isolating PRR from the rest of TCP Cubic.
-  void PrrOnPacketLost();
+  void PrrOnPacketLost(QuicByteCount bytes_in_flight);
   void PrrOnPacketAcked(QuicByteCount acked_bytes);
-  QuicTime::Delta PrrTimeUntilSend();
+  QuicTime::Delta PrrTimeUntilSend(QuicByteCount bytes_in_flight);
 
 
   HybridSlowStart hybrid_slow_start_;
@@ -95,9 +101,6 @@
   // Receiver side advertised window.
   QuicByteCount receive_window_;
 
-  // Bytes in flight, aka bytes on the wire.
-  QuicByteCount bytes_in_flight_;
-
   // Bytes sent and acked since the last loss event.  Used for PRR.
   QuicByteCount prr_out_;
   QuicByteCount prr_delivered_;
diff --git a/net/quic/congestion_control/tcp_cubic_sender_test.cc b/net/quic/congestion_control/tcp_cubic_sender_test.cc
index e6e9e8b..c5d991a 100644
--- a/net/quic/congestion_control/tcp_cubic_sender_test.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender_test.cc
@@ -44,7 +44,6 @@
   RttStats rtt_stats_;
   QuicConnectionStats stats_;
 
-  using TcpCubicSender::AvailableSendWindow;
   using TcpCubicSender::SendWindow;
 };
 
@@ -56,45 +55,64 @@
                                        kDefaultMaxCongestionWindowTCP)),
         receiver_(new TcpReceiver()),
         sequence_number_(1),
-        acked_sequence_number_(0) {
+        acked_sequence_number_(0),
+        bytes_in_flight_(0) {
+    standard_packet_.bytes_sent = kDefaultTCPMSS;
   }
 
   int SendAvailableSendWindow() {
     // Send as long as TimeUntilSend returns Zero.
     int packets_sent = 0;
     bool can_send = sender_->TimeUntilSend(
-        clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero();
+        clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
     while (can_send) {
-      sender_->OnPacketSent(clock_.Now(), sequence_number_++, kDefaultTCPMSS,
-                            HAS_RETRANSMITTABLE_DATA);
+      sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, sequence_number_++,
+                            kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
       ++packets_sent;
+      bytes_in_flight_ += kDefaultTCPMSS;
       can_send = sender_->TimeUntilSend(
-          clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero();
+          clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero();
     }
     return packets_sent;
   }
 
-  void UpdateRtt(QuicTime::Delta rtt) {
-    sender_->rtt_stats_.UpdateRtt(rtt, QuicTime::Delta::Zero(), clock_.Now());
-    sender_->OnRttUpdated(acked_sequence_number_ + 1);
-  }
-
   // Normal is that TCP acks every other segment.
   void AckNPackets(int n) {
+    sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(60),
+                                  QuicTime::Delta::Zero(),
+                                  clock_.Now());
+    SendAlgorithmInterface::CongestionMap acked_packets;
+    SendAlgorithmInterface::CongestionMap lost_packets;
     for (int i = 0; i < n; ++i) {
       ++acked_sequence_number_;
-      UpdateRtt(QuicTime::Delta::FromMilliseconds(60));
-      sender_->OnPacketAcked(acked_sequence_number_, kDefaultTCPMSS);
+      acked_packets[acked_sequence_number_] = standard_packet_;
     }
-    clock_.AdvanceTime(one_ms_);  // 1 millisecond.
+    sender_->OnCongestionEvent(
+        true, bytes_in_flight_, acked_packets, lost_packets);
+    bytes_in_flight_ -= n * kDefaultTCPMSS;
+    clock_.AdvanceTime(one_ms_);
   }
 
   void LoseNPackets(int n) {
+    SendAlgorithmInterface::CongestionMap acked_packets;
+    SendAlgorithmInterface::CongestionMap lost_packets;
     for (int i = 0; i < n; ++i) {
       ++acked_sequence_number_;
-      sender_->OnPacketAbandoned(acked_sequence_number_, kDefaultTCPMSS);
-      sender_->OnPacketLost(acked_sequence_number_, clock_.Now());
+      lost_packets[acked_sequence_number_] = standard_packet_;
     }
+    sender_->OnCongestionEvent(
+        false, bytes_in_flight_, acked_packets, lost_packets);
+    bytes_in_flight_ -= n * kDefaultTCPMSS;
+  }
+
+  // Does not increment acked_sequence_number_.
+  void LosePacket(QuicPacketSequenceNumber sequence_number) {
+    SendAlgorithmInterface::CongestionMap acked_packets;
+    SendAlgorithmInterface::CongestionMap lost_packets;
+    lost_packets[sequence_number] = standard_packet_;
+    sender_->OnCongestionEvent(
+        false, bytes_in_flight_, acked_packets, lost_packets);
+    bytes_in_flight_ -= kDefaultTCPMSS;
   }
 
   const QuicTime::Delta one_ms_;
@@ -103,35 +121,60 @@
   scoped_ptr<TcpReceiver> receiver_;
   QuicPacketSequenceNumber sequence_number_;
   QuicPacketSequenceNumber acked_sequence_number_;
+  QuicByteCount bytes_in_flight_;
+  TransmissionInfo standard_packet_;
 };
 
 TEST_F(TcpCubicSenderTest, SimpleSender) {
   QuicCongestionFeedbackFrame feedback;
   // At startup make sure we are at the default.
-  EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableSendWindow());
   EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
   // At startup make sure we can send.
   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
+                                     0,
+                                     HAS_RETRANSMITTABLE_DATA).IsZero());
+  // Get default QuicCongestionFeedbackFrame from receiver.
+  ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
+  sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
+  // Make sure we can send.
+  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
+                                     0,
+                                     HAS_RETRANSMITTABLE_DATA).IsZero());
+  // And that window is un-affected.
+  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
+
+  // Fill the send window with data, then verify that we can't send.
+  SendAvailableSendWindow();
+  EXPECT_FALSE(sender_->TimeUntilSend(clock_.Now(),
+                                      sender_->GetCongestionWindow(),
+                                      HAS_RETRANSMITTABLE_DATA).IsZero());
+}
+
+TEST_F(TcpCubicSenderTest, ApplicationLimitedSlowStart) {
+  // Send exactly 10 packets and ensure the CWND ends at 14 packets.
+  const int kNumberOfAcks = 5;
+  QuicCongestionFeedbackFrame feedback;
+  // At startup make sure we can send.
+  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
+      0,
       HAS_RETRANSMITTABLE_DATA).IsZero());
   // Get default QuicCongestionFeedbackFrame from receiver.
   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
   // Make sure we can send.
-
   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
-  // And that window is un-affected.
-  EXPECT_EQ(kDefaultWindowTCP, sender_->AvailableSendWindow());
-  EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-
-  // There is available window, so we should be able to send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
+                                     0,
                                      HAS_RETRANSMITTABLE_DATA).IsZero());
 
-  // Fill the send window with data, then verify that we can't send.
   SendAvailableSendWindow();
-  EXPECT_FALSE(sender_->TimeUntilSend(clock_.Now(),
-                                      HAS_RETRANSMITTABLE_DATA).IsZero());
+  for (int i = 0; i < kNumberOfAcks; ++i) {
+    AckNPackets(2);
+  }
+  QuicByteCount bytes_to_send = sender_->SendWindow();
+  // It's expected 2 acks will arrive when the bytes_in_flight are greater than
+  // half the CWND.
+  EXPECT_EQ(kDefaultWindowTCP + kDefaultTCPMSS * 2 * 2,
+            bytes_to_send);
 }
 
 TEST_F(TcpCubicSenderTest, ExponentialSlowStart) {
@@ -139,13 +182,15 @@
   QuicCongestionFeedbackFrame feedback;
   // At startup make sure we can send.
   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
+      0,
       HAS_RETRANSMITTABLE_DATA).IsZero());
   // Get default QuicCongestionFeedbackFrame from receiver.
   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
   // Make sure we can send.
   EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
+                                     0,
+                                     HAS_RETRANSMITTABLE_DATA).IsZero());
 
   for (int i = 0; i < kNumberOfAcks; ++i) {
     // Send our full send window.
@@ -165,15 +210,9 @@
   // Hence we should pass 30 at 65 = 5 + 10 + 20 + 30
   const int kNumberOfAcks = 65;
   QuicCongestionFeedbackFrame feedback;
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
   // Get default QuicCongestionFeedbackFrame from receiver.
   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
-  // Make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
 
   for (int i = 0; i < kNumberOfAcks; ++i) {
     // Send our full send window.
@@ -183,7 +222,6 @@
   QuicByteCount expected_send_window =
       kDefaultWindowTCP + (kDefaultTCPMSS * 2 * kNumberOfAcks);
   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-  EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
 
   // We should now have fallen out of slow start.
   // Testing Reno phase.
@@ -208,15 +246,9 @@
 TEST_F(TcpCubicSenderTest, SlowStartPacketLoss) {
   // Make sure that we fall out of slow start when we encounter a packet loss.
   QuicCongestionFeedbackFrame feedback;
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
   // Get default QuicCongestionFeedbackFrame from receiver.
   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
-  // Make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
 
   const int kNumberOfAcks = 10;
   for (int i = 0; i < kNumberOfAcks; ++i) {
@@ -229,12 +261,8 @@
       (kDefaultTCPMSS * 2 * kNumberOfAcks);
   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
 
-  sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now());
-  ++acked_sequence_number_;
-
-  // Make sure that we can send right now due to limited transmit.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-                                     HAS_RETRANSMITTABLE_DATA).IsZero());
+  // Lose a packet to exit slow start.
+  LoseNPackets(1);
 
   // We should now have fallen out of slow start.
   // We expect window to be cut in half by Reno.
@@ -246,7 +274,6 @@
   size_t number_of_packets_in_window = expected_send_window / kDefaultTCPMSS;
   AckNPackets(number_of_packets_in_window);
   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
-  EXPECT_EQ(0u, sender_->AvailableSendWindow());
 
   // We need to ack every packet in the window before we exit recovery.
   for (size_t i = 0; i < number_of_packets_in_window; ++i) {
@@ -276,9 +303,6 @@
   // Test based on the first example in RFC6937.
   // Make sure that we fall out of slow start when we encounter a packet loss.
   QuicCongestionFeedbackFrame feedback;
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
   // Get default QuicCongestionFeedbackFrame from receiver.
   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
@@ -302,11 +326,6 @@
   expected_send_window /= 2;
   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
 
-  // Send 1 packet to simulate limited transmit.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-                                     HAS_RETRANSMITTABLE_DATA).IsZero());
-  EXPECT_EQ(1, SendAvailableSendWindow());
-
   // Testing TCP proportional rate reduction.
   // We should send one packet for every two received acks over the remaining
   // 18 outstanding packets.
@@ -317,18 +336,13 @@
   for (size_t i = 0; i < remaining_packets_in_recovery - 1; i += 2) {
     AckNPackets(2);
     EXPECT_TRUE(sender_->TimeUntilSend(
-        clock_.Now(), HAS_RETRANSMITTABLE_DATA).IsZero());
-    EXPECT_EQ(0u, sender_->AvailableSendWindow());
+        clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero());
     EXPECT_EQ(1, SendAvailableSendWindow());
     EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
   }
-  // If there is one more packet to ack before completing recovery, ack it.
-  if (remaining_packets_in_recovery % 2 == 1) {
-    AckNPackets(1);
-  }
 
   // We need to ack another window before we increase CWND by 1.
-  for (size_t i = 0; i < number_of_packets_in_window - 1; ++i) {
+  for (size_t i = 0; i < number_of_packets_in_window; ++i) {
     AckNPackets(1);
     EXPECT_EQ(1, SendAvailableSendWindow());
     EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
@@ -345,9 +359,6 @@
   // PRR immediately.
   // Make sure that we fall out of slow start when we encounter a packet loss.
   QuicCongestionFeedbackFrame feedback;
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
   // Get default QuicCongestionFeedbackFrame from receiver.
   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
@@ -365,8 +376,12 @@
   EXPECT_EQ(expected_send_window, sender_->GetCongestionWindow());
 
   // Ack a packet with a 15 packet gap, losing 13 of them due to FACK.
-  sender_->OnPacketAcked(acked_sequence_number_ + 15, kDefaultTCPMSS);
   LoseNPackets(13);
+  // Immediately after the loss, ensure at least one packet can be sent.
+  // Losses without subsequent acks can occur with timer based loss detection.
+  EXPECT_TRUE(sender_->TimeUntilSend(
+      clock_.Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA).IsZero());
+  AckNPackets(1);
 
   // We should now have fallen out of slow start.
   // We expect window to be cut in half by Reno.
@@ -377,15 +392,15 @@
   EXPECT_EQ(2, SendAvailableSendWindow());
 
   // Ack the next packet, which triggers another loss.
-  sender_->OnPacketAcked(acked_sequence_number_ + 4, kDefaultTCPMSS);
   LoseNPackets(1);
+  AckNPackets(1);
 
   // Send 2 packets to simulate PRR-SSRB.
   EXPECT_EQ(2, SendAvailableSendWindow());
 
   // Ack the next packet, which triggers another loss.
-  sender_->OnPacketAcked(acked_sequence_number_ + 4, kDefaultTCPMSS);
   LoseNPackets(1);
+  AckNPackets(1);
 
   // Send 2 packets to simulate PRR-SSRB.
   EXPECT_EQ(2, SendAvailableSendWindow());
@@ -428,7 +443,8 @@
   const int64 kDeviationMs = 3;
   EXPECT_EQ(QuicTime::Delta::Zero(), sender_->RetransmissionDelay());
 
-  UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs));
+  sender_->rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
+                                QuicTime::Delta::Zero(), clock_.Now());
 
   // Initial value is to set the median deviation to half of the initial
   // rtt, the median in then multiplied by a factor of 4 and finally the
@@ -439,8 +455,12 @@
 
   for (int i = 0; i < 100; ++i) {
     // Run to make sure that we converge.
-    UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs));
-    UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs));
+    sender_->rtt_stats_.UpdateRtt(
+        QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
+        QuicTime::Delta::Zero(), clock_.Now());
+    sender_->rtt_stats_.UpdateRtt(
+        QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
+        QuicTime::Delta::Zero(), clock_.Now());
   }
   expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
 
@@ -461,15 +481,9 @@
       new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP));
 
   QuicCongestionFeedbackFrame feedback;
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
   // Get default QuicCongestionFeedbackFrame from receiver.
   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
-  // Make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
 
   for (int i = 0; i < kNumberOfAcks; ++i) {
     // Send our full send window.
@@ -488,21 +502,14 @@
       new TcpCubicSenderPeer(&clock_, true, kMaxCongestionWindowTCP));
 
   QuicCongestionFeedbackFrame feedback;
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
   // Get default QuicCongestionFeedbackFrame from receiver.
   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
-  // Make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
-
 
   SendAvailableSendWindow();
   AckNPackets(2);
   // Make sure we fall out of slow start.
-  sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now());
+  LoseNPackets(1);
 
   for (int i = 0; i < kNumberOfAcks; ++i) {
     // Send our full send window.
@@ -524,20 +531,14 @@
       new TcpCubicSenderPeer(&clock_, false, kMaxCongestionWindowTCP));
 
   QuicCongestionFeedbackFrame feedback;
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
   // Get default QuicCongestionFeedbackFrame from receiver.
   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
-  // Make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
 
   SendAvailableSendWindow();
   AckNPackets(2);
   // Make sure we fall out of slow start.
-  sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now());
+  LoseNPackets(1);
 
   for (int i = 0; i < kNumberOfAcks; ++i) {
     // Send our full send window.
@@ -553,34 +554,29 @@
 TEST_F(TcpCubicSenderTest, MultipleLossesInOneWindow) {
   SendAvailableSendWindow();
   const QuicByteCount initial_window = sender_->GetCongestionWindow();
-  sender_->OnPacketLost(acked_sequence_number_ + 1, clock_.Now());
+  LosePacket(acked_sequence_number_ + 1);
   const QuicByteCount post_loss_window = sender_->GetCongestionWindow();
   EXPECT_GT(initial_window, post_loss_window);
-  sender_->OnPacketLost(acked_sequence_number_ + 3, clock_.Now());
+  LosePacket(acked_sequence_number_ + 3);
   EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
-  sender_->OnPacketLost(sequence_number_ - 1, clock_.Now());
+  LosePacket(sequence_number_ - 1);
   EXPECT_EQ(post_loss_window, sender_->GetCongestionWindow());
 
   // Lose a later packet and ensure the window decreases.
-  sender_->OnPacketLost(sequence_number_, clock_.Now());
+  LosePacket(sequence_number_);
   EXPECT_GT(post_loss_window, sender_->GetCongestionWindow());
 }
 
-TEST_F(TcpCubicSenderTest, SendWindowNotAffectedByAcks) {
-  QuicByteCount send_window = sender_->AvailableSendWindow();
+TEST_F(TcpCubicSenderTest, DontTrackAckPackets) {
+  // Send a packet with no retransmittable data, and ensure it's not tracked.
+  EXPECT_FALSE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
+                                     sequence_number_++, kDefaultTCPMSS,
+                                     NO_RETRANSMITTABLE_DATA));
 
-  // Send a packet with no retransmittable data, and ensure that the congestion
-  // window doesn't change.
-  QuicByteCount bytes_in_packet = min(kDefaultTCPMSS, send_window);
-  sender_->OnPacketSent(clock_.Now(), sequence_number_++, bytes_in_packet,
-                        NO_RETRANSMITTABLE_DATA);
-  EXPECT_EQ(send_window, sender_->AvailableSendWindow());
-
-  // Send a data packet with retransmittable data, and ensure that the
-  // congestion window has shrunk.
-  sender_->OnPacketSent(clock_.Now(), sequence_number_++, bytes_in_packet,
-                        HAS_RETRANSMITTABLE_DATA);
-  EXPECT_GT(send_window, sender_->AvailableSendWindow());
+  // Send a data packet with retransmittable data, and ensure it is tracked.
+  EXPECT_TRUE(sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
+                                    sequence_number_++, kDefaultTCPMSS,
+                                    HAS_RETRANSMITTABLE_DATA));
 }
 
 TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) {
@@ -595,9 +591,6 @@
 TEST_F(TcpCubicSenderTest, CongestionAvoidanceAtEndOfRecovery) {
   // Make sure that we fall out of slow start when we encounter a packet loss.
   QuicCongestionFeedbackFrame feedback;
-  // At startup make sure we can send.
-  EXPECT_TRUE(sender_->TimeUntilSend(clock_.Now(),
-      HAS_RETRANSMITTABLE_DATA).IsZero());
   // Get default QuicCongestionFeedbackFrame from receiver.
   ASSERT_TRUE(receiver_->GenerateCongestionFeedback(&feedback));
   sender_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
diff --git a/net/quic/congestion_control/tcp_loss_algorithm_test.cc b/net/quic/congestion_control/tcp_loss_algorithm_test.cc
index 657ab2b..d7d2d72 100644
--- a/net/quic/congestion_control/tcp_loss_algorithm_test.cc
+++ b/net/quic/congestion_control/tcp_loss_algorithm_test.cc
@@ -171,7 +171,7 @@
   // Early retransmit when the final packet gets acked and the first is nacked.
   unacked_packets_.SetNotPending(2);
   unacked_packets_.NackPacket(1, 1);
-  unacked_packets_.NeuterPacket(1);
+  unacked_packets_.NeuterIfPendingOrRemovePacket(1);
   VerifyLosses(2, NULL, 0);
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
 }
diff --git a/net/quic/crypto/quic_crypto_server_config.cc b/net/quic/crypto/quic_crypto_server_config.cc
index 0a3c1ad..260c0d4 100644
--- a/net/quic/crypto/quic_crypto_server_config.cc
+++ b/net/quic/crypto/quic_crypto_server_config.cc
@@ -1273,11 +1273,10 @@
   primary_config_changed_cb_.reset(cb);
 }
 
-string QuicCryptoServerConfig::NewSourceAddressToken(
-    const Config& config,
-    const IPEndPoint& ip,
-    QuicRandom* rand,
-    QuicWallTime now) const {
+string QuicCryptoServerConfig::NewSourceAddressToken(const Config& config,
+                                                     const IPEndPoint& ip,
+                                                     QuicRandom* rand,
+                                                     QuicWallTime now) const {
   SourceAddressToken source_address_token;
   source_address_token.set_ip(IPAddressToPackedString(ip.address()));
   source_address_token.set_timestamp(now.ToUNIXSeconds());
diff --git a/net/quic/crypto/quic_crypto_server_config.h b/net/quic/crypto/quic_crypto_server_config.h
index feac852..216dbbf 100644
--- a/net/quic/crypto/quic_crypto_server_config.h
+++ b/net/quic/crypto/quic_crypto_server_config.h
@@ -381,20 +381,18 @@
 
   // NewSourceAddressToken returns a fresh source address token for the given
   // IP address.
-  std::string NewSourceAddressToken(
-      const Config& config,
-      const IPEndPoint& ip,
-      QuicRandom* rand,
-      QuicWallTime now) const;
+  std::string NewSourceAddressToken(const Config& config,
+                                    const IPEndPoint& ip,
+                                    QuicRandom* rand,
+                                    QuicWallTime now) const;
 
   // ValidateSourceAddressToken returns true if the source address token in
   // |token| is a valid and timely token for the IP address |ip| given that the
   // current time is |now|.
-  bool ValidateSourceAddressToken(
-      const Config& config,
-      base::StringPiece token,
-      const IPEndPoint& ip,
-      QuicWallTime now) const;
+  bool ValidateSourceAddressToken(const Config& config,
+                                  base::StringPiece token,
+                                  const IPEndPoint& ip,
+                                  QuicWallTime now) const;
 
   // NewServerNonce generates and encrypts a random nonce.
   std::string NewServerNonce(QuicRandom* rand, QuicWallTime now) const;
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index f0e0619..6838a1e 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -23,6 +23,7 @@
 #include "net/quic/quic_bandwidth.h"
 #include "net/quic/quic_config.h"
 #include "net/quic/quic_flags.h"
+#include "net/quic/quic_flow_controller.h"
 #include "net/quic/quic_utils.h"
 
 using base::hash_map;
@@ -243,6 +244,12 @@
                 << kDefaultFlowControlSendWindow << ").";
     max_flow_control_receive_window_bytes_ = kDefaultFlowControlSendWindow;
   }
+
+  flow_controller_.reset(new QuicFlowController(
+      supported_versions.front(), 0, is_server_,
+      kDefaultFlowControlSendWindow, max_flow_control_receive_window_bytes_,
+      max_flow_control_receive_window_bytes_));
+
   if (!is_server_) {
     // Pacing will be enabled if the client negotiates it.
     sent_packet_manager_.MaybeEnablePacing();
@@ -364,6 +371,10 @@
   // Store the new version.
   framer_.set_version(received_version);
 
+  if (received_version < QUIC_VERSION_19) {
+    flow_controller_->Disable();
+  }
+
   // TODO(satyamshekhar): Store the sequence number of this packet and close the
   // connection if we ever received a packet with incorrect version and whose
   // sequence number is greater.
@@ -479,6 +490,9 @@
         DCHECK_EQ(header.public_header.versions[0], version());
         version_negotiation_state_ = NEGOTIATED_VERSION;
         visitor_->OnSuccessfulVersionNegotiation(version());
+        if (version() < QUIC_VERSION_19) {
+          flow_controller_->Disable();
+        }
       }
     } else {
       DCHECK(!header.public_header.version_flag);
@@ -487,6 +501,9 @@
       packet_creator_.StopSendingVersion();
       version_negotiation_state_ = NEGOTIATED_VERSION;
       visitor_->OnSuccessfulVersionNegotiation(version());
+      if (version() < QUIC_VERSION_19) {
+        flow_controller_->Disable();
+      }
     }
   }
 
@@ -504,7 +521,7 @@
   DCHECK_NE(0u, last_header_.fec_group);
   QuicFecGroup* group = GetFecGroup();
   if (group != NULL) {
-    group->Update(last_header_, payload);
+    group->Update(last_decrypted_packet_level_, last_header_, payload);
   }
 }
 
@@ -714,7 +731,8 @@
   DCHECK_NE(0u, last_header_.fec_group);
   QuicFecGroup* group = GetFecGroup();
   if (group != NULL) {
-    group->UpdateFec(last_header_.packet_sequence_number, fec);
+    group->UpdateFec(last_decrypted_packet_level_,
+                     last_header_.packet_sequence_number, fec);
   }
 }
 
@@ -1251,8 +1269,8 @@
   WriteIfNotBlocked();
 }
 
-void QuicConnection::NeuterUnencryptedPackets() {
-  sent_packet_manager_.NeuterUnencryptedPackets();
+void QuicConnection::DiscardUnencryptedPackets() {
+  sent_packet_manager_.DiscardUnencryptedPackets();
   // This may have changed the retransmission timer, so re-arm it.
   retransmission_alarm_->Cancel();
   QuicTime retransmission_time = sent_packet_manager_.GetRetransmissionTime();
@@ -1625,6 +1643,7 @@
 
 void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) {
   encryption_level_ = level;
+  packet_creator_.set_encryption_level(level);
 }
 
 void QuicConnection::SetDecrypter(QuicDecrypter* decrypter,
@@ -1698,6 +1717,8 @@
   revived_header.is_in_fec_group = NOT_IN_FEC_GROUP;
   revived_header.fec_group = 0;
   group_map_.erase(last_header_.fec_group);
+  last_decrypted_packet_level_ = group->effective_encryption_level();
+  DCHECK_LT(last_decrypted_packet_level_, NUM_ENCRYPTION_LEVELS);
   delete group;
 
   last_packet_revived_ = true;
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index 1fe9bef..89affd3 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -49,6 +49,7 @@
 class QuicDecrypter;
 class QuicEncrypter;
 class QuicFecGroup;
+class QuicFlowController;
 class QuicRandom;
 
 namespace test {
@@ -266,6 +267,8 @@
                           QuicStreamId last_good_stream_id,
                           const std::string& reason);
 
+  QuicFlowController* flow_controller() { return flow_controller_.get(); }
+
   // Returns statistics tracked for this connection.
   const QuicConnectionStats& GetStats();
 
@@ -414,9 +417,9 @@
   // initially encrypted packets when the initial encrypter changes.
   void RetransmitUnackedPackets(RetransmissionType retransmission_type);
 
-  // Calls |sent_packet_manager_|'s NeuterUnencryptedPackets. Used when the
+  // Calls |sent_packet_manager_|'s DiscardUnencryptedPackets. Used when the
   // connection becomes forward secure and hasn't received acks for all packets.
-  void NeuterUnencryptedPackets();
+  void DiscardUnencryptedPackets();
 
   // Changes the encrypter used for level |level| to |encrypter|. The function
   // takes ownership of |encrypter|.
@@ -454,9 +457,6 @@
     return sent_packet_manager_;
   }
 
-  // Make sure a stop waiting we got from our peer is sane.
-  bool ValidateStopWaitingFrame(const QuicStopWaitingFrame& stop_waiting);
-
   bool CanWrite(TransmissionType transmission_type,
                 HasRetransmittableData retransmittable,
                 IsHandshake handshake);
@@ -543,6 +543,9 @@
   // Make sure an ack we got from our peer is sane.
   bool ValidateAckFrame(const QuicAckFrame& incoming_ack);
 
+  // Make sure a stop waiting we got from our peer is sane.
+  bool ValidateStopWaitingFrame(const QuicStopWaitingFrame& stop_waiting);
+
   // Sends a version negotiation packet to the peer.
   void SendVersionNegotiationPacket();
 
@@ -742,6 +745,9 @@
   // Initial flow control receive window size for new streams.
   uint32 max_flow_control_receive_window_bytes_;
 
+  // Used for connection level flow control.
+  scoped_ptr<QuicFlowController> flow_controller_;
+
   DISALLOW_COPY_AND_ASSIGN(QuicConnection);
 };
 
diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc
index cd579ff..477cc7e 100644
--- a/net/quic/quic_connection_logger.cc
+++ b/net/quic/quic_connection_logger.cc
@@ -424,6 +424,13 @@
 void QuicConnectionLogger::OnPacketReceived(const IPEndPoint& self_address,
                                             const IPEndPoint& peer_address,
                                             const QuicEncryptedPacket& packet) {
+  if (local_address_from_self_.GetFamily() == ADDRESS_FAMILY_UNSPECIFIED) {
+    local_address_from_self_ = self_address;
+    UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionTypeFromSelf",
+                              self_address.GetFamily(),
+                              ADDRESS_FAMILY_LAST);
+  }
+
   last_received_packet_size_ = packet.length();
   net_log_.AddEvent(
       NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
@@ -551,7 +558,7 @@
 void QuicConnectionLogger::OnPublicResetPacket(
     const QuicPublicResetPacket& packet) {
   net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_PUBLIC_RESET_PACKET_RECEIVED);
-  UpdatePublicResetAddressMismatchHistogram(client_address_,
+  UpdatePublicResetAddressMismatchHistogram(local_address_from_shlo_,
                                             packet.client_address);
 }
 
@@ -581,7 +588,10 @@
     QuicSocketAddressCoder decoder;
     if (message.GetStringPiece(kCADR, &address) &&
         decoder.Decode(address.data(), address.size())) {
-      client_address_ = IPEndPoint(decoder.ip(), decoder.port());
+      local_address_from_shlo_ = IPEndPoint(decoder.ip(), decoder.port());
+      UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionTypeFromPeer",
+                                local_address_from_shlo_.GetFamily(),
+                                ADDRESS_FAMILY_LAST);
     }
   }
 }
diff --git a/net/quic/quic_connection_logger.h b/net/quic/quic_connection_logger.h
index 69faed3..8baa1b8 100644
--- a/net/quic/quic_connection_logger.h
+++ b/net/quic/quic_connection_logger.h
@@ -126,7 +126,9 @@
   // Number of times a truncated ACK frame was received.
   size_t num_truncated_acks_received_;
   // The kCADR value provided by the server in ServerHello.
-  IPEndPoint client_address_;
+  IPEndPoint local_address_from_shlo_;
+  // The first local address from which a packet was received.
+  IPEndPoint local_address_from_self_;
   // Count of the number of frames received.
   int num_frames_received_;
   // Count of the number of duplicate frames received.
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index 3a0c172..6ca7c30 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -601,17 +601,17 @@
     // Simplify tests by not sending feedback unless specifically configured.
     SetFeedback(NULL);
     EXPECT_CALL(
-        *send_algorithm_, TimeUntilSend(_, _)).WillRepeatedly(Return(
+        *send_algorithm_, TimeUntilSend(_, _, _)).WillRepeatedly(Return(
             QuicTime::Delta::Zero()));
     EXPECT_CALL(*receive_algorithm_,
                 RecordIncomingPacket(_, _, _)).Times(AnyNumber());
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
         .Times(AnyNumber());
     EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
         Return(QuicTime::Delta::Zero()));
     EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
         Return(kMaxPacketSize));
-    ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
+    ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
         .WillByDefault(Return(true));
     EXPECT_CALL(visitor_, HasPendingWrites()).Times(AnyNumber());
     EXPECT_CALL(visitor_, HasPendingHandshake()).Times(AnyNumber());
@@ -769,22 +769,22 @@
                                      bool fin,
                                      QuicPacketSequenceNumber* last_packet) {
     QuicByteCount packet_size;
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
-        .WillOnce(DoAll(SaveArg<2>(&packet_size), Return(true)));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+        .WillOnce(DoAll(SaveArg<3>(&packet_size), Return(true)));
     connection_.SendStreamDataWithString(id, data, offset, fin, NULL);
     if (last_packet != NULL) {
       *last_packet =
           QuicConnectionPeer::GetPacketCreator(&connection_)->sequence_number();
     }
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
         .Times(AnyNumber());
     return packet_size;
   }
 
   void SendAckPacketToPeer() {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1);
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
     connection_.SendAck();
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
         .Times(AnyNumber());
   }
 
@@ -1023,7 +1023,8 @@
   // awaiting' is 4.  The connection should then realize 1 will not be
   // retransmitted, and will remove it from the missing list.
   creator_.set_sequence_number(5);
-  QuicAckFrame frame = InitAckFrame(0, 4);
+  QuicAckFrame frame = InitAckFrame(1, 4);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _));
   ProcessAckPacket(&frame);
 
   // Force an ack to be sent.
@@ -1077,10 +1078,7 @@
       .WillOnce(Return(lost_packets));
   EXPECT_CALL(entropy_calculator_,
               EntropyHash(511)).WillOnce(testing::Return(0));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(256);
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(255);
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(255);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&frame);
 
   QuicReceivedPacketManager* received_packet_manager =
@@ -1095,8 +1093,7 @@
   // 192 has already been declared lost, so it doesn't register as an ack.
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(SequenceNumberSet()));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&frame);
   EXPECT_EQ(num_packets,
             received_packet_manager->peer_largest_observed_packet());
@@ -1108,14 +1105,14 @@
   ProcessPacket(1);
   // Delay sending, then queue up an ack.
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::FromMicroseconds(1)));
   QuicConnectionPeer::SendAck(&connection_);
 
   // Process an ack with a least unacked of the received ack.
   // This causes an ack to be sent when TimeUntilSend returns 0.
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillRepeatedly(
+              TimeUntilSend(_, _, _)).WillRepeatedly(
                   testing::Return(QuicTime::Delta::Zero()));
   // Skip a packet and then record an ack.
   creator_.set_sequence_number(2);
@@ -1148,8 +1145,8 @@
 
   QuicPacketSequenceNumber original;
   QuicByteCount packet_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
-      .WillOnce(DoAll(SaveArg<1>(&original), SaveArg<2>(&packet_size),
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(DoAll(SaveArg<2>(&original), SaveArg<3>(&packet_size),
                       Return(true)));
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
   QuicAckFrame frame = InitAckFrame(original, 1);
@@ -1159,20 +1156,17 @@
   lost_packets.insert(1);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1);
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicPacketSequenceNumber retransmission;
   EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, packet_size - kQuicVersionSize, _))
-      .WillOnce(DoAll(SaveArg<1>(&retransmission), Return(true)));
+              OnPacketSent(_, _, _, packet_size - kQuicVersionSize, _))
+      .WillOnce(DoAll(SaveArg<2>(&retransmission), Return(true)));
 
   ProcessAckPacket(&frame);
 
   QuicAckFrame frame2 = InitAckFrame(retransmission, 1);
   NackPacket(original, &frame2);
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(SequenceNumberSet()));
   ProcessAckPacket(&frame2);
@@ -1180,7 +1174,7 @@
   // Now if the peer sends an ack which still reports the retransmitted packet
   // as missing, that will bundle an ack with data after two acks in a row
   // indicate the high water mark needs to be raised.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _,
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _,
                                              HAS_RETRANSMITTABLE_DATA));
   connection_.SendStreamDataWithString(3, "foo", 3, !kFin, NULL);
   // No ack sent.
@@ -1191,7 +1185,7 @@
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillRepeatedly(Return(SequenceNumberSet()));
   ProcessAckPacket(&frame2);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _,
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _,
                                              HAS_RETRANSMITTABLE_DATA));
   connection_.SendStreamDataWithString(3, "foo", 3, !kFin, NULL);
   // Ack bundled.
@@ -1242,7 +1236,7 @@
 
   // Now claim it's one, but set the ordering so it was sent "after" the first
   // one.  This should cause a connection error.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   creator_.set_sequence_number(7);
   if (version() > QUIC_VERSION_15) {
     EXPECT_CALL(visitor_,
@@ -1262,8 +1256,7 @@
   SendStreamDataToPeer(1, "foo", 0, !kFin, NULL);
   SendStreamDataToPeer(1, "bar", 3, !kFin, NULL);
   SendStreamDataToPeer(1, "eep", 6, !kFin, NULL);
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
 
   // Start out saying the largest observed is 2.
   QuicAckFrame frame1 = InitAckFrame(1, 0);
@@ -1280,7 +1273,7 @@
   // Ack a packet which has not been sent.
   EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INVALID_ACK_DATA, false));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   QuicAckFrame frame(MakeAckFrame(1, 0));
   EXPECT_CALL(visitor_, OnCanWrite()).Times(0);
   ProcessAckPacket(&frame);
@@ -1409,8 +1402,7 @@
   SendAckPacketToPeer();  // Packet 5
   EXPECT_EQ(1u, least_unacked());
 
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(3);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
 
   // Peer acks up to packet 3.
   QuicAckFrame frame = InitAckFrame(3, 0);
@@ -1421,8 +1413,7 @@
   // ack for 4.
   EXPECT_EQ(4u, least_unacked());
 
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(3);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
 
   // Peer acks up to packet 4, the last packet.
   QuicAckFrame frame2 = InitAckFrame(6, 0);
@@ -1446,9 +1437,6 @@
 }
 
 TEST_P(QuicConnectionTest, FECSending) {
-  if (version() < QUIC_VERSION_15) {
-    return;
-  }
   // All packets carry version info till version is negotiated.
   size_t payload_length;
   connection_.options()->max_packet_length =
@@ -1459,7 +1447,7 @@
   connection_.options()->max_packets_per_fec_group = 2;
 
   // Send 4 data packets and 2 FEC packets.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(6);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
   // The first stream frame will consume 2 fewer bytes than the other three.
   const string payload(payload_length * 4 - 6, 'a');
   connection_.SendStreamDataWithString(1, payload, 0, !kFin, NULL);
@@ -1468,9 +1456,6 @@
 }
 
 TEST_P(QuicConnectionTest, FECQueueing) {
-  if (version() < QUIC_VERSION_15) {
-    return;
-  }
   // All packets carry version info till version is negotiated.
   size_t payload_length;
   connection_.options()->max_packet_length =
@@ -1490,12 +1475,9 @@
 }
 
 TEST_P(QuicConnectionTest, AbandonFECFromCongestionWindow) {
-  if (version() < QUIC_VERSION_15) {
-    return;
-  }
   connection_.options()->max_packets_per_fec_group = 1;
   // 1 Data and 1 FEC packet.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(2);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
 
   const QuicTime::Delta retransmission_time =
@@ -1504,20 +1486,17 @@
 
   // Abandon FEC packet and data packet.
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   EXPECT_CALL(visitor_, OnCanWrite());
   connection_.OnRetransmissionTimeout();
 }
 
 TEST_P(QuicConnectionTest, DontAbandonAckedFEC) {
-  if (version() < QUIC_VERSION_15) {
-    return;
-  }
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   connection_.options()->max_packets_per_fec_group = 1;
 
   // 1 Data and 1 FEC packet.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(6);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
   // Send some more data afterwards to ensure early retransmit doesn't trigger.
   connection_.SendStreamDataWithString(3, "foo", 3, !kFin, NULL);
@@ -1528,28 +1507,23 @@
   // TODO(ianswett): Note that this is not a sensible ack, since if the FEC was
   // received, it would cause the covered packet to be acked as well.
   NackPacket(1, &ack_fec);
-
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&ack_fec);
   clock_.AdvanceTime(DefaultRetransmissionTime());
 
   // Don't abandon the acked FEC packet, but it will abandon 2 the subsequent
   // FEC packets.
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(3);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
   connection_.GetRetransmissionAlarm()->Fire();
 }
 
 TEST_P(QuicConnectionTest, AbandonAllFEC) {
-  if (version() < QUIC_VERSION_15) {
-    return;
-  }
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   connection_.options()->max_packets_per_fec_group = 1;
 
   // 1 Data and 1 FEC packet.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(6);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
   // Send some more data afterwards to ensure early retransmit doesn't trigger.
   connection_.SendStreamDataWithString(3, "foo", 3, !kFin, NULL);
@@ -1567,10 +1541,7 @@
   lost_packets.insert(2);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(3);
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(2, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(2, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&ack_fec);
 
   clock_.AdvanceTime(DefaultRetransmissionTime().Subtract(
@@ -1597,7 +1568,7 @@
       IgnoreResult(InvokeWithoutArgs(&connection_,
                                      &TestConnection::SendStreamData5))));
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   // Unblock the connection.
   connection_.GetSendAlarm()->Fire();
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -1631,7 +1602,7 @@
       IgnoreResult(InvokeWithoutArgs(&connection_,
                                      &TestConnection::SendCryptoStreamData))));
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(2);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
   // Unblock the connection.
   connection_.GetSendAlarm()->Fire();
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -1657,7 +1628,7 @@
       IgnoreResult(InvokeWithoutArgs(&connection_,
                                      &TestConnection::SendStreamData3))));
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(3);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
   // Unblock the connection.
   connection_.GetSendAlarm()->Fire();
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -1687,7 +1658,7 @@
       IgnoreResult(InvokeWithoutArgs(&connection_,
                                      &TestConnection::SendStreamData5))));
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(2);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
   // Unblock the connection.
   connection_.GetSendAlarm()->Fire();
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -1710,7 +1681,7 @@
       IgnoreResult(InvokeWithoutArgs(&connection_,
                                      &TestConnection::SendStreamData5))));
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
 
   // Process an ack to cause the visitor's OnCanWrite to be invoked.
   creator_.set_sequence_number(2);
@@ -1737,7 +1708,7 @@
 TEST_P(QuicConnectionTest, FramePackingSendv) {
   // Send data in 1 packet by writing multiple blocks in a single iovector
   // using writev.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
 
   char data[] = "ABCD";
   IOVector data_iov;
@@ -1761,7 +1732,7 @@
 
 TEST_P(QuicConnectionTest, FramePackingSendvQueued) {
   // Try to send two stream frames in 1 packet by using writev.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
 
   BlockOnNextWrite();
   char data[] = "ABCD";
@@ -1786,7 +1757,7 @@
 
 TEST_P(QuicConnectionTest, SendingZeroBytes) {
   // Send a zero byte write with a fin using writev.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   IOVector empty_iov;
   connection_.SendStreamData(1, empty_iov, 0, kFin, NULL);
 
@@ -1809,7 +1780,7 @@
                                      &TestConnection::SendStreamData5))));
   EXPECT_CALL(visitor_, HasPendingWrites()).WillOnce(Return(true));
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillRepeatedly(
+              TimeUntilSend(_, _, _)).WillRepeatedly(
                   testing::Return(QuicTime::Delta::Zero()));
 
   connection_.OnCanWrite();
@@ -1833,8 +1804,7 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   // Don't lose a packet on an ack, and nothing is retransmitted.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(1, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicAckFrame ack_one = InitAckFrame(1, 0);
   ProcessAckPacket(&ack_one);
 
@@ -1845,12 +1815,9 @@
   lost_packets.insert(2);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(3, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(2, _)).Times(1);
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(2, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, second_packet_size - kQuicVersionSize, _)).
+              OnPacketSent(_, _, _, second_packet_size - kQuicVersionSize, _)).
                   Times(1);
   ProcessAckPacket(&nack_two);
 }
@@ -1873,10 +1840,7 @@
   lost_packets.insert(2);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(2);
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(2, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(2, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&nack_two);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
 
@@ -1890,7 +1854,7 @@
   // since the previous transmission has been acked, we will not
   // send the retransmission.
   EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _)).Times(0);
+              OnPacketSent(_, _, _, _, _)).Times(0);
 
   writer_->SetWritable();
   connection_.OnCanWrite();
@@ -1902,8 +1866,8 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   QuicPacketSequenceNumber largest_observed;
   QuicByteCount packet_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
-      .WillOnce(DoAll(SaveArg<1>(&largest_observed), SaveArg<2>(&packet_size),
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(DoAll(SaveArg<2>(&largest_observed), SaveArg<3>(&packet_size),
                       Return(true)));
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
 
@@ -1914,17 +1878,15 @@
   lost_packets.insert(1);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1);
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, packet_size - kQuicVersionSize, _));
+              OnPacketSent(_, _, _, packet_size - kQuicVersionSize, _));
   ProcessAckPacket(&frame);
 }
 
 TEST_P(QuicConnectionTest, QueueAfterTwoRTOs) {
   for (int i = 0; i < 10; ++i) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1);
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
     connection_.SendStreamDataWithString(3, "foo", i * 3, !kFin, NULL);
   }
 
@@ -1942,7 +1904,7 @@
       2 * DefaultRetransmissionTime().ToMicroseconds()));
   // Retransmit already retransmitted packets event though the sequence number
   // greater than the largest observed.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(10);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(10);
   connection_.GetRetransmissionAlarm()->Fire();
   connection_.OnCanWrite();
 }
@@ -1953,7 +1915,7 @@
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, NULL);
   EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   connection_.OnPacketSent(WriteResult(WRITE_STATUS_OK, 0));
   EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
 }
@@ -1970,7 +1932,7 @@
   QuicAckFrame ack = InitAckFrame(1, 0);
   ProcessAckPacket(&ack);
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
   connection_.OnPacketSent(WriteResult(WRITE_STATUS_OK, 0));
   EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
 }
@@ -1989,8 +1951,8 @@
 
   // Ack the sent packet before the callback returns, which happens in
   // rare circumstances with write blocked sockets.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
   QuicAckFrame ack = InitAckFrame(1, 0);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&ack);
 
   connection_.OnPacketSent(WriteResult(WRITE_STATUS_OK, 0));
@@ -2037,11 +1999,8 @@
   // the retransmission rate in the case of burst losses.
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(15, _)).Times(1);
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(14);
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(14);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(14);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(14);
   ProcessAckPacket(&nack);
 }
 
@@ -2061,30 +2020,27 @@
   EXPECT_EQ(6u, last_packet);
 
   // Client will ack packets 1, 2, [!3], 4, 5.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(4);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicAckFrame frame1 = InitAckFrame(5, 0);
   NackPacket(3, &frame1);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   ProcessAckPacket(&frame1);
 
   // Now the client implicitly acks 3, and explicitly acks 6.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicAckFrame frame2 = InitAckFrame(6, 0);
   ProcessAckPacket(&frame2);
 }
 
 TEST_P(QuicConnectionTest, DontLatchUnackedPacket) {
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(1);
   SendStreamDataToPeer(1, "foo", 0, !kFin, NULL);  // Packet 1;
   // From now on, we send acks, so the send algorithm won't mark them pending.
-  ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
+  ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
               .WillByDefault(Return(false));
   SendAckPacketToPeer();  // Packet 2
 
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicAckFrame frame = InitAckFrame(1, 0);
   ProcessAckPacket(&frame);
 
@@ -2092,7 +2048,7 @@
   // waiting for a potential ack for 2.
   EXPECT_EQ(2u, outgoing_ack()->sent_info.least_unacked);
 
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   frame = InitAckFrame(2, 0);
   ProcessAckPacket(&frame);
   EXPECT_EQ(3u, outgoing_ack()->sent_info.least_unacked);
@@ -2107,28 +2063,27 @@
   EXPECT_EQ(3u, least_unacked());
 
   // Ack the ack, which updates the rtt and raises the least unacked.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   frame = InitAckFrame(3, 0);
   ProcessAckPacket(&frame);
 
-  ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
+  ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
               .WillByDefault(Return(true));
   SendStreamDataToPeer(1, "bar", 3, false, NULL);  // Packet 4
   EXPECT_EQ(4u, outgoing_ack()->sent_info.least_unacked);
-  ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
+  ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
               .WillByDefault(Return(false));
   SendAckPacketToPeer();  // Packet 5
   EXPECT_EQ(4u, least_unacked());
 
   // Send two data packets at the end, and ensure if the last one is acked,
   // the least unacked is raised above the ack packets.
-  ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
+  ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
               .WillByDefault(Return(true));
   SendStreamDataToPeer(1, "bar", 6, false, NULL);  // Packet 6
   SendStreamDataToPeer(1, "bar", 9, false, NULL);  // Packet 7
 
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   frame = InitAckFrame(7, 0);
   NackPacket(5, &frame);
   NackPacket(6, &frame);
@@ -2284,7 +2239,7 @@
   // Simulate the retransmission alarm firing.
   clock_.AdvanceTime(DefaultRetransmissionTime());
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 2u, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2u, _, _));
   connection_.GetRetransmissionAlarm()->Fire();
   EXPECT_EQ(2u, writer_->header().packet_sequence_number);
   // We do not raise the high water mark yet.
@@ -2312,8 +2267,8 @@
   {
     InSequence s;
     EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 3, _, _));
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 4, _, _));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 3, _, _));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 4, _, _));
   }
 
   // Simulate the retransmission alarm firing.
@@ -2335,7 +2290,7 @@
 
   // Attempt to send a handshake message and have the socket block.
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillRepeatedly(
+              TimeUntilSend(_, _, _)).WillRepeatedly(
                   testing::Return(QuicTime::Delta::Zero()));
   BlockOnNextWrite();
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, NULL);
@@ -2368,7 +2323,7 @@
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
 
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
 
   QuicTime default_retransmission_time = clock_.ApproximateNow().Add(
       DefaultRetransmissionTime());
@@ -2391,9 +2346,7 @@
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
 
   SendStreamDataToPeer(2, "bar", 0, !kFin, NULL);
-
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(1);
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
 
   connection_.RetransmitUnackedPackets(INITIAL_ENCRYPTION_ONLY);
 }
@@ -2427,13 +2380,13 @@
 
 TEST_P(QuicConnectionTest, TestRetransmitOrder) {
   QuicByteCount first_packet_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).WillOnce(
-      DoAll(SaveArg<2>(&first_packet_size), Return(true)));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).WillOnce(
+      DoAll(SaveArg<3>(&first_packet_size), Return(true)));
 
   connection_.SendStreamDataWithString(3, "first_packet", 0, !kFin, NULL);
   QuicByteCount second_packet_size;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).WillOnce(
-      DoAll(SaveArg<2>(&second_packet_size), Return(true)));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).WillOnce(
+      DoAll(SaveArg<3>(&second_packet_size), Return(true)));
   connection_.SendStreamDataWithString(3, "second_packet", 12, !kFin, NULL);
   EXPECT_NE(first_packet_size, second_packet_size);
   // Advance the clock by huge time to make sure packets will be retransmitted.
@@ -2442,9 +2395,9 @@
   {
     InSequence s;
     EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, _, first_packet_size, _));
+                OnPacketSent(_, _, _, first_packet_size, _));
     EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, _, second_packet_size, _));
+                OnPacketSent(_, _, _, second_packet_size, _));
   }
   connection_.GetRetransmissionAlarm()->Fire();
 
@@ -2454,9 +2407,9 @@
   {
     InSequence s;
     EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, _, first_packet_size, _));
+                OnPacketSent(_, _, _, first_packet_size, _));
     EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, _, second_packet_size, _));
+                OnPacketSent(_, _, _, second_packet_size, _));
   }
   connection_.GetRetransmissionAlarm()->Fire();
 }
@@ -2464,8 +2417,8 @@
 TEST_P(QuicConnectionTest, RetransmissionCountCalculation) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   QuicPacketSequenceNumber original_sequence_number;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
-      .WillOnce(DoAll(SaveArg<1>(&original_sequence_number), Return(true)));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(DoAll(SaveArg<2>(&original_sequence_number), Return(true)));
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
 
   EXPECT_TRUE(QuicConnectionPeer::IsSavedForRetransmission(
@@ -2476,8 +2429,8 @@
   clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
   QuicPacketSequenceNumber rto_sequence_number;
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
-      .WillOnce(DoAll(SaveArg<1>(&rto_sequence_number), Return(true)));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(DoAll(SaveArg<2>(&rto_sequence_number), Return(true)));
   connection_.GetRetransmissionAlarm()->Fire();
   EXPECT_FALSE(QuicConnectionPeer::IsSavedForRetransmission(
       &connection_, original_sequence_number));
@@ -2490,17 +2443,14 @@
   lost_packets.insert(rto_sequence_number);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_)).Times(1);
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(rto_sequence_number, _)).Times(1);
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketAbandoned(rto_sequence_number, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicPacketSequenceNumber nack_sequence_number = 0;
   // Ack packets might generate some other packets, which are not
   // retransmissions. (More ack packets).
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
       .Times(AnyNumber());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
-      .WillOnce(DoAll(SaveArg<1>(&nack_sequence_number), Return(true)));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
+      .WillOnce(DoAll(SaveArg<2>(&nack_sequence_number), Return(true)));
   QuicAckFrame ack = InitAckFrame(rto_sequence_number, 0);
   // Nack the retransmitted packet.
   NackPacket(original_sequence_number, &ack);
@@ -2530,7 +2480,7 @@
 
 TEST_P(QuicConnectionTest, DelayRTOWithAckReceipt) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _))
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
       .Times(2);
   connection_.SendStreamDataWithString(2, "foo", 0, !kFin, NULL);
   connection_.SendStreamDataWithString(3, "bar", 0, !kFin, NULL);
@@ -2542,8 +2492,7 @@
   // Advance the time right before the RTO, then receive an ack for the first
   // packet to delay the RTO.
   clock_.AdvanceTime(DefaultRetransmissionTime());
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicAckFrame ack = InitAckFrame(1, 0);
   ProcessAckPacket(&ack);
   EXPECT_TRUE(retransmission_alarm->IsSet());
@@ -2556,7 +2505,7 @@
   EXPECT_TRUE(retransmission_alarm->IsSet());
   EXPECT_LT(retransmission_alarm->deadline(), clock_.ApproximateNow());
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   // Manually cancel the alarm to simulate a real test.
   connection_.GetRetransmissionAlarm()->Fire();
 
@@ -2641,7 +2590,7 @@
 TEST_P(QuicConnectionTest, InitialTimeout) {
   EXPECT_TRUE(connection_.connected());
   EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
 
   QuicTime default_timeout = clock_.ApproximateNow().Add(
       QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs));
@@ -2681,8 +2630,7 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   QuicAckFrame frame = InitAckFrame(1, 0);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(1, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
   EXPECT_EQ(clock_.ApproximateNow().Add(QuicTime::Delta::FromSeconds(15)),
@@ -2735,7 +2683,7 @@
 
   // This time, we should time out.
   EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_EQ(default_timeout.Add(QuicTime::Delta::FromMilliseconds(5)),
             clock_.ApproximateNow());
@@ -2748,9 +2696,9 @@
   // Test that if we send a packet without delay, it is not queued.
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::Zero()));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   connection_.SendPacket(
       ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -2760,9 +2708,9 @@
   // Test that if we send a packet with a delay, it ends up queued.
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::FromMicroseconds(1)));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
   connection_.SendPacket(
       ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
@@ -2772,9 +2720,9 @@
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
   BlockOnNextWrite();
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::Zero()));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
   connection_.SendPacket(
       ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
@@ -2784,7 +2732,7 @@
   // Test that if we send a packet with a delay, it ends up queued.
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::FromMicroseconds(1)));
   connection_.SendPacket(
        ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
@@ -2793,18 +2741,18 @@
   // Advance the clock to fire the alarm, and configure the scheduler
   // to permit the packet to be sent.
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillRepeatedly(
+              TimeUntilSend(_, _, _)).WillRepeatedly(
                   testing::Return(QuicTime::Delta::Zero()));
   clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(1));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   connection_.GetSendAlarm()->Fire();
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
 }
 
 TEST_P(QuicConnectionTest, SendSchedulerDelayThenRetransmit) {
-  EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _))
+  EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
       .WillRepeatedly(testing::Return(QuicTime::Delta::Zero()));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _));
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
   // Advance the time for retransmission of lost packet.
@@ -2813,7 +2761,7 @@
   // sent packet manager, but not yet serialized.
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::FromMicroseconds(1)));
   connection_.GetRetransmissionAlarm()->Fire();
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -2821,11 +2769,11 @@
   // Advance the clock to fire the alarm, and configure the scheduler
   // to permit the packet to be sent.
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).Times(3).
+              TimeUntilSend(_, _, _)).Times(3).
                   WillRepeatedly(testing::Return(QuicTime::Delta::Zero()));
 
   // Ensure the scheduler is notified this is a retransmit.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(1));
   connection_.GetSendAlarm()->Fire();
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -2834,7 +2782,7 @@
 TEST_P(QuicConnectionTest, SendSchedulerDelayAndQueue) {
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::FromMicroseconds(1)));
   connection_.SendPacket(
       ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
@@ -2851,7 +2799,7 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::FromMicroseconds(10)));
   connection_.SendPacket(
       ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
@@ -2861,10 +2809,10 @@
   // retransmit 3. The far end should stop waiting for it.
   QuicAckFrame frame = InitAckFrame(0, 1);
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillRepeatedly(
+              TimeUntilSend(_, _, _)).WillRepeatedly(
                   testing::Return(QuicTime::Delta::Zero()));
   EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _));
+              OnPacketSent(_, _, _, _, _));
   ProcessAckPacket(&frame);
 
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -2876,7 +2824,7 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::FromMicroseconds(10)));
   connection_.SendPacket(
       ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
@@ -2886,7 +2834,7 @@
   // retransmit 3.  The far end should stop waiting for it.
   QuicAckFrame frame = InitAckFrame(0, 1);
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::FromMicroseconds(1)));
   ProcessAckPacket(&frame);
 
@@ -2898,7 +2846,7 @@
   // new data if the send algorithm said not to.
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::FromMicroseconds(10)));
   connection_.SendPacket(
       ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
@@ -2920,7 +2868,7 @@
 
   // Queue the first packet.
   EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _)).WillOnce(
+              TimeUntilSend(_, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::FromMicroseconds(10)));
   const string payload(payload_length, 'a');
   EXPECT_EQ(0u,
@@ -2938,7 +2886,7 @@
           NOT_IN_FEC_GROUP, &payload_length);
 
   // Queue the first packet.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(7);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(7);
   // The first stream frame will consume 2 fewer bytes than the other six.
   const string payload(payload_length * 7 - 12, 'a');
   EXPECT_EQ(payload.size(),
@@ -3078,10 +3026,7 @@
   lost_packets.insert(1);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(2, _)).Times(1);
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1);
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&ack);
   EXPECT_EQ(1u, writer_->frame_count());
   EXPECT_EQ(1u, writer_->stream_frames().size());
@@ -3093,8 +3038,7 @@
   NackPacket(1, &ack);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(SequenceNumberSet()));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(3, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&ack);
 
   // Check that no packet is sent and the ack alarm isn't set.
@@ -3126,12 +3070,11 @@
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
 
-TEST_P(QuicConnectionTest, NoAckForClose) {
+TEST_P(QuicConnectionTest, NoAckSentForClose) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   ProcessPacket(1);
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(0);
   EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_PEER_GOING_AWAY, true));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
   ProcessClosePacket(2, 0);
 }
 
@@ -3141,7 +3084,7 @@
   connection_.CloseConnection(QUIC_PEER_GOING_AWAY, false);
   EXPECT_FALSE(connection_.connected());
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
   connection_.SendPacket(
       ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
 }
@@ -3530,19 +3473,17 @@
 }
 
 TEST_P(QuicConnectionTest, CheckSendStats) {
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   connection_.SendStreamDataWithString(3, "first", 0, !kFin, NULL);
   size_t first_packet_size = writer_->last_packet_size();
 
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   connection_.SendStreamDataWithString(5, "second", 0, !kFin, NULL);
   size_t second_packet_size = writer_->last_packet_size();
 
   // 2 retransmissions due to rto, 1 due to explicit nack.
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _)).Times(3);
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
 
   // Retransmit due to RTO.
   clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
@@ -3557,9 +3498,7 @@
   lost_packets.insert(3);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(4, _)).Times(1);
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   EXPECT_CALL(visitor_, OnCanWrite()).Times(2);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   ProcessAckPacket(&nack_three);
@@ -3724,8 +3663,7 @@
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, delegate.get());
 
   // Process an ACK from the server which should trigger the callback.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicAckFrame frame = InitAckFrame(1, 0);
   ProcessAckPacket(&frame);
 }
@@ -3737,9 +3675,6 @@
   scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate);
   EXPECT_CALL(*delegate, OnAckNotification(_, _, _, _, _)).Times(0);
 
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(2);
-
   // Send some data, which will register the delegate to be notified. This will
   // not be ACKed and so the delegate should never be called.
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, delegate.get());
@@ -3756,8 +3691,7 @@
   lost_packets.insert(1);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&frame);
 }
 
@@ -3781,19 +3715,15 @@
   lost_packets.insert(2);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(3);
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(2, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(2, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   ProcessAckPacket(&frame);
 
   // Now we get an ACK for packet 5 (retransmitted packet 2), which should
   // trigger the callback.
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillRepeatedly(Return(SequenceNumberSet()));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(5, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicAckFrame second_ack_frame = InitAckFrame(5, 0);
   ProcessAckPacket(&second_ack_frame);
 }
@@ -3819,7 +3749,7 @@
   // Simulate the retransmission alarm firing.
   clock_.AdvanceTime(DefaultRetransmissionTime());
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 2u, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2u, _, _));
   connection_.GetRetransmissionAlarm()->Fire();
   EXPECT_EQ(2u, writer_->header().packet_sequence_number);
   // We do not raise the high water mark yet.
@@ -3827,14 +3757,13 @@
 
   // Ack the original packet.
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
   EXPECT_CALL(*delegate, OnAckNotification(1, _, 1, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicAckFrame ack_frame = InitAckFrame(1, 0);
   ProcessAckPacket(&ack_frame);
 
   // Delegate is not notified again when the retransmit is acked.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(2, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicAckFrame second_ack_frame = InitAckFrame(2, 0);
   ProcessAckPacket(&second_ack_frame);
 }
@@ -3861,15 +3790,10 @@
   SequenceNumberSet lost_packets;
   lost_packets.insert(2);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(1, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(3, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(4, _));
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(lost_packets));
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(2, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(2, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   ProcessAckPacket(&frame);
 
   // Now we get an ACK for packet 2, which was previously nacked.
@@ -3882,18 +3806,14 @@
 
   // Verify that the delegate is not notified again when the
   // retransmit is acked.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(5, _));
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(no_lost_packets));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicAckFrame third_ack_frame = InitAckFrame(5, 0);
   ProcessAckPacket(&third_ack_frame);
 }
 
 TEST_P(QuicConnectionTest, AckNotifierFECTriggerCallback) {
-  if (version() < QUIC_VERSION_15) {
-    return;
-  }
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   // Create a delegate which we expect to be called.
@@ -3907,8 +3827,7 @@
 
   // Process an ACK from the server with a revived packet, which should trigger
   // the callback.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   QuicAckFrame frame = InitAckFrame(2, 0);
   NackPacket(1, &frame);
   frame.received_info.revived_packets.insert(1);
@@ -3918,9 +3837,6 @@
 }
 
 TEST_P(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) {
-  if (version() < QUIC_VERSION_15) {
-    return;
-  }
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(visitor_, OnCanWrite());
 
@@ -3929,8 +3845,7 @@
   EXPECT_CALL(*delegate, OnAckNotification(_, _, _, _, _)).Times(1);
 
   // Expect ACKs for 1 packet.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
 
   // Send one packet, and register to be notified on ACK.
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, delegate.get());
diff --git a/net/quic/quic_data_stream_test.cc b/net/quic/quic_data_stream_test.cc
index ca6d99b..b3c0f4c 100644
--- a/net/quic/quic_data_stream_test.cc
+++ b/net/quic/quic_data_stream_test.cc
@@ -413,6 +413,62 @@
                          stream_->flow_controller()));
 }
 
+TEST_P(QuicDataStreamTest, ConnectionFlowControlWindowUpdate) {
+  // Tests that on receipt of data, the connection updates its receive window
+  // offset appropriately, and sends WINDOW_UPDATE frames when its receive
+  // window drops too low.
+  if (GetParam() < QUIC_VERSION_19) {
+    return;
+  }
+  ValueRestore<bool> old_flag2(&FLAGS_enable_quic_stream_flow_control_2, true);
+  ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control, true);
+
+  Initialize(kShouldProcessData);
+
+  // Set a small flow control limit for streams and connection.
+  const uint64 kWindow = 36;
+  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
+                                                 kWindow);
+  QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
+                                              kWindow);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(stream2_->flow_controller(),
+                                                 kWindow);
+  QuicFlowControllerPeer::SetMaxReceiveWindow(stream2_->flow_controller(),
+                                              kWindow);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(connection_->flow_controller(),
+                                                 kWindow);
+  QuicFlowControllerPeer::SetMaxReceiveWindow(connection_->flow_controller(),
+                                              kWindow);
+
+  // Supply headers to both streams so that they are happy to receive data.
+  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
+  stream_->OnStreamHeaders(headers);
+  stream_->OnStreamHeadersComplete(false, headers.size());
+  stream2_->OnStreamHeaders(headers);
+  stream2_->OnStreamHeadersComplete(false, headers.size());
+
+  // Each stream gets a quarter window of data. This should not trigger a
+  // WINDOW_UPDATE for either stream, nor for the connection.
+  string body;
+  GenerateBody(&body, kWindow / 4);
+  QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(body));
+  stream_->OnStreamFrame(frame1);
+  QuicStreamFrame frame2(kStreamId + 2, false, 0, MakeIOVector(body));
+  stream2_->OnStreamFrame(frame2);
+
+  // Now receive a further single byte on one stream - again this does not
+  // trigger a stream WINDOW_UPDATE, but now the connection flow control window
+  // is over half full and thus a connection WINDOW_UPDATE is sent.
+  EXPECT_CALL(*connection_, SendWindowUpdate(kStreamId, _)).Times(0);
+  EXPECT_CALL(*connection_, SendWindowUpdate(kStreamId + 2, _)).Times(0);
+  EXPECT_CALL(*connection_,
+              SendWindowUpdate(0, QuicFlowControllerPeer::ReceiveWindowOffset(
+                                      connection_->flow_controller()) +
+                                      1 + kWindow / 2));
+  QuicStreamFrame frame3(kStreamId, false, (kWindow / 4), MakeIOVector("a"));
+  stream_->OnStreamFrame(frame3);
+}
+
 TEST_P(QuicDataStreamTest, StreamFlowControlViolation) {
   // Tests that on if the peer sends too much data (i.e. violates the flow
   // control protocol), then we terminate the connection.
@@ -443,6 +499,43 @@
   stream_->OnStreamFrame(frame);
 }
 
+TEST_P(QuicDataStreamTest, ConnectionFlowControlViolation) {
+  // Tests that on if the peer sends too much data (i.e. violates the flow
+  // control protocol), at the connection level (rather than the stream level)
+  // then we terminate the connection.
+  if (GetParam() < QUIC_VERSION_19) {
+    return;
+  }
+  ValueRestore<bool> old_flag2(&FLAGS_enable_quic_stream_flow_control_2, true);
+  ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control, true);
+
+  // Stream should not process data, so that data gets buffered in the
+  // sequencer, triggering flow control limits.
+  Initialize(!kShouldProcessData);
+
+  // Set a small flow control window on streams, and connection.
+  const uint64 kStreamWindow = 50;
+  const uint64 kConnectionWindow = 10;
+  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
+                                                 kStreamWindow);
+  QuicFlowControllerPeer::SetReceiveWindowOffset(connection_->flow_controller(),
+                                                 kConnectionWindow);
+
+  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
+  stream_->OnStreamHeaders(headers);
+  EXPECT_EQ(headers, stream_->data());
+  stream_->OnStreamHeadersComplete(false, headers.size());
+
+  // Send enough data to overflow the connection level flow control window.
+  string body;
+  GenerateBody(&body, kConnectionWindow + 1);
+  EXPECT_LT(body.size(),  kStreamWindow);
+  QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body));
+
+  EXPECT_CALL(*connection_, SendConnectionClose(QUIC_FLOW_CONTROL_ERROR));
+  stream_->OnStreamFrame(frame);
+}
+
 TEST_P(QuicDataStreamTest, StreamFlowControlFinNotBlocked) {
   // An attempt to write a FIN with no data should not be flow control blocked,
   // even if the send window is 0.
diff --git a/net/quic/quic_fec_group.cc b/net/quic/quic_fec_group.cc
index aac272f..344f216 100644
--- a/net/quic/quic_fec_group.cc
+++ b/net/quic/quic_fec_group.cc
@@ -22,12 +22,14 @@
 QuicFecGroup::QuicFecGroup()
     : min_protected_packet_(kNoSequenceNumber),
       max_protected_packet_(kNoSequenceNumber),
-      payload_parity_len_(0) {
+      payload_parity_len_(0),
+      effective_encryption_level_(NUM_ENCRYPTION_LEVELS) {
 }
 
 QuicFecGroup::~QuicFecGroup() {}
 
-bool QuicFecGroup::Update(const QuicPacketHeader& header,
+bool QuicFecGroup::Update(EncryptionLevel encryption_level,
+                          const QuicPacketHeader& header,
                           StringPiece decrypted_payload) {
   if (received_packets_.count(header.packet_sequence_number) != 0) {
     return false;
@@ -44,10 +46,14 @@
     return false;
   }
   received_packets_.insert(header.packet_sequence_number);
+  if (encryption_level < effective_encryption_level_) {
+    effective_encryption_level_ = encryption_level;
+  }
   return true;
 }
 
 bool QuicFecGroup::UpdateFec(
+    EncryptionLevel encryption_level,
     QuicPacketSequenceNumber fec_packet_sequence_number,
     const QuicFecData& fec) {
   if (min_protected_packet_ != kNoSequenceNumber) {
@@ -66,6 +72,9 @@
   }
   min_protected_packet_ = fec.fec_group;
   max_protected_packet_ = fec_packet_sequence_number - 1;
+  if (encryption_level < effective_encryption_level_) {
+    effective_encryption_level_ = encryption_level;
+  }
   return true;
 }
 
diff --git a/net/quic/quic_fec_group.h b/net/quic/quic_fec_group.h
index f296b9c..718d09f 100644
--- a/net/quic/quic_fec_group.h
+++ b/net/quic/quic_fec_group.h
@@ -9,8 +9,6 @@
 #ifndef NET_QUIC_QUIC_FEC_GROUP_H_
 #define NET_QUIC_QUIC_FEC_GROUP_H_
 
-#include <set>
-
 #include "base/strings/string_piece.h"
 #include "net/quic/quic_protocol.h"
 
@@ -21,16 +19,19 @@
   QuicFecGroup();
   ~QuicFecGroup();
 
-  // Updates the FEC group based on the delivery of a data packet.
-  // Returns false if this packet has already been seen, true otherwise.
-  bool Update(const QuicPacketHeader& header,
+  // Updates the FEC group based on the delivery of a data packet decrypted at
+  // |encryption_level|. Returns false if this packet has already been seen,
+  // true otherwise.
+  bool Update(EncryptionLevel encryption_level,
+              const QuicPacketHeader& header,
               base::StringPiece decrypted_payload);
 
-  // Updates the FEC group based on the delivery of an FEC packet.
-  // Returns false if this packet has already been seen or if it does
-  // not claim to protect all the packets previously seen in this group.
-  //   |fec_packet_entropy|: XOR of entropy of all packets in the fec group.
-  bool UpdateFec(QuicPacketSequenceNumber fec_packet_sequence_number,
+  // Updates the FEC group based on the delivery of an FEC packet decrypted at
+  // |encryption_level|. Returns false if this packet has already been seen or
+  // if it does not claim to protect all the packets previously seen in this
+  // group.
+  bool UpdateFec(EncryptionLevel encryption_level,
+                 QuicPacketSequenceNumber fec_packet_sequence_number,
                  const QuicFecData& fec);
 
   // Returns true if a packet can be revived from this FEC group.
@@ -64,6 +65,11 @@
     return received_packets_.size();
   }
 
+  // Returns the effective encryption level of the FEC group.
+  EncryptionLevel effective_encryption_level() const {
+    return effective_encryption_level_;
+  }
+
  private:
   bool UpdateParity(base::StringPiece payload);
   // Returns the number of missing packets, or size_t max if the number
@@ -83,6 +89,9 @@
   // The cumulative parity calculation of all received packets.
   char payload_parity_[kMaxPacketSize];
   size_t payload_parity_len_;
+  // The effective encryption level, which is the lowest encryption level of
+  // the data and FEC in the group.
+  EncryptionLevel effective_encryption_level_;
 
   DISALLOW_COPY_AND_ASSIGN(QuicFecGroup);
 };
diff --git a/net/quic/quic_fec_group_test.cc b/net/quic/quic_fec_group_test.cc
index da8d8a0..b9420dd 100644
--- a/net/quic/quic_fec_group_test.cc
+++ b/net/quic/quic_fec_group_test.cc
@@ -69,17 +69,19 @@
           QuicFecData fec;
           fec.fec_group = 0;
           fec.redundancy = StringPiece(redundancy.get(), strlen(kData[0]));
-          ASSERT_TRUE(group.UpdateFec(num_packets, fec));
+          ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, num_packets,
+                                      fec));
         } else {
           QuicPacketHeader header;
           header.packet_sequence_number = packet;
           header.entropy_flag = kEntropyFlag[packet];
-          ASSERT_TRUE(group.Update(header, kData[packet]));
+          ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header,
+                                   kData[packet]));
         }
         ASSERT_TRUE(group.CanRevive() == (packet == num_packets - 1));
       }
     } else {
-    // Update the FEC state for each non-lost packet.
+      // Update the FEC state for each non-lost packet.
       for (size_t packet = 0; packet < num_packets; packet++) {
         if (packet == lost_packet) {
           continue;
@@ -88,7 +90,8 @@
         QuicPacketHeader header;
         header.packet_sequence_number = packet;
         header.entropy_flag = kEntropyFlag[packet];
-        ASSERT_TRUE(group.Update(header, kData[packet]));
+        ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header,
+                                 kData[packet]));
         ASSERT_FALSE(group.CanRevive());
       }
 
@@ -98,7 +101,8 @@
       fec.fec_group = 0;
       fec.redundancy = StringPiece(redundancy.get(), strlen(kData[0]));
 
-      ASSERT_TRUE(group.UpdateFec(num_packets, fec));
+      ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, num_packets,
+                                  fec));
     }
     QuicPacketHeader header;
     char recovered[kMaxPacketSize];
@@ -149,14 +153,14 @@
 
   QuicPacketHeader header;
   header.packet_sequence_number = 3;
-  group.Update(header, data1);
+  group.Update(ENCRYPTION_FORWARD_SECURE, header, data1);
 
   QuicFecData fec;
   fec.fec_group = 1;
   fec.redundancy = redundancy;
 
   header.packet_sequence_number = 2;
-  ASSERT_FALSE(group.UpdateFec(2, fec));
+  ASSERT_FALSE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 2, fec));
 }
 
 TEST_F(QuicFecGroupTest, ProtectsPacketsBefore) {
@@ -164,7 +168,7 @@
   header.packet_sequence_number = 3;
 
   QuicFecGroup group;
-  ASSERT_TRUE(group.Update(header, kData[0]));
+  ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kData[0]));
 
   EXPECT_FALSE(group.ProtectsPacketsBefore(1));
   EXPECT_FALSE(group.ProtectsPacketsBefore(2));
@@ -179,13 +183,13 @@
   header.packet_sequence_number = 3;
 
   QuicFecGroup group;
-  ASSERT_TRUE(group.Update(header, kData[0]));
+  ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kData[0]));
 
   header.packet_sequence_number = 7;
-  ASSERT_TRUE(group.Update(header, kData[0]));
+  ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kData[0]));
 
   header.packet_sequence_number = 5;
-  ASSERT_TRUE(group.Update(header, kData[0]));
+  ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kData[0]));
 
   EXPECT_FALSE(group.ProtectsPacketsBefore(1));
   EXPECT_FALSE(group.ProtectsPacketsBefore(2));
@@ -205,7 +209,7 @@
   fec.redundancy = kData[0];
 
   QuicFecGroup group;
-  ASSERT_TRUE(group.UpdateFec(3, fec));
+  ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 3, fec));
 
   EXPECT_FALSE(group.ProtectsPacketsBefore(1));
   EXPECT_FALSE(group.ProtectsPacketsBefore(2));
@@ -215,4 +219,24 @@
   EXPECT_TRUE(group.ProtectsPacketsBefore(50));
 }
 
+TEST_F(QuicFecGroupTest, EffectiveEncryptionLevel) {
+  QuicFecGroup group;
+  EXPECT_EQ(NUM_ENCRYPTION_LEVELS, group.effective_encryption_level());
+
+  QuicPacketHeader header;
+  header.packet_sequence_number = 5;
+  ASSERT_TRUE(group.Update(ENCRYPTION_INITIAL, header, kData[0]));
+  EXPECT_EQ(ENCRYPTION_INITIAL, group.effective_encryption_level());
+
+  QuicFecData fec;
+  fec.fec_group = 0;
+  fec.redundancy = kData[0];
+  ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 7, fec));
+  EXPECT_EQ(ENCRYPTION_INITIAL, group.effective_encryption_level());
+
+  header.packet_sequence_number = 3;
+  ASSERT_TRUE(group.Update(ENCRYPTION_NONE, header, kData[0]));
+  EXPECT_EQ(ENCRYPTION_NONE, group.effective_encryption_level());
+}
+
 }  // namespace net
diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc
index 2d73d1d..c42afb6 100644
--- a/net/quic/quic_flags.cc
+++ b/net/quic/quic_flags.cc
@@ -21,8 +21,17 @@
 
 // Do not remove this flag until b/11792453 is marked as Fixed.
 // If true, turns on stream flow control in QUIC.
+// If this is disabled, all in flight QUIC connections talking QUIC_VERSION_17
+// or higher will timeout. New connections will be fine.
+// If disabling this flag, also disable enable_quic_connection_flow_control.
 bool FLAGS_enable_quic_stream_flow_control_2 = true;
 
+// Do not remove this flag until b/11792453 is marked as Fixed.
+// If true, turns on connection level flow control in QUIC.
+// If this is disabled, all in flight QUIC connections talking QUIC_VERSION_19
+// or higher will timeout. New connections will be fine.
+bool FLAGS_enable_quic_connection_flow_control = true;
+
 bool FLAGS_quic_allow_oversized_packets_for_test = false;
 // When true, the use time based loss detection instead of nack.
 bool FLAGS_quic_use_time_loss_detection = false;
diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h
index 2bf963a..31585d3 100644
--- a/net/quic/quic_flags.h
+++ b/net/quic/quic_flags.h
@@ -10,6 +10,7 @@
 NET_EXPORT_PRIVATE extern bool FLAGS_track_retransmission_history;
 NET_EXPORT_PRIVATE extern bool FLAGS_enable_quic_pacing;
 NET_EXPORT_PRIVATE extern bool FLAGS_enable_quic_stream_flow_control_2;
+NET_EXPORT_PRIVATE extern bool FLAGS_enable_quic_connection_flow_control;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_allow_oversized_packets_for_test;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_time_loss_detection;
 
diff --git a/net/quic/quic_flow_controller.cc b/net/quic/quic_flow_controller.cc
index d169648..412f250 100644
--- a/net/quic/quic_flow_controller.cc
+++ b/net/quic/quic_flow_controller.cc
@@ -82,9 +82,9 @@
   }
 
   if (bytes_sent_ + bytes_sent > send_window_offset_) {
-    LOG(DFATAL) << "Trying to send an extra " << bytes_sent
-                << " bytes, when bytes_sent = " << bytes_sent_
-                << ", and send_window = " << send_window_offset_;
+    LOG(DFATAL) << ENDPOINT << "Stream " << id_ << " Trying to send an extra "
+                << bytes_sent << " bytes, when bytes_sent = " << bytes_sent_
+                << ", and send_window_offset_ = " << send_window_offset_;
     bytes_sent_ = send_window_offset_;
     return;
   }
@@ -180,7 +180,14 @@
 }
 
 bool QuicFlowController::IsEnabled() const {
-  return FLAGS_enable_quic_stream_flow_control_2 && is_enabled_;
+  bool connection_flow_control_enabled =
+      (id_ == kConnectionLevelId &&
+       FLAGS_enable_quic_connection_flow_control);
+  bool stream_flow_control_enabled =
+      (id_ != kConnectionLevelId &&
+       FLAGS_enable_quic_stream_flow_control_2);
+  return (connection_flow_control_enabled || stream_flow_control_enabled) &&
+         is_enabled_;
 }
 
 bool QuicFlowController::IsBlocked() const {
diff --git a/net/quic/quic_flow_controller.h b/net/quic/quic_flow_controller.h
index 99a9d6f..3125b81 100644
--- a/net/quic/quic_flow_controller.h
+++ b/net/quic/quic_flow_controller.h
@@ -17,6 +17,8 @@
 
 class QuicConnection;
 
+const QuicStreamId kConnectionLevelId = 0;
+
 // QuicFlowController allows a QUIC stream or connection to perform flow
 // control. The stream/connection owns a QuicFlowController which keeps track of
 // bytes sent/received, can tell the owner if it is flow control blocked, and
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc
index d17b569..e445008 100644
--- a/net/quic/quic_framer_test.cc
+++ b/net/quic/quic_framer_test.cc
@@ -241,13 +241,13 @@
     return accept_public_header_;
   }
 
-  virtual void OnDecryptedPacket(EncryptionLevel level) OVERRIDE {}
-
   virtual bool OnUnauthenticatedHeader(
       const QuicPacketHeader& header) OVERRIDE {
     return true;
   }
 
+  virtual void OnDecryptedPacket(EncryptionLevel level) OVERRIDE {}
+
   virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE {
     ++packet_count_;
     header_.reset(new QuicPacketHeader(header));
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index f54d3d1..557e976 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -184,12 +184,12 @@
     EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _)).
         Times(AnyNumber());
     EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, _, _, _)).WillRepeatedly(Return(true));
+                OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
     EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
         Return(QuicTime::Delta::Zero()));
     EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
         Return(kMaxPacketSize));
-    EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _)).
+    EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).
         WillRepeatedly(Return(QuicTime::Delta::Zero()));
     EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
         Return(QuicBandwidth::Zero()));
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index 8a22aa5..5aa0368 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -281,6 +281,15 @@
     EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
   }
 
+  void ExpectQuicAlternateProtocolMapping() {
+    ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol(
+        HostPortPair::FromURL(request_.url)));
+    const PortAlternateProtocolPair alternate =
+        session_->http_server_properties()->GetAlternateProtocol(
+            HostPortPair::FromURL(request_.url));
+    EXPECT_EQ(QUIC, alternate.protocol);
+  }
+
   void AddHangingNonAlternateProtocolSocketData() {
     MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
     hanging_data_.set_connect_data(hanging_connect);
@@ -826,6 +835,33 @@
   EXPECT_TRUE(quic_data.at_write_eof());
 }
 
+TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolOnConnectFailure) {
+  HttpStreamFactory::EnableNpnSpdy3();  // Enables QUIC too.
+
+  // Alternate-protocol job will fail before creating a QUIC session.
+  StaticSocketDataProvider quic_data(NULL, 0, NULL, 0);
+  quic_data.set_connect_data(MockConnect(SYNCHRONOUS,
+                                         ERR_INTERNET_DISCONNECTED));
+  socket_factory_.AddSocketDataProvider(&quic_data);
+
+  // Main job which will succeed even though the alternate job fails.
+  MockRead http_reads[] = {
+    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
+    MockRead("hello from http"),
+    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+    MockRead(ASYNC, OK)
+  };
+
+  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
+                                     NULL, 0);
+  socket_factory_.AddSocketDataProvider(&http_data);
+
+  CreateSession();
+  AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
+  SendRequestAndExpectHttpResponse("hello from http");
+  ExpectQuicAlternateProtocolMapping();
+}
+
 TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
   HttpStreamFactory::EnableNpnSpdy3();  // Enables QUIC too.
 
diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc
index bb243f9..4c57b4b 100644
--- a/net/quic/quic_packet_creator.cc
+++ b/net/quic/quic_packet_creator.cc
@@ -60,6 +60,7 @@
                                      QuicRandom* random_generator,
                                      bool is_server)
     : connection_id_(connection_id),
+      encryption_level_(ENCRYPTION_NONE),
       framer_(framer),
       random_bool_source_(new QuicRandomBoolSource(random_generator)),
       sequence_number_(0),
@@ -78,7 +79,7 @@
     const QuicPacketHeader& header, StringPiece payload) {
   if (fec_group_.get()) {
     DCHECK_NE(0u, header.fec_group);
-    fec_group_->Update(header, payload);
+    fec_group_->Update(encryption_level_, header, payload);
   }
 }
 
diff --git a/net/quic/quic_packet_creator.h b/net/quic/quic_packet_creator.h
index 83494da..95c0847 100644
--- a/net/quic/quic_packet_creator.h
+++ b/net/quic/quic_packet_creator.h
@@ -176,6 +176,11 @@
   QuicEncryptedPacket* SerializeVersionNegotiationPacket(
       const QuicVersionVector& supported_versions);
 
+  // Sets the encryption level that will be applied to new packets.
+  void set_encryption_level(EncryptionLevel level) {
+    encryption_level_ = level;
+  }
+
   // Sequence number of the last created packet, or 0 if no packets have been
   // created.
   QuicPacketSequenceNumber sequence_number() const {
@@ -214,6 +219,7 @@
 
   Options options_;
   QuicConnectionId connection_id_;
+  EncryptionLevel encryption_level_;
   QuicFramer* framer_;
   scoped_ptr<QuicRandomBoolSource> random_bool_source_;
   QuicPacketSequenceNumber sequence_number_;
diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc
index facb15f..32c5c31 100644
--- a/net/quic/quic_protocol.cc
+++ b/net/quic/quic_protocol.cc
@@ -162,6 +162,8 @@
       return MakeQuicTag('Q', '0', '1', '7');
     case QUIC_VERSION_18:
       return MakeQuicTag('Q', '0', '1', '8');
+    case QUIC_VERSION_19:
+      return MakeQuicTag('Q', '0', '1', '9');
     default:
       // This shold be an ERROR because we should never attempt to convert an
       // invalid QuicVersion to be written to the wire.
@@ -192,6 +194,7 @@
     RETURN_STRING_LITERAL(QUIC_VERSION_16);
     RETURN_STRING_LITERAL(QUIC_VERSION_17);
     RETURN_STRING_LITERAL(QUIC_VERSION_18);
+    RETURN_STRING_LITERAL(QUIC_VERSION_19);
     default:
       return "QUIC_VERSION_UNSUPPORTED";
   }
@@ -733,6 +736,44 @@
   return os;
 }
 
+TransmissionInfo::TransmissionInfo()
+    : retransmittable_frames(NULL),
+      sequence_number_length(PACKET_1BYTE_SEQUENCE_NUMBER),
+      sent_time(QuicTime::Zero()),
+      bytes_sent(0),
+      nack_count(0),
+      all_transmissions(NULL),
+      pending(false) { }
+
+TransmissionInfo::TransmissionInfo(
+    RetransmittableFrames* retransmittable_frames,
+    QuicPacketSequenceNumber sequence_number,
+    QuicSequenceNumberLength sequence_number_length)
+    : retransmittable_frames(retransmittable_frames),
+      sequence_number_length(sequence_number_length),
+      sent_time(QuicTime::Zero()),
+      bytes_sent(0),
+      nack_count(0),
+      all_transmissions(new SequenceNumberSet),
+      pending(false) {
+  all_transmissions->insert(sequence_number);
+}
+
+TransmissionInfo::TransmissionInfo(
+    RetransmittableFrames* retransmittable_frames,
+    QuicPacketSequenceNumber sequence_number,
+    QuicSequenceNumberLength sequence_number_length,
+    SequenceNumberSet* all_transmissions)
+    : retransmittable_frames(retransmittable_frames),
+      sequence_number_length(sequence_number_length),
+      sent_time(QuicTime::Zero()),
+      bytes_sent(0),
+      nack_count(0),
+      all_transmissions(all_transmissions),
+      pending(false) {
+  all_transmissions->insert(sequence_number);
+}
+
 QuicConsumedData::QuicConsumedData(size_t bytes_consumed,
                                    bool fin_consumed)
       : bytes_consumed(bytes_consumed),
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index f6dc181..1a14201 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -264,7 +264,8 @@
   QUIC_VERSION_15 = 15,
   QUIC_VERSION_16 = 16,
   QUIC_VERSION_17 = 17,
-  QUIC_VERSION_18 = 18,  // Current version.
+  QUIC_VERSION_18 = 18,
+  QUIC_VERSION_19 = 19,  // Current version.
 };
 
 // This vector contains QUIC versions which we currently support.
@@ -1005,6 +1006,37 @@
   std::set<QuicAckNotifier*> notifiers;
 };
 
+struct NET_EXPORT_PRIVATE TransmissionInfo {
+  // Used by STL when assigning into a map.
+  TransmissionInfo();
+
+  // Constructs a Transmission with a new all_tranmissions set
+  // containing |sequence_number|.
+  TransmissionInfo(RetransmittableFrames* retransmittable_frames,
+                   QuicPacketSequenceNumber sequence_number,
+                   QuicSequenceNumberLength sequence_number_length);
+
+  // Constructs a Transmission with the specified |all_tranmissions| set
+  // and inserts |sequence_number| into it.
+  TransmissionInfo(RetransmittableFrames* retransmittable_frames,
+                   QuicPacketSequenceNumber sequence_number,
+                   QuicSequenceNumberLength sequence_number_length,
+                   SequenceNumberSet* all_transmissions);
+
+  RetransmittableFrames* retransmittable_frames;
+  QuicSequenceNumberLength sequence_number_length;
+  // Zero when the packet is serialized, non-zero once it's sent.
+  QuicTime sent_time;
+  // Zero when the packet is serialized, non-zero once it's sent.
+  QuicByteCount bytes_sent;
+  size_t nack_count;
+  // Stores the sequence numbers of all transmissions of this packet.
+  // Can never be null.
+  SequenceNumberSet* all_transmissions;
+  // Pending packets have not been abandoned or lost.
+  bool pending;
+};
+
 // A struct for functions which consume data payloads and fins.
 struct NET_EXPORT_PRIVATE QuicConsumedData {
   QuicConsumedData(size_t bytes_consumed, bool fin_consumed);
diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc
index 6e103d3..0085f90 100644
--- a/net/quic/quic_sent_packet_manager.cc
+++ b/net/quic/quic_sent_packet_manager.cc
@@ -38,8 +38,7 @@
 static const size_t kDefaultMaxTailLossProbes = 2;
 static const int64 kMinTailLossProbeTimeoutMs = 10;
 
-bool HasCryptoHandshake(
-    const QuicUnackedPacketMap::TransmissionInfo& transmission_info) {
+bool HasCryptoHandshake(const TransmissionInfo& transmission_info) {
   if (transmission_info.retransmittable_frames == NULL) {
     return false;
   }
@@ -120,13 +119,15 @@
 void QuicSentPacketManager::OnIncomingAck(
     const ReceivedPacketInfo& received_info,
     QuicTime ack_receive_time) {
+  QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight();
+
   // We rely on delta_time_largest_observed to compute an RTT estimate, so
   // we only update rtt when the largest observed gets acked.
   largest_observed_ = received_info.largest_observed;
-  bool largest_observed_acked = unacked_packets_.IsUnacked(largest_observed_);
-  MaybeUpdateRTT(received_info, ack_receive_time);
+  bool largest_observed_acked = MaybeUpdateRTT(received_info, ack_receive_time);
   HandleAckForSentPackets(received_info);
-  MaybeRetransmitOnAckFrame(received_info, ack_receive_time);
+  InvokeLossDetection(ack_receive_time);
+  MaybeInvokeCongestionEvent(largest_observed_acked, bytes_in_flight);
 
   // Anytime we are making forward progress and have a new RTT estimate, reset
   // the backoff counters.
@@ -138,10 +139,20 @@
   }
 }
 
+void QuicSentPacketManager::MaybeInvokeCongestionEvent(
+    bool rtt_updated, QuicByteCount bytes_in_flight) {
+  if (rtt_updated || !packets_acked_.empty() ||
+      !packets_lost_.empty()) {
+    send_algorithm_->OnCongestionEvent(
+        rtt_updated, bytes_in_flight, packets_acked_, packets_lost_);
+    packets_acked_.clear();
+    packets_lost_.clear();
+  }
+}
+
 void QuicSentPacketManager::DiscardUnackedPacket(
     QuicPacketSequenceNumber sequence_number) {
-  MarkPacketHandled(sequence_number, QuicTime::Delta::Zero(),
-                    NOT_RECEIVED_BY_PEER);
+  MarkPacketHandled(sequence_number, QuicTime::Delta::Zero());
 }
 
 void QuicSentPacketManager::HandleAckForSentPackets(
@@ -162,20 +173,32 @@
       // Remove any packets not being tracked by the send algorithm, allowing
       // the high water mark to be raised if necessary.
       if (QuicUnackedPacketMap::IsSentAndNotPending(it->second)) {
-        it = MarkPacketHandled(sequence_number, delta_largest_observed,
-                               NOT_RECEIVED_BY_PEER);
+        it = MarkPacketHandled(sequence_number, delta_largest_observed);
       } else {
+        // Consider it multiple nacks when there is a gap between the missing
+        // packet and the largest observed, since the purpose of a nack
+        // threshold is to tolerate re-ordering.  This handles both StretchAcks
+        // and Forward Acks.
+        // The nack count only increases when the largest observed increases.
+        size_t min_nacks = received_info.largest_observed - sequence_number;
+        // Truncated acks can nack the largest observed, so use a min of 1.
+        if (min_nacks == 0) {
+          min_nacks = 1;
+        }
+        unacked_packets_.NackPacket(sequence_number, min_nacks);
         ++it;
       }
       continue;
     }
 
     // Packet was acked, so remove it from our unacked packet list.
-    DVLOG(1) << ENDPOINT <<"Got an ack for packet " << sequence_number;
+    DVLOG(1) << ENDPOINT << "Got an ack for packet " << sequence_number;
     // If data is associated with the most recent transmission of this
     // packet, then inform the caller.
-    it = MarkPacketHandled(sequence_number, delta_largest_observed,
-                           RECEIVED_BY_PEER);
+    if (it->second.pending) {
+      packets_acked_[sequence_number] = it->second;
+    }
+    it = MarkPacketHandled(sequence_number, delta_largest_observed);
   }
 
   // Discard any retransmittable frames associated with revived packets.
@@ -209,8 +232,8 @@
     // pending retransmissions which would be cleared.
     if (frames == NULL && unacked_it->second.all_transmissions->size() == 1 &&
         retransmission_type == ALL_PACKETS) {
-      unacked_it = MarkPacketHandled(unacked_it->first, QuicTime::Delta::Zero(),
-                                     NOT_RECEIVED_BY_PEER);
+      unacked_it = MarkPacketHandled(unacked_it->first,
+                                     QuicTime::Delta::Zero());
       continue;
     }
     // If it had no other transmissions, we handle it above.  If it has
@@ -221,26 +244,26 @@
     // numbers with no connection to the previous ones.
     if (frames != NULL && (retransmission_type == ALL_PACKETS ||
                            frames->encryption_level() == ENCRYPTION_INITIAL)) {
-      OnPacketAbandoned(unacked_it->first);
+      unacked_packets_.SetNotPending(unacked_it->first);
       MarkForRetransmission(unacked_it->first, ALL_UNACKED_RETRANSMISSION);
     }
     ++unacked_it;
   }
 }
 
-void QuicSentPacketManager::NeuterUnencryptedPackets() {
+void QuicSentPacketManager::DiscardUnencryptedPackets() {
   QuicUnackedPacketMap::const_iterator unacked_it = unacked_packets_.begin();
   while (unacked_it != unacked_packets_.end()) {
     const RetransmittableFrames* frames =
         unacked_it->second.retransmittable_frames;
     if (frames != NULL && frames->encryption_level() == ENCRYPTION_NONE) {
-      // Since once you're forward secure, no unencrypted packets will be sent,
-      // crypto or otherwise. Unencrypted packets are neutered and abandoned, to
-      // ensure they are not retransmitted or considered lost from a congestion
-      // control perspective.
+      // Once you're forward secure, no unencrypted packets will be sent.
+      // Additionally, it's likely the peer will be forward secure, and no acks
+      // for these packets will be received, so mark the packet as handled.
       pending_retransmissions_.erase(unacked_it->first);
-      unacked_packets_.NeuterPacket(unacked_it->first);
-      OnPacketAbandoned(unacked_it->first);
+      unacked_it = MarkPacketHandled(unacked_it->first,
+                                     QuicTime::Delta::Zero());
+      continue;
     }
     ++unacked_it;
   }
@@ -249,7 +272,7 @@
 void QuicSentPacketManager::MarkForRetransmission(
     QuicPacketSequenceNumber sequence_number,
     TransmissionType transmission_type) {
-  const QuicUnackedPacketMap::TransmissionInfo& transmission_info =
+  const TransmissionInfo& transmission_info =
       unacked_packets_.GetTransmissionInfo(sequence_number);
   LOG_IF(DFATAL, transmission_info.retransmittable_frames == NULL);
   // TODO(ianswett): Currently the RTO can fire while there are pending NACK
@@ -276,8 +299,7 @@
     PendingRetransmissionMap::const_iterator it =
         pending_retransmissions_.begin();
     do {
-      if (HasCryptoHandshake(
-              unacked_packets_.GetTransmissionInfo(it->first))) {
+      if (HasCryptoHandshake(unacked_packets_.GetTransmissionInfo(it->first))) {
         sequence_number = it->first;
         transmission_type = it->second;
         break;
@@ -286,7 +308,7 @@
     } while (it != pending_retransmissions_.end());
   }
   DCHECK(unacked_packets_.IsUnacked(sequence_number));
-  const QuicUnackedPacketMap::TransmissionInfo& transmission_info =
+  const TransmissionInfo& transmission_info =
       unacked_packets_.GetTransmissionInfo(sequence_number);
   DCHECK(transmission_info.retransmittable_frames);
 
@@ -306,7 +328,7 @@
   // retransmit it, do not retransmit it anymore.
   pending_retransmissions_.erase(sequence_number);
 
-  const QuicUnackedPacketMap::TransmissionInfo& transmission_info =
+  const TransmissionInfo& transmission_info =
       unacked_packets_.GetTransmissionInfo(sequence_number);
   // The AckNotifierManager needs to be notified for revived packets,
   // since it indicates the packet arrived from the appliction's perspective.
@@ -315,32 +337,20 @@
         sequence_number, delta_largest_observed);
   }
 
-  if (!transmission_info.pending) {
-    unacked_packets_.RemovePacket(sequence_number);
-  } else {
-    unacked_packets_.NeuterPacket(sequence_number);
-  }
+  unacked_packets_.NeuterIfPendingOrRemovePacket(sequence_number);
 }
 
 QuicUnackedPacketMap::const_iterator QuicSentPacketManager::MarkPacketHandled(
     QuicPacketSequenceNumber sequence_number,
-    QuicTime::Delta delta_largest_observed, ReceivedByPeer received_by_peer) {
+    QuicTime::Delta delta_largest_observed) {
   if (!unacked_packets_.IsUnacked(sequence_number)) {
     LOG(DFATAL) << "Packet is not unacked: " << sequence_number;
     return unacked_packets_.end();
   }
-  const QuicUnackedPacketMap::TransmissionInfo& transmission_info =
+  const TransmissionInfo& transmission_info =
       unacked_packets_.GetTransmissionInfo(sequence_number);
   // If this packet is pending, remove it and inform the send algorithm.
   if (transmission_info.pending) {
-    if (received_by_peer == RECEIVED_BY_PEER) {
-      send_algorithm_->OnPacketAcked(sequence_number,
-                                     transmission_info.bytes_sent);
-    } else {
-      // It's been abandoned.
-      send_algorithm_->OnPacketAbandoned(sequence_number,
-                                         transmission_info.bytes_sent);
-    }
     unacked_packets_.SetNotPending(sequence_number);
   }
 
@@ -362,24 +372,15 @@
       unacked_packets_.GetTransmissionInfo(newest_transmission));
   while (all_transmissions_it != all_transmissions.rend()) {
     QuicPacketSequenceNumber previous_transmission = *all_transmissions_it;
-    const QuicUnackedPacketMap::TransmissionInfo& transmission_info =
-        unacked_packets_.GetTransmissionInfo(previous_transmission);
     // If this packet was marked for retransmission, don't bother retransmitting
     // it anymore.
     pending_retransmissions_.erase(previous_transmission);
     if (has_crypto_handshake) {
       // If it's a crypto handshake packet, discard it and all retransmissions,
       // since they won't be acked now that one has been processed.
-      if (transmission_info.pending) {
-        OnPacketAbandoned(previous_transmission);
-      }
       unacked_packets_.SetNotPending(previous_transmission);
     }
-    if (!transmission_info.pending) {
-      unacked_packets_.RemovePacket(previous_transmission);
-    } else {
-      unacked_packets_.NeuterPacket(previous_transmission);
-    }
+    unacked_packets_.NeuterIfPendingOrRemovePacket(previous_transmission);
     ++all_transmissions_it;
   }
 
@@ -420,7 +421,10 @@
   }
 
   // Only track packets as pending that the send algorithm wants us to track.
-  if (!send_algorithm_->OnPacketSent(sent_time, sequence_number, bytes,
+  if (!send_algorithm_->OnPacketSent(sent_time,
+                                     unacked_packets_.bytes_in_flight(),
+                                     sequence_number,
+                                     bytes,
                                      has_retransmittable_data)) {
     unacked_packets_.SetSent(sequence_number, sent_time, bytes, false);
     // Do not reset the retransmission timer, since the packet isn't tracked.
@@ -448,10 +452,13 @@
       ++stats_->crypto_retransmit_count;
       RetransmitCryptoPackets();
       return;
-    case LOSS_MODE:
+    case LOSS_MODE: {
       ++stats_->loss_timeout_count;
+      QuicByteCount bytes_in_flight = unacked_packets_.bytes_in_flight();
       InvokeLossDetection(clock_->Now());
+      MaybeInvokeCongestionEvent(false, bytes_in_flight);
       return;
+    }
     case TLP_MODE:
       // If no tail loss probe can be sent, because there are no retransmittable
       // packets, execute a conventional RTO to abandon old packets.
@@ -484,7 +491,7 @@
     packet_retransmitted = true;
     MarkForRetransmission(sequence_number, HANDSHAKE_RETRANSMISSION);
     // Abandon all the crypto retransmissions now so they're not lost later.
-    OnPacketAbandoned(sequence_number);
+    unacked_packets_.SetNotPending(sequence_number);
   }
   DCHECK(packet_retransmitted) << "No crypto packets found to retransmit.";
 }
@@ -552,18 +559,6 @@
   return RTO_MODE;
 }
 
-void QuicSentPacketManager::OnPacketAbandoned(
-    QuicPacketSequenceNumber sequence_number) {
-  const QuicUnackedPacketMap::TransmissionInfo& transmission_info =
-      unacked_packets_.GetTransmissionInfo(sequence_number);
-  if (transmission_info.pending) {
-    LOG_IF(DFATAL, transmission_info.bytes_sent == 0);
-    send_algorithm_->OnPacketAbandoned(sequence_number,
-                                       transmission_info.bytes_sent);
-    unacked_packets_.SetNotPending(sequence_number);
-  }
-}
-
 void QuicSentPacketManager::OnIncomingQuicCongestionFeedbackFrame(
     const QuicCongestionFeedbackFrame& frame,
     const QuicTime& feedback_receive_time) {
@@ -571,36 +566,6 @@
       frame, feedback_receive_time);
 }
 
-void QuicSentPacketManager::MaybeRetransmitOnAckFrame(
-    const ReceivedPacketInfo& received_info,
-    const QuicTime& ack_receive_time) {
-  // Go through all pending packets up to the largest observed and count nacks.
-  for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
-       it != unacked_packets_.end() &&
-           it->first <= received_info.largest_observed; ++it) {
-    if (!it->second.pending) {
-      continue;
-    }
-    QuicPacketSequenceNumber sequence_number = it->first;
-    DVLOG(1) << "still missing packet " << sequence_number;
-    // Acks must be handled previously, so ensure it's missing and not acked.
-    DCHECK(IsAwaitingPacket(received_info, sequence_number));
-
-    // Consider it multiple nacks when there is a gap between the missing packet
-    // and the largest observed, since the purpose of a nack threshold is to
-    // tolerate re-ordering.  This handles both StretchAcks and Forward Acks.
-    // The nack count only increases when the largest observed increases.
-    size_t min_nacks = received_info.largest_observed - sequence_number;
-    // Truncated acks can nack the largest observed, so set the nack count to 1.
-    if (min_nacks == 0) {
-      min_nacks = 1;
-    }
-    unacked_packets_.NackPacket(sequence_number, min_nacks);
-  }
-
-  InvokeLossDetection(ack_receive_time);
-}
-
 void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
   SequenceNumberSet lost_packets =
       loss_algorithm_->DetectLostPackets(unacked_packets_,
@@ -610,45 +575,47 @@
   for (SequenceNumberSet::const_iterator it = lost_packets.begin();
        it != lost_packets.end(); ++it) {
     QuicPacketSequenceNumber sequence_number = *it;
+    const TransmissionInfo& transmission_info =
+        unacked_packets_.GetTransmissionInfo(sequence_number);
     // TODO(ianswett): If it's expected the FEC packet may repair the loss, it
     // should be recorded as a loss to the send algorithm, but not retransmitted
     // until it's known whether the FEC packet arrived.
     ++stats_->packets_lost;
-    send_algorithm_->OnPacketLost(sequence_number, time);
-    OnPacketAbandoned(sequence_number);
+    packets_lost_[sequence_number] = transmission_info;
+    unacked_packets_.SetNotPending(sequence_number);
 
-    if (unacked_packets_.HasRetransmittableFrames(sequence_number)) {
+    if (transmission_info.retransmittable_frames != NULL) {
       MarkForRetransmission(sequence_number, LOSS_RETRANSMISSION);
     } else {
       // Since we will not retransmit this, we need to remove it from
       // unacked_packets_.   This is either the current transmission of
       // a packet whose previous transmission has been acked, or it
       // is a packet that has been TLP retransmitted.
-      unacked_packets_.RemovePacket(sequence_number);
+      unacked_packets_.NeuterIfPendingOrRemovePacket(sequence_number);
     }
   }
 }
 
-void QuicSentPacketManager::MaybeUpdateRTT(
+bool QuicSentPacketManager::MaybeUpdateRTT(
     const ReceivedPacketInfo& received_info,
     const QuicTime& ack_receive_time) {
   if (!unacked_packets_.IsUnacked(received_info.largest_observed)) {
-    return;
+    return false;
   }
   // We calculate the RTT based on the highest ACKed sequence number, the lower
   // sequence numbers will include the ACK aggregation delay.
-  const QuicUnackedPacketMap::TransmissionInfo& transmission_info =
+  const TransmissionInfo& transmission_info =
       unacked_packets_.GetTransmissionInfo(received_info.largest_observed);
   // Don't update the RTT if it hasn't been sent.
   if (transmission_info.sent_time == QuicTime::Zero()) {
-    return;
+    return false;
   }
 
   QuicTime::Delta send_delta =
       ack_receive_time.Subtract(transmission_info.sent_time);
   rtt_stats_.UpdateRtt(
       send_delta, received_info.delta_time_largest_observed, ack_receive_time);
-  send_algorithm_->OnRttUpdated(received_info.largest_observed);
+  return true;
 }
 
 QuicTime::Delta QuicSentPacketManager::TimeUntilSend(
@@ -660,7 +627,8 @@
   if (transmission_type == TLP_RETRANSMISSION) {
     return QuicTime::Delta::Zero();
   }
-  return send_algorithm_->TimeUntilSend(now, retransmittable);
+  return send_algorithm_->TimeUntilSend(
+      now, unacked_packets_.bytes_in_flight(), retransmittable);
 }
 
 // Ensures that the Delayed Ack timer is always set to a value lesser
diff --git a/net/quic/quic_sent_packet_manager.h b/net/quic/quic_sent_packet_manager.h
index 4530349..1af85c4 100644
--- a/net/quic/quic_sent_packet_manager.h
+++ b/net/quic/quic_sent_packet_manager.h
@@ -96,7 +96,7 @@
 
   // Removes the retransmittable frames from all unencrypted packets to ensure
   // they don't get retransmitted.
-  void NeuterUnencryptedPackets();
+  void DiscardUnencryptedPackets();
 
   // Returns true if the unacked packet |sequence_number| has retransmittable
   // frames.  This will only return false if the packet has been acked, if a
@@ -170,11 +170,6 @@
   friend class test::QuicConnectionPeer;
   friend class test::QuicSentPacketManagerPeer;
 
-  enum ReceivedByPeer {
-    RECEIVED_BY_PEER,
-    NOT_RECEIVED_BY_PEER,
-  };
-
   // The retransmission timer is a single timer which switches modes depending
   // upon connection state.
   enum RetransmissionTimeoutMode {
@@ -195,10 +190,6 @@
   // Process the incoming ack looking for newly ack'd data packets.
   void HandleAckForSentPackets(const ReceivedPacketInfo& received_info);
 
-  // Called when a packet is timed out, such as an RTO.  Removes the bytes from
-  // the congestion manager, but does not change the congestion window size.
-  void OnPacketAbandoned(QuicPacketSequenceNumber sequence_number);
-
   // Returns the current retransmission mode.
   RetransmissionTimeoutMode GetRetransmissionMode() const;
 
@@ -221,18 +212,21 @@
   const QuicTime::Delta GetRetransmissionDelay() const;
 
   // Update the RTT if the ack is for the largest acked sequence number.
-  void MaybeUpdateRTT(const ReceivedPacketInfo& received_info,
+  // Returns true if the rtt was updated.
+  bool MaybeUpdateRTT(const ReceivedPacketInfo& received_info,
                       const QuicTime& ack_receive_time);
 
-  // Chooses whether to nack retransmit any packets based on the receipt info.
-  // All acks have been handled before this method is invoked.
-  void MaybeRetransmitOnAckFrame(const ReceivedPacketInfo& received_info,
-                                 const QuicTime& ack_receive_time);
-
   // Invokes the loss detection algorithm and loses and retransmits packets if
   // necessary.
   void InvokeLossDetection(QuicTime time);
 
+  // Invokes OnCongestionEvent if |rtt_updated| is true, there are pending acks,
+  // or pending losses.  Clears pending acks and pending losses afterwards.
+  // |bytes_in_flight| is the number of bytes in flight before the losses or
+  // acks.
+  void MaybeInvokeCongestionEvent(bool rtt_updated,
+                                  QuicByteCount bytes_in_flight);
+
   // Marks |sequence_number| as having been revived by the peer, but not
   // received, so the packet remains pending if it is and the congestion control
   // does not consider the packet acked.
@@ -244,8 +238,7 @@
   // iterator to the next remaining unacked packet.
   QuicUnackedPacketMap::const_iterator MarkPacketHandled(
       QuicPacketSequenceNumber sequence_number,
-      QuicTime::Delta delta_largest_observed,
-      ReceivedByPeer received_by_peer);
+      QuicTime::Delta delta_largest_observed);
 
   // Request that |sequence_number| be retransmitted after the other pending
   // retransmissions.  Does not add it to the retransmissions if it's already
@@ -291,6 +284,10 @@
   size_t max_tail_loss_probes_;
   bool using_pacing_;
 
+  // Sets of packets acked and lost as a result of the last congestion event.
+  SendAlgorithmInterface::CongestionMap packets_acked_;
+  SendAlgorithmInterface::CongestionMap packets_lost_;
+
   DISALLOW_COPY_AND_ASSIGN(QuicSentPacketManager);
 };
 
diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc
index 517ea92..e44dca5 100644
--- a/net/quic/quic_sent_packet_manager_test.cc
+++ b/net/quic/quic_sent_packet_manager_test.cc
@@ -13,6 +13,9 @@
 
 using std::vector;
 using testing::_;
+using testing::ElementsAre;
+using testing::Pair;
+using testing::Pointwise;
 using testing::Return;
 using testing::StrictMock;
 
@@ -20,6 +23,15 @@
 namespace test {
 namespace {
 
+// Default packet length.
+const uint32 kDefaultLength = 1000;
+
+// Matcher to check the key of the key-value pair it receives as first argument
+// equals its second argument.
+MATCHER(KeyEq, "") {
+  return std::tr1::get<0>(arg).first == std::tr1::get<1>(arg);
+}
+
 class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
  protected:
   QuicSentPacketManagerTest()
@@ -36,6 +48,9 @@
     STLDeleteElements(&packets_);
   }
 
+  QuicByteCount BytesInFlight() {
+    return QuicSentPacketManagerPeer::GetBytesInFlight(&manager_);
+  }
   void VerifyUnackedPackets(QuicPacketSequenceNumber* packets,
                             size_t num_packets) {
     if (num_packets == 0) {
@@ -72,6 +87,44 @@
     EXPECT_EQ(num_packets, num_retransmittable);
   }
 
+  void ExpectAck(QuicPacketSequenceNumber largest_observed) {
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(
+        true, _, ElementsAre(Pair(largest_observed, _)), _));
+  }
+
+  void ExpectUpdatedRtt(QuicPacketSequenceNumber largest_observed) {
+    EXPECT_CALL(*send_algorithm_,
+                OnCongestionEvent(true, _, _, _));
+  }
+
+  void ExpectAckAndLoss(bool rtt_updated,
+                        QuicPacketSequenceNumber largest_observed,
+                        QuicPacketSequenceNumber lost_packet) {
+    EXPECT_CALL(*send_algorithm_, OnCongestionEvent(
+        rtt_updated, _, ElementsAre(Pair(largest_observed, _)),
+        ElementsAre(Pair(lost_packet, _))));
+  }
+
+  // |packets_acked| and |packets_lost| should be in sequence number order.
+  void ExpectAcksAndLosses(bool rtt_updated,
+                           QuicPacketSequenceNumber* packets_acked,
+                           size_t num_packets_acked,
+                           QuicPacketSequenceNumber* packets_lost,
+                           size_t num_packets_lost) {
+    vector<QuicPacketSequenceNumber> ack_vector;
+    for (size_t i = 0; i < num_packets_acked; ++i) {
+      ack_vector.push_back(packets_acked[i]);
+    }
+    vector<QuicPacketSequenceNumber> lost_vector;
+    for (size_t i = 0; i < num_packets_lost; ++i) {
+      lost_vector.push_back(packets_lost[i]);
+    }
+    EXPECT_CALL(*send_algorithm_,
+                OnCongestionEvent(rtt_updated, _,
+                                  Pointwise(KeyEq(), ack_vector),
+                                  Pointwise(KeyEq(), lost_vector)));
+  }
+
   void RetransmitPacket(QuicPacketSequenceNumber old_sequence_number,
                         QuicPacketSequenceNumber new_sequence_number) {
     QuicSentPacketManagerPeer::MarkForRetransmission(
@@ -90,11 +143,14 @@
   void RetransmitAndSendPacket(QuicPacketSequenceNumber old_sequence_number,
                                QuicPacketSequenceNumber new_sequence_number) {
     RetransmitPacket(old_sequence_number, new_sequence_number);
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, new_sequence_number, _, _))
+
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, BytesInFlight(), new_sequence_number,
+                             kDefaultLength, HAS_RETRANSMITTABLE_DATA))
         .WillOnce(Return(true));
     manager_.OnPacketSent(new_sequence_number,
                           clock_.Now(),
-                          1000,
+                          kDefaultLength,
                           LOSS_RETRANSMISSION,
                           HAS_RETRANSMITTABLE_DATA);
   }
@@ -106,7 +162,7 @@
   SerializedPacket CreatePacket(QuicPacketSequenceNumber sequence_number,
                                 bool retransmittable) {
     packets_.push_back(QuicPacket::NewDataPacket(
-        NULL, 1000, false, PACKET_8BYTE_CONNECTION_ID, false,
+        NULL, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false,
         PACKET_6BYTE_SEQUENCE_NUMBER));
     return SerializedPacket(
         sequence_number, PACKET_6BYTE_SEQUENCE_NUMBER,
@@ -116,14 +172,15 @@
 
   SerializedPacket CreateFecPacket(QuicPacketSequenceNumber sequence_number) {
     packets_.push_back(QuicPacket::NewFecPacket(
-        NULL, 1000, false, PACKET_8BYTE_CONNECTION_ID, false,
+        NULL, kDefaultLength, false, PACKET_8BYTE_CONNECTION_ID, false,
         PACKET_6BYTE_SEQUENCE_NUMBER));
     return SerializedPacket(sequence_number, PACKET_6BYTE_SEQUENCE_NUMBER,
                             packets_.back(), 0u, NULL);
   }
 
   void SendDataPacket(QuicPacketSequenceNumber sequence_number) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, sequence_number, _, _))
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, BytesInFlight(), sequence_number, _, _))
                     .Times(1).WillOnce(Return(true));
     SerializedPacket packet(CreateDataPacket(sequence_number));
     manager_.OnSerializedPacket(packet);
@@ -133,11 +190,14 @@
   }
 
   void SendCryptoPacket(QuicPacketSequenceNumber sequence_number) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, sequence_number, _, _))
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, BytesInFlight(), sequence_number,
+                             kDefaultLength, HAS_RETRANSMITTABLE_DATA))
                     .Times(1).WillOnce(Return(true));
     SerializedPacket packet(CreateDataPacket(sequence_number));
     packet.retransmittable_frames->AddStreamFrame(
         new QuicStreamFrame(1, false, 0, IOVector()));
+    packet.retransmittable_frames->set_encryption_level(ENCRYPTION_NONE);
     manager_.OnSerializedPacket(packet);
     manager_.OnPacketSent(sequence_number, clock_.ApproximateNow(),
                           packet.packet->length(), NOT_RETRANSMISSION,
@@ -145,7 +205,9 @@
   }
 
   void SendFecPacket(QuicPacketSequenceNumber sequence_number) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, sequence_number, _, _))
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, BytesInFlight(), sequence_number,
+                             kDefaultLength, NO_RETRANSMITTABLE_DATA))
                     .Times(1).WillOnce(Return(true));
     SerializedPacket packet(CreateFecPacket(sequence_number));
     manager_.OnSerializedPacket(packet);
@@ -155,7 +217,9 @@
   }
 
   void SendAckPacket(QuicPacketSequenceNumber sequence_number) {
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, sequence_number, _, _))
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, BytesInFlight(), sequence_number,
+                             kDefaultLength, NO_RETRANSMITTABLE_DATA))
                     .Times(1).WillOnce(Return(false));
     SerializedPacket packet(CreatePacket(sequence_number, false));
     manager_.OnSerializedPacket(packet);
@@ -169,15 +233,16 @@
       QuicPacketSequenceNumber retransmission_sequence_number) {
     EXPECT_TRUE(manager_.HasPendingRetransmissions());
     EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, retransmission_sequence_number, _, _))
+                OnPacketSent(_, _, retransmission_sequence_number,
+                             kDefaultLength, HAS_RETRANSMITTABLE_DATA))
                     .Times(1).WillOnce(Return(true));
     const QuicSentPacketManager::PendingRetransmission pending =
         manager_.NextPendingRetransmission();
     manager_.OnRetransmittedPacket(
         pending.sequence_number, retransmission_sequence_number);
-    manager_.OnPacketSent(retransmission_sequence_number,
-                          clock_.ApproximateNow(), 1000,
-                          pending.transmission_type, HAS_RETRANSMITTABLE_DATA);
+    manager_.OnPacketSent(retransmission_sequence_number, clock_.Now(),
+                          kDefaultLength, pending.transmission_type,
+                          HAS_RETRANSMITTABLE_DATA);
   }
 
   QuicSentPacketManager manager_;
@@ -219,8 +284,7 @@
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 2;
   received_info.missing_packets.insert(1);
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(2, _)).Times(1);
+  ExpectAck(2);
   manager_.OnIncomingAck(received_info, clock_.Now());
 
   // Packet 1 is unacked, pending, but not retransmittable.
@@ -239,8 +303,7 @@
   // Ack 1.
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 1;
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(1, _)).Times(1);
+  ExpectAck(1);
   manager_.OnIncomingAck(received_info, clock_.Now());
 
   // There should no longer be a pending retransmission.
@@ -259,8 +322,7 @@
   clock_.AdvanceTime(rtt);
 
   // Ack 1 but not 2.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(1));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(1, _));
+  ExpectAck(1);
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 1;
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
@@ -283,8 +345,7 @@
   clock_.AdvanceTime(rtt);
 
   // Ack 1 but not 2.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(1));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(1, _));
+  ExpectAck(1);
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 1;
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
@@ -301,16 +362,15 @@
 TEST_F(QuicSentPacketManagerTest, RetransmitThenAckPreviousThenNackRetransmit) {
   SendDataPacket(1);
   RetransmitPacket(1, 2);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 2, _, _))
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2, _, _))
       .WillOnce(Return(true));
-  manager_.OnPacketSent(2, clock_.ApproximateNow(), 1000,
+  manager_.OnPacketSent(2, clock_.ApproximateNow(), kDefaultLength,
                         LOSS_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
   QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
   clock_.AdvanceTime(rtt);
 
   // First, ACK packet 1 which makes packet 2 non-retransmittable.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(1));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(1, _));
+  ExpectAck(1);
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 1;
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
@@ -323,20 +383,15 @@
   // Next, NACK packet 2 three times.
   received_info.largest_observed = 3;
   received_info.missing_packets.insert(2);
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(3));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(3, _));
+  ExpectAck(3);
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   received_info.largest_observed = 4;
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(4));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(4, _));
+  ExpectAck(4);
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   received_info.largest_observed = 5;
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(5));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(5, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(2, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(2, _));
+  ExpectAckAndLoss(true, 5, 2);
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   // No packets remain unacked.
@@ -363,7 +418,7 @@
   // send algorithm is not informed that it has been ACK'd.
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 1;
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(1));
+  ExpectUpdatedRtt(1);
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   // Since 2 was marked for retransmit, when 1 is acked, 2 is discarded.
@@ -384,8 +439,7 @@
   clock_.AdvanceTime(rtt);
 
   // Ack 1 but not 2 or 3.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(1));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(1, _));
+  ExpectAck(1);
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 1;
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
@@ -400,9 +454,8 @@
   SendDataPacket(4);
   received_info.largest_observed = 4;
   received_info.missing_packets.insert(2);
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(4));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(3, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(4, _));
+  QuicPacketSequenceNumber acked[] = { 3, 4 };
+  ExpectAcksAndLosses(true, acked, arraysize(acked), NULL, 0);
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   QuicPacketSequenceNumber unacked2[] = { 2 };
@@ -411,10 +464,7 @@
 
   SendDataPacket(5);
   received_info.largest_observed = 5;
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(5));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(5, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(2, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(2, _));
+  ExpectAckAndLoss(true, 5, 2);
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   VerifyUnackedPackets(NULL, 0);
@@ -433,8 +483,8 @@
   received_info.largest_observed = 3;
   received_info.missing_packets.insert(1);
   received_info.revived_packets.insert(1);
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(2);
+  QuicPacketSequenceNumber acked[] = { 2, 3 };
+  ExpectAcksAndLosses(true, acked, arraysize(acked), NULL, 0);
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   EXPECT_FALSE(manager_.HasPendingRetransmissions());
@@ -446,10 +496,7 @@
 
   // Ack the 4th packet and expect the 1st to be considered lost.
   received_info.largest_observed = 4;
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(4, _));
+  ExpectAckAndLoss(true, 4, 1);
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   EXPECT_FALSE(manager_.HasPendingRetransmissions());
@@ -467,10 +514,9 @@
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 4;
   received_info.missing_packets.insert(1);
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(3);
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _));
+  QuicPacketSequenceNumber acked[] = { 2, 3, 4 };
+  QuicPacketSequenceNumber lost[] = { 1 };
+  ExpectAcksAndLosses(true, acked, arraysize(acked), lost, arraysize(lost));
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   EXPECT_TRUE(manager_.HasPendingRetransmissions());
@@ -483,8 +529,7 @@
   // removed from pending retransmissions map.
   received_info.largest_observed = 5;
   received_info.revived_packets.insert(1);
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(5, _));
+  ExpectAck(5);
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   EXPECT_FALSE(manager_.HasPendingRetransmissions());
@@ -506,9 +551,9 @@
   received_info.missing_packets.insert(3);
   received_info.missing_packets.insert(4);
   received_info.is_truncated = true;
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _));
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _));
+
+  QuicPacketSequenceNumber lost[] = { 1 };
+  ExpectAcksAndLosses(true, NULL, 0, lost, arraysize(lost));
   manager_.OnIncomingAck(received_info, clock_.Now());
 
   // High water mark will be raised.
@@ -534,8 +579,7 @@
     ReceivedPacketInfo received_info;
     received_info.largest_observed = 2;
     received_info.missing_packets.insert(1);
-    EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-    EXPECT_CALL(*send_algorithm_, OnPacketAcked(2, _));
+    ExpectAck(2);
     manager_.OnIncomingAck(received_info, clock_.Now());
     EXPECT_TRUE(manager_.IsUnacked(4));
   }
@@ -549,9 +593,7 @@
     received_info.missing_packets.insert(5);
     received_info.missing_packets.insert(6);
     received_info.is_truncated = true;
-    EXPECT_CALL(*send_algorithm_, OnPacketAcked(1, _));
-    EXPECT_CALL(*send_algorithm_, OnPacketLost(3, _));
-    EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(3, _));
+    ExpectAckAndLoss(false, 1, 3);
     manager_.OnIncomingAck(received_info, clock_.Now());
   }
 
@@ -610,7 +652,7 @@
   manager_.DiscardUnackedPacket(1);
   EXPECT_EQ(2u, manager_.GetLeastUnackedSentPacket());
 
-  // Ack 2.
+  // Ack 2, which has never been sent, so there's no rtt update.
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 2;
   manager_.OnIncomingAck(received_info, clock_.Now());
@@ -627,18 +669,18 @@
 
   SerializedPacket serialized_packet(CreateFecPacket(1));
   manager_.OnSerializedPacket(serialized_packet);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, _))
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _))
                   .Times(1).WillOnce(Return(true));
-  manager_.OnPacketSent(
-      1, QuicTime::Zero(), 1000, NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA);
+  manager_.OnPacketSent(1, QuicTime::Zero(), kDefaultLength, NOT_RETRANSMISSION,
+                        NO_RETRANSMITTABLE_DATA);
 
   SerializedPacket serialized_packet2(CreateFecPacket(2));
   QuicTime sent_time = QuicTime::Zero().Add(QuicTime::Delta::FromSeconds(1));
   manager_.OnSerializedPacket(serialized_packet2);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 2, _, _))
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2, _, _))
                   .Times(1).WillOnce(Return(true));
-  manager_.OnPacketSent(
-      2, sent_time, 1000, NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA);
+  manager_.OnPacketSent(2, sent_time, kDefaultLength, NOT_RETRANSMISSION,
+                        NO_RETRANSMITTABLE_DATA);
 
   QuicPacketSequenceNumber unacked[] = { 1, 2 };
   VerifyUnackedPackets(unacked, arraysize(unacked));
@@ -650,82 +692,6 @@
   EXPECT_EQ(sent_time, QuicSentPacketManagerPeer::GetSentTime(&manager_, 2));
 }
 
-TEST_F(QuicSentPacketManagerTest, FackRetransmit17Packets) {
-  const size_t kNumSentPackets = 25;
-  // Transmit 25 packets.
-  for (QuicPacketSequenceNumber i = 1; i <= kNumSentPackets; ++i) {
-    SendDataPacket(i);
-  }
-
-  // Nack the first 19 packets 3 times, which does not trigger early retransmit.
-  const size_t kLargestObserved = 20;
-  ReceivedPacketInfo received_info;
-  received_info.largest_observed = kLargestObserved;
-  received_info.delta_time_largest_observed =
-      QuicTime::Delta::FromMilliseconds(5);
-  for (size_t i = 1; i < kLargestObserved; ++i) {
-    received_info.missing_packets.insert(i);
-  }
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketAcked(kLargestObserved, _)).Times(1);
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(17);
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(17);
-  manager_.OnIncomingAck(received_info, clock_.Now());
-  EXPECT_EQ(
-      17u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_));
-  for (size_t i = 1; i < kLargestObserved; ++i) {
-    EXPECT_EQ(kLargestObserved - i,
-              QuicSentPacketManagerPeer::GetNackCount(&manager_, i));
-  }
-
-  // Now receive the second packet, out of order, which should lose and
-  // retransmit nothing, because it does not increase the largest observed.
-  // No acks are registered, because the packet was already lost.
-  received_info.missing_packets.erase(2);
-  manager_.OnIncomingAck(received_info, clock_.Now());
-}
-
-TEST_F(QuicSentPacketManagerTest, FackRetransmit14PacketsAlternateAcks) {
-  const size_t kNumSentPackets = 30;
-  // Transmit 15 packets of data and 15 ack packets.  The send algorithm returns
-  // false to inform the sent packet manager not to count acks as pending.
-  for (QuicPacketSequenceNumber i = 1; i <= kNumSentPackets; ++i) {
-    if (i % 2 == 0) {
-      SendAckPacket(i);
-    } else {
-      SendDataPacket(i);
-    }
-  }
-
-  // Nack the first 29 packets 3 times.
-  ReceivedPacketInfo received_info;
-  received_info.largest_observed = kNumSentPackets;
-  received_info.delta_time_largest_observed =
-      QuicTime::Delta::FromMilliseconds(5);
-  for (size_t i = 1; i < kNumSentPackets; ++i) {
-    received_info.missing_packets.insert(i);
-  }
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(14);
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(14);
-  manager_.OnIncomingAck(received_info, clock_.Now());
-  ASSERT_EQ(
-      14u, QuicSentPacketManagerPeer::GetPendingRetransmissionCount(&manager_));
-  // Only non-ack packets have a nack count.
-  for (size_t i = 1; i < kNumSentPackets; i += 2) {
-    EXPECT_EQ(kNumSentPackets - i,
-              QuicSentPacketManagerPeer::GetNackCount(&manager_, i));
-  }
-
-  // Ensure only the odd packets were retransmitted, since the others were not
-  // retransmittable(ie: acks).
-  for (size_t i = 0; i < 13; ++i) {
-    EXPECT_EQ(1 + 2 * i, manager_.NextPendingRetransmission().sequence_number);
-    manager_.OnRetransmittedPacket(1 + 2 * i, kNumSentPackets + 1 + i);
-  }
-}
-
 TEST_F(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
   SendDataPacket(1);
   SendAckPacket(2);
@@ -736,16 +702,14 @@
   received_info.delta_time_largest_observed =
       QuicTime::Delta::FromMilliseconds(5);
 
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(1, _)).Times(1);
+  ExpectAck(1);
   manager_.OnIncomingAck(received_info, clock_.Now());
 
   SendAckPacket(3);
 
   // Now ack the ack and expect only an RTT update.
   received_info.largest_observed = 3;
-
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
+  ExpectUpdatedRtt(3);
   manager_.OnIncomingAck(received_info, clock_.Now());
 }
 
@@ -755,9 +719,7 @@
   SendDataPacket(sequence_number);
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
 
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(sequence_number));
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketAcked(sequence_number, _)).Times(1);
+  ExpectAck(sequence_number);
   ReceivedPacketInfo received_info;
   received_info.largest_observed = sequence_number;
   received_info.delta_time_largest_observed =
@@ -776,9 +738,7 @@
   SendDataPacket(sequence_number);
   clock_.AdvanceTime(expected_rtt);
 
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(sequence_number));
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketAcked(sequence_number, _)).Times(1);
+  ExpectAck(sequence_number);
   ReceivedPacketInfo received_info;
   received_info.largest_observed = sequence_number;
   received_info.delta_time_largest_observed =
@@ -796,9 +756,7 @@
   SendDataPacket(sequence_number);
   clock_.AdvanceTime(expected_rtt);
 
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(sequence_number));
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketAcked(sequence_number, _)).Times(1);
+  ExpectAck(sequence_number);
   ReceivedPacketInfo received_info;
   received_info.largest_observed = sequence_number;
   received_info.delta_time_largest_observed = QuicTime::Delta::Infinite();
@@ -815,9 +773,7 @@
   SendDataPacket(sequence_number);
   clock_.AdvanceTime(expected_rtt);
 
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(sequence_number));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(sequence_number, _))
-      .Times(1);
+  ExpectAck(sequence_number);
   ReceivedPacketInfo received_info;
   received_info.largest_observed = sequence_number;
   received_info.delta_time_largest_observed = QuicTime::Delta::Zero();
@@ -844,8 +800,7 @@
   EXPECT_FALSE(manager_.HasPendingRetransmissions());
 
   // Ack the third and ensure the first two are still pending.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(3, _));
+  ExpectAck(3);
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 3;
   received_info.missing_packets.insert(1);
@@ -856,8 +811,8 @@
 
   // Acking two more packets will lose both of them due to nacks.
   received_info.largest_observed = 5;
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2);
-  EXPECT_CALL(*send_algorithm_, OnPacketLost(_, _)).Times(2);
+  QuicPacketSequenceNumber lost[] = { 1, 2 };
+  ExpectAcksAndLosses(false, NULL, 0, lost, arraysize(lost));
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   EXPECT_FALSE(manager_.HasPendingRetransmissions());
@@ -909,7 +864,6 @@
   EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
 
   // The first retransmits 2 packets.
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2);
   manager_.OnRetransmissionTimeout();
   RetransmitNextPacket(6);
   RetransmitNextPacket(7);
@@ -917,7 +871,6 @@
   EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
 
   // The second retransmits 2 packets.
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2);
   manager_.OnRetransmissionTimeout();
   RetransmitNextPacket(8);
   RetransmitNextPacket(9);
@@ -926,8 +879,8 @@
 
   // Now ack the two crypto packets and the speculatively encrypted request,
   // and ensure the first four crypto packets get abandoned, but not lost.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(5);
+  QuicPacketSequenceNumber acked[] = { 3, 4, 5, 8, 9 };
+  ExpectAcksAndLosses(true, acked, arraysize(acked), NULL, 0);
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 9;
   received_info.missing_packets.insert(1);
@@ -952,7 +905,6 @@
   EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
 
   // The first retransmission timeout retransmits 2 crypto packets.
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2);
   manager_.OnRetransmissionTimeout();
   RetransmitNextPacket(6);
   RetransmitNextPacket(7);
@@ -961,7 +913,6 @@
 
   // Now act like a version negotiation packet arrived, which would cause all
   // unacked packets to be retransmitted.
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(5);
   manager_.RetransmitUnackedPackets(ALL_PACKETS);
 
   // Ensure the first two pending packets are the crypto retransmits.
@@ -980,19 +931,16 @@
   EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
 
   // Retransmit the crypto packet as 2.
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(1);
   manager_.OnRetransmissionTimeout();
   RetransmitNextPacket(2);
 
   // Retransmit the crypto packet as 3.
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(1);
   manager_.OnRetransmissionTimeout();
   RetransmitNextPacket(3);
 
   // Now ack the first crypto packet, and ensure the second gets abandoned and
   // removed from unacked_packets.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(1);
+  ExpectUpdatedRtt(2);
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 2;
   received_info.missing_packets.insert(1);
@@ -1013,7 +961,6 @@
   EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
 
   // Retransmit 2 crypto packets, but not the serialized packet.
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(2);
   manager_.OnRetransmissionTimeout();
   RetransmitNextPacket(6);
   RetransmitNextPacket(7);
@@ -1028,13 +975,11 @@
   EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
 
   // Retransmit the crypto packet as 2.
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(1);
   manager_.OnRetransmissionTimeout();
   RetransmitNextPacket(2);
 
   // Now retransmit all the unacked packets, which occurs when there is a
   // version negotiation.
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _)).Times(1);
   manager_.RetransmitUnackedPackets(ALL_PACKETS);
   QuicPacketSequenceNumber unacked[] = { 1, 2 };
   VerifyUnackedPackets(unacked, arraysize(unacked));
@@ -1043,6 +988,25 @@
   EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
 }
 
+TEST_F(QuicSentPacketManagerTest,
+       CryptoHandshakeRetransmissionThenAbandonAll) {
+  // Send 1 crypto packet.
+  SendCryptoPacket(1);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  // Retransmit the crypto packet as 2.
+  manager_.OnRetransmissionTimeout();
+  RetransmitNextPacket(2);
+
+  // Now discard all unacked unencrypted packets, which occurs when the
+  // connection goes forward secure.
+  manager_.DiscardUnencryptedPackets();
+  VerifyUnackedPackets(NULL, 0);
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+}
+
 TEST_F(QuicSentPacketManagerTest, TailLossProbeTimeoutUnsentDataPacket) {
   QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
   // Serialize two data packets and send the latter.
@@ -1094,7 +1058,6 @@
 
   // Retransmit the packet by invoking the retransmission timeout.
   clock_.AdvanceTime(srtt.Multiply(1.5));
-  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(_, _));
   manager_.OnRetransmissionTimeout();
   RetransmitNextPacket(2);
 
@@ -1163,7 +1126,7 @@
   ReceivedPacketInfo received_info;
   received_info.largest_observed = 2;
   received_info.missing_packets.insert(1);
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
+  ExpectUpdatedRtt(2);
   manager_.OnIncomingAck(received_info, clock_.ApproximateNow());
 
   expected_time = clock_.Now().Add(expected_rto_delay);
@@ -1224,8 +1187,7 @@
 
   // Handle an ack which causes the loss algorithm to be evaluated and
   // set the loss timeout.
-  EXPECT_CALL(*send_algorithm_, OnRttUpdated(_));
-  EXPECT_CALL(*send_algorithm_, OnPacketAcked(2, _));
+  ExpectAck(2);
   EXPECT_CALL(*loss_algorithm, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(SequenceNumberSet()));
   ReceivedPacketInfo received_info;
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc
index ba20d50..66f150b 100644
--- a/net/quic/quic_session.cc
+++ b/net/quic/quic_session.cc
@@ -7,6 +7,7 @@
 #include "base/stl_util.h"
 #include "net/quic/crypto/proof_verifier.h"
 #include "net/quic/quic_connection.h"
+#include "net/quic/quic_flags.h"
 #include "net/quic/quic_headers_stream.h"
 #include "net/ssl/ssl_info.h"
 
@@ -216,6 +217,7 @@
 
 void QuicSession::OnWindowUpdateFrames(
     const vector<QuicWindowUpdateFrame>& frames) {
+  bool connection_window_updated = false;
   for (size_t i = 0; i < frames.size(); ++i) {
     // Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't
     // assume that it still exists.
@@ -223,10 +225,14 @@
     if (stream_id == 0) {
       // This is a window update that applies to the connection, rather than an
       // individual stream.
-      // TODO(rjshade): Adjust connection level flow control window.
       DVLOG(1) << ENDPOINT
                << "Received connection level flow control window update with "
                   "byte offset: " << frames[i].byte_offset;
+      if (FLAGS_enable_quic_connection_flow_control &&
+          connection()->flow_controller()->UpdateSendWindowOffset(
+              frames[i].byte_offset)) {
+        connection_window_updated = true;
+      }
       continue;
     }
 
@@ -235,6 +241,12 @@
       stream->OnWindowUpdateFrame(frames[i]);
     }
   }
+
+  // Connection level flow control window has increased, so blocked streams can
+  // write again.
+  if (connection_window_updated) {
+    OnCanWrite();
+  }
 }
 
 void QuicSession::OnBlockedFrames(const vector<QuicBlockedFrame>& frames) {
@@ -260,7 +272,7 @@
       connection_.get(), QuicConnection::NO_ACK);
   for (size_t i = 0; i < num_writes; ++i) {
     if (!write_blocked_streams_.HasWriteBlockedStreams()) {
-      // Writing one stream removed another?! Something's broken.
+      // Writing one stream removed another!? Something's broken.
       LOG(DFATAL) << "WriteBlockedStream is missing";
       connection_->CloseConnection(QUIC_INTERNAL_ERROR, false);
       return;
@@ -385,6 +397,10 @@
           new_flow_control_send_window);
       it++;
     }
+
+    // Update connection level window.
+    connection()->flow_controller()->UpdateSendWindowOffset(
+        new_flow_control_send_window);
   }
 }
 
@@ -406,7 +422,7 @@
           << "Handshake confirmed without parameter negotiation.";
       // Discard originally encrypted packets, since they can't be decrypted by
       // the peer.
-      connection_->NeuterUnencryptedPackets();
+      connection_->DiscardUnencryptedPackets();
       connection_->SetOverallConnectionTimeout(QuicTime::Delta::Infinite());
       max_open_streams_ = config_.max_streams_per_connection();
       break;
@@ -554,10 +570,6 @@
 #ifndef NDEBUG
   ReliableQuicStream* stream = GetStream(id);
   if (stream != NULL) {
-    if (stream->flow_controller()->IsBlocked()) {
-      LOG(DFATAL) << ENDPOINT << "Stream " << id
-                  << " is flow control blocked and write blocked!";
-    }
     LOG_IF(DFATAL, priority != stream->EffectivePriority())
         << ENDPOINT << "Stream " << id
         << "Priorities do not match.  Got: " << priority
diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc
index 019e27b..b2dfa0e 100644
--- a/net/quic/quic_session_test.cc
+++ b/net/quic/quic_session_test.cc
@@ -366,7 +366,7 @@
   session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority);
 
 
-  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _)).WillRepeatedly(
+  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillRepeatedly(
       Return(QuicTime::Delta::Zero()));
   EXPECT_CALL(*send_algorithm, GetCongestionWindow()).WillOnce(
       Return(kMaxPacketSize * 10));
@@ -381,7 +381,7 @@
           QuicConnectionPeer::GetWriter(session_.connection()));
   EXPECT_CALL(*writer, WritePacket(_, _, _, _)).WillOnce(
                   Return(WriteResult(WRITE_STATUS_OK, 0)));
-  EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _));
+  EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
   session_.OnCanWrite();
   EXPECT_FALSE(session_.HasPendingWrites());
 }
@@ -402,13 +402,13 @@
   session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority);
 
   StreamBlocker stream2_blocker(&session_, stream2->id());
-  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _)).WillOnce(Return(
+  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
       QuicTime::Delta::Zero()));
   EXPECT_CALL(*stream2, OnCanWrite());
-  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _)).WillOnce(Return(
+  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
       QuicTime::Delta::Zero()));
   EXPECT_CALL(*stream6, OnCanWrite());
-  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _)).WillOnce(Return(
+  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
       QuicTime::Delta::Infinite()));
   // stream4->OnCanWrite is not called.
 
@@ -416,14 +416,14 @@
   EXPECT_TRUE(session_.HasPendingWrites());
 
   // Still congestion-control blocked.
-  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _)).WillOnce(Return(
+  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
       QuicTime::Delta::Infinite()));
   session_.OnCanWrite();
   EXPECT_TRUE(session_.HasPendingWrites());
 
   // stream4->OnCanWrite is called once the connection stops being
   // congestion-control blocked.
-  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _)).WillOnce(Return(
+  EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return(
       QuicTime::Delta::Zero()));
   EXPECT_CALL(*stream4, OnCanWrite());
   session_.OnCanWrite();
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index 5008ee8..310f93e 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -306,7 +306,7 @@
     return ERR_QUIC_PROTOCOL_ERROR;
   }
   bool require_confirmation =
-      factory_->require_confirmation() || server_id_.is_https() || is_post_ ||
+      factory_->require_confirmation() || is_post_ ||
       was_alternate_protocol_recently_broken_;
   rv = session_->CryptoConnect(
       require_confirmation,
@@ -430,7 +430,10 @@
 
 QuicStreamFactory::~QuicStreamFactory() {
   CloseAllSessions(ERR_ABORTED);
-  STLDeleteElements(&all_sessions_);
+  while (!all_sessions_.empty()) {
+    delete all_sessions_.begin()->first;
+    all_sessions_.erase(all_sessions_.begin());
+  }
   STLDeleteValues(&active_jobs_);
 }
 
@@ -556,7 +559,6 @@
 }
 
 void QuicStreamFactory::OnSessionGoingAway(QuicClientSession* session) {
-  const QuicConnectionStats& stats = session->connection()->GetStats();
   const AliasSet& aliases = session_aliases_[session];
   for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end();
        ++it) {
@@ -569,28 +571,9 @@
     }
 
     active_sessions_.erase(*it);
-    if (!http_server_properties_)
-      continue;
-
-    if (!session->IsCryptoHandshakeConfirmed()) {
-      // TODO(rch):  In the special case where the session has received no
-      // packets from the peer, we should consider blacklisting this
-      // differently so that we still race TCP but we don't consider the
-      // session connected until the handshake has been confirmed.
-      HistogramBrokenAlternateProtocolLocation(
-          BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_STREAM_FACTORY);
-      http_server_properties_->SetBrokenAlternateProtocol(it->host_port_pair());
-      UMA_HISTOGRAM_COUNTS("Net.QuicHandshakeNotConfirmedNumPacketsReceived",
-                           stats.packets_received);
-      continue;
-    }
-
-    HttpServerProperties::NetworkStats network_stats;
-    network_stats.srtt = base::TimeDelta::FromMicroseconds(stats.srtt_us);
-    network_stats.bandwidth_estimate = stats.estimated_bandwidth;
-    http_server_properties_->SetServerNetworkStats(it->host_port_pair(),
-                                                   network_stats);
+    ProcessGoingAwaySession(session, *it);
   }
+  ProcessGoingAwaySession(session, all_sessions_[session]);
   if (!aliases.empty()) {
     const IpAliasKey ip_alias_key(session->connection()->peer_address(),
                                   aliases.begin()->is_https());
@@ -605,8 +588,8 @@
 void QuicStreamFactory::OnSessionClosed(QuicClientSession* session) {
   DCHECK_EQ(0u, session->GetNumOpenStreams());
   OnSessionGoingAway(session);
-  all_sessions_.erase(session);
   delete session;
+  all_sessions_.erase(session);
 }
 
 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) {
@@ -624,7 +607,7 @@
   }
   while (!all_sessions_.empty()) {
     size_t initial_size = all_sessions_.size();
-    (*all_sessions_.begin())->CloseSessionOnError(error);
+    all_sessions_.begin()->first->CloseSessionOnError(error);
     DCHECK_NE(initial_size, all_sessions_.size());
   }
   DCHECK(all_sessions_.empty());
@@ -773,7 +756,7 @@
       connection, socket.Pass(), writer.Pass(), this,
       quic_crypto_client_stream_factory_, server_info.Pass(), server_id,
       config, &crypto_config_, net_log.net_log());
-  all_sessions_.insert(*session);  // owning pointer
+  all_sessions_[*session] = server_id;  // owning pointer
   return OK;
 }
 
@@ -817,4 +800,32 @@
   }
 }
 
+void QuicStreamFactory::ProcessGoingAwaySession(
+    QuicClientSession* session,
+    const QuicServerId& server_id) {
+  if (!http_server_properties_)
+    return;
+
+  const QuicConnectionStats& stats = session->connection()->GetStats();
+  if (!session->IsCryptoHandshakeConfirmed()) {
+    // TODO(rch):  In the special case where the session has received no
+    // packets from the peer, we should consider blacklisting this
+    // differently so that we still race TCP but we don't consider the
+    // session connected until the handshake has been confirmed.
+    HistogramBrokenAlternateProtocolLocation(
+        BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_STREAM_FACTORY);
+    http_server_properties_->SetBrokenAlternateProtocol(
+        server_id.host_port_pair());
+    UMA_HISTOGRAM_COUNTS("Net.QuicHandshakeNotConfirmedNumPacketsReceived",
+                         stats.packets_received);
+    return;
+  }
+
+  HttpServerProperties::NetworkStats network_stats;
+  network_stats.srtt = base::TimeDelta::FromMicroseconds(stats.srtt_us);
+  network_stats.bandwidth_estimate = stats.estimated_bandwidth;
+  http_server_properties_->SetServerNetworkStats(server_id.host_port_pair(),
+                                                 network_stats);
+}
+
 }  // namespace net
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h
index 079b652..b7936c3 100644
--- a/net/quic/quic_stream_factory.h
+++ b/net/quic/quic_stream_factory.h
@@ -186,6 +186,7 @@
   };
 
   typedef std::map<QuicServerId, QuicClientSession*> SessionMap;
+  typedef std::map<QuicClientSession*, QuicServerId> SessionIdMap;
   typedef std::set<QuicServerId> AliasSet;
   typedef std::map<QuicClientSession*, AliasSet> SessionAliasMap;
   typedef std::set<QuicClientSession*> SessionSet;
@@ -220,6 +221,9 @@
       const QuicServerId& server_id,
       const scoped_ptr<QuicServerInfo>& server_info);
 
+  void ProcessGoingAwaySession(QuicClientSession* session,
+                               const QuicServerId& server_id);
+
   bool require_confirmation_;
   HostResolver* host_resolver_;
   ClientSocketFactory* client_socket_factory_;
@@ -235,7 +239,7 @@
   scoped_ptr<QuicConnectionHelper> helper_;
 
   // Contains owning pointers to all sessions that currently exist.
-  SessionSet all_sessions_;
+  SessionIdMap all_sessions_;
   // Contains non-owning pointers to currently active session
   // (not going away session, once they're implemented).
   SessionMap active_sessions_;
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc
index e5b3a3e..27903e9 100644
--- a/net/quic/quic_stream_factory_test.cc
+++ b/net/quic/quic_stream_factory_test.cc
@@ -72,10 +72,10 @@
 
   static bool IsLiveSession(QuicStreamFactory* factory,
                             QuicClientSession* session) {
-    for (QuicStreamFactory::SessionSet::iterator it =
+    for (QuicStreamFactory::SessionIdMap::iterator it =
              factory->all_sessions_.begin();
          it != factory->all_sessions_.end(); ++it) {
-      if (*it == session)
+      if (it->first == session)
         return true;
     }
     return false;
diff --git a/net/quic/quic_stream_sequencer.cc b/net/quic/quic_stream_sequencer.cc
index 8f59064..61b4f7c 100644
--- a/net/quic/quic_stream_sequencer.cc
+++ b/net/quic/quic_stream_sequencer.cc
@@ -67,7 +67,7 @@
           data.iovec()[i].iov_len);
     }
     num_bytes_consumed_ += bytes_consumed;
-    stream_->flow_controller()->AddBytesConsumed(bytes_consumed);
+    stream_->AddBytesConsumed(bytes_consumed);
     stream_->MaybeSendWindowUpdate();
 
     if (MaybeCloseStream()) {
@@ -95,7 +95,7 @@
         byte_offset, string(static_cast<char*>(iov.iov_base), iov.iov_len)));
     byte_offset += iov.iov_len;
     num_bytes_buffered_ += iov.iov_len;
-    stream_->flow_controller()->AddBytesBuffered(iov.iov_len);
+    stream_->AddBytesBuffered(iov.iov_len);
   }
   return true;
 }
@@ -247,8 +247,8 @@
   num_bytes_consumed_ += bytes_consumed;
   num_bytes_buffered_ -= bytes_consumed;
 
-  stream_->flow_controller()->AddBytesConsumed(bytes_consumed);
-  stream_->flow_controller()->RemoveBytesBuffered(bytes_consumed);
+  stream_->AddBytesConsumed(bytes_consumed);
+  stream_->RemoveBytesBuffered(bytes_consumed);
   stream_->MaybeSendWindowUpdate();
 }
 
diff --git a/net/quic/quic_stream_sequencer.h b/net/quic/quic_stream_sequencer.h
index ccdac94..a21efea 100644
--- a/net/quic/quic_stream_sequencer.h
+++ b/net/quic/quic_stream_sequencer.h
@@ -68,9 +68,11 @@
   size_t num_bytes_buffered() const { return num_bytes_buffered_; }
   QuicStreamOffset num_bytes_consumed() const { return num_bytes_consumed_; }
 
-  int num_frames_received() { return num_frames_received_; }
+  int num_frames_received() const { return num_frames_received_; }
 
-  int num_duplicate_frames_received() { return num_duplicate_frames_received_; }
+  int num_duplicate_frames_received() const {
+    return num_duplicate_frames_received_;
+  }
 
  private:
   friend class test::QuicStreamSequencerPeer;
diff --git a/net/quic/quic_stream_sequencer_test.cc b/net/quic/quic_stream_sequencer_test.cc
index 1875e68..4abd94b 100644
--- a/net/quic/quic_stream_sequencer_test.cc
+++ b/net/quic/quic_stream_sequencer_test.cc
@@ -381,8 +381,7 @@
 
   while (!list_.empty()) {
     int index = OneToN(list_.size()) - 1;
-    LOG(ERROR) << "Sending index " << index << " "
-               << list_[index].second.data();
+    LOG(ERROR) << "Sending index " << index << " " << list_[index].second;
     EXPECT_TRUE(sequencer_->OnFrame(list_[index].first,
                                     list_[index].second.data()));
 
diff --git a/net/quic/quic_unacked_packet_map.cc b/net/quic/quic_unacked_packet_map.cc
index 8d0a4b7..d75991e 100644
--- a/net/quic/quic_unacked_packet_map.cc
+++ b/net/quic/quic_unacked_packet_map.cc
@@ -13,44 +13,6 @@
 
 namespace net {
 
-QuicUnackedPacketMap::TransmissionInfo::TransmissionInfo()
-    : retransmittable_frames(NULL),
-      sequence_number_length(PACKET_1BYTE_SEQUENCE_NUMBER),
-      sent_time(QuicTime::Zero()),
-      bytes_sent(0),
-      nack_count(0),
-      all_transmissions(NULL),
-      pending(false) { }
-
-QuicUnackedPacketMap::TransmissionInfo::TransmissionInfo(
-    RetransmittableFrames* retransmittable_frames,
-    QuicPacketSequenceNumber sequence_number,
-    QuicSequenceNumberLength sequence_number_length)
-    : retransmittable_frames(retransmittable_frames),
-      sequence_number_length(sequence_number_length),
-      sent_time(QuicTime::Zero()),
-      bytes_sent(0),
-      nack_count(0),
-      all_transmissions(new SequenceNumberSet),
-      pending(false) {
-  all_transmissions->insert(sequence_number);
-}
-
-QuicUnackedPacketMap::TransmissionInfo::TransmissionInfo(
-    RetransmittableFrames* retransmittable_frames,
-    QuicPacketSequenceNumber sequence_number,
-    QuicSequenceNumberLength sequence_number_length,
-    SequenceNumberSet* all_transmissions)
-    : retransmittable_frames(retransmittable_frames),
-      sequence_number_length(sequence_number_length),
-      sent_time(QuicTime::Zero()),
-      bytes_sent(0),
-      nack_count(0),
-      all_transmissions(all_transmissions),
-      pending(false) {
-  all_transmissions->insert(sequence_number);
-}
-
 QuicUnackedPacketMap::QuicUnackedPacketMap()
     : largest_sent_packet_(0),
       bytes_in_flight_(0),
@@ -129,7 +91,7 @@
     }
 
     ++it;
-    RemovePacket(sequence_number);
+    NeuterIfPendingOrRemovePacket(sequence_number);
     --num_to_clear;
   }
 }
@@ -157,29 +119,7 @@
   it->second.nack_count = max(min_nacks, it->second.nack_count);
 }
 
-void QuicUnackedPacketMap::RemovePacket(
-    QuicPacketSequenceNumber sequence_number) {
-  UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number);
-  if (it == unacked_packets_.end()) {
-    LOG(DFATAL) << "packet is not unacked: " << sequence_number;
-    return;
-  }
-  const TransmissionInfo& transmission_info = it->second;
-  transmission_info.all_transmissions->erase(sequence_number);
-  if (transmission_info.all_transmissions->empty()) {
-    delete transmission_info.all_transmissions;
-  }
-  if (transmission_info.retransmittable_frames != NULL) {
-    if (transmission_info.retransmittable_frames->HasCryptoHandshake()
-            == IS_HANDSHAKE) {
-      --pending_crypto_packet_count_;
-    }
-    delete transmission_info.retransmittable_frames;
-  }
-  unacked_packets_.erase(it);
-}
-
-void QuicUnackedPacketMap::NeuterPacket(
+void QuicUnackedPacketMap::NeuterIfPendingOrRemovePacket(
     QuicPacketSequenceNumber sequence_number) {
   UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number);
   if (it == unacked_packets_.end()) {
@@ -187,11 +127,6 @@
     return;
   }
   TransmissionInfo* transmission_info = &it->second;
-  if (transmission_info->all_transmissions->size() > 1) {
-    transmission_info->all_transmissions->erase(sequence_number);
-    transmission_info->all_transmissions = new SequenceNumberSet();
-    transmission_info->all_transmissions->insert(sequence_number);
-  }
   if (transmission_info->retransmittable_frames != NULL) {
     if (transmission_info->retransmittable_frames->HasCryptoHandshake()
             == IS_HANDSHAKE) {
@@ -200,6 +135,21 @@
     delete transmission_info->retransmittable_frames;
     transmission_info->retransmittable_frames = NULL;
   }
+  if (transmission_info->pending) {
+    // Neuter it so it can't be retransmitted.
+    if (transmission_info->all_transmissions->size() > 1) {
+      transmission_info->all_transmissions->erase(sequence_number);
+      transmission_info->all_transmissions = new SequenceNumberSet();
+      transmission_info->all_transmissions->insert(sequence_number);
+    }
+  } else {
+    // Remove it.
+    transmission_info->all_transmissions->erase(sequence_number);
+    if (transmission_info->all_transmissions->empty()) {
+      delete transmission_info->all_transmissions;
+    }
+    unacked_packets_.erase(it);
+  }
 }
 
 // static
@@ -251,9 +201,8 @@
   return false;
 }
 
-const QuicUnackedPacketMap::TransmissionInfo&
-    QuicUnackedPacketMap::GetTransmissionInfo(
-        QuicPacketSequenceNumber sequence_number) const {
+const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo(
+    QuicPacketSequenceNumber sequence_number) const {
   return unacked_packets_.find(sequence_number)->second;
 }
 
diff --git a/net/quic/quic_unacked_packet_map.h b/net/quic/quic_unacked_packet_map.h
index 552c0d6..011760a 100644
--- a/net/quic/quic_unacked_packet_map.h
+++ b/net/quic/quic_unacked_packet_map.h
@@ -15,37 +15,6 @@
 // contain the same data (via retransmissions)
 class NET_EXPORT_PRIVATE QuicUnackedPacketMap {
  public:
-  struct NET_EXPORT_PRIVATE TransmissionInfo {
-    // Used by STL when assigning into a map.
-    TransmissionInfo();
-
-    // Constructs a Transmission with a new all_tranmissions set
-    // containing |sequence_number|.
-    TransmissionInfo(RetransmittableFrames* retransmittable_frames,
-                     QuicPacketSequenceNumber sequence_number,
-                     QuicSequenceNumberLength sequence_number_length);
-
-    // Constructs a Transmission with the specified |all_tranmissions| set
-    // and inserts |sequence_number| into it.
-    TransmissionInfo(RetransmittableFrames* retransmittable_frames,
-                     QuicPacketSequenceNumber sequence_number,
-                     QuicSequenceNumberLength sequence_number_length,
-                     SequenceNumberSet* all_transmissions);
-
-    RetransmittableFrames* retransmittable_frames;
-    QuicSequenceNumberLength sequence_number_length;
-    // Zero when the packet is serialized, non-zero once it's sent.
-    QuicTime sent_time;
-    // Zero when the packet is serialized, non-zero once it's sent.
-    QuicByteCount bytes_sent;
-    size_t nack_count;
-    // Stores the sequence numbers of all transmissions of this packet.
-    // Can never be null.
-    SequenceNumberSet* all_transmissions;
-    // Pending packets have not been abandoned or lost.
-    bool pending;
-  };
-
   QuicUnackedPacketMap();
   ~QuicUnackedPacketMap();
 
@@ -94,6 +63,11 @@
     return largest_sent_packet_;
   }
 
+  // Returns the sum of the bytes in all pending packets.
+  QuicByteCount bytes_in_flight() const {
+    return bytes_in_flight_;
+  }
+
   // Returns the smallest sequence number of a serialized packet which has not
   // been acked by the peer.  If there are no unacked packets, returns 0.
   QuicPacketSequenceNumber GetLeastUnackedSentPacket() const;
@@ -146,14 +120,10 @@
   // Returns true if there are any pending crypto packets.
   bool HasPendingCryptoPackets() const;
 
-  // Removes entries from the unacked packet map, and deletes
-  // the retransmittable frames associated with the packet.
+  // Deletes the retransmittable frames associated with the packet and removes
+  // it from unacked packets if it's not pending.
   // Does not remove any previous or subsequent transmissions of this packet.
-  void RemovePacket(QuicPacketSequenceNumber sequence_number);
-
-  // Neuters the specified packet.  Deletes any retransmittable
-  // frames, and sets all_transmissions to only include itself.
-  void NeuterPacket(QuicPacketSequenceNumber sequence_number);
+  void NeuterIfPendingOrRemovePacket(QuicPacketSequenceNumber sequence_number);
 
   // Returns true if the packet has been marked as sent by SetSent.
   static bool IsSentAndNotPending(const TransmissionInfo& transmission_info);
diff --git a/net/quic/quic_write_blocked_list.h b/net/quic/quic_write_blocked_list.h
index 1e58e40..cddd58f 100644
--- a/net/quic/quic_write_blocked_list.h
+++ b/net/quic/quic_write_blocked_list.h
@@ -5,6 +5,8 @@
 #ifndef NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_
 #define NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_
 
+#include <set>
+
 #include "net/base/net_export.h"
 #include "net/quic/quic_protocol.h"
 #include "net/spdy/write_blocked_list.h"
@@ -47,14 +49,18 @@
     if (crypto_stream_blocked_) {
       crypto_stream_blocked_ = false;
       return kCryptoStreamId;
-    } else if (headers_stream_blocked_) {
+    }
+
+    if (headers_stream_blocked_) {
       headers_stream_blocked_ = false;
       return kHeadersStreamId;
-    } else {
-      SpdyPriority priority =
-          base_write_blocked_list_.GetHighestPriorityWriteBlockedList();
-      return base_write_blocked_list_.PopFront(priority);
     }
+
+    SpdyPriority priority =
+        base_write_blocked_list_.GetHighestPriorityWriteBlockedList();
+    QuicStreamId id = base_write_blocked_list_.PopFront(priority);
+    blocked_streams_.erase(id);
+    return id;
   }
 
   void PushBack(QuicStreamId stream_id, QuicPriority priority) {
@@ -62,14 +68,25 @@
       DCHECK_EQ(kHighestPriority, priority);
       // TODO(avd) Add DCHECK(!crypto_stream_blocked_)
       crypto_stream_blocked_ = true;
-    } else if (stream_id == kHeadersStreamId) {
+      return;
+    }
+
+    if (stream_id == kHeadersStreamId) {
       DCHECK_EQ(kHighestPriority, priority);
       // TODO(avd) Add DCHECK(!headers_stream_blocked_);
       headers_stream_blocked_ = true;
-    } else {
-      base_write_blocked_list_.PushBack(
-          stream_id, static_cast<SpdyPriority>(priority));
+      return;
     }
+
+    if (blocked_streams_.find(stream_id) != blocked_streams_.end()) {
+      DVLOG(1) << "Stream " << stream_id << " already in write blocked list.";
+      return;
+    }
+
+    base_write_blocked_list_.PushBack(
+        stream_id, static_cast<SpdyPriority>(priority));
+    blocked_streams_.insert(stream_id);
+    return;
   }
 
  private:
@@ -77,6 +94,11 @@
   bool crypto_stream_blocked_;
   bool headers_stream_blocked_;
 
+  // Keep track of write blocked streams in a set for faster membership checking
+  // than iterating over the base_write_blocked_list_. The contents of this set
+  // should mirror the contents of base_write_blocked_list_.
+  std::set<QuicStreamId> blocked_streams_;
+
   DISALLOW_COPY_AND_ASSIGN(QuicWriteBlockedList);
 };
 
diff --git a/net/quic/quic_write_blocked_list_test.cc b/net/quic/quic_write_blocked_list_test.cc
index d8633ea..6f6bba6 100644
--- a/net/quic/quic_write_blocked_list_test.cc
+++ b/net/quic/quic_write_blocked_list_test.cc
@@ -83,6 +83,30 @@
   EXPECT_FALSE(write_blocked_list.HasWriteBlockedStreams());
 }
 
+TEST(QuicWriteBlockedListTest, NoDuplicateEntries) {
+  // Test that QuicWriteBlockedList doesn't allow duplicate entries.
+  QuicWriteBlockedList write_blocked_list;
+
+  // Try to add a stream to the write blocked list multiple times at the same
+  // priority.
+  const QuicStreamId kBlockedId = 5;
+  write_blocked_list.PushBack(kBlockedId,
+                              QuicWriteBlockedList::kHighestPriority);
+  write_blocked_list.PushBack(kBlockedId,
+                              QuicWriteBlockedList::kHighestPriority);
+  write_blocked_list.PushBack(kBlockedId,
+                              QuicWriteBlockedList::kHighestPriority);
+
+  // This should only result in one blocked stream being added.
+  EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams());
+  EXPECT_TRUE(write_blocked_list.HasWriteBlockedStreams());
+
+  // There should only be one stream to pop off the front.
+  EXPECT_EQ(kBlockedId, write_blocked_list.PopFront());
+  EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams());
+  EXPECT_FALSE(write_blocked_list.HasWriteBlockedStreams());
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace net
diff --git a/net/quic/reliable_quic_stream.cc b/net/quic/reliable_quic_stream.cc
index 93739ae..218bb09 100644
--- a/net/quic/reliable_quic_stream.cc
+++ b/net/quic/reliable_quic_stream.cc
@@ -131,7 +131,8 @@
               session_->config()->ReceivedInitialFlowControlWindowBytes() :
               kDefaultFlowControlSendWindow,
           session_->connection()->max_flow_control_receive_window_bytes(),
-          session_->connection()->max_flow_control_receive_window_bytes()) {
+          session_->connection()->max_flow_control_receive_window_bytes()),
+      connection_flow_controller_(session_->connection()->flow_controller()) {
 }
 
 ReliableQuicStream::~ReliableQuicStream() {
@@ -154,7 +155,8 @@
 
   bool accepted = sequencer_.OnStreamFrame(frame);
 
-  if (flow_controller_.FlowControlViolation()) {
+  if (flow_controller_.FlowControlViolation() ||
+      connection_flow_controller_->FlowControlViolation()) {
     session_->connection()->SendConnectionClose(QUIC_FLOW_CONTROL_ERROR);
     return false;
   }
@@ -165,13 +167,14 @@
 
 void ReliableQuicStream::MaybeSendWindowUpdate() {
   flow_controller_.MaybeSendWindowUpdate(session()->connection());
+  connection_flow_controller_->MaybeSendWindowUpdate(session()->connection());
 }
 
-int ReliableQuicStream::num_frames_received() {
+int ReliableQuicStream::num_frames_received() const {
   return sequencer_.num_frames_received();
 }
 
-int ReliableQuicStream::num_duplicate_frames_received() {
+int ReliableQuicStream::num_duplicate_frames_received() const {
   return sequencer_.num_duplicate_frames_received();
 }
 
@@ -294,6 +297,18 @@
   }
 }
 
+void ReliableQuicStream::MaybeSendBlocked() {
+  flow_controller_.MaybeSendBlocked(session()->connection());
+  connection_flow_controller_->MaybeSendBlocked(session()->connection());
+  // If we are connection level flow control blocked, then add the stream
+  // to the write blocked list. It will be given a chance to write when a
+  // connection level WINDOW_UPDATE arrives.
+  if (connection_flow_controller_->IsBlocked() &&
+      !flow_controller_.IsBlocked()) {
+    session_->MarkWriteBlocked(id(), EffectivePriority());
+  }
+}
+
 QuicConsumedData ReliableQuicStream::WritevData(
     const struct iovec* iov,
     int iov_count,
@@ -312,11 +327,15 @@
 
   if (flow_controller_.IsEnabled()) {
     // How much data we are allowed to write from flow control.
-    size_t send_window = flow_controller_.SendWindowSize();
+    uint64 send_window = flow_controller_.SendWindowSize();
+    if (connection_flow_controller_->IsEnabled()) {
+      send_window =
+          min(send_window, connection_flow_controller_->SendWindowSize());
+    }
 
     if (send_window == 0 && !fin_with_zero_data) {
       // Quick return if we can't send anything.
-      flow_controller_.MaybeSendBlocked(session()->connection());
+      MaybeSendBlocked();
       return QuicConsumedData(0, false);
     }
 
@@ -337,11 +356,11 @@
       id(), data, stream_bytes_written_, fin, ack_notifier_delegate);
   stream_bytes_written_ += consumed_data.bytes_consumed;
 
-  flow_controller_.AddBytesSent(consumed_data.bytes_consumed);
+  AddBytesSent(consumed_data.bytes_consumed);
 
   if (consumed_data.bytes_consumed == write_length) {
     if (!fin_with_zero_data) {
-      flow_controller_.MaybeSendBlocked(session()->connection());
+      MaybeSendBlocked();
     }
     if (fin && consumed_data.fin_consumed) {
       fin_sent_ = true;
@@ -381,7 +400,7 @@
   }
 }
 
-bool ReliableQuicStream::HasBufferedData() {
+bool ReliableQuicStream::HasBufferedData() const {
   return !queued_data_.empty();
 }
 
@@ -412,8 +431,42 @@
     // TODO(rjshade): This does not respect priorities (e.g. multiple
     //                outstanding POSTs are unblocked on arrival of
     //                SHLO with initial window).
+    // As long as the connection is not flow control blocked, we can write!
     OnCanWrite();
   }
 }
 
+void ReliableQuicStream::AddBytesBuffered(uint64 bytes) {
+  if (flow_controller_.IsEnabled()) {
+    flow_controller_.AddBytesBuffered(bytes);
+    connection_flow_controller_->AddBytesBuffered(bytes);
+  }
+}
+
+void ReliableQuicStream::RemoveBytesBuffered(uint64 bytes) {
+  if (flow_controller_.IsEnabled()) {
+    flow_controller_.RemoveBytesBuffered(bytes);
+    connection_flow_controller_->RemoveBytesBuffered(bytes);
+  }
+}
+
+void ReliableQuicStream::AddBytesSent(uint64 bytes) {
+  if (flow_controller_.IsEnabled()) {
+    flow_controller_.AddBytesSent(bytes);
+    connection_flow_controller_->AddBytesSent(bytes);
+  }
+}
+
+void ReliableQuicStream::AddBytesConsumed(uint64 bytes) {
+  if (flow_controller_.IsEnabled()) {
+    flow_controller_.AddBytesConsumed(bytes);
+    connection_flow_controller_->AddBytesConsumed(bytes);
+  }
+}
+
+bool ReliableQuicStream::IsFlowControlBlocked() {
+  return flow_controller_.IsBlocked() ||
+         connection_flow_controller_->IsBlocked();
+}
+
 }  // namespace net
diff --git a/net/quic/reliable_quic_stream.h b/net/quic/reliable_quic_stream.h
index 08a11b1..90cdac4 100644
--- a/net/quic/reliable_quic_stream.h
+++ b/net/quic/reliable_quic_stream.h
@@ -97,12 +97,25 @@
   // sequencer's buffer.
   void MaybeSendWindowUpdate();
 
-  int num_frames_received();
+  int num_frames_received() const;
 
-  int num_duplicate_frames_received();
+  int num_duplicate_frames_received() const;
 
   QuicFlowController* flow_controller() { return &flow_controller_; }
 
+  // Called by the stream sequeuncer as bytes are added to the buffer.
+  void AddBytesBuffered(uint64 bytes);
+  // Called by the stream sequeuncer as bytes are removed from the buffer.
+  void RemoveBytesBuffered(uint64 bytes);
+  // Called when bytese are sent to the peer.
+  void AddBytesSent(uint64 bytes);
+  // Called by the stream sequeuncer as bytes are consumed from the buffer.
+  void AddBytesConsumed(uint64 bytes);
+
+  // Returns true if the stream is flow control blocked, by the stream flow
+  // control window or the connection flow control window.
+  bool IsFlowControlBlocked();
+
  protected:
   // Sends as much of 'data' to the connection as the connection will consume,
   // and then buffers any remaining data in queued_data_.
@@ -128,9 +141,9 @@
   // Close the write side of the socket.  Further writes will fail.
   void CloseWriteSide();
 
-  bool HasBufferedData();
+  bool HasBufferedData() const;
 
-  bool fin_buffered() { return fin_buffered_; }
+  bool fin_buffered() const { return fin_buffered_; }
 
   const QuicSession* session() const { return session_; }
   QuicSession* session() { return session_; }
@@ -164,6 +177,11 @@
   // Calculates and returns total number of bytes this stream has received.
   uint64 TotalReceivedBytes() const;
 
+  // Calls MaybeSendBlocked on our flow controller, and connection level flow
+  // controller. If we are flow control blocked, marks this stream as write
+  // blocked.
+  void MaybeSendBlocked();
+
   std::list<PendingData> queued_data_;
 
   QuicStreamSequencer sequencer_;
@@ -199,6 +217,9 @@
 
   QuicFlowController flow_controller_;
 
+  // The connection level flow controller. Not owned.
+  QuicFlowController* connection_flow_controller_;
+
   DISALLOW_COPY_AND_ASSIGN(ReliableQuicStream);
 };
 
diff --git a/net/quic/reliable_quic_stream_test.cc b/net/quic/reliable_quic_stream_test.cc
index 4d71ca2..d1ad909 100644
--- a/net/quic/reliable_quic_stream_test.cc
+++ b/net/quic/reliable_quic_stream_test.cc
@@ -394,6 +394,9 @@
 
   // Set a large flow control send window so this doesn't interfere with test.
   stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
+  if (FLAGS_enable_quic_connection_flow_control) {
+    connection_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
+  }
 
   scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
 
@@ -446,6 +449,9 @@
 
   // Set a large flow control send window so this doesn't interfere with test.
   stream_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
+  if (FLAGS_enable_quic_connection_flow_control) {
+    connection_->flow_controller()->UpdateSendWindowOffset(kDataSize + 1);
+  }
 
   scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
 
diff --git a/net/quic/test_tools/delayed_verify_strike_register_client.cc b/net/quic/test_tools/delayed_verify_strike_register_client.cc
index eec16b1..b14a118 100644
--- a/net/quic/test_tools/delayed_verify_strike_register_client.cc
+++ b/net/quic/test_tools/delayed_verify_strike_register_client.cc
@@ -29,7 +29,7 @@
     QuicWallTime now,
     ResultCallback* cb) {
   if (delay_verifications_) {
-    pending_verifications_.push_back(VerifyArgs(nonce.as_string(), now, cb));
+    pending_verifications_.push_back(VerifyArgs(nonce, now, cb));
   } else {
     LocalStrikeRegisterClient::VerifyNonceIsValidAndUnique(nonce, now, cb);
   }
diff --git a/net/quic/test_tools/quic_sent_packet_manager_peer.cc b/net/quic/test_tools/quic_sent_packet_manager_peer.cc
index 9984243..479711b 100644
--- a/net/quic/test_tools/quic_sent_packet_manager_peer.cc
+++ b/net/quic/test_tools/quic_sent_packet_manager_peer.cc
@@ -118,5 +118,11 @@
   return sent_packet_manager->unacked_packets_.GetUnackedPackets();
 }
 
+// static
+QuicByteCount QuicSentPacketManagerPeer::GetBytesInFlight(
+    const QuicSentPacketManager* sent_packet_manager) {
+  return sent_packet_manager->unacked_packets_.bytes_in_flight();
+}
+
 }  // namespace test
 }  // namespace net
diff --git a/net/quic/test_tools/quic_sent_packet_manager_peer.h b/net/quic/test_tools/quic_sent_packet_manager_peer.h
index c4db12a..105388d 100644
--- a/net/quic/test_tools/quic_sent_packet_manager_peer.h
+++ b/net/quic/test_tools/quic_sent_packet_manager_peer.h
@@ -63,6 +63,9 @@
   static SequenceNumberSet GetUnackedPackets(
       const QuicSentPacketManager* sent_packet_manager);
 
+  static QuicByteCount GetBytesInFlight(
+      const QuicSentPacketManager* sent_packet_manager);
+
  private:
   DISALLOW_COPY_AND_ASSIGN(QuicSentPacketManagerPeer);
 };
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index 894e468..4582a0e 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -13,7 +13,6 @@
 #include "base/strings/string_piece.h"
 #include "net/quic/congestion_control/loss_detection_interface.h"
 #include "net/quic/congestion_control/send_algorithm_interface.h"
-#include "net/quic/crypto/quic_crypto_client_config.h"
 #include "net/quic/quic_ack_notifier.h"
 #include "net/quic/quic_client_session_base.h"
 #include "net/quic/quic_connection.h"
@@ -401,16 +400,16 @@
   MOCK_METHOD2(OnIncomingQuicCongestionFeedbackFrame,
                void(const QuicCongestionFeedbackFrame&,
                     QuicTime feedback_receive_time));
-  MOCK_METHOD2(OnPacketAcked,
-               void(QuicPacketSequenceNumber, QuicByteCount));
-  MOCK_METHOD2(OnPacketLost, void(QuicPacketSequenceNumber, QuicTime));
-  MOCK_METHOD4(OnPacketSent,
-               bool(QuicTime sent_time, QuicPacketSequenceNumber, QuicByteCount,
-                    HasRetransmittableData));
+  MOCK_METHOD4(OnCongestionEvent, void(bool rtt_updated,
+                                       QuicByteCount bytes_in_flight,
+                                       const CongestionMap& acked_packets,
+                                       const CongestionMap& lost_packets));
+  MOCK_METHOD5(OnPacketSent,
+               bool(QuicTime, QuicByteCount, QuicPacketSequenceNumber,
+                    QuicByteCount, HasRetransmittableData));
   MOCK_METHOD1(OnRetransmissionTimeout, void(bool));
-  MOCK_METHOD2(OnPacketAbandoned, void(QuicPacketSequenceNumber sequence_number,
-                                      QuicByteCount abandoned_bytes));
-  MOCK_METHOD2(TimeUntilSend, QuicTime::Delta(QuicTime now,
+  MOCK_METHOD3(TimeUntilSend, QuicTime::Delta(QuicTime now,
+                                              QuicByteCount bytes_in_flight,
                                               HasRetransmittableData));
   MOCK_CONST_METHOD0(BandwidthEstimate, QuicBandwidth(void));
   MOCK_METHOD1(OnRttUpdated, void(QuicPacketSequenceNumber));
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 3e7554e..be81e9a 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -1540,7 +1540,7 @@
 int MockUDPClientSocket::Connect(const IPEndPoint& address) {
   connected_ = true;
   peer_addr_ = address;
-  return OK;
+  return data_->connect_data().result;
 }
 
 void MockUDPClientSocket::OnReadComplete(const MockRead& data) {
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index c95312d..3a8b39e 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -3497,11 +3497,10 @@
         ssl_config_.version_fallback;
     const std::string& host = host_and_port_.host();
 
-    TransportSecurityState::DomainState domain_state;
-    if (transport_security_state_->GetDomainState(host, sni_available,
-                                                  &domain_state) &&
-        domain_state.HasPublicKeyPins()) {
-      if (!domain_state.CheckPublicKeyPins(
+    if (transport_security_state_->HasPublicKeyPins(host, sni_available)) {
+      if (!transport_security_state_->CheckPublicKeyPins(
+              host,
+              sni_available,
               server_cert_verify_result_.public_key_hashes,
               &pinning_failure_log_)) {
         LOG(ERROR) << pinning_failure_log_;
diff --git a/net/socket_stream/socket_stream.cc b/net/socket_stream/socket_stream.cc
index 5979dd1..7404ff3 100644
--- a/net/socket_stream/socket_stream.cc
+++ b/net/socket_stream/socket_stream.cc
@@ -1337,12 +1337,12 @@
   SSLInfo ssl_info;
   ssl_socket->GetSSLInfo(&ssl_info);
 
-  TransportSecurityState::DomainState domain_state;
-  const bool fatal = context_->transport_security_state() &&
-      context_->transport_security_state()->GetDomainState(url_.host(),
-          SSLConfigService::IsSNIAvailable(context_->ssl_config_service()),
-          &domain_state) &&
-      domain_state.ShouldSSLErrorsBeFatal();
+  TransportSecurityState* state = context_->transport_security_state();
+  const bool fatal =
+      state &&
+      state->ShouldSSLErrorsBeFatal(
+          url_.host(),
+          SSLConfigService::IsSNIAvailable(context_->ssl_config_service()));
 
   delegate_->OnSSLCertificateError(this, ssl_info, fatal);
   return ERR_IO_PENDING;
diff --git a/net/socket_stream/socket_stream_job.cc b/net/socket_stream/socket_stream_job.cc
index 0bd7026..a481b97 100644
--- a/net/socket_stream/socket_stream_job.cc
+++ b/net/socket_stream/socket_stream_job.cc
@@ -28,10 +28,9 @@
     URLRequestContext* context,
     CookieStore* cookie_store) {
   GURL socket_url(url);
-  TransportSecurityState::DomainState domain_state;
-  if (url.scheme() == "ws" && sts && sts->GetDomainState(
-          url.host(), SSLConfigService::IsSNIAvailable(ssl), &domain_state) &&
-      domain_state.ShouldUpgradeToSSL()) {
+  if (url.scheme() == "ws" && sts &&
+      sts->ShouldUpgradeToSSL(url.host(),
+                              SSLConfigService::IsSNIAvailable(ssl))) {
     url::Replacements<char> replacements;
     static const char kNewScheme[] = "wss";
     replacements.SetScheme(kNewScheme, url::Component(0, strlen(kNewScheme)));
diff --git a/net/spdy/fuzzing/hpack_example_generator.cc b/net/spdy/fuzzing/hpack_example_generator.cc
index 081451d..9e49642 100644
--- a/net/spdy/fuzzing/hpack_example_generator.cc
+++ b/net/spdy/fuzzing/hpack_example_generator.cc
@@ -48,7 +48,7 @@
                     &example_count);
 
   DVLOG(1) << "Writing output to " << file_to_write;
-  base::File file_out(base::FilePath(file_to_write),
+  base::File file_out(base::FilePath::FromUTF8Unsafe(file_to_write),
                       base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
   CHECK(file_out.IsValid()) << file_out.error_details();
 
diff --git a/net/spdy/fuzzing/hpack_fuzz_mutator.cc b/net/spdy/fuzzing/hpack_fuzz_mutator.cc
index c6d4e92..f0a4c7a 100644
--- a/net/spdy/fuzzing/hpack_fuzz_mutator.cc
+++ b/net/spdy/fuzzing/hpack_fuzz_mutator.cc
@@ -50,10 +50,11 @@
 
   DVLOG(1) << "Reading input from " << file_to_parse;
   HpackFuzzUtil::Input input;
-  CHECK(base::ReadFileToString(base::FilePath(file_to_parse), &input.input));
+  CHECK(base::ReadFileToString(base::FilePath::FromUTF8Unsafe(file_to_parse),
+                               &input.input));
 
   DVLOG(1) << "Writing output to " << file_to_write;
-  base::File file_out(base::FilePath(file_to_write),
+  base::File file_out(base::FilePath::FromUTF8Unsafe(file_to_write),
                       base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
   CHECK(file_out.IsValid()) << file_out.error_details();
 
diff --git a/net/spdy/fuzzing/hpack_fuzz_wrapper.cc b/net/spdy/fuzzing/hpack_fuzz_wrapper.cc
index 63aa114..07e120d 100644
--- a/net/spdy/fuzzing/hpack_fuzz_wrapper.cc
+++ b/net/spdy/fuzzing/hpack_fuzz_wrapper.cc
@@ -33,9 +33,16 @@
   }
   string file_to_parse = command_line.GetSwitchValueASCII(kFileToParse);
 
+  // ClusterFuzz may invoke as --file-to-parse="". Don't crash in this case.
+  if (file_to_parse.empty()) {
+    LOG(WARNING) << "Empty file to parse given. Doing nothing.";
+    return 0;
+  }
+
   DVLOG(1) << "Reading input from " << file_to_parse;
   HpackFuzzUtil::Input input;
-  CHECK(base::ReadFileToString(base::FilePath(file_to_parse), &input.input));
+  CHECK(base::ReadFileToString(base::FilePath::FromUTF8Unsafe(file_to_parse),
+                               &input.input));
 
   HpackFuzzUtil::FuzzerContext context;
   HpackFuzzUtil::InitializeFuzzerContext(&context);
diff --git a/net/spdy/spdy_write_queue.cc b/net/spdy/spdy_write_queue.cc
index 3a4eef5..05b965d 100644
--- a/net/spdy/spdy_write_queue.cc
+++ b/net/spdy/spdy_write_queue.cc
@@ -5,8 +5,10 @@
 #include "net/spdy/spdy_write_queue.h"
 
 #include <cstddef>
+#include <vector>
 
 #include "base/logging.h"
+#include "base/stl_util.h"
 #include "net/spdy/spdy_buffer.h"
 #include "net/spdy/spdy_buffer_producer.h"
 #include "net/spdy/spdy_stream.h"
@@ -26,7 +28,7 @@
 
 SpdyWriteQueue::PendingWrite::~PendingWrite() {}
 
-SpdyWriteQueue::SpdyWriteQueue() {}
+SpdyWriteQueue::SpdyWriteQueue() : removing_writes_(false) {}
 
 SpdyWriteQueue::~SpdyWriteQueue() {
   Clear();
@@ -44,6 +46,7 @@
                              SpdyFrameType frame_type,
                              scoped_ptr<SpdyBufferProducer> frame_producer,
                              const base::WeakPtr<SpdyStream>& stream) {
+  CHECK(!removing_writes_);
   CHECK_GE(priority, MINIMUM_PRIORITY);
   CHECK_LE(priority, MAXIMUM_PRIORITY);
   if (stream.get())
@@ -55,6 +58,7 @@
 bool SpdyWriteQueue::Dequeue(SpdyFrameType* frame_type,
                              scoped_ptr<SpdyBufferProducer>* frame_producer,
                              base::WeakPtr<SpdyStream>* stream) {
+  CHECK(!removing_writes_);
   for (int i = MAXIMUM_PRIORITY; i >= MINIMUM_PRIORITY; --i) {
     if (!queue_[i].empty()) {
       PendingWrite pending_write = queue_[i].front();
@@ -72,6 +76,8 @@
 
 void SpdyWriteQueue::RemovePendingWritesForStream(
     const base::WeakPtr<SpdyStream>& stream) {
+  CHECK(!removing_writes_);
+  removing_writes_ = true;
   RequestPriority priority = stream->priority();
   CHECK_GE(priority, MINIMUM_PRIORITY);
   CHECK_LE(priority, MAXIMUM_PRIORITY);
@@ -90,23 +96,33 @@
   }
 #endif
 
+  // Defer deletion until queue iteration is complete, as
+  // SpdyBuffer::~SpdyBuffer() can result in callbacks into SpdyWriteQueue.
+  std::vector<SpdyBufferProducer*> erased_buffer_producers;
+
   // Do the actual deletion and removal, preserving FIFO-ness.
   std::deque<PendingWrite>* queue = &queue_[priority];
   std::deque<PendingWrite>::iterator out_it = queue->begin();
   for (std::deque<PendingWrite>::const_iterator it = queue->begin();
        it != queue->end(); ++it) {
     if (it->stream.get() == stream.get()) {
-      delete it->frame_producer;
+      erased_buffer_producers.push_back(it->frame_producer);
     } else {
       *out_it = *it;
       ++out_it;
     }
   }
   queue->erase(out_it, queue->end());
+  removing_writes_ = false;
+  STLDeleteElements(&erased_buffer_producers);  // Invokes callbacks.
 }
 
 void SpdyWriteQueue::RemovePendingWritesForStreamsAfter(
     SpdyStreamId last_good_stream_id) {
+  CHECK(!removing_writes_);
+  removing_writes_ = true;
+  std::vector<SpdyBufferProducer*> erased_buffer_producers;
+
   for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
     // Do the actual deletion and removal, preserving FIFO-ness.
     std::deque<PendingWrite>* queue = &queue_[i];
@@ -115,7 +131,7 @@
          it != queue->end(); ++it) {
       if (it->stream.get() && (it->stream->stream_id() > last_good_stream_id ||
                                it->stream->stream_id() == 0)) {
-        delete it->frame_producer;
+        erased_buffer_producers.push_back(it->frame_producer);
       } else {
         *out_it = *it;
         ++out_it;
@@ -123,16 +139,24 @@
     }
     queue->erase(out_it, queue->end());
   }
+  removing_writes_ = false;
+  STLDeleteElements(&erased_buffer_producers);  // Invokes callbacks.
 }
 
 void SpdyWriteQueue::Clear() {
+  CHECK(!removing_writes_);
+  removing_writes_ = true;
+  std::vector<SpdyBufferProducer*> erased_buffer_producers;
+
   for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
     for (std::deque<PendingWrite>::iterator it = queue_[i].begin();
          it != queue_[i].end(); ++it) {
-      delete it->frame_producer;
+      erased_buffer_producers.push_back(it->frame_producer);
     }
     queue_[i].clear();
   }
+  removing_writes_ = false;
+  STLDeleteElements(&erased_buffer_producers);  // Invokes callbacks.
 }
 
 }  // namespace net
diff --git a/net/spdy/spdy_write_queue.h b/net/spdy/spdy_write_queue.h
index 3bceb29..bd67f6b 100644
--- a/net/spdy/spdy_write_queue.h
+++ b/net/spdy/spdy_write_queue.h
@@ -78,6 +78,8 @@
     ~PendingWrite();
   };
 
+  bool removing_writes_;
+
   // The actual write queue, binned by priority.
   std::deque<PendingWrite> queue_[NUM_PRIORITIES];
 
diff --git a/net/spdy/spdy_write_queue_unittest.cc b/net/spdy/spdy_write_queue_unittest.cc
index 6d6cb3c..2ab415a 100644
--- a/net/spdy/spdy_write_queue_unittest.cc
+++ b/net/spdy/spdy_write_queue_unittest.cc
@@ -23,6 +23,11 @@
 
 namespace {
 
+using std::string;
+
+const char kOriginal[] = "original";
+const char kRequeued[] = "requeued";
+
 class SpdyWriteQueueTest : public ::testing::Test {};
 
 // Makes a SpdyFrameProducer producing a frame with the data in the
@@ -44,6 +49,35 @@
   return StringToProducer(base::IntToString(i));
 }
 
+// Producer whose produced buffer will enqueue yet another buffer into the
+// SpdyWriteQueue upon destruction.
+class RequeingBufferProducer : public SpdyBufferProducer {
+ public:
+  RequeingBufferProducer(SpdyWriteQueue* queue) {
+    buffer_.reset(new SpdyBuffer(kOriginal, arraysize(kOriginal)));
+    buffer_->AddConsumeCallback(
+        base::Bind(RequeingBufferProducer::ConsumeCallback, queue));
+  }
+
+  virtual scoped_ptr<SpdyBuffer> ProduceBuffer() OVERRIDE {
+    return buffer_.Pass();
+  }
+
+  static void ConsumeCallback(SpdyWriteQueue* queue,
+                              size_t size,
+                              SpdyBuffer::ConsumeSource source) {
+    scoped_ptr<SpdyBufferProducer> producer(
+        new SimpleBufferProducer(scoped_ptr<SpdyBuffer>(
+            new SpdyBuffer(kRequeued, arraysize(kRequeued)))));
+
+    queue->Enqueue(
+        MEDIUM, RST_STREAM, producer.Pass(), base::WeakPtr<SpdyStream>());
+  }
+
+ private:
+  scoped_ptr<SpdyBuffer> buffer_;
+};
+
 // Produces a frame with the given producer and returns a copy of its
 // data as a string.
 std::string ProducerToString(scoped_ptr<SpdyBufferProducer> producer) {
@@ -247,6 +281,96 @@
   EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream));
 }
 
+TEST_F(SpdyWriteQueueTest, RequeingProducerWithoutReentrance) {
+  SpdyWriteQueue queue;
+  queue.Enqueue(
+      DEFAULT_PRIORITY,
+      SYN_STREAM,
+      scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)),
+      base::WeakPtr<SpdyStream>());
+  {
+    SpdyFrameType frame_type;
+    scoped_ptr<SpdyBufferProducer> producer;
+    base::WeakPtr<SpdyStream> stream;
+
+    EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream));
+    EXPECT_TRUE(queue.IsEmpty());
+    EXPECT_EQ(string(kOriginal), producer->ProduceBuffer()->GetRemainingData());
+  }
+  // |producer| was destroyed, and a buffer is re-queued.
+  EXPECT_FALSE(queue.IsEmpty());
+
+  SpdyFrameType frame_type;
+  scoped_ptr<SpdyBufferProducer> producer;
+  base::WeakPtr<SpdyStream> stream;
+
+  EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream));
+  EXPECT_EQ(string(kRequeued), producer->ProduceBuffer()->GetRemainingData());
+}
+
+TEST_F(SpdyWriteQueueTest, ReentranceOnClear) {
+  SpdyWriteQueue queue;
+  queue.Enqueue(
+      DEFAULT_PRIORITY,
+      SYN_STREAM,
+      scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)),
+      base::WeakPtr<SpdyStream>());
+
+  queue.Clear();
+  EXPECT_FALSE(queue.IsEmpty());
+
+  SpdyFrameType frame_type;
+  scoped_ptr<SpdyBufferProducer> producer;
+  base::WeakPtr<SpdyStream> stream;
+
+  EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream));
+  EXPECT_EQ(string(kRequeued), producer->ProduceBuffer()->GetRemainingData());
+}
+
+TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesAfter) {
+  scoped_ptr<SpdyStream> stream(MakeTestStream(DEFAULT_PRIORITY));
+  stream->set_stream_id(2);
+
+  SpdyWriteQueue queue;
+  queue.Enqueue(
+      DEFAULT_PRIORITY,
+      SYN_STREAM,
+      scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)),
+      stream->GetWeakPtr());
+
+  queue.RemovePendingWritesForStreamsAfter(1);
+  EXPECT_FALSE(queue.IsEmpty());
+
+  SpdyFrameType frame_type;
+  scoped_ptr<SpdyBufferProducer> producer;
+  base::WeakPtr<SpdyStream> weak_stream;
+
+  EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &weak_stream));
+  EXPECT_EQ(string(kRequeued), producer->ProduceBuffer()->GetRemainingData());
+}
+
+TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesForStream) {
+  scoped_ptr<SpdyStream> stream(MakeTestStream(DEFAULT_PRIORITY));
+  stream->set_stream_id(2);
+
+  SpdyWriteQueue queue;
+  queue.Enqueue(
+      DEFAULT_PRIORITY,
+      SYN_STREAM,
+      scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)),
+      stream->GetWeakPtr());
+
+  queue.RemovePendingWritesForStream(stream->GetWeakPtr());
+  EXPECT_FALSE(queue.IsEmpty());
+
+  SpdyFrameType frame_type;
+  scoped_ptr<SpdyBufferProducer> producer;
+  base::WeakPtr<SpdyStream> weak_stream;
+
+  EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &weak_stream));
+  EXPECT_EQ(string(kRequeued), producer->ProduceBuffer()->GetRemainingData());
+}
+
 }  // namespace
 
 }  // namespace net
diff --git a/net/test/run_all_unittests.cc b/net/test/run_all_unittests.cc
index 1067c21..96e8a3c 100644
--- a/net/test/run_all_unittests.cc
+++ b/net/test/run_all_unittests.cc
@@ -13,8 +13,10 @@
 
 #if defined(OS_ANDROID)
 #include "base/android/jni_android.h"
+#include "base/android/jni_registrar.h"
 #include "base/test/test_file_util.h"
 #include "net/android/net_jni_registrar.h"
+#include "url/android/url_jni_registrar.h"
 #endif
 
 #if !defined(OS_IOS)
@@ -29,10 +31,18 @@
   base::StatisticsRecorder::Initialize();
 
 #if defined(OS_ANDROID)
+  const base::android::RegistrationMethod kNetTestRegisteredMethods[] = {
+    {"NetAndroid", net::android::RegisterJni},
+    {"TestFileUtil", file_util::RegisterContentUriTestUtils},
+    {"UrlAndroid", url::android::RegisterJni},
+  };
+
   // Register JNI bindings for android. Doing it early as the test suite setup
   // may initiate a call to Java.
-  net::android::RegisterJni(base::android::AttachCurrentThread());
-  file_util::RegisterContentUriTestUtils(base::android::AttachCurrentThread());
+  base::android::RegisterNativeMethods(
+      base::android::AttachCurrentThread(),
+      kNetTestRegisteredMethods,
+      arraysize(kNetTestRegisteredMethods));
 #endif
 
   NetTestSuite test_suite(argc, argv);
diff --git a/net/tools/flip_server/loadtime_measurement.h b/net/tools/flip_server/loadtime_measurement.h
index 84a8d3a..59fcc0b 100644
--- a/net/tools/flip_server/loadtime_measurement.h
+++ b/net/tools/flip_server/loadtime_measurement.h
@@ -15,6 +15,7 @@
 #include <string>
 #include <vector>
 
+#include "base/file_util.h"
 #include "base/strings/string_split.h"
 
 // Class to handle loadtime measure related urls, which all start with testing
@@ -28,7 +29,7 @@
                       const std::string& pageload_html_file)
       : num_urls_(0), pageload_html_file_(pageload_html_file) {
     std::string urls_string;
-    read_file_to_string(urls_file.c_str(), &urls_string);
+    base::ReadFileToString(urls_file, &urls_string);
     base::SplitString(urls_string, '\n', &urls_);
     num_urls_ = urls_.size();
   }
@@ -41,7 +42,7 @@
     // remove "/testing/" from uri to get the action
     std::string action = uri.substr(9);
     if (pageload_html_file_.find(action) != std::string::npos) {
-      read_file_to_string(pageload_html_file_.c_str(), &output);
+      base::ReadFileToString(pageload_html_file_, &output);
       return;
     }
     if (action.find("get_total_iteration") == 0) {
@@ -86,22 +87,6 @@
   }
 
  private:
-  void read_file_to_string(const char* filename, std::string* output) {
-    output->clear();
-    int fd = open(filename, 0, "r");
-    if (fd == -1)
-      return;
-    char buffer[4096];
-    ssize_t read_status = read(fd, buffer, sizeof(buffer));
-    while (read_status > 0) {
-      output->append(buffer, static_cast<size_t>(read_status));
-      do {
-        read_status = read(fd, buffer, sizeof(buffer));
-      } while (read_status <= 0 && errno == EINTR);
-    }
-    close(fd);
-  }
-
   int num_urls_;
   std::vector<std::string> urls_;
   std::map<std::string, int> loadtimes_;
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
index fc16af5..ef394b9 100644
--- a/net/tools/quic/end_to_end_test.cc
+++ b/net/tools/quic/end_to_end_test.cc
@@ -166,6 +166,9 @@
     if (negotiated_version_ >= QUIC_VERSION_17) {
       FLAGS_enable_quic_stream_flow_control_2 = true;
     }
+    if (negotiated_version_ >= QUIC_VERSION_19) {
+      FLAGS_enable_quic_connection_flow_control = true;
+    }
     VLOG(1) << "Using Configuration: " << GetParam();
 
     client_config_.SetDefaults();
@@ -471,7 +474,9 @@
   EXPECT_EQ(500u, client_->response_headers()->parsed_response_code());
 }
 
-TEST_P(EndToEndTest, LargePostNoPacketLoss) {
+// TODO(rtenneti): DISABLED_LargePostNoPacketLoss seems to be flaky.
+// http://crbug.com/297040.
+TEST_P(EndToEndTest, DISABLED_LargePostNoPacketLoss) {
   ASSERT_TRUE(Initialize());
 
   client_->client()->WaitForCryptoHandshakeConfirmed();
@@ -650,7 +655,9 @@
   VerifyCleanConnection(true);
 }
 
-TEST_P(EndToEndTest, LargePostLargeBuffer) {
+// TODO(rtenneti): DISABLED_LargePostLargeBuffer seems to be flaky.
+// http://crbug.com/370087.
+TEST_P(EndToEndTest, DISABLED_LargePostLargeBuffer) {
   ASSERT_TRUE(Initialize());
   SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
   // 1Mbit per second with a 128k buffer from server to client.  Wireless
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc
index c06eb60..b074a5d 100644
--- a/net/tools/quic/quic_dispatcher.cc
+++ b/net/tools/quic/quic_dispatcher.cc
@@ -170,6 +170,7 @@
       helper_(new QuicEpollConnectionHelper(epoll_server_)),
       supported_versions_(supported_versions),
       supported_versions_no_flow_control_(supported_versions),
+      supported_versions_no_connection_flow_control_(supported_versions),
       current_packet_(NULL),
       framer_(supported_versions, /*unused*/ QuicTime::Zero(), true),
       framer_visitor_(new QuicFramerVisitor(this)),
@@ -197,6 +198,18 @@
         supported_versions_no_flow_control_.begin(), it + 1);
   }
   CHECK(!supported_versions_no_flow_control_.empty());
+
+  // Remove all versions > QUIC_VERSION_18 from the
+  // supported_versions_no_connection_flow_control_ vector.
+  QuicVersionVector::iterator connection_it = find(
+      supported_versions_no_connection_flow_control_.begin(),
+      supported_versions_no_connection_flow_control_.end(), QUIC_VERSION_19);
+  if (connection_it != supported_versions_no_connection_flow_control_.end()) {
+    supported_versions_no_connection_flow_control_.erase(
+        supported_versions_no_connection_flow_control_.begin(),
+        connection_it + 1);
+  }
+  CHECK(!supported_versions_no_connection_flow_control_.empty());
 }
 
 void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address,
@@ -381,20 +394,29 @@
     const IPEndPoint& server_address,
     const IPEndPoint& client_address,
     uint32 initial_flow_control_window) {
-  // If we have disabled per-stream flow control, then don't allow new
-  // connections to talk QUIC_VERSION_17 or higher.
-  if (FLAGS_enable_quic_stream_flow_control_2) {
+  if (FLAGS_enable_quic_stream_flow_control_2 &&
+      FLAGS_enable_quic_connection_flow_control) {
+    DLOG(INFO) << "Creating QuicDispatcher with all versions.";
     return new QuicConnection(connection_id, client_address, helper_.get(),
                               writer_.get(), true, supported_versions_,
                               initial_flow_control_window_bytes_);
-  } else {
-    DVLOG(1)
-        << "Flow control disabled, creating QuicDispatcher WITHOUT version 17";
+  }
+
+  if (FLAGS_enable_quic_stream_flow_control_2 &&
+      !FLAGS_enable_quic_connection_flow_control) {
+    DLOG(INFO) << "Connection flow control disabled, creating QuicDispatcher "
+               << "WITHOUT version 19 or higher.";
     return new QuicConnection(connection_id, client_address, helper_.get(),
                               writer_.get(), true,
-                              supported_versions_no_flow_control_,
+                              supported_versions_no_connection_flow_control_,
                               initial_flow_control_window_bytes_);
   }
+
+  DLOG(INFO) << "Flow control disabled, creating QuicDispatcher WITHOUT "
+             << "version 17 or higher.";
+  return new QuicConnection(
+      connection_id, client_address, helper_.get(), writer_.get(), true,
+      supported_versions_no_flow_control_, initial_flow_control_window_bytes_);
 }
 
 QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() {
diff --git a/net/tools/quic/quic_dispatcher.h b/net/tools/quic/quic_dispatcher.h
index aaed3ab..fbb2f40 100644
--- a/net/tools/quic/quic_dispatcher.h
+++ b/net/tools/quic/quic_dispatcher.h
@@ -143,6 +143,11 @@
     return supported_versions_no_flow_control_;
   }
 
+  const QuicVersionVector& supported_versions_no_connection_flow_control()
+      const {
+    return supported_versions_no_connection_flow_control_;
+  }
+
   const IPEndPoint& current_server_address() {
     return current_server_address_;
   }
@@ -219,6 +224,13 @@
   // TODO(rjshade): Remove this when
   // FLAGS_enable_quic_stream_flow_control_2 is removed.
   QuicVersionVector supported_versions_no_flow_control_;
+  // Versions which do not support *connection* flow control (introduced in
+  // QUIC_VERSION_19).
+  // This is used to construct new QuicConnections when connection flow control
+  // is disabled via flag.
+  // TODO(rjshade): Remove this when
+  // FLAGS_enable_quic_connection_flow_control is removed.
+  QuicVersionVector supported_versions_no_connection_flow_control_;
 
   // Information about the packet currently being handled.
   IPEndPoint current_client_address_;
diff --git a/net/url_request/url_fetcher.h b/net/url_request/url_fetcher.h
index a831819..415d7e5 100644
--- a/net/url_request/url_fetcher.h
+++ b/net/url_request/url_fetcher.h
@@ -37,8 +37,9 @@
 
 // To use this class, create an instance with the desired URL and a pointer to
 // the object to be notified when the URL has been loaded:
-//   URLFetcher* fetcher = URLFetcher::Create("http://www.google.com",
-//                                            URLFetcher::GET, this);
+//   scoped_ptr<URLFetcher> fetcher(URLFetcher::Create("http://www.google.com",
+//                                                     URLFetcher::GET,
+//                                                     this));
 //
 // You must also set a request context getter:
 //
@@ -51,6 +52,8 @@
 // Finally, start the request:
 //   fetcher->Start();
 //
+// You may cancel the request by destroying the URLFetcher:
+//   fetcher.reset();
 //
 // The object you supply as a delegate must inherit from
 // URLFetcherDelegate; when the fetch is completed,
@@ -94,6 +97,7 @@
   // |url| is the URL to send the request to.
   // |request_type| is the type of request to make.
   // |d| the object that will receive the callback on fetch completion.
+  // Caller is responsible for destroying the returned URLFetcher.
   static URLFetcher* Create(const GURL& url,
                             URLFetcher::RequestType request_type,
                             URLFetcherDelegate* d);
@@ -101,6 +105,7 @@
   // Like above, but if there's a URLFetcherFactory registered with the
   // implementation it will be used. |id| may be used during testing to identify
   // who is creating the URLFetcher.
+  // Caller is responsible for destroying the returned URLFetcher.
   static URLFetcher* Create(int id,
                             const GURL& url,
                             URLFetcher::RequestType request_type,
@@ -281,7 +286,7 @@
   // if an error prevented any response from being received.
   virtual int GetResponseCode() const = 0;
 
-  // Cookies recieved.
+  // Cookies received.
   virtual const ResponseCookies& GetCookies() const = 0;
 
   // Reports that the received content was malformed.
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index 97308b5..e2784ee 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -1065,13 +1065,11 @@
   const GURL& url = this->url();
   if (!url.SchemeIs("http"))
     return false;
-  TransportSecurityState::DomainState domain_state;
-  if (context()->transport_security_state() &&
-      context()->transport_security_state()->GetDomainState(
+  TransportSecurityState* state = context()->transport_security_state();
+  if (state &&
+      state->ShouldUpgradeToSSL(
           url.host(),
-          SSLConfigService::IsSNIAvailable(context()->ssl_config_service()),
-          &domain_state) &&
-      domain_state.ShouldUpgradeToSSL()) {
+          SSLConfigService::IsSNIAvailable(context()->ssl_config_service()))) {
     url::Replacements<char> replacements;
     const char kNewScheme[] = "https";
     replacements.SetScheme(kNewScheme, url::Component(0, strlen(kNewScheme)));
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index ca92f74..8314f32 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -28,13 +28,19 @@
 #include "net/proxy/proxy_service.h"
 #include "net/ssl/ssl_config_service_defaults.h"
 #include "net/url_request/data_protocol_handler.h"
-#include "net/url_request/file_protocol_handler.h"
-#include "net/url_request/ftp_protocol_handler.h"
 #include "net/url_request/static_http_user_agent_settings.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_storage.h"
 #include "net/url_request/url_request_job_factory_impl.h"
 
+#if !defined(DISABLE_FILE_SUPPORT)
+#include "net/url_request/file_protocol_handler.h"
+#endif
+
+#if !defined(DISABLE_FTP_SUPPORT)
+#include "net/url_request/ftp_protocol_handler.h"
+#endif
+
 namespace net {
 
 namespace {
@@ -176,9 +182,20 @@
 URLRequestContextBuilder::HttpNetworkSessionParams::~HttpNetworkSessionParams()
 {}
 
+URLRequestContextBuilder::SchemeFactory::SchemeFactory(
+    const std::string& auth_scheme,
+    net::HttpAuthHandlerFactory* auth_handler_factory)
+    : scheme(auth_scheme), factory(auth_handler_factory) {
+}
+
+URLRequestContextBuilder::SchemeFactory::~SchemeFactory() {
+}
+
 URLRequestContextBuilder::URLRequestContextBuilder()
     : data_enabled_(false),
+#if !defined(DISABLE_FILE_SUPPORT)
       file_enabled_(false),
+#endif
 #if !defined(DISABLE_FTP_SUPPORT)
       ftp_enabled_(false),
 #endif
@@ -231,9 +248,15 @@
           4,  // TODO(willchan): Find a better constant somewhere.
           context->net_log()));
   storage->set_ssl_config_service(new net::SSLConfigServiceDefaults);
-  storage->set_http_auth_handler_factory(
+  HttpAuthHandlerRegistryFactory* http_auth_handler_registry_factory =
       net::HttpAuthHandlerRegistryFactory::CreateDefault(
-          context->host_resolver()));
+           context->host_resolver());
+  for (size_t i = 0; i < extra_http_auth_handlers_.size(); ++i) {
+    http_auth_handler_registry_factory->RegisterSchemeFactory(
+        extra_http_auth_handlers_[i].scheme,
+        extra_http_auth_handlers_[i].factory);
+  }
+  storage->set_http_auth_handler_factory(http_auth_handler_registry_factory);
   storage->set_cookie_store(new CookieMonster(NULL, NULL));
   storage->set_transport_security_state(new net::TransportSecurityState());
   storage->set_http_server_properties(
@@ -298,11 +321,15 @@
   URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl;
   if (data_enabled_)
     job_factory->SetProtocolHandler("data", new DataProtocolHandler);
+
+#if !defined(DISABLE_FILE_SUPPORT)
   if (file_enabled_) {
     job_factory->SetProtocolHandler(
     "file",
     new FileProtocolHandler(context->GetFileThread()->message_loop_proxy()));
   }
+#endif  // !defined(DISABLE_FILE_SUPPORT)
+
 #if !defined(DISABLE_FTP_SUPPORT)
   if (ftp_enabled_) {
     ftp_transaction_factory_.reset(
@@ -310,7 +337,8 @@
     job_factory->SetProtocolHandler("ftp",
         new FtpProtocolHandler(ftp_transaction_factory_.get()));
   }
-#endif
+#endif  // !defined(DISABLE_FTP_SUPPORT)
+
   storage->set_job_factory(job_factory);
 
   // TODO(willchan): Support sdch.
diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h
index 2ad03ee..41db45a 100644
--- a/net/url_request/url_request_context_builder.h
+++ b/net/url_request/url_request_context_builder.h
@@ -15,6 +15,7 @@
 #define NET_URL_REQUEST_URL_REQUEST_CONTEXT_BUILDER_H_
 
 #include <string>
+#include <vector>
 
 #include "base/basictypes.h"
 #include "base/files/file_path.h"
@@ -28,6 +29,7 @@
 class FtpTransactionFactory;
 class HostResolver;
 class HostMappingRules;
+class HttpAuthHandlerFactory;
 class ProxyConfigService;
 class URLRequestContext;
 class NetworkDelegate;
@@ -87,10 +89,12 @@
     data_enabled_ = enable;
   }
 
+#if !defined(DISABLE_FILE_SUPPORT)
   // Control support for file:// requests. By default it's disabled.
   void set_file_enabled(bool enable) {
     file_enabled_ = enable;
   }
+#endif
 
 #if !defined(DISABLE_FTP_SUPPORT)
   // Control support for ftp:// requests. By default it's disabled.
@@ -111,6 +115,16 @@
     network_delegate_.reset(delegate);
   }
 
+
+  // Adds additional auth handler factories to be used in addition to what is
+  // provided in the default |HttpAuthHandlerRegistryFactory|. The auth |scheme|
+  // and |factory| are provided. The builder takes ownership of the factory and
+  // Build() must be called after this method.
+  void add_http_auth_handler_factory(const std::string& scheme,
+                                     net::HttpAuthHandlerFactory* factory) {
+    extra_http_auth_handlers_.push_back(SchemeFactory(scheme, factory));
+  }
+
   // By default HttpCache is enabled with a default constructed HttpCacheParams.
   void EnableHttpCache(const HttpCacheParams& params) {
     http_cache_enabled_ = true;
@@ -131,12 +145,24 @@
   URLRequestContext* Build();
 
  private:
+
+  struct SchemeFactory {
+    SchemeFactory(const std::string& scheme,
+                  net::HttpAuthHandlerFactory* factory);
+    ~SchemeFactory();
+
+    std::string scheme;
+    net::HttpAuthHandlerFactory* factory;
+  };
+
   std::string accept_language_;
   std::string user_agent_;
   // Include support for data:// requests.
   bool data_enabled_;
+#if !defined(DISABLE_FILE_SUPPORT)
   // Include support for file:// requests.
   bool file_enabled_;
+#endif
 #if !defined(DISABLE_FTP_SUPPORT)
   // Include support for ftp:// requests.
   bool ftp_enabled_;
@@ -148,6 +174,7 @@
   scoped_ptr<ProxyConfigService> proxy_config_service_;
   scoped_ptr<NetworkDelegate> network_delegate_;
   scoped_ptr<FtpTransactionFactory> ftp_transaction_factory_;
+  std::vector<SchemeFactory> extra_http_auth_handlers_;
 
   DISALLOW_COPY_AND_ASSIGN(URLRequestContextBuilder);
 };
diff --git a/net/url_request/url_request_context_builder_unittest.cc b/net/url_request/url_request_context_builder_unittest.cc
index e882253..a7a0fee 100644
--- a/net/url_request/url_request_context_builder_unittest.cc
+++ b/net/url_request/url_request_context_builder_unittest.cc
@@ -6,6 +6,8 @@
 
 #include "build/build_config.h"
 #include "net/base/request_priority.h"
+#include "net/http/http_auth_handler.h"
+#include "net/http/http_auth_handler_factory.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_test_util.h"
@@ -36,6 +38,27 @@
                           base::FilePath()) {}
 };
 
+class MockHttpAuthHandlerFactory : public HttpAuthHandlerFactory {
+ public:
+  explicit MockHttpAuthHandlerFactory(int return_code) :
+      return_code_(return_code) {}
+  virtual ~MockHttpAuthHandlerFactory() {}
+
+  virtual int CreateAuthHandler(HttpAuthChallengeTokenizer* challenge,
+                                HttpAuth::Target target,
+                                const GURL& origin,
+                                CreateReason reason,
+                                int nonce_count,
+                                const BoundNetLog& net_log,
+                                scoped_ptr<HttpAuthHandler>* handler) OVERRIDE {
+    handler->reset();
+    return return_code_;
+  }
+
+ private:
+  int return_code_;
+};
+
 class URLRequestContextBuilderTest : public PlatformTest {
  protected:
   URLRequestContextBuilderTest()
@@ -83,6 +106,28 @@
   EXPECT_EQ("Bar", delegate.data_received());
 }
 
+TEST_F(URLRequestContextBuilderTest, ExtraHttpAuthHandlerFactory) {
+  GURL gurl("www.google.com");
+  const int kBasicReturnCode = net::OK;
+  MockHttpAuthHandlerFactory* mock_factory_basic =
+      new MockHttpAuthHandlerFactory(kBasicReturnCode);
+  scoped_ptr<HttpAuthHandler> handler;
+  builder_.add_http_auth_handler_factory("ExtraScheme", mock_factory_basic);
+  scoped_ptr<URLRequestContext> context(builder_.Build());
+  // Verify that a handler is returned for and added scheme.
+  EXPECT_EQ(kBasicReturnCode,
+            context->http_auth_handler_factory()->CreateAuthHandlerFromString(
+                "ExtraScheme",
+                HttpAuth::AUTH_SERVER,
+                gurl,
+                BoundNetLog(),
+                &handler));
+  // Verify that a handler isn't returned for a bogus scheme.
+  EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME,
+            context->http_auth_handler_factory()->CreateAuthHandlerFromString(
+                "Bogus", HttpAuth::AUTH_SERVER, gurl, BoundNetLog(), &handler));
+}
+
 }  // namespace
 
 }  // namespace net
diff --git a/net/url_request/url_request_file_job.cc b/net/url_request/url_request_file_job.cc
index 011a0da..74e6131 100644
--- a/net/url_request/url_request_file_job.cc
+++ b/net/url_request/url_request_file_job.cc
@@ -294,18 +294,20 @@
 }
 
 void URLRequestFileJob::DidRead(scoped_refptr<net::IOBuffer> buf, int result) {
-  OnReadComplete(buf.get(), result);
-  buf = NULL;
   if (result > 0) {
     SetStatus(URLRequestStatus());  // Clear the IO_PENDING status
-  } else if (result == 0) {
-    NotifyDone(URLRequestStatus());
-  } else {
-    NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result));
+    remaining_bytes_ -= result;
+    DCHECK_GE(remaining_bytes_, 0);
   }
 
-  remaining_bytes_ -= result;
-  DCHECK_GE(remaining_bytes_, 0);
+  OnReadComplete(buf.get(), result);
+  buf = NULL;
+
+  if (result == 0) {
+    NotifyDone(URLRequestStatus());
+  } else if (result < 0) {
+    NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result));
+  }
 
   NotifyReadComplete(result);
 }
diff --git a/net/url_request/url_request_file_job.h b/net/url_request/url_request_file_job.h
index 3af83f5..15c1e4d 100644
--- a/net/url_request/url_request_file_job.h
+++ b/net/url_request/url_request_file_job.h
@@ -55,6 +55,8 @@
  protected:
   virtual ~URLRequestFileJob();
 
+  int64 remaining_bytes() const { return remaining_bytes_; }
+
   // The OS-specific full path name of the file
   base::FilePath file_path_;
 
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index c5c209c..e3e84d3 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -841,14 +841,13 @@
       NotifySSLCertificateError(info, true);
     } else {
       // Maybe overridable, maybe not. Ask the delegate to decide.
-      TransportSecurityState::DomainState domain_state;
       const URLRequestContext* context = request_->context();
-      const bool fatal = context->transport_security_state() &&
-          context->transport_security_state()->GetDomainState(
+      TransportSecurityState* state = context->transport_security_state();
+      const bool fatal =
+          state &&
+          state->ShouldSSLErrorsBeFatal(
               request_info_.url.host(),
-              SSLConfigService::IsSNIAvailable(context->ssl_config_service()),
-              &domain_state) &&
-          domain_state.ShouldSSLErrorsBeFatal();
+              SSLConfigService::IsSNIAvailable(context->ssl_config_service()));
       NotifySSLCertificateError(
           transaction_->GetResponseInfo()->ssl_info, fatal);
     }
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index 31a0d50..d2fa685 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -541,132 +541,124 @@
 }
 
 void URLRequestJob::FilteredDataRead(int bytes_read) {
-  DCHECK(filter_.get());  // don't add data if there is no filter
+  DCHECK(filter_);
   filter_->FlushStreamBuffer(bytes_read);
 }
 
 bool URLRequestJob::ReadFilteredData(int* bytes_read) {
-  DCHECK(filter_.get());  // don't add data if there is no filter
-  DCHECK(filtered_read_buffer_.get() !=
-         NULL);                             // we need to have a buffer to fill
-  DCHECK_GT(filtered_read_buffer_len_, 0);  // sanity check
-  DCHECK_LT(filtered_read_buffer_len_, 1000000);  // sanity check
-  DCHECK(raw_read_buffer_.get() ==
-         NULL);  // there should be no raw read buffer yet
+  DCHECK(filter_);
+  DCHECK(filtered_read_buffer_);
+  DCHECK_GT(filtered_read_buffer_len_, 0);
+  DCHECK_LT(filtered_read_buffer_len_, 1000000);  // Sanity check.
+  DCHECK(!raw_read_buffer_);
 
-  bool rv = false;
   *bytes_read = 0;
+  bool rv = false;
 
-  if (is_done())
-    return true;
+  for (;;) {
+    if (is_done())
+      return true;
 
-  if (!filter_needs_more_output_space_ && !filter_->stream_data_len()) {
-    // We don't have any raw data to work with, so
-    // read from the socket.
-    int filtered_data_read;
-    if (ReadRawDataForFilter(&filtered_data_read)) {
-      if (filtered_data_read > 0) {
-        filter_->FlushStreamBuffer(filtered_data_read);  // Give data to filter.
+    if (!filter_needs_more_output_space_ && !filter_->stream_data_len()) {
+      // We don't have any raw data to work with, so read from the transaction.
+      int filtered_data_read;
+      if (ReadRawDataForFilter(&filtered_data_read)) {
+        if (filtered_data_read > 0) {
+          // Give data to filter.
+          filter_->FlushStreamBuffer(filtered_data_read);
+        } else {
+          return true;  // EOF.
+        }
       } else {
-        return true;  // EOF
+        return false;  // IO Pending (or error).
       }
-    } else {
-      return false;  // IO Pending (or error)
-    }
-  }
-
-  if ((filter_->stream_data_len() || filter_needs_more_output_space_)
-      && !is_done()) {
-    // Get filtered data.
-    int filtered_data_len = filtered_read_buffer_len_;
-    Filter::FilterStatus status;
-    int output_buffer_size = filtered_data_len;
-    status = filter_->ReadData(filtered_read_buffer_->data(),
-                               &filtered_data_len);
-
-    if (filter_needs_more_output_space_ && 0 == filtered_data_len) {
-      // filter_needs_more_output_space_ was mistaken... there are no more bytes
-      // and we should have at least tried to fill up the filter's input buffer.
-      // Correct the state, and try again.
-      filter_needs_more_output_space_ = false;
-      return ReadFilteredData(bytes_read);
     }
 
-    switch (status) {
-      case Filter::FILTER_DONE: {
+    if ((filter_->stream_data_len() || filter_needs_more_output_space_) &&
+        !is_done()) {
+      // Get filtered data.
+      int filtered_data_len = filtered_read_buffer_len_;
+      int output_buffer_size = filtered_data_len;
+      Filter::FilterStatus status =
+          filter_->ReadData(filtered_read_buffer_->data(), &filtered_data_len);
+
+      if (filter_needs_more_output_space_ && !filtered_data_len) {
+        // filter_needs_more_output_space_ was mistaken... there are no more
+        // bytes and we should have at least tried to fill up the filter's input
+        // buffer. Correct the state, and try again.
         filter_needs_more_output_space_ = false;
-        *bytes_read = filtered_data_len;
-        postfilter_bytes_read_ += filtered_data_len;
-        rv = true;
-        break;
+        continue;
       }
-      case Filter::FILTER_NEED_MORE_DATA: {
-        filter_needs_more_output_space_ =
-            (filtered_data_len == output_buffer_size);
-        // We have finished filtering all data currently in the buffer.
-        // There might be some space left in the output buffer. One can
-        // consider reading more data from the stream to feed the filter
-        // and filling up the output buffer. This leads to more complicated
-        // buffer management and data notification mechanisms.
-        // We can revisit this issue if there is a real perf need.
-        if (filtered_data_len > 0) {
+      filter_needs_more_output_space_ =
+          (filtered_data_len == output_buffer_size);
+
+      switch (status) {
+        case Filter::FILTER_DONE: {
+          filter_needs_more_output_space_ = false;
           *bytes_read = filtered_data_len;
           postfilter_bytes_read_ += filtered_data_len;
           rv = true;
-        } else {
-          // Read again since we haven't received enough data yet (e.g., we may
-          // not have a complete gzip header yet)
-          rv = ReadFilteredData(bytes_read);
+          break;
         }
-        break;
+        case Filter::FILTER_NEED_MORE_DATA: {
+          // We have finished filtering all data currently in the buffer.
+          // There might be some space left in the output buffer. One can
+          // consider reading more data from the stream to feed the filter
+          // and filling up the output buffer. This leads to more complicated
+          // buffer management and data notification mechanisms.
+          // We can revisit this issue if there is a real perf need.
+          if (filtered_data_len > 0) {
+            *bytes_read = filtered_data_len;
+            postfilter_bytes_read_ += filtered_data_len;
+            rv = true;
+          } else {
+            // Read again since we haven't received enough data yet (e.g., we
+            // may not have a complete gzip header yet).
+            continue;
+          }
+          break;
+        }
+        case Filter::FILTER_OK: {
+          *bytes_read = filtered_data_len;
+          postfilter_bytes_read_ += filtered_data_len;
+          rv = true;
+          break;
+        }
+        case Filter::FILTER_ERROR: {
+          DVLOG(1) << __FUNCTION__ << "() "
+                   << "\"" << (request_ ? request_->url().spec() : "???")
+                   << "\"" << " Filter Error";
+          filter_needs_more_output_space_ = false;
+          NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
+                     ERR_CONTENT_DECODING_FAILED));
+          rv = false;
+          break;
+        }
+        default: {
+          NOTREACHED();
+          filter_needs_more_output_space_ = false;
+          rv = false;
+          break;
+        }
       }
-      case Filter::FILTER_OK: {
-        filter_needs_more_output_space_ =
-            (filtered_data_len == output_buffer_size);
-        *bytes_read = filtered_data_len;
-        postfilter_bytes_read_ += filtered_data_len;
-        rv = true;
-        break;
+
+      // If logging all bytes is enabled, log the filtered bytes read.
+      if (rv && request() && request()->net_log().IsLoggingBytes() &&
+          filtered_data_len > 0) {
+        request()->net_log().AddByteTransferEvent(
+            NetLog::TYPE_URL_REQUEST_JOB_FILTERED_BYTES_READ,
+            filtered_data_len, filtered_read_buffer_->data());
       }
-      case Filter::FILTER_ERROR: {
-        DVLOG(1) << __FUNCTION__ << "() "
-                 << "\"" << (request_ ? request_->url().spec() : "???") << "\""
-                 << " Filter Error";
-        filter_needs_more_output_space_ = false;
-        NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
-                   ERR_CONTENT_DECODING_FAILED));
-        rv = false;
-        break;
-      }
-      default: {
-        NOTREACHED();
-        filter_needs_more_output_space_ = false;
-        rv = false;
-        break;
-      }
+    } else {
+      // we are done, or there is no data left.
+      rv = true;
     }
-    DVLOG(2) << __FUNCTION__ << "() "
-             << "\"" << (request_ ? request_->url().spec() : "???") << "\""
-             << " rv = " << rv
-             << " post bytes read = " << filtered_data_len
-             << " pre total = " << prefilter_bytes_read_
-             << " post total = "
-             << postfilter_bytes_read_;
-    // If logging all bytes is enabled, log the filtered bytes read.
-    if (rv && request() && request()->net_log().IsLoggingBytes() &&
-        filtered_data_len > 0) {
-      request()->net_log().AddByteTransferEvent(
-          NetLog::TYPE_URL_REQUEST_JOB_FILTERED_BYTES_READ,
-          filtered_data_len, filtered_read_buffer_->data());
-    }
-  } else {
-    // we are done, or there is no data left.
-    rv = true;
+    break;
   }
 
   if (rv) {
-    // When we successfully finished a read, we no longer need to
-    // save the caller's buffers. Release our reference.
+    // When we successfully finished a read, we no longer need to save the
+    // caller's buffers. Release our reference.
     filtered_read_buffer_ = NULL;
     filtered_read_buffer_len_ = 0;
   }
diff --git a/net/url_request/url_request_job_unittest.cc b/net/url_request/url_request_job_unittest.cc
index c8bbc19..d90fc9b 100644
--- a/net/url_request/url_request_job_unittest.cc
+++ b/net/url_request/url_request_job_unittest.cc
@@ -15,13 +15,23 @@
 namespace {
 
 // This is a header that signals the end of the data.
-const char kGzipGata[] = "\x1f\x08b\x08\0\0\0\0\0\0\3\3\0\0\0\0\0\0\0\0";
+const char kGzipData[] = "\x1f\x08b\x08\0\0\0\0\0\0\3\3\0\0\0\0\0\0\0\0";
+const char kGzipDataWithName[] =
+    "\x1f\x08b\x08\x08\0\0\0\0\0\0name\0\3\0\0\0\0\0\0\0\0";
 
 void GZipServer(const HttpRequestInfo* request,
                 std::string* response_status,
                 std::string* response_headers,
                 std::string* response_data) {
-  response_data->assign(kGzipGata, sizeof(kGzipGata));
+  response_data->assign(kGzipData, sizeof(kGzipData));
+}
+
+void BigGZipServer(const HttpRequestInfo* request,
+                   std::string* response_status,
+                   std::string* response_headers,
+                   std::string* response_data) {
+  response_data->assign(kGzipDataWithName, sizeof(kGzipDataWithName));
+  response_data->insert(10, 64 * 1024, 'a');
 }
 
 const MockTransaction kGZip_Transaction = {
@@ -104,6 +114,30 @@
   RemoveMockTransaction(&transaction);
 }
 
+// Tests processing a large gzip header one byte at a time.
+TEST(URLRequestJob, SyncSlowTransaction) {
+  MockNetworkLayer network_layer;
+  TestURLRequestContext context;
+  context.set_http_transaction_factory(&network_layer);
+
+  TestDelegate d;
+  TestURLRequest req(
+      GURL(kGZip_Transaction.url), DEFAULT_PRIORITY, &d, &context);
+  MockTransaction transaction(kGZip_Transaction);
+  transaction.test_mode = TEST_MODE_SYNC_ALL | TEST_MODE_SLOW_READ;
+  transaction.handler = &BigGZipServer;
+  AddMockTransaction(&transaction);
+
+  req.set_method("GET");
+  req.Start();
+
+  base::RunLoop().Run();
+
+  EXPECT_TRUE(network_layer.done_reading_called());
+
+  RemoveMockTransaction(&transaction);
+}
+
 TEST(URLRequestJob, RedirectTransactionNotifiedWhenDone) {
   MockNetworkLayer network_layer;
   TestURLRequestContext context;
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 97d3622..7a526a3 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -66,11 +66,8 @@
 #include "net/test/cert_test_util.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
 #include "net/url_request/data_protocol_handler.h"
-#include "net/url_request/file_protocol_handler.h"
-#include "net/url_request/ftp_protocol_handler.h"
 #include "net/url_request/static_http_user_agent_settings.h"
 #include "net/url_request/url_request.h"
-#include "net/url_request/url_request_file_dir_job.h"
 #include "net/url_request/url_request_http_job.h"
 #include "net/url_request/url_request_job_factory_impl.h"
 #include "net/url_request/url_request_redirect_job.h"
@@ -79,6 +76,15 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
+#if !defined(DISABLE_FILE_SUPPORT)
+#include "net/url_request/file_protocol_handler.h"
+#include "net/url_request/url_request_file_dir_job.h"
+#endif
+
+#if !defined(DISABLE_FTP_SUPPORT)
+#include "net/url_request/ftp_protocol_handler.h"
+#endif
+
 #if defined(OS_WIN)
 #include "base/win/scoped_com_initializer.h"
 #include "base/win/scoped_comptr.h"
@@ -598,8 +604,10 @@
     default_context_.set_network_delegate(&default_network_delegate_);
     default_context_.set_net_log(&net_log_);
     job_factory_.SetProtocolHandler("data", new DataProtocolHandler);
+#if !defined(DISABLE_FILE_SUPPORT)
     job_factory_.SetProtocolHandler(
         "file", new FileProtocolHandler(base::MessageLoopProxy::current()));
+#endif
     default_context_.set_job_factory(&job_factory_);
     default_context_.Init();
   }
@@ -4960,14 +4968,13 @@
 
   TransportSecurityState* security_state =
       default_context_.transport_security_state();
-  bool sni_available = true;
   TransportSecurityState::DomainState domain_state;
-  EXPECT_TRUE(security_state->GetDomainState(
-      SpawnedTestServer::kLocalhost, sni_available, &domain_state));
+  EXPECT_TRUE(security_state->GetDynamicDomainState(
+      SpawnedTestServer::kLocalhost, &domain_state));
   EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS,
-            domain_state.upgrade_mode);
-  EXPECT_TRUE(domain_state.sts_include_subdomains);
-  EXPECT_FALSE(domain_state.pkp_include_subdomains);
+            domain_state.sts.upgrade_mode);
+  EXPECT_TRUE(domain_state.sts.include_subdomains);
+  EXPECT_FALSE(domain_state.pkp.include_subdomains);
 #if defined(OS_ANDROID)
   // Android's CertVerifyProc does not (yet) handle pins.
 #else
@@ -5004,17 +5011,15 @@
 
   TransportSecurityState* security_state =
       default_context_.transport_security_state();
-  bool sni_available = true;
   TransportSecurityState::DomainState domain_state;
-  EXPECT_TRUE(security_state->GetDomainState(
-      SpawnedTestServer::kLocalhost, sni_available, &domain_state));
+  EXPECT_TRUE(security_state->GetDynamicDomainState(
+      SpawnedTestServer::kLocalhost, &domain_state));
   EXPECT_EQ(TransportSecurityState::DomainState::MODE_DEFAULT,
-            domain_state.upgrade_mode);
-  EXPECT_FALSE(domain_state.sts_include_subdomains);
-  EXPECT_FALSE(domain_state.pkp_include_subdomains);
+            domain_state.sts.upgrade_mode);
+  EXPECT_FALSE(domain_state.sts.include_subdomains);
+  EXPECT_FALSE(domain_state.pkp.include_subdomains);
   EXPECT_TRUE(domain_state.HasPublicKeyPins());
-  EXPECT_NE(domain_state.upgrade_expiry,
-            domain_state.dynamic_spki_hashes_expiry);
+  EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry);
 }
 
 TEST_F(URLRequestTestHTTP, ProcessSTSOnce) {
@@ -5037,14 +5042,13 @@
   // We should have set parameters from the first header, not the second.
   TransportSecurityState* security_state =
       default_context_.transport_security_state();
-  bool sni_available = true;
   TransportSecurityState::DomainState domain_state;
-  EXPECT_TRUE(security_state->GetDomainState(
-      SpawnedTestServer::kLocalhost, sni_available, &domain_state));
+  EXPECT_TRUE(security_state->GetDynamicDomainState(
+      SpawnedTestServer::kLocalhost, &domain_state));
   EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS,
-            domain_state.upgrade_mode);
-  EXPECT_FALSE(domain_state.sts_include_subdomains);
-  EXPECT_FALSE(domain_state.pkp_include_subdomains);
+            domain_state.sts.upgrade_mode);
+  EXPECT_FALSE(domain_state.sts.include_subdomains);
+  EXPECT_FALSE(domain_state.pkp.include_subdomains);
 }
 
 TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP) {
@@ -5067,25 +5071,23 @@
   // We should have set parameters from the first header, not the second.
   TransportSecurityState* security_state =
       default_context_.transport_security_state();
-  bool sni_available = true;
   TransportSecurityState::DomainState domain_state;
-  EXPECT_TRUE(security_state->GetDomainState(
-      SpawnedTestServer::kLocalhost, sni_available, &domain_state));
+  EXPECT_TRUE(security_state->GetDynamicDomainState(
+      SpawnedTestServer::kLocalhost, &domain_state));
   EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS,
-            domain_state.upgrade_mode);
+            domain_state.sts.upgrade_mode);
 #if defined(OS_ANDROID)
   // Android's CertVerifyProc does not (yet) handle pins.
 #else
   EXPECT_TRUE(domain_state.HasPublicKeyPins());
 #endif
-  EXPECT_NE(domain_state.upgrade_expiry,
-            domain_state.dynamic_spki_hashes_expiry);
+  EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry);
 
   // Even though there is an HSTS header asserting includeSubdomains, it is
   // the *second* such header, and we MUST process only the first.
-  EXPECT_FALSE(domain_state.sts_include_subdomains);
+  EXPECT_FALSE(domain_state.sts.include_subdomains);
   // includeSubdomains does not occur in the test HPKP header.
-  EXPECT_FALSE(domain_state.pkp_include_subdomains);
+  EXPECT_FALSE(domain_state.pkp.include_subdomains);
 }
 
 // Tests that when multiple HPKP headers are present, asserting different
@@ -5109,22 +5111,20 @@
 
   TransportSecurityState* security_state =
       default_context_.transport_security_state();
-  bool sni_available = true;
   TransportSecurityState::DomainState domain_state;
-  EXPECT_TRUE(security_state->GetDomainState(
-      SpawnedTestServer::kLocalhost, sni_available, &domain_state));
+  EXPECT_TRUE(security_state->GetDynamicDomainState(
+      SpawnedTestServer::kLocalhost, &domain_state));
   EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS,
-            domain_state.upgrade_mode);
+            domain_state.sts.upgrade_mode);
 #if defined(OS_ANDROID)
   // Android's CertVerifyProc does not (yet) handle pins.
 #else
   EXPECT_TRUE(domain_state.HasPublicKeyPins());
 #endif
-  EXPECT_NE(domain_state.upgrade_expiry,
-            domain_state.dynamic_spki_hashes_expiry);
+  EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry);
 
-  EXPECT_TRUE(domain_state.sts_include_subdomains);
-  EXPECT_FALSE(domain_state.pkp_include_subdomains);
+  EXPECT_TRUE(domain_state.sts.include_subdomains);
+  EXPECT_FALSE(domain_state.pkp.include_subdomains);
 }
 
 TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) {
@@ -5148,20 +5148,27 @@
   req.Cancel();
 }
 
-TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictRedirects) {
+TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictDataRedirects) {
   // Test URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget().
-  GURL file_url("file:///foo.txt");
   GURL data_url("data:,foo");
-  FileProtocolHandler file_protocol_handler(base::MessageLoopProxy::current());
-  EXPECT_FALSE(file_protocol_handler.IsSafeRedirectTarget(file_url));
   DataProtocolHandler data_protocol_handler;
   EXPECT_FALSE(data_protocol_handler.IsSafeRedirectTarget(data_url));
 
   // Test URLRequestJobFactoryImpl::IsSafeRedirectTarget().
-  EXPECT_FALSE(job_factory_.IsSafeRedirectTarget(file_url));
   EXPECT_FALSE(job_factory_.IsSafeRedirectTarget(data_url));
 }
 
+#if !defined(DISABLE_FILE_SUPPORT)
+TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictFileRedirects) {
+  // Test URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget().
+  GURL file_url("file:///foo.txt");
+  FileProtocolHandler file_protocol_handler(base::MessageLoopProxy::current());
+  EXPECT_FALSE(file_protocol_handler.IsSafeRedirectTarget(file_url));
+
+  // Test URLRequestJobFactoryImpl::IsSafeRedirectTarget().
+  EXPECT_FALSE(job_factory_.IsSafeRedirectTarget(file_url));
+}
+
 TEST_F(URLRequestTestHTTP, RestrictFileRedirects) {
   ASSERT_TRUE(test_server_.Start());
 
@@ -5176,6 +5183,7 @@
   EXPECT_EQ(URLRequestStatus::FAILED, req.status().status());
   EXPECT_EQ(ERR_UNSAFE_REDIRECT, req.status().error());
 }
+#endif  // !defined(DISABLE_FILE_SUPPORT)
 
 TEST_F(URLRequestTestHTTP, RestrictDataRedirects) {
   ASSERT_TRUE(test_server_.Start());
@@ -6662,11 +6670,10 @@
       base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
   ASSERT_TRUE(test_server.Start());
 
-  // We require that the URL be www.google.com in order to pick up the
-  // preloaded and dynamic HSTS and public key pin entries in the
-  // TransportSecurityState. This means that we have to use a
-  // MockHostResolver in order to direct www.google.com to the testserver.
-  // By default, MockHostResolver maps all hosts to 127.0.0.1.
+  // We require that the URL be www.google.com in order to pick up the static
+  // and dynamic STS and PKP entries in the TransportSecurityState. This means
+  // that we have to use a MockHostResolver in order to direct www.google.com to
+  // the testserver. By default, MockHostResolver maps all hosts to 127.0.0.1.
 
   MockHostResolver host_resolver;
   TestNetworkDelegate network_delegate;  // Must outlive URLRequest.
@@ -6674,12 +6681,17 @@
   context.set_network_delegate(&network_delegate);
   context.set_host_resolver(&host_resolver);
   TransportSecurityState transport_security_state;
-  TransportSecurityState::DomainState domain_state;
-  EXPECT_TRUE(transport_security_state.GetDomainState("www.google.com", true,
-                                                      &domain_state));
+
+  TransportSecurityState::DomainState static_domain_state;
+  EXPECT_TRUE(transport_security_state.GetStaticDomainState(
+      "www.google.com", true, &static_domain_state));
   context.set_transport_security_state(&transport_security_state);
   context.Init();
 
+  TransportSecurityState::DomainState dynamic_domain_state;
+  EXPECT_FALSE(transport_security_state.GetDynamicDomainState(
+      "www.google.com", &dynamic_domain_state));
+
   TestDelegate d;
   URLRequest r(GURL(base::StringPrintf("https://www.google.com:%d",
                                        test_server.host_port_pair().port())),
@@ -6697,21 +6709,24 @@
   EXPECT_TRUE(d.have_certificate_errors());
   EXPECT_TRUE(d.certificate_errors_are_fatal());
 
-  // Get a fresh copy of the state, and check that it hasn't been updated.
-  TransportSecurityState::DomainState new_domain_state;
-  EXPECT_TRUE(transport_security_state.GetDomainState("www.google.com", true,
-                                                      &new_domain_state));
-  EXPECT_EQ(new_domain_state.upgrade_mode, domain_state.upgrade_mode);
-  EXPECT_EQ(new_domain_state.sts_include_subdomains,
-            domain_state.sts_include_subdomains);
-  EXPECT_EQ(new_domain_state.pkp_include_subdomains,
-            domain_state.pkp_include_subdomains);
-  EXPECT_TRUE(FingerprintsEqual(new_domain_state.static_spki_hashes,
-                                domain_state.static_spki_hashes));
-  EXPECT_TRUE(FingerprintsEqual(new_domain_state.dynamic_spki_hashes,
-                                domain_state.dynamic_spki_hashes));
-  EXPECT_TRUE(FingerprintsEqual(new_domain_state.bad_static_spki_hashes,
-                                domain_state.bad_static_spki_hashes));
+  // Get a fresh copy of the states, and check that they haven't changed.
+  TransportSecurityState::DomainState new_static_domain_state;
+  EXPECT_TRUE(transport_security_state.GetStaticDomainState(
+      "www.google.com", true, &new_static_domain_state));
+  TransportSecurityState::DomainState new_dynamic_domain_state;
+  EXPECT_FALSE(transport_security_state.GetDynamicDomainState(
+      "www.google.com", &new_dynamic_domain_state));
+
+  EXPECT_EQ(new_static_domain_state.sts.upgrade_mode,
+            static_domain_state.sts.upgrade_mode);
+  EXPECT_EQ(new_static_domain_state.sts.include_subdomains,
+            static_domain_state.sts.include_subdomains);
+  EXPECT_EQ(new_static_domain_state.pkp.include_subdomains,
+            static_domain_state.pkp.include_subdomains);
+  EXPECT_TRUE(FingerprintsEqual(new_static_domain_state.pkp.spki_hashes,
+                                static_domain_state.pkp.spki_hashes));
+  EXPECT_TRUE(FingerprintsEqual(new_static_domain_state.pkp.bad_spki_hashes,
+                                static_domain_state.pkp.bad_spki_hashes));
 }
 
 // Make sure HSTS preserves a POST request's method and body.
diff --git a/ppapi/api/pp_codecs.idl b/ppapi/api/pp_codecs.idl
new file mode 100644
index 0000000..8a7c0f7
--- /dev/null
+++ b/ppapi/api/pp_codecs.idl
@@ -0,0 +1,56 @@
+/* Copyright (c) 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.
+ */
+
+/**
+ * Video profiles.
+ */
+enum PP_VideoProfile {
+  PP_VIDEOPROFILE_H264BASELINE = 0,
+  PP_VIDEOPROFILE_H264MAIN = 1,
+  PP_VIDEOPROFILE_H264EXTENDED = 2,
+  PP_VIDEOPROFILE_H264HIGH = 3,
+  PP_VIDEOPROFILE_H264HIGH10PROFILE = 4,
+  PP_VIDEOPROFILE_H264HIGH422PROFILE = 5,
+  PP_VIDEOPROFILE_H264HIGH444PREDICTIVEPROFILE = 6,
+  PP_VIDEOPROFILE_H264SCALABLEBASELINE = 7,
+  PP_VIDEOPROFILE_H264SCALABLEHIGH = 8,
+  PP_VIDEOPROFILE_H264STEREOHIGH = 9,
+  PP_VIDEOPROFILE_H264MULTIVIEWHIGH = 10,
+  PP_VIDEOPROFILE_VP8MAIN = 11,
+  PP_VIDEOPROFILE_MAX = PP_VIDEOPROFILE_VP8MAIN
+};
+
+/**
+ * Struct describing a decoded video picture. The decoded picture data is stored
+ * in the GL texture corresponding to |texture_id|. The plugin can determine
+ * which Decode call generated the picture using |decode_id|.
+ */
+struct PP_VideoPicture {
+  /**
+   * |decode_id| parameter of the Decode call which generated this picture.
+   * See the PPB_VideoDecoder function Decode() for more details.
+   */
+  uint32_t decode_id;
+
+  /**
+   * Texture ID in the plugin's GL context. The plugin can use this to render
+   * the decoded picture.
+   */
+  uint32_t texture_id;
+
+  /**
+   * The GL texture target for the decoded picture. Possible values are:
+   *   GL_TEXTURE_2D                 (normalized texture coordinates)
+   *   GL_TEXTURE_RECTANGLE_ARB      (dimension dependent texture coordinates)
+   *
+   * The pixel format of the texture is GL_BGRA.
+   */
+  uint32_t texture_target;
+
+  /**
+   * Dimensions of the texture holding the decoded picture.
+   */
+  PP_Size texture_size;
+};
diff --git a/ppapi/api/ppb_media_stream_video_track.idl b/ppapi/api/ppb_media_stream_video_track.idl
index 91e9502..2cf8530 100644
--- a/ppapi/api/ppb_media_stream_video_track.idl
+++ b/ppapi/api/ppb_media_stream_video_track.idl
@@ -12,7 +12,8 @@
 
 label Chrome {
   [channel=dev] M34 = 0.1,
-  M35 = 0.1
+  M35 = 0.1,
+  [channel=dev] M36 = 1.0
 };
 
 /**
@@ -74,6 +75,19 @@
 [version=0.1]
 interface PPB_MediaStreamVideoTrack {
   /**
+   * Creates a PPB_MediaStreamVideoTrack resource for video output. Call this
+   * when you will be creating frames and putting them to the track.
+   *
+   * @param[in] instance A <code>PP_Instance</code> identifying one instance of
+   * a module.
+   *
+   * @return A <code>PP_Resource</code> corresponding to a
+   * PPB_MediaStreamVideoTrack resource if successful, 0 if failed.
+   */
+  [version=1.0]
+  PP_Resource Create([in] PP_Instance instance);
+
+  /**
    * Determines if a resource is a MediaStream video track resource.
    *
    * @param[in] resource The <code>PP_Resource</code> to test.
@@ -211,5 +225,23 @@
    * MediaStream video track resource.
    */
   void Close([in] PP_Resource video_track);
+
+  /**
+   * Gets a free frame for output. The frame is allocated by
+   * <code>Configure()</code>. The caller should fill it with frame data, and
+   * then use |PutFrame()| to send the frame back.
+   */
+  [version=1.0]
+  int32_t GetEmptyFrame([in] PP_Resource video_track,
+                        [out] PP_Resource frame,
+                        [in] PP_CompletionCallback callback);
+
+  /**
+   * Sends a frame returned by |GetEmptyFrame()| to the output track.
+   * After this function, the |frame| should not be used anymore and the
+   * caller should release the reference that it holds.
+   */
+  [version=1.0]
+  int32_t PutFrame([in] PP_Resource video_track, [in] PP_Resource frame);
 };
 
diff --git a/ppapi/api/ppb_video_decoder.idl b/ppapi/api/ppb_video_decoder.idl
new file mode 100644
index 0000000..90a3520
--- /dev/null
+++ b/ppapi/api/ppb_video_decoder.idl
@@ -0,0 +1,203 @@
+/* Copyright (c) 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.
+ */
+
+/**
+ * This file defines the <code>PPB_VideoDecoder</code> interface.
+ */
+
+[generate_thunk]
+
+label Chrome {
+  [channel=dev] M36 = 0.1
+};
+
+/**
+ * Video decoder interface.
+ *
+ * Typical usage:
+ * - Call Create() to create a new video decoder resource.
+ * - Call Initialize() to initialize it with a 3d graphics context and the
+ *   desired codec profile.
+ * - Call Decode() continuously (waiting for each previous call to complete) to
+ *   push bitstream buffers to the decoder.
+ * - Call GetPicture() continuously (waiting for each previous call to complete)
+ *   to pull decoded pictures from the decoder.
+ * - Call Flush() to signal end of stream to the decoder and perform shutdown
+ *   when it completes.
+ * - Call Reset() to quickly stop the decoder (e.g. to implement Seek) and wait
+ *   for the callback before restarting decoding at another point.
+ * - To destroy the decoder, the plugin should release all of its references to
+ *   it. Any pending callbacks will abort before the decoder is destroyed.
+ *
+ * Available video codecs vary by platform.
+ * All: theora, vorbis, vp8.
+ * Chrome and ChromeOS: aac, h264.
+ * ChromeOS: mpeg4.
+ */
+interface PPB_VideoDecoder {
+  /**
+   * Creates a new video decoder resource.
+   *
+   * @param[in] instance A <code>PP_Instance</code> identifying the instance
+   * with the video decoder.
+   *
+   * @return A <code>PP_Resource</code> corresponding to a video decoder if
+   * successful or 0 otherwise.
+   */
+  PP_Resource Create(
+      [in] PP_Instance instance);
+
+  /**
+   * Determines if the given resource is a video decoder.
+   *
+   * @param[in] resource A <code>PP_Resource</code> identifying a resource.
+   *
+   * @return <code>PP_TRUE</code> if the resource is a
+   * <code>PPB_VideoDecoder</code>, <code>PP_FALSE</code> if the resource is
+   * invalid or some other type.
+   */
+  PP_Bool IsVideoDecoder(
+      [in] PP_Resource resource);
+
+  /**
+   * Initializes a video decoder resource. This should be called after Create()
+   * and before any other functions.
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[in] graphics3d_context A <code>PPB_Graphics3D</code> resource to use
+   * during decoding.
+   * @param[in] profile A <code>PP_VideoProfile</code> specifying the video
+   * codec profile.
+   * @param[in] allow_software_fallback A <code>PP_Bool</code> specifying
+   * whether the decoder can fall back to software decoding if a suitable
+   * hardware decoder isn't available.
+   * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
+   * completion.
+   *
+   * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+   * Returns PP_ERROR_NOTSUPPORTED if video decoding is not available, or the
+   * requested profile is not supported. In this case, the client may call
+   * Initialize() again with different parameters to find a good configuration.
+   */
+  int32_t Initialize(
+      [in] PP_Resource video_decoder,
+      [in] PP_Resource graphics3d_context,
+      [in] PP_VideoProfile profile,
+      [in] PP_Bool allow_software_fallback,
+      [in] PP_CompletionCallback callback);
+
+  /**
+   * Decodes a bitstream buffer. Copies |size| bytes of data from the plugin's
+   * |buffer|. The plugin should maintain the buffer and not call Decode() again
+   * until the decoder signals completion by returning PP_OK or by running
+   * |callback|.
+   *
+   * In general, each bitstream buffer should contain a demuxed bitstream frame
+   * for the selected video codec. For example, H264 decoders expect to receive
+   * one AnnexB NAL unit, including the 4 byte start code prefix, while VP8
+   * decoders expect to receive a bitstream frame without the IVF frame header.
+   *
+   * If the call to Decode() eventually results in a picture, the |decode_id|
+   * parameter is copied into the returned picture. The plugin can use this to
+   * associate decoded pictures with Decode() calls (e.g. to assign timestamps
+   * or frame numbers to pictures.) This value is opaque to the API so the
+   * plugin is free to pass any value.
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[in] decode_id An optional value, chosen by the plugin, that can be
+   * used to associate calls to Decode() with decoded pictures returned by
+   * GetPicture().
+   * @param[in] size Buffer size in bytes.
+   * @param[in] buffer Starting address of buffer.
+   * @param[in] callback A <code>PP_CompletionCallback</code> to be called on
+   * completion.
+   *
+   * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+   */
+  int32_t Decode(
+      [in] PP_Resource video_decoder,
+      [in] uint32_t decode_id,
+      [in] uint32_t size,
+      [in] mem_t buffer,
+      [in] PP_CompletionCallback callback);
+
+  /**
+   * Gets the next picture from the decoder. The picture is valid after the
+   * decoder signals completion by returning PP_OK or running |callback|. The
+   * plugin can call GetPicture() again after the decoder signals completion.
+   * When the plugin is finished using the picture, it should return it to the
+   * system by calling RecyclePicture().
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[out] picture A <code>PP_VideoPicture</code> to hold the decoded
+   * picture.
+   * @param[in] callback A <code>PP_CompletionCallback</code> to be called on
+   * completion.
+   *
+   * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+   * Returns PP_OK if a picture is available.
+   * Returns PP_ERROR_ABORTED when Reset() is called, or if a call to Flush()
+   * completes while GetPicture() is pending.
+   */
+  int32_t GetPicture(
+      [in] PP_Resource video_decoder,
+      [out] PP_VideoPicture picture,
+      [in] PP_CompletionCallback callback);
+
+  /**
+   * Recycles a picture that the plugin has received from the decoder.
+   * The plugin should call this as soon as it has finished using the texture so
+   * the decoder can decode more pictures.
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[in] picture A <code>PP_VideoPicture</code> to return to
+   * the decoder.
+   */
+  void RecyclePicture(
+      [in] PP_Resource video_decoder,
+      [in] PP_VideoPicture picture);
+
+  /**
+   * Flushes the decoder. The plugin should call this when it reaches the end of
+   * its video stream in order to stop cleanly. The decoder will run all pending
+   * calls to completion. The plugin should make no further calls to the decoder
+   * other than GetPicture() and RecyclePicture() until the decoder signals
+   * completion by running the callback. Just before completion, any pending
+   * GetPicture() call will complete by running the callback with result
+   * PP_ERROR_ABORTED to signal that no more pictures are available.
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[in] callback A <code>PP_CompletionCallback</code> to be called on
+   * completion.
+   *
+   * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+   */
+  int32_t Flush(
+      [in] PP_Resource video_decoder,
+      [in] PP_CompletionCallback callback);
+
+  /**
+   * Resets the decoder as quickly as possible. The plugin can call Reset() to
+   * skip to another position in the video stream. Pending calls to Decode() and
+   * GetPicture()) are immediately aborted, causing their callbacks to run with
+   * PP_ERROR_ABORTED. The plugin should not make any further calls to the
+   * decoder until the decoder signals completion by running |callback|.
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[in] callback A <code>PP_CompletionCallback</code> to be called on
+   * completion.
+   *
+   * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+   */
+  int32_t Reset(
+      [in] PP_Resource video_decoder,
+      [in] PP_CompletionCallback callback);
+};
diff --git a/ppapi/api/private/ppb_nacl_private.idl b/ppapi/api/private/ppb_nacl_private.idl
index d38f5c5..91c458d 100644
--- a/ppapi/api/private/ppb_nacl_private.idl
+++ b/ppapi/api/private/ppb_nacl_private.idl
@@ -139,6 +139,10 @@
   int32_t opt_level;
 };
 
+/* Callback invoked upon completion of PPP_ManifestService::OpenResource(). */
+typedef void PP_OpenResourceCompletionCallback([inout] mem_t user_data,
+                                               [in] PP_FileHandle file_handle);
+
 /* ManifestService to support irt_open_resource() function.
  * All functions of the service should have PP_Bool return value. It represents
  * whether the service is still alive or not. Trivially Quit() should always
@@ -146,12 +150,20 @@
  * Once false is called, as the service has been destructed, all functions
  * should never be called afterwords.
  */
-interface PP_ManifestService {
+interface PPP_ManifestService {
   /* Called when ManifestService should be destructed. */
   PP_Bool Quit([inout] mem_t user_data);
 
   /* Called when PPAPI initialization in the NaCl plugin is finished. */
   PP_Bool StartupInitializationComplete([inout] mem_t user_data);
+
+  /* Called when irt_open_resource() is invoked in the NaCl plugin.
+   * Upon completion, callback will be invoked with given callback_user_data
+   * and the result file handle (or PP_kInvalidFileHandle on error). */
+  PP_Bool OpenResource([inout] mem_t user_data,
+                       [in] str_t entry_key,
+                       [in] PP_OpenResourceCompletionCallback callback,
+                       [inout] mem_t callback_user_data);
 };
 
 /* PPB_NaCl_Private */
@@ -184,7 +196,7 @@
                     [in] PP_Bool enable_dyncode_syscalls,
                     [in] PP_Bool enable_exception_handling,
                     [in] PP_Bool enable_crash_throttling,
-                    [in] PP_ManifestService manifest_service_interface,
+                    [in] PPP_ManifestService manifest_service_interface,
                     [inout] mem_t manifest_service_user_data,
                     [out] mem_t imc_handle,
                     [out] PP_Var error_message,
@@ -376,6 +388,7 @@
   PP_Bool ResolvesRelativeToPluginBaseUrl([in] PP_Instance instance,
                                           [in] str_t url);
 
+  /* Returns the parsed contents of a data URL. */
   PP_Var ParseDataURL([in] str_t data_url);
 
   /* Processes the NaCl manifest once it's been retrieved.
@@ -391,4 +404,46 @@
   PP_Bool IsPNaCl([in] PP_Instance instance);
 
   PP_Bool DevInterfacesEnabled([in] PP_Instance instance);
+
+  /* Downloads the manifest into the buffer |data|, invoking
+   * |callback| when finished.
+   * TODO(teravest): Merge data URL parsing into this. */
+  void DownloadManifestToBuffer([in] PP_Instance instance,
+                                [out] PP_Var data,
+                                [in] PP_CompletionCallback callback);
+
+  int32_t CreatePnaclManifest([in] PP_Instance instance);
+  int32_t CreateJsonManifest([in] PP_Instance instance,
+                             [in] str_t manifest_base_url,
+                             [in] str_t sandbox_isa,
+                             [in] str_t manifest_data);
+
+  void DestroyManifest([in] PP_Instance instance,
+                       [in] int32_t manifest_id);
+
+  PP_Bool GetManifestProgramURL([in] PP_Instance instance,
+                                [in] int32_t manifest_id,
+                                [out] PP_Var full_url,
+                                [out] PP_PNaClOptions pnacl_options,
+                                [out] PP_Bool uses_nonsfi_mode);
+
+  PP_Bool ManifestResolveKey([in] PP_Instance instance,
+                             [in] int32_t manifest_id,
+                             [in] str_t key,
+                             [out] PP_Var full_url,
+                             [out] PP_PNaClOptions pnacl_options);
+
+  /* Returns the filenames for the llc and ld tools, parsing that information
+   * from the file given in |filename|.
+   */
+  PP_Bool GetPnaclResourceInfo([in] PP_Instance instance,
+                               [in] str_t filename,
+                               [out] PP_Var llc_tool_name,
+                               [out] PP_Var ld_tool_name);
+
+  // PP_Var string of attributes describing the CPU features supported
+  // by the current architecture. The string is a comma-delimited list
+  // of attributes supported by LLVM in its -mattr= option:
+  //   http://llvm.org/docs/CommandGuide/llc.html#cmdoption-mattr
+  PP_Var GetCpuFeatureAttrs();
 };
diff --git a/ppapi/c/pp_codecs.h b/ppapi/c/pp_codecs.h
new file mode 100644
index 0000000..b98769e
--- /dev/null
+++ b/ppapi/c/pp_codecs.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 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.
+ */
+
+/* From pp_codecs.idl modified Tue May  6 05:14:19 2014. */
+
+#ifndef PPAPI_C_PP_CODECS_H_
+#define PPAPI_C_PP_CODECS_H_
+
+#include "ppapi/c/pp_macros.h"
+#include "ppapi/c/pp_size.h"
+#include "ppapi/c/pp_stdint.h"
+
+/**
+ * @file
+ * Video profiles.
+ */
+
+
+/**
+ * @addtogroup Enums
+ * @{
+ */
+typedef enum {
+  PP_VIDEOPROFILE_H264BASELINE = 0,
+  PP_VIDEOPROFILE_H264MAIN = 1,
+  PP_VIDEOPROFILE_H264EXTENDED = 2,
+  PP_VIDEOPROFILE_H264HIGH = 3,
+  PP_VIDEOPROFILE_H264HIGH10PROFILE = 4,
+  PP_VIDEOPROFILE_H264HIGH422PROFILE = 5,
+  PP_VIDEOPROFILE_H264HIGH444PREDICTIVEPROFILE = 6,
+  PP_VIDEOPROFILE_H264SCALABLEBASELINE = 7,
+  PP_VIDEOPROFILE_H264SCALABLEHIGH = 8,
+  PP_VIDEOPROFILE_H264STEREOHIGH = 9,
+  PP_VIDEOPROFILE_H264MULTIVIEWHIGH = 10,
+  PP_VIDEOPROFILE_VP8MAIN = 11,
+  PP_VIDEOPROFILE_MAX = PP_VIDEOPROFILE_VP8MAIN
+} PP_VideoProfile;
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup Structs
+ * @{
+ */
+/**
+ * Struct describing a decoded video picture. The decoded picture data is stored
+ * in the GL texture corresponding to |texture_id|. The plugin can determine
+ * which Decode call generated the picture using |decode_id|.
+ */
+struct PP_VideoPicture {
+  /**
+   * |decode_id| parameter of the Decode call which generated this picture.
+   * See the PPB_VideoDecoder function Decode() for more details.
+   */
+  uint32_t decode_id;
+  /**
+   * Texture ID in the plugin's GL context. The plugin can use this to render
+   * the decoded picture.
+   */
+  uint32_t texture_id;
+  /**
+   * The GL texture target for the decoded picture. Possible values are:
+   *   GL_TEXTURE_2D                 (normalized texture coordinates)
+   *   GL_TEXTURE_RECTANGLE_ARB      (dimension dependent texture coordinates)
+   *
+   * The pixel format of the texture is GL_BGRA.
+   */
+  uint32_t texture_target;
+  /**
+   * Dimensions of the texture holding the decoded picture.
+   */
+  struct PP_Size texture_size;
+};
+/**
+ * @}
+ */
+
+#endif  /* PPAPI_C_PP_CODECS_H_ */
+
diff --git a/ppapi/c/pp_macros.h b/ppapi/c/pp_macros.h
index 61be3d0..ae27731 100644
--- a/ppapi/c/pp_macros.h
+++ b/ppapi/c/pp_macros.h
@@ -3,13 +3,13 @@
  * found in the LICENSE file.
  */
 
-/* From pp_macros.idl modified Wed Feb 26 15:01:03 2014. */
+/* From pp_macros.idl modified Thu Jan 23 14:14:38 2014. */
 
 #ifndef PPAPI_C_PP_MACROS_H_
 #define PPAPI_C_PP_MACROS_H_
 
 
-#define PPAPI_RELEASE 35
+#define PPAPI_RELEASE 36
 
 /**
  * @file
diff --git a/ppapi/c/ppb_media_stream_video_track.h b/ppapi/c/ppb_media_stream_video_track.h
index 1580041..31c7a80 100644
--- a/ppapi/c/ppb_media_stream_video_track.h
+++ b/ppapi/c/ppb_media_stream_video_track.h
@@ -3,19 +3,22 @@
  * found in the LICENSE file.
  */
 
-/* From ppb_media_stream_video_track.idl modified Fri Mar 28 10:13:52 2014. */
+/* From ppb_media_stream_video_track.idl modified Mon Apr  7 15:25:56 2014. */
 
 #ifndef PPAPI_C_PPB_MEDIA_STREAM_VIDEO_TRACK_H_
 #define PPAPI_C_PPB_MEDIA_STREAM_VIDEO_TRACK_H_
 
 #include "ppapi/c/pp_bool.h"
 #include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_instance.h"
 #include "ppapi/c/pp_macros.h"
 #include "ppapi/c/pp_resource.h"
 #include "ppapi/c/pp_stdint.h"
 #include "ppapi/c/pp_var.h"
 
 #define PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_0_1 "PPB_MediaStreamVideoTrack;0.1"
+#define PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_1_0 \
+    "PPB_MediaStreamVideoTrack;1.0" /* dev */
 #define PPB_MEDIASTREAMVIDEOTRACK_INTERFACE \
     PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_0_1
 
@@ -89,7 +92,18 @@
  * @addtogroup Interfaces
  * @{
  */
-struct PPB_MediaStreamVideoTrack_0_1 {
+struct PPB_MediaStreamVideoTrack_1_0 { /* dev */
+  /**
+   * Creates a PPB_MediaStreamVideoTrack resource for video output. Call this
+   * when you will be creating frames and putting them to the track.
+   *
+   * @param[in] instance A <code>PP_Instance</code> identifying one instance of
+   * a module.
+   *
+   * @return A <code>PP_Resource</code> corresponding to a
+   * PPB_MediaStreamVideoTrack resource if successful, 0 if failed.
+   */
+  PP_Resource (*Create)(PP_Instance instance);
   /**
    * Determines if a resource is a MediaStream video track resource.
    *
@@ -219,6 +233,37 @@
    * MediaStream video track resource.
    */
   void (*Close)(PP_Resource video_track);
+  /**
+   * Gets a free frame for output. The frame is allocated by
+   * <code>Configure()</code>. The caller should fill it with frame data, and
+   * then use |PutFrame()| to send the frame back.
+   */
+  int32_t (*GetEmptyFrame)(PP_Resource video_track,
+                           PP_Resource* frame,
+                           struct PP_CompletionCallback callback);
+  /**
+   * Sends a frame returned by |GetEmptyFrame()| to the output track.
+   * After this function, the |frame| should not be used anymore and the
+   * caller should release the reference that it holds.
+   */
+  int32_t (*PutFrame)(PP_Resource video_track, PP_Resource frame);
+};
+
+struct PPB_MediaStreamVideoTrack_0_1 {
+  PP_Bool (*IsMediaStreamVideoTrack)(PP_Resource resource);
+  int32_t (*Configure)(PP_Resource video_track,
+                       const int32_t attrib_list[],
+                       struct PP_CompletionCallback callback);
+  int32_t (*GetAttrib)(PP_Resource video_track,
+                       PP_MediaStreamVideoTrack_Attrib attrib,
+                       int32_t* value);
+  struct PP_Var (*GetId)(PP_Resource video_track);
+  PP_Bool (*HasEnded)(PP_Resource video_track);
+  int32_t (*GetFrame)(PP_Resource video_track,
+                      PP_Resource* frame,
+                      struct PP_CompletionCallback callback);
+  int32_t (*RecycleFrame)(PP_Resource video_track, PP_Resource frame);
+  void (*Close)(PP_Resource video_track);
 };
 
 typedef struct PPB_MediaStreamVideoTrack_0_1 PPB_MediaStreamVideoTrack;
diff --git a/ppapi/c/ppb_video_decoder.h b/ppapi/c/ppb_video_decoder.h
new file mode 100644
index 0000000..f09908c
--- /dev/null
+++ b/ppapi/c/ppb_video_decoder.h
@@ -0,0 +1,209 @@
+/* Copyright (c) 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.
+ */
+
+/* From ppb_video_decoder.idl modified Tue May  6 05:19:45 2014. */
+
+#ifndef PPAPI_C_PPB_VIDEO_DECODER_H_
+#define PPAPI_C_PPB_VIDEO_DECODER_H_
+
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/c/pp_codecs.h"
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_macros.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_size.h"
+#include "ppapi/c/pp_stdint.h"
+
+#define PPB_VIDEODECODER_INTERFACE_0_1 "PPB_VideoDecoder;0.1" /* dev */
+/**
+ * @file
+ * This file defines the <code>PPB_VideoDecoder</code> interface.
+ */
+
+
+/**
+ * @addtogroup Interfaces
+ * @{
+ */
+/**
+ * Video decoder interface.
+ *
+ * Typical usage:
+ * - Call Create() to create a new video decoder resource.
+ * - Call Initialize() to initialize it with a 3d graphics context and the
+ *   desired codec profile.
+ * - Call Decode() continuously (waiting for each previous call to complete) to
+ *   push bitstream buffers to the decoder.
+ * - Call GetPicture() continuously (waiting for each previous call to complete)
+ *   to pull decoded pictures from the decoder.
+ * - Call Flush() to signal end of stream to the decoder and perform shutdown
+ *   when it completes.
+ * - Call Reset() to quickly stop the decoder (e.g. to implement Seek) and wait
+ *   for the callback before restarting decoding at another point.
+ * - To destroy the decoder, the plugin should release all of its references to
+ *   it. Any pending callbacks will abort before the decoder is destroyed.
+ *
+ * Available video codecs vary by platform.
+ * All: theora, vorbis, vp8.
+ * Chrome and ChromeOS: aac, h264.
+ * ChromeOS: mpeg4.
+ */
+struct PPB_VideoDecoder_0_1 { /* dev */
+  /**
+   * Creates a new video decoder resource.
+   *
+   * @param[in] instance A <code>PP_Instance</code> identifying the instance
+   * with the video decoder.
+   *
+   * @return A <code>PP_Resource</code> corresponding to a video decoder if
+   * successful or 0 otherwise.
+   */
+  PP_Resource (*Create)(PP_Instance instance);
+  /**
+   * Determines if the given resource is a video decoder.
+   *
+   * @param[in] resource A <code>PP_Resource</code> identifying a resource.
+   *
+   * @return <code>PP_TRUE</code> if the resource is a
+   * <code>PPB_VideoDecoder</code>, <code>PP_FALSE</code> if the resource is
+   * invalid or some other type.
+   */
+  PP_Bool (*IsVideoDecoder)(PP_Resource resource);
+  /**
+   * Initializes a video decoder resource. This should be called after Create()
+   * and before any other functions.
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[in] graphics3d_context A <code>PPB_Graphics3D</code> resource to use
+   * during decoding.
+   * @param[in] profile A <code>PP_VideoProfile</code> specifying the video
+   * codec profile.
+   * @param[in] allow_software_fallback A <code>PP_Bool</code> specifying
+   * whether the decoder can fall back to software decoding if a suitable
+   * hardware decoder isn't available.
+   * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
+   * completion.
+   *
+   * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+   * Returns PP_ERROR_NOTSUPPORTED if video decoding is not available, or the
+   * requested profile is not supported. In this case, the client may call
+   * Initialize() again with different parameters to find a good configuration.
+   */
+  int32_t (*Initialize)(PP_Resource video_decoder,
+                        PP_Resource graphics3d_context,
+                        PP_VideoProfile profile,
+                        PP_Bool allow_software_fallback,
+                        struct PP_CompletionCallback callback);
+  /**
+   * Decodes a bitstream buffer. Copies |size| bytes of data from the plugin's
+   * |buffer|. The plugin should maintain the buffer and not call Decode() again
+   * until the decoder signals completion by returning PP_OK or by running
+   * |callback|.
+   *
+   * In general, each bitstream buffer should contain a demuxed bitstream frame
+   * for the selected video codec. For example, H264 decoders expect to receive
+   * one AnnexB NAL unit, including the 4 byte start code prefix, while VP8
+   * decoders expect to receive a bitstream frame without the IVF frame header.
+   *
+   * If the call to Decode() eventually results in a picture, the |decode_id|
+   * parameter is copied into the returned picture. The plugin can use this to
+   * associate decoded pictures with Decode() calls (e.g. to assign timestamps
+   * or frame numbers to pictures.) This value is opaque to the API so the
+   * plugin is free to pass any value.
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[in] decode_id An optional value, chosen by the plugin, that can be
+   * used to associate calls to Decode() with decoded pictures returned by
+   * GetPicture().
+   * @param[in] size Buffer size in bytes.
+   * @param[in] buffer Starting address of buffer.
+   * @param[in] callback A <code>PP_CompletionCallback</code> to be called on
+   * completion.
+   *
+   * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+   */
+  int32_t (*Decode)(PP_Resource video_decoder,
+                    uint32_t decode_id,
+                    uint32_t size,
+                    const void* buffer,
+                    struct PP_CompletionCallback callback);
+  /**
+   * Gets the next picture from the decoder. The picture is valid after the
+   * decoder signals completion by returning PP_OK or running |callback|. The
+   * plugin can call GetPicture() again after the decoder signals completion.
+   * When the plugin is finished using the picture, it should return it to the
+   * system by calling RecyclePicture().
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[out] picture A <code>PP_VideoPicture</code> to hold the decoded
+   * picture.
+   * @param[in] callback A <code>PP_CompletionCallback</code> to be called on
+   * completion.
+   *
+   * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+   * Returns PP_OK if a picture is available.
+   * Returns PP_ERROR_ABORTED when Reset() is called, or if a call to Flush()
+   * completes while GetPicture() is pending.
+   */
+  int32_t (*GetPicture)(PP_Resource video_decoder,
+                        struct PP_VideoPicture* picture,
+                        struct PP_CompletionCallback callback);
+  /**
+   * Recycles a picture that the plugin has received from the decoder.
+   * The plugin should call this as soon as it has finished using the texture so
+   * the decoder can decode more pictures.
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[in] picture A <code>PP_VideoPicture</code> to return to
+   * the decoder.
+   */
+  void (*RecyclePicture)(PP_Resource video_decoder,
+                         const struct PP_VideoPicture* picture);
+  /**
+   * Flushes the decoder. The plugin should call this when it reaches the end of
+   * its video stream in order to stop cleanly. The decoder will run all pending
+   * calls to completion. The plugin should make no further calls to the decoder
+   * other than GetPicture() and RecyclePicture() until the decoder signals
+   * completion by running the callback. Just before completion, any pending
+   * GetPicture() call will complete by running the callback with result
+   * PP_ERROR_ABORTED to signal that no more pictures are available.
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[in] callback A <code>PP_CompletionCallback</code> to be called on
+   * completion.
+   *
+   * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+   */
+  int32_t (*Flush)(PP_Resource video_decoder,
+                   struct PP_CompletionCallback callback);
+  /**
+   * Resets the decoder as quickly as possible. The plugin can call Reset() to
+   * skip to another position in the video stream. Pending calls to Decode() and
+   * GetPicture()) are immediately aborted, causing their callbacks to run with
+   * PP_ERROR_ABORTED. The plugin should not make any further calls to the
+   * decoder until the decoder signals completion by running |callback|.
+   *
+   * @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+   * decoder.
+   * @param[in] callback A <code>PP_CompletionCallback</code> to be called on
+   * completion.
+   *
+   * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+   */
+  int32_t (*Reset)(PP_Resource video_decoder,
+                   struct PP_CompletionCallback callback);
+};
+/**
+ * @}
+ */
+
+#endif  /* PPAPI_C_PPB_VIDEO_DECODER_H_ */
+
diff --git a/ppapi/c/private/ppb_nacl_private.h b/ppapi/c/private/ppb_nacl_private.h
index 11e57c3..e630bcf 100644
--- a/ppapi/c/private/ppb_nacl_private.h
+++ b/ppapi/c/private/ppb_nacl_private.h
@@ -3,7 +3,7 @@
  * found in the LICENSE file.
  */
 
-/* From private/ppb_nacl_private.idl modified Fri Apr 25 15:10:15 2014. */
+/* From private/ppb_nacl_private.idl modified Tue May  6 21:29:20 2014. */
 
 #ifndef PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_
 #define PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_
@@ -15,8 +15,8 @@
 #include "ppapi/c/pp_stdint.h"
 #include "ppapi/c/pp_var.h"
 
-#define PP_MANIFESTSERVICE_INTERFACE_1_0 "PP_ManifestService;1.0"
-#define PP_MANIFESTSERVICE_INTERFACE PP_MANIFESTSERVICE_INTERFACE_1_0
+#define PPP_MANIFESTSERVICE_INTERFACE_1_0 "PPP_ManifestService;1.0"
+#define PPP_MANIFESTSERVICE_INTERFACE PPP_MANIFESTSERVICE_INTERFACE_1_0
 
 #define PPB_NACL_PRIVATE_INTERFACE_1_0 "PPB_NaCl_Private;1.0"
 #define PPB_NACL_PRIVATE_INTERFACE PPB_NACL_PRIVATE_INTERFACE_1_0
@@ -168,6 +168,17 @@
  */
 
 /**
+ * @addtogroup Typedefs
+ * @{
+ */
+/* Callback invoked upon completion of PPP_ManifestService::OpenResource(). */
+typedef void (*PP_OpenResourceCompletionCallback)(void* user_data,
+                                                  PP_FileHandle file_handle);
+/**
+ * @}
+ */
+
+/**
  * @addtogroup Interfaces
  * @{
  */
@@ -178,14 +189,21 @@
  * Once false is called, as the service has been destructed, all functions
  * should never be called afterwords.
  */
-struct PP_ManifestService_1_0 {
+struct PPP_ManifestService_1_0 {
   /* Called when ManifestService should be destructed. */
   PP_Bool (*Quit)(void* user_data);
   /* Called when PPAPI initialization in the NaCl plugin is finished. */
   PP_Bool (*StartupInitializationComplete)(void* user_data);
+  /* Called when irt_open_resource() is invoked in the NaCl plugin.
+   * Upon completion, callback will be invoked with given callback_user_data
+   * and the result file handle (or PP_kInvalidFileHandle on error). */
+  PP_Bool (*OpenResource)(void* user_data,
+                          const char* entry_key,
+                          PP_OpenResourceCompletionCallback callback,
+                          void* callback_user_data);
 };
 
-typedef struct PP_ManifestService_1_0 PP_ManifestService;
+typedef struct PPP_ManifestService_1_0 PPP_ManifestService;
 
 /* PPB_NaCl_Private */
 struct PPB_NaCl_Private_1_0 {
@@ -218,7 +236,7 @@
       PP_Bool enable_dyncode_syscalls,
       PP_Bool enable_exception_handling,
       PP_Bool enable_crash_throttling,
-      const struct PP_ManifestService_1_0* manifest_service_interface,
+      const struct PPP_ManifestService_1_0* manifest_service_interface,
       void* manifest_service_user_data,
       void* imc_handle,
       struct PP_Var* error_message,
@@ -372,6 +390,7 @@
   struct PP_Var (*GetManifestBaseURL)(PP_Instance instance);
   PP_Bool (*ResolvesRelativeToPluginBaseUrl)(PP_Instance instance,
                                              const char* url);
+  /* Returns the parsed contents of a data URL. */
   struct PP_Var (*ParseDataURL)(const char* data_url);
   /* Processes the NaCl manifest once it's been retrieved.
    * TODO(teravest): Move the rest of the supporting logic out of the trusted
@@ -382,6 +401,40 @@
   struct PP_Var (*GetManifestURLArgument)(PP_Instance instance);
   PP_Bool (*IsPNaCl)(PP_Instance instance);
   PP_Bool (*DevInterfacesEnabled)(PP_Instance instance);
+  /* Downloads the manifest into the buffer |data|, invoking
+   * |callback| when finished.
+   * TODO(teravest): Merge data URL parsing into this. */
+  void (*DownloadManifestToBuffer)(PP_Instance instance,
+                                   struct PP_Var* data,
+                                   struct PP_CompletionCallback callback);
+  int32_t (*CreatePnaclManifest)(PP_Instance instance);
+  int32_t (*CreateJsonManifest)(PP_Instance instance,
+                                const char* manifest_base_url,
+                                const char* sandbox_isa,
+                                const char* manifest_data);
+  void (*DestroyManifest)(PP_Instance instance, int32_t manifest_id);
+  PP_Bool (*GetManifestProgramURL)(PP_Instance instance,
+                                   int32_t manifest_id,
+                                   struct PP_Var* full_url,
+                                   struct PP_PNaClOptions* pnacl_options,
+                                   PP_Bool* uses_nonsfi_mode);
+  PP_Bool (*ManifestResolveKey)(PP_Instance instance,
+                                int32_t manifest_id,
+                                const char* key,
+                                struct PP_Var* full_url,
+                                struct PP_PNaClOptions* pnacl_options);
+  /* Returns the filenames for the llc and ld tools, parsing that information
+   * from the file given in |filename|.
+   */
+  PP_Bool (*GetPnaclResourceInfo)(PP_Instance instance,
+                                  const char* filename,
+                                  struct PP_Var* llc_tool_name,
+                                  struct PP_Var* ld_tool_name);
+  /* PP_Var string of attributes describing the CPU features supported
+   * by the current architecture. The string is a comma-delimited list
+   * of attributes supported by LLVM in its -mattr= option:
+   *   http://llvm.org/docs/CommandGuide/llc.html#cmdoption-mattr */
+  struct PP_Var (*GetCpuFeatureAttrs)(void);
 };
 
 typedef struct PPB_NaCl_Private_1_0 PPB_NaCl_Private;
diff --git a/ppapi/cpp/media_stream_video_track.cc b/ppapi/cpp/media_stream_video_track.cc
index 38065a3..47ff140 100644
--- a/ppapi/cpp/media_stream_video_track.cc
+++ b/ppapi/cpp/media_stream_video_track.cc
@@ -15,6 +15,10 @@
 
 namespace {
 
+template <> const char* interface_name<PPB_MediaStreamVideoTrack_1_0>() {
+  return PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_1_0;
+}
+
 template <> const char* interface_name<PPB_MediaStreamVideoTrack_0_1>() {
   return PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_0_1;
 }
@@ -33,6 +37,16 @@
   PP_DCHECK(IsMediaStreamVideoTrack(resource));
 }
 
+MediaStreamVideoTrack::MediaStreamVideoTrack(const InstanceHandle& instance) {
+  if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) {
+    PassRefFromConstructor(
+        get_interface<PPB_MediaStreamVideoTrack_1_0>()->Create(
+            instance.pp_instance()));
+    return;
+  }
+  PP_DCHECK(false);
+}
+
 MediaStreamVideoTrack::MediaStreamVideoTrack(PassRef, PP_Resource resource)
     : Resource(PASS_REF, resource) {
 }
@@ -43,7 +57,10 @@
 int32_t MediaStreamVideoTrack::Configure(
     const int32_t attributes[],
     const CompletionCallback& callback) {
-  if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
+  if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) {
+    return get_interface<PPB_MediaStreamVideoTrack_1_0>()->Configure(
+        pp_resource(), attributes, callback.pp_completion_callback());
+  } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
     return get_interface<PPB_MediaStreamVideoTrack_0_1>()->Configure(
         pp_resource(), attributes, callback.pp_completion_callback());
   }
@@ -52,7 +69,10 @@
 
 int32_t MediaStreamVideoTrack::GetAttrib(PP_MediaStreamVideoTrack_Attrib attrib,
                                          int32_t* value) {
-  if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
+  if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) {
+    return get_interface<PPB_MediaStreamVideoTrack_1_0>()->GetAttrib(
+        pp_resource(), attrib, value);
+  } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
     return get_interface<PPB_MediaStreamVideoTrack_0_1>()->GetAttrib(
         pp_resource(), attrib, value);
   }
@@ -60,7 +80,12 @@
 }
 
 std::string MediaStreamVideoTrack::GetId() const {
-  if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
+  if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) {
+    pp::Var id(PASS_REF, get_interface<PPB_MediaStreamVideoTrack_1_0>()->GetId(
+        pp_resource()));
+    if (id.is_string())
+      return id.AsString();
+  } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
     pp::Var id(PASS_REF, get_interface<PPB_MediaStreamVideoTrack_0_1>()->GetId(
         pp_resource()));
     if (id.is_string())
@@ -70,7 +95,10 @@
 }
 
 bool MediaStreamVideoTrack::HasEnded() const {
-  if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
+  if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) {
+    return PP_ToBool(get_interface<PPB_MediaStreamVideoTrack_1_0>()->HasEnded(
+        pp_resource()));
+  } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
     return PP_ToBool(get_interface<PPB_MediaStreamVideoTrack_0_1>()->HasEnded(
         pp_resource()));
   }
@@ -79,7 +107,10 @@
 
 int32_t MediaStreamVideoTrack::GetFrame(
     const CompletionCallbackWithOutput<VideoFrame>& callback) {
-  if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
+  if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) {
+    return get_interface<PPB_MediaStreamVideoTrack_1_0>()->GetFrame(
+        pp_resource(), callback.output(), callback.pp_completion_callback());
+  } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
     return get_interface<PPB_MediaStreamVideoTrack_0_1>()->GetFrame(
         pp_resource(), callback.output(), callback.pp_completion_callback());
   }
@@ -87,7 +118,10 @@
 }
 
 int32_t MediaStreamVideoTrack::RecycleFrame(const VideoFrame& frame) {
-  if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
+  if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) {
+    return get_interface<PPB_MediaStreamVideoTrack_1_0>()->RecycleFrame(
+        pp_resource(), frame.pp_resource());
+  } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
     return get_interface<PPB_MediaStreamVideoTrack_0_1>()->RecycleFrame(
         pp_resource(), frame.pp_resource());
   }
@@ -95,12 +129,35 @@
 }
 
 void MediaStreamVideoTrack::Close() {
-  if (has_interface<PPB_MediaStreamVideoTrack_0_1>())
+  if (has_interface<PPB_MediaStreamVideoTrack_1_0>())
+    get_interface<PPB_MediaStreamVideoTrack_1_0>()->Close(pp_resource());
+  else if (has_interface<PPB_MediaStreamVideoTrack_0_1>())
     get_interface<PPB_MediaStreamVideoTrack_0_1>()->Close(pp_resource());
+
+}
+
+int32_t MediaStreamVideoTrack::GetEmptyFrame(
+    const CompletionCallbackWithOutput<VideoFrame>& callback) {
+  if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) {
+    return get_interface<PPB_MediaStreamVideoTrack_1_0>()->GetEmptyFrame(
+        pp_resource(), callback.output(), callback.pp_completion_callback());
+  }
+  return callback.MayForce(PP_ERROR_NOINTERFACE);
+}
+
+int32_t MediaStreamVideoTrack::PutFrame(const VideoFrame& frame) {
+  if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) {
+    return get_interface<PPB_MediaStreamVideoTrack_1_0>()->PutFrame(
+        pp_resource(), frame.pp_resource());
+  }
+  return PP_ERROR_NOINTERFACE;
 }
 
 bool MediaStreamVideoTrack::IsMediaStreamVideoTrack(const Resource& resource) {
-  if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
+  if (has_interface<PPB_MediaStreamVideoTrack_1_0>()) {
+    return PP_ToBool(get_interface<PPB_MediaStreamVideoTrack_1_0>()->
+        IsMediaStreamVideoTrack(resource.pp_resource()));
+  } else if (has_interface<PPB_MediaStreamVideoTrack_0_1>()) {
     return PP_ToBool(get_interface<PPB_MediaStreamVideoTrack_0_1>()->
         IsMediaStreamVideoTrack(resource.pp_resource()));
   }
diff --git a/ppapi/cpp/media_stream_video_track.h b/ppapi/cpp/media_stream_video_track.h
index 6975986..5d03745 100644
--- a/ppapi/cpp/media_stream_video_track.h
+++ b/ppapi/cpp/media_stream_video_track.h
@@ -41,6 +41,10 @@
   /// @param[in] resource A <code>PPB_MediaStreamVideoTrack</code> resource.
   explicit MediaStreamVideoTrack(const Resource& resource);
 
+  /// Constructs a <code>MediaStreamVideoTrack</code> that outputs given frames
+  /// to a new video track, which will be consumed by Javascript.
+  explicit MediaStreamVideoTrack(const InstanceHandle& instance);
+
   /// A constructor used when you have received a <code>PP_Resource</code> as a
   /// return value that has had 1 ref added for you.
   ///
@@ -134,6 +138,17 @@
   /// After calling <code>Close()</code>, no new frames will be received.
   void Close();
 
+  // Gets a free frame for output. The frame is allocated by
+  // <code>Configure()</code>. The caller should fill it with frame data, and
+  // then use |PutFrame()| to send the frame back.
+  int32_t GetEmptyFrame(
+      const CompletionCallbackWithOutput<VideoFrame>& callback);
+
+  // Sends a frame returned by |GetEmptyFrame()| to the output track.
+  // After this function, the |frame| should not be used anymore and the
+  // caller should release the reference that it holds.
+  int32_t PutFrame(const VideoFrame& frame);
+
   /// Checks whether a <code>Resource</code> is a MediaStream video track,
   /// to test whether it is appropriate for use with the
   /// <code>MediaStreamVideoTrack</code> constructor.
diff --git a/ppapi/cpp/video_decoder.cc b/ppapi/cpp/video_decoder.cc
new file mode 100644
index 0000000..3277a21
--- /dev/null
+++ b/ppapi/cpp/video_decoder.cc
@@ -0,0 +1,96 @@
+// Copyright (c) 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.
+
+#include "ppapi/cpp/video_decoder.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_video_decoder.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/instance_handle.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+template <>
+const char* interface_name<PPB_VideoDecoder_0_1>() {
+  return PPB_VIDEODECODER_INTERFACE_0_1;
+}
+
+}  // namespace
+
+VideoDecoder::VideoDecoder() {
+}
+
+VideoDecoder::VideoDecoder(const InstanceHandle& instance) {
+  if (has_interface<PPB_VideoDecoder_0_1>()) {
+    PassRefFromConstructor(
+        get_interface<PPB_VideoDecoder_0_1>()->Create(instance.pp_instance()));
+  }
+}
+
+VideoDecoder::VideoDecoder(const VideoDecoder& other) : Resource(other) {
+}
+
+int32_t VideoDecoder::Initialize(const Graphics3D& context,
+                                 PP_VideoProfile profile,
+                                 bool allow_software_fallback,
+                                 const CompletionCallback& cc) {
+  if (has_interface<PPB_VideoDecoder_0_1>()) {
+    return get_interface<PPB_VideoDecoder_0_1>()->Initialize(
+        pp_resource(),
+        context.pp_resource(),
+        profile,
+        PP_FromBool(allow_software_fallback),
+        cc.pp_completion_callback());
+  }
+  return cc.MayForce(PP_ERROR_NOINTERFACE);
+}
+
+int32_t VideoDecoder::Decode(uint32_t decode_id,
+                             uint32_t size,
+                             const void* buffer,
+                             const CompletionCallback& cc) {
+  if (has_interface<PPB_VideoDecoder_0_1>()) {
+    return get_interface<PPB_VideoDecoder_0_1>()->Decode(
+        pp_resource(), decode_id, size, buffer, cc.pp_completion_callback());
+  }
+  return cc.MayForce(PP_ERROR_NOINTERFACE);
+}
+
+int32_t VideoDecoder::GetPicture(
+    const CompletionCallbackWithOutput<PP_VideoPicture>& cc) {
+  if (has_interface<PPB_VideoDecoder_0_1>()) {
+    return get_interface<PPB_VideoDecoder_0_1>()->GetPicture(
+        pp_resource(), cc.output(), cc.pp_completion_callback());
+  }
+  return cc.MayForce(PP_ERROR_NOINTERFACE);
+}
+
+void VideoDecoder::RecyclePicture(const PP_VideoPicture& picture) {
+  if (has_interface<PPB_VideoDecoder_0_1>()) {
+    get_interface<PPB_VideoDecoder_0_1>()->RecyclePicture(pp_resource(),
+                                                          &picture);
+  }
+}
+
+int32_t VideoDecoder::Flush(const CompletionCallback& cc) {
+  if (has_interface<PPB_VideoDecoder_0_1>()) {
+    return get_interface<PPB_VideoDecoder_0_1>()->Flush(
+        pp_resource(), cc.pp_completion_callback());
+  }
+  return cc.MayForce(PP_ERROR_NOINTERFACE);
+}
+
+int32_t VideoDecoder::Reset(const CompletionCallback& cc) {
+  if (has_interface<PPB_VideoDecoder_0_1>()) {
+    return get_interface<PPB_VideoDecoder_0_1>()->Reset(
+        pp_resource(), cc.pp_completion_callback());
+  }
+  return cc.MayForce(PP_ERROR_NOINTERFACE);
+}
+
+}  // namespace pp
diff --git a/ppapi/cpp/video_decoder.h b/ppapi/cpp/video_decoder.h
new file mode 100644
index 0000000..f1f2d91
--- /dev/null
+++ b/ppapi/cpp/video_decoder.h
@@ -0,0 +1,168 @@
+// Copyright (c) 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.
+
+#ifndef PPAPI_CPP_VIDEO_DECODER_H_
+#define PPAPI_CPP_VIDEO_DECODER_H_
+
+#include "ppapi/c/pp_codecs.h"
+#include "ppapi/c/pp_size.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/graphics_3d.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/size.h"
+
+/// @file
+/// This file defines the API to create and use a VideoDecoder resource.
+
+struct PP_FileInfo;
+
+namespace pp {
+
+class InstanceHandle;
+
+/// Video decoder interface.
+///
+/// Typical usage:
+/// - Call Create() to create a new video decoder resource.
+/// - Call Initialize() to initialize it with a 3d graphics context and the
+///   desired codec profile.
+/// - Call Decode() continuously (waiting for each previous call to complete) to
+///   push bitstream buffers to the decoder.
+/// - Call GetPicture() continuously (waiting for each previous call to
+///   complete) to pull decoded pictures from the decoder.
+/// - Call Flush() to signal end of stream to the decoder and perform shutdown
+///   when it completes.
+/// - Call Reset() to quickly stop the decoder (e.g. to implement Seek) and wait
+///   for the callback before restarting decoding at another point.
+/// - To destroy the decoder, the plugin should release all of its references to
+///   it. Any pending callbacks will abort before the decoder is destroyed.
+///
+/// Available video codecs vary by platform.
+/// All: theora, vorbis, vp8.
+/// Chrome and ChromeOS: aac, h264.
+/// ChromeOS: mpeg4.
+class VideoDecoder : public Resource {
+ public:
+  /// Default constructor for creating an is_null() <code>VideoDecoder</code>
+  /// object.
+  VideoDecoder();
+
+  /// A constructor used to create a <code>VideoDecoder</code> and associate it
+  /// with the provided <code>Instance</code>.
+  /// @param[in] instance The instance with which this resource will be
+  /// associated.
+  explicit VideoDecoder(const InstanceHandle& instance);
+
+  /// The copy constructor for <code>VideoDecoder</code>.
+  /// @param[in] other A reference to a <code>VideoDecoder</code>.
+  VideoDecoder(const VideoDecoder& other);
+
+  /// Initializes a video decoder resource. This should be called after Create()
+  /// and before any other functions.
+  ///
+  /// @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+  /// decoder.
+  /// @param[in] profile A <code>PP_VideoProfile</code> specifying the video
+  /// codec profile.
+  /// @param[in] allow_software_fallback A <code>PP_Bool</code> specifying
+  /// whether the decoder can fall back to software decoding if a suitable
+  /// hardware decoder isn't available.
+  /// @param[in] callback A <code>CompletionCallback</code> to be called on
+  /// completion.
+  ///
+  /// @return An int32_t containing an error code from <code>pp_errors.h</code>.
+  /// Returns PP_ERROR_NOTSUPPORTED if video decoding is not available, or the
+  /// requested profile is not supported. In this case, the client may call
+  /// Initialize() again with different parameters to find a good configuration.
+  int32_t Initialize(const Graphics3D& graphics3d_context,
+                     PP_VideoProfile profile,
+                     bool allow_software_fallback,
+                     const CompletionCallback& callback);
+
+  /// Decodes a bitstream buffer. Copies |size| bytes of data from the plugin's
+  /// |buffer|. The plugin should maintain the buffer and not call Decode()
+  /// again until the decoder signals completion by returning PP_OK or by
+  /// running |callback|.
+  ///
+  /// In general, each bitstream buffer should contain a demuxed bitstream frame
+  /// for the selected video codec. For example, H264 decoders expect to receive
+  /// one AnnexB NAL unit, including the 4 byte start code prefix, while VP8
+  /// decoders expect to receive a bitstream frame without the IVF frame header.
+  ///
+  /// If the call to Decode() eventually results in a picture, the |decode_id|
+  /// parameter is copied into the returned picture. The plugin can use this to
+  /// associate decoded pictures with Decode() calls (e.g. to assign timestamps
+  /// or frame numbers to pictures.) This value is opaque to the API so the
+  /// plugin is free to pass any value.
+  ///
+  /// @param[in] decode_id An optional value, chosen by the plugin, that can be
+  /// used to associate calls to Decode() with decoded pictures returned by
+  /// GetPicture().
+  /// @param[in] size Buffer size in bytes.
+  /// @param[in] buffer Starting address of buffer.
+  /// @param[in] callback A <code>CompletionCallback</code> to be called on
+  /// completion.
+  ///
+  /// @return An int32_t containing an error code from <code>pp_errors.h</code>.
+  int32_t Decode(uint32_t decode_id,
+                 uint32_t size,
+                 const void* buffer,
+                 const CompletionCallback& callback);
+
+  /// Gets the next picture from the decoder. The picture is valid after the
+  /// decoder signals completion by returning PP_OK or running |callback|. The
+  /// plugin can call GetPicture() again after the decoder signals completion.
+  /// When the plugin is finished using the picture, it should return it to the
+  /// system by calling RecyclePicture().
+  ///
+  /// @param[in] video_decoder A <code>PP_Resource</code> identifying the video
+  /// decoder.
+  /// @param[in] callback A <code>CompletionCallbackWithOutput</code> to be
+  /// called on completion, and on success, to hold the picture descriptor.
+  ///
+  /// @return An int32_t containing an error code from <code>pp_errors.h</code>.
+  /// Returns PP_OK if a picture is available.
+  /// Returns PP_ERROR_ABORTED when Reset() is called, or if a call to Flush()
+  /// completes while GetPicture() is pending.
+  int32_t GetPicture(
+      const CompletionCallbackWithOutput<PP_VideoPicture>& callback);
+
+  /// Recycles a picture that the plugin has received from the decoder.
+  /// The plugin should call this as soon as it has finished using the texture
+  /// so the decoder can decode more pictures.
+  ///
+  /// @param[in] picture A <code>PP_VideoPicture</code> to return to the
+  /// decoder.
+  void RecyclePicture(const PP_VideoPicture& picture);
+
+  /// Flushes the decoder. The plugin should call this when it reaches the end
+  /// of its video stream in order to stop cleanly. The decoder will run all
+  /// pending calls to completion. The plugin should make no further calls to
+  /// the decoder other than GetPicture() and RecyclePicture() until the decoder
+  /// signals completion by running the callback. Just before completion, any
+  /// pending GetPicture() call will complete by running the callback with
+  /// result PP_ERROR_ABORTED to signal that no more pictures are available.
+  ///
+  /// @param[in] callback A <code>CompletionCallback</code> to be called on
+  /// completion.
+  ///
+  /// @return An int32_t containing an error code from <code>pp_errors.h</code>.
+  int32_t Flush(const CompletionCallback& callback);
+
+  /// Resets the decoder as quickly as possible. The plugin can call Reset() to
+  /// skip to another position in the video stream. Pending calls to Decode()
+  /// and GetPicture()) are immediately aborted, causing their callbacks to run
+  /// with PP_ERROR_ABORTED. The plugin should not make any further calls to the
+  /// decoder until the decoder signals completion by running |callback|.
+  ///
+  /// @param[in] callback A <code>CompletionCallback</code> to be called on
+  /// completion.
+  ///
+  /// @return An int32_t containing an error code from <code>pp_errors.h</code>.
+  int32_t Reset(const CompletionCallback& callback);
+};
+
+}  // namespace pp
+
+#endif  // PPAPI_CPP_VIDEO_DECODER_H_
diff --git a/ppapi/examples/video_decode/video_decode.cc b/ppapi/examples/video_decode/video_decode.cc
deleted file mode 100644
index d1f7181..0000000
--- a/ppapi/examples/video_decode/video_decode.cc
+++ /dev/null
@@ -1,685 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include <string.h>
-
-#include <iostream>
-#include <sstream>
-#include <list>
-#include <map>
-#include <set>
-#include <vector>
-
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/c/ppb_console.h"
-#include "ppapi/c/ppb_opengles2.h"
-#include "ppapi/cpp/dev/video_decoder_client_dev.h"
-#include "ppapi/cpp/dev/video_decoder_dev.h"
-#include "ppapi/cpp/graphics_3d.h"
-#include "ppapi/cpp/graphics_3d_client.h"
-#include "ppapi/cpp/instance.h"
-#include "ppapi/cpp/module.h"
-#include "ppapi/cpp/rect.h"
-#include "ppapi/cpp/var.h"
-#include "ppapi/examples/video_decode/testdata.h"
-#include "ppapi/lib/gl/include/GLES2/gl2.h"
-#include "ppapi/lib/gl/include/GLES2/gl2ext.h"
-#include "ppapi/utility/completion_callback_factory.h"
-
-// Use assert as a poor-man's CHECK, even in non-debug mode.
-// Since <assert.h> redefines assert on every inclusion (it doesn't use
-// include-guards), make sure this is the last file #include'd in this file.
-#undef NDEBUG
-#include <assert.h>
-
-// Assert |context_| isn't holding any GL Errors.  Done as a macro instead of a
-// function to preserve line number information in the failure message.
-#define assertNoGLError() \
-  assert(!gles2_if_->GetError(context_->pp_resource()));
-
-namespace {
-
-struct PictureBufferInfo {
-  PP_PictureBuffer_Dev buffer;
-  GLenum texture_target;
-};
-
-struct Shader {
-  Shader() : program(0),
-             texcoord_scale_location(0) {}
-
-  GLuint program;
-  GLint texcoord_scale_location;
-};
-
-class VideoDecodeDemoInstance : public pp::Instance,
-                                public pp::Graphics3DClient,
-                                public pp::VideoDecoderClient_Dev {
- public:
-  VideoDecodeDemoInstance(PP_Instance instance, pp::Module* module);
-  virtual ~VideoDecodeDemoInstance();
-
-  // pp::Instance implementation (see PPP_Instance).
-  virtual void DidChangeView(const pp::Rect& position,
-                             const pp::Rect& clip_ignored);
-
-  // pp::Graphics3DClient implementation.
-  virtual void Graphics3DContextLost() {
-    // TODO(vrk/fischman): Properly reset after a lost graphics context.  In
-    // particular need to delete context_ and re-create textures.
-    // Probably have to recreate the decoder from scratch, because old textures
-    // can still be outstanding in the decoder!
-    assert(false && "Unexpectedly lost graphics context");
-  }
-
-  // pp::VideoDecoderClient_Dev implementation.
-  virtual void ProvidePictureBuffers(
-      PP_Resource decoder,
-      uint32_t req_num_of_bufs,
-      const PP_Size& dimensions,
-      uint32_t texture_target);
-  virtual void DismissPictureBuffer(PP_Resource decoder,
-                                    int32_t picture_buffer_id);
-  virtual void PictureReady(PP_Resource decoder, const PP_Picture_Dev& picture);
-  virtual void NotifyError(PP_Resource decoder, PP_VideoDecodeError_Dev error);
-
- private:
-  enum { kNumConcurrentDecodes = 7,
-         kNumDecoders = 2 };  // Baked into viewport rendering.
-
-  // A single decoder's client interface.
-  class DecoderClient {
-   public:
-    DecoderClient(VideoDecodeDemoInstance* gles2,
-                  pp::VideoDecoder_Dev* decoder);
-    ~DecoderClient();
-
-    void DecodeNextNALUs();
-
-    // Per-decoder implementation of part of pp::VideoDecoderClient_Dev.
-    void ProvidePictureBuffers(
-        uint32_t req_num_of_bufs,
-        PP_Size dimensions,
-        uint32_t texture_target);
-    void DismissPictureBuffer(int32_t picture_buffer_id);
-
-    const PictureBufferInfo& GetPictureBufferInfoById(int id);
-    pp::VideoDecoder_Dev* decoder() { return decoder_; }
-
-   private:
-    void DecodeNextNALU();
-    static void GetNextNALUBoundary(size_t start_pos, size_t* end_pos);
-    void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id);
-    void DecoderFlushDone(int32_t result);
-
-    VideoDecodeDemoInstance* gles2_;
-    pp::VideoDecoder_Dev* decoder_;
-    pp::CompletionCallbackFactory<DecoderClient> callback_factory_;
-    int next_picture_buffer_id_;
-    int next_bitstream_buffer_id_;
-    size_t encoded_data_next_pos_to_decode_;
-    std::set<int> bitstream_ids_at_decoder_;
-    // Map of texture buffers indexed by buffer id.
-    typedef std::map<int, PictureBufferInfo> PictureBufferMap;
-    PictureBufferMap picture_buffers_by_id_;
-    // Map of bitstream buffers indexed by id.
-    typedef std::map<int, pp::Buffer_Dev*> BitstreamBufferMap;
-    BitstreamBufferMap bitstream_buffers_by_id_;
-  };
-
-  // Initialize Video Decoders.
-  void InitializeDecoders();
-
-  // GL-related functions.
-  void InitGL();
-  GLuint CreateTexture(int32_t width, int32_t height, GLenum texture_target);
-  void CreateGLObjects();
-  void Create2DProgramOnce();
-  void CreateRectangleARBProgramOnce();
-  Shader CreateProgram(const char* vertex_shader,
-                       const char* fragment_shader);
-  void CreateShader(GLuint program, GLenum type, const char* source, int size);
-  void DeleteTexture(GLuint id);
-  void PaintFinished(int32_t result, PP_Resource decoder,
-                     int picture_buffer_id);
-
-  // Log an error to the developer console and stderr (though the latter may be
-  // closed due to sandboxing or blackholed for other reasons) by creating a
-  // temporary of this type and streaming to it.  Example usage:
-  // LogError(this).s() << "Hello world: " << 42;
-  class LogError {
-   public:
-    LogError(VideoDecodeDemoInstance* demo) : demo_(demo) {}
-    ~LogError() {
-      const std::string& msg = stream_.str();
-      demo_->console_if_->Log(demo_->pp_instance(), PP_LOGLEVEL_ERROR,
-                              pp::Var(msg).pp_var());
-      std::cerr << msg << std::endl;
-    }
-    // Impl note: it would have been nicer to have LogError derive from
-    // std::ostringstream so that it can be streamed to directly, but lookup
-    // rules turn streamed string literals to hex pointers on output.
-    std::ostringstream& s() { return stream_; }
-   private:
-    VideoDecodeDemoInstance* demo_;  // Unowned.
-    std::ostringstream stream_;
-  };
-
-  pp::Size plugin_size_;
-  bool is_painting_;
-  // When decode outpaces render, we queue up decoded pictures for later
-  // painting.  Elements are <decoder,picture>.
-  std::list<std::pair<PP_Resource, PP_Picture_Dev> > pictures_pending_paint_;
-  int num_frames_rendered_;
-  PP_TimeTicks first_frame_delivered_ticks_;
-  PP_TimeTicks last_swap_request_ticks_;
-  PP_TimeTicks swap_ticks_;
-  pp::CompletionCallbackFactory<VideoDecodeDemoInstance> callback_factory_;
-
-  // Unowned pointers.
-  const PPB_Console* console_if_;
-  const PPB_Core* core_if_;
-  const PPB_OpenGLES2* gles2_if_;
-
-  // Owned data.
-  pp::Graphics3D* context_;
-  typedef std::map<int, DecoderClient*> Decoders;
-  Decoders video_decoders_;
-
-  // Shader program to draw GL_TEXTURE_2D target.
-  Shader shader_2d_;
-  // Shader program to draw GL_TEXTURE_RECTANGLE_ARB target.
-  Shader shader_rectangle_arb_;
-};
-
-VideoDecodeDemoInstance::DecoderClient::DecoderClient(
-      VideoDecodeDemoInstance* gles2, pp::VideoDecoder_Dev* decoder)
-    : gles2_(gles2), decoder_(decoder), callback_factory_(this),
-      next_picture_buffer_id_(0),
-      next_bitstream_buffer_id_(0), encoded_data_next_pos_to_decode_(0) {
-}
-
-VideoDecodeDemoInstance::DecoderClient::~DecoderClient() {
-  delete decoder_;
-  decoder_ = NULL;
-
-  for (BitstreamBufferMap::iterator it = bitstream_buffers_by_id_.begin();
-       it != bitstream_buffers_by_id_.end(); ++it) {
-    delete it->second;
-  }
-  bitstream_buffers_by_id_.clear();
-
-  for (PictureBufferMap::iterator it = picture_buffers_by_id_.begin();
-       it != picture_buffers_by_id_.end(); ++it) {
-    gles2_->DeleteTexture(it->second.buffer.texture_id);
-  }
-  picture_buffers_by_id_.clear();
-}
-
-VideoDecodeDemoInstance::VideoDecodeDemoInstance(PP_Instance instance,
-                                                 pp::Module* module)
-    : pp::Instance(instance), pp::Graphics3DClient(this),
-      pp::VideoDecoderClient_Dev(this),
-      is_painting_(false),
-      num_frames_rendered_(0),
-      first_frame_delivered_ticks_(-1),
-      swap_ticks_(0),
-      callback_factory_(this),
-      context_(NULL) {
-  assert((console_if_ = static_cast<const PPB_Console*>(
-      module->GetBrowserInterface(PPB_CONSOLE_INTERFACE))));
-  assert((core_if_ = static_cast<const PPB_Core*>(
-      module->GetBrowserInterface(PPB_CORE_INTERFACE))));
-  assert((gles2_if_ = static_cast<const PPB_OpenGLES2*>(
-      module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE))));
-}
-
-VideoDecodeDemoInstance::~VideoDecodeDemoInstance() {
-  if (shader_2d_.program)
-    gles2_if_->DeleteProgram(context_->pp_resource(), shader_2d_.program);
-  if (shader_rectangle_arb_.program) {
-    gles2_if_->DeleteProgram(
-        context_->pp_resource(), shader_rectangle_arb_.program);
-  }
-
-  for (Decoders::iterator it = video_decoders_.begin();
-       it != video_decoders_.end(); ++it) {
-    delete it->second;
-  }
-  video_decoders_.clear();
-  delete context_;
-}
-
-void VideoDecodeDemoInstance::DidChangeView(
-    const pp::Rect& position, const pp::Rect& clip_ignored) {
-  if (position.width() == 0 || position.height() == 0)
-    return;
-  if (plugin_size_.width()) {
-    assert(position.size() == plugin_size_);
-    return;
-  }
-  plugin_size_ = position.size();
-
-  // Initialize graphics.
-  InitGL();
-  InitializeDecoders();
-}
-
-void VideoDecodeDemoInstance::InitializeDecoders() {
-  assert(video_decoders_.empty());
-  for (int i = 0; i < kNumDecoders; ++i) {
-    DecoderClient* client = new DecoderClient(
-        this, new pp::VideoDecoder_Dev(
-            this, *context_, PP_VIDEODECODER_H264PROFILE_MAIN));
-    assert(!client->decoder()->is_null());
-    assert(video_decoders_.insert(std::make_pair(
-        client->decoder()->pp_resource(), client)).second);
-    client->DecodeNextNALUs();
-  }
-}
-
-void VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone(
-    int32_t result, int bitstream_buffer_id) {
-  assert(bitstream_ids_at_decoder_.erase(bitstream_buffer_id) == 1);
-  BitstreamBufferMap::iterator it =
-      bitstream_buffers_by_id_.find(bitstream_buffer_id);
-  assert(it != bitstream_buffers_by_id_.end());
-  delete it->second;
-  bitstream_buffers_by_id_.erase(it);
-  DecodeNextNALUs();
-}
-
-void VideoDecodeDemoInstance::DecoderClient::DecoderFlushDone(int32_t result) {
-  assert(result == PP_OK);
-  // Check that each bitstream buffer ID we handed to the decoder got handed
-  // back to us.
-  assert(bitstream_ids_at_decoder_.empty());
-  delete decoder_;
-  decoder_ = NULL;
-}
-
-static bool LookingAtNAL(const unsigned char* encoded, size_t pos) {
-  return pos + 3 < kDataLen &&
-      encoded[pos] == 0 && encoded[pos + 1] == 0 &&
-      encoded[pos + 2] == 0 && encoded[pos + 3] == 1;
-}
-
-void VideoDecodeDemoInstance::DecoderClient::GetNextNALUBoundary(
-    size_t start_pos, size_t* end_pos) {
-  assert(LookingAtNAL(kData, start_pos));
-  *end_pos = start_pos;
-  *end_pos += 4;
-  while (*end_pos + 3 < kDataLen &&
-         !LookingAtNAL(kData, *end_pos)) {
-    ++*end_pos;
-  }
-  if (*end_pos + 3 >= kDataLen) {
-    *end_pos = kDataLen;
-    return;
-  }
-}
-
-void VideoDecodeDemoInstance::DecoderClient::DecodeNextNALUs() {
-  while (encoded_data_next_pos_to_decode_ <= kDataLen &&
-         bitstream_ids_at_decoder_.size() < kNumConcurrentDecodes) {
-    DecodeNextNALU();
-  }
-}
-
-void VideoDecodeDemoInstance::DecoderClient::DecodeNextNALU() {
-  if (encoded_data_next_pos_to_decode_ == kDataLen) {
-    ++encoded_data_next_pos_to_decode_;
-    pp::CompletionCallback cb = callback_factory_.NewCallback(
-        &VideoDecodeDemoInstance::DecoderClient::DecoderFlushDone);
-    decoder_->Flush(cb);
-    return;
-  }
-  size_t start_pos = encoded_data_next_pos_to_decode_;
-  size_t end_pos;
-  GetNextNALUBoundary(start_pos, &end_pos);
-  pp::Buffer_Dev* buffer = new pp::Buffer_Dev(gles2_, end_pos - start_pos);
-  PP_VideoBitstreamBuffer_Dev bitstream_buffer;
-  int id = ++next_bitstream_buffer_id_;
-  bitstream_buffer.id = id;
-  bitstream_buffer.size = end_pos - start_pos;
-  bitstream_buffer.data = buffer->pp_resource();
-  memcpy(buffer->data(), kData + start_pos, end_pos - start_pos);
-  assert(bitstream_buffers_by_id_.insert(std::make_pair(id, buffer)).second);
-
-  pp::CompletionCallback cb =
-      callback_factory_.NewCallback(
-          &VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone, id);
-  assert(bitstream_ids_at_decoder_.insert(id).second);
-  encoded_data_next_pos_to_decode_ = end_pos;
-  decoder_->Decode(bitstream_buffer, cb);
-}
-
-void VideoDecodeDemoInstance::ProvidePictureBuffers(PP_Resource decoder,
-                                                    uint32_t req_num_of_bufs,
-                                                    const PP_Size& dimensions,
-                                                    uint32_t texture_target) {
-  DecoderClient* client = video_decoders_[decoder];
-  assert(client);
-  client->ProvidePictureBuffers(req_num_of_bufs, dimensions, texture_target);
-}
-
-void VideoDecodeDemoInstance::DecoderClient::ProvidePictureBuffers(
-    uint32_t req_num_of_bufs,
-    PP_Size dimensions,
-    uint32_t texture_target) {
-  std::vector<PP_PictureBuffer_Dev> buffers;
-  for (uint32_t i = 0; i < req_num_of_bufs; ++i) {
-    PictureBufferInfo info;
-    info.buffer.size = dimensions;
-    info.texture_target = texture_target;
-    info.buffer.texture_id = gles2_->CreateTexture(
-        dimensions.width, dimensions.height, info.texture_target);
-    int id = ++next_picture_buffer_id_;
-    info.buffer.id = id;
-    buffers.push_back(info.buffer);
-    assert(picture_buffers_by_id_.insert(std::make_pair(id, info)).second);
-  }
-  decoder_->AssignPictureBuffers(buffers);
-}
-
-const PictureBufferInfo&
-VideoDecodeDemoInstance::DecoderClient::GetPictureBufferInfoById(
-    int id) {
-  PictureBufferMap::iterator it = picture_buffers_by_id_.find(id);
-  assert(it != picture_buffers_by_id_.end());
-  return it->second;
-}
-
-void VideoDecodeDemoInstance::DismissPictureBuffer(PP_Resource decoder,
-                                             int32_t picture_buffer_id) {
-  DecoderClient* client = video_decoders_[decoder];
-  assert(client);
-  client->DismissPictureBuffer(picture_buffer_id);
-}
-
-void VideoDecodeDemoInstance::DecoderClient::DismissPictureBuffer(
-    int32_t picture_buffer_id) {
-  gles2_->DeleteTexture(GetPictureBufferInfoById(
-      picture_buffer_id).buffer.texture_id);
-  picture_buffers_by_id_.erase(picture_buffer_id);
-}
-
-void VideoDecodeDemoInstance::PictureReady(PP_Resource decoder,
-                                     const PP_Picture_Dev& picture) {
-  if (first_frame_delivered_ticks_ == -1)
-    assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1);
-  if (is_painting_) {
-    pictures_pending_paint_.push_back(std::make_pair(decoder, picture));
-    return;
-  }
-  DecoderClient* client = video_decoders_[decoder];
-  assert(client);
-  const PictureBufferInfo& info =
-      client->GetPictureBufferInfoById(picture.picture_buffer_id);
-  assert(!is_painting_);
-  is_painting_ = true;
-  int x = 0;
-  int y = 0;
-  if (client != video_decoders_.begin()->second) {
-    x = plugin_size_.width() / kNumDecoders;
-    y = plugin_size_.height() / kNumDecoders;
-  }
-
-  if (info.texture_target == GL_TEXTURE_2D) {
-    Create2DProgramOnce();
-    gles2_if_->UseProgram(context_->pp_resource(), shader_2d_.program);
-    gles2_if_->Uniform2f(
-        context_->pp_resource(), shader_2d_.texcoord_scale_location, 1.0, 1.0);
-  } else {
-    assert(info.texture_target == GL_TEXTURE_RECTANGLE_ARB);
-    CreateRectangleARBProgramOnce();
-    gles2_if_->UseProgram(
-        context_->pp_resource(), shader_rectangle_arb_.program);
-    gles2_if_->Uniform2f(context_->pp_resource(),
-                         shader_rectangle_arb_.texcoord_scale_location,
-                         info.buffer.size.width,
-                         info.buffer.size.height);
-  }
-
-  gles2_if_->Viewport(context_->pp_resource(), x, y,
-                      plugin_size_.width() / kNumDecoders,
-                      plugin_size_.height() / kNumDecoders);
-  gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
-  gles2_if_->BindTexture(
-      context_->pp_resource(), info.texture_target, info.buffer.texture_id);
-  gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4);
-
-  gles2_if_->UseProgram(context_->pp_resource(), 0);
-
-  pp::CompletionCallback cb =
-      callback_factory_.NewCallback(
-          &VideoDecodeDemoInstance::PaintFinished, decoder, info.buffer.id);
-  last_swap_request_ticks_ = core_if_->GetTimeTicks();
-  assert(context_->SwapBuffers(cb) == PP_OK_COMPLETIONPENDING);
-}
-
-void VideoDecodeDemoInstance::NotifyError(PP_Resource decoder,
-                                          PP_VideoDecodeError_Dev error) {
-  LogError(this).s() << "Received error: " << error;
-  assert(false && "Unexpected error; see stderr for details");
-}
-
-// This object is the global object representing this plugin library as long
-// as it is loaded.
-class VideoDecodeDemoModule : public pp::Module {
- public:
-  VideoDecodeDemoModule() : pp::Module() {}
-  virtual ~VideoDecodeDemoModule() {}
-
-  virtual pp::Instance* CreateInstance(PP_Instance instance) {
-    return new VideoDecodeDemoInstance(instance, this);
-  }
-};
-
-void VideoDecodeDemoInstance::InitGL() {
-  assert(plugin_size_.width() && plugin_size_.height());
-  is_painting_ = false;
-
-  assert(!context_);
-  int32_t context_attributes[] = {
-    PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
-    PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
-    PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8,
-    PP_GRAPHICS3DATTRIB_RED_SIZE, 8,
-    PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0,
-    PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0,
-    PP_GRAPHICS3DATTRIB_SAMPLES, 0,
-    PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0,
-    PP_GRAPHICS3DATTRIB_WIDTH, plugin_size_.width(),
-    PP_GRAPHICS3DATTRIB_HEIGHT, plugin_size_.height(),
-    PP_GRAPHICS3DATTRIB_NONE,
-  };
-  context_ = new pp::Graphics3D(this, context_attributes);
-  assert(!context_->is_null());
-  assert(BindGraphics(*context_));
-
-  // Clear color bit.
-  gles2_if_->ClearColor(context_->pp_resource(), 1, 0, 0, 1);
-  gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
-
-  assertNoGLError();
-
-  CreateGLObjects();
-}
-
-void VideoDecodeDemoInstance::PaintFinished(int32_t result, PP_Resource decoder,
-                                      int picture_buffer_id) {
-  assert(result == PP_OK);
-  swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_;
-  is_painting_ = false;
-  ++num_frames_rendered_;
-  if (num_frames_rendered_ % 50 == 0) {
-    double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_;
-    double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000;
-    double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_;
-    LogError(this).s() << "Rendered frames: " << num_frames_rendered_
-                       << ", fps: " << fps << ", with average ms/swap of: "
-                       << ms_per_swap;
-  }
-  DecoderClient* client = video_decoders_[decoder];
-  if (client && client->decoder())
-    client->decoder()->ReusePictureBuffer(picture_buffer_id);
-  if (!pictures_pending_paint_.empty()) {
-    std::pair<PP_Resource, PP_Picture_Dev> decoder_picture =
-        pictures_pending_paint_.front();
-    pictures_pending_paint_.pop_front();
-    PictureReady(decoder_picture.first, decoder_picture.second);
-  }
-}
-
-GLuint VideoDecodeDemoInstance::CreateTexture(int32_t width,
-                                              int32_t height,
-                                              GLenum texture_target) {
-  GLuint texture_id;
-  gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id);
-  assertNoGLError();
-  // Assign parameters.
-  gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
-  gles2_if_->BindTexture(context_->pp_resource(), texture_target, texture_id);
-  gles2_if_->TexParameteri(
-      context_->pp_resource(), texture_target, GL_TEXTURE_MIN_FILTER,
-      GL_NEAREST);
-  gles2_if_->TexParameteri(
-      context_->pp_resource(), texture_target, GL_TEXTURE_MAG_FILTER,
-      GL_NEAREST);
-  gles2_if_->TexParameterf(
-      context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_S,
-      GL_CLAMP_TO_EDGE);
-  gles2_if_->TexParameterf(
-      context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_T,
-      GL_CLAMP_TO_EDGE);
-
-  if (texture_target == GL_TEXTURE_2D) {
-    gles2_if_->TexImage2D(
-        context_->pp_resource(), texture_target, 0, GL_RGBA, width, height, 0,
-        GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-  }
-  assertNoGLError();
-  return texture_id;
-}
-
-void VideoDecodeDemoInstance::DeleteTexture(GLuint id) {
-  gles2_if_->DeleteTextures(context_->pp_resource(), 1, &id);
-}
-
-void VideoDecodeDemoInstance::CreateGLObjects() {
-  // Assign vertex positions and texture coordinates to buffers for use in
-  // shader program.
-  static const float kVertices[] = {
-    -1, 1, -1, -1, 1, 1, 1, -1,  // Position coordinates.
-    0, 1, 0, 0, 1, 1, 1, 0,      // Texture coordinates.
-  };
-
-  GLuint buffer;
-  gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer);
-  gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer);
-
-  gles2_if_->BufferData(context_->pp_resource(), GL_ARRAY_BUFFER,
-                        sizeof(kVertices), kVertices, GL_STATIC_DRAW);
-  assertNoGLError();
-}
-
-static const char kVertexShader[] =
-    "varying vec2 v_texCoord;            \n"
-    "attribute vec4 a_position;          \n"
-    "attribute vec2 a_texCoord;          \n"
-    "uniform vec2 v_scale;               \n"
-    "void main()                         \n"
-    "{                                   \n"
-    "    v_texCoord = v_scale * a_texCoord; \n"
-    "    gl_Position = a_position;       \n"
-    "}";
-
-void VideoDecodeDemoInstance::Create2DProgramOnce() {
-  if (shader_2d_.program)
-    return;
-  static const char kFragmentShader2D[] =
-      "precision mediump float;            \n"
-      "varying vec2 v_texCoord;            \n"
-      "uniform sampler2D s_texture;        \n"
-      "void main()                         \n"
-      "{"
-      "    gl_FragColor = texture2D(s_texture, v_texCoord); \n"
-      "}";
-  shader_2d_ = CreateProgram(kVertexShader, kFragmentShader2D);
-  assertNoGLError();
-}
-
-void VideoDecodeDemoInstance::CreateRectangleARBProgramOnce() {
-  if (shader_rectangle_arb_.program)
-    return;
-  static const char kFragmentShaderRectangle[] =
-      "#extension GL_ARB_texture_rectangle : require\n"
-      "precision mediump float;            \n"
-      "varying vec2 v_texCoord;            \n"
-      "uniform sampler2DRect s_texture;    \n"
-      "void main()                         \n"
-      "{"
-      "    gl_FragColor = texture2DRect(s_texture, v_texCoord).rgba; \n"
-      "}";
-  shader_rectangle_arb_ =
-      CreateProgram(kVertexShader, kFragmentShaderRectangle);
-}
-
-Shader VideoDecodeDemoInstance::CreateProgram(const char* vertex_shader,
-                                              const char* fragment_shader) {
-  Shader shader;
-
-  // Create shader program.
-  shader.program = gles2_if_->CreateProgram(context_->pp_resource());
-  CreateShader(shader.program, GL_VERTEX_SHADER, vertex_shader,
-               strlen(vertex_shader));
-  CreateShader(shader.program, GL_FRAGMENT_SHADER, fragment_shader,
-               strlen(fragment_shader));
-  gles2_if_->LinkProgram(context_->pp_resource(), shader.program);
-  gles2_if_->UseProgram(context_->pp_resource(), shader.program);
-  gles2_if_->Uniform1i(
-      context_->pp_resource(),
-      gles2_if_->GetUniformLocation(
-          context_->pp_resource(), shader.program, "s_texture"), 0);
-  assertNoGLError();
-
-  shader.texcoord_scale_location = gles2_if_->GetUniformLocation(
-      context_->pp_resource(), shader.program, "v_scale");
-
-  GLint pos_location = gles2_if_->GetAttribLocation(
-      context_->pp_resource(), shader.program, "a_position");
-  GLint tc_location = gles2_if_->GetAttribLocation(
-      context_->pp_resource(), shader.program, "a_texCoord");
-  assertNoGLError();
-
-  gles2_if_->EnableVertexAttribArray(context_->pp_resource(), pos_location);
-  gles2_if_->VertexAttribPointer(context_->pp_resource(), pos_location, 2,
-                                 GL_FLOAT, GL_FALSE, 0, 0);
-  gles2_if_->EnableVertexAttribArray(context_->pp_resource(), tc_location);
-  gles2_if_->VertexAttribPointer(
-      context_->pp_resource(), tc_location, 2, GL_FLOAT, GL_FALSE, 0,
-      static_cast<float*>(0) + 8);  // Skip position coordinates.
-
-  gles2_if_->UseProgram(context_->pp_resource(), 0);
-  assertNoGLError();
-  return shader;
-}
-
-void VideoDecodeDemoInstance::CreateShader(
-    GLuint program, GLenum type, const char* source, int size) {
-  GLuint shader = gles2_if_->CreateShader(context_->pp_resource(), type);
-  gles2_if_->ShaderSource(context_->pp_resource(), shader, 1, &source, &size);
-  gles2_if_->CompileShader(context_->pp_resource(), shader);
-  gles2_if_->AttachShader(context_->pp_resource(), program, shader);
-  gles2_if_->DeleteShader(context_->pp_resource(), shader);
-}
-}  // anonymous namespace
-
-namespace pp {
-// Factory function for your specialization of the Module object.
-Module* CreateModule() {
-  return new VideoDecodeDemoModule();
-}
-}  // namespace pp
diff --git a/ppapi/examples/video_decode/video_decode.html b/ppapi/examples/video_decode/video_decode.html
deleted file mode 100644
index 13d42fc..0000000
--- a/ppapi/examples/video_decode/video_decode.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <!--
-  Copyright (c) 2012 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.
-  -->
-<head>
-  <title>Video Decode Example</title>
-</head>
-
-<body>
-
-<embed id="plugin" type="application/x-ppapi-example-video-decode"
-       width="640" height="480"/>
-
-</body>
-</html>
diff --git a/ppapi/examples/video_decode/video_decode_dev.cc b/ppapi/examples/video_decode/video_decode_dev.cc
new file mode 100644
index 0000000..d6cb592
--- /dev/null
+++ b/ppapi/examples/video_decode/video_decode_dev.cc
@@ -0,0 +1,685 @@
+// Copyright (c) 2012 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.
+
+#include <string.h>
+
+#include <iostream>
+#include <list>
+#include <map>
+#include <set>
+#include <sstream>
+#include <vector>
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_console.h"
+#include "ppapi/c/ppb_opengles2.h"
+#include "ppapi/cpp/dev/video_decoder_client_dev.h"
+#include "ppapi/cpp/dev/video_decoder_dev.h"
+#include "ppapi/cpp/graphics_3d.h"
+#include "ppapi/cpp/graphics_3d_client.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/var.h"
+#include "ppapi/examples/video_decode/testdata.h"
+#include "ppapi/lib/gl/include/GLES2/gl2.h"
+#include "ppapi/lib/gl/include/GLES2/gl2ext.h"
+#include "ppapi/utility/completion_callback_factory.h"
+
+// Use assert as a poor-man's CHECK, even in non-debug mode.
+// Since <assert.h> redefines assert on every inclusion (it doesn't use
+// include-guards), make sure this is the last file #include'd in this file.
+#undef NDEBUG
+#include <assert.h>
+
+// Assert |context_| isn't holding any GL Errors.  Done as a macro instead of a
+// function to preserve line number information in the failure message.
+#define assertNoGLError() \
+  assert(!gles2_if_->GetError(context_->pp_resource()));
+
+namespace {
+
+struct PictureBufferInfo {
+  PP_PictureBuffer_Dev buffer;
+  GLenum texture_target;
+};
+
+struct Shader {
+  Shader() : program(0),
+             texcoord_scale_location(0) {}
+
+  GLuint program;
+  GLint texcoord_scale_location;
+};
+
+class VideoDecodeDemoInstance : public pp::Instance,
+                                public pp::Graphics3DClient,
+                                public pp::VideoDecoderClient_Dev {
+ public:
+  VideoDecodeDemoInstance(PP_Instance instance, pp::Module* module);
+  virtual ~VideoDecodeDemoInstance();
+
+  // pp::Instance implementation (see PPP_Instance).
+  virtual void DidChangeView(const pp::Rect& position,
+                             const pp::Rect& clip_ignored);
+
+  // pp::Graphics3DClient implementation.
+  virtual void Graphics3DContextLost() {
+    // TODO(vrk/fischman): Properly reset after a lost graphics context.  In
+    // particular need to delete context_ and re-create textures.
+    // Probably have to recreate the decoder from scratch, because old textures
+    // can still be outstanding in the decoder!
+    assert(false && "Unexpectedly lost graphics context");
+  }
+
+  // pp::VideoDecoderClient_Dev implementation.
+  virtual void ProvidePictureBuffers(
+      PP_Resource decoder,
+      uint32_t req_num_of_bufs,
+      const PP_Size& dimensions,
+      uint32_t texture_target);
+  virtual void DismissPictureBuffer(PP_Resource decoder,
+                                    int32_t picture_buffer_id);
+  virtual void PictureReady(PP_Resource decoder, const PP_Picture_Dev& picture);
+  virtual void NotifyError(PP_Resource decoder, PP_VideoDecodeError_Dev error);
+
+ private:
+  enum { kNumConcurrentDecodes = 7,
+         kNumDecoders = 2 };  // Baked into viewport rendering.
+
+  // A single decoder's client interface.
+  class DecoderClient {
+   public:
+    DecoderClient(VideoDecodeDemoInstance* gles2,
+                  pp::VideoDecoder_Dev* decoder);
+    ~DecoderClient();
+
+    void DecodeNextNALUs();
+
+    // Per-decoder implementation of part of pp::VideoDecoderClient_Dev.
+    void ProvidePictureBuffers(
+        uint32_t req_num_of_bufs,
+        PP_Size dimensions,
+        uint32_t texture_target);
+    void DismissPictureBuffer(int32_t picture_buffer_id);
+
+    const PictureBufferInfo& GetPictureBufferInfoById(int id);
+    pp::VideoDecoder_Dev* decoder() { return decoder_; }
+
+   private:
+    void DecodeNextNALU();
+    static void GetNextNALUBoundary(size_t start_pos, size_t* end_pos);
+    void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id);
+    void DecoderFlushDone(int32_t result);
+
+    VideoDecodeDemoInstance* gles2_;
+    pp::VideoDecoder_Dev* decoder_;
+    pp::CompletionCallbackFactory<DecoderClient> callback_factory_;
+    int next_picture_buffer_id_;
+    int next_bitstream_buffer_id_;
+    size_t encoded_data_next_pos_to_decode_;
+    std::set<int> bitstream_ids_at_decoder_;
+    // Map of texture buffers indexed by buffer id.
+    typedef std::map<int, PictureBufferInfo> PictureBufferMap;
+    PictureBufferMap picture_buffers_by_id_;
+    // Map of bitstream buffers indexed by id.
+    typedef std::map<int, pp::Buffer_Dev*> BitstreamBufferMap;
+    BitstreamBufferMap bitstream_buffers_by_id_;
+  };
+
+  // Initialize Video Decoders.
+  void InitializeDecoders();
+
+  // GL-related functions.
+  void InitGL();
+  GLuint CreateTexture(int32_t width, int32_t height, GLenum texture_target);
+  void CreateGLObjects();
+  void Create2DProgramOnce();
+  void CreateRectangleARBProgramOnce();
+  Shader CreateProgram(const char* vertex_shader,
+                       const char* fragment_shader);
+  void CreateShader(GLuint program, GLenum type, const char* source, int size);
+  void DeleteTexture(GLuint id);
+  void PaintFinished(int32_t result, PP_Resource decoder,
+                     int picture_buffer_id);
+
+  // Log an error to the developer console and stderr (though the latter may be
+  // closed due to sandboxing or blackholed for other reasons) by creating a
+  // temporary of this type and streaming to it.  Example usage:
+  // LogError(this).s() << "Hello world: " << 42;
+  class LogError {
+   public:
+    LogError(VideoDecodeDemoInstance* demo) : demo_(demo) {}
+    ~LogError() {
+      const std::string& msg = stream_.str();
+      demo_->console_if_->Log(demo_->pp_instance(), PP_LOGLEVEL_ERROR,
+                              pp::Var(msg).pp_var());
+      std::cerr << msg << std::endl;
+    }
+    // Impl note: it would have been nicer to have LogError derive from
+    // std::ostringstream so that it can be streamed to directly, but lookup
+    // rules turn streamed string literals to hex pointers on output.
+    std::ostringstream& s() { return stream_; }
+   private:
+    VideoDecodeDemoInstance* demo_;  // Unowned.
+    std::ostringstream stream_;
+  };
+
+  pp::Size plugin_size_;
+  bool is_painting_;
+  // When decode outpaces render, we queue up decoded pictures for later
+  // painting.  Elements are <decoder,picture>.
+  std::list<std::pair<PP_Resource, PP_Picture_Dev> > pictures_pending_paint_;
+  int num_frames_rendered_;
+  PP_TimeTicks first_frame_delivered_ticks_;
+  PP_TimeTicks last_swap_request_ticks_;
+  PP_TimeTicks swap_ticks_;
+  pp::CompletionCallbackFactory<VideoDecodeDemoInstance> callback_factory_;
+
+  // Unowned pointers.
+  const PPB_Console* console_if_;
+  const PPB_Core* core_if_;
+  const PPB_OpenGLES2* gles2_if_;
+
+  // Owned data.
+  pp::Graphics3D* context_;
+  typedef std::map<int, DecoderClient*> Decoders;
+  Decoders video_decoders_;
+
+  // Shader program to draw GL_TEXTURE_2D target.
+  Shader shader_2d_;
+  // Shader program to draw GL_TEXTURE_RECTANGLE_ARB target.
+  Shader shader_rectangle_arb_;
+};
+
+VideoDecodeDemoInstance::DecoderClient::DecoderClient(
+      VideoDecodeDemoInstance* gles2, pp::VideoDecoder_Dev* decoder)
+    : gles2_(gles2), decoder_(decoder), callback_factory_(this),
+      next_picture_buffer_id_(0),
+      next_bitstream_buffer_id_(0), encoded_data_next_pos_to_decode_(0) {
+}
+
+VideoDecodeDemoInstance::DecoderClient::~DecoderClient() {
+  delete decoder_;
+  decoder_ = NULL;
+
+  for (BitstreamBufferMap::iterator it = bitstream_buffers_by_id_.begin();
+       it != bitstream_buffers_by_id_.end(); ++it) {
+    delete it->second;
+  }
+  bitstream_buffers_by_id_.clear();
+
+  for (PictureBufferMap::iterator it = picture_buffers_by_id_.begin();
+       it != picture_buffers_by_id_.end(); ++it) {
+    gles2_->DeleteTexture(it->second.buffer.texture_id);
+  }
+  picture_buffers_by_id_.clear();
+}
+
+VideoDecodeDemoInstance::VideoDecodeDemoInstance(PP_Instance instance,
+                                                 pp::Module* module)
+    : pp::Instance(instance), pp::Graphics3DClient(this),
+      pp::VideoDecoderClient_Dev(this),
+      is_painting_(false),
+      num_frames_rendered_(0),
+      first_frame_delivered_ticks_(-1),
+      swap_ticks_(0),
+      callback_factory_(this),
+      context_(NULL) {
+  assert((console_if_ = static_cast<const PPB_Console*>(
+      module->GetBrowserInterface(PPB_CONSOLE_INTERFACE))));
+  assert((core_if_ = static_cast<const PPB_Core*>(
+      module->GetBrowserInterface(PPB_CORE_INTERFACE))));
+  assert((gles2_if_ = static_cast<const PPB_OpenGLES2*>(
+      module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE))));
+}
+
+VideoDecodeDemoInstance::~VideoDecodeDemoInstance() {
+  if (shader_2d_.program)
+    gles2_if_->DeleteProgram(context_->pp_resource(), shader_2d_.program);
+  if (shader_rectangle_arb_.program) {
+    gles2_if_->DeleteProgram(
+        context_->pp_resource(), shader_rectangle_arb_.program);
+  }
+
+  for (Decoders::iterator it = video_decoders_.begin();
+       it != video_decoders_.end(); ++it) {
+    delete it->second;
+  }
+  video_decoders_.clear();
+  delete context_;
+}
+
+void VideoDecodeDemoInstance::DidChangeView(
+    const pp::Rect& position, const pp::Rect& clip_ignored) {
+  if (position.width() == 0 || position.height() == 0)
+    return;
+  if (plugin_size_.width()) {
+    assert(position.size() == plugin_size_);
+    return;
+  }
+  plugin_size_ = position.size();
+
+  // Initialize graphics.
+  InitGL();
+  InitializeDecoders();
+}
+
+void VideoDecodeDemoInstance::InitializeDecoders() {
+  assert(video_decoders_.empty());
+  for (int i = 0; i < kNumDecoders; ++i) {
+    DecoderClient* client = new DecoderClient(
+        this, new pp::VideoDecoder_Dev(
+            this, *context_, PP_VIDEODECODER_H264PROFILE_MAIN));
+    assert(!client->decoder()->is_null());
+    assert(video_decoders_.insert(std::make_pair(
+        client->decoder()->pp_resource(), client)).second);
+    client->DecodeNextNALUs();
+  }
+}
+
+void VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone(
+    int32_t result, int bitstream_buffer_id) {
+  assert(bitstream_ids_at_decoder_.erase(bitstream_buffer_id) == 1);
+  BitstreamBufferMap::iterator it =
+      bitstream_buffers_by_id_.find(bitstream_buffer_id);
+  assert(it != bitstream_buffers_by_id_.end());
+  delete it->second;
+  bitstream_buffers_by_id_.erase(it);
+  DecodeNextNALUs();
+}
+
+void VideoDecodeDemoInstance::DecoderClient::DecoderFlushDone(int32_t result) {
+  assert(result == PP_OK);
+  // Check that each bitstream buffer ID we handed to the decoder got handed
+  // back to us.
+  assert(bitstream_ids_at_decoder_.empty());
+  delete decoder_;
+  decoder_ = NULL;
+}
+
+static bool LookingAtNAL(const unsigned char* encoded, size_t pos) {
+  return pos + 3 < kDataLen &&
+      encoded[pos] == 0 && encoded[pos + 1] == 0 &&
+      encoded[pos + 2] == 0 && encoded[pos + 3] == 1;
+}
+
+void VideoDecodeDemoInstance::DecoderClient::GetNextNALUBoundary(
+    size_t start_pos, size_t* end_pos) {
+  assert(LookingAtNAL(kData, start_pos));
+  *end_pos = start_pos;
+  *end_pos += 4;
+  while (*end_pos + 3 < kDataLen &&
+         !LookingAtNAL(kData, *end_pos)) {
+    ++*end_pos;
+  }
+  if (*end_pos + 3 >= kDataLen) {
+    *end_pos = kDataLen;
+    return;
+  }
+}
+
+void VideoDecodeDemoInstance::DecoderClient::DecodeNextNALUs() {
+  while (encoded_data_next_pos_to_decode_ <= kDataLen &&
+         bitstream_ids_at_decoder_.size() < kNumConcurrentDecodes) {
+    DecodeNextNALU();
+  }
+}
+
+void VideoDecodeDemoInstance::DecoderClient::DecodeNextNALU() {
+  if (encoded_data_next_pos_to_decode_ == kDataLen) {
+    ++encoded_data_next_pos_to_decode_;
+    pp::CompletionCallback cb = callback_factory_.NewCallback(
+        &VideoDecodeDemoInstance::DecoderClient::DecoderFlushDone);
+    decoder_->Flush(cb);
+    return;
+  }
+  size_t start_pos = encoded_data_next_pos_to_decode_;
+  size_t end_pos;
+  GetNextNALUBoundary(start_pos, &end_pos);
+  pp::Buffer_Dev* buffer = new pp::Buffer_Dev(gles2_, end_pos - start_pos);
+  PP_VideoBitstreamBuffer_Dev bitstream_buffer;
+  int id = ++next_bitstream_buffer_id_;
+  bitstream_buffer.id = id;
+  bitstream_buffer.size = end_pos - start_pos;
+  bitstream_buffer.data = buffer->pp_resource();
+  memcpy(buffer->data(), kData + start_pos, end_pos - start_pos);
+  assert(bitstream_buffers_by_id_.insert(std::make_pair(id, buffer)).second);
+
+  pp::CompletionCallback cb =
+      callback_factory_.NewCallback(
+          &VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone, id);
+  assert(bitstream_ids_at_decoder_.insert(id).second);
+  encoded_data_next_pos_to_decode_ = end_pos;
+  decoder_->Decode(bitstream_buffer, cb);
+}
+
+void VideoDecodeDemoInstance::ProvidePictureBuffers(PP_Resource decoder,
+                                                    uint32_t req_num_of_bufs,
+                                                    const PP_Size& dimensions,
+                                                    uint32_t texture_target) {
+  DecoderClient* client = video_decoders_[decoder];
+  assert(client);
+  client->ProvidePictureBuffers(req_num_of_bufs, dimensions, texture_target);
+}
+
+void VideoDecodeDemoInstance::DecoderClient::ProvidePictureBuffers(
+    uint32_t req_num_of_bufs,
+    PP_Size dimensions,
+    uint32_t texture_target) {
+  std::vector<PP_PictureBuffer_Dev> buffers;
+  for (uint32_t i = 0; i < req_num_of_bufs; ++i) {
+    PictureBufferInfo info;
+    info.buffer.size = dimensions;
+    info.texture_target = texture_target;
+    info.buffer.texture_id = gles2_->CreateTexture(
+        dimensions.width, dimensions.height, info.texture_target);
+    int id = ++next_picture_buffer_id_;
+    info.buffer.id = id;
+    buffers.push_back(info.buffer);
+    assert(picture_buffers_by_id_.insert(std::make_pair(id, info)).second);
+  }
+  decoder_->AssignPictureBuffers(buffers);
+}
+
+const PictureBufferInfo&
+VideoDecodeDemoInstance::DecoderClient::GetPictureBufferInfoById(
+    int id) {
+  PictureBufferMap::iterator it = picture_buffers_by_id_.find(id);
+  assert(it != picture_buffers_by_id_.end());
+  return it->second;
+}
+
+void VideoDecodeDemoInstance::DismissPictureBuffer(PP_Resource decoder,
+                                             int32_t picture_buffer_id) {
+  DecoderClient* client = video_decoders_[decoder];
+  assert(client);
+  client->DismissPictureBuffer(picture_buffer_id);
+}
+
+void VideoDecodeDemoInstance::DecoderClient::DismissPictureBuffer(
+    int32_t picture_buffer_id) {
+  gles2_->DeleteTexture(GetPictureBufferInfoById(
+      picture_buffer_id).buffer.texture_id);
+  picture_buffers_by_id_.erase(picture_buffer_id);
+}
+
+void VideoDecodeDemoInstance::PictureReady(PP_Resource decoder,
+                                     const PP_Picture_Dev& picture) {
+  if (first_frame_delivered_ticks_ == -1)
+    assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1);
+  if (is_painting_) {
+    pictures_pending_paint_.push_back(std::make_pair(decoder, picture));
+    return;
+  }
+  DecoderClient* client = video_decoders_[decoder];
+  assert(client);
+  const PictureBufferInfo& info =
+      client->GetPictureBufferInfoById(picture.picture_buffer_id);
+  assert(!is_painting_);
+  is_painting_ = true;
+  int x = 0;
+  int y = 0;
+  if (client != video_decoders_.begin()->second) {
+    x = plugin_size_.width() / kNumDecoders;
+    y = plugin_size_.height() / kNumDecoders;
+  }
+
+  if (info.texture_target == GL_TEXTURE_2D) {
+    Create2DProgramOnce();
+    gles2_if_->UseProgram(context_->pp_resource(), shader_2d_.program);
+    gles2_if_->Uniform2f(
+        context_->pp_resource(), shader_2d_.texcoord_scale_location, 1.0, 1.0);
+  } else {
+    assert(info.texture_target == GL_TEXTURE_RECTANGLE_ARB);
+    CreateRectangleARBProgramOnce();
+    gles2_if_->UseProgram(
+        context_->pp_resource(), shader_rectangle_arb_.program);
+    gles2_if_->Uniform2f(context_->pp_resource(),
+                         shader_rectangle_arb_.texcoord_scale_location,
+                         info.buffer.size.width,
+                         info.buffer.size.height);
+  }
+
+  gles2_if_->Viewport(context_->pp_resource(), x, y,
+                      plugin_size_.width() / kNumDecoders,
+                      plugin_size_.height() / kNumDecoders);
+  gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
+  gles2_if_->BindTexture(
+      context_->pp_resource(), info.texture_target, info.buffer.texture_id);
+  gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4);
+
+  gles2_if_->UseProgram(context_->pp_resource(), 0);
+
+  pp::CompletionCallback cb =
+      callback_factory_.NewCallback(
+          &VideoDecodeDemoInstance::PaintFinished, decoder, info.buffer.id);
+  last_swap_request_ticks_ = core_if_->GetTimeTicks();
+  assert(context_->SwapBuffers(cb) == PP_OK_COMPLETIONPENDING);
+}
+
+void VideoDecodeDemoInstance::NotifyError(PP_Resource decoder,
+                                          PP_VideoDecodeError_Dev error) {
+  LogError(this).s() << "Received error: " << error;
+  assert(false && "Unexpected error; see stderr for details");
+}
+
+// This object is the global object representing this plugin library as long
+// as it is loaded.
+class VideoDecodeDemoModule : public pp::Module {
+ public:
+  VideoDecodeDemoModule() : pp::Module() {}
+  virtual ~VideoDecodeDemoModule() {}
+
+  virtual pp::Instance* CreateInstance(PP_Instance instance) {
+    return new VideoDecodeDemoInstance(instance, this);
+  }
+};
+
+void VideoDecodeDemoInstance::InitGL() {
+  assert(plugin_size_.width() && plugin_size_.height());
+  is_painting_ = false;
+
+  assert(!context_);
+  int32_t context_attributes[] = {
+    PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
+    PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
+    PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8,
+    PP_GRAPHICS3DATTRIB_RED_SIZE, 8,
+    PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0,
+    PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0,
+    PP_GRAPHICS3DATTRIB_SAMPLES, 0,
+    PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0,
+    PP_GRAPHICS3DATTRIB_WIDTH, plugin_size_.width(),
+    PP_GRAPHICS3DATTRIB_HEIGHT, plugin_size_.height(),
+    PP_GRAPHICS3DATTRIB_NONE,
+  };
+  context_ = new pp::Graphics3D(this, context_attributes);
+  assert(!context_->is_null());
+  assert(BindGraphics(*context_));
+
+  // Clear color bit.
+  gles2_if_->ClearColor(context_->pp_resource(), 1, 0, 0, 1);
+  gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
+
+  assertNoGLError();
+
+  CreateGLObjects();
+}
+
+void VideoDecodeDemoInstance::PaintFinished(int32_t result, PP_Resource decoder,
+                                      int picture_buffer_id) {
+  assert(result == PP_OK);
+  swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_;
+  is_painting_ = false;
+  ++num_frames_rendered_;
+  if (num_frames_rendered_ % 50 == 0) {
+    double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_;
+    double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000;
+    double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_;
+    LogError(this).s() << "Rendered frames: " << num_frames_rendered_
+                       << ", fps: " << fps << ", with average ms/swap of: "
+                       << ms_per_swap;
+  }
+  DecoderClient* client = video_decoders_[decoder];
+  if (client && client->decoder())
+    client->decoder()->ReusePictureBuffer(picture_buffer_id);
+  if (!pictures_pending_paint_.empty()) {
+    std::pair<PP_Resource, PP_Picture_Dev> decoder_picture =
+        pictures_pending_paint_.front();
+    pictures_pending_paint_.pop_front();
+    PictureReady(decoder_picture.first, decoder_picture.second);
+  }
+}
+
+GLuint VideoDecodeDemoInstance::CreateTexture(int32_t width,
+                                              int32_t height,
+                                              GLenum texture_target) {
+  GLuint texture_id;
+  gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id);
+  assertNoGLError();
+  // Assign parameters.
+  gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
+  gles2_if_->BindTexture(context_->pp_resource(), texture_target, texture_id);
+  gles2_if_->TexParameteri(
+      context_->pp_resource(), texture_target, GL_TEXTURE_MIN_FILTER,
+      GL_NEAREST);
+  gles2_if_->TexParameteri(
+      context_->pp_resource(), texture_target, GL_TEXTURE_MAG_FILTER,
+      GL_NEAREST);
+  gles2_if_->TexParameterf(
+      context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_S,
+      GL_CLAMP_TO_EDGE);
+  gles2_if_->TexParameterf(
+      context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_T,
+      GL_CLAMP_TO_EDGE);
+
+  if (texture_target == GL_TEXTURE_2D) {
+    gles2_if_->TexImage2D(
+        context_->pp_resource(), texture_target, 0, GL_RGBA, width, height, 0,
+        GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+  }
+  assertNoGLError();
+  return texture_id;
+}
+
+void VideoDecodeDemoInstance::DeleteTexture(GLuint id) {
+  gles2_if_->DeleteTextures(context_->pp_resource(), 1, &id);
+}
+
+void VideoDecodeDemoInstance::CreateGLObjects() {
+  // Assign vertex positions and texture coordinates to buffers for use in
+  // shader program.
+  static const float kVertices[] = {
+    -1, 1, -1, -1, 1, 1, 1, -1,  // Position coordinates.
+    0, 1, 0, 0, 1, 1, 1, 0,      // Texture coordinates.
+  };
+
+  GLuint buffer;
+  gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer);
+  gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer);
+
+  gles2_if_->BufferData(context_->pp_resource(), GL_ARRAY_BUFFER,
+                        sizeof(kVertices), kVertices, GL_STATIC_DRAW);
+  assertNoGLError();
+}
+
+static const char kVertexShader[] =
+    "varying vec2 v_texCoord;            \n"
+    "attribute vec4 a_position;          \n"
+    "attribute vec2 a_texCoord;          \n"
+    "uniform vec2 v_scale;               \n"
+    "void main()                         \n"
+    "{                                   \n"
+    "    v_texCoord = v_scale * a_texCoord; \n"
+    "    gl_Position = a_position;       \n"
+    "}";
+
+void VideoDecodeDemoInstance::Create2DProgramOnce() {
+  if (shader_2d_.program)
+    return;
+  static const char kFragmentShader2D[] =
+      "precision mediump float;            \n"
+      "varying vec2 v_texCoord;            \n"
+      "uniform sampler2D s_texture;        \n"
+      "void main()                         \n"
+      "{"
+      "    gl_FragColor = texture2D(s_texture, v_texCoord); \n"
+      "}";
+  shader_2d_ = CreateProgram(kVertexShader, kFragmentShader2D);
+  assertNoGLError();
+}
+
+void VideoDecodeDemoInstance::CreateRectangleARBProgramOnce() {
+  if (shader_rectangle_arb_.program)
+    return;
+  static const char kFragmentShaderRectangle[] =
+      "#extension GL_ARB_texture_rectangle : require\n"
+      "precision mediump float;            \n"
+      "varying vec2 v_texCoord;            \n"
+      "uniform sampler2DRect s_texture;    \n"
+      "void main()                         \n"
+      "{"
+      "    gl_FragColor = texture2DRect(s_texture, v_texCoord).rgba; \n"
+      "}";
+  shader_rectangle_arb_ =
+      CreateProgram(kVertexShader, kFragmentShaderRectangle);
+}
+
+Shader VideoDecodeDemoInstance::CreateProgram(const char* vertex_shader,
+                                              const char* fragment_shader) {
+  Shader shader;
+
+  // Create shader program.
+  shader.program = gles2_if_->CreateProgram(context_->pp_resource());
+  CreateShader(shader.program, GL_VERTEX_SHADER, vertex_shader,
+               strlen(vertex_shader));
+  CreateShader(shader.program, GL_FRAGMENT_SHADER, fragment_shader,
+               strlen(fragment_shader));
+  gles2_if_->LinkProgram(context_->pp_resource(), shader.program);
+  gles2_if_->UseProgram(context_->pp_resource(), shader.program);
+  gles2_if_->Uniform1i(
+      context_->pp_resource(),
+      gles2_if_->GetUniformLocation(
+          context_->pp_resource(), shader.program, "s_texture"), 0);
+  assertNoGLError();
+
+  shader.texcoord_scale_location = gles2_if_->GetUniformLocation(
+      context_->pp_resource(), shader.program, "v_scale");
+
+  GLint pos_location = gles2_if_->GetAttribLocation(
+      context_->pp_resource(), shader.program, "a_position");
+  GLint tc_location = gles2_if_->GetAttribLocation(
+      context_->pp_resource(), shader.program, "a_texCoord");
+  assertNoGLError();
+
+  gles2_if_->EnableVertexAttribArray(context_->pp_resource(), pos_location);
+  gles2_if_->VertexAttribPointer(context_->pp_resource(), pos_location, 2,
+                                 GL_FLOAT, GL_FALSE, 0, 0);
+  gles2_if_->EnableVertexAttribArray(context_->pp_resource(), tc_location);
+  gles2_if_->VertexAttribPointer(
+      context_->pp_resource(), tc_location, 2, GL_FLOAT, GL_FALSE, 0,
+      static_cast<float*>(0) + 8);  // Skip position coordinates.
+
+  gles2_if_->UseProgram(context_->pp_resource(), 0);
+  assertNoGLError();
+  return shader;
+}
+
+void VideoDecodeDemoInstance::CreateShader(
+    GLuint program, GLenum type, const char* source, int size) {
+  GLuint shader = gles2_if_->CreateShader(context_->pp_resource(), type);
+  gles2_if_->ShaderSource(context_->pp_resource(), shader, 1, &source, &size);
+  gles2_if_->CompileShader(context_->pp_resource(), shader);
+  gles2_if_->AttachShader(context_->pp_resource(), program, shader);
+  gles2_if_->DeleteShader(context_->pp_resource(), shader);
+}
+}  // anonymous namespace
+
+namespace pp {
+// Factory function for your specialization of the Module object.
+Module* CreateModule() {
+  return new VideoDecodeDemoModule();
+}
+}  // namespace pp
diff --git a/ppapi/examples/video_decode/video_decode_dev.html b/ppapi/examples/video_decode/video_decode_dev.html
new file mode 100644
index 0000000..8e098ca
--- /dev/null
+++ b/ppapi/examples/video_decode/video_decode_dev.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+  <!--
+  Copyright (c) 2012 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.
+  -->
+<head>
+  <title>Video Decode (Dev) Example</title>
+</head>
+
+<body>
+
+<embed id="plugin" type="application/x-ppapi-example-video-decode-dev"
+       width="640" height="480"/>
+
+</body>
+</html>
diff --git a/ppapi/host/resource_host.cc b/ppapi/host/resource_host.cc
index 4e12260..b453398 100644
--- a/ppapi/host/resource_host.cc
+++ b/ppapi/host/resource_host.cc
@@ -56,6 +56,10 @@
   return false;
 }
 
+bool ResourceHost::IsMediaStreamVideoTrackHost() {
+  return false;
+}
+
 bool ResourceHost::IsGraphics2DHost() {
   return false;
 }
diff --git a/ppapi/host/resource_host.h b/ppapi/host/resource_host.h
index 37ccbed..a9518ee 100644
--- a/ppapi/host/resource_host.h
+++ b/ppapi/host/resource_host.h
@@ -59,6 +59,7 @@
   virtual bool IsFileRefHost();
   virtual bool IsFileSystemHost();
   virtual bool IsGraphics2DHost();
+  virtual bool IsMediaStreamVideoTrackHost();
 
  protected:
   // Adds a ResourceMessageFilter to handle resource messages. Incoming
diff --git a/ppapi/nacl_irt/DEPS b/ppapi/nacl_irt/DEPS
index b759edf..8e4bc77 100644
--- a/ppapi/nacl_irt/DEPS
+++ b/ppapi/nacl_irt/DEPS
@@ -10,6 +10,7 @@
   "+native_client/src/shared/srpc/nacl_srpc.h",
   "+native_client/src/untrusted/irt/irt.h",
   "+native_client/src/untrusted/irt/irt_private.h",
-  # The IRT also needs to know the sysconf enums.
+  # The IRT also needs to know the errno and sysconf enums.
+  "+native_client/src/trusted/service_runtime/include/sys/errno.h",
   "+native_client/src/trusted/service_runtime/include/sys/unistd.h",
 ]
diff --git a/ppapi/nacl_irt/irt_manifest.h b/ppapi/nacl_irt/irt_manifest.h
new file mode 100644
index 0000000..b1e0923
--- /dev/null
+++ b/ppapi/nacl_irt/irt_manifest.h
@@ -0,0 +1,21 @@
+// 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.
+
+#ifndef PPAPI_NACL_IRT_IRT_MANIFEST_H_
+#define PPAPI_NACL_IRT_IRT_MANIFEST_H_
+
+#include "ppapi/proxy/ppapi_proxy_export.h"
+
+namespace ppapi {
+
+// The implementation of irt_open_resource() based on ManifestService.
+// This communicates with the renderer process via Chrome IPC to obtain the
+// read-only file descriptor of the resource specified in the manifest file
+// with the key |file| in files section. Returns 0 on success, or error number
+// on failure. See also irt_open_resource()'s comment.
+PPAPI_PROXY_EXPORT int IrtOpenResource(const char* file, int* fd);
+
+}  // namespace ppapi
+
+#endif  // PPAPI_NACL_IRT_IRT_MANIFEST_H_
diff --git a/ppapi/nacl_irt/manifest_service.cc b/ppapi/nacl_irt/manifest_service.cc
index ed7c4eb..0afa217 100644
--- a/ppapi/nacl_irt/manifest_service.cc
+++ b/ppapi/nacl_irt/manifest_service.cc
@@ -8,10 +8,15 @@
 #include "ipc/ipc_channel_handle.h"
 #include "ipc/ipc_channel_proxy.h"
 #include "ipc/ipc_sync_message_filter.h"
+#include "native_client/src/trusted/service_runtime/include/sys/errno.h"
+#include "ppapi/nacl_irt/irt_manifest.h"
+#include "ppapi/nacl_irt/plugin_startup.h"
 #include "ppapi/proxy/ppapi_messages.h"
 
 namespace ppapi {
 
+const char kFilePrefix[] = "files/";
+
 ManifestService::ManifestService(
     const IPC::ChannelHandle& handle,
     scoped_refptr<base::MessageLoopProxy> io_message_loop,
@@ -19,7 +24,7 @@
   filter_ = new IPC::SyncMessageFilter(shutdown_event);
   channel_.reset(new IPC::ChannelProxy(handle,
                                        IPC::Channel::MODE_SERVER,
-                                       NULL, // Listener
+                                       NULL,  // Listener
                                        io_message_loop));
   channel_->AddFilter(filter_.get());
 }
@@ -31,4 +36,34 @@
   filter_->Send(new PpapiHostMsg_StartupInitializationComplete);
 }
 
+bool ManifestService::OpenResource(const char* file, int* fd) {
+  // OpenResource will return INVALID SerializedHandle, if it is not supported.
+  // Specifically, PNaCl doesn't support open resource.
+  ppapi::proxy::SerializedHandle ipc_fd;
+  if (!filter_->Send(new PpapiHostMsg_OpenResource(
+          std::string(kFilePrefix) + file, &ipc_fd)) ||
+      !ipc_fd.is_file()) {
+    LOG(ERROR) << "ManifestService::OpenResource failed:" << file;
+    *fd = -1;
+    return false;
+  }
+
+  *fd = ipc_fd.descriptor().fd;
+  return true;
+}
+
+int IrtOpenResource(const char* file, int* fd) {
+  // Remove leading '/' character.
+  if (file[0] == '/')
+    ++file;
+
+  ManifestService* manifest_service = GetManifestService();
+  if (manifest_service == NULL ||
+      !manifest_service->OpenResource(file, fd)) {
+    return NACL_ABI_EIO;
+  }
+
+  return (*fd == -1) ? NACL_ABI_ENOENT : 0;
+}
+
 }  // namespace ppapi
diff --git a/ppapi/nacl_irt/manifest_service.h b/ppapi/nacl_irt/manifest_service.h
index ec5e38c..ce414cc 100644
--- a/ppapi/nacl_irt/manifest_service.h
+++ b/ppapi/nacl_irt/manifest_service.h
@@ -30,6 +30,7 @@
   ~ManifestService();
 
   void StartupInitializationComplete();
+  bool OpenResource(const char* file, int* fd);
 
  private:
   scoped_ptr<IPC::ChannelProxy> channel_;
diff --git a/ppapi/nacl_irt/public/irt_nonsfi.h b/ppapi/nacl_irt/public/irt_nonsfi.h
new file mode 100644
index 0000000..acc0eac
--- /dev/null
+++ b/ppapi/nacl_irt/public/irt_nonsfi.h
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+#ifndef PPAPI_NACL_IRT_PUBLIC_IRT_NONSFI_H_
+#define PPAPI_NACL_IRT_PUBLIC_IRT_NONSFI_H_
+
+#include <stddef.h>
+
+/*
+ * This interface is only available on ARM, only for Non-SFI.
+ */
+#define NACL_IRT_ICACHE_v0_1 "nacl-irt-icache-0.1"
+struct nacl_irt_icache {
+  /*
+   * clear_cache() makes instruction cache and data cache for the address
+   * range from |addr| to |(intptr_t)addr + size| (exclusive) coherent.
+   */
+  int (*clear_cache)(void* addr, size_t size);
+};
+
+#endif  // PPAPI_NACL_IRT_PUBLIC_IRT_NONSFI_H_
diff --git a/ppapi/native_client/native_client.gyp b/ppapi/native_client/native_client.gyp
index 5621cbc..97dc9c7 100644
--- a/ppapi/native_client/native_client.gyp
+++ b/ppapi/native_client/native_client.gyp
@@ -251,7 +251,7 @@
             ],
           },
           'dependencies': [
-            'src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:pnacl_irt_shim_for_irt',
+            'src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:shim_for_irt',
             '../ppapi_proxy_nacl.gyp:ppapi_proxy_nacl',
             '../ppapi_ipc_nacl.gyp:ppapi_ipc_nacl',
             '../ppapi_shared_nacl.gyp:ppapi_shared_nacl',
diff --git a/ppapi/native_client/src/trusted/plugin/file_utils.cc b/ppapi/native_client/src/trusted/plugin/file_utils.cc
deleted file mode 100644
index d834327..0000000
--- a/ppapi/native_client/src/trusted/plugin/file_utils.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2013 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.
-
-// Some common file utilities for plugin code.
-
-#include "ppapi/native_client/src/trusted/plugin/file_utils.h"
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "native_client/src/include/nacl_scoped_ptr.h"
-#include "native_client/src/include/portability_io.h"
-#include "native_client/src/include/portability_string.h"
-
-
-namespace plugin {
-namespace file_utils {
-
-StatusCode SlurpFile(int32_t fd,
-                     nacl::string& out_buf,
-                     size_t max_size_to_read) {
-  struct stat stat_buf;
-  if (fstat(fd, &stat_buf) != 0) {
-    CLOSE(fd);
-    return PLUGIN_FILE_ERROR_STAT;
-  }
-
-  // Figure out how large a buffer we need to slurp the whole file (with a
-  // '\0' at the end).
-  size_t bytes_to_read = static_cast<size_t>(stat_buf.st_size);
-  if (bytes_to_read > max_size_to_read - 1) {
-    CLOSE(fd);
-    return PLUGIN_FILE_ERROR_FILE_TOO_LARGE;
-  }
-
-  FILE* input_file = fdopen(fd, "rb");
-  if (!input_file) {
-    CLOSE(fd);
-    return PLUGIN_FILE_ERROR_OPEN;
-  }
-  // From here on, closing input_file will automatically close fd.
-
-  nacl::scoped_array<char> buffer(new char[bytes_to_read + 1]);
-  if (buffer == NULL) {
-    fclose(input_file);
-    return PLUGIN_FILE_ERROR_MEM_ALLOC;
-  }
-
-  size_t total_bytes_read = 0;
-  while (bytes_to_read > 0) {
-    size_t bytes_this_read = fread(&buffer[total_bytes_read],
-                                   sizeof(char),
-                                   bytes_to_read,
-                                   input_file);
-    if (bytes_this_read < bytes_to_read && (feof(input_file) ||
-                                            ferror(input_file))) {
-      fclose(input_file);
-      return PLUGIN_FILE_ERROR_READ;
-    }
-    total_bytes_read += bytes_this_read;
-    bytes_to_read -= bytes_this_read;
-  }
-
-  fclose(input_file);
-  buffer[total_bytes_read] = '\0';
-  out_buf = buffer.get();
-  return PLUGIN_FILE_SUCCESS;
-}
-
-}  // namespace file_utils
-}  // namespace plugin
-
diff --git a/ppapi/native_client/src/trusted/plugin/file_utils.h b/ppapi/native_client/src/trusted/plugin/file_utils.h
deleted file mode 100644
index 223bf66..0000000
--- a/ppapi/native_client/src/trusted/plugin/file_utils.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2013 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.
-
-// Some common file utilities for plugin code.
-
-#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_UTILS_H_
-#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_UTILS_H_
-
-#include "native_client/src/include/nacl_string.h"
-#include "native_client/src/include/portability_io.h"
-#include "ppapi/c/pp_stdint.h"
-
-namespace plugin {
-namespace file_utils {
-
-enum StatusCode {
-  PLUGIN_FILE_SUCCESS = 0,
-  PLUGIN_FILE_ERROR_MEM_ALLOC = 1,
-  PLUGIN_FILE_ERROR_OPEN = 2,
-  PLUGIN_FILE_ERROR_FILE_TOO_LARGE = 3,
-  PLUGIN_FILE_ERROR_STAT = 4,
-  PLUGIN_FILE_ERROR_READ = 5
-};
-
-// Slurp the whole contents of the given file (|fd| - open file descriptor) into
-// |out_buf|. |max_size_to_read| is the maximal allowed size of the file.
-// If the file turns out to be larger, an error is returned. In any case,
-// |fd| is closed.
-StatusCode SlurpFile(int32_t fd,
-                     nacl::string& out_buf,
-                     size_t max_size_to_read = (1 << 20));
-
-}  // namespace file_utils
-}  // namespace plugin
-
-#endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_UTILS_H_
-
diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.cc b/ppapi/native_client/src/trusted/plugin/json_manifest.cc
deleted file mode 100644
index 0187497..0000000
--- a/ppapi/native_client/src/trusted/plugin/json_manifest.cc
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
- * Copyright (c) 2012 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.
- */
-
-#include <algorithm>
-
-#include "ppapi/native_client/src/trusted/plugin/json_manifest.h"
-
-#include <stdlib.h>
-
-#include "native_client/src/include/nacl_base.h"
-#include "native_client/src/include/nacl_macros.h"
-#include "native_client/src/include/nacl_string.h"
-#include "native_client/src/include/portability.h"
-#include "native_client/src/shared/platform/nacl_check.h"
-#include "ppapi/c/private/ppb_nacl_private.h"
-#include "ppapi/cpp/dev/url_util_dev.h"
-#include "ppapi/cpp/var.h"
-#include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
-#include "ppapi/native_client/src/trusted/plugin/utility.h"
-#include "third_party/jsoncpp/source/include/json/reader.h"
-
-namespace plugin {
-
-namespace {
-// Top-level section name keys
-const char* const kProgramKey =     "program";
-const char* const kInterpreterKey = "interpreter";
-const char* const kFilesKey =       "files";
-
-// ISA Dictionary keys
-const char* const kX8632Key =       "x86-32";
-const char* const kX8632NonSFIKey = "x86-32-nonsfi";
-const char* const kX8664Key =       "x86-64";
-const char* const kX8664NonSFIKey = "x86-64-nonsfi";
-const char* const kArmKey =         "arm";
-const char* const kArmNonSFIKey =   "arm-nonsfi";
-const char* const kPortableKey =    "portable";
-
-// Url Resolution keys
-const char* const kPnaclDebugKey =     "pnacl-debug";
-const char* const kPnaclTranslateKey = "pnacl-translate";
-const char* const kUrlKey =            "url";
-
-// PNaCl keys
-const char* const kOptLevelKey = "optlevel";
-
-// Sample NaCl manifest file:
-// {
-//   "program": {
-//     "x86-32": {"url": "myprogram_x86-32.nexe"},
-//     "x86-64": {"url": "myprogram_x86-64.nexe"},
-//     "arm": {"url": "myprogram_arm.nexe"}
-//   },
-//   "interpreter": {
-//     "x86-32": {"url": "interpreter_x86-32.nexe"},
-//     "x86-64": {"url": "interpreter_x86-64.nexe"},
-//     "arm": {"url": "interpreter_arm.nexe"}
-//   },
-//   "files": {
-//     "foo.txt": {
-//       "portable": {"url": "foo.txt"}
-//     },
-//     "bar.txt": {
-//       "x86-32": {"url": "x86-32/bar.txt"},
-//       "portable": {"url": "bar.txt"}
-//     },
-//     "libfoo.so": {
-//       "x86-64" : { "url": "..." }
-//     }
-//   }
-// }
-
-// Sample PNaCl manifest file:
-// {
-//   "program": {
-//     "portable": {
-//       "pnacl-translate": {
-//         "url": "myprogram.pexe"
-//       },
-//       "pnacl-debug": {
-//         "url": "myprogram.debug.pexe",
-//         "opt_level": 0
-//       }
-//     }
-//   },
-//   "files": {
-//     "foo.txt": {
-//       "portable": {"url": "foo.txt"}
-//     },
-//     "bar.txt": {
-//       "portable": {"url": "bar.txt"}
-//     }
-//   }
-// }
-
-// Returns the key for the architecture in non-SFI mode.
-nacl::string GetNonSFIKey(const nacl::string& sandbox_isa) {
-  return sandbox_isa + "-nonsfi";
-}
-
-// Looks up |property_name| in the vector |valid_names| with length
-// |valid_name_count|.  Returns true if |property_name| is found.
-bool FindMatchingProperty(const nacl::string& property_name,
-                          const char** valid_names,
-                          size_t valid_name_count) {
-  for (size_t i = 0; i < valid_name_count; ++i) {
-    if (property_name == valid_names[i]) {
-      return true;
-    }
-  }
-  return false;
-}
-
-// Return true if this is a valid dictionary.  Having only keys present in
-// |valid_keys| and having at least the keys in |required_keys|.
-// Error messages will be placed in |error_string|, given that the dictionary
-// was the property value of |container_key|.
-// E.g., "container_key" : dictionary
-bool IsValidDictionary(const Json::Value& dictionary,
-                       const nacl::string& container_key,
-                       const nacl::string& parent_key,
-                       const char** valid_keys,
-                       size_t valid_key_count,
-                       const char** required_keys,
-                       size_t required_key_count,
-                       nacl::string* error_string) {
-  if (!dictionary.isObject()) {
-    nacl::stringstream error_stream;
-    error_stream << parent_key << " property '" << container_key
-                 << "' is non-dictionary value '"
-                 << dictionary.toStyledString() << "'.";
-    *error_string = error_stream.str();
-    return false;
-  }
-  // Check for unknown dictionary members.
-  Json::Value::Members members = dictionary.getMemberNames();
-  for (size_t i = 0; i < members.size(); ++i) {
-    nacl::string property_name = members[i];
-    if (!FindMatchingProperty(property_name,
-                              valid_keys,
-                              valid_key_count)) {
-      // For forward compatibility, we do not prohibit other keys being in
-      // the dictionary.
-      PLUGIN_PRINTF(("WARNING: '%s' property '%s' has unknown key '%s'.\n",
-                     parent_key.c_str(),
-                     container_key.c_str(), property_name.c_str()));
-    }
-  }
-  // Check for required members.
-  for (size_t i = 0; i < required_key_count; ++i) {
-    if (!dictionary.isMember(required_keys[i])) {
-      nacl::stringstream error_stream;
-      error_stream << parent_key << " property '" << container_key
-                   << "' does not have required key: '"
-                   << required_keys[i] << "'.";
-      *error_string = error_stream.str();
-      return false;
-    }
-  }
-  return true;
-}
-
-// Validate a "url" dictionary assuming it was resolved from container_key.
-// E.g., "container_key" : { "url": "foo.txt" }
-bool IsValidUrlSpec(const Json::Value& url_spec,
-                    const nacl::string& container_key,
-                    const nacl::string& parent_key,
-                    const nacl::string& sandbox_isa,
-                    nacl::string* error_string) {
-  static const char* kManifestUrlSpecRequired[] = {
-    kUrlKey
-  };
-  const char** urlSpecPlusOptional;
-  size_t urlSpecPlusOptionalLength;
-  if (sandbox_isa == kPortableKey) {
-    static const char* kPnaclUrlSpecPlusOptional[] = {
-      kUrlKey,
-      kOptLevelKey,
-    };
-    urlSpecPlusOptional = kPnaclUrlSpecPlusOptional;
-    urlSpecPlusOptionalLength = NACL_ARRAY_SIZE(kPnaclUrlSpecPlusOptional);
-  } else {
-    // URL specifications must not contain "pnacl-translate" keys.
-    // This prohibits NaCl clients from invoking PNaCl.
-    if (url_spec.isMember(kPnaclTranslateKey)) {
-      nacl::stringstream error_stream;
-      error_stream << "PNaCl-like NMF with application/x-nacl mimetype instead "
-                   << "of x-pnacl mimetype (has " << kPnaclTranslateKey << ").";
-      *error_string = error_stream.str();
-      return false;
-    }
-    urlSpecPlusOptional = kManifestUrlSpecRequired;
-    urlSpecPlusOptionalLength = NACL_ARRAY_SIZE(kManifestUrlSpecRequired);
-  }
-  if (!IsValidDictionary(url_spec, container_key, parent_key,
-                         urlSpecPlusOptional,
-                         urlSpecPlusOptionalLength,
-                         kManifestUrlSpecRequired,
-                         NACL_ARRAY_SIZE(kManifestUrlSpecRequired),
-                         error_string)) {
-    return false;
-  }
-  // Verify the correct types of the fields if they exist.
-  Json::Value url = url_spec[kUrlKey];
-  if (!url.isString()) {
-    nacl::stringstream error_stream;
-    error_stream << parent_key << " property '" << container_key <<
-        "' has non-string value '" << url.toStyledString() <<
-        "' for key '" << kUrlKey << "'.";
-    *error_string = error_stream.str();
-    return false;
-  }
-  Json::Value opt_level = url_spec[kOptLevelKey];
-  if (!opt_level.empty() && !opt_level.isNumeric()) {
-    nacl::stringstream error_stream;
-    error_stream << parent_key << " property '" << container_key <<
-        "' has non-numeric value '" << opt_level.toStyledString() <<
-        "' for key '" << kOptLevelKey << "'.";
-    *error_string = error_stream.str();
-    return false;
-  }
-  return true;
-}
-
-// Validate a "pnacl-translate" or "pnacl-debug" dictionary, assuming
-// it was resolved from container_key.
-// E.g., "container_key" : { "pnacl-translate" : URLSpec }
-bool IsValidPnaclTranslateSpec(const Json::Value& pnacl_spec,
-                               const nacl::string& container_key,
-                               const nacl::string& parent_key,
-                               const nacl::string& sandbox_isa,
-                               nacl::string* error_string) {
-  static const char* kManifestPnaclSpecValid[] = {
-    kPnaclDebugKey,
-    kPnaclTranslateKey
-  };
-  static const char* kManifestPnaclSpecRequired[] = {
-    kPnaclTranslateKey
-  };
-  if (!IsValidDictionary(pnacl_spec, container_key, parent_key,
-                         kManifestPnaclSpecValid,
-                         NACL_ARRAY_SIZE(kManifestPnaclSpecValid),
-                         kManifestPnaclSpecRequired,
-                         NACL_ARRAY_SIZE(kManifestPnaclSpecRequired),
-                         error_string)) {
-    return false;
-  }
-  Json::Value url_spec = pnacl_spec[kPnaclTranslateKey];
-  if (!IsValidUrlSpec(url_spec, kPnaclTranslateKey,
-                      container_key, sandbox_isa, error_string)) {
-    return false;
-  }
-  return true;
-}
-
-// Validates that |dictionary| is a valid ISA dictionary.  An ISA dictionary
-// is validated to have keys from within the set of recognized ISAs.  Unknown
-// ISAs are allowed, but ignored and warnings are produced. It is also validated
-// that it must have an entry to match the ISA specified in |sandbox_isa| or
-// have a fallback 'portable' entry if there is no match. Returns true if
-// |dictionary| is an ISA to URL map.  Sets |error_info| to something
-// descriptive if it fails.
-bool IsValidISADictionary(const Json::Value& dictionary,
-                          const nacl::string& parent_key,
-                          const nacl::string& sandbox_isa,
-                          bool must_find_matching_entry,
-                          bool nonsfi_enabled,
-                          ErrorInfo* error_info) {
-  if (error_info == NULL) return false;
-
-  // An ISA to URL dictionary has to be an object.
-  if (!dictionary.isObject()) {
-    error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE,
-                          nacl::string("manifest: ") + parent_key +
-                          " property is not an ISA to URL dictionary");
-    return false;
-  }
-  // Build the set of reserved ISA dictionary keys.
-  const char** isaProperties;
-  size_t isaPropertiesLength;
-  if (sandbox_isa == kPortableKey) {
-    // The known values for PNaCl ISA dictionaries in the manifest.
-    static const char* kPnaclManifestISAProperties[] = {
-      kPortableKey
-    };
-    isaProperties = kPnaclManifestISAProperties;
-    isaPropertiesLength = NACL_ARRAY_SIZE(kPnaclManifestISAProperties);
-  } else {
-    // The known values for NaCl ISA dictionaries in the manifest.
-    static const char* kNaClManifestISAProperties[] = {
-      kX8632Key,
-      kX8632NonSFIKey,
-      kX8664Key,
-      kX8664NonSFIKey,
-      kArmKey,
-      kArmNonSFIKey,
-      // "portable" is here to allow checking that, if present, it can
-      // only refer to an URL, such as for a data file, and not to
-      // "pnacl-translate", which would cause the creation of a nexe.
-      kPortableKey
-    };
-    isaProperties = kNaClManifestISAProperties;
-    isaPropertiesLength = NACL_ARRAY_SIZE(kNaClManifestISAProperties);
-  }
-  // Check that entries in the dictionary are structurally correct.
-  Json::Value::Members members = dictionary.getMemberNames();
-  for (size_t i = 0; i < members.size(); ++i) {
-    nacl::string property_name = members[i];
-    Json::Value property_value = dictionary[property_name];
-    nacl::string error_string;
-    if (FindMatchingProperty(property_name,
-                             isaProperties,
-                             isaPropertiesLength)) {
-      // For NaCl, arch entries can only be
-      //     "arch/portable" : URLSpec
-      // For PNaCl arch in "program" dictionary entries can be
-      //     "portable" : { "pnacl-translate": URLSpec }
-      //  or "portable" : { "pnacl-debug": URLSpec }
-      // For PNaCl arch elsewhere, dictionary entries can only be
-      //     "portable" : URLSpec
-      if ((sandbox_isa != kPortableKey &&
-           !IsValidUrlSpec(property_value, property_name, parent_key,
-                           sandbox_isa, &error_string)) ||
-          (sandbox_isa == kPortableKey &&
-           parent_key == kProgramKey &&
-           !IsValidPnaclTranslateSpec(property_value, property_name, parent_key,
-                                      sandbox_isa, &error_string)) ||
-          (sandbox_isa == kPortableKey &&
-           parent_key != kProgramKey &&
-           !IsValidUrlSpec(property_value, property_name, parent_key,
-                           sandbox_isa, &error_string))) {
-        error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE,
-                              nacl::string("manifest: ") + error_string);
-        return false;
-      }
-    } else {
-      // For forward compatibility, we do not prohibit other keys being in
-      // the dictionary, as they may be architectures supported in later
-      // versions.  However, the value of these entries must be an URLSpec.
-      PLUGIN_PRINTF(("IsValidISADictionary: unrecognized key '%s'.\n",
-                     property_name.c_str()));
-      if (!IsValidUrlSpec(property_value, property_name, parent_key,
-                          sandbox_isa, &error_string)) {
-        error_info->SetReport(PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE,
-                              nacl::string("manifest: ") + error_string);
-        return false;
-      }
-    }
-  }
-
-  if (sandbox_isa == kPortableKey) {
-    bool has_portable = dictionary.isMember(kPortableKey);
-
-    if (!has_portable) {
-      error_info->SetReport(
-          PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH,
-          nacl::string("manifest: no version of ") + parent_key +
-          " given for portable.");
-      return false;
-    }
-  } else if (must_find_matching_entry) {
-    // TODO(elijahtaylor) add ISA resolver here if we expand ISAs to include
-    // micro-architectures that can resolve to multiple valid sandboxes.
-    bool has_isa = dictionary.isMember(sandbox_isa);
-    bool has_nonsfi_isa =
-        nonsfi_enabled && dictionary.isMember(GetNonSFIKey(sandbox_isa));
-    bool has_portable = dictionary.isMember(kPortableKey);
-
-    if (!has_isa && !has_nonsfi_isa && !has_portable) {
-      error_info->SetReport(
-          PP_NACL_ERROR_MANIFEST_PROGRAM_MISSING_ARCH,
-          nacl::string("manifest: no version of ") + parent_key +
-          " given for current arch and no portable version found.");
-      return false;
-    }
-  }
-
-  return true;
-}
-
-void GrabUrlAndPNaClOptions(const Json::Value& url_spec,
-                            nacl::string* url,
-                            PP_PNaClOptions* pnacl_options) {
-  *url = url_spec[kUrlKey].asString();
-  pnacl_options->translate = PP_TRUE;
-  if (url_spec.isMember(kOptLevelKey)) {
-    int32_t opt_raw = url_spec[kOptLevelKey].asInt();
-    int32_t opt_level;
-    // Currently only allow 0 or 2, since that is what we test.
-    if (opt_raw <= 0)
-      opt_level = 0;
-    else
-      opt_level = 2;
-    pnacl_options->opt_level = opt_level;
-  }
-}
-
-}  // namespace
-
-bool JsonManifest::Init(const nacl::string& manifest_json,
-                        ErrorInfo* error_info) {
-  if (error_info == NULL) {
-    return false;
-  }
-  Json::Reader reader;
-  if (!reader.parse(manifest_json, dictionary_)) {
-    std::string json_error = reader.getFormatedErrorMessages();
-    error_info->SetReport(PP_NACL_ERROR_MANIFEST_PARSING,
-                          "manifest JSON parsing failed: " + json_error);
-    return false;
-  }
-  // Parse has ensured the string was valid JSON.  Check that it matches the
-  // manifest schema.
-  return MatchesSchema(error_info);
-}
-
-bool JsonManifest::MatchesSchema(ErrorInfo* error_info) {
-  pp::Var exception;
-  if (error_info == NULL) {
-    return false;
-  }
-  if (!dictionary_.isObject()) {
-    error_info->SetReport(
-        PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE,
-        "manifest: is not a json dictionary.");
-    return false;
-  }
-  Json::Value::Members members = dictionary_.getMemberNames();
-  for (size_t i = 0; i < members.size(); ++i) {
-    // The top level dictionary entries valid in the manifest file.
-    static const char* kManifestTopLevelProperties[] = { kProgramKey,
-                                                         kInterpreterKey,
-                                                         kFilesKey };
-    nacl::string property_name = members[i];
-    if (!FindMatchingProperty(property_name,
-                              kManifestTopLevelProperties,
-                              NACL_ARRAY_SIZE(kManifestTopLevelProperties))) {
-      PLUGIN_PRINTF(("JsonManifest::MatchesSchema: WARNING: unknown top-level "
-                     "section '%s' in manifest.\n", property_name.c_str()));
-    }
-  }
-
-  // A manifest file must have a program section.
-  if (!dictionary_.isMember(kProgramKey)) {
-    error_info->SetReport(
-        PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE,
-        nacl::string("manifest: missing '") + kProgramKey + "' section.");
-    return false;
-  }
-
-  // Validate the program section.
-  // There must be a matching (portable or sandbox_isa_) entry for program for
-  // NaCl.
-  if (!IsValidISADictionary(dictionary_[kProgramKey],
-                            kProgramKey,
-                            sandbox_isa_,
-                            true,
-                            nonsfi_enabled_,
-                            error_info)) {
-    return false;
-  }
-
-  // Validate the interpreter section (if given).
-  // There must be a matching (portable or sandbox_isa_) entry for interpreter
-  // for NaCl.
-  if (dictionary_.isMember(kInterpreterKey)) {
-    if (!IsValidISADictionary(dictionary_[kInterpreterKey],
-                              kInterpreterKey,
-                              sandbox_isa_,
-                              true,
-                              nonsfi_enabled_,
-                              error_info)) {
-      return false;
-    }
-  }
-
-  // Validate the file dictionary (if given).
-  // The "files" key does not require a matching (portable or sandbox_isa_)
-  // entry at schema validation time for NaCl.  This allows manifests to specify
-  // resources that are only loaded for a particular sandbox_isa.
-  if (dictionary_.isMember(kFilesKey)) {
-    const Json::Value& files = dictionary_[kFilesKey];
-    if (!files.isObject()) {
-      error_info->SetReport(
-          PP_NACL_ERROR_MANIFEST_SCHEMA_VALIDATE,
-          nacl::string("manifest: '") + kFilesKey + "' is not a dictionary.");
-    }
-    Json::Value::Members members = files.getMemberNames();
-    for (size_t i = 0; i < members.size(); ++i) {
-      nacl::string file_name = members[i];
-      if (!IsValidISADictionary(files[file_name],
-                                file_name,
-                                sandbox_isa_,
-                                false,
-                                nonsfi_enabled_,
-                                error_info)) {
-        return false;
-      }
-    }
-  }
-
-  return true;
-}
-
-bool JsonManifest::GetURLFromISADictionary(const Json::Value& dictionary,
-                                           const nacl::string& parent_key,
-                                           nacl::string* url,
-                                           PP_PNaClOptions* pnacl_options,
-                                           bool* uses_nonsfi_mode,
-                                           ErrorInfo* error_info) const {
-  DCHECK(url != NULL && pnacl_options != NULL && error_info != NULL);
-
-  // When the application actually requests a resolved URL, we must have
-  // a matching entry (sandbox_isa_ or portable) for NaCl.
-  if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa_, true,
-                            nonsfi_enabled_, error_info)) {
-    error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL,
-                          "architecture " + sandbox_isa_ +
-                          " is not found for file " + parent_key);
-    return false;
-  }
-
-  // The call to IsValidISADictionary() above guarantees that either
-  // sandbox_isa_, its nonsfi mode, or kPortableKey is present in the
-  // dictionary.
-  *uses_nonsfi_mode = false;
-  nacl::string chosen_isa;
-  if (sandbox_isa_ == kPortableKey) {
-    chosen_isa = kPortableKey;
-  } else {
-    nacl::string nonsfi_isa = GetNonSFIKey(sandbox_isa_);
-    if (nonsfi_enabled_ && dictionary.isMember(nonsfi_isa)) {
-      chosen_isa = nonsfi_isa;
-      *uses_nonsfi_mode = true;
-    } else if (dictionary.isMember(sandbox_isa_)) {
-      chosen_isa = sandbox_isa_;
-    } else if (dictionary.isMember(kPortableKey)) {
-      chosen_isa = kPortableKey;
-    } else {
-      // Should not reach here, because the earlier IsValidISADictionary()
-      // call checked that the manifest covers the current architecture.
-      DCHECK(false);
-    }
-  }
-
-  const Json::Value& isa_spec = dictionary[chosen_isa];
-  // If the PNaCl debug flag is turned on, look for pnacl-debug entries first.
-  // If found, mark that it is a debug URL. Otherwise, fall back to
-  // checking for pnacl-translate URLs, etc. and don't mark it as a debug URL.
-  if (pnacl_debug_ && isa_spec.isMember(kPnaclDebugKey)) {
-    GrabUrlAndPNaClOptions(isa_spec[kPnaclDebugKey], url, pnacl_options);
-    pnacl_options->is_debug = PP_TRUE;
-  } else if (isa_spec.isMember(kPnaclTranslateKey)) {
-    GrabUrlAndPNaClOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options);
-  } else {
-    // NaCl
-    *url = isa_spec[kUrlKey].asString();
-    pnacl_options->translate = PP_FALSE;
-  }
-
-  return true;
-}
-
-bool JsonManifest::GetKeyUrl(const Json::Value& dictionary,
-                             const nacl::string& key,
-                             nacl::string* full_url,
-                             PP_PNaClOptions* pnacl_options,
-                             ErrorInfo* error_info) const {
-  DCHECK(full_url != NULL && pnacl_options != NULL && error_info != NULL);
-  if (!dictionary.isMember(key)) {
-    error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL,
-                          "file key not found in manifest");
-    return false;
-  }
-  const Json::Value& isa_dict = dictionary[key];
-  nacl::string relative_url;
-  bool uses_nonsfi_mode;
-  if (!GetURLFromISADictionary(isa_dict, key, &relative_url,
-                               pnacl_options, &uses_nonsfi_mode, error_info)) {
-    return false;
-  }
-  return ResolveURL(relative_url, full_url, error_info);
-}
-
-bool JsonManifest::GetProgramURL(nacl::string* full_url,
-                                 PP_PNaClOptions* pnacl_options,
-                                 bool* uses_nonsfi_mode,
-                                 ErrorInfo* error_info) const {
-  if (full_url == NULL || pnacl_options == NULL || error_info == NULL)
-    return false;
-
-  const Json::Value& program = dictionary_[kProgramKey];
-
-  nacl::string nexe_url;
-  nacl::string error_string;
-
-  if (!GetURLFromISADictionary(program,
-                               kProgramKey,
-                               &nexe_url,
-                               pnacl_options,
-                               uses_nonsfi_mode,
-                               error_info)) {
-    return false;
-  }
-
-  return ResolveURL(nexe_url, full_url, error_info);
-}
-
-bool JsonManifest::ResolveKey(const nacl::string& key,
-                              nacl::string* full_url,
-                              PP_PNaClOptions* pnacl_options,
-                              ErrorInfo* error_info) const {
-  NaClLog(3, "JsonManifest::ResolveKey(%s)\n", key.c_str());
-  // key must be one of kProgramKey or kFileKey '/' file-section-key
-
-  if (full_url == NULL || pnacl_options == NULL || error_info == NULL)
-    return false;
-
-  if (key == kProgramKey) {
-    return GetKeyUrl(dictionary_, key, full_url, pnacl_options, error_info);
-  }
-  nacl::string::const_iterator p = find(key.begin(), key.end(), '/');
-  if (p == key.end()) {
-    error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL,
-                          nacl::string("ResolveKey: invalid key, no slash: ")
-                          + key);
-    return false;
-  }
-
-  // generalize to permit other sections?
-  nacl::string prefix(key.begin(), p);
-  if (prefix != kFilesKey) {
-    error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL,
-                          nacl::string("ResolveKey: invalid key: not \"files\""
-                                       " prefix: ") + key);
-    return false;
-  }
-
-  nacl::string rest(p + 1, key.end());
-
-  const Json::Value& files = dictionary_[kFilesKey];
-  if (!files.isObject()) {
-    error_info->SetReport(
-        PP_NACL_ERROR_MANIFEST_RESOLVE_URL,
-        nacl::string("ResolveKey: no \"files\" dictionary"));
-    return false;
-  }
-  if (!files.isMember(rest)) {
-    error_info->SetReport(
-        PP_NACL_ERROR_MANIFEST_RESOLVE_URL,
-        nacl::string("ResolveKey: no such \"files\" entry: ") + key);
-    return false;
-  }
-  return GetKeyUrl(files, rest, full_url, pnacl_options, error_info);
-}
-
-bool JsonManifest::ResolveURL(const nacl::string& relative_url,
-                              nacl::string* full_url,
-                              ErrorInfo* error_info) const {
-  // The contents of the manifest are resolved relative to the manifest URL.
-  CHECK(url_util_ != NULL);
-  pp::Var resolved_url =
-      url_util_->ResolveRelativeToURL(pp::Var(manifest_base_url_),
-                                      relative_url);
-  if (!resolved_url.is_string()) {
-    error_info->SetReport(
-        PP_NACL_ERROR_MANIFEST_RESOLVE_URL,
-        "could not resolve url '" + relative_url +
-        "' relative to manifest base url '" + manifest_base_url_.c_str() +
-        "'.");
-    return false;
-  }
-  *full_url = resolved_url.AsString();
-  return true;
-}
-
-}  // namespace plugin
diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.h b/ppapi/native_client/src/trusted/plugin/json_manifest.h
deleted file mode 100644
index dd7e3ab..0000000
--- a/ppapi/native_client/src/trusted/plugin/json_manifest.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2012 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.
- */
-
-// Manifest processing for JSON manifests.
-
-#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_JSON_MANIFEST_H_
-#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_JSON_MANIFEST_H_
-
-#include <map>
-#include <set>
-#include <string>
-
-#include "native_client/src/include/nacl_macros.h"
-#include "native_client/src/include/nacl_string.h"
-#include "ppapi/native_client/src/trusted/plugin/manifest.h"
-#include "third_party/jsoncpp/source/include/json/value.h"
-
-struct PP_PNaClOptions;
-
-namespace pp {
-class URLUtil_Dev;
-}  // namespace pp
-
-namespace plugin {
-
-class ErrorInfo;
-
-class JsonManifest : public Manifest {
- public:
-  JsonManifest(const pp::URLUtil_Dev* url_util,
-               const nacl::string& manifest_base_url,
-               const nacl::string& sandbox_isa,
-               bool nonsfi_enabled,
-               bool pnacl_debug)
-      : url_util_(url_util),
-        manifest_base_url_(manifest_base_url),
-        sandbox_isa_(sandbox_isa),
-        nonsfi_enabled_(nonsfi_enabled),
-        pnacl_debug_(pnacl_debug),
-        dictionary_(Json::nullValue) { }
-  virtual ~JsonManifest() { }
-
-  // Initialize the manifest object for use by later lookups.  The return
-  // value is true if the manifest parses correctly and matches the schema.
-  bool Init(const nacl::string& json, ErrorInfo* error_info);
-
-  // Gets the full program URL for the current sandbox ISA from the
-  // manifest file.
-  virtual bool GetProgramURL(nacl::string* full_url,
-                             PP_PNaClOptions* pnacl_options,
-                             bool* uses_nonsfi_mode,
-                             ErrorInfo* error_info) const;
-
-  // Resolves a key from the "files" section to a fully resolved URL,
-  // i.e., relative URL values are fully expanded relative to the
-  // manifest's URL (via ResolveURL).
-  // If there was an error, details are reported via error_info.
-  virtual bool ResolveKey(const nacl::string& key,
-                          nacl::string* full_url,
-                          PP_PNaClOptions* pnacl_options,
-                          ErrorInfo* error_info) const;
-
- private:
-  NACL_DISALLOW_COPY_AND_ASSIGN(JsonManifest);
-
-  // Resolves a URL relative to the manifest base URL
-  bool ResolveURL(const nacl::string& relative_url,
-                  nacl::string* full_url,
-                  ErrorInfo* error_info) const;
-
-  // Checks that |dictionary_| is a valid manifest, according to the schema.
-  // Returns true on success, and sets |error_info| to a detailed message
-  // if not.
-  bool MatchesSchema(ErrorInfo* error_info);
-
-  bool GetKeyUrl(const Json::Value& dictionary,
-                 const nacl::string& key,
-                 nacl::string* full_url,
-                 PP_PNaClOptions* pnacl_options,
-                 ErrorInfo* error_info) const;
-
-  bool GetURLFromISADictionary(const Json::Value& dictionary,
-                               const nacl::string& parent_key,
-                               nacl::string* url,
-                               PP_PNaClOptions* pnacl_options,
-                               bool* uses_nonsfi_mode,
-                               ErrorInfo* error_info) const;
-
-  const pp::URLUtil_Dev* url_util_;
-  nacl::string manifest_base_url_;
-  nacl::string sandbox_isa_;
-  bool nonsfi_enabled_;
-  bool pnacl_debug_;
-
-  Json::Value dictionary_;
-};
-
-}  // namespace plugin
-
-#endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_JSON_MANIFEST_H_
diff --git a/ppapi/native_client/src/trusted/plugin/manifest.h b/ppapi/native_client/src/trusted/plugin/manifest.h
deleted file mode 100644
index 03ed71e..0000000
--- a/ppapi/native_client/src/trusted/plugin/manifest.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2012 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.
- */
-
-// Manifest interface class.
-
-#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_
-#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_
-
-#include <map>
-#include <set>
-#include <string>
-
-#include "native_client/src/include/nacl_macros.h"
-#include "native_client/src/include/nacl_string.h"
-#include "third_party/jsoncpp/source/include/json/value.h"
-
-struct PP_PNaClOptions;
-
-namespace pp {
-class URLUtil_Dev;
-}  // namespace pp
-
-namespace plugin {
-
-class ErrorInfo;
-
-class Manifest {
- public:
-  Manifest() { }
-  virtual ~Manifest() { }
-
-  // A convention in the interfaces below regarding permit_extension_url:
-  // Some manifests (e.g., the pnacl coordinator manifest) need to access
-  // resources from an extension origin distinct from the plugin's origin
-  // (e.g., the pnacl coordinator needs to load llc, ld, and some libraries).
-  // This out-parameter is true if this manifest lookup confers access to
-  // a resource in the extension origin.
-
-  // Gets the full program URL for the current sandbox ISA from the
-  // manifest file.  Fills in |pnacl_options| if the program requires
-  // PNaCl translation.
-  virtual bool GetProgramURL(nacl::string* full_url,
-                             PP_PNaClOptions* pnacl_options,
-                             bool* uses_nonsfi_mode,
-                             ErrorInfo* error_info) const = 0;
-
-  // Resolves a key from the "files" section to a fully resolved URL,
-  // i.e., relative URL values are fully expanded relative to the
-  // manifest's URL.  Fills in |pnacl_options| if
-  // the resolved key requires a pnacl translation step to obtain
-  // the final requested resource.
-  // If there was an error, details are reported via error_info.
-  virtual bool ResolveKey(const nacl::string& key,
-                          nacl::string* full_url,
-                          PP_PNaClOptions* pnacl_options,
-                          ErrorInfo* error_info) const = 0;
-
- protected:
-  NACL_DISALLOW_COPY_AND_ASSIGN(Manifest);
-};
-
-
-}  // namespace plugin
-
-#endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_MANIFEST_H_
diff --git a/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h b/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h
index 4d4c923..5e8ca99 100644
--- a/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h
+++ b/ppapi/native_client/src/trusted/plugin/nacl_entry_points.h
@@ -28,7 +28,7 @@
     PP_Bool enable_dyncode_syscalls,
     PP_Bool enable_exception_handling,
     PP_Bool enable_crash_throttling,
-    const PP_ManifestService* manifest_service_interface,
+    const PPP_ManifestService* manifest_service_interface,
     void* manifest_service_user_data,
     NaClHandle* result_socket,
     struct PP_Var* error_message,
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc
index 986f6d7..ce2d4ba 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.cc
+++ b/ppapi/native_client/src/trusted/plugin/plugin.cc
@@ -34,8 +34,6 @@
 #include "ppapi/cpp/dev/url_util_dev.h"
 #include "ppapi/cpp/module.h"
 
-#include "ppapi/native_client/src/trusted/plugin/file_utils.h"
-#include "ppapi/native_client/src/trusted/plugin/json_manifest.h"
 #include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h"
 #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h"
 #include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
@@ -137,11 +135,11 @@
 bool Plugin::LoadNaClModuleFromBackgroundThread(
     nacl::DescWrapper* wrapper,
     NaClSubprocess* subprocess,
-    const Manifest* manifest,
+    int32_t manifest_id,
     const SelLdrStartParams& params) {
   CHECK(!pp::Module::Get()->core()->IsMainThread());
   ServiceRuntime* service_runtime =
-      new ServiceRuntime(this, manifest, false, uses_nonsfi_mode_,
+      new ServiceRuntime(this, manifest_id, false, uses_nonsfi_mode_,
                          pp::BlockUntilComplete(), pp::BlockUntilComplete());
   subprocess->set_service_runtime(service_runtime);
   PLUGIN_PRINTF(("Plugin::LoadNaClModuleFromBackgroundThread "
@@ -229,7 +227,7 @@
                            enable_crash_throttling);
   ErrorInfo error_info;
   ServiceRuntime* service_runtime =
-      new ServiceRuntime(this, manifest_.get(), true, uses_nonsfi_mode,
+      new ServiceRuntime(this, manifest_id_, true, uses_nonsfi_mode,
                          init_done_cb, crash_cb);
   main_subprocess_.set_service_runtime(service_runtime);
   PLUGIN_PRINTF(("Plugin::LoadNaClModule (service_runtime=%p)\n",
@@ -294,7 +292,7 @@
 
 NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url,
                                              nacl::DescWrapper* wrapper,
-                                             const Manifest* manifest,
+                                             int32_t manifest_id,
                                              ErrorInfo* error_info) {
   nacl::scoped_ptr<NaClSubprocess> nacl_subprocess(
       new NaClSubprocess("helper module", NULL, NULL));
@@ -321,7 +319,7 @@
                            false /* enable_exception_handling */,
                            true /* enable_crash_throttling */);
   if (!LoadNaClModuleFromBackgroundThread(wrapper, nacl_subprocess.get(),
-                                          manifest, params)) {
+                                          manifest_id, params)) {
     return NULL;
   }
   // We need not wait for the init_done callback.  We can block
@@ -370,8 +368,8 @@
       uses_nonsfi_mode_(false),
       wrapper_factory_(NULL),
       time_of_last_progress_event_(0),
-      manifest_open_time_(-1),
       nexe_open_time_(-1),
+      manifest_id_(-1),
       nacl_interface_(NULL),
       uma_interface_(this) {
   PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%"
@@ -566,74 +564,14 @@
 void Plugin::NaClManifestFileDidOpen(int32_t pp_error) {
   PLUGIN_PRINTF(("Plugin::NaClManifestFileDidOpen (pp_error=%"
                  NACL_PRId32 ")\n", pp_error));
-  int64_t now = NaClGetTimeOfDayMicroseconds();
-  int64_t download_time;
-  if (now < manifest_open_time_)
-    download_time = 0;
-  else
-    download_time = now - manifest_open_time_;
-  HistogramTimeSmall("NaCl.Perf.StartupTime.ManifestDownload",
-                     download_time / 1000);
-  HistogramHTTPStatusCode(
-      nacl_interface_->GetIsInstalled(pp_instance()) ?
-          "NaCl.HttpStatusCodeClass.Manifest.InstalledApp" :
-          "NaCl.HttpStatusCodeClass.Manifest.NotInstalledApp",
-      nexe_downloader_.status_code());
-  ErrorInfo error_info;
-  NaClFileInfo tmp_info(nexe_downloader_.GetFileInfo());
-  NaClFileInfoAutoCloser info(&tmp_info);
-  PLUGIN_PRINTF(("Plugin::NaClManifestFileDidOpen (file_desc=%"
-                 NACL_PRId32 ")\n", info.get_desc()));
-  if (pp_error != PP_OK || info.get_desc() == NACL_NO_FILE_DESC) {
-    if (pp_error == PP_ERROR_ABORTED) {
-      ReportLoadAbort();
-    } else if (pp_error == PP_ERROR_NOACCESS) {
-      error_info.SetReport(PP_NACL_ERROR_MANIFEST_NOACCESS_URL,
-                           "access to manifest url was denied.");
-      ReportLoadError(error_info);
-    } else {
-      error_info.SetReport(PP_NACL_ERROR_MANIFEST_LOAD_URL,
-                           "could not load manifest url.");
-      ReportLoadError(error_info);
-    }
-    return;
-  }
-  nacl::string json_buffer;
-  // SlurpFile closes the file descriptor after reading (or on error).
-  file_utils::StatusCode status = file_utils::SlurpFile(
-      info.Release().desc, json_buffer, kNaClManifestMaxFileBytes);
+  if (pp_error == PP_OK) {
+    // Take local ownership of manifest_data_var_
+    pp::Var manifest_data = pp::Var(pp::PASS_REF, manifest_data_var_);
+    manifest_data_var_ = PP_MakeUndefined();
 
-  if (status != file_utils::PLUGIN_FILE_SUCCESS) {
-    switch (status) {
-      case file_utils::PLUGIN_FILE_SUCCESS:
-        CHECK(0);
-        break;
-      case file_utils::PLUGIN_FILE_ERROR_MEM_ALLOC:
-        error_info.SetReport(PP_NACL_ERROR_MANIFEST_MEMORY_ALLOC,
-                             "could not allocate manifest memory.");
-        break;
-      case file_utils::PLUGIN_FILE_ERROR_OPEN:
-        error_info.SetReport(PP_NACL_ERROR_MANIFEST_OPEN,
-                             "could not open manifest file.");
-        break;
-      case file_utils::PLUGIN_FILE_ERROR_FILE_TOO_LARGE:
-        error_info.SetReport(PP_NACL_ERROR_MANIFEST_TOO_LARGE,
-                             "manifest file too large.");
-        break;
-      case file_utils::PLUGIN_FILE_ERROR_STAT:
-        error_info.SetReport(PP_NACL_ERROR_MANIFEST_STAT,
-                             "could not stat manifest file.");
-        break;
-      case file_utils::PLUGIN_FILE_ERROR_READ:
-        error_info.SetReport(PP_NACL_ERROR_MANIFEST_READ,
-                             "could not read manifest file.");
-        break;
-    }
-    ReportLoadError(error_info);
-    return;
+    std::string json_buffer = manifest_data.AsString();
+    ProcessNaClManifest(json_buffer);
   }
-
-  ProcessNaClManifest(json_buffer);
 }
 
 void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) {
@@ -642,20 +580,19 @@
   if (!SetManifestObject(manifest_json))
     return;
 
-  nacl::string program_url;
+  PP_Var pp_program_url;
   PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2};
-  bool uses_nonsfi_mode;
-  ErrorInfo error_info;
-  if (manifest_->GetProgramURL(
-          &program_url, &pnacl_options, &uses_nonsfi_mode, &error_info)) {
+  PP_Bool uses_nonsfi_mode;
+  if (nacl_interface_->GetManifestProgramURL(pp_instance(),
+          manifest_id_, &pp_program_url, &pnacl_options, &uses_nonsfi_mode)) {
+    std::string program_url = pp::Var(pp::PASS_REF, pp_program_url).AsString();
     // TODO(teravest): Make ProcessNaClManifest take responsibility for more of
     // this function.
     nacl_interface_->ProcessNaClManifest(pp_instance(), program_url.c_str());
-    uses_nonsfi_mode_ = uses_nonsfi_mode;
+    uses_nonsfi_mode_ = PP_ToBool(uses_nonsfi_mode);
     if (pnacl_options.translate) {
       pp::CompletionCallback translate_callback =
           callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate);
-      // Will always call the callback on success or failure.
       pnacl_coordinator_.reset(
           PnaclCoordinator::BitcodeToNative(this,
                                             program_url,
@@ -681,8 +618,6 @@
       return;
     }
   }
-  // Failed to select the program and/or the translator.
-  ReportLoadError(error_info);
 }
 
 void Plugin::RequestNaClManifest(const nacl::string& url) {
@@ -713,13 +648,11 @@
   } else {
     pp::CompletionCallback open_callback =
         callback_factory_.NewCallback(&Plugin::NaClManifestFileDidOpen);
-    manifest_open_time_ = NaClGetTimeOfDayMicroseconds();
-    // Will always call the callback on success or failure.
-    CHECK(nexe_downloader_.Open(nmf_resolved_url.AsString(),
-                                DOWNLOAD_TO_FILE,
-                                open_callback,
-                                false,
-                                NULL));
+    std::string nmf_resolved_url_str = nmf_resolved_url.AsString();
+    nacl_interface_->DownloadManifestToBuffer(
+        pp_instance(),
+        &manifest_data_var_,
+        open_callback.pp_completion_callback());
   }
 }
 
@@ -727,30 +660,22 @@
 bool Plugin::SetManifestObject(const nacl::string& manifest_json) {
   PLUGIN_PRINTF(("Plugin::SetManifestObject(): manifest_json='%s'.\n",
        manifest_json.c_str()));
-  ErrorInfo error_info;
-
   // Determine whether lookups should use portable (i.e., pnacl versions)
   // rather than platform-specific files.
   bool is_pnacl = nacl_interface_->IsPNaCl(pp_instance());
-  bool nonsfi_mode_enabled =
-      PP_ToBool(nacl_interface_->IsNonSFIModeEnabled());
   pp::Var manifest_base_url =
       pp::Var(pp::PASS_REF, nacl_interface_->GetManifestBaseURL(pp_instance()));
   std::string manifest_base_url_str = manifest_base_url.AsString();
-  bool pnacl_debug = GetNaClInterface()->NaClDebugEnabledForURL(
-      manifest_base_url_str.c_str());
   const char* sandbox_isa = nacl_interface_->GetSandboxArch();
-  nacl::scoped_ptr<JsonManifest> json_manifest(
-      new JsonManifest(pp::URLUtil_Dev::Get(),
-                       manifest_base_url_str,
-                       (is_pnacl ? kPortableArch : sandbox_isa),
-                       nonsfi_mode_enabled,
-                       pnacl_debug));
-  if (!json_manifest->Init(manifest_json, &error_info)) {
-    ReportLoadError(error_info);
+
+  int32_t manifest_id = nacl_interface_->CreateJsonManifest(
+      pp_instance(),
+      manifest_base_url_str.c_str(),
+      is_pnacl ? kPortableArch : sandbox_isa,
+      manifest_json.c_str());
+  if (manifest_id == -1)
     return false;
-  }
-  manifest_.reset(json_manifest.release());
+  manifest_id_ = manifest_id;
   return true;
 }
 
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.gypi b/ppapi/native_client/src/trusted/plugin/plugin.gypi
index d9de561..27ee36a 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.gypi
+++ b/ppapi/native_client/src/trusted/plugin/plugin.gypi
@@ -7,8 +7,6 @@
     'chromium_code': 1,  # Use higher warning level.
     'common_sources': [
       'file_downloader.cc',
-      'file_utils.cc',
-      'json_manifest.cc',
       'module_ppapi.cc',
       'nacl_subprocess.cc',
       'plugin.cc',
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h
index 2e1c779..1978be7 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.h
+++ b/ppapi/native_client/src/trusted/plugin/plugin.h
@@ -111,7 +111,7 @@
   // Returns NULL or the NaClSubprocess of the new helper NaCl module.
   NaClSubprocess* LoadHelperNaClModule(const nacl::string& helper_url,
                                        nacl::DescWrapper* wrapper,
-                                       const Manifest* manifest,
+                                       int32_t manifest_id,
                                        ErrorInfo* error_info);
 
   enum LengthComputable {
@@ -164,8 +164,6 @@
   // document to request the URL using CORS even if this function returns false.
   bool DocumentCanRequest(const std::string& url);
 
-  Manifest const* manifest() const { return manifest_.get(); }
-
   // set_exit_status may be called off the main thread.
   void set_exit_status(int exit_status);
 
@@ -206,7 +204,7 @@
   // This will fully initialize the |subprocess| if the load was successful.
   bool LoadNaClModuleFromBackgroundThread(nacl::DescWrapper* wrapper,
                                           NaClSubprocess* subprocess,
-                                          const Manifest* manifest,
+                                          int32_t manifest_id,
                                           const SelLdrStartParams& params);
 
   // Start sel_ldr from the main thread, given the start params.
@@ -304,9 +302,6 @@
 
   nacl::scoped_ptr<PnaclCoordinator> pnacl_coordinator_;
 
-  // The manifest dictionary.  Used for looking up resources to be loaded.
-  nacl::scoped_ptr<Manifest> manifest_;
-
   // Keep track of the FileDownloaders created to fetch urls.
   std::set<FileDownloader*> url_downloaders_;
   // Keep track of file descriptors opened by StreamAsFile().
@@ -331,9 +326,11 @@
   int exit_status_;
 
   // Open times are in microseconds.
-  int64_t manifest_open_time_;
   int64_t nexe_open_time_;
 
+  PP_Var manifest_data_var_;
+  int32_t manifest_id_;
+
   const PPB_NaCl_Private* nacl_interface_;
   pp::UMAPrivate uma_interface_;
 };
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
index fd108b7..27c75c7 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
@@ -16,7 +16,6 @@
 #include "ppapi/c/pp_errors.h"
 #include "ppapi/c/private/ppb_uma_private.h"
 
-#include "ppapi/native_client/src/trusted/plugin/manifest.h"
 #include "ppapi/native_client/src/trusted/plugin/plugin.h"
 #include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
 #include "ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h"
@@ -26,64 +25,6 @@
 namespace plugin {
 
 //////////////////////////////////////////////////////////////////////
-//  Pnacl-specific manifest support.
-//////////////////////////////////////////////////////////////////////
-
-// The PNaCl linker gets file descriptors via the service runtime's
-// reverse service lookup.  The reverse service lookup requires a manifest.
-// Normally, that manifest is an NMF containing mappings for shared libraries.
-// Here, we provide a manifest that redirects to PNaCl component files
-// that are part of Chrome.
-class PnaclManifest : public Manifest {
- public:
-  PnaclManifest(const nacl::string& sandbox_arch)
-      : sandbox_arch_(sandbox_arch) { }
-
-  virtual ~PnaclManifest() { }
-
-  virtual bool GetProgramURL(nacl::string* full_url,
-                             PP_PNaClOptions* pnacl_options,
-                             bool* uses_nonsfi_mode,
-                             ErrorInfo* error_info) const {
-    // Does not contain program urls.
-    UNREFERENCED_PARAMETER(full_url);
-    UNREFERENCED_PARAMETER(pnacl_options);
-    UNREFERENCED_PARAMETER(uses_nonsfi_mode);
-    UNREFERENCED_PARAMETER(error_info);
-    PLUGIN_PRINTF(("PnaclManifest does not contain a program\n"));
-    error_info->SetReport(PP_NACL_ERROR_MANIFEST_GET_NEXE_URL,
-                          "pnacl manifest does not contain a program.");
-    return false;
-  }
-
-  virtual bool ResolveKey(const nacl::string& key,
-                          nacl::string* full_url,
-                          PP_PNaClOptions* pnacl_options,
-                          ErrorInfo* error_info) const {
-    // All of the component files are native (do not require pnacl translate).
-    pnacl_options->translate = PP_FALSE;
-    // We can only resolve keys in the files/ namespace.
-    const nacl::string kFilesPrefix = "files/";
-    size_t files_prefix_pos = key.find(kFilesPrefix);
-    if (files_prefix_pos == nacl::string::npos) {
-      error_info->SetReport(PP_NACL_ERROR_MANIFEST_RESOLVE_URL,
-                            "key did not start with files/");
-      return false;
-    }
-    // Resolve the full URL to the file. Provide it with a platform-specific
-    // prefix.
-    nacl::string key_basename = key.substr(kFilesPrefix.length());
-    *full_url = PnaclUrls::GetBaseUrl() + sandbox_arch_ + "/" + key_basename;
-    return true;
-  }
-
- private:
-  NACL_DISALLOW_COPY_AND_ASSIGN(PnaclManifest);
-
-  nacl::string sandbox_arch_;
-};
-
-//////////////////////////////////////////////////////////////////////
 //  UMA stat helpers.
 //////////////////////////////////////////////////////////////////////
 
@@ -159,6 +100,12 @@
                            opt_level, kOptUnknown+1);
 }
 
+nacl::string GetArchitectureAttributes(Plugin* plugin) {
+  pp::Var attrs_var(pp::PASS_REF,
+                    plugin->nacl_interface()->GetCpuFeatureAttrs());
+  return attrs_var.AsString();
+}
+
 }  // namespace
 
 
@@ -182,10 +129,10 @@
       new PnaclCoordinator(plugin, pexe_url,
                            pnacl_options,
                            translate_notify_callback);
-  coordinator->pnacl_init_time_ = NaClGetTimeOfDayMicroseconds();
-  PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p, ",
-                 reinterpret_cast<const void*>(coordinator->manifest_.get())));
+  PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest_id=%d)\n",
+                 coordinator->manifest_id_));
 
+  coordinator->pnacl_init_time_ = NaClGetTimeOfDayMicroseconds();
   int cpus = plugin->nacl_interface()->GetNumberOfProcessors();
   coordinator->split_module_count_ = std::min(4, std::max(1, cpus));
 
@@ -206,9 +153,11 @@
     plugin_(plugin),
     translate_notify_callback_(translate_notify_callback),
     translation_finished_reported_(false),
-    manifest_(new PnaclManifest(plugin->nacl_interface()->GetSandboxArch())),
+    manifest_id_(
+        GetNaClInterface()->CreatePnaclManifest(plugin->pp_instance())),
     pexe_url_(pexe_url),
     pnacl_options_(pnacl_options),
+    architecture_attributes_(GetArchitectureAttributes(plugin)),
     split_module_count_(1),
     num_object_files_opened_(0),
     is_cache_hit_(PP_FALSE),
@@ -479,7 +428,7 @@
           1,
           pnacl_options_.opt_level,
           headers.c_str(),
-          "", // No extra compile flags yet.
+          architecture_attributes_.c_str(), // Extra compile flags.
           &is_cache_hit_,
           temp_nexe_file_->existing_handle(),
           cb.pp_completion_callback());
@@ -670,13 +619,14 @@
 
   CHECK(translate_thread_ != NULL);
   translate_thread_->RunTranslate(report_translate_finished,
-                                  manifest_.get(),
+                                  manifest_id_,
                                   &obj_files_,
                                   temp_nexe_file_.get(),
                                   invalid_desc_wrapper_.get(),
                                   &error_info_,
                                   resources_.get(),
                                   &pnacl_options_,
+                                  architecture_attributes_,
                                   this,
                                   plugin_);
 }
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
index 99d6e70..058f9ac 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
@@ -27,7 +27,6 @@
 
 namespace plugin {
 
-class Manifest;
 class Plugin;
 class PnaclCoordinator;
 class PnaclTranslateThread;
@@ -204,7 +203,7 @@
 
   // The manifest used by resource loading and ld + llc's reverse service
   // to look up objects and libraries.
-  nacl::scoped_ptr<const Manifest> manifest_;
+  int32_t manifest_id_;
   // An auxiliary class that manages downloaded resources (llc and ld nexes).
   nacl::scoped_ptr<PnaclResources> resources_;
 
@@ -212,6 +211,10 @@
   nacl::string pexe_url_;
   // Options for translation.
   PP_PNaClOptions pnacl_options_;
+  // Architecture-specific attributes used for translation. These are
+  // supplied by Chrome, not the developer, and are therefore different
+  // from PNaCl options.
+  nacl::string architecture_attributes_;
 
   // Object file, produced by the translator and consumed by the linker.
   std::vector<TempFile*> obj_files_;
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc
index 160066b..12ef449 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc
@@ -8,8 +8,6 @@
 #include "native_client/src/shared/platform/nacl_check.h"
 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
 #include "ppapi/c/pp_errors.h"
-#include "ppapi/native_client/src/trusted/plugin/file_utils.h"
-#include "ppapi/native_client/src/trusted/plugin/manifest.h"
 #include "ppapi/native_client/src/trusted/plugin/plugin.h"
 #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h"
 #include "ppapi/native_client/src/trusted/plugin/utility.h"
@@ -107,73 +105,24 @@
   PLUGIN_PRINTF(("Pnacl-converted resources info url: %s\n",
                  resource_info_filename.c_str()));
 
-  int32_t fd = GetPnaclFD(plugin_, resource_info_filename.c_str());
-  if (fd < 0) {
-    // File-open failed. Assume this means that the file is
-    // not actually installed.
-    coordinator_->ReportNonPpapiError(PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
-        nacl::string("The Portable Native Client (pnacl) component is not "
-                     "installed. Please consult chrome://components for more "
-                     "information."));
-    return;
+  PP_Var pp_llc_tool_name_var;
+  PP_Var pp_ld_tool_name_var;
+  if (!plugin_->nacl_interface()->GetPnaclResourceInfo(
+          plugin_->pp_instance(),
+          resource_info_filename.c_str(),
+          &pp_llc_tool_name_var,
+          &pp_ld_tool_name_var)) {
+    coordinator_->ExitWithError();
   }
 
-  nacl::string json_buffer;
-  file_utils::StatusCode status = file_utils::SlurpFile(fd, json_buffer);
-  if (status != file_utils::PLUGIN_FILE_SUCCESS) {
-    coordinator_->ReportNonPpapiError(PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
-        nacl::string("PnaclResources::ReadResourceInfo reading "
-                     "failed for: ") + resource_info_filename);
-    return;
-  }
-
-  // Finally, we have the resource info JSON data in json_buffer.
-  PLUGIN_PRINTF(("Resource info JSON data:\n%s\n", json_buffer.c_str()));
-  if (!ParseResourceInfo(json_buffer))
-    return;
-
-  // Done. Queue the completion callback.
+  pp::Var llc_tool_name(pp::PASS_REF, pp_llc_tool_name_var);
+  pp::Var ld_tool_name(pp::PASS_REF, pp_ld_tool_name_var);
+  llc_tool_name_ = llc_tool_name.AsString();
+  ld_tool_name_ = ld_tool_name.AsString();
   pp::Core* core = pp::Module::Get()->core();
   core->CallOnMainThread(0, resource_info_read_cb, PP_OK);
 }
 
-bool PnaclResources::ParseResourceInfo(const nacl::string& buf) {
-  // Expect the JSON file to contain a top-level object (dictionary).
-  Json::Reader json_reader;
-  Json::Value json_data;
-  if (!json_reader.parse(buf, json_data)) {
-    std::string errmsg = nacl::string("JSON parse error: ") +
-        json_reader.getFormatedErrorMessages();
-    coordinator_->ReportNonPpapiError(PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
-        nacl::string("Parsing resource info failed: ") + errmsg + "\n");
-    return false;
-  }
-
-  if (!json_data.isObject()) {
-    coordinator_->ReportNonPpapiError(PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
-        nacl::string("Parsing resource info failed: "
-                     "Malformed JSON dictionary\n"));
-    return false;
-  }
-
-  if (json_data.isMember("pnacl-llc-name")) {
-    Json::Value json_name = json_data["pnacl-llc-name"];
-    if (json_name.isString()) {
-      llc_tool_name_ = json_name.asString();
-      PLUGIN_PRINTF(("Set llc_tool_name=%s\n", llc_tool_name_.c_str()));
-    }
-  }
-
-  if (json_data.isMember("pnacl-ld-name")) {
-    Json::Value json_name = json_data["pnacl-ld-name"];
-    if (json_name.isString()) {
-      ld_tool_name_ = json_name.asString();
-      PLUGIN_PRINTF(("Set ld_tool_name=%s\n", ld_tool_name_.c_str()));
-    }
-  }
-  return true;
-}
-
 nacl::string PnaclResources::GetFullUrl(
     const nacl::string& partial_url, const nacl::string& sandbox_arch) const {
   return PnaclUrls::GetBaseUrl() + sandbox_arch + "/" + partial_url;
@@ -184,8 +133,8 @@
   PLUGIN_PRINTF(("PnaclResources::StartLoad\n"));
 
   std::vector<nacl::string> resource_urls;
-  resource_urls.push_back(GetLlcUrl());
-  resource_urls.push_back(GetLdUrl());
+  resource_urls.push_back(llc_tool_name_);
+  resource_urls.push_back(ld_tool_name_);
 
   PLUGIN_PRINTF(("PnaclResources::StartLoad -- local install of PNaCl.\n"));
   // Do a blocking load of each of the resources.
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_resources.h b/ppapi/native_client/src/trusted/plugin/pnacl_resources.h
index 91d87a2..7cefa6f 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_resources.h
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_resources.h
@@ -86,10 +86,6 @@
   // Tool names for llc and ld; read from the resource info file.
   nacl::string llc_tool_name_;
   nacl::string ld_tool_name_;
-
-  // Parses resource info json data in |buf|.  Returns true if successful.
-  // Otherwise returns false.
-  bool ParseResourceInfo(const nacl::string& buf);
 };
 
 }  // namespace plugin;
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
index 10f01bb..695e7f2 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
@@ -7,6 +7,7 @@
 #include <iterator>
 
 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
+#include "ppapi/cpp/var.h"
 #include "ppapi/native_client/src/trusted/plugin/plugin.h"
 #include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
 #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h"
@@ -17,20 +18,36 @@
 namespace plugin {
 namespace {
 
-nacl::string GetOptCommandLine(int32_t opt_level, bool is_debug) {
-  nacl::string str;
+template <typename Val>
+nacl::string MakeCommandLineArg(const char* key, const Val val) {
   nacl::stringstream ss;
-  ss << "-O" << opt_level;
-  str = ss.str();
-  str += '\x00';
+  ss << key << val;
+  return ss.str();
+}
 
-  // Debug info is only available in LLVM format pexes,
-  // not in PNaCl format pexes.
-  if (is_debug) {
-    str += "-bitcode-format=llvm";
-    str += '\x00';
+void GetLlcCommandLine(Plugin* plugin,
+                       std::vector<char>* split_args,
+                       size_t obj_files_size,
+                       int32_t opt_level,
+                       bool is_debug,
+                       const nacl::string &architecture_attributes) {
+  typedef std::vector<nacl::string> Args;
+  Args args;
+
+  // TODO(dschuff): This CL override is ugly. Change llc to default to
+  // using the number of modules specified in the first param, and
+  // ignore multiple uses of -split-module
+  args.push_back(MakeCommandLineArg("-split-module=", obj_files_size));
+  args.push_back(MakeCommandLineArg("-O=", opt_level));
+  if (is_debug)
+    args.push_back("-bitcode-format=llvm");
+  if (!architecture_attributes.empty())
+    args.push_back("-mattr=" + architecture_attributes);
+
+  for (Args::const_iterator arg(args.begin()); arg != args.end(); ++arg) {
+    std::copy(arg->begin(), arg->end(), std::back_inserter(*split_args));
+    split_args->push_back('\x00');
   }
-  return str;
 }
 
 }  // namespace
@@ -39,7 +56,7 @@
                                                ld_subprocess_active_(false),
                                                done_(false),
                                                compile_time_(0),
-                                               manifest_(NULL),
+                                               manifest_id_(0),
                                                obj_files_(NULL),
                                                nexe_file_(NULL),
                                                coordinator_error_info_(NULL),
@@ -53,23 +70,25 @@
 
 void PnaclTranslateThread::RunTranslate(
     const pp::CompletionCallback& finish_callback,
-    const Manifest* manifest,
+    int32_t manifest_id,
     const std::vector<TempFile*>* obj_files,
     TempFile* nexe_file,
     nacl::DescWrapper* invalid_desc_wrapper,
     ErrorInfo* error_info,
     PnaclResources* resources,
     PP_PNaClOptions* pnacl_options,
+    const nacl::string &architecture_attributes,
     PnaclCoordinator* coordinator,
     Plugin* plugin) {
   PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n"));
-  manifest_ = manifest;
+  manifest_id_ = manifest_id;
   obj_files_ = obj_files;
   nexe_file_ = nexe_file;
   invalid_desc_wrapper_ = invalid_desc_wrapper;
   coordinator_error_info_ = error_info;
   resources_ = resources;
   pnacl_options_ = pnacl_options;
+  architecture_attributes_ = architecture_attributes;
   coordinator_ = coordinator;
   plugin_ = plugin;
 
@@ -129,7 +148,7 @@
 
 NaClSubprocess* PnaclTranslateThread::StartSubprocess(
     const nacl::string& url_for_nexe,
-    const Manifest* manifest,
+    int32_t manifest_id,
     ErrorInfo* error_info) {
   PLUGIN_PRINTF(("PnaclTranslateThread::StartSubprocess (url_for_nexe=%s)\n",
                  url_for_nexe.c_str()));
@@ -140,8 +159,8 @@
   // string gets silently dropped by GURL.
   nacl::string full_url = resources_->GetFullUrl(
       url_for_nexe, plugin_->nacl_interface()->GetSandboxArch());
-  nacl::scoped_ptr<NaClSubprocess> subprocess(
-      plugin_->LoadHelperNaClModule(full_url, wrapper, manifest, error_info));
+  nacl::scoped_ptr<NaClSubprocess> subprocess(plugin_->LoadHelperNaClModule(
+      full_url, wrapper, manifest_id, error_info));
   if (subprocess.get() == NULL) {
     PLUGIN_PRINTF((
         "PnaclTranslateThread::StartSubprocess: subprocess creation failed\n"));
@@ -173,7 +192,7 @@
     nacl::MutexLocker ml(&subprocess_mu_);
     int64_t llc_start_time = NaClGetTimeOfDayMicroseconds();
     llc_subprocess_.reset(
-      StartSubprocess(resources_->GetLlcUrl(), manifest_, &error_info));
+      StartSubprocess(resources_->GetLlcUrl(), manifest_id_, &error_info));
     if (llc_subprocess_ == NULL) {
       TranslateFailed(PP_NACL_ERROR_PNACL_LLC_SETUP,
                       "Compile process could not be created: " +
@@ -198,17 +217,12 @@
   bool init_success;
 
   std::vector<char> split_args;
-  nacl::stringstream ss;
-  // TODO(dschuff): This CL override is ugly. Change llc to default to using
-  // the number of modules specified in the first param, and ignore multiple
-  // uses of -split-module
-  ss << "-split-module=" << obj_files_->size();
-  nacl::string split_arg = ss.str();
-  std::copy(split_arg.begin(), split_arg.end(), std::back_inserter(split_args));
-  split_args.push_back('\x00');
-  nacl::string options = GetOptCommandLine(pnacl_options_->opt_level,
-                                           pnacl_options_->is_debug);
-  std::copy(options.begin(), options.end(), std::back_inserter(split_args));
+  GetLlcCommandLine(plugin_,
+                    &split_args,
+                    obj_files_->size(),
+                    pnacl_options_->opt_level,
+                    pnacl_options_->is_debug,
+                    architecture_attributes_);
   init_success = llc_subprocess_->InvokeSrpcMethod(
       "StreamInitWithSplit",
       "ihhhhhhhhhhhhhhhhC",
@@ -350,7 +364,7 @@
     nacl::MutexLocker ml(&subprocess_mu_);
     int64_t ld_start_time = NaClGetTimeOfDayMicroseconds();
     ld_subprocess_.reset(
-      StartSubprocess(resources_->GetLdUrl(), manifest_, &error_info));
+      StartSubprocess(resources_->GetLdUrl(), manifest_id_, &error_info));
     if (ld_subprocess_ == NULL) {
       TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP,
                       "Link process could not be created: " +
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h
index db1dbf0..1032c1e 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h
@@ -28,7 +28,6 @@
 
 namespace plugin {
 
-class Manifest;
 class NaClSubprocess;
 class Plugin;
 class PnaclCoordinator;
@@ -43,13 +42,14 @@
   // Start the translation process. It will continue to run and consume data
   // as it is passed in with PutBytes.
   void RunTranslate(const pp::CompletionCallback& finish_callback,
-                    const Manifest* manifest,
+                    int32_t manifest_id,
                     const std::vector<TempFile*>* obj_files,
                     TempFile* nexe_file,
                     nacl::DescWrapper* invalid_desc_wrapper,
                     ErrorInfo* error_info,
                     PnaclResources* resources,
                     PP_PNaClOptions* pnacl_options,
+                    const nacl::string &architecture_attributes,
                     PnaclCoordinator* coordinator,
                     Plugin* plugin);
 
@@ -69,7 +69,7 @@
  private:
   // Starts an individual llc or ld subprocess used for translation.
   NaClSubprocess* StartSubprocess(const nacl::string& url,
-                                  const Manifest* manifest,
+                                  int32_t manifest_id,
                                   ErrorInfo* error_info);
   // Helper thread entry point for translation. Takes a pointer to
   // PnaclTranslateThread and calls DoTranslate().
@@ -114,13 +114,14 @@
   int64_t compile_time_;
 
   // Data about the translation files, owned by the coordinator
-  const Manifest* manifest_;
+  int32_t manifest_id_;
   const std::vector<TempFile*>* obj_files_;
   TempFile* nexe_file_;
   nacl::DescWrapper* invalid_desc_wrapper_;
   ErrorInfo* coordinator_error_info_;
   PnaclResources* resources_;
   PP_PNaClOptions* pnacl_options_;
+  nacl::string architecture_attributes_;
   PnaclCoordinator* coordinator_;
   Plugin* plugin_;
  private:
diff --git a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc
index bd8ee9e..d27de7e 100644
--- a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc
+++ b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.cc
@@ -27,7 +27,7 @@
     bool enable_dyncode_syscalls,
     bool enable_exception_handling,
     bool enable_crash_throttling,
-    const PP_ManifestService* manifest_service_interface,
+    const PPP_ManifestService* manifest_service_interface,
     void* manifest_service_user_data,
     PP_Var* error_message,
     pp::CompletionCallback callback) {
diff --git a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h
index 50e8848..7ab2339 100644
--- a/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h
+++ b/ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h
@@ -25,7 +25,7 @@
                      bool enable_dyncode_syscalls,
                      bool enable_exception_handling,
                      bool enable_crash_throttling,
-                     const PP_ManifestService* manifest_service_interface,
+                     const PPP_ManifestService* manifest_service_interface,
                      void* manifest_service_user_data,
                      PP_Var* error_message,
                      pp::CompletionCallback callback);
diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
index 131f9ae..c3a7f94 100644
--- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc
+++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
@@ -47,7 +47,6 @@
 #include "ppapi/cpp/core.h"
 #include "ppapi/cpp/completion_callback.h"
 
-#include "ppapi/native_client/src/trusted/plugin/manifest.h"
 #include "ppapi/native_client/src/trusted/plugin/plugin.h"
 #include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
 #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h"
@@ -56,6 +55,42 @@
 #include "ppapi/native_client/src/trusted/weak_ref/call_on_main_thread.h"
 
 namespace plugin {
+
+class OpenManifestEntryAsyncCallback {
+ public:
+  OpenManifestEntryAsyncCallback(PP_OpenResourceCompletionCallback callback,
+                                 void* callback_user_data)
+      : callback_(callback), callback_user_data_(callback_user_data) {
+  }
+
+  ~OpenManifestEntryAsyncCallback() {
+    if (callback_)
+      callback_(callback_user_data_, PP_kInvalidFileHandle);
+  }
+
+  void Run(int32_t pp_error) {
+#if defined(OS_WIN)
+    // Currently, this is used only for non-SFI mode, and now the mode is not
+    // supported on windows.
+    // TODO(hidehiko): Support it on Windows when we switch to use
+    // ManifestService also in SFI-mode.
+    NACL_NOTREACHED();
+#elif defined(OS_POSIX)
+    // On posix, PlatformFile is the file descriptor.
+    callback_(callback_user_data_, (pp_error == PP_OK) ? info_.desc : -1);
+    callback_ = NULL;
+#endif
+  }
+
+  NaClFileInfo* mutable_info() { return &info_; }
+
+ private:
+  NaClFileInfo info_;
+  PP_OpenResourceCompletionCallback callback_;
+  void* callback_user_data_;
+  DISALLOW_COPY_AND_ASSIGN(OpenManifestEntryAsyncCallback);
+};
+
 namespace {
 
 // For doing crude quota enforcement on writes to temp files.
@@ -92,6 +127,25 @@
     return true;
   }
 
+  bool OpenResource(const char* entry_key,
+                    PP_OpenResourceCompletionCallback callback,
+                    void* callback_user_data) {
+    // Release this instance if the ServiceRuntime is already destructed.
+    if (anchor_->is_abandoned()) {
+      callback(callback_user_data, PP_kInvalidFileHandle);
+      delete this;
+      return false;
+    }
+
+    OpenManifestEntryAsyncCallback* open_manifest_callback =
+        new OpenManifestEntryAsyncCallback(callback, callback_user_data);
+    plugin_reverse_->OpenManifestEntryAsync(
+        entry_key,
+        open_manifest_callback->mutable_info(),
+        open_manifest_callback);
+    return true;
+  }
+
   static PP_Bool QuitTrampoline(void* user_data) {
     return PP_FromBool(static_cast<ManifestService*>(user_data)->Quit());
   }
@@ -101,6 +155,15 @@
                        StartupInitializationComplete());
   }
 
+  static PP_Bool OpenResourceTrampoline(
+      void* user_data,
+      const char* entry_key,
+      PP_OpenResourceCompletionCallback callback,
+      void* callback_user_data) {
+    return PP_FromBool(static_cast<ManifestService*>(user_data)->OpenResource(
+        entry_key, callback, callback_user_data));
+  }
+
  private:
   // Weak reference to check if plugin_reverse is legally accessible or not.
   nacl::WeakRefAnchor* anchor_;
@@ -110,23 +173,37 @@
 };
 
 // Vtable to pass functions to LaunchSelLdr.
-const PP_ManifestService kManifestServiceVTable = {
+const PPP_ManifestService kManifestServiceVTable = {
   &ManifestService::QuitTrampoline,
   &ManifestService::StartupInitializationCompleteTrampoline,
+  &ManifestService::OpenResourceTrampoline,
 };
 
 }  // namespace
 
+OpenManifestEntryResource::~OpenManifestEntryResource() {
+  MaybeRunCallback(PP_ERROR_ABORTED);
+}
+
+void OpenManifestEntryResource::MaybeRunCallback(int32_t pp_error) {
+  if (!callback)
+    return;
+
+  callback->Run(pp_error);
+  delete callback;
+  callback = NULL;
+}
+
 PluginReverseInterface::PluginReverseInterface(
     nacl::WeakRefAnchor* anchor,
     Plugin* plugin,
-    const Manifest* manifest,
+    int32_t manifest_id,
     ServiceRuntime* service_runtime,
     pp::CompletionCallback init_done_cb,
     pp::CompletionCallback crash_cb)
       : anchor_(anchor),
         plugin_(plugin),
-        manifest_(manifest),
+        manifest_id_(manifest_id),
         service_runtime_(service_runtime),
         shutting_down_(false),
         init_done_cb_(init_done_cb),
@@ -195,7 +272,7 @@
   // the main thread before this function can return. The pointers it contains
   // to stack variables will not leak.
   OpenManifestEntryResource* to_open =
-      new OpenManifestEntryResource(url_key, info, &op_complete);
+      new OpenManifestEntryResource(url_key, info, &op_complete, NULL);
   CHECK(to_open != NULL);
   NaClLog(4, "PluginReverseInterface::OpenManifestEntry: %s\n",
           url_key.c_str());
@@ -245,6 +322,16 @@
   return true;
 }
 
+void PluginReverseInterface::OpenManifestEntryAsync(
+    const nacl::string& entry_key,
+    struct NaClFileInfo* info,
+    OpenManifestEntryAsyncCallback* callback) {
+  bool op_complete = false;
+  OpenManifestEntryResource to_open(
+      entry_key, info, &op_complete, callback);
+  OpenManifestEntry_MainThreadContinuation(&to_open, PP_OK);
+}
+
 // Transfer point from OpenManifestEntry() which runs on the main thread
 // (Some PPAPI actions -- like StreamAsFile -- can only run on the main thread).
 // OpenManifestEntry() is waiting on a condvar for this continuation to
@@ -259,24 +346,26 @@
 
   NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n");
 
-  std::string mapped_url;
+  PP_Var pp_mapped_url;
   PP_PNaClOptions pnacl_options = {PP_FALSE, PP_FALSE, 2};
-  ErrorInfo error_info;
-  if (!manifest_->ResolveKey(p->url, &mapped_url,
-                             &pnacl_options, &error_info)) {
+  if (!GetNaClInterface()->ManifestResolveKey(plugin_->pp_instance(),
+                                              manifest_id_,
+                                              p->url.c_str(),
+                                              &pp_mapped_url,
+                                              &pnacl_options)) {
     NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n");
-    NaClLog(4,
-            "Error code %d, string %s\n",
-            error_info.error_code(),
-            error_info.message().c_str());
     // Failed, and error_info has the details on what happened.  Wake
     // up requesting thread -- we are done.
-    nacl::MutexLocker take(&mu_);
-    *p->op_complete_ptr = true;  // done...
-    p->file_info->desc = -1;  // but failed.
-    NaClXCondVarBroadcast(&cv_);
+    {
+      nacl::MutexLocker take(&mu_);
+      *p->op_complete_ptr = true;  // done...
+      p->file_info->desc = -1;  // but failed.
+      NaClXCondVarBroadcast(&cv_);
+    }
+    p->MaybeRunCallback(PP_OK);
     return;
   }
+  nacl::string mapped_url = pp::Var(pp_mapped_url).AsString();
   NaClLog(4,
           "OpenManifestEntry_MainThreadContinuation: "
           "ResolveKey: %s -> %s (pnacl_translate(%d))\n",
@@ -287,10 +376,13 @@
     NaClLog(4,
             "OpenManifestEntry_MainThreadContinuation: "
             "Requires PNaCl translation -- not supported\n");
-    nacl::MutexLocker take(&mu_);
-    *p->op_complete_ptr = true;  // done...
-    p->file_info->desc = -1;  // but failed.
-    NaClXCondVarBroadcast(&cv_);
+    {
+      nacl::MutexLocker take(&mu_);
+      *p->op_complete_ptr = true;  // done...
+      p->file_info->desc = -1;  // but failed.
+      NaClXCondVarBroadcast(&cv_);
+    }
+    p->MaybeRunCallback(PP_OK);
     return;
   }
 
@@ -308,14 +400,17 @@
               "OpenManifestEntry_MainThreadContinuation: "
               "GetReadonlyPnaclFd failed\n");
     }
-    nacl::MutexLocker take(&mu_);
-    *p->op_complete_ptr = true;  // done!
-    // TODO(ncbray): enable the fast loading and validation paths for this
-    // type of file.
-    p->file_info->desc = fd;
-    NaClXCondVarBroadcast(&cv_);
+    {
+      nacl::MutexLocker take(&mu_);
+      *p->op_complete_ptr = true;  // done!
+      // TODO(ncbray): enable the fast loading and validation paths for this
+      // type of file.
+      p->file_info->desc = fd;
+      NaClXCondVarBroadcast(&cv_);
+    }
     NaClLog(4,
             "OpenManifestEntry_MainThreadContinuation: GetPnaclFd okay\n");
+    p->MaybeRunCallback(PP_OK);
     return;
   }
 
@@ -325,6 +420,9 @@
   // to create another instance.
   OpenManifestEntryResource* open_cont = new OpenManifestEntryResource(*p);
   open_cont->url = mapped_url;
+  // Callback is now delegated from p to open_cont. So, here we manually clear
+  // complete callback.
+  p->callback = NULL;
   pp::CompletionCallback stream_cc = WeakRefNewCallback(
       anchor_,
       this,
@@ -352,22 +450,26 @@
   NaClLog(4,
           "Entered StreamAsFile_MainThreadContinuation\n");
 
-  nacl::MutexLocker take(&mu_);
-  if (result == PP_OK) {
-    NaClLog(4, "StreamAsFile_MainThreadContinuation: GetFileInfo(%s)\n",
-            p->url.c_str());
-    *p->file_info = plugin_->GetFileInfo(p->url);
+  {
+    nacl::MutexLocker take(&mu_);
+    if (result == PP_OK) {
+      NaClLog(4, "StreamAsFile_MainThreadContinuation: GetFileInfo(%s)\n",
+              p->url.c_str());
+      *p->file_info = plugin_->GetFileInfo(p->url);
 
-    NaClLog(4,
-            "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n",
-            p->file_info->desc);
-  } else {
-    NaClLog(4,
-            "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n");
-    p->file_info->desc = -1;
+      NaClLog(4,
+              "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n",
+              p->file_info->desc);
+    } else {
+      NaClLog(
+          4,
+          "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n");
+      p->file_info->desc = -1;
+    }
+    *p->op_complete_ptr = true;
+    NaClXCondVarBroadcast(&cv_);
   }
-  *p->op_complete_ptr = true;
-  NaClXCondVarBroadcast(&cv_);
+  p->MaybeRunCallback(PP_OK);
 }
 
 bool PluginReverseInterface::CloseManifestEntry(int32_t desc) {
@@ -462,7 +564,7 @@
 }
 
 ServiceRuntime::ServiceRuntime(Plugin* plugin,
-                               const Manifest* manifest,
+                               int32_t manifest_id,
                                bool main_service_runtime,
                                bool uses_nonsfi_mode,
                                pp::CompletionCallback init_done_cb,
@@ -473,7 +575,7 @@
       reverse_service_(NULL),
       anchor_(new nacl::WeakRefAnchor()),
       rev_interface_(new PluginReverseInterface(anchor_, plugin,
-                                                manifest,
+                                                manifest_id,
                                                 this,
                                                 init_done_cb, crash_cb)),
       exit_status_(-1),
diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.h b/ppapi/native_client/src/trusted/plugin/service_runtime.h
index 07850d4..74dc68d 100644
--- a/ppapi/native_client/src/trusted/plugin/service_runtime.h
+++ b/ppapi/native_client/src/trusted/plugin/service_runtime.h
@@ -40,7 +40,7 @@
 namespace plugin {
 
 class ErrorInfo;
-class Manifest;
+class OpenManifestEntryAsyncCallback;
 class Plugin;
 class SrpcClient;
 class ServiceRuntime;
@@ -87,13 +87,19 @@
  public:
   OpenManifestEntryResource(const std::string& target_url,
                             struct NaClFileInfo* finfo,
-                            bool* op_complete)
+                            bool* op_complete,
+                            OpenManifestEntryAsyncCallback* callback)
       : url(target_url),
         file_info(finfo),
-        op_complete_ptr(op_complete) {}
+        op_complete_ptr(op_complete),
+        callback(callback) {}
+  ~OpenManifestEntryResource();
+  void MaybeRunCallback(int32_t pp_error);
+
   std::string url;
   struct NaClFileInfo* file_info;
   bool* op_complete_ptr;
+  OpenManifestEntryAsyncCallback* callback;
 };
 
 struct CloseManifestEntryResource {
@@ -140,7 +146,7 @@
  public:
   PluginReverseInterface(nacl::WeakRefAnchor* anchor,
                          Plugin* plugin,
-                         const Manifest* manifest,
+                         int32_t manifest_id,
                          ServiceRuntime* service_runtime,
                          pp::CompletionCallback init_done_cb,
                          pp::CompletionCallback crash_cb);
@@ -170,6 +176,15 @@
                            const pp::FileIO& file_io);
   void AddTempQuotaManagedFile(const nacl::string& file_id);
 
+  // This is a sibling of OpenManifestEntry. While OpenManifestEntry is
+  // a sync function and must be called on a non-main thread,
+  // OpenManifestEntryAsync must be called on the main thread. Upon completion
+  // (even on error), callback will be invoked. The caller has responsibility
+  // to keep the memory passed to info until callback is invoked.
+  void OpenManifestEntryAsync(const nacl::string& key,
+                              struct NaClFileInfo* info,
+                              OpenManifestEntryAsyncCallback* callback);
+
  protected:
   virtual void PostMessage_MainThreadContinuation(PostMessageResource* p,
                                                   int32_t err);
@@ -190,7 +205,7 @@
   nacl::WeakRefAnchor* anchor_;  // holds a ref
   Plugin* plugin_;  // value may be copied, but should be used only in
                     // main thread in WeakRef-protected callbacks.
-  const Manifest* manifest_;
+  int32_t manifest_id_;
   ServiceRuntime* service_runtime_;
   NaClMutex mu_;
   NaClCondVar cv_;
@@ -207,7 +222,7 @@
   // TODO(sehr): This class should also implement factory methods, using the
   // Start method below.
   ServiceRuntime(Plugin* plugin,
-                 const Manifest* manifest,
+                 int32_t manifest_id,
                  bool main_service_runtime,
                  bool uses_nonsfi_mode,
                  pp::CompletionCallback init_done_cb,
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp
index 1dae487..d3d5f2a 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp
@@ -9,7 +9,10 @@
   'targets': [
     {
       # The full library, which PNaCl uses for offline .pexe -> .nexe.
-      'target_name': 'pnacl_irt_shim_aot',
+      # We keep the target names in this file short to avoid having really long
+      # path names on Windows.
+      # https://code.google.com/p/nativeclient/issues/detail?id=3846
+      'target_name': 'shim_aot',
       'type': 'none',
       'variables': {
         'nlib_target': 'libpnacl_irt_shim.a',
@@ -50,10 +53,10 @@
     # If we ever change that hook interface or change the in-IRT shim's ABI,
     # we would need to clear the translation cache to match the new IRT.
     {
-      'target_name': 'pnacl_irt_shim_browser',
+      'target_name': 'shim_browser',
       'type': 'none',
       'variables': {
-        # Same name as pnacl_irt_shim_aot, so that we don't need to change
+        # Same output file name as shim_aot, so that we don't need to change
         # the linker commandlines, but output to the "for_browser" directory,
         # and have the pnacl_support_extension copy from that directory.
         'nlib_target': 'libpnacl_irt_shim.a',
@@ -85,7 +88,7 @@
       # Second half of shim library for PNaCl in-browser translation.
       # This half goes into the IRT and is returned by the unstable
       # IRT hook interface.
-      'target_name': 'pnacl_irt_shim_for_irt',
+      'target_name': 'shim_for_irt',
       'type': 'none',
       'variables': {
         'nlib_target': 'libpnacl_irt_shim_for_irt.a',
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
index 59535b4..c217676 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
@@ -48,6 +48,7 @@
 #include "ppapi/c/ppb_var_array.h"
 #include "ppapi/c/ppb_var_array_buffer.h"
 #include "ppapi/c/ppb_var_dictionary.h"
+#include "ppapi/c/ppb_video_decoder.h"
 #include "ppapi/c/ppb_websocket.h"
 #include "ppapi/c/ppp_messaging.h"
 #include "ppapi/c/private/ppb_content_decryptor_private.h"
@@ -115,6 +116,7 @@
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_IMEInputEvent_1_0;
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MediaStreamAudioTrack_0_1;
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_0_1;
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0;
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MessageLoop_1_0;
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Messaging_1_0;
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MouseLock_1_0;
@@ -135,6 +137,7 @@
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VarArray_1_0;
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VarArrayBuffer_1_0;
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VarDictionary_1_0;
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoDecoder_0_1;
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_WebSocket_1_0;
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_Messaging_1_0;
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Alarms_Dev_0_1;
@@ -1075,6 +1078,65 @@
 
 /* End wrapper methods for PPB_MediaStreamVideoTrack_0_1 */
 
+/* Begin wrapper methods for PPB_MediaStreamVideoTrack_1_0 */
+
+static PP_Resource Pnacl_M36_PPB_MediaStreamVideoTrack_Create(PP_Instance instance) {
+  const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface;
+  return iface->Create(instance);
+}
+
+static PP_Bool Pnacl_M36_PPB_MediaStreamVideoTrack_IsMediaStreamVideoTrack(PP_Resource resource) {
+  const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface;
+  return iface->IsMediaStreamVideoTrack(resource);
+}
+
+static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_Configure(PP_Resource video_track, const int32_t attrib_list[], struct PP_CompletionCallback* callback) {
+  const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface;
+  return iface->Configure(video_track, attrib_list, *callback);
+}
+
+static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_GetAttrib(PP_Resource video_track, PP_MediaStreamVideoTrack_Attrib attrib, int32_t* value) {
+  const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface;
+  return iface->GetAttrib(video_track, attrib, value);
+}
+
+static void Pnacl_M36_PPB_MediaStreamVideoTrack_GetId(struct PP_Var* _struct_result, PP_Resource video_track) {
+  const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface;
+  *_struct_result = iface->GetId(video_track);
+}
+
+static PP_Bool Pnacl_M36_PPB_MediaStreamVideoTrack_HasEnded(PP_Resource video_track) {
+  const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface;
+  return iface->HasEnded(video_track);
+}
+
+static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_GetFrame(PP_Resource video_track, PP_Resource* frame, struct PP_CompletionCallback* callback) {
+  const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface;
+  return iface->GetFrame(video_track, frame, *callback);
+}
+
+static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_RecycleFrame(PP_Resource video_track, PP_Resource frame) {
+  const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface;
+  return iface->RecycleFrame(video_track, frame);
+}
+
+static void Pnacl_M36_PPB_MediaStreamVideoTrack_Close(PP_Resource video_track) {
+  const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface;
+  iface->Close(video_track);
+}
+
+static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_GetEmptyFrame(PP_Resource video_track, PP_Resource* frame, struct PP_CompletionCallback* callback) {
+  const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface;
+  return iface->GetEmptyFrame(video_track, frame, *callback);
+}
+
+static int32_t Pnacl_M36_PPB_MediaStreamVideoTrack_PutFrame(PP_Resource video_track, PP_Resource frame) {
+  const struct PPB_MediaStreamVideoTrack_1_0 *iface = Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0.real_iface;
+  return iface->PutFrame(video_track, frame);
+}
+
+/* End wrapper methods for PPB_MediaStreamVideoTrack_1_0 */
+
 /* Begin wrapper methods for PPB_MessageLoop_1_0 */
 
 static PP_Resource Pnacl_M25_PPB_MessageLoop_Create(PP_Instance instance) {
@@ -1702,6 +1764,50 @@
 
 /* End wrapper methods for PPB_VarDictionary_1_0 */
 
+/* Begin wrapper methods for PPB_VideoDecoder_0_1 */
+
+static PP_Resource Pnacl_M36_PPB_VideoDecoder_Create(PP_Instance instance) {
+  const struct PPB_VideoDecoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDecoder_0_1.real_iface;
+  return iface->Create(instance);
+}
+
+static PP_Bool Pnacl_M36_PPB_VideoDecoder_IsVideoDecoder(PP_Resource resource) {
+  const struct PPB_VideoDecoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDecoder_0_1.real_iface;
+  return iface->IsVideoDecoder(resource);
+}
+
+static int32_t Pnacl_M36_PPB_VideoDecoder_Initialize(PP_Resource video_decoder, PP_Resource graphics3d_context, PP_VideoProfile profile, PP_Bool allow_software_fallback, struct PP_CompletionCallback* callback) {
+  const struct PPB_VideoDecoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDecoder_0_1.real_iface;
+  return iface->Initialize(video_decoder, graphics3d_context, profile, allow_software_fallback, *callback);
+}
+
+static int32_t Pnacl_M36_PPB_VideoDecoder_Decode(PP_Resource video_decoder, uint32_t decode_id, uint32_t size, const void* buffer, struct PP_CompletionCallback* callback) {
+  const struct PPB_VideoDecoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDecoder_0_1.real_iface;
+  return iface->Decode(video_decoder, decode_id, size, buffer, *callback);
+}
+
+static int32_t Pnacl_M36_PPB_VideoDecoder_GetPicture(PP_Resource video_decoder, struct PP_VideoPicture* picture, struct PP_CompletionCallback* callback) {
+  const struct PPB_VideoDecoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDecoder_0_1.real_iface;
+  return iface->GetPicture(video_decoder, picture, *callback);
+}
+
+static void Pnacl_M36_PPB_VideoDecoder_RecyclePicture(PP_Resource video_decoder, const struct PP_VideoPicture* picture) {
+  const struct PPB_VideoDecoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDecoder_0_1.real_iface;
+  iface->RecyclePicture(video_decoder, picture);
+}
+
+static int32_t Pnacl_M36_PPB_VideoDecoder_Flush(PP_Resource video_decoder, struct PP_CompletionCallback* callback) {
+  const struct PPB_VideoDecoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDecoder_0_1.real_iface;
+  return iface->Flush(video_decoder, *callback);
+}
+
+static int32_t Pnacl_M36_PPB_VideoDecoder_Reset(PP_Resource video_decoder, struct PP_CompletionCallback* callback) {
+  const struct PPB_VideoDecoder_0_1 *iface = Pnacl_WrapperInfo_PPB_VideoDecoder_0_1.real_iface;
+  return iface->Reset(video_decoder, *callback);
+}
+
+/* End wrapper methods for PPB_VideoDecoder_0_1 */
+
 /* Not generating wrapper methods for PPB_VideoFrame_0_1 */
 
 /* Not generating wrapper methods for PPB_View_1_0 */
@@ -3082,11 +3188,11 @@
 
 /* End wrapper methods for PPB_IsolatedFileSystem_Private_0_2 */
 
-/* Not generating wrapper methods for PP_ManifestService_1_0 */
+/* Not generating wrapper methods for PPP_ManifestService_1_0 */
 
 /* Begin wrapper methods for PPB_NaCl_Private_1_0 */
 
-static void Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, const struct PP_ManifestService_1_0* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback* callback) {
+static void Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, const struct PPP_ManifestService_1_0* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback* callback) {
   const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
   iface->LaunchSelLdr(instance, alleged_url, uses_irt, uses_ppapi, uses_nonsfi_mode, enable_ppapi_dev, enable_dyncode_syscalls, enable_exception_handling, enable_crash_throttling, manifest_service_interface, manifest_service_user_data, imc_handle, error_message, *callback);
 }
@@ -3276,6 +3382,46 @@
   return iface->DevInterfacesEnabled(instance);
 }
 
+static void Pnacl_M25_PPB_NaCl_Private_DownloadManifestToBuffer(PP_Instance instance, struct PP_Var* data, struct PP_CompletionCallback* callback) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  iface->DownloadManifestToBuffer(instance, data, *callback);
+}
+
+static int32_t Pnacl_M25_PPB_NaCl_Private_CreatePnaclManifest(PP_Instance instance) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  return iface->CreatePnaclManifest(instance);
+}
+
+static int32_t Pnacl_M25_PPB_NaCl_Private_CreateJsonManifest(PP_Instance instance, const char* manifest_base_url, const char* sandbox_isa, const char* manifest_data) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  return iface->CreateJsonManifest(instance, manifest_base_url, sandbox_isa, manifest_data);
+}
+
+static void Pnacl_M25_PPB_NaCl_Private_DestroyManifest(PP_Instance instance, int32_t manifest_id) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  iface->DestroyManifest(instance, manifest_id);
+}
+
+static PP_Bool Pnacl_M25_PPB_NaCl_Private_GetManifestProgramURL(PP_Instance instance, int32_t manifest_id, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options, PP_Bool* uses_nonsfi_mode) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  return iface->GetManifestProgramURL(instance, manifest_id, full_url, pnacl_options, uses_nonsfi_mode);
+}
+
+static PP_Bool Pnacl_M25_PPB_NaCl_Private_ManifestResolveKey(PP_Instance instance, int32_t manifest_id, const char* key, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  return iface->ManifestResolveKey(instance, manifest_id, key, full_url, pnacl_options);
+}
+
+static PP_Bool Pnacl_M25_PPB_NaCl_Private_GetPnaclResourceInfo(PP_Instance instance, const char* filename, struct PP_Var* llc_tool_name, struct PP_Var* ld_tool_name) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  return iface->GetPnaclResourceInfo(instance, filename, llc_tool_name, ld_tool_name);
+}
+
+static void Pnacl_M25_PPB_NaCl_Private_GetCpuFeatureAttrs(struct PP_Var* _struct_result) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  *_struct_result = iface->GetCpuFeatureAttrs();
+}
+
 /* End wrapper methods for PPB_NaCl_Private_1_0 */
 
 /* Begin wrapper methods for PPB_NetAddress_Private_0_1 */
@@ -4370,6 +4516,20 @@
     .Close = (void (*)(PP_Resource video_track))&Pnacl_M35_PPB_MediaStreamVideoTrack_Close
 };
 
+static const struct PPB_MediaStreamVideoTrack_1_0 Pnacl_Wrappers_PPB_MediaStreamVideoTrack_1_0 = {
+    .Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M36_PPB_MediaStreamVideoTrack_Create,
+    .IsMediaStreamVideoTrack = (PP_Bool (*)(PP_Resource resource))&Pnacl_M36_PPB_MediaStreamVideoTrack_IsMediaStreamVideoTrack,
+    .Configure = (int32_t (*)(PP_Resource video_track, const int32_t attrib_list[], struct PP_CompletionCallback callback))&Pnacl_M36_PPB_MediaStreamVideoTrack_Configure,
+    .GetAttrib = (int32_t (*)(PP_Resource video_track, PP_MediaStreamVideoTrack_Attrib attrib, int32_t* value))&Pnacl_M36_PPB_MediaStreamVideoTrack_GetAttrib,
+    .GetId = (struct PP_Var (*)(PP_Resource video_track))&Pnacl_M36_PPB_MediaStreamVideoTrack_GetId,
+    .HasEnded = (PP_Bool (*)(PP_Resource video_track))&Pnacl_M36_PPB_MediaStreamVideoTrack_HasEnded,
+    .GetFrame = (int32_t (*)(PP_Resource video_track, PP_Resource* frame, struct PP_CompletionCallback callback))&Pnacl_M36_PPB_MediaStreamVideoTrack_GetFrame,
+    .RecycleFrame = (int32_t (*)(PP_Resource video_track, PP_Resource frame))&Pnacl_M36_PPB_MediaStreamVideoTrack_RecycleFrame,
+    .Close = (void (*)(PP_Resource video_track))&Pnacl_M36_PPB_MediaStreamVideoTrack_Close,
+    .GetEmptyFrame = (int32_t (*)(PP_Resource video_track, PP_Resource* frame, struct PP_CompletionCallback callback))&Pnacl_M36_PPB_MediaStreamVideoTrack_GetEmptyFrame,
+    .PutFrame = (int32_t (*)(PP_Resource video_track, PP_Resource frame))&Pnacl_M36_PPB_MediaStreamVideoTrack_PutFrame
+};
+
 static const struct PPB_MessageLoop_1_0 Pnacl_Wrappers_PPB_MessageLoop_1_0 = {
     .Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M25_PPB_MessageLoop_Create,
     .GetForMainThread = (PP_Resource (*)(void))&Pnacl_M25_PPB_MessageLoop_GetForMainThread,
@@ -4541,6 +4701,17 @@
     .GetKeys = (struct PP_Var (*)(struct PP_Var dict))&Pnacl_M29_PPB_VarDictionary_GetKeys
 };
 
+static const struct PPB_VideoDecoder_0_1 Pnacl_Wrappers_PPB_VideoDecoder_0_1 = {
+    .Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M36_PPB_VideoDecoder_Create,
+    .IsVideoDecoder = (PP_Bool (*)(PP_Resource resource))&Pnacl_M36_PPB_VideoDecoder_IsVideoDecoder,
+    .Initialize = (int32_t (*)(PP_Resource video_decoder, PP_Resource graphics3d_context, PP_VideoProfile profile, PP_Bool allow_software_fallback, struct PP_CompletionCallback callback))&Pnacl_M36_PPB_VideoDecoder_Initialize,
+    .Decode = (int32_t (*)(PP_Resource video_decoder, uint32_t decode_id, uint32_t size, const void* buffer, struct PP_CompletionCallback callback))&Pnacl_M36_PPB_VideoDecoder_Decode,
+    .GetPicture = (int32_t (*)(PP_Resource video_decoder, struct PP_VideoPicture* picture, struct PP_CompletionCallback callback))&Pnacl_M36_PPB_VideoDecoder_GetPicture,
+    .RecyclePicture = (void (*)(PP_Resource video_decoder, const struct PP_VideoPicture* picture))&Pnacl_M36_PPB_VideoDecoder_RecyclePicture,
+    .Flush = (int32_t (*)(PP_Resource video_decoder, struct PP_CompletionCallback callback))&Pnacl_M36_PPB_VideoDecoder_Flush,
+    .Reset = (int32_t (*)(PP_Resource video_decoder, struct PP_CompletionCallback callback))&Pnacl_M36_PPB_VideoDecoder_Reset
+};
+
 /* Not generating wrapper interface for PPB_VideoFrame_0_1 */
 
 /* Not generating wrapper interface for PPB_View_1_0 */
@@ -4966,10 +5137,10 @@
     .Open = (int32_t (*)(PP_Instance instance, PP_IsolatedFileSystemType_Private type, PP_Resource* file_system, struct PP_CompletionCallback callback))&Pnacl_M33_PPB_IsolatedFileSystem_Private_Open
 };
 
-/* Not generating wrapper interface for PP_ManifestService_1_0 */
+/* Not generating wrapper interface for PPP_ManifestService_1_0 */
 
 static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = {
-    .LaunchSelLdr = (void (*)(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, const struct PP_ManifestService_1_0* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr,
+    .LaunchSelLdr = (void (*)(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, const struct PPP_ManifestService_1_0* manifest_service_interface, void* manifest_service_user_data, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr,
     .StartPpapiProxy = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_StartPpapiProxy,
     .UrandomFD = (int32_t (*)(void))&Pnacl_M25_PPB_NaCl_Private_UrandomFD,
     .Are3DInterfacesDisabled = (PP_Bool (*)(void))&Pnacl_M25_PPB_NaCl_Private_Are3DInterfacesDisabled,
@@ -5006,7 +5177,15 @@
     .ProcessNaClManifest = (void (*)(PP_Instance instance, const char* program_url))&Pnacl_M25_PPB_NaCl_Private_ProcessNaClManifest,
     .GetManifestURLArgument = (struct PP_Var (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetManifestURLArgument,
     .IsPNaCl = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_IsPNaCl,
-    .DevInterfacesEnabled = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_DevInterfacesEnabled
+    .DevInterfacesEnabled = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_DevInterfacesEnabled,
+    .DownloadManifestToBuffer = (void (*)(PP_Instance instance, struct PP_Var* data, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_DownloadManifestToBuffer,
+    .CreatePnaclManifest = (int32_t (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_CreatePnaclManifest,
+    .CreateJsonManifest = (int32_t (*)(PP_Instance instance, const char* manifest_base_url, const char* sandbox_isa, const char* manifest_data))&Pnacl_M25_PPB_NaCl_Private_CreateJsonManifest,
+    .DestroyManifest = (void (*)(PP_Instance instance, int32_t manifest_id))&Pnacl_M25_PPB_NaCl_Private_DestroyManifest,
+    .GetManifestProgramURL = (PP_Bool (*)(PP_Instance instance, int32_t manifest_id, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options, PP_Bool* uses_nonsfi_mode))&Pnacl_M25_PPB_NaCl_Private_GetManifestProgramURL,
+    .ManifestResolveKey = (PP_Bool (*)(PP_Instance instance, int32_t manifest_id, const char* key, struct PP_Var* full_url, struct PP_PNaClOptions* pnacl_options))&Pnacl_M25_PPB_NaCl_Private_ManifestResolveKey,
+    .GetPnaclResourceInfo = (PP_Bool (*)(PP_Instance instance, const char* filename, struct PP_Var* llc_tool_name, struct PP_Var* ld_tool_name))&Pnacl_M25_PPB_NaCl_Private_GetPnaclResourceInfo,
+    .GetCpuFeatureAttrs = (struct PP_Var (*)(void))&Pnacl_M25_PPB_NaCl_Private_GetCpuFeatureAttrs
 };
 
 static const struct PPB_NetAddress_Private_0_1 Pnacl_Wrappers_PPB_NetAddress_Private_0_1 = {
@@ -5361,6 +5540,12 @@
   .real_iface = NULL
 };
 
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0 = {
+  .iface_macro = PPB_MEDIASTREAMVIDEOTRACK_INTERFACE_1_0,
+  .wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_MediaStreamVideoTrack_1_0,
+  .real_iface = NULL
+};
+
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_MessageLoop_1_0 = {
   .iface_macro = PPB_MESSAGELOOP_INTERFACE_1_0,
   .wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_MessageLoop_1_0,
@@ -5481,6 +5666,12 @@
   .real_iface = NULL
 };
 
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoDecoder_0_1 = {
+  .iface_macro = PPB_VIDEODECODER_INTERFACE_0_1,
+  .wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_VideoDecoder_0_1,
+  .real_iface = NULL
+};
+
 static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_WebSocket_1_0 = {
   .iface_macro = PPB_WEBSOCKET_INTERFACE_1_0,
   .wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_WebSocket_1_0,
@@ -5864,6 +6055,7 @@
   &Pnacl_WrapperInfo_PPB_IMEInputEvent_1_0,
   &Pnacl_WrapperInfo_PPB_MediaStreamAudioTrack_0_1,
   &Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_0_1,
+  &Pnacl_WrapperInfo_PPB_MediaStreamVideoTrack_1_0,
   &Pnacl_WrapperInfo_PPB_MessageLoop_1_0,
   &Pnacl_WrapperInfo_PPB_Messaging_1_0,
   &Pnacl_WrapperInfo_PPB_MouseLock_1_0,
@@ -5884,6 +6076,7 @@
   &Pnacl_WrapperInfo_PPB_VarArray_1_0,
   &Pnacl_WrapperInfo_PPB_VarArrayBuffer_1_0,
   &Pnacl_WrapperInfo_PPB_VarDictionary_1_0,
+  &Pnacl_WrapperInfo_PPB_VideoDecoder_0_1,
   &Pnacl_WrapperInfo_PPB_WebSocket_1_0,
   &Pnacl_WrapperInfo_PPB_Alarms_Dev_0_1,
   &Pnacl_WrapperInfo_PPB_AudioInput_Dev_0_3,
diff --git a/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_component_crx_gen.py b/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_component_crx_gen.py
index db0a143..bdc6cbf 100755
--- a/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_component_crx_gen.py
+++ b/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_component_crx_gen.py
@@ -18,6 +18,7 @@
 import platform
 import re
 import shutil
+import subprocess
 import sys
 
 J = os.path.join
@@ -63,34 +64,6 @@
 
 ######################################################################
 
-def GetNaClRoot():
-  """ Find the native_client path, relative to this script.
-      This script is in ppapi/... and native_client is a sibling of ppapi.
-  """
-  script_file = os.path.abspath(__file__)
-  def SearchForNaCl(cur_dir):
-    if cur_dir.endswith('ppapi'):
-      parent = os.path.dirname(cur_dir)
-      sibling = os.path.join(parent, 'native_client')
-      if not os.path.isdir(sibling):
-        raise Exception('Could not find native_client relative to %s' %
-                        script_file)
-      return sibling
-    # Detect when we've the root (linux is /, but windows is not...)
-    next_dir = os.path.dirname(cur_dir)
-    if cur_dir == next_dir:
-      raise Exception('Could not find native_client relative to %s' %
-                      script_file)
-    return SearchForNaCl(next_dir)
-
-  return SearchForNaCl(script_file)
-
-
-NACL_ROOT = GetNaClRoot()
-
-
-######################################################################
-
 # Normalize the platform name to be the way SCons finds chrome binaries.
 # This is based on the platform "building" the extension.
 
@@ -130,7 +103,8 @@
 
   # File paths that are set from the command line.
   pnacl_template = None
-  tool_revisions = None
+  package_version_path = None
+  pnacl_package = 'pnacl_newlib'
 
   # Agreed-upon name for pnacl-specific info.
   pnacl_json = 'pnacl.json'
@@ -140,25 +114,29 @@
     PnaclPackaging.pnacl_template = path
 
   @staticmethod
-  def SetToolsRevisionPath(path):
-    PnaclPackaging.tool_revisions = path
+  def SetPackageVersionPath(path):
+    PnaclPackaging.package_version_path = path
+
+  @staticmethod
+  def SetPnaclPackageName(name):
+    PnaclPackaging.pnacl_package = name
 
   @staticmethod
   def PnaclToolsRevision():
-    with open(PnaclPackaging.tool_revisions, 'r') as f:
-      for line in f.read().splitlines():
-        if line.startswith('PNACL_VERSION'):
-          _, version = line.split('=')
-          # CWS happens to use version quads, so make it a quad too.
-          # However, each component of the quad is limited to 64K max.
-          # Try to handle a bit more.
-          max_version = 2 ** 16
-          version = int(version)
-          version_more = version / max_version
-          version = version % max_version
-          return '0.1.%d.%d' % (version_more, version)
-    raise Exception('Cannot find PNACL_VERSION in TOOL_REVISIONS file: %s' %
-                    PnaclPackaging.tool_revisions)
+    pkg_ver_cmd = [sys.executable, PnaclPackaging.package_version_path,
+                   'getrevision',
+                   '--revision-package', PnaclPackaging.pnacl_package]
+
+    version = subprocess.check_output(pkg_ver_cmd).strip()
+
+    # CWS happens to use version quads, so make it a quad too.
+    # However, each component of the quad is limited to 64K max.
+    # Try to handle a bit more.
+    max_version = 2 ** 16
+    version = int(version)
+    version_more = version / max_version
+    version = version % max_version
+    return '0.1.%d.%d' % (version_more, version)
 
   @staticmethod
   def GeneratePnaclInfo(target_dir, abi_version, arch):
@@ -334,8 +312,10 @@
   parser.add_option('--info_template_path',
                     dest='info_template_path', default=None,
                     help='Path of the info template file')
-  parser.add_option('--tool_revisions_path', dest='tool_revisions_path',
-                    default=None, help='Location of NaCl TOOL_REVISIONS file.')
+  parser.add_option('--package_version_path', dest='package_version_path',
+                    default=None, help='Path to package_version.py script.')
+  parser.add_option('--pnacl_package_name', dest='pnacl_package_name',
+                    default=None, help='Name of PNaCl package.')
   parser.add_option('--pnacl_translator_path', dest='pnacl_translator_path',
                     default=None, help='Location of PNaCl translator.')
   parser.add_option('-v', '--verbose', dest='verbose', default=False,
@@ -365,8 +345,13 @@
   if options.info_template_path:
     PnaclPackaging.SetPnaclInfoTemplatePath(options.info_template_path)
 
-  if options.tool_revisions_path:
-    PnaclPackaging.SetToolsRevisionPath(options.tool_revisions_path)
+  if options.package_version_path:
+    PnaclPackaging.SetPackageVersionPath(options.package_version_path)
+  else:
+    raise Exception('Package verison script must be specified.')
+
+  if options.pnacl_package_name:
+    PnaclPackaging.SetPnaclPackageName(options.pnacl_package_name)
 
   lib_overrides = {}
   for o in options.lib_overrides:
diff --git a/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp b/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp
index af1dec1..d4ede90 100644
--- a/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp
+++ b/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp
@@ -16,19 +16,17 @@
       'action_name': 'Untar pnacl_translator',
       'description': 'Untar pnacl_translator',
       'inputs': [
-        '<(DEPTH)/native_client/build/cygtar.py',
-        '<(DEPTH)/native_client/toolchain/.tars/naclsdk_pnacl_translator.tgz',
+        '<(DEPTH)/native_client/build/package_version/package_version.py',
+        '<(DEPTH)/native_client/toolchain/.tars/<(OS)_x86/pnacl_translator.json',
       ],
-      'outputs': ['<(SHARED_INTERMEDIATE_DIR)/pnacl_translator/stamp.untar'],
+      'outputs': ['<(SHARED_INTERMEDIATE_DIR)/<(OS)_x86/pnacl_translator/pnacl_translator.json'],
       'action': [
         'python',
-        '<(DEPTH)/native_client/build/untar_toolchain.py',
-        '--tool', 'pnacl',
-        '--tmp', '<(SHARED_INTERMEDIATE_DIR)/temp/untar',
-        '--sdk', '<(SHARED_INTERMEDIATE_DIR)/temp/sdk',
-        '--os', '<(OS)',
-        '--fin', '<(SHARED_INTERMEDIATE_DIR)/pnacl_translator',
-        '<(DEPTH)/native_client/toolchain/.tars/naclsdk_pnacl_translator.tgz',
+        '<(DEPTH)/native_client/build/package_version/package_version.py',
+        '--packages', 'pnacl_translator',
+        '--tar-dir', '<(DEPTH)/native_client/toolchain/.tars',
+        '--dest-dir', '<(SHARED_INTERMEDIATE_DIR)',
+        'extract',
       ],
     }],
   },
@@ -38,7 +36,7 @@
     'conditions': [
       ['disable_nacl==0 and disable_pnacl==0 and disable_nacl_untrusted==0', {
         'dependencies': [
-          '../../../../../ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:pnacl_irt_shim_browser',
+          '../../../../../ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:shim_browser',
           '../../../../../native_client/tools.gyp:prep_toolchain',
           'untar_pnacl_translator',
         ],
@@ -53,9 +51,9 @@
             'inputs': [
               'pnacl_component_crx_gen.py',
               # A stamp file representing the contents of pnacl_translator.
-              '<(SHARED_INTERMEDIATE_DIR)/pnacl_translator/stamp.untar',
+              '<(SHARED_INTERMEDIATE_DIR)/<(OS)_x86/pnacl_translator/pnacl_translator.json',
               '<(DEPTH)/native_client/pnacl/driver/pnacl_info_template.json',
-              '<(DEPTH)/native_client/TOOL_REVISIONS',
+              '<(DEPTH)/native_client/toolchain_revisions/pnacl_newlib.json',
             ],
             'conditions': [
                 # On windows we need both ia32 and x64.
@@ -185,8 +183,9 @@
               '<@(lib_overrides)',
               '--target_arch=<(target_arch)',
               '--info_template_path=<(DEPTH)/native_client/pnacl/driver/pnacl_info_template.json',
-              '--pnacl_translator_path=<(SHARED_INTERMEDIATE_DIR)/pnacl_translator',
-              '--tool_revisions_path=<(DEPTH)/native_client/TOOL_REVISIONS',
+              '--pnacl_translator_path=<(SHARED_INTERMEDIATE_DIR)/<(OS)_x86/pnacl_translator',
+              '--package_version_path=<(DEPTH)/native_client/build/package_version/package_version.py',
+              '--pnacl_package_name=pnacl_newlib',
               # ABI Version Number.
               '1',
             ],
diff --git a/ppapi/ppapi_nacl.gyp b/ppapi/ppapi_nacl.gyp
index 3f31f57..1853780 100644
--- a/ppapi/ppapi_nacl.gyp
+++ b/ppapi/ppapi_nacl.gyp
@@ -186,7 +186,7 @@
           },
           # Shim is a dependency for the nexe because we pre-translate.
           'dependencies': [
-            '<(DEPTH)/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:pnacl_irt_shim_aot',
+            '<(DEPTH)/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:shim_aot',
           ],
           'actions': [
             {
@@ -221,7 +221,7 @@
           },
           # Shim is a dependency for the nexe because we pre-translate.
           'dependencies': [
-            '<(DEPTH)/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:pnacl_irt_shim_aot',
+            '<(DEPTH)/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:shim_aot',
           ],
           'actions': [
             {
@@ -245,7 +245,7 @@
           },
           # Shim is a dependency for the nexe because we pre-translate.
           'dependencies': [
-            '<(DEPTH)/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:pnacl_irt_shim_aot',
+            '<(DEPTH)/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:shim_aot',
           ],
           'actions': [
             {
diff --git a/ppapi/ppapi_nacl_test_common.gypi b/ppapi/ppapi_nacl_test_common.gypi
index b5c6055..0d9b676 100644
--- a/ppapi/ppapi_nacl_test_common.gypi
+++ b/ppapi/ppapi_nacl_test_common.gypi
@@ -19,6 +19,7 @@
       'nacl_newlib_out_dir': '<(PRODUCT_DIR)/>(nexe_destination_dir)/newlib',
       'nacl_glibc_out_dir': '<(PRODUCT_DIR)/>(nexe_destination_dir)/glibc',
       'nacl_pnacl_newlib_out_dir': '<(PRODUCT_DIR)/>(nexe_destination_dir)/pnacl',
+      'nacl_pnacl_newlib_nonsfi_out_dir': '<(PRODUCT_DIR)/>(nexe_destination_dir)/nonsfi',
       'target_conditions': [
         ['nexe_target!=""', {
           # These variables are used for nexe building and for library building.
@@ -33,6 +34,7 @@
           'nmf_glibc%': '>(nacl_glibc_out_dir)/>(nexe_target).nmf',
           'out_pnacl_newlib%': '>(nacl_pnacl_newlib_out_dir)/>(nexe_target)_newlib_pnacl.pexe',
           'nmf_pnacl_newlib%': '>(nacl_pnacl_newlib_out_dir)/>(nexe_target).nmf',
+          'out_pnacl_newlib_x86_32_nonsfi_nexe': '>(nacl_pnacl_newlib_nonsfi_out_dir)/>(nexe_target)_pnacl_newlib_x32_nonsfi.nexe',
         }],
       ],
     },
@@ -62,7 +64,8 @@
           },
         ],
       }],
-      ['test_files!=[] and build_pnacl_newlib==1 and disable_pnacl==0', {
+      # Nonsfi pnacl copy is covered below. Currently, these are exclusive.
+      ['test_files!=[] and build_pnacl_newlib==1 and disable_pnacl==0 and enable_x86_32_nonsfi==0', {
         'copies': [
           {
             'destination': '>(nacl_pnacl_newlib_out_dir)',
@@ -72,6 +75,16 @@
           },
         ],
       }],
+      ['test_files!=[] and build_pnacl_newlib==1 and enable_x86_32_nonsfi==1', {
+        'copies': [
+          {
+            'destination': '>(nacl_pnacl_newlib_nonsfi_out_dir)',
+            'files': [
+              '>@(test_files)',
+            ],
+          },
+        ],
+      }],
       ['nexe_target!=""', {
         'variables': {
           # Patch over the fact that untrusted.gypi doesn't define these in all
diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi
index 3913777..94f88f9 100644
--- a/ppapi/ppapi_shared.gypi
+++ b/ppapi/ppapi_shared.gypi
@@ -267,7 +267,8 @@
           'thunk/ppb_video_capture_api.h',
           'thunk/ppb_video_capture_thunk.cc',
           'thunk/ppb_video_decoder_api.h',
-          'thunk/ppb_video_decoder_thunk.cc',
+          'thunk/ppb_video_decoder_dev_api.h',
+          'thunk/ppb_video_decoder_dev_thunk.cc',
           'thunk/ppb_video_destination_private_api.h',
           'thunk/ppb_video_destination_private_thunk.cc',
           'thunk/ppb_video_frame_api.h',
@@ -327,7 +328,7 @@
               'thunk/ppb_transport_thunk.cc',
               'thunk/ppb_url_util_thunk.cc',
               'thunk/ppb_video_capture_thunk.cc',
-              'thunk/ppb_video_decoder_thunk.cc',
+              'thunk/ppb_video_decoder_dev_thunk.cc',
             ],
           }],
           # We exclude a few more things for nacl_win64, to avoid pulling in
diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi
index 066fcd0..43a17dd 100644
--- a/ppapi/ppapi_sources.gypi
+++ b/ppapi/ppapi_sources.gypi
@@ -7,6 +7,7 @@
     'c_source_files': [
       'c/pp_array_output.h',
       'c/pp_bool.h',
+      'c/pp_codecs.h',
       'c/pp_completion_callback.h',
       'c/pp_errors.h',
       'c/pp_file_info.h',
@@ -62,6 +63,7 @@
       'c/ppb_var_array.h',
       'c/ppb_var_array_buffer.h',
       'c/ppb_var_dictionary.h',
+      'c/ppb_video_decoder.h',
       'c/ppb_video_frame.h',
       'c/ppb_view.h',
       'c/ppb_websocket.h',
@@ -236,6 +238,8 @@
       'cpp/var_array_buffer.h',
       'cpp/var_dictionary.cc',
       'cpp/var_dictionary.h',
+      'cpp/video_decoder.cc',
+      'cpp/video_decoder.h',
       'cpp/video_frame.cc',
       'cpp/video_frame.h',
       'cpp/view.cc',
@@ -565,8 +569,8 @@
       'tests/test_url_util.h',
       'tests/test_utils.cc',
       'tests/test_utils.h',
-      'tests/test_video_decoder.cc',
-      'tests/test_video_decoder.h',
+      'tests/test_video_decoder_dev.cc',
+      'tests/test_video_decoder_dev.h',
       'tests/test_x509_certificate_private.cc',
       'tests/test_x509_certificate_private.h',
 
diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi
index e6d4156..d7e281e 100644
--- a/ppapi/ppapi_tests.gypi
+++ b/ppapi/ppapi_tests.gypi
@@ -126,8 +126,7 @@
       ],
       'conditions': [
         # See http://crbug.com/162998#c4 for why this is needed.
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and use_allocator!="none"', {
           'dependencies': [
             '../base/allocator/allocator.gyp:allocator',
           ],
@@ -191,8 +190,7 @@
       'conditions': [
         [ 'os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            [ '(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            [ 'use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
@@ -453,7 +451,25 @@
         'lib/gl/include',
       ],
       'sources': [
-        'examples/video_decode/video_decode.cc',
+        # TODO(bbudge) Change to new example when implementation lands.
+        'examples/video_decode/video_decode_dev.cc',
+        'examples/video_decode/testdata.h',
+      ],
+      # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
+      'target_name': 'ppapi_example_video_decode_dev',
+      'dependencies': [
+        'ppapi_example_skeleton',
+        'ppapi.gyp:ppapi_cpp',
+        'ppapi.gyp:ppapi_gles2',
+      ],
+      'include_dirs': [
+        'lib/gl/include',
+      ],
+      'sources': [
+        'examples/video_decode/video_decode_dev.cc',
         'examples/video_decode/testdata.h',
       ],
       # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc
index d04818e..3c45dfd 100644
--- a/ppapi/proxy/interface_list.cc
+++ b/ppapi/proxy/interface_list.cc
@@ -291,7 +291,6 @@
          PPP_Instance_Private_Proxy::GetProxyInterface());
 #endif
   AddProxy(API_ID_PPP_MESSAGING, &ProxyFactory<PPP_Messaging_Proxy>);
-  AddPPP(PPP_MESSAGING_INTERFACE, PPP_Messaging_Proxy::GetProxyInterface());
   AddProxy(API_ID_PPP_MOUSE_LOCK, &ProxyFactory<PPP_MouseLock_Proxy>);
   AddPPP(PPP_MOUSELOCK_INTERFACE, PPP_MouseLock_Proxy::GetProxyInterface());
   AddProxy(API_ID_PPP_PRINTING, &ProxyFactory<PPP_Printing_Proxy>);
diff --git a/ppapi/proxy/media_stream_track_resource_base.cc b/ppapi/proxy/media_stream_track_resource_base.cc
index d259036..4431da3 100644
--- a/ppapi/proxy/media_stream_track_resource_base.cc
+++ b/ppapi/proxy/media_stream_track_resource_base.cc
@@ -22,6 +22,14 @@
   AttachToPendingHost(RENDERER, pending_renderer_id);
 }
 
+MediaStreamTrackResourceBase::MediaStreamTrackResourceBase(
+    Connection connection,
+    PP_Instance instance)
+    : PluginResource(connection, instance),
+      buffer_manager_(this),
+      has_ended_(false) {
+}
+
 MediaStreamTrackResourceBase::~MediaStreamTrackResourceBase() {
 }
 
@@ -40,6 +48,9 @@
         PpapiPluginMsg_MediaStreamTrack_InitBuffers, OnPluginMsgInitBuffers)
     PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
         PpapiPluginMsg_MediaStreamTrack_EnqueueBuffer, OnPluginMsgEnqueueBuffer)
+    PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
+        PpapiPluginMsg_MediaStreamTrack_EnqueueBuffers,
+        OnPluginMsgEnqueueBuffers)
     PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(
         PluginResource::OnReplyReceived(params, msg))
   IPC_END_MESSAGE_MAP()
@@ -55,11 +66,13 @@
 void MediaStreamTrackResourceBase::OnPluginMsgInitBuffers(
     const ResourceMessageReplyParams& params,
     int32_t number_of_buffers,
-    int32_t buffer_size) {
+    int32_t buffer_size,
+    bool readonly) {
   base::SharedMemoryHandle shm_handle = base::SharedMemory::NULLHandle();
   params.TakeSharedMemoryHandleAtIndex(0, &shm_handle);
   buffer_manager_.SetBuffers(number_of_buffers, buffer_size,
-      scoped_ptr<base::SharedMemory>(new base::SharedMemory(shm_handle, true)),
+      scoped_ptr<base::SharedMemory>(new base::SharedMemory(shm_handle,
+                                                            readonly)),
       false);
 }
 
@@ -69,5 +82,12 @@
   buffer_manager_.EnqueueBuffer(index);
 }
 
+void MediaStreamTrackResourceBase::OnPluginMsgEnqueueBuffers(
+    const ResourceMessageReplyParams& params,
+    const std::vector<int32_t>& indices) {
+  for (size_t i = 0; i < indices.size(); ++i)
+    buffer_manager_.EnqueueBuffer(indices[i]);
+}
+
 }  // namespace proxy
 }  // namespace ppapi
diff --git a/ppapi/proxy/media_stream_track_resource_base.h b/ppapi/proxy/media_stream_track_resource_base.h
index b5438ce..087d4a9 100644
--- a/ppapi/proxy/media_stream_track_resource_base.h
+++ b/ppapi/proxy/media_stream_track_resource_base.h
@@ -21,10 +21,14 @@
                                int pending_renderer_id,
                                const std::string& id);
 
+  MediaStreamTrackResourceBase(Connection connection, PP_Instance instance);
+
   virtual ~MediaStreamTrackResourceBase();
 
   std::string id() const { return id_; }
 
+  void set_id(const std::string& id) { id_ = id; }
+
   bool has_ended() const { return has_ended_; }
 
   MediaStreamBufferManager* buffer_manager() { return &buffer_manager_; }
@@ -45,9 +49,12 @@
   // Message handlers:
   void OnPluginMsgInitBuffers(const ResourceMessageReplyParams& params,
                               int32_t number_of_buffers,
-                              int32_t buffer_size);
+                              int32_t buffer_size,
+                              bool readonly);
   void OnPluginMsgEnqueueBuffer(const ResourceMessageReplyParams& params,
                                 int32_t index);
+  void OnPluginMsgEnqueueBuffers(const ResourceMessageReplyParams& params,
+                                 const std::vector<int32_t>& indices);
 
   MediaStreamBufferManager buffer_manager_;
 
diff --git a/ppapi/proxy/media_stream_video_track_resource.cc b/ppapi/proxy/media_stream_video_track_resource.cc
index aaa5b52..fc60231 100644
--- a/ppapi/proxy/media_stream_video_track_resource.cc
+++ b/ppapi/proxy/media_stream_video_track_resource.cc
@@ -24,6 +24,14 @@
       get_frame_output_(NULL) {
 }
 
+MediaStreamVideoTrackResource::MediaStreamVideoTrackResource(
+    Connection connection,
+    PP_Instance instance)
+    : MediaStreamTrackResourceBase(connection, instance),
+      get_frame_output_(NULL) {
+  SendCreate(RENDERER, PpapiHostMsg_MediaStreamVideoTrack_Create());
+}
+
 MediaStreamVideoTrackResource::~MediaStreamVideoTrackResource() {
   Close();
 }
@@ -150,6 +158,17 @@
   MediaStreamTrackResourceBase::CloseInternal();
 }
 
+int32_t MediaStreamVideoTrackResource::GetEmptyFrame(
+    PP_Resource* frame, scoped_refptr<TrackedCallback> callback) {
+  return GetFrame(frame, callback);
+}
+
+int32_t MediaStreamVideoTrackResource::PutFrame(PP_Resource frame) {
+  // TODO(ronghuawu): Consider to rename RecycleFrame to PutFrame and use
+  // one set of GetFrame and PutFrame for both input and output.
+  return RecycleFrame(frame);
+}
+
 void MediaStreamVideoTrackResource::OnNewBufferEnqueued() {
   if (!TrackedCallback::IsPending(get_frame_callback_))
     return;
@@ -189,7 +208,13 @@
 }
 
 void MediaStreamVideoTrackResource::OnPluginMsgConfigureReply(
-    const ResourceMessageReplyParams& params) {
+    const ResourceMessageReplyParams& params,
+    const std::string& track_id) {
+  if (id().empty()) {
+    set_id(track_id);
+  } else {
+    DCHECK_EQ(id(), track_id);
+  }
   if (TrackedCallback::IsPending(configure_callback_)) {
     scoped_refptr<TrackedCallback> callback;
     callback.swap(configure_callback_);
diff --git a/ppapi/proxy/media_stream_video_track_resource.h b/ppapi/proxy/media_stream_video_track_resource.h
index d1b3bb5..1e9927f 100644
--- a/ppapi/proxy/media_stream_video_track_resource.h
+++ b/ppapi/proxy/media_stream_video_track_resource.h
@@ -26,6 +26,8 @@
                                 int pending_renderer_id,
                                 const std::string& id);
 
+  MediaStreamVideoTrackResource(Connection connection, PP_Instance instance);
+
   virtual ~MediaStreamVideoTrackResource();
 
   // Resource overrides:
@@ -43,6 +45,9 @@
                            scoped_refptr<TrackedCallback> callback) OVERRIDE;
   virtual int32_t RecycleFrame(PP_Resource frame) OVERRIDE;
   virtual void Close() OVERRIDE;
+  virtual int32_t GetEmptyFrame(
+      PP_Resource* frame, scoped_refptr<TrackedCallback> callback) OVERRIDE;
+  virtual int32_t PutFrame(PP_Resource frame) OVERRIDE;
 
   // MediaStreamBufferManager::Delegate overrides:
   virtual void OnNewBufferEnqueued() OVERRIDE;
@@ -53,7 +58,8 @@
   void ReleaseFrames();
 
   // IPC message handlers.
-  void OnPluginMsgConfigureReply(const ResourceMessageReplyParams& params);
+  void OnPluginMsgConfigureReply(const ResourceMessageReplyParams& params,
+                                 const std::string& track_id);
 
   // Allocated frame resources by |GetFrame()|.
   typedef std::map<PP_Resource, scoped_refptr<VideoFrameResource> > FrameMap;
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.cc b/ppapi/proxy/ppapi_command_buffer_proxy.cc
index e9a8a35..0623cd8 100644
--- a/ppapi/proxy/ppapi_command_buffer_proxy.cc
+++ b/ppapi/proxy/ppapi_command_buffer_proxy.cc
@@ -181,6 +181,7 @@
     size_t width,
     size_t height,
     unsigned internalformat,
+    unsigned usage,
     int32* id) {
   NOTREACHED();
   return NULL;
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.h b/ppapi/proxy/ppapi_command_buffer_proxy.h
index 32cbfad..2f1b02e 100644
--- a/ppapi/proxy/ppapi_command_buffer_proxy.h
+++ b/ppapi/proxy/ppapi_command_buffer_proxy.h
@@ -7,8 +7,8 @@
 
 #include "base/callback.h"
 #include "base/containers/hash_tables.h"
+#include "gpu/command_buffer/client/gpu_control.h"
 #include "gpu/command_buffer/common/command_buffer.h"
-#include "gpu/command_buffer/common/gpu_control.h"
 #include "ppapi/proxy/ppapi_proxy_export.h"
 #include "ppapi/shared_impl/host_resource.h"
 
@@ -42,11 +42,11 @@
 
   // gpu::GpuControl implementation:
   virtual gpu::Capabilities GetCapabilities() OVERRIDE;
-  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(
-      size_t width,
-      size_t height,
-      unsigned internalformat,
-      int32* id) OVERRIDE;
+  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(size_t width,
+                                                      size_t height,
+                                                      unsigned internalformat,
+                                                      unsigned usage,
+                                                      int32* id) OVERRIDE;
   virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
   virtual uint32 InsertSyncPoint() OVERRIDE;
   virtual void SignalSyncPoint(uint32 sync_point,
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index 10cde4e..95ac3d9 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -756,6 +756,11 @@
 // Notify the renderer that the PPAPI channel gets ready in the plugin.
 IPC_MESSAGE_CONTROL0(PpapiHostMsg_StartupInitializationComplete);
 
+// Calls renderer to open a resource file for nacl_irt_open_resource().
+IPC_SYNC_MESSAGE_CONTROL1_1(PpapiHostMsg_OpenResource,
+                            std::string /* key */,
+                            ppapi::proxy::SerializedHandle /* fd */)
+
 // Logs the given message to the console of all instances.
 IPC_MESSAGE_CONTROL4(PpapiHostMsg_LogWithSource,
                      PP_Instance /* instance */,
@@ -1433,20 +1438,25 @@
                      std::string /* track_id */)
 IPC_MESSAGE_CONTROL1(PpapiPluginMsg_MediaStreamVideoTrack_CreateFromPendingHost,
                      std::string /* track_id */)
+IPC_MESSAGE_CONTROL0(PpapiHostMsg_MediaStreamVideoTrack_Create)
 IPC_MESSAGE_CONTROL1(
     PpapiHostMsg_MediaStreamVideoTrack_Configure,
     ppapi::MediaStreamVideoTrackShared::Attributes /* attributes */)
-IPC_MESSAGE_CONTROL0(PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply)
+IPC_MESSAGE_CONTROL1(PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply,
+                     std::string /* track_id */)
 
 // Message for init buffers. It also takes a shared memory handle which is put
 // in the outer ResourceReplyMessage.
-IPC_MESSAGE_CONTROL2(PpapiPluginMsg_MediaStreamTrack_InitBuffers,
+IPC_MESSAGE_CONTROL3(PpapiPluginMsg_MediaStreamTrack_InitBuffers,
                      int32_t /* number_of_buffers */,
-                     int32_t /* buffer_size */)
+                     int32_t /* buffer_size */,
+                     bool /* readonly */)
 IPC_MESSAGE_CONTROL1(PpapiPluginMsg_MediaStreamTrack_EnqueueBuffer,
                      int32_t /* index */);
 IPC_MESSAGE_CONTROL1(PpapiHostMsg_MediaStreamTrack_EnqueueBuffer,
                      int32_t /* index */);
+IPC_MESSAGE_CONTROL1(PpapiPluginMsg_MediaStreamTrack_EnqueueBuffers,
+                     std::vector<int32_t> /* indices */);
 IPC_MESSAGE_CONTROL0(PpapiHostMsg_MediaStreamTrack_Close)
 
 // NetworkMonitor.
diff --git a/ppapi/proxy/ppb_video_decoder_proxy.cc b/ppapi/proxy/ppb_video_decoder_proxy.cc
index dd42050..4eae1f2 100644
--- a/ppapi/proxy/ppb_video_decoder_proxy.cc
+++ b/ppapi/proxy/ppb_video_decoder_proxy.cc
@@ -18,7 +18,7 @@
 using ppapi::thunk::EnterResourceNoLock;
 using ppapi::thunk::PPB_Buffer_API;
 using ppapi::thunk::PPB_Graphics3D_API;
-using ppapi::thunk::PPB_VideoDecoder_API;
+using ppapi::thunk::PPB_VideoDecoder_Dev_API;
 
 namespace ppapi {
 namespace proxy {
@@ -33,7 +33,7 @@
                               PP_Resource graphics_context,
                               PP_VideoDecoder_Profile profile);
 
-  // PPB_VideoDecoder_API implementation.
+  // PPB_VideoDecoder_Dev_API implementation.
   virtual int32_t Decode(const PP_VideoBitstreamBuffer_Dev* bitstream_buffer,
                          scoped_refptr<TrackedCallback> callback) OVERRIDE;
   virtual void AssignPictureBuffers(
@@ -225,14 +225,14 @@
 
   // Make the resource and get the API pointer to its interface.
   result->SetHostResource(
-      instance, resource_creation.functions()->CreateVideoDecoder(
+      instance, resource_creation.functions()->CreateVideoDecoderDev(
           instance, graphics_context.host_resource(), profile));
 }
 
 void PPB_VideoDecoder_Proxy::OnMsgDecode(
     const HostResource& decoder,
     const HostResource& buffer, int32 id, uint32 size) {
-  EnterHostFromHostResourceForceCallback<PPB_VideoDecoder_API> enter(
+  EnterHostFromHostResourceForceCallback<PPB_VideoDecoder_Dev_API> enter(
       decoder, callback_factory_,
       &PPB_VideoDecoder_Proxy::SendMsgEndOfBitstreamACKToPlugin, decoder, id);
   if (enter.failed())
@@ -244,7 +244,7 @@
 void PPB_VideoDecoder_Proxy::OnMsgAssignPictureBuffers(
     const HostResource& decoder,
     const std::vector<PP_PictureBuffer_Dev>& buffers) {
-  EnterHostFromHostResource<PPB_VideoDecoder_API> enter(decoder);
+  EnterHostFromHostResource<PPB_VideoDecoder_Dev_API> enter(decoder);
   if (enter.succeeded() && !buffers.empty()) {
     const PP_PictureBuffer_Dev* buffer_array = &buffers.front();
     enter.object()->AssignPictureBuffers(buffers.size(), buffer_array);
@@ -253,13 +253,13 @@
 
 void PPB_VideoDecoder_Proxy::OnMsgReusePictureBuffer(
     const HostResource& decoder, int32 picture_buffer_id) {
-  EnterHostFromHostResource<PPB_VideoDecoder_API> enter(decoder);
+  EnterHostFromHostResource<PPB_VideoDecoder_Dev_API> enter(decoder);
   if (enter.succeeded())
     enter.object()->ReusePictureBuffer(picture_buffer_id);
 }
 
 void PPB_VideoDecoder_Proxy::OnMsgFlush(const HostResource& decoder) {
-  EnterHostFromHostResourceForceCallback<PPB_VideoDecoder_API> enter(
+  EnterHostFromHostResourceForceCallback<PPB_VideoDecoder_Dev_API> enter(
       decoder, callback_factory_,
       &PPB_VideoDecoder_Proxy::SendMsgFlushACKToPlugin, decoder);
   if (enter.succeeded())
@@ -267,7 +267,7 @@
 }
 
 void PPB_VideoDecoder_Proxy::OnMsgReset(const HostResource& decoder) {
-  EnterHostFromHostResourceForceCallback<PPB_VideoDecoder_API> enter(
+  EnterHostFromHostResourceForceCallback<PPB_VideoDecoder_Dev_API> enter(
       decoder, callback_factory_,
       &PPB_VideoDecoder_Proxy::SendMsgResetACKToPlugin, decoder);
   if (enter.succeeded())
@@ -275,7 +275,7 @@
 }
 
 void PPB_VideoDecoder_Proxy::OnMsgDestroy(const HostResource& decoder) {
-  EnterHostFromHostResource<PPB_VideoDecoder_API> enter(decoder);
+  EnterHostFromHostResource<PPB_VideoDecoder_Dev_API> enter(decoder);
   if (enter.succeeded())
     enter.object()->Destroy();
 }
@@ -300,21 +300,21 @@
 
 void PPB_VideoDecoder_Proxy::OnMsgEndOfBitstreamACK(
     const HostResource& decoder, int32_t id, int32_t result) {
-  EnterPluginFromHostResource<PPB_VideoDecoder_API> enter(decoder);
+  EnterPluginFromHostResource<PPB_VideoDecoder_Dev_API> enter(decoder);
   if (enter.succeeded())
     static_cast<VideoDecoder*>(enter.object())->EndOfBitstreamACK(id, result);
 }
 
 void PPB_VideoDecoder_Proxy::OnMsgFlushACK(
     const HostResource& decoder, int32_t result) {
-  EnterPluginFromHostResource<PPB_VideoDecoder_API> enter(decoder);
+  EnterPluginFromHostResource<PPB_VideoDecoder_Dev_API> enter(decoder);
   if (enter.succeeded())
     static_cast<VideoDecoder*>(enter.object())->FlushACK(result);
 }
 
 void PPB_VideoDecoder_Proxy::OnMsgResetACK(
     const HostResource& decoder, int32_t result) {
-  EnterPluginFromHostResource<PPB_VideoDecoder_API> enter(decoder);
+  EnterPluginFromHostResource<PPB_VideoDecoder_Dev_API> enter(decoder);
   if (enter.succeeded())
     static_cast<VideoDecoder*>(enter.object())->ResetACK(result);
 }
diff --git a/ppapi/proxy/ppb_video_decoder_proxy.h b/ppapi/proxy/ppb_video_decoder_proxy.h
index e9127a7..dbc030e 100644
--- a/ppapi/proxy/ppb_video_decoder_proxy.h
+++ b/ppapi/proxy/ppb_video_decoder_proxy.h
@@ -9,7 +9,7 @@
 #include "ppapi/proxy/interface_proxy.h"
 #include "ppapi/proxy/proxy_completion_callback_factory.h"
 #include "ppapi/shared_impl/ppb_video_decoder_shared.h"
-#include "ppapi/thunk/ppb_video_decoder_api.h"
+#include "ppapi/thunk/ppb_video_decoder_dev_api.h"
 #include "ppapi/utility/completion_callback_factory.h"
 
 namespace ppapi {
diff --git a/ppapi/proxy/ppp_messaging_proxy.cc b/ppapi/proxy/ppp_messaging_proxy.cc
index 2a859bc..ba83ca7 100644
--- a/ppapi/proxy/ppp_messaging_proxy.cc
+++ b/ppapi/proxy/ppp_messaging_proxy.cc
@@ -19,34 +19,6 @@
 namespace ppapi {
 namespace proxy {
 
-namespace {
-
-#if !defined(OS_NACL)
-void HandleMessage(PP_Instance instance, PP_Var message_data) {
-  HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
-  if (!dispatcher || (message_data.type == PP_VARTYPE_OBJECT)) {
-    // The dispatcher should always be valid, and the browser should never send
-    // an 'object' var over PPP_Messaging.
-    NOTREACHED();
-    return;
-  }
-
-  dispatcher->Send(new PpapiMsg_PPPMessaging_HandleMessage(
-      API_ID_PPP_MESSAGING,
-      instance,
-      SerializedVarSendInputShmem(dispatcher, message_data, instance)));
-}
-
-static const PPP_Messaging messaging_interface = {
-  &HandleMessage
-};
-#else
-// The NaCl plugin doesn't need the host side interface - stub it out.
-static const PPP_Messaging messaging_interface = {};
-#endif  // !defined(OS_NACL)
-
-}  // namespace
-
 PPP_Messaging_Proxy::PPP_Messaging_Proxy(Dispatcher* dispatcher)
     : InterfaceProxy(dispatcher),
       ppp_messaging_impl_(NULL) {
@@ -59,11 +31,6 @@
 PPP_Messaging_Proxy::~PPP_Messaging_Proxy() {
 }
 
-// static
-const PPP_Messaging* PPP_Messaging_Proxy::GetProxyInterface() {
-  return &messaging_interface;
-}
-
 bool PPP_Messaging_Proxy::OnMessageReceived(const IPC::Message& msg) {
   if (!dispatcher()->IsPlugin())
     return false;
diff --git a/ppapi/proxy/ppp_messaging_proxy.h b/ppapi/proxy/ppp_messaging_proxy.h
index b75feab..210574a 100644
--- a/ppapi/proxy/ppp_messaging_proxy.h
+++ b/ppapi/proxy/ppp_messaging_proxy.h
@@ -20,8 +20,6 @@
   PPP_Messaging_Proxy(Dispatcher* dispatcher);
   virtual ~PPP_Messaging_Proxy();
 
-  static const PPP_Messaging* GetProxyInterface();
-
   // InterfaceProxy implementation.
   virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
 
diff --git a/ppapi/proxy/ppp_messaging_proxy_unittest.cc b/ppapi/proxy/ppp_messaging_proxy_unittest.cc
index 1fe0ef7..d1fa9b6 100644
--- a/ppapi/proxy/ppp_messaging_proxy_unittest.cc
+++ b/ppapi/proxy/ppp_messaging_proxy_unittest.cc
@@ -8,7 +8,10 @@
 #include "ppapi/c/pp_var.h"
 #include "ppapi/c/ppb_var.h"
 #include "ppapi/c/ppp_messaging.h"
+#include "ppapi/proxy/ppapi_messages.h"
 #include "ppapi/proxy/ppapi_proxy_test.h"
+#include "ppapi/proxy/serialized_var.h"
+#include "ppapi/shared_impl/api_id.h"
 #include "ppapi/shared_impl/proxy_lock.h"
 #include "ppapi/shared_impl/var.h"
 
@@ -42,6 +45,17 @@
   &HandleMessage
 };
 
+// CallHandleMessage does the host-side work to cause HandleMessage to be called
+// in the plugin side.
+void CallHandleMessage(Dispatcher* dispatcher,
+                       PP_Instance instance,
+                       PP_Var message) {
+  dispatcher->Send(new PpapiMsg_PPPMessaging_HandleMessage(
+      API_ID_PPP_MESSAGING,
+      instance,
+      SerializedVarSendInputShmem(dispatcher, message, instance)));
+}
+
 class PPP_Messaging_ProxyTest : public TwoWayTest {
  public:
   PPP_Messaging_ProxyTest()
@@ -68,29 +82,25 @@
 }  // namespace
 
 TEST_F(PPP_Messaging_ProxyTest, SendMessages) {
-  // Grab the host-side proxy of ppp_messaging.
-  const PPP_Messaging* ppp_messaging = static_cast<const PPP_Messaging*>(
-      host().host_dispatcher()->GetProxiedInterface(
-          PPP_MESSAGING_INTERFACE));
-
   PP_Instance expected_instance = pp_instance();
   PP_Var expected_var = PP_MakeUndefined();
   ResetReceived();
-  ppp_messaging->HandleMessage(expected_instance, expected_var);
+  Dispatcher* host_dispatcher = host().GetDispatcher();
+  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
   handle_message_called.Wait();
   EXPECT_EQ(expected_instance, received_instance);
   EXPECT_EQ(expected_var.type, received_var.type);
 
   expected_var = PP_MakeNull();
   ResetReceived();
-  ppp_messaging->HandleMessage(expected_instance, expected_var);
+  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
   handle_message_called.Wait();
   EXPECT_EQ(expected_instance, received_instance);
   EXPECT_EQ(expected_var.type, received_var.type);
 
   expected_var = PP_MakeBool(PP_TRUE);
   ResetReceived();
-  ppp_messaging->HandleMessage(expected_instance, expected_var);
+  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
   handle_message_called.Wait();
   EXPECT_EQ(expected_instance, received_instance);
   EXPECT_EQ(expected_var.type, received_var.type);
@@ -98,7 +108,7 @@
 
   expected_var = PP_MakeInt32(12345);
   ResetReceived();
-  ppp_messaging->HandleMessage(expected_instance, expected_var);
+  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
   handle_message_called.Wait();
   EXPECT_EQ(expected_instance, received_instance);
   EXPECT_EQ(expected_var.type, received_var.type);
@@ -106,7 +116,7 @@
 
   expected_var = PP_MakeDouble(3.1415);
   ResetReceived();
-  ppp_messaging->HandleMessage(expected_instance, expected_var);
+  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
   handle_message_called.Wait();
   EXPECT_EQ(expected_instance, received_instance);
   EXPECT_EQ(expected_var.type, received_var.type);
@@ -115,7 +125,7 @@
   const std::string kTestString("Hello world!");
   expected_var = StringVar::StringToPPVar(kTestString);
   ResetReceived();
-  ppp_messaging->HandleMessage(expected_instance, expected_var);
+  CallHandleMessage(host_dispatcher, expected_instance, expected_var);
   // Now release the var, and the string should go away (because the ref
   // count should be one).
   host().var_tracker().ReleaseVar(expected_var);
diff --git a/ppapi/proxy/ppp_video_decoder_proxy.cc b/ppapi/proxy/ppp_video_decoder_proxy.cc
index cb1569f..1980318 100644
--- a/ppapi/proxy/ppp_video_decoder_proxy.cc
+++ b/ppapi/proxy/ppp_video_decoder_proxy.cc
@@ -10,11 +10,9 @@
 #include "ppapi/proxy/ppapi_messages.h"
 #include "ppapi/proxy/ppb_video_decoder_proxy.h"
 #include "ppapi/thunk/enter.h"
-#include "ppapi/thunk/ppb_video_decoder_api.h"
+#include "ppapi/thunk/ppb_video_decoder_dev_api.h"
 #include "ppapi/thunk/thunk.h"
 
-using ppapi::thunk::PPB_VideoDecoder_API;
-
 namespace ppapi {
 namespace proxy {
 
diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc
index a4dbeec..eda6308 100644
--- a/ppapi/proxy/resource_creation_proxy.cc
+++ b/ppapi/proxy/resource_creation_proxy.cc
@@ -18,6 +18,7 @@
 #include "ppapi/proxy/graphics_2d_resource.h"
 #include "ppapi/proxy/host_resolver_private_resource.h"
 #include "ppapi/proxy/host_resolver_resource.h"
+#include "ppapi/proxy/media_stream_video_track_resource.h"
 #include "ppapi/proxy/net_address_resource.h"
 #include "ppapi/proxy/network_monitor_resource.h"
 #include "ppapi/proxy/output_protection_resource.h"
@@ -290,6 +291,12 @@
       format, *size, init_to_zero);
 }
 
+PP_Resource ResourceCreationProxy::CreateMediaStreamVideoTrack(
+    PP_Instance instance) {
+  return (new MediaStreamVideoTrackResource(GetConnection(),
+                                            instance))->GetReference();
+}
+
 PP_Resource ResourceCreationProxy::CreateNetAddressFromIPv4Address(
     PP_Instance instance,
     const PP_NetAddress_IPv4* ipv4_addr) {
@@ -458,7 +465,7 @@
       ->GetReference();
 }
 
-PP_Resource ResourceCreationProxy::CreateVideoDecoder(
+PP_Resource ResourceCreationProxy::CreateVideoDecoderDev(
     PP_Instance instance,
     PP_Resource context3d_id,
     PP_VideoDecoder_Profile profile) {
diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h
index 4719c4a..c32bce3 100644
--- a/ppapi/proxy/resource_creation_proxy.h
+++ b/ppapi/proxy/resource_creation_proxy.h
@@ -129,6 +129,8 @@
                                             PP_ImageDataFormat format,
                                             const PP_Size* size,
                                             PP_Bool init_to_zero) OVERRIDE;
+  virtual PP_Resource CreateMediaStreamVideoTrack(
+      PP_Instance instance) OVERRIDE;
   virtual PP_Resource CreateNetAddressFromIPv4Address(
       PP_Instance instance,
       const PP_NetAddress_IPv4* ipv4_addr) OVERRIDE;
@@ -176,7 +178,7 @@
                                       PP_Bool vertical) OVERRIDE;
   virtual PP_Resource CreateTalk(PP_Instance instance) OVERRIDE;
   virtual PP_Resource CreateVideoCapture(PP_Instance instance) OVERRIDE;
-  virtual PP_Resource CreateVideoDecoder(
+  virtual PP_Resource CreateVideoDecoderDev(
       PP_Instance instance,
       PP_Resource context3d_id,
       PP_VideoDecoder_Profile profile) OVERRIDE;
diff --git a/ppapi/shared_impl/dictionary_var.cc b/ppapi/shared_impl/dictionary_var.cc
index 54d2010..8676c43 100644
--- a/ppapi/shared_impl/dictionary_var.cc
+++ b/ppapi/shared_impl/dictionary_var.cc
@@ -90,7 +90,7 @@
 
 bool DictionaryVar::SetWithStringKey(const std::string& utf8_key,
                                      const PP_Var& value) {
-  if (!IsStringUTF8(utf8_key))
+  if (!base::IsStringUTF8(utf8_key))
     return false;
 
   key_value_map_[utf8_key] = value;
diff --git a/ppapi/shared_impl/file_ref_util.cc b/ppapi/shared_impl/file_ref_util.cc
index 3be8e0a..a5523cb 100644
--- a/ppapi/shared_impl/file_ref_util.cc
+++ b/ppapi/shared_impl/file_ref_util.cc
@@ -36,7 +36,7 @@
   //   The path starts with '/'
   //   The path must contain valid UTF-8 characters.
   //   It must not FilePath::ReferencesParent().
-  if (path.empty() || !IsStringUTF8(path) || path[0] != '/')
+  if (path.empty() || !base::IsStringUTF8(path) || path[0] != '/')
     return false;
   base::FilePath file_path = base::FilePath::FromUTF8Unsafe(path);
   if (file_path.ReferencesParent())
diff --git a/ppapi/shared_impl/media_stream_buffer_manager.cc b/ppapi/shared_impl/media_stream_buffer_manager.cc
index d6c4b0d..29bc153 100644
--- a/ppapi/shared_impl/media_stream_buffer_manager.cc
+++ b/ppapi/shared_impl/media_stream_buffer_manager.cc
@@ -59,6 +59,12 @@
   return buffer;
 }
 
+std::vector<int32_t> MediaStreamBufferManager::DequeueBuffers() {
+  std::vector<int32_t> buffers(buffer_queue_.begin(), buffer_queue_.end());
+  buffer_queue_.clear();
+  return buffers;
+}
+
 void MediaStreamBufferManager::EnqueueBuffer(int32_t index) {
   CHECK_GE(index, 0) << "Invalid buffer index";
   CHECK_LT(index, number_of_buffers_) << "Invalid buffer index";
@@ -66,10 +72,9 @@
   delegate_->OnNewBufferEnqueued();
 }
 
-MediaStreamBuffer* MediaStreamBufferManager::GetBufferPointer(
-    int32_t index) {
-  CHECK_GE(index, 0) << "Invalid buffer index";
-  CHECK_LT(index, number_of_buffers_) << "Invalid buffer index";
+MediaStreamBuffer* MediaStreamBufferManager::GetBufferPointer(int32_t index) {
+  if (index < 0 || index >= number_of_buffers_)
+    return NULL;
   return buffers_[index];
 }
 
diff --git a/ppapi/shared_impl/media_stream_buffer_manager.h b/ppapi/shared_impl/media_stream_buffer_manager.h
index 240be5d..eafd10c 100644
--- a/ppapi/shared_impl/media_stream_buffer_manager.h
+++ b/ppapi/shared_impl/media_stream_buffer_manager.h
@@ -62,6 +62,9 @@
   // Dequeues a buffer from |buffer_queue_|.
   int32_t DequeueBuffer();
 
+  // Dequeues all the buffers from |buffer_queue_|.
+  std::vector<int32_t> DequeueBuffers();
+
   // Puts a buffer into |buffer_queue_|.
   void EnqueueBuffer(int32_t index);
 
diff --git a/ppapi/shared_impl/media_stream_buffer_manager_unittest.cc b/ppapi/shared_impl/media_stream_buffer_manager_unittest.cc
index 8370567..9374875 100644
--- a/ppapi/shared_impl/media_stream_buffer_manager_unittest.cc
+++ b/ppapi/shared_impl/media_stream_buffer_manager_unittest.cc
@@ -79,11 +79,9 @@
     EXPECT_EQ(PP_ERROR_FAILED, manager.DequeueBuffer());
     EXPECT_EQ(PP_ERROR_FAILED, manager.DequeueBuffer());
 
-    // Test crash for passing invalid index to GetBufferPointer()
-    EXPECT_DEATH(manager.GetBufferPointer(-1),
-                 ".*Check failed: index >= 0.*");
-    EXPECT_DEATH(manager.GetBufferPointer(kNumberOfBuffers),
-                 ".*Check failed: index < number_of_buffers_.*");
+    // Returns NULL for invalid index to GetBufferPointer()
+    EXPECT_EQ(NULL, manager.GetBufferPointer(-1));
+    EXPECT_EQ(NULL, manager.GetBufferPointer(kNumberOfBuffers));
 
     // Test crash for passing invalid index to EnqueueBuffer().
     EXPECT_DEATH(manager.EnqueueBuffer(-1),
diff --git a/ppapi/shared_impl/ppb_opengles2_shared.cc b/ppapi/shared_impl/ppb_opengles2_shared.cc
index 00cb2ed..ab040d5 100644
--- a/ppapi/shared_impl/ppb_opengles2_shared.cc
+++ b/ppapi/shared_impl/ppb_opengles2_shared.cc
@@ -1576,83 +1576,155 @@
 }  // namespace
 const PPB_OpenGLES2* PPB_OpenGLES2_Shared::GetInterface() {
   static const struct PPB_OpenGLES2 ppb_opengles2 = {
-      &ActiveTexture,                       &AttachShader,
-      &BindAttribLocation,                  &BindBuffer,
-      &BindFramebuffer,                     &BindRenderbuffer,
-      &BindTexture,                         &BlendColor,
-      &BlendEquation,                       &BlendEquationSeparate,
-      &BlendFunc,                           &BlendFuncSeparate,
-      &BufferData,                          &BufferSubData,
-      &CheckFramebufferStatus,              &Clear,
-      &ClearColor,                          &ClearDepthf,
-      &ClearStencil,                        &ColorMask,
-      &CompileShader,                       &CompressedTexImage2D,
-      &CompressedTexSubImage2D,             &CopyTexImage2D,
-      &CopyTexSubImage2D,                   &CreateProgram,
-      &CreateShader,                        &CullFace,
-      &DeleteBuffers,                       &DeleteFramebuffers,
-      &DeleteProgram,                       &DeleteRenderbuffers,
-      &DeleteShader,                        &DeleteTextures,
-      &DepthFunc,                           &DepthMask,
-      &DepthRangef,                         &DetachShader,
-      &Disable,                             &DisableVertexAttribArray,
-      &DrawArrays,                          &DrawElements,
-      &Enable,                              &EnableVertexAttribArray,
-      &Finish,                              &Flush,
-      &FramebufferRenderbuffer,             &FramebufferTexture2D,
-      &FrontFace,                           &GenBuffers,
-      &GenerateMipmap,                      &GenFramebuffers,
-      &GenRenderbuffers,                    &GenTextures,
-      &GetActiveAttrib,                     &GetActiveUniform,
-      &GetAttachedShaders,                  &GetAttribLocation,
-      &GetBooleanv,                         &GetBufferParameteriv,
-      &GetError,                            &GetFloatv,
-      &GetFramebufferAttachmentParameteriv, &GetIntegerv,
-      &GetProgramiv,                        &GetProgramInfoLog,
-      &GetRenderbufferParameteriv,          &GetShaderiv,
-      &GetShaderInfoLog,                    &GetShaderPrecisionFormat,
-      &GetShaderSource,                     &GetString,
-      &GetTexParameterfv,                   &GetTexParameteriv,
-      &GetUniformfv,                        &GetUniformiv,
-      &GetUniformLocation,                  &GetVertexAttribfv,
-      &GetVertexAttribiv,                   &GetVertexAttribPointerv,
-      &Hint,                                &IsBuffer,
-      &IsEnabled,                           &IsFramebuffer,
-      &IsProgram,                           &IsRenderbuffer,
-      &IsShader,                            &IsTexture,
-      &LineWidth,                           &LinkProgram,
-      &PixelStorei,                         &PolygonOffset,
-      &ReadPixels,                          &ReleaseShaderCompiler,
-      &RenderbufferStorage,                 &SampleCoverage,
-      &Scissor,                             &ShaderBinary,
-      &ShaderSource,                        &StencilFunc,
-      &StencilFuncSeparate,                 &StencilMask,
-      &StencilMaskSeparate,                 &StencilOp,
-      &StencilOpSeparate,                   &TexImage2D,
-      &TexParameterf,                       &TexParameterfv,
-      &TexParameteri,                       &TexParameteriv,
-      &TexSubImage2D,                       &Uniform1f,
-      &Uniform1fv,                          &Uniform1i,
-      &Uniform1iv,                          &Uniform2f,
-      &Uniform2fv,                          &Uniform2i,
-      &Uniform2iv,                          &Uniform3f,
-      &Uniform3fv,                          &Uniform3i,
-      &Uniform3iv,                          &Uniform4f,
-      &Uniform4fv,                          &Uniform4i,
-      &Uniform4iv,                          &UniformMatrix2fv,
-      &UniformMatrix3fv,                    &UniformMatrix4fv,
-      &UseProgram,                          &ValidateProgram,
-      &VertexAttrib1f,                      &VertexAttrib1fv,
-      &VertexAttrib2f,                      &VertexAttrib2fv,
-      &VertexAttrib3f,                      &VertexAttrib3fv,
-      &VertexAttrib4f,                      &VertexAttrib4fv,
-      &VertexAttribPointer,                 &Viewport};
+      &ActiveTexture,
+      &AttachShader,
+      &BindAttribLocation,
+      &BindBuffer,
+      &BindFramebuffer,
+      &BindRenderbuffer,
+      &BindTexture,
+      &BlendColor,
+      &BlendEquation,
+      &BlendEquationSeparate,
+      &BlendFunc,
+      &BlendFuncSeparate,
+      &BufferData,
+      &BufferSubData,
+      &CheckFramebufferStatus,
+      &Clear,
+      &ClearColor,
+      &ClearDepthf,
+      &ClearStencil,
+      &ColorMask,
+      &CompileShader,
+      &CompressedTexImage2D,
+      &CompressedTexSubImage2D,
+      &CopyTexImage2D,
+      &CopyTexSubImage2D,
+      &CreateProgram,
+      &CreateShader,
+      &CullFace,
+      &DeleteBuffers,
+      &DeleteFramebuffers,
+      &DeleteProgram,
+      &DeleteRenderbuffers,
+      &DeleteShader,
+      &DeleteTextures,
+      &DepthFunc,
+      &DepthMask,
+      &DepthRangef,
+      &DetachShader,
+      &Disable,
+      &DisableVertexAttribArray,
+      &DrawArrays,
+      &DrawElements,
+      &Enable,
+      &EnableVertexAttribArray,
+      &Finish,
+      &Flush,
+      &FramebufferRenderbuffer,
+      &FramebufferTexture2D,
+      &FrontFace,
+      &GenBuffers,
+      &GenerateMipmap,
+      &GenFramebuffers,
+      &GenRenderbuffers,
+      &GenTextures,
+      &GetActiveAttrib,
+      &GetActiveUniform,
+      &GetAttachedShaders,
+      &GetAttribLocation,
+      &GetBooleanv,
+      &GetBufferParameteriv,
+      &GetError,
+      &GetFloatv,
+      &GetFramebufferAttachmentParameteriv,
+      &GetIntegerv,
+      &GetProgramiv,
+      &GetProgramInfoLog,
+      &GetRenderbufferParameteriv,
+      &GetShaderiv,
+      &GetShaderInfoLog,
+      &GetShaderPrecisionFormat,
+      &GetShaderSource,
+      &GetString,
+      &GetTexParameterfv,
+      &GetTexParameteriv,
+      &GetUniformfv,
+      &GetUniformiv,
+      &GetUniformLocation,
+      &GetVertexAttribfv,
+      &GetVertexAttribiv,
+      &GetVertexAttribPointerv,
+      &Hint,
+      &IsBuffer,
+      &IsEnabled,
+      &IsFramebuffer,
+      &IsProgram,
+      &IsRenderbuffer,
+      &IsShader,
+      &IsTexture,
+      &LineWidth,
+      &LinkProgram,
+      &PixelStorei,
+      &PolygonOffset,
+      &ReadPixels,
+      &ReleaseShaderCompiler,
+      &RenderbufferStorage,
+      &SampleCoverage,
+      &Scissor,
+      &ShaderBinary,
+      &ShaderSource,
+      &StencilFunc,
+      &StencilFuncSeparate,
+      &StencilMask,
+      &StencilMaskSeparate,
+      &StencilOp,
+      &StencilOpSeparate,
+      &TexImage2D,
+      &TexParameterf,
+      &TexParameterfv,
+      &TexParameteri,
+      &TexParameteriv,
+      &TexSubImage2D,
+      &Uniform1f,
+      &Uniform1fv,
+      &Uniform1i,
+      &Uniform1iv,
+      &Uniform2f,
+      &Uniform2fv,
+      &Uniform2i,
+      &Uniform2iv,
+      &Uniform3f,
+      &Uniform3fv,
+      &Uniform3i,
+      &Uniform3iv,
+      &Uniform4f,
+      &Uniform4fv,
+      &Uniform4i,
+      &Uniform4iv,
+      &UniformMatrix2fv,
+      &UniformMatrix3fv,
+      &UniformMatrix4fv,
+      &UseProgram,
+      &ValidateProgram,
+      &VertexAttrib1f,
+      &VertexAttrib1fv,
+      &VertexAttrib2f,
+      &VertexAttrib2fv,
+      &VertexAttrib3f,
+      &VertexAttrib3fv,
+      &VertexAttrib4f,
+      &VertexAttrib4fv,
+      &VertexAttribPointer,
+      &Viewport};
   return &ppb_opengles2;
 }
 const PPB_OpenGLES2InstancedArrays*
 PPB_OpenGLES2_Shared::GetInstancedArraysInterface() {
   static const struct PPB_OpenGLES2InstancedArrays ppb_opengles2 = {
-      &DrawArraysInstancedANGLE, &DrawElementsInstancedANGLE,
+      &DrawArraysInstancedANGLE,
+      &DrawElementsInstancedANGLE,
       &VertexAttribDivisorANGLE};
   return &ppb_opengles2;
 }
@@ -1677,14 +1749,21 @@
 const PPB_OpenGLES2ChromiumMapSub*
 PPB_OpenGLES2_Shared::GetChromiumMapSubInterface() {
   static const struct PPB_OpenGLES2ChromiumMapSub ppb_opengles2 = {
-      &MapBufferSubDataCHROMIUM, &UnmapBufferSubDataCHROMIUM,
-      &MapTexSubImage2DCHROMIUM, &UnmapTexSubImage2DCHROMIUM};
+      &MapBufferSubDataCHROMIUM,
+      &UnmapBufferSubDataCHROMIUM,
+      &MapTexSubImage2DCHROMIUM,
+      &UnmapTexSubImage2DCHROMIUM};
   return &ppb_opengles2;
 }
 const PPB_OpenGLES2Query* PPB_OpenGLES2_Shared::GetQueryInterface() {
   static const struct PPB_OpenGLES2Query ppb_opengles2 = {
-      &GenQueriesEXT, &DeleteQueriesEXT, &IsQueryEXT,          &BeginQueryEXT,
-      &EndQueryEXT,   &GetQueryivEXT,    &GetQueryObjectuivEXT};
+      &GenQueriesEXT,
+      &DeleteQueriesEXT,
+      &IsQueryEXT,
+      &BeginQueryEXT,
+      &EndQueryEXT,
+      &GetQueryivEXT,
+      &GetQueryObjectuivEXT};
   return &ppb_opengles2;
 }
 const PPB_OpenGLES2DrawBuffers_Dev*
diff --git a/ppapi/shared_impl/ppb_url_util_shared.cc b/ppapi/shared_impl/ppb_url_util_shared.cc
index b328059..0e90f2f 100644
--- a/ppapi/shared_impl/ppb_url_util_shared.cc
+++ b/ppapi/shared_impl/ppb_url_util_shared.cc
@@ -14,7 +14,7 @@
 
 namespace {
 
-void ConvertComponent(const url_parse::Component& input,
+void ConvertComponent(const url::Component& input,
                       PP_URLComponent_Dev* output) {
   output->begin = input.begin;
   output->len = input.len;
@@ -26,8 +26,7 @@
 //
 // Output can be NULL to specify "do nothing." This rule is followed by all the
 // url util functions, so we implement it once here.
-void ConvertComponents(const url_parse::Parsed& input,
-                       PP_URLComponents_Dev* output) {
+void ConvertComponents(const url::Parsed& input, PP_URLComponents_Dev* output) {
   if (!output)
     return;
 
diff --git a/ppapi/shared_impl/ppb_video_decoder_shared.cc b/ppapi/shared_impl/ppb_video_decoder_shared.cc
index 97275db..88c9ca2 100644
--- a/ppapi/shared_impl/ppb_video_decoder_shared.cc
+++ b/ppapi/shared_impl/ppb_video_decoder_shared.cc
@@ -29,7 +29,8 @@
   DCHECK(graphics_context_ == 0);
 }
 
-thunk::PPB_VideoDecoder_API* PPB_VideoDecoder_Shared::AsPPB_VideoDecoder_API() {
+thunk::PPB_VideoDecoder_Dev_API*
+PPB_VideoDecoder_Shared::AsPPB_VideoDecoder_Dev_API() {
   return this;
 }
 
diff --git a/ppapi/shared_impl/ppb_video_decoder_shared.h b/ppapi/shared_impl/ppb_video_decoder_shared.h
index 618b6d0..ce294fb 100644
--- a/ppapi/shared_impl/ppb_video_decoder_shared.h
+++ b/ppapi/shared_impl/ppb_video_decoder_shared.h
@@ -13,7 +13,7 @@
 #include "ppapi/c/dev/ppb_video_decoder_dev.h"
 #include "ppapi/shared_impl/resource.h"
 #include "ppapi/shared_impl/tracked_callback.h"
-#include "ppapi/thunk/ppb_video_decoder_api.h"
+#include "ppapi/thunk/ppb_video_decoder_dev_api.h"
 
 namespace gpu {
 namespace gles2 {
@@ -27,16 +27,17 @@
 // events. Both the proxy and the renderer implementation share this code.
 class PPAPI_SHARED_EXPORT PPB_VideoDecoder_Shared
     : public Resource,
-      NON_EXPORTED_BASE(public thunk::PPB_VideoDecoder_API) {
+      NON_EXPORTED_BASE(public thunk::PPB_VideoDecoder_Dev_API) {
  public:
   explicit PPB_VideoDecoder_Shared(PP_Instance instance);
   explicit PPB_VideoDecoder_Shared(const HostResource& host_resource);
   virtual ~PPB_VideoDecoder_Shared();
 
   // Resource overrides.
-  virtual thunk::PPB_VideoDecoder_API* AsPPB_VideoDecoder_API() OVERRIDE;
+  virtual thunk::PPB_VideoDecoder_Dev_API* AsPPB_VideoDecoder_Dev_API()
+      OVERRIDE;
 
-  // PPB_VideoDecoder_API implementation.
+  // PPB_VideoDecoder_Dev_API implementation.
   virtual void Destroy() OVERRIDE;
 
  protected:
diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h
index 9c22cf6..3fe3496 100644
--- a/ppapi/shared_impl/resource.h
+++ b/ppapi/shared_impl/resource.h
@@ -80,7 +80,7 @@
   F(PPB_URLRequestInfo_API)             \
   F(PPB_URLResponseInfo_API)            \
   F(PPB_VideoCapture_API)               \
-  F(PPB_VideoDecoder_API)               \
+  F(PPB_VideoDecoder_Dev_API)           \
   F(PPB_VideoDestination_Private_API)   \
   F(PPB_VideoFrame_API)                 \
   F(PPB_VideoLayer_API)                 \
diff --git a/ppapi/shared_impl/var.cc b/ppapi/shared_impl/var.cc
index 8f3ddb5..3020182 100644
--- a/ppapi/shared_impl/var.cc
+++ b/ppapi/shared_impl/var.cc
@@ -148,7 +148,7 @@
 // static
 PP_Var StringVar::StringToPPVar(const char* data, uint32 len) {
   scoped_refptr<StringVar> str(new StringVar(data, len));
-  if (!str.get() || !IsStringUTF8(str->value()))
+  if (!str.get() || !base::IsStringUTF8(str->value()))
     return PP_MakeNull();
   return str->GetPPVar();
 }
diff --git a/ppapi/tests/test_video_decoder.cc b/ppapi/tests/test_video_decoder.cc
deleted file mode 100644
index dc36685..0000000
--- a/ppapi/tests/test_video_decoder.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ppapi/tests/test_video_decoder.h"
-
-#include "ppapi/c/dev/ppb_video_decoder_dev.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/c/ppb_var.h"
-#include "ppapi/tests/testing_instance.h"
-
-REGISTER_TEST_CASE(VideoDecoder);
-
-bool TestVideoDecoder::Init() {
-  video_decoder_interface_ = static_cast<const PPB_VideoDecoder_Dev*>(
-      pp::Module::Get()->GetBrowserInterface(PPB_VIDEODECODER_DEV_INTERFACE));
-  return video_decoder_interface_ && CheckTestingInterface();
-}
-
-void TestVideoDecoder::RunTests(const std::string& filter) {
-  RUN_TEST(CreateFailure, filter);
-}
-
-void TestVideoDecoder::QuitMessageLoop() {
-  testing_interface_->QuitMessageLoop(instance_->pp_instance());
-}
-
-std::string TestVideoDecoder::TestCreateFailure() {
-  PP_Resource decoder = video_decoder_interface_->Create(
-      instance_->pp_instance(), 0, static_cast<PP_VideoDecoder_Profile>(-1));
-  if (decoder != 0)
-    return "Create: error detecting invalid context & configs";
-
-  PASS();
-}
diff --git a/ppapi/tests/test_video_decoder.h b/ppapi/tests/test_video_decoder.h
deleted file mode 100644
index e6d7e66..0000000
--- a/ppapi/tests/test_video_decoder.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef PPAPI_TESTS_TEST_VIDEO_DECODER_H_
-#define PPAPI_TESTS_TEST_VIDEO_DECODER_H_
-
-#include <string>
-
-#include "ppapi/c/dev/ppb_video_decoder_dev.h"
-#include "ppapi/c/pp_stdint.h"
-#include "ppapi/tests/test_case.h"
-
-class TestVideoDecoder : public TestCase {
- public:
-  explicit TestVideoDecoder(TestingInstance* instance) : TestCase(instance) {}
-
-  // TestCase implementation.
-  virtual bool Init();
-  virtual void RunTests(const std::string& filter);
-
-  void QuitMessageLoop();
-
- private:
-  std::string TestCreateFailure();
-
-  // Used by the tests that access the C API directly.
-  const PPB_VideoDecoder_Dev* video_decoder_interface_;
-};
-
-#endif  // PPAPI_TESTS_TEST_VIDEO_DECODER_H_
diff --git a/ppapi/tests/test_video_decoder_dev.cc b/ppapi/tests/test_video_decoder_dev.cc
new file mode 100644
index 0000000..86c2c13
--- /dev/null
+++ b/ppapi/tests/test_video_decoder_dev.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_video_decoder_dev.h"
+
+#include "ppapi/c/dev/ppb_video_decoder_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_var.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(VideoDecoderDev);
+
+bool TestVideoDecoderDev::Init() {
+  video_decoder_interface_ = static_cast<const PPB_VideoDecoder_Dev*>(
+      pp::Module::Get()->GetBrowserInterface(PPB_VIDEODECODER_DEV_INTERFACE));
+  return video_decoder_interface_ && CheckTestingInterface();
+}
+
+void TestVideoDecoderDev::RunTests(const std::string& filter) {
+  RUN_TEST(CreateFailure, filter);
+}
+
+void TestVideoDecoderDev::QuitMessageLoop() {
+  testing_interface_->QuitMessageLoop(instance_->pp_instance());
+}
+
+std::string TestVideoDecoderDev::TestCreateFailure() {
+  PP_Resource decoder = video_decoder_interface_->Create(
+      instance_->pp_instance(), 0, static_cast<PP_VideoDecoder_Profile>(-1));
+  if (decoder != 0)
+    return "Create: error detecting invalid context & configs";
+
+  PASS();
+}
diff --git a/ppapi/tests/test_video_decoder_dev.h b/ppapi/tests/test_video_decoder_dev.h
new file mode 100644
index 0000000..6a13ca3
--- /dev/null
+++ b/ppapi/tests/test_video_decoder_dev.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2012 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.
+
+#ifndef PPAPI_TESTS_TEST_VIDEO_DECODER_DEV_H_
+#define PPAPI_TESTS_TEST_VIDEO_DECODER_DEV_H_
+
+#include <string>
+
+#include "ppapi/c/dev/ppb_video_decoder_dev.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/tests/test_case.h"
+
+class TestVideoDecoderDev : public TestCase {
+ public:
+  explicit TestVideoDecoderDev(TestingInstance* instance)
+      : TestCase(instance) {}
+
+  // TestCase implementation.
+  virtual bool Init();
+  virtual void RunTests(const std::string& filter);
+
+  void QuitMessageLoop();
+
+ private:
+  std::string TestCreateFailure();
+
+  // Used by the tests that access the C API directly.
+  const PPB_VideoDecoder_Dev* video_decoder_interface_;
+};
+
+#endif  // PPAPI_TESTS_TEST_VIDEO_DECODER_DEV_H_
diff --git a/ppapi/thunk/ppb_media_stream_video_track_api.h b/ppapi/thunk/ppb_media_stream_video_track_api.h
index 9f18eaf..6cee06a 100644
--- a/ppapi/thunk/ppb_media_stream_video_track_api.h
+++ b/ppapi/thunk/ppb_media_stream_video_track_api.h
@@ -23,6 +23,10 @@
                            scoped_refptr<ppapi::TrackedCallback> callback) = 0;
   virtual int32_t RecycleFrame(PP_Resource frame) = 0;
   virtual void Close() = 0;
+  virtual int32_t GetEmptyFrame(
+      PP_Resource* frame,
+      scoped_refptr<ppapi::TrackedCallback> callback) = 0;
+  virtual int32_t PutFrame(PP_Resource frame) = 0;
 };
 
 }  // namespace thunk
diff --git a/ppapi/thunk/ppb_media_stream_video_track_thunk.cc b/ppapi/thunk/ppb_media_stream_video_track_thunk.cc
index c39ee1c..8a26a41 100644
--- a/ppapi/thunk/ppb_media_stream_video_track_thunk.cc
+++ b/ppapi/thunk/ppb_media_stream_video_track_thunk.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// From ppb_media_stream_video_track.idl modified Tue Mar 25 18:18:10 2014.
+// From ppb_media_stream_video_track.idl modified Mon Mar 31 14:40:45 2014.
 
 #include "ppapi/c/pp_completion_callback.h"
 #include "ppapi/c/pp_errors.h"
@@ -17,6 +17,14 @@
 
 namespace {
 
+PP_Resource Create(PP_Instance instance) {
+  VLOG(4) << "PPB_MediaStreamVideoTrack::Create()";
+  EnterResourceCreation enter(instance);
+  if (enter.failed())
+    return 0;
+  return enter.functions()->CreateMediaStreamVideoTrack(instance);
+}
+
 PP_Bool IsMediaStreamVideoTrack(PP_Resource resource) {
   VLOG(4) << "PPB_MediaStreamVideoTrack::IsMediaStreamVideoTrack()";
   EnterResource<PPB_MediaStreamVideoTrack_API> enter(resource, false);
@@ -90,6 +98,27 @@
   enter.object()->Close();
 }
 
+int32_t GetEmptyFrame(PP_Resource video_track,
+                      PP_Resource* frame,
+                      struct PP_CompletionCallback callback) {
+  VLOG(4) << "PPB_MediaStreamVideoTrack::GetEmptyFrame()";
+  EnterResource<PPB_MediaStreamVideoTrack_API> enter(video_track,
+                                                     callback,
+                                                     true);
+  if (enter.failed())
+    return enter.retval();
+  return enter.SetResult(enter.object()->GetEmptyFrame(frame,
+                                                       enter.callback()));
+}
+
+int32_t PutFrame(PP_Resource video_track, PP_Resource frame) {
+  VLOG(4) << "PPB_MediaStreamVideoTrack::PutFrame()";
+  EnterResource<PPB_MediaStreamVideoTrack_API> enter(video_track, true);
+  if (enter.failed())
+    return enter.retval();
+  return enter.object()->PutFrame(frame);
+}
+
 const PPB_MediaStreamVideoTrack_0_1 g_ppb_mediastreamvideotrack_thunk_0_1 = {
   &IsMediaStreamVideoTrack,
   &Configure,
@@ -101,6 +130,20 @@
   &Close
 };
 
+const PPB_MediaStreamVideoTrack_1_0 g_ppb_mediastreamvideotrack_thunk_1_0 = {
+  &Create,
+  &IsMediaStreamVideoTrack,
+  &Configure,
+  &GetAttrib,
+  &GetId,
+  &HasEnded,
+  &GetFrame,
+  &RecycleFrame,
+  &Close,
+  &GetEmptyFrame,
+  &PutFrame
+};
+
 }  // namespace
 
 PPAPI_THUNK_EXPORT const PPB_MediaStreamVideoTrack_0_1*
@@ -108,5 +151,10 @@
   return &g_ppb_mediastreamvideotrack_thunk_0_1;
 }
 
+PPAPI_THUNK_EXPORT const PPB_MediaStreamVideoTrack_1_0*
+    GetPPB_MediaStreamVideoTrack_1_0_Thunk() {
+  return &g_ppb_mediastreamvideotrack_thunk_1_0;
+}
+
 }  // namespace thunk
 }  // namespace ppapi
diff --git a/ppapi/thunk/ppb_video_decoder_api.h b/ppapi/thunk/ppb_video_decoder_api.h
index e26c887..c40845e 100644
--- a/ppapi/thunk/ppb_video_decoder_api.h
+++ b/ppapi/thunk/ppb_video_decoder_api.h
@@ -1,12 +1,13 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 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.
 
-#ifndef PPAPI_THUNK_VIDEO_DECODER_API_H_
-#define PPAPI_THUNK_VIDEO_DECODER_API_H_
+#ifndef PPAPI_THUNK_PPB_VIDEO_DECODER_API_H_
+#define PPAPI_THUNK_PPB_VIDEO_DECODER_API_H_
 
-#include "base/memory/ref_counted.h"
-#include "ppapi/c/dev/ppb_video_decoder_dev.h"
+#include "ppapi/c/pp_codecs.h"
+#include "ppapi/c/ppb_video_decoder.h"
+#include "ppapi/thunk/ppapi_thunk_export.h"
 
 namespace ppapi {
 
@@ -14,21 +15,26 @@
 
 namespace thunk {
 
-class PPB_VideoDecoder_API {
+class PPAPI_THUNK_EXPORT PPB_VideoDecoder_API {
  public:
   virtual ~PPB_VideoDecoder_API() {}
 
-  virtual int32_t Decode(const PP_VideoBitstreamBuffer_Dev* bitstream_buffer,
+  virtual int32_t Initialize(PP_Resource context,
+                             PP_VideoProfile profile,
+                             PP_Bool allow_software_fallback,
+                             scoped_refptr<TrackedCallback> callback) = 0;
+  virtual int32_t Decode(uint32_t decode_id,
+                         uint32_t size,
+                         const void* buffer,
                          scoped_refptr<TrackedCallback> callback) = 0;
-  virtual void AssignPictureBuffers(uint32_t no_of_buffers,
-                                    const PP_PictureBuffer_Dev* buffers) = 0;
-  virtual void ReusePictureBuffer(int32_t picture_buffer_id) = 0;
+  virtual int32_t GetPicture(PP_VideoPicture* picture,
+                             scoped_refptr<TrackedCallback> callback) = 0;
+  virtual void RecyclePicture(const PP_VideoPicture* picture) = 0;
   virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) = 0;
   virtual int32_t Reset(scoped_refptr<TrackedCallback> callback) = 0;
-  virtual void Destroy() = 0;
 };
 
 }  // namespace thunk
 }  // namespace ppapi
 
-#endif  // PPAPI_THUNK_VIDEO_DECODER_API_H_
+#endif  // PPAPI_THUNK_PPB_VIDEO_DECODER_API_H_
diff --git a/ppapi/thunk/ppb_video_decoder_dev_api.h b/ppapi/thunk/ppb_video_decoder_dev_api.h
new file mode 100644
index 0000000..d652f5f
--- /dev/null
+++ b/ppapi/thunk/ppb_video_decoder_dev_api.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef PPAPI_THUNK_VIDEO_DECODER_DEV_API_H_
+#define PPAPI_THUNK_VIDEO_DECODER_DEV_API_H_
+
+#include "base/memory/ref_counted.h"
+#include "ppapi/c/dev/ppb_video_decoder_dev.h"
+
+namespace ppapi {
+
+class TrackedCallback;
+
+namespace thunk {
+
+class PPB_VideoDecoder_Dev_API {
+ public:
+  virtual ~PPB_VideoDecoder_Dev_API() {}
+
+  virtual int32_t Decode(const PP_VideoBitstreamBuffer_Dev* bitstream_buffer,
+                         scoped_refptr<TrackedCallback> callback) = 0;
+  virtual void AssignPictureBuffers(uint32_t no_of_buffers,
+                                    const PP_PictureBuffer_Dev* buffers) = 0;
+  virtual void ReusePictureBuffer(int32_t picture_buffer_id) = 0;
+  virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) = 0;
+  virtual int32_t Reset(scoped_refptr<TrackedCallback> callback) = 0;
+  virtual void Destroy() = 0;
+};
+
+}  // namespace thunk
+}  // namespace ppapi
+
+#endif  // PPAPI_THUNK_VIDEO_DECODER_DEV_API_H_
diff --git a/ppapi/thunk/ppb_video_decoder_dev_thunk.cc b/ppapi/thunk/ppb_video_decoder_dev_thunk.cc
new file mode 100644
index 0000000..bf15dd8
--- /dev/null
+++ b/ppapi/thunk/ppb_video_decoder_dev_thunk.cc
@@ -0,0 +1,96 @@
+// 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.
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/shared_impl/tracked_callback.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_video_decoder_dev_api.h"
+#include "ppapi/thunk/resource_creation_api.h"
+#include "ppapi/thunk/thunk.h"
+
+namespace ppapi {
+namespace thunk {
+
+namespace {
+
+typedef EnterResource<PPB_VideoDecoder_Dev_API> EnterVideoDecoder;
+
+PP_Resource Create(PP_Instance instance,
+                   PP_Resource graphics_3d,
+                   PP_VideoDecoder_Profile profile) {
+  EnterResourceCreation enter(instance);
+  if (enter.failed())
+    return 0;
+  return enter.functions()->CreateVideoDecoderDev(
+      instance, graphics_3d, profile);
+}
+
+PP_Bool IsVideoDecoder(PP_Resource resource) {
+  EnterVideoDecoder enter(resource, false);
+  return PP_FromBool(enter.succeeded());
+}
+
+int32_t Decode(PP_Resource video_decoder,
+               const PP_VideoBitstreamBuffer_Dev* bitstream_buffer,
+               PP_CompletionCallback callback) {
+  EnterVideoDecoder enter(video_decoder, callback, true);
+  if (enter.failed())
+    return enter.retval();
+  return enter.SetResult(
+      enter.object()->Decode(bitstream_buffer, enter.callback()));
+}
+
+void AssignPictureBuffers(PP_Resource video_decoder,
+                          uint32_t no_of_buffers,
+                          const PP_PictureBuffer_Dev* buffers) {
+  EnterVideoDecoder enter(video_decoder, true);
+  if (enter.succeeded())
+    enter.object()->AssignPictureBuffers(no_of_buffers, buffers);
+}
+
+void ReusePictureBuffer(PP_Resource video_decoder, int32_t picture_buffer_id) {
+  EnterVideoDecoder enter(video_decoder, true);
+  if (enter.succeeded())
+    enter.object()->ReusePictureBuffer(picture_buffer_id);
+}
+
+int32_t Flush(PP_Resource video_decoder, PP_CompletionCallback callback) {
+  EnterVideoDecoder enter(video_decoder, callback, true);
+  if (enter.failed())
+    return enter.retval();
+  return enter.SetResult(enter.object()->Flush(enter.callback()));
+}
+
+int32_t Reset(PP_Resource video_decoder, PP_CompletionCallback callback) {
+  EnterVideoDecoder enter(video_decoder, callback, true);
+  if (enter.failed())
+    return enter.retval();
+  return enter.SetResult(enter.object()->Reset(enter.callback()));
+}
+
+void Destroy(PP_Resource video_decoder) {
+  EnterVideoDecoder enter(video_decoder, true);
+  if (enter.succeeded())
+    enter.object()->Destroy();
+}
+
+const PPB_VideoDecoder_Dev g_ppb_videodecoder_dev_thunk = {
+  &Create,
+  &IsVideoDecoder,
+  &Decode,
+  &AssignPictureBuffers,
+  &ReusePictureBuffer,
+  &Flush,
+  &Reset,
+  &Destroy
+};
+
+}  // namespace
+
+const PPB_VideoDecoder_Dev_0_16* GetPPB_VideoDecoder_Dev_0_16_Thunk() {
+  return &g_ppb_videodecoder_dev_thunk;
+}
+
+}  // namespace thunk
+}  // namespace ppapi
diff --git a/ppapi/thunk/ppb_video_decoder_thunk.cc b/ppapi/thunk/ppb_video_decoder_thunk.cc
index 2472d8a..d84617c 100644
--- a/ppapi/thunk/ppb_video_decoder_thunk.cc
+++ b/ppapi/thunk/ppb_video_decoder_thunk.cc
@@ -1,95 +1,119 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 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.
 
+// From ppb_video_decoder.idl modified Tue May  6 05:06:35 2014.
+
+#include "ppapi/c/pp_completion_callback.h"
 #include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_video_decoder.h"
 #include "ppapi/shared_impl/tracked_callback.h"
 #include "ppapi/thunk/enter.h"
-#include "ppapi/thunk/thunk.h"
+#include "ppapi/thunk/ppapi_thunk_export.h"
 #include "ppapi/thunk/ppb_video_decoder_api.h"
-#include "ppapi/thunk/resource_creation_api.h"
 
 namespace ppapi {
 namespace thunk {
 
 namespace {
 
-typedef EnterResource<PPB_VideoDecoder_API> EnterVideoDecoder;
-
-PP_Resource Create(PP_Instance instance,
-                   PP_Resource graphics_3d,
-                   PP_VideoDecoder_Profile profile) {
+PP_Resource Create(PP_Instance instance) {
+  VLOG(4) << "PPB_VideoDecoder::Create()";
   EnterResourceCreation enter(instance);
   if (enter.failed())
     return 0;
-  return enter.functions()->CreateVideoDecoder(instance, graphics_3d, profile);
+  return enter.functions()->CreateVideoDecoder(instance);
 }
 
 PP_Bool IsVideoDecoder(PP_Resource resource) {
-  EnterVideoDecoder enter(resource, false);
+  VLOG(4) << "PPB_VideoDecoder::IsVideoDecoder()";
+  EnterResource<PPB_VideoDecoder_API> enter(resource, false);
   return PP_FromBool(enter.succeeded());
 }
 
-int32_t Decode(PP_Resource video_decoder,
-               const PP_VideoBitstreamBuffer_Dev* bitstream_buffer,
-               PP_CompletionCallback callback) {
-  EnterVideoDecoder enter(video_decoder, callback, true);
+int32_t Initialize(PP_Resource video_decoder,
+                   PP_Resource graphics3d_context,
+                   PP_VideoProfile profile,
+                   PP_Bool allow_software_fallback,
+                   struct PP_CompletionCallback callback) {
+  VLOG(4) << "PPB_VideoDecoder::Initialize()";
+  EnterResource<PPB_VideoDecoder_API> enter(video_decoder, callback, true);
   if (enter.failed())
     return enter.retval();
-  return enter.SetResult(enter.object()->Decode(bitstream_buffer,
+  return enter.SetResult(enter.object()->Initialize(graphics3d_context,
+                                                    profile,
+                                                    allow_software_fallback,
+                                                    enter.callback()));
+}
+
+int32_t Decode(PP_Resource video_decoder,
+               uint32_t decode_id,
+               uint32_t size,
+               const void* buffer,
+               struct PP_CompletionCallback callback) {
+  VLOG(4) << "PPB_VideoDecoder::Decode()";
+  EnterResource<PPB_VideoDecoder_API> enter(video_decoder, callback, true);
+  if (enter.failed())
+    return enter.retval();
+  return enter.SetResult(enter.object()->Decode(decode_id,
+                                                size,
+                                                buffer,
                                                 enter.callback()));
 }
 
-void AssignPictureBuffers(PP_Resource video_decoder,
-                          uint32_t no_of_buffers,
-                          const PP_PictureBuffer_Dev* buffers) {
-  EnterVideoDecoder enter(video_decoder, true);
-  if (enter.succeeded())
-    enter.object()->AssignPictureBuffers(no_of_buffers, buffers);
+int32_t GetPicture(PP_Resource video_decoder,
+                   struct PP_VideoPicture* picture,
+                   struct PP_CompletionCallback callback) {
+  VLOG(4) << "PPB_VideoDecoder::GetPicture()";
+  EnterResource<PPB_VideoDecoder_API> enter(video_decoder, callback, true);
+  if (enter.failed())
+    return enter.retval();
+  return enter.SetResult(enter.object()->GetPicture(picture, enter.callback()));
 }
 
-void ReusePictureBuffer(PP_Resource video_decoder, int32_t picture_buffer_id) {
-  EnterVideoDecoder enter(video_decoder, true);
-  if (enter.succeeded())
-    enter.object()->ReusePictureBuffer(picture_buffer_id);
+void RecyclePicture(PP_Resource video_decoder,
+                    const struct PP_VideoPicture* picture) {
+  VLOG(4) << "PPB_VideoDecoder::RecyclePicture()";
+  EnterResource<PPB_VideoDecoder_API> enter(video_decoder, true);
+  if (enter.failed())
+    return;
+  enter.object()->RecyclePicture(picture);
 }
 
-int32_t Flush(PP_Resource video_decoder, PP_CompletionCallback callback) {
-  EnterVideoDecoder enter(video_decoder, callback, true);
+int32_t Flush(PP_Resource video_decoder,
+              struct PP_CompletionCallback callback) {
+  VLOG(4) << "PPB_VideoDecoder::Flush()";
+  EnterResource<PPB_VideoDecoder_API> enter(video_decoder, callback, true);
   if (enter.failed())
     return enter.retval();
   return enter.SetResult(enter.object()->Flush(enter.callback()));
 }
 
 int32_t Reset(PP_Resource video_decoder,
-              PP_CompletionCallback callback) {
-  EnterVideoDecoder enter(video_decoder, callback, true);
+              struct PP_CompletionCallback callback) {
+  VLOG(4) << "PPB_VideoDecoder::Reset()";
+  EnterResource<PPB_VideoDecoder_API> enter(video_decoder, callback, true);
   if (enter.failed())
     return enter.retval();
   return enter.SetResult(enter.object()->Reset(enter.callback()));
 }
 
-void Destroy(PP_Resource video_decoder) {
-  EnterVideoDecoder enter(video_decoder, true);
-  if (enter.succeeded())
-    enter.object()->Destroy();
-}
-
-const PPB_VideoDecoder_Dev g_ppb_videodecoder_thunk = {
+const PPB_VideoDecoder_0_1 g_ppb_videodecoder_thunk_0_1 = {
   &Create,
   &IsVideoDecoder,
+  &Initialize,
   &Decode,
-  &AssignPictureBuffers,
-  &ReusePictureBuffer,
+  &GetPicture,
+  &RecyclePicture,
   &Flush,
-  &Reset,
-  &Destroy
+  &Reset
 };
 
 }  // namespace
 
-const PPB_VideoDecoder_Dev_0_16* GetPPB_VideoDecoder_Dev_0_16_Thunk() {
-  return &g_ppb_videodecoder_thunk;
+PPAPI_THUNK_EXPORT const PPB_VideoDecoder_0_1*
+    GetPPB_VideoDecoder_0_1_Thunk() {
+  return &g_ppb_videodecoder_thunk_0_1;
 }
 
 }  // namespace thunk
diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h
index 0c3dd42..498d0d8 100644
--- a/ppapi/thunk/resource_creation_api.h
+++ b/ppapi/thunk/resource_creation_api.h
@@ -141,6 +141,7 @@
                                             PP_ImageDataFormat format,
                                             const PP_Size* size,
                                             PP_Bool init_to_zero) = 0;
+  virtual PP_Resource CreateMediaStreamVideoTrack(PP_Instance instance) = 0;
   virtual PP_Resource CreateNetAddressFromIPv4Address(
       PP_Instance instance,
       const PP_NetAddress_IPv4* ipv4_addr) = 0;
@@ -184,7 +185,7 @@
                                       PP_Bool vertical) = 0;
   virtual PP_Resource CreateTalk(PP_Instance instance) = 0;
   virtual PP_Resource CreateVideoCapture(PP_Instance instance) = 0;
-  virtual PP_Resource CreateVideoDecoder(
+  virtual PP_Resource CreateVideoDecoderDev(
       PP_Instance instance,
       PP_Resource context3d_id,
       PP_VideoDecoder_Profile profile) = 0;
diff --git a/printing/android/java/src/org/chromium/printing/PrintingContext.java b/printing/android/java/src/org/chromium/printing/PrintingContext.java
index 0ade96f..e50f0ce 100644
--- a/printing/android/java/src/org/chromium/printing/PrintingContext.java
+++ b/printing/android/java/src/org/chromium/printing/PrintingContext.java
@@ -67,7 +67,7 @@
     }
 
     @CalledByNative
-    public static PrintingContext create(int nativeObjectPointer) {
+    public static PrintingContext create(long nativeObjectPointer) {
         ThreadUtils.assertOnUiThread();
         return new PrintingContext(nativeObjectPointer);
     }
@@ -132,4 +132,4 @@
     private native void nativeAskUserForSettingsReply(
             long nativePrintingContextAndroid,
             boolean success);
-}
\ No newline at end of file
+}
diff --git a/printing/backend/cups_helper.cc b/printing/backend/cups_helper.cc
index 9215bb9..296b95e 100644
--- a/printing/backend/cups_helper.cc
+++ b/printing/backend/cups_helper.cc
@@ -314,7 +314,7 @@
     return;
 
   int port = print_server_url.IntPort();
-  if (port == url_parse::PORT_UNSPECIFIED)
+  if (port == url::PORT_UNSPECIFIED)
     port = kDefaultIPPServerPort;
 
   http_ = httpConnectEncrypt(print_server_url.host().c_str(), port, encryption);
diff --git a/printing/printing.gyp b/printing/printing.gyp
index aea2c2e..792f5df 100644
--- a/printing/printing.gyp
+++ b/printing/printing.gyp
@@ -247,8 +247,7 @@
         }],
         [ 'os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
diff --git a/printing/printing.target.darwin-arm.mk b/printing/printing.target.darwin-arm.mk
index 2cf6295..c37ac87 100644
--- a/printing/printing.target.darwin-arm.mk
+++ b/printing/printing.target.darwin-arm.mk
@@ -66,7 +66,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -115,11 +114,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -191,7 +185,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -240,11 +233,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/printing/printing.target.darwin-arm64.mk b/printing/printing.target.darwin-arm64.mk
index 56cd6a0..16f4fb2 100644
--- a/printing/printing.target.darwin-arm64.mk
+++ b/printing/printing.target.darwin-arm64.mk
@@ -111,11 +111,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -231,11 +226,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/printing/printing.target.darwin-mips.mk b/printing/printing.target.darwin-mips.mk
index 2f6c5c1..93075bb 100644
--- a/printing/printing.target.darwin-mips.mk
+++ b/printing/printing.target.darwin-mips.mk
@@ -114,11 +114,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -238,11 +233,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/printing/printing.target.darwin-x86.mk b/printing/printing.target.darwin-x86.mk
index cf78473..6340aa7 100644
--- a/printing/printing.target.darwin-x86.mk
+++ b/printing/printing.target.darwin-x86.mk
@@ -68,7 +68,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -116,11 +115,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -193,7 +187,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -241,11 +234,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/printing/printing.target.darwin-x86_64.mk b/printing/printing.target.darwin-x86_64.mk
index f1ffd07..84a71ce 100644
--- a/printing/printing.target.darwin-x86_64.mk
+++ b/printing/printing.target.darwin-x86_64.mk
@@ -68,7 +68,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -116,11 +115,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -193,7 +187,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -241,11 +234,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/printing/printing.target.linux-arm.mk b/printing/printing.target.linux-arm.mk
index 2cf6295..c37ac87 100644
--- a/printing/printing.target.linux-arm.mk
+++ b/printing/printing.target.linux-arm.mk
@@ -66,7 +66,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -115,11 +114,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -191,7 +185,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -240,11 +233,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/printing/printing.target.linux-arm64.mk b/printing/printing.target.linux-arm64.mk
index 56cd6a0..16f4fb2 100644
--- a/printing/printing.target.linux-arm64.mk
+++ b/printing/printing.target.linux-arm64.mk
@@ -111,11 +111,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -231,11 +226,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/printing/printing.target.linux-mips.mk b/printing/printing.target.linux-mips.mk
index 2f6c5c1..93075bb 100644
--- a/printing/printing.target.linux-mips.mk
+++ b/printing/printing.target.linux-mips.mk
@@ -114,11 +114,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -238,11 +233,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/printing/printing.target.linux-x86.mk b/printing/printing.target.linux-x86.mk
index cf78473..6340aa7 100644
--- a/printing/printing.target.linux-x86.mk
+++ b/printing/printing.target.linux-x86.mk
@@ -68,7 +68,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -116,11 +115,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -193,7 +187,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -241,11 +234,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/printing/printing.target.linux-x86_64.mk b/printing/printing.target.linux-x86_64.mk
index f1ffd07..84a71ce 100644
--- a/printing/printing.target.linux-x86_64.mk
+++ b/printing/printing.target.linux-x86_64.mk
@@ -68,7 +68,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -116,11 +115,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -193,7 +187,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -241,11 +234,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/printing/printing_jni_headers.target.darwin-arm.mk b/printing/printing_jni_headers.target.darwin-arm.mk
index 5a3440a..cec312d 100644
--- a/printing/printing_jni_headers.target.darwin-arm.mk
+++ b/printing/printing_jni_headers.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "printing_printing_gyp_printing_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/printing/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/printing/PrintingContext.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/printing/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -54,7 +55,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/printing/printing_jni_headers.target.darwin-arm64.mk b/printing/printing_jni_headers.target.darwin-arm64.mk
index 5a5bd8a..85eb7d8 100644
--- a/printing/printing_jni_headers.target.darwin-arm64.mk
+++ b/printing/printing_jni_headers.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "printing_printing_gyp_printing_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/printing/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/printing/PrintingContext.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/printing/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/printing/printing_jni_headers.target.darwin-mips.mk b/printing/printing_jni_headers.target.darwin-mips.mk
index 01982be..1196a9e 100644
--- a/printing/printing_jni_headers.target.darwin-mips.mk
+++ b/printing/printing_jni_headers.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "printing_printing_gyp_printing_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/printing/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/printing/PrintingContext.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/printing/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/printing/printing_jni_headers.target.darwin-x86.mk b/printing/printing_jni_headers.target.darwin-x86.mk
index 2d2d6b8..e9db976 100644
--- a/printing/printing_jni_headers.target.darwin-x86.mk
+++ b/printing/printing_jni_headers.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "printing_printing_gyp_printing_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/printing/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/printing/PrintingContext.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/printing/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -56,7 +57,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/printing/printing_jni_headers.target.darwin-x86_64.mk b/printing/printing_jni_headers.target.darwin-x86_64.mk
index 5d2bbf0..ef5e27b 100644
--- a/printing/printing_jni_headers.target.darwin-x86_64.mk
+++ b/printing/printing_jni_headers.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "printing_printing_gyp_printing_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/printing/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/printing/PrintingContext.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/printing/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -56,7 +57,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/printing/printing_jni_headers.target.linux-arm.mk b/printing/printing_jni_headers.target.linux-arm.mk
index 5a3440a..cec312d 100644
--- a/printing/printing_jni_headers.target.linux-arm.mk
+++ b/printing/printing_jni_headers.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "printing_printing_gyp_printing_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/printing/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/printing/PrintingContext.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/printing/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -54,7 +55,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +138,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/printing/printing_jni_headers.target.linux-arm64.mk b/printing/printing_jni_headers.target.linux-arm64.mk
index 5a5bd8a..85eb7d8 100644
--- a/printing/printing_jni_headers.target.linux-arm64.mk
+++ b/printing/printing_jni_headers.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "printing_printing_gyp_printing_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/printing/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/printing/PrintingContext.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/printing/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/printing/printing_jni_headers.target.linux-mips.mk b/printing/printing_jni_headers.target.linux-mips.mk
index 01982be..1196a9e 100644
--- a/printing/printing_jni_headers.target.linux-mips.mk
+++ b/printing/printing_jni_headers.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "printing_printing_gyp_printing_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/printing/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/printing/PrintingContext.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/printing/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/printing/printing_jni_headers.target.linux-x86.mk b/printing/printing_jni_headers.target.linux-x86.mk
index 2d2d6b8..e9db976 100644
--- a/printing/printing_jni_headers.target.linux-x86.mk
+++ b/printing/printing_jni_headers.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "printing_printing_gyp_printing_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/printing/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/printing/PrintingContext.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/printing/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -56,7 +57,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/printing/printing_jni_headers.target.linux-x86_64.mk b/printing/printing_jni_headers.target.linux-x86_64.mk
index 5d2bbf0..ef5e27b 100644
--- a/printing/printing_jni_headers.target.linux-x86_64.mk
+++ b/printing/printing_jni_headers.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "printing_printing_gyp_printing_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/printing/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/printing/PrintingContext.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/printing/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/printing/jni/PrintingContext_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -56,7 +57,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +140,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/remoting/OWNERS b/remoting/OWNERS
index 861085c..e93827b 100644
--- a/remoting/OWNERS
+++ b/remoting/OWNERS
@@ -1,3 +1,4 @@
+dcaiafa@chromium.org
 garykac@chromium.org
 jamiewalch@chromium.org
 lambroslambrou@chromium.org
diff --git a/remoting/android/java/README b/remoting/android/java/README
index 6e6720b..9d72048 100644
--- a/remoting/android/java/README
+++ b/remoting/android/java/README
@@ -1,7 +1,8 @@
-The icon:
+The icons:
 ic_action_keyboard.png
+ic_action_full_screen.png
 
-was taken from the icon pack at:
+were taken from the icon pack at:
 https://developer.android.com/design/downloads/index.html
 
 which carries the following notice:
diff --git a/remoting/android/java/res/drawable-hdpi/ic_action_full_screen.png b/remoting/android/java/res/drawable-hdpi/ic_action_full_screen.png
new file mode 100644
index 0000000..22f30d3
--- /dev/null
+++ b/remoting/android/java/res/drawable-hdpi/ic_action_full_screen.png
Binary files differ
diff --git a/remoting/android/java/res/drawable-mdpi/ic_action_full_screen.png b/remoting/android/java/res/drawable-mdpi/ic_action_full_screen.png
new file mode 100644
index 0000000..e4a9ff0
--- /dev/null
+++ b/remoting/android/java/res/drawable-mdpi/ic_action_full_screen.png
Binary files differ
diff --git a/remoting/android/java/res/drawable-xhdpi/ic_action_full_screen.png b/remoting/android/java/res/drawable-xhdpi/ic_action_full_screen.png
new file mode 100644
index 0000000..6d90c07
--- /dev/null
+++ b/remoting/android/java/res/drawable-xhdpi/ic_action_full_screen.png
Binary files differ
diff --git a/remoting/android/java/res/drawable-xxhdpi/ic_action_full_screen.png b/remoting/android/java/res/drawable-xxhdpi/ic_action_full_screen.png
new file mode 100644
index 0000000..e8dff1e
--- /dev/null
+++ b/remoting/android/java/res/drawable-xxhdpi/ic_action_full_screen.png
Binary files differ
diff --git a/remoting/android/java/res/menu/desktop_actionbar.xml b/remoting/android/java/res/menu/desktop_actionbar.xml
index f737132..3b4cc64 100644
--- a/remoting/android/java/res/menu/desktop_actionbar.xml
+++ b/remoting/android/java/res/menu/desktop_actionbar.xml
@@ -12,8 +12,8 @@
             android:icon="@drawable/ic_action_keyboard"
             android:showAsAction="ifRoom"/>
     <item android:id="@+id/actionbar_hide"
-            android:title="@string/close"
-            android:icon="@android:drawable/ic_menu_close_clear_cancel"
+            android:title="@string/full_screen"
+            android:icon="@drawable/ic_action_full_screen"
             android:showAsAction="ifRoom"/>
     <item android:id="@+id/actionbar_send_ctrl_alt_del"
             android:title="@string/send_ctrl_alt_del"
diff --git a/remoting/client/jni/chromoting_jni_runtime.cc b/remoting/client/jni/chromoting_jni_runtime.cc
index 06cd7ff..467213e 100644
--- a/remoting/client/jni/chromoting_jni_runtime.cc
+++ b/remoting/client/jni/chromoting_jni_runtime.cc
@@ -53,17 +53,20 @@
 }
 
 static jstring GetApiKey(JNIEnv* env, jclass clazz) {
-  return env->NewStringUTF(google_apis::GetAPIKey().c_str());
+  return ConvertUTF8ToJavaString(
+      env, google_apis::GetAPIKey().c_str()).Release();
 }
 
 static jstring GetClientId(JNIEnv* env, jclass clazz) {
-  return env->NewStringUTF(
-      google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING).c_str());
+  return ConvertUTF8ToJavaString(
+      env, google_apis::GetOAuth2ClientID(
+          google_apis::CLIENT_REMOTING).c_str()).Release();
 }
 
 static jstring GetClientSecret(JNIEnv* env, jclass clazz) {
-  return env->NewStringUTF(
-      google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_REMOTING).c_str());
+  return ConvertUTF8ToJavaString(
+      env, google_apis::GetOAuth2ClientSecret(
+          google_apis::CLIENT_REMOTING).c_str()).Release();
 }
 
 static void Connect(JNIEnv* env,
diff --git a/remoting/client/plugin/media_source_video_renderer.cc b/remoting/client/plugin/media_source_video_renderer.cc
index f14a61e..5326754 100644
--- a/remoting/client/plugin/media_source_video_renderer.cc
+++ b/remoting/client/plugin/media_source_video_renderer.cc
@@ -8,6 +8,7 @@
 
 #include "base/callback_helpers.h"
 #include "base/logging.h"
+#include "base/time/time.h"
 #include "remoting/proto/video.pb.h"
 #include "remoting/protocol/session_config.h"
 #include "third_party/libwebm/source/mkvmuxer.hpp"
@@ -20,7 +21,7 @@
  public:
   typedef std::vector<uint8_t> DataBuffer;
 
-  VideoWriter(const webrtc::DesktopSize& frame_size);
+  explicit VideoWriter(const webrtc::DesktopSize& frame_size);
   virtual ~VideoWriter();
 
   const webrtc::DesktopSize& size() { return frame_size_; }
@@ -52,7 +53,24 @@
   segment_.reset(new mkvmuxer::Segment());
   segment_->Init(this);
   segment_->set_mode(mkvmuxer::Segment::kLive);
+
+  // DateUTC is specified in nanoseconds from 0:00 on January 1st, 2001.
+  base::Time::Exploded millennium_exploded;
+  memset(&millennium_exploded, 0, sizeof(millennium_exploded));
+  millennium_exploded.year = 2001;
+  millennium_exploded.month = 1;
+  millennium_exploded.day_of_month = 1;
+  segment_->GetSegmentInfo()->set_date_utc(
+      (base::Time::Now() - base::Time::FromUTCExploded(millennium_exploded))
+          .InMicroseconds() *
+      base::Time::kNanosecondsPerMicrosecond);
+
   segment_->AddVideoTrack(frame_size_.width(), frame_size_.height(), 1);
+  mkvmuxer::VideoTrack* video_track =
+      reinterpret_cast<mkvmuxer::VideoTrack*>(segment_->GetTrackByNumber(1));
+  video_track->set_frame_rate(base::Time::kNanosecondsPerSecond /
+                              kFrameIntervalNs);
+  video_track->set_default_duration(base::Time::kNanosecondsPerSecond);
   mkvmuxer::SegmentInfo* const info = segment_->GetSegmentInfo();
   info->set_writing_app("ChromotingViewer");
   info->set_muxing_app("ChromotingViewer");
diff --git a/remoting/client/plugin/media_source_video_renderer.h b/remoting/client/plugin/media_source_video_renderer.h
index 2df7758..25d7d07 100644
--- a/remoting/client/plugin/media_source_video_renderer.h
+++ b/remoting/client/plugin/media_source_video_renderer.h
@@ -41,7 +41,7 @@
     virtual void OnMediaSourceData(uint8_t* buffer, size_t buffer_size) = 0;
   };
 
-  MediaSourceVideoRenderer(Delegate* delegate);
+  explicit MediaSourceVideoRenderer(Delegate* data_forwarder);
   virtual ~MediaSourceVideoRenderer();
 
   // VideoRenderer interface.
diff --git a/remoting/client/plugin/pepper_input_handler.cc b/remoting/client/plugin/pepper_input_handler.cc
index 9069f1a..60a2746 100644
--- a/remoting/client/plugin/pepper_input_handler.cc
+++ b/remoting/client/plugin/pepper_input_handler.cc
@@ -75,6 +75,9 @@
 
     case PP_INPUTEVENT_TYPE_MOUSEDOWN:
     case PP_INPUTEVENT_TYPE_MOUSEUP: {
+      if (!has_focus_)
+        return false;
+
       pp::MouseInputEvent pp_mouse_event(event);
       protocol::MouseEvent mouse_event;
       switch (pp_mouse_event.GetButton()) {
@@ -111,6 +114,9 @@
     case PP_INPUTEVENT_TYPE_MOUSEMOVE:
     case PP_INPUTEVENT_TYPE_MOUSEENTER:
     case PP_INPUTEVENT_TYPE_MOUSELEAVE: {
+      if (!has_focus_)
+        return false;
+
       pp::MouseInputEvent pp_mouse_event(event);
       protocol::MouseEvent mouse_event;
       mouse_event.set_x(pp_mouse_event.GetPosition().x());
@@ -128,6 +134,9 @@
     }
 
     case PP_INPUTEVENT_TYPE_WHEEL: {
+      if (!has_focus_)
+        return false;
+
       pp::WheelInputEvent pp_wheel_event(event);
 
       // Don't handle scroll-by-page events, for now.
diff --git a/remoting/codec/video_encoder_vpx.cc b/remoting/codec/video_encoder_vpx.cc
index 0977564..59bb5dc 100644
--- a/remoting/codec/video_encoder_vpx.cc
+++ b/remoting/codec/video_encoder_vpx.cc
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/sys_info.h"
-#include "base/time/time.h"
 #include "media/base/yuv_convert.h"
 #include "remoting/base/util.h"
 #include "remoting/proto/video.pb.h"
@@ -29,6 +28,30 @@
 // map for the encoder.
 const int kMacroBlockSize = 16;
 
+void SetCommonCodecParameters(const webrtc::DesktopSize& size,
+                              vpx_codec_enc_cfg_t* config) {
+  // Use millisecond granularity time base.
+  config->g_timebase.num = 1;
+  config->g_timebase.den = 1000;
+
+  // Adjust default target bit-rate to account for actual desktop size.
+  config->rc_target_bitrate = size.width() * size.height() *
+      config->rc_target_bitrate / config->g_w / config->g_h;
+
+  config->g_w = size.width();
+  config->g_h = size.height();
+  config->g_pass = VPX_RC_ONE_PASS;
+
+  // Start emitting packets immediately.
+  config->g_lag_in_frames = 0;
+
+  // Using 2 threads gives a great boost in performance for most systems with
+  // adequate processing power. NB: Going to multiple threads on low end
+  // windows systems can really hurt performance.
+  // http://crbug.com/99179
+  config->g_threads = (base::SysInfo::NumberOfProcessors() > 2) ? 2 : 1;
+}
+
 ScopedVpxCodec CreateVP8Codec(const webrtc::DesktopSize& size) {
   ScopedVpxCodec codec(new vpx_codec_ctx_t);
 
@@ -40,26 +63,16 @@
   if (ret != VPX_CODEC_OK)
     return ScopedVpxCodec();
 
-  config.rc_target_bitrate = size.width() * size.height() *
-      config.rc_target_bitrate / config.g_w / config.g_h;
-  config.g_w = size.width();
-  config.g_h = size.height();
-  config.g_pass = VPX_RC_ONE_PASS;
+  SetCommonCodecParameters(size, &config);
 
   // Value of 2 means using the real time profile. This is basically a
   // redundant option since we explicitly select real time mode when doing
   // encoding.
   config.g_profile = 2;
 
-  // Using 2 threads gives a great boost in performance for most systems with
-  // adequate processing power. NB: Going to multiple threads on low end
-  // windows systems can really hurt performance.
-  // http://crbug.com/99179
-  config.g_threads = (base::SysInfo::NumberOfProcessors() > 2) ? 2 : 1;
+  // Clamping the quantizer constrains the worst-case quality and CPU usage.
   config.rc_min_quantizer = 20;
   config.rc_max_quantizer = 30;
-  config.g_timebase.num = 1;
-  config.g_timebase.den = 20;
 
   if (vpx_codec_enc_init(codec.get(), algo, &config, 0))
     return ScopedVpxCodec();
@@ -88,19 +101,13 @@
   if (ret != VPX_CODEC_OK)
     return ScopedVpxCodec();
 
-  //config.rc_target_bitrate = size.width() * size.height() *
-  //    config.rc_target_bitrate / config.g_w / config.g_h;
-  config.g_w = size.width();
-  config.g_h = size.height();
-  config.g_pass = VPX_RC_ONE_PASS;
+  SetCommonCodecParameters(size, &config);
 
-  // Only the default profile is currently supported for VP9 encoding.
+  // Configure VP9 for I420 source frames.
   config.g_profile = 0;
 
-  // Start emitting packets immediately.
-  config.g_lag_in_frames = 0;
-
-  // Prevent VP9 from ruining output quality with quantization.
+  // Disable quantization entirely, putting the encoder in "lossless" mode.
+  config.rc_min_quantizer = 0;
   config.rc_max_quantizer = 0;
 
   if (vpx_codec_enc_init(codec.get(), algo, &config, 0))
@@ -142,13 +149,16 @@
   DCHECK_LE(32, frame.size().width());
   DCHECK_LE(32, frame.size().height());
 
-  base::Time encode_start_time = base::Time::Now();
+  base::TimeTicks encode_start_time = base::TimeTicks::Now();
 
   if (!codec_ ||
       !frame.size().equals(webrtc::DesktopSize(image_->w, image_->h))) {
     bool ret = Initialize(frame.size());
     // TODO(hclam): Handle error better.
     CHECK(ret) << "Initialization of encoder failed";
+
+    // Set now as the base for timestamp calculation.
+    timestamp_base_ = encode_start_time;
   }
 
   // Convert the updated capture data ready for encode.
@@ -168,17 +178,14 @@
   }
 
   // Do the actual encoding.
-  vpx_codec_err_t ret = vpx_codec_encode(codec_.get(), image_.get(),
-                                         last_timestamp_,
-                                         1, 0, VPX_DL_REALTIME);
+  int timestamp = (encode_start_time - timestamp_base_).InMilliseconds();
+  vpx_codec_err_t ret = vpx_codec_encode(
+      codec_.get(), image_.get(), timestamp, 1, 0, VPX_DL_REALTIME);
   DCHECK_EQ(ret, VPX_CODEC_OK)
       << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n"
       << "Details: " << vpx_codec_error(codec_.get()) << "\n"
       << vpx_codec_error_detail(codec_.get());
 
-  // TODO(hclam): Apply the proper timestamp here.
-  last_timestamp_ += 50;
-
   // Read the encoded data.
   vpx_codec_iter_t iter = NULL;
   bool got_data = false;
@@ -209,7 +216,7 @@
   packet->mutable_format()->set_screen_height(frame.size().height());
   packet->set_capture_time_ms(frame.capture_time_ms());
   packet->set_encode_time_ms(
-      (base::Time::Now() - encode_start_time).InMillisecondsRoundedUp());
+      (base::TimeTicks::Now() - encode_start_time).InMillisecondsRoundedUp());
   if (!frame.dpi().is_zero()) {
     packet->mutable_format()->set_x_dpi(frame.dpi().x());
     packet->mutable_format()->set_y_dpi(frame.dpi().y());
@@ -229,8 +236,7 @@
 VideoEncoderVpx::VideoEncoderVpx(const InitializeCodecCallback& init_codec)
     : init_codec_(init_codec),
       active_map_width_(0),
-      active_map_height_(0),
-      last_timestamp_(0) {
+      active_map_height_(0) {
 }
 
 bool VideoEncoderVpx::Initialize(const webrtc::DesktopSize& size) {
@@ -257,39 +263,36 @@
   active_map_height_ = (image_->h + kMacroBlockSize - 1) / kMacroBlockSize;
   active_map_.reset(new uint8[active_map_width_ * active_map_height_]);
 
-  // YUV image size is 1.5 times of a plane. Multiplication is performed first
-  // to avoid rounding error.
-  const int y_plane_size = image_->w * image_->h;
-  const int uv_width = (image_->w + 1) / 2;
-  const int uv_height = (image_->h + 1) / 2;
-  const int uv_plane_size = uv_width * uv_height;
-  const int yuv_image_size = y_plane_size + uv_plane_size * 2;
+  // libyuv's fast-path requires 16-byte aligned pointers and strides, so pad
+  // the Y, U and V planes' strides to multiples of 16 bytes.
+  const int y_stride = ((image_->w - 1) & ~15) + 16;
+  const int uv_unaligned_stride = y_stride / 2;
+  const int uv_stride = ((uv_unaligned_stride - 1) & ~15) + 16;
 
-  // libvpx may try to access memory after the buffer (it still
-  // doesn't use it) - it copies the data in 16x16 blocks:
-  // crbug.com/119633 . Here we workaround that problem by adding
-  // padding at the end of the buffer. Overreading to U and V buffers
-  // is safe so the padding is necessary only at the end.
-  //
-  // TODO(sergeyu): Remove this padding when the bug is fixed in libvpx.
-  const int active_map_area = active_map_width_ * kMacroBlockSize *
-      active_map_height_ * kMacroBlockSize;
-  const int padding_size = active_map_area - y_plane_size;
-  const int buffer_size = yuv_image_size + padding_size;
+  // libvpx accesses the source image in macro blocks, and will over-read
+  // if the image is not padded out to the next macroblock: crbug.com/119633.
+  // Pad the Y, U and V planes' height out to compensate.
+  // Assuming macroblocks are 16x16, aligning the planes' strides above also
+  // macroblock aligned them.
+  DCHECK_EQ(16, kMacroBlockSize);
+  const int y_rows = active_map_height_ * kMacroBlockSize;
+  const int uv_rows = y_rows / 2;
 
+  // Allocate a YUV buffer large enough for the aligned data & padding.
+  const int buffer_size = y_stride * y_rows + 2 * uv_stride * uv_rows;
   yuv_image_.reset(new uint8[buffer_size]);
 
   // Reset image value to 128 so we just need to fill in the y plane.
-  memset(yuv_image_.get(), 128, yuv_image_size);
+  memset(yuv_image_.get(), 128, buffer_size);
 
   // Fill in the information for |image_|.
   unsigned char* image = reinterpret_cast<unsigned char*>(yuv_image_.get());
   image_->planes[0] = image;
-  image_->planes[1] = image + y_plane_size;
-  image_->planes[2] = image + y_plane_size + uv_plane_size;
-  image_->stride[0] = image_->w;
-  image_->stride[1] = uv_width;
-  image_->stride[2] = uv_width;
+  image_->planes[1] = image_->planes[0] + y_stride * y_rows;
+  image_->planes[2] = image_->planes[1] + uv_stride * uv_rows;
+  image_->stride[0] = y_stride;
+  image_->stride[1] = uv_stride;
+  image_->stride[2] = uv_stride;
 
   // Initialize the codec.
   codec_ = init_codec_.Run(size);
diff --git a/remoting/codec/video_encoder_vpx.h b/remoting/codec/video_encoder_vpx.h
index 286745f..dd7fb2e 100644
--- a/remoting/codec/video_encoder_vpx.h
+++ b/remoting/codec/video_encoder_vpx.h
@@ -6,6 +6,7 @@
 #define REMOTING_CODEC_VIDEO_ENCODER_VPX_H_
 
 #include "base/callback.h"
+#include "base/time/time.h"
 #include "remoting/codec/scoped_vpx_codec.h"
 #include "remoting/codec/video_encoder.h"
 
@@ -55,7 +56,7 @@
   scoped_ptr<uint8[]> active_map_;
   int active_map_width_;
   int active_map_height_;
-  int last_timestamp_;
+  base::TimeTicks timestamp_base_;
 
   // Buffer for storing the yuv image.
   scoped_ptr<uint8[]> yuv_image_;
diff --git a/remoting/host/it2me/it2me_native_messaging_host_main.cc b/remoting/host/it2me/it2me_native_messaging_host_main.cc
index 77d91a2..1483e04 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_main.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_main.cc
@@ -81,8 +81,8 @@
   // the hosting executable specifies "Windows" subsystem. However the returned
   // handles are invalid in that case unless standard input and output are
   // redirected to a pipe or file.
-  base::PlatformFile read_file = GetStdHandle(STD_INPUT_HANDLE);
-  base::PlatformFile write_file = GetStdHandle(STD_OUTPUT_HANDLE);
+  base::File read_file(GetStdHandle(STD_INPUT_HANDLE));
+  base::File write_file(GetStdHandle(STD_OUTPUT_HANDLE));
 
   // After the native messaging channel starts the native messaging reader
   // will keep doing blocking read operations on the input named pipe.
@@ -95,8 +95,9 @@
   SetStdHandle(STD_INPUT_HANDLE, NULL);
   SetStdHandle(STD_OUTPUT_HANDLE, NULL);
 #elif defined(OS_POSIX)
-  base::PlatformFile read_file = STDIN_FILENO;
-  base::PlatformFile write_file = STDOUT_FILENO;
+  // The files are automatically closed.
+  base::File read_file(STDIN_FILENO);
+  base::File write_file(STDOUT_FILENO);
 #else
 #error Not implemented.
 #endif
@@ -112,7 +113,7 @@
 
   // Set up the native messaging channel.
   scoped_ptr<NativeMessagingChannel> channel(
-      new NativeMessagingChannel(read_file, write_file));
+      new NativeMessagingChannel(read_file.Pass(), write_file.Pass()));
 
   scoped_ptr<It2MeNativeMessagingHost> host(
       new It2MeNativeMessagingHost(
diff --git a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
index 76389d1..b438b96 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
@@ -192,13 +192,13 @@
   void ExitTest();
 
   // Each test creates two unidirectional pipes: "input" and "output".
-  // It2MeNativeMessagingHost reads from input_read_handle and writes to
-  // output_write_handle. The unittest supplies data to input_write_handle, and
+  // It2MeNativeMessagingHost reads from input_read_file and writes to
+  // output_write_file. The unittest supplies data to input_write_handle, and
   // verifies output from output_read_handle.
   //
   // unittest -> [input] -> It2MeNativeMessagingHost -> [output] -> unittest
-  base::PlatformFile input_write_handle_;
-  base::PlatformFile output_read_handle_;
+  base::File input_write_file_;
+  base::File output_read_file_;
 
   // Message loop of the test thread.
   scoped_ptr<base::MessageLoop> test_message_loop_;
@@ -239,7 +239,7 @@
 void It2MeNativeMessagingHostTest::TearDown() {
   // Closing the write-end of the input will send an EOF to the native
   // messaging reader. This will trigger a host shutdown.
-  base::ClosePlatformFile(input_write_handle_);
+  input_write_file_.Close();
 
   // Start a new RunLoop and Wait until the host finishes shutting down.
   test_run_loop_.reset(new base::RunLoop());
@@ -250,23 +250,23 @@
   EXPECT_FALSE(response);
 
   // The It2MeNativeMessagingHost dtor closes the handles that are passed to it.
-  // So the only handle left to close is |output_read_handle_|.
-  base::ClosePlatformFile(output_read_handle_);
+  // So the only handle left to close is |output_read_file_|.
+  output_read_file_.Close();
 }
 
 scoped_ptr<base::DictionaryValue>
 It2MeNativeMessagingHostTest::ReadMessageFromOutputPipe() {
   uint32 length;
-  int read_result = base::ReadPlatformFileAtCurrentPos(
-      output_read_handle_, reinterpret_cast<char*>(&length), sizeof(length));
+  int read_result = output_read_file_.ReadAtCurrentPos(
+      reinterpret_cast<char*>(&length), sizeof(length));
   if (read_result != sizeof(length)) {
     // The output pipe has been closed, return an empty message.
     return scoped_ptr<base::DictionaryValue>();
   }
 
   std::string message_json(length, '\0');
-  read_result = base::ReadPlatformFileAtCurrentPos(
-      output_read_handle_, string_as_array(&message_json), length);
+  read_result = output_read_file_.ReadAtCurrentPos(
+      string_as_array(&message_json), length);
   if (read_result != static_cast<int>(length)) {
     LOG(ERROR) << "Message size (" << read_result
                << ") doesn't match the header (" << length << ").";
@@ -289,10 +289,9 @@
   base::JSONWriter::Write(&message, &message_json);
 
   uint32 length = message_json.length();
-  base::WritePlatformFileAtCurrentPos(
-      input_write_handle_, reinterpret_cast<char*>(&length), sizeof(length));
-  base::WritePlatformFileAtCurrentPos(
-      input_write_handle_, message_json.data(), length);
+  input_write_file_.WriteAtCurrentPos(reinterpret_cast<char*>(&length),
+                                      sizeof(length));
+  input_write_file_.WriteAtCurrentPos(message_json.data(), length);
 }
 
 void It2MeNativeMessagingHostTest::VerifyHelloResponse(int request_id) {
@@ -423,17 +422,18 @@
 void It2MeNativeMessagingHostTest::StartHost() {
   DCHECK(host_task_runner_->RunsTasksOnCurrentThread());
 
-  base::PlatformFile input_read_handle;
-  base::PlatformFile output_write_handle;
+  base::File input_read_file;
+  base::File output_write_file;
 
-  ASSERT_TRUE(MakePipe(&input_read_handle, &input_write_handle_));
-  ASSERT_TRUE(MakePipe(&output_read_handle_, &output_write_handle));
+  ASSERT_TRUE(MakePipe(&input_read_file, &input_write_file_));
+  ASSERT_TRUE(MakePipe(&output_read_file_, &output_write_file));
 
   // Creating a native messaging host with a mock It2MeHostFactory.
   scoped_ptr<It2MeHostFactory> factory(new MockIt2MeHostFactory());
 
   scoped_ptr<NativeMessagingChannel> channel(
-      new NativeMessagingChannel(input_read_handle, output_write_handle));
+      new NativeMessagingChannel(input_read_file.Pass(),
+                                 output_write_file.Pass()));
 
   host_.reset(
       new It2MeNativeMessagingHost(
diff --git a/remoting/host/native_messaging/native_messaging_channel.cc b/remoting/host/native_messaging/native_messaging_channel.cc
index 186b33b..007de56 100644
--- a/remoting/host/native_messaging/native_messaging_channel.cc
+++ b/remoting/host/native_messaging/native_messaging_channel.cc
@@ -17,24 +17,23 @@
 
 namespace {
 
-base::PlatformFile DuplicatePlatformFile(base::PlatformFile handle) {
+base::File DuplicatePlatformFile(base::File file) {
   base::PlatformFile result;
 #if defined(OS_WIN)
   if (!DuplicateHandle(GetCurrentProcess(),
-                       handle,
+                       file.TakePlatformFile(),
                        GetCurrentProcess(),
                        &result,
                        0,
                        FALSE,
                        DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
-    PLOG(ERROR) << "Failed to duplicate handle " << handle;
-    return base::kInvalidPlatformFileValue;
+    PLOG(ERROR) << "Failed to duplicate handle " << file.GetPlatformFile();
+    return base::File();
   }
-  return result;
+  return base::File(result);
 #elif defined(OS_POSIX)
-  result = dup(handle);
-  base::ClosePlatformFile(handle);
-  return result;
+  result = dup(file.GetPlatformFile());
+  return base::File(result);
 #else
 #error Not implemented.
 #endif
@@ -45,11 +44,11 @@
 namespace remoting {
 
 NativeMessagingChannel::NativeMessagingChannel(
-    base::PlatformFile input,
-    base::PlatformFile output)
-    : native_messaging_reader_(DuplicatePlatformFile(input)),
+    base::File input,
+    base::File output)
+    : native_messaging_reader_(DuplicatePlatformFile(input.Pass())),
       native_messaging_writer_(new NativeMessagingWriter(
-          DuplicatePlatformFile(output))),
+          DuplicatePlatformFile(output.Pass()))),
       weak_factory_(this) {
   weak_ptr_ = weak_factory_.GetWeakPtr();
 }
diff --git a/remoting/host/native_messaging/native_messaging_channel.h b/remoting/host/native_messaging/native_messaging_channel.h
index 472cc06..926f547 100644
--- a/remoting/host/native_messaging/native_messaging_channel.h
+++ b/remoting/host/native_messaging/native_messaging_channel.h
@@ -6,10 +6,10 @@
 #define REMOTING_HOST_NATIVE_MESSAGING_NATIVE_MESSAGING_CHANNEL_H_
 
 #include "base/callback.h"
+#include "base/files/file.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "base/platform_file.h"
 #include "base/threading/non_thread_safe.h"
 #include "remoting/host/native_messaging/native_messaging_reader.h"
 #include "remoting/host/native_messaging/native_messaging_writer.h"
@@ -31,7 +31,7 @@
 
   // Constructs an object taking the ownership of |input| and |output|. Closes
   // |input| and |output| to prevent the caller from using them.
-  NativeMessagingChannel(base::PlatformFile input, base::PlatformFile output);
+  NativeMessagingChannel(base::File input, base::File output);
   ~NativeMessagingChannel();
 
   // Starts reading and processing messages.
diff --git a/remoting/host/native_messaging/native_messaging_reader.cc b/remoting/host/native_messaging/native_messaging_reader.cc
index 30f307b..b2ff66d 100644
--- a/remoting/host/native_messaging/native_messaging_reader.cc
+++ b/remoting/host/native_messaging/native_messaging_reader.cc
@@ -35,7 +35,7 @@
 
 class NativeMessagingReader::Core {
  public:
-  Core(base::PlatformFile handle,
+  Core(base::File file,
        scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
        scoped_refptr<base::SequencedTaskRunner> read_task_runner,
        base::WeakPtr<NativeMessagingReader> reader_);
@@ -63,11 +63,11 @@
 };
 
 NativeMessagingReader::Core::Core(
-    base::PlatformFile handle,
+    base::File file,
     scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
     scoped_refptr<base::SequencedTaskRunner> read_task_runner,
     base::WeakPtr<NativeMessagingReader> reader)
-    : read_stream_(handle),
+    : read_stream_(file.Pass()),
       reader_(reader),
       caller_task_runner_(caller_task_runner),
       read_task_runner_(read_task_runner) {
@@ -130,12 +130,12 @@
       base::Bind(&NativeMessagingReader::InvokeEofCallback, reader_));
 }
 
-NativeMessagingReader::NativeMessagingReader(base::PlatformFile handle)
+NativeMessagingReader::NativeMessagingReader(base::File file)
     : reader_thread_("Reader"),
       weak_factory_(this) {
   reader_thread_.Start();
   read_task_runner_ = reader_thread_.message_loop_proxy();
-  core_.reset(new Core(handle, base::ThreadTaskRunnerHandle::Get(),
+  core_.reset(new Core(file.Pass(), base::ThreadTaskRunnerHandle::Get(),
                        read_task_runner_, weak_factory_.GetWeakPtr()));
 }
 
diff --git a/remoting/host/native_messaging/native_messaging_reader.h b/remoting/host/native_messaging/native_messaging_reader.h
index a9e2047..ed93e8d 100644
--- a/remoting/host/native_messaging/native_messaging_reader.h
+++ b/remoting/host/native_messaging/native_messaging_reader.h
@@ -7,9 +7,9 @@
 
 #include "base/basictypes.h"
 #include "base/callback.h"
+#include "base/files/file.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "base/platform_file.h"
 #include "base/threading/thread.h"
 
 namespace base {
@@ -25,7 +25,7 @@
  public:
   typedef base::Callback<void(scoped_ptr<base::Value>)> MessageCallback;
 
-  explicit NativeMessagingReader(base::PlatformFile handle);
+  explicit NativeMessagingReader(base::File file);
   ~NativeMessagingReader();
 
   // Begin reading messages from the Native Messaging client webapp, calling
diff --git a/remoting/host/native_messaging/native_messaging_reader_unittest.cc b/remoting/host/native_messaging/native_messaging_reader_unittest.cc
index 35af8a2..964dffe 100644
--- a/remoting/host/native_messaging/native_messaging_reader_unittest.cc
+++ b/remoting/host/native_messaging/native_messaging_reader_unittest.cc
@@ -22,7 +22,6 @@
   virtual ~NativeMessagingReaderTest();
 
   virtual void SetUp() OVERRIDE;
-  virtual void TearDown() OVERRIDE;
 
   // Starts the reader and runs the MessageLoop to completion.
   void Run();
@@ -39,8 +38,8 @@
 
  protected:
   scoped_ptr<NativeMessagingReader> reader_;
-  base::PlatformFile read_handle_;
-  base::PlatformFile write_handle_;
+  base::File read_file_;
+  base::File write_file_;
   scoped_ptr<base::Value> message_;
 
  private:
@@ -56,18 +55,13 @@
 NativeMessagingReaderTest::~NativeMessagingReaderTest() {}
 
 void NativeMessagingReaderTest::SetUp() {
-  ASSERT_TRUE(MakePipe(&read_handle_, &write_handle_));
-  reader_.reset(new NativeMessagingReader(read_handle_));
-}
-
-void NativeMessagingReaderTest::TearDown() {
-  // |read_handle_| is owned by NativeMessagingReader's FileStream, so don't
-  // try to close it here. Also, |write_handle_| gets closed by Run().
+  ASSERT_TRUE(MakePipe(&read_file_, &write_file_));
+  reader_.reset(new NativeMessagingReader(read_file_.Pass()));
 }
 
 void NativeMessagingReaderTest::Run() {
   // Close the write-end, so the reader doesn't block waiting for more data.
-  base::ClosePlatformFile(write_handle_);
+  write_file_.Close();
 
   // base::Unretained is safe since no further tasks can run after
   // RunLoop::Run() returns.
@@ -88,8 +82,7 @@
 }
 
 void NativeMessagingReaderTest::WriteData(const char* data, int length) {
-  int written = base::WritePlatformFileAtCurrentPos(write_handle_, data,
-                                                    length);
+  int written = write_file_.WriteAtCurrentPos(data, length);
   ASSERT_EQ(length, written);
 }
 
diff --git a/remoting/host/native_messaging/native_messaging_writer.cc b/remoting/host/native_messaging/native_messaging_writer.cc
index fdfc25a..3266fdb 100644
--- a/remoting/host/native_messaging/native_messaging_writer.cc
+++ b/remoting/host/native_messaging/native_messaging_writer.cc
@@ -29,8 +29,8 @@
 
 namespace remoting {
 
-NativeMessagingWriter::NativeMessagingWriter(base::PlatformFile handle)
-    : write_stream_(handle),
+NativeMessagingWriter::NativeMessagingWriter(base::File file)
+    : write_stream_(file.Pass()),
       fail_(false) {
 }
 
diff --git a/remoting/host/native_messaging/native_messaging_writer.h b/remoting/host/native_messaging/native_messaging_writer.h
index 560707a..41f60bf 100644
--- a/remoting/host/native_messaging/native_messaging_writer.h
+++ b/remoting/host/native_messaging/native_messaging_writer.h
@@ -6,7 +6,6 @@
 #define REMOTING_HOST_NATIVE_MESSAGING_NATIVE_MESSAGING_WRITER_H_
 
 #include "base/files/file.h"
-#include "base/platform_file.h"
 
 namespace base {
 class Value;
@@ -18,7 +17,7 @@
 // webapp.
 class NativeMessagingWriter {
  public:
-  explicit NativeMessagingWriter(base::PlatformFile handle);
+  explicit NativeMessagingWriter(base::File file);
   ~NativeMessagingWriter();
 
   // Sends a message to the Native Messaging client, returning true if
diff --git a/remoting/host/native_messaging/native_messaging_writer_unittest.cc b/remoting/host/native_messaging/native_messaging_writer_unittest.cc
index 52bdb1f..be7f2f0 100644
--- a/remoting/host/native_messaging/native_messaging_writer_unittest.cc
+++ b/remoting/host/native_messaging/native_messaging_writer_unittest.cc
@@ -21,13 +21,11 @@
   virtual ~NativeMessagingWriterTest();
 
   virtual void SetUp() OVERRIDE;
-  virtual void TearDown() OVERRIDE;
 
  protected:
   scoped_ptr<NativeMessagingWriter> writer_;
-  base::PlatformFile read_handle_;
-  base::PlatformFile write_handle_;
-  bool read_handle_open_;
+  base::File read_file_;
+  base::File write_file_;
 };
 
 NativeMessagingWriterTest::NativeMessagingWriterTest() {}
@@ -35,17 +33,8 @@
 NativeMessagingWriterTest::~NativeMessagingWriterTest() {}
 
 void NativeMessagingWriterTest::SetUp() {
-  ASSERT_TRUE(MakePipe(&read_handle_, &write_handle_));
-  writer_.reset(new NativeMessagingWriter(write_handle_));
-  read_handle_open_ = true;
-}
-
-void NativeMessagingWriterTest::TearDown() {
-  // |write_handle_| is owned by NativeMessagingWriter's FileStream, so don't
-  // try to close it here. And close |read_handle_| only if it hasn't
-  // already been closed.
-  if (read_handle_open_)
-    base::ClosePlatformFile(read_handle_);
+  ASSERT_TRUE(MakePipe(&read_file_, &write_file_));
+  writer_.reset(new NativeMessagingWriter(write_file_.Pass()));
 }
 
 TEST_F(NativeMessagingWriterTest, GoodMessage) {
@@ -55,12 +44,10 @@
 
   // Read from the pipe and verify the content.
   uint32 length;
-  int read = base::ReadPlatformFileAtCurrentPos(
-      read_handle_, reinterpret_cast<char*>(&length), 4);
+  int read = read_file_.ReadAtCurrentPos(reinterpret_cast<char*>(&length), 4);
   EXPECT_EQ(4, read);
   std::string content(length, '\0');
-  read = base::ReadPlatformFileAtCurrentPos(read_handle_,
-                                            string_as_array(&content), length);
+  read = read_file_.ReadAtCurrentPos(string_as_array(&content), length);
   EXPECT_EQ(static_cast<int>(length), read);
 
   // |content| should now contain serialized |message|.
@@ -71,7 +58,7 @@
   // and verify the read end immediately hits EOF.
   writer_.reset(NULL);
   char unused;
-  read = base::ReadPlatformFileAtCurrentPos(read_handle_, &unused, 1);
+  read = read_file_.ReadAtCurrentPos(&unused, 1);
   EXPECT_LE(read, 0);
 }
 
@@ -88,13 +75,10 @@
   int read;
   std::string content;
   for (int i = 0; i < 2; i++) {
-    read = base::ReadPlatformFileAtCurrentPos(
-        read_handle_, reinterpret_cast<char*>(&length), 4);
+    read = read_file_.ReadAtCurrentPos(reinterpret_cast<char*>(&length), 4);
     EXPECT_EQ(4, read) << "i = " << i;
     content.resize(length);
-    read = base::ReadPlatformFileAtCurrentPos(read_handle_,
-                                              string_as_array(&content),
-                                              length);
+    read = read_file_.ReadAtCurrentPos(string_as_array(&content), length);
     EXPECT_EQ(static_cast<int>(length), read) << "i = " << i;
   }
 
@@ -105,8 +89,7 @@
 
 TEST_F(NativeMessagingWriterTest, FailedWrite) {
   // Close the read end so that writing fails immediately.
-  base::ClosePlatformFile(read_handle_);
-  read_handle_open_ = false;
+  read_file_.Close();
 
   base::DictionaryValue message;
   EXPECT_FALSE(writer_->WriteMessage(message));
diff --git a/remoting/host/setup/me2me_native_messaging_host.cc b/remoting/host/setup/me2me_native_messaging_host.cc
index b7183b0..72076db 100644
--- a/remoting/host/setup/me2me_native_messaging_host.cc
+++ b/remoting/host/setup/me2me_native_messaging_host.cc
@@ -661,7 +661,8 @@
   // Set up the native messaging channel to talk to the elevated host.
   // Note that input for the elevate channel is output forthe elevated host.
   elevated_channel_.reset(new NativeMessagingChannel(
-      delegate_read_handle.Take(), delegate_write_handle.Take()));
+      base::File(delegate_read_handle.Take()),
+      base::File(delegate_write_handle.Take())));
 
   elevated_channel_->Start(
       base::Bind(&Me2MeNativeMessagingHost::ProcessDelegateResponse, weak_ptr_),
diff --git a/remoting/host/setup/me2me_native_messaging_host_main.cc b/remoting/host/setup/me2me_native_messaging_host_main.cc
index 5e0e0e2..8cf6566 100644
--- a/remoting/host/setup/me2me_native_messaging_host_main.cc
+++ b/remoting/host/setup/me2me_native_messaging_host_main.cc
@@ -102,8 +102,8 @@
     }
   }
 
-  base::PlatformFile read_file;
-  base::PlatformFile write_file;
+  base::File read_file;
+  base::File write_file;
   bool needs_elevation = false;
 
 #if defined(OS_WIN)
@@ -126,19 +126,19 @@
       command_line->GetSwitchValueNative(kOutputSwitchName);
 
     // A NULL SECURITY_ATTRIBUTES signifies that the handle can't be inherited
-    read_file = CreateFile(
+    read_file = base::File(CreateFile(
         input_pipe_name.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING,
-        FILE_ATTRIBUTE_NORMAL, NULL);
-    if (read_file == INVALID_HANDLE_VALUE) {
+        FILE_ATTRIBUTE_NORMAL, NULL));
+    if (!read_file.IsValid()) {
       LOG_GETLASTERROR(ERROR) <<
           "CreateFile failed on '" << input_pipe_name << "'";
       return kInitializationFailed;
     }
 
-    write_file = CreateFile(
+    write_file = base::File(CreateFile(
         output_pipe_name.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
-        FILE_ATTRIBUTE_NORMAL, NULL);
-    if (write_file == INVALID_HANDLE_VALUE) {
+        FILE_ATTRIBUTE_NORMAL, NULL));
+    if (!write_file.IsValid()) {
       LOG_GETLASTERROR(ERROR) <<
           "CreateFile failed on '" << output_pipe_name << "'";
       return kInitializationFailed;
@@ -148,8 +148,8 @@
     // the hosting executable specifies "Windows" subsystem. However the
     // returned handles are invalid in that case unless standard input and
     // output are redirected to a pipe or file.
-    read_file = GetStdHandle(STD_INPUT_HANDLE);
-    write_file = GetStdHandle(STD_OUTPUT_HANDLE);
+    read_file = base::File(GetStdHandle(STD_INPUT_HANDLE));
+    write_file = base::File(GetStdHandle(STD_OUTPUT_HANDLE));
 
     // After the native messaging channel starts the native messaging reader
     // will keep doing blocking read operations on the input named pipe.
@@ -163,8 +163,9 @@
     SetStdHandle(STD_OUTPUT_HANDLE, NULL);
   }
 #elif defined(OS_POSIX)
-  read_file = STDIN_FILENO;
-  write_file = STDOUT_FILENO;
+  // The files will be automatically closed.
+  read_file = base::File(STDIN_FILENO);
+  write_file = base::File(STDOUT_FILENO);
 #else
 #error Not implemented.
 #endif
@@ -229,7 +230,7 @@
 
   // Set up the native messaging channel.
   scoped_ptr<NativeMessagingChannel> channel(
-      new NativeMessagingChannel(read_file, write_file));
+      new NativeMessagingChannel(read_file.Pass(), write_file.Pass()));
 
   // Create the native messaging host.
   scoped_ptr<Me2MeNativeMessagingHost> host(
diff --git a/remoting/host/setup/me2me_native_messaging_host_unittest.cc b/remoting/host/setup/me2me_native_messaging_host_unittest.cc
index 0d0f2af..65ba402 100644
--- a/remoting/host/setup/me2me_native_messaging_host_unittest.cc
+++ b/remoting/host/setup/me2me_native_messaging_host_unittest.cc
@@ -251,12 +251,12 @@
 
   // Each test creates two unidirectional pipes: "input" and "output".
   // Me2MeNativeMessagingHost reads from input_read_handle and writes to
-  // output_write_handle. The unittest supplies data to input_write_handle, and
+  // output_write_file. The unittest supplies data to input_write_handle, and
   // verifies output from output_read_handle.
   //
   // unittest -> [input] -> Me2MeNativeMessagingHost -> [output] -> unittest
-  base::PlatformFile input_write_handle_;
-  base::PlatformFile output_read_handle_;
+  base::File input_write_file_;
+  base::File output_read_file_;
 
   // Message loop of the test thread.
   scoped_ptr<base::MessageLoop> test_message_loop_;
@@ -277,11 +277,11 @@
 Me2MeNativeMessagingHostTest::~Me2MeNativeMessagingHostTest() {}
 
 void Me2MeNativeMessagingHostTest::SetUp() {
-  base::PlatformFile input_read_handle;
-  base::PlatformFile output_write_handle;
+  base::File input_read_file;
+  base::File output_write_file;
 
-  ASSERT_TRUE(MakePipe(&input_read_handle, &input_write_handle_));
-  ASSERT_TRUE(MakePipe(&output_read_handle_, &output_write_handle));
+  ASSERT_TRUE(MakePipe(&input_read_file, &input_write_file_));
+  ASSERT_TRUE(MakePipe(&output_read_file_, &output_write_file));
 
   test_message_loop_.reset(new base::MessageLoop());
   test_run_loop_.reset(new base::RunLoop());
@@ -308,11 +308,11 @@
 void Me2MeNativeMessagingHostTest::StartHost() {
   DCHECK(host_task_runner_->RunsTasksOnCurrentThread());
 
-  base::PlatformFile input_read_handle;
-  base::PlatformFile output_write_handle;
+  base::File input_read_file;
+  base::File output_write_file;
 
-  ASSERT_TRUE(MakePipe(&input_read_handle, &input_write_handle_));
-  ASSERT_TRUE(MakePipe(&output_read_handle_, &output_write_handle));
+  ASSERT_TRUE(MakePipe(&input_read_file, &input_write_file_));
+  ASSERT_TRUE(MakePipe(&output_read_file_, &output_write_file));
 
   daemon_controller_delegate_ = new MockDaemonControllerDelegate();
   scoped_refptr<DaemonController> daemon_controller(
@@ -324,7 +324,8 @@
           new MockPairingRegistryDelegate()));
 
   scoped_ptr<NativeMessagingChannel> channel(
-      new NativeMessagingChannel(input_read_handle, output_write_handle));
+      new NativeMessagingChannel(input_read_file.Pass(),
+                                 output_write_file.Pass()));
 
   host_.reset(new Me2MeNativeMessagingHost(
         false,
@@ -367,7 +368,7 @@
 void Me2MeNativeMessagingHostTest::TearDown() {
   // Closing the write-end of the input will send an EOF to the native
   // messaging reader. This will trigger a host shutdown.
-  base::ClosePlatformFile(input_write_handle_);
+  input_write_file_.Close();
 
   // Start a new RunLoop and Wait until the host finishes shutting down.
   test_run_loop_.reset(new base::RunLoop());
@@ -378,22 +379,22 @@
   EXPECT_FALSE(response);
 
   // The It2MeMe2MeNativeMessagingHost dtor closes the handles that are passed
-  // to it. So the only handle left to close is |output_read_handle_|.
-  base::ClosePlatformFile(output_read_handle_);
+  // to it. So the only handle left to close is |output_read_file_|.
+  output_read_file_.Close();
 }
 
 scoped_ptr<base::DictionaryValue>
 Me2MeNativeMessagingHostTest::ReadMessageFromOutputPipe() {
   uint32 length;
-  int read_result = base::ReadPlatformFileAtCurrentPos(
-      output_read_handle_, reinterpret_cast<char*>(&length), sizeof(length));
+  int read_result = output_read_file_.ReadAtCurrentPos(
+      reinterpret_cast<char*>(&length), sizeof(length));
   if (read_result != sizeof(length)) {
     return scoped_ptr<base::DictionaryValue>();
   }
 
   std::string message_json(length, '\0');
-  read_result = base::ReadPlatformFileAtCurrentPos(
-      output_read_handle_, string_as_array(&message_json), length);
+  read_result = output_read_file_.ReadAtCurrentPos(
+      string_as_array(&message_json), length);
   if (read_result != static_cast<int>(length)) {
     return scoped_ptr<base::DictionaryValue>();
   }
@@ -413,11 +414,9 @@
   base::JSONWriter::Write(&message, &message_json);
 
   uint32 length = message_json.length();
-  base::WritePlatformFileAtCurrentPos(input_write_handle_,
-                                      reinterpret_cast<char*>(&length),
+  input_write_file_.WriteAtCurrentPos(reinterpret_cast<char*>(&length),
                                       sizeof(length));
-  base::WritePlatformFileAtCurrentPos(input_write_handle_, message_json.data(),
-                                      length);
+  input_write_file_.WriteAtCurrentPos(message_json.data(), length);
 }
 
 void Me2MeNativeMessagingHostTest::TestBadRequest(const base::Value& message) {
diff --git a/remoting/host/setup/oauth_helper.cc b/remoting/host/setup/oauth_helper.cc
index 7746df1..65f06bc 100644
--- a/remoting/host/setup/oauth_helper.cc
+++ b/remoting/host/setup/oauth_helper.cc
@@ -12,7 +12,7 @@
 namespace {
 
 std::string GetComponent(const std::string& url,
-                         const url_parse::Component component) {
+                         const url::Component component) {
   if (component.len < 0) {
     return std::string();
   }
@@ -53,9 +53,9 @@
 
 std::string GetOauthCodeInUrl(const std::string& url,
                               const std::string& redirect_url) {
-  url_parse::Parsed url_parsed;
+  url::Parsed url_parsed;
   ParseStandardURL(url.c_str(), url.length(), &url_parsed);
-  url_parse::Parsed redirect_url_parsed;
+  url::Parsed redirect_url_parsed;
   ParseStandardURL(redirect_url.c_str(), redirect_url.length(),
                    &redirect_url_parsed);
   if (GetComponent(url, url_parsed.scheme) !=
@@ -66,9 +66,9 @@
       GetComponent(redirect_url, redirect_url_parsed.host)) {
     return std::string();
   }
-  url_parse::Component query = url_parsed.query;
-  url_parse::Component key;
-  url_parse::Component value;
+  url::Component query = url_parsed.query;
+  url::Component key;
+  url::Component value;
   while (ExtractQueryKeyValue(url.c_str(), &query, &key, &value)) {
     if (GetComponent(url, key) == "code") {
       return GetComponent(url, value);
diff --git a/remoting/host/setup/test_util.cc b/remoting/host/setup/test_util.cc
index 9266c74..51c610b 100644
--- a/remoting/host/setup/test_util.cc
+++ b/remoting/host/setup/test_util.cc
@@ -12,15 +12,21 @@
 
 namespace remoting {
 
-bool MakePipe(base::PlatformFile* read_handle,
-              base::PlatformFile* write_handle) {
+bool MakePipe(base::File* read_file,
+              base::File* write_file) {
 #if defined(OS_WIN)
-  return CreatePipe(read_handle, write_handle, NULL, 0) != FALSE;
+  base::PlatformFile read_handle;
+  base::PlatformFile write_handle;
+  if (!CreatePipe(&read_handle, &write_handle, NULL, 0))
+    return false;
+  *read_file = base::File(read_handle);
+  *write_file = base::File(write_handle);
+  return true;
 #elif defined(OS_POSIX)
   int fds[2];
   if (pipe(fds) == 0) {
-    *read_handle = fds[0];
-    *write_handle = fds[1];
+    *read_file = base::File(fds[0]);
+    *write_file = base::File(fds[1]);
     return true;
   }
   return false;
diff --git a/remoting/host/setup/test_util.h b/remoting/host/setup/test_util.h
index 77a46ab..8a40f5b 100644
--- a/remoting/host/setup/test_util.h
+++ b/remoting/host/setup/test_util.h
@@ -5,15 +5,14 @@
 #ifndef REMOTING_HOST_SETUP_TEST_UTIL_H_
 #define REMOTING_HOST_SETUP_TEST_UTIL_H_
 
-#include "base/platform_file.h"
+#include "base/files/file.h"
 
 namespace remoting {
 
 // Creates an anonymous, unidirectional pipe, returning true if successful. On
-// success, the caller is responsible for closing both ends using
-// base::ClosePlatformFile().
-bool MakePipe(base::PlatformFile* read_handle,
-              base::PlatformFile* write_handle);
+// success, the receives ownership of both files.
+bool MakePipe(base::File* read_file,
+              base::File* write_file);
 
 }  // namespace remoting
 
diff --git a/remoting/protocol/connection_to_host.cc b/remoting/protocol/connection_to_host.cc
index b7599cf..d2ce7ff 100644
--- a/remoting/protocol/connection_to_host.cc
+++ b/remoting/protocol/connection_to_host.cc
@@ -223,11 +223,6 @@
   event_callback_->OnConnectionReady(active);
 }
 
-void ConnectionToHost::OnChannelReconnectionTimeout() {
-  LOG(ERROR) << "Failed to connect video channel";
-  CloseOnError(CHANNEL_CONNECTION_ERROR);
-}
-
 ConnectionToHost::State ConnectionToHost::state() const {
   return state_;
 }
diff --git a/remoting/protocol/connection_to_host.h b/remoting/protocol/connection_to_host.h
index b08226c..e50e041 100644
--- a/remoting/protocol/connection_to_host.h
+++ b/remoting/protocol/connection_to_host.h
@@ -141,8 +141,6 @@
   // Stops writing in the channels.
   void CloseChannels();
 
-  void OnChannelReconnectionTimeout();
-
   void SetState(State state, ErrorCode error);
 
   bool allow_nat_traversal_;
diff --git a/remoting/protocol/libjingle_transport_factory.cc b/remoting/protocol/libjingle_transport_factory.cc
index 35769a5..fd5ba0d 100644
--- a/remoting/protocol/libjingle_transport_factory.cc
+++ b/remoting/protocol/libjingle_transport_factory.cc
@@ -4,7 +4,9 @@
 
 #include "remoting/protocol/libjingle_transport_factory.h"
 
+#include "base/base64.h"
 #include "base/callback.h"
+#include "base/rand_util.h"
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/timer/timer.h"
@@ -44,6 +46,20 @@
 // Get fresh STUN/Relay configuration every hour.
 const int kJingleInfoUpdatePeriodSeconds = 3600;
 
+// TODO(sergeyu): Remove this function and use talk_base::CreateRandomString()
+// when it's fixed to work reliably. See crbug.com/364689 .
+std::string CreateRandomString(int length) {
+  // Number of random bytes to generate base64 string at least |length|
+  // characters long.
+  int raw_length = (length + 1) * 3 / 4;
+  std::string base64;
+  base::Base64Encode(base::RandBytesAsString(raw_length), &base64);
+  DCHECK(static_cast<int>(base64.size()) == length ||
+         static_cast<int>(base64.size()) == length + 1);
+  base64.resize(length);
+  return base64;
+}
+
 class LibjingleStreamTransport
     : public StreamTransport,
       public base::SupportsWeakPtr<LibjingleStreamTransport>,
@@ -126,12 +142,13 @@
     : port_allocator_(port_allocator),
       network_settings_(network_settings),
       event_handler_(NULL),
-      ice_username_fragment_(
-          talk_base::CreateRandomString(cricket::ICE_UFRAG_LENGTH)),
-      ice_password_(talk_base::CreateRandomString(cricket::ICE_PWD_LENGTH)),
+      ice_username_fragment_(CreateRandomString(cricket::ICE_UFRAG_LENGTH)),
+      ice_password_(CreateRandomString(cricket::ICE_PWD_LENGTH)),
       can_start_(false),
       channel_was_writable_(false),
       connect_attempts_left_(kMaxReconnectAttempts) {
+  DCHECK(!ice_username_fragment_.empty());
+  DCHECK(!ice_password_.empty());
 }
 
 LibjingleStreamTransport::~LibjingleStreamTransport() {
@@ -369,7 +386,7 @@
   --connect_attempts_left_;
 
   // Restart ICE by resetting ICE password.
-  ice_password_ = talk_base::CreateRandomString(cricket::ICE_PWD_LENGTH);
+  ice_password_ = CreateRandomString(cricket::ICE_PWD_LENGTH);
   channel_->SetIceCredentials(ice_username_fragment_, ice_password_);
 }
 
diff --git a/remoting/protocol/me2me_host_authenticator_factory.cc b/remoting/protocol/me2me_host_authenticator_factory.cc
index 7e407c8..30c6419 100644
--- a/remoting/protocol/me2me_host_authenticator_factory.cc
+++ b/remoting/protocol/me2me_host_authenticator_factory.cc
@@ -141,7 +141,7 @@
 
   // Verify that the client's jid is an ASCII string, and then check that the
   // client JID has the expected prefix. Comparison is case insensitive.
-  if (!IsStringASCII(remote_jid) ||
+  if (!base::IsStringASCII(remote_jid) ||
       !StartsWithASCII(remote_jid, remote_jid_prefix + '/', false)) {
     LOG(ERROR) << "Rejecting incoming connection from " << remote_jid;
     return scoped_ptr<Authenticator>(new RejectingAuthenticator());
diff --git a/remoting/protocol/monitored_video_stub_unittest.cc b/remoting/protocol/monitored_video_stub_unittest.cc
index 74f26aa..8cd8f48 100644
--- a/remoting/protocol/monitored_video_stub_unittest.cc
+++ b/remoting/protocol/monitored_video_stub_unittest.cc
@@ -14,6 +14,7 @@
 
 using ::testing::_;
 using ::testing::AnyNumber;
+using ::testing::AtMost;
 using ::testing::InvokeWithoutArgs;
 
 namespace remoting {
@@ -46,6 +47,10 @@
 
 TEST_F(MonitoredVideoStubTest, OnChannelConnected) {
   EXPECT_CALL(*this, OnVideoChannelStatus(true));
+  // On slow machines, the connectivity check timer may fire before the test
+  // finishes, so we expect to see at most one transition to not ready.
+  EXPECT_CALL(*this, OnVideoChannelStatus(false)).Times(AtMost(1));
+
   monitor_->ProcessVideoPacket(packet_.Pass(), base::Closure());
   base::RunLoop().RunUntilIdle();
 }
@@ -64,7 +69,10 @@
 TEST_F(MonitoredVideoStubTest, OnChannelStayConnected) {
   // Verify no extra connected events are fired when packets are received
   // frequently
-  EXPECT_CALL(*this, OnVideoChannelStatus(_)).Times(1);
+  EXPECT_CALL(*this, OnVideoChannelStatus(true));
+  // On slow machines, the connectivity check timer may fire before the test
+  // finishes, so we expect to see at most one transition to not ready.
+  EXPECT_CALL(*this, OnVideoChannelStatus(false)).Times(AtMost(1));
 
   monitor_->ProcessVideoPacket(packet_.Pass(), base::Closure());
   monitor_->ProcessVideoPacket(packet_.Pass(), base::Closure());
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 49cf630..128ce31 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -52,6 +52,10 @@
         'host_plugin_extension': 'arm.so',
         'host_plugin_prefix': 'lib',
       }],
+      ['os_posix == 1 and OS != "mac" and target_arch == "arm64"', {
+        'host_plugin_extension': 'arm64.so',
+        'host_plugin_prefix': 'lib',
+      }],
       ['os_posix == 1 and OS != "mac" and target_arch == "mipsel"', {
         'host_plugin_extension': 'mipsel.so',
         'host_plugin_prefix': 'lib',
diff --git a/remoting/remoting_host.gypi b/remoting/remoting_host.gypi
index 3782fff..ff1996f 100644
--- a/remoting/remoting_host.gypi
+++ b/remoting/remoting_host.gypi
@@ -752,8 +752,7 @@
                 }],  # mac_breakpad==1
               ],  # conditions
             }],  # OS=mac
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+            ['OS=="linux" and use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
@@ -784,8 +783,7 @@
             'host/setup/me2me_native_messaging_host_main.h',
           ],
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+            ['OS=="linux" and use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
@@ -877,8 +875,7 @@
                 '../build/linux/system.gyp:gtk',
               ],
             }],
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+            ['OS=="linux" and use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
diff --git a/remoting/remoting_host_linux.gypi b/remoting/remoting_host_linux.gypi
index 770e764..5187bd2 100644
--- a/remoting/remoting_host_linux.gypi
+++ b/remoting/remoting_host_linux.gypi
@@ -128,8 +128,7 @@
             'host/setup/start_host.cc',
           ],
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
diff --git a/remoting/remoting_test.gypi b/remoting/remoting_test.gypi
index 65160c3..f5fc9d6 100644
--- a/remoting/remoting_test.gypi
+++ b/remoting/remoting_test.gypi
@@ -230,13 +230,24 @@
             ['exclude', '^base/resources_unittest\\.cc$'],
           ]
         }],
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        [ 'OS == "linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        [ 'OS == "linux" and use_allocator!="none"', {
           'dependencies': [
             '../base/allocator/allocator.gyp:allocator',
           ],
         }],
       ],  # end of 'conditions'
     },  # end of target 'remoting_unittests'
+    {
+      'target_name': 'remoting_browser_test_resources',
+      'type': 'none',
+      'copies': [
+        {
+          'destination': '<(PRODUCT_DIR)',
+            'files': [
+              '<@(remoting_webapp_js_browser_test_files)',
+            ],
+        },
+      ], #end of copies
+    },  # end of target 'remoting_browser_test_resources'
   ],  # end of targets
 }
diff --git a/remoting/remoting_webapp_files.gypi b/remoting/remoting_webapp_files.gypi
index 40b97dd..c862a13 100644
--- a/remoting/remoting_webapp_files.gypi
+++ b/remoting/remoting_webapp_files.gypi
@@ -48,6 +48,7 @@
       'webapp/clipboard.js',
       'webapp/media_source_renderer.js',
       'webapp/session_connector.js',
+      'webapp/smart_reconnector.js',
     ],
     # Remoting core JavaScript files.
     'remoting_webapp_js_core_files': [
@@ -119,6 +120,10 @@
     'remoting_webapp_js_gnubby_auth_files': [
       'webapp/gnubby_auth_handler.js',
     ],
+    # browser test JavaScript files.
+    'remoting_webapp_js_browser_test_files': [
+      'webapp/browser_test/browser_test.js',
+    ],
     # The JavaScript files required by main.html.
     'remoting_webapp_main_html_js_files': [
       # Include the core files first as it is required by the other files.
@@ -134,6 +139,9 @@
       '<@(remoting_webapp_js_ui_host_control_files)',
       '<@(remoting_webapp_js_ui_host_display_files)',
       '<@(remoting_webapp_js_wcs_container_files)',
+      # Uncomment this line to include browser test files in the web app
+      # to expedite debugging or local development.
+      # '<@(remoting_webapp_js_browser_test_files)'
     ],
 
     # The JavaScript files required by wcs_sandbox.html.
diff --git a/remoting/resources/remoting_strings.grd b/remoting/resources/remoting_strings.grd
index 35367d1..805a6d3 100644
--- a/remoting/resources/remoting_strings.grd
+++ b/remoting/resources/remoting_strings.grd
@@ -551,7 +551,7 @@
       <message desc="Footer text displayed at the host after an access code has been generated, but before a client connects." name="IDS_FOOTER_WAITING">
         waiting for connection…
       </message>
-      <message desc="Menu option for toggle full-screen mode. Equivalent to using the Wrench menu to do the same thing." name="IDS_FULL_SCREEN">
+      <message desc="Menu option for toggle full-screen mode. Equivalent to using the Wrench menu to do the same thing." name="IDS_FULL_SCREEN" formatter_data="android_java">
         Full screen
       </message>
       <message desc="Button displayed underneath explanatory text for app features. Clicking causes the text, infographic and the button itself to be replaced by the actual UI for that feature." name="IDS_GET_STARTED">
diff --git a/remoting/resources/remoting_strings_sr.xtb b/remoting/resources/remoting_strings_sr.xtb
index c2255b2..196d92e 100644
--- a/remoting/resources/remoting_strings_sr.xtb
+++ b/remoting/resources/remoting_strings_sr.xtb
@@ -83,7 +83,7 @@
 <translation id="2013996867038862849">Сви упарени клијенти су избрисани.</translation>
 <translation id="7081428606750359611">Хост за Chromoting</translation>
 <translation id="8228265668171617545">Откривена је некомпатибилна верзија Chromoting-а. Проверите да ли на оба рачунара имате најновију верзију Chrome-а и Chromoting-а и покушајте поново.</translation>
-<translation id="6985691951107243942">Желите ли стварно да онемогућите даљинско повезивање са хостом <ph name="HOSTNAME"/>? Ако се предомислите, потребно је да посетите тај рачунар да бисте поново омогућили везе.</translation>
+<translation id="6985691951107243942">Желите ли стварно да онемогућите даљинско повезивање са хостом <ph name="HOSTNAME"/>? Ако се предомислите, треба да посетите тај рачунар да бисте поново омогућили везе.</translation>
 <translation id="1436054138039008644"><ph name="HOSTNAME"/> (последњи пут онлајн <ph name="DATE"/>)</translation>
 <translation id="9149992051684092333">Да бисте почели да делите рачунар, у наставку дајте приступни кôд особи која ће вам помагати.</translation>
 <translation id="409800995205263688">НАПОМЕНА: Подешавања смерница дозвољавају везе само између рачунара у оквиру ваше мреже.</translation>
@@ -114,7 +114,7 @@
 <translation id="701976023053394610">Даљинска помоћ</translation>
 <translation id="6099500228377758828">Услуга Chrome удаљени рачунар</translation>
 <translation id="2747641796667576127">Ажурирања софтвера се обично обављају аутоматски, али могу да буду неуспешна у неким ретким случајевима. Ажурирање софтвера не би требало да траје дуже од неколико минута и може да се обавља док сте даљински повезани са рачунаром.</translation>
-<translation id="3933246213702324812">Chromoting на хосту <ph name="HOSTNAME"/> је застарео и потребно је да га ажурирате.</translation>
+<translation id="3933246213702324812">Chromoting на хосту <ph name="HOSTNAME"/> је застарео и треба да га ажурирате.</translation>
 <translation id="6193698048504518729">Повежите се са хостом <ph name="HOSTNAME"/></translation>
 <translation id="8116630183974937060">Дошло је до грешке на мрежи. Уверите се да је уређај онлајн и покушајте поново.</translation>
 <translation id="3020807351229499221">Ажурирање PIN-а није успело. Покушајте поново касније.</translation>
@@ -191,7 +191,7 @@
 <translation id="6668065415969892472">PIN је ажуриран.</translation>
 <translation id="4513946894732546136">Повратне информације</translation>
 <translation id="4277736576214464567">Приступни кôд је неважећи. Покушајте поново.</translation>
-<translation id="979100198331752041">Chrome удаљени рачунар на хосту <ph name="HOSTNAME"/> је застарео и потребно је да га ажурирате.</translation>
+<translation id="979100198331752041">Chrome удаљени рачунар на хосту <ph name="HOSTNAME"/> је застарео и треба да га ажурирате.</translation>
 <translation id="7729639150174291243">Нисте пријављени на Chrome удаљени рачунар. Пријавите се и покушајте поново.</translation>
 <translation id="2841013758207633010">Време</translation>
 <translation id="6011539954251327702">Chromoting вам омогућава да безбедно делите рачунар на вебу. Потребно је да оба корисника покрену апликацију Chromoting, која може да се пронађе на <ph name="URL"/>.</translation>
diff --git a/remoting/webapp/all_js_load.gtestjs b/remoting/webapp/all_js_load.gtestjs
index 6eedd3e..9b26026 100644
--- a/remoting/webapp/all_js_load.gtestjs
+++ b/remoting/webapp/all_js_load.gtestjs
@@ -57,6 +57,7 @@
     'remoting.js',
     'session_connector.js',
     'server_log_entry.js',
+    'smart_reconnector.js',
     'stats_accumulator.js',
     'toolbar.js',
     'ui_mode.js',
diff --git a/remoting/webapp/base.js b/remoting/webapp/base.js
index 19d574d..f010d73 100644
--- a/remoting/webapp/base.js
+++ b/remoting/webapp/base.js
@@ -50,8 +50,8 @@
     var error = /** @type {Error} */ e;
     var callstack = error.stack
       .replace(/^\s+(at eval )?at\s+/gm, '') // Remove 'at' and indentation.
-      .split('\n')
-      .splice(0,2); // Remove the stack of the current function.
+      .split('\n');
+    callstack.splice(0,2); // Remove the stack of the current function.
   }
   return callstack.join('\n');
 };
@@ -100,6 +100,19 @@
 base.doNothing = function() {};
 
 /**
+ * Returns an array containing the values of |dict|.
+ * @param {!Object} dict
+ * @return {Array}
+ */
+base.values = function (dict) {
+  return Object.keys(dict).map(
+    /** @param {string} key */
+    function(key) {
+      return dict[key];
+    });
+};
+
+/**
  * A mixin for classes with events.
  *
  * For example, to create an alarm event for SmokeDetector:
diff --git a/remoting/webapp/browser_test/browser_test.js b/remoting/webapp/browser_test/browser_test.js
new file mode 100644
index 0000000..85985aa
--- /dev/null
+++ b/remoting/webapp/browser_test/browser_test.js
@@ -0,0 +1,155 @@
+// 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.
+
+/**
+ * @fileoverview
+ * @suppress {checkTypes}  By default, JSCompile is not run on test files.
+ *    However, you can modify |remoting_webapp_files.gypi| locally to include
+ *    the test in the package to expedite local development.  This suppress
+ *    is here so that JSCompile won't complain.
+ *
+ * Provides basic functionality for JavaScript based browser test.
+ *
+ * To define a browser test, create a class under the browserTest namespace.
+ * You can pass arbitrary object literals to the browser test from the C++ test
+ * harness as the test data.  Each browser test class should implement the run
+ * method.
+ * For example:
+ *
+ * browserTest.My_Test = function(myObjectLiteral) {};
+ * browserTest.My_Test.prototype.run() = function() { ... };
+ *
+ * The browser test is async in nature.  It will keep running until
+ * browserTest.fail("My error message.") or browserTest.pass() is called.
+ *
+ * For example:
+ *
+ * browserTest.My_Test.prototype.run() = function() {
+ *   window.setTimeout(function() {
+ *     if (doSomething()) {
+ *       browserTest.pass();
+ *     } else {
+ *       browserTest.fail('My error message.');
+ *     }
+ *   }, 1000);
+ * };
+ *
+ * You will then invoke the test in C++ by calling:
+ *
+ *   RunJavaScriptTest(web_content, "My_Test", "{"
+ *    "pin: 123123"
+ *  "}");
+ */
+
+'use strict';
+
+var browserTest = {};
+
+browserTest.init = function() {
+  // The domAutomationController is used to communicate progress back to the
+  // C++ calling code.  It will only exist if chrome is run with the flag
+  // --dom-automation.  It is stubbed out here so that browser test can be run
+  // under the regular app.
+  browserTest.automationController_ = window.domAutomationController || {
+    send: function(json) {
+      var result = JSON.parse(json);
+      if (result.succeeded) {
+        console.log('Test Passed.');
+      } else {
+        console.error(result.error_message);
+      }
+    }
+  };
+};
+
+browserTest.assert = function(expr, message) {
+  if (!expr) {
+    message = (message) ? '<' + message + '>' : '';
+    browserTest.fail('Assertion failed.' + message);
+  }
+};
+
+browserTest.fail = function(error_message, opt_stack_trace) {
+  var stack_trace = opt_stack_trace || base.debug.callstack();
+
+  // To run browserTest locally:
+  // 1. Go to |remoting_webapp_files| and look for
+  //    |remoting_webapp_js_browser_test_files| and uncomment it
+  // 2. gclient runhooks
+  // 3. rebuild the webapp
+  // 4. Run it in the console browserTest.runTest(browserTest.MyTest, {});
+  // 5. The line below will trap the test in the debugger in case of
+  //    failure.
+  debugger;
+
+  browserTest.automationController_.send(JSON.stringify({
+    succeeded: false,
+    error_message: error_message,
+    stack_trace: stack_trace
+  }));
+};
+
+browserTest.pass = function() {
+  browserTest.automationController_.send(JSON.stringify({
+    succeeded: true,
+    error_message: '',
+    stack_trace: ''
+  }));
+};
+
+browserTest.clickOnControl = function(id) {
+  var element = document.getElementById(id);
+  browserTest.assert(element);
+  element.click();
+};
+
+/** @enum {number} */
+browserTest.Timeout = {
+  NONE: -1,
+  DEFAULT: 5000
+};
+
+browserTest.waitForUIMode = function(expectedMode, callback, opt_timeout) {
+  var uiModeChanged = remoting.testEvents.Names.uiModeChanged;
+  var timerId = null;
+
+  if (opt_timeout === undefined) {
+    opt_timeout = browserTest.Timeout.DEFAULT;
+  }
+
+  function onTimeout() {
+    remoting.testEvents.removeEventListener(uiModeChanged, onUIModeChanged);
+    browserTest.fail('Timeout waiting for ' + expectedMode);
+  }
+
+  function onUIModeChanged (mode) {
+    if (mode == expectedMode) {
+      remoting.testEvents.removeEventListener(uiModeChanged, onUIModeChanged);
+      window.clearTimeout(timerId);
+      timerId = null;
+      try {
+        callback();
+      } catch (e) {
+        browserTest.fail(e.toString(), e.stack);
+      }
+    }
+  }
+
+  if (opt_timeout != browserTest.Timeout.NONE) {
+    timerId = window.setTimeout(onTimeout.bind(window, timerId), opt_timeout);
+  }
+  remoting.testEvents.addEventListener(uiModeChanged, onUIModeChanged);
+};
+
+browserTest.runTest = function(testClass, data) {
+  try {
+    var test = new testClass(data);
+    browserTest.assert(typeof test.run == 'function');
+    test.run();
+  } catch (e) {
+    browserTest.fail(e.toString(), e.stack);
+  }
+};
+
+browserTest.init();
\ No newline at end of file
diff --git a/remoting/webapp/client_screen.js b/remoting/webapp/client_screen.js
index b870e8a..dd583b7 100644
--- a/remoting/webapp/client_screen.js
+++ b/remoting/webapp/client_screen.js
@@ -71,7 +71,7 @@
   } else {
     remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_ME2ME);
   }
-  remoting.clientSession.disconnect(true);
+  remoting.clientSession.disconnect(remoting.Error.NONE);
   remoting.clientSession = null;
   console.log('Disconnected.');
 };
@@ -102,13 +102,12 @@
 
 /**
  * Callback function called when the state of the client plugin changes. The
- * current state is available via the |state| member variable.
+ * current and previous states are available via the |state| member variable.
  *
- * @param {number} oldState The previous state of the plugin.
- * @param {number} newState The current state of the plugin.
+ * @param {remoting.ClientSession.StateEvent} state
  */
-function onClientStateChange_(oldState, newState) {
-  switch (newState) {
+function onClientStateChange_(state) {
+  switch (state.current) {
     case remoting.ClientSession.State.CLOSED:
       console.log('Connection closed by host');
       if (remoting.clientSession.getMode() ==
@@ -129,14 +128,16 @@
       break;
 
     default:
-      console.error('Unexpected client plugin state: ' + newState);
+      console.error('Unexpected client plugin state: ' + state.current);
       // This should only happen if the web-app and client plugin get out of
       // sync, so MISSING_PLUGIN is a suitable error.
       showConnectError_(remoting.Error.MISSING_PLUGIN);
       break;
   }
-  remoting.clientSession.disconnect(false);
-  remoting.clientSession.removePlugin();
+
+  remoting.clientSession.removeEventListener('stateChanged',
+                                             onClientStateChange_);
+  remoting.clientSession.cleanup();
   remoting.clientSession = null;
 }
 
@@ -332,7 +333,7 @@
 /** @param {remoting.ClientSession} clientSession */
 remoting.onConnected = function(clientSession) {
   remoting.clientSession = clientSession;
-  remoting.clientSession.setOnStateChange(onClientStateChange_);
+  remoting.clientSession.addEventListener('stateChanged', onClientStateChange_);
   setConnectionInterruptedButtonsText_();
   var connectedTo = document.getElementById('connected-to');
   connectedTo.innerText = remoting.connector.getHostDisplayName();
diff --git a/remoting/webapp/client_session.js b/remoting/webapp/client_session.js
index 92ded18..7b0d80e 100644
--- a/remoting/webapp/client_session.js
+++ b/remoting/webapp/client_session.js
@@ -44,6 +44,7 @@
  * @param {string} clientPairedSecret For paired Me2Me connections, the
  *     paired secret for this client, as issued by the host.
  * @constructor
+ * @extends {base.EventSource}
  */
 remoting.ClientSession = function(accessCode, fetchPin, fetchThirdPartyToken,
                                   authenticationMethods,
@@ -89,9 +90,6 @@
   /** @private */
   this.hasReceivedFrame_ = false;
   this.logToServer = new remoting.LogToServer();
-  /** @type {?function(remoting.ClientSession.State,
-                       remoting.ClientSession.State):void} */
-  this.onStateChange_ = null;
 
   /** @type {number?} @private */
   this.notifyClientResolutionTimer_ = null;
@@ -116,7 +114,7 @@
   this.callToggleFullScreen_ = remoting.fullscreen.toggle.bind(
       remoting.fullscreen);
   /** @private */
-  this.callOnFullScreenChanged_ = this.onFullScreenChanged_.bind(this);
+  this.callOnFullScreenChanged_ = this.onFullScreenChanged_.bind(this)
 
   /** @private */
   this.screenOptionsMenu_ = new remoting.MenuButton(
@@ -154,15 +152,15 @@
       'click', this.callSetScreenMode_, false);
   this.fullScreenButton_.addEventListener(
       'click', this.callToggleFullScreen_, false);
+  this.defineEvents(Object.keys(remoting.ClientSession.Events));
 };
 
-/**
- * @param {?function(remoting.ClientSession.State,
-                     remoting.ClientSession.State):void} onStateChange
- *     The callback to invoke when the session changes state.
- */
-remoting.ClientSession.prototype.setOnStateChange = function(onStateChange) {
-  this.onStateChange_ = onStateChange;
+base.extend(remoting.ClientSession, base.EventSource);
+
+/** @enum {string} */
+remoting.ClientSession.Events = {
+  stateChanged: 'stateChanged',
+  videoChannelStateChanged: 'videoChannelStateChanged'
 };
 
 /**
@@ -229,7 +227,20 @@
     throw "Invalid ClientSession.State: " + state;
   }
   return remoting.ClientSession.State[state];
-}
+};
+
+/**
+  @constructor
+  @param {remoting.ClientSession.State} current
+  @param {remoting.ClientSession.State} previous
+*/
+remoting.ClientSession.StateEvent = function(current, previous) {
+  /** @type {remoting.ClientSession.State} */
+  this.previous = previous
+
+  /** @type {remoting.ClientSession.State} */
+  this.current = current;
+};
 
 /** @enum {number} */
 remoting.ClientSession.ConnectionError = {
@@ -377,7 +388,11 @@
     this.plugin_.releaseAllKeys();
     if (this.plugin_.element()) {
       // Focus should stay on the element, not (for example) the toolbar.
-      this.plugin_.element().focus();
+      // Due to crbug.com/246335, we can't restore the focus immediately,
+      // otherwise the plugin gets confused about whether or not it has focus.
+      window.setTimeout(
+          this.plugin_.element().focus.bind(this.plugin_.element()),
+          0);
     }
   }
 };
@@ -561,19 +576,32 @@
 };
 
 /**
- * Deletes the <embed> element from the container and disconnects.
+ * Disconnect the current session with a particular |error|.  The session will
+ * raise a |stateChanged| event in response to it.  The caller should then call
+ * |cleanup| to remove and destroy the <embed> element.
  *
- * @param {boolean} isUserInitiated True for user-initiated disconnects, False
- *     for disconnects due to connection failures.
+ * @param {remoting.Error} error The reason for the disconnection.  Use
+ *    remoting.Error.NONE if there is no error.
  * @return {void} Nothing.
  */
-remoting.ClientSession.prototype.disconnect = function(isUserInitiated) {
-  if (isUserInitiated) {
-    // The plugin won't send a state change notification, so we explicitly log
-    // the fact that the connection has closed.
-    this.logToServer.logClientSessionStateChange(
-        remoting.ClientSession.State.CLOSED, remoting.Error.NONE, this.mode_);
-  }
+remoting.ClientSession.prototype.disconnect = function(error) {
+  var state = (error == remoting.Error.NONE) ?
+                  remoting.ClientSession.State.CLOSED :
+                  remoting.ClientSession.State.FAILED;
+
+  // The plugin won't send a state change notification, so we explicitly log
+  // the fact that the connection has closed.
+  this.logToServer.logClientSessionStateChange(state, error, this.mode_);
+  this.error_ = error;
+  this.setState_(state);
+};
+
+/**
+ * Deletes the <embed> element from the container and disconnects.
+ *
+ * @return {void} Nothing.
+ */
+remoting.ClientSession.prototype.cleanup = function() {
   remoting.wcsSandbox.setOnIq(null);
   this.sendIq_(
       '<cli:iq ' +
@@ -969,6 +997,9 @@
   } else {
     this.plugin_.element().classList.remove("session-client-inactive");
   }
+
+  this.raiseEvent(remoting.ClientSession.Events.videoChannelStateChanged,
+                  ready);
 };
 
 /**
@@ -1022,9 +1053,10 @@
   if (this.state_ == remoting.ClientSession.State.CONNECTED) {
     this.createGnubbyAuthHandler_();
   }
-  if (this.onStateChange_) {
-    this.onStateChange_(oldState, newState);
-  }
+
+  this.raiseEvent(remoting.ClientSession.Events.stateChanged,
+    new remoting.ClientSession.StateEvent(newState, oldState)
+  );
 };
 
 /**
@@ -1071,9 +1103,9 @@
  */
 remoting.ClientSession.prototype.pauseVideo = function(pause) {
   if (this.plugin_) {
-    this.plugin_.pauseVideo(pause)
+    this.plugin_.pauseVideo(pause);
   }
-}
+};
 
 /**
  * Requests that the host pause or resume audio.
diff --git a/remoting/webapp/html/client_plugin.html b/remoting/webapp/html/client_plugin.html
index af375ae..7353b23 100644
--- a/remoting/webapp/html/client_plugin.html
+++ b/remoting/webapp/html/client_plugin.html
@@ -4,8 +4,12 @@
 found in the LICENSE file.
 -->
 <div class="vertically-centered">
-    <div id="video-container">
-      <video id="mediasource-video-output"></video>
-      <div id="client-plugin-container" class="horizontally-centered"></div>
+  <div class="full-width">
+    <div class="horizontally-centered">
+      <div id="video-container">
+        <video id="mediasource-video-output"></video>
+        <div id="client-plugin-container"></div>
+      </div>
     </div>
+  </div>
 </div>
diff --git a/remoting/webapp/main.css b/remoting/webapp/main.css
index 2e16fbb..ec616a8 100644
--- a/remoting/webapp/main.css
+++ b/remoting/webapp/main.css
@@ -707,6 +707,10 @@
   display: none !important;
 }
 
+.full-width {
+  width: 100%;
+}
+
 .full-height {
   height: 100%;
 }
@@ -745,7 +749,6 @@
 /* video-container needs relative position so that mediasource-video-output can
  * be positioned relative to the parent with position:absolute. */
 #video-container {
-  width: 100%;
   position: relative;
 }
 
diff --git a/remoting/webapp/remoting.js b/remoting/webapp/remoting.js
index 07bd828..893edfd 100644
--- a/remoting/webapp/remoting.js
+++ b/remoting/webapp/remoting.js
@@ -14,6 +14,14 @@
  */
 remoting.isAppsV2 = false;
 
+
+/**
+ * @type {base.EventSource} An event source object for handling global events.
+ *    This is an interim hack.  Eventually, we should move functionalities
+ *    away from the remoting namespace and into smaller objects.
+ */
+remoting.testEvents;
+
 /**
  * Show the authorization consent UI and register a one-shot event handler to
  * continue the authorization process.
@@ -148,6 +156,14 @@
     };
     isWindowed_(onIsWindowed);
   }
+
+  remoting.testEvents = new base.EventSource();
+
+  /** @enum {string} */
+  remoting.testEvents.Names = {
+    uiModeChanged: 'uiModeChanged'
+  };
+  remoting.testEvents.defineEvents(base.values(remoting.testEvents.Names));
 };
 
 /**
diff --git a/remoting/webapp/session_connector.js b/remoting/webapp/session_connector.js
index 3c507d4..d3169bb 100644
--- a/remoting/webapp/session_connector.js
+++ b/remoting/webapp/session_connector.js
@@ -59,6 +59,19 @@
    */
   this.connectionMode_ = remoting.ClientSession.Mode.ME2ME;
 
+  /**
+   * @type {remoting.SmartReconnector}
+   * @private
+   */
+  this.reconnector_ = null;
+
+  /**
+   * @private
+   */
+  this.bound_ = {
+    onStateChange : this.onStateChange_.bind(this)
+  };
+
   // Initialize/declare per-connection state.
   this.reset();
 };
@@ -393,7 +406,9 @@
       authenticationMethods, this.hostId_, this.hostJid_, this.hostPublicKey_,
       this.connectionMode_, this.clientPairingId_, this.clientPairedSecret_);
   this.clientSession_.logHostOfflineErrors(!this.refreshHostJidIfOffline_);
-  this.clientSession_.setOnStateChange(this.onStateChange_.bind(this));
+  this.clientSession_.addEventListener(
+      remoting.ClientSession.Events.stateChanged,
+      this.bound_.onStateChange);
   this.clientSession_.createPluginAndConnect(this.pluginParent_,
                                              this.onExtensionMessage_);
 };
@@ -404,20 +419,24 @@
  * events). Errors that occur while connecting either trigger a reconnect
  * or notify the onError handler.
  *
- * @param {number} oldState The previous state of the plugin.
- * @param {number} newState The current state of the plugin.
+ * @param  {remoting.ClientSession.StateEvent} event
  * @return {void} Nothing.
  * @private
  */
-remoting.SessionConnector.prototype.onStateChange_ =
-    function(oldState, newState) {
-  switch (newState) {
+remoting.SessionConnector.prototype.onStateChange_ = function(event) {
+  switch (event.current) {
     case remoting.ClientSession.State.CONNECTED:
       // When the connection succeeds, deregister for state-change callbacks
       // and pass the session to the onOk callback. It is expected that it
       // will register a new state-change callback to handle disconnect
       // or error conditions.
-      this.clientSession_.setOnStateChange(null);
+      this.clientSession_.removeEventListener(
+          remoting.ClientSession.Events.stateChanged,
+          this.bound_.onStateChange);
+
+      base.dispose(this.reconnector_);
+      this.reconnector_ =
+          new remoting.SmartReconnector(this, this.clientSession_);
       this.onOk_(this.clientSession_);
       break;
 
@@ -452,6 +471,7 @@
       }
       if (error == remoting.Error.HOST_IS_OFFLINE &&
           this.refreshHostJidIfOffline_) {
+        // The plugin will be re-created when the host finished refreshing
         remoting.hostList.refresh(this.onHostListRefresh_.bind(this));
       } else {
         this.onError_(error);
@@ -459,7 +479,7 @@
       break;
 
     default:
-      console.error('Unexpected client plugin state: ' + newState);
+      console.error('Unexpected client plugin state: ' + event.current);
       // This should only happen if the web-app and client plugin get out of
       // sync, and even then the version check should ensure compatibility.
       this.onError_(remoting.Error.MISSING_PLUGIN);
@@ -512,4 +532,4 @@
     function(accessCode) {
   // Trim whitespace.
   return accessCode.replace(/\s/g, '');
-};
+};
\ No newline at end of file
diff --git a/remoting/webapp/smart_reconnector.js b/remoting/webapp/smart_reconnector.js
new file mode 100644
index 0000000..55186b4
--- /dev/null
+++ b/remoting/webapp/smart_reconnector.js
@@ -0,0 +1,143 @@
+// 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.
+
+/**
+ * @fileoverview
+ * Class handling reconnecting the session when it is disconnected due to
+ * network failure.
+ *
+ * The SmartReconnector listens for changes in connection state of
+ * |clientSession| to determine if a reconnection is needed.  It then calls into
+ * |connector| to reconnect the session.
+ */
+
+'use strict';
+
+/** @suppress {duplicate} */
+var remoting = remoting || {};
+
+/**
+ * @constructor
+ * @param {remoting.SessionConnector} connector This is used to reconnect the
+ *    the session when necessary
+ * @param {remoting.ClientSession} clientSession This represents the current
+ *    remote desktop connection.  It is used to monitor the changes in
+ *    connection state.
+ * @implements {base.Disposable}
+ */
+remoting.SmartReconnector = function(connector, clientSession) {
+  /** @private */
+  this.connector_ = connector;
+
+  /** @private */
+  this.clientSession_ = clientSession;
+
+  /** @private */
+  this.reconnectTimerId_ = null;
+
+  /** @private */
+  this.connectionTimeoutTimerId_ = null;
+
+  /** @private */
+  this.bound_ = {
+    reconnect: this.reconnect_.bind(this),
+    reconnectAsync: this.reconnectAsync_.bind(this),
+    startReconnectTimeout: this.startReconnectTimeout_.bind(this),
+    stateChanged: this.stateChanged_.bind(this),
+    videoChannelStateChanged: this.videoChannelStateChanged_.bind(this)
+  };
+
+  clientSession.addEventListener(
+      remoting.ClientSession.Events.stateChanged,
+      this.bound_.stateChanged);
+  clientSession.addEventListener(
+      remoting.ClientSession.Events.videoChannelStateChanged,
+      this.bound_.videoChannelStateChanged);
+};
+
+// The online event only means the network adapter is enabled, but
+// it doesn't necessarily mean that we have a working internet connection.
+// Therefore, delay the connection by |kReconnectDelay| to allow for the network
+// to connect.
+remoting.SmartReconnector.kReconnectDelay = 2000;
+
+// If no frames are received from the server for more than |kConnectionTimeout|,
+// disconnect the session.
+remoting.SmartReconnector.kConnectionTimeout = 10000;
+
+remoting.SmartReconnector.prototype = {
+  reconnect_: function() {
+    this.cancelPending_();
+    remoting.disconnect();
+    remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
+    this.connector_.reconnect();
+  },
+
+  reconnectAsync_: function() {
+    this.cancelPending_();
+    remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
+    this.reconnectTimerId_ = window.setTimeout(
+        this.bound_.reconnect, remoting.SmartReconnector.kReconnectDelay);
+  },
+
+  /**
+   * @param {remoting.ClientSession.StateEvent} event
+   */
+  stateChanged_: function(event) {
+    var State = remoting.ClientSession.State;
+    if (event.previous === State.CONNECTED && event.current === State.FAILED) {
+      this.cancelPending_();
+      if (navigator.onLine) {
+        this.reconnect_();
+      } else {
+        window.addEventListener('online', this.bound_.reconnectAsync, false);
+      }
+    }
+  },
+
+  /**
+   * @param {boolean} active  This function is called if no frames are received
+   *    on the client for more than 1 second.
+   */
+  videoChannelStateChanged_: function (active) {
+    this.cancelPending_();
+    if (!active) {
+      // If the channel becomes inactive due to a lack of network connection,
+      // wait for it to go online.  The plugin will try to reconnect the video
+      // channel once it is online.  If the video channels doesn't finish
+      // reconnecting within the timeout, tear down the session and reconnect.
+      if (navigator.onLine) {
+        this.reconnect_();
+      } else {
+        window.addEventListener(
+          'online', this.bound_.startReconnectTimeout, false);
+      }
+    }
+  },
+
+  startReconnectTimeout_: function () {
+    this.cancelPending_();
+    this.connectionTimeoutTimerId_ = window.setTimeout(
+          this.bound_.reconnect, remoting.SmartReconnector.kConnectionTimeout);
+  },
+
+  cancelPending_: function() {
+    window.removeEventListener(
+        'online', this.bound_.startReconnectTimeout, false);
+    window.removeEventListener('online', this.bound_.reconnectAsync, false);
+    window.clearTimeout(this.reconnectTimerId_);
+    window.clearTimeout(this.connectionTimeoutTimerId_);
+    this.reconnectTimerId_ = null;
+    this.connectionTimeoutTimerId_ = null;
+  },
+
+  dispose: function() {
+    this.clientSession_.removeEventListener(
+        remoting.ClientSession.Events.stateChanged,
+        this.bound_.stateChanged);
+    this.clientSession_.removeEventListener(
+        remoting.ClientSession.Events.videoChannelStateChanged,
+        this.bound_.videoChannelStateChanged);
+  }
+};
diff --git a/remoting/webapp/ui_mode.js b/remoting/webapp/ui_mode.js
index 579d88b..e9d8474 100644
--- a/remoting/webapp/ui_mode.js
+++ b/remoting/webapp/ui_mode.js
@@ -143,6 +143,8 @@
     htmlNode.classList.remove('no-horizontal-scroll');
     htmlNode.classList.remove('no-vertical-scroll');
   }
+
+  remoting.testEvents.raiseEvent(remoting.testEvents.Names.uiModeChanged, mode);
 };
 
 /**
diff --git a/sandbox/linux/DEPS b/sandbox/linux/DEPS
new file mode 100644
index 0000000..5c5f476
--- /dev/null
+++ b/sandbox/linux/DEPS
@@ -0,0 +1,25 @@
+include_rules = [
+  # First, exclude everything.
+  # Exclude a few dependencies that are included in the root DEPS and that we
+  # don't need.
+  # Sadly, there is no way to exclude all root DEPS since the root has no name.
+  "-ipc",
+  "-library_loaders",
+  "-third_party",
+  "-url",
+  # Make sure that each subdirectory has to declare its dependencies in
+  # sandbox/ explicitly.
+  "-sandbox/linux",
+
+  # Second, add what we want to allow.
+  # Anything included from sandbox/linux must be declared after this line or in
+  # a more specific DEPS file.
+  # base/, build/ and testing/ are already included in the global DEPS file,
+  # but be explicit.
+  "+base",
+  "+build",
+  "+testing",
+  "+sandbox/linux/sandbox_export.h",
+  # Everyone can use tests/
+  "+sandbox/linux/tests",
+]
diff --git a/sandbox/linux/sandbox_linux.gypi b/sandbox/linux/sandbox_linux.gypi
index 0cccd2e..e86345e 100644
--- a/sandbox/linux/sandbox_linux.gypi
+++ b/sandbox/linux/sandbox_linux.gypi
@@ -66,11 +66,28 @@
         '../..',
       ],
       'sources': [
+        'tests/sandbox_test_runner.h',
+        'tests/sandbox_test_runner_function_pointer.cc',
+        'tests/sandbox_test_runner_function_pointer.h',
         'tests/test_utils.cc',
         'tests/test_utils.h',
         'tests/unit_tests.cc',
         'tests/unit_tests.h',
       ],
+      'conditions': [
+        [ 'use_seccomp_bpf==1', {
+          'sources': [
+            'seccomp-bpf/bpf_tester_compatibility_delegate.cc',
+            'seccomp-bpf/bpf_tester_compatibility_delegate.h',
+            'seccomp-bpf/bpf_tests.h',
+            'seccomp-bpf/sandbox_bpf_test_runner.cc',
+            'seccomp-bpf/sandbox_bpf_test_runner.h',
+          ],
+          'dependencies': [
+            'seccomp_bpf',
+          ]
+        }],
+      ],
     },
     {
       # The main sandboxing test target.
@@ -112,6 +129,7 @@
         'seccomp-bpf/linux_seccomp.h',
         'seccomp-bpf/sandbox_bpf.cc',
         'seccomp-bpf/sandbox_bpf.h',
+        'seccomp-bpf/sandbox_bpf_compatibility_policy.h',
         'seccomp-bpf/sandbox_bpf_policy.h',
         'seccomp-bpf/syscall.cc',
         'seccomp-bpf/syscall.h',
diff --git a/sandbox/linux/sandbox_linux_test_sources.gypi b/sandbox/linux/sandbox_linux_test_sources.gypi
index 9764830..bf41471 100644
--- a/sandbox/linux/sandbox_linux_test_sources.gypi
+++ b/sandbox/linux/sandbox_linux_test_sources.gypi
@@ -31,7 +31,8 @@
     }],
     [ 'use_seccomp_bpf==1', {
       'sources': [
-        'seccomp-bpf/bpf_tests.h',
+        'seccomp-bpf-helpers/baseline_policy_unittest.cc',
+        'seccomp-bpf/bpf_tests_unittest.cc',
         'seccomp-bpf/codegen_unittest.cc',
         'seccomp-bpf/errorcode_unittest.cc',
         'seccomp-bpf/sandbox_bpf_unittest.cc',
diff --git a/sandbox/linux/seccomp-bpf-helpers/DEPS b/sandbox/linux/seccomp-bpf-helpers/DEPS
new file mode 100644
index 0000000..e8000d3
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf-helpers/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+  "+sandbox/linux/services",
+  "+sandbox/linux/seccomp-bpf",
+]
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
index 79b5b02..217bdac 100644
--- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
@@ -97,6 +97,10 @@
     return ErrorCode(ErrorCode::ERR_ALLOWED);
   }
 
+  if (sysno == __NR_clone) {
+    return RestrictCloneToThreadsAndEPERMFork(sandbox);
+  }
+
 #if defined(__x86_64__) || defined(__arm__)
   if (sysno == __NR_socketpair) {
     // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen.
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc
new file mode 100644
index 0000000..9182e07
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc
@@ -0,0 +1,115 @@
+// 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.
+
+#include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "base/posix/eintr_wrapper.h"
+#include "base/threading/thread.h"
+#include "build/build_config.h"
+#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
+#include "sandbox/linux/seccomp-bpf/bpf_tests.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
+#include "sandbox/linux/services/linux_syscalls.h"
+#include "sandbox/linux/services/thread_helpers.h"
+#include "sandbox/linux/tests/unit_tests.h"
+
+namespace sandbox {
+
+namespace {
+
+// |pid| is the return value of a fork()-like call. This
+// makes sure that if fork() succeeded the child exits
+// and the parent waits for it.
+void HandlePostForkReturn(pid_t pid) {
+  const int kChildExitCode = 1;
+  if (pid > 0) {
+    int status = 0;
+    PCHECK(pid == HANDLE_EINTR(waitpid(pid, &status, 0)));
+    CHECK(WIFEXITED(status));
+    CHECK_EQ(kChildExitCode, WEXITSTATUS(status));
+  } else if (pid == 0) {
+    _exit(kChildExitCode);
+  }
+}
+
+// Check that HandlePostForkReturn works.
+TEST(BaselinePolicy, HandlePostForkReturn) {
+  pid_t pid = fork();
+  HandlePostForkReturn(pid);
+}
+
+BPF_TEST_C(BaselinePolicy, FchmodErrno, BaselinePolicy) {
+  int ret = fchmod(-1, 07777);
+  BPF_ASSERT_EQ(-1, ret);
+  // Without the sandbox, this would EBADF instead.
+  BPF_ASSERT_EQ(EPERM, errno);
+}
+
+// TODO(jln): make this work with the sanitizers.
+#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
+
+BPF_TEST_C(BaselinePolicy, ForkErrno, BaselinePolicy) {
+  errno = 0;
+  pid_t pid = fork();
+  const int fork_errno = errno;
+  HandlePostForkReturn(pid);
+
+  BPF_ASSERT_EQ(-1, pid);
+  BPF_ASSERT_EQ(EPERM, fork_errno);
+}
+
+pid_t ForkX86Glibc() {
+  return syscall(__NR_clone, CLONE_PARENT_SETTID | SIGCHLD);
+}
+
+BPF_TEST_C(BaselinePolicy, ForkX86Eperm, BaselinePolicy) {
+  errno = 0;
+  pid_t pid = ForkX86Glibc();
+  const int fork_errno = errno;
+  HandlePostForkReturn(pid);
+
+  BPF_ASSERT_EQ(-1, pid);
+  BPF_ASSERT_EQ(EPERM, fork_errno);
+}
+
+pid_t ForkARMGlibc() {
+  return syscall(__NR_clone,
+                 CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD);
+}
+
+BPF_TEST_C(BaselinePolicy, ForkArmEperm, BaselinePolicy) {
+  errno = 0;
+  pid_t pid = ForkARMGlibc();
+  const int fork_errno = errno;
+  HandlePostForkReturn(pid);
+
+  BPF_ASSERT_EQ(-1, pid);
+  BPF_ASSERT_EQ(EPERM, fork_errno);
+}
+
+BPF_TEST_C(BaselinePolicy, CreateThread, BaselinePolicy) {
+  base::Thread thread("sandbox_tests");
+  BPF_ASSERT(thread.Start());
+}
+
+BPF_DEATH_TEST_C(BaselinePolicy,
+                 DisallowedCloneFlagCrashes,
+                 DEATH_MESSAGE(GetCloneErrorMessageContentForTests()),
+                 BaselinePolicy) {
+  pid_t pid = syscall(__NR_clone, CLONE_THREAD | SIGCHLD);
+  HandlePostForkReturn(pid);
+}
+
+#endif  // !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
+
+}  // namespace
+
+}  // namespace sandbox
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
index 2f46401..29c5910 100644
--- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
@@ -19,6 +19,7 @@
 
 #include "base/basictypes.h"
 #include "base/logging.h"
+#include "build/build_config.h"
 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
@@ -51,25 +52,53 @@
 #endif
 }
 
+inline bool IsAndroid() {
+#if defined(OS_ANDROID)
+  return true;
+#else
+  return false;
+#endif
+}
+
 }  // namespace.
 
 namespace sandbox {
 
+// Allow Glibc's and Android pthread creation flags, crash on any other
+// thread creation attempts and EPERM attempts to use neither
+// CLONE_VM, nor CLONE_THREAD, which includes all fork() implementations.
 ErrorCode RestrictCloneToThreadsAndEPERMFork(SandboxBPF* sandbox) {
-  // Glibc's pthread.
-  return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
-                       CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
-                       CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS |
-                       CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID,
-                       ErrorCode(ErrorCode::ERR_ALLOWED),
-         sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
-                       CLONE_PARENT_SETTID | SIGCHLD,
-                       ErrorCode(EPERM),
-         // ARM
-         sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
-                       CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD,
-                       ErrorCode(EPERM),
-         sandbox->Trap(SIGSYSCloneFailure, NULL))));
+  if (!IsAndroid()) {
+    const uint64_t kGlibcPthreadFlags =
+        CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD |
+        CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID |
+        CLONE_CHILD_CLEARTID;
+
+    return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
+                         kGlibcPthreadFlags,
+                         ErrorCode(ErrorCode::ERR_ALLOWED),
+           sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
+                         CLONE_VM | CLONE_THREAD,
+                         sandbox->Trap(SIGSYSCloneFailure, NULL),
+                         ErrorCode(EPERM)));
+  } else {
+    const uint64_t kAndroidCloneMask = CLONE_VM | CLONE_FS | CLONE_FILES |
+                                       CLONE_SIGHAND | CLONE_THREAD |
+                                       CLONE_SYSVSEM;
+    const uint64_t kObsoleteAndroidCloneMask =
+        kAndroidCloneMask | CLONE_DETACHED;
+
+    return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
+                         kAndroidCloneMask,
+                         ErrorCode(ErrorCode::ERR_ALLOWED),
+           sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
+                         kObsoleteAndroidCloneMask,
+                         ErrorCode(ErrorCode::ERR_ALLOWED),
+           sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
+                         CLONE_VM | CLONE_THREAD,
+                         sandbox->Trap(SIGSYSCloneFailure, NULL),
+                         ErrorCode(EPERM))));
+  }
 }
 
 ErrorCode RestrictPrctl(SandboxBPF* sandbox) {
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
index 792807a..5f8785e 100644
--- a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
@@ -350,7 +350,6 @@
 // This should be thought through in conjunction with IsFutex().
 bool SyscallSets::IsAllowedProcessStartOrDeath(int sysno) {
   switch (sysno) {
-    case __NR_clone:  // TODO(jln): restrict flags.
     case __NR_exit:
     case __NR_exit_group:
     case __NR_wait4:
@@ -359,6 +358,7 @@
     case __NR_waitpid:
 #endif
       return true;
+    case __NR_clone:  // Should be parameter-restricted.
     case __NR_setns:  // Privileged.
     case __NR_fork:
 #if defined(__i386__) || defined(__x86_64__)
diff --git a/sandbox/linux/seccomp-bpf/DEPS b/sandbox/linux/seccomp-bpf/DEPS
new file mode 100644
index 0000000..15b2b36
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+sandbox/linux/services"
+]
diff --git a/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.cc b/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.cc
new file mode 100644
index 0000000..2fa209b
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.cc
@@ -0,0 +1,21 @@
+// 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.
+
+#include "sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h"
+
+namespace sandbox {
+
+// static
+template <>
+void* BPFTesterCompatibilityDelegate<void>::NewAux() {
+  return NULL;
+}
+
+// static
+template <>
+void BPFTesterCompatibilityDelegate<void>::DeleteAux(void* aux) {
+  CHECK(!aux);
+}
+
+}  // namespace sandbox
diff --git a/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h b/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h
new file mode 100644
index 0000000..c211d04
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h
@@ -0,0 +1,81 @@
+// 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.
+
+#ifndef SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTER_COMPATIBILITY_DELEGATE_H_
+#define SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTER_COMPATIBILITY_DELEGATE_H_
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "base/memory/scoped_ptr.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf_compatibility_policy.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h"
+#include "sandbox/linux/tests/sandbox_test_runner.h"
+#include "sandbox/linux/tests/unit_tests.h"
+
+namespace sandbox {
+
+// This templated class allows building a BPFTesterDelegate from a
+// deprecated-style BPF policy (that is a SyscallEvaluator function pointer,
+// instead of a SandboxBPFPolicy class), specified in |policy_function| and a
+// function pointer to a test in |test_function|.
+// This allows both the policy and the test function to take a pointer to an
+// object of type "Aux" as a parameter. This is used to implement the BPF_TEST
+// macro and should generally not be used directly.
+template <class Aux = void>
+class BPFTesterCompatibilityDelegate : public BPFTesterDelegate {
+ public:
+  typedef Aux AuxType;
+  BPFTesterCompatibilityDelegate(
+      void (*test_function)(AuxType*),
+      typename CompatibilityPolicy<AuxType>::SyscallEvaluator policy_function)
+      : aux_pointer_for_policy_(NULL),
+        test_function_(test_function),
+        policy_function_(policy_function) {
+    // This will be NULL iff AuxType is void.
+    aux_pointer_for_policy_ = NewAux();
+  }
+
+  virtual ~BPFTesterCompatibilityDelegate() {
+    DeleteAux(aux_pointer_for_policy_);
+  }
+
+  virtual scoped_ptr<SandboxBPFPolicy> GetSandboxBPFPolicy() OVERRIDE {
+    // The current method is guaranteed to only run in the child process
+    // running the test. In this process, the current object is guaranteed
+    // to live forever. So it's ok to pass aux_pointer_for_policy_ to
+    // the policy, which could in turn pass it to the kernel via Trap().
+    return scoped_ptr<SandboxBPFPolicy>(new CompatibilityPolicy<AuxType>(
+        policy_function_, aux_pointer_for_policy_));
+  }
+
+  virtual void RunTestFunction() OVERRIDE {
+    // Run the actual test.
+    // The current object is guaranteed to live forever in the child process
+    // where this will run.
+    test_function_(aux_pointer_for_policy_);
+  }
+
+ private:
+  // Allocate an object of type Aux. This is specialized to return NULL when
+  // trying to allocate a void.
+  static Aux* NewAux() { return new Aux(); }
+  static void DeleteAux(Aux* aux) { delete aux; }
+
+  AuxType* aux_pointer_for_policy_;
+  void (*test_function_)(AuxType*);
+  typename CompatibilityPolicy<AuxType>::SyscallEvaluator policy_function_;
+  DISALLOW_COPY_AND_ASSIGN(BPFTesterCompatibilityDelegate);
+};
+
+// Specialization of NewAux that returns NULL;
+template <>
+void* BPFTesterCompatibilityDelegate<void>::NewAux();
+template <>
+void BPFTesterCompatibilityDelegate<void>::DeleteAux(void* aux);
+
+}  // namespace sandbox
+
+#endif  // SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTER_COMPATIBILITY_DELEGATE_H_
diff --git a/sandbox/linux/seccomp-bpf/bpf_tests.h b/sandbox/linux/seccomp-bpf/bpf_tests.h
index 357e29c..8fa5579 100644
--- a/sandbox/linux/seccomp-bpf/bpf_tests.h
+++ b/sandbox/linux/seccomp-bpf/bpf_tests.h
@@ -5,42 +5,55 @@
 #ifndef SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTS_H__
 #define SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTS_H__
 
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
+#include "base/basictypes.h"
 #include "build/build_config.h"
+#include "sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h"
 #include "sandbox/linux/tests/unit_tests.h"
-#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
 
 namespace sandbox {
 
-// A BPF_DEATH_TEST is just the same as a BPF_TEST, but it assumes that the
-// test will fail with a particular known error condition. Use the DEATH_XXX()
-// macros from unit_tests.h to specify the expected error condition.
-// A BPF_DEATH_TEST is always disabled under ThreadSanitizer, see
-// crbug.com/243968.
-#define BPF_DEATH_TEST(test_case_name, test_name, death, policy, aux...) \
-  void BPF_TEST_##test_name(sandbox::BPFTests<aux>::AuxType& BPF_AUX);   \
-  TEST(test_case_name, DISABLE_ON_TSAN(test_name)) {                     \
-    sandbox::BPFTests<aux>::TestArgs arg(BPF_TEST_##test_name, policy);  \
-    sandbox::BPFTests<aux>::RunTestInProcess(                            \
-        sandbox::BPFTests<aux>::TestWrapper, &arg, death);               \
-  }                                                                      \
-  void BPF_TEST_##test_name(sandbox::BPFTests<aux>::AuxType& BPF_AUX)
+// BPF_TEST_C() is a special version of SANDBOX_TEST(). It runs a test function
+// in a sub-process, under a seccomp-bpf policy specified in
+// |bpf_policy_class_name| without failing on configurations that are allowed
+// to not support seccomp-bpf in their kernels.
+// This is the preferred format for new BPF tests. |bpf_policy_class_name| is a
+// class name  (which will be default-constructed) that implements the
+// SandboxBPFPolicy interface.
+// The test function's body can simply follow. Test functions should use
+// the BPF_ASSERT macros defined below, not GTEST's macros. The use of
+// CHECK* macros is supported but less robust.
+#define BPF_TEST_C(test_case_name, test_name, bpf_policy_class_name)     \
+  BPF_DEATH_TEST_C(                                                      \
+      test_case_name, test_name, DEATH_SUCCESS(), bpf_policy_class_name)
 
-// BPF_TEST() is a special version of SANDBOX_TEST(). It turns into a no-op,
-// if the host does not have kernel support for running BPF filters.
-// Also, it takes advantage of the Die class to avoid calling LOG(FATAL), from
-// inside our tests, as we don't need or even want all the error handling that
-// LOG(FATAL) would do.
-// BPF_TEST() takes a C++ data type as an optional fourth parameter. If
-// present, this sets up a variable that can be accessed as "BPF_AUX". This
-// variable will be passed as an argument to the "policy" function. Policies
-// would typically use it as an argument to SandboxBPF::Trap(), if they want to
-// communicate data between the BPF_TEST() and a Trap() function.
-#define BPF_TEST(test_case_name, test_name, policy, aux...) \
-  BPF_DEATH_TEST(test_case_name, test_name, DEATH_SUCCESS(), policy, aux)
+// Identical to BPF_TEST_C but allows to specify the nature of death.
+#define BPF_DEATH_TEST_C(                                            \
+    test_case_name, test_name, death, bpf_policy_class_name)         \
+  void BPF_TEST_C_##test_name();                                     \
+  TEST(test_case_name, DISABLE_ON_TSAN(test_name)) {                 \
+    sandbox::SandboxBPFTestRunner bpf_test_runner(                   \
+        new sandbox::BPFTesterSimpleDelegate<bpf_policy_class_name>( \
+            BPF_TEST_C_##test_name));                                \
+    sandbox::UnitTests::RunTestInProcess(&bpf_test_runner, death);   \
+  }                                                                  \
+  void BPF_TEST_C_##test_name()
+
+// This form of BPF_TEST is a little verbose and should be reserved for complex
+// tests where a lot of control is required.
+// |bpf_tester_delegate_class| must be a classname implementing the
+// BPFTesterDelegate interface.
+#define BPF_TEST_D(test_case_name, test_name, bpf_tester_delegate_class)     \
+  BPF_DEATH_TEST_D(                                                          \
+      test_case_name, test_name, DEATH_SUCCESS(), bpf_tester_delegate_class)
+
+// Identical to BPF_TEST_D but allows to specify the nature of death.
+#define BPF_DEATH_TEST_D(                                          \
+    test_case_name, test_name, death, bpf_tester_delegate_class)   \
+  TEST(test_case_name, DISABLE_ON_TSAN(test_name)) {               \
+    sandbox::SandboxBPFTestRunner bpf_test_runner(                 \
+        new bpf_tester_delegate_class());                          \
+    sandbox::UnitTests::RunTestInProcess(&bpf_test_runner, death); \
+  }
 
 // Assertions are handled exactly the same as with a normal SANDBOX_TEST()
 #define BPF_ASSERT SANDBOX_ASSERT
@@ -51,70 +64,61 @@
 #define BPF_ASSERT_LE(x, y) BPF_ASSERT((x) <= (y))
 #define BPF_ASSERT_GE(x, y) BPF_ASSERT((x) >= (y))
 
-// The "Aux" type is optional. We use an "empty" type by default, so that if
-// the caller doesn't provide any type, all the BPF_AUX related data compiles
-// to nothing.
-template <class Aux = int[0]>
-class BPFTests : public UnitTests {
+// This form of BPF_TEST is now discouraged (but still allowed) in favor of
+// BPF_TEST_D and BPF_TEST_C.
+// The |policy| parameter should be a SyscallEvaluator function pointer
+// (which is now a deprecated way of expressing policies).
+// BPF_TEST() takes a C++ data type as an optional fourth parameter. If
+// present, this sets up a variable that can be accessed as "BPF_AUX". This
+// variable will be passed as an argument to the "policy" function. Policies
+// would typically use it as an argument to SandboxBPF::Trap(), if they want to
+// communicate data between the BPF_TEST() and a Trap() function. The life-time
+// of this object is the same as the life-time of the process running under the
+// seccomp-bpf policy.
+// The type specified in |aux| and the last parameter of the policy function
+// must be compatible. If |aux| is not specified, the policy function must
+// take a void* as its last parameter (that is, must have the EvaluateSyscall
+// type).
+#define BPF_TEST(test_case_name, test_name, policy, aux...)               \
+  BPF_DEATH_TEST(test_case_name, test_name, DEATH_SUCCESS(), policy, aux)
+
+// A BPF_DEATH_TEST is just the same as a BPF_TEST, but it assumes that the
+// test will fail with a particular known error condition. Use the DEATH_XXX()
+// macros from unit_tests.h to specify the expected error condition.
+#define BPF_DEATH_TEST(test_case_name, test_name, death, policy, aux...)       \
+  void BPF_TEST_##test_name(                                                   \
+      sandbox::BPFTesterCompatibilityDelegate<aux>::AuxType* BPF_AUX);         \
+  TEST(test_case_name, DISABLE_ON_TSAN(test_name)) {                           \
+    sandbox::SandboxBPFTestRunner bpf_test_runner(                             \
+        new sandbox::BPFTesterCompatibilityDelegate<aux>(BPF_TEST_##test_name, \
+                                                         policy));             \
+    sandbox::UnitTests::RunTestInProcess(&bpf_test_runner, death);             \
+  }                                                                            \
+  void BPF_TEST_##test_name(                                                   \
+      sandbox::BPFTesterCompatibilityDelegate<aux>::AuxType* BPF_AUX)
+
+// This class takes a simple function pointer as a constructor parameter and a
+// class name as a template parameter to implement the BPFTesterDelegate
+// interface which can be used to build BPF unittests with
+// the SandboxBPFTestRunner class.
+template <class PolicyClass>
+class BPFTesterSimpleDelegate : public BPFTesterDelegate {
  public:
-  typedef Aux AuxType;
+  explicit BPFTesterSimpleDelegate(void (*test_function)(void))
+      : test_function_(test_function) {}
+  virtual ~BPFTesterSimpleDelegate() {}
 
-  class TestArgs {
-   public:
-    TestArgs(void (*t)(AuxType&), sandbox::SandboxBPF::EvaluateSyscall p)
-        : test_(t), policy_(p), aux_() {}
-
-    void (*test() const)(AuxType&) { return test_; }
-    sandbox::SandboxBPF::EvaluateSyscall policy() const { return policy_; }
-
-   private:
-    friend class BPFTests;
-
-    void (*test_)(AuxType&);
-    sandbox::SandboxBPF::EvaluateSyscall policy_;
-    AuxType aux_;
-  };
-
-  static void TestWrapper(void* void_arg) {
-    TestArgs* arg = reinterpret_cast<TestArgs*>(void_arg);
-    sandbox::Die::EnableSimpleExit();
-    if (sandbox::SandboxBPF::SupportsSeccompSandbox(-1) ==
-        sandbox::SandboxBPF::STATUS_AVAILABLE) {
-      // Ensure the the sandbox is actually available at this time
-      int proc_fd;
-      BPF_ASSERT((proc_fd = open("/proc", O_RDONLY | O_DIRECTORY)) >= 0);
-      BPF_ASSERT(sandbox::SandboxBPF::SupportsSeccompSandbox(proc_fd) ==
-                 sandbox::SandboxBPF::STATUS_AVAILABLE);
-
-      // Initialize and then start the sandbox with our custom policy
-      sandbox::SandboxBPF sandbox;
-      sandbox.set_proc_fd(proc_fd);
-      sandbox.SetSandboxPolicyDeprecated(arg->policy(), &arg->aux_);
-      BPF_ASSERT(sandbox.StartSandbox(
-          sandbox::SandboxBPF::PROCESS_SINGLE_THREADED));
-
-      arg->test()(arg->aux_);
-    } else {
-      printf("This BPF test is not fully running in this configuration!\n");
-      // Android and Valgrind are the only configurations where we accept not
-      // having kernel BPF support.
-      if (!IsAndroid() && !IsRunningOnValgrind()) {
-        const bool seccomp_bpf_is_supported = false;
-        BPF_ASSERT(seccomp_bpf_is_supported);
-      }
-      // Call the compiler and verify the policy. That's the least we can do,
-      // if we don't have kernel support.
-      sandbox::SandboxBPF sandbox;
-      sandbox.SetSandboxPolicyDeprecated(arg->policy(), &arg->aux_);
-      sandbox::SandboxBPF::Program* program =
-          sandbox.AssembleFilter(true /* force_verification */);
-      delete program;
-      sandbox::UnitTests::IgnoreThisTest();
-    }
+  virtual scoped_ptr<SandboxBPFPolicy> GetSandboxBPFPolicy() OVERRIDE {
+    return scoped_ptr<SandboxBPFPolicy>(new PolicyClass());
+  }
+  virtual void RunTestFunction() OVERRIDE {
+    DCHECK(test_function_);
+    test_function_();
   }
 
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(BPFTests);
+  void (*test_function_)(void);
+  DISALLOW_COPY_AND_ASSIGN(BPFTesterSimpleDelegate);
 };
 
 }  // namespace sandbox
diff --git a/sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc b/sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc
new file mode 100644
index 0000000..d83b8ed
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc
@@ -0,0 +1,156 @@
+// 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.
+
+#include "sandbox/linux/seccomp-bpf/bpf_tests.h"
+
+#include <errno.h>
+#include <sys/ptrace.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "build/build_config.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
+#include "sandbox/linux/services/linux_syscalls.h"
+#include "sandbox/linux/tests/unit_tests.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace sandbox {
+
+namespace {
+
+ErrorCode EmptyPolicy(SandboxBPF* sandbox, int sysno, void* aux) {
+  // |aux| should always be NULL since a type was not specified as an argument
+  // to BPF_TEST.
+  BPF_ASSERT(NULL == aux);
+  if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
+    return ErrorCode(ENOSYS);
+  } else {
+    return ErrorCode(ErrorCode::ERR_ALLOWED);
+  }
+}
+
+BPF_TEST(BPFTest, BPFAUXIsNull, EmptyPolicy) {
+  // Check that the implicit BPF_AUX argument is NULL when we
+  // don't specify a fourth parameter to BPF_TEST.
+  BPF_ASSERT(NULL == BPF_AUX);
+}
+
+class FourtyTwo {
+ public:
+  static const int kMagicValue = 42;
+  FourtyTwo() : value_(kMagicValue) {}
+  int value() { return value_; }
+
+ private:
+  int value_;
+  DISALLOW_COPY_AND_ASSIGN(FourtyTwo);
+};
+
+ErrorCode EmptyPolicyTakesClass(SandboxBPF* sandbox,
+                                int sysno,
+                                FourtyTwo* fourty_two) {
+  // |aux| should point to an instance of FourtyTwo.
+  BPF_ASSERT(fourty_two);
+  BPF_ASSERT(FourtyTwo::kMagicValue == fourty_two->value());
+  if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
+    return ErrorCode(ENOSYS);
+  } else {
+    return ErrorCode(ErrorCode::ERR_ALLOWED);
+  }
+}
+
+BPF_TEST(BPFTest,
+         BPFAUXPointsToClass,
+         EmptyPolicyTakesClass,
+         FourtyTwo /* *BPF_AUX */) {
+  // BPF_AUX should point to an instance of FourtyTwo.
+  BPF_ASSERT(BPF_AUX);
+  BPF_ASSERT(FourtyTwo::kMagicValue == BPF_AUX->value());
+}
+
+void DummyTestFunction(FourtyTwo *fourty_two) {
+}
+
+TEST(BPFTest, BPFTesterCompatibilityDelegateLeakTest) {
+  // Don't do anything, simply gives dynamic tools an opportunity to detect
+  // leaks.
+  {
+    BPFTesterCompatibilityDelegate<FourtyTwo> simple_delegate(
+        DummyTestFunction, EmptyPolicyTakesClass);
+  }
+  {
+    // Test polymorphism.
+    scoped_ptr<BPFTesterDelegate> simple_delegate(
+        new BPFTesterCompatibilityDelegate<FourtyTwo>(DummyTestFunction,
+                                                      EmptyPolicyTakesClass));
+  }
+}
+
+class EnosysPtracePolicy : public SandboxBPFPolicy {
+ public:
+  EnosysPtracePolicy() {
+    my_pid_ = syscall(__NR_getpid);
+  }
+  virtual ~EnosysPtracePolicy() {
+    // Policies should be able to bind with the process on which they are
+    // created. They should never be created in a parent process.
+    BPF_ASSERT_EQ(my_pid_, syscall(__NR_getpid));
+  }
+
+  virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
+                                    int system_call_number) const OVERRIDE {
+    if (!SandboxBPF::IsValidSyscallNumber(system_call_number)) {
+      return ErrorCode(ENOSYS);
+    } else if (system_call_number == __NR_ptrace) {
+      // The EvaluateSyscall function should run in the process that created
+      // the current object.
+      BPF_ASSERT_EQ(my_pid_, syscall(__NR_getpid));
+      return ErrorCode(ENOSYS);
+    } else {
+      return ErrorCode(ErrorCode::ERR_ALLOWED);
+    }
+  }
+
+ private:
+  pid_t my_pid_;
+  DISALLOW_COPY_AND_ASSIGN(EnosysPtracePolicy);
+};
+
+class BasicBPFTesterDelegate : public BPFTesterDelegate {
+ public:
+  BasicBPFTesterDelegate() {}
+  virtual ~BasicBPFTesterDelegate() {}
+
+  virtual scoped_ptr<SandboxBPFPolicy> GetSandboxBPFPolicy() OVERRIDE {
+    return scoped_ptr<SandboxBPFPolicy>(new EnosysPtracePolicy());
+  }
+  virtual void RunTestFunction() OVERRIDE {
+    errno = 0;
+    int ret = ptrace(PTRACE_TRACEME, -1, NULL, NULL);
+    BPF_ASSERT(-1 == ret);
+    BPF_ASSERT(ENOSYS == errno);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BasicBPFTesterDelegate);
+};
+
+// This is the most powerful and complex way to create a BPF test, but it
+// requires a full class definition (BasicBPFTesterDelegate).
+BPF_TEST_D(BPFTest, BPFTestWithDelegateClass, BasicBPFTesterDelegate);
+
+// This is the simplest form of BPF tests.
+BPF_TEST_C(BPFTest, BPFTestWithInlineTest, EnosysPtracePolicy) {
+  errno = 0;
+  int ret = ptrace(PTRACE_TRACEME, -1, NULL, NULL);
+  BPF_ASSERT(-1 == ret);
+  BPF_ASSERT(ENOSYS == errno);
+}
+
+}  // namespace
+
+}  // namespace sandbox
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
index 1538fe8..497c343 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
@@ -25,6 +25,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
 #include "sandbox/linux/seccomp-bpf/codegen.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf_compatibility_policy.h"
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h"
 #include "sandbox/linux/seccomp-bpf/syscall.h"
 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
@@ -202,25 +203,6 @@
   SANDBOX_DIE(static_cast<char*>(aux));
 }
 
-// This class allows compatibility with the old, deprecated SetSandboxPolicy.
-class CompatibilityPolicy : public SandboxBPFPolicy {
- public:
-  CompatibilityPolicy(SandboxBPF::EvaluateSyscall syscall_evaluator, void* aux)
-      : syscall_evaluator_(syscall_evaluator), aux_(aux) {
-    DCHECK(syscall_evaluator_);
-  }
-
-  virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
-                                    int system_call_number) const OVERRIDE {
-    return syscall_evaluator_(sandbox_compiler, system_call_number, aux_);
-  }
-
- private:
-  SandboxBPF::EvaluateSyscall syscall_evaluator_;
-  void* aux_;
-  DISALLOW_COPY_AND_ASSIGN(CompatibilityPolicy);
-};
-
 }  // namespace
 
 SandboxBPF::SandboxBPF()
@@ -498,7 +480,7 @@
   if (sandbox_has_started_ || !conds_) {
     SANDBOX_DIE("Cannot change policy after sandbox has started");
   }
-  SetSandboxPolicy(new CompatibilityPolicy(syscall_evaluator, aux));
+  SetSandboxPolicy(new CompatibilityPolicy<void>(syscall_evaluator, aux));
 }
 
 // Don't take a scoped_ptr here, polymorphism make their use awkward.
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.h b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
index 67b84b9..2391c5d 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.h
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
@@ -73,7 +73,6 @@
   typedef ErrorCode (*EvaluateSyscall)(SandboxBPF* sandbox_compiler,
                                        int system_call_number,
                                        void* aux);
-  typedef std::vector<std::pair<EvaluateSyscall, void*> > Evaluators;
   // A vector of BPF instructions that need to be installed as a filter
   // program in the kernel.
   typedef std::vector<struct sock_filter> Program;
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_compatibility_policy.h b/sandbox/linux/seccomp-bpf/sandbox_bpf_compatibility_policy.h
new file mode 100644
index 0000000..bd947ad
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_compatibility_policy.h
@@ -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.
+
+#ifndef SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_COMPATIBILITY_POLICY_H_
+#define SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_COMPATIBILITY_POLICY_H_
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h"
+
+namespace sandbox {
+
+// This class allows compatibility with the old, deprecated
+// policies that were designed for SetSandboxPolicyDeprecated().
+template <class AuxType>
+class CompatibilityPolicy : public SandboxBPFPolicy {
+ public:
+  typedef ErrorCode (*SyscallEvaluator)(SandboxBPF* sandbox_compiler,
+                                        int system_call_number,
+                                        AuxType* aux);
+  CompatibilityPolicy(SyscallEvaluator syscall_evaluator, AuxType* aux)
+      : syscall_evaluator_(syscall_evaluator), aux_(aux) {}
+
+  virtual ~CompatibilityPolicy() {}
+
+  virtual ErrorCode EvaluateSyscall(SandboxBPF* sandbox_compiler,
+                                    int system_call_number) const OVERRIDE {
+    return syscall_evaluator_(sandbox_compiler, system_call_number, aux_);
+  }
+
+ private:
+  SyscallEvaluator syscall_evaluator_;
+  AuxType* aux_;
+  DISALLOW_COPY_AND_ASSIGN(CompatibilityPolicy);
+};
+
+}  // namespace sandbox
+
+#endif  // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_COMPATIBILITY_POLICY_H_
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.cc
new file mode 100644
index 0000000..ade1d49
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.cc
@@ -0,0 +1,70 @@
+// 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.
+
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h"
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
+#include "sandbox/linux/tests/unit_tests.h"
+
+namespace sandbox {
+
+SandboxBPFTestRunner::SandboxBPFTestRunner(
+    BPFTesterDelegate* bpf_tester_delegate)
+    : bpf_tester_delegate_(bpf_tester_delegate) {
+}
+
+SandboxBPFTestRunner::~SandboxBPFTestRunner() {
+}
+
+void SandboxBPFTestRunner::Run() {
+  DCHECK(bpf_tester_delegate_);
+  sandbox::Die::EnableSimpleExit();
+
+  scoped_ptr<SandboxBPFPolicy> policy =
+      bpf_tester_delegate_->GetSandboxBPFPolicy();
+
+  if (sandbox::SandboxBPF::SupportsSeccompSandbox(-1) ==
+      sandbox::SandboxBPF::STATUS_AVAILABLE) {
+    // Ensure the the sandbox is actually available at this time
+    int proc_fd;
+    SANDBOX_ASSERT((proc_fd = open("/proc", O_RDONLY | O_DIRECTORY)) >= 0);
+    SANDBOX_ASSERT(sandbox::SandboxBPF::SupportsSeccompSandbox(proc_fd) ==
+                   sandbox::SandboxBPF::STATUS_AVAILABLE);
+
+    // Initialize and then start the sandbox with our custom policy
+    sandbox::SandboxBPF sandbox;
+    sandbox.set_proc_fd(proc_fd);
+    sandbox.SetSandboxPolicy(policy.release());
+    SANDBOX_ASSERT(
+        sandbox.StartSandbox(sandbox::SandboxBPF::PROCESS_SINGLE_THREADED));
+
+    // Run the actual test.
+    bpf_tester_delegate_->RunTestFunction();
+  } else {
+    printf("This BPF test is not fully running in this configuration!\n");
+    // Android and Valgrind are the only configurations where we accept not
+    // having kernel BPF support.
+    if (!IsAndroid() && !IsRunningOnValgrind()) {
+      const bool seccomp_bpf_is_supported = false;
+      SANDBOX_ASSERT(seccomp_bpf_is_supported);
+    }
+    // Call the compiler and verify the policy. That's the least we can do,
+    // if we don't have kernel support.
+    sandbox::SandboxBPF sandbox;
+    sandbox.SetSandboxPolicy(policy.release());
+    sandbox::SandboxBPF::Program* program =
+        sandbox.AssembleFilter(true /* force_verification */);
+    delete program;
+    sandbox::UnitTests::IgnoreThisTest();
+  }
+}
+
+}  // namespace sandbox
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h b/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h
new file mode 100644
index 0000000..c1beba2
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_TEST_RUNNER_H_
+#define SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_TEST_RUNNER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h"
+#include "sandbox/linux/tests/sandbox_test_runner.h"
+
+namespace sandbox {
+
+// To create a SandboxBPFTestRunner object, one needs to implement this
+// interface and pass an instance to the SandboxBPFTestRunner constructor.
+// In the child process running the test, the BPFTesterDelegate object is
+// guaranteed to not be destroyed until the child process terminates.
+class BPFTesterDelegate {
+ public:
+  BPFTesterDelegate() {}
+  virtual ~BPFTesterDelegate() {}
+
+  // This will instanciate a policy suitable for the test we want to run. It is
+  // guaranteed to only be called from the child process that will run the
+  // test.
+  virtual scoped_ptr<SandboxBPFPolicy> GetSandboxBPFPolicy() = 0;
+  // This will be called from a child process with the BPF sandbox turned on.
+  virtual void RunTestFunction() = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BPFTesterDelegate);
+};
+
+// This class implements the SandboxTestRunner interface and Run() will
+// initialize a seccomp-bpf sandbox (specified by |bpf_tester_delegate|) and
+// run a test function (via |bpf_tester_delegate|) if the current kernel
+// configuration allows it. If it can not run the test under seccomp-bpf,
+// Run() will still compile the policy which should allow to get some coverage
+// under tools such as Valgrind.
+class SandboxBPFTestRunner : public SandboxTestRunner {
+ public:
+  // This constructor takes ownership of the |bpf_tester_delegate| object.
+  // (It doesn't take a scoped_ptr since they make polymorphism verbose).
+  explicit SandboxBPFTestRunner(BPFTesterDelegate* bpf_tester_delegate);
+  virtual ~SandboxBPFTestRunner();
+
+  virtual void Run() OVERRIDE;
+
+ private:
+  scoped_ptr<BPFTesterDelegate> bpf_tester_delegate_;
+  DISALLOW_COPY_AND_ASSIGN(SandboxBPFTestRunner);
+};
+
+}  // namespace sandbox
+
+#endif  // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_TEST_RUNNER_H_
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
index 5c5c627..3b7470b 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
@@ -21,6 +21,7 @@
 #include <ostream>
 
 #include "base/bind.h"
+#include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "build/build_config.h"
 #include "sandbox/linux/seccomp-bpf/bpf_tests.h"
@@ -115,7 +116,10 @@
 
 // A simple blacklist test
 
-ErrorCode BlacklistNanosleepPolicy(SandboxBPF*, int sysno, void*) {
+ErrorCode BlacklistNanosleepPolicy(SandboxBPF*, int sysno, void* aux) {
+  // Since no type was specified in BPF_TEST as a fourth argument,
+  // |aux| must be NULL here.
+  BPF_ASSERT(NULL == aux);
   if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
     // FIXME: we should really not have to do that in a trivial policy
     return ErrorCode(ENOSYS);
@@ -136,7 +140,6 @@
   BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1);
   BPF_ASSERT(errno == EACCES);
 }
-
 // Now do a simple whitelist test
 
 ErrorCode WhitelistGetpidPolicy(SandboxBPF*, int sysno, void*) {
@@ -161,7 +164,6 @@
 }
 
 // A simple blacklist policy, with a SIGSYS handler
-
 intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) {
   // We also check that the auxiliary data is correct
   SANDBOX_ASSERT(aux);
@@ -171,7 +173,7 @@
 
 ErrorCode BlacklistNanosleepPolicySigsys(SandboxBPF* sandbox,
                                          int sysno,
-                                         void* aux) {
+                                         int* aux) {
   if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
     // FIXME: we should really not have to do that in a trivial policy
     return ErrorCode(ENOSYS);
@@ -188,20 +190,20 @@
 BPF_TEST(SandboxBPF,
          BasicBlacklistWithSigsys,
          BlacklistNanosleepPolicySigsys,
-         int /* BPF_AUX */) {
+         int /* (*BPF_AUX) */) {
   // getpid() should work properly
   errno = 0;
   BPF_ASSERT(syscall(__NR_getpid) > 0);
   BPF_ASSERT(errno == 0);
 
   // Our Auxiliary Data, should be reset by the signal handler
-  BPF_AUX = -1;
+  *BPF_AUX = -1;
   const struct timespec ts = {0, 0};
   BPF_ASSERT(syscall(__NR_nanosleep, &ts, NULL) == -1);
   BPF_ASSERT(errno == ENOMEM);
 
   // We expect the signal handler to modify AuxData
-  BPF_ASSERT(BPF_AUX == kExpectedReturnValue);
+  BPF_ASSERT(*BPF_AUX == kExpectedReturnValue);
 }
 
 // A simple test that verifies we can return arbitrary errno values.
@@ -444,7 +446,7 @@
   return SandboxBPF::ForwardSyscall(args);
 }
 
-ErrorCode GreyListedPolicy(SandboxBPF* sandbox, int sysno, void* aux) {
+ErrorCode GreyListedPolicy(SandboxBPF* sandbox, int sysno, int* aux) {
   // The use of UnsafeTrap() causes us to print a warning message. This is
   // generally desirable, but it results in the unittest failing, as it doesn't
   // expect any messages on "stderr". So, temporarily disable messages. The
@@ -477,12 +479,12 @@
   }
 }
 
-BPF_TEST(SandboxBPF, GreyListedPolicy, GreyListedPolicy, int /* BPF_AUX */) {
+BPF_TEST(SandboxBPF, GreyListedPolicy, GreyListedPolicy, int /* (*BPF_AUX) */) {
   BPF_ASSERT(syscall(__NR_getpid) == -1);
   BPF_ASSERT(errno == EPERM);
-  BPF_ASSERT(BPF_AUX == 0);
+  BPF_ASSERT(*BPF_AUX == 0);
   BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid));
-  BPF_ASSERT(BPF_AUX == 2);
+  BPF_ASSERT(*BPF_AUX == 2);
   char name[17] = {};
   BPF_ASSERT(!syscall(__NR_prctl,
                       PR_GET_NAME,
@@ -490,7 +492,7 @@
                       (void*)NULL,
                       (void*)NULL,
                       (void*)NULL));
-  BPF_ASSERT(BPF_AUX == 3);
+  BPF_ASSERT(*BPF_AUX == 3);
   BPF_ASSERT(*name);
 }
 
@@ -724,8 +726,9 @@
   }
 }
 
-ErrorCode DenyOpenPolicy(SandboxBPF* sandbox, int sysno, void* aux) {
-  InitializedOpenBroker* iob = static_cast<InitializedOpenBroker*>(aux);
+ErrorCode DenyOpenPolicy(SandboxBPF* sandbox,
+                         int sysno,
+                         InitializedOpenBroker* iob) {
   if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
     return ErrorCode(ENOSYS);
   }
@@ -752,9 +755,9 @@
 BPF_TEST(SandboxBPF,
          UseOpenBroker,
          DenyOpenPolicy,
-         InitializedOpenBroker /* BPF_AUX */) {
-  BPF_ASSERT(BPF_AUX.initialized());
-  BrokerProcess* broker_process = BPF_AUX.broker_process();
+         InitializedOpenBroker /* (*BPF_AUX) */) {
+  BPF_ASSERT(BPF_AUX->initialized());
+  BrokerProcess* broker_process = BPF_AUX->broker_process();
   BPF_ASSERT(broker_process != NULL);
 
   // First, use the broker "manually"
@@ -1161,15 +1164,18 @@
   static const int kMaxArgs = 6;
 };
 
-ErrorCode EqualityStressTestPolicy(SandboxBPF* sandbox, int sysno, void* aux) {
-  return reinterpret_cast<EqualityStressTest*>(aux)->Policy(sandbox, sysno);
+ErrorCode EqualityStressTestPolicy(SandboxBPF* sandbox,
+                                   int sysno,
+                                   EqualityStressTest* aux) {
+  DCHECK(aux);
+  return aux->Policy(sandbox, sysno);
 }
 
 BPF_TEST(SandboxBPF,
          EqualityTests,
          EqualityStressTestPolicy,
-         EqualityStressTest /* BPF_AUX */) {
-  BPF_AUX.VerifyFilter();
+         EqualityStressTest /* (*BPF_AUX) */) {
+  BPF_AUX->VerifyFilter();
 }
 
 ErrorCode EqualityArgumentWidthPolicy(SandboxBPF* sandbox, int sysno, void*) {
diff --git a/sandbox/linux/seccomp-bpf/syscall_unittest.cc b/sandbox/linux/seccomp-bpf/syscall_unittest.cc
index 60db69b..bdeee4f 100644
--- a/sandbox/linux/seccomp-bpf/syscall_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/syscall_unittest.cc
@@ -70,7 +70,7 @@
 
 // SIGSYS trap handler that will be called on __NR_uname.
 intptr_t CopySyscallArgsToAux(const struct arch_seccomp_data& args, void* aux) {
-  // |aux| is a pointer to our BPF_AUX.
+  // |aux| is our BPF_AUX pointer.
   std::vector<uint64_t>* const seen_syscall_args =
       static_cast<std::vector<uint64_t>*>(aux);
   BPF_ASSERT(arraysize(args.args) == 6);
@@ -78,7 +78,9 @@
   return -ENOMEM;
 }
 
-ErrorCode CopyAllArgsOnUnamePolicy(SandboxBPF* sandbox, int sysno, void* aux) {
+ErrorCode CopyAllArgsOnUnamePolicy(SandboxBPF* sandbox,
+                                   int sysno,
+                                   std::vector<uint64_t>* aux) {
   if (!SandboxBPF::IsValidSyscallNumber(sysno)) {
     return ErrorCode(ENOSYS);
   }
@@ -94,7 +96,7 @@
 BPF_TEST(Syscall,
          SyntheticSixArgs,
          CopyAllArgsOnUnamePolicy,
-         std::vector<uint64_t> /* BPF_AUX */) {
+         std::vector<uint64_t> /* (*BPF_AUX) */) {
   const int kExpectedValue = 42;
   // In this test we only pass integers to the kernel. We might want to make
   // additional tests to try other types. What we will see depends on
@@ -116,17 +118,17 @@
                             syscall_args[5]) == -ENOMEM);
 
   // We expect the trap handler to have copied the 6 arguments.
-  BPF_ASSERT(BPF_AUX.size() == 6);
+  BPF_ASSERT(BPF_AUX->size() == 6);
 
   // Don't loop here so that we can see which argument does cause the failure
   // easily from the failing line.
   // uint64_t is the type passed to our SIGSYS handler.
-  BPF_ASSERT(BPF_AUX[0] == static_cast<uint64_t>(syscall_args[0]));
-  BPF_ASSERT(BPF_AUX[1] == static_cast<uint64_t>(syscall_args[1]));
-  BPF_ASSERT(BPF_AUX[2] == static_cast<uint64_t>(syscall_args[2]));
-  BPF_ASSERT(BPF_AUX[3] == static_cast<uint64_t>(syscall_args[3]));
-  BPF_ASSERT(BPF_AUX[4] == static_cast<uint64_t>(syscall_args[4]));
-  BPF_ASSERT(BPF_AUX[5] == static_cast<uint64_t>(syscall_args[5]));
+  BPF_ASSERT((*BPF_AUX)[0] == static_cast<uint64_t>(syscall_args[0]));
+  BPF_ASSERT((*BPF_AUX)[1] == static_cast<uint64_t>(syscall_args[1]));
+  BPF_ASSERT((*BPF_AUX)[2] == static_cast<uint64_t>(syscall_args[2]));
+  BPF_ASSERT((*BPF_AUX)[3] == static_cast<uint64_t>(syscall_args[3]));
+  BPF_ASSERT((*BPF_AUX)[4] == static_cast<uint64_t>(syscall_args[4]));
+  BPF_ASSERT((*BPF_AUX)[5] == static_cast<uint64_t>(syscall_args[5]));
 }
 
 TEST(Syscall, ComplexSyscallSixArgs) {
diff --git a/sandbox/linux/suid/client/DEPS b/sandbox/linux/suid/client/DEPS
new file mode 100644
index 0000000..99a337d
--- /dev/null
+++ b/sandbox/linux/suid/client/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+sandbox/linux/services",
+]
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.cc b/sandbox/linux/suid/client/setuid_sandbox_client.cc
index 3300cb4..fc03cdd 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_client.cc
+++ b/sandbox/linux/suid/client/setuid_sandbox_client.cc
@@ -5,6 +5,8 @@
 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
 
 #include <fcntl.h>
+#include <stdlib.h>
+#include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -136,7 +138,7 @@
 
 SetuidSandboxClient* SetuidSandboxClient::Create() {
   base::Environment* environment(base::Environment::Create());
-  SetuidSandboxClient* sandbox_client(new(SetuidSandboxClient));
+  SetuidSandboxClient* sandbox_client(new SetuidSandboxClient);
 
   CHECK(environment);
   sandbox_client->env_ = environment;
@@ -152,6 +154,21 @@
   delete env_;
 }
 
+void SetuidSandboxClient::CloseDummyFile() {
+  // When we're launched through the setuid sandbox, SetupLaunchOptions
+  // arranges for kZygoteIdFd to be a dummy file descriptor to satisfy an
+  // ancient setuid sandbox ABI requirement. However, the descriptor is no
+  // longer needed, so we can simply close it right away now.
+  CHECK(IsSuidSandboxChild());
+
+  // Sanity check that kZygoteIdFd refers to a pipe.
+  struct stat st;
+  PCHECK(0 == fstat(kZygoteIdFd, &st));
+  CHECK(S_ISFIFO(st.st_mode));
+
+  PCHECK(0 == IGNORE_EINTR(close(kZygoteIdFd)));
+}
+
 bool SetuidSandboxClient::ChrootMe() {
   int ipc_fd = GetIPCDescriptor(env_);
 
@@ -226,12 +243,6 @@
   return false;
 }
 
-int SetuidSandboxClient::GetUniqueToChildFileDescriptor() {
-  // The setuid binary is hard-wired to close this in the helper process it
-  // creates.
-  return kZygoteIdFd;
-}
-
 base::FilePath SetuidSandboxClient::GetSandboxBinaryPath() {
   base::FilePath sandbox_binary;
   base::FilePath exe_dir;
@@ -256,8 +267,7 @@
   return sandbox_binary;
 }
 
-void SetuidSandboxClient::PrependWrapper(base::CommandLine* cmd_line,
-                                         base::LaunchOptions* options) {
+void SetuidSandboxClient::PrependWrapper(base::CommandLine* cmd_line) {
   std::string sandbox_binary(GetSandboxBinaryPath().value());
   struct stat st;
   if (sandbox_binary.empty() || stat(sandbox_binary.c_str(), &st) != 0) {
@@ -275,15 +285,30 @@
                << sandbox_binary << " is owned by root and has mode 4755.";
   }
 
-  if (cmd_line) {
-    cmd_line->PrependWrapper(sandbox_binary);
-  }
+  cmd_line->PrependWrapper(sandbox_binary);
+}
 
-  if (options) {
-    // Launching a setuid binary requires PR_SET_NO_NEW_PRIVS to not be used.
-    options->allow_new_privs = true;
-    UnsetExpectedEnvironmentVariables(&options->environ);
-  }
+void SetuidSandboxClient::SetupLaunchOptions(
+    base::LaunchOptions* options,
+    base::FileHandleMappingVector* fds_to_remap,
+    base::ScopedFD* dummy_fd) {
+  DCHECK(options);
+  DCHECK(fds_to_remap);
+
+  // Launching a setuid binary requires PR_SET_NO_NEW_PRIVS to not be used.
+  options->allow_new_privs = true;
+  UnsetExpectedEnvironmentVariables(&options->environ);
+
+  // Set dummy_fd to the reading end of a closed pipe.
+  int pipe_fds[2];
+  PCHECK(0 == pipe(pipe_fds));
+  PCHECK(0 == IGNORE_EINTR(close(pipe_fds[1])));
+  dummy_fd->reset(pipe_fds[0]);
+
+  // We no longer need a dummy socket for discovering the child's PID,
+  // but the sandbox is still hard-coded to expect a file descriptor at
+  // kZygoteIdFd. Fixing this requires a sandbox API change. :(
+  fds_to_remap->push_back(std::make_pair(dummy_fd->get(), kZygoteIdFd));
 }
 
 void SetuidSandboxClient::SetupLaunchEnvironment() {
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.h b/sandbox/linux/suid/client/setuid_sandbox_client.h
index 332c63b..2bbad7a 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_client.h
+++ b/sandbox/linux/suid/client/setuid_sandbox_client.h
@@ -8,14 +8,10 @@
 #include "base/basictypes.h"
 #include "base/callback_forward.h"
 #include "base/files/file_path.h"
+#include "base/files/scoped_file.h"
+#include "base/process/launch.h"
 #include "sandbox/linux/sandbox_export.h"
 
-namespace base {
-class CommandLine;
-class Environment;
-struct LaunchOptions;
-}
-
 namespace sandbox {
 
 // Helper class to use the setuid sandbox. This class is to be used both
@@ -28,23 +24,21 @@
 // 1. A calls SetupLaunchEnvironment()
 // 2. A sets up a CommandLine and then amends it with
 //    PrependWrapper() (or manually, by relying on GetSandboxBinaryPath()).
-// 3. A makes sure that GetUniqueToChildFileDescriptor() is an existing file
-//    descriptor that can be closed by the helper process created by the
-//    setuid sandbox. (This is the right file descriptor to use for magic
-//    "must-be-unique" sockets that are use to identify processes across
-//    pid namespaces.)
+// 3. A uses SetupLaunchOptions() to arrange for a dummy descriptor for the
+//    setuid sandbox ABI.
 // 4. A launches B with base::LaunchProcess, using the amended CommandLine.
-// 5. B performs various initializations that require access to the file
+// 5. B uses CloseDummyFile() to close the dummy file descriptor.
+// 6. B performs various initializations that require access to the file
 //    system.
-// 5.b (optional) B uses sandbox::Credentials::HasOpenDirectory() to verify
+// 6.b (optional) B uses sandbox::Credentials::HasOpenDirectory() to verify
 //    that no directory is kept open (which would allow bypassing the setuid
 //    sandbox).
-// 6. B should be prepared to assume the role of init(1). In particular, B
+// 7. B should be prepared to assume the role of init(1). In particular, B
 //    cannot receive any signal from any other process, excluding SIGKILL.
 //    If B dies, all the processes in the namespace will die.
 //    B can fork() and the parent can assume the role of init(1), by using
 //    CreateInitProcessReaper().
-// 7. B requests being chroot-ed through ChrootMe() and
+// 8. B requests being chroot-ed through ChrootMe() and
 //    requests other sandboxing status via the status functions.
 class SANDBOX_EXPORT SetuidSandboxClient {
  public:
@@ -52,6 +46,8 @@
   static class SetuidSandboxClient* Create();
   ~SetuidSandboxClient();
 
+  // Close the dummy file descriptor leftover from the sandbox ABI.
+  void CloseDummyFile();
   // Ask the setuid helper over the setuid sandbox IPC channel to chroot() us
   // to an empty directory.
   // Will only work if we have been launched through the setuid helper.
@@ -76,22 +72,21 @@
   // The setuid sandbox may still be disabled via the environment.
   // This is tracked in crbug.com/245376.
   bool IsDisabledViaEnvironment();
-  // When using the setuid sandbox, an extra helper process is created.
-  // Unfortunately, this helper process is hard-wired to close a specific file
-  // descriptor.
-  // The caller must make sure that GetUniqueToChildFileDescriptor() is an
-  // existing file descriptor that can be closed by the helper process. It's ok
-  // to make it a dummy, useless file descriptor if needed.
-  int GetUniqueToChildFileDescriptor();
   // Get the sandbox binary path. This method knows about the
   // CHROME_DEVEL_SANDBOX environment variable used for user-managed builds. If
   // the sandbox binary cannot be found, it will return an empty FilePath.
   base::FilePath GetSandboxBinaryPath();
-  // Modify |cmd_line| and |options| to launch via the setuid sandbox. Crash if
-  // the setuid sandbox binary cannot be found. Either can be NULL if the caller
-  // needs additional control.
-  void PrependWrapper(base::CommandLine* cmd_line,
-                      base::LaunchOptions* options);
+  // Modify |cmd_line| to launch via the setuid sandbox. Crash if the setuid
+  // sandbox binary cannot be found.  |cmd_line| must not be NULL.
+  void PrependWrapper(base::CommandLine* cmd_line);
+  // Set-up the launch options for launching via the setuid sandbox.  Caller is
+  // responsible for keeping |dummy_fd| alive until LaunchProcess() completes.
+  // |options| and |fds_to_remap| must not be NULL.
+  // (Keeping |dummy_fd| alive is an unfortunate historical artifact of the
+  // chrome-sandbox ABI.)
+  void SetupLaunchOptions(base::LaunchOptions* options,
+                          base::FileHandleMappingVector* fds_to_remap,
+                          base::ScopedFD* dummy_fd);
   // Set-up the environment. This should be done prior to launching the setuid
   // helper.
   void SetupLaunchEnvironment();
@@ -106,4 +101,3 @@
 }  // namespace sandbox
 
 #endif  // SANDBOX_LINUX_SUID_SETUID_SANDBOX_CLIENT_H_
-
diff --git a/sandbox/linux/tests/sandbox_test_runner.h b/sandbox/linux/tests/sandbox_test_runner.h
new file mode 100644
index 0000000..4cb7102
--- /dev/null
+++ b/sandbox/linux/tests/sandbox_test_runner.h
@@ -0,0 +1,25 @@
+// 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.
+
+#ifndef SANDBOX_LINUX_TESTS_SANDBOX_TEST_RUNNER_H_
+#define SANDBOX_LINUX_TESTS_SANDBOX_TEST_RUNNER_H_
+
+#include "base/basictypes.h"
+
+namespace sandbox {
+
+// A simple "runner" class to implement tests.
+class SandboxTestRunner {
+ public:
+  SandboxTestRunner() {}
+  virtual ~SandboxTestRunner() {}
+  virtual void Run() = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SandboxTestRunner);
+};
+
+}  // namespace sandbox
+
+#endif  // SANDBOX_LINUX_TESTS_SANDBOX_TEST_RUNNER_H_
diff --git a/sandbox/linux/tests/sandbox_test_runner_function_pointer.cc b/sandbox/linux/tests/sandbox_test_runner_function_pointer.cc
new file mode 100644
index 0000000..69e05ac
--- /dev/null
+++ b/sandbox/linux/tests/sandbox_test_runner_function_pointer.cc
@@ -0,0 +1,25 @@
+// 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.
+
+#include "sandbox/linux/tests/sandbox_test_runner_function_pointer.h"
+
+#include "base/logging.h"
+#include "build/build_config.h"
+
+namespace sandbox {
+
+SandboxTestRunnerFunctionPointer::SandboxTestRunnerFunctionPointer(
+    void (*function_to_run)(void))
+    : function_to_run_(function_to_run) {
+}
+
+SandboxTestRunnerFunctionPointer::~SandboxTestRunnerFunctionPointer() {
+}
+
+void SandboxTestRunnerFunctionPointer::Run() {
+  DCHECK(function_to_run_);
+  function_to_run_();
+}
+
+}  // namespace sandbox
diff --git a/sandbox/linux/tests/sandbox_test_runner_function_pointer.h b/sandbox/linux/tests/sandbox_test_runner_function_pointer.h
new file mode 100644
index 0000000..1cb709f
--- /dev/null
+++ b/sandbox/linux/tests/sandbox_test_runner_function_pointer.h
@@ -0,0 +1,26 @@
+// 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.
+
+#ifndef SANDBOX_LINUX_TESTS_SANDBOX_TEST_RUNNER_FUNCTION_POINTER_H_
+#define SANDBOX_LINUX_TESTS_SANDBOX_TEST_RUNNER_FUNCTION_POINTER_H_
+
+#include "base/basictypes.h"
+#include "sandbox/linux/tests/sandbox_test_runner.h"
+
+namespace sandbox {
+
+class SandboxTestRunnerFunctionPointer : public SandboxTestRunner {
+ public:
+  SandboxTestRunnerFunctionPointer(void (*function_to_run)(void));
+  virtual ~SandboxTestRunnerFunctionPointer() OVERRIDE;
+  virtual void Run() OVERRIDE;
+
+ private:
+  void (*function_to_run_)(void);
+  DISALLOW_COPY_AND_ASSIGN(SandboxTestRunnerFunctionPointer);
+};
+
+}  // namespace sandbox
+
+#endif  // SANDBOX_LINUX_TESTS_SANDBOX_TEST_RUNNER__FUNCTION_POINTER_H_
diff --git a/sandbox/linux/tests/unit_tests.cc b/sandbox/linux/tests/unit_tests.cc
index 42b85a8..d3ee81b 100644
--- a/sandbox/linux/tests/unit_tests.cc
+++ b/sandbox/linux/tests/unit_tests.cc
@@ -12,6 +12,7 @@
 #include <unistd.h>
 
 #include "base/file_util.h"
+#include "base/posix/eintr_wrapper.h"
 #include "base/third_party/valgrind/valgrind.h"
 #include "build/build_config.h"
 #include "sandbox/linux/tests/unit_tests.h"
@@ -105,10 +106,10 @@
 // in the BPF sandbox, as it potentially makes global state changes and as
 // it also tends to raise fatal errors, if the code has been used in an
 // insecure manner.
-void UnitTests::RunTestInProcess(UnitTests::Test test,
-                                 void* arg,
+void UnitTests::RunTestInProcess(SandboxTestRunner* test_runner,
                                  DeathCheck death,
                                  const void* death_aux) {
+  CHECK(test_runner);
   // We need to fork(), so we can't be multi-threaded, as threads could hold
   // locks.
   int num_threads = CountThreads();
@@ -174,7 +175,7 @@
     struct rlimit no_core = {0};
     setrlimit(RLIMIT_CORE, &no_core);
 
-    test(arg);
+    test_runner->Run();
     _exit(kExpectedValue);
   }
 
diff --git a/sandbox/linux/tests/unit_tests.h b/sandbox/linux/tests/unit_tests.h
index bc1939c..9531595 100644
--- a/sandbox/linux/tests/unit_tests.h
+++ b/sandbox/linux/tests/unit_tests.h
@@ -7,6 +7,7 @@
 
 #include "base/basictypes.h"
 #include "build/build_config.h"
+#include "sandbox/linux/tests/sandbox_test_runner_function_pointer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace sandbox {
@@ -62,12 +63,13 @@
 // that the test actually dies. The death test only passes if the death occurs
 // in the expected fashion, as specified by "death" and "death_aux". These two
 // parameters are typically set to one of the DEATH_XXX() macros.
-#define SANDBOX_DEATH_TEST(test_case_name, test_name, death)             \
-  void TEST_##test_name(void*);                                          \
-  TEST(test_case_name, test_name) {                                      \
-    sandbox::UnitTests::RunTestInProcess(TEST_##test_name, NULL, death); \
-  }                                                                      \
-  void TEST_##test_name(void*)
+#define SANDBOX_DEATH_TEST(test_case_name, test_name, death)                \
+  void TEST_##test_name(void);                                              \
+  TEST(test_case_name, test_name) {                                         \
+    SandboxTestRunnerFunctionPointer sandbox_test_runner(TEST_##test_name); \
+    sandbox::UnitTests::RunTestInProcess(&sandbox_test_runner, death);      \
+  }                                                                         \
+  void TEST_##test_name(void)
 
 // Define a new test case that runs inside of a GTest death test. This is
 // necessary, as most of our tests by definition make global and irreversible
@@ -88,9 +90,10 @@
   ((expr) ? static_cast<void>(0) : sandbox::UnitTests::AssertionFailure( \
                                        SANDBOX_STR(expr), __FILE__, __LINE__))
 
+// This class allows to run unittests in their own process. The main method is
+// RunTestInProcess().
 class UnitTests {
  public:
-  typedef void (*Test)(void*);
   typedef void (*DeathCheck)(int status,
                              const std::string& msg,
                              const void* aux);
@@ -99,8 +102,12 @@
   // directly. It is automatically invoked by SANDBOX_TEST(). Most sandboxing
   // functions make global irreversible changes to the execution environment
   // and must therefore execute in their own isolated process.
-  static void RunTestInProcess(Test test,
-                               void* arg,
+  // |test_runner| must implement the SandboxTestRunner interface and will run
+  // in a subprocess.
+  // Note: since the child process (created with fork()) will never return from
+  // RunTestInProcess(), |test_runner| is guaranteed to exist for the lifetime
+  // of the child process.
+  static void RunTestInProcess(SandboxTestRunner* test_runner,
                                DeathCheck death,
                                const void* death_aux);
 
diff --git a/sandbox/sandbox_services.target.darwin-arm.mk b/sandbox/sandbox_services.target.darwin-arm.mk
index 3a93b3e..248a767 100644
--- a/sandbox/sandbox_services.target.darwin-arm.mk
+++ b/sandbox/sandbox_services.target.darwin-arm.mk
@@ -45,7 +45,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -133,7 +132,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sandbox/sandbox_services.target.darwin-x86.mk b/sandbox/sandbox_services.target.darwin-x86.mk
index 47be915..3eb1812 100644
--- a/sandbox/sandbox_services.target.darwin-x86.mk
+++ b/sandbox/sandbox_services.target.darwin-x86.mk
@@ -47,7 +47,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -135,7 +134,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/sandbox_services.target.darwin-x86_64.mk b/sandbox/sandbox_services.target.darwin-x86_64.mk
index 5982b2c..ee7ac3d 100644
--- a/sandbox/sandbox_services.target.darwin-x86_64.mk
+++ b/sandbox/sandbox_services.target.darwin-x86_64.mk
@@ -47,7 +47,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -135,7 +134,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/sandbox_services.target.linux-arm.mk b/sandbox/sandbox_services.target.linux-arm.mk
index 3a93b3e..248a767 100644
--- a/sandbox/sandbox_services.target.linux-arm.mk
+++ b/sandbox/sandbox_services.target.linux-arm.mk
@@ -45,7 +45,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -133,7 +132,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sandbox/sandbox_services.target.linux-x86.mk b/sandbox/sandbox_services.target.linux-x86.mk
index 47be915..3eb1812 100644
--- a/sandbox/sandbox_services.target.linux-x86.mk
+++ b/sandbox/sandbox_services.target.linux-x86.mk
@@ -47,7 +47,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -135,7 +134,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/sandbox_services.target.linux-x86_64.mk b/sandbox/sandbox_services.target.linux-x86_64.mk
index 5982b2c..ee7ac3d 100644
--- a/sandbox/sandbox_services.target.linux-x86_64.mk
+++ b/sandbox/sandbox_services.target.linux-x86_64.mk
@@ -47,7 +47,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -135,7 +134,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/sandbox_services_headers.target.darwin-arm.mk b/sandbox/sandbox_services_headers.target.darwin-arm.mk
index 054f04c..d2b380e 100644
--- a/sandbox/sandbox_services_headers.target.darwin-arm.mk
+++ b/sandbox/sandbox_services_headers.target.darwin-arm.mk
@@ -40,7 +40,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -125,7 +124,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sandbox/sandbox_services_headers.target.darwin-x86.mk b/sandbox/sandbox_services_headers.target.darwin-x86.mk
index a9f35a9..cf8421a 100644
--- a/sandbox/sandbox_services_headers.target.darwin-x86.mk
+++ b/sandbox/sandbox_services_headers.target.darwin-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/sandbox_services_headers.target.darwin-x86_64.mk b/sandbox/sandbox_services_headers.target.darwin-x86_64.mk
index bc9fbc3..4d6658e 100644
--- a/sandbox/sandbox_services_headers.target.darwin-x86_64.mk
+++ b/sandbox/sandbox_services_headers.target.darwin-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/sandbox_services_headers.target.linux-arm.mk b/sandbox/sandbox_services_headers.target.linux-arm.mk
index 054f04c..d2b380e 100644
--- a/sandbox/sandbox_services_headers.target.linux-arm.mk
+++ b/sandbox/sandbox_services_headers.target.linux-arm.mk
@@ -40,7 +40,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -125,7 +124,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sandbox/sandbox_services_headers.target.linux-x86.mk b/sandbox/sandbox_services_headers.target.linux-x86.mk
index a9f35a9..cf8421a 100644
--- a/sandbox/sandbox_services_headers.target.linux-x86.mk
+++ b/sandbox/sandbox_services_headers.target.linux-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/sandbox_services_headers.target.linux-x86_64.mk b/sandbox/sandbox_services_headers.target.linux-x86_64.mk
index bc9fbc3..4d6658e 100644
--- a/sandbox/sandbox_services_headers.target.linux-x86_64.mk
+++ b/sandbox/sandbox_services_headers.target.linux-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/seccomp_bpf.target.darwin-arm.mk b/sandbox/seccomp_bpf.target.darwin-arm.mk
index 97a5d03..e232e26 100644
--- a/sandbox/seccomp_bpf.target.darwin-arm.mk
+++ b/sandbox/seccomp_bpf.target.darwin-arm.mk
@@ -50,7 +50,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +136,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sandbox/seccomp_bpf.target.darwin-x86.mk b/sandbox/seccomp_bpf.target.darwin-x86.mk
index 1feffcd..be3488f 100644
--- a/sandbox/seccomp_bpf.target.darwin-x86.mk
+++ b/sandbox/seccomp_bpf.target.darwin-x86.mk
@@ -52,7 +52,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/seccomp_bpf.target.darwin-x86_64.mk b/sandbox/seccomp_bpf.target.darwin-x86_64.mk
index 677a5ef..6180638 100644
--- a/sandbox/seccomp_bpf.target.darwin-x86_64.mk
+++ b/sandbox/seccomp_bpf.target.darwin-x86_64.mk
@@ -52,7 +52,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/seccomp_bpf.target.linux-arm.mk b/sandbox/seccomp_bpf.target.linux-arm.mk
index 97a5d03..e232e26 100644
--- a/sandbox/seccomp_bpf.target.linux-arm.mk
+++ b/sandbox/seccomp_bpf.target.linux-arm.mk
@@ -50,7 +50,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +136,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sandbox/seccomp_bpf.target.linux-x86.mk b/sandbox/seccomp_bpf.target.linux-x86.mk
index 1feffcd..be3488f 100644
--- a/sandbox/seccomp_bpf.target.linux-x86.mk
+++ b/sandbox/seccomp_bpf.target.linux-x86.mk
@@ -52,7 +52,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/seccomp_bpf.target.linux-x86_64.mk b/sandbox/seccomp_bpf.target.linux-x86_64.mk
index 677a5ef..6180638 100644
--- a/sandbox/seccomp_bpf.target.linux-x86_64.mk
+++ b/sandbox/seccomp_bpf.target.linux-x86_64.mk
@@ -52,7 +52,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/seccomp_bpf_helpers.target.darwin-arm.mk b/sandbox/seccomp_bpf_helpers.target.darwin-arm.mk
index 891944d..2f1569a 100644
--- a/sandbox/seccomp_bpf_helpers.target.darwin-arm.mk
+++ b/sandbox/seccomp_bpf_helpers.target.darwin-arm.mk
@@ -44,7 +44,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -131,7 +130,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sandbox/seccomp_bpf_helpers.target.darwin-x86.mk b/sandbox/seccomp_bpf_helpers.target.darwin-x86.mk
index 9f6a442..c537e98 100644
--- a/sandbox/seccomp_bpf_helpers.target.darwin-x86.mk
+++ b/sandbox/seccomp_bpf_helpers.target.darwin-x86.mk
@@ -46,7 +46,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/seccomp_bpf_helpers.target.darwin-x86_64.mk b/sandbox/seccomp_bpf_helpers.target.darwin-x86_64.mk
index 1309413..59ad6c3 100644
--- a/sandbox/seccomp_bpf_helpers.target.darwin-x86_64.mk
+++ b/sandbox/seccomp_bpf_helpers.target.darwin-x86_64.mk
@@ -46,7 +46,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/seccomp_bpf_helpers.target.linux-arm.mk b/sandbox/seccomp_bpf_helpers.target.linux-arm.mk
index 891944d..2f1569a 100644
--- a/sandbox/seccomp_bpf_helpers.target.linux-arm.mk
+++ b/sandbox/seccomp_bpf_helpers.target.linux-arm.mk
@@ -44,7 +44,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -131,7 +130,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sandbox/seccomp_bpf_helpers.target.linux-x86.mk b/sandbox/seccomp_bpf_helpers.target.linux-x86.mk
index 9f6a442..c537e98 100644
--- a/sandbox/seccomp_bpf_helpers.target.linux-x86.mk
+++ b/sandbox/seccomp_bpf_helpers.target.linux-x86.mk
@@ -46,7 +46,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sandbox/seccomp_bpf_helpers.target.linux-x86_64.mk b/sandbox/seccomp_bpf_helpers.target.linux-x86_64.mk
index 1309413..59ad6c3 100644
--- a/sandbox/seccomp_bpf_helpers.target.linux-x86_64.mk
+++ b/sandbox/seccomp_bpf_helpers.target.linux-x86_64.mk
@@ -46,7 +46,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sdch/sdch.target.darwin-arm.mk b/sdch/sdch.target.darwin-arm.mk
index 5aab1eb..9e701ee 100644
--- a/sdch/sdch.target.darwin-arm.mk
+++ b/sdch/sdch.target.darwin-arm.mk
@@ -53,7 +53,6 @@
 	./sdch/logging_forward.h \
 	-Wno-deprecated-declarations \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -145,7 +144,6 @@
 	./sdch/logging_forward.h \
 	-Wno-deprecated-declarations \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sdch/sdch.target.darwin-x86.mk b/sdch/sdch.target.darwin-x86.mk
index 675d1f9..88c0bab 100644
--- a/sdch/sdch.target.darwin-x86.mk
+++ b/sdch/sdch.target.darwin-x86.mk
@@ -55,7 +55,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sdch/sdch.target.darwin-x86_64.mk b/sdch/sdch.target.darwin-x86_64.mk
index 4730456..59b06b6 100644
--- a/sdch/sdch.target.darwin-x86_64.mk
+++ b/sdch/sdch.target.darwin-x86_64.mk
@@ -55,7 +55,6 @@
 	-Wno-deprecated-declarations \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-Wno-deprecated-declarations \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sdch/sdch.target.linux-arm.mk b/sdch/sdch.target.linux-arm.mk
index 5aab1eb..9e701ee 100644
--- a/sdch/sdch.target.linux-arm.mk
+++ b/sdch/sdch.target.linux-arm.mk
@@ -53,7 +53,6 @@
 	./sdch/logging_forward.h \
 	-Wno-deprecated-declarations \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -145,7 +144,6 @@
 	./sdch/logging_forward.h \
 	-Wno-deprecated-declarations \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sdch/sdch.target.linux-x86.mk b/sdch/sdch.target.linux-x86.mk
index 675d1f9..88c0bab 100644
--- a/sdch/sdch.target.linux-x86.mk
+++ b/sdch/sdch.target.linux-x86.mk
@@ -55,7 +55,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sdch/sdch.target.linux-x86_64.mk b/sdch/sdch.target.linux-x86_64.mk
index 4730456..59b06b6 100644
--- a/sdch/sdch.target.linux-x86_64.mk
+++ b/sdch/sdch.target.linux-x86_64.mk
@@ -55,7 +55,6 @@
 	-Wno-deprecated-declarations \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-Wno-deprecated-declarations \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index 35a91c4..fab5c16 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -425,7 +425,7 @@
   if (cpu_arch == "x86" || cpu_arch == "x64") {
     sources = [
       # SSE 2
-      "//third_party/skia/src/opts/opts_check_SSE2.cpp",
+      "//third_party/skia/src/opts/opts_check_x86.cpp",
       "//third_party/skia/src/opts/SkBitmapFilter_opts_SSE2.cpp",
       "//third_party/skia/src/opts/SkBitmapProcState_opts_SSE2.cpp",
       "//third_party/skia/src/opts/SkBlitRect_opts_SSE2.cpp",
diff --git a/skia/ext/analysis_canvas.cc b/skia/ext/analysis_canvas.cc
index 15ec6d8..59ae948 100644
--- a/skia/ext/analysis_canvas.cc
+++ b/skia/ext/analysis_canvas.cc
@@ -253,6 +253,13 @@
   has_text_ = true;
 }
 
+void AnalysisCanvas::onDrawDRRect(const SkRRect& outer,
+                                  const SkRRect& inner,
+                                  const SkPaint& paint) {
+  is_solid_color_ = false;
+  is_transparent_ = false;
+}
+
 void AnalysisCanvas::drawVertices(SkCanvas::VertexMode,
                                   int vertex_count,
                                   const SkPoint verts[],
diff --git a/skia/ext/analysis_canvas.h b/skia/ext/analysis_canvas.h
index efe9314..29a360d 100644
--- a/skia/ext/analysis_canvas.h
+++ b/skia/ext/analysis_canvas.h
@@ -105,6 +105,9 @@
                                 const SkPath& path,
                                 const SkMatrix* matrix,
                                 const SkPaint&) OVERRIDE;
+  virtual void onDrawDRRect(const SkRRect& outer,
+                            const SkRRect& inner,
+                            const SkPaint&) OVERRIDE;
 
 private:
   typedef SkCanvas INHERITED;
diff --git a/skia/ext/paint_simplifier.cc b/skia/ext/paint_simplifier.cc
index 6b69766..8df91a8 100644
--- a/skia/ext/paint_simplifier.cc
+++ b/skia/ext/paint_simplifier.cc
@@ -26,7 +26,6 @@
   paint->setSubpixelText(false);
   paint->setLCDRenderText(false);
 
-  paint->setFilterBitmap(false);
   paint->setMaskFilter(NULL);
 
   // Uncomment this line to shade simplified tiles pink during debugging.
diff --git a/skia/ext/pixel_ref_utils_unittest.cc b/skia/ext/pixel_ref_utils_unittest.cc
index ab8f7b0..237bc60 100644
--- a/skia/ext/pixel_ref_utils_unittest.cc
+++ b/skia/ext/pixel_ref_utils_unittest.cc
@@ -51,13 +51,7 @@
     return SkShader::kDefault_BitmapType;
   }
 
-  // Pure virtual implementaiton.
-  virtual SkShader::Context* createContext(const SkBitmap& device,
-                                           const SkPaint& paint,
-                                           const SkMatrix& matrix,
-                                           void* storage) const OVERRIDE {
-    return NULL;
-  };
+  // not indended to return an actual context. Just need to supply this.
   virtual size_t contextSize() const OVERRIDE {
     return sizeof(SkShader::Context);
   }
diff --git a/skia/skia_chrome.target.darwin-arm.mk b/skia/skia_chrome.target.darwin-arm.mk
index da29624..2eee03f 100644
--- a/skia/skia_chrome.target.darwin-arm.mk
+++ b/skia/skia_chrome.target.darwin-arm.mk
@@ -62,7 +62,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -114,11 +113,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -196,7 +190,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -248,11 +241,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_chrome.target.darwin-arm64.mk b/skia/skia_chrome.target.darwin-arm64.mk
index d7b2f64..edbe1eb 100644
--- a/skia/skia_chrome.target.darwin-arm64.mk
+++ b/skia/skia_chrome.target.darwin-arm64.mk
@@ -110,11 +110,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -238,11 +233,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_chrome.target.darwin-mips.mk b/skia/skia_chrome.target.darwin-mips.mk
index 07ab127..2de52e7 100644
--- a/skia/skia_chrome.target.darwin-mips.mk
+++ b/skia/skia_chrome.target.darwin-mips.mk
@@ -114,11 +114,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -247,11 +242,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_chrome.target.darwin-x86.mk b/skia/skia_chrome.target.darwin-x86.mk
index dc68c71..1401b7c 100644
--- a/skia/skia_chrome.target.darwin-x86.mk
+++ b/skia/skia_chrome.target.darwin-x86.mk
@@ -64,7 +64,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -115,11 +114,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -197,7 +191,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -248,11 +241,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_chrome.target.darwin-x86_64.mk b/skia/skia_chrome.target.darwin-x86_64.mk
index 3db898b..8c0cd13 100644
--- a/skia/skia_chrome.target.darwin-x86_64.mk
+++ b/skia/skia_chrome.target.darwin-x86_64.mk
@@ -64,7 +64,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -115,11 +114,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -197,7 +191,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -248,11 +241,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_chrome.target.linux-arm.mk b/skia/skia_chrome.target.linux-arm.mk
index da29624..2eee03f 100644
--- a/skia/skia_chrome.target.linux-arm.mk
+++ b/skia/skia_chrome.target.linux-arm.mk
@@ -62,7 +62,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -114,11 +113,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -196,7 +190,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -248,11 +241,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_chrome.target.linux-arm64.mk b/skia/skia_chrome.target.linux-arm64.mk
index d7b2f64..edbe1eb 100644
--- a/skia/skia_chrome.target.linux-arm64.mk
+++ b/skia/skia_chrome.target.linux-arm64.mk
@@ -110,11 +110,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -238,11 +233,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_chrome.target.linux-mips.mk b/skia/skia_chrome.target.linux-mips.mk
index 07ab127..2de52e7 100644
--- a/skia/skia_chrome.target.linux-mips.mk
+++ b/skia/skia_chrome.target.linux-mips.mk
@@ -114,11 +114,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -247,11 +242,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_chrome.target.linux-x86.mk b/skia/skia_chrome.target.linux-x86.mk
index dc68c71..1401b7c 100644
--- a/skia/skia_chrome.target.linux-x86.mk
+++ b/skia/skia_chrome.target.linux-x86.mk
@@ -64,7 +64,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -115,11 +114,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -197,7 +191,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -248,11 +241,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_chrome.target.linux-x86_64.mk b/skia/skia_chrome.target.linux-x86_64.mk
index 3db898b..8c0cd13 100644
--- a/skia/skia_chrome.target.linux-x86_64.mk
+++ b/skia/skia_chrome.target.linux-x86_64.mk
@@ -64,7 +64,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -115,11 +114,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -197,7 +191,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -248,11 +241,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_chrome_opts.target.darwin-x86.mk b/skia/skia_chrome_opts.target.darwin-x86.mk
index 52fc943..1f6484d 100644
--- a/skia/skia_chrome_opts.target.darwin-x86.mk
+++ b/skia/skia_chrome_opts.target.darwin-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/skia/skia_chrome_opts.target.darwin-x86_64.mk b/skia/skia_chrome_opts.target.darwin-x86_64.mk
index 61446d0..9fea4bf 100644
--- a/skia/skia_chrome_opts.target.darwin-x86_64.mk
+++ b/skia/skia_chrome_opts.target.darwin-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/skia/skia_chrome_opts.target.linux-x86.mk b/skia/skia_chrome_opts.target.linux-x86.mk
index 52fc943..1f6484d 100644
--- a/skia/skia_chrome_opts.target.linux-x86.mk
+++ b/skia/skia_chrome_opts.target.linux-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/skia/skia_chrome_opts.target.linux-x86_64.mk b/skia/skia_chrome_opts.target.linux-x86_64.mk
index 61446d0..9fea4bf 100644
--- a/skia/skia_chrome_opts.target.linux-x86_64.mk
+++ b/skia/skia_chrome_opts.target.linux-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -131,7 +130,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/skia/skia_library.gypi b/skia/skia_library.gypi
index 3353b63..fe1793f 100644
--- a/skia/skia_library.gypi
+++ b/skia/skia_library.gypi
@@ -33,7 +33,7 @@
     '../third_party/skia/src/images/SkScaledBitmapSampler.cpp',
     '../third_party/skia/src/images/SkScaledBitmapSampler.h',
 
-    '../third_party/skia/src/opts/opts_check_SSE2.cpp',
+    '../third_party/skia/src/opts/opts_check_x86.cpp',
 
     '../third_party/skia/src/ports/SkFontConfigInterface_android.cpp',
     '../third_party/skia/src/ports/SkFontConfigInterface_direct.cpp',
@@ -187,7 +187,7 @@
     [ 'target_arch == "arm" or target_arch == "arm64" or \
        target_arch == "mipsel"', {
       'sources!': [
-        '../third_party/skia/src/opts/opts_check_SSE2.cpp'
+        '../third_party/skia/src/opts/opts_check_x86.cpp'
       ],
     }],
     [ 'desktop_linux == 1 or chromeos == 1', {
@@ -249,7 +249,7 @@
         '../third_party/skia/src/utils/mac/SkStream_mac.cpp',
       ],
       'sources/': [
-        ['exclude', 'opts_check_SSE2\\.cpp$'],
+        ['exclude', 'opts_check_x86\\.cpp$'],
       ],
 
       # The main skia_opts target does not currently work on iOS because the
diff --git a/skia/skia_library.target.darwin-arm.mk b/skia/skia_library.target.darwin-arm.mk
index 22505ac..e932394 100644
--- a/skia/skia_library.target.darwin-arm.mk
+++ b/skia/skia_library.target.darwin-arm.mk
@@ -334,6 +334,7 @@
 	third_party/skia/src/gpu/GrClipMaskCache.cpp \
 	third_party/skia/src/gpu/GrClipMaskManager.cpp \
 	third_party/skia/src/gpu/GrGpu.cpp \
+	third_party/skia/src/gpu/GrGpuObject.cpp \
 	third_party/skia/src/gpu/GrGpuFactory.cpp \
 	third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \
 	third_party/skia/src/gpu/GrLayerCache.cpp \
@@ -349,7 +350,6 @@
 	third_party/skia/src/gpu/GrRectanizer_skyline.cpp \
 	third_party/skia/src/gpu/GrRenderTarget.cpp \
 	third_party/skia/src/gpu/GrReducedClip.cpp \
-	third_party/skia/src/gpu/GrResource.cpp \
 	third_party/skia/src/gpu/GrResourceCache.cpp \
 	third_party/skia/src/gpu/GrStencil.cpp \
 	third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \
@@ -424,7 +424,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -476,11 +475,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -570,7 +564,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -622,11 +615,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_library.target.darwin-arm64.mk b/skia/skia_library.target.darwin-arm64.mk
index 16453c1..91ab600 100644
--- a/skia/skia_library.target.darwin-arm64.mk
+++ b/skia/skia_library.target.darwin-arm64.mk
@@ -334,6 +334,7 @@
 	third_party/skia/src/gpu/GrClipMaskCache.cpp \
 	third_party/skia/src/gpu/GrClipMaskManager.cpp \
 	third_party/skia/src/gpu/GrGpu.cpp \
+	third_party/skia/src/gpu/GrGpuObject.cpp \
 	third_party/skia/src/gpu/GrGpuFactory.cpp \
 	third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \
 	third_party/skia/src/gpu/GrLayerCache.cpp \
@@ -349,7 +350,6 @@
 	third_party/skia/src/gpu/GrRectanizer_skyline.cpp \
 	third_party/skia/src/gpu/GrRenderTarget.cpp \
 	third_party/skia/src/gpu/GrReducedClip.cpp \
-	third_party/skia/src/gpu/GrResource.cpp \
 	third_party/skia/src/gpu/GrResourceCache.cpp \
 	third_party/skia/src/gpu/GrStencil.cpp \
 	third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \
@@ -471,11 +471,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -611,11 +606,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_library.target.darwin-mips.mk b/skia/skia_library.target.darwin-mips.mk
index a5d337f..c8d0242 100644
--- a/skia/skia_library.target.darwin-mips.mk
+++ b/skia/skia_library.target.darwin-mips.mk
@@ -334,6 +334,7 @@
 	third_party/skia/src/gpu/GrClipMaskCache.cpp \
 	third_party/skia/src/gpu/GrClipMaskManager.cpp \
 	third_party/skia/src/gpu/GrGpu.cpp \
+	third_party/skia/src/gpu/GrGpuObject.cpp \
 	third_party/skia/src/gpu/GrGpuFactory.cpp \
 	third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \
 	third_party/skia/src/gpu/GrLayerCache.cpp \
@@ -349,7 +350,6 @@
 	third_party/skia/src/gpu/GrRectanizer_skyline.cpp \
 	third_party/skia/src/gpu/GrRenderTarget.cpp \
 	third_party/skia/src/gpu/GrReducedClip.cpp \
-	third_party/skia/src/gpu/GrResource.cpp \
 	third_party/skia/src/gpu/GrResourceCache.cpp \
 	third_party/skia/src/gpu/GrStencil.cpp \
 	third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \
@@ -475,11 +475,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -620,11 +615,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_library.target.darwin-x86.mk b/skia/skia_library.target.darwin-x86.mk
index 5c08327..64140e7 100644
--- a/skia/skia_library.target.darwin-x86.mk
+++ b/skia/skia_library.target.darwin-x86.mk
@@ -29,7 +29,7 @@
 	third_party/skia/src/core/SkPaintOptionsAndroid.cpp \
 	third_party/skia/src/ports/SkImageDecoder_empty.cpp \
 	third_party/skia/src/images/SkScaledBitmapSampler.cpp \
-	third_party/skia/src/opts/opts_check_SSE2.cpp \
+	third_party/skia/src/opts/opts_check_x86.cpp \
 	third_party/skia/src/ports/SkFontConfigInterface_android.cpp \
 	third_party/skia/src/ports/SkFontHost_fontconfig.cpp \
 	third_party/skia/src/fonts/SkFontMgr_indirect.cpp \
@@ -335,6 +335,7 @@
 	third_party/skia/src/gpu/GrClipMaskCache.cpp \
 	third_party/skia/src/gpu/GrClipMaskManager.cpp \
 	third_party/skia/src/gpu/GrGpu.cpp \
+	third_party/skia/src/gpu/GrGpuObject.cpp \
 	third_party/skia/src/gpu/GrGpuFactory.cpp \
 	third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \
 	third_party/skia/src/gpu/GrLayerCache.cpp \
@@ -350,7 +351,6 @@
 	third_party/skia/src/gpu/GrRectanizer_skyline.cpp \
 	third_party/skia/src/gpu/GrRenderTarget.cpp \
 	third_party/skia/src/gpu/GrReducedClip.cpp \
-	third_party/skia/src/gpu/GrResource.cpp \
 	third_party/skia/src/gpu/GrResourceCache.cpp \
 	third_party/skia/src/gpu/GrStencil.cpp \
 	third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \
@@ -426,7 +426,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -477,11 +476,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -571,7 +565,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -622,11 +615,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_library.target.darwin-x86_64.mk b/skia/skia_library.target.darwin-x86_64.mk
index 903ca72..dd29c40 100644
--- a/skia/skia_library.target.darwin-x86_64.mk
+++ b/skia/skia_library.target.darwin-x86_64.mk
@@ -29,7 +29,7 @@
 	third_party/skia/src/core/SkPaintOptionsAndroid.cpp \
 	third_party/skia/src/ports/SkImageDecoder_empty.cpp \
 	third_party/skia/src/images/SkScaledBitmapSampler.cpp \
-	third_party/skia/src/opts/opts_check_SSE2.cpp \
+	third_party/skia/src/opts/opts_check_x86.cpp \
 	third_party/skia/src/ports/SkFontConfigInterface_android.cpp \
 	third_party/skia/src/ports/SkFontHost_fontconfig.cpp \
 	third_party/skia/src/fonts/SkFontMgr_indirect.cpp \
@@ -335,6 +335,7 @@
 	third_party/skia/src/gpu/GrClipMaskCache.cpp \
 	third_party/skia/src/gpu/GrClipMaskManager.cpp \
 	third_party/skia/src/gpu/GrGpu.cpp \
+	third_party/skia/src/gpu/GrGpuObject.cpp \
 	third_party/skia/src/gpu/GrGpuFactory.cpp \
 	third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \
 	third_party/skia/src/gpu/GrLayerCache.cpp \
@@ -350,7 +351,6 @@
 	third_party/skia/src/gpu/GrRectanizer_skyline.cpp \
 	third_party/skia/src/gpu/GrRenderTarget.cpp \
 	third_party/skia/src/gpu/GrReducedClip.cpp \
-	third_party/skia/src/gpu/GrResource.cpp \
 	third_party/skia/src/gpu/GrResourceCache.cpp \
 	third_party/skia/src/gpu/GrStencil.cpp \
 	third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \
@@ -426,7 +426,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -477,11 +476,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -571,7 +565,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -622,11 +615,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_library.target.linux-arm.mk b/skia/skia_library.target.linux-arm.mk
index 22505ac..e932394 100644
--- a/skia/skia_library.target.linux-arm.mk
+++ b/skia/skia_library.target.linux-arm.mk
@@ -334,6 +334,7 @@
 	third_party/skia/src/gpu/GrClipMaskCache.cpp \
 	third_party/skia/src/gpu/GrClipMaskManager.cpp \
 	third_party/skia/src/gpu/GrGpu.cpp \
+	third_party/skia/src/gpu/GrGpuObject.cpp \
 	third_party/skia/src/gpu/GrGpuFactory.cpp \
 	third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \
 	third_party/skia/src/gpu/GrLayerCache.cpp \
@@ -349,7 +350,6 @@
 	third_party/skia/src/gpu/GrRectanizer_skyline.cpp \
 	third_party/skia/src/gpu/GrRenderTarget.cpp \
 	third_party/skia/src/gpu/GrReducedClip.cpp \
-	third_party/skia/src/gpu/GrResource.cpp \
 	third_party/skia/src/gpu/GrResourceCache.cpp \
 	third_party/skia/src/gpu/GrStencil.cpp \
 	third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \
@@ -424,7 +424,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -476,11 +475,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -570,7 +564,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -622,11 +615,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_library.target.linux-arm64.mk b/skia/skia_library.target.linux-arm64.mk
index 16453c1..91ab600 100644
--- a/skia/skia_library.target.linux-arm64.mk
+++ b/skia/skia_library.target.linux-arm64.mk
@@ -334,6 +334,7 @@
 	third_party/skia/src/gpu/GrClipMaskCache.cpp \
 	third_party/skia/src/gpu/GrClipMaskManager.cpp \
 	third_party/skia/src/gpu/GrGpu.cpp \
+	third_party/skia/src/gpu/GrGpuObject.cpp \
 	third_party/skia/src/gpu/GrGpuFactory.cpp \
 	third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \
 	third_party/skia/src/gpu/GrLayerCache.cpp \
@@ -349,7 +350,6 @@
 	third_party/skia/src/gpu/GrRectanizer_skyline.cpp \
 	third_party/skia/src/gpu/GrRenderTarget.cpp \
 	third_party/skia/src/gpu/GrReducedClip.cpp \
-	third_party/skia/src/gpu/GrResource.cpp \
 	third_party/skia/src/gpu/GrResourceCache.cpp \
 	third_party/skia/src/gpu/GrStencil.cpp \
 	third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \
@@ -471,11 +471,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -611,11 +606,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_library.target.linux-mips.mk b/skia/skia_library.target.linux-mips.mk
index a5d337f..c8d0242 100644
--- a/skia/skia_library.target.linux-mips.mk
+++ b/skia/skia_library.target.linux-mips.mk
@@ -334,6 +334,7 @@
 	third_party/skia/src/gpu/GrClipMaskCache.cpp \
 	third_party/skia/src/gpu/GrClipMaskManager.cpp \
 	third_party/skia/src/gpu/GrGpu.cpp \
+	third_party/skia/src/gpu/GrGpuObject.cpp \
 	third_party/skia/src/gpu/GrGpuFactory.cpp \
 	third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \
 	third_party/skia/src/gpu/GrLayerCache.cpp \
@@ -349,7 +350,6 @@
 	third_party/skia/src/gpu/GrRectanizer_skyline.cpp \
 	third_party/skia/src/gpu/GrRenderTarget.cpp \
 	third_party/skia/src/gpu/GrReducedClip.cpp \
-	third_party/skia/src/gpu/GrResource.cpp \
 	third_party/skia/src/gpu/GrResourceCache.cpp \
 	third_party/skia/src/gpu/GrStencil.cpp \
 	third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \
@@ -475,11 +475,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -620,11 +615,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_library.target.linux-x86.mk b/skia/skia_library.target.linux-x86.mk
index 5c08327..64140e7 100644
--- a/skia/skia_library.target.linux-x86.mk
+++ b/skia/skia_library.target.linux-x86.mk
@@ -29,7 +29,7 @@
 	third_party/skia/src/core/SkPaintOptionsAndroid.cpp \
 	third_party/skia/src/ports/SkImageDecoder_empty.cpp \
 	third_party/skia/src/images/SkScaledBitmapSampler.cpp \
-	third_party/skia/src/opts/opts_check_SSE2.cpp \
+	third_party/skia/src/opts/opts_check_x86.cpp \
 	third_party/skia/src/ports/SkFontConfigInterface_android.cpp \
 	third_party/skia/src/ports/SkFontHost_fontconfig.cpp \
 	third_party/skia/src/fonts/SkFontMgr_indirect.cpp \
@@ -335,6 +335,7 @@
 	third_party/skia/src/gpu/GrClipMaskCache.cpp \
 	third_party/skia/src/gpu/GrClipMaskManager.cpp \
 	third_party/skia/src/gpu/GrGpu.cpp \
+	third_party/skia/src/gpu/GrGpuObject.cpp \
 	third_party/skia/src/gpu/GrGpuFactory.cpp \
 	third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \
 	third_party/skia/src/gpu/GrLayerCache.cpp \
@@ -350,7 +351,6 @@
 	third_party/skia/src/gpu/GrRectanizer_skyline.cpp \
 	third_party/skia/src/gpu/GrRenderTarget.cpp \
 	third_party/skia/src/gpu/GrReducedClip.cpp \
-	third_party/skia/src/gpu/GrResource.cpp \
 	third_party/skia/src/gpu/GrResourceCache.cpp \
 	third_party/skia/src/gpu/GrStencil.cpp \
 	third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \
@@ -426,7 +426,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -477,11 +476,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -571,7 +565,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -622,11 +615,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_library.target.linux-x86_64.mk b/skia/skia_library.target.linux-x86_64.mk
index 903ca72..dd29c40 100644
--- a/skia/skia_library.target.linux-x86_64.mk
+++ b/skia/skia_library.target.linux-x86_64.mk
@@ -29,7 +29,7 @@
 	third_party/skia/src/core/SkPaintOptionsAndroid.cpp \
 	third_party/skia/src/ports/SkImageDecoder_empty.cpp \
 	third_party/skia/src/images/SkScaledBitmapSampler.cpp \
-	third_party/skia/src/opts/opts_check_SSE2.cpp \
+	third_party/skia/src/opts/opts_check_x86.cpp \
 	third_party/skia/src/ports/SkFontConfigInterface_android.cpp \
 	third_party/skia/src/ports/SkFontHost_fontconfig.cpp \
 	third_party/skia/src/fonts/SkFontMgr_indirect.cpp \
@@ -335,6 +335,7 @@
 	third_party/skia/src/gpu/GrClipMaskCache.cpp \
 	third_party/skia/src/gpu/GrClipMaskManager.cpp \
 	third_party/skia/src/gpu/GrGpu.cpp \
+	third_party/skia/src/gpu/GrGpuObject.cpp \
 	third_party/skia/src/gpu/GrGpuFactory.cpp \
 	third_party/skia/src/gpu/GrInOrderDrawBuffer.cpp \
 	third_party/skia/src/gpu/GrLayerCache.cpp \
@@ -350,7 +351,6 @@
 	third_party/skia/src/gpu/GrRectanizer_skyline.cpp \
 	third_party/skia/src/gpu/GrRenderTarget.cpp \
 	third_party/skia/src/gpu/GrReducedClip.cpp \
-	third_party/skia/src/gpu/GrResource.cpp \
 	third_party/skia/src/gpu/GrResourceCache.cpp \
 	third_party/skia/src/gpu/GrStencil.cpp \
 	third_party/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp \
@@ -426,7 +426,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -477,11 +476,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -571,7 +565,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -622,11 +615,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts.target.darwin-arm.mk b/skia/skia_opts.target.darwin-arm.mk
index a19e807..707f30d 100644
--- a/skia/skia_opts.target.darwin-arm.mk
+++ b/skia/skia_opts.target.darwin-arm.mk
@@ -48,7 +48,6 @@
 	-Wa,-mimplicit-it=always \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -175,7 +169,6 @@
 	-Wa,-mimplicit-it=always \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -227,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts.target.darwin-arm64.mk b/skia/skia_opts.target.darwin-arm64.mk
index 544093b..6dddd56 100644
--- a/skia/skia_opts.target.darwin-arm64.mk
+++ b/skia/skia_opts.target.darwin-arm64.mk
@@ -99,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -218,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts.target.darwin-mips.mk b/skia/skia_opts.target.darwin-mips.mk
index 23b1820..8f490ae 100644
--- a/skia/skia_opts.target.darwin-mips.mk
+++ b/skia/skia_opts.target.darwin-mips.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -223,11 +218,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts.target.darwin-x86.mk b/skia/skia_opts.target.darwin-x86.mk
index f9afdd1..f00e510 100644
--- a/skia/skia_opts.target.darwin-x86.mk
+++ b/skia/skia_opts.target.darwin-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -172,7 +166,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -223,11 +216,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts.target.darwin-x86_64.mk b/skia/skia_opts.target.darwin-x86_64.mk
index 330fc6d..48541cd 100644
--- a/skia/skia_opts.target.darwin-x86_64.mk
+++ b/skia/skia_opts.target.darwin-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -172,7 +166,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -223,11 +216,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts.target.linux-arm.mk b/skia/skia_opts.target.linux-arm.mk
index a19e807..707f30d 100644
--- a/skia/skia_opts.target.linux-arm.mk
+++ b/skia/skia_opts.target.linux-arm.mk
@@ -48,7 +48,6 @@
 	-Wa,-mimplicit-it=always \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -175,7 +169,6 @@
 	-Wa,-mimplicit-it=always \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -227,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts.target.linux-arm64.mk b/skia/skia_opts.target.linux-arm64.mk
index 544093b..6dddd56 100644
--- a/skia/skia_opts.target.linux-arm64.mk
+++ b/skia/skia_opts.target.linux-arm64.mk
@@ -99,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -218,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts.target.linux-mips.mk b/skia/skia_opts.target.linux-mips.mk
index 23b1820..8f490ae 100644
--- a/skia/skia_opts.target.linux-mips.mk
+++ b/skia/skia_opts.target.linux-mips.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -223,11 +218,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts.target.linux-x86.mk b/skia/skia_opts.target.linux-x86.mk
index f9afdd1..f00e510 100644
--- a/skia/skia_opts.target.linux-x86.mk
+++ b/skia/skia_opts.target.linux-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -172,7 +166,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -223,11 +216,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts.target.linux-x86_64.mk b/skia/skia_opts.target.linux-x86_64.mk
index 330fc6d..48541cd 100644
--- a/skia/skia_opts.target.linux-x86_64.mk
+++ b/skia/skia_opts.target.linux-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -172,7 +166,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -223,11 +216,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts_neon.target.darwin-arm.mk b/skia/skia_opts_neon.target.darwin-arm.mk
index 44d176a..4cb6bef 100644
--- a/skia/skia_opts_neon.target.darwin-arm.mk
+++ b/skia/skia_opts_neon.target.darwin-arm.mk
@@ -49,7 +49,6 @@
 	-fomit-frame-pointer \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -176,7 +170,6 @@
 	-fomit-frame-pointer \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -228,11 +221,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts_neon.target.linux-arm.mk b/skia/skia_opts_neon.target.linux-arm.mk
index 44d176a..4cb6bef 100644
--- a/skia/skia_opts_neon.target.linux-arm.mk
+++ b/skia/skia_opts_neon.target.linux-arm.mk
@@ -49,7 +49,6 @@
 	-fomit-frame-pointer \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -176,7 +170,6 @@
 	-fomit-frame-pointer \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -228,11 +221,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts_ssse3.target.darwin-x86.mk b/skia/skia_opts_ssse3.target.darwin-x86.mk
index 33144f9..bac7a18 100644
--- a/skia/skia_opts_ssse3.target.darwin-x86.mk
+++ b/skia/skia_opts_ssse3.target.darwin-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -166,7 +160,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -217,11 +210,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts_ssse3.target.darwin-x86_64.mk b/skia/skia_opts_ssse3.target.darwin-x86_64.mk
index 03d131c..d413fac 100644
--- a/skia/skia_opts_ssse3.target.darwin-x86_64.mk
+++ b/skia/skia_opts_ssse3.target.darwin-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -166,7 +160,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -217,11 +210,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts_ssse3.target.linux-x86.mk b/skia/skia_opts_ssse3.target.linux-x86.mk
index 33144f9..bac7a18 100644
--- a/skia/skia_opts_ssse3.target.linux-x86.mk
+++ b/skia/skia_opts_ssse3.target.linux-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -166,7 +160,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -217,11 +210,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_opts_ssse3.target.linux-x86_64.mk b/skia/skia_opts_ssse3.target.linux-x86_64.mk
index 03d131c..d413fac 100644
--- a/skia/skia_opts_ssse3.target.linux-x86_64.mk
+++ b/skia/skia_opts_ssse3.target.linux-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -166,7 +160,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -217,11 +210,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/skia/skia_test_expectations.txt b/skia/skia_test_expectations.txt
index 1c56eff..4327f6e 100644
--- a/skia/skia_test_expectations.txt
+++ b/skia/skia_test_expectations.txt
@@ -48,15 +48,4 @@
 #
 # START OVERRIDES HERE
 
-# The Skia roll to r13482 altered the following layout tests:
-crbug.com/344497 [ Win ] virtual/deferred/fast/images/webp-color-profile-lossy.html [ ImageOnlyFailure ]
-
-# Roll to 13948 caused negligible changes to transformations to be rebaselined (fmalita):
-crbug.com/356644 fast/canvas/image-pattern-rotate.html [ ImageOnlyFailure ]
-crbug.com/356644 virtual/gpu/fast/canvas/image-object-in-canvas.html [ ImageOnlyFailure ]
-
-# Roll to 14271+ cases negligible changes to SkTwoPtConicalGradient.
-crbug.com/365698 fast/gradients/radial-centered.html [ ImageOnlyFailure ]
-crbug.com/365698 svg/custom/radialGradient-focal-radius.svg [ ImageOnlyFailure ]
-
 # END OVERRIDES HERE (this line ensures that the file is newline-terminated)
diff --git a/sql/sql.gyp b/sql/sql.gyp
index f62a2eb..6245940 100644
--- a/sql/sql.gyp
+++ b/sql/sql.gyp
@@ -99,8 +99,7 @@
       'conditions': [
         ['os_posix==1 and OS!="mac" and OS!="ios"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '../base/allocator/allocator.gyp:allocator',
               ],
diff --git a/sql/sql.target.darwin-arm.mk b/sql/sql.target.darwin-arm.mk
index 6e1cdfa..4bd833d 100644
--- a/sql/sql.target.darwin-arm.mk
+++ b/sql/sql.target.darwin-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -136,7 +135,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sql/sql.target.darwin-x86.mk b/sql/sql.target.darwin-x86.mk
index c9bf1f4..87409a8 100644
--- a/sql/sql.target.darwin-x86.mk
+++ b/sql/sql.target.darwin-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sql/sql.target.darwin-x86_64.mk b/sql/sql.target.darwin-x86_64.mk
index 3f5d446..3edb16e 100644
--- a/sql/sql.target.darwin-x86_64.mk
+++ b/sql/sql.target.darwin-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sql/sql.target.linux-arm.mk b/sql/sql.target.linux-arm.mk
index 6e1cdfa..4bd833d 100644
--- a/sql/sql.target.linux-arm.mk
+++ b/sql/sql.target.linux-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -136,7 +135,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/sql/sql.target.linux-x86.mk b/sql/sql.target.linux-x86.mk
index c9bf1f4..87409a8 100644
--- a/sql/sql.target.linux-x86.mk
+++ b/sql/sql.target.linux-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sql/sql.target.linux-x86_64.mk b/sql/sql.target.linux-x86_64.mk
index 3f5d446..3edb16e 100644
--- a/sql/sql.target.linux-x86_64.mk
+++ b/sql/sql.target.linux-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -138,7 +137,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/sync/android/java/src/org/chromium/sync/notifier/SyncStatusHelper.java b/sync/android/java/src/org/chromium/sync/notifier/SyncStatusHelper.java
index 0db47f8..569848f 100644
--- a/sync/android/java/src/org/chromium/sync/notifier/SyncStatusHelper.java
+++ b/sync/android/java/src/org/chromium/sync/notifier/SyncStatusHelper.java
@@ -103,7 +103,7 @@
 
             mAccount = account;
 
-            StrictMode.ThreadPolicy oldPolicy = temporarilyAllowDiskWritesAndDiskReads();
+            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
             mSyncAutomatically = mSyncContentResolverDelegate.getSyncAutomatically(
                     account, mContractAuthority);
             mIsSyncable = mSyncContentResolverDelegate.getIsSyncable(account, mContractAuthority);
@@ -116,7 +116,7 @@
         @VisibleForTesting
         protected void setIsSyncableInternal(Account account) {
             mIsSyncable = 1;
-            StrictMode.ThreadPolicy oldPolicy = temporarilyAllowDiskWritesAndDiskReads();
+            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
             mSyncContentResolverDelegate.setIsSyncable(account, mContractAuthority, 1);
             StrictMode.setThreadPolicy(oldPolicy);
             mDidUpdate = true;
@@ -125,7 +125,7 @@
         @VisibleForTesting
         protected void setSyncAutomaticallyInternal(Account account, boolean value) {
             mSyncAutomatically = value;
-            StrictMode.ThreadPolicy oldPolicy = temporarilyAllowDiskWritesAndDiskReads();
+            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
             mSyncContentResolverDelegate.setSyncAutomatically(account, mContractAuthority, value);
             StrictMode.setThreadPolicy(oldPolicy);
             mDidUpdate = true;
@@ -186,7 +186,7 @@
     }
 
     private void updateMasterSyncAutomaticallySetting() {
-        StrictMode.ThreadPolicy oldPolicy = temporarilyAllowDiskWritesAndDiskReads();
+        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
         synchronized (mCachedSettings) {
             mCachedMasterSyncAutomatically = mSyncContentResolverDelegate
                     .getMasterSyncAutomatically();
@@ -371,7 +371,7 @@
             mCachedSettings.setIsSyncable(account);
         }
 
-        StrictMode.ThreadPolicy oldPolicy = temporarilyAllowDiskWritesAndDiskReads();
+        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
         // Disable the syncability of Chrome for all other accounts. Don't use
         // our cache as we're touching many accounts that aren't signed in, so this saves
         // extra calls to Android sync configuration.
@@ -414,25 +414,6 @@
         }
     }
 
-    /**
-     * Sets a new StrictMode.ThreadPolicy based on the current one, but allows disk reads
-     * and disk writes.
-     *
-     * The return value is the old policy, which must be applied after the disk access is finished,
-     * by using StrictMode.setThreadPolicy(oldPolicy).
-     *
-     * @return the policy before allowing reads and writes.
-     */
-    private static StrictMode.ThreadPolicy temporarilyAllowDiskWritesAndDiskReads() {
-        StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
-        StrictMode.ThreadPolicy.Builder newPolicy =
-                new StrictMode.ThreadPolicy.Builder(oldPolicy);
-        newPolicy.permitDiskReads();
-        newPolicy.permitDiskWrites();
-        StrictMode.setThreadPolicy(newPolicy.build());
-        return oldPolicy;
-    }
-
     private boolean getAndClearDidUpdateStatus() {
         boolean didGetStatusUpdate;
         synchronized (mCachedSettings) {
diff --git a/sync/api/attachments/attachment_id.cc b/sync/api/attachments/attachment_id.cc
index 6f3e0a2..e61705e 100644
--- a/sync/api/attachments/attachment_id.cc
+++ b/sync/api/attachments/attachment_id.cc
@@ -5,7 +5,7 @@
 #include "sync/api/attachments/attachment_id.h"
 
 #include "base/logging.h"
-#include "base/rand_util.h"
+#include "sync/internal_api/public/base/attachment_id_proto.h"
 #include "sync/protocol/sync.pb.h"
 
 namespace syncer {
@@ -53,10 +53,7 @@
 
 // Static.
 AttachmentId AttachmentId::Create() {
-  // Only requirement here is that this id must be globally unique.
-  // TODO(maniscalco): Consider making this base64 encoded.
-  sync_pb::AttachmentIdProto proto;
-  proto.set_unique_id(base::RandBytesAsString(16));
+  sync_pb::AttachmentIdProto proto = CreateAttachmentIdProto();
   return AttachmentId(&proto);
 }
 
diff --git a/sync/api/attachments/attachment_service.h b/sync/api/attachments/attachment_service.h
index 81a1a63..9e5e25d 100644
--- a/sync/api/attachments/attachment_service.h
+++ b/sync/api/attachments/attachment_service.h
@@ -38,11 +38,22 @@
   // The result of a DropAttachments operation.
   enum DropResult {
     DROP_SUCCESS,            // No error, all attachments dropped.
-    DROP_UNSPECIFIED_ERROR,  // An unspecified error occurred.
+    DROP_UNSPECIFIED_ERROR,  // An unspecified error occurred. Some or all
+                             // attachments may not have been dropped.
   };
 
   typedef base::Callback<void(const DropResult&)> DropCallback;
 
+  // The result of a StoreAttachments operation.
+  enum StoreResult {
+    STORE_SUCCESS,            // No error, all attachments stored (at least
+                              // locally).
+    STORE_UNSPECIFIED_ERROR,  // An unspecified error occurred. Some or all
+                              // attachments may not have been stored.
+  };
+
+  typedef base::Callback<void(const StoreResult&)> StoreCallback;
+
   AttachmentService();
   virtual ~AttachmentService();
 
@@ -55,10 +66,12 @@
   virtual void DropAttachments(const AttachmentIdList& attachment_ids,
                                const DropCallback& callback) = 0;
 
-  // This method should be called when a SyncData is about to be added to the
-  // sync database so we have a chance to persist the Attachment locally and
-  // schedule it for upload to the sync server.
-  virtual void OnSyncDataAdd(const SyncData& sync_data) = 0;
+  // Store |attachments| on device and (eventually) upload them to the server.
+  //
+  // Invokes |callback| once the attachments have been written to device
+  // storage.
+  virtual void StoreAttachments(const AttachmentList& attachments,
+                                const StoreCallback& callback) = 0;
 
   // This method should be called when a SyncData is about to be deleted from
   // the sync database so we can remove any unreferenced attachments from local
diff --git a/sync/api/attachments/attachment_service_proxy.cc b/sync/api/attachments/attachment_service_proxy.cc
index 9bc40e5..6590033 100644
--- a/sync/api/attachments/attachment_service_proxy.cc
+++ b/sync/api/attachments/attachment_service_proxy.cc
@@ -35,6 +35,15 @@
   task_runner->PostTask(FROM_HERE, base::Bind(callback, result));
 }
 
+// Invokes |callback| with |result| and |attachments| in the |task_runner|
+// thread.
+void ProxyStoreCallback(
+    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
+    const AttachmentService::StoreCallback& callback,
+    const AttachmentService::StoreResult& result) {
+  task_runner->PostTask(FROM_HERE, base::Bind(callback, result));
+}
+
 }  // namespace
 
 AttachmentServiceProxy::AttachmentServiceProxy() {
@@ -85,11 +94,17 @@
                                             proxy_callback));
 }
 
-void AttachmentServiceProxy::OnSyncDataAdd(const SyncData& sync_data) {
+void AttachmentServiceProxy::StoreAttachments(const AttachmentList& attachments,
+                                              const StoreCallback& callback) {
   DCHECK(wrapped_task_runner_);
+  StoreCallback proxy_callback = base::Bind(
+      &ProxyStoreCallback, base::MessageLoopProxy::current(), callback);
   wrapped_task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&AttachmentService::OnSyncDataAdd, core_, sync_data));
+      base::Bind(&AttachmentService::StoreAttachments,
+                 core_,
+                 attachments,
+                 proxy_callback));
 }
 
 void AttachmentServiceProxy::OnSyncDataDelete(const SyncData& sync_data) {
@@ -137,11 +152,13 @@
   wrapped_->DropAttachments(attachment_ids, callback);
 }
 
-void AttachmentServiceProxy::Core::OnSyncDataAdd(const SyncData& sync_data) {
+void AttachmentServiceProxy::Core::StoreAttachments(
+    const AttachmentList& attachments,
+    const StoreCallback& callback) {
   if (!wrapped_) {
     return;
   }
-  wrapped_->OnSyncDataAdd(sync_data);
+  wrapped_->StoreAttachments(attachments, callback);
 }
 
 void AttachmentServiceProxy::Core::OnSyncDataDelete(const SyncData& sync_data) {
diff --git a/sync/api/attachments/attachment_service_proxy.h b/sync/api/attachments/attachment_service_proxy.h
index 7085625..462cdda 100644
--- a/sync/api/attachments/attachment_service_proxy.h
+++ b/sync/api/attachments/attachment_service_proxy.h
@@ -58,7 +58,8 @@
       const GetOrDownloadCallback& callback) OVERRIDE;
   virtual void DropAttachments(const AttachmentIdList& attachment_ids,
                                const DropCallback& callback) OVERRIDE;
-  virtual void OnSyncDataAdd(const SyncData& sync_data) OVERRIDE;
+  virtual void StoreAttachments(const AttachmentList& attachment,
+                                const StoreCallback& callback) OVERRIDE;
   virtual void OnSyncDataDelete(const SyncData& sync_data) OVERRIDE;
   virtual void OnSyncDataUpdate(const AttachmentIdList& old_attachment_ids,
                                 const SyncData& updated_sync_data) OVERRIDE;
@@ -89,7 +90,8 @@
         const GetOrDownloadCallback& callback) OVERRIDE;
     virtual void DropAttachments(const AttachmentIdList& attachment_ids,
                                  const DropCallback& callback) OVERRIDE;
-    virtual void OnSyncDataAdd(const SyncData& sync_data) OVERRIDE;
+    virtual void StoreAttachments(const AttachmentList& attachment,
+                                  const StoreCallback& callback) OVERRIDE;
     virtual void OnSyncDataDelete(const SyncData& sync_data) OVERRIDE;
     virtual void OnSyncDataUpdate(const AttachmentIdList& old_attachment_ids,
                                   const SyncData& updated_sync_data) OVERRIDE;
diff --git a/sync/api/attachments/attachment_service_proxy_unittest.cc b/sync/api/attachments/attachment_service_proxy_unittest.cc
index f6e3502..08c499e 100644
--- a/sync/api/attachments/attachment_service_proxy_unittest.cc
+++ b/sync/api/attachments/attachment_service_proxy_unittest.cc
@@ -56,9 +56,12 @@
         FROM_HERE, base::Bind(callback, AttachmentService::DROP_SUCCESS));
   }
 
-  virtual void OnSyncDataAdd(const SyncData& sync_data) OVERRIDE {
+  virtual void StoreAttachments(const AttachmentList& attachments,
+                                const StoreCallback& callback) OVERRIDE {
     CalledOnValidThread();
     Increment();
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE, base::Bind(callback, AttachmentService::STORE_SUCCESS));
   }
 
   virtual void OnSyncDataDelete(const SyncData& sync_data) OVERRIDE {
@@ -119,8 +122,11 @@
                    base::Unretained(this));
     callback_drop = base::Bind(&AttachmentServiceProxyTest::IncrementDrop,
                                base::Unretained(this));
+    callback_store = base::Bind(&AttachmentServiceProxyTest::IncrementStore,
+                                base::Unretained(this));
     count_callback_get_or_download = 0;
     count_callback_drop = 0;
+    count_callback_store = 0;
   }
 
   virtual void TearDown()
@@ -147,6 +153,12 @@
     ++count_callback_drop;
   }
 
+  // a StoreCallback
+  void IncrementStore(const AttachmentService::StoreResult&) {
+    CalledOnValidThread();
+    ++count_callback_store;
+  }
+
   void WaitForStubThread() {
     base::WaitableEvent done(false, false);
     stub_thread->message_loop()->PostTask(
@@ -165,21 +177,23 @@
 
   AttachmentService::GetOrDownloadCallback callback_get_or_download;
   AttachmentService::DropCallback callback_drop;
+  AttachmentService::StoreCallback callback_store;
 
   // number of times callback_get_or_download was invoked
   int count_callback_get_or_download;
   // number of times callback_drop was invoked
   int count_callback_drop;
+  // number of times callback_store was invoked
+  int count_callback_store;
 };
 
 // Verify that each of AttachmentServiceProxy's regular methods (those that
 // don't take callbacks) are invoked on the stub.
 TEST_F(AttachmentServiceProxyTest, MethodsAreProxied) {
-  proxy->OnSyncDataAdd(sync_data);
   proxy->OnSyncDataDelete(sync_data_delete);
   proxy->OnSyncDataUpdate(AttachmentIdList(), sync_data);
   WaitForStubThread();
-  EXPECT_EQ(3, stub->GetCallCount());
+  EXPECT_EQ(2, stub->GetCallCount());
 }
 
 // Verify that each of AttachmentServiceProxy's callback methods (those that
@@ -188,9 +202,10 @@
 TEST_F(AttachmentServiceProxyTest, MethodsWithCallbacksAreProxied) {
   proxy->GetOrDownloadAttachments(AttachmentIdList(), callback_get_or_download);
   proxy->DropAttachments(AttachmentIdList(), callback_drop);
+  proxy->StoreAttachments(AttachmentList(), callback_store);
   // Wait for the posted calls to execute in the stub thread.
   WaitForStubThread();
-  EXPECT_EQ(2, stub->GetCallCount());
+  EXPECT_EQ(3, stub->GetCallCount());
   // At this point the stub thread has finished executed the calls. However, the
   // result callbacks it has posted may not have executed yet. Wait a second
   // time to ensure the stub thread has executed the posted result callbacks.
@@ -199,6 +214,7 @@
   loop.RunUntilIdle();
   EXPECT_EQ(1, count_callback_get_or_download);
   EXPECT_EQ(1, count_callback_drop);
+  EXPECT_EQ(1, count_callback_store);
 }
 
 // Verify that it's safe to use an AttachmentServiceProxy even after its wrapped
diff --git a/sync/api/attachments/attachment_uploader.cc b/sync/api/attachments/attachment_uploader.cc
new file mode 100644
index 0000000..db081b1
--- /dev/null
+++ b/sync/api/attachments/attachment_uploader.cc
@@ -0,0 +1,14 @@
+// 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.
+
+#include "sync/api/attachments/attachment_uploader.h"
+
+namespace syncer {
+
+AttachmentUploader::AttachmentUploader() {
+}
+AttachmentUploader::~AttachmentUploader() {
+}
+
+}  // namespace syncer
diff --git a/sync/api/attachments/attachment_uploader.h b/sync/api/attachments/attachment_uploader.h
new file mode 100644
index 0000000..325a9e7
--- /dev/null
+++ b/sync/api/attachments/attachment_uploader.h
@@ -0,0 +1,46 @@
+// 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.
+
+#ifndef SYNC_API_ATTACHMENTS_ATTACHMENT_UPLOADER_H_
+#define SYNC_API_ATTACHMENTS_ATTACHMENT_UPLOADER_H_
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "sync/api/attachments/attachment.h"
+#include "sync/base/sync_export.h"
+
+namespace syncer {
+
+// AttachmentUploader is responsible for uploading attachments to the server.
+class SYNC_EXPORT AttachmentUploader {
+ public:
+  // The result of an UploadAttachment operation.
+  enum UploadResult {
+    UPLOAD_SUCCESS,            // No error, attachment was uploaded
+                               // successfully.
+    UPLOAD_UNSPECIFIED_ERROR,  // An unspecified error occurred.
+  };
+
+  typedef base::Callback<void(const UploadResult&, const AttachmentId&)>
+      UploadCallback;
+
+  AttachmentUploader();
+  virtual ~AttachmentUploader();
+
+  // Upload |attachment| and invoke |callback| when done.
+  //
+  // |callback| will be invoked when the operation has completed (successfully
+  // or otherwise).
+  //
+  // |callback| will receive an UploadResult code and an updated AttachmentId
+  // |containing the server address of the newly uploaded attachment.
+  virtual void UploadAttachment(const Attachment& attachment,
+                                const UploadCallback& callback) = 0;
+};
+
+}  // namespace syncer
+
+#endif  // SYNC_API_ATTACHMENTS_ATTACHMENT_UPLOADER_H_
diff --git a/sync/api/attachments/fake_attachment_service.cc b/sync/api/attachments/fake_attachment_service.cc
index b9eb88e..f86f380 100644
--- a/sync/api/attachments/fake_attachment_service.cc
+++ b/sync/api/attachments/fake_attachment_service.cc
@@ -8,14 +8,19 @@
 #include "base/message_loop/message_loop.h"
 #include "sync/api/attachments/attachment.h"
 #include "sync/api/attachments/fake_attachment_store.h"
+#include "sync/api/attachments/fake_attachment_uploader.h"
 
 namespace syncer {
 
 FakeAttachmentService::FakeAttachmentService(
-    scoped_ptr<AttachmentStore> attachment_store)
-    : attachment_store_(attachment_store.Pass()), weak_ptr_factory_(this) {
+    scoped_ptr<AttachmentStore> attachment_store,
+    scoped_ptr<AttachmentUploader> attachment_uploader)
+    : attachment_store_(attachment_store.Pass()),
+      attachment_uploader_(attachment_uploader.Pass()),
+      weak_ptr_factory_(this) {
   DCHECK(CalledOnValidThread());
   DCHECK(attachment_store_);
+  DCHECK(attachment_uploader_);
 }
 
 FakeAttachmentService::~FakeAttachmentService() {
@@ -26,8 +31,11 @@
 scoped_ptr<syncer::AttachmentService> FakeAttachmentService::CreateForTest() {
   scoped_ptr<syncer::AttachmentStore> attachment_store(
       new syncer::FakeAttachmentStore(base::MessageLoopProxy::current()));
+  scoped_ptr<AttachmentUploader> attachment_uploader(
+      new FakeAttachmentUploader);
   scoped_ptr<syncer::AttachmentService> attachment_service(
-      new syncer::FakeAttachmentService(attachment_store.Pass()));
+      new syncer::FakeAttachmentService(attachment_store.Pass(),
+                                        attachment_uploader.Pass()));
   return attachment_service.Pass();
 }
 
@@ -51,10 +59,15 @@
                                      callback));
 }
 
-void FakeAttachmentService::OnSyncDataAdd(const SyncData& sync_data) {
+void FakeAttachmentService::StoreAttachments(const AttachmentList& attachments,
+                                             const StoreCallback& callback) {
   DCHECK(CalledOnValidThread());
-  // TODO(maniscalco): Ensure the linked attachments get persisted in local
-  // storage and schedule them for upload to the server (bug 356351).
+  attachment_store_->Write(attachments,
+                           base::Bind(&FakeAttachmentService::WriteDone,
+                                      weak_ptr_factory_.GetWeakPtr(),
+                                      callback));
+  // TODO(maniscalco): Ensure the linked attachments are schedule for upload to
+  // the server (bug 356351).
 }
 
 void FakeAttachmentService::OnSyncDataDelete(const SyncData& sync_data) {
@@ -99,4 +112,16 @@
                                          base::Bind(callback, drop_result));
 }
 
+void FakeAttachmentService::WriteDone(const StoreCallback& callback,
+                                      const AttachmentStore::Result& result) {
+  AttachmentService::StoreResult store_result =
+      AttachmentService::STORE_UNSPECIFIED_ERROR;
+  if (result == AttachmentStore::SUCCESS) {
+    store_result = AttachmentService::STORE_SUCCESS;
+  }
+  // TODO(maniscalco): Deal with case where an error occurred (bug 361251).
+  base::MessageLoop::current()->PostTask(FROM_HERE,
+                                         base::Bind(callback, store_result));
+}
+
 }  // namespace syncer
diff --git a/sync/api/attachments/fake_attachment_service.h b/sync/api/attachments/fake_attachment_service.h
index eb97c52..8159e0f 100644
--- a/sync/api/attachments/fake_attachment_service.h
+++ b/sync/api/attachments/fake_attachment_service.h
@@ -10,6 +10,7 @@
 #include "sync/api/attachments/attachment_service.h"
 #include "sync/api/attachments/attachment_service_proxy.h"
 #include "sync/api/attachments/attachment_store.h"
+#include "sync/api/attachments/attachment_uploader.h"
 
 namespace syncer {
 
@@ -17,7 +18,8 @@
 class SYNC_EXPORT FakeAttachmentService : public AttachmentService,
                                           public base::NonThreadSafe {
  public:
-  explicit FakeAttachmentService(scoped_ptr<AttachmentStore> attachment_store);
+  FakeAttachmentService(scoped_ptr<AttachmentStore> attachment_store,
+                        scoped_ptr<AttachmentUploader> attachment_uploader);
   virtual ~FakeAttachmentService();
 
   // Create a FakeAttachmentService suitable for use in tests.
@@ -29,7 +31,8 @@
       OVERRIDE;
   virtual void DropAttachments(const AttachmentIdList& attachment_ids,
                                const DropCallback& callback) OVERRIDE;
-  virtual void OnSyncDataAdd(const SyncData& sync_data) OVERRIDE;
+  virtual void StoreAttachments(const AttachmentList& attachments,
+                                const StoreCallback& callback) OVERRIDE;
   virtual void OnSyncDataDelete(const SyncData& sync_data) OVERRIDE;
   virtual void OnSyncDataUpdate(const AttachmentIdList& old_attachment_ids,
                                 const SyncData& updated_sync_data) OVERRIDE;
@@ -40,8 +43,11 @@
                 scoped_ptr<AttachmentMap> attachments);
   void DropDone(const DropCallback& callback,
                 const AttachmentStore::Result& result);
+  void WriteDone(const StoreCallback& callback,
+                 const AttachmentStore::Result& result);
 
   const scoped_ptr<AttachmentStore> attachment_store_;
+  const scoped_ptr<AttachmentUploader> attachment_uploader_;
   // Must be last data member.
   base::WeakPtrFactory<FakeAttachmentService> weak_ptr_factory_;
 
diff --git a/sync/api/attachments/fake_attachment_uploader.cc b/sync/api/attachments/fake_attachment_uploader.cc
new file mode 100644
index 0000000..7ed929d
--- /dev/null
+++ b/sync/api/attachments/fake_attachment_uploader.cc
@@ -0,0 +1,32 @@
+// 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.
+
+#include "sync/api/attachments/fake_attachment_uploader.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "sync/api/attachments/attachment.h"
+
+namespace syncer {
+
+FakeAttachmentUploader::FakeAttachmentUploader() {
+  DCHECK(CalledOnValidThread());
+}
+
+FakeAttachmentUploader::~FakeAttachmentUploader() {
+  DCHECK(CalledOnValidThread());
+}
+
+void FakeAttachmentUploader::UploadAttachment(const Attachment& attachment,
+                                              const UploadCallback& callback) {
+  DCHECK(CalledOnValidThread());
+  UploadResult result = UPLOAD_SUCCESS;
+  AttachmentId updated_id = attachment.GetId();
+  // TODO(maniscalco): Update the attachment id with server address information
+  // before passing it to the callback.
+  base::MessageLoop::current()->PostTask(
+      FROM_HERE, base::Bind(callback, result, updated_id));
+}
+
+}  // namespace syncer
diff --git a/sync/api/attachments/fake_attachment_uploader.h b/sync/api/attachments/fake_attachment_uploader.h
new file mode 100644
index 0000000..7e48d61
--- /dev/null
+++ b/sync/api/attachments/fake_attachment_uploader.h
@@ -0,0 +1,30 @@
+// 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.
+
+#ifndef SYNC_API_ATTACHMENTS_FAKE_ATTACHMENT_UPLOADER_H_
+#define SYNC_API_ATTACHMENTS_FAKE_ATTACHMENT_UPLOADER_H_
+
+#include "base/threading/non_thread_safe.h"
+#include "sync/api/attachments/attachment_uploader.h"
+
+namespace syncer {
+
+// A fake implementation of AttachmentUploader.
+class SYNC_EXPORT FakeAttachmentUploader : public AttachmentUploader,
+                                           public base::NonThreadSafe {
+ public:
+  FakeAttachmentUploader();
+  virtual ~FakeAttachmentUploader();
+
+  // AttachmentUploader implementation.
+  virtual void UploadAttachment(const Attachment& attachment,
+                                const UploadCallback& callback) OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FakeAttachmentUploader);
+};
+
+}  // namespace syncer
+
+#endif  // SYNC_API_ATTACHMENTS_FAKE_ATTACHMENT_UPLOADER_H_
diff --git a/sync/api/attachments/fake_attachment_uploader_unittest.cc b/sync/api/attachments/fake_attachment_uploader_unittest.cc
new file mode 100644
index 0000000..09dccfc
--- /dev/null
+++ b/sync/api/attachments/fake_attachment_uploader_unittest.cc
@@ -0,0 +1,60 @@
+// 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.
+
+#include "sync/api/attachments/fake_attachment_uploader.h"
+
+#include "base/bind.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/message_loop/message_loop.h"
+#include "sync/api/attachments/attachment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace syncer {
+
+namespace {
+
+const char kAttachmentData[] = "some data";
+
+}  // namespace
+
+class FakeAttachmentUploaderTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    upload_callback_count = 0;
+    upload_callback = base::Bind(&FakeAttachmentUploaderTest::Increment,
+                                 base::Unretained(this),
+                                 &upload_callback_count);
+  }
+  base::MessageLoop message_loop;
+  FakeAttachmentUploader uploader;
+  int upload_callback_count;
+  AttachmentUploader::UploadCallback upload_callback;
+
+ private:
+  void Increment(int* success_count,
+                 const AttachmentUploader::UploadResult& result,
+                 const AttachmentId& ignored) {
+    if (result == AttachmentUploader::UPLOAD_SUCCESS) {
+      ++(*success_count);
+    }
+  }
+};
+
+// Call upload attachment several times, see that the supplied callback is
+// invoked the same number of times with a result of SUCCESS.
+TEST_F(FakeAttachmentUploaderTest, UploadAttachment) {
+  scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
+  some_data->data() = kAttachmentData;
+  Attachment attachment1 = Attachment::Create(some_data);
+  Attachment attachment2 = Attachment::Create(some_data);
+  Attachment attachment3 = Attachment::Create(some_data);
+  uploader.UploadAttachment(attachment1, upload_callback);
+  uploader.UploadAttachment(attachment2, upload_callback);
+  uploader.UploadAttachment(attachment3, upload_callback);
+  message_loop.RunUntilIdle();
+  EXPECT_EQ(upload_callback_count, 3);
+}
+
+}  // namespace syncer
diff --git a/sync/api/sync_data.cc b/sync/api/sync_data.cc
index fa48ea5..35a21f9 100644
--- a/sync/api/sync_data.cc
+++ b/sync/api/sync_data.cc
@@ -36,6 +36,21 @@
   return syncer::AttachmentId::CreateFromProto(proto);
 }
 
+// Return true iff |attachments| contains one or more elements with the same
+// AttachmentId.
+bool ContainsDuplicateAttachments(const syncer::AttachmentList& attachments) {
+  std::set<syncer::AttachmentId> id_set;
+  AttachmentList::const_iterator iter = attachments.begin();
+  AttachmentList::const_iterator end = attachments.end();
+  for (; iter != end; ++iter) {
+    if (id_set.find(iter->GetId()) != id_set.end()) {
+      return true;
+    }
+    id_set.insert(iter->GetId());
+  }
+  return false;
+}
+
 }  // namespace
 
 namespace syncer {
@@ -96,15 +111,13 @@
       sync_tag, non_unique_title, specifics, attachments);
 }
 
-// TODO(maniscalco): What should happen if the same Attachment appears in the
-// list twice? Document the behavior and add a test case.
-//
 // Static.
 SyncData SyncData::CreateLocalDataWithAttachments(
     const std::string& sync_tag,
     const std::string& non_unique_title,
     const sync_pb::EntitySpecifics& specifics,
     const AttachmentList& attachments) {
+  DCHECK(!ContainsDuplicateAttachments(attachments));
   sync_pb::SyncEntity entity;
   entity.set_client_defined_unique_tag(sync_tag);
   entity.set_non_unique_name(non_unique_title);
@@ -113,9 +126,6 @@
                  attachments.end(),
                  RepeatedFieldBackInserter(entity.mutable_attachment_id()),
                  AttachmentToProto);
-  // TODO(maniscalco): Actually pass the attachments to the ctor and make them
-  // available to the AttachmentService once this SyncData gets passed into
-  // GenericChangeProcesso::ProcessSyncChanges (bug 354530).
   AttachmentList copy_of_attachments(attachments);
   return SyncData(kInvalidId,
                   &entity,
diff --git a/sync/api/sync_data.h b/sync/api/sync_data.h
index bb99b74..8795141 100644
--- a/sync/api/sync_data.h
+++ b/sync/api/sync_data.h
@@ -43,14 +43,19 @@
   // Default copy and assign welcome.
 
   // Helper methods for creating SyncData objects for local data.
-  // The sync tag must be a string unique to this datatype and is used as a node
+  //
+  // |sync_tag| Must be a string unique to this datatype and is used as a node
   // identifier server-side.
+  //
   // For deletes: |datatype| must specify the datatype who node is being
   // deleted.
-  // For adds/updates: the specifics must be valid and the non-unique title (can
-  // be the same as sync tag) must be specfied.
-  // Note: the non_unique_title is primarily for debug purposes, and will be
-  // overwritten if the datatype is encrypted.
+  //
+  // For adds/updates: |specifics| must be valid and |non_unique_title| (can be
+  // the same as |sync_tag|) must be specfied.  Note: |non_unique_title| is
+  // primarily for debug purposes, and will be overwritten if the datatype is
+  // encrypted.
+  //
+  // For data with attachments: |attachments| must not contain duplicates.
   static SyncData CreateLocalDelete(
       const std::string& sync_tag,
       ModelType datatype);
diff --git a/sync/engine/directory_commit_contribution.cc b/sync/engine/directory_commit_contribution.cc
index a662c0e..11fe518 100644
--- a/sync/engine/directory_commit_contribution.cc
+++ b/sync/engine/directory_commit_contribution.cc
@@ -23,7 +23,10 @@
 scoped_ptr<DirectoryCommitContribution> DirectoryCommitContribution::Build(
     syncable::Directory* dir,
     ModelType type,
-    size_t max_entries) {
+    size_t max_entries,
+    DirectoryTypeDebugInfoEmitter* debug_info_emitter) {
+  DCHECK(debug_info_emitter);
+
   std::vector<int64> metahandles;
 
   syncable::ModelNeutralWriteTransaction trans(FROM_HERE, SYNCER, dir);
@@ -45,7 +48,12 @@
   dir->GetDataTypeContext(&trans, type, &context);
 
   return scoped_ptr<DirectoryCommitContribution>(
-      new DirectoryCommitContribution(metahandles, entities, context, dir));
+      new DirectoryCommitContribution(
+          metahandles,
+          entities,
+          context,
+          dir,
+          debug_info_emitter));
 }
 
 void DirectoryCommitContribution::AddToCommitMessage(
@@ -150,13 +158,15 @@
     const std::vector<int64>& metahandles,
     const google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>& entities,
     const sync_pb::DataTypeContext& context,
-    syncable::Directory* dir)
+    syncable::Directory* dir,
+    DirectoryTypeDebugInfoEmitter* debug_info_emitter)
     : dir_(dir),
       metahandles_(metahandles),
       entities_(entities),
       context_(context),
       entries_start_index_(0xDEADBEEF),
-      syncing_bits_set_(true) {}
+      syncing_bits_set_(true),
+      debug_info_emitter_(debug_info_emitter) {}
 
 void DirectoryCommitContribution::UnsetSyncingBits() {
   syncable::ModelNeutralWriteTransaction trans(FROM_HERE, SYNCER, dir_);
diff --git a/sync/engine/directory_commit_contribution.h b/sync/engine/directory_commit_contribution.h
index 83cefe9..0b15358 100644
--- a/sync/engine/directory_commit_contribution.h
+++ b/sync/engine/directory_commit_contribution.h
@@ -14,6 +14,7 @@
 #include "sync/internal_api/public/base/model_type.h"
 #include "sync/internal_api/public/util/syncer_error.h"
 #include "sync/protocol/sync.pb.h"
+#include "sync/sessions/directory_type_debug_info_emitter.h"
 #include "sync/sessions/status_controller.h"
 
 namespace syncer {
@@ -47,7 +48,8 @@
   static scoped_ptr<DirectoryCommitContribution> Build(
       syncable::Directory* dir,
       ModelType type,
-      size_t max_items);
+      size_t max_items,
+      DirectoryTypeDebugInfoEmitter* debug_info_emitter);
 
   // Serialize this contribution's entries to the given commit request |msg|.
   //
@@ -83,7 +85,8 @@
       const std::vector<int64>& metahandles,
       const google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>& entities,
       const sync_pb::DataTypeContext& context,
-      syncable::Directory* directory);
+      syncable::Directory* directory,
+      DirectoryTypeDebugInfoEmitter* debug_info_emitter);
 
   void UnsetSyncingBits();
 
@@ -99,6 +102,9 @@
   // called.  This flag must be unset by the time our destructor is called.
   bool syncing_bits_set_;
 
+  // A pointer to the commit counters of our parent CommitContributor.
+  DirectoryTypeDebugInfoEmitter* debug_info_emitter_;
+
   DISALLOW_COPY_AND_ASSIGN(DirectoryCommitContribution);
 };
 
diff --git a/sync/engine/directory_commit_contribution_unittest.cc b/sync/engine/directory_commit_contribution_unittest.cc
index e17817c..867fcde 100644
--- a/sync/engine/directory_commit_contribution_unittest.cc
+++ b/sync/engine/directory_commit_contribution_unittest.cc
@@ -85,8 +85,9 @@
     CreateUnsyncedItem(&trans, EXTENSIONS, "extension1");
   }
 
+  DirectoryTypeDebugInfoEmitter emitter;
   scoped_ptr<DirectoryCommitContribution> cc(
-      DirectoryCommitContribution::Build(dir(), PREFERENCES, 5));
+      DirectoryCommitContribution::Build(dir(), PREFERENCES, 5, &emitter));
   ASSERT_EQ(2U, cc->GetNumEntries());
 
   const std::vector<int64>& metahandles = cc->metahandles_;
@@ -110,8 +111,9 @@
     CreateUnsyncedItem(&trans, EXTENSIONS, "extension1");
   }
 
+  DirectoryTypeDebugInfoEmitter emitter;
   scoped_ptr<DirectoryCommitContribution> cc(
-      DirectoryCommitContribution::Build(dir(), PREFERENCES, 1));
+      DirectoryCommitContribution::Build(dir(), PREFERENCES, 1, &emitter));
   ASSERT_EQ(1U, cc->GetNumEntries());
 
   int64 only_metahandle = cc->metahandles_[0];
@@ -132,10 +134,12 @@
     CreateUnsyncedItem(&trans, EXTENSIONS, "extension1");
   }
 
+  DirectoryTypeDebugInfoEmitter emitter1;
+  DirectoryTypeDebugInfoEmitter emitter2;
   scoped_ptr<DirectoryCommitContribution> pref_cc(
-      DirectoryCommitContribution::Build(dir(), PREFERENCES, 25));
+      DirectoryCommitContribution::Build(dir(), PREFERENCES, 25, &emitter1));
   scoped_ptr<DirectoryCommitContribution> ext_cc(
-      DirectoryCommitContribution::Build(dir(), EXTENSIONS, 25));
+      DirectoryCommitContribution::Build(dir(), EXTENSIONS, 25, &emitter2));
 
   sync_pb::ClientToServerMessage message;
   pref_cc->AddToCommitMessage(&message);
@@ -184,10 +188,12 @@
     ext1_handle = CreateUnsyncedItem(&trans, EXTENSIONS, "extension1");
   }
 
+  DirectoryTypeDebugInfoEmitter emitter1;
+  DirectoryTypeDebugInfoEmitter emitter2;
   scoped_ptr<DirectoryCommitContribution> pref_cc(
-      DirectoryCommitContribution::Build(dir(), PREFERENCES, 25));
+      DirectoryCommitContribution::Build(dir(), PREFERENCES, 25, &emitter1));
   scoped_ptr<DirectoryCommitContribution> ext_cc(
-      DirectoryCommitContribution::Build(dir(), EXTENSIONS, 25));
+      DirectoryCommitContribution::Build(dir(), EXTENSIONS, 25, &emitter2));
 
   sync_pb::ClientToServerMessage message;
   pref_cc->AddToCommitMessage(&message);
diff --git a/sync/engine/directory_commit_contributor.cc b/sync/engine/directory_commit_contributor.cc
index 41d1e12..d3e0043 100644
--- a/sync/engine/directory_commit_contributor.cc
+++ b/sync/engine/directory_commit_contributor.cc
@@ -5,21 +5,27 @@
 #include "sync/engine/directory_commit_contributor.h"
 
 #include "sync/engine/directory_commit_contribution.h"
+#include "sync/sessions/directory_type_debug_info_emitter.h"
 
 namespace syncer {
 
 DirectoryCommitContributor::DirectoryCommitContributor(
     syncable::Directory* dir,
-    ModelType type)
+    ModelType type,
+    DirectoryTypeDebugInfoEmitter* debug_info_emitter)
     : dir_(dir),
-      type_(type) {}
+      type_(type),
+      debug_info_emitter_(debug_info_emitter) {}
 
 DirectoryCommitContributor::~DirectoryCommitContributor() {}
 
 scoped_ptr<CommitContribution>
 DirectoryCommitContributor::GetContribution(size_t max_entries) {
-  return DirectoryCommitContribution::Build(dir_, type_, max_entries)
-      .PassAs<CommitContribution>();
+  return DirectoryCommitContribution::Build(
+      dir_,
+      type_,
+      max_entries,
+      debug_info_emitter_).PassAs<CommitContribution>();
 }
 
 }  // namespace syncer
diff --git a/sync/engine/directory_commit_contributor.h b/sync/engine/directory_commit_contributor.h
index abc1a6c..a1c9104 100644
--- a/sync/engine/directory_commit_contributor.h
+++ b/sync/engine/directory_commit_contributor.h
@@ -18,6 +18,8 @@
 class Directory;
 }
 
+class DirectoryTypeDebugInfoEmitter;
+
 // This class represents the syncable::Directory as a source of items to commit
 // to the sync server.
 //
@@ -27,7 +29,9 @@
 // of a DirectoryCommitContribution.
 class DirectoryCommitContributor : public CommitContributor {
  public:
-  DirectoryCommitContributor(syncable::Directory* dir, ModelType type);
+  DirectoryCommitContributor(syncable::Directory* dir,
+                             ModelType type,
+                             DirectoryTypeDebugInfoEmitter* debug_info_emitter);
   virtual ~DirectoryCommitContributor();
 
   virtual scoped_ptr<CommitContribution> GetContribution(
@@ -37,6 +41,8 @@
   syncable::Directory* dir_;
   ModelType type_;
 
+  DirectoryTypeDebugInfoEmitter* debug_info_emitter_;
+
   DISALLOW_COPY_AND_ASSIGN(DirectoryCommitContributor);
 };
 
diff --git a/sync/engine/directory_update_handler.cc b/sync/engine/directory_update_handler.cc
index 72cdf12..8f0da59 100644
--- a/sync/engine/directory_update_handler.cc
+++ b/sync/engine/directory_update_handler.cc
@@ -7,7 +7,7 @@
 #include "sync/engine/conflict_resolver.h"
 #include "sync/engine/process_updates_util.h"
 #include "sync/engine/update_applicator.h"
-#include "sync/sessions/status_controller.h"
+#include "sync/sessions/directory_type_debug_info_emitter.h"
 #include "sync/syncable/directory.h"
 #include "sync/syncable/syncable_model_neutral_write_transaction.h"
 #include "sync/syncable/syncable_write_transaction.h"
@@ -19,10 +19,12 @@
 DirectoryUpdateHandler::DirectoryUpdateHandler(
     syncable::Directory* dir,
     ModelType type,
-    scoped_refptr<ModelSafeWorker> worker)
+    scoped_refptr<ModelSafeWorker> worker,
+    DirectoryTypeDebugInfoEmitter* debug_info_emitter)
   : dir_(dir),
     type_(type),
-    worker_(worker) {}
+    worker_(worker),
+    debug_info_emitter_(debug_info_emitter) {}
 
 DirectoryUpdateHandler::~DirectoryUpdateHandler() {}
 
diff --git a/sync/engine/directory_update_handler.h b/sync/engine/directory_update_handler.h
index ef5052d..73c18a0 100644
--- a/sync/engine/directory_update_handler.h
+++ b/sync/engine/directory_update_handler.h
@@ -32,6 +32,7 @@
 class Directory;
 }
 
+class DirectoryTypeDebugInfoEmitter;
 class ModelSafeWorker;
 
 // This class represents the syncable::Directory's processes for requesting and
@@ -44,7 +45,8 @@
  public:
   DirectoryUpdateHandler(syncable::Directory* dir,
                          ModelType type,
-                         scoped_refptr<ModelSafeWorker> worker);
+                         scoped_refptr<ModelSafeWorker> worker,
+                         DirectoryTypeDebugInfoEmitter* debug_info_emitter);
   virtual ~DirectoryUpdateHandler();
 
   // UpdateHandler implementation.
@@ -93,6 +95,7 @@
   syncable::Directory* dir_;
   ModelType type_;
   scoped_refptr<ModelSafeWorker> worker_;
+  DirectoryTypeDebugInfoEmitter* debug_info_emitter_;
 
   scoped_ptr<sync_pb::GarbageCollectionDirective> cached_gc_directive_;
 
diff --git a/sync/engine/directory_update_handler_unittest.cc b/sync/engine/directory_update_handler_unittest.cc
index ec8cc35..ec0a14e 100644
--- a/sync/engine/directory_update_handler_unittest.cc
+++ b/sync/engine/directory_update_handler_unittest.cc
@@ -11,6 +11,7 @@
 #include "sync/internal_api/public/base/model_type.h"
 #include "sync/internal_api/public/test/test_entry_factory.h"
 #include "sync/protocol/sync.pb.h"
+#include "sync/sessions/directory_type_debug_info_emitter.h"
 #include "sync/sessions/status_controller.h"
 #include "sync/syncable/directory.h"
 #include "sync/syncable/entry.h"
@@ -55,6 +56,7 @@
   syncable::Directory* dir() {
     return dir_maker_.directory();
   }
+
  protected:
   scoped_ptr<sync_pb::SyncEntity> CreateUpdate(
       const std::string& id,
@@ -123,7 +125,8 @@
 
 // Test that the bookmark tag is set on newly downloaded items.
 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, NewBookmarkTag) {
-  DirectoryUpdateHandler handler(dir(), BOOKMARKS, ui_worker());
+  DirectoryTypeDebugInfoEmitter emitter;
+  DirectoryUpdateHandler handler(dir(), BOOKMARKS, ui_worker(), &emitter);
   sync_pb::GetUpdatesResponse gu_response;
   sessions::StatusController status;
 
@@ -161,7 +164,8 @@
 // Test the receipt of a type root node.
 TEST_F(DirectoryUpdateHandlerProcessUpdateTest,
        ReceiveServerCreatedBookmarkFolders) {
-  DirectoryUpdateHandler handler(dir(), BOOKMARKS, ui_worker());
+  DirectoryTypeDebugInfoEmitter emitter;
+  DirectoryUpdateHandler handler(dir(), BOOKMARKS, ui_worker(), &emitter);
   sync_pb::GetUpdatesResponse gu_response;
   sessions::StatusController status;
 
@@ -195,7 +199,8 @@
 
 // Test the receipt of a non-bookmark item.
 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, ReceiveNonBookmarkItem) {
-  DirectoryUpdateHandler handler(dir(), AUTOFILL, ui_worker());
+  DirectoryTypeDebugInfoEmitter emitter;
+  DirectoryUpdateHandler handler(dir(), AUTOFILL, ui_worker(), &emitter);
   sync_pb::GetUpdatesResponse gu_response;
   sessions::StatusController status;
 
@@ -226,7 +231,8 @@
 
 // Tests the setting of progress markers.
 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, ProcessNewProgressMarkers) {
-  DirectoryUpdateHandler handler(dir(), BOOKMARKS, ui_worker());
+  DirectoryTypeDebugInfoEmitter emitter;
+  DirectoryUpdateHandler handler(dir(), BOOKMARKS, ui_worker(), &emitter);
 
   sync_pb::DataTypeProgressMarker progress;
   progress.set_data_type_id(GetSpecificsFieldNumberFromModelType(BOOKMARKS));
@@ -242,7 +248,9 @@
 }
 
 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, GarbageCollectionByVersion) {
-  DirectoryUpdateHandler handler(dir(), SYNCED_NOTIFICATIONS, ui_worker());
+  DirectoryTypeDebugInfoEmitter emitter;
+  DirectoryUpdateHandler handler(dir(), SYNCED_NOTIFICATIONS,
+                                 ui_worker(), &emitter);
   sessions::StatusController status;
 
   sync_pb::DataTypeProgressMarker progress;
@@ -305,7 +313,9 @@
 }
 
 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, ContextVersion) {
-  DirectoryUpdateHandler handler(dir(), SYNCED_NOTIFICATIONS, ui_worker());
+  DirectoryTypeDebugInfoEmitter emitter;
+  DirectoryUpdateHandler handler(dir(), SYNCED_NOTIFICATIONS,
+                                 ui_worker(), &emitter);
   sessions::StatusController status;
   int field_number = GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS);
 
@@ -411,12 +421,14 @@
 
     update_handler_map_.insert(std::make_pair(
         BOOKMARKS,
-        new DirectoryUpdateHandler(directory(), BOOKMARKS, ui_worker_)));
+        new DirectoryUpdateHandler(directory(), BOOKMARKS,
+                                   ui_worker_, &bookmarks_emitter_)));
     update_handler_map_.insert(std::make_pair(
         PASSWORDS,
         new DirectoryUpdateHandler(directory(),
-                                       PASSWORDS,
-                                       password_worker_)));
+                                   PASSWORDS,
+                                   password_worker_,
+                                   &passwords_emitter_)));
   }
 
   virtual void TearDown() OVERRIDE {
@@ -451,6 +463,9 @@
   scoped_refptr<FakeModelWorker> password_worker_;
   scoped_refptr<FakeModelWorker> passive_worker_;
 
+  DirectoryTypeDebugInfoEmitter bookmarks_emitter_;
+  DirectoryTypeDebugInfoEmitter passwords_emitter_;
+
   UpdateHandlerMap update_handler_map_;
   STLValueDeleter<UpdateHandlerMap> update_handler_map_deleter_;
 };
diff --git a/sync/engine/get_commit_ids.cc b/sync/engine/get_commit_ids.cc
index 80222ee..5f91915 100644
--- a/sync/engine/get_commit_ids.cc
+++ b/sync/engine/get_commit_ids.cc
@@ -108,9 +108,13 @@
 // Return true if this entry has any attachments that haven't yet been uploaded
 // to the server.
 bool HasAttachmentNotOnServer(const syncable::Entry& entry) {
-  // TODO(maniscalco): Once AttachmentMetadata is fleshed out, implement this
-  // function to return true if any of the attachments haven't been uploaded to
-  // the server. Add test case (bug 356266).
+  // TODO(maniscalco): Add test case (bug 356266).
+  const sync_pb::AttachmentMetadata& metadata = entry.GetAttachmentMetadata();
+  for (int i = 0; i < metadata.record_size(); ++i) {
+    if (!metadata.record(i).is_on_server()) {
+      return true;
+    }
+  }
   return false;
 }
 
diff --git a/sync/internal_api/base_node.cc b/sync/internal_api/base_node.cc
index 0788395..57dbb22 100644
--- a/sync/internal_api/base_node.cc
+++ b/sync/internal_api/base_node.cc
@@ -291,10 +291,13 @@
 }
 
 const syncer::AttachmentIdList BaseNode::GetAttachmentIds() const {
-  // TODO(maniscalco): Once EntryKernel is capable of storing AttachmentIds,
-  // update this method to retrieve the list of AttachmentIds from read_node and
-  // pass it to CreateRemoteData (bug 348625).
-  return AttachmentIdList();
+  AttachmentIdList result;
+  const sync_pb::AttachmentMetadata& metadata =
+      GetEntry()->GetAttachmentMetadata();
+  for (int i = 0; i < metadata.record_size(); ++i) {
+    result.push_back(AttachmentId::CreateFromProto(metadata.record(i).id()));
+  }
+  return result;
 }
 
 void BaseNode::SetUnencryptedSpecifics(
diff --git a/sync/internal_api/http_bridge.cc b/sync/internal_api/http_bridge.cc
index 59d04fa..fe700f8 100644
--- a/sync/internal_api/http_bridge.cc
+++ b/sync/internal_api/http_bridge.cc
@@ -210,8 +210,7 @@
   GURL temp(url);
   GURL::Replacements replacements;
   std::string port_str = base::IntToString(port);
-  replacements.SetPort(port_str.c_str(),
-                       url_parse::Component(0, port_str.length()));
+  replacements.SetPort(port_str.c_str(), url::Component(0, port_str.length()));
   url_for_request_ = temp.ReplaceComponents(replacements);
 }
 
diff --git a/sync/internal_api/public/base/attachment_id_proto.cc b/sync/internal_api/public/base/attachment_id_proto.cc
new file mode 100644
index 0000000..4b1ea3c
--- /dev/null
+++ b/sync/internal_api/public/base/attachment_id_proto.cc
@@ -0,0 +1,21 @@
+// 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.
+
+#include "sync/internal_api/public/base/attachment_id_proto.h"
+
+#include "base/guid.h"
+#include "base/logging.h"
+
+namespace syncer {
+
+sync_pb::AttachmentIdProto CreateAttachmentIdProto() {
+  // Only requirement here is that this id must be globally unique.
+  sync_pb::AttachmentIdProto proto;
+  std::string guid = base::GenerateGUID();
+  DCHECK(!guid.empty());
+  proto.set_unique_id(guid);
+  return proto;
+}
+
+}  // namespace syncer
diff --git a/sync/internal_api/public/base/attachment_id_proto.h b/sync/internal_api/public/base/attachment_id_proto.h
new file mode 100644
index 0000000..3332d81
--- /dev/null
+++ b/sync/internal_api/public/base/attachment_id_proto.h
@@ -0,0 +1,20 @@
+// 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.
+
+#ifndef SYNC_INTERNAL_API_PUBLIC_BASE_ATTACHMENT_ID_PROTO_H_
+#define SYNC_INTERNAL_API_PUBLIC_BASE_ATTACHMENT_ID_PROTO_H_
+
+#include "sync/base/sync_export.h"
+#include "sync/protocol/sync.pb.h"
+
+namespace syncer {
+
+// Helper functions that are logically part of sync_pb::AttachmentIdProto.
+
+// Creates a unique AttachmentIdProto.
+SYNC_EXPORT_PRIVATE sync_pb::AttachmentIdProto CreateAttachmentIdProto();
+
+}  // namespace syncer
+
+#endif  // SYNC_INTERNAL_API_PUBLIC_BASE_ATTACHMENT_ID_PROTO_H_
diff --git a/sync/internal_api/public/base_transaction.h b/sync/internal_api/public/base_transaction.h
index 2f4fa3c..c75086e 100644
--- a/sync/internal_api/public/base_transaction.h
+++ b/sync/internal_api/public/base_transaction.h
@@ -24,6 +24,9 @@
 // syncable, and are used in a similar way. Unlike syncable::BaseTransaction,
 // whose construction requires an explicit syncable::Directory, a sync
 // API BaseTransaction is created from a UserShare object.
+//
+// Note, these transactions are not atomic. Individual operations can
+// fail. There is no built-in rollback or undo mechanism.
 class SYNC_EXPORT BaseTransaction {
  public:
   // Provide access to the underlying syncable objects from BaseNode.
diff --git a/sync/internal_api/public/sync_manager.h b/sync/internal_api/public/sync_manager.h
index 7488586..5b5f337 100644
--- a/sync/internal_api/public/sync_manager.h
+++ b/sync/internal_api/public/sync_manager.h
@@ -45,10 +45,11 @@
 class InternalComponentsFactory;
 class JsBackend;
 class JsEventHandler;
+class ProtocolEvent;
 class SyncCoreProxy;
 class SyncEncryptionHandler;
-class ProtocolEvent;
 class SyncScheduler;
+class TypeDebugInfoObserver;
 struct Experiments;
 struct UserShare;
 
@@ -361,6 +362,18 @@
 
   // Returns any buffered protocol events.  Does not clear the buffer.
   virtual ScopedVector<syncer::ProtocolEvent> GetBufferedProtocolEvents() = 0;
+
+  // Functions to manage registrations of DebugInfoObservers.
+  virtual void RegisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) = 0;
+  virtual void UnregisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) = 0;
+  virtual bool HasDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) = 0;
+
+  // Request that all current counter values be emitted as though they had just
+  // been updated.  Useful for initializing new observers' state.
+  virtual void RequestEmitDebugInfo() = 0;
 };
 
 }  // namespace syncer
diff --git a/sync/internal_api/public/test/fake_sync_manager.h b/sync/internal_api/public/test/fake_sync_manager.h
index 55e4f3b..9b08831 100644
--- a/sync/internal_api/public/test/fake_sync_manager.h
+++ b/sync/internal_api/public/test/fake_sync_manager.h
@@ -130,6 +130,13 @@
   virtual scoped_ptr<base::ListValue> GetAllNodesForType(
       syncer::ModelType type) OVERRIDE;
   virtual void RefreshTypes(ModelTypeSet types) OVERRIDE;
+  virtual void RegisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual void UnregisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual bool HasDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual void RequestEmitDebugInfo() OVERRIDE;
 
  private:
   scoped_refptr<base::SequencedTaskRunner> sync_task_runner_;
diff --git a/sync/internal_api/public/write_node.h b/sync/internal_api/public/write_node.h
index e41c966..5b47bd6 100644
--- a/sync/internal_api/public/write_node.h
+++ b/sync/internal_api/public/write_node.h
@@ -173,6 +173,10 @@
   void SetPriorityPreferenceSpecifics(
       const sync_pb::PriorityPreferenceSpecifics& specifics);
 
+  // Set the attachment metadata.
+  void SetAttachmentMetadata(
+      const sync_pb::AttachmentMetadata& attachment_metadata);
+
   // Implementation of BaseNode's abstract virtual accessors.
   virtual const syncable::Entry* GetEntry() const OVERRIDE;
 
diff --git a/sync/internal_api/sync_backup_manager.cc b/sync/internal_api/sync_backup_manager.cc
index f255ae6..10215be 100644
--- a/sync/internal_api/sync_backup_manager.cc
+++ b/sync/internal_api/sync_backup_manager.cc
@@ -109,4 +109,15 @@
   unsynced_.clear();
 }
 
+void SyncBackupManager::RegisterDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {}
+
+void SyncBackupManager::UnregisterDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {}
+
+bool SyncBackupManager::HasDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) { return false; }
+
+void SyncBackupManager::RequestEmitDebugInfo() {}
+
 }  // namespace syncer
diff --git a/sync/internal_api/sync_backup_manager.h b/sync/internal_api/sync_backup_manager.h
index 1bee105..e6b9ca4 100644
--- a/sync/internal_api/sync_backup_manager.h
+++ b/sync/internal_api/sync_backup_manager.h
@@ -48,6 +48,14 @@
       const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
       syncable::BaseTransaction* trans) OVERRIDE;
 
+  virtual void RegisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual void UnregisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual bool HasDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual void RequestEmitDebugInfo() OVERRIDE;
+
  private:
   // Replaces local IDs with server IDs and clear unsynced bit of modified
   // entries.
diff --git a/sync/internal_api/sync_encryption_handler_impl.cc b/sync/internal_api/sync_encryption_handler_impl.cc
index 34bf033..d3dd33f 100644
--- a/sync/internal_api/sync_encryption_handler_impl.cc
+++ b/sync/internal_api/sync_encryption_handler_impl.cc
@@ -344,7 +344,6 @@
   // encryption is to set a custom passphrase.
   if (IsNigoriMigratedToKeystore(node.GetNigoriSpecifics())) {
     if (!is_explicit) {
-      DCHECK(cryptographer->is_ready());
       // The user is setting a new implicit passphrase. At this point we don't
       // care, so drop it on the floor. This is safe because if we have a
       // migrated nigori node, then we don't need to create an initial
diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc
index 60bd3da..c2894b4 100644
--- a/sync/internal_api/sync_manager_impl.cc
+++ b/sync/internal_api/sync_manager_impl.cc
@@ -1126,6 +1126,25 @@
   return protocol_event_buffer_.GetBufferedProtocolEvents();
 }
 
+void SyncManagerImpl::RegisterDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {
+  model_type_registry_->RegisterDirectoryTypeDebugInfoObserver(observer);
+}
+
+void SyncManagerImpl::UnregisterDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {
+  model_type_registry_->UnregisterDirectoryTypeDebugInfoObserver(observer);
+}
+
+bool SyncManagerImpl::HasDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {
+  return model_type_registry_->HasDirectoryTypeDebugInfoObserver(observer);
+}
+
+void SyncManagerImpl::RequestEmitDebugInfo() {
+  model_type_registry_->RequestEmitDebugInfo();
+}
+
 // static.
 int SyncManagerImpl::GetDefaultNudgeDelay() {
   return kDefaultNudgeDelayMilliseconds;
diff --git a/sync/internal_api/sync_manager_impl.h b/sync/internal_api/sync_manager_impl.h
index 653e48a..9402737 100644
--- a/sync/internal_api/sync_manager_impl.h
+++ b/sync/internal_api/sync_manager_impl.h
@@ -35,6 +35,7 @@
 class ModelTypeRegistry;
 class SyncAPIServerConnectionManager;
 class SyncCore;
+class TypeDebugInfoObserver;
 class WriteNode;
 class WriteTransaction;
 
@@ -121,6 +122,13 @@
       GetBufferedProtocolEvents() OVERRIDE;
   virtual scoped_ptr<base::ListValue> GetAllNodesForType(
       syncer::ModelType type) OVERRIDE;
+  virtual void RegisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual void UnregisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual bool HasDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual void RequestEmitDebugInfo() OVERRIDE;
 
   // SyncEncryptionHandler::Observer implementation.
   virtual void OnPassphraseRequired(
diff --git a/sync/internal_api/sync_manager_impl_unittest.cc b/sync/internal_api/sync_manager_impl_unittest.cc
index a5c0c81..20b7685 100644
--- a/sync/internal_api/sync_manager_impl_unittest.cc
+++ b/sync/internal_api/sync_manager_impl_unittest.cc
@@ -210,22 +210,94 @@
   }
 
  protected:
+  // Create an entry with the given |model_type|, |client_tag| and
+  // |attachment_metadata|.
+  void CreateEntryWithAttachmentMetadata(
+      const ModelType& model_type,
+      const std::string& client_tag,
+      const sync_pb::AttachmentMetadata& attachment_metadata);
+
+  // Attempts to load the entry specified by |model_type| and |client_tag| and
+  // returns the lookup result code.
+  BaseNode::InitByLookupResult LookupEntryByClientTag(
+      const ModelType& model_type,
+      const std::string& client_tag);
+
+  // Replace the entry specified by |model_type| and |client_tag| with a
+  // tombstone.
+  void ReplaceWithTombstone(const ModelType& model_type,
+                            const std::string& client_tag);
+
+  // Save changes to the Directory, destroy it then reload it.
+  bool ReloadDir();
+
+  UserShare* user_share();
+  syncable::Directory* dir();
+  SyncEncryptionHandler* encryption_handler();
+
+ private:
   base::MessageLoop message_loop_;
   TestUserShare test_user_share_;
 };
 
+UserShare* SyncApiTest::user_share() {
+  return test_user_share_.user_share();
+}
+
+syncable::Directory* SyncApiTest::dir() {
+  return test_user_share_.user_share()->directory.get();
+}
+
+SyncEncryptionHandler* SyncApiTest::encryption_handler() {
+  return test_user_share_.encryption_handler();
+}
+
+bool SyncApiTest::ReloadDir() {
+  return test_user_share_.Reload();
+}
+
+void SyncApiTest::CreateEntryWithAttachmentMetadata(
+    const ModelType& model_type,
+    const std::string& client_tag,
+    const sync_pb::AttachmentMetadata& attachment_metadata) {
+  syncer::WriteTransaction trans(FROM_HERE, user_share());
+  syncer::ReadNode root_node(&trans);
+  root_node.InitByRootLookup();
+  syncer::WriteNode node(&trans);
+  ASSERT_EQ(node.InitUniqueByCreation(model_type, root_node, client_tag),
+            syncer::WriteNode::INIT_SUCCESS);
+  node.SetAttachmentMetadata(attachment_metadata);
+}
+
+BaseNode::InitByLookupResult SyncApiTest::LookupEntryByClientTag(
+    const ModelType& model_type,
+    const std::string& client_tag) {
+  syncer::ReadTransaction trans(FROM_HERE, user_share());
+  syncer::ReadNode node(&trans);
+  return node.InitByClientTagLookup(model_type, client_tag);
+}
+
+void SyncApiTest::ReplaceWithTombstone(const ModelType& model_type,
+                                       const std::string& client_tag) {
+  syncer::WriteTransaction trans(FROM_HERE, user_share());
+  syncer::WriteNode node(&trans);
+  ASSERT_EQ(node.InitByClientTagLookup(model_type, client_tag),
+            syncer::WriteNode::INIT_OK);
+  node.Tombstone();
+}
+
 TEST_F(SyncApiTest, SanityCheckTest) {
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     EXPECT_TRUE(trans.GetWrappedTrans());
   }
   {
-    WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
+    WriteTransaction trans(FROM_HERE, user_share());
     EXPECT_TRUE(trans.GetWrappedTrans());
   }
   {
     // No entries but root should exist
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     ReadNode node(&trans);
     // Metahandle 1 can be root, sanity check 2
     EXPECT_EQ(BaseNode::INIT_FAILED_ENTRY_NOT_GOOD, node.InitByIdLookup(2));
@@ -234,17 +306,16 @@
 
 TEST_F(SyncApiTest, BasicTagWrite) {
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     ReadNode root_node(&trans);
     root_node.InitByRootLookup();
     EXPECT_EQ(root_node.GetFirstChildId(), 0);
   }
 
-  ignore_result(MakeNode(test_user_share_.user_share(),
-                         BOOKMARKS, "testtag"));
+  ignore_result(MakeNode(user_share(), BOOKMARKS, "testtag"));
 
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     ReadNode node(&trans);
     EXPECT_EQ(BaseNode::INIT_OK,
               node.InitByClientTagLookup(BOOKMARKS, "testtag"));
@@ -258,21 +329,18 @@
 
 TEST_F(SyncApiTest, ModelTypesSiloed) {
   {
-    WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
+    WriteTransaction trans(FROM_HERE, user_share());
     ReadNode root_node(&trans);
     root_node.InitByRootLookup();
     EXPECT_EQ(root_node.GetFirstChildId(), 0);
   }
 
-  ignore_result(MakeNode(test_user_share_.user_share(),
-                         BOOKMARKS, "collideme"));
-  ignore_result(MakeNode(test_user_share_.user_share(),
-                         PREFERENCES, "collideme"));
-  ignore_result(MakeNode(test_user_share_.user_share(),
-                         AUTOFILL, "collideme"));
+  ignore_result(MakeNode(user_share(), BOOKMARKS, "collideme"));
+  ignore_result(MakeNode(user_share(), PREFERENCES, "collideme"));
+  ignore_result(MakeNode(user_share(), AUTOFILL, "collideme"));
 
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
 
     ReadNode bookmarknode(&trans);
     EXPECT_EQ(BaseNode::INIT_OK,
@@ -297,14 +365,14 @@
 
 TEST_F(SyncApiTest, ReadMissingTagsFails) {
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     ReadNode node(&trans);
     EXPECT_EQ(BaseNode::INIT_FAILED_ENTRY_NOT_GOOD,
               node.InitByClientTagLookup(BOOKMARKS,
                   "testtag"));
   }
   {
-    WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
+    WriteTransaction trans(FROM_HERE, user_share());
     WriteNode node(&trans);
     EXPECT_EQ(BaseNode::INIT_FAILED_ENTRY_NOT_GOOD,
               node.InitByClientTagLookup(BOOKMARKS,
@@ -320,7 +388,7 @@
   std::string test_title("test1");
 
   {
-    WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
+    WriteTransaction trans(FROM_HERE, user_share());
     ReadNode root_node(&trans);
     root_node.InitByRootLookup();
 
@@ -341,7 +409,7 @@
 
   // Ensure we can delete something with a tag.
   {
-    WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
+    WriteTransaction trans(FROM_HERE, user_share());
     WriteNode wnode(&trans);
     EXPECT_EQ(BaseNode::INIT_OK,
               wnode.InitByClientTagLookup(BOOKMARKS,
@@ -355,7 +423,7 @@
   // Lookup of a node which was deleted should return failure,
   // but have found some data about the node.
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     ReadNode node(&trans);
     EXPECT_EQ(BaseNode::INIT_FAILED_ENTRY_IS_DEL,
               node.InitByClientTagLookup(BOOKMARKS,
@@ -366,7 +434,7 @@
   }
 
   {
-    WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
+    WriteTransaction trans(FROM_HERE, user_share());
     ReadNode folder_node(&trans);
     EXPECT_EQ(BaseNode::INIT_OK, folder_node.InitByIdLookup(folder_id));
 
@@ -384,7 +452,7 @@
 
   // Now look up should work.
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     ReadNode node(&trans);
     EXPECT_EQ(BaseNode::INIT_OK,
               node.InitByClientTagLookup(BOOKMARKS,
@@ -397,11 +465,11 @@
 TEST_F(SyncApiTest, WriteAndReadPassword) {
   KeyParams params = {"localhost", "username", "passphrase"};
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     trans.GetCryptographer()->AddKey(params);
   }
   {
-    WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
+    WriteTransaction trans(FROM_HERE, user_share());
     ReadNode root_node(&trans);
     root_node.InitByRootLookup();
 
@@ -415,7 +483,7 @@
     password_node.SetPasswordSpecifics(data);
   }
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     ReadNode root_node(&trans);
     root_node.InitByRootLookup();
 
@@ -431,13 +499,13 @@
 TEST_F(SyncApiTest, WriteEncryptedTitle) {
   KeyParams params = {"localhost", "username", "passphrase"};
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     trans.GetCryptographer()->AddKey(params);
   }
-  test_user_share_.encryption_handler()->EnableEncryptEverything();
+  encryption_handler()->EnableEncryptEverything();
   int bookmark_id;
   {
-    WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
+    WriteTransaction trans(FROM_HERE, user_share());
     ReadNode root_node(&trans);
     root_node.InitByRootLookup();
 
@@ -453,7 +521,7 @@
     pref_node.SetTitle("bar");
   }
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     ReadNode root_node(&trans);
     root_node.InitByRootLookup();
 
@@ -472,9 +540,8 @@
 }
 
 TEST_F(SyncApiTest, BaseNodeSetSpecifics) {
-  int64 child_id = MakeNode(test_user_share_.user_share(),
-                            BOOKMARKS, "testtag");
-  WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
+  int64 child_id = MakeNode(user_share(), BOOKMARKS, "testtag");
+  WriteTransaction trans(FROM_HERE, user_share());
   WriteNode node(&trans);
   EXPECT_EQ(BaseNode::INIT_OK, node.InitByIdLookup(child_id));
 
@@ -489,9 +556,8 @@
 }
 
 TEST_F(SyncApiTest, BaseNodeSetSpecificsPreservesUnknownFields) {
-  int64 child_id = MakeNode(test_user_share_.user_share(),
-                            BOOKMARKS, "testtag");
-  WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
+  int64 child_id = MakeNode(user_share(), BOOKMARKS, "testtag");
+  WriteTransaction trans(FROM_HERE, user_share());
   WriteNode node(&trans);
   EXPECT_EQ(BaseNode::INIT_OK, node.InitByIdLookup(child_id));
   EXPECT_TRUE(node.GetEntitySpecifics().unknown_fields().empty());
@@ -508,7 +574,7 @@
 }
 
 TEST_F(SyncApiTest, EmptyTags) {
-  WriteTransaction trans(FROM_HERE, test_user_share_.user_share());
+  WriteTransaction trans(FROM_HERE, user_share());
   ReadNode root_node(&trans);
   root_node.InitByRootLookup();
   WriteNode node(&trans);
@@ -522,10 +588,9 @@
 
 // Test counting nodes when the type's root node has no children.
 TEST_F(SyncApiTest, GetTotalNodeCountEmpty) {
-  int64 type_root = MakeServerNodeForType(test_user_share_.user_share(),
-                                          BOOKMARKS);
+  int64 type_root = MakeServerNodeForType(user_share(), BOOKMARKS);
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     ReadNode type_root_node(&trans);
     EXPECT_EQ(BaseNode::INIT_OK,
               type_root_node.InitByIdLookup(type_root));
@@ -535,14 +600,10 @@
 
 // Test counting nodes when there is one child beneath the type's root.
 TEST_F(SyncApiTest, GetTotalNodeCountOneChild) {
-  int64 type_root = MakeServerNodeForType(test_user_share_.user_share(),
-                                          BOOKMARKS);
-  int64 parent = MakeFolderWithParent(test_user_share_.user_share(),
-                                      BOOKMARKS,
-                                      type_root,
-                                      NULL);
+  int64 type_root = MakeServerNodeForType(user_share(), BOOKMARKS);
+  int64 parent = MakeFolderWithParent(user_share(), BOOKMARKS, type_root, NULL);
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     ReadNode type_root_node(&trans);
     EXPECT_EQ(BaseNode::INIT_OK,
               type_root_node.InitByIdLookup(type_root));
@@ -557,32 +618,15 @@
 // Test counting nodes when there are multiple children beneath the type root,
 // and one of those children has children of its own.
 TEST_F(SyncApiTest, GetTotalNodeCountMultipleChildren) {
-  int64 type_root = MakeServerNodeForType(test_user_share_.user_share(),
-                                          BOOKMARKS);
-  int64 parent = MakeFolderWithParent(test_user_share_.user_share(),
-                                      BOOKMARKS,
-                                      type_root,
-                                      NULL);
-  ignore_result(MakeFolderWithParent(test_user_share_.user_share(),
-                                     BOOKMARKS,
-                                     type_root,
-                                     NULL));
-  int64 child1 = MakeFolderWithParent(
-      test_user_share_.user_share(),
-      BOOKMARKS,
-      parent,
-      NULL);
-  ignore_result(MakeBookmarkWithParent(
-      test_user_share_.user_share(),
-      parent,
-      NULL));
-  ignore_result(MakeBookmarkWithParent(
-      test_user_share_.user_share(),
-      child1,
-      NULL));
+  int64 type_root = MakeServerNodeForType(user_share(), BOOKMARKS);
+  int64 parent = MakeFolderWithParent(user_share(), BOOKMARKS, type_root, NULL);
+  ignore_result(MakeFolderWithParent(user_share(), BOOKMARKS, type_root, NULL));
+  int64 child1 = MakeFolderWithParent(user_share(), BOOKMARKS, parent, NULL);
+  ignore_result(MakeBookmarkWithParent(user_share(), parent, NULL));
+  ignore_result(MakeBookmarkWithParent(user_share(), child1, NULL));
 
   {
-    ReadTransaction trans(FROM_HERE, test_user_share_.user_share());
+    ReadTransaction trans(FROM_HERE, user_share());
     ReadNode type_root_node(&trans);
     EXPECT_EQ(BaseNode::INIT_OK,
               type_root_node.InitByIdLookup(type_root));
@@ -594,6 +638,57 @@
   }
 }
 
+// Verify that Directory keeps track of which attachments are referenced by
+// which entries.
+TEST_F(SyncApiTest, AttachmentLinking) {
+  // Add an entry with an attachment.
+  std::string tag1("some tag");
+  syncer::AttachmentId attachment_id(syncer::AttachmentId::Create());
+  sync_pb::AttachmentMetadata attachment_metadata;
+  sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
+  *record->mutable_id() = attachment_id.GetProto();
+  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
+  CreateEntryWithAttachmentMetadata(PREFERENCES, tag1, attachment_metadata);
+
+  // See that the directory knows it's linked.
+  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
+
+  // Add a second entry referencing the same attachment.
+  std::string tag2("some other tag");
+  CreateEntryWithAttachmentMetadata(PREFERENCES, tag2, attachment_metadata);
+
+  // See that the directory knows it's still linked.
+  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
+
+  // Tombstone the first entry.
+  ReplaceWithTombstone(syncer::PREFERENCES, tag1);
+
+  // See that the attachment is still considered linked because the entry hasn't
+  // been purged from the Directory.
+  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
+
+  // Save changes and see that the entry is truly gone.
+  ASSERT_TRUE(dir()->SaveChanges());
+  ASSERT_EQ(LookupEntryByClientTag(PREFERENCES, tag1),
+            syncer::WriteNode::INIT_FAILED_ENTRY_NOT_GOOD);
+
+  // However, the attachment is still linked.
+  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
+
+  // Save, destroy, and recreate the directory.  See that it's still linked.
+  ASSERT_TRUE(ReloadDir());
+  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
+
+  // Tombstone the second entry, save changes, see that it's truly gone.
+  ReplaceWithTombstone(syncer::PREFERENCES, tag2);
+  ASSERT_TRUE(dir()->SaveChanges());
+  ASSERT_EQ(LookupEntryByClientTag(PREFERENCES, tag2),
+            syncer::WriteNode::INIT_FAILED_ENTRY_NOT_GOOD);
+
+  // Finally, the attachment is no longer linked.
+  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
+}
+
 namespace {
 
 class TestHttpPostProviderInterface : public HttpPostProviderInterface {
diff --git a/sync/internal_api/sync_rollback_manager_base.cc b/sync/internal_api/sync_rollback_manager_base.cc
index 98fcd48..e5a4779 100644
--- a/sync/internal_api/sync_rollback_manager_base.cc
+++ b/sync/internal_api/sync_rollback_manager_base.cc
@@ -8,7 +8,6 @@
 #include "sync/internal_api/public/internal_components_factory.h"
 #include "sync/internal_api/public/read_node.h"
 #include "sync/internal_api/public/read_transaction.h"
-#include "sync/internal_api/public/util/syncer_error.h"
 #include "sync/internal_api/public/write_transaction.h"
 #include "sync/syncable/directory_backing_store.h"
 #include "sync/syncable/mutable_entry.h"
@@ -20,13 +19,31 @@
 const char kMobileBookmarksTag[] = "synced_bookmarks";
 const char kOtherBookmarksTag[] = "other_bookmarks";
 
+class DummyEntryptionHandler : public syncer::SyncEncryptionHandler {
+  virtual void AddObserver(Observer* observer) OVERRIDE {}
+  virtual void RemoveObserver(Observer* observer) OVERRIDE {}
+  virtual void Init() OVERRIDE {}
+  virtual void SetEncryptionPassphrase(const std::string& passphrase,
+                                       bool is_explicit) OVERRIDE {}
+  virtual void SetDecryptionPassphrase(const std::string& passphrase)
+      OVERRIDE {}
+  virtual void EnableEncryptEverything() OVERRIDE {}
+  virtual bool EncryptEverythingEnabled() const OVERRIDE {
+    return false;
+  }
+  virtual syncer::PassphraseType GetPassphraseType() const OVERRIDE {
+    return syncer::KEYSTORE_PASSPHRASE;
+  }
+};
+
 }  // anonymous namespace
 
 namespace syncer {
 
 SyncRollbackManagerBase::SyncRollbackManagerBase()
     : report_unrecoverable_error_function_(NULL),
-      weak_ptr_factory_(this) {
+      weak_ptr_factory_(this),
+      dummy_handler_(new DummyEntryptionHandler) {
 }
 
 SyncRollbackManagerBase::~SyncRollbackManagerBase() {
@@ -85,7 +102,6 @@
 
 void SyncRollbackManagerBase::UpdateCredentials(
     const SyncCredentials& credentials) {
-  NOTREACHED();
 }
 
 void SyncRollbackManagerBase::StartSyncingNormally(
@@ -101,9 +117,6 @@
       const ModelSafeRoutingInfo& new_routing_info,
       const base::Closure& ready_task,
       const base::Closure& retry_task) {
-  DCHECK(to_purge.Empty());
-  DCHECK(to_journal.Empty());
-  DCHECK(to_unapply.Empty());
   for (ModelTypeSet::Iterator type = to_download.First();
       type.Good(); type.Inc()) {
     if (InitTypeRootNode(type.Get())) {
@@ -169,7 +182,7 @@
 }
 
 SyncEncryptionHandler* SyncRollbackManagerBase::GetEncryptionHandler() {
-  return NULL;
+  return dummy_handler_.get();
 }
 
 void SyncRollbackManagerBase::RefreshTypes(ModelTypeSet types) {
@@ -319,4 +332,15 @@
   entry.PutSpecifics(specifics);
 }
 
+void SyncRollbackManagerBase::RegisterDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {}
+
+void SyncRollbackManagerBase::UnregisterDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {}
+
+bool SyncRollbackManagerBase::HasDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) { return false; }
+
+void SyncRollbackManagerBase::RequestEmitDebugInfo() {}
+
 }  // namespace syncer
diff --git a/sync/internal_api/sync_rollback_manager_base.h b/sync/internal_api/sync_rollback_manager_base.h
index d6ba564..b6469da 100644
--- a/sync/internal_api/sync_rollback_manager_base.h
+++ b/sync/internal_api/sync_rollback_manager_base.h
@@ -113,6 +113,14 @@
       const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
       ModelTypeSet models_with_changes) OVERRIDE;
 
+  virtual void RegisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual void UnregisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual bool HasDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer) OVERRIDE;
+  virtual void RequestEmitDebugInfo() OVERRIDE;
+
  private:
   void NotifyInitializationSuccess();
   void NotifyInitializationFailure();
@@ -132,6 +140,8 @@
 
   base::WeakPtrFactory<SyncRollbackManagerBase> weak_ptr_factory_;
 
+  scoped_ptr<SyncEncryptionHandler> dummy_handler_;
+
   DISALLOW_COPY_AND_ASSIGN(SyncRollbackManagerBase);
 };
 
diff --git a/sync/internal_api/test/fake_sync_manager.cc b/sync/internal_api/test/fake_sync_manager.cc
index c7873a8..5b0f121 100644
--- a/sync/internal_api/test/fake_sync_manager.cc
+++ b/sync/internal_api/test/fake_sync_manager.cc
@@ -253,6 +253,19 @@
   last_refresh_request_types_ = types;
 }
 
+void FakeSyncManager::RegisterDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {}
+
+void FakeSyncManager::UnregisterDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {}
+
+bool FakeSyncManager::HasDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {
+  return false;
+}
+
+void FakeSyncManager::RequestEmitDebugInfo() {}
+
 void FakeSyncManager::OnIncomingInvalidation(
       const ObjectIdInvalidationMap& invalidation_map) {
   // Do nothing.
diff --git a/sync/internal_api/write_node.cc b/sync/internal_api/write_node.cc
index 6a634eb..c3ef081 100644
--- a/sync/internal_api/write_node.cc
+++ b/sync/internal_api/write_node.cc
@@ -464,6 +464,11 @@
   return PutPredecessor(predecessor);
 }
 
+void WriteNode::SetAttachmentMetadata(
+    const sync_pb::AttachmentMetadata& attachment_metadata) {
+  entry_->PutAttachmentMetadata(attachment_metadata);
+}
+
 const syncable::Entry* WriteNode::GetEntry() const {
   return entry_;
 }
diff --git a/sync/notifier/gcm_network_channel.cc b/sync/notifier/gcm_network_channel.cc
index 484ea05..654123a 100644
--- a/sync/notifier/gcm_network_channel.cc
+++ b/sync/notifier/gcm_network_channel.cc
@@ -14,6 +14,7 @@
 // is safe to exclude these protos from Android build.
 #include "google/cacheinvalidation/android_channel.pb.h"
 #include "google/cacheinvalidation/channel_common.pb.h"
+#include "google/cacheinvalidation/types.pb.h"
 #endif
 #include "google_apis/gaia/google_service_auth_error.h"
 #include "net/http/http_status_code.h"
@@ -94,7 +95,7 @@
 
 void RecordOutgoingMessageStatus(OutgoingMessageStatus status) {
   UMA_HISTOGRAM_ENUMERATION(kOutgoingMessageStatusHistogram,
-                            MESSAGE_DISCARDED,
+                            status,
                             OUTGOING_MESSAGE_STATUS_COUNT);
 }
 
@@ -365,6 +366,14 @@
   // Do nothing. We get access token by requesting it for every message.
 }
 
+int GCMNetworkChannel::GetInvalidationClientType() {
+#if defined(OS_IOS)
+  return ipc::invalidation::ClientType::CHROME_SYNC_GCM_IOS;
+#else
+  return ipc::invalidation::ClientType::CHROME_SYNC_GCM_DESKTOP;
+#endif
+}
+
 void GCMNetworkChannel::ResetRegisterBackoffEntryForTest(
     const net::BackoffEntry::Policy* policy) {
   register_backoff_entry_.reset(new net::BackoffEntry(policy));
diff --git a/sync/notifier/gcm_network_channel.h b/sync/notifier/gcm_network_channel.h
index 3f2afc9..5f86ce7 100644
--- a/sync/notifier/gcm_network_channel.h
+++ b/sync/notifier/gcm_network_channel.h
@@ -66,6 +66,7 @@
   // SyncNetworkChannel implementation.
   virtual void UpdateCredentials(const std::string& email,
                                  const std::string& token) OVERRIDE;
+  virtual int GetInvalidationClientType() OVERRIDE;
   virtual void RequestDetailedStatus(
       base::Callback<void(const base::DictionaryValue&)> callback) OVERRIDE;
 
diff --git a/sync/notifier/push_client_channel.cc b/sync/notifier/push_client_channel.cc
index 3426d2c..9bf78f4 100644
--- a/sync/notifier/push_client_channel.cc
+++ b/sync/notifier/push_client_channel.cc
@@ -6,6 +6,7 @@
 
 #include "base/stl_util.h"
 #include "google/cacheinvalidation/client_gateway.pb.h"
+#include "google/cacheinvalidation/types.pb.h"
 #include "jingle/notifier/listener/push_client.h"
 
 namespace syncer {
@@ -40,6 +41,14 @@
   push_client_->UpdateCredentials(email, token);
 }
 
+int PushClientChannel::GetInvalidationClientType() {
+#if defined(OS_IOS)
+  return ipc::invalidation::ClientType::CHROME_SYNC_IOS;
+#else
+  return ipc::invalidation::ClientType::CHROME_SYNC;
+#endif
+}
+
 void PushClientChannel::RequestDetailedStatus(
     base::Callback<void(const base::DictionaryValue&)> callback) {
   callback.Run(*CollectDebugData());
diff --git a/sync/notifier/push_client_channel.h b/sync/notifier/push_client_channel.h
index 7e33e5e..0ca9113 100644
--- a/sync/notifier/push_client_channel.h
+++ b/sync/notifier/push_client_channel.h
@@ -43,6 +43,7 @@
   // credentials.
   virtual void UpdateCredentials(const std::string& email,
       const std::string& token) OVERRIDE;
+  virtual int GetInvalidationClientType() OVERRIDE;
 
   // notifier::PushClient::Observer implementation.
   virtual void OnNotificationsEnabled() OVERRIDE;
diff --git a/sync/notifier/sync_invalidation_listener.cc b/sync/notifier/sync_invalidation_listener.cc
index 231a5b7..8a6acb1 100644
--- a/sync/notifier/sync_invalidation_listener.cc
+++ b/sync/notifier/sync_invalidation_listener.cc
@@ -13,7 +13,6 @@
 #include "base/tracked_objects.h"
 #include "google/cacheinvalidation/include/invalidation-client.h"
 #include "google/cacheinvalidation/include/types.h"
-#include "google/cacheinvalidation/types.pb.h"
 #include "jingle/notifier/listener/push_client.h"
 #include "sync/notifier/invalidation_util.h"
 #include "sync/notifier/object_id_invalidation_map.h"
@@ -76,15 +75,12 @@
   DCHECK(delegate);
   delegate_ = delegate;
 
-#if defined(OS_IOS)
-  int client_type = ipc::invalidation::ClientType::CHROME_SYNC_IOS;
-#else
-  int client_type = ipc::invalidation::ClientType::CHROME_SYNC;
-#endif
-  invalidation_client_.reset(
-      create_invalidation_client_callback.Run(
-          &sync_system_resources_, client_type, client_id,
-          kApplicationName, this));
+  invalidation_client_.reset(create_invalidation_client_callback.Run(
+      &sync_system_resources_,
+      sync_network_channel_->GetInvalidationClientType(),
+      client_id,
+      kApplicationName,
+      this));
   invalidation_client_->Start();
 
   registration_manager_.reset(
diff --git a/sync/notifier/sync_system_resources.h b/sync/notifier/sync_system_resources.h
index a616ee4..b618dc9 100644
--- a/sync/notifier/sync_system_resources.h
+++ b/sync/notifier/sync_system_resources.h
@@ -116,6 +116,11 @@
   virtual void UpdateCredentials(const std::string& email,
       const std::string& token) = 0;
 
+  // Return value from GetInvalidationClientType will be passed to
+  // invalidation::CreateInvalidationClient. Subclass should return one of the
+  // values from ipc::invalidation::ClientType enum from types.proto.
+  virtual int GetInvalidationClientType() = 0;
+
   // Subclass should implement RequestDetailedStatus to provide debugging
   // information.
   virtual void RequestDetailedStatus(
diff --git a/sync/notifier/sync_system_resources_unittest.cc b/sync/notifier/sync_system_resources_unittest.cc
index f8dd459..8acc729 100644
--- a/sync/notifier/sync_system_resources_unittest.cc
+++ b/sync/notifier/sync_system_resources_unittest.cc
@@ -191,6 +191,10 @@
       const std::string& token) OVERRIDE {
   }
 
+  virtual int GetInvalidationClientType() OVERRIDE {
+    return 0;
+  }
+
   virtual void RequestDetailedStatus(
       base::Callback<void(const base::DictionaryValue&)> callback) OVERRIDE {
     base::DictionaryValue value;
diff --git a/sync/protocol/attachments.proto b/sync/protocol/attachments.proto
index 50815d3..e08e2b0 100644
--- a/sync/protocol/attachments.proto
+++ b/sync/protocol/attachments.proto
@@ -21,7 +21,16 @@
   optional string unique_id = 1;
 }
 
+// Metadata for a single attachment.
+message AttachmentMetadataRecord {
+  optional AttachmentIdProto id = 1;
+  // Indicates we know this attachment exists on the server.
+  optional bool is_on_server = 2;
+}
+
 // A collection of attachment metadata. This proto is part of EntryKernel's "on
 // disk" representation. Private to sync.
 message AttachmentMetadata {
+  // One record per attachment.
+  repeated AttachmentMetadataRecord record = 1;
 }
diff --git a/sync/protocol/extension_specifics.proto b/sync/protocol/extension_specifics.proto
index 05120d3..650fd06 100644
--- a/sync/protocol/extension_specifics.proto
+++ b/sync/protocol/extension_specifics.proto
@@ -35,5 +35,9 @@
 
   // The name of the extension. Used for bookmark apps.
   optional string name = 6;
+
+  // Whether this extension was installed remotely, and hasn't been approved by
+  // a user in chrome yet.
+  optional bool remote_install = 7;
 }
 
diff --git a/sync/protocol/proto_value_conversions.cc b/sync/protocol/proto_value_conversions.cc
index 4fb8bdd..e1c8851 100644
--- a/sync/protocol/proto_value_conversions.cc
+++ b/sync/protocol/proto_value_conversions.cc
@@ -508,6 +508,14 @@
   return value;
 }
 
+base::DictionaryValue* EnhancedBookmarksFlagsToValue(
+    const sync_pb::EnhancedBookmarksFlags& proto) {
+  base::DictionaryValue* value = new base::DictionaryValue();
+  SET_BOOL(enabled);
+  SET_STR(extension_id);
+  return value;
+}
+
 }  // namespace
 
 base::DictionaryValue* ExperimentsSpecificsToValue(
@@ -519,7 +527,7 @@
   SET_EXPERIMENT_ENABLED_FIELD(pre_commit_update_avoidance);
   SET(favicon_sync, FaviconSyncFlagsToValue);
   SET_EXPERIMENT_ENABLED_FIELD(gcm_channel);
-  SET_EXPERIMENT_ENABLED_FIELD(enhanced_bookmarks);
+  SET(enhanced_bookmarks, EnhancedBookmarksFlagsToValue);
   SET_EXPERIMENT_ENABLED_FIELD(gcm_invalidations);
   return value;
 }
@@ -541,6 +549,7 @@
   SET_STR(update_url);
   SET_BOOL(enabled);
   SET_BOOL(incognito_enabled);
+  SET_BOOL(remote_install);
   SET_STR(name);
   return value;
 }
diff --git a/sync/sessions/model_type_registry.cc b/sync/sessions/model_type_registry.cc
index a41a7f3..668f8da 100644
--- a/sync/sessions/model_type_registry.cc
+++ b/sync/sessions/model_type_registry.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/message_loop/message_loop_proxy.h"
+#include "base/observer_list.h"
 #include "sync/engine/directory_commit_contributor.h"
 #include "sync/engine/directory_update_handler.h"
 #include "sync/engine/non_blocking_type_processor_core.h"
@@ -30,22 +31,21 @@
 
 void ModelTypeRegistry::SetEnabledDirectoryTypes(
     const ModelSafeRoutingInfo& routing_info) {
-  // Remove all existing directory processors and delete them.
+  // Remove all existing directory processors and delete them.  The
+  // DebugInfoEmitters are not deleted here, since we want to preserve their
+  // counters.
   for (ModelTypeSet::Iterator it = enabled_directory_types_.First();
        it.Good(); it.Inc()) {
     size_t result1 = update_handler_map_.erase(it.Get());
     size_t result2 = commit_contributor_map_.erase(it.Get());
-    size_t result3 = directory_type_debug_info_emitter_map_.erase(it.Get());
     DCHECK_EQ(1U, result1);
     DCHECK_EQ(1U, result2);
-    DCHECK_EQ(1U, result3);
   }
 
   // Clear the old instances of directory update handlers and commit
   // contributors, deleting their contents in the processs.
   directory_update_handlers_.clear();
   directory_commit_contributors_.clear();
-  directory_type_debug_info_emitters_.clear();
 
   // Create new ones and add them to the appropriate containers.
   for (ModelSafeRoutingInfo::const_iterator routing_iter = routing_info.begin();
@@ -57,18 +57,28 @@
     DCHECK(worker_it != workers_map_.end());
     scoped_refptr<ModelSafeWorker> worker = worker_it->second;
 
-    DirectoryTypeDebugInfoEmitter* emitter =
-        new DirectoryTypeDebugInfoEmitter(directory_, type,
-                                          &type_debug_info_observers_);
+    // DebugInfoEmitters are never deleted.  Use existing one if we have it.
+    DirectoryTypeDebugInfoEmitter* emitter = NULL;
+    DirectoryTypeDebugInfoEmitterMap::iterator it =
+        directory_type_debug_info_emitter_map_.find(type);
+    if (it != directory_type_debug_info_emitter_map_.end()) {
+      emitter = it->second;
+    } else {
+      emitter = new DirectoryTypeDebugInfoEmitter(directory_, type,
+                                                  &type_debug_info_observers_);
+      directory_type_debug_info_emitter_map_.insert(
+          std::make_pair(type, emitter));
+      directory_type_debug_info_emitters_.push_back(emitter);
+    }
+
     DirectoryCommitContributor* committer =
-        new DirectoryCommitContributor(directory_, type);
+        new DirectoryCommitContributor(directory_, type, emitter);
     DirectoryUpdateHandler* updater =
-        new DirectoryUpdateHandler(directory_, type, worker);
+        new DirectoryUpdateHandler(directory_, type, worker, emitter);
 
     // These containers take ownership of their contents.
     directory_commit_contributors_.push_back(committer);
     directory_update_handlers_.push_back(updater);
-    directory_type_debug_info_emitters_.push_back(emitter);
 
     bool inserted1 =
         update_handler_map_.insert(std::make_pair(type, updater)).second;
@@ -77,11 +87,6 @@
     bool inserted2 =
         commit_contributor_map_.insert(std::make_pair(type, committer)).second;
     DCHECK(inserted2) << "Attempt to override existing type handler in map";
-
-    bool inserted3 =
-        directory_type_debug_info_emitter_map_.insert(
-            std::make_pair(type, emitter)).second;
-    DCHECK(inserted3) << "Attempt to override existing type handler in map";
   }
 
   enabled_directory_types_ = GetRoutingInfoTypes(routing_info);
@@ -160,6 +165,32 @@
   return &directory_type_debug_info_emitter_map_;
 }
 
+void ModelTypeRegistry::RegisterDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {
+  if (!type_debug_info_observers_.HasObserver(observer))
+    type_debug_info_observers_.AddObserver(observer);
+}
+
+void ModelTypeRegistry::UnregisterDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {
+  type_debug_info_observers_.RemoveObserver(observer);
+}
+
+bool ModelTypeRegistry::HasDirectoryTypeDebugInfoObserver(
+    syncer::TypeDebugInfoObserver* observer) {
+  return type_debug_info_observers_.HasObserver(observer);
+}
+
+void ModelTypeRegistry::RequestEmitDebugInfo() {
+  for (DirectoryTypeDebugInfoEmitterMap::iterator it =
+       directory_type_debug_info_emitter_map_.begin();
+       it != directory_type_debug_info_emitter_map_.end(); ++it) {
+    it->second->EmitCommitCountersUpdate();
+    it->second->EmitUpdateCountersUpdate();
+    it->second->EmitStatusCountersUpdate();
+  }
+}
+
 ModelTypeSet ModelTypeRegistry::GetEnabledDirectoryTypes() const {
   return enabled_directory_types_;
 }
diff --git a/sync/sessions/model_type_registry.h b/sync/sessions/model_type_registry.h
index 3ee36c7..20d6d20 100644
--- a/sync/sessions/model_type_registry.h
+++ b/sync/sessions/model_type_registry.h
@@ -73,6 +73,14 @@
   CommitContributorMap* commit_contributor_map();
   DirectoryTypeDebugInfoEmitterMap* directory_type_debug_info_emitter_map();
 
+  void RegisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer);
+  void UnregisterDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer);
+  bool HasDirectoryTypeDebugInfoObserver(
+      syncer::TypeDebugInfoObserver* observer);
+  void RequestEmitDebugInfo();
+
  private:
   ModelTypeSet GetEnabledNonBlockingTypes() const;
   ModelTypeSet GetEnabledDirectoryTypes() const;
diff --git a/sync/sessions/model_type_registry_unittest.cc b/sync/sessions/model_type_registry_unittest.cc
index 0248e8d..375e84b 100644
--- a/sync/sessions/model_type_registry_unittest.cc
+++ b/sync/sessions/model_type_registry_unittest.cc
@@ -113,6 +113,24 @@
   registry()->SetEnabledDirectoryTypes(routing_info2);
 }
 
+// Test disabling then re-enabling some directory types.
+//
+// We don't get to inspect any of the state we're modifying.  This test is
+// useful only for detecting crashes or memory leaks.
+TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_OffAndOn) {
+  ModelSafeRoutingInfo routing_info1;
+  routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
+  routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_UI));
+  routing_info1.insert(std::make_pair(AUTOFILL, GROUP_DB));
+
+  registry()->SetEnabledDirectoryTypes(routing_info1);
+
+  ModelSafeRoutingInfo routing_info2;
+  registry()->SetEnabledDirectoryTypes(routing_info2);
+
+  registry()->SetEnabledDirectoryTypes(routing_info1);
+}
+
 TEST_F(ModelTypeRegistryTest, NonBlockingTypes) {
   NonBlockingTypeProcessor themes_processor(syncer::THEMES);
   NonBlockingTypeProcessor sessions_processor(syncer::SESSIONS);
diff --git a/sync/sync_api.gypi b/sync/sync_api.gypi
index 8cee5bd..dfe05f8 100644
--- a/sync/sync_api.gypi
+++ b/sync/sync_api.gypi
@@ -25,10 +25,14 @@
     'api/attachments/attachment_service_proxy_for_test.h',
     'api/attachments/attachment_store.cc',
     'api/attachments/attachment_store.h',
+    'api/attachments/attachment_uploader.cc',
+    'api/attachments/attachment_uploader.h',
     'api/attachments/fake_attachment_service.cc',
     'api/attachments/fake_attachment_service.h',
     'api/attachments/fake_attachment_store.cc',
     'api/attachments/fake_attachment_store.h',
+    'api/attachments/fake_attachment_uploader.cc',
+    'api/attachments/fake_attachment_uploader.h',
     'api/string_ordinal.h',
     'api/syncable_service.cc',
     'api/syncable_service.h',
diff --git a/sync/sync_internal_api.gypi b/sync/sync_internal_api.gypi
index 6078dd8..6f9af03 100644
--- a/sync/sync_internal_api.gypi
+++ b/sync/sync_internal_api.gypi
@@ -45,6 +45,8 @@
     'internal_api/protocol_event_buffer.h',
     'internal_api/public/base/ack_handle.cc',
     'internal_api/public/base/ack_handle.h',
+    'internal_api/public/base/attachment_id_proto.cc',
+    'internal_api/public/base/attachment_id_proto.h',
     'internal_api/public/base/cancelation_observer.cc',
     'internal_api/public/base/cancelation_observer.h',
     'internal_api/public/base/cancelation_signal.cc',
diff --git a/sync/sync_tests.gypi b/sync/sync_tests.gypi
index fffefa5..4bb0c7a 100644
--- a/sync/sync_tests.gypi
+++ b/sync/sync_tests.gypi
@@ -113,6 +113,12 @@
       'sources': [
         'test/fake_server/bookmark_entity.cc',
         'test/fake_server/bookmark_entity.h',
+        'test/fake_server/bookmark_entity_builder.cc',
+        'test/fake_server/bookmark_entity_builder.h',
+        'test/fake_server/entity_builder.cc',
+        'test/fake_server/entity_builder.h',
+        'test/fake_server/entity_builder_factory.cc',
+        'test/fake_server/entity_builder_factory.h',
         'test/fake_server/fake_server.cc',
         'test/fake_server/fake_server.h',
         'test/fake_server/fake_server_entity.cc',
@@ -476,6 +482,7 @@
           'api/attachments/attachment_id_unittest.cc',
           'api/attachments/attachment_service_proxy_unittest.cc',
           'api/attachments/fake_attachment_store_unittest.cc',
+          'api/attachments/fake_attachment_uploader_unittest.cc',
           'api/sync_change_unittest.cc',
           'api/sync_data_unittest.cc',
           'api/sync_error_unittest.cc',
@@ -504,8 +511,7 @@
         # TODO(akalin): This is needed because histogram.cc uses
         # leak_annotations.h, which pulls this in.  Make 'base'
         # propagate this dependency.
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and use_allocator!="none"', {
           'dependencies': [
             '../base/allocator/allocator.gyp:allocator',
           ],
@@ -598,27 +604,6 @@
           ],
         },
 
-        # A standalone executable that runs a Sync FakeServer instance.
-        {
-          'target_name': 'run_sync_fake_server',
-          'type': 'executable',
-          'dependencies': [
-            '../base/base.gyp:base',
-            '../base/base.gyp:test_support_base',
-            '../net/net.gyp:http_server',
-            '../net/net.gyp:net',
-            '../net/net.gyp:net_test_support',
-            '../testing/gtest.gyp:gtest',
-            '../url/url.gyp:url_lib',
-            'test_support_sync_fake_server',
-          ],
-          'sources': [
-            'test/fake_server/run_sync_fake_server.cc',
-            'test/fake_server/fake_sync_server_http_handler.cc',
-            'test/fake_server/fake_sync_server_http_handler.h',
-          ],
-        },
-
         # A tool to listen to sync notifications and print them out.
         {
           'target_name': 'sync_listen_notifications',
diff --git a/sync/syncable/directory.cc b/sync/syncable/directory.cc
index 75c1bec..cebb2d4 100644
--- a/sync/syncable/directory.cc
+++ b/sync/syncable/directory.cc
@@ -10,6 +10,7 @@
 #include "base/debug/trace_event.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
+#include "sync/internal_api/public/base/attachment_id_proto.h"
 #include "sync/internal_api/public/base/unique_position.h"
 #include "sync/internal_api/public/util/unrecoverable_error_handler.h"
 #include "sync/syncable/entry.h"
@@ -123,6 +124,7 @@
 }
 
 void Directory::InitializeIndices(MetahandlesMap* handles_map) {
+  ScopedKernelLock lock(this);
   kernel_->metahandles_map.swap(*handles_map);
   for (MetahandlesMap::const_iterator it = kernel_->metahandles_map.begin();
        it != kernel_->metahandles_map.end(); ++it) {
@@ -152,6 +154,7 @@
            kernel_->ids_map.end()) << "Unexpected duplicate use of ID";
     kernel_->ids_map[entry->ref(ID).value()] = entry;
     DCHECK(!entry->is_dirty());
+    AddToAttachmentIndex(metahandle, entry->ref(ATTACHMENT_METADATA), lock);
   }
 }
 
@@ -362,6 +365,8 @@
       return false;
     }
   }
+  AddToAttachmentIndex(
+      entry->ref(META_HANDLE), entry->ref(ATTACHMENT_METADATA), *lock);
 
   // Should NEVER be created with a client tag or server tag.
   if (!SyncAssert(entry->ref(UNIQUE_SERVER_TAG).empty(), FROM_HERE,
@@ -408,6 +413,51 @@
   return true;
 }
 
+void Directory::RemoveFromAttachmentIndex(
+    const int64 metahandle,
+    const sync_pb::AttachmentMetadata& attachment_metadata,
+    const ScopedKernelLock& lock) {
+  for (int i = 0; i < attachment_metadata.record_size(); ++i) {
+    AttachmentIdUniqueId unique_id =
+        attachment_metadata.record(i).id().unique_id();
+    IndexByAttachmentId::iterator iter =
+        kernel_->index_by_attachment_id.find(unique_id);
+    if (iter != kernel_->index_by_attachment_id.end()) {
+      iter->second.erase(metahandle);
+      if (iter->second.empty()) {
+        kernel_->index_by_attachment_id.erase(iter);
+      }
+    }
+  }
+}
+
+void Directory::AddToAttachmentIndex(
+    const int64 metahandle,
+    const sync_pb::AttachmentMetadata& attachment_metadata,
+    const ScopedKernelLock& lock) {
+  for (int i = 0; i < attachment_metadata.record_size(); ++i) {
+    AttachmentIdUniqueId unique_id =
+        attachment_metadata.record(i).id().unique_id();
+    IndexByAttachmentId::iterator iter =
+        kernel_->index_by_attachment_id.find(unique_id);
+    if (iter == kernel_->index_by_attachment_id.end()) {
+      iter = kernel_->index_by_attachment_id.insert(std::make_pair(
+                                                        unique_id,
+                                                        MetahandleSet())).first;
+    }
+    iter->second.insert(metahandle);
+  }
+}
+
+void Directory::UpdateAttachmentIndex(
+    const int64 metahandle,
+    const sync_pb::AttachmentMetadata& old_metadata,
+    const sync_pb::AttachmentMetadata& new_metadata) {
+  ScopedKernelLock lock(this);
+  RemoveFromAttachmentIndex(metahandle, old_metadata, lock);
+  AddToAttachmentIndex(metahandle, new_metadata, lock);
+}
+
 bool Directory::unrecoverable_error_set(const BaseTransaction* trans) const {
   DCHECK(trans != NULL);
   return unrecoverable_error_set_;
@@ -548,6 +598,9 @@
                       "Deleted entry still present",
                       (&trans)))
         return false;
+      RemoveFromAttachmentIndex(
+          entry->ref(META_HANDLE), entry->ref(ATTACHMENT_METADATA), lock);
+
       delete entry;
     }
     if (trans.unrecoverable_error_set())
@@ -607,7 +660,8 @@
 
 void Directory::DeleteEntry(bool save_to_journal,
                             EntryKernel* entry,
-                            EntryKernelSet* entries_to_journal) {
+                            EntryKernelSet* entries_to_journal,
+                            const ScopedKernelLock& lock) {
   int64 handle = entry->ref(META_HANDLE);
   ModelType server_type = GetModelTypeFromSpecifics(
       entry->ref(SERVER_SPECIFICS));
@@ -637,6 +691,7 @@
         kernel_->server_tags_map.erase(entry->ref(UNIQUE_SERVER_TAG));
     DCHECK_EQ(1u, num_erased);
   }
+  RemoveFromAttachmentIndex(handle, entry->ref(ATTACHMENT_METADATA), lock);
 
   if (save_to_journal) {
     entries_to_journal->insert(entry);
@@ -704,7 +759,7 @@
                types_to_journal.Has(server_type)) &&
               (delete_journal_->IsDeleteJournalEnabled(local_type) ||
                delete_journal_->IsDeleteJournalEnabled(server_type));
-          DeleteEntry(save_to_journal, entry, &entries_to_journal);
+          DeleteEntry(save_to_journal, entry, &entries_to_journal, lock);
         }
       }
 
@@ -762,6 +817,17 @@
   return true;
 }
 
+bool Directory::IsAttachmentLinked(
+    const sync_pb::AttachmentIdProto& attachment_id_proto) const {
+  ScopedKernelLock lock(this);
+  IndexByAttachmentId::const_iterator iter =
+      kernel_->index_by_attachment_id.find(attachment_id_proto.unique_id());
+  if (iter != kernel_->index_by_attachment_id.end() && !iter->second.empty()) {
+    return true;
+  }
+  return false;
+}
+
 void Directory::HandleSaveChangesFailure(const SaveChangesSnapshot& snapshot) {
   WriteTransaction trans(FROM_HERE, HANDLE_SAVE_FAILURE, this);
   ScopedKernelLock lock(this);
diff --git a/sync/syncable/directory.h b/sync/syncable/directory.h
index fdac9b4..5d26bbd 100644
--- a/sync/syncable/directory.h
+++ b/sync/syncable/directory.h
@@ -47,6 +47,9 @@
   FULL_DB_VERIFICATION = 2 // Check every entry.  This can be expensive.
 };
 
+// Directory stores and manages EntryKernels.
+//
+// This class is tightly coupled to several other classes (see friends).
 class SYNC_EXPORT Directory {
   friend class BaseTransaction;
   friend class Entry;
@@ -80,6 +83,9 @@
   typedef base::hash_map<int64, EntryKernel*> MetahandlesMap;
   typedef base::hash_map<std::string, EntryKernel*> IdsMap;
   typedef base::hash_map<std::string, EntryKernel*> TagsMap;
+  typedef std::string AttachmentIdUniqueId;
+  typedef base::hash_map<AttachmentIdUniqueId, MetahandleSet>
+      IndexByAttachmentId;
 
   static const base::FilePath::CharType kSyncDatabaseFilename[];
 
@@ -383,6 +389,14 @@
   // WARNING! This can be slow, as it iterates over all entries for a type.
   bool ResetVersionsForType(BaseWriteTransaction* trans, ModelType type);
 
+  // Returns true iff the attachment identified by |attachment_id_proto| is
+  // linked to an entry.
+  //
+  // An attachment linked to a deleted entry is still considered linked if the
+  // entry hasn't yet been purged.
+  bool IsAttachmentLinked(
+      const sync_pb::AttachmentIdProto& attachment_id_proto) const;
+
  protected:  // for friends, mainly used by Entry constructors
   virtual EntryKernel* GetEntryByHandle(int64 handle);
   virtual EntryKernel* GetEntryByHandle(int64 metahandle,
@@ -394,6 +408,11 @@
                  const Id& new_id);
   bool ReindexParentId(BaseWriteTransaction* trans, EntryKernel* const entry,
                        const Id& new_parent_id);
+  // Update the attachment index for |metahandle| removing it from the index
+  // under |old_metadata| entries and add it under |new_metadata| entries.
+  void UpdateAttachmentIndex(const int64 metahandle,
+                             const sync_pb::AttachmentMetadata& old_metadata,
+                             const sync_pb::AttachmentMetadata& new_metadata);
   void ClearDirtyMetahandles();
 
   DirOpenResult OpenImpl(
@@ -451,6 +470,17 @@
     // within parent.  Protected by the ScopedKernelLock.
     ParentChildIndex parent_child_index;
 
+    // This index keeps track of which metahandles refer to a given attachment.
+    // Think of it as the inverse of EntryKernel's AttachmentMetadata Records.
+    //
+    // Because entries can be undeleted (e.g. PutIsDel(false)), entries should
+    // not removed from the index until they are actually deleted from memory.
+    //
+    // All access should go through IsAttachmentLinked,
+    // RemoveFromAttachmentIndex, AddToAttachmentIndex, and
+    // UpdateAttachmentIndex methods to avoid iterator invalidation errors.
+    IndexByAttachmentId index_by_attachment_id;
+
     // 3 in-memory indices on bits used extremely frequently by the syncer.
     // |unapplied_update_metahandles| is keyed by the server model type.
     MetahandleSet unapplied_update_metahandles[MODEL_TYPE_COUNT];
@@ -543,7 +573,19 @@
   void UnapplyEntry(EntryKernel* entry);
   void DeleteEntry(bool save_to_journal,
                    EntryKernel* entry,
-                   EntryKernelSet* entries_to_journal);
+                   EntryKernelSet* entries_to_journal,
+                   const ScopedKernelLock& lock);
+
+  // Remove each of |metahandle|'s attachment ids from index_by_attachment_id.
+  void RemoveFromAttachmentIndex(
+      const int64 metahandle,
+      const sync_pb::AttachmentMetadata& attachment_metadata,
+      const ScopedKernelLock& lock);
+  // Add each of |metahandle|'s attachment ids to the index_by_attachment_id.
+  void AddToAttachmentIndex(
+      const int64 metahandle,
+      const sync_pb::AttachmentMetadata& attachment_metadata,
+      const ScopedKernelLock& lock);
 
   Kernel* kernel_;
 
diff --git a/sync/syncable/directory_backing_store.cc b/sync/syncable/directory_backing_store.cc
index e466548..ec28a53 100644
--- a/sync/syncable/directory_backing_store.cc
+++ b/sync/syncable/directory_backing_store.cc
@@ -70,6 +70,11 @@
     entry.ref(static_cast<UniquePositionField>(i)).SerializeToString(&temp);
     statement->BindBlob(index++, temp.data(), temp.length());
   }
+  for (; i < ATTACHMENT_METADATA_FIELDS_END; ++i) {
+    std::string temp;
+    entry.ref(static_cast<AttachmentMetadataField>(i)).SerializeToString(&temp);
+    statement->BindBlob(index++, temp.data(), temp.length());
+  }
 }
 
 // The caller owns the returned EntryKernel*.  Assumes the statement currently
@@ -114,6 +119,10 @@
     kernel->mutable_ref(static_cast<UniquePositionField>(i)) =
         UniquePosition::FromProto(proto);
   }
+  for (; i < ATTACHMENT_METADATA_FIELDS_END; ++i) {
+    kernel->mutable_ref(static_cast<AttachmentMetadataField>(i)).ParseFromArray(
+        statement->ColumnBlob(i), statement->ColumnByteLength(i));
+  }
   return kernel.Pass();
 }
 
diff --git a/sync/syncable/directory_unittest.cc b/sync/syncable/directory_unittest.cc
index b2bff36..f58f54f 100644
--- a/sync/syncable/directory_unittest.cc
+++ b/sync/syncable/directory_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/strings/stringprintf.h"
 #include "base/test/values_test_util.h"
+#include "sync/internal_api/public/base/attachment_id_proto.h"
 #include "sync/syncable/syncable_proto_util.h"
 #include "sync/syncable/syncable_util.h"
 #include "sync/syncable/syncable_write_transaction.h"
@@ -84,23 +85,45 @@
 }
 
 // Creates an empty entry and sets the ID field to a default one.
-void SyncableDirectoryTest::CreateEntry(const std::string& entryname) {
-  CreateEntry(entryname, TestIdFactory::FromNumber(-99));
+void SyncableDirectoryTest::CreateEntry(const ModelType& model_type,
+                                        const std::string& entryname) {
+  CreateEntry(model_type, entryname, TestIdFactory::FromNumber(-99));
 }
 
 // Creates an empty entry and sets the ID field to id.
-void SyncableDirectoryTest::CreateEntry(const std::string& entryname,
+void SyncableDirectoryTest::CreateEntry(const ModelType& model_type,
+                                        const std::string& entryname,
                                         const int id) {
-  CreateEntry(entryname, TestIdFactory::FromNumber(id));
+  CreateEntry(model_type, entryname, TestIdFactory::FromNumber(id));
 }
-void SyncableDirectoryTest::CreateEntry(const std::string& entryname, Id id) {
+
+void SyncableDirectoryTest::CreateEntry(const ModelType& model_type,
+                                        const std::string& entryname,
+                                        const Id& id) {
+  CreateEntryWithAttachmentMetadata(
+      model_type, entryname, id, sync_pb::AttachmentMetadata());
+}
+
+void SyncableDirectoryTest::CreateEntryWithAttachmentMetadata(
+    const ModelType& model_type,
+    const std::string& entryname,
+    const Id& id,
+    const sync_pb::AttachmentMetadata& attachment_metadata) {
   WriteTransaction wtrans(FROM_HERE, UNITTEST, dir_.get());
-  MutableEntry me(&wtrans, CREATE, BOOKMARKS, wtrans.root_id(), entryname);
+  MutableEntry me(&wtrans, CREATE, model_type, wtrans.root_id(), entryname);
   ASSERT_TRUE(me.good());
   me.PutId(id);
+  me.PutAttachmentMetadata(attachment_metadata);
   me.PutIsUnsynced(true);
 }
 
+void SyncableDirectoryTest::DeleteEntry(const Id& id) {
+  WriteTransaction trans(FROM_HERE, UNITTEST, dir().get());
+  MutableEntry entry(&trans, GET_BY_ID, id);
+  ASSERT_TRUE(entry.good());
+  entry.PutIsDel(true);
+}
+
 DirOpenResult SyncableDirectoryTest::SimulateSaveAndReloadDir() {
   if (!dir_->SaveChanges())
     return FAILED_IN_UNITTEST;
@@ -411,8 +434,8 @@
   int64 handle2 = 0;
   {
     // Create two bookmark entries and save in database.
-    CreateEntry("item1", id1);
-    CreateEntry("item2", id2);
+    CreateEntry(BOOKMARKS, "item1", id1);
+    CreateEntry(BOOKMARKS, "item2", id2);
     {
       WriteTransaction trans(FROM_HERE, UNITTEST, dir().get());
       MutableEntry item1(&trans, GET_BY_ID, id1);
@@ -529,7 +552,7 @@
 }
 
 TEST_F(SyncableDirectoryTest, TestBasicLookupValidID) {
-  CreateEntry("rtc");
+  CreateEntry(BOOKMARKS, "rtc");
   ReadTransaction rtrans(FROM_HERE, dir().get());
   Entry e(&rtrans, GET_BY_ID, TestIdFactory::FromNumber(-99));
   ASSERT_TRUE(e.good());
@@ -1521,6 +1544,100 @@
   }
 }
 
+// Verify that Directory is notifed when a MutableEntry's AttachmentMetadata
+// changes.
+TEST_F(SyncableDirectoryTest, MutableEntry_PutAttachmentMetadata) {
+  sync_pb::AttachmentMetadata attachment_metadata;
+  sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
+  sync_pb::AttachmentIdProto attachment_id_proto =
+      syncer::CreateAttachmentIdProto();
+  *record->mutable_id() = attachment_id_proto;
+  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
+  {
+    WriteTransaction trans(FROM_HERE, UNITTEST, dir().get());
+
+    // Create an entry with attachment metadata and see that the attachment id
+    // is not linked.
+    MutableEntry entry(
+        &trans, CREATE, PREFERENCES, trans.root_id(), "some entry");
+    entry.PutId(TestIdFactory::FromNumber(-1));
+    entry.PutIsUnsynced(true);
+    ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
+
+    // Now add the attachment metadata and see that Directory believes it is
+    // linked.
+    entry.PutAttachmentMetadata(attachment_metadata);
+    ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
+
+    // Clear out the attachment metadata and see that it's no longer linked.
+    sync_pb::AttachmentMetadata empty_attachment_metadata;
+    entry.PutAttachmentMetadata(empty_attachment_metadata);
+    ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
+  }
+  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
+}
+
+// Verify that deleted entries with attachments will retain the attachments.
+TEST_F(SyncableDirectoryTest, Directory_DeleteDoesNotUnlinkAttachments) {
+  sync_pb::AttachmentMetadata attachment_metadata;
+  sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
+  sync_pb::AttachmentIdProto attachment_id_proto =
+      syncer::CreateAttachmentIdProto();
+  *record->mutable_id() = attachment_id_proto;
+  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
+  const Id id = TestIdFactory::FromNumber(-1);
+
+  // Create an entry with attachment metadata and see that the attachment id
+  // is linked.
+  CreateEntryWithAttachmentMetadata(
+      PREFERENCES, "some entry", id, attachment_metadata);
+  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
+
+  // Delete the entry and see that it's still linked because the entry hasn't
+  // yet been purged.
+  DeleteEntry(id);
+  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
+
+  // Reload the Directory, purging the deleted entry, and see that the
+  // attachment is no longer linked.
+  SimulateSaveAndReloadDir();
+  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
+}
+
+// Verify that a given attachment can be referenced by multiple entries and that
+// any one of the references is sufficient to ensure it remains linked.
+TEST_F(SyncableDirectoryTest, Directory_LastReferenceUnlinksAttachments) {
+  // Create one attachment.
+  sync_pb::AttachmentMetadata attachment_metadata;
+  sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
+  sync_pb::AttachmentIdProto attachment_id_proto =
+      syncer::CreateAttachmentIdProto();
+  *record->mutable_id() = attachment_id_proto;
+
+  // Create two entries, each referencing the attachment.
+  const Id id1 = TestIdFactory::FromNumber(-1);
+  const Id id2 = TestIdFactory::FromNumber(-2);
+  CreateEntryWithAttachmentMetadata(
+      PREFERENCES, "some entry", id1, attachment_metadata);
+  CreateEntryWithAttachmentMetadata(
+      PREFERENCES, "some other entry", id2, attachment_metadata);
+
+  // See that the attachment is considered linked.
+  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
+
+  // Delete the first entry, reload the Directory, see that the attachment is
+  // still linked.
+  DeleteEntry(id1);
+  SimulateSaveAndReloadDir();
+  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
+
+  // Delete the second entry, reload the Directory, see that the attachment is
+  // no loner linked.
+  DeleteEntry(id2);
+  SimulateSaveAndReloadDir();
+  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
+}
+
 }  // namespace syncable
 
 }  // namespace syncer
diff --git a/sync/syncable/directory_unittest.h b/sync/syncable/directory_unittest.h
index 14e1a99..81e3888 100644
--- a/sync/syncable/directory_unittest.h
+++ b/sync/syncable/directory_unittest.h
@@ -31,7 +31,6 @@
 //
 // Serves as base class for several other test fixtures.
 class SyncableDirectoryTest : public testing::Test {
- private:
  protected:
   static const char kDirectoryName[];
 
@@ -47,12 +46,24 @@
   DirOpenResult ReopenDirectory();
 
   // Creates an empty entry and sets the ID field to a default one.
-  void CreateEntry(const std::string& entryname);
+  void CreateEntry(const ModelType& model_type, const std::string& entryname);
 
   // Creates an empty entry and sets the ID field to id.
-  void CreateEntry(const std::string& entryname, const int id);
+  void CreateEntry(const ModelType& model_type,
+                   const std::string& entryname,
+                   const int id);
 
-  void CreateEntry(const std::string& entryname, Id id);
+  void CreateEntry(const ModelType& model_type,
+                   const std::string& entryname,
+                   const Id& id);
+
+  void CreateEntryWithAttachmentMetadata(
+      const ModelType& model_type,
+      const std::string& entryname,
+      const Id& id,
+      const sync_pb::AttachmentMetadata& attachment_metadata);
+
+  void DeleteEntry(const Id& id);
 
   // When a directory is saved then loaded from disk, it will pass through
   // DropDeletedEntries().  This will remove some entries from the directory.
diff --git a/sync/syncable/entry_kernel.h b/sync/syncable/entry_kernel.h
index b6bc2ab..6380420 100644
--- a/sync/syncable/entry_kernel.h
+++ b/sync/syncable/entry_kernel.h
@@ -333,6 +333,10 @@
   inline UniquePosition& mutable_ref(UniquePositionField field) {
     return unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN];
   }
+  inline sync_pb::AttachmentMetadata& mutable_ref(
+      AttachmentMetadataField field) {
+    return attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN];
+  }
 
   ModelType GetModelType() const;
   ModelType GetServerModelType() const;
diff --git a/sync/syncable/mutable_entry.cc b/sync/syncable/mutable_entry.cc
index 863e65b..d9d5daa 100644
--- a/sync/syncable/mutable_entry.cc
+++ b/sync/syncable/mutable_entry.cc
@@ -233,6 +233,20 @@
   return true;
 }
 
+void MutableEntry::PutAttachmentMetadata(
+    const sync_pb::AttachmentMetadata& attachment_metadata) {
+  DCHECK(kernel_);
+  write_transaction()->TrackChangesTo(kernel_);
+  if (kernel_->ref(ATTACHMENT_METADATA).SerializeAsString() !=
+      attachment_metadata.SerializeAsString()) {
+    dir()->UpdateAttachmentIndex(GetMetahandle(),
+                                 kernel_->ref(ATTACHMENT_METADATA),
+                                 attachment_metadata);
+    kernel_->put(ATTACHMENT_METADATA, attachment_metadata);
+    kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles);
+  }
+}
+
 // This function sets only the flags needed to get this entry to sync.
 bool MarkForSyncing(MutableEntry* e) {
   DCHECK_NE(static_cast<MutableEntry*>(NULL), e);
diff --git a/sync/syncable/mutable_entry.h b/sync/syncable/mutable_entry.h
index 8c2f2ab..c064358 100644
--- a/sync/syncable/mutable_entry.h
+++ b/sync/syncable/mutable_entry.h
@@ -59,6 +59,9 @@
   // ID to put the node in first position.
   bool PutPredecessor(const Id& predecessor_id);
 
+  void PutAttachmentMetadata(
+      const sync_pb::AttachmentMetadata& attachment_metadata);
+
  private:
   // Kind of redundant. We should reduce the number of pointers
   // floating around if at all possible. Could we store this in Directory?
diff --git a/sync/test/fake_server/bookmark_entity.h b/sync/test/fake_server/bookmark_entity.h
index 8c68a81..3f108ba 100644
--- a/sync/test/fake_server/bookmark_entity.h
+++ b/sync/test/fake_server/bookmark_entity.h
@@ -36,13 +36,6 @@
       FakeServerEntity* current_server_entity,
       const std::string& parent_id);
 
-  // FakeServerEntity implementation.
-  virtual std::string GetParentId() const OVERRIDE;
-  virtual sync_pb::SyncEntity* SerializeAsProto() OVERRIDE;
-  virtual bool IsDeleted() const OVERRIDE;
-  virtual bool IsFolder() const OVERRIDE;
-
- private:
   BookmarkEntity(const std::string& id,
                  const syncer::ModelType& model_type,
                  int64 version,
@@ -56,6 +49,13 @@
                  int64 creation_time,
                  int64 last_modified_time);
 
+  // FakeServerEntity implementation.
+  virtual std::string GetParentId() const OVERRIDE;
+  virtual sync_pb::SyncEntity* SerializeAsProto() OVERRIDE;
+  virtual bool IsDeleted() const OVERRIDE;
+  virtual bool IsFolder() const OVERRIDE;
+
+ private:
   // All member values have equivalent fields in SyncEntity.
   std::string originator_cache_guid_;
   std::string originator_client_item_id_;
diff --git a/sync/test/fake_server/bookmark_entity_builder.cc b/sync/test/fake_server/bookmark_entity_builder.cc
new file mode 100644
index 0000000..04e7e97
--- /dev/null
+++ b/sync/test/fake_server/bookmark_entity_builder.cc
@@ -0,0 +1,85 @@
+// 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.
+
+#include "sync/test/fake_server/bookmark_entity_builder.h"
+
+#include <string>
+
+#include "base/guid.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
+#include "sync/internal_api/public/base/model_type.h"
+#include "sync/internal_api/public/base/unique_position.h"
+#include "sync/protocol/sync.pb.h"
+#include "sync/syncable/syncable_util.h"
+#include "sync/test/fake_server/bookmark_entity.h"
+#include "sync/test/fake_server/fake_server_entity.h"
+#include "sync/util/time.h"
+#include "url/gurl.h"
+
+using std::string;
+
+using syncer::ModelType;
+using syncer::syncable::GenerateSyncableBookmarkHash;
+
+// A version must be passed when creating a FakeServerEntity, but this value
+// is overrideen immediately when saving the entity in FakeServer.
+const int64 kUnusedVersion = 0L;
+
+// Default time (creation and last modified) used when creating entities.
+const int64 kDefaultTime = 1234L;
+
+namespace fake_server {
+
+BookmarkEntityBuilder::BookmarkEntityBuilder(
+    const string& title,
+    const GURL& url,
+    const string& originator_cache_guid,
+    const string& originator_client_item_id)
+    : EntityBuilder(syncer::BOOKMARKS, title),
+      url_(url),
+      originator_cache_guid_(originator_cache_guid),
+      originator_client_item_id_(originator_client_item_id) {
+}
+
+BookmarkEntityBuilder::~BookmarkEntityBuilder() {
+}
+
+scoped_ptr<FakeServerEntity> BookmarkEntityBuilder::Build() {
+  if (!url_.is_valid()) {
+    return make_scoped_ptr<FakeServerEntity>(NULL);
+  }
+
+  sync_pb::EntitySpecifics entity_specifics;
+  sync_pb::BookmarkSpecifics* bookmark_specifics =
+      entity_specifics.mutable_bookmark();
+  bookmark_specifics->set_title(name_);
+  bookmark_specifics->set_url(url_.spec());
+
+  sync_pb::UniquePosition unique_position;
+  // TODO(pvalenzuela): Allow caller customization of the position integer.
+  string suffix = GenerateSyncableBookmarkHash(originator_cache_guid_,
+                                               originator_client_item_id_);
+  syncer::UniquePosition::FromInt64(0, suffix).ToProto(&unique_position);
+
+  return make_scoped_ptr<FakeServerEntity>(
+      new BookmarkEntity(id_,
+                         model_type_,
+                         kUnusedVersion,
+                         name_,
+                         originator_cache_guid_,
+                         originator_client_item_id_,
+                         unique_position,
+                         entity_specifics,
+                         // TODO(pvalenzuela): Support bookmark folders.
+                         false,
+                         // TODO(pvalenzuela): Support caller specification of
+                         // the parent bookmark folder.
+                         FakeServerEntity::CreateId(syncer::BOOKMARKS,
+                                                    "bookmark_bar"),
+                         kDefaultTime,
+                         kDefaultTime));
+}
+
+}  // namespace fake_server
diff --git a/sync/test/fake_server/bookmark_entity_builder.h b/sync/test/fake_server/bookmark_entity_builder.h
new file mode 100644
index 0000000..e8275fa
--- /dev/null
+++ b/sync/test/fake_server/bookmark_entity_builder.h
@@ -0,0 +1,40 @@
+// 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.
+
+#ifndef SYNC_TEST_FAKE_SERVER_BOOKMARK_ENTITY_BUILDER_H_
+#define SYNC_TEST_FAKE_SERVER_BOOKMARK_ENTITY_BUILDER_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "sync/internal_api/public/base/model_type.h"
+#include "sync/test/fake_server/entity_builder.h"
+#include "sync/test/fake_server/fake_server_entity.h"
+#include "url/gurl.h"
+
+namespace fake_server {
+
+// Builder for BookmarkEntity objects.
+class BookmarkEntityBuilder : public EntityBuilder {
+ public:
+  explicit BookmarkEntityBuilder(const std::string& title,
+                                 const GURL& url,
+                                 const std::string& originator_cache_guid,
+                                 const std::string& originator_client_item_id);
+
+  virtual ~BookmarkEntityBuilder();
+
+  // EntityBuilder
+  virtual scoped_ptr<FakeServerEntity> Build() OVERRIDE;
+
+ private:
+  // The bookmark's URL.
+  GURL url_;
+  std::string originator_cache_guid_;
+  std::string originator_client_item_id_;
+};
+
+}  // namespace fake_server
+
+#endif  // SYNC_TEST_FAKE_SERVER_BOOKMARK_ENTITY_BUILDER_H_
diff --git a/sync/test/fake_server/entity_builder.cc b/sync/test/fake_server/entity_builder.cc
new file mode 100644
index 0000000..c5e2acf
--- /dev/null
+++ b/sync/test/fake_server/entity_builder.cc
@@ -0,0 +1,27 @@
+// 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.
+
+#include "sync/test/fake_server/entity_builder.h"
+
+#include <string>
+
+#include "base/guid.h"
+#include "sync/internal_api/public/base/model_type.h"
+
+using std::string;
+
+using syncer::ModelType;
+
+namespace fake_server {
+
+EntityBuilder::EntityBuilder(ModelType model_type, const string& name)
+    : id_(FakeServerEntity::CreateId(model_type, base::GenerateGUID())),
+      model_type_(model_type),
+      name_(name) {
+}
+
+EntityBuilder::~EntityBuilder() {
+}
+
+}  // namespace fake_server
diff --git a/sync/test/fake_server/entity_builder.h b/sync/test/fake_server/entity_builder.h
new file mode 100644
index 0000000..adb3d10
--- /dev/null
+++ b/sync/test/fake_server/entity_builder.h
@@ -0,0 +1,37 @@
+// 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.
+
+#ifndef SYNC_TEST_FAKE_SERVER_ENTITY_BUILDER_H_
+#define SYNC_TEST_FAKE_SERVER_ENTITY_BUILDER_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "sync/internal_api/public/base/model_type.h"
+#include "sync/test/fake_server/fake_server_entity.h"
+#include "url/gurl.h"
+
+namespace fake_server {
+
+// Parent class for FakeServerEntity builders.
+class EntityBuilder {
+ public:
+  virtual ~EntityBuilder();
+
+  // Builds a FakeServerEntity and returns a scoped_ptr tht owns it. If building
+  // was not successful, the returned scoped_ptr will not own a
+  // FakeServerEntity*.
+  virtual scoped_ptr<FakeServerEntity> Build() = 0;
+
+ protected:
+  EntityBuilder(syncer::ModelType model_type, const std::string& name);
+
+  std::string id_;
+  syncer::ModelType model_type_;
+  std::string name_;
+};
+
+}  // namespace fake_server
+
+#endif  // SYNC_TEST_FAKE_SERVER_ENTITY_BUILDER_H_
diff --git a/sync/test/fake_server/entity_builder_factory.cc b/sync/test/fake_server/entity_builder_factory.cc
new file mode 100644
index 0000000..a8f3d9e
--- /dev/null
+++ b/sync/test/fake_server/entity_builder_factory.cc
@@ -0,0 +1,39 @@
+// 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.
+
+#include "sync/test/fake_server/entity_builder_factory.h"
+
+#include <string>
+
+#include "base/guid.h"
+#include "base/strings/string_number_conversions.h"
+#include "sync/test/fake_server/bookmark_entity_builder.h"
+#include "url/gurl.h"
+
+using std::string;
+
+namespace fake_server {
+
+EntityBuilderFactory::EntityBuilderFactory()
+    : cache_guid_(base::GenerateGUID()), latest_client_item_id_(0L)  {
+}
+
+EntityBuilderFactory::EntityBuilderFactory(const string& cache_guid)
+    : cache_guid_(cache_guid), latest_client_item_id_(0L) {
+}
+
+EntityBuilderFactory::~EntityBuilderFactory() {
+}
+
+BookmarkEntityBuilder EntityBuilderFactory::NewBookmarkEntityBuilder(
+    const string& title, const GURL& url) {
+  --latest_client_item_id_;
+  BookmarkEntityBuilder builder(title,
+                                url,
+                                cache_guid_,
+                                base::Int64ToString(latest_client_item_id_));
+  return builder;
+}
+
+}  // namespace fake_server
diff --git a/sync/test/fake_server/entity_builder_factory.h b/sync/test/fake_server/entity_builder_factory.h
new file mode 100644
index 0000000..f3b36f7
--- /dev/null
+++ b/sync/test/fake_server/entity_builder_factory.h
@@ -0,0 +1,37 @@
+// 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.
+
+#ifndef SYNC_TEST_FAKE_SERVER_ENTITY_BUILDER_FACTORY_H_
+#define SYNC_TEST_FAKE_SERVER_ENTITY_BUILDER_FACTORY_H_
+
+#include <string>
+
+#include "sync/test/fake_server/bookmark_entity_builder.h"
+#include "url/gurl.h"
+
+namespace fake_server {
+
+// Creates various types of EntityBuilders.
+//
+// add comment of why this class exists
+class EntityBuilderFactory {
+ public:
+  EntityBuilderFactory();
+  EntityBuilderFactory(const std::string& cache_guid);
+  virtual ~EntityBuilderFactory();
+
+  BookmarkEntityBuilder NewBookmarkEntityBuilder(const std::string& title,
+                                                 const GURL& url);
+ private:
+  // An identifier used when creating entities. This value is used similarly to
+  // the value in the Sync directory code.
+  std::string cache_guid_;
+
+  // The latest client item id assigned to an entity.
+  int64 latest_client_item_id_;
+};
+
+}  // namespace fake_server
+
+#endif  // SYNC_TEST_FAKE_SERVER_ENTITY_BUILDER_FACTORY_H_
diff --git a/sync/test/fake_server/fake_server.cc b/sync/test/fake_server/fake_server.cc
index d758e5d..44bce54 100644
--- a/sync/test/fake_server/fake_server.cc
+++ b/sync/test/fake_server/fake_server.cc
@@ -4,6 +4,7 @@
 
 #include "sync/test/fake_server/fake_server.h"
 
+#include <algorithm>
 #include <limits>
 #include <string>
 #include <vector>
@@ -29,7 +30,6 @@
 using std::string;
 using std::vector;
 
-using base::AutoLock;
 using syncer::GetModelType;
 using syncer::ModelType;
 using syncer::ModelTypeSet;
@@ -97,21 +97,6 @@
     return min_version_;
   }
 
-  // Returns the data type IDs of types being synced for the first time.
-  vector<ModelType> GetFirstTimeTypes(
-      ModelTypeSet created_permanent_entity_types) const {
-    vector<ModelType> types;
-
-    ModelTypeToVersionMap::const_iterator it;
-    for (it = request_from_version_.begin(); it != request_from_version_.end();
-         ++it) {
-      if (it->second == 0 && !created_permanent_entity_types.Has(it->first))
-        types.push_back(it->first);
-    }
-
-    return types;
-  }
-
  private:
   typedef std::map<ModelType, int64> ModelTypeToVersionMap;
 
@@ -162,26 +147,17 @@
 
 FakeServer::FakeServer() : version_(0), birthday_(kDefaultBirthday) {
   keystore_keys_.push_back(kDefaultKeystoreKey);
+  CHECK(CreateDefaultPermanentItems());
 }
 
 FakeServer::~FakeServer() {
   STLDeleteContainerPairSecondPointers(entities_.begin(), entities_.end());
 }
 
-bool FakeServer::CreateDefaultPermanentItems(
-    const vector<ModelType>& first_time_types) {
-  for (vector<ModelType>::const_iterator it = first_time_types.begin();
-       it != first_time_types.end(); ++it) {
-    if (!ModelTypeSet::All().Has(*it)) {
-      NOTREACHED() << "An unexpected ModelType was encountered.";
-    }
-
-    ModelType model_type = *it;
-    if (created_permanent_entity_types_.Has(model_type)) {
-      // Do not create an entity for the type if it has already been created.
-      continue;
-    }
-
+bool FakeServer::CreateDefaultPermanentItems() {
+  ModelTypeSet all_types = syncer::ProtocolTypes();
+  for (ModelTypeSet::Iterator it = all_types.First(); it.Good(); it.Inc()) {
+    ModelType model_type = it.Get();
     FakeServerEntity* top_level_entity =
         PermanentEntity::CreateTopLevel(model_type);
     if (top_level_entity == NULL) {
@@ -210,8 +186,6 @@
       }
       SaveEntity(other_bookmarks_entity);
     }
-
-    created_permanent_entity_types_.Put(model_type);
   }
 
   return true;
@@ -238,11 +212,8 @@
   entities_[entity->GetId()] = entity;
 }
 
-int FakeServer::HandleCommand(const string& request,
-                              int* response_code,
-                              string* response) {
-  AutoLock lock(lock_);
-
+void FakeServer::HandleCommand(const string& request,
+                               const HandleCommandCallback& callback) {
   sync_pb::ClientToServerMessage message;
   bool parsed = message.ParseFromString(request);
   DCHECK(parsed);
@@ -259,20 +230,20 @@
                                     response_proto.mutable_commit());
       break;
     default:
-      return net::ERR_NOT_IMPLEMENTED;
+      callback.Run(net::ERR_NOT_IMPLEMENTED, 0, string());;
+      return;
   }
 
   if (!success) {
     // TODO(pvalenzuela): Add logging here so that tests have more info about
     // the failure.
-    return net::HTTP_BAD_REQUEST;
+    callback.Run(net::ERR_FAILED, 0, string());
+    return;
   }
 
   response_proto.set_error_code(sync_pb::SyncEnums::SUCCESS);
   response_proto.set_store_birthday(birthday_);
-  *response_code = net::HTTP_OK;
-  *response = response_proto.SerializeAsString();
-  return 0;
+  callback.Run(0, net::HTTP_OK, response_proto.SerializeAsString());
 }
 
 bool FakeServer::HandleGetUpdatesRequest(
@@ -283,11 +254,7 @@
   response->set_changes_remaining(0);
 
   scoped_ptr<UpdateSieve> sieve = UpdateSieve::Create(get_updates);
-  vector<ModelType> first_time_types = sieve->GetFirstTimeTypes(
-      created_permanent_entity_types_);
-  if (!CreateDefaultPermanentItems(first_time_types)) {
-    return false;
-  }
+
   if (get_updates.create_mobile_bookmarks_folder() &&
       !CreateMobileBookmarksPermanentItem()) {
     return false;
@@ -324,13 +291,13 @@
   return true;
 }
 
-bool FakeServer::CommitEntity(
+string FakeServer::CommitEntity(
     const sync_pb::SyncEntity& client_entity,
     sync_pb::CommitResponse_EntryResponse* entry_response,
     string client_guid,
-    std::map<string, string>* client_to_server_ids) {
+    string parent_id) {
   if (client_entity.version() == 0 && client_entity.deleted()) {
-    return false;
+    return string();
   }
 
   FakeServerEntity* entity;
@@ -339,7 +306,7 @@
     // TODO(pvalenzuela): Change the behavior of DeleteChilden so that it does
     // not modify server data if it fails.
     if (!DeleteChildren(client_entity.id_string())) {
-      return false;
+      return string();
     }
   } else if (GetModelType(client_entity) == syncer::NIGORI) {
     // NIGORI is the only permanent item type that should be updated by the
@@ -356,11 +323,6 @@
       entity = UniqueClientEntity::CreateNew(client_entity);
     }
   } else {
-    string parent_id = client_entity.parent_id_string();
-    if (client_to_server_ids->find(parent_id) !=
-        client_to_server_ids->end()) {
-      parent_id = (*client_to_server_ids)[parent_id];
-    }
     // TODO(pvalenzuela): Validate entity's parent ID.
     if (entities_.find(client_entity.id_string()) != entities_.end()) {
       entity = BookmarkEntity::CreateUpdatedVersion(
@@ -375,17 +337,12 @@
   if (entity == NULL) {
     // TODO(pvalenzuela): Add logging so that it is easier to determine why
     // creation failed.
-    return false;
-  }
-
-  // Record the ID if it was renamed.
-  if (client_entity.id_string() != entity->GetId()) {
-    (*client_to_server_ids)[client_entity.id_string()] = entity->GetId();
+    return string();
   }
 
   SaveEntity(entity);
   BuildEntryResponseForSuccessfulCommit(entry_response, entity);
-  return true;
+  return entity->GetId();
 }
 
 void FakeServer::BuildEntryResponseForSuccessfulCommit(
@@ -442,6 +399,7 @@
     sync_pb::CommitResponse* response) {
   std::map<string, string> client_to_server_ids;
   string guid = commit.cache_guid();
+  ModelTypeSet committed_model_types;
 
   // TODO(pvalenzuela): Add validation of CommitMessage.entries.
   ::google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>::const_iterator it;
@@ -449,11 +407,30 @@
     sync_pb::CommitResponse_EntryResponse* entry_response =
         response->add_entryresponse();
 
-    if (!CommitEntity(*it, entry_response, guid, &client_to_server_ids)) {
+    sync_pb::SyncEntity client_entity = *it;
+    string parent_id = client_entity.parent_id_string();
+    if (client_to_server_ids.find(parent_id) !=
+        client_to_server_ids.end()) {
+      parent_id = client_to_server_ids[parent_id];
+    }
+
+    string entity_id = CommitEntity(client_entity,
+                                    entry_response,
+                                    guid,
+                                    parent_id);
+    if (entity_id.empty()) {
       return false;
     }
+
+    // Record the ID if it was renamed.
+    if (entity_id != client_entity.id_string()) {
+      client_to_server_ids[client_entity.id_string()] = entity_id;
+    }
+    FakeServerEntity* entity = entities_[entity_id];
+    committed_model_types.Put(entity->GetModelType());
   }
 
+  FOR_EACH_OBSERVER(Observer, observers_, OnCommit(committed_model_types));
   return true;
 }
 
@@ -489,4 +466,16 @@
   return dictionary.Pass();
 }
 
+void FakeServer::InjectEntity(scoped_ptr<FakeServerEntity> entity) {
+  SaveEntity(entity.release());
+}
+
+void FakeServer::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void FakeServer::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
 }  // namespace fake_server
diff --git a/sync/test/fake_server/fake_server.h b/sync/test/fake_server/fake_server.h
index 0621bbc..8bb2c08 100644
--- a/sync/test/fake_server/fake_server.h
+++ b/sync/test/fake_server/fake_server.h
@@ -7,10 +7,12 @@
 
 #include <map>
 #include <string>
+#include <vector>
 
 #include "base/basictypes.h"
+#include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/synchronization/lock.h"
+#include "base/observer_list.h"
 #include "base/values.h"
 #include "sync/internal_api/public/base/model_type.h"
 #include "sync/protocol/sync.pb.h"
@@ -21,15 +23,26 @@
 // A fake version of the Sync server used for testing.
 class FakeServer {
  public:
+  typedef base::Callback<void(int, int, const std::string&)>
+      HandleCommandCallback;
+
+  class Observer {
+   public:
+    virtual ~Observer() {}
+
+    // Called after FakeServer has processed a successful commit. The types
+    // updated as part of the commit are passed in |committed_model_types|.
+    virtual void OnCommit(syncer::ModelTypeSet committed_model_types) = 0;
+  };
+
   FakeServer();
   virtual ~FakeServer();
 
-  // Handles a /command POST to the server. If the return value is 0 (success),
-  // |response_code| and |response| will be set. Otherwise, the return value
-  // will be a network error code.
-  int HandleCommand(const std::string& request,
-                    int* response_code,
-                    std::string* response);
+  // Asynchronously handles a /command POST to the server. If the error_code is
+  // passed to |callback| is 0 (success), the POST's response code and content
+  // will also be passed.
+  void HandleCommand(const std::string& request,
+                     const HandleCommandCallback& callback);
 
   // Creates a DicionaryValue representation of all entities present in the
   // server. The dictionary keys are the strings generated by ModelTypeToString
@@ -37,6 +50,19 @@
   // names.
   scoped_ptr<base::DictionaryValue> GetEntitiesAsDictionaryValue();
 
+  // Adds the FakeServerEntity* owned by |entity| to the server's collection
+  // of entities. This method makes no guarantees that the added entity will
+  // result in successful server operations.
+  void InjectEntity(scoped_ptr<FakeServerEntity> entity);
+
+  // Adds |observer| to FakeServer's observer list. This should be called
+  // before the Profile associated with |observer| is connected to the server.
+  void AddObserver(Observer* observer);
+
+  // Removes |observer| from the FakeServer's observer list. This method
+  // must be called if AddObserver was ever called with |observer|.
+  void RemoveObserver(Observer* observer);
+
  private:
   typedef std::map<std::string, FakeServerEntity*> EntityMap;
 
@@ -48,9 +74,8 @@
   bool HandleCommitRequest(const sync_pb::CommitMessage& commit,
                            sync_pb::CommitResponse* response);
 
-  // Inserts the appropriate permanent items in |entities_|.
-  bool CreateDefaultPermanentItems(
-      const std::vector<syncer::ModelType>& first_time_types);
+  // Inserts the default permanent items in |entities_|.
+  bool CreateDefaultPermanentItems();
 
   // Inserts the mobile bookmarks folder entity in |entities_|.
   bool CreateMobileBookmarksPermanentItem();
@@ -59,14 +84,15 @@
   void SaveEntity(FakeServerEntity* entity);
 
   // Commits a client-side SyncEntity to the server as a FakeServerEntity.
-  // The client that sent the commit is identified via |client_guid| and all
-  // entity ID renaming is tracked with |client_to_server_ids|. If the commit
-  // is successful, true is returned and the server's version of the SyncEntity
-  // is stored in |server_entity|.
-  bool CommitEntity(const sync_pb::SyncEntity& client_entity,
-                    sync_pb::CommitResponse_EntryResponse* entry_response,
-                    std::string client_guid,
-                    std::map<std::string, std::string>* client_to_server_ids);
+  // The client that sent the commit is identified via |client_guid|. The
+  // parent ID string present in |client_entity| should be ignored in favor
+  // of |parent_id|. If the commit is successful, the entity's server ID string
+  // is returned and a new FakeServerEntity is saved in |entities_|.
+  std::string CommitEntity(
+      const sync_pb::SyncEntity& client_entity,
+      sync_pb::CommitResponse_EntryResponse* entry_response,
+      std::string client_guid,
+      std::string parent_id);
 
   // Populates |entry_response| based on |entity|. It is assumed that
   // SaveEntity has already been called on |entity|.
@@ -82,14 +108,6 @@
   // |id|. A tombstone is not created for the entity itself.
   bool DeleteChildren(const std::string& id);
 
-  // The lock used to ensure that only one client is communicating with server
-  // at any given time.
-  //
-  // It is probably preferable to have FakeServer operate on its own thread and
-  // communicate with it via PostTask, but clients would still need to wait for
-  // requests to finish before proceeding.
-  base::Lock lock_;
-
   // This is the last version number assigned to an entity. The next entity will
   // have a version number of version_ + 1.
   int64 version_;
@@ -104,10 +122,8 @@
   // All Keystore keys known to the server.
   std::vector<std::string> keystore_keys_;
 
-  // All ModelTypes for which permanent entities have been created. These types
-  // are kept track of so that permanent entities are not recreated for new
-  // clients.
-  syncer::ModelTypeSet created_permanent_entity_types_;
+  // FakeServer's observers.
+  ObserverList<Observer, true> observers_;
 };
 
 }  // namespace fake_server
diff --git a/sync/test/fake_server/fake_server_entity.h b/sync/test/fake_server/fake_server_entity.h
index dd2cc75..7f30bb0 100644
--- a/sync/test/fake_server/fake_server_entity.h
+++ b/sync/test/fake_server/fake_server_entity.h
@@ -17,6 +17,15 @@
 // The representation of a Sync entity for the fake server.
 class FakeServerEntity {
  public:
+  // Creates an ID of the form <type><separator><inner-id> where
+  // <type> is the EntitySpecifics field number for |model_type|, <separator>
+  // is kIdSeparator, and <inner-id> is |inner_id|.
+  //
+  // If |inner_id| is globally unique, then the returned ID will also be
+  // globally unique.
+  static std::string CreateId(const syncer::ModelType& model_type,
+                              const std::string& inner_id);
+
   virtual ~FakeServerEntity();
   const std::string& GetId() const;
   syncer::ModelType GetModelType() const;
@@ -31,15 +40,6 @@
   virtual bool IsFolder() const = 0;
 
  protected:
-  // Creates an ID of the form <type><separator><inner-id> where
-  // <type> is the EntitySpecifics field number for |model_type|, <separator>
-  // is kIdSeparator, and <inner-id> is |inner_id|.
-  //
-  // If |inner_id| is globally unique, then the returned ID will also be
-  // globally unique.
-  static std::string CreateId(const syncer::ModelType& model_type,
-                              const std::string& inner_id);
-
   // Extracts the ModelType from |id|. If |id| is malformed or does not contain
   // a valid ModelType, UNSPECIFIED is returned.
   static syncer::ModelType GetModelTypeFromId(const std::string& id);
diff --git a/sync/test/fake_server/fake_server_http_post_provider.cc b/sync/test/fake_server/fake_server_http_post_provider.cc
index e0b3436..fbfe16f 100644
--- a/sync/test/fake_server/fake_server_http_post_provider.cc
+++ b/sync/test/fake_server/fake_server_http_post_provider.cc
@@ -6,6 +6,11 @@
 
 #include <string>
 
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner.h"
+#include "base/synchronization/waitable_event.h"
 #include "sync/test/fake_server/fake_server.h"
 
 using syncer::HttpPostProviderInterface;
@@ -13,7 +18,9 @@
 namespace fake_server {
 
 FakeServerHttpPostProviderFactory::FakeServerHttpPostProviderFactory(
-    FakeServer* fake_server) : fake_server_(fake_server) { }
+    FakeServer* fake_server,
+    scoped_refptr<base::SequencedTaskRunner> task_runner)
+        : fake_server_(fake_server), task_runner_(task_runner) { }
 
 FakeServerHttpPostProviderFactory::~FakeServerHttpPostProviderFactory() { }
 
@@ -21,7 +28,7 @@
 
 HttpPostProviderInterface* FakeServerHttpPostProviderFactory::Create() {
   FakeServerHttpPostProvider* http =
-      new FakeServerHttpPostProvider(fake_server_);
+      new FakeServerHttpPostProvider(fake_server_, task_runner_);
   http->AddRef();
   return http;
 }
@@ -32,7 +39,11 @@
 }
 
 FakeServerHttpPostProvider::FakeServerHttpPostProvider(
-    FakeServer* fake_server) : fake_server_(fake_server) { }
+    FakeServer* fake_server,
+    scoped_refptr<base::SequencedTaskRunner> task_runner)
+        : fake_server_(fake_server),
+          task_runner_(task_runner),
+          post_complete_(false, false) { }
 
 FakeServerHttpPostProvider::~FakeServerHttpPostProvider() { }
 
@@ -54,13 +65,29 @@
   request_content_.assign(content, content_length);
 }
 
+void FakeServerHttpPostProvider::OnPostComplete(int error_code,
+                                                int response_code,
+                                                const std::string& response) {
+  post_error_code_ = error_code;
+  post_response_code_ = response_code;
+  response_ = response;
+  post_complete_.Signal();
+}
+
 bool FakeServerHttpPostProvider::MakeSynchronousPost(int* error_code,
                                                      int* response_code) {
-  // This assumes that a POST is being made to /command.
-  *error_code = fake_server_->HandleCommand(request_content_,
-                                            response_code,
-                                            &response_);
-  return (*error_code == 0);
+  // It is assumed that a POST is being made to /command.
+  FakeServer::HandleCommandCallback callback = base::Bind(
+      &FakeServerHttpPostProvider::OnPostComplete, base::Unretained(this));
+  task_runner_->PostNonNestableTask(FROM_HERE,
+                                    base::Bind(&FakeServer::HandleCommand,
+                                               base::Unretained(fake_server_),
+                                               base::ConstRef(request_content_),
+                                               base::ConstRef(callback)));
+  post_complete_.Wait();
+  *error_code = post_error_code_;
+  *response_code = post_response_code_;
+  return *error_code == 0;
 }
 
 int FakeServerHttpPostProvider::GetResponseContentLength() const {
diff --git a/sync/test/fake_server/fake_server_http_post_provider.h b/sync/test/fake_server/fake_server_http_post_provider.h
index 63f1eda..9e2aa0e 100644
--- a/sync/test/fake_server/fake_server_http_post_provider.h
+++ b/sync/test/fake_server/fake_server_http_post_provider.h
@@ -8,6 +8,8 @@
 #include <string>
 
 #include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner.h"
+#include "base/synchronization/waitable_event.h"
 #include "sync/internal_api/public/http_post_provider_factory.h"
 #include "sync/internal_api/public/http_post_provider_interface.h"
 
@@ -19,7 +21,9 @@
     : public syncer::HttpPostProviderInterface,
       public base::RefCountedThreadSafe<FakeServerHttpPostProvider> {
  public:
-  explicit FakeServerHttpPostProvider(FakeServer* fake_server);
+  explicit FakeServerHttpPostProvider(
+      FakeServer* fake_server,
+      scoped_refptr<base::SequencedTaskRunner> task_runner);
 
   // HttpPostProviderInterface implementation.
   virtual void SetExtraRequestHeaders(const char* headers) OVERRIDE;
@@ -39,13 +43,22 @@
   virtual ~FakeServerHttpPostProvider();
 
  private:
+  void OnPostComplete(int error_code,
+                      int response_code,
+                      const std::string& response);
+
   FakeServer* const fake_server_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
   std::string response_;
   std::string request_url_;
   int request_port_;
   std::string request_content_;
   std::string request_content_type_;
   std::string extra_request_headers_;
+  int post_error_code_;
+  int post_response_code_;
+  base::WaitableEvent post_complete_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeServerHttpPostProvider);
 };
@@ -53,7 +66,9 @@
 class FakeServerHttpPostProviderFactory
     : public syncer::HttpPostProviderFactory {
  public:
-  explicit FakeServerHttpPostProviderFactory(FakeServer* fake_server);
+  explicit FakeServerHttpPostProviderFactory(
+      FakeServer* fake_server,
+      scoped_refptr<base::SequencedTaskRunner> task_runner);
   virtual ~FakeServerHttpPostProviderFactory();
 
   // HttpPostProviderFactory:
@@ -63,6 +78,7 @@
 
  private:
   FakeServer* const fake_server_;
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeServerHttpPostProviderFactory);
 };
diff --git a/sync/test/fake_server/fake_server_network_resources.cc b/sync/test/fake_server/fake_server_network_resources.cc
index 56d5ea2..c3bedb0 100644
--- a/sync/test/fake_server/fake_server_network_resources.cc
+++ b/sync/test/fake_server/fake_server_network_resources.cc
@@ -5,6 +5,7 @@
 #include "sync/test/fake_server/fake_server_network_resources.h"
 
 #include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
 #include "sync/internal_api/public/base/cancelation_signal.h"
 #include "sync/internal_api/public/http_post_provider_factory.h"
 #include "sync/internal_api/public/network_time_update_callback.h"
@@ -28,7 +29,9 @@
         const NetworkTimeUpdateCallback& network_time_update_callback,
         CancelationSignal* cancelation_signal) {
   return make_scoped_ptr<syncer::HttpPostProviderFactory>(
-      new FakeServerHttpPostProviderFactory(fake_server_));
+      new FakeServerHttpPostProviderFactory(
+          fake_server_,
+          base::MessageLoop::current()->message_loop_proxy()));
 }
 
 }  // namespace fake_server
diff --git a/sync/test/fake_server/fake_sync_server_http_handler.cc b/sync/test/fake_server/fake_sync_server_http_handler.cc
deleted file mode 100644
index 4438e4d..0000000
--- a/sync/test/fake_server/fake_sync_server_http_handler.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// 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.
-
-#include <iostream>
-
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_errors.h"
-#include "net/server/http_server_request_info.h"
-#include "net/server/http_server_response_info.h"
-#include "net/socket/tcp_listen_socket.h"
-#include "sync/test/fake_server/fake_sync_server_http_handler.h"
-
-namespace fake_server {
-
-FakeSyncServerHttpHandler::FakeSyncServerHttpHandler() : requested_port_(0) {}
-
-FakeSyncServerHttpHandler::FakeSyncServerHttpHandler(int port)
-    : requested_port_(port) {}
-
-FakeSyncServerHttpHandler::~FakeSyncServerHttpHandler() {}
-
-// Note that this must be called from within an IO MessageLoop because it
-// initializes a net::HttpServer.
-void FakeSyncServerHttpHandler::Start() {
-  VLOG(1) << "Starting web server";
-  net::TCPListenSocketFactory factory("0.0.0.0", requested_port_);
-  server_ = new net::HttpServer(factory, this);
-  net::IPEndPoint address;
-  int error = server_->GetLocalAddress(&address);
-  CHECK_EQ(net::OK, error) << base::StringPrintf(
-        "Error %d while trying to choose a port: %s",
-        error,
-        net::ErrorToString(error));
-
-  LOG(INFO) << base::StringPrintf("Listening on port %d", address.port());
-}
-
-void FakeSyncServerHttpHandler::OnHttpRequest(
-    int connection_id,
-    const net::HttpServerRequestInfo& info) {
-
-  // Hand http requests over to the sync FakeServer implementation to process
-  VLOG(1) << "Request path: " << info.path;
-  int response_code = -1;
-  std::string response;
-  int server_return_value = fake_sync_server_.HandleCommand(info.data,
-                                                            &response_code,
-                                                            &response);
-  if (server_return_value == 0) {
-    // A '0' error code indicates a successful request to FakeServer
-    server_->Send(connection_id, net::HttpStatusCode(response_code),
-                  response, "text/html");
-    VLOG(1) << "Sync response sent: " << response;
-  } else {
-    // The FakeServer returned a non-0 error code.
-    std::string error_message = base::StringPrintf(
-        "Error processing sync request: error code %d. (%s)",
-        server_return_value,
-        net::ErrorToString(server_return_value));
-    server_->Send500(connection_id, error_message);
-    LOG(ERROR) << error_message;
-  }
-}
-
-void FakeSyncServerHttpHandler::OnWebSocketRequest(
-      int connection_id,
-      const net::HttpServerRequestInfo& info) {}
-
-void FakeSyncServerHttpHandler::OnWebSocketMessage(int connection_id,
-                                  const std::string& data) {}
-
-void FakeSyncServerHttpHandler::OnClose(int connection_id) {}
-
-} // namespace fake_server
diff --git a/sync/test/fake_server/fake_sync_server_http_handler.h b/sync/test/fake_server/fake_sync_server_http_handler.h
deleted file mode 100644
index ef5ecb5..0000000
--- a/sync/test/fake_server/fake_sync_server_http_handler.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// 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.
-
-#ifndef SYNC_TEST_FAKE_SERVER_FAKE_SERVER_HTTP_HANDLER_H_
-#define SYNC_TEST_FAKE_SERVER_FAKE_SERVER_HTTP_HANDLER_H_
-
-#include "net/server/http_server.h"
-#include "sync/test/fake_server/fake_server.h"
-
-namespace fake_server {
-
-// An HTTP server that forwards requests to FakeServer, providing a quick way
-// to test Sync client code.
-class FakeSyncServerHttpHandler : public net::HttpServer::Delegate {
- public:
-  // Creates a fake sync server that listens on an available port.
-  FakeSyncServerHttpHandler();
-
-  // Creates a fake sync server that listens on a specified port.
-  explicit FakeSyncServerHttpHandler(int port);
-
-  virtual ~FakeSyncServerHttpHandler();
-
-  // Begin accepting HTTP requests. Must be called from an IO MessageLoop.
-  void Start();
-
-  // Overridden from net::HttpServer::Delegate.
-  // HTTP requests are processed and WebSocket requests are currently
-  // unimplemented.
-  virtual void OnHttpRequest(int connection_id,
-                             const net::HttpServerRequestInfo& info) OVERRIDE;
-  virtual void OnWebSocketRequest(
-      int connection_id,
-      const net::HttpServerRequestInfo& info) OVERRIDE;
-
-  virtual void OnWebSocketMessage(int connection_id,
-                                  const std::string& data) OVERRIDE;
-
-  virtual void OnClose(int connection_id) OVERRIDE;
-
- private:
-  int requested_port_;
-
-  scoped_refptr<net::HttpServer> server_;
-
-  fake_server::FakeServer fake_sync_server_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeSyncServerHttpHandler);
-};
-
-}  // namespace fake_server
-
-#endif  // SYNC_TEST_FAKE_SERVER_FAKE_SERVER_HTTP_HANDLER_H_
diff --git a/sync/test/fake_server/run_sync_fake_server.cc b/sync/test/fake_server/run_sync_fake_server.cc
deleted file mode 100644
index 9ded029..0000000
--- a/sync/test/fake_server/run_sync_fake_server.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-#include <iostream>
-
-#include "base/at_exit.h"
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "base/strings/string_number_conversions.h"
-#include "sync/test/fake_server/fake_sync_server_http_handler.h"
-
-const char kPortNumberSwitch[] = "port";
-
-// This runs a FakeSyncServerHttpHandler as a command-line app.
-int main(int argc, char* argv[]) {
-  using fake_server::FakeSyncServerHttpHandler;
-
-  CommandLine::Init(argc, argv);
-  CommandLine* command_line = CommandLine::ForCurrentProcess();
-  logging::LoggingSettings settings;
-  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
-  logging::InitLogging(settings);
-
-  FakeSyncServerHttpHandler* server;
-
-  // Check if a port was specified on the command line
-  if (command_line->HasSwitch(kPortNumberSwitch)) {
-    std::string requested_port =
-        command_line->GetSwitchValueASCII(kPortNumberSwitch);
-    int port;
-    if (!base::StringToInt(requested_port, &port)) {
-      LOG(ERROR) << "Invalid --" << kPortNumberSwitch << " specified: \""
-                 << requested_port << "\"";
-      return -1;
-    }
-
-    server = new FakeSyncServerHttpHandler(port);
-  } else {
-    LOG(INFO) << "Selecting an avilable port. Pass --" << kPortNumberSwitch
-              << "=<port number> to specify your own.";
-    server = new FakeSyncServerHttpHandler();
-  }
-
-  base::WeakPtrFactory<FakeSyncServerHttpHandler> server_ptr_factory(server);
-
-  // An HttpServer must be run on a IO MessageLoop.
-  base::AtExitManager exit_manager; // Debug builds demand that ExitManager
-                                    // be initialized before MessageLoop.
-  base::MessageLoop message_loop(base::MessageLoop::TYPE_IO);
-  bool posted = message_loop.current()->message_loop_proxy()->PostTask(
-      FROM_HERE,
-      base::Bind(&FakeSyncServerHttpHandler::Start,
-                 server_ptr_factory.GetWeakPtr()));
-  CHECK(posted) << "Failed to start the HTTP server. PostTask returned false.";
-  message_loop.current()->Run();
-
-  return 0;
-}
diff --git a/sync/util/cryptographer_unittest.cc b/sync/util/cryptographer_unittest.cc
index c045064..3719db3 100644
--- a/sync/util/cryptographer_unittest.cc
+++ b/sync/util/cryptographer_unittest.cc
@@ -189,7 +189,7 @@
 
   std::string token;
   EXPECT_TRUE(cryptographer_.GetBootstrapToken(&token));
-  EXPECT_TRUE(IsStringUTF8(token));
+  EXPECT_TRUE(base::IsStringUTF8(token));
 
   Cryptographer other_cryptographer(&encryptor_);
   other_cryptographer.Bootstrap(token);
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index e9797eb..b6575d5 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -32,7 +32,8 @@
       "ipc_tests",
       "sync_unit_tests",
       "unit_tests",
-      "sql_unittests"
+      "sql_unittests",
+      "nacl_loader_unittests"
     ]
   },
   "Linux ChromiumOS Tests (2)": {
@@ -75,7 +76,8 @@
       "ipc_tests",
       "sync_unit_tests",
       "unit_tests",
-      "sql_unittests"
+      "sql_unittests",
+      "nacl_loader_unittests"
     ]
   },
   "Linux ChromiumOS Tests (dbg)(2)": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
new file mode 100644
index 0000000..99a9438
--- /dev/null
+++ b/testing/buildbot/chromium.fyi.json
@@ -0,0 +1,206 @@
+{
+  "Linux Trusty": {
+    "gtest_tests": [
+      "app_list_unittests",
+      "aura_unittests",
+      "interactive_ui_tests",
+      "base_unittests",
+      "cacheinvalidation_unittests",
+      "cast_unittests",
+      "cc_unittests",
+      "chromedriver_unittests",
+      "components_unittests",
+      "compositor_unittests",
+      "crypto_unittests",
+      "dbus_unittests",
+      "gcm_unit_tests",
+      "gfx_unittests",
+      "google_apis_unittests",
+      "gpu_unittests",
+      "url_unittests",
+      "jingle_unittests",
+      "content_unittests",
+      "device_unittests",
+      "events_unittests",
+      "media_unittests",
+      "net_unittests",
+      "ppapi_unittests",
+      "printing_unittests",
+      "remoting_unittests",
+      "sandbox_linux_unittests",
+      "ui_unittests",
+      "ipc_tests",
+      "sync_unit_tests",
+      "unit_tests",
+      "views_unittests",
+      "wm_unittests",
+      "sql_unittests",
+      "browser_tests",
+      "content_browsertests",
+      "webkit_compositor_bindings_unittests",
+      "mojo_apps_js_unittests",
+      "mojo_common_unittests",
+      "mojo_js_unittests",
+      "mojo_public_bindings_unittests",
+      "mojo_public_environment_unittests",
+      "mojo_public_system_unittests",
+      "mojo_public_utility_unittests",
+      "mojo_service_manager_unittests",
+      "mojo_system_unittests",
+      "nacl_loader_unittests"
+    ]
+  },
+  "Linux Trusty (dbg)": {
+    "gtest_tests": [
+      "app_list_unittests",
+      "aura_unittests",
+      "interactive_ui_tests",
+      "base_unittests",
+      "cacheinvalidation_unittests",
+      "cast_unittests",
+      "cc_unittests",
+      "chromedriver_unittests",
+      "components_unittests",
+      "compositor_unittests",
+      "crypto_unittests",
+      "dbus_unittests",
+      "gcm_unit_tests",
+      "gfx_unittests",
+      "google_apis_unittests",
+      "gpu_unittests",
+      "url_unittests",
+      "jingle_unittests",
+      "content_unittests",
+      "device_unittests",
+      "events_unittests",
+      "media_unittests",
+      "net_unittests",
+      "ppapi_unittests",
+      "printing_unittests",
+      "remoting_unittests",
+      "sandbox_linux_unittests",
+      "ui_unittests",
+      "ipc_tests",
+      "sync_unit_tests",
+      "unit_tests",
+      "views_unittests",
+      "wm_unittests",
+      "sql_unittests",
+      "browser_tests",
+      "content_browsertests",
+      "webkit_compositor_bindings_unittests",
+      "mojo_apps_js_unittests",
+      "mojo_common_unittests",
+      "mojo_js_unittests",
+      "mojo_public_bindings_unittests",
+      "mojo_public_environment_unittests",
+      "mojo_public_system_unittests",
+      "mojo_public_utility_unittests",
+      "mojo_service_manager_unittests",
+      "mojo_system_unittests",
+      "nacl_loader_unittests"
+    ]
+  },
+  "Linux Trusty (32)": {
+    "gtest_tests": [
+      "app_list_unittests",
+      "aura_unittests",
+      "interactive_ui_tests",
+      "base_unittests",
+      "cacheinvalidation_unittests",
+      "cast_unittests",
+      "cc_unittests",
+      "chromedriver_unittests",
+      "components_unittests",
+      "compositor_unittests",
+      "crypto_unittests",
+      "dbus_unittests",
+      "gcm_unit_tests",
+      "gfx_unittests",
+      "google_apis_unittests",
+      "gpu_unittests",
+      "url_unittests",
+      "jingle_unittests",
+      "content_unittests",
+      "device_unittests",
+      "events_unittests",
+      "media_unittests",
+      "net_unittests",
+      "ppapi_unittests",
+      "printing_unittests",
+      "remoting_unittests",
+      "sandbox_linux_unittests",
+      "ui_unittests",
+      "ipc_tests",
+      "sync_unit_tests",
+      "unit_tests",
+      "views_unittests",
+      "wm_unittests",
+      "sql_unittests",
+      "browser_tests",
+      "content_browsertests",
+      "webkit_compositor_bindings_unittests",
+      "mojo_apps_js_unittests",
+      "mojo_common_unittests",
+      "mojo_js_unittests",
+      "mojo_public_bindings_unittests",
+      "mojo_public_environment_unittests",
+      "mojo_public_system_unittests",
+      "mojo_public_utility_unittests",
+      "mojo_service_manager_unittests",
+      "mojo_system_unittests",
+      "nacl_loader_unittests"
+    ]
+  },
+  "Linux Trusty (dbg)(32)": {
+    "gtest_tests": [
+      "app_list_unittests",
+      "aura_unittests",
+      "interactive_ui_tests",
+      "base_unittests",
+      "cacheinvalidation_unittests",
+      "cast_unittests",
+      "cc_unittests",
+      "chromedriver_unittests",
+      "components_unittests",
+      "compositor_unittests",
+      "crypto_unittests",
+      "dbus_unittests",
+      "gcm_unit_tests",
+      "gfx_unittests",
+      "google_apis_unittests",
+      "gpu_unittests",
+      "url_unittests",
+      "jingle_unittests",
+      "content_unittests",
+      "device_unittests",
+      "events_unittests",
+      "media_unittests",
+      "net_unittests",
+      "ppapi_unittests",
+      "printing_unittests",
+      "remoting_unittests",
+      "sandbox_linux_unittests",
+      "ui_unittests",
+      "ipc_tests",
+      "sync_unit_tests",
+      "unit_tests",
+      "views_unittests",
+      "wm_unittests",
+      "sql_unittests",
+      "browser_tests",
+      "content_browsertests",
+      "webkit_compositor_bindings_unittests",
+      "mojo_apps_js_unittests",
+      "mojo_common_unittests",
+      "mojo_js_unittests",
+      "mojo_public_bindings_unittests",
+      "mojo_public_environment_unittests",
+      "mojo_public_system_unittests",
+      "mojo_public_utility_unittests",
+      "mojo_service_manager_unittests",
+      "mojo_system_unittests",
+      "nacl_loader_unittests"
+    ]
+  }
+}
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 8195c87..f3dfdb0 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -46,7 +46,9 @@
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
       "mojo_service_manager_unittests",
-      "mojo_system_unittests"
+      "mojo_system_unittests",
+      "mojo_view_manager_unittests",
+      "nacl_loader_unittests"
     ]
   },
   "Linux GTK Tests": {
@@ -89,7 +91,8 @@
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
       "mojo_service_manager_unittests",
-      "mojo_system_unittests"
+      "mojo_system_unittests",
+      "nacl_loader_unittests"
     ]
   },
   "Linux Tests (dbg)(1)(32)": {
@@ -142,7 +145,9 @@
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
       "mojo_service_manager_unittests",
-      "mojo_system_unittests"
+      "mojo_system_unittests",
+      "mojo_view_manager_unittests",
+      "nacl_loader_unittests"
     ]
   },
   "Linux Tests (dbg)(1)": {
@@ -196,7 +201,9 @@
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
       "mojo_service_manager_unittests",
-      "mojo_system_unittests"
+      "mojo_system_unittests",
+      "mojo_view_manager_unittests",
+      "nacl_loader_unittests"
     ]
   },
   "Linux Clang (dbg)": {
@@ -221,7 +228,9 @@
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
       "mojo_service_manager_unittests",
-      "mojo_system_unittests"
+      "mojo_system_unittests",
+      "mojo_view_manager_unittests",
+      "nacl_loader_unittests"
     ]
   }
 }
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index e095afe..bb4b7a4 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -49,6 +49,7 @@
       "mojo_public_utility_unittests",
       "mojo_service_manager_unittests",
       "mojo_system_unittests",
+      "sandbox_mac_unittests",
       {"test": "browser_tests", "shard_index": 2, "total_shards": 3}
     ]
   },
@@ -102,6 +103,7 @@
       "mojo_public_utility_unittests",
       "mojo_service_manager_unittests",
       "mojo_system_unittests",
+      "sandbox_mac_unittests",
       {"test": "browser_tests", "shard_index": 2, "total_shards": 3}
     ]
   },
@@ -128,6 +130,7 @@
       "gfx_unittests",
       "media_unittests",
       "net_unittests",
+      "sandbox_mac_unittests",
       {"test": "browser_tests", "shard_index": 1, "total_shards": 4}
     ]
   },
@@ -185,6 +188,7 @@
       "gfx_unittests",
       "media_unittests",
       "net_unittests",
+      "sandbox_mac_unittests",
       {"test": "browser_tests", "shard_index": 1, "total_shards": 4}
     ]
   },
diff --git a/testing/buildbot/chromium_trybot.json b/testing/buildbot/chromium_trybot.json
index b1cb7d3..2fa23bd 100644
--- a/testing/buildbot/chromium_trybot.json
+++ b/testing/buildbot/chromium_trybot.json
@@ -40,6 +40,10 @@
   "mojo_public_utility_unittests",
   "mojo_service_manager_unittests",
   "mojo_system_unittests",
+  {
+    "test": "nacl_loader_unittests",
+    "platforms": ["linux"]
+  },
   "net_unittests",
   "ppapi_unittests",
   "printing_unittests",
@@ -54,11 +58,19 @@
     "chromium_configs": ["chromium_chromeos", "chromium_chromeos_clang"]
   },
   {
+    "test": "mojo_view_manager_unittests",
+    "platforms": ["linux"]
+  },
+  {
     "test": "sandbox_linux_unittests",
     "platforms": ["linux"],
     "args": ["--test-launcher-print-test-stdio=always"]
   },
   {
+    "test": "sandbox_mac_unittests",
+    "platforms": ["mac"]
+  },
+  {
     "test": "views_unittests",
     "platforms": ["win"]
   },
diff --git a/testing/gtest_prod.target.darwin-arm.mk b/testing/gtest_prod.target.darwin-arm.mk
index c687759..04217c9 100644
--- a/testing/gtest_prod.target.darwin-arm.mk
+++ b/testing/gtest_prod.target.darwin-arm.mk
@@ -39,7 +39,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -125,7 +124,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/testing/gtest_prod.target.darwin-x86.mk b/testing/gtest_prod.target.darwin-x86.mk
index 4fcb9da..53149e9 100644
--- a/testing/gtest_prod.target.darwin-x86.mk
+++ b/testing/gtest_prod.target.darwin-x86.mk
@@ -41,7 +41,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/testing/gtest_prod.target.darwin-x86_64.mk b/testing/gtest_prod.target.darwin-x86_64.mk
index b0d18a9..06c6bf2 100644
--- a/testing/gtest_prod.target.darwin-x86_64.mk
+++ b/testing/gtest_prod.target.darwin-x86_64.mk
@@ -41,7 +41,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/testing/gtest_prod.target.linux-arm.mk b/testing/gtest_prod.target.linux-arm.mk
index c687759..04217c9 100644
--- a/testing/gtest_prod.target.linux-arm.mk
+++ b/testing/gtest_prod.target.linux-arm.mk
@@ -39,7 +39,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -125,7 +124,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/testing/gtest_prod.target.linux-x86.mk b/testing/gtest_prod.target.linux-x86.mk
index 4fcb9da..53149e9 100644
--- a/testing/gtest_prod.target.linux-x86.mk
+++ b/testing/gtest_prod.target.linux-x86.mk
@@ -41,7 +41,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/testing/gtest_prod.target.linux-x86_64.mk b/testing/gtest_prod.target.linux-x86_64.mk
index b0d18a9..06c6bf2 100644
--- a/testing/gtest_prod.target.linux-x86_64.mk
+++ b/testing/gtest_prod.target.linux-x86_64.mk
@@ -41,7 +41,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn
new file mode 100644
index 0000000..a957e2f
--- /dev/null
+++ b/third_party/BUILD.gn
@@ -0,0 +1,39 @@
+# 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.
+
+if (is_android) {
+  import("//build/config/android/config.gni")
+}
+
+declare_args() {
+  # Uses system libjpeg. If true, overrides use_libjpeg_turbo.
+  use_system_libjpeg = is_android && is_android_webview_build
+
+  # Uses libjpeg_turbo as the jpeg implementation. Has no effect if
+  # use_system_libjpeg is set.
+  use_libjpeg_turbo = true
+}
+
+config("system_libjpeg_config") {
+  defines = [ "USE_SYSTEM_LIBJPEG" ]
+}
+
+config("libjpeg_turbo_config") {
+  defines = [ "USE_LIBJPEG_TURBO" ]
+}
+
+# This is a meta target that forwards to the system's libjpeg,
+# third_party/libjpeg, or third_party/libjpeg_turbo depending on the build args
+# declared in this file.
+group("jpeg") {
+  if (use_system_libjpeg) {
+    libs = [ "jpeg" ]
+    direct_dependent_configs = [ ":system_libjpeg_config" ]
+  } else if (use_libjpeg_turbo) {
+    deps = [ "//third_party/libjpeg_turbo:libjpeg" ]
+    direct_dependent_configs = [ ":libjpeg_turbo_config" ]
+  } else {
+    deps = [ "//third_party/libjpeg:libjpeg" ]
+  }
+}
diff --git a/third_party/android_opengl/LICENSE b/third_party/android_opengl/LICENSE
new file mode 100644
index 0000000..ea64da8
--- /dev/null
+++ b/third_party/android_opengl/LICENSE
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
\ No newline at end of file
diff --git a/third_party/android_opengl/OWNERS b/third_party/android_opengl/OWNERS
new file mode 100644
index 0000000..540d858
--- /dev/null
+++ b/third_party/android_opengl/OWNERS
@@ -0,0 +1,2 @@
+dtrainor@chromium.org
+powei@chromium.org
\ No newline at end of file
diff --git a/third_party/android_opengl/README.chromium b/third_party/android_opengl/README.chromium
new file mode 100644
index 0000000..f33e90f
--- /dev/null
+++ b/third_party/android_opengl/README.chromium
@@ -0,0 +1,15 @@
+Name: etc1
+Version: 0
+URL: https://source.android.com/
+License: Apache 2.0
+Security Critical: no
+
+Description:
+This directory contains an ETC1 encoding API.  The source derives from
+frameworks/base/opengl/include/ETC1/etc1.cpp from the Android Open Source
+Project.
+
+Local modifications:
+- Removed decoding.
+- Generalize so that output size is independent of input size.
+- Handle cases of out-of-bounds blocks along the image boundary.
diff --git a/third_party/android_opengl/README.security b/third_party/android_opengl/README.security
new file mode 100644
index 0000000..63af0ee
--- /dev/null
+++ b/third_party/android_opengl/README.security
@@ -0,0 +1 @@
+This library has not been reviewed by security team for handling untrusted input.  Contact security@chromium.org for any questions.
\ No newline at end of file
diff --git a/third_party/android_opengl/etc1/etc1.cpp b/third_party/android_opengl/etc1/etc1.cpp
new file mode 100644
index 0000000..7dd08d9
--- /dev/null
+++ b/third_party/android_opengl/etc1/etc1.cpp
@@ -0,0 +1,589 @@
+// Copyright 2009 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This is branched from frameworks/base/opengl/include/ETC1/etc1.cc
+//
+// It has been modified as follows:
+// 1. Unused or not related to encoding methods have been removed.
+// 2. Methods related to determining the size of the output texture have been
+//    added.
+// 3. EncodeImage has been modified to operate directly on a bitmap, work with
+//    4bpp input, and resize the output to a power-of-two size in order to work
+//    with the graphics driver.
+//
+
+#include "etc1.h"
+
+#include <string>
+#include <cmath>
+
+/* From http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt
+
+ The number of bits that represent a 4x4 texel block is 64 bits if
+ <internalformat> is given by ETC1_RGB8_OES.
+
+ The data for a block is a number of bytes,
+
+ {q0, q1, q2, q3, q4, q5, q6, q7}
+
+ where byte q0 is located at the lowest memory address and q7 at
+ the highest. The 64 bits specifying the block is then represented
+ by the following 64 bit integer:
+
+ int64bit = 256*(256*(256*(256*(256*(256*(256*q0+q1)+q2)+q3)+q4)+q5)+q6)+q7;
+
+ ETC1_RGB8_OES:
+
+ a) bit layout in bits 63 through 32 if diffbit = 0
+
+ 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48
+ -----------------------------------------------
+ | base col1 | base col2 | base col1 | base col2 |
+ | R1 (4bits)| R2 (4bits)| G1 (4bits)| G2 (4bits)|
+ -----------------------------------------------
+
+ 47 46 45 44 43 42 41 40 39 38 37 36 35 34  33  32
+ ---------------------------------------------------
+ | base col1 | base col2 | table  | table  |diff|flip|
+ | B1 (4bits)| B2 (4bits)| cw 1   | cw 2   |bit |bit |
+ ---------------------------------------------------
+
+
+ b) bit layout in bits 63 through 32 if diffbit = 1
+
+ 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48
+ -----------------------------------------------
+ | base col1    | dcol 2 | base col1    | dcol 2 |
+ | R1' (5 bits) | dR2    | G1' (5 bits) | dG2    |
+ -----------------------------------------------
+
+ 47 46 45 44 43 42 41 40 39 38 37 36 35 34  33  32
+ ---------------------------------------------------
+ | base col 1   | dcol 2 | table  | table  |diff|flip|
+ | B1' (5 bits) | dB2    | cw 1   | cw 2   |bit |bit |
+ ---------------------------------------------------
+
+
+ c) bit layout in bits 31 through 0 (in both cases)
+
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
+ -----------------------------------------------
+ |       most significant pixel index bits       |
+ | p| o| n| m| l| k| j| i| h| g| f| e| d| c| b| a|
+ -----------------------------------------------
+
+ 15 14 13 12 11 10  9  8  7  6  5  4  3   2   1  0
+ --------------------------------------------------
+ |         least significant pixel index bits       |
+ | p| o| n| m| l| k| j| i| h| g| f| e| d| c | b | a |
+ --------------------------------------------------
+
+
+ Add table 3.17.2: Intensity modifier sets for ETC1 compressed textures:
+
+ table codeword                modifier table
+ ------------------        ----------------------
+ 0                     -8  -2  2   8
+ 1                    -17  -5  5  17
+ 2                    -29  -9  9  29
+ 3                    -42 -13 13  42
+ 4                    -60 -18 18  60
+ 5                    -80 -24 24  80
+ 6                   -106 -33 33 106
+ 7                   -183 -47 47 183
+
+
+ Add table 3.17.3 Mapping from pixel index values to modifier values for
+ ETC1 compressed textures:
+
+ pixel index value
+ ---------------
+ msb     lsb           resulting modifier value
+ -----   -----          -------------------------
+ 1       1            -b (large negative value)
+ 1       0            -a (small negative value)
+ 0       0             a (small positive value)
+ 0       1             b (large positive value)
+
+
+ */
+
+#define ETC1_ENCODED_BLOCK_SIZE 8
+#define ETC1_DECODED_BLOCK_SIZE 48
+
+namespace {
+
+typedef unsigned char etc1_byte;
+typedef int etc1_bool;
+typedef unsigned int etc1_uint32;
+
+static const int kModifierTable[] = {
+/* 0 */2, 8, -2, -8,
+/* 1 */5, 17, -5, -17,
+/* 2 */9, 29, -9, -29,
+/* 3 */13, 42, -13, -42,
+/* 4 */18, 60, -18, -60,
+/* 5 */24, 80, -24, -80,
+/* 6 */33, 106, -33, -106,
+/* 7 */47, 183, -47, -183 };
+
+
+static inline etc1_byte clamp(int x) {
+    return (etc1_byte) (x >= 0 ? (x < 255 ? x : 255) : 0);
+}
+
+static
+inline int convert4To8(int b) {
+    int c = b & 0xf;
+    return (c << 4) | c;
+}
+
+static
+inline int convert5To8(int b) {
+    int c = b & 0x1f;
+    return (c << 3) | (c >> 2);
+}
+
+static
+inline int convert6To8(int b) {
+    int c = b & 0x3f;
+    return (c << 2) | (c >> 4);
+}
+
+static
+inline int divideBy255(int d) {
+    return (d + 128 + (d >> 8)) >> 8;
+}
+
+static
+inline int convert8To4(int b) {
+    int c = b & 0xff;
+    return divideBy255(c * 15);
+}
+
+static
+inline int convert8To5(int b) {
+    int c = b & 0xff;
+    return divideBy255(c * 31);
+}
+
+typedef struct {
+    etc1_uint32 high;
+    etc1_uint32 low;
+    etc1_uint32 score; // Lower is more accurate
+} etc_compressed;
+
+static
+inline void take_best(etc_compressed* a, const etc_compressed* b) {
+    if (a->score > b->score) {
+        *a = *b;
+    }
+}
+
+static
+void etc_average_colors_subblock(const etc1_byte* pIn, etc1_uint32 inMask,
+        etc1_byte* pColors, bool flipped, bool second) {
+    int r = 0;
+    int g = 0;
+    int b = 0;
+
+    if (flipped) {
+        int by = 0;
+        if (second) {
+            by = 2;
+        }
+        for (int y = 0; y < 2; y++) {
+            int yy = by + y;
+            for (int x = 0; x < 4; x++) {
+                int i = x + 4 * yy;
+                if (inMask & (1 << i)) {
+                    const etc1_byte* p = pIn + i * 3;
+                    r += *(p++);
+                    g += *(p++);
+                    b += *(p++);
+                }
+            }
+        }
+    } else {
+        int bx = 0;
+        if (second) {
+            bx = 2;
+        }
+        for (int y = 0; y < 4; y++) {
+            for (int x = 0; x < 2; x++) {
+                int xx = bx + x;
+                int i = xx + 4 * y;
+                if (inMask & (1 << i)) {
+                    const etc1_byte* p = pIn + i * 3;
+                    r += *(p++);
+                    g += *(p++);
+                    b += *(p++);
+                }
+            }
+        }
+    }
+    pColors[0] = (etc1_byte)((r + 4) >> 3);
+    pColors[1] = (etc1_byte)((g + 4) >> 3);
+    pColors[2] = (etc1_byte)((b + 4) >> 3);
+}
+
+static
+inline int square(int x) {
+    return x * x;
+}
+
+static etc1_uint32 chooseModifier(const etc1_byte* pBaseColors,
+        const etc1_byte* pIn, etc1_uint32 *pLow, int bitIndex,
+        const int* pModifierTable) {
+    etc1_uint32 bestScore = ~0;
+    int bestIndex = 0;
+    int pixelR = pIn[0];
+    int pixelG = pIn[1];
+    int pixelB = pIn[2];
+    int r = pBaseColors[0];
+    int g = pBaseColors[1];
+    int b = pBaseColors[2];
+    for (int i = 0; i < 4; i++) {
+        int modifier = pModifierTable[i];
+        int decodedG = clamp(g + modifier);
+        etc1_uint32 score = (etc1_uint32) (6 * square(decodedG - pixelG));
+        if (score >= bestScore) {
+            continue;
+        }
+        int decodedR = clamp(r + modifier);
+        score += (etc1_uint32) (3 * square(decodedR - pixelR));
+        if (score >= bestScore) {
+            continue;
+        }
+        int decodedB = clamp(b + modifier);
+        score += (etc1_uint32) square(decodedB - pixelB);
+        if (score < bestScore) {
+            bestScore = score;
+            bestIndex = i;
+        }
+    }
+    etc1_uint32 lowMask = (((bestIndex >> 1) << 16) | (bestIndex & 1))
+            << bitIndex;
+    *pLow |= lowMask;
+    return bestScore;
+}
+
+static
+void etc_encode_subblock_helper(const etc1_byte* pIn, etc1_uint32 inMask,
+        etc_compressed* pCompressed, bool flipped, bool second,
+        const etc1_byte* pBaseColors, const int* pModifierTable) {
+    int score = pCompressed->score;
+    if (flipped) {
+        int by = 0;
+        if (second) {
+            by = 2;
+        }
+        for (int y = 0; y < 2; y++) {
+            int yy = by + y;
+            for (int x = 0; x < 4; x++) {
+                int i = x + 4 * yy;
+                if (inMask & (1 << i)) {
+                    score += chooseModifier(pBaseColors, pIn + i * 3,
+                            &pCompressed->low, yy + x * 4, pModifierTable);
+                }
+            }
+        }
+    } else {
+        int bx = 0;
+        if (second) {
+            bx = 2;
+        }
+        for (int y = 0; y < 4; y++) {
+            for (int x = 0; x < 2; x++) {
+                int xx = bx + x;
+                int i = xx + 4 * y;
+                if (inMask & (1 << i)) {
+                    score += chooseModifier(pBaseColors, pIn + i * 3,
+                            &pCompressed->low, y + xx * 4, pModifierTable);
+                }
+            }
+        }
+    }
+    pCompressed->score = score;
+}
+
+static bool inRange4bitSigned(int color) {
+    return color >= -4 && color <= 3;
+}
+
+static void etc_encodeBaseColors(etc1_byte* pBaseColors,
+        const etc1_byte* pColors, etc_compressed* pCompressed) {
+    int r1, g1, b1, r2, g2, b2; // 8 bit base colors for sub-blocks
+    bool differential;
+    {
+        int r51 = convert8To5(pColors[0]);
+        int g51 = convert8To5(pColors[1]);
+        int b51 = convert8To5(pColors[2]);
+        int r52 = convert8To5(pColors[3]);
+        int g52 = convert8To5(pColors[4]);
+        int b52 = convert8To5(pColors[5]);
+
+        r1 = convert5To8(r51);
+        g1 = convert5To8(g51);
+        b1 = convert5To8(b51);
+
+        int dr = r52 - r51;
+        int dg = g52 - g51;
+        int db = b52 - b51;
+
+        differential = inRange4bitSigned(dr) && inRange4bitSigned(dg)
+                && inRange4bitSigned(db);
+        if (differential) {
+            r2 = convert5To8(r51 + dr);
+            g2 = convert5To8(g51 + dg);
+            b2 = convert5To8(b51 + db);
+            pCompressed->high |= (r51 << 27) | ((7 & dr) << 24) | (g51 << 19)
+                    | ((7 & dg) << 16) | (b51 << 11) | ((7 & db) << 8) | 2;
+        }
+    }
+
+    if (!differential) {
+        int r41 = convert8To4(pColors[0]);
+        int g41 = convert8To4(pColors[1]);
+        int b41 = convert8To4(pColors[2]);
+        int r42 = convert8To4(pColors[3]);
+        int g42 = convert8To4(pColors[4]);
+        int b42 = convert8To4(pColors[5]);
+        r1 = convert4To8(r41);
+        g1 = convert4To8(g41);
+        b1 = convert4To8(b41);
+        r2 = convert4To8(r42);
+        g2 = convert4To8(g42);
+        b2 = convert4To8(b42);
+        pCompressed->high |= (r41 << 28) | (r42 << 24) | (g41 << 20) | (g42
+                << 16) | (b41 << 12) | (b42 << 8);
+    }
+    pBaseColors[0] = r1;
+    pBaseColors[1] = g1;
+    pBaseColors[2] = b1;
+    pBaseColors[3] = r2;
+    pBaseColors[4] = g2;
+    pBaseColors[5] = b2;
+}
+
+static
+void etc_encode_block_helper(const etc1_byte* pIn, etc1_uint32 inMask,
+        const etc1_byte* pColors, etc_compressed* pCompressed, bool flipped) {
+    pCompressed->score = ~0;
+    pCompressed->high = (flipped ? 1 : 0);
+    pCompressed->low = 0;
+
+    etc1_byte pBaseColors[6];
+
+    etc_encodeBaseColors(pBaseColors, pColors, pCompressed);
+
+    int originalHigh = pCompressed->high;
+
+    const int* pModifierTable = kModifierTable;
+    for (int i = 0; i < 8; i++, pModifierTable += 4) {
+        etc_compressed temp;
+        temp.score = 0;
+        temp.high = originalHigh | (i << 5);
+        temp.low = 0;
+        etc_encode_subblock_helper(pIn, inMask, &temp, flipped, false,
+                pBaseColors, pModifierTable);
+        take_best(pCompressed, &temp);
+    }
+    pModifierTable = kModifierTable;
+    etc_compressed firstHalf = *pCompressed;
+    for (int i = 0; i < 8; i++, pModifierTable += 4) {
+        etc_compressed temp;
+        temp.score = firstHalf.score;
+        temp.high = firstHalf.high | (i << 2);
+        temp.low = firstHalf.low;
+        etc_encode_subblock_helper(pIn, inMask, &temp, flipped, true,
+                pBaseColors + 3, pModifierTable);
+        if (i == 0) {
+            *pCompressed = temp;
+        } else {
+            take_best(pCompressed, &temp);
+        }
+    }
+}
+
+static void writeBigEndian(etc1_byte* pOut, etc1_uint32 d) {
+    pOut[0] = (etc1_byte)(d >> 24);
+    pOut[1] = (etc1_byte)(d >> 16);
+    pOut[2] = (etc1_byte)(d >> 8);
+    pOut[3] = (etc1_byte) d;
+}
+
+// Input is a 4 x 4 square of 3-byte pixels in form R, G, B
+// inmask is a 16-bit mask where bit (1 << (x + y * 4)) tells whether the corresponding (x,y)
+// pixel is valid or not. Invalid pixel color values are ignored when compressing.
+// Output is an ETC1 compressed version of the data.
+
+static void etc1_encode_block(etc1_byte* pIn, int inMask, etc1_byte* pOut) {
+    etc1_byte colors[6];
+    etc1_byte flippedColors[6];
+    etc_average_colors_subblock(pIn, inMask, colors, false, false);
+    etc_average_colors_subblock(pIn, inMask, colors + 3, false, true);
+    etc_average_colors_subblock(pIn, inMask, flippedColors, true, false);
+    etc_average_colors_subblock(pIn, inMask, flippedColors + 3, true, true);
+
+    etc_compressed a, b;
+    etc_encode_block_helper(pIn, inMask, colors, &a, false);
+    etc_encode_block_helper(pIn, inMask, flippedColors, &b, true);
+    take_best(&a, &b);
+    writeBigEndian(pOut, a.high);
+    writeBigEndian(pOut + 4, a.low);
+}
+
+}  // anonymous namespace
+
+// Return the size of the encoded image data.
+
+etc1_uint32 etc1_get_encoded_data_size(etc1_uint32 width, etc1_uint32 height) {
+  return (((width + 3) & ~3) * ((height + 3) & ~3)) >> 1;
+}
+
+// Encode an entire image.
+// pIn - pointer to the image data. Formatted such that the Red component of
+//       pixel (x,y) is at pIn + pixelSize * x + stride * y + redOffset;
+// pOut - pointer to encoded data. Must be large enough to store entire encoded image.
+// Returns false if there was an error.
+
+bool etc1_encode_image(const etc1_byte* pIn, etc1_uint32 width, etc1_uint32 height,
+         etc1_uint32 pixelSize, etc1_uint32 stride, etc1_byte* pOut, etc1_uint32 outWidth,
+         etc1_uint32 outHeight) {
+    if (pixelSize < 2) {
+          return false;
+    }
+    static const unsigned short kYMask[] = { 0x0, 0xf, 0xff, 0xfff, 0xffff };
+    static const unsigned short kXMask[] = { 0x0, 0x1111, 0x3333, 0x7777,
+            0xffff };
+    etc1_byte block[ETC1_DECODED_BLOCK_SIZE];
+    etc1_byte encoded[ETC1_ENCODED_BLOCK_SIZE];
+
+    etc1_uint32 encodedWidth = (outWidth + 3) & ~3;
+    etc1_uint32 encodedHeight = (outHeight + 3) & ~3;
+
+    for (etc1_uint32 y = 0; y < encodedHeight; y += 4) {
+        etc1_uint32 yEnd = outHeight - y;
+        if (yEnd > 4) {
+            yEnd = 4;
+        }
+        int ymask = kYMask[yEnd];
+        for (etc1_uint32 x = 0; x < encodedWidth; x += 4) {
+            etc1_uint32 xEnd = outWidth - x;
+            if (xEnd > 4) {
+                xEnd = 4;
+            }
+            const int mask = ymask & kXMask[xEnd];
+            // Shortcut to only encode blocks which overlap the input image.
+            // The outside region will be undefined garbage.
+            if (x < width && y < height) {
+                for (etc1_uint32 cy = 0; cy < yEnd; cy++) {
+                    etc1_byte* q = block + (cy * 4) * 3;
+                    const etc1_byte* p = pIn + pixelSize * x + stride * (y + cy);
+                    if (y + cy < height) {
+                        for (etc1_uint32 cx = 0; cx < xEnd; cx++) {
+                            if (x + cx < width) {
+                                if (pixelSize == 4) {
+                                    // RGBA_8888: Filter out the input's alpha channel.
+                                    *q++ = p[0];
+                                    *q++ = p[1];
+                                    *q++ = p[2];
+                                } else {
+                                    // RGB_565: Unpack input's 2 bytes to RGB.
+                                    int pixel = (p[1] << 8) | p[0];
+                                    *q++ = convert5To8(pixel >> 11);
+                                    *q++ = convert6To8(pixel >> 5);
+                                    *q++ = convert5To8(pixel);
+                                }
+                                p += pixelSize;
+                            } else {
+                                // Out of bounds of the input image but within a
+                                // block that must be properly encoded, so pad
+                                // the original image with the last pixel.
+                                *(q + 0) = *(q - 3);
+                                *(q + 1) = *(q - 2);
+                                *(q + 2) = *(q - 1);
+                                q += 3;
+                            }
+                        }
+                    } else {
+                      // Out of bounds of the input image but within a
+                      // block that must be properly encoded, so pad the
+                      // original image with the last pixel.
+                      *(q + 0) = *(q - 12);
+                      *(q + 1) = *(q - 11);
+                      *(q + 2) = *(q - 10);
+                      q += 3;
+                    }
+                }
+                etc1_encode_block(block, mask, encoded);
+                memcpy(pOut, encoded, sizeof(encoded));
+            } else if (x == width && width > 0 && height > 0) {
+                // We need to extend the block right after to the last pixel of
+                // the source bitmap for the blending to work nicely.
+                for (etc1_uint32 cy = 0; cy < yEnd; cy++) {
+                    etc1_byte* q = block + (cy * 4) * 3;
+                    const etc1_byte* p = pIn + pixelSize * (width - 1) +
+                            stride * std::min(y + cy, height - 1);
+                    for (etc1_uint32 cx = 0; cx < xEnd; cx++) {
+                        if (pixelSize == 4) {
+                            // RGBA_8888: Filter out the input's alpha channel.
+                            *q++ = p[0];
+                            *q++ = p[1];
+                            *q++ = p[2];
+                        } else {
+                            // RGB_565: Unpack input's 2 bytes to RGB.
+                            int pixel = (p[1] << 8) | p[0];
+                            *q++ = convert5To8(pixel >> 11);
+                            *q++ = convert6To8(pixel >> 5);
+                            *q++ = convert5To8(pixel);
+                        }
+                    }
+                }
+                etc1_encode_block(block, mask, encoded);
+                memcpy(pOut, encoded, sizeof(encoded));
+            } else if (y == height && width > 0 && height > 0) {
+                // We need to extend the block right after to the last pixel of
+                // the source bitmap for the blending to work nicely.
+                for (etc1_uint32 cy = 0; cy < yEnd; cy++) {
+                    etc1_byte* q = block + (cy * 4) * 3;
+                    for (etc1_uint32 cx = 0; cx < xEnd; cx++) {
+                        const etc1_byte* p = pIn +
+                                pixelSize * std::min(x + cx, width - 1) +
+                                stride * (height - 1);
+                        if (pixelSize == 4) {
+                            // RGBA_8888: Filter out the input's alpha channel.
+                            *q++ = p[0];
+                            *q++ = p[1];
+                            *q++ = p[2];
+                        } else {
+                            // RGB_565: Unpack input's 2 bytes to RGB.
+                            int pixel = (p[1] << 8) | p[0];
+                            *q++ = convert5To8(pixel >> 11);
+                            *q++ = convert6To8(pixel >> 5);
+                            *q++ = convert5To8(pixel);
+                        }
+                    }
+                }
+                etc1_encode_block(block, mask, encoded);
+                memcpy(pOut, encoded, sizeof(encoded));
+            } else {
+                memset(pOut, 0xFF, sizeof(encoded));
+            }
+            pOut += sizeof(encoded);
+        }
+    }
+    return true;
+}
diff --git a/third_party/android_opengl/etc1/etc1.gyp b/third_party/android_opengl/etc1/etc1.gyp
new file mode 100644
index 0000000..bd9d4bf
--- /dev/null
+++ b/third_party/android_opengl/etc1/etc1.gyp
@@ -0,0 +1,16 @@
+# 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.
+
+{
+  'targets': [
+    {
+      'target_name': 'etc1',
+      'type': 'static_library',
+      'sources': [
+        'etc1.cpp',
+        'etc1.h',
+      ],
+    },
+  ]
+}
diff --git a/third_party/android_opengl/etc1/etc1.h b/third_party/android_opengl/etc1/etc1.h
new file mode 100644
index 0000000..0106967
--- /dev/null
+++ b/third_party/android_opengl/etc1/etc1.h
@@ -0,0 +1,38 @@
+// Copyright 2009 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This is branched from AOSP's frameworks/base/opengl/include/ETC1/etc1.h
+//
+// It has been modified to implement Chromium's ETC1 API.  The decoding path
+// has been removed as we do not require it.
+
+#ifndef THIRD_PARTY_ANDROID_OPENGL_ETC1_ETC1_H_
+#define THIRD_PARTY_ANDROID_OPENGL_ETC1_ETC1_H_
+
+// Return the size of the encoded image data.
+
+unsigned int etc1_get_encoded_data_size(unsigned int width, unsigned int height);
+
+// Encode an entire image.
+// pIn - pointer to the image data. Formatted such that
+//       pixel (x,y) is at pIn + pixelSize * x + stride * y;
+// pOut - pointer to encoded data. Must be large enough to store entire encoded image.
+// pixelSize can be 2 or 3. 2 is an GL_UNSIGNED_SHORT_5_6_5 image, 3 is a GL_BYTE RGB image.
+// returns non-zero if there is an error.
+
+bool etc1_encode_image(const unsigned char* pIn, unsigned int width, unsigned int height,
+         unsigned int pixelSize, unsigned int stride, unsigned char* pOut, unsigned int outWidth,
+         unsigned int outHeight);
+
+#endif // THIRD_PARTY_ANDROID_OPENGL_ETC1_ETC1_H_
diff --git a/third_party/android_platform/README.chromium b/third_party/android_platform/README.chromium
index 3db9f23..2bf9bb2 100644
--- a/third_party/android_platform/README.chromium
+++ b/third_party/android_platform/README.chromium
@@ -2,8 +2,8 @@
 Short Name: android platform development
 URL: https://android.googlesource.com/platform/development
 Version: 0
-Date: 2013/07/03
-Revision: f56a37e
+Date: 2014/05/02
+Revision: 1b10ec4
 License: Apache 2.0
 License File: NOT_SHIPPED
 Security Critical: no
@@ -15,3 +15,5 @@
 Only picked the few scripts needed by chrome.
 Updated output directories to use environment variable.
 When calling addr2line, check the symbol is a file (and not a directory).
+Added support for parsing LOG(FATAL) and DCHECK errors and their
+    stack traces, as emitted by src/base/debug/stack_trace_android.cc
\ No newline at end of file
diff --git a/third_party/android_platform/development/scripts/stack b/third_party/android_platform/development/scripts/stack
index 2cd086f..e55f688 100755
--- a/third_party/android_platform/development/scripts/stack
+++ b/third_party/android_platform/development/scripts/stack
@@ -54,7 +54,7 @@
   print "       argument information. Also, the 'stack data' section will be"
   print "       printed."
   print
-  print "  --arch=arm|x86"
+  print "  --arch=arm|arm64|x86_64|x86|mips"
   print "       the target architecture"
   print
   print "  FILE should contain a stack trace in it somewhere"
diff --git a/third_party/android_platform/development/scripts/stack_core.py b/third_party/android_platform/development/scripts/stack_core.py
index 4120636..a11fbb4 100755
--- a/third_party/android_platform/development/scripts/stack_core.py
+++ b/third_party/android_platform/development/scripts/stack_core.py
@@ -72,6 +72,15 @@
   thread_line = re.compile("(.*)(\-\-\- ){15}\-\-\-")
   dalvik_jni_thread_line = re.compile("(\".*\" prio=[0-9]+ tid=[0-9]+ NATIVE.*)")
   dalvik_native_thread_line = re.compile("(\".*\" sysTid=[0-9]+ nice=[0-9]+.*)")
+
+  width = "{8}"
+  if symbol.ARCH == "arm64" or symbol.ARCH == "x86_64":
+    width = "{16}"
+
+  # Matches LOG(FATAL) lines, like the following example:
+  #   [FATAL:source_file.cc(33)] Check failed: !instances_.empty()
+  log_fatal_line = re.compile("(\[FATAL\:.*\].*)$")
+
   # Note that both trace and value line matching allow for variable amounts of
   # whitespace (e.g. \t). This is because the we want to allow for the stack
   # tool to operate on AndroidFeedback provided system logs. AndroidFeedback
@@ -83,13 +92,23 @@
   # Or lines from AndroidFeedback crash report system logs like:
   #   03-25 00:51:05.520 I/DEBUG ( 65): #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so
   # Please note the spacing differences.
-  trace_line = re.compile("(.*)\#(?P<frame>[0-9]+)[ \t]+(..)[ \t]+(0x)?(?P<address>[0-9a-f]{0,8})[ \t]+(?P<lib>[^\r\n \t]*)(?P<symbol_present> \((?P<symbol_name>.*)\))?")  # pylint: disable-msg=C6310
+  trace_line = re.compile("(.*)\#(?P<frame>[0-9]+)[ \t]+(..)[ \t]+(0x)?(?P<address>[0-9a-f]{0,16})[ \t]+(?P<lib>[^\r\n \t]*)(?P<symbol_present> \((?P<symbol_name>.*)\))?")  # pylint: disable-msg=C6310
+
+  # Matches lines emitted by src/base/debug/stack_trace_android.cc, like:
+  #   #00 0x7324d92d /data/app-lib/org.chromium.native_test-1/libbase.cr.so+0x0006992d
+  # This pattern includes the unused named capture groups <symbol_present> and
+  # <symbol_name> so that it can interoperate with the |trace_line| regex.
+  debug_trace_line = re.compile(
+      '(.*)(?P<frame>\#[0-9]+ 0x[0-9a-f]' + width + ') '
+      '(?P<lib>[^+]+)\+0x(?P<address>[0-9a-f]' + width + ')'
+      '(?P<symbol_present>)(?P<symbol_name>)')
+
   # Examples of matched value lines include:
   #   bea4170c  8018e4e9  /data/data/com.my.project/lib/libmyproject.so
   #   bea4170c  8018e4e9  /data/data/com.my.project/lib/libmyproject.so (symbol)
   #   03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so
   # Again, note the spacing differences.
-  value_line = re.compile("(.*)([0-9a-f]{8})[ \t]+([0-9a-f]{8})[ \t]+([^\r\n \t]*)( \((.*)\))?")
+  value_line = re.compile("(.*)([0-9a-f]" + width + ")[ \t]+([0-9a-f]" + width + ")[ \t]+([^\r\n \t]*)( \((.*)\))?")
   # Lines from 'code around' sections of the output will be matched before
   # value lines because otheriwse the 'code around' sections will be confused as
   # value lines.
@@ -97,7 +116,12 @@
   # Examples include:
   #   801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
   #   03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
-  code_line = re.compile("(.*)[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[a-f0-9]{8}[ \t]*[ \r\n]")  # pylint: disable-msg=C6310
+  code_line = re.compile("(.*)[ \t]*[a-f0-9]" + width +
+                         "[ \t]*[a-f0-9]" + width +
+                         "[ \t]*[a-f0-9]" + width +
+                         "[ \t]*[a-f0-9]" + width +
+                         "[ \t]*[a-f0-9]" + width +
+                         "[ \t]*[ \r\n]")  # pylint: disable-msg=C6310
 
   trace_lines = []
   value_lines = []
@@ -113,7 +137,7 @@
     line = unicode(ln, errors='ignore')
     lib, address = None, None
 
-    match = trace_line.match(line)
+    match = trace_line.match(line) or debug_trace_line.match(line)
     if match:
       address, lib = match.group('address', 'lib')
 
@@ -138,8 +162,10 @@
     thread_header = thread_line.search(line)
     dalvik_jni_thread_header = dalvik_jni_thread_line.search(line)
     dalvik_native_thread_header = dalvik_native_thread_line.search(line)
-    if process_header or signal_header or register_header or thread_header \
-        or dalvik_jni_thread_header or dalvik_native_thread_header:
+    log_fatal_header = log_fatal_line.search(line)
+    if (process_header or signal_header or register_header or thread_header or
+        dalvik_jni_thread_header or dalvik_native_thread_header or
+        log_fatal_header) :
       if trace_lines or value_lines:
         PrintOutput(trace_lines, value_lines, more_info)
         PrintDivider()
@@ -158,9 +184,12 @@
         print dalvik_jni_thread_header.group(1)
       if dalvik_native_thread_header:
         print dalvik_native_thread_header.group(1)
+      if log_fatal_header:
+        print log_fatal_header.group(1)
       continue
-    if trace_line.match(line):
-      match = trace_line.match(line)
+
+    match = trace_line.match(line) or debug_trace_line.match(line)
+    if match:
       frame, code_addr, area, symbol_present, symbol_name = match.group(
           'frame', 'address', 'lib', 'symbol_present', 'symbol_name')
 
@@ -199,8 +228,8 @@
       # Code lines should be ignored. If this were exluded the 'code around'
       # sections would trigger value_line matches.
       continue;
-    if value_line.match(line):
-      match = value_line.match(line)
+    match = value_line.match(line)
+    if match:
       (unused_, addr, value, area, symbol_present, symbol_name) = match.groups()
       if area == UNKNOWN or area == HEAP or area == STACK or not area:
         value_lines.append((addr, value, "", area))
diff --git a/third_party/android_platform/development/scripts/symbol.py b/third_party/android_platform/development/scripts/symbol.py
index 9eb2484..d1fbaf7 100755
--- a/third_party/android_platform/development/scripts/symbol.py
+++ b/third_party/android_platform/development/scripts/symbol.py
@@ -52,13 +52,29 @@
   if ARCH == "arm":
     toolchain_source = "arm-linux-androideabi-4.6"
     toolchain_prefix = "arm-linux-androideabi"
-  else:
+    ndk = "ndk"
+  elif ARCH == "arm64":
+    toolchain_source = "aarch64-linux-android-4.8"
+    toolchain_prefix = "aarch64-linux-android"
+    ndk = "ndk_experimental"
+  elif ARCH == "x86":
     toolchain_source = "x86-4.6"
     toolchain_prefix = "i686-android-linux"
+    ndk = "ndk"
+  elif ARCH == "x86_64":
+    toolchain_source = "x86_64-4.8"
+    toolchain_prefix = "x86_64-linux-android"
+    ndk = "ndk_experimental"
+  elif ARCH == "mips":
+    toolchain_source = "mipsel-linux-android-4.6"
+    toolchain_prefix = "mipsel-linux-android"
+    ndk = "ndk"
+  else:
+    raise Exception("Could not find tool chain")
 
   toolchain_subdir = (
-      "third_party/android_tools/ndk/toolchains/%s/prebuilt/linux-x86_64/bin" %
-       toolchain_source)
+      "third_party/android_tools/%s/toolchains/%s/prebuilt/linux-x86_64/bin" %
+       (ndk, toolchain_source))
 
   return os.path.join(CHROME_SRC,
                       toolchain_subdir,
@@ -78,14 +94,29 @@
     return TOOLCHAIN_INFO
 
   ## Known toolchains, newer ones in the front.
-  if ARCH == "arm":
+  if ARCH == "arm64":
+    gcc_version = "4.8"
     known_toolchains = [
-      ("arm-linux-androideabi-4.6", "arm", "arm-linux-androideabi"),
+      ("aarch64-linux-android-" + gcc_version, "aarch64", "aarch64-linux-android")
+    ]
+  elif ARCH == "arm":
+    gcc_version = "4.6"
+    known_toolchains = [
+      ("arm-linux-androideabi-" + gcc_version, "arm", "arm-linux-androideabi"),
     ]
   elif ARCH =="x86":
     known_toolchains = [
       ("i686-android-linux-4.4.3", "x86", "i686-android-linux")
     ]
+  elif ARCH =="x86_64":
+    known_toolchains = [
+      ("x86_64-linux-android-4.8", "x86_64", "x86_64-linux-android")
+    ]
+  elif ARCH == "mips":
+    gcc_version = "4.6"
+    known_toolchains = [
+      ("mipsel-linux-android-" + gcc_version, "mips", "mipsel-linux-android")
+    ]
   else:
     known_toolchains = []
 
@@ -94,6 +125,7 @@
     toolchain_info = (label, platform, target);
     if os.path.exists(ToolPath("addr2line", toolchain_info)):
       TOOLCHAIN_INFO = toolchain_info
+      print "Using toolchain from :" + ToolPath("", TOOLCHAIN_INFO)
       return toolchain_info
 
   raise Exception("Could not find tool chain")
diff --git a/third_party/ashmem/ashmem.target.darwin-arm.mk b/third_party/ashmem/ashmem.target.darwin-arm.mk
index 7c713c8..fb3f2f9 100644
--- a/third_party/ashmem/ashmem.target.darwin-arm.mk
+++ b/third_party/ashmem/ashmem.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_ashmem_shim_headers":
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/ashmem/ashmem.target.darwin-arm64.mk b/third_party/ashmem/ashmem.target.darwin-arm64.mk
index 7c713c8..fb3f2f9 100644
--- a/third_party/ashmem/ashmem.target.darwin-arm64.mk
+++ b/third_party/ashmem/ashmem.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_ashmem_shim_headers":
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/ashmem/ashmem.target.darwin-mips.mk b/third_party/ashmem/ashmem.target.darwin-mips.mk
index 7c713c8..fb3f2f9 100644
--- a/third_party/ashmem/ashmem.target.darwin-mips.mk
+++ b/third_party/ashmem/ashmem.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_ashmem_shim_headers":
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/ashmem/ashmem.target.darwin-x86.mk b/third_party/ashmem/ashmem.target.darwin-x86.mk
index 7c713c8..fb3f2f9 100644
--- a/third_party/ashmem/ashmem.target.darwin-x86.mk
+++ b/third_party/ashmem/ashmem.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_ashmem_shim_headers":
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/ashmem/ashmem.target.darwin-x86_64.mk b/third_party/ashmem/ashmem.target.darwin-x86_64.mk
index 7c713c8..fb3f2f9 100644
--- a/third_party/ashmem/ashmem.target.darwin-x86_64.mk
+++ b/third_party/ashmem/ashmem.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_ashmem_shim_headers":
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/ashmem/ashmem.target.linux-arm.mk b/third_party/ashmem/ashmem.target.linux-arm.mk
index 7c713c8..fb3f2f9 100644
--- a/third_party/ashmem/ashmem.target.linux-arm.mk
+++ b/third_party/ashmem/ashmem.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_ashmem_shim_headers":
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/ashmem/ashmem.target.linux-arm64.mk b/third_party/ashmem/ashmem.target.linux-arm64.mk
index 7c713c8..fb3f2f9 100644
--- a/third_party/ashmem/ashmem.target.linux-arm64.mk
+++ b/third_party/ashmem/ashmem.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_ashmem_shim_headers":
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/ashmem/ashmem.target.linux-mips.mk b/third_party/ashmem/ashmem.target.linux-mips.mk
index 7c713c8..fb3f2f9 100644
--- a/third_party/ashmem/ashmem.target.linux-mips.mk
+++ b/third_party/ashmem/ashmem.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_ashmem_shim_headers":
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/ashmem/ashmem.target.linux-x86.mk b/third_party/ashmem/ashmem.target.linux-x86.mk
index 7c713c8..fb3f2f9 100644
--- a/third_party/ashmem/ashmem.target.linux-x86.mk
+++ b/third_party/ashmem/ashmem.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_ashmem_shim_headers":
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/ashmem/ashmem.target.linux-x86_64.mk b/third_party/ashmem/ashmem.target.linux-x86_64.mk
index 7c713c8..fb3f2f9 100644
--- a/third_party/ashmem/ashmem.target.linux-x86_64.mk
+++ b/third_party/ashmem/ashmem.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_ashmem_shim_headers":
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/shim_headers/ashmem/target/third_party/ashmem/ashmem.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/brotli/brotli.target.darwin-arm.mk b/third_party/brotli/brotli.target.darwin-arm.mk
index 43031f9..d328c05 100644
--- a/third_party/brotli/brotli.target.darwin-arm.mk
+++ b/third_party/brotli/brotli.target.darwin-arm.mk
@@ -43,7 +43,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/brotli/brotli.target.darwin-x86.mk b/third_party/brotli/brotli.target.darwin-x86.mk
index b26c4fc..643df32 100644
--- a/third_party/brotli/brotli.target.darwin-x86.mk
+++ b/third_party/brotli/brotli.target.darwin-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/brotli/brotli.target.darwin-x86_64.mk b/third_party/brotli/brotli.target.darwin-x86_64.mk
index 29477f2..15341f2 100644
--- a/third_party/brotli/brotli.target.darwin-x86_64.mk
+++ b/third_party/brotli/brotli.target.darwin-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/brotli/brotli.target.linux-arm.mk b/third_party/brotli/brotli.target.linux-arm.mk
index 43031f9..d328c05 100644
--- a/third_party/brotli/brotli.target.linux-arm.mk
+++ b/third_party/brotli/brotli.target.linux-arm.mk
@@ -43,7 +43,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/brotli/brotli.target.linux-x86.mk b/third_party/brotli/brotli.target.linux-x86.mk
index b26c4fc..643df32 100644
--- a/third_party/brotli/brotli.target.linux-x86.mk
+++ b/third_party/brotli/brotli.target.linux-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/brotli/brotli.target.linux-x86_64.mk b/third_party/brotli/brotli.target.linux-x86_64.mk
index 29477f2..15341f2 100644
--- a/third_party/brotli/brotli.target.linux-x86_64.mk
+++ b/third_party/brotli/brotli.target.linux-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/dom_distiller_js/README.chromium b/third_party/dom_distiller_js/README.chromium
index 8624807..8c1f18c 100644
--- a/third_party/dom_distiller_js/README.chromium
+++ b/third_party/dom_distiller_js/README.chromium
@@ -1,6 +1,6 @@
 Name: dom-distiller-js
 URL: https://code.google.com/p/dom-distiller
-Version: d690d4a859
+Version: feccd237e1
 License: BSD
 Security Critical: yes
 
diff --git a/third_party/dom_distiller_js/js/domdistiller.js b/third_party/dom_distiller_js/js/domdistiller.js
index 9500c16..1fa8719 100644
--- a/third_party/dom_distiller_js/js/domdistiller.js
+++ b/third_party/dom_distiller_js/js/domdistiller.js
@@ -1,392 +1,493 @@
-var $gwt_version = "2.5.1";var $wnd = window;var $doc = $wnd.document;var $moduleName, $moduleBase;var $strongName = 'A3E72C9BA7989CB6DCC7DDB00D2BFB9F';var $stats = $wnd.__gwtStatsEvent ? function(a) {return $wnd.__gwtStatsEvent(a);} : null,$sessionId = $wnd.__gwtStatsSessionId ? $wnd.__gwtStatsSessionId : null;$stats && $stats({moduleName:'domdistiller',sessionId:$sessionId,subSystem:'startup',evtGroup:'moduleStartup',millis:(new Date()).getTime(),type:'moduleEvalStart'});
+var $gwt_version = "2.5.1";var $wnd = window;var $doc = $wnd.document;var $moduleName, $moduleBase;var $strongName = 'FB651259968FB01B556F7C0AA981CE71';var $stats = $wnd.__gwtStatsEvent ? function(a) {return $wnd.__gwtStatsEvent(a);} : null,$sessionId = $wnd.__gwtStatsSessionId ? $wnd.__gwtStatsSessionId : null;$stats && $stats({moduleName:'domdistiller',sessionId:$sessionId,subSystem:'startup',evtGroup:'moduleStartup',millis:(new Date()).getTime(),type:'moduleEvalStart'});
 function U(){}
-function sp(){}
-function Ab(){}
-function Gc(){}
-function Qc(){}
-function Qh(){}
-function Fh(){}
-function Lh(){}
-function Vh(){}
-function $h(){}
-function qd(){}
-function vd(){}
-function yj(){}
-function rp(){}
-function K(){J()}
-function jd(){$c()}
-function bc(){bd($c())}
-function kn(){bn(this)}
-function R(){P(this)}
+function nu(){}
+function Wb(){}
+function bc(){}
+function Vf(){}
+function Vl(){}
+function Al(){}
+function Gl(){}
+function Ll(){}
+function Lg(){}
+function dg(){}
+function Fg(){}
+function Ql(){}
+function vn(){}
+function mu(){}
+function J(){I()}
+function Ld(){Kd()}
+function yg(){ng()}
+function qf(){qg(ng())}
+function Q(){O(this)}
 function $(){Y(this)}
-function Kb(){Ib(this)}
-function Ri(){wi(this)}
-function hl(){al(this)}
-function hh(a){this.b=a}
-function jh(a){this.b=a}
-function kb(a){this.b=a}
-function Dg(a){this.b=a}
-function di(a){this.b=a}
-function hj(a){this.b=a}
-function oj(a){this.b=a}
-function Mj(a){this.b=a}
-function $j(a){this.b=a}
-function Dl(a){this.b=a}
-function Ql(a){this.b=a}
-function Hm(a){this.b=a}
-function Sm(a){this.b=a}
-function mm(a){this.e=a}
-function Gn(a){this.b=a}
-function bg(a,b){a.b=b}
-function tg(a,b){a.q=b}
-function md(a,b){a.b+=b}
-function nd(a,b){a.b+=b}
-function od(a,b){a.b+=b}
-function ud(a,b){a.src=b}
-function sd(b,a){b.href=a}
-function al(a){a.b=new qd}
-function Zk(){this.b=new qd}
-function Sn(){this.b=new Ri}
-function fg(){fg=sp;new cg}
-function cg(){new kn}
-function tb(a,b){_n(a.b,b)}
-function tn(a,b){a.length=b}
-function bj(){bc.call(this)}
-function Hj(){bc.call(this)}
-function Vj(){bc.call(this)}
-function kk(){bc.call(this)}
-function Ao(){bc.call(this)}
-function Tj(a){cc.call(this,a)}
-function Xj(a){cc.call(this,a)}
-function ol(a){cc.call(this,a)}
-function ok(a){Tj.call(this,a)}
-function Si(a){Ki.call(this,a)}
-function Xi(){Xi=sp;Wi=new Yi}
-function Dc(){Dc=sp;Cc=new Gc}
-function ip(){ip=sp;hp=new bp}
-function J(){J=sp;fg();ag(Ip)}
-function bb(){bb=sp;fg();ag(Ip)}
-function Uk(){Uk=sp;Rk={};Tk={}}
-function Tn(){this.b=new Si(2)}
-function so(){this.b=this.c=this}
-function cc(a){bd($c());this.f=a}
-function Zf(a){return new Xf[a]}
-function Di(b,a){return b.f[Yp+a]}
-function ig(b,a){return b.exec(a)}
-function nj(a,b){return a.b-b.b}
-function hk(a,b){return a>b?a:b}
-function ik(a,b){return a<b?a:b}
-function Rn(a,b){return yi(a.b,b)}
-function jm(a){return a.c<a.e.M()}
-function Kc(a){return Oc(($c(),a))}
-function Hg(a){return a>=48&&a<=57}
-function jp(a){ip();return Xo(a)}
-function Vo(a,b,c){Gi(a.c,b,c)}
-function vn(a,b,c){a.splice(b,c)}
-function vo(a,b){this.b=a;this.c=b}
-function _g(a,b){this.b=a;this.c=b}
-function Cm(a,b){this.b=a;this.c=b}
-function Mm(a,b){this.b=a;this.c=b}
-function xg(a,b){this.c=a;this.b=b}
-function Vl(a,b){this.c=a;this.b=b}
-function Ro(a){this.c=a;this.b=Hq}
-function il(a){jl.call(this,a.tS())}
-function hg(a){fg();gg.call(this,a)}
-function Ko(){fg();gg.call(this,Kp)}
-function jl(a){al(this);nd(this.b,a)}
-function ln(a){bn(this);tn(this.b,a)}
-function bn(a){a.b=Ad(Rf,wp,0,0,0)}
-function zc(a){$wnd.clearTimeout(a)}
-function dl(a,b){nd(a.b,b);return a}
-function cl(a,b){md(a.b,b);return a}
-function co(a){go(a);return a.b.c.d}
-function Lj(a,b){return Nj(a.b,b.b)}
-function Fi(b,a){return Yp+a in b.f}
-function xk(b,a){return b.indexOf(a)}
-function Lc(a){return parseInt(a)||-1}
-function Pd(a){return a==null?null:a}
-function Jd(a,b){return a.cM&&a.cM[b]}
-function bo(a,b){new to(b,a.b);++a.c}
-function ao(a,b,c){new to(b,c);++a.c}
-function kp(a,b,c){ip();Zo(hp,a,b,c)}
-function wn(a,b,c,d){a.splice(b,c,d)}
-function bm(a,b){(a<0||a>=b)&&em(a,b)}
-function Id(a,b){return a.cM&&!!a.cM[b]}
-function cp(a){return a&&a.g?a.g:null}
-function wd(a){return xd(a,0,a.length)}
-function Ik(a){return Ad(Tf,wp,1,a,0)}
-function Od(a){return a.tM==sp||Id(a,1)}
-function yc(a){return a.$H||(a.$H=++qc)}
-function Dj(a){return typeof a==Eq&&a>0}
-function tk(b,a){return b.charCodeAt(a)}
-function rd(b,a){return b.appendChild(a)}
-function Md(a,b){return a!=null&&Id(a,b)}
-function jg(c,a,b){return a.replace(c,b)}
-function yk(b,a){return b.lastIndexOf(a)}
-function Go(a,b){return Kd(Bi(a.b,b),30)}
-function ic(a){return Nd(a)?Kc(Ld(a)):Kp}
-function hc(a){return a==null?null:a.name}
-function ho(){this.b=new so;this.c=0}
-function fb(a){this.b=a;this.c=new kn}
-function vb(a){this.c=a;this.b=new ho}
-function pp(){this.b=new kn;this.c=new Ri}
-function go(a){if(a.c==0){throw new Ao}}
-function mo(a){if(!a.d){throw new Vj}}
-function fn(a,b){bm(b,a.c);return a.b[b]}
-function mp(a,b){ip();a['__gwtex_wrap']=b}
-function ep(a,b){for(p in b){a[p]=b[p]}}
-function Fk(c,a,b){return c.substr(a,b-a)}
-function gj(a,b){return a.b==b.b?0:a.b?1:-1}
-function fc(a){return a==null?null:a.message}
-function ec(a){return Nd(a)?fc(Ld(a)):a+Kp}
-function tc(a,b,c){return a.apply(b,c);var d}
-function zk(c,a,b){return c.lastIndexOf(a,b)}
-function Qk(a){return String.fromCharCode(a)}
-function bd(){var a;a=_c(new jd);dd(a)}
-function wj(){wj=sp;vj=Ad(Pf,wp,14,128,0)}
-function gk(){gk=sp;fk=Ad(Qf,wp,18,256,0)}
-function cb(){cb=sp;fg();ag('DomToSaxParser')}
-function $c(){$c=sp;Error.stackTraceLimit=128}
-function Bg(){Bg=sp;Ag=new Dg(60);new Dg(200)}
-function wh(){nh();xh.call(this,(Xi(),Wi))}
-function Og(a,b){this.c=1;this.b=a;this.d=b}
-function Fb(a,b){this.d=0;this.c=a;this.b=b}
-function no(a,b,c){this.e=a;this.c=c;this.b=b}
-function So(a){this.c=a;this.b=Hq;this.b+='i'}
-function ro(a){a.b.c=a.c;a.c.b=a.b;a.b=a.c=a}
-function Mo(a){a.b=ig(a.d,a.c);return !!a.b}
-function Cj(a){var b=Xf[a.c];a=null;return b}
-function dn(a,b){Cd(a.b,a.c++,b);return true}
-function Pc(){try{null.a()}catch(a){return a}}
-function _n(a,b){new to(b,a.b);++a.c;return true}
-function Zj(a,b){return a.b<b.b?-1:a.b>b.b?1:0}
-function Qo(a,b){return new Oo(a.c,a.b,b.tS())}
-function Ek(b,a){return b.substr(a,b.length-a)}
-function Un(a){this.b=new Si(a.b.e);ql(this,a)}
-function gg(a){fg();this.b=new cg;bg(this.b,a)}
-function mc(a){var b;return b=a,Od(b)?b.cZ:de}
-function nc(a){var b;return b=a,Od(b)?b.hC():yc(b)}
-function ni(a){var b;b=new Dl(a);return new Cm(a,b)}
-function fh(){fh=sp;new hh(null);eh=new hh(Jp)}
-function Fd(){Fd=sp;Dd=[];Ed=[];Gd(new vd,Dd,Ed)}
-function Rg(){Rg=sp;Qg=new Ro('[\\?\\!\\.\\-\\:]+')}
-function fj(){fj=sp;dj=new hj(false);ej=new hj(true)}
-function Rm(a){var b;b=Kd(km(a.b.b),27).Z();return b}
-function Qn(a,b){var c;c=Gi(a.b,b,a);return c==null}
-function Cn(a,b,c){var d;d=xd(a,b,c);Dn(d,a,b,c,-b)}
-function lc(a,b){var c;return c=a,Od(c)?c.eQ(b):c===b}
-function Mc(a,b){a.length>=b&&a.splice(0,b);return a}
-function Hc(a,b){!a&&(a=[]);a[a.length]=b;return a}
-function Vf(a){if(Md(a,23)){return a}return new dc(a)}
-function Bm(a){var b;b=new Il(a.c.b);return new Hm(b)}
-function Lm(a){var b;b=new Il(a.c.b);return new Sm(b)}
-function uh(a,b){if(b==null||b.length==0){return}a.w=b}
-function pd(a,b){a.b=a.b.substr(0,0-0)+Kp+Ek(a.b,b)}
-function Nd(a){return a!=null&&a.tM!=sp&&!Id(a,1)}
-function Qi(a,b){return Pd(a)===Pd(b)||a!=null&&lc(a,b)}
-function Bo(a,b){return Pd(a)===Pd(b)||a!=null&&lc(a,b)}
-function em(a,b){throw new Xj('Index: '+a+', Size: '+b)}
-function rm(a,b){if(a.d==-1){throw new Vj}a.b.cb(a.d,b)}
-function qk(a,b){this.b=iq;this.e=a;this.c=b;this.d=-1}
-function bp(){this.c=new Ri;this.b=new Ri;this.d=new Ri}
-function Xk(){if(Sk==256){Rk=Tk;Tk={};Sk=0}++Sk}
-function P(a){if(!O){O=true;ip();Vo(hp,Sd,a);Q(a)}}
-function Y(a){if(!X){X=true;ip();Vo(hp,Ud,a);Z(a)}}
-function Ib(a){if(!Hb){Hb=true;ip();Vo(hp,ae,a);Jb(a)}}
-function qh(a){if(!a.q){bl(a.x,32);bl(a.u,32);a.q=true}}
-function wi(a){a.b=[];a.f={};a.d=false;a.c=null;a.e=0}
-function ad(a,b){var c;c=cd(a,Nd(b.c)?Ld(b.c):null);dd(c)}
-function Ad(a,b,c,d,e){var f;f=zd(e,d);Bd(a,b,c,f);return f}
-function Mb(a,b){var c;c=new Ob(a);jb(new kb(c),b);return c.b}
-function fo(a){var b;go(a);--a.c;b=a.b.c;ro(b);return b.d}
-function bl(a,b){od(a.b,String.fromCharCode(b));return a}
-function Kd(a,b){if(a!=null&&!Jd(a,b)){throw new Hj}return a}
-function uk(a,b){if(!Md(b,1)){return false}return String(a)==b}
-function Ck(c,a,b){b=Jk(b);return c.replace(RegExp(a),b)}
-function Bk(c,a,b){b=Jk(b);return c.replace(RegExp(a,Hq),b)}
-function lp(a,b,c,d,e,f){ip();return $o(hp,a,b,c,d,e,f)}
-function Mk(a,b){a=String(a);if(a==b){return 0}return a<b?-1:1}
-function No(a,b){a.b=null;a.d.lastIndex=0;return jg(a.d,a.c,b)}
-function Nn(a,b){var c,d;d=a.c;for(c=0;c<d;++c){jn(a,c,b[c])}}
-function op(a,b){var c;Gi(a.c,b,ek(a.b.c));c=new rp;dn(a.b,c)}
-function cn(a,b,c){(b<0||b>a.c)&&em(b,a.c);wn(a.b,b,0,c);++a.c}
-function Oo(a,b,c){this.d=new RegExp(a,b);this.c=c;this.b=null}
-function pb(a){this.c=new yb(a);this.b=new kn;this.e=new kn}
-function Ob(a){this.c=false;this.d=new yb(a);this.b=new kn}
-function Io(){this.b=new Ri;this.c=new Ko;Gi(this.b,Kp,this.c)}
-function yb(a){this.c=new mm(a);a.c==0||(this.b=Ld(km(this.c)))}
-function dc(a){bc.call(this);this.c=a;this.b=Kp;ad(new jd,this)}
-function ml(a){cc.call(this,'String index out of range: '+a)}
-function qm(a){if(a.c<=0){throw new Ao}return a.b.ab(a.d=--a.c)}
-function lm(a){if(a.d<0){throw new Vj}a.e.bb(a.d);a.c=a.d;a.d=-1}
-function to(a,b){this.d=a;this.b=b;this.c=b.c;b.c.b=this;b.c=this}
-function Ii(a,b){var c;c=a.c;a.c=b;if(!a.d){a.d=true;++a.e}return c}
-function sg(a,b){if(b!=a.c){a.c=b;return true}else{return false}}
-function Eo(a,b){if(Go(a,b.b.b)){return false}Fo(a,b);return true}
-function mb(a,b){while(a.b.c==1&&a.c!=b){a=Kd(Wm(a.b,0),4)}return a}
-function jn(a,b,c){var d;d=(bm(b,a.c),a.b[b]);Cd(a.b,b,c);return d}
-function yd(a,b){var c,d;c=a;d=zd(0,b);Bd(c.cZ,c.cM,c.qI,d);return d}
-function Bd(a,b,c,d){Fd();Hd(d,Dd,Ed);d.cZ=a;d.cM=b;d.qI=c;return d}
-function Hd(a,b,c){Fd();for(var d=0,e=b.length;d<e;++d){a[b[d]]=c[d]}}
-function wk(a,b,c,d){var e;for(e=0;e<b;++e){c[d++]=a.charCodeAt(e)}}
-function wc(a,b,c){var d;d=uc();try{return tc(a,b,c)}finally{xc(d)}}
-function xn(a,b,c,d){Array.prototype.splice.apply(a,[b,c].concat(d))}
-function el(a,b){od(a.b,String.fromCharCode.apply(null,b));return a}
-function Fn(a,b,c){var d;bm(b,a.b.length);d=a.b[b];Cd(a.b,b,c);return d}
-function hn(a,b){var c;c=(bm(b,a.c),a.b[b]);vn(a.b,b,1);--a.c;return c}
-function Bj(a,b){var c;c=new yj;c.e=a+b;Dj(0)&&Ej(0,c);c.b=2;return c}
-function ap(a,b){var c=[a];for(i=0;i<b.length;i++)c.push(b[i]);return c}
-function Yo(a,b){var c=a[b];var d=0;for(k in c)d=Math.max(d,k);return d}
-function td(a){var b=a.parentNode;(!b||b.nodeType!=1)&&(b=null);return b}
-function Ld(a){if(a!=null&&(a.tM==sp||Id(a,1))){throw new Hj}return a}
-function km(a){if(a.c>=a.e.M()){throw new Ao}return a.e.ab(a.d=a.c++)}
-function rg(a){if(a.k==0){a.k=a.i;a.n=1}a.s=a.k/a.n;a.e=a.i==0?0:a.j/a.i}
-function gc(a){return a==null?cq:Nd(a)?hc(Ld(a)):Md(a,1)?dq:mc(a).e}
-function yi(a,b){return b==null?a.d:Md(b,1)?Fi(a,Kd(b,1)):Ei(a,b,a.P(b))}
-function Bi(a,b){return b==null?a.c:Md(b,1)?Di(a,Kd(b,1)):Ci(a,b,a.P(b))}
-function Qd(a){return ~~Math.max(Math.min(a,2147483647),-2147483648)}
-function Ac(){return $wnd.setTimeout(function(){pc!=0&&(pc=0);sc=-1},10)}
-function xc(a){a&&Fc((Dc(),Cc));--pc;if(a){if(sc!=-1){zc(sc);sc=-1}}}
-function Gd(a,b,c){var d=0,e;for(var f in a){if(e=a[f]){b[d]=f;c[d]=e;++d}}}
-function Ji(e,a,b){var c,d=e.f;a=Yp+a;a in d?(c=d[a]):++e.e;d[a]=b;return c}
-function Aj(a,b,c,d){var e;e=new yj;e.e=a+b;Dj(c)&&Ej(c,e);e.d=d;return e}
-function xd(a,b,c){var d,e;d=a;e=d.slice(b,c);Bd(d.cZ,d.cM,d.qI,e);return e}
-function Rb(a,b,c){var d,e;e=new So(b);d=new Oo(e.c,e.b,a);return No(d,c)}
-function fl(a,b,c,d){var e;od(a.b,(e=c+d,Hk(b.length,c,e),Kk(b,c,e)));return a}
-function gn(a,b,c){for(;c<a.c;++c){if(Bo(b,a.b[c])){return c}}return -1}
-function Kk(a,b,c){a=a.slice(b,c);return String.fromCharCode.apply(null,a)}
-function cd(a,b){var c;c=Wc(a,b);return c.length==0?(new Qc).E(b):Mc(c,1)}
-function oh(a,b){var c;c=Kd(co(a.n),24);if(!c){c=new ho;fo(a.n);bo(a.n,c)}bo(c,b)}
-function sm(a,b){var c;this.b=a;this.e=a;c=a.M();(b<0||b>c)&&em(b,c);this.c=b}
-function Fc(a){var b,c;if(a.c){c=null;do{b=a.c;a.c=null;c=Ic(b,c)}while(a.c);a.c=c}}
-function Ec(a){var b,c;if(a.b){c=null;do{b=a.b;a.b=null;c=Ic(b,c)}while(a.b);a.b=c}}
-function lo(a){if(a.c==a.e.b){throw new Ao}a.d=a.c;a.c=a.c.b;++a.b;return a.d.d}
-function xb(a,b){if(b!=a.b)return false;a.b=jm(a.c)?Ld(km(a.c)):null;return true}
-function vk(b,a){if(a==null)return false;return b==a||b.toLowerCase()==a.toLowerCase()}
-function vc(b){return function(){try{return wc(b,this,arguments)}catch(a){throw a}}}
-function Gi(a,b,c){return b==null?Ii(a,c):Md(b,1)?Ji(a,Kd(b,1),c):Hi(a,b,c,~~nc(b))}
-function Il(a){var b;b=new kn;a.d&&dn(b,new Ql(a));vi(a,b);ui(a,b);this.b=new mm(b)}
-function gl(a){var b;b=a.b.b.length;0<b?(pd(a.b,b),a):0>b&&el(a,Ad(Of,wp,-1,-b,1))}
-function Fo(a,b){var c,d;c=b.b.b;d=Fk(c,0,hk(0,yk(c,Ok(46))));Ho(a,d);Gi(a.b,b.b.b,b)}
-function Ho(a,b){var c,d;c=Kd(Bi(a.b,b),30);if(!c){d=new gg(b);Fo(a,d);return d}return c}
-function ql(a,b){var c,d;d=b.T();c=false;while(d.W()){a.Q(d.X())&&(c=true)}return c}
-function Vb(a,b){var c,d;d=new So(b);c=new Oo(d.c,d.b,a);return c.b=ig(c.d,c.c),!!c.b}
-function Zg(){Zg=sp;new _g(false,0);new _g(true,0);Yg=new _g(true,150)}
-function pg(){pg=sp;ng=new Sn;og=new ug(Kp,ng,0,0,0,0,-1);new ug(Kp,ng,0,0,0,0,2147483647)}
-function Dh(){Dh=sp;Ah=new Fh;yh=new Lh;zh=new Qh;Ch=new Vh;Bh=new $h;new Ro('([\\+\\-]?)([0-9])')}
-function _c(a){var b;b=Mc(cd(a,Pc()),3);b.length==0&&(b=Mc((new Qc).C(),1));return b}
-function lb(a){var b;for(b=a.parentNode;!!b&&b.nodeType!=9;a=b,b=b.parentNode){}return a}
-function Sb(a){var b;for(b=0;b<a.length;++b){if(!Tb(uj(a.charCodeAt(b))))return false}return true}
-function rl(a,b){var c;while(a.W()){c=a.X();if(b==null?c==null:lc(b,c)){return a}}return null}
-function uj(a){var b;if(a<128){b=(wj(),vj)[a];!b&&(b=vj[a]=new oj(a));return b}return new oj(a)}
-function Hk(a,b,c){if(b<0){throw new ml(b)}if(c<b){throw new ml(c-b)}if(c>a){throw new ml(c)}}
-function Kh(a){if(--a.f==0){if(a.k==0){qh(a);dl(a.x,Bq);bl(a.x,32);a.q=true}}return false}
-function en(a,b){var c,d;c=b.U();d=c.length;if(d==0){return false}xn(a.b,a.c,0,c);a.c+=d;return true}
-function zj(a,b,c){var d;d=new yj;d.e=a+b;Dj(c!=0?-c:0)&&Ej(c!=0?-c:0,d);d.b=4;d.d=Ve;return d}
-function Db(a){var b,c;c=Kp;for(b=a.c-1;b>=0;--b){c+=(bm(b,a.c),Kd(a.b[b],1));b>0&&(c+=Tp)}return c}
-function jb(a,b){var c,d;if(!a.b.A(b))return;c=b.childNodes;for(d=0;d<c.length;++d){jb(a,c[d])}a.b.z(b)}
-function qg(a,b){var c,d,e;if(b==null){return}!a.d&&(a.d=new Sn);for(d=0,e=b.length;d<e;++d){c=b[d];Qn(a.d,c)}}
-function Nj(a,b){if(isNaN(a)){return isNaN(b)?0:1}else if(isNaN(b)){return -1}return a<b?-1:a>b?1:0}
-function _i(a){$i();var b;b=No(Qo(Zi,a),'\u2063');b=Bk(b,'[ \u2063]+',Zp);b=Ub(b);return Dk(b,'[ ]+',0)}
-function Wk(a){Uk();var b=Yp+a;var c=Tk[b];if(c!=null){return c}c=Rk[b];c==null&&(c=Vk(a));Xk();return Tk[b]=c}
-function vi(e,a){var b=e.f;for(var c in b){if(c.charCodeAt(0)==58){var d=new Vl(e,c.substring(1));a.Q(d)}}}
-function ag(a){var b,c,d;c=(!Do&&(Do=new Io),Do);b=Kd(Bi(c.b,a),30);if(!b){d=new hg(a);Eo(c,d);return d}return b}
-function ub(a){var b,c,d;d=a.c.cloneNode(false);for(c=eo(a.b,0);c.c!=c.e.b;){b=Kd(lo(c),4);rd(d,ub(b))}return d}
-function $b(a){var b,c,d;c=Ad(Sf,wp,21,a.length,0);for(d=0,b=a.length;d<b;++d){if(!a[d]){throw new kk}c[d]=a[d]}}
-function Wc(a,b){var c,d,e;e=b&&b.stack?b.stack.split(gq):[];for(c=0,d=e.length;c<d;++c){e[c]=a.D(e[c])}return e}
-function ek(a){var b,c;if(a>-129&&a<128){b=a+128;c=(gk(),fk)[b];!c&&(c=fk[b]=new $j(a));return c}return new $j(a)}
-function zi(e,a){var b=e.f;for(var c in b){if(c.charCodeAt(0)==58){var d=b[c];if(e.O(a,d)){return true}}}return false}
-function qj(a){if(a>=48&&a<58){return a-48}if(a>=97&&a<97){return a-97+10}if(a>=65&&a<65){return a-65+10}return -1}
-function Ai(a,b){if(a.d&&Qi(a.c,b)){return true}else if(zi(a,b)){return true}else if(xi(a,b)){return true}return false}
-function Mg(){Mg=sp;Kg=new Og(false,false);new Og(false,true);new Og(true,false);Lg=new Og(true,true)}
-function xh(a){this.x=new hl;this.u=new hl;this.t=new kn;this.c=new Sn;this.n=new ho;this.e=new ho;this.r=a}
-function ug(a,b,c,d,e,f,g){pg();this.r=a;this.b=b;this.i=c;this.j=d;this.k=e;this.n=f;this.p=g;this.o=g;rg(this)}
-function Bn(a,b,c,d,e,f,g){var h;h=c;while(f<g){h>=d||b<c&&Kd(a[b],16).cT(a[h])<=0?Cd(e,f++,a[b++]):Cd(e,f++,a[h++])}}
-function An(a,b,c){var d,e,f;for(d=b+1;d<c;++d){for(e=d;e>b&&Kd(a[e-1],16).cT(a[e])>0;--e){f=a[e];Cd(a,e,a[e-1]);Cd(a,e-1,f)}}}
-function Zo(a,b,c,d){var e,f;f=d?a.d:a.b;e=Ld(!b?f.c:Ci(f,b,~~yc(b)));!e?(e=c):ep(e,c);!b?Ii(f,e):Hi(f,b,e,~~yc(b))}
-function sh(a,b,c){var d;d=Kd(Bi(a.r,b),10);d?(a.d=d.H(a,b,c)|a.d):(a.d=true);(!d||d.G())&&--a.s;a.d&&th(a);fo(a.n)}
-function vh(a,b,c,d){var e;bo(a.n,null);e=Kd(Bi(a.r,b),10);if(e){e.G()&&++a.s;a.d=e.I(a,b,c,d)|a.d}else{++a.s;a.d=true}a.o=b}
-function gwtOnLoad(b,c,d,e){$moduleName=c;$moduleBase=d;if(b)try{Gp(Uf)()}catch(a){b(c)}else{Gp(Uf)()}}
-function Ki(a){wi(this);if(a<0){throw new Tj('initial capacity was negative or load factor was non-positive')}}
-function $i(){$i=sp;Zi=new Ro('\\b');new Ro('[\u2063]*([\\"\'\\.,\\!\\@\\-\\:\\;\\$\\?\\(\\)/])[\u2063]*')}
-function Vi(a,b,c){Gi(a,b.toUpperCase(),c);Gi(a,b.toLowerCase(),c);b==null?Ii(a,c):b!=null?Ji(a,b,c):Hi(a,null,c,~~Wk(null))}
-function mi(a,b){var c,d,e;for(d=new Il(a.K().b);jm(d.b);){c=Kd(km(d.b),27);e=c.Y();if(b==null?e==null:lc(b,e)){return c}}return null}
-function Ci(h,a,b){var c=h.b[b];if(c){for(var d=0,e=c.length;d<e;++d){var f=c[d];var g=f.Y();if(h.O(a,g)){return f.Z()}}}return null}
-function Ei(h,a,b){var c=h.b[b];if(c){for(var d=0,e=c.length;d<e;++d){var f=c[d];var g=f.Y();if(h.O(a,g)){return true}}}return false}
-function uc(){var a;if(pc!=0){a=(new Date).getTime();if(a-rc>2000){rc=a;sc=Ac()}}if(pc++==0){Ec((Dc(),Cc));return true}return false}
-function Ub(a){if(a.length==0||a[0]>Zp&&a[a.length-1]>Zp){return a}return a.replace(/^[\u0000-\u0020]*|[\u0000-\u0020]*$/g,Kp)}
-function Gk(c){if(c.length==0||c[0]>Zp&&c[c.length-1]>Zp){return c}var a=c.replace(/^(\s*)/,Kp);var b=a.replace(/\s*$/,Kp);return b}
-function ui(h,a){var b=h.b;for(var c in b){var d=parseInt(c,10);if(c==d){var e=b[d];for(var f=0,g=e.length;f<g;++f){a.Q(e[f])}}}}
-function Wm(b,c){var d;d=eo(b,c);try{return lo(d)}catch(a){a=Vf(a);if(Md(a,28)){throw new Xj("Can't get element "+c)}else throw a}}
-function Tb(a){var b;b=a.b;return 9<=b&&b<=13||28<=b&&b<=32||b==5760||b==6158||8192<=b&&b<=8198||8232<=b&&b<=8233||b==8287||b==12288}
-function ob(a){var b;for(b=0;b<a.b.c;++b){if(fn(a.e,b)==null){jn(a.e,b,new vb(Ld(fn(a.b,b))));tb(Kd(fn(a.e,b-1),4),Kd(fn(a.e,b),4))}}}
-function db(a){cb();var b,c,d,e;b=new pp;e=a.attributes;for(c=0;c<e.length;++c){d=e[c];op(b,(d.nodeName,d.nodeName),d.nodeValue)}return b}
-function ch(a){var b,c,d,e;b=false;d=a.b;for(c=new sm(d,d.c);c.c>0;){e=Kd(qm(c),8);if(e.c){if(!!e.d&&Rn(e.d,xq)){sg(e,false);b=true}else{break}}}return b}
-function gh(a,b){var c,d,e,f;f=b.b;c=false;for(d=new mm(f);d.c<d.e.M();){e=Kd(km(d),8);if(!e.c&&(a.b==null||!(!!e.d&&Rn(e.d,Jp)))){lm(d);c=true}}return c}
-function Oc(b){var c=Kp;try{for(var d in b){if(d!='name'&&d!='message'&&d!='toString'){try{c+='\n '+d+Qp+b[d]}catch(a){}}}}catch(a){}return c}
-function gp(a,b){var c=a[b];var d=c==null?cq:typeof c;if(d==Sp){return Object.prototype.toString.call(c)==Jq||typeof c.length==Eq?'array':d}return d}
-function $l(a,b){var c,d;for(c=0,d=a.b.length;c<d;++c){if(b==null?(bm(c,a.b.length),a.b[c])==null:lc(b,(bm(c,a.b.length),a.b[c]))){return c}}return -1}
-function Ic(b,c){var d,e,f;for(d=0,e=b.length;d<e;++d){f=b[d];try{f[1]?f[0].db()&&(c=Hc(c,f)):f[0].db()}catch(a){a=Vf(a);if(!Md(a,23))throw a}}return c}
-function Jk(a){var b;b=0;while(0<=(b=a.indexOf('\\',b))){a.charCodeAt(b+1)==36?(a=a.substr(0,b-0)+'$'+Ek(a,++b)):(a=a.substr(0,b-0)+Ek(a,++b))}return a}
-function eo(a,b){var c,d;(b<0||b>a.c)&&em(b,a.c);if(b>=~~a.c>>1){d=a.b;for(c=a.c;c>b;--c){d=d.c}}else{d=a.b.b;for(c=0;c<b;++c){d=d.b}}return new no(a,b,d)}
-function dp(a,b){var c;if(Ve==b){return true}if(Jf==b&&Md(a,31)){return true}if(a!=null){for(c=mc(a);!!c&&c!=Ve;c=c.d){if(c==b){return true}}}return false}
-function Ak(d,a,b){var c;if(a<256){c=ck(a);c='\\x'+'00'.substring(c.length)+c}else{c=String.fromCharCode(a)}return d.replace(RegExp(c,Hq),String.fromCharCode(b))}
-function Sg(a,b,c){var d,e,f,g;g=Dk(b,c,0);if(g.length==1){return}for(d=0;d<g.length;++d){f=g[d];if(f.indexOf(rq)!=-1){continue}e=Dk(f,sq,0).length;e>=4&&Qn(a,f)}}
-function Ej(a,b){var c;b.c=a;if(a==2){c=String.prototype}else{if(a>0){var d=Cj(b);if(d){c=d.prototype}else{d=Xf[a]=function(){};d.cZ=b;return}}else{return}}c.cZ=b}
-function mk(){mk=sp;lk=Bd(Of,wp,-1,[48,49,50,51,52,53,54,55,56,57,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122])}
-function ck(a){var b,c,d;b=Ad(Of,wp,-1,8,1);c=(mk(),lk);d=7;if(a>=0){while(a>15){b[d--]=c[a&15];a>>=4}}else{while(d>0){b[d--]=c[a&15];a>>=4}}b[d]=c[a&15];return Kk(b,d,8)}
-function sl(a){var b,c,d,e;d=new Zk;b=null;d.b.b+=jq;c=a.T();while(c.W()){b!=null?(nd(d.b,b),d):(b=Cq);e=c.X();nd(d.b,e===a?'(this Collection)':Kp+e)}d.b.b+=kq;return d.b.b}
-function M(a){var b,c,d,e,f,g;g=a;c=g.getElementsByTagName(Lp);for(d=0;d<c.length;++d){f=c[d];sd(f,f.href)}b=g.getElementsByTagName(Mp);for(d=0;d<b.length;++d){e=b[d];ud(e,e.src)}}
-function zd(a,b){var c=new Array(b);if(a==3){for(var d=0;d<b;++d){var e=new Object;e.l=e.m=e.h=0;c[d]=e}}else if(a>0){var e=[null,0,false][a];for(var d=0;d<b;++d){c[d]=e}}return c}
-function xi(l,a){var b=l.b;for(var c in b){var d=parseInt(c,10);if(c==d){var e=b[d];for(var f=0,g=e.length;f<g;++f){var h=e[f];var j=h.Z();if(l.O(a,j)){return true}}}}return false}
-function Eg(a,b,c){var d;b.e<=0.333333?a.e<=0.555556?b.i<=16?c.i<=15?a.i<=4?(d=false):(d=true):(d=true):(d=true):b.i<=40?c.i<=17?(d=false):(d=true):(d=true):(d=false);return sg(b,d)}
-function Xo(a){var b,c,d,e,f;f=Dk(a,'\\.',0);e=$wnd;b=0;for(c=f.length-1;b<c;++b){if(!uk(f[b],'client')){e[f[b]]||(e[f[b]]={});e=e!=null?e[f[b]]:null}}d=e!=null?e[f[b]]:null;return d}
-function Ig(a,b,c){var d,e,f,g;d=0;while(d<b&&Hg(a.charCodeAt(d))){++d}if(d!=0){for(f=0,g=c.length;f<g;++f){e=c[f];if(!(d<0||d>=a.length)&&a.indexOf(e,d)==d){return true}}}return false}
-function $f(a){return $stats({moduleName:$moduleName,sessionId:$sessionId,subSystem:'startup',evtGroup:'moduleStartup',millis:(new Date).getTime(),type:'onModuleLoadStart',className:a})}
-function um(a,b,c){this.d=a;this.b=b;this.c=c-b;if(b>c){throw new Tj(Iq+b+' > toIndex: '+c)}if(b<0){throw new Xj(Iq+b+' < 0')}if(c>a.c){throw new Xj('toIndex: '+c+' > wrapped.size() '+a.c)}}
-function Jc(a){var b,c,d;d=Kp;a=Gk(a);b=a.indexOf(eq);c=a.indexOf('function')==0?8:0;if(b==-1){b=xk(a,Ok(64));c=a.indexOf('function ')==0?9:0}b!=-1&&(d=Gk(a.substr(c,b-c)));return d.length>0?d:fq}
-function Cg(a,b){var c,d,e,f,g,h;d=false;h=0;f=false;for(g=new mm(b.b);g.c<g.e.M();){c=Kd(km(g),8);e=!!c.d&&Rn(c.d,qq);c.c&&(h+=c.s>=9?c.i:0);e&&h>=a.b&&(f=true);if(f){d=true;sg(c,false)}}return d}
-function Ok(a){var b,c;if(a>=65536){b=55296+(~~(a-65536)>>10&1023)&65535;c=56320+(a-65536&1023)&65535;return String.fromCharCode(b)+String.fromCharCode(c)}else{return String.fromCharCode(a&65535)}}
-function Hi(l,a,b,c){var d=l.b[c];if(d){for(var e=0,f=d.length;e<f;++e){var g=d[e];var h=g.Y();if(l.O(a,h)){var j=g.Z();g.$(b);return j}}}else{d=l.b[c]=[]}var g=new vo(a,b);d.push(g);++l.e;return null}
-function Vk(a){var b,c,d,e;b=0;d=a.length;e=d-4;c=0;while(c<e){b=a.charCodeAt(c+3)+31*(a.charCodeAt(c+2)+31*(a.charCodeAt(c+1)+31*(a.charCodeAt(c)+31*b)))|0;c+=4}while(c<d){b=b*31+tk(a,c++)}return b|0}
-function Cd(a,b,c){if(c!=null){if(a.qI>0&&!Jd(c,a.qI)){throw new bj}else if(a.qI==-1&&(c.tM==sp||Id(c,1))){throw new bj}else if(a.qI<-1&&!(c.tM!=sp&&!Id(c,1))&&!Jd(c,-a.qI)){throw new bj}}return a[b]=c}
-function Dn(a,b,c,d,e){var f,g,h,j;f=d-c;if(f<7){An(b,c,d);return}h=c+e;g=d+e;j=h+(~~(g-h)>>1);Dn(b,a,h,j,-e);Dn(b,a,j,g,-e);if(Kd(a[j-1],16).cT(a[j])<=0){while(c<d){Cd(b,c++,a[h++])}return}Bn(a,h,j,g,b,c,d)}
-function Wo(a,b){var c=[];for(i=0;i<a-1;i++)c.push(b[i]);var d=b.length;var e=a-1;if(d>=a&&Object.prototype.toString.apply(b[e])===Jq){c.push(b[e])}else{var f=[];for(i=e;i<d;i++)f.push(b[i]);c.push(f)}return c}
-function Yf(a,b,c){var d=Xf[a];if(d&&!d.cZ){_=d.prototype}else{!d&&(d=Xf[a]=function(){});_=d.prototype=b<0?{}:Zf(b);_.cM=c}for(var e=3;e<arguments.length;++e){arguments[e].prototype=_}if(d.cZ){_.cZ=d.cZ;d.cZ=null}}
-function Tg(a,b){var c,d,e,f,g,h;h=Dk(a,b,0);if(h.length==1){return null}d=0;e=Kp;for(c=0;c<h.length;++c){g=h[c];if(g.indexOf(rq)!=-1){continue}f=Dk(g,sq,0).length;if(f>d||g.length>e.length){d=f;e=g}}return e.length==0?null:Gk(e)}
-function bh(a){var b,c,d,e;b=false;c=2147483647;for(e=new mm(a.b);e.c<e.e.M();){d=Kd(km(e),8);if(d.c&&!!d.d&&Rn(d.d,vq)){c=d.q}else{if(d.q>c&&!!d.d&&Rn(d.d,uq)&&!!d.d&&Rn(d.d,wq)&&d.e==0){sg(d,true);b=true}else{c=2147483647}}}return b}
-function On(a){var b,c,d,e,f,g,h;if(a){for(e=0,d=a.b.length-1;e<d;++e,--d){h=(bm(e,a.b.length),a.b[e]);Fn(a,e,(bm(d,a.b.length),a.b[d]));Fn(a,d,h)}}else{b=new sm(null,0);f=new sm(null,null.b.length);while(b.c<f.c-1){c=km(b);g=qm(f);rm(b,g);rm(f,c)}}}
-function ah(a){var b,c,d,e;b=false;c=-1;for(e=new mm(a.b);e.c<e.e.M();){d=Kd(km(e),8);if(d.c&&!!d.d&&Rn(d.d,vq)){c=d.q;break}}if(c==-1){return false}for(e=new mm(a.b);e.c<e.e.M();){d=Kd(km(e),8);if(!d.c){if(d.i>=100&&d.q==c){sg(d,true);b=true}}}return b}
-function Fg(a){var b,c,d,e,f,g;g=a.b;d=new sm(g,0);if(d.c>=d.e.M()){return false}f=(pg(),og);b=Kd(km(d),8);e=d.c<d.e.M()?Kd(km(d),8):og;c=Eg(f,b,e)|false;if(e!=og){while(d.c<d.e.M()){f=b;b=e;e=Kd(km(d),8);c=Eg(f,b,e)|c}f=b;b=e;e=og;c=Eg(f,b,e)|c}return c}
-function ph(a,b){var c,d,e,f,g,h;for(d=eo(a.e,0);d.c!=d.e.b;){c=Kd(lo(d),18);if(c){!b.d&&(b.d=new Tn);Qn(b.d,'font-'+c);break}}for(f=eo(a.n,0);f.c!=f.e.b;){e=Kd(lo(f),24);if(e){for(h=eo(e,0);h.c!=h.e.b;){g=Kd(lo(h),9);!!g&&(qg(b,g.b),undefined)}}}dn(a.t,b)}
-function _o(a,b,c,d,e){var f,g,h,j,l,m,n,o,q;n=Ld(!c?b.c:Ci(b,c,~~yc(c)))[d][e.length];h=null;o=null;f=null;for(g=0,j=!n?0:n.length;g<j;++g){m=n[g];if(fp(m,e)){h=m[0];o=m[1];f=m[2];break}}if(!h){return null}else{e=f?f(a,e):e;l=(q=h.apply(a,e),[o?o(q):q]);return l}}
-function Kj(a){var b,c,d,e;if(a==null){throw new ok(cq)}c=a.length;d=c>0&&a.charCodeAt(0)==45?1:0;for(b=d;b<c;++b){if(qj(a.charCodeAt(b))==-1){throw new ok(Fq+a+Gq)}}e=parseInt(a,10);if(isNaN(e)){throw new ok(Fq+a+Gq)}else if(e<-2147483648||e>2147483647){throw new ok(Fq+a+Gq)}return e}
-function Wg(a){var b,c,d,e,f,g;d=0;g=-1;c=-1;for(f=new mm(a.b);f.c<f.e.M();){e=Kd(km(f),8);if(c==-1&&!!e.d&&Rn(e.d,Jp)){g=d;c=-1}c==-1&&e.c&&(c=d);++d}if(c<=g||g==-1){return false}b=false;for(f=new mm(new um(a.b,g,c));f.c<f.e.M();){e=Kd(km(f),8);!!e.d&&Rn(e.d,uq)&&(b=sg(e,true)|b)}return b}
-function dd(a){var b,c,d,e,f,g,h,j,l;l=Ad(Sf,wp,21,a.length,0);for(e=0,f=l.length;e<f;++e){j=Dk(a[e],hq,0);b=-1;d=iq;if(j.length==2&&j[1]!=null){h=j[1];g=yk(h,Ok(58));c=zk(h,Ok(58),g-1);d=h.substr(0,c-0);if(g!=-1&&c!=-1){Lc(h.substr(c+1,g-(c+1)));b=Lc(Ek(h,g+1))}}l[e]=new qk(j[0],d+Hp+b)}$b(l)}
-function Ug(a,b){var c,d,e,f;if(!a.b){return false}c=false;for(e=new mm(b.b);e.c<e.e.M();){d=Kd(km(e),8);f=d.r.tS();f=Ak(f,160,32);f=Bk(f,tq,Kp);f=Gk(f).toLowerCase();if(Rn(a.b,f)){!d.d&&(d.d=new Tn);Qn(d.d,Jp);c=true;break}f=Gk(No(Qo(Qg,f),Kp));if(Rn(a.b,f)){!d.d&&(d.d=new Tn);Qn(d.d,Jp);c=true;break}}return c}
-function $o(a,b,c,d,e,f,g){var h,j,l,m,n;j=f?a.d:a.b;if(g){for(m=Yo(Ld(!c?j.c:Ci(j,c,~~yc(c))),d),l=m;l>=1;--l){h=Wo(l,e);n=_o(b,j,c,d,h);if(!n){h=ap(b,h);n=_o(b,j,c,d,h)}if(n){return n}}}else{n=_o(b,j,c,d,e);if(!n){e=ap(b,e);n=_o(b,j,c,d,e)}if(n){return n}}throw new cc("Can't find exported method for given arguments: "+d+Yp+e.length+gq)}
-function Uf(){var a;!!$stats&&$f('com.google.gwt.useragent.client.UserAgentAsserter');a=lg();uk(mq,a)||($wnd.alert('ERROR: Possible problem with your *.gwt.xml module file.\nThe compile time user.agent value (safari) does not match the runtime user.agent value ('+a+'). Expect more errors.\n'),undefined);!!$stats&&$f('com.google.gwt.user.client.DocumentModeAsserter');kg();!!$stats&&$f('com.dom_distiller.client.DomDistiller');bb();ip();new R;new $;new Kb}
-function Dk(n,a,b){var c=new RegExp(a,Hq);var d=[];var e=0;var f=n;var g=null;while(true){var h=c.exec(f);if(h==null||f==Kp||e==b-1&&b>0){d[e]=f;break}else{d[e]=f.substring(0,h.index);f=f.substring(h.index+h[0].length,f.length);c.lastIndex=0;if(g==f){d[e]=f.substring(0,1);f=f.substring(1)}g=f;e++}}if(b==0&&n.length>0){var j=d.length;while(j>0&&d[j-1]==Kp){--j}j<d.length&&d.splice(j,d.length-j)}var l=Ik(d.length);for(var m=0;m<d.length;++m){l[m]=d[m]}return l}
-function fp(a,b){var c,d,e,f,g,h,j,l,m,n;for(e=0,m=b.length;e<m;++e){l=a[e+3];c=gp(b,e);if(uk(c,l)){continue}if(uk('string',l)&&uk(cq,c)){continue}h=uk(Eq,c);f=uk('boolean',c);if(Ve===l){h&&(b[e]=new Mj(b[e]),undefined);f&&(b[e]=(fj(),b[e]?ej:dj),undefined);continue}j=h||f;g=!j&&l!=null&&mc(l)==Le;if(g){n=b[e];if(n==null||dp(n,Kd(l,15))){continue}if(Nd(n)){d=cp(Ld(n));if(d!=null){if(dp(d,Kd(l,15))){b[e]=d;continue}}}}if(uk(Sp,l)&&!h&&!f){continue}return false}return true}
-function Bb(){var a,b,c,d,e,f;c=$wnd.location.pathname;f=Dk(c,Tp,0);On(new Gn(f));a=new kn;for(b=0;b<f.length;++b){e=f[b];if(e.indexOf(Up)!=-1){d=Dk(e,Vp,0)[1];Vb(d,'[^a-zA-Z]')||(e=Dk(e,Vp,0)[0])}e=Rb(e,',00',Kp);b<2&&(e=Rb(e,'((_|-)?p[a-z]*|(_|-))[0-9]{1,2}$',Kp));if(!e.length)continue;if(b<2&&Vb(e,'^\\d{1,2}$'))continue;if(b==0&&vk(e,'index'))continue;if(b<2&&e.length<3&&!Vb(f[0],'[a-z]')){continue}Cd(a.b,a.c++,e)}return $wnd.location.protocol+'//'+$wnd.location.host+Tp+Db(a)}
-function rh(a,b,c,d){var e,f,g,h,j;++a.v;if(a.d){th(a);a.d=false}if(a.k!=0){return}j=false;g=false;if(d==0){return}f=c+d;for(h=c;h<f;++h){Tb(uj(b[h]))&&(b[h]=32)}while(c<f){e=b[c];if(e==32){j=true;++c;--d}else{break}}while(d>0){e=b[c+d-1];if(e==32){g=true;--d}else{break}}if(d==0){if(j||g){if(!a.q){bl(a.u,32);bl(a.x,32)}a.q=true}else{a.q=false}return}if(j){if(!a.q){bl(a.u,32);bl(a.x,32)}}a.b==-1&&(a.b=a.s);fl(a.u,b,c,d);fl(a.x,b,c,d);if(g){bl(a.u,32);bl(a.x,32)}a.q=g;Qn(a.c,ek(a.v))}
+function mc(){kc(this)}
+function tc(){rc(this)}
+function Ac(){yc(this)}
+function Wd(){Ud(this)}
+function Nm(){sm(this)}
+function gp(){_o(this)}
+function kr(){br(this)}
+function Md(){return}
+function Zj(){new kr}
+function Yj(a,b){a.b=b}
+function ok(a,b){a.q=b}
+function Bg(a,b){a.b+=b}
+function Cg(a,b){a.b+=b}
+function Dg(a,b){a.b+=b}
+function Dp(a){this.b=a}
+function Qp(a){this.b=a}
+function nb(a){this.b=a}
+function yk(a){this.b=a}
+function cl(a){this.b=a}
+function el(a){this.b=a}
+function $l(a){this.b=a}
+function dn(a){this.b=a}
+function ln(a){this.b=a}
+function Kn(a){this.b=a}
+function Yn(a){this.b=a}
+function Hq(a){this.b=a}
+function Sq(a){this.b=a}
+function mq(a){this.e=a}
+function Gr(a){this.b=a}
+function _r(a){this.b=a}
+function Kg(a,b){a.src=b}
+function Hg(b,a){b.href=a}
+function _o(a){a.b=new Fg}
+function Yo(){this.b=new Fg}
+function Fs(){this.b=new Nm}
+function Kd(){Kd=nu;new Nm}
+function ak(){ak=nu;new Zj}
+function zd(){xd();return td}
+function Pe(){Ne();return He}
+function gu(a){au();return a}
+function tr(a,b){a.length=b}
+function Lc(a,b){Os(a.b,b)}
+function eu(a,b){au();a[Jw]=b}
+function au(){au=nu;_t=new Vt}
+function Sf(){Sf=nu;Rf=new Vf}
+function Tm(){Tm=nu;Sm=new Um}
+function I(){I=nu;ak();Xj(Ku)}
+function Zm(){qf.call(this)}
+function Fn(){qf.call(this)}
+function Tn(){qf.call(this)}
+function jo(){qf.call(this)}
+function mt(){qf.call(this)}
+function rf(a){pf.call(this,a)}
+function Rn(a){rf.call(this,a)}
+function Vn(a){rf.call(this,a)}
+function np(a){rf.call(this,a)}
+function no(a){Rn.call(this,a)}
+function Om(a){Gm.call(this,a)}
+function Te(a){this.b=new ke(a)}
+function Gs(){this.b=new Om(2)}
+function Uj(a){return new Sj[a]}
+function nd(a,b){return a.c-b.c}
+function kn(a,b){return a.b-b.b}
+function go(a,b){return a>b?a:b}
+function ho(a,b){return a<b?a:b}
+function dk(b,a){return b.exec(a)}
+function zm(b,a){return b.f[fv+a]}
+function Qr(a,b){return ps(a.b,b)}
+function Es(a,b){return um(a.b,b)}
+function bu(a){au();return Kt(a)}
+function pf(a){qg(ng());this.f=a}
+function Et(a){this.c=a;this.b=Gw}
+function od(a,b){this.b=a;this.c=b}
+function sk(a,b){this.c=a;this.b=b}
+function zs(a){this.d=a;ws(this)}
+function et(){this.b=this.c=this}
+function Wk(a,b){this.b=a;this.c=b}
+function Vp(a,b){this.c=a;this.b=b}
+function Cq(a,b){this.b=a;this.c=b}
+function Mq(a,b){this.b=a;this.c=b}
+function yd(a,b){od.call(this,a,b)}
+function Oe(a,b){od.call(this,a,b)}
+function is(a,b){this.c=a;this.b=b}
+function ht(a,b){this.b=a;this.c=b}
+function It(a,b,c){Cm(a.c,b,c)}
+function vr(a,b,c){a.splice(b,c)}
+function Jn(a,b){return Ln(a.b,b.b)}
+function jq(a){return a.c<a.e.fb()}
+function Zf(a){return bg((ng(),a))}
+function Ck(a){return a>=48&&a<=57}
+function Bm(b,a){return fv+a in b.f}
+function Rs(a){Us(a);return a.b.c.d}
+function fu(a){au();return Tt(_t,a)}
+function hu(a){au();return Ut(_t,a)}
+function ck(a){ak();bk.call(this,a)}
+function wt(){ak();bk.call(this,Mu)}
+function hp(a){ip.call(this,a.tS())}
+function Of(a){$wnd.clearTimeout(a)}
+function wo(b,a){return b.indexOf(a)}
+function dh(a){return a==null?null:a}
+function cb(){cb=nu;ak();Xj(Ku)}
+function To(){To=nu;Qo={};So={}}
+function br(a){a.b=Qg(Mj,vu,0,0,0)}
+function cu(a,b,c){au();Mt(_t,a,b,c)}
+function wr(a,b,c,d){a.splice(b,c,d)}
+function Ps(a,b,c){new ft(b,c);++a.c}
+function Qs(a,b){new ft(b,a.b);++a.c}
+function bp(a,b){Bg(a.b,b);return a}
+function cp(a,b){Cg(a.b,b);return a}
+function bq(a,b){(a<0||a>=b)&&eq(a,b)}
+function Zg(a,b){return a.cM&&a.cM[b]}
+function Wt(a){return a&&a.g?a.g:null}
+function $f(a){return parseInt(a)||-1}
+function Ho(a){return Qg(Oj,su,1,a,0)}
+function Mg(a){return Ng(a,0,a.length)}
+function xs(a){return a.b<a.d.b.length}
+function Nf(a){return a.$H||(a.$H=++Ff)}
+function Yg(a,b){return a.cM&&!!a.cM[b]}
+function ch(a){return a.tM==nu||Yg(a,1)}
+function Bn(a){return typeof a==Dw&&a>0}
+function so(b,a){return b.charCodeAt(a)}
+function lr(a){br(this);tr(this.b,a)}
+function ip(a){_o(this);Cg(this.b,a)}
+function Nc(a){this.c=a;this.b=new Vs}
+function gb(a){this.b=a;this.c=new kr}
+function ed(){this.c=false;this.b=new kr}
+function Cd(){this.b=false;this.c=false}
+function Vs(){this.b=new et;this.c=0}
+function qg(){var a;a=og(new yg);sg(a)}
+function Re(){re.call(this,(Ne(),Me))}
+function $s(a){if(!a.d){throw new Tn}}
+function Us(a){if(a.c==0){throw new mt}}
+function fr(a,b){bq(b,a.c);return a.b[b]}
+function Yt(a,b){for(p in b){a[p]=b[p]}}
+function st(a,b){return $g(xm(a.b,b),48)}
+function ah(a,b){return a!=null&&Yg(a,b)}
+function ek(c,a,b){return a.replace(c,b)}
+function Eo(c,a,b){return c.substr(a,b-a)}
+function xo(b,a){return b.lastIndexOf(a)}
+function Gg(b,a){return b.appendChild(a)}
+function xf(a){return bh(a)?Zf(_g(a)):Mu}
+function tf(a){return bh(a)?uf(_g(a)):a+Mu}
+function wf(a){return a==null?null:a.name}
+function uf(a){return a==null?null:a.message}
+function cn(a,b){return a.b==b.b?0:a.b?1:-1}
+function If(a,b,c){return a.apply(b,c);var d}
+function yo(c,a,b){return c.lastIndexOf(a,b)}
+function Po(a){return String.fromCharCode(a)}
+function tn(){tn=nu;sn=Qg(Kj,vu,27,128,0)}
+function fo(){fo=nu;eo=Qg(Lj,vu,34,256,0)}
+function db(){db=nu;ak();Xj('DomToSaxParser')}
+function rl(){il();sl.call(this,(Tm(),Sm))}
+function ku(){this.b=new kr;this.c=new Nm}
+function qs(a,b){this.b=a;this.c=b;this.d=0}
+function Jk(a,b){this.c=1;this.b=a;this.d=b}
+function Fd(a,b,c){this.b=a;this.d=b;this.c=c}
+function _s(a,b,c){this.e=a;this.c=c;this.b=b}
+function Ft(a){this.c=a;this.b=Gw;this.b+='i'}
+function bk(a){ak();this.b=new Zj;Yj(this.b,a)}
+function yt(a){a.b=dk(a.d,a.c);return !!a.b}
+function An(a){var b=Sj[a.d];a=null;return b}
+function cg(){try{null.a()}catch(a){return a}}
+function dr(a,b){Sg(a.b,a.c++,b);return true}
+function Ig(a,b){return a.getAttribute(b)||Mu}
+function Xn(a,b){return a.b<b.b?-1:a.b>b.b?1:0}
+function Dt(a,b){return new Bt(a.c,a.b,b.tS())}
+function Do(b,a){return b.substr(a,b.length-a)}
+function Hs(a){this.b=new Om(a.b.e);pp(this,a)}
+function es(a){this.d=a;this.b=new zs(this.d.b)}
+function ke(a){fe();this.c=new kr;je(this,a,null)}
+function wk(){wk=nu;vk=new yk(60);new yk(200)}
+function al(){al=nu;new cl(null);_k=new cl(Lu)}
+function Vg(){Vg=nu;Tg=[];Ug=[];Wg(new Lg,Tg,Ug)}
+function ng(){ng=nu;Error.stackTraceLimit=128}
+function dt(a){a.b.c=a.c;a.c.b=a.b;a.b=a.c=a}
+function Bf(a){var b;return b=a,ch(b)?b.cZ:Ph}
+function Cf(a){var b;return b=a,ch(b)?b.hC():Nf(b)}
+function im(a){var b;b=new Dp(a);return new Cq(a,b)}
+function jm(a){var b;b=new Dp(a);return new Mq(a,b)}
+function Sr(a,b,c){os(a.b,b);return Tr(a,b.c,c)}
+function Cr(a,b,c){var d;d=Ng(a,b,c);Dr(d,a,b,c,-b)}
+function Ds(a,b){var c;c=Cm(a.b,b,a);return c==null}
+function Os(a,b){new ft(b,a.b);++a.c;return true}
+function Wf(a,b){!a&&(a=[]);a[a.length]=b;return a}
+function _f(a,b){a.length>=b&&a.splice(0,b);return a}
+function zt(a,b){if(!a.b){throw new Tn}return a.b[b]}
+function Eg(a,b){a.b=a.b.substr(0,0-0)+Mu+Do(a.b,b)}
+function pe(a,b){return um(a.c,b)?$g(xm(a.c,b),1):Mu}
+function Af(a,b){var c;return c=a,ch(c)?c.eQ(b):c===b}
+function Bq(a){var b;b=new Ip(a.c.b);return new Hq(b)}
+function Lq(a){var b;b=new Ip(a.c.b);return new Sq(b)}
+function Rq(a){var b;b=$g(kq(a.b.b),45).sb();return b}
+function bh(a){return a!=null&&a.tM!=nu&&!Yg(a,1)}
+function bn(){bn=nu;_m=new dn(false);an=new dn(true)}
+function Mk(){Mk=nu;Lk=new Et('[\\?\\!\\.\\-\\:]+')}
+function Wo(){if(Ro==256){Qo=So;So={};Ro=0}++Ro}
+function O(a){if(!N){N=true;au();It(_t,gh,a);P(a)}}
+function Y(a){if(!X){X=true;au();It(_t,ih,a);Z(a)}}
+function kc(a){if(!jc){jc=true;au();It(_t,mh,a);lc(a)}}
+function yc(a){if(!xc){xc=true;au();It(_t,nh,a);zc(a)}}
+function Ud(a){if(!Td){Td=true;au();It(_t,Dh,a);Vd(a)}}
+function ll(a){if(!a.q){ap(a.x,32);ap(a.u,32);a.q=true}}
+function sm(a){a.b=[];a.f={};a.d=false;a.c=null;a.e=0}
+function po(a,b){this.b=hw;this.e=a;this.c=b;this.d=-1}
+function Rd(a,b,c){this.c=a;this.e=0;this.d=b;this.b=c}
+function Vt(){this.c=new Nm;this.b=new Nm;this.d=new Nm}
+function Ce(){re.call(this,(Ne(),Ke));Cm(this.c,$v,Mu)}
+function dd(a){return $g(jr(a.b,Qg(Oj,su,1,a.b.c,0)),40)}
+function Rr(a,b){return ps(a.b,b)?a.c[$g(b,31).c]:null}
+function Mm(a,b){return dh(a)===dh(b)||a!=null&&Af(a,b)}
+function nt(a,b){return dh(a)===dh(b)||a!=null&&Af(a,b)}
+function pg(a,b){var c;c=rg(a,bh(b.c)?_g(b.c):null);sg(c)}
+function Tr(a,b,c){var d;d=a.c[b];Sg(a.c,b,c);return d}
+function Ts(a){var b;Us(a);--a.c;b=a.b.c;dt(b);return b.d}
+function ap(a,b){Dg(a.b,String.fromCharCode(b));return a}
+function pl(a,b){if(b==null||b.length==0){return}a.w=b}
+function Qj(a){if(ah(a,41)){return a}return new sf(a)}
+function rq(a,b){if(a.d==-1){throw new Tn}a.b.xb(a.d,b)}
+function $g(a,b){if(a!=null&&!Zg(a,b)){throw new Fn}return a}
+function Qg(a,b,c,d,e){var f;f=Pg(e,d);Rg(a,b,c,f);return f}
+function Zd(a,b){var c;c=new _d(a);mb(new nb(c),b);return c.b}
+function Hc(a){this.c=new Id(a);this.b=new kr;this.e=new kr}
+function _d(a){this.c=false;this.d=new Id(a);this.b=new kr}
+function wb(a){this.n=a;this.b=a.getElementsByTagName(av)}
+function lp(a){pf.call(this,'String index out of range: '+a)}
+function eq(a,b){throw new Vn('Index: '+a+', Size: '+b)}
+function Bo(c,a,b){b=Io(b);return c.replace(RegExp(a),b)}
+function Ao(c,a,b){b=Io(b);return c.replace(RegExp(a,Gw),b)}
+function du(a,b,c,d,e,f){au();return Nt(_t,a,b,c,d,e,f)}
+function to(a,b){if(!ah(b,1)){return false}return String(a)==b}
+function Lo(a,b){a=String(a);if(a==b){return 0}return a<b?-1:1}
+function nk(a,b){if(b!=a.c){a.c=b;return true}else{return false}}
+function At(a,b){a.b=null;a.d.lastIndex=0;return ek(a.d,a.c,b)}
+function qq(a){if(a.c<=0){throw new mt}return a.b.vb(a.d=--a.c)}
+function lq(a){if(a.d<0){throw new Tn}a.e.wb(a.d);a.c=a.d;a.d=-1}
+function Bt(a,b,c){this.d=new RegExp(a,b);this.c=c;this.b=null}
+function ft(a,b){this.d=a;this.b=b;this.c=b.c;b.c.b=this;b.c=this}
+function ut(){this.b=new Nm;this.c=new wt;Cm(this.b,Mu,this.c)}
+function Id(a){this.c=new mq(a);a.c==0||(this.b=_g(kq(this.c)))}
+function sf(a){qf.call(this);this.c=a;this.b=Mu;pg(new yg,this)}
+function ju(a,b){var c;Cm(a.c,b,co(a.b.c));c=new mu;dr(a.b,c)}
+function Nr(a,b){var c,d;d=a.c;for(c=0;c<d;++c){ir(a,c,b[c])}}
+function vo(a,b,c,d){var e;for(e=0;e<b;++e){c[d++]=a.charCodeAt(e)}}
+function ir(a,b,c){var d;d=(bq(b,a.c),a.b[b]);Sg(a.b,b,c);return d}
+function cr(a,b,c){(b<0||b>a.c)&&eq(b,a.c);wr(a.b,b,0,c);++a.c}
+function qe(a,b,c){um(a.c,b)&&!$g(xm(a.c,b),1).length&&Cm(a.c,b,c)}
+function Ec(a,b){while(a.b.c==1&&a.c!=b){a=$g(Wq(a.b,0),9)}return a}
+function qt(a,b){if(st(a,b.b.b)){return false}rt(a,b);return true}
+function dp(a,b){Dg(a.b,String.fromCharCode.apply(null,b));return a}
+function Em(a,b){var c;c=a.c;a.c=b;if(!a.d){a.d=true;++a.e}return c}
+function Og(a,b){var c,d;c=a;d=Pg(0,b);Rg(c.cZ,c.cM,c.qI,d);return d}
+function Rg(a,b,c,d){Vg();Xg(d,Tg,Ug);d.cZ=a;d.cM=b;d.qI=c;return d}
+function Xg(a,b,c){Vg();for(var d=0,e=b.length;d<e;++d){a[b[d]]=c[d]}}
+function Lf(a,b,c){var d;d=Jf();try{return If(a,b,c)}finally{Mf(d)}}
+function xr(a,b,c,d){Array.prototype.splice.apply(a,[b,c].concat(d))}
+function hr(a,b){var c;c=(bq(b,a.c),a.b[b]);vr(a.b,b,1);--a.c;return c}
+function zn(a,b){var c;c=new vn;c.f=a+b;Bn(0)&&Cn(0,c);c.c=2;return c}
+function Fr(a,b,c){var d;bq(b,a.b.length);d=a.b[b];Sg(a.b,b,c);return d}
+function gr(a,b,c){for(;c<a.c;++c){if(nt(b,a.b[c])){return c}}return -1}
+function _g(a){if(a!=null&&(a.tM==nu||Yg(a,1))){throw new Fn}return a}
+function kq(a){if(a.c>=a.e.fb()){throw new mt}return a.e.vb(a.d=a.c++)}
+function rc(a){if(!qc){qc=true;au();It(_t,rh,a);new mc;new Ac;sc(a)}}
+function mk(a){if(a.k==0){a.k=a.i;a.n=1}a.s=a.k/a.n;a.e=a.i==0?0:a.j/a.i}
+function vf(a){return a==null?bw:bh(a)?wf(_g(a)):ah(a,1)?cw:Bf(a).f}
+function eh(a){return ~~Math.max(Math.min(a,2147483647),-2147483648)}
+function um(a,b){return b==null?a.d:ah(b,1)?Bm(a,$g(b,1)):Am(a,b,a.ib(b))}
+function xm(a,b){return b==null?a.c:ah(b,1)?zm(a,$g(b,1)):ym(a,b,a.ib(b))}
+function Lt(a,b){var c=a[b];var d=0;for(k in c)d=Math.max(d,k);return d}
+function St(a,b){var c=[a];for(i=0;i<b.length;i++)c.push(b[i]);return c}
+function Jg(a){var b=a.parentNode;(!b||b.nodeType!=1)&&(b=null);return b}
+function Ng(a,b,c){var d,e;d=a;e=d.slice(b,c);Rg(d.cZ,d.cM,d.qI,e);return e}
+function cf(a,b,c){var d,e;e=new Ft(b);d=new Bt(e.c,e.b,a);return At(d,c)}
+function xn(a,b,c,d){var e;e=new vn;e.f=a+b;Bn(c)&&Cn(c,e);e.e=d;return e}
+function le(a,b){fe();var c;c=a;!!a.length&&!!b.length&&(c+=Yu);c+=b;return c}
+function ep(a,b,c,d){var e;Dg(a.b,(e=c+d,Go(b.length,c,e),Jo(b,c,e)));return a}
+function rg(a,b){var c;c=jg(a,b);return c.length==0?(new dg).Z(b):_f(c,1)}
+function Jo(a,b,c){a=a.slice(b,c);return String.fromCharCode.apply(null,a)}
+function Wg(a,b,c){var d=0,e;for(var f in a){if(e=a[f]){b[d]=f;c[d]=e;++d}}}
+function Fm(e,a,b){var c,d=e.f;a=fv+a;a in d?(c=d[a]):++e.e;d[a]=b;return c}
+function ps(a,b){var c;if(ah(b,31)){c=$g(b,31);return a.c[c.c]==c}return false}
+function Tt(a,b){var c;if(b==null){return null}return c=b[Jw],!c&&(c=Pt(a,b)),c}
+function sq(a,b){var c;this.b=a;this.e=a;c=a.fb();(b<0||b>c)&&eq(b,c);this.c=b}
+function jl(a,b){var c;c=$g(Rs(a.n),42);if(!c){c=new Vs;Ts(a.n);Qs(a.n,c)}Qs(c,b)}
+function pb(a){var b;a.c=Mu;b=jb(a.n,'byline-name');!!b&&(a.c=b.textContent)}
+function ws(a){var b;++a.b;for(b=a.d.b.length;a.b<b;++a.b){if(a.d.c[a.b]){return}}}
+function ys(a){if(a.b>=a.d.b.length){throw new mt}a.c=a.b;ws(a);return a.d.c[a.c]}
+function Zs(a){if(a.c==a.e.b){throw new mt}a.d=a.c;a.c=a.c.b;++a.b;return a.d.d}
+function Hd(a,b){if(b!=a.b)return false;a.b=jq(a.c)?_g(kq(a.c)):null;return true}
+function Uk(){Uk=nu;new Wk(false,0);new Wk(true,0);Tk=new Wk(true,150)}
+function Pf(){return $wnd.setTimeout(function(){Ef!=0&&(Ef=0);Hf=-1},10)}
+function Mf(a){a&&Uf((Sf(),Rf));--Ef;if(a){if(Hf!=-1){Of(Hf);Hf=-1}}}
+function Fe(){re.call(this,(Ne(),Le));Cm(this.c,aw,Mu);Cm(this.c,_v,Mu)}
+function Cm(a,b,c){return b==null?Em(a,c):ah(b,1)?Fm(a,$g(b,1),c):Dm(a,b,c,~~Cf(b))}
+function rt(a,b){var c,d;c=b.b.b;d=Eo(c,0,go(0,xo(c,No(46))));tt(a,d);Cm(a.b,b.b.b,b)}
+function fp(a){var b;b=a.b.b.length;0<b?(Eg(a.b,b),a):0>b&&dp(a,Qg(Fj,Du,-1,-b,1))}
+function Ip(a){var b;b=new kr;a.d&&dr(b,new Qp(a));rm(a,b);qm(a,b);this.b=new mq(b)}
+function Tf(a){var b,c;if(a.b){c=null;do{b=a.b;a.b=null;c=Xf(b,c)}while(a.b);a.b=c}}
+function Uf(a){var b,c;if(a.c){c=null;do{b=a.c;a.c=null;c=Xf(b,c)}while(a.c);a.c=c}}
+function og(a){var b;b=_f(rg(a,cg()),3);b.length==0&&(b=_f((new dg).X(),1));return b}
+function tt(a,b){var c,d;c=$g(xm(a.b,b),48);if(!c){d=new bk(b);rt(a,d);return d}return c}
+function pp(a,b){var c,d;d=b.mb();c=false;while(d.pb()){a.jb(d.qb())&&(c=true)}return c}
+function gf(a,b){var c,d;d=new Ft(b);c=new Bt(d.c,d.b,a);return c.b=dk(c.d,c.c),!!c.b}
+function yn(a,b,c,d,e){var f;f=new vn;f.f=a+b;Bn(c)&&Cn(c,f);f.c=e?8:0;f.e=d;f.b=e;return f}
+function wn(a,b,c){var d;d=new vn;d.f=a+b;Bn(c!=0?-c:0)&&Cn(c!=0?-c:0,d);d.c=4;d.e=Gi;return d}
+function Dc(a){var b;for(b=a.parentNode;!!b&&b.nodeType!=9;a=b,b=b.parentNode){}return a}
+function df(a){var b;for(b=0;b<a.length;++b){if(!ef(rn(a.charCodeAt(b))))return false}return true}
+function qp(a,b){var c;while(a.pb()){c=a.qb();if(b==null?c==null:Af(b,c)){return a}}return null}
+function rn(a){var b;if(a<128){b=(tn(),sn)[a];!b&&(b=sn[a]=new ln(a));return b}return new ln(a)}
+function Go(a,b,c){if(b<0){throw new lp(b)}if(c<b){throw new lp(c-b)}if(c>a){throw new lp(c)}}
+function Kf(b){return function(){try{return Lf(b,this,arguments)}catch(a){throw a}}}
+function bd(b){try{return new Sc(b)}catch(a){a=Qj(a);if(ah(a,33)){return null}else throw a}}
+function Fl(a){if(--a.f==0){if(a.k==0){ll(a);cp(a.x,Aw);ap(a.x,32);a.q=true}}return false}
+function Pd(a){var b,c;c=Mu;for(b=a.c-1;b>=0;--b){c+=(bq(b,a.c),$g(a.b[b],1));b>0&&(c+=tv)}return c}
+function er(a,b){var c,d;c=b.nb();d=c.length;if(d==0){return false}xr(a.b,a.c,0,c);a.c+=d;return true}
+function Hb(a){var b,c;c=a.width;if(c<400)return false;b=c/a.height;return b>=1.3&&b<=3}
+function uo(b,a){if(a==null)return false;return b==a||b.toLowerCase()==a.toLowerCase()}
+function Ut(a,b){var c,d;if(b==null){return null}d=[];for(c=0;c<b.length;++c){d[c]=Tt(a,b[c])}return d}
+function mb(a,b){var c,d;if(!a.b.B(b))return;c=b.childNodes;for(d=0;d<c.length;++d){mb(a,c[d])}a.b.A(b)}
+function Be(a){var b;b=um(a.c,Kv)?$g(xm(a.c,Kv),1):Mu;return !b.length?um(a.c,$v)?$g(xm(a.c,$v),1):Mu:b}
+function te(a){var b;b=le(um(a.c,Pv)?$g(xm(a.c,Pv),1):Mu,ve(a,Qv));return !b.length?b:'Copyright '+b}
+function Qt(a,b){var c,d;c=$g(xm(a.c,b),50);d=b.e;if(!c&&!!d&&d!=Gi){return Qt(a,d)}return c?c.y():null}
+function ue(a){var b,c;c=um(a.c,kv)?$g(xm(a.c,kv),1):Mu;if(!c.length)return null;b=new bc;b.f=c;return b}
+function Ln(a,b){if(isNaN(a)){return isNaN(b)?0:1}else if(isNaN(b)){return -1}return a<b?-1:a>b?1:0}
+function os(a,b){var c;if(!b){throw new jo}c=b.c;if(!a.c[c]){Sg(a.c,c,b);++a.d;return true}return false}
+function Kb(a){var b;this.b=new kr;b=bd(a);!!b&&dr(this.b,b);dr(this.b,new Te(a));dr(this.b,new wb(a))}
+function sl(a){this.x=new gp;this.u=new gp;this.t=new kr;this.c=new Fs;this.n=new Vs;this.e=new Vs;this.r=a}
+function yl(){yl=nu;vl=new Al;tl=new Gl;ul=new Ll;xl=new Ql;wl=new Vl;new Et('([\\+\\-]?)([0-9])')}
+function kk(){kk=nu;ik=new Fs;jk=new pk(Mu,ik,0,0,0,0,-1);new pk(Mu,ik,0,0,0,0,2147483647)}
+function Hk(){Hk=nu;Fk=new Jk(false,false);new Jk(false,true);new Jk(true,false);Gk=new Jk(true,true)}
+function xd(){xd=nu;vd=new yd('OG',0);wd=new yd('PROFILE',1);ud=new yd(sv,2);td=Rg(Hj,wu,10,[vd,wd,ud])}
+function Wm(){Wm=nu;Vm=new Et('\\b');new Et('[\u2063]*([\\"\'\\.,\\!\\@\\-\\:\\;\\$\\?\\(\\)/])[\u2063]*')}
+function Xm(a){Wm();var b;b=At(Dt(Vm,a),'\u2063');b=Ao(b,'[ \u2063]+',Yu);b=ff(b);return Co(b,'[ ]+',0)}
+function Vo(a){To();var b=fv+a;var c=So[b];if(c!=null){return c}c=Qo[b];c==null&&(c=Uo(a));Wo();return So[b]=c}
+function rm(e,a){var b=e.f;for(var c in b){if(c.charCodeAt(0)==58){var d=new Vp(e,c.substring(1));a.jb(d)}}}
+function he(a){var b,c,d;b=new kr;for(c=0;c<a.c.c;++c){d=$g(fr(a.c,c),18);d.d==(Ne(),Ie)&&dr(b,$g(d,14))}return b}
+function ie(a){var b,c,d;c=new kr;for(b=0;b<a.c.c;++b){d=$g(fr(a.c,b),18);d.d==(Ne(),Je)&&dr(c,$g(d,15))}return c}
+function Mc(a){var b,c,d;d=a.c.cloneNode(false);for(c=Ss(a.b,0);c.c!=c.e.b;){b=$g(Zs(c),9);Gg(d,Mc(b))}return d}
+function Xj(a){var b,c,d;c=(!pt&&(pt=new ut),pt);b=$g(xm(c.b,a),48);if(!b){d=new ck(a);qt(c,d);return d}return b}
+function co(a){var b,c;if(a>-129&&a<128){b=a+128;c=(fo(),eo)[b];!c&&(c=eo[b]=new Yn(a));return c}return new Yn(a)}
+function qb(a){var b,c;a.d=Mu;for(b=0;b<a.b.length;++b){c=a.b[b];if(uo(c.name,'copyright')){a.d=c.content;break}}}
+function mf(a){var b,c,d;c=Qg(Nj,vu,38,a.length,0);for(d=0,b=a.length;d<b;++d){if(!a[d]){throw new jo}c[d]=a[d]}}
+function lk(a,b){var c,d,e;if(b==null){return}!a.d&&(a.d=new Fs);for(d=0,e=b.length;d<e;++d){c=b[d];Ds(a.d,c)}}
+function jg(a,b){var c,d,e;e=b&&b.stack?b.stack.split(fw):[];for(c=0,d=e.length;c<d;++c){e[c]=a.Y(e[c])}return e}
+function vm(e,a){var b=e.f;for(var c in b){if(c.charCodeAt(0)==58){var d=b[c];if(e.hb(a,d)){return true}}}return false}
+function wm(a,b){if(a.d&&Mm(a.c,b)){return true}else if(vm(a,b)){return true}else if(tm(a,b)){return true}return false}
+function nn(a){if(a>=48&&a<58){return a-48}if(a>=97&&a<97){return a-97+10}if(a>=65&&a<65){return a-65+10}return -1}
+function Gm(a){sm(this);if(a<0){throw new Rn('initial capacity was negative or load factor was non-positive')}}
+function re(a){this.d=a;this.c=new Nm;this.b=new Nm;Cm(this.c,Kv,Mu);Cm(this.c,hv,Mu);Cm(this.c,iv,Mu);Cm(this.c,kv,Mu)}
+function pk(a,b,c,d,e,f,g){kk();this.r=a;this.b=b;this.i=c;this.j=d;this.k=e;this.n=f;this.p=g;this.o=g;mk(this)}
+function Br(a,b,c,d,e,f,g){var h;h=c;while(f<g){h>=d||b<c&&$g(a[b],29).cT(a[h])<=0?Sg(e,f++,a[b++]):Sg(e,f++,a[h++])}}
+function Mt(a,b,c,d){var e,f;f=d?a.d:a.b;e=_g(!b?f.c:ym(f,b,~~Nf(b)));!e?(e=c):Yt(e,c);!b?Em(f,e):Dm(f,b,e,~~Nf(b))}
+function Rm(a,b,c){Cm(a,b.toUpperCase(),c);Cm(a,b.toLowerCase(),c);b==null?Em(a,c):b!=null?Fm(a,b,c):Dm(a,null,c,~~Vo(null))}
+function nl(a,b,c){var d;d=$g(xm(a.r,b),23);d?(a.d=d.ab(a,b,c)|a.d):(a.d=true);(!d||d._())&&--a.s;a.d&&ol(a);Ts(a.n)}
+function ql(a,b,c,d){var e;Qs(a.n,null);e=$g(xm(a.r,b),23);if(e){e._()&&++a.s;a.d=e.bb(a,b,c,d)|a.d}else{++a.s;a.d=true}a.o=b}
+function $r(a,b){var c,d,e;if(ah(b,45)){c=$g(b,45);d=c.rb();if(Qr(a.b,d)){e=Rr(a.b,d);return nt(c.sb(),e)}}return false}
+function Cp(a,b){var c,d,e;if(ah(b,45)){c=$g(b,45);d=c.rb();if(um(a.b,d)){e=xm(a.b,d);return a.b.gb(c.sb(),e)}}return false}
+function hm(a,b){var c,d,e;for(d=a.db().mb();d.pb();){c=$g(d.qb(),45);e=c.rb();if(b==null?e==null:Af(b,e)){return c}}return null}
+function Rt(a,b){var c,d,e;e=Qt(a,Bf(b));if(!e){for(d=Lq(jm(a.c));jq(d.b.b);){c=$g(Rq(d),50);if(c.z(b)){e=c.y();break}}}return e}
+function id(a){var b,c;if(a.b.c==0)return;for(b=a.b.c-1;b>=0;--b){c=$g(fr(a.b,b),40)[0];(c==null||!c.length)&&hr(a.b,b)}}
+function tb(a){var b,c;a.f=true;for(b=0;b<a.b.length;++b){c=a.b[b];if(uo(c.name,'IE_RM_OFF')){a.j=uo(c.content,Zu);break}}}
+function Ur(a){var b;this.b=(b=$g(a.b&&a.b(),32),new qs(b,$g(Og(b,b.length),32)));this.c=Qg(Mj,vu,0,this.b.b.length,0)}
+function jr(a,b){var c;b.length<a.c&&(b=Og(b,a.c));for(c=0;c<a.c;++c){Sg(b,c,a.b[c])}b.length>a.c&&Sg(b,a.c,null);return b}
+function Ar(a,b,c){var d,e,f;for(d=b+1;d<c;++d){for(e=d;e>b&&$g(a[e-1],29).cT(a[e])>0;--e){f=a[e];Sg(a,e,a[e-1]);Sg(a,e-1,f)}}}
+function Gc(a){var b;for(b=0;b<a.b.c;++b){if(fr(a.e,b)==null){ir(a.e,b,new Nc(_g(fr(a.b,b))));Lc($g(fr(a.e,b-1),9),$g(fr(a.e,b),9))}}}
+function gwtOnLoad(b,c,d,e){$moduleName=c;$moduleBase=d;if(b)try{Iu(Pj)()}catch(a){b(c)}else{Iu(Pj)()}}
+function Wq(b,c){var d;d=Ss(b,c);try{return Zs(d)}catch(a){a=Qj(a);if(ah(a,46)){throw new Vn("Can't get element "+c)}else throw a}}
+function qm(h,a){var b=h.b;for(var c in b){var d=parseInt(c,10);if(c==d){var e=b[d];for(var f=0,g=e.length;f<g;++f){a.jb(e[f])}}}}
+function ym(h,a,b){var c=h.b[b];if(c){for(var d=0,e=c.length;d<e;++d){var f=c[d];var g=f.rb();if(h.hb(a,g)){return f.sb()}}}return null}
+function Am(h,a,b){var c=h.b[b];if(c){for(var d=0,e=c.length;d<e;++d){var f=c[d];var g=f.rb();if(h.hb(a,g)){return true}}}return false}
+function Jf(){var a;if(Ef!=0){a=(new Date).getTime();if(a-Gf>2000){Gf=a;Hf=Pf()}}if(Ef++==0){Tf((Sf(),Rf));return true}return false}
+function jd(){this.c=Rg(Oj,su,1,[kv,'image:url','image:secure_url','image:type','image:width','image:height']);this.b=new kr}
+function ff(a){if(a.length==0||a[0]>Yu&&a[a.length-1]>Yu){return a}return a.replace(/^[\u0000-\u0020]*|[\u0000-\u0020]*$/g,Mu)}
+function Fo(c){if(c.length==0||c[0]>Yu&&c[c.length-1]>Yu){return c}var a=c.replace(/^(\s*)/,Mu);var b=a.replace(/\s*$/,Mu);return b}
+function ef(a){var b;b=a.b;return 9<=b&&b<=13||28<=b&&b<=32||b==5760||b==6158||8192<=b&&b<=8198||8232<=b&&b<=8233||b==8287||b==12288}
+function eb(a){db();var b,c,d,e;b=new ku;e=a.attributes;for(c=0;c<e.length;++c){d=e[c];ju(b,(d.nodeName,d.nodeName),d.nodeValue)}return b}
+function Zk(a){var b,c,d,e;b=false;d=a.b;for(c=new sq(d,d.c);c.c>0;){e=$g(qq(c),21);if(e.c){if(!!e.d&&Es(e.d,ww)){nk(e,false);b=true}else{break}}}return b}
+function bg(b){var c=Mu;try{for(var d in b){if(d!=Kv&&d!='message'&&d!='toString'){try{c+='\n '+d+Su+b[d]}catch(a){}}}}catch(a){}return c}
+function Ee(a){var b;b=um(a.c,Kv)?$g(xm(a.c,Kv),1):Mu;return !b.length?le(um(a.c,_v)?$g(xm(a.c,_v),1):Mu,um(a.c,aw)?$g(xm(a.c,aw),1):Mu):b}
+function Rc(a,b,c){var d;if(c==null||!c.length){Sr(a.d,(xd(),vd),b);return}d=Do(c,1);to(d,dv)?Sr(a.d,(xd(),wd),b):to(d,ev)&&Sr(a.d,(xd(),ud),b)}
+function ze(){re.call(this,(Ne(),Je));Cm(this.c,Uv,Mu);Cm(this.c,Vv,Mu);Cm(this.c,Wv,Mu);Cm(this.c,Zv,Mu);Cm(this.c,Xv,Mu);Cm(this.c,Yv,Mu)}
+function me(a){var b,c;b=a.getAttribute('ITEMPROP')||Mu;if(!b.length)return Qg(Oj,su,1,0,0);c=Co(b,Ru,0);return c.length>0?c:Rg(Oj,su,1,[b])}
+function $t(a,b){var c=a[b];var d=c==null?bw:typeof c;if(d==Uu){return Object.prototype.toString.call(c)==Iw||typeof c.length==Dw?'array':d}return d}
+function $p(a,b){var c,d;for(c=0,d=a.b.length;c<d;++c){if(b==null?(bq(c,a.b.length),a.b[c])==null:Af(b,(bq(c,a.b.length),a.b[c]))){return c}}return -1}
+function Xf(b,c){var d,e,f;for(d=0,e=b.length;d<e;++d){f=b[d];try{f[1]?f[0].yb()&&(c=Wf(c,f)):f[0].yb()}catch(a){a=Qj(a);if(!ah(a,41))throw a}}return c}
+function Io(a){var b;b=0;while(0<=(b=a.indexOf('\\',b))){a.charCodeAt(b+1)==36?(a=a.substr(0,b-0)+'$'+Do(a,++b)):(a=a.substr(0,b-0)+Do(a,++b))}return a}
+function Ss(a,b){var c,d;(b<0||b>a.c)&&eq(b,a.c);if(b>=~~a.c>>1){d=a.b;for(c=a.c;c>b;--c){d=d.c}}else{d=a.b.b;for(c=0;c<b;++c){d=d.b}}return new _s(a,b,d)}
+function Xt(a,b){var c;if(Gi==b){return true}if(Aj==b&&ah(a,49)){return true}if(a!=null){for(c=Bf(a);!!c&&c!=Gi;c=c.e){if(c==b){return true}}}return false}
+function bl(a,b){var c,d,e,f;f=b.b;c=false;for(d=new mq(f);d.c<d.e.fb();){e=$g(kq(d),21);if(!e.c&&(a.b==null||!(!!e.d&&Es(e.d,Lu)))){lq(d);c=true}}return c}
+function zo(d,a,b){var c;if(a<256){c=ao(a);c='\\x'+'00'.substring(c.length)+c}else{c=String.fromCharCode(a)}return d.replace(RegExp(c,Gw),String.fromCharCode(b))}
+function Nk(a,b,c){var d,e,f,g;g=Co(b,c,0);if(g.length==1){return}for(d=0;d<g.length;++d){f=g[d];if(f.indexOf(qw)!=-1){continue}e=Co(f,rw,0).length;e>=4&&Ds(a,f)}}
+function Cn(a,b){var c;b.d=a;if(a==2){c=String.prototype}else{if(a>0){var d=An(b);if(d){c=d.prototype}else{d=Sj[a]=function(){};d.cZ=b;return}}else{return}}c.cZ=b}
+function zb(a){var b,c,d;d=Jg(a);if(!to('FIGURE',d.tagName))return Mu;b=d.getElementsByTagName('FIGCAPTION');c=b.length;if(c>0&&c<=2)return b[0].textContent;return Mu}
+function Bd(a,b){var c,d;if(!a.c)return Mu;c=$g(b.f[':first_name'],1);c==null&&(c=Mu);d=$g(b.f[':last_name'],1);d!=null&&!!c.length&&!!d.length&&(c+=Yu);c+=d;return c}
+function Ne(){Ne=nu;Je=new Oe('IMAGE',0);Ie=new Oe(sv,1);Le=new Oe('PERSON',2);Ke=new Oe('ORGANIZATION',3);Me=new Oe('UNSUPPORTED',4);He=Rg(Jj,wu,19,[Je,Ie,Le,Ke,Me])}
+function rb(a){var b,c,d;a.e=Mu;b=jb(a.n,'dateline');if(b){a.e=b.textContent}else{for(c=0;c<a.b.length;++c){d=a.b[c];if(uo(d.name,'displaydate')){a.e=d.content;break}}}}
+function lo(){lo=nu;ko=Rg(Fj,Du,-1,[48,49,50,51,52,53,54,55,56,57,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122])}
+function ao(a){var b,c,d;b=Qg(Fj,Du,-1,8,1);c=(lo(),ko);d=7;if(a>=0){while(a>15){b[d--]=c[a&15];a>>=4}}else{while(d>0){b[d--]=c[a&15];a>>=4}}b[d]=c[a&15];return Jo(b,d,8)}
+function Pt(a,b){var c,d,e,f,g;if((Bf(b).c&4)!=0){c=$g(b,37);g=[];for(e=0;e<c.length;++e){g[e]=Pt(a,c[e])}return g}d=Rt(a,b);f=d&&typeof d==Vu?new d(b):b;b[Jw]=f;return f}
+function kb(a,b){var c,d,e,f;c=a.getElementsByTagName(Xu);for(f=0;f<c.length;++f){e=c[f];d=e.className.toLowerCase();if((Yu+d+Yu).indexOf(Yu+b+Yu)!=-1)return e}return null}
+function L(a){var b,c,d,e,f,g;g=a;c=g.getElementsByTagName(Nu);for(d=0;d<c.length;++d){f=c[d];Hg(f,f.href)}b=g.getElementsByTagName(Ou);for(d=0;d<b.length;++d){e=b[d];Kg(e,e.src)}}
+function rp(a){var b,c,d,e;d=new Yo;b=null;d.b.b+=iw;c=a.mb();while(c.pb()){b!=null?(Cg(d.b,b),d):(b=Bw);e=c.qb();Cg(d.b,e===a?'(this Collection)':Mu+e)}d.b.b+=jw;return d.b.b}
+function Pg(a,b){var c=new Array(b);if(a==3){for(var d=0;d<b;++d){var e=new Object;e.l=e.m=e.h=0;c[d]=e}}else if(a>0){var e=[null,0,false][a];for(var d=0;d<b;++d){c[d]=e}}return c}
+function zk(a,b,c){var d;b.e<=0.333333?a.e<=0.555556?b.i<=16?c.i<=15?a.i<=4?(d=false):(d=true):(d=true):(d=true):b.i<=40?c.i<=17?(d=false):(d=true):(d=true):(d=false);return nk(b,d)}
+function tm(l,a){var b=l.b;for(var c in b){var d=parseInt(c,10);if(c==d){var e=b[d];for(var f=0,g=e.length;f<g;++f){var h=e[f];var j=h.sb();if(l.hb(a,j)){return true}}}}return false}
+function Kt(a){var b,c,d,e,f;f=Co(a,'\\.',0);e=$wnd;b=0;for(c=f.length-1;b<c;++b){if(!to(f[b],'client')){e[f[b]]||(e[f[b]]={});e=e!=null?e[f[b]]:null}}d=e!=null?e[f[b]]:null;return d}
+function vb(a){var b,c,d;a.o=Mu;if(a.b.length==0)return;d=a.n.getElementsByTagName(Pu);if(d.length==0)return;for(b=0;b<a.b.length;++b){c=a.b[b];if(uo(c.name,_u)){a.o=c.content;break}}}
+function ve(a,b){var c,d;c=um(a.c,b)?$g(xm(a.c,b),1):Mu;if(c.length)return c;d=um(a.b,b)?$g(xm(a.b,b),18):null;!!d&&(d.d==(Ne(),Le)?(c=Ee($g(d,17))):d.d==Ke&&(c=Be($g(d,16))));return c}
+function Dk(a,b,c){var d,e,f,g;d=0;while(d<b&&Ck(a.charCodeAt(d))){++d}if(d!=0){for(f=0,g=c.length;f<g;++f){e=c[f];if(!(d<0||d>=a.length)&&a.indexOf(e,d)==d){return true}}}return false}
+function Vj(a){return $stats({moduleName:$moduleName,sessionId:$sessionId,subSystem:'startup',evtGroup:'moduleStartup',millis:(new Date).getTime(),type:'onModuleLoadStart',className:a})}
+function Yf(a){var b,c,d;d=Mu;a=Fo(a);b=a.indexOf(dw);c=a.indexOf(Vu)==0?8:0;if(b==-1){b=wo(a,No(64));c=a.indexOf('function ')==0?9:0}b!=-1&&(d=Fo(a.substr(c,b-c)));return d.length>0?d:ew}
+function uq(a,b,c){this.d=a;this.b=b;this.c=c-b;if(b>c){throw new Rn(Hw+b+' > toIndex: '+c)}if(b<0){throw new Vn(Hw+b+' < 0')}if(c>a.c){throw new Vn('toIndex: '+c+' > wrapped.size() '+a.c)}}
+function jb(a,b){if(typeof a.querySelector==Vu)return a.querySelector(Wu+b);if(typeof a.getElementsByClassName==Vu){var c=a.getElementsByClassName(b);return c.length==0?null:c[0]}return kb(a,b)}
+function ub(a){var b,c,d;a.k=Mu;b=a.n.getElementsByTagName(Xu);for(d=0;d<b.length&&!a.k.length;++d){c=b[d];a.k=c.getAttribute($u)||Mu;!a.k.length&&(a.k=c.getAttribute('source_organization')||Mu)}}
+function No(a){var b,c;if(a>=65536){b=55296+(~~(a-65536)>>10&1023)&65535;c=56320+(a-65536&1023)&65535;return String.fromCharCode(b)+String.fromCharCode(c)}else{return String.fromCharCode(a&65535)}}
 
-function Q(g){var d=jp('com.dom_distiller.ContentExtractor');var e,f=g;$wnd.com.dom_distiller.ContentExtractor=Gp(function(){var a,b=this,c=arguments;c.length==1&&f.y(c[0])?(a=c[0]):c.length==0&&(a=new K);b.g=a;mp(a,b);return b});e=$wnd.com.dom_distiller.ContentExtractor.prototype=new Object;$wnd.com.dom_distiller.ContentExtractor.extractContent=Gp(function(){return L()});if(d)for(p in d)$wnd.com.dom_distiller.ContentExtractor[p]===undefined&&($wnd.com.dom_distiller.ContentExtractor[p]=d[p])}
-function th(a){var b,c,d,e,f,g,h,j,l,m,n,o,q,r;if(a.j==0){vk(Np,a.o)&&a.j==0&&uh(a,Gk(a.x.b.b));gl(a.u);gl(a.x);return}c=a.x.b.b.length;switch(c){case 0:return;case 1:if(a.q){gl(a.u);gl(a.x);return}}r=_i(a.x);f=0;d=0;j=0;b=-1;e=0;g=0;for(n=0,o=r.length;n<o;++n){m=r[n];if(uk(Aq,m)){a.i=true}else if(uk(Bq,m)){a.i=false}else if(Mo(Qo(mh,m))){++e;++f;++g;a.i&&++d;q=m.length;b+=q+1;if(b>80){++j;b=q;g=1}}else{++e}}if(e==0){return}if(j==0){h=f;j=1}else{h=f-g}l=new ug(Ub(a.u.b.b),a.c,f,d,h,j,a.p);a.c=new Sn;++a.p;gl(a.u);gl(a.x);tg(l,a.b);ph(a,l);a.b=-1}
-function $g(a,b){var c,d,e,f,g,h,j,l,m,n,o;n=b.b;if(n.c<2){return false}g=-1;e=null;f=-1;c=0;h=-1;for(m=new mm(n);m.c<m.e.M();){l=Kd(km(m),8);if(l.c){j=l.i;if(j>g){e=l;g=j;h=c;a.b&&(f=l.q)}}++c}for(m=new mm(n);m.c<m.e.M();){l=Kd(km(m),8);if(l==e){sg(l,true);!l.d&&(l.d=new Tn);Qn(l.d,vq)}else{sg(l,false);!l.d&&(l.d=new Tn);Qn(l.d,uq)}}if(a.b&&h!=-1){for(d=new sm(n,h);d.c>0;){l=Kd(qm(d),8);o=l.q;if(o<f){break}else o==f&&l.i>=a.c&&sg(l,true)}for(d=new sm(n,h);d.c<d.e.M();){l=Kd(km(d),8);o=l.q;if(o<f){break}else o==f&&l.i>=a.c&&sg(l,true)}}return true}
-function lg(){var b=navigator.userAgent.toLowerCase();var c=function(a){return parseInt(a[1])*1000+parseInt(a[2])};if(function(){return b.indexOf(oq)!=-1}())return oq;if(function(){return b.indexOf('webkit')!=-1}())return mq;if(function(){return b.indexOf(pq)!=-1&&$doc.documentMode>=9}())return 'ie9';if(function(){return b.indexOf(pq)!=-1&&$doc.documentMode>=8}())return 'ie8';if(function(){var a=/msie ([0-9]+)\.([0-9]+)/.exec(b);if(a&&a.length==3)return c(a)>=6000}())return 'ie6';if(function(){return b.indexOf('gecko')!=-1}())return 'gecko1_8';return 'unknown'}
-function Jb(g){var d=jp('com.dom_distiller.PagingLinksFinder');var e,f=g;$wnd.com.dom_distiller.PagingLinksFinder=Gp(function(){var a,b=this,c=arguments;c.length==1&&f.y(c[0])?(a=c[0]):c.length==0&&(a=new Ab);b.g=a;mp(a,b);return b});e=$wnd.com.dom_distiller.PagingLinksFinder.prototype=new Object;$wnd.com.dom_distiller.PagingLinksFinder.findNext=Gp(function(a){return Cb(a,0)});$wnd.com.dom_distiller.PagingLinksFinder.findPrevious=Gp(function(a){return Cb(a,1)});if(d)for(p in d)$wnd.com.dom_distiller.PagingLinksFinder[p]===undefined&&($wnd.com.dom_distiller.PagingLinksFinder[p]=d[p])}
-function Z(g){var d=jp('com.dom_distiller.DocumentTitleGetter');var e,f=g;$wnd.com.dom_distiller.DocumentTitleGetter=Gp(function(){var a,b=this,c=arguments;c.length==1&&f.y(c[0])?(a=c[0]):c.length==0&&(a=new U);b.g=a;mp(a,b);return b});e=$wnd.com.dom_distiller.DocumentTitleGetter.prototype=new Object;$wnd.com.dom_distiller.DocumentTitleGetter.getDocumentTitle=Gp(function(a,b){return lp(null,Ud,0,arguments,true,false)[0]});kp(Ud,{0:{2:[[V,null,undefined,Ve,Sp]]}},true);if(d)for(p in d)$wnd.com.dom_distiller.DocumentTitleGetter[p]===undefined&&($wnd.com.dom_distiller.DocumentTitleGetter[p]=d[p])}
-function V(a,b){var c,d,e,f,g,h,j;c=Kp;d=Kp;if(mc(a)==_e){c=d=(f=a,Od(f)?f.tS():f.toString?f.toString():'[JavaScriptObject]')}else if(b){e=b.getElementsByTagName(Np);e.length>0&&(c=d=e[0].textContent)}if(c==Kp)return Kp;if(Vb(c,' [\\|\\-] ')){c=Rb(d,'(.*)[\\|\\-] .*',Op);Dk(c,Pp,0).length<3&&(c=Rb(d,'[^\\|\\-]*[\\|\\-](.*)',Op))}else if(c.indexOf(Qp)!=-1){c=Rb(d,'.*:(.*)',Op);Dk(c,Pp,0).length<3&&(c=Rb(d,'[^:]*[:](.*)',Op))}else if(!!b&&(c.length>150||c.length<15)){c=(g=b.getElementsByTagName(Rp),g.length==1?g[0].textContent:null);c==null&&(c=d)}c=(h=new So('^\\s+|\\s+$'),j=new Oo(h.c,h.b,c),No(j,Kp));Dk(c,Pp,0).length<=4&&(c=d);return c}
-function Vg(a){Rg();var b;if(a==null){this.b=null}else{a=Ak(a,160,32);a=Bk(a,tq,Kp);a=Gk(a).toLowerCase();if(a.length==0){this.b=null}else{this.b=new Sn;Qn(this.b,a);b=Tg(a,'[ ]*[\\|\xBB|-][ ]*');b!=null&&Qn(this.b,b);b=Tg(a,'[ ]*[\\|\xBB|:][ ]*');b!=null&&Qn(this.b,b);b=Tg(a,'[ ]*[\\|\xBB|:\\(\\)][ ]*');b!=null&&Qn(this.b,b);b=Tg(a,'[ ]*[\\|\xBB|:\\(\\)\\-][ ]*');b!=null&&Qn(this.b,b);b=Tg(a,'[ ]*[\\|\xBB|,|:\\(\\)\\-][ ]*');b!=null&&Qn(this.b,b);b=Tg(a,'[ ]*[\\|\xBB|,|:\\(\\)\\-\xA0][ ]*');b!=null&&Qn(this.b,b);Sg(this.b,a,'[ ]+[\\|][ ]+');Sg(this.b,a,'[ ]+[\\-][ ]+');Qn(this.b,Ck(a,' - [^\\-]+$',Kp));Qn(this.b,Ck(a,'^[^\\-]+ - ',Kp))}}}
-function Ng(a,b){var c,d,e,f,g,h,j,l,m,n,o;n=b.b;if(n.c<2){return false}d=false;if(a.b){j=null;g=0;for(m=new mm(n);m.c<m.e.M();){l=Kd(km(m),8);++g;if(l.c){j=l;break}}if(!j){return false}}else{j=(bm(0,n.c),Kd(n.b[0],8));g=1}for(f=new sm(n,g);f.c<f.e.M();){c=Kd(km(f),8);if(!c.c){j=c;continue}e=c.p-j.o-1;if(e<=a.c){h=true;a.b&&(!j.c||!c.c)&&(h=false);h&&a.d&&j.q!=c.q&&(h=false);if(h){Md(j.r,22)||(j.r=new il(j.r));o=Kd(j.r,22);o.b.b+=gq;cl(o,c.r);j.i+=c.i;j.j+=c.j;j.k+=c.k;j.n+=c.n;j.p=ik(j.p,c.p);j.o=hk(j.o,c.o);rg(j);j.c=j.c|c.c;!j.b&&(j.b=new Sn);ql(j.b,c.b);j.f+=c.f;!!c.d&&(!j.d?(j.d=new Un(c.d)):j.d.R(c.d));j.q=ik(j.q,c.q);lm(f);d=true}else{j=c}}else{j=c}}return d}
-function L(){var o,q,r,s;J();var a,b,c,d,e,f,g,h,j,l,m,n;g=new wh;f=$doc.documentElement;n=(cb(),o=new fb(g),jb(new kb(o),f),o.c);th(g);e=(th(g),new xg(g.w,g.t));true|Gg(e)|Ug(new Vg(e.c),e)|Fg(e)|Cg((Bg(),Ag),e)|ch(e)|Ng((Mg(),Kg),e)|gh((fh(),eh),e)|Ng(Lg,e)|$g((Zg(),Yg),e)|Wg(e)|ah(e)|bh(e);d=new kn;for(m=new mm(e.b);m.c<m.e.M();){l=Kd(km(m),8);!!l.d&&Rn(l.d,Jp)||en(d,l.b)}q=xd(d.b,0,d.c);Cn(q,0,q.length);Nn(d,q);c=new ln(d.c);for(j=new mm(d);j.c<j.e.M();){h=Kd(km(j),18);dn(c,Ld(fn(n,h.b-1)))}b=Mb(c,$doc.documentElement);a=ub((r=new pb(b),s=lb((bm(0,b.c),Ld(b.b[0]))),jb(new kb(r),s),mb(r.d,(bm(0,b.c),Ld(b.b[0])))));if(a.nodeType!=1){return Kp}M(a);return a.innerHTML}
-function Gg(a){var b,c,d,e,f,g,h;b=false;for(f=new mm(a.b);f.c<f.e.M();){e=Kd(km(f),8);d=e.i;if(d<15){g=Gk(e.r.tS());c=g.length;if(c>=8){h=g.toLowerCase();if(h.indexOf('comments')==0||Ig(h,c,Bd(Tf,wp,1,[' comments',' users responded in']))||h.indexOf('\xA9 reuters')==0||h.indexOf('please rate this')==0||h.indexOf('post a comment')==0||h.indexOf('what you think...')!=-1||h.indexOf('add your comment')!=-1||h.indexOf('add comment')!=-1||h.indexOf('reader views')!=-1||h.indexOf('have your say')!=-1||h.indexOf('reader comments')!=-1||h.indexOf('r\xE4tta artikeln')!=-1||uk(h,'thanks for your comments - this feedback is now closed')){!e.d&&(e.d=new Tn);Qn(e.d,qq);b=true}}else e.e==1&&uk(g,'Comment')&&(!e.d&&(e.d=new Tn),Qn(e.d,qq))}}return b}
-function Yi(){wi(this);Vi(this,'STYLE',(Dh(),Ah));Vi(this,'SCRIPT',Ah);Vi(this,'OPTION',Ah);Vi(this,'OBJECT',Ah);Vi(this,'EMBED',Ah);Vi(this,'APPLET',Ah);Vi(this,'LINK',Ah);Vi(this,Lp,yh);Vi(this,'BODY',zh);Vi(this,'STRIKE',Bh);Vi(this,'U',Bh);Vi(this,'B',Bh);Vi(this,'I',Bh);Vi(this,'EM',Bh);Vi(this,'STRONG',Bh);Vi(this,'SPAN',Bh);Vi(this,'SUP',Bh);Vi(this,'CODE',Bh);Vi(this,'TT',Bh);Vi(this,'SUB',Bh);Vi(this,'VAR',Bh);Vi(this,'ABBR',Ch);Vi(this,'ACRONYM',Ch);Vi(this,'FONT',Bh);Vi(this,'NOSCRIPT',Ah);Vi(this,'LI',new di(new jh(Bd(Tf,wp,1,[wq]))));Vi(this,Rp,new di(new jh(Bd(Tf,wp,1,['de.l3s.boilerpipe/H1',xq]))));Vi(this,'H2',new di(new jh(Bd(Tf,wp,1,['de.l3s.boilerpipe/H2',xq]))));Vi(this,'H3',new di(new jh(Bd(Tf,wp,1,['de.l3s.boilerpipe/H3',xq]))))}
-function kg(){var a,b,c;b=$doc.compatMode;a=Bd(Tf,wp,1,[nq]);for(c=0;c<a.length;++c){if(uk(a[c],b)){return}}a.length==1&&uk(nq,a[0])&&uk('BackCompat',b)?"GWT no longer supports Quirks Mode (document.compatMode=' BackCompat').<br>Make sure your application's host HTML page has a Standards Mode (document.compatMode=' CSS1Compat') doctype,<br>e.g. by using &lt;!doctype html&gt; at the start of your application's HTML page.<br><br>To continue using this unsupported rendering mode and risk layout problems, suppress this message by adding<br>the following line to your*.gwt.xml module file:<br>&nbsp;&nbsp;&lt;extend-configuration-property name=\"document.compatMode\" value=\""+b+'"/&gt;':"Your *.gwt.xml module configuration prohibits the use of the current doucment rendering mode (document.compatMode=' "+b+"').<br>Modify your application's host HTML page doctype, or update your custom 'document.compatMode' configuration property settings."}
-function Cb(b,c){var d,e,f,g,h,j,l,m,n,o,q,r,s,t,u,v,w,x,y,z,A,B,C;e=Bb();B=Rb($wnd.location.href,Wp,Kp);d=b.getElementsByTagName(Lp);y=new Ri;for(f=0;f<d.length;++f){h=d[f];l=Rb(Rb(h.href,'#.*$',Kp),Wp,Kp);if(!l.length||!Vb(l,'^https?://')||vk(l,B)||c==0&&vk(l,e)){continue}A=Dk(l,'\\/+',0);if(A.length<3||!vk($wnd.location.host,A[1])){continue}o=h.textContent;if(Vb(o,Xp)||o.length>25){continue}if(c==0){m=Rb(l,e,Kp);if(!Vb(m,'\\d'))continue}n=null;if(l==null?y.d:l!=null?Yp+l in y.f:Ei(y,null,~~Wk(null))){n=Kd(l==null?y.c:l!=null?y.f[Yp+l]:Ci(y,null,~~Wk(null)),6);n.c+=' | '+o}else{n=new Fb(o,l);l==null?Ii(y,n):l!=null?Ji(y,l,n):Hi(y,null,n,~~Wk(null))}l.indexOf(e)!=0&&(n.d-=25);j=o+Zp+h.className+Zp+h.id;Vb(j,c==0?$p:_p)&&(n.d+=50);Vb(j,aq)&&(n.d+=25);Vb(j,'(first|last)')&&(c==0&&!Vb(n.c,$p)||c==1&&!Vb(n.c,_p))&&(n.d-=65);(Vb(j,bq)||Vb(j,Xp))&&(n.d-=50);Vb(j,c==0?_p:$p)&&(n.d-=200);w=false;r=false;u=td(h);while(!!u&&(!w||!r)){v=u.className+Zp+u.id;if(!w&&Vb(v,aq)){n.d+=25;w=true}if(!r&&Vb(v,bq)){if(!Vb(v,'article|body|content|entry|hentry|main|page|pagination|post|text|blog|story')){n.d-=25;r=true}}u=td(u)}(Vb(l,'p(a|g|ag)?(e|ing|ination)?(=|\\/)[0-9]{1,2}')||Vb(l,'(page|paging)'))&&(n.d+=25);Vb(l,Xp)&&(n.d-=15);q=0;try{q=Kj(o)}catch(a){a=Vf(a);if(!Md(a,20))throw a}q>0&&(q==1?(n.d-=10):(n.d+=0>10-q?0:10-q))}z=null;if(y.e!=0){x=(C=new Dl(y),new Mm(y,C));g=Lm(x);while(jm(g.b.b)){t=Kd(Rm(g),6);t.d>=50&&(!z||z.d<t.d)&&(z=t)}}if(z){s=Rb(z.b,Wp,Kp);return s}return null}
-function nh(){nh=sp;mh=new Ro('[0-9A-Za-z\xAA\xB2-\xB3\xB5\xB9-\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u0236\u0250-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EE\u037A\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03F5\u03F7-\u03FB\u0400-\u0481\u048A-\u04CE\u04D0-\u04F5\u04F8-\u04F9\u0500-\u050F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0640-\u064A\u0660-\u0669\u066E-\u066F\u0671-\u06D3\u06D5\u06E5-\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u074F\u0780-\u07A5\u07B1\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09DC-\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0-\u0AE1\u0AE6-\u0AEF\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB5\u0BB7-\u0BB9\u0BE7-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C60-\u0C61\u0C66-\u0C6F\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0-\u0CE1\u0CE6-\u0CEF\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D60-\u0D61\u0D66-\u0D6F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDD\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6A\u0F88-\u0F8B\u1000-\u1021\u1023-\u1027\u1029-\u102A\u1040-\u1049\u1050-\u1055\u10A0-\u10C5\u10D0-\u10F8\u1100-\u1159\u115F-\u11A2\u11A8-\u11F9\u1200-\u1206\u1208-\u1246\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1286\u1288\u128A-\u128D\u1290-\u12AE\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12CE\u12D0-\u12D6\u12D8-\u12EE\u12F0-\u130E\u1310\u1312-\u1315\u1318-\u131E\u1320-\u1346\u1348-\u135A\u1369-\u137C\u13A0-\u13F4\u1401-\u166C\u166F-\u1676\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1877\u1880-\u18A8\u1900-\u191C\u1946-\u196D\u1970-\u1974\u1D00-\u1D6B\u1E00-\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070-\u2071\u2074-\u2079\u207F-\u2089\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2131\u2133-\u2139\u213D-\u213F\u2145-\u2149\u2153-\u2183\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312C\u3131-\u318E\u3192-\u3195\u31A0-\u31B7\u31F0-\u31FF\u3220-\u3229\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DB5\u4E00-\u9FA5\uA000-\uA48C\uAC00-\uD7A3\uF900-\uFA2D\uFA30-\uFA6A\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]')}
-var Kp='',gq='\n',Zp=' ',Gq='"',Op='$1',Aq='$\uE00A<',tq="'",eq='(',$p='(next|weiter|continue|>([^\\|]|$)|\xBB([^\\|]|$))',_p='(prev|early|old|new|<|\xAB)',lq=')',Cq=', ',Up='.',rq='.com',Tp='/',Yp=':',Qp=': ',Dq='=',Bq='>\uE00A$',Hp='@',hq='@@',Lp='A',nq='CSS1Compat',Ip='DomDistiller',Fq='For input string: "',Rp='H1',Mp='IMG',dq='String',Np='TITLE',iq='Unknown',jq='[',sq='[\b ]+',Vp='[.]',Mq='[Ljava.lang.',Jq='[object Array]',Wp='\\/$',Pp='\\s+',kq=']',fq='anonymous',Sq='com.dom_distiller.client.',Lq='com.google.gwt.core.client.',Nq='com.google.gwt.core.client.impl.',Qq='com.google.gwt.logging.impl.',bq='combx|comment|com-|contact|foot|footer|footnote|masthead|media|meta|outbrain|promo|related|scroll|shoutbox|sidebar|sponsor|shopping|tags|tool|widget',Uq='de.l3s.boilerpipe.document.',Xq='de.l3s.boilerpipe.filters.english.',Wq='de.l3s.boilerpipe.filters.heuristics.',Tq='de.l3s.boilerpipe.sax.',xq='de.l3s.boilerpipe/HEADING',qq='de.l3s.boilerpipe/INDICATES_END_OF_TEXT',wq='de.l3s.boilerpipe/LI',uq='de.l3s.boilerpipe/MIGHT_BE_CONTENT',Jp='de.l3s.boilerpipe/TITLE',vq='de.l3s.boilerpipe/VERY_LIKELY_CONTENT',Iq='fromIndex: ',Hq='g',Kq='java.lang.',Rq='java.util.',Oq='java.util.logging.',Vq='java.util.regex.',pq='msie',cq='null',Eq='number',Sp='object',oq='opera',Pq='org.timepedia.exporter.client.',Yq='org.xml.sax.',aq='pag(e|ing|inat)',Xp='print|archive|comment|discuss|e[\\-]?mail|share|reply|all|login|sign|single',mq='safari',yq='{',zq='}';var _,Xf={},xp={11:1,23:1},Bp={11:1,26:1},Ap={26:1},Dp={27:1},Cp={29:1},yp={30:1},Fp={11:1,25:1},Ep={25:1},vp={},zp={10:1},wp={11:1};Yf(1,-1,vp);_.eQ=function F(a){return this===a};_.gC=function G(){return this.cZ};_.hC=function H(){return yc(this)};_.tS=function I(){return this.cZ.e+Hp+ck(this.hC())};_.toString=function(){return this.tS()};_.tM=sp;Yf(3,1,{2:1,31:1},K);Yf(4,1,{},R);_.y=function S(a){return a!=null&&Md(a,2)};var O=false;Yf(5,1,{3:1,31:1},U);Yf(6,1,{},$);_.y=function ab(a){return a!=null&&Md(a,3)};var X=false;Yf(9,1,{},fb);_.z=function gb(a){var b;b=a;sh(this.b,b.tagName,b.tagName)};_.A=function hb(a){var b,c,d,e,f;switch(a.nodeType){case 3:dn(this.c,a);d=a.data;rh(this.b,(e=d.length,f=Ad(Of,wp,-1,e,1),wk(d,e,f,0),f),0,d.length);return false;case 1:c=a;b=db(c);vh(this.b,c.tagName,c.tagName,b);return true;case 9:default:return false;}};_.b=null;_.c=null;Yf(10,1,{},kb);_.b=null;Yf(12,1,{},pb);_.z=function qb(a){hn(this.b,this.b.c-1);hn(this.e,this.e.c-1)};_.A=function rb(a){if(!this.c.b)return false;dn(this.b,a);dn(this.e,null);if(this.e.c==1){this.d=new vb(a);jn(this.e,0,this.d)}xb(this.c,a)&&ob(this);return true};_.b=null;_.c=null;_.d=null;_.e=null;Yf(13,1,{4:1},vb);_.b=null;_.c=null;Yf(14,1,{},yb);_.b=null;_.c=null;Yf(15,1,{5:1,31:1},Ab);Yf(16,1,{6:1},Fb);_.b=null;_.c=null;_.d=0;Yf(17,1,{},Kb);_.y=function Lb(a){return a!=null&&Md(a,5)};var Hb=false;Yf(19,1,{},Ob);_.z=function Pb(a){};_.A=function Qb(a){if(!this.d.b&&!this.c){return false}if(xb(this.d,a)){this.c=true;dn(this.b,a)}else a.nodeType==3&&!Sb(a.nodeValue)&&(this.c=false);switch(a.nodeType){case 3:return true;case 1:this.c&&a.nodeType==1&&uk(Mp,a.tagName)&&dn(this.b,a);return true;case 9:default:return false;}};_.b=null;_.c=false;_.d=null;Yf(26,1,xp);_.B=function _b(){return this.f};_.tS=function ac(){var a,b;a=this.cZ.e;b=this.B();return b!=null?a+Qp+b:a};_.f=null;Yf(25,26,xp);Yf(24,25,xp,cc);Yf(23,24,xp,dc);_.B=function jc(){this.d==null&&(this.e=gc(this.c),this.b=this.b+Qp+ec(this.c),this.d=eq+this.e+') '+ic(this.c)+this.b,undefined);return this.d};_.b=Kp;_.c=null;_.d=null;_.e=null;Yf(30,1,{});var pc=0,qc=0,rc=0,sc=-1;Yf(32,30,{},Gc);_.b=null;_.c=null;var Cc;Yf(35,1,{},Qc);_.C=function Rc(){var a={};var b=[];var c=arguments.callee.caller.caller;while(c){var d=this.D(c.toString());b.push(d);var e=Yp+d;var f=a[e];if(f){var g,h;for(g=0,h=f.length;g<h;g++){if(f[g]===c){return b}}}(f||(a[e]=[])).push(c);c=c.caller}return b};_.D=function Sc(a){return Jc(a)};_.E=function Tc(a){return []};Yf(37,35,{});_.C=function Xc(){return Mc(this.E(Pc()),this.F())};_.E=function Yc(a){return Wc(this,a)};_.F=function Zc(){return 2};Yf(36,37,{});_.C=function ed(){return _c(this)};_.D=function fd(a){var b,c,d,e;if(a.length==0){return fq}e=Gk(a);e.indexOf('at ')==0&&(e=Ek(e,3));c=e.indexOf(jq);c!=-1&&(e=Gk(e.substr(0,c-0))+Gk(Ek(e,e.indexOf(kq,c)+1)));c=e.indexOf(eq);if(c==-1){c=e.indexOf(Hp);if(c==-1){d=e;e=Kp}else{d=Gk(Ek(e,c+1));e=Gk(e.substr(0,c-0))}}else{b=e.indexOf(lq,c);d=e.substr(c+1,b-(c+1));e=Gk(e.substr(0,c-0))}c=xk(e,Ok(46));c!=-1&&(e=Ek(e,c+1));return (e.length>0?e:fq)+hq+d};_.E=function gd(a){return cd(this,a)};_.F=function hd(){return 3};Yf(38,36,{},jd);Yf(39,1,{});Yf(40,39,{},qd);_.b=Kp;Yf(49,1,{},vd);_.qI=0;var Dd,Ed;Yf(58,1,{},cg);_.b=null;Yf(60,1,yp,gg);_.b=null;Yf(59,60,yp,hg);Yf(67,1,{8:1},ug);_.tS=function vg(){return jq+this.p+'-'+this.o+';tl='+this.q+'; nw='+this.i+';nwl='+this.n+';ld='+this.e+']\t'+(this.c?'CONTENT':'boilerplate')+','+this.d+gq+this.r.tS()};_.b=null;_.c=false;_.d=null;_.e=0;_.f=0;_.i=0;_.j=0;_.k=0;_.n=0;_.o=0;_.p=0;_.q=0;_.r=null;_.s=0;var ng,og;Yf(68,1,{},xg);_.b=null;_.c=null;Yf(69,1,{});Yf(70,69,{},Dg);_.b=0;var Ag;Yf(73,1,{},Og);_.b=false;_.c=0;_.d=false;var Kg,Lg;Yf(74,1,{},Vg);_.b=null;var Qg;Yf(76,1,{},_g);_.b=false;_.c=0;var Yg;Yf(80,1,{},hh);_.b=null;var eh;Yf(81,1,{9:1},jh);_.tS=function kh(){return xe.e+Hp+ck(yc(this))+yq+new Gn(this.b)+zq};_.b=null;Yf(82,1,{},wh);_.b=-1;_.d=false;_.f=0;_.i=false;_.j=0;_.k=0;_.o=null;_.p=0;_.q=false;_.r=null;_.s=0;_.v=0;_.w=null;var mh;var yh,zh,Ah,Bh,Ch;Yf(84,1,zp,Fh);_.G=function Gh(){return true};_.H=function Hh(a,b,c){--a.k;return true};_.I=function Ih(a,b,c,d){++a.k;return true};Yf(85,1,zp,Lh);_.G=function Mh(){return true};_.H=function Nh(a,b,c){return Kh(a)};_.I=function Oh(a,b,c,d){a.f++>0&&Kh(a);if(a.k==0){qh(a);dl(a.x,Aq);bl(a.x,32);a.q=true}return false};Yf(86,1,zp,Qh);_.G=function Rh(){return true};_.H=function Sh(a,b,c){th(a);--a.j;return false};_.I=function Th(a,b,c,d){th(a);++a.j;return false};Yf(87,1,zp,Vh);_.G=function Wh(){return false};_.H=function Xh(a,b,c){qh(a);return false};_.I=function Yh(a,b,c,d){qh(a);return false};Yf(88,1,zp,$h);_.G=function _h(){return false};_.H=function ai(a,b,c){return false};_.I=function bi(a,b,c,d){return false};Yf(89,1,zp,di);_.G=function ei(){return true};_.H=function fi(a,b,c){return true};_.I=function gi(a,b,c,d){oh(a,this.b);return true};_.b=null;Yf(94,1,Ap);_.J=function oi(a){return !!mi(this,a)};_.eQ=function pi(a){var b,c,d,e,f;if(a===this){return true}if(!Md(a,26)){return false}e=Kd(a,26);if(this.M()!=e.M()){return false}for(c=new Il(e.K().b);jm(c.b);){b=Kd(km(c.b),27);d=b.Y();f=b.Z();if(!this.J(d)){return false}if(!Bo(f,this.L(d))){return false}}return true};_.L=function qi(a){var b;b=mi(this,a);return !b?null:b.Z()};_.hC=function ri(){var a,b,c;c=0;for(b=new Il(this.K().b);jm(b.b);){a=Kd(km(b.b),27);c+=a.hC();c=~~c}return c};_.M=function si(){return this.K().b.e};_.tS=function ti(){var a,b,c,d;d=yq;a=false;for(c=new Il(this.K().b);jm(c.b);){b=Kd(km(c.b),27);a?(d+=Cq):(a=true);d+=Kp+b.Y();d+=Dq;d+=Kp+b.Z()}return d+zq};Yf(93,94,Ap);_.J=function Li(a){return yi(this,a)};_.K=function Mi(){return new Dl(this)};_.O=function Ni(a,b){return this.N(a,b)};_.L=function Oi(a){return Bi(this,a)};_.M=function Pi(){return this.e};_.b=null;_.c=null;_.d=false;_.e=0;_.f=null;Yf(92,93,Bp,Ri,Si);_.N=function Ti(a,b){return Qi(a,b)};_.P=function Ui(a){return ~~nc(a)};Yf(91,92,Bp);Yf(90,91,Bp,Yi);var Wi;var Zi;Yf(96,24,xp,bj);Yf(97,1,{11:1,12:1,16:1},hj);_.cT=function ij(a){return gj(this,Kd(a,12))};_.eQ=function jj(a){return Md(a,12)&&Kd(a,12).b==this.b};_.hC=function kj(){return this.b?1231:1237};_.tS=function lj(){return this.b?'true':'false'};_.b=false;var dj,ej;Yf(98,1,{11:1,14:1,16:1},oj);_.cT=function pj(a){return nj(this,Kd(a,14))};_.eQ=function rj(a){return Md(a,14)&&Kd(a,14).b==this.b};_.hC=function sj(){return this.b};_.tS=function tj(){return Qk(this.b)};_.b=0;var vj;Yf(100,1,{15:1},yj);_.tS=function Fj(){return ((this.b&2)!=0?'interface ':(this.b&1)!=0?Kp:'class ')+this.e};_.b=0;_.c=0;_.d=null;_.e=null;Yf(101,24,xp,Hj);Yf(103,1,{11:1,19:1});Yf(102,103,{11:1,16:1,17:1,19:1},Mj);_.cT=function Oj(a){return Lj(this,Kd(a,17))};_.eQ=function Pj(a){return Md(a,17)&&Kd(a,17).b==this.b};_.hC=function Qj(){return Qd(this.b)};_.tS=function Rj(){return Kp+this.b};_.b=0;Yf(104,24,xp,Tj);Yf(105,24,xp,Vj);Yf(106,24,xp,Xj);Yf(107,103,{11:1,16:1,18:1,19:1},$j);_.cT=function _j(a){return Zj(this,Kd(a,18))};_.eQ=function ak(a){return Md(a,18)&&Kd(a,18).b==this.b};_.hC=function bk(){return this.b};_.tS=function dk(){return Kp+this.b};_.b=0;var fk;Yf(110,24,xp,kk);var lk;Yf(112,104,{11:1,20:1,23:1},ok);Yf(113,1,{11:1,21:1},qk);_.tS=function rk(){return this.b+Up+this.e+eq+(this.c!=null?this.c:'Unknown Source')+(this.d>=0?Yp+this.d:Kp)+lq};_.b=null;_.c=null;_.d=0;_.e=null;_=String.prototype;_.cM={1:1,11:1,13:1,16:1};_.cT=function Lk(a){return Mk(this,Kd(a,1))};_.eQ=function Nk(a){return uk(this,a)};_.hC=function Pk(){return Wk(this)};_.tS=_.toString;var Rk,Sk=0,Tk;Yf(115,1,{13:1},Zk);_.tS=function $k(){return this.b.b};Yf(116,1,{13:1,22:1},hl,il);_.tS=function kl(){return this.b.b};Yf(117,106,xp,ml);Yf(118,24,xp,ol);Yf(119,1,{});_.Q=function tl(a){throw new ol('Add not supported on this collection')};_.R=function ul(a){return ql(this,a)};_.S=function vl(a){var b;b=rl(this.T(),a);return !!b};_.U=function wl(){return this.V(Ad(Rf,wp,0,this.M(),0))};_.V=function xl(a){var b,c,d;d=this.M();a.length<d&&(a=yd(a,d));c=this.T();for(b=0;b<d;++b){Cd(a,b,c.X())}a.length>d&&Cd(a,d,null);return a};_.tS=function yl(){return sl(this)};Yf(121,119,Cp);_.eQ=function Bl(a){var b,c,d;if(a===this){return true}if(!Md(a,29)){return false}c=Kd(a,29);if(c.M()!=this.M()){return false}for(b=c.T();b.W();){d=b.X();if(!this.S(d)){return false}}return true};_.hC=function Cl(){var a,b,c;a=0;for(b=this.T();b.W();){c=b.X();if(c!=null){a+=nc(c);a=~~a}}return a};Yf(120,121,Cp,Dl);_.S=function El(a){var b,c,d;if(Md(a,27)){b=Kd(a,27);c=b.Y();if(yi(this.b,c)){d=Bi(this.b,c);return this.b.N(b.Z(),d)}}return false};_.T=function Fl(){return new Il(this.b)};_.M=function Gl(){return this.b.e};_.b=null;Yf(122,1,{},Il);_.W=function Jl(){return jm(this.b)};_.X=function Kl(){return Kd(km(this.b),27)};_.b=null;Yf(124,1,Dp);_.eQ=function Nl(a){var b;if(Md(a,27)){b=Kd(a,27);if(Bo(this.Y(),b.Y())&&Bo(this.Z(),b.Z())){return true}}return false};_.hC=function Ol(){var a,b;a=0;b=0;this.Y()!=null&&(a=nc(this.Y()));this.Z()!=null&&(b=nc(this.Z()));return a^b};_.tS=function Pl(){return this.Y()+Dq+this.Z()};Yf(123,124,Dp,Ql);_.Y=function Rl(){return null};_.Z=function Sl(){return this.b.c};_.$=function Tl(a){return Ii(this.b,a)};_.b=null;Yf(125,124,Dp,Vl);_.Y=function Wl(){return this.b};_.Z=function Xl(){return Di(this.c,this.b)};_.$=function Yl(a){return Ji(this.c,this.b,a)};_.b=null;_.c=null;Yf(126,119,Ep);_._=function _l(a,b){throw new ol('Add not supported on this list')};_.Q=function am(a){this._(this.M(),a);return true};_.eQ=function cm(a){var b,c,d,e,f;if(a===this){return true}if(!Md(a,25)){return false}f=Kd(a,25);if(this.M()!=f.M()){return false}d=this.T();e=f.T();while(d.W()){b=d.X();c=e.X();if(!(b==null?c==null:lc(b,c))){return false}}return true};_.hC=function dm(){var a,b,c;b=1;a=this.T();while(a.W()){c=a.X();b=31*b+(c==null?0:nc(c));b=~~b}return b};_.T=function fm(){return new mm(this)};_.bb=function gm(a){throw new ol('Remove not supported on this list')};_.cb=function hm(a,b){throw new ol('Set not supported on this list')};Yf(127,1,{},mm);_.W=function nm(){return jm(this)};_.X=function om(){return km(this)};_.c=0;_.d=-1;_.e=null;Yf(128,127,{},sm);_.b=null;Yf(129,126,Ep,um);_._=function vm(a,b){bm(a,this.c+1);++this.c;cn(this.d,this.b+a,b)};_.ab=function wm(a){bm(a,this.c);return fn(this.d,this.b+a)};_.bb=function xm(a){var b;bm(a,this.c);b=hn(this.d,this.b+a);--this.c;return b};_.cb=function ym(a,b){bm(a,this.c);return jn(this.d,this.b+a,b)};_.M=function zm(){return this.c};_.b=0;_.c=0;_.d=null;Yf(130,121,Cp,Cm);_.S=function Dm(a){return yi(this.b,a)};_.T=function Em(){return Bm(this)};_.M=function Fm(){return this.c.b.e};_.b=null;_.c=null;Yf(131,1,{},Hm);_.W=function Im(){return jm(this.b.b)};_.X=function Jm(){var a;a=Kd(km(this.b.b),27);return a.Y()};_.b=null;Yf(132,119,{},Mm);_.S=function Nm(a){return Ai(this.b,a)};_.T=function Om(){return Lm(this)};_.M=function Pm(){return this.c.b.e};_.b=null;_.c=null;Yf(133,1,{},Sm);_.W=function Tm(){return jm(this.b.b)};_.X=function Um(){return Rm(this)};_.b=null;Yf(134,126,Ep);_._=function Xm(a,b){var c;c=eo(this,a);ao(c.e,b,c.c);++c.b;c.d=null};_.ab=function Ym(a){return Wm(this,a)};_.T=function Zm(){return eo(this,0)};_.bb=function $m(b){var c,d;c=eo(this,b);try{d=lo(c)}catch(a){a=Vf(a);if(Md(a,28)){throw new Xj("Can't remove element "+b)}else throw a}mo(c);c.c==c.d?(c.c=c.d.b):--c.b;ro(c.d);c.d=null;--c.e.c;return d};_.cb=function _m(b,c){var d,e;d=eo(this,b);try{e=lo(d);mo(d);d.d.d=c;return e}catch(a){a=Vf(a);if(Md(a,28)){throw new Xj("Can't set element "+b)}else throw a}};Yf(135,126,Fp,kn,ln);_._=function mn(a,b){cn(this,a,b)};_.Q=function nn(a){return dn(this,a)};_.R=function on(a){return en(this,a)};_.S=function pn(a){return gn(this,a,0)!=-1};_.ab=function qn(a){return fn(this,a)};_.bb=function rn(a){return hn(this,a)};_.cb=function sn(a,b){return jn(this,a,b)};_.M=function un(){return this.c};_.U=function yn(){return xd(this.b,0,this.c)};_.V=function zn(a){var b;a.length<this.c&&(a=yd(a,this.c));for(b=0;b<this.c;++b){Cd(a,b,this.b[b])}a.length>this.c&&Cd(a,this.c,null);return a};_.c=0;Yf(137,126,Fp,Gn);_.S=function Hn(a){return $l(this,a)!=-1};_.ab=function In(a){return bm(a,this.b.length),this.b[a]};_.cb=function Jn(a,b){return Fn(this,a,b)};_.M=function Kn(){return this.b.length};_.U=function Ln(){return wd(this.b)};_.V=function Mn(a){var b,c;c=this.b.length;a.length<c&&(a=yd(a,c));for(b=0;b<c;++b){Cd(a,b,this.b[b])}a.length>c&&Cd(a,c,null);return a};_.b=null;Yf(140,121,{11:1,29:1},Sn,Tn,Un);_.Q=function Vn(a){return Qn(this,a)};_.S=function Wn(a){return yi(this.b,a)};_.T=function Xn(){return Bm(ni(this.b))};_.M=function Yn(){return this.b.e};_.tS=function Zn(){return sl(ni(this.b))};_.b=null;Yf(141,134,{11:1,24:1,25:1},ho);_.Q=function io(a){return _n(this,a)};_.M=function jo(){return this.c};_.b=null;_.c=0;Yf(142,1,{},no);_.W=function oo(){return this.c!=this.e.b};_.X=function po(){return lo(this)};_.b=0;_.c=null;_.d=null;_.e=null;Yf(143,1,{},so,to);_.b=null;_.c=null;_.d=null;Yf(144,124,Dp,vo);_.Y=function wo(){return this.b};_.Z=function xo(){return this.c};_.$=function yo(a){var b;b=this.c;this.c=a;return b};_.b=null;_.c=null;Yf(145,24,{11:1,23:1,28:1},Ao);Yf(147,1,{},Io);_.b=null;_.c=null;var Do=null;Yf(148,60,yp,Ko);Yf(149,1,{},Oo);_.b=null;_.c=null;_.d=null;Yf(150,1,{},Ro,So);_.b=null;_.c=null;Yf(152,1,{});Yf(151,152,{},bp);var hp;Yf(158,1,{},pp);_.b=null;_.c=null;Yf(159,1,{},rp);var Gp=vc;
+function xk(a,b){var c,d,e,f,g,h;d=false;h=0;f=false;for(g=new mq(b.b);g.c<g.e.fb();){c=$g(kq(g),21);e=!!c.d&&Es(c.d,pw);c.c&&(h+=c.s>=9?c.i:0);e&&h>=a.b&&(f=true);if(f){d=true;nk(c,false)}}return d}
+function Uo(a){var b,c,d,e;b=0;d=a.length;e=d-4;c=0;while(c<e){b=a.charCodeAt(c+3)+31*(a.charCodeAt(c+2)+31*(a.charCodeAt(c+1)+31*(a.charCodeAt(c)+31*b)))|0;c+=4}while(c<d){b=b*31+so(a,c++)}return b|0}
+function Sg(a,b,c){if(c!=null){if(a.qI>0&&!Zg(c,a.qI)){throw new Zm}else if(a.qI==-1&&(c.tM==nu||Yg(c,1))){throw new Zm}else if(a.qI<-1&&!(c.tM!=nu&&!Yg(c,1))&&!Zg(c,-a.qI)){throw new Zm}}return a[b]=c}
+function sb(a){var b,c,d,e,f;a.i=new kr;b=a.n.getElementsByTagName(Ou);for(d=0;d<b.length;++d){f=b[d];c=zb(f);if(c!=null&&!!c.length||Hb(f)){e=new bc;e.f=f.src;e.b=c;e.i=f.width;e.c=f.height;dr(a.i,e)}}}
+function Dm(l,a,b,c){var d=l.b[c];if(d){for(var e=0,f=d.length;e<f;++e){var g=d[e];var h=g.rb();if(l.hb(a,h)){var j=g.sb();g.tb(b);return j}}}else{d=l.b[c]=[]}var g=new ht(a,b);d.push(g);++l.e;return null}
+function Dr(a,b,c,d,e){var f,g,h,j;f=d-c;if(f<7){Ar(b,c,d);return}h=c+e;g=d+e;j=h+(~~(g-h)>>1);Dr(b,a,h,j,-e);Dr(b,a,j,g,-e);if($g(a[j-1],29).cT(a[j])<=0){while(c<d){Sg(b,c++,a[h++])}return}Br(a,h,j,g,b,c,d)}
+function Jt(a,b){var c=[];for(i=0;i<a-1;i++)c.push(b[i]);var d=b.length;var e=a-1;if(d>=a&&Object.prototype.toString.apply(b[e])===Iw){c.push(b[e])}else{var f=[];for(i=e;i<d;i++)f.push(b[i]);c.push(f)}return c}
+function Tj(a,b,c){var d=Sj[a];if(d&&!d.cZ){_=d.prototype}else{!d&&(d=Sj[a]=function(){});_=d.prototype=b<0?{}:Uj(b);_.cM=c}for(var e=3;e<arguments.length;++e){arguments[e].prototype=_}if(d.cZ){_.cZ=d.cZ;d.cZ=null}}
+function se(a){var b,c;b=new Wb;b.e=um(a.c,Lv)?$g(xm(a.c,Lv),1):Mu;b.d=um(a.c,Mv)?$g(xm(a.c,Mv),1):Mu;b.f=um(a.c,Nv)?$g(xm(a.c,Nv),1):Mu;c=ve(a,pv);!c.length&&(c=ve(a,Ov));b.b=!c.length?Qg(Oj,su,1,0,0):Rg(Oj,su,1,[c]);return b}
+function Ok(a,b){var c,d,e,f,g,h;h=Co(a,b,0);if(h.length==1){return null}d=0;e=Mu;for(c=0;c<h.length;++c){g=h[c];if(g.indexOf(qw)!=-1){continue}f=Co(g,rw,0).length;if(f>d||g.length>e.length){d=f;e=g}}return e.length==0?null:Fo(e)}
+function Yk(a){var b,c,d,e;b=false;c=2147483647;for(e=new mq(a.b);e.c<e.e.fb();){d=$g(kq(e),21);if(d.c&&!!d.d&&Es(d.d,uw)){c=d.q}else{if(d.q>c&&!!d.d&&Es(d.d,tw)&&!!d.d&&Es(d.d,vw)&&d.e==0){nk(d,true);b=true}else{c=2147483647}}}return b}
+function ge(a){var b,c,d;c=(d=a.getAttribute(Jv)||Mu,um(ee,d)?$g(xm(ee,d),19):(Ne(),Me));switch(c.c){case 0:b=new ze;break;case 1:b=new we;break;case 2:b=new Fe;break;case 3:b=new Ce;break;case 4:b=new Re;break;default:return null;}return b}
+function Or(a){var b,c,d,e,f,g,h;if(a){for(e=0,d=a.b.length-1;e<d;++e,--d){h=(bq(e,a.b.length),a.b[e]);Fr(a,e,(bq(d,a.b.length),a.b[d]));Fr(a,d,h)}}else{b=new sq(null,0);f=new sq(null,null.b.length);while(b.c<f.c-1){c=kq(b);g=qq(f);rq(b,g);rq(f,c)}}}
+function Xk(a){var b,c,d,e;b=false;c=-1;for(e=new mq(a.b);e.c<e.e.fb();){d=$g(kq(e),21);if(d.c&&!!d.d&&Es(d.d,uw)){c=d.q;break}}if(c==-1){return false}for(e=new mq(a.b);e.c<e.e.fb();){d=$g(kq(e),21);if(!d.c){if(d.i>=100&&d.q==c){nk(d,true);b=true}}}return b}
+function kl(a,b){var c,d,e,f,g,h;for(d=Ss(a.e,0);d.c!=d.e.b;){c=$g(Zs(d),34);if(c){!b.d&&(b.d=new Gs);Ds(b.d,'font-'+c);break}}for(f=Ss(a.n,0);f.c!=f.e.b;){e=$g(Zs(f),42);if(e){for(h=Ss(e,0);h.c!=h.e.b;){g=$g(Zs(h),22);!!g&&(lk(b,g.b),undefined)}}}dr(a.t,b)}
+function Ak(a){var b,c,d,e,f,g;g=a.b;d=new sq(g,0);if(d.c>=d.e.fb()){return false}f=(kk(),jk);b=$g(kq(d),21);e=d.c<d.e.fb()?$g(kq(d),21):jk;c=zk(f,b,e)|false;if(e!=jk){while(d.c<d.e.fb()){f=b;b=e;e=$g(kq(d),21);c=zk(f,b,e)|c}f=b;b=e;e=jk;c=zk(f,b,e)|c}return c}
+function Ot(a,b,c,d,e){var f,g,h,j,l,m,n,o,q;n=_g(!c?b.c:ym(b,c,~~Nf(c)))[d][e.length];h=null;o=null;f=null;for(g=0,j=!n?0:n.length;g<j;++g){m=n[g];if(Zt(m,e)){h=m[0];o=m[1];f=m[2];break}}if(!h){return null}else{e=f?f(a,e):e;l=(q=h.apply(a,e),[o?o(q):q]);return l}}
+function In(a){var b,c,d,e;if(a==null){throw new no(bw)}c=a.length;d=c>0&&a.charCodeAt(0)==45?1:0;for(b=d;b<c;++b){if(nn(a.charCodeAt(b))==-1){throw new no(Ew+a+Fw)}}e=parseInt(a,10);if(isNaN(e)){throw new no(Ew+a+Fw)}else if(e<-2147483648||e>2147483647){throw new no(Ew+a+Fw)}return e}
+function sg(a){var b,c,d,e,f,g,h,j,l;l=Qg(Nj,vu,38,a.length,0);for(e=0,f=l.length;e<f;++e){j=Co(a[e],gw,0);b=-1;d=hw;if(j.length==2&&j[1]!=null){h=j[1];g=xo(h,No(58));c=yo(h,No(58),g-1);d=h.substr(0,c-0);if(g!=-1&&c!=-1){$f(h.substr(c+1,g-(c+1)));b=$f(Do(h,g+1))}}l[e]=new po(j[0],d+Ju+b)}mf(l)}
+function Rk(a){var b,c,d,e,f,g;d=0;g=-1;c=-1;for(f=new mq(a.b);f.c<f.e.fb();){e=$g(kq(f),21);if(c==-1&&!!e.d&&Es(e.d,Lu)){g=d;c=-1}c==-1&&e.c&&(c=d);++d}if(c<=g||g==-1){return false}b=false;for(f=new mq(new uq(a.b,g,c));f.c<f.e.fb();){e=$g(kq(f),21);!!e.d&&Es(e.d,tw)&&(b=nk(e,true)|b)}return b}
+function we(){re.call(this,(Ne(),Ie));Cm(this.c,Rv,Mu);Cm(this.c,$u,Mu);Cm(this.c,Qv,Mu);Cm(this.c,Pv,Mu);Cm(this.c,Mv,Mu);Cm(this.c,Lv,Mu);Cm(this.c,pv,Mu);Cm(this.c,Ov,Mu);Cm(this.c,Nv,Mu);Cm(this.b,$u,null);Cm(this.b,Qv,null);Cm(this.b,pv,null);Cm(this.b,Ov,null);Cm(this.b,Sv,null);Cm(this.b,Tv,null)}
+function Pk(a,b){var c,d,e,f;if(!a.b){return false}c=false;for(e=new mq(b.b);e.c<e.e.fb();){d=$g(kq(e),21);f=d.r.tS();f=zo(f,160,32);f=Ao(f,sw,Mu);f=Fo(f).toLowerCase();if(Es(a.b,f)){!d.d&&(d.d=new Gs);Ds(d.d,Lu);c=true;break}f=Fo(At(Dt(Lk,f),Mu));if(Es(a.b,f)){!d.d&&(d.d=new Gs);Ds(d.d,Lu);c=true;break}}return c}
+function Qc(a,b){var c,d,e,f,g,h,j;d=b.getElementsByTagName(av);for(e=0;e<d.length;++e){g=d[e];j=(g.getAttribute('property')||Mu).toLowerCase();for(f=0;f<a.f.length;++f){h=$g(Rr(a.d,a.f[f].d),1)+fv;if(wo(j,h+a.f[f].b)!=0)continue;j=Do(j,h.length);c=true;!!a.f[f].c&&(c=a.f[f].c.V(j,g.content,a.i));c&&Cm(a.i,a.f[f].b,g.content)}}}
+function hd(b){var c,d,e,f;f=Qg(Gj,tu,7,b.b.c,0);for(c=0;c<b.b.c;++c){d=$g(fr(b.b,c),40);e=new bc;f[c]=e;e.f=d[1]!=null&&!!d[1].length?d[1]:d[0];d[2]!=null&&(e.d=d[2]);d[3]!=null&&(e.e=d[3]);try{d[4]!=null&&(e.i=In(d[4]))}catch(a){a=Qj(a);if(!ah(a,36))throw a}try{d[5]!=null&&(e.c=In(d[5]))}catch(a){a=Qj(a);if(!ah(a,36))throw a}}return f}
+function Nt(a,b,c,d,e,f,g){var h,j,l,m,n;j=f?a.d:a.b;if(g){for(m=Lt(_g(!c?j.c:ym(j,c,~~Nf(c))),d),l=m;l>=1;--l){h=Jt(l,e);n=Ot(b,j,c,d,h);if(!n){h=St(b,h);n=Ot(b,j,c,d,h)}if(n){return n}}}else{n=Ot(b,j,c,d,e);if(!n){e=St(b,e);n=Ot(b,j,c,d,e)}if(n){return n}}throw new rf("Can't find exported method for given arguments: "+d+fv+e.length+fw)}
+function ye(b){var c;c=new bc;c.f=um(b.c,Uv)?$g(xm(b.c,Uv),1):Mu;!c.f.length&&(c.f=um(b.c,hv)?$g(xm(b.c,hv),1):Mu);c.e=um(b.c,Vv)?$g(xm(b.c,Vv),1):Mu;c.b=um(b.c,Wv)?$g(xm(b.c,Wv),1):Mu;try{c.i=In(um(b.c,Xv)?$g(xm(b.c,Xv),1):Mu)}catch(a){a=Qj(a);if(!ah(a,33))throw a}try{c.c=In(um(b.c,Yv)?$g(xm(b.c,Yv),1):Mu)}catch(a){a=Qj(a);if(!ah(a,33))throw a}return c}
+function Co(n,a,b){var c=new RegExp(a,Gw);var d=[];var e=0;var f=n;var g=null;while(true){var h=c.exec(f);if(h==null||f==Mu||e==b-1&&b>0){d[e]=f;break}else{d[e]=f.substring(0,h.index);f=f.substring(h.index+h[0].length,f.length);c.lastIndex=0;if(g==f){d[e]=f.substring(0,1);f=f.substring(1)}g=f;e++}}if(b==0&&n.length>0){var j=d.length;while(j>0&&d[j-1]==Mu){--j}j<d.length&&d.splice(j,d.length-j)}var l=Ho(d.length);for(var m=0;m<d.length;++m){l[m]=d[m]}return l}
+function Zt(a,b){var c,d,e,f,g,h,j,l,m,n;for(e=0,m=b.length;e<m;++e){l=a[e+3];c=$t(b,e);if(to(c,l)){continue}if(to('string',l)&&to(bw,c)){continue}h=to(Dw,c);f=to('boolean',c);if(Gi===l){h&&(b[e]=new Kn(b[e]),undefined);f&&(b[e]=(bn(),b[e]?an:_m),undefined);continue}j=h||f;g=!j&&l!=null&&Bf(l)==vi;if(g){n=b[e];if(n==null||Xt(n,$g(l,28))){continue}if(bh(n)){d=Wt(_g(n));if(d!=null){if(Xt(d,$g(l,28))){b[e]=d;continue}}}}if(to(Uu,l)&&!h&&!f){continue}return false}return true}
+function Pj(){var a;!!$stats&&Vj('com.google.gwt.useragent.client.UserAgentAsserter');a=gk();to(lw,a)||($wnd.alert('ERROR: Possible problem with your *.gwt.xml module file.\nThe compile time user.agent value (safari) does not match the runtime user.agent value ('+a+'). Expect more errors.\n'),undefined);!!$stats&&Vj('com.google.gwt.user.client.DocumentModeAsserter');fk();!!$stats&&Vj('com.dom_distiller.client.DomDistiller');cb();au();new tc;new Q;new $;new mc;new Ac;new Wd}
+function Nd(){var a,b,c,d,e,f;c=$wnd.location.pathname;f=Co(c,tv,0);Or(new Gr(f));a=new kr;for(b=0;b<f.length;++b){e=f[b];if(e.indexOf(Wu)!=-1){d=Co(e,uv,0)[1];gf(d,'[^a-zA-Z]')||(e=Co(e,uv,0)[0])}e=cf(e,',00',Mu);b<2&&(e=cf(e,'((_|-)?p[a-z]*|(_|-))[0-9]{1,2}$',Mu));if(!e.length)continue;if(b<2&&gf(e,'^\\d{1,2}$'))continue;if(b==0&&uo(e,'index'))continue;if(b<2&&e.length<3&&!gf(f[0],'[a-z]')){continue}Sg(a.b,a.c++,e)}return $wnd.location.protocol+'//'+$wnd.location.host+tv+Pd(a)}
+function ml(a,b,c,d){var e,f,g,h,j;++a.v;if(a.d){ol(a);a.d=false}if(a.k!=0){return}j=false;g=false;if(d==0){return}f=c+d;for(h=c;h<f;++h){ef(rn(b[h]))&&(b[h]=32)}while(c<f){e=b[c];if(e==32){j=true;++c;--d}else{break}}while(d>0){e=b[c+d-1];if(e==32){g=true;--d}else{break}}if(d==0){if(j||g){if(!a.q){ap(a.u,32);ap(a.x,32)}a.q=true}else{a.q=false}return}if(j){if(!a.q){ap(a.u,32);ap(a.x,32)}}a.b==-1&&(a.b=a.s);ep(a.u,b,c,d);ep(a.x,b,c,d);if(g){ap(a.u,32);ap(a.x,32)}a.q=g;Ds(a.c,co(a.v))}
+function P(g){var d=bu('com.dom_distiller.ContentExtractor');var e,f=g;$wnd.com.dom_distiller.ContentExtractor=Iu(function(){var a,b=this,c=arguments;c.length==1&&f.z(c[0])?(a=c[0]):c.length==0&&(a=new J);b.g=a;eu(a,b);return b});e=$wnd.com.dom_distiller.ContentExtractor.prototype=new Object;$wnd.com.dom_distiller.ContentExtractor.extractContent=Iu(function(){return K()});if(d)for(p in d)$wnd.com.dom_distiller.ContentExtractor[p]===undefined&&($wnd.com.dom_distiller.ContentExtractor[p]=d[p])}
+function ol(a){var b,c,d,e,f,g,h,j,l,m,n,o,q,r;if(a.j==0){uo(Pu,a.o)&&a.j==0&&pl(a,Fo(a.x.b.b));fp(a.u);fp(a.x);return}c=a.x.b.b.length;switch(c){case 0:return;case 1:if(a.q){fp(a.u);fp(a.x);return}}r=Xm(a.x);f=0;d=0;j=0;b=-1;e=0;g=0;for(n=0,o=r.length;n<o;++n){m=r[n];if(to(zw,m)){a.i=true}else if(to(Aw,m)){a.i=false}else if(yt(Dt(hl,m))){++e;++f;++g;a.i&&++d;q=m.length;b+=q+1;if(b>80){++j;b=q;g=1}}else{++e}}if(e==0){return}if(j==0){h=f;j=1}else{h=f-g}l=new pk(ff(a.u.b.b),a.c,f,d,h,j,a.p);a.c=new Fs;++a.p;fp(a.u);fp(a.x);ok(l,a.b);kl(a,l);a.b=-1}
+function Vk(a,b){var c,d,e,f,g,h,j,l,m,n,o;n=b.b;if(n.c<2){return false}g=-1;e=null;f=-1;c=0;h=-1;for(m=new mq(n);m.c<m.e.fb();){l=$g(kq(m),21);if(l.c){j=l.i;if(j>g){e=l;g=j;h=c;a.b&&(f=l.q)}}++c}for(m=new mq(n);m.c<m.e.fb();){l=$g(kq(m),21);if(l==e){nk(l,true);!l.d&&(l.d=new Gs);Ds(l.d,uw)}else{nk(l,false);!l.d&&(l.d=new Gs);Ds(l.d,tw)}}if(a.b&&h!=-1){for(d=new sq(n,h);d.c>0;){l=$g(qq(d),21);o=l.q;if(o<f){break}else o==f&&l.i>=a.c&&nk(l,true)}for(d=new sq(n,h);d.c<d.e.fb();){l=$g(kq(d),21);o=l.q;if(o<f){break}else o==f&&l.i>=a.c&&nk(l,true)}}return true}
+function gk(){var b=navigator.userAgent.toLowerCase();var c=function(a){return parseInt(a[1])*1000+parseInt(a[2])};if(function(){return b.indexOf(nw)!=-1}())return nw;if(function(){return b.indexOf('webkit')!=-1}())return lw;if(function(){return b.indexOf(ow)!=-1&&$doc.documentMode>=9}())return 'ie9';if(function(){return b.indexOf(ow)!=-1&&$doc.documentMode>=8}())return 'ie8';if(function(){var a=/msie ([0-9]+)\.([0-9]+)/.exec(b);if(a&&a.length==3)return c(a)>=6000}())return 'ie6';if(function(){return b.indexOf('gecko')!=-1}())return 'gecko1_8';return 'unknown'}
+function Vd(g){var d=bu('com.dom_distiller.PagingLinksFinder');var e,f=g;$wnd.com.dom_distiller.PagingLinksFinder=Iu(function(){var a,b=this,c=arguments;c.length==1&&f.z(c[0])?(a=c[0]):c.length==0&&(a=new Ld);b.g=a;eu(a,b);return b});e=$wnd.com.dom_distiller.PagingLinksFinder.prototype=new Object;$wnd.com.dom_distiller.PagingLinksFinder.findNext=Iu(function(a){return Kd(),Od(a,0)});$wnd.com.dom_distiller.PagingLinksFinder.findPrevious=Iu(function(a){return Kd(),Od(a,1)});if(d)for(p in d)$wnd.com.dom_distiller.PagingLinksFinder[p]===undefined&&($wnd.com.dom_distiller.PagingLinksFinder[p]=d[p])}
+function Z(g){var d=bu('com.dom_distiller.DocumentTitleGetter');var e,f=g;$wnd.com.dom_distiller.DocumentTitleGetter=Iu(function(){var a,b=this,c=arguments;c.length==1&&f.z(c[0])?(a=c[0]):c.length==0&&(a=new U);b.g=a;eu(a,b);return b});e=$wnd.com.dom_distiller.DocumentTitleGetter.prototype=new Object;$wnd.com.dom_distiller.DocumentTitleGetter.getDocumentTitle=Iu(function(a,b){return du(null,ih,0,arguments,true,false)[0]});cu(ih,{0:{2:[[V,null,undefined,Gi,Uu]]}},true);if(d)for(p in d)$wnd.com.dom_distiller.DocumentTitleGetter[p]===undefined&&($wnd.com.dom_distiller.DocumentTitleGetter[p]=d[p])}
+function je(a,b,c){var d,e,f,g,h,j,l,m,n,o;h=null;g=b.hasAttribute('ITEMSCOPE')&&b.hasAttribute(Jv);j=c?me(b):Qg(Oj,su,1,0,0);if(g){h=ge(b);!!h&&h.d!=(Ne(),Me)&&(!c||c.d!=(Ne(),Me)||j.length==0)&&dr(a.c,h)}if(j.length>0&&c.d!=(Ne(),Me)&&(!h||h.d!=(Ne(),Me))){for(f=0;f<j.length;++f){h?(um(c.b,j[f])&&Cm(c.b,j[f],h),undefined):qe(c,j[f],(l=Mu,m=b.tagName,um(de,m)&&(l=Ig(b,$g(xm(de,m),1))),!l.length&&(l=b.textContent),l))}}!a.b.length&&(a.b=(n=Mu,o=b.tagName,(uo(o,Nu)||uo(o,Ev))&&uo(b.getAttribute('REL')||Mu,pv)&&(n=b.textContent),n));e=b.childNodes;for(f=0;f<e.length;++f){d=e[f];if(d.nodeType!=1)continue;je(a,d,h?h:c)}}
+function V(a,b){var c,d,e,f,g,h,j;c=Mu;d=Mu;if(Bf(a)==Mi){c=d=(f=a,ch(f)?f.tS():f.toString?f.toString():'[JavaScriptObject]')}else if(b){e=b.getElementsByTagName(Pu);e.length>0&&(c=d=e[0].textContent)}if(c==Mu)return Mu;if(gf(c,' [\\|\\-] ')){c=cf(d,'(.*)[\\|\\-] .*',Qu);Co(c,Ru,0).length<3&&(c=cf(d,'[^\\|\\-]*[\\|\\-](.*)',Qu))}else if(c.indexOf(Su)!=-1){c=cf(d,'.*:(.*)',Qu);Co(c,Ru,0).length<3&&(c=cf(d,'[^:]*[:](.*)',Qu))}else if(!!b&&(c.length>150||c.length<15)){c=(g=b.getElementsByTagName(Tu),g.length==1?g[0].textContent:null);c==null&&(c=d)}c=(h=new Ft('^\\s+|\\s+$'),j=new Bt(h.c,h.b,c),At(j,Mu));Co(c,Ru,0).length<=4&&(c=d);return c}
+function Qk(a){Mk();var b;if(a==null){this.b=null}else{a=zo(a,160,32);a=Ao(a,sw,Mu);a=Fo(a).toLowerCase();if(a.length==0){this.b=null}else{this.b=new Fs;Ds(this.b,a);b=Ok(a,'[ ]*[\\|\xBB|-][ ]*');b!=null&&Ds(this.b,b);b=Ok(a,'[ ]*[\\|\xBB|:][ ]*');b!=null&&Ds(this.b,b);b=Ok(a,'[ ]*[\\|\xBB|:\\(\\)][ ]*');b!=null&&Ds(this.b,b);b=Ok(a,'[ ]*[\\|\xBB|:\\(\\)\\-][ ]*');b!=null&&Ds(this.b,b);b=Ok(a,'[ ]*[\\|\xBB|,|:\\(\\)\\-][ ]*');b!=null&&Ds(this.b,b);b=Ok(a,'[ ]*[\\|\xBB|,|:\\(\\)\\-\xA0][ ]*');b!=null&&Ds(this.b,b);Nk(this.b,a,'[ ]+[\\|][ ]+');Nk(this.b,a,'[ ]+[\\-][ ]+');Ds(this.b,Bo(a,' - [^\\-]+$',Mu));Ds(this.b,Bo(a,'^[^\\-]+ - ',Mu))}}}
+function K(){var o,q,r,s;I();var a,b,c,d,e,f,g,h,j,l,m,n;g=new rl;f=$doc.documentElement;n=(db(),o=new gb(g),mb(new nb(o),f),o.c);ol(g);e=(ol(g),new sk(g.w,g.t));true|Bk(e)|Pk(new Qk(e.c),e)|Ak(e)|xk((wk(),vk),e)|Zk(e)|Ik((Hk(),Fk),e)|bl((al(),_k),e)|Ik(Gk,e)|Vk((Uk(),Tk),e)|Rk(e)|Xk(e)|Yk(e);d=new kr;for(m=new mq(e.b);m.c<m.e.fb();){l=$g(kq(m),21);!!l.d&&Es(l.d,Lu)||er(d,l.b)}q=Ng(d.b,0,d.c);Cr(q,0,q.length);Nr(d,q);c=new lr(d.c);for(j=new mq(d);j.c<j.e.fb();){h=$g(kq(j),34);dr(c,_g(fr(n,h.b-1)))}b=Zd(c,$doc.documentElement);a=Mc((r=new Hc(b),s=Dc((bq(0,b.c),_g(b.b[0]))),mb(new nb(r),s),Ec(r.d,(bq(0,b.c),_g(b.b[0])))));if(a.nodeType!=1){return Mu}L(a);return a.innerHTML}
+function Ik(a,b){var c,d,e,f,g,h,j,l,m,n,o;n=b.b;if(n.c<2){return false}d=false;if(a.b){j=null;g=0;for(m=new mq(n);m.c<m.e.fb();){l=$g(kq(m),21);++g;if(l.c){j=l;break}}if(!j){return false}}else{j=(bq(0,n.c),$g(n.b[0],21));g=1}for(f=new sq(n,g);f.c<f.e.fb();){c=$g(kq(f),21);if(!c.c){j=c;continue}e=c.p-j.o-1;if(e<=a.c){h=true;a.b&&(!j.c||!c.c)&&(h=false);h&&a.d&&j.q!=c.q&&(h=false);if(h){ah(j.r,39)||(j.r=new hp(j.r));o=$g(j.r,39);o.b.b+=fw;bp(o,c.r);j.i+=c.i;j.j+=c.j;j.k+=c.k;j.n+=c.n;j.p=ho(j.p,c.p);j.o=go(j.o,c.o);mk(j);j.c=j.c|c.c;!j.b&&(j.b=new Fs);pp(j.b,c.b);j.f+=c.f;!!c.d&&(!j.d?(j.d=new Hs(c.d)):j.d.kb(c.d));j.q=ho(j.q,c.q);lq(f);d=true}else{j=c}}else{j=c}}return d}
+function lc(g){var d=bu('com.dom_distiller.MarkupParser.Article');var e,f=g;$wnd.com.dom_distiller.MarkupParser.Article=Iu(function(){var a,b=this,c=arguments;c.length==1&&f.z(c[0])?(a=c[0]):c.length==0&&(a=new Wb);b.g=a;eu(a,b);return b});e=$wnd.com.dom_distiller.MarkupParser.Article.prototype=new Object;e.getAuthors=Iu(function(){return gu(this.g.M())});e.getExpirationTime=Iu(function(){return this.g.N()});e.getModifiedTime=Iu(function(){return this.g.O()});e.getPublishedTime=Iu(function(){return this.g.P()});e.getSection=Iu(function(){return this.g.Q()});if(d)for(p in d)$wnd.com.dom_distiller.MarkupParser.Article[p]===undefined&&($wnd.com.dom_distiller.MarkupParser.Article[p]=d[p])}
+function zc(g){var d=bu('com.dom_distiller.MarkupParser.Image');var e,f=g;$wnd.com.dom_distiller.MarkupParser.Image=Iu(function(){var a,b=this,c=arguments;c.length==1&&f.z(c[0])?(a=c[0]):c.length==0&&(a=new bc);b.g=a;eu(a,b);return b});e=$wnd.com.dom_distiller.MarkupParser.Image.prototype=new Object;e.getCaption=Iu(function(){return this.g.R()});e.getHeight=Iu(function(){return this.g.S()});e.getSecureUrl=Iu(function(){return this.g.T()});e.getType=Iu(function(){return this.g.J()});e.getUrl=Iu(function(){return this.g.K()});e.getWidth=Iu(function(){return this.g.U()});if(d)for(p in d)$wnd.com.dom_distiller.MarkupParser.Image[p]===undefined&&($wnd.com.dom_distiller.MarkupParser.Image[p]=d[p])}
+function Pc(a,b){var c,d,e,f,g,h,j,l,m,n,o,q,r;o=Mu;to('HTML',b.tagName)&&(o=b.getAttribute(cv)||Mu);if(!o.length){f=b.getElementsByTagName('HEAD');f.length==1&&(o=f[0].getAttribute(cv)||Mu)}if(!o.length){e=b.attributes;for(g=0;g<e.length;++g){m=e[g];c=m.nodeName.toLowerCase();l=new Ft('^xmlns:(\\w+)');j=new Bt(l.c,l.b,c);j.b=dk(j.d,j.c);if(!j.b)continue;d=m.nodeValue;r=new Ft('^http:\\/\\/ogp.me\\/ns(\\/\\w+)*#');q=new Bt(r.c,r.b,d);q.b=dk(q.d,q.c);!!q.b&&Rc(a,zt(j,1),zt(q,1))}}else{n=new Ft('((\\w+):\\s+(http:\\/\\/ogp.me\\/ns(\\/\\w+)*#))\\s*');h=new Bt(n.c,n.b,o);while(h.b=dk(h.d,h.c),!!h.b){Rc(a,zt(h,2),zt(h,4))}}Rr(a.d,(xd(),vd))==null&&Sr(a.d,vd,'og');Rr(a.d,wd)==null&&Sr(a.d,wd,dv);Rr(a.d,ud)==null&&Sr(a.d,ud,ev)}
+function Um(){sm(this);Rm(this,'STYLE',(yl(),vl));Rm(this,'SCRIPT',vl);Rm(this,'OPTION',vl);Rm(this,Gv,vl);Rm(this,Cv,vl);Rm(this,'APPLET',vl);Rm(this,Ev,vl);Rm(this,Nu,tl);Rm(this,'BODY',ul);Rm(this,'STRIKE',wl);Rm(this,'U',wl);Rm(this,'B',wl);Rm(this,'I',wl);Rm(this,'EM',wl);Rm(this,'STRONG',wl);Rm(this,'SPAN',wl);Rm(this,'SUP',wl);Rm(this,'CODE',wl);Rm(this,'TT',wl);Rm(this,'SUB',wl);Rm(this,'VAR',wl);Rm(this,'ABBR',xl);Rm(this,'ACRONYM',xl);Rm(this,'FONT',wl);Rm(this,'NOSCRIPT',vl);Rm(this,'LI',new $l(new el(Rg(Oj,su,1,[vw]))));Rm(this,Tu,new $l(new el(Rg(Oj,su,1,['de.l3s.boilerpipe/H1',ww]))));Rm(this,'H2',new $l(new el(Rg(Oj,su,1,['de.l3s.boilerpipe/H2',ww]))));Rm(this,'H3',new $l(new el(Rg(Oj,su,1,['de.l3s.boilerpipe/H3',ww]))))}
+function Bk(a){var b,c,d,e,f,g,h;b=false;for(f=new mq(a.b);f.c<f.e.fb();){e=$g(kq(f),21);d=e.i;if(d<15){g=Fo(e.r.tS());c=g.length;if(c>=8){h=g.toLowerCase();if(h.indexOf('comments')==0||Dk(h,c,Rg(Oj,su,1,[' comments',' users responded in']))||h.indexOf('\xA9 reuters')==0||h.indexOf('please rate this')==0||h.indexOf('post a comment')==0||h.indexOf('what you think...')!=-1||h.indexOf('add your comment')!=-1||h.indexOf('add comment')!=-1||h.indexOf('reader views')!=-1||h.indexOf('have your say')!=-1||h.indexOf('reader comments')!=-1||h.indexOf('r\xE4tta artikeln')!=-1||to(h,'thanks for your comments - this feedback is now closed')){!e.d&&(e.d=new Gs);Ds(e.d,pw);b=true}}else e.e==1&&to(g,'Comment')&&(!e.d&&(e.d=new Gs),Ds(e.d,pw))}}return b}
+function fe(){fe=nu;ee=new Nm;Cm(ee,'http://schema.org/ImageObject',(Ne(),Je));Cm(ee,'http://schema.org/Article',Ie);Cm(ee,'http://schema.org/BlogPosting',Ie);Cm(ee,'http://schema.org/NewsArticle',Ie);Cm(ee,'http://schema.org/ScholarlyArticle',Ie);Cm(ee,'http://schema.org/TechArticle',Ie);Cm(ee,'http://schema.org/Person',Le);Cm(ee,'http://schema.org/Organization',Ke);Cm(ee,'http://schema.org/Corporation',Ke);Cm(ee,'http://schema.org/EducationalOrganization',Ke);Cm(ee,'http://schema.org/GovernmentOrganization',Ke);Cm(ee,'http://schema.org/NGO',Ke);de=new Nm;Cm(de,Ou,Bv);Cm(de,'AUDIO',Bv);Cm(de,Cv,Bv);Cm(de,'IFRAME',Bv);Cm(de,'SOURCE',Bv);Cm(de,'TRACK',Bv);Cm(de,'VIDEO',Bv);Cm(de,Nu,Dv);Cm(de,Ev,Dv);Cm(de,'AREA',Dv);Cm(de,av,Fv);Cm(de,'TIME','DATETIME');Cm(de,Gv,Hv);Cm(de,Hv,Iv);Cm(de,'METER',Iv)}
+function Sc(a){var b;this.c=new jd;this.e=new Cd;this.b=new ed;this.f=Rg(Ij,vu,11,[new Fd(_u,(xd(),vd),null),new Fd(gv,vd,null),new Fd(hv,vd,null),new Fd(iv,vd,null),new Fd(jv,vd,null),new Fd(kv,vd,this.c),new Fd('image:',vd,this.c),new Fd('first_name',wd,this.e),new Fd('last_name',wd,this.e),new Fd(lv,ud,this.b),new Fd(mv,ud,this.b),new Fd(nv,ud,this.b),new Fd(ov,ud,this.b),new Fd(pv,ud,this.b)]);this.i=new Nm;this.d=new Ur(wh);Pc(this,a);Qc(this,a);id(this.c);b=$g(Rr(this.d,vd),1)+fv;if(!(um(this.i,_u)?$g(xm(this.i,_u),1):Mu).length)throw new pf(qv+b+'title" property is missing.');if(!(um(this.i,gv)?$g(xm(this.i,gv),1):Mu).length)throw new pf(qv+b+'type" property is missing.');if(!(um(this.i,hv)?$g(xm(this.i,hv),1):Mu).length)throw new pf(qv+b+'url" property is missing.');if(hd(this.c).length==0)throw new pf(qv+b+'image" property is missing.')}
+function sc(g){var d=bu('com.dom_distiller.MarkupParser');var e,f=g;$wnd.com.dom_distiller.MarkupParser=Iu(function(){var a,b=this,c=arguments;c.length==1&&f.z(c[0])?(a=c[0]):c.length==1&&(a=new Kb(c[0]));b.g=a;eu(a,b);return b});e=$wnd.com.dom_distiller.MarkupParser.prototype=new Object;$wnd.com.dom_distiller.MarkupParser.ARTICLE_TYPE=bv;e.getArticle=Iu(function(){return fu(this.g.C())});e.getAuthor=Iu(function(){return this.g.D()});e.getCopyright=Iu(function(){return this.g.E()});e.getDescription=Iu(function(){return this.g.F()});e.getImages=Iu(function(){return hu(this.g.G())});e.getPublisher=Iu(function(){return this.g.H()});e.getTitle=Iu(function(){return this.g.I()});e.getType=Iu(function(){return this.g.J()});e.getUrl=Iu(function(){return this.g.K()});e.optOut=Iu(function(){return this.g.L()});if(d)for(p in d)$wnd.com.dom_distiller.MarkupParser[p]===undefined&&($wnd.com.dom_distiller.MarkupParser[p]=d[p])}
+function fk(){var a,b,c;b=$doc.compatMode;a=Rg(Oj,su,1,[mw]);for(c=0;c<a.length;++c){if(to(a[c],b)){return}}a.length==1&&to(mw,a[0])&&to('BackCompat',b)?"GWT no longer supports Quirks Mode (document.compatMode=' BackCompat').<br>Make sure your application's host HTML page has a Standards Mode (document.compatMode=' CSS1Compat') doctype,<br>e.g. by using &lt;!doctype html&gt; at the start of your application's HTML page.<br><br>To continue using this unsupported rendering mode and risk layout problems, suppress this message by adding<br>the following line to your*.gwt.xml module file:<br>&nbsp;&nbsp;&lt;extend-configuration-property name=\"document.compatMode\" value=\""+b+'"/&gt;':"Your *.gwt.xml module configuration prohibits the use of the current doucment rendering mode (document.compatMode=' "+b+"').<br>Modify your application's host HTML page doctype, or update your custom 'document.compatMode' configuration property settings."}
+function Od(b,c){var d,e,f,g,h,j,l,m,n,o,q,r,s,t,u,v,w,x,y,z,A,B;e=Nd();B=cf($wnd.location.href,vv,Mu);d=b.getElementsByTagName(Nu);y=new Nm;for(f=0;f<d.length;++f){h=d[f];l=cf(cf(h.href,'#.*$',Mu),vv,Mu);if(!l.length||!gf(l,'^https?://')||uo(l,B)||c==0&&uo(l,e)){continue}A=Co(l,'\\/+',0);if(A.length<3||!uo($wnd.location.host,A[1])){continue}o=h.textContent;if(gf(o,wv)||o.length>25){continue}if(c==0){m=cf(l,e,Mu);if(!gf(m,'\\d')){continue}}n=null;if(l==null?y.d:l!=null?fv+l in y.f:Am(y,null,~~Vo(null))){n=$g(l==null?y.c:l!=null?y.f[fv+l]:ym(y,null,~~Vo(null)),13);n.d+=' | '+o}else{n=new Rd(f,o,l);l==null?Em(y,n):l!=null?Fm(y,l,n):Dm(y,null,n,~~Vo(null))}l.indexOf(e)!=0&&(n.e-=25);j=o+Yu+h.className+Yu+h.id;gf(j,c==0?xv:yv)&&(n.e+=50);gf(j,zv)&&(n.e+=25);gf(j,'(first|last)')&&(c==0&&!gf(n.d,xv)||c==1&&!gf(n.d,yv))&&(n.e-=65);(gf(j,Av)||gf(j,wv))&&(n.e-=50);gf(j,c==0?yv:xv)&&(n.e-=200);w=false;r=false;u=Jg(h);while(!!u&&(!w||!r)){v=u.className+Yu+u.id;if(!w&&gf(v,zv)){n.e+=25;w=true}if(!r&&gf(v,Av)){if(!gf(v,'article|body|content|entry|hentry|main|page|pagination|post|text|blog|story')){n.e-=25;r=true}}u=Jg(u)}(gf(l,'p(a|g|ag)?(e|ing|ination)?(=|\\/)[0-9]{1,2}')||gf(l,'(page|paging)'))&&(n.e+=25);gf(l,wv)&&(n.e-=15);q=0;try{q=In(o)}catch(a){a=Qj(a);if(!ah(a,36))throw a}q>0&&(q==1?(n.e-=10):(n.e+=0>10-q?0:10-q))}z=null;if(y.e!=0){x=jm(y);g=Lq(x);while(jq(g.b.b)){s=$g(Rq(g),13);s.e>=50&&(!z||z.e<s.e)&&(z=s)}}t=null;if(z){t=cf(z.b,vv,Mu);Md(d[z.c])}return t}
+function il(){il=nu;hl=new Et('[0-9A-Za-z\xAA\xB2-\xB3\xB5\xB9-\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u0236\u0250-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EE\u037A\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03F5\u03F7-\u03FB\u0400-\u0481\u048A-\u04CE\u04D0-\u04F5\u04F8-\u04F9\u0500-\u050F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0640-\u064A\u0660-\u0669\u066E-\u066F\u0671-\u06D3\u06D5\u06E5-\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u074F\u0780-\u07A5\u07B1\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09DC-\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0-\u0AE1\u0AE6-\u0AEF\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB5\u0BB7-\u0BB9\u0BE7-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C60-\u0C61\u0C66-\u0C6F\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0-\u0CE1\u0CE6-\u0CEF\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D60-\u0D61\u0D66-\u0D6F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDD\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6A\u0F88-\u0F8B\u1000-\u1021\u1023-\u1027\u1029-\u102A\u1040-\u1049\u1050-\u1055\u10A0-\u10C5\u10D0-\u10F8\u1100-\u1159\u115F-\u11A2\u11A8-\u11F9\u1200-\u1206\u1208-\u1246\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1286\u1288\u128A-\u128D\u1290-\u12AE\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12CE\u12D0-\u12D6\u12D8-\u12EE\u12F0-\u130E\u1310\u1312-\u1315\u1318-\u131E\u1320-\u1346\u1348-\u135A\u1369-\u137C\u13A0-\u13F4\u1401-\u166C\u166F-\u1676\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1877\u1880-\u18A8\u1900-\u191C\u1946-\u196D\u1970-\u1974\u1D00-\u1D6B\u1E00-\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070-\u2071\u2074-\u2079\u207F-\u2089\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2131\u2133-\u2139\u213D-\u213F\u2145-\u2149\u2153-\u2183\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312C\u3131-\u318E\u3192-\u3195\u31A0-\u31B7\u31F0-\u31FF\u3220-\u3229\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DB5\u4E00-\u9FA5\uA000-\uA48C\uAC00-\uD7A3\uF900-\uFA2D\uFA30-\uFA6A\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]')}
 
-var Ve=Aj(Kq,'Object',1,null),de=Aj(Lq,'JavaScriptObject$',27,Ve),Rf=zj(Mq,'Object;',163),af=Aj(Kq,'Throwable',26,Ve),Ne=Aj(Kq,'Exception',25,af),We=Aj(Kq,'RuntimeException',24,Ne),Xe=Aj(Kq,'StackTraceElement',113,Ve),Sf=zj(Mq,'StackTraceElement;',166),me=Aj('com.google.gwt.lang.','SeedUtil',55,Ve),Ie=Aj(Kq,'Boolean',97,Ve),Ue=Aj(Kq,'Number',103,Ve),Of=zj(Kp,'[C',167),Je=Aj(Kq,'Character',98,Ve),Pf=zj(Mq,'Character;',168),Le=Aj(Kq,'Class',100,Ve),Me=Aj(Kq,'Double',102,Ue),Re=Aj(Kq,'Integer',107,Ue),Qf=zj(Mq,'Integer;',169),_e=Aj(Kq,dq,2,Ve),Tf=zj(Mq,'String;',164),Ke=Aj(Kq,'ClassCastException',101,We),Ze=Aj(Kq,'StringBuilder',116,Ve),He=Aj(Kq,'ArrayStoreException',96,We),ce=Aj(Lq,'JavaScriptException',23,We),le=Aj(Nq,'StringBufferImpl',39,Ve),Gf=Aj(Oq,'Logger',60,Ve),Lf=Aj(Pq,'ExporterBaseImpl',152,Ve),Kf=Aj(Pq,'ExporterBaseActual',151,Lf),Jf=Bj(Pq,'Exportable'),je=Aj(Nq,'StackTraceCreator$Collector',35,Ve),ie=Aj(Nq,'StackTraceCreator$CollectorMoz',37,je),he=Aj(Nq,'StackTraceCreator$CollectorChrome',36,ie),ge=Aj(Nq,'StackTraceCreator$CollectorChromeNoSourceMap',38,he),ke=Aj(Nq,'StringBufferImplAppend',40,le),ee=Aj(Lq,'Scheduler',30,Ve),fe=Aj(Nq,'SchedulerImpl',32,ee),ne=Aj(Qq,'LoggerImplRegular',58,Ve),sf=Aj(Rq,'AbstractMap',94,Ve),hf=Aj(Rq,'AbstractHashMap',93,sf),cf=Aj(Rq,'AbstractCollection',119,Ve),uf=Aj(Rq,'AbstractSet',121,cf),ef=Aj(Rq,'AbstractHashMap$EntrySet',120,uf),df=Aj(Rq,'AbstractHashMap$EntrySetIterator',122,Ve),rf=Aj(Rq,'AbstractMapEntry',124,Ve),ff=Aj(Rq,'AbstractHashMap$MapEntryNull',123,rf),gf=Aj(Rq,'AbstractHashMap$MapEntryString',125,rf),of=Aj(Rq,'AbstractMap$1',130,uf),nf=Aj(Rq,'AbstractMap$1$1',131,Ve),qf=Aj(Rq,'AbstractMap$2',132,cf),pf=Aj(Rq,'AbstractMap$2$1',133,Ve),Se=Aj(Kq,'NullPointerException',110,We),Oe=Aj(Kq,'IllegalArgumentException',104,We),mf=Aj(Rq,'AbstractList',126,cf),vf=Aj(Rq,'ArrayList',135,mf),jf=Aj(Rq,'AbstractList$IteratorImpl',127,Ve),kf=Aj(Rq,'AbstractList$ListIteratorImpl',128,jf),lf=Aj(Rq,'AbstractList$SubList',129,mf),xf=Aj(Rq,'HashMap',92,hf),Ff=Aj(Oq,'LogManager',147,Ve),Ef=Aj(Oq,'LogManager$RootLogger',148,Gf),oe=Aj(Qq,'LoggerWithExposedConstructor',59,Gf),Rd=Aj(Sq,'ContentExtractor_ExporterImpl',4,Ve),Sd=Aj(Sq,'ContentExtractor',3,Ve),Td=Aj(Sq,'DocumentTitleGetter_ExporterImpl',6,Ve),Ud=Aj(Sq,'DocumentTitleGetter',5,Ve),_d=Aj(Sq,'PagingLinksFinder_ExporterImpl',17,Ve),ae=Aj(Sq,'PagingLinksFinder',15,Ve),Ye=Aj(Kq,'StringBuffer',115,Ve),Cf=Aj(Rq,'MapEntryImpl',144,rf),$d=Aj(Sq,'PagingLinksFinder$PagingLinkObj',16,Ve),bf=Aj(Kq,'UnsupportedOperationException',118,We),Df=Aj(Rq,'NoSuchElementException',145,We),Pe=Aj(Kq,'IllegalStateException',105,We),ye=Aj(Tq,'BoilerpipeHTMLContentHandler',82,Ve),qe=Aj(Uq,'TextDocument',68,Ve),pe=Aj(Uq,'TextBlock',67,Ve),Vd=Aj(Sq,'DomToSaxParser$DomToSaxVisitor',9,Ve),Wd=Aj(Sq,'DomWalker',10,Ve),yf=Aj(Rq,'HashSet',140,uf),be=Aj(Sq,'RelevantImageFinder$Visitor',19,Ve),Yd=Aj(Sq,'NodeTree',13,Ve),Xd=Aj(Sq,'NodeListExpander$Visitor',12,Ve),If=Aj(Vq,'Pattern',150,Ve),Hf=Aj(Vq,'Matcher',149,Ve),Te=Aj(Kq,'NumberFormatException',112,Oe),Ge=Aj(Tq,'TagActionMap',91,xf),Fe=Aj(Tq,'DefaultTagActionMap',90,Ge),ue=Aj(Wq,'DocumentTitleMatchClassifier',74,Ve),re=Aj(Xq,'HeuristicFilterBase',69,Ve),se=Aj(Xq,'IgnoreBlocksAfterContentFilter',70,re),te=Aj(Wq,'BlockProximityFusion',73,Ve),we=Aj('de.l3s.boilerpipe.filters.simple.','BoilerplateBlockFilter',80,Ve),ve=Aj(Wq,'KeepLargestBlockFilter',76,Ve),wf=Aj(Rq,'Arrays$ArrayList',137,mf),Qe=Aj(Kq,'IndexOutOfBoundsException',106,We),Zd=Aj(Sq,'OrderedNodeMatcher',14,Ve),Ee=Aj(Tq,'CommonTagActions$BlockTagLabelAction',89,Ve),ze=Aj(Tq,'CommonTagActions$1',84,Ve),Ae=Aj(Tq,'CommonTagActions$2',85,Ve),Be=Aj(Tq,'CommonTagActions$3',86,Ve),Ce=Aj(Tq,'CommonTagActions$4',87,Ve),De=Aj(Tq,'CommonTagActions$5',88,Ve),xe=Aj('de.l3s.boilerpipe.labels.','LabelAction',81,Ve),tf=Aj(Rq,'AbstractSequentialList',134,mf),Bf=Aj(Rq,'LinkedList',141,tf),zf=Aj(Rq,'LinkedList$ListIteratorImpl',142,Ve),Af=Aj(Rq,'LinkedList$Node',143,Ve),Nf=Aj(Yq,'AttributesImpl',158,Ve),Mf=Aj(Yq,'AttributesImpl$AttributeData',159,Ve),$e=Aj(Kq,'StringIndexOutOfBoundsException',117,Qe);$stats && $stats({moduleName:'domdistiller',sessionId:$sessionId,subSystem:'startup',evtGroup:'moduleStartup',millis:(new Date()).getTime(),type:'moduleEvalEnd'});if ($wnd.domdistiller) $wnd.domdistiller.onScriptLoad();
+var Mu='',fw='\n',Yu=' ',Fw='"',Qu='$1',zw='$\uE00A<',sw="'",dw='(',xv='(next|weiter|continue|>([^\\|]|$)|\xBB([^\\|]|$))',yv='(prev|early|old|new|<|\xAB)',kw=')',Xu='*',Bw=', ',Wu='.',qw='.com',tv='/',fv=':',Su=': ',rv=':type',Cw='=',Aw='>\uE00A$',Ju='@',gw='@@',Nu='A',sv='ARTICLE',bv='Article',Fv='CONTENT',mw='CSS1Compat',Hv='DATA',Ku='DomDistiller',Cv='EMBED',Ew='For input string: "',Tu='H1',Dv='HREF',Ou='IMG',Jv='ITEMTYPE',Ev='LINK',av='META',Gv='OBJECT',qv='Required "',Bv='SRC',cw='String',Pu='TITLE',hw='Unknown',Iv='VALUE',iw='[',rw='[\b ]+',uv='[.]',Yw='[Lcom.dom_distiller.client.',Mw='[Ljava.lang.',Iw='[object Array]',vv='\\/$',Ru='\\s+',jw=']',Jw='__gwtex_wrap',ew='anonymous',ev='article',Nv='articleSection',Sv='associatedMedia',pv='author',Wv='caption',Sw='com.dom_distiller.client.',Lw='com.google.gwt.core.client.',Nw='com.google.gwt.core.client.impl.',Qw='com.google.gwt.logging.impl.',Av='combx|comment|com-|contact|foot|footer|footnote|masthead|media|meta|outbrain|promo|related|scroll|shoutbox|sidebar|sponsor|shopping|tags|tool|widget',Uv='contentUrl',Qv='copyrightHolder',Pv='copyrightYear',Ov='creator',Mv='dateModified',Lv='datePublished',Uw='de.l3s.boilerpipe.document.',Ww='de.l3s.boilerpipe.filters.english.',Vw='de.l3s.boilerpipe.filters.heuristics.',Tw='de.l3s.boilerpipe.sax.',ww='de.l3s.boilerpipe/HEADING',pw='de.l3s.boilerpipe/INDICATES_END_OF_TEXT',vw='de.l3s.boilerpipe/LI',tw='de.l3s.boilerpipe/MIGHT_BE_CONTENT',Lu='de.l3s.boilerpipe/TITLE',uw='de.l3s.boilerpipe/VERY_LIKELY_CONTENT',iv='description',Tv='encoding',Vv='encodingFormat',ov='expiration_time',aw='familyName',Hw='fromIndex: ',Vu='function',Gw='g',_v='givenName',Rv='headline',Yv='height',kv='image',Kw='java.lang.',Rw='java.util.',Ow='java.util.logging.',Xw='java.util.regex.',$v='legalName',nv='modified_time',ow='msie',Kv='name',bw='null',Dw='number',Uu='object',nw='opera',Pw='org.timepedia.exporter.client.',Zw='org.xml.sax.',zv='pag(e|ing|inat)',cv='prefix',wv='print|archive|comment|discuss|e[\\-]?mail|share|reply|all|login|sign|single',dv='profile',mv='published_time',$u='publisher',Zv='representativeOfPage',lw='safari',lv='section',jv='site_name',_u='title',Zu='true',gv='type',hv='url',Xv='width',xw='{',yw='}';var _,Sj={},Hu={24:1,43:1},ru={50:1},Bu={44:1},vu={24:1,37:1},yu={24:1,33:1,41:1},zu={48:1},uu={5:1},Eu={47:1},Du={24:1},qu={},tu={8:1,24:1,37:1},su={24:1,37:1,40:1},wu={24:1,32:1,37:1},Gu={43:1},Au={23:1},xu={18:1},Fu={45:1},Cu={24:1,44:1};Tj(1,-1,qu);_.eQ=function E(a){return this===a};_.gC=function F(){return this.cZ};_.hC=function G(){return Nf(this)};_.tS=function H(){return this.cZ.f+Ju+ao(this.hC())};_.toString=function(){return this.tS()};_.tM=nu;Tj(3,1,{2:1,49:1},J);Tj(4,1,ru,Q);_.y=function R(){return $wnd.com.dom_distiller.ContentExtractor};_.z=function S(a){return a!=null&&ah(a,2)};var N=false;Tj(5,1,{3:1,49:1},U);Tj(6,1,ru,$);_.y=function ab(){return $wnd.com.dom_distiller.DocumentTitleGetter};_.z=function bb(a){return a!=null&&ah(a,3)};var X=false;Tj(9,1,{},gb);_.A=function hb(a){var b;b=a;nl(this.b,b.tagName,b.tagName)};_.B=function ib(a){var b,c,d,e,f;switch(a.nodeType){case 3:dr(this.c,a);d=a.data;ml(this.b,(e=d.length,f=Qg(Fj,Du,-1,e,1),vo(d,e,f,0),f),0,d.length);return false;case 1:c=a;b=eb(c);ql(this.b,c.tagName,c.tagName,b);return true;case 9:default:return false;}};_.b=null;_.c=null;Tj(11,1,{},nb);_.b=null;Tj(12,1,uu,wb);_.C=function xb(){var a,b;a=new Wb;this.e==null&&rb(this);a.e=this.e;b=(this.c==null&&pb(this),this.c);a.b=!b.length?Qg(Oj,su,1,0,0):Rg(Oj,su,1,[b]);return a};_.D=function yb(){return this.c==null&&pb(this),this.c};_.E=function Ab(){this.d==null&&qb(this);return this.d};_.F=function Bb(){return Mu};_.G=function Cb(){!this.i&&sb(this);return $g(jr(this.i,Qg(Gj,tu,7,this.i.c,0)),8)};_.H=function Db(){this.k==null&&ub(this);return this.k};_.I=function Eb(){this.o==null&&vb(this);return this.o};_.J=function Fb(){return Mu};_.K=function Gb(){return Mu};_.L=function Ib(){this.f||tb(this);return this.j};_.b=null;_.c=null;_.d=null;_.e=null;_.f=false;_.i=null;_.j=false;_.k=null;_.n=null;_.o=null;Tj(13,1,{4:1,49:1},Kb);_.C=function Lb(){var a,b;a=null;for(b=0;b<this.b.c&&!a;++b){a=$g(fr(this.b,b),5).C()}return a};_.D=function Mb(){var a,b;a=Mu;for(b=0;b<this.b.c&&!a.length;++b){a=$g(fr(this.b,b),5).D()}return a};_.E=function Nb(){var a,b;a=Mu;for(b=0;b<this.b.c&&!a.length;++b){a=$g(fr(this.b,b),5).E()}return a};_.F=function Ob(){var a,b;a=Mu;for(b=0;b<this.b.c&&!a.length;++b){a=$g(fr(this.b,b),5).F()}return a};_.G=function Pb(){var a,b;b=null;for(a=0;a<this.b.c;++a){b=$g(fr(this.b,a),5).G();if(b.length>0)break}return b};_.H=function Qb(){var a,b;b=Mu;for(a=0;a<this.b.c&&!b.length;++a){b=$g(fr(this.b,a),5).H()}return b};_.I=function Rb(){var a,b;b=Mu;for(a=0;a<this.b.c&&!b.length;++a){b=$g(fr(this.b,a),5).I()}return b};_.J=function Sb(){var a,b;b=Mu;for(a=0;a<this.b.c&&!b.length;++a){b=$g(fr(this.b,a),5).J()}return b};_.K=function Tb(){var a,b;b=Mu;for(a=0;a<this.b.c&&!b.length;++a){b=$g(fr(this.b,a),5).K()}return b};_.L=function Ub(){var a,b;b=false;for(a=0;a<this.b.c&&!b;++a){b=$g(fr(this.b,a),5).L()}return b};_.b=null;Tj(14,1,{6:1,49:1},Wb);_.M=function Xb(){return this.b};_.N=function Yb(){return this.c};_.O=function Zb(){return this.d};_.P=function $b(){return this.e};_.Q=function _b(){return this.f};_.b=null;_.c=Mu;_.d=Mu;_.e=Mu;_.f=Mu;Tj(15,1,{7:1,49:1},bc);_.R=function cc(){return this.b};_.S=function dc(){return this.c};_.T=function ec(){return this.d};_.J=function fc(){return this.e};_.K=function gc(){return this.f};_.U=function hc(){return this.i};_.b=Mu;_.c=0;_.d=Mu;_.e=Mu;_.f=Mu;_.i=0;Tj(16,1,ru,mc);_.y=function nc(){return $wnd.com.dom_distiller.MarkupParser.Article};_.z=function oc(a){return a!=null&&ah(a,6)};var jc=false;Tj(17,1,ru,tc);_.y=function uc(){return $wnd.com.dom_distiller.MarkupParser};_.z=function vc(a){return a!=null&&ah(a,4)};var qc=false;Tj(18,1,ru,Ac);_.y=function Bc(){return $wnd.com.dom_distiller.MarkupParser.Image};_.z=function Cc(a){return a!=null&&ah(a,7)};var xc=false;Tj(20,1,{},Hc);_.A=function Ic(a){hr(this.b,this.b.c-1);hr(this.e,this.e.c-1)};_.B=function Jc(a){if(!this.c.b)return false;dr(this.b,a);dr(this.e,null);if(this.e.c==1){this.d=new Nc(a);ir(this.e,0,this.d)}Hd(this.c,a)&&Gc(this);return true};_.b=null;_.c=null;_.d=null;_.e=null;Tj(21,1,{9:1},Nc);_.b=null;_.c=null;Tj(22,1,uu,Sc);_.C=function Tc(){var a;a=new Wb;a.e=um(this.i,mv)?$g(xm(this.i,mv),1):Mu;a.d=um(this.i,nv)?$g(xm(this.i,nv),1):Mu;a.c=um(this.i,ov)?$g(xm(this.i,ov),1):Mu;a.f=um(this.i,lv)?$g(xm(this.i,lv),1):Mu;a.b=dd(this.b);if(!a.f.length&&!a.e.length&&!a.d.length&&!a.c.length&&a.b.length==0){return null}return a};_.D=function Uc(){return Bd(this.e,this.i)};_.E=function Vc(){return Mu};_.F=function Wc(){return um(this.i,iv)?$g(xm(this.i,iv),1):Mu};_.G=function Xc(){return hd(this.c)};_.H=function Yc(){return um(this.i,jv)?$g(xm(this.i,jv),1):Mu};_.I=function Zc(){return um(this.i,_u)?$g(xm(this.i,_u),1):Mu};_.J=function $c(){var a;a=um(this.i,gv)?$g(xm(this.i,gv),1):Mu;return uo(a,ev)?bv:Mu};_.K=function _c(){return um(this.i,hv)?$g(xm(this.i,hv),1):Mu};_.L=function ad(){return false};_.d=null;_.i=null;Tj(23,1,{},ed);_.V=function fd(a,b,c){var d;if(!this.c){d=$g(c.f[rv],1);this.c=d!=null&&uo(d,ev)}if(!this.c)return false;if(to(a,pv)){dr(this.b,b);return false}return true};_.b=null;_.c=false;Tj(24,1,{},jd);_.V=function kd(a,b,c){var d,e;if(to(a,kv)){e=Qg(Oj,su,1,this.c.length,0);e[0]=b;dr(this.b,e)}else{if(this.b.c==0){e=Qg(Oj,su,1,this.c.length,0);dr(this.b,e)}else{e=$g(fr(this.b,this.b.c-1),40)}for(d=1;d<this.c.length;++d){if(to(a,this.c[d])){e[d]=b;break}}}return false};_.b=null;Tj(26,1,{24:1,29:1,31:1});_.cT=function pd(a){return nd(this,$g(a,31))};_.eQ=function qd(a){return this===a};_.hC=function rd(){return Nf(this)};_.tS=function sd(){return this.b};_.b=null;_.c=0;Tj(25,26,{10:1,24:1,29:1,31:1},yd);var td,ud,vd,wd;Tj(27,1,{},Cd);_.V=function Dd(a,b,c){var d;if(!this.b){d=$g(c.f[rv],1);this.c=d!=null&&uo(d,dv);this.b=true}return this.c};_.b=false;_.c=false;Tj(28,1,{11:1},Fd);_.b=null;_.c=null;_.d=null;Tj(29,1,{},Id);_.b=null;_.c=null;Tj(30,1,{12:1,49:1},Ld);Tj(31,1,{13:1},Rd);_.b=null;_.c=-1;_.d=null;_.e=0;Tj(32,1,ru,Wd);_.y=function Xd(){return $wnd.com.dom_distiller.PagingLinksFinder};_.z=function Yd(a){return a!=null&&ah(a,12)};var Td=false;Tj(34,1,{},_d);_.A=function ae(a){};_.B=function be(a){if(!this.d.b&&!this.c){return false}if(Hd(this.d,a)){this.c=true;dr(this.b,a)}else a.nodeType==3&&!df(a.nodeValue)&&(this.c=false);switch(a.nodeType){case 3:return true;case 1:this.c&&a.nodeType==1&&to(Ou,a.tagName)&&dr(this.b,a);return true;case 9:default:return false;}};_.b=null;_.c=false;_.d=null;Tj(35,1,{},ke);_.b=Mu;var de=null,ee=null;Tj(37,1,xu);_.b=null;_.c=null;_.d=null;Tj(36,37,{14:1,18:1},we);Tj(38,37,{15:1,18:1},ze);Tj(39,37,{16:1,18:1},Ce);Tj(40,37,{17:1,18:1},Fe);Tj(41,26,{19:1,24:1,29:1,31:1},Oe);var He,Ie,Je,Ke,Le,Me;Tj(42,37,xu,Re);Tj(43,1,uu,Te);_.C=function Ue(){var a;a=he(this.b);return a.c==0?null:se((bq(0,a.c),$g(a.b[0],14)))};_.D=function Ve(){var a,b,c;c=Mu;b=he(this.b);if(b.c!=0){a=(bq(0,b.c),$g(b.b[0],14));c=ve(a,pv);!c.length&&(c=ve(a,Ov))}return !c.length?this.b.b:c};_.E=function We(){var a;a=he(this.b);return a.c==0?Mu:te((bq(0,a.c),$g(a.b[0],14)))};_.F=function Xe(){var a;a=he(this.b);return a.c==0?Mu:pe((bq(0,a.c),$g(a.b[0],14)),iv)};_.G=function Ye(){var a,b,c,d,e,f,g,h,j,l;j=new kr;b=he(this.b);c=null;for(e=0;e<b.c;++e){a=(bq(e,b.c),$g(b.b[e],14));if(!c){c=(l=um(a.b,Sv)?$g(xm(a.b,Sv),18):null,!l&&(l=um(a.b,Tv)?$g(xm(a.b,Tv),18):null),!!l&&l.d==(Ne(),Je)?$g(l,15):null);if(c)continue}f=ue(a);!!f&&(Sg(j.b,j.c++,f),true)}h=ie(this.b);d=false;for(e=0;e<h.c;++e){g=(bq(e,h.c),$g(h.b[e],15));f=ye(g);if(g==c||!d&&uo(pe(g,Zv),Zu)){d=true;cr(j,0,f)}else{Sg(j.b,j.c++,f)}}return $g(jr(j,Qg(Gj,tu,7,j.c,0)),8)};_.H=function Ze(){var a,b,c;c=Mu;b=he(this.b);if(b.c!=0){a=(bq(0,b.c),$g(b.b[0],14));c=ve(a,$u);!c.length&&(c=ve(a,Qv))}return c};_.I=function $e(){var a,b,c;c=Mu;a=he(this.b);for(b=0;b<a.c&&!c.length;++b){c=pe((bq(b,a.c),$g(a.b[b],14)),Rv)}for(b=0;b<a.c&&!c.length;++b){c=pe((bq(b,a.c),$g(a.b[b],14)),Kv)}return c};_.J=function _e(){return he(this.b).c==0?Mu:bv};_.K=function af(){var a;a=he(this.b);return a.c==0?Mu:pe((bq(0,a.c),$g(a.b[0],14)),hv)};_.L=function bf(){return false};_.b=null;Tj(50,1,{24:1,41:1});_.W=function nf(){return this.f};_.tS=function of(){var a,b;a=this.cZ.f;b=this.W();return b!=null?a+Su+b:a};_.f=null;Tj(49,50,yu,pf);Tj(48,49,yu,rf);Tj(47,48,yu,sf);_.W=function yf(){this.d==null&&(this.e=vf(this.c),this.b=this.b+Su+tf(this.c),this.d=dw+this.e+') '+xf(this.c)+this.b,undefined);return this.d};_.b=Mu;_.c=null;_.d=null;_.e=null;Tj(54,1,{});var Ef=0,Ff=0,Gf=0,Hf=-1;Tj(56,54,{},Vf);_.b=null;_.c=null;var Rf;Tj(59,1,{},dg);_.X=function eg(){var a={};var b=[];var c=arguments.callee.caller.caller;while(c){var d=this.Y(c.toString());b.push(d);var e=fv+d;var f=a[e];if(f){var g,h;for(g=0,h=f.length;g<h;g++){if(f[g]===c){return b}}}(f||(a[e]=[])).push(c);c=c.caller}return b};_.Y=function fg(a){return Yf(a)};_.Z=function gg(a){return []};Tj(61,59,{});_.X=function kg(){return _f(this.Z(cg()),this.$())};_.Z=function lg(a){return jg(this,a)};_.$=function mg(){return 2};Tj(60,61,{});_.X=function tg(){return og(this)};_.Y=function ug(a){var b,c,d,e;if(a.length==0){return ew}e=Fo(a);e.indexOf('at ')==0&&(e=Do(e,3));c=e.indexOf(iw);c!=-1&&(e=Fo(e.substr(0,c-0))+Fo(Do(e,e.indexOf(jw,c)+1)));c=e.indexOf(dw);if(c==-1){c=e.indexOf(Ju);if(c==-1){d=e;e=Mu}else{d=Fo(Do(e,c+1));e=Fo(e.substr(0,c-0))}}else{b=e.indexOf(kw,c);d=e.substr(c+1,b-(c+1));e=Fo(e.substr(0,c-0))}c=wo(e,No(46));c!=-1&&(e=Do(e,c+1));return (e.length>0?e:ew)+gw+d};_.Z=function vg(a){return rg(this,a)};_.$=function wg(){return 3};Tj(62,60,{},yg);Tj(63,1,{});Tj(64,63,{},Fg);_.b=Mu;Tj(75,1,{},Lg);_.qI=0;var Tg,Ug;Tj(84,1,{},Zj);_.b=null;Tj(86,1,zu,bk);_.b=null;Tj(85,86,zu,ck);Tj(93,1,{21:1},pk);_.tS=function qk(){return iw+this.p+'-'+this.o+';tl='+this.q+'; nw='+this.i+';nwl='+this.n+';ld='+this.e+']\t'+(this.c?Fv:'boilerplate')+','+this.d+fw+this.r.tS()};_.b=null;_.c=false;_.d=null;_.e=0;_.f=0;_.i=0;_.j=0;_.k=0;_.n=0;_.o=0;_.p=0;_.q=0;_.r=null;_.s=0;var ik,jk;Tj(94,1,{},sk);_.b=null;_.c=null;Tj(95,1,{});Tj(96,95,{},yk);_.b=0;var vk;Tj(99,1,{},Jk);_.b=false;_.c=0;_.d=false;var Fk,Gk;Tj(100,1,{},Qk);_.b=null;var Lk;Tj(102,1,{},Wk);_.b=false;_.c=0;var Tk;Tj(106,1,{},cl);_.b=null;var _k;Tj(107,1,{22:1},el);_.tS=function fl(){return hi.f+Ju+ao(Nf(this))+xw+new Gr(this.b)+yw};_.b=null;Tj(108,1,{},rl);_.b=-1;_.d=false;_.f=0;_.i=false;_.j=0;_.k=0;_.o=null;_.p=0;_.q=false;_.r=null;_.s=0;_.v=0;_.w=null;var hl;var tl,ul,vl,wl,xl;Tj(110,1,Au,Al);_._=function Bl(){return true};_.ab=function Cl(a,b,c){--a.k;return true};_.bb=function Dl(a,b,c,d){++a.k;return true};Tj(111,1,Au,Gl);_._=function Hl(){return true};_.ab=function Il(a,b,c){return Fl(a)};_.bb=function Jl(a,b,c,d){a.f++>0&&Fl(a);if(a.k==0){ll(a);cp(a.x,zw);ap(a.x,32);a.q=true}return false};Tj(112,1,Au,Ll);_._=function Ml(){return true};_.ab=function Nl(a,b,c){ol(a);--a.j;return false};_.bb=function Ol(a,b,c,d){ol(a);++a.j;return false};Tj(113,1,Au,Ql);_._=function Rl(){return false};_.ab=function Sl(a,b,c){ll(a);return false};_.bb=function Tl(a,b,c,d){ll(a);return false};Tj(114,1,Au,Vl);_._=function Wl(){return false};_.ab=function Xl(a,b,c){return false};_.bb=function Yl(a,b,c,d){return false};Tj(115,1,Au,$l);_._=function _l(){return true};_.ab=function am(a,b,c){return true};_.bb=function bm(a,b,c,d){jl(a,this.b);return true};_.b=null;Tj(120,1,Bu);_.cb=function km(a){return !!hm(this,a)};_.eQ=function lm(a){var b,c,d,e,f;if(a===this){return true}if(!ah(a,44)){return false}e=$g(a,44);if(this.fb()!=e.fb()){return false}for(c=e.db().mb();c.pb();){b=$g(c.qb(),45);d=b.rb();f=b.sb();if(!this.cb(d)){return false}if(!nt(f,this.eb(d))){return false}}return true};_.eb=function mm(a){var b;b=hm(this,a);return !b?null:b.sb()};_.hC=function nm(){var a,b,c;c=0;for(b=this.db().mb();b.pb();){a=$g(b.qb(),45);c+=a.hC();c=~~c}return c};_.fb=function om(){return this.db().fb()};_.tS=function pm(){var a,b,c,d;d=xw;a=false;for(c=this.db().mb();c.pb();){b=$g(c.qb(),45);a?(d+=Bw):(a=true);d+=Mu+b.rb();d+=Cw;d+=Mu+b.sb()}return d+yw};Tj(119,120,Bu);_.cb=function Hm(a){return um(this,a)};_.db=function Im(){return new Dp(this)};_.hb=function Jm(a,b){return this.gb(a,b)};_.eb=function Km(a){return xm(this,a)};_.fb=function Lm(){return this.e};_.b=null;_.c=null;_.d=false;_.e=0;_.f=null;Tj(118,119,Cu,Nm,Om);_.gb=function Pm(a,b){return Mm(a,b)};_.ib=function Qm(a){return ~~Cf(a)};Tj(117,118,Cu);Tj(116,117,Cu,Um);var Sm;var Vm;Tj(122,48,yu,Zm);Tj(123,1,{24:1,25:1,29:1},dn);_.cT=function en(a){return cn(this,$g(a,25))};_.eQ=function fn(a){return ah(a,25)&&$g(a,25).b==this.b};_.hC=function gn(){return this.b?1231:1237};_.tS=function hn(){return this.b?Zu:'false'};_.b=false;var _m,an;Tj(124,1,{24:1,27:1,29:1},ln);_.cT=function mn(a){return kn(this,$g(a,27))};_.eQ=function on(a){return ah(a,27)&&$g(a,27).b==this.b};_.hC=function pn(){return this.b};_.tS=function qn(){return Po(this.b)};_.b=0;var sn;Tj(126,1,{28:1},vn);_.tS=function Dn(){return ((this.c&2)!=0?'interface ':(this.c&1)!=0?Mu:'class ')+this.f};_.b=null;_.c=0;_.d=0;_.e=null;_.f=null;Tj(127,48,yu,Fn);Tj(129,1,{24:1,35:1});Tj(128,129,{24:1,29:1,30:1,35:1},Kn);_.cT=function Mn(a){return Jn(this,$g(a,30))};_.eQ=function Nn(a){return ah(a,30)&&$g(a,30).b==this.b};_.hC=function On(){return eh(this.b)};_.tS=function Pn(){return Mu+this.b};_.b=0;Tj(130,48,yu,Rn);Tj(131,48,yu,Tn);Tj(132,48,yu,Vn);Tj(133,129,{24:1,29:1,34:1,35:1},Yn);_.cT=function Zn(a){return Xn(this,$g(a,34))};_.eQ=function $n(a){return ah(a,34)&&$g(a,34).b==this.b};_.hC=function _n(){return this.b};_.tS=function bo(){return Mu+this.b};_.b=0;var eo;Tj(136,48,yu,jo);var ko;Tj(138,130,{24:1,33:1,36:1,41:1},no);Tj(139,1,{24:1,38:1},po);_.tS=function qo(){return this.b+Wu+this.e+dw+(this.c!=null?this.c:'Unknown Source')+(this.d>=0?fv+this.d:Mu)+kw};_.b=null;_.c=null;_.d=0;_.e=null;_=String.prototype;_.cM={1:1,24:1,26:1,29:1};_.cT=function Ko(a){return Lo(this,$g(a,1))};_.eQ=function Mo(a){return to(this,a)};_.hC=function Oo(){return Vo(this)};_.tS=_.toString;var Qo,Ro=0,So;Tj(141,1,{26:1},Yo);_.tS=function Zo(){return this.b.b};Tj(142,1,{26:1,39:1},gp,hp);_.tS=function jp(){return this.b.b};Tj(143,132,yu,lp);Tj(144,48,yu,np);Tj(145,1,{});_.jb=function sp(a){throw new np('Add not supported on this collection')};_.kb=function tp(a){return pp(this,a)};_.lb=function up(a){var b;b=qp(this.mb(),a);return !!b};_.nb=function vp(){return this.ob(Qg(Mj,vu,0,this.fb(),0))};_.ob=function wp(a){var b,c,d;d=this.fb();a.length<d&&(a=Og(a,d));c=this.mb();for(b=0;b<d;++b){Sg(a,b,c.qb())}a.length>d&&Sg(a,d,null);return a};_.tS=function xp(){return rp(this)};Tj(147,145,Eu);_.eQ=function Ap(a){var b,c,d;if(a===this){return true}if(!ah(a,47)){return false}c=$g(a,47);if(c.fb()!=this.fb()){return false}for(b=c.mb();b.pb();){d=b.qb();if(!this.lb(d)){return false}}return true};_.hC=function Bp(){var a,b,c;a=0;for(b=this.mb();b.pb();){c=b.qb();if(c!=null){a+=Cf(c);a=~~a}}return a};Tj(146,147,Eu,Dp);_.lb=function Ep(a){return Cp(this,a)};_.mb=function Fp(){return new Ip(this.b)};_.fb=function Gp(){return this.b.e};_.b=null;Tj(148,1,{},Ip);_.pb=function Jp(){return jq(this.b)};_.qb=function Kp(){return $g(kq(this.b),45)};_.b=null;Tj(150,1,Fu);_.eQ=function Np(a){var b;if(ah(a,45)){b=$g(a,45);if(nt(this.rb(),b.rb())&&nt(this.sb(),b.sb())){return true}}return false};_.hC=function Op(){var a,b;a=0;b=0;this.rb()!=null&&(a=Cf(this.rb()));this.sb()!=null&&(b=Cf(this.sb()));return a^b};_.tS=function Pp(){return this.rb()+Cw+this.sb()};Tj(149,150,Fu,Qp);_.rb=function Rp(){return null};_.sb=function Sp(){return this.b.c};_.tb=function Tp(a){return Em(this.b,a)};_.b=null;Tj(151,150,Fu,Vp);_.rb=function Wp(){return this.b};_.sb=function Xp(){return zm(this.c,this.b)};_.tb=function Yp(a){return Fm(this.c,this.b,a)};_.b=null;_.c=null;Tj(152,145,Gu);_.ub=function _p(a,b){throw new np('Add not supported on this list')};_.jb=function aq(a){this.ub(this.fb(),a);return true};_.eQ=function cq(a){var b,c,d,e,f;if(a===this){return true}if(!ah(a,43)){return false}f=$g(a,43);if(this.fb()!=f.fb()){return false}d=this.mb();e=f.mb();while(d.pb()){b=d.qb();c=e.qb();if(!(b==null?c==null:Af(b,c))){return false}}return true};_.hC=function dq(){var a,b,c;b=1;a=this.mb();while(a.pb()){c=a.qb();b=31*b+(c==null?0:Cf(c));b=~~b}return b};_.mb=function fq(){return new mq(this)};_.wb=function gq(a){throw new np('Remove not supported on this list')};_.xb=function hq(a,b){throw new np('Set not supported on this list')};Tj(153,1,{},mq);_.pb=function nq(){return jq(this)};_.qb=function oq(){return kq(this)};_.c=0;_.d=-1;_.e=null;Tj(154,153,{},sq);_.b=null;Tj(155,152,Gu,uq);_.ub=function vq(a,b){bq(a,this.c+1);++this.c;cr(this.d,this.b+a,b)};_.vb=function wq(a){bq(a,this.c);return fr(this.d,this.b+a)};_.wb=function xq(a){var b;bq(a,this.c);b=hr(this.d,this.b+a);--this.c;return b};_.xb=function yq(a,b){bq(a,this.c);return ir(this.d,this.b+a,b)};_.fb=function zq(){return this.c};_.b=0;_.c=0;_.d=null;Tj(156,147,Eu,Cq);_.lb=function Dq(a){return um(this.b,a)};_.mb=function Eq(){return Bq(this)};_.fb=function Fq(){return this.c.b.e};_.b=null;_.c=null;Tj(157,1,{},Hq);_.pb=function Iq(){return jq(this.b.b)};_.qb=function Jq(){var a;a=$g(kq(this.b.b),45);return a.rb()};_.b=null;Tj(158,145,{},Mq);_.lb=function Nq(a){return wm(this.b,a)};_.mb=function Oq(){return Lq(this)};_.fb=function Pq(){return this.c.b.e};_.b=null;_.c=null;Tj(159,1,{},Sq);_.pb=function Tq(){return jq(this.b.b)};_.qb=function Uq(){return Rq(this)};_.b=null;Tj(160,152,Gu);_.ub=function Xq(a,b){var c;c=Ss(this,a);Ps(c.e,b,c.c);++c.b;c.d=null};_.vb=function Yq(a){return Wq(this,a)};_.mb=function Zq(){return Ss(this,0)};_.wb=function $q(b){var c,d;c=Ss(this,b);try{d=Zs(c)}catch(a){a=Qj(a);if(ah(a,46)){throw new Vn("Can't remove element "+b)}else throw a}$s(c);c.c==c.d?(c.c=c.d.b):--c.b;dt(c.d);c.d=null;--c.e.c;return d};_.xb=function _q(b,c){var d,e;d=Ss(this,b);try{e=Zs(d);$s(d);d.d.d=c;return e}catch(a){a=Qj(a);if(ah(a,46)){throw new Vn("Can't set element "+b)}else throw a}};Tj(161,152,Hu,kr,lr);_.ub=function mr(a,b){cr(this,a,b)};_.jb=function nr(a){return dr(this,a)};_.kb=function or(a){return er(this,a)};_.lb=function pr(a){return gr(this,a,0)!=-1};_.vb=function qr(a){return fr(this,a)};_.wb=function rr(a){return hr(this,a)};_.xb=function sr(a,b){return ir(this,a,b)};_.fb=function ur(){return this.c};_.nb=function yr(){return Ng(this.b,0,this.c)};_.ob=function zr(a){return jr(this,a)};_.c=0;Tj(163,152,Hu,Gr);_.lb=function Hr(a){return $p(this,a)!=-1};_.vb=function Ir(a){return bq(a,this.b.length),this.b[a]};_.xb=function Jr(a,b){return Fr(this,a,b)};_.fb=function Kr(){return this.b.length};_.nb=function Lr(){return Mg(this.b)};_.ob=function Mr(a){var b,c;c=this.b.length;a.length<c&&(a=Og(a,c));for(b=0;b<c;++b){Sg(a,b,this.b[b])}a.length>c&&Sg(a,c,null);return a};_.b=null;Tj(166,120,Bu,Ur);_.cb=function Vr(a){return ps(this.b,a)};_.db=function Wr(){return new _r(this)};_.eb=function Xr(a){return Rr(this,a)};_.fb=function Yr(){return this.b.d};_.b=null;_.c=null;Tj(167,147,Eu,_r);_.lb=function as(a){return $r(this,a)};_.mb=function bs(){return new es(this.b)};_.fb=function cs(){return this.b.b.d};_.b=null;Tj(168,1,{},es);_.pb=function fs(){return xs(this.b)};_.qb=function gs(){return this.c=ys(this.b),new is(this.d,this.c)};_.c=null;_.d=null;Tj(169,150,Fu,is);_.rb=function js(){return this.b};_.sb=function ks(){return this.c.c[this.b.c]};_.tb=function ls(a){var b;b=this.c.c[this.b.c];Sg(this.c.c,this.b.c,a);return b};_.b=null;_.c=null;Tj(170,147,Eu);Tj(171,170,Eu,qs);_.jb=function rs(a){return os(this,$g(a,31))};_.lb=function ss(a){return ps(this,a)};_.mb=function ts(){return new zs(this)};_.fb=function us(){return this.d};_.b=null;_.c=null;_.d=0;Tj(172,1,{},zs);_.pb=function As(){return xs(this)};_.qb=function Bs(){return ys(this)};_.b=-1;_.c=-1;_.d=null;Tj(173,147,{24:1,47:1},Fs,Gs,Hs);_.jb=function Is(a){return Ds(this,a)};_.lb=function Js(a){return um(this.b,a)};_.mb=function Ks(){return Bq(im(this.b))};_.fb=function Ls(){return this.b.e};_.tS=function Ms(){return rp(im(this.b))};_.b=null;Tj(174,160,{24:1,42:1,43:1},Vs);_.jb=function Ws(a){return Os(this,a)};_.fb=function Xs(){return this.c};_.b=null;_.c=0;Tj(175,1,{},_s);_.pb=function at(){return this.c!=this.e.b};_.qb=function bt(){return Zs(this)};_.b=0;_.c=null;_.d=null;_.e=null;Tj(176,1,{},et,ft);_.b=null;_.c=null;_.d=null;Tj(177,150,Fu,ht);_.rb=function it(){return this.b};_.sb=function jt(){return this.c};_.tb=function kt(a){var b;b=this.c;this.c=a;return b};_.b=null;_.c=null;Tj(178,48,{24:1,33:1,41:1,46:1},mt);Tj(180,1,{},ut);_.b=null;_.c=null;var pt=null;Tj(181,86,zu,wt);Tj(182,1,{},Bt);_.b=null;_.c=null;_.d=null;Tj(183,1,{},Et,Ft);_.b=null;_.c=null;Tj(185,1,{});Tj(184,185,{},Vt);var _t;Tj(191,1,{},ku);_.b=null;_.c=null;Tj(192,1,{},mu);var Iu=Kf;var Gi=xn(Kw,'Object',1,null),Ph=xn(Lw,'JavaScriptObject$',51,Gi),Mj=wn(Mw,'Object;',196),Ni=xn(Kw,'Throwable',50,Gi),yi=xn(Kw,'Exception',49,Ni),Hi=xn(Kw,'RuntimeException',48,yi),Ii=xn(Kw,'StackTraceElement',139,Gi),Nj=wn(Mw,'StackTraceElement;',199),Yh=xn('com.google.gwt.lang.','SeedUtil',81,Gi),xi=xn(Kw,'Enum',26,Gi),si=xn(Kw,'Boolean',123,Gi),Fi=xn(Kw,'Number',129,Gi),Fj=wn(Mu,'[C',200),ti=xn(Kw,'Character',124,Gi),Kj=wn(Mw,'Character;',201),vi=xn(Kw,'Class',126,Gi),wi=xn(Kw,'Double',128,Fi),Ci=xn(Kw,'Integer',133,Fi),Lj=wn(Mw,'Integer;',202),Mi=xn(Kw,cw,2,Gi),Oj=wn(Mw,'String;',197),ui=xn(Kw,'ClassCastException',127,Hi),Ki=xn(Kw,'StringBuilder',142,Gi),ri=xn(Kw,'ArrayStoreException',122,Hi),Oh=xn(Lw,'JavaScriptException',47,Hi),Xh=xn(Nw,'StringBufferImpl',63,Gi),xj=xn(Ow,'Logger',86,Gi),Cj=xn(Pw,'ExporterBaseImpl',185,Gi),Bj=xn(Pw,'ExporterBaseActual',184,Cj),Aj=zn(Pw,'Exportable'),Vh=xn(Nw,'StackTraceCreator$Collector',59,Gi),Uh=xn(Nw,'StackTraceCreator$CollectorMoz',61,Vh),Th=xn(Nw,'StackTraceCreator$CollectorChrome',60,Uh),Sh=xn(Nw,'StackTraceCreator$CollectorChromeNoSourceMap',62,Th),Wh=xn(Nw,'StringBufferImplAppend',64,Xh),Qh=xn(Lw,'Scheduler',54,Gi),Rh=xn(Nw,'SchedulerImpl',56,Qh),Zh=xn(Qw,'LoggerImplRegular',84,Gi),cj=xn(Rw,'AbstractMap',120,Gi),Ui=xn(Rw,'AbstractHashMap',119,cj),Pi=xn(Rw,'AbstractCollection',145,Gi),ej=xn(Rw,'AbstractSet',147,Pi),Ri=xn(Rw,'AbstractHashMap$EntrySet',146,ej),Qi=xn(Rw,'AbstractHashMap$EntrySetIterator',148,Gi),bj=xn(Rw,'AbstractMapEntry',150,Gi),Si=xn(Rw,'AbstractHashMap$MapEntryNull',149,bj),Ti=xn(Rw,'AbstractHashMap$MapEntryString',151,bj),$i=xn(Rw,'AbstractMap$1',156,ej),Zi=xn(Rw,'AbstractMap$1$1',157,Gi),aj=xn(Rw,'AbstractMap$2',158,Pi),_i=xn(Rw,'AbstractMap$2$1',159,Gi),Di=xn(Kw,'NullPointerException',136,Hi),zi=xn(Kw,'IllegalArgumentException',130,Hi),Yi=xn(Rw,'AbstractList',152,Pi),fj=xn(Rw,'ArrayList',161,Yi),Vi=xn(Rw,'AbstractList$IteratorImpl',153,Gi),Wi=xn(Rw,'AbstractList$ListIteratorImpl',154,Vi),Xi=xn(Rw,'AbstractList$SubList',155,Yi),oj=xn(Rw,'HashMap',118,Ui),wj=xn(Ow,'LogManager',180,Gi),vj=xn(Ow,'LogManager$RootLogger',181,xj),$h=xn(Qw,'LoggerWithExposedConstructor',85,xj),ph=xn(Sw,'MarkupParser_ExporterImpl',17,Gi),rh=xn(Sw,'MarkupParser',13,Gi),fh=xn(Sw,'ContentExtractor_ExporterImpl',4,Gi),gh=xn(Sw,'ContentExtractor',3,Gi),hh=xn(Sw,'DocumentTitleGetter_ExporterImpl',6,Gi),ih=xn(Sw,'DocumentTitleGetter',5,Gi),oh=xn(Sw,'MarkupParser_Article_ExporterImpl',16,Gi),mh=xn(Sw,'MarkupParser$Article',14,Gi),qh=xn(Sw,'MarkupParser_Image_ExporterImpl',18,Gi),nh=xn(Sw,'MarkupParser$Image',15,Gi),Ch=xn(Sw,'PagingLinksFinder_ExporterImpl',32,Gi),Dh=xn(Sw,'PagingLinksFinder',30,Gi),Ji=xn(Kw,'StringBuffer',141,Gi),tj=xn(Rw,'MapEntryImpl',177,bj),Bh=xn(Sw,'PagingLinksFinder$PagingLinkObj',31,Gi),Oi=xn(Kw,'UnsupportedOperationException',144,Hi),uj=xn(Rw,'NoSuchElementException',178,Hi),Ai=xn(Kw,'IllegalStateException',131,Hi),ii=xn(Tw,'BoilerpipeHTMLContentHandler',108,Gi),ai=xn(Uw,'TextDocument',94,Gi),_h=xn(Uw,'TextBlock',93,Gi),jh=xn(Sw,'DomToSaxParser$DomToSaxVisitor',9,Gi),kh=xn(Sw,'DomWalker',11,Gi),pj=xn(Rw,'HashSet',173,ej),Eh=xn(Sw,'RelevantImageFinder$Visitor',34,Gi),th=xn(Sw,'NodeTree',21,Gi),sh=xn(Sw,'NodeListExpander$Visitor',20,Gi),qi=xn(Tw,'TagActionMap',117,oj),pi=xn(Tw,'DefaultTagActionMap',116,qi),ei=xn(Vw,'DocumentTitleMatchClassifier',100,Gi),bi=xn(Ww,'HeuristicFilterBase',95,Gi),ci=xn(Ww,'IgnoreBlocksAfterContentFilter',96,bi),di=xn(Vw,'BlockProximityFusion',99,Gi),gi=xn('de.l3s.boilerpipe.filters.simple.','BoilerplateBlockFilter',106,Gi),fi=xn(Vw,'KeepLargestBlockFilter',102,Gi),gj=xn(Rw,'Arrays$ArrayList',163,Yi),zj=xn(Xw,'Pattern',183,Gi),yj=xn(Xw,'Matcher',182,Gi),Ei=xn(Kw,'NumberFormatException',138,zi),yh=xn(Sw,'OpenGraphProtocolParser$PropertyRecord',28,Gi),Ij=wn(Yw,'OpenGraphProtocolParser$PropertyRecord;',203),zh=xn(Sw,'OpenGraphProtocolParser',22,Gi),wh=yn(Sw,'OpenGraphProtocolParser$Prefix',25,xi,zd),Hj=wn(Yw,'OpenGraphProtocolParser$Prefix;',204),vh=xn(Sw,'OpenGraphProtocolParser$ImageParser',24,Gi),Gj=wn(Yw,'MarkupParser$Image;',205),xh=xn(Sw,'OpenGraphProtocolParser$ProfileParser',27,Gi),uh=xn(Sw,'OpenGraphProtocolParser$ArticleParser',23,Gi),Mh=xn(Sw,'SchemaOrgParserAccessor',43,Gi),lh=xn(Sw,'IEReadingViewParser',12,Gi),Bi=xn(Kw,'IndexOutOfBoundsException',132,Hi),Ah=xn(Sw,'OrderedNodeMatcher',29,Gi),Nh=xn(Sw,'SchemaOrgParser',35,Gi),Kh=yn(Sw,'SchemaOrgParser$Type',41,xi,Pe),Jj=wn(Yw,'SchemaOrgParser$Type;',206),Jh=xn(Sw,'SchemaOrgParser$ThingItem',37,Gi),Gh=xn(Sw,'SchemaOrgParser$ImageItem',38,Jh),Fh=xn(Sw,'SchemaOrgParser$ArticleItem',36,Jh),Ih=xn(Sw,'SchemaOrgParser$PersonItem',40,Jh),Hh=xn(Sw,'SchemaOrgParser$OrganizationItem',39,Jh),Lh=xn(Sw,'SchemaOrgParser$UnsupportedItem',42,Jh),oi=xn(Tw,'CommonTagActions$BlockTagLabelAction',115,Gi),ji=xn(Tw,'CommonTagActions$1',110,Gi),ki=xn(Tw,'CommonTagActions$2',111,Gi),li=xn(Tw,'CommonTagActions$3',112,Gi),mi=xn(Tw,'CommonTagActions$4',113,Gi),ni=xn(Tw,'CommonTagActions$5',114,Gi),hi=xn('de.l3s.boilerpipe.labels.','LabelAction',107,Gi),dj=xn(Rw,'AbstractSequentialList',160,Yi),sj=xn(Rw,'LinkedList',174,dj),qj=xn(Rw,'LinkedList$ListIteratorImpl',175,Gi),rj=xn(Rw,'LinkedList$Node',176,Gi),kj=xn(Rw,'EnumMap',166,cj),ij=xn(Rw,'EnumMap$EntrySet',167,ej),hj=xn(Rw,'EnumMap$EntrySetIterator',168,Gi),jj=xn(Rw,'EnumMap$MapEntry',169,bj),Ej=xn(Zw,'AttributesImpl',191,Gi),Dj=xn(Zw,'AttributesImpl$AttributeData',192,Gi),nj=xn(Rw,'EnumSet',170,ej),mj=xn(Rw,'EnumSet$EnumSetImpl',171,nj),lj=xn(Rw,'EnumSet$EnumSetImpl$IteratorImpl',172,Gi),Li=xn(Kw,'StringIndexOutOfBoundsException',143,Bi);$stats && $stats({moduleName:'domdistiller',sessionId:$sessionId,subSystem:'startup',evtGroup:'moduleStartup',millis:(new Date()).getTime(),type:'moduleEvalEnd'});if ($wnd.domdistiller) $wnd.domdistiller.onScriptLoad();
 gwtOnLoad(undefined,"domdistiller","",0);
diff --git a/third_party/fips181/COPYING b/third_party/fips181/COPYING
new file mode 100644
index 0000000..352abe4
--- /dev/null
+++ b/third_party/fips181/COPYING
@@ -0,0 +1,27 @@
+Copyright (c) 1999, 2000, 2001, 2002
+Adel I. Mirzazhanov. All rights reserved
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ 
+     1.Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer. 
+     2.Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution. 
+     3.The name of the author may not be used to endorse or promote products
+       derived from this software without specific prior written permission. 
+ 		  
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN  NO  EVENT  SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES;  LOSS OF USE,  DATA,  OR  PROFITS;  OR BUSINESS
+INTERRUPTION)  HOWEVER  CAUSED  AND  ON  ANY  THEORY OF LIABILITY,
+WHETHER  IN  CONTRACT,   STRICT   LIABILITY,  OR  TORT  (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+		  
\ No newline at end of file
diff --git a/third_party/fips181/OWNERS b/third_party/fips181/OWNERS
new file mode 100644
index 0000000..1860fb1
--- /dev/null
+++ b/third_party/fips181/OWNERS
@@ -0,0 +1,2 @@
+gcasto@chromium.org
+wfh@chromium.org
diff --git a/third_party/fips181/README.chromium b/third_party/fips181/README.chromium
new file mode 100644
index 0000000..93af1b4
--- /dev/null
+++ b/third_party/fips181/README.chromium
@@ -0,0 +1,16 @@
+Name: fips181
+URL: http://www.adel.nursat.kz/apg/
+Version: 2.2.3
+Security Critical: yes
+License: BSD 3-Clause
+License File: COPYING
+
+Description:
+
+A C library that provides an implementation of FIPS 181 Automated Password
+Generator (APG).
+
+Local Modifications:
+
+pronpass.c and pronpass.h were imported as files fips181.cc and fips181.h
+
diff --git a/third_party/fips181/fips181.cc b/third_party/fips181/fips181.cc
new file mode 100644
index 0000000..ca78293
--- /dev/null
+++ b/third_party/fips181/fips181.cc
@@ -0,0 +1,2290 @@
+/*
+** This module uses code from the NIST implementation of  FIPS-181,
+** but the algorythm is CHANGED and I think that I CAN
+** copyright it. See copiright notes below.
+*/
+
+/*
+** Copyright (c) 1999, 2000, 2001, 2002, 2003
+** Adel I. Mirzazhanov. All rights reserved
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions
+** are met:
+** 
+**     1.Redistributions of source code must retain the above copyright notice,
+**       this list of conditions and the following disclaimer. 
+**     2.Redistributions in binary form must reproduce the above copyright
+**       notice, this list of conditions and the following disclaimer in the
+**       documentation and/or other materials provided with the distribution. 
+**     3.The name of the author may not be used to endorse or promote products
+**       derived from this software without specific prior written permission. 
+** 		  
+** THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND ANY EXPRESS
+** OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED.  IN  NO  EVENT  SHALL THE AUTHOR BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+** DAMAGES (INCLUDING, BUT NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE
+** GOODS OR SERVICES;  LOSS OF USE,  DATA,  OR  PROFITS;  OR BUSINESS
+** INTERRUPTION)  HOWEVER  CAUSED  AND  ON  ANY  THEORY OF LIABILITY,
+** WHETHER  IN  CONTRACT,   STRICT   LIABILITY,  OR  TORT  (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__)
+#include <strings.h> 
+#endif
+#include <time.h>
+#include <sys/types.h>
+#include "pronpass.h"
+#include "randpass.h"
+#include "convert.h"
+#include "errs.h"
+
+struct unit
+{
+    char    unit_code[5];
+    USHORT  flags;
+};
+
+static struct unit  rules[] =
+{   {"a", VOWEL},
+    {"b", NO_SPECIAL_RULE},
+    {"c", NO_SPECIAL_RULE},
+    {"d", NO_SPECIAL_RULE},
+    {"e", NO_FINAL_SPLIT | VOWEL},
+    {"f", NO_SPECIAL_RULE},
+    {"g", NO_SPECIAL_RULE},
+    {"h", NO_SPECIAL_RULE},
+    {"i", VOWEL},
+    {"j", NO_SPECIAL_RULE},
+    {"k", NO_SPECIAL_RULE},
+    {"l", NO_SPECIAL_RULE},
+    {"m", NO_SPECIAL_RULE},
+    {"n", NO_SPECIAL_RULE},
+    {"o", VOWEL},
+    {"p", NO_SPECIAL_RULE},
+    {"r", NO_SPECIAL_RULE},
+    {"s", NO_SPECIAL_RULE},
+    {"t", NO_SPECIAL_RULE},
+    {"u", VOWEL},
+    {"v", NO_SPECIAL_RULE},
+    {"w", NO_SPECIAL_RULE},
+    {"x", NOT_BEGIN_SYLLABLE},
+    {"y", ALTERNATE_VOWEL | VOWEL},
+    {"z", NO_SPECIAL_RULE},
+    {"ch", NO_SPECIAL_RULE},
+    {"gh", NO_SPECIAL_RULE},
+    {"ph", NO_SPECIAL_RULE},
+    {"rh", NO_SPECIAL_RULE},
+    {"sh", NO_SPECIAL_RULE},
+    {"th", NO_SPECIAL_RULE},
+    {"wh", NO_SPECIAL_RULE},
+    {"qu", NO_SPECIAL_RULE},
+    {"ck", NOT_BEGIN_SYLLABLE}
+};
+
+static int  digram[][RULE_SIZE] =
+{
+    {/* aa */ ILLEGAL_PAIR,
+     /* ab */ ANY_COMBINATION,
+     /* ac */ ANY_COMBINATION,
+     /* ad */ ANY_COMBINATION,
+     /* ae */ ILLEGAL_PAIR,
+     /* af */ ANY_COMBINATION,
+     /* ag */ ANY_COMBINATION,
+     /* ah */ NOT_BEGIN | BREAK | NOT_END,
+     /* ai */ ANY_COMBINATION,
+     /* aj */ ANY_COMBINATION,
+     /* ak */ ANY_COMBINATION,
+     /* al */ ANY_COMBINATION,
+     /* am */ ANY_COMBINATION,
+     /* an */ ANY_COMBINATION,
+     /* ao */ ILLEGAL_PAIR,
+     /* ap */ ANY_COMBINATION,
+     /* ar */ ANY_COMBINATION,
+     /* as */ ANY_COMBINATION,
+     /* at */ ANY_COMBINATION,
+     /* au */ ANY_COMBINATION,
+     /* av */ ANY_COMBINATION,
+     /* aw */ ANY_COMBINATION,
+     /* ax */ ANY_COMBINATION,
+     /* ay */ ANY_COMBINATION,
+     /* az */ ANY_COMBINATION,
+     /* ach */ ANY_COMBINATION,
+     /* agh */ ILLEGAL_PAIR,
+     /* aph */ ANY_COMBINATION,
+     /* arh */ ILLEGAL_PAIR,
+     /* ash */ ANY_COMBINATION,
+     /* ath */ ANY_COMBINATION,
+     /* awh */ ILLEGAL_PAIR,
+     /* aqu */ BREAK | NOT_END,
+     /* ack */ ANY_COMBINATION},
+    {/* ba */ ANY_COMBINATION,
+     /* bb */ NOT_BEGIN | BREAK | NOT_END,
+     /* bc */ NOT_BEGIN | BREAK | NOT_END,
+     /* bd */ NOT_BEGIN | BREAK | NOT_END,
+     /* be */ ANY_COMBINATION,
+     /* bf */ NOT_BEGIN | BREAK | NOT_END,
+     /* bg */ NOT_BEGIN | BREAK | NOT_END,
+     /* bh */ NOT_BEGIN | BREAK | NOT_END,
+     /* bi */ ANY_COMBINATION,
+     /* bj */ NOT_BEGIN | BREAK | NOT_END,
+     /* bk */ NOT_BEGIN | BREAK | NOT_END,
+     /* bl */ BEGIN | SUFFIX | NOT_END,
+     /* bm */ NOT_BEGIN | BREAK | NOT_END,
+     /* bn */ NOT_BEGIN | BREAK | NOT_END,
+     /* bo */ ANY_COMBINATION,
+     /* bp */ NOT_BEGIN | BREAK | NOT_END,
+     /* br */ BEGIN | END,
+     /* bs */ NOT_BEGIN,
+     /* bt */ NOT_BEGIN | BREAK | NOT_END,
+     /* bu */ ANY_COMBINATION,
+     /* bv */ NOT_BEGIN | BREAK | NOT_END,
+     /* bw */ NOT_BEGIN | BREAK | NOT_END,
+     /* bx */ ILLEGAL_PAIR,
+     /* by */ ANY_COMBINATION,
+     /* bz */ NOT_BEGIN | BREAK | NOT_END,
+     /* bch */ NOT_BEGIN | BREAK | NOT_END,
+     /* bgh */ ILLEGAL_PAIR,
+     /* bph */ NOT_BEGIN | BREAK | NOT_END,
+     /* brh */ ILLEGAL_PAIR,
+     /* bsh */ NOT_BEGIN | BREAK | NOT_END,
+     /* bth */ NOT_BEGIN | BREAK | NOT_END,
+     /* bwh */ ILLEGAL_PAIR,
+     /* bqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* bck */ ILLEGAL_PAIR },
+    {/* ca */ ANY_COMBINATION,
+     /* cb */ NOT_BEGIN | BREAK | NOT_END,
+     /* cc */ NOT_BEGIN | BREAK | NOT_END,
+     /* cd */ NOT_BEGIN | BREAK | NOT_END,
+     /* ce */ ANY_COMBINATION,
+     /* cf */ NOT_BEGIN | BREAK | NOT_END,
+     /* cg */ NOT_BEGIN | BREAK | NOT_END,
+     /* ch */ NOT_BEGIN | BREAK | NOT_END,
+     /* ci */ ANY_COMBINATION,
+     /* cj */ NOT_BEGIN | BREAK | NOT_END,
+     /* ck */ NOT_BEGIN | BREAK | NOT_END,
+     /* cl */ SUFFIX | NOT_END,
+     /* cm */ NOT_BEGIN | BREAK | NOT_END,
+     /* cn */ NOT_BEGIN | BREAK | NOT_END,
+     /* co */ ANY_COMBINATION,
+     /* cp */ NOT_BEGIN | BREAK | NOT_END,
+     /* cr */ NOT_END,
+     /* cs */ NOT_BEGIN | END,
+     /* ct */ NOT_BEGIN | PREFIX,
+     /* cu */ ANY_COMBINATION,
+     /* cv */ NOT_BEGIN | BREAK | NOT_END,
+     /* cw */ NOT_BEGIN | BREAK | NOT_END,
+     /* cx */ ILLEGAL_PAIR,
+     /* cy */ ANY_COMBINATION,
+     /* cz */ NOT_BEGIN | BREAK | NOT_END,
+     /* cch */ ILLEGAL_PAIR,
+     /* cgh */ ILLEGAL_PAIR,
+     /* cph */ NOT_BEGIN | BREAK | NOT_END,
+     /* crh */ ILLEGAL_PAIR,
+     /* csh */ NOT_BEGIN | BREAK | NOT_END,
+     /* cth */ NOT_BEGIN | BREAK | NOT_END,
+     /* cwh */ ILLEGAL_PAIR,
+     /* cqu */ NOT_BEGIN | SUFFIX | NOT_END,
+     /* cck */ ILLEGAL_PAIR},
+    {/* da */ ANY_COMBINATION,
+     /* db */ NOT_BEGIN | BREAK | NOT_END,
+     /* dc */ NOT_BEGIN | BREAK | NOT_END,
+     /* dd */ NOT_BEGIN,
+     /* de */ ANY_COMBINATION,
+     /* df */ NOT_BEGIN | BREAK | NOT_END,
+     /* dg */ NOT_BEGIN | BREAK | NOT_END,
+     /* dh */ NOT_BEGIN | BREAK | NOT_END,
+     /* di */ ANY_COMBINATION,
+     /* dj */ NOT_BEGIN | BREAK | NOT_END,
+     /* dk */ NOT_BEGIN | BREAK | NOT_END,
+     /* dl */ NOT_BEGIN | BREAK | NOT_END,
+     /* dm */ NOT_BEGIN | BREAK | NOT_END,
+     /* dn */ NOT_BEGIN | BREAK | NOT_END,
+     /* do */ ANY_COMBINATION,
+     /* dp */ NOT_BEGIN | BREAK | NOT_END,
+     /* dr */ BEGIN | NOT_END,
+     /* ds */ NOT_BEGIN | END,
+     /* dt */ NOT_BEGIN | BREAK | NOT_END,
+     /* du */ ANY_COMBINATION,
+     /* dv */ NOT_BEGIN | BREAK | NOT_END,
+     /* dw */ NOT_BEGIN | BREAK | NOT_END,
+     /* dx */ ILLEGAL_PAIR,
+     /* dy */ ANY_COMBINATION,
+     /* dz */ NOT_BEGIN | BREAK | NOT_END,
+     /* dch */ NOT_BEGIN | BREAK | NOT_END,
+     /* dgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* dph */ NOT_BEGIN | BREAK | NOT_END,
+     /* drh */ ILLEGAL_PAIR,
+     /* dsh */ NOT_BEGIN | NOT_END,
+     /* dth */ NOT_BEGIN | PREFIX,
+     /* dwh */ ILLEGAL_PAIR,
+     /* dqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* dck */ ILLEGAL_PAIR },
+    {/* ea */ ANY_COMBINATION,
+     /* eb */ ANY_COMBINATION,
+     /* ec */ ANY_COMBINATION,
+     /* ed */ ANY_COMBINATION,
+     /* ee */ ANY_COMBINATION,
+     /* ef */ ANY_COMBINATION,
+     /* eg */ ANY_COMBINATION,
+     /* eh */ NOT_BEGIN | BREAK | NOT_END,
+     /* ei */ NOT_END,
+     /* ej */ ANY_COMBINATION,
+     /* ek */ ANY_COMBINATION,
+     /* el */ ANY_COMBINATION,
+     /* em */ ANY_COMBINATION,
+     /* en */ ANY_COMBINATION,
+     /* eo */ BREAK,
+     /* ep */ ANY_COMBINATION,
+     /* er */ ANY_COMBINATION,
+     /* es */ ANY_COMBINATION,
+     /* et */ ANY_COMBINATION,
+     /* eu */ ANY_COMBINATION,
+     /* ev */ ANY_COMBINATION,
+     /* ew */ ANY_COMBINATION,
+     /* ex */ ANY_COMBINATION,
+     /* ey */ ANY_COMBINATION,
+     /* ez */ ANY_COMBINATION,
+     /* ech */ ANY_COMBINATION,
+     /* egh */ NOT_BEGIN | BREAK | NOT_END,
+     /* eph */ ANY_COMBINATION,
+     /* erh */ ILLEGAL_PAIR,
+     /* esh */ ANY_COMBINATION,
+     /* eth */ ANY_COMBINATION,
+     /* ewh */ ILLEGAL_PAIR,
+     /* equ */ BREAK | NOT_END,
+     /* eck */ ANY_COMBINATION },
+    {/* fa */ ANY_COMBINATION,
+     /* fb */ NOT_BEGIN | BREAK | NOT_END,
+     /* fc */ NOT_BEGIN | BREAK | NOT_END,
+     /* fd */ NOT_BEGIN | BREAK | NOT_END,
+     /* fe */ ANY_COMBINATION,
+     /* ff */ NOT_BEGIN,
+     /* fg */ NOT_BEGIN | BREAK | NOT_END,
+     /* fh */ NOT_BEGIN | BREAK | NOT_END,
+     /* fi */ ANY_COMBINATION,
+     /* fj */ NOT_BEGIN | BREAK | NOT_END,
+     /* fk */ NOT_BEGIN | BREAK | NOT_END,
+     /* fl */ BEGIN | SUFFIX | NOT_END,
+     /* fm */ NOT_BEGIN | BREAK | NOT_END,
+     /* fn */ NOT_BEGIN | BREAK | NOT_END,
+     /* fo */ ANY_COMBINATION,
+     /* fp */ NOT_BEGIN | BREAK | NOT_END,
+     /* fr */ BEGIN | NOT_END,
+     /* fs */ NOT_BEGIN,
+     /* ft */ NOT_BEGIN,
+     /* fu */ ANY_COMBINATION,
+     /* fv */ NOT_BEGIN | BREAK | NOT_END,
+     /* fw */ NOT_BEGIN | BREAK | NOT_END,
+     /* fx */ ILLEGAL_PAIR,
+     /* fy */ NOT_BEGIN,
+     /* fz */ NOT_BEGIN | BREAK | NOT_END,
+     /* fch */ NOT_BEGIN | BREAK | NOT_END,
+     /* fgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* fph */ NOT_BEGIN | BREAK | NOT_END,
+     /* frh */ ILLEGAL_PAIR,
+     /* fsh */ NOT_BEGIN | BREAK | NOT_END,
+     /* fth */ NOT_BEGIN | BREAK | NOT_END,
+     /* fwh */ ILLEGAL_PAIR,
+     /* fqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* fck */ ILLEGAL_PAIR },
+    {/* ga */ ANY_COMBINATION,
+     /* gb */ NOT_BEGIN | BREAK | NOT_END,
+     /* gc */ NOT_BEGIN | BREAK | NOT_END,
+     /* gd */ NOT_BEGIN | BREAK | NOT_END,
+     /* ge */ ANY_COMBINATION,
+     /* gf */ NOT_BEGIN | BREAK | NOT_END,
+     /* gg */ NOT_BEGIN,
+     /* gh */ NOT_BEGIN | BREAK | NOT_END,
+     /* gi */ ANY_COMBINATION,
+     /* gj */ NOT_BEGIN | BREAK | NOT_END,
+     /* gk */ ILLEGAL_PAIR,
+     /* gl */ BEGIN | SUFFIX | NOT_END,
+     /* gm */ NOT_BEGIN | BREAK | NOT_END,
+     /* gn */ NOT_BEGIN | BREAK | NOT_END,
+     /* go */ ANY_COMBINATION,
+     /* gp */ NOT_BEGIN | BREAK | NOT_END,
+     /* gr */ BEGIN | NOT_END,
+     /* gs */ NOT_BEGIN | END,
+     /* gt */ NOT_BEGIN | BREAK | NOT_END,
+     /* gu */ ANY_COMBINATION,
+     /* gv */ NOT_BEGIN | BREAK | NOT_END,
+     /* gw */ NOT_BEGIN | BREAK | NOT_END,
+     /* gx */ ILLEGAL_PAIR,
+     /* gy */ NOT_BEGIN,
+     /* gz */ NOT_BEGIN | BREAK | NOT_END,
+     /* gch */ NOT_BEGIN | BREAK | NOT_END,
+     /* ggh */ ILLEGAL_PAIR,
+     /* gph */ NOT_BEGIN | BREAK | NOT_END,
+     /* grh */ ILLEGAL_PAIR,
+     /* gsh */ NOT_BEGIN,
+     /* gth */ NOT_BEGIN,
+     /* gwh */ ILLEGAL_PAIR,
+     /* gqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* gck */ ILLEGAL_PAIR },
+    {/* ha */ ANY_COMBINATION,
+     /* hb */ NOT_BEGIN | BREAK | NOT_END,
+     /* hc */ NOT_BEGIN | BREAK | NOT_END,
+     /* hd */ NOT_BEGIN | BREAK | NOT_END,
+     /* he */ ANY_COMBINATION,
+     /* hf */ NOT_BEGIN | BREAK | NOT_END,
+     /* hg */ NOT_BEGIN | BREAK | NOT_END,
+     /* hh */ ILLEGAL_PAIR,
+     /* hi */ ANY_COMBINATION,
+     /* hj */ NOT_BEGIN | BREAK | NOT_END,
+     /* hk */ NOT_BEGIN | BREAK | NOT_END,
+     /* hl */ NOT_BEGIN | BREAK | NOT_END,
+     /* hm */ NOT_BEGIN | BREAK | NOT_END,
+     /* hn */ NOT_BEGIN | BREAK | NOT_END,
+     /* ho */ ANY_COMBINATION,
+     /* hp */ NOT_BEGIN | BREAK | NOT_END,
+     /* hr */ NOT_BEGIN | BREAK | NOT_END,
+     /* hs */ NOT_BEGIN | BREAK | NOT_END,
+     /* ht */ NOT_BEGIN | BREAK | NOT_END,
+     /* hu */ ANY_COMBINATION,
+     /* hv */ NOT_BEGIN | BREAK | NOT_END,
+     /* hw */ NOT_BEGIN | BREAK | NOT_END,
+     /* hx */ ILLEGAL_PAIR,
+     /* hy */ ANY_COMBINATION,
+     /* hz */ NOT_BEGIN | BREAK | NOT_END,
+     /* hch */ NOT_BEGIN | BREAK | NOT_END,
+     /* hgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* hph */ NOT_BEGIN | BREAK | NOT_END,
+     /* hrh */ ILLEGAL_PAIR,
+     /* hsh */ NOT_BEGIN | BREAK | NOT_END,
+     /* hth */ NOT_BEGIN | BREAK | NOT_END,
+     /* hwh */ ILLEGAL_PAIR,
+     /* hqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* hck */ ILLEGAL_PAIR },
+    {/* ia */ ANY_COMBINATION,
+     /* ib */ ANY_COMBINATION,
+     /* ic */ ANY_COMBINATION,
+     /* id */ ANY_COMBINATION,
+     /* ie */ NOT_BEGIN,
+     /* if */ ANY_COMBINATION,
+     /* ig */ ANY_COMBINATION,
+     /* ih */ NOT_BEGIN | BREAK | NOT_END,
+     /* ii */ ILLEGAL_PAIR,
+     /* ij */ ANY_COMBINATION,
+     /* ik */ ANY_COMBINATION,
+     /* il */ ANY_COMBINATION,
+     /* im */ ANY_COMBINATION,
+     /* in */ ANY_COMBINATION,
+     /* io */ BREAK,
+     /* ip */ ANY_COMBINATION,
+     /* ir */ ANY_COMBINATION,
+     /* is */ ANY_COMBINATION,
+     /* it */ ANY_COMBINATION,
+     /* iu */ NOT_BEGIN | BREAK | NOT_END,
+     /* iv */ ANY_COMBINATION,
+     /* iw */ NOT_BEGIN | BREAK | NOT_END,
+     /* ix */ ANY_COMBINATION,
+     /* iy */ NOT_BEGIN | BREAK | NOT_END,
+     /* iz */ ANY_COMBINATION,
+     /* ich */ ANY_COMBINATION,
+     /* igh */ NOT_BEGIN,
+     /* iph */ ANY_COMBINATION,
+     /* irh */ ILLEGAL_PAIR,
+     /* ish */ ANY_COMBINATION,
+     /* ith */ ANY_COMBINATION,
+     /* iwh */ ILLEGAL_PAIR,
+     /* iqu */ BREAK | NOT_END,
+     /* ick */ ANY_COMBINATION },
+    {/* ja */ ANY_COMBINATION,
+     /* jb */ NOT_BEGIN | BREAK | NOT_END,
+     /* jc */ NOT_BEGIN | BREAK | NOT_END,
+     /* jd */ NOT_BEGIN | BREAK | NOT_END,
+     /* je */ ANY_COMBINATION,
+     /* jf */ NOT_BEGIN | BREAK | NOT_END,
+     /* jg */ ILLEGAL_PAIR,
+     /* jh */ NOT_BEGIN | BREAK | NOT_END,
+     /* ji */ ANY_COMBINATION,
+     /* jj */ ILLEGAL_PAIR,
+     /* jk */ NOT_BEGIN | BREAK | NOT_END,
+     /* jl */ NOT_BEGIN | BREAK | NOT_END,
+     /* jm */ NOT_BEGIN | BREAK | NOT_END,
+     /* jn */ NOT_BEGIN | BREAK | NOT_END,
+     /* jo */ ANY_COMBINATION,
+     /* jp */ NOT_BEGIN | BREAK | NOT_END,
+     /* jr */ NOT_BEGIN | BREAK | NOT_END,
+     /* js */ NOT_BEGIN | BREAK | NOT_END,
+     /* jt */ NOT_BEGIN | BREAK | NOT_END,
+     /* ju */ ANY_COMBINATION,
+     /* jv */ NOT_BEGIN | BREAK | NOT_END,
+     /* jw */ NOT_BEGIN | BREAK | NOT_END,
+     /* jx */ ILLEGAL_PAIR,
+     /* jy */ NOT_BEGIN,
+     /* jz */ NOT_BEGIN | BREAK | NOT_END,
+     /* jch */ NOT_BEGIN | BREAK | NOT_END,
+     /* jgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* jph */ NOT_BEGIN | BREAK | NOT_END,
+     /* jrh */ ILLEGAL_PAIR,
+     /* jsh */ NOT_BEGIN | BREAK | NOT_END,
+     /* jth */ NOT_BEGIN | BREAK | NOT_END,
+     /* jwh */ ILLEGAL_PAIR,
+     /* jqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* jck */ ILLEGAL_PAIR },
+    {/* ka */ ANY_COMBINATION,
+     /* kb */ NOT_BEGIN | BREAK | NOT_END,
+     /* kc */ NOT_BEGIN | BREAK | NOT_END,
+     /* kd */ NOT_BEGIN | BREAK | NOT_END,
+     /* ke */ ANY_COMBINATION,
+     /* kf */ NOT_BEGIN | BREAK | NOT_END,
+     /* kg */ NOT_BEGIN | BREAK | NOT_END,
+     /* kh */ NOT_BEGIN | BREAK | NOT_END,
+     /* ki */ ANY_COMBINATION,
+     /* kj */ NOT_BEGIN | BREAK | NOT_END,
+     /* kk */ NOT_BEGIN | BREAK | NOT_END,
+     /* kl */ SUFFIX | NOT_END,
+     /* km */ NOT_BEGIN | BREAK | NOT_END,
+     /* kn */ BEGIN | SUFFIX | NOT_END,
+     /* ko */ ANY_COMBINATION,
+     /* kp */ NOT_BEGIN | BREAK | NOT_END,
+     /* kr */ SUFFIX | NOT_END,
+     /* ks */ NOT_BEGIN | END,
+     /* kt */ NOT_BEGIN | BREAK | NOT_END,
+     /* ku */ ANY_COMBINATION,
+     /* kv */ NOT_BEGIN | BREAK | NOT_END,
+     /* kw */ NOT_BEGIN | BREAK | NOT_END,
+     /* kx */ ILLEGAL_PAIR,
+     /* ky */ NOT_BEGIN,
+     /* kz */ NOT_BEGIN | BREAK | NOT_END,
+     /* kch */ NOT_BEGIN | BREAK | NOT_END,
+     /* kgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* kph */ NOT_BEGIN | PREFIX,
+     /* krh */ ILLEGAL_PAIR,
+     /* ksh */ NOT_BEGIN,
+     /* kth */ NOT_BEGIN | BREAK | NOT_END,
+     /* kwh */ ILLEGAL_PAIR,
+     /* kqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* kck */ ILLEGAL_PAIR },
+    {/* la */ ANY_COMBINATION,
+     /* lb */ NOT_BEGIN | PREFIX,
+     /* lc */ NOT_BEGIN | BREAK | NOT_END,
+     /* ld */ NOT_BEGIN | PREFIX,
+     /* le */ ANY_COMBINATION,
+     /* lf */ NOT_BEGIN | PREFIX,
+     /* lg */ NOT_BEGIN | PREFIX,
+     /* lh */ NOT_BEGIN | BREAK | NOT_END,
+     /* li */ ANY_COMBINATION,
+     /* lj */ NOT_BEGIN | PREFIX,
+     /* lk */ NOT_BEGIN | PREFIX,
+     /* ll */ NOT_BEGIN | PREFIX,
+     /* lm */ NOT_BEGIN | PREFIX,
+     /* ln */ NOT_BEGIN | BREAK | NOT_END,
+     /* lo */ ANY_COMBINATION,
+     /* lp */ NOT_BEGIN | PREFIX,
+     /* lr */ NOT_BEGIN | BREAK | NOT_END,
+     /* ls */ NOT_BEGIN,
+     /* lt */ NOT_BEGIN | PREFIX,
+     /* lu */ ANY_COMBINATION,
+     /* lv */ NOT_BEGIN | PREFIX,
+     /* lw */ NOT_BEGIN | BREAK | NOT_END,
+     /* lx */ ILLEGAL_PAIR,
+     /* ly */ ANY_COMBINATION,
+     /* lz */ NOT_BEGIN | BREAK | NOT_END,
+     /* lch */ NOT_BEGIN | PREFIX,
+     /* lgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* lph */ NOT_BEGIN | PREFIX,
+     /* lrh */ ILLEGAL_PAIR,
+     /* lsh */ NOT_BEGIN | PREFIX,
+     /* lth */ NOT_BEGIN | PREFIX,
+     /* lwh */ ILLEGAL_PAIR,
+     /* lqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* lck */ ILLEGAL_PAIR },
+    {/* ma */ ANY_COMBINATION,
+     /* mb */ NOT_BEGIN | BREAK | NOT_END,
+     /* mc */ NOT_BEGIN | BREAK | NOT_END,
+     /* md */ NOT_BEGIN | BREAK | NOT_END,
+     /* me */ ANY_COMBINATION,
+     /* mf */ NOT_BEGIN | BREAK | NOT_END,
+     /* mg */ NOT_BEGIN | BREAK | NOT_END,
+     /* mh */ NOT_BEGIN | BREAK | NOT_END,
+     /* mi */ ANY_COMBINATION,
+     /* mj */ NOT_BEGIN | BREAK | NOT_END,
+     /* mk */ NOT_BEGIN | BREAK | NOT_END,
+     /* ml */ NOT_BEGIN | BREAK | NOT_END,
+     /* mm */ NOT_BEGIN,
+     /* mn */ NOT_BEGIN | BREAK | NOT_END,
+     /* mo */ ANY_COMBINATION,
+     /* mp */ NOT_BEGIN,
+     /* mr */ NOT_BEGIN | BREAK | NOT_END,
+     /* ms */ NOT_BEGIN,
+     /* mt */ NOT_BEGIN,
+     /* mu */ ANY_COMBINATION,
+     /* mv */ NOT_BEGIN | BREAK | NOT_END,
+     /* mw */ NOT_BEGIN | BREAK | NOT_END,
+     /* mx */ ILLEGAL_PAIR,
+     /* my */ ANY_COMBINATION,
+     /* mz */ NOT_BEGIN | BREAK | NOT_END,
+     /* mch */ NOT_BEGIN | PREFIX,
+     /* mgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* mph */ NOT_BEGIN,
+     /* mrh */ ILLEGAL_PAIR,
+     /* msh */ NOT_BEGIN,
+     /* mth */ NOT_BEGIN,
+     /* mwh */ ILLEGAL_PAIR,
+     /* mqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* mck */ ILLEGAL_PAIR },
+    {/* na */ ANY_COMBINATION,
+     /* nb */ NOT_BEGIN | BREAK | NOT_END,
+     /* nc */ NOT_BEGIN | BREAK | NOT_END,
+     /* nd */ NOT_BEGIN,
+     /* ne */ ANY_COMBINATION,
+     /* nf */ NOT_BEGIN | BREAK | NOT_END,
+     /* ng */ NOT_BEGIN | PREFIX,
+     /* nh */ NOT_BEGIN | BREAK | NOT_END,
+     /* ni */ ANY_COMBINATION,
+     /* nj */ NOT_BEGIN | BREAK | NOT_END,
+     /* nk */ NOT_BEGIN | PREFIX,
+     /* nl */ NOT_BEGIN | BREAK | NOT_END,
+     /* nm */ NOT_BEGIN | BREAK | NOT_END,
+     /* nn */ NOT_BEGIN,
+     /* no */ ANY_COMBINATION,
+     /* np */ NOT_BEGIN | BREAK | NOT_END,
+     /* nr */ NOT_BEGIN | BREAK | NOT_END,
+     /* ns */ NOT_BEGIN,
+     /* nt */ NOT_BEGIN,
+     /* nu */ ANY_COMBINATION,
+     /* nv */ NOT_BEGIN | BREAK | NOT_END,
+     /* nw */ NOT_BEGIN | BREAK | NOT_END,
+     /* nx */ ILLEGAL_PAIR,
+     /* ny */ NOT_BEGIN,
+     /* nz */ NOT_BEGIN | BREAK | NOT_END,
+     /* nch */ NOT_BEGIN | PREFIX,
+     /* ngh */ NOT_BEGIN | BREAK | NOT_END,
+     /* nph */ NOT_BEGIN | PREFIX,
+     /* nrh */ ILLEGAL_PAIR,
+     /* nsh */ NOT_BEGIN,
+     /* nth */ NOT_BEGIN,
+     /* nwh */ ILLEGAL_PAIR,
+     /* nqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* nck */ NOT_BEGIN | PREFIX },
+    {/* oa */ ANY_COMBINATION,
+     /* ob */ ANY_COMBINATION,
+     /* oc */ ANY_COMBINATION,
+     /* od */ ANY_COMBINATION,
+     /* oe */ ILLEGAL_PAIR,
+     /* of */ ANY_COMBINATION,
+     /* og */ ANY_COMBINATION,
+     /* oh */ NOT_BEGIN | BREAK | NOT_END,
+     /* oi */ ANY_COMBINATION,
+     /* oj */ ANY_COMBINATION,
+     /* ok */ ANY_COMBINATION,
+     /* ol */ ANY_COMBINATION,
+     /* om */ ANY_COMBINATION,
+     /* on */ ANY_COMBINATION,
+     /* oo */ ANY_COMBINATION,
+     /* op */ ANY_COMBINATION,
+     /* or */ ANY_COMBINATION,
+     /* os */ ANY_COMBINATION,
+     /* ot */ ANY_COMBINATION,
+     /* ou */ ANY_COMBINATION,
+     /* ov */ ANY_COMBINATION,
+     /* ow */ ANY_COMBINATION,
+     /* ox */ ANY_COMBINATION,
+     /* oy */ ANY_COMBINATION,
+     /* oz */ ANY_COMBINATION,
+     /* och */ ANY_COMBINATION,
+     /* ogh */ NOT_BEGIN,
+     /* oph */ ANY_COMBINATION,
+     /* orh */ ILLEGAL_PAIR,
+     /* osh */ ANY_COMBINATION,
+     /* oth */ ANY_COMBINATION,
+     /* owh */ ILLEGAL_PAIR,
+     /* oqu */ BREAK | NOT_END,
+     /* ock */ ANY_COMBINATION },
+    {/* pa */ ANY_COMBINATION,
+     /* pb */ NOT_BEGIN | BREAK | NOT_END,
+     /* pc */ NOT_BEGIN | BREAK | NOT_END,
+     /* pd */ NOT_BEGIN | BREAK | NOT_END,
+     /* pe */ ANY_COMBINATION,
+     /* pf */ NOT_BEGIN | BREAK | NOT_END,
+     /* pg */ NOT_BEGIN | BREAK | NOT_END,
+     /* ph */ NOT_BEGIN | BREAK | NOT_END,
+     /* pi */ ANY_COMBINATION,
+     /* pj */ NOT_BEGIN | BREAK | NOT_END,
+     /* pk */ NOT_BEGIN | BREAK | NOT_END,
+     /* pl */ SUFFIX | NOT_END,
+     /* pm */ NOT_BEGIN | BREAK | NOT_END,
+     /* pn */ NOT_BEGIN | BREAK | NOT_END,
+     /* po */ ANY_COMBINATION,
+     /* pp */ NOT_BEGIN | PREFIX,
+     /* pr */ NOT_END,
+     /* ps */ NOT_BEGIN | END,
+     /* pt */ NOT_BEGIN | END,
+     /* pu */ NOT_BEGIN | END,
+     /* pv */ NOT_BEGIN | BREAK | NOT_END,
+     /* pw */ NOT_BEGIN | BREAK | NOT_END,
+     /* px */ ILLEGAL_PAIR,
+     /* py */ ANY_COMBINATION,
+     /* pz */ NOT_BEGIN | BREAK | NOT_END,
+     /* pch */ NOT_BEGIN | BREAK | NOT_END,
+     /* pgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* pph */ NOT_BEGIN | BREAK | NOT_END,
+     /* prh */ ILLEGAL_PAIR,
+     /* psh */ NOT_BEGIN | BREAK | NOT_END,
+     /* pth */ NOT_BEGIN | BREAK | NOT_END,
+     /* pwh */ ILLEGAL_PAIR,
+     /* pqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* pck */ ILLEGAL_PAIR },
+    {/* ra */ ANY_COMBINATION,
+     /* rb */ NOT_BEGIN | PREFIX,
+     /* rc */ NOT_BEGIN | PREFIX,
+     /* rd */ NOT_BEGIN | PREFIX,
+     /* re */ ANY_COMBINATION,
+     /* rf */ NOT_BEGIN | PREFIX,
+     /* rg */ NOT_BEGIN | PREFIX,
+     /* rh */ NOT_BEGIN | BREAK | NOT_END,
+     /* ri */ ANY_COMBINATION,
+     /* rj */ NOT_BEGIN | PREFIX,
+     /* rk */ NOT_BEGIN | PREFIX,
+     /* rl */ NOT_BEGIN | PREFIX,
+     /* rm */ NOT_BEGIN | PREFIX,
+     /* rn */ NOT_BEGIN | PREFIX,
+     /* ro */ ANY_COMBINATION,
+     /* rp */ NOT_BEGIN | PREFIX,
+     /* rr */ NOT_BEGIN | PREFIX,
+     /* rs */ NOT_BEGIN | PREFIX,
+     /* rt */ NOT_BEGIN | PREFIX,
+     /* ru */ ANY_COMBINATION,
+     /* rv */ NOT_BEGIN | PREFIX,
+     /* rw */ NOT_BEGIN | BREAK | NOT_END,
+     /* rx */ ILLEGAL_PAIR,
+     /* ry */ ANY_COMBINATION,
+     /* rz */ NOT_BEGIN | PREFIX,
+     /* rch */ NOT_BEGIN | PREFIX,
+     /* rgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* rph */ NOT_BEGIN | PREFIX,
+     /* rrh */ ILLEGAL_PAIR,
+     /* rsh */ NOT_BEGIN | PREFIX,
+     /* rth */ NOT_BEGIN | PREFIX,
+     /* rwh */ ILLEGAL_PAIR,
+     /* rqu */ NOT_BEGIN | PREFIX | NOT_END,
+     /* rck */ NOT_BEGIN | PREFIX },
+    {/* sa */ ANY_COMBINATION,
+     /* sb */ NOT_BEGIN | BREAK | NOT_END,
+     /* sc */ NOT_END,
+     /* sd */ NOT_BEGIN | BREAK | NOT_END,
+     /* se */ ANY_COMBINATION,
+     /* sf */ NOT_BEGIN | BREAK | NOT_END,
+     /* sg */ NOT_BEGIN | BREAK | NOT_END,
+     /* sh */ NOT_BEGIN | BREAK | NOT_END,
+     /* si */ ANY_COMBINATION,
+     /* sj */ NOT_BEGIN | BREAK | NOT_END,
+     /* sk */ ANY_COMBINATION,
+     /* sl */ BEGIN | SUFFIX | NOT_END,
+     /* sm */ SUFFIX | NOT_END,
+     /* sn */ PREFIX | SUFFIX | NOT_END,
+     /* so */ ANY_COMBINATION,
+     /* sp */ ANY_COMBINATION,
+     /* sr */ NOT_BEGIN | NOT_END,
+     /* ss */ NOT_BEGIN | PREFIX,
+     /* st */ ANY_COMBINATION,
+     /* su */ ANY_COMBINATION,
+     /* sv */ NOT_BEGIN | BREAK | NOT_END,
+     /* sw */ BEGIN | SUFFIX | NOT_END,
+     /* sx */ ILLEGAL_PAIR,
+     /* sy */ ANY_COMBINATION,
+     /* sz */ NOT_BEGIN | BREAK | NOT_END,
+     /* sch */ BEGIN | SUFFIX | NOT_END,
+     /* sgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* sph */ NOT_BEGIN | BREAK | NOT_END,
+     /* srh */ ILLEGAL_PAIR,
+     /* ssh */ NOT_BEGIN | BREAK | NOT_END,
+     /* sth */ NOT_BEGIN | BREAK | NOT_END,
+     /* swh */ ILLEGAL_PAIR,
+     /* squ */ SUFFIX | NOT_END,
+     /* sck */ NOT_BEGIN },
+    {/* ta */ ANY_COMBINATION,
+     /* tb */ NOT_BEGIN | BREAK | NOT_END,
+     /* tc */ NOT_BEGIN | BREAK | NOT_END,
+     /* td */ NOT_BEGIN | BREAK | NOT_END,
+     /* te */ ANY_COMBINATION,
+     /* tf */ NOT_BEGIN | BREAK | NOT_END,
+     /* tg */ NOT_BEGIN | BREAK | NOT_END,
+     /* th */ NOT_BEGIN | BREAK | NOT_END,
+     /* ti */ ANY_COMBINATION,
+     /* tj */ NOT_BEGIN | BREAK | NOT_END,
+     /* tk */ NOT_BEGIN | BREAK | NOT_END,
+     /* tl */ NOT_BEGIN | BREAK | NOT_END,
+     /* tm */ NOT_BEGIN | BREAK | NOT_END,
+     /* tn */ NOT_BEGIN | BREAK | NOT_END,
+     /* to */ ANY_COMBINATION,
+     /* tp */ NOT_BEGIN | BREAK | NOT_END,
+     /* tr */ NOT_END,
+     /* ts */ NOT_BEGIN | END,
+     /* tt */ NOT_BEGIN | PREFIX,
+     /* tu */ ANY_COMBINATION,
+     /* tv */ NOT_BEGIN | BREAK | NOT_END,
+     /* tw */ BEGIN | SUFFIX | NOT_END,
+     /* tx */ ILLEGAL_PAIR,
+     /* ty */ ANY_COMBINATION,
+     /* tz */ NOT_BEGIN | BREAK | NOT_END,
+     /* tch */ NOT_BEGIN,
+     /* tgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* tph */ NOT_BEGIN | END,
+     /* trh */ ILLEGAL_PAIR,
+     /* tsh */ NOT_BEGIN | END,
+     /* tth */ NOT_BEGIN | BREAK | NOT_END,
+     /* twh */ ILLEGAL_PAIR,
+     /* tqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* tck */ ILLEGAL_PAIR },
+    {/* ua */ NOT_BEGIN | BREAK | NOT_END,
+     /* ub */ ANY_COMBINATION,
+     /* uc */ ANY_COMBINATION,
+     /* ud */ ANY_COMBINATION,
+     /* ue */ NOT_BEGIN,
+     /* uf */ ANY_COMBINATION,
+     /* ug */ ANY_COMBINATION,
+     /* uh */ NOT_BEGIN | BREAK | NOT_END,
+     /* ui */ NOT_BEGIN | BREAK | NOT_END,
+     /* uj */ ANY_COMBINATION,
+     /* uk */ ANY_COMBINATION,
+     /* ul */ ANY_COMBINATION,
+     /* um */ ANY_COMBINATION,
+     /* un */ ANY_COMBINATION,
+     /* uo */ NOT_BEGIN | BREAK,
+     /* up */ ANY_COMBINATION,
+     /* ur */ ANY_COMBINATION,
+     /* us */ ANY_COMBINATION,
+     /* ut */ ANY_COMBINATION,
+     /* uu */ ILLEGAL_PAIR,
+     /* uv */ ANY_COMBINATION,
+     /* uw */ NOT_BEGIN | BREAK | NOT_END,
+     /* ux */ ANY_COMBINATION,
+     /* uy */ NOT_BEGIN | BREAK | NOT_END,
+     /* uz */ ANY_COMBINATION,
+     /* uch */ ANY_COMBINATION,
+     /* ugh */ NOT_BEGIN | PREFIX,
+     /* uph */ ANY_COMBINATION,
+     /* urh */ ILLEGAL_PAIR,
+     /* ush */ ANY_COMBINATION,
+     /* uth */ ANY_COMBINATION,
+     /* uwh */ ILLEGAL_PAIR,
+     /* uqu */ BREAK | NOT_END,
+     /* uck */ ANY_COMBINATION },
+    {/* va */ ANY_COMBINATION,
+     /* vb */ NOT_BEGIN | BREAK | NOT_END,
+     /* vc */ NOT_BEGIN | BREAK | NOT_END,
+     /* vd */ NOT_BEGIN | BREAK | NOT_END,
+     /* ve */ ANY_COMBINATION,
+     /* vf */ NOT_BEGIN | BREAK | NOT_END,
+     /* vg */ NOT_BEGIN | BREAK | NOT_END,
+     /* vh */ NOT_BEGIN | BREAK | NOT_END,
+     /* vi */ ANY_COMBINATION,
+     /* vj */ NOT_BEGIN | BREAK | NOT_END,
+     /* vk */ NOT_BEGIN | BREAK | NOT_END,
+     /* vl */ NOT_BEGIN | BREAK | NOT_END,
+     /* vm */ NOT_BEGIN | BREAK | NOT_END,
+     /* vn */ NOT_BEGIN | BREAK | NOT_END,
+     /* vo */ ANY_COMBINATION,
+     /* vp */ NOT_BEGIN | BREAK | NOT_END,
+     /* vr */ NOT_BEGIN | BREAK | NOT_END,
+     /* vs */ NOT_BEGIN | BREAK | NOT_END,
+     /* vt */ NOT_BEGIN | BREAK | NOT_END,
+     /* vu */ ANY_COMBINATION,
+     /* vv */ NOT_BEGIN | BREAK | NOT_END,
+     /* vw */ NOT_BEGIN | BREAK | NOT_END,
+     /* vx */ ILLEGAL_PAIR,
+     /* vy */ NOT_BEGIN,
+     /* vz */ NOT_BEGIN | BREAK | NOT_END,
+     /* vch */ NOT_BEGIN | BREAK | NOT_END,
+     /* vgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* vph */ NOT_BEGIN | BREAK | NOT_END,
+     /* vrh */ ILLEGAL_PAIR,
+     /* vsh */ NOT_BEGIN | BREAK | NOT_END,
+     /* vth */ NOT_BEGIN | BREAK | NOT_END,
+     /* vwh */ ILLEGAL_PAIR,
+     /* vqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* vck */ ILLEGAL_PAIR },
+    {/* wa */ ANY_COMBINATION,
+     /* wb */ NOT_BEGIN | PREFIX,
+     /* wc */ NOT_BEGIN | BREAK | NOT_END,
+     /* wd */ NOT_BEGIN | PREFIX | END,
+     /* we */ ANY_COMBINATION,
+     /* wf */ NOT_BEGIN | PREFIX,
+     /* wg */ NOT_BEGIN | PREFIX | END,
+     /* wh */ NOT_BEGIN | BREAK | NOT_END,
+     /* wi */ ANY_COMBINATION,
+     /* wj */ NOT_BEGIN | BREAK | NOT_END,
+     /* wk */ NOT_BEGIN | PREFIX,
+     /* wl */ NOT_BEGIN | PREFIX | SUFFIX,
+     /* wm */ NOT_BEGIN | PREFIX,
+     /* wn */ NOT_BEGIN | PREFIX,
+     /* wo */ ANY_COMBINATION,
+     /* wp */ NOT_BEGIN | PREFIX,
+     /* wr */ BEGIN | SUFFIX | NOT_END,
+     /* ws */ NOT_BEGIN | PREFIX,
+     /* wt */ NOT_BEGIN | PREFIX,
+     /* wu */ ANY_COMBINATION,
+     /* wv */ NOT_BEGIN | PREFIX,
+     /* ww */ NOT_BEGIN | BREAK | NOT_END,
+     /* wx */ NOT_BEGIN | PREFIX,
+     /* wy */ ANY_COMBINATION,
+     /* wz */ NOT_BEGIN | PREFIX,
+     /* wch */ NOT_BEGIN,
+     /* wgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* wph */ NOT_BEGIN,
+     /* wrh */ ILLEGAL_PAIR,
+     /* wsh */ NOT_BEGIN,
+     /* wth */ NOT_BEGIN,
+     /* wwh */ ILLEGAL_PAIR,
+     /* wqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* wck */ NOT_BEGIN },
+    {/* xa */ NOT_BEGIN,
+     /* xb */ NOT_BEGIN | BREAK | NOT_END,
+     /* xc */ NOT_BEGIN | BREAK | NOT_END,
+     /* xd */ NOT_BEGIN | BREAK | NOT_END,
+     /* xe */ NOT_BEGIN,
+     /* xf */ NOT_BEGIN | BREAK | NOT_END,
+     /* xg */ NOT_BEGIN | BREAK | NOT_END,
+     /* xh */ NOT_BEGIN | BREAK | NOT_END,
+     /* xi */ NOT_BEGIN,
+     /* xj */ NOT_BEGIN | BREAK | NOT_END,
+     /* xk */ NOT_BEGIN | BREAK | NOT_END,
+     /* xl */ NOT_BEGIN | BREAK | NOT_END,
+     /* xm */ NOT_BEGIN | BREAK | NOT_END,
+     /* xn */ NOT_BEGIN | BREAK | NOT_END,
+     /* xo */ NOT_BEGIN,
+     /* xp */ NOT_BEGIN | BREAK | NOT_END,
+     /* xr */ NOT_BEGIN | BREAK | NOT_END,
+     /* xs */ NOT_BEGIN | BREAK | NOT_END,
+     /* xt */ NOT_BEGIN | BREAK | NOT_END,
+     /* xu */ NOT_BEGIN,
+     /* xv */ NOT_BEGIN | BREAK | NOT_END,
+     /* xw */ NOT_BEGIN | BREAK | NOT_END,
+     /* xx */ ILLEGAL_PAIR,
+     /* xy */ NOT_BEGIN,
+     /* xz */ NOT_BEGIN | BREAK | NOT_END,
+     /* xch */ NOT_BEGIN | BREAK | NOT_END,
+     /* xgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* xph */ NOT_BEGIN | BREAK | NOT_END,
+     /* xrh */ ILLEGAL_PAIR,
+     /* xsh */ NOT_BEGIN | BREAK | NOT_END,
+     /* xth */ NOT_BEGIN | BREAK | NOT_END,
+     /* xwh */ ILLEGAL_PAIR,
+     /* xqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* xck */ ILLEGAL_PAIR },
+    {/* ya */ ANY_COMBINATION,
+     /* yb */ NOT_BEGIN,
+     /* yc */ NOT_BEGIN | NOT_END,
+     /* yd */ NOT_BEGIN,
+     /* ye */ ANY_COMBINATION,
+     /* yf */ NOT_BEGIN | NOT_END,
+     /* yg */ NOT_BEGIN,
+     /* yh */ NOT_BEGIN | BREAK | NOT_END,
+     /* yi */ BEGIN | NOT_END,
+     /* yj */ NOT_BEGIN | NOT_END,
+     /* yk */ NOT_BEGIN,
+     /* yl */ NOT_BEGIN | NOT_END,
+     /* ym */ NOT_BEGIN,
+     /* yn */ NOT_BEGIN,
+     /* yo */ ANY_COMBINATION,
+     /* yp */ NOT_BEGIN,
+     /* yr */ NOT_BEGIN | BREAK | NOT_END,
+     /* ys */ NOT_BEGIN,
+     /* yt */ NOT_BEGIN,
+     /* yu */ ANY_COMBINATION,
+     /* yv */ NOT_BEGIN | NOT_END,
+     /* yw */ NOT_BEGIN | BREAK | NOT_END,
+     /* yx */ NOT_BEGIN,
+     /* yy */ ILLEGAL_PAIR,
+     /* yz */ NOT_BEGIN,
+     /* ych */ NOT_BEGIN | BREAK | NOT_END,
+     /* ygh */ NOT_BEGIN | BREAK | NOT_END,
+     /* yph */ NOT_BEGIN | BREAK | NOT_END,
+     /* yrh */ ILLEGAL_PAIR,
+     /* ysh */ NOT_BEGIN | BREAK | NOT_END,
+     /* yth */ NOT_BEGIN | BREAK | NOT_END,
+     /* ywh */ ILLEGAL_PAIR,
+     /* yqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* yck */ ILLEGAL_PAIR },
+    {/* za */ ANY_COMBINATION,
+     /* zb */ NOT_BEGIN | BREAK | NOT_END,
+     /* zc */ NOT_BEGIN | BREAK | NOT_END,
+     /* zd */ NOT_BEGIN | BREAK | NOT_END,
+     /* ze */ ANY_COMBINATION,
+     /* zf */ NOT_BEGIN | BREAK | NOT_END,
+     /* zg */ NOT_BEGIN | BREAK | NOT_END,
+     /* zh */ NOT_BEGIN | BREAK | NOT_END,
+     /* zi */ ANY_COMBINATION,
+     /* zj */ NOT_BEGIN | BREAK | NOT_END,
+     /* zk */ NOT_BEGIN | BREAK | NOT_END,
+     /* zl */ NOT_BEGIN | BREAK | NOT_END,
+     /* zm */ NOT_BEGIN | BREAK | NOT_END,
+     /* zn */ NOT_BEGIN | BREAK | NOT_END,
+     /* zo */ ANY_COMBINATION,
+     /* zp */ NOT_BEGIN | BREAK | NOT_END,
+     /* zr */ NOT_BEGIN | NOT_END,
+     /* zs */ NOT_BEGIN | BREAK | NOT_END,
+     /* zt */ NOT_BEGIN,
+     /* zu */ ANY_COMBINATION,
+     /* zv */ NOT_BEGIN | BREAK | NOT_END,
+     /* zw */ SUFFIX | NOT_END,
+     /* zx */ ILLEGAL_PAIR,
+     /* zy */ ANY_COMBINATION,
+     /* zz */ NOT_BEGIN,
+     /* zch */ NOT_BEGIN | BREAK | NOT_END,
+     /* zgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* zph */ NOT_BEGIN | BREAK | NOT_END,
+     /* zrh */ ILLEGAL_PAIR,
+     /* zsh */ NOT_BEGIN | BREAK | NOT_END,
+     /* zth */ NOT_BEGIN | BREAK | NOT_END,
+     /* zwh */ ILLEGAL_PAIR,
+     /* zqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* zck */ ILLEGAL_PAIR },
+    {/* cha */ ANY_COMBINATION,
+     /* chb */ NOT_BEGIN | BREAK | NOT_END,
+     /* chc */ NOT_BEGIN | BREAK | NOT_END,
+     /* chd */ NOT_BEGIN | BREAK | NOT_END,
+     /* che */ ANY_COMBINATION,
+     /* chf */ NOT_BEGIN | BREAK | NOT_END,
+     /* chg */ NOT_BEGIN | BREAK | NOT_END,
+     /* chh */ NOT_BEGIN | BREAK | NOT_END,
+     /* chi */ ANY_COMBINATION,
+     /* chj */ NOT_BEGIN | BREAK | NOT_END,
+     /* chk */ NOT_BEGIN | BREAK | NOT_END,
+     /* chl */ NOT_BEGIN | BREAK | NOT_END,
+     /* chm */ NOT_BEGIN | BREAK | NOT_END,
+     /* chn */ NOT_BEGIN | BREAK | NOT_END,
+     /* cho */ ANY_COMBINATION,
+     /* chp */ NOT_BEGIN | BREAK | NOT_END,
+     /* chr */ NOT_END,
+     /* chs */ NOT_BEGIN | BREAK | NOT_END,
+     /* cht */ NOT_BEGIN | BREAK | NOT_END,
+     /* chu */ ANY_COMBINATION,
+     /* chv */ NOT_BEGIN | BREAK | NOT_END,
+     /* chw */ NOT_BEGIN | NOT_END,
+     /* chx */ ILLEGAL_PAIR,
+     /* chy */ ANY_COMBINATION,
+     /* chz */ NOT_BEGIN | BREAK | NOT_END,
+     /* chch */ ILLEGAL_PAIR,
+     /* chgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* chph */ NOT_BEGIN | BREAK | NOT_END,
+     /* chrh */ ILLEGAL_PAIR,
+     /* chsh */ NOT_BEGIN | BREAK | NOT_END,
+     /* chth */ NOT_BEGIN | BREAK | NOT_END,
+     /* chwh */ ILLEGAL_PAIR,
+     /* chqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* chck */ ILLEGAL_PAIR },
+    {/* gha */ ANY_COMBINATION,
+     /* ghb */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghc */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghd */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghe */ ANY_COMBINATION,
+     /* ghf */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghg */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghh */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghi */ BEGIN | NOT_END,
+     /* ghj */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghk */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghl */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghm */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghn */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* gho */ BEGIN | NOT_END,
+     /* ghp */ NOT_BEGIN | BREAK | NOT_END,
+     /* ghr */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghs */ NOT_BEGIN | PREFIX,
+     /* ght */ NOT_BEGIN | PREFIX,
+     /* ghu */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghv */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghw */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghx */ ILLEGAL_PAIR,
+     /* ghy */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghz */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghch */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghgh */ ILLEGAL_PAIR,
+     /* ghph */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghrh */ ILLEGAL_PAIR,
+     /* ghsh */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghth */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghwh */ ILLEGAL_PAIR,
+     /* ghqu */ NOT_BEGIN | BREAK | PREFIX | NOT_END,
+     /* ghck */ ILLEGAL_PAIR },
+    {/* pha */ ANY_COMBINATION,
+     /* phb */ NOT_BEGIN | BREAK | NOT_END,
+     /* phc */ NOT_BEGIN | BREAK | NOT_END,
+     /* phd */ NOT_BEGIN | BREAK | NOT_END,
+     /* phe */ ANY_COMBINATION,
+     /* phf */ NOT_BEGIN | BREAK | NOT_END,
+     /* phg */ NOT_BEGIN | BREAK | NOT_END,
+     /* phh */ NOT_BEGIN | BREAK | NOT_END,
+     /* phi */ ANY_COMBINATION,
+     /* phj */ NOT_BEGIN | BREAK | NOT_END,
+     /* phk */ NOT_BEGIN | BREAK | NOT_END,
+     /* phl */ BEGIN | SUFFIX | NOT_END,
+     /* phm */ NOT_BEGIN | BREAK | NOT_END,
+     /* phn */ NOT_BEGIN | BREAK | NOT_END,
+     /* pho */ ANY_COMBINATION,
+     /* php */ NOT_BEGIN | BREAK | NOT_END,
+     /* phr */ NOT_END,
+     /* phs */ NOT_BEGIN,
+     /* pht */ NOT_BEGIN,
+     /* phu */ ANY_COMBINATION,
+     /* phv */ NOT_BEGIN | NOT_END,
+     /* phw */ NOT_BEGIN | NOT_END,
+     /* phx */ ILLEGAL_PAIR,
+     /* phy */ NOT_BEGIN,
+     /* phz */ NOT_BEGIN | BREAK | NOT_END,
+     /* phch */ NOT_BEGIN | BREAK | NOT_END,
+     /* phgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* phph */ ILLEGAL_PAIR,
+     /* phrh */ ILLEGAL_PAIR,
+     /* phsh */ NOT_BEGIN | BREAK | NOT_END,
+     /* phth */ NOT_BEGIN | BREAK | NOT_END,
+     /* phwh */ ILLEGAL_PAIR,
+     /* phqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* phck */ ILLEGAL_PAIR },
+    {/* rha */ BEGIN | NOT_END,
+     /* rhb */ ILLEGAL_PAIR,
+     /* rhc */ ILLEGAL_PAIR,
+     /* rhd */ ILLEGAL_PAIR,
+     /* rhe */ BEGIN | NOT_END,
+     /* rhf */ ILLEGAL_PAIR,
+     /* rhg */ ILLEGAL_PAIR,
+     /* rhh */ ILLEGAL_PAIR,
+     /* rhi */ BEGIN | NOT_END,
+     /* rhj */ ILLEGAL_PAIR,
+     /* rhk */ ILLEGAL_PAIR,
+     /* rhl */ ILLEGAL_PAIR,
+     /* rhm */ ILLEGAL_PAIR,
+     /* rhn */ ILLEGAL_PAIR,
+     /* rho */ BEGIN | NOT_END,
+     /* rhp */ ILLEGAL_PAIR,
+     /* rhr */ ILLEGAL_PAIR,
+     /* rhs */ ILLEGAL_PAIR,
+     /* rht */ ILLEGAL_PAIR,
+     /* rhu */ BEGIN | NOT_END,
+     /* rhv */ ILLEGAL_PAIR,
+     /* rhw */ ILLEGAL_PAIR,
+     /* rhx */ ILLEGAL_PAIR,
+     /* rhy */ BEGIN | NOT_END,
+     /* rhz */ ILLEGAL_PAIR,
+     /* rhch */ ILLEGAL_PAIR,
+     /* rhgh */ ILLEGAL_PAIR,
+     /* rhph */ ILLEGAL_PAIR,
+     /* rhrh */ ILLEGAL_PAIR,
+     /* rhsh */ ILLEGAL_PAIR,
+     /* rhth */ ILLEGAL_PAIR,
+     /* rhwh */ ILLEGAL_PAIR,
+     /* rhqu */ ILLEGAL_PAIR,
+     /* rhck */ ILLEGAL_PAIR },
+    {/* sha */ ANY_COMBINATION,
+     /* shb */ NOT_BEGIN | BREAK | NOT_END,
+     /* shc */ NOT_BEGIN | BREAK | NOT_END,
+     /* shd */ NOT_BEGIN | BREAK | NOT_END,
+     /* she */ ANY_COMBINATION,
+     /* shf */ NOT_BEGIN | BREAK | NOT_END,
+     /* shg */ NOT_BEGIN | BREAK | NOT_END,
+     /* shh */ ILLEGAL_PAIR,
+     /* shi */ ANY_COMBINATION,
+     /* shj */ NOT_BEGIN | BREAK | NOT_END,
+     /* shk */ NOT_BEGIN,
+     /* shl */ BEGIN | SUFFIX | NOT_END,
+     /* shm */ BEGIN | SUFFIX | NOT_END,
+     /* shn */ BEGIN | SUFFIX | NOT_END,
+     /* sho */ ANY_COMBINATION,
+     /* shp */ NOT_BEGIN,
+     /* shr */ BEGIN | SUFFIX | NOT_END,
+     /* shs */ NOT_BEGIN | BREAK | NOT_END,
+     /* sht */ SUFFIX,
+     /* shu */ ANY_COMBINATION,
+     /* shv */ NOT_BEGIN | BREAK | NOT_END,
+     /* shw */ SUFFIX | NOT_END,
+     /* shx */ ILLEGAL_PAIR,
+     /* shy */ ANY_COMBINATION,
+     /* shz */ NOT_BEGIN | BREAK | NOT_END,
+     /* shch */ NOT_BEGIN | BREAK | NOT_END,
+     /* shgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* shph */ NOT_BEGIN | BREAK | NOT_END,
+     /* shrh */ ILLEGAL_PAIR,
+     /* shsh */ ILLEGAL_PAIR,
+     /* shth */ NOT_BEGIN | BREAK | NOT_END,
+     /* shwh */ ILLEGAL_PAIR,
+     /* shqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* shck */ ILLEGAL_PAIR },
+    {/* tha */ ANY_COMBINATION,
+     /* thb */ NOT_BEGIN | BREAK | NOT_END,
+     /* thc */ NOT_BEGIN | BREAK | NOT_END,
+     /* thd */ NOT_BEGIN | BREAK | NOT_END,
+     /* the */ ANY_COMBINATION,
+     /* thf */ NOT_BEGIN | BREAK | NOT_END,
+     /* thg */ NOT_BEGIN | BREAK | NOT_END,
+     /* thh */ NOT_BEGIN | BREAK | NOT_END,
+     /* thi */ ANY_COMBINATION,
+     /* thj */ NOT_BEGIN | BREAK | NOT_END,
+     /* thk */ NOT_BEGIN | BREAK | NOT_END,
+     /* thl */ NOT_BEGIN | BREAK | NOT_END,
+     /* thm */ NOT_BEGIN | BREAK | NOT_END,
+     /* thn */ NOT_BEGIN | BREAK | NOT_END,
+     /* tho */ ANY_COMBINATION,
+     /* thp */ NOT_BEGIN | BREAK | NOT_END,
+     /* thr */ NOT_END,
+     /* ths */ NOT_BEGIN | END,
+     /* tht */ NOT_BEGIN | BREAK | NOT_END,
+     /* thu */ ANY_COMBINATION,
+     /* thv */ NOT_BEGIN | BREAK | NOT_END,
+     /* thw */ SUFFIX | NOT_END,
+     /* thx */ ILLEGAL_PAIR,
+     /* thy */ ANY_COMBINATION,
+     /* thz */ NOT_BEGIN | BREAK | NOT_END,
+     /* thch */ NOT_BEGIN | BREAK | NOT_END,
+     /* thgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* thph */ NOT_BEGIN | BREAK | NOT_END,
+     /* thrh */ ILLEGAL_PAIR,
+     /* thsh */ NOT_BEGIN | BREAK | NOT_END,
+     /* thth */ ILLEGAL_PAIR,
+     /* thwh */ ILLEGAL_PAIR,
+     /* thqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* thck */ ILLEGAL_PAIR },
+    {/* wha */ BEGIN | NOT_END,
+     /* whb */ ILLEGAL_PAIR,
+     /* whc */ ILLEGAL_PAIR,
+     /* whd */ ILLEGAL_PAIR,
+     /* whe */ BEGIN | NOT_END,
+     /* whf */ ILLEGAL_PAIR,
+     /* whg */ ILLEGAL_PAIR,
+     /* whh */ ILLEGAL_PAIR,
+     /* whi */ BEGIN | NOT_END,
+     /* whj */ ILLEGAL_PAIR,
+     /* whk */ ILLEGAL_PAIR,
+     /* whl */ ILLEGAL_PAIR,
+     /* whm */ ILLEGAL_PAIR,
+     /* whn */ ILLEGAL_PAIR,
+     /* who */ BEGIN | NOT_END,
+     /* whp */ ILLEGAL_PAIR,
+     /* whr */ ILLEGAL_PAIR,
+     /* whs */ ILLEGAL_PAIR,
+     /* wht */ ILLEGAL_PAIR,
+     /* whu */ ILLEGAL_PAIR,
+     /* whv */ ILLEGAL_PAIR,
+     /* whw */ ILLEGAL_PAIR,
+     /* whx */ ILLEGAL_PAIR,
+     /* why */ BEGIN | NOT_END,
+     /* whz */ ILLEGAL_PAIR,
+     /* whch */ ILLEGAL_PAIR,
+     /* whgh */ ILLEGAL_PAIR,
+     /* whph */ ILLEGAL_PAIR,
+     /* whrh */ ILLEGAL_PAIR,
+     /* whsh */ ILLEGAL_PAIR,
+     /* whth */ ILLEGAL_PAIR,
+     /* whwh */ ILLEGAL_PAIR,
+     /* whqu */ ILLEGAL_PAIR,
+     /* whck */ ILLEGAL_PAIR },
+    {/* qua */ ANY_COMBINATION,
+     /* qub */ ILLEGAL_PAIR,
+     /* quc */ ILLEGAL_PAIR,
+     /* qud */ ILLEGAL_PAIR,
+     /* que */ ANY_COMBINATION,
+     /* quf */ ILLEGAL_PAIR,
+     /* qug */ ILLEGAL_PAIR,
+     /* quh */ ILLEGAL_PAIR,
+     /* qui */ ANY_COMBINATION,
+     /* quj */ ILLEGAL_PAIR,
+     /* quk */ ILLEGAL_PAIR,
+     /* qul */ ILLEGAL_PAIR,
+     /* qum */ ILLEGAL_PAIR,
+     /* qun */ ILLEGAL_PAIR,
+     /* quo */ ANY_COMBINATION,
+     /* qup */ ILLEGAL_PAIR,
+     /* qur */ ILLEGAL_PAIR,
+     /* qus */ ILLEGAL_PAIR,
+     /* qut */ ILLEGAL_PAIR,
+     /* quu */ ILLEGAL_PAIR,
+     /* quv */ ILLEGAL_PAIR,
+     /* quw */ ILLEGAL_PAIR,
+     /* qux */ ILLEGAL_PAIR,
+     /* quy */ ILLEGAL_PAIR,
+     /* quz */ ILLEGAL_PAIR,
+     /* quch */ ILLEGAL_PAIR,
+     /* qugh */ ILLEGAL_PAIR,
+     /* quph */ ILLEGAL_PAIR,
+     /* qurh */ ILLEGAL_PAIR,
+     /* qush */ ILLEGAL_PAIR,
+     /* quth */ ILLEGAL_PAIR,
+     /* quwh */ ILLEGAL_PAIR,
+     /* ququ */ ILLEGAL_PAIR,
+     /* quck */ ILLEGAL_PAIR },
+    {/* cka */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckb */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckc */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckd */ NOT_BEGIN | BREAK | NOT_END,
+     /* cke */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckf */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckg */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckh */ NOT_BEGIN | BREAK | NOT_END,
+     /* cki */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckj */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckk */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckl */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckm */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckn */ NOT_BEGIN | BREAK | NOT_END,
+     /* cko */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckp */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckr */ NOT_BEGIN | BREAK | NOT_END,
+     /* cks */ NOT_BEGIN,
+     /* ckt */ NOT_BEGIN | BREAK | NOT_END,
+     /* cku */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckv */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckw */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckx */ ILLEGAL_PAIR,
+     /* cky */ NOT_BEGIN,
+     /* ckz */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckch */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckgh */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckph */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckrh */ ILLEGAL_PAIR,
+     /* cksh */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckth */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckwh */ ILLEGAL_PAIR,
+     /* ckqu */ NOT_BEGIN | BREAK | NOT_END,
+     /* ckck */ ILLEGAL_PAIR}
+};
+
+/*
+** gen_pron_pass will generate a Random word and place it in the
+** buffer word.  Also, the hyphenated word will be placed into
+** the buffer hyphenated_word.  Both word and hyphenated_word must
+** be pre-allocated.  The words generated will have sizes between
+** minlen and maxlen.  If restrict is TRUE, words will not be generated that
+** appear as login names or as entries in the on-line dictionary.
+** This algorithm was initially worded out by Morrie Gasser in 1975.
+** Any changes here are minimal so that as many word combinations
+** can be produced as possible (and thus keep the words Random).
+** The seed is used on first use of the routine.
+** The length of the unhyphenated word is returned, or -1 if there
+** were an error (length settings are wrong or dictionary checking
+** could not be done.
+*/
+int
+gen_pron_pass (char *word, char *hyphenated_word, USHORT minlen,
+               USHORT maxlen, unsigned int pass_mode)
+{
+
+    int     pwlen;
+
+ /* 
+  * Check for minlen>maxlen.  This is an error.
+  * and a length of 0.
+  */
+    if (minlen > maxlen || minlen > APG_MAX_PASSWORD_LENGTH ||
+        maxlen > APG_MAX_PASSWORD_LENGTH)
+      return (-1);
+ /* 
+  * Check for zero length words.  This is technically not an error,
+  * so we take the short cut and return a null word and a length of 0.
+  */
+    if (maxlen == 0)
+    {
+     word[0] = '\0';
+     hyphenated_word[0] = '\0';
+     return (0);
+    }
+
+ /* 
+  * Find password.
+  */
+    pwlen = gen_word (word, hyphenated_word, get_random (minlen, maxlen), pass_mode);
+    return (pwlen);
+}
+
+
+/*
+ * This is the routine that returns a Random word -- as
+ * yet unchecked against the passwd file or the dictionary.
+ * It collects Random syllables until a predetermined
+ * word length is found.  If a retry threshold is reached,
+ * another word is tried.  Given that the Random number
+ * generator is uniformly distributed, eventually a word
+ * will be found if the retry limit is adequately large enough.
+ */
+int
+gen_word (char *word, char *hyphenated_word, USHORT pwlen, unsigned int pass_mode)
+{
+    USHORT word_length;
+    USHORT syllable_length;
+    char   *new_syllable;
+    char   *syllable_for_hyph;
+    USHORT *syllable_units;
+    USHORT word_size;
+    USHORT word_place;
+    USHORT *word_units;
+    USHORT syllable_size;
+    UINT   tries;
+    int ch_flag = FALSE;
+    int dsd = 0;
+
+    /*
+     * Keep count of retries.
+     */
+    tries = 0;
+
+    /*
+     * The length of the word in characters.
+     */
+    word_length = 0;
+
+    /*
+     * The length of the word in character units (each of which is one or
+     * two characters long.
+     */
+    word_size = 0;
+
+    /*
+     * Initialize the array storing the word units.  Since we know the
+     * length of the word, we only need one of that length.  This method is
+     * preferable to a static array, since it allows us flexibility in
+     * choosing arbitrarily long word lengths.  Since a word can contain one
+     * syllable, we should make syllable_units, the array holding the
+     * analogous units for an individual syllable, the same length. No
+     * explicit rule limits the length of syllables, but digram rules and
+     * heuristics do so indirectly.
+     */
+    if ( (word_units     = (USHORT *) calloc (sizeof (USHORT), pwlen+1))==NULL ||
+         (syllable_units = (USHORT *) calloc (sizeof (USHORT), pwlen+1))==NULL ||
+         (new_syllable   = (char *) calloc (sizeof (USHORT), pwlen+1))  ==NULL ||
+	 (syllable_for_hyph = (char *) calloc (sizeof(char), 20))==NULL)
+	   return(-1);
+
+    /*
+     * Find syllables until the entire word is constructed.
+     */
+    while (word_length < pwlen)
+    {
+     /*
+      * Get the syllable and find its length.
+      */
+     (void) gen_syllable (new_syllable, pwlen - word_length, syllable_units, &syllable_size);
+     syllable_length = strlen (new_syllable);
+     
+     /*
+      * Append the syllable units to the word units.
+      */
+     for (word_place = 0; word_place <= syllable_size; word_place++)
+         word_units[word_size + word_place] = syllable_units[word_place];
+     word_size += syllable_size + 1;
+
+     /* 
+      * If the word has been improperly formed, throw out
+      * the syllable.  The checks performed here are those
+      * that must be formed on a word basis.  The other
+      * tests are performed entirely within the syllable.
+      * Otherwise, append the syllable to the word and
+      * append the syllable to the hyphenated version of
+      * the word.
+      */
+     if (improper_word (word_units, word_size) ||
+        ((word_length == 0) && have_initial_y (syllable_units, syllable_size)) ||
+        ((word_length + syllable_length == pwlen) && have_final_split (syllable_units, syllable_size)))
+           word_size -= syllable_size + 1;
+     else
+     {
+         if (word_length == 0)
+         {
+          /*
+          ** Modify syllable for numeric or capital symbols required
+          ** Should be done after word quality check. 
+          */
+	  dsd = randint(2);
+          if ( ((pass_mode & S_NB) > 0) && (syllable_length == 1) && dsd == 0)
+            {
+             numerize(new_syllable);
+	     ch_flag = TRUE;
+            }
+          if ( ((pass_mode & S_SS) > 0) && (syllable_length == 1) && (dsd == 1))
+            {
+	      specialize(new_syllable);
+	      ch_flag = TRUE;
+	    }
+          if ( ( (pass_mode & S_CL) > 0) && (ch_flag != TRUE))
+             capitalize(new_syllable);
+          ch_flag = FALSE;
+          /**/
+          (void) strcpy (word, new_syllable);
+	  if (syllable_length == 1)
+	     {
+	      symb2name(new_syllable, syllable_for_hyph);
+              (void) strcpy (hyphenated_word, syllable_for_hyph);
+	     }
+	  else
+	     {
+              (void) strcpy (hyphenated_word, new_syllable);
+	     }
+	  (void)memset ( (void *)new_syllable, 0, (size_t)(pwlen * sizeof(USHORT)+1));
+	  (void)memset ( (void *)syllable_for_hyph, 0, 20);
+         }
+         else
+         {
+          /*
+          ** Modify syllable for numeric or capital symbols required
+          ** Should be done after word quality check.
+          */
+	  dsd = randint(2);
+          if ( ((pass_mode & S_NB) > 0) && (syllable_length == 1) && (dsd == 0))
+            {
+             numerize(new_syllable);
+	     ch_flag = TRUE;
+            }
+          if ( ( (pass_mode & S_SS) > 0) && (syllable_length == 1) && (dsd == 1))
+            {
+	     specialize(new_syllable);
+	     ch_flag = TRUE;
+	    }
+          if ( ( (pass_mode & S_CL) > 0) && (ch_flag != TRUE))
+             capitalize(new_syllable);
+          ch_flag = FALSE;
+          /**/
+          (void) strcat (word, new_syllable);
+          (void) strcat (hyphenated_word, "-");
+	  if (syllable_length == 1)
+	     {
+	      symb2name(new_syllable, syllable_for_hyph);
+              (void) strcat (hyphenated_word, syllable_for_hyph);
+	     }
+	  else
+	     {
+              (void) strcat (hyphenated_word, new_syllable);
+	     }
+	  (void)memset ( (void *)new_syllable, 0, (size_t)(pwlen * sizeof(USHORT)+1));
+	  (void)memset ( (void *)syllable_for_hyph, 0, 20);
+         }
+         word_length += syllable_length;
+     }
+
+       /* 
+        * Keep track of the times we have tried to get
+        * syllables.  If we have exceeded the threshold,
+        * reinitialize the pwlen and word_size variables, clear
+        * out the word arrays, and start from scratch.
+        */
+     tries++;
+     if (tries > MAX_RETRIES)
+     {
+         word_length = 0;
+         word_size = 0;
+         tries = 0;
+         (void) strcpy (word, "");
+         (void) strcpy (hyphenated_word, "");
+     }
+    }
+
+    /* 
+     * The units arrays and syllable storage are internal to this
+     * routine.  Since the caller has no need for them, we
+     * release the space.
+     */
+    free ((char *) new_syllable);
+    free ((char *) syllable_units);
+    free ((char *) word_units);
+    free ((char *) syllable_for_hyph);
+
+    return ((int) word_length);
+}
+
+
+
+/*
+ * Check that the word does not contain illegal combinations
+ * that may span syllables.  Specifically, these are:
+ *   1. An illegal pair of units between syllables.
+ *   2. Three consecutive vowel units.
+ *   3. Three consecutive consonant units.
+ * The checks are made against units (1 or 2 letters), not against
+ * the individual letters, so three consecutive units can have
+ * the length of 6 at most.
+ */
+boolean
+improper_word (USHORT *units, USHORT word_size)
+{
+    USHORT unit_count;
+    boolean failure;
+
+    failure = FALSE;
+
+    for (unit_count = 0; !failure && (unit_count < word_size);
+         unit_count++)
+    {
+     /* 
+      * Check for ILLEGAL_PAIR.  This should have been caught
+      * for units within a syllable, but in some cases it
+      * would have gone unnoticed for units between syllables
+      * (e.g., when saved_unit's in gen_syllable() were not
+      * used).
+      */
+     if ((unit_count != 0) &&
+          (digram[units[unit_count - 1]][units[unit_count]] &
+              ILLEGAL_PAIR))
+         failure = TRUE;
+
+     /* 
+      * Check for consecutive vowels or consonants.  Because
+      * the initial y of a syllable is treated as a consonant
+      * rather than as a vowel, we exclude y from the first
+      * vowel in the vowel test.  The only problem comes when
+      * y ends a syllable and two other vowels start the next,
+      * like fly-oint.  Since such words are still
+      * pronounceable, we accept this.
+      */
+     if (!failure && (unit_count >= 2))
+     {
+         /*
+          * Vowel check.
+          */
+         if ((((rules[units[unit_count - 2]].flags & VOWEL) &&
+                   !(rules[units[unit_count - 2]].flags &
+                    ALTERNATE_VOWEL)) &&
+               (rules[units[unit_count - 1]].flags & VOWEL) &&
+               (rules[units[unit_count]].flags & VOWEL)) ||
+         /*
+          * Consonant check.
+          */
+              (!(rules[units[unit_count - 2]].flags & VOWEL) &&
+               !(rules[units[unit_count - 1]].flags & VOWEL) &&
+               !(rules[units[unit_count]].flags & VOWEL)))
+          failure = TRUE;
+     }
+    }
+
+    return (failure);
+}
+
+
+/*
+ * Treating y as a vowel is sometimes a problem.  Some words
+ * get formed that look irregular.  One special group is when
+ * y starts a word and is the only vowel in the first syllable.
+ * The word ycl is one example.  We discard words like these.
+ */
+boolean
+have_initial_y (USHORT *units, USHORT unit_size)
+{
+    USHORT unit_count;
+    USHORT vowel_count;
+    USHORT normal_vowel_count;
+
+    vowel_count = 0;
+    normal_vowel_count = 0;
+
+    for (unit_count = 0; unit_count <= unit_size; unit_count++)
+     /*
+      * Count vowels.
+      */
+     if (rules[units[unit_count]].flags & VOWEL)
+     {
+         vowel_count++;
+
+         /*
+          * Count the vowels that are not: 1. y, 2. at the start of
+          * the word.
+          */
+         if (!(rules[units[unit_count]].flags & ALTERNATE_VOWEL) ||
+              (unit_count != 0))
+          normal_vowel_count++;
+     }
+
+    return ((vowel_count <= 1) && (normal_vowel_count == 0));
+}
+
+
+/*
+ * Besides the problem with the letter y, there is one with
+ * a silent e at the end of words, like face or nice.  We
+ * allow this silent e, but we do not allow it as the only
+ * vowel at the end of the word or syllables like ble will
+ * be generated.
+ */
+boolean
+have_final_split (USHORT *units, USHORT unit_size)
+{
+    USHORT unit_count;
+    USHORT vowel_count;
+
+    vowel_count = 0;
+
+    /*
+     *    Count all the vowels in the word.
+     */
+    for (unit_count = 0; unit_count <= unit_size; unit_count++)
+     if (rules[units[unit_count]].flags & VOWEL)
+         vowel_count++;
+
+    /*
+     * Return TRUE iff the only vowel was e, found at the end if the
+     * word.
+     */
+    return ((vowel_count == 1) &&
+         (rules[units[unit_size]].flags & NO_FINAL_SPLIT));
+}
+
+
+/*
+ * Generate next unit to password, making sure that it follows
+ * these rules:
+ *   1. Each syllable must contain exactly 1 or 2 consecutive
+ *      vowels, where y is considered a vowel.
+ *   2. Syllable end is determined as follows:
+ *        a. Vowel is generated and previous unit is a
+ *           consonant and syllable already has a vowel.  In
+ *           this case, new syllable is started and already
+ *           contains a vowel.
+ *        b. A pair determined to be a "break" pair is encountered.
+ *           In this case new syllable is started with second unit
+ *           of this pair.
+ *        c. End of password is encountered.
+ *        d. "begin" pair is encountered legally.  New syllable is
+ *           started with this pair.
+ *        e. "end" pair is legally encountered.  New syllable has
+ *           nothing yet.
+ *   3. Try generating another unit if:
+ *        a. third consecutive vowel and not y.
+ *        b. "break" pair generated but no vowel yet in current
+ *           or previous 2 units are "not_end".
+ *        c. "begin" pair generated but no vowel in syllable
+ *           preceding begin pair, or both previous 2 pairs are
+ *          designated "not_end".
+ *        d. "end" pair generated but no vowel in current syllable
+ *           or in "end" pair.
+ *        e. "not_begin" pair generated but new syllable must
+ *           begin (because previous syllable ended as defined in
+ *           2 above).
+ *        f. vowel is generated and 2a is satisfied, but no syllable
+ *           break is possible in previous 3 pairs.
+ *        g. Second and third units of syllable must begin, and
+ *           first unit is "alternate_vowel".
+ */
+char *
+gen_syllable (char *syllable, USHORT pwlen, USHORT *units_in_syllable,
+              USHORT *syllable_length)
+{
+    USHORT  unit = 0;
+    SHORT   current_unit = 0;
+    USHORT  vowel_count = 0;
+    boolean rule_broken;
+    boolean want_vowel;
+    boolean want_another_unit;
+    UINT    tries = 0;
+    USHORT  last_unit = 0;
+    SHORT   length_left = 0;
+    USHORT  hold_saved_unit = 0;
+    static  USHORT saved_unit;
+    static  USHORT saved_pair[2];
+
+    /*
+     * This is needed if the saved_unit is tries and the syllable then
+     * discarded because of the retry limit. Since the saved_unit is OK and
+     * fits in nicely with the preceding syllable, we will always use it.
+     */
+    hold_saved_unit = saved_unit;
+
+    /*
+     * Loop until valid syllable is found.
+     */
+    do
+    {
+     /* 
+      * Try for a new syllable.  Initialize all pertinent
+      * syllable variables.
+      */
+     tries = 0;
+     saved_unit = hold_saved_unit;
+     (void) strcpy (syllable, "");
+     vowel_count = 0;
+     current_unit = 0;
+     length_left = (short int) pwlen;
+     want_another_unit = TRUE;
+
+     /*
+      * This loop finds all the units for the syllable.
+      */
+     do
+     {
+         want_vowel = FALSE;
+
+         /*
+          * This loop continues until a valid unit is found for the
+          * current position within the syllable.
+          */
+         do
+         {
+          /* 
+           * If there are saved_unit's from the previous
+           * syllable, use them up first.
+           */
+          if (saved_unit != 0)
+          {
+              /* 
+               * If there were two saved units, the first is
+               * guaranteed (by checks performed in the previous
+               * syllable) to be valid.  We ignore the checks
+               * and place it in this syllable manually.
+               */
+              if (saved_unit == 2)
+              {
+               units_in_syllable[0] = saved_pair[1];
+               if (rules[saved_pair[1]].flags & VOWEL)
+                   vowel_count++;
+               current_unit++;
+               (void) strcpy (syllable, rules[saved_pair[1]].unit_code);
+               length_left -= strlen (syllable);
+              }
+
+              /* 
+               * The unit becomes the last unit checked in the
+               * previous syllable.
+               */
+              unit = saved_pair[0];
+
+              /*
+               * The saved units have been used.  Do not try to
+               * reuse them in this syllable (unless this particular
+               * syllable is rejected at which point we start to rebuild
+               * it with these same saved units.
+               */
+              saved_unit = 0;
+          }
+          else
+              /* 
+               * If we don't have to scoff the saved units,
+               * we generate a Random one.  If we know it has
+               * to be a vowel, we get one rather than looping
+               * through until one shows up.
+               */
+              if (want_vowel)
+               unit = random_unit (VOWEL);
+              else
+               unit = random_unit (NO_SPECIAL_RULE);
+          length_left -= (short int) strlen (rules[unit].unit_code);
+
+          /*
+           * Prevent having a word longer than expected.
+           */
+          if (length_left < 0)
+              rule_broken = TRUE;
+          else
+              rule_broken = FALSE;
+
+          /*
+           * First unit of syllable.  This is special because the
+           * digram tests require 2 units and we don't have that yet.
+           * Nevertheless, we can perform some checks.
+           */
+          if (current_unit == 0)
+          {
+              /* 
+               * If the shouldn't begin a syllable, don't
+               * use it.
+               */
+              if (rules[unit].flags & NOT_BEGIN_SYLLABLE)
+               rule_broken = TRUE;
+              else
+               /* 
+                * If this is the last unit of a word,
+                * we have a one unit syllable.  Since each
+                * syllable must have a vowel, we make sure
+                * the unit is a vowel.  Otherwise, we
+                * discard it.
+                */
+               if (length_left == 0)
+	          {
+                   if (rules[unit].flags & VOWEL)
+                    want_another_unit = FALSE;
+                   else
+                    rule_broken = TRUE;
+		  }
+          }
+          else
+          {
+              /* 
+               * There are some digram tests that are
+               * universally true.  We test them out.
+               */
+
+              /*
+               * Reject ILLEGAL_PAIRS of units.
+               */
+              if ((ALLOWED (ILLEGAL_PAIR)) ||
+
+              /*
+               * Reject units that will be split between syllables
+               * when the syllable has no vowels in it.
+               */
+                   (ALLOWED (BREAK) && (vowel_count == 0)) ||
+
+              /*
+               * Reject a unit that will end a syllable when no
+               * previous unit was a vowel and neither is this one.
+               */
+                   (ALLOWED (END) && (vowel_count == 0) &&
+                    !(rules[unit].flags & VOWEL)))
+               rule_broken = TRUE;
+
+              if (current_unit == 1)
+              {
+               /*
+                * Reject the unit if we are at te starting digram of
+                * a syllable and it does not fit.
+                */
+               if (ALLOWED (NOT_BEGIN))
+                   rule_broken = TRUE;
+              }
+              else
+              {
+               /* 
+                * We are not at the start of a syllable.
+                * Save the previous unit for later tests.
+                */
+               last_unit = units_in_syllable[current_unit - 1];
+
+               /*
+                * Do not allow syllables where the first letter is y
+                * and the next pair can begin a syllable.  This may
+                * lead to splits where y is left alone in a syllable.
+                * Also, the combination does not sound to good even
+                * if not split.
+                */
+               if (((current_unit == 2) &&
+                        (ALLOWED (BEGIN)) &&
+                        (rules[units_in_syllable[0]].flags &
+                         ALTERNATE_VOWEL)) ||
+
+                    /*
+                     * If this is the last unit of a word, we should
+                     * reject any digram that cannot end a syllable.
+                     */
+                    (ALLOWED (NOT_END) &&
+                        (length_left == 0)) ||
+
+                    /*
+                     * Reject the unit if the digram it forms wants
+                     * to break the syllable, but the resulting
+                     * digram that would end the syllable is not
+                     * allowed to end a syllable.
+                     */
+                    (ALLOWED (BREAK) &&
+                        (digram[units_in_syllable
+                             [current_unit - 2]]
+                         [last_unit] &
+                         NOT_END)) ||
+
+                    /*
+                     * Reject the unit if the digram it forms
+                     * expects a vowel preceding it and there is
+                     * none.
+                     */
+                    (ALLOWED (PREFIX) &&
+                        !(rules[units_in_syllable
+                             [current_unit - 2]].flags &
+                         VOWEL)))
+                   rule_broken = TRUE;
+
+               /*
+                * The following checks occur when the current unit
+                * is a vowel and we are not looking at a word ending
+                * with an e.
+                */
+               if (!rule_broken &&
+                    (rules[unit].flags & VOWEL) &&
+                    ((length_left > 0) ||
+                        !(rules[last_unit].flags &
+                         NO_FINAL_SPLIT)))
+                  {
+                   /*
+                    * Don't allow 3 consecutive vowels in a
+                    * syllable.  Although some words formed like this
+                    * are OK, like beau, most are not.
+                    */
+                   if ((vowel_count > 1) &&
+                        (rules[last_unit].flags & VOWEL))
+                    rule_broken = TRUE;
+                   else
+                    /*
+                     * Check for the case of
+                     * vowels-consonants-vowel, which is only
+                     * legal if the last vowel is an e and we are
+                     * the end of the word (wich is not
+                     * happening here due to a previous check.
+                     */
+                    if ((vowel_count != 0) &&
+                         !(rules[last_unit].flags & VOWEL))
+                    {
+                        /*
+                         * Try to save the vowel for the next
+                         * syllable, but if the syllable left here
+                         * is not proper (i.e., the resulting last
+                         * digram cannot legally end it), just
+                         * discard it and try for another.   
+                         */
+                        if (digram[units_in_syllable
+                              [current_unit - 2]]
+                             [last_unit] &
+                             NOT_END)
+                         rule_broken = TRUE;
+                        else
+                        {
+                         saved_unit = 1;
+                         saved_pair[0] = unit;
+                         want_another_unit = FALSE;
+                        }
+                    }
+		  }
+              }
+
+              /*
+               * The unit picked and the digram formed are legal.
+               * We now determine if we can end the syllable.  It may,
+               * in some cases, mean the last unit(s) may be deferred to
+               * the next syllable.  We also check here to see if the
+               * digram formed expects a vowel to follow.
+               */
+              if (!rule_broken && want_another_unit)
+              {
+               /*
+                * This word ends in a silent e.
+                */
+/******/        if (((vowel_count != 0) &&
+                     (rules[unit].flags & NO_FINAL_SPLIT) &&
+                     (length_left == 0) &&
+                    !(rules[last_unit].flags & VOWEL)) ||
+
+                    /*
+                     * This syllable ends either because the digram
+                     * is an END pair or we would otherwise exceed
+                     * the length of the word.
+                     */
+                    (ALLOWED (END) || (length_left == 0)))
+		   {
+                   want_another_unit = FALSE;
+		   }
+	       else
+                   /*
+                    * Since we have a vowel in the syllable
+                    * already, if the digram calls for the end of the
+                    * syllable, we can legally split it off. We also
+                    * make sure that we are not at the end of the
+                    * dangerous because that syllable may not have
+                    * vowels, or it may not be a legal syllable end,
+                    * and the retrying mechanism will loop infinitely
+                    * with the same digram.
+                    */
+                   if ((vowel_count != 0) && (length_left > 0))
+                   {
+                    /*
+                     * If we must begin a syllable, we do so if
+                     * the only vowel in THIS syllable is not part
+                     * of the digram we are pushing to the next
+                     * syllable.
+                     */
+                    if (ALLOWED (BEGIN) &&
+                         (current_unit > 1) &&
+                         !((vowel_count == 1) &&
+                         (rules[last_unit].flags & VOWEL)))
+                    {
+                        saved_unit = 2;
+                        saved_pair[0] = unit;
+                        saved_pair[1] = last_unit;
+                        want_another_unit = FALSE;
+                    }
+                    else
+                        if (ALLOWED (BREAK))
+                        {
+                         saved_unit = 1;
+                         saved_pair[0] = unit;
+                         want_another_unit = FALSE;
+                        }
+                   }
+                   else
+                    if (ALLOWED (SUFFIX))
+		     {
+                        want_vowel = TRUE;
+		     }
+              }
+          }
+/********/
+          tries++;
+
+          /*
+           * If this unit was illegal, redetermine the amount of
+           * letters left to go in the word.
+           */
+          if (rule_broken)
+              length_left += (short int) strlen (rules[unit].unit_code);
+         }
+         while (rule_broken && (tries <= MAX_RETRIES));
+
+         /*
+          * The unit fit OK.
+          */
+         if (tries <= MAX_RETRIES)
+         {
+          /* 
+           * If the unit were a vowel, count it in.
+           * However, if the unit were a y and appear
+           * at the start of the syllable, treat it
+           * like a constant (so that words like year can
+           * appear and not conflict with the 3 consecutive
+           * vowel rule.
+           */
+          if ((rules[unit].flags & VOWEL) &&
+               ((current_unit > 0) ||
+                   !(rules[unit].flags & ALTERNATE_VOWEL)))
+              vowel_count++;
+
+          /* 
+           * If a unit or units were to be saved, we must
+           * adjust the syllable formed.  Otherwise, we
+           * append the current unit to the syllable.
+           */
+          switch (saved_unit)
+          {
+              case 0: 
+               units_in_syllable[current_unit] = unit;
+               (void) strcat (syllable, rules[unit].unit_code);
+               break;
+              case 1: 
+               current_unit--;
+               break;
+              case 2: 
+               (void) strcpy (&syllable[strlen (syllable) -
+                        strlen (rules[last_unit].unit_code)],"");
+               length_left += (short int) strlen (rules[last_unit].unit_code);
+               current_unit -= 2;
+               break;
+          }
+         }
+         else
+         /*
+          * Whoops!  Too many tries.  We set rule_broken so we can
+          * loop in the outer loop and try another syllable.
+          */
+          rule_broken = TRUE;
+
+         /*
+          * ...and the syllable length grows.
+          */
+         *syllable_length = current_unit;
+
+         current_unit++;
+     }
+     while ((tries <= MAX_RETRIES) && want_another_unit);
+    }
+    while (rule_broken ||
+           illegal_placement (units_in_syllable, *syllable_length));
+
+    return (syllable);
+}
+
+
+/*
+ * This routine goes through an individual syllable and checks
+ * for illegal combinations of letters that go beyond looking
+ * at digrams.  We look at things like 3 consecutive vowels or
+ * consonants, or syllables with consonants between vowels (unless
+ * one of them is the final silent e).
+ */
+boolean
+illegal_placement (USHORT *units, USHORT pwlen)
+{
+    USHORT vowel_count;
+    USHORT unit_count;
+    boolean failure;
+
+    vowel_count = 0;
+    failure = FALSE;
+
+    for (unit_count = 0; !failure && (unit_count <= pwlen);
+         unit_count++)
+    {
+     if (unit_count >= 1)
+     {
+         /* 
+          * Don't allow vowels to be split with consonants in
+          * a single syllable.  If we find such a combination
+          * (except for the silent e) we have to discard the
+          * syllable).
+          */
+         if ((!(rules[units[unit_count - 1]].flags & VOWEL) &&
+               (rules[units[unit_count]].flags & VOWEL) &&
+               !((rules[units[unit_count]].flags & NO_FINAL_SPLIT) &&
+                   (unit_count == pwlen)) && (vowel_count != 0)) ||
+         /*
+          * Perform these checks when we have at least 3 units.
+          */
+              ((unit_count >= 2) &&
+
+                  /*
+                   * Disallow 3 consecutive consonants.
+                   */
+               ((!(rules[units[unit_count - 2]].flags & VOWEL) &&
+                    !(rules[units[unit_count - 1]].flags &
+                        VOWEL) &&
+                    !(rules[units[unit_count]].flags &
+                        VOWEL)) ||
+
+                   /*
+                    * Disallow 3 consecutive vowels, where the first is
+                    * not a y.
+                    */
+                   (((rules[units[unit_count - 2]].flags &
+                         VOWEL) &&
+                        !((rules[units[0]].flags &
+                             ALTERNATE_VOWEL) &&
+                         (unit_count == 2))) &&
+                    (rules[units[unit_count - 1]].flags &
+                        VOWEL) &&
+                    (rules[units[unit_count]].flags &
+                        VOWEL)))))
+          failure = TRUE;
+     }
+
+     /* 
+      * Count the vowels in the syllable.  As mentioned somewhere
+      * above, exclude the initial y of a syllable.  Instead,
+      * treat it as a consonant.
+      */
+     if ((rules[units[unit_count]].flags & VOWEL) &&
+          !((rules[units[0]].flags & ALTERNATE_VOWEL) &&
+              (unit_count == 0) && (pwlen != 0)))
+         vowel_count++;
+    }
+
+    return (failure);
+}
+
+
+
+/*
+ * This is the standard Random unit generating routine for
+ * gen_syllable().  It does not reference the digrams, but
+ * assumes that it contains 34 units in a particular order.
+ * This routine attempts to return unit indexes with a distribution
+ * approaching that of the distribution of the 34 units in
+ * English.  In order to do this, a Random number (supposedly
+ * uniformly distributed) is used to do a table lookup into an
+ * array containing unit indices.  There are 211 entries in
+ * the array for the random_unit entry point.  The probability
+ * of a particular unit being generated is equal to the
+ * fraction of those 211 entries that contain that unit index.
+ * For example, the letter `a' is unit number 1.  Since unit
+ * index 1 appears 10 times in the array, the probability of
+ * selecting an `a' is 10/211.
+ *
+ * Changes may be made to the digram table without affect to this
+ * procedure providing the letter-to-number correspondence of
+ * the units does not change.  Likewise, the distribution of the
+ * 34 units may be altered (and the array size may be changed)
+ * in this procedure without affecting the digram table or any other
+ * programs using the Random_word subroutine.
+ */
+static USHORT numbers[] =
+{
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    1, 1, 1, 1, 1, 1, 1, 1,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+    5, 5, 5, 5, 5, 5, 5, 5,
+    6, 6, 6, 6, 6, 6, 6, 6,
+    7, 7, 7, 7, 7, 7,
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+    9, 9, 9, 9, 9, 9, 9, 9,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    11, 11, 11, 11, 11, 11,
+    12, 12, 12, 12, 12, 12,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    15, 15, 15, 15, 15, 15,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    17, 17, 17, 17, 17, 17, 17, 17,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    19, 19, 19, 19, 19, 19,
+    20, 20, 20, 20, 20, 20, 20, 20,
+    21, 21, 21, 21, 21, 21, 21, 21,
+    22,
+    23, 23, 23, 23, 23, 23, 23, 23,
+    24,
+    25,
+    26,
+    27,
+    28,
+    29, 29,
+    30,
+    31,
+    32,
+    33
+};
+
+
+/*
+ * This structure has a typical English frequency of vowels.
+ * The value of an entry is the vowel position (a=0, e=4, i=8,
+ * o=14, u=19, y=23) in the rules array.  The number of times
+ * the value appears is the frequency.  Thus, the letter "a"
+ * is assumed to appear 2/12 = 1/6 of the time.  This array
+ * may be altered if better data is obtained.  The routines that
+ * use vowel_numbers will adjust to the size difference
+automatically.
+ */
+static USHORT vowel_numbers[] =
+{
+    0, 0, 4, 4, 4, 8, 8, 14, 14, 19, 19, 23
+};
+
+
+/*
+ * Select a unit (a letter or a consonant group).  If a vowel is
+ * expected, use the vowel_numbers array rather than looping through
+ * the numbers array until a vowel is found.
+ */
+USHORT
+random_unit (USHORT type)
+{
+     USHORT number;
+
+    /* 
+     * Sometimes, we are asked to explicitly get a vowel (i.e., if
+     * a digram pair expects one following it).  This is a shortcut
+     * to do that and avoid looping with rejected consonants.
+     */
+    if (type & VOWEL)
+     number = vowel_numbers[get_random (0, (sizeof (vowel_numbers) / sizeof (USHORT))-1)];
+    else
+     /* 
+      * Get any letter according to the English distribution.
+      */
+     number = numbers[get_random (0, (sizeof (numbers) / sizeof (USHORT))-1)];
+    return (number);
+}
+
+
+/*
+** get_random() -
+** This routine should return a uniformly distributed Random number between
+** minlen and maxlen inclusive.  The Electronic Code Book form of CAST is
+** used to produce the Random number.  The inputs to CAST are the old pass-
+** word and a pseudoRandom key generated according to the procedure out-
+** lined in Appendix C of ANSI X9.17.
+** INPUT:
+**   USHORT - minimum
+**   USHORT - maximum
+** OUTPUT:
+**   USHORT - random number
+** NOTES:
+**   none.
+*/
+
+USHORT
+get_random (USHORT minlen, USHORT maxlen)
+{
+ USHORT ret = 0;
+ ret = minlen + (USHORT) randint ((int) (maxlen - minlen + 1));
+ return (ret);
+}
diff --git a/third_party/fips181/fips181.gyp b/third_party/fips181/fips181.gyp
new file mode 100644
index 0000000..e47a890
--- /dev/null
+++ b/third_party/fips181/fips181.gyp
@@ -0,0 +1,24 @@
+# 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.
+
+{
+  'targets': [
+    {
+      'target_name': 'fips181',
+      'type': 'static_library',
+      'include_dirs': [
+        '.',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [
+          '.',
+        ],
+      },
+      'sources': [
+        'fips181.cc',
+        'fips181.h',
+      ],
+    },
+  ],
+}
diff --git a/third_party/fips181/fips181.h b/third_party/fips181/fips181.h
new file mode 100644
index 0000000..bc9270b
--- /dev/null
+++ b/third_party/fips181/fips181.h
@@ -0,0 +1,84 @@
+/*
+** This module uses code from the NIST implementation of  FIPS-181,
+** but the algorythm is CHANGED and I think that I CAN
+** copyright it. See copiright notes below.
+*/
+
+/*
+** Copyright (c) 1999, 2000, 2001, 2002, 2003
+** Adel I. Mirzazhanov. All rights reserved
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions
+** are met:
+** 
+**     1.Redistributions of source code must retain the above copyright notice,
+**       this list of conditions and the following disclaimer. 
+**     2.Redistributions in binary form must reproduce the above copyright
+**       notice, this list of conditions and the following disclaimer in the
+**       documentation and/or other materials provided with the distribution. 
+**     3.The name of the author may not be used to endorse or promote products
+**       derived from this software without specific prior written permission. 
+** 		  
+** THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND ANY EXPRESS
+** OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED.  IN  NO  EVENT  SHALL THE AUTHOR BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+** DAMAGES (INCLUDING, BUT NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE
+** GOODS OR SERVICES;  LOSS OF USE,  DATA,  OR  PROFITS;  OR BUSINESS
+** INTERRUPTION)  HOWEVER  CAUSED  AND  ON  ANY  THEORY OF LIABILITY,
+** WHETHER  IN  CONTRACT,   STRICT   LIABILITY,  OR  TORT  (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef APG_PRONPASS_H
+#define APG_PRONPASS_H	1
+
+#ifndef APG_OWN_TYPES_H
+#include "owntypes.h"
+#endif /* APG_OWN_TYPES_H */
+
+#ifndef APG_RND_H
+#include "rnd.h"
+#endif /* APG_RND_H */
+
+#define RULE_SIZE             (sizeof(rules)/sizeof(struct unit))
+#define ALLOWED(flag)         (digram[units_in_syllable[current_unit -1]][unit] & (flag))
+
+#define MAX_UNACCEPTABLE      20
+#define MAX_RETRIES           (4 * (int) pwlen + RULE_SIZE)
+
+#define NOT_BEGIN_SYLLABLE    010
+#define NO_FINAL_SPLIT        04
+#define VOWEL                 02
+#define ALTERNATE_VOWEL       01
+#define NO_SPECIAL_RULE       0
+
+#define BEGIN                 0200
+#define NOT_BEGIN             0100
+#define BREAK                 040
+#define PREFIX                020
+#define ILLEGAL_PAIR          010
+#define SUFFIX                04
+#define END                   02
+#define NOT_END               01
+#define ANY_COMBINATION       0
+
+extern int gen_pron_pass (char *word, char *hyphenated_word, USHORT minlen,
+               USHORT maxlen, unsigned int pass_mode);
+
+USHORT  random_unit (USHORT type);
+USHORT  get_random (USHORT minlen, USHORT maxlen);
+boolean have_initial_y (USHORT *units, USHORT unit_size);
+boolean illegal_placement (USHORT *units, USHORT pwlen);
+boolean improper_word (USHORT *units, USHORT word_size);
+boolean have_final_split (USHORT *units, USHORT unit_size);
+int gen_word (char *word, char *hyphenated_word, USHORT pwlen,
+              unsigned int pass_mode);
+char   	*gen_syllable(char *syllable, USHORT pwlen, USHORT *units_in_syllable,
+                      USHORT *syllable_length);
+
+#endif /* APG_PRONPASS_H */
diff --git a/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-arm.mk b/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-arm.mk
index f82ebb6..1730ed0 100644
--- a/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-arm.mk
+++ b/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-arm.mk
@@ -70,7 +70,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -165,7 +164,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-x86.mk b/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-x86.mk
index 0cf3898..09ef7ea 100644
--- a/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-x86.mk
+++ b/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-x86.mk
@@ -72,7 +72,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -167,7 +166,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-x86_64.mk b/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-x86_64.mk
index 5bc524c..c8ae047 100644
--- a/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-x86_64.mk
+++ b/third_party/harfbuzz-ng/harfbuzz-ng.target.darwin-x86_64.mk
@@ -72,7 +72,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -167,7 +166,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-arm.mk b/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-arm.mk
index f82ebb6..1730ed0 100644
--- a/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-arm.mk
+++ b/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-arm.mk
@@ -70,7 +70,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -165,7 +164,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-x86.mk b/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-x86.mk
index 0cf3898..09ef7ea 100644
--- a/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-x86.mk
+++ b/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-x86.mk
@@ -72,7 +72,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -167,7 +166,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-x86_64.mk b/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-x86_64.mk
index 5bc524c..c8ae047 100644
--- a/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-x86_64.mk
+++ b/third_party/harfbuzz-ng/harfbuzz-ng.target.linux-x86_64.mk
@@ -72,7 +72,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -167,7 +166,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/hwcplus/include/android/log.h b/third_party/hwcplus/include/android/log.h
new file mode 100644
index 0000000..0ea4c29
--- /dev/null
+++ b/third_party/hwcplus/include/android/log.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_LOG_H
+#define _ANDROID_LOG_H
+
+/******************************************************************
+ *
+ * IMPORTANT NOTICE:
+ *
+ *   This file is part of Android's set of stable system headers
+ *   exposed by the Android NDK (Native Development Kit) since
+ *   platform release 1.5
+ *
+ *   Third-party source AND binary code relies on the definitions
+ *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
+ *
+ *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
+ *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
+ *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
+ *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
+ */
+
+/*
+ * Support routines to send messages to the Android in-kernel log buffer,
+ * which can later be accessed through the 'logcat' utility.
+ *
+ * Each log message must have
+ *   - a priority
+ *   - a log tag
+ *   - some text
+ *
+ * The tag normally corresponds to the component that emits the log message,
+ * and should be reasonably small.
+ *
+ * Log message text may be truncated to less than an implementation-specific
+ * limit (e.g. 1023 characters max).
+ *
+ * Note that a newline character ("\n") will be appended automatically to your
+ * log message, if not already there. It is not possible to send several messages
+ * and have them appear on a single line in logcat.
+ *
+ * PLEASE USE LOGS WITH MODERATION:
+ *
+ *  - Sending log messages eats CPU and slow down your application and the
+ *    system.
+ *
+ *  - The circular log buffer is pretty small (<64KB), sending many messages
+ *    might push off other important log messages from the rest of the system.
+ *
+ *  - In release builds, only send log messages to account for exceptional
+ *    conditions.
+ *
+ * NOTE: These functions MUST be implemented by /system/lib/liblog.so
+ */
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Android log priority values, in ascending priority order.
+ */
+typedef enum android_LogPriority {
+    ANDROID_LOG_UNKNOWN = 0,
+    ANDROID_LOG_DEFAULT,    /* only for SetMinPriority() */
+    ANDROID_LOG_VERBOSE,
+    ANDROID_LOG_DEBUG,
+    ANDROID_LOG_INFO,
+    ANDROID_LOG_WARN,
+    ANDROID_LOG_ERROR,
+    ANDROID_LOG_FATAL,
+    ANDROID_LOG_SILENT,     /* only for SetMinPriority(); must be last */
+} android_LogPriority;
+
+/*
+ * Send a simple string to the log.
+ */
+int __android_log_write(int prio, const char *tag, const char *text);
+
+/*
+ * Send a formatted string to the log, used like printf(fmt,...)
+ */
+int __android_log_print(int prio, const char *tag,  const char *fmt, ...)
+#if defined(__GNUC__)
+    __attribute__ ((format(printf, 3, 4)))
+#endif
+    ;
+
+/*
+ * A variant of __android_log_print() that takes a va_list to list
+ * additional parameters.
+ */
+int __android_log_vprint(int prio, const char *tag,
+                         const char *fmt, va_list ap);
+
+/*
+ * Log an assertion failure and SIGTRAP the process to have a chance
+ * to inspect it, if a debugger is attached. This uses the FATAL priority.
+ */
+void __android_log_assert(const char *cond, const char *tag,
+			  const char *fmt, ...)    
+#if defined(__GNUC__)
+    __attribute__ ((noreturn))
+    __attribute__ ((format(printf, 3, 4)))
+#endif
+    ;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ANDROID_LOG_H */
diff --git a/third_party/hwcplus/include/cutils/properties.h b/third_party/hwcplus/include/cutils/properties.h
new file mode 100644
index 0000000..66a9c5b
--- /dev/null
+++ b/third_party/hwcplus/include/cutils/properties.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CUTILS_PROPERTIES_H
+#define __CUTILS_PROPERTIES_H
+
+#include <sys/cdefs.h>
+#include <stddef.h>
+#ifdef ANDROID
+#include <sys/system_properties.h>
+#else
+#ifndef PROP_NAME_MAX
+#define PROP_NAME_MAX  32
+#endif
+#ifndef PROP_VALUE_MAX
+#define PROP_VALUE_MAX  92
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* System properties are *small* name value pairs managed by the
+** property service.  If your data doesn't fit in the provided
+** space it is not appropriate for a system property.
+**
+** WARNING: system/bionic/include/sys/system_properties.h also defines
+**          these, but with different names.  (TODO: fix that)
+*/
+#define PROPERTY_KEY_MAX   PROP_NAME_MAX
+#define PROPERTY_VALUE_MAX  PROP_VALUE_MAX
+
+/* property_get: returns the length of the value which will never be
+** greater than PROPERTY_VALUE_MAX - 1 and will always be zero terminated.
+** (the length does not include the terminating zero).
+**
+** If the property read fails or returns an empty value, the default
+** value is used (if nonnull).
+*/
+int property_get(const char *key, char *value, const char *default_value);
+
+/* property_set: returns 0 on success, < 0 on failure
+*/
+int property_set(const char *key, const char *value);
+    
+int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie);    
+
+#if defined(__BIONIC_FORTIFY)
+
+extern int __property_get_real(const char *, char *, const char *)
+    __asm__(__USER_LABEL_PREFIX__ "property_get");
+__errordecl(__property_get_too_small_error, "property_get() called with too small of a buffer");
+
+__BIONIC_FORTIFY_INLINE
+int property_get(const char *key, char *value, const char *default_value) {
+    size_t bos = __bos(value);
+    if (bos < PROPERTY_VALUE_MAX) {
+        __property_get_too_small_error();
+    }
+    return __property_get_real(key, value, default_value);
+}
+
+#endif
+
+#ifdef HAVE_SYSTEM_PROPERTY_SERVER
+/*
+ * We have an external property server instead of built-in libc support.
+ * Used by the simulator.
+ */
+#define SYSTEM_PROPERTY_PIPE_NAME       "/tmp/android-sysprop"
+
+enum {
+    kSystemPropertyUnknown = 0,
+    kSystemPropertyGet,
+    kSystemPropertySet,
+    kSystemPropertyList
+};
+#endif /*HAVE_SYSTEM_PROPERTY_SERVER*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/third_party/hwcplus/include/hardware/hardware.h b/third_party/hwcplus/include/hardware/hardware.h
index 416ae39..9466537 100644
--- a/third_party/hwcplus/include/hardware/hardware.h
+++ b/third_party/hwcplus/include/hardware/hardware.h
@@ -225,6 +225,12 @@
 int hw_get_module_by_class(const char *class_id, const char *inst,
                            const struct hw_module_t **module);
 
+/**
+ * Provide a function to handle log messages.
+ */
+typedef int (*hwcplus_log_fn_t)(int prio, const char* tag, const char* msg);
+void hwcplus_set_log_fn(hwcplus_log_fn_t fn);
+
 __END_DECLS
 
 #endif  /* ANDROID_INCLUDE_HARDWARE_HARDWARE_H */
diff --git a/third_party/hwcplus/include/log/log.h b/third_party/hwcplus/include/log/log.h
new file mode 100644
index 0000000..4677ed4
--- /dev/null
+++ b/third_party/hwcplus/include/log/log.h
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// C/C++ logging functions.  See the logging documentation for API details.
+//
+// We'd like these to be available from C code (in case we import some from
+// somewhere), so this has a C interface.
+//
+// The output will be correct when the log file is shared between multiple
+// threads and/or multiple processes so long as the operating system
+// supports O_APPEND.  These calls have mutex-protected data structures
+// and so are NOT reentrant.  Do not use LOG in a signal handler.
+//
+#ifndef _LIBS_LOG_LOG_H
+#define _LIBS_LOG_LOG_H
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#ifdef HAVE_PTHREADS
+#include <pthread.h>
+#endif
+#include <stdarg.h>
+
+#ifdef ANDROID
+#include <log/uio.h>
+#include <log/logd.h>
+#else
+#include <android/log.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------------------------------------------------------------
+
+/*
+ * Normally we strip ALOGV (VERBOSE messages) from release builds.
+ * You can modify this (for example with "#define LOG_NDEBUG 0"
+ * at the top of your source file) to change that behavior.
+ */
+#ifndef LOG_NDEBUG
+#ifdef NDEBUG
+#define LOG_NDEBUG 1
+#else
+#define LOG_NDEBUG 0
+#endif
+#endif
+
+/*
+ * This is the local tag used for the following simplified
+ * logging macros.  You can change this preprocessor definition
+ * before using the other macros to change the tag.
+ */
+#ifndef LOG_TAG
+#define LOG_TAG NULL
+#endif
+
+// ---------------------------------------------------------------------
+
+/*
+ * Simplified macro to send a verbose log message using the current LOG_TAG.
+ */
+#ifndef ALOGV
+#if LOG_NDEBUG
+#define ALOGV(...)   ((void)0)
+#else
+#define ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
+#endif
+#endif
+
+#define CONDITION(cond)     (__builtin_expect((cond)!=0, 0))
+
+#ifndef ALOGV_IF
+#if LOG_NDEBUG
+#define ALOGV_IF(cond, ...)   ((void)0)
+#else
+#define ALOGV_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+#endif
+
+/*
+ * Simplified macro to send a debug log message using the current LOG_TAG.
+ */
+#ifndef ALOGD
+#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef ALOGD_IF
+#define ALOGD_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an info log message using the current LOG_TAG.
+ */
+#ifndef ALOGI
+#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef ALOGI_IF
+#define ALOGI_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send a warning log message using the current LOG_TAG.
+ */
+#ifndef ALOGW
+#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef ALOGW_IF
+#define ALOGW_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an error log message using the current LOG_TAG.
+ */
+#ifndef ALOGE
+#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef ALOGE_IF
+#define ALOGE_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+// ---------------------------------------------------------------------
+
+/*
+ * Conditional based on whether the current LOG_TAG is enabled at
+ * verbose priority.
+ */
+#ifndef IF_ALOGV
+#if LOG_NDEBUG
+#define IF_ALOGV() if (false)
+#else
+#define IF_ALOGV() IF_ALOG(LOG_VERBOSE, LOG_TAG)
+#endif
+#endif
+
+/*
+ * Conditional based on whether the current LOG_TAG is enabled at
+ * debug priority.
+ */
+#ifndef IF_ALOGD
+#define IF_ALOGD() IF_ALOG(LOG_DEBUG, LOG_TAG)
+#endif
+
+/*
+ * Conditional based on whether the current LOG_TAG is enabled at
+ * info priority.
+ */
+#ifndef IF_ALOGI
+#define IF_ALOGI() IF_ALOG(LOG_INFO, LOG_TAG)
+#endif
+
+/*
+ * Conditional based on whether the current LOG_TAG is enabled at
+ * warn priority.
+ */
+#ifndef IF_ALOGW
+#define IF_ALOGW() IF_ALOG(LOG_WARN, LOG_TAG)
+#endif
+
+/*
+ * Conditional based on whether the current LOG_TAG is enabled at
+ * error priority.
+ */
+#ifndef IF_ALOGE
+#define IF_ALOGE() IF_ALOG(LOG_ERROR, LOG_TAG)
+#endif
+
+
+// ---------------------------------------------------------------------
+
+/*
+ * Simplified macro to send a verbose system log message using the current LOG_TAG.
+ */
+#ifndef SLOGV
+#if LOG_NDEBUG
+#define SLOGV(...)   ((void)0)
+#else
+#define SLOGV(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
+#endif
+#endif
+
+#define CONDITION(cond)     (__builtin_expect((cond)!=0, 0))
+
+#ifndef SLOGV_IF
+#if LOG_NDEBUG
+#define SLOGV_IF(cond, ...)   ((void)0)
+#else
+#define SLOGV_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+#endif
+
+/*
+ * Simplified macro to send a debug system log message using the current LOG_TAG.
+ */
+#ifndef SLOGD
+#define SLOGD(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef SLOGD_IF
+#define SLOGD_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an info system log message using the current LOG_TAG.
+ */
+#ifndef SLOGI
+#define SLOGI(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef SLOGI_IF
+#define SLOGI_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send a warning system log message using the current LOG_TAG.
+ */
+#ifndef SLOGW
+#define SLOGW(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef SLOGW_IF
+#define SLOGW_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an error system log message using the current LOG_TAG.
+ */
+#ifndef SLOGE
+#define SLOGE(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef SLOGE_IF
+#define SLOGE_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+// ---------------------------------------------------------------------
+
+/*
+ * Simplified macro to send a verbose radio log message using the current LOG_TAG.
+ */
+#ifndef RLOGV
+#if LOG_NDEBUG
+#define RLOGV(...)   ((void)0)
+#else
+#define RLOGV(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
+#endif
+#endif
+
+#define CONDITION(cond)     (__builtin_expect((cond)!=0, 0))
+
+#ifndef RLOGV_IF
+#if LOG_NDEBUG
+#define RLOGV_IF(cond, ...)   ((void)0)
+#else
+#define RLOGV_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+#endif
+
+/*
+ * Simplified macro to send a debug radio log message using the current LOG_TAG.
+ */
+#ifndef RLOGD
+#define RLOGD(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef RLOGD_IF
+#define RLOGD_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an info radio log message using the current LOG_TAG.
+ */
+#ifndef RLOGI
+#define RLOGI(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef RLOGI_IF
+#define RLOGI_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send a warning radio log message using the current LOG_TAG.
+ */
+#ifndef RLOGW
+#define RLOGW(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef RLOGW_IF
+#define RLOGW_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an error radio log message using the current LOG_TAG.
+ */
+#ifndef RLOGE
+#define RLOGE(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef RLOGE_IF
+#define RLOGE_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+
+// ---------------------------------------------------------------------
+
+/*
+ * Log a fatal error.  If the given condition fails, this stops program
+ * execution like a normal assertion, but also generating the given message.
+ * It is NOT stripped from release builds.  Note that the condition test
+ * is -inverted- from the normal assert() semantics.
+ */
+#ifndef LOG_ALWAYS_FATAL_IF
+#define LOG_ALWAYS_FATAL_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)android_printAssert(#cond, LOG_TAG, ## __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+#ifndef LOG_ALWAYS_FATAL
+#define LOG_ALWAYS_FATAL(...) \
+    ( ((void)android_printAssert(NULL, LOG_TAG, ## __VA_ARGS__)) )
+#endif
+
+/*
+ * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that
+ * are stripped out of release builds.
+ */
+#if LOG_NDEBUG
+
+#ifndef LOG_FATAL_IF
+#define LOG_FATAL_IF(cond, ...) ((void)0)
+#endif
+#ifndef LOG_FATAL
+#define LOG_FATAL(...) ((void)0)
+#endif
+
+#else
+
+#ifndef LOG_FATAL_IF
+#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__)
+#endif
+#ifndef LOG_FATAL
+#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
+#endif
+
+#endif
+
+/*
+ * Assertion that generates a log message when the assertion fails.
+ * Stripped out of release builds.  Uses the current LOG_TAG.
+ */
+#ifndef ALOG_ASSERT
+#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__)
+//#define ALOG_ASSERT(cond) LOG_FATAL_IF(!(cond), "Assertion failed: " #cond)
+#endif
+
+// ---------------------------------------------------------------------
+
+/*
+ * Basic log message macro.
+ *
+ * Example:
+ *  ALOG(LOG_WARN, NULL, "Failed with error %d", errno);
+ *
+ * The second argument may be NULL or "" to indicate the "global" tag.
+ */
+#ifndef ALOG
+#define ALOG(priority, tag, ...) \
+    LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
+#endif
+
+/*
+ * Log macro that allows you to specify a number for the priority.
+ */
+#ifndef LOG_PRI
+#define LOG_PRI(priority, tag, ...) \
+    android_printLog(priority, tag, __VA_ARGS__)
+#endif
+
+/*
+ * Log macro that allows you to pass in a varargs ("args" is a va_list).
+ */
+#ifndef LOG_PRI_VA
+#define LOG_PRI_VA(priority, tag, fmt, args) \
+    android_vprintLog(priority, NULL, tag, fmt, args)
+#endif
+
+/*
+ * Conditional given a desired logging priority and tag.
+ */
+#ifndef IF_ALOG
+#define IF_ALOG(priority, tag) \
+    if (android_testLog(ANDROID_##priority, tag))
+#endif
+
+// ---------------------------------------------------------------------
+
+/*
+ * Event logging.
+ */
+
+/*
+ * Event log entry types.  These must match up with the declarations in
+ * java/android/android/util/EventLog.java.
+ */
+typedef enum {
+    EVENT_TYPE_INT      = 0,
+    EVENT_TYPE_LONG     = 1,
+    EVENT_TYPE_STRING   = 2,
+    EVENT_TYPE_LIST     = 3,
+} AndroidEventLogType;
+
+
+#ifndef LOG_EVENT_INT
+#define LOG_EVENT_INT(_tag, _value) {                                       \
+        int intBuf = _value;                                                \
+        (void) android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf,            \
+            sizeof(intBuf));                                                \
+    }
+#endif
+#ifndef LOG_EVENT_LONG
+#define LOG_EVENT_LONG(_tag, _value) {                                      \
+        long long longBuf = _value;                                         \
+        (void) android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf,          \
+            sizeof(longBuf));                                               \
+    }
+#endif
+#ifndef LOG_EVENT_STRING
+#define LOG_EVENT_STRING(_tag, _value)                                      \
+    ((void) 0)  /* not implemented -- must combine len with string */
+#endif
+/* TODO: something for LIST */
+
+/*
+ * ===========================================================================
+ *
+ * The stuff in the rest of this file should not be used directly.
+ */
+
+#define android_printLog(prio, tag, fmt...) \
+    __android_log_print(prio, tag, fmt)
+
+#define android_vprintLog(prio, cond, tag, fmt...) \
+    __android_log_vprint(prio, tag, fmt)
+
+/* XXX Macros to work around syntax errors in places where format string
+ * arg is not passed to ALOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF
+ * (happens only in debug builds).
+ */
+
+/* Returns 2nd arg.  Used to substitute default value if caller's vararg list
+ * is empty.
+ */
+#define __android_second(dummy, second, ...)     second
+
+/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
+ * returns nothing.
+ */
+#define __android_rest(first, ...)               , ## __VA_ARGS__
+
+#define android_printAssert(cond, tag, fmt...) \
+    __android_log_assert(cond, tag, \
+        __android_second(0, ## fmt, NULL) __android_rest(fmt))
+
+#define android_writeLog(prio, tag, text) \
+    __android_log_write(prio, tag, text)
+
+#define android_bWriteLog(tag, payload, len) \
+    __android_log_bwrite(tag, payload, len)
+#define android_btWriteLog(tag, type, payload, len) \
+    __android_log_btwrite(tag, type, payload, len)
+
+// TODO: remove these prototypes and their users
+#define android_testLog(prio, tag) (1)
+#define android_writevLog(vec,num) do{}while(0)
+#define android_write1Log(str,len) do{}while (0)
+#define android_setMinPriority(tag, prio) do{}while(0)
+//#define android_logToCallback(func) do{}while(0)
+#define android_logToFile(tag, file) (0)
+#define android_logToFd(tag, fd) (0)
+
+typedef enum {
+    LOG_ID_MAIN = 0,
+    LOG_ID_RADIO = 1,
+    LOG_ID_EVENTS = 2,
+    LOG_ID_SYSTEM = 3,
+
+    LOG_ID_MAX
+} log_id_t;
+
+/*
+ * Send a simple string to the log.
+ */
+int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text);
+int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LIBS_CUTILS_LOG_H
diff --git a/third_party/hwcplus/include/system/graphics.h b/third_party/hwcplus/include/system/graphics.h
index be86ae4..4ba6a9e 100644
--- a/third_party/hwcplus/include/system/graphics.h
+++ b/third_party/hwcplus/include/system/graphics.h
@@ -18,6 +18,9 @@
 #define SYSTEM_CORE_INCLUDE_ANDROID_GRAPHICS_H
 
 #include <stdint.h>
+#ifndef ANDROID
+#include <stddef.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/third_party/hwcplus/src/hardware.c b/third_party/hwcplus/src/hardware.c
index 6713ea0..4ff293d 100644
--- a/third_party/hwcplus/src/hardware.c
+++ b/third_party/hwcplus/src/hardware.c
@@ -23,17 +23,29 @@
 #include <pthread.h>
 #include <errno.h>
 #include <limits.h>
+#include <stdlib.h>
 
 #define LOG_TAG "HAL"
+#ifdef ANDROID
 #include <utils/Log.h>
+#else
+#include <stdio.h>
+#include <unistd.h>
+#include <log/log.h>
+#endif
+
+#if defined(__LP64__)
+#define _64 "64"
+#else
+#define _64 ""
+#endif
 
 /** Base path of the hal modules */
-#if defined(__LP64__)
-#define HAL_LIBRARY_PATH1 "/system/lib64/hw"
-#define HAL_LIBRARY_PATH2 "/vendor/lib64/hw"
-#else
-#define HAL_LIBRARY_PATH1 "/system/lib/hw"
-#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"
+#ifndef HAL_LIBRARY_PATH1
+#define HAL_LIBRARY_PATH1 "/system/lib" _64 "/hw"
+#endif
+#ifndef HAL_LIBRARY_PATH2
+#define HAL_LIBRARY_PATH2 "/vendor/lib" _64 "/hw"
 #endif
 
 /**
@@ -129,6 +141,14 @@
 static int hw_module_exists(char *path, size_t path_len, const char *name,
                             const char *subname)
 {
+    char *hal_library_path = getenv("HAL_LIBRARY_PATH");
+    if (hal_library_path) {
+        snprintf(path, path_len, "%s/%s.%s.so",
+                 hal_library_path, name, subname);
+        if (access(path, R_OK) == 0)
+            return 0;
+    }
+
     snprintf(path, path_len, "%s/%s.%s.so",
              HAL_LIBRARY_PATH2, name, subname);
     if (access(path, R_OK) == 0)
diff --git a/third_party/hwcplus/src/hwcplus_util.c b/third_party/hwcplus/src/hwcplus_util.c
new file mode 100644
index 0000000..57c4519
--- /dev/null
+++ b/third_party/hwcplus/src/hwcplus_util.c
@@ -0,0 +1,75 @@
+// 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.
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <hardware/hardware.h>
+#include <cutils/properties.h>
+
+#define LOG_BUF_SIZE 1024
+
+static int default_log_fn(int prio, const char* tag, const char* msg);
+
+static hwcplus_log_fn_t hwcplus_log_fn = default_log_fn;
+
+void hwcplus_set_log_fn(hwcplus_log_fn_t fn) {
+    hwcplus_log_fn = fn;
+}
+
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char* dst, const char* src, size_t siz) {
+    char* d = dst;
+    const char* s = src;
+    size_t n = siz;
+
+    /* Copy as many bytes as will fit */
+    if (n != 0) {
+        while (--n != 0) {
+            if ((*d++ = *s++) == '\0')
+                break;
+        }
+    }
+
+    /* Not enough room in dst, add NUL and traverse rest of src */
+    if (n == 0) {
+        if (siz != 0)
+            *d = '\0'; /* NUL-terminate dst */
+        while (*s++) {
+        }
+    }
+
+    return(s - src - 1); /* count does not include NUL */
+}
+#endif
+
+static int default_log_fn(int prio, const char* tag, const char* msg) {
+    fprintf(stderr, "<%d> %s %s\n", prio, tag, msg);
+}
+
+int __android_log_write(int prio, const char* tag, const char* msg) {
+    hwcplus_log_fn(prio, tag, msg);
+}
+
+int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
+    va_list ap;
+    char buf[LOG_BUF_SIZE];
+
+    va_start(ap, fmt);
+    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
+    va_end(ap);
+
+    return __android_log_write(prio, tag, buf);
+}
+
+int property_get(const char* key, char* value, const char* default_value) {
+    printf("property_get %s\n", key);
+    const char* r = default_value;
+    if (!r)
+        r = "";
+    strncpy(value, r, PROPERTY_VALUE_MAX);
+    return strlen(r);
+}
+
diff --git a/third_party/iaccessible2/README.chromium b/third_party/iaccessible2/README.chromium
index c224897..6ce0cbd 100644
--- a/third_party/iaccessible2/README.chromium
+++ b/third_party/iaccessible2/README.chromium
@@ -1,8 +1,9 @@
 Name: IAccessible2 COM interfaces for accessibility
 Short Name: IAccessible2
 URL: http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2
-Version: unknown
+Version: 1.3
 License: BSD
+Security Critical: yes
 
 Description:
   This directory contains the IAccessible2 API, a set of COM interfaces
diff --git a/third_party/iaccessible2/ia2_api_all.idl b/third_party/iaccessible2/ia2_api_all.idl
index 564c920..729ed26 100644
--- a/third_party/iaccessible2/ia2_api_all.idl
+++ b/third_party/iaccessible2/ia2_api_all.idl
@@ -1,10 +1,65 @@
 /*************************************************************************
  *
+ *  File Name (api_all_headers.idl)
+ * 
+ *  IAccessible2 IDL Specification 
+ * 
+ *  Copyright (c) 2013 Linux Foundation 
+ *  All rights reserved. 
+ *   
+ *   
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met: 
+ *   
+ *   1. Redistributions of source code must retain the above copyright 
+ *      notice, this list of conditions and the following disclaimer. 
+ *   
+ *   2. Redistributions in binary form must reproduce the above 
+ *      copyright notice, this list of conditions and the following 
+ *      disclaimer in the documentation and/or other materials 
+ *      provided with the distribution. 
+ *
+ *   3. Neither the name of the Linux Foundation nor the names of its 
+ *      contributors may be used to endorse or promote products 
+ *      derived from this software without specific prior written 
+ *      permission. 
+ *   
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ *  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+ *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+ *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *   
+ *  This BSD License conforms to the Open Source Initiative "Simplified 
+ *  BSD License" as published at: 
+ *  http://www.opensource.org/licenses/bsd-license.php 
+ *   
+ *  IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 
+ *  mark may be used in accordance with the Linux Foundation Trademark 
+ *  Policy to indicate compliance with the IAccessible2 specification. 
+ * 
+ ************************************************************************/ 
+
+import "objidl.idl";
+import "oaidl.idl";
+import "oleacc.idl";
+
+/*************************************************************************
+ *
  *  File Name (IA2CommonTypes.idl)
  * 
  *  IAccessible2 IDL Specification 
  * 
- *  Copyright (c) 2007, 2010 Linux Foundation 
+ *  Copyright (c) 2007, 2013 Linux Foundation 
  *  Copyright (c) 2006 IBM Corporation 
  *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
  *  All rights reserved. 
@@ -195,7 +250,7 @@
  * 
  *  IAccessible2 IDL Specification 
  * 
- *  Copyright (c) 2007, 2010 Linux Foundation 
+ *  Copyright (c) 2007, 2013 Linux Foundation 
  *  Copyright (c) 2006 IBM Corporation 
  *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
  *  All rights reserved. 
@@ -242,9 +297,9 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
 
 /** @defgroup grpRelations Relations 
   Use the following constants to compare against the BSTRs returned by 
@@ -252,6 +307,20 @@
 */ 
 ///@{
 
+/** The target object is the containing application object. */
+const WCHAR *const IA2_RELATION_CONTAINING_APPLICATION = L"containingApplication";
+
+/** The target object is the containing document object. The target object implements
+ the IAccessibleDocument interface.
+*/
+const WCHAR *const IA2_RELATION_CONTAINING_DOCUMENT = L"containingDocument";
+
+/** The target object is the containing tab pane object. */
+const WCHAR *const IA2_RELATION_CONTAINING_TAB_PANE = L"containingTabPane";
+
+/** The target object is the containing window object. */
+const WCHAR *const IA2_RELATION_CONTAINING_WINDOW = L"containingWindow";
+
 /** Some attribute of this object is affected by a target object. */
 const WCHAR *const IA2_RELATION_CONTROLLED_BY = L"controlledBy";
 
@@ -302,23 +371,39 @@
 */
 const WCHAR *const IA2_RELATION_MEMBER_OF = L"memberOf";
 
-/** This object is a child of a target object. */
+/** The target object is the next object in the tab order. */
+const WCHAR *const IA2_RELATION_NEXT_TABBABLE = L"nextTabbable";
+
+/** This object is a logical child of a target object.  This relation is the reciprocal
+ of the IA2_RELATION_NODE_PARENT_OF relation. In some cases an application's accessible
+ tree is such that objects can be in a logical parent-child relationship which is
+ different from the hierarchy of the accessible tree. */
 const WCHAR *const IA2_RELATION_NODE_CHILD_OF = L"nodeChildOf";
 
+/** This object is a logical parent of a target object. This relation is the reciprocal
+ of the IA2_RELATION_NODE_CHILD_OF relation. In some cases an application's accessible
+ tree is such that objects can be in a logical parent-child relationship which is
+ different from the hierarchy of the accessible tree. */
+const WCHAR *const IA2_RELATION_NODE_PARENT_OF = L"nodeParentOf";
+
 /** This object is a parent window of the target object. */
 const WCHAR *const IA2_RELATION_PARENT_WINDOW_OF = L"parentWindowOf";
 
 /** This object is a transient component related to the target object. 
- When this object is activated the target object doesn't loose focus.
+ When this object is activated the target object doesn't lose focus.
 */
 const WCHAR *const IA2_RELATION_POPUP_FOR = L"popupFor";
 
+/** The target object is the previous object in the tab order. */
+const WCHAR *const IA2_RELATION_PREVIOUS_TABBABLE = L"previousTabbable";
+
 /** This object is a sub window of a target object. */
 const WCHAR *const IA2_RELATION_SUBWINDOW_OF = L"subwindowOf";
 
 ///@}
 
-/// This interface gives access to an object's set of relations.
+/** This interface gives access to an object's set of relations.
+*/
 [object, uuid(7CDF86EE-C3DA-496a-BDA4-281B336E1FDC)]
 interface IAccessibleRelation : IUnknown
 {
@@ -355,8 +440,7 @@
     0 based index
    @param [out] target
    @retval S_OK
-   @retval S_FALSE if there is nothing to return, [out] value is NULL
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL 
+   @retval E_INVALIDARG if bad [in] passed
    @note Use QueryInterface to get IAccessible2.
   */
   [propget] HRESULT target
@@ -376,7 +460,7 @@
    @param [out] nTargets
 	actual number of targets in the returned array (not more than maxTargets)
    @retval S_OK
-   @retval S_FALSE if there is nothing to return, nTargets is set to 0
+   @retval E_INVALIDARG if bad [in] passed, e.g. a negative value
   */
   [propget] HRESULT targets
     (
@@ -393,7 +477,7 @@
  *
  *  IAccessible2 IDL Specification 
  * 
- *  Copyright (c) 2007, 2010 Linux Foundation 
+ *  Copyright (c) 2007, 2013 Linux Foundation 
  *  Copyright (c) 2006 IBM Corporation 
  *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
  *  All rights reserved. 
@@ -440,9 +524,34 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
+
+/** This enum defines values which are predefined actions for use when implementing
+ support for media.
+
+ This enum is used when specifying an action for IAccessibleAction::doAction.
+*/
+
+enum IA2Actions {
+  IA2_ACTION_OPEN = -1,         /**< Used to inform the server that the client will
+                                signal via IA2_ACTION_COMPLETE when it has consumed
+                                the content provided by the object.  This action
+                                allows the object's server to wait for all clients
+                                to signal their readiness for additional content.
+                                Any form of content generation that requires
+                                synchronization with an AT would require use of this
+                                action.  One example is the generation of text describing
+                                visual content not obvious from a video's sound track.
+                                In this scenario the Text to Speech or Braille output
+                                may take more time than the related length of silence
+                                in the video's sound track. */
+  IA2_ACTION_COMPLETE = -2,  	/**< Used by the client to inform the server that it has
+                                consumed the most recent content provided by this object. */
+  IA2_ACTION_CLOSE = -3         /**< Used to inform the server that the client no longer
+                                requires synchronization. */
+};
         
 /** @brief This interface gives access to actions that can be executed
   for accessible objects.
@@ -486,7 +595,9 @@
     0 based index specifying the action to perform.  If it lies outside
     the valid range no action is performed.
    @retval S_OK
-   @retval E_INVALIDARG if bad [in] passed 
+   @retval S_FALSE if action could not be performed
+   @retval E_INVALIDARG if bad [in] passed
+   @note If implementing support for media, refer to the predefined constants in the ::IA2Actions enum.
     */
   HRESULT doAction
     (
@@ -501,7 +612,7 @@
     The returned value is a localized string of the specified action.
    @retval S_OK
    @retval S_FALSE if there is nothing to return, [out] value is NULL 
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL 
+   @retval E_INVALIDARG if bad [in] passed
     */
   [propget] HRESULT description
     (
@@ -536,12 +647,12 @@
 	"Special Consideration when using Arrays" for more details.
    @param [out] keyBindings
     An array of BSTRs, allocated by the server, one for each key binding.
-	Free it with CoTaskMemFree.
+	The client must free it with CoTaskMemFree.
    @param [out] nBindings
     The number of key bindings returned; the size of the returned array.
    @retval S_OK
-   @retval S_FALSE if there are no relations, [out] values are NULL and 0 respectively 
-   @retval E_INVALIDARG if bad [in] passed, [out] values are NULL and 0 respectively 
+   @retval S_FALSE if there are no key bindings, [out] values are NULL and 0 respectively 
+   @retval E_INVALIDARG if bad [in] passed
 	*/
   [propget] HRESULT keyBinding
     (
@@ -557,7 +668,7 @@
    @param [out] name
    @retval S_OK
    @retval S_FALSE if there is nothing to return, [out] value is NULL 
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL 
+   @retval E_INVALIDARG if bad [in] passed
    */
   [propget] HRESULT name
     (
@@ -571,7 +682,7 @@
    @param [out] localizedName
    @retval S_OK
    @retval S_FALSE if there is nothing to return, [out] value is NULL 
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL 
+   @retval E_INVALIDARG if bad [in] passed
    */
   [propget] HRESULT localizedName
     (
@@ -586,7 +697,7 @@
  * 
  *  IAccessible2 IDL Specification 
  * 
- *  Copyright (c) 2007, 2010 Linux Foundation 
+ *  Copyright (c) 2007, 2013 Linux Foundation 
  *  Copyright (c) 2006 IBM Corporation 
  *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
  *  All rights reserved. 
@@ -633,7 +744,7 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
+
 
 /** Collection of roles
 
@@ -683,10 +794,9 @@
   */
   IA2_ROLE_DIRECTORY_PANE,
 
-  /** An editable text object in a toolbar.
-   <BR><B>Note:</B> This role has been deprecated.  The edit bar role was meant
-   for a text area in a tool bar. However, to detect a text area in a tool bar
-   the AT can query the parent.
+  /** An editable text object in a toolbar. <b>Deprecated.</b>
+   The edit bar role was meant for a text area in a tool bar. However, to detect
+   a text area in a tool bar the AT can query the parent.
   */
   IA2_ROLE_EDITBAR,
 
@@ -739,7 +849,7 @@
   */
   IA2_ROLE_HEADER,
 
-  /// Heading.  Use the IAccessible2::attributes heading-level attribute to determine the heading level.
+  /// Heading.  Use the IAccessible2::attributes level attribute to determine the heading level.
   IA2_ROLE_HEADING,
 
   /// A small fixed size picture, typically used to decorate components.
@@ -774,7 +884,9 @@
   */
   IA2_ROLE_LAYERED_PANE,
 
-  /// An embedded note which is not visible until activated.
+  /** A section whose content is parenthetic or ancillary to the main content
+   of the resource.
+  */
   IA2_ROLE_NOTE,
 
  /** A specialized pane whose primary use is inside a dialog.
@@ -860,7 +972,18 @@
    the scroll bars, the contents of the viewport can change.
    Also refer to ::IA2_ROLE_SCROLL_PANE.
   */
-  IA2_ROLE_VIEW_PORT
+  IA2_ROLE_VIEW_PORT,
+
+  /** An object containing content which is complementary to the main content of
+   a document, but remains meaningful when separated from the main content.  There
+   are various types of content that would appropriately have this role.  For example,
+   in the case where content is delivered via a web portal to a web browser, this may
+   include but not be limited to show times, current weather, related articles, or
+   stocks to watch.  The complementary role indicates that contained content is relevant
+   to the main content.  If the complementary content is completely separable main
+   content, it may be appropriate to use a more general role.
+  */
+  IA2_ROLE_COMPLEMENTARY_CONTENT
   
 };
 /*************************************************************************
@@ -916,7 +1039,7 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
+
 
 typedef long AccessibleStates;
 
@@ -957,7 +1080,12 @@
 /** Indicates the user interface object corresponding to this object no longer exists. */
 IA2_STATE_DEFUNCT =					0x4,
 
-/** Indicates the user can change the contents of this object. */
+/** An object with this state has a caret and implements the IAccessibleText interface.
+  
+ Such fields may be read-only, so STATE_SYSTEM_READONLY is valid in combination
+  with IA2_STATE_EDITABLE.
+
+*/
 IA2_STATE_EDITABLE =				0x8,
 
 /** Indicates the orientation of this object is horizontal. */
@@ -1043,7 +1171,28 @@
 IA2_STATE_TRANSIENT =				0x10000,
 
 /** Indicates the orientation of this object is vertical. */
-IA2_STATE_VERTICAL =				0x20000
+IA2_STATE_VERTICAL =				0x20000,
+
+/** Indicates this object is checkable.
+
+ The standard checkable objects are check boxes, radio buttons, check box menu
+ items, radio menu items, and toggle buttons.  Since assistive technology will
+ determine that these objects are checkable via the object's role the checkable
+ state is not required.  However, this state is necessary in those cases where
+ an object has a role which is not one of the previously mentioned roles.  An
+ example is a table cell which indicates whether or not an email has an attachment,
+ whether or not an mail is considered spam, and whether or not an email has been read.
+ */
+IA2_STATE_CHECKABLE =				0x40000,
+
+/** Indicates this object is pinned.
+
+ This state indicates that an object is fixed at a certain location.  One example
+ is a browser tab that when pinned cannot be moved until unpinned.  Another example
+ is a movable or floating object that when pinned remains in its pinned location
+ until being unpinned.
+ */
+IA2_STATE_PINNED =					0x80000
 
 };
 /*************************************************************************
@@ -1052,7 +1201,7 @@
  * 
  *  IAccessible2 IDL Specification 
  * 
- *  Copyright (c) 2007, 2010 Linux Foundation 
+ *  Copyright (c) 2007, 2013 Linux Foundation 
  *  Copyright (c) 2006 IBM Corporation 
  *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
  *  All rights reserved. 
@@ -1103,18 +1252,22 @@
 
  @section _interfaces Interfaces
   IAccessible2\n
+  IAccessible2_2\n
   IAccessibleAction\n
   IAccessibleApplication\n
   IAccessibleComponent\n
+  IAccessibleDocument\n
+  IAccessibleEditableText\n
   IAccessibleHypertext\n
+  IAccessibleHypertext2\n
   IAccessibleHyperlink\n
   IAccessibleImage\n
   IAccessibleRelation\n
-  IAccessibleTable [deprecated]\n
+  IAccessibleTable [Deprecated]\n
   IAccessibleTable2\n
   IAccessibleTableCell\n
   IAccessibleText\n
-  IAccessibleEditableText\n
+  IAccessibleText2\n
   IAccessibleValue
 
  @section _structs Structs
@@ -1123,6 +1276,7 @@
   IA2TextSegment
 
  @section _enums Enums
+  ::IA2Actions values are predefined actions for use when implementing support for HTML5 media.\n
   ::IA2CoordinateType values define the requested coordinate type (screen or parent window).\n
   ::IA2EventID values identify events.\n
   ::IA2Role values defines roles which are in addition to the existing MSAA roles.\n
@@ -1142,7 +1296,7 @@
  @page _licensePage BSD License
   %IAccessible2 IDL Specification
 
-  Copyright (c) 2007, 2010 Linux Foundation\n
+  Copyright (c) 2007, 2013 Linux Foundation\n
   Copyright (c) 2006 IBM Corporation\n
   Copyright (c) 2000, 2006 Sun Microsystems, Inc.\n
   All rights reserved.
@@ -1194,7 +1348,7 @@
  @ref _memory\n
  &nbsp;&nbsp;@ref _arrayConsideration\n
  @ref _indexes\n
- @ref _enums\n
+ @ref _enumBase\n
  @ref _specialOffsets\n
  @ref _dicoveringInterfaces\n
  @ref _changingInterfaces\n
@@ -1205,9 +1359,9 @@
  @ref _trademark
 
  @section _errors Error Handling
-  HRESULT values are defined by the Microsoft&reg; Win32&reg; API.  For more information, refer to 
-  <a href="http://msdn2.microsoft.com/en-us/library/bb401631.aspx">Interpreting HRESULT Values</a>
-  in MSDN&reg;.
+  HRESULT values are defined by the Microsoft&reg; Win32&reg; API.  For more information, refer to
+  <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa378137%28v=vs.85%29.aspx">
+  Interpreting HRESULT Values</a> in MSDN&reg;.
 
   Note that the S_FALSE return value is considered a non-error value and the 
   SUCCEEDED macro will return TRUE.  S_FALSE is used when there is no failure
@@ -1244,26 +1398,33 @@
    String: What are the rules for BSTR allocation and deallocation?</a>
 
  @subsection _arrayConsideration Special Consideration when using Arrays
-  There are several methods which return arrays.  It is considered a best practice
-  for the client to allocate and free the arrays.  This can be done for 
-  IAccessible2::relations and IAccessibleRelation::targets.  However, due to the
-  coding of the IDL for the remaining methods which return arrays, the server must
-  allocate the array and the client must free the array when no longer needed.  
-  These methods are IAccessible2::extendedStates, IAccessible2::localizedExtendedStates, 
-  IAccessibleAction::keyBinding, IAccessibleTable::selectedChildren, 
-  IAccessibleTable::selectedColumns, and IAccessibleTable::selectedRows.  For those 
-  methods, the server must allocate both the top level array and any storage 
-  associated with it, e.g. for BSTRs.  The client must use CoTaskMemFree to free
-  the array and any BSTRs must be freed with SysFreeString.  
+  There are several methods which return arrays.  In the case of IAccessible2::relations
+  and IAccessibleRelation::targets the client must allocate and free the arrays.
+
+  For the remaining methods which return arrays, the server must allocate the array
+  and the client must free the array when no longer needed.  These methods are
+  IAccessible2::extendedStates, IAccessible2::localizedExtendedStates,
+  IAccessible2_2::relationTargetsOfType, IAccessibleAction::keyBinding, 
+  IAccessibleHypertext2::hyperlinks, IAccessibleTable::selectedChildren, 
+  IAccessibleTable::selectedColumns, IAccessibleTable::selectedRows,
+  IAccessibleTable2::selectedCells, IAccessibleTable2::selectedColumns,
+  IAccessibleTable2::selectedRows, IAccessibleTableCell::columnHeaderCells,
+  and IAccessibleTableCell::rowHeaderCells.
+  For those methods, the server must allocate both the top level array and any storage 
+  associated with it, e.g. for BSTRs.  The server must allocate the arrays with 
+  CoTaskMemAlloc and any BSTRs with SysAllocString.  The client must use CoTaskMemFree
+  to free the array and any BSTRs must be freed with SysFreeString.  
   
-  Also, the IDL for those methods includes an extraneous [in] parameter for the 
-  caller to specify the max size of the array.  This parameter will be ignored by 
-  the COM server.
+  Also, the IDL for IAccessible2::extendedStates, IAccessible2::localizedExtendedStates, 
+  IAccessibleAction::keyBinding, IAccessibleTable::selectedChildren, 
+  IAccessibleTable::selectedColumns, and IAccessibleTable::selectedRows includes an
+  extraneous [in] parameter for the caller to specify the max size of the array.
+  This parameter will be ignored by the COM server.
 
  @section _indexes Zero and One Based Indexes
   Unless otherwise specified all offsets and indexes are 0 based. 
 
- @section _enums Enums
+ @section _enumBase Enum Base
   Note that enums start at 0.
 
  @section _specialOffsets Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods
@@ -1303,18 +1464,16 @@
   } 
   @endcode
 
- @section _changingInterfaces Changing between Accessible Interfaces
-  Note that developers must always implement MSAA's IAccessible and, if needed, some 
-  of the interfaces in the set of IAccessible2 interfaces.  Although the IAccessible2 
-  IDL is currently coded such that IAccessible2 is a subclass of MSAA's IAccessible, 
-  none of MSAA's IAccessible methods are overridden or extended.  In order to allow 
-  future removal of the inheritance, Assistive Technologies (ATs) should not rely on 
-  that inheritance. 
+  @section _changingInterfaces Changing between Accessible Interfaces
+  Note that developers must always implement MSAA's IAccessible and, if needed, some
+  of the interfaces in the set of IAccessible2 interfaces.  Although the IAccessible2
+  IDL is coded such that IAccessible2 is a subclass of MSAA's IAccessible, none of
+  MSAA's IAccessible methods are redefined by IAccessible2.
 
   QueryService must be used to switch from a reference to an MSAA IAccessible interface 
   to another interface.  This has been 
-  <a href="http://www.accessinteropalliance.org/docs/Introducing_IAccessibleEx.doc">
-  documented by Microsoft</a> and the pertinent facts have been extracted below: 
+  <a href="http://www.atia.org/files/public/Introducing_IAccessibleEx.doc">
+  documented</a> and the pertinent facts have been extracted below: 
 
   @par 
    Why use QueryService instead of just using QueryInterface to get IAccessibleEx 
@@ -1387,9 +1546,9 @@
 
 **/
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
 
 
 
@@ -1404,13 +1563,15 @@
   BSTR variant;  ///< Application specific variant of the locale
 } IA2Locale;
 
-/** This interface must always be provided for objects that support some
+/** @brief This interface exposes the primary set of information about an
+ IAccessible2 enabled accessible object.
+
+ This interface must always be provided for objects that support some
  portion of the collection of the %IAccessible2 interfaces.
 
  Please refer to @ref _changingInterfaces "Changing between Accessible Interfaces"
  for special considerations related to use of the MSAA IAccessible interface and 
  the set of %IAccessible2 interfaces.
-
  */
 [object, uuid(E89F726E-C4F4-4c19-BB19-B647D7FA8478)]
 interface IAccessible2 : IAccessible
@@ -1430,7 +1591,7 @@
      0 based
    @param [out] relation
    @retval S_OK
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT relation
     (
@@ -1449,6 +1610,7 @@
     actual number of relations in the returned array (not more than maxRelations)
    @retval S_OK
    @retval S_FALSE if there are no relations, nRelations is set to 0
+   @note As a performant alternative, client code should consider using IAccessible2_2::relationTargetsOfType.
   */
   [propget] HRESULT relations
     (
@@ -1518,16 +1680,19 @@
     1 based, 0 indicates that this value is not applicable
    @param [out] positionInGroup
     1 based, 0 indicates that this value is not applicable. This is an index
-	into the objects in the current group, not an index into all the objects
-	at the same group level.
+    into the objects in the current group, not an index into all the objects
+    at the same group level.
    @retval S_OK if at least one value is valid
-   @retval S_FALSE if no values are valid
+   @retval S_FALSE if no values are valid, [out] values are 0s
    @note This method is meant to describe the nature of an object's containment
-    structure.  This is normally not implemented on a combo box to describe the nature
+    structure.  It's exposed by trees, tree grids, nested lists, nested menus,
+    but not headings, which uses the level object attribute.  It is also exposed
+    by radio buttons (with groupLevel == 0).
+   @note This is normally not implemented on a combo box to describe the nature
     of its contents.  Normally an AT will get that information from its child list 
-	object.  However, in some cases when combo boxes are not able to be structured
-	such that the list is a child of the combo box, this method is implemented
-	on the combo box itself. ATs can use this interface if a child list is not found.
+    object.  However, in some cases when non-edit combo boxes are not able to be structured
+    such that the list is a child of the combo box, this method is implemented on
+    the combo box itself. ATs can use this interface if a child list is not found.
 	*/
   [propget] HRESULT groupPosition
     (
@@ -1591,7 +1756,7 @@
     This parameter is ignored. Refer to @ref _arrayConsideration 
 	"Special Consideration when using Arrays" for more details.
    @param [out] extendedStates
-    This array is allocated by the server.  Free it with CoTaskMemFree.
+    This array is allocated by the server.  The client must free it with CoTaskMemFree.
    @param [out] nExtendedStates
     The number of extended states returned; the size of the returned array.
    @retval S_OK
@@ -1605,11 +1770,12 @@
     );
 
   /** @brief Returns the localized extended states (array of strings).
+
    @param [in] maxLocalizedExtendedStates
     This parameter is ignored. Refer to @ref _arrayConsideration 
 	"Special Consideration when using Arrays" for more details.
    @param [out] localizedExtendedStates
-    This array is allocated by the server.  Free it with CoTaskMemFree. 
+    This array is allocated by the server.  The client must free it with CoTaskMemFree. 
    @param [out] nLocalizedExtendedStates
     The number of localized extended states returned; the size of the returned array.
    @retval S_OK
@@ -1654,7 +1820,11 @@
    One means of implementing this would be to create a factory with a 32 bit number 
    generator and a reuse pool.  The number generator would emit numbers starting 
    at 1.  Each time an object's life cycle ended, its number would be saved into a 
-   resuse pool.  The number generator would be used whenever the reuse pool was empty.
+   reuse pool.  The number generator would be used whenever the reuse pool was empty.
+
+   Another way to create a unique ID is to generate it from a pointer value, e.g. an
+   object's address. That would be unique because no two active objects can use the
+   same allocated memory space.
 
    @param [out] uniqueID
    @retval S_OK
@@ -1705,7 +1875,7 @@
      [out, retval] IA2Locale *locale
     );
 
-  /** @brief Returns the attributes specific to this %IAccessible2 object, such as a cell's formula.
+  /** @brief Returns the attributes specific to this object, such as a cell's formula.
    @param [out] attributes
    @retval S_OK
    @retval S_FALSE returned if there is nothing to return, [out] value is NULL
@@ -1719,6 +1889,129 @@
 
 /*************************************************************************
  *
+ *  File Name (Accessible2_2.idl)
+ * 
+ *  IAccessible2 IDL Specification 
+ * 
+ *  Copyright (c) 2007, 2013 Linux Foundation 
+ *  Copyright (c) 2006 IBM Corporation 
+ *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
+ *  All rights reserved. 
+ *   
+ *   
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met: 
+ *   
+ *   1. Redistributions of source code must retain the above copyright 
+ *      notice, this list of conditions and the following disclaimer. 
+ *   
+ *   2. Redistributions in binary form must reproduce the above 
+ *      copyright notice, this list of conditions and the following 
+ *      disclaimer in the documentation and/or other materials 
+ *      provided with the distribution. 
+ *
+ *   3. Neither the name of the Linux Foundation nor the names of its 
+ *      contributors may be used to endorse or promote products 
+ *      derived from this software without specific prior written 
+ *      permission. 
+ *   
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ *  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+ *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+ *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *   
+ *  This BSD License conforms to the Open Source Initiative "Simplified 
+ *  BSD License" as published at: 
+ *  http://www.opensource.org/licenses/bsd-license.php 
+ *   
+ *  IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 
+ *  mark may be used in accordance with the Linux Foundation Trademark 
+ *  Policy to indicate compliance with the IAccessible2 specification. 
+ * 
+ ************************************************************************/ 
+
+
+
+
+
+
+/** @brief This interface exposes the primary set of information about an
+ IAccessible2 enabled accessible object.
+
+ This interface must always be provided for objects that support some
+ portion of the collection of the %IAccessible2 interfaces.
+
+ Please refer to @ref _changingInterfaces "Changing between Accessible Interfaces"
+ for special considerations related to use of the MSAA IAccessible interface and 
+ the set of %IAccessible2 interfaces.
+ */
+[object, uuid(6C9430E9-299D-4E6F-BD01-A82A1E88D3FF)]
+interface IAccessible2_2 : IAccessible2
+{
+  /** @brief Returns the attribute value of a specified attribute specific to this object.
+   @param [in] name
+   @param [out] attribute
+   @retval S_OK
+   @retval S_FALSE returned if there is nothing to return, [out] value is NULL.
+   @retval E_INVALIDARG if bad [in] passed.
+   @note The output value is a VARIANT.  Typically it will be a VT_BSTR, but there
+     are some cases where it will be a VT_I4 or VT_BOOL.  Refer to the <a href=
+     "http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/objectattributesIAccessible2">
+     Object Attributes specification</a> for more information.
+  */
+  [propget] HRESULT attribute
+    (
+     [in] BSTR name,
+     [out, retval] VARIANT *attribute
+    );
+
+  /** @brief Returns the deepest hypertext accessible in the subtree of this object, and the caret offset within it.
+   @param [out] accessible
+   @param [out] caretOffset
+   @retval S_OK
+   @retval S_FALSE returned if there is no caret in any of the objects in the subtree, [out] accessible is NULL and [out] caretOffset is -1.
+  */
+  [propget] HRESULT accessibleWithCaret
+    (
+     [out] IUnknown **accessible,
+     [out, retval] long *caretOffset
+    );
+
+  /** @brief Returns relation targets for a specified target type.
+   @param [in] type
+    The requested @ref grpRelations "relation type".
+   @param [in] maxTargets
+    The number of targets requested.  0 indicates that all targets should be returned.
+   @param [out] targets
+    This array is allocated by the server.  The client must free it with CoTaskMemFree.
+   @param [out] nTargets
+    The number of targets returned; the size of the returned array.
+   @retval S_OK
+   @retval S_FALSE if there are no targets, [out] values are NULL and 0 respectively.
+   @retval E_INVALIDARG if bad [in] passed.
+  */
+  [propget] HRESULT relationTargetsOfType
+    (
+     [in] BSTR type,
+     [in] long maxTargets,
+     [out, size_is(,*nTargets)] IUnknown ***targets,
+     [out, retval] long *nTargets
+    );
+
+}
+
+/*************************************************************************
+ *
  *  File Name (AccessibleComponent.idl)
  * 
  *  IAccessible2 IDL Specification 
@@ -1770,9 +2063,9 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
 
 /** A value specifying a color in ARGB format, where each 8 bit color component
 specifies alpha, red, green, and blue respectively.  The alpha value is optional.
@@ -1894,9 +2187,9 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
 
 /** @brief This interface gives access to a single numerical value.
 
@@ -1917,7 +2210,7 @@
     Returns the current value represented by this object.  See the section about 
 	@ref _variants "VARIANTs" for additional information.
    @retval S_OK
-   @retval S_FALSE if there is nothing to return, [out] value is NULL
+   @retval S_FALSE if there is nothing to return, [out] value is a VARIANT with vt = VT_EMPTY
   */
   [propget] HRESULT currentValue
     (
@@ -1932,7 +2225,7 @@
 	value the new value will be the minimum and if it is greater than the 
 	maximum then the new value will be the maximum.
 
-   @param [out] value
+   @param [in] value
     The new value represented by this object.  The set of admissible types for 
     this argument is implementation dependent.
    @retval S_OK
@@ -1952,6 +2245,7 @@
     has no upper bound then an empty object is returned.  See the section about 
 	@ref _variants "VARIANTs" for additional information.
    @retval S_OK
+   @retval S_FALSE if there is nothing to return, [out] value is a VARIANT with vt = VT_EMPTY
   */
   [propget] HRESULT maximumValue
     (
@@ -1968,6 +2262,7 @@
     has no lower bound then an empty object is returned.  See the section about 
 	@ref _variants "VARIANTs" for additional information.
    @retval S_OK
+   @retval S_FALSE if there is nothing to return, [out] value is a VARIANT with vt = VT_EMPTY
   */
   [propget] HRESULT minimumValue
     (
@@ -1981,7 +2276,7 @@
  * 
  *  IAccessible2 IDL Specification 
  * 
- *  Copyright (c) 2007, 2010 Linux Foundation 
+ *  Copyright (c) 2007, 2013 Linux Foundation 
  *  Copyright (c) 2006 IBM Corporation 
  *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
  *  All rights reserved. 
@@ -2028,9 +2323,9 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
 
 
 /** A structure containing a substring and the start and end offsets in the enclosing string.
@@ -2059,25 +2354,25 @@
 */
 
 enum IA2TextBoundaryType {
-  IA2_TEXT_BOUNDARY_CHAR,		/**< Typically, a single character is returned.  In some cases more than
-								 one character is returned, for example, when a document contains field
-								 data such as a field containing a date, time, or footnote reference.
-								 In this case the caret can move over several characters in one movement
-								 of the caret.  Note that after the caret moves, the caret offset changes
-								 by the number of characters in the field, e.g. by 8 characters in the 
-								 following date: 03/26/07. */
-  IA2_TEXT_BOUNDARY_WORD,		/**< The range provided matches the range observed when the application
-								 processes the Ctrl + left arrow and Ctrl + right arrow key sequences.
-								 Typically this is from the start of one word to the start of the next, but
-								 various applications are inconsistent in the handling of the end of a line. */
-  IA2_TEXT_BOUNDARY_SENTENCE,	///< Range is from start of one sentence to the start of another sentence.
-  IA2_TEXT_BOUNDARY_PARAGRAPH,	///< Range is from start of one paragraph to the start of another paragraph.
-  IA2_TEXT_BOUNDARY_LINE,		/**< Range is from start of one line to the start of another line. This
+  IA2_TEXT_BOUNDARY_CHAR,       /**< Typically, a single character is returned.  In some cases more than
+                                 one character is returned, for example, when a document contains field
+                                 data such as a field containing a date, time, or footnote reference.
+                                 In this case the caret can move over several characters in one movement
+                                 of the caret.  Note that after the caret moves, the caret offset changes
+                                 by the number of characters in the field, e.g. by 8 characters in the 
+                                 following date: 03/26/07. */
+  IA2_TEXT_BOUNDARY_WORD,       /**< The range provided matches the range observed when the application
+                                 processes the Ctrl + left arrow and Ctrl + right arrow key sequences.
+                                 Typically this is from the start of one word to the start of the next, but
+                                 various applications are inconsistent in the handling of the end of a line. */
+  IA2_TEXT_BOUNDARY_SENTENCE,   ///< Range is from start of one sentence to the start of another sentence.
+  IA2_TEXT_BOUNDARY_PARAGRAPH,  ///< Range is from start of one paragraph to the start of another paragraph.
+  IA2_TEXT_BOUNDARY_LINE,       /**< Range is from start of one line to the start of another line. This
                                  often means that an end-of-line character will appear at the end of the
-								 range. However in the case of some applications an end-of-line character
-								 indicates the end of a paragraph and the lines composing the paragraph,
-								 other than the last line, do not contain an end of line character. */
-  IA2_TEXT_BOUNDARY_ALL			///< Using this value will cause all text to be returned.
+                                 range. However in the case of some applications an end-of-line character
+                                 indicates the end of a paragraph and the lines composing the paragraph,
+                                 other than the last line, do not contain an end of line character. */
+  IA2_TEXT_BOUNDARY_ALL         ///< Using this value will cause all text to be returned.
 };
 
 /** @brief This interface gives read-only access to text.
@@ -2118,6 +2413,9 @@
     Offset of first character after new selection (0 based).
    @retval S_OK
    @retval E_INVALIDARG if bad [in] passed
+   @note  Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleText methods.
   */
   HRESULT addSelection
     (
@@ -2127,21 +2425,22 @@
 
   /** @brief Returns text attributes.
    @param [in] offset
-    Text offset (0 based)
+    Text offset (0 based).  Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleText methods.
    @param [out] startOffset    
     The starting offset of the character range over which all text attributes match 
-	those of offset. (0 based)
+    those of offset. (0 based)
    @param [out] endOffset    
     The offset of the first character past the character range over which all text 
-	attributes match those of offset. (0 based)
+    attributes match those of offset. (0 based)
    @param [out] textAttributes  
     A string of attributes describing the text.  The attributes are described in the
     <a href="http://www.linuxfoundation.org/en/Accessibility/IAccessible2/TextAttributes">
     text attributes specification</a> on the %IAccessible2 web site.
    @retval S_OK
    @retval S_FALSE if there is nothing to return, [out] values are 0s and NULL respectively 
-   @retval E_INVALIDARG if bad [in] passed, [out] values are 0s and NULL respectively 
-        
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT attributes
     (
@@ -2168,7 +2467,8 @@
    <li>the caretOffset for "two" would be 2, matching the "o"</li>
    </ul>
    The caret position/offset is that of the character logically following it, e.g.
-   to the right of it in a left to right language.
+   to the right of it in a left to right language, or to the left of it in a right
+   to left language.
    @param [out] offset
     The returned offset is relative to the text represented by this object.
    @retval S_OK
@@ -2202,7 +2502,9 @@
     event for this index.
    @param [in] offset
     Index of the character for which to return its bounding box. The valid range 
-    is 0..length.
+    is 0..length.  Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleText methods.
    @param [in] coordType
     Specifies if the coordinates are relative to the screen or to the parent window.
    @param [out] x
@@ -2214,7 +2516,7 @@
    @param [out] height
     Height of the bounding box of the referenced character. 
    @retval S_OK
-   @retval E_INVALIDARG if bad [in] passed, [out] values are 0s 
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT characterExtents
     (
@@ -2246,17 +2548,19 @@
             
    @param [in] x
     The position's x value for which to look up the index of the character that
-	is rendered on to the display at that point.
+    is rendered on to the display at that point.
    @param [in] y
     The position's y value for which to look up the index of the character that
-	is rendered on to the display at that point.            
+    is rendered on to the display at that point.            
    @param [in] coordType
     Screen coordinates or window coordinates.
    @param [out] offset
     Index of the character under the given point or -1 if the point
     is invalid or there is no character under the point.
    @retval S_OK
-   @retval E_INVALIDARG if bad [in] passed, [out] value is 0 
+   @retval S_FALSE if nothing to return, [out] value is -1
+
+   @retval E_INVALIDARG if bad [in] passed
     */
   [propget] HRESULT offsetAtPoint
     (
@@ -2267,6 +2571,27 @@
     );
 
   /** @brief Returns the character offsets of Nth active text selection
+
+   Returns the 0-based starting and ending offsets of the Nth selection.  If the
+   text is implemented as a tree of text objects with embed characters in higher
+   levels representing substrings of child text objects, consider the following.
+   If the starting selection offset is in one of the child text objects, then the
+   starting offset in the higher level text object would be at the embed character
+   representing the child text object that contains the starting selection offset.
+   If the ending selection offset is in one of the child text objects, then the
+   ending offset in the higher level text object would be just after the embed
+   character representing the child text object that contains the ending selection
+   offset.
+
+   For example, if the string "one two three" is implemented as a two text objects,
+   with a top level text object containing an embed character "one ? three" and a
+   child text object containing "two" and if the selection is the string "two" then:
+   <ul>
+   <li>the startOffset for the "one ? three" object would be 4, matching the embed character and the endOffset would be 5.</li>
+   <li>the startOffset for the "two" object would be 0, and the endOffset would be 3</li>
+   </ul>
+   Selection offsets are that of the character logically following it, e.g.
+   to the right of it in a left to right language or to the left of it in a right to left language.
    @param [in] selectionIndex
     Index of selection (0 based).
    @param [out] startOffset
@@ -2274,8 +2599,7 @@
    @param [out] endOffset
     0 based offset of one past the last selected character.
    @retval S_OK
-   @retval S_FALSE if there is nothing to return, [out] values are 0s 
-   @retval E_INVALIDARG if bad [in] passed, [out] values are 0s 
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT selection
     (
@@ -2288,12 +2612,12 @@
 
    The substring starts with the character at startOffset (inclusive) and up to 
     the character at endOffset (exclusive), if startOffset is less or equal 
-    endOffste.  If endOffset is lower than startOffset, the result is the same 
+    endOffset.  If endOffset is lower than startOffset, the result is the same 
     as a call with the two arguments being exchanged.
 
    The whole text can be requested by passing the indices zero and 
     IAccessibleText::nCharacters. If both indices have the same value, an empty 
-	string is returned.
+    string is returned.
    @param [in] startOffset
     Index of the first character to include in the returned string. The valid range 
     is 0..length.
@@ -2305,9 +2629,13 @@
     and up to the character at endOffset (exclusive), if startOffset is less than 
     or equal to endOffset.
    @retval S_OK
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL
-   @note The returned string may be longer than endOffset-startOffset bytes if text 
-   contains multi-byte characters.
+   @retval E_INVALIDARG if bad [in] passed
+   @note
+   @li The returned string may be longer than endOffset-startOffset bytes if text 
+    contains multi-byte characters.
+   @li Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleText methods.
   */
   [propget] HRESULT text
     (
@@ -2326,15 +2654,19 @@
    For example, if text type is ::IA2_TEXT_BOUNDARY_WORD, then the complete 
     word that is closest to and located before offset is returned.
 
-   If the index is valid, but no suitable word (or other boundary type) is found, a
-    NULL pointer is returned.
+   If the index is valid, but no text is found, S_FALSE is returned along with out
+    values of 0, 0, and a NULL pointer.  This would happen for boundary types other
+    than character when the text consists entirely of whitespace.
 
    @param [in] offset
     Index of the character for which to return the text part before it.  The index 
     character will not be part of the returned string. The valid range is 0..length.
+    Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleText methods.
    @param [in] boundaryType
     The type of the text portion to return.  See ::IA2TextBoundaryType for the 
-	complete list.
+    complete list.
    @param [out] startOffset
     0 based offset of first character.
    @param [out] endOffset
@@ -2345,8 +2677,8 @@
    @retval S_OK
    @retval S_FALSE if the requested boundary type is not implemented, such as 
     ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return; 
-	[out] values are 0s and NULL respectively 
-   @retval E_INVALIDARG if bad [in] passed, [out] values are 0s and NULL respectively 
+    [out] values are 0s and NULL respectively 
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT textBeforeOffset
     (
@@ -2367,12 +2699,16 @@
    For example, if text type is ::IA2_TEXT_BOUNDARY_WORD, then the complete 
     word that is closest to and located after offset is returned.
 
-   If the index is valid, but no suitable word (or other text type) is found, a 
-    NULL pointer is returned.
+   If the index is valid, but no text is found, S_FALSE is returned along with out
+    values of 0, 0, and a NULL pointer.  This would happen for boundary types other
+    than character when the text consists entirely of whitespace.
 
    @param [in] offset
-    Index of the character for which to return the text part before it.  The index 
+    Index of the character for which to return the text part after it.  The index 
     character will not be part of the returned string. The valid range is 0..length.
+    Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleText methods.
    @param [in] boundaryType
     The type of the text portion to return.  See ::IA2TextBoundaryType for the complete 
     list.
@@ -2386,8 +2722,8 @@
    @retval S_OK
    @retval S_FALSE if the requested boundary type is not implemented, such as 
     ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return; 
-	[out] values are 0s and NULL respectively 
-   @retval E_INVALIDARG if bad [in] passed, [out] values are 0s and NULL respectively 
+    [out] values are 0s and NULL respectively 
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT textAfterOffset
     (
@@ -2399,15 +2735,26 @@
     );
 
   /** @brief Returns a text portion that spans the given position.
-    
-   Returns the substring of the specified text type at the specified offset.
 
-   If the index is valid, but no suitable word (or other text type) is found, a 
-    NULL pointer is returned.
+   Returns the substring defined by the specified boundary type at the specified
+    offset.  Refer to IA2TextBoundaryType for more details.
+
+   For the word boundary type the returned string will contain the word at the
+    offset if the offset is inside a word and will contain the word before the
+    offset if the offset is not inside a word.  All offsets from the first to the
+    last characters of a word are considered inside the word.  Boundary types of
+    sentence and paragraph should exhibit similar behavior.
+
+   If the index is valid, but no text is found, S_FALSE is returned along with out
+    values of 0, 0, and a NULL pointer.  This would happen for boundary types other
+    than character when the text consists entirely of whitespace.
 
    @param [in] offset
-    Index of the character for which to return the text part before it.  The index 
-    character will not be part of the returned string. The valid range is 0..length.
+    Index of the character for which to return the text part it belongs to.  The valid
+    range is 0..length.
+    Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleText methods.
    @param [in] boundaryType
     The type of the text portion to return.  See ::IA2TextBoundaryType for the complete 
     list.
@@ -2421,8 +2768,8 @@
    @retval S_OK
    @retval S_FALSE if the requested boundary type is not implemented, such as 
     ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return; 
-	[out] values are 0s and NULL respectively 
-   @retval E_INVALIDARG if bad [in] passed, [out] values are 0s and NULL respectively 
+    [out] values are 0s and NULL respectively 
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT textAtOffset
     (
@@ -2460,7 +2807,9 @@
     The new index of the caret.  This caret is actually placed to the left side of 
     the character with that index.  An index of 0 places the caret so that the next 
     insertion goes before the first character.  An index of IAccessibleText::nCharacters 
-	leads to insertion after the last character.
+    leads to insertion after the last character.  Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleText methods.
    @retval S_OK
    @retval E_FAIL if the caret cannot be set
    @retval E_INVALIDARG if bad [in] passed
@@ -2479,6 +2828,9 @@
     New ending offset (0 based) - the offset of the character just past the last character of the selection.
    @retval S_OK
    @retval E_INVALIDARG if bad [in] passed
+   @note Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleText methods.
   */
   HRESULT setSelection
     (
@@ -2508,12 +2860,15 @@
     Defines where the object should be placed on the screen.
    @retval S_OK
    @retval E_INVALIDARG if bad [in] passed
+   @note Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleText methods.
   */
   HRESULT scrollSubstringTo
     (
      [in] long startIndex,
      [in] long endIndex,
-	 [in] enum IA2ScrollType scrollType
+     [in] enum IA2ScrollType scrollType
     );
 
   /** @brief Moves the top left of a substring to a specified location.
@@ -2531,14 +2886,17 @@
    @retval S_OK
    @retval S_FALSE if the object is already at the specified location.
    @retval E_INVALIDARG if bad [in] passed
+   @note Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleText methods.
   */
   HRESULT scrollSubstringToPoint
     (
      [in] long startIndex,
      [in] long endIndex,
      [in] enum IA2CoordinateType coordinateType,
-	 [in] long x,
-	 [in] long y 
+     [in] long x,
+     [in] long y 
     );
 
   /** @brief Returns any inserted text.
@@ -2560,12 +2918,14 @@
    @param [out] newText
     The text that was just inserted.
    @retval S_OK
-   @retval S_FALSE if there is nothing to return, [out] value is NULL
+   @retval S_FALSE If there is nothing to return, the values of IA2TextSegment
+    struct are set as follows:  text = NULL, start = 0, end = 0.
+
   */
   [propget] HRESULT newText
     (
-	 [out, retval] IA2TextSegment *newText
-	);
+     [out, retval] IA2TextSegment *newText
+    );
 
   /** @brief Returns any removed text.
 
@@ -2585,21 +2945,22 @@
    @param [out] oldText
     The text that was just removed.
    @retval S_OK
-   @retval S_FALSE if there is nothing to return, [out] value is NULL
+   @retval S_FALSE If there is nothing to return, the values of IA2TextSegment
+    struct are set as follows:  text = NULL, start = 0, end = 0.
   */
   [propget] HRESULT oldText
     (
-	 [out, retval] IA2TextSegment *oldText
-	);
+     [out, retval] IA2TextSegment *oldText
+    );
 
 }
 /*************************************************************************
  *
- *  File Name (AccessibleEditableText.idl)
+ *  File Name (AccessibleText2.idl)
  * 
  *  IAccessible2 IDL Specification 
  * 
- *  Copyright (c) 2007, 2010 Linux Foundation 
+ *  Copyright (c) 2007, 2013 Linux Foundation 
  *  Copyright (c) 2006 IBM Corporation 
  *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
  *  All rights reserved. 
@@ -2646,9 +3007,107 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
+
+
+
+/** @brief This interface gives read-only access to text.
+
+ The %IAccessibleText2 interface extends the functionality of the
+ %IAccessibleText interface.
+*/
+[object, uuid(9690A9CC-5C80-4DF5-852E-2D5AE4189A54)]
+interface IAccessibleText2 : IAccessibleText
+{
+
+  /** @brief Returns the range and of the specified set of attributes.
+
+   Return the range (start and end offsets) and text attributes that correspond
+    to the given attributes filter at the given offset.
+
+   @param [in] offset
+    The offset at which to search for the attributes specified in the filter.
+   @param [in] filter
+    The requested attribute names.  The filter format is "attribute1, attribute2".
+   @param [out] startOffset
+    The starting (0-based) offset of the text containing the specified attributes.
+   @param [out] endOffset
+    The (0-based) offset one past the last character of the text containing the
+    specified attributes.
+   @param [out] attributeValues
+    The values of the requested attributes.
+   @retval S_OK
+   @retval S_FALSE if nothing to return, [out] values are -1, -1, NULL respectively.
+   @retval E_INVALIDARG if bad [in] passed.
+   */
+  [propget] HRESULT attributeRange
+    (
+     [in] long offset,
+     [in] BSTR filter,
+     [out] long *startOffset,
+     [out] long *endOffset,	
+     [out, retval] BSTR *attributeValues
+    );
+
+}
+/*************************************************************************
+ *
+ *  File Name (AccessibleEditableText.idl)
+ * 
+ *  IAccessible2 IDL Specification 
+ * 
+ *  Copyright (c) 2007, 2012 Linux Foundation 
+ *  Copyright (c) 2006 IBM Corporation 
+ *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
+ *  All rights reserved. 
+ *   
+ *   
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met: 
+ *   
+ *   1. Redistributions of source code must retain the above copyright 
+ *      notice, this list of conditions and the following disclaimer. 
+ *   
+ *   2. Redistributions in binary form must reproduce the above 
+ *      copyright notice, this list of conditions and the following 
+ *      disclaimer in the documentation and/or other materials 
+ *      provided with the distribution. 
+ *
+ *   3. Neither the name of the Linux Foundation nor the names of its 
+ *      contributors may be used to endorse or promote products 
+ *      derived from this software without specific prior written 
+ *      permission. 
+ *   
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ *  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+ *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+ *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *   
+ *  This BSD License conforms to the Open Source Initiative "Simplified 
+ *  BSD License" as published at: 
+ *  http://www.opensource.org/licenses/bsd-license.php 
+ *   
+ *  IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 
+ *  mark may be used in accordance with the Linux Foundation Trademark 
+ *  Policy to indicate compliance with the IAccessible2 specification. 
+ * 
+ ************************************************************************/ 
+
+
+
+
 
 
 /** @brief This interface provides clipboard capability to text objects.
@@ -2676,8 +3135,8 @@
 
   /** @brief Copies the text range into the clipboard.
     
-   The specified text between the two given indices is copied into the
-    system clipboard.  
+   The selection is set to the specified offsets and then selection is copied into
+   the system clipboard.
         
    @param [in] startOffset
     Start index of the text to moved into the clipboard.
@@ -2687,6 +3146,11 @@
     The valid range is 0..length.
    @retval S_OK
    @retval E_INVALIDARG if bad [in] passed
+   @note Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleEditableText
+    methods.
+   @deprecated This function is available via the application's GUI.
   */
   HRESULT copyText
     (
@@ -2707,6 +3171,10 @@
     The valid range is 0..length.
    @retval S_OK
    @retval E_INVALIDARG if bad [in] passed
+   @note Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleEditableText
+    methods.
   */
   HRESULT deleteText
     (
@@ -2722,6 +3190,10 @@
    @param [in] offset
     Index at which to insert the text.
     The valid range is 0..length.
+	Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleEditableText
+    methods.
    @param [in] text
     Text that is inserted.
    @retval S_OK
@@ -2735,8 +3207,8 @@
   
   /** @brief Deletes a range of text and copies it to the clipboard.
     
-   The text between the two given indices is deleted from the text
-    represented by this object and copied to the clipboard.
+   The selection is set to the specified offsets, the selection is then copied into
+    the system clipboard, and then the selection is deleted.
 
    @param [in] startOffset
     Start index of the text to be deleted.
@@ -2746,6 +3218,11 @@
     The valid range is 0..length.
    @retval S_OK
    @retval E_INVALIDARG if bad [in] passed
+   @note Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleEditableText
+    methods.
+   @deprecated This function is available via the application's GUI.
   */
   HRESULT cutText
     (
@@ -2753,19 +3230,25 @@
      [in] long endOffset
     );
 
-  /** @brief Pastes text from the clipboard.
+  /** @brief Pastes content from the clipboard.
     
-   The text in the system clipboard is pasted into the text represented
-    by this object at the given index.  This method is similar to the 
-	IAccessibleEditableText::insertText method. If the index is not valid 
-	the system clipboard text is not inserted.
-   
+   Any existing selection is removed, the clipboard content is then pasted into 
+    this object's text at the given offset.  This method is similar to the insertText
+    method.  If the index is not valid the system clipboard content is not inserted. The
+    behavior is the same as	when Ctrl+V is used, i.e. the pasted contents are not
+    necessarily plain text.
+  
    @param [in] offset
-    Index at which to insert the text from the system clipboard into
+    Index at which to insert the content from the system clipboard into
     the text represented by this object.
     The valid range is 0..length.
+	Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleEditableText
+    methods.
    @retval S_OK
    @retval E_INVALIDARG if bad [in] passed
+   @deprecated This function is available via the application's GUI.
   */
   HRESULT pasteText
     (
@@ -2784,12 +3267,16 @@
     Start index of the text to be replaced.
     The valid range is 0..length.
    @param [in] endOffset
-    Start index of the text to be replaced.
+    End index of the text to be replaced.
     The valid range is 0..length.
    @param [in] text
     The Text that replaces the text between the given indices.
    @retval S_OK
    @retval E_INVALIDARG if bad [in] passed
+   @note Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleEditableText
+    methods.
   */
   HRESULT replaceText
     (
@@ -2807,13 +3294,17 @@
     Start index of the text whose attributes are modified.
     The valid range is 0..length.
    @param [in] endOffset
-    Start index of the text whose attributes are modified.
+    End index of the text whose attributes are modified.
     The valid range is 0..length.
    @param [in] attributes
     Set of attributes that replaces the old list of attributes of
     the specified text portion.
    @retval S_OK
    @retval E_INVALIDARG if bad [in] passed
+   @note Refer to @ref _specialOffsets 
+    "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" 
+    for information about special offsets that can be used in %IAccessibleEditableText
+    methods.
   */
   HRESULT setAttributes
     (
@@ -2876,9 +3367,9 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
 
 
 /** @brief This interface represents hyperlinks.
@@ -2936,8 +3427,7 @@
 	an IUnknown VARIANT for IAccessibleImage.  See the section about 
 	@ref _variants "VARIANTs" for additional information.
    @retval S_OK
-   @retval S_FALSE if there is nothing to return, [out] value is NULL 
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL 
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT anchor
     (
@@ -2958,8 +3448,7 @@
 	activated when the link is activated.  See the section about 
 	@ref _variants "VARIANTs" for additional information.
    @retval S_OK
-   @retval S_FALSE if there is nothing to return, [out] value is NULL 
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL 
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT anchorTarget
     (
@@ -2999,12 +3488,13 @@
    This has also been used to indicate whether or not the URI of the anchorTarget
    is malformed.
 
-   Note: This method is not being used, is deprecated, and should not be implemented or
-   used.  It is likely that this method will be removed in a later version of the IDL.
-
    @param [out] valid
+    If false, one or more of the object's links are invalid.
+	If true, all of the object's links are valid.
    @retval S_OK
-   @retval S_FALSE if there is nothing to return, [out] value is FALSE 
+   @retval S_FALSE if there is nothing to return, [out] value is FALSE
+   @note This method is not being used, is deprecated, and should not be implemented or
+    used.  It is likely that this method will be removed in a later version of the IDL.
   */
   [propget] HRESULT valid
     (
@@ -3064,9 +3554,9 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
 
 
 
@@ -3104,7 +3594,7 @@
     of links minus one, a reference to the specified hyperlink object is returned.  
     If the index is invalid then a NULL pointer is returned.
    @retval S_OK
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL 
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT hyperlink
     (
@@ -3125,7 +3615,7 @@
 	character index, or -1 if charIndex is not on a link.
    @retval S_OK
    @retval S_FALSE if there is nothing to return, [out] value is -1
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL 
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT hyperlinkIndex
     (
@@ -3136,11 +3626,11 @@
 }
 /*************************************************************************
  *
- *  File Name (AccessibleTable.idl)
+ *  File Name (AccessibleHypertext2.idl)
  * 
  *  IAccessible2 IDL Specification 
  * 
- *  Copyright (c) 2007, 2010 Linux Foundation 
+ *  Copyright (c) 2007, 2013 Linux Foundation 
  *  Copyright (c) 2006 IBM Corporation 
  *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
  *  All rights reserved. 
@@ -3187,9 +3677,96 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
+
+
+
+/** @brief This interface exposes information about hypertext in a document.
+
+ The %IAccessibleHypertext2 interface extends the functinality of the
+ %IAccessibleHypertext inteface.
+*/
+[object, uuid(CF64D89F-8287-4B44-8501-A827453A6077)]
+interface IAccessibleHypertext2 : IAccessibleHypertext
+{
+
+ /** @brief Returns the links for this object.
+
+   The returned IAccessibleHyperlink objects encapsulate the hyperlink and 
+    provides several kinds of information describing it.
+
+   @param [out] hyperlinks
+    This array is allocated by the server.  The client must free it with CoTaskMemFree.
+   @param [out] nHyperlinks
+    The number of links returned; the size of the returned array.
+   @retval S_OK
+   @retval S_FALSE if there are no links, [out] values are NULL and 0 respectively
+  */
+  [propget] HRESULT hyperlinks
+    (
+     [out, size_is(,*nHyperlinks)] IAccessibleHyperlink ***hyperlinks,
+     [out, retval] long *nHyperlinks
+    );
+
+}
+/*************************************************************************
+ *
+ *  File Name (AccessibleTable.idl)
+ * 
+ *  IAccessible2 IDL Specification 
+ * 
+ *  Copyright (c) 2007, 2013 Linux Foundation 
+ *  Copyright (c) 2006 IBM Corporation 
+ *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
+ *  All rights reserved. 
+ *   
+ *   
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met: 
+ *   
+ *   1. Redistributions of source code must retain the above copyright 
+ *      notice, this list of conditions and the following disclaimer. 
+ *   
+ *   2. Redistributions in binary form must reproduce the above 
+ *      copyright notice, this list of conditions and the following 
+ *      disclaimer in the documentation and/or other materials 
+ *      provided with the distribution. 
+ *
+ *   3. Neither the name of the Linux Foundation nor the names of its 
+ *      contributors may be used to endorse or promote products 
+ *      derived from this software without specific prior written 
+ *      permission. 
+ *   
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ *  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+ *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+ *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *   
+ *  This BSD License conforms to the Open Source Initiative "Simplified 
+ *  BSD License" as published at: 
+ *  http://www.opensource.org/licenses/bsd-license.php 
+ *   
+ *  IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 
+ *  mark may be used in accordance with the Linux Foundation Trademark 
+ *  Policy to indicate compliance with the IAccessible2 specification. 
+ * 
+ ************************************************************************/ 
+
+
+
+
 
 
 
@@ -3473,7 +4050,7 @@
 	"Special Consideration when using Arrays" for more details.
    @param [out] children
     An array of cell indexes of selected cells (each index is 0 based), 
-	allocated by the server. Free it with CoTaskMemFree.
+	allocated by the server. The client must free it with CoTaskMemFree.
    @param [out] nChildren
     The number of cell indexes returned; the size of the returned array.
    @retval S_OK
@@ -3492,7 +4069,7 @@
 	"Special Consideration when using Arrays" for more details.
    @param [out] columns
 	An array of column indexes of selected columns (each index is 0 based), allocated
-	by the server. Free it with CoTaskMemFree.
+	by the server. The client must free it with CoTaskMemFree.
    @param [out] nColumns
     The number of column indexes returned; the size of the returned array.
    @retval S_OK
@@ -3511,7 +4088,7 @@
 	"Special Consideration when using Arrays" for more details.
    @param [out] rows
     An array of row indexes of selected rows (each index is 0 based), allocated
-	by the server. Free it with CoTaskMemFree.
+	by the server. The client must free it with CoTaskMemFree.
    @param [out] nRows
     The number of row indexes returned; the size of the returned array.
    @retval S_OK
@@ -3691,7 +4268,7 @@
  * 
  *  IAccessible2 IDL Specification 
  * 
- *  Copyright (c) 2007, 2010 Linux Foundation 
+ *  Copyright (c) 2007, 2012 Linux Foundation 
  *  Copyright (c) 2006 IBM Corporation 
  *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
  *  All rights reserved. 
@@ -3738,9 +4315,9 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
 
 
 
@@ -3766,7 +4343,7 @@
     object is returned that represents the requested cell regardless of whether 
     the cell is currently visible (on the screen).
    @retval S_OK
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL 
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT cellAt
     (
@@ -3781,7 +4358,8 @@
     If the table has a caption then a reference to it is returned, else a NULL 
     pointer is returned.
    @retval S_OK
-   @retval S_FALSE if there is nothing to return, [out] value is NULL 
+   @retval S_FALSE if there is nothing to return, [out] value is NULL
+   @deprecated use a describedBy relation
   */
   [propget] HRESULT caption
     (
@@ -3796,7 +4374,7 @@
     description exists.  Otherwise a NULL pointer is returned.
    @retval S_OK
    @retval S_FALSE if there is nothing to return, [out] value is NULL 
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT columnDescription
     (
@@ -3863,7 +4441,7 @@
     description exists.  Otherwise a NULL pointer is returned.
    @retval S_OK
    @retval S_FALSE if there is nothing to return, [out] value is NULL 
-   @retval E_INVALIDARG if bad [in] passed, [out] value is NULL
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT rowDescription
     (
@@ -3874,7 +4452,8 @@
   /** @brief Returns a list of accessibles currently selected.
    @param [out] cells
     Pointer to an array of references to selected accessibles.  The array is
-    allocated by the server.  Free it with CoTaskMemFree.
+    allocated by the server with CoTaskMemAlloc and freed by the client with
+    CoTaskMemFree.
    @param [out] nSelectedCells
     The number of accessibles returned; the size of the returned array.
    @retval S_OK
@@ -3882,14 +4461,15 @@
   */
   [propget] HRESULT selectedCells
     (
-     [out, size_is(,*nSelectedCells,)] IUnknown ***cells,
+     [out, size_is(,*nSelectedCells)] IUnknown ***cells,
      [out, retval] long *nSelectedCells
     );
 
   /** @brief Returns a list of column indexes currently selected (0 based).
    @param [out] selectedColumns
     A pointer to an array of column indexes of selected columns (each index is
-    0 based).  The array is allocated by the server. Free it with CoTaskMemFree.
+    0 based).  The array is allocated by the server with CoTaskMemAlloc and
+    freed by the client with CoTaskMemFree.
    @param [out] nColumns
     The number of column indexes returned; the size of the returned array.
    @retval S_OK
@@ -3903,8 +4483,9 @@
 
   /** @brief Returns a list of row indexes currently selected (0 based).
    @param [out] selectedRows
-    An array of row indexes of selected rows (each index is 0 based), allocated
-    by the server. Free it with CoTaskMemFree.
+    An array of row indexes of selected rows (each index is 0 based).  The array
+    is allocated by the server with CoTaskMemAlloc and freed by the client with
+    CoTaskMemFree.
    @param [out] nRows
     The number of row indexes returned; the size of the returned array.
    @retval S_OK
@@ -3923,7 +4504,8 @@
     representing the table's summary or a NULL pointer if the table 
     does not support a summary.
    @retval S_OK
-   @retval S_FALSE if there is nothing to return, [out] value is NULL 
+   @retval S_FALSE if there is nothing to return, [out] value is NULL
+   @deprecated Use the labeledBy relation
   */
   [propget] HRESULT summary
     (
@@ -3937,7 +4519,7 @@
    @param [out] isSelected
     Returns TRUE if the specified column is selected completely and FALSE otherwise.
    @retval S_OK
-   @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT isColumnSelected
     (
@@ -3952,7 +4534,7 @@
    @param [out] isSelected
     Returns TRUE if the specified row is selected completely and FALSE otherwise.
    @retval S_OK
-   @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE
+   @retval E_INVALIDARG if bad [in] passed
   */
   [propget] HRESULT isRowSelected
     (
@@ -4063,7 +4645,7 @@
  * 
  *  IAccessible2 IDL Specification 
  * 
- *  Copyright (c) 2007, 2010 Linux Foundation 
+ *  Copyright (c) 2007, 2013 Linux Foundation 
  *  Copyright (c) 2006 IBM Corporation 
  *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
  *  All rights reserved. 
@@ -4110,9 +4692,9 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
 
 
 /** @brief This interface gives access to the cells of a two-dimensional table.
@@ -4140,7 +4722,7 @@
 
    @param [out] cellAccessibles
     Pointer to an array of references to cell accessibles.  The array is allocated
-	by the server.  Free it with CoTaskMemFree.
+	by the server.  The client must free it with CoTaskMemFree.
    @param [out] nColumnHeaderCells
     The number of accessibles returned; the size of the returned array.
    @retval S_OK
@@ -4148,7 +4730,7 @@
   */
   [propget] HRESULT columnHeaderCells
     (
-     [out, size_is(,*nColumnHeaderCells,)] IUnknown ***cellAccessibles,
+     [out, size_is(,*nColumnHeaderCells)] IUnknown ***cellAccessibles,
      [out, retval] long *nColumnHeaderCells
     );
 
@@ -4179,7 +4761,7 @@
 
    @param [out] cellAccessibles
     Pointer to an array of references to cell accessibles.  The array is allocated
-	by the server.  Free it with CoTaskMemFree.
+	by the server.  The client must free it with CoTaskMemFree.
    @param [out] nRowHeaderCells
     The number of accessibles returned; the size of the returned array.
    @retval S_OK
@@ -4187,7 +4769,7 @@
   */
   [propget] HRESULT rowHeaderCells
     (
-     [out, size_is(,*nRowHeaderCells,)] IUnknown ***cellAccessibles,
+     [out, size_is(,*nRowHeaderCells)] IUnknown ***cellAccessibles,
      [out, retval] long *nRowHeaderCells
     );
 
@@ -4304,9 +4886,9 @@
  * 
  ************************************************************************/ 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
 
 
 /** @brief This interface represents images and icons.
@@ -4427,7 +5009,7 @@
   */
   IA2_EVENT_ACTION_CHANGED = 0x101,
 
-  /** The active descendant of a component has changed.
+  /** <b>Deprecated.</b> The active descendant of a component has changed.
 	
 	Note: This event constant is misspelled and thus is deprecated and will be
 	removed in a later version. Please use the correctly spelled version which
@@ -4646,9 +5228,9 @@
  ************************************************************************/ 
 
 
-import "objidl.idl";
-import "oaidl.idl";
-import "oleacc.idl";
+
+
+
 
 /** @brief This interface gives access to the application's name and version information.
         
@@ -4677,6 +5259,9 @@
 
   /** @brief Returns the application version.
    @param [out] version
+    The version string must not contain levels when it is know beforehand that
+    this information will never require a change in a client's behavior.
+    For example, use "3.6.0" rather than "3.6.0.v201005131500".
    @retval S_OK
    @retval S_FALSE if there is nothing to return, [out] value is NULL
   */
@@ -4697,6 +5282,9 @@
 
   /** @brief Returns the toolkit/bridge version.
    @param [out] version
+    The version string must not contain levels when it is know beforehand that
+    this information will never require a change in a client's behavior.
+    For example, use "3.6.0" rather than "3.6.0.v201005131500".
    @retval S_OK
    @retval S_FALSE if there is nothing to return, [out] value is NULL
   */
@@ -4709,11 +5297,89 @@
 
 /*************************************************************************
  *
+ *  File Name (AccessibleDocument.idl)
+ * 
+ *  IAccessible2 IDL Specification 
+ * 
+ *  Copyright (c) 2013 Linux Foundation 
+ *  All rights reserved. 
+ *   
+ *   
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions 
+ *  are met: 
+ *   
+ *   1. Redistributions of source code must retain the above copyright 
+ *      notice, this list of conditions and the following disclaimer. 
+ *   
+ *   2. Redistributions in binary form must reproduce the above 
+ *      copyright notice, this list of conditions and the following 
+ *      disclaimer in the documentation and/or other materials 
+ *      provided with the distribution. 
+ *
+ *   3. Neither the name of the Linux Foundation nor the names of its 
+ *      contributors may be used to endorse or promote products 
+ *      derived from this software without specific prior written 
+ *      permission. 
+ *   
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ *  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+ *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+ *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *   
+ *  This BSD License conforms to the Open Source Initiative "Simplified 
+ *  BSD License" as published at: 
+ *  http://www.opensource.org/licenses/bsd-license.php 
+ *   
+ *  IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 
+ *  mark may be used in accordance with the Linux Foundation Trademark 
+ *  Policy to indicate compliance with the IAccessible2 specification. 
+ * 
+ ************************************************************************/ 
+
+
+
+
+
+/** @brief This interface represents documents.
+
+ This interface is used for a representation of documents.
+*/
+[object, uuid(C48C7FCF-4AB5-4056-AFA6-902D6E1D1149)]
+interface IAccessibleDocument : IUnknown
+{
+  /** @brief Returns the most recently used anchor target within a document.
+  
+   A document's most recently targeted in-page anchor is returned.  A typical use
+    of this method is to fetch the anchor target within an HTML document.  In this
+    case anchor targets are those which have been defined with the &lt;a&gt; tag.  
+
+   @param [out] accessible
+   @retval S_OK
+   @retval S_FALSE if there are no existing valid anchor targets, [out] value is NULL.
+  */
+  [propget] HRESULT anchorTarget
+    (
+     [out, retval] IUnknown **accessible
+    );
+
+}
+/*************************************************************************
+ *
  *  File Name (IA2TypeLibrary.idl)
  * 
  *  IAccessible2 IDL Specification 
  * 
- *  Copyright (c) 2007, 2010 Linux Foundation 
+ *  Copyright (c) 2007, 2012 Linux Foundation 
  *  Copyright (c) 2006 IBM Corporation 
  *  Copyright (c) 2000, 2006 Sun Microsystems, Inc. 
  *  All rights reserved. 
@@ -4768,28 +5434,33 @@
 cpp_quote("")
 
 [
-    uuid(c974e070-3787-490a-87b0-e333b06ca1e2),
+    uuid(CE3F726E-D1D3-44FE-B995-FF1DB3B48B2B),
     helpstring("IAccessible2 Type Library"),
-    version(1.2),
+    version(1.3),
     hidden
 ]
 
 library IAccessible2Lib
 {
     importlib ("stdole2.tlb");
+    importlib ("oleacc.dll");
     interface IAccessible2;
+    interface IAccessible2_2;
     interface IAccessibleAction;
     interface IAccessibleApplication;
     interface IAccessibleComponent;
+    interface IAccessibleDocument;
     interface IAccessibleEditableText;
     interface IAccessibleHyperlink;
     interface IAccessibleHypertext;
+    interface IAccessibleHypertext2;
     interface IAccessibleImage;
     interface IAccessibleRelation;
     interface IAccessibleTable;
     interface IAccessibleTable2;
     interface IAccessibleTableCell;
     interface IAccessibleText;
+    interface IAccessibleText2;
     interface IAccessibleValue;
     enum IA2CoordinateType;
     enum IA2EventID;
diff --git a/third_party/iccjpeg/iccjpeg.target.darwin-arm.mk b/third_party/iccjpeg/iccjpeg.target.darwin-arm.mk
index f9c1c8c..205e268 100644
--- a/third_party/iccjpeg/iccjpeg.target.darwin-arm.mk
+++ b/third_party/iccjpeg/iccjpeg.target.darwin-arm.mk
@@ -40,7 +40,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -128,7 +127,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/iccjpeg/iccjpeg.target.darwin-x86.mk b/third_party/iccjpeg/iccjpeg.target.darwin-x86.mk
index a89d8b6..2263ae7 100644
--- a/third_party/iccjpeg/iccjpeg.target.darwin-x86.mk
+++ b/third_party/iccjpeg/iccjpeg.target.darwin-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/iccjpeg/iccjpeg.target.darwin-x86_64.mk b/third_party/iccjpeg/iccjpeg.target.darwin-x86_64.mk
index 1822d2b..ea7bbe8 100644
--- a/third_party/iccjpeg/iccjpeg.target.darwin-x86_64.mk
+++ b/third_party/iccjpeg/iccjpeg.target.darwin-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/iccjpeg/iccjpeg.target.linux-arm.mk b/third_party/iccjpeg/iccjpeg.target.linux-arm.mk
index f9c1c8c..205e268 100644
--- a/third_party/iccjpeg/iccjpeg.target.linux-arm.mk
+++ b/third_party/iccjpeg/iccjpeg.target.linux-arm.mk
@@ -40,7 +40,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -128,7 +127,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/iccjpeg/iccjpeg.target.linux-x86.mk b/third_party/iccjpeg/iccjpeg.target.linux-x86.mk
index a89d8b6..2263ae7 100644
--- a/third_party/iccjpeg/iccjpeg.target.linux-x86.mk
+++ b/third_party/iccjpeg/iccjpeg.target.linux-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/iccjpeg/iccjpeg.target.linux-x86_64.mk b/third_party/iccjpeg/iccjpeg.target.linux-x86_64.mk
index 1822d2b..ea7bbe8 100644
--- a/third_party/iccjpeg/iccjpeg.target.linux-x86_64.mk
+++ b/third_party/iccjpeg/iccjpeg.target.linux-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -130,7 +129,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/leveldatabase/README.chromium b/third_party/leveldatabase/README.chromium
index 3d7b021..6a64e01 100644
--- a/third_party/leveldatabase/README.chromium
+++ b/third_party/leveldatabase/README.chromium
@@ -1,7 +1,7 @@
 Name: LevelDB: A Fast Persistent Key-Value Store
 Short Name: leveldb
 URL: http://code.google.com/p/leveldb/
-Version: r79
+Version: r80
 License: New BSD
 License File: src/LICENSE
 Security Critical: yes
diff --git a/third_party/leveldatabase/leveldatabase.target.darwin-arm.mk b/third_party/leveldatabase/leveldatabase.target.darwin-arm.mk
index f7cb3a3..5d1571e 100644
--- a/third_party/leveldatabase/leveldatabase.target.darwin-arm.mk
+++ b/third_party/leveldatabase/leveldatabase.target.darwin-arm.mk
@@ -77,7 +77,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -170,7 +169,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/leveldatabase/leveldatabase.target.darwin-x86.mk b/third_party/leveldatabase/leveldatabase.target.darwin-x86.mk
index 76ddae3..532cfe0 100644
--- a/third_party/leveldatabase/leveldatabase.target.darwin-x86.mk
+++ b/third_party/leveldatabase/leveldatabase.target.darwin-x86.mk
@@ -79,7 +79,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -172,7 +171,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/leveldatabase/leveldatabase.target.darwin-x86_64.mk b/third_party/leveldatabase/leveldatabase.target.darwin-x86_64.mk
index 7084ead..2e005d5 100644
--- a/third_party/leveldatabase/leveldatabase.target.darwin-x86_64.mk
+++ b/third_party/leveldatabase/leveldatabase.target.darwin-x86_64.mk
@@ -79,7 +79,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -172,7 +171,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/leveldatabase/leveldatabase.target.linux-arm.mk b/third_party/leveldatabase/leveldatabase.target.linux-arm.mk
index f7cb3a3..5d1571e 100644
--- a/third_party/leveldatabase/leveldatabase.target.linux-arm.mk
+++ b/third_party/leveldatabase/leveldatabase.target.linux-arm.mk
@@ -77,7 +77,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -170,7 +169,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/leveldatabase/leveldatabase.target.linux-x86.mk b/third_party/leveldatabase/leveldatabase.target.linux-x86.mk
index 76ddae3..532cfe0 100644
--- a/third_party/leveldatabase/leveldatabase.target.linux-x86.mk
+++ b/third_party/leveldatabase/leveldatabase.target.linux-x86.mk
@@ -79,7 +79,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -172,7 +171,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/leveldatabase/leveldatabase.target.linux-x86_64.mk b/third_party/leveldatabase/leveldatabase.target.linux-x86_64.mk
index 7084ead..2e005d5 100644
--- a/third_party/leveldatabase/leveldatabase.target.linux-x86_64.mk
+++ b/third_party/leveldatabase/leveldatabase.target.linux-x86_64.mk
@@ -79,7 +79,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -172,7 +171,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libc++/libc++.gyp b/third_party/libc++/libc++.gyp
index b5f14f8..0e6fbe4 100644
--- a/third_party/libc++/libc++.gyp
+++ b/third_party/libc++/libc++.gyp
@@ -5,14 +5,52 @@
 {
   'targets': [
     {
-      'target_name': 'libc++',
-      'type': 'shared_library',
+      'target_name': 'libcxx_proxy',
+      'type': 'none',
+      'dependencies=': [
+        'libc++',
+      ],
+      # Do not add dependency on libc++.so to dependents of this target. We
+      # don't want to pass libc++.so on the command line to the linker, as that
+      # would cause it to be linked into C executables which don't need it.
+      # Instead, we supply -stdlib=libc++ and let the clang driver decide.
+      'dependencies_traverse': 0,
       'variables': {
-        'prune_self_dependency': 1,
         # Don't add this target to the dependencies of targets with type=none.
         'link_dependency': 1,
       },
+      'direct_dependent_settings': {
+        'target_conditions': [
+          ['_type!="none"', {
+            'include_dirs': [
+              'trunk/include',
+              '../libc++abi/trunk/include',
+            ],
+            'cflags_cc': [
+              '-nostdinc++',
+            ],
+            'ldflags': [
+              '-stdlib=libc++',
+              # Normally the generator takes care of RPATH. Our case is special
+              # because the generator is unaware of the libc++.so dependency.
+              # Note that setting RPATH here is a potential security issue. See:
+              # https://code.google.com/p/gyp/issues/detail?id=315
+              '-Wl,-R,\$$ORIGIN/lib/',
+            ],
+            'library_dirs': [
+              '<(PRODUCT_DIR)/lib/',
+            ],
+          }],
+        ],
+      },
+    },
+    {
+      'target_name': 'libc++',
+      'type': 'shared_library',
       'dependencies=': [
+        # libc++abi is linked statically into libc++.so. This allows us to get
+        # both libc++ and libc++abi by passing '-stdlib=libc++'. If libc++abi
+        # was a separate DSO, we'd have to link against it explicitly.
         '../libc++abi/libc++abi.gyp:libc++abi',
       ],
       'sources': [
@@ -62,22 +100,6 @@
         '-Wstrict-overflow=4',
         '-nostdinc++',
       ],
-      'direct_dependent_settings': {
-        'target_conditions': [
-          ['_type!="none"', {
-            'include_dirs': [
-              'trunk/include',
-            ],
-            'cflags_cc': [
-              '-nostdinc++',
-            ],
-            'ldflags': [
-              '-stdlib=libc++',
-              '-L<(PRODUCT_DIR)/lib/',
-            ],
-          }],
-        ],
-      },
       'cflags_cc!': [
         '-fno-rtti',
       ],
@@ -87,7 +109,6 @@
       ],
       'ldflags': [
         '-nodefaultlibs',
-        '<(PRODUCT_DIR)/lib/libc++abi.so',
       ],
       'ldflags!': [
         # This somehow causes a warning from clang about an unused compilation
diff --git a/third_party/libc++abi/libc++abi.gyp b/third_party/libc++abi/libc++abi.gyp
index 3d97735..b32ca09 100644
--- a/third_party/libc++abi/libc++abi.gyp
+++ b/third_party/libc++abi/libc++abi.gyp
@@ -6,12 +6,7 @@
   'targets': [
     {
       'target_name': 'libc++abi',
-      'type': 'shared_library',
-      'variables': {
-        'prune_self_dependency': 1,
-        # Don't add this target to the dependencies of targets with type=none.
-        'link_dependency': 1,
-      },
+      'type': 'static_library',
       'dependencies=': [],
       'sources': [
         'trunk/src/abort_message.cpp',
@@ -56,21 +51,6 @@
         '-Wnewline-eof',
         '-nostdinc++',
       ],
-      'direct_dependent_settings': {
-        'target_conditions': [
-          ['_type!="none"', {
-            'include_dirs': [
-              'trunk/include',
-            ],
-            'cflags_cc': [
-              '-nostdinc++',
-            ],
-            'ldflags': [
-              '-L<(PRODUCT_DIR)/lib/',
-            ],
-          }],
-        ],
-      },
       'cflags_cc!': [
         '-fno-rtti',
       ],
diff --git a/third_party/libevent/libevent.target.darwin-arm.mk b/third_party/libevent/libevent.target.darwin-arm.mk
index 2d04cc0..2882e3a 100644
--- a/third_party/libevent/libevent.target.darwin-arm.mk
+++ b/third_party/libevent/libevent.target.darwin-arm.mk
@@ -52,7 +52,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -140,7 +139,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libevent/libevent.target.darwin-x86.mk b/third_party/libevent/libevent.target.darwin-x86.mk
index df14f06..c205e41 100644
--- a/third_party/libevent/libevent.target.darwin-x86.mk
+++ b/third_party/libevent/libevent.target.darwin-x86.mk
@@ -54,7 +54,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libevent/libevent.target.darwin-x86_64.mk b/third_party/libevent/libevent.target.darwin-x86_64.mk
index 19bb0fe..6ff1cda 100644
--- a/third_party/libevent/libevent.target.darwin-x86_64.mk
+++ b/third_party/libevent/libevent.target.darwin-x86_64.mk
@@ -54,7 +54,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libevent/libevent.target.linux-arm.mk b/third_party/libevent/libevent.target.linux-arm.mk
index 2d04cc0..2882e3a 100644
--- a/third_party/libevent/libevent.target.linux-arm.mk
+++ b/third_party/libevent/libevent.target.linux-arm.mk
@@ -52,7 +52,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -140,7 +139,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libevent/libevent.target.linux-x86.mk b/third_party/libevent/libevent.target.linux-x86.mk
index df14f06..c205e41 100644
--- a/third_party/libevent/libevent.target.linux-x86.mk
+++ b/third_party/libevent/libevent.target.linux-x86.mk
@@ -54,7 +54,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libevent/libevent.target.linux-x86_64.mk b/third_party/libevent/libevent.target.linux-x86_64.mk
index 19bb0fe..6ff1cda 100644
--- a/third_party/libevent/libevent.target.linux-x86_64.mk
+++ b/third_party/libevent/libevent.target.linux-x86_64.mk
@@ -54,7 +54,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium
index e51a17f..d308a95 100644
--- a/third_party/libjingle/README.chromium
+++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@
 Name: libjingle
 URL: http://code.google.com/p/webrtc/
 Version: unknown
-Revision: 5963
+Revision: 6085
 License: BSD
 License File: source/talk/COPYING
 Security Critical: yes
diff --git a/third_party/libjingle/libjingle.gyp b/third_party/libjingle/libjingle.gyp
index b346576..42b136e 100644
--- a/third_party/libjingle/libjingle.gyp
+++ b/third_party/libjingle/libjingle.gyp
@@ -365,6 +365,7 @@
             '<(libjingle_source)/talk/app/webrtc/statscollector.h',
             '<(libjingle_source)/talk/app/webrtc/statstypes.h',
             '<(libjingle_source)/talk/app/webrtc/streamcollection.h',
+            '<(libjingle_source)/talk/app/webrtc/umametrics.h',
             '<(libjingle_source)/talk/app/webrtc/videosource.cc',
             '<(libjingle_source)/talk/app/webrtc/videosource.h',
             '<(libjingle_source)/talk/app/webrtc/videosourceinterface.h',
@@ -428,6 +429,8 @@
             '<(libjingle_source)/talk/media/webrtc/webrtcvoe.h',
             '<(libjingle_source)/talk/session/media/audiomonitor.cc',
             '<(libjingle_source)/talk/session/media/audiomonitor.h',
+            '<(libjingle_source)/talk/session/media/bundlefilter.cc',
+            '<(libjingle_source)/talk/session/media/bundlefilter.h',
             '<(libjingle_source)/talk/session/media/call.cc',
             '<(libjingle_source)/talk/session/media/call.h',
             '<(libjingle_source)/talk/session/media/channel.cc',
@@ -453,8 +456,6 @@
             '<(libjingle_source)/talk/session/media/soundclip.h',
             '<(libjingle_source)/talk/session/media/srtpfilter.cc',
             '<(libjingle_source)/talk/session/media/srtpfilter.h',
-            '<(libjingle_source)/talk/session/media/ssrcmuxfilter.cc',
-            '<(libjingle_source)/talk/session/media/ssrcmuxfilter.h',
             '<(libjingle_source)/talk/session/media/typingmonitor.cc',
             '<(libjingle_source)/talk/session/media/typingmonitor.h',
             '<(libjingle_source)/talk/session/media/voicechannel.h',
diff --git a/third_party/libjingle/libjingle.target.darwin-arm.mk b/third_party/libjingle/libjingle.target.darwin-arm.mk
index 46310de..a4cf91b 100644
--- a/third_party/libjingle/libjingle.target.darwin-arm.mk
+++ b/third_party/libjingle/libjingle.target.darwin-arm.mk
@@ -157,7 +157,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -274,7 +273,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libjingle/libjingle.target.darwin-x86.mk b/third_party/libjingle/libjingle.target.darwin-x86.mk
index a3050ee..3a5590a 100644
--- a/third_party/libjingle/libjingle.target.darwin-x86.mk
+++ b/third_party/libjingle/libjingle.target.darwin-x86.mk
@@ -159,7 +159,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -275,7 +274,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle.target.darwin-x86_64.mk b/third_party/libjingle/libjingle.target.darwin-x86_64.mk
index 0158c63..4ad6749 100644
--- a/third_party/libjingle/libjingle.target.darwin-x86_64.mk
+++ b/third_party/libjingle/libjingle.target.darwin-x86_64.mk
@@ -159,7 +159,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -277,7 +276,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle.target.linux-arm.mk b/third_party/libjingle/libjingle.target.linux-arm.mk
index 46310de..a4cf91b 100644
--- a/third_party/libjingle/libjingle.target.linux-arm.mk
+++ b/third_party/libjingle/libjingle.target.linux-arm.mk
@@ -157,7 +157,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -274,7 +273,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libjingle/libjingle.target.linux-x86.mk b/third_party/libjingle/libjingle.target.linux-x86.mk
index a3050ee..3a5590a 100644
--- a/third_party/libjingle/libjingle.target.linux-x86.mk
+++ b/third_party/libjingle/libjingle.target.linux-x86.mk
@@ -159,7 +159,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -275,7 +274,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle.target.linux-x86_64.mk b/third_party/libjingle/libjingle.target.linux-x86_64.mk
index 0158c63..4ad6749 100644
--- a/third_party/libjingle/libjingle.target.linux-x86_64.mk
+++ b/third_party/libjingle/libjingle.target.linux-x86_64.mk
@@ -159,7 +159,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -277,7 +276,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_p2p_constants.target.darwin-arm.mk b/third_party/libjingle/libjingle_p2p_constants.target.darwin-arm.mk
index 04e4293..c92022f 100644
--- a/third_party/libjingle/libjingle_p2p_constants.target.darwin-arm.mk
+++ b/third_party/libjingle/libjingle_p2p_constants.target.darwin-arm.mk
@@ -41,7 +41,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -157,7 +156,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libjingle/libjingle_p2p_constants.target.darwin-x86.mk b/third_party/libjingle/libjingle_p2p_constants.target.darwin-x86.mk
index 89f2876..5cebda1 100644
--- a/third_party/libjingle/libjingle_p2p_constants.target.darwin-x86.mk
+++ b/third_party/libjingle/libjingle_p2p_constants.target.darwin-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +157,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_p2p_constants.target.darwin-x86_64.mk b/third_party/libjingle/libjingle_p2p_constants.target.darwin-x86_64.mk
index aecccc7..8b837fe 100644
--- a/third_party/libjingle/libjingle_p2p_constants.target.darwin-x86_64.mk
+++ b/third_party/libjingle/libjingle_p2p_constants.target.darwin-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -160,7 +159,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_p2p_constants.target.linux-arm.mk b/third_party/libjingle/libjingle_p2p_constants.target.linux-arm.mk
index 04e4293..c92022f 100644
--- a/third_party/libjingle/libjingle_p2p_constants.target.linux-arm.mk
+++ b/third_party/libjingle/libjingle_p2p_constants.target.linux-arm.mk
@@ -41,7 +41,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -157,7 +156,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libjingle/libjingle_p2p_constants.target.linux-x86.mk b/third_party/libjingle/libjingle_p2p_constants.target.linux-x86.mk
index 89f2876..5cebda1 100644
--- a/third_party/libjingle/libjingle_p2p_constants.target.linux-x86.mk
+++ b/third_party/libjingle/libjingle_p2p_constants.target.linux-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +157,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_p2p_constants.target.linux-x86_64.mk b/third_party/libjingle/libjingle_p2p_constants.target.linux-x86_64.mk
index aecccc7..8b837fe 100644
--- a/third_party/libjingle/libjingle_p2p_constants.target.linux-x86_64.mk
+++ b/third_party/libjingle/libjingle_p2p_constants.target.linux-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -160,7 +159,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_webrtc.target.darwin-arm.mk b/third_party/libjingle/libjingle_webrtc.target.darwin-arm.mk
index 76e0acd..41671c1 100644
--- a/third_party/libjingle/libjingle_webrtc.target.darwin-arm.mk
+++ b/third_party/libjingle/libjingle_webrtc.target.darwin-arm.mk
@@ -41,7 +41,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -158,7 +157,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libjingle/libjingle_webrtc.target.darwin-x86.mk b/third_party/libjingle/libjingle_webrtc.target.darwin-x86.mk
index bf3625d..445b698 100644
--- a/third_party/libjingle/libjingle_webrtc.target.darwin-x86.mk
+++ b/third_party/libjingle/libjingle_webrtc.target.darwin-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -159,7 +158,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_webrtc.target.darwin-x86_64.mk b/third_party/libjingle/libjingle_webrtc.target.darwin-x86_64.mk
index 0f73d97..fd3192a 100644
--- a/third_party/libjingle/libjingle_webrtc.target.darwin-x86_64.mk
+++ b/third_party/libjingle/libjingle_webrtc.target.darwin-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -161,7 +160,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_webrtc.target.linux-arm.mk b/third_party/libjingle/libjingle_webrtc.target.linux-arm.mk
index 76e0acd..41671c1 100644
--- a/third_party/libjingle/libjingle_webrtc.target.linux-arm.mk
+++ b/third_party/libjingle/libjingle_webrtc.target.linux-arm.mk
@@ -41,7 +41,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -158,7 +157,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libjingle/libjingle_webrtc.target.linux-x86.mk b/third_party/libjingle/libjingle_webrtc.target.linux-x86.mk
index bf3625d..445b698 100644
--- a/third_party/libjingle/libjingle_webrtc.target.linux-x86.mk
+++ b/third_party/libjingle/libjingle_webrtc.target.linux-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -159,7 +158,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_webrtc.target.linux-x86_64.mk b/third_party/libjingle/libjingle_webrtc.target.linux-x86_64.mk
index 0f73d97..fd3192a 100644
--- a/third_party/libjingle/libjingle_webrtc.target.linux-x86_64.mk
+++ b/third_party/libjingle/libjingle_webrtc.target.linux-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -161,7 +160,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_webrtc_common.target.darwin-arm.mk b/third_party/libjingle/libjingle_webrtc_common.target.darwin-arm.mk
index 73688a8..bad77f2 100644
--- a/third_party/libjingle/libjingle_webrtc_common.target.darwin-arm.mk
+++ b/third_party/libjingle/libjingle_webrtc_common.target.darwin-arm.mk
@@ -70,6 +70,7 @@
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideocapturer.cc \
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.cc \
 	third_party/libjingle/source/talk/session/media/audiomonitor.cc \
+	third_party/libjingle/source/talk/session/media/bundlefilter.cc \
 	third_party/libjingle/source/talk/session/media/call.cc \
 	third_party/libjingle/source/talk/session/media/channel.cc \
 	third_party/libjingle/source/talk/session/media/channelmanager.cc \
@@ -82,7 +83,6 @@
 	third_party/libjingle/source/talk/session/media/rtcpmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/soundclip.cc \
 	third_party/libjingle/source/talk/session/media/srtpfilter.cc \
-	third_party/libjingle/source/talk/session/media/ssrcmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/typingmonitor.cc \
 	third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc \
 	third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc \
@@ -102,7 +102,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -243,7 +242,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libjingle/libjingle_webrtc_common.target.darwin-arm64.mk b/third_party/libjingle/libjingle_webrtc_common.target.darwin-arm64.mk
index 2254316..c9545bc 100644
--- a/third_party/libjingle/libjingle_webrtc_common.target.darwin-arm64.mk
+++ b/third_party/libjingle/libjingle_webrtc_common.target.darwin-arm64.mk
@@ -70,6 +70,7 @@
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideocapturer.cc \
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.cc \
 	third_party/libjingle/source/talk/session/media/audiomonitor.cc \
+	third_party/libjingle/source/talk/session/media/bundlefilter.cc \
 	third_party/libjingle/source/talk/session/media/call.cc \
 	third_party/libjingle/source/talk/session/media/channel.cc \
 	third_party/libjingle/source/talk/session/media/channelmanager.cc \
@@ -82,7 +83,6 @@
 	third_party/libjingle/source/talk/session/media/rtcpmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/soundclip.cc \
 	third_party/libjingle/source/talk/session/media/srtpfilter.cc \
-	third_party/libjingle/source/talk/session/media/ssrcmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/typingmonitor.cc \
 	third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc \
 	third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc \
diff --git a/third_party/libjingle/libjingle_webrtc_common.target.darwin-mips.mk b/third_party/libjingle/libjingle_webrtc_common.target.darwin-mips.mk
index e68611d..557b37a 100644
--- a/third_party/libjingle/libjingle_webrtc_common.target.darwin-mips.mk
+++ b/third_party/libjingle/libjingle_webrtc_common.target.darwin-mips.mk
@@ -70,6 +70,7 @@
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideocapturer.cc \
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.cc \
 	third_party/libjingle/source/talk/session/media/audiomonitor.cc \
+	third_party/libjingle/source/talk/session/media/bundlefilter.cc \
 	third_party/libjingle/source/talk/session/media/call.cc \
 	third_party/libjingle/source/talk/session/media/channel.cc \
 	third_party/libjingle/source/talk/session/media/channelmanager.cc \
@@ -82,7 +83,6 @@
 	third_party/libjingle/source/talk/session/media/rtcpmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/soundclip.cc \
 	third_party/libjingle/source/talk/session/media/srtpfilter.cc \
-	third_party/libjingle/source/talk/session/media/ssrcmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/typingmonitor.cc \
 	third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc \
 	third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc \
diff --git a/third_party/libjingle/libjingle_webrtc_common.target.darwin-x86.mk b/third_party/libjingle/libjingle_webrtc_common.target.darwin-x86.mk
index 68221e4..898acba 100644
--- a/third_party/libjingle/libjingle_webrtc_common.target.darwin-x86.mk
+++ b/third_party/libjingle/libjingle_webrtc_common.target.darwin-x86.mk
@@ -70,6 +70,7 @@
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideocapturer.cc \
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.cc \
 	third_party/libjingle/source/talk/session/media/audiomonitor.cc \
+	third_party/libjingle/source/talk/session/media/bundlefilter.cc \
 	third_party/libjingle/source/talk/session/media/call.cc \
 	third_party/libjingle/source/talk/session/media/channel.cc \
 	third_party/libjingle/source/talk/session/media/channelmanager.cc \
@@ -82,7 +83,6 @@
 	third_party/libjingle/source/talk/session/media/rtcpmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/soundclip.cc \
 	third_party/libjingle/source/talk/session/media/srtpfilter.cc \
-	third_party/libjingle/source/talk/session/media/ssrcmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/typingmonitor.cc \
 	third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc \
 	third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc \
@@ -104,7 +104,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -245,7 +244,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_webrtc_common.target.darwin-x86_64.mk b/third_party/libjingle/libjingle_webrtc_common.target.darwin-x86_64.mk
index 3e5f1c6..c4a8100 100644
--- a/third_party/libjingle/libjingle_webrtc_common.target.darwin-x86_64.mk
+++ b/third_party/libjingle/libjingle_webrtc_common.target.darwin-x86_64.mk
@@ -70,6 +70,7 @@
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideocapturer.cc \
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.cc \
 	third_party/libjingle/source/talk/session/media/audiomonitor.cc \
+	third_party/libjingle/source/talk/session/media/bundlefilter.cc \
 	third_party/libjingle/source/talk/session/media/call.cc \
 	third_party/libjingle/source/talk/session/media/channel.cc \
 	third_party/libjingle/source/talk/session/media/channelmanager.cc \
@@ -82,7 +83,6 @@
 	third_party/libjingle/source/talk/session/media/rtcpmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/soundclip.cc \
 	third_party/libjingle/source/talk/session/media/srtpfilter.cc \
-	third_party/libjingle/source/talk/session/media/ssrcmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/typingmonitor.cc \
 	third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc \
 	third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc \
@@ -104,7 +104,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -247,7 +246,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_webrtc_common.target.linux-arm.mk b/third_party/libjingle/libjingle_webrtc_common.target.linux-arm.mk
index 73688a8..bad77f2 100644
--- a/third_party/libjingle/libjingle_webrtc_common.target.linux-arm.mk
+++ b/third_party/libjingle/libjingle_webrtc_common.target.linux-arm.mk
@@ -70,6 +70,7 @@
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideocapturer.cc \
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.cc \
 	third_party/libjingle/source/talk/session/media/audiomonitor.cc \
+	third_party/libjingle/source/talk/session/media/bundlefilter.cc \
 	third_party/libjingle/source/talk/session/media/call.cc \
 	third_party/libjingle/source/talk/session/media/channel.cc \
 	third_party/libjingle/source/talk/session/media/channelmanager.cc \
@@ -82,7 +83,6 @@
 	third_party/libjingle/source/talk/session/media/rtcpmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/soundclip.cc \
 	third_party/libjingle/source/talk/session/media/srtpfilter.cc \
-	third_party/libjingle/source/talk/session/media/ssrcmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/typingmonitor.cc \
 	third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc \
 	third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc \
@@ -102,7 +102,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -243,7 +242,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libjingle/libjingle_webrtc_common.target.linux-arm64.mk b/third_party/libjingle/libjingle_webrtc_common.target.linux-arm64.mk
index 2254316..c9545bc 100644
--- a/third_party/libjingle/libjingle_webrtc_common.target.linux-arm64.mk
+++ b/third_party/libjingle/libjingle_webrtc_common.target.linux-arm64.mk
@@ -70,6 +70,7 @@
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideocapturer.cc \
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.cc \
 	third_party/libjingle/source/talk/session/media/audiomonitor.cc \
+	third_party/libjingle/source/talk/session/media/bundlefilter.cc \
 	third_party/libjingle/source/talk/session/media/call.cc \
 	third_party/libjingle/source/talk/session/media/channel.cc \
 	third_party/libjingle/source/talk/session/media/channelmanager.cc \
@@ -82,7 +83,6 @@
 	third_party/libjingle/source/talk/session/media/rtcpmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/soundclip.cc \
 	third_party/libjingle/source/talk/session/media/srtpfilter.cc \
-	third_party/libjingle/source/talk/session/media/ssrcmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/typingmonitor.cc \
 	third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc \
 	third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc \
diff --git a/third_party/libjingle/libjingle_webrtc_common.target.linux-mips.mk b/third_party/libjingle/libjingle_webrtc_common.target.linux-mips.mk
index e68611d..557b37a 100644
--- a/third_party/libjingle/libjingle_webrtc_common.target.linux-mips.mk
+++ b/third_party/libjingle/libjingle_webrtc_common.target.linux-mips.mk
@@ -70,6 +70,7 @@
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideocapturer.cc \
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.cc \
 	third_party/libjingle/source/talk/session/media/audiomonitor.cc \
+	third_party/libjingle/source/talk/session/media/bundlefilter.cc \
 	third_party/libjingle/source/talk/session/media/call.cc \
 	third_party/libjingle/source/talk/session/media/channel.cc \
 	third_party/libjingle/source/talk/session/media/channelmanager.cc \
@@ -82,7 +83,6 @@
 	third_party/libjingle/source/talk/session/media/rtcpmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/soundclip.cc \
 	third_party/libjingle/source/talk/session/media/srtpfilter.cc \
-	third_party/libjingle/source/talk/session/media/ssrcmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/typingmonitor.cc \
 	third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc \
 	third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc \
diff --git a/third_party/libjingle/libjingle_webrtc_common.target.linux-x86.mk b/third_party/libjingle/libjingle_webrtc_common.target.linux-x86.mk
index 68221e4..898acba 100644
--- a/third_party/libjingle/libjingle_webrtc_common.target.linux-x86.mk
+++ b/third_party/libjingle/libjingle_webrtc_common.target.linux-x86.mk
@@ -70,6 +70,7 @@
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideocapturer.cc \
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.cc \
 	third_party/libjingle/source/talk/session/media/audiomonitor.cc \
+	third_party/libjingle/source/talk/session/media/bundlefilter.cc \
 	third_party/libjingle/source/talk/session/media/call.cc \
 	third_party/libjingle/source/talk/session/media/channel.cc \
 	third_party/libjingle/source/talk/session/media/channelmanager.cc \
@@ -82,7 +83,6 @@
 	third_party/libjingle/source/talk/session/media/rtcpmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/soundclip.cc \
 	third_party/libjingle/source/talk/session/media/srtpfilter.cc \
-	third_party/libjingle/source/talk/session/media/ssrcmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/typingmonitor.cc \
 	third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc \
 	third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc \
@@ -104,7 +104,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -245,7 +244,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libjingle_webrtc_common.target.linux-x86_64.mk b/third_party/libjingle/libjingle_webrtc_common.target.linux-x86_64.mk
index 3e5f1c6..c4a8100 100644
--- a/third_party/libjingle/libjingle_webrtc_common.target.linux-x86_64.mk
+++ b/third_party/libjingle/libjingle_webrtc_common.target.linux-x86_64.mk
@@ -70,6 +70,7 @@
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideocapturer.cc \
 	third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.cc \
 	third_party/libjingle/source/talk/session/media/audiomonitor.cc \
+	third_party/libjingle/source/talk/session/media/bundlefilter.cc \
 	third_party/libjingle/source/talk/session/media/call.cc \
 	third_party/libjingle/source/talk/session/media/channel.cc \
 	third_party/libjingle/source/talk/session/media/channelmanager.cc \
@@ -82,7 +83,6 @@
 	third_party/libjingle/source/talk/session/media/rtcpmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/soundclip.cc \
 	third_party/libjingle/source/talk/session/media/srtpfilter.cc \
-	third_party/libjingle/source/talk/session/media/ssrcmuxfilter.cc \
 	third_party/libjingle/source/talk/session/media/typingmonitor.cc \
 	third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc \
 	third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc \
@@ -104,7 +104,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -247,7 +246,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libpeerconnection.target.darwin-arm.mk b/third_party/libjingle/libpeerconnection.target.darwin-arm.mk
index f2eb519..cc1a2ff 100644
--- a/third_party/libjingle/libpeerconnection.target.darwin-arm.mk
+++ b/third_party/libjingle/libpeerconnection.target.darwin-arm.mk
@@ -42,7 +42,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -165,7 +164,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libjingle/libpeerconnection.target.darwin-x86.mk b/third_party/libjingle/libpeerconnection.target.darwin-x86.mk
index ee68221..f708777 100644
--- a/third_party/libjingle/libpeerconnection.target.darwin-x86.mk
+++ b/third_party/libjingle/libpeerconnection.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -166,7 +165,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libpeerconnection.target.darwin-x86_64.mk b/third_party/libjingle/libpeerconnection.target.darwin-x86_64.mk
index bd2ec00..bd3896f 100644
--- a/third_party/libjingle/libpeerconnection.target.darwin-x86_64.mk
+++ b/third_party/libjingle/libpeerconnection.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -168,7 +167,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libpeerconnection.target.linux-arm.mk b/third_party/libjingle/libpeerconnection.target.linux-arm.mk
index f2eb519..cc1a2ff 100644
--- a/third_party/libjingle/libpeerconnection.target.linux-arm.mk
+++ b/third_party/libjingle/libpeerconnection.target.linux-arm.mk
@@ -42,7 +42,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -165,7 +164,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libjingle/libpeerconnection.target.linux-x86.mk b/third_party/libjingle/libpeerconnection.target.linux-x86.mk
index ee68221..f708777 100644
--- a/third_party/libjingle/libpeerconnection.target.linux-x86.mk
+++ b/third_party/libjingle/libpeerconnection.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -166,7 +165,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjingle/libpeerconnection.target.linux-x86_64.mk b/third_party/libjingle/libpeerconnection.target.linux-x86_64.mk
index bd2ec00..bd3896f 100644
--- a/third_party/libjingle/libpeerconnection.target.linux-x86_64.mk
+++ b/third_party/libjingle/libpeerconnection.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -168,7 +167,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libjpeg/BUILD.gn b/third_party/libjpeg/BUILD.gn
index 7d06e1a..1a3ffc6 100644
--- a/third_party/libjpeg/BUILD.gn
+++ b/third_party/libjpeg/BUILD.gn
@@ -2,6 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# Do not use the targets in this file unless you need a certain libjpeg
+# implementation. Use the meta target //third_party:jpeg instead.
+
 source_set("libjpeg") {
   sources = [
     "jcapimin.c",
diff --git a/third_party/libphonenumber/libphonenumber.target.darwin-arm.mk b/third_party/libphonenumber/libphonenumber.target.darwin-arm.mk
index 46b959e..718089f 100644
--- a/third_party/libphonenumber/libphonenumber.target.darwin-arm.mk
+++ b/third_party/libphonenumber/libphonenumber.target.darwin-arm.mk
@@ -41,7 +41,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -140,7 +139,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libphonenumber/libphonenumber.target.darwin-x86.mk b/third_party/libphonenumber/libphonenumber.target.darwin-x86.mk
index 3cfb241..5d89b75 100644
--- a/third_party/libphonenumber/libphonenumber.target.darwin-x86.mk
+++ b/third_party/libphonenumber/libphonenumber.target.darwin-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libphonenumber/libphonenumber.target.darwin-x86_64.mk b/third_party/libphonenumber/libphonenumber.target.darwin-x86_64.mk
index eeba15f..873ac9c 100644
--- a/third_party/libphonenumber/libphonenumber.target.darwin-x86_64.mk
+++ b/third_party/libphonenumber/libphonenumber.target.darwin-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libphonenumber/libphonenumber.target.linux-arm.mk b/third_party/libphonenumber/libphonenumber.target.linux-arm.mk
index 46b959e..718089f 100644
--- a/third_party/libphonenumber/libphonenumber.target.linux-arm.mk
+++ b/third_party/libphonenumber/libphonenumber.target.linux-arm.mk
@@ -41,7 +41,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -140,7 +139,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libphonenumber/libphonenumber.target.linux-x86.mk b/third_party/libphonenumber/libphonenumber.target.linux-x86.mk
index 3cfb241..5d89b75 100644
--- a/third_party/libphonenumber/libphonenumber.target.linux-x86.mk
+++ b/third_party/libphonenumber/libphonenumber.target.linux-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libphonenumber/libphonenumber.target.linux-x86_64.mk b/third_party/libphonenumber/libphonenumber.target.linux-x86_64.mk
index eeba15f..873ac9c 100644
--- a/third_party/libphonenumber/libphonenumber.target.linux-x86_64.mk
+++ b/third_party/libphonenumber/libphonenumber.target.linux-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-arm.mk b/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-arm.mk
index 8a9944b..cbf5d0c 100644
--- a/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-arm.mk
+++ b/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-arm.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "third_party_libphonenumber_libphonenumber_gyp_libphonenumber_without_metadata_target_genproto":
 # "{'inputs': ['../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['src/resources/phonemetadata.proto', 'src/resources/phonenumber.proto'], 'action': ['python', '../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'src/resources', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/phonemetadata.pb.h: $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py ;
 
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -99,7 +101,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -201,7 +202,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-arm64.mk b/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-arm64.mk
index f04c405..bb2ed87 100644
--- a/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-arm64.mk
+++ b/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-arm64.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "third_party_libphonenumber_libphonenumber_gyp_libphonenumber_without_metadata_target_genproto":
 # "{'inputs': ['../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['src/resources/phonemetadata.proto', 'src/resources/phonenumber.proto'], 'action': ['python', '../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'src/resources', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/phonemetadata.pb.h: $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py ;
 
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-mips.mk b/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-mips.mk
index a6cf6e8..fe9b72b 100644
--- a/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-mips.mk
+++ b/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-mips.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "third_party_libphonenumber_libphonenumber_gyp_libphonenumber_without_metadata_target_genproto":
 # "{'inputs': ['../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['src/resources/phonemetadata.proto', 'src/resources/phonenumber.proto'], 'action': ['python', '../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'src/resources', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/phonemetadata.pb.h: $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py ;
 
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-x86.mk b/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-x86.mk
index 9c6121a..7ec9a80 100644
--- a/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-x86.mk
+++ b/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-x86.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "third_party_libphonenumber_libphonenumber_gyp_libphonenumber_without_metadata_target_genproto":
 # "{'inputs': ['../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['src/resources/phonemetadata.proto', 'src/resources/phonenumber.proto'], 'action': ['python', '../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'src/resources', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/phonemetadata.pb.h: $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py ;
 
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -101,7 +103,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -203,7 +204,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-x86_64.mk b/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-x86_64.mk
index c230914..bca61c9 100644
--- a/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-x86_64.mk
+++ b/third_party/libphonenumber/libphonenumber_without_metadata.target.darwin-x86_64.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "third_party_libphonenumber_libphonenumber_gyp_libphonenumber_without_metadata_target_genproto":
 # "{'inputs': ['../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['src/resources/phonemetadata.proto', 'src/resources/phonenumber.proto'], 'action': ['python', '../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'src/resources', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/phonemetadata.pb.h: $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py ;
 
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -101,7 +103,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -203,7 +204,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-arm.mk b/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-arm.mk
index 8a9944b..cbf5d0c 100644
--- a/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-arm.mk
+++ b/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-arm.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "third_party_libphonenumber_libphonenumber_gyp_libphonenumber_without_metadata_target_genproto":
 # "{'inputs': ['../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['src/resources/phonemetadata.proto', 'src/resources/phonenumber.proto'], 'action': ['python', '../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'src/resources', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/phonemetadata.pb.h: $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py ;
 
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -99,7 +101,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -201,7 +202,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-arm64.mk b/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-arm64.mk
index f04c405..bb2ed87 100644
--- a/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-arm64.mk
+++ b/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-arm64.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "third_party_libphonenumber_libphonenumber_gyp_libphonenumber_without_metadata_target_genproto":
 # "{'inputs': ['../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['src/resources/phonemetadata.proto', 'src/resources/phonenumber.proto'], 'action': ['python', '../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'src/resources', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/phonemetadata.pb.h: $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py ;
 
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-mips.mk b/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-mips.mk
index a6cf6e8..fe9b72b 100644
--- a/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-mips.mk
+++ b/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-mips.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "third_party_libphonenumber_libphonenumber_gyp_libphonenumber_without_metadata_target_genproto":
 # "{'inputs': ['../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['src/resources/phonemetadata.proto', 'src/resources/phonenumber.proto'], 'action': ['python', '../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'src/resources', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/phonemetadata.pb.h: $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py ;
 
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-x86.mk b/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-x86.mk
index 9c6121a..7ec9a80 100644
--- a/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-x86.mk
+++ b/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-x86.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "third_party_libphonenumber_libphonenumber_gyp_libphonenumber_without_metadata_target_genproto":
 # "{'inputs': ['../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['src/resources/phonemetadata.proto', 'src/resources/phonenumber.proto'], 'action': ['python', '../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'src/resources', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/phonemetadata.pb.h: $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py ;
 
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -101,7 +103,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -203,7 +204,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-x86_64.mk b/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-x86_64.mk
index c230914..bca61c9 100644
--- a/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-x86_64.mk
+++ b/third_party/libphonenumber/libphonenumber_without_metadata.target.linux-x86_64.mk
@@ -20,6 +20,7 @@
 ### Generated for rule "third_party_libphonenumber_libphonenumber_gyp_libphonenumber_without_metadata_target_genproto":
 # "{'inputs': ['../../tools/protoc_wrapper/protoc_wrapper.py', '$(gyp_shared_intermediate_dir)/protoc'], 'process_outputs_as_sources': '1', 'extension': 'proto', 'outputs': ['$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s_pb2.py', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.cc', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h'], 'rule_name': 'genproto', 'rule_sources': ['src/resources/phonemetadata.proto', 'src/resources/phonenumber.proto'], 'action': ['python', '../../tools/protoc_wrapper/protoc_wrapper.py', '--include', '', '--protobuf', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/%(INPUT_ROOT)s.pb.h', '--proto-in-dir', 'src/resources', '--proto-in-file', '%(INPUT_ROOT)s$(suffix $<)', '--use-system-protobuf=0', '--', '$(gyp_shared_intermediate_dir)/protoc', '--cpp_out', '$(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers', '--python_out', '$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers'], 'message': 'Generating C++ and Python code from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 $(gyp_shared_intermediate_dir)/protoc_out/third_party/libphonenumber/phonenumbers/phonemetadata.pb.h: $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonemetadata_pb2.py ;
 
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/pyproto/third_party/libphonenumber/phonenumbers/phonenumber_pb2.py: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -101,7 +103,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -203,7 +204,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libpng/libpng.target.darwin-arm.mk b/third_party/libpng/libpng.target.darwin-arm.mk
index 3a8eb5e..2b5838b 100644
--- a/third_party/libpng/libpng.target.darwin-arm.mk
+++ b/third_party/libpng/libpng.target.darwin-arm.mk
@@ -55,7 +55,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -145,7 +144,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libpng/libpng.target.darwin-x86.mk b/third_party/libpng/libpng.target.darwin-x86.mk
index 7346dde..92d2ae3 100644
--- a/third_party/libpng/libpng.target.darwin-x86.mk
+++ b/third_party/libpng/libpng.target.darwin-x86.mk
@@ -57,7 +57,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libpng/libpng.target.darwin-x86_64.mk b/third_party/libpng/libpng.target.darwin-x86_64.mk
index 1a73106..7afef78 100644
--- a/third_party/libpng/libpng.target.darwin-x86_64.mk
+++ b/third_party/libpng/libpng.target.darwin-x86_64.mk
@@ -57,7 +57,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libpng/libpng.target.linux-arm.mk b/third_party/libpng/libpng.target.linux-arm.mk
index 3a8eb5e..2b5838b 100644
--- a/third_party/libpng/libpng.target.linux-arm.mk
+++ b/third_party/libpng/libpng.target.linux-arm.mk
@@ -55,7 +55,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -145,7 +144,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libpng/libpng.target.linux-x86.mk b/third_party/libpng/libpng.target.linux-x86.mk
index 7346dde..92d2ae3 100644
--- a/third_party/libpng/libpng.target.linux-x86.mk
+++ b/third_party/libpng/libpng.target.linux-x86.mk
@@ -57,7 +57,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libpng/libpng.target.linux-x86_64.mk b/third_party/libpng/libpng.target.linux-x86_64.mk
index 1a73106..7afef78 100644
--- a/third_party/libpng/libpng.target.linux-x86_64.mk
+++ b/third_party/libpng/libpng.target.linux-x86_64.mk
@@ -57,7 +57,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_dec.target.darwin-arm.mk b/third_party/libwebp/libwebp_dec.target.darwin-arm.mk
index b3770b7..0962c2b 100644
--- a/third_party/libwebp/libwebp_dec.target.darwin-arm.mk
+++ b/third_party/libwebp/libwebp_dec.target.darwin-arm.mk
@@ -49,7 +49,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -136,7 +135,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_dec.target.darwin-x86.mk b/third_party/libwebp/libwebp_dec.target.darwin-x86.mk
index 57ffcd5..2c2c0e8 100644
--- a/third_party/libwebp/libwebp_dec.target.darwin-x86.mk
+++ b/third_party/libwebp/libwebp_dec.target.darwin-x86.mk
@@ -52,7 +52,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_dec.target.darwin-x86_64.mk b/third_party/libwebp/libwebp_dec.target.darwin-x86_64.mk
index 17dffda..925ffda 100644
--- a/third_party/libwebp/libwebp_dec.target.darwin-x86_64.mk
+++ b/third_party/libwebp/libwebp_dec.target.darwin-x86_64.mk
@@ -52,7 +52,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_dec.target.linux-arm.mk b/third_party/libwebp/libwebp_dec.target.linux-arm.mk
index b3770b7..0962c2b 100644
--- a/third_party/libwebp/libwebp_dec.target.linux-arm.mk
+++ b/third_party/libwebp/libwebp_dec.target.linux-arm.mk
@@ -49,7 +49,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -136,7 +135,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_dec.target.linux-x86.mk b/third_party/libwebp/libwebp_dec.target.linux-x86.mk
index 57ffcd5..2c2c0e8 100644
--- a/third_party/libwebp/libwebp_dec.target.linux-x86.mk
+++ b/third_party/libwebp/libwebp_dec.target.linux-x86.mk
@@ -52,7 +52,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_dec.target.linux-x86_64.mk b/third_party/libwebp/libwebp_dec.target.linux-x86_64.mk
index 17dffda..925ffda 100644
--- a/third_party/libwebp/libwebp_dec.target.linux-x86_64.mk
+++ b/third_party/libwebp/libwebp_dec.target.linux-x86_64.mk
@@ -52,7 +52,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +138,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_demux.target.darwin-arm.mk b/third_party/libwebp/libwebp_demux.target.darwin-arm.mk
index b19a5c8..ded60bb 100644
--- a/third_party/libwebp/libwebp_demux.target.darwin-arm.mk
+++ b/third_party/libwebp/libwebp_demux.target.darwin-arm.mk
@@ -39,7 +39,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -126,7 +125,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_demux.target.darwin-x86.mk b/third_party/libwebp/libwebp_demux.target.darwin-x86.mk
index b8278e0..7b55b49 100644
--- a/third_party/libwebp/libwebp_demux.target.darwin-x86.mk
+++ b/third_party/libwebp/libwebp_demux.target.darwin-x86.mk
@@ -41,7 +41,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_demux.target.darwin-x86_64.mk b/third_party/libwebp/libwebp_demux.target.darwin-x86_64.mk
index d22c037..6e84fa7 100644
--- a/third_party/libwebp/libwebp_demux.target.darwin-x86_64.mk
+++ b/third_party/libwebp/libwebp_demux.target.darwin-x86_64.mk
@@ -41,7 +41,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_demux.target.linux-arm.mk b/third_party/libwebp/libwebp_demux.target.linux-arm.mk
index b19a5c8..ded60bb 100644
--- a/third_party/libwebp/libwebp_demux.target.linux-arm.mk
+++ b/third_party/libwebp/libwebp_demux.target.linux-arm.mk
@@ -39,7 +39,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -126,7 +125,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_demux.target.linux-x86.mk b/third_party/libwebp/libwebp_demux.target.linux-x86.mk
index b8278e0..7b55b49 100644
--- a/third_party/libwebp/libwebp_demux.target.linux-x86.mk
+++ b/third_party/libwebp/libwebp_demux.target.linux-x86.mk
@@ -41,7 +41,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_demux.target.linux-x86_64.mk b/third_party/libwebp/libwebp_demux.target.linux-x86_64.mk
index d22c037..6e84fa7 100644
--- a/third_party/libwebp/libwebp_demux.target.linux-x86_64.mk
+++ b/third_party/libwebp/libwebp_demux.target.linux-x86_64.mk
@@ -41,7 +41,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -128,7 +127,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_dsp.target.darwin-arm.mk b/third_party/libwebp/libwebp_dsp.target.darwin-arm.mk
index 9409727..85afcaf 100644
--- a/third_party/libwebp/libwebp_dsp.target.darwin-arm.mk
+++ b/third_party/libwebp/libwebp_dsp.target.darwin-arm.mk
@@ -47,7 +47,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +133,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_dsp.target.darwin-x86.mk b/third_party/libwebp/libwebp_dsp.target.darwin-x86.mk
index 04d7f87..faa4bb3 100644
--- a/third_party/libwebp/libwebp_dsp.target.darwin-x86.mk
+++ b/third_party/libwebp/libwebp_dsp.target.darwin-x86.mk
@@ -49,7 +49,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_dsp.target.darwin-x86_64.mk b/third_party/libwebp/libwebp_dsp.target.darwin-x86_64.mk
index abdd0d8..5d8278d 100644
--- a/third_party/libwebp/libwebp_dsp.target.darwin-x86_64.mk
+++ b/third_party/libwebp/libwebp_dsp.target.darwin-x86_64.mk
@@ -49,7 +49,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_dsp.target.linux-arm.mk b/third_party/libwebp/libwebp_dsp.target.linux-arm.mk
index 9409727..85afcaf 100644
--- a/third_party/libwebp/libwebp_dsp.target.linux-arm.mk
+++ b/third_party/libwebp/libwebp_dsp.target.linux-arm.mk
@@ -47,7 +47,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -134,7 +133,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_dsp.target.linux-x86.mk b/third_party/libwebp/libwebp_dsp.target.linux-x86.mk
index 04d7f87..faa4bb3 100644
--- a/third_party/libwebp/libwebp_dsp.target.linux-x86.mk
+++ b/third_party/libwebp/libwebp_dsp.target.linux-x86.mk
@@ -49,7 +49,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_dsp.target.linux-x86_64.mk b/third_party/libwebp/libwebp_dsp.target.linux-x86_64.mk
index abdd0d8..5d8278d 100644
--- a/third_party/libwebp/libwebp_dsp.target.linux-x86_64.mk
+++ b/third_party/libwebp/libwebp_dsp.target.linux-x86_64.mk
@@ -49,7 +49,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -136,7 +135,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_dsp_neon.target.darwin-arm.mk b/third_party/libwebp/libwebp_dsp_neon.target.darwin-arm.mk
index c877d1a..68906e4 100644
--- a/third_party/libwebp/libwebp_dsp_neon.target.darwin-arm.mk
+++ b/third_party/libwebp/libwebp_dsp_neon.target.darwin-arm.mk
@@ -42,7 +42,6 @@
 	-mfpu=neon \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-mfpu=neon \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_dsp_neon.target.linux-arm.mk b/third_party/libwebp/libwebp_dsp_neon.target.linux-arm.mk
index c877d1a..68906e4 100644
--- a/third_party/libwebp/libwebp_dsp_neon.target.linux-arm.mk
+++ b/third_party/libwebp/libwebp_dsp_neon.target.linux-arm.mk
@@ -42,7 +42,6 @@
 	-mfpu=neon \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-mfpu=neon \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_enc.target.darwin-arm.mk b/third_party/libwebp/libwebp_enc.target.darwin-arm.mk
index fbf8a17..f9a8f9f 100644
--- a/third_party/libwebp/libwebp_enc.target.darwin-arm.mk
+++ b/third_party/libwebp/libwebp_enc.target.darwin-arm.mk
@@ -55,7 +55,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -142,7 +141,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_enc.target.darwin-x86.mk b/third_party/libwebp/libwebp_enc.target.darwin-x86.mk
index 2d2d0da..62f6247 100644
--- a/third_party/libwebp/libwebp_enc.target.darwin-x86.mk
+++ b/third_party/libwebp/libwebp_enc.target.darwin-x86.mk
@@ -57,7 +57,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_enc.target.darwin-x86_64.mk b/third_party/libwebp/libwebp_enc.target.darwin-x86_64.mk
index f2de0e7..61aa6b8 100644
--- a/third_party/libwebp/libwebp_enc.target.darwin-x86_64.mk
+++ b/third_party/libwebp/libwebp_enc.target.darwin-x86_64.mk
@@ -57,7 +57,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_enc.target.linux-arm.mk b/third_party/libwebp/libwebp_enc.target.linux-arm.mk
index fbf8a17..f9a8f9f 100644
--- a/third_party/libwebp/libwebp_enc.target.linux-arm.mk
+++ b/third_party/libwebp/libwebp_enc.target.linux-arm.mk
@@ -55,7 +55,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -142,7 +141,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_enc.target.linux-x86.mk b/third_party/libwebp/libwebp_enc.target.linux-x86.mk
index 2d2d0da..62f6247 100644
--- a/third_party/libwebp/libwebp_enc.target.linux-x86.mk
+++ b/third_party/libwebp/libwebp_enc.target.linux-x86.mk
@@ -57,7 +57,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_enc.target.linux-x86_64.mk b/third_party/libwebp/libwebp_enc.target.linux-x86_64.mk
index f2de0e7..61aa6b8 100644
--- a/third_party/libwebp/libwebp_enc.target.linux-x86_64.mk
+++ b/third_party/libwebp/libwebp_enc.target.linux-x86_64.mk
@@ -57,7 +57,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_utils.target.darwin-arm.mk b/third_party/libwebp/libwebp_utils.target.darwin-arm.mk
index a147fb9..b1383ad 100644
--- a/third_party/libwebp/libwebp_utils.target.darwin-arm.mk
+++ b/third_party/libwebp/libwebp_utils.target.darwin-arm.mk
@@ -51,7 +51,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +137,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_utils.target.darwin-x86.mk b/third_party/libwebp/libwebp_utils.target.darwin-x86.mk
index 0924ca2..169a3a5 100644
--- a/third_party/libwebp/libwebp_utils.target.darwin-x86.mk
+++ b/third_party/libwebp/libwebp_utils.target.darwin-x86.mk
@@ -53,7 +53,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_utils.target.darwin-x86_64.mk b/third_party/libwebp/libwebp_utils.target.darwin-x86_64.mk
index 25e7455..86986b1 100644
--- a/third_party/libwebp/libwebp_utils.target.darwin-x86_64.mk
+++ b/third_party/libwebp/libwebp_utils.target.darwin-x86_64.mk
@@ -53,7 +53,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_utils.target.linux-arm.mk b/third_party/libwebp/libwebp_utils.target.linux-arm.mk
index a147fb9..b1383ad 100644
--- a/third_party/libwebp/libwebp_utils.target.linux-arm.mk
+++ b/third_party/libwebp/libwebp_utils.target.linux-arm.mk
@@ -51,7 +51,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -138,7 +137,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libwebp/libwebp_utils.target.linux-x86.mk b/third_party/libwebp/libwebp_utils.target.linux-x86.mk
index 0924ca2..169a3a5 100644
--- a/third_party/libwebp/libwebp_utils.target.linux-x86.mk
+++ b/third_party/libwebp/libwebp_utils.target.linux-x86.mk
@@ -53,7 +53,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libwebp/libwebp_utils.target.linux-x86_64.mk b/third_party/libwebp/libwebp_utils.target.linux-x86_64.mk
index 25e7455..86986b1 100644
--- a/third_party/libwebp/libwebp_utils.target.linux-x86_64.mk
+++ b/third_party/libwebp/libwebp_utils.target.linux-x86_64.mk
@@ -53,7 +53,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -140,7 +139,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libxml/libxml.target.darwin-arm.mk b/third_party/libxml/libxml.target.darwin-arm.mk
index 0958041..a591ee1 100644
--- a/third_party/libxml/libxml.target.darwin-arm.mk
+++ b/third_party/libxml/libxml.target.darwin-arm.mk
@@ -84,7 +84,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -180,7 +179,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libxml/libxml.target.darwin-x86.mk b/third_party/libxml/libxml.target.darwin-x86.mk
index 150d2d1..dbc95a3 100644
--- a/third_party/libxml/libxml.target.darwin-x86.mk
+++ b/third_party/libxml/libxml.target.darwin-x86.mk
@@ -86,7 +86,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -182,7 +181,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libxml/libxml.target.darwin-x86_64.mk b/third_party/libxml/libxml.target.darwin-x86_64.mk
index 6e12fd1..52178c1 100644
--- a/third_party/libxml/libxml.target.darwin-x86_64.mk
+++ b/third_party/libxml/libxml.target.darwin-x86_64.mk
@@ -86,7 +86,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -182,7 +181,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libxml/libxml.target.linux-arm.mk b/third_party/libxml/libxml.target.linux-arm.mk
index 0958041..a591ee1 100644
--- a/third_party/libxml/libxml.target.linux-arm.mk
+++ b/third_party/libxml/libxml.target.linux-arm.mk
@@ -84,7 +84,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -180,7 +179,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libxml/libxml.target.linux-x86.mk b/third_party/libxml/libxml.target.linux-x86.mk
index 150d2d1..dbc95a3 100644
--- a/third_party/libxml/libxml.target.linux-x86.mk
+++ b/third_party/libxml/libxml.target.linux-x86.mk
@@ -86,7 +86,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -182,7 +181,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libxml/libxml.target.linux-x86_64.mk b/third_party/libxml/libxml.target.linux-x86_64.mk
index 6e12fd1..52178c1 100644
--- a/third_party/libxml/libxml.target.linux-x86_64.mk
+++ b/third_party/libxml/libxml.target.linux-x86_64.mk
@@ -86,7 +86,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -182,7 +181,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libxslt/libxslt.target.darwin-arm.mk b/third_party/libxslt/libxslt.target.darwin-arm.mk
index 2f139fc..587186e 100644
--- a/third_party/libxslt/libxslt.target.darwin-arm.mk
+++ b/third_party/libxslt/libxslt.target.darwin-arm.mk
@@ -57,7 +57,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -153,7 +152,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libxslt/libxslt.target.darwin-x86.mk b/third_party/libxslt/libxslt.target.darwin-x86.mk
index ccb093d..ed8531e 100644
--- a/third_party/libxslt/libxslt.target.darwin-x86.mk
+++ b/third_party/libxslt/libxslt.target.darwin-x86.mk
@@ -59,7 +59,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +154,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libxslt/libxslt.target.darwin-x86_64.mk b/third_party/libxslt/libxslt.target.darwin-x86_64.mk
index 739b5b8..b75b944 100644
--- a/third_party/libxslt/libxslt.target.darwin-x86_64.mk
+++ b/third_party/libxslt/libxslt.target.darwin-x86_64.mk
@@ -59,7 +59,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +154,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libxslt/libxslt.target.linux-arm.mk b/third_party/libxslt/libxslt.target.linux-arm.mk
index 2f139fc..587186e 100644
--- a/third_party/libxslt/libxslt.target.linux-arm.mk
+++ b/third_party/libxslt/libxslt.target.linux-arm.mk
@@ -57,7 +57,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -153,7 +152,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/libxslt/libxslt.target.linux-x86.mk b/third_party/libxslt/libxslt.target.linux-x86.mk
index ccb093d..ed8531e 100644
--- a/third_party/libxslt/libxslt.target.linux-x86.mk
+++ b/third_party/libxslt/libxslt.target.linux-x86.mk
@@ -59,7 +59,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +154,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/libxslt/libxslt.target.linux-x86_64.mk b/third_party/libxslt/libxslt.target.linux-x86_64.mk
index 739b5b8..b75b944 100644
--- a/third_party/libxslt/libxslt.target.linux-x86_64.mk
+++ b/third_party/libxslt/libxslt.target.linux-x86_64.mk
@@ -59,7 +59,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +154,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/lzma_sdk/lzma_sdk.target.darwin-arm.mk b/third_party/lzma_sdk/lzma_sdk.target.darwin-arm.mk
index 468d6bf..7a9dc93 100644
--- a/third_party/lzma_sdk/lzma_sdk.target.darwin-arm.mk
+++ b/third_party/lzma_sdk/lzma_sdk.target.darwin-arm.mk
@@ -56,7 +56,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -145,7 +144,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/lzma_sdk/lzma_sdk.target.darwin-x86.mk b/third_party/lzma_sdk/lzma_sdk.target.darwin-x86.mk
index f7807a2..4ebed85 100644
--- a/third_party/lzma_sdk/lzma_sdk.target.darwin-x86.mk
+++ b/third_party/lzma_sdk/lzma_sdk.target.darwin-x86.mk
@@ -58,7 +58,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/lzma_sdk/lzma_sdk.target.darwin-x86_64.mk b/third_party/lzma_sdk/lzma_sdk.target.darwin-x86_64.mk
index e49f5bc..15647b9 100644
--- a/third_party/lzma_sdk/lzma_sdk.target.darwin-x86_64.mk
+++ b/third_party/lzma_sdk/lzma_sdk.target.darwin-x86_64.mk
@@ -58,7 +58,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/lzma_sdk/lzma_sdk.target.linux-arm.mk b/third_party/lzma_sdk/lzma_sdk.target.linux-arm.mk
index 468d6bf..7a9dc93 100644
--- a/third_party/lzma_sdk/lzma_sdk.target.linux-arm.mk
+++ b/third_party/lzma_sdk/lzma_sdk.target.linux-arm.mk
@@ -56,7 +56,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -145,7 +144,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/lzma_sdk/lzma_sdk.target.linux-x86.mk b/third_party/lzma_sdk/lzma_sdk.target.linux-x86.mk
index f7807a2..4ebed85 100644
--- a/third_party/lzma_sdk/lzma_sdk.target.linux-x86.mk
+++ b/third_party/lzma_sdk/lzma_sdk.target.linux-x86.mk
@@ -58,7 +58,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/lzma_sdk/lzma_sdk.target.linux-x86_64.mk b/third_party/lzma_sdk/lzma_sdk.target.linux-x86_64.mk
index e49f5bc..15647b9 100644
--- a/third_party/lzma_sdk/lzma_sdk.target.linux-x86_64.mk
+++ b/third_party/lzma_sdk/lzma_sdk.target.linux-x86_64.mk
@@ -58,7 +58,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -147,7 +146,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/modp_b64/modp_b64.target.darwin-arm.mk b/third_party/modp_b64/modp_b64.target.darwin-arm.mk
index ec79080..9aba193 100644
--- a/third_party/modp_b64/modp_b64.target.darwin-arm.mk
+++ b/third_party/modp_b64/modp_b64.target.darwin-arm.mk
@@ -40,7 +40,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -127,7 +126,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/modp_b64/modp_b64.target.darwin-x86.mk b/third_party/modp_b64/modp_b64.target.darwin-x86.mk
index 0080dbb..051bb58 100644
--- a/third_party/modp_b64/modp_b64.target.darwin-x86.mk
+++ b/third_party/modp_b64/modp_b64.target.darwin-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/modp_b64/modp_b64.target.darwin-x86_64.mk b/third_party/modp_b64/modp_b64.target.darwin-x86_64.mk
index 224d28c..f80750b 100644
--- a/third_party/modp_b64/modp_b64.target.darwin-x86_64.mk
+++ b/third_party/modp_b64/modp_b64.target.darwin-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/modp_b64/modp_b64.target.linux-arm.mk b/third_party/modp_b64/modp_b64.target.linux-arm.mk
index ec79080..9aba193 100644
--- a/third_party/modp_b64/modp_b64.target.linux-arm.mk
+++ b/third_party/modp_b64/modp_b64.target.linux-arm.mk
@@ -40,7 +40,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -127,7 +126,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/modp_b64/modp_b64.target.linux-x86.mk b/third_party/modp_b64/modp_b64.target.linux-x86.mk
index 0080dbb..051bb58 100644
--- a/third_party/modp_b64/modp_b64.target.linux-x86.mk
+++ b/third_party/modp_b64/modp_b64.target.linux-x86.mk
@@ -42,7 +42,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/modp_b64/modp_b64.target.linux-x86_64.mk b/third_party/modp_b64/modp_b64.target.linux-x86_64.mk
index 224d28c..f80750b 100644
--- a/third_party/modp_b64/modp_b64.target.linux-x86_64.mk
+++ b/third_party/modp_b64/modp_b64.target.linux-x86_64.mk
@@ -42,7 +42,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/npapi/npapi.target.darwin-arm.mk b/third_party/npapi/npapi.target.darwin-arm.mk
index c721094..dfd3d2c6 100644
--- a/third_party/npapi/npapi.target.darwin-arm.mk
+++ b/third_party/npapi/npapi.target.darwin-arm.mk
@@ -39,7 +39,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -125,7 +124,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/npapi/npapi.target.darwin-x86.mk b/third_party/npapi/npapi.target.darwin-x86.mk
index ce9b354..82d4f27 100644
--- a/third_party/npapi/npapi.target.darwin-x86.mk
+++ b/third_party/npapi/npapi.target.darwin-x86.mk
@@ -41,7 +41,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/npapi/npapi.target.darwin-x86_64.mk b/third_party/npapi/npapi.target.darwin-x86_64.mk
index 2e00749..f8a83a1 100644
--- a/third_party/npapi/npapi.target.darwin-x86_64.mk
+++ b/third_party/npapi/npapi.target.darwin-x86_64.mk
@@ -41,7 +41,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/npapi/npapi.target.linux-arm.mk b/third_party/npapi/npapi.target.linux-arm.mk
index c721094..dfd3d2c6 100644
--- a/third_party/npapi/npapi.target.linux-arm.mk
+++ b/third_party/npapi/npapi.target.linux-arm.mk
@@ -39,7 +39,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -125,7 +124,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/npapi/npapi.target.linux-x86.mk b/third_party/npapi/npapi.target.linux-x86.mk
index ce9b354..82d4f27 100644
--- a/third_party/npapi/npapi.target.linux-x86.mk
+++ b/third_party/npapi/npapi.target.linux-x86.mk
@@ -41,7 +41,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/npapi/npapi.target.linux-x86_64.mk b/third_party/npapi/npapi.target.linux-x86_64.mk
index 2e00749..f8a83a1 100644
--- a/third_party/npapi/npapi.target.linux-x86_64.mk
+++ b/third_party/npapi/npapi.target.linux-x86_64.mk
@@ -41,7 +41,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/opus/opus.target.darwin-arm.mk b/third_party/opus/opus.target.darwin-arm.mk
index 8b5ec28..25121e8 100644
--- a/third_party/opus/opus.target.darwin-arm.mk
+++ b/third_party/opus/opus.target.darwin-arm.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "convert_assembler":
 $(gyp_intermediate_dir)/celt_pitch_xcorr_arm_gnu.S: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/celt_pitch_xcorr_arm_gnu.S: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/celt_pitch_xcorr_arm_gnu.S: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/celt_pitch_xcorr_arm_gnu.S: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/celt_pitch_xcorr_arm_gnu.S: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -182,7 +183,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -285,7 +285,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/opus/opus.target.darwin-x86.mk b/third_party/opus/opus.target.darwin-x86.mk
index e3a995d..10b0a26 100644
--- a/third_party/opus/opus.target.darwin-x86.mk
+++ b/third_party/opus/opus.target.darwin-x86.mk
@@ -175,7 +175,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -270,7 +269,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/opus/opus.target.darwin-x86_64.mk b/third_party/opus/opus.target.darwin-x86_64.mk
index 9e7aaec..f60881b 100644
--- a/third_party/opus/opus.target.darwin-x86_64.mk
+++ b/third_party/opus/opus.target.darwin-x86_64.mk
@@ -175,7 +175,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -270,7 +269,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/opus/opus.target.linux-arm.mk b/third_party/opus/opus.target.linux-arm.mk
index 8b5ec28..25121e8 100644
--- a/third_party/opus/opus.target.linux-arm.mk
+++ b/third_party/opus/opus.target.linux-arm.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "convert_assembler":
 $(gyp_intermediate_dir)/celt_pitch_xcorr_arm_gnu.S: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/celt_pitch_xcorr_arm_gnu.S: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/celt_pitch_xcorr_arm_gnu.S: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/celt_pitch_xcorr_arm_gnu.S: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/celt_pitch_xcorr_arm_gnu.S: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -182,7 +183,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -285,7 +285,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/opus/opus.target.linux-x86.mk b/third_party/opus/opus.target.linux-x86.mk
index e3a995d..10b0a26 100644
--- a/third_party/opus/opus.target.linux-x86.mk
+++ b/third_party/opus/opus.target.linux-x86.mk
@@ -175,7 +175,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -270,7 +269,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/opus/opus.target.linux-x86_64.mk b/third_party/opus/opus.target.linux-x86_64.mk
index 9e7aaec..f60881b 100644
--- a/third_party/opus/opus.target.linux-x86_64.mk
+++ b/third_party/opus/opus.target.linux-x86_64.mk
@@ -175,7 +175,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -270,7 +269,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/protobuf/README.chromium b/third_party/protobuf/README.chromium
index ab2cff4..298c207 100644
--- a/third_party/protobuf/README.chromium
+++ b/third_party/protobuf/README.chromium
@@ -31,6 +31,8 @@
 Revision 516 was cherry-picked from upstream.
 Revision 517 was cherry-picked from upstream.
 Revision 522 was cherry-picked from upstream.
+Revision 523 was cherry-picked from upstream.
+Revision 524 was cherry-picked from upstream.
 
 Notes about Java:
 We have not forked the Java version of protobuf-lite, so the Java version does
diff --git a/third_party/protobuf/protobuf_full_do_not_use.host.darwin-arm.mk b/third_party/protobuf/protobuf_full_do_not_use.host.darwin-arm.mk
index 09a91d2..47b09ba 100644
--- a/third_party/protobuf/protobuf_full_do_not_use.host.darwin-arm.mk
+++ b/third_party/protobuf/protobuf_full_do_not_use.host.darwin-arm.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protobuf_full_do_not_use.host.darwin-arm64.mk b/third_party/protobuf/protobuf_full_do_not_use.host.darwin-arm64.mk
index 3cc41cb..d54b60e 100644
--- a/third_party/protobuf/protobuf_full_do_not_use.host.darwin-arm64.mk
+++ b/third_party/protobuf/protobuf_full_do_not_use.host.darwin-arm64.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protobuf_full_do_not_use.host.darwin-mips.mk b/third_party/protobuf/protobuf_full_do_not_use.host.darwin-mips.mk
index 9c70f16..13056aa 100644
--- a/third_party/protobuf/protobuf_full_do_not_use.host.darwin-mips.mk
+++ b/third_party/protobuf/protobuf_full_do_not_use.host.darwin-mips.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protobuf_full_do_not_use.host.darwin-x86.mk b/third_party/protobuf/protobuf_full_do_not_use.host.darwin-x86.mk
index 09a91d2..47b09ba 100644
--- a/third_party/protobuf/protobuf_full_do_not_use.host.darwin-x86.mk
+++ b/third_party/protobuf/protobuf_full_do_not_use.host.darwin-x86.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protobuf_full_do_not_use.host.darwin-x86_64.mk b/third_party/protobuf/protobuf_full_do_not_use.host.darwin-x86_64.mk
index 3cc41cb..d54b60e 100644
--- a/third_party/protobuf/protobuf_full_do_not_use.host.darwin-x86_64.mk
+++ b/third_party/protobuf/protobuf_full_do_not_use.host.darwin-x86_64.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protobuf_full_do_not_use.host.linux-arm.mk b/third_party/protobuf/protobuf_full_do_not_use.host.linux-arm.mk
index 8e3728e..d522219 100644
--- a/third_party/protobuf/protobuf_full_do_not_use.host.linux-arm.mk
+++ b/third_party/protobuf/protobuf_full_do_not_use.host.linux-arm.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protobuf_full_do_not_use.host.linux-arm64.mk b/third_party/protobuf/protobuf_full_do_not_use.host.linux-arm64.mk
index 55e200f..f7388a4 100644
--- a/third_party/protobuf/protobuf_full_do_not_use.host.linux-arm64.mk
+++ b/third_party/protobuf/protobuf_full_do_not_use.host.linux-arm64.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protobuf_full_do_not_use.host.linux-mips.mk b/third_party/protobuf/protobuf_full_do_not_use.host.linux-mips.mk
index aea20fa..5745de4 100644
--- a/third_party/protobuf/protobuf_full_do_not_use.host.linux-mips.mk
+++ b/third_party/protobuf/protobuf_full_do_not_use.host.linux-mips.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protobuf_full_do_not_use.host.linux-x86.mk b/third_party/protobuf/protobuf_full_do_not_use.host.linux-x86.mk
index 8e3728e..d522219 100644
--- a/third_party/protobuf/protobuf_full_do_not_use.host.linux-x86.mk
+++ b/third_party/protobuf/protobuf_full_do_not_use.host.linux-x86.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protobuf_full_do_not_use.host.linux-x86_64.mk b/third_party/protobuf/protobuf_full_do_not_use.host.linux-x86_64.mk
index 55e200f..f7388a4 100644
--- a/third_party/protobuf/protobuf_full_do_not_use.host.linux-x86_64.mk
+++ b/third_party/protobuf/protobuf_full_do_not_use.host.linux-x86_64.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protobuf_lite.target.darwin-arm.mk b/third_party/protobuf/protobuf_lite.target.darwin-arm.mk
index dadf1ed..55d89d3 100644
--- a/third_party/protobuf/protobuf_lite.target.darwin-arm.mk
+++ b/third_party/protobuf/protobuf_lite.target.darwin-arm.mk
@@ -52,7 +52,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -144,7 +143,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/protobuf/protobuf_lite.target.darwin-x86.mk b/third_party/protobuf/protobuf_lite.target.darwin-x86.mk
index d6fa2e0..ea5b2b7 100644
--- a/third_party/protobuf/protobuf_lite.target.darwin-x86.mk
+++ b/third_party/protobuf/protobuf_lite.target.darwin-x86.mk
@@ -54,7 +54,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,7 +145,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/protobuf/protobuf_lite.target.darwin-x86_64.mk b/third_party/protobuf/protobuf_lite.target.darwin-x86_64.mk
index 2d711fc..6d03e6c 100644
--- a/third_party/protobuf/protobuf_lite.target.darwin-x86_64.mk
+++ b/third_party/protobuf/protobuf_lite.target.darwin-x86_64.mk
@@ -54,7 +54,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,7 +145,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/protobuf/protobuf_lite.target.linux-arm.mk b/third_party/protobuf/protobuf_lite.target.linux-arm.mk
index dadf1ed..55d89d3 100644
--- a/third_party/protobuf/protobuf_lite.target.linux-arm.mk
+++ b/third_party/protobuf/protobuf_lite.target.linux-arm.mk
@@ -52,7 +52,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -144,7 +143,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/protobuf/protobuf_lite.target.linux-x86.mk b/third_party/protobuf/protobuf_lite.target.linux-x86.mk
index d6fa2e0..ea5b2b7 100644
--- a/third_party/protobuf/protobuf_lite.target.linux-x86.mk
+++ b/third_party/protobuf/protobuf_lite.target.linux-x86.mk
@@ -54,7 +54,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,7 +145,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/protobuf/protobuf_lite.target.linux-x86_64.mk b/third_party/protobuf/protobuf_lite.target.linux-x86_64.mk
index 2d711fc..6d03e6c 100644
--- a/third_party/protobuf/protobuf_lite.target.linux-x86_64.mk
+++ b/third_party/protobuf/protobuf_lite.target.linux-x86_64.mk
@@ -54,7 +54,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,7 +145,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/protobuf/protoc.host.darwin-arm.mk b/third_party/protobuf/protoc.host.darwin-arm.mk
index f2ad175..6daa79e 100644
--- a/third_party/protobuf/protoc.host.darwin-arm.mk
+++ b/third_party/protobuf/protoc.host.darwin-arm.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protoc.host.darwin-arm64.mk b/third_party/protobuf/protoc.host.darwin-arm64.mk
index 3af6326..0e1eba2 100644
--- a/third_party/protobuf/protoc.host.darwin-arm64.mk
+++ b/third_party/protobuf/protoc.host.darwin-arm64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protoc.host.darwin-mips.mk b/third_party/protobuf/protoc.host.darwin-mips.mk
index 4a9c5ae..8476fd4 100644
--- a/third_party/protobuf/protoc.host.darwin-mips.mk
+++ b/third_party/protobuf/protoc.host.darwin-mips.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protoc.host.darwin-x86.mk b/third_party/protobuf/protoc.host.darwin-x86.mk
index f2ad175..6daa79e 100644
--- a/third_party/protobuf/protoc.host.darwin-x86.mk
+++ b/third_party/protobuf/protoc.host.darwin-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protoc.host.darwin-x86_64.mk b/third_party/protobuf/protoc.host.darwin-x86_64.mk
index 3af6326..0e1eba2 100644
--- a/third_party/protobuf/protoc.host.darwin-x86_64.mk
+++ b/third_party/protobuf/protoc.host.darwin-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protoc.host.linux-arm.mk b/third_party/protobuf/protoc.host.linux-arm.mk
index 7055ef0..e86c39f 100644
--- a/third_party/protobuf/protoc.host.linux-arm.mk
+++ b/third_party/protobuf/protoc.host.linux-arm.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protoc.host.linux-arm64.mk b/third_party/protobuf/protoc.host.linux-arm64.mk
index c1b91fb..94eeeda 100644
--- a/third_party/protobuf/protoc.host.linux-arm64.mk
+++ b/third_party/protobuf/protoc.host.linux-arm64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protoc.host.linux-mips.mk b/third_party/protobuf/protoc.host.linux-mips.mk
index 3e7776d..3b14e86 100644
--- a/third_party/protobuf/protoc.host.linux-mips.mk
+++ b/third_party/protobuf/protoc.host.linux-mips.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protoc.host.linux-x86.mk b/third_party/protobuf/protoc.host.linux-x86.mk
index 7055ef0..e86c39f 100644
--- a/third_party/protobuf/protoc.host.linux-x86.mk
+++ b/third_party/protobuf/protoc.host.linux-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/protoc.host.linux-x86_64.mk b/third_party/protobuf/protoc.host.linux-x86_64.mk
index c1b91fb..94eeeda 100644
--- a/third_party/protobuf/protoc.host.linux-x86_64.mk
+++ b/third_party/protobuf/protoc.host.linux-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h b/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
index c13cddb..fe9727a 100644
--- a/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
+++ b/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
@@ -38,12 +38,16 @@
 namespace internal {
 
 inline void MemoryBarrier() {
-  __asm__ __volatile__ (  // NOLINT
-    "dmb ish                                  \n\t"  // Data memory barrier.
-    ::: "memory"
-  );  // NOLINT
+  __asm__ __volatile__ ("dmb ish" ::: "memory");  // NOLINT
 }
 
+// NoBarrier versions of the operation include "memory" in the clobber list.
+// This is not required for direct usage of the NoBarrier versions of the
+// operations. However this is required for correctness when they are used as
+// part of the Acquire or Release versions, to ensure that nothing from outside
+// the call is reordered between the operation and the memory barrier. This does
+// not change the code generated, so has no or minimal impact on the
+// NoBarrier operations.
 
 inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
                                          Atomic32 old_value,
@@ -59,13 +63,12 @@
     "stxr %w[temp], %w[new_value], %[ptr]  \n\t"  // Try to store the new value.
     "cbnz %w[temp], 0b                     \n\t"  // Retry if it did not work.
     "1:                                    \n\t"
-    "clrex                                 \n\t"  // In case we didn't swap.
     : [prev]"=&r" (prev),
       [temp]"=&r" (temp),
       [ptr]"+Q" (*ptr)
-    : [old_value]"r" (old_value),
+    : [old_value]"IJr" (old_value),
       [new_value]"r" (new_value)
-    : "memory", "cc"
+    : "cc", "memory"
   );  // NOLINT
 
   return prev;
@@ -105,7 +108,7 @@
     : [result]"=&r" (result),
       [temp]"=&r" (temp),
       [ptr]"+Q" (*ptr)
-    : [increment]"r" (increment)
+    : [increment]"IJr" (increment)
     : "memory"
   );  // NOLINT
 
@@ -124,28 +127,8 @@
 inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
                                        Atomic32 old_value,
                                        Atomic32 new_value) {
-  Atomic32 prev;
-  int32_t temp;
-
-  __asm__ __volatile__ (  // NOLINT
-    "0:                                    \n\t"
-    "ldxr %w[prev], %[ptr]                 \n\t"  // Load the previous value.
-    "cmp %w[prev], %w[old_value]           \n\t"
-    "bne 1f                                \n\t"
-    "stxr %w[temp], %w[new_value], %[ptr]  \n\t"  // Try to store the new value.
-    "cbnz %w[temp], 0b                     \n\t"  // Retry if it did not work.
-    "dmb ish                               \n\t"  // Data memory barrier.
-    "1:                                    \n\t"
-    // If the compare failed the 'dmb' is unnecessary, but we still need a
-    // 'clrex'.
-    "clrex                                 \n\t"
-    : [prev]"=&r" (prev),
-      [temp]"=&r" (temp),
-      [ptr]"+Q" (*ptr)
-    : [old_value]"r" (old_value),
-      [new_value]"r" (new_value)
-    : "memory", "cc"
-  );  // NOLINT
+  Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  MemoryBarrier();
 
   return prev;
 }
@@ -153,28 +136,8 @@
 inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
                                        Atomic32 old_value,
                                        Atomic32 new_value) {
-  Atomic32 prev;
-  int32_t temp;
-
   MemoryBarrier();
-
-  __asm__ __volatile__ (  // NOLINT
-    "0:                                    \n\t"
-    "ldxr %w[prev], %[ptr]                 \n\t"  // Load the previous value.
-    "cmp %w[prev], %w[old_value]           \n\t"
-    "bne 1f                                \n\t"
-    "stxr %w[temp], %w[new_value], %[ptr]  \n\t"  // Try to store the new value.
-    "cbnz %w[temp], 0b                     \n\t"  // Retry if it did not work.
-    "1:                                    \n\t"
-    // If the compare failed the we still need a 'clrex'.
-    "clrex                                 \n\t"
-    : [prev]"=&r" (prev),
-      [temp]"=&r" (temp),
-      [ptr]"+Q" (*ptr)
-    : [old_value]"r" (old_value),
-      [new_value]"r" (new_value)
-    : "memory", "cc"
-  );  // NOLINT
+  Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
 
   return prev;
 }
@@ -189,8 +152,12 @@
 }
 
 inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
-  MemoryBarrier();
-  *ptr = value;
+  __asm__ __volatile__ (  // NOLINT
+    "stlr %w[value], %[ptr]  \n\t"
+    : [ptr]"=Q" (*ptr)
+    : [value]"r" (value)
+    : "memory"
+  );  // NOLINT
 }
 
 inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
@@ -198,8 +165,15 @@
 }
 
 inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
-  Atomic32 value = *ptr;
-  MemoryBarrier();
+  Atomic32 value;
+
+  __asm__ __volatile__ (  // NOLINT
+    "ldar %w[value], %[ptr]  \n\t"
+    : [value]"=r" (value)
+    : [ptr]"Q" (*ptr)
+    : "memory"
+  );  // NOLINT
+
   return value;
 }
 
@@ -225,13 +199,12 @@
     "stxr %w[temp], %[new_value], %[ptr]   \n\t"
     "cbnz %w[temp], 0b                     \n\t"
     "1:                                    \n\t"
-    "clrex                                 \n\t"
     : [prev]"=&r" (prev),
       [temp]"=&r" (temp),
       [ptr]"+Q" (*ptr)
-    : [old_value]"r" (old_value),
+    : [old_value]"IJr" (old_value),
       [new_value]"r" (new_value)
-    : "memory", "cc"
+    : "cc", "memory"
   );  // NOLINT
 
   return prev;
@@ -271,7 +244,7 @@
     : [result]"=&r" (result),
       [temp]"=&r" (temp),
       [ptr]"+Q" (*ptr)
-    : [increment]"r" (increment)
+    : [increment]"IJr" (increment)
     : "memory"
   );  // NOLINT
 
@@ -290,26 +263,8 @@
 inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
                                        Atomic64 old_value,
                                        Atomic64 new_value) {
-  Atomic64 prev;
-  int32_t temp;
-
-  __asm__ __volatile__ (  // NOLINT
-    "0:                                    \n\t"
-    "ldxr %[prev], %[ptr]                  \n\t"
-    "cmp %[prev], %[old_value]             \n\t"
-    "bne 1f                                \n\t"
-    "stxr %w[temp], %[new_value], %[ptr]   \n\t"
-    "cbnz %w[temp], 0b                     \n\t"
-    "dmb ish                               \n\t"
-    "1:                                    \n\t"
-    "clrex                                 \n\t"
-    : [prev]"=&r" (prev),
-      [temp]"=&r" (temp),
-      [ptr]"+Q" (*ptr)
-    : [old_value]"r" (old_value),
-      [new_value]"r" (new_value)
-    : "memory", "cc"
-  );  // NOLINT
+  Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  MemoryBarrier();
 
   return prev;
 }
@@ -317,27 +272,8 @@
 inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
                                        Atomic64 old_value,
                                        Atomic64 new_value) {
-  Atomic64 prev;
-  int32_t temp;
-
   MemoryBarrier();
-
-  __asm__ __volatile__ (  // NOLINT
-    "0:                                    \n\t"
-    "ldxr %[prev], %[ptr]                  \n\t"
-    "cmp %[prev], %[old_value]             \n\t"
-    "bne 1f                                \n\t"
-    "stxr %w[temp], %[new_value], %[ptr]   \n\t"
-    "cbnz %w[temp], 0b                     \n\t"
-    "1:                                    \n\t"
-    "clrex                                 \n\t"
-    : [prev]"=&r" (prev),
-      [temp]"=&r" (temp),
-      [ptr]"+Q" (*ptr)
-    : [old_value]"r" (old_value),
-      [new_value]"r" (new_value)
-    : "memory", "cc"
-  );  // NOLINT
+  Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
 
   return prev;
 }
@@ -352,8 +288,12 @@
 }
 
 inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
-  MemoryBarrier();
-  *ptr = value;
+  __asm__ __volatile__ (  // NOLINT
+    "stlr %x[value], %[ptr]  \n\t"
+    : [ptr]"=Q" (*ptr)
+    : [value]"r" (value)
+    : "memory"
+  );  // NOLINT
 }
 
 inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
@@ -361,8 +301,15 @@
 }
 
 inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
-  Atomic64 value = *ptr;
-  MemoryBarrier();
+  Atomic64 value;
+
+  __asm__ __volatile__ (  // NOLINT
+    "ldar %x[value], %[ptr]  \n\t"
+    : [value]"=r" (value)
+    : [ptr]"Q" (*ptr)
+    : "memory"
+  );  // NOLINT
+
   return value;
 }
 
diff --git a/third_party/qcms/qcms.target.darwin-arm.mk b/third_party/qcms/qcms.target.darwin-arm.mk
index 9af603f..6b02925 100644
--- a/third_party/qcms/qcms.target.darwin-arm.mk
+++ b/third_party/qcms/qcms.target.darwin-arm.mk
@@ -43,7 +43,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -129,7 +128,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/qcms/qcms.target.darwin-x86.mk b/third_party/qcms/qcms.target.darwin-x86.mk
index d7a74a8..6afe12d 100644
--- a/third_party/qcms/qcms.target.darwin-x86.mk
+++ b/third_party/qcms/qcms.target.darwin-x86.mk
@@ -47,7 +47,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -134,7 +133,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/qcms/qcms.target.darwin-x86_64.mk b/third_party/qcms/qcms.target.darwin-x86_64.mk
index 35c5cc4..2988425 100644
--- a/third_party/qcms/qcms.target.darwin-x86_64.mk
+++ b/third_party/qcms/qcms.target.darwin-x86_64.mk
@@ -47,7 +47,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -134,7 +133,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/qcms/qcms.target.linux-arm.mk b/third_party/qcms/qcms.target.linux-arm.mk
index 9af603f..6b02925 100644
--- a/third_party/qcms/qcms.target.linux-arm.mk
+++ b/third_party/qcms/qcms.target.linux-arm.mk
@@ -43,7 +43,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -129,7 +128,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/qcms/qcms.target.linux-x86.mk b/third_party/qcms/qcms.target.linux-x86.mk
index d7a74a8..6afe12d 100644
--- a/third_party/qcms/qcms.target.linux-x86.mk
+++ b/third_party/qcms/qcms.target.linux-x86.mk
@@ -47,7 +47,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -134,7 +133,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/qcms/qcms.target.linux-x86_64.mk b/third_party/qcms/qcms.target.linux-x86_64.mk
index 35c5cc4..2988425 100644
--- a/third_party/qcms/qcms.target.linux-x86_64.mk
+++ b/third_party/qcms/qcms.target.linux-x86_64.mk
@@ -47,7 +47,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -134,7 +133,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/re2/re2.target.darwin-arm.mk b/third_party/re2/re2.target.darwin-arm.mk
index 8c732cb..0461dac 100644
--- a/third_party/re2/re2.target.darwin-arm.mk
+++ b/third_party/re2/re2.target.darwin-arm.mk
@@ -64,7 +64,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -152,7 +151,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/re2/re2.target.darwin-x86.mk b/third_party/re2/re2.target.darwin-x86.mk
index e780e4f..61e85d9 100644
--- a/third_party/re2/re2.target.darwin-x86.mk
+++ b/third_party/re2/re2.target.darwin-x86.mk
@@ -66,7 +66,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +153,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/re2/re2.target.darwin-x86_64.mk b/third_party/re2/re2.target.darwin-x86_64.mk
index a76c609..686973d 100644
--- a/third_party/re2/re2.target.darwin-x86_64.mk
+++ b/third_party/re2/re2.target.darwin-x86_64.mk
@@ -66,7 +66,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +153,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/re2/re2.target.linux-arm.mk b/third_party/re2/re2.target.linux-arm.mk
index 8c732cb..0461dac 100644
--- a/third_party/re2/re2.target.linux-arm.mk
+++ b/third_party/re2/re2.target.linux-arm.mk
@@ -64,7 +64,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -152,7 +151,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/re2/re2.target.linux-x86.mk b/third_party/re2/re2.target.linux-x86.mk
index e780e4f..61e85d9 100644
--- a/third_party/re2/re2.target.linux-x86.mk
+++ b/third_party/re2/re2.target.linux-x86.mk
@@ -66,7 +66,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +153,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/re2/re2.target.linux-x86_64.mk b/third_party/re2/re2.target.linux-x86_64.mk
index a76c609..686973d 100644
--- a/third_party/re2/re2.target.linux-x86_64.mk
+++ b/third_party/re2/re2.target.linux-x86_64.mk
@@ -66,7 +66,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -154,7 +153,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/sfntly/sfntly.target.darwin-arm.mk b/third_party/sfntly/sfntly.target.darwin-arm.mk
index 704c379..7d9fcbc 100644
--- a/third_party/sfntly/sfntly.target.darwin-arm.mk
+++ b/third_party/sfntly/sfntly.target.darwin-arm.mk
@@ -92,7 +92,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -183,7 +182,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/sfntly/sfntly.target.darwin-x86.mk b/third_party/sfntly/sfntly.target.darwin-x86.mk
index 76b7a8f..03ed18f 100644
--- a/third_party/sfntly/sfntly.target.darwin-x86.mk
+++ b/third_party/sfntly/sfntly.target.darwin-x86.mk
@@ -94,7 +94,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -185,7 +184,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/sfntly/sfntly.target.darwin-x86_64.mk b/third_party/sfntly/sfntly.target.darwin-x86_64.mk
index 2920bf9..908eea0 100644
--- a/third_party/sfntly/sfntly.target.darwin-x86_64.mk
+++ b/third_party/sfntly/sfntly.target.darwin-x86_64.mk
@@ -94,7 +94,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -185,7 +184,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/sfntly/sfntly.target.linux-arm.mk b/third_party/sfntly/sfntly.target.linux-arm.mk
index 704c379..7d9fcbc 100644
--- a/third_party/sfntly/sfntly.target.linux-arm.mk
+++ b/third_party/sfntly/sfntly.target.linux-arm.mk
@@ -92,7 +92,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -183,7 +182,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/sfntly/sfntly.target.linux-x86.mk b/third_party/sfntly/sfntly.target.linux-x86.mk
index 76b7a8f..03ed18f 100644
--- a/third_party/sfntly/sfntly.target.linux-x86.mk
+++ b/third_party/sfntly/sfntly.target.linux-x86.mk
@@ -94,7 +94,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -185,7 +184,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/sfntly/sfntly.target.linux-x86_64.mk b/third_party/sfntly/sfntly.target.linux-x86_64.mk
index 2920bf9..908eea0 100644
--- a/third_party/sfntly/sfntly.target.linux-x86_64.mk
+++ b/third_party/sfntly/sfntly.target.linux-x86_64.mk
@@ -94,7 +94,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -185,7 +184,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/smhasher/cityhash.target.darwin-arm.mk b/third_party/smhasher/cityhash.target.darwin-arm.mk
index ef9a167..34fb58a 100644
--- a/third_party/smhasher/cityhash.target.darwin-arm.mk
+++ b/third_party/smhasher/cityhash.target.darwin-arm.mk
@@ -39,7 +39,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -125,7 +124,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/smhasher/cityhash.target.darwin-x86.mk b/third_party/smhasher/cityhash.target.darwin-x86.mk
index 9e86cad..fe51c11 100644
--- a/third_party/smhasher/cityhash.target.darwin-x86.mk
+++ b/third_party/smhasher/cityhash.target.darwin-x86.mk
@@ -41,7 +41,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/smhasher/cityhash.target.darwin-x86_64.mk b/third_party/smhasher/cityhash.target.darwin-x86_64.mk
index 5b74964..320a670 100644
--- a/third_party/smhasher/cityhash.target.darwin-x86_64.mk
+++ b/third_party/smhasher/cityhash.target.darwin-x86_64.mk
@@ -41,7 +41,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/smhasher/cityhash.target.linux-arm.mk b/third_party/smhasher/cityhash.target.linux-arm.mk
index ef9a167..34fb58a 100644
--- a/third_party/smhasher/cityhash.target.linux-arm.mk
+++ b/third_party/smhasher/cityhash.target.linux-arm.mk
@@ -39,7 +39,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -125,7 +124,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/smhasher/cityhash.target.linux-x86.mk b/third_party/smhasher/cityhash.target.linux-x86.mk
index 9e86cad..fe51c11 100644
--- a/third_party/smhasher/cityhash.target.linux-x86.mk
+++ b/third_party/smhasher/cityhash.target.linux-x86.mk
@@ -41,7 +41,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/smhasher/cityhash.target.linux-x86_64.mk b/third_party/smhasher/cityhash.target.linux-x86_64.mk
index 5b74964..320a670 100644
--- a/third_party/smhasher/cityhash.target.linux-x86_64.mk
+++ b/third_party/smhasher/cityhash.target.linux-x86_64.mk
@@ -41,7 +41,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -127,7 +126,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/sqlite/sqlite.target.darwin-arm.mk b/third_party/sqlite/sqlite.target.darwin-arm.mk
index e191e29..de00372 100644
--- a/third_party/sqlite/sqlite.target.darwin-arm.mk
+++ b/third_party/sqlite/sqlite.target.darwin-arm.mk
@@ -47,7 +47,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -156,7 +155,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/sqlite/sqlite.target.darwin-x86.mk b/third_party/sqlite/sqlite.target.darwin-x86.mk
index f420831..8963c0b 100644
--- a/third_party/sqlite/sqlite.target.darwin-x86.mk
+++ b/third_party/sqlite/sqlite.target.darwin-x86.mk
@@ -49,7 +49,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +157,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/sqlite/sqlite.target.darwin-x86_64.mk b/third_party/sqlite/sqlite.target.darwin-x86_64.mk
index aeca9f4..6647ea7 100644
--- a/third_party/sqlite/sqlite.target.darwin-x86_64.mk
+++ b/third_party/sqlite/sqlite.target.darwin-x86_64.mk
@@ -49,7 +49,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +157,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/sqlite/sqlite.target.linux-arm.mk b/third_party/sqlite/sqlite.target.linux-arm.mk
index e191e29..de00372 100644
--- a/third_party/sqlite/sqlite.target.linux-arm.mk
+++ b/third_party/sqlite/sqlite.target.linux-arm.mk
@@ -47,7 +47,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -156,7 +155,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/sqlite/sqlite.target.linux-x86.mk b/third_party/sqlite/sqlite.target.linux-x86.mk
index f420831..8963c0b 100644
--- a/third_party/sqlite/sqlite.target.linux-x86.mk
+++ b/third_party/sqlite/sqlite.target.linux-x86.mk
@@ -49,7 +49,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +157,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/sqlite/sqlite.target.linux-x86_64.mk b/third_party/sqlite/sqlite.target.linux-x86_64.mk
index aeca9f4..6647ea7 100644
--- a/third_party/sqlite/sqlite.target.linux-x86_64.mk
+++ b/third_party/sqlite/sqlite.target.linux-x86_64.mk
@@ -49,7 +49,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -158,7 +157,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/usrsctp/usrsctplib.target.darwin-arm.mk b/third_party/usrsctp/usrsctplib.target.darwin-arm.mk
index 0bb6508..28beda3 100644
--- a/third_party/usrsctp/usrsctplib.target.darwin-arm.mk
+++ b/third_party/usrsctp/usrsctplib.target.darwin-arm.mk
@@ -63,7 +63,6 @@
 	-w \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -159,7 +158,6 @@
 	-w \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/usrsctp/usrsctplib.target.darwin-x86.mk b/third_party/usrsctp/usrsctplib.target.darwin-x86.mk
index 6cd8c18..797e354 100644
--- a/third_party/usrsctp/usrsctplib.target.darwin-x86.mk
+++ b/third_party/usrsctp/usrsctplib.target.darwin-x86.mk
@@ -65,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -161,7 +160,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/usrsctp/usrsctplib.target.darwin-x86_64.mk b/third_party/usrsctp/usrsctplib.target.darwin-x86_64.mk
index 6947ff0..47a2b1e 100644
--- a/third_party/usrsctp/usrsctplib.target.darwin-x86_64.mk
+++ b/third_party/usrsctp/usrsctplib.target.darwin-x86_64.mk
@@ -65,7 +65,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -162,7 +161,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/usrsctp/usrsctplib.target.linux-arm.mk b/third_party/usrsctp/usrsctplib.target.linux-arm.mk
index 0bb6508..28beda3 100644
--- a/third_party/usrsctp/usrsctplib.target.linux-arm.mk
+++ b/third_party/usrsctp/usrsctplib.target.linux-arm.mk
@@ -63,7 +63,6 @@
 	-w \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -159,7 +158,6 @@
 	-w \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/usrsctp/usrsctplib.target.linux-x86.mk b/third_party/usrsctp/usrsctplib.target.linux-x86.mk
index 6cd8c18..797e354 100644
--- a/third_party/usrsctp/usrsctplib.target.linux-x86.mk
+++ b/third_party/usrsctp/usrsctplib.target.linux-x86.mk
@@ -65,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -161,7 +160,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/usrsctp/usrsctplib.target.linux-x86_64.mk b/third_party/usrsctp/usrsctplib.target.linux-x86_64.mk
index 6947ff0..47a2b1e 100644
--- a/third_party/usrsctp/usrsctplib.target.linux-x86_64.mk
+++ b/third_party/usrsctp/usrsctplib.target.linux-x86_64.mk
@@ -65,7 +65,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -162,7 +161,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/yasm/config_sources.host.darwin-x86.mk b/third_party/yasm/config_sources.host.darwin-x86.mk
index 076a7d7..2e619ac 100644
--- a/third_party/yasm/config_sources.host.darwin-x86.mk
+++ b/third_party/yasm/config_sources.host.darwin-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := .stamp
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -156,7 +155,6 @@
 
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
 LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
@@ -164,5 +162,3 @@
 	$(hide) echo "Gyp timestamp: $@"
 	$(hide) mkdir -p $(dir $@)
 	$(hide) touch $@
-
-LOCAL_2ND_ARCH_VAR_PREFIX :=
diff --git a/third_party/yasm/config_sources.host.darwin-x86_64.mk b/third_party/yasm/config_sources.host.darwin-x86_64.mk
index 0461d77..8aefdbd 100644
--- a/third_party/yasm/config_sources.host.darwin-x86_64.mk
+++ b/third_party/yasm/config_sources.host.darwin-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := .stamp
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -158,7 +157,6 @@
 
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
 LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
@@ -166,5 +164,3 @@
 	$(hide) echo "Gyp timestamp: $@"
 	$(hide) mkdir -p $(dir $@)
 	$(hide) touch $@
-
-LOCAL_2ND_ARCH_VAR_PREFIX :=
diff --git a/third_party/yasm/config_sources.host.linux-x86.mk b/third_party/yasm/config_sources.host.linux-x86.mk
index 076a7d7..2e619ac 100644
--- a/third_party/yasm/config_sources.host.linux-x86.mk
+++ b/third_party/yasm/config_sources.host.linux-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := .stamp
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -156,7 +155,6 @@
 
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
 LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
@@ -164,5 +162,3 @@
 	$(hide) echo "Gyp timestamp: $@"
 	$(hide) mkdir -p $(dir $@)
 	$(hide) touch $@
-
-LOCAL_2ND_ARCH_VAR_PREFIX :=
diff --git a/third_party/yasm/config_sources.host.linux-x86_64.mk b/third_party/yasm/config_sources.host.linux-x86_64.mk
index 0461d77..8aefdbd 100644
--- a/third_party/yasm/config_sources.host.linux-x86_64.mk
+++ b/third_party/yasm/config_sources.host.linux-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := .stamp
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -158,7 +157,6 @@
 
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
 LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
@@ -166,5 +164,3 @@
 	$(hide) echo "Gyp timestamp: $@"
 	$(hide) mkdir -p $(dir $@)
 	$(hide) touch $@
-
-LOCAL_2ND_ARCH_VAR_PREFIX :=
diff --git a/third_party/yasm/generate_files.host.darwin-x86.mk b/third_party/yasm/generate_files.host.darwin-x86.mk
index bc5f2f2..6ac00f7 100644
--- a/third_party/yasm/generate_files.host.darwin-x86.mk
+++ b/third_party/yasm/generate_files.host.darwin-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := .stamp
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -19,6 +18,7 @@
 
 ### Rules for action "generate_x86_insn":
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +31,7 @@
 
 ### Rules for action "generate_version":
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +45,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_generate_files_host_generate_gperf":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/genperf'], 'extension': 'gperf', 'process_outputs_as_sources': '0', 'outputs': ['$(gyp_shared_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_gperf', 'rule_sources': ['source/patched-yasm/modules/arch/x86/x86cpu.gperf', 'source/patched-yasm/modules/arch/x86/x86regtmod.gperf'], 'action': ['$(gyp_shared_intermediate_dir)/genperf', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'message': 'yasm genperf for $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -207,7 +210,6 @@
 
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
 LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
@@ -215,5 +217,3 @@
 	$(hide) echo "Gyp timestamp: $@"
 	$(hide) mkdir -p $(dir $@)
 	$(hide) touch $@
-
-LOCAL_2ND_ARCH_VAR_PREFIX :=
diff --git a/third_party/yasm/generate_files.host.darwin-x86_64.mk b/third_party/yasm/generate_files.host.darwin-x86_64.mk
index c0814a8..6214521 100644
--- a/third_party/yasm/generate_files.host.darwin-x86_64.mk
+++ b/third_party/yasm/generate_files.host.darwin-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := .stamp
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -19,6 +18,7 @@
 
 ### Rules for action "generate_x86_insn":
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +31,7 @@
 
 ### Rules for action "generate_version":
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +45,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_generate_files_host_generate_gperf":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/genperf'], 'extension': 'gperf', 'process_outputs_as_sources': '0', 'outputs': ['$(gyp_shared_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_gperf', 'rule_sources': ['source/patched-yasm/modules/arch/x86/x86cpu.gperf', 'source/patched-yasm/modules/arch/x86/x86regtmod.gperf'], 'action': ['$(gyp_shared_intermediate_dir)/genperf', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'message': 'yasm genperf for $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -209,7 +212,6 @@
 
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
 LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
@@ -217,5 +219,3 @@
 	$(hide) echo "Gyp timestamp: $@"
 	$(hide) mkdir -p $(dir $@)
 	$(hide) touch $@
-
-LOCAL_2ND_ARCH_VAR_PREFIX :=
diff --git a/third_party/yasm/generate_files.host.linux-x86.mk b/third_party/yasm/generate_files.host.linux-x86.mk
index bc5f2f2..6ac00f7 100644
--- a/third_party/yasm/generate_files.host.linux-x86.mk
+++ b/third_party/yasm/generate_files.host.linux-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := .stamp
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -19,6 +18,7 @@
 
 ### Rules for action "generate_x86_insn":
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +31,7 @@
 
 ### Rules for action "generate_version":
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +45,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_generate_files_host_generate_gperf":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/genperf'], 'extension': 'gperf', 'process_outputs_as_sources': '0', 'outputs': ['$(gyp_shared_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_gperf', 'rule_sources': ['source/patched-yasm/modules/arch/x86/x86cpu.gperf', 'source/patched-yasm/modules/arch/x86/x86regtmod.gperf'], 'action': ['$(gyp_shared_intermediate_dir)/genperf', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'message': 'yasm genperf for $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -207,7 +210,6 @@
 
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
 LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
@@ -215,5 +217,3 @@
 	$(hide) echo "Gyp timestamp: $@"
 	$(hide) mkdir -p $(dir $@)
 	$(hide) touch $@
-
-LOCAL_2ND_ARCH_VAR_PREFIX :=
diff --git a/third_party/yasm/generate_files.host.linux-x86_64.mk b/third_party/yasm/generate_files.host.linux-x86_64.mk
index c0814a8..6214521 100644
--- a/third_party/yasm/generate_files.host.linux-x86_64.mk
+++ b/third_party/yasm/generate_files.host.linux-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := .stamp
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -19,6 +18,7 @@
 
 ### Rules for action "generate_x86_insn":
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86insns.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +31,7 @@
 
 ### Rules for action "generate_version":
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/version.mac: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -44,6 +45,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_generate_files_host_generate_gperf":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/genperf'], 'extension': 'gperf', 'process_outputs_as_sources': '0', 'outputs': ['$(gyp_shared_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_gperf', 'rule_sources': ['source/patched-yasm/modules/arch/x86/x86cpu.gperf', 'source/patched-yasm/modules/arch/x86/x86regtmod.gperf'], 'action': ['$(gyp_shared_intermediate_dir)/genperf', '$(RULE_SOURCES)', '$(gyp_shared_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'message': 'yasm genperf for $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86cpu.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -52,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/third_party/yasm/x86regtmod.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -209,7 +212,6 @@
 
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp
 LOCAL_UNINSTALLABLE_MODULE := true
-LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
@@ -217,5 +219,3 @@
 	$(hide) echo "Gyp timestamp: $@"
 	$(hide) mkdir -p $(dir $@)
 	$(hide) touch $@
-
-LOCAL_2ND_ARCH_VAR_PREFIX :=
diff --git a/third_party/yasm/genmacro.host.darwin-x86.mk b/third_party/yasm/genmacro.host.darwin-x86.mk
index 7dc7431..43079fd 100644
--- a/third_party/yasm/genmacro.host.darwin-x86.mk
+++ b/third_party/yasm/genmacro.host.darwin-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genmacro.host.darwin-x86_64.mk b/third_party/yasm/genmacro.host.darwin-x86_64.mk
index 6a6173e..974980e 100644
--- a/third_party/yasm/genmacro.host.darwin-x86_64.mk
+++ b/third_party/yasm/genmacro.host.darwin-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genmacro.host.linux-x86.mk b/third_party/yasm/genmacro.host.linux-x86.mk
index c25706a..3463ff7 100644
--- a/third_party/yasm/genmacro.host.linux-x86.mk
+++ b/third_party/yasm/genmacro.host.linux-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genmacro.host.linux-x86_64.mk b/third_party/yasm/genmacro.host.linux-x86_64.mk
index 81d8b58..5bd43c6 100644
--- a/third_party/yasm/genmacro.host.linux-x86_64.mk
+++ b/third_party/yasm/genmacro.host.linux-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genmodule.host.darwin-x86.mk b/third_party/yasm/genmodule.host.darwin-x86.mk
index 15cbc16..58a4704 100644
--- a/third_party/yasm/genmodule.host.darwin-x86.mk
+++ b/third_party/yasm/genmodule.host.darwin-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genmodule.host.darwin-x86_64.mk b/third_party/yasm/genmodule.host.darwin-x86_64.mk
index bcc1475..b080a00 100644
--- a/third_party/yasm/genmodule.host.darwin-x86_64.mk
+++ b/third_party/yasm/genmodule.host.darwin-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genmodule.host.linux-x86.mk b/third_party/yasm/genmodule.host.linux-x86.mk
index 79f916b..018b58e 100644
--- a/third_party/yasm/genmodule.host.linux-x86.mk
+++ b/third_party/yasm/genmodule.host.linux-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genmodule.host.linux-x86_64.mk b/third_party/yasm/genmodule.host.linux-x86_64.mk
index 09a54eb..1f3456e 100644
--- a/third_party/yasm/genmodule.host.linux-x86_64.mk
+++ b/third_party/yasm/genmodule.host.linux-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genperf.host.darwin-x86.mk b/third_party/yasm/genperf.host.darwin-x86.mk
index 259b1b1..a128e7e 100644
--- a/third_party/yasm/genperf.host.darwin-x86.mk
+++ b/third_party/yasm/genperf.host.darwin-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genperf.host.darwin-x86_64.mk b/third_party/yasm/genperf.host.darwin-x86_64.mk
index 9c0c6d4..4693c40 100644
--- a/third_party/yasm/genperf.host.darwin-x86_64.mk
+++ b/third_party/yasm/genperf.host.darwin-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genperf.host.linux-x86.mk b/third_party/yasm/genperf.host.linux-x86.mk
index 3d7d3a0..4d4c34c 100644
--- a/third_party/yasm/genperf.host.linux-x86.mk
+++ b/third_party/yasm/genperf.host.linux-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genperf.host.linux-x86_64.mk b/third_party/yasm/genperf.host.linux-x86_64.mk
index 931e558..76d74b0 100644
--- a/third_party/yasm/genperf.host.linux-x86_64.mk
+++ b/third_party/yasm/genperf.host.linux-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genperf_libs.host.darwin-x86.mk b/third_party/yasm/genperf_libs.host.darwin-x86.mk
index b623f11..c8338b3 100644
--- a/third_party/yasm/genperf_libs.host.darwin-x86.mk
+++ b/third_party/yasm/genperf_libs.host.darwin-x86.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genperf_libs.host.darwin-x86_64.mk b/third_party/yasm/genperf_libs.host.darwin-x86_64.mk
index 08ba320..8660d6d 100644
--- a/third_party/yasm/genperf_libs.host.darwin-x86_64.mk
+++ b/third_party/yasm/genperf_libs.host.darwin-x86_64.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genperf_libs.host.linux-x86.mk b/third_party/yasm/genperf_libs.host.linux-x86.mk
index 8b9194f..6a01743 100644
--- a/third_party/yasm/genperf_libs.host.linux-x86.mk
+++ b/third_party/yasm/genperf_libs.host.linux-x86.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genperf_libs.host.linux-x86_64.mk b/third_party/yasm/genperf_libs.host.linux-x86_64.mk
index 774cdc9..bb2063c 100644
--- a/third_party/yasm/genperf_libs.host.linux-x86_64.mk
+++ b/third_party/yasm/genperf_libs.host.linux-x86_64.mk
@@ -7,8 +7,7 @@
 LOCAL_MODULE_SUFFIX := .a
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genstring.host.darwin-x86.mk b/third_party/yasm/genstring.host.darwin-x86.mk
index c8dfc37..61f3995 100644
--- a/third_party/yasm/genstring.host.darwin-x86.mk
+++ b/third_party/yasm/genstring.host.darwin-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genstring.host.darwin-x86_64.mk b/third_party/yasm/genstring.host.darwin-x86_64.mk
index 624a704..83a2746 100644
--- a/third_party/yasm/genstring.host.darwin-x86_64.mk
+++ b/third_party/yasm/genstring.host.darwin-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genstring.host.linux-x86.mk b/third_party/yasm/genstring.host.linux-x86.mk
index b3b5c6a..79c23b2 100644
--- a/third_party/yasm/genstring.host.linux-x86.mk
+++ b/third_party/yasm/genstring.host.linux-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genstring.host.linux-x86_64.mk b/third_party/yasm/genstring.host.linux-x86_64.mk
index b5b25af..0301fc4 100644
--- a/third_party/yasm/genstring.host.linux-x86_64.mk
+++ b/third_party/yasm/genstring.host.linux-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genversion.host.darwin-x86.mk b/third_party/yasm/genversion.host.darwin-x86.mk
index 41b6982..bd21d2c 100644
--- a/third_party/yasm/genversion.host.darwin-x86.mk
+++ b/third_party/yasm/genversion.host.darwin-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genversion.host.darwin-x86_64.mk b/third_party/yasm/genversion.host.darwin-x86_64.mk
index 933a16d..448040b 100644
--- a/third_party/yasm/genversion.host.darwin-x86_64.mk
+++ b/third_party/yasm/genversion.host.darwin-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genversion.host.linux-x86.mk b/third_party/yasm/genversion.host.linux-x86.mk
index cd272cc..4bb3aff 100644
--- a/third_party/yasm/genversion.host.linux-x86.mk
+++ b/third_party/yasm/genversion.host.linux-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/genversion.host.linux-x86_64.mk b/third_party/yasm/genversion.host.linux-x86_64.mk
index e3101c5..1e7f5fd 100644
--- a/third_party/yasm/genversion.host.linux-x86_64.mk
+++ b/third_party/yasm/genversion.host.linux-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/re2c.host.darwin-x86.mk b/third_party/yasm/re2c.host.darwin-x86.mk
index 4085abe..50c5e3e 100644
--- a/third_party/yasm/re2c.host.darwin-x86.mk
+++ b/third_party/yasm/re2c.host.darwin-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/re2c.host.darwin-x86_64.mk b/third_party/yasm/re2c.host.darwin-x86_64.mk
index 8a5139f..aca77b8 100644
--- a/third_party/yasm/re2c.host.darwin-x86_64.mk
+++ b/third_party/yasm/re2c.host.darwin-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/re2c.host.linux-x86.mk b/third_party/yasm/re2c.host.linux-x86.mk
index c64ad4d..87b31c8 100644
--- a/third_party/yasm/re2c.host.linux-x86.mk
+++ b/third_party/yasm/re2c.host.linux-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/re2c.host.linux-x86_64.mk b/third_party/yasm/re2c.host.linux-x86_64.mk
index d9d7066..40f043b 100644
--- a/third_party/yasm/re2c.host.linux-x86_64.mk
+++ b/third_party/yasm/re2c.host.linux-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
diff --git a/third_party/yasm/yasm.host.darwin-x86.mk b/third_party/yasm/yasm.host.darwin-x86.mk
index 1a69bd9..38afbda 100644
--- a/third_party/yasm/yasm.host.darwin-x86.mk
+++ b/third_party/yasm/yasm.host.darwin-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -25,6 +24,7 @@
 
 ### Rules for action "generate_nasm_macros":
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -35,6 +35,7 @@
 
 ### Rules for action "generate_nasm_version":
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -45,6 +46,7 @@
 
 ### Rules for action "generate_win64_gas":
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,6 +57,7 @@
 
 ### Rules for action "generate_win64_nasm":
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,6 +68,7 @@
 
 ### Rules for action "generate_license":
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/license.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -75,6 +79,7 @@
 
 ### Rules for action "generate_lc3b_token":
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -85,6 +90,7 @@
 
 ### Rules for action "generate_module":
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/module.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +104,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_yasm_host_generate_gperf":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/genperf'], 'extension': 'gperf', 'process_outputs_as_sources': '0', 'outputs': ['$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_gperf', 'rule_sources': ['$(gyp_shared_intermediate_dir)/third_party/yasm/x86insn_nasm.gperf', '$(gyp_shared_intermediate_dir)/third_party/yasm/x86insn_gas.gperf'], 'action': ['$(gyp_shared_intermediate_dir)/genperf', '$(RULE_SOURCES)', '$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'message': 'yasm gperf for $(RULE_SOURCES)'}":
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +113,7 @@
 
 
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -117,6 +125,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_yasm_host_generate_re2c":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/re2c'], 'extension': 're', 'process_outputs_as_sources': '1', 'outputs': ['$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_re2c', 'rule_sources': ['source/patched-yasm/modules/parsers/gas/gas-token.re', 'source/patched-yasm/modules/parsers/nasm/nasm-token.re'], 'action': ['$(gyp_shared_intermediate_dir)/re2c', '-b', '-o', '$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c', '$(RULE_SOURCES)'], 'message': 'yasm re2c for $(RULE_SOURCES)'}":
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -125,6 +134,7 @@
 
 
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/yasm/yasm.host.darwin-x86_64.mk b/third_party/yasm/yasm.host.darwin-x86_64.mk
index 07d553f..97935fc 100644
--- a/third_party/yasm/yasm.host.darwin-x86_64.mk
+++ b/third_party/yasm/yasm.host.darwin-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -25,6 +24,7 @@
 
 ### Rules for action "generate_nasm_macros":
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -35,6 +35,7 @@
 
 ### Rules for action "generate_nasm_version":
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -45,6 +46,7 @@
 
 ### Rules for action "generate_win64_gas":
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,6 +57,7 @@
 
 ### Rules for action "generate_win64_nasm":
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,6 +68,7 @@
 
 ### Rules for action "generate_license":
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/license.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -75,6 +79,7 @@
 
 ### Rules for action "generate_lc3b_token":
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -85,6 +90,7 @@
 
 ### Rules for action "generate_module":
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/module.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +104,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_yasm_host_generate_gperf":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/genperf'], 'extension': 'gperf', 'process_outputs_as_sources': '0', 'outputs': ['$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_gperf', 'rule_sources': ['$(gyp_shared_intermediate_dir)/third_party/yasm/x86insn_nasm.gperf', '$(gyp_shared_intermediate_dir)/third_party/yasm/x86insn_gas.gperf'], 'action': ['$(gyp_shared_intermediate_dir)/genperf', '$(RULE_SOURCES)', '$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'message': 'yasm gperf for $(RULE_SOURCES)'}":
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +113,7 @@
 
 
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -117,6 +125,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_yasm_host_generate_re2c":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/re2c'], 'extension': 're', 'process_outputs_as_sources': '1', 'outputs': ['$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_re2c', 'rule_sources': ['source/patched-yasm/modules/parsers/gas/gas-token.re', 'source/patched-yasm/modules/parsers/nasm/nasm-token.re'], 'action': ['$(gyp_shared_intermediate_dir)/re2c', '-b', '-o', '$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c', '$(RULE_SOURCES)'], 'message': 'yasm re2c for $(RULE_SOURCES)'}":
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -125,6 +134,7 @@
 
 
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/yasm/yasm.host.linux-x86.mk b/third_party/yasm/yasm.host.linux-x86.mk
index a20d701..5e6b625 100644
--- a/third_party/yasm/yasm.host.linux-x86.mk
+++ b/third_party/yasm/yasm.host.linux-x86.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -25,6 +24,7 @@
 
 ### Rules for action "generate_nasm_macros":
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -35,6 +35,7 @@
 
 ### Rules for action "generate_nasm_version":
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -45,6 +46,7 @@
 
 ### Rules for action "generate_win64_gas":
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,6 +57,7 @@
 
 ### Rules for action "generate_win64_nasm":
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,6 +68,7 @@
 
 ### Rules for action "generate_license":
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/license.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -75,6 +79,7 @@
 
 ### Rules for action "generate_lc3b_token":
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -85,6 +90,7 @@
 
 ### Rules for action "generate_module":
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/module.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +104,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_yasm_host_generate_gperf":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/genperf'], 'extension': 'gperf', 'process_outputs_as_sources': '0', 'outputs': ['$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_gperf', 'rule_sources': ['$(gyp_shared_intermediate_dir)/third_party/yasm/x86insn_nasm.gperf', '$(gyp_shared_intermediate_dir)/third_party/yasm/x86insn_gas.gperf'], 'action': ['$(gyp_shared_intermediate_dir)/genperf', '$(RULE_SOURCES)', '$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'message': 'yasm gperf for $(RULE_SOURCES)'}":
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +113,7 @@
 
 
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -117,6 +125,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_yasm_host_generate_re2c":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/re2c'], 'extension': 're', 'process_outputs_as_sources': '1', 'outputs': ['$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_re2c', 'rule_sources': ['source/patched-yasm/modules/parsers/gas/gas-token.re', 'source/patched-yasm/modules/parsers/nasm/nasm-token.re'], 'action': ['$(gyp_shared_intermediate_dir)/re2c', '-b', '-o', '$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c', '$(RULE_SOURCES)'], 'message': 'yasm re2c for $(RULE_SOURCES)'}":
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -125,6 +134,7 @@
 
 
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/yasm/yasm.host.linux-x86_64.mk b/third_party/yasm/yasm.host.linux-x86_64.mk
index 3f1459f..8839099 100644
--- a/third_party/yasm/yasm.host.linux-x86_64.mk
+++ b/third_party/yasm/yasm.host.linux-x86_64.mk
@@ -8,8 +8,7 @@
 LOCAL_MODULE_SUFFIX := 
 LOCAL_MODULE_TAGS := optional
 LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)
-gyp_intermediate_dir := $(call local-intermediates-dir,,$(GYP_VAR_PREFIX))
+gyp_intermediate_dir := $(call local-intermediates-dir)
 gyp_shared_intermediate_dir := $(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))
 
 # Make sure our deps are built first.
@@ -25,6 +24,7 @@
 
 ### Rules for action "generate_nasm_macros":
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-macros.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -35,6 +35,7 @@
 
 ### Rules for action "generate_nasm_version":
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-version.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -45,6 +46,7 @@
 
 ### Rules for action "generate_win64_gas":
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-gas.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,6 +57,7 @@
 
 ### Rules for action "generate_win64_nasm":
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/win64-nasm.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,6 +68,7 @@
 
 ### Rules for action "generate_license":
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/license.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/license.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -75,6 +79,7 @@
 
 ### Rules for action "generate_lc3b_token":
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/lc3bid.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -85,6 +90,7 @@
 
 ### Rules for action "generate_module":
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/module.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/module.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -98,6 +104,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_yasm_host_generate_gperf":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/genperf'], 'extension': 'gperf', 'process_outputs_as_sources': '0', 'outputs': ['$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_gperf', 'rule_sources': ['$(gyp_shared_intermediate_dir)/third_party/yasm/x86insn_nasm.gperf', '$(gyp_shared_intermediate_dir)/third_party/yasm/x86insn_gas.gperf'], 'action': ['$(gyp_shared_intermediate_dir)/genperf', '$(RULE_SOURCES)', '$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'message': 'yasm gperf for $(RULE_SOURCES)'}":
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_nasm.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -106,6 +113,7 @@
 
 
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/x86insn_gas.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -117,6 +125,7 @@
 ### Generated for rule "third_party_yasm_yasm_gyp_yasm_host_generate_re2c":
 # "{'inputs': ['$(gyp_shared_intermediate_dir)/re2c'], 'extension': 're', 'process_outputs_as_sources': '1', 'outputs': ['$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c'], 'rule_name': 'generate_re2c', 'rule_sources': ['source/patched-yasm/modules/parsers/gas/gas-token.re', 'source/patched-yasm/modules/parsers/nasm/nasm-token.re'], 'action': ['$(gyp_shared_intermediate_dir)/re2c', '-b', '-o', '$(gyp_intermediate_dir)/third_party/yasm/%(INPUT_ROOT)s.c', '$(RULE_SOURCES)'], 'message': 'yasm re2c for $(RULE_SOURCES)'}":
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/gas-token.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -125,6 +134,7 @@
 
 
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_local_path := $(LOCAL_PATH)
+$(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_intermediate_dir)/third_party/yasm/nasm-token.c: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/third_party/zlib/contrib/minizip/unzip.c b/third_party/zlib/contrib/minizip/unzip.c
index 22481a2..af59b80 100644
--- a/third_party/zlib/contrib/minizip/unzip.c
+++ b/third_party/zlib/contrib/minizip/unzip.c
@@ -1705,11 +1705,6 @@
 
     pfile_in_zip_read_info->stream.avail_out = (uInt)len;
 
-    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
-        (!(pfile_in_zip_read_info->raw)))
-        pfile_in_zip_read_info->stream.avail_out =
-            (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
-
     if ((len>pfile_in_zip_read_info->rest_read_compressed+
            pfile_in_zip_read_info->stream.avail_in) &&
          (pfile_in_zip_read_info->raw))
diff --git a/third_party/zlib/google/test/data/test_mismatch_size.zip b/third_party/zlib/google/test/data/test_mismatch_size.zip
new file mode 100644
index 0000000..b83c66f
--- /dev/null
+++ b/third_party/zlib/google/test/data/test_mismatch_size.zip
Binary files differ
diff --git a/third_party/zlib/google/zip.cc b/third_party/zlib/google/zip.cc
index 5fbfca9..726df33 100644
--- a/third_party/zlib/google/zip.cc
+++ b/third_party/zlib/google/zip.cc
@@ -26,38 +26,6 @@
 
 namespace {
 
-// Returns a zip_fileinfo struct with the time represented by |file_time|.
-zip_fileinfo TimeToZipFileInfo(const base::Time& file_time) {
-  base::Time::Exploded file_time_parts;
-  file_time.LocalExplode(&file_time_parts);
-
-  zip_fileinfo zip_info = {};
-  if (file_time_parts.year >= 1980) {
-    // This if check works around the handling of the year value in
-    // contrib/minizip/zip.c in function zip64local_TmzDateToDosDate
-    // It assumes that dates below 1980 are in the double digit format.
-    // Hence the fail safe option is to leave the date unset. Some programs
-    // might show the unset date as 1980-0-0 which is invalid.
-    zip_info.tmz_date.tm_year = file_time_parts.year;
-    zip_info.tmz_date.tm_mon = file_time_parts.month - 1;
-    zip_info.tmz_date.tm_mday = file_time_parts.day_of_month;
-    zip_info.tmz_date.tm_hour = file_time_parts.hour;
-    zip_info.tmz_date.tm_min = file_time_parts.minute;
-    zip_info.tmz_date.tm_sec = file_time_parts.second;
-  }
-
-  return zip_info;
-}
-
-// Returns a zip_fileinfo with the last modification date of |path| set.
-zip_fileinfo GetFileInfoForZipping(const base::FilePath& path) {
-  base::Time file_time;
-  base::File::Info file_info;
-  if (base::GetFileInfo(path, &file_info))
-    file_time = file_info.last_modified;
-  return TimeToZipFileInfo(file_time);
-}
-
 bool AddFileToZip(zipFile zip_file, const base::FilePath& src_dir) {
   base::File file(src_dir, base::File::FLAG_OPEN | base::File::FLAG_READ);
   if (!file.IsValid()) {
@@ -95,34 +63,9 @@
   if (is_directory)
     str_path += "/";
 
-  // Section 4.4.4 http://www.pkware.com/documents/casestudies/APPNOTE.TXT
-  // Setting the Language encoding flag so the file is told to be in utf-8.
-  const uLong LANGUAGE_ENCODING_FLAG = 0x1 << 11;
-
-  zip_fileinfo file_info = GetFileInfoForZipping(path);
-
-  if (ZIP_OK != zipOpenNewFileInZip4(
-                    zip_file,  // file
-                    str_path.c_str(),  // filename
-                    &file_info,  // zipfi
-                    NULL,  // extrafield_local,
-                    0u,  // size_extrafield_local
-                    NULL,  // extrafield_global
-                    0u,  // size_extrafield_global
-                    NULL,  // comment
-                    Z_DEFLATED,  // method
-                    Z_DEFAULT_COMPRESSION,  // level
-                    0,  // raw
-                    -MAX_WBITS,  // windowBits
-                    DEF_MEM_LEVEL,  // memLevel
-                    Z_DEFAULT_STRATEGY,  // strategy
-                    NULL,  // password
-                    0,  // crcForCrypting
-                    0,  // versionMadeBy
-                    LANGUAGE_ENCODING_FLAG)) {  // flagBase
-    DLOG(ERROR) << "Could not open zip file entry " << str_path;
+  zip_fileinfo file_info = zip::internal::GetFileInfoForZipping(path);
+  if (!zip::internal::ZipOpenNewFileInZip(zip_file, str_path, &file_info))
     return false;
-  }
 
   bool success = true;
   if (!is_directory) {
@@ -202,7 +145,7 @@
 
     if (!AddEntryToZip(zip_file, path, src_dir)) {
       success = false;
-      return false;
+      break;
     }
   }
 
diff --git a/third_party/zlib/google/zip.h b/third_party/zlib/google/zip.h
index 9809fce..0232401 100644
--- a/third_party/zlib/google/zip.h
+++ b/third_party/zlib/google/zip.h
@@ -5,6 +5,8 @@
 #ifndef THIRD_PARTY_ZLIB_GOOGLE_ZIP_H_
 #define THIRD_PARTY_ZLIB_GOOGLE_ZIP_H_
 
+#include <vector>
+
 #include "base/callback.h"
 #include "base/files/file_path.h"
 
diff --git a/third_party/zlib/google/zip.target.darwin-arm.mk b/third_party/zlib/google/zip.target.darwin-arm.mk
index 033bb4a..db3c9c5 100644
--- a/third_party/zlib/google/zip.target.darwin-arm.mk
+++ b/third_party/zlib/google/zip.target.darwin-arm.mk
@@ -42,7 +42,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -131,7 +130,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/zlib/google/zip.target.darwin-x86.mk b/third_party/zlib/google/zip.target.darwin-x86.mk
index e05e7b2..fe6a965 100644
--- a/third_party/zlib/google/zip.target.darwin-x86.mk
+++ b/third_party/zlib/google/zip.target.darwin-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/zlib/google/zip.target.darwin-x86_64.mk b/third_party/zlib/google/zip.target.darwin-x86_64.mk
index c471d4f..8556e6a 100644
--- a/third_party/zlib/google/zip.target.darwin-x86_64.mk
+++ b/third_party/zlib/google/zip.target.darwin-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/zlib/google/zip.target.linux-arm.mk b/third_party/zlib/google/zip.target.linux-arm.mk
index 033bb4a..db3c9c5 100644
--- a/third_party/zlib/google/zip.target.linux-arm.mk
+++ b/third_party/zlib/google/zip.target.linux-arm.mk
@@ -42,7 +42,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -131,7 +130,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/zlib/google/zip.target.linux-x86.mk b/third_party/zlib/google/zip.target.linux-x86.mk
index e05e7b2..fe6a965 100644
--- a/third_party/zlib/google/zip.target.linux-x86.mk
+++ b/third_party/zlib/google/zip.target.linux-x86.mk
@@ -44,7 +44,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/zlib/google/zip.target.linux-x86_64.mk b/third_party/zlib/google/zip.target.linux-x86_64.mk
index c471d4f..8556e6a 100644
--- a/third_party/zlib/google/zip.target.linux-x86_64.mk
+++ b/third_party/zlib/google/zip.target.linux-x86_64.mk
@@ -44,7 +44,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -133,7 +132,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/zlib/google/zip_internal.cc b/third_party/zlib/google/zip_internal.cc
index a01ae8c..6349b7a 100644
--- a/third_party/zlib/google/zip_internal.cc
+++ b/third_party/zlib/google/zip_internal.cc
@@ -2,12 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "third_party/zlib/google/zip.h"
+#include "third_party/zlib/google/zip_internal.h"
 
 #include <algorithm>
 
+#include "base/file_util.h"
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
 
 #if defined(USE_SYSTEM_MINIZIP)
 #include <minizip/ioapi.h>
@@ -230,6 +232,28 @@
   return 0;
 }
 
+// Returns a zip_fileinfo struct with the time represented by |file_time|.
+zip_fileinfo TimeToZipFileInfo(const base::Time& file_time) {
+  base::Time::Exploded file_time_parts;
+  file_time.LocalExplode(&file_time_parts);
+
+  zip_fileinfo zip_info = {};
+  if (file_time_parts.year >= 1980) {
+    // This if check works around the handling of the year value in
+    // contrib/minizip/zip.c in function zip64local_TmzDateToDosDate
+    // It assumes that dates below 1980 are in the double digit format.
+    // Hence the fail safe option is to leave the date unset. Some programs
+    // might show the unset date as 1980-0-0 which is invalid.
+    zip_info.tmz_date.tm_year = file_time_parts.year;
+    zip_info.tmz_date.tm_mon = file_time_parts.month - 1;
+    zip_info.tmz_date.tm_mday = file_time_parts.day_of_month;
+    zip_info.tmz_date.tm_hour = file_time_parts.hour;
+    zip_info.tmz_date.tm_min = file_time_parts.minute;
+    zip_info.tmz_date.tm_sec = file_time_parts.second;
+  }
+
+  return zip_info;
+}
 }  // namespace
 
 namespace zip {
@@ -266,7 +290,7 @@
 #endif
 
 // static
-unzFile PreprareMemoryForUnzipping(const std::string& data) {
+unzFile PrepareMemoryForUnzipping(const std::string& data) {
   if (data.empty())
     return NULL;
 
@@ -312,5 +336,45 @@
 }
 #endif
 
+zip_fileinfo GetFileInfoForZipping(const base::FilePath& path) {
+  base::Time file_time;
+  base::File::Info file_info;
+  if (base::GetFileInfo(path, &file_info))
+    file_time = file_info.last_modified;
+  return TimeToZipFileInfo(file_time);
+}
+
+bool ZipOpenNewFileInZip(zipFile zip_file,
+                         const std::string& str_path,
+                         const zip_fileinfo* file_info) {
+  // Section 4.4.4 http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+  // Setting the Language encoding flag so the file is told to be in utf-8.
+  const uLong LANGUAGE_ENCODING_FLAG = 0x1 << 11;
+
+  if (ZIP_OK != zipOpenNewFileInZip4(
+                    zip_file,  // file
+                    str_path.c_str(),  // filename
+                    file_info,  // zipfi
+                    NULL,  // extrafield_local,
+                    0u,  // size_extrafield_local
+                    NULL,  // extrafield_global
+                    0u,  // size_extrafield_global
+                    NULL,  // comment
+                    Z_DEFLATED,  // method
+                    Z_DEFAULT_COMPRESSION,  // level
+                    0,  // raw
+                    -MAX_WBITS,  // windowBits
+                    DEF_MEM_LEVEL,  // memLevel
+                    Z_DEFAULT_STRATEGY,  // strategy
+                    NULL,  // password
+                    0,  // crcForCrypting
+                    0,  // versionMadeBy
+                    LANGUAGE_ENCODING_FLAG)) {  // flagBase
+    DLOG(ERROR) << "Could not open zip file entry " << str_path;
+    return false;
+  }
+  return true;
+}
+
 }  // namespace internal
 }  // namespace zip
diff --git a/third_party/zlib/google/zip_internal.h b/third_party/zlib/google/zip_internal.h
index 57894be..ffd4039 100644
--- a/third_party/zlib/google/zip_internal.h
+++ b/third_party/zlib/google/zip_internal.h
@@ -19,6 +19,10 @@
 #include "third_party/zlib/contrib/minizip/zip.h"
 #endif
 
+namespace base {
+class FilePath;
+}
+
 // Utility functions and constants used internally for the zip file
 // library in the directory. Don't use them outside of the library.
 namespace zip {
@@ -41,7 +45,7 @@
 // Creates a custom unzFile object which reads data from the specified string.
 // This custom unzFile object overrides the I/O API functions of zlib so it can
 // read data from the specified string.
-unzFile PreprareMemoryForUnzipping(const std::string& data);
+unzFile PrepareMemoryForUnzipping(const std::string& data);
 
 // Opens the given file name in UTF-8 for zipping, with some setup for
 // Windows. |append_flag| will be passed to zipOpen2().
@@ -53,6 +57,14 @@
 zipFile OpenFdForZipping(int zip_fd, int append_flag);
 #endif
 
+// Returns a zip_fileinfo with the last modification date of |path| set.
+zip_fileinfo GetFileInfoForZipping(const base::FilePath& path);
+
+// Wrapper around zipOpenNewFileInZip4 which passes most common options.
+bool ZipOpenNewFileInZip(zipFile zip_file,
+                         const std::string& str_path,
+                         const zip_fileinfo* file_info);
+
 const int kZipMaxPath = 256;
 const int kZipBufSize = 8192;
 
diff --git a/third_party/zlib/google/zip_reader.cc b/third_party/zlib/google/zip_reader.cc
index f34f4f7..aa85fa3 100644
--- a/third_party/zlib/google/zip_reader.cc
+++ b/third_party/zlib/google/zip_reader.cc
@@ -107,7 +107,7 @@
 }
 
 bool ZipReader::OpenFromString(const std::string& data) {
-  zip_file_ = internal::PreprareMemoryForUnzipping(data);
+  zip_file_ = internal::PrepareMemoryForUnzipping(data);
   if (!zip_file_)
     return false;
   return OpenInternal();
diff --git a/third_party/zlib/google/zip_reader.h b/third_party/zlib/google/zip_reader.h
index e16a2fb..60b53ee 100644
--- a/third_party/zlib/google/zip_reader.h
+++ b/third_party/zlib/google/zip_reader.h
@@ -64,6 +64,8 @@
 
     // Returns the size of the original file (i.e. after uncompressed).
     // Returns 0 if the entry is a directory.
+    // Note: this value should not be trusted, because it is stored as metadata
+    // in the zip archive and can be different from the real uncompressed size.
     int64 original_size() const { return original_size_; }
 
     // Returns the last modified time. If the time stored in the zip file was
diff --git a/third_party/zlib/google/zip_unittest.cc b/third_party/zlib/google/zip_unittest.cc
index 22e350f..c606434 100644
--- a/third_party/zlib/google/zip_unittest.cc
+++ b/third_party/zlib/google/zip_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
 #include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 #include "third_party/zlib/google/zip.h"
@@ -302,4 +303,32 @@
 }
 #endif  // defined(OS_POSIX)
 
+TEST_F(ZipTest, UnzipFilesWithIncorrectSize) {
+  base::FilePath test_data_folder;
+  ASSERT_TRUE(GetTestDataDirectory(&test_data_folder));
+
+  // test_mismatch_size.zip contains files with names from 0.txt to 7.txt with
+  // sizes from 0 to 7 bytes respectively, but the metadata in the zip file says
+  // the uncompressed size is 3 bytes. The ZipReader and minizip code needs to
+  // be clever enough to get all the data out.
+  base::FilePath test_zip_file =
+      test_data_folder.AppendASCII("test_mismatch_size.zip");
+
+  base::ScopedTempDir scoped_temp_dir;
+  ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
+  const base::FilePath& temp_dir = scoped_temp_dir.path();
+
+  ASSERT_TRUE(zip::Unzip(test_zip_file, temp_dir));
+  EXPECT_TRUE(base::DirectoryExists(temp_dir.AppendASCII("d")));
+
+  for (int i = 0; i < 8; i++) {
+    SCOPED_TRACE(base::StringPrintf("Processing %d.txt", i));
+    base::FilePath file_path = temp_dir.AppendASCII(
+        base::StringPrintf("%d.txt", i));
+    int64 file_size = -1;
+    EXPECT_TRUE(base::GetFileSize(file_path, &file_size));
+    EXPECT_EQ(static_cast<int64>(i), file_size);
+  }
+}
+
 }  // namespace
diff --git a/third_party/zlib/minizip.target.darwin-arm.mk b/third_party/zlib/minizip.target.darwin-arm.mk
index 20bb9de..89d83af 100644
--- a/third_party/zlib/minizip.target.darwin-arm.mk
+++ b/third_party/zlib/minizip.target.darwin-arm.mk
@@ -41,7 +41,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/zlib/minizip.target.darwin-x86.mk b/third_party/zlib/minizip.target.darwin-x86.mk
index be064af..60703ef 100644
--- a/third_party/zlib/minizip.target.darwin-x86.mk
+++ b/third_party/zlib/minizip.target.darwin-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/zlib/minizip.target.darwin-x86_64.mk b/third_party/zlib/minizip.target.darwin-x86_64.mk
index dad07e7..9575773 100644
--- a/third_party/zlib/minizip.target.darwin-x86_64.mk
+++ b/third_party/zlib/minizip.target.darwin-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/zlib/minizip.target.linux-arm.mk b/third_party/zlib/minizip.target.linux-arm.mk
index 20bb9de..89d83af 100644
--- a/third_party/zlib/minizip.target.linux-arm.mk
+++ b/third_party/zlib/minizip.target.linux-arm.mk
@@ -41,7 +41,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -130,7 +129,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/zlib/minizip.target.linux-x86.mk b/third_party/zlib/minizip.target.linux-x86.mk
index be064af..60703ef 100644
--- a/third_party/zlib/minizip.target.linux-x86.mk
+++ b/third_party/zlib/minizip.target.linux-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/zlib/minizip.target.linux-x86_64.mk b/third_party/zlib/minizip.target.linux-x86_64.mk
index dad07e7..9575773 100644
--- a/third_party/zlib/minizip.target.linux-x86_64.mk
+++ b/third_party/zlib/minizip.target.linux-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -132,7 +131,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/zlib/zlib.target.darwin-arm.mk b/third_party/zlib/zlib.target.darwin-arm.mk
index d713bc3..f1ec74d 100644
--- a/third_party/zlib/zlib.target.darwin-arm.mk
+++ b/third_party/zlib/zlib.target.darwin-arm.mk
@@ -53,7 +53,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -140,7 +139,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/zlib/zlib.target.darwin-x86.mk b/third_party/zlib/zlib.target.darwin-x86.mk
index 8075de2..1f3ebb0 100644
--- a/third_party/zlib/zlib.target.darwin-x86.mk
+++ b/third_party/zlib/zlib.target.darwin-x86.mk
@@ -55,7 +55,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/zlib/zlib.target.darwin-x86_64.mk b/third_party/zlib/zlib.target.darwin-x86_64.mk
index 0108417..cbcd17a 100644
--- a/third_party/zlib/zlib.target.darwin-x86_64.mk
+++ b/third_party/zlib/zlib.target.darwin-x86_64.mk
@@ -55,7 +55,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/zlib/zlib.target.linux-arm.mk b/third_party/zlib/zlib.target.linux-arm.mk
index d713bc3..f1ec74d 100644
--- a/third_party/zlib/zlib.target.linux-arm.mk
+++ b/third_party/zlib/zlib.target.linux-arm.mk
@@ -53,7 +53,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -140,7 +139,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/third_party/zlib/zlib.target.linux-x86.mk b/third_party/zlib/zlib.target.linux-x86.mk
index 8075de2..1f3ebb0 100644
--- a/third_party/zlib/zlib.target.linux-x86.mk
+++ b/third_party/zlib/zlib.target.linux-x86.mk
@@ -55,7 +55,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/third_party/zlib/zlib.target.linux-x86_64.mk b/third_party/zlib/zlib.target.linux-x86_64.mk
index 0108417..cbcd17a 100644
--- a/third_party/zlib/zlib.target.linux-x86_64.mk
+++ b/third_party/zlib/zlib.target.linux-x86_64.mk
@@ -55,7 +55,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -142,7 +141,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/tools/binary_size/java/src/org/chromium/tools/binary_size/Addr2LineWorkerPool.java b/tools/binary_size/java/src/org/chromium/tools/binary_size/Addr2LineWorkerPool.java
index 4f0e517..626e7e4 100644
--- a/tools/binary_size/java/src/org/chromium/tools/binary_size/Addr2LineWorkerPool.java
+++ b/tools/binary_size/java/src/org/chromium/tools/binary_size/Addr2LineWorkerPool.java
@@ -276,6 +276,8 @@
                             inStream = null; // New readers need to be created next iteration
                         }
                     }
+                } catch (RuntimeException e) {
+                    throw e;
                 } catch (Exception e) {
                     e.printStackTrace();
                 } finally {
@@ -464,4 +466,4 @@
     int getDedupeCount() {
         return mDedupeCount.get();
     }
-}
\ No newline at end of file
+}
diff --git a/tools/binary_size/java/src/org/chromium/tools/binary_size/NmDumper.java b/tools/binary_size/java/src/org/chromium/tools/binary_size/NmDumper.java
index 0d77e37..81b05fa 100644
--- a/tools/binary_size/java/src/org/chromium/tools/binary_size/NmDumper.java
+++ b/tools/binary_size/java/src/org/chromium/tools/binary_size/NmDumper.java
@@ -91,7 +91,8 @@
 
         private Output() {
             try {
-                new File(mOutPath).getParentFile().mkdirs();
+                File parentDir = new File(mOutPath).getParentFile();
+                assert (parentDir.mkdirs() || parentDir.isDirectory());
                 outWriter = new PrintWriter(mOutPath);
             } catch (FileNotFoundException e) {
                 throw new RuntimeException("Can't open output file: " + mOutPath, e);
@@ -99,7 +100,8 @@
 
             if (mFailPath != null) {
                 try {
-                    new File(mFailPath).getParentFile().mkdirs();
+                    File parentDir = new File(mFailPath).getParentFile();
+                    assert (parentDir.mkdirs() || parentDir.isDirectory());
                     failWriter = new PrintWriter(mFailPath);
                 } catch (FileNotFoundException e) {
                     throw new RuntimeException("Can't open fail file: " + mFailPath, e);
@@ -110,7 +112,8 @@
 
             if (mSkipPath != null) {
                 try {
-                    new File(mSkipPath).getParentFile().mkdirs();
+                    File parentDir = new File(mSkipPath).getParentFile();
+                    assert (parentDir.mkdirs() || parentDir.isDirectory());
                     skipWriter = new PrintWriter(mSkipPath);
                 } catch (IOException e) {
                     throw new RuntimeException("Can't open skip file: " + mSkipPath, e);
@@ -120,23 +123,25 @@
             }
         }
 
-        private synchronized void println(PrintWriter writer, String string) {
+        private void println(PrintWriter writer, String string) {
             if (writer != null) {
-                writer.println(string);
-                writer.flush();
+                synchronized (writer) {
+                    writer.println(string);
+                    writer.flush();
+                }
             }
         }
 
-        synchronized void print(String string) {
+        void print(String string) {
             println(outWriter, string);
         }
 
-        synchronized void printSkip(String string) {
+        void printSkip(String string) {
             println(skipWriter, string);
             println(outWriter, string);
         }
 
-        synchronized void printFail(String string) {
+        void printFail(String string) {
             println(failWriter, string);
             println(outWriter, string);
         }
@@ -158,4 +163,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tools/bisect-perf-regression.py b/tools/bisect-perf-regression.py
index f05b6e6..6021824 100755
--- a/tools/bisect-perf-regression.py
+++ b/tools/bisect-perf-regression.py
@@ -696,7 +696,7 @@
 
 def WriteStringToFile(text, file_name):
   try:
-    with open(file_name, "w") as f:
+    with open(file_name, "wb") as f:
       f.write(text)
   except IOError as e:
     raise RuntimeError('Error writing to file [%s]' % file_name )
diff --git a/tools/checkdeps/java_checker.py b/tools/checkdeps/java_checker.py
index 61e51df..36e4623 100644
--- a/tools/checkdeps/java_checker.py
+++ b/tools/checkdeps/java_checker.py
@@ -56,7 +56,7 @@
         if d == 'out':
           dirs.remove(d)
         # Skip third-party directories.
-        if d == 'third_party':
+        if d in ('third_party', 'ThirdParty'):
           dirs.remove(d)
       for f in files:
         if f.endswith('.java'):
diff --git a/tools/chromeproxy_testserver/OWNERS b/tools/chromeproxy_testserver/OWNERS
new file mode 100644
index 0000000..6a63b53
--- /dev/null
+++ b/tools/chromeproxy_testserver/OWNERS
@@ -0,0 +1,3 @@
+bengr@chromium.org
+bolian@chromium.org
+marq@chromium.org
diff --git a/tools/chromeproxy_testserver/app.yaml b/tools/chromeproxy_testserver/app.yaml
new file mode 100644
index 0000000..6a89db7
--- /dev/null
+++ b/tools/chromeproxy_testserver/app.yaml
@@ -0,0 +1,10 @@
+application: chromeproxy-test
+version: 1
+runtime: go
+api_version: go1
+
+handlers:
+- url: /image
+  static_dir: image
+- url: /.*
+  script: _go_app
diff --git a/tools/chromeproxy_testserver/data/image1.png b/tools/chromeproxy_testserver/data/image1.png
new file mode 100644
index 0000000..c657f94
--- /dev/null
+++ b/tools/chromeproxy_testserver/data/image1.png
Binary files differ
diff --git a/tools/chromeproxy_testserver/image/image1.png b/tools/chromeproxy_testserver/image/image1.png
new file mode 100644
index 0000000..c657f94
--- /dev/null
+++ b/tools/chromeproxy_testserver/image/image1.png
Binary files differ
diff --git a/tools/chromeproxy_testserver/server.go b/tools/chromeproxy_testserver/server.go
new file mode 100644
index 0000000..c40bc5e
--- /dev/null
+++ b/tools/chromeproxy_testserver/server.go
@@ -0,0 +1,159 @@
+// Test server to facilitate the data reduction proxy Telemetry tests.
+//
+// The server runs at http://chromeproxy-test.appspot.com/. Please contact
+// people in OWNERS for server issues.
+//
+// For running an AppEngine Go server, see:
+// https://developers.google.com/appengine/docs/go/gettingstarted/introduction.
+//
+// The goal is to keep the test logic on the client side (Telemetry)
+// as much as possible. This server will only return a resource
+// and/or override the response as specified by the data encoded
+// in the request URL queries.
+//
+// For example, on receiving the query
+// /default?respBody=bmV3IGJvZHk=&respHeader=eyJWaWEiOlsiVmlhMSIsIlZpYTIiXX0%3D&respStatus=204
+// the server sends back a response with
+//	Status code: 204
+//	Additional response headers: "Via: Via1" and "Via: Via2"
+//	Response body: "new body"
+// where the overriding headers and body are base64 encoded in the request query.
+
+package server
+
+import (
+	"bytes"
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"net/http"
+	"os"
+	"strconv"
+)
+
+func init() {
+	http.HandleFunc("/requestHeader", requestHeader)
+	http.HandleFunc("/resource", resource)
+	http.HandleFunc("/default", defaultResponse)
+}
+
+// requestHander returns request headers in response body as text.
+func requestHeader(w http.ResponseWriter, r *http.Request) {
+	r.Header.Write(w)
+}
+
+// resource returns the content of a data file specified by "r=" query as the response body.
+// The response could be overridden by request queries.
+// See parseOverrideQuery.
+func resource(w http.ResponseWriter, r *http.Request) {
+	wroteBody, err := applyOverride(w, r)
+	if err != nil || wroteBody {
+		return
+	}
+	path, ok := r.URL.Query()["r"]
+	if !ok || len(path) != 1 {
+		w.WriteHeader(http.StatusBadRequest)
+		w.Write([]byte("no resource in query"))
+		return
+	}
+	if _, err := writeFromFile(w, path[0]); err != nil {
+		w.WriteHeader(http.StatusBadRequest)
+		w.Write([]byte(fmt.Sprintf("Failed to get %s: %v", path[0], err)))
+		return
+	}
+}
+
+// defaultResponse returns "ok" as response body, if the body is not overridden.
+// The response could be overridden by request queries.
+// See parseOverrideQuery.
+func defaultResponse(w http.ResponseWriter, r *http.Request) {
+	wroteBody, err := applyOverride(w, r)
+	if err != nil {
+		return
+	}
+	if !wroteBody {
+		w.Write([]byte("ok"))
+	}
+}
+
+type override struct {
+	status int
+	header http.Header
+	body   io.Reader
+}
+
+// parseOverrideQuery parses the queries in r and returns an override.
+// It supports the following queries:
+//   "respStatus": an integer to override response status code;
+//   "respHeader": base64 encoded JSON data to override the response headers;
+//   "respBody": base64 encoded JSON data to override the response body.
+func parseOverrideQuery(r *http.Request) (*override, error) {
+	q := r.URL.Query()
+	resp := &override{0, nil, nil}
+	if v, ok := q["respStatus"]; ok && len(v) == 1 && len(v[0]) > 0 {
+		status, err := strconv.ParseInt(v[0], 10, 0)
+		if err != nil {
+			return nil, errors.New(fmt.Sprintf("respStatus: %v", err))
+		}
+		resp.status = int(status)
+	}
+	if v, ok := q["respHeader"]; ok && len(v) == 1 && len(v[0]) > 0 {
+		// Example header after base64 decoding:
+		//  {"Via": ["Telemetry Test", "Test2"], "Name": ["XYZ"], "Cache-Control": ["public"]}
+		headerValue, err := base64.URLEncoding.DecodeString(v[0])
+		if err != nil {
+			return nil, errors.New(fmt.Sprintf("Decoding respHeader: %v", err))
+		}
+		var header http.Header
+		err = json.Unmarshal(headerValue, &header)
+		if err != nil {
+			return nil, errors.New(
+				fmt.Sprintf("Unmarlshal (%s) error: %v", string(headerValue), err))
+		}
+		resp.header = header
+	}
+	if v, ok := q["respBody"]; ok && len(v) == 1 && len(v[0]) > 0 {
+		body, err := base64.URLEncoding.DecodeString(v[0])
+		if err != nil {
+			return nil, errors.New(
+				fmt.Sprintf("Decoding respBody error: %v", err))
+		}
+		resp.body = bytes.NewBuffer(body)
+	}
+	return resp, nil
+}
+
+// applyOverride applies the override queries in r to w and returns whether the response
+// body is overridden.
+func applyOverride(w http.ResponseWriter, r *http.Request) (wroteBody bool, err error) {
+	resp, err := parseOverrideQuery(r)
+	if err != nil {
+		w.WriteHeader(http.StatusBadRequest)
+		w.Write([]byte(err.Error()))
+		return false, err
+	}
+	headers := w.Header()
+	if resp.header != nil {
+		for k, v := range resp.header {
+			headers[k] = v
+		}
+	}
+	if resp.status > 0 {
+		w.WriteHeader(resp.status)
+	}
+	if resp.body != nil {
+		_, err := io.Copy(w, resp.body)
+		return true, err
+	}
+	return false, nil
+}
+
+func writeFromFile(w io.Writer, filename string) (int64, error) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return 0, err
+	}
+	return io.Copy(w, f)
+}
diff --git a/tools/chromeproxy_testserver/server_test.go b/tools/chromeproxy_testserver/server_test.go
new file mode 100644
index 0000000..d215131
--- /dev/null
+++ b/tools/chromeproxy_testserver/server_test.go
@@ -0,0 +1,99 @@
+package server
+
+import (
+	"encoding/base64"
+	"encoding/json"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
+	"reflect"
+	"strconv"
+	"testing"
+)
+
+func composeQuery(path string, code int, headers http.Header, body []byte) (string, error) {
+	u, err := url.Parse(path)
+	if err != nil {
+		return "", err
+	}
+	q := u.Query()
+	if code > 0 {
+		q.Set("respStatus", strconv.Itoa(code))
+	}
+	if headers != nil {
+		h, err := json.Marshal(headers)
+		if err != nil {
+			return "", err
+		}
+		q.Set("respHeader", base64.URLEncoding.EncodeToString(h))
+	}
+	if len(body) > 0 {
+		q.Set("respBody", base64.URLEncoding.EncodeToString(body))
+	}
+	u.RawQuery = q.Encode()
+	return u.String(), nil
+}
+
+func TestResponseOverride(t *testing.T) {
+	tests := []struct {
+		name    string
+		code    int
+		headers http.Header
+		body    []byte
+	}{
+		{name: "code", code: 204},
+		{name: "body", body: []byte("new body")},
+		{
+			name: "headers",
+			headers: http.Header{
+				"Via":          []string{"Via1", "Via2"},
+				"Content-Type": []string{"random content"},
+			},
+		},
+		{
+			name: "everything",
+			code: 204,
+			body: []byte("new body"),
+			headers: http.Header{
+				"Via":          []string{"Via1", "Via2"},
+				"Content-Type": []string{"random content"},
+			},
+		},
+	}
+
+	for _, test := range tests {
+		u, err := composeQuery("http://test.com/override", test.code, test.headers, test.body)
+		if err != nil {
+			t.Errorf("%s: composeQuery: %v", test.name, err)
+			return
+		}
+		req, err := http.NewRequest("GET", u, nil)
+		if err != nil {
+			t.Errorf("%s: http.NewRequest: %v", test.name, err)
+			return
+		}
+		w := httptest.NewRecorder()
+		defaultResponse(w, req)
+		if test.code > 0 {
+			if got, want := w.Code, test.code; got != want {
+				t.Errorf("%s: response code: got %d want %d", test.name, got, want)
+				return
+			}
+		}
+		if test.headers != nil {
+			for k, want := range test.headers {
+				got, ok := w.HeaderMap[k]
+				if !ok || !reflect.DeepEqual(got, want) {
+					t.Errorf("%s: header %s: code: got %v want %v", test.name, k, got, want)
+					return
+				}
+			}
+		}
+		if test.body != nil {
+			if got, want := string(w.Body.Bytes()), string(test.body); got != want {
+				t.Errorf("%s: body: got %s want %s", test.name, got, want)
+				return
+			}
+		}
+	}
+}
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
index 47ab43c..eec7d84 100644
--- a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
+++ b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
@@ -116,6 +116,10 @@
     "[blink-gc] Stack-allocated class %0 derives class %1"
     " which is not stack allocated.";
 
+const char kClassOverridesNew[] =
+    "[blink-gc] Garbage collected class %0"
+    " is not permitted to override its new operator.";
+
 struct BlinkGCPluginOptions {
   BlinkGCPluginOptions() : enable_oilpan(false), dump_graph(false) {}
   bool enable_oilpan;
@@ -564,6 +568,8 @@
         diagnostic_.getCustomDiagID(getErrorLevel(), kMissingFinalizeDispatch);
     diag_derives_non_stack_allocated_ =
         diagnostic_.getCustomDiagID(getErrorLevel(), kDerivesNonStackAllocated);
+    diag_class_overrides_new_ =
+        diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew);
 
     // Register note messages.
     diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID(
@@ -700,6 +706,9 @@
 
       CheckDispatch(info);
 
+      if (CXXMethodDecl* newop = info->DeclaresNewOperator())
+        ReportClassOverridesNew(info, newop);
+
       // TODO: Remove this exception once TreeShared is properly traced.
       if (!info->IsTreeShared()) {
         CheckGCRootsVisitor visitor;
@@ -1236,6 +1245,13 @@
         << info->record() << base->info()->record();
   }
 
+  void ReportClassOverridesNew(RecordInfo* info, CXXMethodDecl* newop) {
+    SourceLocation loc = newop->getLocStart();
+    SourceManager& manager = instance_.getSourceManager();
+    FullSourceLoc full_loc(loc, manager);
+    diagnostic_.Report(full_loc, diag_class_overrides_new_) << info->record();
+  }
+
   void NoteManualDispatchMethod(CXXMethodDecl* dispatch) {
     SourceLocation loc = dispatch->getLocStart();
     SourceManager& manager = instance_.getSourceManager();
@@ -1316,6 +1332,7 @@
   unsigned diag_missing_trace_dispatch_;
   unsigned diag_missing_finalize_dispatch_;
   unsigned diag_derives_non_stack_allocated_;
+  unsigned diag_class_overrides_new_;
 
   unsigned diag_field_requires_tracing_note_;
   unsigned diag_raw_ptr_to_gc_managed_class_note_;
diff --git a/tools/clang/blink_gc_plugin/Config.h b/tools/clang/blink_gc_plugin/Config.h
index ba440be..917d070 100644
--- a/tools/clang/blink_gc_plugin/Config.h
+++ b/tools/clang/blink_gc_plugin/Config.h
@@ -56,26 +56,35 @@
 
   static bool IsWTFCollection(const std::string& name) {
     return name == "Vector" ||
+           name == "Deque" ||
            name == "HashSet" ||
-           name == "HashMap" ||
-           name == "HashCountedSet" ||
            name == "ListHashSet" ||
-           name == "Deque";
-  }
-
-  static bool IsPersistentGCCollection(const std::string& name) {
-    return name == "PersistentHeapVector" ||
-           name == "PersistentHeapHashMap" ||
-           name == "PersistentHeapHashSet";
+           name == "LinkedHashSet" ||
+           name == "HashCountedSet" ||
+           name == "HashMap";
   }
 
   static bool IsGCCollection(const std::string& name) {
     return name == "HeapVector" ||
-           name == "HeapHashMap" ||
+           name == "HeapDeque" ||
            name == "HeapHashSet" ||
+           name == "HeapListHashSet" ||
+           name == "HeapLinkedHashSet" ||
+           name == "HeapHashCountedSet" ||
+           name == "HeapHashMap" ||
            IsPersistentGCCollection(name);
   }
 
+  static bool IsPersistentGCCollection(const std::string& name) {
+    return name == "PersistentHeapVector" ||
+           name == "PersistentHeapDeque" ||
+           name == "PersistentHeapHashSet" ||
+           name == "PersistentHeapListHashSet" ||
+           name == "PersistentHeapLinkedHashSet" ||
+           name == "PersistentHeapHashCountedSet" ||
+           name == "PersistentHeapHashMap";
+  }
+
   static bool IsHashMap(const std::string& name) {
     return name == "HashMap" ||
            name == "HeapHashMap" ||
diff --git a/tools/clang/blink_gc_plugin/RecordInfo.cpp b/tools/clang/blink_gc_plugin/RecordInfo.cpp
index bbe4e58..7378077 100644
--- a/tools/clang/blink_gc_plugin/RecordInfo.cpp
+++ b/tools/clang/blink_gc_plugin/RecordInfo.cpp
@@ -230,6 +230,16 @@
   return is_only_placement_newable_;
 }
 
+CXXMethodDecl* RecordInfo::DeclaresNewOperator() {
+  for (CXXRecordDecl::method_iterator it = record_->method_begin();
+       it != record_->method_end();
+       ++it) {
+    if (it->getNameAsString() == kNewOperatorName && it->getNumParams() == 1)
+      return *it;
+  }
+  return 0;
+}
+
 // An object requires a tracing method if it has any fields that need tracing.
 bool RecordInfo::RequiresTraceMethod() {
   if (IsStackAllocated())
@@ -504,11 +514,9 @@
     for (TemplateArgs::iterator it = args.begin(); it != args.end(); ++it) {
       if (Edge* member = CreateEdge(*it)) {
         edge->members().push_back(member);
-      } else {
-        // We failed to create an edge so abort the entire edge construction.
-        delete edge;  // Will delete the already allocated members.
-        return 0;
       }
+      // TODO: Handle the case where we fail to create an edge (eg, if the
+      // argument is a primitive type or just not fully known yet).
     }
     return edge;
   }
diff --git a/tools/clang/blink_gc_plugin/RecordInfo.h b/tools/clang/blink_gc_plugin/RecordInfo.h
index fdbb3b9..3e87114 100644
--- a/tools/clang/blink_gc_plugin/RecordInfo.h
+++ b/tools/clang/blink_gc_plugin/RecordInfo.h
@@ -95,6 +95,7 @@
   bool IsNonNewable();
   bool IsOnlyPlacementNewable();
   bool IsTreeShared();
+  clang::CXXMethodDecl* DeclaresNewOperator();
 
   bool RequiresTraceMethod();
   bool NeedsFinalization();
diff --git a/tools/clang/blink_gc_plugin/tests/class_overrides_new.cpp b/tools/clang/blink_gc_plugin/tests/class_overrides_new.cpp
new file mode 100644
index 0000000..9f47f82
--- /dev/null
+++ b/tools/clang/blink_gc_plugin/tests/class_overrides_new.cpp
@@ -0,0 +1,7 @@
+// 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.
+
+#include "class_overrides_new.h"
+
+// Nothing to define.
diff --git a/tools/clang/blink_gc_plugin/tests/class_overrides_new.h b/tools/clang/blink_gc_plugin/tests/class_overrides_new.h
new file mode 100644
index 0000000..c76daef
--- /dev/null
+++ b/tools/clang/blink_gc_plugin/tests/class_overrides_new.h
@@ -0,0 +1,20 @@
+// 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.
+
+#ifndef CLASS_OVERRIDES_NEW_H_
+#define CLASS_OVERRIDES_NEW_H_
+
+#include "heap/stubs.h"
+
+namespace WebCore {
+
+class HeapObject : public GarbageCollected<HeapObject> {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    void trace(Visitor*) { }
+};
+
+}
+
+#endif
diff --git a/tools/clang/blink_gc_plugin/tests/class_overrides_new.txt b/tools/clang/blink_gc_plugin/tests/class_overrides_new.txt
new file mode 100644
index 0000000..17f50fe
--- /dev/null
+++ b/tools/clang/blink_gc_plugin/tests/class_overrides_new.txt
@@ -0,0 +1,8 @@
+In file included from class_overrides_new.cpp:5:
+./class_overrides_new.h:13:5: warning: [blink-gc] Garbage collected class 'HeapObject' is not permitted to override its new operator.
+    WTF_MAKE_FAST_ALLOCATED;
+    ^
+./heap/stubs.h:14:5: note: expanded from macro 'WTF_MAKE_FAST_ALLOCATED'
+    void* operator new(size_t size);            \
+    ^
+1 warning generated.
diff --git a/tools/clang/blink_gc_plugin/tests/heap/stubs.h b/tools/clang/blink_gc_plugin/tests/heap/stubs.h
index 41bf6ba..a9e64f5 100644
--- a/tools/clang/blink_gc_plugin/tests/heap/stubs.h
+++ b/tools/clang/blink_gc_plugin/tests/heap/stubs.h
@@ -7,6 +7,14 @@
 
 #include "stddef.h"
 
+#define WTF_MAKE_FAST_ALLOCATED                 \
+    public:                                     \
+    void* operator new(size_t, void* p);        \
+    void* operator new[](size_t, void* p);      \
+    void* operator new(size_t size);            \
+    private:                                    \
+    typedef int __thisIsHereToForceASemicolonAfterThisMacro
+
 namespace WTF {
 
 template<typename T> class RefCounted { };
@@ -53,9 +61,10 @@
 template<>
 class VectorDestructorBase<0, true, true> {};
 
-template<typename T,
-         size_t inlineCapacity = 0,
-         typename Allocator = DefaultAllocator>
+template<
+    typename T,
+    size_t inlineCapacity = 0,
+    typename Allocator = DefaultAllocator>
 class Vector : public VectorDestructorBase<inlineCapacity,
                                            Allocator::isGarbageCollected,
                                            VectorTraits<T>::needsDestruction> {
@@ -64,6 +73,49 @@
     T& operator[](size_t);
 };
 
+template<
+    typename T,
+    size_t inlineCapacity = 0,
+    typename Allocator = DefaultAllocator>
+class Deque {};
+
+template<
+    typename ValueArg,
+    typename HashArg = void,
+    typename TraitsArg = void,
+    typename Allocator = DefaultAllocator>
+class HashSet {};
+
+template<
+    typename ValueArg,
+    typename HashArg = void,
+    typename TraitsArg = void,
+    typename Allocator = DefaultAllocator>
+class ListHashSet {};
+
+template<
+    typename ValueArg,
+    typename HashArg = void,
+    typename TraitsArg = void,
+    typename Allocator = DefaultAllocator>
+class LinkedHashSet {};
+
+template<
+    typename ValueArg,
+    typename HashArg = void,
+    typename TraitsArg = void,
+    typename Allocator = DefaultAllocator>
+class HashCountedSet {};
+
+template<
+    typename KeyArg,
+    typename MappedArg,
+    typename HashArg = void,
+    typename KeyTraitsArg = void,
+    typename MappedTraitsArg = void,
+    typename Allocator = DefaultAllocator>
+class HashMap {};
+
 }
 
 namespace WebCore {
@@ -107,6 +159,13 @@
     bool operator!() const { return false; }
 };
 
+template<typename T> class WeakMember {
+public:
+    operator T*() const { return 0; }
+    T* operator->() { return 0; }
+    bool operator!() const { return false; }
+};
+
 template<typename T> class Persistent {
 public:
     operator T*() const { return 0; }
@@ -122,12 +181,36 @@
 template<typename T, size_t inlineCapacity = 0>
 class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> { };
 
+template<typename T, size_t inlineCapacity = 0>
+class HeapDeque : public Vector<T, inlineCapacity, HeapAllocator> { };
+
+template<typename T>
+class HeapHashSet : public HashSet<T, void, void, HeapAllocator> { };
+
+template<typename T>
+class HeapListHashSet : public ListHashSet<T, void, void, HeapAllocator> { };
+
+template<typename T>
+class HeapLinkedHashSet : public LinkedHashSet<T, void, void, HeapAllocator> {
+};
+
+template<typename T>
+class HeapHashCountedSet : public HashCountedSet<T, void, void, HeapAllocator> {
+};
+
+template<typename K, typename V>
+class HeapHashMap : public HashMap<K, V, void, void, void, HeapAllocator> { };
+
 template<typename T>
 class PersistentHeapVector : public Vector<T, 0, HeapAllocator> { };
 
 class Visitor {
 public:
-    template<typename T> void trace(const T&);
+    template<typename T>
+    void trace(const T&);
+
+    template<typename T, void (T::*method)(Visitor*)>
+    void registerWeakMembers(const T* obj);
 };
 
 class GarbageCollectedMixin {
diff --git a/tools/clang/blink_gc_plugin/tests/trace_collections.cpp b/tools/clang/blink_gc_plugin/tests/trace_collections.cpp
new file mode 100644
index 0000000..2dd028e
--- /dev/null
+++ b/tools/clang/blink_gc_plugin/tests/trace_collections.cpp
@@ -0,0 +1,13 @@
+// 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.
+
+#include "trace_collections.h"
+
+namespace WebCore {
+
+void HeapObject::trace(Visitor* visitor)
+{
+}
+
+}
diff --git a/tools/clang/blink_gc_plugin/tests/trace_collections.h b/tools/clang/blink_gc_plugin/tests/trace_collections.h
new file mode 100644
index 0000000..0694bec
--- /dev/null
+++ b/tools/clang/blink_gc_plugin/tests/trace_collections.h
@@ -0,0 +1,44 @@
+// 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.
+
+#ifndef TRACE_COLLECTIONS_H_
+#define TRACE_COLLECTIONS_H_
+
+#include "heap/stubs.h"
+
+namespace WebCore {
+
+class HeapObject : public GarbageCollected<HeapObject> {
+public:
+    void trace(Visitor*);
+private:
+    HeapVector<Member<HeapObject> > m_heapVector;
+    Vector<Member<HeapObject>, 0, HeapAllocator> m_wtfVector;
+
+    HeapDeque<Member<HeapObject> > m_heapDeque;
+    Deque<Member<HeapObject>, 0, HeapAllocator> m_wtfDeque;
+
+    HeapHashSet<Member<HeapObject> > m_heapSet;
+    HashSet<Member<HeapObject>, void, HeapAllocator> m_wtfSet;
+
+    HeapListHashSet<Member<HeapObject> > m_heapListSet;
+    ListHashSet<Member<HeapObject>, void, HeapAllocator> m_wtfListSet;
+
+    HeapLinkedHashSet<Member<HeapObject> > m_heapLinkedSet;
+    LinkedHashSet<Member<HeapObject>, void, HeapAllocator> m_wtfLinkedSet;
+
+    HeapHashCountedSet<Member<HeapObject> > m_heapCountedSet;
+    HashCountedSet<Member<HeapObject>, void, HeapAllocator> m_wtfCountedSet;
+
+    HeapHashMap<int, Member<HeapObject> > m_heapMapKey;
+    HeapHashMap<Member<HeapObject>, int > m_heapMapVal;
+    HashMap<int, Member<HeapObject>, void, void, void, HeapAllocator>
+    m_wtfMapKey;
+    HashMap<Member<HeapObject>, int, void, void, void, HeapAllocator>
+    m_wtfMapVal;
+};
+
+}
+
+#endif
diff --git a/tools/clang/blink_gc_plugin/tests/trace_collections.txt b/tools/clang/blink_gc_plugin/tests/trace_collections.txt
new file mode 100644
index 0000000..7c20ad4
--- /dev/null
+++ b/tools/clang/blink_gc_plugin/tests/trace_collections.txt
@@ -0,0 +1,52 @@
+trace_collections.cpp:9:1: warning: [blink-gc] Class 'HeapObject' has untraced fields that require tracing.
+void HeapObject::trace(Visitor* visitor)
+^
+./trace_collections.h:16:5: note: [blink-gc] Untraced field 'm_heapVector' declared here:
+    HeapVector<Member<HeapObject> > m_heapVector;
+    ^
+./trace_collections.h:17:5: note: [blink-gc] Untraced field 'm_wtfVector' declared here:
+    Vector<Member<HeapObject>, 0, HeapAllocator> m_wtfVector;
+    ^
+./trace_collections.h:19:5: note: [blink-gc] Untraced field 'm_heapDeque' declared here:
+    HeapDeque<Member<HeapObject> > m_heapDeque;
+    ^
+./trace_collections.h:20:5: note: [blink-gc] Untraced field 'm_wtfDeque' declared here:
+    Deque<Member<HeapObject>, 0, HeapAllocator> m_wtfDeque;
+    ^
+./trace_collections.h:22:5: note: [blink-gc] Untraced field 'm_heapSet' declared here:
+    HeapHashSet<Member<HeapObject> > m_heapSet;
+    ^
+./trace_collections.h:23:5: note: [blink-gc] Untraced field 'm_wtfSet' declared here:
+    HashSet<Member<HeapObject>, void, HeapAllocator> m_wtfSet;
+    ^
+./trace_collections.h:25:5: note: [blink-gc] Untraced field 'm_heapListSet' declared here:
+    HeapListHashSet<Member<HeapObject> > m_heapListSet;
+    ^
+./trace_collections.h:26:5: note: [blink-gc] Untraced field 'm_wtfListSet' declared here:
+    ListHashSet<Member<HeapObject>, void, HeapAllocator> m_wtfListSet;
+    ^
+./trace_collections.h:28:5: note: [blink-gc] Untraced field 'm_heapLinkedSet' declared here:
+    HeapLinkedHashSet<Member<HeapObject> > m_heapLinkedSet;
+    ^
+./trace_collections.h:29:5: note: [blink-gc] Untraced field 'm_wtfLinkedSet' declared here:
+    LinkedHashSet<Member<HeapObject>, void, HeapAllocator> m_wtfLinkedSet;
+    ^
+./trace_collections.h:31:5: note: [blink-gc] Untraced field 'm_heapCountedSet' declared here:
+    HeapHashCountedSet<Member<HeapObject> > m_heapCountedSet;
+    ^
+./trace_collections.h:32:5: note: [blink-gc] Untraced field 'm_wtfCountedSet' declared here:
+    HashCountedSet<Member<HeapObject>, void, HeapAllocator> m_wtfCountedSet;
+    ^
+./trace_collections.h:34:5: note: [blink-gc] Untraced field 'm_heapMapKey' declared here:
+    HeapHashMap<int, Member<HeapObject> > m_heapMapKey;
+    ^
+./trace_collections.h:35:5: note: [blink-gc] Untraced field 'm_heapMapVal' declared here:
+    HeapHashMap<Member<HeapObject>, int > m_heapMapVal;
+    ^
+./trace_collections.h:36:5: note: [blink-gc] Untraced field 'm_wtfMapKey' declared here:
+    HashMap<int, Member<HeapObject>, void, void, void, HeapAllocator>
+    ^
+./trace_collections.h:38:5: note: [blink-gc] Untraced field 'm_wtfMapVal' declared here:
+    HashMap<Member<HeapObject>, int, void, void, void, HeapAllocator>
+    ^
+1 warning generated.
diff --git a/tools/clang/blink_gc_plugin/tests/weak_fields_require_tracing.cpp b/tools/clang/blink_gc_plugin/tests/weak_fields_require_tracing.cpp
new file mode 100644
index 0000000..478cc65
--- /dev/null
+++ b/tools/clang/blink_gc_plugin/tests/weak_fields_require_tracing.cpp
@@ -0,0 +1,28 @@
+// 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.
+
+#include "weak_fields_require_tracing.h"
+
+namespace WebCore {
+
+void HeapObject::trace(Visitor* visitor)
+{
+    // Missing visitor->trace(m_obj1);
+    // Missing visitor->trace(m_obj2);
+    // visitor->trace(m_obj3) in callback.
+    // Missing visitor->trace(m_set1);
+    visitor->trace(m_set2);
+    visitor->registerWeakMembers<HeapObject,
+                                 &HeapObject::clearWeakMembers>(this);
+}
+
+void HeapObject::clearWeakMembers(Visitor* visitor)
+{
+    visitor->trace(m_obj1);  // Does not count.
+    // Missing visitor->trace(m_obj2);
+    visitor->trace(m_obj3);  // OK.
+    visitor->trace(m_set1);  // Does not count.
+}
+
+}
diff --git a/tools/clang/blink_gc_plugin/tests/weak_fields_require_tracing.h b/tools/clang/blink_gc_plugin/tests/weak_fields_require_tracing.h
new file mode 100644
index 0000000..67264d5
--- /dev/null
+++ b/tools/clang/blink_gc_plugin/tests/weak_fields_require_tracing.h
@@ -0,0 +1,26 @@
+// 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.
+
+#ifndef WEAK_FIELDS_REQUIRE_TRACING_H_
+#define WEAK_FIELDS_REQUIRE_TRACING_H_
+
+#include "heap/stubs.h"
+
+namespace WebCore {
+
+class HeapObject : public GarbageCollected<HeapObject> {
+public:
+    void trace(Visitor*);
+    void clearWeakMembers(Visitor*);
+private:
+    Member<HeapObject> m_obj1;
+    WeakMember<HeapObject> m_obj2;
+    WeakMember<HeapObject> m_obj3;
+    HeapHashSet<WeakMember<HeapObject> > m_set1;
+    HeapHashSet<WeakMember<HeapObject> > m_set2;
+};
+
+}
+
+#endif
diff --git a/tools/clang/blink_gc_plugin/tests/weak_fields_require_tracing.txt b/tools/clang/blink_gc_plugin/tests/weak_fields_require_tracing.txt
new file mode 100644
index 0000000..02f56a3
--- /dev/null
+++ b/tools/clang/blink_gc_plugin/tests/weak_fields_require_tracing.txt
@@ -0,0 +1,13 @@
+weak_fields_require_tracing.cpp:9:1: warning: [blink-gc] Class 'HeapObject' has untraced fields that require tracing.
+void HeapObject::trace(Visitor* visitor)
+^
+./weak_fields_require_tracing.h:17:5: note: [blink-gc] Untraced field 'm_obj1' declared here:
+    Member<HeapObject> m_obj1;
+    ^
+./weak_fields_require_tracing.h:18:5: note: [blink-gc] Untraced field 'm_obj2' declared here:
+    WeakMember<HeapObject> m_obj2;
+    ^
+./weak_fields_require_tracing.h:20:5: note: [blink-gc] Untraced field 'm_set1' declared here:
+    HeapHashSet<WeakMember<HeapObject> > m_set1;
+    ^
+1 warning generated.
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 45a3408..a57bd0d 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -139,10 +139,13 @@
              ['&&', 'cmake', '-GNinja', '-DCMAKE_BUILD_TYPE=Release',
               '-DLLVM_ENABLE_ASSERTIONS=ON', LLVM_DIR])
   RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'ninja', 'compiler-rt'])
+
+  # TODO(hans): Make this (and the .gypi file) version number independent.
   asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang',
-                                     '3.5', 'lib', 'windows')
+                                     '3.5.0', 'lib', 'windows')
   asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
-                                     '3.5', 'lib', 'windows')
+                                     '3.5.0', 'lib', 'windows')
+
   if not os.path.exists(asan_rt_lib_dst_dir):
     os.makedirs(asan_rt_lib_dst_dir)
   for root, _, files in os.walk(asan_rt_lib_src_dir):
diff --git a/tools/cr/cr/__init__.py b/tools/cr/cr/__init__.py
index 928e08b..3c51575 100644
--- a/tools/cr/cr/__init__.py
+++ b/tools/cr/cr/__init__.py
@@ -8,8 +8,14 @@
 Commonly accessed elements, including all plugins, are promoted into this
 module.
 """
-import sys
 
-from cr.config import Config
-from cr.loader import AutoExport
-import cr.plugin
+import cr.loader
+from cr.loader import Import
+
+Import(__name__, 'auto.user')
+Import(__name__, 'autocomplete')
+Import(__name__, 'config')
+Import(__name__, 'plugin')
+Import(__name__, 'base')
+Import(__name__, 'commands')
+Import(__name__, 'actions')
diff --git a/tools/cr/cr/actions/__init__.py b/tools/cr/cr/actions/__init__.py
index 5f818b3..63ca9b0 100644
--- a/tools/cr/cr/actions/__init__.py
+++ b/tools/cr/cr/actions/__init__.py
@@ -8,3 +8,10 @@
 These actions are the things that actually perform the work, they are generally
 run in sequences by commands.
 """
+
+import cr
+
+cr.Import(__name__, 'action')
+cr.Import(__name__, 'runner')
+cr.Import(__name__, 'builder')
+cr.Import(__name__, 'installer')
diff --git a/tools/cr/cr/base/__init__.py b/tools/cr/cr/base/__init__.py
index 05babb8..81cdefe 100644
--- a/tools/cr/cr/base/__init__.py
+++ b/tools/cr/cr/base/__init__.py
@@ -3,3 +3,9 @@
 # found in the LICENSE file.
 
 """A package for the base supporting classes of the cr tool."""
+
+import cr
+
+cr.Import(__name__, 'platform')
+cr.Import(__name__, 'buildtype')
+cr.Import(__name__, 'client')
diff --git a/tools/cr/cr/base/client.py b/tools/cr/cr/base/client.py
index 9ab52f9..dee8630 100644
--- a/tools/cr/cr/base/client.py
+++ b/tools/cr/cr/base/client.py
@@ -204,3 +204,24 @@
       print ' ', name, '=', cr.context.Get(name)
   except AttributeError:
     pass
+
+
+class InitHook(cr.Plugin, cr.Plugin.Type):
+  """Base class for output directory initialization hooks.
+
+  Implementations used to fix from old version to new ones live in the
+  cr.fixups package.
+  """
+
+  def Run(self, old_version, config):
+    """Run the initialization hook.
+
+    This is invoked once per init invocation.
+    Args:
+      old_version: The old version,
+          0.0 if the old version was bad or missing,
+          None if building a new output direcory.
+      config: The mutable config that will be written.
+    """
+    raise NotImplementedError('Must be overridden.')
+
diff --git a/tools/cr/cr/base/host.py b/tools/cr/cr/base/host.py
index f60b55b..5ff7ed8 100644
--- a/tools/cr/cr/base/host.py
+++ b/tools/cr/cr/base/host.py
@@ -14,6 +14,13 @@
 # Controls what verbosity level turns on command trail logging
 _TRAIL_VERBOSITY = 2
 
+def PrintTrail(trail):
+  print 'Command expanded the following variables:'
+  for key, value in trail:
+    if value == None:
+      value = ''
+    print '   ', key, '=', value
+
 
 class Host(cr.Plugin, cr.Plugin.Type):
   """Base class for implementing cr hosts.
@@ -75,9 +82,7 @@
     if cr.context.verbose:
       print ' '.join(command)
       if cr.context.verbose >= _TRAIL_VERBOSITY:
-        print 'Command expanded the following variables:'
-        for key, value in trail:
-          print '   ', key, '=', value
+        PrintTrail(trail)
     if ignore_dry_run or not cr.context.dry_run:
       out = None
       if capture:
@@ -93,9 +98,7 @@
         print 'Failed to exec', command
         # Don't log the trail if we already have
         if cr.context.verbose < _TRAIL_VERBOSITY:
-          print 'Variables used to build the command were:'
-          for key, value in trail:
-            print '   ', key, '=', value
+          PrintTrail(trail)
         exit(1)
       try:
         if ignore_interrupt_signal:
diff --git a/tools/cr/cr/commands/__init__.py b/tools/cr/cr/commands/__init__.py
index 852ecbe..1617a30 100644
--- a/tools/cr/cr/commands/__init__.py
+++ b/tools/cr/cr/commands/__init__.py
@@ -7,3 +7,9 @@
 This package has all the standard commands built in to the cr tool.
 Most commands use actions to perform the real work.
 """
+
+import cr
+
+cr.Import(__name__, 'command')
+cr.Import(__name__, 'prepare')
+cr.Import(__name__, 'init')
diff --git a/tools/cr/cr/commands/init.py b/tools/cr/cr/commands/init.py
index 5991825..95652c7 100644
--- a/tools/cr/cr/commands/init.py
+++ b/tools/cr/cr/commands/init.py
@@ -146,7 +146,7 @@
       build_package.config.OVERRIDES[name] = value
 
     # Run all the output directory init hooks
-    for hook in InitHook.Plugins():
+    for hook in cr.InitHook.Plugins():
       hook.Run(old_version, build_package.config)
     # Redo activations, they might have changed
     cr.plugin.Activate()
@@ -157,24 +157,3 @@
     # Prepare the platform in here, using the updated config
     cr.Platform.Prepare()
     cr.SelectCommand.Select()
-
-
-class InitHook(cr.Plugin, cr.Plugin.Type):
-  """Base class for output directory initialization hooks.
-
-  Implementations used to fix from old version to new ones live in the
-  cr.fixups package.
-  """
-
-  def Run(self, old_version, config):
-    """Run the initialization hook.
-
-    This is invoked once per init invocation.
-    Args:
-      old_version: The old version,
-          0.0 if the old version was bad or missing,
-          None if building a new output direcory.
-      config: The mutable config that will be written.
-    """
-    raise NotImplementedError('Must be overridden.')
-
diff --git a/tools/cr/cr/config.py b/tools/cr/cr/config.py
index 5b4ca8e..7c235b6 100644
--- a/tools/cr/cr/config.py
+++ b/tools/cr/cr/config.py
@@ -66,7 +66,7 @@
     return value
 
 
-class Config(cr.visitor.Node):
+class Config(cr.visitor.Node, cr.loader.AutoExport):
   """The main variable holding class.
 
   This holds a set of unresolved key value pairs, and the set of child Config
@@ -142,7 +142,7 @@
 
     Raw values can be callable, simple values, or contain format strings.
     Args:
-      visitor: The vistior asking to resolve a value.
+      visitor: The visitor asking to resolve a value.
       key: The key being visited.
       value: The unresolved value associated with the key.
     Returns:
@@ -165,6 +165,11 @@
       value = hook(self, key, value)
     return value
 
+  def Missing(self, key):
+    for hook in self.fixup_hooks:
+      hook(self, key, None)
+    raise KeyError(key)
+
   @staticmethod
   def ParseValue(value):
     """Converts a string to a value.
@@ -237,4 +242,3 @@
 
   def __contains__(self, key):
     return self.Find(key) is not None
-
diff --git a/tools/cr/cr/loader.py b/tools/cr/cr/loader.py
index 9a5aaca..21cb6f5 100644
--- a/tools/cr/cr/loader.py
+++ b/tools/cr/cr/loader.py
@@ -68,18 +68,33 @@
       basenames = sorted(os.listdir(path))
     except OSError:
       basenames = []
+    packages = []
     for basename in basenames:
       fullpath = os.path.join(path, basename)
       if os.path.isdir(fullpath):
         name = '.'.join([package.__name__, basename])
-        child = _Import(name)
-        modules.extend(_ScanPackage(child))
+        packages.append(name)
       elif basename.endswith('.py') and not basename.startswith('_'):
         name = '.'.join([package.__name__, basename[:-3]])
-        modules.append(name)
+        module = _Import(name)
+        _ScanModule(module)
+        modules.append(module)
+    for name in packages:
+      child = _Import(name)
+      modules.extend(_ScanPackage(child))
   return modules
 
 
+def Import(package, name):
+  module = _Import(package + '.' + name)
+  path = getattr(module, '__path__', None)
+  if path:
+    _ScanPackage(module)
+  else:
+    _ScanModule(module)
+  return module
+
+
 def Scan():
   """Scans from the cr package down, loading modules as needed.
 
@@ -92,32 +107,7 @@
   Modules are allowed to refer to each other, their import will be retried
   until it succeeds or no progress can be made on any module.
   """
-  remains = _ScanPackage(cr)
-  progress = True
-  modules = []
-  while progress and remains:
-    progress = False
-    todo = remains
-    remains = []
-    for name in todo:
-      try:
-        module = _Import(name)
-        modules.append(module)
-        _ScanModule(module)
-        progress = True
-      except:  # sink all errors here pylint: disable=bare-except
-        # Try this one again, if progress was made on a possible dependency
-        remains.append(name)
-  if remains:
-    print "Cannot load all of", remains
-    # There are modules that won't import in any order.
-    # Print all the errors as we can't determine root cause.
-    for name in remains:
-      try:
-        _Import(name)
-      except ImportError as e:
-        print 'Failed importing', name, ':', e
-    exit(1)
+  modules = _ScanPackage(cr)
   # Now scan all the found modules one more time.
   # This happens after all imports, in case any imports register scan hooks.
   for module in modules:
diff --git a/tools/cr/cr/targets/__init__.py b/tools/cr/cr/targets/__init__.py
index 852ecbe..e44e02b 100644
--- a/tools/cr/cr/targets/__init__.py
+++ b/tools/cr/cr/targets/__init__.py
@@ -7,3 +7,7 @@
 This package has all the standard commands built in to the cr tool.
 Most commands use actions to perform the real work.
 """
+
+import cr
+
+cr.Import(__name__, 'target')
diff --git a/tools/cr/cr/targets/chrome.py b/tools/cr/cr/targets/chrome.py
index 49d09ee..5b63365 100644
--- a/tools/cr/cr/targets/chrome.py
+++ b/tools/cr/cr/targets/chrome.py
@@ -9,10 +9,6 @@
 
 class ChromeTarget(cr.NamedTarget):
   NAME = 'chrome'
-  DEFAULT = cr.Config.From(
-      #  CR_URL is the page to open when the target is run.
-      CR_URL='https://www.google.com/',
-  )
   CONFIG = cr.Config.From(
       CR_RUN_ARGUMENTS=cr.Config.Optional('-d "{CR_URL!e}"'),
       CR_TARGET_NAME='Chrome',
diff --git a/tools/cr/cr/targets/chrome_shell.py b/tools/cr/cr/targets/chrome_shell.py
index bd326c4..65ff627 100644
--- a/tools/cr/cr/targets/chrome_shell.py
+++ b/tools/cr/cr/targets/chrome_shell.py
@@ -9,10 +9,6 @@
 
 class ChromeShellTarget(cr.NamedTarget):
   NAME = 'chrome_shell'
-  DEFAULT = cr.Config.From(
-      #  CR_URL is the page to open when the target is run.
-      CR_URL='https://www.google.com/',
-  )
   CONFIG = cr.Config.From(
       CR_RUN_ARGUMENTS=cr.Config.Optional('-d "{CR_URL!e}"'),
       CR_TARGET_NAME='ChromeShell',
diff --git a/tools/cr/cr/targets/content_shell.py b/tools/cr/cr/targets/content_shell.py
index f4a415d..b8d7fee 100644
--- a/tools/cr/cr/targets/content_shell.py
+++ b/tools/cr/cr/targets/content_shell.py
@@ -9,10 +9,6 @@
 
 class ContentShellTarget(cr.NamedTarget):
   NAME = 'content_shell'
-  DEFAULT = cr.Config.From(
-      #  CR_URL is the page to open when the target is run.
-      CR_URL='https://www.google.com/',
-  )
   CONFIG = cr.Config.From(
       CR_RUN_ARGUMENTS=cr.Config.Optional('-d "{CR_URL!e}"'),
       CR_TARGET_NAME='ContentShell',
diff --git a/tools/cr/cr/visitor.py b/tools/cr/cr/visitor.py
index 339040c..8e01c70 100644
--- a/tools/cr/cr/visitor.py
+++ b/tools/cr/cr/visitor.py
@@ -239,11 +239,14 @@
   def Get(self, key, raise_errors=False):
     search = SearchVisitor(key).VisitNode(self)
     if not search.found:
-      raise KeyError(key)
+      self.Missing(key)
     if search.error and raise_errors:
       raise search.error  # bad type inference pylint: disable=raising-bad-type
     return search.value
 
+  def Missing(self, key):
+    raise KeyError(key)
+
   def Resolve(self, visitor, key, value):
     _ = visitor, key
     return value
diff --git a/tools/cr/main.py b/tools/cr/main.py
index 3dd63bd..b5c2a4b 100644
--- a/tools/cr/main.py
+++ b/tools/cr/main.py
@@ -10,10 +10,6 @@
 import os
 import sys
 import cr
-import cr.auto.user
-import cr.autocomplete
-import cr.loader
-import cr.base.context
 
 _CONTACT = 'iancottrell@chromium.org'
 
diff --git a/tools/gn/BUILD.gn b/tools/gn/BUILD.gn
index 9712706..ee7b3b8 100644
--- a/tools/gn/BUILD.gn
+++ b/tools/gn/BUILD.gn
@@ -52,6 +52,7 @@
     "functions.h",
     "functions_target.cc",
     "function_exec_script.cc",
+    "function_get_target_outputs.cc",
     "function_process_file_template.cc",
     "function_read_file.cc",
     "function_rebase_path.cc",
@@ -177,6 +178,7 @@
     "escape_unittest.cc",
     "filesystem_utils_unittest.cc",
     "file_template_unittest.cc",
+    "function_get_target_outputs_unittest.cc",
     "function_rebase_path_unittest.cc",
     "functions_unittest.cc",
     "header_checker_unittest.cc",
@@ -187,6 +189,7 @@
     "ninja_binary_target_writer_unittest.cc",
     "ninja_copy_target_writer_unittest.cc",
     "ninja_helper_unittest.cc",
+    "ninja_target_writer_unittest.cc",
     "operators_unittest.cc",
     "parse_tree_unittest.cc",
     "parser_unittest.cc",
@@ -202,6 +205,7 @@
     "test_with_scope.cc",
     "test_with_scope.h",
     "tokenizer_unittest.cc",
+    "value_unittest.cc",
     "visibility_unittest.cc",
   ]
   deps = [
diff --git a/tools/gn/args.cc b/tools/gn/args.cc
index 2c4891c..db7b84d 100644
--- a/tools/gn/args.cc
+++ b/tools/gn/args.cc
@@ -26,20 +26,33 @@
     "   - default_os\n"
     "   - os (by default this is the same as \"default_os\")\n"
     "\n"
-    "  Second, arguments specified on the command-line via \"--args\" are\n"
-    "  applied. These can override the system default ones, and add new ones.\n"
-    "  These are whitespace-separated. For example:\n"
+    "  If specified, arguments from the --args command line flag are used. If\n"
+    "  that flag is not specified, args from previous builds in the build\n"
+    "  directory will be used (this is in the file args.gn in the build\n"
+    "  directory).\n"
     "\n"
-    "    gn --args=\"enable_doom_melon=false\" os=\\\"beos\\\"\n"
-    "\n"
-    "  Third, toolchain overrides are applied. These are specified in the\n"
+    "  Last, for targets being compiled with a non-default toolchain, the\n"
+    "  toolchain overrides are applied. These are specified in the\n"
     "  toolchain_args section of a toolchain definition. The use-case for\n"
     "  this is that a toolchain may be building code for a different\n"
     "  platform, and that it may want to always specify Posix, for example.\n"
     "  See \"gn help toolchain_args\" for more.\n"
     "\n"
-    "  It is an error to specify an override for a build argument that never\n"
-    "  appears in a \"declare_args\" call.\n"
+    "  If you specify an override for a build argument that never appears in\n"
+    "  a \"declare_args\" call, a nonfatal error will be displayed.\n"
+    "\n"
+    "Examples\n"
+    "\n"
+    "  gn args out/FooBar\n"
+    "      Create the directory out/FooBar and open an editor. You would type\n"
+    "      something like this into that file:\n"
+    "          enable_doom_melon=false\n"
+    "          os=\"android\"\n"
+    "\n"
+    "  gn gen out/FooBar --args=\"enable_doom_melon=true os=\\\"android\\\"\"\n"
+    "      This will overwrite the build directory with the given arguments.\n"
+    "      (Note that the quotes inside the args command will usually need to\n"
+    "      be escaped for your shell to pass through strings values.)\n"
     "\n"
     "How build arguments are used\n"
     "\n"
diff --git a/tools/gn/bin/linux/gn.sha1 b/tools/gn/bin/linux/gn.sha1
index a97f17c..400bfda 100644
--- a/tools/gn/bin/linux/gn.sha1
+++ b/tools/gn/bin/linux/gn.sha1
@@ -1 +1 @@
-5d83f785d62856cc6f9817608c5e25fc11803748
\ No newline at end of file
+4cbb0e8664dd415f9dec44f8f70c9686630cf38f
\ No newline at end of file
diff --git a/tools/gn/bin/linux/gn32.sha1 b/tools/gn/bin/linux/gn32.sha1
index 5f5ef66..5899de9 100644
--- a/tools/gn/bin/linux/gn32.sha1
+++ b/tools/gn/bin/linux/gn32.sha1
@@ -1 +1 @@
-cdb58345bba399de11e45c255f9b598aba984820
\ No newline at end of file
+2bd6770e283ec33de78b7ce8433f419fbdaf6708
\ No newline at end of file
diff --git a/tools/gn/bin/mac/gn.sha1 b/tools/gn/bin/mac/gn.sha1
index 6d33175..a08886c 100644
--- a/tools/gn/bin/mac/gn.sha1
+++ b/tools/gn/bin/mac/gn.sha1
@@ -1 +1 @@
-1d037c843cc1ae86203dee80d6461720b1058413
+19fa6c687133c3479ee4917e950831fcee38d9d9
diff --git a/tools/gn/bin/win/gn.exe.sha1 b/tools/gn/bin/win/gn.exe.sha1
index 86893a2..68dc432 100644
--- a/tools/gn/bin/win/gn.exe.sha1
+++ b/tools/gn/bin/win/gn.exe.sha1
@@ -1,2 +1,2 @@
-deb2bfcaaa9eb465ada1b9f407e19361f03370e9
+4d8d44ebf698f16080e35600f9cad2fff178010c
 
diff --git a/tools/gn/command_args.cc b/tools/gn/command_args.cc
index 72a623f..6ee05f7 100644
--- a/tools/gn/command_args.cc
+++ b/tools/gn/command_args.cc
@@ -2,21 +2,38 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <stdio.h>
+#include <stdlib.h>
+
 #include <map>
 
+#include "base/command_line.h"
+#include "base/environment.h"
+#include "base/file_util.h"
+#include "base/process/launch.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "tools/gn/commands.h"
+#include "tools/gn/filesystem_utils.h"
 #include "tools/gn/input_file.h"
 #include "tools/gn/parse_tree.h"
 #include "tools/gn/setup.h"
 #include "tools/gn/standard_out.h"
 #include "tools/gn/tokenizer.h"
+#include "tools/gn/trace.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#include <shellapi.h>
+#endif
 
 namespace commands {
 
 namespace {
 
+const char kSwitchList[] = "list";
+const char kSwitchShort[] = "short";
+
 bool DoesLineBeginWithComment(const base::StringPiece& line) {
   // Skip whitespace.
   size_t i = 0;
@@ -95,67 +112,50 @@
   }
 }
 
-}  // namespace
-
-extern const char kArgs[] = "args";
-extern const char kArgs_HelpShort[] =
-    "args: Display configurable arguments declared by the build.";
-extern const char kArgs_Help[] =
-    "gn args [arg name]\n"
-    "  Displays all arguments declared by buildfiles along with their\n"
-    "  description. Build arguments are anything in a declare_args() block\n"
-    "  in any buildfile. The comment preceding the declaration will be\n"
-    "  displayed here (so comment well!).\n"
-    "\n"
-    "  These arguments can be overridden on the command-line:\n"
-    "    --args=\"doom_melon_setting=5 component_build=1\"\n"
-    "  or in a toolchain definition (see \"gn help buildargs\" for more on\n"
-    "  how this all works).\n"
-    "\n"
-    "  If \"arg name\" is specified, only the information for that argument\n"
-    "  will be displayed. Otherwise all arguments will be displayed.\n";
-
-int RunArgs(const std::vector<std::string>& args) {
+int ListArgs(const std::string& build_dir) {
   Setup* setup = new Setup;
   setup->set_check_for_bad_items(false);
-  // TODO(brettw) bug 343726: Use a temporary directory instead of this
-  // default one to avoid messing up any build that's in there.
-  if (!setup->DoSetup("//out/Default/") || !setup->Run())
+  if (!setup->DoSetup(build_dir) || !setup->Run())
     return 1;
 
   Scope::KeyValueMap build_args;
   setup->build_settings().build_args().MergeDeclaredArguments(&build_args);
 
-  if (args.size() == 1) {
-    // Get help on a specific command.
-    Scope::KeyValueMap::const_iterator found_arg = build_args.find(args[0]);
+  // Find all of the arguments we care about. Use a regular map so they're
+  // sorted nicely when we write them out.
+  std::map<base::StringPiece, Value> sorted_args;
+  std::string list_value =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kSwitchList);
+  if (list_value.empty()) {
+    // List all values.
+    for (Scope::KeyValueMap::const_iterator i = build_args.begin();
+         i != build_args.end(); ++i)
+      sorted_args.insert(*i);
+  } else {
+    // List just the one specified as the parameter to --list.
+    Scope::KeyValueMap::const_iterator found_arg = build_args.find(list_value);
     if (found_arg == build_args.end()) {
       Err(Location(), "Unknown build argument.",
-          "You asked for \"" + args[0] + "\" which I didn't find in any "
-          "buildfile\nassociated with this build.");
+          "You asked for \"" + list_value + "\" which I didn't find in any "
+          "build file\nassociated with this build.").PrintToStdout();
       return 1;
     }
-    PrintArgHelp(args[0], found_arg->second);
-    return 0;
-  } else if (args.size() > 1) {
-    // Too many arguments.
-    Err(Location(), "You're holding it wrong.",
-        "Usage: \"gn args [arg name]\"").PrintToStdout();
-    return 1;
+    sorted_args.insert(*found_arg);
   }
 
-  // List all arguments. First put them in a regular map so they're sorted.
-  std::map<base::StringPiece, Value> sorted_args;
-  for (Scope::KeyValueMap::const_iterator i = build_args.begin();
-       i != build_args.end(); ++i)
-    sorted_args.insert(*i);
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchShort)) {
+    // Short key=value output.
+    for (std::map<base::StringPiece, Value>::iterator i = sorted_args.begin();
+         i != sorted_args.end(); ++i) {
+      OutputString(i->first.as_string());
+      OutputString(" = ");
+      OutputString(i->second.ToString(true));
+      OutputString("\n");
+    }
+    return 0;
+  }
 
-  OutputString(
-      "Available build arguments. Note that the which arguments are declared\n"
-      "and their default values may depend on other arguments or the current\n"
-      "platform and architecture. So setting some values may add, remove, or\n"
-      "change the default value of other values.\n\n");
-
+  // Long output.
   for (std::map<base::StringPiece, Value>::iterator i = sorted_args.begin();
        i != sorted_args.end(); ++i) {
     PrintArgHelp(i->first, i->second);
@@ -165,4 +165,183 @@
   return 0;
 }
 
+#if defined(OS_WIN)
+
+bool RunEditor(const base::FilePath& file_to_edit) {
+  SHELLEXECUTEINFO info;
+  memset(&info, 0, sizeof(info));
+  info.cbSize = sizeof(info);
+  info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_CLASSNAME;
+  info.lpFile = file_to_edit.value().c_str();
+  info.nShow = SW_SHOW;
+  info.lpClass = L".txt";
+  if (!::ShellExecuteEx(&info)) {
+    Err(Location(), "Couldn't run editor.",
+        "Just edit \"" + FilePathToUTF8(file_to_edit) +
+        "\" manually instead.").PrintToStdout();
+    return false;
+  }
+
+  if (!info.hProcess) {
+    // Windows re-used an existing process.
+    OutputString("\"" + FilePathToUTF8(file_to_edit) +
+                 "\" opened in editor, save it and press <Enter> when done.\n");
+    getchar();
+  } else {
+    OutputString("Waiting for editor on \"" + FilePathToUTF8(file_to_edit) +
+                 "\"...\n");
+    ::WaitForSingleObject(info.hProcess, INFINITE);
+    ::CloseHandle(info.hProcess);
+  }
+  return true;
+}
+
+#else  // POSIX
+
+bool RunEditor(const base::FilePath& file_to_edit) {
+  // Prefer $VISUAL, then $EDITOR, then vi.
+  const char* editor_ptr = getenv("VISUAL");
+  if (!editor_ptr)
+    editor_ptr = getenv("EDITOR");
+  if (!editor_ptr)
+    editor_ptr = "vi";
+
+  std::string cmd(editor_ptr);
+  cmd.append(" \"");
+
+  // Its impossible to do this properly since we don't know the user's shell,
+  // but quoting and escaping internal quotes should handle 99.999% of all
+  // cases.
+  std::string escaped_name = file_to_edit.value();
+  ReplaceSubstringsAfterOffset(&escaped_name, 0, "\"", "\\\"");
+  cmd.append(escaped_name);
+  cmd.push_back('"');
+
+  OutputString("Waiting for editor on \"" + file_to_edit.value() +
+               "\"...\n");
+  return system(cmd.c_str()) == 0;
+}
+
+#endif
+
+int EditArgsFile(const std::string& build_dir) {
+  {
+    // Scope the setup. We only use it for some basic state. We'll do the
+    // "real" build below in the gen command.
+    Setup setup;
+    setup.set_check_for_bad_items(false);
+    // Don't fill build arguments. We're about to edit the file which supplies
+    // these in the first place.
+    setup.set_fill_arguments(false);
+    if (!setup.DoSetup(build_dir))
+      return 1;
+
+    // Ensure the file exists. Need to normalize path separators since on
+    // Windows they can come out as forward slashes here, and that confuses some
+    // of the commands.
+    base::FilePath arg_file =
+        setup.build_settings().GetFullPath(setup.GetBuildArgFile())
+        .NormalizePathSeparators();
+    if (!base::PathExists(arg_file)) {
+      std::string argfile_default_contents =
+          "# Build arguments go here. Examples:\n"
+          "#   enable_doom_melon = true\n"
+          "#   crazy_something = \"absolutely\"\n";
+#if defined(OS_WIN)
+      // Use Windows lineendings for this file since it will often open in
+      // Notepad which can't handle Unix ones.
+      ReplaceSubstringsAfterOffset(&argfile_default_contents, 0, "\n", "\r\n");
+#endif
+      base::CreateDirectory(arg_file.DirName());
+      base::WriteFile(arg_file, argfile_default_contents.c_str(),
+                      static_cast<int>(argfile_default_contents.size()));
+    }
+
+    ScopedTrace editor_trace(TraceItem::TRACE_SETUP, "Waiting for editor");
+    if (!RunEditor(arg_file))
+      return 1;
+  }
+
+  // Now do a normal "gen" command.
+  OutputString("Generating files...\n");
+  std::vector<std::string> gen_commands;
+  gen_commands.push_back(build_dir);
+  return RunGen(gen_commands);
+}
+
+}  // namespace
+
+extern const char kArgs[] = "args";
+extern const char kArgs_HelpShort[] =
+    "args: Display or configure arguments declared by the build.";
+extern const char kArgs_Help[] =
+    "gn args [arg name]\n"
+    "\n"
+    "  See also \"gn help buildargs\" for a more high-level overview of how\n"
+    "  build arguments work.\n"
+    "\n"
+    "Usage\n"
+    "  gn args <dir_name>\n"
+    "      Open the arguments for the given build directory in an editor\n"
+    "      (as specified by the EDITOR environment variable). If the given\n"
+    "      build directory doesn't exist, it will be created and an empty\n"
+    "      args file will be opened in the editor. You would type something\n"
+    "      like this into that file:\n"
+    "          enable_doom_melon=false\n"
+    "          os=\"android\"\n"
+    "\n"
+    "      Note: you can edit the build args manually by editing the file\n"
+    "      \"args.gn\" in the build directory and then running\n"
+    "      \"gn gen <build_dir>\".\n"
+    "\n"
+    "  gn args <dir_name> --list[=<exact_arg>] [--short]\n"
+    "      Lists all build arguments available in the current configuration,\n"
+    "      or, if an exact_arg is specified for the list flag, just that one\n"
+    "      build argument.\n"
+    "\n"
+    "      The output will list the declaration location, default value, and\n"
+    "      comment preceeding the declaration. If --short is specified,\n"
+    "      only the names and values will be printed.\n"
+    "\n"
+    "      If the dir_name is specified, the build configuration will be\n"
+    "      taken from that build directory. The reason this is needed is that\n"
+    "      the definition of some arguments is dependent on the build\n"
+    "      configuration, so setting some values might add, remove, or change\n"
+    "      the default values for other arguments. Specifying your exact\n"
+    "      configuration allows the proper arguments to be displayed.\n"
+    "\n"
+    "      Instead of specifying the dir_name, you can also use the\n"
+    "      command-line flag to specify the build configuration:\n"
+    "        --args=<exact list of args to use>\n"
+    "\n"
+    "Examples\n"
+    "  gn args out/Debug\n"
+    "    Opens an editor with the args for out/Debug.\n"
+    "\n"
+    "  gn args out/Debug --list --short\n"
+    "    Prints all arguments with their default values for the out/Debug\n"
+    "    build.\n"
+    "\n"
+    "  gn args out/Debug --list=cpu_arch\n"
+    "    Prints information about the \"cpu_arch\" argument for the out/Debug\n"
+    "    build.\n"
+    "\n"
+    "  gn args --list --args=\"os=\\\"android\\\" enable_doom_melon=true\"\n"
+    "    Prints all arguments with the default values for a build with the\n"
+    "    given arguments set (which may affect the values of other\n"
+    "    arguments).\n";
+
+int RunArgs(const std::vector<std::string>& args) {
+  if (args.size() != 1) {
+    Err(Location(), "Exactly one build dir needed.",
+        "Usage: \"gn args <build_dir>\"\n"
+        "Or see \"gn help args\" for more variants.").PrintToStdout();
+    return 1;
+  }
+
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchList))
+    return ListArgs(args[0]);
+  return EditArgsFile(args[0]);
+}
+
 }  // namespace commands
diff --git a/tools/gn/command_help.cc b/tools/gn/command_help.cc
index 2d9d8dd..6e41656 100644
--- a/tools/gn/command_help.cc
+++ b/tools/gn/command_help.cc
@@ -43,8 +43,6 @@
   PrintShortHelp(
       "-q: Quiet mode, don't print anything on success.");
   PrintShortHelp(
-      "--output: Directory for build output (relative to source root).");
-  PrintShortHelp(
       "--root: Specifies source root (overrides .gn file).");
   PrintShortHelp(
       "--time: Outputs a summary of how long everything took.");
diff --git a/tools/gn/escape_unittest.cc b/tools/gn/escape_unittest.cc
index 44440de..7ba0af0 100644
--- a/tools/gn/escape_unittest.cc
+++ b/tools/gn/escape_unittest.cc
@@ -17,8 +17,9 @@
   opts.mode = ESCAPE_SHELL;
   std::string result = EscapeString("asdf: \"$\\bar", opts, NULL);
 #if defined(OS_WIN)
-  // Windows shell doesn't escape backslashes.
-  EXPECT_EQ("\"asdf: \"$\\bar\"", result);
+  // Windows shell doesn't escape backslashes, but it does backslash-escape
+  // quotes.
+  EXPECT_EQ("\"asdf: \\\"$\\bar\"", result);
 #else
   EXPECT_EQ("\"asdf: \\\"$\\\\bar\"", result);
 #endif
diff --git a/tools/gn/file_template.cc b/tools/gn/file_template.cc
index ec34993..b27087b 100644
--- a/tools/gn/file_template.cc
+++ b/tools/gn/file_template.cc
@@ -91,6 +91,13 @@
     ParseOneTemplateString(t[i]);
 }
 
+FileTemplate::FileTemplate(const std::vector<SourceFile>& t)
+    : has_substitutions_(false) {
+  std::fill(types_required_, &types_required_[Subrange::NUM_TYPES], false);
+  for (size_t i = 0; i < t.size(); i++)
+    ParseOneTemplateString(t[i].value());
+}
+
 FileTemplate::~FileTemplate() {
 }
 
@@ -121,6 +128,7 @@
 
   const std::vector<Value>& sources_list = sources.list_value();
   for (size_t i = 0; i < sources_list.size(); i++) {
+    string_output.clear();
     if (!sources_list[i].VerifyTypeIs(Value::STRING, err))
       return;
 
@@ -140,17 +148,18 @@
       subst[i] = GetSubstitution(str, static_cast<Subrange::Type>(i));
   }
 
-  output->resize(templates_.container().size());
+  size_t first_output_index = output->size();
+  output->resize(output->size() + templates_.container().size());
   for (size_t template_i = 0;
        template_i < templates_.container().size(); template_i++) {
     const Template& t = templates_[template_i];
-    (*output)[template_i].clear();
+    std::string& cur_output = (*output)[first_output_index + template_i];
     for (size_t subrange_i = 0; subrange_i < t.container().size();
          subrange_i++) {
       if (t[subrange_i].type == Subrange::LITERAL)
-        (*output)[template_i].append(t[subrange_i].literal);
+        cur_output.append(t[subrange_i].literal);
       else
-        (*output)[template_i].append(subst[t[subrange_i].type]);
+        cur_output.append(subst[t[subrange_i].type]);
     }
   }
 }
diff --git a/tools/gn/file_template.h b/tools/gn/file_template.h
index d66b3e3..30b40da 100644
--- a/tools/gn/file_template.h
+++ b/tools/gn/file_template.h
@@ -14,6 +14,7 @@
 
 struct EscapeOptions;
 class ParseNode;
+class SourceFile;
 class Target;
 
 extern const char kSourceExpansion_Help[];
@@ -61,6 +62,8 @@
   // set. In this case you should not use this object.
   FileTemplate(const Value& t, Err* err);
   FileTemplate(const std::vector<std::string>& t);
+  FileTemplate(const std::vector<SourceFile>& t);
+
   ~FileTemplate();
 
   // Returns an output template representing the given target's script
@@ -80,6 +83,9 @@
              const ParseNode* origin,
              std::vector<Value>* dest,
              Err* err) const;
+
+  // Low-level version of Apply that handles one source file. The results
+  // will be *appended* to the output.
   void ApplyString(const std::string& input,
                    std::vector<std::string>* output) const;
 
diff --git a/tools/gn/file_template_unittest.cc b/tools/gn/file_template_unittest.cc
index e05bda0..0120a8b 100644
--- a/tools/gn/file_template_unittest.cc
+++ b/tools/gn/file_template_unittest.cc
@@ -19,6 +19,7 @@
   ASSERT_EQ(1u, result.size());
   EXPECT_EQ("something_static", result[0]);
 
+  result.clear();
   t.ApplyString("lalala", &result);
   ASSERT_EQ(1u, result.size());
   EXPECT_EQ("something_static", result[0]);
diff --git a/tools/gn/filesystem_utils.cc b/tools/gn/filesystem_utils.cc
index 0bc266d..6279964 100644
--- a/tools/gn/filesystem_utils.cc
+++ b/tools/gn/filesystem_utils.cc
@@ -181,6 +181,8 @@
     return SOURCE_RC;
   if (extension == "S" || extension == "s")
     return SOURCE_S;
+  if (extension == "o" || extension == "obj")
+    return SOURCE_O;
 
   return SOURCE_UNKNOWN;
 }
diff --git a/tools/gn/filesystem_utils.h b/tools/gn/filesystem_utils.h
index cb5fbfd..09451a5 100644
--- a/tools/gn/filesystem_utils.h
+++ b/tools/gn/filesystem_utils.h
@@ -26,6 +26,7 @@
   SOURCE_MM,
   SOURCE_S,
   SOURCE_RC,
+  SOURCE_O,  // Object files can be inputs, too. Also counts .obj.
 };
 
 SourceFileType GetSourceFileType(const SourceFile& file);
diff --git a/tools/gn/function_get_target_outputs.cc b/tools/gn/function_get_target_outputs.cc
new file mode 100644
index 0000000..370fee9
--- /dev/null
+++ b/tools/gn/function_get_target_outputs.cc
@@ -0,0 +1,181 @@
+// 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.
+
+#include "tools/gn/build_settings.h"
+#include "tools/gn/file_template.h"
+#include "tools/gn/functions.h"
+#include "tools/gn/ninja_helper.h"
+#include "tools/gn/parse_tree.h"
+#include "tools/gn/settings.h"
+#include "tools/gn/target.h"
+#include "tools/gn/value.h"
+
+namespace functions {
+
+namespace {
+
+void GetOutputsForTarget(const BuildSettings* build_settings,
+                         const Target* target,
+                         std::vector<std::string>* ret) {
+  switch (target->output_type()) {
+    case Target::ACTION:
+    case Target::COPY_FILES: {
+      // Actions and copy targets: return the outputs specified.
+      const std::vector<SourceFile>& outs = target->action_values().outputs();
+      ret->reserve(outs.size());
+      for (size_t i = 0; i < outs.size(); i++)
+        ret->push_back(outs[i].value());
+      break;
+    }
+
+    case Target::ACTION_FOREACH: {
+      // Action_foreach: return the result of the template in the outputs.
+      FileTemplate file_template(target->action_values().outputs());
+      const std::vector<SourceFile>& sources = target->sources();
+      for (size_t i = 0; i < sources.size(); i++)
+        file_template.ApplyString(sources[i].value(), ret);
+      break;
+    }
+
+    case Target::EXECUTABLE:
+    case Target::SHARED_LIBRARY:
+    case Target::STATIC_LIBRARY:
+      // Return the resulting binary file. Currently, fall through to the
+      // Ninja helper below which will compute the main output name.
+      //
+      // TODO(brettw) some targets have secondary files which should go into
+      // the list after the main (like shared libraries on Windows have an
+      // import library).
+    case Target::GROUP:
+    case Target::SOURCE_SET: {
+      // These return the stamp file, which is computed by the NinjaHelper.
+      NinjaHelper helper(build_settings);
+      OutputFile output_file = helper.GetTargetOutputFile(target);
+
+      // The output file is relative to the build dir.
+      std::string absolute_output_file = build_settings->build_dir().value();
+      absolute_output_file.append(output_file.value());
+
+      ret->push_back(absolute_output_file);
+      break;
+    }
+
+    default:
+      NOTREACHED();
+  }
+}
+
+}  // namespace
+
+const char kGetTargetOutputs[] = "get_target_outputs";
+const char kGetTargetOutputs_HelpShort[] =
+    "get_target_outputs: [file list] Get the list of outputs from a target.";
+const char kGetTargetOutputs_Help[] =
+    "get_target_outputs: [file list] Get the list of outputs from a target.\n"
+    "\n"
+    "  get_target_outputs(target_label)\n"
+    "\n"
+    "  Returns a list of output files for the named target. The named target\n"
+    "  must have been previously defined in the current file before this\n"
+    "  function is called (it can't reference targets in other files because\n"
+    "  there isn't a defined execution order, and it obviously can't\n"
+    "  reference targets that are defined after the function call).\n"
+    "\n"
+    "Return value\n"
+    "\n"
+    "  The names in the resulting list will be absolute file paths (normally\n"
+    "  like \"//out/Debug/bar.exe\", depending on the build directory).\n"
+    "\n"
+    "  action targets: this will just return the files specified in the\n"
+    "  \"outputs\" variable of the target.\n"
+    "\n"
+    "  action_foreach targets: this will return the result of applying\n"
+    "  the output template to the sources (see \"gn help source_expansion\").\n"
+    "  This will be the same result (though with guaranteed absolute file\n"
+    "  paths), as process_file_template will return for those inputs\n"
+    "  (see \"gn help process_file_template\").\n"
+    "\n"
+    "  binary targets (executables, libraries): this will return a list\n"
+    "  of the resulting binary file(s). The \"main output\" (the actual\n"
+    "  binary or library) will always be the 0th element in the result.\n"
+    "  Depending on the platform and output type, there may be other output\n"
+    "  files as well (like import libraries) which will follow.\n"
+    "\n"
+    "  source sets and groups: this will return a list containing the path of\n"
+    "  the \"stamp\" file that Ninja will produce once all outputs are\n"
+    "  generated. This probably isn't very useful.\n"
+    "\n"
+    "Example\n"
+    "\n"
+    "  # Say this action generates a bunch of C source files.\n"
+    "  action_foreach(\"my_action\") {\n"
+    "    sources = [ ... ]\n"
+    "    outputs = [ ... ]\n"
+    "  }\n"
+    "\n"
+    "  # Compile the resulting source files into a source set.\n"
+    "  source_set(\"my_lib\") {\n"
+    "    sources = get_target_outputs(\":my_action\")\n"
+    "  }\n";
+
+Value RunGetTargetOutputs(Scope* scope,
+                          const FunctionCallNode* function,
+                          const std::vector<Value>& args,
+                          Err* err) {
+  if (args.size() != 1) {
+    *err = Err(function, "Expected one argument.");
+    return Value();
+  }
+
+  // Resolve the requested label.
+  Label label = Label::Resolve(scope->GetSourceDir(),
+                               ToolchainLabelForScope(scope), args[0], err);
+  if (label.is_null())
+    return Value();
+
+  // Find the referenced target. The targets previously encountered in this
+  // scope will have been stashed in the item collector (they'll be dispatched
+  // when this file is done running) so we can look through them.
+  const Target* target = NULL;
+  Scope::ItemVector* collector = scope->GetItemCollector();
+  if (!collector) {
+    *err = Err(function, "No targets defined in this context.");
+    return Value();
+  }
+  for (size_t i = 0; i < collector->size(); i++) {
+    const Item* item = (*collector)[i]->get();
+    if (item->label() != label)
+      continue;
+
+    const Target* as_target = item->AsTarget();
+    if (!as_target) {
+      *err = Err(function, "Label does not refer to a target.",
+          label.GetUserVisibleName(false) +
+          "\nrefers to a " + item->GetItemTypeName());
+      return Value();
+    }
+    target = as_target;
+    break;
+  }
+
+  if (!target) {
+    *err = Err(function, "Target not found in this context.",
+        label.GetUserVisibleName(false) +
+        "\nwas not found. get_target_outputs() can only be used for targets\n"
+        "previously defined in the current file.");
+    return Value();
+  }
+
+  std::vector<std::string> files;
+  GetOutputsForTarget(scope->settings()->build_settings(), target, &files);
+
+  Value ret(function, Value::LIST);
+  ret.list_value().reserve(files.size());
+  for (size_t i = 0; i < files.size(); i++)
+    ret.list_value().push_back(Value(function, files[i]));
+
+  return ret;
+}
+
+}  // namespace functions
diff --git a/tools/gn/function_get_target_outputs_unittest.cc b/tools/gn/function_get_target_outputs_unittest.cc
new file mode 100644
index 0000000..2833fdd
--- /dev/null
+++ b/tools/gn/function_get_target_outputs_unittest.cc
@@ -0,0 +1,115 @@
+// 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.
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "tools/gn/functions.h"
+#include "tools/gn/target.h"
+#include "tools/gn/test_with_scope.h"
+
+namespace {
+
+class GetTargetOutputsTest : public testing::Test {
+ public:
+  GetTargetOutputsTest() {
+    // Want consistent target names so explicitly set platform.
+    setup_.settings()->set_target_os(Settings::LINUX);
+    setup_.scope()->set_item_collector(&items_);
+  }
+
+  Value GetTargetOutputs(const std::string& name, Err* err) {
+    FunctionCallNode function;
+    std::vector<Value> args;
+    args.push_back(Value(NULL, name));
+    return functions::RunGetTargetOutputs(setup_.scope(), &function, args, err);
+  }
+
+  // Shortcut to get a label with the current toolchain.
+  Label GetLabel(const std::string& dir, const std::string& name) {
+    return Label(SourceDir(dir), name, setup_.toolchain()->label().dir(),
+                 setup_.toolchain()->label().name());
+  }
+
+  // Asserts that the given list contains a single string with the given value.
+  void AssertSingleStringEquals(const Value& list,
+                                const std::string& expected) {
+    ASSERT_TRUE(list.type() == Value::LIST);
+    ASSERT_EQ(1u, list.list_value().size());
+    ASSERT_TRUE(list.list_value()[0].type() == Value::STRING);
+    ASSERT_EQ(expected, list.list_value()[0].string_value());
+  }
+
+  void AssertTwoStringsEqual(const Value& list,
+                             const std::string& expected1,
+                             const std::string& expected2) {
+    ASSERT_TRUE(list.type() == Value::LIST);
+    ASSERT_EQ(2u, list.list_value().size());
+    ASSERT_TRUE(list.list_value()[0].type() == Value::STRING);
+    ASSERT_EQ(expected1, list.list_value()[0].string_value());
+    ASSERT_TRUE(list.list_value()[1].type() == Value::STRING);
+    ASSERT_EQ(expected2, list.list_value()[1].string_value());
+  }
+
+ protected:
+  TestWithScope setup_;
+
+  Scope::ItemVector items_;
+};
+
+}  // namespace
+
+TEST_F(GetTargetOutputsTest, Executable) {
+  Target* exe = new Target(setup_.settings(), GetLabel("//foo/", "bar"));
+  exe->set_output_type(Target::EXECUTABLE);
+  items_.push_back(new scoped_ptr<Item>(exe));
+
+  Err err;
+  Value result = GetTargetOutputs("//foo:bar", &err);
+  ASSERT_FALSE(err.has_error());
+  // The TestWithScope declares that the build is Linux, so we'll have no
+  // extension for the binaries.
+  AssertSingleStringEquals(result, "//out/Debug/bar");
+}
+
+TEST_F(GetTargetOutputsTest, SourceSet) {
+  Target* source_set = new Target(setup_.settings(), GetLabel("//foo/", "bar"));
+  source_set->set_output_type(Target::SOURCE_SET);
+  items_.push_back(new scoped_ptr<Item>(source_set));
+
+  Err err;
+  Value result = GetTargetOutputs("//foo:bar", &err);
+  ASSERT_FALSE(err.has_error());
+  AssertSingleStringEquals(result, "//out/Debug/obj/foo/bar.stamp");
+}
+
+TEST_F(GetTargetOutputsTest, Action) {
+  Target* action = new Target(setup_.settings(), GetLabel("//foo/", "bar"));
+  action->set_output_type(Target::ACTION);
+  action->action_values().outputs().push_back(SourceFile("//output1.txt"));
+  action->action_values().outputs().push_back(SourceFile("//output2.txt"));
+
+  items_.push_back(new scoped_ptr<Item>(action));
+
+  Err err;
+  Value result = GetTargetOutputs("//foo:bar", &err);
+  ASSERT_FALSE(err.has_error());
+  AssertTwoStringsEqual(result, "//output1.txt", "//output2.txt");
+}
+
+TEST_F(GetTargetOutputsTest, ActionForeach) {
+  Target* action = new Target(setup_.settings(), GetLabel("//foo/", "bar"));
+  action->set_output_type(Target::ACTION_FOREACH);
+  action->sources().push_back(SourceFile("//file.txt"));
+  action->action_values().outputs().push_back(
+      SourceFile("//out/Debug/{{source_file_part}}.one"));
+  action->action_values().outputs().push_back(
+      SourceFile("//out/Debug/{{source_file_part}}.two"));
+
+  items_.push_back(new scoped_ptr<Item>(action));
+
+  Err err;
+  Value result = GetTargetOutputs("//foo:bar", &err);
+  ASSERT_FALSE(err.has_error());
+  AssertTwoStringsEqual(result, "//out/Debug/file.txt.one",
+                        "//out/Debug/file.txt.two");
+}
diff --git a/tools/gn/function_template.cc b/tools/gn/function_template.cc
index 13d0186..368dc97 100644
--- a/tools/gn/function_template.cc
+++ b/tools/gn/function_template.cc
@@ -167,8 +167,7 @@
     return Value();
   }
 
-  scope->AddTemplate(template_name,
-                     scoped_ptr<Template>(new Template(scope, function)));
+  scope->AddTemplate(template_name, new Template(scope, function));
   return Value();
 }
 
diff --git a/tools/gn/function_toolchain.cc b/tools/gn/function_toolchain.cc
index 43d8cd7..c930df2 100644
--- a/tools/gn/function_toolchain.cc
+++ b/tools/gn/function_toolchain.cc
@@ -119,7 +119,13 @@
   if (!block_scope.CheckForUnusedVars(err))
     return Value();
 
-  scope->settings()->build_settings()->ItemDefined(toolchain.PassAs<Item>());
+  // Save this target for the file.
+  Scope::ItemVector* collector = scope->GetItemCollector();
+  if (!collector) {
+    *err = Err(function, "Can't define a toolchain in this context.");
+    return Value();
+  }
+  collector->push_back(new scoped_ptr<Item>(toolchain.PassAs<Item>()));
   return Value();
 }
 
diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc
index 0146350..3a19dfb 100644
--- a/tools/gn/functions.cc
+++ b/tools/gn/functions.cc
@@ -243,8 +243,14 @@
   if (err->has_error())
     return Value();
 
-  // Mark as complete.
-  scope->settings()->build_settings()->ItemDefined(config.PassAs<Item>());
+  // Save the generated item.
+  Scope::ItemVector* collector = scope->GetItemCollector();
+  if (!collector) {
+    *err = Err(function, "Can't define a config in this context.");
+    return Value();
+  }
+  collector->push_back(new scoped_ptr<Item>(config.PassAs<Item>()));
+
   return Value();
 }
 
@@ -646,6 +652,7 @@
     INSERT_FUNCTION(Defined, false)
     INSERT_FUNCTION(ExecScript, false)
     INSERT_FUNCTION(GetEnv, false)
+    INSERT_FUNCTION(GetTargetOutputs, false)
     INSERT_FUNCTION(Import, false)
     INSERT_FUNCTION(Print, false)
     INSERT_FUNCTION(ProcessFileTemplate, false)
diff --git a/tools/gn/functions.h b/tools/gn/functions.h
index 8a1bf3a..d3eb364 100644
--- a/tools/gn/functions.h
+++ b/tools/gn/functions.h
@@ -147,6 +147,14 @@
                 const std::vector<Value>& args,
                 Err* err);
 
+extern const char kGetTargetOutputs[];
+extern const char kGetTargetOutputs_HelpShort[];
+extern const char kGetTargetOutputs_Help[];
+Value RunGetTargetOutputs(Scope* scope,
+                          const FunctionCallNode* function,
+                          const std::vector<Value>& args,
+                          Err* err);
+
 extern const char kGroup[];
 extern const char kGroup_HelpShort[];
 extern const char kGroup_Help[];
diff --git a/tools/gn/functions_target.cc b/tools/gn/functions_target.cc
index ccca7cd..becbbab 100644
--- a/tools/gn/functions_target.cc
+++ b/tools/gn/functions_target.cc
@@ -58,7 +58,7 @@
 #define SCRIPT_EXECUTION_CONTEXT \
     "  The script will be executed with the given arguments with the current\n"\
     "  directory being that of the root build directory. If you pass files\n"\
-    "  to your script, see \"gn help to_build_path\" for how to convert\n" \
+    "  to your script, see \"gn help rebase_path\" for how to convert\n" \
     "  file names to be relative to the build directory (file names in the\n" \
     "  sources, outputs, and source_prereqs will be all treated as relative\n" \
     "  to the current build file and converted as needed automatically).\n"
@@ -70,6 +70,14 @@
     "  reference the output or generated intermediate file directories,\n" \
     "  respectively.\n"
 
+#define ACTION_DEPS \
+    "  The \"deps\" for an action will always be completed before any part\n" \
+    "  of the action is run so it can depend on the output of previous\n" \
+    "  steps. The \"datadeps\" will be built if the action is built, but\n" \
+    "  may not have completed before all steps of the action are started.\n" \
+    "  This can give additional parallelism in the build for runtime-only\n" \
+    "  dependencies.\n"
+
 const char kAction[] = "action";
 const char kAction_HelpShort[] =
     "action: Declare a target that runs a script a single time.";
@@ -80,15 +88,24 @@
     "  or more output files. If you want to run a script once for each of a\n"
     "  set of input files, see \"gn help action_foreach\".\n"
     "\n"
+    "Inputs\n"
+    "\n"
     "  In an action the \"sources\" and \"source_prereqs\" are treated the\n"
     "  same: they're both input dependencies on script execution with no\n"
     "  special handling. If you want to pass the sources to your script, you\n"
-    "  must do so explicitly by including them in the \"args\".\n"
+    "  must do so explicitly by including them in the \"args\". Note also\n"
+    "  that this means there is no special handling of paths since GN\n"
+    "  doesn't know which of the args are paths and not. You will want to use\n"
+    "  rebase_path() to convert paths to be relative to the root_build_dir.\n"
     "\n"
     "  It is recommended you put inputs to your script in the \"sources\"\n"
     "  variable, and stuff like other Python files required to run your\n"
     "  script in the \"source_prereqs\" variable.\n"
     "\n"
+    ACTION_DEPS
+    "\n"
+    "Outputs\n"
+    "\n"
     "  You should specify files created by your script by specifying them in\n"
     "  the \"outputs\".\n"
     "\n"
@@ -117,7 +134,8 @@
     "\n"
     "    # Note that we have to manually pass the sources to our script if\n"
     "    # the script needs them as inputs.\n"
-    "    args = [ \"--out\", to_build_path(target_gen_dir) ] + sources\n"
+    "    args = [ \"--out\", rebase_path(target_gen_dir, root_build_dir) ] +\n"
+    "           rebase_path(sources, root_build_dir)\n"
     "  }\n";
 
 Value RunAction(Scope* scope,
@@ -141,6 +159,8 @@
     "  of sources. If you want to run a script once that takes many files as\n"
     "  input, see \"gn help action\".\n"
     "\n"
+    "Inputs\n"
+    "\n"
     "  The script will be run once per file in the \"sources\" variable. The\n"
     "  \"outputs\" variable should specify one or more files with a source\n"
     "  expansion pattern in it (see \"gn help source_expansion\"). The output\n"
@@ -152,6 +172,10 @@
     "  listed in the \"source_prereqs\" variable. These files are treated as\n"
     "  dependencies of each script invocation.\n"
     "\n"
+    ACTION_DEPS
+    "\n"
+    "Outputs\n"
+    "\n"
     SCRIPT_EXECUTION_CONTEXT
     "\n"
     "File name handling\n"
@@ -182,11 +206,12 @@
     "\n"
     "    # Note that since \"args\" is opaque to GN, if you specify paths\n"
     "    # here, you will need to convert it to be relative to the build\n"
-    "    # directory using \"to_build_path()\".\n"
-    "    args = [ \"{{source}}\",\n"
-    "             \"-o\",\n"
-    "             to_build_path(relative_target_gen_dir) + \"/\" +\n"
-    "                 {{source_name_part}}.h\" ]\n"
+    "    # directory using \"rebase_path()\".\n"
+    "    args = [\n"
+    "      \"{{source}}\",\n"
+    "      \"-o\",\n"
+    "      rebase_path(relative_target_gen_dir, root_build_dir) +\n"
+    "        \"/{{source_name_part}}.h\" ]\n"
     "  }\n"
     "\n";
 Value RunActionForEach(Scope* scope,
diff --git a/tools/gn/gn.gyp b/tools/gn/gn.gyp
index 75f72c4..93560ed 100644
--- a/tools/gn/gn.gyp
+++ b/tools/gn/gn.gyp
@@ -56,6 +56,7 @@
         'functions.cc',
         'functions.h',
         'function_exec_script.cc',
+        'function_get_target_outputs.cc',
         'function_process_file_template.cc',
         'function_read_file.cc',
         'function_rebase_path.cc',
@@ -178,6 +179,7 @@
         'escape_unittest.cc',
         'filesystem_utils_unittest.cc',
         'file_template_unittest.cc',
+        'function_get_target_outputs_unittest.cc',
         'function_rebase_path_unittest.cc',
         'functions_unittest.cc',
         'header_checker_unittest.cc',
@@ -188,6 +190,7 @@
         'ninja_binary_target_writer_unittest.cc',
         'ninja_copy_target_writer_unittest.cc',
         'ninja_helper_unittest.cc',
+        'ninja_target_writer_unittest.cc',
         'operators_unittest.cc',
         'parse_tree_unittest.cc',
         'parser_unittest.cc',
@@ -202,6 +205,7 @@
         'test_with_scope.cc',
         'test_with_scope.h',
         'tokenizer_unittest.cc',
+        'value_unittest.cc',
         'visibility_unittest.cc',
       ],
       'dependencies': [
diff --git a/tools/gn/loader.cc b/tools/gn/loader.cc
index 2893e23..885670a 100644
--- a/tools/gn/loader.cc
+++ b/tools/gn/loader.cc
@@ -247,6 +247,10 @@
   ScopePerFileProvider per_file_provider(&our_scope, true);
   our_scope.set_source_dir(file_name.GetDir());
 
+  // Targets, etc. generated as part of running this file will end up here.
+  Scope::ItemVector collected_items;
+  our_scope.set_item_collector(&collected_items);
+
   ScopedTrace trace(TraceItem::TRACE_FILE_EXECUTE, file_name.value());
   trace.SetToolchain(settings->toolchain_label());
 
@@ -255,6 +259,10 @@
   if (err.has_error())
     g_scheduler->FailWithError(err);
 
+  // Pass all of the items that were defined off to the builder.
+  for (size_t i = 0; i < collected_items.size(); i++)
+    settings->build_settings()->ItemDefined(collected_items[i]->Pass());
+
   trace.Done();
 
   main_loop_->PostTask(FROM_HERE, base::Bind(&LoaderImpl::DidLoadFile, this));
diff --git a/tools/gn/ninja_action_target_writer.cc b/tools/gn/ninja_action_target_writer.cc
index fef58ac..1b71fce 100644
--- a/tools/gn/ninja_action_target_writer.cc
+++ b/tools/gn/ninja_action_target_writer.cc
@@ -25,7 +25,24 @@
 void NinjaActionTargetWriter::Run() {
   FileTemplate args_template(target_->action_values().args());
   std::string custom_rule_name = WriteRuleDefinition(args_template);
-  std::string implicit_deps = GetSourcesImplicitDeps();
+
+  // Collect our deps to pass as "extra hard dependencies" for input deps. This
+  // will force all of the action's dependencies to be completed before the
+  // action is run. Usually, if an action has a dependency, it will be
+  // operating on the result of that previous step, so we need to be sure to
+  // serialize these.
+  std::vector<const Target*> extra_hard_deps;
+  for (size_t i = 0; i < target_->deps().size(); i++)
+    extra_hard_deps.push_back(target_->deps()[i].ptr);
+
+  // For ACTIONs this is a bit inefficient since it creates an input dep
+  // stamp file even though we're only going to use it once. It would save a
+  // build step to skip this and write the order-only deps directly on the
+  // build rule. This should probably be handled by WriteInputDepsStampAndGetDep
+  // automatically if we supply a count of sources (so it can optimize based on
+  // how many times things would be duplicated).
+  std::string implicit_deps = WriteInputDepsStampAndGetDep(extra_hard_deps);
+  out_ << std::endl;
 
   // Collects all output files for writing below.
   std::vector<OutputFile> output_files;
@@ -54,19 +71,7 @@
       path_output_.WriteFile(out_, output_path);
     }
 
-    out_ << ": " << custom_rule_name << implicit_deps;
-
-    // In the case of running the script once, we allow you to write the input
-    // dependencies in both sources and source_prereqs. source_prereqs are
-    // already in the implicit deps written above, but the sources aren't
-    // (since treating the sources this was is unique to an action).
-    const Target::FileList& sources = target_->sources();
-    for (size_t i = 0; i < sources.size(); i++) {
-      out_ << " ";
-      path_output_.WriteFile(out_, sources[i]);
-    }
-    out_ << std::endl;
-
+    out_ << ": " << custom_rule_name << implicit_deps << std::endl;
     if (target_->action_values().has_depfile()) {
       out_ << "  depfile = ";
       WriteDepfile(SourceFile());
@@ -129,7 +134,6 @@
     out_ << "  restat = 1" << std::endl;
   }
 
-  out_ << std::endl;
   return custom_rule_name;
 }
 
@@ -185,10 +189,22 @@
   out_ << ": "
        << helper_.GetRulePrefix(target_->settings())
        << "stamp";
+
+  // The action stamp depends on all output files from running the action.
   for (size_t i = 0; i < output_files.size(); i++) {
     out_ << " ";
     path_output_.WriteFile(out_, output_files[i]);
   }
+
+  // It also depends on all datadeps. These are needed at runtime and should
+  // be compiled when the action is, but don't need to be done before we run
+  // the action.
+  for (size_t i = 0; i < target_->datadeps().size(); i++) {
+    out_ << " ";
+    path_output_.WriteFile(out_,
+        helper_.GetTargetOutputFile(target_->datadeps()[i].ptr));
+  }
+
   out_ << std::endl;
 }
 
diff --git a/tools/gn/ninja_action_target_writer_unittest.cc b/tools/gn/ninja_action_target_writer_unittest.cc
index 87903e7..7254b48 100644
--- a/tools/gn/ninja_action_target_writer_unittest.cc
+++ b/tools/gn/ninja_action_target_writer_unittest.cc
@@ -119,10 +119,11 @@
         "rule __foo_bar___rule\n"
         "  command = /usr/bin/python ../../foo/script.py\n"
         "  description = ACTION //foo:bar()\n"
-        "  restat = 1"
+        "  restat = 1\n"
+        "build obj/foo/bar.inputdeps.stamp: "
+            "stamp ../../foo/included.txt ../../foo/source.txt\n"
         "\n"
-        "\n"
-        "build foo.out: __foo_bar___rule | ../../foo/included.txt ../../foo/source.txt\n"
+        "build foo.out: __foo_bar___rule | obj/foo/bar.inputdeps.stamp\n"
         "\n"
         "build obj/foo/bar.stamp: stamp foo.out\n";
     std::string out_str = out.str();
@@ -153,8 +154,10 @@
         "  restat = 1\n"
         "  rspfile = __foo_bar___rule.$unique_name.rsp\n"
         "  rspfile_content = C$:/python/python.exe ../../foo/script.py\n"
+        "build obj/foo/bar.inputdeps.stamp: "
+            "stamp ../../foo/included.txt ../../foo/source.txt\n"
         "\n"
-        "build foo.out: __foo_bar___rule | ../../foo/included.txt ../../foo/source.txt\n"
+        "build foo.out: __foo_bar___rule | obj/foo/bar.inputdeps.stamp\n"
         "\n"
         "build obj/foo/bar.stamp: stamp foo.out\n";
     std::string out_str = out.str();
@@ -168,8 +171,20 @@
 TEST(NinjaActionTargetWriter, ForEach) {
   TestWithScope setup;
   setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
+
+  // Some dependencies that the action can depend on. Use actions for these
+  // so they have a nice platform-independent stamp file that can appear in the
+  // output (rather than having to worry about how the current platform names
+  // binaries).
+  Target dep(setup.settings(), Label(SourceDir("//foo/"), "dep"));
+  dep.set_output_type(Target::ACTION);
+  Target datadep(setup.settings(), Label(SourceDir("//foo/"), "datadep"));
+  datadep.set_output_type(Target::ACTION);
+
   Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
   target.set_output_type(Target::ACTION_FOREACH);
+  target.deps().push_back(LabelTargetPair(&dep));
+  target.datadeps().push_back(LabelTargetPair(&datadep));
 
   target.sources().push_back(SourceFile("//foo/input1.txt"));
   target.sources().push_back(SourceFile("//foo/input2.txt"));
@@ -202,17 +217,20 @@
             "\"--out=foo$ bar${source_name_part}.o\"\n"
         "  description = ACTION //foo:bar()\n"
         "  restat = 1\n"
+        "build obj/foo/bar.inputdeps.stamp: "
+            "stamp ../../foo/included.txt obj/foo/dep.stamp\n"
         "\n"
         "build input1.out: __foo_bar___rule ../../foo/input1.txt | "
-            "../../foo/included.txt\n"
+            "obj/foo/bar.inputdeps.stamp\n"
         "  source = ../../foo/input1.txt\n"
         "  source_name_part = input1\n"
         "build input2.out: __foo_bar___rule ../../foo/input2.txt | "
-            "../../foo/included.txt\n"
+            "obj/foo/bar.inputdeps.stamp\n"
         "  source = ../../foo/input2.txt\n"
         "  source_name_part = input2\n"
         "\n"
-        "build obj/foo/bar.stamp: stamp input1.out input2.out\n";
+        "build obj/foo/bar.stamp: "
+            "stamp input1.out input2.out obj/foo/datadep.stamp\n";
 
     std::string out_str = out.str();
 #if defined(OS_WIN)
@@ -244,19 +262,22 @@
         "  rspfile = __foo_bar___rule.$unique_name.rsp\n"
         "  rspfile_content = C$:/python/python.exe ../../foo/script.py -i "
             "${source} \"--out=foo$ bar${source_name_part}.o\"\n"
+        "build obj/foo/bar.inputdeps.stamp: "
+            "stamp ../../foo/included.txt obj/foo/dep.stamp\n"
         "\n"
         "build input1.out: __foo_bar___rule ../../foo/input1.txt | "
-            "../../foo/included.txt\n"
+            "obj/foo/bar.inputdeps.stamp\n"
         "  unique_name = 0\n"
         "  source = ../../foo/input1.txt\n"
         "  source_name_part = input1\n"
         "build input2.out: __foo_bar___rule ../../foo/input2.txt | "
-            "../../foo/included.txt\n"
+            "obj/foo/bar.inputdeps.stamp\n"
         "  unique_name = 1\n"
         "  source = ../../foo/input2.txt\n"
         "  source_name_part = input2\n"
         "\n"
-        "build obj/foo/bar.stamp: stamp input1.out input2.out\n";
+        "build obj/foo/bar.stamp: "
+            "stamp input1.out input2.out obj/foo/datadep.stamp\n";
     std::string out_str = out.str();
 #if defined(OS_WIN)
     std::replace(out_str.begin(), out_str.end(), '\\', '/');
@@ -304,14 +325,15 @@
             "\"--out=foo$ bar${source_name_part}.o\"\n"
         "  description = ACTION //foo:bar()\n"
         "  restat = 1\n"
+        "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/included.txt\n"
         "\n"
         "build gen/input1.d input1.out: __foo_bar___rule ../../foo/input1.txt"
-            " | ../../foo/included.txt\n"
+            " | obj/foo/bar.inputdeps.stamp\n"
         "  source = ../../foo/input1.txt\n"
         "  source_name_part = input1\n"
         "  depfile = gen/input1.d\n"
         "build gen/input2.d input2.out: __foo_bar___rule ../../foo/input2.txt"
-            " | ../../foo/included.txt\n"
+            " | obj/foo/bar.inputdeps.stamp\n"
         "  source = ../../foo/input2.txt\n"
         "  source_name_part = input2\n"
         "  depfile = gen/input2.d\n"
@@ -348,15 +370,16 @@
         "  rspfile = __foo_bar___rule.$unique_name.rsp\n"
         "  rspfile_content = C$:/python/python.exe ../../foo/script.py -i "
             "${source} \"--out=foo$ bar${source_name_part}.o\"\n"
+        "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/included.txt\n"
         "\n"
         "build gen/input1.d input1.out: __foo_bar___rule ../../foo/input1.txt"
-            " | ../../foo/included.txt\n"
+            " | obj/foo/bar.inputdeps.stamp\n"
         "  unique_name = 0\n"
         "  source = ../../foo/input1.txt\n"
         "  source_name_part = input1\n"
         "  depfile = gen/input1.d\n"
         "build gen/input2.d input2.out: __foo_bar___rule ../../foo/input2.txt"
-            " | ../../foo/included.txt\n"
+            " | obj/foo/bar.inputdeps.stamp\n"
         "  unique_name = 1\n"
         "  source = ../../foo/input2.txt\n"
         "  source_name_part = input2\n"
diff --git a/tools/gn/ninja_binary_target_writer.cc b/tools/gn/ninja_binary_target_writer.cc
index 392bc54..1204d4f 100644
--- a/tools/gn/ninja_binary_target_writer.cc
+++ b/tools/gn/ninja_binary_target_writer.cc
@@ -146,7 +146,8 @@
   const Target::FileList& sources = target_->sources();
   object_files->reserve(sources.size());
 
-  std::string implicit_deps = GetSourcesImplicitDeps();
+  std::string implicit_deps =
+      WriteInputDepsStampAndGetDep(std::vector<const Target*>());
 
   for (size_t i = 0; i < sources.size(); i++) {
     const SourceFile& input_file = sources[i];
@@ -154,6 +155,12 @@
     SourceFileType input_file_type = GetSourceFileType(input_file);
     if (input_file_type == SOURCE_UNKNOWN)
       continue;  // Skip unknown file types.
+    if (input_file_type == SOURCE_O) {
+      // Object files just get passed to the output and not compiled.
+      object_files->push_back(helper_.GetOutputFileForSource(
+          target_, input_file, input_file_type));
+      continue;
+    }
     std::string command =
         helper_.GetRuleForSourceType(settings_, input_file_type);
     if (command.empty())
@@ -179,7 +186,7 @@
   // that case?
   OutputFile windows_manifest;
   if (settings_->IsWin()) {
-    windows_manifest.value().assign(helper_.GetTargetOutputDir(target_));
+    windows_manifest = helper_.GetTargetOutputDir(target_);
     windows_manifest.value().append(target_->label().name());
     windows_manifest.value().append(".intermediate.manifest");
     out_ << "manifests = ";
diff --git a/tools/gn/ninja_binary_target_writer_unittest.cc b/tools/gn/ninja_binary_target_writer_unittest.cc
index 94755c6..4f120c2 100644
--- a/tools/gn/ninja_binary_target_writer_unittest.cc
+++ b/tools/gn/ninja_binary_target_writer_unittest.cc
@@ -17,6 +17,10 @@
   target.set_output_type(Target::SOURCE_SET);
   target.sources().push_back(SourceFile("//foo/input1.cc"));
   target.sources().push_back(SourceFile("//foo/input2.cc"));
+  // Also test object files, which should be just passed through to the
+  // dependents to link.
+  target.sources().push_back(SourceFile("//foo/input3.o"));
+  target.sources().push_back(SourceFile("//foo/input4.obj"));
   target.OnResolved();
 
   // Source set itself.
@@ -39,7 +43,8 @@
         "build obj/foo/bar.input1.obj: cxx ../../foo/input1.cc\n"
         "build obj/foo/bar.input2.obj: cxx ../../foo/input2.cc\n"
         "\n"
-        "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.obj obj/foo/bar.input2.obj\n";
+        "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.obj "
+            "obj/foo/bar.input2.obj ../../foo/input3.o ../../foo/input4.obj\n";
     std::string out_str = out.str();
 #if defined(OS_WIN)
     std::replace(out_str.begin(), out_str.end(), '\\', '/');
@@ -74,7 +79,10 @@
         "ldflags = /MANIFEST /ManifestFile:obj/foo/shlib.intermediate."
             "manifest\n"
         "libs =\n"
-        "build shlib.dll shlib.dll.lib: solink obj/foo/bar.input1.obj "
+        // Ordering of the obj files here is arbitrary. Currently they're put
+        // in a set and come out sorted.
+        "build shlib.dll shlib.dll.lib: solink ../../foo/input3.o "
+            "../../foo/input4.obj obj/foo/bar.input1.obj "
             "obj/foo/bar.input2.obj\n"
         "  soname = shlib.dll\n"
         "  lib = shlib.dll\n"
diff --git a/tools/gn/ninja_build_writer.cc b/tools/gn/ninja_build_writer.cc
index c0fc7fc..f903904 100644
--- a/tools/gn/ninja_build_writer.cc
+++ b/tools/gn/ninja_build_writer.cc
@@ -51,7 +51,11 @@
   const CommandLine::SwitchMap& switches = our_cmdline.GetSwitches();
   for (CommandLine::SwitchMap::const_iterator i = switches.begin();
        i != switches.end(); ++i) {
-    if (i->first != "q" && i->first != "root") {
+    // Only write arguments we haven't already written. Always skip "args"
+    // since those will have been written to the file and will be used
+    // implicitly in the future. Keeping --args would mean changes to the file
+    // would be ignored.
+    if (i->first != "q" && i->first != "root" && i->first != "args") {
       std::string escaped_value =
           EscapeString(FilePathToUTF8(i->second), escape_shell, NULL);
       cmdline.AppendSwitchASCII(i->first, escaped_value);
@@ -130,23 +134,6 @@
        << "  generator = 1\n"
        << "  depfile = build.ninja.d\n";
 
-  // Provide a way to force regenerating ninja files if the user is suspicious
-  // something is out-of-date. This will be "ninja refresh".
-  out_ << "\nbuild refresh: gn\n";
-
-  // Provide a way to see what flags are associated with this build:
-  // This will be "ninja show".
-  const CommandLine& our_cmdline = *CommandLine::ForCurrentProcess();
-  std::string args = our_cmdline.GetSwitchValueASCII("args");
-  out_ << "rule echo\n";
-  out_ << "  command = echo $text\n";
-  out_ << "  description = ECHO $desc\n";
-  out_ << "build show: echo\n";
-  out_ << "  desc = build arguments:\n";
-  out_ << "  text = "
-       << (args.empty() ? std::string("No build args, using defaults.") : args)
-       << "\n";
-
   // Input build files. These go in the ".d" file. If we write them as
   // dependencies in the .ninja file itself, ninja will expect the files to
   // exist and will error if they don't. When files are listed in a depfile,
diff --git a/tools/gn/ninja_helper.cc b/tools/gn/ninja_helper.cc
index e5d1ff8..75843ee 100644
--- a/tools/gn/ninja_helper.cc
+++ b/tools/gn/ninja_helper.cc
@@ -5,6 +5,7 @@
 #include "tools/gn/ninja_helper.h"
 
 #include "base/logging.h"
+#include "base/strings/string_util.h"
 #include "tools/gn/filesystem_utils.h"
 #include "tools/gn/string_utils.h"
 #include "tools/gn/target.h"
@@ -34,15 +35,16 @@
   return kObjectDirNoSlash;
 }
 
-std::string NinjaHelper::GetTargetOutputDir(const Target* target) const {
-  return kObjectDirNoSlash + target->label().dir().SourceAbsoluteWithOneSlash();
-}
-
-OutputFile NinjaHelper::GetNinjaFileForTarget(const Target* target) const {
+OutputFile NinjaHelper::GetTargetOutputDir(const Target* target) const {
   OutputFile ret(target->settings()->toolchain_output_subdir());
   ret.value().append(kObjectDirNoSlash);
   AppendStringPiece(&ret.value(),
                     target->label().dir().SourceAbsoluteWithOneSlash());
+  return ret;
+}
+
+OutputFile NinjaHelper::GetNinjaFileForTarget(const Target* target) const {
+  OutputFile ret = GetTargetOutputDir(target);
   ret.value().append(target->label().name());
   ret.value().append(".ninja");
   return ret;
@@ -85,6 +87,33 @@
       name.append("res");
       break;
 
+    // Pass .o/.obj files through unchanged.
+    case SOURCE_O: {
+      // System-absolute file names get preserved (they don't need to be
+      // rebased relative to the build dir).
+      if (source.is_system_absolute())
+        return OutputFile(source.value());
+
+      // Files that are already inside the build dir should not be made
+      // relative to the source tree. Doing so will insert an unnecessary
+      // "../.." into the path which won't match the corresponding target
+      // name in ninja.
+      CHECK(build_settings_->build_dir().is_source_absolute());
+      CHECK(source.is_source_absolute());
+      if (StartsWithASCII(source.value(),
+                          build_settings_->build_dir().value(),
+                          true)) {
+        return OutputFile(
+            source.value().substr(
+                build_settings_->build_dir().value().size()));
+      }
+
+      // Construct the relative location of the file from the build dir.
+      OutputFile ret(build_to_src_no_last_slash());
+      source.SourceAbsoluteWithOneSlash().AppendToString(&ret.value());
+      return ret;
+    }
+
     case SOURCE_H:
     case SOURCE_UNKNOWN:
       NOTREACHED();
@@ -223,5 +252,7 @@
 
   // TODO(brettw) asm files.
 
+  // .obj files have no rules to make them (they're already built) so we return
+  // the enpty string for SOURCE_O.
   return std::string();
 }
diff --git a/tools/gn/ninja_helper.h b/tools/gn/ninja_helper.h
index 84a2c89..69a9564 100644
--- a/tools/gn/ninja_helper.h
+++ b/tools/gn/ninja_helper.h
@@ -28,7 +28,7 @@
   std::string GetTopleveOutputDir() const;
 
   // Ends in a slash.
-  std::string GetTargetOutputDir(const Target* target) const;
+  OutputFile GetTargetOutputDir(const Target* target) const;
 
   // Example: "base/base.ninja". The string version will not be escaped, and
   // will always have slashes for path separators.
diff --git a/tools/gn/ninja_helper_unittest.cc b/tools/gn/ninja_helper_unittest.cc
index 81f3669..3df7a13 100644
--- a/tools/gn/ninja_helper_unittest.cc
+++ b/tools/gn/ninja_helper_unittest.cc
@@ -24,7 +24,7 @@
     settings.set_target_os(Settings::WIN);
 
     // Output going to "out/Debug".
-    build_settings.SetBuildDir(SourceDir("/out/Debug/"));
+    build_settings.SetBuildDir(SourceDir("//out/Debug/"));
 
     // Our source target is in "tools/gn".
     target.set_output_type(Target::EXECUTABLE);
@@ -58,6 +58,32 @@
                                           SOURCE_CC).value());
 }
 
+TEST(NinjaHelper, GetOutputFileForObject) {
+  HelperSetterUpper setup;
+  NinjaHelper helper(&setup.build_settings);
+
+  EXPECT_EQ(OutputFile("../../tools/gn/foo.o").value(),
+            helper.GetOutputFileForSource(&setup.target,
+                                          SourceFile("//tools/gn/foo.o"),
+                                          SOURCE_O).value());
+
+  EXPECT_EQ(OutputFile("../../tools/gn/foo.obj").value(),
+            helper.GetOutputFileForSource(&setup.target,
+                                          SourceFile("//tools/gn/foo.obj"),
+                                          SOURCE_O).value());
+
+  EXPECT_EQ(OutputFile("nested/foo.o").value(),
+            helper.GetOutputFileForSource(
+                &setup.target,
+                SourceFile("//out/Debug/nested/foo.o"),
+                SOURCE_O).value());
+
+  EXPECT_EQ(OutputFile("/abs/rooted/foo.o").value(),
+            helper.GetOutputFileForSource(&setup.target,
+                                          SourceFile("/abs/rooted/foo.o"),
+                                          SOURCE_O).value());
+}
+
 TEST(NinjaHelper, GetTargetOutputFile) {
   HelperSetterUpper setup;
   NinjaHelper helper(&setup.build_settings);
diff --git a/tools/gn/ninja_target_writer.cc b/tools/gn/ninja_target_writer.cc
index 91d0683..a5a6e67 100644
--- a/tools/gn/ninja_target_writer.cc
+++ b/tools/gn/ninja_target_writer.cc
@@ -84,31 +84,66 @@
                   static_cast<int>(contents.size()));
 }
 
-std::string NinjaTargetWriter::GetSourcesImplicitDeps() const {
-  std::ostringstream ret;
-  ret << " |";
+std::string NinjaTargetWriter::WriteInputDepsStampAndGetDep(
+    const std::vector<const Target*>& extra_hard_deps) const {
+  // For an action (where we run a script only once) the sources are the same
+  // as the source prereqs.
+  bool list_sources_as_input_deps = target_->output_type() == Target::ACTION;
+
+  if (extra_hard_deps.empty() &&
+      target_->source_prereqs().empty() &&
+      target_->recursive_hard_deps().empty() &&
+      (!list_sources_as_input_deps || target_->sources().empty()))
+    return std::string();  // No input/hard deps.
+
+  // One potential optimization is if there are few input dependencies (or
+  // potentially few sources that depend on these) it's better to just write
+  // all hard deps on each sources line than have this intermediate stamp. We
+  // do the stamp file because duplicating all the order-only deps for each
+  // source file can really explode the ninja file but this won't be the most
+  // optimal thing in all cases.
+
+  OutputFile input_stamp_file = helper_.GetTargetOutputDir(target_);
+  input_stamp_file.value().append(target_->label().name());
+  input_stamp_file.value().append(".inputdeps.stamp");
+
+  std::ostringstream stamp_file_stream;
+  path_output_.WriteFile(stamp_file_stream, input_stamp_file);
+  std::string stamp_file_string = stamp_file_stream.str();
+
+  out_ << "build " << stamp_file_string << ": stamp";
 
   // Input files are order-only deps.
   const Target::FileList& prereqs = target_->source_prereqs();
-  bool has_files = !prereqs.empty();
   for (size_t i = 0; i < prereqs.size(); i++) {
-    ret << " ";
-    path_output_.WriteFile(ret, prereqs[i]);
+    out_ << " ";
+    path_output_.WriteFile(out_, prereqs[i]);
   }
-
-  // Add on any direct deps marked as "hard".
-  const LabelTargetVector& deps = target_->deps();
-  for (size_t i = 0; i < deps.size(); i++) {
-    if (deps[i].ptr->hard_dep()) {
-      has_files = true;
-      ret << " ";
-      path_output_.WriteFile(ret, helper_.GetTargetOutputFile(deps[i].ptr));
+  if (list_sources_as_input_deps) {
+    const Target::FileList& sources = target_->sources();
+    for (size_t i = 0; i < sources.size(); i++) {
+      out_ << " ";
+      path_output_.WriteFile(out_, sources[i]);
     }
   }
 
-  if (has_files)
-    return ret.str();
-  return std::string();  // No files added.
+  // Add on any hard deps that are direct or indirect dependencies.
+  const std::set<const Target*>& hard_deps = target_->recursive_hard_deps();
+  for (std::set<const Target*>::const_iterator i = hard_deps.begin();
+       i != hard_deps.end(); ++i) {
+    out_ << " ";
+    path_output_.WriteFile(out_, helper_.GetTargetOutputFile(*i));
+  }
+
+  // Extra hard deps passed in.
+  for (size_t i = 0; i < extra_hard_deps.size(); i++) {
+    out_ << " ";
+    path_output_.WriteFile(out_,
+        helper_.GetTargetOutputFile(extra_hard_deps[i]));
+  }
+
+  out_ << "\n";
+  return " | " + stamp_file_string;
 }
 
 FileTemplate NinjaTargetWriter::GetOutputTemplate() const {
diff --git a/tools/gn/ninja_target_writer.h b/tools/gn/ninja_target_writer.h
index 3837868..51e3ba1 100644
--- a/tools/gn/ninja_target_writer.h
+++ b/tools/gn/ninja_target_writer.h
@@ -29,11 +29,14 @@
   virtual void Run() = 0;
 
  protected:
-  // Returns the string to be appended to source rules that encodes the
-  // order-only dependencies for the current target. This will include the
-  // "|" character so can just be appended to the source rules. If there are no
-  // implicit dependencies, returns the empty string.
-  std::string GetSourcesImplicitDeps() const;
+  // Writes to the output stream a stamp rule for input dependencies, and
+  // returns the string to be appended to source rules that encodes the
+  // order-only dependencies for the current target. This will include the "|"
+  // character so can just be appended to the source rules. If there are no
+  // implicit dependencies and no extra target dependencies passed in, returns
+  // the empty string.
+  std::string WriteInputDepsStampAndGetDep(
+      const std::vector<const Target*>& extra_hard_deps) const;
 
   // Returns the FileTemplate constructed from the outputs variable. This is
   // like FileTemplate::GetForTargetOutputs except this additionally trims the
diff --git a/tools/gn/ninja_target_writer_unittest.cc b/tools/gn/ninja_target_writer_unittest.cc
new file mode 100644
index 0000000..058fae8
--- /dev/null
+++ b/tools/gn/ninja_target_writer_unittest.cc
@@ -0,0 +1,95 @@
+// 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.
+
+#include <sstream>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "tools/gn/ninja_target_writer.h"
+#include "tools/gn/test_with_scope.h"
+
+namespace {
+
+class TestingNinjaTargetWriter : public NinjaTargetWriter {
+ public:
+  TestingNinjaTargetWriter(const Target* target,
+                           const Toolchain* toolchain,
+                           std::ostream& out)
+      : NinjaTargetWriter(target, toolchain, out) {
+  }
+
+  virtual void Run() OVERRIDE {}
+
+  // Make this public so the test can call it.
+  std::string WriteInputDepsStampAndGetDep(
+      const std::vector<const Target*>& extra_hard_deps) {
+    return NinjaTargetWriter::WriteInputDepsStampAndGetDep(extra_hard_deps);
+  }
+};
+
+}  // namespace
+
+TEST(NinjaTargetWriter, WriteInputDepsStampAndGetDep) {
+  TestWithScope setup;
+
+  // Make a base target that's a hard dep (action).
+  Target base_target(setup.settings(), Label(SourceDir("//foo/"), "base"));
+  base_target.set_output_type(Target::ACTION);
+
+  // Dependent target that also includes a source prerequisite (should get
+  // included) and a source (should not be included).
+  Target target(setup.settings(), Label(SourceDir("//foo/"), "target"));
+  target.set_output_type(Target::EXECUTABLE);
+  target.source_prereqs().push_back(SourceFile("//foo/input.txt"));
+  target.sources().push_back(SourceFile("//foo/source.txt"));
+  target.deps().push_back(LabelTargetPair(&base_target));
+
+  // Dependent action to test that action sources will be treated the same as
+  // source_prereqs.
+  Target action(setup.settings(), Label(SourceDir("//foo/"), "action"));
+  action.set_output_type(Target::ACTION);
+  action.sources().push_back(SourceFile("//foo/action_source.txt"));
+  action.deps().push_back(LabelTargetPair(&target));
+
+  base_target.OnResolved();
+  target.OnResolved();
+  action.OnResolved();
+
+  // Input deps for the base (should be nothing, it has no hard deps).
+  {
+    std::ostringstream stream;
+    TestingNinjaTargetWriter writer(&base_target, setup.toolchain(), stream);
+    std::string dep =
+        writer.WriteInputDepsStampAndGetDep(std::vector<const Target*>());
+
+    EXPECT_TRUE(dep.empty());
+    EXPECT_TRUE(stream.str().empty());
+  }
+
+  // Input deps for the target (should depend on the base).
+  {
+    std::ostringstream stream;
+    TestingNinjaTargetWriter writer(&target, setup.toolchain(), stream);
+    std::string dep =
+        writer.WriteInputDepsStampAndGetDep(std::vector<const Target*>());
+
+    EXPECT_EQ(" | obj/foo/target.inputdeps.stamp", dep);
+    EXPECT_EQ("build obj/foo/target.inputdeps.stamp: stamp "
+                  "../../foo/input.txt obj/foo/base.stamp\n",
+              stream.str());
+  }
+
+  // Input deps for action which should depend on the base since its a hard dep
+  // that is a (indirect) dependency, as well as the the action source.
+  {
+    std::ostringstream stream;
+    TestingNinjaTargetWriter writer(&action, setup.toolchain(), stream);
+    std::string dep =
+        writer.WriteInputDepsStampAndGetDep(std::vector<const Target*>());
+
+    EXPECT_EQ(" | obj/foo/action.inputdeps.stamp", dep);
+    EXPECT_EQ("build obj/foo/action.inputdeps.stamp: stamp "
+                  "../../foo/action_source.txt obj/foo/base.stamp\n",
+              stream.str());
+  }
+}
diff --git a/tools/gn/operators.cc b/tools/gn/operators.cc
index 30da234..3a815ea 100644
--- a/tools/gn/operators.cc
+++ b/tools/gn/operators.cc
@@ -592,7 +592,11 @@
     return ExecuteAnd(scope, op_node, left, right, err);
 
   Value left_value = GetValueOrFillError(op_node, left, "left", scope, err);
+  if (err->has_error())
+    return Value();
   Value right_value = GetValueOrFillError(op_node, right, "right", scope, err);
+  if (err->has_error())
+    return Value();
 
   // +, -.
   if (op.type() == Token::MINUS)
diff --git a/tools/gn/scope.cc b/tools/gn/scope.cc
index 9315749..b2d8d66 100644
--- a/tools/gn/scope.cc
+++ b/tools/gn/scope.cc
@@ -22,27 +22,29 @@
     : const_containing_(NULL),
       mutable_containing_(NULL),
       settings_(settings),
-      mode_flags_(0) {
+      mode_flags_(0),
+      item_collector_(NULL) {
 }
 
 Scope::Scope(Scope* parent)
     : const_containing_(NULL),
       mutable_containing_(parent),
       settings_(parent->settings()),
-      mode_flags_(0) {
+      mode_flags_(0),
+      item_collector_(NULL) {
 }
 
 Scope::Scope(const Scope* parent)
     : const_containing_(parent),
       mutable_containing_(NULL),
       settings_(parent->settings()),
-      mode_flags_(0) {
+      mode_flags_(0),
+      item_collector_(NULL) {
 }
 
 Scope::~Scope() {
   STLDeleteContainerPairSecondPointers(target_defaults_.begin(),
                                        target_defaults_.end());
-  STLDeleteContainerPairSecondPointers(templates_.begin(), templates_.end());
 }
 
 const Value* Scope::GetValue(const base::StringPiece& ident,
@@ -121,17 +123,17 @@
   return &r.value;
 }
 
-bool Scope::AddTemplate(const std::string& name, scoped_ptr<Template> templ) {
+bool Scope::AddTemplate(const std::string& name, const Template* templ) {
   if (GetTemplate(name))
     return false;
-  templates_[name] = templ.release();
+  templates_[name] = templ;
   return true;
 }
 
 const Template* Scope::GetTemplate(const std::string& name) const {
   TemplateMap::const_iterator found = templates_.find(name);
   if (found != templates_.end())
-    return found->second;
+    return found->second.get();
   if (containing())
     return containing()->GetTemplate(name);
   return NULL;
@@ -285,10 +287,7 @@
     }
 
     // Be careful to delete any pointer we're about to clobber.
-    const Template** dest_template = &dest->templates_[i->first];
-    if (*dest_template)
-      delete *dest_template;
-    *dest_template = i->second->Clone().release();
+    dest->templates_[i->first] = i->second;
   }
 
   return true;
@@ -390,6 +389,14 @@
   return source_dir_;
 }
 
+Scope::ItemVector* Scope::GetItemCollector() {
+  if (item_collector_)
+    return item_collector_;
+  if (mutable_containing())
+    return mutable_containing()->GetItemCollector();
+  return NULL;
+}
+
 void Scope::SetProperty(const void* key, void* value) {
   if (!value) {
     DCHECK(properties_.find(key) != properties_.end());
diff --git a/tools/gn/scope.h b/tools/gn/scope.h
index 82e037f..1b0246d 100644
--- a/tools/gn/scope.h
+++ b/tools/gn/scope.h
@@ -10,7 +10,9 @@
 
 #include "base/basictypes.h"
 #include "base/containers/hash_tables.h"
+#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
 #include "tools/gn/err.h"
 #include "tools/gn/pattern.h"
 #include "tools/gn/source_dir.h"
@@ -18,6 +20,7 @@
 
 class FunctionCallNode;
 class ImportManager;
+class Item;
 class ParseNode;
 class Settings;
 class TargetManager;
@@ -37,6 +40,9 @@
 class Scope {
  public:
   typedef base::hash_map<base::StringPiece, Value> KeyValueMap;
+  // Holds an owning list of scoped_ptrs of Items (since we can't make a vector
+  // of scoped_ptrs).
+  typedef ScopedVector< scoped_ptr<Item> > ItemVector;
 
   // Allows code to provide values for built-in variables. This class will
   // automatically register itself on construction and deregister itself on
@@ -132,7 +138,7 @@
   // AddTemplate will fail and return false if a rule with that name already
   // exists. GetTemplate returns NULL if the rule doesn't exist, and it will
   // check all containing scoped rescursively.
-  bool AddTemplate(const std::string& name, scoped_ptr<Template> templ);
+  bool AddTemplate(const std::string& name, const Template* templ);
   const Template* GetTemplate(const std::string& name) const;
 
   // Marks the given identifier as (un)used in the current scope.
@@ -224,6 +230,26 @@
   const SourceDir& GetSourceDir() const;
   void set_source_dir(const SourceDir& d) { source_dir_ = d; }
 
+  // The item collector is where Items (Targets, Configs, etc.) go that have
+  // been defined. If a scope can generate items, this non-owning pointer will
+  // point to the storage for such items. The creator of this scope will be
+  // responsible for setting up the collector and then dealing with the
+  // collected items once execution of the context is complete.
+  //
+  // The items in a scope are collected as we go and then dispatched at the end
+  // of execution of a scope so that we can query the previously-generated
+  // targets (like getting the outputs).
+  //
+  // This can be null if the current scope can not generate items (like for
+  // imports and such).
+  //
+  // When retrieving the collector, the non-const scopes are recursively
+  // queried. The collector is not copied for closures, etc.
+  void set_item_collector(ItemVector* collector) {
+    item_collector_ = collector;
+  }
+  ItemVector* GetItemCollector();
+
   // Properties are opaque pointers that code can use to set state on a Scope
   // that it can retrieve later.
   //
@@ -280,9 +306,11 @@
   scoped_ptr<PatternList> sources_assignment_filter_;
 
   // Owning pointers, must be deleted.
-  typedef std::map<std::string, const Template*> TemplateMap;
+  typedef std::map<std::string, scoped_refptr<const Template> > TemplateMap;
   TemplateMap templates_;
 
+  ItemVector* item_collector_;
+
   // Opaque pointers. See SetProperty() above.
   typedef std::map<const void*, void*> PropertyMap;
   PropertyMap properties_;
diff --git a/tools/gn/secondary/chrome/BUILD.gn b/tools/gn/secondary/chrome/BUILD.gn
index 1d77368..c0467d8 100644
--- a/tools/gn/secondary/chrome/BUILD.gn
+++ b/tools/gn/secondary/chrome/BUILD.gn
@@ -96,6 +96,8 @@
   sources = [
     "browser/devtools/device/adb/adb_client_socket.cc",
     "browser/devtools/device/adb/adb_client_socket.h",
+    "browser/devtools/device/adb/adb_device_provider.cc",
+    "browser/devtools/device/adb/adb_device_provider.h",
     "browser/devtools/device/android_device_manager.cc",
     "browser/devtools/device/android_device_manager.h",
     "browser/devtools/device/android_web_socket.cc",
@@ -103,12 +105,16 @@
     "browser/devtools/device/devtools_android_bridge.h",
     "browser/devtools/device/port_forwarding_controller.cc",
     "browser/devtools/device/port_forwarding_controller.h",
+    "browser/devtools/device/self_device_provider.cc",
+    "browser/devtools/device/self_device_provider.h",
     "browser/devtools/device/usb/android_rsa.cc",
     "browser/devtools/device/usb/android_rsa.h",
     "browser/devtools/device/usb/android_usb_device.cc",
     "browser/devtools/device/usb/android_usb_device.h",
     "browser/devtools/device/usb/android_usb_socket.cc",
     "browser/devtools/device/usb/android_usb_socket.h",
+    "browser/devtools/device/usb/usb_device_provider.cc",
+    "browser/devtools/device/usb/usb_device_provider.h",
     "browser/devtools/browser_list_tabcontents_provider.cc",
     "browser/devtools/browser_list_tabcontents_provider.h",
     "browser/devtools/devtools_contents_resizing_strategy.cc",
diff --git a/tools/gn/secondary/third_party/libjpeg_turbo/BUILD.gn b/tools/gn/secondary/third_party/libjpeg_turbo/BUILD.gn
new file mode 100644
index 0000000..0d0248b
--- /dev/null
+++ b/tools/gn/secondary/third_party/libjpeg_turbo/BUILD.gn
@@ -0,0 +1,164 @@
+# 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.
+
+# Do not use the targets in this file unless you need a certain libjpeg
+# implementation. Use the meta target //third_party:jpeg instead.
+
+if (cpu_arch == "arm") {
+  import("//build/config/arm.gni")
+}
+
+source_set("simd") {
+  if (cpu_arch == "x86") {
+    sources = [
+      "simd/jsimd_i386.c",
+      "simd/jccolmmx.asm",
+      "simd/jccolss2.asm",
+      "simd/jcgrammx.asm",
+      "simd/jcgrass2.asm",
+      "simd/jcqnt3dn.asm",
+      "simd/jcqntmmx.asm",
+      "simd/jcqnts2f.asm",
+      "simd/jcqnts2i.asm",
+      "simd/jcqntsse.asm",
+      "simd/jcsammmx.asm",
+      "simd/jcsamss2.asm",
+      "simd/jdcolmmx.asm",
+      "simd/jdcolss2.asm",
+      "simd/jdmermmx.asm",
+      "simd/jdmerss2.asm",
+      "simd/jdsammmx.asm",
+      "simd/jdsamss2.asm",
+      "simd/jf3dnflt.asm",
+      "simd/jfmmxfst.asm",
+      "simd/jfmmxint.asm",
+      "simd/jfss2fst.asm",
+      "simd/jfss2int.asm",
+      "simd/jfsseflt.asm",
+      "simd/ji3dnflt.asm",
+      "simd/jimmxfst.asm",
+      "simd/jimmxint.asm",
+      "simd/jimmxred.asm",
+      "simd/jiss2flt.asm",
+      "simd/jiss2fst.asm",
+      "simd/jiss2int.asm",
+      "simd/jiss2red.asm",
+      "simd/jisseflt.asm",
+      "simd/jsimdcpu.asm",
+    ]
+  } else if (cpu_arch == "x64") {
+    sources = [
+      "simd/jsimd_x86_64.c",
+      "simd/jccolss2-64.asm",
+      "simd/jcgrass2-64.asm",
+      "simd/jcqnts2f-64.asm",
+      "simd/jcqnts2i-64.asm",
+      "simd/jcsamss2-64.asm",
+      "simd/jdcolss2-64.asm",
+      "simd/jdmerss2-64.asm",
+      "simd/jdsamss2-64.asm",
+      "simd/jfss2fst-64.asm",
+      "simd/jfss2int-64.asm",
+      "simd/jfsseflt-64.asm",
+      "simd/jiss2flt-64.asm",
+      "simd/jiss2fst-64.asm",
+      "simd/jiss2int-64.asm",
+      "simd/jiss2red-64.asm",
+    ]
+  } else if (cpu_arch == "arm" && arm_version >= 7 &&
+             (arm_use_neon || arm_optionally_use_neon)) {
+    sources = [
+      "simd/jsimd_arm.c",
+      "simd/jsimd_arm_neon.S",
+    ]
+  } else {
+    sources = [ "jsimd_none.c" ]
+  }
+}
+
+config("libjpeg_config") {
+  include_dirs = [ "." ]
+}
+
+source_set("libjpeg") {
+  sources = [
+    "jcapimin.c",
+    "jcapistd.c",
+    "jccoefct.c",
+    "jccolor.c",
+    "jcdctmgr.c",
+    "jchuff.c",
+    "jchuff.h",
+    "jcinit.c",
+    "jcmainct.c",
+    "jcmarker.c",
+    "jcmaster.c",
+    "jcomapi.c",
+    "jconfig.h",
+    "jcparam.c",
+    "jcphuff.c",
+    "jcprepct.c",
+    "jcsample.c",
+    "jdapimin.c",
+    "jdapistd.c",
+    "jdatadst.c",
+    "jdatasrc.c",
+    "jdcoefct.c",
+    "jdcolor.c",
+    "jdct.h",
+    "jddctmgr.c",
+    "jdhuff.c",
+    "jdhuff.h",
+    "jdinput.c",
+    "jdmainct.c",
+    "jdmarker.c",
+    "jdmaster.c",
+    "jdmerge.c",
+    "jdphuff.c",
+    "jdpostct.c",
+    "jdsample.c",
+    "jerror.c",
+    "jerror.h",
+    "jfdctflt.c",
+    "jfdctfst.c",
+    "jfdctint.c",
+    "jidctflt.c",
+    "jidctfst.c",
+    "jidctint.c",
+    "jidctred.c",
+    "jinclude.h",
+    "jmemmgr.c",
+    "jmemnobs.c",
+    "jmemsys.h",
+    "jmorecfg.h",
+    "jpegint.h",
+    "jpeglib.h",
+    "jpeglibmangler.h",
+    "jquant1.c",
+    "jquant2.c",
+    "jutils.c",
+    "jversion.h",
+  ]
+
+  defines = [
+    "WITH_SIMD",
+    "MOTION_JPEG_SUPPORTED",
+    "NO_GETENV",
+  ]
+
+  configs += [ ":libjpeg_config" ]
+
+  direct_dependent_configs = [ ":libjpeg_config" ]
+
+  # MemorySanitizer doesn't support assembly code, so keep it disabled in
+  # MSan builds for now.
+  # TODO: Enable on Linux when .asm files are recognized.
+  if (is_msan || is_linux) {
+    sources += [ "jsimd_none.c" ]
+  } else {
+    deps = [ ":simd" ]
+  }
+
+  # TODO(GYP): Compile the .asm files with YASM as GYP does.
+}
diff --git a/tools/gn/secondary/v8/BUILD.gn b/tools/gn/secondary/v8/BUILD.gn
deleted file mode 100644
index 0704f3c..0000000
--- a/tools/gn/secondary/v8/BUILD.gn
+++ /dev/null
@@ -1,708 +0,0 @@
-# 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.
-
-# These will need to be user-settable to support standalone V8 builds.
-v8_compress_startup_data = "off"
-v8_enable_i18n_support = true
-v8_use_default_platform = false
-
-# Shared configuration for our internal targets.
-config("internal_config") {
-  visibility = ":*"  # Only targets in this file can depend on this.
-
-  include_dirs = [ "src" ]
-
-  if (component_mode == "shared_library") {
-    defines = [
-      "BUILDING_V8_SHARED",
-      "V8_SHARED",
-    ]
-  }
-}
-
-# TODO(jochen) Figure out how to maintain this file without blocking v8 rolls.
-source_set("v8_base") {
-}
-#if (is_android) {
-#  source_set("v8_base") {
-#  }
-#} else {
-#
-#source_set("v8_base") {
-#  sources = [
-#    "src/accessors.cc",
-#    "src/accessors.h",
-#    "src/allocation.cc",
-#    "src/allocation.h",
-#    "src/allocation-site-scopes.cc",
-#    "src/allocation-site-scopes.h",
-#    "src/allocation-tracker.cc",
-#    "src/allocation-tracker.h",
-#    "src/api.cc",
-#    "src/api.h",
-#    "src/arguments.cc",
-#    "src/arguments.h",
-#    "src/assembler.cc",
-#    "src/assembler.h",
-#    "src/assert-scope.h",
-#    "src/assert-scope.cc",
-#    "src/ast.cc",
-#    "src/ast.h",
-#    "src/atomicops.h",
-#    "src/atomicops_internals_x86_gcc.cc",
-#    "src/bignum-dtoa.cc",
-#    "src/bignum-dtoa.h",
-#    "src/bignum.cc",
-#    "src/bignum.h",
-#    "src/bootstrapper.cc",
-#    "src/bootstrapper.h",
-#    "src/builtins.cc",
-#    "src/builtins.h",
-#    "src/bytecodes-irregexp.h",
-#    "src/cached-powers.cc",
-#    "src/cached-powers.h",
-#    "src/char-predicates-inl.h",
-#    "src/char-predicates.h",
-#    "src/checks.cc",
-#    "src/checks.h",
-#    "src/circular-queue-inl.h",
-#    "src/circular-queue.h",
-#    "src/code-stubs.cc",
-#    "src/code-stubs.h",
-#    "src/code-stubs-hydrogen.cc",
-#    "src/code.h",
-#    "src/codegen.cc",
-#    "src/codegen.h",
-#    "src/compilation-cache.cc",
-#    "src/compilation-cache.h",
-#    "src/compiler.cc",
-#    "src/compiler.h",
-#    "src/contexts.cc",
-#    "src/contexts.h",
-#    "src/conversions-inl.h",
-#    "src/conversions.cc",
-#    "src/conversions.h",
-#    "src/counters.cc",
-#    "src/counters.h",
-#    "src/cpu-profiler-inl.h",
-#    "src/cpu-profiler.cc",
-#    "src/cpu-profiler.h",
-#    "src/cpu.cc",
-#    "src/cpu.h",
-#    "src/data-flow.cc",
-#    "src/data-flow.h",
-#    "src/date.cc",
-#    "src/date.h",
-#    "src/dateparser-inl.h",
-#    "src/dateparser.cc",
-#    "src/dateparser.h",
-#    "src/debug-agent.cc",
-#    "src/debug-agent.h",
-#    "src/debug.cc",
-#    "src/debug.h",
-#    "src/deoptimizer.cc",
-#    "src/deoptimizer.h",
-#    "src/disasm.h",
-#    "src/disassembler.cc",
-#    "src/disassembler.h",
-#    "src/diy-fp.cc",
-#    "src/diy-fp.h",
-#    "src/double.h",
-#    "src/dtoa.cc",
-#    "src/dtoa.h",
-#    "src/effects.h",
-#    "src/elements-kind.cc",
-#    "src/elements-kind.h",
-#    "src/elements.cc",
-#    "src/elements.h",
-#    "src/execution.cc",
-#    "src/execution.h",
-#    "src/extensions/externalize-string-extension.cc",
-#    "src/extensions/externalize-string-extension.h",
-#    "src/extensions/free-buffer-extension.cc",
-#    "src/extensions/free-buffer-extension.h",
-#    "src/extensions/gc-extension.cc",
-#    "src/extensions/gc-extension.h",
-#    "src/extensions/statistics-extension.cc",
-#    "src/extensions/statistics-extension.h",
-#    "src/extensions/trigger-failure-extension.cc",
-#    "src/extensions/trigger-failure-extension.h",
-#    "src/factory.cc",
-#    "src/factory.h",
-#    "src/fast-dtoa.cc",
-#    "src/fast-dtoa.h",
-#    "src/feedback-slots.h",
-#    "src/fixed-dtoa.cc",
-#    "src/fixed-dtoa.h",
-#    "src/flag-definitions.h",
-#    "src/flags.cc",
-#    "src/flags.h",
-#    "src/frames-inl.h",
-#    "src/frames.cc",
-#    "src/frames.h",
-#    "src/full-codegen.cc",
-#    "src/full-codegen.h",
-#    "src/func-name-inferrer.cc",
-#    "src/func-name-inferrer.h",
-#    "src/gdb-jit.cc",
-#    "src/gdb-jit.h",
-#    "src/global-handles.cc",
-#    "src/global-handles.h",
-#    "src/globals.h",
-#    "src/handles-inl.h",
-#    "src/handles.cc",
-#    "src/handles.h",
-#    "src/hashmap.h",
-#    "src/heap-inl.h",
-#    "src/heap-profiler.cc",
-#    "src/heap-profiler.h",
-#    "src/heap-snapshot-generator-inl.h",
-#    "src/heap-snapshot-generator.cc",
-#    "src/heap-snapshot-generator.h",
-#    "src/heap.cc",
-#    "src/heap.h",
-#    "src/hydrogen-alias-analysis.h",
-#    "src/hydrogen-bce.cc",
-#    "src/hydrogen-bce.h",
-#    "src/hydrogen-bch.cc",
-#    "src/hydrogen-bch.h",
-#    "src/hydrogen-canonicalize.cc",
-#    "src/hydrogen-canonicalize.h",
-#    "src/hydrogen-check-elimination.cc",
-#    "src/hydrogen-check-elimination.h",
-#    "src/hydrogen-dce.cc",
-#    "src/hydrogen-dce.h",
-#    "src/hydrogen-dehoist.cc",
-#    "src/hydrogen-dehoist.h",
-#    "src/hydrogen-environment-liveness.cc",
-#    "src/hydrogen-environment-liveness.h",
-#    "src/hydrogen-escape-analysis.cc",
-#    "src/hydrogen-escape-analysis.h",
-#    "src/hydrogen-flow-engine.h",
-#    "src/hydrogen-instructions.cc",
-#    "src/hydrogen-instructions.h",
-#    "src/hydrogen.cc",
-#    "src/hydrogen.h",
-#    "src/hydrogen-gvn.cc",
-#    "src/hydrogen-gvn.h",
-#    "src/hydrogen-infer-representation.cc",
-#    "src/hydrogen-infer-representation.h",
-#    "src/hydrogen-infer-types.cc",
-#    "src/hydrogen-infer-types.h",
-#    "src/hydrogen-load-elimination.cc",
-#    "src/hydrogen-load-elimination.h",
-#    "src/hydrogen-mark-deoptimize.cc",
-#    "src/hydrogen-mark-deoptimize.h",
-#    "src/hydrogen-mark-unreachable.cc",
-#    "src/hydrogen-mark-unreachable.h",
-#    "src/hydrogen-osr.cc",
-#    "src/hydrogen-osr.h",
-#    "src/hydrogen-range-analysis.cc",
-#    "src/hydrogen-range-analysis.h",
-#    "src/hydrogen-redundant-phi.cc",
-#    "src/hydrogen-redundant-phi.h",
-#    "src/hydrogen-removable-simulates.cc",
-#    "src/hydrogen-removable-simulates.h",
-#    "src/hydrogen-representation-changes.cc",
-#    "src/hydrogen-representation-changes.h",
-#    "src/hydrogen-sce.cc",
-#    "src/hydrogen-sce.h",
-#    "src/hydrogen-store-elimination.cc",
-#    "src/hydrogen-store-elimination.h",
-#    "src/hydrogen-uint32-analysis.cc",
-#    "src/hydrogen-uint32-analysis.h",
-#    "src/i18n.cc",
-#    "src/i18n.h",
-#    "src/icu_util.cc",
-#    "src/icu_util.h",
-#    "src/ic-inl.h",
-#    "src/ic.cc",
-#    "src/ic.h",
-#    "src/incremental-marking.cc",
-#    "src/incremental-marking.h",
-#    "src/interface.cc",
-#    "src/interface.h",
-#    "src/interpreter-irregexp.cc",
-#    "src/interpreter-irregexp.h",
-#    "src/isolate.cc",
-#    "src/isolate.h",
-#    "src/json-parser.h",
-#    "src/json-stringifier.h",
-#    "src/jsregexp-inl.h",
-#    "src/jsregexp.cc",
-#    "src/jsregexp.h",
-#    "src/lazy-instance.h",
-#    # TODO(jochen): move libplatform/ files to their own target.
-#    "src/libplatform/default-platform.cc",
-#    "src/libplatform/default-platform.h",
-#    "src/libplatform/task-queue.cc",
-#    "src/libplatform/task-queue.h",
-#    "src/libplatform/worker-thread.cc",
-#    "src/libplatform/worker-thread.h",
-#    "src/list-inl.h",
-#    "src/list.h",
-#    "src/lithium-allocator-inl.h",
-#    "src/lithium-allocator.cc",
-#    "src/lithium-allocator.h",
-#    "src/lithium-codegen.cc",
-#    "src/lithium-codegen.h",
-#    "src/lithium.cc",
-#    "src/lithium.h",
-#    "src/liveedit.cc",
-#    "src/liveedit.h",
-#    "src/log-inl.h",
-#    "src/log-utils.cc",
-#    "src/log-utils.h",
-#    "src/log.cc",
-#    "src/log.h",
-#    "src/macro-assembler.h",
-#    "src/mark-compact.cc",
-#    "src/mark-compact.h",
-#    "src/messages.cc",
-#    "src/messages.h",
-#    "src/msan.h",
-#    "src/natives.h",
-#    "src/objects-debug.cc",
-#    "src/objects-inl.h",
-#    "src/objects-printer.cc",
-#    "src/objects-visiting.cc",
-#    "src/objects-visiting.h",
-#    "src/objects.cc",
-#    "src/objects.h",
-#    "src/once.cc",
-#    "src/once.h",
-#    "src/optimizing-compiler-thread.h",
-#    "src/optimizing-compiler-thread.cc",
-#    "src/parser.cc",
-#    "src/parser.h",
-#    "src/platform/elapsed-timer.h",
-#    "src/platform/time.cc",
-#    "src/platform/time.h",
-#    "src/platform.h",
-#    "src/platform/condition-variable.cc",
-#    "src/platform/condition-variable.h",
-#    "src/platform/mutex.cc",
-#    "src/platform/mutex.h",
-#    "src/platform/semaphore.cc",
-#    "src/platform/semaphore.h",
-#    "src/platform/socket.cc",
-#    "src/platform/socket.h",
-#    "src/preparse-data-format.h",
-#    "src/preparse-data.cc",
-#    "src/preparse-data.h",
-#    "src/preparser.cc",
-#    "src/preparser.h",
-#    "src/prettyprinter.cc",
-#    "src/prettyprinter.h",
-#    "src/profile-generator-inl.h",
-#    "src/profile-generator.cc",
-#    "src/profile-generator.h",
-#    "src/property-details.h",
-#    "src/property.cc",
-#    "src/property.h",
-#    "src/regexp-macro-assembler-irregexp-inl.h",
-#    "src/regexp-macro-assembler-irregexp.cc",
-#    "src/regexp-macro-assembler-irregexp.h",
-#    "src/regexp-macro-assembler-tracer.cc",
-#    "src/regexp-macro-assembler-tracer.h",
-#    "src/regexp-macro-assembler.cc",
-#    "src/regexp-macro-assembler.h",
-#    "src/regexp-stack.cc",
-#    "src/regexp-stack.h",
-#    "src/rewriter.cc",
-#    "src/rewriter.h",
-#    "src/runtime-profiler.cc",
-#    "src/runtime-profiler.h",
-#    "src/runtime.cc",
-#    "src/runtime.h",
-#    "src/safepoint-table.cc",
-#    "src/safepoint-table.h",
-#    "src/sampler.cc",
-#    "src/sampler.h",
-#    "src/scanner-character-streams.cc",
-#    "src/scanner-character-streams.h",
-#    "src/scanner.cc",
-#    "src/scanner.h",
-#    "src/scopeinfo.cc",
-#    "src/scopeinfo.h",
-#    "src/scopes.cc",
-#    "src/scopes.h",
-#    "src/serialize.cc",
-#    "src/serialize.h",
-#    "src/small-pointer-list.h",
-#    "src/smart-pointers.h",
-#    "src/snapshot-common.cc",
-#    "src/snapshot.h",
-#    "src/spaces-inl.h",
-#    "src/spaces.cc",
-#    "src/spaces.h",
-#    "src/store-buffer-inl.h",
-#    "src/store-buffer.cc",
-#    "src/store-buffer.h",
-#    "src/string-search.cc",
-#    "src/string-search.h",
-#    "src/string-stream.cc",
-#    "src/string-stream.h",
-#    "src/strtod.cc",
-#    "src/strtod.h",
-#    "src/stub-cache.cc",
-#    "src/stub-cache.h",
-#    "src/sweeper-thread.h",
-#    "src/sweeper-thread.cc",
-#    "src/token.cc",
-#    "src/token.h",
-#    "src/transitions-inl.h",
-#    "src/transitions.cc",
-#    "src/transitions.h",
-#    "src/type-info.cc",
-#    "src/type-info.h",
-#    "src/types-inl.h",
-#    "src/types.cc",
-#    "src/types.h",
-#    "src/typing.cc",
-#    "src/typing.h",
-#    "src/unbound-queue-inl.h",
-#    "src/unbound-queue.h",
-#    "src/unicode-inl.h",
-#    "src/unicode.cc",
-#    "src/unicode.h",
-#    "src/unique.h",
-#    "src/uri.h",
-#    "src/utils-inl.h",
-#    "src/utils.cc",
-#    "src/utils.h",
-#    "src/utils/random-number-generator.cc",
-#    "src/utils/random-number-generator.h",
-#    "src/v8-counters.cc",
-#    "src/v8-counters.h",
-#    "src/v8.cc",
-#    "src/v8.h",
-#    "src/v8checks.h",
-#    "src/v8conversions.cc",
-#    "src/v8conversions.h",
-#    "src/v8globals.h",
-#    "src/v8memory.h",
-#    "src/v8threads.cc",
-#    "src/v8threads.h",
-#    "src/v8utils.cc",
-#    "src/v8utils.h",
-#    "src/variables.cc",
-#    "src/variables.h",
-#    "src/version.cc",
-#    "src/version.h",
-#    "src/vm-state-inl.h",
-#    "src/vm-state.h",
-#    "src/zone-inl.h",
-#    "src/zone.cc",
-#    "src/zone.h",
-#  ]
-#
-#  if (cpu_arch == "x86") {
-#    # TODO(brettw) the GYP file has
-#    #   or v8_target_arch=="mac" or OS=="mac"
-#    # which I don't understand.
-#    sources += [
-#      "src/ia32/assembler-ia32-inl.h",
-#      "src/ia32/assembler-ia32.cc",
-#      "src/ia32/assembler-ia32.h",
-#      "src/ia32/builtins-ia32.cc",
-#      "src/ia32/code-stubs-ia32.cc",
-#      "src/ia32/code-stubs-ia32.h",
-#      "src/ia32/codegen-ia32.cc",
-#      "src/ia32/codegen-ia32.h",
-#      "src/ia32/cpu-ia32.cc",
-#      "src/ia32/debug-ia32.cc",
-#      "src/ia32/deoptimizer-ia32.cc",
-#      "src/ia32/disasm-ia32.cc",
-#      "src/ia32/frames-ia32.cc",
-#      "src/ia32/frames-ia32.h",
-#      "src/ia32/full-codegen-ia32.cc",
-#      "src/ia32/ic-ia32.cc",
-#      "src/ia32/lithium-codegen-ia32.cc",
-#      "src/ia32/lithium-codegen-ia32.h",
-#      "src/ia32/lithium-gap-resolver-ia32.cc",
-#      "src/ia32/lithium-gap-resolver-ia32.h",
-#      "src/ia32/lithium-ia32.cc",
-#      "src/ia32/lithium-ia32.h",
-#      "src/ia32/macro-assembler-ia32.cc",
-#      "src/ia32/macro-assembler-ia32.h",
-#      "src/ia32/regexp-macro-assembler-ia32.cc",
-#      "src/ia32/regexp-macro-assembler-ia32.h",
-#      "src/ia32/stub-cache-ia32.cc",
-#    ]
-#  } else if (cpu_arch == "x64") {
-#    sources += [
-#      "src/x64/assembler-x64-inl.h",
-#      "src/x64/assembler-x64.cc",
-#      "src/x64/assembler-x64.h",
-#      "src/x64/builtins-x64.cc",
-#      "src/x64/code-stubs-x64.cc",
-#      "src/x64/code-stubs-x64.h",
-#      "src/x64/codegen-x64.cc",
-#      "src/x64/codegen-x64.h",
-#      "src/x64/cpu-x64.cc",
-#      "src/x64/debug-x64.cc",
-#      "src/x64/deoptimizer-x64.cc",
-#      "src/x64/disasm-x64.cc",
-#      "src/x64/frames-x64.cc",
-#      "src/x64/frames-x64.h",
-#      "src/x64/full-codegen-x64.cc",
-#      "src/x64/ic-x64.cc",
-#      "src/x64/lithium-codegen-x64.cc",
-#      "src/x64/lithium-codegen-x64.h",
-#      "src/x64/lithium-gap-resolver-x64.cc",
-#      "src/x64/lithium-gap-resolver-x64.h",
-#      "src/x64/lithium-x64.cc",
-#      "src/x64/lithium-x64.h",
-#      "src/x64/macro-assembler-x64.cc",
-#      "src/x64/macro-assembler-x64.h",
-#      "src/x64/regexp-macro-assembler-x64.cc",
-#      "src/x64/regexp-macro-assembler-x64.h",
-#      "src/x64/stub-cache-x64.cc",
-#    ]
-#  } else if (cpu_arch == "arm") {
-#    sources += [
-#      "src/arm/assembler-arm-inl.h",
-#      "src/arm/assembler-arm.cc",
-#      "src/arm/assembler-arm.h",
-#      "src/arm/builtins-arm.cc",
-#      "src/arm/code-stubs-arm.cc",
-#      "src/arm/code-stubs-arm.h",
-#      "src/arm/codegen-arm.cc",
-#      "src/arm/codegen-arm.h",
-#      "src/arm/constants-arm.h",
-#      "src/arm/constants-arm.cc",
-#      "src/arm/cpu-arm.cc",
-#      "src/arm/debug-arm.cc",
-#      "src/arm/deoptimizer-arm.cc",
-#      "src/arm/disasm-arm.cc",
-#      "src/arm/frames-arm.cc",
-#      "src/arm/frames-arm.h",
-#      "src/arm/full-codegen-arm.cc",
-#      "src/arm/ic-arm.cc",
-#      "src/arm/lithium-arm.cc",
-#      "src/arm/lithium-arm.h",
-#      "src/arm/lithium-codegen-arm.cc",
-#      "src/arm/lithium-codegen-arm.h",
-#      "src/arm/lithium-gap-resolver-arm.cc",
-#      "src/arm/lithium-gap-resolver-arm.h",
-#      "src/arm/macro-assembler-arm.cc",
-#      "src/arm/macro-assembler-arm.h",
-#      "src/arm/regexp-macro-assembler-arm.cc",
-#      "src/arm/regexp-macro-assembler-arm.h",
-#      "src/arm/simulator-arm.cc",
-#      "src/arm/stub-cache-arm.cc",
-#    ]
-#  } else if (cpu_arch == "arm64") {
-#    sources += [
-#      "src/arm64/assembler-arm64.cc",
-#      "src/arm64/assembler-arm64.h",
-#      "src/arm64/assembler-arm64-inl.h",
-#      "src/arm64/builtins-arm64.cc",
-#      "src/arm64/codegen-arm64.cc",
-#      "src/arm64/codegen-arm64.h",
-#      "src/arm64/code-stubs-arm64.cc",
-#      "src/arm64/code-stubs-arm64.h",
-#      "src/arm64/constants-arm64.h",
-#      "src/arm64/cpu-arm64.cc",
-#      "src/arm64/cpu-arm64.h",
-#      "src/arm64/debug-arm64.cc",
-#      "src/arm64/decoder-arm64.cc",
-#      "src/arm64/decoder-arm64.h",
-#      "src/arm64/decoder-arm64-inl.h",
-#      "src/arm64/deoptimizer-arm64.cc",
-#      "src/arm64/disasm-arm64.cc",
-#      "src/arm64/disasm-arm64.h",
-#      "src/arm64/frames-arm64.cc",
-#      "src/arm64/frames-arm64.h",
-#      "src/arm64/full-codegen-arm64.cc",
-#      "src/arm64/ic-arm64.cc",
-#      "src/arm64/instructions-arm64.cc",
-#      "src/arm64/instructions-arm64.h",
-#      "src/arm64/instrument-arm64.cc",
-#      "src/arm64/instrument-arm64.h",
-#      "src/arm64/lithium-arm64.cc",
-#      "src/arm64/lithium-arm64.h",
-#      "src/arm64/lithium-codegen-arm64.cc",
-#      "src/arm64/lithium-codegen-arm64.h",
-#      "src/arm64/lithium-gap-resolver-arm64.cc",
-#      "src/arm64/lithium-gap-resolver-arm64.h",
-#      "src/arm64/macro-assembler-arm64.cc",
-#      "src/arm64/macro-assembler-arm64.h",
-#      "src/arm64/macro-assembler-arm64-inl.h",
-#      "src/arm64/regexp-macro-assembler-arm64.cc",
-#      "src/arm64/regexp-macro-assembler-arm64.h",
-#      "src/arm64/simulator-arm64.cc",
-#      "src/arm64/simulator-arm64.h",
-#      "src/arm64/stub-cache-arm64.cc",
-#      "src/arm64/utils-arm64.cc",
-#      "src/arm64/utils-arm64.h",
-#    ]
-#  } else if (cpu_arch == "mipsel") {
-#    sources += [
-#      "src/mips/assembler-mips.cc",
-#      "src/mips/assembler-mips.h",
-#      "src/mips/assembler-mips-inl.h",
-#      "src/mips/builtins-mips.cc",
-#      "src/mips/codegen-mips.cc",
-#      "src/mips/codegen-mips.h",
-#      "src/mips/code-stubs-mips.cc",
-#      "src/mips/code-stubs-mips.h",
-#      "src/mips/constants-mips.cc",
-#      "src/mips/constants-mips.h",
-#      "src/mips/cpu-mips.cc",
-#      "src/mips/debug-mips.cc",
-#      "src/mips/deoptimizer-mips.cc",
-#      "src/mips/disasm-mips.cc",
-#      "src/mips/frames-mips.cc",
-#      "src/mips/frames-mips.h",
-#      "src/mips/full-codegen-mips.cc",
-#      "src/mips/ic-mips.cc",
-#      "src/mips/lithium-codegen-mips.cc",
-#      "src/mips/lithium-codegen-mips.h",
-#      "src/mips/lithium-gap-resolver-mips.cc",
-#      "src/mips/lithium-gap-resolver-mips.h",
-#      "src/mips/lithium-mips.cc",
-#      "src/mips/lithium-mips.h",
-#      "src/mips/macro-assembler-mips.cc",
-#      "src/mips/macro-assembler-mips.h",
-#      "src/mips/regexp-macro-assembler-mips.cc",
-#      "src/mips/regexp-macro-assembler-mips.h",
-#      "src/mips/simulator-mips.cc",
-#      "src/mips/stub-cache-mips.cc",
-#    ]
-#  }
-#
-#  configs += [ ":internal_config" ]
-#
-#  defines = []
-#  deps = []
-#
-#  if (is_posix) {
-#    sources += [
-#      "src/platform-posix.cc"
-#    ]
-#  }
-#
-#  if (is_linux) {
-#    sources += [
-#      "src/platform-linux.cc"
-#    ]
-#
-#    # TODO(brettw)
-#    # 'conditions': [
-#    #  ['v8_compress_startup_data=="bz2"', {
-#    #    'libraries': [
-#    #      '-lbz2',
-#    #    ]
-#    #   }],
-#    # ],
-#
-#    libs = [ "rt" ]
-#  } else if (is_android) {
-#    # TODO(brettW) OS=="android" condition from tools/gyp/v8.gyp
-#  } else if (is_mac) {
-#    sources += [ "src/platform-macoscc" ]
-#  } else if (is_win) {
-#    sources += [
-#      "src/platform-win32.cc",
-#      "src/win32-math.cc",
-#      "src/win32-math.h",
-#    ]
-#
-#    defines += [ "_CRT_RAND_S" ]  # for rand_s()
-#
-#    libs = [ "winmm.lib", "ws2_32.lib" ]
-#  }
-#
-#
-#  if (v8_enable_i18n_support) {
-#    deps += [ "//third_party/icu" ]
-#    if (is_win) {
-#      deps += [ "//third_party/icu:icudata" ]
-#    }
-#  } else {
-#    sources -= [
-#      "src/i18n.cc",
-#      "src/i18n.h",
-#    ]
-#  }
-#
-#  # TODO(brettw) other conditions from v8.gyp
-#  # TODO(brettw) icu_use_data_file_flag
-#}
-#
-#action("js2c") {
-#  script = "tools/js2c.py"
-#
-#  # The script depends on this other script, this rule causes a rebuild if it
-#  # changes.
-#  source_prereqs = [ "tools/jsmin.py" ]
-#
-#  sources = [
-#    "src/runtime.js",
-#    "src/v8natives.js",
-#    "src/array.js",
-#    "src/string.js",
-#    "src/uri.js",
-#    "src/math.js",
-#    "src/messages.js",
-#    "src/apinatives.js",
-#    "src/debug-debugger.js",
-#    "src/mirror-debugger.js",
-#    "src/liveedit-debugger.js",
-#    "src/date.js",
-#    "src/json.js",
-#    "src/regexp.js",
-#    "src/arraybuffer.js",
-#    "src/typedarray.js",
-#    "src/object-observe.js",
-#    "src/macros.py",
-#  ]
-#
-#  outputs = [
-#    "$target_gen_dir/libraries.cc"
-#  ]
-#
-#  if (v8_enable_i18n_support) {
-#    sources += [ "src/i18n.js" ]
-#  }
-#
-#  args =
-#    rebase_path(outputs, root_build_dir) +
-#    [ "CORE", v8_compress_startup_data ] + 
-#    rebase_path(sources, root_build_dir)
-#}
-#
-#source_set("v8_nosnapshot") {
-#  visibility = ":*"  # Only targets in this file can depend on this.
-#
-#  sources = [
-#
-#  ]
-#
-#  configs += [ ":internal_config" ]
-#}
-#
-# TODO finish this, currently has linker errors.
-#executable("mksnapshot") {
-#  visibility = ":*"  # Only targets in this file can depend on this.
-#
-#  sources = [
-#    "src/mksnapshot.cc",
-#  ]
-#
-#  configs += [ ":internal_config" ]
-#
-#  deps = [
-#    ":v8_base",
-#    ":v8_nosnapshot",
-#  ]
-#
-#  if (v8_compress_startup_data == "bz2") {
-#    libs = [ "bz2" ]
-#  }
-#}
-#
-#}  # end Android commenting-out.
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc
index d956c0f..a3f0dcb 100644
--- a/tools/gn/setup.cc
+++ b/tools/gn/setup.cc
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 
 #include <algorithm>
+#include <sstream>
 
 #include "base/bind.h"
 #include "base/command_line.h"
@@ -133,6 +134,8 @@
 
 // CommonSetup -----------------------------------------------------------------
 
+const char CommonSetup::kBuildArgFileName[] = "args.gn";
+
 CommonSetup::CommonSetup()
     : build_settings_(),
       loader_(new LoaderImpl(&build_settings_)),
@@ -215,7 +218,8 @@
 Setup::Setup()
     : CommonSetup(),
       empty_settings_(&empty_build_settings_, std::string()),
-      dotfile_scope_(&empty_settings_) {
+      dotfile_scope_(&empty_settings_),
+      fill_arguments_(true) {
   empty_settings_.set_toolchain_label(Label());
   build_settings_.set_item_defined_callback(
       base::Bind(&ItemDefinedCallback, scheduler_.main_loop(), builder_));
@@ -236,8 +240,8 @@
       cmdline->HasSwitch(kTracelogSwitch))
     EnableTracing();
 
-  if (!FillArguments(*cmdline))
-    return false;
+  ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "DoSetup");
+
   if (!FillSourceDir(*cmdline))
     return false;
   if (!RunConfigFile())
@@ -246,6 +250,10 @@
     return false;
   if (!FillBuildDir(build_dir))  // Must be after FillSourceDir to resolve.
     return false;
+  if (fill_arguments_) {
+    if (!FillArguments(*cmdline))
+      return false;
+  }
   FillPythonPath();
 
   return true;
@@ -262,14 +270,59 @@
   return &scheduler_;
 }
 
-bool Setup::FillArguments(const CommandLine& cmdline) {
-  std::string args = cmdline.GetSwitchValueASCII(kSwitchArgs);
-  if (args.empty())
-    return true;  // Nothing to set.
+SourceFile Setup::GetBuildArgFile() const {
+  return SourceFile(build_settings_.build_dir().value() + kBuildArgFileName);
+}
 
+bool Setup::FillArguments(const CommandLine& cmdline) {
+  // Add a dependency on the build arguments file. If this changes, we want
+  // to re-generated the build.
+  g_scheduler->AddGenDependency(build_settings_.GetFullPath(GetBuildArgFile()));
+
+  // Use the args on the command line if specified, and save them. Do this even
+  // if the list is empty (this means clear any defaults).
+  if (cmdline.HasSwitch(kSwitchArgs)) {
+    if (!FillArgsFromCommandLine(cmdline.GetSwitchValueASCII(kSwitchArgs)))
+      return false;
+    SaveArgsToFile();
+    return true;
+  }
+
+  // No command line args given, use the arguments from the build dir (if any).
+  return FillArgsFromFile();
+}
+
+bool Setup::FillArgsFromCommandLine(const std::string& args) {
   args_input_file_.reset(new InputFile(SourceFile()));
   args_input_file_->SetContents(args);
-  args_input_file_->set_friendly_name("the command-line \"--args\" settings");
+  args_input_file_->set_friendly_name("the command-line \"--args\"");
+  return FillArgsFromArgsInputFile();
+}
+
+bool Setup::FillArgsFromFile() {
+  ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "Load args file");
+
+  SourceFile build_arg_source_file = GetBuildArgFile();
+  base::FilePath build_arg_file =
+      build_settings_.GetFullPath(build_arg_source_file);
+
+  std::string contents;
+  if (!base::ReadFileToString(build_arg_file, &contents))
+    return true;  // File doesn't exist, continue with default args.
+  if (contents.empty())
+    return true;  // Empty file, do nothing.
+
+  args_input_file_.reset(new InputFile(build_arg_source_file));
+  args_input_file_->SetContents(contents);
+  args_input_file_->set_friendly_name(
+      "build arg file (use \"gn args <out_dir>\" to edit)");
+
+  setup_trace.Done();  // Only want to count the load as part of the trace.
+  return FillArgsFromArgsInputFile();
+}
+
+bool Setup::FillArgsFromArgsInputFile() {
+  ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "Parse args");
 
   Err err;
   args_tokens_ = Tokenizer::Tokenize(args_input_file_.get(), &err);
@@ -298,6 +351,42 @@
   return true;
 }
 
+bool Setup::SaveArgsToFile() {
+  ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "Save args file");
+
+  Scope::KeyValueMap args = build_settings_.build_args().GetAllOverrides();
+
+  std::ostringstream stream;
+  for (Scope::KeyValueMap::const_iterator i = args.begin();
+       i != args.end(); ++i) {
+    stream << i->first.as_string() << " = " << i->second.ToString(true);
+    stream << std::endl;
+  }
+
+  // For the first run, the build output dir might not be created yet, so do
+  // that so we can write a file into it. Ignore errors, we'll catch the error
+  // when we try to write a file to it below.
+  base::FilePath build_arg_file =
+      build_settings_.GetFullPath(GetBuildArgFile());
+  base::CreateDirectory(build_arg_file.DirName());
+
+  std::string contents = stream.str();
+#if defined(OS_WIN)
+  // Use Windows lineendings for this file since it will often open in
+  // Notepad which can't handle Unix ones.
+  ReplaceSubstringsAfterOffset(&contents, 0, "\n", "\r\n");
+#endif
+  if (base::WriteFile(build_arg_file, contents.c_str(),
+      static_cast<int>(contents.size())) == -1) {
+    Err(Location(), "Args file could not be written.",
+      "The file is \"" + FilePathToUTF8(build_arg_file) +
+        "\"").PrintToStdout();
+    return false;
+  }
+
+  return true;
+}
+
 bool Setup::FillSourceDir(const CommandLine& cmdline) {
   // Find the .gn file.
   base::FilePath root_path;
@@ -369,6 +458,8 @@
 }
 
 void Setup::FillPythonPath() {
+  // Trace this since it tends to be a bit slow on Windows.
+  ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "Fill Python Path");
 #if defined(OS_WIN)
   // Find Python on the path so we can use the absolute path in the build.
   const base::char16 kGetPython[] =
diff --git a/tools/gn/setup.h b/tools/gn/setup.h
index eb9d37b..0cd0a79 100644
--- a/tools/gn/setup.h
+++ b/tools/gn/setup.h
@@ -58,6 +58,10 @@
   Builder* builder() { return builder_.get(); }
   LoaderImpl* loader() { return loader_.get(); }
 
+  // Name of the file in the root build directory that contains the build
+  // arguements.
+  static const char kBuildArgFileName[];
+
  protected:
   CommonSetup();
   CommonSetup(const CommonSetup& other);
@@ -105,10 +109,31 @@
 
   virtual Scheduler* GetScheduler() OVERRIDE;
 
+  // Returns the file used to store the build arguments. Note that the path
+  // might not exist.
+  SourceFile GetBuildArgFile() const;
+
+  // Sets whether the build arguments should be filled during setup from the
+  // command line/build argument file. This will be true by default. The use
+  // case for setting it to false is when editing build arguments, we don't
+  // want to rely on them being valid.
+  void set_fill_arguments(bool fa) { fill_arguments_ = fa; }
+
  private:
   // Fills build arguments. Returns true on success.
   bool FillArguments(const base::CommandLine& cmdline);
 
+  // Fills the build arguments from the command line or from the build arg file.
+  bool FillArgsFromCommandLine(const std::string& args);
+  bool FillArgsFromFile();
+
+  // Given an already-loaded args_input_file_, parses and saves the resulting
+  // arguments. Backend for the different FillArgs variants.
+  bool FillArgsFromArgsInputFile();
+
+  // Writes the build arguments to the build arg file.
+  bool SaveArgsToFile();
+
   // Fills the root directory into the settings. Returns true on success.
   bool FillSourceDir(const base::CommandLine& cmdline);
 
@@ -140,6 +165,10 @@
   std::vector<Token> dotfile_tokens_;
   scoped_ptr<ParseNode> dotfile_root_;
 
+  // Set to true when we should populate the build arguments from the command
+  // line or build argument file. See setter above.
+  bool fill_arguments_;
+
   // State for invoking the command line args. We specifically want to keep
   // this around for the entire run so that Values can blame to the command
   // line when we issue errors about them.
diff --git a/tools/gn/target.cc b/tools/gn/target.cc
index 259fcf5..b6845d0 100644
--- a/tools/gn/target.cc
+++ b/tools/gn/target.cc
@@ -148,6 +148,7 @@
     PullDependentTargetInfo(&unique_configs);
   }
   PullForwardedDependentConfigs();
+  PullRecursiveHardDeps();
 }
 
 bool Target::IsLinkable() const {
@@ -204,3 +205,13 @@
         from_target->direct_dependent_configs().end());
   }
 }
+
+void Target::PullRecursiveHardDeps() {
+  for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) {
+    const Target* dep = deps_[dep_i].ptr;
+    if (dep->hard_dep())
+      recursive_hard_deps_.insert(dep);
+    recursive_hard_deps_.insert(dep->recursive_hard_deps().begin(),
+                                dep->recursive_hard_deps().end());
+  }
+}
diff --git a/tools/gn/target.h b/tools/gn/target.h
index 6f3965b..3205114 100644
--- a/tools/gn/target.h
+++ b/tools/gn/target.h
@@ -87,9 +87,13 @@
   const FileList& data() const { return data_; }
   FileList& data() { return data_; }
 
-  // Targets depending on this one should have an order dependency.
-  bool hard_dep() const { return hard_dep_; }
-  void set_hard_dep(bool hd) { hard_dep_ = hd; }
+  // Returns true if targets depending on this one should have an order
+  // dependency.
+  bool hard_dep() const {
+    return output_type_ == ACTION ||
+           output_type_ == ACTION_FOREACH ||
+           output_type_ == COPY_FILES;
+  }
 
   // Linked dependencies.
   const LabelTargetVector& deps() const { return deps_; }
@@ -145,13 +149,19 @@
   const OrderedSet<SourceDir>& all_lib_dirs() const { return all_lib_dirs_; }
   const OrderedSet<std::string>& all_libs() const { return all_libs_; }
 
+  const std::set<const Target*>& recursive_hard_deps() const {
+    return recursive_hard_deps_;
+  }
+
  private:
-  // Pulls necessary information from dependents to this one when all
+  // Pulls necessary information from dependencies to this one when all
   // dependencies have been resolved.
   void PullDependentTargetInfo(std::set<const Config*>* unique_configs);
 
-  // Pulls dependent configs that need forwarding.
+  // These each pull specific things from dependencies to this one when all
+  // deps have been resolved.
   void PullForwardedDependentConfigs();
+  void PullRecursiveHardDeps();
 
   OutputType output_type_;
   std::string output_name_;
@@ -196,6 +206,10 @@
   OrderedSet<SourceDir> all_lib_dirs_;
   OrderedSet<std::string> all_libs_;
 
+  // All hard deps from this target and all dependencies. Filled in when this
+  // target is marked resolved. This will not include the current target.
+  std::set<const Target*> recursive_hard_deps_;
+
   ConfigValues config_values_;  // Used for all binary targets.
   ActionValues action_values_;  // Used for action[_foreach] targets.
 
diff --git a/tools/gn/target_generator.cc b/tools/gn/target_generator.cc
index 570e1f8..cf6bc1f 100644
--- a/tools/gn/target_generator.cc
+++ b/tools/gn/target_generator.cc
@@ -117,8 +117,16 @@
                "I am very confused.");
   }
 
-  if (!err->has_error())
-    scope->settings()->build_settings()->ItemDefined(target.PassAs<Item>());
+  if (err->has_error())
+    return;
+
+  // Save this target for the file.
+  Scope::ItemVector* collector = scope->GetItemCollector();
+  if (!collector) {
+    *err = Err(function_call, "Can't define a target in this context.");
+    return;
+  }
+  collector->push_back(new scoped_ptr<Item>(target.PassAs<Item>()));
 }
 
 const BuildSettings* TargetGenerator::GetBuildSettings() const {
@@ -201,16 +209,13 @@
   if (err_->has_error())
     return;
 
-  FillHardDep();
-}
-
-void TargetGenerator::FillHardDep() {
-  const Value* hard_dep_value = scope_->GetValue(variables::kHardDep, true);
-  if (!hard_dep_value)
-    return;
-  if (!hard_dep_value->VerifyTypeIs(Value::BOOLEAN, err_))
-    return;
-  target_->set_hard_dep(hard_dep_value->boolean_value());
+  // Mark the "hard_dep" variable as used. This was previously part of GN but
+  // is now unused, and we don't want to throw errors for build files setting
+  // it while the new binary is being pushed.
+  // TODO(brettw) remove this code when all hard_deps are removed.
+  const char kHardDep[] = "hard_dep";
+  if (scope_->IsSetButUnused(kHardDep))
+    scope_->MarkUsed(kHardDep);
 }
 
 void TargetGenerator::FillOutputs() {
diff --git a/tools/gn/target_generator.h b/tools/gn/target_generator.h
index 42ad6e7..967c268 100644
--- a/tools/gn/target_generator.h
+++ b/tools/gn/target_generator.h
@@ -63,7 +63,6 @@
   void FillDependentConfigs();  // Includes all types of dependent configs.
   void FillData();
   void FillDependencies();  // Includes data dependencies.
-  void FillHardDep();
 
   // Reads configs/deps from the given var name, and uses the given setting on
   // the target to save them.
diff --git a/tools/gn/template.cc b/tools/gn/template.cc
index bf4eb61..29a6b09 100644
--- a/tools/gn/template.cc
+++ b/tools/gn/template.cc
@@ -24,12 +24,6 @@
 Template::~Template() {
 }
 
-scoped_ptr<Template> Template::Clone() const {
-  // We can make a new closure from our closure to copy it.
-  return scoped_ptr<Template>(
-      new Template(closure_->MakeClosure(), definition_));
-}
-
 Value Template::Invoke(Scope* scope,
                        const FunctionCallNode* invocation,
                        const std::vector<Value>& args,
@@ -62,6 +56,9 @@
 
   ScopePerFileProvider per_file_provider(&template_scope, true);
 
+  // Targets defined in the template go in the collector for the invoking file.
+  template_scope.set_item_collector(scope->GetItemCollector());
+
   // We jump through some hoops to avoid copying the invocation scope when
   // setting it in the template scope (since the invocation scope may have
   // large lists of source files in it and could be expensive to copy).
diff --git a/tools/gn/template.h b/tools/gn/template.h
index 0176862..0b123e0 100644
--- a/tools/gn/template.h
+++ b/tools/gn/template.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 
 class BlockNode;
@@ -17,7 +18,14 @@
 class Scope;
 class Value;
 
-class Template {
+// Represents the information associated with a template() call in GN, which
+// includes a closure and the code to run when the template is invoked.
+//
+// This class is immutable so we can reference it from multiple threads without
+// locking. Normally, this will be assocated with a .gni file and then a
+// reference will be taken by each .gn file that imports it. These files might
+// execute the template in parallel.
+class Template : public base::RefCountedThreadSafe<Template> {
  public:
   // Makes a new closure based on the given scope.
   Template(const Scope* scope, const FunctionCallNode* def);
@@ -25,11 +33,6 @@
   // Takes ownership of a previously-constructed closure.
   Template(scoped_ptr<Scope> closure, const FunctionCallNode* def);
 
-  ~Template();
-
-  // Makes a copy of this template.
-  scoped_ptr<Template> Clone() const;
-
   // Invoke the template. The values correspond to the state of the code
   // invoking the template.
   Value Invoke(Scope* scope,
@@ -42,12 +45,13 @@
   LocationRange GetDefinitionRange() const;
 
  private:
+  friend class base::RefCountedThreadSafe<Template>;
+
   Template();
+  ~Template();
 
   scoped_ptr<Scope> closure_;
   const FunctionCallNode* definition_;
-
-  DISALLOW_COPY_AND_ASSIGN(Template);
 };
 
 #endif  // TOOLS_GN_TEMPLATE_H_
diff --git a/tools/gn/template_unittest.cc b/tools/gn/template_unittest.cc
index 13ec848..905dc7b 100644
--- a/tools/gn/template_unittest.cc
+++ b/tools/gn/template_unittest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/strings/string_number_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "tools/gn/test_with_scope.h"
 
@@ -73,3 +74,20 @@
   input.parsed()->Execute(setup.scope(), &err);
   EXPECT_TRUE(err.has_error());
 }
+
+// Previous versions of the template implementation would copy templates by
+// value when it makes a closure. Doing a sequence of them means that every new
+// one copies all previous ones, which gives a significant blow-up in memory.
+// If this test doesn't crash with out-of-memory, it passed.
+TEST(Template, MemoryBlowUp) {
+  TestWithScope setup;
+  std::string code;
+  for (int i = 0; i < 100; i++)
+    code += "template(\"test" + base::IntToString(i) + "\") {}\n";
+
+  TestParseInput input(code);
+
+  Err err;
+  input.parsed()->Execute(setup.scope(), &err);
+  ASSERT_FALSE(input.has_error());
+}
diff --git a/tools/gn/trace.cc b/tools/gn/trace.cc
index acd735d..4dfb6ca 100644
--- a/tools/gn/trace.cc
+++ b/tools/gn/trace.cc
@@ -167,8 +167,8 @@
 }
 
 void EnableTracing() {
-  CHECK(!trace_log);
-  trace_log = new TraceLog;
+  if (!trace_log)
+    trace_log = new TraceLog;
 }
 
 void AddTrace(TraceItem* item) {
@@ -204,6 +204,7 @@
       case TraceItem::TRACE_CHECK_HEADER:
         headers_checked++;
         break;
+      case TraceItem::TRACE_SETUP:
       case TraceItem::TRACE_FILE_LOAD:
       case TraceItem::TRACE_FILE_WRITE:
       case TraceItem::TRACE_DEFINE_TARGET:
@@ -265,6 +266,9 @@
 
     out << ",\"cat\":";
     switch (item.type()) {
+      case TraceItem::TRACE_SETUP:
+        out << "\"setup\"";
+        break;
       case TraceItem::TRACE_FILE_LOAD:
         out << "\"load\"";
         break;
diff --git a/tools/gn/trace.h b/tools/gn/trace.h
index 2063be8..a1be63a 100644
--- a/tools/gn/trace.h
+++ b/tools/gn/trace.h
@@ -19,6 +19,7 @@
 class TraceItem {
  public:
   enum Type {
+    TRACE_SETUP,
     TRACE_FILE_LOAD,
     TRACE_FILE_PARSE,
     TRACE_FILE_EXECUTE,
diff --git a/tools/gn/value.cc b/tools/gn/value.cc
index 1fb7155..3632ddf 100644
--- a/tools/gn/value.cc
+++ b/tools/gn/value.cc
@@ -5,6 +5,7 @@
 #include "tools/gn/value.h"
 
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
 #include "tools/gn/scope.h"
 
 Value::Value()
@@ -130,8 +131,17 @@
     case INTEGER:
       return base::Int64ToString(int_value_);
     case STRING:
-      if (quote_string)
-        return "\"" + string_value_ + "\"";
+      if (quote_string) {
+        std::string escaped = string_value_;
+        // First escape all special uses of a backslash.
+        ReplaceSubstringsAfterOffset(&escaped, 0, "\\$", "\\\\$");
+        ReplaceSubstringsAfterOffset(&escaped, 0, "\\\"", "\\\\\"");
+
+        // Now escape special chars.
+        ReplaceSubstringsAfterOffset(&escaped, 0, "$", "\\$");
+        ReplaceSubstringsAfterOffset(&escaped, 0, "\"", "\\\"");
+        return "\"" + escaped + "\"";
+      }
       return string_value_;
     case LIST: {
       std::string result = "[";
diff --git a/tools/gn/value.h b/tools/gn/value.h
index e6a9813..87a2941 100644
--- a/tools/gn/value.h
+++ b/tools/gn/value.h
@@ -106,7 +106,8 @@
   void SetScopeValue(scoped_ptr<Scope> scope);
 
   // Converts the given value to a string. Returns true if strings should be
-  // quoted or the ToString of a string should be the string itself.
+  // quoted or the ToString of a string should be the string itself. If the
+  // string is quoted, it will also enable escaping.
   std::string ToString(bool quote_strings) const;
 
   // Verifies that the value is of the given type. If it isn't, returns
diff --git a/tools/gn/value_unittest.cc b/tools/gn/value_unittest.cc
new file mode 100644
index 0000000..c7d4948
--- /dev/null
+++ b/tools/gn/value_unittest.cc
@@ -0,0 +1,29 @@
+// 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.
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "tools/gn/value.h"
+
+TEST(Value, ToString) {
+  Value strval(NULL, "hi\" $me\\you\\$\\\"");
+  EXPECT_EQ("hi\" $me\\you\\$\\\"", strval.ToString(false));
+  EXPECT_EQ("\"hi\\\" \\$me\\you\\\\\\$\\\\\\\"\"", strval.ToString(true));
+
+  // Test lists, bools, and ints.
+  Value listval(NULL, Value::LIST);
+  listval.list_value().push_back(Value(NULL, "hi\"me"));
+  listval.list_value().push_back(Value(NULL, true));
+  listval.list_value().push_back(Value(NULL, false));
+  listval.list_value().push_back(Value(NULL, static_cast<int64>(42)));
+  // Printing lists always causes embedded strings to be quoted (ignoring the
+  // quote flag), or else they wouldn't make much sense.
+  EXPECT_EQ("[\"hi\\\"me\", true, false, 42]", listval.ToString(false));
+  EXPECT_EQ("[\"hi\\\"me\", true, false, 42]", listval.ToString(true));
+
+  // Some weird types, we may want to enhance or change printing of these, but
+  // here we test the current behavior.
+  EXPECT_EQ("<void>", Value().ToString(false));
+  EXPECT_EQ("<scope>", Value(NULL, Value::SCOPE).ToString(false));
+}
+
diff --git a/tools/gn/variables.cc b/tools/gn/variables.cc
index 344a9d9..528e6ae 100644
--- a/tools/gn/variables.cc
+++ b/tools/gn/variables.cc
@@ -529,42 +529,6 @@
     "      forward_dependent_configs_from = deps\n"
     "    }\n";
 
-const char kHardDep[] = "hard_dep";
-const char kHardDep_HelpShort[] =
-    "hard_dep: [boolean] Indicates a target should be built before dependees.";
-const char kHardDep_Help[] =
-    "hard_dep: Indicates a target should be built before dependees.\n"
-    "\n"
-    "  Ninja's default is to assume that targets can be compiled\n"
-    "  independently. This breaks down for generated files that are included\n"
-    "  in other targets because Ninja doesn't know to run the generator\n"
-    "  before compiling the source file.\n"
-    "\n"
-    "  Setting \"hard_dep\" to true on a target means that no sources in\n"
-    "  targets depending directly on this one will be compiled until this\n"
-    "  target is complete. It will introduce a Ninja implicit dependency\n"
-    "  from those sources to this target. This flag is not transitive so\n"
-    "  it will only affect direct dependents, which will cause problems if\n"
-    "  a direct dependent uses this generated file in a public header that a\n"
-    "  third target consumes. Try not to do this.\n"
-    "\n"
-    "  See also \"gn help source_prereqs\" which allows you to specify the\n"
-    "  exact generated file dependency on the target consuming it.\n"
-    "\n"
-    "Example:\n"
-    "  executable(\"foo\") {\n"
-    "    # myresource will be run before any of the sources in this target\n"
-    "    # are compiled.\n"
-    "    deps = [ \":myresource\" ]\n"
-    "    ...\n"
-    "  }\n"
-    "\n"
-    "  action(\"myresource\") {\n"
-    "    hard_dep = true\n"
-    "    script = \"my_generator.py\"\n"
-    "    outputs = \"$target_gen_dir/myresource.h\"\n"
-    "  }\n";
-
 const char kIncludeDirs[] = "include_dirs";
 const char kIncludeDirs_HelpShort[] =
     "include_dirs: [directory list] Additional include directories.";
@@ -781,9 +745,7 @@
     "  dependencies your script may have.\n"
     "\n"
     "  See also \"gn help data\" and \"gn help datadeps\" (which declare\n"
-    "  run-time rather than compile-time dependencies), and\n"
-    "  \"gn help hard_dep\" which allows you to declare the source dependency\n"
-    "  on the target generating a file rather than the target consuming it.\n"
+    "  run-time rather than compile-time dependencies).\n"
     "\n"
     "Examples:\n"
     "  executable(\"foo\") {\n"
@@ -923,7 +885,6 @@
     INSERT_VARIABLE(Deps)
     INSERT_VARIABLE(DirectDependentConfigs)
     INSERT_VARIABLE(ForwardDependentConfigsFrom)
-    INSERT_VARIABLE(HardDep)
     INSERT_VARIABLE(IncludeDirs)
     INSERT_VARIABLE(Ldflags)
     INSERT_VARIABLE(Libs)
diff --git a/tools/gn/variables.h b/tools/gn/variables.h
index 80404ae..020e25b 100644
--- a/tools/gn/variables.h
+++ b/tools/gn/variables.h
@@ -127,10 +127,6 @@
 extern const char kForwardDependentConfigsFrom_HelpShort[];
 extern const char kForwardDependentConfigsFrom_Help[];
 
-extern const char kHardDep[];
-extern const char kHardDep_HelpShort[];
-extern const char kHardDep_Help[];
-
 extern const char kIncludeDirs[];
 extern const char kIncludeDirs_HelpShort[];
 extern const char kIncludeDirs_Help[];
diff --git a/tools/isolate_driver.py b/tools/isolate_driver.py
index a779820..4db823e 100755
--- a/tools/isolate_driver.py
+++ b/tools/isolate_driver.py
@@ -13,6 +13,10 @@
 
 This script loads build.ninja and processes it to determine all the executables
 referenced by the isolated target. It adds them in the wrapping .isolate file.
+
+WARNING: The target to use for build.ninja analysis is the base name of the
+.isolate file plus '_run'. For example, 'foo_test.isolate' would have the target
+'foo_test_run' analysed.
 """
 
 import StringIO
@@ -211,8 +215,9 @@
       '.', temp_isolate_dir).replace(os.path.sep, '/')
 
   # It's a big assumption here that the name of the isolate file matches the
-  # primary target. Fix accordingly if this doesn't hold true.
-  target = isolate[:-len('.isolate')]
+  # primary target '_run'. Fix accordingly if this doesn't hold true, e.g.
+  # complain to maruel@.
+  target = isolate[:-len('.isolate')] + '_run'
   build_steps = load_ninja(build_dir)
   binary_deps = post_process_deps(build_dir, recurse(target, build_steps, None))
   logging.debug(
diff --git a/tools/json_schema_compiler/api_gen_util.target.darwin-arm.mk b/tools/json_schema_compiler/api_gen_util.target.darwin-arm.mk
index 49306f3..3f04a8b 100644
--- a/tools/json_schema_compiler/api_gen_util.target.darwin-arm.mk
+++ b/tools/json_schema_compiler/api_gen_util.target.darwin-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -127,7 +126,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/tools/json_schema_compiler/api_gen_util.target.darwin-x86.mk b/tools/json_schema_compiler/api_gen_util.target.darwin-x86.mk
index 9380123..f12d673 100644
--- a/tools/json_schema_compiler/api_gen_util.target.darwin-x86.mk
+++ b/tools/json_schema_compiler/api_gen_util.target.darwin-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/tools/json_schema_compiler/api_gen_util.target.darwin-x86_64.mk b/tools/json_schema_compiler/api_gen_util.target.darwin-x86_64.mk
index e2a4835..47a731a 100644
--- a/tools/json_schema_compiler/api_gen_util.target.darwin-x86_64.mk
+++ b/tools/json_schema_compiler/api_gen_util.target.darwin-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/tools/json_schema_compiler/api_gen_util.target.linux-arm.mk b/tools/json_schema_compiler/api_gen_util.target.linux-arm.mk
index 49306f3..3f04a8b 100644
--- a/tools/json_schema_compiler/api_gen_util.target.linux-arm.mk
+++ b/tools/json_schema_compiler/api_gen_util.target.linux-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -127,7 +126,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/tools/json_schema_compiler/api_gen_util.target.linux-x86.mk b/tools/json_schema_compiler/api_gen_util.target.linux-x86.mk
index 9380123..f12d673 100644
--- a/tools/json_schema_compiler/api_gen_util.target.linux-x86.mk
+++ b/tools/json_schema_compiler/api_gen_util.target.linux-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/tools/json_schema_compiler/api_gen_util.target.linux-x86_64.mk b/tools/json_schema_compiler/api_gen_util.target.linux-x86_64.mk
index e2a4835..47a731a 100644
--- a/tools/json_schema_compiler/api_gen_util.target.linux-x86_64.mk
+++ b/tools/json_schema_compiler/api_gen_util.target.linux-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py
index fbd47ff..b6dfb6f 100644
--- a/tools/json_schema_compiler/cc_generator.py
+++ b/tools/json_schema_compiler/cc_generator.py
@@ -191,6 +191,9 @@
       .Sblock('    %s) {' % self._GenerateParams(
           ('const base::Value& value', '%(name)s* out'))))
 
+    if self._generate_error_messages:
+      c.Append('DCHECK(error);')
+
     if type_.property_type == PropertyType.CHOICES:
       for choice in type_.choices:
         (c.Sblock('if (%s) {' % self._GenerateValueIsTypeExpression('value',
@@ -313,7 +316,10 @@
     (c.Append('// static')
       .Append('scoped_ptr<%s> %s::FromValue(%s) {' % (classname,
         cpp_namespace, self._GenerateParams(('const base::Value& value',))))
-      .Append('  scoped_ptr<%s> out(new %s());' % (classname, classname))
+    )
+    if self._generate_error_messages:
+      c.Append('DCHECK(error);')
+    (c.Append('  scoped_ptr<%s> out(new %s());' % (classname, classname))
       .Append('  if (!Populate(%s))' % self._GenerateArgs(
           ('value', 'out.get()')))
       .Append('    return scoped_ptr<%s>();' % classname)
@@ -362,7 +368,10 @@
       is_ptr = prop.optional or prop.type_.property_type == PropertyType.ANY
       c.Append('value->SetWithoutPathExpansion("%s", %s);' % (
           prop.name,
-          self._CreateValueFromType(prop.type_, prop_var, is_ptr=is_ptr)))
+          self._CreateValueFromType(cpp_namespace,
+                                    prop.type_,
+                                    prop_var,
+                                    is_ptr=is_ptr)))
 
       if prop.optional:
         c.Eblock('}')
@@ -383,6 +392,7 @@
           .Append('   it != additional_properties.end(); ++it) {')
           .Append('value->SetWithoutPathExpansion(it->first, %s);' %
               self._CreateValueFromType(
+                  cpp_namespace,
                   type_.additional_properties,
                   '%sit->second' % ('*' if needs_unwrap else '')))
           .Eblock('}')
@@ -404,8 +414,10 @@
       (c.Sblock('if (%s) {' % choice_var)
           .Append('DCHECK(!result) << "Cannot set multiple choices for %s";' %
                       type_.unix_name)
-          .Append('result.reset(%s);' %
-                      self._CreateValueFromType(choice, '*%s' % choice_var))
+          .Append('result.reset(%s);' % self._CreateValueFromType(
+              cpp_namespace,
+              choice,
+              '*%s' % choice_var))
         .Eblock('}')
       )
     (c.Append('DCHECK(result) << "Must set at least one choice for %s";' %
@@ -441,7 +453,8 @@
 
     # Results::Create function
     if function.callback:
-      c.Concat(self._GenerateCreateCallbackArguments('Results',
+      c.Concat(self._GenerateCreateCallbackArguments(function_namespace,
+                                                     'Results',
                                                      function.callback))
 
     c.Append('}  // namespace %s' % function_namespace)
@@ -454,12 +467,14 @@
     (c.Append('namespace %s {' % event_namespace)
       .Append()
       .Cblock(self._GenerateEventNameConstant(None, event))
-      .Cblock(self._GenerateCreateCallbackArguments(None, event))
+      .Cblock(self._GenerateCreateCallbackArguments(event_namespace,
+                                                    None,
+                                                    event))
       .Append('}  // namespace %s' % event_namespace)
     )
     return c
 
-  def _CreateValueFromType(self, type_, var, is_ptr=False):
+  def _CreateValueFromType(self, cpp_namespace, type_, var, is_ptr=False):
     """Creates a base::Value given a type. Generated code passes ownership
     to caller.
 
@@ -482,7 +497,9 @@
         vardot = '(%s).' % var
       return '%sDeepCopy()' % vardot
     elif underlying_type.property_type == PropertyType.ENUM:
-      return 'new base::StringValue(ToString(%s))' % var
+      classname = cpp_util.Classname(schema_util.StripNamespace(
+          underlying_type.name))
+      return 'new base::StringValue(%sToString(%s))' % (classname, var)
     elif underlying_type.property_type == PropertyType.BINARY:
       if is_ptr:
         vardot = var + '->'
@@ -492,6 +509,7 @@
               (vardot, vardot))
     elif underlying_type.property_type == PropertyType.ARRAY:
       return '%s.release()' % self._util_cc_helper.CreateValueFromArray(
+          cpp_namespace,
           underlying_type,
           var,
           is_ptr)
@@ -544,7 +562,10 @@
     (c.Append('// static')
       .Sblock('scoped_ptr<Params> Params::Create(%s) {' % self._GenerateParams(
         ['const base::ListValue& args']))
-      .Concat(self._GenerateParamsCheck(function, 'args'))
+    )
+    if self._generate_error_messages:
+      c.Append('DCHECK(error);')
+    (c.Concat(self._GenerateParamsCheck(function, 'args'))
       .Append('scoped_ptr<Params> params(new Params());')
     )
 
@@ -707,7 +728,6 @@
                      is_ptr=is_ptr))
       else:
         (c.Sblock('if (!%s) {' % self._util_cc_helper.PopulateArrayFromList(
-              underlying_type,
               'list',
               dst_var,
               is_ptr)))
@@ -868,8 +888,8 @@
       c.Append('// static')
     maybe_namespace = '' if cpp_namespace is None else '%s::' % cpp_namespace
 
-    c.Sblock('std::string %sToString(%s enum_param) {' %
-                 (maybe_namespace, classname))
+    c.Sblock('std::string %s%sToString(%s enum_param) {' %
+                 (maybe_namespace, classname, classname))
     c.Sblock('switch (enum_param) {')
     for enum_value in self._type_helper.FollowRef(type_).enum_values:
       (c.Append('case %s: ' % self._type_helper.GetEnumValue(type_, enum_value))
@@ -881,6 +901,12 @@
       .Append('return "";')
       .Eblock('}')
     )
+
+    (c.Append()
+      .Sblock('std::string %sToString(%s enum_param) {' %
+                  (maybe_namespace, classname))
+      .Append('return %s%sToString(enum_param);' % (maybe_namespace, classname))
+      .Eblock('}'))
     return c
 
   def _GenerateEnumFromString(self, cpp_namespace, type_):
@@ -909,7 +935,10 @@
     )
     return c
 
-  def _GenerateCreateCallbackArguments(self, function_scope, callback):
+  def _GenerateCreateCallbackArguments(self,
+                                       cpp_namespace,
+                                       function_scope,
+                                       callback):
     """Generate all functions to create Value parameters for a callback.
 
     E.g for function "Bar", generate Bar::Results::Create
@@ -932,8 +961,10 @@
     for param in params:
       declaration_list.append(cpp_util.GetParameterDeclaration(
           param, self._type_helper.GetCppType(param.type_)))
-      c.Append('create_results->Append(%s);' %
-          self._CreateValueFromType(param.type_, param.unix_name))
+      c.Append('create_results->Append(%s);' % self._CreateValueFromType(
+          cpp_namespace,
+          param.type_,
+          param.unix_name))
     c.Append('return create_results.Pass();')
     c.Eblock('}')
     c.Substitute({
@@ -976,13 +1007,9 @@
     c = Code()
     if not self._generate_error_messages:
       return c
-    (c.Append('if (error) {')
-      .Append('  if (error->length())')
-      .Append('    error->append(UTF8ToUTF16("; "));')
-      .Append('  error->append(UTF8ToUTF16(%s));' % body)
-      .Append('}')
-      .Append('else')
-      .Append('  *error = UTF8ToUTF16(%s);' % body))
+    (c.Append('if (error->length())')
+      .Append('  error->append(UTF8ToUTF16("; "));')
+      .Append('error->append(UTF8ToUTF16(%s));' % body))
     return c
 
   def _GenerateParams(self, params):
diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py
index 237a028..a7cac43 100644
--- a/tools/json_schema_compiler/h_generator.py
+++ b/tools/json_schema_compiler/h_generator.py
@@ -214,6 +214,8 @@
       # static. On the other hand, those declared inline (e.g. in an object) do.
       maybe_static = '' if is_toplevel else 'static '
       (c.Append()
+        .Append('%sstd::string %sToString(%s as_enum);' %
+                (maybe_static, classname, classname))
         .Append('%sstd::string ToString(%s as_enum);' %
                 (maybe_static, classname))
         .Append('%s%s Parse%s(const std::string& as_string);' %
@@ -398,5 +400,5 @@
     # For example, optional properties may have failed to parse, but the
     # parser was able to continue.
     if self._generate_error_messages:
-      params += ('base::string16* error = NULL',)
+      params += ('base::string16* error',)
     return ', '.join(str(p) for p in params)
diff --git a/tools/json_schema_compiler/test/arrays_unittest.cc b/tools/json_schema_compiler/test/arrays_unittest.cc
index f3fb058..9aca730 100644
--- a/tools/json_schema_compiler/test/arrays_unittest.cc
+++ b/tools/json_schema_compiler/test/arrays_unittest.cc
@@ -52,21 +52,32 @@
 }
 
 TEST(JsonSchemaCompilerArrayTest, EnumArrayType) {
-  std::vector<EnumArrayType::TypesType> enums;
-  enums.push_back(EnumArrayType::TYPES_TYPE_ONE);
-  enums.push_back(EnumArrayType::TYPES_TYPE_TWO);
-  enums.push_back(EnumArrayType::TYPES_TYPE_THREE);
-
-  scoped_ptr<base::ListValue> types(new base::ListValue());
-  for (size_t i = 0; i < enums.size(); ++i)
-    types->Append(new base::StringValue(EnumArrayType::ToString(enums[i])));
-
+  // { "types": ["one", "two", "three"] }
+  base::ListValue* types = new base::ListValue();
+  types->AppendString("one");
+  types->AppendString("two");
+  types->AppendString("three");
   base::DictionaryValue value;
-  value.Set("types", types.release());
+  value.Set("types", types);
 
   EnumArrayType enum_array_type;
+
+  // Test Populate.
   ASSERT_TRUE(EnumArrayType::Populate(value, &enum_array_type));
-  EXPECT_EQ(enums, enum_array_type.types);
+  {
+    EnumArrayType::TypesType enums[] = {
+      EnumArrayType::TYPES_TYPE_ONE,
+      EnumArrayType::TYPES_TYPE_TWO,
+      EnumArrayType::TYPES_TYPE_THREE,
+    };
+    std::vector<EnumArrayType::TypesType> enums_vector(
+        enums, enums + arraysize(enums));
+    EXPECT_EQ(enums_vector, enum_array_type.types);
+  }
+
+  // Test ToValue.
+  scoped_ptr<base::Value> as_value(enum_array_type.ToValue());
+  EXPECT_TRUE(value.Equals(as_value.get())) << value << " != " << *as_value;
 }
 
 TEST(JsonSchemaCompilerArrayTest, OptionalEnumArrayType) {
diff --git a/tools/json_schema_compiler/test/enums.json b/tools/json_schema_compiler/test/enums.json
index 8891dc7..c776313 100644
--- a/tools/json_schema_compiler/test/enums.json
+++ b/tools/json_schema_compiler/test/enums.json
@@ -32,6 +32,19 @@
         }
       },
       {
+        "id": "InlineAndReferenceEnum",
+        "type": "object",
+        "properties": {
+          "inline_enum": {
+            "type": "string",
+            "enum": ["test1", "test2", "test3"]
+          },
+          "reference_enum": {
+            "$ref": "Enumeration"
+          }
+        }
+      },
+      {
         "id": "OptionalEnumType",
         "type": "object",
         "properties": {
diff --git a/tools/json_schema_compiler/test/enums_unittest.cc b/tools/json_schema_compiler/test/enums_unittest.cc
index be7a381..0a2d5d1 100644
--- a/tools/json_schema_compiler/test/enums_unittest.cc
+++ b/tools/json_schema_compiler/test/enums_unittest.cc
@@ -53,6 +53,18 @@
     ASSERT_TRUE(HasEnumeration::Populate(value, &enumeration));
     EXPECT_TRUE(value.Equals(enumeration.ToValue().get()));
   }
+  {
+    InlineAndReferenceEnum enumeration;
+    base::DictionaryValue value;
+    ASSERT_FALSE(InlineAndReferenceEnum::Populate(value, &enumeration));
+
+    value.Set("inline_enum", base::Value::CreateStringValue("test2"));
+    ASSERT_FALSE(InlineAndReferenceEnum::Populate(value, &enumeration));
+
+    value.Set("reference_enum", base::Value::CreateStringValue("one"));
+    ASSERT_TRUE(InlineAndReferenceEnum::Populate(value, &enumeration));
+    EXPECT_TRUE(value.Equals(enumeration.ToValue().get()));
+  }
 }
 
 TEST(JsonSchemaCompilerEnumsTest, EnumsArrayAsType) {
diff --git a/tools/json_schema_compiler/test/error_generation_unittest.cc b/tools/json_schema_compiler/test/error_generation_unittest.cc
index 78cd706..42f9576 100644
--- a/tools/json_schema_compiler/test/error_generation_unittest.cc
+++ b/tools/json_schema_compiler/test/error_generation_unittest.cc
@@ -78,7 +78,8 @@
   {
     scoped_ptr<base::ListValue> params_value = List(
         new FundamentalValue(5));
-    EXPECT_TRUE(TestFunction::Params::Create(*params_value));
+    base::string16 error;
+    EXPECT_TRUE(TestFunction::Params::Create(*params_value, &error));
   }
   {
     scoped_ptr<base::ListValue> params_value = List(
@@ -96,7 +97,8 @@
   {
     scoped_ptr<base::ListValue> params_value = List(
         new FundamentalValue(5));
-    EXPECT_TRUE(TestFunction::Params::Create(*params_value));
+    base::string16 error;
+    EXPECT_TRUE(TestFunction::Params::Create(*params_value, &error));
   }
   {
     scoped_ptr<base::ListValue> params_value = List(
@@ -125,9 +127,10 @@
 
 TEST(JsonSchemaCompilerErrorTest, WrongParameterCreationType) {
   {
+    base::string16 error;
     scoped_ptr<base::ListValue> params_value = List(
         new base::StringValue("Yeah!"));
-    EXPECT_TRUE(TestString::Params::Create(*params_value));
+    EXPECT_TRUE(TestString::Params::Create(*params_value, &error));
   }
   {
     scoped_ptr<base::ListValue> params_value = List(
diff --git a/tools/json_schema_compiler/util.h b/tools/json_schema_compiler/util.h
index 228eced..5cc4008 100644
--- a/tools/json_schema_compiler/util.h
+++ b/tools/json_schema_compiler/util.h
@@ -173,6 +173,24 @@
   return scoped_ptr<base::Value>();
 }
 
+template <class TParent, class T>
+scoped_ptr<base::Value> CreateValueFromEnumArray(const std::vector<T>& from) {
+  base::ListValue* list = new base::ListValue();
+  for (typename std::vector<T>::const_iterator it = from.begin();
+      it != from.end(); ++it) {
+    list->AppendString(TParent::ToString(*it));
+  }
+  return scoped_ptr<base::Value>(list);
+}
+
+template <class TParent, class T>
+scoped_ptr<base::Value> CreateValueFromOptionalEnumArray(
+    const scoped_ptr<std::vector<T> >& from) {
+  if (from.get())
+    return CreateValueFromEnumArray<TParent>(*from);
+  return scoped_ptr<base::Value>();
+}
+
 std::string ValueTypeToString(base::Value::Type type);
 
 }  // namespace util
diff --git a/tools/json_schema_compiler/util_cc_helper.py b/tools/json_schema_compiler/util_cc_helper.py
index df5b6de..8640283 100644
--- a/tools/json_schema_compiler/util_cc_helper.py
+++ b/tools/json_schema_compiler/util_cc_helper.py
@@ -2,7 +2,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-API_UTIL_NAMESPACE = 'json_schema_compiler::util'
+from model import PropertyType
+
+
+_API_UTIL_NAMESPACE = 'json_schema_compiler::util'
+
 
 class UtilCCHelper(object):
   """A util class that generates code that uses
@@ -19,7 +23,7 @@
     """
     prop = array_prop.item_type
     sub = {
-        'namespace': API_UTIL_NAMESPACE,
+        'namespace': _API_UTIL_NAMESPACE,
         'name': name,
         'src': src,
         'dst': dst,
@@ -35,45 +39,47 @@
 
     return val % sub
 
-  def PopulateArrayFromList(self, array_prop, src, dst, optional):
+  def PopulateArrayFromList(self, src, dst, optional):
     """Generates code to get an array from src into dst.
 
     src: ListValue*
     dst: std::vector or scoped_ptr<std::vector>
     """
-    prop = array_prop.item_type
-    sub = {
-        'namespace': API_UTIL_NAMESPACE,
-        'src': src,
-        'dst': dst,
-        'type': self._type_manager.GetCppType(prop),
-    }
-
     if optional:
       val = '%(namespace)s::PopulateOptionalArrayFromList(*%(src)s, &%(dst)s)'
     else:
       val = '%(namespace)s::PopulateArrayFromList(*%(src)s, &%(dst)s)'
-
-    return val % sub
-
-  def CreateValueFromArray(self, array_prop, src, optional):
-    """Generates code to create a scoped_pt<Value> from the array at src.
-
-    src: std::vector or scoped_ptr<std::vector>
-    """
-    prop = array_prop.item_type
-    sub = {
-        'namespace': API_UTIL_NAMESPACE,
-        'src': src,
-        'type': self._type_manager.GetCppType(prop),
+    return val % {
+      'namespace': _API_UTIL_NAMESPACE,
+      'src': src,
+      'dst': dst
     }
 
-    if optional:
-      val = '%(namespace)s::CreateValueFromOptionalArray(%(src)s)'
-    else:
-      val = '%(namespace)s::CreateValueFromArray(%(src)s)'
+  def CreateValueFromArray(self, cpp_namespace, type_, src, optional):
+    """Generates code to create a scoped_pt<Value> from the array at src.
 
-    return val % sub
+    |cpp_namespace| The namespace which contains |type_|. This is needed for
+        enum conversions, where the ToString method is on the containing
+        namespace.
+    |type_| The type of the values being converted. This is needed for enum
+        conversions, to know whether to use the Enum form of conversion.
+    |src| The variable to convert, either a vector or scoped_ptr<vector>.
+    |optional| Whether |type_| was optional. Optional types are pointers so
+        must be treated differently.
+    """
+    if type_.item_type.property_type == PropertyType.ENUM:
+      # Enums are treated specially because C++ templating thinks that they're
+      # ints, but really they're strings.
+      if optional:
+        name = 'CreateValueFromOptionalEnumArray<%s>' % cpp_namespace
+      else:
+        name = 'CreateValueFromEnumArray<%s>' % cpp_namespace
+    else:
+      if optional:
+        name = 'CreateValueFromOptionalArray'
+      else:
+        name = 'CreateValueFromArray'
+    return '%s::%s(%s)' % (_API_UTIL_NAMESPACE, name, src)
 
   def GetIncludePath(self):
     return '#include "tools/json_schema_compiler/util.h"'
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index cacb05f..dcf7313 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -2891,6 +2891,14 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="GoogleNow.MessageCenter.NotificationPoppedUp">
+  <owner>robliao@chromium.org</owner>
+  <owner>skare@chromium.org</owner>
+  <description>
+    A Google Now notification was popped up to the user.
+  </description>
+</action>
+
 <action name="GoogleNow.MessageClicked">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <description>Please enter the description of this user action.</description>
@@ -8675,6 +8683,16 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="Options_SearchEngineRemoved">
+  <owner>michaelpg@chromium.org</owner>
+  <description>Settings: Manage search engines...: Remove</description>
+</action>
+
+<action name="Options_SearchEngineSetDefault">
+  <owner>michaelpg@chromium.org</owner>
+  <description>Settings: Manage search engines...: Make default</description>
+</action>
+
 <action name="Options_SensitivitySlider_Changed">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <description>Please enter the description of this user action.</description>
@@ -8755,6 +8773,16 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="Options_SpellingServiceCheckbox_Disable">
+  <owner>michaelpg@chromium.org</owner>
+  <description>Settings: Privacy: Use spelling service</description>
+</action>
+
+<action name="Options_SpellingServiceCheckbox_Enable">
+  <owner>michaelpg@chromium.org</owner>
+  <description>Settings: Privacy: Use spelling service</description>
+</action>
+
 <action name="Options_Startup_Custom">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <description>Please enter the description of this user action.</description>
@@ -9276,6 +9304,21 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="PermissionBubbleRequest">
+  <owner>gbillock@chromium.org</owner>
+  <owner>leng@chromium.org</owner>
+  <description>A website requested a permission.</description>
+</action>
+
+<action name="PermissionBubbleRequestQueued">
+  <owner>gbillock@chromium.org</owner>
+  <owner>leng@chromium.org</owner>
+  <description>
+    A website requested a permission which was queued because an existing
+    permission request was already visible.
+  </description>
+</action>
+
 <action name="PlatformVerificationAccepted">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <description>Please enter the description of this user action.</description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 54b82f0..04892de 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -468,6 +468,14 @@
   </summary>
 </histogram>
 
+<histogram name="Apps.AppListWarmupDuration" units="milliseconds">
+  <owner>tapted@chromium.org</owner>
+  <summary>
+    The amount of time spent in warmup (in WarmupForProfile call). This will
+    tell us how long warmup blocks the UI.
+  </summary>
+</histogram>
+
 <histogram name="Ash.ActiveTouchPoints">
   <owner>kuscher@google.com</owner>
   <owner>rbyers@chromium.org</owner>
@@ -1936,8 +1944,21 @@
   <summary>Records the media type of every video being cast.</summary>
 </histogram>
 
+<histogram name="Cast.Sender.CastPlayerResult" enum="CastPlayBackState">
+  <owner>maybelle@chromium.org</owner>
+  <owner>miguelg@chromium.org</owner>
+  <summary>
+    Records the result of a request to play remotely on a per player app basis
+    within Chrome for Android.
+  </summary>
+</histogram>
+
 <histogram name="Cast.Sender.CastPlaySuccess" enum="BooleanSuccess">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <obsolete>
+    Deprecated 04/2014, and replaced by Cast.Sender.CastPlayerResult.
+  </obsolete>
+  <owner>maybelle@chromium.org</owner>
+  <owner>miguelg@chromium.org</owner>
   <summary>
     Records the result of a request to play remotely. The value will be true if
     the playback succeeded, and false if there was an error.
@@ -2268,6 +2289,14 @@
   </summary>
 </histogram>
 
+<histogram name="Clipboard.X11StoreCopyPasteDuration" units="ms">
+  <owner>pkotwicz@chromium.org</owner>
+  <summary>
+    The length of time that it takes to transfer ownership of Chrome's CLIPBOARD
+    selection to the clipboard manager when Chrome exits.
+  </summary>
+</histogram>
+
 <histogram name="CloudPrint.AuthEvent" enum="CloudPrintAuthEventType">
   <owner>vitalybuka@chromium.org</owner>
   <summary>Event counts in CloudPrintAuth.</summary>
@@ -7307,8 +7336,18 @@
   <summary>Events in Google Now component extension.</summary>
 </histogram>
 
+<histogram name="GoogleNow.MessageCenter.Displayed.NotificationsVisible"
+    units="count">
+  <owner>robliao@chromium.org</owner>
+  <owner>skare@chromium.org</owner>
+  <summary>
+    Count of the number of Google Now notifications visible when the message
+    center/notification center is shown.
+  </summary>
+</histogram>
+
 <histogram name="GoogleUpdate.EffectivePolicy" enum="UpdatePolicy">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>gab@chromium.org</owner>
   <summary>
     The effective update policy for Chrome on Windows. Recorded once per startup
     (following a 45 seconds delay).
@@ -8581,7 +8620,7 @@
   </summary>
 </histogram>
 
-<histogram name="LocalDiscovery.FirewallState" enum="BooleanEnabled">
+<histogram name="LocalDiscovery.IsFirewallReady" enum="BooleanEnabled">
   <owner>noamsml@chromium.org</owner>
   <owner>vitalybuka@chromium.org</owner>
   <summary>
@@ -8866,6 +8905,14 @@
   <summary>EME NeedKey event count.</summary>
 </histogram>
 
+<histogram name="Media.EME.OutputProtection" enum="MediaOutputProtectionStatus">
+  <owner>xhwang@chromium.org</owner>
+  <summary>
+    Output protection query status and result. One query and one positive (no
+    unprotected external links) result (if any) are reported per CDM instance.
+  </summary>
+</histogram>
+
 <histogram name="Media.EME.Unknown.addKey" enum="MediaKeyException">
   <owner>xhwang@chromium.org</owner>
   <summary>addKey result using an unknown key system.</summary>
@@ -10143,6 +10190,7 @@
 </histogram>
 
 <histogram name="NaCl.Client.Helper.InitState" enum="NaClHelperStatus">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10151,6 +10199,7 @@
 </histogram>
 
 <histogram name="NaCl.Client.Helper.StateOnFork" enum="NaClHelperStatus">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10160,6 +10209,7 @@
 </histogram>
 
 <histogram name="NaCl.Client.OSArch" enum="NaClOSArchEnum">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>The OS/Architecture of a nexe that was loaded.</summary>
@@ -10167,6 +10217,7 @@
 
 <histogram name="NaCl.HttpStatusCodeClass.Manifest.InstalledApp"
     enum="NaClHttpStatusCodeClass">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10177,6 +10228,7 @@
 
 <histogram name="NaCl.HttpStatusCodeClass.Manifest.NotInstalledApp"
     enum="NaClHttpStatusCodeClass">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10187,6 +10239,7 @@
 
 <histogram name="NaCl.HttpStatusCodeClass.Nexe.InstalledApp"
     enum="NaClHttpStatusCodeClass">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10197,6 +10250,7 @@
 
 <histogram name="NaCl.HttpStatusCodeClass.Nexe.NotInstalledApp"
     enum="NaClHttpStatusCodeClass">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10206,6 +10260,7 @@
 </histogram>
 
 <histogram name="NaCl.LoadStatus.Plugin" enum="NaClPluginErrorCode">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>The error code returned by NaCl's Chrome plugin.</summary>
@@ -10213,6 +10268,7 @@
 
 <histogram name="NaCl.LoadStatus.Plugin.InstalledApp"
     enum="NaClPluginErrorCode">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10223,6 +10279,7 @@
 
 <histogram name="NaCl.LoadStatus.Plugin.NotInstalledApp"
     enum="NaClPluginErrorCode">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10232,6 +10289,7 @@
 </histogram>
 
 <histogram name="NaCl.LoadStatus.SelLdr" enum="NaClSelLdrErrorCode">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>The error code returned by NaCl's sel_ldr.</summary>
@@ -10239,6 +10297,7 @@
 
 <histogram name="NaCl.LoadStatus.SelLdr.InstalledApp"
     enum="NaClSelLdrErrorCode">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10248,6 +10307,7 @@
 
 <histogram name="NaCl.LoadStatus.SelLdr.NotInstalledApp"
     enum="NaClSelLdrErrorCode">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10256,6 +10316,7 @@
 </histogram>
 
 <histogram name="NaCl.Manifest.IsDataURI" enum="NaClManifestType">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10267,6 +10328,7 @@
   <obsolete>
     Deprecated 6/2011, renamed.
   </obsolete>
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10275,12 +10337,14 @@
 </histogram>
 
 <histogram name="NaCl.ModuleUptime.Crash" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>The time a NaCl module ran before it crashed.</summary>
 </histogram>
 
 <histogram name="NaCl.ModuleUptime.Normal" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>The time a NaCl module ran without crashing, at shutdown.</summary>
@@ -10290,6 +10354,7 @@
   <obsolete>
     Deprecated 6/2011, renamed.
   </obsolete>
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10301,6 +10366,7 @@
   <obsolete>
     Deprecated 6/2011, renamed.
   </obsolete>
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10312,6 +10378,7 @@
   <obsolete>
     Deprecated 6/2011, renamed.
   </obsolete>
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10325,6 +10392,7 @@
   <obsolete>
     Deprecated 6/2011, renamed.
   </obsolete>
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10335,6 +10403,7 @@
 </histogram>
 
 <histogram name="NaCl.Options.PNaCl.OptLevel" enum="PNaClOptionsOptLevelEnum">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10347,12 +10416,14 @@
   <obsolete>
     Deprecated 6/2011, renamed.
   </obsolete>
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>The OS/Architecture of a nexe that was loaded.</summary>
 </histogram>
 
 <histogram name="NaCl.Perf.PNaClCache.IsHit" enum="PNaClTranslationCacheEnum">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10362,6 +10433,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.PNaClLoadTime.CompileKBPerSec" units="KB/s">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10371,6 +10443,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.PNaClLoadTime.CompileTime" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10380,6 +10453,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.PNaClLoadTime.LinkTime" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10389,6 +10463,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.PNaClLoadTime.LoadCompiler" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10397,6 +10472,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.PNaClLoadTime.LoadLinker" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10406,6 +10482,7 @@
 
 <histogram name="NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded"
     units="%">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10416,6 +10493,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.PNaClLoadTime.TotalUncachedKBPerSec" units="KB/s">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10427,6 +10505,7 @@
 
 <histogram name="NaCl.Perf.PNaClLoadTime.TotalUncachedTime"
     units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10436,12 +10515,14 @@
 </histogram>
 
 <histogram name="NaCl.Perf.Size.Manifest" units="KB">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>The size of the manifest file.</summary>
 </histogram>
 
 <histogram name="NaCl.Perf.Size.Nexe" units="KB">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10450,6 +10531,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.Size.Pexe" units="KB">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10459,6 +10541,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.Size.PexeNexeSizePct" units="%">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10468,6 +10551,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.Size.PNaClTranslatedNexe" units="KB">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10478,12 +10562,14 @@
 </histogram>
 
 <histogram name="NaCl.Perf.StartupTime.LoadModule" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>The time it took to load the NaCl module into sel_ldr.</summary>
 </histogram>
 
 <histogram name="NaCl.Perf.StartupTime.LoadModulePerMB" units="milliseconds/MB">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10493,6 +10579,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.StartupTime.ManifestDownload" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10501,6 +10588,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.StartupTime.NaClOverhead" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10512,6 +10600,7 @@
 
 <histogram name="NaCl.Perf.StartupTime.NaClOverheadPerMB"
     units="milliseconds/MB">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10523,6 +10612,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.StartupTime.NexeDownload" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10532,6 +10622,7 @@
 
 <histogram name="NaCl.Perf.StartupTime.NexeDownloadPerMB"
     units="milliseconds/MB">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10541,6 +10632,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.StartupTime.Total" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10550,6 +10642,7 @@
 </histogram>
 
 <histogram name="NaCl.Perf.StartupTime.TotalPerMB" units="milliseconds/MB">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10560,6 +10653,7 @@
 </histogram>
 
 <histogram name="NaCl.ShutdownTime.Total" units="milliseconds">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>The time it took the NaCl module to shut down.</summary>
@@ -10570,6 +10664,7 @@
     Deprecated 5/2011, data is duplicated by NaCl.NexeStartupTime, and
     normalizing to 'tab opens' is unusual.
   </obsolete>
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10579,6 +10674,7 @@
 </histogram>
 
 <histogram name="NaCl.ValidationCache.Query" enum="NaClValidationCacheEnum">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10587,6 +10683,7 @@
 </histogram>
 
 <histogram name="NaCl.ValidationCache.Set" enum="NaClValidationCacheEnum">
+  <owner>jvoung@chromium.org</owner>
   <owner>mackinlay@google.com</owner>
   <owner>ncbray@chromium.org</owner>
   <summary>
@@ -10599,6 +10696,18 @@
   <summary>The scheme of the URL for each main-frame navigation.</summary>
 </histogram>
 
+<histogram name="NCN.NetworkOperatorMCCMNC_ConnectionChange">
+  <owner>bolian@chromium.org</owner>
+  <owner>bengr@google.com</owner>
+  <owner>marq@google.com</owner>
+  <summary>
+    The MCC (mobile country code) and MNC (mobile network code) of the network
+    operator when the network connection is changed to a mobile network. Value
+    zero means the connection is changed to a non-mobile network or the operator
+    code is unknown.
+  </summary>
+</histogram>
+
 <histogram name="Net.AlternateProtocolBrokenLocation"
     enum="BrokenAlternateProtocolLocation">
   <owner>rch@chromium.org</owner>
@@ -12769,7 +12878,7 @@
 </histogram>
 
 <histogram name="Net.QuicEphemeralPortsSuggested">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The number of ports suggested per server.</summary>
 </histogram>
 
@@ -12826,7 +12935,7 @@
 
 <histogram name="Net.QuicSession.21CumulativePacketsReceived"
     units="Received in Ranges">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     This histogram summarizes information about a 21 packet sequence, indicating
     for each of the 21 possible prefixes of this pattern, how many packets were
@@ -12845,7 +12954,7 @@
 
 <histogram name="Net.QuicSession.6PacketsPatternsReceived"
     units="Binay of Packets ACKed">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     Each of the 64 buckets represents a different binary pattern of 6
     consecutive packets that were received by the client.  The LSB of the bucket
@@ -12910,8 +13019,21 @@
   </summary>
 </histogram>
 
+<histogram name="Net.QuicSession.ConnectionTypeFromPeer" enum="AddressFamily">
+  <owner>rch@chromium.org</owner>
+  <summary>
+    The IP Address family of this connection, as reported by the server.
+  </summary>
+</histogram>
+
+<histogram name="Net.QuicSession.ConnectionTypeFromSelf" enum="AddressFamily">
+  <owner>rch@chromium.org</owner>
+  <summary>The IP Address family of this connection, as seen locally.</summary>
+</histogram>
+
 <histogram name="Net.QuicSession.CreationError" enum="QuicSessionErrorCodes">
   <owner>jar@chromium.org</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     Count of errors during attempts to create a QUIC session (before even using
     the session).
@@ -12987,7 +13109,7 @@
 </histogram>
 
 <histogram name="Net.QuicSession.PacketLossRate" units="1/10th Percent">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The ratio of the number of missing packets, to the maximum packet sequence
     number received,  for QUIC connections longer than 21 packets received via
@@ -13006,7 +13128,7 @@
 
 <histogram name="Net.QuicSession.PublicResetAddressMismatch"
     enum="QuicAddressMismatch">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     When a public reset packet is received, whether the client IP address and
     port number in it differ from the client IP address and port number in the
@@ -13341,13 +13463,13 @@
 </histogram>
 
 <histogram name="Net.SpdyConnectionLatency" units="milliseconds">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>Time from when the Connect() starts until it completes.</summary>
 </histogram>
 
 <histogram name="Net.SpdyFrameStreamAndSessionFlowControlState"
     enum="SpdyFrameFlowControlState">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The counts of the flow control state of each frame (with stream and session
     flow control on).
@@ -13356,7 +13478,7 @@
 
 <histogram name="Net.SpdyFrameStreamFlowControlState"
     enum="SpdyFrameFlowControlState">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The counts of the flow control state of each frame (with stream flow control
     on).
@@ -13375,7 +13497,7 @@
 
 <histogram name="Net.SpdyIPPoolDomainMatch" enum="SpdyIPPoolDomainMatch"
     units="count">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     Status of checking if a SPDY domain can handle a IP match.  If a match is
     found, we successfully used the IP Pooling.  If a match is not found, we
@@ -13385,27 +13507,27 @@
 </histogram>
 
 <histogram name="Net.SpdyPing.RTT" units="milliseconds">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The RTT for SPDY's PING.</summary>
 </histogram>
 
 <histogram name="Net.SpdyPriorityCount">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The count of streams at each priority over Spdy sessions.</summary>
 </histogram>
 
 <histogram name="Net.SpdyRecvBytes" units="bytes">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The number of bytes recevied per stream.</summary>
 </histogram>
 
 <histogram name="Net.SpdySendBytes" units="bytes">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The number of bytes sent per stream.</summary>
 </histogram>
 
 <histogram name="Net.SpdySession.BytesRead.EOF" units="bytes">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     Total number of bytes recevied per session before closing session due to
     EOF.
@@ -13413,7 +13535,7 @@
 </histogram>
 
 <histogram name="Net.SpdySession.BytesRead.OtherErrors" units="bytes">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     Total number of bytes recevied per session before closing session due to an
     error during read.
@@ -13421,7 +13543,7 @@
 </histogram>
 
 <histogram name="Net.SpdySession.ClosedOnError" enum="NetErrorCodes">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     Net error codes when SpdySession was closed, doesn't inlcuding net::OK.
   </summary>
@@ -13429,7 +13551,7 @@
 
 <histogram name="Net.SpdySession.CreateStreamWithSocketConnected"
     enum="BooleanSuccess">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>Socket connected status in SpdySession::CreateStream.</summary>
 </histogram>
 
@@ -13438,7 +13560,7 @@
   <obsolete>
     Replaced by SpdySessionErrorDetails2 on 2013-04-19.
   </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     WARNING: r181910 added an enum value in the middle, so don't trust the
     counts for values 9 and above for Chrome builds after that revision.
@@ -13449,7 +13571,7 @@
 
 <histogram name="Net.SpdySessionErrorDetails2" enum="SpdyProtocolErrorDetails2"
     units="count">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The type of SPDY Protocol error encountered.</summary>
 </histogram>
 
@@ -13458,7 +13580,7 @@
   <obsolete>
     Replaced by SpdySessionErrorDetails_Google2 on 2013-04-19.
   </obsolete>
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The type of SPDY Protocol error encountered when talking to a google.com
     server.
@@ -13467,7 +13589,7 @@
 
 <histogram name="Net.SpdySessionErrorDetails_Google2"
     enum="SpdyProtocolErrorDetails2" units="count">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     WARNING: r181910 added an enum value in the middle, so don't trust the
     counts for values 9 and above for Chrome builds after that revision.
@@ -13478,13 +13600,13 @@
 </histogram>
 
 <histogram name="Net.SpdySessionGet" enum="SpdySessionGet" units="count">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The type of SPDY Session used when looking up a session.</summary>
 </histogram>
 
 <histogram name="Net.SpdySessionGetPeerAddressNotConnected"
     enum="BooleanSuccess">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     Whether SpdySession::Get{Peer,Local}Address was called when the connection
     had no socket.
@@ -13495,6 +13617,7 @@
     enum="BooleanDataReductionProxy">
   <owner>bengr@chromium.org</owner>
   <owner>bolian@chromium.org</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The count of SPDY sessions using the data reduction proxy and the count of
     other SPDY sessions.
@@ -13503,7 +13626,7 @@
 
 <histogram name="Net.SpdySessionSocketNotConnectedGetLocalAddress"
     enum="BooleanSuccess">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     SpdySession::GetLocalAddress returned ERR_SOCKET_NOT_CONNECTED.
   </summary>
@@ -13511,26 +13634,26 @@
 
 <histogram name="Net.SpdySessionSocketNotConnectedGetPeerAddress"
     enum="BooleanSuccess">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     SpdySession::GetPeerAddress returned ERR_SOCKET_NOT_CONNECTED.
   </summary>
 </histogram>
 
 <histogram name="Net.SpdySessionsWithStalls">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The count of SPDY Sessions with or without stalls.</summary>
 </histogram>
 
 <histogram name="Net.SpdySettingsCwnd" units="packets">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The congestion window (in pkts) received at the end of a SpdySession.
   </summary>
 </histogram>
 
 <histogram name="Net.SpdySettingsCwndSent" units="packets">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The congestion window (in pkts) sent at the beginning of a SpdySession.
   </summary>
@@ -13538,31 +13661,31 @@
 
 <histogram name="Net.SpdySettingsReceived" enum="SpdySettingsReceived"
     units="%">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     Percentage of sessions which received settings from the server.
   </summary>
 </histogram>
 
 <histogram name="Net.SpdySettingsRetransRate" units="%">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The Download Retransmission Rate (%) received at the end of a SpdySession.
   </summary>
 </histogram>
 
 <histogram name="Net.SpdySettingsRTT" units="milliseconds">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The RTT received at the end of a SpdySession.</summary>
 </histogram>
 
 <histogram name="Net.SpdySettingsSent" enum="SpdySettingsSent" units="%">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>Percentage of sessions which sent settings to the server.</summary>
 </histogram>
 
 <histogram name="Net.SpdyStreamDownloadTime" units="milliseconds">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The time between receiving the first chunk and the last chunk of data on a
     Spdy stream.
@@ -13570,36 +13693,36 @@
 </histogram>
 
 <histogram name="Net.SpdyStreamsAbandonedPerSession">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The number of pushed, but abandoned streams over a single session.
   </summary>
 </histogram>
 
 <histogram name="Net.SpdyStreamsPerSession">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The number of streams issued over a single session.</summary>
 </histogram>
 
 <histogram name="Net.SpdyStreamsPushedAndClaimedPerSession">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The number of pushed, and used streams over a single session.
   </summary>
 </histogram>
 
 <histogram name="Net.SpdyStreamsPushedPerSession">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The number of push streams received over a single session.</summary>
 </histogram>
 
 <histogram name="Net.SpdyStreamStallsPerSession">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>The number of stream stalls per session.</summary>
 </histogram>
 
 <histogram name="Net.SpdyStreamTime" units="milliseconds">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The time of a Spdy stream.  Measured from sending the first chunk to
     receiving the last chunk of data.
@@ -13607,7 +13730,7 @@
 </histogram>
 
 <histogram name="Net.SpdyStreamTimeToFirstByte" units="milliseconds">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The time between sending the request and receiving the first chunk of data
     on a Spdy stream.
@@ -13615,14 +13738,14 @@
 </histogram>
 
 <histogram name="Net.SpdySynStreamCompressionPercentage">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The percent compression achieved when compression SYN_STREAM frames.
   </summary>
 </histogram>
 
 <histogram name="Net.SpdyVersion" enum="ProtocolVersion">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>rch@chromium.org</owner>
   <summary>
     The SPDY protocol version that is used to talk to SPDY servers.
   </summary>
@@ -16396,12 +16519,24 @@
 
 <histogram name="Omnibox.FocusToOpenTime" units="ms">
   <owner>mpearson@chromium.org</owner>
+  <obsolete>
+    Replaced with Omnibox.FocusToOpenTimeAnyPopupState in April 2014.
+  </obsolete>
   <summary>
     The length of time between when a user focused on the omnibox and opened an
     omnibox match (which could be what they typed or a suggestion).
   </summary>
 </histogram>
 
+<histogram name="Omnibox.FocusToOpenTimeAnyPopupState" units="ms">
+  <owner>mpearson@chromium.org</owner>
+  <summary>
+    The length of time between when a user focused on the omnibox and opened an
+    omnibox match (which could be what they typed or a suggestion).  This is
+    recorded regardless of whether the omnibox dropdown (a.k.a. popup) is open.
+  </summary>
+</histogram>
+
 <histogram name="Omnibox.Paste" units="count">
   <owner>mpearson@chromium.org</owner>
   <summary>
@@ -16509,6 +16644,7 @@
 </histogram>
 
 <histogram name="Omnibox.UserTextCleared" enum="OmniboxUserTextCleared">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>mpearson@chromium.org</owner>
   <summary>
     Counts the number of times that the user text is cleared.  IME users are
@@ -20599,6 +20735,15 @@
   <summary>Times a profile name and/or avatar was updated.</summary>
 </histogram>
 
+<histogram name="Profile.UpgradeEnrollment" enum="ProfileUpgradeEnrollment">
+  <owner>mlerman@chromium.org</owner>
+  <summary>
+    The process which leads a user to enroll in New Profile Management. Also
+    tracks if the user chooses to opt out, and tutorials which guide the user
+    into New Profile Management.
+  </summary>
+</histogram>
+
 <histogram name="Profile.VisitedLinksSize" units="MB">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <summary>Size of the visited links database.</summary>
@@ -20804,14 +20949,19 @@
 </histogram>
 
 <histogram name="Rappor.DiscardReason" enum="RapporDiscardReason">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>holte@chromium.org</owner>
   <summary>
     For each Rappor log that is discarded, the reason that it was discarded.
   </summary>
 </histogram>
 
+<histogram name="Rappor.FailedUploadErrorCode" enum="NetErrorCodes">
+  <owner>holte@chromium.org</owner>
+  <summary>Net error codes for failed Rappor uploads.</summary>
+</histogram>
+
 <histogram name="Rappor.UploadResponseCode" enum="HttpResponseCode">
-  <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
+  <owner>holte@chromium.org</owner>
   <summary>
     For each upload to the Rappor server, log the response received from the
     server.
@@ -22315,6 +22465,18 @@
   <summary>The number of chunk URLs in an update response.</summary>
 </histogram>
 
+<histogram name="SB2.VolunteerPrefixesRemoved">
+  <owner>shess@chromium.org</owner>
+  <summary>
+    Older versions of the safe-browsing code incorrectly added additional
+    SBPrefix items when receiving full hashes.  This caused errors when
+    calculating when to send gethash requests to the server.  An additional pass
+    over the data has been added to remove the excess prefixes.  This histogram
+    tracks progress of that code for purposes of informing a decision on when to
+    remove the additional pass.  See http://crbug.com/361248 .
+  </summary>
+</histogram>
+
 <histogram name="SBClientDownload.CheckDownloadStats"
     enum="SBClientDownloadCheckDownloadStats">
   <owner>mattm@chromium.org</owner>
@@ -22821,6 +22983,15 @@
   </summary>
 </histogram>
 
+<histogram name="Search.MigratedPrefToDictionaryValue" enum="BooleanHit">
+  <owner>erikwright@chromium.org</owner>
+  <summary>
+    The number of times that a user-selected DSE was migrated from separate
+    String/List/..Value preferences to the new single DictionaryValue used in
+    M36.
+  </summary>
+</histogram>
+
 <histogram name="ServicesCustomization.LoadResult"
     enum="ServicesCustomizationLoadResult">
   <owner>dpolukhin@chromium.org</owner>
@@ -29349,6 +29520,22 @@
   </summary>
 </histogram>
 
+<histogram name="Viewport.MetaTagType" enum="MetaTagTypeEnum">
+  <owner>bokan@chromium.org</owner>
+  <summary>
+    The viewport meta tag type seen on each page load. Only recorded on Android.
+  </summary>
+</histogram>
+
+<histogram name="Viewport.OverviewZoom" units="Percent">
+  <owner>bokan@chromium.org</owner>
+  <summary>
+    The screen width as a percentage of viewport width (i.e. zoom at which we
+    can see the whole page). Only recorded on Android and for viewport meta tags
+    with constant width.
+  </summary>
+</histogram>
+
 <histogram name="VirtualKeyboard.KeyboardControlEvent"
     enum="KeyboardControlEvent">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
@@ -29890,6 +30077,7 @@
 </histogram>
 
 <histogram name="WebFont.BlankTextShownTime" units="milliseconds">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     A histogram tracking the time we spent showing blank text because a web font
@@ -29900,6 +30088,7 @@
 
 <histogram name="WebFont.CacheHit" enum="WebFontCacheHit">
   <owner>dmikurube@chromium.org</owner>
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     Recorded upon web fonts load. Counts the number of times web font is loaded
@@ -29910,10 +30099,12 @@
 
 <histogram name="WebFont.CORSSuccess" enum="BooleanSuccess">
   <owner>bashi@chromium.org</owner>
+  <owner>kenjibaheux@chromium.org</owner>
   <summary>The success or failure of web fonts CORS-enabled fetching.</summary>
 </histogram>
 
 <histogram name="WebFont.DownloadTime.0.Under10KB" units="milliseconds">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time it takes for a webfont download to finish, for webfonts of under
@@ -29922,6 +30113,7 @@
 </histogram>
 
 <histogram name="WebFont.DownloadTime.1.10KBTo50KB" units="milliseconds">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time it takes for a webfont download to finish, for webfonts of
@@ -29930,6 +30122,7 @@
 </histogram>
 
 <histogram name="WebFont.DownloadTime.2.50KBTo100KB" units="milliseconds">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time it takes for a webfont download to finish, for webfonts of
@@ -29938,6 +30131,7 @@
 </histogram>
 
 <histogram name="WebFont.DownloadTime.3.100KBTo1MB" units="milliseconds">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time it takes for a webfont download to finish, for webfonts of
@@ -29946,6 +30140,7 @@
 </histogram>
 
 <histogram name="WebFont.DownloadTime.4.Over1MB" units="milliseconds">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time it takes for a webfont download to finish, for webfonts of over
@@ -29954,6 +30149,7 @@
 </histogram>
 
 <histogram name="WebFont.DownloadTime.LoadError" units="milliseconds">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time taken for a webfont download that failed. Includes aborted
@@ -29962,6 +30158,7 @@
 </histogram>
 
 <histogram name="WebFont.HadBlankText" enum="BooleanHadBlankText">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     This metrics is logged when a page that use web fonts is loaded. The value
@@ -29974,6 +30171,7 @@
   <obsolete>
     Renamed to WebFont.StyleRecalcToDownloadLatency for clarity.
   </obsolete>
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time from when the webfont was referenced by a calculated style for the
@@ -29985,6 +30183,7 @@
   <obsolete>
     Deprecated as of 8/2013, replaced by WebFont.DownloadTime.0.Under10KB.
   </obsolete>
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time it takes for a webfont download to finish, for webfonts of under
@@ -29996,6 +30195,7 @@
   <obsolete>
     Deprecated as of 8/2013, replaced by WebFont.DownloadTime.1.10KBTo50KB.
   </obsolete>
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time it takes for a webfont download to finish, for webfonts of
@@ -30007,6 +30207,7 @@
   <obsolete>
     Deprecated as of 8/2013, replaced by WebFont.DownloadTime.2.50KBTo100KB.
   </obsolete>
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time it takes for a webfont download to finish, for webfonts of
@@ -30018,6 +30219,7 @@
   <obsolete>
     Deprecated as of 8/2013, replaced by WebFont.DownloadTime.3.100KBTo1MB.
   </obsolete>
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time it takes for a webfont download to finish, for webfonts of
@@ -30029,6 +30231,7 @@
   <obsolete>
     Deprecated as of 8/2013, replaced by WebFont.DownloadTime.4.Over1MB.
   </obsolete>
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time it takes for a webfont download to finish, for webfonts of over
@@ -30040,6 +30243,7 @@
   <obsolete>
     Deprecated as of 8/2013, replaced by WebFont.DownloadTime.LoadError.
   </obsolete>
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time taken for a webfont download that failed. Includes aborted
@@ -30049,6 +30253,7 @@
 
 <histogram name="WebFont.LocalFontUsed" enum="BooleanUsage">
   <owner>dmikurube@chromium.org</owner>
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     Whether a locallly installed font is actually used when @font-face had local
@@ -30058,6 +30263,7 @@
 
 <histogram name="WebFont.Resource.StyleRecalcToDownloadLatency"
     units="milliseconds">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time from when the webfont was referenced by a calculated style for the
@@ -30068,6 +30274,7 @@
 </histogram>
 
 <histogram name="WebFont.Resource.UsageType" enum="WebFontUsageType">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     For each webfont, this records (a) if the font was 'styled', i.e. referenced
@@ -30085,6 +30292,7 @@
     Deprecated as of 9/2013, replaced by
     WebFont.Resource.StyleRecalcToDownloadLatency.
   </obsolete>
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The time from when the webfont was referenced by a calculated style for the
@@ -30096,6 +30304,7 @@
   <obsolete>
     Deprecated as of 9/2013, replaced by WebFont.Resource.UsageType.
   </obsolete>
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     For each webfont, this records (a) if the font was 'styled', i.e. referenced
@@ -30109,6 +30318,7 @@
 </histogram>
 
 <histogram name="WebFont.WebFontsInPage">
+  <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
     The number of webfonts used in a page. This is recorded when the first
@@ -30254,6 +30464,24 @@
   </summary>
 </histogram>
 
+<histogram name="WebRTC.DataChannelMaxRetransmits">
+  <owner>perkj@chromium.org</owner>
+  <summary>
+    The maximum number of retransmissions that are attempted in unreliable mode.
+    It is set to the value used in the configuration when a RTCDataChannel is
+    created.
+  </summary>
+</histogram>
+
+<histogram name="WebRTC.DataChannelMaxRetransmitTime" units="milliseconds">
+  <owner>perkj@chromium.org</owner>
+  <summary>
+    The length of the time window during which transmissions and retransmissions
+    may occur in unreliable mode. It is set to the value used in the
+    configuration when a RTCDataChannel is created.
+  </summary>
+</histogram>
+
 <histogram name="WebRTC.DesktopCaptureCounters" enum="DesktopCaptureCounters">
   <owner>jiayl@chromium.org</owner>
   <summary>
@@ -30498,6 +30726,12 @@
   <int value="4" label="Snapped"/>
 </enum>
 
+<enum name="AddressFamily" type="int">
+  <int value="0" label="Unspecified"/>
+  <int value="1" label="IPv4"/>
+  <int value="2" label="IPv6"/>
+</enum>
+
 <enum name="AlternateProtocolUsage" type="int">
   <int value="0" label="ALTERNATE_PROTOCOL_USAGE_NO_RACE"/>
   <int value="1" label="ALTERNATE_PROTOCOL_USAGE_WON_RACE"/>
@@ -31305,6 +31539,13 @@
   <int value="8" label="YV12"/>
 </enum>
 
+<enum name="CastPlayBackState" type="int">
+  <int value="0" label="YT_PLAYER_SUCCESS"/>
+  <int value="1" label="YT_PLAYER_FAILURE"/>
+  <int value="2" label="DEFAULT_PLAYER_SUCCESS"/>
+  <int value="3" label="DEFAULT_PLAYER_FAILURE"/>
+</enum>
+
 <enum name="CatSixtyFour" type="int">
   <int value="0" label="Saber-Toothed Cat (&lt;10.6), 32-bit (?)"/>
   <int value="1" label="Saber-Toothed Cat (&lt;10.6), 64-bit (?)"/>
@@ -32779,6 +33020,7 @@
       label="Enable the use of relay servers by the remote access host"/>
   <int value="264"
       label="Restrict the UDP port range used by the remote access host"/>
+  <int value="265" label="Enables the old web-based signin flows"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations" type="int">
@@ -33765,6 +34007,22 @@
   <int value="747" label="BLUETOOTHSOCKET_GETSOCKETS"/>
   <int value="748" label="WEBSTOREPRIVATE_SIGNINFUNCTION"/>
   <int value="749" label="SHELL_CREATEWINDOW"/>
+  <int value="750"
+      label="FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDSUCCESS"/>
+  <int value="751"
+      label="FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDERROR"/>
+  <int value="752" label="BROWSER_OPENTAB"/>
+  <int value="753" label="MANAGEMENT_CREATEAPPSHORTCUT"/>
+  <int value="754" label="WEBVIEW_SHOWCONTEXTMENU"/>
+  <int value="755" label="WEBRTCLOGGINGPRIVATE_STARTRTPDUMP"/>
+  <int value="756" label="WEBRTCLOGGINGPRIVATE_STOPRTPDUMP"/>
+  <int value="757" label="AUTOMATIONINTERNAL_ENABLEDESKTOP"/>
+  <int value="758" label="HOTWORDPRIVATE_SETHOTWORDSESSIONSTATE"/>
+  <int value="759" label="HOTWORDPRIVATE_NOTIFYHOTWORDRECOGNITION"/>
+  <int value="760"
+      label="FILESYSTEMPROVIDERINTERNAL_READDIRECTORYREQUESTEDSUCCESS"/>
+  <int value="761"
+      label="FILESYSTEMPROVIDERINTERNAL_READDIRECTORYREQUESTEDERROR"/>
 </enum>
 
 <enum name="ExtensionInstallCause" type="int">
@@ -34059,7 +34317,7 @@
 </enum>
 
 <enum name="FeatureObserver" type="int">
-<!-- Generated from ../../../third_party/WebKit/Source/core/frame/UseCounter.h -->
+<!-- Generated from ..\..\..\third_party\WebKit\Source\core\frame\UseCounter.h -->
 
   <int value="0" label="PageDestruction"/>
   <int value="1" label="LegacyNotifications"/>
@@ -34402,6 +34660,82 @@
   <int value="338" label="CanvasRenderingContext2DSetFillColor"/>
   <int value="339" label="CanvasRenderingContext2DDrawImageFromRect"/>
   <int value="340" label="CanvasRenderingContext2DSetShadow"/>
+  <int value="341" label="PrefixedPerformanceClearResourceTimings"/>
+  <int value="342" label="PrefixedPerformanceSetResourceTimingBufferSize"/>
+  <int value="343" label="EventSrcElement"/>
+  <int value="344" label="EventCancelBubble"/>
+  <int value="345" label="EventPath"/>
+  <int value="346" label="EventClipboardData"/>
+  <int value="347" label="NodeIteratorDetach"/>
+  <int value="348" label="AttrNodeValue"/>
+  <int value="349" label="AttrTextContent"/>
+  <int value="350" label="EventGetReturnValueTrue"/>
+  <int value="351" label="EventGetReturnValueFalse"/>
+  <int value="352" label="EventSetReturnValueTrue"/>
+  <int value="353" label="EventSetReturnValueFalse"/>
+  <int value="354" label="NodeIteratorExpandEntityReferences"/>
+  <int value="355" label="TreeWalkerExpandEntityReferences"/>
+  <int value="356" label="WindowOffscreenBuffering"/>
+  <int value="357" label="WindowDefaultStatus"/>
+  <int value="358" label="WindowDefaultstatus"/>
+  <int value="359" label="PrefixedConvertPointFromPageToNode"/>
+  <int value="360" label="PrefixedConvertPointFromNodeToPage"/>
+  <int value="361" label="PrefixedTransitionEventConstructor"/>
+  <int value="362" label="PrefixedMutationObserverConstructor"/>
+  <int value="363" label="PrefixedIDBCursorConstructor"/>
+  <int value="364" label="PrefixedIDBDatabaseConstructor"/>
+  <int value="365" label="PrefixedIDBFactoryConstructor"/>
+  <int value="366" label="PrefixedIDBIndexConstructor"/>
+  <int value="367" label="PrefixedIDBKeyRangeConstructor"/>
+  <int value="368" label="PrefixedIDBObjectStoreConstructor"/>
+  <int value="369" label="PrefixedIDBRequestConstructor"/>
+  <int value="370" label="PrefixedIDBTransactionConstructor"/>
+  <int value="371" label="NotificationPermission"/>
+  <int value="372" label="RangeDetach"/>
+  <int value="373" label="DocumentImportNodeOptionalArgument"/>
+  <int value="374" label="HTMLTableElementVspace"/>
+  <int value="375" label="HTMLTableElementHspace"/>
+  <int value="376" label="PrefixedDocumentExitPointerLock"/>
+  <int value="377" label="PrefixedDocumentPointerLockElement"/>
+  <int value="378" label="PrefixedTouchRadiusX"/>
+  <int value="379" label="PrefixedTouchRadiusY"/>
+  <int value="380" label="PrefixedTouchRotationAngle"/>
+  <int value="381" label="PrefixedTouchForce"/>
+  <int value="382" label="PrefixedMouseEventMovementX"/>
+  <int value="383" label="PrefixedMouseEventMovementY"/>
+  <int value="384" label="PrefixedWheelEventDirectionInvertedFromDevice"/>
+  <int value="385" label="PrefixedWheelEventInit"/>
+  <int value="386" label="PrefixedFileRelativePath"/>
+  <int value="387" label="DocumentCaretRangeFromPoint"/>
+  <int value="388" label="DocumentGetCSSCanvasContext"/>
+  <int value="389" label="ElementScrollIntoViewIfNeeded"/>
+  <int value="390" label="ElementScrollByLines"/>
+  <int value="391" label="ElementScrollByPages"/>
+  <int value="392" label="RangeCompareNode"/>
+  <int value="393" label="RangeExpand"/>
+  <int value="394" label="HTMLFrameElementWidth"/>
+  <int value="395" label="HTMLFrameElementHeight"/>
+  <int value="396" label="HTMLImageElementX"/>
+  <int value="397" label="HTMLImageElementY"/>
+  <int value="398" label="HTMLOptionsCollectionRemoveElement"/>
+  <int value="399" label="HTMLPreElementWrap"/>
+  <int value="400" label="SelectionBaseNode"/>
+  <int value="401" label="SelectionBaseOffset"/>
+  <int value="402" label="SelectionExtentNode"/>
+  <int value="403" label="SelectionExtentOffset"/>
+  <int value="404" label="SelectionType"/>
+  <int value="405" label="SelectionModify"/>
+  <int value="406" label="SelectionSetBaseAndExtent"/>
+  <int value="407" label="SelectionEmpty"/>
+  <int value="408" label="SVGFEMorphologyElementSetRadius"/>
+  <int value="409" label="VTTCue"/>
+  <int value="410" label="VTTCueRender"/>
+  <int value="411" label="VTTCueRenderVertical"/>
+  <int value="412" label="VTTCueRenderSnapToLinesFalse"/>
+  <int value="413" label="VTTCueRenderLineNotAuto"/>
+  <int value="414" label="VTTCueRenderPositionNot50"/>
+  <int value="415" label="VTTCueRenderSizeNot100"/>
+  <int value="416" label="VTTCueRenderAlignNotMiddle"/>
 </enum>
 
 <enum name="FFmpegCodecs" type="int">
@@ -35384,6 +35718,8 @@
   <int value="21" label="DeleteDatabase"/>
   <int value="22" label="TransactionCommit"/>
   <int value="23" label="GetDatabaseNames"/>
+  <int value="24" label="ReadBlobJournal"/>
+  <int value="25" label="DecodeBlobJournal"/>
 </enum>
 
 <enum name="IDBLevelDBBackingStoreOpenResult" type="int">
@@ -37039,6 +37375,22 @@
   <int value="3" label="kInvalidPlayerState"/>
 </enum>
 
+<enum name="MediaOutputProtectionStatus" type="int">
+  <int value="0" label="Queried"/>
+  <int value="1" label="No external link"/>
+  <int value="2" label="All external links protected"/>
+</enum>
+
+<enum name="MetaTagTypeEnum" type="int">
+  <int value="0" label="No viewport tag"/>
+  <int value="1" label="Viewport meta with device width"/>
+  <int value="2" label="Viewport meta with constant width"/>
+  <int value="4" label="Viewport meta other"/>
+  <int value="5" label="HandheldFriendly meta"/>
+  <int value="6" label="MobileOptimized meta"/>
+  <int value="7" label="XHTML-MP document type"/>
+</enum>
+
 <enum name="MigrationNssToPemNetworkTypes" type="int">
   <int value="0" label="EAP"/>
   <int value="1" label="OpenVPN"/>
@@ -37818,7 +38170,7 @@
 <enum name="NotificationActionType" type="int">
   <int value="0" label="Unknown"/>
   <int value="1" label="Notification added"/>
-  <int value="2" label="Notificaiton updated"/>
+  <int value="2" label="Notification updated"/>
   <int value="3" label="Notification clicked"/>
   <int value="4" label="Notification button clicked"/>
   <int value="5" label="Notification displayed"/>
@@ -38281,6 +38633,7 @@
   <int value="0" label="Opened automatically / Offering a password to save"/>
   <int value="1" label="Opened manually / Offering a password to save"/>
   <int value="2" label="Opened manually / Managing saved passwords"/>
+  <int value="3" label="Opened manually / Site is blacklisted"/>
 </enum>
 
 <enum name="PasswordGenerationEvent" type="int">
@@ -38733,6 +39086,7 @@
   <int value="3" label="Clicked 'Never'"/>
   <int value="4" label="Clicked 'Manage passwords'"/>
   <int value="5" label="Clicked 'Done'"/>
+  <int value="6" label="Clicked 'Enable password manager'"/>
 </enum>
 
 <enum name="PepperInterface" type="int">
@@ -39620,6 +39974,14 @@
   <int value="1" label="Secondary (user-created) profile"/>
 </enum>
 
+<enum name="ProfileUpgradeEnrollment" type="int">
+  <int value="0" label="User viewed the Upgrade promo card in the user menu."/>
+  <int value="1" label="User selected to view the intro tutorial."/>
+  <int value="2" label="User opted into New Profile Management by Promo card."/>
+  <int value="3" label="User closed the Upgrade card."/>
+  <int value="4" label="Used disabled New Profiles Management."/>
+</enum>
+
 <enum name="ProtectorError" type="int">
   <obsolete>
     Deprecated 8/2013. No longer generated.
@@ -40246,6 +40608,8 @@
   <int value="18" label="OTHER"/>
   <int value="19" label="CRX"/>
   <int value="20" label="APK"/>
+  <int value="21" label="DMG"/>
+  <int value="22" label="PKG"/>
 </enum>
 
 <enum name="SBClientDownloadIsSignedBinary" type="int">
@@ -42561,6 +42925,7 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="CertificateTypeAlgorithms" separator=".">
+  <owner>rsleevi@chromium.org</owner>
   <suffix name="DH" label="DH"/>
   <suffix name="DSA" label="DSA"/>
   <suffix name="ECDH" label="ECDH"/>
@@ -43142,6 +43507,7 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="InstantExtended_QuerytoQuery">
+  <owner>macourteau@chromium.org</owner>
   <suffix name="400" label="Omnibox width &lt; 400"/>
   <suffix name="700" label="Omnibox width &lt; 700"/>
   <suffix name="1200" label="Omnibox width &lt; 1200"/>
@@ -43326,6 +43692,7 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="Net.QuicSession.21CumulativePackets" separator="_">
+  <owner>rch@chromium.org</owner>
   <suffix name="First21"
       label="Only the first group of 21 packets in a connection via"/>
   <suffix name="Some21s"
@@ -43335,6 +43702,7 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="Net.QuicSession.6PacketPatterns" separator="_">
+  <owner>rch@chromium.org</owner>
   <suffix name="First6"
       label="Only the first group of 6 packets in a connection via"/>
   <suffix name="Some6s"
@@ -43344,6 +43712,7 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="Net.QuicSession.PacketReceived" separator="_">
+  <owner>rch@chromium.org</owner>
   <suffix name="Ack"
       label="Only packets that were received by Chrome as well being part of
              connections via"/>
@@ -43361,6 +43730,7 @@
 
 <histogram_suffixes name="Net.QuicSession.PacketReceived_CONNECTION_TYPE"
     separator="_">
+  <owner>rch@chromium.org</owner>
   <suffix name="CONNECTION_UNKNOWN" label="WiFi are tallied."/>
   <suffix name="CONNECTION_ETHERNET"
       label="ethernet are tallied, but this may include connections to a WiFi
@@ -45088,6 +45458,7 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="QuicPortSelection" separator="">
+  <owner>rch@chromium.org</owner>
   <suffix name="SelectPort"
       label="An effort was mode to (try to) consistently connect using the
              same source port for the given server IP/port."/>
@@ -45098,6 +45469,7 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="QuicRttCount" separator="">
+  <owner>rch@chromium.org</owner>
   <suffix name="ForHTTP" label="Only insecure HTTP connections are counted."/>
   <suffix name="ForHTTPS" label="Only secure HTTPS connections are counted."/>
   <affected-histogram name="Net.QuicSession.ConnectRandomPort"/>
diff --git a/tools/metrics/histograms/update_use_counter_feature_enum.py b/tools/metrics/histograms/update_use_counter_feature_enum.py
index 8bb139d..ad4de16 100755
--- a/tools/metrics/histograms/update_use_counter_feature_enum.py
+++ b/tools/metrics/histograms/update_use_counter_feature_enum.py
@@ -17,6 +17,9 @@
 from update_histogram_enum import ReadHistogramValues
 from update_histogram_enum import UpdateHistogramEnum
 
+USE_COUNTER_HEADER_PATH = \
+    '../../../third_party/WebKit/Source/core/frame/UseCounter.h'
+
 
 def print_enum_for_dashboard(enum_dict):
   """Prints enum_items formatted for use in uma.py of Chromium dashboard."""
@@ -33,19 +36,16 @@
                     'https://github.com/GoogleChrome/chromium-dashboard')
   options, args = parser.parse_args()
 
-  source_path = os.path.join(
-      '..', '..', '..',
-      'third_party', 'WebKit', 'Source', 'core', 'frame', 'UseCounter.h')
-
   START_MARKER = '^enum Feature {'
   END_MARKER = '^NumberOfFeatures'
 
   if options.dashboard:
-    enum_dict = ReadHistogramValues(source_path, START_MARKER, END_MARKER)
-    print_enum_for_dashboard(enum_items)
+    enum_dict = ReadHistogramValues(
+        USE_COUNTER_HEADER_PATH, START_MARKER, END_MARKER)
+    print_enum_for_dashboard(enum_dict)
   else:
     UpdateHistogramEnum(
         histogram_enum_name='FeatureObserver',
-        source_enum_path=source_path,
+        source_enum_path=USE_COUNTER_HEADER_PATH,
         start_marker=START_MARKER,
         end_marker=END_MARKER)
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py
index 7bba799..2e17ca9 100644
--- a/tools/perf/benchmarks/blink_perf.py
+++ b/tools/perf/benchmarks/blink_perf.py
@@ -110,15 +110,3 @@
     path = os.path.join(util.GetChromiumSrcDir(),
         'third_party', 'WebKit', 'PerformanceTests', 'Animation')
     return _CreatePageSetFromPath(path)
-
-class BlinkPerfWebAnimations(test.Test):
-  tag = 'web_animations'
-  test = _BlinkPerfMeasurement
-
-  def CreatePageSet(self, options):
-    path = os.path.join(util.GetChromiumSrcDir(),
-        'third_party', 'WebKit', 'PerformanceTests', 'Animation')
-    return _CreatePageSetFromPath(path)
-
-  def CustomizeBrowserOptions(self, options):
-    options.AppendExtraBrowserArgs('--enable-web-animations-css')
diff --git a/tools/perf/benchmarks/chrome_proxy.py b/tools/perf/benchmarks/chrome_proxy.py
index 8a04e97..5c58709 100644
--- a/tools/perf/benchmarks/chrome_proxy.py
+++ b/tools/perf/benchmarks/chrome_proxy.py
@@ -73,6 +73,18 @@
   page_set = 'page_sets/chrome_proxy/safebrowsing.py'
 
 
+class ChromeProxyHTTPFallbackProbeURL(test.Test):
+  tag = 'fallback-probe'
+  test = chrome_proxy.ChromeProxyHTTPFallbackProbeURL
+  page_set = 'page_sets/chrome_proxy/synthetic.py'
+
+
+class ChromeProxyHTTPFallbackViaHeader(test.Test):
+  tag = 'fallback-viaheader'
+  test = chrome_proxy.ChromeProxyHTTPFallbackViaHeader
+  page_set = 'page_sets/chrome_proxy/fallback_viaheader.py'
+
+
 class ChromeProxySmoke(test.Test):
   tag = 'smoke'
   test = chrome_proxy.ChromeProxySmoke
diff --git a/tools/perf/benchmarks/dromaeo.py b/tools/perf/benchmarks/dromaeo.py
index f3f11d1..eb47892 100644
--- a/tools/perf/benchmarks/dromaeo.py
+++ b/tools/perf/benchmarks/dromaeo.py
@@ -74,6 +74,7 @@
   query_param = 'dom-attr'
 
 
+@test.Disabled('xp')  # crbug.com/323782
 class DromaeoDomCoreModify(_DromaeoBenchmark):
   """Dromaeo DOMCore modify JavaScript benchmark."""
   tag = 'domcoremodify'
diff --git a/tools/perf/benchmarks/jsgamebench.py b/tools/perf/benchmarks/jsgamebench.py
index c94f754..fbb9cba 100644
--- a/tools/perf/benchmarks/jsgamebench.py
+++ b/tools/perf/benchmarks/jsgamebench.py
@@ -6,7 +6,6 @@
 
 import os
 
-from metrics import power
 from telemetry import test
 from telemetry.page import page_measurement
 from telemetry.page import page_set
@@ -15,22 +14,12 @@
 class _JsgamebenchMeasurement(page_measurement.PageMeasurement):
   def __init__(self):
     super(_JsgamebenchMeasurement, self).__init__()
-    self._power_metric = power.PowerMetric()
-
-  def CustomizeBrowserOptions(self, options):
-    power.PowerMetric.CustomizeBrowserOptions(options)
-
-  def DidNavigateToPage(self, page, tab):
-    self._power_metric.Start(page, tab)
 
   def MeasurePage(self, page, tab, results):
     tab.ExecuteJavaScript('UI.call({}, "perftest")')
     tab.WaitForJavaScriptExpression(
         'document.getElementById("perfscore0") != null', 1800)
 
-    self._power_metric.Stop(page, tab)
-    self._power_metric.AddResults(tab, results)
-
     js_get_results = 'document.getElementById("perfscore0").innerHTML'
     result = int(tab.EvaluateJavaScript(js_get_results))
     results.Add('Score', 'score (bigger is better)', result)
diff --git a/tools/perf/benchmarks/kraken.py b/tools/perf/benchmarks/kraken.py
index 985325f..0401862 100644
--- a/tools/perf/benchmarks/kraken.py
+++ b/tools/perf/benchmarks/kraken.py
@@ -28,9 +28,9 @@
     self._power_metric.Start(page, tab)
 
   def MeasurePage(self, page, tab, results):
-    tab.WaitForDocumentReadyStateToBeComplete()
     tab.WaitForJavaScriptExpression(
         'document.title.indexOf("Results") != -1', 700)
+    tab.WaitForDocumentReadyStateToBeComplete()
 
     self._power_metric.Stop(page, tab)
     self._power_metric.AddResults(tab, results)
diff --git a/tools/perf/benchmarks/memory.py b/tools/perf/benchmarks/memory.py
index 9e8b7a6..b009305 100644
--- a/tools/perf/benchmarks/memory.py
+++ b/tools/perf/benchmarks/memory.py
@@ -6,6 +6,7 @@
 from measurements import memory
 
 
+@test.Disabled('android')  # crbug.com/370977
 class MemoryMobile(test.Test):
   test = memory.Memory
   page_set = 'page_sets/mobile_memory.py'
@@ -22,6 +23,7 @@
   page_set = 'page_sets/top_desktop_sites_2012Q3.py'
 
 
+@test.Disabled('android')  # crbug.com/371153
 class MemoryToughDomMemoryCases(test.Test):
   test = memory.Memory
   page_set = 'page_sets/tough_dom_memory_cases.py'
diff --git a/tools/perf/benchmarks/page_cycler.py b/tools/perf/benchmarks/page_cycler.py
index 4aa97ae..1a62a89 100644
--- a/tools/perf/benchmarks/page_cycler.py
+++ b/tools/perf/benchmarks/page_cycler.py
@@ -61,7 +61,7 @@
   options = {'pageset_repeat': 10}
 
 
-@test.Disabled('win')  # crbug.com/353260
+@test.Disabled('linux', 'win')  # crbug.com/353260
 class PageCyclerNetsimTop10(test.Test):
   """Measures load time of the top 10 sites under simulated cable network."""
   tag = 'netsim'
@@ -95,6 +95,7 @@
   options = {'pageset_repeat': 10}
 
 
+@test.Disabled('android')  # crbug.com/357326
 class PageCyclerToughLayoutCases(test.Test):
   test = page_cycler.PageCycler
   page_set = 'page_sets/tough_layout_cases.py'
diff --git a/tools/perf/benchmarks/rasterize_and_record_micro.py b/tools/perf/benchmarks/rasterize_and_record_micro.py
index a5e88a3..fcf108c 100644
--- a/tools/perf/benchmarks/rasterize_and_record_micro.py
+++ b/tools/perf/benchmarks/rasterize_and_record_micro.py
@@ -9,7 +9,7 @@
 
 # RasterizeAndRecord disabled on mac because of crbug.com/350684.
 # RasterizeAndRecord disabled on windows because of crbug.com/338057.
-@test.Disabled('mac', 'win')
+@test.Disabled('android', 'mac', 'win')  # android tracked by crbug.com/371148
 class RasterizeAndRecordMicroTop25(test.Test):
   """Measures rasterize and record performance on the top 25 web pages.
 
@@ -18,7 +18,7 @@
   page_set = 'page_sets/top_25.py'
 
 
-@test.Disabled('mac', 'win')
+@test.Disabled('android', 'mac', 'win')  # android tracked by crbug.com/371148
 class RasterizeAndRecordMicroKeyMobileSites(test.Test):
   """Measures rasterize and record performance on the key mobile sites.
 
@@ -27,7 +27,7 @@
   page_set = 'page_sets/key_mobile_sites.py'
 
 
-@test.Disabled('mac', 'win')
+@test.Disabled('android', 'mac', 'win')
 class RasterizeAndRecordMicroKeySilkCases(test.Test):
   """Measures rasterize and record performance on the silk sites.
 
@@ -36,7 +36,7 @@
   page_set = 'page_sets/key_silk_cases.py'
 
 
-@test.Disabled('mac', 'win')
+@test.Disabled('android', 'mac', 'win')
 class RasterizeAndRecordMicroFastPathKeySilkCases(test.Test):
   """Measures rasterize and record performance on the silk sites.
 
@@ -50,7 +50,7 @@
     silk_flags.CustomizeBrowserOptionsForFastPath(options)
 
 
-@test.Disabled('mac', 'win')
+@test.Disabled('android', 'mac', 'win')
 class RasterizeAndRecordMicroFastPathGpuRasterizationKeySilkCases(test.Test):
   """Measures rasterize and record performance on the silk sites.
 
diff --git a/tools/perf/benchmarks/scheduler.py b/tools/perf/benchmarks/scheduler.py
index 881f56c..a6fb1a6 100644
--- a/tools/perf/benchmarks/scheduler.py
+++ b/tools/perf/benchmarks/scheduler.py
@@ -6,6 +6,7 @@
 from measurements import smoothness
 
 
+@test.Disabled('linux')  # crbug.com/368767
 class SchedulerToughSchedulingCases(test.Test):
   """Measures rendering statistics while interacting with pages that have
   challenging scheduling properties.
diff --git a/tools/perf/benchmarks/smoothness.py b/tools/perf/benchmarks/smoothness.py
index f4fa52d..292ed60 100644
--- a/tools/perf/benchmarks/smoothness.py
+++ b/tools/perf/benchmarks/smoothness.py
@@ -7,6 +7,7 @@
 from telemetry import test
 
 
+@test.Disabled  # crbug.com/368767
 class SmoothnessTop25(test.Test):
   """Measures rendering statistics while scrolling down the top 25 web pages.
 
@@ -15,7 +16,7 @@
   page_set = 'page_sets/top_25.py'
 
 
-@test.Disabled('mac')
+@test.Disabled('linux', 'mac', 'win')  # crbug.com/368767
 class SmoothnessToughCanvasCases(test.Test):
   test = smoothness.Smoothness
   page_set = 'page_sets/tough_canvas_cases.py'
@@ -39,12 +40,13 @@
   page_set = 'page_sets/key_mobile_sites.py'
 
 
-@test.Disabled('android')  # crbug.com/350692
+@test.Disabled('android', 'mac')  # crbug.com/350692, crbug.com/368767
 class SmoothnessToughAnimationCases(test.Test):
   test = smoothness.Smoothness
   page_set = 'page_sets/tough_animation_cases.py'
 
 
+@test.Disabled('android')  # crbug.com/355952
 class SmoothnessKeySilkCases(test.Test):
   """Measures rendering statistics for the key silk cases without GPU
   rasterization
@@ -53,6 +55,7 @@
   page_set = 'page_sets/key_silk_cases.py'
 
 
+@test.Disabled('android')  # crbug.com/355952
 class SmoothnessFastPathKeySilkCases(test.Test):
   """Measures rendering statistics for the key silk cases without GPU
   rasterization using bleeding edge rendering fast paths.
@@ -64,6 +67,7 @@
     silk_flags.CustomizeBrowserOptionsForFastPath(options)
 
 
+@test.Disabled('android')  # crbug.com/363783
 class SmoothnessGpuRasterizationTop25(test.Test):
   """Measures rendering statistics for the top 25 with GPU rasterization
   """
@@ -74,6 +78,7 @@
     silk_flags.CustomizeBrowserOptionsForGpuRasterization(options)
 
 
+@test.Disabled('android')  # crbug.com/363783
 class SmoothnessGpuRasterizationKeyMobileSites(test.Test):
   """Measures rendering statistics for the key mobile sites with GPU
   rasterization
@@ -85,6 +90,7 @@
     silk_flags.CustomizeBrowserOptionsForGpuRasterization(options)
 
 
+@test.Disabled('android')  # crbug.com/355952
 class SmoothnessGpuRasterizationKeySilkCases(test.Test):
   """Measures rendering statistics for the key silk cases with GPU rasterization
   """
@@ -95,6 +101,7 @@
     silk_flags.CustomizeBrowserOptionsForGpuRasterization(options)
 
 
+@test.Disabled('android')  # crbug.com/355952
 class SmoothnessFastPathGpuRasterizationKeySilkCases(
     SmoothnessGpuRasterizationKeySilkCases):
   """Measures rendering statistics for the key silk cases with GPU rasterization
@@ -118,7 +125,7 @@
   page_set = 'page_sets/tough_pinch_zoom_cases.py'
 
 
-@test.Enabled('android')
+@test.Disabled  # crbug.com/370725
 class SmoothnessPolymer(test.Test):
   """Measures rendering statistics for Polymer cases.
   """
@@ -126,7 +133,7 @@
   page_set = 'page_sets/polymer.py'
 
 
-@test.Enabled('android')
+@test.Disabled  # crbug.com/370725
 class SmoothnessFastPathPolymer(test.Test):
   """Measures rendering statistics for the Polymer cases without GPU
   rasterization using bleeding edge rendering fast paths.
@@ -138,7 +145,7 @@
     silk_flags.CustomizeBrowserOptionsForFastPath(options)
 
 
-@test.Enabled('android')
+@test.Disabled  # crbug.com/370725
 class SmoothnessGpuRasterizationPolymer(test.Test):
   """Measures rendering statistics for the Polymer cases with GPU rasterization
   """
@@ -149,7 +156,7 @@
     silk_flags.CustomizeBrowserOptionsForGpuRasterization(options)
 
 
-@test.Enabled('android')
+@test.Disabled  # crbug.com/370725
 class SmoothnessFastPathGpuRasterizationPolymer(
     SmoothnessGpuRasterizationPolymer):
   """Measures rendering statistics for the Polymer cases with GPU rasterization
diff --git a/tools/perf/benchmarks/spaceport.py b/tools/perf/benchmarks/spaceport.py
index f4cc522..fa16a38 100644
--- a/tools/perf/benchmarks/spaceport.py
+++ b/tools/perf/benchmarks/spaceport.py
@@ -7,7 +7,6 @@
 import logging
 import os
 
-from metrics import power
 from telemetry import test
 from telemetry.core import util
 from telemetry.page import page_measurement
@@ -17,22 +16,14 @@
 class _SpaceportMeasurement(page_measurement.PageMeasurement):
   def __init__(self):
     super(_SpaceportMeasurement, self).__init__()
-    self._power_metric = power.PowerMetric()
 
   def CustomizeBrowserOptions(self, options):
     options.AppendExtraBrowserArgs('--disable-gpu-vsync')
-    power.PowerMetric.CustomizeBrowserOptions(options)
-
-  def DidNavigateToPage(self, page, tab):
-    self._power_metric.Start(page, tab)
 
   def MeasurePage(self, page, tab, results):
     tab.WaitForJavaScriptExpression(
         '!document.getElementById("start-performance-tests").disabled', 60)
 
-    self._power_metric.Stop(page, tab)
-    self._power_metric.AddResults(tab, results)
-
     tab.ExecuteJavaScript("""
         window.__results = {};
         window.console.log = function(str) {
diff --git a/tools/perf/benchmarks/thread_times.py b/tools/perf/benchmarks/thread_times.py
index a1fcd53..00e49bb 100644
--- a/tools/perf/benchmarks/thread_times.py
+++ b/tools/perf/benchmarks/thread_times.py
@@ -7,6 +7,7 @@
 from measurements import thread_times
 
 
+@test.Disabled('android')  # crbug.com/355952
 class ThreadTimesKeySilkCases(test.Test):
   """Measures timeline metrics while performing smoothness action on key silk
   cases."""
@@ -15,6 +16,7 @@
   options = {"report_silk_results": True}
 
 
+@test.Disabled('android')  # crbug.com/355952
 class ThreadTimesFastPathKeySilkCases(test.Test):
   """Measures timeline metrics while performing smoothness action on key silk
   cases using bleeding edge rendering fast paths."""
@@ -53,4 +55,4 @@
   Polymer cases."""
   test = thread_times.ThreadTimes
   page_set = "page_sets/polymer.py"
-  options = { 'report_silk_results': True }
\ No newline at end of file
+  options = { 'report_silk_results': True }
diff --git a/tools/perf/measurements/chrome_proxy.py b/tools/perf/measurements/chrome_proxy.py
index 7a2b441..b1c5084 100644
--- a/tools/perf/measurements/chrome_proxy.py
+++ b/tools/perf/measurements/chrome_proxy.py
@@ -1,7 +1,10 @@
 # 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.
+
+import base64
 import logging
+import urlparse
 
 from metrics import chrome_proxy
 from metrics import loading
@@ -123,6 +126,94 @@
     self._metrics.AddResultsForSafebrowsing(tab, results)
 
 
+_FAKE_PROXY_AUTH_VALUE = 'aabbccdd3b7579186c1b0620614fdb1f0000ffff'
+_TEST_SERVER = 'chromeproxy-test.appspot.com'
+_TEST_SERVER_DEFAULT_URL = 'http://' + _TEST_SERVER + '/default'
+
+
+# We rely on the chromeproxy-test server to facilitate some of the tests.
+# The test server code is at <TBD location> and runs at _TEST_SERVER
+#
+# The test server allow request to override response status, headers, and
+# body through query parameters. See GetResponseOverrideURL.
+def GetResponseOverrideURL(url, respStatus=0, respHeader="", respBody=""):
+  """ Compose the request URL with query parameters to override
+  the chromeproxy-test server response.
+  """
+
+  queries = []
+  if respStatus > 0:
+    queries.append('respStatus=%d' % respStatus)
+  if respHeader:
+    queries.append('respHeader=%s' % base64.b64encode(respHeader))
+  if respBody:
+    queries.append('respBody=%s' % base64.b64encode(respBody))
+  if len(queries) == 0:
+    return url
+  "&".join(queries)
+  # url has query already
+  if urlparse.urlparse(url).query:
+    return url + '&' + "&".join(queries)
+  else:
+    return url + '?' + "&".join(queries)
+
+
+class ChromeProxyHTTPFallbackProbeURL(ChromeProxyValidation):
+  """Correctness measurement for proxy fallback.
+
+  In this test, the probe URL does not return 'OK'. Chrome is expected
+  to use the fallback proxy.
+  """
+
+  def __init__(self):
+    super(ChromeProxyHTTPFallbackProbeURL, self).__init__()
+
+  def CustomizeBrowserOptions(self, options):
+    super(ChromeProxyHTTPFallbackProbeURL,
+          self).CustomizeBrowserOptions(options)
+    # Use the test server probe URL which returns the response
+    # body as specified by respBody.
+    probe_url = GetResponseOverrideURL(
+        _TEST_SERVER_DEFAULT_URL,
+        respBody='not OK')
+    options.AppendExtraBrowserArgs(
+        '--data-reduction-proxy-probe-url=%s' % probe_url)
+
+  def AddResults(self, tab, results):
+    self._metrics.AddResultsForHTTPFallback(tab, results)
+
+
+# Depends on the fix of http://crbug.com/330342.
+class ChromeProxyHTTPFallbackViaHeader(ChromeProxyValidation):
+  """Correctness measurement for proxy fallback.
+
+  In this test, the configured proxy is the chromeproxy-test server which
+  will send back a response without the expected Via header. Chrome is
+  expected to use the fallback proxy and add the configured proxy to the
+  bad proxy list.
+  """
+
+  def __init__(self):
+    super(ChromeProxyHTTPFallbackViaHeader, self).__init__()
+
+  def CustomizeBrowserOptions(self, options):
+    super(ChromeProxyHTTPFallbackViaHeader,
+          self).CustomizeBrowserOptions(options)
+    options.AppendExtraBrowserArgs('--ignore-certificate-errors')
+    options.AppendExtraBrowserArgs(
+        '--spdy-proxy-auth-origin=http://%s' % _TEST_SERVER)
+    options.AppendExtraBrowserArgs(
+        '--spdy-proxy-auth-value=%s' % _FAKE_PROXY_AUTH_VALUE)
+
+  def AddResults(self, tab, results):
+    proxies = [
+        _TEST_SERVER + ":80",
+        self._metrics.effective_proxies['fallback'],
+        self._metrics.effective_proxies['direct']]
+    bad_proxies = [_TEST_SERVER + ":80"]
+    self._metrics.AddResultsForHTTPFallback(tab, results, proxies, bad_proxies)
+
+
 class ChromeProxySmoke(ChromeProxyValidation):
   """Smoke measurement for basic chrome proxy correctness."""
 
diff --git a/tools/perf/measurements/measurement_unittest.py b/tools/perf/measurements/measurement_unittest.py
index 8386be3..7fbcad0 100644
--- a/tools/perf/measurements/measurement_unittest.py
+++ b/tools/perf/measurements/measurement_unittest.py
@@ -15,7 +15,7 @@
 class MeasurementUnitTest(unittest.TestCase):
 
   # TODO(achuith): Fix crbug.com/351114.
-  @test.Disabled('android', 'chromeos')
+  @test.Disabled('android', 'chromeos', 'win')
   def testMeasurementSmoke(self):
     # Run all Measurements against the first Page in the PageSet of the first
     # Benchmark that uses them.
diff --git a/tools/perf/measurements/page_cycler.py b/tools/perf/measurements/page_cycler.py
index b7dffbc..c57f254 100644
--- a/tools/perf/measurements/page_cycler.py
+++ b/tools/perf/measurements/page_cycler.py
@@ -81,15 +81,11 @@
       tab.ClearCache(force=True)
     if self._report_speed_index:
       self._speedindex_metric.Start(page, tab)
+    self._cpu_metric.Start(page, tab)
 
   def DidNavigateToPage(self, page, tab):
     self._memory_metric.Start(page, tab)
     self._power_metric.Start(page, tab)
-    # TODO(qyearsley): Uncomment the following line and move it to
-    # WillNavigateToPage once the cpu metric has been changed.
-    # This is being temporarily commented out to let the page cycler
-    # results return to how they were before the cpu metric was added.
-    # self._cpu_metric.Start(page, tab) See crbug.com/301714.
     if self._record_v8_object_stats:
       self._v8_object_stats_metric.Start(page, tab)
 
@@ -142,10 +138,8 @@
     self._memory_metric.AddResults(tab, results)
     self._power_metric.AddResults(tab, results)
 
-    # TODO(qyearsley): Uncomment the following line when CPU metric is
-    # changed. See crbug.com/301714.
-    # self._cpu_metric.Stop(page, tab)
-    # self._cpu_metric.AddResults(tab, results)
+    self._cpu_metric.Stop(page, tab)
+    self._cpu_metric.AddResults(tab, results)
     if self._record_v8_object_stats:
       self._v8_object_stats_metric.Stop(page, tab)
       self._v8_object_stats_metric.AddResults(tab, results)
diff --git a/tools/perf/measurements/page_cycler_unittest.py b/tools/perf/measurements/page_cycler_unittest.py
index 5923b3f..e797f2a 100644
--- a/tools/perf/measurements/page_cycler_unittest.py
+++ b/tools/perf/measurements/page_cycler_unittest.py
@@ -53,6 +53,22 @@
     pass
 
 
+class FakeBrowser(object):
+  _iteration = 0
+
+  @property
+  def cpu_stats(self):
+    FakeBrowser._iteration += 1
+    return {
+        'Browser': {'CpuProcessTime': FakeBrowser._iteration,
+                    'TotalTime': FakeBrowser._iteration * 2},
+        'Renderer': {'CpuProcessTime': FakeBrowser._iteration,
+                    'TotalTime': FakeBrowser._iteration * 3},
+        'Gpu': {'CpuProcessTime': FakeBrowser._iteration,
+                 'TotalTime': FakeBrowser._iteration * 4}
+    }
+
+
 class PageCyclerUnitTest(unittest.TestCase):
 
   def SetUpCycler(self, args, setup_memory_module=False):
@@ -79,7 +95,7 @@
       real_memory_module = page_cycler.memory
       try:
         page_cycler.memory = mock_memory_module
-        cycler.DidStartBrowser(None)
+        cycler.DidStartBrowser(FakeBrowser())
       finally:
         page_cycler.memory = real_memory_module
 
@@ -106,7 +122,7 @@
                                '--cold-load-percent=50'],
                               True)
 
-    url_name = "http://fakepage.com"
+    url_name = 'http://fakepage.com'
     page = FakePage(url_name)
     tab = FakeTab()
     results = page_measurement_results.PageMeasurementResults()
@@ -114,7 +130,7 @@
     for i in range(5):
       cycler.WillNavigateToPage(page, tab)
       self.assertEqual(max(0, i - 2), tab.clear_cache_calls,
-                       "Iteration %d tab.clear_cache_calls %d" %
+                       'Iteration %d tab.clear_cache_calls %d' %
                        (i, tab.clear_cache_calls))
       results.WillMeasurePage(page)
       cycler.MeasurePage(page, tab, results)
@@ -122,9 +138,9 @@
       values = results.page_specific_values_for_current_page
       results.DidMeasurePage()
 
-      self.assertEqual(1, len(values))
-      self.assertEqual(values[0].page, page)
+      self.assertGreater(len(values), 2)
 
+      self.assertEqual(values[0].page, page)
       chart_name = 'cold_times' if i == 0 or i > 2 else 'warm_times'
       self.assertEqual(values[0].name, '%s.page_load_time' % chart_name)
       self.assertEqual(values[0].units, 'ms')
@@ -133,7 +149,7 @@
 
   def testColdWarm(self):
     cycler = self.SetUpCycler(['--pageset-repeat=3'], True)
-    pages = [FakePage("http://fakepage1.com"), FakePage("http://fakepage2.com")]
+    pages = [FakePage('http://fakepage1.com'), FakePage('http://fakepage2.com')]
     tab = FakeTab()
     results = page_measurement_results.PageMeasurementResults()
     for i in range(3):
@@ -145,10 +161,44 @@
         values = results.page_specific_values_for_current_page
         results.DidMeasurePage()
 
-        self.assertEqual(1, len(values))
+        self.assertGreater(len(values), 2)
+
         self.assertEqual(values[0].page, page)
 
         chart_name = 'cold_times' if i == 0 or i > 1 else 'warm_times'
         self.assertEqual(values[0].name, '%s.page_load_time' % chart_name)
+        self.assertEqual(values[0].units, 'ms')
+
+        cycler.DidNavigateToPage(page, tab)
+
+  def testResults(self):
+    cycler = self.SetUpCycler([], True)
+
+    pages = [FakePage('http://fakepage1.com'), FakePage('http://fakepage2.com')]
+    tab = FakeTab()
+    results = page_measurement_results.PageMeasurementResults()
+
+    for i in range(2):
+      for page in pages:
+        cycler.WillNavigateToPage(page, tab)
+        results.WillMeasurePage(page)
+        cycler.MeasurePage(page, tab, results)
+
+        values = results.page_specific_values_for_current_page
+        results.DidMeasurePage()
+
+        self.assertEqual(4, len(values))
+
+        self.assertEqual(values[0].page, page)
+        chart_name = 'cold_times' if i == 0 else 'warm_times'
+        self.assertEqual(values[0].name, '%s.page_load_time' % chart_name)
+        self.assertEqual(values[0].units, 'ms')
+
+        for value, expected in zip(values[1:], ['gpu', 'renderer', 'browser']):
+          self.assertEqual(value.page, page)
+          self.assertEqual(value.name,
+                           'cpu_utilization.cpu_utilization_%s' % expected)
+          self.assertEqual(value.units, '%')
+
 
         cycler.DidNavigateToPage(page, tab)
diff --git a/tools/perf/measurements/polymer_load.py b/tools/perf/measurements/polymer_load.py
index d7edf3d..d6c322b 100644
--- a/tools/perf/measurements/polymer_load.py
+++ b/tools/perf/measurements/polymer_load.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_measurement
 
 
-class PageForPolymerLoad(page.PageWithDefaultRunNavigate):
+class PageForPolymerLoad(page.Page):
 
   def __init__(self, url, page_set):
     super(PageForPolymerLoad, self).__init__(
diff --git a/tools/perf/measurements/record_per_area.py b/tools/perf/measurements/record_per_area.py
index 5eccaf8..ef7686a 100644
--- a/tools/perf/measurements/record_per_area.py
+++ b/tools/perf/measurements/record_per_area.py
@@ -4,7 +4,7 @@
 
 import time
 
-from metrics import smoothness
+from measurements import smoothness
 from telemetry.page import page_measurement
 
 class RecordPerArea(page_measurement.PageMeasurement):
@@ -18,7 +18,7 @@
                       '(must be long enought to load all content)')
 
   def CustomizeBrowserOptions(self, options):
-    smoothness.SmoothnessMetrics.CustomizeBrowserOptions(options)
+    smoothness.Smoothness.CustomizeBrowserOptions(options)
     options.AppendExtraBrowserArgs([
         '--enable-impl-side-painting',
         '--force-compositing-mode',
diff --git a/tools/perf/measurements/record_per_area_unittest.py b/tools/perf/measurements/record_per_area_unittest.py
new file mode 100644
index 0000000..127b003
--- /dev/null
+++ b/tools/perf/measurements/record_per_area_unittest.py
@@ -0,0 +1,30 @@
+# 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.
+
+from measurements import record_per_area
+from telemetry import test
+from telemetry.core import wpr_modes
+from telemetry.page import page_measurement_unittest_base
+from telemetry.unittest import options_for_unittests
+
+
+class RecordPerAreaUnitTest(
+      page_measurement_unittest_base.PageMeasurementUnitTestBase):
+  """Smoke test for record_per_area measurement
+
+     Runs record_per_area measurement on a simple page and verifies
+     that all metrics were added to the results. The test is purely functional,
+     i.e. it only checks if the metrics are present and non-zero.
+  """
+
+  def setUp(self):
+    self._options = options_for_unittests.GetCopy()
+    self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
+
+  @test.Disabled('android')
+  def testRecordPerArea(self):
+    ps = self.CreatePageSetFromFileInUnittestDataDir('scrollable_page.html')
+    measurement = record_per_area.RecordPerArea()
+    results = self.RunMeasurement(measurement, ps, options=self._options)
+    self.assertEquals(0, len(results.failures))
diff --git a/tools/perf/measurements/repaint_unittest.py b/tools/perf/measurements/repaint_unittest.py
index d752d40..26989a9 100644
--- a/tools/perf/measurements/repaint_unittest.py
+++ b/tools/perf/measurements/repaint_unittest.py
@@ -12,7 +12,7 @@
 from telemetry.unittest import options_for_unittests
 
 
-class TestRepaintPage(page_module.PageWithDefaultRunNavigate):
+class TestRepaintPage(page_module.Page):
   def __init__(self, page_set, base_dir):
     super(TestRepaintPage, self).__init__('file://blank.html',
                                           page_set, base_dir)
@@ -34,7 +34,7 @@
     self._options = options_for_unittests.GetCopy()
     self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
 
-  @test.Disabled('android')
+  @test.Disabled  # http://crbug.com/368767
   def testRepaint(self):
     ps = self.CreateEmptyPageSet()
     ps.AddPage(TestRepaintPage(ps, ps.base_dir))
diff --git a/tools/perf/measurements/session_restore.py b/tools/perf/measurements/session_restore.py
index fffabcd..ff210b4 100644
--- a/tools/perf/measurements/session_restore.py
+++ b/tools/perf/measurements/session_restore.py
@@ -6,7 +6,7 @@
 from measurements import startup
 from metrics import cpu
 from metrics import startup_metric
-
+from telemetry.core import util
 
 class SessionRestore(startup.Startup):
   """Performs a measurement of Chromium's Session restore performance.
@@ -27,6 +27,11 @@
         '--restore-last-session'
     ])
 
+  def TabForPage(self, page, browser):
+    # Detect that the session restore has completed.
+    util.WaitFor(lambda: len(browser.tabs), 30)
+    return browser.tabs[0]
+
   def CanRunForPage(self, page):
     # No matter how many pages in the pageset, just perform one test iteration.
     return page.page_set.pages.index(page) == 0
@@ -54,9 +59,9 @@
     self._cpu_metric.Start(None, None)
 
   def MeasurePage(self, page, tab, results):
-
     tab.browser.foreground_tab.WaitForDocumentReadyStateToBeComplete()
-    # Record CPU usage from browser start to when all pages have loaded.
+
+    # Record CPU usage from browser start to when the foreground page is loaded.
     self._cpu_metric.Stop(None, None)
     self._cpu_metric.AddResults(tab, results, 'cpu_utilization')
 
diff --git a/tools/perf/measurements/smoothness.py b/tools/perf/measurements/smoothness.py
index e9cdcc2..9ca784c 100644
--- a/tools/perf/measurements/smoothness.py
+++ b/tools/perf/measurements/smoothness.py
@@ -13,7 +13,8 @@
     self._power_metric = None
     self._smoothness_controller = None
 
-  def CustomizeBrowserOptions(self, options):
+  @classmethod
+  def CustomizeBrowserOptions(cls, options):
     options.AppendExtraBrowserArgs('--enable-gpu-benchmarking')
     options.AppendExtraBrowserArgs('--touch-events=enabled')
     power.PowerMetric.CustomizeBrowserOptions(options)
diff --git a/tools/perf/measurements/smoothness_controller.py b/tools/perf/measurements/smoothness_controller.py
index c80834f..af663f8 100644
--- a/tools/perf/measurements/smoothness_controller.py
+++ b/tools/perf/measurements/smoothness_controller.py
@@ -1,13 +1,14 @@
 # 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.
+import sys
 
 from measurements import smooth_gesture_util
-from metrics import smoothness
 from telemetry.core.timeline.model import TimelineModel
 from telemetry.page import page_measurement
 from telemetry.page.actions import action_runner
 from telemetry.web_perf import timeline_interaction_record as tir_module
+from telemetry.web_perf.metrics import smoothness
 
 
 RUN_SMOOTH_ACTIONS = 'RunSmoothAllActions'
@@ -21,6 +22,7 @@
 class SmoothnessController(object):
   def __init__(self):
     self._timeline_model = None
+    self._tracing_timeline_data = None
 
   def Start(self, page, tab):
     custom_categories = ['webkit.console', 'benchmark']
@@ -39,8 +41,9 @@
     # Stop tracing for smoothness metric.
     if tab.browser.platform.IsRawDisplayFrameRateSupported():
       tab.browser.platform.StopRawDisplayFrameRateMeasurement()
-    tracing_timeline_data = tab.browser.StopTracing()
-    self._timeline_model = TimelineModel(timeline_data=tracing_timeline_data)
+    self._tracing_timeline_data = tab.browser.StopTracing()
+    self._timeline_model = TimelineModel(
+      timeline_data=self._tracing_timeline_data)
 
   def AddResults(self, tab, results):
     # Add results of smoothness metric. This computes the smoothness metric for
@@ -69,10 +72,14 @@
     # TODO(nednguyen): when crbug.com/239179 is marked fixed, makes sure that
     # page sets are responsible for issueing the markers themselves.
     if len(smooth_records) == 0:
-      assert run_smooth_actions_record, (
-        'SmoothnessController fails to issue markers for the whole '
-        'interaction.')
-      smooth_records = [run_smooth_actions_record]
+      if run_smooth_actions_record is None:
+        sys.stderr.write('Raw tracing data:\n')
+        sys.stderr.write(repr(self._tracing_timeline_data.EventData()))
+        sys.stderr.write('\n')
+        raise Exception('SmoothnessController failed to issue markers for the '
+                        'whole interaction.')
+      else:
+        smooth_records = [run_smooth_actions_record]
 
     # Create an interaction_record for this legacy measurement. Since we don't
     # wrap the results that is sent to smoothnes metric, the logical_name will
diff --git a/tools/perf/measurements/smoothness_unittest.py b/tools/perf/measurements/smoothness_unittest.py
index 7722a5c..0aba865 100644
--- a/tools/perf/measurements/smoothness_unittest.py
+++ b/tools/perf/measurements/smoothness_unittest.py
@@ -7,6 +7,8 @@
 from telemetry.core import wpr_modes
 from telemetry.page import page
 from telemetry.page import page_measurement_unittest_base
+# pylint: disable=W0401,W0614
+from telemetry.page.actions.all_page_actions import *
 from telemetry.unittest import options_for_unittests
 
 class FakePlatform(object):
@@ -25,6 +27,16 @@
     self.category_filter = category_filter
 
 
+class AnimatedPage(page.Page):
+  def __init__(self, page_set):
+    super(AnimatedPage, self).__init__(
+      url='file://animated_page.html',
+      page_set=page_set, base_dir=page_set.base_dir)
+
+  def RunSmoothness(self, action_runner):
+    action_runner.RunAction(WaitAction({'seconds': 1}))
+
+
 class FakeTab(object):
   def __init__(self):
     self.browser = FakeBrowser()
@@ -109,8 +121,9 @@
           mean_touch_scroll_latency[0].GetRepresentativeNumber(), 0)
 
   def testSmoothnessForPageWithNoGesture(self):
-    ps = self.CreatePageSetFromFileInUnittestDataDir('animated_page.html')
-    setattr(ps.pages[0], 'RunSmoothness', {'action': 'wait', 'seconds' : 1})
+    ps = self.CreateEmptyPageSet()
+    ps.AddPage(AnimatedPage(ps))
+
     measurement = smoothness.Smoothness()
     results = self.RunMeasurement(measurement, ps, options=self._options)
     self.assertEquals(0, len(results.failures))
diff --git a/tools/perf/measurements/thread_times.py b/tools/perf/measurements/thread_times.py
index 3f106fc..60423d2 100644
--- a/tools/perf/measurements/thread_times.py
+++ b/tools/perf/measurements/thread_times.py
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 from measurements import timeline_controller
 from metrics import timeline
+from telemetry.core.backends.chrome import tracing_backend
 from telemetry.page import page_measurement
 
 class ThreadTimes(page_measurement.PageMeasurement):
@@ -26,10 +27,10 @@
     if self.options.report_silk_details:
       # We need the other traces in order to have any details to report.
       self.timeline_controller.trace_categories = \
-          timeline_controller.DEFAULT_TRACE_CATEGORIES
+          tracing_backend.DEFAULT_TRACE_CATEGORIES
     else:
       self._timeline_controller.trace_categories = \
-          timeline_controller.MINIMAL_TRACE_CATEGORIES
+          tracing_backend.MINIMAL_TRACE_CATEGORIES
     self._timeline_controller.Start(page, tab)
 
   def DidRunActions(self, page, tab):
diff --git a/tools/perf/measurements/thread_times_unittest.py b/tools/perf/measurements/thread_times_unittest.py
index 132a8c4..cc27498 100644
--- a/tools/perf/measurements/thread_times_unittest.py
+++ b/tools/perf/measurements/thread_times_unittest.py
@@ -3,13 +3,16 @@
 # found in the LICENSE file.
 
 from measurements import thread_times
+from measurements import smoothness_unittest
 from metrics import timeline
 from telemetry import test
 from telemetry.core import wpr_modes
 from telemetry.page import page_measurement_unittest_base
+
 from telemetry.unittest import options_for_unittests
 
 
+
 class ThreadTimesUnitTest(
       page_measurement_unittest_base.PageMeasurementUnitTestBase):
   def setUp(self):
@@ -30,8 +33,8 @@
       self.assertEquals(len(cpu_time), 1)
 
   def testBasicForPageWithNoGesture(self):
-    ps = self.CreatePageSetFromFileInUnittestDataDir('animated_page.html')
-    setattr(ps.pages[0], 'RunSmoothness', {'action': 'wait', 'seconds' : 1})
+    ps = self.CreateEmptyPageSet()
+    ps.AddPage(smoothness_unittest.AnimatedPage(ps))
 
     measurement = thread_times.ThreadTimes()
     timeline_options = self._options
diff --git a/tools/perf/measurements/timeline_based_measurement.py b/tools/perf/measurements/timeline_based_measurement.py
deleted file mode 100644
index 5194c38..0000000
--- a/tools/perf/measurements/timeline_based_measurement.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# 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.
-
-from measurements import timeline_controller
-from telemetry.web_perf import timeline_interaction_record as tir_module
-from metrics import smoothness
-from telemetry.page import page_measurement
-from telemetry.core.timeline import model as model_module
-
-
-# TimelineBasedMeasurement considers all instrumentation as producing a single
-# timeline. But, depending on the amount of instrumentation that is enabled,
-# overhead increases. The user of the measurement must therefore chose between
-# a few levels of instrumentation.
-NO_OVERHEAD_LEVEL = 'no-overhead'
-MINIMAL_OVERHEAD_LEVEL = 'minimal-overhead'
-DEBUG_OVERHEAD_LEVEL = 'debug-overhead'
-
-ALL_OVERHEAD_LEVELS = [
-  NO_OVERHEAD_LEVEL,
-  MINIMAL_OVERHEAD_LEVEL,
-  DEBUG_OVERHEAD_LEVEL
-]
-
-
-class _ResultsWrapper(object):
-  def __init__(self, results, interaction_record):
-    self._results = results
-    self._interaction_record = interaction_record
-
-  def Add(self, trace_name, units, value, chart_name=None, data_type='default'):
-    trace_name = self._interaction_record.GetResultNameFor(trace_name)
-    self._results.Add(trace_name, units, value, chart_name, data_type)
-
-  def AddSummary(self, trace_name, units, value, chart_name=None,
-                  data_type='default'):
-    trace_name = self._interaction_record.GetResultNameFor(trace_name)
-    self._results.AddSummary(trace_name, units, value, chart_name, data_type)
-
-
-class _TimelineBasedMetrics(object):
-  def __init__(self, model, renderer_thread,
-               create_metrics_for_interaction_record_callback):
-    self._model = model
-    self._renderer_thread = renderer_thread
-    self._create_metrics_for_interaction_record_callback = \
-        create_metrics_for_interaction_record_callback
-
-  def FindTimelineInteractionRecords(self):
-    # TODO(nduca): Add support for page-load interaction record.
-    return [tir_module.TimelineInteractionRecord.FromEvent(event) for
-            event in self._renderer_thread.async_slices
-            if tir_module.IsTimelineInteractionRecord(event.name)]
-
-
-  def AddResults(self, results):
-    interactions = self.FindTimelineInteractionRecords()
-    if len(interactions) == 0:
-      raise Exception('Expected at least one Interaction on the page')
-    for interaction in interactions:
-      metrics = \
-          self._create_metrics_for_interaction_record_callback(interaction)
-      wrapped_results = _ResultsWrapper(results, interaction)
-      for m in metrics:
-        m.AddResults(self._model, self._renderer_thread,
-                     [interaction], wrapped_results)
-
-
-class TimelineBasedMeasurement(page_measurement.PageMeasurement):
-  """Collects multiple metrics pages based on their interaction records.
-
-  A timeline measurement shifts the burden of what metrics to collect onto the
-  page under test, or the pageset running that page. Instead of the measurement
-  having a fixed set of values it collects about the page, the page being tested
-  issues (via javascript) an Interaction record into the user timing API that
-  describing what the page is doing at that time, as well as a standardized set
-  of flags describing the semantics of the work being done. The
-  TimelineBasedMeasurement object collects a trace that includes both these
-  interaction recorsd, and a user-chosen amount of performance data using
-  Telemetry's various timeline-producing APIs, tracing especially.
-
-  It then passes the recorded timeline to different TimelineBasedMetrics based
-  on those flags. This allows a single run through a page to produce load timing
-  data, smoothness data, critical jank information and overall cpu usage
-  information.
-
-  For information on how to mark up a page to work with
-  TimelineBasedMeasurement, refer to the
-  perf.metrics.timeline_interaction_record module.
-
-  """
-  def __init__(self):
-    super(TimelineBasedMeasurement, self).__init__('RunSmoothness')
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser):
-    parser.add_option(
-        '--overhead-level', type='choice',
-        choices=ALL_OVERHEAD_LEVELS,
-        default=NO_OVERHEAD_LEVEL,
-        help='How much overhead to incur during the measurement.')
-
-  def WillNavigateToPage(self, page, tab):
-    if not tab.browser.supports_tracing:
-      raise Exception('Not supported')
-    assert self.options.overhead_level in ALL_OVERHEAD_LEVELS
-    if self.options.overhead_level == NO_OVERHEAD_LEVEL:
-      categories = timeline_controller.MINIMAL_TRACE_CATEGORIES
-    elif self.options.overhead_level == \
-        MINIMAL_OVERHEAD_LEVEL:
-      categories = ''
-    else:
-      categories = '*,disabled-by-default-cc.debug'
-    categories = ','.join([categories] + page.GetSyntheticDelayCategories())
-    tab.browser.StartTracing(categories)
-
-  def CreateMetricsForTimelineInteractionRecord(self, interaction):
-    """ Subclass of TimelineBasedMeasurement overrides this method to customize
-    the binding of interaction's flags to metrics.
-    """
-    res = []
-    if interaction.is_smooth:
-      res.append(smoothness.SmoothnessMetric())
-    return res
-
-  def MeasurePage(self, page, tab, results):
-    """ Collect all possible metrics and added them to results. """
-    trace_result = tab.browser.StopTracing()
-    model = model_module.TimelineModel(trace_result)
-    renderer_thread = model.GetRendererThreadFromTab(tab)
-    meta_metrics = _TimelineBasedMetrics(
-      model, renderer_thread, self.CreateMetricsForTimelineInteractionRecord)
-    meta_metrics.AddResults(results)
-
-  def CleanUpAfterPage(self, page, tab):
-    if tab.browser.is_tracing_running:
-      tab.browser.StopTracing()
diff --git a/tools/perf/measurements/timeline_based_measurement_unittest.py b/tools/perf/measurements/timeline_based_measurement_unittest.py
deleted file mode 100644
index eec9adb..0000000
--- a/tools/perf/measurements/timeline_based_measurement_unittest.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# 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.
-
-import os
-import unittest
-
-from measurements import timeline_based_measurement as tbm_module
-from metrics import timeline_based_metric
-from telemetry import test
-from telemetry.core import wpr_modes
-from telemetry.core.timeline import model as model_module
-from telemetry.core.timeline import async_slice
-from telemetry.page import page_measurement_results
-from telemetry.page import page_measurement_unittest_base
-from telemetry.page import page_set
-from telemetry.unittest import options_for_unittests
-
-class TimelineBasedMetricsTests(unittest.TestCase):
-  def setUp(self):
-    model = model_module.TimelineModel()
-    renderer_thread = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    renderer_thread.name = 'CrRendererMain'
-
-    # [      X       ]
-    #      [  Y  ]
-    renderer_thread.BeginSlice('cat1', 'x.y', 10, 0)
-    renderer_thread.EndSlice(20, 20)
-
-    renderer_thread.async_slices.append(async_slice.AsyncSlice(
-        'cat', 'Interaction.LogicalName1/is_smooth',
-        timestamp=0, duration=20,
-        start_thread=renderer_thread, end_thread=renderer_thread))
-    renderer_thread.async_slices.append(async_slice.AsyncSlice(
-        'cat', 'Interaction.LogicalName2/is_loading_resources',
-        timestamp=25, duration=5,
-        start_thread=renderer_thread, end_thread=renderer_thread))
-    model.FinalizeImport()
-
-    self.model = model
-    self.renderer_thread = renderer_thread
-
-  def testFindTimelineInteractionRecords(self):
-    metric = tbm_module._TimelineBasedMetrics( # pylint: disable=W0212
-      self.model, self.renderer_thread, lambda _: [] )
-    interactions = metric.FindTimelineInteractionRecords()
-    self.assertEquals(2, len(interactions))
-    self.assertTrue(interactions[0].is_smooth)
-    self.assertEquals(0, interactions[0].start)
-    self.assertEquals(20, interactions[0].end)
-
-    self.assertTrue(interactions[1].is_loading_resources)
-    self.assertEquals(25, interactions[1].start)
-    self.assertEquals(30, interactions[1].end)
-
-  def testAddResults(self):
-    results = page_measurement_results.PageMeasurementResults()
-    class FakeSmoothMetric(timeline_based_metric.TimelineBasedMetric):
-      def AddResults(self, model, renderer_thread,
-                     interaction_records, results):
-        results.Add('FakeSmoothMetric', 'ms', 1)
-
-    class FakeLoadingMetric(timeline_based_metric.TimelineBasedMetric):
-      def AddResults(self, model, renderer_thread,
-                     interaction_records, results):
-        for r in interaction_records:
-          assert r.logical_name == 'LogicalName2'
-        results.Add('FakeLoadingMetric', 'ms', 2)
-
-    def CreateMetricsForTimelineInteractionRecord(interaction):
-      res = []
-      if interaction.is_smooth:
-        res.append(FakeSmoothMetric())
-      if interaction.is_loading_resources:
-        res.append(FakeLoadingMetric())
-      return res
-
-    metric = tbm_module._TimelineBasedMetrics( # pylint: disable=W0212
-        self.model, self.renderer_thread,
-        CreateMetricsForTimelineInteractionRecord)
-    ps = page_set.PageSet(file_path=os.path.dirname(__file__))
-    ps.AddPageWithDefaultRunNavigate('http://www.bar.com/')
-
-    results.WillMeasurePage(ps.pages[0])
-    metric.AddResults(results)
-    results.DidMeasurePage()
-
-    v = results.FindAllPageSpecificValuesNamed('LogicalName1-FakeSmoothMetric')
-    self.assertEquals(len(v), 1)
-    v = results.FindAllPageSpecificValuesNamed('LogicalName2-FakeLoadingMetric')
-    self.assertEquals(len(v), 1)
-
-
-class TimelineBasedMeasurementTest(
-      page_measurement_unittest_base.PageMeasurementUnitTestBase):
-  def setUp(self):
-    self._options = options_for_unittests.GetCopy()
-    self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
-
-  # Disabled due to flakiness: crbug.com/368386
-  @test.Disabled
-  def testTimelineBasedForSmoke(self):
-    ps = self.CreatePageSetFromFileInUnittestDataDir(
-        'interaction_enabled_page.html')
-    setattr(ps.pages[0], 'RunSmoothness', {'action': 'wait',
-                                        'javascript': 'window.animationDone'})
-    measurement = tbm_module.TimelineBasedMeasurement()
-    results = self.RunMeasurement(measurement, ps,
-                                  options=self._options)
-    self.assertEquals(0, len(results.failures))
-    v = results.FindAllPageSpecificValuesNamed('CenterAnimation-jank')
-    self.assertEquals(len(v), 1)
-    v = results.FindAllPageSpecificValuesNamed('DrawerAnimation-jank')
-    self.assertEquals(len(v), 1)
-
diff --git a/tools/perf/measurements/timeline_controller.py b/tools/perf/measurements/timeline_controller.py
index 1b8f2f1..ab5ba54 100644
--- a/tools/perf/measurements/timeline_controller.py
+++ b/tools/perf/measurements/timeline_controller.py
@@ -3,27 +3,19 @@
 # found in the LICENSE file.
 from measurements import smooth_gesture_util
 
+from telemetry.core.backends.chrome import tracing_backend
 from telemetry.core.timeline.model import TimelineModel
 from telemetry.page.actions import action_runner
 from telemetry.web_perf import timeline_interaction_record as tir_module
 
-# All tracing categories not disabled-by-default
-DEFAULT_TRACE_CATEGORIES = None
-
-# Categories for absolute minimum overhead tracing. This contains no
-# sub-traces of thread tasks, so it's only useful for capturing the
-# cpu-time spent on threads (as well as needed benchmark traces)
-MINIMAL_TRACE_CATEGORIES = ("toplevel,"
-                            "benchmark,"
-                            "webkit.console,"
-                            "trace_event_overhead")
 
 RUN_SMOOTH_ACTIONS = 'RunSmoothAllActions'
 
+
 class TimelineController(object):
   def __init__(self):
     super(TimelineController, self).__init__()
-    self.trace_categories = DEFAULT_TRACE_CATEGORIES
+    self.trace_categories = tracing_backend.DEFAULT_TRACE_CATEGORIES
     self._model = None
     self._renderer_process = None
     self._smooth_records = []
diff --git a/tools/perf/metrics/chrome_proxy.js b/tools/perf/metrics/chrome_proxy.js
index b79b19c..63fc81f 100644
--- a/tools/perf/metrics/chrome_proxy.js
+++ b/tools/perf/metrics/chrome_proxy.js
@@ -10,19 +10,30 @@
   var PROXY_VIEW_EFFECTIVE_SETTINGS_ID = 'proxy-view-effective-settings';
   var PROXY_VIEW_BAD_PROXIES_ID = 'proxy-view-bad-proxies-div';
   var PROXY_VIEW_BAD_PROXIES_TBODY = 'proxy-view-bad-proxies-tbody';
-  var PRXOY_SETTINGS_PREFIX = 'Proxy server for HTTP: '
+  var PRXOY_SETTINGS_PREFIX = 'Proxy server for HTTP: ['
   var PROXY_SETTINGS_SIGNATURE = 'proxy.googlezip.net:443, ' +
     'compress.googlezip.net:80, direct://';
 
-  function getEffectiveProxySettings(doc) {
+  // Returns the effective proxy in an array from settings.
+  // An example of the settings is:
+  // "Proxy server for HTTP: [proxy.googlezip.net:443, " +
+  // "compress.googlezip.net:80, direct://]"
+  function getEffectiveProxies(doc) {
     var settings = doc.getElementById(PROXY_VIEW_EFFECTIVE_SETTINGS_ID);
     if (settings && settings.innerHTML &&
       settings.innerHTML.indexOf(PRXOY_SETTINGS_PREFIX) == 0) {
-      return settings.innerHTML.substr(PRXOY_SETTINGS_PREFIX.length);
+      var left = settings.innerHTML.indexOf('[');
+      var right = settings.innerHTML.indexOf(']');
+      if (left >= 0 && right > left) {
+        return settings.innerHTML.substring(left + 1, right).split(/[ ,]+/);
+      }
     }
-    return "";
+    return [];
   }
 
+  // Returns an array of bad proxies. Each element is a bad proxy with
+  // attribute 'proxy' as the proxy name and attribute 'retry' as the
+  // next retry time.
   function getBadProxyList(doc) {
     var bad_proxies = doc.getElementById(PROXY_VIEW_BAD_PROXIES_ID);
     if (bad_proxies.hasAttribute('style') &&
@@ -50,8 +61,10 @@
       return null;
     }
     info = {};
-    info.settings = getEffectiveProxySettings(document);
-    info.enabled = (info.settings.indexOf(PROXY_SETTINGS_SIGNATURE) >= 0);
+    info.proxies = getEffectiveProxies(document);
+    info.enabled = (info.proxies.length > 1 &&
+        info.proxies[info.proxies.length - 1] == 'direct://' &&
+        info.proxies[info.proxies.length - 2] != 'direct://');
     info.badProxies = getBadProxyList(document);
     return info;
   };
diff --git a/tools/perf/metrics/chrome_proxy.py b/tools/perf/metrics/chrome_proxy.py
index a17d9e7..5517f0a 100644
--- a/tools/perf/metrics/chrome_proxy.py
+++ b/tools/perf/metrics/chrome_proxy.py
@@ -16,15 +16,18 @@
 CHROME_PROXY_VIA_HEADER = 'Chrome-Compression-Proxy'
 CHROME_PROXY_VIA_HEADER_DEPRECATED = '1.1 Chrome Compression Proxy'
 
-ALL_PROXIES = ['compress.googlezip.net:80', 'https://proxy.googlezip.net:443']
+PROXY_SETTING_HTTPS = 'proxy.googlezip.net:443'
+PROXY_SETTING_HTTPS_WITH_SCHEME = 'https://' + PROXY_SETTING_HTTPS
+PROXY_SETTING_HTTP = 'compress.googlezip.net:80'
+PROXY_SETTING_DIRECT = 'direct://'
 
 # The default Chrome Proxy bypass time is a range from one to five mintues.
 # See ProxyList::UpdateRetryInfoOnFallback in net/proxy/proxy_list.cc.
 DEFAULT_BYPASS_MIN_SECONDS = 60
 DEFAULT_BYPASS_MAX_SECONDS = 5 * 60
 
-def GetProxyInfoFromNetworkInternals(tab):
-  tab.Navigate('chrome://net-internals#proxy')
+def GetProxyInfoFromNetworkInternals(tab, url='chrome://net-internals#proxy'):
+  tab.Navigate(url)
   with open(os.path.join(os.path.dirname(__file__), 'chrome_proxy.js')) as f:
     js = f.read()
     tab.ExecuteJavaScript(js)
@@ -83,6 +86,11 @@
   def __init__(self):
     super(ChromeProxyMetric, self).__init__()
     self.compute_data_saving = True
+    self.effective_proxies = {
+        "proxy": PROXY_SETTING_HTTPS_WITH_SCHEME,
+        "fallback": PROXY_SETTING_HTTP,
+        "direct": PROXY_SETTING_DIRECT,
+        }
 
   def SetEvents(self, events):
     """Used for unittest."""
@@ -129,7 +137,7 @@
       badProxies, expected_proxies,
       retry_seconds_low = DEFAULT_BYPASS_MIN_SECONDS,
       retry_seconds_high = DEFAULT_BYPASS_MAX_SECONDS):
-    """."""
+    """Verify the bad proxy list and their retry times are expected. """
     if not badProxies or (len(badProxies) != len(expected_proxies)):
       return False
 
@@ -171,8 +179,11 @@
       info = GetProxyInfoFromNetworkInternals(tab)
       if not info['enabled']:
         raise ChromeProxyMetricException, (
-            "Chrome proxy should be enabled. proxy info: %s" % info)
-      self.VerifyBadProxies(info['badProxies'], ALL_PROXIES)
+            'Chrome proxy should be enabled. proxy info: %s' % info)
+      self.VerifyBadProxies(
+          info['badProxies'],
+          [self.effective_proxies['proxy'],
+           self.effective_proxies['fallback']])
 
     results.Add('bypass', 'count', bypass_count)
 
@@ -195,3 +206,32 @@
       raise ChromeProxyMetricException, (
           'Safebrowsing failed (count=%d, safebrowsing_count=%d)\n' % (
               count, safebrowsing_count))
+
+  def AddResultsForHTTPFallback(
+      self, tab, results, expected_proxies=None, expected_bad_proxies=None):
+    info = GetProxyInfoFromNetworkInternals(tab)
+    if not 'enabled' in info or not info['enabled']:
+      raise ChromeProxyMetricException, (
+          'Chrome proxy should be enabled. proxy info: %s' % info)
+
+    if not expected_proxies:
+      expected_proxies = [self.effective_proxies['fallback'],
+                          self.effective_proxies['direct']]
+    if not expected_bad_proxies:
+      expected_bad_proxies = []
+
+    proxies = info['proxies']
+    if proxies != expected_proxies:
+      raise ChromeProxyMetricException, (
+          'Wrong effective proxies (%s). Expect: "%s"' % (
+          str(proxies), str(expected_proxies)))
+
+    bad_proxies = []
+    if 'badProxies' in info and info['badProxies']:
+      bad_proxies = [p['proxy'] for p in info['badProxies']
+                     if 'proxy' in p and p['proxy']]
+    if bad_proxies != expected_bad_proxies:
+      raise ChromeProxyMetricException, (
+          'Wrong bad proxies (%s). Expect: "%s"' % (
+          str(bad_proxies), str(expected_bad_proxies)))
+    results.Add('http_fallback', 'boolean', True)
diff --git a/tools/perf/metrics/chrome_proxy_unittest.py b/tools/perf/metrics/chrome_proxy_unittest.py
index 01f8f5f..a4d2cab 100644
--- a/tools/perf/metrics/chrome_proxy_unittest.py
+++ b/tools/perf/metrics/chrome_proxy_unittest.py
@@ -71,6 +71,15 @@
 
 
 class ChromeProxyMetricTest(unittest.TestCase):
+
+  _test_proxy_info = {}
+
+  def _StubGetProxyInfo(self, info):
+    def stub(unused_tab, unused_url=''):  # pylint: disable=W0613
+      return ChromeProxyMetricTest._test_proxy_info
+    chrome_proxy.GetProxyInfoFromNetworkInternals = stub
+    ChromeProxyMetricTest._test_proxy_info = info
+
   def testChromeProxyResponse(self):
     # An https non-proxy response.
     resp = chrome_proxy.ChromeProxyResponse(
@@ -166,6 +175,44 @@
     metric.AddResultsForBypass(None, results)
     results.AssertHasPageSpecificScalarValue('bypass', 'count', 1)
 
+  def testChromeProxyMetricForHTTPFallback(self):
+    metric = chrome_proxy.ChromeProxyMetric()
+    metric.SetEvents([
+        EVENT_HTML_PROXY,
+        EVENT_HTML_PROXY_DEPRECATED_VIA])
+    results = test_page_measurement_results.TestPageMeasurementResults(self)
+
+    fallback_exception = False
+    info = {}
+    info['enabled'] = False
+    self._StubGetProxyInfo(info)
+    try:
+      metric.AddResultsForBypass(None, results)
+    except chrome_proxy.ChromeProxyMetricException:
+      fallback_exception = True
+    self.assertTrue(fallback_exception)
+
+    fallback_exception = False
+    info['enabled'] = True
+    info['proxies'] = [
+        'something.else.com:80',
+        chrome_proxy.PROXY_SETTING_DIRECT
+        ]
+    self._StubGetProxyInfo(info)
+    try:
+      metric.AddResultsForBypass(None, results)
+    except chrome_proxy.ChromeProxyMetricException:
+      fallback_exception = True
+    self.assertTrue(fallback_exception)
+
+    info['enabled'] = True
+    info['proxies'] = [
+        chrome_proxy.PROXY_SETTING_HTTP,
+        chrome_proxy.PROXY_SETTING_DIRECT
+        ]
+    self._StubGetProxyInfo(info)
+    metric.AddResultsForHTTPFallback(None, results)
+
   def testChromeProxyMetricForSafebrowsing(self):
     metric = chrome_proxy.ChromeProxyMetric()
     metric.SetEvents([EVENT_MALWARE_PROXY])
diff --git a/tools/perf/metrics/rendering_stats.py b/tools/perf/metrics/rendering_stats.py
deleted file mode 100644
index e35699a..0000000
--- a/tools/perf/metrics/rendering_stats.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# Copyright 2013 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.
-
-from operator import attrgetter
-from telemetry.page import page_measurement
-
-# These are LatencyInfo component names indicating the various components
-# that the input event has travelled through.
-# This is when the input event first reaches chrome.
-UI_COMP_NAME = 'INPUT_EVENT_LATENCY_UI_COMPONENT'
-# This is when the input event was originally created by OS.
-ORIGINAL_COMP_NAME = 'INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT'
-# This is when the input event was sent from browser to renderer.
-BEGIN_COMP_NAME = 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT'
-# This is when the input event has reached swap buffer.
-END_COMP_NAME = 'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT'
-
-
-class NotEnoughFramesError(page_measurement.MeasurementFailure):
-  def __init__(self, frame_count):
-    super(NotEnoughFramesError, self).__init__(
-      'Only %i frame timestamps were collected ' % frame_count +
-      '(at least two are required).\n'
-      'Issues that have caused this in the past:\n' +
-      '- Browser bugs that prevents the page from redrawing\n' +
-      '- Bugs in the synthetic gesture code\n' +
-      '- Page and benchmark out of sync (e.g. clicked element was renamed)\n' +
-      '- Pages that render extremely slow\n' +
-      '- Pages that can\'t be scrolled')
-
-
-def GetScrollInputLatencyEvents(scroll_type, browser_process, timeline_range):
-  """Get scroll events' LatencyInfo from the browser process's trace buffer
-     that are within the timeline_range.
-
-  Scroll events (MouseWheel, GestureScrollUpdate or JS scroll on TouchMove)
-  dump their LatencyInfo into trace buffer as async trace event with name
-  "InputLatency". The trace event has a memeber 'step' containing its event
-  type and a memeber 'data' containing its latency history.
-
-  """
-  scroll_events = []
-  if not browser_process:
-    return scroll_events
-  for event in browser_process.IterAllAsyncSlicesOfName("InputLatency"):
-    if event.start >= timeline_range.min and event.end <= timeline_range.max:
-      for ss in event.sub_slices:
-        if 'step' not in ss.args:
-          continue
-        if 'data' not in ss.args:
-          continue
-        if ss.args['step'] == scroll_type:
-          scroll_events.append(ss)
-  return scroll_events
-
-
-def ComputeMouseWheelScrollLatency(mouse_wheel_events):
-  """ Compute the mouse wheel scroll latency.
-
-  Mouse wheel scroll latency is the time from when mouse wheel event is sent
-  from browser RWH to renderer (the timestamp of component
-  'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT') to when the scrolled page is
-  buffer swapped (the timestamp of component
-  'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT')
-
-  """
-  mouse_wheel_latency = []
-  for event in mouse_wheel_events:
-    data = event.args['data']
-    if BEGIN_COMP_NAME in data and END_COMP_NAME in data:
-      latency = data[END_COMP_NAME]['time'] - data[BEGIN_COMP_NAME]['time']
-      mouse_wheel_latency.append(latency / 1000.0)
-  return mouse_wheel_latency
-
-
-def ComputeTouchScrollLatency(touch_scroll_events):
-  """ Compute the touch scroll latency.
-
-  Touch scroll latency is the time from when the touch event is created to
-  when the scrolled page is buffer swapped.
-  Touch event on differnt platforms uses different LatencyInfo component to
-  record its creation timestamp. On Aura, the creation time is kept in
-  'INPUT_EVENT_LATENCY_UI_COMPONENT' . On Android, the creation time is kept
-  in 'INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT'.
-
-  """
-  touch_scroll_latency = []
-  for event in touch_scroll_events:
-    data = event.args['data']
-    if END_COMP_NAME in data:
-      end_time = data[END_COMP_NAME]['time']
-      if UI_COMP_NAME in data and ORIGINAL_COMP_NAME in data:
-        raise ValueError, 'LatencyInfo has both UI and ORIGINAL component'
-      if UI_COMP_NAME in data:
-        latency = end_time - data[UI_COMP_NAME]['time']
-        touch_scroll_latency.append(latency / 1000.0)
-      elif ORIGINAL_COMP_NAME in data:
-        latency = end_time - data[ORIGINAL_COMP_NAME]['time']
-        touch_scroll_latency.append(latency / 1000.0)
-  return touch_scroll_latency
-
-
-def HasRenderingStats(process):
-  """ Returns True if the process contains at least one
-      BenchmarkInstrumentation::*RenderingStats event with a frame.
-  """
-  if not process:
-    return False
-  for event in process.IterAllSlicesOfName(
-      'BenchmarkInstrumentation::MainThreadRenderingStats'):
-    if 'data' in event.args and event.args['data']['frame_count'] == 1:
-      return True
-  for event in process.IterAllSlicesOfName(
-      'BenchmarkInstrumentation::ImplThreadRenderingStats'):
-    if 'data' in event.args and event.args['data']['frame_count'] == 1:
-      return True
-  return False
-
-
-class RenderingStats(object):
-  def __init__(self, renderer_process, browser_process, timeline_ranges):
-    """
-    Utility class for extracting rendering statistics from the timeline (or
-    other loggin facilities), and providing them in a common format to classes
-    that compute benchmark metrics from this data.
-
-    Stats are lists of lists of numbers. The outer list stores one list per
-    timeline range.
-
-    All *_time values are measured in milliseconds.
-    """
-    assert(len(timeline_ranges) > 0)
-    # Find the top level process with rendering stats (browser or renderer).
-    if HasRenderingStats(browser_process):
-      timestamp_process = browser_process
-    else:
-      timestamp_process  = renderer_process
-
-    self.frame_timestamps = []
-    self.frame_times = []
-    self.paint_times = []
-    self.painted_pixel_counts = []
-    self.record_times = []
-    self.recorded_pixel_counts = []
-    self.rasterize_times = []
-    self.rasterized_pixel_counts = []
-    # End-to-end latency for MouseWheel scroll - from when mouse wheel event is
-    # generated to when the scrolled page is buffer swapped.
-    self.mouse_wheel_scroll_latency = []
-    # End-to-end latency for GestureScrollUpdate scroll - from when the touch
-    # event is generated to the scrolled page is buffer swapped.
-    self.touch_scroll_latency = []
-    # End-to-end latency for JS touch handler scrolling - from when the touch
-    # event is generated to the scrolled page is buffer swapped.
-    self.js_touch_scroll_latency = []
-
-    for timeline_range in timeline_ranges:
-      self.frame_timestamps.append([])
-      self.frame_times.append([])
-      self.paint_times.append([])
-      self.painted_pixel_counts.append([])
-      self.record_times.append([])
-      self.recorded_pixel_counts.append([])
-      self.rasterize_times.append([])
-      self.rasterized_pixel_counts.append([])
-      self.mouse_wheel_scroll_latency.append([])
-      self.touch_scroll_latency.append([])
-      self.js_touch_scroll_latency.append([])
-
-      if timeline_range.is_empty:
-        continue
-      self._InitFrameTimestampsFromTimeline(timestamp_process, timeline_range)
-      self._InitMainThreadRenderingStatsFromTimeline(
-          renderer_process, timeline_range)
-      self._InitImplThreadRenderingStatsFromTimeline(
-          renderer_process, timeline_range)
-      self._InitScrollLatencyStatsFromTimeline(browser_process, timeline_range)
-
-    # Check if we have collected at least 2 frames in every range. Otherwise we
-    # can't compute any meaningful metrics.
-    for segment in self.frame_timestamps:
-      if len(segment) < 2:
-        raise NotEnoughFramesError(len(segment))
-
-  def _InitScrollLatencyStatsFromTimeline(
-      self, browser_process, timeline_range):
-    mouse_wheel_events = GetScrollInputLatencyEvents(
-        "MouseWheel", browser_process, timeline_range)
-    self.mouse_wheel_scroll_latency = ComputeMouseWheelScrollLatency(
-        mouse_wheel_events)
-
-    touch_scroll_events = GetScrollInputLatencyEvents(
-        "GestureScrollUpdate", browser_process, timeline_range)
-    self.touch_scroll_latency = ComputeTouchScrollLatency(touch_scroll_events)
-
-    js_touch_scroll_events = GetScrollInputLatencyEvents(
-        "TouchMove", browser_process, timeline_range)
-    self.js_touch_scroll_latency = ComputeTouchScrollLatency(
-        js_touch_scroll_events)
-
-  def _GatherEvents(self, event_name, process, timeline_range):
-    events = []
-    for event in process.IterAllSlicesOfName(event_name):
-      if event.start >= timeline_range.min and event.end <= timeline_range.max:
-        if 'data' not in event.args:
-          continue
-        events.append(event)
-    events.sort(key=attrgetter('start'))
-    return events
-
-  def _AddFrameTimestamp(self, event):
-    frame_count = event.args['data']['frame_count']
-    if frame_count > 1:
-      raise ValueError, 'trace contains multi-frame render stats'
-    if frame_count == 1:
-      self.frame_timestamps[-1].append(
-          event.start)
-      if len(self.frame_timestamps[-1]) >= 2:
-        self.frame_times[-1].append(round(self.frame_timestamps[-1][-1] -
-                                          self.frame_timestamps[-1][-2], 2))
-
-  def _InitFrameTimestampsFromTimeline(self, process, timeline_range):
-    event_name = 'BenchmarkInstrumentation::MainThreadRenderingStats'
-    for event in self._GatherEvents(event_name, process, timeline_range):
-      self._AddFrameTimestamp(event)
-
-    event_name = 'BenchmarkInstrumentation::ImplThreadRenderingStats'
-    for event in self._GatherEvents(event_name, process, timeline_range):
-      self._AddFrameTimestamp(event)
-
-
-  def _InitMainThreadRenderingStatsFromTimeline(self, process, timeline_range):
-    event_name = 'BenchmarkInstrumentation::MainThreadRenderingStats'
-    for event in self._GatherEvents(event_name, process, timeline_range):
-      self.paint_times[-1].append(1000.0 *
-          event.args['data']['paint_time'])
-      self.painted_pixel_counts[-1].append(
-          event.args['data']['painted_pixel_count'])
-      self.record_times[-1].append(1000.0 *
-          event.args['data']['record_time'])
-      self.recorded_pixel_counts[-1].append(
-          event.args['data']['recorded_pixel_count'])
-
-  def _InitImplThreadRenderingStatsFromTimeline(self, process, timeline_range):
-    event_name = 'BenchmarkInstrumentation::ImplThreadRenderingStats'
-    for event in self._GatherEvents(event_name, process, timeline_range):
-      self.rasterize_times[-1].append(1000.0 *
-          event.args['data']['rasterize_time'])
-      self.rasterized_pixel_counts[-1].append(
-          event.args['data']['rasterized_pixel_count'])
diff --git a/tools/perf/metrics/rendering_stats_unittest.py b/tools/perf/metrics/rendering_stats_unittest.py
deleted file mode 100644
index 10419ca..0000000
--- a/tools/perf/metrics/rendering_stats_unittest.py
+++ /dev/null
@@ -1,464 +0,0 @@
-# Copyright 2013 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.
-
-import random
-import unittest
-
-from metrics.rendering_stats import UI_COMP_NAME, BEGIN_COMP_NAME, END_COMP_NAME
-from metrics.rendering_stats import GetScrollInputLatencyEvents
-from metrics.rendering_stats import ComputeMouseWheelScrollLatency
-from metrics.rendering_stats import ComputeTouchScrollLatency
-from metrics.rendering_stats import HasRenderingStats
-from metrics.rendering_stats import RenderingStats
-from metrics.rendering_stats import NotEnoughFramesError
-import telemetry.core.timeline.bounds as timeline_bounds
-from telemetry.core.timeline import model
-import telemetry.core.timeline.async_slice as tracing_async_slice
-
-
-class MockTimer(object):
-  """A mock timer class which can generate random durations.
-
-  An instance of this class is used as a global timer to generate random
-  durations for stats and consistent timestamps for all mock trace events.
-  The unit of time is milliseconds.
-  """
-  def __init__(self):
-    self.milliseconds = 0
-
-  def Get(self):
-    return self.milliseconds
-
-  def Advance(self, low=0, high=1):
-    delta = random.uniform(low, high)
-    self.milliseconds += delta
-    return delta
-
-
-class ReferenceRenderingStats(object):
-  """ Stores expected data for comparison with actual RenderingStats """
-  def __init__(self):
-    self.frame_timestamps = []
-    self.frame_times = []
-    self.paint_times = []
-    self.painted_pixel_counts = []
-    self.record_times = []
-    self.recorded_pixel_counts = []
-    self.rasterize_times = []
-    self.rasterized_pixel_counts = []
-
-  def AppendNewRange(self):
-    self.frame_timestamps.append([])
-    self.frame_times.append([])
-    self.paint_times.append([])
-    self.painted_pixel_counts.append([])
-    self.record_times.append([])
-    self.recorded_pixel_counts.append([])
-    self.rasterize_times.append([])
-    self.rasterized_pixel_counts.append([])
-
-class ReferenceInputLatencyStats(object):
-  """ Stores expected data for comparison with actual input latency stats """
-  def __init__(self):
-    self.mouse_wheel_scroll_latency = []
-    self.touch_scroll_latency = []
-    self.js_touch_scroll_latency = []
-    self.mouse_wheel_scroll_events = []
-    self.touch_scroll_events = []
-    self.js_touch_scroll_events = []
-
-def AddMainThreadRenderingStats(mock_timer, thread, first_frame,
-                                ref_stats = None):
-  """ Adds a random main thread rendering stats event.
-
-  thread: The timeline model thread to which the event will be added.
-  first_frame: Is this the first frame within the bounds of an action?
-  ref_stats: A ReferenceRenderingStats object to record expected values.
-  """
-  # Create randonm data and timestap for main thread rendering stats.
-  data = { 'frame_count': 0,
-           'paint_time': 0.0,
-           'painted_pixel_count': 0,
-           'record_time': mock_timer.Advance(2, 4) / 1000.0,
-           'recorded_pixel_count': 3000*3000 }
-  timestamp = mock_timer.Get()
-
-  # Add a slice with the event data to the given thread.
-  thread.PushCompleteSlice(
-      'benchmark', 'BenchmarkInstrumentation::MainThreadRenderingStats',
-      timestamp, duration=0.0, thread_timestamp=None, thread_duration=None,
-      args={'data': data})
-
-  if not ref_stats:
-    return
-
-  # Add timestamp only if a frame was output
-  if data['frame_count'] == 1:
-    if not first_frame:
-      # Add frame_time if this is not the first frame in within the bounds of an
-      # action.
-      prev_timestamp = ref_stats.frame_timestamps[-1][-1]
-      ref_stats.frame_times[-1].append(round(timestamp - prev_timestamp, 2))
-    ref_stats.frame_timestamps[-1].append(timestamp)
-
-  ref_stats.paint_times[-1].append(data['paint_time'] * 1000.0)
-  ref_stats.painted_pixel_counts[-1].append(data['painted_pixel_count'])
-  ref_stats.record_times[-1].append(data['record_time'] * 1000.0)
-  ref_stats.recorded_pixel_counts[-1].append(data['recorded_pixel_count'])
-
-
-def AddImplThreadRenderingStats(mock_timer, thread, first_frame,
-                                ref_stats = None):
-  """ Adds a random impl thread rendering stats event.
-
-  thread: The timeline model thread to which the event will be added.
-  first_frame: Is this the first frame within the bounds of an action?
-  ref_stats: A ReferenceRenderingStats object to record expected values.
-  """
-  # Create randonm data and timestap for impl thread rendering stats.
-  data = { 'frame_count': 1,
-           'rasterize_time': mock_timer.Advance(5, 10) / 1000.0,
-           'rasterized_pixel_count': 1280*720 }
-  timestamp = mock_timer.Get()
-
-  # Add a slice with the event data to the given thread.
-  thread.PushCompleteSlice(
-      'benchmark', 'BenchmarkInstrumentation::ImplThreadRenderingStats',
-      timestamp, duration=0.0, thread_timestamp=None, thread_duration=None,
-      args={'data': data})
-
-  if not ref_stats:
-    return
-
-  # Add timestamp only if a frame was output
-  if data['frame_count'] == 1:
-    if not first_frame:
-      # Add frame_time if this is not the first frame in within the bounds of an
-      # action.
-      prev_timestamp = ref_stats.frame_timestamps[-1][-1]
-      ref_stats.frame_times[-1].append(round(timestamp - prev_timestamp, 2))
-    ref_stats.frame_timestamps[-1].append(timestamp)
-
-  ref_stats.rasterize_times[-1].append(data['rasterize_time'] * 1000.0)
-  ref_stats.rasterized_pixel_counts[-1].append(data['rasterized_pixel_count'])
-
-
-def AddInputLatencyStats(mock_timer, input_type, start_thread, end_thread,
-                         ref_latency_stats = None):
-  """ Adds a random input latency stats event.
-
-  input_type: The input type for which the latency slice is generated.
-  start_thread: The start thread on which the async slice is added.
-  end_thread: The end thread on which the async slice is ended.
-  ref_latency_stats: A ReferenceInputLatencyStats object for expected values.
-  """
-
-  mock_timer.Advance(2, 4)
-  ui_comp_time = mock_timer.Get() * 1000.0
-  mock_timer.Advance(2, 4)
-  begin_comp_time = mock_timer.Get() * 1000.0
-  mock_timer.Advance(10, 20)
-  end_comp_time = mock_timer.Get() * 1000.0
-
-  data = { UI_COMP_NAME: {'time': ui_comp_time},
-           BEGIN_COMP_NAME: {'time': begin_comp_time},
-           END_COMP_NAME: {'time': end_comp_time} }
-
-  timestamp = mock_timer.Get()
-
-  async_slice = tracing_async_slice.AsyncSlice(
-      'benchmark', 'InputLatency', timestamp)
-
-  async_sub_slice = tracing_async_slice.AsyncSlice(
-      'benchmark', 'InputLatency', timestamp)
-  async_sub_slice.args = {'data': data, 'step': input_type}
-  async_sub_slice.parent_slice = async_slice
-  async_sub_slice.start_thread = start_thread
-  async_sub_slice.end_thread = end_thread
-
-  async_slice.sub_slices.append(async_sub_slice)
-  async_slice.start_thread = start_thread
-  async_slice.end_thread = end_thread
-  start_thread.AddAsyncSlice(async_slice)
-
-  if not ref_latency_stats:
-    return
-
-  if input_type == 'MouseWheel':
-    ref_latency_stats.mouse_wheel_scroll_events.append(async_sub_slice)
-    ref_latency_stats.mouse_wheel_scroll_latency.append(
-        (data[END_COMP_NAME]['time'] - data[BEGIN_COMP_NAME]['time']) / 1000.0)
-
-  if input_type == 'GestureScrollUpdate':
-    ref_latency_stats.touch_scroll_events.append(async_sub_slice)
-    ref_latency_stats.touch_scroll_latency.append(
-        (data[END_COMP_NAME]['time'] - data[UI_COMP_NAME]['time']) / 1000.0)
-
-  if input_type == 'TouchMove':
-    ref_latency_stats.js_touch_scroll_events.append(async_sub_slice)
-    ref_latency_stats.js_touch_scroll_latency.append(
-        (data[END_COMP_NAME]['time'] - data[UI_COMP_NAME]['time']) / 1000.0)
-
-class RenderingStatsUnitTest(unittest.TestCase):
-  def testHasRenderingStats(self):
-    timeline = model.TimelineModel()
-    timer = MockTimer()
-
-    # A process without rendering stats
-    process_without_stats = timeline.GetOrCreateProcess(pid = 1)
-    thread_without_stats = process_without_stats.GetOrCreateThread(tid = 11)
-    process_without_stats.FinalizeImport()
-    self.assertFalse(HasRenderingStats(thread_without_stats))
-
-    # A process with rendering stats, but no frames in them
-    process_without_frames = timeline.GetOrCreateProcess(pid = 2)
-    thread_without_frames = process_without_frames.GetOrCreateThread(tid = 21)
-    AddMainThreadRenderingStats(timer, thread_without_frames, True, None)
-    process_without_frames.FinalizeImport()
-    self.assertFalse(HasRenderingStats(thread_without_frames))
-
-    # A process with rendering stats and frames in them
-    process_with_frames = timeline.GetOrCreateProcess(pid = 3)
-    thread_with_frames = process_with_frames.GetOrCreateThread(tid = 31)
-    AddImplThreadRenderingStats(timer, thread_with_frames, True, None)
-    process_with_frames.FinalizeImport()
-    self.assertTrue(HasRenderingStats(thread_with_frames))
-
-  def testRangeWithoutFrames(self):
-    timer = MockTimer()
-    timeline = model.TimelineModel()
-
-    # Create a renderer process, with a main thread and impl thread.
-    renderer = timeline.GetOrCreateProcess(pid = 2)
-    renderer_main = renderer.GetOrCreateThread(tid = 21)
-    renderer_compositor = renderer.GetOrCreateThread(tid = 22)
-
-    # Create 10 main and impl rendering stats events for Action A.
-    timer.Advance(2, 4)
-    renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddMainThreadRenderingStats(timer, renderer_main, first, None)
-      AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
-    timer.Advance(2, 4)
-    renderer_main.EndSlice(timer.Get())
-
-    # Create 5 main and impl rendering stats events not within any action.
-    for i in xrange(0, 5):
-      first = (i == 0)
-      AddMainThreadRenderingStats(timer, renderer_main, first, None)
-      AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
-
-    # Create Action B without any frames. This should trigger
-    # NotEnoughFramesError when the RenderingStats object is created.
-    timer.Advance(2, 4)
-    renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '')
-    timer.Advance(2, 4)
-    renderer_main.EndSlice(timer.Get())
-
-    renderer.FinalizeImport()
-
-    timeline_markers = timeline.FindTimelineMarkers(['ActionA', 'ActionB'])
-    timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker)
-                        for marker in timeline_markers ]
-    self.assertRaises(NotEnoughFramesError, RenderingStats,
-                      renderer, None, timeline_ranges)
-
-  def testFromTimeline(self):
-    timeline = model.TimelineModel()
-
-    # Create a browser process and a renderer process, and a main thread and
-    # impl thread for each.
-    browser = timeline.GetOrCreateProcess(pid = 1)
-    browser_main = browser.GetOrCreateThread(tid = 11)
-    browser_compositor = browser.GetOrCreateThread(tid = 12)
-    renderer = timeline.GetOrCreateProcess(pid = 2)
-    renderer_main = renderer.GetOrCreateThread(tid = 21)
-    renderer_compositor = renderer.GetOrCreateThread(tid = 22)
-
-    timer = MockTimer()
-    renderer_ref_stats = ReferenceRenderingStats()
-    browser_ref_stats = ReferenceRenderingStats()
-
-    # Create 10 main and impl rendering stats events for Action A.
-    timer.Advance(2, 4)
-    renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
-    renderer_ref_stats.AppendNewRange()
-    browser_ref_stats.AppendNewRange()
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddMainThreadRenderingStats(
-          timer, renderer_main, first, renderer_ref_stats)
-      AddImplThreadRenderingStats(
-          timer, renderer_compositor, first, renderer_ref_stats)
-      AddMainThreadRenderingStats(
-          timer, browser_main, first, browser_ref_stats)
-      AddImplThreadRenderingStats(
-          timer, browser_compositor, first, browser_ref_stats)
-    timer.Advance(2, 4)
-    renderer_main.EndSlice(timer.Get())
-
-    # Create 5 main and impl rendering stats events not within any action.
-    for i in xrange(0, 5):
-      first = (i == 0)
-      AddMainThreadRenderingStats(timer, renderer_main, first, None)
-      AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
-      AddMainThreadRenderingStats(timer, browser_main, first, None)
-      AddImplThreadRenderingStats(timer, browser_compositor, first, None)
-
-    # Create 10 main and impl rendering stats events for Action B.
-    timer.Advance(2, 4)
-    renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '')
-    renderer_ref_stats.AppendNewRange()
-    browser_ref_stats.AppendNewRange()
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddMainThreadRenderingStats(
-          timer, renderer_main, first, renderer_ref_stats)
-      AddImplThreadRenderingStats(
-          timer, renderer_compositor, first, renderer_ref_stats)
-      AddMainThreadRenderingStats(
-          timer, browser_main, first, browser_ref_stats)
-      AddImplThreadRenderingStats(
-          timer, browser_compositor, first, browser_ref_stats)
-    timer.Advance(2, 4)
-    renderer_main.EndSlice(timer.Get())
-
-    # Create 10 main and impl rendering stats events for Action A.
-    timer.Advance(2, 4)
-    renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
-    renderer_ref_stats.AppendNewRange()
-    browser_ref_stats.AppendNewRange()
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddMainThreadRenderingStats(
-          timer, renderer_main, first, renderer_ref_stats)
-      AddImplThreadRenderingStats(
-          timer, renderer_compositor, first, renderer_ref_stats)
-      AddMainThreadRenderingStats(
-          timer, browser_main, first, browser_ref_stats)
-      AddImplThreadRenderingStats(
-          timer, browser_compositor, first, browser_ref_stats)
-    timer.Advance(2, 4)
-    renderer_main.EndSlice(timer.Get())
-
-    browser.FinalizeImport()
-    renderer.FinalizeImport()
-
-    timeline_markers = timeline.FindTimelineMarkers(
-        ['ActionA', 'ActionB', 'ActionA'])
-    timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker)
-                        for marker in timeline_markers ]
-    stats = RenderingStats(renderer, browser, timeline_ranges)
-
-    # Compare rendering stats to reference.
-    self.assertEquals(stats.frame_timestamps,
-                      browser_ref_stats.frame_timestamps)
-    self.assertEquals(stats.frame_times, browser_ref_stats.frame_times)
-    self.assertEquals(stats.rasterize_times, renderer_ref_stats.rasterize_times)
-    self.assertEquals(stats.rasterized_pixel_counts,
-                      renderer_ref_stats.rasterized_pixel_counts)
-    self.assertEquals(stats.paint_times, renderer_ref_stats.paint_times)
-    self.assertEquals(stats.painted_pixel_counts,
-                      renderer_ref_stats.painted_pixel_counts)
-    self.assertEquals(stats.record_times, renderer_ref_stats.record_times)
-    self.assertEquals(stats.recorded_pixel_counts,
-                      renderer_ref_stats.recorded_pixel_counts)
-
-  def testScrollLatencyFromTimeline(self):
-    timeline = model.TimelineModel()
-
-    # Create a browser process and a renderer process.
-    browser = timeline.GetOrCreateProcess(pid = 1)
-    browser_main = browser.GetOrCreateThread(tid = 11)
-    renderer = timeline.GetOrCreateProcess(pid = 2)
-    renderer_main = renderer.GetOrCreateThread(tid = 21)
-
-    timer = MockTimer()
-    ref_latency_stats = ReferenceInputLatencyStats()
-
-    # Create 10 input latency stats events for Action A.
-    timer.Advance(2, 4)
-    renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
-    for _ in xrange(0, 10):
-      AddInputLatencyStats(timer, 'MouseWheel', browser_main,
-                           renderer_main, ref_latency_stats)
-      AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main,
-                           renderer_main, ref_latency_stats)
-      AddInputLatencyStats(timer, 'TouchMove', browser_main,
-                           renderer_main, ref_latency_stats)
-    timer.Advance(2, 4)
-    renderer_main.EndSlice(timer.Get())
-
-    # Create 5 input latency stats events not within any action.
-    timer.Advance(2, 4)
-    for _ in xrange(0, 5):
-      AddInputLatencyStats(timer, 'MouseWheel', browser_main,
-                           renderer_main, None)
-      AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main,
-                           renderer_main, None)
-      AddInputLatencyStats(timer, 'TouchMove', browser_main,
-                           renderer_main, None)
-
-    # Create 10 input latency stats events for Action B.
-    timer.Advance(2, 4)
-    renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '')
-    for _ in xrange(0, 10):
-      AddInputLatencyStats(timer, 'MouseWheel', browser_main,
-                           renderer_main, ref_latency_stats)
-      AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main,
-                           renderer_main, ref_latency_stats)
-      AddInputLatencyStats(timer, 'TouchMove', browser_main,
-                           renderer_main, ref_latency_stats)
-    timer.Advance(2, 4)
-    renderer_main.EndSlice(timer.Get())
-
-    # Create 10 input latency stats events for Action A.
-    timer.Advance(2, 4)
-    renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
-    for _ in xrange(0, 10):
-      AddInputLatencyStats(timer, 'MouseWheel', browser_main,
-                                  renderer_main, ref_latency_stats)
-      AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main,
-                                  renderer_main, ref_latency_stats)
-      AddInputLatencyStats(timer, 'TouchMove', browser_main,
-                                  renderer_main, ref_latency_stats)
-    timer.Advance(2, 4)
-    renderer_main.EndSlice(timer.Get())
-
-    browser.FinalizeImport()
-    renderer.FinalizeImport()
-
-    mouse_wheel_scroll_events = []
-    touch_scroll_events = []
-    js_touch_scroll_events = []
-
-    timeline_markers = timeline.FindTimelineMarkers(
-        ['ActionA', 'ActionB', 'ActionA'])
-    for timeline_range in [ timeline_bounds.Bounds.CreateFromEvent(marker)
-                            for marker in timeline_markers ]:
-      if timeline_range.is_empty:
-        continue
-      tmp_mouse_events = GetScrollInputLatencyEvents(
-          'MouseWheel', browser, timeline_range)
-      tmp_touch_scroll_events = GetScrollInputLatencyEvents(
-          'GestureScrollUpdate', browser, timeline_range)
-      tmp_js_touch_scroll_events = GetScrollInputLatencyEvents(
-          'TouchMove', browser, timeline_range)
-      mouse_wheel_scroll_events.extend(tmp_mouse_events)
-      touch_scroll_events.extend(tmp_touch_scroll_events)
-      js_touch_scroll_events.extend(tmp_js_touch_scroll_events)
-
-    self.assertEquals(mouse_wheel_scroll_events,
-                      ref_latency_stats.mouse_wheel_scroll_events)
-    self.assertEquals(touch_scroll_events,
-                      ref_latency_stats.touch_scroll_events)
-    self.assertEquals(js_touch_scroll_events,
-                      ref_latency_stats.js_touch_scroll_events)
-    self.assertEquals(ComputeMouseWheelScrollLatency(mouse_wheel_scroll_events),
-                      ref_latency_stats.mouse_wheel_scroll_latency)
-    self.assertEquals(ComputeTouchScrollLatency(touch_scroll_events),
-                      ref_latency_stats.touch_scroll_latency)
-    self.assertEquals(ComputeTouchScrollLatency(js_touch_scroll_events),
-                      ref_latency_stats.js_touch_scroll_latency)
diff --git a/tools/perf/metrics/smoothness.py b/tools/perf/metrics/smoothness.py
deleted file mode 100644
index cc94bd9..0000000
--- a/tools/perf/metrics/smoothness.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2013 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.
-
-from metrics import timeline_based_metric
-from metrics import rendering_stats
-from telemetry.page.perf_tests_helper import FlattenList
-from telemetry.util import statistics
-
-
-class SmoothnessMetric(timeline_based_metric.TimelineBasedMetric):
-  def __init__(self):
-    super(SmoothnessMetric, self).__init__()
-
-  def AddResults(self, model, renderer_thread, interaction_records, results):
-    renderer_process = renderer_thread.parent
-    stats = rendering_stats.RenderingStats(
-      renderer_process, model.browser_process,
-      [r.GetBounds() for r in interaction_records])
-    if stats.mouse_wheel_scroll_latency:
-      mean_mouse_wheel_scroll_latency = statistics.ArithmeticMean(
-        stats.mouse_wheel_scroll_latency)
-      mouse_wheel_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
-        stats.mouse_wheel_scroll_latency)
-      results.Add('mean_mouse_wheel_scroll_latency', 'ms',
-                  round(mean_mouse_wheel_scroll_latency, 3))
-      results.Add('mouse_wheel_scroll_latency_discrepancy', 'ms',
-                  round(mouse_wheel_scroll_latency_discrepancy, 4))
-
-    if stats.touch_scroll_latency:
-      mean_touch_scroll_latency = statistics.ArithmeticMean(
-        stats.touch_scroll_latency)
-      touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
-        stats.touch_scroll_latency)
-      results.Add('mean_touch_scroll_latency', 'ms',
-                  round(mean_touch_scroll_latency, 3))
-      results.Add('touch_scroll_latency_discrepancy', 'ms',
-                  round(touch_scroll_latency_discrepancy, 4))
-
-    if stats.js_touch_scroll_latency:
-      mean_js_touch_scroll_latency = statistics.ArithmeticMean(
-        stats.js_touch_scroll_latency)
-      js_touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
-        stats.js_touch_scroll_latency)
-      results.Add('mean_js_touch_scroll_latency', 'ms',
-                  round(mean_js_touch_scroll_latency, 3))
-      results.Add('js_touch_scroll_latency_discrepancy', 'ms',
-                  round(js_touch_scroll_latency_discrepancy, 4))
-
-    # List of raw frame times.
-    frame_times = FlattenList(stats.frame_times)
-    results.Add('frame_times', 'ms', frame_times)
-
-    # Arithmetic mean of frame times.
-    mean_frame_time = statistics.ArithmeticMean(frame_times)
-    results.Add('mean_frame_time', 'ms', round(mean_frame_time, 3))
-
-    # Absolute discrepancy of frame time stamps.
-    frame_discrepancy = statistics.TimestampsDiscrepancy(
-      stats.frame_timestamps)
-    results.Add('jank', 'ms', round(frame_discrepancy, 4))
-
-    # Are we hitting 60 fps for 95 percent of all frames?
-    # We use 19ms as a somewhat looser threshold, instead of 1000.0/60.0.
-    percentile_95 = statistics.Percentile(frame_times, 95.0)
-    results.Add('mostly_smooth', 'score', 1.0 if percentile_95 < 19.0 else 0.0)
diff --git a/tools/perf/metrics/timeline.py b/tools/perf/metrics/timeline.py
index 3de78e9..c524352 100644
--- a/tools/perf/metrics/timeline.py
+++ b/tools/perf/metrics/timeline.py
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 import collections
 
-from metrics import timeline_based_metric
+from telemetry.web_perf.metrics import timeline_based_metric
 
 
 class LoadTimesTimelineMetric(timeline_based_metric.TimelineBasedMetric):
diff --git a/tools/perf/page_sets/alexa1-10000.py b/tools/perf/page_sets/alexa1-10000.py
index 6433f16..cc52b68 100644
--- a/tools/perf/page_sets/alexa1-10000.py
+++ b/tools/perf/page_sets/alexa1-10000.py
@@ -4,10 +4,10 @@
 # pylint: disable=W0401,W0614
 from telemetry.page.actions.all_page_actions import *
 from telemetry.page.page_set import PageSet
-from telemetry.page.page import PageWithDefaultRunNavigate
+from telemetry.page.page import Page
 
 
-class Alexa1To10000Page(PageWithDefaultRunNavigate):
+class Alexa1To10000Page(Page):
 
   def __init__(self, url, page_set):
     super(Alexa1To10000Page, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/blank_page.py b/tools/perf/page_sets/blank_page.py
index 85ce5b1..b3c0469 100644
--- a/tools/perf/page_sets/blank_page.py
+++ b/tools/perf/page_sets/blank_page.py
@@ -5,7 +5,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class BlankPage(page_module.PageWithDefaultRunNavigate):
+class BlankPage(page_module.Page):
   def __init__(self, url, page_set):
     super(BlankPage, self).__init__(url, page_set=page_set)
 
diff --git a/tools/perf/page_sets/browser_control.py b/tools/perf/page_sets/browser_control.py
index 3bf327e..434c434 100644
--- a/tools/perf/page_sets/browser_control.py
+++ b/tools/perf/page_sets/browser_control.py
@@ -7,15 +7,15 @@
 from telemetry.page import page_set as page_set_module
 
 
-class BrowserControlPage(page_module.PageWithDefaultRunNavigate):
+class BrowserControlPage(page_module.Page):
   """ Why: Continually attach and detach a DOM tree from a basic document. """
 
   def __init__(self, page_set):
     super(BrowserControlPage, self).__init__(
       url='file://endure/browser_control.html',
-      page_set=page_set)
+      page_set=page_set,
+      name='browser_control')
     self.user_agent_type = 'desktop'
-    self.name = 'browser_control'
 
   def RunEndure(self, action_runner):
     action_runner.RunAction(WaitAction({'seconds': 2}))
diff --git a/tools/perf/page_sets/browser_control_click.py b/tools/perf/page_sets/browser_control_click.py
index b6e1015..780d52c 100644
--- a/tools/perf/page_sets/browser_control_click.py
+++ b/tools/perf/page_sets/browser_control_click.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class BrowserControlClickPage(page_module.PageWithDefaultRunNavigate):
+class BrowserControlClickPage(page_module.Page):
 
   """ Why: Use a JavaScript .click() call to attach and detach a DOM tree
   from a basic document.
@@ -16,9 +16,9 @@
   def __init__(self, page_set):
     super(BrowserControlClickPage, self).__init__(
       url='file://endure/browser_control_click.html',
-      page_set=page_set)
+      page_set=page_set,
+     name='browser_control_click')
     self.user_agent_type = 'desktop'
-    self.name = 'browser_control_click'
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
diff --git a/tools/perf/page_sets/calendar_forward_backward.py b/tools/perf/page_sets/calendar_forward_backward.py
index b8b6825..2d0be43 100644
--- a/tools/perf/page_sets/calendar_forward_backward.py
+++ b/tools/perf/page_sets/calendar_forward_backward.py
@@ -7,19 +7,19 @@
 from telemetry.page import page_set as page_set_module
 
 
-class CalendarForwardBackwardPage(page_module.PageWithDefaultRunNavigate):
+class CalendarForwardBackwardPage(page_module.Page):
 
   """ Why: Click forward(4x) and backwards(4x) repeatedly """
 
   def __init__(self, page_set):
     super(CalendarForwardBackwardPage, self).__init__(
       url='https://www.google.com/calendar/',
-      page_set=page_set)
+      page_set=page_set,
+      name='calendar_forward_backward')
     self.credentials_path = 'data/credentials.json'
     self.credentials = 'google'
     self.user_agent_type = 'desktop'
     self.archive_data_file = 'data/calendar_forward_backward.json'
-    self.name = 'calendar_forward_backward'
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
diff --git a/tools/perf/page_sets/chrome_proxy/bypass.py b/tools/perf/page_sets/chrome_proxy/bypass.py
index ddd3b37..1a593c3 100644
--- a/tools/perf/page_sets/chrome_proxy/bypass.py
+++ b/tools/perf/page_sets/chrome_proxy/bypass.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class BypassPage(page_module.PageWithDefaultRunNavigate):
+class BypassPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(BypassPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/chrome_proxy/fallback_viaheader.py b/tools/perf/page_sets/chrome_proxy/fallback_viaheader.py
new file mode 100644
index 0000000..9710414
--- /dev/null
+++ b/tools/perf/page_sets/chrome_proxy/fallback_viaheader.py
@@ -0,0 +1,24 @@
+# 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.
+# pylint: disable=W0401,W0614
+from telemetry.page.actions.all_page_actions import *
+from telemetry.page import page as page_module
+from telemetry.page import page_set as page_set_module
+
+
+class FallbackViaHeaderPage(page_module.Page):
+
+  def __init__(self, url, page_set):
+    super(FallbackViaHeaderPage, self).__init__(url=url, page_set=page_set)
+
+
+class FallbackViaHeaderPageSet(page_set_module.PageSet):
+
+  """ Chrome proxy test sites """
+
+  def __init__(self):
+    super(FallbackViaHeaderPageSet, self).__init__()
+
+    self.AddPage(FallbackViaHeaderPage(
+        'http://chromeproxy-test.appspot.com/default', self))
diff --git a/tools/perf/page_sets/chrome_proxy/safebrowsing.py b/tools/perf/page_sets/chrome_proxy/safebrowsing.py
index ff52d72..b7c337d 100644
--- a/tools/perf/page_sets/chrome_proxy/safebrowsing.py
+++ b/tools/perf/page_sets/chrome_proxy/safebrowsing.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class SafebrowsingPage(page_module.PageWithDefaultRunNavigate):
+class SafebrowsingPage(page_module.Page):
 
   """
   Why: Expect 'malware ahead' page. Use a short navigation timeout because no
diff --git a/tools/perf/page_sets/chrome_proxy/smoke.py b/tools/perf/page_sets/chrome_proxy/smoke.py
index d383e8f..5f80bc8 100644
--- a/tools/perf/page_sets/chrome_proxy/smoke.py
+++ b/tools/perf/page_sets/chrome_proxy/smoke.py
@@ -7,10 +7,10 @@
 from telemetry.page import page_set as page_set_module
 
 
-class SmokePage(page_module.PageWithDefaultRunNavigate):
+class SmokePage(page_module.Page):
 
-  def __init__(self, url, page_set):
-    super(SmokePage, self).__init__(url=url, page_set=page_set)
+  def __init__(self, url, page_set, name=''):
+    super(SmokePage, self).__init__(url=url, page_set=page_set, name=name)
     self.archive_data_file = '../data/chrome_proxy_smoke.json'
 
 
@@ -23,9 +23,8 @@
   def __init__(self, page_set):
     super(Page1, self).__init__(
       url='http://aws1.mdw.la/fw/',
-      page_set=page_set)
-
-    self.name = 'header validation'
+      page_set=page_set,
+      name='header validation')
 
 
 class Page2(SmokePage):
@@ -37,9 +36,8 @@
   def __init__(self, page_set):
     super(Page2, self).__init__(
       url='http://aws1.mdw.la/static/',
-      page_set=page_set)
-
-    self.name = 'compression: image'
+      page_set=page_set,
+      name='compression: image')
 
 
 class Page3(SmokePage):
@@ -51,9 +49,8 @@
   def __init__(self, page_set):
     super(Page3, self).__init__(
       url='http://aws1.mdw.la/bypass/',
-      page_set=page_set)
-
-    self.name = 'bypass'
+      page_set=page_set,
+      name='bypass')
     self.restart_after = True
 
 
@@ -66,9 +63,8 @@
   def __init__(self, page_set):
     super(Page4, self).__init__(
       url='http://aws1.mdw.la/static/',
-      page_set=page_set)
-
-    self.name = 'compression: javascript'
+      page_set=page_set,
+      name='compression: javascript')
 
 
 class Page5(SmokePage):
@@ -80,9 +76,8 @@
   def __init__(self, page_set):
     super(Page5, self).__init__(
       url='http://aws1.mdw.la/static/',
-      page_set=page_set)
-
-    self.name = 'compression: css'
+      page_set=page_set,
+      name='compression: css')
 
 
 class Page6(SmokePage):
@@ -95,9 +90,8 @@
   def __init__(self, page_set):
     super(Page6, self).__init__(
       url='http://www.ianfette.org/',
-      page_set=page_set)
-
-    self.name = 'safebrowsing'
+      page_set=page_set,
+      name='safebrowsing')
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction({'timeout_seconds': 5}))
diff --git a/tools/perf/page_sets/chrome_proxy/synthetic.py b/tools/perf/page_sets/chrome_proxy/synthetic.py
index a9216f3..94700c1 100644
--- a/tools/perf/page_sets/chrome_proxy/synthetic.py
+++ b/tools/perf/page_sets/chrome_proxy/synthetic.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class SyntheticPage(page_module.PageWithDefaultRunNavigate):
+class SyntheticPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(SyntheticPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/chrome_proxy/top_20.py b/tools/perf/page_sets/chrome_proxy/top_20.py
index ebb2bec..94f11c5 100644
--- a/tools/perf/page_sets/chrome_proxy/top_20.py
+++ b/tools/perf/page_sets/chrome_proxy/top_20.py
@@ -7,12 +7,11 @@
 from telemetry.page import page_set as page_set_module
 
 
-class Top20Page(page_module.PageWithDefaultRunNavigate):
+class Top20Page(page_module.Page):
 
   def __init__(self, url, page_set, name=''):
-    super(Top20Page, self).__init__(url=url, page_set=page_set)
+    super(Top20Page, self).__init__(url=url, page_set=page_set, name=name)
     self.archive_data_file = '../data/chrome_proxy_top_20.json'
-    self.name = name
 
 class Top20PageSet(page_set_module.PageSet):
 
diff --git a/tools/perf/page_sets/data/pica.json b/tools/perf/page_sets/data/pica.json
index be7c361..374e725 100644
--- a/tools/perf/page_sets/data/pica.json
+++ b/tools/perf/page_sets/data/pica.json
@@ -1,8 +1,8 @@
 {
     "description": "Describes the Web Page Replay archives for a page set. Don't edit by hand! Use record_wpr for updating.", 
     "archives": {
-        "pica_007.wpr": [
+        "pica_008.wpr": [
             "http://localhost/polymer/projects/pica/"
         ]
     }
-}
+}
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/pica_008.wpr.sha1 b/tools/perf/page_sets/data/pica_008.wpr.sha1
new file mode 100644
index 0000000..aba8d2a
--- /dev/null
+++ b/tools/perf/page_sets/data/pica_008.wpr.sha1
@@ -0,0 +1 @@
+51d0ea9413d9658ff0ea375d1af394cc5009d90b
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/polymer.json b/tools/perf/page_sets/data/polymer.json
index 5cf0feb..283eaaf 100644
--- a/tools/perf/page_sets/data/polymer.json
+++ b/tools/perf/page_sets/data/polymer.json
@@ -1,8 +1,9 @@
 {
     "description": "Describes the Web Page Replay archives for a page set. Don't edit by hand! Use record_wpr for updating.", 
     "archives": {
-        "polymer_000.wpr": [
-            "http://localhost:8000/components/paper-calculator/demo.html"
+        "polymer_002.wpr": [
+            "http://localhost:8000/components/paper-calculator/demo.html", 
+            "http://localhost:8000/components/paper-shadow/demo.html"
         ]
     }
 }
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/polymer_002.wpr.sha1 b/tools/perf/page_sets/data/polymer_002.wpr.sha1
new file mode 100644
index 0000000..5b56080
--- /dev/null
+++ b/tools/perf/page_sets/data/polymer_002.wpr.sha1
@@ -0,0 +1 @@
+f038526c3c1aa5ddf2542035f4a4edf1930d0e42
\ No newline at end of file
diff --git a/tools/perf/page_sets/five_blank_pages.py b/tools/perf/page_sets/five_blank_pages.py
index eec1a92..94e25df 100644
--- a/tools/perf/page_sets/five_blank_pages.py
+++ b/tools/perf/page_sets/five_blank_pages.py
@@ -13,5 +13,5 @@
   def __init__(self):
     super(FiveBlankPagesPageSet, self).__init__()
     for _ in xrange(5):
-      self.AddPage(page_module.PageWithDefaultRunNavigate(
+      self.AddPage(page_module.Page(
         'file://blank_page/blank_page.html', self))
diff --git a/tools/perf/page_sets/gmail_alt_threadlist_conversation.py b/tools/perf/page_sets/gmail_alt_threadlist_conversation.py
index 9e2aebc..648ef52 100644
--- a/tools/perf/page_sets/gmail_alt_threadlist_conversation.py
+++ b/tools/perf/page_sets/gmail_alt_threadlist_conversation.py
@@ -8,18 +8,18 @@
 
 
 class GmailAltThreadlistConversationPage(
-  page_module.PageWithDefaultRunNavigate):
+  page_module.Page):
 
   """ Why: Alternate between Inbox and the first email conversation. """
 
   def __init__(self, page_set):
     super(GmailAltThreadlistConversationPage, self).__init__(
       url='https://mail.google.com/mail/',
-      page_set=page_set)
+      page_set=page_set,
+      name='gmail_alt_threadlist_conversation')
     self.credentials_path = 'data/credentials.json'
     self.user_agent_type = 'desktop'
     self.archive_data_file = 'data/gmail_alt_threadlist_conversation.json'
-    self.name = 'gmail_alt_threadlist_conversation'
     self.credentials = 'google'
 
   def RunNavigateSteps(self, action_runner):
diff --git a/tools/perf/page_sets/gmail_alt_two_labels.py b/tools/perf/page_sets/gmail_alt_two_labels.py
index 4ffac30..1482318 100644
--- a/tools/perf/page_sets/gmail_alt_two_labels.py
+++ b/tools/perf/page_sets/gmail_alt_two_labels.py
@@ -7,20 +7,20 @@
 from telemetry.page import page_set as page_set_module
 
 
-class GmailAltTwoLabelsPage(page_module.PageWithDefaultRunNavigate):
+class GmailAltTwoLabelsPage(page_module.Page):
 
   """ Why: Alternate between Inbox and Sent Mail """
 
   def __init__(self, page_set):
     super(GmailAltTwoLabelsPage, self).__init__(
       url='https://mail.google.com/mail/',
-      page_set=page_set)
+      page_set=page_set,
+      name='gmail_alt_two_labels')
 
     self.credentials_path = 'data/credentials.json'
     self.credentials = 'google'
     self.user_agent_type = 'desktop'
     self.archive_data_file = 'data/gmail_alt_two_labels.json'
-    self.name = 'gmail_alt_two_labels'
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
diff --git a/tools/perf/page_sets/gmail_compose_discard.py b/tools/perf/page_sets/gmail_compose_discard.py
index 31650f4..6bb0940 100644
--- a/tools/perf/page_sets/gmail_compose_discard.py
+++ b/tools/perf/page_sets/gmail_compose_discard.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class GmailComposeDiscardPage(page_module.PageWithDefaultRunNavigate):
+class GmailComposeDiscardPage(page_module.Page):
 
   """ Why: Compose and discard a new email """
 
diff --git a/tools/perf/page_sets/gmail_expand_collapse_conversation.py b/tools/perf/page_sets/gmail_expand_collapse_conversation.py
index 1799e52..6b1dc35 100644
--- a/tools/perf/page_sets/gmail_expand_collapse_conversation.py
+++ b/tools/perf/page_sets/gmail_expand_collapse_conversation.py
@@ -8,7 +8,7 @@
 
 
 class GmailExpandCollapseConversationPage(
-  page_module.PageWithDefaultRunNavigate):
+  page_module.Page):
 
   """ Why: Expand and Collapse a long conversation. """
   # TODO(edmundyan): Find a long conversation rather than hardcode url
@@ -16,12 +16,12 @@
   def __init__(self, page_set):
     super(GmailExpandCollapseConversationPage, self).__init__(
       url='https://mail.google.com/mail/u/0/#inbox/13c6a141fa95ffe0',
-      page_set=page_set)
+      page_set=page_set,
+      name='gmail_expand_collapse_conversation')
     self.credentials_path = 'data/credentials.json'
     self.credentials = 'google'
     self.user_agent_type = 'desktop'
     self.archive_data_file = 'data/gmail_expand_collapse_conversation.json'
-    self.name = 'gmail_expand_collapse_conversation'
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
diff --git a/tools/perf/page_sets/gmail_refresh.py b/tools/perf/page_sets/gmail_refresh.py
index ccc4a22..5382688 100644
--- a/tools/perf/page_sets/gmail_refresh.py
+++ b/tools/perf/page_sets/gmail_refresh.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class GmailRefreshPage(page_module.PageWithDefaultRunNavigate):
+class GmailRefreshPage(page_module.Page):
 
   """ Why: Continually reload the gmail page. """
 
diff --git a/tools/perf/page_sets/image_decoding_measurement.py b/tools/perf/page_sets/image_decoding_measurement.py
index 4ee3267..ba1052e 100644
--- a/tools/perf/page_sets/image_decoding_measurement.py
+++ b/tools/perf/page_sets/image_decoding_measurement.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ImageDecodingMeasurementPage(page_module.PageWithDefaultRunNavigate):
+class ImageDecodingMeasurementPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ImageDecodingMeasurementPage, self).__init__(url=url,
diff --git a/tools/perf/page_sets/indexeddb_offline.py b/tools/perf/page_sets/indexeddb_offline.py
index e322b16..8679d65 100644
--- a/tools/perf/page_sets/indexeddb_offline.py
+++ b/tools/perf/page_sets/indexeddb_offline.py
@@ -7,16 +7,16 @@
 from telemetry.page import page_set as page_set_module
 
 
-class IndexeddbOfflinePage(page_module.PageWithDefaultRunNavigate):
+class IndexeddbOfflinePage(page_module.Page):
 
   """ Why: Simulates user input while offline and sync while online. """
 
   def __init__(self, page_set):
     super(IndexeddbOfflinePage, self).__init__(
       url='file://endure/indexeddb_app.html',
-      page_set=page_set)
+      page_set=page_set,
+      name='indexeddb_offline')
     self.user_agent_type = 'desktop'
-    self.name = 'indexeddb_offline'
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
diff --git a/tools/perf/page_sets/intl_ar_fa_he.py b/tools/perf/page_sets/intl_ar_fa_he.py
index dc05286..21f029ca 100644
--- a/tools/perf/page_sets/intl_ar_fa_he.py
+++ b/tools/perf/page_sets/intl_ar_fa_he.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class IntlArFaHePage(page_module.PageWithDefaultRunNavigate):
+class IntlArFaHePage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(IntlArFaHePage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/intl_es_fr_pt-BR.py b/tools/perf/page_sets/intl_es_fr_pt-BR.py
index 7d3fc1b..ea7ee7a 100644
--- a/tools/perf/page_sets/intl_es_fr_pt-BR.py
+++ b/tools/perf/page_sets/intl_es_fr_pt-BR.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class IntlEsFrPtBrPage(page_module.PageWithDefaultRunNavigate):
+class IntlEsFrPtBrPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(IntlEsFrPtBrPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/intl_hi_ru.py b/tools/perf/page_sets/intl_hi_ru.py
index 644e058..0f760a8 100644
--- a/tools/perf/page_sets/intl_hi_ru.py
+++ b/tools/perf/page_sets/intl_hi_ru.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class IntlHiRuPage(page_module.PageWithDefaultRunNavigate):
+class IntlHiRuPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(IntlHiRuPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/intl_ja_zh.py b/tools/perf/page_sets/intl_ja_zh.py
index 44c1028..a2ae3b0 100644
--- a/tools/perf/page_sets/intl_ja_zh.py
+++ b/tools/perf/page_sets/intl_ja_zh.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class IntlJaZhPage(page_module.PageWithDefaultRunNavigate):
+class IntlJaZhPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(IntlJaZhPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/intl_ko_th_vi.py b/tools/perf/page_sets/intl_ko_th_vi.py
index 909118a..33a1ecb 100644
--- a/tools/perf/page_sets/intl_ko_th_vi.py
+++ b/tools/perf/page_sets/intl_ko_th_vi.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class IntlKoThViPage(page_module.PageWithDefaultRunNavigate):
+class IntlKoThViPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(IntlKoThViPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/key_desktop_sites.py b/tools/perf/page_sets/key_desktop_sites.py
index 71ef2d0..9d78463 100644
--- a/tools/perf/page_sets/key_desktop_sites.py
+++ b/tools/perf/page_sets/key_desktop_sites.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class KeyDesktopSitesPage(page_module.PageWithDefaultRunNavigate):
+class KeyDesktopSitesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(KeyDesktopSitesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/key_mobile_sites.py b/tools/perf/page_sets/key_mobile_sites.py
index 81acf65..a2c5a91 100644
--- a/tools/perf/page_sets/key_mobile_sites.py
+++ b/tools/perf/page_sets/key_mobile_sites.py
@@ -7,10 +7,11 @@
 from telemetry.page import page_set as page_set_module
 
 
-class KeyMobileSitesPage(page_module.PageWithDefaultRunNavigate):
+class KeyMobileSitesPage(page_module.Page):
 
-  def __init__(self, url, page_set):
-    super(KeyMobileSitesPage, self).__init__(url=url, page_set=page_set)
+  def __init__(self, url, page_set, name=''):
+    super(KeyMobileSitesPage, self).__init__(url=url, page_set=page_set,
+                                             name=name)
     self.credentials_path = 'data/credentials.json'
     self.user_agent_type = 'mobile'
     self.archive_data_file = 'data/key_mobile_sites.json'
@@ -165,9 +166,8 @@
   def __init__(self, page_set):
     super(Page9, self).__init__(
       url='http://googlewebmastercentral.blogspot.com/',
-      page_set=page_set)
-
-    self.name = 'Blogger'
+      page_set=page_set,
+      name='Blogger')
 
 
 class Page10(KeyMobileSitesPage):
@@ -178,9 +178,8 @@
     super(Page10, self).__init__(
       # pylint: disable=C0301
       url='http://en.blog.wordpress.com/2012/09/04/freshly-pressed-editors-picks-for-august-2012/',
-      page_set=page_set)
-
-    self.name = 'Wordpress'
+      page_set=page_set,
+      name='Wordpress')
 
 
 class Page11(KeyMobileSitesPage):
@@ -190,9 +189,8 @@
   def __init__(self, page_set):
     super(Page11, self).__init__(
       url='https://www.linkedin.com/in/linustorvalds',
-      page_set=page_set)
-
-    self.name = 'LinkedIn'
+      page_set=page_set,
+      name='LinkedIn')
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
@@ -210,9 +208,8 @@
   def __init__(self, page_set):
     super(Page12, self).__init__(
       url='http://en.wikipedia.org/wiki/Wikipedia',
-      page_set=page_set)
-
-    self.name = 'Wikipedia (1 tab)'
+      page_set=page_set,
+      name='Wikipedia (1 tab)')
 
 
 class Page13(KeyMobileSitesPage):
@@ -222,9 +219,8 @@
   def __init__(self, page_set):
     super(Page13, self).__init__(
       url='http://twitter.com/katyperry',
-      page_set=page_set)
-
-    self.name = 'Twitter'
+      page_set=page_set,
+      name='Twitter')
     self.disabled = 'Forbidden (Rate Limit Exceeded)'
 
 
@@ -235,9 +231,8 @@
   def __init__(self, page_set):
     super(Page14, self).__init__(
       url='http://pinterest.com',
-      page_set=page_set)
-
-    self.name = 'Pinterest'
+      page_set=page_set,
+      name='Pinterest')
 
 
 class Page15(KeyMobileSitesPage):
@@ -247,9 +242,8 @@
   def __init__(self, page_set):
     super(Page15, self).__init__(
       url='http://espn.go.com',
-      page_set=page_set)
-
-    self.name = 'ESPN'
+      page_set=page_set,
+      name='ESPN')
     self.disabled = 'Fails often; crbug.com/249722'
 
 
@@ -479,7 +473,7 @@
           function(callback) {
             callback(document.getElementById(':5'));
           }''',
-        'remaining_scroll_distance_function': '''
+        'scroll_distance_function': '''
           function() {
             return Math.max(0, 2500 +
               document.getElementById(':h').getBoundingClientRect().top);
@@ -487,6 +481,31 @@
       }))
 
 
+class Page26(KeyMobileSitesPage):
+
+  """
+  Why: #1 world commerce website by visits; #3 commerce in the US by time spent
+  """
+
+  def __init__(self, page_set):
+    super(Page26, self).__init__(
+      url='http://www.amazon.com/gp/aw/s/ref=is_box_?k=nicolas+cage',
+      page_set=page_set)
+
+  def RunSmoothness(self, action_runner):
+    action_runner.RunAction(ScrollAction(
+      {
+        'scrollable_element_function': '''
+          function(callback) {
+            callback(document.getElementById('search'));
+          }''',
+        'scroll_distance_function': '''
+          function() {
+            return document.body.scrollHeight - window.innerHeight;
+          }'''
+      }))
+
+
 class KeyMobileSitesPageSet(page_set_module.PageSet):
 
   """ Key mobile sites """
@@ -522,6 +541,7 @@
 #    self.AddPage(Page23(self))
     self.AddPage(Page24(self))
     self.AddPage(Page25(self))
+    self.AddPage(Page26(self))
 
     urls_list = [
       # Why: crbug.com/242544
@@ -540,9 +560,6 @@
       'http://news.yahoo.com',
       # Why: #2 news worldwide
       'http://www.cnn.com',
-      # Why: #1 world commerce website by visits; #3 commerce in the US by time
-      # spent
-      'http://www.amazon.com/gp/aw/s/ref=is_box_?k=nicolas+cage',
       # Why: #1 commerce website by time spent by users in US
       'http://shop.mobileweb.ebay.com/searchresults?kw=viking+helmet',
       # Why: #1 Alexa recreation
diff --git a/tools/perf/page_sets/key_search_mobile.py b/tools/perf/page_sets/key_search_mobile.py
index 80217c4..f4f1c18 100644
--- a/tools/perf/page_sets/key_search_mobile.py
+++ b/tools/perf/page_sets/key_search_mobile.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class KeySearchMobilePage(page_module.PageWithDefaultRunNavigate):
+class KeySearchMobilePage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(KeySearchMobilePage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/key_silk_cases.py b/tools/perf/page_sets/key_silk_cases.py
index 4da7b66..cea90cf 100644
--- a/tools/perf/page_sets/key_silk_cases.py
+++ b/tools/perf/page_sets/key_silk_cases.py
@@ -8,7 +8,7 @@
 from telemetry.web_perf import timeline_interaction_record as tir_module
 
 
-class KeySilkCasesPage(page_module.PageWithDefaultRunNavigate):
+class KeySilkCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(KeySilkCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/maps.py b/tools/perf/page_sets/maps.py
index ca56029..677d362 100644
--- a/tools/perf/page_sets/maps.py
+++ b/tools/perf/page_sets/maps.py
@@ -7,14 +7,14 @@
 from telemetry.page import page_set as page_set_module
 
 
-class MapsPage(page_module.PageWithDefaultRunNavigate):
+class MapsPage(page_module.Page):
 
   def __init__(self, page_set):
     super(MapsPage, self).__init__(
       url='http://localhost:10020/tracker.html',
-      page_set=page_set)
+      page_set=page_set,
+      name='Maps.maps_001')
     self.archive_data_file = 'data/maps.json'
-    self.name = 'Maps.maps_001'
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
diff --git a/tools/perf/page_sets/media_cns_cases.py b/tools/perf/page_sets/media_cns_cases.py
index 7e90902..9824f5a 100644
--- a/tools/perf/page_sets/media_cns_cases.py
+++ b/tools/perf/page_sets/media_cns_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class BasicPlayPage(page_module.PageWithDefaultRunNavigate):
+class BasicPlayPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(BasicPlayPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/mobile_memory.py b/tools/perf/page_sets/mobile_memory.py
index 270865e..d04c659 100644
--- a/tools/perf/page_sets/mobile_memory.py
+++ b/tools/perf/page_sets/mobile_memory.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class MobileMemoryPage(page_module.PageWithDefaultRunNavigate):
+class MobileMemoryPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(MobileMemoryPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/mse_cases.py b/tools/perf/page_sets/mse_cases.py
index ff943b4..ce3f48c 100644
--- a/tools/perf/page_sets/mse_cases.py
+++ b/tools/perf/page_sets/mse_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class MseCasesPage(page_module.PageWithDefaultRunNavigate):
+class MseCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(MseCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/page_cycler/alexa_us.py b/tools/perf/page_sets/page_cycler/alexa_us.py
index 889f12f..b378858 100644
--- a/tools/perf/page_sets/page_cycler/alexa_us.py
+++ b/tools/perf/page_sets/page_cycler/alexa_us.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class AlexaUsPage(page_module.PageWithDefaultRunNavigate):
+class AlexaUsPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(AlexaUsPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/page_cycler/bloat.py b/tools/perf/page_sets/page_cycler/bloat.py
index 0b53a0b..f033790 100644
--- a/tools/perf/page_sets/page_cycler/bloat.py
+++ b/tools/perf/page_sets/page_cycler/bloat.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class BloatPage(page_module.PageWithDefaultRunNavigate):
+class BloatPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(BloatPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/page_cycler/dhtml.py b/tools/perf/page_sets/page_cycler/dhtml.py
index a9103b7..447311a 100644
--- a/tools/perf/page_sets/page_cycler/dhtml.py
+++ b/tools/perf/page_sets/page_cycler/dhtml.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class DhtmlPage(page_module.PageWithDefaultRunNavigate):
+class DhtmlPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(DhtmlPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/page_cycler/dom.py b/tools/perf/page_sets/page_cycler/dom.py
index 62736a5..cb6c85c 100644
--- a/tools/perf/page_sets/page_cycler/dom.py
+++ b/tools/perf/page_sets/page_cycler/dom.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class DomPage(page_module.PageWithDefaultRunNavigate):
+class DomPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(DomPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/page_cycler/intl1.py b/tools/perf/page_sets/page_cycler/intl1.py
index 4cf9ef6..cdc13c3 100644
--- a/tools/perf/page_sets/page_cycler/intl1.py
+++ b/tools/perf/page_sets/page_cycler/intl1.py
@@ -6,7 +6,7 @@
 from telemetry.page import page as page_module
 from telemetry.page import page_set as page_set_module
 
-class Intl1Page(page_module.PageWithDefaultRunNavigate):
+class Intl1Page(page_module.Page):
 
   def __init__(self, url, page_set):
     super(Intl1Page, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/page_cycler/intl2.py b/tools/perf/page_sets/page_cycler/intl2.py
index c45d69f..df22811 100644
--- a/tools/perf/page_sets/page_cycler/intl2.py
+++ b/tools/perf/page_sets/page_cycler/intl2.py
@@ -6,7 +6,7 @@
 from telemetry.page import page as page_module
 from telemetry.page import page_set as page_set_module
 
-class Intl2Page(page_module.PageWithDefaultRunNavigate):
+class Intl2Page(page_module.Page):
 
   def __init__(self, url, page_set):
     super(Intl2Page, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/page_cycler/morejs.py b/tools/perf/page_sets/page_cycler/morejs.py
index ce57cbc..459f9dd 100644
--- a/tools/perf/page_sets/page_cycler/morejs.py
+++ b/tools/perf/page_sets/page_cycler/morejs.py
@@ -6,7 +6,7 @@
 from telemetry.page import page as page_module
 from telemetry.page import page_set as page_set_module
 
-class MorejsPage(page_module.PageWithDefaultRunNavigate):
+class MorejsPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(MorejsPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/page_cycler/morejsnp.py b/tools/perf/page_sets/page_cycler/morejsnp.py
index 5fe2f77..3a97e07 100644
--- a/tools/perf/page_sets/page_cycler/morejsnp.py
+++ b/tools/perf/page_sets/page_cycler/morejsnp.py
@@ -6,7 +6,7 @@
 from telemetry.page import page as page_module
 from telemetry.page import page_set as page_set_module
 
-class MorejsnpPage(page_module.PageWithDefaultRunNavigate):
+class MorejsnpPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(MorejsnpPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/page_cycler/moz.py b/tools/perf/page_sets/page_cycler/moz.py
index e807ac7..23f1dcf 100644
--- a/tools/perf/page_sets/page_cycler/moz.py
+++ b/tools/perf/page_sets/page_cycler/moz.py
@@ -6,7 +6,7 @@
 from telemetry.page import page as page_module
 from telemetry.page import page_set as page_set_module
 
-class MozPage(page_module.PageWithDefaultRunNavigate):
+class MozPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(MozPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/page_cycler/moz2.py b/tools/perf/page_sets/page_cycler/moz2.py
index 6b7b1f8..24fd609 100644
--- a/tools/perf/page_sets/page_cycler/moz2.py
+++ b/tools/perf/page_sets/page_cycler/moz2.py
@@ -6,7 +6,7 @@
 from telemetry.page import page as page_module
 from telemetry.page import page_set as page_set_module
 
-class Moz2Page(page_module.PageWithDefaultRunNavigate):
+class Moz2Page(page_module.Page):
 
   def __init__(self, url, page_set):
     super(Moz2Page, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/page_set_unittest.py b/tools/perf/page_sets/page_set_unittest.py
index db235b3..fa83e72 100644
--- a/tools/perf/page_sets/page_set_unittest.py
+++ b/tools/perf/page_sets/page_set_unittest.py
@@ -2,42 +2,12 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import logging
 import os
-import unittest
 
-from telemetry.core import discover
-from telemetry.page import page_set as page_set_module
-from telemetry.page import page_set_archive_info
+from telemetry.test_util import page_set_smoke_test
 
 
-class PageSetUnitTest(unittest.TestCase):
+class PageSetUnitTest(page_set_smoke_test.PageSetSmokeTest):
 
   def testSmoke(self):
-    # Instantiate all page sets and verify that all URLs have an associated
-    # archive.
-    page_sets_dir = os.path.dirname(__file__)
-    page_sets = discover.GetAllPageSetFilenames(page_sets_dir)
-    for path in page_sets:
-      page_set = page_set_module.PageSet.FromFile(path)
-
-      # TODO: Eventually these should be fatal.
-      if not page_set.archive_data_file:
-        logging.warning('Skipping %s: missing archive data file', path)
-        continue
-      if not os.path.exists(os.path.join(page_sets_dir,
-                                         page_set.archive_data_file)):
-        logging.warning('Skipping %s: archive data file not found', path)
-        continue
-
-      wpr_archive_info = page_set_archive_info.PageSetArchiveInfo.FromFile(
-        os.path.join(page_sets_dir, page_set.archive_data_file),
-        ignore_archive=True)
-
-      logging.info('Testing %s', path)
-      for page in page_set.pages:
-        if not page.url.startswith('http'):
-          continue
-        self.assertTrue(wpr_archive_info.WprFilePathForPage(page),
-                        msg='No archive found for %s in %s' % (
-                            page.url, page_set.archive_data_file))
+    self.RunSmokeTest(os.path.dirname(__file__))
diff --git a/tools/perf/page_sets/plus_alt_posts_photos.py b/tools/perf/page_sets/plus_alt_posts_photos.py
index 19b5ab9..5fdbc27 100644
--- a/tools/perf/page_sets/plus_alt_posts_photos.py
+++ b/tools/perf/page_sets/plus_alt_posts_photos.py
@@ -7,19 +7,19 @@
 from telemetry.page import page_set as page_set_module
 
 
-class PlusAltPostsPhotosPage(page_module.PageWithDefaultRunNavigate):
+class PlusAltPostsPhotosPage(page_module.Page):
 
   """ Why: Alternate between clicking posts and albums """
 
   def __init__(self, page_set):
     super(PlusAltPostsPhotosPage, self).__init__(
       url='https://plus.google.com/+BarackObama/posts',
-      page_set=page_set)
+      page_set=page_set,
+      name='plus_alt_posts_photos')
     self.credentials_path = 'data/credentials.json'
     self.credentials = 'google'
     self.user_agent_type = 'desktop'
     self.archive_data_file = 'data/plus_alt_posts_photos.json'
-    self.name = 'plus_alt_posts_photos'
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
diff --git a/tools/perf/page_sets/polymer.py b/tools/perf/page_sets/polymer.py
index f1a3f97..7612991 100644
--- a/tools/perf/page_sets/polymer.py
+++ b/tools/perf/page_sets/polymer.py
@@ -6,21 +6,31 @@
 from telemetry.page import page as page_module
 from telemetry.page import page_set as page_set_module
 
-class PolymerCalculatorPage(page_module.PageWithDefaultRunNavigate):
+class PolymerPage(page_module.Page):
+
+  def __init__(self, url, page_set):
+    super(PolymerPage, self).__init__(
+      url=url,
+      page_set=page_set)
+    self.archive_data_file = "data/polymer.json"
+    self.script_to_evaluate_on_commit = '''
+      document.addEventListener("polymer-ready", function() {
+        window.__polymer_ready = true;
+      });
+    '''
+
+  def RunNavigateSteps(self, action_runner):
+    action_runner.RunAction(NavigateAction())
+    action_runner.RunAction(WaitAction(
+      { 'javascript': "window.__polymer_ready" }))
+
+
+class PolymerCalculatorPage(PolymerPage):
 
   def __init__(self, page_set):
     super(PolymerCalculatorPage, self).__init__(
       url='http://localhost:8000/components/paper-calculator/demo.html',
       page_set=page_set)
-    self.user_agent_type = 'mobile'
-    self.archive_data_file = 'data/polymer.json'
-
-  def RunNavigateSteps(self, action_runner):
-    action_runner.RunAction(NavigateAction())
-    action_runner.RunAction(WaitAction(
-      {
-        'seconds': 2
-      }))
 
   def RunSmoothness(self, action_runner):
     self.TapButton(action_runner)
@@ -52,9 +62,8 @@
         'direction': 'left',
         'wait_after': {
           'javascript': '''
-            (o = document.querySelector(
-              "body /deep/ #outerPanels"
-            )), o.opened || o.wideMode
+            var outer = document.querySelector("body /deep/ #outerPanels");
+            outer.opened || outer.wideMode;
           '''
         },
         'top_start_percentage': 0.2,
@@ -74,6 +83,40 @@
       }))
 
 
+class PolymerShadowPage(PolymerPage):
+
+  def __init__(self, page_set):
+    super(PolymerShadowPage, self).__init__(
+      url='http://localhost:8000/components/paper-shadow/demo.html',
+      page_set=page_set)
+    self.archive_data_file = 'data/polymer.json'
+
+  def RunSmoothness(self, action_runner):
+    action_runner.RunAction(JavascriptAction(
+      {
+        'expression': "document.getElementById('fab').scrollIntoView()"
+      }))
+    action_runner.RunAction(WaitAction(
+      {
+        'seconds': 5
+      }))
+    self.AnimateShadow(action_runner, 'card')
+    self.AnimateShadow(action_runner, 'fab')
+
+  def AnimateShadow(self, action_runner, eid):
+    for i in range(1, 6):
+      action_runner.RunAction(JavascriptAction(
+        {
+          'expression': '''
+            document.getElementById("{0}").z = {1}
+          '''.format(eid, i)
+        }))
+      action_runner.RunAction(WaitAction(
+        {
+          'seconds': 1
+        }))
+
+
 class PolymerPageSet(page_set_module.PageSet):
 
   def __init__(self):
@@ -82,3 +125,4 @@
       archive_data_file='data/polymer.json')
 
     self.AddPage(PolymerCalculatorPage(self))
+    self.AddPage(PolymerShadowPage(self))
diff --git a/tools/perf/page_sets/startup_pages.py b/tools/perf/page_sets/startup_pages.py
index f10dace..6fe7305 100644
--- a/tools/perf/page_sets/startup_pages.py
+++ b/tools/perf/page_sets/startup_pages.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class StartedPage(page_module.PageWithDefaultRunNavigate):
+class StartedPage(page_module.Page):
 
   def __init__(self, url, startup_url, page_set):
     super(StartedPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/startup_pages_record.py b/tools/perf/page_sets/startup_pages_record.py
index 66d144e..e230ab0 100644
--- a/tools/perf/page_sets/startup_pages_record.py
+++ b/tools/perf/page_sets/startup_pages_record.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class StartupPagesRecordPage(page_module.PageWithDefaultRunNavigate):
+class StartupPagesRecordPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(StartupPagesRecordPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/top_10.py b/tools/perf/page_sets/top_10.py
index ae7e992..34ffd11 100644
--- a/tools/perf/page_sets/top_10.py
+++ b/tools/perf/page_sets/top_10.py
@@ -7,9 +7,9 @@
 from telemetry.page import page_set as page_set_module
 
 
-class SimpleScrollPage(page_module.PageWithDefaultRunNavigate):
-  def __init__(self, url, page_set, credentials=''):
-    super(SimpleScrollPage, self).__init__(url, page_set=page_set)
+class SimpleScrollPage(page_module.Page):
+  def __init__(self, url, page_set, credentials='', name=''):
+    super(SimpleScrollPage, self).__init__(url, page_set=page_set, name=name)
     self.credentials = credentials
 
   def RunSmoothness(self, action_runner):
@@ -77,8 +77,8 @@
     super(Facebook, self).__init__(
       url='http://www.facebook.com/barackobama',
       page_set=page_set,
-      credentials='facebook')
-    self.name = "Facebook"
+      credentials='facebook',
+      name='Facebook')
 
   def RunNavigateSteps(self, action_runner):
     super(Facebook, self).RunNavigateSteps(action_runner)
@@ -110,10 +110,8 @@
     self.AddPage(Facebook(self))
 
     # #6 (Alexa) most visited worldwide,Picked an interesting page
-    wikipedia_page = SimpleScrollPage('http://en.wikipedia.org/wiki/Wikipedia',
-                                      self)
-    wikipedia_page.name = "Wikipedia"
-    self.AddPage(wikipedia_page)
+    self.AddPage(SimpleScrollPage('http://en.wikipedia.org/wiki/Wikipedia',
+                                  self, name='Wikipedia'))
 
     # #1 world commerce website by visits; #3 commerce in the US by time spent
     self.AddPage(SimpleScrollPage('http://www.amazon.com', self))
diff --git a/tools/perf/page_sets/top_10_mobile.py b/tools/perf/page_sets/top_10_mobile.py
index 27fc272..8c6115e 100644
--- a/tools/perf/page_sets/top_10_mobile.py
+++ b/tools/perf/page_sets/top_10_mobile.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class Top10MobilePage(page_module.PageWithDefaultRunNavigate):
+class Top10MobilePage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(Top10MobilePage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/top_25.py b/tools/perf/page_sets/top_25.py
index 43899c0..75b8853 100644
--- a/tools/perf/page_sets/top_25.py
+++ b/tools/perf/page_sets/top_25.py
@@ -7,10 +7,10 @@
 from telemetry.page import page_set as page_set_module
 
 
-class Top25Page(page_module.PageWithDefaultRunNavigate):
+class Top25Page(page_module.Page):
 
-  def __init__(self, url, page_set):
-    super(Top25Page, self).__init__(url=url, page_set=page_set)
+  def __init__(self, url, page_set, name=''):
+    super(Top25Page, self).__init__(url=url, page_set=page_set, name=name)
     self.credentials_path = 'data/credentials.json'
     self.user_agent_type = 'desktop'
     self.archive_data_file = 'data/top_25.json'
@@ -356,9 +356,9 @@
     super(GoogleDocPage, self).__init__(
       # pylint: disable=C0301
       url='https://docs.google.com/document/d/1X-IKNjtEnx-WW5JIKRLsyhz5sbsat3mfTpAPUSX3_s4/view',
-      page_set=page_set)
+      page_set=page_set,
+      name='Docs  (1 open document tab)')
 
-    self.name = 'Docs  (1 open document tab)'
     self.credentials = 'google'
 
   def RunNavigateSteps(self, action_runner):
@@ -503,9 +503,8 @@
   def __init__(self, page_set):
     super(BlogspotPage, self).__init__(
       url='http://googlewebmastercentral.blogspot.com/',
-      page_set=page_set)
-
-    self.name = 'Blogger'
+      page_set=page_set,
+      name='Blogger')
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
@@ -557,9 +556,8 @@
     super(WordpressPage, self).__init__(
       # pylint: disable=C0301
       url='http://en.blog.wordpress.com/2012/09/04/freshly-pressed-editors-picks-for-august-2012/',
-      page_set=page_set)
-
-    self.name = 'Wordpress'
+      page_set=page_set,
+      name='Wordpress')
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
@@ -608,9 +606,8 @@
   def __init__(self, page_set):
     super(FacebookPage, self).__init__(
       url='http://www.facebook.com/barackobama',
-      page_set=page_set)
-
-    self.name = 'Facebook'
+      page_set=page_set,
+      name='Facebook')
     self.credentials = 'facebook'
 
   def RunNavigateSteps(self, action_runner):
@@ -679,9 +676,8 @@
   def __init__(self, page_set):
     super(LinkedinPage, self).__init__(
       url='http://www.linkedin.com/in/linustorvalds',
-      page_set=page_set)
-
-    self.name = 'LinkedIn'
+      page_set=page_set,
+      name='LinkedIn')
 
 
 class WikipediaPage(Top25Page):
@@ -691,9 +687,8 @@
   def __init__(self, page_set):
     super(WikipediaPage, self).__init__(
       url='http://en.wikipedia.org/wiki/Wikipedia',
-      page_set=page_set)
-
-    self.name = 'Wikipedia (1 tab)'
+      page_set=page_set,
+      name='Wikipedia (1 tab)')
 
 
 class TwitterPage(Top25Page):
@@ -703,9 +698,8 @@
   def __init__(self, page_set):
     super(TwitterPage, self).__init__(
       url='https://twitter.com/katyperry',
-      page_set=page_set)
-
-    self.name = 'Twitter'
+      page_set=page_set,
+      name='Twitter')
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
@@ -728,9 +722,8 @@
   def __init__(self, page_set):
     super(PinterestPage, self).__init__(
       url='http://pinterest.com',
-      page_set=page_set)
-
-    self.name = 'Pinterest'
+      page_set=page_set,
+      name='Pinterest')
 
   def RunSmoothness(self, action_runner):
     action_runner.RunAction(ScrollAction(
@@ -746,9 +739,8 @@
   def __init__(self, page_set):
     super(ESPNPage, self).__init__(
       url='http://espn.go.com',
-      page_set=page_set)
-
-    self.name = 'ESPN'
+      page_set=page_set,
+      name='ESPN')
 
   def RunSmoothness(self, action_runner):
     action_runner.RunAction(ScrollAction(
@@ -765,9 +757,8 @@
     super(WeatherDotComPage, self).__init__(
       # pylint: disable=C0301
       url='http://www.weather.com/weather/right-now/Mountain+View+CA+94043',
-      page_set=page_set)
-
-    self.name = 'Weather.com'
+      page_set=page_set,
+      name='Weather.com')
 
 
 class YahooGamesPage(Top25Page):
diff --git a/tools/perf/page_sets/top_desktop_sites_2012Q3.py b/tools/perf/page_sets/top_desktop_sites_2012Q3.py
index 285dea6..8aab0f1 100644
--- a/tools/perf/page_sets/top_desktop_sites_2012Q3.py
+++ b/tools/perf/page_sets/top_desktop_sites_2012Q3.py
@@ -4,10 +4,10 @@
 # pylint: disable=W0401,W0614
 from telemetry.page.actions.all_page_actions import *
 from telemetry.page.page_set import PageSet
-from telemetry.page.page import PageWithDefaultRunNavigate
+from telemetry.page.page import Page
 
 
-class Top2012Q3Page(PageWithDefaultRunNavigate):
+class Top2012Q3Page(Page):
 
   def __init__(self, url, page_set):
     super(Top2012Q3Page, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/tough_animation_cases.py b/tools/perf/page_sets/tough_animation_cases.py
index 6e00173..773f2c7 100644
--- a/tools/perf/page_sets/tough_animation_cases.py
+++ b/tools/perf/page_sets/tough_animation_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughAnimationCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughAnimationCasesPage(page_module.Page):
 
   def __init__(self, url, page_set, need_measurement_ready):
     super(ToughAnimationCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/tough_canvas_cases.py b/tools/perf/page_sets/tough_canvas_cases.py
index 09312be..0f35771 100644
--- a/tools/perf/page_sets/tough_canvas_cases.py
+++ b/tools/perf/page_sets/tough_canvas_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughCanvasCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughCanvasCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ToughCanvasCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/tough_dom_memory_cases.py b/tools/perf/page_sets/tough_dom_memory_cases.py
index 7ce521a..a519584 100644
--- a/tools/perf/page_sets/tough_dom_memory_cases.py
+++ b/tools/perf/page_sets/tough_dom_memory_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughDomMemoryCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughDomMemoryCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ToughDomMemoryCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/tough_energy_cases.py b/tools/perf/page_sets/tough_energy_cases.py
index 7a2320c..1dacf92 100644
--- a/tools/perf/page_sets/tough_energy_cases.py
+++ b/tools/perf/page_sets/tough_energy_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughEnergyCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughEnergyCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ToughEnergyCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/tough_image_cases.py b/tools/perf/page_sets/tough_image_cases.py
index a4cf4b9..0845581 100644
--- a/tools/perf/page_sets/tough_image_cases.py
+++ b/tools/perf/page_sets/tough_image_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughImageCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughImageCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ToughImageCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/tough_layer_cases.py b/tools/perf/page_sets/tough_layer_cases.py
index 795cf53..054552f 100644
--- a/tools/perf/page_sets/tough_layer_cases.py
+++ b/tools/perf/page_sets/tough_layer_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughLayerCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughLayerCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ToughLayerCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/tough_layout_cases.py b/tools/perf/page_sets/tough_layout_cases.py
index de1230e..ab958ad 100644
--- a/tools/perf/page_sets/tough_layout_cases.py
+++ b/tools/perf/page_sets/tough_layout_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughLayoutCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughLayoutCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ToughLayoutCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/tough_memory_multi_tab.py b/tools/perf/page_sets/tough_memory_multi_tab.py
index fb12514..ab73923 100644
--- a/tools/perf/page_sets/tough_memory_multi_tab.py
+++ b/tools/perf/page_sets/tough_memory_multi_tab.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughMemoryMultiTabPage(page_module.PageWithDefaultRunNavigate):
+class ToughMemoryMultiTabPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ToughMemoryMultiTabPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/tough_pinch_zoom_cases.py b/tools/perf/page_sets/tough_pinch_zoom_cases.py
index 7a5d2c7..799cfc4 100644
--- a/tools/perf/page_sets/tough_pinch_zoom_cases.py
+++ b/tools/perf/page_sets/tough_pinch_zoom_cases.py
@@ -7,10 +7,11 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughPinchZoomCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughPinchZoomCasesPage(page_module.Page):
 
-  def __init__(self, url, page_set):
-    super(ToughPinchZoomCasesPage, self).__init__(url=url, page_set=page_set)
+  def __init__(self, url, page_set, name=''):
+    super(ToughPinchZoomCasesPage, self).__init__(url=url, page_set=page_set,
+                                                  name=name)
     self.credentials_path = 'data/credentials.json'
     self.user_agent_type = 'desktop'
     self.archive_data_file = 'data/tough_pinch_zoom_cases.json'
@@ -147,9 +148,7 @@
   def __init__(self, page_set):
     super(BlogSpotPage, self).__init__(
       url='http://googlewebmastercentral.blogspot.com/',
-      page_set=page_set)
-
-    self.name = 'Blogger'
+      page_set=page_set, name='Blogger')
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
@@ -167,9 +166,7 @@
   def __init__(self, page_set):
     super(FacebookPage, self).__init__(
       url='http://www.facebook.com/barackobama',
-      page_set=page_set)
-
-    self.name = 'Facebook'
+      page_set=page_set, name='Facebook')
     self.credentials = 'facebook'
 
   def RunNavigateSteps(self, action_runner):
@@ -188,9 +185,7 @@
   def __init__(self, page_set):
     super(LinkedinPage, self).__init__(
       url='http://www.linkedin.com/in/linustorvalds',
-      page_set=page_set)
-
-    self.name = 'LinkedIn'
+      page_set=page_set, name='LinkedIn')
 
 
 class WikipediaPage(ToughPinchZoomCasesPage):
@@ -200,9 +195,7 @@
   def __init__(self, page_set):
     super(WikipediaPage, self).__init__(
       url='http://en.wikipedia.org/wiki/Wikipedia',
-      page_set=page_set)
-
-    self.name = 'Wikipedia (1 tab)'
+      page_set=page_set, name='Wikipedia (1 tab)')
 
 
 class TwitterPage(ToughPinchZoomCasesPage):
@@ -212,9 +205,7 @@
   def __init__(self, page_set):
     super(TwitterPage, self).__init__(
       url='https://twitter.com/katyperry',
-      page_set=page_set)
-
-    self.name = 'Twitter'
+      page_set=page_set, name='Twitter')
 
   def RunNavigateSteps(self, action_runner):
     action_runner.RunAction(NavigateAction())
@@ -227,9 +218,7 @@
   def __init__(self, page_set):
     super(ESPNPage, self).__init__(
       url='http://espn.go.com/nba',
-      page_set=page_set)
-
-    self.name = 'ESPN'
+      page_set=page_set, name='ESPN')
 
 
 class WeatherDotComPage(ToughPinchZoomCasesPage):
@@ -240,9 +229,7 @@
     super(WeatherDotComPage, self).__init__(
       # pylint: disable=C0301
       url='http://www.weather.com/weather/right-now/Mountain+View+CA+94043',
-      page_set=page_set)
-
-    self.name = 'Weather.com'
+      page_set=page_set, name='Weather.com')
 
 
 class YahooGamePage(ToughPinchZoomCasesPage):
diff --git a/tools/perf/page_sets/tough_scheduling_cases.py b/tools/perf/page_sets/tough_scheduling_cases.py
index 86d3471..30c875d 100644
--- a/tools/perf/page_sets/tough_scheduling_cases.py
+++ b/tools/perf/page_sets/tough_scheduling_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughSchedulingCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughSchedulingCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ToughSchedulingCasesPage, self).__init__(url=url, page_set=page_set)
@@ -318,6 +318,39 @@
         'scroll_distance_function': 'function() { return 400; }'
       }))
 
+class EmptyTouchHandlerPage(ToughSchedulingCasesPage):
+
+  """ Why: Scrolling on a page with a touch handler that consumes no events but
+      may be slow """
+
+  def __init__(self, name, desktop, slow_handler, bounce, page_set):
+    super(EmptyTouchHandlerPage, self).__init__(
+      url='file://tough_scheduling_cases/empty_touch_handler' +
+        ('_desktop' if desktop else '') + '.html?' + name,
+      page_set=page_set)
+
+    if slow_handler:
+      self.synthetic_delays = {
+        'blink.HandleInputEvent': {'target_duration': 0.2}
+      }
+
+    self.bounce = bounce
+
+  def RunSmoothness(self, action_runner):
+    if self.bounce:
+      action = ScrollBounceAction()
+    else:
+      action = ScrollAction(
+        {
+          'scroll_requires_touch': True,
+           """ Speed and distance are tuned to run exactly as long as a scroll
+                bounce """
+          'speed': 400,
+          'scroll_distance_function': 'function() { return 2100; }'
+        })
+
+    action_runner.RunAction(action)
+
 class ToughSchedulingCasesPageSet(page_set_module.PageSet):
 
   """ Tough scheduler latency test cases """
@@ -354,7 +387,8 @@
       'file://tough_scheduling_cases/raf_canvas.html',
       self))
     self.AddPage(Page13(self))
-    self.AddPage(Page14(self))
+    # Disabled for flakiness. See 368532
+    # self.AddPage(Page14(self))
     self.AddPage(Page15(self))
     self.AddPage(Page16(self))
     # Why: Test a requestAnimationFrame handler with concurrent CSS animation
@@ -369,3 +403,49 @@
     self.AddPage(Page18(self))
     self.AddPage(Page19(self))
     self.AddPage(Page20(self))
+    # Why: Baseline for scrolling in the presence of a no-op touch handler
+    self.AddPage(EmptyTouchHandlerPage(
+      name='baseline',
+      desktop=False,
+      slow_handler=False,
+      bounce=False,
+      page_set=self))
+    # Why: Slow handler blocks scroll start
+    self.AddPage(EmptyTouchHandlerPage(
+      name='slow_handler',
+      desktop=False,
+      slow_handler=True,
+      bounce=False,
+      page_set=self))
+    # Why: Slow handler blocks scroll start until touch ACK timeout
+    self.AddPage(EmptyTouchHandlerPage(
+      name='desktop_slow_handler',
+      desktop=True,
+      slow_handler=True,
+      bounce=False,
+      page_set=self))
+    # Why: Scroll bounce showing repeated transitions between scrolling and
+    # sending synchronous touchmove events.  Should be nearly as fast as
+    # scroll baseline.
+    self.AddPage(EmptyTouchHandlerPage(
+      name='bounce',
+      desktop=False,
+      slow_handler=False,
+      bounce=True,
+      page_set=self))
+    # Why: Scroll bounce with slow handler, repeated blocking.
+    self.AddPage(EmptyTouchHandlerPage(
+      name='bounce_slow_handler',
+      desktop=False,
+      slow_handler=True,
+      bounce=True,
+      page_set=self))
+    # Why: Scroll bounce with slow handler on desktop, blocks only once until
+    # ACK timeout.
+    self.AddPage(EmptyTouchHandlerPage(
+      name='bounce_desktop_slow_handler',
+      desktop=True,
+      slow_handler=True,
+      bounce=True,
+      page_set=self))
+
diff --git a/tools/perf/page_sets/tough_scheduling_cases/empty_touch_handler.html b/tools/perf/page_sets/tough_scheduling_cases/empty_touch_handler.html
new file mode 100644
index 0000000..ec45cb0
--- /dev/null
+++ b/tools/perf/page_sets/tough_scheduling_cases/empty_touch_handler.html
@@ -0,0 +1,274 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta name="viewport" content="width=device-width">
+  <title>Empty touch handler</title>
+  <style type="text/css">
+    body {
+      height: 10000px;
+      margin: 0px;
+      background-image: linear-gradient(rgba(0, 0, 0, .1) 50%, transparent 50%, transparent);
+      background-size: 100px 100px;
+    }
+  </style>
+  <script type="text/javascript">
+    function empty(e) {
+    }
+
+    function startExperiment() {
+      window.addEventListener('touchstart', empty);
+      window.addEventListener('touchmove', empty);
+      window.addEventListener('touchend', empty);
+      window.addEventListener('touchcancel', empty);
+      window.addEventListener('wheel', empty);
+    }
+
+    window.addEventListener('load', startExperiment);
+  </script>
+</head>
+<body>
+  <h2>Touch handler scrolling</h2>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+</body>
+</html>
+
+
diff --git a/tools/perf/page_sets/tough_scheduling_cases/empty_touch_handler_desktop.html b/tools/perf/page_sets/tough_scheduling_cases/empty_touch_handler_desktop.html
new file mode 100644
index 0000000..9176cab
--- /dev/null
+++ b/tools/perf/page_sets/tough_scheduling_cases/empty_touch_handler_desktop.html
@@ -0,0 +1,273 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Empty touch handler</title>
+  <style type="text/css">
+    body {
+      height: 10000px;
+      margin: 0px;
+      background-image: linear-gradient(rgba(0, 0, 0, .1) 50%, transparent 50%, transparent);
+      background-size: 100px 100px;
+    }
+  </style>
+  <script type="text/javascript">
+    function empty(e) {
+    }
+
+    function startExperiment() {
+      window.addEventListener('touchstart', empty);
+      window.addEventListener('touchmove', empty);
+      window.addEventListener('touchend', empty);
+      window.addEventListener('touchcancel', empty);
+      window.addEventListener('wheel', empty);
+    }
+
+    window.addEventListener('load', startExperiment);
+  </script>
+</head>
+<body>
+  <h2>Touch handler scrolling</h2>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+  <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps.</p>
+  <p>Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz.</p>
+  <p>Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex.</p>
+  <p>Two driven jocks help fax my big quiz. Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled.</p>
+  <p>Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq. Cozy sphinx waves quart jug of bad milk.</p>
+  <p>A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox.</p>
+  <p>The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV for luck.</p>
+  <p>A wizard's job is to vex chumps quickly in fog. Watch "Jeopardy! ", Alex Trebek's fun TV quiz game. Woven silk pyjamas exchanged for blue quartz.</p>
+  <p>Brawny gods just flocked up to quiz and vex him. Adjusting quiver and bow, Zompyc[1] killed the fox. My faxed joke won a pager in the cable TV quiz show.</p>
+  <p>Amazingly few discotheques provide jukeboxes. My girl wove six dozen plaid jackets before she quit. Six big devils from Japan quickly forgot how to waltz.</p>
+  <p>Big July earthquakes confound zany experimental vow. Foxy parsons quiz and cajole the lovably dim wiki-girl.</p>
+  <p>Have a pick: twenty six letters - no forcing a jumbled quiz! Crazy Fredericka bought many very exquisite opal jewels.</p>
+  <p>Sixty zippers were quickly picked from the woven jute bag. A quick movement of the enemy will jeopardize six gunboats.</p>
+  <p>All questions asked by five watch experts amazed the judge. Jack quietly moved up front and seized the big ball of wax. The quick, brown fox jumps over a lazy dog.</p>
+  <p>DJs flock by when MTV ax quiz prog. Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs. Waltz, bad nymph, for quick jigs vex!</p>
+  <p>Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack. Quick wafting zephyrs vex bold Jim.</p>
+  <p>Quick zephyrs blow, vexing daft Jim. Sex-charged fop blew my junk TV quiz. How quickly daft jumping zebras vex. Two driven jocks help fax my big quiz.</p>
+  <p>Quick, Baz, get my woven flax jodhpurs! "Now fax quiz Jack! " my brave ghost pled. Five quacking zephyrs jolt my wax bed. Flummoxed by job, kvetching W. zaps Iraq.</p>
+  <p>Cozy sphinx waves quart jug of bad milk. A very bad quack might jinx zippy fowls. Few quips galvanized the mock jury box. Quick brown dogs jump over the lazy fox. The jay, pig, fox, zebra, and my wolves quack! Blowzy red vixens fight for a quick jump. Joaquin Phoenix was gazed by MTV</p>
+</body>
+</html>
+
+
diff --git a/tools/perf/page_sets/tough_scrolling_cases.py b/tools/perf/page_sets/tough_scrolling_cases.py
index f4a402f..a74655a 100644
--- a/tools/perf/page_sets/tough_scrolling_cases.py
+++ b/tools/perf/page_sets/tough_scrolling_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughScrollingCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughScrollingCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ToughScrollingCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/tough_texture_upload_cases.py b/tools/perf/page_sets/tough_texture_upload_cases.py
index 73c2e1d..53819a4 100644
--- a/tools/perf/page_sets/tough_texture_upload_cases.py
+++ b/tools/perf/page_sets/tough_texture_upload_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughTextureUploadCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughTextureUploadCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(
diff --git a/tools/perf/page_sets/tough_video_cases.py b/tools/perf/page_sets/tough_video_cases.py
index 23ff4a2..fc23647 100644
--- a/tools/perf/page_sets/tough_video_cases.py
+++ b/tools/perf/page_sets/tough_video_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughVideoCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughVideoCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ToughVideoCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/tough_webgl_cases.py b/tools/perf/page_sets/tough_webgl_cases.py
index 5d1dff8..6d8e734 100644
--- a/tools/perf/page_sets/tough_webgl_cases.py
+++ b/tools/perf/page_sets/tough_webgl_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class ToughWebglCasesPage(page_module.PageWithDefaultRunNavigate):
+class ToughWebglCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(ToughWebglCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/typical_25.py b/tools/perf/page_sets/typical_25.py
index c2454f3..94dd7d7 100644
--- a/tools/perf/page_sets/typical_25.py
+++ b/tools/perf/page_sets/typical_25.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class Typical25Page(page_module.PageWithDefaultRunNavigate):
+class Typical25Page(page_module.Page):
 
   def __init__(self, url, page_set):
     super(Typical25Page, self).__init__(url=url, page_set=page_set)
diff --git a/tools/perf/page_sets/webrtc_cases.py b/tools/perf/page_sets/webrtc_cases.py
index a02b1c8..a9d83fb 100644
--- a/tools/perf/page_sets/webrtc_cases.py
+++ b/tools/perf/page_sets/webrtc_cases.py
@@ -7,7 +7,7 @@
 from telemetry.page import page_set as page_set_module
 
 
-class WebrtcCasesPage(page_module.PageWithDefaultRunNavigate):
+class WebrtcCasesPage(page_module.Page):
 
   def __init__(self, url, page_set):
     super(WebrtcCasesPage, self).__init__(url=url, page_set=page_set)
diff --git a/tools/safely-roll-deps.py b/tools/safely-roll-deps.py
index 0871348..2f1e490 100755
--- a/tools/safely-roll-deps.py
+++ b/tools/safely-roll-deps.py
@@ -45,6 +45,18 @@
   return old_rev
 
 
+class PrintSubprocess(object):
+  """Wrapper for subprocess2 which prints out every command."""
+  def __getattr__(self, attr):
+    def _run_subprocess2(cmd, *args, **kwargs):
+      print cmd
+      sys.stdout.flush()
+      return getattr(subprocess2, attr)(cmd, *args, **kwargs)
+    return _run_subprocess2
+
+prnt_subprocess = PrintSubprocess()
+
+
 def main():
   tool_dir = os.path.dirname(os.path.abspath(__file__))
   parser = optparse.OptionParser(usage='%prog [options] <project> <new rev>',
@@ -87,8 +99,8 @@
   os.environ['EDITOR'] = 'true'
 
   if options.force and not options.dry_run:
-    subprocess2.check_call(['git', 'clean', '-d', '-f'])
-    subprocess2.call(['git', 'rebase', '--abort'])
+    prnt_subprocess.check_call(['git', 'clean', '-d', '-f'])
+    prnt_subprocess.call(['git', 'rebase', '--abort'])
 
   old_branch = scm.GIT.GetBranch(root_dir)
   new_branch = '%s_roll' % project
@@ -99,19 +111,19 @@
   if old_branch == new_branch:
     if options.force:
       if not options.dry_run:
-        subprocess2.check_call(['git', 'checkout', options.upstream, '-f'])
-        subprocess2.call(['git', 'branch', '-D', old_branch])
+        prnt_subprocess.check_call(['git', 'checkout', options.upstream, '-f'])
+        prnt_subprocess.call(['git', 'branch', '-D', old_branch])
     else:
       parser.error('Please delete the branch %s and move to a different branch'
                    % new_branch)
 
   if not options.dry_run:
-    subprocess2.check_call(['git', 'fetch', 'origin'])
-    subprocess2.call(['git', 'svn', 'fetch'])
+    prnt_subprocess.check_call(['git', 'fetch', 'origin'])
+    prnt_subprocess.call(['git', 'svn', 'fetch'])
     branch_cmd = ['git', 'checkout', '-b', new_branch, options.upstream]
     if options.force:
       branch_cmd.append('-f')
-    subprocess2.check_output(branch_cmd)
+    prnt_subprocess.check_output(branch_cmd)
 
   try:
     old_rev = int(process_deps(os.path.join(root_dir, 'DEPS'), project, new_rev,
@@ -127,8 +139,9 @@
       print 'Commit message: ' + commit_msg
       return 0
 
-    subprocess2.check_output(['git', 'commit', '-m', commit_msg, 'DEPS'])
-    subprocess2.check_call(['git', 'diff', '--no-ext-diff', options.upstream])
+    prnt_subprocess.check_output(['git', 'commit', '-m', commit_msg, 'DEPS'])
+    prnt_subprocess.check_call(['git', 'diff', '--no-ext-diff',
+                                options.upstream])
     upload_cmd = ['git', 'cl', 'upload']
     if options.commit:
       upload_cmd.append('--use-commit-queue')
@@ -136,11 +149,11 @@
       upload_cmd.append('--send-mail')
     if options.cc:
       upload_cmd.extend(['--cc', options.cc])
-    subprocess2.check_call(upload_cmd)
+    prnt_subprocess.check_call(upload_cmd)
   finally:
     if not options.dry_run:
-      subprocess2.check_output(['git', 'checkout', old_branch])
-      subprocess2.check_output(['git', 'branch', '-D', new_branch])
+      prnt_subprocess.check_output(['git', 'checkout', old_branch])
+      prnt_subprocess.check_output(['git', 'branch', '-D', new_branch])
   return 0
 
 
diff --git a/tools/telemetry/telemetry/core/backends/chrome/chrome_browser_options.py b/tools/telemetry/telemetry/core/backends/chrome/chrome_browser_options.py
index d2533a0..8922607 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/chrome_browser_options.py
+++ b/tools/telemetry/telemetry/core/backends/chrome/chrome_browser_options.py
@@ -33,7 +33,7 @@
     # Create a browser with oobe property.
     self.create_browser_with_oobe = False
     # Clear enterprise policy before logging in.
-    self.clear_enterprise_policy = False
+    self.clear_enterprise_policy = True
 
     self.auto_login = True
     self.gaia_login = False
diff --git a/tools/telemetry/telemetry/core/backends/chrome/cros_browser_backend.py b/tools/telemetry/telemetry/core/backends/chrome/cros_browser_backend.py
index 8b64494..5cf8abe 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/cros_browser_backend.py
+++ b/tools/telemetry/telemetry/core/backends/chrome/cros_browser_backend.py
@@ -16,12 +16,6 @@
 
 
 class CrOSBrowserBackend(chrome_browser_backend.ChromeBrowserBackend):
-  # Some developers' workflow includes running the Chrome process from
-  # /usr/local/... instead of the default location. We have to check for both
-  # paths in order to support this workflow.
-  CHROME_PATHS = ['/opt/google/chrome/chrome ',
-                  '/usr/local/opt/google/chrome/chrome ']
-
   def __init__(self, browser_type, browser_options, cri, is_guest,
                extensions_to_load):
     super(CrOSBrowserBackend, self).__init__(
@@ -58,25 +52,19 @@
       cri.Chown(extension_dir)
       e.local_path = os.path.join(extension_dir, os.path.basename(e.path))
 
-    self._cri.RunCmdOnDevice(['stop', 'ui'])
-
-    if self.browser_options.clear_enterprise_policy:
-      self._cri.RmRF('/var/lib/whitelist/*')
-      self._cri.RmRF('/home/chronos/Local\ State')
+    self._cri.RestartUI(self.browser_options.clear_enterprise_policy)
+    util.WaitFor(self.IsBrowserRunning, 20)
 
     # Delete test user's cryptohome vault (user data directory).
     if not self.browser_options.dont_override_profile:
       self._cri.RunCmdOnDevice(['cryptohome', '--action=remove', '--force',
-                                '--user=%s' % self.browser_options.username])
+                                '--user=%s' % self._username])
     if self.browser_options.profile_dir:
       cri.RmRF(self.profile_directory)
       cri.PushFile(self.browser_options.profile_dir + '/Default',
                    self.profile_directory)
       cri.Chown(self.profile_directory)
 
-    self._cri.RunCmdOnDevice(['start', 'ui'])
-    util.WaitFor(self.IsBrowserRunning, 20)
-
     self._SetBranchNumber(self._GetChromeVersion())
 
   def GetBrowserStartupArgs(self):
@@ -100,42 +88,8 @@
 
     return args
 
-  def _GetSessionManagerPid(self, procs):
-    """Returns the pid of the session_manager process, given the list of
-    processes."""
-    for pid, process, _, _ in procs:
-      if process.startswith('/sbin/session_manager '):
-        return pid
-    return None
-
-  def _GetChromeProcess(self):
-    """Locates the the main chrome browser process.
-
-    Chrome on cros is usually in /opt/google/chrome, but could be in
-    /usr/local/ for developer workflows - debug chrome is too large to fit on
-    rootfs.
-
-    Chrome spawns multiple processes for renderers. pids wrap around after they
-    are exhausted so looking for the smallest pid is not always correct. We
-    locate the session_manager's pid, and look for the chrome process that's an
-    immediate child. This is the main browser process.
-    """
-    procs = self._cri.ListProcesses()
-    session_manager_pid = self._GetSessionManagerPid(procs)
-    if not session_manager_pid:
-      return None
-
-    # Find the chrome process that is the child of the session_manager.
-    for pid, process, ppid, _ in procs:
-      if ppid != session_manager_pid:
-        continue
-      for path in self.CHROME_PATHS:
-        if process.startswith(path):
-          return {'pid': pid, 'path': path, 'args': process}
-    return None
-
   def _GetChromeVersion(self):
-    result = util.WaitFor(self._GetChromeProcess, timeout=30)
+    result = util.WaitFor(self._cri.GetChromeProcess, timeout=30)
     assert result and result['path']
     (version, _) = self._cri.RunCmdOnDevice([result['path'], '--version'])
     assert version
@@ -143,14 +97,11 @@
 
   @property
   def pid(self):
-    result = self._GetChromeProcess()
-    if result and 'pid' in result:
-      return result['pid']
-    return None
+    return self._cri.GetChromePid()
 
   @property
   def browser_directory(self):
-    result = self._GetChromeProcess()
+    result = self._cri.GetChromeProcess()
     if result and 'path' in result:
       return os.path.dirname(result['path'])
     return None
@@ -208,20 +159,23 @@
         # Guest browsing shuts down the current browser and launches an
         # incognito browser in a separate process, which we need to wait for.
         util.WaitFor(lambda: pid != self.pid, 10)
-        self._WaitForBrowserToComeUp()
       elif self.browser_options.gaia_login:
-        self.oobe.NavigateGaiaLogin(self.browser_options.username,
-                                    self.browser_options.password)
+        try:
+          self.oobe.NavigateGaiaLogin(self._username, self._password)
+        except util.TimeoutException:
+          self._cri.TakeScreenShot('gaia-login')
+          raise
       else:
-        self.oobe.NavigateFakeLogin(self.browser_options.username,
-                                    self.browser_options.password)
+        self.oobe.NavigateFakeLogin(self._username, self._password)
+      self._WaitForLogin()
 
     logging.info('Browser is up!')
 
   def Close(self):
     super(CrOSBrowserBackend, self).Close()
 
-    self._RestartUI() # Logs out.
+    if self._cri:
+      self._cri.RestartUI(False) # Logs out.
 
     util.WaitFor(lambda: not self._IsCryptohomeMounted(), 30)
 
@@ -249,17 +203,6 @@
   def GetStackTrace(self):
     return 'Cannot get stack trace on CrOS'
 
-  def _RestartUI(self):
-    if self._cri:
-      logging.info('(Re)starting the ui (logs the user out)')
-      if self._cri.IsServiceRunning('ui'):
-        self._cri.RunCmdOnDevice(['restart', 'ui'])
-      else:
-        self._cri.RunCmdOnDevice(['start', 'ui'])
-
-  def TakeScreenShot(self, screenshot_prefix):
-    self._cri.TakeScreenShot(screenshot_prefix)
-
   @property
   @decorators.Cache
   def misc_web_contents_backend(self):
@@ -274,8 +217,16 @@
   def oobe_exists(self):
     return self.misc_web_contents_backend.oobe_exists
 
+  @property
+  def _username(self):
+    return self.browser_options.username
+
+  @property
+  def _password(self):
+    return self.browser_options.password
+
   def _IsCryptohomeMounted(self):
-    username = '$guest' if self._is_guest else self.browser_options.username
+    username = '$guest' if self._is_guest else self._username
     return self._cri.IsCryptohomeMounted(username, self._is_guest)
 
   def _IsLoggedIn(self):
@@ -285,23 +236,24 @@
             self.HasBrowserFinishedLaunching() and
             not self.oobe_exists)
 
-  def WaitForLogin(self):
+  def _WaitForLogin(self):
     if self._is_guest:
+      self._WaitForBrowserToComeUp()
       util.WaitFor(self._IsCryptohomeMounted, 30)
       return
 
     try:
       util.WaitFor(self._IsLoggedIn, 60)
     except util.TimeoutException:
-      self.TakeScreenShot('login-screen')
+      self._cri.TakeScreenShot('login-screen')
       raise exceptions.LoginException('Timed out going through login screen')
 
     # Wait for extensions to load.
     try:
       self._WaitForBrowserToComeUp()
     except util.TimeoutException:
-      logging.error('Chrome args: %s' % self._GetChromeProcess()['args'])
-      self.TakeScreenShot('extension-timeout')
+      logging.error('Chrome args: %s' % self._cri.GetChromeProcess()['args'])
+      self._cri.TakeScreenShot('extension-timeout')
       raise
 
     # Workaround for crbug.com/329271, crbug.com/334726.
diff --git a/tools/telemetry/telemetry/core/backends/chrome/cros_interface.py b/tools/telemetry/telemetry/core/backends/chrome/cros_interface.py
index edc6f8d..bad6022 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/cros_interface.py
+++ b/tools/telemetry/telemetry/core/backends/chrome/cros_interface.py
@@ -15,6 +15,12 @@
 # around pexpect, I suspect, if we wanted it to be faster. But, this was
 # convenient.
 
+# Some developers' workflow includes running the Chrome process from
+# /usr/local/... instead of the default location. We have to check for both
+# paths in order to support this workflow.
+_CHROME_PATHS = ['/opt/google/chrome/chrome ',
+                '/usr/local/opt/google/chrome/chrome ']
+
 def IsRunningOnCrosDevice():
   """Returns True if we're on a ChromeOS device."""
   lsb_release = '/etc/lsb-release'
@@ -287,6 +293,47 @@
     logging.debug("ListProcesses(<predicate>)->[%i processes]" % len(procs))
     return procs
 
+  def _GetSessionManagerPid(self, procs):
+    """Returns the pid of the session_manager process, given the list of
+    processes."""
+    for pid, process, _, _ in procs:
+      if process.startswith('/sbin/session_manager '):
+        return pid
+    return None
+
+  def GetChromeProcess(self):
+    """Locates the the main chrome browser process.
+
+    Chrome on cros is usually in /opt/google/chrome, but could be in
+    /usr/local/ for developer workflows - debug chrome is too large to fit on
+    rootfs.
+
+    Chrome spawns multiple processes for renderers. pids wrap around after they
+    are exhausted so looking for the smallest pid is not always correct. We
+    locate the session_manager's pid, and look for the chrome process that's an
+    immediate child. This is the main browser process.
+    """
+    procs = self.ListProcesses()
+    session_manager_pid = self._GetSessionManagerPid(procs)
+    if not session_manager_pid:
+      return None
+
+    # Find the chrome process that is the child of the session_manager.
+    for pid, process, ppid, _ in procs:
+      if ppid != session_manager_pid:
+        continue
+      for path in _CHROME_PATHS:
+        if process.startswith(path):
+          return {'pid': pid, 'path': path, 'args': process}
+    return None
+
+  def GetChromePid(self):
+    """Returns pid of main chrome browser process."""
+    result = self.GetChromeProcess()
+    if result and 'pid' in result:
+      return result['pid']
+    return None
+
   def RmRF(self, filename):
     logging.debug("rm -rf %s" % filename)
     self.RunCmdOnDevice(['rm', '-rf', filename], quiet=True)
@@ -384,3 +431,15 @@
             screenshot_file])
         return
     logging.warning('screenshot directory full.')
+
+  def RestartUI(self, clear_enterprise_policy):
+    logging.info('(Re)starting the ui (logs the user out)')
+    if clear_enterprise_policy:
+      self.RunCmdOnDevice(['stop', 'ui'])
+      self.RmRF('/var/lib/whitelist/*')
+      self.RmRF('/home/chronos/Local\ State')
+
+    if self.IsServiceRunning('ui'):
+      self.RunCmdOnDevice(['restart', 'ui'])
+    else:
+      self.RunCmdOnDevice(['start', 'ui'])
diff --git a/tools/telemetry/telemetry/core/backends/chrome/cros_test_case.py b/tools/telemetry/telemetry/core/backends/chrome/cros_test_case.py
index a12d768..5fd71d6 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/cros_test_case.py
+++ b/tools/telemetry/telemetry/core/backends/chrome/cros_test_case.py
@@ -74,3 +74,12 @@
     return util.WaitFor(
         lambda: extension.EvaluateJavaScript('window.__login_status'), 10)
 
+  def _Credentials(self, credentials_path):
+    """Returns credentials from file."""
+    credentials_path = os.path.join(os.path.dirname(__file__),
+                                    credentials_path)
+    if os.path.isfile(credentials_path):
+      with open(credentials_path) as f:
+        username, password = f.read().rstrip().split(':')
+        return (username, password)
+    return (None, None)
diff --git a/tools/telemetry/telemetry/core/backends/chrome/cros_unittest.py b/tools/telemetry/telemetry/core/backends/chrome/cros_unittest.py
index 2d5277c..35f3f28 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/cros_unittest.py
+++ b/tools/telemetry/telemetry/core/backends/chrome/cros_unittest.py
@@ -64,6 +64,19 @@
         pass
       util.WaitFor(lambda: not self._IsCryptohomeMounted(), 20)
 
+  @test.Enabled('chromeos')
+  def testGaiaLogin(self):
+    """Tests gaia login. Credentials are expected to be found in a
+    credentials.txt file, with a single line of format username:password."""
+    if self._is_guest:
+      return
+    (username, password) = self._Credentials('credentials.txt')
+    if username and password:
+      with self._CreateBrowser(gaia_login=True,
+                               username=username,
+                               password=password):
+        self.assertTrue(util.WaitFor(self._IsCryptohomeMounted, 10))
+
 
 class CrOSScreenLockerTest(cros_test_case.CrOSTestCase):
   def _IsScreenLocked(self, browser):
diff --git a/tools/telemetry/telemetry/core/backends/chrome/misc_web_contents_backend.py b/tools/telemetry/telemetry/core/backends/chrome/misc_web_contents_backend.py
index 592a96b..efa0c77 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/misc_web_contents_backend.py
+++ b/tools/telemetry/telemetry/core/backends/chrome/misc_web_contents_backend.py
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from telemetry.core import exceptions
 from telemetry.core.backends.chrome import inspector_backend_list
 from telemetry.core.backends.chrome import oobe
 
@@ -12,15 +13,18 @@
   """
 
   def __init__(self, browser_backend):
-    def OobeBackendWrapper(inspector_backend, backend_list):
-      return oobe.Oobe(inspector_backend, backend_list, browser_backend)
     super(MiscWebContentsBackend, self).__init__(
-        browser_backend, backend_wrapper=OobeBackendWrapper)
+        browser_backend, backend_wrapper=oobe.Oobe)
 
   @property
   def oobe_exists(self):
     """Lightweight property to determine if the oobe webui is visible."""
-    return bool(len(self))
+    try:
+      return bool(len(self))
+    except (exceptions.BrowserGoneException,
+            exceptions.BrowserConnectionGoneException,
+            exceptions.TabCrashException):
+      return False
 
   def GetOobe(self):
     if not len(self):
diff --git a/tools/telemetry/telemetry/core/backends/chrome/oobe.py b/tools/telemetry/telemetry/core/backends/chrome/oobe.py
index ded264c..5206763 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/oobe.py
+++ b/tools/telemetry/telemetry/core/backends/chrome/oobe.py
@@ -9,48 +9,8 @@
 from telemetry.core import util
 
 class Oobe(web_contents.WebContents):
-  def __init__(self, inspector_backend, backend_list, browser_backend):
+  def __init__(self, inspector_backend, backend_list):
     super(Oobe, self).__init__(inspector_backend, backend_list)
-    self._backend = browser_backend
-
-  def _SigninUIState(self):
-    """Returns the signin ui state of the oobe. HIDDEN: 0, GAIA_SIGNIN: 1,
-    ACCOUNT_PICKER: 2, WRONG_HWID_WARNING: 3, MANAGED_USER_CREATION_FLOW: 4.
-    These values are in
-    chrome/browser/resources/chromeos/login/display_manager.js
-    """
-    return self.EvaluateJavaScript('''
-      loginHeader = document.getElementById('login-header-bar')
-      if (loginHeader) {
-        loginHeader.signinUIState_;
-      }
-    ''')
-
-  def _WaitForSigninScreen(self):
-    """Waits for oobe to be on the signin or account picker screen."""
-    def OnAccountPickerScreen():
-      signin_state = self._SigninUIState()
-      # GAIA_SIGNIN or ACCOUNT_PICKER screens.
-      return signin_state == 1 or signin_state == 2
-    try:
-      util.WaitFor(OnAccountPickerScreen, 60)
-    except util.TimeoutException:
-      raise exceptions.LoginException('Timed out waiting for signin screen, '
-                                      'signin state %d' % self._SigninUIState())
-
-  def _ClickBrowseAsGuest(self):
-    """Click the Browse As Guest button on the account picker screen. This will
-    restart the browser, and we could have a tab crash or a browser crash."""
-    try:
-      self.EvaluateJavaScript("""
-          var guest = document.getElementById("guest-user-button");
-          if (guest) {
-            guest.click();
-          }
-      """)
-    except (exceptions.TabCrashException,
-            exceptions.BrowserConnectionGoneException):
-      pass
 
   def _GaiaLoginContext(self):
     for gaia_context in range(15):
@@ -62,47 +22,30 @@
         pass
     return None
 
-  def NavigateGuestLogin(self):
-    """Navigates through oobe login screen as guest."""
-    logging.info('Logging in as guest')
+  def _ExecuteOobeApi(self, api, *args):
+    logging.info('Invoking %s' % api)
     util.WaitFor(lambda: self.EvaluateJavaScript(
-        'typeof Oobe !== \'undefined\''), 10)
+        "typeof Oobe !== 'undefined'"), 10)
 
-    if self.EvaluateJavaScript(
-        "typeof Oobe.guestLoginForTesting != 'undefined'"):
-      self.ExecuteJavaScript('Oobe.guestLoginForTesting();')
-    else:
-      self._WaitForSigninScreen()
-      self._ClickBrowseAsGuest()
+    if self.EvaluateJavaScript("typeof %s == 'undefined'" % api):
+      raise exceptions.LoginException('%s js api missing' % api)
 
-    self._backend.WaitForLogin()
+    js = api + '(' + ("'%s'," * len(args)).rstrip(',') + ');'
+    self.ExecuteJavaScript(js % args)
+
+  def NavigateGuestLogin(self):
+    """Logs in as guest."""
+    self._ExecuteOobeApi('Oobe.guestLoginForTesting')
 
   def NavigateFakeLogin(self, username, password):
-    """Logs in using Oobe.loginForTesting."""
-    logging.info('Invoking Oobe.loginForTesting')
-    util.WaitFor(lambda: self.EvaluateJavaScript(
-        'typeof Oobe !== \'undefined\''), 10)
-
-    if self.EvaluateJavaScript(
-        'typeof Oobe.loginForTesting == \'undefined\''):
-      raise exceptions.LoginException('Oobe.loginForTesting js api missing')
-
-    self.ExecuteJavaScript(
-        'Oobe.loginForTesting(\'%s\', \'%s\');' % (username, password))
-    self._backend.WaitForLogin()
+    """Fake user login."""
+    self._ExecuteOobeApi('Oobe.loginForTesting', username, password)
 
   def NavigateGaiaLogin(self, username, password):
-    """Logs into the GAIA service with provided credentials."""
-    logging.info('Invoking Oobe.addUserForTesting')
-    util.WaitFor(lambda: self.EvaluateJavaScript(
-        'typeof Oobe !== \'undefined\''), 10)
-    self.ExecuteJavaScript('Oobe.addUserForTesting();')
+    """Logs in to GAIA with provided credentials."""
+    self._ExecuteOobeApi('Oobe.addUserForTesting')
 
-    try:
-      gaia_context = util.WaitFor(self._GaiaLoginContext, timeout=30)
-    except util.TimeoutException:
-      self._backend.TakeScreenShot('add-user-screen')
-      raise
+    gaia_context = util.WaitFor(self._GaiaLoginContext, timeout=30)
 
     self.ExecuteJavaScriptInContext("""
         document.getElementById('Email').value='%s';
@@ -110,4 +53,3 @@
         document.getElementById('signIn').click();"""
             % (username, password),
         gaia_context)
-    self._backend.WaitForLogin()
diff --git a/tools/telemetry/telemetry/core/backends/chrome/tracing_backend.py b/tools/telemetry/telemetry/core/backends/chrome/tracing_backend.py
index 1e1c405..9050c2f 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/tracing_backend.py
+++ b/tools/telemetry/telemetry/core/backends/chrome/tracing_backend.py
@@ -10,6 +10,19 @@
 from telemetry.core.backends.chrome import tracing_timeline_data
 
 
+# All tracing categories not disabled-by-default
+DEFAULT_TRACE_CATEGORIES = None
+
+
+# Categories for absolute minimum overhead tracing. This contains no
+# sub-traces of thread tasks, so it's only useful for capturing the
+# cpu-time spent on threads (as well as needed benchmark traces)
+MINIMAL_TRACE_CATEGORIES = ("toplevel,"
+                            "benchmark,"
+                            "webkit.console,"
+                            "trace_event_overhead")
+
+
 class TracingUnsupportedException(Exception):
   pass
 
diff --git a/tools/telemetry/telemetry/page/actions/all_page_actions.py b/tools/telemetry/telemetry/page/actions/all_page_actions.py
index 1fff40c..d11525f 100644
--- a/tools/telemetry/telemetry/page/actions/all_page_actions.py
+++ b/tools/telemetry/telemetry/page/actions/all_page_actions.py
@@ -24,6 +24,7 @@
 from telemetry.page.actions.repaint_continuously import (
   RepaintContinuouslyAction)
 from telemetry.page.actions.scroll import ScrollAction
+from telemetry.page.actions.scroll_bounce import ScrollBounceAction
 from telemetry.page.actions.seek import SeekAction
 from telemetry.page.actions.tap import TapAction
 from telemetry.page.actions.swipe import SwipeAction
@@ -38,6 +39,3 @@
 
 def FindClassWithName(name):
   return _page_action_classes.get(name)
-
-def RegisterClassForTest(name, clazz):
-  _page_action_classes[name] = clazz
diff --git a/tools/telemetry/telemetry/page/actions/gesture_common.js b/tools/telemetry/telemetry/page/actions/gesture_common.js
index d977e37..1d21628 100644
--- a/tools/telemetry/telemetry/page/actions/gesture_common.js
+++ b/tools/telemetry/telemetry/page/actions/gesture_common.js
@@ -13,6 +13,15 @@
                  left: bound.left,
                  width: bound.width,
                  height: bound.height };
+    if (rect.top < 0) {
+      rect.height += rect.top;
+      rect.top = 0;
+    }
+    if (rect.left < 0) {
+      rect.width += rect.left;
+      rect.left = 0;
+    }
+
     var outsideHeight = (rect.top + rect.height) - window.innerHeight;
     var outsideWidth = (rect.left + rect.width) - window.innerWidth;
 
diff --git a/tools/telemetry/telemetry/page/actions/scroll_bounce.js b/tools/telemetry/telemetry/page/actions/scroll_bounce.js
new file mode 100644
index 0000000..fbbf477
--- /dev/null
+++ b/tools/telemetry/telemetry/page/actions/scroll_bounce.js
@@ -0,0 +1,58 @@
+// 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.
+
+'use strict';
+
+(function() {
+  function supportedByBrowser() {
+    return !!(window.chrome &&
+              chrome.gpuBenchmarking &&
+              chrome.gpuBenchmarking.scrollBounce);
+  }
+
+  function ScrollBounceAction(opt_callback) {
+    var self = this;
+
+    this.beginMeasuringHook = function() {}
+    this.endMeasuringHook = function() {}
+
+    this.callback_ = opt_callback;
+  }
+
+  ScrollBounceAction.prototype.start = function(options) {
+    this.options_ = options;
+    // Assign this.element_ here instead of constructor, because the constructor
+    // ensures this method will be called after the document is loaded.
+    this.element_ = this.options_.element;
+    requestAnimationFrame(this.startGesture_.bind(this));
+  };
+
+  ScrollBounceAction.prototype.startGesture_ = function() {
+    this.beginMeasuringHook();
+
+    var rect = __GestureCommon_GetBoundingVisibleRect(this.options_.element);
+    var start_left =
+        rect.left + rect.width * this.options_.left_start_percentage;
+    var start_top =
+        rect.top + rect.height * this.options_.top_start_percentage;
+    chrome.gpuBenchmarking.scrollBounce(this.options_.direction,
+                                        this.options_.distance,
+                                        this.options_.overscroll,
+                                        this.options_.repeat_count,
+                                        this.onGestureComplete_.bind(this),
+                                        start_left, start_top,
+                                        this.options_.speed);
+  };
+
+  ScrollBounceAction.prototype.onGestureComplete_ = function() {
+    this.endMeasuringHook();
+
+    // We're done.
+    if (this.callback_)
+      this.callback_();
+  };
+
+  window.__ScrollBounceAction = ScrollBounceAction;
+  window.__ScrollBounceAction_SupportedByBrowser = supportedByBrowser;
+})();
diff --git a/tools/telemetry/telemetry/page/actions/scroll_bounce.py b/tools/telemetry/telemetry/page/actions/scroll_bounce.py
new file mode 100644
index 0000000..755a1f3
--- /dev/null
+++ b/tools/telemetry/telemetry/page/actions/scroll_bounce.py
@@ -0,0 +1,121 @@
+# 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.
+import os
+
+from telemetry.page.actions.gesture_action import GestureAction
+from telemetry.page.actions import page_action
+
+class ScrollBounceAction(GestureAction):
+  def __init__(self, attributes=None):
+    super(ScrollBounceAction, self).__init__(attributes)
+
+  def WillRunAction(self, page, tab):
+    for js_file in ['gesture_common.js', 'scroll_bounce.js']:
+      with open(os.path.join(os.path.dirname(__file__), js_file)) as f:
+        js = f.read()
+        tab.ExecuteJavaScript(js)
+
+    # Fail if browser doesn't support synthetic scroll bounce gestures.
+    if not tab.EvaluateJavaScript(
+        'window.__ScrollBounceAction_SupportedByBrowser()'):
+      raise page_action.PageActionNotSupported(
+          'Synthetic scroll bounce not supported for this browser')
+
+    # Fail if we can't send touch events (bouncing is really only
+    # interesting for touch)
+    if not GestureAction.IsGestureSourceTypeSupported(tab, 'touch'):
+      raise page_action.PageActionNotSupported(
+          'Touch scroll not supported for this browser')
+
+    if (GestureAction.GetGestureSourceTypeFromOptions(tab) ==
+        'chrome.gpuBenchmarking.MOUSE_INPUT'):
+      raise page_action.PageActionNotSupported(
+          'ScrollBounce page action does not support mouse input')
+
+    done_callback = 'function() { window.__scrollBounceActionDone = true; }'
+    tab.ExecuteJavaScript("""
+        window.__scrollBounceActionDone = false;
+        window.__scrollBounceAction = new __ScrollBounceAction(%s);"""
+        % (done_callback))
+
+  def RunGesture(self, page, tab):
+    left_start_percentage = 0.5
+    top_start_percentage = 0.5
+    direction = 'down'
+    # Should be big enough to do more than just hide the URL bar.
+    distance = 100
+    # This needs to be < height / repeat_count so we don't walk off the screen.
+    # We also probably don't want to spend more than a couple frames in
+    # overscroll since it may mask any synthetic delays.
+    overscroll = 10
+    # It's the transitions we really want to stress, make this big.
+    repeat_count = 10
+    # 7 pixels per frame should be plenty of frames.
+    speed = 400
+    if hasattr(self, 'left_start_percentage'):
+      left_start_percentage = self.left_start_percentage
+    if hasattr(self, 'top_start_percentage'):
+      top_start_percentage = self.top_start_percentage
+    if hasattr(self, 'direction'):
+      direction = self.direction
+      if direction not in ['down', 'up', 'left', 'right']:
+        raise page_action.PageActionNotSupported(
+            'Invalid scroll bounce direction: %s' % direction)
+    if hasattr(self, 'distance'):
+      distance = self.distance
+    if hasattr(self, 'overscroll'):
+      overscroll = self.overscroll
+    if hasattr(self, 'repeat_count'):
+      repeat_count = self.repeat_count
+    if hasattr(self, 'speed'):
+      speed = self.speed
+    if hasattr(self, 'element_function'):
+      tab.ExecuteJavaScript("""
+          (%s)(function(element) { window.__scrollBounceAction.start(
+             { element: element,
+               left_start_percentage: %s,
+               top_start_percentage: %s,
+               direction: '%s',
+               distance: %s,
+               overscroll: %s,
+               repeat_count: %s,
+               speed: %s })
+             });""" % (self.element_function,
+                       left_start_percentage,
+                       top_start_percentage,
+                       direction,
+                       distance,
+                       overscroll,
+                       repeat_count,
+                       speed))
+    else:
+      tab.ExecuteJavaScript("""
+          window.__scrollBounceAction.start(
+          { element: document.body,
+            left_start_percentage: %s,
+            top_start_percentage: %s,
+            direction: '%s',
+            distance: %s,
+            overscroll: %s,
+            repeat_count: %s,
+            speed: %s });"""
+        % (left_start_percentage,
+           top_start_percentage,
+           direction,
+           distance,
+           overscroll,
+           repeat_count,
+           speed))
+
+    tab.WaitForJavaScriptExpression('window.__scrollBounceActionDone', 60)
+
+  def CanBeBound(self):
+    return True
+
+  def BindMeasurementJavaScript(self, tab, start_js, stop_js):
+    # Make the scroll bounce action start and stop measurement automatically.
+    tab.ExecuteJavaScript("""
+        window.__scrollBounceAction.beginMeasuringHook = function() { %s };
+        window.__scrollBounceAction.endMeasuringHook = function() { %s };
+    """ % (start_js, stop_js))
diff --git a/tools/telemetry/telemetry/page/actions/scroll_unittest.py b/tools/telemetry/telemetry/page/actions/scroll_unittest.py
index 98684f9..d463038 100644
--- a/tools/telemetry/telemetry/page/actions/scroll_unittest.py
+++ b/tools/telemetry/telemetry/page/actions/scroll_unittest.py
@@ -80,7 +80,11 @@
     # scrollable area being more than twice as tall as the viewport) would
     # result in a scroll location outside of the viewport bounds.
     self._tab.ExecuteJavaScript("""document.body.style.height =
-                           (2 * window.innerHeight + 1) + 'px';""")
+                           (3 * window.innerHeight + 1) + 'px';""")
+    self._tab.ExecuteJavaScript("""document.body.style.width =
+                           (3 * window.innerWidth + 1) + 'px';""")
+    self._tab.ExecuteJavaScript(
+        "window.scrollTo(window.innerWidth, window.innerHeight);")
 
     rect_top = int(self._tab.EvaluateJavaScript(
         '__GestureCommon_GetBoundingVisibleRect(document.body).top'))
@@ -97,6 +101,10 @@
     viewport_height = int(self._tab.EvaluateJavaScript('window.innerHeight'))
     viewport_width = int(self._tab.EvaluateJavaScript('window.innerWidth'))
 
+    self.assertTrue(rect_top >= 0,
+        msg='%s >= %s' % (rect_top, 0))
+    self.assertTrue(rect_left >= 0,
+        msg='%s >= %s' % (rect_left, 0))
     self.assertTrue(rect_bottom <= viewport_height,
         msg='%s + %s <= %s' % (rect_top, rect_height, viewport_height))
     self.assertTrue(rect_right <= viewport_width,
diff --git a/tools/telemetry/telemetry/page/page.py b/tools/telemetry/telemetry/page/page.py
index 344175a..961f341 100644
--- a/tools/telemetry/telemetry/page/page.py
+++ b/tools/telemetry/telemetry/page/page.py
@@ -11,20 +11,21 @@
 
 
 class Page(object):
-  def __init__(self, url, page_set=None, base_dir=None):
-    self.url = url
+  def __init__(self, url, page_set=None, base_dir=None, name=''):
+    self._url = url
     self._page_set = page_set
     # Default value of base_dir is the directory of the file that defines the
     # class of this page instace.
     if base_dir is None:
       base_dir = os.path.dirname(inspect.getfile(self.__class__))
     self._base_dir = base_dir
+    self._name = name
 
     # These attributes can be set dynamically by the page.
+    self.synthetic_delays = dict()
     self.startup_url = page_set.startup_url if page_set else ''
     self.credentials = None
     self.disabled = False
-    self.name = None
     self.script_to_evaluate_on_commit = None
     self._SchemeErrorCheck()
 
@@ -39,24 +40,22 @@
       if startup_url_scheme == 'file':
         raise ValueError('startup_url with local file scheme is not supported')
 
-  # With python page_set, this property will no longer be needed since pages can
-  # share property through a common ancestor class.
-  # TODO(nednguyen): remove this when crbug.com/239179 is marked fixed
-  def __getattr__(self, name):
-    # Disable this property on not dict based page_set
-    if (self.page_set and hasattr(self.page_set, name) and
-        self.page_set.IsDictBasedPageSet()):
-      return getattr(self.page_set, name)
-    raise AttributeError(
-        '%r object has no attribute %r' % (self.__class__, name))
+  def RunNavigateSteps(self, action_runner):
+    action_runner.RunAction(NavigateAction())
 
   @property
   def page_set(self):
     return self._page_set
 
+  @property
+  def name(self):
+    return self._name
+
+  @property
+  def url(self):
+    return self._url
+
   def GetSyntheticDelayCategories(self):
-    if not hasattr(self, 'synthetic_delays'):
-      return []
     result = []
     for delay, options in self.synthetic_delays.items():
       options = '%f;%s' % (options.get('target_duration', 0),
@@ -142,13 +141,3 @@
   @property
   def archive_path(self):
     return self.page_set.WprFilePathForPage(self)
-
-
-# TODO(nednguyen): remove this and move RunNavigateSteps to page when
-# crbug.com/239179 is marked fixed
-class PageWithDefaultRunNavigate(Page):
-  def __init__(self, *args, **kwargs):
-    super(PageWithDefaultRunNavigate, self).__init__(*args, **kwargs)
-
-  def RunNavigateSteps(self, action_runner):
-    action_runner.RunAction(NavigateAction())
diff --git a/tools/telemetry/telemetry/page/page_filter_unittest.py b/tools/telemetry/telemetry/page/page_filter_unittest.py
index 70e7410..be3ec56 100644
--- a/tools/telemetry/telemetry/page/page_filter_unittest.py
+++ b/tools/telemetry/telemetry/page/page_filter_unittest.py
@@ -28,12 +28,14 @@
 class PageFilterTest(unittest.TestCase):
   def setUp(self):
     ps = page_set.PageSet()
-    self.p1 = page.Page('file://conformance/textures/tex-sub-image-2d.html', ps)
-    self.p1.name = 'WebglConformance.conformance_textures_tex_sub_image_2d'
-    self.p2 = page.Page('file://othersuite/textures/tex-sub-image-3d.html', ps)
-    self.p2.name = 'OtherSuite.textures_tex_sub_image_3d'
-    self.p3 = page.Page('file://othersuite/textures/tex-sub-image-3d.html', ps)
-    self.p3.name = None
+    self.p1 = page.Page(
+      'file://conformance/textures/tex-sub-image-2d.html', page_set=ps,
+      name='WebglConformance.conformance_textures_tex_sub_image_2d')
+    self.p2 = page.Page(
+      'file://othersuite/textures/tex-sub-image-3d.html', page_set=ps,
+      name='OtherSuite.textures_tex_sub_image_3d')
+    self.p3 = page.Page(
+      'file://othersuite/textures/tex-sub-image-3d.html', page_set=ps)
 
   def testURLPattern(self):
     options = MockUrlFilterOptions('conformance/textures', '')
diff --git a/tools/telemetry/telemetry/page/page_measurement.py b/tools/telemetry/telemetry/page/page_measurement.py
index dcaa8b0..993897e 100644
--- a/tools/telemetry/telemetry/page/page_measurement.py
+++ b/tools/telemetry/telemetry/page/page_measurement.py
@@ -8,7 +8,6 @@
 class MeasurementFailure(page_test.Failure):
   """Exception that can be thrown from MeasurePage to indicate an undesired but
   designed-for problem."""
-  pass
 
 
 class PageMeasurement(page_test.PageTest):
@@ -43,13 +42,12 @@
                discard_first_result=False,
                clear_cache_before_each_run=False):
     super(PageMeasurement, self).__init__(
-      '_RunTest',
       action_name_to_run,
       needs_browser_restart_after_each_page,
       discard_first_result,
       clear_cache_before_each_run)
 
-  def _RunTest(self, page, tab, results):
+  def ValidatePage(self, page, tab, results):
     results.WillMeasurePage(page)
     try:
       self.MeasurePage(page, tab, results)
diff --git a/tools/telemetry/telemetry/page/page_measurement_unittest.py b/tools/telemetry/telemetry/page/page_measurement_unittest.py
index 3754fb3..63209e0 100644
--- a/tools/telemetry/telemetry/page/page_measurement_unittest.py
+++ b/tools/telemetry/telemetry/page/page_measurement_unittest.py
@@ -12,8 +12,6 @@
 from telemetry.page import page_measurement_unittest_base
 from telemetry.page import page_set
 from telemetry.page import page_set_archive_info
-from telemetry.page.actions import all_page_actions
-from telemetry.page.actions import page_action
 from telemetry.unittest import options_for_unittests
 
 
@@ -62,6 +60,14 @@
   def MeasurePage(self, page, tab, results):
     pass
 
+class PageWithAction(page_module.Page):
+  def __init__(self, url, ps):
+    super(PageWithAction, self).__init__(url, ps, ps.base_dir)
+    self.run_test_action_called = False
+
+  def RunTestAction(self, _):
+    self.run_test_action_called = True
+
 class PageMeasurementUnitTest(
   page_measurement_unittest_base.PageMeasurementUnitTestBase):
 
@@ -146,14 +152,9 @@
         os.remove(test_archive)
 
   def testActions(self):
-    action_called = [False]
-    class MockAction(page_action.PageAction):
-      def RunAction(self, page, tab):
-        action_called[0] = True
-    all_page_actions.RegisterClassForTest('mock', MockAction)
-
-    ps = self.CreatePageSetFromFileInUnittestDataDir('blank.html')
-    setattr(ps.pages[0], 'RunTestAction', {'action': 'mock'})
+    ps = self.CreateEmptyPageSet()
+    page = PageWithAction('file://blank.html', ps)
+    ps.AddPage(page)
     measurement = MeasurementWithAction()
     self.RunMeasurement(measurement, ps, options=self._options)
-    self.assertTrue(action_called[0])
+    self.assertTrue(page.run_test_action_called)
diff --git a/tools/telemetry/telemetry/page/page_measurement_unittest_base.py b/tools/telemetry/telemetry/page/page_measurement_unittest_base.py
index 412cd4e..7b76a2b 100644
--- a/tools/telemetry/telemetry/page/page_measurement_unittest_base.py
+++ b/tools/telemetry/telemetry/page/page_measurement_unittest_base.py
@@ -15,7 +15,7 @@
 from telemetry.unittest import options_for_unittests
 
 
-class BasicTestPage(page_module.PageWithDefaultRunNavigate):
+class BasicTestPage(page_module.Page):
   def __init__(self, url, page_set, base_dir):
     super(BasicTestPage, self).__init__(url, page_set, base_dir)
 
diff --git a/tools/telemetry/telemetry/page/page_runner.py b/tools/telemetry/telemetry/page/page_runner.py
index 76927f0..21a4ce1 100644
--- a/tools/telemetry/telemetry/page/page_runner.py
+++ b/tools/telemetry/telemetry/page/page_runner.py
@@ -246,9 +246,7 @@
 def _PrepareAndRunPage(test, page_set, expectations, finder_options,
                        browser_options, page, credentials_path,
                        possible_browser, results, state):
-  if finder_options.use_live_sites:
-    possible_browser.finder_options.browser_options.wpr_mode = wpr_modes.WPR_OFF
-  elif browser_options.wpr_mode != wpr_modes.WPR_RECORD:
+  if browser_options.wpr_mode != wpr_modes.WPR_RECORD:
     possible_browser.finder_options.browser_options.wpr_mode = (
         wpr_modes.WPR_REPLAY
         if page.archive_path and os.path.isfile(page.archive_path)
diff --git a/tools/telemetry/telemetry/page/page_runner_unittest.py b/tools/telemetry/telemetry/page/page_runner_unittest.py
index 37d5f57..285d11f 100644
--- a/tools/telemetry/telemetry/page/page_runner_unittest.py
+++ b/tools/telemetry/telemetry/page/page_runner_unittest.py
@@ -45,14 +45,14 @@
     self.login_return_value = login_return_value
 
   @property
-  def credentials_type(self): # pylint: disable=R0201
+  def credentials_type(self):
     return 'test'
 
-  def LoginNeeded(self, tab, config): # pylint: disable=W0613
+  def LoginNeeded(self, *_):
     self.did_get_login = True
     return self.login_return_value
 
-  def LoginNoLongerNeeded(self, tab): # pylint: disable=W0613
+  def LoginNoLongerNeeded(self, _):
     self.did_get_login_no_longer_needed = True
 
 
@@ -63,17 +63,17 @@
   def testHandlingOfCrashedTab(self):
     ps = page_set.PageSet()
     expectations = test_expectations.TestExpectations()
-    page1 = page_module.PageWithDefaultRunNavigate('chrome://crash', ps)
+    page1 = page_module.Page('chrome://crash', ps)
     ps.pages.append(page1)
 
     class Test(page_test.PageTest):
-      def RunTest(self, *args):
+      def ValidatePage(self, *args):
         pass
 
     options = options_for_unittests.GetCopy()
     options.output_format = 'none'
     SetUpPageRunnerArguments(options)
-    results = page_runner.Run(Test('RunTest'), ps, expectations, options)
+    results = page_runner.Run(Test(), ps, expectations, options)
     self.assertEquals(0, len(results.successes))
     self.assertEquals(0, len(results.failures))
     self.assertEquals(1, len(results.errors))
@@ -93,7 +93,7 @@
       def __init__(self, *args):
         super(Test, self).__init__(*args)
         self.run_count = 0
-      def RunTest(self, *_):
+      def ValidatePage(self, *_):
         old_run_count = self.run_count
         self.run_count += 1
         if old_run_count == 0:
@@ -101,7 +101,7 @@
 
     options = options_for_unittests.GetCopy()
     options.output_format = 'none'
-    test = Test('RunTest')
+    test = Test()
     SetUpPageRunnerArguments(options)
     results = page_runner.Run(test, ps, expectations, options)
     self.assertEquals(2, test.run_count)
@@ -116,14 +116,14 @@
     ps.pages.append(page1)
 
     class Test(page_test.PageTest):
-      def RunTest(self, *_):
+      def ValidatePage(self, *_):
         pass
 
     options = options_for_unittests.GetCopy()
     options.output_format = 'none'
     SetUpPageRunnerArguments(options)
     results = page_runner.Run(
-        Test('RunTest'), ps, expectations, options)
+        Test(), ps, expectations, options)
     self.assertEquals(1, len(results.successes))
     self.assertEquals(0, len(results.failures))
     self.assertEquals(0, len(results.errors))
@@ -212,7 +212,7 @@
 
     class Measurement(page_measurement.PageMeasurement):
       i = 0
-      def MeasurePage(self, _, __, results):
+      def MeasurePage(self, _1, _2, results):
         self.i += 1
         results.Add('metric', 'unit', self.i)
 
@@ -255,8 +255,7 @@
     assert credentials_backend.did_get_login_no_longer_needed == True
     assert did_run
 
-  def runCredentialsTest(self, # pylint: disable=R0201
-                         credentials_backend):
+  def runCredentialsTest(self, credentials_backend):
     ps = page_set.PageSet()
     expectations = test_expectations.TestExpectations()
     page = page_module.Page(
@@ -273,13 +272,13 @@
 
       class TestThatInstallsCredentialsBackend(page_test.PageTest):
         def __init__(self, credentials_backend):
-          super(TestThatInstallsCredentialsBackend, self).__init__('RunTest')
+          super(TestThatInstallsCredentialsBackend, self).__init__()
           self._credentials_backend = credentials_backend
 
         def DidStartBrowser(self, browser):
           browser.credentials.AddBackend(self._credentials_backend)
 
-        def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201
+        def ValidatePage(self, *_):
           did_run[0] = True
 
       test = TestThatInstallsCredentialsBackend(credentials_backend)
@@ -301,7 +300,7 @@
     ps.user_agent_type = 'tablet'
 
     class TestUserAgent(page_test.PageTest):
-      def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201
+      def ValidatePage(self, _1, tab, _2):
         actual_user_agent = tab.EvaluateJavaScript('window.navigator.userAgent')
         expected_user_agent = user_agent.UA_TYPE_MAPPING['tablet']
         assert actual_user_agent.strip() == expected_user_agent
@@ -311,7 +310,7 @@
         # should fail, but since it skipped all the asserts, it slipped by.
         self.hasRun = True # pylint: disable=W0201
 
-    test = TestUserAgent('RunTest')
+    test = TestUserAgent()
     options = options_for_unittests.GetCopy()
     options.output_format = 'none'
     SetUpPageRunnerArguments(options)
@@ -328,12 +327,8 @@
     ps.pages.append(page)
 
     class TestOneTab(page_test.PageTest):
-      def __init__(self,
-                   test_method_name,
-                   action_name_to_run='',
-                   needs_browser_restart_after_each_page=False):
-        super(TestOneTab, self).__init__(test_method_name, action_name_to_run,
-                                         needs_browser_restart_after_each_page)
+      def __init__(self):
+        super(TestOneTab, self).__init__()
         self._browser = None
 
       def DidStartBrowser(self, browser):
@@ -341,13 +336,13 @@
         if self._browser.supports_tab_control:
           self._browser.tabs.New()
 
-      def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201
+      def ValidatePage(self, *_):
         if not self._browser.supports_tab_control:
           logging.warning('Browser does not support tab control, skipping test')
           return
         assert len(self._browser.tabs) == 1
 
-    test = TestOneTab('RunTest')
+    test = TestOneTab()
     options = options_for_unittests.GetCopy()
     options.output_format = 'none'
     SetUpPageRunnerArguments(options)
@@ -363,11 +358,8 @@
     ps.pages.append(page)
 
     class TestBeforeLaunch(page_test.PageTest):
-      def __init__(self,
-                   test_method_name,
-                   action_name_to_run=''):
-        super(TestBeforeLaunch, self).__init__(
-            test_method_name, action_name_to_run, False)
+      def __init__(self):
+        super(TestBeforeLaunch, self).__init__()
         self._did_call_will_start = False
         self._did_call_did_start = False
 
@@ -379,10 +371,10 @@
         assert self._did_call_will_start
         self._did_call_did_start = True
 
-      def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201
+      def ValidatePage(self, *_):
         assert self._did_call_did_start
 
-    test = TestBeforeLaunch('RunTest')
+    test = TestBeforeLaunch()
     options = options_for_unittests.GetCopy()
     options.output_format = 'none'
     SetUpPageRunnerArguments(options)
@@ -429,60 +421,20 @@
     ps.pages.append(page)
 
     class Test(page_test.PageTest):
-      def __init__(self,
-                   test_method_name,
-                   action_name_to_run=''):
-        super(Test, self).__init__(
-            test_method_name, action_name_to_run, False)
+      def __init__(self):
+        super(Test, self).__init__()
         self.did_call_clean_up = False
 
-      def RunTest(self, _, _2, _3):
+      def ValidatePage(self, *_):
         raise Exception('Intentional failure')
 
       def CleanUpAfterPage(self, page, tab):
         self.did_call_clean_up = True
 
 
-    test = Test('RunTest')
+    test = Test()
     options = options_for_unittests.GetCopy()
     options.output_format = 'none'
     SetUpPageRunnerArguments(options)
     page_runner.Run(test, ps, expectations, options)
     assert test.did_call_clean_up
-
-  def TestUseLiveSitesFlag(self, options, expected_is_page_from_archive):
-    ps = page_set.PageSet(
-      file_path=util.GetUnittestDataDir(),
-      archive_data_file='data/archive_blank.json')
-    ps.pages.append(page_module.Page(
-      'file://blank.html', ps, base_dir=ps.base_dir))
-    expectations = test_expectations.TestExpectations()
-
-    class ArchiveTest(page_measurement.PageMeasurement):
-      def __init__(self):
-        super(ArchiveTest, self).__init__()
-        self.is_page_from_archive = False
-
-      def WillNavigateToPage(self, page, tab):
-        self.is_page_from_archive = (
-          tab.browser._wpr_server is not None) # pylint: disable=W0212
-
-      def MeasurePage(self, _, __, results):
-        pass
-
-    test = ArchiveTest()
-    page_runner.Run(test, ps, expectations, options)
-    self.assertEquals(expected_is_page_from_archive, test.is_page_from_archive)
-
-  def testUseLiveSitesFlagSet(self):
-    options = options_for_unittests.GetCopy()
-    options.output_format = 'none'
-    options.use_live_sites = True
-    SetUpPageRunnerArguments(options)
-    self.TestUseLiveSitesFlag(options, expected_is_page_from_archive=False)
-
-  def testUseLiveSitesFlagUnset(self):
-    options = options_for_unittests.GetCopy()
-    options.output_format = 'none'
-    SetUpPageRunnerArguments(options)
-    self.TestUseLiveSitesFlag(options, expected_is_page_from_archive=True)
diff --git a/tools/telemetry/telemetry/page/page_set.py b/tools/telemetry/telemetry/page/page_set.py
index 9471653..d58f0ae 100644
--- a/tools/telemetry/telemetry/page/page_set.py
+++ b/tools/telemetry/telemetry/page/page_set.py
@@ -9,20 +9,6 @@
 from telemetry.core import util
 from telemetry.page import page as page_module
 from telemetry.page import page_set_archive_info
-from telemetry.page.actions.navigate import NavigateAction
-
-# TODO(nednguyen): Remove this when crbug.com/239179 is marked fixed
-LEGACY_NAME_CONVERSION_DICT = {
-  'endure' : 'RunEndure',
-  'navigate_steps' : 'RunNavigateSteps',
-  'media_metrics' : 'RunMediaMetrics',
-  'stress_memory' : 'RunStressMemory',
-  'no_op' : 'RunNoOp',
-  'repaint' : 'RunRepaint',
-  'smoothness' : 'RunSmoothness',
-  'webrtc' : 'RunWebrtc'
-}
-
 
 class PageSetError(Exception):
   pass
@@ -59,48 +45,6 @@
         self.serving_dirs.add(os.path.realpath(sd))
       else:
         self.serving_dirs.add(os.path.realpath(os.path.join(self.base_dir, sd)))
-    self._is_dict_based_page_set = False
-
-
-  # TODO(nednguyen): Remove this when crbug.com/239179 is marked fixed
-  def IsDictBasedPageSet(self):
-    return self._is_dict_based_page_set
-
-  def _InitializeFromDict(self, attributes):
-    self._is_dict_based_page_set = True
-    if attributes:
-      for k, v in attributes.iteritems():
-        if k in LEGACY_NAME_CONVERSION_DICT:
-          setattr(self, LEGACY_NAME_CONVERSION_DICT[k], v)
-        else:
-          setattr(self, k, v)
-
-    # Create a Page object for every page.
-    self.pages = []
-    if attributes and 'pages' in attributes:
-      for page_attributes in attributes['pages']:
-        url = page_attributes.pop('url')
-        page = page_module.Page(
-            url, self, base_dir=self.base_dir)
-        for k, v in page_attributes.iteritems():
-          setattr(page, k, v)
-        page._SchemeErrorCheck()  # pylint: disable=W0212
-        for legacy_name in LEGACY_NAME_CONVERSION_DICT:
-          if hasattr(page, legacy_name):
-            setattr(page, LEGACY_NAME_CONVERSION_DICT[legacy_name],
-                    getattr(page, legacy_name))
-            delattr(page, legacy_name)
-        self.AddPage(page)
-
-    # Prepend base_dir to our serving dirs.
-    # Always use realpath to ensure no duplicates in set.
-    self.serving_dirs = set()
-    if attributes and 'serving_dirs' in attributes:
-      if not isinstance(attributes['serving_dirs'], list):
-        raise ValueError('serving_dirs must be a list.')
-      for serving_dir in attributes['serving_dirs']:
-        self.serving_dirs.add(
-            os.path.realpath(os.path.join(self.base_dir, serving_dir)))
 
   def AddPage(self, page):
     assert page.page_set is self
@@ -110,16 +54,9 @@
     """ Add a simple page with url equals to page_url that contains only default
     RunNavigateSteps.
     """
-    self.AddPage(page_module.PageWithDefaultRunNavigate(
+    self.AddPage(page_module.Page(
       page_url, self, self.base_dir))
 
-  # In json page_set, a page inherits attributes from its page_set. With
-  # python page_set, this property will no longer be needed since pages can
-  # share property through a common ancestor class.
-  # TODO(nednguyen): move this to page when crbug.com/239179 is marked fixed
-  def RunNavigateSteps(self, action_runner):
-    action_runner.RunAction(NavigateAction())
-
   @staticmethod
   def FromFile(file_path):
     _, ext_name = os.path.splitext(file_path)
@@ -152,13 +89,6 @@
                                      % file_path)
     return page_set
 
-  @staticmethod
-  def FromDict(attributes, file_path=''):
-    page_set = PageSet(file_path)
-    # pylint: disable=W0212
-    page_set._InitializeFromDict(attributes)
-    return page_set
-
   @property
   def base_dir(self):
     if os.path.isfile(self.file_path):
diff --git a/tools/telemetry/telemetry/page/page_set_archive_info_unittest.py b/tools/telemetry/telemetry/page/page_set_archive_info_unittest.py
index 740bfbc..f94b76b 100644
--- a/tools/telemetry/telemetry/page/page_set_archive_info_unittest.py
+++ b/tools/telemetry/telemetry/page/page_set_archive_info_unittest.py
@@ -13,8 +13,7 @@
 
 class MockPage(page.Page):
   def __init__(self, url, name=None):
-    super(MockPage, self).__init__(url, None)
-    self.name = name
+    super(MockPage, self).__init__(url, None, name=name)
 
 
 page1 = MockPage('http://www.foo.com/', 'Foo')
diff --git a/tools/telemetry/telemetry/page/page_set_unittest.py b/tools/telemetry/telemetry/page/page_set_unittest.py
index cc15d7d..0b5b4ea 100644
--- a/tools/telemetry/telemetry/page/page_set_unittest.py
+++ b/tools/telemetry/telemetry/page/page_set_unittest.py
@@ -41,43 +41,6 @@
     finally:
       os.rmdir(directory_path)
 
-  def testRenamingCompoundActions(self):
-    ps = page_set.PageSet.FromDict({
-      'serving_dirs': ['a/b'],
-      'smoothness' : { 'action' : 'scroll' },
-      'pages': [
-        {'url': 'http://www.foo.com',
-         'stress_memory': {'action': 'javasciprt'}
-        },
-        {'url': 'http://www.bar.com',
-         'navigate_steps': {'action': 'navigate2'},
-         'repaint' : {'action': 'scroll'}
-        },
-      ]}, 'file://foo.js')
-
-    self.assertTrue(hasattr(ps.pages[0], 'RunNavigateSteps'))
-    self.assertEquals(ps.pages[0].RunSmoothness, {'action': 'scroll'})
-    self.assertEquals(ps.pages[0].RunStressMemory, {'action': 'javasciprt'})
-
-    self.assertEquals(ps.pages[1].RunSmoothness, {'action': 'scroll'})
-    self.assertEquals(ps.pages[1].RunNavigateSteps, {'action': 'navigate2'})
-    self.assertEquals(ps.pages[1].RunRepaint, {'action': 'scroll'})
-
-  def testRunNavigateStepsInheritance(self):
-    ps = page_set.PageSet.FromDict({
-      'serving_dirs': ['a/b'],
-      'navigate_steps' : { 'action' : 'navigate1' },
-      'pages': [
-        {'url': 'http://www.foo.com',
-        },
-        {'url': 'http://www.bar.com',
-         'navigate_steps': {'action': 'navigate2'},
-        },
-      ]}, 'file://foo.js')
-
-    self.assertEquals(ps.pages[0].RunNavigateSteps, {'action': 'navigate1'})
-    self.assertEquals(ps.pages[1].RunNavigateSteps, {'action': 'navigate2'})
-
   def testSuccesfulPythonPageSetLoading(self):
     test_pps_dir = os.path.join(util.GetUnittestDataDir(), 'test_page_set.py')
     pps = page_set.PageSet.FromFile(test_pps_dir)
@@ -115,15 +78,3 @@
     self.assertEqual(
       os.path.normpath(os.path.join(
         util.GetUnittestDataDir(), 'pages/foo.html')), external_page.file_path)
-
-  def testDictBasedPageSet(self):
-    dict_ps = page_set.PageSet.FromDict({
-      'description': 'hello',
-      'archive_path': 'foo.wpr',
-      'pages': [{'url': 'file://../../otherdir/foo/'}]
-      }, os.path.dirname(__file__))
-    self.assertTrue(dict_ps.IsDictBasedPageSet())
-
-    test_pps_dir = os.path.join(util.GetUnittestDataDir(), 'test_page_set.py')
-    python_ps = page_set.PageSet.FromFile(test_pps_dir)
-    self.assertFalse(python_ps.IsDictBasedPageSet())
diff --git a/tools/telemetry/telemetry/page/page_test.py b/tools/telemetry/telemetry/page/page_test.py
index b581f68..4e04bb1 100644
--- a/tools/telemetry/telemetry/page/page_test.py
+++ b/tools/telemetry/telemetry/page/page_test.py
@@ -2,71 +2,22 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import logging
-
 from telemetry.core import command_line
 
 from telemetry.page import test_expectations
 from telemetry.page.actions import action_runner as action_runner_module
-from telemetry.page.actions import all_page_actions
 from telemetry.page.actions import interact
 
 
-def _GetActionFromData(action_data):
-  action_name = action_data['action']
-  action = all_page_actions.FindClassWithName(action_name)
-  if not action:
-    logging.critical('Could not find an action named %s.', action_name)
-    logging.critical('Check the page set for a typo and check the error '
-                     'log for possible Python loading/compilation errors.')
-    raise Exception('Action "%s" not found.' % action_name)
-  return action(action_data)
-
-
-def GetSubactionFromData(page, subaction_data, interactive):
-  subaction_name = subaction_data['action']
-  if hasattr(page, subaction_name):
-    return GetCompoundActionFromPage(page, subaction_name, interactive)
-  else:
-    return [_GetActionFromData(subaction_data)]
-
-
-def GetCompoundActionFromPage(page, action_name, interactive=False):
-  if interactive:
-    return [interact.InteractAction()]
-
-  if not action_name:
-    return []
-
-  action_data_list = getattr(page, action_name)
-  if not isinstance(action_data_list, list):
-    action_data_list = [action_data_list]
-
-  action_list = []
-  for subaction_data in action_data_list:
-    for _ in xrange(subaction_data.get('repeat', 1)):
-      action_list += GetSubactionFromData(page, subaction_data, interactive)
-  return action_list
-
-
-def GetRunMethodForPage(page, action_name):
-  def RunMethod(action_runner):
-    for action in GetCompoundActionFromPage(page, action_name):
-      action_runner.RunAction(action)
-  return RunMethod
-
-
 class Failure(Exception):
   """Exception that can be thrown from PageMeasurement to indicate an
   undesired but designed-for problem."""
-  pass
 
 
 class TestNotSupportedOnPlatformFailure(Failure):
   """Exception that can be thrown to indicate that a certain feature required
   to run the test is not available on the platform, hardware configuration, or
   browser version."""
-  pass
 
 
 class PageTest(command_line.Command):
@@ -75,7 +26,6 @@
   options = {}
 
   def __init__(self,
-               test_method_name,
                action_name_to_run='',
                needs_browser_restart_after_each_page=False,
                discard_first_result=False,
@@ -86,11 +36,6 @@
     super(PageTest, self).__init__()
 
     self.options = None
-    try:
-      self._test_method = getattr(self, test_method_name)
-    except AttributeError:
-      raise ValueError, 'No such method %s.%s' % (
-        self.__class_, test_method_name)  # pylint: disable=E1101
     if action_name_to_run:
       assert action_name_to_run.startswith('Run') \
           and '_' not in action_name_to_run, \
@@ -202,7 +147,6 @@
 
   def CustomizeBrowserOptions(self, options):
     """Override to add test-specific options to the BrowserOptions object"""
-    pass
 
   def CustomizeBrowserOptionsForSinglePage(self, page, options):
     """Set options specific to the test and the given page.
@@ -217,11 +161,9 @@
 
   def WillStartBrowser(self, browser):
     """Override to manipulate the browser environment before it launches."""
-    pass
 
   def DidStartBrowser(self, browser):
     """Override to customize the browser right after it has launched."""
-    pass
 
   def CanRunForPage(self, page):  # pylint: disable=W0613
     """Override to customize if the test can be ran for the given page."""
@@ -242,15 +184,12 @@
 
   def WillRunPageRepeats(self, page):
     """Override to do operations before each page is iterated over."""
-    pass
 
   def DidRunPageRepeats(self, page):
     """Override to do operations after each page is iterated over."""
-    pass
 
   def DidStartHTTPServer(self, tab):
     """Override to do operations after the HTTP server is started."""
-    pass
 
   def WillNavigateToPage(self, page, tab):
     """Override to do operations before the page is navigated, notably Telemetry
@@ -258,24 +197,19 @@
     calling this function:
     * Ensure only one tab is open.
     * Call WaitForDocumentReadyStateToComplete on the tab."""
-    pass
 
   def DidNavigateToPage(self, page, tab):
     """Override to do operations right after the page is navigated and after
     all waiting for completion has occurred."""
-    pass
 
   def WillRunActions(self, page, tab):
     """Override to do operations before running the actions on the page."""
-    pass
 
   def DidRunActions(self, page, tab):
     """Override to do operations after running the actions on the page."""
-    pass
 
   def CleanUpAfterPage(self, page, tab):
     """Called after the test run method was run, even if it failed."""
-    pass
 
   def CreateExpectations(self, page_set):   # pylint: disable=W0613
     """Override to make this test generate its own expectations instead of
@@ -290,9 +224,15 @@
   def ValidatePageSet(self, page_set):
     """Override to examine the page set before the test run.  Useful for
     example to validate that the pageset can be used with the test."""
-    pass
+
+  def ValidatePage(self, page, tab, results):
+    """Override to check the actual test assertions.
+
+    This is where most your test logic should go."""
+    raise NotImplementedError()
 
   def RunPage(self, page, tab, results):
+    # Run actions.
     interactive = self.options and self.options.interactive
     action_runner = action_runner_module.ActionRunner(page, tab, self)
     self.WillRunActions(page, tab)
@@ -301,14 +241,13 @@
     else:
       self._RunMethod(page, self._action_name_to_run, action_runner)
     self.DidRunActions(page, tab)
-    self._test_method(page, tab, results)
+
+    # Run validator.
+    self.ValidatePage(page, tab, results)
 
   def _RunMethod(self, page, method_name, action_runner):
     if hasattr(page, method_name):
       run_method = getattr(page, method_name)
-      # method is runnable, this must be the RunMethod of legacy json page_set
-      if not callable(run_method):
-        run_method = GetRunMethodForPage(page, method_name)
       run_method(action_runner)
 
   def RunNavigateSteps(self, page, tab):
@@ -317,7 +256,7 @@
     Runs the 'navigate_steps' page attribute as a compound action.
     """
     action_runner = action_runner_module.ActionRunner(page, tab, None)
-    self._RunMethod(page, "RunNavigateSteps", action_runner)
+    page.RunNavigateSteps(action_runner)
 
   def IsExiting(self):
     return self._exit_requested
diff --git a/tools/telemetry/telemetry/page/page_test_unittest.py b/tools/telemetry/telemetry/page/page_test_unittest.py
index 9598c03..ff4c731 100644
--- a/tools/telemetry/telemetry/page/page_test_unittest.py
+++ b/tools/telemetry/telemetry/page/page_test_unittest.py
@@ -7,78 +7,27 @@
 from telemetry.core import util
 from telemetry.page import page as page_module
 from telemetry.page import page_test
-from telemetry.page.actions import all_page_actions
-from telemetry.page.actions import page_action
 
-def _CreatePage(test_filename):
-  url = 'file://' + test_filename
-  page = page_module.Page(url, None, base_dir=util.GetUnittestDataDir())
-  return page
 
 class DoNothingPageTest(page_test.PageTest):
-  def __init__(self, action_name_to_run=''):
-    super(DoNothingPageTest, self).__init__('DoNothing', action_name_to_run)
-
-  def DoNothing(self, page, tab, results):
+  def ValidatePage(self, *_):
     pass
 
-class AppendAction(page_action.PageAction):
-  def RunAction(self, page, tab):
-    self.var.append(True)
+
+class TestPage(page_module.Page):
+  def __init__(self, url, page_set, base_dir):
+    super(TestPage, self).__init__(url, page_set, base_dir)
+    self.run_action_to_run_called = False
+
+  def RunActionToRun(self, _):
+    self.run_action_to_run_called = True
 
 class PageTestUnitTest(unittest.TestCase):
-  def setUp(self):
-    super(PageTestUnitTest, self).setUp()
-    all_page_actions.RegisterClassForTest('append', AppendAction)
-
-    self._page_test = DoNothingPageTest('RunActionToRun')
-    self._page = _CreatePage('blank.html')
 
   def testRunActions(self):
-    action_called = []
-    action_to_run = [
-      { 'action': 'append', 'var': action_called }
-    ]
-    setattr(self._page, 'RunActionToRun', action_to_run)
+    test = DoNothingPageTest('RunActionToRun')
+    page = TestPage('file://blank.html', None, util.GetUnittestDataDir())
 
-    self._page_test.RunPage(self._page, None, None)
+    test.RunPage(page, None, None)
 
-    self.assertTrue(action_called)
-
-  def testReferenceAction(self):
-    action_list = []
-    action_to_run = [
-      { 'action': 'RunReferencedAction' },
-    ]
-    referenced_action = { 'action': 'append', 'var': action_list }
-    setattr(self._page, 'RunActionToRun', action_to_run)
-    setattr(self._page, 'RunReferencedAction', referenced_action)
-
-    self._page_test.RunPage(self._page, None, None)
-
-    self.assertEqual(action_list, [True])
-
-  def testRepeatAction(self):
-    action_list = []
-    action_to_run = { 'action': 'append', 'var': action_list, 'repeat': 10 }
-    setattr(self._page, 'RunActionToRun', action_to_run)
-
-    self._page_test.RunPage(self._page, None, None)
-
-    self.assertEqual(len(action_list), 10)
-
-  def testRepeatReferenceAction(self):
-    action_list = []
-    action_to_run = { 'action': 'RunReferencedAction', 'repeat': 3 }
-    referenced_action = [
-      { 'action': 'append', 'var': action_list },
-    ]
-    setattr(self._page, 'RunActionToRun', action_to_run)
-    setattr(self._page, 'RunReferencedAction', referenced_action)
-
-    self._page_test.RunPage(self._page, None, None)
-
-    self.assertEqual(action_list,
-                     [True, True, True])
-
-
+    self.assertTrue(page.run_action_to_run_called)
diff --git a/tools/telemetry/telemetry/page/record_wpr.py b/tools/telemetry/telemetry/page/record_wpr.py
index ace54e2..f12a410 100755
--- a/tools/telemetry/telemetry/page/record_wpr.py
+++ b/tools/telemetry/telemetry/page/record_wpr.py
@@ -2,18 +2,15 @@
 # Copyright (c) 2012 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.
-import json
 import logging
 import os
 import sys
 import tempfile
 import time
-import urlparse
 
 from telemetry import test
 from telemetry.core import browser_options
 from telemetry.core import discover
-from telemetry.core import util
 from telemetry.core import wpr_modes
 from telemetry.page import page_measurement
 from telemetry.page import page_measurement_results
@@ -26,7 +23,7 @@
 from telemetry.page.actions import interact
 
 
-class RecordPage(page_test.PageTest):
+class RecordPage(page_test.PageTest):  # pylint: disable=W0223
   def __init__(self, measurements):
     # This class overwrites PageTest.Run, so that the test method name is not
     # really used (except for throwing an exception if it doesn't exist).
@@ -84,20 +81,6 @@
       should_reload = True
 
 
-def _CreatePageSetForUrl(url):
-  ps_name = urlparse.urlparse(url).hostname + '.json'
-  ps_path = os.path.join(util.GetBaseDir(), 'page_sets', ps_name)
-  ps = {'archive_data_file': '../data/%s' % ps_name,
-        'pages': [
-          { 'url': url }
-          ]
-        }
-  with open(ps_path, 'w') as f:
-    f.write(json.dumps(ps))
-  print 'Created new page set %s' % ps_path
-  return page_set.PageSet.FromFile(ps_path)
-
-
 def Main(base_dir):
   measurements = {
       n: cls for n, cls in discover.DiscoverClasses(
@@ -130,9 +113,6 @@
   elif discover.IsPageSetFile(target):
     parser.parse_args()
     ps = page_set.PageSet.FromFile(target)
-  elif target.startswith('http'):
-    parser.parse_args()
-    ps = _CreatePageSetForUrl(target)
   else:
     parser.print_usage()
     sys.exit(1)
diff --git a/tools/telemetry/telemetry/page/test_expectations_unittest.py b/tools/telemetry/telemetry/page/test_expectations_unittest.py
index 53314db..fa77f7a 100644
--- a/tools/telemetry/telemetry/page/test_expectations_unittest.py
+++ b/tools/telemetry/telemetry/page/test_expectations_unittest.py
@@ -186,6 +186,6 @@
   # Expectations can be set against page names as well as urls
   def testPageNameExpectations(self):
     ps = page_set.PageSet()
-    page = page_module.Page('http://test.com/page11.html', ps)
-    page.name = "Pages.page_11"
+    page = page_module.Page('http://test.com/page11.html', ps,
+                            name='Pages.page_11')
     self.assertExpectationEquals('fail', page)
diff --git a/tools/telemetry/telemetry/test_util/__init__.py b/tools/telemetry/telemetry/test_util/__init__.py
new file mode 100644
index 0000000..07db778
--- /dev/null
+++ b/tools/telemetry/telemetry/test_util/__init__.py
@@ -0,0 +1,4 @@
+# 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.
+"""A library for bootstrapping Telemetry performance unittesting."""
diff --git a/tools/telemetry/telemetry/test_util/page_set_smoke_test.py b/tools/telemetry/telemetry/test_util/page_set_smoke_test.py
new file mode 100644
index 0000000..00d1a4b
--- /dev/null
+++ b/tools/telemetry/telemetry/test_util/page_set_smoke_test.py
@@ -0,0 +1,47 @@
+# 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.
+
+import logging
+import os
+import unittest
+
+from telemetry.core import discover
+from telemetry.page import page_set as page_set_module
+from telemetry.page import page_set_archive_info
+
+
+class PageSetSmokeTest(unittest.TestCase):
+
+  def RunSmokeTest(self, page_sets_dir):
+    """
+    Run smoke test on all page sets in page_sets_dir. Subclass of
+    PageSetSmokeTest is supposed to call this in some test method to run smoke
+    test.
+    """
+    # Instantiate all page sets and verify that all URLs have an associated
+    # archive.
+    page_sets = discover.GetAllPageSetFilenames(page_sets_dir)
+    for path in page_sets:
+      page_set = page_set_module.PageSet.FromFile(path)
+
+      # TODO: Eventually these should be fatal.
+      if not page_set.archive_data_file:
+        logging.warning('Skipping %s: missing archive data file', path)
+        continue
+      if not os.path.exists(os.path.join(page_sets_dir,
+                                         page_set.archive_data_file)):
+        logging.warning('Skipping %s: archive data file not found', path)
+        continue
+
+      wpr_archive_info = page_set_archive_info.PageSetArchiveInfo.FromFile(
+        os.path.join(page_sets_dir, page_set.archive_data_file),
+        ignore_archive=True)
+
+      logging.info('Testing %s', path)
+      for page in page_set.pages:
+        if not page.url.startswith('http'):
+          continue
+        self.assertTrue(wpr_archive_info.WprFilePathForPage(page),
+                        msg='No archive found for %s in %s' % (
+                            page.url, page_set.archive_data_file))
diff --git a/tools/telemetry/telemetry/web_perf/__init__.py b/tools/telemetry/telemetry/web_perf/__init__.py
index c6d4f1e..648af8e 100644
--- a/tools/telemetry/telemetry/web_perf/__init__.py
+++ b/tools/telemetry/telemetry/web_perf/__init__.py
@@ -2,6 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 """
-The web_perf module provides timeline_interaction_record for measuring web
-app's performance through tracing timeline.
+The web_perf module provides utilities and measurements for benchmarking web
+app's performance.
 """
diff --git a/tools/telemetry/telemetry/web_perf/metrics/__init__.py b/tools/telemetry/telemetry/web_perf/metrics/__init__.py
new file mode 100644
index 0000000..89406a1
--- /dev/null
+++ b/tools/telemetry/telemetry/web_perf/metrics/__init__.py
@@ -0,0 +1,6 @@
+# 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.
+"""
+The web_perf.metrics module provides metrics for analyzing web performance.
+"""
diff --git a/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py b/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py
new file mode 100644
index 0000000..1a483b8
--- /dev/null
+++ b/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py
@@ -0,0 +1,255 @@
+# 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.
+
+from operator import attrgetter
+from telemetry.page import page_measurement
+
+# These are LatencyInfo component names indicating the various components
+# that the input event has travelled through.
+# This is when the input event first reaches chrome.
+UI_COMP_NAME = 'INPUT_EVENT_LATENCY_UI_COMPONENT'
+# This is when the input event was originally created by OS.
+ORIGINAL_COMP_NAME = 'INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT'
+# This is when the input event was sent from browser to renderer.
+BEGIN_COMP_NAME = 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT'
+# This is when the input event has reached swap buffer.
+END_COMP_NAME = 'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT'
+
+
+class NotEnoughFramesError(page_measurement.MeasurementFailure):
+  def __init__(self, frame_count):
+    super(NotEnoughFramesError, self).__init__(
+      'Only %i frame timestamps were collected ' % frame_count +
+      '(at least two are required).\n'
+      'Issues that have caused this in the past:\n' +
+      '- Browser bugs that prevents the page from redrawing\n' +
+      '- Bugs in the synthetic gesture code\n' +
+      '- Page and benchmark out of sync (e.g. clicked element was renamed)\n' +
+      '- Pages that render extremely slow\n' +
+      '- Pages that can\'t be scrolled')
+
+
+def GetScrollInputLatencyEvents(scroll_type, browser_process, timeline_range):
+  """Get scroll events' LatencyInfo from the browser process's trace buffer
+     that are within the timeline_range.
+
+  Scroll events (MouseWheel, GestureScrollUpdate or JS scroll on TouchMove)
+  dump their LatencyInfo into trace buffer as async trace event with name
+  "InputLatency". The trace event has a memeber 'step' containing its event
+  type and a memeber 'data' containing its latency history.
+
+  """
+  scroll_events = []
+  if not browser_process:
+    return scroll_events
+  for event in browser_process.IterAllAsyncSlicesOfName("InputLatency"):
+    if event.start >= timeline_range.min and event.end <= timeline_range.max:
+      for ss in event.sub_slices:
+        if 'step' not in ss.args:
+          continue
+        if 'data' not in ss.args:
+          continue
+        if ss.args['step'] == scroll_type:
+          scroll_events.append(ss)
+  return scroll_events
+
+
+def ComputeMouseWheelScrollLatency(mouse_wheel_events):
+  """ Compute the mouse wheel scroll latency.
+
+  Mouse wheel scroll latency is the time from when mouse wheel event is sent
+  from browser RWH to renderer (the timestamp of component
+  'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT') to when the scrolled page is
+  buffer swapped (the timestamp of component
+  'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT')
+
+  """
+  mouse_wheel_latency = []
+  for event in mouse_wheel_events:
+    data = event.args['data']
+    if BEGIN_COMP_NAME in data and END_COMP_NAME in data:
+      latency = data[END_COMP_NAME]['time'] - data[BEGIN_COMP_NAME]['time']
+      mouse_wheel_latency.append(latency / 1000.0)
+  return mouse_wheel_latency
+
+
+def ComputeTouchScrollLatency(touch_scroll_events):
+  """ Compute the touch scroll latency.
+
+  Touch scroll latency is the time from when the touch event is created to
+  when the scrolled page is buffer swapped.
+  Touch event on differnt platforms uses different LatencyInfo component to
+  record its creation timestamp. On Aura, the creation time is kept in
+  'INPUT_EVENT_LATENCY_UI_COMPONENT' . On Android, the creation time is kept
+  in 'INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT'.
+
+  """
+  touch_scroll_latency = []
+  for event in touch_scroll_events:
+    data = event.args['data']
+    if END_COMP_NAME in data:
+      end_time = data[END_COMP_NAME]['time']
+      if UI_COMP_NAME in data and ORIGINAL_COMP_NAME in data:
+        raise ValueError, 'LatencyInfo has both UI and ORIGINAL component'
+      if UI_COMP_NAME in data:
+        latency = end_time - data[UI_COMP_NAME]['time']
+        touch_scroll_latency.append(latency / 1000.0)
+      elif ORIGINAL_COMP_NAME in data:
+        latency = end_time - data[ORIGINAL_COMP_NAME]['time']
+        touch_scroll_latency.append(latency / 1000.0)
+  return touch_scroll_latency
+
+
+def HasRenderingStats(process):
+  """ Returns True if the process contains at least one
+      BenchmarkInstrumentation::*RenderingStats event with a frame.
+  """
+  if not process:
+    return False
+  for event in process.IterAllSlicesOfName(
+      'BenchmarkInstrumentation::MainThreadRenderingStats'):
+    if 'data' in event.args and event.args['data']['frame_count'] == 1:
+      return True
+  for event in process.IterAllSlicesOfName(
+      'BenchmarkInstrumentation::ImplThreadRenderingStats'):
+    if 'data' in event.args and event.args['data']['frame_count'] == 1:
+      return True
+  return False
+
+
+class RenderingStats(object):
+  def __init__(self, renderer_process, browser_process, timeline_ranges):
+    """
+    Utility class for extracting rendering statistics from the timeline (or
+    other loggin facilities), and providing them in a common format to classes
+    that compute benchmark metrics from this data.
+
+    Stats are lists of lists of numbers. The outer list stores one list per
+    timeline range.
+
+    All *_time values are measured in milliseconds.
+    """
+    assert(len(timeline_ranges) > 0)
+    # Find the top level process with rendering stats (browser or renderer).
+    if HasRenderingStats(browser_process):
+      timestamp_process = browser_process
+    else:
+      timestamp_process  = renderer_process
+
+    self.frame_timestamps = []
+    self.frame_times = []
+    self.paint_times = []
+    self.painted_pixel_counts = []
+    self.record_times = []
+    self.recorded_pixel_counts = []
+    self.rasterize_times = []
+    self.rasterized_pixel_counts = []
+    self.approximated_pixel_percentages = []
+    # End-to-end latency for MouseWheel scroll - from when mouse wheel event is
+    # generated to when the scrolled page is buffer swapped.
+    self.mouse_wheel_scroll_latency = []
+    # End-to-end latency for GestureScrollUpdate scroll - from when the touch
+    # event is generated to the scrolled page is buffer swapped.
+    self.touch_scroll_latency = []
+    # End-to-end latency for JS touch handler scrolling - from when the touch
+    # event is generated to the scrolled page is buffer swapped.
+    self.js_touch_scroll_latency = []
+
+    for timeline_range in timeline_ranges:
+      self.frame_timestamps.append([])
+      self.frame_times.append([])
+      self.paint_times.append([])
+      self.painted_pixel_counts.append([])
+      self.record_times.append([])
+      self.recorded_pixel_counts.append([])
+      self.rasterize_times.append([])
+      self.rasterized_pixel_counts.append([])
+      self.approximated_pixel_percentages.append([])
+      self.mouse_wheel_scroll_latency.append([])
+      self.touch_scroll_latency.append([])
+      self.js_touch_scroll_latency.append([])
+
+      if timeline_range.is_empty:
+        continue
+      self._InitFrameTimestampsFromTimeline(timestamp_process, timeline_range)
+      self._InitMainThreadRenderingStatsFromTimeline(
+          renderer_process, timeline_range)
+      self._InitImplThreadRenderingStatsFromTimeline(
+          renderer_process, timeline_range)
+      self._InitScrollLatencyStatsFromTimeline(browser_process, timeline_range)
+
+    # Check if we have collected at least 2 frames in every range. Otherwise we
+    # can't compute any meaningful metrics.
+    for segment in self.frame_timestamps:
+      if len(segment) < 2:
+        raise NotEnoughFramesError(len(segment))
+
+  def _InitScrollLatencyStatsFromTimeline(
+      self, browser_process, timeline_range):
+    mouse_wheel_events = GetScrollInputLatencyEvents(
+        "MouseWheel", browser_process, timeline_range)
+    self.mouse_wheel_scroll_latency = ComputeMouseWheelScrollLatency(
+        mouse_wheel_events)
+
+    touch_scroll_events = GetScrollInputLatencyEvents(
+        "GestureScrollUpdate", browser_process, timeline_range)
+    self.touch_scroll_latency = ComputeTouchScrollLatency(touch_scroll_events)
+
+    js_touch_scroll_events = GetScrollInputLatencyEvents(
+        "TouchMove", browser_process, timeline_range)
+    self.js_touch_scroll_latency = ComputeTouchScrollLatency(
+        js_touch_scroll_events)
+
+  def _GatherEvents(self, event_name, process, timeline_range):
+    events = []
+    for event in process.IterAllSlicesOfName(event_name):
+      if event.start >= timeline_range.min and event.end <= timeline_range.max:
+        if 'data' not in event.args:
+          continue
+        events.append(event)
+    events.sort(key=attrgetter('start'))
+    return events
+
+  def _AddFrameTimestamp(self, event):
+    frame_count = event.args['data']['frame_count']
+    if frame_count > 1:
+      raise ValueError, 'trace contains multi-frame render stats'
+    if frame_count == 1:
+      self.frame_timestamps[-1].append(
+          event.start)
+      if len(self.frame_timestamps[-1]) >= 2:
+        self.frame_times[-1].append(round(self.frame_timestamps[-1][-1] -
+                                          self.frame_timestamps[-1][-2], 2))
+
+  def _InitFrameTimestampsFromTimeline(self, process, timeline_range):
+    event_name = 'BenchmarkInstrumentation::MainThreadRenderingStats'
+    for event in self._GatherEvents(event_name, process, timeline_range):
+      self._AddFrameTimestamp(event)
+
+    event_name = 'BenchmarkInstrumentation::ImplThreadRenderingStats'
+    for event in self._GatherEvents(event_name, process, timeline_range):
+      self._AddFrameTimestamp(event)
+
+
+  def _InitMainThreadRenderingStatsFromTimeline(self, process, timeline_range):
+    event_name = 'BenchmarkInstrumentation::MainThreadRenderingStats'
+    for event in self._GatherEvents(event_name, process, timeline_range):
+      data = event.args['data']
+      self.paint_times[-1].append(1000.0 * data['paint_time'])
+      self.painted_pixel_counts[-1].append(data['painted_pixel_count'])
+      self.record_times[-1].append(1000.0 * data['record_time'])
+      self.recorded_pixel_counts[-1].append(data['recorded_pixel_count'])
+
+  def _InitImplThreadRenderingStatsFromTimeline(self, process, timeline_range):
+    event_name = 'BenchmarkInstrumentation::ImplThreadRenderingStats'
+    for event in self._GatherEvents(event_name, process, timeline_range):
+      data = event.args['data']
+      self.rasterize_times[-1].append(1000.0 * data['rasterize_time'])
+      self.rasterized_pixel_counts[-1].append(data['rasterized_pixel_count'])
+      if data.get('visible_content_area', 0):
+        self.approximated_pixel_percentages[-1].append(
+            round(float(data['approximated_visible_content_area']) /
+                  float(data['visible_content_area']) * 100.0, 3))
+      else:
+        self.approximated_pixel_percentages[-1].append(0.0)
diff --git a/tools/telemetry/telemetry/web_perf/metrics/rendering_stats_unittest.py b/tools/telemetry/telemetry/web_perf/metrics/rendering_stats_unittest.py
new file mode 100644
index 0000000..4ec6644
--- /dev/null
+++ b/tools/telemetry/telemetry/web_perf/metrics/rendering_stats_unittest.py
@@ -0,0 +1,477 @@
+# 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.
+
+import random
+import unittest
+
+from telemetry.web_perf.metrics.rendering_stats import (
+  UI_COMP_NAME, BEGIN_COMP_NAME, END_COMP_NAME)
+from telemetry.web_perf.metrics.rendering_stats import (
+  GetScrollInputLatencyEvents)
+from telemetry.web_perf.metrics.rendering_stats import (
+  ComputeMouseWheelScrollLatency)
+from telemetry.web_perf.metrics.rendering_stats import ComputeTouchScrollLatency
+from telemetry.web_perf.metrics.rendering_stats import HasRenderingStats
+from telemetry.web_perf.metrics.rendering_stats import RenderingStats
+from telemetry.web_perf.metrics.rendering_stats import NotEnoughFramesError
+from telemetry.util.statistics import DivideIfPossibleOrZero
+import telemetry.core.timeline.bounds as timeline_bounds
+from telemetry.core.timeline import model
+import telemetry.core.timeline.async_slice as tracing_async_slice
+
+
+class MockTimer(object):
+  """A mock timer class which can generate random durations.
+
+  An instance of this class is used as a global timer to generate random
+  durations for stats and consistent timestamps for all mock trace events.
+  The unit of time is milliseconds.
+  """
+  def __init__(self):
+    self.milliseconds = 0
+
+  def Get(self):
+    return self.milliseconds
+
+  def Advance(self, low=0, high=1):
+    delta = random.uniform(low, high)
+    self.milliseconds += delta
+    return delta
+
+
+class ReferenceRenderingStats(object):
+  """ Stores expected data for comparison with actual RenderingStats """
+  def __init__(self):
+    self.frame_timestamps = []
+    self.frame_times = []
+    self.paint_times = []
+    self.painted_pixel_counts = []
+    self.record_times = []
+    self.recorded_pixel_counts = []
+    self.rasterize_times = []
+    self.rasterized_pixel_counts = []
+    self.approximated_pixel_percentages = []
+
+  def AppendNewRange(self):
+    self.frame_timestamps.append([])
+    self.frame_times.append([])
+    self.paint_times.append([])
+    self.painted_pixel_counts.append([])
+    self.record_times.append([])
+    self.recorded_pixel_counts.append([])
+    self.rasterize_times.append([])
+    self.rasterized_pixel_counts.append([])
+    self.approximated_pixel_percentages.append([])
+
+class ReferenceInputLatencyStats(object):
+  """ Stores expected data for comparison with actual input latency stats """
+  def __init__(self):
+    self.mouse_wheel_scroll_latency = []
+    self.touch_scroll_latency = []
+    self.js_touch_scroll_latency = []
+    self.mouse_wheel_scroll_events = []
+    self.touch_scroll_events = []
+    self.js_touch_scroll_events = []
+
+def AddMainThreadRenderingStats(mock_timer, thread, first_frame,
+                                ref_stats = None):
+  """ Adds a random main thread rendering stats event.
+
+  thread: The timeline model thread to which the event will be added.
+  first_frame: Is this the first frame within the bounds of an action?
+  ref_stats: A ReferenceRenderingStats object to record expected values.
+  """
+  # Create randonm data and timestap for main thread rendering stats.
+  data = { 'frame_count': 0,
+           'paint_time': 0.0,
+           'painted_pixel_count': 0,
+           'record_time': mock_timer.Advance(2, 4) / 1000.0,
+           'recorded_pixel_count': 3000*3000 }
+  timestamp = mock_timer.Get()
+
+  # Add a slice with the event data to the given thread.
+  thread.PushCompleteSlice(
+      'benchmark', 'BenchmarkInstrumentation::MainThreadRenderingStats',
+      timestamp, duration=0.0, thread_timestamp=None, thread_duration=None,
+      args={'data': data})
+
+  if not ref_stats:
+    return
+
+  # Add timestamp only if a frame was output
+  if data['frame_count'] == 1:
+    if not first_frame:
+      # Add frame_time if this is not the first frame in within the bounds of an
+      # action.
+      prev_timestamp = ref_stats.frame_timestamps[-1][-1]
+      ref_stats.frame_times[-1].append(round(timestamp - prev_timestamp, 2))
+    ref_stats.frame_timestamps[-1].append(timestamp)
+
+  ref_stats.paint_times[-1].append(data['paint_time'] * 1000.0)
+  ref_stats.painted_pixel_counts[-1].append(data['painted_pixel_count'])
+  ref_stats.record_times[-1].append(data['record_time'] * 1000.0)
+  ref_stats.recorded_pixel_counts[-1].append(data['recorded_pixel_count'])
+
+
+def AddImplThreadRenderingStats(mock_timer, thread, first_frame,
+                                ref_stats = None):
+  """ Adds a random impl thread rendering stats event.
+
+  thread: The timeline model thread to which the event will be added.
+  first_frame: Is this the first frame within the bounds of an action?
+  ref_stats: A ReferenceRenderingStats object to record expected values.
+  """
+  # Create randonm data and timestap for impl thread rendering stats.
+  data = { 'frame_count': 1,
+           'rasterize_time': mock_timer.Advance(5, 10) / 1000.0,
+           'rasterized_pixel_count': 1280*720,
+           'visible_content_area': random.uniform(0, 100),
+           'approximated_visible_content_area': random.uniform(0, 5)}
+  timestamp = mock_timer.Get()
+
+  # Add a slice with the event data to the given thread.
+  thread.PushCompleteSlice(
+      'benchmark', 'BenchmarkInstrumentation::ImplThreadRenderingStats',
+      timestamp, duration=0.0, thread_timestamp=None, thread_duration=None,
+      args={'data': data})
+
+  if not ref_stats:
+    return
+
+  # Add timestamp only if a frame was output
+  if data['frame_count'] == 1:
+    if not first_frame:
+      # Add frame_time if this is not the first frame in within the bounds of an
+      # action.
+      prev_timestamp = ref_stats.frame_timestamps[-1][-1]
+      ref_stats.frame_times[-1].append(round(timestamp - prev_timestamp, 2))
+    ref_stats.frame_timestamps[-1].append(timestamp)
+
+  ref_stats.rasterize_times[-1].append(data['rasterize_time'] * 1000.0)
+  ref_stats.rasterized_pixel_counts[-1].append(data['rasterized_pixel_count'])
+  ref_stats.approximated_pixel_percentages[-1].append(
+      round(DivideIfPossibleOrZero(data['approximated_visible_content_area'],
+                                   data['visible_content_area']) * 100.0, 3))
+
+
+def AddInputLatencyStats(mock_timer, input_type, start_thread, end_thread,
+                         ref_latency_stats = None):
+  """ Adds a random input latency stats event.
+
+  input_type: The input type for which the latency slice is generated.
+  start_thread: The start thread on which the async slice is added.
+  end_thread: The end thread on which the async slice is ended.
+  ref_latency_stats: A ReferenceInputLatencyStats object for expected values.
+  """
+
+  mock_timer.Advance(2, 4)
+  ui_comp_time = mock_timer.Get() * 1000.0
+  mock_timer.Advance(2, 4)
+  begin_comp_time = mock_timer.Get() * 1000.0
+  mock_timer.Advance(10, 20)
+  end_comp_time = mock_timer.Get() * 1000.0
+
+  data = { UI_COMP_NAME: {'time': ui_comp_time},
+           BEGIN_COMP_NAME: {'time': begin_comp_time},
+           END_COMP_NAME: {'time': end_comp_time} }
+
+  timestamp = mock_timer.Get()
+
+  async_slice = tracing_async_slice.AsyncSlice(
+      'benchmark', 'InputLatency', timestamp)
+
+  async_sub_slice = tracing_async_slice.AsyncSlice(
+      'benchmark', 'InputLatency', timestamp)
+  async_sub_slice.args = {'data': data, 'step': input_type}
+  async_sub_slice.parent_slice = async_slice
+  async_sub_slice.start_thread = start_thread
+  async_sub_slice.end_thread = end_thread
+
+  async_slice.sub_slices.append(async_sub_slice)
+  async_slice.start_thread = start_thread
+  async_slice.end_thread = end_thread
+  start_thread.AddAsyncSlice(async_slice)
+
+  if not ref_latency_stats:
+    return
+
+  if input_type == 'MouseWheel':
+    ref_latency_stats.mouse_wheel_scroll_events.append(async_sub_slice)
+    ref_latency_stats.mouse_wheel_scroll_latency.append(
+        (data[END_COMP_NAME]['time'] - data[BEGIN_COMP_NAME]['time']) / 1000.0)
+
+  if input_type == 'GestureScrollUpdate':
+    ref_latency_stats.touch_scroll_events.append(async_sub_slice)
+    ref_latency_stats.touch_scroll_latency.append(
+        (data[END_COMP_NAME]['time'] - data[UI_COMP_NAME]['time']) / 1000.0)
+
+  if input_type == 'TouchMove':
+    ref_latency_stats.js_touch_scroll_events.append(async_sub_slice)
+    ref_latency_stats.js_touch_scroll_latency.append(
+        (data[END_COMP_NAME]['time'] - data[UI_COMP_NAME]['time']) / 1000.0)
+
+class RenderingStatsUnitTest(unittest.TestCase):
+  def testHasRenderingStats(self):
+    timeline = model.TimelineModel()
+    timer = MockTimer()
+
+    # A process without rendering stats
+    process_without_stats = timeline.GetOrCreateProcess(pid = 1)
+    thread_without_stats = process_without_stats.GetOrCreateThread(tid = 11)
+    process_without_stats.FinalizeImport()
+    self.assertFalse(HasRenderingStats(thread_without_stats))
+
+    # A process with rendering stats, but no frames in them
+    process_without_frames = timeline.GetOrCreateProcess(pid = 2)
+    thread_without_frames = process_without_frames.GetOrCreateThread(tid = 21)
+    AddMainThreadRenderingStats(timer, thread_without_frames, True, None)
+    process_without_frames.FinalizeImport()
+    self.assertFalse(HasRenderingStats(thread_without_frames))
+
+    # A process with rendering stats and frames in them
+    process_with_frames = timeline.GetOrCreateProcess(pid = 3)
+    thread_with_frames = process_with_frames.GetOrCreateThread(tid = 31)
+    AddImplThreadRenderingStats(timer, thread_with_frames, True, None)
+    process_with_frames.FinalizeImport()
+    self.assertTrue(HasRenderingStats(thread_with_frames))
+
+  def testRangeWithoutFrames(self):
+    timer = MockTimer()
+    timeline = model.TimelineModel()
+
+    # Create a renderer process, with a main thread and impl thread.
+    renderer = timeline.GetOrCreateProcess(pid = 2)
+    renderer_main = renderer.GetOrCreateThread(tid = 21)
+    renderer_compositor = renderer.GetOrCreateThread(tid = 22)
+
+    # Create 10 main and impl rendering stats events for Action A.
+    timer.Advance(2, 4)
+    renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
+    for i in xrange(0, 10):
+      first = (i == 0)
+      AddMainThreadRenderingStats(timer, renderer_main, first, None)
+      AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
+    timer.Advance(2, 4)
+    renderer_main.EndSlice(timer.Get())
+
+    # Create 5 main and impl rendering stats events not within any action.
+    for i in xrange(0, 5):
+      first = (i == 0)
+      AddMainThreadRenderingStats(timer, renderer_main, first, None)
+      AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
+
+    # Create Action B without any frames. This should trigger
+    # NotEnoughFramesError when the RenderingStats object is created.
+    timer.Advance(2, 4)
+    renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '')
+    timer.Advance(2, 4)
+    renderer_main.EndSlice(timer.Get())
+
+    renderer.FinalizeImport()
+
+    timeline_markers = timeline.FindTimelineMarkers(['ActionA', 'ActionB'])
+    timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker)
+                        for marker in timeline_markers ]
+    self.assertRaises(NotEnoughFramesError, RenderingStats,
+                      renderer, None, timeline_ranges)
+
+  def testFromTimeline(self):
+    timeline = model.TimelineModel()
+
+    # Create a browser process and a renderer process, and a main thread and
+    # impl thread for each.
+    browser = timeline.GetOrCreateProcess(pid = 1)
+    browser_main = browser.GetOrCreateThread(tid = 11)
+    browser_compositor = browser.GetOrCreateThread(tid = 12)
+    renderer = timeline.GetOrCreateProcess(pid = 2)
+    renderer_main = renderer.GetOrCreateThread(tid = 21)
+    renderer_compositor = renderer.GetOrCreateThread(tid = 22)
+
+    timer = MockTimer()
+    renderer_ref_stats = ReferenceRenderingStats()
+    browser_ref_stats = ReferenceRenderingStats()
+
+    # Create 10 main and impl rendering stats events for Action A.
+    timer.Advance(2, 4)
+    renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
+    renderer_ref_stats.AppendNewRange()
+    browser_ref_stats.AppendNewRange()
+    for i in xrange(0, 10):
+      first = (i == 0)
+      AddMainThreadRenderingStats(
+          timer, renderer_main, first, renderer_ref_stats)
+      AddImplThreadRenderingStats(
+          timer, renderer_compositor, first, renderer_ref_stats)
+      AddMainThreadRenderingStats(
+          timer, browser_main, first, browser_ref_stats)
+      AddImplThreadRenderingStats(
+          timer, browser_compositor, first, browser_ref_stats)
+    timer.Advance(2, 4)
+    renderer_main.EndSlice(timer.Get())
+
+    # Create 5 main and impl rendering stats events not within any action.
+    for i in xrange(0, 5):
+      first = (i == 0)
+      AddMainThreadRenderingStats(timer, renderer_main, first, None)
+      AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
+      AddMainThreadRenderingStats(timer, browser_main, first, None)
+      AddImplThreadRenderingStats(timer, browser_compositor, first, None)
+
+    # Create 10 main and impl rendering stats events for Action B.
+    timer.Advance(2, 4)
+    renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '')
+    renderer_ref_stats.AppendNewRange()
+    browser_ref_stats.AppendNewRange()
+    for i in xrange(0, 10):
+      first = (i == 0)
+      AddMainThreadRenderingStats(
+          timer, renderer_main, first, renderer_ref_stats)
+      AddImplThreadRenderingStats(
+          timer, renderer_compositor, first, renderer_ref_stats)
+      AddMainThreadRenderingStats(
+          timer, browser_main, first, browser_ref_stats)
+      AddImplThreadRenderingStats(
+          timer, browser_compositor, first, browser_ref_stats)
+    timer.Advance(2, 4)
+    renderer_main.EndSlice(timer.Get())
+
+    # Create 10 main and impl rendering stats events for Action A.
+    timer.Advance(2, 4)
+    renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
+    renderer_ref_stats.AppendNewRange()
+    browser_ref_stats.AppendNewRange()
+    for i in xrange(0, 10):
+      first = (i == 0)
+      AddMainThreadRenderingStats(
+          timer, renderer_main, first, renderer_ref_stats)
+      AddImplThreadRenderingStats(
+          timer, renderer_compositor, first, renderer_ref_stats)
+      AddMainThreadRenderingStats(
+          timer, browser_main, first, browser_ref_stats)
+      AddImplThreadRenderingStats(
+          timer, browser_compositor, first, browser_ref_stats)
+    timer.Advance(2, 4)
+    renderer_main.EndSlice(timer.Get())
+
+    browser.FinalizeImport()
+    renderer.FinalizeImport()
+
+    timeline_markers = timeline.FindTimelineMarkers(
+        ['ActionA', 'ActionB', 'ActionA'])
+    timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker)
+                        for marker in timeline_markers ]
+    stats = RenderingStats(renderer, browser, timeline_ranges)
+
+    # Compare rendering stats to reference.
+    self.assertEquals(stats.frame_timestamps,
+                      browser_ref_stats.frame_timestamps)
+    self.assertEquals(stats.frame_times, browser_ref_stats.frame_times)
+    self.assertEquals(stats.rasterize_times, renderer_ref_stats.rasterize_times)
+    self.assertEquals(stats.rasterized_pixel_counts,
+                      renderer_ref_stats.rasterized_pixel_counts)
+    self.assertEquals(stats.approximated_pixel_percentages,
+                      renderer_ref_stats.approximated_pixel_percentages)
+    self.assertEquals(stats.paint_times, renderer_ref_stats.paint_times)
+    self.assertEquals(stats.painted_pixel_counts,
+                      renderer_ref_stats.painted_pixel_counts)
+    self.assertEquals(stats.record_times, renderer_ref_stats.record_times)
+    self.assertEquals(stats.recorded_pixel_counts,
+                      renderer_ref_stats.recorded_pixel_counts)
+
+  def testScrollLatencyFromTimeline(self):
+    timeline = model.TimelineModel()
+
+    # Create a browser process and a renderer process.
+    browser = timeline.GetOrCreateProcess(pid = 1)
+    browser_main = browser.GetOrCreateThread(tid = 11)
+    renderer = timeline.GetOrCreateProcess(pid = 2)
+    renderer_main = renderer.GetOrCreateThread(tid = 21)
+
+    timer = MockTimer()
+    ref_latency_stats = ReferenceInputLatencyStats()
+
+    # Create 10 input latency stats events for Action A.
+    timer.Advance(2, 4)
+    renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
+    for _ in xrange(0, 10):
+      AddInputLatencyStats(timer, 'MouseWheel', browser_main,
+                           renderer_main, ref_latency_stats)
+      AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main,
+                           renderer_main, ref_latency_stats)
+      AddInputLatencyStats(timer, 'TouchMove', browser_main,
+                           renderer_main, ref_latency_stats)
+    timer.Advance(2, 4)
+    renderer_main.EndSlice(timer.Get())
+
+    # Create 5 input latency stats events not within any action.
+    timer.Advance(2, 4)
+    for _ in xrange(0, 5):
+      AddInputLatencyStats(timer, 'MouseWheel', browser_main,
+                           renderer_main, None)
+      AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main,
+                           renderer_main, None)
+      AddInputLatencyStats(timer, 'TouchMove', browser_main,
+                           renderer_main, None)
+
+    # Create 10 input latency stats events for Action B.
+    timer.Advance(2, 4)
+    renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '')
+    for _ in xrange(0, 10):
+      AddInputLatencyStats(timer, 'MouseWheel', browser_main,
+                           renderer_main, ref_latency_stats)
+      AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main,
+                           renderer_main, ref_latency_stats)
+      AddInputLatencyStats(timer, 'TouchMove', browser_main,
+                           renderer_main, ref_latency_stats)
+    timer.Advance(2, 4)
+    renderer_main.EndSlice(timer.Get())
+
+    # Create 10 input latency stats events for Action A.
+    timer.Advance(2, 4)
+    renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '')
+    for _ in xrange(0, 10):
+      AddInputLatencyStats(timer, 'MouseWheel', browser_main,
+                                  renderer_main, ref_latency_stats)
+      AddInputLatencyStats(timer, 'GestureScrollUpdate', browser_main,
+                                  renderer_main, ref_latency_stats)
+      AddInputLatencyStats(timer, 'TouchMove', browser_main,
+                                  renderer_main, ref_latency_stats)
+    timer.Advance(2, 4)
+    renderer_main.EndSlice(timer.Get())
+
+    browser.FinalizeImport()
+    renderer.FinalizeImport()
+
+    mouse_wheel_scroll_events = []
+    touch_scroll_events = []
+    js_touch_scroll_events = []
+
+    timeline_markers = timeline.FindTimelineMarkers(
+        ['ActionA', 'ActionB', 'ActionA'])
+    for timeline_range in [ timeline_bounds.Bounds.CreateFromEvent(marker)
+                            for marker in timeline_markers ]:
+      if timeline_range.is_empty:
+        continue
+      tmp_mouse_events = GetScrollInputLatencyEvents(
+          'MouseWheel', browser, timeline_range)
+      tmp_touch_scroll_events = GetScrollInputLatencyEvents(
+          'GestureScrollUpdate', browser, timeline_range)
+      tmp_js_touch_scroll_events = GetScrollInputLatencyEvents(
+          'TouchMove', browser, timeline_range)
+      mouse_wheel_scroll_events.extend(tmp_mouse_events)
+      touch_scroll_events.extend(tmp_touch_scroll_events)
+      js_touch_scroll_events.extend(tmp_js_touch_scroll_events)
+
+    self.assertEquals(mouse_wheel_scroll_events,
+                      ref_latency_stats.mouse_wheel_scroll_events)
+    self.assertEquals(touch_scroll_events,
+                      ref_latency_stats.touch_scroll_events)
+    self.assertEquals(js_touch_scroll_events,
+                      ref_latency_stats.js_touch_scroll_events)
+    self.assertEquals(ComputeMouseWheelScrollLatency(mouse_wheel_scroll_events),
+                      ref_latency_stats.mouse_wheel_scroll_latency)
+    self.assertEquals(ComputeTouchScrollLatency(touch_scroll_events),
+                      ref_latency_stats.touch_scroll_latency)
+    self.assertEquals(ComputeTouchScrollLatency(js_touch_scroll_events),
+                      ref_latency_stats.js_touch_scroll_latency)
diff --git a/tools/telemetry/telemetry/web_perf/metrics/smoothness.py b/tools/telemetry/telemetry/web_perf/metrics/smoothness.py
new file mode 100644
index 0000000..c2a8b54
--- /dev/null
+++ b/tools/telemetry/telemetry/web_perf/metrics/smoothness.py
@@ -0,0 +1,72 @@
+# 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.
+
+from telemetry.web_perf.metrics import timeline_based_metric
+from telemetry.web_perf.metrics import rendering_stats
+from telemetry.page.perf_tests_helper import FlattenList
+from telemetry.util import statistics
+
+
+class SmoothnessMetric(timeline_based_metric.TimelineBasedMetric):
+  def __init__(self):
+    super(SmoothnessMetric, self).__init__()
+
+  def AddResults(self, model, renderer_thread, interaction_records, results):
+    renderer_process = renderer_thread.parent
+    stats = rendering_stats.RenderingStats(
+      renderer_process, model.browser_process,
+      [r.GetBounds() for r in interaction_records])
+    if stats.mouse_wheel_scroll_latency:
+      mean_mouse_wheel_scroll_latency = statistics.ArithmeticMean(
+        stats.mouse_wheel_scroll_latency)
+      mouse_wheel_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
+        stats.mouse_wheel_scroll_latency)
+      results.Add('mean_mouse_wheel_scroll_latency', 'ms',
+                  round(mean_mouse_wheel_scroll_latency, 3))
+      results.Add('mouse_wheel_scroll_latency_discrepancy', 'ms',
+                  round(mouse_wheel_scroll_latency_discrepancy, 4))
+
+    if stats.touch_scroll_latency:
+      mean_touch_scroll_latency = statistics.ArithmeticMean(
+        stats.touch_scroll_latency)
+      touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
+        stats.touch_scroll_latency)
+      results.Add('mean_touch_scroll_latency', 'ms',
+                  round(mean_touch_scroll_latency, 3))
+      results.Add('touch_scroll_latency_discrepancy', 'ms',
+                  round(touch_scroll_latency_discrepancy, 4))
+
+    if stats.js_touch_scroll_latency:
+      mean_js_touch_scroll_latency = statistics.ArithmeticMean(
+        stats.js_touch_scroll_latency)
+      js_touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy(
+        stats.js_touch_scroll_latency)
+      results.Add('mean_js_touch_scroll_latency', 'ms',
+                  round(mean_js_touch_scroll_latency, 3))
+      results.Add('js_touch_scroll_latency_discrepancy', 'ms',
+                  round(js_touch_scroll_latency_discrepancy, 4))
+
+    # List of raw frame times.
+    frame_times = FlattenList(stats.frame_times)
+    results.Add('frame_times', 'ms', frame_times)
+
+    # Arithmetic mean of frame times.
+    mean_frame_time = statistics.ArithmeticMean(frame_times)
+    results.Add('mean_frame_time', 'ms', round(mean_frame_time, 3))
+
+    # Absolute discrepancy of frame time stamps.
+    frame_discrepancy = statistics.TimestampsDiscrepancy(
+      stats.frame_timestamps)
+    results.Add('jank', 'ms', round(frame_discrepancy, 4))
+
+    # Are we hitting 60 fps for 95 percent of all frames?
+    # We use 19ms as a somewhat looser threshold, instead of 1000.0/60.0.
+    percentile_95 = statistics.Percentile(frame_times, 95.0)
+    results.Add('mostly_smooth', 'score', 1.0 if percentile_95 < 19.0 else 0.0)
+
+    # Mean percentage of pixels approximated (missing tiles, low resolution
+    # tiles, non-ideal resolution tiles)
+    results.Add('mean_pixels_approximated', 'percent',
+                round(statistics.ArithmeticMean(
+                    FlattenList(stats.approximated_pixel_percentages)), 3))
diff --git a/tools/perf/metrics/timeline_based_metric.py b/tools/telemetry/telemetry/web_perf/metrics/timeline_based_metric.py
similarity index 100%
rename from tools/perf/metrics/timeline_based_metric.py
rename to tools/telemetry/telemetry/web_perf/metrics/timeline_based_metric.py
diff --git a/tools/telemetry/telemetry/web_perf/timeline_based_measurement.py b/tools/telemetry/telemetry/web_perf/timeline_based_measurement.py
new file mode 100644
index 0000000..a9cb2df
--- /dev/null
+++ b/tools/telemetry/telemetry/web_perf/timeline_based_measurement.py
@@ -0,0 +1,138 @@
+# 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.
+
+from telemetry.core.backends.chrome import tracing_backend
+from telemetry.web_perf import timeline_interaction_record as tir_module
+from telemetry.web_perf.metrics import smoothness
+from telemetry.page import page_measurement
+from telemetry.core.timeline import model as model_module
+
+
+# TimelineBasedMeasurement considers all instrumentation as producing a single
+# timeline. But, depending on the amount of instrumentation that is enabled,
+# overhead increases. The user of the measurement must therefore chose between
+# a few levels of instrumentation.
+NO_OVERHEAD_LEVEL = 'no-overhead'
+MINIMAL_OVERHEAD_LEVEL = 'minimal-overhead'
+DEBUG_OVERHEAD_LEVEL = 'debug-overhead'
+
+ALL_OVERHEAD_LEVELS = [
+  NO_OVERHEAD_LEVEL,
+  MINIMAL_OVERHEAD_LEVEL,
+  DEBUG_OVERHEAD_LEVEL
+]
+
+
+class _ResultsWrapper(object):
+  def __init__(self, results, interaction_record):
+    self._results = results
+    self._interaction_record = interaction_record
+
+  def Add(self, trace_name, units, value, chart_name=None, data_type='default'):
+    trace_name = self._interaction_record.GetResultNameFor(trace_name)
+    self._results.Add(trace_name, units, value, chart_name, data_type)
+
+  def AddSummary(self, trace_name, units, value, chart_name=None,
+                  data_type='default'):
+    trace_name = self._interaction_record.GetResultNameFor(trace_name)
+    self._results.AddSummary(trace_name, units, value, chart_name, data_type)
+
+
+class _TimelineBasedMetrics(object):
+  def __init__(self, model, renderer_thread,
+               create_metrics_for_interaction_record_callback):
+    self._model = model
+    self._renderer_thread = renderer_thread
+    self._create_metrics_for_interaction_record_callback = \
+        create_metrics_for_interaction_record_callback
+
+  def FindTimelineInteractionRecords(self):
+    # TODO(nduca): Add support for page-load interaction record.
+    return [tir_module.TimelineInteractionRecord.FromEvent(event) for
+            event in self._renderer_thread.async_slices
+            if tir_module.IsTimelineInteractionRecord(event.name)]
+
+
+  def AddResults(self, results):
+    interactions = self.FindTimelineInteractionRecords()
+    if len(interactions) == 0:
+      raise Exception('Expected at least one Interaction on the page')
+    for interaction in interactions:
+      metrics = \
+          self._create_metrics_for_interaction_record_callback(interaction)
+      wrapped_results = _ResultsWrapper(results, interaction)
+      for m in metrics:
+        m.AddResults(self._model, self._renderer_thread,
+                     [interaction], wrapped_results)
+
+
+class TimelineBasedMeasurement(page_measurement.PageMeasurement):
+  """Collects multiple metrics pages based on their interaction records.
+
+  A timeline measurement shifts the burden of what metrics to collect onto the
+  page under test, or the pageset running that page. Instead of the measurement
+  having a fixed set of values it collects about the page, the page being tested
+  issues (via javascript) an Interaction record into the user timing API that
+  describing what the page is doing at that time, as well as a standardized set
+  of flags describing the semantics of the work being done. The
+  TimelineBasedMeasurement object collects a trace that includes both these
+  interaction recorsd, and a user-chosen amount of performance data using
+  Telemetry's various timeline-producing APIs, tracing especially.
+
+  It then passes the recorded timeline to different TimelineBasedMetrics based
+  on those flags. This allows a single run through a page to produce load timing
+  data, smoothness data, critical jank information and overall cpu usage
+  information.
+
+  For information on how to mark up a page to work with
+  TimelineBasedMeasurement, refer to the
+  perf.metrics.timeline_interaction_record module.
+
+  """
+  def __init__(self):
+    super(TimelineBasedMeasurement, self).__init__('RunSmoothness')
+
+  @classmethod
+  def AddCommandLineArgs(cls, parser):
+    parser.add_option(
+        '--overhead-level', type='choice',
+        choices=ALL_OVERHEAD_LEVELS,
+        default=NO_OVERHEAD_LEVEL,
+        help='How much overhead to incur during the measurement.')
+
+  def WillNavigateToPage(self, page, tab):
+    if not tab.browser.supports_tracing:
+      raise Exception('Not supported')
+    assert self.options.overhead_level in ALL_OVERHEAD_LEVELS
+    if self.options.overhead_level == NO_OVERHEAD_LEVEL:
+      categories = tracing_backend.MINIMAL_TRACE_CATEGORIES
+    elif self.options.overhead_level == \
+        MINIMAL_OVERHEAD_LEVEL:
+      categories = ''
+    else:
+      categories = '*,disabled-by-default-cc.debug'
+    categories = ','.join([categories] + page.GetSyntheticDelayCategories())
+    tab.browser.StartTracing(categories)
+
+  def CreateMetricsForTimelineInteractionRecord(self, interaction):
+    """ Subclass of TimelineBasedMeasurement overrides this method to customize
+    the binding of interaction's flags to metrics.
+    """
+    res = []
+    if interaction.is_smooth:
+      res.append(smoothness.SmoothnessMetric())
+    return res
+
+  def MeasurePage(self, page, tab, results):
+    """ Collect all possible metrics and added them to results. """
+    trace_result = tab.browser.StopTracing()
+    model = model_module.TimelineModel(trace_result)
+    renderer_thread = model.GetRendererThreadFromTab(tab)
+    meta_metrics = _TimelineBasedMetrics(
+      model, renderer_thread, self.CreateMetricsForTimelineInteractionRecord)
+    meta_metrics.AddResults(results)
+
+  def CleanUpAfterPage(self, page, tab):
+    if tab.browser.is_tracing_running:
+      tab.browser.StopTracing()
diff --git a/tools/telemetry/telemetry/web_perf/timeline_based_measurement_unittest.py b/tools/telemetry/telemetry/web_perf/timeline_based_measurement_unittest.py
new file mode 100644
index 0000000..0e86d35
--- /dev/null
+++ b/tools/telemetry/telemetry/web_perf/timeline_based_measurement_unittest.py
@@ -0,0 +1,115 @@
+# 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.
+
+import os
+import unittest
+
+from telemetry import test
+from telemetry.core import wpr_modes
+from telemetry.core.timeline import model as model_module
+from telemetry.core.timeline import async_slice
+from telemetry.page import page_measurement_results
+from telemetry.page import page_measurement_unittest_base
+from telemetry.page import page_set
+from telemetry.unittest import options_for_unittests
+from telemetry.web_perf import timeline_based_measurement as tbm_module
+from telemetry.web_perf.metrics import timeline_based_metric
+
+class TimelineBasedMetricsTests(unittest.TestCase):
+  def setUp(self):
+    model = model_module.TimelineModel()
+    renderer_thread = model.GetOrCreateProcess(1).GetOrCreateThread(2)
+    renderer_thread.name = 'CrRendererMain'
+
+    # [      X       ]
+    #      [  Y  ]
+    renderer_thread.BeginSlice('cat1', 'x.y', 10, 0)
+    renderer_thread.EndSlice(20, 20)
+
+    renderer_thread.async_slices.append(async_slice.AsyncSlice(
+        'cat', 'Interaction.LogicalName1/is_smooth',
+        timestamp=0, duration=20,
+        start_thread=renderer_thread, end_thread=renderer_thread))
+    renderer_thread.async_slices.append(async_slice.AsyncSlice(
+        'cat', 'Interaction.LogicalName2/is_loading_resources',
+        timestamp=25, duration=5,
+        start_thread=renderer_thread, end_thread=renderer_thread))
+    model.FinalizeImport()
+
+    self.model = model
+    self.renderer_thread = renderer_thread
+
+  def testFindTimelineInteractionRecords(self):
+    metric = tbm_module._TimelineBasedMetrics( # pylint: disable=W0212
+      self.model, self.renderer_thread, lambda _: [] )
+    interactions = metric.FindTimelineInteractionRecords()
+    self.assertEquals(2, len(interactions))
+    self.assertTrue(interactions[0].is_smooth)
+    self.assertEquals(0, interactions[0].start)
+    self.assertEquals(20, interactions[0].end)
+
+    self.assertTrue(interactions[1].is_loading_resources)
+    self.assertEquals(25, interactions[1].start)
+    self.assertEquals(30, interactions[1].end)
+
+  def testAddResults(self):
+    results = page_measurement_results.PageMeasurementResults()
+    class FakeSmoothMetric(timeline_based_metric.TimelineBasedMetric):
+      def AddResults(self, model, renderer_thread,
+                     interaction_records, results):
+        results.Add('FakeSmoothMetric', 'ms', 1)
+
+    class FakeLoadingMetric(timeline_based_metric.TimelineBasedMetric):
+      def AddResults(self, model, renderer_thread,
+                     interaction_records, results):
+        for r in interaction_records:
+          assert r.logical_name == 'LogicalName2'
+        results.Add('FakeLoadingMetric', 'ms', 2)
+
+    def CreateMetricsForTimelineInteractionRecord(interaction):
+      res = []
+      if interaction.is_smooth:
+        res.append(FakeSmoothMetric())
+      if interaction.is_loading_resources:
+        res.append(FakeLoadingMetric())
+      return res
+
+    metric = tbm_module._TimelineBasedMetrics( # pylint: disable=W0212
+        self.model, self.renderer_thread,
+        CreateMetricsForTimelineInteractionRecord)
+    ps = page_set.PageSet(file_path=os.path.dirname(__file__))
+    ps.AddPageWithDefaultRunNavigate('http://www.bar.com/')
+
+    results.WillMeasurePage(ps.pages[0])
+    metric.AddResults(results)
+    results.DidMeasurePage()
+
+    v = results.FindAllPageSpecificValuesNamed('LogicalName1-FakeSmoothMetric')
+    self.assertEquals(len(v), 1)
+    v = results.FindAllPageSpecificValuesNamed('LogicalName2-FakeLoadingMetric')
+    self.assertEquals(len(v), 1)
+
+
+class TimelineBasedMeasurementTest(
+      page_measurement_unittest_base.PageMeasurementUnitTestBase):
+  def setUp(self):
+    self._options = options_for_unittests.GetCopy()
+    self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
+
+  # Disabled due to flakiness: crbug.com/368386
+  @test.Disabled
+  def testTimelineBasedForSmoke(self):
+    ps = self.CreatePageSetFromFileInUnittestDataDir(
+        'interaction_enabled_page.html')
+    setattr(ps.pages[0], 'RunSmoothness', {'action': 'wait',
+                                        'javascript': 'window.animationDone'})
+    measurement = tbm_module.TimelineBasedMeasurement()
+    results = self.RunMeasurement(measurement, ps,
+                                  options=self._options)
+    self.assertEquals(0, len(results.failures))
+    v = results.FindAllPageSpecificValuesNamed('CenterAnimation-jank')
+    self.assertEquals(len(v), 1)
+    v = results.FindAllPageSpecificValuesNamed('DrawerAnimation-jank')
+    self.assertEquals(len(v), 1)
+
diff --git a/tools/telemetry/unittest_data/data/archive_blank.json b/tools/telemetry/unittest_data/data/archive_blank.json
deleted file mode 100644
index d6568ad..0000000
--- a/tools/telemetry/unittest_data/data/archive_blank.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-    "description": "Describes the Web Page Replay archives for a page set. Don't edit by hand! Use record_wpr for updating.", 
-    "archives": {
-        "archive_blank_000.wpr": [
-            "blank.html"
-        ]
-    }
-}
\ No newline at end of file
diff --git a/tools/telemetry/unittest_data/data/archive_blank_000.wpr.sha1 b/tools/telemetry/unittest_data/data/archive_blank_000.wpr.sha1
deleted file mode 100644
index badfd21..0000000
--- a/tools/telemetry/unittest_data/data/archive_blank_000.wpr.sha1
+++ /dev/null
@@ -1 +0,0 @@
-03a05fcccf9a3d354226d95b95363c74a06ec72a
\ No newline at end of file
diff --git a/tools/valgrind/chrome_tests.py b/tools/valgrind/chrome_tests.py
index 0947701..09d8485 100755
--- a/tools/valgrind/chrome_tests.py
+++ b/tools/valgrind/chrome_tests.py
@@ -375,6 +375,45 @@
   def TestPhoneNumber(self):
     return self.SimpleTest("phonenumber", "libphonenumber_unittests")
 
+  def TestMojoSystem(self):
+    return self.SimpleTest("mojo_system", "mojo_system_unittests")
+
+  def TestMojoPublicSystem(self):
+    return self.SimpleTest("mojo_public_system",
+                           "mojo_public_system_unittests")
+
+  def TestMojoPublicUtility(self):
+    return self.SimpleTest("mojo_public_utility",
+                           "mojo_public_unittests_unittests")
+
+  def TestMojoPublicBindings(self):
+    return self.SimpleTest("mojo_public_bindings",
+                           "mojo_public_bindings_unittests")
+
+  def TestMojoPublicEnv(self):
+    return self.SimpleTest("mojo_public_env",
+                           "mojo_public_environment_unittests")
+
+  def TestMojoPublicSysPerf(self):
+    return self.SimpleTest("mojo_public_sysperf",
+                           "mojo_public_system_perftests")
+
+  def TestMojoCommon(self):
+    return self.SimpleTest("mojo_common", "mojo_common_unittests")
+
+  def TestMojoAppsJS(self):
+    return self.SimpleTest("mojo_apps_js", "mojo_apps_js_unittests")
+
+  def TestMojoJS(self):
+    return self.SimpleTest("mojo_js", "mojo_js_unittests")
+
+  def TestMojoServiceManager(self):
+    return self.SimpleTest("mojo_service_manager",
+                           "mojo_service_manager_unittests")
+
+  def TestMojoViewManager(self):
+    return self.SimpleTest("mojo_view_manager", "mojo_view_manager_unittests")
+
   # Valgrind timeouts are in seconds.
   UI_VALGRIND_ARGS = ["--timeout=14400", "--trace_children", "--indirect"]
   # UI test timeouts are in milliseconds.
@@ -465,10 +504,11 @@
     # tests if we're low on memory.
     jobs = max(1, int(multiprocessing.cpu_count() * 0.3))
     script_cmd = ["python", script, "-v",
-                  "--run-singly",  # run a separate DumpRenderTree for each test
+                  # run a separate DumpRenderTree for each test
+                  "--batch-size=1",
                   "--fully-parallel",
                   "--child-processes=%d" % jobs,
-                  "--time-out-ms=200000",
+                  "--time-out-ms=800000",
                   "--no-retry-failures",  # retrying takes too much time
                   # http://crbug.com/176908: Don't launch a browser when done.
                   "--no-show-results",
@@ -520,9 +560,9 @@
     try:
       f = open(chunk_file)
       if f:
-        str = f.read()
-        if len(str):
-          chunk_num = int(str)
+        chunk_str = f.read()
+        if len(chunk_str):
+          chunk_num = int(chunk_str)
         # This should be enough so that we have a couple of complete runs
         # of test data stored in the archive (although note that when we loop
         # that we almost guaranteed won't be at the end of the test list)
@@ -605,6 +645,17 @@
     "libaddressinput_unittests": TestAddressInput,
     "phonenumber": TestPhoneNumber,
     "libphonenumber_unittests": TestPhoneNumber,
+    "mojo_system": TestMojoSystem,
+    "mojo_public_system": TestMojoPublicSystem,
+    "mojo_public_utility": TestMojoPublicUtility,
+    "mojo_public_bindings": TestMojoPublicBindings,
+    "mojo_public_env": TestMojoPublicEnv,
+    "mojo_public_sysperf": TestMojoPublicSysPerf,
+    "mojo_common": TestMojoCommon,
+    "mojo_apps_js": TestMojoAppsJS,
+    "mojo_js": TestMojoJS,
+    "mojo_service_manager": TestMojoServiceManager,
+    "mojo_view_manager": TestMojoViewManager,
   }
 
 
diff --git a/tools/valgrind/drmemory/suppressions.txt b/tools/valgrind/drmemory/suppressions.txt
index 689fa1b..cfbd525 100644
--- a/tools/valgrind/drmemory/suppressions.txt
+++ b/tools/valgrind/drmemory/suppressions.txt
@@ -455,3 +455,37 @@
 name=http://crbug.com/42043-gdi
 ...
 QuickTime.qts!*
+
+UNADDRESSABLE ACCESS
+name=IntentionalCrash
+*!content::*::*Crash*
+*!content::*::MaybeHandleDebugURL
+
+HANDLE LEAK
+name=http://crbug.com/371348
+system call NtCreateSection
+KERNELBASE.dll!CreateFileMappingW
+base.dll!base::SharedMemory::Create
+base.dll!base::SharedMemory::CreateAndMapAnonymous
+content.dll!content::ChildThread::AllocateSharedMemory
+content.dll!content::ChildSharedBitmapManager::AllocateSharedBitmap
+cc.dll!cc::ResourceProvider::CreateBitmap
+
+HANDLE LEAK
+name=http://crbug.com/371357
+system call NtCreateEvent
+KERNELBASE.dll!CreateEventExW
+KERNELBASE.dll!CreateEventW
+base.dll!base::WaitableEvent::WaitableEvent
+base.dll!base::MessagePumpDefault::MessagePumpDefault
+base.dll!base::MessageLoop::CreateMessagePumpForType
+base.dll!base::MessageLoop::MessageLoop
+
+HANDLE LEAK
+name=http://crbug.com/371368
+system call NtCreateNamedPipeFile
+KERNELBASE.dll!CreateNamedPipeW
+ipc.dll!IPC::Channel::ChannelImpl::CreatePipe
+ipc.dll!IPC::Channel::ChannelImpl::ChannelImpl
+ipc.dll!IPC::Channel::Channel
+ipc.dll!IPC::ChannelProxy::Context::CreateChannel
diff --git a/tools/valgrind/drmemory/suppressions_full.txt b/tools/valgrind/drmemory/suppressions_full.txt
index f2ba6a7..54e1cf6 100644
--- a/tools/valgrind/drmemory/suppressions_full.txt
+++ b/tools/valgrind/drmemory/suppressions_full.txt
@@ -1677,15 +1677,9 @@
 *!WebCore::OfflineAudioDestinationNode::offlineRender
 
 UNINITIALIZED READ
-name=bug_290451
+name=bug_364724
 *!base::MD5DigestToBase16
-*!content::WebKitTestRunner::CaptureDump
-*!content::WebKitTestRunner::testFinished
-*!WebTestRunner::TestRunner::completeNotifyDone
-*!WebTestRunner::TestRunner::notifyDone
-*!WebTestRunner::CppBoundClass::MemberCallback<>::run
-*!WebTestRunner::CppBoundClass::invoke
-*!WebTestRunner::CppNPObject::invoke
+*!content::WebKitTestRunner::CaptureDumpPixels
 
 UNINITIALIZED READ
 name=bug_298143
@@ -2101,3 +2095,25 @@
 name=bug_42043
 ...
 QuickTime.qts!*
+
+UNINITIALIZED READ
+name=bug_369141
+...
+*!WebCore::RenderLayerClipper::updateClipRects
+*!WebCore::RenderLayerClipper::parentClipRects
+*!WebCore::RenderLayerClipper::backgroundClipRect
+
+HANDLE LEAK
+name=bug_370178
+system call NtCreateEvent
+KERNELBASE.dll!CreateEventExW
+KERNELBASE.dll!CreateEventW
+base.dll!base::WaitableEvent::WaitableEvent
+gpu.dll!gpu::InProcessCommandBuffer::Initialize
+gl_in_process_context.dll!gpu::`anonymous namespace'::GLInProcessContextImpl::Initialize
+gl_in_process_context.dll!gpu::GLInProcessContext::CreateContext
+
+UNINITIALIZED READ
+name=bug_371844
+*!content::GamepadProvider::PadState::Match
+*!content::GamepadProvider::DoPoll
diff --git a/tools/valgrind/gtest_exclude/content_unittests.gtest_mac.txt b/tools/valgrind/gtest_exclude/content_unittests.gtest_mac.txt
index 1deed43..9f22169 100644
--- a/tools/valgrind/gtest_exclude/content_unittests.gtest_mac.txt
+++ b/tools/valgrind/gtest_exclude/content_unittests.gtest_mac.txt
@@ -38,9 +38,9 @@
 # http://crbug.com/247601
 FontSerializationTest.StyledFonts
 MacSandboxTest.FontLoadingTest
+VideoCaptureManagerTest.CreateAndAbort
 VideoCaptureManagerTest.ManipulateDeviceAndCheckCapabilities
 VideoCaptureManagerTest.StartDeviceAndGetDeviceFormatInUse
-VideoCaptureDeviceTest.FakeCapture
 
 # http://crbug.com/280583
 DesktopCaptureDeviceTest.ScreenResolutionChangeVariableResolution
@@ -51,4 +51,6 @@
 GamepadProviderTest.UserGesture
 
 # Flaky. http://crbug.com/365715
+AppCacheRequestHandlerTest.MainResource_Hit
 AppCacheRequestHandlerTest.MainResource_Miss
+AppCacheRequestHandlerTest.WorkerRequest
diff --git a/tools/valgrind/gtest_exclude/libaddressinput_unittests.gtest-drmemory_win32.txt b/tools/valgrind/gtest_exclude/libaddressinput_unittests.gtest-drmemory_win32.txt
new file mode 100644
index 0000000..f6c92e7
--- /dev/null
+++ b/tools/valgrind/gtest_exclude/libaddressinput_unittests.gtest-drmemory_win32.txt
@@ -0,0 +1,8 @@
+# fail in native run
+RuleTest.CanonicalizeSubKeyTest
+# fail on bot only and fail natively, cannot reproduce locally
+AddressValidatorTest.*
+CountryRulesAggregatorTest.ValidRulesets
+ExampleAddressValidatorTest.examples
+RetrieverTest.*
+FakeDownloaderTest.*
diff --git a/tools/valgrind/gtest_exclude/libphonenumber_unittests.gtest-drmemory_win32.txt b/tools/valgrind/gtest_exclude/libphonenumber_unittests.gtest-drmemory_win32.txt
new file mode 100644
index 0000000..4d2b324
--- /dev/null
+++ b/tools/valgrind/gtest_exclude/libphonenumber_unittests.gtest-drmemory_win32.txt
@@ -0,0 +1,3 @@
+# fail in native run
+PhoneNumberMatcherTest.MatchesWithStrictGroupingLeniency
+PhoneNumberMatcherTest.MatchesWithExactGroupingLeniency
diff --git a/tools/valgrind/gtest_exclude/media_unittests.gtest_mac.txt b/tools/valgrind/gtest_exclude/media_unittests.gtest_mac.txt
index 138864b..b49ec0c 100644
--- a/tools/valgrind/gtest_exclude/media_unittests.gtest_mac.txt
+++ b/tools/valgrind/gtest_exclude/media_unittests.gtest_mac.txt
@@ -1,3 +1,3 @@
-# Crashes under Valgrind on Mac, http://crbug.com/344108
+# Crashes under Valgrind on Mac, http://crbug.com/247601
 VideoCaptureDeviceTest.FakeCapture
 VideoCaptureDeviceTest.FakeCaptureVariableResolution
diff --git a/tools/valgrind/gtest_exclude/net_unittests.gtest-drmemory_win32.txt b/tools/valgrind/gtest_exclude/net_unittests.gtest-drmemory_win32.txt
index 4e82ac1..217bbb3 100644
--- a/tools/valgrind/gtest_exclude/net_unittests.gtest-drmemory_win32.txt
+++ b/tools/valgrind/gtest_exclude/net_unittests.gtest-drmemory_win32.txt
@@ -25,3 +25,6 @@
 
 # DrM-i#1465
 URLRequestTest.ResolveShortcutTest
+
+# Crashes, http://crbug.com/369840
+ProxyResolverV8TracingTest.MultipleResolvers
diff --git a/tools/valgrind/gtest_exclude/ui_unittests.gtest-memcheck.txt b/tools/valgrind/gtest_exclude/ui_unittests.gtest-memcheck.txt
index 9474d9f..32aba7b 100644
--- a/tools/valgrind/gtest_exclude/ui_unittests.gtest-memcheck.txt
+++ b/tools/valgrind/gtest_exclude/ui_unittests.gtest-memcheck.txt
@@ -1,2 +1,5 @@
 # http://crbug.com/222606
 RenderTextTest.DisplayRectShowsCursorLTR
+
+# http://crbug.com/370168
+TouchExplorationTest.*
diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt
index 107d6b6..f5b0ba6 100644
--- a/tools/valgrind/memcheck/suppressions.txt
+++ b/tools/valgrind/memcheck/suppressions.txt
@@ -5050,25 +5050,6 @@
    fun:_ZN3ash4test53FocusCyclerTest_CycleFocusThroughWindowWithPanes_Test8TestBodyEv
 }
 {
-   bug_238170a
-   Memcheck:Uninitialized
-   fun:_ZN7WebCore20ElementRuleCollector20collectMatchingRulesERKNS_12MatchRequestERNS_13StyleResolver9RuleRangeE
-   fun:_ZN7WebCore20ElementRuleCollector19hasAnyMatchingRulesEPNS_7RuleSetE
-}
-{
-   bug_238170b
-   Memcheck:Uninitialized
-   fun:_ZN7WebCore20ElementRuleCollector20collectMatchingRulesERKNS_12MatchRequestERNS_13StyleResolver9RuleRangeE
-   fun:_ZN7WebCore13StyleResolver16matchAuthorRulesERNS_20ElementRuleCollectorEb
-}
-{
-   bug_238170c
-   Memcheck:Uninitialized
-   fun:_ZN7WebCore23ReplaceSelectionCommand7doApplyEv
-   fun:_ZN7WebCore20CompositeEditCommand5applyEv
-   fun:_ZN7WebCore12applyCommandEN3WTF10PassRefPtrINS_20CompositeEditCommandEEE
-}
-{
    bug_238547
    Memcheck:Leak
    fun:_Znw*
@@ -5723,12 +5704,6 @@
    fun:_ZN7WebCore27WorkerGlobalScopeV8InternalL31createImageBitmapMethodCallbackERKN2v820FunctionCallbackInfoINS1_5ValueEEE
 }
 {
-   bug_290451
-   Memcheck:Uninitialized
-   fun:_ZN4base17MD5DigestToBase16ERKNS_9MD5DigestE
-   fun:_ZN7content16WebKitTestRunner11CaptureDumpEv
-}
-{
    bug_290559a
    Memcheck:Leak
    fun:_Znw*
@@ -6186,6 +6161,14 @@
    fun:_ZN7content17BlinkPlatformImpl9DoTimeoutEv
 }
 {
+   bug_350809
+   Memcheck:Uninitialized
+   fun:_ZN7WebCore23ReplaceSelectionCommand7doApplyEv
+   fun:_ZN7WebCore20CompositeEditCommand5applyEv
+   fun:_ZN7WebCore6Editor28replaceSelectionWithFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbbb
+   fun:_ZN7WebCore6Editor24replaceSelectionWithTextERKN3WTF6StringEbb
+}
+{
   bug_361594
   Memcheck:Uninitialized
   ...
@@ -6296,12 +6279,18 @@
    fun:event_base_loop
 }
 {
+   bug_364724b
+   Memcheck:Uninitialized
+   fun:_ZN4base17MD5DigestToBase16ERKNS_9MD5DigestE
+   fun:_ZN7content16WebKitTestRunner17CaptureDumpPixelsERK8SkBitmap
+}
+{
    bug_364821
    Memcheck:Leak
    fun:malloc
    fun:_ZN3WTF10fastMallocEm
-   fun:_ZN3WTF10RefCountedIN7WebCore14NewScriptStateEEnwEm
-   fun:_ZN7WebCore14NewScriptState6createEN2v86HandleINS1_7ContextEEEN3WTF10PassRefPtrINS_15DOMWrapperWorldEEE
+   fun:_ZN3WTF10RefCountedIN7WebCore11ScriptStateEEnwEm
+   fun:_ZN7WebCore11ScriptState6createEN2v86HandleINS1_7ContextEEEN3WTF10PassRefPtrINS_15DOMWrapperWorldEEE
    fun:_ZN7WebCore22WorkerScriptController25initializeContextIfNeededEv
    fun:_ZN7WebCore22WorkerScriptController8evaluateERKN3WTF6StringES4_RKNS1_12TextPositionEPNS_31WorkerGlobalScopeExecutionStateE
    fun:_ZN7WebCore22WorkerScriptController8evaluateERKNS_16ScriptSourceCodeEPN3WTF6RefPtrINS_10ErrorEventEEE
@@ -6380,3 +6369,54 @@
    fun:_ZN4mojo9RemotePtrINS_11ShellClientEE5resetENS_16ScopedHandleBaseINS_15InterfaceHandleIS1_EEEEPNS_5ShellEPNS_12ErrorHandlerEP15MojoAsyncWaiter
    fun:_ZN7content19MojoApplicationHost4InitEv
 }
+{
+   bug_369843
+   Memcheck:Leak
+   fun:_Znw*
+   fun:_ZN7content27ServiceWorkerContextWrapper12InitInternalERKN4base8FilePathEPNS1_19SequencedTaskRunnerEPN5quota17QuotaManagerProxyE
+}
+{
+   bug_370206
+   Memcheck:Leak
+   fun:malloc
+   fun:_ZN3WTF16DefaultAllocator15backingAllocateEm
+   fun:_ZN3WTF16DefaultAllocator13backingMallocIPN7WebCore14InlineIteratorEvEET_m
+   ...
+   fun:_ZN3WTF17HashMapTranslatorINS_18HashMapValueTraitsINS_10HashTraitsIPN7WebCore7BidiRun*
+}
+{
+   bug_370210
+   Memcheck:Leak
+   fun:_Znw*
+   fun:_ZN7WebCore20InternalsGeolocation24setGeolocationClientMockERNS_9InternalsEPNS_8DocumentE
+   fun:_ZN7WebCore19InternalsV8InternalL30setGeolocationClientMockMethodERKN2v820FunctionCallbackInfoINS1_5ValueEEE
+   fun:_ZN7WebCore19InternalsV8InternalL38setGeolocationClientMockMethodCallbackERKN2v820FunctionCallbackInfoINS1_5ValueEEE
+   fun:_ZN2v88internal25FunctionCallbackArguments4CallEPFvRKNS_20FunctionCallbackInfoINS_5ValueEEEE
+}
+{
+   bug_370327
+   Memcheck:Leak
+   fun:_Znw*
+   fun:_ZN2v88internal6Parser12ParseProgramEv
+   fun:_ZN2v88internal6Parser5ParseEv
+   fun:_ZN2v88internal6Parser5ParseEPNS0_15CompilationInfoEb
+   fun:_ZN2v88internalL15CompileToplevelEPNS0_15CompilationInfoE*
+   fun:_ZN2v88internal8Compiler13CompileScriptENS0_6HandleINS0_6StringEEENS2_INS0_6ObjectEEEiibNS2_INS0_7Context*
+   fun:_ZN2v814ScriptCompiler14CompileUnboundEPNS_7IsolateEPNS0_6SourceENS0_14CompileOptionsE
+}
+{
+  bug_371844
+  Memcheck:Uninitialized
+  fun:bcmp
+  fun:_ZNK7content15GamepadProvider8PadState5MatchERKN5blink10WebGamepadE
+  fun:_ZN7content15GamepadProvider6DoPollEv
+}
+{
+   bug_371860
+   Memcheck:Leak
+   fun:_Znw*
+   ...
+   fun:_ZN8feedback20FeedbackUploaderTestC1Ev
+   fun:_ZN8feedback*FeedbackUploaderTest*
+   fun:_ZN7testing8internal15TestFactoryImplIN8feedback*
+}
diff --git a/tools/valgrind/memcheck/suppressions_mac.txt b/tools/valgrind/memcheck/suppressions_mac.txt
index 098c7b9..ea4e2a0 100644
--- a/tools/valgrind/memcheck/suppressions_mac.txt
+++ b/tools/valgrind/memcheck/suppressions_mac.txt
@@ -2385,3 +2385,21 @@
    fun:_ZN4base9TestSuite3RunEv
    fun:_ZN7content17UnitTestTestSuite3RunEv
 }
+{
+   bug_369597
+   Memcheck:Leak
+   fun:malloc_zone_malloc
+   ...
+   fun:ImageProviderCopyImageBlockSetCallback
+   fun:CGImageProviderCopyImageBlockSet
+   fun:img_blocks_create
+   fun:img_data_lock
+   fun:CGSImageDataLock
+   fun:ripc_AcquireImage
+   fun:ripc_DrawImage
+   fun:CGContextDrawImage
+   ...
+   fun:_ZN12_GLOBAL__N_143NSImageOrNSImageRepToSkBitmapWithColorSpaceEP7NSImageP10NSImageRep7_NSSizebP12CGColorSpace
+   fun:_ZN3gfx31NSImageToSkBitmapWithColorSpaceEP7NSImagebP12CGColorSpace
+   fun:_ZNK2ui9Clipboard9ReadImageENS_13ClipboardTypeE
+}
diff --git a/tools/valgrind/tsan_v2/suppressions.txt b/tools/valgrind/tsan_v2/suppressions.txt
index 1f8b185..f4cae72 100644
--- a/tools/valgrind/tsan_v2/suppressions.txt
+++ b/tools/valgrind/tsan_v2/suppressions.txt
@@ -253,3 +253,12 @@
 
 # https://code.google.com/p/v8/issues/detail?id=3143
 race:v8::internal::FLAG_track_double_fields
+
+# http://crbug.com/370244
+race:cc::RenderingStatsInstrumentation::AccumulateAndClearImplThreadStats
+
+# https://crbug.com/369257
+# TODO(mtklein): annotate properly and remove suppressions.
+race:SandboxIPCHandler::HandleFontMatchRequest
+race:SkFontConfigInterfaceDirect::matchFamilyName
+race:SkFontConfigInterface::GetSingletonDirectInterface
diff --git a/ui/accessibility/accessibility.target.darwin-arm.mk b/ui/accessibility/accessibility.target.darwin-arm.mk
index e0b3d18..297a8a3 100644
--- a/ui/accessibility/accessibility.target.darwin-arm.mk
+++ b/ui/accessibility/accessibility.target.darwin-arm.mk
@@ -50,7 +50,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -175,7 +169,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -224,11 +217,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/accessibility/accessibility.target.darwin-arm64.mk b/ui/accessibility/accessibility.target.darwin-arm64.mk
index 6549bc5..b785263 100644
--- a/ui/accessibility/accessibility.target.darwin-arm64.mk
+++ b/ui/accessibility/accessibility.target.darwin-arm64.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -215,11 +210,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/accessibility/accessibility.target.darwin-mips.mk b/ui/accessibility/accessibility.target.darwin-mips.mk
index 397a231..340443d 100644
--- a/ui/accessibility/accessibility.target.darwin-mips.mk
+++ b/ui/accessibility/accessibility.target.darwin-mips.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -222,11 +217,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/accessibility/accessibility.target.darwin-x86.mk b/ui/accessibility/accessibility.target.darwin-x86.mk
index 8980f55..b3e1d22 100644
--- a/ui/accessibility/accessibility.target.darwin-x86.mk
+++ b/ui/accessibility/accessibility.target.darwin-x86.mk
@@ -52,7 +52,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -177,7 +171,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -225,11 +218,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/accessibility/accessibility.target.darwin-x86_64.mk b/ui/accessibility/accessibility.target.darwin-x86_64.mk
index 7fe8024..c307c15 100644
--- a/ui/accessibility/accessibility.target.darwin-x86_64.mk
+++ b/ui/accessibility/accessibility.target.darwin-x86_64.mk
@@ -52,7 +52,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -177,7 +171,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -225,11 +218,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/accessibility/accessibility.target.linux-arm.mk b/ui/accessibility/accessibility.target.linux-arm.mk
index e0b3d18..297a8a3 100644
--- a/ui/accessibility/accessibility.target.linux-arm.mk
+++ b/ui/accessibility/accessibility.target.linux-arm.mk
@@ -50,7 +50,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -175,7 +169,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -224,11 +217,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/accessibility/accessibility.target.linux-arm64.mk b/ui/accessibility/accessibility.target.linux-arm64.mk
index 6549bc5..b785263 100644
--- a/ui/accessibility/accessibility.target.linux-arm64.mk
+++ b/ui/accessibility/accessibility.target.linux-arm64.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -215,11 +210,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/accessibility/accessibility.target.linux-mips.mk b/ui/accessibility/accessibility.target.linux-mips.mk
index 397a231..340443d 100644
--- a/ui/accessibility/accessibility.target.linux-mips.mk
+++ b/ui/accessibility/accessibility.target.linux-mips.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -222,11 +217,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/accessibility/accessibility.target.linux-x86.mk b/ui/accessibility/accessibility.target.linux-x86.mk
index 8980f55..b3e1d22 100644
--- a/ui/accessibility/accessibility.target.linux-x86.mk
+++ b/ui/accessibility/accessibility.target.linux-x86.mk
@@ -52,7 +52,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -177,7 +171,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -225,11 +218,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/accessibility/accessibility.target.linux-x86_64.mk b/ui/accessibility/accessibility.target.linux-x86_64.mk
index 7fe8024..c307c15 100644
--- a/ui/accessibility/accessibility.target.linux-x86_64.mk
+++ b/ui/accessibility/accessibility.target.linux-x86_64.mk
@@ -52,7 +52,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -177,7 +171,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -225,11 +218,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/accessibility/ax_enums.idl b/ui/accessibility/ax_enums.idl
index ea46143..1a3d978 100644
--- a/ui/accessibility/ax_enums.idl
+++ b/ui/accessibility/ax_enums.idl
@@ -73,6 +73,7 @@
     document,
     drawer,
     editable_text,
+    embedded_object,
     footer,
     form,
     grid,
diff --git a/ui/accessibility/ax_gen.target.darwin-arm.mk b/ui/accessibility/ax_gen.target.darwin-arm.mk
index 96328b1..34deebc 100644
--- a/ui/accessibility/ax_gen.target.darwin-arm.mk
+++ b/ui/accessibility/ax_gen.target.darwin-arm.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "genapi_bundle":
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +32,7 @@
 ### Generated for rule "ui_accessibility_accessibility_gyp_ax_gen_target_genapi_idl":
 # "{'inputs': ['../../tools/json_schema_compiler/cc_generator.py', '../../tools/json_schema_compiler/code.py', '../../tools/json_schema_compiler/compiler.py', '../../tools/json_schema_compiler/cpp_generator.py', '../../tools/json_schema_compiler/cpp_type_generator.py', '../../tools/json_schema_compiler/cpp_util.py', '../../tools/json_schema_compiler/h_generator.py', '../../tools/json_schema_compiler/idl_schema.py', '../../tools/json_schema_compiler/model.py', '../../tools/json_schema_compiler/util.cc', '../../tools/json_schema_compiler/util.h', '../../tools/json_schema_compiler/util_cc_helper.py'], 'process_outputs_as_sources': '1', 'extension': 'idl', 'msvs_external_rule': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.cc', '$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.h'], 'rule_name': 'genapi_idl', 'rule_sources': ['ax_enums.idl'], 'action': ['python', '../../tools/json_schema_compiler/compiler.py', '$(RULE_SOURCES)', '--root=../..', '--destdir=$(gyp_shared_intermediate_dir)', '--namespace=', '--generator=cpp', '--impl-dir=chrome/browser/extensions/api'], 'message': 'Generating C++ code from $(RULE_SOURCES) IDL files'}":
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -86,7 +88,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -173,7 +174,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/accessibility/ax_gen.target.darwin-arm64.mk b/ui/accessibility/ax_gen.target.darwin-arm64.mk
index 61167d6..bd9d5bc 100644
--- a/ui/accessibility/ax_gen.target.darwin-arm64.mk
+++ b/ui/accessibility/ax_gen.target.darwin-arm64.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "genapi_bundle":
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +32,7 @@
 ### Generated for rule "ui_accessibility_accessibility_gyp_ax_gen_target_genapi_idl":
 # "{'inputs': ['../../tools/json_schema_compiler/cc_generator.py', '../../tools/json_schema_compiler/code.py', '../../tools/json_schema_compiler/compiler.py', '../../tools/json_schema_compiler/cpp_generator.py', '../../tools/json_schema_compiler/cpp_type_generator.py', '../../tools/json_schema_compiler/cpp_util.py', '../../tools/json_schema_compiler/h_generator.py', '../../tools/json_schema_compiler/idl_schema.py', '../../tools/json_schema_compiler/model.py', '../../tools/json_schema_compiler/util.cc', '../../tools/json_schema_compiler/util.h', '../../tools/json_schema_compiler/util_cc_helper.py'], 'process_outputs_as_sources': '1', 'extension': 'idl', 'msvs_external_rule': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.cc', '$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.h'], 'rule_name': 'genapi_idl', 'rule_sources': ['ax_enums.idl'], 'action': ['python', '../../tools/json_schema_compiler/compiler.py', '$(RULE_SOURCES)', '--root=../..', '--destdir=$(gyp_shared_intermediate_dir)', '--namespace=', '--generator=cpp', '--impl-dir=chrome/browser/extensions/api'], 'message': 'Generating C++ code from $(RULE_SOURCES) IDL files'}":
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/accessibility/ax_gen.target.darwin-mips.mk b/ui/accessibility/ax_gen.target.darwin-mips.mk
index 82a261f..b119309 100644
--- a/ui/accessibility/ax_gen.target.darwin-mips.mk
+++ b/ui/accessibility/ax_gen.target.darwin-mips.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "genapi_bundle":
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +32,7 @@
 ### Generated for rule "ui_accessibility_accessibility_gyp_ax_gen_target_genapi_idl":
 # "{'inputs': ['../../tools/json_schema_compiler/cc_generator.py', '../../tools/json_schema_compiler/code.py', '../../tools/json_schema_compiler/compiler.py', '../../tools/json_schema_compiler/cpp_generator.py', '../../tools/json_schema_compiler/cpp_type_generator.py', '../../tools/json_schema_compiler/cpp_util.py', '../../tools/json_schema_compiler/h_generator.py', '../../tools/json_schema_compiler/idl_schema.py', '../../tools/json_schema_compiler/model.py', '../../tools/json_schema_compiler/util.cc', '../../tools/json_schema_compiler/util.h', '../../tools/json_schema_compiler/util_cc_helper.py'], 'process_outputs_as_sources': '1', 'extension': 'idl', 'msvs_external_rule': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.cc', '$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.h'], 'rule_name': 'genapi_idl', 'rule_sources': ['ax_enums.idl'], 'action': ['python', '../../tools/json_schema_compiler/compiler.py', '$(RULE_SOURCES)', '--root=../..', '--destdir=$(gyp_shared_intermediate_dir)', '--namespace=', '--generator=cpp', '--impl-dir=chrome/browser/extensions/api'], 'message': 'Generating C++ code from $(RULE_SOURCES) IDL files'}":
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/accessibility/ax_gen.target.darwin-x86.mk b/ui/accessibility/ax_gen.target.darwin-x86.mk
index 083a186..78d9c08 100644
--- a/ui/accessibility/ax_gen.target.darwin-x86.mk
+++ b/ui/accessibility/ax_gen.target.darwin-x86.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "genapi_bundle":
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +32,7 @@
 ### Generated for rule "ui_accessibility_accessibility_gyp_ax_gen_target_genapi_idl":
 # "{'inputs': ['../../tools/json_schema_compiler/cc_generator.py', '../../tools/json_schema_compiler/code.py', '../../tools/json_schema_compiler/compiler.py', '../../tools/json_schema_compiler/cpp_generator.py', '../../tools/json_schema_compiler/cpp_type_generator.py', '../../tools/json_schema_compiler/cpp_util.py', '../../tools/json_schema_compiler/h_generator.py', '../../tools/json_schema_compiler/idl_schema.py', '../../tools/json_schema_compiler/model.py', '../../tools/json_schema_compiler/util.cc', '../../tools/json_schema_compiler/util.h', '../../tools/json_schema_compiler/util_cc_helper.py'], 'process_outputs_as_sources': '1', 'extension': 'idl', 'msvs_external_rule': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.cc', '$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.h'], 'rule_name': 'genapi_idl', 'rule_sources': ['ax_enums.idl'], 'action': ['python', '../../tools/json_schema_compiler/compiler.py', '$(RULE_SOURCES)', '--root=../..', '--destdir=$(gyp_shared_intermediate_dir)', '--namespace=', '--generator=cpp', '--impl-dir=chrome/browser/extensions/api'], 'message': 'Generating C++ code from $(RULE_SOURCES) IDL files'}":
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -88,7 +90,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -175,7 +176,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/accessibility/ax_gen.target.darwin-x86_64.mk b/ui/accessibility/ax_gen.target.darwin-x86_64.mk
index 4870072..aa0333f 100644
--- a/ui/accessibility/ax_gen.target.darwin-x86_64.mk
+++ b/ui/accessibility/ax_gen.target.darwin-x86_64.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "genapi_bundle":
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +32,7 @@
 ### Generated for rule "ui_accessibility_accessibility_gyp_ax_gen_target_genapi_idl":
 # "{'inputs': ['../../tools/json_schema_compiler/cc_generator.py', '../../tools/json_schema_compiler/code.py', '../../tools/json_schema_compiler/compiler.py', '../../tools/json_schema_compiler/cpp_generator.py', '../../tools/json_schema_compiler/cpp_type_generator.py', '../../tools/json_schema_compiler/cpp_util.py', '../../tools/json_schema_compiler/h_generator.py', '../../tools/json_schema_compiler/idl_schema.py', '../../tools/json_schema_compiler/model.py', '../../tools/json_schema_compiler/util.cc', '../../tools/json_schema_compiler/util.h', '../../tools/json_schema_compiler/util_cc_helper.py'], 'process_outputs_as_sources': '1', 'extension': 'idl', 'msvs_external_rule': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.cc', '$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.h'], 'rule_name': 'genapi_idl', 'rule_sources': ['ax_enums.idl'], 'action': ['python', '../../tools/json_schema_compiler/compiler.py', '$(RULE_SOURCES)', '--root=../..', '--destdir=$(gyp_shared_intermediate_dir)', '--namespace=', '--generator=cpp', '--impl-dir=chrome/browser/extensions/api'], 'message': 'Generating C++ code from $(RULE_SOURCES) IDL files'}":
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -88,7 +90,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -175,7 +176,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/accessibility/ax_gen.target.linux-arm.mk b/ui/accessibility/ax_gen.target.linux-arm.mk
index 96328b1..34deebc 100644
--- a/ui/accessibility/ax_gen.target.linux-arm.mk
+++ b/ui/accessibility/ax_gen.target.linux-arm.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "genapi_bundle":
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +32,7 @@
 ### Generated for rule "ui_accessibility_accessibility_gyp_ax_gen_target_genapi_idl":
 # "{'inputs': ['../../tools/json_schema_compiler/cc_generator.py', '../../tools/json_schema_compiler/code.py', '../../tools/json_schema_compiler/compiler.py', '../../tools/json_schema_compiler/cpp_generator.py', '../../tools/json_schema_compiler/cpp_type_generator.py', '../../tools/json_schema_compiler/cpp_util.py', '../../tools/json_schema_compiler/h_generator.py', '../../tools/json_schema_compiler/idl_schema.py', '../../tools/json_schema_compiler/model.py', '../../tools/json_schema_compiler/util.cc', '../../tools/json_schema_compiler/util.h', '../../tools/json_schema_compiler/util_cc_helper.py'], 'process_outputs_as_sources': '1', 'extension': 'idl', 'msvs_external_rule': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.cc', '$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.h'], 'rule_name': 'genapi_idl', 'rule_sources': ['ax_enums.idl'], 'action': ['python', '../../tools/json_schema_compiler/compiler.py', '$(RULE_SOURCES)', '--root=../..', '--destdir=$(gyp_shared_intermediate_dir)', '--namespace=', '--generator=cpp', '--impl-dir=chrome/browser/extensions/api'], 'message': 'Generating C++ code from $(RULE_SOURCES) IDL files'}":
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -86,7 +88,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -173,7 +174,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/accessibility/ax_gen.target.linux-arm64.mk b/ui/accessibility/ax_gen.target.linux-arm64.mk
index 61167d6..bd9d5bc 100644
--- a/ui/accessibility/ax_gen.target.linux-arm64.mk
+++ b/ui/accessibility/ax_gen.target.linux-arm64.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "genapi_bundle":
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +32,7 @@
 ### Generated for rule "ui_accessibility_accessibility_gyp_ax_gen_target_genapi_idl":
 # "{'inputs': ['../../tools/json_schema_compiler/cc_generator.py', '../../tools/json_schema_compiler/code.py', '../../tools/json_schema_compiler/compiler.py', '../../tools/json_schema_compiler/cpp_generator.py', '../../tools/json_schema_compiler/cpp_type_generator.py', '../../tools/json_schema_compiler/cpp_util.py', '../../tools/json_schema_compiler/h_generator.py', '../../tools/json_schema_compiler/idl_schema.py', '../../tools/json_schema_compiler/model.py', '../../tools/json_schema_compiler/util.cc', '../../tools/json_schema_compiler/util.h', '../../tools/json_schema_compiler/util_cc_helper.py'], 'process_outputs_as_sources': '1', 'extension': 'idl', 'msvs_external_rule': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.cc', '$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.h'], 'rule_name': 'genapi_idl', 'rule_sources': ['ax_enums.idl'], 'action': ['python', '../../tools/json_schema_compiler/compiler.py', '$(RULE_SOURCES)', '--root=../..', '--destdir=$(gyp_shared_intermediate_dir)', '--namespace=', '--generator=cpp', '--impl-dir=chrome/browser/extensions/api'], 'message': 'Generating C++ code from $(RULE_SOURCES) IDL files'}":
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/accessibility/ax_gen.target.linux-mips.mk b/ui/accessibility/ax_gen.target.linux-mips.mk
index 82a261f..b119309 100644
--- a/ui/accessibility/ax_gen.target.linux-mips.mk
+++ b/ui/accessibility/ax_gen.target.linux-mips.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "genapi_bundle":
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +32,7 @@
 ### Generated for rule "ui_accessibility_accessibility_gyp_ax_gen_target_genapi_idl":
 # "{'inputs': ['../../tools/json_schema_compiler/cc_generator.py', '../../tools/json_schema_compiler/code.py', '../../tools/json_schema_compiler/compiler.py', '../../tools/json_schema_compiler/cpp_generator.py', '../../tools/json_schema_compiler/cpp_type_generator.py', '../../tools/json_schema_compiler/cpp_util.py', '../../tools/json_schema_compiler/h_generator.py', '../../tools/json_schema_compiler/idl_schema.py', '../../tools/json_schema_compiler/model.py', '../../tools/json_schema_compiler/util.cc', '../../tools/json_schema_compiler/util.h', '../../tools/json_schema_compiler/util_cc_helper.py'], 'process_outputs_as_sources': '1', 'extension': 'idl', 'msvs_external_rule': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.cc', '$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.h'], 'rule_name': 'genapi_idl', 'rule_sources': ['ax_enums.idl'], 'action': ['python', '../../tools/json_schema_compiler/compiler.py', '$(RULE_SOURCES)', '--root=../..', '--destdir=$(gyp_shared_intermediate_dir)', '--namespace=', '--generator=cpp', '--impl-dir=chrome/browser/extensions/api'], 'message': 'Generating C++ code from $(RULE_SOURCES) IDL files'}":
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/accessibility/ax_gen.target.linux-x86.mk b/ui/accessibility/ax_gen.target.linux-x86.mk
index 083a186..78d9c08 100644
--- a/ui/accessibility/ax_gen.target.linux-x86.mk
+++ b/ui/accessibility/ax_gen.target.linux-x86.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "genapi_bundle":
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +32,7 @@
 ### Generated for rule "ui_accessibility_accessibility_gyp_ax_gen_target_genapi_idl":
 # "{'inputs': ['../../tools/json_schema_compiler/cc_generator.py', '../../tools/json_schema_compiler/code.py', '../../tools/json_schema_compiler/compiler.py', '../../tools/json_schema_compiler/cpp_generator.py', '../../tools/json_schema_compiler/cpp_type_generator.py', '../../tools/json_schema_compiler/cpp_util.py', '../../tools/json_schema_compiler/h_generator.py', '../../tools/json_schema_compiler/idl_schema.py', '../../tools/json_schema_compiler/model.py', '../../tools/json_schema_compiler/util.cc', '../../tools/json_schema_compiler/util.h', '../../tools/json_schema_compiler/util_cc_helper.py'], 'process_outputs_as_sources': '1', 'extension': 'idl', 'msvs_external_rule': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.cc', '$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.h'], 'rule_name': 'genapi_idl', 'rule_sources': ['ax_enums.idl'], 'action': ['python', '../../tools/json_schema_compiler/compiler.py', '$(RULE_SOURCES)', '--root=../..', '--destdir=$(gyp_shared_intermediate_dir)', '--namespace=', '--generator=cpp', '--impl-dir=chrome/browser/extensions/api'], 'message': 'Generating C++ code from $(RULE_SOURCES) IDL files'}":
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -88,7 +90,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -175,7 +176,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/accessibility/ax_gen.target.linux-x86_64.mk b/ui/accessibility/ax_gen.target.linux-x86_64.mk
index 4870072..aa0333f 100644
--- a/ui/accessibility/ax_gen.target.linux-x86_64.mk
+++ b/ui/accessibility/ax_gen.target.linux-x86_64.mk
@@ -15,6 +15,7 @@
 
 ### Rules for action "genapi_bundle":
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/generated_api.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -31,6 +32,7 @@
 ### Generated for rule "ui_accessibility_accessibility_gyp_ax_gen_target_genapi_idl":
 # "{'inputs': ['../../tools/json_schema_compiler/cc_generator.py', '../../tools/json_schema_compiler/code.py', '../../tools/json_schema_compiler/compiler.py', '../../tools/json_schema_compiler/cpp_generator.py', '../../tools/json_schema_compiler/cpp_type_generator.py', '../../tools/json_schema_compiler/cpp_util.py', '../../tools/json_schema_compiler/h_generator.py', '../../tools/json_schema_compiler/idl_schema.py', '../../tools/json_schema_compiler/model.py', '../../tools/json_schema_compiler/util.cc', '../../tools/json_schema_compiler/util.h', '../../tools/json_schema_compiler/util_cc_helper.py'], 'process_outputs_as_sources': '1', 'extension': 'idl', 'msvs_external_rule': '1', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.cc', '$(gyp_shared_intermediate_dir)/ui/accessibility/%(INPUT_ROOT)s.h'], 'rule_name': 'genapi_idl', 'rule_sources': ['ax_enums.idl'], 'action': ['python', '../../tools/json_schema_compiler/compiler.py', '$(RULE_SOURCES)', '--root=../..', '--destdir=$(gyp_shared_intermediate_dir)', '--namespace=', '--generator=cpp', '--impl-dir=chrome/browser/extensions/api'], 'message': 'Generating C++ code from $(RULE_SOURCES) IDL files'}":
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/accessibility/ax_enums.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -88,7 +90,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -175,7 +176,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/accessibility/ax_tree_serializer.h b/ui/accessibility/ax_tree_serializer.h
index 546f95f..f1cbfce 100644
--- a/ui/accessibility/ax_tree_serializer.h
+++ b/ui/accessibility/ax_tree_serializer.h
@@ -417,8 +417,13 @@
   out_update->nodes.push_back(AXNodeData());
   AXNodeData* serialized_node = &out_update->nodes.back();
   tree_->SerializeNode(node, serialized_node);
-  if (serialized_node->id == client_root_->id)
+  // TODO(dmazzoni/dtseng): Make the serializer not depend on roles to identify
+  // the root.
+  if (serialized_node->id == client_root_->id &&
+      (serialized_node->role != AX_ROLE_ROOT_WEB_AREA &&
+       serialized_node->role != AX_ROLE_DESKTOP)) {
     serialized_node->role = AX_ROLE_ROOT_WEB_AREA;
+  }
   serialized_node->child_ids.clear();
 
   // Iterate over the children, make note of the ones that are new
diff --git a/ui/android/bitmap_format_java.target.darwin-arm.mk b/ui/android/bitmap_format_java.target.darwin-arm.mk
index 2936157..809f315 100644
--- a/ui/android/bitmap_format_java.target.darwin-arm.mk
+++ b/ui/android/bitmap_format_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_bitmap_format_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../gfx/android/bitmap_config_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/BitmapFormat.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/android/bitmap_format_java.target.darwin-arm64.mk b/ui/android/bitmap_format_java.target.darwin-arm64.mk
index acc7926..06573a8 100644
--- a/ui/android/bitmap_format_java.target.darwin-arm64.mk
+++ b/ui/android/bitmap_format_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_bitmap_format_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../gfx/android/bitmap_config_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/BitmapFormat.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/android/bitmap_format_java.target.darwin-mips.mk b/ui/android/bitmap_format_java.target.darwin-mips.mk
index f288e01..8f07c99 100644
--- a/ui/android/bitmap_format_java.target.darwin-mips.mk
+++ b/ui/android/bitmap_format_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_bitmap_format_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../gfx/android/bitmap_config_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/BitmapFormat.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/android/bitmap_format_java.target.darwin-x86.mk b/ui/android/bitmap_format_java.target.darwin-x86.mk
index 53edddc..391f010 100644
--- a/ui/android/bitmap_format_java.target.darwin-x86.mk
+++ b/ui/android/bitmap_format_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_bitmap_format_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../gfx/android/bitmap_config_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/BitmapFormat.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/android/bitmap_format_java.target.darwin-x86_64.mk b/ui/android/bitmap_format_java.target.darwin-x86_64.mk
index ea3e7e3..65b86e6 100644
--- a/ui/android/bitmap_format_java.target.darwin-x86_64.mk
+++ b/ui/android/bitmap_format_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_bitmap_format_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../gfx/android/bitmap_config_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/BitmapFormat.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/android/bitmap_format_java.target.linux-arm.mk b/ui/android/bitmap_format_java.target.linux-arm.mk
index 2936157..809f315 100644
--- a/ui/android/bitmap_format_java.target.linux-arm.mk
+++ b/ui/android/bitmap_format_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_bitmap_format_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../gfx/android/bitmap_config_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/BitmapFormat.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/android/bitmap_format_java.target.linux-arm64.mk b/ui/android/bitmap_format_java.target.linux-arm64.mk
index acc7926..06573a8 100644
--- a/ui/android/bitmap_format_java.target.linux-arm64.mk
+++ b/ui/android/bitmap_format_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_bitmap_format_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../gfx/android/bitmap_config_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/BitmapFormat.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/android/bitmap_format_java.target.linux-mips.mk b/ui/android/bitmap_format_java.target.linux-mips.mk
index f288e01..8f07c99 100644
--- a/ui/android/bitmap_format_java.target.linux-mips.mk
+++ b/ui/android/bitmap_format_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_bitmap_format_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../gfx/android/bitmap_config_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/BitmapFormat.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/android/bitmap_format_java.target.linux-x86.mk b/ui/android/bitmap_format_java.target.linux-x86.mk
index 53edddc..391f010 100644
--- a/ui/android/bitmap_format_java.target.linux-x86.mk
+++ b/ui/android/bitmap_format_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_bitmap_format_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../gfx/android/bitmap_config_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/BitmapFormat.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/android/bitmap_format_java.target.linux-x86_64.mk b/ui/android/bitmap_format_java.target.linux-x86_64.mk
index ea3e7e3..65b86e6 100644
--- a/ui/android/bitmap_format_java.target.linux-x86_64.mk
+++ b/ui/android/bitmap_format_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_bitmap_format_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../gfx/android/bitmap_config_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/BitmapFormat.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/gfx/BitmapFormat.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/android/java/res/drawable-hdpi/autofill_popup_background_down.9.png b/ui/android/java/res/drawable-hdpi/autofill_popup_background_down.9.png
deleted file mode 100644
index 62478fc..0000000
--- a/ui/android/java/res/drawable-hdpi/autofill_popup_background_down.9.png
+++ /dev/null
Binary files differ
diff --git a/ui/android/java/res/drawable-hdpi/autofill_popup_background_up.9.png b/ui/android/java/res/drawable-hdpi/autofill_popup_background_up.9.png
deleted file mode 100644
index 290f526..0000000
--- a/ui/android/java/res/drawable-hdpi/autofill_popup_background_up.9.png
+++ /dev/null
Binary files differ
diff --git a/ui/android/java/res/drawable-xhdpi/autofill_popup_background_down.9.png b/ui/android/java/res/drawable-xhdpi/autofill_popup_background_down.9.png
deleted file mode 100644
index ab4d02c..0000000
--- a/ui/android/java/res/drawable-xhdpi/autofill_popup_background_down.9.png
+++ /dev/null
Binary files differ
diff --git a/ui/android/java/res/drawable-xhdpi/autofill_popup_background_up.9.png b/ui/android/java/res/drawable-xhdpi/autofill_popup_background_up.9.png
deleted file mode 100644
index cf3f9e6..0000000
--- a/ui/android/java/res/drawable-xhdpi/autofill_popup_background_up.9.png
+++ /dev/null
Binary files differ
diff --git a/ui/android/java/res/drawable/autofill_popup_background.xml b/ui/android/java/res/drawable/autofill_popup_background.xml
deleted file mode 100644
index 0f8d38b..0000000
--- a/ui/android/java/res/drawable/autofill_popup_background.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- Copyright 2013 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_above_anchor="true"
-        android:drawable="@drawable/autofill_popup_background_up" />
-    <item android:drawable="@drawable/autofill_popup_background_down" />
-</selector>
\ No newline at end of file
diff --git a/ui/android/java/res/drawable/autofill_popup_background_down.9.png b/ui/android/java/res/drawable/autofill_popup_background_down.9.png
deleted file mode 100644
index 0fb3b87..0000000
--- a/ui/android/java/res/drawable/autofill_popup_background_down.9.png
+++ /dev/null
Binary files differ
diff --git a/ui/android/java/res/drawable/autofill_popup_background_up.9.png b/ui/android/java/res/drawable/autofill_popup_background_up.9.png
deleted file mode 100644
index 4ab1786..0000000
--- a/ui/android/java/res/drawable/autofill_popup_background_up.9.png
+++ /dev/null
Binary files differ
diff --git a/ui/android/java/res/drawable/dropdown_popup_background.xml b/ui/android/java/res/drawable/dropdown_popup_background.xml
new file mode 100644
index 0000000..71b5271
--- /dev/null
+++ b/ui/android/java/res/drawable/dropdown_popup_background.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_above_anchor="true"
+        android:drawable="@drawable/dropdown_popup_background_up" />
+    <item android:drawable="@drawable/dropdown_popup_background_down" />
+</selector>
\ No newline at end of file
diff --git a/ui/android/java/res/layout/autofill_text.xml b/ui/android/java/res/layout/autofill_text.xml
deleted file mode 100644
index bab3d77..0000000
--- a/ui/android/java/res/layout/autofill_text.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2013 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/autofill_menu_text"
-    android:orientation="vertical"
-    android:gravity="center_vertical">
-
-    <TextView android:id="@+id/autofill_label"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="10dp"
-        android:layout_marginEnd="10dp"
-        android:ellipsize="end"
-        android:singleLine="true"
-        android:textSize="18sp"
-        android:includeFontPadding="false"/>
-    <TextView android:id="@+id/autofill_sublabel"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="10dp"
-        android:layout_marginEnd="10dp"
-        android:textSize="14sp"
-        android:textColor="#8b8b8b"
-        android:ellipsize="end"
-        android:singleLine="true"
-        android:includeFontPadding="false"/>
-</LinearLayout>
diff --git a/ui/android/java/res/layout/dropdown_item.xml b/ui/android/java/res/layout/dropdown_item.xml
new file mode 100644
index 0000000..3f16a21
--- /dev/null
+++ b/ui/android/java/res/layout/dropdown_item.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/dropdown_menu_text"
+    android:orientation="vertical"
+    android:gravity="center_vertical">
+
+    <TextView android:id="@+id/dropdown_label"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="10dp"
+        android:layout_marginEnd="10dp"
+        android:ellipsize="end"
+        android:singleLine="true"
+        android:textSize="18sp"
+        android:includeFontPadding="false"/>
+    <TextView android:id="@+id/dropdown_sublabel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="10dp"
+        android:layout_marginEnd="10dp"
+        android:textSize="14sp"
+        android:textColor="#8b8b8b"
+        android:ellipsize="end"
+        android:singleLine="true"
+        android:includeFontPadding="false"/>
+</LinearLayout>
diff --git a/ui/android/java/res/values-v17/styles.xml b/ui/android/java/res/values-v17/styles.xml
index 8295ddf..48b87ff 100644
--- a/ui/android/java/res/values-v17/styles.xml
+++ b/ui/android/java/res/values-v17/styles.xml
@@ -7,7 +7,7 @@
 -->
 
 <resources>
-    <style name="AutofillPopupWindow" parent="@android:style/Widget.ListPopupWindow">
-        <item name="android:popupBackground">@drawable/autofill_popup_background</item>
+    <style name="DropdownPopupWindow" parent="@android:style/Widget.ListPopupWindow">
+        <item name="android:popupBackground">@drawable/dropdown_popup_background</item>
     </style>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/ui/android/java/res/values/colors.xml b/ui/android/java/res/values/colors.xml
index 9aa152b..8eaed12 100644
--- a/ui/android/java/res/values/colors.xml
+++ b/ui/android/java/res/values/colors.xml
@@ -7,7 +7,7 @@
 <resources>
     <color name="color_picker_border_color">#B0B0B0</color>
     <color name="color_picker_background_color">#FFFFFF</color>
-    <color name="autofill_divider_color">#E5E5E5</color>
-    <color name="autofill_dark_divider_color">#C0C0C0</color>
+    <color name="dropdown_divider_color">#E5E5E5</color>
+    <color name="dropdown_dark_divider_color">#C0C0C0</color>
 </resources>
 
diff --git a/ui/android/java/res/values/dimens.xml b/ui/android/java/res/values/dimens.xml
index 0360254..5a7a227 100644
--- a/ui/android/java/res/values/dimens.xml
+++ b/ui/android/java/res/values/dimens.xml
@@ -12,8 +12,8 @@
     -->
     <dimen name="color_picker_gradient_margin">14.5dp</dimen>
     <dimen name="color_button_height">60dp</dimen>
-    <dimen name="autofill_text_height">44dp</dimen>
-    <dimen name="autofill_text_divider_height">1px</dimen>
+    <dimen name="dropdown_item_height">44dp</dimen>
+    <dimen name="dropdown_item_divider_height">1px</dimen>
 
     <!--
          Fallback values if the corresponding com.android.internal.R dimensions
diff --git a/ui/android/java/res/values/values.xml b/ui/android/java/res/values/values.xml
index 046cf8b..73f8c71 100644
--- a/ui/android/java/res/values/values.xml
+++ b/ui/android/java/res/values/values.xml
@@ -6,6 +6,5 @@
 -->
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- AutofillPopup constants -->
-    <item type="id" name="autofill_popup_window" />
+    <item type="id" name="dropdown_popup_window" />
 </resources>
\ No newline at end of file
diff --git a/ui/android/java/resource_map/org/chromium/ui/R.java b/ui/android/java/resource_map/org/chromium/ui/R.java
index 76d1a0d..74c3ac5 100644
--- a/ui/android/java/resource_map/org/chromium/ui/R.java
+++ b/ui/android/java/resource_map/org/chromium/ui/R.java
@@ -36,9 +36,9 @@
         public static int color_picker_button_white;
     }
     public static final class id {
-        public static int autofill_label;
-        public static int autofill_popup_window;
-        public static int autofill_sublabel;
+        public static int dropdown_label;
+        public static int dropdown_popup_window;
+        public static int dropdown_sublabel;
         public static int selected_color_view;
         public static int title;
         public static int more_colors_button;
@@ -52,7 +52,7 @@
         public static int seek_bar;
     }
     public static final class layout {
-        public static int autofill_text;
+        public static int dropdown_item;
         public static int color_picker_dialog_title;
         public static int color_picker_dialog_content;
         public static int color_picker_advanced_component;
@@ -62,16 +62,16 @@
         public static int color_picker_advanced_select_handle;
     }
     public static final class style {
-        public static int AutofillPopupWindow;
+        public static int DropdownPopupWindow;
     }
     public static final class color {
-        public static int autofill_dark_divider_color;
-        public static int autofill_divider_color;
+        public static int dropdown_dark_divider_color;
+        public static int dropdown_divider_color;
         public static int color_picker_border_color;
     }
     public static final class dimen {
-        public static int autofill_text_height;
-        public static int autofill_text_divider_height;
+        public static int dropdown_item_height;
+        public static int dropdown_item_divider_height;
         public static int color_button_height;
         public static int config_min_scaling_span;
         public static int config_min_scaling_touch_major;
diff --git a/ui/android/java/src/org/chromium/ui/DropdownAdapter.java b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java
new file mode 100644
index 0000000..2b561d1
--- /dev/null
+++ b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java
@@ -0,0 +1,119 @@
+// 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.ui;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView.LayoutParams;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import org.chromium.base.ApiCompatibilityUtils;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Dropdown item adapter for DropdownPopupWindow.
+ */
+public class DropdownAdapter extends ArrayAdapter<DropdownItem> {
+    private Context mContext;
+    private Set<Integer> mSeparators;
+    private boolean mAreAllItemsEnabled;
+
+    public DropdownAdapter(Context context, List<DropdownItem> items, Set<Integer> separators) {
+        super(context, R.layout.dropdown_item, items);
+        mSeparators = separators;
+        mContext = context;
+        mAreAllItemsEnabled = checkAreAllItemsEnabled();
+    }
+
+    public DropdownAdapter(Context context, DropdownItem[] items, Set<Integer> separators) {
+        super(context, R.layout.dropdown_item, items);
+        mSeparators = separators;
+        mContext = context;
+        mAreAllItemsEnabled = checkAreAllItemsEnabled();
+    }
+
+    private boolean checkAreAllItemsEnabled() {
+        for (int i = 0; i < getCount(); i++) {
+            DropdownItem item = getItem(i);
+            if (item.isEnabled() && !item.isGroupHeader()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        View layout = convertView;
+        if (convertView == null) {
+            LayoutInflater inflater =
+                    (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            layout = inflater.inflate(R.layout.dropdown_item, null);
+            ApiCompatibilityUtils.setBackgroundForView(layout, new DropdownDividerDrawable());
+        }
+
+        DropdownItem item = getItem(position);
+
+        TextView labelView = (TextView) layout.findViewById(R.id.dropdown_label);
+        labelView.setText(item.getLabel());
+
+        labelView.setEnabled(item.isEnabled());
+        if (item.isGroupHeader()) {
+            labelView.setTypeface(null, Typeface.BOLD);
+        } else {
+            labelView.setTypeface(null, Typeface.NORMAL);
+        }
+
+        DropdownDividerDrawable divider = (DropdownDividerDrawable) layout.getBackground();
+        int height = mContext.getResources().getDimensionPixelSize(R.dimen.dropdown_item_height);
+        if (position == 0) {
+            divider.setColor(Color.TRANSPARENT);
+        } else {
+            int dividerHeight = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.dropdown_item_divider_height);
+            height += dividerHeight;
+            divider.setHeight(dividerHeight);
+            if (mSeparators != null && mSeparators.contains(position)) {
+                divider.setColor(mContext.getResources().getColor(
+                                 R.color.dropdown_dark_divider_color));
+            } else {
+                divider.setColor(mContext.getResources().getColor(
+                                 R.color.dropdown_divider_color));
+            }
+        }
+        layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, height));
+
+        TextView sublabelView = (TextView) layout.findViewById(R.id.dropdown_sublabel);
+        CharSequence sublabel = item.getSublabel();
+        if (TextUtils.isEmpty(sublabel)) {
+            sublabelView.setVisibility(View.GONE);
+        } else {
+            sublabelView.setText(sublabel);
+            sublabelView.setVisibility(View.VISIBLE);
+        }
+
+        return layout;
+    }
+
+    @Override
+    public boolean areAllItemsEnabled() {
+        return mAreAllItemsEnabled;
+    }
+
+    @Override
+    public boolean isEnabled(int position) {
+        if (position < 0 || position >= getCount()) return false;
+        DropdownItem item = getItem(position);
+        return item.isEnabled() && !item.isGroupHeader();
+    }
+}
diff --git a/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java b/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java
new file mode 100644
index 0000000..da5009b
--- /dev/null
+++ b/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java
@@ -0,0 +1,54 @@
+// 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.ui;
+
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+
+class DropdownDividerDrawable extends Drawable {
+
+    private Paint mPaint;
+    private Rect mDividerRect;
+
+    public DropdownDividerDrawable() {
+        mPaint = new Paint();
+        mDividerRect = new Rect();
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        canvas.drawRect(mDividerRect, mPaint);
+    }
+
+    @Override
+    public void onBoundsChange(Rect bounds) {
+        mDividerRect.set(0, 0, bounds.width(), mDividerRect.height());
+    }
+
+    public void setHeight(int height) {
+        mDividerRect.set(0, 0, mDividerRect.right, height);
+    }
+
+    public void setColor(int color) {
+        mPaint.setColor(color);
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter cf) {
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.OPAQUE;
+    }
+}
diff --git a/ui/android/java/src/org/chromium/ui/DropdownItem.java b/ui/android/java/src/org/chromium/ui/DropdownItem.java
new file mode 100644
index 0000000..46d8d0e
--- /dev/null
+++ b/ui/android/java/src/org/chromium/ui/DropdownItem.java
@@ -0,0 +1,27 @@
+// 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.ui;
+
+/**
+ * Dropdown item interface used to access all the information needed to show the item.
+ */
+public interface DropdownItem {
+    /**
+     * Returns the label that should be shown in the dropdown.
+     */
+    String getLabel();
+    /**
+     * Returns the sublabel that should be shown in the dropdown.
+     */
+    String getSublabel();
+    /**
+     * Returns true if the item should be enabled in the dropdown.
+     */
+    boolean isEnabled();
+    /**
+     * Returns true if the item should be a group header in the dropdown.
+     */
+    boolean isGroupHeader();
+}
diff --git a/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java b/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java
new file mode 100644
index 0000000..f4f54af
--- /dev/null
+++ b/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java
@@ -0,0 +1,126 @@
+// 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.ui;
+
+import android.content.Context;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.view.View.OnLayoutChangeListener;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.ListAdapter;
+import android.widget.ListPopupWindow;
+
+import org.chromium.ui.base.ViewAndroidDelegate;
+
+/**
+ * The dropdown list popup window.
+ */
+public class DropdownPopupWindow extends ListPopupWindow {
+
+    private final Context mContext;
+    private final ViewAndroidDelegate mViewAndroidDelegate;
+    private final View mAnchorView;
+    private float mAnchorWidth;
+    private float mAnchorHeight;
+    private float mAnchorX;
+    private float mAnchorY;
+    private OnLayoutChangeListener mLayoutChangeListener;
+
+    /**
+     * Creates an DropdownPopupWindow with specified parameters.
+     * @param context Application context.
+     * @param viewAndroidDelegate View delegate used to add and remove views.
+     */
+    public DropdownPopupWindow(Context context, ViewAndroidDelegate viewAndroidDelegate) {
+        super(context, null, 0, R.style.DropdownPopupWindow);
+        mContext = context;
+        mViewAndroidDelegate = viewAndroidDelegate;
+
+        mAnchorView = mViewAndroidDelegate.acquireAnchorView();
+        mAnchorView.setId(R.id.dropdown_popup_window);
+        mAnchorView.setTag(this);
+
+        mLayoutChangeListener = new OnLayoutChangeListener() {
+            @Override
+            public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                if (v == mAnchorView) DropdownPopupWindow.this.show();
+            }
+        };
+
+        mAnchorView.addOnLayoutChangeListener(mLayoutChangeListener);
+        setAnchorView(mAnchorView);
+    }
+
+    /**
+     * Sets the location and the size of the anchor view that the DropdownPopupWindow will use to
+     * attach itself.
+     * @param x X coordinate of the top left corner of the anchor view.
+     * @param y Y coordinate of the top left corner of the anchor view.
+     * @param width The width of the anchor view.
+     * @param height The height of the anchor view.
+     */
+    public void setAnchorRect(float x, float y, float width, float height) {
+        mAnchorWidth = width;
+        mAnchorHeight = height;
+        mAnchorX = x;
+        mAnchorY = y;
+        if (mAnchorView != null) {
+            mViewAndroidDelegate.setAnchorViewPosition(mAnchorView, mAnchorX, mAnchorY,
+                    mAnchorWidth, mAnchorHeight);
+        }
+    }
+
+    @Override
+    public void show() {
+        // An ugly hack to keep the popup from expanding on top of the keyboard.
+        setInputMethodMode(INPUT_METHOD_NEEDED);
+        super.show();
+        getListView().setDividerHeight(0);
+        int contentWidth = measureContentWidth();
+        float contentWidthInDip = contentWidth /
+                mContext.getResources().getDisplayMetrics().density;
+        if (contentWidthInDip > mAnchorWidth) {
+            setContentWidth(contentWidth);
+        } else {
+            setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
+        }
+        mViewAndroidDelegate.setAnchorViewPosition(mAnchorView, mAnchorX, mAnchorY, mAnchorWidth,
+                mAnchorHeight);
+    }
+
+    @Override
+    public void dismiss() {
+        super.dismiss();
+        mAnchorView.removeOnLayoutChangeListener(mLayoutChangeListener);
+        mAnchorView.setTag(null);
+        mViewAndroidDelegate.releaseAnchorView(mAnchorView);
+    }
+
+    /**
+     * Measures the width of the list content.
+     * @return The popup window width in pixels.
+     */
+    private int measureContentWidth() {
+        int maxWidth = 0;
+        View itemView = null;
+        final ListAdapter adapter = getListView().getAdapter();
+        if (adapter == null)
+          return 0;
+        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        for (int i = 0; i < adapter.getCount(); i++) {
+            itemView = adapter.getView(i, itemView, null);
+            LinearLayout.LayoutParams params =
+                    new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
+                            LinearLayout.LayoutParams.WRAP_CONTENT);
+            itemView.setLayoutParams(params);
+            itemView.measure(widthMeasureSpec, heightMeasureSpec);
+            maxWidth = Math.max(maxWidth, itemView.getMeasuredWidth());
+        }
+        return maxWidth;
+    }
+}
diff --git a/ui/android/java/src/org/chromium/ui/autofill/AutofillDividerDrawable.java b/ui/android/java/src/org/chromium/ui/autofill/AutofillDividerDrawable.java
deleted file mode 100644
index 9aa88e8..0000000
--- a/ui/android/java/src/org/chromium/ui/autofill/AutofillDividerDrawable.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2013 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.ui.autofill;
-
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-
-class AutofillDividerDrawable extends Drawable {
-
-    private Paint mPaint;
-    private Rect mDividerRect;
-
-    public AutofillDividerDrawable() {
-        mPaint = new Paint();
-        mDividerRect = new Rect();
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        canvas.drawRect(mDividerRect, mPaint);
-    }
-
-    @Override
-    public void onBoundsChange(Rect bounds) {
-        mDividerRect.set(0, 0, bounds.width(), mDividerRect.height());
-    }
-
-    public void setHeight(int height) {
-        mDividerRect.set(0, 0, mDividerRect.right, height);
-    }
-
-    public void setColor(int color) {
-        mPaint.setColor(color);
-    }
-
-    @Override
-    public void setAlpha(int alpha) {
-    }
-
-    @Override
-    public void setColorFilter(ColorFilter cf) {
-    }
-
-    @Override
-    public int getOpacity() {
-        return PixelFormat.OPAQUE;
-    }
-}
diff --git a/ui/android/java/src/org/chromium/ui/autofill/AutofillListAdapter.java b/ui/android/java/src/org/chromium/ui/autofill/AutofillListAdapter.java
deleted file mode 100644
index 94608af..0000000
--- a/ui/android/java/src/org/chromium/ui/autofill/AutofillListAdapter.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2013 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.ui.autofill;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AbsListView.LayoutParams;
-import android.widget.ArrayAdapter;
-import android.widget.TextView;
-
-import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.ui.R;
-
-import java.util.ArrayList;
-import java.util.Set;
-
-/**
- * Autofill suggestion adapter for AutofillWindow.
- */
-public class AutofillListAdapter extends ArrayAdapter<AutofillSuggestion> {
-    private Context mContext;
-    private Set<Integer> mSeparators;
-
-    AutofillListAdapter(Context context,
-                        ArrayList<AutofillSuggestion> objects,
-                        Set<Integer> separators) {
-        super(context, R.layout.autofill_text, objects);
-        mSeparators = separators;
-        mContext = context;
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        View layout = convertView;
-        if (convertView == null) {
-            LayoutInflater inflater =
-                    (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            layout = inflater.inflate(R.layout.autofill_text, null);
-            ApiCompatibilityUtils.setBackgroundForView(layout, new AutofillDividerDrawable());
-        }
-        TextView labelView = (TextView) layout.findViewById(R.id.autofill_label);
-        labelView.setText(getItem(position).mLabel);
-
-        AutofillDividerDrawable divider = (AutofillDividerDrawable) layout.getBackground();
-        int height = mContext.getResources().getDimensionPixelSize(R.dimen.autofill_text_height);
-        if (position == 0) {
-            divider.setColor(Color.TRANSPARENT);
-        } else {
-            int dividerHeight = mContext.getResources().getDimensionPixelSize(
-                    R.dimen.autofill_text_divider_height);
-            height += dividerHeight;
-            divider.setHeight(dividerHeight);
-            if (mSeparators.contains(position)) {
-                divider.setColor(mContext.getResources().getColor(
-                                 R.color.autofill_dark_divider_color));
-            } else {
-                divider.setColor(mContext.getResources().getColor(
-                                 R.color.autofill_divider_color));
-            }
-        }
-        layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, height));
-
-        TextView sublabelView = (TextView) layout.findViewById(R.id.autofill_sublabel);
-        CharSequence sublabel = getItem(position).mSublabel;
-        if (TextUtils.isEmpty(sublabel)) {
-            sublabelView.setVisibility(View.GONE);
-        } else {
-            sublabelView.setText(sublabel);
-            sublabelView.setVisibility(View.VISIBLE);
-        }
-
-        return layout;
-    }
-}
diff --git a/ui/android/java/src/org/chromium/ui/autofill/AutofillPopup.java b/ui/android/java/src/org/chromium/ui/autofill/AutofillPopup.java
index 749ab75..d2f9bc7 100644
--- a/ui/android/java/src/org/chromium/ui/autofill/AutofillPopup.java
+++ b/ui/android/java/src/org/chromium/ui/autofill/AutofillPopup.java
@@ -5,17 +5,12 @@
 package org.chromium.ui.autofill;
 
 import android.content.Context;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnLayoutChangeListener;
 import android.widget.AdapterView;
-import android.widget.ListPopupWindow;
-import android.widget.TextView;
 
-import org.chromium.ui.R;
+import org.chromium.ui.DropdownAdapter;
+import org.chromium.ui.DropdownItem;
+import org.chromium.ui.DropdownPopupWindow;
 import org.chromium.ui.base.ViewAndroidDelegate;
 
 import java.util.ArrayList;
@@ -26,7 +21,7 @@
 /**
  * The Autofill suggestion popup that lists relevant suggestions.
  */
-public class AutofillPopup extends ListPopupWindow implements AdapterView.OnItemClickListener {
+public class AutofillPopup extends DropdownPopupWindow implements AdapterView.OnItemClickListener {
 
     /**
      * Constants defining types of Autofill suggestion entries.
@@ -40,19 +35,8 @@
     private static final int ITEM_ID_SEPARATOR_ENTRY = -3;
     private static final int ITEM_ID_DATA_LIST_ENTRY = -6;
 
-    private static final int TEXT_PADDING_DP = 30;
-
-    private final AutofillPopupDelegate mAutofillCallback;
     private final Context mContext;
-    private final ViewAndroidDelegate mViewAndroidDelegate;
-    private View mAnchorView;
-    private float mAnchorWidth;
-    private float mAnchorHeight;
-    private float mAnchorX;
-    private float mAnchorY;
-    private Paint mLabelViewPaint;
-    private Paint mSublabelViewPaint;
-    private OnLayoutChangeListener mLayoutChangeListener;
+    private final AutofillPopupDelegate mAutofillCallback;
     private List<AutofillSuggestion> mSuggestions;
 
 
@@ -80,67 +64,21 @@
      */
     public AutofillPopup(Context context, ViewAndroidDelegate viewAndroidDelegate,
             AutofillPopupDelegate autofillCallback) {
-        super(context, null, 0, R.style.AutofillPopupWindow);
+        super(context, viewAndroidDelegate);
         mContext = context;
-        mViewAndroidDelegate = viewAndroidDelegate;
         mAutofillCallback = autofillCallback;
 
         setOnItemClickListener(this);
-
-        mAnchorView = mViewAndroidDelegate.acquireAnchorView();
-        mAnchorView.setId(R.id.autofill_popup_window);
-        mAnchorView.setTag(this);
-
-        mViewAndroidDelegate.setAnchorViewPosition(mAnchorView, mAnchorX, mAnchorY, mAnchorWidth,
-                mAnchorHeight);
-
-        mLayoutChangeListener = new OnLayoutChangeListener() {
-            @Override
-            public void onLayoutChange(View v, int left, int top, int right, int bottom,
-                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
-                if (v == mAnchorView) AutofillPopup.this.show();
-            }
-        };
-
-        mAnchorView.addOnLayoutChangeListener(mLayoutChangeListener);
-        setAnchorView(mAnchorView);
-    }
-
-    @Override
-    public void show() {
-        // An ugly hack to keep the popup from expanding on top of the keyboard.
-        setInputMethodMode(INPUT_METHOD_NEEDED);
-        super.show();
-        getListView().setDividerHeight(0);
     }
 
     /**
-     * Sets the location and the size of the anchor view that the AutofillPopup will use to attach
-     * itself.
-     * @param x X coordinate of the top left corner of the anchor view.
-     * @param y Y coordinate of the top left corner of the anchor view.
-     * @param width The width of the anchor view.
-     * @param height The height of the anchor view.
-     */
-    public void setAnchorRect(float x, float y, float width, float height) {
-        mAnchorWidth = width;
-        mAnchorHeight = height;
-        mAnchorX = x;
-        mAnchorY = y;
-        if (mAnchorView != null) {
-            mViewAndroidDelegate.setAnchorViewPosition(mAnchorView, mAnchorX, mAnchorY,
-                    mAnchorWidth, mAnchorHeight);
-        }
-    }
-
-    /**
-     * Sets the Autofill suggestions to display in the popup and shows the popup.
+     * Filters the Autofill suggestions to the ones that we support and shows the popup.
      * @param suggestions Autofill suggestion data.
      */
-    public void show(AutofillSuggestion[] suggestions) {
+    public void filterAndShow(AutofillSuggestion[] suggestions) {
         mSuggestions = new ArrayList<AutofillSuggestion>(Arrays.asList(suggestions));
         // Remove the AutofillSuggestions with IDs that are not supported by Android
-        ArrayList<AutofillSuggestion> cleanedData = new ArrayList<AutofillSuggestion>();
+        ArrayList<DropdownItem> cleanedData = new ArrayList<DropdownItem>();
         HashSet<Integer> separators = new HashSet<Integer>();
         for (int i = 0; i < suggestions.length; i++) {
             int itemId = suggestions[i].mUniqueId;
@@ -151,11 +89,8 @@
                 separators.add(cleanedData.size());
             }
         }
-        setAdapter(new AutofillListAdapter(mContext, cleanedData, separators));
-        // Once the mAnchorRect is resized and placed correctly, it will show the Autofill popup.
-        mAnchorWidth = Math.max(getDesiredWidth(cleanedData), mAnchorWidth);
-        mViewAndroidDelegate.setAnchorViewPosition(mAnchorView, mAnchorX, mAnchorY, mAnchorWidth,
-                mAnchorHeight);
+        setAdapter(new DropdownAdapter(mContext, cleanedData, separators));
+        show();
     }
 
     /**
@@ -167,61 +102,16 @@
     }
 
     /**
-     * Hides the popup and removes the anchor view from the ContainerView.
+     * Hides the popup.
      */
     public void hide() {
         super.dismiss();
-        mAnchorView.removeOnLayoutChangeListener(mLayoutChangeListener);
-        mAnchorView.setTag(null);
-        mViewAndroidDelegate.releaseAnchorView(mAnchorView);
-    }
-
-    /**
-     * Get desired popup window width by calculating the maximum text length from Autofill data.
-     * @param data Autofill suggestion data.
-     * @return The popup window width in DIP.
-     */
-    private float getDesiredWidth(ArrayList<AutofillSuggestion> data) {
-        if (mLabelViewPaint == null || mSublabelViewPaint == null) {
-            LayoutInflater inflater =
-                    (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            View layout = inflater.inflate(R.layout.autofill_text, null);
-            TextView labelView = (TextView) layout.findViewById(R.id.autofill_label);
-            mLabelViewPaint = labelView.getPaint();
-            TextView sublabelView = (TextView) layout.findViewById(R.id.autofill_sublabel);
-            mSublabelViewPaint = sublabelView.getPaint();
-        }
-
-        float maxTextWidth = 0;
-        Rect bounds = new Rect();
-        for (int i = 0; i < data.size(); ++i) {
-            bounds.setEmpty();
-            String label = data.get(i).mLabel;
-            if (!TextUtils.isEmpty(label)) {
-                mLabelViewPaint.getTextBounds(label, 0, label.length(), bounds);
-            }
-            float labelWidth = bounds.width();
-
-            bounds.setEmpty();
-            String sublabel = data.get(i).mSublabel;
-            if (!TextUtils.isEmpty(sublabel)) {
-                mSublabelViewPaint.getTextBounds(sublabel, 0, sublabel.length(), bounds);
-            }
-
-            float localMax = Math.max(labelWidth, bounds.width());
-            maxTextWidth = Math.max(maxTextWidth, localMax);
-        }
-        // Scale it down to make it unscaled by screen density.
-        maxTextWidth = maxTextWidth / mContext.getResources().getDisplayMetrics().density;
-        // Adding padding.
-        return maxTextWidth + TEXT_PADDING_DP;
     }
 
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        AutofillListAdapter adapter = (AutofillListAdapter) parent.getAdapter();
-        AutofillSuggestion selectedSuggestion = adapter.getItem(position);
-        int listIndex = mSuggestions.indexOf(selectedSuggestion);
+        DropdownAdapter adapter = (DropdownAdapter) parent.getAdapter();
+        int listIndex = mSuggestions.indexOf(adapter.getItem(position));
         assert listIndex > -1;
         mAutofillCallback.suggestionSelected(listIndex);
     }
diff --git a/ui/android/java/src/org/chromium/ui/autofill/AutofillSuggestion.java b/ui/android/java/src/org/chromium/ui/autofill/AutofillSuggestion.java
index d6c457e..685a687 100644
--- a/ui/android/java/src/org/chromium/ui/autofill/AutofillSuggestion.java
+++ b/ui/android/java/src/org/chromium/ui/autofill/AutofillSuggestion.java
@@ -4,10 +4,12 @@
 
 package org.chromium.ui.autofill;
 
+import org.chromium.ui.DropdownItem;
+
 /**
  * Autofill suggestion container used to store information needed for each Autofill popup entry.
  */
-public class AutofillSuggestion {
+public class AutofillSuggestion implements DropdownItem {
     final String mLabel;
     final String mSublabel;
     final int mUniqueId;
@@ -24,14 +26,26 @@
         mUniqueId = uniqueId;
     }
 
+    @Override
     public String getLabel() {
         return mLabel;
     }
 
+    @Override
     public String getSublabel() {
         return mSublabel;
     }
 
+    @Override
+    public boolean isEnabled() {
+        return true;
+    }
+
+    @Override
+    public boolean isGroupHeader() {
+        return false;
+    }
+
     public int getUniqueId() {
         return mUniqueId;
     }
diff --git a/ui/android/window_open_disposition_java.target.darwin-arm.mk b/ui/android/window_open_disposition_java.target.darwin-arm.mk
index e91f032..5f71265 100644
--- a/ui/android/window_open_disposition_java.target.darwin-arm.mk
+++ b/ui/android/window_open_disposition_java.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_window_open_disposition_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../base/window_open_disposition_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/WindowOpenDisposition.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/android/window_open_disposition_java.target.darwin-arm64.mk b/ui/android/window_open_disposition_java.target.darwin-arm64.mk
index 22553f7..61e61af 100644
--- a/ui/android/window_open_disposition_java.target.darwin-arm64.mk
+++ b/ui/android/window_open_disposition_java.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_window_open_disposition_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../base/window_open_disposition_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/WindowOpenDisposition.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/android/window_open_disposition_java.target.darwin-mips.mk b/ui/android/window_open_disposition_java.target.darwin-mips.mk
index 816bbb3..3c161b1 100644
--- a/ui/android/window_open_disposition_java.target.darwin-mips.mk
+++ b/ui/android/window_open_disposition_java.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_window_open_disposition_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../base/window_open_disposition_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/WindowOpenDisposition.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/android/window_open_disposition_java.target.darwin-x86.mk b/ui/android/window_open_disposition_java.target.darwin-x86.mk
index a9f8630..6c48507 100644
--- a/ui/android/window_open_disposition_java.target.darwin-x86.mk
+++ b/ui/android/window_open_disposition_java.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_window_open_disposition_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../base/window_open_disposition_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/WindowOpenDisposition.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/android/window_open_disposition_java.target.darwin-x86_64.mk b/ui/android/window_open_disposition_java.target.darwin-x86_64.mk
index b905904..c2a4857 100644
--- a/ui/android/window_open_disposition_java.target.darwin-x86_64.mk
+++ b/ui/android/window_open_disposition_java.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_window_open_disposition_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../base/window_open_disposition_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/WindowOpenDisposition.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/android/window_open_disposition_java.target.linux-arm.mk b/ui/android/window_open_disposition_java.target.linux-arm.mk
index e91f032..5f71265 100644
--- a/ui/android/window_open_disposition_java.target.linux-arm.mk
+++ b/ui/android/window_open_disposition_java.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_window_open_disposition_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../base/window_open_disposition_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/WindowOpenDisposition.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/android/window_open_disposition_java.target.linux-arm64.mk b/ui/android/window_open_disposition_java.target.linux-arm64.mk
index 22553f7..61e61af 100644
--- a/ui/android/window_open_disposition_java.target.linux-arm64.mk
+++ b/ui/android/window_open_disposition_java.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_window_open_disposition_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../base/window_open_disposition_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/WindowOpenDisposition.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/android/window_open_disposition_java.target.linux-mips.mk b/ui/android/window_open_disposition_java.target.linux-mips.mk
index 816bbb3..3c161b1 100644
--- a/ui/android/window_open_disposition_java.target.linux-mips.mk
+++ b/ui/android/window_open_disposition_java.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_window_open_disposition_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../base/window_open_disposition_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/WindowOpenDisposition.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/android/window_open_disposition_java.target.linux-x86.mk b/ui/android/window_open_disposition_java.target.linux-x86.mk
index a9f8630..6c48507 100644
--- a/ui/android/window_open_disposition_java.target.linux-x86.mk
+++ b/ui/android/window_open_disposition_java.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_window_open_disposition_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../base/window_open_disposition_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/WindowOpenDisposition.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/android/window_open_disposition_java.target.linux-x86_64.mk b/ui/android/window_open_disposition_java.target.linux-x86_64.mk
index b905904..c2a4857 100644
--- a/ui/android/window_open_disposition_java.target.linux-x86_64.mk
+++ b/ui/android/window_open_disposition_java.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_android_ui_android_gyp_window_open_disposition_java_target_generate_java_constants":
 # "{'inputs': ['../../build/android/gyp/util/build_utils.py', '../../build/android/gyp/gcc_preprocess.py', '../base/window_open_disposition_list.h'], 'extension': 'template', 'outputs': ['$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'], 'variables': {'output_path': '$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java'}, 'rule_name': 'generate_java_constants', 'rule_sources': ['java/WindowOpenDisposition.template'], 'action': ['python', '../../build/android/gyp/gcc_preprocess.py', '--include-path=../..', '--output=$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/%(INPUT_ROOT)s.java', '--template=$(RULE_SOURCES)'], 'message': 'Generating Java from cpp template $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/templates/org/chromium/ui/WindowOpenDisposition.java: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/app_list/app_list.gyp b/ui/app_list/app_list.gyp
index 6665742..3dda480 100644
--- a/ui/app_list/app_list.gyp
+++ b/ui/app_list/app_list.gyp
@@ -258,8 +258,7 @@
           ],
         }],
         # See http://crbug.com/162998#c4 for why this is needed.
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and use_allocator!="none"', {
           'dependencies': [
             '../../base/allocator/allocator.gyp:allocator',
             # The following two dependencies provide the missing
diff --git a/ui/app_list/app_list_model.h b/ui/app_list/app_list_model.h
index af669d0..1da8506 100644
--- a/ui/app_list/app_list_model.h
+++ b/ui/app_list/app_list_model.h
@@ -5,6 +5,8 @@
 #ifndef UI_APP_LIST_APP_LIST_MODEL_H_
 #define UI_APP_LIST_APP_LIST_MODEL_H_
 
+#include <string>
+
 #include "base/basictypes.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/observer_list.h"
diff --git a/ui/app_list/app_list_switches.cc b/ui/app_list/app_list_switches.cc
index 406519e..8f3da33 100644
--- a/ui/app_list/app_list_switches.cc
+++ b/ui/app_list/app_list_switches.cc
@@ -18,12 +18,12 @@
 // If set, the app info context menu item is available in the app list UI.
 const char kEnableAppInfo[] = "enable-app-list-app-info";
 
-// If set, the experimental app list will be used.
-const char kEnableExperimentalAppList[] = "enable-experimental-app-list";
+// If set, the app list will be centered and wide instead of tall.
+const char kEnableCenteredAppList[] = "enable-centered-app-list";
 
-// If set, the experimental app list position will be used.
-const char kEnableExperimentalAppListPosition[] =
-    "enable-experimental-app-list-position";
+// If set, the experimental app list will be used. Implies
+// --enable-centered-app-list.
+const char kEnableExperimentalAppList[] = "enable-experimental-app-list";
 
 // Enables syncing of the app list independent of extensions.
 const char kEnableSyncAppList[] = "enable-sync-app-list";
@@ -63,9 +63,8 @@
       kEnableExperimentalAppList);
 }
 
-bool IsExperimentalAppListPositionEnabled() {
-  return CommandLine::ForCurrentProcess()->HasSwitch(
-             kEnableExperimentalAppListPosition) ||
+bool IsCenteredAppListEnabled() {
+  return CommandLine::ForCurrentProcess()->HasSwitch(kEnableCenteredAppList) ||
          IsExperimentalAppListEnabled();
 }
 
diff --git a/ui/app_list/app_list_switches.h b/ui/app_list/app_list_switches.h
index 17b6716..d422e67 100644
--- a/ui/app_list/app_list_switches.h
+++ b/ui/app_list/app_list_switches.h
@@ -14,8 +14,8 @@
 APP_LIST_EXPORT extern const char kDisableSyncAppList[];
 APP_LIST_EXPORT extern const char kDisableVoiceSearch[];
 APP_LIST_EXPORT extern const char kEnableAppInfo[];
+APP_LIST_EXPORT extern const char kEnableCenteredAppList[];
 APP_LIST_EXPORT extern const char kEnableExperimentalAppList[];
-APP_LIST_EXPORT extern const char kEnableExperimentalAppListPosition[];
 APP_LIST_EXPORT extern const char kEnableHotwordAlwaysOn[];
 APP_LIST_EXPORT extern const char kEnableSyncAppList[];
 
@@ -29,7 +29,11 @@
 
 bool APP_LIST_EXPORT IsExperimentalAppListEnabled();
 
-bool APP_LIST_EXPORT IsExperimentalAppListPositionEnabled();
+// Determines whether either command-line switch was given for enabling the
+// centered app list position. Do not use this when positioning the app list;
+// instead use AppListViewDelegate::ShouldCenterWindow. It checks a superset of
+// the conditions that trigger the position.
+bool APP_LIST_EXPORT IsCenteredAppListEnabled();
 
 }  // namespace switches
 }  // namespace app_list
diff --git a/ui/app_list/app_list_view_delegate.h b/ui/app_list/app_list_view_delegate.h
index f0c43db..83f8102 100644
--- a/ui/app_list/app_list_view_delegate.h
+++ b/ui/app_list/app_list_view_delegate.h
@@ -149,6 +149,9 @@
   // Returns the list of users (for AppListMenu).
   virtual const Users& GetUsers() const = 0;
 
+  // Returns true if the app list should be centered and in landscape mode.
+  virtual bool ShouldCenterWindow() const = 0;
+
   // Adds/removes an observer for profile changes.
   virtual void AddObserver(AppListViewDelegateObserver* observer) {}
   virtual void RemoveObserver(AppListViewDelegateObserver* observer) {}
diff --git a/ui/app_list/cocoa/apps_grid_controller.mm b/ui/app_list/cocoa/apps_grid_controller.mm
index 5687108..360254c 100644
--- a/ui/app_list/cocoa/apps_grid_controller.mm
+++ b/ui/app_list/cocoa/apps_grid_controller.mm
@@ -73,7 +73,8 @@
 // Create any new pages after updating |items_|.
 - (void)updatePages:(size_t)startItemIndex;
 
-- (void)updatePageContent:(size_t)pageIndex;
+- (void)updatePageContent:(size_t)pageIndex
+               resetModel:(BOOL)resetModel;
 
 // Bridged methods for AppListItemListObserver.
 - (void)listItemAdded:(size_t)index
@@ -87,11 +88,6 @@
 // Moves the selection by |indexDelta| items.
 - (BOOL)moveSelectionByDelta:(int)indexDelta;
 
-// -[NSCollectionView frameForItemAtIndex:] misreports the frame origin of an
-// item when the method is called during a scroll animation provided by the
-// NSScrollView. This returns the correct value.
-- (NSRect)trueFrameForItemAtIndex:(size_t)itemIndex;
-
 @end
 
 namespace app_list {
@@ -458,18 +454,23 @@
 
   const size_t startPage = startItemIndex / kItemsPerPage;
   // All pages on or after |startPage| may need items added or removed.
-  for (size_t pageIndex = startPage; pageIndex < targetPages; ++pageIndex)
-    [self updatePageContent:pageIndex];
+  for (size_t pageIndex = startPage; pageIndex < targetPages; ++pageIndex) {
+    [self updatePageContent:pageIndex
+                 resetModel:YES];
+  }
 }
 
-- (void)updatePageContent:(size_t)pageIndex {
+- (void)updatePageContent:(size_t)pageIndex
+               resetModel:(BOOL)resetModel {
   NSCollectionView* pageView = [self collectionViewAtPageIndex:pageIndex];
-  // Clear the models first, otherwise removed items could be autoreleased at
-  // an unknown point in the future, when the model owner may have gone away.
-  for (size_t i = 0; i < [[pageView content] count]; ++i) {
-    AppsGridViewItem* gridItem =
-        base::mac::ObjCCastStrict<AppsGridViewItem>([pageView itemAtIndex:i]);
-    [gridItem setModel:NULL];
+  if (resetModel) {
+    // Clear the models first, otherwise removed items could be autoreleased at
+    // an unknown point in the future, when the model owner may have gone away.
+    for (size_t i = 0; i < [[pageView content] count]; ++i) {
+      AppsGridViewItem* gridItem = base::mac::ObjCCastStrict<AppsGridViewItem>(
+          [pageView itemAtIndex:i]);
+      [gridItem setModel:NULL];
+    }
   }
 
   NSRange inPageRange = NSIntersectionRange(
@@ -477,13 +478,14 @@
       NSMakeRange(0, [items_ count]));
   NSArray* pageContent = [items_ subarrayWithRange:inPageRange];
   [pageView setContent:pageContent];
+  if (!resetModel)
+    return;
 
   for (size_t i = 0; i < [pageContent count]; ++i) {
     AppsGridViewItem* gridItem = base::mac::ObjCCastStrict<AppsGridViewItem>(
         [pageView itemAtIndex:i]);
     [gridItem setModel:static_cast<app_list::AppListItem*>(
         [[pageContent objectAtIndex:i] pointerValue])];
-    [gridItem setInitialFrameRect:[self trueFrameForItemAtIndex:i]];
   }
 }
 
@@ -498,7 +500,8 @@
   size_t fromPageIndex = fromIndex / kItemsPerPage;
   size_t toPageIndex = toIndex / kItemsPerPage;
   if (fromPageIndex == toPageIndex) {
-    [self updatePageContent:fromPageIndex];
+    [self updatePageContent:fromPageIndex
+                 resetModel:NO];  // Just reorder items.
     return;
   }
 
@@ -506,7 +509,8 @@
     std::swap(fromPageIndex, toPageIndex);
 
   for (size_t i = fromPageIndex; i <= toPageIndex; ++i) {
-    [self updatePageContent:i];
+    [self updatePageContent:i
+                 resetModel:YES];
   }
 }
 
@@ -611,15 +615,6 @@
   return YES;
 }
 
-- (NSRect)trueFrameForItemAtIndex:(size_t)itemIndex {
-  size_t column = itemIndex % kFixedColumns;
-  size_t row = itemIndex % kItemsPerPage / kFixedColumns;
-  return NSMakeRect(column * kPreferredTileWidth,
-                    row * kPreferredTileHeight,
-                    kPreferredTileWidth,
-                    kPreferredTileHeight);
-}
-
 - (void)selectItemAtIndex:(NSUInteger)index {
   if (index >= [items_ count])
     return;
diff --git a/ui/app_list/cocoa/apps_grid_view_item.h b/ui/app_list/cocoa/apps_grid_view_item.h
index 4838018..6106050 100644
--- a/ui/app_list/cocoa/apps_grid_view_item.h
+++ b/ui/app_list/cocoa/apps_grid_view_item.h
@@ -36,15 +36,6 @@
 // Set the represented model, updating views. Clears if |itemModel| is NULL.
 - (void)setModel:(app_list::AppListItem*)itemModel;
 
-// Set the frame that will be used the first time the NSCollectionView performs
-// layout on the item.
-// This is required because the first time an NSCollectionView becomes visible,
-// it performs a layout, and it can attempt to set a frame that differs from the
-// -[NSCollectionView frameForItemAtIndex:] reported when the cell was created.
-// Worse, this frame can have a non-integral origin, leading to graphical
-// glitches because the content is no longer pixel-aligned.
-- (void)setInitialFrameRect:(NSRect)frameRect;
-
 // Model accessor, via the |observerBridge_|.
 - (app_list::AppListItem*)model;
 
diff --git a/ui/app_list/cocoa/apps_grid_view_item.mm b/ui/app_list/cocoa/apps_grid_view_item.mm
index e7f399e..c61b38c 100644
--- a/ui/app_list/cocoa/apps_grid_view_item.mm
+++ b/ui/app_list/cocoa/apps_grid_view_item.mm
@@ -137,22 +137,13 @@
 // grid, and to draw with a highlight when selected.
 @interface AppsGridItemBackgroundView : NSView {
  @private
-  // Whether the item is selected, and draws a background.
   BOOL selected_;
-
-  // Whether to intercept the next call to -[NSView setFrame:] and override it.
-  BOOL overrideNextSetFrame_;
-
-  // The frame given to -[super setFrame:], when |overrideNextSetFrame_| is set.
-  NSRect overrideFrame_;
 }
 
 - (NSButton*)button;
 
 - (void)setSelected:(BOOL)flag;
 
-- (void)setOneshotFrameRect:(NSRect)frameRect;
-
 @end
 
 @interface AppsGridItemButtonCell : NSButtonCell {
@@ -182,20 +173,6 @@
   [self setNeedsDisplay:YES];
 }
 
-- (void)setOneshotFrameRect:(NSRect)frameRect {
-  [super setFrame:frameRect];
-  overrideNextSetFrame_ = YES;
-  overrideFrame_ = frameRect;
-}
-
-- (void)setFrame:(NSRect)frameRect {
-  if (overrideNextSetFrame_) {
-    frameRect = overrideFrame_;
-    overrideNextSetFrame_ = NO;
-  }
-  [super setFrame:frameRect];
-}
-
 // Ignore all hit tests. The grid controller needs to be the owner of any drags.
 - (NSView*)hitTest:(NSPoint)aPoint {
   return nil;
@@ -334,10 +311,6 @@
   [[self view] addTrackingArea:trackingArea_.get()];
 }
 
-- (void)setInitialFrameRect:(NSRect)frameRect {
-  [[self itemBackgroundView] setOneshotFrameRect:frameRect];
-}
-
 - (app_list::AppListItem*)model {
   return observerBridge_->model();
 }
diff --git a/ui/app_list/test/app_list_test_view_delegate.cc b/ui/app_list/test/app_list_test_view_delegate.cc
index 41d725b..0f4aa5f 100644
--- a/ui/app_list/test/app_list_test_view_delegate.cc
+++ b/ui/app_list/test/app_list_test_view_delegate.cc
@@ -129,6 +129,10 @@
   return users_;
 }
 
+bool AppListTestViewDelegate::ShouldCenterWindow() const {
+  return false;
+}
+
 void AppListTestViewDelegate::ReplaceTestModel(int item_count) {
   model_.reset(new AppListTestModel);
   model_->PopulateApps(item_count);
diff --git a/ui/app_list/test/app_list_test_view_delegate.h b/ui/app_list/test/app_list_test_view_delegate.h
index 1070ea3..ff929c6 100644
--- a/ui/app_list/test/app_list_test_view_delegate.h
+++ b/ui/app_list/test/app_list_test_view_delegate.h
@@ -76,6 +76,7 @@
   virtual content::WebContents* GetStartPageContents() OVERRIDE;
   virtual content::WebContents* GetSpeechRecognitionContents() OVERRIDE;
   virtual const Users& GetUsers() const OVERRIDE;
+  virtual bool ShouldCenterWindow() const OVERRIDE;
   virtual void AddObserver(AppListViewDelegateObserver* observer) OVERRIDE;
   virtual void RemoveObserver(AppListViewDelegateObserver* observer) OVERRIDE;
 
diff --git a/ui/app_list/views/app_list_folder_view.cc b/ui/app_list/views/app_list_folder_view.cc
index 015f72c..b9e93b0 100644
--- a/ui/app_list/views/app_list_folder_view.cc
+++ b/ui/app_list/views/app_list_folder_view.cc
@@ -276,9 +276,10 @@
 }
 
 void AppListFolderView::DispatchEndDragEventForReparent(
-    bool events_forwarded_to_drag_drop_host) {
-  container_view_->apps_grid_view()->
-      EndDragFromReparentItemInRootLevel(events_forwarded_to_drag_drop_host);
+    bool events_forwarded_to_drag_drop_host,
+    bool cancel_drag) {
+  container_view_->apps_grid_view()->EndDragFromReparentItemInRootLevel(
+      events_forwarded_to_drag_drop_host, cancel_drag);
 }
 
 void AppListFolderView::HideViewImmediately() {
@@ -302,6 +303,10 @@
   return folder_item_->folder_type() == AppListFolderItem::FOLDER_TYPE_OEM;
 }
 
+void AppListFolderView::SetRootLevelDragViewVisible(bool visible) {
+  container_view_->apps_grid_view()->SetDragViewVisible(visible);
+}
+
 void AppListFolderView::GetAccessibleState(ui::AXViewState* state) {
   state->role = ui::AX_ROLE_BUTTON;
   state->name = accessible_name_;
diff --git a/ui/app_list/views/app_list_folder_view.h b/ui/app_list/views/app_list_folder_view.h
index 6d71ba1..6172ec4 100644
--- a/ui/app_list/views/app_list_folder_view.h
+++ b/ui/app_list/views/app_list_folder_view.h
@@ -5,6 +5,8 @@
 #ifndef UI_APP_LIST_VIEWS_APP_LIST_FOLDER_VIEW_H_
 #define UI_APP_LIST_VIEWS_APP_LIST_FOLDER_VIEW_H_
 
+#include <string>
+
 #include "ui/app_list/app_list_item_list_observer.h"
 #include "ui/app_list/views/apps_grid_view.h"
 #include "ui/app_list/views/apps_grid_view_folder_delegate.h"
@@ -101,9 +103,11 @@
       AppsGridView::Pointer pointer,
       const gfx::Point& drag_point_in_folder_grid) OVERRIDE;
   virtual void DispatchEndDragEventForReparent(
-      bool events_forwarded_to_drag_drop_host) OVERRIDE;
+      bool events_forwarded_to_drag_drop_host,
+      bool cancel_drag) OVERRIDE;
   virtual bool IsPointOutsideOfFolderBoundary(const gfx::Point& point) OVERRIDE;
   virtual bool IsOEMFolder() const OVERRIDE;
+  virtual void SetRootLevelDragViewVisible(bool visible) OVERRIDE;
 
   AppsContainerView* container_view_;  // Not owned.
   AppListMainView* app_list_main_view_;   // Not Owned.
diff --git a/ui/app_list/views/app_list_item_view.cc b/ui/app_list/views/app_list_item_view.cc
index ceb0f13..2364a79 100644
--- a/ui/app_list/views/app_list_item_view.cc
+++ b/ui/app_list/views/app_list_item_view.cc
@@ -27,6 +27,7 @@
 #include "ui/gfx/image/image_skia_operations.h"
 #include "ui/gfx/point.h"
 #include "ui/gfx/transform_util.h"
+#include "ui/views/background.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/menu/menu_runner.h"
@@ -40,6 +41,15 @@
 const int kIconTitleSpacing = 7;
 const int kProgressBarHorizontalPadding = 12;
 
+// The font is different on each platform. The font size is adjusted on some
+// platforms to keep a consistent look.
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// Reducing the font size by 2 makes it the same as the Windows font size.
+const int kFontSizeDelta = -2;
+#else
+const int kFontSizeDelta = 0;
+#endif
+
 // Radius of the folder dropping preview circle.
 const int kFolderPreviewRadius = 40;
 
@@ -72,10 +82,12 @@
   title_->SetBackgroundColor(0);
   title_->SetAutoColorReadabilityEnabled(false);
   title_->SetEnabledColor(kGridTitleColor);
-  title_->SetFontList(rb.GetFontList(kItemTextFontStyle));
+  title_->SetFontList(
+      rb.GetFontList(kItemTextFontStyle).DeriveWithSizeDelta(kFontSizeDelta));
   title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   title_->SetVisible(!item_->is_installing());
   title_->Invalidate();
+  SetTitleSubpixelAA();
 
   const gfx::ShadowValue kIconShadows[] = {
     gfx::ShadowValue(gfx::Point(0, 2), 2, SkColorSetARGB(0x24, 0, 0, 0)),
@@ -192,6 +204,32 @@
   SetUIState(UI_STATE_DRAGGING);
 }
 
+void AppListItemView::SetTitleSubpixelAA() {
+  // TODO(tapted): Enable AA for folders as well, taking care to play nice with
+  // the folder bubble animation.
+  bool enable_aa = !item_->IsInFolder() && ui_state_ == UI_STATE_NORMAL &&
+                   !item_->highlighted() &&
+                   !apps_grid_view_->IsSelectedView(this) &&
+                   !apps_grid_view_->IsAnimatingView(this);
+
+  bool currently_enabled = title_->background() != NULL;
+  if (currently_enabled == enable_aa)
+    return;
+
+  if (enable_aa) {
+    title_->SetBackgroundColor(app_list::kContentsBackgroundColor);
+    title_->set_background(views::Background::CreateSolidBackground(
+        app_list::kContentsBackgroundColor));
+  } else {
+    // In other cases, keep the background transparent to ensure correct
+    // interactions with animations. This will temporarily disable subpixel AA.
+    title_->SetBackgroundColor(0);
+    title_->set_background(NULL);
+  }
+  title_->Invalidate();
+  title_->SchedulePaint();
+}
+
 void AppListItemView::Prerender() {
   title_->PaintToBackingImage();
 }
@@ -289,6 +327,11 @@
   progress_bar_->SetBoundsRect(progress_bar_bounds);
 }
 
+void AppListItemView::SchedulePaintInRect(const gfx::Rect& r) {
+  SetTitleSubpixelAA();
+  views::CustomButton::SchedulePaintInRect(r);
+}
+
 void AppListItemView::OnPaint(gfx::Canvas* canvas) {
   if (apps_grid_view_->IsDraggedView(this))
     return;
diff --git a/ui/app_list/views/app_list_item_view.h b/ui/app_list/views/app_list_item_view.h
index 166ce10..a55102b 100644
--- a/ui/app_list/views/app_list_item_view.h
+++ b/ui/app_list/views/app_list_item_view.h
@@ -92,6 +92,10 @@
   // Invoked when |mouse_drag_timer_| fires to show dragging UI.
   void OnMouseDragTimer();
 
+  // If the item is not in a folder, not highlighted, not being dragged, and not
+  // having something dropped onto it, enables subpixel AA for the title.
+  void SetTitleSubpixelAA();
+
   // AppListItemObserver overrides:
   virtual void ItemIconChanged() OVERRIDE;
   virtual void ItemNameChanged() OVERRIDE;
@@ -102,6 +106,7 @@
   // views::View overrides:
   virtual const char* GetClassName() const OVERRIDE;
   virtual void Layout() OVERRIDE;
+  virtual void SchedulePaintInRect(const gfx::Rect& r) OVERRIDE;
   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
 
   // views::ContextMenuController overrides:
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc
index 28c06a1..b6255a0 100644
--- a/ui/app_list/views/app_list_main_view.cc
+++ b/ui/app_list/views/app_list_main_view.cc
@@ -170,6 +170,10 @@
   contents_view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
 }
 
+bool AppListMainView::ShouldCenterWindow() const {
+  return delegate_->ShouldCenterWindow();
+}
+
 void AppListMainView::PreloadIcons(gfx::NativeView parent) {
   ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P;
   if (parent)
diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h
index caa83b9..8a9334e 100644
--- a/ui/app_list/views/app_list_main_view.h
+++ b/ui/app_list/views/app_list_main_view.h
@@ -62,6 +62,9 @@
 
   ContentsView* contents_view() const { return contents_view_; }
 
+  // Returns true if the app list should be centered and in landscape mode.
+  bool ShouldCenterWindow() const;
+
  private:
   class IconLoader;
 
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc
index 4924eb9..0499d45 100644
--- a/ui/app_list/views/app_list_view.cc
+++ b/ui/app_list/views/app_list_view.cc
@@ -28,11 +28,9 @@
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animation_observer.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
-#include "ui/gfx/display.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/insets.h"
 #include "ui/gfx/path.h"
-#include "ui/gfx/screen.h"
 #include "ui/gfx/skia_util.h"
 #include "ui/views/bubble/bubble_frame_view.h"
 #include "ui/views/bubble/bubble_window_targeter.h"
@@ -131,8 +129,7 @@
       app_list_main_view_(NULL),
       signin_view_(NULL),
       speech_view_(NULL),
-      animation_observer_(new HideViewAnimationObserver()),
-      screen_to_keep_centered_on_(NULL) {
+      animation_observer_(new HideViewAnimationObserver()) {
   CHECK(delegate);
 
   delegate_->AddObserver(this);
@@ -157,7 +154,6 @@
   SetAnchorView(anchor);
   InitAsBubbleInternal(
       parent, pagination_model, arrow, border_accepts_events, anchor_offset);
-  screen_to_keep_centered_on_ = NULL;
 }
 
 void AppListView::InitAsBubbleAtFixedLocation(
@@ -170,20 +166,6 @@
   SetAnchorRect(gfx::Rect(anchor_point_in_screen, gfx::Size()));
   InitAsBubbleInternal(
       parent, pagination_model, arrow, border_accepts_events, gfx::Vector2d());
-  screen_to_keep_centered_on_ = NULL;
-}
-
-void AppListView::InitAsBubbleCenteredOnPrimaryDisplay(
-    gfx::NativeView parent,
-    PaginationModel* pagination_model,
-    gfx::Screen* screen_to_keep_centered_on,
-    views::BubbleBorder::Arrow arrow,
-    bool border_accepts_events) {
-  screen_to_keep_centered_on_ = screen_to_keep_centered_on;
-  SetAnchorView(NULL);
-  SetAnchorRect(gfx::Rect(GetCenterPoint(), gfx::Size()));
-  InitAsBubbleInternal(
-      parent, pagination_model, arrow, border_accepts_events, gfx::Vector2d());
 }
 
 void AppListView::SetBubbleArrow(views::BubbleBorder::Arrow arrow) {
@@ -211,11 +193,13 @@
 }
 
 void AppListView::UpdateBounds() {
-  if (screen_to_keep_centered_on_)
-    SetAnchorRect(gfx::Rect(GetCenterPoint(), gfx::Size()));
   SizeToContents();
 }
 
+bool AppListView::ShouldCenterWindow() const {
+  return delegate_->ShouldCenterWindow();
+}
+
 gfx::Size AppListView::GetPreferredSize() {
   return app_list_main_view_->GetPreferredSize();
 }
@@ -317,7 +301,6 @@
   OnProfilesChanged();
   set_color(kContentsBackgroundColor);
   set_margins(gfx::Insets());
-  set_move_with_anchor(true);
   set_parent_window(parent);
   set_close_on_deactivate(false);
   set_close_on_esc(false);
@@ -357,12 +340,6 @@
     delegate_->ViewInitialized();
 }
 
-gfx::Point AppListView::GetCenterPoint() {
-  DCHECK(screen_to_keep_centered_on_);
-  gfx::Rect bounds = screen_to_keep_centered_on_->GetPrimaryDisplay().bounds();
-  return bounds.CenterPoint();
-}
-
 void AppListView::OnBeforeBubbleWidgetInit(
     views::Widget::InitParams* params,
     views::Widget* widget) const {
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h
index 5eb79c1..7180918 100644
--- a/ui/app_list/views/app_list_view.h
+++ b/ui/app_list/views/app_list_view.h
@@ -17,10 +17,6 @@
 class FilePath;
 }
 
-namespace gfx {
-class Screen;
-}
-
 namespace app_list {
 class ApplicationDragAndDropHost;
 class AppListMainView;
@@ -39,7 +35,6 @@
                                     public AppListViewDelegateObserver,
                                     public SpeechUIModelObserver {
  public:
-
   // Takes ownership of |delegate|.
   explicit AppListView(AppListViewDelegate* delegate);
   virtual ~AppListView();
@@ -61,15 +56,6 @@
                                    views::BubbleBorder::Arrow arrow,
                                    bool border_accepts_events);
 
-  // Initializes the widget and use the center of the primary display for
-  // positioning.
-  void InitAsBubbleCenteredOnPrimaryDisplay(
-      gfx::NativeView parent,
-      PaginationModel* pagination_model,
-      gfx::Screen* screen_to_keep_centered_on,
-      views::BubbleBorder::Arrow arrow,
-      bool border_accepts_events);
-
   void SetBubbleArrow(views::BubbleBorder::Arrow arrow);
 
   void SetAnchorPoint(const gfx::Point& anchor_point);
@@ -89,6 +75,9 @@
 
   void UpdateBounds();
 
+  // Returns true if the app list should be centered and in landscape mode.
+  bool ShouldCenterWindow() const;
+
   // Overridden from views::View:
   virtual gfx::Size GetPreferredSize() OVERRIDE;
   virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
@@ -123,10 +112,6 @@
                             bool border_accepts_events,
                             const gfx::Vector2d& anchor_offset);
 
-  // Gets the point at the center of the current screen.
-  // |screen_to_keep_centered_on_| must not be NULL.
-  gfx::Point GetCenterPoint();
-
   // Overridden from views::BubbleDelegateView:
   virtual void OnBeforeBubbleWidgetInit(
       views::Widget::InitParams* params,
@@ -165,10 +150,6 @@
   ObserverList<AppListViewObserver> observers_;
   scoped_ptr<HideViewAnimationObserver> animation_observer_;
 
-  // If non-NULL, the app list will remain centered on this screen's primary
-  // display.
-  gfx::Screen* screen_to_keep_centered_on_;
-
   DISALLOW_COPY_AND_ASSIGN(AppListView);
 };
 
diff --git a/ui/app_list/views/apps_container_view.cc b/ui/app_list/views/apps_container_view.cc
index 8b612d8..7e5adf7 100644
--- a/ui/app_list/views/apps_container_view.cc
+++ b/ui/app_list/views/apps_container_view.cc
@@ -30,7 +30,8 @@
   apps_grid_view_ = new AppsGridView(app_list_main_view, pagination_model);
   int cols = kPreferredCols;
   int rows = kPreferredRows;
-  if (app_list::switches::IsExperimentalAppListPositionEnabled()) {
+  // ShouldCenterWindow also implies that it is wide instead of tall.
+  if (app_list_main_view->ShouldCenterWindow()) {
     cols = kExperimentalPreferredCols;
     rows = kExperimentalPreferredRows;
   }
diff --git a/ui/app_list/views/apps_container_view.h b/ui/app_list/views/apps_container_view.h
index fceacee..909e0e3 100644
--- a/ui/app_list/views/apps_container_view.h
+++ b/ui/app_list/views/apps_container_view.h
@@ -5,6 +5,8 @@
 #ifndef UI_APP_LIST_VIEWS_APPS_CONTAINER_VIEW_H_
 #define UI_APP_LIST_VIEWS_APPS_CONTAINER_VIEW_H_
 
+#include <vector>
+
 #include "ui/app_list/app_list_folder_item.h"
 #include "ui/app_list/views/top_icon_animation_view.h"
 #include "ui/views/view.h"
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc
index 2c55642..1637f1d 100644
--- a/ui/app_list/views/apps_grid_view.cc
+++ b/ui/app_list/views/apps_grid_view.cc
@@ -128,11 +128,11 @@
   }
   virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE {
     view_->layer()->SetOpacity(1.0f);
-    view_->layer()->ScheduleDraw();
+    view_->SchedulePaint();
   }
   virtual void AnimationCanceled(const gfx::Animation* animation) OVERRIDE {
     view_->layer()->SetOpacity(1.0f);
-    view_->layer()->ScheduleDraw();
+    view_->SchedulePaint();
   }
 
  private:
@@ -171,6 +171,27 @@
   DISALLOW_COPY_AND_ASSIGN(ItemRemoveAnimationDelegate);
 };
 
+// ItemMoveAnimationDelegate observes when an item finishes animating when it is
+// not moving between rows. This is to ensure an item is repainted for the
+// "zoom out" case when releasing an item being dragged.
+class ItemMoveAnimationDelegate
+    : public views::BoundsAnimator::OwnedAnimationDelegate {
+ public:
+  ItemMoveAnimationDelegate(views::View* view) : view_(view) {}
+
+  virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE {
+    view_->SchedulePaint();
+  }
+  virtual void AnimationCanceled(const gfx::Animation* animation) OVERRIDE {
+    view_->SchedulePaint();
+  }
+
+ private:
+  views::View* view_;
+
+  DISALLOW_COPY_AND_ASSIGN(ItemMoveAnimationDelegate);
+};
+
 // Gets the distance between the centers of the |rect_1| and |rect_2|.
 int GetDistanceBetweenRects(gfx::Rect rect_1,
                             gfx::Rect rect_2) {
@@ -217,6 +238,8 @@
     shortcut_path_ = shortcut_path;
   }
 
+  bool running() { return running_; }
+
   bool CanRun() {
     return has_shortcut_path_ && !running_;
   }
@@ -368,6 +391,7 @@
 
 void AppsGridView::ResetForShowApps() {
   activated_item_view_ = NULL;
+  ClearDragState();
   layer()->SetOpacity(1.0f);
   SetVisible(true);
   // Set all views to visible in case they weren't made visible again by an
@@ -472,10 +496,20 @@
 
 bool AppsGridView::RunSynchronousDrag() {
 #if defined(OS_WIN)
-  if (synchronous_drag_ && synchronous_drag_->CanRun()) {
+  if (!synchronous_drag_)
+    return false;
+
+  if (synchronous_drag_->CanRun()) {
+    if (IsDraggingForReparentInHiddenGridView())
+      folder_delegate_->SetRootLevelDragViewVisible(false);
     synchronous_drag_->Run();
     synchronous_drag_ = NULL;
     return true;
+  } else if (!synchronous_drag_->running()) {
+    // The OS drag is not ready yet. If the root grid has a drag view because
+    // a reparent has started, ensure it is visible.
+    if (IsDraggingForReparentInHiddenGridView())
+      folder_delegate_->SetRootLevelDragViewVisible(true);
   }
 #endif
   return false;
@@ -544,6 +578,11 @@
     // Move the view to the front so that it appears on top of other views.
     ReorderChildView(drag_view_, -1);
     bounds_animator_.StopAnimatingView(drag_view_);
+    // Stopping the animation may have invalidated our drag view due to the
+    // view hierarchy changing.
+    if (!drag_view_)
+      return;
+
     StartSettingUpSynchronousDrag();
     if (!dragging_for_reparent_item_)
       StartDragAndDropHostDrag(point);
@@ -607,12 +646,17 @@
     DCHECK(!IsDraggingForReparentInRootLevelGridView());
     forward_events_to_drag_and_drop_host_ = false;
     drag_and_drop_host_->EndDrag(cancel);
-    if (IsDraggingForReparentInHiddenGridView())
-      folder_delegate_->DispatchEndDragEventForReparent(true);
+    if (IsDraggingForReparentInHiddenGridView()) {
+      folder_delegate_->DispatchEndDragEventForReparent(
+          true /* events_forwarded_to_drag_drop_host */,
+          cancel /* cancel_drag */);
+    }
   } else {
     if (IsDraggingForReparentInHiddenGridView()) {
       // Forward the EndDrag event to the root level grid view.
-      folder_delegate_->DispatchEndDragEventForReparent(cancel);
+      folder_delegate_->DispatchEndDragEventForReparent(
+          false /* events_forwarded_to_drag_drop_host */,
+          cancel /* cancel_drag */);
       EndDragForReparentInHiddenFolderGridView();
       return;
     }
@@ -655,14 +699,7 @@
   CleanUpSynchronousDrag();
 
   SetAsFolderDroppingTarget(drop_target_, false);
-  drop_attempt_ = DROP_FOR_NONE;
-  drag_pointer_ = NONE;
-  drop_target_ = Index();
-  drag_view_->OnDragEnded();
-  drag_view_ = NULL;
-  drag_start_grid_view_ = gfx::Point();
-  drag_start_page_ = -1;
-  drag_view_offset_ = gfx::Point();
+  ClearDragState();
   AnimateToIdealBounds();
 
   StopPageFlipTimer();
@@ -671,9 +708,6 @@
   // container ink bubble.
   if (folder_delegate_ && !IsDraggingForReparentInHiddenGridView())
     folder_delegate_->UpdateFolderViewBackground(false);
-
-  if (IsDraggingForReparentInHiddenGridView())
-    dragging_for_reparent_item_ = false;
 }
 
 void AppsGridView::StopPageFlipTimer() {
@@ -760,6 +794,29 @@
   return drag_view_ == view;
 }
 
+void AppsGridView::ClearDragState() {
+  drop_attempt_ = DROP_FOR_NONE;
+  drag_pointer_ = NONE;
+  drop_target_ = Index();
+  drag_start_grid_view_ = gfx::Point();
+  drag_start_page_ = -1;
+  drag_view_offset_ = gfx::Point();
+
+  if (drag_view_) {
+    drag_view_->OnDragEnded();
+    if (IsDraggingForReparentInRootLevelGridView()) {
+      DeleteItemViewAtIndex(view_model_.GetIndexOfView(drag_view_));
+    }
+  }
+  drag_view_ = NULL;
+  dragging_for_reparent_item_ = false;
+}
+
+void AppsGridView::SetDragViewVisible(bool visible) {
+  DCHECK(drag_view_);
+  SetViewHidden(drag_view_, !visible, true);
+}
+
 void AppsGridView::SetDragAndDropHostOfCurrentAppList(
     ApplicationDragAndDropHost* drag_and_drop_host) {
   drag_and_drop_host_ = drag_and_drop_host;
@@ -776,6 +833,10 @@
   }
 }
 
+bool AppsGridView::IsAnimatingView(views::View* view) {
+  return bounds_animator_.IsAnimating(view);
+}
+
 gfx::Size AppsGridView::GetPreferredSize() {
   const gfx::Insets insets(GetInsets());
   const gfx::Size tile_size = gfx::Size(kPreferredTileWidth,
@@ -1140,8 +1201,12 @@
                            current,
                            target_visible,
                            target);
-    } else {
+    } else if (visible || bounds_animator_.IsAnimating(view)) {
       bounds_animator_.AnimateViewTo(view, target);
+      bounds_animator_.SetAnimationDelegate(
+          view, new ItemMoveAnimationDelegate(view), true);
+    } else {
+      view->SetBoundsRect(target);
     }
   }
 }
@@ -1377,37 +1442,24 @@
 }
 
 void AppsGridView::EndDragFromReparentItemInRootLevel(
-    bool events_forwarded_to_drag_drop_host) {
+    bool events_forwarded_to_drag_drop_host,
+    bool cancel_drag) {
   // EndDrag was called before if |drag_view_| is NULL.
   if (!drag_view_)
     return;
 
   DCHECK(IsDraggingForReparentInRootLevelGridView());
-  bool cancel_reparent = false;
-  scoped_ptr<AppListItemView> cached_drag_view;
-  if (!events_forwarded_to_drag_drop_host) {
+  bool cancel_reparent = cancel_drag || drop_attempt_ == DROP_FOR_NONE;
+  if (!events_forwarded_to_drag_drop_host && !cancel_reparent) {
     CalculateDropTarget(last_drag_point_, true);
     if (IsValidIndex(drop_target_)) {
       if (drop_attempt_ == DROP_FOR_REORDER) {
         ReparentItemForReorder(drag_view_, drop_target_);
       } else if (drop_attempt_ == DROP_FOR_FOLDER) {
         ReparentItemToAnotherFolder(drag_view_, drop_target_);
-      } else {  // DROP_FOR_NONE_
-        cancel_reparent = true;
-        // Note(jennyz): cached_drag_view makes sure drag_view_ will be deleted
-        // after AnimateToIdealBounds() is called.
-        // There is a problem in layer() animation which cause DCHECK failure
-        // if a child view is deleted immediately before re-creating layer in
-        // layer animation. The layer tree seems marked dirty, and complaining
-        // when we try to re-create layer in AnimationBetweenRows when calling
-        // AnimateToIdealBounds.
-        cached_drag_view.reset(drag_view_);
       }
     }
-
-    if (!cancel_reparent) {
-      SetViewHidden(drag_view_, false /* show */, true /* no animate */);
-    }
+    SetViewHidden(drag_view_, false /* show */, true /* no animate */);
   }
 
   // The drag can be ended after the synchronous drag is created but before it
@@ -1415,18 +1467,16 @@
   CleanUpSynchronousDrag();
 
   SetAsFolderDroppingTarget(drop_target_, false);
-  drop_attempt_ = DROP_FOR_NONE;
-  drag_pointer_ = NONE;
-  drop_target_ = Index();
-  if (!cancel_reparent)
+  if (cancel_reparent) {
+    CancelFolderItemReparent(drag_view_);
+  } else {
+    // By setting |drag_view_| to NULL here, we prevent ClearDragState() from
+    // cleaning up the newly created AppListItemView, effectively claiming
+    // ownership of the newly created drag view.
     drag_view_->OnDragEnded();
-  drag_view_ = NULL;
-  drag_start_grid_view_ = gfx::Point();
-  drag_start_page_ = -1;
-  drag_view_offset_ = gfx::Point();
-  dragging_for_reparent_item_ = false;
-  if (cancel_reparent)
-    CancelFolderItemReparent(cached_drag_view.get());
+    drag_view_ = NULL;
+  }
+  ClearDragState();
   AnimateToIdealBounds();
 
   StopPageFlipTimer();
@@ -1444,15 +1494,7 @@
   CleanUpSynchronousDrag();
 
   SetAsFolderDroppingTarget(drop_target_, false);
-  drop_attempt_ = DROP_FOR_NONE;
-  drag_pointer_ = NONE;
-  drop_target_ = Index();
-  drag_view_->OnDragEnded();
-  drag_view_ = NULL;
-  drag_start_grid_view_ = gfx::Point();
-  drag_start_page_ = -1;
-  drag_view_offset_ = gfx::Point();
-  dragging_for_reparent_item_ = false;
+  ClearDragState();
 }
 
 void AppsGridView::OnFolderItemRemoved() {
@@ -1759,10 +1801,6 @@
   // the animation completes.
   CalculateIdealBounds();
 
-  // Remove drag_view_ from view_model_, it will be deleted after the animation.
-  int drag_view_index = view_model_.GetIndexOfView(drag_item_view);
-  view_model_.Remove(drag_view_index);
-
   gfx::Rect target_icon_rect =
       GetTargetIconRectInFolder(drag_item_view, activated_item_view_);
 
@@ -1794,6 +1832,8 @@
   view_model_.Remove(index);
   if (item_view == activated_item_view_)
     activated_item_view_ = NULL;
+  if (item_view == drag_view_)
+    drag_view_ = NULL;
   delete item_view;
 }
 
diff --git a/ui/app_list/views/apps_grid_view.h b/ui/app_list/views/apps_grid_view.h
index 62827ce..5b02667 100644
--- a/ui/app_list/views/apps_grid_view.h
+++ b/ui/app_list/views/apps_grid_view.h
@@ -6,6 +6,7 @@
 #define UI_APP_LIST_VIEWS_APPS_GRID_VIEW_H_
 
 #include <set>
+#include <string>
 
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
@@ -114,6 +115,8 @@
   void UpdateDrag(Pointer pointer, const gfx::Point& point);
   void EndDrag(bool cancel);
   bool IsDraggedView(const views::View* view) const;
+  void ClearDragState();
+  void SetDragViewVisible(bool visible);
 
   // Set the drag and drop host for application links.
   void SetDragAndDropHostOfCurrentAppList(
@@ -122,6 +125,9 @@
   // Prerenders the icons on and around |page_index|.
   void Prerender(int page_index);
 
+  // Return true if the |bounds_animator_| is animating |view|.
+  bool IsAnimatingView(views::View* view);
+
   bool has_dragged_view() const { return drag_view_ != NULL; }
   bool dragging() const { return drag_pointer_ != NONE; }
 
@@ -172,8 +178,10 @@
   // root level grid view to end reparenting a folder item.
   // |events_forwarded_to_drag_drop_host|: True if the dragged item is dropped
   // to the drag_drop_host, eg. dropped on shelf.
+  // |cancel_drag|: True if the drag is ending because it has been canceled.
   void EndDragFromReparentItemInRootLevel(
-      bool events_forwarded_to_drag_drop_host);
+      bool events_forwarded_to_drag_drop_host,
+      bool cancel_drag);
 
   // Handles EndDrag event in the hidden folder grid view to end reparenting
   // a folder item.
diff --git a/ui/app_list/views/apps_grid_view_folder_delegate.h b/ui/app_list/views/apps_grid_view_folder_delegate.h
index a5f1d7d..4be530c 100644
--- a/ui/app_list/views/apps_grid_view_folder_delegate.h
+++ b/ui/app_list/views/apps_grid_view_folder_delegate.h
@@ -44,8 +44,10 @@
   // view for reparenting a folder item.
   // |events_forwarded_to_drag_drop_host|: True if the dragged item is dropped
   // to the drag_drop_host, eg. dropped on shelf.
+  // |cancel_drag|: True if the drag is ending because it has been canceled.
   virtual void DispatchEndDragEventForReparent(
-      bool events_forwarded_to_drag_drop_host) = 0;
+      bool events_forwarded_to_drag_drop_host,
+      bool cancel_drag) = 0;
 
   // Returns true if |point| falls outside of the folder container ink bubble.
   virtual bool IsPointOutsideOfFolderBoundary(const gfx::Point& point) = 0;
@@ -53,6 +55,10 @@
   // Returns true if the associated folder item is an OEM folder.
   virtual bool IsOEMFolder() const = 0;
 
+  // Hides or show the root level's grid view. This is needed so that the
+  // synchronous drag has an icon for reparenting while it loads.
+  virtual void SetRootLevelDragViewVisible(bool visible) = 0;
+
  protected:
   virtual ~AppsGridViewFolderDelegate() {}
 };
diff --git a/ui/app_list/views/apps_grid_view_unittest.cc b/ui/app_list/views/apps_grid_view_unittest.cc
index 965d1bb..d93943d 100644
--- a/ui/app_list/views/apps_grid_view_unittest.cc
+++ b/ui/app_list/views/apps_grid_view_unittest.cc
@@ -206,7 +206,8 @@
       const gfx::Point& drag_point_in_folder_grid) OVERRIDE {}
 
   virtual void DispatchEndDragEventForReparent(
-      bool events_forwarded_to_drag_drop_host) OVERRIDE {}
+      bool events_forwarded_to_drag_drop_host,
+      bool cancel_drag) OVERRIDE {}
 
   virtual bool IsPointOutsideOfFolderBoundary(const gfx::Point& point)
       OVERRIDE {
@@ -215,6 +216,8 @@
 
   virtual bool IsOEMFolder() const OVERRIDE { return false; }
 
+  virtual void SetRootLevelDragViewVisible(bool visible) OVERRIDE {}
+
   bool show_bubble() { return show_bubble_; }
 
  private:
diff --git a/ui/app_list/views/cached_label.cc b/ui/app_list/views/cached_label.cc
index a7d9e27..ea289f3 100644
--- a/ui/app_list/views/cached_label.cc
+++ b/ui/app_list/views/cached_label.cc
@@ -17,9 +17,15 @@
 void CachedLabel::PaintToBackingImage() {
   if (image_.size() == size() && !needs_repaint_)
     return;
-  gfx::Canvas canvas(size(), 1.0f, false /* is_opaque */);
-  canvas.FillRect(GetLocalBounds(), SkColorSetARGB(0, 0, 0, 0),
-                  SkXfermode::kSrc_Mode);
+
+  bool is_opaque = SkColorGetA(background_color()) == 0xFF;
+  gfx::Canvas canvas(size(), 1.0f, is_opaque);
+  // If a background is provided, it will initialize the canvas in
+  // View::OnPaintBackground(). Otherwise, the background must be set here.
+  if (!background()) {
+    canvas.FillRect(
+        GetLocalBounds(), background_color(), SkXfermode::kSrc_Mode);
+  }
   Label::OnPaint(&canvas);
   image_ = gfx::ImageSkia(canvas.ExtractImageRep());
   needs_repaint_ = false;
diff --git a/ui/app_list/views/contents_switcher_view.cc b/ui/app_list/views/contents_switcher_view.cc
index d931720..07e5991 100644
--- a/ui/app_list/views/contents_switcher_view.cc
+++ b/ui/app_list/views/contents_switcher_view.cc
@@ -4,58 +4,20 @@
 
 #include "ui/app_list/views/contents_switcher_view.h"
 
+#include "grit/ui_resources.h"
 #include "ui/app_list/app_list_constants.h"
 #include "ui/app_list/views/contents_view.h"
-#include "ui/gfx/canvas.h"
+#include "ui/base/resource/resource_bundle.h"
 #include "ui/views/controls/button/custom_button.h"
+#include "ui/views/controls/button/image_button.h"
 #include "ui/views/layout/box_layout.h"
 
 namespace app_list {
 
 namespace {
 
-const int kPreferredHeight = 36;
-
+const int kPreferredHeight = 32;
 const int kButtonSpacing = 4;
-const int kButtonWidth = 36;
-const int kButtonHeight = 36;
-
-class ContentsSwitcherButton : public views::CustomButton {
- public:
-  explicit ContentsSwitcherButton(views::ButtonListener* listener,
-                                  ContentsView::ShowState show_state)
-      : views::CustomButton(listener) {
-    set_tag(show_state);
-  }
-
-  virtual ~ContentsSwitcherButton() {}
-
-  // Overridden from views::View:
-  virtual gfx::Size GetPreferredSize() OVERRIDE {
-    return gfx::Size(kButtonWidth, kButtonHeight);
-  }
-
-  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
-    PaintButton(
-        canvas,
-        state() == STATE_HOVERED ? kPagerHoverColor : kPagerNormalColor);
-  }
-
- private:
-  // Paints a rectangular button.
-  void PaintButton(gfx::Canvas* canvas, SkColor base_color) {
-    gfx::Rect rect(GetContentsBounds());
-    rect.ClampToCenteredSize(gfx::Size(kButtonWidth, kButtonHeight));
-
-    SkPaint paint;
-    paint.setAntiAlias(true);
-    paint.setStyle(SkPaint::kFill_Style);
-    paint.setColor(base_color);
-    canvas->DrawRect(rect, paint);
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(ContentsSwitcherButton);
-};
 
 }  // namespace
 
@@ -65,14 +27,22 @@
 
   buttons_->SetLayoutManager(new views::BoxLayout(
       views::BoxLayout::kHorizontal, 0, 0, kButtonSpacing));
-  buttons_->AddChildView(
-      new ContentsSwitcherButton(this, ContentsView::SHOW_APPS));
-  buttons_->AddChildView(
-      new ContentsSwitcherButton(this, ContentsView::SHOW_SEARCH_RESULTS));
+  AddSwitcherButton(IDR_APP_LIST_SEARCH_ICON,
+                    ContentsView::SHOW_SEARCH_RESULTS);
+  AddSwitcherButton(IDR_APP_LIST_APPS_ICON, ContentsView::SHOW_APPS);
 }
 
 ContentsSwitcherView::~ContentsSwitcherView() {}
 
+void ContentsSwitcherView::AddSwitcherButton(int resource_id, int tag) {
+  views::ImageButton* button = new views::ImageButton(this);
+  button->SetImage(
+      views::CustomButton::STATE_NORMAL,
+      ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id));
+  button->set_tag(tag);
+  buttons_->AddChildView(button);
+}
+
 gfx::Size ContentsSwitcherView::GetPreferredSize() {
   return gfx::Size(buttons_->GetPreferredSize().width(), kPreferredHeight);
 }
diff --git a/ui/app_list/views/contents_switcher_view.h b/ui/app_list/views/contents_switcher_view.h
index df6d6fe..fcbcfbf 100644
--- a/ui/app_list/views/contents_switcher_view.h
+++ b/ui/app_list/views/contents_switcher_view.h
@@ -21,6 +21,10 @@
   virtual ~ContentsSwitcherView();
 
  private:
+  // Adds a switcher button using |resource_id| as the button's image and |tag|
+  // as the button's id.
+  void AddSwitcherButton(int resource_id, int tag);
+
   // Overridden from views::View:
   virtual gfx::Size GetPreferredSize() OVERRIDE;
   virtual void Layout() OVERRIDE;
diff --git a/ui/app_list/views/folder_header_view.cc b/ui/app_list/views/folder_header_view.cc
index fd54984..4346fec 100644
--- a/ui/app_list/views/folder_header_view.cc
+++ b/ui/app_list/views/folder_header_view.cc
@@ -4,6 +4,8 @@
 
 #include "ui/app_list/views/folder_header_view.h"
 
+#include <algorithm>
+
 #include "base/strings/utf_string_conversions.h"
 #include "grit/ui_resources.h"
 #include "grit/ui_strings.h"
diff --git a/ui/app_list/views/folder_header_view_delegate.h b/ui/app_list/views/folder_header_view_delegate.h
index 639b7fc..843c071 100644
--- a/ui/app_list/views/folder_header_view_delegate.h
+++ b/ui/app_list/views/folder_header_view_delegate.h
@@ -5,6 +5,12 @@
 #ifndef UI_APP_LIST_VIEWS_FOLDER_HEADER_VIEW_DELEGATE_H_
 #define UI_APP_LIST_VIEWS_FOLDER_HEADER_VIEW_DELEGATE_H_
 
+#include <string>
+
+namespace ui {
+class Event;
+}
+
 namespace app_list {
 
 class AppListFolderItem;
diff --git a/ui/app_list/views/search_result_view.h b/ui/app_list/views/search_result_view.h
index 7e04742..bf2bb37 100644
--- a/ui/app_list/views/search_result_view.h
+++ b/ui/app_list/views/search_result_view.h
@@ -43,7 +43,7 @@
   // Internal class name.
   static const char kViewClassName[];
 
-  SearchResultView(SearchResultListView* list_view);
+  explicit SearchResultView(SearchResultListView* list_view);
   virtual ~SearchResultView();
 
   // Sets/gets SearchResult displayed by this view.
diff --git a/ui/app_list/views/speech_view.cc b/ui/app_list/views/speech_view.cc
index 56df2fc..0f3a499 100644
--- a/ui/app_list/views/speech_view.cc
+++ b/ui/app_list/views/speech_view.cc
@@ -7,12 +7,14 @@
 #include "base/strings/utf_string_conversions.h"
 #include "grit/ui_resources.h"
 #include "grit/ui_strings.h"
+#include "third_party/skia/include/core/SkPath.h"
 #include "ui/app_list/app_list_model.h"
 #include "ui/app_list/app_list_view_delegate.h"
 #include "ui/app_list/speech_ui_model.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/path.h"
 #include "ui/views/animation/bounds_animator.h"
 #include "ui/views/background.h"
 #include "ui/views/controls/button/image_button.h"
@@ -75,7 +77,9 @@
 
  private:
   // Overridden from views::View:
-  virtual bool HitTestRect(const gfx::Rect& rect) const OVERRIDE;
+  virtual bool HasHitTestMask() const OVERRIDE;
+  virtual void GetHitTestMask(views::View::HitTestSource source,
+                              gfx::Path* mask) const OVERRIDE;
 
   DISALLOW_COPY_AND_ASSIGN(MicButton);
 };
@@ -85,14 +89,20 @@
 
 MicButton::~MicButton() {}
 
-bool MicButton::HitTestRect(const gfx::Rect& rect) const {
-  if (!views::ImageButton::HitTestRect(rect))
-    return false;
+bool MicButton::HasHitTestMask() const {
+  return true;
+}
 
+void MicButton::GetHitTestMask(views::View::HitTestSource source,
+                               gfx::Path* mask) const {
+  // The mic button icon is a circle. |source| doesn't matter.
   gfx::Rect local_bounds = GetLocalBounds();
-  int radius = local_bounds.width() / 2;
-  return (rect.origin() - local_bounds.CenterPoint()).LengthSquared() <
-      radius * radius;
+  int radius = local_bounds.width() / 2 + kIndicatorRadiusMinOffset;
+  gfx::Point center = local_bounds.CenterPoint();
+  center.set_y(center.y() + kIndicatorCenterOffsetY);
+  mask->addCircle(SkIntToScalar(center.x()),
+                  SkIntToScalar(center.y()),
+                  SkIntToScalar(radius));
 }
 
 }  // namespace
diff --git a/ui/app_list/views/top_icon_animation_view.cc b/ui/app_list/views/top_icon_animation_view.cc
index 521f092..8ec6921 100644
--- a/ui/app_list/views/top_icon_animation_view.cc
+++ b/ui/app_list/views/top_icon_animation_view.cc
@@ -30,6 +30,9 @@
 }
 
 TopIconAnimationView::~TopIconAnimationView() {
+  // Required due to RequiresNotificationWhenAnimatorDestroyed() returning true.
+  // See ui::LayerAnimationObserver for details.
+  StopObservingImplicitAnimations();
 }
 
 void TopIconAnimationView::AddObserver(TopIconAnimationObserver* observer) {
@@ -80,4 +83,8 @@
   delete this;
 }
 
+bool TopIconAnimationView::RequiresNotificationWhenAnimatorDestroyed() const {
+  return true;
+}
+
 }  // namespace app_list
diff --git a/ui/app_list/views/top_icon_animation_view.h b/ui/app_list/views/top_icon_animation_view.h
index c50d122..02790a9 100644
--- a/ui/app_list/views/top_icon_animation_view.h
+++ b/ui/app_list/views/top_icon_animation_view.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef UI_APP_LIST_VIEWS_TOP_ICON_ANIMATION_VIEW_H
-#define UI_APP_LIST_VIEWS_TOP_ICON_ANIMATION_VIEW_H
+#ifndef UI_APP_LIST_VIEWS_TOP_ICON_ANIMATION_VIEW_H_
+#define UI_APP_LIST_VIEWS_TOP_ICON_ANIMATION_VIEW_H_
 
 #include "base/observer_list.h"
 #include "ui/compositor/layer_animation_observer.h"
@@ -59,6 +59,7 @@
 
   // ui::ImplicitAnimationObserver overrides:
   virtual void OnImplicitAnimationsCompleted() OVERRIDE;
+  virtual bool RequiresNotificationWhenAnimatorDestroyed() const OVERRIDE;
 
   gfx::Size icon_size_;
   views::ImageView* icon_;  // Owned by views hierarchy.
@@ -74,4 +75,4 @@
 
 }  // namespace app_list
 
-#endif  // UI_APP_LIST_VIEWS_TOP_ICON_ANIMATION_VIEW_H
+#endif  // UI_APP_LIST_VIEWS_TOP_ICON_ANIMATION_VIEW_H_
diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp
index a8900f8..7aabb85 100644
--- a/ui/aura/aura.gyp
+++ b/ui/aura/aura.gyp
@@ -262,6 +262,7 @@
         '../compositor/compositor.gyp:compositor_test_support',
         '../events/events.gyp:events',
         '../events/events.gyp:events_base',
+        '../events/events.gyp:gesture_detection',
         '../gfx/gfx.gyp:gfx',
         '../gfx/gfx.gyp:gfx_geometry',
         '../gl/gl.gyp:gl',
@@ -285,8 +286,7 @@
             '<(DEPTH)/third_party/mesa/mesa.gyp:osmesa',
           ],
         }],
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and use_allocator!="none"', {
           'dependencies': [
            # See http://crbug.com/162998#c4 for why this is needed.
             '../../base/allocator/allocator.gyp:allocator',
diff --git a/ui/aura/bench/bench_main.cc b/ui/aura/bench/bench_main.cc
index c5b98c0..f2eadee 100644
--- a/ui/aura/bench/bench_main.cc
+++ b/ui/aura/bench/bench_main.cc
@@ -304,7 +304,7 @@
   base::i18n::InitializeICU();
 
   base::MessageLoopForUI message_loop;
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
   scoped_ptr<aura::TestScreen> test_screen(
       aura::TestScreen::CreateFullscreen());
   gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen.get());
diff --git a/ui/aura/demo/demo_main.cc b/ui/aura/demo/demo_main.cc
index 23262fa..a8716e1 100644
--- a/ui/aura/demo/demo_main.cc
+++ b/ui/aura/demo/demo_main.cc
@@ -128,7 +128,7 @@
   // Create the message-loop here before creating the root window.
   base::MessageLoopForUI message_loop;
 
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
   scoped_ptr<aura::TestScreen> test_screen(aura::TestScreen::Create());
   gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen.get());
   scoped_ptr<aura::WindowTreeHost> host(
diff --git a/ui/aura/env.cc b/ui/aura/env.cc
index f701695..bd074f9 100644
--- a/ui/aura/env.cc
+++ b/ui/aura/env.cc
@@ -31,10 +31,10 @@
 }
 
 //static
-void Env::CreateInstance() {
+void Env::CreateInstance(bool create_event_source) {
   if (!instance_) {
     instance_ = new Env;
-    instance_->Init();
+    instance_->Init(create_event_source);
   }
 }
 
@@ -67,10 +67,10 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Env, private:
 
-void Env::Init() {
+void Env::Init(bool create_event_source) {
   ui::Compositor::Initialize();
 
-  if (!ui::PlatformEventSource::GetInstance())
+  if (create_event_source && !ui::PlatformEventSource::GetInstance())
     event_source_ = ui::PlatformEventSource::CreateDefault();
 }
 
diff --git a/ui/aura/env.h b/ui/aura/env.h
index 1d6c19d..159ac48 100644
--- a/ui/aura/env.h
+++ b/ui/aura/env.h
@@ -32,7 +32,11 @@
   Env();
   virtual ~Env();
 
-  static void CreateInstance();
+  // Creates the single Env instance (if it hasn't been created yet). If
+  // |create_event_source| is true a PlatformEventSource is created.
+  // TODO(sky): nuke |create_event_source|. Only necessary while mojo's
+  // nativeviewportservice lives in the same process as the viewmanager.
+  static void CreateInstance(bool create_event_source);
   static Env* GetInstance();
   static void DeleteInstance();
 
@@ -63,7 +67,8 @@
   friend class Window;
   friend class WindowTreeHost;
 
-  void Init();
+  // See description of CreateInstance() for deatils of |create_event_source|.
+  void Init(bool create_event_source);
 
   // Called by the Window when it is initialized. Notifies observers.
   void NotifyWindowInitialized(Window* window);
diff --git a/ui/aura/gestures/gesture_recognizer_unittest.cc b/ui/aura/gestures/gesture_recognizer_unittest.cc
index d155048..be8e86c 100644
--- a/ui/aura/gestures/gesture_recognizer_unittest.cc
+++ b/ui/aura/gestures/gesture_recognizer_unittest.cc
@@ -682,9 +682,8 @@
   virtual void SetUp() OVERRIDE {
     // TODO(tdresser): Once unified GR has landed, only run these tests once.
     if (UsingUnifiedGR()) {
-      // TODO(tdresser): use unified GR once it's available.
-      // CommandLine::ForCurrentProcess()->AppendSwitch(
-      //    switches::kUseUnifiedGestureDetector);
+      CommandLine::ForCurrentProcess()->AppendSwitch(
+          switches::kUseUnifiedGestureDetector);
     }
 
     AuraTestBase::SetUp();
@@ -746,6 +745,11 @@
 // Check that appropriate touch events generate tap gesture events
 // when information about the touch radii are provided.
 TEST_P(GestureRecognizerTest, GestureEventTapRegion) {
+  // TODO(tdresser): enable this test with unified GR once we resolve the
+  // bounding box differences. See crbug.com/366641.
+  if (UsingUnifiedGR())
+    return;
+
   scoped_ptr<GestureEventConsumeDelegate> delegate(
       new GestureEventConsumeDelegate());
   TimedEvents tes;
@@ -3709,6 +3713,11 @@
 
 TEST_P(GestureRecognizerTest,
        TransferEventDispatchesTouchCancel) {
+  // TODO(tdresser): enable this test with unified GR once two finger tap is
+  // supported. See crbug.com/354396.
+  if (UsingUnifiedGR())
+    return;
+
   scoped_ptr<GestureEventConsumeDelegate> delegate(
       new GestureEventConsumeDelegate());
   TimedEvents tes;
diff --git a/ui/aura/test/aura_test_helper.cc b/ui/aura/test/aura_test_helper.cc
index 34183db..78ad742 100644
--- a/ui/aura/test/aura_test_helper.cc
+++ b/ui/aura/test/aura_test_helper.cc
@@ -55,7 +55,7 @@
 void AuraTestHelper::SetUp() {
   setup_called_ = true;
 
-  Env::CreateInstance();
+  Env::CreateInstance(true);
   // Unit tests generally don't want to query the system, rather use the state
   // from RootWindow.
   EnvTestHelper(Env::GetInstance()).SetInputStateLookup(
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc
index a089435..3dc7432 100644
--- a/ui/aura/window_event_dispatcher.cc
+++ b/ui/aura/window_event_dispatcher.cc
@@ -495,11 +495,6 @@
   return (consumer_window && consumer_window->GetRootWindow() == window());
 }
 
-void WindowEventDispatcher::DispatchPostponedGestureEvent(
-    ui::GestureEvent* event) {
-  DispatchGestureEvent(event);
-}
-
 void WindowEventDispatcher::DispatchCancelTouchEvent(ui::TouchEvent* event) {
   DispatchDetails details = OnEventFromSource(event);
   if (details.dispatcher_destroyed)
diff --git a/ui/aura/window_event_dispatcher.h b/ui/aura/window_event_dispatcher.h
index 1a877f8..79ba3c7 100644
--- a/ui/aura/window_event_dispatcher.h
+++ b/ui/aura/window_event_dispatcher.h
@@ -72,11 +72,6 @@
 
   void DispatchCancelModeEvent();
 
-  // Handles a gesture event. Returns true if handled. Unlike the other
-  // event-dispatching function (e.g. for touch/mouse/keyboard events), gesture
-  // events are dispatched from GestureRecognizer instead of WindowTreeHost.
-  void DispatchGestureEvent(ui::GestureEvent* event);
-
   // Dispatches a ui::ET_MOUSE_EXITED event at |point|.
   // TODO(beng): needed only for WTH::OnCursorVisibilityChanged().
   void DispatchMouseExitAtPoint(const gfx::Point& point);
@@ -184,7 +179,7 @@
 
   // Overridden from ui::GestureEventHelper.
   virtual bool CanDispatchToConsumer(ui::GestureConsumer* consumer) OVERRIDE;
-  virtual void DispatchPostponedGestureEvent(ui::GestureEvent* event) OVERRIDE;
+  virtual void DispatchGestureEvent(ui::GestureEvent* event) OVERRIDE;
   virtual void DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE;
 
   // Overridden from WindowObserver:
diff --git a/ui/aura/window_targeter.cc b/ui/aura/window_targeter.cc
index a572094..7a32de5 100644
--- a/ui/aura/window_targeter.cc
+++ b/ui/aura/window_targeter.cc
@@ -18,32 +18,6 @@
 WindowTargeter::WindowTargeter() {}
 WindowTargeter::~WindowTargeter() {}
 
-bool WindowTargeter::WindowCanAcceptEvent(aura::Window* window,
-                                          const ui::LocatedEvent& event) const {
-  if (!window->IsVisible())
-    return false;
-  if (window->ignore_events())
-    return false;
-  client::EventClient* client = client::GetEventClient(window->GetRootWindow());
-  if (client && !client->CanProcessEventsWithinSubtree(window))
-    return false;
-
-  Window* parent = window->parent();
-  if (parent && parent->delegate_ && !parent->delegate_->
-      ShouldDescendIntoChildForEventHandling(window, event.location())) {
-    return false;
-  }
-  return true;
-}
-
-bool WindowTargeter::EventLocationInsideBounds(
-    aura::Window* window, const ui::LocatedEvent& event) const {
-  gfx::Point point = event.location();
-  if (window->parent())
-    aura::Window::ConvertPointToTarget(window->parent(), window, &point);
-  return gfx::Rect(window->bounds().size()).Contains(point);
-}
-
 ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root,
                                                     ui::Event* event) {
   Window* window = static_cast<Window*>(root);
@@ -64,14 +38,34 @@
   return target;
 }
 
-bool WindowTargeter::SubtreeShouldBeExploredForEvent(
-    ui::EventTarget* root,
-    const ui::LocatedEvent& event) {
-  Window* window = static_cast<Window*>(root);
-  if (!WindowCanAcceptEvent(window, event))
+bool WindowTargeter::SubtreeCanAcceptEvent(
+    ui::EventTarget* target,
+    const ui::LocatedEvent& event) const {
+  aura::Window* window = static_cast<aura::Window*>(target);
+  if (!window->IsVisible())
+    return false;
+  if (window->ignore_events())
+    return false;
+  client::EventClient* client = client::GetEventClient(window->GetRootWindow());
+  if (client && !client->CanProcessEventsWithinSubtree(window))
     return false;
 
-  return EventLocationInsideBounds(window, event);
+  Window* parent = window->parent();
+  if (parent && parent->delegate_ && !parent->delegate_->
+      ShouldDescendIntoChildForEventHandling(window, event.location())) {
+    return false;
+  }
+  return true;
+}
+
+bool WindowTargeter::EventLocationInsideBounds(
+    ui::EventTarget* target,
+    const ui::LocatedEvent& event) const {
+  aura::Window* window = static_cast<aura::Window*>(target);
+  gfx::Point point = event.location();
+  if (window->parent())
+    aura::Window::ConvertPointToTarget(window->parent(), window, &point);
+  return gfx::Rect(window->bounds().size()).Contains(point);
 }
 
 ui::EventTarget* WindowTargeter::FindTargetForLocatedEvent(
diff --git a/ui/aura/window_targeter.h b/ui/aura/window_targeter.h
index 0b0acb3..e64ef75 100644
--- a/ui/aura/window_targeter.h
+++ b/ui/aura/window_targeter.h
@@ -18,24 +18,18 @@
   virtual ~WindowTargeter();
 
  protected:
-  bool WindowCanAcceptEvent(aura::Window* window,
-                            const ui::LocatedEvent& event) const;
-
-  // Returns whether the location of the event is in an actionable region of the
-  // window. Note that the location etc. of |event| is in the |window|'s
-  // parent's coordinate system.
-  virtual bool EventLocationInsideBounds(aura::Window* window,
-                                         const ui::LocatedEvent& event) const;
-
   // ui::EventTargeter:
   virtual ui::EventTarget* FindTargetForEvent(ui::EventTarget* root,
                                               ui::Event* event) OVERRIDE;
   virtual ui::EventTarget* FindTargetForLocatedEvent(
       ui::EventTarget* root,
       ui::LocatedEvent* event) OVERRIDE;
-  virtual bool SubtreeShouldBeExploredForEvent(
+  virtual bool SubtreeCanAcceptEvent(
       ui::EventTarget* target,
-      const ui::LocatedEvent& event) OVERRIDE;
+      const ui::LocatedEvent& event) const OVERRIDE;
+  virtual bool EventLocationInsideBounds(
+      ui::EventTarget* target,
+      const ui::LocatedEvent& event) const OVERRIDE;
 
  private:
   Window* FindTargetForKeyEvent(Window* root_window,
diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc
index 39f4c95..2118c2e 100644
--- a/ui/aura/window_tree_host.cc
+++ b/ui/aura/window_tree_host.cc
@@ -178,7 +178,6 @@
 }
 
 void WindowTreeHost::DestroyCompositor() {
-  DCHECK(GetAcceleratedWidget());
   compositor_.reset();
 }
 
diff --git a/ui/aura/window_tree_host_ozone.cc b/ui/aura/window_tree_host_ozone.cc
index 44514d0..5b4a29f 100644
--- a/ui/aura/window_tree_host_ozone.cc
+++ b/ui/aura/window_tree_host_ozone.cc
@@ -40,8 +40,9 @@
 bool WindowTreeHostOzone::CanDispatchEvent(const ui::PlatformEvent& ne) {
   CHECK(ne);
   ui::Event* event = static_cast<ui::Event*>(ne);
-  if (event->IsMouseEvent() || event->IsScrollEvent() || event->IsTouchEvent())
-    return bounds_.Contains(static_cast<ui::LocatedEvent*>(event)->location());
+  if (event->IsMouseEvent() || event->IsScrollEvent())
+    return ui::CursorFactoryOzone::GetInstance()->GetCursorWindow() == widget_;
+
   return true;
 }
 
diff --git a/ui/aura/window_tree_host_x11.cc b/ui/aura/window_tree_host_x11.cc
index 5fec30c..b6d5876 100644
--- a/ui/aura/window_tree_host_x11.cc
+++ b/ui/aura/window_tree_host_x11.cc
@@ -56,10 +56,6 @@
   "WM_DELETE_WINDOW",
   "_NET_WM_PING",
   "_NET_WM_PID",
-  "WM_S0",
-#if defined(OS_CHROMEOS)
-  "Tap Paused",  // Defined in the gestures library.
-#endif
   NULL
 };
 
@@ -172,6 +168,9 @@
                   PropModeReplace,
                   reinterpret_cast<unsigned char*>(&pid), 1);
 
+  // Allow subclasses to create and cache additional atoms.
+  atom_cache_.allow_uncached_atoms();
+
   XRRSelectInput(xdisplay_, x_root_window_,
                  RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
   CreateCompositor(GetAcceleratedWidget());
@@ -574,13 +573,6 @@
     XFreeEventData(xev->xgeneric.display, &last_event.xcookie);
 }
 
-bool WindowTreeHostX11::IsWindowManagerPresent() {
-  // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
-  // of WM_Sn selections (where n is a screen number).
-  return XGetSelectionOwner(
-      xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
-}
-
 void WindowTreeHostX11::SetCursorInternal(gfx::NativeCursor cursor) {
   XDefineCursor(xdisplay_, xwindow_, cursor.platform());
 }
diff --git a/ui/aura/window_tree_host_x11.h b/ui/aura/window_tree_host_x11.h
index 31232b1..f09b28d 100644
--- a/ui/aura/window_tree_host_x11.h
+++ b/ui/aura/window_tree_host_x11.h
@@ -79,11 +79,6 @@
   // calibration).
   void DispatchXI2Event(const base::NativeEvent& event);
 
-  // Returns true if there's an X window manager present... in most cases.  Some
-  // window managers (notably, ion3) don't implement enough of ICCCM for us to
-  // detect that they're there.
-  bool IsWindowManagerPresent();
-
   // Sets the cursor on |xwindow_| to |cursor|.  Does not check or update
   // |current_cursor_|.
   void SetCursorInternal(gfx::NativeCursor cursor);
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index 10d920a..5093aa8 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -313,7 +313,6 @@
       "cursor/cursor_loader_x11.cc",
       "cursor/cursor_loader_x11.h",
       "cursor/cursor_mac.mm",
-      "cursor/cursor_win.cc",
       "cursor/cursor_x11.cc",
       "x/selection_owner.cc",
       "x/selection_owner.h",
@@ -380,6 +379,7 @@
     ]
   }
 
+  libs = []
   if (is_win) {
     deps += [
       "//third_party/wtl",
@@ -397,7 +397,7 @@
       "/DELAYLOAD:d3d10_1.dll",
       "/DELAYLOAD:dwmapi.dll",
     ]
-    libs = [
+    libs += [
       "d2d1.lib",
       "d3d10_1.lib",
       "dwmapi.lib",
@@ -474,7 +474,7 @@
       #":ui_base_jni_headers",
     ]
 
-    libs = [
+    libs += [
       "jnigraphics",
     ]
   }
@@ -512,3 +512,31 @@
     #'hard_dependency': 1,
   #}
 }
+
+source_set("ui_base_test_support") {
+  sources = [
+    "test/ui_controls.h",
+    "test/ui_controls_aura.cc",
+    "test/ui_controls_internal_win.cc",
+    "test/ui_controls_internal_win.h",
+    "test/ui_controls_mac.mm",
+    "test/ui_controls_win.cc",
+  ]
+
+  deps = [
+    "//base",
+    "//skia",
+    "//testing/gtest",
+    "//ui/gfx",
+    "//ui/gfx/geometry",
+  ]
+
+  if (!is_ios) {
+    sources += [
+      "ime/dummy_input_method.cc",
+      "ime/dummy_input_method.h",
+      "ime/dummy_text_input_client.cc",
+      "ime/dummy_text_input_client.h",
+    ]
+  }
+}
diff --git a/ui/base/clipboard/clipboard_aurax11.cc b/ui/base/clipboard/clipboard_aurax11.cc
index 71739df..77c19c1 100644
--- a/ui/base/clipboard/clipboard_aurax11.cc
+++ b/ui/base/clipboard/clipboard_aurax11.cc
@@ -15,6 +15,7 @@
 #include "base/memory/ref_counted_memory.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/singleton.h"
+#include "base/metrics/histogram.h"
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -35,17 +36,21 @@
 namespace {
 
 const char kClipboard[] = "CLIPBOARD";
+const char kClipboardManager[] = "CLIPBOARD_MANAGER";
 const char kMimeTypeFilename[] = "chromium/filename";
 const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data";
 const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste";
+const char kSaveTargets[] = "SAVE_TARGETS";
 const char kTargets[] = "TARGETS";
 
 const char* kAtomsToCache[] = {
   kClipboard,
+  kClipboardManager,
   Clipboard::kMimeTypePNG,
   kMimeTypeFilename,
   kMimeTypeMozillaURL,
   kMimeTypeWebkitSmartPaste,
+  kSaveTargets,
   kString,
   kTargets,
   kText,
@@ -232,6 +237,10 @@
   // given type.
   ::Atom LookupSelectionForClipboardType(ClipboardType type) const;
 
+  // Returns the X11 type that we pass to various XSelection functions for
+  // CLIPBOARD_TYPE_COPY_PASTE.
+  ::Atom GetCopyPasteSelection() const;
+
   // Returns the object which is responsible for communication on |type|.
   SelectionRequestor* GetSelectionRequestorForClipboardType(ClipboardType type);
 
@@ -278,6 +287,10 @@
   // Clears a certain clipboard type, whether we own it or not.
   void Clear(ClipboardType type);
 
+  // If we own the CLIPBOARD selection, requests the clipboard manager to take
+  // ownership of it.
+  void StoreCopyPasteDataAndWait();
+
  private:
   // PlatformEventDispatcher:
   virtual bool CanDispatchEvent(const PlatformEvent& event) OVERRIDE;
@@ -295,6 +308,7 @@
   // Objects which request and receive selection data.
   SelectionRequestor clipboard_requestor_;
   SelectionRequestor primary_requestor_;
+  SelectionRequestor clipboard_manager_requestor_;
 
   // Temporary target map that we write to during DispatchObects.
   SelectionFormatMap clipboard_data_;
@@ -320,8 +334,11 @@
           NULL)),
       atom_cache_(x_display_, kAtomsToCache),
       clipboard_requestor_(x_display_, x_window_,
-                           atom_cache_.GetAtom(kClipboard)),
-      primary_requestor_(x_display_, x_window_, XA_PRIMARY),
+                           atom_cache_.GetAtom(kClipboard), this),
+      primary_requestor_(x_display_, x_window_, XA_PRIMARY, this),
+      clipboard_manager_requestor_(x_display_, x_window_,
+                                   atom_cache_.GetAtom(kClipboardManager),
+                                   this),
       clipboard_owner_(x_display_, x_window_, atom_cache_.GetAtom(kClipboard)),
       primary_owner_(x_display_, x_window_, XA_PRIMARY) {
   // We don't know all possible MIME types at compile time.
@@ -344,17 +361,21 @@
 ::Atom Clipboard::AuraX11Details::LookupSelectionForClipboardType(
     ClipboardType type) const {
   if (type == CLIPBOARD_TYPE_COPY_PASTE)
-    return atom_cache_.GetAtom(kClipboard);
+    return GetCopyPasteSelection();
 
   return XA_PRIMARY;
 }
 
+::Atom Clipboard::AuraX11Details::GetCopyPasteSelection() const {
+  return atom_cache_.GetAtom(kClipboard);
+}
+
 const SelectionFormatMap& Clipboard::AuraX11Details::LookupStorageForAtom(
     ::Atom atom) {
   if (atom == XA_PRIMARY)
     return primary_owner_.selection_format_map();
 
-  DCHECK_EQ(atom_cache_.GetAtom(kClipboard), atom);
+  DCHECK_EQ(GetCopyPasteSelection(), atom);
   return clipboard_owner_.selection_format_map();
 }
 
@@ -485,6 +506,27 @@
     primary_owner_.ClearSelectionOwner();
 }
 
+void Clipboard::AuraX11Details::StoreCopyPasteDataAndWait() {
+  ::Atom selection = GetCopyPasteSelection();
+  if (XGetSelectionOwner(x_display_, selection) != x_window_)
+    return;
+
+  ::Atom clipboard_manager_atom = atom_cache_.GetAtom(kClipboardManager);
+  if (XGetSelectionOwner(x_display_, clipboard_manager_atom) == None)
+    return;
+
+  const SelectionFormatMap& format_map = LookupStorageForAtom(selection);
+  if (format_map.size() == 0)
+    return;
+  std::vector<Atom> targets = format_map.GetTypes();
+
+  base::TimeTicks start = base::TimeTicks::Now();
+  clipboard_manager_requestor_.PerformBlockingConvertSelectionWithParameter(
+      atom_cache_.GetAtom(kSaveTargets), targets);
+  UMA_HISTOGRAM_TIMES("Clipboard.X11StoreCopyPasteDuration",
+                      base::TimeTicks::Now() - start);
+}
+
 bool Clipboard::AuraX11Details::CanDispatchEvent(const PlatformEvent& event) {
   return event->xany.window == x_window_;
 }
@@ -492,24 +534,35 @@
 uint32_t Clipboard::AuraX11Details::DispatchEvent(const PlatformEvent& xev) {
   switch (xev->type) {
     case SelectionRequest: {
-      if (xev->xselectionrequest.selection == XA_PRIMARY)
+      if (xev->xselectionrequest.selection == XA_PRIMARY) {
         primary_owner_.OnSelectionRequest(xev->xselectionrequest);
-      else
+      } else {
+        // We should not get requests for the CLIPBOARD_MANAGER selection
+        // because we never take ownership of it.
+        DCHECK_EQ(GetCopyPasteSelection(), xev->xselectionrequest.selection);
         clipboard_owner_.OnSelectionRequest(xev->xselectionrequest);
+      }
       break;
     }
     case SelectionNotify: {
-      if (xev->xselection.selection == XA_PRIMARY)
+      ::Atom selection = xev->xselection.selection;
+      if (selection == XA_PRIMARY)
         primary_requestor_.OnSelectionNotify(xev->xselection);
-      else
+      else if (selection == GetCopyPasteSelection())
         clipboard_requestor_.OnSelectionNotify(xev->xselection);
+      else if (selection == atom_cache_.GetAtom(kClipboardManager))
+        clipboard_manager_requestor_.OnSelectionNotify(xev->xselection);
       break;
     }
     case SelectionClear: {
-      if (xev->xselectionclear.selection == XA_PRIMARY)
+      if (xev->xselectionclear.selection == XA_PRIMARY) {
         primary_owner_.OnSelectionClear(xev->xselectionclear);
-      else
+      } else {
+        // We should not get requests for the CLIPBOARD_MANAGER selection
+        // because we never take ownership of it.
+        DCHECK_EQ(GetCopyPasteSelection(), xev->xselection.selection);
         clipboard_owner_.OnSelectionClear(xev->xselectionclear);
+        }
       break;
     }
     default:
@@ -530,9 +583,7 @@
 Clipboard::~Clipboard() {
   DCHECK(CalledOnValidThread());
 
-  // TODO(erg): We need to do whatever the equivalent of
-  // gtk_clipboard_store(clipboard_) is here. When we shut down, we want the
-  // current selection to live on.
+  aurax11_details_->StoreCopyPasteDataAndWait();
 }
 
 void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) {
diff --git a/ui/base/cursor/ozone/cursor_factory_ozone.cc b/ui/base/cursor/ozone/cursor_factory_ozone.cc
index 46c1da3..709412e 100644
--- a/ui/base/cursor/ozone/cursor_factory_ozone.cc
+++ b/ui/base/cursor/ozone/cursor_factory_ozone.cc
@@ -47,4 +47,9 @@
   NOTIMPLEMENTED();
 }
 
+gfx::AcceleratedWidget CursorFactoryOzone::GetCursorWindow() {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
 }  // namespace ui
diff --git a/ui/base/cursor/ozone/cursor_factory_ozone.h b/ui/base/cursor/ozone/cursor_factory_ozone.h
index 8ea2e74..ac18a50 100644
--- a/ui/base/cursor/ozone/cursor_factory_ozone.h
+++ b/ui/base/cursor/ozone/cursor_factory_ozone.h
@@ -43,6 +43,11 @@
   // TODO(spang): Move this.
   virtual void SetCursor(gfx::AcceleratedWidget widget, PlatformCursor cursor);
 
+  // Returns the window on which the cursor is active.
+  // TODO(dnicoara) Move this once the WindowTreeHost refactoring finishes and
+  // WindowTreeHost::CanDispatchEvent() is no longer present.
+  virtual gfx::AcceleratedWidget GetCursorWindow();
+
  private:
   static CursorFactoryOzone* impl_;  // not owned
 };
diff --git a/ui/base/ime/ime.gypi b/ui/base/ime/ime.gypi
index f3b08bb..c76989f 100644
--- a/ui/base/ime/ime.gypi
+++ b/ui/base/ime/ime.gypi
@@ -61,6 +61,8 @@
     'remote_input_method_win.h',
     'text_input_client.cc',
     'text_input_client.h',
+    'text_input_focus_manager.cc',
+    'text_input_focus_manager.h',
     'text_input_type.h',
     'win/imm32_manager.cc',
     'win/imm32_manager.h',
diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc
index d3b561c..5391f54 100644
--- a/ui/base/ime/input_method_base.cc
+++ b/ui/base/ime/input_method_base.cc
@@ -10,6 +10,8 @@
 #include "ui/base/ime/input_method_delegate.h"
 #include "ui/base/ime/input_method_observer.h"
 #include "ui/base/ime/text_input_client.h"
+#include "ui/base/ime/text_input_focus_manager.h"
+#include "ui/base/ui_base_switches_util.h"
 #include "ui/events/event.h"
 
 namespace ui {
@@ -56,6 +58,9 @@
 }
 
 TextInputClient* InputMethodBase::GetTextInputClient() const {
+  if (switches::IsTextInputFocusManagerEnabled())
+    return TextInputFocusManager::GetInstance()->GetFocusedTextInputClient();
+
   return system_toplevel_window_focused_ ? text_input_client_ : NULL;
 }
 
@@ -123,6 +128,9 @@
 
 void InputMethodBase::SetFocusedTextInputClientInternal(
     TextInputClient* client) {
+  if (switches::IsTextInputFocusManagerEnabled())
+    return;
+
   TextInputClient* old = text_input_client_;
   if (old == client)
     return;
diff --git a/ui/base/ime/text_input_focus_manager.cc b/ui/base/ime/text_input_focus_manager.cc
new file mode 100644
index 0000000..4fd7dcf
--- /dev/null
+++ b/ui/base/ime/text_input_focus_manager.cc
@@ -0,0 +1,41 @@
+// 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.
+
+#include "ui/base/ime/text_input_focus_manager.h"
+
+#include "base/logging.h"
+#include "base/memory/singleton.h"
+
+namespace ui {
+
+TextInputFocusManager* TextInputFocusManager::GetInstance() {
+  TextInputFocusManager* instance = Singleton<TextInputFocusManager>::get();
+  DCHECK(instance->thread_checker_.CalledOnValidThread());
+  return instance;
+}
+
+TextInputClient* TextInputFocusManager::GetFocusedTextInputClient() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  return focused_text_input_client_;
+}
+
+void TextInputFocusManager::FocusTextInputClient(
+    TextInputClient* text_input_client) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  focused_text_input_client_ = text_input_client;
+}
+
+void TextInputFocusManager::BlurTextInputClient(
+    TextInputClient* text_input_client) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  if (focused_text_input_client_ == text_input_client)
+    focused_text_input_client_ = NULL;
+}
+
+TextInputFocusManager::TextInputFocusManager()
+    : focused_text_input_client_(NULL) {}
+
+TextInputFocusManager::~TextInputFocusManager() {}
+
+}  // namespace ui
diff --git a/ui/base/ime/text_input_focus_manager.h b/ui/base/ime/text_input_focus_manager.h
new file mode 100644
index 0000000..22f47e3
--- /dev/null
+++ b/ui/base/ime/text_input_focus_manager.h
@@ -0,0 +1,47 @@
+// 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.
+
+#ifndef UI_BASE_IME_TEXT_INPUT_FOCUS_MANAGER_H_
+#define UI_BASE_IME_TEXT_INPUT_FOCUS_MANAGER_H_
+
+#include "base/macros.h"
+#include "base/threading/thread_checker.h"
+#include "ui/base/ui_base_export.h"
+
+template <typename T> struct DefaultSingletonTraits;
+
+namespace ui {
+
+class TextInputClient;
+
+// Manages the focused TextInputClient across windows and their contents.
+class UI_BASE_EXPORT TextInputFocusManager {
+ public:
+  static TextInputFocusManager* GetInstance();
+
+  // Returns the currently focused text input client or NULL.
+  TextInputClient* GetFocusedTextInputClient();
+
+  // Changes the text input focus to |text_input_client|.
+  void FocusTextInputClient(TextInputClient* text_input_client);
+
+  // Removes the text input focus from |text_input_client|.  If
+  // |text_input_client| was not focused, does nothing.
+  void BlurTextInputClient(TextInputClient* text_input_client);
+
+ private:
+  friend struct DefaultSingletonTraits<TextInputFocusManager>;
+
+  TextInputFocusManager();
+  ~TextInputFocusManager();
+
+  TextInputClient* focused_text_input_client_;
+  base::ThreadChecker thread_checker_;
+
+  DISALLOW_COPY_AND_ASSIGN(TextInputFocusManager);
+};
+
+}  // namespace ui
+
+#endif  // UI_BASE_IME_TEXT_INPUT_FOCUS_MANAGER_H_
diff --git a/ui/base/l10n/l10n_util.cc b/ui/base/l10n/l10n_util.cc
index 70a1c20..44d8df5 100644
--- a/ui/base/l10n/l10n_util.cc
+++ b/ui/base/l10n/l10n_util.cc
@@ -505,7 +505,7 @@
   // the translation is available or not.  If ICU doesn't have a translated
   // name for this locale, GetDisplayNameForLocale will just return the
   // locale code.
-  return !IsStringASCII(display_name) ||
+  return !base::IsStringASCII(display_name) ||
       base::UTF16ToASCII(display_name) != locale;
 }
 
diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc
index e2a9144..f70a1f7 100644
--- a/ui/base/resource/resource_bundle.cc
+++ b/ui/base/resource/resource_bundle.cc
@@ -34,7 +34,6 @@
 #include "ui/gfx/safe_integer_conversions.h"
 #include "ui/gfx/screen.h"
 #include "ui/gfx/size_conversions.h"
-#include "ui/gfx/skbitmap_operations.h"
 
 #if defined(OS_CHROMEOS)
 #include "ui/base/l10n/l10n_util.h"
@@ -116,19 +115,6 @@
           skia::ImageOperations::RESIZE_LANCZOS3,
           gfx::ToCeiledInt(image.width() * scale),
           gfx::ToCeiledInt(image.height() * scale));
-      // If --highlight-missing-scaled-resources is specified, log the resource
-      // id and blend the created resource with red.
-      if (ShouldHighlightMissingScaledResources()) {
-        LOG(ERROR) << "Missing " << scale << "x scaled resource. id="
-                   << resource_id_;
-
-        SkBitmap mask;
-        mask.setConfig(SkBitmap::kARGB_8888_Config,
-                       image.width(), image.height());
-        mask.allocPixels();
-        mask.eraseColor(SK_ColorRED);
-        image = SkBitmapOperations::CreateBlendedBitmap(image, mask, 0.2);
-      }
     } else {
       image = PlatformScaleImage(image,
                                  ui::GetScaleForScaleFactor(scale_factor),
@@ -774,12 +760,6 @@
 }
 
 // static
-bool ResourceBundle::ShouldHighlightMissingScaledResources() {
-  return CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kHighlightMissingScaledResources);
-}
-
-// static
 bool ResourceBundle::PNGContainsFallbackMarker(const unsigned char* buf,
                                                size_t size) {
   if (size < arraysize(kPngMagic) ||
diff --git a/ui/base/resource/resource_bundle_ios.mm b/ui/base/resource/resource_bundle_ios.mm
index d947c2f..1f18967 100644
--- a/ui/base/resource/resource_bundle_ios.mm
+++ b/ui/base/resource/resource_bundle_ios.mm
@@ -151,14 +151,6 @@
       CGContextSetBlendMode(context, kCGBlendModeCopy);
       CGContextDrawImage(context, target_rect, [ui_image CGImage]);
 
-      if (ShouldHighlightMissingScaledResources()) {
-        CGContextSetFillColorSpace(context, color_space);
-        CGFloat components[4] = { 1.0, 0.0, 0.0, 0.3 };  // Translucent red.
-        CGContextSetFillColor(context, components);
-        CGContextSetBlendMode(context, kCGBlendModeNormal);
-        CGContextFillRect(context, target_rect);
-      }
-
       base::ScopedCFTypeRef<CGImageRef> cg_image(
           CGBitmapContextCreateImage(context));
       ui_image.reset([[UIImage alloc] initWithCGImage:cg_image
diff --git a/ui/base/strings/ui_strings.target.darwin-arm.mk b/ui/base/strings/ui_strings.target.darwin-arm.mk
index 4ba78a8..0dd972f 100644
--- a/ui/base/strings/ui_strings.target.darwin-arm.mk
+++ b/ui/base/strings/ui_strings.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_strings":
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -80,6 +81,7 @@
 
 ### Rules for action "app_locale_settings":
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/strings/ui_strings.target.darwin-arm64.mk b/ui/base/strings/ui_strings.target.darwin-arm64.mk
index 4ba78a8..0dd972f 100644
--- a/ui/base/strings/ui_strings.target.darwin-arm64.mk
+++ b/ui/base/strings/ui_strings.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_strings":
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -80,6 +81,7 @@
 
 ### Rules for action "app_locale_settings":
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/strings/ui_strings.target.darwin-mips.mk b/ui/base/strings/ui_strings.target.darwin-mips.mk
index 4ba78a8..0dd972f 100644
--- a/ui/base/strings/ui_strings.target.darwin-mips.mk
+++ b/ui/base/strings/ui_strings.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_strings":
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -80,6 +81,7 @@
 
 ### Rules for action "app_locale_settings":
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/strings/ui_strings.target.darwin-x86.mk b/ui/base/strings/ui_strings.target.darwin-x86.mk
index 4ba78a8..0dd972f 100644
--- a/ui/base/strings/ui_strings.target.darwin-x86.mk
+++ b/ui/base/strings/ui_strings.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_strings":
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -80,6 +81,7 @@
 
 ### Rules for action "app_locale_settings":
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/strings/ui_strings.target.darwin-x86_64.mk b/ui/base/strings/ui_strings.target.darwin-x86_64.mk
index 4ba78a8..0dd972f 100644
--- a/ui/base/strings/ui_strings.target.darwin-x86_64.mk
+++ b/ui/base/strings/ui_strings.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_strings":
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -80,6 +81,7 @@
 
 ### Rules for action "app_locale_settings":
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/strings/ui_strings.target.linux-arm.mk b/ui/base/strings/ui_strings.target.linux-arm.mk
index 4ba78a8..0dd972f 100644
--- a/ui/base/strings/ui_strings.target.linux-arm.mk
+++ b/ui/base/strings/ui_strings.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_strings":
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -80,6 +81,7 @@
 
 ### Rules for action "app_locale_settings":
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/strings/ui_strings.target.linux-arm64.mk b/ui/base/strings/ui_strings.target.linux-arm64.mk
index 4ba78a8..0dd972f 100644
--- a/ui/base/strings/ui_strings.target.linux-arm64.mk
+++ b/ui/base/strings/ui_strings.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_strings":
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -80,6 +81,7 @@
 
 ### Rules for action "app_locale_settings":
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/strings/ui_strings.target.linux-mips.mk b/ui/base/strings/ui_strings.target.linux-mips.mk
index 4ba78a8..0dd972f 100644
--- a/ui/base/strings/ui_strings.target.linux-mips.mk
+++ b/ui/base/strings/ui_strings.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_strings":
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -80,6 +81,7 @@
 
 ### Rules for action "app_locale_settings":
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/strings/ui_strings.target.linux-x86.mk b/ui/base/strings/ui_strings.target.linux-x86.mk
index 4ba78a8..0dd972f 100644
--- a/ui/base/strings/ui_strings.target.linux-x86.mk
+++ b/ui/base/strings/ui_strings.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_strings":
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -80,6 +81,7 @@
 
 ### Rules for action "app_locale_settings":
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/strings/ui_strings.target.linux-x86_64.mk b/ui/base/strings/ui_strings.target.linux-x86_64.mk
index 4ba78a8..0dd972f 100644
--- a/ui/base/strings/ui_strings.target.linux-x86_64.mk
+++ b/ui/base/strings/ui_strings.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_strings":
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_strings/grit/ui_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -80,6 +81,7 @@
 
 ### Rules for action "app_locale_settings":
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/app_locale_settings/grit/app_locale_settings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/strings/ui_strings_am.xtb b/ui/base/strings/ui_strings_am.xtb
index b2bc258..080f3ad 100644
--- a/ui/base/strings/ui_strings_am.xtb
+++ b/ui/base/strings/ui_strings_am.xtb
@@ -32,15 +32,15 @@
 <translation id="9038489124413477075">ያልተሰየመ አቃፊ</translation>
 <translation id="1940483897317142625">ወደ የመስመር መጨረሻ ሰርዝ</translation>
 <translation id="8507996248087185956"><ph name="NUMBER_DEFAULT"/> ደቂቃ</translation>
-<translation id="3520476450377425184"><ph name="NUMBER_MANY"/> ቀናት ይቀራሉ</translation>
+<translation id="3520476450377425184"><ph name="NUMBER_MANY"/> ቀኖች ይቀራሉ</translation>
 <translation id="932327136139879170">መነሻ</translation>
 <translation id="5600907569873192868"><ph name="NUMBER_MANY"/> ደቂቃ ይቀራል</translation>
-<translation id="8666066831007952346"><ph name="NUMBER_TWO"/> ቀናት ይቀራሉ</translation>
+<translation id="8666066831007952346"><ph name="NUMBER_TWO"/> ቀኖች ይቀራሉ</translation>
 <translation id="6390842777729054533">ከ<ph name="NUMBER_ZERO"/> ሴኮንድ በፊት</translation>
 <translation id="3909791450649380159">&amp;ቁረጥ</translation>
 <translation id="2560788951337264832"><ph name="NUMBER_ZERO"/> ደቂቃዎች ቀርተዋል</translation>
 <translation id="688711909580084195">ርዕስ-አልባ ድረ-ገጽ</translation>
-<translation id="3353284378027041011">ከ<ph name="NUMBER_FEW"/> ቀናት በፊት</translation>
+<translation id="3353284378027041011">ከ<ph name="NUMBER_FEW"/> ቀኖች በፊት</translation>
 <translation id="5076340679995252485">&amp;ለጥፍ</translation>
 <translation id="7460907917090416791"><ph name="QUANTITY"/> ቴባ</translation>
 <translation id="7139614227326422685">ቃል ወደ ቀኝ ውሰድ</translation>
@@ -65,7 +65,7 @@
 <translation id="7836361698254323868"><ph name="NUMBER_ONE"/> ደቂቃ ቀርቷል</translation>
 <translation id="2953767478223974804"><ph name="NUMBER_ONE"/> ደቂቃ</translation>
 <translation id="8210608804940886430">ወደታች አንቀሳቅስ</translation>
-<translation id="1572103024875503863"><ph name="NUMBER_MANY"/> ቀናት</translation>
+<translation id="1572103024875503863"><ph name="NUMBER_MANY"/> ቀኖች</translation>
 <translation id="7163503212501929773"><ph name="NUMBER_MANY"/> ሰዓቶች ይቀራሉ</translation>
 <translation id="5329858601952122676">&amp;ሠርዝ</translation>
 <translation id="6556866813142980365">ድገም</translation>
@@ -125,7 +125,7 @@
 <translation id="2148716181193084225">ዛሬ</translation>
 <translation id="7960078400008666149">ለአንድ ሰዓት አትረብሽ</translation>
 <translation id="4373894838514502496">ከ<ph name="NUMBER_FEW"/> ደቂቃ በፊት</translation>
-<translation id="4115153316875436289"><ph name="NUMBER_TWO"/> ቀናት</translation>
+<translation id="4115153316875436289"><ph name="NUMBER_TWO"/> ቀኖች</translation>
 <translation id="2190355936436201913">(ባዶ)</translation>
 <translation id="1164369517022005061"><ph name="NUMBER_DEFAULT"/> ሰዓት ይቀራል</translation>
 <translation id="152482086482215392"><ph name="NUMBER_ONE"/> ሴኮንድ ይቀራል</translation>
@@ -166,8 +166,8 @@
 <translation id="5368780922436099921"><ph name="NUMBER_ZERO"/> ሰከንዶች ቀርተዋል</translation>
 <translation id="1095623615273566396"><ph name="NUMBER_FEW"/> ሴኮንድ</translation>
 <translation id="5583640892426849032">Backspace</translation>
-<translation id="5263972071113911534">ከ<ph name="NUMBER_MANY"/> ቀናት በፊት</translation>
-<translation id="8355915647418390920"><ph name="NUMBER_FEW"/> ቀናት</translation>
+<translation id="5263972071113911534">ከ<ph name="NUMBER_MANY"/> ቀኖች በፊት</translation>
+<translation id="8355915647418390920"><ph name="NUMBER_FEW"/> ቀኖች</translation>
 <translation id="5116333507878097773"><ph name="NUMBER_ONE"/> ሰዓት</translation>
 <translation id="2679312662830811292">ከ<ph name="NUMBER_ONE"/> ደቂቃ በፊት</translation>
 <translation id="8788572795284305350">ከ<ph name="NUMBER_ZERO"/> ሰዓት በፊት</translation>
@@ -177,7 +177,7 @@
 <translation id="9098468523912235228">ከ<ph name="NUMBER_DEFAULT"/> ሴኮንድ በፊት</translation>
 <translation id="494645311413743213"><ph name="NUMBER_TWO"/> ሴኮንድ ይቀራል</translation>
 <translation id="4570886800634958009">ማሳወቂያ ዘርጋ</translation>
-<translation id="566737009157135450">ወደኋላ ሰርዝ</translation>
+<translation id="566737009157135450">ቃለል ወደኋላ ሰርዝ</translation>
 <translation id="436869212180315161">ተጫን</translation>
 <translation id="4860787810836767172">ከ<ph name="NUMBER_FEW"/> ሴኮንድ በፊት</translation>
 <translation id="2297836609126180313"><ph name="QUANTITY"/> ቴባ/ሰ</translation>
@@ -193,7 +193,7 @@
 <translation id="8226233771743600312">ለአንድ ቀን አትረብሽ</translation>
 <translation id="4252565523989510616">ቃል ወደፊት ሰርዝ</translation>
 <translation id="7457942297256758195">ሁሉንም አጽዳ</translation>
-<translation id="822618367988303761">ከ<ph name="NUMBER_TWO"/> ቀናት በፊት</translation>
+<translation id="822618367988303761">ከ<ph name="NUMBER_TWO"/> ቀኖች በፊት</translation>
 <translation id="4745438305783437565"><ph name="NUMBER_FEW"/> ደቂቃ</translation>
 <translation id="1963692530539281474"><ph name="NUMBER_DEFAULT"/> ቀን ይቀራል</translation>
 <translation id="7509440305564869263"><ph name="NUMBER_FEW"/> ደቂቃዎች</translation>
diff --git a/ui/base/strings/ui_strings_fa.xtb b/ui/base/strings/ui_strings_fa.xtb
index a436c03..b7a5a4d 100644
--- a/ui/base/strings/ui_strings_fa.xtb
+++ b/ui/base/strings/ui_strings_fa.xtb
@@ -109,7 +109,7 @@
 <translation id="7363290921156020669"><ph name="NUMBER_ZERO"/> mins</translation>
 <translation id="9107059250669762581"><ph name="NUMBER_DEFAULT"/> روز</translation>
 <translation id="6463061331681402734"><ph name="NUMBER_MANY"/> mins</translation>
-<translation id="6122334925474904337">خرکت به کلمه راست و اصلاح انتخاب</translation>
+<translation id="6122334925474904337">حرکت به کلمه راست و اصلاح انتخاب</translation>
 <translation id="7634624804467787019"><ph name="NUMBER_ONE"/> دقیقه</translation>
 <translation id="8448317557906454022"><ph name="NUMBER_ZERO"/> secs ago</translation>
 <translation id="4927753642311223124">اینجا خبری نیست، برگردید.</translation>
diff --git a/ui/base/strings/ui_strings_iw.xtb b/ui/base/strings/ui_strings_iw.xtb
index f39dfc8..3a82c41 100644
--- a/ui/base/strings/ui_strings_iw.xtb
+++ b/ui/base/strings/ui_strings_iw.xtb
@@ -43,7 +43,7 @@
 <translation id="3353284378027041011">לפני <ph name="NUMBER_FEW"/> ימים</translation>
 <translation id="5076340679995252485">&amp;הדבק</translation>
 <translation id="7460907917090416791"><ph name="QUANTITY"/> TB</translation>
-<translation id="7139614227326422685">העבר את המילה ימינה</translation>
+<translation id="7139614227326422685">עבור ימינה למילה</translation>
 <translation id="364720409959344976">בחירת תיקיה להעלאה</translation>
 <translation id="4999762576397546063">Ctrl+<ph name="KEY_COMBO_NAME"/></translation>
 <translation id="7770995925463083016">לפני <ph name="NUMBER_TWO"/> דקות</translation>
@@ -77,7 +77,7 @@
 <translation id="3424538384153559412"><ph name="NUMBER_TWO"/> דקות</translation>
 <translation id="50960180632766478">נותרו <ph name="NUMBER_FEW"/> דקות</translation>
 <translation id="5517291721709019259">נותרו <ph name="NUMBER_FEW"/> שניות</translation>
-<translation id="6903282483217634857">העבר ימינה</translation>
+<translation id="6903282483217634857">עבור ימינה</translation>
 <translation id="6659594942844771486">Tab</translation>
 <translation id="3049748772180311791"><ph name="QUANTITY"/> MB</translation>
 <translation id="4988273303304146523">לפני <ph name="NUMBER_DEFAULT"/> ימים</translation>
@@ -96,20 +96,20 @@
 <translation id="290555789621781773"><ph name="NUMBER_TWO"/> דקות</translation>
 <translation id="5149131957118398098"><ph name="NUMBER_ZERO"/> hours left</translation>
 <translation id="7135556860107312402">אפשר התראות ממקורות אלה:</translation>
-<translation id="2479520428668657293">העבר ימינה ושנה את הבחירה</translation>
+<translation id="2479520428668657293">עבור ימינה ושנה את הבחירה</translation>
 <translation id="8112886015144590373"><ph name="NUMBER_FEW"/> שעות</translation>
 <translation id="1398853756734560583">הגדל</translation>
 <translation id="4250229828105606438">צילום מסך</translation>
 <translation id="6690744523875189208"><ph name="NUMBER_TWO"/> שעות</translation>
 <translation id="5260878308685146029"><ph name="NUMBER_TWO"/> דקות נותרו</translation>
-<translation id="2557207087669398617">העבר לתחילת השורה</translation>
+<translation id="2557207087669398617">עבור לתחילת השורה</translation>
 <translation id="3757388668994797779"><ph name="QUANTITY"/> GB</translation>
 <translation id="1901303067676059328">בחר &amp;הכל</translation>
 <translation id="2168039046890040389">דף למעלה</translation>
 <translation id="7363290921156020669"><ph name="NUMBER_ZERO"/> mins</translation>
 <translation id="9107059250669762581"><ph name="NUMBER_DEFAULT"/> ימים</translation>
 <translation id="6463061331681402734"><ph name="NUMBER_MANY"/> דקות</translation>
-<translation id="6122334925474904337">העבר את המילה ימינה ושנה את הבחירה</translation>
+<translation id="6122334925474904337">עבור ימינה למילה ושנה את הבחירה</translation>
 <translation id="7634624804467787019"><ph name="NUMBER_ONE"/> דקה</translation>
 <translation id="8448317557906454022">לפני <ph name="NUMBER_ZERO"/> שניות</translation>
 <translation id="4927753642311223124">אין התראות להצגה, המשך הלאה.</translation>
@@ -117,7 +117,7 @@
 <translation id="6357135709975569075"><ph name="NUMBER_ZERO"/> days</translation>
 <translation id="3183922693828471536">גלול ל'כאן'</translation>
 <translation id="4552416320897244156">דף למטה</translation>
-<translation id="3066573403916685335">העבר למטה</translation>
+<translation id="3066573403916685335">רד למטה</translation>
 <translation id="7052633198403197513">F1</translation>
 <translation id="2052389551707911401"><ph name="NUMBER_MANY"/> שעות</translation>
 <translation id="8677655579646609597"><ph name="QUANTITY"/> KB/s‎</translation>
@@ -134,8 +134,8 @@
 <translation id="7414887922320653780">נותרו <ph name="NUMBER_ONE"/> שעות</translation>
 <translation id="1413622004203049571">השבת הודעות מאת <ph name="NOTIFIER_NAME"/></translation>
 <translation id="2666092431469916601">למעלה</translation>
-<translation id="2538759511191347839">העבר לסוף השורה ושנה את הבחירה</translation>
-<translation id="928465423150706909">העבר לסוף השורה</translation>
+<translation id="2538759511191347839">עבור לסוף השורה ושנה את הבחירה</translation>
+<translation id="928465423150706909">עבור לסוף השורה</translation>
 <translation id="8331626408530291785">גלול למעלה</translation>
 <translation id="7907591526440419938">פתח קובץ</translation>
 <translation id="2864069933652346933"><ph name="NUMBER_ZERO"/> days left</translation>
@@ -145,12 +145,12 @@
 <translation id="6808150112686056157">עצור מדיה</translation>
 <translation id="1308727876662951186"><ph name="NUMBER_ZERO"/> mins left</translation>
 <translation id="3157931365184549694">שחזר</translation>
-<translation id="5349525451964472598">העבר שמאלה ושנה את הבחירה</translation>
-<translation id="1781701194097416995">העבר את המילה שמאלה</translation>
+<translation id="5349525451964472598">עבור שמאלה ושנה את הבחירה</translation>
+<translation id="1781701194097416995">עבור שמאלה למילה</translation>
 <translation id="1243314992276662751">העלה</translation>
 <translation id="50030952220075532">נותר יום <ph name="NUMBER_ONE"/></translation>
 <translation id="8179976553408161302">היכנס</translation>
-<translation id="8471049483003785219">העבר את המילה שמאלה ושנה את הבחירה</translation>
+<translation id="8471049483003785219">עבור שמאלה למילה ושנה את הבחירה</translation>
 <translation id="945522503751344254">שלח משוב</translation>
 <translation id="9170848237812810038">&amp;ביטול</translation>
 <translation id="1285266685456062655">לפני <ph name="NUMBER_FEW"/> שעות</translation>
@@ -173,11 +173,11 @@
 <translation id="8788572795284305350"><ph name="NUMBER_ZERO"/> hours ago</translation>
 <translation id="3740362395218339114"><ph name="QUANTITY"/> GB/s</translation>
 <translation id="6644971472240498405">יום <ph name="NUMBER_ONE"/></translation>
-<translation id="2704295676501803339">העבר שמאלה</translation>
+<translation id="2704295676501803339">עבור שמאלה</translation>
 <translation id="9098468523912235228">לפני <ph name="NUMBER_DEFAULT"/> שניות</translation>
 <translation id="494645311413743213"><ph name="NUMBER_TWO"/> שניות נותרו</translation>
 <translation id="4570886800634958009">הרחבת הודעה</translation>
-<translation id="566737009157135450">מחק את המילה לאחור</translation>
+<translation id="566737009157135450">מחק מילה אחת לאחור</translation>
 <translation id="436869212180315161">לחץ</translation>
 <translation id="4860787810836767172">לפני <ph name="NUMBER_FEW"/> שניות</translation>
 <translation id="2297836609126180313"><ph name="QUANTITY"/> TB/s</translation>
@@ -191,7 +191,7 @@
 <translation id="6699343763173986273">הרצועה הבאה במדיה</translation>
 <translation id="5445120697129764393">נותרו <ph name="NUMBER_DEFAULT"/> שניות</translation>
 <translation id="8226233771743600312">נא לא להפריע ליום אחד</translation>
-<translation id="4252565523989510616">מחק את המילה קדימה</translation>
+<translation id="4252565523989510616">מחק מילה אחת קדימה</translation>
 <translation id="7457942297256758195">נקה הכל</translation>
 <translation id="822618367988303761">לפני <ph name="NUMBER_TWO"/> ימים</translation>
 <translation id="4745438305783437565"><ph name="NUMBER_FEW"/> דקות</translation>
@@ -207,7 +207,7 @@
 <translation id="6907759265145635167"><ph name="QUANTITY"/> PB/s</translation>
 <translation id="2743387203779672305">העתק ללוח</translation>
 <translation id="8371695176452482769">דבר עכשיו</translation>
-<translation id="1167268268675672572">העבר לתחילת השורה ושנה את הבחירה</translation>
+<translation id="1167268268675672572">עבור לתחילת השורה ושנה את הבחירה</translation>
 <translation id="6965382102122355670">אישור</translation>
 <translation id="7850320739366109486">נא לא להפריע</translation>
 <translation id="6978839998405419496"><ph name="NUMBER_ZERO"/> days ago</translation>
diff --git a/ui/base/strings/ui_strings_ms.xtb b/ui/base/strings/ui_strings_ms.xtb
index c94b4f1..c4d8d3a 100644
--- a/ui/base/strings/ui_strings_ms.xtb
+++ b/ui/base/strings/ui_strings_ms.xtb
@@ -30,7 +30,7 @@
 <translation id="5608669887400696928"><ph name="NUMBER_DEFAULT"/> jam</translation>
 <translation id="3990502903496589789">Tepi Kanan</translation>
 <translation id="9038489124413477075">Folder Tanpa Nama</translation>
-<translation id="1940483897317142625">Padamkan Hingga Akhir Baris</translation>
+<translation id="1940483897317142625">Padamkan Hingga Hujung Baris</translation>
 <translation id="8507996248087185956"><ph name="NUMBER_DEFAULT"/> mins</translation>
 <translation id="3520476450377425184"><ph name="NUMBER_MANY"/> hari lagi</translation>
 <translation id="932327136139879170">Halaman Utama</translation>
diff --git a/ui/base/strings/ui_strings_th.xtb b/ui/base/strings/ui_strings_th.xtb
index 65bad62..15d37db 100644
--- a/ui/base/strings/ui_strings_th.xtb
+++ b/ui/base/strings/ui_strings_th.xtb
@@ -30,7 +30,7 @@
 <translation id="5608669887400696928"><ph name="NUMBER_DEFAULT"/> ชั่วโมง</translation>
 <translation id="3990502903496589789">ขอบขวา</translation>
 <translation id="9038489124413477075">โฟลเดอร์ที่ไม่มีชื่อ</translation>
-<translation id="1940483897317142625">ลบจนถึงท้ายบรรทัด</translation>
+<translation id="1940483897317142625">ลบจนสุดบรรทัด</translation>
 <translation id="8507996248087185956"><ph name="NUMBER_DEFAULT"/> นาที</translation>
 <translation id="3520476450377425184">เหลือ <ph name="NUMBER_MANY"/> วัน</translation>
 <translation id="932327136139879170">Home</translation>
@@ -43,7 +43,7 @@
 <translation id="3353284378027041011"><ph name="NUMBER_FEW"/> วันที่ผ่านมา</translation>
 <translation id="5076340679995252485">&amp;วาง</translation>
 <translation id="7460907917090416791"><ph name="QUANTITY"/> TB</translation>
-<translation id="7139614227326422685">ย้ายคำมาทางขวา</translation>
+<translation id="7139614227326422685">เลื่อนไปทางขวาทีละคำ</translation>
 <translation id="364720409959344976">เลือกโฟลเดอร์เพื่ออัปโหลด</translation>
 <translation id="4999762576397546063">Ctrl+<ph name="KEY_COMBO_NAME"/></translation>
 <translation id="7770995925463083016"><ph name="NUMBER_TWO"/> นาทีที่ผ่านมา</translation>
@@ -77,7 +77,7 @@
 <translation id="3424538384153559412"><ph name="NUMBER_TWO"/> minutes</translation>
 <translation id="50960180632766478">เหลือ <ph name="NUMBER_FEW"/> นาที</translation>
 <translation id="5517291721709019259"><ph name="NUMBER_FEW"/> seconds left</translation>
-<translation id="6903282483217634857">ย้ายไปทางขวา</translation>
+<translation id="6903282483217634857">เลื่อนไปทางขวา</translation>
 <translation id="6659594942844771486">แท็บ</translation>
 <translation id="3049748772180311791"><ph name="QUANTITY"/> MB</translation>
 <translation id="4988273303304146523"><ph name="NUMBER_DEFAULT"/> วันที่ผ่านมา</translation>
@@ -96,20 +96,20 @@
 <translation id="290555789621781773"><ph name="NUMBER_TWO"/> นาที</translation>
 <translation id="5149131957118398098"><ph name="NUMBER_ZERO"/> hours left</translation>
 <translation id="7135556860107312402">อนุญาตให้มีการแจ้งเตือนจากรายการต่อไปนี้</translation>
-<translation id="2479520428668657293">ย้ายไปทางขวาและปรับการเลือก</translation>
+<translation id="2479520428668657293">เลื่อนไปทางขวาและปรับการเลือก</translation>
 <translation id="8112886015144590373"><ph name="NUMBER_FEW"/> ชั่วโมง</translation>
 <translation id="1398853756734560583">ย่อ</translation>
 <translation id="4250229828105606438">ภาพหน้าจอ</translation>
 <translation id="6690744523875189208"><ph name="NUMBER_TWO"/> ชั่วโมง</translation>
 <translation id="5260878308685146029">เหลือ <ph name="NUMBER_TWO"/> นาที</translation>
-<translation id="2557207087669398617">ย้ายไปจุดเริ่มต้นบรรทัด</translation>
+<translation id="2557207087669398617">เลื่อนไปจุดเริ่มต้นบรรทัด</translation>
 <translation id="3757388668994797779"><ph name="QUANTITY"/> GB</translation>
 <translation id="1901303067676059328">เลือก&amp;ทั้งหมด</translation>
 <translation id="2168039046890040389">เลื่อนหน้าขึ้น</translation>
 <translation id="7363290921156020669"><ph name="NUMBER_ZERO"/> mins</translation>
 <translation id="9107059250669762581"><ph name="NUMBER_DEFAULT"/> วัน</translation>
 <translation id="6463061331681402734"><ph name="NUMBER_MANY"/> นาที</translation>
-<translation id="6122334925474904337">ย้ายคำไปทางขวาและปรับการเลือก</translation>
+<translation id="6122334925474904337">เลื่อนไปทางขวาทีละคำและปรับการเลือก</translation>
 <translation id="7634624804467787019"><ph name="NUMBER_ONE"/> นาที</translation>
 <translation id="8448317557906454022"><ph name="NUMBER_ZERO"/> วินาทีที่ผ่านมา</translation>
 <translation id="4927753642311223124">ที่นี่ไม่มีอะไรต้องดู ไปต่อได้</translation>
@@ -134,8 +134,8 @@
 <translation id="7414887922320653780">เหลือ <ph name="NUMBER_ONE"/> ชั่วโมง</translation>
 <translation id="1413622004203049571">ปิดการแจ้งเตือนจาก <ph name="NOTIFIER_NAME"/></translation>
 <translation id="2666092431469916601">ด้านบน</translation>
-<translation id="2538759511191347839">ย้ายไปท้ายบรรทัดและปรับการเลือก</translation>
-<translation id="928465423150706909">ย้ายไปท้ายบรรทัด</translation>
+<translation id="2538759511191347839">เลื่อนไปสุดบรรทัดและปรับการเลือก</translation>
+<translation id="928465423150706909">เลื่อนไปสุดบรรทัด</translation>
 <translation id="8331626408530291785">เลื่อนขึ้น</translation>
 <translation id="7907591526440419938">เปิดไฟล์</translation>
 <translation id="2864069933652346933"><ph name="NUMBER_ZERO"/> days left</translation>
@@ -145,12 +145,12 @@
 <translation id="6808150112686056157">หยุดสื่อ</translation>
 <translation id="1308727876662951186"><ph name="NUMBER_ZERO"/> mins left</translation>
 <translation id="3157931365184549694">คืนค่า</translation>
-<translation id="5349525451964472598">ย้ายไปทางซ้ายและปรับการเลือก</translation>
-<translation id="1781701194097416995">ย้ายคำไปทางซ้าย</translation>
+<translation id="5349525451964472598">เลื่อนไปทางซ้ายและปรับการเลือก</translation>
+<translation id="1781701194097416995">เลื่อนไปทางซ้ายทีละคำ</translation>
 <translation id="1243314992276662751">อัปโหลด</translation>
 <translation id="50030952220075532">เหลือ <ph name="NUMBER_ONE"/> วัน</translation>
 <translation id="8179976553408161302">เข้าใช้</translation>
-<translation id="8471049483003785219">ย้ายคำไปทางซ้ายและปรับการเลือก</translation>
+<translation id="8471049483003785219">เลื่อนไปทางซ้ายทีละคำและปรับการเลือก</translation>
 <translation id="945522503751344254">ส่งความคิดเห็น</translation>
 <translation id="9170848237812810038">เ&amp;ลิกทำ</translation>
 <translation id="1285266685456062655"><ph name="NUMBER_FEW"/> ชั่วโมงที่ผ่านมา</translation>
@@ -173,7 +173,7 @@
 <translation id="8788572795284305350"><ph name="NUMBER_ZERO"/> hours ago</translation>
 <translation id="3740362395218339114"><ph name="QUANTITY"/> GB/วินาที</translation>
 <translation id="6644971472240498405"><ph name="NUMBER_ONE"/> วัน</translation>
-<translation id="2704295676501803339">ย้ายไปทางซ้าย</translation>
+<translation id="2704295676501803339">เลื่อนไปทางซ้าย</translation>
 <translation id="9098468523912235228"><ph name="NUMBER_DEFAULT"/> วินาทีที่ผ่านมา</translation>
 <translation id="494645311413743213">เหลือ <ph name="NUMBER_TWO"/> วินาที</translation>
 <translation id="4570886800634958009">ขยายการแจ้งเตือน</translation>
@@ -207,7 +207,7 @@
 <translation id="6907759265145635167"><ph name="QUANTITY"/> PB/วินาที</translation>
 <translation id="2743387203779672305">คัดลอกไว้ที่คลิปบอร์ด</translation>
 <translation id="8371695176452482769">เชิญพูดเลย</translation>
-<translation id="1167268268675672572">ย้ายไปจุดเริ่มต้นของบรรทัดและปรับการเลือก</translation>
+<translation id="1167268268675672572">เลื่อนไปจุดเริ่มต้นของบรรทัดและปรับการเลือก</translation>
 <translation id="6965382102122355670">ตกลง</translation>
 <translation id="7850320739366109486">ห้ามรบกวน</translation>
 <translation id="6978839998405419496"><ph name="NUMBER_ZERO"/> days ago</translation>
diff --git a/ui/base/strings/ui_strings_zh-CN.xtb b/ui/base/strings/ui_strings_zh-CN.xtb
index 0020688..e354d1c 100644
--- a/ui/base/strings/ui_strings_zh-CN.xtb
+++ b/ui/base/strings/ui_strings_zh-CN.xtb
@@ -43,7 +43,7 @@
 <translation id="3353284378027041011"><ph name="NUMBER_FEW"/> 天前</translation>
 <translation id="5076340679995252485">粘贴(&amp;P)</translation>
 <translation id="7460907917090416791"><ph name="QUANTITY"/> TB</translation>
-<translation id="7139614227326422685">向右移一个字</translation>
+<translation id="7139614227326422685">右移一个字</translation>
 <translation id="364720409959344976">选择要上传的文件夹</translation>
 <translation id="4999762576397546063">Ctrl+<ph name="KEY_COMBO_NAME"/></translation>
 <translation id="7770995925463083016"><ph name="NUMBER_TWO"/> 分钟前</translation>
@@ -109,7 +109,7 @@
 <translation id="7363290921156020669"><ph name="NUMBER_ZERO"/> mins</translation>
 <translation id="9107059250669762581"><ph name="NUMBER_DEFAULT"/> 天</translation>
 <translation id="6463061331681402734"><ph name="NUMBER_MANY"/> mins</translation>
-<translation id="6122334925474904337">向右移一个字并更改选择范围</translation>
+<translation id="6122334925474904337">右移一个字并更改选择范围</translation>
 <translation id="7634624804467787019"><ph name="NUMBER_ONE"/> 分钟</translation>
 <translation id="8448317557906454022"><ph name="NUMBER_ZERO"/> 秒前</translation>
 <translation id="4927753642311223124">这里没有任何通知,往前走吧。</translation>
@@ -146,11 +146,11 @@
 <translation id="1308727876662951186"><ph name="NUMBER_ZERO"/> mins left</translation>
 <translation id="3157931365184549694">恢复</translation>
 <translation id="5349525451964472598">左移并更改选择范围</translation>
-<translation id="1781701194097416995">向左移一个字</translation>
+<translation id="1781701194097416995">左移一个字</translation>
 <translation id="1243314992276662751">上传</translation>
 <translation id="50030952220075532"><ph name="NUMBER_ONE"/> day left</translation>
 <translation id="8179976553408161302">进入</translation>
-<translation id="8471049483003785219">向左移一个字并更改选择范围</translation>
+<translation id="8471049483003785219">左移一个字并更改选择范围</translation>
 <translation id="945522503751344254">发送反馈</translation>
 <translation id="9170848237812810038">撤消(&amp;U)</translation>
 <translation id="1285266685456062655"><ph name="NUMBER_FEW"/> 小时前</translation>
diff --git a/ui/base/touch/touch_editing_controller.h b/ui/base/touch/touch_editing_controller.h
index 8be9317..9c0298e 100644
--- a/ui/base/touch/touch_editing_controller.h
+++ b/ui/base/touch/touch_editing_controller.h
@@ -55,6 +55,10 @@
   // Tells the editable to open context menu.
   virtual void OpenContextMenu(const gfx::Point& anchor) = 0;
 
+  // Tells the editable to end touch editing and destroy touch selection
+  // controller it owns.
+  virtual void DestroyTouchSelection() = 0;
+
  protected:
   virtual ~TouchEditable() {}
 };
diff --git a/ui/base/ui_base.target.darwin-arm.mk b/ui/base/ui_base.target.darwin-arm.mk
index 25882a1..52fd50f 100644
--- a/ui/base/ui_base.target.darwin-arm.mk
+++ b/ui/base/ui_base.target.darwin-arm.mk
@@ -78,7 +78,8 @@
 	ui/base/ime/input_method_base.cc \
 	ui/base/ime/input_method_initializer.cc \
 	ui/base/ime/mock_input_method.cc \
-	ui/base/ime/text_input_client.cc
+	ui/base/ime/text_input_client.cc \
+	ui/base/ime/text_input_focus_manager.cc
 
 
 # Flags passed to both C and C++ files.
@@ -95,7 +96,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -145,11 +145,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -224,7 +219,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -274,11 +268,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/base/ui_base.target.darwin-arm64.mk b/ui/base/ui_base.target.darwin-arm64.mk
index 10f6e9b..bf74652 100644
--- a/ui/base/ui_base.target.darwin-arm64.mk
+++ b/ui/base/ui_base.target.darwin-arm64.mk
@@ -78,7 +78,8 @@
 	ui/base/ime/input_method_base.cc \
 	ui/base/ime/input_method_initializer.cc \
 	ui/base/ime/mock_input_method.cc \
-	ui/base/ime/text_input_client.cc
+	ui/base/ime/text_input_client.cc \
+	ui/base/ime/text_input_focus_manager.cc
 
 
 # Flags passed to both C and C++ files.
@@ -141,11 +142,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -265,11 +261,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/base/ui_base.target.darwin-mips.mk b/ui/base/ui_base.target.darwin-mips.mk
index 9576b7b..ecf83f0 100644
--- a/ui/base/ui_base.target.darwin-mips.mk
+++ b/ui/base/ui_base.target.darwin-mips.mk
@@ -78,7 +78,8 @@
 	ui/base/ime/input_method_base.cc \
 	ui/base/ime/input_method_initializer.cc \
 	ui/base/ime/mock_input_method.cc \
-	ui/base/ime/text_input_client.cc
+	ui/base/ime/text_input_client.cc \
+	ui/base/ime/text_input_focus_manager.cc
 
 
 # Flags passed to both C and C++ files.
@@ -144,11 +145,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -272,11 +268,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/base/ui_base.target.darwin-x86.mk b/ui/base/ui_base.target.darwin-x86.mk
index 4800538..6e6871b 100644
--- a/ui/base/ui_base.target.darwin-x86.mk
+++ b/ui/base/ui_base.target.darwin-x86.mk
@@ -78,7 +78,8 @@
 	ui/base/ime/input_method_base.cc \
 	ui/base/ime/input_method_initializer.cc \
 	ui/base/ime/mock_input_method.cc \
-	ui/base/ime/text_input_client.cc
+	ui/base/ime/text_input_client.cc \
+	ui/base/ime/text_input_focus_manager.cc
 
 
 # Flags passed to both C and C++ files.
@@ -97,7 +98,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -145,11 +145,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -225,7 +220,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -273,11 +267,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/base/ui_base.target.darwin-x86_64.mk b/ui/base/ui_base.target.darwin-x86_64.mk
index 7748803..a83ab45 100644
--- a/ui/base/ui_base.target.darwin-x86_64.mk
+++ b/ui/base/ui_base.target.darwin-x86_64.mk
@@ -78,7 +78,8 @@
 	ui/base/ime/input_method_base.cc \
 	ui/base/ime/input_method_initializer.cc \
 	ui/base/ime/mock_input_method.cc \
-	ui/base/ime/text_input_client.cc
+	ui/base/ime/text_input_client.cc \
+	ui/base/ime/text_input_focus_manager.cc
 
 
 # Flags passed to both C and C++ files.
@@ -97,7 +98,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,11 +146,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -226,7 +221,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -275,11 +269,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/base/ui_base.target.linux-arm.mk b/ui/base/ui_base.target.linux-arm.mk
index 25882a1..52fd50f 100644
--- a/ui/base/ui_base.target.linux-arm.mk
+++ b/ui/base/ui_base.target.linux-arm.mk
@@ -78,7 +78,8 @@
 	ui/base/ime/input_method_base.cc \
 	ui/base/ime/input_method_initializer.cc \
 	ui/base/ime/mock_input_method.cc \
-	ui/base/ime/text_input_client.cc
+	ui/base/ime/text_input_client.cc \
+	ui/base/ime/text_input_focus_manager.cc
 
 
 # Flags passed to both C and C++ files.
@@ -95,7 +96,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -145,11 +145,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -224,7 +219,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -274,11 +268,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/base/ui_base.target.linux-arm64.mk b/ui/base/ui_base.target.linux-arm64.mk
index 10f6e9b..bf74652 100644
--- a/ui/base/ui_base.target.linux-arm64.mk
+++ b/ui/base/ui_base.target.linux-arm64.mk
@@ -78,7 +78,8 @@
 	ui/base/ime/input_method_base.cc \
 	ui/base/ime/input_method_initializer.cc \
 	ui/base/ime/mock_input_method.cc \
-	ui/base/ime/text_input_client.cc
+	ui/base/ime/text_input_client.cc \
+	ui/base/ime/text_input_focus_manager.cc
 
 
 # Flags passed to both C and C++ files.
@@ -141,11 +142,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -265,11 +261,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/base/ui_base.target.linux-mips.mk b/ui/base/ui_base.target.linux-mips.mk
index 9576b7b..ecf83f0 100644
--- a/ui/base/ui_base.target.linux-mips.mk
+++ b/ui/base/ui_base.target.linux-mips.mk
@@ -78,7 +78,8 @@
 	ui/base/ime/input_method_base.cc \
 	ui/base/ime/input_method_initializer.cc \
 	ui/base/ime/mock_input_method.cc \
-	ui/base/ime/text_input_client.cc
+	ui/base/ime/text_input_client.cc \
+	ui/base/ime/text_input_focus_manager.cc
 
 
 # Flags passed to both C and C++ files.
@@ -144,11 +145,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -272,11 +268,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/base/ui_base.target.linux-x86.mk b/ui/base/ui_base.target.linux-x86.mk
index 4800538..6e6871b 100644
--- a/ui/base/ui_base.target.linux-x86.mk
+++ b/ui/base/ui_base.target.linux-x86.mk
@@ -78,7 +78,8 @@
 	ui/base/ime/input_method_base.cc \
 	ui/base/ime/input_method_initializer.cc \
 	ui/base/ime/mock_input_method.cc \
-	ui/base/ime/text_input_client.cc
+	ui/base/ime/text_input_client.cc \
+	ui/base/ime/text_input_focus_manager.cc
 
 
 # Flags passed to both C and C++ files.
@@ -97,7 +98,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -145,11 +145,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -225,7 +220,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -273,11 +267,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/base/ui_base.target.linux-x86_64.mk b/ui/base/ui_base.target.linux-x86_64.mk
index 7748803..a83ab45 100644
--- a/ui/base/ui_base.target.linux-x86_64.mk
+++ b/ui/base/ui_base.target.linux-x86_64.mk
@@ -78,7 +78,8 @@
 	ui/base/ime/input_method_base.cc \
 	ui/base/ime/input_method_initializer.cc \
 	ui/base/ime/mock_input_method.cc \
-	ui/base/ime/text_input_client.cc
+	ui/base/ime/text_input_client.cc \
+	ui/base/ime/text_input_focus_manager.cc
 
 
 # Flags passed to both C and C++ files.
@@ -97,7 +98,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -146,11 +146,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -226,7 +221,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -275,11 +269,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/base/ui_base_jni_headers.target.darwin-arm.mk b/ui/base/ui_base_jni_headers.target.darwin-arm.mk
index 48c03c7..24320c9 100644
--- a/ui/base/ui_base_jni_headers.target.darwin-arm.mk
+++ b/ui/base/ui_base_jni_headers.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_base_ui_base_gyp_ui_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/base/Clipboard.java', '../android/java/src/org/chromium/ui/base/DeviceFormFactor.java', '../android/java/src/org/chromium/ui/base/LocalizationUtils.java', '../android/java/src/org/chromium/ui/base/SelectFileDialog.java', '../android/java/src/org/chromium/ui/base/TouchDevice.java', '../android/java/src/org/chromium/ui/base/ViewAndroid.java', '../android/java/src/org/chromium/ui/base/WindowAndroid.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,7 +121,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -198,7 +204,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/base/ui_base_jni_headers.target.darwin-arm64.mk b/ui/base/ui_base_jni_headers.target.darwin-arm64.mk
index 310619a..ed66ed9 100644
--- a/ui/base/ui_base_jni_headers.target.darwin-arm64.mk
+++ b/ui/base/ui_base_jni_headers.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_base_ui_base_gyp_ui_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/base/Clipboard.java', '../android/java/src/org/chromium/ui/base/DeviceFormFactor.java', '../android/java/src/org/chromium/ui/base/LocalizationUtils.java', '../android/java/src/org/chromium/ui/base/SelectFileDialog.java', '../android/java/src/org/chromium/ui/base/TouchDevice.java', '../android/java/src/org/chromium/ui/base/ViewAndroid.java', '../android/java/src/org/chromium/ui/base/WindowAndroid.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/ui_base_jni_headers.target.darwin-mips.mk b/ui/base/ui_base_jni_headers.target.darwin-mips.mk
index 12ed8a1..158048a 100644
--- a/ui/base/ui_base_jni_headers.target.darwin-mips.mk
+++ b/ui/base/ui_base_jni_headers.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_base_ui_base_gyp_ui_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/base/Clipboard.java', '../android/java/src/org/chromium/ui/base/DeviceFormFactor.java', '../android/java/src/org/chromium/ui/base/LocalizationUtils.java', '../android/java/src/org/chromium/ui/base/SelectFileDialog.java', '../android/java/src/org/chromium/ui/base/TouchDevice.java', '../android/java/src/org/chromium/ui/base/ViewAndroid.java', '../android/java/src/org/chromium/ui/base/WindowAndroid.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/ui_base_jni_headers.target.darwin-x86.mk b/ui/base/ui_base_jni_headers.target.darwin-x86.mk
index b420500..474d6ee 100644
--- a/ui/base/ui_base_jni_headers.target.darwin-x86.mk
+++ b/ui/base/ui_base_jni_headers.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_base_ui_base_gyp_ui_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/base/Clipboard.java', '../android/java/src/org/chromium/ui/base/DeviceFormFactor.java', '../android/java/src/org/chromium/ui/base/LocalizationUtils.java', '../android/java/src/org/chromium/ui/base/SelectFileDialog.java', '../android/java/src/org/chromium/ui/base/TouchDevice.java', '../android/java/src/org/chromium/ui/base/ViewAndroid.java', '../android/java/src/org/chromium/ui/base/WindowAndroid.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,7 +123,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -200,7 +206,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/base/ui_base_jni_headers.target.darwin-x86_64.mk b/ui/base/ui_base_jni_headers.target.darwin-x86_64.mk
index 8499080..d7ca2e9 100644
--- a/ui/base/ui_base_jni_headers.target.darwin-x86_64.mk
+++ b/ui/base/ui_base_jni_headers.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_base_ui_base_gyp_ui_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/base/Clipboard.java', '../android/java/src/org/chromium/ui/base/DeviceFormFactor.java', '../android/java/src/org/chromium/ui/base/LocalizationUtils.java', '../android/java/src/org/chromium/ui/base/SelectFileDialog.java', '../android/java/src/org/chromium/ui/base/TouchDevice.java', '../android/java/src/org/chromium/ui/base/ViewAndroid.java', '../android/java/src/org/chromium/ui/base/WindowAndroid.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,7 +123,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -200,7 +206,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/base/ui_base_jni_headers.target.linux-arm.mk b/ui/base/ui_base_jni_headers.target.linux-arm.mk
index 48c03c7..24320c9 100644
--- a/ui/base/ui_base_jni_headers.target.linux-arm.mk
+++ b/ui/base/ui_base_jni_headers.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_base_ui_base_gyp_ui_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/base/Clipboard.java', '../android/java/src/org/chromium/ui/base/DeviceFormFactor.java', '../android/java/src/org/chromium/ui/base/LocalizationUtils.java', '../android/java/src/org/chromium/ui/base/SelectFileDialog.java', '../android/java/src/org/chromium/ui/base/TouchDevice.java', '../android/java/src/org/chromium/ui/base/ViewAndroid.java', '../android/java/src/org/chromium/ui/base/WindowAndroid.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -114,7 +121,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -198,7 +204,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/base/ui_base_jni_headers.target.linux-arm64.mk b/ui/base/ui_base_jni_headers.target.linux-arm64.mk
index 310619a..ed66ed9 100644
--- a/ui/base/ui_base_jni_headers.target.linux-arm64.mk
+++ b/ui/base/ui_base_jni_headers.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_base_ui_base_gyp_ui_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/base/Clipboard.java', '../android/java/src/org/chromium/ui/base/DeviceFormFactor.java', '../android/java/src/org/chromium/ui/base/LocalizationUtils.java', '../android/java/src/org/chromium/ui/base/SelectFileDialog.java', '../android/java/src/org/chromium/ui/base/TouchDevice.java', '../android/java/src/org/chromium/ui/base/ViewAndroid.java', '../android/java/src/org/chromium/ui/base/WindowAndroid.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/ui_base_jni_headers.target.linux-mips.mk b/ui/base/ui_base_jni_headers.target.linux-mips.mk
index 12ed8a1..158048a 100644
--- a/ui/base/ui_base_jni_headers.target.linux-mips.mk
+++ b/ui/base/ui_base_jni_headers.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_base_ui_base_gyp_ui_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/base/Clipboard.java', '../android/java/src/org/chromium/ui/base/DeviceFormFactor.java', '../android/java/src/org/chromium/ui/base/LocalizationUtils.java', '../android/java/src/org/chromium/ui/base/SelectFileDialog.java', '../android/java/src/org/chromium/ui/base/TouchDevice.java', '../android/java/src/org/chromium/ui/base/ViewAndroid.java', '../android/java/src/org/chromium/ui/base/WindowAndroid.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/base/ui_base_jni_headers.target.linux-x86.mk b/ui/base/ui_base_jni_headers.target.linux-x86.mk
index b420500..474d6ee 100644
--- a/ui/base/ui_base_jni_headers.target.linux-x86.mk
+++ b/ui/base/ui_base_jni_headers.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_base_ui_base_gyp_ui_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/base/Clipboard.java', '../android/java/src/org/chromium/ui/base/DeviceFormFactor.java', '../android/java/src/org/chromium/ui/base/LocalizationUtils.java', '../android/java/src/org/chromium/ui/base/SelectFileDialog.java', '../android/java/src/org/chromium/ui/base/TouchDevice.java', '../android/java/src/org/chromium/ui/base/ViewAndroid.java', '../android/java/src/org/chromium/ui/base/WindowAndroid.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,7 +123,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -200,7 +206,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/base/ui_base_jni_headers.target.linux-x86_64.mk b/ui/base/ui_base_jni_headers.target.linux-x86_64.mk
index 8499080..d7ca2e9 100644
--- a/ui/base/ui_base_jni_headers.target.linux-x86_64.mk
+++ b/ui/base/ui_base_jni_headers.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_base_ui_base_gyp_ui_base_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/base/Clipboard.java', '../android/java/src/org/chromium/ui/base/DeviceFormFactor.java', '../android/java/src/org/chromium/ui/base/LocalizationUtils.java', '../android/java/src/org/chromium/ui/base/SelectFileDialog.java', '../android/java/src/org/chromium/ui/base/TouchDevice.java', '../android/java/src/org/chromium/ui/base/ViewAndroid.java', '../android/java/src/org/chromium/ui/base/WindowAndroid.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/Clipboard_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/DeviceFormFactor_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/LocalizationUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -42,6 +45,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/SelectFileDialog_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -50,6 +54,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/TouchDevice_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -58,6 +63,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/ViewAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -66,6 +72,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/jni/WindowAndroid_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -116,7 +123,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -200,7 +206,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc
index 6b56a0f..588dcc2 100644
--- a/ui/base/ui_base_switches.cc
+++ b/ui/base/ui_base_switches.cc
@@ -14,6 +14,9 @@
 // Disables use of DWM composition for top level windows.
 const char kDisableDwmComposition[] = "disable-dwm-composition";
 
+// Disables an experimental focus manager to track text input clients.
+const char kDisableTextInputFocusManager[] = "disable-text-input-focus-manager";
+
 // Disables touch adjustment.
 const char kDisableTouchAdjustment[] = "disable-touch-adjustment";
 
@@ -23,20 +26,15 @@
 // Disables controls that support touch base text editing.
 const char kDisableTouchEditing[] = "disable-touch-editing";
 
+// Enables an experimental focus manager to track text input clients.
+const char kEnableTextInputFocusManager[] = "enable-text-input-focus-manager";
+
 // Enables touch event based drag and drop.
 const char kEnableTouchDragDrop[] = "enable-touch-drag-drop";
 
 // Enables controls that support touch base text editing.
 const char kEnableTouchEditing[] = "enable-touch-editing";
 
-// If a resource is requested at a scale factor at which it is not available
-// or the resource is the incorrect size (based on the size of the 1x resource),
-// generates the missing resource and applies a red mask to the generated
-// resource. Resources for which hidpi is not supported because of software
-// reasons will show up pixelated.
-const char kHighlightMissingScaledResources[] =
-    "highlight-missing-scaled-resources";
-
 // The language file that we want to try to open. Of the form
 // language[-country] where language is the 2 letter code from ISO-639.
 const char kLang[] = "lang";
diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h
index dbcdca4..a1d404a 100644
--- a/ui/base/ui_base_switches.h
+++ b/ui/base/ui_base_switches.h
@@ -17,12 +17,13 @@
 #endif
 
 UI_BASE_EXPORT extern const char kDisableDwmComposition[];
+UI_BASE_EXPORT extern const char kDisableTextInputFocusManager[];
 UI_BASE_EXPORT extern const char kDisableTouchAdjustment[];
 UI_BASE_EXPORT extern const char kDisableTouchDragDrop[];
 UI_BASE_EXPORT extern const char kDisableTouchEditing[];
+UI_BASE_EXPORT extern const char kEnableTextInputFocusManager[];
 UI_BASE_EXPORT extern const char kEnableTouchDragDrop[];
 UI_BASE_EXPORT extern const char kEnableTouchEditing[];
-UI_BASE_EXPORT extern const char kHighlightMissingScaledResources[];
 UI_BASE_EXPORT extern const char kLang[];
 UI_BASE_EXPORT extern const char kLocalePak[];
 UI_BASE_EXPORT extern const char kNoMessageBox[];
diff --git a/ui/base/ui_base_switches_util.cc b/ui/base/ui_base_switches_util.cc
index 3089607..c896745 100644
--- a/ui/base/ui_base_switches_util.cc
+++ b/ui/base/ui_base_switches_util.cc
@@ -9,6 +9,11 @@
 
 namespace switches {
 
+bool IsTextInputFocusManagerEnabled() {
+  return CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kEnableTextInputFocusManager);
+}
+
 bool IsTouchDragDropEnabled() {
 #if defined(OS_CHROMEOS)
   return !CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/ui/base/ui_base_switches_util.h b/ui/base/ui_base_switches_util.h
index 92badcc..8dbc408 100644
--- a/ui/base/ui_base_switches_util.h
+++ b/ui/base/ui_base_switches_util.h
@@ -5,11 +5,11 @@
 #ifndef UI_BASE_UI_BASE_SWITCHES_UTIL_H_
 #define UI_BASE_UI_BASE_SWITCHES_UTIL_H_
 
-#include "base/compiler_specific.h"
 #include "ui/base/ui_base_export.h"
 
 namespace switches {
 
+UI_BASE_EXPORT bool IsTextInputFocusManagerEnabled();
 UI_BASE_EXPORT bool IsTouchDragDropEnabled();
 UI_BASE_EXPORT bool IsTouchEditingEnabled();
 
diff --git a/ui/base/x/selection_owner.cc b/ui/base/x/selection_owner.cc
index ed1ce98..c30187e 100644
--- a/ui/base/x/selection_owner.cc
+++ b/ui/base/x/selection_owner.cc
@@ -9,20 +9,67 @@
 
 #include "base/logging.h"
 #include "ui/base/x/selection_utils.h"
+#include "ui/base/x/x11_util.h"
 
 namespace ui {
 
 namespace {
 
+const char kAtomPair[] = "ATOM_PAIR";
 const char kMultiple[] = "MULTIPLE";
+const char kSaveTargets[] = "SAVE_TARGETS";
 const char kTargets[] = "TARGETS";
 
 const char* kAtomsToCache[] = {
+  kAtomPair,
   kMultiple,
+  kSaveTargets,
   kTargets,
   NULL
 };
 
+// Gets the value of an atom pair array property. On success, true is returned
+// and the value is stored in |value|.
+bool GetAtomPairArrayProperty(XID window,
+                              Atom property,
+                              std::vector<std::pair<Atom,Atom> >* value) {
+  Atom type = None;
+  int format = 0;  // size in bits of each item in 'property'
+  unsigned long num_items = 0;
+  unsigned char* properties = NULL;
+  unsigned long remaining_bytes = 0;
+
+  int result = XGetWindowProperty(gfx::GetXDisplay(),
+                                  window,
+                                  property,
+                                  0,          // offset into property data to
+                                              // read
+                                  (~0L),      // entire array
+                                  False,      // deleted
+                                  AnyPropertyType,
+                                  &type,
+                                  &format,
+                                  &num_items,
+                                  &remaining_bytes,
+                                  &properties);
+
+  if (result != Success)
+    return false;
+
+  // GTK does not require |type| to be kAtomPair.
+  if (format != 32 || num_items % 2 != 0) {
+    XFree(properties);
+    return false;
+  }
+
+  Atom* atom_properties = reinterpret_cast<Atom*>(properties);
+  value->clear();
+  for (size_t i = 0; i < num_items; i+=2)
+    value->push_back(std::make_pair(atom_properties[i], atom_properties[i+1]));
+  XFree(properties);
+  return true;
+}
+
 }  // namespace
 
 SelectionOwner::SelectionOwner(Display* x_display,
@@ -75,40 +122,40 @@
   reply.xselection.property = None;  // Indicates failure
   reply.xselection.time = event.time;
 
-  // Get the proper selection.
-  Atom targets_atom = atom_cache_.GetAtom(kTargets);
-  if (event.target == targets_atom) {
-    // We have been asked for TARGETS. Send an atom array back with the data
-    // types we support.
-    std::vector<Atom> targets;
-    targets.push_back(targets_atom);
-    RetrieveTargets(&targets);
+  if (event.target == atom_cache_.GetAtom(kMultiple)) {
+    // The contents of |event.property| should be a list of
+    // <target,property> pairs.
+    std::vector<std::pair<Atom,Atom> > conversions;
+    if (GetAtomPairArrayProperty(event.requestor,
+                                 event.property,
+                                 &conversions)) {
+      std::vector<Atom> conversion_results;
+      for (size_t i = 0; i < conversions.size(); ++i) {
+        bool conversion_successful = ProcessTarget(conversions[i].first,
+                                                   event.requestor,
+                                                   conversions[i].second);
+        conversion_results.push_back(conversions[i].first);
+        conversion_results.push_back(
+            conversion_successful ? conversions[i].second : None);
+      }
 
-    XChangeProperty(x_display_, event.requestor, event.property, XA_ATOM, 32,
-                    PropModeReplace,
-                    reinterpret_cast<unsigned char*>(&targets.front()),
-                    targets.size());
-    reply.xselection.property = event.property;
-  } else if (event.target == atom_cache_.GetAtom(kMultiple)) {
-    // TODO(erg): Theoretically, the spec claims I'm supposed to handle the
-    // MULTIPLE case, but I haven't seen it in the wild yet.
-    NOTIMPLEMENTED();
-  } else {
-    // Try to find the data type in map.
-    SelectionFormatMap::const_iterator it =
-        format_map_.find(event.target);
-    if (it != format_map_.end()) {
-      XChangeProperty(x_display_, event.requestor, event.property,
-                      event.target, 8,
-                      PropModeReplace,
-                      const_cast<unsigned char*>(
-                          reinterpret_cast<const unsigned char*>(
-                              it->second->front())),
-                      it->second->size());
+      // Set the property to indicate which conversions succeeded. This matches
+      // what GTK does.
+      XChangeProperty(
+          x_display_,
+          event.requestor,
+          event.property,
+          atom_cache_.GetAtom(kAtomPair),
+          32,
+          PropModeReplace,
+          reinterpret_cast<const unsigned char*>(&conversion_results.front()),
+          conversion_results.size());
+
       reply.xselection.property = event.property;
     }
-    // I would put error logging here, but GTK ignores TARGETS and spams us
-    // looking for its own internal types.
+  } else {
+    if (ProcessTarget(event.target, event.requestor, event.property))
+      reply.xselection.property = event.property;
   }
 
   // Send off the reply.
@@ -122,5 +169,47 @@
   // we need to delay clearing.
 }
 
+bool SelectionOwner::ProcessTarget(Atom target,
+                                   ::Window requestor,
+                                   ::Atom property) {
+  Atom multiple_atom = atom_cache_.GetAtom(kMultiple);
+  Atom save_targets_atom = atom_cache_.GetAtom(kSaveTargets);
+  Atom targets_atom = atom_cache_.GetAtom(kTargets);
+
+  if (target == multiple_atom || target == save_targets_atom)
+    return false;
+
+  if (target == targets_atom) {
+    // We have been asked for TARGETS. Send an atom array back with the data
+    // types we support.
+    std::vector<Atom> targets;
+    targets.push_back(targets_atom);
+    targets.push_back(save_targets_atom);
+    targets.push_back(multiple_atom);
+    RetrieveTargets(&targets);
+
+    XChangeProperty(x_display_, requestor, property, XA_ATOM, 32,
+                    PropModeReplace,
+                    reinterpret_cast<unsigned char*>(&targets.front()),
+                    targets.size());
+    return true;
+  } else {
+    // Try to find the data type in map.
+    SelectionFormatMap::const_iterator it = format_map_.find(target);
+    if (it != format_map_.end()) {
+      XChangeProperty(x_display_, requestor, property, target, 8,
+                      PropModeReplace,
+                      const_cast<unsigned char*>(
+                          reinterpret_cast<const unsigned char*>(
+                              it->second->front())),
+                      it->second->size());
+      return true;
+    }
+    // I would put error logging here, but GTK ignores TARGETS and spams us
+    // looking for its own internal types.
+  }
+  return false;
+}
+
 }  // namespace ui
 
diff --git a/ui/base/x/selection_owner.h b/ui/base/x/selection_owner.h
index 29bc232..81d7e73 100644
--- a/ui/base/x/selection_owner.h
+++ b/ui/base/x/selection_owner.h
@@ -53,6 +53,11 @@
   // don't, but there were open todos in the previous implementation.
 
  private:
+  // Attempts to convert the selection to |target|. If the conversion is
+  // successful, true is returned and the result is stored in the |property|
+  // of |requestor|.
+  bool ProcessTarget(::Atom target, ::Window requestor, ::Atom property);
+
   // Our X11 state.
   Display* x_display_;
   ::Window x_window_;
diff --git a/ui/base/x/selection_requestor.cc b/ui/base/x/selection_requestor.cc
index 8757c72..a946787 100644
--- a/ui/base/x/selection_requestor.cc
+++ b/ui/base/x/selection_requestor.cc
@@ -7,6 +7,8 @@
 #include "base/run_loop.h"
 #include "ui/base/x/selection_utils.h"
 #include "ui/base/x/x11_util.h"
+#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/events/platform/platform_event_source.h"
 #include "ui/gfx/x/x11_types.h"
 
 namespace ui {
@@ -24,10 +26,12 @@
 
 SelectionRequestor::SelectionRequestor(Display* x_display,
                                        Window x_window,
-                                       Atom selection_name)
+                                       Atom selection_name,
+                                       PlatformEventDispatcher* dispatcher)
     : x_display_(x_display),
       x_window_(x_window),
       selection_name_(selection_name),
+      dispatcher_(dispatcher),
       atom_cache_(x_display_, kAtomsToCache) {
 }
 
@@ -39,38 +43,26 @@
     size_t* out_data_bytes,
     size_t* out_data_items,
     Atom* out_type) {
-  // The name of the property we're asking to be set on |x_window_|.
-  Atom property_to_set = atom_cache_.GetAtom(kChromeSelection);
+  // The name of the property that we are either:
+  // - Passing as a parameter with the XConvertSelection() request.
+  // OR
+  // - Asking the selection owner to set on |x_window_|.
+  Atom property = atom_cache_.GetAtom(kChromeSelection);
 
   XConvertSelection(x_display_,
                     selection_name_,
                     target,
-                    property_to_set,
+                    property,
                     x_window_,
                     CurrentTime);
 
   // Now that we've thrown our message off to the X11 server, we block waiting
   // for a response.
-  base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
-  base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
-  base::RunLoop run_loop;
-
-  // Stop waiting for a response after a certain amount of time.
-  const int kMaxWaitTimeForClipboardResponse = 300;
-  loop->PostDelayedTask(
-      FROM_HERE,
-      run_loop.QuitClosure(),
-      base::TimeDelta::FromMilliseconds(kMaxWaitTimeForClipboardResponse));
-
-  PendingRequest pending_request(target, run_loop.QuitClosure());
-  pending_requests_.push_back(&pending_request);
-  run_loop.Run();
-  DCHECK(!pending_requests_.empty());
-  DCHECK_EQ(&pending_request, pending_requests_.back());
-  pending_requests_.pop_back();
+  PendingRequest pending_request(target);
+  BlockTillSelectionNotifyForRequest(&pending_request);
 
   bool success = false;
-  if (pending_request.returned_property == property_to_set) {
+  if (pending_request.returned_property == property) {
     success =  ui::GetRawBytesOfProperty(x_window_,
                                          pending_request.returned_property,
                                          out_data, out_data_bytes,
@@ -81,6 +73,13 @@
   return success;
 }
 
+void SelectionRequestor::PerformBlockingConvertSelectionWithParameter(
+    Atom target,
+    const std::vector< ::Atom>& parameter) {
+  SetAtomArrayProperty(x_window_, kChromeSelection, "ATOM", parameter);
+  PerformBlockingConvertSelection(target, NULL, NULL, NULL, NULL);
+}
+
 SelectionData SelectionRequestor::RequestAndWaitForTypes(
     const std::vector< ::Atom>& types) {
   for (std::vector< ::Atom>::const_iterator it = types.begin();
@@ -133,13 +132,51 @@
 
   request_notified->returned_property = event.property;
   request_notified->returned = true;
-  request_notified->quit_closure.Run();
+
+  if (!request_notified->quit_closure.is_null())
+    request_notified->quit_closure.Run();
 }
 
-SelectionRequestor::PendingRequest::PendingRequest(Atom target,
-                                                   base::Closure quit_closure)
+void SelectionRequestor::BlockTillSelectionNotifyForRequest(
+    PendingRequest* request) {
+  pending_requests_.push_back(request);
+
+  const int kMaxWaitTimeForClipboardResponse = 300;
+  if (PlatformEventSource::GetInstance()) {
+    base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
+    base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
+    base::RunLoop run_loop;
+
+    request->quit_closure = run_loop.QuitClosure();
+    loop->PostDelayedTask(
+        FROM_HERE,
+        request->quit_closure,
+        base::TimeDelta::FromMilliseconds(kMaxWaitTimeForClipboardResponse));
+
+    run_loop.Run();
+  } else {
+    // This occurs if PerformBlockingConvertSelection() is called during
+    // shutdown and the PlatformEventSource has already been destroyed.
+    base::TimeTicks start = base::TimeTicks::Now();
+    while (!request->returned) {
+      if (XPending(x_display_)) {
+        XEvent event;
+        XNextEvent(x_display_, &event);
+        dispatcher_->DispatchEvent(&event);
+      }
+      base::TimeDelta wait_time = base::TimeTicks::Now() - start;
+      if (wait_time.InMilliseconds() > kMaxWaitTimeForClipboardResponse)
+        break;
+    }
+  }
+
+  DCHECK(!pending_requests_.empty());
+  DCHECK_EQ(request, pending_requests_.back());
+  pending_requests_.pop_back();
+}
+
+SelectionRequestor::PendingRequest::PendingRequest(Atom target)
     : target(target),
-      quit_closure(quit_closure),
       returned_property(None),
       returned(false) {
 }
diff --git a/ui/base/x/selection_requestor.h b/ui/base/x/selection_requestor.h
index 333d308..f142dd0 100644
--- a/ui/base/x/selection_requestor.h
+++ b/ui/base/x/selection_requestor.h
@@ -20,6 +20,7 @@
 #include "ui/gfx/x/x11_atom_cache.h"
 
 namespace ui {
+class PlatformEventDispatcher;
 class SelectionData;
 
 // Requests and later receives data from the X11 server through the selection
@@ -33,7 +34,8 @@
  public:
   SelectionRequestor(Display* xdisplay,
                      ::Window xwindow,
-                     ::Atom selection_name);
+                     ::Atom selection_name,
+                     PlatformEventDispatcher* dispatcher);
   ~SelectionRequestor();
 
   // Does the work of requesting |target| from the selection we handle,
@@ -48,6 +50,12 @@
       size_t* out_data_items,
       ::Atom* out_type);
 
+  // Requests |target| from the selection that we handle, passing |parameter|
+  // as a parameter to XConvertSelection().
+  void PerformBlockingConvertSelectionWithParameter(
+      ::Atom target,
+      const std::vector< ::Atom>& parameter);
+
   // Returns the first of |types| offered by the current selection holder, or
   // returns NULL if none of those types are available.
   SelectionData RequestAndWaitForTypes(const std::vector< ::Atom>& types);
@@ -57,16 +65,9 @@
   void OnSelectionNotify(const XSelectionEvent& event);
 
  private:
-  // Our X11 state.
-  Display* x_display_;
-  ::Window x_window_;
-
-  // The X11 selection that this instance communicates on.
-  ::Atom selection_name_;
-
   // A request that has been issued and we are waiting for a response to.
   struct PendingRequest {
-    PendingRequest(Atom target, base::Closure quit_closure);
+    explicit PendingRequest(Atom target);
     ~PendingRequest();
 
     // Data to the current XConvertSelection request. Used for error detection;
@@ -86,6 +87,24 @@
     bool returned;
   };
 
+  // Blocks till SelectionNotify is received for the target specified in
+  // |request|.
+  void BlockTillSelectionNotifyForRequest(PendingRequest* request);
+
+  // Our X11 state.
+  Display* x_display_;
+  ::Window x_window_;
+
+  // The X11 selection that this instance communicates on.
+  ::Atom selection_name_;
+
+  // Dispatcher which handles SelectionNotify and SelectionRequest for
+  // |selection_name_|. PerformBlockingConvertSelection() calls the
+  // dispatcher directly if PerformBlockingConvertSelection() is called after
+  // the PlatformEventSource is destroyed.
+  // Not owned.
+  PlatformEventDispatcher* dispatcher_;
+
   // A list of requests for which we are waiting for responses.
   std::list<PendingRequest*> pending_requests_;
 
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc
index b2b5ef4..4bfd5c7 100644
--- a/ui/base/x/x11_util.cc
+++ b/ui/base/x/x11_util.cc
@@ -300,6 +300,15 @@
   return shared_memory_support;
 }
 
+bool QueryRenderSupport(Display* dpy) {
+  int dummy;
+  // We don't care about the version of Xrender since all the features which
+  // we use are included in every version.
+  static bool render_supported = XRenderQueryExtension(dpy, &dummy, &dummy);
+
+  return render_supported;
+}
+
 ::Cursor GetXCursor(int cursor_shape) {
   if (!cursor_cache)
     cursor_cache = new XCursorCache;
diff --git a/ui/base/x/x11_util.h b/ui/base/x/x11_util.h
index e9af790..cd347c6 100644
--- a/ui/base/x/x11_util.h
+++ b/ui/base/x/x11_util.h
@@ -58,6 +58,9 @@
 // Return the shared memory type of our X connection.
 UI_BASE_EXPORT SharedMemorySupport QuerySharedMemorySupport(XDisplay* dpy);
 
+// Return true iff the display supports Xrender
+UI_BASE_EXPORT bool QueryRenderSupport(XDisplay* dpy);
+
 // Returns an X11 Cursor, sharable across the process.
 // |cursor_shape| is an X font cursor shape, see XCreateFontCursor().
 UI_BASE_EXPORT ::Cursor GetXCursor(int cursor_shape);
diff --git a/ui/base/x/x11_util_internal.h b/ui/base/x/x11_util_internal.h
index e71f023..f663fc5 100644
--- a/ui/base/x/x11_util_internal.h
+++ b/ui/base/x/x11_util_internal.h
@@ -28,7 +28,7 @@
 // Get the XRENDER format id for ARGB32 (Skia's format).
 //
 // NOTE:Currently this don't support multiple screens/displays.
-XRenderPictFormat* GetRenderARGB32Format(Display* dpy);
+UI_BASE_EXPORT XRenderPictFormat* GetRenderARGB32Format(Display* dpy);
 
 // --------------------------------------------------------------------------
 // X11 error handling.
diff --git a/ui/chromeos/DEPS b/ui/chromeos/DEPS
index cc606ca..df97d67 100644
--- a/ui/chromeos/DEPS
+++ b/ui/chromeos/DEPS
@@ -1,5 +1,8 @@
 include_rules = [
   "+chromeos/dbus",
+  "+ui/aura",
   "+ui/events",
+  "+ui/gfx",
+  "+ui/gl",
   "+ui/wm",
 ]
diff --git a/ui/chromeos/touch_exploration_controller.cc b/ui/chromeos/touch_exploration_controller.cc
new file mode 100644
index 0000000..94ceb2d
--- /dev/null
+++ b/ui/chromeos/touch_exploration_controller.cc
@@ -0,0 +1,166 @@
+// 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.
+
+#include "ui/chromeos/touch_exploration_controller.h"
+
+#include "base/logging.h"
+#include "ui/aura/client/cursor_client.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/events/event.h"
+
+namespace ui {
+
+TouchExplorationController::TouchExplorationController(
+    aura::Window* root_window)
+        : root_window_(root_window) {
+  CHECK(root_window);
+  root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
+}
+
+TouchExplorationController::~TouchExplorationController() {
+  root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
+}
+
+ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
+    const ui::Event& event,
+    scoped_ptr<ui::Event>* rewritten_event) {
+  if (!event.IsTouchEvent())
+    return ui::EVENT_REWRITE_CONTINUE;
+
+  const ui::TouchEvent& touch_event =
+      static_cast<const ui::TouchEvent&>(event);
+  const ui::EventType type = touch_event.type();
+  const gfx::PointF& location = touch_event.location_f();
+  const int touch_id = touch_event.touch_id();
+  const int flags = touch_event.flags();
+
+  if (type == ui::ET_TOUCH_PRESSED) {
+    touch_ids_.push_back(touch_id);
+    touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
+    // If this is the first and only finger touching - rewrite the touch as a
+    // mouse move. Otherwise let the it go through as is.
+    if (touch_ids_.size() == 1) {
+      *rewritten_event = CreateMouseMoveEvent(location, flags);
+      EnterTouchToMouseMode();
+      return ui::EVENT_REWRITE_REWRITTEN;
+    }
+    return ui::EVENT_REWRITE_CONTINUE;
+  } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
+    std::vector<int>::iterator it =
+        std::find(touch_ids_.begin(), touch_ids_.end(), touch_id);
+    // We may fail to find the finger if the exploration mode was turned on
+    // while the user had some fingers touching the screen. We simply ignore
+    // those fingers for the purposes of event transformation.
+    if (it == touch_ids_.end())
+      return ui::EVENT_REWRITE_CONTINUE;
+    const bool first_finger_released = it == touch_ids_.begin();
+    touch_ids_.erase(it);
+    int num_erased = touch_locations_.erase(touch_id);
+    DCHECK_EQ(num_erased, 1);
+    const int num_fingers_remaining = touch_ids_.size();
+
+    if (num_fingers_remaining == 0) {
+      *rewritten_event = CreateMouseMoveEvent(location, flags);
+      return ui::EVENT_REWRITE_REWRITTEN;
+    }
+
+    // If we are left with one finger - enter the mouse move mode.
+    const bool enter_mouse_move_mode = num_fingers_remaining == 1;
+
+    if (!enter_mouse_move_mode && !first_finger_released) {
+      // No special handling needed.
+      return ui::EVENT_REWRITE_CONTINUE;
+    }
+
+    // If the finger which was released was the first one, - we need to rewrite
+    // the release event as a release of the was second / now first finger.
+    // This is the finger which will now be getting "substracted".
+    if (first_finger_released) {
+      int rewritten_release_id = touch_ids_[0];
+      const gfx::PointF& rewritten_release_location =
+          touch_locations_[rewritten_release_id];
+      ui::TouchEvent* rewritten_release_event = new ui::TouchEvent(
+          ui::ET_TOUCH_RELEASED,
+          rewritten_release_location,
+          rewritten_release_id,
+          event.time_stamp());
+      rewritten_release_event->set_flags(touch_event.flags());
+      rewritten_event->reset(rewritten_release_event);
+    } else if (enter_mouse_move_mode) {
+      // Dispatch the release event as is.
+      // TODO(mfomitchev): We can get rid of this clause once we have
+      // EVENT_REWRITE_DISPATCH_ANOTHER working without having to set
+      // rewritten_event.
+      rewritten_event->reset(new ui::TouchEvent(touch_event));
+    }
+
+    if (enter_mouse_move_mode) {
+      // Since we are entering the mouse move mode - also dispatch a mouse move
+      // event at the location of the one remaining finger. (num_fingers == 1)
+      const gfx::PointF& mouse_move_location = touch_locations_[touch_ids_[0]];
+      next_dispatch_event_ =
+          CreateMouseMoveEvent(mouse_move_location, flags).Pass();
+      return ui::EVENT_REWRITE_DISPATCH_ANOTHER;
+    }
+    return ui::EVENT_REWRITE_REWRITTEN;
+  } else if (type == ui::ET_TOUCH_MOVED) {
+    std::vector<int>::iterator it =
+        std::find(touch_ids_.begin(), touch_ids_.end(), touch_id);
+    // We may fail to find the finger if the exploration mode was turned on
+    // while the user had some fingers touching the screen. We simply ignore
+    // those fingers for the purposes of event transformation.
+    if (it == touch_ids_.end())
+      return ui::EVENT_REWRITE_CONTINUE;
+    touch_locations_[*it] = location;
+    if (touch_ids_.size() == 1) {
+      // Touch moves are rewritten as mouse moves when there's only one finger
+      // touching the screen.
+      *rewritten_event = CreateMouseMoveEvent(location, flags).Pass();
+      return ui::EVENT_REWRITE_REWRITTEN;
+    }
+    if (touch_id == touch_ids_.front()) {
+      // Touch moves of the first finger are discarded when there's more than
+      // one finger touching.
+      return ui::EVENT_REWRITE_DISCARD;
+    }
+    return ui::EVENT_REWRITE_CONTINUE;
+  }
+  NOTREACHED() << "Unexpected event type received.";
+  return ui::EVENT_REWRITE_CONTINUE;
+}
+
+ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
+    const ui::Event& last_event,
+    scoped_ptr<ui::Event>* new_event) {
+  CHECK(next_dispatch_event_);
+  DCHECK(last_event.IsTouchEvent());
+  *new_event = next_dispatch_event_.Pass();
+  // Enter the mouse move mode if needed
+  if ((*new_event)->IsMouseEvent())
+    EnterTouchToMouseMode();
+  return ui::EVENT_REWRITE_REWRITTEN;
+}
+
+scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent(
+    const gfx::PointF& location,
+    int flags) {
+  return scoped_ptr<ui::Event>(
+      new ui::MouseEvent(ui::ET_MOUSE_MOVED,
+                         location,
+                         location,
+                         flags | ui::EF_IS_SYNTHESIZED | ui::EF_FROM_TOUCH,
+                         0));
+}
+
+void TouchExplorationController::EnterTouchToMouseMode() {
+  aura::client::CursorClient* cursor_client =
+      aura::client::GetCursorClient(root_window_);
+  if (cursor_client && !cursor_client->IsMouseEventsEnabled())
+    cursor_client->EnableMouseEvents();
+  if (cursor_client && cursor_client->IsCursorVisible())
+    cursor_client->HideCursor();
+}
+
+}  // namespace ui
diff --git a/ui/chromeos/touch_exploration_controller.h b/ui/chromeos/touch_exploration_controller.h
new file mode 100644
index 0000000..d6fa8af
--- /dev/null
+++ b/ui/chromeos/touch_exploration_controller.h
@@ -0,0 +1,67 @@
+// 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.
+
+#ifndef UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
+#define UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
+
+#include "base/values.h"
+#include "ui/chromeos/ui_chromeos_export.h"
+#include "ui/events/event_rewriter.h"
+#include "ui/gfx/geometry/point.h"
+
+namespace aura {
+class Window;
+}
+
+namespace ui {
+
+class Event;
+
+// TouchExplorationController is used in tandem with "Spoken Feedback" to
+// make the touch UI accessible. TouchExplorationController rewrites the
+// incoming touch events as follows:
+// - When one finger is touching the screen, touch events are converted to mouse
+//   moves. This is the "Touch Exploration Mode". (The idea is that mouse moves
+//   will be subsequently used by another component to move focus between UI
+//   elements, and the elements will be read out to the user.)
+// - When more than one finger is touching the screen, touches from the
+//   first (i.e. "oldest") finger are ignored, and the other touches go through
+//   as is.
+// The caller is expected to retain ownership of instances of this class and
+// destroy them before |root_window| is destroyed.
+class UI_CHROMEOS_EXPORT TouchExplorationController :
+    public ui::EventRewriter {
+ public:
+  explicit TouchExplorationController(aura::Window* root_window);
+  virtual ~TouchExplorationController();
+
+ private:
+  scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location,
+                                             int flags);
+
+  void EnterTouchToMouseMode();
+
+  // Overridden from ui::EventRewriter
+  virtual ui::EventRewriteStatus RewriteEvent(
+      const ui::Event& event, scoped_ptr<ui::Event>* rewritten_event) OVERRIDE;
+  virtual ui::EventRewriteStatus NextDispatchEvent(
+      const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) OVERRIDE;
+
+  // A set of touch ids for fingers currently touching the screen.
+  std::vector<int> touch_ids_;
+
+  // Map of touch ids to their last known location.
+  std::map<int, gfx::PointF> touch_locations_;
+
+  // Initialized from RewriteEvent() and dispatched in NextDispatchEvent().
+  scoped_ptr<ui::Event> next_dispatch_event_;
+
+  aura::Window* root_window_;
+
+  DISALLOW_COPY_AND_ASSIGN(TouchExplorationController);
+};
+
+}  // namespace ui
+
+#endif  // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
diff --git a/ui/chromeos/touch_exploration_controller_unittest.cc b/ui/chromeos/touch_exploration_controller_unittest.cc
new file mode 100644
index 0000000..1ec3f8b
--- /dev/null
+++ b/ui/chromeos/touch_exploration_controller_unittest.cc
@@ -0,0 +1,459 @@
+// 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.
+
+#include "ui/chromeos/touch_exploration_controller.h"
+
+#include "base/time/time.h"
+#include "ui/aura/client/cursor_client.h"
+#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/event_generator.h"
+#include "ui/aura/test/test_cursor_client.h"
+#include "ui/aura/window.h"
+#include "ui/events/event.h"
+#include "ui/events/event_utils.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_surface.h"
+
+namespace ui {
+
+namespace {
+// Records all mouse and touch events.
+class EventCapturer : public ui::EventHandler {
+ public:
+  EventCapturer() {}
+  virtual ~EventCapturer() {}
+
+  void Reset() {
+    events_.clear();
+  }
+
+  virtual void OnEvent(ui::Event* event) OVERRIDE {
+    if (event->IsMouseEvent()) {
+      events_.push_back(
+          new ui::MouseEvent(static_cast<ui::MouseEvent&>(*event)));
+    } else if (event->IsTouchEvent()) {
+      events_.push_back(
+          new ui::TouchEvent(static_cast<ui::TouchEvent&>(*event)));
+    } else {
+      return;
+    }
+    // Stop event propagation so we don't click on random stuff that
+    // might break test assumptions.
+    event->StopPropagation();
+    // If there is a possibility that we're in an infinite loop, we should
+    // exit early with a sensible error rather than letting the test time out.
+    ASSERT_LT(events_.size(), 100u);
+  }
+  const ScopedVector<ui::LocatedEvent>& captured_events() const {
+    return events_;
+  }
+
+ private:
+  ScopedVector<ui::LocatedEvent> events_;
+
+  DISALLOW_COPY_AND_ASSIGN(EventCapturer);
+};
+
+}  // namespace
+
+class TouchExplorationTest : public aura::test::AuraTestBase {
+ public:
+  TouchExplorationTest() {}
+  virtual ~TouchExplorationTest() {}
+
+  virtual void SetUp() OVERRIDE {
+    if (gfx::GetGLImplementation() == gfx::kGLImplementationNone)
+      gfx::GLSurface::InitializeOneOffForTests();
+    aura::test::AuraTestBase::SetUp();
+    cursor_client_.reset(new aura::test::TestCursorClient(root_window()));
+    root_window()->AddPreTargetHandler(&event_capturer_);
+  }
+
+  virtual void TearDown() OVERRIDE {
+    root_window()->RemovePreTargetHandler(&event_capturer_);
+    SwitchTouchExplorationMode(false);
+    cursor_client_.reset();
+    aura::test::AuraTestBase::TearDown();
+  }
+
+  const ScopedVector<ui::LocatedEvent>& GetCapturedEvents() {
+    return event_capturer_.captured_events();
+  }
+
+  void ClearCapturedEvents() {
+    event_capturer_.Reset();
+  }
+
+ protected:
+  aura::client::CursorClient* cursor_client() { return cursor_client_.get(); }
+
+  void SwitchTouchExplorationMode(bool on) {
+    if (!on && touch_exploration_controller_.get())
+      touch_exploration_controller_.reset();
+    else if (on && !touch_exploration_controller_.get())
+      touch_exploration_controller_.reset(
+          new ui::TouchExplorationController(root_window()));
+  }
+
+  bool IsInTouchToMouseMode() {
+    aura::client::CursorClient* cursor_client =
+        aura::client::GetCursorClient(root_window());
+    return cursor_client &&
+           cursor_client->IsMouseEventsEnabled() &&
+           !cursor_client->IsCursorVisible();
+  }
+
+ private:
+  EventCapturer event_capturer_;
+  scoped_ptr<ui::TouchExplorationController> touch_exploration_controller_;
+  scoped_ptr<aura::test::TestCursorClient> cursor_client_;
+
+  DISALLOW_COPY_AND_ASSIGN(TouchExplorationTest);
+};
+
+// Executes a number of assertions to confirm that |e1| and |e2| are touch
+// events and are equal to each other.
+void ConfirmEventsAreTouchAndEqual(ui::Event* e1, ui::Event* e2) {
+  ASSERT_TRUE(e1->IsTouchEvent());
+  ASSERT_TRUE(e2->IsTouchEvent());
+  ui::TouchEvent* touch_event1 = static_cast<ui::TouchEvent*>(e1);
+  ui::TouchEvent* touch_event2 = static_cast<ui::TouchEvent*>(e2);
+  EXPECT_EQ(touch_event1->type(), touch_event2->type());
+  EXPECT_EQ(touch_event1->location(), touch_event2->location());
+  EXPECT_EQ(touch_event1->touch_id(), touch_event2->touch_id());
+  EXPECT_EQ(touch_event1->flags(), touch_event2->flags());
+  EXPECT_EQ(touch_event1->time_stamp(), touch_event2->time_stamp());
+}
+
+// Executes a number of assertions to confirm that |e1| and |e2| are mouse
+// events and are equal to each other.
+void ConfirmEventsAreMouseAndEqual(ui::Event* e1, ui::Event* e2) {
+  ASSERT_TRUE(e1->IsMouseEvent());
+  ASSERT_TRUE(e2->IsMouseEvent());
+  ui::MouseEvent* mouse_event1 = static_cast<ui::MouseEvent*>(e1);
+  ui::MouseEvent* mouse_event2 = static_cast<ui::MouseEvent*>(e2);
+  EXPECT_EQ(mouse_event1->type(), mouse_event2->type());
+  EXPECT_EQ(mouse_event1->location(), mouse_event2->location());
+  EXPECT_EQ(mouse_event1->root_location(), mouse_event2->root_location());
+  EXPECT_EQ(mouse_event1->flags(), mouse_event2->flags());
+}
+
+#define CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(e1, e2) \
+  ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreTouchAndEqual(e1, e2))
+
+#define CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(e1, e2) \
+  ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreMouseAndEqual(e1, e2))
+
+// TODO(mfomitchev): Need to investigate why we don't get mouse enter/exit
+// events when running these tests as part of ui_unittests. We do get them when
+// the tests are run as part of ash unit tests.
+
+// Simple test to confirm one-finger touches are transformed into mouse moves.
+TEST_F(TouchExplorationTest, OneFingerTouch) {
+  SwitchTouchExplorationMode(true);
+  cursor_client()->ShowCursor();
+  cursor_client()->DisableMouseEvents();
+  aura::test::EventGenerator generator(root_window());
+  gfx::Point location_start = generator.current_location();
+  gfx::Point location_end(11, 12);
+  generator.PressTouch();
+  EXPECT_TRUE(IsInTouchToMouseMode());
+  generator.MoveTouch(location_end);
+  // Confirm the actual mouse moves are unaffected.
+  ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED,
+                            gfx::Point(13, 14),
+                            gfx::Point(13, 14),
+                            0,
+                            0);
+  generator.Dispatch(&mouse_move);
+  generator.ReleaseTouch();
+
+  const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
+  ScopedVector<ui::LocatedEvent>::const_iterator it;
+  // TODO(mfomitchev): mouse enter/exit events
+  int num_mouse_moves = 0;
+  for (it = captured_events.begin(); it != captured_events.end(); ++it) {
+    int type = (*it)->type();
+    // Ignore enter and exit mouse events synthesized when the mouse cursor is
+    // shown or hidden.
+    if (type == ui::ET_MOUSE_ENTERED || type == ui::ET_MOUSE_EXITED)
+      continue;
+    EXPECT_EQ(ui::ET_MOUSE_MOVED, (*it)->type());
+    if (num_mouse_moves == 0)
+      EXPECT_EQ(location_start, (*it)->location());
+    if (num_mouse_moves == 1 || num_mouse_moves == 3)
+      EXPECT_EQ(location_end, (*it)->location());
+    if (num_mouse_moves == 2)
+      CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(*it, &mouse_move);
+    if (num_mouse_moves != 2) {
+      EXPECT_TRUE((*it)->flags() & ui::EF_IS_SYNTHESIZED);
+      EXPECT_TRUE((*it)->flags() & ui::EF_FROM_TOUCH);
+    }
+    num_mouse_moves++;
+  }
+  EXPECT_EQ(4, num_mouse_moves);
+}
+
+// Turn the touch exploration mode on in the middle of the touch gesture.
+// Confirm that events from the finger which was touching when the mode was
+// turned on don't get rewritten.
+TEST_F(TouchExplorationTest, TurnOnMidTouch) {
+  SwitchTouchExplorationMode(false);
+  cursor_client()->ShowCursor();
+  cursor_client()->DisableMouseEvents();
+  aura::test::EventGenerator generator(root_window());
+  generator.PressTouchId(1);
+  EXPECT_TRUE(cursor_client()->IsCursorVisible());
+  EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
+  ClearCapturedEvents();
+
+  // Enable touch exploration mode while the first finger is touching the
+  // screen. Ensure that subsequent events from that first finger are not
+  // affected by the touch exploration mode, while the touch events from another
+  // finger get rewritten.
+  SwitchTouchExplorationMode(true);
+  ui::TouchEvent touch_move(ui::ET_TOUCH_MOVED,
+                            gfx::Point(11, 12),
+                            1,
+                            ui::EventTimeForNow());
+  generator.Dispatch(&touch_move);
+  EXPECT_TRUE(cursor_client()->IsCursorVisible());
+  EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
+  const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
+  ASSERT_EQ(1u, captured_events.size());
+  CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move);
+  ClearCapturedEvents();
+
+  // The press from the second finger should get rewritten.
+  generator.PressTouchId(2);
+  EXPECT_TRUE(IsInTouchToMouseMode());
+  // TODO(mfomitchev): mouse enter/exit events
+  ScopedVector<ui::LocatedEvent>::const_iterator it;
+  for (it = captured_events.begin(); it != captured_events.end(); ++it) {
+    if ((*it)->type() == ui::ET_MOUSE_MOVED)
+      break;
+  }
+  EXPECT_NE(captured_events.end(), it);
+  ClearCapturedEvents();
+
+  // The release of the first finger shouldn't be affected.
+  ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED,
+                               gfx::Point(11, 12),
+                               1,
+                               ui::EventTimeForNow());
+  generator.Dispatch(&touch_release);
+  ASSERT_EQ(1u, captured_events.size());
+  CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release);
+  ClearCapturedEvents();
+
+  // The move and release from the second finger should get rewritten.
+  generator.MoveTouchId(gfx::Point(13, 14), 2);
+  generator.ReleaseTouchId(2);
+  ASSERT_EQ(2u, captured_events.size());
+  EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type());
+  EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type());
+}
+
+TEST_F(TouchExplorationTest, TwoFingerTouch) {
+  SwitchTouchExplorationMode(true);
+  aura::test::EventGenerator generator(root_window());
+  generator.PressTouchId(1);
+  ClearCapturedEvents();
+
+  // Confirm events from the second finger go through as is.
+  cursor_client()->ShowCursor();
+  cursor_client()->DisableMouseEvents();
+  ui::TouchEvent touch_press(ui::ET_TOUCH_PRESSED,
+                             gfx::Point(10, 11),
+                             2,
+                             ui::EventTimeForNow());
+  generator.Dispatch(&touch_press);
+  EXPECT_TRUE(cursor_client()->IsCursorVisible());
+  EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
+  const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
+  // TODO(mfomitchev): mouse enter/exit events
+  // There will be a ET_MOUSE_EXITED event synthesized when the mouse cursor is
+  // hidden - ignore it.
+  ScopedVector<ui::LocatedEvent>::const_iterator it;
+  for (it = captured_events.begin(); it != captured_events.end(); ++it) {
+    if ((*it)->type() == ui::ET_TOUCH_PRESSED) {
+      CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(*it, &touch_press);
+      break;
+    }
+  }
+  EXPECT_NE(captured_events.end(), it);
+  ClearCapturedEvents();
+  ui::TouchEvent touch_move(ui::ET_TOUCH_MOVED,
+                            gfx::Point(20, 21),
+                            2,
+                            ui::EventTimeForNow());
+  generator.Dispatch(&touch_move);
+  ASSERT_EQ(1u, captured_events.size());
+  CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move);
+  ClearCapturedEvents();
+
+  // Confirm mouse moves go through unaffected.
+  ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED,
+                            gfx::Point(13, 14),
+                            gfx::Point(13, 14),
+                            0,
+                            0);
+  generator.Dispatch(&mouse_move);
+  // TODO(mfomitchev): mouse enter/exit events
+  // Ignore synthesized ET_MOUSE_ENTERED/ET_MOUSE_EXITED
+  for (it = captured_events.begin(); it != captured_events.end(); ++it) {
+    if ((*it)->type() == ui::ET_MOUSE_MOVED) {
+      CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(*it, &mouse_move);
+      break;
+    }
+  }
+  EXPECT_NE(captured_events.end(), it);
+  ClearCapturedEvents();
+
+  // Have some other fingers touch/move/release
+  generator.PressTouchId(3);
+  generator.PressTouchId(4);
+  generator.MoveTouchId(gfx::Point(30, 31), 3);
+  generator.ReleaseTouchId(3);
+  generator.ReleaseTouchId(4);
+  ClearCapturedEvents();
+
+  // Events from the first finger should not go through while the second finger
+  // is touching.
+  gfx::Point touch1_location = gfx::Point(15, 16);
+  generator.MoveTouchId(touch1_location, 1);
+  EXPECT_EQ(0u, GetCapturedEvents().size());
+
+  EXPECT_TRUE(cursor_client()->IsCursorVisible());
+  EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
+
+  // A release of the second finger should go through, plus there should be a
+  // mouse move at |touch1_location| generated.
+  ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED,
+                               gfx::Point(25, 26),
+                               2,
+                               ui::EventTimeForNow());
+  generator.Dispatch(&touch_release);
+  EXPECT_TRUE(IsInTouchToMouseMode());
+  ASSERT_GE(captured_events.size(), 2u);
+  CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release);
+  // TODO(mfomitchev): mouse enter/exit events
+  // Ignore synthesized ET_MOUSE_ENTERED/ET_MOUSE_EXITED
+  for (it = captured_events.begin(); it != captured_events.end(); ++it) {
+    if ((*it)->type() == ui::ET_MOUSE_MOVED) {
+      EXPECT_EQ(touch1_location, (*it)->location());
+      break;
+    }
+  }
+  EXPECT_NE(captured_events.end(), it);
+}
+
+TEST_F(TouchExplorationTest, MultiFingerTouch) {
+  SwitchTouchExplorationMode(true);
+  aura::test::EventGenerator generator(root_window());
+  generator.PressTouchId(1);
+  generator.PressTouchId(2);
+  ClearCapturedEvents();
+
+  // Confirm events from other fingers go through as is.
+  ui::TouchEvent touch3_press(ui::ET_TOUCH_PRESSED,
+                              gfx::Point(10, 11),
+                              3,
+                              ui::EventTimeForNow());
+  ui::TouchEvent touch3_move1(ui::ET_TOUCH_MOVED,
+                              gfx::Point(12, 13),
+                              3,
+                              ui::EventTimeForNow());
+  ui::TouchEvent touch4_press(ui::ET_TOUCH_PRESSED,
+                              gfx::Point(20, 21),
+                              4,
+                              ui::EventTimeForNow());
+  ui::TouchEvent touch3_move2(ui::ET_TOUCH_MOVED,
+                              gfx::Point(14, 15),
+                              3,
+                              ui::EventTimeForNow());
+  ui::TouchEvent touch4_move(ui::ET_TOUCH_MOVED,
+                             gfx::Point(22, 23),
+                             4,
+                             ui::EventTimeForNow());
+  ui::TouchEvent touch3_release(ui::ET_TOUCH_RELEASED,
+                                gfx::Point(14, 15),
+                                3,
+                                ui::EventTimeForNow());
+  ui::TouchEvent touch4_release(ui::ET_TOUCH_RELEASED,
+                                gfx::Point(22, 23),
+                                4,
+                                ui::EventTimeForNow());
+  generator.Dispatch(&touch3_press);
+  generator.Dispatch(&touch3_move1);
+  generator.Dispatch(&touch4_press);
+  generator.Dispatch(&touch3_move2);
+  generator.Dispatch(&touch4_move);
+  generator.Dispatch(&touch3_release);
+  generator.Dispatch(&touch4_release);
+
+  const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
+  ASSERT_EQ(7u, captured_events.size());
+  CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch3_press);
+  CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[1], &touch3_move1);
+  CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[2], &touch4_press);
+  CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[3], &touch3_move2);
+  CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[4], &touch4_move);
+  CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[5], &touch3_release);
+  CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[6], &touch4_release);
+}
+
+// Test the case when there are multiple fingers on the screen and the first
+// finger is released. This should be rewritten as a release of the second
+// finger. Additionally, if the second finger is the only finger left touching,
+// we should enter a mouse move mode, and a mouse move event should be
+// dispatched.
+TEST_F(TouchExplorationTest, FirstFingerLifted) {
+  SwitchTouchExplorationMode(true);
+  aura::test::EventGenerator generator(root_window());
+  generator.PressTouchId(1);
+  generator.PressTouchId(2);
+  gfx::Point touch2_location(10, 11);
+  generator.MoveTouchId(touch2_location, 2);
+  generator.PressTouchId(3);
+  gfx::Point touch3_location(20, 21);
+  generator.MoveTouchId(touch3_location, 3);
+  ClearCapturedEvents();
+
+  // Release of finger 1 should be rewritten as a release of finger 2.
+  generator.ReleaseTouchId(1);
+  const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
+  ASSERT_EQ(1u, captured_events.size());
+  EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[0]->type());
+  ui::TouchEvent* touch_event =
+      static_cast<ui::TouchEvent*>(captured_events[0]);
+  EXPECT_EQ(2, touch_event->touch_id());
+  EXPECT_EQ(touch2_location, touch_event->location());
+  ClearCapturedEvents();
+
+  // Release of finger 2 should be rewritten as a release of finger 3, plus
+  // we should enter the mouse move mode and a mouse move event should be
+  // dispatched.
+  cursor_client()->ShowCursor();
+  cursor_client()->DisableMouseEvents();
+  generator.ReleaseTouchId(2);
+  EXPECT_TRUE(IsInTouchToMouseMode());
+  ASSERT_GE(2u, captured_events.size());
+  EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[0]->type());
+  touch_event = static_cast<ui::TouchEvent*>(captured_events[0]);
+  EXPECT_EQ(3, touch_event->touch_id());
+  EXPECT_EQ(touch3_location, touch_event->location());
+  // TODO(mfomitchev): mouse enter/exit events
+  ScopedVector<ui::LocatedEvent>::const_iterator it;
+  for (it = captured_events.begin(); it != captured_events.end(); ++it) {
+    if ((*it)->type() == ui::ET_MOUSE_MOVED) {
+      EXPECT_EQ(touch3_location, (*it)->location());
+      break;
+    }
+  }
+  EXPECT_NE(captured_events.end(), it);
+}
+
+}  // namespace ui
diff --git a/ui/chromeos/ui_chromeos.gyp b/ui/chromeos/ui_chromeos.gyp
index 7f7362e..9a87672 100644
--- a/ui/chromeos/ui_chromeos.gyp
+++ b/ui/chromeos/ui_chromeos.gyp
@@ -12,6 +12,8 @@
       'type': '<(component)',
       'dependencies': [
         '../../base/base.gyp:base',
+        '../../skia/skia.gyp:skia',
+        '../aura/aura.gyp:aura',
         '../events/events.gyp:events',
         '../wm/wm.gyp:wm',
       ],
@@ -19,6 +21,8 @@
         'UI_CHROMEOS_IMPLEMENTATION',
       ],
       'sources': [
+        'touch_exploration_controller.cc',
+        'touch_exploration_controller.h',
         'user_activity_power_manager_notifier.cc',
         'user_activity_power_manager_notifier.h',
       ],
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index 423f2bf..788cd48 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -41,7 +41,6 @@
 
 bool g_compositor_initialized = false;
 base::Thread* g_compositor_thread = NULL;
-cc::SharedBitmapManager* g_shared_bitmap_manager;
 
 ui::ContextFactory* g_context_factory = NULL;
 
@@ -160,12 +159,12 @@
   if (!!g_compositor_thread) {
     host_ = cc::LayerTreeHost::CreateThreaded(
         this,
-        g_shared_bitmap_manager,
+        g_context_factory->GetSharedBitmapManager(),
         settings,
         g_compositor_thread->message_loop_proxy());
   } else {
     host_ = cc::LayerTreeHost::CreateSingleThreaded(
-        this, this, g_shared_bitmap_manager, settings);
+        this, this, g_context_factory->GetSharedBitmapManager(), settings);
   }
   UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor",
                       base::TimeTicks::Now() - before_create);
@@ -234,11 +233,6 @@
   g_compositor_initialized = false;
 }
 
-// static
-void Compositor::SetSharedBitmapManager(cc::SharedBitmapManager* manager) {
-  g_shared_bitmap_manager = manager;
-}
-
 void Compositor::ScheduleDraw() {
   if (g_compositor_thread) {
     host_->Composite(gfx::FrameTime::Now());
diff --git a/ui/compositor/compositor.gyp b/ui/compositor/compositor.gyp
index 1145e8e..2822397 100644
--- a/ui/compositor/compositor.gyp
+++ b/ui/compositor/compositor.gyp
@@ -162,8 +162,7 @@
         }],
         ['os_posix == 1 and OS != "mac"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
               'dependencies': [
                 '<(DEPTH)/base/allocator/allocator.gyp:allocator',
               ],
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index 13e6e1a..3cc0269 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -93,6 +93,9 @@
   // When true, the factory uses test contexts that do not do real GL
   // operations.
   virtual bool DoesCreateTestContexts() = 0;
+
+  // Gets the shared bitmap manager for software mode.
+  virtual cc::SharedBitmapManager* GetSharedBitmapManager() = 0;
 };
 
 // This class represents a lock on the compositor, that can be used to prevent
@@ -136,7 +139,6 @@
   static bool WasInitializedWithThread();
   static scoped_refptr<base::MessageLoopProxy> GetCompositorMessageLoop();
   static void Terminate();
-  static void SetSharedBitmapManager(cc::SharedBitmapManager* manager);
 
   // Schedules a redraw of the layer tree associated with this compositor.
   void ScheduleDraw();
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc
index a0a3bca..81cff54 100644
--- a/ui/compositor/layer.cc
+++ b/ui/compositor/layer.cc
@@ -654,7 +654,8 @@
 
 void Layer::PaintContents(SkCanvas* sk_canvas,
                           const gfx::Rect& clip,
-                          gfx::RectF* opaque) {
+                          gfx::RectF* opaque,
+                          ContentLayerClient::GraphicsContextStatus gc_status) {
   TRACE_EVENT0("ui", "Layer::PaintContents");
   scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
       sk_canvas, device_scale_factor_));
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h
index c42cbfe..3cc7aa8 100644
--- a/ui/compositor/layer.h
+++ b/ui/compositor/layer.h
@@ -315,7 +315,10 @@
 
   // ContentLayerClient
   virtual void PaintContents(
-      SkCanvas* canvas, const gfx::Rect& clip, gfx::RectF* opaque) OVERRIDE;
+      SkCanvas* canvas,
+      const gfx::Rect& clip,
+      gfx::RectF* opaque,
+      ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE;
   virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
   virtual bool FillsBoundsCompletely() const OVERRIDE;
 
diff --git a/ui/compositor/test/context_factories_for_test.cc b/ui/compositor/test/context_factories_for_test.cc
index 6e842dd..045739d 100644
--- a/ui/compositor/test/context_factories_for_test.cc
+++ b/ui/compositor/test/context_factories_for_test.cc
@@ -6,7 +6,6 @@
 
 #include "base/command_line.h"
 #include "base/sys_info.h"
-#include "cc/test/test_shared_bitmap_manager.h"
 #include "ui/compositor/compositor.h"
 #include "ui/compositor/compositor_switches.h"
 #include "ui/compositor/test/in_process_context_factory.h"
@@ -16,7 +15,6 @@
 
 static ui::ContextFactory* g_implicit_factory = NULL;
 static gfx::DisableNullDrawGLBindings* g_disable_null_draw = NULL;
-static cc::TestSharedBitmapManager* g_shared_bitmap_manager = NULL;
 
 }  // namespace
 
@@ -33,17 +31,12 @@
     g_disable_null_draw = new gfx::DisableNullDrawGLBindings;
   g_implicit_factory = new InProcessContextFactory();
   ContextFactory::SetInstance(g_implicit_factory);
-  g_shared_bitmap_manager = new cc::TestSharedBitmapManager();
-  Compositor::SetSharedBitmapManager(g_shared_bitmap_manager);
 }
 
 void TerminateContextFactoryForTests() {
   ContextFactory::SetInstance(NULL);
   delete g_implicit_factory;
   g_implicit_factory = NULL;
-  Compositor::SetSharedBitmapManager(NULL);
-  delete g_shared_bitmap_manager;
-  g_shared_bitmap_manager = NULL;
   delete g_disable_null_draw;
   g_disable_null_draw = NULL;
 }
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc
index 959d984..7aa8098 100644
--- a/ui/compositor/test/in_process_context_factory.cc
+++ b/ui/compositor/test/in_process_context_factory.cc
@@ -5,6 +5,7 @@
 #include "ui/compositor/test/in_process_context_factory.h"
 
 #include "cc/output/output_surface.h"
+#include "cc/test/test_shared_bitmap_manager.h"
 #include "ui/compositor/reflector.h"
 #include "ui/gl/gl_implementation.h"
 #include "ui/gl/gl_surface.h"
@@ -14,7 +15,8 @@
 
 namespace ui {
 
-InProcessContextFactory::InProcessContextFactory() {
+InProcessContextFactory::InProcessContextFactory()
+    : shared_bitmap_manager_(new cc::TestSharedBitmapManager()) {
   DCHECK_NE(gfx::GetGLImplementation(), gfx::kGLImplementationNone);
 }
 
@@ -74,4 +76,8 @@
 
 bool InProcessContextFactory::DoesCreateTestContexts() { return false; }
 
+cc::SharedBitmapManager* InProcessContextFactory::GetSharedBitmapManager() {
+  return shared_bitmap_manager_.get();
+}
+
 }  // namespace ui
diff --git a/ui/compositor/test/in_process_context_factory.h b/ui/compositor/test/in_process_context_factory.h
index ae44c94..5c7cf8b 100644
--- a/ui/compositor/test/in_process_context_factory.h
+++ b/ui/compositor/test/in_process_context_factory.h
@@ -34,10 +34,12 @@
       OVERRIDE;
   virtual void RemoveCompositor(Compositor* compositor) OVERRIDE;
   virtual bool DoesCreateTestContexts() OVERRIDE;
+  virtual cc::SharedBitmapManager* GetSharedBitmapManager() OVERRIDE;
 
  private:
   scoped_refptr<webkit::gpu::ContextProviderInProcess>
       shared_main_thread_contexts_;
+  scoped_ptr<cc::SharedBitmapManager> shared_bitmap_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(InProcessContextFactory);
 };
diff --git a/ui/display/chromeos/x11/native_display_delegate_x11.cc b/ui/display/chromeos/x11/native_display_delegate_x11.cc
index f6acd60..fb965d9 100644
--- a/ui/display/chromeos/x11/native_display_delegate_x11.cc
+++ b/ui/display/chromeos/x11/native_display_delegate_x11.cc
@@ -296,10 +296,12 @@
   int current_height = DisplayHeight(display_, DefaultScreen(display_));
   VLOG(1) << "CreateFrameBuffer: new=" << size.width() << "x" << size.height()
           << " current=" << current_width << "x" << current_height;
+
+  DestroyUnusedCrtcs(size);
+
   if (size.width() == current_width && size.height() == current_height)
     return;
 
-  DestroyUnusedCrtcs(size);
   int mm_width = size.width() * kPixelsToMmScale;
   int mm_height = size.height() * kPixelsToMmScale;
   XRRSetScreenSize(
diff --git a/ui/events/dom4_keycode_converter.target.darwin-arm.mk b/ui/events/dom4_keycode_converter.target.darwin-arm.mk
index b0a045c..57f759a 100644
--- a/ui/events/dom4_keycode_converter.target.darwin-arm.mk
+++ b/ui/events/dom4_keycode_converter.target.darwin-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -127,7 +126,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/events/dom4_keycode_converter.target.darwin-x86.mk b/ui/events/dom4_keycode_converter.target.darwin-x86.mk
index ed11429..57618d4 100644
--- a/ui/events/dom4_keycode_converter.target.darwin-x86.mk
+++ b/ui/events/dom4_keycode_converter.target.darwin-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/events/dom4_keycode_converter.target.darwin-x86_64.mk b/ui/events/dom4_keycode_converter.target.darwin-x86_64.mk
index da5b2ad..3dcd1e8 100644
--- a/ui/events/dom4_keycode_converter.target.darwin-x86_64.mk
+++ b/ui/events/dom4_keycode_converter.target.darwin-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/events/dom4_keycode_converter.target.linux-arm.mk b/ui/events/dom4_keycode_converter.target.linux-arm.mk
index b0a045c..57f759a 100644
--- a/ui/events/dom4_keycode_converter.target.linux-arm.mk
+++ b/ui/events/dom4_keycode_converter.target.linux-arm.mk
@@ -41,7 +41,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -127,7 +126,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/events/dom4_keycode_converter.target.linux-x86.mk b/ui/events/dom4_keycode_converter.target.linux-x86.mk
index ed11429..57618d4 100644
--- a/ui/events/dom4_keycode_converter.target.linux-x86.mk
+++ b/ui/events/dom4_keycode_converter.target.linux-x86.mk
@@ -43,7 +43,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/events/dom4_keycode_converter.target.linux-x86_64.mk b/ui/events/dom4_keycode_converter.target.linux-x86_64.mk
index da5b2ad..3dcd1e8 100644
--- a/ui/events/dom4_keycode_converter.target.linux-x86_64.mk
+++ b/ui/events/dom4_keycode_converter.target.linux-x86_64.mk
@@ -43,7 +43,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -129,7 +128,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/events/event_constants.h b/ui/events/event_constants.h
index 0c4e404..5564312 100644
--- a/ui/events/event_constants.h
+++ b/ui/events/event_constants.h
@@ -84,7 +84,9 @@
   EF_LEFT_MOUSE_BUTTON   = 1 << 4,
   EF_MIDDLE_MOUSE_BUTTON = 1 << 5,
   EF_RIGHT_MOUSE_BUTTON  = 1 << 6,
-  EF_COMMAND_DOWN        = 1 << 7,  // Only useful on OSX
+  EF_COMMAND_DOWN        = 1 << 7,  // GUI Key (e.g. Command on OS X keyboards,
+                                    // Search on Chromebook keyboards,
+                                    // Windows on MS-oriented keyboards)
   EF_EXTENDED            = 1 << 8,  // Windows extended key (see WM_KEYDOWN doc)
   EF_IS_SYNTHESIZED      = 1 << 9,
   EF_ALTGR_DOWN          = 1 << 10,
diff --git a/ui/events/event_switches.cc b/ui/events/event_switches.cc
index 829b9d0..93e938f 100644
--- a/ui/events/event_switches.cc
+++ b/ui/events/event_switches.cc
@@ -19,6 +19,8 @@
 const char kTouchEventsEnabled[] = "enabled";
 //   disabled: touch events are disabled.
 const char kTouchEventsDisabled[] = "disabled";
+// Use the unified gesture detector, instead of the aura gesture detector.
+const char kUseUnifiedGestureDetector[] = "use-unified-gesture-detector";
 
 #if defined(OS_LINUX)
 // Tells chrome to interpret events from these devices as touch events. Only
diff --git a/ui/events/event_switches.h b/ui/events/event_switches.h
index 7ac2722..07cf083 100644
--- a/ui/events/event_switches.h
+++ b/ui/events/event_switches.h
@@ -15,6 +15,7 @@
 EVENTS_BASE_EXPORT extern const char kTouchEventsAuto[];
 EVENTS_BASE_EXPORT extern const char kTouchEventsEnabled[];
 EVENTS_BASE_EXPORT extern const char kTouchEventsDisabled[];
+EVENTS_BASE_EXPORT extern const char kUseUnifiedGestureDetector[];
 
 #if defined(OS_LINUX)
 EVENTS_BASE_EXPORT extern const char kTouchDevices[];
diff --git a/ui/events/event_targeter.cc b/ui/events/event_targeter.cc
index 85b4c3f..e76b589 100644
--- a/ui/events/event_targeter.cc
+++ b/ui/events/event_targeter.cc
@@ -52,7 +52,8 @@
 
 bool EventTargeter::SubtreeShouldBeExploredForEvent(EventTarget* target,
                                                     const LocatedEvent& event) {
-  return true;
+  return SubtreeCanAcceptEvent(target, event) &&
+         EventLocationInsideBounds(target, event);
 }
 
 EventTarget* EventTargeter::FindNextBestTarget(EventTarget* previous_target,
@@ -60,4 +61,14 @@
   return NULL;
 }
 
+bool EventTargeter::SubtreeCanAcceptEvent(EventTarget* target,
+                                          const LocatedEvent& event) const {
+  return true;
+}
+
+bool EventTargeter::EventLocationInsideBounds(EventTarget* target,
+                                              const LocatedEvent& event) const {
+  return true;
+}
+
 }  // namespace ui
diff --git a/ui/events/event_targeter.h b/ui/events/event_targeter.h
index 44ea2a0..dead49f 100644
--- a/ui/events/event_targeter.h
+++ b/ui/events/event_targeter.h
@@ -32,9 +32,13 @@
   virtual EventTarget* FindTargetForLocatedEvent(EventTarget* root,
                                                  LocatedEvent* event);
 
-  // Returns true of |target| or one of its descendants can be a target of
-  // |event|. Note that the location etc. of |event| is in |target|'s parent's
-  // coordinate system.
+  // Returns true if |target| or one of its descendants can be a target of
+  // |event|. This requires that |target| and its descendants are not
+  // prohibited from accepting the event, and that the event is within an
+  // actionable region of the target's bounds. Note that the location etc. of
+  // |event| is in |target|'s parent's coordinate system.
+  // TODO(tdanderson|sadrul): This function should be made non-virtual and
+  //                          non-public.
   virtual bool SubtreeShouldBeExploredForEvent(EventTarget* target,
                                                const LocatedEvent& event);
 
@@ -44,6 +48,21 @@
   // coordinate space).
   virtual EventTarget* FindNextBestTarget(EventTarget* previous_target,
                                           Event* event);
+
+ protected:
+  // Returns false if neither |target| nor any of its descendants are allowed
+  // to accept |event| for reasons unrelated to the event's location or the
+  // target's bounds. For example, overrides of this function may consider
+  // attributes such as the visibility or enabledness of |target|. Note that
+  // the location etc. of |event| is in |target|'s parent's coordinate system.
+  virtual bool SubtreeCanAcceptEvent(EventTarget* target,
+                                     const LocatedEvent& event) const;
+
+  // Returns whether the location of the event is in an actionable region of the
+  // target. Note that the location etc. of |event| is in the |target|'s
+  // parent's coordinate system.
+  virtual bool EventLocationInsideBounds(EventTarget* target,
+                                         const LocatedEvent& event) const;
 };
 
 }  // namespace ui
diff --git a/ui/events/events.gyp b/ui/events/events.gyp
index fed04fb..7b810b7 100644
--- a/ui/events/events.gyp
+++ b/ui/events/events.gyp
@@ -39,6 +39,8 @@
         'events_base_export.h',
         'gesture_event_details.cc',
         'gesture_event_details.h',
+        'gestures/gesture_configuration.cc',
+        'gestures/gesture_configuration.h',
         'keycodes/keyboard_code_conversion.cc',
         'keycodes/keyboard_code_conversion.h',
         'keycodes/keyboard_code_conversion_android.cc',
@@ -78,6 +80,7 @@
         '../gfx/gfx.gyp:gfx',
         '../gfx/gfx.gyp:gfx_geometry',
         'events_base',
+        'gesture_detection',
       ],
       'defines': [
         'EVENTS_IMPLEMENTATION',
@@ -106,16 +109,18 @@
         'event_utils.h',
         'events_export.h',
         'events_stub.cc',
-        'gestures/gesture_configuration.cc',
-        'gestures/gesture_configuration.h',
         'gestures/gesture_point.cc',
         'gestures/gesture_point.h',
+        'gestures/gesture_provider_aura.cc',
+        'gestures/gesture_provider_aura.h',
         'gestures/gesture_recognizer.h',
         'gestures/gesture_recognizer_impl.cc',
         'gestures/gesture_recognizer_impl.h',
         'gestures/gesture_sequence.cc',
         'gestures/gesture_sequence.h',
         'gestures/gesture_types.h',
+        'gestures/motion_event_aura.cc',
+        'gestures/motion_event_aura.h',
         'gestures/velocity_calculator.cc',
         'gestures/velocity_calculator.h',
         'ozone/device/device_event.cc',
@@ -171,6 +176,24 @@
         'linux/text_edit_key_bindings_delegate_auralinux.h',
       ],
       'conditions': [
+        ['use_aura==0', {
+          'sources!': [
+            'gestures/gesture_point.cc',
+            'gestures/gesture_point.h',
+            'gestures/gesture_provider_aura.cc',
+            'gestures/gesture_provider_aura.h',
+            'gestures/gesture_recognizer.h',
+            'gestures/gesture_recognizer_impl.cc',
+            'gestures/gesture_recognizer_impl.h',
+            'gestures/gesture_sequence.cc',
+            'gestures/gesture_sequence.h',
+            'gestures/gesture_types.h',
+            'gestures/motion_event_aura.cc',
+            'gestures/motion_event_aura.h',
+            'gestures/velocity_calculator.cc',
+            'gestures/velocity_calculator.h',
+          ],
+        }],
         # We explicitly enumerate the platforms we _do_ provide native cracking
         # for here.
         ['OS=="win" or OS=="mac" or use_x11==1 or use_ozone==1', {
@@ -253,6 +276,9 @@
         'gesture_detection/bitset_32.h',
         'gesture_detection/filtered_gesture_provider.cc',
         'gesture_detection/filtered_gesture_provider.h',
+        'gesture_detection/gesture_config_helper.h',
+        'gesture_detection/gesture_config_helper_android.cc',
+        'gesture_detection/gesture_config_helper_aura.cc',
         'gesture_detection/gesture_detection_export.h',
         'gesture_detection/gesture_detector.cc',
         'gesture_detection/gesture_detector.h',
@@ -260,9 +286,6 @@
         'gesture_detection/gesture_event_data.h',
         'gesture_detection/gesture_event_data_packet.cc',
         'gesture_detection/gesture_event_data_packet.h',
-        'gesture_detection/gesture_config_helper.h',
-        'gesture_detection/gesture_config_helper_aura.cc',
-        'gesture_detection/gesture_config_helper_android.cc',
         'gesture_detection/gesture_provider.cc',
         'gesture_detection/gesture_provider.h',
         'gesture_detection/motion_event.h',
@@ -278,11 +301,6 @@
         'gesture_detection/velocity_tracker.h',
       ],
       'conditions': [
-        ['use_aura==1', {
-          'dependencies': [
-            'events'
-          ],
-        }],
         ['use_aura!=1 and OS!="android"', {
           'sources': [
             'gesture_detection/gesture_config_helper.cc',
@@ -340,7 +358,7 @@
         'events',
         'events_base',
         'events_test_support',
-        'gesture_detection'
+        'gesture_detection',
       ],
       'sources': [
         'cocoa/events_mac_unittest.mm',
@@ -348,6 +366,7 @@
         'event_processor_unittest.cc',
         'event_rewriter_unittest.cc',
         'event_unittest.cc',
+        'gestures/motion_event_aura_unittest.cc',
         'gestures/velocity_calculator_unittest.cc',
         'gesture_detection/bitset_32_unittest.cc',
         'gesture_detection/gesture_provider_unittest.cc',
@@ -363,8 +382,13 @@
         'x/events_x_unittest.cc',
       ],
       'conditions': [
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['use_aura==0', {
+          'sources!': [
+            'gestures/motion_event_aura_unittest.cc',
+            'gestures/velocity_calculator_unittest.cc',
+          ],
+        }],
+        ['OS=="linux" and use_allocator!="none"', {
           'dependencies': [
             '<(DEPTH)/base/allocator/allocator.gyp:allocator',
           ],
diff --git a/ui/events/events_base.target.darwin-arm.mk b/ui/events/events_base.target.darwin-arm.mk
index 1476dfe..9d3f6e4 100644
--- a/ui/events/events_base.target.darwin-arm.mk
+++ b/ui/events/events_base.target.darwin-arm.mk
@@ -27,6 +27,7 @@
 LOCAL_SRC_FILES := \
 	ui/events/event_switches.cc \
 	ui/events/gesture_event_details.cc \
+	ui/events/gestures/gesture_configuration.cc \
 	ui/events/keycodes/keyboard_code_conversion.cc \
 	ui/events/keycodes/keyboard_code_conversion_android.cc \
 	ui/events/latency_info.cc
@@ -46,7 +47,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -170,7 +165,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -219,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/events_base.target.darwin-arm64.mk b/ui/events/events_base.target.darwin-arm64.mk
index 2f39029..c91a5b1 100644
--- a/ui/events/events_base.target.darwin-arm64.mk
+++ b/ui/events/events_base.target.darwin-arm64.mk
@@ -27,6 +27,7 @@
 LOCAL_SRC_FILES := \
 	ui/events/event_switches.cc \
 	ui/events/gesture_event_details.cc \
+	ui/events/gestures/gesture_configuration.cc \
 	ui/events/keycodes/keyboard_code_conversion.cc \
 	ui/events/keycodes/keyboard_code_conversion_android.cc \
 	ui/events/latency_info.cc
@@ -91,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -210,11 +206,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/events_base.target.darwin-mips.mk b/ui/events/events_base.target.darwin-mips.mk
index a18ef72..bf542a4 100644
--- a/ui/events/events_base.target.darwin-mips.mk
+++ b/ui/events/events_base.target.darwin-mips.mk
@@ -27,6 +27,7 @@
 LOCAL_SRC_FILES := \
 	ui/events/event_switches.cc \
 	ui/events/gesture_event_details.cc \
+	ui/events/gestures/gesture_configuration.cc \
 	ui/events/keycodes/keyboard_code_conversion.cc \
 	ui/events/keycodes/keyboard_code_conversion_android.cc \
 	ui/events/latency_info.cc
@@ -94,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -217,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/events_base.target.darwin-x86.mk b/ui/events/events_base.target.darwin-x86.mk
index 816c652..d331a31 100644
--- a/ui/events/events_base.target.darwin-x86.mk
+++ b/ui/events/events_base.target.darwin-x86.mk
@@ -27,6 +27,7 @@
 LOCAL_SRC_FILES := \
 	ui/events/event_switches.cc \
 	ui/events/gesture_event_details.cc \
+	ui/events/gestures/gesture_configuration.cc \
 	ui/events/keycodes/keyboard_code_conversion.cc \
 	ui/events/keycodes/keyboard_code_conversion_android.cc \
 	ui/events/latency_info.cc
@@ -48,7 +49,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -96,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -172,7 +167,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,11 +214,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/events_base.target.darwin-x86_64.mk b/ui/events/events_base.target.darwin-x86_64.mk
index e4aaf20..49bdfef 100644
--- a/ui/events/events_base.target.darwin-x86_64.mk
+++ b/ui/events/events_base.target.darwin-x86_64.mk
@@ -27,6 +27,7 @@
 LOCAL_SRC_FILES := \
 	ui/events/event_switches.cc \
 	ui/events/gesture_event_details.cc \
+	ui/events/gestures/gesture_configuration.cc \
 	ui/events/keycodes/keyboard_code_conversion.cc \
 	ui/events/keycodes/keyboard_code_conversion_android.cc \
 	ui/events/latency_info.cc
@@ -48,7 +49,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -96,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -172,7 +167,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,11 +214,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/events_base.target.linux-arm.mk b/ui/events/events_base.target.linux-arm.mk
index 1476dfe..9d3f6e4 100644
--- a/ui/events/events_base.target.linux-arm.mk
+++ b/ui/events/events_base.target.linux-arm.mk
@@ -27,6 +27,7 @@
 LOCAL_SRC_FILES := \
 	ui/events/event_switches.cc \
 	ui/events/gesture_event_details.cc \
+	ui/events/gestures/gesture_configuration.cc \
 	ui/events/keycodes/keyboard_code_conversion.cc \
 	ui/events/keycodes/keyboard_code_conversion_android.cc \
 	ui/events/latency_info.cc
@@ -46,7 +47,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -170,7 +165,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -219,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/events_base.target.linux-arm64.mk b/ui/events/events_base.target.linux-arm64.mk
index 2f39029..c91a5b1 100644
--- a/ui/events/events_base.target.linux-arm64.mk
+++ b/ui/events/events_base.target.linux-arm64.mk
@@ -27,6 +27,7 @@
 LOCAL_SRC_FILES := \
 	ui/events/event_switches.cc \
 	ui/events/gesture_event_details.cc \
+	ui/events/gestures/gesture_configuration.cc \
 	ui/events/keycodes/keyboard_code_conversion.cc \
 	ui/events/keycodes/keyboard_code_conversion_android.cc \
 	ui/events/latency_info.cc
@@ -91,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -210,11 +206,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/events_base.target.linux-mips.mk b/ui/events/events_base.target.linux-mips.mk
index a18ef72..bf542a4 100644
--- a/ui/events/events_base.target.linux-mips.mk
+++ b/ui/events/events_base.target.linux-mips.mk
@@ -27,6 +27,7 @@
 LOCAL_SRC_FILES := \
 	ui/events/event_switches.cc \
 	ui/events/gesture_event_details.cc \
+	ui/events/gestures/gesture_configuration.cc \
 	ui/events/keycodes/keyboard_code_conversion.cc \
 	ui/events/keycodes/keyboard_code_conversion_android.cc \
 	ui/events/latency_info.cc
@@ -94,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -217,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/events_base.target.linux-x86.mk b/ui/events/events_base.target.linux-x86.mk
index 816c652..d331a31 100644
--- a/ui/events/events_base.target.linux-x86.mk
+++ b/ui/events/events_base.target.linux-x86.mk
@@ -27,6 +27,7 @@
 LOCAL_SRC_FILES := \
 	ui/events/event_switches.cc \
 	ui/events/gesture_event_details.cc \
+	ui/events/gestures/gesture_configuration.cc \
 	ui/events/keycodes/keyboard_code_conversion.cc \
 	ui/events/keycodes/keyboard_code_conversion_android.cc \
 	ui/events/latency_info.cc
@@ -48,7 +49,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -96,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -172,7 +167,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,11 +214,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/events_base.target.linux-x86_64.mk b/ui/events/events_base.target.linux-x86_64.mk
index e4aaf20..49bdfef 100644
--- a/ui/events/events_base.target.linux-x86_64.mk
+++ b/ui/events/events_base.target.linux-x86_64.mk
@@ -27,6 +27,7 @@
 LOCAL_SRC_FILES := \
 	ui/events/event_switches.cc \
 	ui/events/gesture_event_details.cc \
+	ui/events/gestures/gesture_configuration.cc \
 	ui/events/keycodes/keyboard_code_conversion.cc \
 	ui/events/keycodes/keyboard_code_conversion_android.cc \
 	ui/events/latency_info.cc
@@ -48,7 +49,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -96,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -172,7 +167,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,11 +214,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/gesture_detection.target.darwin-arm.mk b/ui/events/gesture_detection.target.darwin-arm.mk
index cbbfc18..5b07219 100644
--- a/ui/events/gesture_detection.target.darwin-arm.mk
+++ b/ui/events/gesture_detection.target.darwin-arm.mk
@@ -26,10 +26,10 @@
 
 LOCAL_SRC_FILES := \
 	ui/events/gesture_detection/filtered_gesture_provider.cc \
+	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_detector.cc \
 	ui/events/gesture_detection/gesture_event_data.cc \
 	ui/events/gesture_detection/gesture_event_data_packet.cc \
-	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_provider.cc \
 	ui/events/gesture_detection/scale_gesture_detector.cc \
 	ui/events/gesture_detection/snap_scroll_controller.cc \
@@ -52,7 +52,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -176,7 +170,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -225,11 +218,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/gesture_detection.target.darwin-arm64.mk b/ui/events/gesture_detection.target.darwin-arm64.mk
index f2e192a..d8768e0 100644
--- a/ui/events/gesture_detection.target.darwin-arm64.mk
+++ b/ui/events/gesture_detection.target.darwin-arm64.mk
@@ -26,10 +26,10 @@
 
 LOCAL_SRC_FILES := \
 	ui/events/gesture_detection/filtered_gesture_provider.cc \
+	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_detector.cc \
 	ui/events/gesture_detection/gesture_event_data.cc \
 	ui/events/gesture_detection/gesture_event_data_packet.cc \
-	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_provider.cc \
 	ui/events/gesture_detection/scale_gesture_detector.cc \
 	ui/events/gesture_detection/snap_scroll_controller.cc \
@@ -97,11 +97,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -216,11 +211,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/gesture_detection.target.darwin-mips.mk b/ui/events/gesture_detection.target.darwin-mips.mk
index 4bb9390..6209359 100644
--- a/ui/events/gesture_detection.target.darwin-mips.mk
+++ b/ui/events/gesture_detection.target.darwin-mips.mk
@@ -26,10 +26,10 @@
 
 LOCAL_SRC_FILES := \
 	ui/events/gesture_detection/filtered_gesture_provider.cc \
+	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_detector.cc \
 	ui/events/gesture_detection/gesture_event_data.cc \
 	ui/events/gesture_detection/gesture_event_data_packet.cc \
-	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_provider.cc \
 	ui/events/gesture_detection/scale_gesture_detector.cc \
 	ui/events/gesture_detection/snap_scroll_controller.cc \
@@ -100,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -223,11 +218,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/gesture_detection.target.darwin-x86.mk b/ui/events/gesture_detection.target.darwin-x86.mk
index 500e5a9..24cb538 100644
--- a/ui/events/gesture_detection.target.darwin-x86.mk
+++ b/ui/events/gesture_detection.target.darwin-x86.mk
@@ -26,10 +26,10 @@
 
 LOCAL_SRC_FILES := \
 	ui/events/gesture_detection/filtered_gesture_provider.cc \
+	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_detector.cc \
 	ui/events/gesture_detection/gesture_event_data.cc \
 	ui/events/gesture_detection/gesture_event_data_packet.cc \
-	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_provider.cc \
 	ui/events/gesture_detection/scale_gesture_detector.cc \
 	ui/events/gesture_detection/snap_scroll_controller.cc \
@@ -54,7 +54,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -102,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -226,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/gesture_detection.target.darwin-x86_64.mk b/ui/events/gesture_detection.target.darwin-x86_64.mk
index 0c7c065..aa9840f 100644
--- a/ui/events/gesture_detection.target.darwin-x86_64.mk
+++ b/ui/events/gesture_detection.target.darwin-x86_64.mk
@@ -26,10 +26,10 @@
 
 LOCAL_SRC_FILES := \
 	ui/events/gesture_detection/filtered_gesture_provider.cc \
+	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_detector.cc \
 	ui/events/gesture_detection/gesture_event_data.cc \
 	ui/events/gesture_detection/gesture_event_data_packet.cc \
-	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_provider.cc \
 	ui/events/gesture_detection/scale_gesture_detector.cc \
 	ui/events/gesture_detection/snap_scroll_controller.cc \
@@ -54,7 +54,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -102,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -226,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/gesture_detection.target.linux-arm.mk b/ui/events/gesture_detection.target.linux-arm.mk
index cbbfc18..5b07219 100644
--- a/ui/events/gesture_detection.target.linux-arm.mk
+++ b/ui/events/gesture_detection.target.linux-arm.mk
@@ -26,10 +26,10 @@
 
 LOCAL_SRC_FILES := \
 	ui/events/gesture_detection/filtered_gesture_provider.cc \
+	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_detector.cc \
 	ui/events/gesture_detection/gesture_event_data.cc \
 	ui/events/gesture_detection/gesture_event_data_packet.cc \
-	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_provider.cc \
 	ui/events/gesture_detection/scale_gesture_detector.cc \
 	ui/events/gesture_detection/snap_scroll_controller.cc \
@@ -52,7 +52,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -176,7 +170,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -225,11 +218,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/gesture_detection.target.linux-arm64.mk b/ui/events/gesture_detection.target.linux-arm64.mk
index f2e192a..d8768e0 100644
--- a/ui/events/gesture_detection.target.linux-arm64.mk
+++ b/ui/events/gesture_detection.target.linux-arm64.mk
@@ -26,10 +26,10 @@
 
 LOCAL_SRC_FILES := \
 	ui/events/gesture_detection/filtered_gesture_provider.cc \
+	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_detector.cc \
 	ui/events/gesture_detection/gesture_event_data.cc \
 	ui/events/gesture_detection/gesture_event_data_packet.cc \
-	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_provider.cc \
 	ui/events/gesture_detection/scale_gesture_detector.cc \
 	ui/events/gesture_detection/snap_scroll_controller.cc \
@@ -97,11 +97,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -216,11 +211,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/gesture_detection.target.linux-mips.mk b/ui/events/gesture_detection.target.linux-mips.mk
index 4bb9390..6209359 100644
--- a/ui/events/gesture_detection.target.linux-mips.mk
+++ b/ui/events/gesture_detection.target.linux-mips.mk
@@ -26,10 +26,10 @@
 
 LOCAL_SRC_FILES := \
 	ui/events/gesture_detection/filtered_gesture_provider.cc \
+	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_detector.cc \
 	ui/events/gesture_detection/gesture_event_data.cc \
 	ui/events/gesture_detection/gesture_event_data_packet.cc \
-	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_provider.cc \
 	ui/events/gesture_detection/scale_gesture_detector.cc \
 	ui/events/gesture_detection/snap_scroll_controller.cc \
@@ -100,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -223,11 +218,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/gesture_detection.target.linux-x86.mk b/ui/events/gesture_detection.target.linux-x86.mk
index 500e5a9..24cb538 100644
--- a/ui/events/gesture_detection.target.linux-x86.mk
+++ b/ui/events/gesture_detection.target.linux-x86.mk
@@ -26,10 +26,10 @@
 
 LOCAL_SRC_FILES := \
 	ui/events/gesture_detection/filtered_gesture_provider.cc \
+	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_detector.cc \
 	ui/events/gesture_detection/gesture_event_data.cc \
 	ui/events/gesture_detection/gesture_event_data_packet.cc \
-	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_provider.cc \
 	ui/events/gesture_detection/scale_gesture_detector.cc \
 	ui/events/gesture_detection/snap_scroll_controller.cc \
@@ -54,7 +54,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -102,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -226,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/gesture_detection.target.linux-x86_64.mk b/ui/events/gesture_detection.target.linux-x86_64.mk
index 0c7c065..aa9840f 100644
--- a/ui/events/gesture_detection.target.linux-x86_64.mk
+++ b/ui/events/gesture_detection.target.linux-x86_64.mk
@@ -26,10 +26,10 @@
 
 LOCAL_SRC_FILES := \
 	ui/events/gesture_detection/filtered_gesture_provider.cc \
+	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_detector.cc \
 	ui/events/gesture_detection/gesture_event_data.cc \
 	ui/events/gesture_detection/gesture_event_data_packet.cc \
-	ui/events/gesture_detection/gesture_config_helper_android.cc \
 	ui/events/gesture_detection/gesture_provider.cc \
 	ui/events/gesture_detection/scale_gesture_detector.cc \
 	ui/events/gesture_detection/snap_scroll_controller.cc \
@@ -54,7 +54,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -102,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -226,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/events/gesture_detection/gesture_config_helper_aura.cc b/ui/events/gesture_detection/gesture_config_helper_aura.cc
index 420b7fa..836d04b 100644
--- a/ui/events/gesture_detection/gesture_config_helper_aura.cc
+++ b/ui/events/gesture_detection/gesture_config_helper_aura.cc
@@ -2,8 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// MSVC++ requires this to be set before any other includes to get M_PI.
+#define _USE_MATH_DEFINES
+
 #include "ui/events/gesture_detection/gesture_config_helper.h"
 
+#include <cmath>
+
 #include "ui/events/gestures/gesture_configuration.h"
 #include "ui/gfx/screen.h"
 
@@ -30,7 +35,8 @@
   config.swipe_enabled = true;
   config.minimum_swipe_velocity = GestureConfiguration::min_swipe_speed();
   config.maximum_swipe_deviation_angle =
-      atan2(1.f, GestureConfiguration::max_swipe_deviation_ratio());
+      atan2(1.f, GestureConfiguration::max_swipe_deviation_ratio()) * 180.0f /
+      static_cast<float>(M_PI);
 
   return config;
 }
@@ -40,8 +46,7 @@
 
   config.gesture_detector_config = DefaultGestureDetectorConfig();
   config.min_scaling_touch_major = GestureConfiguration::default_radius() * 2;
-  config.min_scaling_span =
-      GestureConfiguration::min_distance_for_pinch_scroll_in_pixels();
+  config.min_scaling_span = GestureConfiguration::min_scaling_span_in_pixels();
   return config;
 }
 
diff --git a/ui/events/gesture_detection/gesture_event_data_packet.cc b/ui/events/gesture_detection/gesture_event_data_packet.cc
index a02217c..58d4e50 100644
--- a/ui/events/gesture_detection/gesture_event_data_packet.cc
+++ b/ui/events/gesture_detection/gesture_event_data_packet.cc
@@ -35,14 +35,16 @@
 GestureEventDataPacket::GestureEventDataPacket()
     : gesture_count_(0), gesture_source_(UNDEFINED) {}
 
-GestureEventDataPacket::GestureEventDataPacket(GestureSource source)
-    : gesture_count_(0), gesture_source_(source) {
+GestureEventDataPacket::GestureEventDataPacket(base::TimeTicks timestamp,
+                                               GestureSource source)
+    : timestamp_(timestamp), gesture_count_(0), gesture_source_(source) {
   DCHECK_NE(gesture_source_, UNDEFINED);
 }
 
 GestureEventDataPacket::GestureEventDataPacket(
     const GestureEventDataPacket& other)
-    : gesture_count_(other.gesture_count_),
+    : timestamp_(other.timestamp_),
+      gesture_count_(other.gesture_count_),
       gesture_source_(other.gesture_source_) {
   std::copy(other.gestures_, other.gestures_ + other.gesture_count_, gestures_);
 }
@@ -51,6 +53,7 @@
 
 GestureEventDataPacket& GestureEventDataPacket::operator=(
     const GestureEventDataPacket& other) {
+  timestamp_ = other.timestamp_;
   gesture_count_ = other.gesture_count_;
   gesture_source_ = other.gesture_source_;
   std::copy(other.gestures_, other.gestures_ + other.gesture_count_, gestures_);
@@ -65,12 +68,12 @@
 
 GestureEventDataPacket GestureEventDataPacket::FromTouch(
     const ui::MotionEvent& touch) {
-  return GestureEventDataPacket(ToGestureSource(touch));
+  return GestureEventDataPacket(touch.GetEventTime(), ToGestureSource(touch));
 }
 
 GestureEventDataPacket GestureEventDataPacket::FromTouchTimeout(
     const GestureEventData& gesture) {
-  GestureEventDataPacket packet(TOUCH_TIMEOUT);
+  GestureEventDataPacket packet(gesture.time, TOUCH_TIMEOUT);
   packet.Push(gesture);
   return packet;
 }
diff --git a/ui/events/gesture_detection/gesture_event_data_packet.h b/ui/events/gesture_detection/gesture_event_data_packet.h
index 999d9a0..fee86f1 100644
--- a/ui/events/gesture_detection/gesture_event_data_packet.h
+++ b/ui/events/gesture_detection/gesture_event_data_packet.h
@@ -40,14 +40,16 @@
 
   void Push(const GestureEventData& gesture);
 
+  const base::TimeTicks& timestamp() const { return timestamp_; }
   const GestureEventData& gesture(size_t i) const { return gestures_[i]; }
   size_t gesture_count() const { return gesture_count_; }
   GestureSource gesture_source() const { return gesture_source_; }
 
  private:
-  explicit GestureEventDataPacket(GestureSource source);
+  GestureEventDataPacket(base::TimeTicks timestamp, GestureSource source);
 
   enum { kMaxGesturesPerTouch = 5 };
+  base::TimeTicks timestamp_;
   GestureEventData gestures_[kMaxGesturesPerTouch];
   size_t gesture_count_;
   GestureSource gesture_source_;
diff --git a/ui/events/gesture_detection/mock_motion_event.cc b/ui/events/gesture_detection/mock_motion_event.cc
index 3ee63df..26d884f 100644
--- a/ui/events/gesture_detection/mock_motion_event.cc
+++ b/ui/events/gesture_detection/mock_motion_event.cc
@@ -72,10 +72,6 @@
   return id;
 }
 
-void MockMotionEvent::SetId(int new_id) {
-  id = new_id;
-}
-
 int MockMotionEvent::GetPointerId(size_t pointer_index) const {
   DCHECK(pointer_index < pointer_count);
   return static_cast<int>(pointer_index);
@@ -131,6 +127,14 @@
   return cancel_event.PassAs<MotionEvent>();
 }
 
+void MockMotionEvent::SetId(int new_id) {
+  id = new_id;
+}
+
+void MockMotionEvent::SetTime(base::TimeTicks new_time) {
+  time = new_time;
+}
+
 void MockMotionEvent::PressPoint(float x, float y) {
   // Reset the pointer count if the previously released and/or cancelled pointer
   // was the last pointer in the event.
diff --git a/ui/events/gesture_detection/mock_motion_event.h b/ui/events/gesture_detection/mock_motion_event.h
index 8d514fb..3cff718 100644
--- a/ui/events/gesture_detection/mock_motion_event.h
+++ b/ui/events/gesture_detection/mock_motion_event.h
@@ -64,6 +64,7 @@
 
   // Utility methods.
   void SetId(int new_id);
+  void SetTime(base::TimeTicks new_time);
   void PressPoint(float x, float y);
   void MovePoint(size_t index, float x, float y);
   void ReleasePoint();
diff --git a/ui/events/gesture_detection/motion_event.h b/ui/events/gesture_detection/motion_event.h
index f0d6354..741d1d5 100644
--- a/ui/events/gesture_detection/motion_event.h
+++ b/ui/events/gesture_detection/motion_event.h
@@ -31,6 +31,8 @@
 
   virtual int GetId() const = 0;
   virtual Action GetAction() const = 0;
+  // Only valid if |GetAction()| returns ACTION_POINTER_UP or
+  // ACTION_POINTER_DOWN.
   virtual int GetActionIndex() const = 0;
   virtual size_t GetPointerCount() const = 0;
   virtual int GetPointerId(size_t pointer_index) const = 0;
diff --git a/ui/events/gesture_detection/touch_disposition_gesture_filter.cc b/ui/events/gesture_detection/touch_disposition_gesture_filter.cc
index 6c47c23..bfff780 100644
--- a/ui/events/gesture_detection/touch_disposition_gesture_filter.cc
+++ b/ui/events/gesture_detection/touch_disposition_gesture_filter.cc
@@ -16,11 +16,12 @@
                gesture_type_count_too_large);
 
 GestureEventData CreateGesture(EventType type,
-                               int motion_event_id) {
+                               int motion_event_id,
+                               const base::TimeTicks& timestamp) {
   GestureEventDetails details(type, 0, 0);
   return GestureEventData(type,
                           motion_event_id,
-                          base::TimeTicks(),
+                          timestamp,
                           0,
                           0,
                           1,
@@ -204,23 +205,30 @@
 
 void TouchDispositionGestureFilter::FilterAndSendPacket(
     const GestureEventDataPacket& packet) {
+  if (packet.gesture_source() == GestureEventDataPacket::TOUCH_SEQUENCE_START) {
+    CancelTapIfNecessary(packet.timestamp());
+    EndScrollIfNecessary(packet.timestamp());
+    CancelFlingIfNecessary(packet.timestamp());
+  }
+
   for (size_t i = 0; i < packet.gesture_count(); ++i) {
     const GestureEventData& gesture = packet.gesture(i);
     DCHECK(ET_GESTURE_TYPE_START <= gesture.type &&
            gesture.type <= ET_GESTURE_TYPE_END);
     if (state_.Filter(gesture.type)) {
-      CancelTapIfNecessary();
+      CancelTapIfNecessary(gesture.time);
       continue;
     }
     SendGesture(gesture);
   }
+
   if (packet.gesture_source() ==
       GestureEventDataPacket::TOUCH_SEQUENCE_CANCEL) {
-    EndScrollIfNecessary();
-    CancelTapIfNecessary();
+    EndScrollIfNecessary(packet.timestamp());
+    CancelTapIfNecessary(packet.timestamp());
   } else if (packet.gesture_source() ==
              GestureEventDataPacket::TOUCH_SEQUENCE_END) {
-    EndScrollIfNecessary();
+    EndScrollIfNecessary(packet.timestamp());
   }
 }
 
@@ -231,8 +239,8 @@
     case ET_GESTURE_LONG_TAP:
       if (!needs_tap_ending_event_)
         return;
-      CancelTapIfNecessary();
-      CancelFlingIfNecessary();
+      CancelTapIfNecessary(event.time);
+      CancelFlingIfNecessary(event.time);
       break;
     case ET_GESTURE_TAP_DOWN:
       DCHECK(!needs_tap_ending_event_);
@@ -246,7 +254,7 @@
       needs_show_press_event_ = false;
       break;
     case ET_GESTURE_DOUBLE_TAP:
-      CancelTapIfNecessary();
+      CancelTapIfNecessary(event.time);
       needs_show_press_event_ = false;
       break;
     case ET_GESTURE_TAP:
@@ -263,9 +271,9 @@
       needs_tap_ending_event_ = false;
       break;
     case ET_GESTURE_SCROLL_BEGIN:
-      CancelTapIfNecessary();
-      CancelFlingIfNecessary();
-      EndScrollIfNecessary();
+      CancelTapIfNecessary(event.time);
+      CancelFlingIfNecessary(event.time);
+      EndScrollIfNecessary(event.time);
       ending_event_motion_event_id_ = event.motion_event_id;
       needs_scroll_ending_event_ = true;
       break;
@@ -273,7 +281,7 @@
       needs_scroll_ending_event_ = false;
       break;
     case ET_SCROLL_FLING_START:
-      CancelFlingIfNecessary();
+      CancelFlingIfNecessary(event.time);
       ending_event_motion_event_id_ = event.motion_event_id;
       needs_fling_ending_event_ = true;
       needs_scroll_ending_event_ = false;
@@ -287,38 +295,38 @@
   client_->ForwardGestureEvent(event);
 }
 
-void TouchDispositionGestureFilter::CancelTapIfNecessary() {
+void TouchDispositionGestureFilter::CancelTapIfNecessary(
+    const base::TimeTicks& timestamp) {
   if (!needs_tap_ending_event_)
     return;
 
-  SendGesture(
-      CreateGesture(ET_GESTURE_TAP_CANCEL, ending_event_motion_event_id_));
+  SendGesture(CreateGesture(
+      ET_GESTURE_TAP_CANCEL, ending_event_motion_event_id_, timestamp));
   DCHECK(!needs_tap_ending_event_);
 }
 
-void TouchDispositionGestureFilter::CancelFlingIfNecessary() {
+void TouchDispositionGestureFilter::CancelFlingIfNecessary(
+    const base::TimeTicks& timestamp) {
   if (!needs_fling_ending_event_)
     return;
 
-  SendGesture(
-      CreateGesture(ET_SCROLL_FLING_CANCEL, ending_event_motion_event_id_));
+  SendGesture(CreateGesture(
+      ET_SCROLL_FLING_CANCEL, ending_event_motion_event_id_, timestamp));
   DCHECK(!needs_fling_ending_event_);
 }
 
-void TouchDispositionGestureFilter::EndScrollIfNecessary() {
+void TouchDispositionGestureFilter::EndScrollIfNecessary(
+    const base::TimeTicks& timestamp) {
   if (!needs_scroll_ending_event_)
     return;
 
-  SendGesture(
-      CreateGesture(ET_GESTURE_SCROLL_END, ending_event_motion_event_id_));
+  SendGesture(CreateGesture(
+      ET_GESTURE_SCROLL_END, ending_event_motion_event_id_, timestamp));
   DCHECK(!needs_scroll_ending_event_);
 }
 
 void TouchDispositionGestureFilter::PopGestureSequence() {
   DCHECK(Head().empty());
-  CancelTapIfNecessary();
-  CancelFlingIfNecessary();
-  EndScrollIfNecessary();
   state_ = GestureHandlingState();
   sequences_.pop();
 }
diff --git a/ui/events/gesture_detection/touch_disposition_gesture_filter.h b/ui/events/gesture_detection/touch_disposition_gesture_filter.h
index 6d5e51f..fc49301 100644
--- a/ui/events/gesture_detection/touch_disposition_gesture_filter.h
+++ b/ui/events/gesture_detection/touch_disposition_gesture_filter.h
@@ -78,9 +78,9 @@
 
   void FilterAndSendPacket(const GestureEventDataPacket& packet);
   void SendGesture(const GestureEventData& gesture);
-  void CancelTapIfNecessary();
-  void CancelFlingIfNecessary();
-  void EndScrollIfNecessary();
+  void CancelTapIfNecessary(const base::TimeTicks& timestamp);
+  void CancelFlingIfNecessary(const base::TimeTicks& timestamp);
+  void EndScrollIfNecessary(const base::TimeTicks& timestamp);
   void PopGestureSequence();
   GestureSequence& Head();
   GestureSequence& Tail();
diff --git a/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc b/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
index 728d4b2..6e78240 100644
--- a/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
+++ b/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
@@ -30,6 +30,7 @@
   // TouchDispositionGestureFilterClient
   virtual void ForwardGestureEvent(const GestureEventData& event) OVERRIDE {
     ++sent_gesture_count_;
+    last_sent_gesture_time_ = event.time;
     sent_gestures_.push_back(event.type);
     if (cancel_after_next_gesture_) {
       CancelTouchPoint();
@@ -96,6 +97,7 @@
   }
 
   void SendTouchGestures() {
+    touch_event_.SetTime(base::TimeTicks::Now());
     EXPECT_EQ(TouchDispositionGestureFilter::SUCCESS,
               SendTouchGestures(touch_event_, pending_gesture_packet_));
     GestureEventDataPacket gesture_packet;
@@ -127,13 +129,9 @@
     queue_->OnTouchEventAck(event_consumed);
   }
 
-  void SendTouchConsumedAck() {
-    SendTouchEventAck(true);
-  }
+  void SendTouchConsumedAck() { SendTouchEventAck(true); }
 
-  void SendTouchNotConsumedAck() {
-    SendTouchEventAck(false);
-  }
+  void SendTouchNotConsumedAck() { SendTouchEventAck(false); }
 
   void PushGesture(EventType type) {
     pending_gesture_packet_.Push(CreateGesture(type));
@@ -159,14 +157,20 @@
     SendTouchGestures();
   }
 
-  bool GesturesSent() const {
-    return !sent_gestures_.empty();
+  void ResetTouchPoints() { touch_event_ = MockMotionEvent(); }
+
+  bool GesturesSent() const { return !sent_gestures_.empty(); }
+
+  base::TimeTicks LastSentGestureTime() const {
+    return last_sent_gesture_time_;
   }
 
-  bool IsEmpty() const {
-    return queue_->IsEmpty();
+  base::TimeTicks CurrentTouchTime() const {
+    return touch_event_.GetEventTime();
   }
 
+  bool IsEmpty() const { return queue_->IsEmpty(); }
+
   GestureList GetAndResetSentGestures() {
     GestureList sent_gestures;
     sent_gestures.swap(sent_gestures_);
@@ -188,6 +192,7 @@
   MockMotionEvent touch_event_;
   GestureEventDataPacket pending_gesture_packet_;
   size_t sent_gesture_count_;
+  base::TimeTicks last_sent_gesture_time_;
   GestureList sent_gestures_;
 };
 
@@ -558,16 +563,34 @@
   EXPECT_TRUE(GesturesMatch(Gestures(ET_SCROLL_FLING_START),
                             GetAndResetSentGestures()));
 
-  // A new touch seqeuence should cancel the outstanding fling.
+  // A new touch sequence should cancel the outstanding fling.
   PressTouchPoint(1, 1);
   SendTouchNotConsumedAck();
   EXPECT_TRUE(GesturesMatch(Gestures(ET_SCROLL_FLING_CANCEL),
                             GetAndResetSentGestures()));
+  EXPECT_EQ(CurrentTouchTime(), LastSentGestureTime());
   ReleaseTouchPoint();
   SendTouchNotConsumedAck();
   EXPECT_FALSE(GesturesSent());
 }
 
+TEST_F(TouchDispositionGestureFilterTest, ScrollEndedOnTouchReleaseIfNoFling) {
+  // Simulate a scroll.
+  PushGesture(ET_GESTURE_TAP_DOWN);
+  PushGesture(ET_GESTURE_SCROLL_BEGIN);
+  PressTouchPoint(1, 1);
+  SendTouchNotConsumedAck();
+  EXPECT_TRUE(GesturesMatch(
+      Gestures(
+          ET_GESTURE_TAP_DOWN, ET_GESTURE_TAP_CANCEL, ET_GESTURE_SCROLL_BEGIN),
+      GetAndResetSentGestures()));
+  ReleaseTouchPoint();
+  SendTouchNotConsumedAck();
+  EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_SCROLL_END),
+                            GetAndResetSentGestures()));
+  EXPECT_EQ(CurrentTouchTime(), LastSentGestureTime());
+}
+
 TEST_F(TouchDispositionGestureFilterTest, ScrollEndedOnNewTouchSequence) {
   // Simulate a scroll.
   PushGesture(ET_GESTURE_TAP_DOWN);
@@ -578,14 +601,14 @@
       Gestures(
           ET_GESTURE_TAP_DOWN, ET_GESTURE_TAP_CANCEL, ET_GESTURE_SCROLL_BEGIN),
       GetAndResetSentGestures()));
-  ReleaseTouchPoint();
-  SendTouchNotConsumedAck();
 
-  // A new touch seqeuence should end the outstanding scroll.
+  // A new touch sequence should end the outstanding scroll.
+  ResetTouchPoints();
   PressTouchPoint(1, 1);
   SendTouchConsumedAck();
   EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_SCROLL_END),
                             GetAndResetSentGestures()));
+  EXPECT_EQ(CurrentTouchTime(), LastSentGestureTime());
 }
 
 TEST_F(TouchDispositionGestureFilterTest, FlingCancelledOnScrollBegin) {
@@ -864,6 +887,7 @@
   SendTouchNotConsumedAck();
   EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP_CANCEL),
                             GetAndResetSentGestures()));
+  EXPECT_EQ(CurrentTouchTime(), LastSentGestureTime());
 
   PushGesture(ET_GESTURE_SCROLL_BEGIN);
   PressTouchPoint(1, 1);
@@ -877,6 +901,7 @@
   SendTouchConsumedAck();
   EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_SCROLL_END),
                             GetAndResetSentGestures()));
+  EXPECT_EQ(CurrentTouchTime(), LastSentGestureTime());
 }
 
 TEST_F(TouchDispositionGestureFilterTest,
@@ -924,6 +949,7 @@
   SendTouchNotConsumedAck();
   EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP_CANCEL),
                             GetAndResetSentGestures()));
+  EXPECT_EQ(CurrentTouchTime(), LastSentGestureTime());
 }
 
 // Test that a GestureEvent whose dispatch causes a cancel event to be fired
diff --git a/ui/events/gestures/gesture_configuration.cc b/ui/events/gestures/gesture_configuration.cc
index 524812c..5205280 100644
--- a/ui/events/gestures/gesture_configuration.cc
+++ b/ui/events/gestures/gesture_configuration.cc
@@ -34,6 +34,10 @@
 double
   GestureConfiguration::min_touch_down_duration_in_seconds_for_click_ = 0.01;
 
+// If this is too small, we currently can get single finger pinch zoom. See
+// crbug.com/357237 for details.
+int GestureConfiguration::min_scaling_span_in_pixels_ = 125;
+
 // The number of points used in the linear regression which determines
 // touch velocity. Velocity is reported for 2 or more touch move events.
 int GestureConfiguration::points_buffered_for_velocity_ = 8;
diff --git a/ui/events/gestures/gesture_configuration.h b/ui/events/gestures/gesture_configuration.h
index 1338e1d..f121b75 100644
--- a/ui/events/gestures/gesture_configuration.h
+++ b/ui/events/gestures/gesture_configuration.h
@@ -6,7 +6,7 @@
 #define UI_EVENTS_GESTURES_GESTURE_CONFIGURATION_H_
 
 #include "base/basictypes.h"
-#include "ui/events/events_export.h"
+#include "ui/events/events_base_export.h"
 
 namespace ui {
 
@@ -14,7 +14,7 @@
 // approaches (windows, chrome, others).  This would turn into an
 // abstract base class.
 
-class EVENTS_EXPORT GestureConfiguration {
+class EVENTS_BASE_EXPORT GestureConfiguration {
  public:
   // Number of parameters in the array of parameters for the fling acceleration
   // curve.
@@ -143,6 +143,15 @@
   static void set_min_touch_down_duration_in_seconds_for_click(double val) {
     min_touch_down_duration_in_seconds_for_click_ = val;
   }
+
+  static int min_scaling_span_in_pixels() {
+    return min_scaling_span_in_pixels_;
+  };
+
+  static void set_min_scaling_span_in_pixels(int val) {
+    min_scaling_span_in_pixels_ = val;
+  }
+
   static int points_buffered_for_velocity() {
     return points_buffered_for_velocity_;
   }
@@ -235,6 +244,7 @@
   static float min_scroll_velocity_;
   static double min_swipe_speed_;
   static double min_touch_down_duration_in_seconds_for_click_;
+  static int min_scaling_span_in_pixels_;
   static int points_buffered_for_velocity_;
   static double rail_break_proportion_;
   static double rail_start_proportion_;
diff --git a/ui/events/gestures/gesture_provider_aura.cc b/ui/events/gestures/gesture_provider_aura.cc
new file mode 100644
index 0000000..c73d317
--- /dev/null
+++ b/ui/events/gestures/gesture_provider_aura.cc
@@ -0,0 +1,68 @@
+// 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.
+
+#include "ui/events/gestures/gesture_provider_aura.h"
+
+#include "base/logging.h"
+#include "ui/events/event.h"
+#include "ui/events/gesture_detection/gesture_config_helper.h"
+#include "ui/events/gesture_detection/gesture_event_data.h"
+
+namespace ui {
+
+GestureProviderAura::GestureProviderAura(GestureProviderAuraClient* client)
+    : client_(client),
+      filtered_gesture_provider_(ui::DefaultGestureProviderConfig(), this) {
+  filtered_gesture_provider_.SetDoubleTapSupportForPlatformEnabled(false);
+}
+
+GestureProviderAura::~GestureProviderAura() {}
+
+bool GestureProviderAura::OnTouchEvent(const TouchEvent& event) {
+  last_touch_event_flags_ = event.flags();
+  bool pointer_id_is_active = false;
+  for (size_t i = 0; i < pointer_state_.GetPointerCount(); ++i) {
+    if (event.touch_id() != pointer_state_.GetPointerId(i))
+      continue;
+    pointer_id_is_active = true;
+    break;
+  }
+
+  if (event.type() == ET_TOUCH_PRESSED && pointer_id_is_active) {
+    // Ignore touch press events if we already believe the pointer is down.
+    return false;
+  } else if (event.type() != ET_TOUCH_PRESSED && !pointer_id_is_active) {
+    // We could have an active touch stream transfered to us, resulting in touch
+    // move or touch up events without associated touch down events. Ignore
+    // them.
+    return false;
+  }
+
+  pointer_state_.OnTouch(event);
+  bool result = filtered_gesture_provider_.OnTouchEvent(pointer_state_);
+  pointer_state_.CleanupRemovedTouchPoints(event);
+  return result;
+}
+
+void GestureProviderAura::OnTouchEventAck(bool event_consumed) {
+  filtered_gesture_provider_.OnTouchEventAck(event_consumed);
+}
+
+void GestureProviderAura::OnGestureEvent(
+    const GestureEventData& gesture) {
+  ui::GestureEvent event(gesture.type,
+                         gesture.x,
+                         gesture.y,
+                         last_touch_event_flags_,
+                         gesture.time - base::TimeTicks(),
+                         gesture.details,
+                         // ui::GestureEvent stores a bitfield indicating the
+                         // ids of active touch points. This is currently only
+                         // used when one finger is down, and will eventually
+                         // be cleaned up. See crbug.com/366707.
+                         1 << gesture.motion_event_id);
+  client_->OnGestureEvent(&event);
+}
+
+}  // namespace content
diff --git a/ui/events/gestures/gesture_provider_aura.h b/ui/events/gestures/gesture_provider_aura.h
new file mode 100644
index 0000000..b4a9ded
--- /dev/null
+++ b/ui/events/gestures/gesture_provider_aura.h
@@ -0,0 +1,50 @@
+// 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.
+
+#ifndef UI_EVENTS_GESTURE_DETECTION_UI_GESTURE_PROVIDER_H_
+#define UI_EVENTS_GESTURE_DETECTION_UI_GESTURE_PROVIDER_H_
+
+#include "base/basictypes.h"
+#include "ui/events/event.h"
+#include "ui/events/events_export.h"
+#include "ui/events/gesture_detection/filtered_gesture_provider.h"
+#include "ui/events/gesture_detection/gesture_event_data_packet.h"
+#include "ui/events/gesture_detection/touch_disposition_gesture_filter.h"
+#include "ui/events/gestures/motion_event_aura.h"
+
+namespace ui {
+
+class EVENTS_EXPORT GestureProviderAuraClient {
+ public:
+  virtual ~GestureProviderAuraClient() {}
+  virtual void OnGestureEvent(GestureEvent* event) = 0;
+};
+
+// Provides gesture detection and dispatch given a sequence of touch events
+// and touch event acks.
+class EVENTS_EXPORT GestureProviderAura : public GestureProviderClient {
+ public:
+  GestureProviderAura(GestureProviderAuraClient* client);
+  virtual ~GestureProviderAura();
+
+  bool OnTouchEvent(const TouchEvent& event);
+  void OnTouchEventAck(bool event_consumed);
+  const MotionEventAura& pointer_state() { return pointer_state_; }
+
+  // GestureProviderClient implementation
+  virtual void OnGestureEvent(const GestureEventData& gesture) OVERRIDE;
+
+ private:
+  GestureProviderAuraClient* client_;
+  MotionEventAura pointer_state_;
+  FilteredGestureProvider filtered_gesture_provider_;
+
+  int last_touch_event_flags_;
+
+  DISALLOW_COPY_AND_ASSIGN(GestureProviderAura);
+};
+
+}  // namespace ui
+
+#endif  // UI_EVENTS_GESTURE_DETECTION_UI_GESTURE_PROVIDER_H_
diff --git a/ui/events/gestures/gesture_recognizer_impl.cc b/ui/events/gestures/gesture_recognizer_impl.cc
index 7e04463..d2316d4 100644
--- a/ui/events/gestures/gesture_recognizer_impl.cc
+++ b/ui/events/gestures/gesture_recognizer_impl.cc
@@ -4,11 +4,16 @@
 
 #include "ui/events/gestures/gesture_recognizer_impl.h"
 
+#include <limits>
+
+#include "base/command_line.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
 #include "base/time/time.h"
 #include "ui/events/event.h"
 #include "ui/events/event_constants.h"
+#include "ui/events/event_switches.h"
 #include "ui/events/event_utils.h"
 #include "ui/events/gestures/gesture_configuration.h"
 #include "ui/events/gestures/gesture_sequence.h"
@@ -54,16 +59,23 @@
   }
 }
 
+GestureProviderAura* CreateGestureProvider(GestureProviderAuraClient* client) {
+  return new GestureProviderAura(client);
+}
+
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
 // GestureRecognizerImpl, public:
 
-GestureRecognizerImpl::GestureRecognizerImpl() {
+GestureRecognizerImpl::GestureRecognizerImpl()
+    : use_unified_gesture_detector_(CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kUseUnifiedGestureDetector)) {
 }
 
 GestureRecognizerImpl::~GestureRecognizerImpl() {
   STLDeleteValues(&consumer_sequence_);
+  STLDeleteValues(&consumer_gesture_provider_);
 }
 
 // Checks if this finger is already down, if so, returns the current target.
@@ -83,34 +95,65 @@
 
 GestureConsumer* GestureRecognizerImpl::GetTargetForLocation(
     const gfx::PointF& location, int source_device_id) {
-  const GesturePoint* closest_point = NULL;
-  int64 closest_distance_squared = 0;
-  std::map<GestureConsumer*, GestureSequence*>::iterator i;
-  for (i = consumer_sequence_.begin(); i != consumer_sequence_.end(); ++i) {
-    const GesturePoint* points = i->second->points();
-    for (int j = 0; j < GestureSequence::kMaxGesturePoints; ++j) {
-      if (!points[j].in_use() ||
-          source_device_id != points[j].source_device_id()) {
-        continue;
-      }
-      gfx::Vector2dF delta = points[j].last_touch_position() - location;
-      // Relative distance is all we need here, so LengthSquared() is
-      // appropriate, and cheaper than Length().
-      int64 distance_squared = delta.LengthSquared();
-      if (!closest_point || distance_squared < closest_distance_squared) {
-        closest_point = &points[j];
-        closest_distance_squared = distance_squared;
-      }
-    }
-  }
-
   const int max_distance =
       GestureConfiguration::max_separation_for_gesture_touches_in_pixels();
 
-  if (closest_distance_squared < max_distance * max_distance && closest_point)
-    return touch_id_target_[closest_point->touch_id()];
-  else
-    return NULL;
+  if (!use_unified_gesture_detector_) {
+    const GesturePoint* closest_point = NULL;
+    int64 closest_distance_squared = 0;
+    std::map<GestureConsumer*, GestureSequence*>::iterator i;
+    for (i = consumer_sequence_.begin(); i != consumer_sequence_.end(); ++i) {
+      const GesturePoint* points = i->second->points();
+      for (int j = 0; j < GestureSequence::kMaxGesturePoints; ++j) {
+        if (!points[j].in_use() ||
+            source_device_id != points[j].source_device_id()) {
+          continue;
+        }
+        gfx::Vector2dF delta = points[j].last_touch_position() - location;
+        // Relative distance is all we need here, so LengthSquared() is
+        // appropriate, and cheaper than Length().
+        int64 distance_squared = delta.LengthSquared();
+        if (!closest_point || distance_squared < closest_distance_squared) {
+          closest_point = &points[j];
+          closest_distance_squared = distance_squared;
+        }
+      }
+    }
+
+    if (closest_distance_squared < max_distance * max_distance && closest_point)
+      return touch_id_target_[closest_point->touch_id()];
+    else
+      return NULL;
+  } else {
+    gfx::PointF closest_point;
+    int closest_touch_id;
+    float closest_distance_squared = std::numeric_limits<float>::infinity();
+
+    std::map<GestureConsumer*, GestureProviderAura*>::iterator i;
+    for (i = consumer_gesture_provider_.begin();
+         i != consumer_gesture_provider_.end();
+         ++i) {
+      const MotionEventAura& pointer_state = i->second->pointer_state();
+      for (size_t j = 0; j < pointer_state.GetPointerCount(); ++j) {
+        if (source_device_id != pointer_state.GetSourceDeviceId(j))
+          continue;
+        gfx::PointF point(pointer_state.GetX(j), pointer_state.GetY(j));
+        // Relative distance is all we need here, so LengthSquared() is
+        // appropriate, and cheaper than Length().
+        float distance_squared = (point - location).LengthSquared();
+        if (distance_squared < closest_distance_squared) {
+          closest_point = point;
+          closest_touch_id = pointer_state.GetPointerId(j);
+          closest_distance_squared = distance_squared;
+        }
+      }
+    }
+
+    if (closest_distance_squared < max_distance * max_distance)
+      return touch_id_target_[closest_touch_id];
+    else
+      return NULL;
+  }
 }
 
 void GestureRecognizerImpl::TransferEventsTo(GestureConsumer* current_consumer,
@@ -140,18 +183,30 @@
                                  &touch_id_target_);
     TransferTouchIdToConsumerMap(current_consumer, new_consumer,
                                  &touch_id_target_for_gestures_);
-    TransferConsumer(current_consumer, new_consumer, &consumer_sequence_);
+    if (!use_unified_gesture_detector_)
+      TransferConsumer(current_consumer, new_consumer, &consumer_sequence_);
+    else
+      TransferConsumer(
+          current_consumer, new_consumer, &consumer_gesture_provider_);
   }
 }
 
 bool GestureRecognizerImpl::GetLastTouchPointForTarget(
     GestureConsumer* consumer,
     gfx::PointF* point) {
-  if (consumer_sequence_.count(consumer) == 0)
-    return false;
-
-  *point = consumer_sequence_[consumer]->last_touch_location();
-  return true;
+  if (!use_unified_gesture_detector_) {
+    if (consumer_sequence_.count(consumer) == 0)
+      return false;
+    *point = consumer_sequence_[consumer]->last_touch_location();
+    return true;
+  } else {
+    if (consumer_gesture_provider_.count(consumer) == 0)
+      return false;
+    const MotionEvent& pointer_state =
+        consumer_gesture_provider_[consumer]->pointer_state();
+    *point = gfx::PointF(pointer_state.GetX(), pointer_state.GetY());
+    return true;
+  }
 }
 
 bool GestureRecognizerImpl::CancelActiveTouches(GestureConsumer* consumer) {
@@ -187,6 +242,16 @@
   return gesture_sequence;
 }
 
+GestureProviderAura* GestureRecognizerImpl::GetGestureProviderForConsumer(
+    GestureConsumer* consumer) {
+  GestureProviderAura* gesture_provider = consumer_gesture_provider_[consumer];
+  if (!gesture_provider) {
+    gesture_provider = CreateGestureProvider(this);
+    consumer_gesture_provider_[consumer] = gesture_provider;
+  }
+  return gesture_provider;
+}
+
 void GestureRecognizerImpl::SetupTargets(const TouchEvent& event,
                                          GestureConsumer* target) {
   if (event.type() == ui::ET_TOUCH_RELEASED ||
@@ -214,22 +279,55 @@
   }
 }
 
+void GestureRecognizerImpl::DispatchGestureEvent(GestureEvent* event) {
+  GestureConsumer* consumer = GetTargetForGestureEvent(*event);
+  if (consumer) {
+    GestureEventHelper* helper = FindDispatchHelperForConsumer(consumer);
+    if (helper)
+      helper->DispatchGestureEvent(event);
+  }
+}
+
 GestureSequence::Gestures* GestureRecognizerImpl::ProcessTouchEventForGesture(
     const TouchEvent& event,
     ui::EventResult result,
     GestureConsumer* target) {
   SetupTargets(event, target);
-  GestureSequence* gesture_sequence = GetGestureSequenceForConsumer(target);
-  return gesture_sequence->ProcessTouchEventForGesture(event, result);
+
+  if (!use_unified_gesture_detector_) {
+    GestureSequence* gesture_sequence = GetGestureSequenceForConsumer(target);
+    return gesture_sequence->ProcessTouchEventForGesture(event, result);
+  } else {
+    GestureProviderAura* gesture_provider =
+        GetGestureProviderForConsumer(target);
+    // TODO(tdresser) - detect gestures eagerly.
+    if (!(result & ER_CONSUMED)) {
+      if (gesture_provider->OnTouchEvent(event))
+        gesture_provider->OnTouchEventAck(result != ER_UNHANDLED);
+    }
+    return NULL;
+  }
 }
 
 bool GestureRecognizerImpl::CleanupStateForConsumer(
     GestureConsumer* consumer) {
   bool state_cleaned_up = false;
-  if (consumer_sequence_.count(consumer)) {
-    state_cleaned_up = true;
-    delete consumer_sequence_[consumer];
-    consumer_sequence_.erase(consumer);
+
+  if (!use_unified_gesture_detector_) {
+    if (consumer_sequence_.count(consumer)) {
+      state_cleaned_up = true;
+      delete consumer_sequence_[consumer];
+      consumer_sequence_.erase(consumer);
+    }
+  } else {
+    if (consumer_gesture_provider_.count(consumer)) {
+      state_cleaned_up = true;
+      // Don't immediately delete the GestureProvider, as we could be in the
+      // middle of dispatching a set of gestures.
+      base::MessageLoop::current()->DeleteSoon(
+          FROM_HERE, consumer_gesture_provider_[consumer]);
+      consumer_gesture_provider_.erase(consumer);
+    }
   }
 
   state_cleaned_up |= RemoveConsumerFromMap(consumer, &touch_id_target_);
@@ -251,12 +349,11 @@
 }
 
 void GestureRecognizerImpl::DispatchPostponedGestureEvent(GestureEvent* event) {
-  GestureConsumer* consumer = GetTargetForGestureEvent(*event);
-  if (consumer) {
-    GestureEventHelper* helper = FindDispatchHelperForConsumer(consumer);
-    if (helper)
-      helper->DispatchPostponedGestureEvent(event);
-  }
+  DispatchGestureEvent(event);
+}
+
+void GestureRecognizerImpl::OnGestureEvent(GestureEvent* event) {
+  DispatchGestureEvent(event);
 }
 
 GestureEventHelper* GestureRecognizerImpl::FindDispatchHelperForConsumer(
diff --git a/ui/events/gestures/gesture_recognizer_impl.h b/ui/events/gestures/gesture_recognizer_impl.h
index f136894..80a3007 100644
--- a/ui/events/gestures/gesture_recognizer_impl.h
+++ b/ui/events/gestures/gesture_recognizer_impl.h
@@ -12,6 +12,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "ui/events/event_constants.h"
 #include "ui/events/events_export.h"
+#include "ui/events/gestures/gesture_provider_aura.h"
 #include "ui/events/gestures/gesture_recognizer.h"
 #include "ui/events/gestures/gesture_sequence.h"
 #include "ui/gfx/point.h"
@@ -23,8 +24,12 @@
 class GestureSequence;
 class TouchEvent;
 
+// TODO(tdresser): Once the unified gesture recognition process sticks
+// (crbug.com/332418), GestureRecognizerImpl can be cleaned up
+// significantly.
 class EVENTS_EXPORT GestureRecognizerImpl : public GestureRecognizer,
-                                            public GestureSequenceDelegate {
+                                            public GestureSequenceDelegate,
+                                            public GestureProviderAuraClient {
  public:
   typedef std::map<int, GestureConsumer*> TouchIdToConsumerMap;
 
@@ -47,14 +52,19 @@
   virtual bool CancelActiveTouches(GestureConsumer* consumer) OVERRIDE;
 
  protected:
-  virtual GestureSequence* CreateSequence(GestureSequenceDelegate* delegate);
   virtual GestureSequence* GetGestureSequenceForConsumer(GestureConsumer* c);
+  virtual GestureProviderAura* GetGestureProviderForConsumer(
+      GestureConsumer* c);
+  virtual GestureSequence* CreateSequence(
+      ui::GestureSequenceDelegate* delegate);
 
  private:
   // Sets up the target consumer for gestures based on the touch-event.
   void SetupTargets(const TouchEvent& event, GestureConsumer* consumer);
   void CancelTouches(std::vector<std::pair<int, GestureConsumer*> >* touches);
 
+  void DispatchGestureEvent(GestureEvent* event);
+
   // Overridden from GestureRecognizer
   virtual Gestures* ProcessTouchEventForGesture(
       const TouchEvent& event,
@@ -68,11 +78,15 @@
   // Overridden from ui::GestureSequenceDelegate.
   virtual void DispatchPostponedGestureEvent(GestureEvent* event) OVERRIDE;
 
+  // Overridden from GestureProviderAuraClient
+  virtual void OnGestureEvent(GestureEvent* event) OVERRIDE;
+
   // Convenience method to find the GestureEventHelper that can dispatch events
   // to a specific |consumer|.
   GestureEventHelper* FindDispatchHelperForConsumer(GestureConsumer* consumer);
 
   std::map<GestureConsumer*, GestureSequence*> consumer_sequence_;
+  std::map<GestureConsumer*, GestureProviderAura*> consumer_gesture_provider_;
 
   // Both |touch_id_target_| and |touch_id_target_for_gestures_| map a touch-id
   // to its target window.  touch-ids are removed from |touch_id_target_| on
@@ -83,6 +97,8 @@
 
   std::vector<GestureEventHelper*> helpers_;
 
+  bool use_unified_gesture_detector_;
+
   DISALLOW_COPY_AND_ASSIGN(GestureRecognizerImpl);
 };
 
diff --git a/ui/events/gestures/gesture_types.h b/ui/events/gestures/gesture_types.h
index 8514508..c15a2fd 100644
--- a/ui/events/gestures/gesture_types.h
+++ b/ui/events/gestures/gesture_types.h
@@ -28,7 +28,7 @@
 
   // Returns true if this helper can dispatch events to |consumer|.
   virtual bool CanDispatchToConsumer(GestureConsumer* consumer) = 0;
-  virtual void DispatchPostponedGestureEvent(GestureEvent* event) = 0;
+  virtual void DispatchGestureEvent(GestureEvent* event) = 0;
   virtual void DispatchCancelTouchEvent(TouchEvent* event) = 0;
 };
 
diff --git a/ui/events/gestures/motion_event_aura.cc b/ui/events/gestures/motion_event_aura.cc
new file mode 100644
index 0000000..c19341e
--- /dev/null
+++ b/ui/events/gestures/motion_event_aura.cc
@@ -0,0 +1,241 @@
+// 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.
+
+#include "ui/events/gestures/motion_event_aura.h"
+
+#include "base/logging.h"
+#include "ui/events/gestures/gesture_configuration.h"
+
+namespace ui {
+
+MotionEventAura::MotionEventAura()
+    : pointer_count_(0), cached_action_index_(-1) {
+}
+
+MotionEventAura::MotionEventAura(
+    size_t pointer_count,
+    const base::TimeTicks& last_touch_time,
+    Action cached_action,
+    int cached_action_index,
+    const PointData (&active_touches)[GestureSequence::kMaxGesturePoints])
+    : pointer_count_(pointer_count),
+      last_touch_time_(last_touch_time),
+      cached_action_(cached_action),
+      cached_action_index_(cached_action_index) {
+  DCHECK(pointer_count_);
+  for (size_t i = 0; i < pointer_count; ++i)
+    active_touches_[i] = active_touches[i];
+}
+
+MotionEventAura::~MotionEventAura() {}
+
+MotionEventAura::PointData MotionEventAura::GetPointDataFromTouchEvent(
+    const TouchEvent& touch) {
+  PointData point_data;
+  point_data.x = touch.x();
+  point_data.y = touch.y();
+  point_data.touch_id = touch.touch_id();
+  point_data.pressure = touch.force();
+  point_data.source_device_id = touch.source_device_id();
+
+  // TODO(tdresser): at some point we should start using both radii if they are
+  // available, but for now we use the max.
+  point_data.major_radius = std::max(touch.radius_x(), touch.radius_y());
+  if (!point_data.major_radius)
+    point_data.major_radius = GestureConfiguration::default_radius();
+  return point_data;
+}
+
+void MotionEventAura::OnTouch(const TouchEvent& touch) {
+  switch (touch.type()) {
+    case ET_TOUCH_PRESSED:
+      AddTouch(touch);
+      break;
+    case ET_TOUCH_RELEASED:
+    case ET_TOUCH_CANCELLED:
+      // Removing these touch points needs to be postponed until after the
+      // MotionEvent has been dispatched. This cleanup occurs in
+      // CleanupRemovedTouchPoints.
+      UpdateTouch(touch);
+      break;
+    case ET_TOUCH_MOVED:
+      UpdateTouch(touch);
+      break;
+    default:
+      NOTREACHED();
+      break;
+  }
+
+  UpdateCachedAction(touch);
+  last_touch_time_ = touch.time_stamp() + base::TimeTicks();
+}
+
+int MotionEventAura::GetId() const {
+  return GetPointerId(0);
+}
+
+MotionEvent::Action MotionEventAura::GetAction() const {
+  return cached_action_;
+}
+
+int MotionEventAura::GetActionIndex() const {
+  DCHECK(cached_action_ == ACTION_POINTER_DOWN ||
+         cached_action_ == ACTION_POINTER_UP);
+  DCHECK_GE(cached_action_index_, 0);
+  DCHECK_LE(cached_action_index_, static_cast<int>(pointer_count_));
+  return cached_action_index_;
+}
+
+size_t MotionEventAura::GetPointerCount() const { return pointer_count_; }
+
+int MotionEventAura::GetPointerId(size_t pointer_index) const {
+  DCHECK_LE(pointer_index, pointer_count_);
+  return active_touches_[pointer_index].touch_id;
+}
+
+float MotionEventAura::GetX(size_t pointer_index) const {
+  DCHECK_LE(pointer_index, pointer_count_);
+  return active_touches_[pointer_index].x;
+}
+
+float MotionEventAura::GetY(size_t pointer_index) const {
+  DCHECK_LE(pointer_index, pointer_count_);
+  return active_touches_[pointer_index].y;
+}
+
+float MotionEventAura::GetTouchMajor(size_t pointer_index) const {
+  DCHECK_LE(pointer_index, pointer_count_);
+  return active_touches_[pointer_index].major_radius * 2;
+}
+
+float MotionEventAura::GetPressure(size_t pointer_index) const {
+  DCHECK_LE(pointer_index, pointer_count_);
+  return active_touches_[pointer_index].pressure;
+}
+
+base::TimeTicks MotionEventAura::GetEventTime() const {
+  return last_touch_time_;
+}
+
+size_t MotionEventAura::GetHistorySize() const { return 0; }
+
+base::TimeTicks MotionEventAura::GetHistoricalEventTime(
+    size_t historical_index) const {
+  NOTIMPLEMENTED();
+  return base::TimeTicks();
+}
+
+float MotionEventAura::GetHistoricalTouchMajor(size_t pointer_index,
+                                             size_t historical_index) const {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
+float MotionEventAura::GetHistoricalX(size_t pointer_index,
+                                    size_t historical_index) const {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
+float MotionEventAura::GetHistoricalY(size_t pointer_index,
+                                    size_t historical_index) const {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
+scoped_ptr<MotionEvent> MotionEventAura::Clone() const {
+  return scoped_ptr<MotionEvent>(new MotionEventAura(pointer_count_,
+                                                     last_touch_time_,
+                                                     cached_action_,
+                                                     cached_action_index_,
+                                                     active_touches_));
+}
+scoped_ptr<MotionEvent> MotionEventAura::Cancel() const {
+  return scoped_ptr<MotionEvent>(new MotionEventAura(
+      pointer_count_, last_touch_time_, ACTION_CANCEL, -1, active_touches_));
+}
+
+void MotionEventAura::CleanupRemovedTouchPoints(const TouchEvent& event) {
+  if (event.type() != ET_TOUCH_RELEASED &&
+      event.type() != ET_TOUCH_CANCELLED) {
+    return;
+  }
+
+  int index_to_delete = static_cast<int>(GetIndexFromId(event.touch_id()));
+  pointer_count_--;
+  active_touches_[index_to_delete] = active_touches_[pointer_count_];
+}
+
+MotionEventAura::PointData::PointData()
+    : x(0),
+      y(0),
+      touch_id(0),
+      pressure(0),
+      source_device_id(0),
+      major_radius(0) {
+}
+
+int MotionEventAura::GetSourceDeviceId(size_t pointer_index) const {
+  DCHECK_LE(pointer_index, pointer_count_);
+  return active_touches_[pointer_index].source_device_id;
+}
+
+void MotionEventAura::AddTouch(const TouchEvent& touch) {
+  if (pointer_count_ == static_cast<size_t>(GestureSequence::kMaxGesturePoints))
+    return;
+
+  active_touches_[pointer_count_] = GetPointDataFromTouchEvent(touch);
+  pointer_count_++;
+}
+
+
+void MotionEventAura::UpdateTouch(const TouchEvent& touch) {
+  active_touches_[GetIndexFromId(touch.touch_id())] =
+      GetPointDataFromTouchEvent(touch);
+}
+
+void MotionEventAura::UpdateCachedAction(const TouchEvent& touch) {
+  DCHECK(pointer_count_);
+  switch (touch.type()) {
+    case ET_TOUCH_PRESSED:
+      if (pointer_count_ == 1) {
+        cached_action_ = ACTION_DOWN;
+      } else {
+        cached_action_ = ACTION_POINTER_DOWN;
+        cached_action_index_ =
+            static_cast<int>(GetIndexFromId(touch.touch_id()));
+      }
+      break;
+    case ET_TOUCH_RELEASED:
+      if (pointer_count_ == 1) {
+        cached_action_ = ACTION_UP;
+      } else {
+        cached_action_ = ACTION_POINTER_UP;
+        cached_action_index_ =
+            static_cast<int>(GetIndexFromId(touch.touch_id()));
+        DCHECK_LE(cached_action_index_, static_cast<int>(pointer_count_));
+      }
+      break;
+    case ET_TOUCH_CANCELLED:
+      cached_action_ = ACTION_CANCEL;
+      break;
+    case ET_TOUCH_MOVED:
+      cached_action_ = ACTION_MOVE;
+      break;
+    default:
+      NOTREACHED();
+      break;
+  }
+}
+
+size_t MotionEventAura::GetIndexFromId(int id) const {
+  for (size_t i = 0; i < pointer_count_; ++i) {
+    if (active_touches_[i].touch_id == id)
+      return i;
+  }
+  NOTREACHED();
+  return 0;
+}
+
+}  // namespace ui
diff --git a/ui/events/gestures/motion_event_aura.h b/ui/events/gestures/motion_event_aura.h
new file mode 100644
index 0000000..0713584
--- /dev/null
+++ b/ui/events/gestures/motion_event_aura.h
@@ -0,0 +1,102 @@
+// 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.
+
+#ifndef UI_EVENTS_GESTURE_DETECTION_UI_MOTION_EVENT_H_
+#define UI_EVENTS_GESTURE_DETECTION_UI_MOTION_EVENT_H_
+
+#include "ui/events/gesture_detection/motion_event.h"
+
+#include <map>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
+#include "ui/events/event.h"
+#include "ui/events/events_export.h"
+#include "ui/events/gestures/gesture_sequence.h"
+
+namespace ui {
+
+// Implementation of MotionEvent which takes a stream of ui::TouchEvents.
+class EVENTS_EXPORT MotionEventAura : public MotionEvent {
+ public:
+  MotionEventAura();
+  virtual ~MotionEventAura();
+
+  void OnTouch(const TouchEvent& touch);
+
+  // MotionEvent implementation.
+  virtual int GetId() const OVERRIDE;
+  virtual Action GetAction() const OVERRIDE;
+  virtual int GetActionIndex() const OVERRIDE;
+  virtual size_t GetPointerCount() const OVERRIDE;
+  virtual int GetPointerId(size_t pointer_index) const OVERRIDE;
+  virtual float GetX(size_t pointer_index) const OVERRIDE;
+  virtual float GetY(size_t pointer_index) const OVERRIDE;
+  virtual float GetTouchMajor(size_t pointer_index) const OVERRIDE;
+  virtual float GetPressure(size_t pointer_index) const OVERRIDE;
+  virtual base::TimeTicks GetEventTime() const OVERRIDE;
+
+  virtual size_t GetHistorySize() const OVERRIDE;
+  virtual base::TimeTicks GetHistoricalEventTime(size_t historical_index) const
+      OVERRIDE;
+  virtual float GetHistoricalTouchMajor(size_t pointer_index,
+                                        size_t historical_index) const OVERRIDE;
+  virtual float GetHistoricalX(size_t pointer_index,
+                               size_t historical_index) const OVERRIDE;
+  virtual float GetHistoricalY(size_t pointer_index,
+                               size_t historical_index) const OVERRIDE;
+
+  virtual scoped_ptr<MotionEvent> Clone() const OVERRIDE;
+  virtual scoped_ptr<MotionEvent> Cancel() const OVERRIDE;
+
+  int GetSourceDeviceId(size_t pointer_index) const;
+
+  // We can't cleanup removed touch points immediately upon receipt of a
+  // TouchCancel or TouchRelease, as the MotionEvent needs to be able to report
+  // information about those touch events. Once the MotionEvent has been
+  // processed, we call CleanupRemovedTouchPoints to do the required
+  // book-keeping.
+  void CleanupRemovedTouchPoints(const TouchEvent& event);
+
+ private:
+  struct PointData {
+    PointData();
+    float x;
+    float y;
+    int touch_id;
+    float pressure;
+    int source_device_id;
+    float major_radius;
+  };
+
+  MotionEventAura(
+      size_t pointer_count,
+      const base::TimeTicks& last_touch_time,
+      Action cached_action,
+      int cached_action_index,
+      const PointData (&active_touches)[GestureSequence::kMaxGesturePoints]);
+
+  static PointData GetPointDataFromTouchEvent(const TouchEvent& touch);
+  void AddTouch(const TouchEvent& touch);
+  void UpdateTouch(const TouchEvent& touch);
+  void UpdateCachedAction(const TouchEvent& touch);
+  size_t GetIndexFromId(int id) const;
+
+  size_t pointer_count_;
+  base::TimeTicks last_touch_time_;
+  Action cached_action_;
+  // The index of the touch responsible for last ACTION_POINTER_DOWN or
+  // ACTION_POINTER_UP. -1 if no such action has occurred.
+  int cached_action_index_;
+
+  // We want constant time indexing by pointer_index, and fast indexing by id.
+  // TODO(tdresser): figure out which constant to use here.
+  PointData active_touches_[GestureSequence::kMaxGesturePoints];
+
+  DISALLOW_COPY_AND_ASSIGN(MotionEventAura);
+};
+
+}  // namespace ui
+
+#endif  // UI_EVENTS_GESTURE_DETECTION_UI_MOTION_EVENT_H_
diff --git a/ui/events/gestures/motion_event_aura_unittest.cc b/ui/events/gestures/motion_event_aura_unittest.cc
new file mode 100644
index 0000000..e937d26
--- /dev/null
+++ b/ui/events/gestures/motion_event_aura_unittest.cc
@@ -0,0 +1,293 @@
+// 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.
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/event.h"
+#include "ui/events/gestures/motion_event_aura.h"
+
+namespace {
+
+ui::TouchEvent TouchWithType(ui::EventType type, int id) {
+  return ui::TouchEvent(
+      type, gfx::PointF(0, 0), id, base::TimeDelta::FromMilliseconds(0));
+}
+
+ui::TouchEvent TouchWithPosition(ui::EventType type,
+                                 int id,
+                                 float x,
+                                 float y,
+                                 float radius,
+                                 float pressure) {
+  return ui::TouchEvent(type,
+                        gfx::PointF(x, y),
+                        0,
+                        id,
+                        base::TimeDelta::FromMilliseconds(0),
+                        radius,
+                        radius,
+                        0,
+                        pressure);
+}
+
+ui::TouchEvent TouchWithTime(ui::EventType type, int id, int ms) {
+  return ui::TouchEvent(
+      type, gfx::PointF(0, 0), id, base::TimeDelta::FromMilliseconds(ms));
+}
+
+base::TimeTicks MsToTicks(int ms) {
+  return base::TimeTicks() + base::TimeDelta::FromMilliseconds(ms);
+}
+
+}  // namespace
+
+namespace ui {
+
+TEST(MotionEventAuraTest, PointerCountAndIds) {
+  // Test that |PointerCount()| returns the correct number of pointers, and ids
+  // are assigned correctly.
+  int ids[] = {4, 6, 1};
+
+  MotionEventAura event;
+  EXPECT_EQ(0U, event.GetPointerCount());
+
+  TouchEvent press0 = TouchWithType(ET_TOUCH_PRESSED, ids[0]);
+  event.OnTouch(press0);
+  EXPECT_EQ(1U, event.GetPointerCount());
+
+  EXPECT_EQ(ids[0], event.GetPointerId(0));
+
+  TouchEvent press1 = TouchWithType(ET_TOUCH_PRESSED, ids[1]);
+  event.OnTouch(press1);
+  EXPECT_EQ(2U, event.GetPointerCount());
+
+  EXPECT_EQ(ids[0], event.GetPointerId(0));
+  EXPECT_EQ(ids[1], event.GetPointerId(1));
+
+  TouchEvent press2 = TouchWithType(ET_TOUCH_PRESSED, ids[2]);
+  event.OnTouch(press2);
+  EXPECT_EQ(3U, event.GetPointerCount());
+
+  EXPECT_EQ(ids[0], event.GetPointerId(0));
+  EXPECT_EQ(ids[1], event.GetPointerId(1));
+  EXPECT_EQ(ids[2], event.GetPointerId(2));
+
+  TouchEvent release1 = TouchWithType(ET_TOUCH_RELEASED, ids[1]);
+  event.OnTouch(release1);
+  event.CleanupRemovedTouchPoints(release1);
+  EXPECT_EQ(2U, event.GetPointerCount());
+
+  EXPECT_EQ(ids[0], event.GetPointerId(0));
+  EXPECT_EQ(ids[2], event.GetPointerId(1));
+
+  // Test cloning of pointer count and id information.
+  scoped_ptr<MotionEvent> clone = event.Clone();
+  EXPECT_EQ(2U, clone->GetPointerCount());
+  EXPECT_EQ(ids[0], clone->GetPointerId(0));
+  EXPECT_EQ(ids[2], clone->GetPointerId(1));
+
+  TouchEvent release0 = TouchWithType(ET_TOUCH_RELEASED, ids[0]);
+  event.OnTouch(release0);
+  event.CleanupRemovedTouchPoints(release0);
+  EXPECT_EQ(1U, event.GetPointerCount());
+
+  EXPECT_EQ(ids[2], event.GetPointerId(0));
+
+  TouchEvent release2 = TouchWithType(ET_TOUCH_RELEASED, ids[2]);
+  event.OnTouch(release2);
+  event.CleanupRemovedTouchPoints(release2);
+  EXPECT_EQ(0U, event.GetPointerCount());
+}
+
+TEST(MotionEventAuraTest, GetActionIndexAfterRemoval) {
+  // Test that |GetActionIndex()| returns the correct index when points have
+  // been removed.
+  int ids[] = {4, 6, 9};
+
+  MotionEventAura event;
+  EXPECT_EQ(0U, event.GetPointerCount());
+
+  TouchEvent press0 = TouchWithType(ET_TOUCH_PRESSED, ids[0]);
+  event.OnTouch(press0);
+  TouchEvent press1 = TouchWithType(ET_TOUCH_PRESSED, ids[1]);
+  event.OnTouch(press1);
+  TouchEvent press2 = TouchWithType(ET_TOUCH_PRESSED, ids[2]);
+  event.OnTouch(press2);
+  EXPECT_EQ(3U, event.GetPointerCount());
+
+  TouchEvent release1 = TouchWithType(ET_TOUCH_RELEASED, ids[1]);
+  event.OnTouch(release1);
+  event.CleanupRemovedTouchPoints(release1);
+  EXPECT_EQ(1, event.GetActionIndex());
+  EXPECT_EQ(2U, event.GetPointerCount());
+
+  TouchEvent release2 = TouchWithType(ET_TOUCH_RELEASED, ids[0]);
+  event.OnTouch(release2);
+  event.CleanupRemovedTouchPoints(release2);
+  EXPECT_EQ(0, event.GetActionIndex());
+  EXPECT_EQ(1U, event.GetPointerCount());
+
+  TouchEvent release0 = TouchWithType(ET_TOUCH_RELEASED, ids[2]);
+  event.OnTouch(release0);
+  event.CleanupRemovedTouchPoints(release0);
+  EXPECT_EQ(0U, event.GetPointerCount());
+}
+
+TEST(MotionEventAuraTest, PointerLocations) {
+  // Test that location information is stored correctly.
+  MotionEventAura event;
+
+  int ids[] = {15, 13};
+  float x;
+  float y;
+  float r;
+  float p;
+
+  x = 14.4f;
+  y = 17.3f;
+  r = 25.7f;
+  p = 48.2f;
+  TouchEvent press0 = TouchWithPosition(ET_TOUCH_PRESSED, ids[0], x, y, r, p);
+  event.OnTouch(press0);
+
+  EXPECT_EQ(1U, event.GetPointerCount());
+  EXPECT_FLOAT_EQ(x, event.GetX(0));
+  EXPECT_FLOAT_EQ(y, event.GetY(0));
+  EXPECT_FLOAT_EQ(r, event.GetTouchMajor(0) / 2);
+  EXPECT_FLOAT_EQ(p, event.GetPressure(0));
+
+  x = 17.8f;
+  y = 12.1f;
+  r = 21.2f;
+  p = 18.4f;
+  TouchEvent press1 = TouchWithPosition(ET_TOUCH_PRESSED, ids[1], x, y, r, p);
+  event.OnTouch(press1);
+
+  EXPECT_EQ(2U, event.GetPointerCount());
+  EXPECT_FLOAT_EQ(x, event.GetX(1));
+  EXPECT_FLOAT_EQ(y, event.GetY(1));
+  EXPECT_FLOAT_EQ(r, event.GetTouchMajor(1) / 2);
+  EXPECT_FLOAT_EQ(p, event.GetPressure(1));
+
+  // Test cloning of pointer location information.
+  scoped_ptr<MotionEvent> clone = event.Clone();
+  EXPECT_EQ(2U, clone->GetPointerCount());
+  EXPECT_FLOAT_EQ(x, clone->GetX(1));
+  EXPECT_FLOAT_EQ(y, clone->GetY(1));
+  EXPECT_FLOAT_EQ(r, clone->GetTouchMajor(1) / 2);
+  EXPECT_FLOAT_EQ(p, clone->GetPressure(1));
+
+  x = 27.9f;
+  y = 22.3f;
+  r = 7.6f;
+  p = 82.1f;
+  TouchEvent move1 = TouchWithPosition(ET_TOUCH_MOVED, ids[1], x, y, r, p);
+  event.OnTouch(move1);
+
+  EXPECT_FLOAT_EQ(x, event.GetX(1));
+  EXPECT_FLOAT_EQ(y, event.GetY(1));
+  EXPECT_FLOAT_EQ(r, event.GetTouchMajor(1) / 2);
+  EXPECT_FLOAT_EQ(p, event.GetPressure(1));
+
+
+  x = 34.6f;
+  y = 23.8f;
+  r = 12.9f;
+  p = 14.2f;
+  TouchEvent move0 = TouchWithPosition(ET_TOUCH_MOVED, ids[0], x, y, r, p);
+  event.OnTouch(move0);
+
+  EXPECT_FLOAT_EQ(x, event.GetX(0));
+  EXPECT_FLOAT_EQ(y, event.GetY(0));
+  EXPECT_FLOAT_EQ(r, event.GetTouchMajor(0) / 2);
+  EXPECT_FLOAT_EQ(p, event.GetPressure(0));
+}
+
+TEST(MotionEventAuraTest, Timestamps) {
+  // Test that timestamp information is stored and converted correctly.
+  MotionEventAura event;
+  int ids[] = {7, 13};
+  int times_in_ms[] = {59436, 60263, 82175};
+
+  TouchEvent press0 = TouchWithTime(
+      ui::ET_TOUCH_PRESSED, ids[0], times_in_ms[0]);
+  event.OnTouch(press0);
+  EXPECT_EQ(MsToTicks(times_in_ms[0]), event.GetEventTime());
+
+  TouchEvent press1 = TouchWithTime(
+      ui::ET_TOUCH_PRESSED, ids[1], times_in_ms[1]);
+  event.OnTouch(press1);
+  EXPECT_EQ(MsToTicks(times_in_ms[1]), event.GetEventTime());
+
+  TouchEvent move0 = TouchWithTime(
+      ui::ET_TOUCH_MOVED, ids[0], times_in_ms[2]);
+  event.OnTouch(move0);
+  EXPECT_EQ(MsToTicks(times_in_ms[2]), event.GetEventTime());
+
+  // Test cloning of timestamp information.
+  scoped_ptr<MotionEvent> clone = event.Clone();
+  EXPECT_EQ(MsToTicks(times_in_ms[2]), clone->GetEventTime());
+}
+
+TEST(MotionEventAuraTest, CachedAction) {
+  // Test that the cached action and cached action index are correct.
+  int ids[] = {4, 6};
+  MotionEventAura event;
+
+  TouchEvent press0 = TouchWithType(ET_TOUCH_PRESSED, ids[0]);
+  event.OnTouch(press0);
+  EXPECT_EQ(MotionEvent::ACTION_DOWN, event.GetAction());
+  EXPECT_EQ(1U, event.GetPointerCount());
+
+  TouchEvent press1 = TouchWithType(ET_TOUCH_PRESSED, ids[1]);
+  event.OnTouch(press1);
+  EXPECT_EQ(MotionEvent::ACTION_POINTER_DOWN, event.GetAction());
+  EXPECT_EQ(1, event.GetActionIndex());
+  EXPECT_EQ(2U, event.GetPointerCount());
+
+  // Test cloning of CachedAction information.
+  scoped_ptr<MotionEvent> clone = event.Clone();
+  EXPECT_EQ(MotionEvent::ACTION_POINTER_DOWN, clone->GetAction());
+  EXPECT_EQ(1, clone->GetActionIndex());
+
+  TouchEvent move0 = TouchWithType(ET_TOUCH_MOVED, ids[0]);
+  event.OnTouch(move0);
+  EXPECT_EQ(MotionEvent::ACTION_MOVE, event.GetAction());
+  EXPECT_EQ(2U, event.GetPointerCount());
+
+  TouchEvent release0 = TouchWithType(ET_TOUCH_RELEASED, ids[0]);
+  event.OnTouch(release0);
+  EXPECT_EQ(MotionEvent::ACTION_POINTER_UP, event.GetAction());
+  EXPECT_EQ(2U, event.GetPointerCount());
+  event.CleanupRemovedTouchPoints(release0);
+  EXPECT_EQ(1U, event.GetPointerCount());
+
+  TouchEvent release1 = TouchWithType(ET_TOUCH_RELEASED, ids[1]);
+  event.OnTouch(release1);
+  EXPECT_EQ(MotionEvent::ACTION_UP, event.GetAction());
+  EXPECT_EQ(1U, event.GetPointerCount());
+  event.CleanupRemovedTouchPoints(release1);
+  EXPECT_EQ(0U, event.GetPointerCount());
+}
+
+TEST(MotionEventAuraTest, Cancel) {
+  int ids[] = {4, 6};
+  MotionEventAura event;
+
+  TouchEvent press0 = TouchWithType(ET_TOUCH_PRESSED, ids[0]);
+  event.OnTouch(press0);
+  EXPECT_EQ(MotionEvent::ACTION_DOWN, event.GetAction());
+  EXPECT_EQ(1U, event.GetPointerCount());
+
+  TouchEvent press1 = TouchWithType(ET_TOUCH_PRESSED, ids[1]);
+  event.OnTouch(press1);
+  EXPECT_EQ(MotionEvent::ACTION_POINTER_DOWN, event.GetAction());
+  EXPECT_EQ(1, event.GetActionIndex());
+  EXPECT_EQ(2U, event.GetPointerCount());
+
+  scoped_ptr<MotionEvent> cancel = event.Cancel();
+  EXPECT_EQ(MotionEvent::ACTION_CANCEL, cancel->GetAction());
+  EXPECT_EQ(2U, static_cast<MotionEventAura*>(cancel.get())->GetPointerCount());
+}
+
+}  // namespace ui
diff --git a/ui/events/ozone/evdev/cursor_delegate_evdev.h b/ui/events/ozone/evdev/cursor_delegate_evdev.h
index b9ed4e9..586ce8d 100644
--- a/ui/events/ozone/evdev/cursor_delegate_evdev.h
+++ b/ui/events/ozone/evdev/cursor_delegate_evdev.h
@@ -22,8 +22,7 @@
   virtual void MoveCursorTo(gfx::AcceleratedWidget widget,
                             const gfx::PointF& location) = 0;
 
-  // Window under cursor & location in window.
-  virtual gfx::AcceleratedWidget window() = 0;
+  // Location in window.
   virtual gfx::PointF location() = 0;
 };
 
diff --git a/ui/events/test/events_test_utils.cc b/ui/events/test/events_test_utils.cc
index 26bdb01..5b5b1ba 100644
--- a/ui/events/test/events_test_utils.cc
+++ b/ui/events/test/events_test_utils.cc
@@ -4,6 +4,8 @@
 
 #include "ui/events/test/events_test_utils.h"
 
+#include "ui/events/event_source.h"
+
 namespace ui {
 
 EventTestApi::EventTestApi(Event* event) : event_(event) {}
diff --git a/ui/events/test/events_test_utils.h b/ui/events/test/events_test_utils.h
index 62c0ca4..ff38fc5 100644
--- a/ui/events/test/events_test_utils.h
+++ b/ui/events/test/events_test_utils.h
@@ -6,11 +6,13 @@
 #define UI_EVENTS_TEST_EVENTS_TEST_UTILS_H_
 
 #include "ui/events/event.h"
-#include "ui/events/event_source.h"
+#include "ui/events/event_dispatcher.h"
 #include "ui/events/event_target.h"
 
 namespace ui {
 
+class EventSource;
+
 class EventTestApi {
  public:
   explicit EventTestApi(Event* event);
diff --git a/ui/events/x/events_x.cc b/ui/events/x/events_x.cc
index 59e16cd..b03af6b 100644
--- a/ui/events/x/events_x.cc
+++ b/ui/events/x/events_x.cc
@@ -137,6 +137,8 @@
     flags |= ui::EF_ALT_DOWN;
   if (state & LockMask)
     flags |= ui::EF_CAPS_LOCK_DOWN;
+  if (state & Mod4Mask)
+    flags |= ui::EF_COMMAND_DOWN;
   if (state & Mod5Mask)
     flags |= ui::EF_ALTGR_DOWN;
   if (state & Button1Mask)
diff --git a/ui/file_manager/file_manager/audio_player.html b/ui/file_manager/file_manager/audio_player.html
index 87b5622..5a7070f 100644
--- a/ui/file_manager/file_manager/audio_player.html
+++ b/ui/file_manager/file_manager/audio_player.html
@@ -31,7 +31,7 @@
 
     <script src="common/js/async_util.js"></script>
     <script src="common/js/util.js"></script>
-    <script src="common/js/path_util.js"></script>
+    <script src="common/js/volume_manager_common.js"></script>
     <script src="foreground/js/file_type.js"></script>
     <script src="foreground/js/volume_manager_wrapper.js"></script>
     <script src="foreground/js/metadata/metadata_cache.js"></script>
diff --git a/ui/file_manager/file_manager/audio_player/js/audio_player_scripts.js b/ui/file_manager/file_manager/audio_player/js/audio_player_scripts.js
index b800c48..9f84d7f 100644
--- a/ui/file_manager/file_manager/audio_player/js/audio_player_scripts.js
+++ b/ui/file_manager/file_manager/audio_player/js/audio_player_scripts.js
@@ -15,7 +15,6 @@
 
 // Force Polymer into dirty-checking mode, see http://crbug.com/351967
 Object['observe'] = undefined;
-Object['unobserve'] = undefined;
 
 <include src="../../../../../third_party/polymer/platform/platform.js">
 <include src="../../../../../third_party/polymer/polymer/polymer.js">
@@ -27,7 +26,7 @@
 
 <include src="../../common/js/async_util.js"/>
 <include src="../../common/js/util.js"/>
-<include src="../../common/js/path_util.js"/>
+<include src="../../common/js/volume_manager_common.js"/>
 <include src="../../foreground/js/file_type.js"/>
 <include src="../../foreground/js/volume_manager_wrapper.js">
 <include src="../../foreground/js/metadata/metadata_cache.js"/>
diff --git a/ui/file_manager/file_manager/background/js/device_handler.js b/ui/file_manager/file_manager/background/js/device_handler.js
index e196f8f..fa098d1 100644
--- a/ui/file_manager/file_manager/background/js/device_handler.js
+++ b/ui/file_manager/file_manager/background/js/device_handler.js
@@ -17,7 +17,7 @@
   this.mountStatus_ = {};
 
   /**
-   * List of ID of notificaitons that have a button.
+   * List of ID of notifications that have a button.
    * @type {Array.<string>}
    * @private
    */
@@ -176,7 +176,7 @@
 };
 
 /**
- * Shows the notificaiton after 5 seconds.
+ * Shows the notification after 5 seconds.
  * @param {string} devicePath Device path.
  */
 DeviceHandler.Notification.prototype.showLater = function(devicePath) {
diff --git a/ui/file_manager/file_manager/background/js/volume_manager.js b/ui/file_manager/file_manager/background/js/volume_manager.js
index ecf70ff..3787aaa 100644
--- a/ui/file_manager/file_manager/background/js/volume_manager.js
+++ b/ui/file_manager/file_manager/background/js/volume_manager.js
@@ -8,7 +8,7 @@
  * Represents each volume, such as "drive", "download directory", each "USB
  * flush storage", or "mounted zip archive" etc.
  *
- * @param {util.VolumeType} volumeType The type of the volume.
+ * @param {VolumeManagerCommon.VolumeType} volumeType The type of the volume.
  * @param {string} volumeId ID of the volume.
  * @param {DOMFileSystem} fileSystem The file system object for this volume.
  * @param {string} error The error if an error is found.
@@ -39,21 +39,21 @@
   this.displayRoot_ = null;
   this.displayRootPromise_ = null;
 
-  if (volumeType === util.VolumeType.DRIVE) {
+  if (volumeType === VolumeManagerCommon.VolumeType.DRIVE) {
     // TODO(mtomasz): Convert fake entries to DirectoryProvider.
-    this.fakeEntries_[RootType.DRIVE_OFFLINE] = {
+    this.fakeEntries_[VolumeManagerCommon.RootType.DRIVE_OFFLINE] = {
       isDirectory: true,
-      rootType: RootType.DRIVE_OFFLINE,
+      rootType: VolumeManagerCommon.RootType.DRIVE_OFFLINE,
       toURL: function() { return 'fake-entry://drive_offline' }
     };
-    this.fakeEntries_[RootType.DRIVE_SHARED_WITH_ME] = {
+    this.fakeEntries_[VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME] = {
       isDirectory: true,
-      rootType: RootType.DRIVE_SHARED_WITH_ME,
+      rootType: VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME,
       toURL: function() { return 'fake-entry://drive_shared_with_me'; }
     };
-    this.fakeEntries_[RootType.DRIVE_RECENT] = {
+    this.fakeEntries_[VolumeManagerCommon.RootType.DRIVE_RECENT] = {
       isDirectory: true,
-      rootType: RootType.DRIVE_RECENT,
+      rootType: VolumeManagerCommon.RootType.DRIVE_RECENT,
       toURL: function() { return 'fake-entry://drive_recent'; }
     };
   }
@@ -71,7 +71,7 @@
 
 VolumeInfo.prototype = {
   /**
-   * @return {util.VolumeType} Volume type.
+   * @return {VolumeManagerCommon.VolumeType} Volume type.
    */
   get volumeType() {
     return this.volumeType_;
@@ -145,7 +145,7 @@
   if (!this.displayRootPromise_) {
     // TODO(mtomasz): Do not add VolumeInfo which failed to resolve root, and
     // remove this if logic. Call onSuccess() always, instead.
-    if (this.volumeType !== util.VolumeType.DRIVE) {
+    if (this.volumeType !== VolumeManagerCommon.VolumeType.DRIVE) {
       if (this.fileSystem_)
         this.displayRootPromise_ = Promise.resolve(this.fileSystem_.root);
       else
@@ -171,12 +171,15 @@
 var volumeManagerUtil = {};
 
 /**
- * Throws an Error when the given error is not in util.VolumeError.
- * @param {util.VolumeError} error Status string usually received from APIs.
+ * Throws an Error when the given error is not in
+ * VolumeManagerCommon.VolumeError.
+ *
+ * @param {VolumeManagerCommon.VolumeError} error Status string usually received
+ *     from APIs.
  */
 volumeManagerUtil.validateError = function(error) {
-  for (var key in util.VolumeError) {
-    if (error === util.VolumeError[key])
+  for (var key in VolumeManagerCommon.VolumeError) {
+    if (error === VolumeManagerCommon.VolumeError[key])
       return;
   }
 
@@ -191,10 +194,10 @@
 volumeManagerUtil.createVolumeInfo = function(volumeMetadata, callback) {
   var localizedLabel;
   switch (volumeMetadata.volumeType) {
-    case util.VolumeType.DOWNLOADS:
+    case VolumeManagerCommon.VolumeType.DOWNLOADS:
       localizedLabel = str('DOWNLOADS_DIRECTORY_LABEL');
       break;
-    case util.VolumeType.DRIVE:
+    case VolumeManagerCommon.VolumeType.DRIVE:
       localizedLabel = str('DRIVE_DIRECTORY_LABEL');
       break;
     default:
@@ -219,7 +222,8 @@
               localizedLabel));
           return;
         }
-        if (volumeMetadata.volumeType === util.VolumeType.DRIVE) {
+        if (volumeMetadata.volumeType ==
+            VolumeManagerCommon.VolumeType.DRIVE) {
           // After file system is mounted, we "read" drive grand root
           // entry at first. This triggers full feed fetch on background.
           // Note: we don't need to handle errors here, because even if
@@ -246,17 +250,17 @@
 
 /**
  * The order of the volume list based on root type.
- * @type {Array.<util.VolumeType>}
+ * @type {Array.<VolumeManagerCommon.VolumeType>}
  * @const
  * @private
  */
 volumeManagerUtil.volumeListOrder_ = [
-  util.VolumeType.DRIVE,
-  util.VolumeType.DOWNLOADS,
-  util.VolumeType.ARCHIVE,
-  util.VolumeType.REMOVABLE,
-  util.VolumeType.MTP,
-  util.VolumeType.CLOUD_DEVICE
+  VolumeManagerCommon.VolumeType.DRIVE,
+  VolumeManagerCommon.VolumeType.DOWNLOADS,
+  VolumeManagerCommon.VolumeType.ARCHIVE,
+  VolumeManagerCommon.VolumeType.REMOVABLE,
+  VolumeManagerCommon.VolumeType.MTP,
+  VolumeManagerCommon.VolumeType.CLOUD_DEVICE
 ];
 
 /**
@@ -421,8 +425,8 @@
   // The status should be merged into VolumeManager.
   // TODO(hidehiko): Remove them after the migration.
   this.driveConnectionState_ = {
-    type: util.DriveConnectionType.OFFLINE,
-    reason: util.DriveConnectionReason.NO_SERVICE
+    type: VolumeManagerCommon.DriveConnectionType.OFFLINE,
+    reason: VolumeManagerCommon.DriveConnectionReason.NO_SERVICE
   };
 
   chrome.fileBrowserPrivate.onDriveConnectionStatusChanged.addListener(
@@ -443,7 +447,7 @@
 
 /**
  * Returns the drive connection state.
- * @return {util.DriveConnectionType} Connection type.
+ * @return {VolumeManagerCommon.DriveConnectionType} Connection type.
  */
 VolumeManager.prototype.getDriveConnectionState = function() {
   return this.driveConnectionState_;
@@ -518,7 +522,8 @@
               volumeMetadata,
               function(volumeInfo) {
                 this.volumeInfoList.add(volumeInfo);
-                if (volumeMetadata.volumeType === util.VolumeType.DRIVE)
+                if (volumeMetadata.volumeType ===
+                    VolumeManagerCommon.VolumeType.DRIVE)
                   this.onDriveConnectionStatusChanged_();
                 continueCallback();
               }.bind(this));
@@ -559,7 +564,8 @@
                 this.volumeInfoList.add(volumeInfo);
                 this.finishRequest_(requestKey, event.status, volumeInfo);
 
-                if (volumeInfo.volumeType === util.VolumeType.DRIVE) {
+                if (volumeInfo.volumeType ===
+                    VolumeManagerCommon.VolumeType.DRIVE) {
                   // Update the network connection status, because until the
                   // drive is initialized, the status is set to not ready.
                   // TODO(mtomasz): The connection status should be migrated
@@ -578,7 +584,7 @@
       case 'unmount':
         var volumeId = event.volumeMetadata.volumeId;
         var status = event.status;
-        if (status === util.VolumeError.PATH_UNMOUNTED) {
+        if (status === VolumeManagerCommon.VolumeError.PATH_UNMOUNTED) {
           console.warn('Volume already unmounted: ', volumeId);
           status = 'success';
         }
@@ -620,7 +626,8 @@
 /**
  * @param {string} fileUrl File url to the archive file.
  * @param {function(VolumeInfo)} successCallback Success callback.
- * @param {function(util.VolumeError)} errorCallback Error callback.
+ * @param {function(VolumeManagerCommon.VolumeError)} errorCallback Error
+ *     callback.
  */
 VolumeManager.prototype.mountArchive = function(
     fileUrl, successCallback, errorCallback) {
@@ -636,7 +643,8 @@
  * Unmounts volume.
  * @param {!VolumeInfo} volumeInfo Volume to be unmounted.
  * @param {function()} successCallback Success callback.
- * @param {function(util.VolumeError)} errorCallback Error callback.
+ * @param {function(VolumeManagerCommon.VolumeError)} errorCallback Error
+ *     callback.
  */
 VolumeManager.prototype.unmount = function(volumeInfo,
                                            successCallback,
@@ -658,7 +666,7 @@
 /**
  * Obtains volume information of the current profile.
  *
- * @param {util.VolumeType} volumeType Volume type.
+ * @param {VolumeManagerCommon.VolumeType} volumeType Volume type.
  * @return {VolumeInfo} Volume info.
  */
 VolumeManager.prototype.getCurrentProfileVolumeInfo = function(volumeType) {
@@ -693,16 +701,16 @@
   var rootType;
   var isReadOnly;
   var isRootEntry;
-  if (volumeInfo.volumeType === util.VolumeType.DRIVE) {
+  if (volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DRIVE) {
     // For Drive, the roots are /root and /other, instead of /. Root URLs
     // contain trailing slashes.
     if (entry.fullPath == '/root' || entry.fullPath.indexOf('/root/') === 0) {
-      rootType = RootType.DRIVE;
+      rootType = VolumeManagerCommon.RootType.DRIVE;
       isReadOnly = volumeInfo.isReadOnly;
       isRootEntry = entry.fullPath === '/root';
     } else if (entry.fullPath == '/other' ||
                entry.fullPath.indexOf('/other/') === 0) {
-      rootType = RootType.DRIVE_OTHER;
+      rootType = VolumeManagerCommon.RootType.DRIVE_OTHER;
       isReadOnly = true;
       isRootEntry = entry.fullPath === '/other';
     } else {
@@ -712,20 +720,20 @@
     }
   } else {
     switch (volumeInfo.volumeType) {
-      case util.VolumeType.DOWNLOADS:
-        rootType = RootType.DOWNLOADS;
+      case VolumeManagerCommon.VolumeType.DOWNLOADS:
+        rootType = VolumeManagerCommon.RootType.DOWNLOADS;
         break;
-      case util.VolumeType.REMOVABLE:
-        rootType = RootType.REMOVABLE;
+      case VolumeManagerCommon.VolumeType.REMOVABLE:
+        rootType = VolumeManagerCommon.RootType.REMOVABLE;
         break;
-      case util.VolumeType.ARCHIVE:
-        rootType = RootType.ARCHIVE;
+      case VolumeManagerCommon.VolumeType.ARCHIVE:
+        rootType = VolumeManagerCommon.RootType.ARCHIVE;
         break;
-      case util.VolumeType.CLOUD_DEVICE:
-        rootType = RootType.CLOUD_DEVICE;
+      case VolumeManagerCommon.VolumeType.CLOUD_DEVICE:
+        rootType = VolumeManagerCommon.RootType.CLOUD_DEVICE;
         break;
-      case util.VolumeType.MTP:
-        rootType = RootType.MTP;
+      case VolumeManagerCommon.VolumeType.MTP:
+        rootType = VolumeManagerCommon.RootType.MTP;
         break;
       default:
         // Programming error, throw an exception.
@@ -740,10 +748,10 @@
 
 /**
  * @param {string} key Key produced by |makeRequestKey_|.
- * @param {function(VolumeInfo)} successCallback To be called when request
+ * @param {function(VolumeInfo)} successCallback To be called when the request
  *     finishes successfully.
- * @param {function(util.VolumeError)} errorCallback To be called when
- *     request fails.
+ * @param {function(VolumeManagerCommon.VolumeError)} errorCallback To be called
+ *     when the request fails.
  * @private
  */
 VolumeManager.prototype.startRequest_ = function(key,
@@ -770,13 +778,14 @@
  */
 VolumeManager.prototype.onTimeout_ = function(key) {
   this.invokeRequestCallbacks_(this.requests_[key],
-                               util.VolumeError.TIMEOUT);
+                               VolumeManagerCommon.VolumeError.TIMEOUT);
   delete this.requests_[key];
 };
 
 /**
  * @param {string} key Key produced by |makeRequestKey_|.
- * @param {util.VolumeError|'success'} status Status received from the API.
+ * @param {VolumeManagerCommon.VolumeError|'success'} status Status received
+ *     from the API.
  * @param {VolumeInfo=} opt_volumeInfo Volume info of the mounted volume.
  * @private
  */
@@ -792,8 +801,8 @@
 
 /**
  * @param {Object} request Structure created in |startRequest_|.
- * @param {util.VolumeError|string} status If status === 'success'
- *     success callbacks are called.
+ * @param {VolumeManagerCommon.VolumeError|string} status If status ===
+ *     'success' success callbacks are called.
  * @param {VolumeInfo=} opt_volumeInfo Volume info of the mounted volume.
  * @private
  */
@@ -817,7 +826,7 @@
  * file system.
  *
  * @param {!VolumeInfo} volumeInfo Volume information.
- * @param {RootType} rootType Root type.
+ * @param {VolumeManagerCommon.RootType} rootType Root type.
  * @param {boolean} isRootEntry Whether the entry is root entry or not.
  * @param {boolean} isReadOnly Whether the entry is read only or not.
  * @constructor
@@ -831,7 +840,7 @@
 
   /**
    * Root type.
-   * @type {RootType}
+   * @type {VolumeManagerCommon.RootType}
    */
   this.rootType = rootType;
 
@@ -847,9 +856,9 @@
    * @type {boolean}
    */
   this.isSpecialSearchRoot =
-      this.rootType === RootType.DRIVE_OFFLINE ||
-      this.rootType === RootType.DRIVE_SHARED_WITH_ME ||
-      this.rootType === RootType.DRIVE_RECENT;
+      this.rootType === VolumeManagerCommon.RootType.DRIVE_OFFLINE ||
+      this.rootType === VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME ||
+      this.rootType === VolumeManagerCommon.RootType.DRIVE_RECENT;
 
   /**
    * Whether the location is under Google Drive or a special search root which
@@ -857,11 +866,11 @@
    * @type {boolean}
    */
   this.isDriveBased =
-      this.rootType === RootType.DRIVE ||
-      this.rootType === RootType.DRIVE_OTHER ||
-      this.rootType === RootType.DRIVE_SHARED_WITH_ME ||
-      this.rootType === RootType.DRIVE_RECENT ||
-      this.rootType === RootType.DRIVE_OFFLINE;
+      this.rootType === VolumeManagerCommon.RootType.DRIVE ||
+      this.rootType === VolumeManagerCommon.RootType.DRIVE_OTHER ||
+      this.rootType === VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME ||
+      this.rootType === VolumeManagerCommon.RootType.DRIVE_RECENT ||
+      this.rootType === VolumeManagerCommon.RootType.DRIVE_OFFLINE;
 
   /**
    * Whether the given path can be a target path of folder shortcut.
diff --git a/ui/file_manager/file_manager/common/js/path_util.js b/ui/file_manager/file_manager/common/js/path_util.js
deleted file mode 100644
index e55aad8..0000000
--- a/ui/file_manager/file_manager/common/js/path_util.js
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2012 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.
-
-'use strict';
-
-/**
- * Type of a root directory.
- * @enum {string}
- * @const
- */
-var RootType = Object.freeze({
-  // Root of local directory.
-  DOWNLOADS: 'downloads',
-
-  // Root of mounted archive file.
-  ARCHIVE: 'archive',
-
-  // Root of removal volume.
-  REMOVABLE: 'removable',
-
-  // Root of drive directory.
-  DRIVE: 'drive',
-
-  // Root for privet storage volume.
-  CLOUD_DEVICE: 'cloud_device',
-
-  // Root for MTP device.
-  MTP: 'mtp',
-
-  // Root for entries that is not located under RootType.DRIVE. e.g. shared
-  // files.
-  DRIVE_OTHER: 'drive_other',
-
-  // Fake root for offline available files on the drive.
-  DRIVE_OFFLINE: 'drive_offline',
-
-  // Fake root for shared files on the drive.
-  DRIVE_SHARED_WITH_ME: 'drive_shared_with_me',
-
-  // Fake root for recent files on the drive.
-  DRIVE_RECENT: 'drive_recent'
-});
-
-var PathUtil = {};
-
-/**
- * Extracts the extension of the path.
- *
- * Examples:
- * PathUtil.splitExtension('abc.ext') -> ['abc', '.ext']
- * PathUtil.splitExtension('a/b/abc.ext') -> ['a/b/abc', '.ext']
- * PathUtil.splitExtension('a/b') -> ['a/b', '']
- * PathUtil.splitExtension('.cshrc') -> ['', '.cshrc']
- * PathUtil.splitExtension('a/b.backup/hoge') -> ['a/b.backup/hoge', '']
- *
- * @param {string} path Path to be extracted.
- * @return {Array.<string>} Filename and extension of the given path.
- */
-PathUtil.splitExtension = function(path) {
-  var dotPosition = path.lastIndexOf('.');
-  if (dotPosition <= path.lastIndexOf('/'))
-    dotPosition = -1;
-
-  var filename = dotPosition != -1 ? path.substr(0, dotPosition) : path;
-  var extension = dotPosition != -1 ? path.substr(dotPosition) : '';
-  return [filename, extension];
-};
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js
index ce8f5fe..144e89e 100644
--- a/ui/file_manager/file_manager/common/js/util.js
+++ b/ui/file_manager/file_manager/common/js/util.js
@@ -1284,68 +1284,56 @@
 };
 
 /**
- * Error type of VolumeManager.
- * @enum {string}
- * @const
+ * Returns the localized name for the root type. If not available, then returns
+ * null.
+ *
+ * @param {VolumeManagerCommon.RootType} rootType The root type.
+ * @return {?string} The localized name, or null if not available.
  */
-util.VolumeError = Object.freeze({
-  /* Internal errors */
-  NOT_MOUNTED: 'not_mounted',
-  TIMEOUT: 'timeout',
+util.getRootTypeLabel = function(rootType) {
+  var str = function(id) {
+    return loadTimeData.getString(id);
+  };
 
-  /* System events */
-  UNKNOWN: 'error_unknown',
-  INTERNAL: 'error_internal',
-  UNKNOWN_FILESYSTEM: 'error_unknown_filesystem',
-  UNSUPPORTED_FILESYSTEM: 'error_unsupported_filesystem',
-  INVALID_ARCHIVE: 'error_invalid_archive',
-  AUTHENTICATION: 'error_authentication',
-  PATH_UNMOUNTED: 'error_path_unmounted'
-});
+  switch (rootType) {
+    case VolumeManagerCommon.RootType.DOWNLOADS:
+      return str('DOWNLOADS_DIRECTORY_LABEL');
+    case VolumeManagerCommon.RootType.DRIVE:
+      return str('DRIVE_MY_DRIVE_LABEL');
+    case VolumeManagerCommon.RootType.DRIVE_OFFLINE:
+      return str('DRIVE_OFFLINE_COLLECTION_LABEL');
+    case VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME:
+      return str('DRIVE_SHARED_WITH_ME_COLLECTION_LABEL');
+    case VolumeManagerCommon.RootType.DRIVE_RECENT:
+      return str('DRIVE_RECENT_COLLECTION_LABEL');
+  }
+
+  // Translation not found.
+  return null;
+};
 
 /**
- * List of connection types of drive.
+ * Extracts the extension of the path.
  *
- * Keep this in sync with the kDriveConnectionType* constants in
- * private_api_dirve.cc.
+ * Examples:
+ * util.splitExtension('abc.ext') -> ['abc', '.ext']
+ * util.splitExtension('a/b/abc.ext') -> ['a/b/abc', '.ext']
+ * util.splitExtension('a/b') -> ['a/b', '']
+ * util.splitExtension('.cshrc') -> ['', '.cshrc']
+ * util.splitExtension('a/b.backup/hoge') -> ['a/b.backup/hoge', '']
  *
- * @enum {string}
- * @const
+ * @param {string} path Path to be extracted.
+ * @return {Array.<string>} Filename and extension of the given path.
  */
-util.DriveConnectionType = Object.freeze({
-  OFFLINE: 'offline',  // Connection is offline or drive is unavailable.
-  METERED: 'metered',  // Connection is metered. Should limit traffic.
-  ONLINE: 'online'     // Connection is online.
-});
+util.splitExtension = function(path) {
+  var dotPosition = path.lastIndexOf('.');
+  if (dotPosition <= path.lastIndexOf('/'))
+    dotPosition = -1;
 
-/**
- * List of reasons of DriveConnectionType.
- *
- * Keep this in sync with the kDriveConnectionReason constants in
- * private_api_drive.cc.
- *
- * @enum {string}
- * @const
- */
-util.DriveConnectionReason = Object.freeze({
-  NOT_READY: 'not_ready',    // Drive is not ready or authentication is failed.
-  NO_NETWORK: 'no_network',  // Network connection is unavailable.
-  NO_SERVICE: 'no_service'   // Drive service is unavailable.
-});
-
-/**
- * The type of each volume.
- * @enum {string}
- * @const
- */
-util.VolumeType = Object.freeze({
-  DRIVE: 'drive',
-  DOWNLOADS: 'downloads',
-  REMOVABLE: 'removable',
-  ARCHIVE: 'archive',
-  CLOUD_DEVICE: 'cloud_device',
-  MTP: 'mtp'
-});
+  var filename = dotPosition != -1 ? path.substr(0, dotPosition) : path;
+  var extension = dotPosition != -1 ? path.substr(dotPosition) : '';
+  return [filename, extension];
+};
 
 /**
  * Returns the localized name of the entry.
@@ -1359,18 +1347,20 @@
 
   if (locationInfo && locationInfo.isRootEntry) {
     switch (locationInfo.rootType) {
-      case RootType.DRIVE:
+      case VolumeManagerCommon.RootType.DOWNLOADS:
+        return str('DOWNLOADS_DIRECTORY_LABEL');
+      case VolumeManagerCommon.RootType.DRIVE:
         return str('DRIVE_MY_DRIVE_LABEL');
-      case RootType.DRIVE_OFFLINE:
+      case VolumeManagerCommon.RootType.DRIVE_OFFLINE:
         return str('DRIVE_OFFLINE_COLLECTION_LABEL');
-      case RootType.DRIVE_SHARED_WITH_ME:
+      case VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME:
         return str('DRIVE_SHARED_WITH_ME_COLLECTION_LABEL');
-      case RootType.DRIVE_RECENT:
+      case VolumeManagerCommon.RootType.DRIVE_RECENT:
         return str('DRIVE_RECENT_COLLECTION_LABEL');
-      case RootType.DOWNLOADS:
-      case RootType.ARCHIVE:
-      case RootType.REMOVABLE:
-      case RootType.MTP:
+      case VolumeManagerCommon.RootType.DOWNLOADS:
+      case VolumeManagerCommon.RootType.ARCHIVE:
+      case VolumeManagerCommon.RootType.REMOVABLE:
+      case VolumeManagerCommon.RootType.MTP:
         return locationInfo.volumeInfo.label;
       default:
         console.error('Unsupported root type: ' + locationInfo.rootType);
diff --git a/ui/file_manager/file_manager/common/js/volume_manager_common.js b/ui/file_manager/file_manager/common/js/volume_manager_common.js
new file mode 100644
index 0000000..8a2344e
--- /dev/null
+++ b/ui/file_manager/file_manager/common/js/volume_manager_common.js
@@ -0,0 +1,239 @@
+// 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.
+
+'use strict';
+
+/**
+ * Namespace for common types shared between VolumeManager and
+ * VolumeManagerWrapper.
+ */
+var VolumeManagerCommon = {};
+
+/**
+ * Type of a root directory.
+ * @enum {string}
+ * @const
+ */
+VolumeManagerCommon.RootType = Object.freeze({
+  // Root for a downloads directory.
+  DOWNLOADS: 'downloads',
+
+  // Root for a mounted archive volume.
+  ARCHIVE: 'archive',
+
+  // Root for a removable volume.
+  REMOVABLE: 'removable',
+
+  // Root for a drive volume.
+  DRIVE: 'drive',
+
+  // Root for a privet storage volume.
+  CLOUD_DEVICE: 'cloud_device',
+
+  // Root for a MTP volume.
+  MTP: 'mtp',
+
+  // Root for entries that is not located under RootType.DRIVE. e.g. shared
+  // files.
+  DRIVE_OTHER: 'drive_other',
+
+  // Fake root for offline available files on the drive.
+  DRIVE_OFFLINE: 'drive_offline',
+
+  // Fake root for shared files on the drive.
+  DRIVE_SHARED_WITH_ME: 'drive_shared_with_me',
+
+  // Fake root for recent files on the drive.
+  DRIVE_RECENT: 'drive_recent'
+});
+
+/**
+ * Error type of VolumeManager.
+ * @enum {string}
+ * @const
+ */
+VolumeManagerCommon.VolumeError = Object.freeze({
+  /* Internal errors */
+  TIMEOUT: 'timeout',
+
+  /* System events */
+  UNKNOWN: 'error_unknown',
+  INTERNAL: 'error_internal',
+  INVALID_ARGUMENT: 'error_invalid_argument',
+  INVALID_PATH: 'error_invalid_path',
+  ALREADY_MOUNTED: 'error_path_already_mounted',
+  PATH_NOT_MOUNTED: 'error_path_not_mounted',
+  DIRECTORY_CREATION_FAILED: 'error_directory_creation_failed',
+  INVALID_MOUNT_OPTIONS: 'error_invalid_mount_options',
+  INVALID_UNMOUNT_OPTIONS: 'error_invalid_unmount_options',
+  INSUFFICIENT_PERMISSIONS: 'error_insufficient_permissions',
+  MOUNT_PROGRAM_NOT_FOUND: 'error_mount_program_not_found',
+  MOUNT_PROGRAM_FAILED: 'error_mount_program_failed',
+  INVALID_DEVICE_PATH: 'error_invalid_device_path',
+  UNKNOWN_FILESYSTEM: 'error_unknown_filesystem',
+  UNSUPPORTED_FILESYSTEM: 'error_unsupported_filesystem',
+  INVALID_ARCHIVE: 'error_invalid_archive',
+  AUTHENTICATION: 'error_authentication',
+  PATH_UNMOUNTED: 'error_path_unmounted'
+});
+
+/**
+ * List of connection types of drive.
+ *
+ * Keep this in sync with the kDriveConnectionType* constants in
+ * private_api_dirve.cc.
+ *
+ * @enum {string}
+ * @const
+ */
+VolumeManagerCommon.DriveConnectionType = Object.freeze({
+  OFFLINE: 'offline',  // Connection is offline or drive is unavailable.
+  METERED: 'metered',  // Connection is metered. Should limit traffic.
+  ONLINE: 'online'     // Connection is online.
+});
+
+/**
+ * List of reasons of DriveConnectionType.
+ *
+ * Keep this in sync with the kDriveConnectionReason constants in
+ * private_api_drive.cc.
+ *
+ * @enum {string}
+ * @const
+ */
+VolumeManagerCommon.DriveConnectionReason = Object.freeze({
+  NOT_READY: 'not_ready',    // Drive is not ready or authentication is failed.
+  NO_NETWORK: 'no_network',  // Network connection is unavailable.
+  NO_SERVICE: 'no_service'   // Drive service is unavailable.
+});
+
+/**
+ * The type of each volume.
+ * @enum {string}
+ * @const
+ */
+VolumeManagerCommon.VolumeType = Object.freeze({
+  DRIVE: 'drive',
+  DOWNLOADS: 'downloads',
+  REMOVABLE: 'removable',
+  ARCHIVE: 'archive',
+  CLOUD_DEVICE: 'cloud_device',
+  MTP: 'mtp',
+});
+
+
+// Copyright (c) 2012 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.
+
+'use strict';
+
+/**
+ * Namespace for common types shared between VolumeManager and
+ * VolumeManagerWrapper.
+ */
+var VolumeManagerCommon = {};
+
+/**
+ * Type of a root directory.
+ * @enum {string}
+ * @const
+ */
+VolumeManagerCommon.RootType = Object.freeze({
+  // Root for a downloads directory.
+  DOWNLOADS: 'downloads',
+
+  // Root for a mounted archive volume.
+  ARCHIVE: 'archive',
+
+  // Root for a removable volume.
+  REMOVABLE: 'removable',
+
+  // Root for a drive volume.
+  DRIVE: 'drive',
+
+  // Root for a privet storage volume.
+  CLOUD_DEVICE: 'cloud_device',
+
+  // Root for a MTP volume.
+  MTP: 'mtp',
+
+  // Root for entries that is not located under RootType.DRIVE. e.g. shared
+  // files.
+  DRIVE_OTHER: 'drive_other',
+
+  // Fake root for offline available files on the drive.
+  DRIVE_OFFLINE: 'drive_offline',
+
+  // Fake root for shared files on the drive.
+  DRIVE_SHARED_WITH_ME: 'drive_shared_with_me',
+
+  // Fake root for recent files on the drive.
+  DRIVE_RECENT: 'drive_recent'
+});
+
+/**
+ * Error type of VolumeManager.
+ * @enum {string}
+ * @const
+ */
+VolumeManagerCommon.VolumeError = Object.freeze({
+  /* Internal errors */
+  NOT_MOUNTED: 'not_mounted',
+  TIMEOUT: 'timeout',
+
+  /* System events */
+  UNKNOWN: 'error_unknown',
+  INTERNAL: 'error_internal',
+  UNKNOWN_FILESYSTEM: 'error_unknown_filesystem',
+  UNSUPPORTED_FILESYSTEM: 'error_unsupported_filesystem',
+  INVALID_ARCHIVE: 'error_invalid_archive',
+  AUTHENTICATION: 'error_authentication',
+  PATH_UNMOUNTED: 'error_path_unmounted'
+});
+
+/**
+ * List of connection types of drive.
+ *
+ * Keep this in sync with the kDriveConnectionType* constants in
+ * private_api_dirve.cc.
+ *
+ * @enum {string}
+ * @const
+ */
+VolumeManagerCommon.DriveConnectionType = Object.freeze({
+  OFFLINE: 'offline',  // Connection is offline or drive is unavailable.
+  METERED: 'metered',  // Connection is metered. Should limit traffic.
+  ONLINE: 'online'     // Connection is online.
+});
+
+/**
+ * List of reasons of DriveConnectionType.
+ *
+ * Keep this in sync with the kDriveConnectionReason constants in
+ * private_api_drive.cc.
+ *
+ * @enum {string}
+ * @const
+ */
+VolumeManagerCommon.DriveConnectionReason = Object.freeze({
+  NOT_READY: 'not_ready',    // Drive is not ready or authentication is failed.
+  NO_NETWORK: 'no_network',  // Network connection is unavailable.
+  NO_SERVICE: 'no_service'   // Drive service is unavailable.
+});
+
+/**
+ * The type of each volume.
+ * @enum {string}
+ * @const
+ */
+VolumeManagerCommon.VolumeType = Object.freeze({
+  DRIVE: 'drive',
+  DOWNLOADS: 'downloads',
+  REMOVABLE: 'removable',
+  ARCHIVE: 'archive',
+  CLOUD_DEVICE: 'cloud_device'
+});
+
+
diff --git a/ui/file_manager/file_manager/foreground/js/directory_contents.js b/ui/file_manager/file_manager/foreground/js/directory_contents.js
index 6223883..37125ba 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_contents.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_contents.js
@@ -638,6 +638,11 @@
   var entriesFiltered = [].filter.call(
       entries, this.context_.fileFilter.filter.bind(this.context_.fileFilter));
 
+  // Caching URL to reduce a number of calls of toURL in sort.
+  // This is a temporary solution. We need to fix a root cause of slow toURL.
+  // See crbug.com/370908 for detail.
+  entriesFiltered.forEach(function(entry) { entry.cachedUrl = entry.toURL(); });
+
   // Update the filelist without waiting the metadata.
   this.fileList_.push.apply(this.fileList_, entriesFiltered);
   cr.dispatchSimpleEvent(this, 'scan-updated');
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js
index 7736e0f..9afcacc 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_model.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -81,7 +81,8 @@
 };
 
 /**
- * @return {?RootType} Root type of current root, or null if not found.
+ * @return {?VolumeManagerCommon.RootType} Root type of current root, or null if
+ *     not found.
  */
 DirectoryModel.prototype.getCurrentRootType = function() {
   var entry = this.currentDirContents_.getDirectoryEntry();
@@ -164,6 +165,11 @@
  * @private
  */
 DirectoryModel.prototype.onWatcherDirectoryChanged_ = function() {
+  // Clear the metadata cache since something in this directory has changed.
+  var directoryEntry = this.getCurrentDirEntry();
+  if (!util.isFakeEntry(directoryEntry))
+    this.metadataCache_.clearRecursively(directoryEntry, '*');
+
   this.rescanSoon();
 };
 
@@ -405,7 +411,8 @@
     if (!dirContents.isSearch()) {
       var locationInfo =
           this.volumeManager_.getLocationInfo(dirContents.getDirectoryEntry());
-      if (locationInfo.volumeInfo.volumeType === util.VolumeType.DOWNLOADS &&
+      if (locationInfo.volumeInfo.volumeType ===
+          VolumeManagerCommon.VolumeType.DOWNLOADS &&
           locationInfo.isRootEntry) {
         metrics.recordMediumCount('DownloadsCount',
                                   dirContents.fileList_.length);
@@ -485,10 +492,10 @@
   // TODO(hidehiko): We should update directory model even the search result
   // is shown.
   var rootType = this.getCurrentRootType();
-  if ((rootType === RootType.DRIVE ||
-       rootType === RootType.DRIVE_SHARED_WITH_ME ||
-       rootType === RootType.DRIVE_RECENT ||
-       rootType === RootType.DRIVE_OFFLINE) &&
+  if ((rootType === VolumeManagerCommon.RootType.DRIVE ||
+       rootType === VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME ||
+       rootType === VolumeManagerCommon.RootType.DRIVE_RECENT ||
+       rootType === VolumeManagerCommon.RootType.DRIVE_OFFLINE) &&
       this.isSearching())
     return;
 
@@ -801,7 +808,7 @@
   if (!locationInfo)
     return null;
   var canUseDriveSearch = this.volumeManager_.getDriveConnectionState().type !==
-      util.DriveConnectionType.OFFLINE &&
+      VolumeManagerCommon.DriveConnectionType.OFFLINE &&
       locationInfo.isDriveBased;
 
   if (query && canUseDriveSearch) {
@@ -814,15 +821,15 @@
     // Drive special search.
     var searchType;
     switch (locationInfo.rootType) {
-      case RootType.DRIVE_OFFLINE:
+      case VolumeManagerCommon.RootType.DRIVE_OFFLINE:
         searchType =
             DriveMetadataSearchContentScanner.SearchType.SEARCH_OFFLINE;
         break;
-      case RootType.DRIVE_SHARED_WITH_ME:
+      case VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME:
         searchType =
             DriveMetadataSearchContentScanner.SearchType.SEARCH_SHARED_WITH_ME;
         break;
-      case RootType.DRIVE_RECENT:
+      case VolumeManagerCommon.RootType.DRIVE_RECENT:
         searchType =
             DriveMetadataSearchContentScanner.SearchType.SEARCH_RECENT_FILES;
         break;
diff --git a/ui/file_manager/file_manager/foreground/js/drive_banners.js b/ui/file_manager/file_manager/foreground/js/drive_banners.js
index 078778f..106f1eb 100644
--- a/ui/file_manager/file_manager/foreground/js/drive_banners.js
+++ b/ui/file_manager/file_manager/foreground/js/drive_banners.js
@@ -300,7 +300,7 @@
   }
 
   var driveVolume = this.volumeManager_.getCurrentProfileVolumeInfo(
-      util.VolumeType.DRIVE);
+      VolumeManagerCommon.VolumeType.DRIVE);
   if (this.welcomeHeaderCounter_ >= WELCOME_HEADER_COUNTER_LIMIT ||
       !driveVolume || driveVolume.error) {
     // The banner is already shown enough times or the drive FS is not mounted.
@@ -399,7 +399,7 @@
     return false;
   var locationInfo = this.volumeManager_.getLocationInfo(entry);
   return locationInfo &&
-      locationInfo.rootType === RootType.DRIVE &&
+      locationInfo.rootType === VolumeManagerCommon.RootType.DRIVE &&
       locationInfo.volumeInfo.profile.isCurrentProfile;
 };
 
@@ -465,8 +465,8 @@
     function(volumeInfo) {
   return volumeInfo &&
       volumeInfo.profile.isCurrentProfile &&
-      (volumeInfo.volumeType === util.VolumeType.DOWNLOADS ||
-       volumeInfo.volumeType === util.VolumeType.DRIVE);
+      (volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DOWNLOADS ||
+       volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DRIVE);
 };
 
 /**
@@ -500,11 +500,11 @@
   // TODO(kaznacheev): Unify the two low space warning.
   var threshold = 0;
   switch (volume.volumeType) {
-    case util.VolumeType.DOWNLOADS:
+    case VolumeManagerCommon.VolumeType.DOWNLOADS:
       this.showLowDriveSpaceWarning_(false);
       threshold = 0.2;
       break;
-    case util.VolumeType.DRIVE:
+    case VolumeManagerCommon.VolumeType.DRIVE:
       this.showLowDownloadsSpaceWarning_(false);
       threshold = 0.1;
       break;
@@ -536,7 +536,7 @@
 
         var remainingRatio = sizeStats.remainingSize / sizeStats.totalSize;
         var isLowDiskSpace = remainingRatio < threshold;
-        if (volume.volumeType === util.VolumeType.DOWNLOADS)
+        if (volume.volumeType === VolumeManagerCommon.VolumeType.DOWNLOADS)
           this.showLowDownloadsSpaceWarning_(isLowDiskSpace);
         else
           this.showLowDriveSpaceWarning_(isLowDiskSpace, sizeStats);
@@ -625,7 +625,7 @@
  */
 FileListBannerController.prototype.onVolumeInfoListSplice_ = function(event) {
   var isDriveVolume = function(volumeInfo) {
-    return volumeInfo.volumeType === util.VolumeType.DRIVE;
+    return volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DRIVE;
   };
   if (event.removed.some(isDriveVolume) || event.added.some(isDriveVolume))
     this.updateDriveUnmountedPanel_();
@@ -641,7 +641,7 @@
   var node = this.document_.body;
   if (this.isOnCurrentProfileDrive()) {
     var driveVolume = this.volumeManager_.getCurrentProfileVolumeInfo(
-        util.VolumeType.DRIVE);
+        VolumeManagerCommon.VolumeType.DRIVE);
     if (driveVolume && driveVolume.error) {
       this.ensureDriveUnmountedPanelInitialized_();
       this.unmountedPanel_.classList.add('retry-enabled');
@@ -663,7 +663,7 @@
   var connection = this.volumeManager_.getDriveConnectionState();
   var showDriveNotReachedMessage =
       this.isOnCurrentProfileDrive() &&
-      connection.type == util.DriveConnectionType.OFFLINE &&
-      connection.reason == util.DriveConnectionReason.NOT_READY;
+      connection.type == VolumeManagerCommon.DriveConnectionType.OFFLINE &&
+      connection.reason == VolumeManagerCommon.DriveConnectionReason.NOT_READY;
   this.authFailedBanner_.hidden = !showDriveNotReachedMessage;
 };
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index 428f018..07aa224 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -1068,7 +1068,7 @@
 
     var driveVolume = this.volumeManager_.getVolumeInfo(entry);
     var visible = driveVolume && !driveVolume.error &&
-        driveVolume.volumeType === util.VolumeType.DRIVE;
+        driveVolume.volumeType === VolumeManagerCommon.VolumeType.DRIVE;
     this.dialogDom_.
         querySelector('.dialog-middlebar-contents').hidden = !visible;
     this.dialogDom_.querySelector('#middlebar-splitter').hidden = !visible;
@@ -1727,10 +1727,10 @@
    */
   FileManager.prototype.isOnDrive = function() {
     var rootType = this.directoryModel_.getCurrentRootType();
-    return rootType === RootType.DRIVE ||
-           rootType === RootType.DRIVE_SHARED_WITH_ME ||
-           rootType === RootType.DRIVE_RECENT ||
-           rootType === RootType.DRIVE_OFFLINE;
+    return rootType === VolumeManagerCommon.RootType.DRIVE ||
+           rootType === VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME ||
+           rootType === VolumeManagerCommon.RootType.DRIVE_RECENT ||
+           rootType === VolumeManagerCommon.RootType.DRIVE_OFFLINE;
   };
 
   /**
@@ -2147,7 +2147,7 @@
       }
 
       var basename = entry.name;
-      var splitted = PathUtil.splitExtension(basename);
+      var splitted = util.splitExtension(basename);
       var filename = splitted[0];
       var extension = splitted[1];
       var mime = props[0].contentMimeType;
@@ -2372,7 +2372,8 @@
       this.dialogDom_.setAttribute('unformatted', '');
 
       var errorNode = this.dialogDom_.querySelector('#format-panel > .error');
-      if (volumeInfo.error == util.VolumeError.UNSUPPORTED_FILESYSTEM) {
+      if (volumeInfo.error ===
+          VolumeManagerCommon.VolumeError.UNSUPPORTED_FILESYSTEM) {
         errorNode.textContent = str('UNSUPPORTED_FILESYSTEM_WARNING');
       } else {
         errorNode.textContent = str('UNKNOWN_FILESYSTEM_WARNING');
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
index c59b96e..c4123c6 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -224,6 +224,22 @@
 };
 
 /**
+ * Returns a directory entry when only one entry is selected and it is
+ * directory. Otherwise, returns null.
+ * @param {FileSelection} selection Instance of FileSelection.
+ * @return {?DirectoryEntry} Directory entry which is selected alone.
+ */
+CommandUtil.getOnlyOneSelectedDirectory = function(selection) {
+  if (!selection)
+    return null;
+  if (selection.totalCount !== 1)
+    return null;
+  if (!selection.entries[0].isDirectory)
+    return null;
+  return selection.entries[0];
+};
+
+/**
  * Handle of the command events.
  * @param {FileManager} fileManager FileManager.
  * @constructor
@@ -351,10 +367,10 @@
     var rootType =
         locationInfo && locationInfo.isRootEntry && locationInfo.rootType;
 
-    event.canExecute = (rootType == RootType.ARCHIVE ||
-                        rootType == RootType.REMOVABLE);
+    event.canExecute = (rootType == VolumeManagerCommon.RootType.ARCHIVE ||
+                        rootType == VolumeManagerCommon.RootType.REMOVABLE);
     event.command.setHidden(!event.canExecute);
-    event.command.label = rootType == RootType.ARCHIVE ?
+    event.command.label = rootType == VolumeManagerCommon.RootType.ARCHIVE ?
         str('CLOSE_ARCHIVE_BUTTON_LABEL') :
         str('UNMOUNT_DEVICE_BUTTON_LABEL');
   }
@@ -397,7 +413,8 @@
     if (!root)
       root = directoryModel.getCurrentDirEntry();
     var location = root && fileManager.volumeManager.getLocationInfo(root);
-    var removable = location && location.rootType === RootType.REMOVABLE;
+    var removable = location && location.rootType ===
+        VolumeManagerCommon.RootType.REMOVABLE;
     // Don't check if the volume is read-only. Unformatted volume is considered
     // read-only per VolumeInfo.isReadOnly, but can be formatted. An error will
     // be raised if formatting failed anyway.
@@ -495,14 +512,46 @@
  * @type {Command}
  */
 CommandHandler.COMMANDS_['paste'] = {
-  execute: function() {
-    document.execCommand(event.command.id);
+  execute: function(event, fileManager) {
+    fileManager.document.execCommand(event.command.id);
   },
   canExecute: function(event, fileManager) {
-    var document = fileManager.document;
     var fileTransferController = fileManager.fileTransferController;
     event.canExecute = (fileTransferController &&
         fileTransferController.queryPasteCommandEnabled());
+    // Hide this command if only one folder is selected.
+    event.command.setHidden(!!CommandUtil.getOnlyOneSelectedDirectory(
+        fileManager.getSelection()));
+  }
+};
+
+/**
+ * Pastes files from clipboard into the selected folder.
+ * @type {Command}
+ */
+CommandHandler.COMMANDS_['paste-into-folder'] = {
+  execute: function(event, fileManager) {
+    var selection = fileManager.getSelection();
+    var dest = CommandUtil.getOnlyOneSelectedDirectory(selection);
+    if (!dest) return;
+
+    // This handler tweaks the Event object for 'paste' event so that
+    // the FileTransferController can distinguish this 'paste-into-folder'
+    // command and know the destination directory.
+    var handler = function(inEvent) {
+      inEvent.destDirectory = dest;
+    };
+    fileManager.document.addEventListener('paste', handler, true);
+    fileManager.document.execCommand('paste');
+    fileManager.document.removeEventListener('paste', handler, true);
+  },
+  canExecute: function(event, fileManager) {
+    var fileTransferController = fileManager.fileTransferController;
+    event.canExecute = (fileTransferController &&
+        fileTransferController.queryPasteCommandEnabled());
+    // Hide this command unless only one folder is selected.
+    event.command.setHidden(!CommandUtil.getOnlyOneSelectedDirectory(
+        fileManager.getSelection()));
   }
 };
 
@@ -737,7 +786,7 @@
     var selection = fileManager.getSelection();
     var isDriveOffline =
         fileManager.volumeManager.getDriveConnectionState().type ===
-            util.DriveConnectionType.OFFLINE;
+            VolumeManagerCommon.DriveConnectionType.OFFLINE;
     event.canExecute = fileManager.isOnDrive() &&
         !isDriveOffline &&
         selection && selection.totalCount == 1;
diff --git a/ui/file_manager/file_manager/foreground/js/file_selection.js b/ui/file_manager/file_manager/foreground/js/file_selection.js
index 9d6ca48..ec8b2e6 100644
--- a/ui/file_manager/file_manager/foreground/js/file_selection.js
+++ b/ui/file_manager/file_manager/foreground/js/file_selection.js
@@ -315,7 +315,7 @@
 FileSelectionHandler.prototype.isFileSelectionAvailable = function() {
   var isDriveOffline =
       this.fileManager_.volumeManager.getDriveConnectionState().type ===
-          util.DriveConnectionType.OFFLINE;
+          VolumeManagerCommon.DriveConnectionType.OFFLINE;
   return !this.fileManager_.isOnDrive() || !isDriveOffline ||
       this.selection.allDriveFilesPresent;
 };
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks.js b/ui/file_manager/file_manager/foreground/js/file_tasks.js
index 8a2aa0f..18dd66e 100644
--- a/ui/file_manager/file_manager/foreground/js/file_tasks.js
+++ b/ui/file_manager/file_manager/foreground/js/file_tasks.js
@@ -329,7 +329,7 @@
     return;
 
   var filename = entries[0].name;
-  var extension = PathUtil.splitExtension(filename)[1];
+  var extension = util.splitExtension(filename)[1];
   var mimeType = this.mimeTypes_[0];
 
   var showAlert = function() {
@@ -471,7 +471,7 @@
   var entries = this.entries_;
 
   var isDriveOffline = fm.volumeManager.getDriveConnectionState().type ===
-      util.DriveConnectionType.OFFLINE;
+      VolumeManagerCommon.DriveConnectionType.OFFLINE;
 
   if (fm.isOnDrive() && isDriveOffline) {
     fm.metadataCache_.get(entries, 'drive', function(props) {
@@ -497,7 +497,7 @@
   }
 
   var isOnMetered = fm.volumeManager.getDriveConnectionState().type ===
-      util.DriveConnectionType.METERED;
+      VolumeManagerCommon.DriveConnectionType.METERED;
 
   if (fm.isOnDrive() && isOnMetered) {
     fm.metadataCache_.get(entries, 'drive', function(driveProps) {
@@ -687,8 +687,8 @@
     // is writable or not.
     var readonly = fm.isOnReadonlyDirectory();
     var currentDir = fm.getCurrentDirectoryEntry();
-    var downloadsVolume =
-        fm.volumeManager.getCurrentProfileVolumeInfo(RootType.DOWNLOADS);
+    var downloadsVolume = fm.volumeManager.getCurrentProfileVolumeInfo(
+            VolumeManagerCommon.RootType.DOWNLOADS);
     var downloadsDir = downloadsVolume && downloadsVolume.fileSystem.root;
 
     // TODO(mtomasz): Pass Entry instead of localized name. Conversion to a
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
index f39f76b..9614d2b 100644
--- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
@@ -354,7 +354,7 @@
             // TODO(hirono): Make the loop cancellable.
             var requestDriveShare = function(index) {
               if (index >= shareEntries.length)
-                return Promise.cast();
+                return;
               return new Promise(function(fulfill) {
                 chrome.fileBrowserPrivate.requestDriveShare(
                     shareEntries[index].toURL(),
@@ -763,10 +763,8 @@
     if (!volumeInfo)
       return false;
     var isDriveOffline = this.volumeManager_.getDriveConnectionState().type ===
-        util.DriveConnectionType.OFFLINE;
-    if (this.isOnDrive &&
-        isDriveOffline &&
-        !this.allDriveFilesAvailable)
+        VolumeManagerCommon.DriveConnectionType.OFFLINE;
+    if (this.isOnDrive && isDriveOffline && !this.allDriveFilesAvailable)
       return false;
     return true;
   },
@@ -817,14 +815,17 @@
    * @this {FileTransferController}
    */
   onPaste_: function(event) {
+    // If the event has destDirectory property, paste files into the directory.
+    // This occurs when the command fires from menu item 'Paste into folder'.
+    var destination = event.destDirectory || this.currentDirectoryContentEntry;
+
     // Need to update here since 'beforepaste' doesn't fire.
     if (!this.isDocumentWideEvent_() ||
-        !this.canPasteOrDrop_(event.clipboardData,
-                              this.currentDirectoryContentEntry)) {
+        !this.canPasteOrDrop_(event.clipboardData, destination)) {
       return;
     }
     event.preventDefault();
-    var effect = this.paste(event.clipboardData);
+    var effect = this.paste(event.clipboardData, destination);
 
     // On cut, we clear the clipboard after the file is pasted/moved so we don't
     // try to move/delete the original file again.
diff --git a/ui/file_manager/file_manager/foreground/js/file_type.js b/ui/file_manager/file_manager/foreground/js/file_type.js
index 4313d02..6ac91c9 100644
--- a/ui/file_manager/file_manager/foreground/js/file_type.js
+++ b/ui/file_manager/file_manager/foreground/js/file_type.js
@@ -146,7 +146,7 @@
   }
 
   // Unknown file type.
-  var extension = PathUtil.splitExtension(name)[1];
+  var extension = util.splitExtension(name)[1];
   if (extension === '') {
     return { name: 'NO_EXTENSION_FILE_TYPE', type: 'UNKNOWN', icon: '' };
   }
diff --git a/ui/file_manager/file_manager/foreground/js/folder_shortcuts_data_model.js b/ui/file_manager/file_manager/foreground/js/folder_shortcuts_data_model.js
index 7e9a00e..acf55f5 100644
--- a/ui/file_manager/file_manager/foreground/js/folder_shortcuts_data_model.js
+++ b/ui/file_manager/file_manager/foreground/js/folder_shortcuts_data_model.js
@@ -74,7 +74,7 @@
     if (this.lastDriveRootURL_)
       return;
     var volumeInfo = this.volumeManager_.getCurrentProfileVolumeInfo(
-        util.VolumeType.DRIVE);
+        VolumeManagerCommon.VolumeType.DRIVE);
     if (volumeInfo)
       this.lastDriveRootURL_ = volumeInfo.fileSystem.root.toURL();
   },
@@ -96,7 +96,7 @@
 
     this.queue_.run(function(queueCallback) {
       var volumeInfo = this.volumeManager_.getCurrentProfileVolumeInfo(
-          util.VolumeType.DRIVE);
+          VolumeManagerCommon.VolumeType.DRIVE);
       var changed = false;
       var resolvedURLs = {};
       this.rememberLastDriveURL_();  // Required for conversions.
@@ -128,7 +128,7 @@
         // does not exist anymore.
         if (!volumeInfo ||
             this.volumeManager_.getDriveConnectionState().type !==
-                util.DriveConnectionType.ONLINE) {
+                VolumeManagerCommon.DriveConnectionType.ONLINE) {
           if (!this.unresolvablePaths_[path]) {
             changed = true;
             this.unresolvablePaths_[path] = true;
@@ -479,7 +479,7 @@
     // If Drive is online, then delete the shortcut permanently. Otherwise,
     // delete from model and add to |unresolvablePaths_|.
     if (this.volumeManager_.getDriveConnectionState().type !==
-        util.DriveConnectionType.ONLINE) {
+        VolumeManagerCommon.DriveConnectionType.ONLINE) {
       var path = this.convertUrlToStoredPath_(entry.toURL());
       // TODO(mtomasz): Add support for multi-profile.
       this.unresolvablePaths_[path] = true;
diff --git a/ui/file_manager/file_manager/foreground/js/main_scripts.js b/ui/file_manager/file_manager/foreground/js/main_scripts.js
index 2f920f2..e06b761 100644
--- a/ui/file_manager/file_manager/foreground/js/main_scripts.js
+++ b/ui/file_manager/file_manager/foreground/js/main_scripts.js
@@ -70,7 +70,7 @@
 //<include src="../../common/js/error_util.js"/>
 //
 //<include src="../../common/js/async_util.js"/>
-//<include src="../../common/js/path_util.js"/>
+//<include src="../../common/js/volume_manager_common.js"/>
 //<include src="../../common/js/util.js"/>
 //<include src="../../common/js/progress_center_common.js">
 //
diff --git a/ui/file_manager/file_manager/foreground/js/media/mediaplayer_scripts.js b/ui/file_manager/file_manager/foreground/js/media/mediaplayer_scripts.js
index 496a8d0..eee64c9 100644
--- a/ui/file_manager/file_manager/foreground/js/media/mediaplayer_scripts.js
+++ b/ui/file_manager/file_manager/foreground/js/media/mediaplayer_scripts.js
@@ -18,7 +18,7 @@
 
 //<include src="../../../common/js/async_util.js"/>
 //<include src="../../../common/js/util.js"/>
-//<include src="../../../common/js/path_util.js"/>
+//<include src="../../../common/js/volume_manager_common.js"/>
 //<include src="../file_type.js"/>
 //<include src="../volume_manager_wrapper.js">
 //<include src="../metadata/metadata_cache.js"/>
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache.js
index cbe8f4a..33082e8 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache.js
@@ -320,26 +320,16 @@
 
 /**
  * Returns the cached metadata value, or |null| if not present.
- * @param {Entry|Array.<Entry>} entries The list of entries. May be just a
- *     single entry.
+ * @param {Entry} entry Entry.
  * @param {string} type The metadata type.
  * @return {Object} The metadata or null.
  */
-MetadataCache.prototype.getCached = function(entries, type) {
-  var single = false;
-  if (!(entries instanceof Array)) {
-    single = true;
-    entries = [entries];
-  }
-
-  var result = [];
-  for (var index = 0; index < entries.length; index++) {
-    var entryURL = entries[index].toURL();
-    result.push(entryURL in this.cache_ ?
-        (this.cache_[entryURL].properties[type] || null) : null);
-  }
-
-  return single ? result[0] : result;
+MetadataCache.prototype.getCached = function(entry, type) {
+  // Entry.cachedUrl may be set in DirectoryContents.onNewEntries_().
+  // See the comment there for detail.
+  var entryURL = entry.cachedUrl || entry.toURL();
+  var cache = this.cache_[entryURL];
+  return cache ? (cache.properties[type] || null) : null;
 };
 
 /**
diff --git a/ui/file_manager/file_manager/foreground/js/photo/gallery_scripts.js b/ui/file_manager/file_manager/foreground/js/photo/gallery_scripts.js
index f9f2007..41d98d0 100644
--- a/ui/file_manager/file_manager/foreground/js/photo/gallery_scripts.js
+++ b/ui/file_manager/file_manager/foreground/js/photo/gallery_scripts.js
@@ -33,7 +33,7 @@
 
 //<include src="../../../common/js/async_util.js">
 //<include src="../../../common/js/util.js">
-//<include src="../../../common/js/path_util.js">
+//<include src="../../../common/js/volume_manager_common.js">
 //<include src="../file_type.js">
 //<include src="../volume_manager_wrapper.js">
 
diff --git a/ui/file_manager/file_manager/foreground/js/suggest_apps_dialog.js b/ui/file_manager/file_manager/foreground/js/suggest_apps_dialog.js
index e11acba..1195bc8 100644
--- a/ui/file_manager/file_manager/foreground/js/suggest_apps_dialog.js
+++ b/ui/file_manager/file_manager/foreground/js/suggest_apps_dialog.js
@@ -341,12 +341,13 @@
 
 /**
  * Called when the connection status is changed.
- * @param {util.DriveConnectionType} connectionType Current connection type.
+ * @param {VolumeManagerCommon.DriveConnectionType} connectionType Current
+ *     connection type.
  */
 SuggestAppsDialog.prototype.onDriveConnectionChanged =
     function(connectionType) {
   if (this.state_ !== SuggestAppsDialog.State.UNINITIALIZED &&
-      connectionType === util.DriveConnectionType.OFFLINE) {
+      connectionType === VolumeManagerCommon.DriveConnectionType.OFFLINE) {
     this.state_ = SuggestAppsDialog.State.INITIALIZE_FAILED_CLOSING;
     this.hide();
   }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/breadcrumbs_controller.js b/ui/file_manager/file_manager/foreground/js/ui/breadcrumbs_controller.js
index fc3dacf..83173c2 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/breadcrumbs_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/breadcrumbs_controller.js
@@ -61,13 +61,15 @@
     }
 
     if (entryLocationInfo.isRootEntry &&
-        entryLocationInfo.rootType === RootType.DRIVE_OTHER) {
+        entryLocationInfo.rootType ===
+            VolumeManagerCommon.RootType.DRIVE_OTHER) {
       this.metadataCache_.getOne(previousEntry, 'drive', function(result) {
         if (result && result.sharedWithMe) {
           // Adds the shared-with-me entry instead.
           var driveVolumeInfo = entryLocationInfo.volumeInfo;
           var sharedWithMeEntry =
-              driveVolumeInfo.fakeEntries[RootType.DRIVE_SHARED_WITH_ME];
+              driveVolumeInfo.fakeEntries[
+                  VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME];
           if (sharedWithMeEntry)
             entries.unshift(sharedWithMeEntry);
           else
diff --git a/ui/file_manager/file_manager/foreground/js/ui/navigation_list.js b/ui/file_manager/file_manager/foreground/js/ui/navigation_list.js
index 2092fdb..ee42443 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/navigation_list.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/navigation_list.js
@@ -55,7 +55,7 @@
     typeIcon = modelItem.volumeInfo.volumeType;
   } else if (modelItem.isShortcut) {
     // Shortcuts are available for Drive only.
-    typeIcon = util.VolumeType.DRIVE;
+    typeIcon = VolumeManagerCommon.VolumeType.DRIVE;
   }
   this.iconDiv_.setAttribute('volume-type-icon', typeIcon);
 
@@ -67,8 +67,10 @@
   this.label_.textContent = modelItem.label;
 
   if (modelItem.isVolume &&
-      (modelItem.volumeInfo.volumeType === util.VolumeType.ARCHIVE ||
-       modelItem.volumeInfo.volumeType === util.VolumeType.REMOVABLE)) {
+      (modelItem.volumeInfo.volumeType ===
+           VolumeManagerCommon.VolumeType.ARCHIVE ||
+       modelItem.volumeInfo.volumeType ===
+           VolumeManagerCommon.VolumeType.REMOVABLE)) {
     this.eject_ = cr.doc.createElement('div');
     // Block other mouse handlers.
     this.eject_.addEventListener(
@@ -100,9 +102,10 @@
   // The context menu is shown on the following items:
   // - Removable and Archive volumes
   // - Folder shortcuts
-  if (this.modelItem_.isVolume &&
-      (this.modelItem_.volumeInfo.volumeType === util.VolumeType.REMOVABLE ||
-       this.modelItem_.volumeInfo.volumeType === util.VolumeType.ARCHIVE) ||
+  if (this.modelItem_.isVolume && (this.modelItem_.volumeInfo.volumeType ===
+          VolumeManagerCommon.VolumeType.REMOVABLE ||
+      this.modelItem_.volumeInfo.volumeType ===
+          VolumeManagerCommon.VolumeType.ARCHIVE) ||
       this.modelItem_.isShortcut) {
     cr.ui.contextMenuHandler.setContextMenu(this, menu);
   }
diff --git a/ui/file_manager/file_manager/foreground/js/volume_manager_wrapper.js b/ui/file_manager/file_manager/foreground/js/volume_manager_wrapper.js
index a320792..1780db7 100644
--- a/ui/file_manager/file_manager/foreground/js/volume_manager_wrapper.js
+++ b/ui/file_manager/file_manager/foreground/js/volume_manager_wrapper.js
@@ -89,7 +89,8 @@
   for (var i = 0; i < this.volumeManager_.volumeInfoList.length; i++) {
     var volumeInfo = this.volumeManager_.volumeInfoList.item(i);
     // TODO(hidehiko): Filter mounted volumes located on Drive File System.
-    if (!this.driveEnabled_ && volumeInfo.volumeType === util.VolumeType.DRIVE)
+    if (!this.driveEnabled_ && volumeInfo.volumeType ===
+        VolumeManagerCommon.VolumeType.DRIVE)
       continue;
     volumeInfoList.push(volumeInfo);
   }
@@ -137,8 +138,10 @@
     // If the drive is disabled, ignore all drive related events.
     if (event.type === 'drive-connection-changed' ||
         (event.type === 'externally-unmounted' &&
-         event.volumeInfo.volumeType === util.VolumeType.DRIVE))
+         event.volumeInfo.volumeType ===
+             VolumeManagerCommon.VolumeType.DRIVE)) {
       return;
+    }
   }
 
   this.dispatchEvent(event);
@@ -160,20 +163,20 @@
     var index = event.index;
     for (var i = 0; i < event.index; i++) {
       if (this.volumeManager_.volumeInfoList.item(i).volumeType ===
-          util.VolumeType.DRIVE)
+          VolumeManagerCommon.VolumeType.DRIVE)
         index--;
     }
 
     var numRemovedVolumes = 0;
     for (var i = 0; i < event.removed.length; i++) {
-      if (event.removed[i].volumeType !== util.VolumeType.DRIVE)
+      if (event.removed[i].volumeType !== VolumeManagerCommon.VolumeType.DRIVE)
         numRemovedVolumes++;
     }
 
     var addedVolumes = [];
     for (var i = 0; i < event.added.length; i++) {
       var volumeInfo = event.added[i];
-      if (volumeInfo.volumeType !== util.VolumeType.DRIVE)
+      if (volumeInfo.volumeType !== VolumeManagerCommon.VolumeType.DRIVE)
         addedVolumes.push(volumeInfo);
     }
 
@@ -199,13 +202,14 @@
 };
 
 /**
- * @return {util.DriveConnectionType} Current drive connection state.
+ * @return {VolumeManagerCommon.DriveConnectionType} Current drive connection
+ *     state.
  */
 VolumeManagerWrapper.prototype.getDriveConnectionState = function() {
   if (!this.driveEnabled_ || !this.volumeManager_) {
     return {
-      type: util.DriveConnectionType.OFFLINE,
-      reason: util.DriveConnectionReason.NO_SERVICE
+      type: VolumeManagerCommon.DriveConnectionType.OFFLINE,
+      reason: VolumeManagerCommon.DriveConnectionReason.NO_SERVICE
     };
   }
 
@@ -224,7 +228,7 @@
 
 /**
  * Obtains a volume information of the current profile.
- * @param {util.VolumeType} volumeType Volume type.
+ * @param {VolumeManagerCommon.VolumeType} volumeType Volume type.
  * @return {VolumeInfo} Found volume info.
  */
 VolumeManagerWrapper.prototype.getCurrentProfileVolumeInfo =
@@ -242,7 +246,7 @@
     function(callback) {
   this.ensureInitialized(function() {
     var defaultVolume = this.getCurrentProfileVolumeInfo(
-        util.VolumeType.DOWNLOADS);
+        VolumeManagerCommon.VolumeType.DOWNLOADS);
     defaultVolume.resolveDisplayRoot(callback, function() {
       // defaultVolume is DOWNLOADS and resolveDisplayRoot should succeed.
       throw new Error(
@@ -272,8 +276,8 @@
  * @param {string} fileUrl The path to the archive file to be mounted.
  * @param {function(VolumeInfo)} successCallback Called with the VolumeInfo
  *     instance.
- * @param {function(util.VolumeError)} errorCallback Called when an error
- *     occurs.
+ * @param {function(VolumeManagerCommon.VolumeError)} errorCallback Called when
+ *     an error occurs.
  */
 VolumeManagerWrapper.prototype.mountArchive = function(
     fileUrl, successCallback, errorCallback) {
@@ -290,8 +294,8 @@
  * Requests unmount the specified volume.
  * @param {!VolumeInfo} volumeInfo Volume to be unmounted.
  * @param {function()} successCallback Called on success.
- * @param {function(util.VolumeError)} errorCallback Called when an error
- *     occurs.
+ * @param {function(VolumeManagerCommon.VolumeError)} errorCallback Called when
+ *     an error occurs.
  */
 VolumeManagerWrapper.prototype.unmount = function(
     volumeInfo, successCallback, errorCallback) {
@@ -314,6 +318,7 @@
  */
 VolumeManagerWrapper.prototype.filterDisabledDriveVolume_ =
     function(volumeInfo) {
-  var isDrive = volumeInfo && volumeInfo.volumeType === util.VolumeType.DRIVE;
+  var isDrive = volumeInfo && volumeInfo.volumeType ===
+      VolumeManagerCommon.VolumeType.DRIVE;
   return this.driveEnabled_ || !isDrive ? volumeInfo : null;
 };
diff --git a/ui/file_manager/file_manager/gallery.html b/ui/file_manager/file_manager/gallery.html
index a42f9ed..15a9312 100644
--- a/ui/file_manager/file_manager/gallery.html
+++ b/ui/file_manager/file_manager/gallery.html
@@ -43,7 +43,7 @@
 
     <script src="common/js/async_util.js"></script>
     <script src="common/js/util.js"></script>
-    <script src="common/js/path_util.js"></script>
+    <script src="common/js/volume_manager_common.js"></script>
 
     <script src="foreground/js/file_type.js"></script>
     <script src="foreground/js/volume_manager_wrapper.js"></script>
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html
index 2263125..d622ca1 100644
--- a/ui/file_manager/file_manager/main.html
+++ b/ui/file_manager/file_manager/main.html
@@ -83,7 +83,7 @@
       <script src="foreground/js/error_counter.js"></script>
 
       <script src="common/js/async_util.js"></script>
-      <script src="common/js/path_util.js"></script>
+      <script src="common/js/volume_manager_common.js"></script>
       <script src="common/js/util.js"></script>
       <script src="common/js/progress_center_common.js"></script>
 
@@ -147,6 +147,8 @@
                shortcut="U+0043-Ctrl">
       <command id="paste" i18n-values="label:PASTE_BUTTON_LABEL"
                shortcut="U+0056-Ctrl">
+      <command id="paste-into-folder"
+               i18n-values="label:PASTE_INTO_FOLDER_BUTTON_LABEL">
       <command id="rename" i18n-values="label:RENAME_BUTTON_LABEL"
                shortcut="Enter-Ctrl">
       <command id="delete" shortcut="U+007F">
@@ -211,6 +213,7 @@
       <menuitem command="#cut" visibleif="full-page"></menuitem>
       <menuitem command="#copy" visibleif="full-page"></menuitem>
       <menuitem command="#paste" visibleif="full-page"></menuitem>
+      <menuitem command="#paste-into-folder" visibleif="full-page"></menuitem>
       <hr visibleif="full-page">
       <menuitem command="#rename"></menuitem>
       <menuitem command="#delete" i18n-content="DELETE_BUTTON_LABEL"></menuitem>
diff --git a/ui/file_manager/file_manager/manifest.json b/ui/file_manager/file_manager/manifest.json
index 4f774e1..6dbae2c 100644
--- a/ui/file_manager/file_manager/manifest.json
+++ b/ui/file_manager/file_manager/manifest.json
@@ -219,9 +219,9 @@
         "chrome://resources/js/cr/event_target.js",
         "chrome://resources/js/cr/ui/array_data_model.js",
         "common/js/async_util.js",
-        "common/js/path_util.js",
         "common/js/progress_center_common.js",
         "common/js/util.js",
+        "common/js/volume_manager_common.js",
         "background/js/device_handler.js",
         "background/js/drive_sync_handler.js",
         "background/js/file_operation_handler.js",
diff --git a/ui/file_manager/file_manager/mediaplayer.html b/ui/file_manager/file_manager/mediaplayer.html
index 31fa435..3f7e1f3 100644
--- a/ui/file_manager/file_manager/mediaplayer.html
+++ b/ui/file_manager/file_manager/mediaplayer.html
@@ -30,7 +30,7 @@
 
     <script src="common/js/async_util.js"></script>
     <script src="common/js/util.js"></script>
-    <script src="common/js/path_util.js"></script>
+    <script src="common/js/volume_manager_common.js"></script>
 
     <script src="foreground/js/file_type.js"></script>
     <script src="foreground/js/volume_manager_wrapper.js"></script>
diff --git a/ui/file_manager/file_manager_resources.grd b/ui/file_manager/file_manager_resources.grd
index a3bcbf6..ed1fa98 100644
--- a/ui/file_manager/file_manager_resources.grd
+++ b/ui/file_manager/file_manager_resources.grd
@@ -27,12 +27,12 @@
       <include name="IDR_FILE_MANAGER_DRIVE_SYNC_HANDLER_JS" file="file_manager/background/js/drive_sync_handler.js" flattenhtml="false" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_FILE_OPERATION_HANDLER_JS" file="file_manager/background/js/file_operation_handler.js" flattenhtml="false" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_FILE_OPERATION_MANAGER_JS" file="file_manager/background/js/file_operation_manager.js" flattenhtml="false" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_PATH_UTIL_JS" file="file_manager/common/js/path_util.js" flattenhtml="false" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_PROGRESS_CENTER_COMMON_JS" file="file_manager/common/js/progress_center_common.js" flattenhtml="false" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_PROGRESS_CENTER_JS" file="file_manager/background/js/progress_center.js" flattenhtml="false" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_TEST_UTIL_JS" file="file_manager/background/js/test_util.js" flattenhtml="false" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_UTIL_JS" file="file_manager/common/js/util.js" flattenhtml="false" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_VOLUME_MANAGER_JS" file="file_manager/background/js/volume_manager.js" flattenhtml="false" type="BINDATA" />
+      <include name="IDR_FILE_MANAGER_VOLUME_MANAGER_COMMON_JS" file="file_manager/common/js/volume_manager_common.js" flattenhtml="false" type="BINDATA" />
 
       <!-- Scripts required by the metadata parser worker. -->
       <include name="IDR_FILE_MANAGER_UTIL" file="file_manager/common/js/util.js" type="BINDATA" />
diff --git a/ui/file_manager/gallery/gallery.html b/ui/file_manager/gallery/gallery.html
index 9818f11..0f0fb4c 100644
--- a/ui/file_manager/gallery/gallery.html
+++ b/ui/file_manager/gallery/gallery.html
@@ -42,7 +42,7 @@
     <script src="chrome://resources/js/cr/ui/grid.js"></script>
 
     <script src="../file_manager/common/js/async_util.js"></script>
-    <script src="../file_manager/common/js/path_util.js"></script>
+    <script src="../file_manager/common/js/volume_manager_common.js"></script>
 
     <script src="../file_manager/foreground/js/file_type.js"></script>
     <script src="../file_manager/foreground/js/volume_manager_wrapper.js"></script>
diff --git a/ui/file_manager/gallery/js/gallery_scripts.js b/ui/file_manager/gallery/js/gallery_scripts.js
index baf13a9..738964b 100644
--- a/ui/file_manager/gallery/js/gallery_scripts.js
+++ b/ui/file_manager/gallery/js/gallery_scripts.js
@@ -34,7 +34,7 @@
 
 //<include src="../../file_manager/common/js/async_util.js">
 //<include src="../../file_manager/common/js/util.js">
-//<include src="../../file_manager/common/js/path_util.js">
+//<include src="../../file_manager/common/js/volume_manager_common.js">
 //<include src="../../file_manager/foreground/js/file_type.js">
 //<include src="../../file_manager/foreground/js/volume_manager_wrapper.js">
 
diff --git a/ui/file_manager/gallery/manifest.json b/ui/file_manager/gallery/manifest.json
index b8062fa..dd9329e 100644
--- a/ui/file_manager/gallery/manifest.json
+++ b/ui/file_manager/gallery/manifest.json
@@ -51,6 +51,7 @@
         "chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/common/js/util.js",
         "chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/common/js/async_util.js",
         "chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/common/js/path_util.js",
+        "chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/common/js/volume_manager_common.js",
         "chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/background/js/volume_manager.js",
         "chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/background/js/test_util.js",
         "chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/common/js/error_util.js",
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index 1571f3f..9a3463d 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -264,7 +264,7 @@
       "codec/jpeg_codec.h",
     ]
   } else {
-    deps += [ "//third_party/libjpeg" ]
+    deps += [ "//third_party:jpeg" ]
   }
 
   # Android.
@@ -389,6 +389,61 @@
   }
 }
 
+component("gfx_geometry") {
+  sources = [
+    "geometry/box_f.cc",
+    "geometry/box_f.h",
+    "geometry/cubic_bezier.h",
+    "geometry/cubic_bezier.cc",
+    "geometry/insets.cc",
+    "geometry/insets.h",
+    "geometry/insets_base.h",
+    "geometry/insets_f.cc",
+    "geometry/insets_f.h",
+    "geometry/matrix3_f.cc",
+    "geometry/matrix3_f.h",
+    "geometry/point.cc",
+    "geometry/point.h",
+    "geometry/point3_f.cc",
+    "geometry/point3_f.h",
+    "geometry/point_base.h",
+    "geometry/point_conversions.cc",
+    "geometry/point_conversions.h",
+    "geometry/point_f.cc",
+    "geometry/point_f.h",
+    "geometry/quad_f.cc",
+    "geometry/quad_f.h",
+    "geometry/rect.cc",
+    "geometry/rect.h",
+    "geometry/rect_base.h",
+    "geometry/rect_base_impl.h",
+    "geometry/rect_conversions.cc",
+    "geometry/rect_conversions.h",
+    "geometry/rect_f.cc",
+    "geometry/rect_f.h",
+    "geometry/r_tree.cc",
+    "geometry/r_tree.h",
+    "geometry/safe_integer_conversions.h",
+    "geometry/size.cc",
+    "geometry/size.h",
+    "geometry/size_base.h",
+    "geometry/size_conversions.cc",
+    "geometry/size_conversions.h",
+    "geometry/size_f.cc",
+    "geometry/size_f.h",
+    "geometry/vector2d.cc",
+    "geometry/vector2d.h",
+    "geometry/vector2d_conversions.cc",
+    "geometry/vector2d_conversions.h",
+    "geometry/vector2d_f.cc",
+    "geometry/vector2d_f.h",
+    "geometry/vector3d_f.cc",
+    "geometry/vector3d_f.h",
+  ]
+  defines = [ "GFX_IMPLEMENTATION" ]
+  deps = [ "//base" ]
+}
+
 source_set("gfx_test_support") {
   sources = [
     "test/gfx_util.cc",
diff --git a/ui/gfx/android/java_bitmap.cc b/ui/gfx/android/java_bitmap.cc
index 90df12a..1cc6948 100644
--- a/ui/gfx/android/java_bitmap.cc
+++ b/ui/gfx/android/java_bitmap.cc
@@ -12,6 +12,7 @@
 #include "ui/gfx/size.h"
 
 using base::android::AttachCurrentThread;
+using base::android::ConvertUTF8ToJavaString;
 
 namespace gfx {
 
@@ -73,7 +74,7 @@
   DCHECK(name);
   DCHECK(!size.IsEmpty());
   JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jstring> jname(env, env->NewStringUTF(name));
+  ScopedJavaLocalRef<jstring> jname(ConvertUTF8ToJavaString(env, name));
   return Java_BitmapHelper_decodeDrawableResource(
       env, jname.obj(), size.width(), size.height());
 }
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc
index 0b78195..a541c5a 100644
--- a/ui/gfx/canvas.cc
+++ b/ui/gfx/canvas.cc
@@ -377,63 +377,63 @@
                           int dest_h,
                           bool filter,
                           const SkPaint& paint) {
-  DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() &&
-              src_y + src_h < std::numeric_limits<int16_t>::max());
-  if (src_w <= 0 || src_h <= 0) {
-    NOTREACHED() << "Attempting to draw bitmap from an empty rect!";
-    return;
-  }
+  DrawImageIntHelper(image, src_x, src_y, src_w, src_h, dest_x, dest_y, dest_w,
+                     dest_h, filter, paint, image_scale_, false);
+}
 
-  if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h))
-    return;
+void Canvas::DrawImageIntInPixel(const ImageSkia& image,
+                                 int src_x,
+                                 int src_y,
+                                 int src_w,
+                                 int src_h,
+                                 int dest_x,
+                                 int dest_y,
+                                 int dest_w,
+                                 int dest_h,
+                                 bool filter,
+                                 const SkPaint& paint) {
+  // Logic as below:-
+  // 1. Translate the destination rectangle using the current translation
+  //    values from the SkCanvas matrix stack.
+  // 2. Save the current state of the canvas.
+  // 3. Reset the scales and the translation values in the SkCanvas matrix
+  //    stack top.
+  // 4. Set the scale in gfx::Canvas instance to 1.0, 1.0.
+  // 5. Draw the image.
+  // 6. Restore the state of the canvas and the SkCanvas matrix stack.
+  SkMatrix matrix = canvas_->getTotalMatrix();
 
-  float user_scale_x = static_cast<float>(dest_w) / src_w;
-  float user_scale_y = static_cast<float>(dest_h) / src_h;
-
-  const ImageSkiaRep& image_rep = GetImageRepToPaint(image,
-      user_scale_x, user_scale_y);
-  if (image_rep.is_null())
-    return;
-
-  SkRect dest_rect = { SkIntToScalar(dest_x),
+  SkRect destination_rect;
+  destination_rect.set(SkIntToScalar(dest_x),
                        SkIntToScalar(dest_y),
                        SkIntToScalar(dest_x + dest_w),
-                       SkIntToScalar(dest_y + dest_h) };
+                       SkIntToScalar(dest_y + dest_h));
+  matrix.setScaleX(1.0f);
+  matrix.setScaleY(1.0f);
+  matrix.mapRect(&destination_rect, destination_rect);
 
-  if (src_w == dest_w && src_h == dest_h &&
-      user_scale_x == 1.0f && user_scale_y == 1.0f &&
-      image_rep.scale() == 1.0f) {
-    // Workaround for apparent bug in Skia that causes image to occasionally
-    // shift.
-    SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h };
-    const SkBitmap& bitmap = image_rep.sk_bitmap();
-    canvas_->drawBitmapRect(bitmap, &src_rect, dest_rect, &paint);
-    return;
-  }
+  Save();
 
-  // Make a bitmap shader that contains the bitmap we want to draw. This is
-  // basically what SkCanvas.drawBitmap does internally, but it gives us
-  // more control over quality and will use the mipmap in the source image if
-  // it has one, whereas drawBitmap won't.
-  SkMatrix shader_scale;
-  shader_scale.setScale(SkFloatToScalar(user_scale_x),
-                        SkFloatToScalar(user_scale_y));
-  shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y));
-  shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y));
+  // The destination is now in pixel values. No need for further translation.
+  matrix.setTranslate(0, 0);
+  canvas_->setMatrix(matrix);
 
-  skia::RefPtr<SkShader> shader = CreateImageRepShader(
-      image_rep,
-      SkShader::kRepeat_TileMode,
-      shader_scale);
+  DrawImageIntHelper(image,
+                     src_x,
+                     src_y,
+                     src_w,
+                     src_h,
+                     SkScalarRoundToInt(destination_rect.x()),
+                     SkScalarRoundToInt(destination_rect.y()),
+                     SkScalarRoundToInt(destination_rect.width()),
+                     SkScalarRoundToInt(destination_rect.height()),
+                     filter,
+                     paint,
+                     image_scale_,
+                     true);
 
-  // Set up our paint to use the shader & release our reference (now just owned
-  // by the paint).
-  SkPaint p(paint);
-  p.setFilterBitmap(filter);
-  p.setShader(shader.get());
-
-  // The rect will be filled by the bitmap.
-  canvas_->drawRect(dest_rect, p);
+  // Restore the state of the canvas.
+  Restore();
 }
 
 void Canvas::DrawImageInPath(const ImageSkia& image,
@@ -505,7 +505,7 @@
     return;
 
   const ImageSkiaRep& image_rep = GetImageRepToPaint(
-      image, tile_scale_x, tile_scale_y);
+      image, image_scale_, tile_scale_x, tile_scale_y);
   if (image_rep.is_null())
     return;
 
@@ -563,14 +563,15 @@
 }
 
 const ImageSkiaRep& Canvas::GetImageRepToPaint(const ImageSkia& image) const {
-  return GetImageRepToPaint(image, 1.0f, 1.0f);
+  return GetImageRepToPaint(image, image_scale_, 1.0f, 1.0f);
 }
 
 const ImageSkiaRep& Canvas::GetImageRepToPaint(
     const ImageSkia& image,
+    float image_scale,
     float user_additional_scale_x,
     float user_additional_scale_y) const {
-  const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale_);
+  const ImageSkiaRep& image_rep = image.GetRepresentation(image_scale);
 
   if (!image_rep.is_null()) {
     SkMatrix m = canvas_->getTotalMatrix();
@@ -587,4 +588,77 @@
   return image_rep;
 }
 
+void Canvas::DrawImageIntHelper(const ImageSkia& image,
+                                int src_x,
+                                int src_y,
+                                int src_w,
+                                int src_h,
+                                int dest_x,
+                                int dest_y,
+                                int dest_w,
+                                int dest_h,
+                                bool filter,
+                                const SkPaint& paint,
+                                float image_scale,
+                                bool pixel) {
+  DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() &&
+              src_y + src_h < std::numeric_limits<int16_t>::max());
+  if (src_w <= 0 || src_h <= 0) {
+    NOTREACHED() << "Attempting to draw bitmap from an empty rect!";
+    return;
+  }
+
+  if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h))
+    return;
+
+  float user_scale_x = static_cast<float>(dest_w) / src_w;
+  float user_scale_y = static_cast<float>(dest_h) / src_h;
+
+  const ImageSkiaRep& image_rep = GetImageRepToPaint(image,
+      image_scale, user_scale_x, user_scale_y);
+  if (image_rep.is_null())
+    return;
+
+  SkRect dest_rect = { SkIntToScalar(dest_x),
+                       SkIntToScalar(dest_y),
+                       SkIntToScalar(dest_x + dest_w),
+                       SkIntToScalar(dest_y + dest_h) };
+
+  if (src_w == dest_w && src_h == dest_h &&
+      user_scale_x == 1.0f && user_scale_y == 1.0f &&
+      image_rep.scale() == 1.0f && !pixel) {
+    // Workaround for apparent bug in Skia that causes image to occasionally
+    // shift.
+    SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h };
+    const SkBitmap& bitmap = image_rep.sk_bitmap();
+    canvas_->drawBitmapRect(bitmap, &src_rect, dest_rect, &paint);
+    return;
+  }
+
+  // Make a bitmap shader that contains the bitmap we want to draw. This is
+  // basically what SkCanvas.drawBitmap does internally, but it gives us
+  // more control over quality and will use the mipmap in the source image if
+  // it has one, whereas drawBitmap won't.
+  SkMatrix shader_scale;
+  shader_scale.setScale(SkFloatToScalar(user_scale_x),
+                        SkFloatToScalar(user_scale_y));
+  shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y));
+  shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y));
+
+  skia::RefPtr<SkShader> shader = CreateImageRepShaderForScale(
+      image_rep,
+      SkShader::kRepeat_TileMode,
+      shader_scale,
+      pixel ? 1.0f : image_scale);
+
+  // Set up our paint to use the shader & release our reference (now just owned
+  // by the paint).
+  SkPaint p(paint);
+  p.setFilterBitmap(filter);
+  p.setShader(shader.get());
+
+  // The rect will be filled by the bitmap.
+  canvas_->drawRect(dest_rect, p);
+}
+
 }  // namespace gfx
diff --git a/ui/gfx/canvas.h b/ui/gfx/canvas.h
index b3be76a..93171d5 100644
--- a/ui/gfx/canvas.h
+++ b/ui/gfx/canvas.h
@@ -320,6 +320,22 @@
                     bool filter,
                     const SkPaint& paint);
 
+  // Same as the DrawImageInt functions above. Difference being this does not
+  // do any scaling, i.e. it assumes that the source/destination/image, etc are
+  // in pixels. It does translate the destination rectangle to ensure that the
+  // image is displayed at the correct pixel coordinates.
+  void DrawImageIntInPixel(const ImageSkia& image,
+                           int src_x,
+                           int src_y,
+                           int src_w,
+                           int src_h,
+                           int dest_x,
+                           int dest_y,
+                           int dest_w,
+                           int dest_h,
+                           bool filter,
+                           const SkPaint& paint);
+
   // Draws an |image| with the top left corner at |x| and |y|, clipped to
   // |path|.
   // Parameters are specified relative to current canvas scale not in pixels.
@@ -435,9 +451,27 @@
   const ImageSkiaRep& GetImageRepToPaint(const ImageSkia& image) const;
   const ImageSkiaRep& GetImageRepToPaint(
       const ImageSkia& image,
+      float image_scale,
       float user_defined_scale_factor_x,
       float user_defined_scale_factor_y) const;
 
+  // Helper for the DrawImageInt functions declared above. The |pixel|
+  // parameter if true indicates that the bounds and the image are to
+  // be assumed to be in pixels, i.e. no scaling needs to be performed.
+  void DrawImageIntHelper(const ImageSkia& image,
+                          int src_x,
+                          int src_y,
+                          int src_w,
+                          int src_h,
+                          int dest_x,
+                          int dest_y,
+                          int dest_w,
+                          int dest_h,
+                          bool filter,
+                          const SkPaint& paint,
+                          float image_scale,
+                          bool pixel);
+
   // The device scale factor at which drawing on this canvas occurs.
   // An additional scale can be applied via Canvas::Scale(). However,
   // Canvas::Scale() does not affect |image_scale_|.
diff --git a/ui/gfx/geometry/r_tree.cc b/ui/gfx/geometry/r_tree.cc
index e62e546..00e75eb 100644
--- a/ui/gfx/geometry/r_tree.cc
+++ b/ui/gfx/geometry/r_tree.cc
@@ -627,8 +627,7 @@
   // Lastly check the root. If it has only one non-leaf child, delete it and
   // replace it with its child.
   if (root_->count() == 1 && root_->level() > 0) {
-    scoped_ptr<Node> new_root(root_->RemoveAndReturnLastChild());
-    root_.swap(new_root);
+    root_ = root_->RemoveAndReturnLastChild();
   }
 }
 
@@ -716,10 +715,14 @@
   // Traverse up the tree, removing the child from each parent and deleting
   // parent nodes, until we either encounter the root of the tree or a parent
   // that still has sufficient children.
-  while (parent && parent->RemoveChild(child, &orphans) < min_children_) {
-    if (child != node) {
+  while (parent) {
+    size_t children_remaining = parent->RemoveChild(child, &orphans);
+    if (child != node)
       delete child;
-    }
+
+    if (children_remaining >= min_children_)
+      break;
+
     child = parent;
     parent = parent->parent();
   }
diff --git a/ui/gfx/gfx.gyp b/ui/gfx/gfx.gyp
index 338b8a3..f46a0c1 100644
--- a/ui/gfx/gfx.gyp
+++ b/ui/gfx/gfx.gyp
@@ -449,12 +449,28 @@
     {
       'target_name': 'gfx_unittests',
       'type': '<(gtest_target_type)',
-      'sources': [
+      # iOS uses a small subset of ui. common_sources are the only files that
+      # are built on iOS.
+      'common_sources' : [
+        'image/image_family_unittest.cc',
+        'image/image_unittest.cc',
+        'image/image_unittest_util.cc',
+        'image/image_unittest_util.h',
+        'image/image_unittest_util_ios.mm',
+        'image/image_unittest_util_mac.mm',
+      ],
+      'all_sources': [
+        '<@(_common_sources)',
         'animation/animation_container_unittest.cc',
         'animation/animation_unittest.cc',
         'animation/multi_animation_unittest.cc',
         'animation/slide_animation_unittest.cc',
+        'animation/tween_unittest.cc',
+        'blit_unittest.cc',
+        'break_list_unittest.cc',
+        'codec/jpeg_codec_unittest.cc',
         'codec/png_codec_unittest.cc',
+        'color_analysis_unittest.cc',
         'color_utils_unittest.cc',
         'display_unittest.cc',
         'geometry/box_unittest.cc',
@@ -464,18 +480,23 @@
         'geometry/point_unittest.cc',
         'geometry/point3_unittest.cc',
         'geometry/quad_unittest.cc',
-        'geometry/rect_unittest.cc',
         'geometry/r_tree_unittest.cc',
+        'geometry/rect_unittest.cc',
         'geometry/safe_integer_conversions_unittest.cc',
         'geometry/size_unittest.cc',
         'geometry/vector2d_unittest.cc',
         'geometry/vector3d_unittest.cc',
+        'image/image_mac_unittest.mm',
+        'image/image_util_unittest.cc',
         'range/range_mac_unittest.mm',
         'range/range_unittest.cc',
         'range/range_win_unittest.cc',
+        'sequential_id_generator_unittest.cc',
         'shadow_value_unittest.cc',
         'skbitmap_operations_unittest.cc',
         'skrect_conversion_unittest.cc',
+        'transform_util_unittest.cc',
+        'utf16_indexing_unittest.cc',
       ],
       'dependencies': [
         '../../base/base.gyp:base',
@@ -486,8 +507,14 @@
         '../../third_party/libpng/libpng.gyp:libpng',
         'gfx',
         'gfx_geometry',
+        'gfx_test_support',
       ],
       'conditions': [
+        ['OS == "ios"', {
+          'sources': ['<@(_common_sources)'],
+        }, {  # OS != "ios"
+          'sources': ['<@(_all_sources)'],
+        }],
         ['OS == "win"', {
           # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
           'msvs_disabled_warnings': [ 4267, ],
diff --git a/ui/gfx/gfx.target.darwin-arm.mk b/ui/gfx/gfx.target.darwin-arm.mk
index c0856af..61b6773 100644
--- a/ui/gfx/gfx.target.darwin-arm.mk
+++ b/ui/gfx/gfx.target.darwin-arm.mk
@@ -102,7 +102,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -151,11 +150,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -234,7 +228,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -283,11 +276,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gfx/gfx.target.darwin-arm64.mk b/ui/gfx/gfx.target.darwin-arm64.mk
index c839065..d8f5bd9 100644
--- a/ui/gfx/gfx.target.darwin-arm64.mk
+++ b/ui/gfx/gfx.target.darwin-arm64.mk
@@ -147,11 +147,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -274,11 +269,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gfx/gfx.target.darwin-mips.mk b/ui/gfx/gfx.target.darwin-mips.mk
index 6b4891d..2e2b29d 100644
--- a/ui/gfx/gfx.target.darwin-mips.mk
+++ b/ui/gfx/gfx.target.darwin-mips.mk
@@ -150,11 +150,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -281,11 +276,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gfx/gfx.target.darwin-x86.mk b/ui/gfx/gfx.target.darwin-x86.mk
index 16c6974..7997bdb 100644
--- a/ui/gfx/gfx.target.darwin-x86.mk
+++ b/ui/gfx/gfx.target.darwin-x86.mk
@@ -104,7 +104,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -152,11 +151,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -236,7 +230,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -284,11 +277,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gfx/gfx.target.darwin-x86_64.mk b/ui/gfx/gfx.target.darwin-x86_64.mk
index c6da4b3..19119d3 100644
--- a/ui/gfx/gfx.target.darwin-x86_64.mk
+++ b/ui/gfx/gfx.target.darwin-x86_64.mk
@@ -104,7 +104,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -152,11 +151,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -236,7 +230,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -284,11 +277,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gfx/gfx.target.linux-arm.mk b/ui/gfx/gfx.target.linux-arm.mk
index c0856af..61b6773 100644
--- a/ui/gfx/gfx.target.linux-arm.mk
+++ b/ui/gfx/gfx.target.linux-arm.mk
@@ -102,7 +102,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -151,11 +150,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -234,7 +228,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -283,11 +276,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gfx/gfx.target.linux-arm64.mk b/ui/gfx/gfx.target.linux-arm64.mk
index c839065..d8f5bd9 100644
--- a/ui/gfx/gfx.target.linux-arm64.mk
+++ b/ui/gfx/gfx.target.linux-arm64.mk
@@ -147,11 +147,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -274,11 +269,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gfx/gfx.target.linux-mips.mk b/ui/gfx/gfx.target.linux-mips.mk
index 6b4891d..2e2b29d 100644
--- a/ui/gfx/gfx.target.linux-mips.mk
+++ b/ui/gfx/gfx.target.linux-mips.mk
@@ -150,11 +150,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -281,11 +276,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gfx/gfx.target.linux-x86.mk b/ui/gfx/gfx.target.linux-x86.mk
index 16c6974..7997bdb 100644
--- a/ui/gfx/gfx.target.linux-x86.mk
+++ b/ui/gfx/gfx.target.linux-x86.mk
@@ -104,7 +104,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -152,11 +151,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -236,7 +230,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -284,11 +277,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gfx/gfx.target.linux-x86_64.mk b/ui/gfx/gfx.target.linux-x86_64.mk
index c6da4b3..19119d3 100644
--- a/ui/gfx/gfx.target.linux-x86_64.mk
+++ b/ui/gfx/gfx.target.linux-x86_64.mk
@@ -104,7 +104,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -152,11 +151,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -236,7 +230,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -284,11 +277,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gfx/gfx_geometry.target.darwin-arm.mk b/ui/gfx/gfx_geometry.target.darwin-arm.mk
index f0ba328..0b5fdfa 100644
--- a/ui/gfx/gfx_geometry.target.darwin-arm.mk
+++ b/ui/gfx/gfx_geometry.target.darwin-arm.mk
@@ -61,7 +61,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -148,7 +147,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/gfx/gfx_geometry.target.darwin-x86.mk b/ui/gfx/gfx_geometry.target.darwin-x86.mk
index d5b6c04..0b4cc72 100644
--- a/ui/gfx/gfx_geometry.target.darwin-x86.mk
+++ b/ui/gfx/gfx_geometry.target.darwin-x86.mk
@@ -63,7 +63,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +149,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gfx/gfx_geometry.target.darwin-x86_64.mk b/ui/gfx/gfx_geometry.target.darwin-x86_64.mk
index 9e065e9..835149c 100644
--- a/ui/gfx/gfx_geometry.target.darwin-x86_64.mk
+++ b/ui/gfx/gfx_geometry.target.darwin-x86_64.mk
@@ -63,7 +63,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +149,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gfx/gfx_geometry.target.linux-arm.mk b/ui/gfx/gfx_geometry.target.linux-arm.mk
index f0ba328..0b5fdfa 100644
--- a/ui/gfx/gfx_geometry.target.linux-arm.mk
+++ b/ui/gfx/gfx_geometry.target.linux-arm.mk
@@ -61,7 +61,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -148,7 +147,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/gfx/gfx_geometry.target.linux-x86.mk b/ui/gfx/gfx_geometry.target.linux-x86.mk
index d5b6c04..0b4cc72 100644
--- a/ui/gfx/gfx_geometry.target.linux-x86.mk
+++ b/ui/gfx/gfx_geometry.target.linux-x86.mk
@@ -63,7 +63,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +149,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gfx/gfx_geometry.target.linux-x86_64.mk b/ui/gfx/gfx_geometry.target.linux-x86_64.mk
index 9e065e9..835149c 100644
--- a/ui/gfx/gfx_geometry.target.linux-x86_64.mk
+++ b/ui/gfx/gfx_geometry.target.linux-x86_64.mk
@@ -63,7 +63,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -150,7 +149,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gfx/gfx_jni_headers.target.darwin-arm.mk b/ui/gfx/gfx_jni_headers.target.darwin-arm.mk
index b62cff6..87e2124 100644
--- a/ui/gfx/gfx_jni_headers.target.darwin-arm.mk
+++ b/ui/gfx/gfx_jni_headers.target.darwin-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_gfx_gfx_gyp_gfx_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gfx/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gfx/BitmapHelper.java', '../android/java/src/org/chromium/ui/gfx/DeviceDisplayInfo.java', '../android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gfx/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,7 +77,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -158,7 +160,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/gfx/gfx_jni_headers.target.darwin-arm64.mk b/ui/gfx/gfx_jni_headers.target.darwin-arm64.mk
index ddce5fb..d67c98d 100644
--- a/ui/gfx/gfx_jni_headers.target.darwin-arm64.mk
+++ b/ui/gfx/gfx_jni_headers.target.darwin-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_gfx_gfx_gyp_gfx_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gfx/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gfx/BitmapHelper.java', '../android/java/src/org/chromium/ui/gfx/DeviceDisplayInfo.java', '../android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gfx/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gfx/gfx_jni_headers.target.darwin-mips.mk b/ui/gfx/gfx_jni_headers.target.darwin-mips.mk
index a277945..80d1f07 100644
--- a/ui/gfx/gfx_jni_headers.target.darwin-mips.mk
+++ b/ui/gfx/gfx_jni_headers.target.darwin-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_gfx_gfx_gyp_gfx_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gfx/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gfx/BitmapHelper.java', '../android/java/src/org/chromium/ui/gfx/DeviceDisplayInfo.java', '../android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gfx/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gfx/gfx_jni_headers.target.darwin-x86.mk b/ui/gfx/gfx_jni_headers.target.darwin-x86.mk
index 7f0331e..abbf85f 100644
--- a/ui/gfx/gfx_jni_headers.target.darwin-x86.mk
+++ b/ui/gfx/gfx_jni_headers.target.darwin-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_gfx_gfx_gyp_gfx_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gfx/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gfx/BitmapHelper.java', '../android/java/src/org/chromium/ui/gfx/DeviceDisplayInfo.java', '../android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gfx/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,7 +79,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -160,7 +162,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gfx/gfx_jni_headers.target.darwin-x86_64.mk b/ui/gfx/gfx_jni_headers.target.darwin-x86_64.mk
index 3964812..02f831f 100644
--- a/ui/gfx/gfx_jni_headers.target.darwin-x86_64.mk
+++ b/ui/gfx/gfx_jni_headers.target.darwin-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_gfx_gfx_gyp_gfx_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gfx/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gfx/BitmapHelper.java', '../android/java/src/org/chromium/ui/gfx/DeviceDisplayInfo.java', '../android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gfx/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,7 +79,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -160,7 +162,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gfx/gfx_jni_headers.target.linux-arm.mk b/ui/gfx/gfx_jni_headers.target.linux-arm.mk
index b62cff6..87e2124 100644
--- a/ui/gfx/gfx_jni_headers.target.linux-arm.mk
+++ b/ui/gfx/gfx_jni_headers.target.linux-arm.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_gfx_gfx_gyp_gfx_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gfx/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gfx/BitmapHelper.java', '../android/java/src/org/chromium/ui/gfx/DeviceDisplayInfo.java', '../android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gfx/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -74,7 +77,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -158,7 +160,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/gfx/gfx_jni_headers.target.linux-arm64.mk b/ui/gfx/gfx_jni_headers.target.linux-arm64.mk
index ddce5fb..d67c98d 100644
--- a/ui/gfx/gfx_jni_headers.target.linux-arm64.mk
+++ b/ui/gfx/gfx_jni_headers.target.linux-arm64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_gfx_gfx_gyp_gfx_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gfx/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gfx/BitmapHelper.java', '../android/java/src/org/chromium/ui/gfx/DeviceDisplayInfo.java', '../android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gfx/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gfx/gfx_jni_headers.target.linux-mips.mk b/ui/gfx/gfx_jni_headers.target.linux-mips.mk
index a277945..80d1f07 100644
--- a/ui/gfx/gfx_jni_headers.target.linux-mips.mk
+++ b/ui/gfx/gfx_jni_headers.target.linux-mips.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_gfx_gfx_gyp_gfx_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gfx/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gfx/BitmapHelper.java', '../android/java/src/org/chromium/ui/gfx/DeviceDisplayInfo.java', '../android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gfx/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gfx/gfx_jni_headers.target.linux-x86.mk b/ui/gfx/gfx_jni_headers.target.linux-x86.mk
index 7f0331e..abbf85f 100644
--- a/ui/gfx/gfx_jni_headers.target.linux-x86.mk
+++ b/ui/gfx/gfx_jni_headers.target.linux-x86.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_gfx_gfx_gyp_gfx_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gfx/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gfx/BitmapHelper.java', '../android/java/src/org/chromium/ui/gfx/DeviceDisplayInfo.java', '../android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gfx/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,7 +79,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -160,7 +162,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gfx/gfx_jni_headers.target.linux-x86_64.mk b/ui/gfx/gfx_jni_headers.target.linux-x86_64.mk
index 3964812..02f831f 100644
--- a/ui/gfx/gfx_jni_headers.target.linux-x86_64.mk
+++ b/ui/gfx/gfx_jni_headers.target.linux-x86_64.mk
@@ -18,6 +18,7 @@
 ### Generated for rule "ui_gfx_gfx_gyp_gfx_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gfx/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gfx/BitmapHelper.java', '../android/java/src/org/chromium/ui/gfx/DeviceDisplayInfo.java', '../android/java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gfx/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/BitmapHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -26,6 +27,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/DeviceDisplayInfo_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -34,6 +36,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gfx/jni/ViewConfigurationHelper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -76,7 +79,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -160,7 +162,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gfx/gpu_memory_buffer.h b/ui/gfx/gpu_memory_buffer.h
index de50943..d09dd10 100644
--- a/ui/gfx/gpu_memory_buffer.h
+++ b/ui/gfx/gpu_memory_buffer.h
@@ -65,17 +65,14 @@
 // regular CPU code, but can also be read by the GPU.
 class GFX_EXPORT GpuMemoryBuffer {
  public:
-  enum AccessMode { READ_ONLY, WRITE_ONLY, READ_WRITE };
-
   GpuMemoryBuffer();
   virtual ~GpuMemoryBuffer();
 
   // Maps the buffer into the client's address space so it can be written to by
   // the CPU. This call may block, for instance if the GPU needs to finish
-  // accessing the buffer or if CPU caches need to be synchronized. |mode|
-  // indicate how the client intends to use the mapped buffer. Returns NULL on
-  // failure.
-  virtual void* Map(AccessMode mode) = 0;
+  // accessing the buffer or if CPU caches need to be synchronized. Returns NULL
+  // on failure.
+  virtual void* Map() = 0;
 
   // Unmaps the buffer. It's illegal to use the pointer returned by Map() after
   // this has been called.
diff --git a/ui/gfx/nine_image_painter.cc b/ui/gfx/nine_image_painter.cc
index 92a38f7..bb80b2e 100644
--- a/ui/gfx/nine_image_painter.cc
+++ b/ui/gfx/nine_image_painter.cc
@@ -8,6 +8,8 @@
 
 #include "third_party/skia/include/core/SkPaint.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/safe_integer_conversions.h"
 #include "ui/gfx/image/image_skia_operations.h"
 #include "ui/gfx/insets.h"
 #include "ui/gfx/rect.h"
@@ -17,6 +19,16 @@
 
 namespace {
 
+// The following functions width and height of the image in pixels for the
+// scale factor in the Canvas.
+int ImageWidthInPixels(const ImageSkia& i, Canvas* c) {
+  return i.GetRepresentation(c->image_scale()).pixel_width();
+}
+
+int ImageHeightInPixels(const ImageSkia& i, Canvas* c) {
+  return i.GetRepresentation(c->image_scale()).pixel_height();
+}
+
 // Stretches the given image over the specified canvas area.
 void Fill(Canvas* c,
           const ImageSkia& i,
@@ -25,7 +37,8 @@
           int w,
           int h,
           const SkPaint& paint) {
-  c->DrawImageInt(i, 0, 0, i.width(), i.height(), x, y, w, h, false, paint);
+  c->DrawImageIntInPixel(i, 0, 0, ImageWidthInPixels(i, c),
+                         ImageHeightInPixels(i, c), x, y, w, h, false, paint);
 }
 
 }  // namespace
@@ -85,38 +98,51 @@
   SkPaint paint;
   paint.setAlpha(alpha);
 
+  // Scale the bounds and convert to the smallest enclosing rectangle after
+  // scaling. This is to ensure that we paint all pixels correctly.
+  Rect scaled_enclosing_rect =
+      ToEnclosingRect(RectF(ScalePoint(bounds.origin(), canvas->image_scale()),
+                            ScaleSize(bounds.size(), canvas->image_scale())));
+
   // In case the corners and edges don't all have the same width/height, we draw
   // the center first, and extend it out in all directions to the edges of the
   // images with the smallest widths/heights.  This way there will be no
   // unpainted areas, though some corners or edges might overlap the center.
-  int w = bounds.width();
-  int i0w = images_[0].width();
-  int i2w = images_[2].width();
-  int i3w = images_[3].width();
-  int i5w = images_[5].width();
-  int i6w = images_[6].width();
-  int i8w = images_[8].width();
+  int w = scaled_enclosing_rect.width();
+  int i0w = ImageWidthInPixels(images_[0], canvas);
+  int i2w = ImageWidthInPixels(images_[2], canvas);
+  int i3w = ImageWidthInPixels(images_[3], canvas);
+  int i5w = ImageWidthInPixels(images_[5], canvas);
+  int i6w = ImageWidthInPixels(images_[6], canvas);
+  int i8w = ImageWidthInPixels(images_[8], canvas);
+
   int i4x = std::min(std::min(i0w, i3w), i6w);
   int i4w = w - i4x - std::min(std::min(i2w, i5w), i8w);
-  int h = bounds.height();
-  int i0h = images_[0].height();
-  int i1h = images_[1].height();
-  int i2h = images_[2].height();
-  int i6h = images_[6].height();
-  int i7h = images_[7].height();
-  int i8h = images_[8].height();
+  int h = scaled_enclosing_rect.height();
+
+  int i0h = ImageHeightInPixels(images_[0], canvas);
+  int i1h = ImageHeightInPixels(images_[1], canvas);
+  int i2h = ImageHeightInPixels(images_[2], canvas);
+  int i6h = ImageHeightInPixels(images_[6], canvas);
+  int i7h = ImageHeightInPixels(images_[7], canvas);
+  int i8h = ImageHeightInPixels(images_[8], canvas);
+
   int i4y = std::min(std::min(i0h, i1h), i2h);
   int i4h = h - i4y - std::min(std::min(i6h, i7h), i8h);
   if (!images_[4].isNull())
     Fill(canvas, images_[4], i4x, i4y, i4w, i4h, paint);
-  canvas->DrawImageInt(images_[0], 0, 0, paint);
+  canvas->DrawImageIntInPixel(images_[0], 0, 0, i0w, i0h,
+                              0, 0, i0w, i0h, false, paint);
   Fill(canvas, images_[1], i0w, 0, w - i0w - i2w, i1h, paint);
-  canvas->DrawImageInt(images_[2], w - i2w, 0, paint);
+  canvas->DrawImageIntInPixel(images_[2], 0, 0, i2w, i2h, w - i2w, 0,
+                              i2w, i2h, false, paint);
   Fill(canvas, images_[3], 0, i0h, i3w, h - i0h - i6h, paint);
   Fill(canvas, images_[5], w - i5w, i2h, i5w, h - i2h - i8h, paint);
-  canvas->DrawImageInt(images_[6], 0, h - i6h, paint);
+  canvas->DrawImageIntInPixel(images_[6], 0, 0, i6w, i6h, 0, h - i6h,
+                              i6w, i6h, false, paint);
   Fill(canvas, images_[7], i6w, h - i7h, w - i6w - i8w, i7h, paint);
-  canvas->DrawImageInt(images_[8], w - i8w, h - i8h, paint);
+  canvas->DrawImageIntInPixel(images_[8], 0, 0, i8w, i8h, w - i8w, h - i8h,
+                              i8w, i8h, false, paint);
 }
 
 }  // namespace gfx
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index 6455738..4d16d9a 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -501,26 +501,28 @@
 void RenderText::MoveCursor(BreakType break_type,
                             VisualCursorDirection direction,
                             bool select) {
-  SelectionModel position(cursor_position(), selection_model_.caret_affinity());
+  SelectionModel cursor(cursor_position(), selection_model_.caret_affinity());
   // Cancelling a selection moves to the edge of the selection.
   if (break_type != LINE_BREAK && !selection().is_empty() && !select) {
     SelectionModel selection_start = GetSelectionModelForSelectionStart();
     int start_x = GetCursorBounds(selection_start, true).x();
-    int cursor_x = GetCursorBounds(position, true).x();
+    int cursor_x = GetCursorBounds(cursor, true).x();
     // Use the selection start if it is left (when |direction| is CURSOR_LEFT)
     // or right (when |direction| is CURSOR_RIGHT) of the selection end.
     if (direction == CURSOR_RIGHT ? start_x > cursor_x : start_x < cursor_x)
-      position = selection_start;
-    // For word breaks, use the nearest word boundary in the appropriate
-    // |direction|.
+      cursor = selection_start;
+    // Use the nearest word boundary in the proper |direction| for word breaks.
     if (break_type == WORD_BREAK)
-      position = GetAdjacentSelectionModel(position, break_type, direction);
+      cursor = GetAdjacentSelectionModel(cursor, break_type, direction);
+    // Use an adjacent selection model if the cursor is not at a valid position.
+    if (!IsValidCursorIndex(cursor.caret_pos()))
+      cursor = GetAdjacentSelectionModel(cursor, CHARACTER_BREAK, direction);
   } else {
-    position = GetAdjacentSelectionModel(position, break_type, direction);
+    cursor = GetAdjacentSelectionModel(cursor, break_type, direction);
   }
   if (select)
-    position.set_selection_start(selection().start());
-  MoveCursorTo(position);
+    cursor.set_selection_start(selection().start());
+  MoveCursorTo(cursor);
 }
 
 bool RenderText::MoveCursorTo(const SelectionModel& model) {
@@ -528,9 +530,8 @@
   size_t text_length = text().length();
   Range range(std::min(model.selection().start(), text_length),
               std::min(model.caret_pos(), text_length));
-  // The current model only supports caret positions at valid character indices.
-  if (!IsCursorablePosition(range.start()) ||
-      !IsCursorablePosition(range.end()))
+  // The current model only supports caret positions at valid cursor indices.
+  if (!IsValidCursorIndex(range.start()) || !IsValidCursorIndex(range.end()))
     return false;
   SelectionModel sel(range, model.caret_affinity());
   bool changed = sel != selection_model_;
@@ -538,17 +539,11 @@
   return changed;
 }
 
-bool RenderText::MoveCursorTo(const Point& point, bool select) {
-  SelectionModel position = FindCursorPosition(point);
-  if (select)
-    position.set_selection_start(selection().start());
-  return MoveCursorTo(position);
-}
-
 bool RenderText::SelectRange(const Range& range) {
   Range sel(std::min(range.start(), text().length()),
             std::min(range.end(), text().length()));
-  if (!IsCursorablePosition(sel.start()) || !IsCursorablePosition(sel.end()))
+  // Allow selection bounds at valid indicies amid multi-character graphemes.
+  if (!IsValidLogicalIndex(sel.start()) || !IsValidLogicalIndex(sel.end()))
     return false;
   LogicalCursorDirection affinity =
       (sel.is_reversed() || sel.is_empty()) ? CURSOR_FORWARD : CURSOR_BACKWARD;
@@ -767,6 +762,21 @@
   canvas->FillRect(GetCursorBounds(position, true), cursor_color_);
 }
 
+bool RenderText::IsValidLogicalIndex(size_t index) {
+  // Check that the index is at a valid code point (not mid-surrgate-pair) and
+  // that it's not truncated from the layout text (its glyph may be shown).
+  //
+  // Indices within truncated text are disallowed so users can easily interact
+  // with the underlying truncated text using the ellipsis as a proxy. This lets
+  // users select all text, select the truncated text, and transition from the
+  // last rendered glyph to the end of the text without getting invisible cursor
+  // positions nor needing unbounded arrow key presses to traverse the ellipsis.
+  return index == 0 || index == text().length() ||
+      (index < text().length() &&
+       (truncate_length_ == 0 || index < truncate_length_) &&
+       IsValidCodePointIndex(text(), index));
+}
+
 Rect RenderText::GetCursorBounds(const SelectionModel& caret,
                                  bool insert_mode) {
   // TODO(ckocagil): Support multiline. This function should return the height
@@ -774,9 +784,8 @@
   //                 the multiline size, eliminate its use here.
 
   EnsureLayout();
-
   size_t caret_pos = caret.caret_pos();
-  DCHECK(IsCursorablePosition(caret_pos));
+  DCHECK(IsValidLogicalIndex(caret_pos));
   // In overtype mode, ignore the affinity and always indicate that we will
   // overtype the next character.
   LogicalCursorDirection caret_affinity =
@@ -817,7 +826,7 @@
   if (direction == CURSOR_FORWARD) {
     while (index < text().length()) {
       index++;
-      if (IsCursorablePosition(index))
+      if (IsValidCursorIndex(index))
         return index;
     }
     return text().length();
@@ -825,7 +834,7 @@
 
   while (index > 0) {
     index--;
-    if (IsCursorablePosition(index))
+    if (IsValidCursorIndex(index))
       return index;
   }
   return 0;
@@ -1108,7 +1117,7 @@
 
 void RenderText::MoveCursorTo(size_t position, bool select) {
   size_t cursor = std::min(position, text().length());
-  if (IsCursorablePosition(cursor))
+  if (IsValidCursorIndex(cursor))
     SetSelectionModel(SelectionModel(
         Range(select ? selection().start() : cursor, cursor),
         (cursor == 0) ? CURSOR_FORWARD : CURSOR_BACKWARD));
diff --git a/ui/gfx/render_text.h b/ui/gfx/render_text.h
index 93054b4..52564fb 100644
--- a/ui/gfx/render_text.h
+++ b/ui/gfx/render_text.h
@@ -289,11 +289,6 @@
   // grapheme boundary), it is a no-op and returns false.
   bool MoveCursorTo(const SelectionModel& selection_model);
 
-  // Move the cursor to the position associated with the clicked point.
-  // If |select| is false, the selection start is moved to the same position.
-  // Returns true if the cursor position or selection range changed.
-  bool MoveCursorTo(const Point& point, bool select);
-
   // Set the selection_model_ based on |range|.
   // If the |range| start or end is greater than text length, it is modified
   // to be the text length.
@@ -378,9 +373,13 @@
   // Gets the SelectionModel from a visual point in local coordinates.
   virtual SelectionModel FindCursorPosition(const Point& point) = 0;
 
-  // Return true if cursor can appear in front of the character at |position|,
-  // which means it is a grapheme boundary or the first character in the text.
-  virtual bool IsCursorablePosition(size_t position) = 0;
+  // Returns true if the position is a valid logical index into text(), and is
+  // also a valid grapheme boundary, which may be used as a cursor position.
+  virtual bool IsValidCursorIndex(size_t index) = 0;
+
+  // Returns true if the position is a valid logical index into text(). Indices
+  // amid multi-character graphemes are allowed here, unlike IsValidCursorIndex.
+  virtual bool IsValidLogicalIndex(size_t index);
 
   // Get the visual bounds of a cursor at |caret|. These bounds typically
   // represent a vertical line if |insert_mode| is true. Pass false for
@@ -388,8 +387,7 @@
   // are in local coordinates, but may be outside the visible region if the text
   // is longer than the textfield. Subsequent text, cursor, or bounds changes
   // may invalidate returned values. Note that |caret| must be placed at
-  // grapheme boundary, that is, |IsCursorablePosition(caret.caret_pos())| must
-  // return true.
+  // grapheme boundary, i.e. caret.caret_pos() must be a cursorable position.
   Rect GetCursorBounds(const SelectionModel& caret, bool insert_mode);
 
   // Compute the current cursor bounds, panning the text to show the cursor in
@@ -398,10 +396,9 @@
   const Rect& GetUpdatedCursorBounds();
 
   // Given an |index| in text(), return the next or previous grapheme boundary
-  // in logical order (that is, the nearest index for which
-  // |IsCursorablePosition(index)| returns true). The return value is in the
-  // range 0 to text().length() inclusive (the input is clamped if it is out of
-  // that range). Always moves by at least one character index unless the
+  // in logical order (i.e. the nearest cursorable index). The return value is
+  // in the range 0 to text().length() inclusive (the input is clamped if it is
+  // out of that range). Always moves by at least one character index unless the
   // supplied index is already at the boundary of the string.
   size_t IndexOfAdjacentGrapheme(size_t index,
                                  LogicalCursorDirection direction);
diff --git a/ui/gfx/render_text_mac.cc b/ui/gfx/render_text_mac.cc
index af0be63..3ad484b 100644
--- a/ui/gfx/render_text_mac.cc
+++ b/ui/gfx/render_text_mac.cc
@@ -45,7 +45,7 @@
 
   std::vector<RenderText::FontSpan> spans;
   for (size_t i = 0; i < runs_.size(); ++i) {
-    gfx::Font font(runs_[i].font_name, runs_[i].text_size);
+    Font font(runs_[i].font_name, runs_[i].text_size);
     const CFRange cf_range = CTRunGetStringRange(runs_[i].ct_run);
     const Range range(cf_range.location, cf_range.location + cf_range.length);
     spans.push_back(RenderText::FontSpan(font, range));
@@ -93,9 +93,9 @@
   return index;
 }
 
-bool RenderTextMac::IsCursorablePosition(size_t position) {
+bool RenderTextMac::IsValidCursorIndex(size_t index) {
   // TODO(asvitkine): Implement this. http://crbug.com/131618
-  return true;
+  return IsValidLogicalIndex(index);
 }
 
 void RenderTextMac::ResetLayout() {
@@ -211,7 +211,7 @@
     end = TextIndexToLayoutIndex(style.GetRange().end());
     const CFRange range = CFRangeMake(i, end - i);
     base::ScopedCFTypeRef<CGColorRef> foreground(
-        gfx::CGColorCreateFromSkColor(style.color()));
+        CGColorCreateFromSkColor(style.color()));
     CFAttributedStringSetAttribute(attr_string, range,
         kCTForegroundColorAttributeName, foreground);
     CFArrayAppendValue(attributes_, foreground);
@@ -254,9 +254,9 @@
 
   // TODO(asvitkine): Don't use GetLineOffset() until draw time, since it may be
   // updated based on alignment changes without resetting the layout.
-  gfx::Vector2d text_offset = GetLineOffset(0);
+  Vector2d text_offset = GetLineOffset(0);
   // Skia will draw glyphs with respect to the baseline.
-  text_offset += gfx::Vector2d(0, common_baseline_);
+  text_offset += Vector2d(0, common_baseline_);
 
   const SkScalar x = SkIntToScalar(text_offset.x());
   const SkScalar y = SkIntToScalar(text_offset.y());
@@ -325,7 +325,7 @@
         base::mac::GetValueFromDictionary<CGColorRef>(
             attributes, kCTForegroundColorAttributeName);
     if (foreground)
-      run->foreground = gfx::CGColorRefToSkColor(foreground);
+      run->foreground = CGColorRefToSkColor(foreground);
 
     const CFNumberRef underline =
         base::mac::GetValueFromDictionary<CFNumberRef>(
diff --git a/ui/gfx/render_text_mac.h b/ui/gfx/render_text_mac.h
index 3a18a0f..ad03b84 100644
--- a/ui/gfx/render_text_mac.h
+++ b/ui/gfx/render_text_mac.h
@@ -44,7 +44,7 @@
   virtual std::vector<Rect> GetSubstringBounds(const Range& range) OVERRIDE;
   virtual size_t TextIndexToLayoutIndex(size_t index) const OVERRIDE;
   virtual size_t LayoutIndexToTextIndex(size_t index) const OVERRIDE;
-  virtual bool IsCursorablePosition(size_t position) OVERRIDE;
+  virtual bool IsValidCursorIndex(size_t index) OVERRIDE;
   virtual void ResetLayout() OVERRIDE;
   virtual void EnsureLayout() OVERRIDE;
   virtual void DrawVisualText(Canvas* canvas) OVERRIDE;
diff --git a/ui/gfx/render_text_pango.cc b/ui/gfx/render_text_pango.cc
index fdf3d59..bda684b 100644
--- a/ui/gfx/render_text_pango.cc
+++ b/ui/gfx/render_text_pango.cc
@@ -40,8 +40,7 @@
 }
 
 // Checks whether |range| contains |index|. This is not the same as calling
-// |range.Contains(gfx::Range(index))| - as that would return true when
-// |index| == |range.end()|.
+// range.Contains(Range(index)), which returns true if |index| == |range.end()|.
 bool IndexInRange(const Range& range, size_t index) {
   return index >= range.start() && index < range.end();
 }
@@ -249,7 +248,7 @@
 
 size_t RenderTextPango::TextIndexToLayoutIndex(size_t index) const {
   DCHECK(layout_);
-  ptrdiff_t offset = gfx::UTF16IndexToOffset(text(), 0, index);
+  ptrdiff_t offset = UTF16IndexToOffset(text(), 0, index);
   // Clamp layout indices to the length of the text actually used for layout.
   offset = std::min<size_t>(offset, g_utf8_strlen(layout_text_, -1));
   const char* layout_pointer = g_utf8_offset_to_pointer(layout_text_, offset);
@@ -260,24 +259,19 @@
   DCHECK(layout_);
   const char* layout_pointer = layout_text_ + index;
   const long offset = g_utf8_pointer_to_offset(layout_text_, layout_pointer);
-  return gfx::UTF16OffsetToIndex(text(), 0, offset);
+  return UTF16OffsetToIndex(text(), 0, offset);
 }
 
-bool RenderTextPango::IsCursorablePosition(size_t position) {
-  if (position == 0 && text().empty())
+bool RenderTextPango::IsValidCursorIndex(size_t index) {
+  if (index == 0 || index == text().length())
     return true;
-  if (position >= text().length())
-    return position == text().length();
-  if (!gfx::IsValidCodePointIndex(text(), position))
+  if (!IsValidLogicalIndex(index))
     return false;
 
   EnsureLayout();
-  ptrdiff_t offset = gfx::UTF16IndexToOffset(text(), 0, position);
-  // Check that the index corresponds with a valid text code point, that it is
-  // marked as a legitimate cursor position by Pango, and that it is not
-  // truncated from layout text (its glyph is shown on screen).
-  return (offset < num_log_attrs_ && log_attrs_[offset].is_cursor_position &&
-          offset < g_utf8_strlen(layout_text_, -1));
+  ptrdiff_t offset = UTF16IndexToOffset(text(), 0, index);
+  // Check that the index is marked as a legitimate cursor position by Pango.
+  return offset < num_log_attrs_ && log_attrs_[offset].is_cursor_position;
 }
 
 void RenderTextPango::ResetLayout() {
@@ -391,11 +385,10 @@
   ApplyTextShadows(&renderer);
 
   // TODO(derat): Use font-specific params: http://crbug.com/125235
-  const gfx::FontRenderParams& render_params =
-      gfx::GetDefaultFontRenderParams();
+  const FontRenderParams& render_params = GetDefaultFontRenderParams();
   const bool use_subpixel_rendering =
       render_params.subpixel_rendering !=
-          gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE;
+          FontRenderParams::SUBPIXEL_RENDERING_NONE;
   renderer.SetFontSmoothingSettings(
       render_params.antialiasing,
       use_subpixel_rendering && !background_is_transparent(),
@@ -403,16 +396,16 @@
 
   SkPaint::Hinting skia_hinting = SkPaint::kNormal_Hinting;
   switch (render_params.hinting) {
-    case gfx::FontRenderParams::HINTING_NONE:
+    case FontRenderParams::HINTING_NONE:
       skia_hinting = SkPaint::kNo_Hinting;
       break;
-    case gfx::FontRenderParams::HINTING_SLIGHT:
+    case FontRenderParams::HINTING_SLIGHT:
       skia_hinting = SkPaint::kSlight_Hinting;
       break;
-    case gfx::FontRenderParams::HINTING_MEDIUM:
+    case FontRenderParams::HINTING_MEDIUM:
       skia_hinting = SkPaint::kNormal_Hinting;
       break;
-    case gfx::FontRenderParams::HINTING_FULL:
+    case FontRenderParams::HINTING_FULL:
       skia_hinting = SkPaint::kFull_Hinting;
       break;
   }
diff --git a/ui/gfx/render_text_pango.h b/ui/gfx/render_text_pango.h
index ba7361c..4c62e0a 100644
--- a/ui/gfx/render_text_pango.h
+++ b/ui/gfx/render_text_pango.h
@@ -36,7 +36,7 @@
   virtual std::vector<Rect> GetSubstringBounds(const Range& range) OVERRIDE;
   virtual size_t TextIndexToLayoutIndex(size_t index) const OVERRIDE;
   virtual size_t LayoutIndexToTextIndex(size_t index) const OVERRIDE;
-  virtual bool IsCursorablePosition(size_t position) OVERRIDE;
+  virtual bool IsValidCursorIndex(size_t index) OVERRIDE;
   virtual void ResetLayout() OVERRIDE;
   virtual void EnsureLayout() OVERRIDE;
   virtual void DrawVisualText(Canvas* canvas) OVERRIDE;
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index cbe3dd5..9cf7bb6 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -44,8 +44,7 @@
 #endif
 
 // Checks whether |range| contains |index|. This is not the same as calling
-// |range.Contains(gfx::Range(index))| - as that would return true when
-// |index| == |range.end()|.
+// range.Contains(Range(index)), which returns true if |index| == |range.end()|.
 bool IndexInRange(const Range& range, size_t index) {
   return index >= range.start() && index < range.end();
 }
@@ -295,9 +294,9 @@
   EXPECT_EQ(1U, render_text->TextIndexToLayoutIndex(2U));
   EXPECT_EQ(0U, render_text->LayoutIndexToTextIndex(0U));
   EXPECT_EQ(2U, render_text->LayoutIndexToTextIndex(1U));
-  EXPECT_TRUE(render_text->IsCursorablePosition(0U));
-  EXPECT_FALSE(render_text->IsCursorablePosition(1U));
-  EXPECT_TRUE(render_text->IsCursorablePosition(2U));
+  EXPECT_TRUE(render_text->IsValidCursorIndex(0U));
+  EXPECT_FALSE(render_text->IsValidCursorIndex(1U));
+  EXPECT_TRUE(render_text->IsValidCursorIndex(2U));
 
   // FindCursorPosition() should not return positions between a surrogate pair.
   render_text->SetDisplayRect(Rect(0, 0, 20, 20));
@@ -443,11 +442,11 @@
 
   scoped_ptr<RenderText> expected_render_text(RenderText::CreateInstance());
   expected_render_text->SetFontList(FontList("serif, Sans serif, 12px"));
-  expected_render_text->SetDisplayRect(gfx::Rect(0, 0, 9999, 100));
+  expected_render_text->SetDisplayRect(Rect(0, 0, 9999, 100));
 
   scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
   render_text->SetFontList(FontList("serif, Sans serif, 12px"));
-  render_text->SetElideBehavior(gfx::ELIDE_AT_END);
+  render_text->SetElideBehavior(ELIDE_AT_END);
 
   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
     // Compute expected width
@@ -461,7 +460,7 @@
       input.append(WideToUTF16(L" MMMMMMMMMMM"));
 
     render_text->SetText(input);
-    render_text->SetDisplayRect(gfx::Rect(0, 0, expected_width, 100));
+    render_text->SetDisplayRect(Rect(0, 0, expected_width, 100));
     EXPECT_EQ(input, render_text->text())
         << "->For case " << i << ": " << cases[i].text << "\n";
     EXPECT_EQ(WideToUTF16(cases[i].layout_text), render_text->GetLayoutText())
@@ -473,14 +472,14 @@
 TEST_F(RenderTextTest, ElidedObscuredText) {
   scoped_ptr<RenderText> expected_render_text(RenderText::CreateInstance());
   expected_render_text->SetFontList(FontList("serif, Sans serif, 12px"));
-  expected_render_text->SetDisplayRect(gfx::Rect(0, 0, 9999, 100));
+  expected_render_text->SetDisplayRect(Rect(0, 0, 9999, 100));
   expected_render_text->SetText(WideToUTF16(L"**\x2026"));
 
   scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
   render_text->SetFontList(FontList("serif, Sans serif, 12px"));
-  render_text->SetElideBehavior(gfx::ELIDE_AT_END);
+  render_text->SetElideBehavior(ELIDE_AT_END);
   render_text->SetDisplayRect(
-      gfx::Rect(0, 0, expected_render_text->GetContentWidth(), 100));
+      Rect(0, 0, expected_render_text->GetContentWidth(), 100));
   render_text->SetObscured(true);
   render_text->SetText(WideToUTF16(L"abcdef"));
   EXPECT_EQ(WideToUTF16(L"abcdef"), render_text->text());
@@ -892,26 +891,58 @@
     { kText3, 50, 6, 6 },
   };
 
-  // TODO(asvitkine): Disable tests that fail on XP bots due to lack of complete
-  //                  font support for some scripts - http://crbug.com/106450
 #if defined(OS_WIN)
+  // TODO(msw): XP fails due to lack of font support: http://crbug.com/106450
   if (base::win::GetVersion() < base::win::VERSION_VISTA)
     return;
 #endif
 
   scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
+    SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "]", i));
     render_text->SetText(cases[i].text);
 
     size_t next = render_text->IndexOfAdjacentGrapheme(cases[i].index,
                                                        CURSOR_FORWARD);
     EXPECT_EQ(cases[i].expected_next, next);
-    EXPECT_TRUE(render_text->IsCursorablePosition(next));
+    EXPECT_TRUE(render_text->IsValidCursorIndex(next));
 
     size_t previous = render_text->IndexOfAdjacentGrapheme(cases[i].index,
                                                            CURSOR_BACKWARD);
     EXPECT_EQ(cases[i].expected_previous, previous);
-    EXPECT_TRUE(render_text->IsCursorablePosition(previous));
+    EXPECT_TRUE(render_text->IsValidCursorIndex(previous));
+  }
+}
+
+TEST_F(RenderTextTest, MidGraphemeSelectionBounds) {
+#if defined(OS_WIN)
+  // TODO(msw): XP fails due to lack of font support: http://crbug.com/106450
+  if (base::win::GetVersion() < base::win::VERSION_VISTA)
+    return;
+#endif
+
+  // Test that selection bounds may be set amid multi-character graphemes.
+  const base::string16 kHindi = WideToUTF16(L"\x0915\x093f");
+  const base::string16 kThai = WideToUTF16(L"\x0e08\x0e33");
+  const base::string16 cases[] = { kHindi, kThai };
+
+  scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
+  for (size_t i = 0; i < arraysize(cases); i++) {
+    SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "]", i));
+    render_text->SetText(cases[i]);
+    EXPECT_TRUE(render_text->IsValidLogicalIndex(1));
+#if !defined(OS_MACOSX)
+    EXPECT_FALSE(render_text->IsValidCursorIndex(1));
+#endif
+    EXPECT_TRUE(render_text->SelectRange(Range(2, 1)));
+    EXPECT_EQ(Range(2, 1), render_text->selection());
+    EXPECT_EQ(1U, render_text->cursor_position());
+    // Although selection bounds may be set within a multi-character grapheme,
+    // cursor movement (e.g. via arrow key) should avoid those indices.
+    render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false);
+    EXPECT_EQ(0U, render_text->cursor_position());
+    render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false);
+    EXPECT_EQ(2U, render_text->cursor_position());
   }
 }
 
@@ -941,9 +972,8 @@
     { kHebrewLatin, base::i18n::RIGHT_TO_LEFT },
   };
 
-  // TODO(asvitkine): Disable tests that fail on XP bots due to lack of complete
-  //                  font support for some scripts - http://crbug.com/106450
 #if defined(OS_WIN)
+  // TODO(msw): XP fails due to lack of font support: http://crbug.com/106450
   if (base::win::GetVersion() < base::win::VERSION_VISTA)
     return;
 #endif
diff --git a/ui/gfx/render_text_win.cc b/ui/gfx/render_text_win.cc
index 46f46dd..19b2caa 100644
--- a/ui/gfx/render_text_win.cc
+++ b/ui/gfx/render_text_win.cc
@@ -504,19 +504,14 @@
 // static
 std::map<std::string, Font> RenderTextWin::successful_substitute_fonts_;
 
-RenderTextWin::RenderTextWin()
-    : RenderText(),
-      needs_layout_(false) {
+RenderTextWin::RenderTextWin() : RenderText(), needs_layout_(false) {
   set_truncate_length(kMaxUniscribeTextLength);
-
   memset(&script_control_, 0, sizeof(script_control_));
   memset(&script_state_, 0, sizeof(script_state_));
-
   MoveCursorTo(EdgeSelectionModel(CURSOR_LEFT));
 }
 
-RenderTextWin::~RenderTextWin() {
-}
+RenderTextWin::~RenderTextWin() {}
 
 Size RenderTextWin::GetStringSize() {
   EnsureLayout();
@@ -716,7 +711,7 @@
 
 size_t RenderTextWin::TextIndexToLayoutIndex(size_t index) const {
   DCHECK_LE(index, text().length());
-  ptrdiff_t i = obscured() ? gfx::UTF16IndexToOffset(text(), 0, index) : index;
+  ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index;
   CHECK_GE(i, 0);
   // Clamp layout indices to the length of the text actually used for layout.
   return std::min<size_t>(GetLayoutText().length(), i);
@@ -727,24 +722,22 @@
     return index;
 
   DCHECK_LE(index, GetLayoutText().length());
-  const size_t text_index = gfx::UTF16OffsetToIndex(text(), 0, index);
+  const size_t text_index = UTF16OffsetToIndex(text(), 0, index);
   DCHECK_LE(text_index, text().length());
   return text_index;
 }
 
-bool RenderTextWin::IsCursorablePosition(size_t position) {
-  if (position == 0 || position == text().length())
+bool RenderTextWin::IsValidCursorIndex(size_t index) {
+  if (index == 0 || index == text().length())
     return true;
+  if (!IsValidLogicalIndex(index))
+    return false;
   EnsureLayout();
-
-  // Check that the index is at a valid code point (not mid-surrgate-pair),
-  // that it is not truncated from layout text (its glyph is shown on screen),
-  // and that its glyph has distinct bounds (not mid-multi-character-grapheme).
-  // An example of a multi-character-grapheme that is not a surrogate-pair is:
-  // \x0915\x093f - (ki) - one of many Devanagari biconsonantal conjuncts.
-  return gfx::IsValidCodePointIndex(text(), position) &&
-         position < LayoutIndexToTextIndex(GetLayoutText().length()) &&
-         GetGlyphBounds(position) != GetGlyphBounds(position - 1);
+  // Disallow indices amid multi-character graphemes by checking glyph bounds.
+  // These characters are not surrogate-pairs, but may yield a single glyph:
+  //   \x0915\x093f - (ki) - one of many Devanagari biconsonantal conjuncts.
+  //   \x0e08\x0e33 - (cho chan + sara am) - a Thai consonant and vowel pair.
+  return GetGlyphBounds(index) != GetGlyphBounds(index - 1);
 }
 
 void RenderTextWin::ResetLayout() {
@@ -843,7 +836,7 @@
       for (size_t k = glyph_range.start(); k < glyph_range.end(); ++k) {
         pos[k - glyph_range.start()].set(
             SkIntToScalar(text_offset.x() + run->offsets[k].du + segment_x),
-            SkIntToScalar(text_offset.y() + run->offsets[k].dv));
+            SkIntToScalar(text_offset.y() - run->offsets[k].dv));
         segment_x += run->advance_widths[k];
       }
       pos.back().set(SkIntToScalar(text_offset.x() + segment_x),
@@ -860,8 +853,13 @@
         const Range intersection =
             colors().GetRange(it).Intersect(segment->char_range);
         const Range colored_glyphs = CharRangeToGlyphRange(*run, intersection);
+        // The range may be empty if a portion of a multi-character grapheme is
+        // selected, yielding two colors for a single glyph. For now, this just
+        // paints the glyph with a single style, but it should paint it twice,
+        // clipped according to selection bounds. See http://crbug.com/366786
+        if (colored_glyphs.is_empty())
+          continue;
         DCHECK(glyph_range.Contains(colored_glyphs));
-        DCHECK(!colored_glyphs.is_empty());
         const SkPoint& start_pos =
             pos[colored_glyphs.start() - glyph_range.start()];
         const SkPoint& end_pos =
diff --git a/ui/gfx/render_text_win.h b/ui/gfx/render_text_win.h
index 1a1ba48..4e8caf6 100644
--- a/ui/gfx/render_text_win.h
+++ b/ui/gfx/render_text_win.h
@@ -80,7 +80,7 @@
   virtual std::vector<Rect> GetSubstringBounds(const Range& range) OVERRIDE;
   virtual size_t TextIndexToLayoutIndex(size_t index) const OVERRIDE;
   virtual size_t LayoutIndexToTextIndex(size_t index) const OVERRIDE;
-  virtual bool IsCursorablePosition(size_t position) OVERRIDE;
+  virtual bool IsValidCursorIndex(size_t index) OVERRIDE;
   virtual void ResetLayout() OVERRIDE;
   virtual void EnsureLayout() OVERRIDE;
   virtual void DrawVisualText(Canvas* canvas) OVERRIDE;
diff --git a/ui/gfx/selection_model.h b/ui/gfx/selection_model.h
index d509e89..356416d 100644
--- a/ui/gfx/selection_model.h
+++ b/ui/gfx/selection_model.h
@@ -73,19 +73,16 @@
   size_t caret_pos() const { return selection_.end(); }
   LogicalCursorDirection caret_affinity() const { return caret_affinity_; }
 
+  // WARNING: Generally the selection start should not be changed without
+  // considering the effect on the caret affinity.
+  void set_selection_start(size_t pos) { selection_.set_start(pos); }
+
   bool operator==(const SelectionModel& sel) const;
   bool operator!=(const SelectionModel& sel) const { return !(*this == sel); }
 
   std::string ToString() const;
 
  private:
-  friend class RenderText;
-
-  // TODO(benrg): Generally the selection start should not be changed without
-  // considering the effect on the caret affinity. This setter is exposed only
-  // to RenderText to discourage misuse, and should probably be removed.
-  void set_selection_start(size_t pos) { selection_.set_start(pos); }
-
   // Logical selection. The logical caret position is the end of the selection.
   Range selection_;
 
diff --git a/ui/gfx/skia_util.cc b/ui/gfx/skia_util.cc
index 943f51e..b8100b0 100644
--- a/ui/gfx/skia_util.cc
+++ b/ui/gfx/skia_util.cc
@@ -64,13 +64,21 @@
 skia::RefPtr<SkShader> CreateImageRepShader(const gfx::ImageSkiaRep& image_rep,
                                             SkShader::TileMode tile_mode,
                                             const SkMatrix& local_matrix) {
+  return CreateImageRepShaderForScale(image_rep, tile_mode, local_matrix,
+                                      image_rep.scale());
+}
+
+skia::RefPtr<SkShader> CreateImageRepShaderForScale(
+    const gfx::ImageSkiaRep& image_rep,
+    SkShader::TileMode tile_mode,
+    const SkMatrix& local_matrix,
+    SkScalar scale) {
   skia::RefPtr<SkShader> shader = skia::AdoptRef(SkShader::CreateBitmapShader(
       image_rep.sk_bitmap(), tile_mode, tile_mode));
   SkScalar scale_x = local_matrix.getScaleX();
   SkScalar scale_y = local_matrix.getScaleY();
-  SkScalar bitmap_scale = SkFloatToScalar(image_rep.scale());
 
-  // Unscale matrix by |bitmap_scale| such that the bitmap is drawn at the
+  // Unscale matrix by |scale| such that the bitmap is drawn at the
   // correct density.
   // Convert skew and translation to pixel coordinates.
   // Thus, for |bitmap_scale| = 2:
@@ -78,9 +86,9 @@
   // should be converted to
   //   x scale = 1, x translation = 2 pixels.
   SkMatrix shader_scale = local_matrix;
-  shader_scale.preScale(bitmap_scale, bitmap_scale);
-  shader_scale.setScaleX(SkScalarDiv(scale_x, bitmap_scale));
-  shader_scale.setScaleY(SkScalarDiv(scale_y, bitmap_scale));
+  shader_scale.preScale(scale, scale);
+  shader_scale.setScaleX(SkScalarDiv(scale_x, scale));
+  shader_scale.setScaleY(SkScalarDiv(scale_y, scale));
 
   shader->setLocalMatrix(shader_scale);
   return shader;
@@ -99,6 +107,12 @@
       grad_points, grad_colors, NULL, 2, SkShader::kRepeat_TileMode));
 }
 
+static SkScalar RadiusToSigma(double radius) {
+  // This captures historically what skia did under the hood. Now skia accepts
+  // sigma, not radius, so we perform the conversion.
+  return radius > 0 ? SkDoubleToScalar(0.57735f * radius + 0.5) : 0;
+}
+
 skia::RefPtr<SkDrawLooper> CreateShadowDrawLooper(
     const std::vector<ShadowValue>& shadows) {
   if (shadows.empty())
@@ -122,8 +136,8 @@
     // SkBlurMaskFilter's blur radius defines the range to extend the blur from
     // original mask, which is half of blur amount as defined in ShadowValue.
     skia::RefPtr<SkMaskFilter> blur_mask = skia::AdoptRef(
-        SkBlurMaskFilter::Create(SkDoubleToScalar(shadow.blur() / 2),
-                                 SkBlurMaskFilter::kNormal_BlurStyle,
+        SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
+                                 RadiusToSigma(shadow.blur() / 2),
                                  SkBlurMaskFilter::kHighQuality_BlurFlag));
     skia::RefPtr<SkColorFilter> color_filter = skia::AdoptRef(
         SkColorFilter::CreateModeFilter(shadow.color(),
diff --git a/ui/gfx/skia_util.h b/ui/gfx/skia_util.h
index 92c886a..0c75983 100644
--- a/ui/gfx/skia_util.h
+++ b/ui/gfx/skia_util.h
@@ -47,6 +47,13 @@
     SkShader::TileMode tile_mode,
     const SkMatrix& local_matrix);
 
+// Creates a bitmap shader for the image rep with the passed in scale factor.
+GFX_EXPORT skia::RefPtr<SkShader> CreateImageRepShaderForScale(
+    const gfx::ImageSkiaRep& image_rep,
+    SkShader::TileMode tile_mode,
+    const SkMatrix& local_matrix,
+    SkScalar scale);
+
 // Creates a vertical gradient shader. The caller owns the shader.
 // Example usage to avoid leaks:
 GFX_EXPORT skia::RefPtr<SkShader> CreateGradientShader(int start_point,
diff --git a/ui/gl/gl.target.darwin-arm.mk b/ui/gl/gl.target.darwin-arm.mk
index 09e3cbf..2cffce8 100644
--- a/ui/gl/gl.target.darwin-arm.mk
+++ b/ui/gl/gl.target.darwin-arm.mk
@@ -19,6 +19,7 @@
 
 ### Rules for action "generate_gl_bindings":
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,7 +141,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -191,11 +191,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -272,7 +267,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -323,11 +317,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gl/gl.target.darwin-arm64.mk b/ui/gl/gl.target.darwin-arm64.mk
index afe2f38..f7e36f3 100644
--- a/ui/gl/gl.target.darwin-arm64.mk
+++ b/ui/gl/gl.target.darwin-arm64.mk
@@ -19,6 +19,7 @@
 
 ### Rules for action "generate_gl_bindings":
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -187,11 +188,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -314,11 +310,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gl/gl.target.darwin-mips.mk b/ui/gl/gl.target.darwin-mips.mk
index 3e1cee4..5f3d4dc 100644
--- a/ui/gl/gl.target.darwin-mips.mk
+++ b/ui/gl/gl.target.darwin-mips.mk
@@ -19,6 +19,7 @@
 
 ### Rules for action "generate_gl_bindings":
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -190,11 +191,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -321,11 +317,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gl/gl.target.darwin-x86.mk b/ui/gl/gl.target.darwin-x86.mk
index f5dee02..d930bfa 100644
--- a/ui/gl/gl.target.darwin-x86.mk
+++ b/ui/gl/gl.target.darwin-x86.mk
@@ -19,6 +19,7 @@
 
 ### Rules for action "generate_gl_bindings":
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -142,7 +143,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -192,11 +192,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -274,7 +269,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -324,11 +318,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gl/gl.target.darwin-x86_64.mk b/ui/gl/gl.target.darwin-x86_64.mk
index de76f59..7e3c35b 100644
--- a/ui/gl/gl.target.darwin-x86_64.mk
+++ b/ui/gl/gl.target.darwin-x86_64.mk
@@ -19,6 +19,7 @@
 
 ### Rules for action "generate_gl_bindings":
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -142,7 +143,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -192,11 +192,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -274,7 +269,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -324,11 +318,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gl/gl.target.linux-arm.mk b/ui/gl/gl.target.linux-arm.mk
index 09e3cbf..2cffce8 100644
--- a/ui/gl/gl.target.linux-arm.mk
+++ b/ui/gl/gl.target.linux-arm.mk
@@ -19,6 +19,7 @@
 
 ### Rules for action "generate_gl_bindings":
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -140,7 +141,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -191,11 +191,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -272,7 +267,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -323,11 +317,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gl/gl.target.linux-arm64.mk b/ui/gl/gl.target.linux-arm64.mk
index afe2f38..f7e36f3 100644
--- a/ui/gl/gl.target.linux-arm64.mk
+++ b/ui/gl/gl.target.linux-arm64.mk
@@ -19,6 +19,7 @@
 
 ### Rules for action "generate_gl_bindings":
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -187,11 +188,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -314,11 +310,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gl/gl.target.linux-mips.mk b/ui/gl/gl.target.linux-mips.mk
index 3e1cee4..5f3d4dc 100644
--- a/ui/gl/gl.target.linux-mips.mk
+++ b/ui/gl/gl.target.linux-mips.mk
@@ -19,6 +19,7 @@
 
 ### Rules for action "generate_gl_bindings":
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -190,11 +191,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -321,11 +317,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gl/gl.target.linux-x86.mk b/ui/gl/gl.target.linux-x86.mk
index f5dee02..d930bfa 100644
--- a/ui/gl/gl.target.linux-x86.mk
+++ b/ui/gl/gl.target.linux-x86.mk
@@ -19,6 +19,7 @@
 
 ### Rules for action "generate_gl_bindings":
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -142,7 +143,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -192,11 +192,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -274,7 +269,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -324,11 +318,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gl/gl.target.linux-x86_64.mk b/ui/gl/gl.target.linux-x86_64.mk
index de76f59..7e3c35b 100644
--- a/ui/gl/gl.target.linux-x86_64.mk
+++ b/ui/gl/gl.target.linux-x86_64.mk
@@ -19,6 +19,7 @@
 
 ### Rules for action "generate_gl_bindings":
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/gl_bindings_autogen_egl.cc: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -142,7 +143,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -192,11 +192,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -274,7 +269,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -324,11 +318,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h
index a1786e6..23182bc 100644
--- a/ui/gl/gl_bindings.h
+++ b/ui/gl/gl_bindings.h
@@ -131,6 +131,11 @@
 // GL_CHROMIUM_sync_query
 #define GL_COMMANDS_COMPLETED_CHROMIUM                   0x84F7
 
+// GL_CHROMIUM_image
+#define GL_IMAGE_ROWBYTES_CHROMIUM                       0x78F0
+#define GL_IMAGE_MAP_CHROMIUM                            0x78F1
+#define GL_IMAGE_SCANOUT_CHROMIUM                        0x78F2
+
 // GL_OES_texure_3D
 #define GL_SAMPLER_3D_OES                                0x8B5F
 
diff --git a/ui/gl/gl_implementation_android.cc b/ui/gl/gl_implementation_android.cc
index 3fae1ee..77dcb90 100644
--- a/ui/gl/gl_implementation_android.cc
+++ b/ui/gl/gl_implementation_android.cc
@@ -44,14 +44,12 @@
 
   switch (implementation) {
     case kGLImplementationEGLGLES2: {
-      base::NativeLibrary gles_library = LoadLibrary("libGLESv2.so");
-      if (!gles_library) {
-        LOG(ERROR) << "Failed to load libGLESv2.so.";
+      base::NativeLibrary gles_library =
+          LoadLibraryAndPrintError("libGLESv2.so");
+      if (!gles_library)
         return false;
-      }
-      base::NativeLibrary egl_library = LoadLibrary("libEGL.so");
+      base::NativeLibrary egl_library = LoadLibraryAndPrintError("libEGL.so");
       if (!egl_library) {
-        LOG(ERROR) << "Failed to load libEGL.so.";
         base::UnloadNativeLibrary(gles_library);
         return false;
       }
diff --git a/ui/gl/gl_implementation_osmesa.cc b/ui/gl/gl_implementation_osmesa.cc
index c8ef874..90de690 100644
--- a/ui/gl/gl_implementation_osmesa.cc
+++ b/ui/gl/gl_implementation_osmesa.cc
@@ -15,20 +15,19 @@
 
 namespace gfx {
 
-// Load a library, printing an error message on failure.
-base::NativeLibrary LoadLibrary(const base::FilePath& filename) {
+base::NativeLibrary LoadLibraryAndPrintError(const base::FilePath& filename) {
   base::NativeLibraryLoadError error;
   base::NativeLibrary library = base::LoadNativeLibrary(filename, &error);
   if (!library) {
-    DVLOG(1) << "Failed to load " << filename.MaybeAsASCII() << ": "
-             << error.ToString();
+    LOG(ERROR) << "Failed to load " << filename.MaybeAsASCII() << ": "
+               << error.ToString();
     return NULL;
   }
   return library;
 }
 
-base::NativeLibrary LoadLibrary(const char* filename) {
-  return LoadLibrary(base::FilePath(filename));
+base::NativeLibrary LoadLibraryAndPrintError(const char* filename) {
+  return LoadLibraryAndPrintError(base::FilePath(filename));
 }
 
 bool InitializeStaticGLBindingsOSMesaGL() {
@@ -39,11 +38,9 @@
   }
 
   base::FilePath library_path = module_path.Append("libosmesa.so");
-  base::NativeLibrary library = LoadLibrary(library_path);
-  if (!library) {
-    LOG(ERROR) << "Failed to load " << library_path.value() << ".";
+  base::NativeLibrary library = LoadLibraryAndPrintError(library_path);
+  if (!library)
     return false;
-  }
 
   GLGetProcAddressProc get_proc_address =
       reinterpret_cast<GLGetProcAddressProc>(
diff --git a/ui/gl/gl_implementation_osmesa.h b/ui/gl/gl_implementation_osmesa.h
index 16180b7..595c24e 100644
--- a/ui/gl/gl_implementation_osmesa.h
+++ b/ui/gl/gl_implementation_osmesa.h
@@ -11,9 +11,9 @@
 namespace gfx {
 
 bool InitializeStaticGLBindingsOSMesaGL();
-base::NativeLibrary LoadLibrary(const char* filename);
-base::NativeLibrary LoadLibrary(const base::FilePath& filename);
+base::NativeLibrary LoadLibraryAndPrintError(const char* filename);
+base::NativeLibrary LoadLibraryAndPrintError(const base::FilePath& filename);
 
 }  // namespace gfx
 
-#endif  // UI_GL_GL_IMPLEMENTATION_OSMESA_
\ No newline at end of file
+#endif  // UI_GL_GL_IMPLEMENTATION_OSMESA_
diff --git a/ui/gl/gl_implementation_x11.cc b/ui/gl/gl_implementation_x11.cc
index 0dc524b..176f7d2 100644
--- a/ui/gl/gl_implementation_x11.cc
+++ b/ui/gl/gl_implementation_x11.cc
@@ -68,17 +68,15 @@
       const CommandLine* command_line = CommandLine::ForCurrentProcess();
 
       if (command_line->HasSwitch(switches::kTestGLLib))
-        library = LoadLibrary(command_line->GetSwitchValueASCII(
-            switches::kTestGLLib).c_str());
+        library = LoadLibraryAndPrintError(
+            command_line->GetSwitchValueASCII(switches::kTestGLLib).c_str());
 
       if (!library) {
-        library = LoadLibrary(kGLLibraryName);
+        library = LoadLibraryAndPrintError(kGLLibraryName);
       }
 
-      if (!library) {
-        LOG(ERROR) << "Failed to load " << kGLLibraryName << ".";
+      if (!library)
         return false;
-      }
 
       GLGetProcAddressProc get_proc_address =
           reinterpret_cast<GLGetProcAddressProc>(
@@ -99,14 +97,13 @@
       break;
     }
     case kGLImplementationEGLGLES2: {
-      base::NativeLibrary gles_library = LoadLibrary(kGLESv2LibraryName);
-      if (!gles_library) {
-        LOG(ERROR) << "Failed to load " << kGLESv2LibraryName << ".";
+      base::NativeLibrary gles_library =
+          LoadLibraryAndPrintError(kGLESv2LibraryName);
+      if (!gles_library)
         return false;
-      }
-      base::NativeLibrary egl_library = LoadLibrary(kEGLLibraryName);
+      base::NativeLibrary egl_library =
+          LoadLibraryAndPrintError(kEGLLibraryName);
       if (!egl_library) {
-        LOG(ERROR) << "Failed to load " << kEGLLibraryName << ".";
         base::UnloadNativeLibrary(gles_library);
         return false;
       }
diff --git a/ui/gl/gl_jni_headers.target.darwin-arm.mk b/ui/gl/gl_jni_headers.target.darwin-arm.mk
index 8ca36af..eade780 100644
--- a/ui/gl/gl_jni_headers.target.darwin-arm.mk
+++ b/ui/gl/gl_jni_headers.target.darwin-arm.mk
@@ -19,6 +19,7 @@
 ### Generated for rule "ui_gl_gl_gyp_gl_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gl/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gl/SurfaceTexturePlatformWrapper.java', '../android/java/src/org/chromium/ui/gl/SurfaceTextureListener.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gl/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,7 +67,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -149,7 +150,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/gl/gl_jni_headers.target.darwin-arm64.mk b/ui/gl/gl_jni_headers.target.darwin-arm64.mk
index 17ac3b5..17b898b 100644
--- a/ui/gl/gl_jni_headers.target.darwin-arm64.mk
+++ b/ui/gl/gl_jni_headers.target.darwin-arm64.mk
@@ -19,6 +19,7 @@
 ### Generated for rule "ui_gl_gl_gyp_gl_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gl/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gl/SurfaceTexturePlatformWrapper.java', '../android/java/src/org/chromium/ui/gl/SurfaceTextureListener.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gl/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gl/gl_jni_headers.target.darwin-mips.mk b/ui/gl/gl_jni_headers.target.darwin-mips.mk
index 4d9b9d6..1cffa65 100644
--- a/ui/gl/gl_jni_headers.target.darwin-mips.mk
+++ b/ui/gl/gl_jni_headers.target.darwin-mips.mk
@@ -19,6 +19,7 @@
 ### Generated for rule "ui_gl_gl_gyp_gl_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gl/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gl/SurfaceTexturePlatformWrapper.java', '../android/java/src/org/chromium/ui/gl/SurfaceTextureListener.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gl/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gl/gl_jni_headers.target.darwin-x86.mk b/ui/gl/gl_jni_headers.target.darwin-x86.mk
index 03bb823..e44e0b2 100644
--- a/ui/gl/gl_jni_headers.target.darwin-x86.mk
+++ b/ui/gl/gl_jni_headers.target.darwin-x86.mk
@@ -19,6 +19,7 @@
 ### Generated for rule "ui_gl_gl_gyp_gl_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gl/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gl/SurfaceTexturePlatformWrapper.java', '../android/java/src/org/chromium/ui/gl/SurfaceTextureListener.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gl/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -67,7 +69,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -151,7 +152,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gl/gl_jni_headers.target.darwin-x86_64.mk b/ui/gl/gl_jni_headers.target.darwin-x86_64.mk
index 64ed511..a8d0c65 100644
--- a/ui/gl/gl_jni_headers.target.darwin-x86_64.mk
+++ b/ui/gl/gl_jni_headers.target.darwin-x86_64.mk
@@ -19,6 +19,7 @@
 ### Generated for rule "ui_gl_gl_gyp_gl_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gl/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gl/SurfaceTexturePlatformWrapper.java', '../android/java/src/org/chromium/ui/gl/SurfaceTextureListener.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gl/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -67,7 +69,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -151,7 +152,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gl/gl_jni_headers.target.linux-arm.mk b/ui/gl/gl_jni_headers.target.linux-arm.mk
index 8ca36af..eade780 100644
--- a/ui/gl/gl_jni_headers.target.linux-arm.mk
+++ b/ui/gl/gl_jni_headers.target.linux-arm.mk
@@ -19,6 +19,7 @@
 ### Generated for rule "ui_gl_gl_gyp_gl_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gl/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gl/SurfaceTexturePlatformWrapper.java', '../android/java/src/org/chromium/ui/gl/SurfaceTextureListener.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gl/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -65,7 +67,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -149,7 +150,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/gl/gl_jni_headers.target.linux-arm64.mk b/ui/gl/gl_jni_headers.target.linux-arm64.mk
index 17ac3b5..17b898b 100644
--- a/ui/gl/gl_jni_headers.target.linux-arm64.mk
+++ b/ui/gl/gl_jni_headers.target.linux-arm64.mk
@@ -19,6 +19,7 @@
 ### Generated for rule "ui_gl_gl_gyp_gl_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gl/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gl/SurfaceTexturePlatformWrapper.java', '../android/java/src/org/chromium/ui/gl/SurfaceTextureListener.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gl/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gl/gl_jni_headers.target.linux-mips.mk b/ui/gl/gl_jni_headers.target.linux-mips.mk
index 4d9b9d6..1cffa65 100644
--- a/ui/gl/gl_jni_headers.target.linux-mips.mk
+++ b/ui/gl/gl_jni_headers.target.linux-mips.mk
@@ -19,6 +19,7 @@
 ### Generated for rule "ui_gl_gl_gyp_gl_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gl/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gl/SurfaceTexturePlatformWrapper.java', '../android/java/src/org/chromium/ui/gl/SurfaceTextureListener.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gl/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gl/gl_jni_headers.target.linux-x86.mk b/ui/gl/gl_jni_headers.target.linux-x86.mk
index 03bb823..e44e0b2 100644
--- a/ui/gl/gl_jni_headers.target.linux-x86.mk
+++ b/ui/gl/gl_jni_headers.target.linux-x86.mk
@@ -19,6 +19,7 @@
 ### Generated for rule "ui_gl_gl_gyp_gl_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gl/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gl/SurfaceTexturePlatformWrapper.java', '../android/java/src/org/chromium/ui/gl/SurfaceTextureListener.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gl/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -67,7 +69,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -151,7 +152,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gl/gl_jni_headers.target.linux-x86_64.mk b/ui/gl/gl_jni_headers.target.linux-x86_64.mk
index 64ed511..a8d0c65 100644
--- a/ui/gl/gl_jni_headers.target.linux-x86_64.mk
+++ b/ui/gl/gl_jni_headers.target.linux-x86_64.mk
@@ -19,6 +19,7 @@
 ### Generated for rule "ui_gl_gl_gyp_gl_jni_headers_target_generate_jni_headers":
 # "{'inputs': ['../../base/android/jni_generator/jni_generator.py', '../../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/ui/gl/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['../android/java/src/org/chromium/ui/gl/SurfaceTexturePlatformWrapper.java', '../android/java/src/org/chromium/ui/gl/SurfaceTextureListener.java'], 'action': ['../../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/ui/gl/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTexturePlatformWrapper_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -27,6 +28,7 @@
 
 
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/SurfaceTextureListener_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -67,7 +69,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -151,7 +152,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gl/gl_surface.cc b/ui/gl/gl_surface.cc
index 4e74f49..92b2b45 100644
--- a/ui/gl/gl_surface.cc
+++ b/ui/gl/gl_surface.cc
@@ -42,7 +42,9 @@
   // The default implementation is always the first one in list.
   GLImplementation impl = allowed_impls[0];
   bool fallback_to_osmesa = false;
-  if (cmd->HasSwitch(switches::kUseGL)) {
+  if (cmd->HasSwitch(switches::kOverrideUseGLWithOSMesaForTests)) {
+    impl = kGLImplementationOSMesaGL;
+  } else if (cmd->HasSwitch(switches::kUseGL)) {
     std::string requested_implementation_name =
         cmd->GetSwitchValueASCII(switches::kUseGL);
     if (requested_implementation_name == "any") {
diff --git a/ui/gl/gl_switches.cc b/ui/gl/gl_switches.cc
index d32786f..a32c5f6 100644
--- a/ui/gl/gl_switches.cc
+++ b/ui/gl/gl_switches.cc
@@ -60,12 +60,16 @@
 // library first, but fall back to regular library if loading fails.
 const char kTestGLLib[]                     = "test-gl-lib";
 
+// Use hardware gpu, if available, for tests.
+const char kUseGpuInTests[] = "use-gpu-in-tests";
+
 // Disables GL drawing operations which produce pixel output. With this
 // the GL output will not be correct but tests will run faster.
 const char kDisableGLDrawingForTests[] = "disable-gl-drawing-for-tests";
 
-// Use hardware gpu, if available, for tests.
-const char kUseGpuInTests[] = "use-gpu-in-tests";
+// Forces the use of OSMesa instead of hardware gpu.
+const char kOverrideUseGLWithOSMesaForTests[] =
+    "override-use-gl-with-osmesa-for-tests";
 
 // This is the list of switches passed from this file that are passed from the
 // GpuProcessHost to the GPU Process. Add your switch to this list if you need
@@ -76,6 +80,8 @@
   kEnableGPUServiceLogging,
   kEnableGPUServiceTracing,
   kGpuNoContextLost,
+  kDisableGLDrawingForTests,
+  kOverrideUseGLWithOSMesaForTests,
 };
 const int kGLSwitchesCopiedFromGpuProcessHostNumSwitches =
     arraysize(kGLSwitchesCopiedFromGpuProcessHost);
diff --git a/ui/gl/gl_switches.h b/ui/gl/gl_switches.h
index e64b3da..779ecfb 100644
--- a/ui/gl/gl_switches.h
+++ b/ui/gl/gl_switches.h
@@ -42,9 +42,12 @@
 GL_EXPORT extern const char kUseGL[];
 GL_EXPORT extern const char kSwiftShaderPath[];
 GL_EXPORT extern const char kTestGLLib[];
-GL_EXPORT extern const char kDisableGLDrawingForTests[];
 GL_EXPORT extern const char kUseGpuInTests[];
 
+// These flags are used by the test harness code, not passed in by users.
+GL_EXPORT extern const char kDisableGLDrawingForTests[];
+GL_EXPORT extern const char kOverrideUseGLWithOSMesaForTests[];
+
 GL_EXPORT extern const char* kGLSwitchesCopiedFromGpuProcessHost[];
 GL_EXPORT extern const int kGLSwitchesCopiedFromGpuProcessHostNumSwitches;
 
diff --git a/ui/gl/surface_jni_headers.target.darwin-arm.mk b/ui/gl/surface_jni_headers.target.darwin-arm.mk
index 94de7b4..0b9088c 100644
--- a/ui/gl/surface_jni_headers.target.darwin-arm.mk
+++ b/ui/gl/surface_jni_headers.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/gl/surface_jni_headers.target.darwin-arm64.mk b/ui/gl/surface_jni_headers.target.darwin-arm64.mk
index a01ec88..6fa90da 100644
--- a/ui/gl/surface_jni_headers.target.darwin-arm64.mk
+++ b/ui/gl/surface_jni_headers.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gl/surface_jni_headers.target.darwin-mips.mk b/ui/gl/surface_jni_headers.target.darwin-mips.mk
index 5a50ce7..0812894 100644
--- a/ui/gl/surface_jni_headers.target.darwin-mips.mk
+++ b/ui/gl/surface_jni_headers.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gl/surface_jni_headers.target.darwin-x86.mk b/ui/gl/surface_jni_headers.target.darwin-x86.mk
index 12ac8fa..207ce81 100644
--- a/ui/gl/surface_jni_headers.target.darwin-x86.mk
+++ b/ui/gl/surface_jni_headers.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gl/surface_jni_headers.target.darwin-x86_64.mk b/ui/gl/surface_jni_headers.target.darwin-x86_64.mk
index 8d326cf..4481a94 100644
--- a/ui/gl/surface_jni_headers.target.darwin-x86_64.mk
+++ b/ui/gl/surface_jni_headers.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gl/surface_jni_headers.target.linux-arm.mk b/ui/gl/surface_jni_headers.target.linux-arm.mk
index 94de7b4..0b9088c 100644
--- a/ui/gl/surface_jni_headers.target.linux-arm.mk
+++ b/ui/gl/surface_jni_headers.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/ui/gl/surface_jni_headers.target.linux-arm64.mk b/ui/gl/surface_jni_headers.target.linux-arm64.mk
index a01ec88..6fa90da 100644
--- a/ui/gl/surface_jni_headers.target.linux-arm64.mk
+++ b/ui/gl/surface_jni_headers.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gl/surface_jni_headers.target.linux-mips.mk b/ui/gl/surface_jni_headers.target.linux-mips.mk
index 5a50ce7..0812894 100644
--- a/ui/gl/surface_jni_headers.target.linux-mips.mk
+++ b/ui/gl/surface_jni_headers.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/gl/surface_jni_headers.target.linux-x86.mk b/ui/gl/surface_jni_headers.target.linux-x86.mk
index 12ac8fa..207ce81 100644
--- a/ui/gl/surface_jni_headers.target.linux-x86.mk
+++ b/ui/gl/surface_jni_headers.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/gl/surface_jni_headers.target.linux-x86_64.mk b/ui/gl/surface_jni_headers.target.linux-x86_64.mk
index 8d326cf..4481a94 100644
--- a/ui/gl/surface_jni_headers.target.linux-x86_64.mk
+++ b/ui/gl/surface_jni_headers.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/gl/jni/Surface_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/ui/keyboard/keyboard.gyp b/ui/keyboard/keyboard.gyp
index c4ca714..e780048 100644
--- a/ui/keyboard/keyboard.gyp
+++ b/ui/keyboard/keyboard.gyp
@@ -99,8 +99,7 @@
         'keyboard_controller_unittest.cc',
       ],
       'conditions': [
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and use_allocator!="none"', {
           'dependencies': [
             '<(DEPTH)/base/allocator/allocator.gyp:allocator',
           ],
diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc
index 1d84b50..0a2fd1f 100644
--- a/ui/keyboard/keyboard_controller.cc
+++ b/ui/keyboard/keyboard_controller.cc
@@ -201,6 +201,7 @@
     container_->RemoveObserver(this);
   if (input_method_)
     input_method_->RemoveObserver(this);
+  ResetWindowInsets();
 }
 
 // static
@@ -438,6 +439,17 @@
   }
 }
 
+void KeyboardController::ResetWindowInsets() {
+  const gfx::Insets insets;
+  scoped_ptr<content::RenderWidgetHostIterator> widgets(
+      content::RenderWidgetHost::GetRenderWidgetHosts());
+  while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
+    content::RenderWidgetHostView* view = widget->GetView();
+    if (view)
+      view->SetInsets(insets);
+  }
+}
+
 bool KeyboardController::WillHideKeyboard() const {
   return weak_factory_.HasWeakPtrs();
 }
diff --git a/ui/keyboard/keyboard_controller.h b/ui/keyboard/keyboard_controller.h
index 2eb6653..7bd8e2f 100644
--- a/ui/keyboard/keyboard_controller.h
+++ b/ui/keyboard/keyboard_controller.h
@@ -122,6 +122,9 @@
   // Show virtual keyboard immediately with animation.
   void ShowKeyboardInternal();
 
+  // Clears any insets on web content windows.
+  void ResetWindowInsets();
+
   // Returns true if keyboard is scheduled to hide.
   bool WillHideKeyboard() const;
 
diff --git a/ui/keyboard/keyboard_controller_proxy.cc b/ui/keyboard/keyboard_controller_proxy.cc
index 100b3f1..2ade09d 100644
--- a/ui/keyboard/keyboard_controller_proxy.cc
+++ b/ui/keyboard/keyboard_controller_proxy.cc
@@ -11,7 +11,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/common/bindings_policy.h"
 #include "ui/aura/layout_manager.h"
@@ -69,7 +68,7 @@
   }
 
   // Overridden from content::WebContentsObserver:
-  virtual void WebContentsDestroyed(content::WebContents* contents) OVERRIDE {
+  virtual void WebContentsDestroyed() OVERRIDE {
     delete this;
   }
 
@@ -122,7 +121,7 @@
     LoadContents(GetVirtualKeyboardUrl());
   }
 
-  return keyboard_contents_->GetView()->GetNativeView();
+  return keyboard_contents_->GetNativeView();
 }
 
 bool KeyboardControllerProxy::HasKeyboardWindow() const {
diff --git a/ui/keyboard/keyboard_resources.grd b/ui/keyboard/keyboard_resources.grd
index 36566ae..ffcbda5 100644
--- a/ui/keyboard/keyboard_resources.grd
+++ b/ui/keyboard/keyboard_resources.grd
@@ -33,9 +33,8 @@
       <include name="IDR_KEYBOARD_IMAGES_RELOAD" file="resources/images/reload.svg" type="BINDATA" />
       <include name="IDR_KEYBOARD_IMAGES_RETURN" file="resources/images/return.png" type="BINDATA" />
       <include name="IDR_KEYBOARD_IMAGES_RIGHT" file="resources/images/right.svg" type="BINDATA" />
-      <include name="IDR_KEYBOARD_IMAGES_SEARCH" file="resources/images/search.svg" type="BINDATA" />
-      <include name="IDR_KEYBOARD_IMAGES_SHIFT" file="resources/images/shift.svg" type="BINDATA" />
-      <include name="IDR_KEYBOARD_IMAGES_SHIFT_FILLED" file="resources/images/shift-filled.svg" type="BINDATA" />
+      <include name="IDR_KEYBOARD_IMAGES_SEARCH" file="resources/images/search.png" type="BINDATA" />
+      <include name="IDR_KEYBOARD_IMAGES_SHIFT" file="resources/images/shift.png" type="BINDATA" />
       <include name="IDR_KEYBOARD_IMAGES_SHUTDOWN" file="resources/images/shutdown.svg" type="BINDATA" />
       <include name="IDR_KEYBOARD_IMAGES_TAB" file="resources/images/tab.png" type="BINDATA" />
       <include name="IDR_KEYBOARD_IMAGES_UP" file="resources/images/up.svg" type="BINDATA" />
diff --git a/ui/keyboard/keyboard_util.cc b/ui/keyboard/keyboard_util.cc
index 0643c1c..1d9409b 100644
--- a/ui/keyboard/keyboard_util.cc
+++ b/ui/keyboard/keyboard_util.cc
@@ -298,9 +298,8 @@
     {"keyboard/images/reload.svg", IDR_KEYBOARD_IMAGES_RELOAD},
     {"keyboard/images/return.png", IDR_KEYBOARD_IMAGES_RETURN},
     {"keyboard/images/right.svg", IDR_KEYBOARD_IMAGES_RIGHT},
-    {"keyboard/images/search.svg", IDR_KEYBOARD_IMAGES_SEARCH},
-    {"keyboard/images/shift.svg", IDR_KEYBOARD_IMAGES_SHIFT},
-    {"keyboard/images/shift-filled.svg", IDR_KEYBOARD_IMAGES_SHIFT_FILLED},
+    {"keyboard/images/search.png", IDR_KEYBOARD_IMAGES_SEARCH},
+    {"keyboard/images/shift.png", IDR_KEYBOARD_IMAGES_SHIFT},
     {"keyboard/images/shutdown.svg", IDR_KEYBOARD_IMAGES_SHUTDOWN},
     {"keyboard/images/tab.png", IDR_KEYBOARD_IMAGES_TAB},
     {"keyboard/images/up.svg", IDR_KEYBOARD_IMAGES_UP},
diff --git a/ui/keyboard/resources/elements/kb-altkey-container.html b/ui/keyboard/resources/elements/kb-altkey-container.html
index 001fa80..8ed1dc5 100644
--- a/ui/keyboard/resources/elements/kb-altkey-container.html
+++ b/ui/keyboard/resources/elements/kb-altkey-container.html
@@ -10,7 +10,6 @@
     <style>
       :host {
         -webkit-box-flex: 1;
-        background-color: rgba(0, 0, 0, 0.6);
         bottom: 0;
         left: 0;
         position: absolute;
diff --git a/ui/keyboard/resources/elements/kb-altkey-set.html b/ui/keyboard/resources/elements/kb-altkey-set.html
index 65a175f..dd47179 100644
--- a/ui/keyboard/resources/elements/kb-altkey-set.html
+++ b/ui/keyboard/resources/elements/kb-altkey-set.html
@@ -4,11 +4,14 @@
   -- found in the LICENSE file.
   -->
 
-<polymer-element name="kb-altkey-set" attributes="offset char">
+<polymer-element name="kb-altkey-set" attributes="offset char"
+    on-pointerout="{{out}}">
   <template>
     <style>
       :host {
-         background-color: #848484;
+        -webkit-box-shadow: 0 0 12px 5px rgba(204, 204, 204, 0.65),
+            0 3px 4px 4px rgba(136, 136, 136, 0.65);
+         background-color: #ffffff;
          border-radius: 2px;
          display: -webkit-box;
          text-align: center;
diff --git a/ui/keyboard/resources/elements/kb-altkey-set.js b/ui/keyboard/resources/elements/kb-altkey-set.js
index 9679d9f..09e0ef7 100644
--- a/ui/keyboard/resources/elements/kb-altkey-set.js
+++ b/ui/keyboard/resources/elements/kb-altkey-set.js
@@ -4,4 +4,7 @@
 
 Polymer('kb-altkey-set', {
   offset: 0,
+  out: function(e) {
+    e.stopPropagation();
+  }
 });
diff --git a/ui/keyboard/resources/elements/kb-altkey.html b/ui/keyboard/resources/elements/kb-altkey.html
index 34ff0fe..1d4cc4e 100644
--- a/ui/keyboard/resources/elements/kb-altkey.html
+++ b/ui/keyboard/resources/elements/kb-altkey.html
@@ -18,7 +18,7 @@
       }
 
       :host(.active) {
-        background-color: #afafaf;
+        background-color: #dddddd
       }
 
       :host(:first-child) {
@@ -26,6 +26,10 @@
         border-bottom-left-radius: 2px;
       }
 
+      :host(:not(:first-child)) .key{
+        border-left: solid 2px #dddddd;
+      }
+
       :host(:last-child) {
         border-top-right-radius: 2px;
         border-bottom-right-radius: 2px;
@@ -33,7 +37,7 @@
 
       :host .key {
         bottom: 0;
-        color: #ffffff;
+        color: #666666;
         font-family: roboto-bold;
         font-weight: 100;
         height: 1.2em;
diff --git a/ui/keyboard/resources/elements/kb-key.html b/ui/keyboard/resources/elements/kb-key.html
index a7273fb..902eb3c 100644
--- a/ui/keyboard/resources/elements/kb-key.html
+++ b/ui/keyboard/resources/elements/kb-key.html
@@ -14,7 +14,7 @@
         border-style: solid;
         border-width: 0px 0px;
         color: #666666;
-        font-family: 'Droid Sans';
+        font-family: roboto-bold;
         font-weight: 100;
       }
 
@@ -53,13 +53,13 @@
         height: 30%;
       }
 
-      :host([image].search) .key {
-        height: 80%;
+      :host([image].tab) .key {
+        height: 40%;
       }
 
       :host .hint,
       :host([invert]) key {
-        color: #bbbbbb;
+        color: #bababa;
       }
 
       :host .hint {
@@ -69,6 +69,10 @@
         top: 5%;
       }
 
+      :host-context(.hide-hint-text) .hint {
+        display: none;
+      }
+
       :host([invert]) .hint {
         color: #666666;
       }
@@ -77,6 +81,10 @@
         font-size: 70%;
       }
 
+      :host(.dark.active) {
+        background-color: #cccccc;
+      }
+
       :host(.active) {
         background-color: #dddddd;
         background-size: cover;
diff --git a/ui/keyboard/resources/elements/kb-keyboard.js b/ui/keyboard/resources/elements/kb-keyboard.js
index 654bf38..5933271 100644
--- a/ui/keyboard/resources/elements/kb-keyboard.js
+++ b/ui/keyboard/resources/elements/kb-keyboard.js
@@ -424,7 +424,8 @@
       return;
     }
     // Triggers swipe hintText if it's a purely vertical swipe.
-    if (!(direction & (SwipeDirection.LEFT | SwipeDirection.RIGHT))) {
+    if (this.activeKeyset.flick &&
+        !(direction & (SwipeDirection.LEFT | SwipeDirection.RIGHT))) {
       // Check if event is relevant to us.
       if ((!detail.endSwipe) || (detail.isComplex))
         return;
diff --git a/ui/keyboard/resources/elements/kb-keyset.html b/ui/keyboard/resources/elements/kb-keyset.html
index 096f22d..9494064 100644
--- a/ui/keyboard/resources/elements/kb-keyset.html
+++ b/ui/keyboard/resources/elements/kb-keyset.html
@@ -4,8 +4,8 @@
   -- found in the LICENSE file.
   -->
 
-<polymer-element name="kb-keyset" attributes="align isDefault nextKeyset pitch
-    weightRight weightTop weightBottom" on-key-up="{{keyUp}}"
+<polymer-element name="kb-keyset" attributes="align flick isDefault nextKeyset
+    pitch weightRight weightTop weightBottom" on-key-up="{{keyUp}}"
     on-key-longpress="{{keyLongpress}}">
   <template>
     <style>
diff --git a/ui/keyboard/resources/elements/kb-keyset.js b/ui/keyboard/resources/elements/kb-keyset.js
index 1637764..60a0a01 100644
--- a/ui/keyboard/resources/elements/kb-keyset.js
+++ b/ui/keyboard/resources/elements/kb-keyset.js
@@ -4,6 +4,8 @@
 
 Polymer('kb-keyset', {
   align: "center",
+  // Propagate flick gestures to keys in this keyset.
+  flick: true,
   isDefault: false,
   nextKeyset: undefined,
   // Weight offsets for positioning the keyset.
diff --git a/ui/keyboard/resources/elements/kb-shift-key.html b/ui/keyboard/resources/elements/kb-shift-key.html
index 6f537d4..dca707a 100644
--- a/ui/keyboard/resources/elements/kb-shift-key.html
+++ b/ui/keyboard/resources/elements/kb-shift-key.html
@@ -5,8 +5,8 @@
   -->
 
 <polymer-element name="kb-shift-key" attributes="lowerCaseKeysetId
-    upperCaseKeysetId" class="shift dark" char="Shift" on-pointerout="{{out}}"
-    extends="kb-key">
+    upperCaseKeysetId" class="shift dark" char="Shift" image="shift.png"
+    on-pointerout="{{out}}" extends="kb-key">
   <template>
     <style>
       .shift-light-wrapper {
diff --git a/ui/keyboard/resources/images/down.svg b/ui/keyboard/resources/images/down.svg
index f83fdd0..5d9d928 100644
--- a/ui/keyboard/resources/images/down.svg
+++ b/ui/keyboard/resources/images/down.svg
@@ -24,4 +24,4 @@
          d="M 0,0 3.57,-3.57 7.199,0"
          inkscape:connector-curvature="0"
          id="path14"
-         style="fill:none;stroke:#666666;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g></svg>
+         style="fill:none;stroke:#555555;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g></svg>
diff --git a/ui/keyboard/resources/images/left.svg b/ui/keyboard/resources/images/left.svg
index 8c2e743..0780e94 100644
--- a/ui/keyboard/resources/images/left.svg
+++ b/ui/keyboard/resources/images/left.svg
@@ -24,4 +24,4 @@
          d="M 0,0 -3.57,-3.57 0,-7.199"
          inkscape:connector-curvature="0"
          id="path14"
-         style="fill:none;stroke:#666666;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g></svg>
+         style="fill:none;stroke:#555555;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g></svg>
diff --git a/ui/keyboard/resources/images/right.svg b/ui/keyboard/resources/images/right.svg
index 9417842..d79bfca 100644
--- a/ui/keyboard/resources/images/right.svg
+++ b/ui/keyboard/resources/images/right.svg
@@ -24,4 +24,4 @@
          d="M 0,0 3.57,3.57 0,7.199"
          inkscape:connector-curvature="0"
          id="path14"
-         style="fill:none;stroke:#666666;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g></svg>
+         style="fill:none;stroke:#555555;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g></svg>
diff --git a/ui/keyboard/resources/images/search.png b/ui/keyboard/resources/images/search.png
new file mode 100644
index 0000000..1e67e24
--- /dev/null
+++ b/ui/keyboard/resources/images/search.png
Binary files differ
diff --git a/ui/keyboard/resources/images/search.svg b/ui/keyboard/resources/images/search.svg
deleted file mode 100644
index 5a5a783..0000000
--- a/ui/keyboard/resources/images/search.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1"
-	 id="svg5959" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" sodipodi:docname="New document 8" inkscape:version="0.48.3.1 r9886"
-	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="48px" height="48px"
-	 viewBox="0 0 48 48" enable-background="new 0 0 48 48" xml:space="preserve">
-<sodipodi:namedview  inkscape:window-maximized="0" inkscape:window-y="566" inkscape:window-x="437" inkscape:document-units="px" inkscape:grid-bbox="true" inkscape:current-layer="layer1" inkscape:pageshadow="2" inkscape:window-height="401" inkscape:pageopacity="0.0" inkscape:window-width="534" showgrid="true" inkscape:cy="24" inkscape:cx="24" inkscape:zoom="7" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base">
-	</sodipodi:namedview>
-<g id="layer1" inkscape:groupmode="layer" inkscape:label="Layer 1">
-	<g id="g1682" transform="matrix(1.25,0,0,-1.25,36.051257,32.440573)">
-		<path id="path1684" inkscape:connector-curvature="0" fill="#666666" d="M0.114-0.8l-5.342,5.346h-1.102L-6.819,5.03
-			c2.267,2.885,2.064,6.957-0.52,9.551c-2.802,2.799-7.329,2.799-10.138,0c-2.786-2.809-2.788-7.338,0-10.139
-			c2.598-2.58,6.629-2.792,9.557-0.513l0.486-0.485V2.342l5.338-5.347c0.324-0.32,1.108-0.198,1.756,0.447
-			C0.307-1.908,0.441-1.126,0.114-0.8 M-8.772,5.897L-8.772,5.897h-0.02V5.878c-2.006-1.991-5.24-1.987-7.244,0.008
-			c-1.992,2.003-1.992,5.244,0,7.252c2.013,2,5.25,2,7.254,0C-6.784,11.13-6.784,7.899-8.772,5.897"/>
-	</g>
-</g>
-</svg>
diff --git a/ui/keyboard/resources/images/shift-filled.svg b/ui/keyboard/resources/images/shift-filled.svg
deleted file mode 100644
index a6a87bb..0000000
--- a/ui/keyboard/resources/images/shift-filled.svg
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1"
-	 id="svg6007" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" sodipodi:docname="New document 11" inkscape:version="0.48.3.1 r9886"
-	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="48px" height="48px"
-	 viewBox="0 0 48 48" enable-background="new 0 0 48 48" xml:space="preserve">
-<sodipodi:namedview  inkscape:window-maximized="0" inkscape:window-y="346" inkscape:window-x="391" inkscape:document-units="px" inkscape:grid-bbox="true" inkscape:current-layer="layer1" inkscape:pageshadow="2" inkscape:window-height="401" inkscape:pageopacity="0.0" inkscape:window-width="534" showgrid="true" inkscape:cy="24" inkscape:cx="24" inkscape:zoom="7" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base">
-	</sodipodi:namedview>
-<g id="layer1" inkscape:groupmode="layer" inkscape:label="Layer 1">
-	<g id="g1726" transform="matrix(1.25,0,0,-1.25,24.286964,10.049732)">
-		<path id="path1728" inkscape:connector-curvature="0" fill="#666666" d="M-0.229-0.686l-7.02-7.051l-7.021-7.054h8.134v-6.845
-			H5.256v6.845h8.555L6.795-7.736L-0.229-0.686z"/>
-	</g>
-</g>
-</svg>
diff --git a/ui/keyboard/resources/images/shift.png b/ui/keyboard/resources/images/shift.png
new file mode 100644
index 0000000..4458fda
--- /dev/null
+++ b/ui/keyboard/resources/images/shift.png
Binary files differ
diff --git a/ui/keyboard/resources/images/shift.svg b/ui/keyboard/resources/images/shift.svg
deleted file mode 100644
index 39f25d2..0000000
--- a/ui/keyboard/resources/images/shift.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1"
-	 id="svg6007" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" sodipodi:docname="New document 11" inkscape:version="0.48.3.1 r9886"
-	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="48px" height="48px"
-	 viewBox="0 0 48 48" enable-background="new 0 0 48 48" xml:space="preserve">
-<sodipodi:namedview  inkscape:window-maximized="0" inkscape:window-y="346" inkscape:window-x="391" inkscape:document-units="px" inkscape:grid-bbox="true" inkscape:current-layer="layer1" inkscape:pageshadow="2" inkscape:window-height="401" inkscape:pageopacity="0.0" inkscape:window-width="534" showgrid="true" inkscape:cy="24" inkscape:cx="24" inkscape:zoom="7" borderopacity="1.0" bordercolor="#666666" pagecolor="#ffffff" id="base">
-	</sodipodi:namedview>
-<g id="layer1" inkscape:groupmode="layer" inkscape:label="Layer 1">
-	<g id="g1726" transform="matrix(1.25,0,0,-1.25,24.286964,10.049732)">
-		<path id="path1728" inkscape:connector-curvature="0" fill="#666666" d="M-0.229-0.686l-7.02-7.051l-7.021-7.054h8.134v-6.845
-			H5.256v6.845h8.555L6.795-7.736L-0.229-0.686z M-0.229-3.873l5.428-5.45l3.198-3.216H5.256h-2.25v-2.25v-4.595h-6.891v4.595v2.25
-			h-2.25h-2.72l3.201,3.215L-0.229-3.873z"/>
-	</g>
-</g>
-</svg>
diff --git a/ui/keyboard/resources/images/tab.png b/ui/keyboard/resources/images/tab.png
index 4b2fe5d..49745de 100644
--- a/ui/keyboard/resources/images/tab.png
+++ b/ui/keyboard/resources/images/tab.png
Binary files differ
diff --git a/ui/keyboard/resources/images/up.svg b/ui/keyboard/resources/images/up.svg
index 696f92f..408e062 100644
--- a/ui/keyboard/resources/images/up.svg
+++ b/ui/keyboard/resources/images/up.svg
@@ -24,4 +24,4 @@
          d="M 0,0 -3.57,3.57 -7.199,0"
          inkscape:connector-curvature="0"
          id="path14"
-         style="fill:none;stroke:#666666;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g></svg>
+         style="fill:none;stroke:#555555;stroke-width:1.60000002;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g></svg>
diff --git a/ui/keyboard/resources/layouts/qwerty.html b/ui/keyboard/resources/layouts/qwerty.html
index 0c65162..3c357ca 100644
--- a/ui/keyboard/resources/layouts/qwerty.html
+++ b/ui/keyboard/resources/layouts/qwerty.html
@@ -5,10 +5,9 @@
   -->
 
 
-<kb-keyset id="qwerty-upper" pitch="10 20">
-  <kb-row>
-    <kb-key-sequence keys="QWERTYUIOP" hintTexts="1234567890">
-    </kb-key-sequence>
+<kb-keyset id="qwerty-upper" flick=false pitch="10 20">
+  <kb-row class="hide-hint-text">
+    <kb-key-sequence keys="QWERTYUIOP" hintTexts="1234567890"></kb-key-sequence>
     <kb-key class="dark" char="&#x0008;" image="backspace.png"
         repeat sound="keypress-delete" stretch weight="110"></kb-key>
   </kb-row>
@@ -39,10 +38,9 @@
   </kb-altkey-container>
 </kb-keyset>
 
-<kb-keyset id="qwerty-lower" isDefault=true pitch="10 20">
-  <kb-row>
-    <kb-key-sequence keys="qwertyuiop" hintTexts="1234567890">
-    </kb-key-sequence>
+<kb-keyset id="qwerty-lower" flick=false isDefault=true pitch="10 20">
+  <kb-row class="hide-hint-text">
+    <kb-key-sequence keys="qwertyuiop" hintTexts="1234567890"></kb-key-sequence>
     <kb-key class="dark" char="&#x0008;" repeat stretch align="right"
         image="backspace.png" sound="keypress-delete" weight="110"></kb-key>
   </kb-row>
diff --git a/ui/keyboard/resources/layouts/system-qwerty.html b/ui/keyboard/resources/layouts/system-qwerty.html
index 983d7ac..ae301c7 100644
--- a/ui/keyboard/resources/layouts/system-qwerty.html
+++ b/ui/keyboard/resources/layouts/system-qwerty.html
@@ -13,14 +13,14 @@
     </kb-key>
   </kb-row>
   <kb-row align="left">
-    <kb-key class="dark" char="&#x0009;" align="center"
+    <kb-key class="dark tab" char="&#x0009;" align="center"
         image="tab.png" weight="155"></kb-key>
     <kb-key-sequence keys="QWERTYUIOP"></kb-key-sequence>
     <kb-key-sequence invert=true keys="[]\"
         hintTexts="{}|"></kb-key-sequence>
   </kb-row>
   <kb-row>
-    <kb-key class="search dark" char="Search" image='search'
+    <kb-key class="search dark" char="Search" image='search.png'
         weight="210"> </kb-key>
     <kb-key-sequence keys="ASDFGHJKL"></kb-key-sequence>
     <kb-key-sequence invert=true keys=";&apos;" hintTexts=':"'>
@@ -67,13 +67,13 @@
         align="right"></kb-key>
   </kb-row>
   <kb-row align="left">
-    <kb-key class="dark" char="&#x0009;" align="center"
+    <kb-key class="dark tab" char="&#x0009;" align="center"
         image="tab.png" weight="155"></kb-key>
     <kb-key-sequence keys="qwertyuiop"></kb-key-sequence>
     <kb-key-sequence keys="[]\" hintTexts="{}|"></kb-key-sequence>
   </kb-row>
   <kb-row>
-    <kb-key class="search dark" char="Search" image='search'
+    <kb-key class="search dark" char="Search" image='search.png'
         weight="210"></kb-key>
     <kb-key-sequence keys="asdfghjkl"></kb-key-sequence>
     <kb-key-sequence keys=";&apos;" hintTexts=':"'></kb-key-sequence>
diff --git a/ui/keyboard/resources/main.css b/ui/keyboard/resources/main.css
index 974a634..dfea91e 100644
--- a/ui/keyboard/resources/main.css
+++ b/ui/keyboard/resources/main.css
@@ -14,22 +14,16 @@
  * shadow dom.
  */
 kb-keyboard.ctrl-active kb-modifier-key[char=Ctrl],
-kb-keyboard.alt-active kb-modifier-key[char=Alt] {
-  background-color: #bbbbbb;
-}
-
-kb-keyboard[keyset="upper"] kb-shift-key.dark /deep/ .key {
-  background-image: url('images/shift-filled.svg');
-}
-
-kb-keyboard[keyset="lower"] kb-shift-key /deep/ .key{
-  background-image: url('images/shift.svg');
+kb-keyboard.alt-active kb-modifier-key[char=Alt],
+kb-keyboard.caps-locked kb-shift-key.dark {
+  -webkit-box-shadow: inset 0 0 3px 2px #aaaaaa;
+  background-color: #cccccc;
 }
 
 /**
 * Controls whether the shift key should be highlighted or not.
 */
-kb-keyboard.caps-locked kb-shift-key.dark /deep/
+kb-keyboard[keyset="upper"] kb-shift-key.dark /deep/
     .shift-light {
     background-color: #4285f4;
 }
diff --git a/ui/message_center/cocoa/notification_controller.mm b/ui/message_center/cocoa/notification_controller.mm
index a6ab485..369b121 100644
--- a/ui/message_center/cocoa/notification_controller.mm
+++ b/ui/message_center/cocoa/notification_controller.mm
@@ -250,10 +250,18 @@
 // Returns the wrapped text that could fit within the content rect with not
 // more than the given number of lines. The wrapped text would be painted using
 // the given font. The Ellipsis could be added at the end of the last line if
-// it is too long.
+// it is too long. Outputs the number of lines computed in the actualLines
+// parameter.
+- (base::string16)wrapText:(const base::string16&)text
+                   forFont:(NSFont*)font
+          maxNumberOfLines:(size_t)lines
+               actualLines:(size_t*)actualLines;
+
+// Same as above without outputting the lines formatted.
 - (base::string16)wrapText:(const base::string16&)text
                    forFont:(NSFont*)font
           maxNumberOfLines:(size_t)lines;
+
 @end
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -343,22 +351,34 @@
       message_center::kTextTopPadding - messageBottomGap - contextMessageTopGap;
 
   // Set the title and recalculate the frame.
-  int titleLineLimit = notification_->message().empty()
-                           ? message_center::kTitleNoMessageLineLimit
-                           : message_center::kTitleLineLimit;
+  size_t actualTitleLines = 0;
   [title_ setString:base::SysUTF16ToNSString(
       [self wrapText:notification_->title()
-             forFont:[title_ font]
-       maxNumberOfLines:titleLineLimit])];
+                forFont:[title_ font]
+       maxNumberOfLines:message_center::kMaxTitleLines
+            actualLines:&actualTitleLines])];
   [title_ sizeToFit];
   NSRect titleFrame = [title_ frame];
   titleFrame.origin.y = NSMaxY(rootFrame) - titlePadding - NSHeight(titleFrame);
 
+  // The number of message lines depends on the number of context message lines
+  // and the lines within the title, and whether an image exists.
+  int messageLineLimit = message_center::kMessageExpandedLineLimit;
+  if (actualTitleLines > 1)
+    messageLineLimit -= (actualTitleLines - 1) * 2;
+  if (!notification_->image().IsEmpty()) {
+    messageLineLimit /= 2;
+    if (!notification_->context_message().empty())
+      messageLineLimit -= message_center::kContextMessageLineLimit;
+  }
+  if (messageLineLimit < 0)
+    messageLineLimit = 0;
+
   // Set the message and recalculate the frame.
   [message_ setString:base::SysUTF16ToNSString(
       [self wrapText:notification_->message()
              forFont:[message_ font]
-       maxNumberOfLines:message_center::kMessageExpandedLineLimit])];
+      maxNumberOfLines:messageLineLimit])];
   [message_ sizeToFit];
   NSRect messageFrame = [message_ frame];
 
@@ -790,9 +810,11 @@
 
 - (base::string16)wrapText:(const base::string16&)text
                    forFont:(NSFont*)nsfont
-    maxNumberOfLines:(size_t)lines {
-  if (text.empty())
-    return text;
+          maxNumberOfLines:(size_t)lines
+               actualLines:(size_t*)actualLines {
+  *actualLines = 0;
+  if (text.empty() || lines == 0)
+    return base::string16();
   gfx::FontList font_list((gfx::Font(nsfont)));
   int width = NSWidth([self currentContentRect]);
   int height = (lines + 1) * font_list.GetHeight();
@@ -816,7 +838,18 @@
     wrapped.push_back(last);
   }
 
+  *actualLines = wrapped.size();
   return lines == 1 ? wrapped[0] : JoinString(wrapped, '\n');
 }
 
+- (base::string16)wrapText:(const base::string16&)text
+                   forFont:(NSFont*)nsfont
+          maxNumberOfLines:(size_t)lines {
+  size_t unused;
+  return [self wrapText:text
+                forFont:nsfont
+       maxNumberOfLines:lines
+            actualLines:&unused];
+}
+
 @end
diff --git a/ui/message_center/cocoa/notification_controller_unittest.mm b/ui/message_center/cocoa/notification_controller_unittest.mm
index 6f50e91..91d1b1b 100644
--- a/ui/message_center/cocoa/notification_controller_unittest.mm
+++ b/ui/message_center/cocoa/notification_controller_unittest.mm
@@ -9,6 +9,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "third_party/skia/include/core/SkBitmap.h"
 #import "ui/base/cocoa/hover_image_button.h"
 #import "ui/gfx/test/ui_cocoa_test_helper.h"
 #include "ui/message_center/fake_message_center.h"
@@ -358,4 +359,83 @@
   EXPECT_FALSE([[controller contextMessageView] isHidden]);
 }
 
+TEST_F(NotificationControllerTest, MessageSize) {
+  message_center::RichNotificationData data;
+  std::string id("id");
+  NotifierId notifier_id(NotifierId::APPLICATION, "notifier");
+  scoped_ptr<Notification> notification(new Notification(
+      NOTIFICATION_TYPE_BASE_FORMAT,
+      id,
+      base::UTF8ToUTF16(""),
+      ASCIIToUTF16("And\neven\nthe\nmessage is long.\nThis sure is wordy"),
+      gfx::Image(),
+      base::string16() /* display_source */,
+      notifier_id,
+      data,
+      NULL /* delegate */));
+
+  base::scoped_nsobject<MCNotificationController> controller(
+      [[MCNotificationController alloc] initWithNotification:notification.get()
+                                               messageCenter:NULL]);
+
+  // Set up the default layout.
+  [controller view];
+
+  auto compute_message_lines = ^{
+      NSString* string = [[[controller messageView] textStorage] string];
+      unsigned numberOfLines, index, stringLength = [string length];
+      for (index = 0, numberOfLines = 0; index < stringLength; numberOfLines++)
+        index = NSMaxRange([string lineRangeForRange:NSMakeRange(index, 0)]);
+
+      return numberOfLines;
+  };
+
+  // Message and no title: 5 lines.
+  EXPECT_EQ(5u, compute_message_lines());
+
+  // Message and one line title: 5 lines.
+  notification->set_title(ASCIIToUTF16("one line"));
+  [controller updateNotification:notification.get()];
+  EXPECT_EQ(5u, compute_message_lines());
+
+  // Message and two line title: 3 lines.
+  notification->set_title(ASCIIToUTF16("two\nlines"));
+  [controller updateNotification:notification.get()];
+  EXPECT_EQ(3u, compute_message_lines());
+
+  // Message, image and no title: 2 lines.
+  SkBitmap bitmap;
+  bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
+  bitmap.allocPixels();
+  bitmap.eraseColor(SK_ColorGREEN);
+  notification->set_title(ASCIIToUTF16(""));
+  notification->set_image(gfx::Image::CreateFrom1xBitmap(bitmap));
+  [controller updateNotification:notification.get()];
+  EXPECT_EQ(2u, compute_message_lines());
+
+  // Message, image and one line title: 2 lines.
+  notification->set_title(ASCIIToUTF16("one line"));
+  [controller updateNotification:notification.get()];
+  EXPECT_EQ(2u, compute_message_lines());
+
+  // Message, image and two line title: 1 lines.
+  notification->set_title(ASCIIToUTF16("two\nlines"));
+  [controller updateNotification:notification.get()];
+  EXPECT_EQ(1u, compute_message_lines());
+
+  // Same as above, but context message takes away from message lines.
+  notification->set_context_message(base::UTF8ToUTF16("foo"));
+  notification->set_title(ASCIIToUTF16(""));
+  [controller updateNotification:notification.get()];
+  EXPECT_EQ(1u, compute_message_lines());
+
+  notification->set_title(ASCIIToUTF16("one line"));
+  [controller updateNotification:notification.get()];
+  EXPECT_EQ(1u, compute_message_lines());
+
+  notification->set_title(ASCIIToUTF16("two\nlines"));
+  [controller updateNotification:notification.get()];
+  EXPECT_EQ(0u, compute_message_lines());
+}
+
 }  // namespace message_center
diff --git a/ui/message_center/cocoa/popup_collection.mm b/ui/message_center/cocoa/popup_collection.mm
index fb22019..3d89012 100644
--- a/ui/message_center/cocoa/popup_collection.mm
+++ b/ui/message_center/cocoa/popup_collection.mm
@@ -191,7 +191,8 @@
     bounds.origin.y = y;
     [popup showWithAnimation:bounds];
     [popups_ addObject:popup];
-    messageCenter_->DisplayedNotification(notification->id());
+    messageCenter_->DisplayedNotification(
+        notification->id(), message_center::DISPLAY_SOURCE_POPUP);
     return YES;
   }
 
diff --git a/ui/message_center/cocoa/tray_view_controller.mm b/ui/message_center/cocoa/tray_view_controller.mm
index 2458457..6743051 100644
--- a/ui/message_center/cocoa/tray_view_controller.mm
+++ b/ui/message_center/cocoa/tray_view_controller.mm
@@ -56,7 +56,7 @@
 // Step 1: hide all notifications pending removal with fade-out animation.
 - (void)hideNotificationsPendingRemoval;
 
-// Step 2: move up all remaining notfications to take over the available space
+// Step 2: move up all remaining notifications to take over the available space
 // due to hiding notifications. The scroll view and the window remain unchanged.
 - (void)moveUpRemainingNotifications;
 
@@ -67,7 +67,7 @@
 // "Clear All" is clicked.
 - (void)clearOneNotification;
 
-// When all visible notificatons slide out, re-enable controls and remove
+// When all visible notifications slide out, re-enable controls and remove
 // notifications from the message center.
 - (void)finalizeClearAll;
 
@@ -205,7 +205,8 @@
       [[scrollView_ documentView] addSubview:[controller view]];
 
       [notifications_ addObject:controller];  // Transfer ownership.
-      messageCenter_->DisplayedNotification((*it)->id());
+      messageCenter_->DisplayedNotification(
+          (*it)->id(), message_center::DISPLAY_SOURCE_MESSAGE_CENTER);
 
       notification = controller.get();
     } else {
diff --git a/ui/message_center/fake_message_center.cc b/ui/message_center/fake_message_center.cc
index c34eb2c..45bf1b0 100644
--- a/ui/message_center/fake_message_center.cc
+++ b/ui/message_center/fake_message_center.cc
@@ -106,7 +106,9 @@
                                                bool mark_notification_as_read) {
 }
 
-void FakeMessageCenter::DisplayedNotification(const std::string& id) {
+void FakeMessageCenter::DisplayedNotification(
+    const std::string& id,
+    const DisplaySource source) {
 }
 
 void FakeMessageCenter::SetNotifierSettingsProvider(
diff --git a/ui/message_center/fake_message_center.h b/ui/message_center/fake_message_center.h
index e81ac37..da4051b 100644
--- a/ui/message_center/fake_message_center.h
+++ b/ui/message_center/fake_message_center.h
@@ -56,7 +56,9 @@
                                          int button_index) OVERRIDE;
   virtual void MarkSinglePopupAsShown(const std::string& id,
                                       bool mark_notification_as_read) OVERRIDE;
-  virtual void DisplayedNotification(const std::string& id) OVERRIDE;
+  virtual void DisplayedNotification(
+      const std::string& id,
+      const DisplaySource source) OVERRIDE;
   virtual void SetNotifierSettingsProvider(
       NotifierSettingsProvider* provider) OVERRIDE;
   virtual NotifierSettingsProvider* GetNotifierSettingsProvider() OVERRIDE;
diff --git a/ui/message_center/message_center.gyp b/ui/message_center/message_center.gyp
index 8812eb9..3efce08 100644
--- a/ui/message_center/message_center.gyp
+++ b/ui/message_center/message_center.gyp
@@ -224,6 +224,7 @@
             'views/bounded_label_unittest.cc',
             'views/message_center_view_unittest.cc',
             'views/message_popup_collection_unittest.cc',
+            'views/notification_view_unittest.cc',
             'views/notifier_settings_view_unittest.cc',
           ],
         }],
@@ -235,8 +236,7 @@
           ],
         }],
         # See http://crbug.com/162998#c4 for why this is needed.
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and use_allocator!="none"', {
           'dependencies': [
             '../../base/allocator/allocator.gyp:allocator',
           ],
diff --git a/ui/message_center/message_center.h b/ui/message_center/message_center.h
index 6ad648a..12ee38e 100644
--- a/ui/message_center/message_center.h
+++ b/ui/message_center/message_center.h
@@ -65,7 +65,7 @@
   // VISIBILITY_TRANSIENT or VISIBILITY_SETTINGS.
   virtual NotificationList::PopupNotifications GetPopupNotifications() = 0;
 
-  // Management of NotificaitonBlockers.
+  // Management of NotificationBlockers.
   virtual void AddNotificationBlocker(NotificationBlocker* blocker) = 0;
   virtual void RemoveNotificationBlocker(NotificationBlocker* blocker) = 0;
 
@@ -125,7 +125,9 @@
   // This should be called by UI classes when a notification is first displayed
   // to the user, in order to decrement the unread_count for the tray, and to
   // notify observers that the notification is visible.
-  virtual void DisplayedNotification(const std::string& id) = 0;
+  virtual void DisplayedNotification(
+      const std::string& id,
+      const DisplaySource source) = 0;
 
   // Setter/getter of notifier settings provider. This will be a weak reference.
   // This should be set at the initialization process. The getter may return
diff --git a/ui/message_center/message_center_impl.cc b/ui/message_center/message_center_impl.cc
index 4885aa7..c45cb94 100644
--- a/ui/message_center/message_center_impl.cc
+++ b/ui/message_center/message_center_impl.cc
@@ -354,7 +354,9 @@
   message_center_->MarkSinglePopupAsShown(id, false);
 }
 
-void PopupTimersController::OnNotificationDisplayed(const std::string& id) {
+void PopupTimersController::OnNotificationDisplayed(
+    const std::string& id,
+    const DisplaySource source) {
   OnNotificationUpdated(id);
 }
 
@@ -804,7 +806,9 @@
       MessageCenterObserver, observer_list_, OnNotificationUpdated(id));
 }
 
-void MessageCenterImpl::DisplayedNotification(const std::string& id) {
+void MessageCenterImpl::DisplayedNotification(
+    const std::string& id,
+    const DisplaySource source) {
   if (!HasNotification(id))
     return;
 
@@ -816,7 +820,9 @@
   if (delegate.get())
     delegate->Display();
   FOR_EACH_OBSERVER(
-      MessageCenterObserver, observer_list_, OnNotificationDisplayed(id));
+      MessageCenterObserver,
+      observer_list_,
+      OnNotificationDisplayed(id, source));
 }
 
 void MessageCenterImpl::SetNotifierSettingsProvider(
diff --git a/ui/message_center/message_center_impl.h b/ui/message_center/message_center_impl.h
index ae1d05b..765f5ac 100644
--- a/ui/message_center/message_center_impl.h
+++ b/ui/message_center/message_center_impl.h
@@ -85,7 +85,9 @@
   virtual ~PopupTimersController();
 
   // MessageCenterObserver implementation.
-  virtual void OnNotificationDisplayed(const std::string& id) OVERRIDE;
+  virtual void OnNotificationDisplayed(
+      const std::string& id,
+      const DisplaySource source) OVERRIDE;
   virtual void OnNotificationUpdated(const std::string& id) OVERRIDE;
   virtual void OnNotificationRemoved(const std::string& id, bool by_user)
       OVERRIDE;
@@ -177,7 +179,9 @@
                                          int button_index) OVERRIDE;
   virtual void MarkSinglePopupAsShown(const std::string& id,
                                       bool mark_notification_as_read) OVERRIDE;
-  virtual void DisplayedNotification(const std::string& id) OVERRIDE;
+  virtual void DisplayedNotification(
+      const std::string& id,
+      const DisplaySource source) OVERRIDE;
   virtual void SetNotifierSettingsProvider(
       NotifierSettingsProvider* provider) OVERRIDE;
   virtual NotifierSettingsProvider* GetNotifierSettingsProvider() OVERRIDE;
diff --git a/ui/message_center/message_center_impl_unittest.cc b/ui/message_center/message_center_impl_unittest.cc
index 1e8ab41..fcd0db7 100644
--- a/ui/message_center/message_center_impl_unittest.cc
+++ b/ui/message_center/message_center_impl_unittest.cc
@@ -743,7 +743,8 @@
       message_center()->GetVisibleNotifications();
   for (NotificationList::Notifications::const_iterator iter =
            notifications.begin(); iter != notifications.end(); ++iter) {
-    message_center()->DisplayedNotification((*iter)->id());
+    message_center()->DisplayedNotification(
+        (*iter)->id(), message_center::DISPLAY_SOURCE_MESSAGE_CENTER);
   }
   EXPECT_EQ(0u, message_center()->UnreadNotificationCount());
 
diff --git a/ui/message_center/message_center_observer.h b/ui/message_center/message_center_observer.h
index 901b60e..202430d 100644
--- a/ui/message_center/message_center_observer.h
+++ b/ui/message_center/message_center_observer.h
@@ -42,7 +42,9 @@
 
   // Called when the notification associated with |notification_id| is actually
   // displayed.
-  virtual void OnNotificationDisplayed(const std::string& notification_id) {}
+  virtual void OnNotificationDisplayed(
+      const std::string& notification_id,
+      const DisplaySource source) {}
 
   // Called when the notification center is shown or hidden.
   virtual void OnCenterVisibilityChanged(Visibility visibility) {}
diff --git a/ui/message_center/message_center_style.h b/ui/message_center/message_center_style.h
index 0ba1829..738464c 100644
--- a/ui/message_center/message_center_style.h
+++ b/ui/message_center/message_center_style.h
@@ -112,8 +112,7 @@
 const SkColor kProgressBarSliceColor = SkColorSetRGB(120, 120, 120);
 
 // Line limits.
-const int kTitleLineLimit = 1;
-const int kTitleNoMessageLineLimit = 2;
+const int kMaxTitleLines = 2;
 const int kMessageCollapsedLineLimit = 2;
 const int kMessageExpandedLineLimit = 5;
 const int kContextMessageLineLimit = 1;
diff --git a/ui/message_center/message_center_tray.cc b/ui/message_center/message_center_tray.cc
index fff1fd2..671b979 100644
--- a/ui/message_center/message_center_tray.cc
+++ b/ui/message_center/message_center_tray.cc
@@ -233,7 +233,8 @@
 }
 
 void MessageCenterTray::OnNotificationDisplayed(
-    const std::string& notification_id) {
+    const std::string& notification_id,
+    const DisplaySource source) {
   NotifyMessageCenterTrayChanged();
 }
 
diff --git a/ui/message_center/message_center_tray.h b/ui/message_center/message_center_tray.h
index 278eb2e..4539417 100644
--- a/ui/message_center/message_center_tray.h
+++ b/ui/message_center/message_center_tray.h
@@ -85,7 +85,8 @@
       const std::string& notification_id,
       int button_index) OVERRIDE;
   virtual void OnNotificationDisplayed(
-      const std::string& notification_id) OVERRIDE;
+      const std::string& notification_id,
+      const DisplaySource source) OVERRIDE;
   virtual void OnQuietModeChanged(bool in_quiet_mode) OVERRIDE;
   virtual void OnBlockingStateChanged(NotificationBlocker* blocker) OVERRIDE;
 
diff --git a/ui/message_center/message_center_types.h b/ui/message_center/message_center_types.h
index 4cfe68e..32f0f13 100644
--- a/ui/message_center/message_center_types.h
+++ b/ui/message_center/message_center_types.h
@@ -13,7 +13,15 @@
   // When the message center view is being displayed.
   VISIBILITY_MESSAGE_CENTER,
   // When the settings view is being displayed.
-  VISIBILITY_SETTINGS
+  VISIBILITY_SETTINGS,
+};
+
+// Identifies the source of a displayed notification.
+enum DisplaySource {
+  // Displayed from the message center.
+  DISPLAY_SOURCE_MESSAGE_CENTER = 0,
+  // Displayed as a popup.
+  DISPLAY_SOURCE_POPUP,
 };
 
 }  // namespace message_center
diff --git a/ui/message_center/views/message_center_button_bar.cc b/ui/message_center/views/message_center_button_bar.cc
index 88e7eaa..a85fd18 100644
--- a/ui/message_center/views/message_center_button_bar.cc
+++ b/ui/message_center/views/message_center_button_bar.cc
@@ -13,6 +13,7 @@
 #include "ui/gfx/text_constants.h"
 #include "ui/message_center/message_center.h"
 #include "ui/message_center/message_center_style.h"
+#include "ui/message_center/message_center_tray.h"
 #include "ui/message_center/notifier_settings.h"
 #include "ui/message_center/views/message_center_view.h"
 #include "ui/views/controls/button/button.h"
@@ -93,6 +94,9 @@
     bool settings_initially_visible)
     : message_center_view_(message_center_view),
       message_center_(message_center),
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+      close_bubble_button_(NULL),
+#endif
       title_arrow_(NULL),
       notification_label_(NULL),
       button_container_(NULL),
@@ -166,6 +170,20 @@
                                    IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL);
   button_container_->AddChildView(settings_button_);
 
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+  close_bubble_button_ = new views::ImageButton(this);
+  close_bubble_button_->SetImage(
+      views::Button::STATE_NORMAL,
+      resource_bundle.GetImageSkiaNamed(IDR_NOTIFICATION_BUBBLE_CLOSE));
+  close_bubble_button_->SetImage(
+      views::Button::STATE_HOVERED,
+      resource_bundle.GetImageSkiaNamed(IDR_NOTIFICATION_BUBBLE_CLOSE_HOVER));
+  close_bubble_button_->SetImage(
+      views::Button::STATE_PRESSED,
+      resource_bundle.GetImageSkiaNamed(IDR_NOTIFICATION_BUBBLE_CLOSE_PRESSED));
+  AddChildView(close_bubble_button_);
+#endif
+
   SetCloseAllButtonEnabled(!settings_initially_visible);
   SetBackArrowVisible(settings_initially_visible);
   ViewVisibilityChanged();
@@ -214,11 +232,24 @@
                     0,
                     0);
 
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+  // The close-bubble button.
+  column->AddColumn(views::GridLayout::LEADING,
+                    views::GridLayout::LEADING,
+                    0.0f,
+                    views::GridLayout::USE_PREF,
+                    0,
+                    0);
+#endif
+
   layout->StartRow(0, 0);
   if (title_arrow_->visible())
     layout->AddView(title_arrow_);
   layout->AddView(notification_label_);
   layout->AddView(button_container_);
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+  layout->AddView(close_bubble_button_);
+#endif
 }
 
 MessageCenterButtonBar::~MessageCenterButtonBar() {}
@@ -259,6 +290,10 @@
     else
       message_center()->EnterQuietModeWithExpire(base::TimeDelta::FromDays(1));
     quiet_mode_button_->SetToggled(message_center()->IsQuietMode());
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+  } else if (sender == close_bubble_button_) {
+    message_center_view()->tray()->HideMessageCenterBubble();
+#endif
   } else {
     NOTREACHED();
   }
diff --git a/ui/message_center/views/message_center_button_bar.h b/ui/message_center/views/message_center_button_bar.h
index 8190e3e..524a01f 100644
--- a/ui/message_center/views/message_center_button_bar.h
+++ b/ui/message_center/views/message_center_button_bar.h
@@ -63,6 +63,15 @@
   MessageCenterView* message_center_view_;  // Weak reference.
   MessageCenter* message_center_;           // Weak reference.
 
+  // |close_bubble_button_| closes the message center bubble. This is required
+  // for desktop Linux because the status icon doesn't toggle the bubble, and
+  // close-on-deactivation is off. This is a tentative solution. Once pkotwicz
+  // Fixes the problem of focus-follow-mouse, close-on-deactivation will be
+  // back and this field will be removed. See crbug.com/319516.
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+  views::ImageButton* close_bubble_button_;
+#endif
+
   // Sub-views of the button bar.
   NotificationCenterButton* title_arrow_;
   views::Label* notification_label_;
diff --git a/ui/message_center/views/message_center_view.cc b/ui/message_center/views/message_center_view.cc
index 27b4978..a290d7a 100644
--- a/ui/message_center/views/message_center_view.cc
+++ b/ui/message_center/views/message_center_view.cc
@@ -620,7 +620,8 @@
            notifications.begin(); iter != notifications.end(); ++iter) {
     AddNotificationAt(*(*iter), index++);
 
-    message_center_->DisplayedNotification((*iter)->id());
+    message_center_->DisplayedNotification(
+        (*iter)->id(), message_center::DISPLAY_SOURCE_MESSAGE_CENTER);
     if (notification_views_.size() >= kMaxVisibleMessageCenterNotifications)
       break;
   }
diff --git a/ui/message_center/views/message_center_view.h b/ui/message_center/views/message_center_view.h
index 8a870ee..25dfdee 100644
--- a/ui/message_center/views/message_center_view.h
+++ b/ui/message_center/views/message_center_view.h
@@ -61,6 +61,7 @@
   void SetSettingsVisible(bool visible);
   void OnSettingsChanged();
   bool settings_visible() const { return settings_visible_; }
+  MessageCenterTray* tray() { return tray_; }
 
   void SetIsClosing(bool is_closing);
 
@@ -104,7 +105,7 @@
   MessageCenter* message_center_;  // Weak reference.
   MessageCenterTray* tray_;  // Weak reference.
 
-  // Map notification_id->NotificationView*. It contains all NotificaitonViews
+  // Map notification_id->NotificationView*. It contains all NotificationViews
   // currently displayed in MessageCenter.
   typedef std::map<std::string, NotificationView*> NotificationViewsMap;
   NotificationViewsMap notification_views_;  // Weak.
diff --git a/ui/message_center/views/message_popup_collection.cc b/ui/message_center/views/message_popup_collection.cc
index f5103a9..fb4cef9 100644
--- a/ui/message_center/views/message_popup_collection.cc
+++ b/ui/message_center/views/message_popup_collection.cc
@@ -186,7 +186,8 @@
           toast, ui::AX_EVENT_ALERT);
     }
 
-    message_center_->DisplayedNotification((*iter)->id());
+    message_center_->DisplayedNotification(
+        (*iter)->id(), message_center::DISPLAY_SOURCE_POPUP);
   }
 }
 
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc
index 671b420..5109a19 100644
--- a/ui/message_center/views/notification_view.cc
+++ b/ui/message_center/views/notification_view.cc
@@ -318,15 +318,13 @@
     const gfx::FontList& font_list =
         default_label_font_list.DeriveWithSizeDelta(2);
     int padding = kTitleLineHeight - font_list.GetHeight();
-    int title_lines = notification.message().empty() ? kTitleNoMessageLineLimit
-                                                     : kTitleLineLimit;
     int title_character_limit =
-        kNotificationWidth * title_lines / kMinPixelsPerTitleCharacter;
+        kNotificationWidth * kMaxTitleLines / kMinPixelsPerTitleCharacter;
     title_view_ = new BoundedLabel(
         gfx::TruncateString(notification.title(), title_character_limit),
         font_list);
     title_view_->SetLineHeight(kTitleLineHeight);
-    title_view_->SetLineLimit(title_lines);
+    title_view_->SetLineLimit(kMaxTitleLines);
     title_view_->SetColors(message_center::kRegularTextColor,
                            kRegularTextBackgroundColor);
     title_view_->SetBorder(MakeTextBorder(padding, 3, 0));
@@ -470,8 +468,13 @@
   // line limit would be different for the specified width than it currently is.
   // TODO(dharcourt): Avoid BoxLayout and directly compute the correct height.
   if (message_view_) {
+    int title_lines = 0;
+    if (title_view_) {
+      title_lines = title_view_->GetLinesForWidthAndLimit(width,
+                                                          kMaxTitleLines);
+    }
     int used_limit = message_view_->GetLineLimit();
-    int correct_limit = GetMessageLineLimit(width);
+    int correct_limit = GetMessageLineLimit(title_lines, width);
     if (used_limit != correct_limit) {
       top_height -= GetMessageHeight(content_width, used_limit);
       top_height += GetMessageHeight(content_width, correct_limit);
@@ -495,8 +498,13 @@
   int content_width = width() - insets.width();
 
   // Before any resizing, set or adjust the number of message lines.
+  int title_lines = 0;
+  if (title_view_) {
+    title_lines =
+        title_view_->GetLinesForWidthAndLimit(width(), kMaxTitleLines);
+  }
   if (message_view_)
-    message_view_->SetLineLimit(GetMessageLineLimit(width()));
+    message_view_->SetLineLimit(GetMessageLineLimit(title_lines, width()));
 
   // Top views.
   int top_height = top_view_->GetHeightForWidth(content_width);
@@ -580,11 +588,22 @@
   controller_->RemoveNotification(notification_id, by_user);
 }
 
-int NotificationView::GetMessageLineLimit(int width) {
+int NotificationView::GetMessageLineLimit(int title_lines, int width) {
   // Image notifications require that the image must be kept flush against
   // their icons, but we can allow more text if no image.
-  if (!image_view_)
-    return message_center::kMessageExpandedLineLimit;
+  int effective_title_lines = std::max(0, title_lines - 1);
+  int line_reduction_from_title = (image_view_ ? 1 : 2) * effective_title_lines;
+  if (!image_view_) {
+    // Title lines are counted as twice as big as message lines for the purpose
+    // of this calculation.
+    // The effect from the title reduction here should be:
+    //   * 0 title lines: 5 max lines message.
+    //   * 1 title line:  5 max lines message.
+    //   * 2 title lines: 3 max lines message.
+    return std::max(
+        0,
+        message_center::kMessageExpandedLineLimit - line_reduction_from_title);
+  }
 
   int message_line_limit = message_center::kMessageCollapsedLineLimit;
 
@@ -595,7 +614,13 @@
         message_center::kContextMessageLineLimit);
   }
 
-  DCHECK_GT(message_line_limit, 0);
+  // The effect from the title reduction here should be:
+  //   * 0 title lines: 2 max lines message + context message.
+  //   * 1 title line:  2 max lines message + context message.
+  //   * 2 title lines: 1 max lines message + context message.
+  message_line_limit =
+      std::max(0, message_line_limit - line_reduction_from_title);
+
   return message_line_limit;
 }
 
diff --git a/ui/message_center/views/notification_view.h b/ui/message_center/views/notification_view.h
index a607b03..3a35169 100644
--- a/ui/message_center/views/notification_view.h
+++ b/ui/message_center/views/notification_view.h
@@ -39,8 +39,7 @@
   static NotificationView* Create(MessageCenterController* controller,
                                   const Notification& notification,
                                   bool top_level);
-
-    virtual ~NotificationView();
+  virtual ~NotificationView();
 
   // Overridden from views::View:
   virtual gfx::Size GetPreferredSize() OVERRIDE;
@@ -69,7 +68,8 @@
                    const Notification& notification);
 
  private:
-  int GetMessageLineLimit(int width);
+  FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, TestLineLimits);
+  int GetMessageLineLimit(int title_lines, int width);
   int GetMessageHeight(int width, int limit);
 
   MessageCenterController* controller_;  // Weak, lives longer then views.
diff --git a/ui/message_center/views/notification_view_unittest.cc b/ui/message_center/views/notification_view_unittest.cc
new file mode 100644
index 0000000..8868628
--- /dev/null
+++ b/ui/message_center/views/notification_view_unittest.cc
@@ -0,0 +1,77 @@
+// 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.
+
+#include "ui/message_center/views/notification_view.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/image/image.h"
+#include "ui/message_center/notification.h"
+
+namespace message_center {
+
+/* Test fixture ***************************************************************/
+
+typedef testing::Test NotificationViewTest;
+
+TEST_F(NotificationViewTest, TestLineLimits) {
+  message_center::RichNotificationData data;
+  std::string id("id");
+  NotifierId notifier_id(NotifierId::APPLICATION, "notifier");
+  scoped_ptr<Notification> notification(
+      new Notification(NOTIFICATION_TYPE_BASE_FORMAT,
+                       id,
+                       base::UTF8ToUTF16("test title"),
+                       base::UTF8ToUTF16("test message"),
+                       gfx::Image(),
+                       base::string16() /* display_source */,
+                       notifier_id,
+                       data,
+                       NULL /* delegate */));
+  scoped_ptr<NotificationView> view(new NotificationView(NULL, *notification));
+
+  EXPECT_EQ(5, view->GetMessageLineLimit(0, 360));
+  EXPECT_EQ(5, view->GetMessageLineLimit(1, 360));
+  EXPECT_EQ(3, view->GetMessageLineLimit(2, 360));
+
+  SkBitmap bitmap;
+  bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
+  bitmap.allocPixels();
+  bitmap.eraseColor(SK_ColorGREEN);
+  data.image = gfx::Image::CreateFrom1xBitmap(bitmap);
+  notification.reset(new Notification(NOTIFICATION_TYPE_BASE_FORMAT,
+                                      id,
+                                      base::UTF8ToUTF16("test title"),
+                                      base::UTF8ToUTF16("test message"),
+                                      gfx::Image(),
+                                      base::string16() /* display_source */,
+                                      notifier_id,
+                                      data,
+                                      NULL /* delegate */));
+  view.reset(new NotificationView(NULL, *notification));
+
+  EXPECT_EQ(2, view->GetMessageLineLimit(0, 360));
+  EXPECT_EQ(2, view->GetMessageLineLimit(1, 360));
+  EXPECT_EQ(1, view->GetMessageLineLimit(2, 360));
+
+  data.context_message = base::UTF8ToUTF16("foo");
+  notification.reset(new Notification(NOTIFICATION_TYPE_BASE_FORMAT,
+                                      id,
+                                      base::UTF8ToUTF16("test title"),
+                                      base::UTF8ToUTF16("test message"),
+                                      gfx::Image(),
+                                      base::string16() /* display_source */,
+                                      notifier_id,
+                                      data,
+                                      NULL /* delegate */));
+  view.reset(new NotificationView(NULL, *notification));
+
+  EXPECT_EQ(1, view->GetMessageLineLimit(0, 360));
+  EXPECT_EQ(1, view->GetMessageLineLimit(1, 360));
+  EXPECT_EQ(0, view->GetMessageLineLimit(2, 360));
+}
+
+}  // namespace message_center
diff --git a/ui/native_theme/native_theme.h b/ui/native_theme/native_theme.h
index f4ea130..eec9d63 100644
--- a/ui/native_theme/native_theme.h
+++ b/ui/native_theme/native_theme.h
@@ -320,10 +320,10 @@
   void AddObserver(NativeThemeObserver* observer);
   void RemoveObserver(NativeThemeObserver* observer);
 
- protected:
   // Notify observers of native theme changes.
   void NotifyObservers();
 
+ protected:
   NativeTheme();
   virtual ~NativeTheme();
 
diff --git a/ui/native_theme/native_theme.target.darwin-arm.mk b/ui/native_theme/native_theme.target.darwin-arm.mk
index 4c22d14..2dff423 100644
--- a/ui/native_theme/native_theme.target.darwin-arm.mk
+++ b/ui/native_theme/native_theme.target.darwin-arm.mk
@@ -51,7 +51,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -177,7 +171,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -226,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/native_theme/native_theme.target.darwin-arm64.mk b/ui/native_theme/native_theme.target.darwin-arm64.mk
index d14e982..7e00be7 100644
--- a/ui/native_theme/native_theme.target.darwin-arm64.mk
+++ b/ui/native_theme/native_theme.target.darwin-arm64.mk
@@ -96,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -217,11 +212,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/native_theme/native_theme.target.darwin-mips.mk b/ui/native_theme/native_theme.target.darwin-mips.mk
index 04d3267..8b4a393 100644
--- a/ui/native_theme/native_theme.target.darwin-mips.mk
+++ b/ui/native_theme/native_theme.target.darwin-mips.mk
@@ -99,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -224,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/native_theme/native_theme.target.darwin-x86.mk b/ui/native_theme/native_theme.target.darwin-x86.mk
index db9f3b9..2e66585 100644
--- a/ui/native_theme/native_theme.target.darwin-x86.mk
+++ b/ui/native_theme/native_theme.target.darwin-x86.mk
@@ -53,7 +53,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -226,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/native_theme/native_theme.target.darwin-x86_64.mk b/ui/native_theme/native_theme.target.darwin-x86_64.mk
index 859e964..3128e61 100644
--- a/ui/native_theme/native_theme.target.darwin-x86_64.mk
+++ b/ui/native_theme/native_theme.target.darwin-x86_64.mk
@@ -53,7 +53,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -179,7 +173,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -227,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/native_theme/native_theme.target.linux-arm.mk b/ui/native_theme/native_theme.target.linux-arm.mk
index 4c22d14..2dff423 100644
--- a/ui/native_theme/native_theme.target.linux-arm.mk
+++ b/ui/native_theme/native_theme.target.linux-arm.mk
@@ -51,7 +51,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -177,7 +171,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -226,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/native_theme/native_theme.target.linux-arm64.mk b/ui/native_theme/native_theme.target.linux-arm64.mk
index d14e982..7e00be7 100644
--- a/ui/native_theme/native_theme.target.linux-arm64.mk
+++ b/ui/native_theme/native_theme.target.linux-arm64.mk
@@ -96,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -217,11 +212,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/native_theme/native_theme.target.linux-mips.mk b/ui/native_theme/native_theme.target.linux-mips.mk
index 04d3267..8b4a393 100644
--- a/ui/native_theme/native_theme.target.linux-mips.mk
+++ b/ui/native_theme/native_theme.target.linux-mips.mk
@@ -99,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -224,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/native_theme/native_theme.target.linux-x86.mk b/ui/native_theme/native_theme.target.linux-x86.mk
index db9f3b9..2e66585 100644
--- a/ui/native_theme/native_theme.target.linux-x86.mk
+++ b/ui/native_theme/native_theme.target.linux-x86.mk
@@ -53,7 +53,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -226,11 +219,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/native_theme/native_theme.target.linux-x86_64.mk b/ui/native_theme/native_theme.target.linux-x86_64.mk
index 859e964..3128e61 100644
--- a/ui/native_theme/native_theme.target.linux-x86_64.mk
+++ b/ui/native_theme/native_theme.target.linux-x86_64.mk
@@ -53,7 +53,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -179,7 +173,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -227,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/ozone/ozone.gyp b/ui/ozone/ozone.gyp
index f2b1a2f..9e3bac6 100644
--- a/ui/ozone/ozone.gyp
+++ b/ui/ozone/ozone.gyp
@@ -8,6 +8,8 @@
     'external_ozone_platforms': [],
     'external_ozone_platform_files': [],
     'external_ozone_platform_deps': [],
+    'internal_ozone_platforms': [],
+    'internal_ozone_platform_deps': [],
   },
   'targets': [
     {
@@ -20,6 +22,7 @@
         '<(DEPTH)/ui/gfx/gfx.gyp:gfx_geometry',
         '<(DEPTH)/skia/skia.gyp:skia',
         '<@(external_ozone_platform_deps)',
+        '<@(internal_ozone_platform_deps)',
       ],
       'defines': [
         'OZONE_IMPLEMENTATION',
@@ -28,6 +31,7 @@
         'platform_list_file': '<(SHARED_INTERMEDIATE_DIR)/ui/ozone/ozone_platform_list.cc',
         'ozone_platforms': [
           '<@(external_ozone_platforms)',
+          '<@(internal_ozone_platforms)',
         ],
       },
       'sources': [
@@ -41,37 +45,10 @@
         'ozone_platform.h',
         'ozone_switches.cc',
         'ozone_switches.h',
-        'platform/dri/chromeos/display_mode_dri.cc',
-        'platform/dri/chromeos/display_mode_dri.h',
-        'platform/dri/chromeos/display_snapshot_dri.cc',
-        'platform/dri/chromeos/display_snapshot_dri.h',
-        'platform/dri/chromeos/native_display_delegate_dri.cc',
-        'platform/dri/chromeos/native_display_delegate_dri.h',
-        'platform/dri/ozone_platform_dri.cc',
-        'platform/dri/ozone_platform_dri.h',
-        'platform/dri/cursor_factory_evdev_dri.cc',
-        'platform/dri/cursor_factory_evdev_dri.h',
-        'platform/dri/dri_buffer.cc',
-        'platform/dri/dri_buffer.h',
-        'platform/dri/dri_surface.cc',
-        'platform/dri/dri_surface.h',
-        'platform/dri/dri_surface_factory.cc',
-        'platform/dri/dri_surface_factory.h',
-        'platform/dri/dri_util.cc',
-        'platform/dri/dri_util.h',
-        'platform/dri/dri_vsync_provider.cc',
-        'platform/dri/dri_vsync_provider.h',
-        'platform/dri/dri_wrapper.cc',
-        'platform/dri/dri_wrapper.h',
-        'platform/dri/hardware_display_controller.cc',
-        'platform/dri/hardware_display_controller.h',
-        'platform/test/ozone_platform_test.cc',
-        'platform/test/ozone_platform_test.h',
         '<@(external_ozone_platform_files)',
       ],
       'includes': [
         'ime/ime.gypi',
-        'platform/caca/caca.gypi',
       ],
       'actions': [
         {
@@ -95,43 +72,34 @@
         },
       ],
       'conditions': [
-        ['<(ozone_platform_dri)==1', {
-          'variables': {
-            'ozone_platforms': [
-              'dri'
-            ]
-          },
-          'dependencies': [
-            '../../build/linux/system.gyp:dridrm',
-            '../../ui/display/display.gyp:display_util',
+        ['use_udev == 0', {
+          'sources/': [
+            ['exclude', '_udev\\.(h|cc)$'],
           ],
-        }, {  # ozone_platform_dri==0
-          'sources/': [
-            ['exclude', '^platform/dri/'],
-          ]
-        }],
-        ['<(ozone_platform_test)==1', {
-          'variables': {
-            'ozone_platforms': [
-              'test'
-            ],
-          }
-        }, {  # ozone_platform_test==0
-          'sources/': [
-            ['exclude', '^platform/test/'],
-          ]
         }],
         ['chromeos==1', {
           'dependencies': [
             '<(DEPTH)/ui/display/display.gyp:display_types',
           ],
         }],
-        ['use_udev == 0', {
-          'sources/': [
-            ['exclude', '_udev\\.(h|cc)$'],
-          ],
-        }],
       ]
     },
   ],
+  'conditions': [
+    ['<(ozone_platform_caca) == 1', {
+      'includes': [
+        'platform/caca/caca.gypi',
+      ],
+    }],
+    ['<(ozone_platform_dri) == 1', {
+      'includes': [
+        'platform/dri/dri.gypi',
+      ],
+    }],
+    ['<(ozone_platform_test) == 1', {
+      'includes': [
+        'platform/test/test.gypi',
+      ],
+    }],
+  ],
 }
diff --git a/ui/ozone/platform/caca/caca.gypi b/ui/ozone/platform/caca/caca.gypi
index 0a4edac..8c1b55d 100644
--- a/ui/ozone/platform/caca/caca.gypi
+++ b/ui/ozone/platform/caca/caca.gypi
@@ -4,16 +4,27 @@
 
 {
   'variables': {
-    'chromium_code': 1,
-    'ozone_platform_caca%': 0,
+    'internal_ozone_platform_deps': [
+      'ozone_platform_caca',
+    ],
+    'internal_ozone_platforms': [
+      'caca'
+    ],
   },
-  'conditions': [
-    ['<(ozone_platform_caca) == 1', {
-      'variables': {
-        'ozone_platforms': [
-          'caca'
-        ],
-      },
+  'targets': [
+    {
+      'target_name': 'ozone_platform_caca',
+      'type': 'static_library',
+      'defines': [
+        'OZONE_IMPLEMENTATION',
+      ],
+      'dependencies': [
+        '../../base/base.gyp:base',
+        '../../skia/skia.gyp:skia',
+        '../events/events.gyp:events',
+        '../gfx/gfx.gyp:gfx',
+        '../gfx/gfx.gyp:gfx_geometry',
+      ],
       'link_settings': {
         'libraries': [
           '-lcaca',
@@ -22,13 +33,13 @@
       'sources': [
         'caca_connection.cc',
         'caca_connection.h',
-        'ozone_platform_caca.cc',
-        'ozone_platform_caca.h',
         'caca_event_factory.cc',
         'caca_event_factory.h',
         'caca_surface_factory.cc',
         'caca_surface_factory.h',
+        'ozone_platform_caca.cc',
+        'ozone_platform_caca.h',
       ],
-    }],
+    },
   ],
 }
diff --git a/ui/ozone/platform/dri/chromeos/display_snapshot_dri.cc b/ui/ozone/platform/dri/chromeos/display_snapshot_dri.cc
index df9f4c6..b14c590 100644
--- a/ui/ozone/platform/dri/chromeos/display_snapshot_dri.cc
+++ b/ui/ozone/platform/dri/chromeos/display_snapshot_dri.cc
@@ -13,6 +13,7 @@
 #include "base/strings/stringprintf.h"
 #include "ui/display/util/edid_parser.h"
 #include "ui/ozone/platform/dri/chromeos/display_mode_dri.h"
+#include "ui/ozone/platform/dri/dri_util.h"
 #include "ui/ozone/platform/dri/dri_wrapper.h"
 
 namespace ui {
@@ -40,22 +41,6 @@
   }
 }
 
-bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs) {
-  return lhs.clock == rhs.clock &&
-         lhs.hdisplay == rhs.vdisplay &&
-         lhs.vrefresh == rhs.vrefresh &&
-         lhs.hsync_start == rhs.hsync_start &&
-         lhs.hsync_end == rhs.hsync_end &&
-         lhs.htotal == rhs.htotal &&
-         lhs.hskew == rhs.hskew &&
-         lhs.vsync_start == rhs.vsync_start &&
-         lhs.vsync_end == rhs.vsync_end &&
-         lhs.vtotal == rhs.vtotal &&
-         lhs.vscan == rhs.vscan &&
-         lhs.flags == rhs.flags &&
-         strcmp(lhs.name, rhs.name) == 0;
-}
-
 bool IsAspectPreserving(DriWrapper* drm, drmModeConnector* connector) {
   drmModePropertyRes* property = drm->GetProperty(connector, "scaling mode");
   if (property) {
diff --git a/ui/ozone/platform/dri/chromeos/native_display_delegate_dri.cc b/ui/ozone/platform/dri/chromeos/native_display_delegate_dri.cc
index ec9b765..109f7f1 100644
--- a/ui/ozone/platform/dri/chromeos/native_display_delegate_dri.cc
+++ b/ui/ozone/platform/dri/chromeos/native_display_delegate_dri.cc
@@ -61,7 +61,7 @@
 }
 
 std::vector<DisplaySnapshot*> NativeDisplayDelegateDri::GetDisplays() {
-  cached_displays_.clear();
+  ScopedVector<DisplaySnapshotDri> old_displays(cached_displays_.Pass());
   cached_modes_.clear();
 
   drmModeRes* resources = drmModeGetResources(
@@ -88,6 +88,22 @@
 
   drmModeFreeResources(resources);
 
+  for (size_t i = 0; i < old_displays.size(); ++i) {
+    bool found = false;
+    for (size_t j = 0; j < cached_displays_.size(); ++j) {
+      if (old_displays[i]->connector() == cached_displays_[j]->connector() &&
+          old_displays[i]->crtc() == cached_displays_[j]->crtc()) {
+        found = true;
+        break;
+      }
+    }
+
+    if (!found) {
+      surface_factory_->DestroyHardwareDisplayController(
+          old_displays[i]->connector(), old_displays[i]->crtc());
+    }
+  }
+
   std::vector<DisplaySnapshot*> generic_displays(cached_displays_.begin(),
                                                  cached_displays_.end());
   return generic_displays;
@@ -167,8 +183,11 @@
   if (event.device_type() != DeviceEvent::DISPLAY)
     return;
 
-  if (event.action_type() == DeviceEvent::CHANGE)
-    NOTIMPLEMENTED();
+  if (event.action_type() == DeviceEvent::CHANGE) {
+    VLOG(1) << "Got display changed event";
+    FOR_EACH_OBSERVER(
+        NativeDisplayObserver, observers_, OnConfigurationChanged());
+  }
 }
 
 }  // namespace ui
diff --git a/ui/ozone/platform/dri/cursor_factory_evdev_dri.cc b/ui/ozone/platform/dri/cursor_factory_evdev_dri.cc
index 46b26db..273dd1a 100644
--- a/ui/ozone/platform/dri/cursor_factory_evdev_dri.cc
+++ b/ui/ozone/platform/dri/cursor_factory_evdev_dri.cc
@@ -14,9 +14,7 @@
   // TODO(dnicoara) Assume the first widget since at this point there are no
   // widgets initialized.
   cursor_window_ = DriSurfaceFactory::kDefaultWidgetHandle;
-  cursor_bounds_ = gfx::RectF(0, 0, 2560, 1700);  // TODO(spang): Argh!
-  cursor_location_ =
-      gfx::PointF(cursor_bounds_.width() / 2, cursor_bounds_.height() / 2);
+  cursor_location_ = gfx::PointF(2560 / 2, 1700 / 2);  // TODO(spang): Argh!
 
   // The DRI cursor is invisible unless explicitly set. Therefore, set the
   // pointer cursor on initialization.
@@ -31,6 +29,7 @@
     scoped_refptr<BitmapCursorOzone> cursor) {
   if (cursor_ == cursor)
     return;
+
   cursor_ = cursor;
   if (cursor_)
     dri_->SetHardwareCursor(
@@ -41,12 +40,16 @@
 
 void CursorFactoryEvdevDri::MoveCursorTo(gfx::AcceleratedWidget widget,
                                          const gfx::PointF& location) {
+  if (widget != cursor_window_)
+    dri_->UnsetHardwareCursor(cursor_window_);
+
   cursor_window_ = widget;
   cursor_location_ = location;
-  cursor_location_.SetToMax(
-      gfx::PointF(cursor_bounds_.x(), cursor_bounds_.y()));
-  cursor_location_.SetToMin(
-      gfx::PointF(cursor_bounds_.right(), cursor_bounds_.bottom()));
+
+  gfx::Size size = dri_->GetWidgetSize(cursor_window_);
+  cursor_location_.SetToMax(gfx::PointF(0, 0));
+  cursor_location_.SetToMin(gfx::PointF(size.width(), size.height()));
+
   if (cursor_)
     dri_->MoveHardwareCursor(cursor_window_, bitmap_location());
 }
@@ -55,7 +58,7 @@
   MoveCursorTo(cursor_window_, cursor_location_ + delta);
 }
 
-gfx::AcceleratedWidget CursorFactoryEvdevDri::window() {
+gfx::AcceleratedWidget CursorFactoryEvdevDri::GetCursorWindow() {
   return cursor_window_;
 }
 
diff --git a/ui/ozone/platform/dri/cursor_factory_evdev_dri.h b/ui/ozone/platform/dri/cursor_factory_evdev_dri.h
index b1a1a7d..da13219 100644
--- a/ui/ozone/platform/dri/cursor_factory_evdev_dri.h
+++ b/ui/ozone/platform/dri/cursor_factory_evdev_dri.h
@@ -25,6 +25,7 @@
   virtual ~CursorFactoryEvdevDri();
 
   // BitmapCursorFactoryOzone:
+  virtual gfx::AcceleratedWidget GetCursorWindow() OVERRIDE;
   virtual void SetBitmapCursor(gfx::AcceleratedWidget widget,
                                scoped_refptr<BitmapCursorOzone> cursor)
       OVERRIDE;
@@ -33,7 +34,6 @@
   virtual void MoveCursorTo(gfx::AcceleratedWidget widget,
                             const gfx::PointF& location) OVERRIDE;
   virtual void MoveCursor(const gfx::Vector2dF& delta) OVERRIDE;
-  virtual gfx::AcceleratedWidget window() OVERRIDE;
   virtual gfx::PointF location() OVERRIDE;
 
  private:
@@ -49,9 +49,6 @@
   // The window under the cursor.
   gfx::AcceleratedWidget cursor_window_;
 
-  // The bounds of the window under the cursor.
-  gfx::RectF cursor_bounds_;
-
   // The location of the cursor within the window.
   gfx::PointF cursor_location_;
 };
diff --git a/ui/ozone/platform/dri/dri.gypi b/ui/ozone/platform/dri/dri.gypi
new file mode 100644
index 0000000..f7a1246
--- /dev/null
+++ b/ui/ozone/platform/dri/dri.gypi
@@ -0,0 +1,59 @@
+# 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.
+
+{
+  'variables': {
+    'internal_ozone_platform_deps': [
+      'ozone_platform_dri',
+    ],
+    'internal_ozone_platforms': [
+      'dri'
+    ],
+  },
+  'targets': [
+    {
+      'target_name': 'ozone_platform_dri',
+      'type': 'static_library',
+      'dependencies': [
+        '../../base/base.gyp:base',
+        '../../build/linux/system.gyp:dridrm',
+        '../../skia/skia.gyp:skia',
+        '../display/display.gyp:display_types',
+        '../display/display.gyp:display_util',
+        '../events/events.gyp:events',
+        '../gfx/gfx.gyp:gfx',
+        '../gfx/gfx.gyp:gfx_geometry',
+      ],
+      'defines': [
+        'OZONE_IMPLEMENTATION',
+      ],
+      'sources': [
+        'chromeos/display_mode_dri.cc',
+        'chromeos/display_mode_dri.h',
+        'chromeos/display_snapshot_dri.cc',
+        'chromeos/display_snapshot_dri.h',
+        'chromeos/native_display_delegate_dri.cc',
+        'chromeos/native_display_delegate_dri.h',
+        'cursor_factory_evdev_dri.cc',
+        'cursor_factory_evdev_dri.h',
+        'dri_buffer.cc',
+        'dri_buffer.h',
+        'dri_surface.cc',
+        'dri_surface.h',
+        'dri_surface_factory.cc',
+        'dri_surface_factory.h',
+        'dri_util.cc',
+        'dri_util.h',
+        'dri_vsync_provider.cc',
+        'dri_vsync_provider.h',
+        'dri_wrapper.cc',
+        'dri_wrapper.h',
+        'hardware_display_controller.cc',
+        'hardware_display_controller.h',
+        'ozone_platform_dri.cc',
+        'ozone_platform_dri.h',
+      ],
+    },
+  ],
+}
diff --git a/ui/ozone/platform/dri/dri_surface_factory.cc b/ui/ozone/platform/dri/dri_surface_factory.cc
index cca9175..78d7acf 100644
--- a/ui/ozone/platform/dri/dri_surface_factory.cc
+++ b/ui/ozone/platform/dri/dri_surface_factory.cc
@@ -104,6 +104,10 @@
 }
 
 void DriSurfaceAdapter::PresentCanvas(const gfx::Rect& damage) {
+  // The underlying display is gone.
+  if (!dri_->IsWidgetValid(widget_))
+    return;
+
   SkCanvas* canvas = dri_->GetCanvasForWidget(widget_);
 
   // The DriSurface is double buffered, so the current back buffer is
@@ -131,7 +135,8 @@
     : drm_(),
       state_(UNINITIALIZED),
       controllers_(),
-      allocated_widgets_(0) {
+      allocated_widgets_(0),
+      last_added_widget_(0) {
 }
 
 DriSurfaceFactory::~DriSurfaceFactory() {
@@ -244,14 +249,32 @@
 scoped_ptr<gfx::VSyncProvider> DriSurfaceFactory::CreateVSyncProvider(
     gfx::AcceleratedWidget w) {
   CHECK(state_ == INITIALIZED);
-  return scoped_ptr<gfx::VSyncProvider>(new DriVSyncProvider(
-      GetControllerForWidget(w)));
+  return scoped_ptr<gfx::VSyncProvider>(new DriVSyncProvider(this, w));
 }
 
 bool DriSurfaceFactory::CreateHardwareDisplayController(
     uint32_t connector, uint32_t crtc, const drmModeModeInfo& mode) {
-  scoped_ptr<HardwareDisplayController> controller(
-      new HardwareDisplayController(drm_.get(), connector, crtc, mode));
+  gfx::AcceleratedWidget widget = 0;
+  scoped_ptr<HardwareDisplayController> controller;
+  for (HardwareDisplayControllerMap::iterator it = controllers_.begin();
+       it != controllers_.end(); ++it) {
+    if (it->second->connector_id() == connector &&
+        it->second->crtc_id() == crtc) {
+      if (SameMode(mode, it->second->get_mode()))
+        return true;
+
+      widget = it->first;
+      controller.reset(it->second);
+      controller->UnbindSurfaceFromController();
+      break;
+    }
+  }
+
+  if (!controller) {
+    controller.reset(
+        new HardwareDisplayController(drm_.get(), connector, crtc));
+    widget = ++last_added_widget_;
+  }
 
   // Create a surface suitable for the current controller.
   scoped_ptr<DriSurface> surface(CreateSurface(
@@ -265,19 +288,43 @@
   // Bind the surface to the controller. This will register the backing buffers
   // with the hardware CRTC such that we can show the buffers and performs the
   // initial modeset. The controller takes ownership of the surface.
-  if (!controller->BindSurfaceToController(surface.Pass())) {
+  if (!controller->BindSurfaceToController(surface.Pass(), mode)) {
     LOG(ERROR) << "Failed to bind surface to controller";
     return false;
   }
 
-  controllers_.push_back(controller.release());
+  controllers_.insert(std::make_pair(widget,
+                                     controller.release()));
   return true;
 }
 
+void DriSurfaceFactory::DestroyHardwareDisplayController(
+    uint32_t connector, uint32_t crtc) {
+  for (HardwareDisplayControllerMap::iterator it = controllers_.begin();
+       it != controllers_.end(); ++it) {
+    if (it->second->connector_id() == connector &&
+        it->second->crtc_id() == crtc) {
+      delete it->second;
+      controllers_.erase(it);
+      return;
+    }
+  }
+}
+
 bool DriSurfaceFactory::DisableHardwareDisplayController(uint32_t crtc) {
   return drm_->DisableCrtc(crtc);
 }
 
+gfx::Size DriSurfaceFactory::GetWidgetSize(gfx::AcceleratedWidget w) {
+  if (IsWidgetValid(w)) {
+    HardwareDisplayController* controller = GetControllerForWidget(w);
+    return gfx::Size(controller->get_mode().hdisplay,
+                     controller->get_mode().vdisplay);
+  }
+
+  return gfx::Size(0, 0);
+}
+
 void DriSurfaceFactory::SetHardwareCursor(gfx::AcceleratedWidget window,
                                           const SkBitmap& image,
                                           const gfx::Point& location) {
@@ -297,7 +344,8 @@
   if (state_ != INITIALIZED)
     return;
 
-  GetControllerForWidget(window)->MoveCursor(location);
+  if (IsWidgetValid(window))
+    GetControllerForWidget(window)->MoveCursor(location);
 }
 
 void DriSurfaceFactory::UnsetHardwareCursor(gfx::AcceleratedWidget window) {
@@ -309,6 +357,10 @@
   ResetCursor(window);
 }
 
+bool DriSurfaceFactory::IsWidgetValid(gfx::AcceleratedWidget w) const {
+  return controllers_.find(w) != controllers_.end();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // DriSurfaceFactory private
 
@@ -357,6 +409,9 @@
 }
 
 void DriSurfaceFactory::ResetCursor(gfx::AcceleratedWidget w) {
+  if (!IsWidgetValid(w))
+    return;
+
   if (!cursor_bitmap_.empty()) {
     // Draw new cursor into backbuffer.
     UpdateCursorImage(cursor_surface_.get(), cursor_bitmap_);
@@ -372,10 +427,10 @@
 
 HardwareDisplayController* DriSurfaceFactory::GetControllerForWidget(
     gfx::AcceleratedWidget w) {
-  CHECK_GE(w, 1);
-  CHECK_LE(static_cast<size_t>(w), controllers_.size());
+  HardwareDisplayControllerMap::iterator it = controllers_.find(w);
+  CHECK(it != controllers_.end());
 
-  return controllers_[w - 1];
+  return it->second;
 }
 
 }  // namespace ui
diff --git a/ui/ozone/platform/dri/dri_surface_factory.h b/ui/ozone/platform/dri/dri_surface_factory.h
index 2a35871..6984b7b 100644
--- a/ui/ozone/platform/dri/dri_surface_factory.h
+++ b/ui/ozone/platform/dri/dri_surface_factory.h
@@ -5,8 +5,9 @@
 #ifndef UI_OZONE_PLATFORM_DRI_DRI_SURFACE_FACTORY_H_
 #define UI_OZONE_PLATFORM_DRI_DRI_SURFACE_FACTORY_H_
 
+#include <map>
+
 #include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/ozone/surface_factory_ozone.h"
 #include "ui/ozone/ozone_export.h"
@@ -53,6 +54,8 @@
   virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider(
       gfx::AcceleratedWidget w);
 
+  gfx::Size GetWidgetSize(gfx::AcceleratedWidget w);
+
   void SetHardwareCursor(gfx::AcceleratedWidget window,
                          const SkBitmap& image,
                          const gfx::Point& location);
@@ -69,8 +72,16 @@
                                        uint32_t crtc,
                                        const drmModeModeInfo& mode);
 
+  void DestroyHardwareDisplayController(uint32_t connector, uint32_t crtc);
+
   bool DisableHardwareDisplayController(uint32_t crtc);
 
+  bool IsWidgetValid(gfx::AcceleratedWidget w) const;
+
+  // Returns the controller in |controllers_| associated with |w|.
+  HardwareDisplayController* GetControllerForWidget(
+      gfx::AcceleratedWidget w);
+
   DriWrapper* drm() const { return drm_.get(); }
 
  private:
@@ -92,17 +103,16 @@
   // Draw the last set cursor & update the cursor plane.
   void ResetCursor(gfx::AcceleratedWidget w);
 
-  // Returns the controller in |controllers_| associated with |w|.
-  HardwareDisplayController* GetControllerForWidget(
-      gfx::AcceleratedWidget w);
-
   scoped_ptr<DriWrapper> drm_;
 
   HardwareState state_;
 
+  typedef std::map<gfx::AcceleratedWidget, HardwareDisplayController*>
+      HardwareDisplayControllerMap;
   // Active outputs.
-  ScopedVector<HardwareDisplayController> controllers_;
+  HardwareDisplayControllerMap controllers_;
   int allocated_widgets_;
+  int last_added_widget_;
 
   scoped_ptr<DriSurface> cursor_surface_;
 
diff --git a/ui/ozone/platform/dri/dri_surface_unittest.cc b/ui/ozone/platform/dri/dri_surface_unittest.cc
index ed7393a..75a79d6 100644
--- a/ui/ozone/platform/dri/dri_surface_unittest.cc
+++ b/ui/ozone/platform/dri/dri_surface_unittest.cc
@@ -137,7 +137,7 @@
 void DriSurfaceTest::SetUp() {
   drm_.reset(new MockDriWrapper());
   controller_.reset(new ui::HardwareDisplayController(
-      drm_.get(), kConnectorId, kCrtcId, kDefaultMode));
+      drm_.get(), kConnectorId, kCrtcId));
 
   surface_.reset(new MockDriSurface(drm_.get(),
                                     gfx::Size(kDefaultMode.hdisplay,
@@ -161,7 +161,8 @@
 
 TEST_F(DriSurfaceTest, CheckFBIDOnSwap) {
   EXPECT_TRUE(surface_->Initialize());
-  controller_->BindSurfaceToController(surface_.PassAs<ui::DriSurface>());
+  controller_->BindSurfaceToController(surface_.PassAs<ui::DriSurface>(),
+                                       kDefaultMode);
 
   // Check that the framebuffer ID is correct.
   EXPECT_EQ(2u, controller_->get_surface()->GetFramebufferId());
diff --git a/ui/ozone/platform/dri/dri_util.cc b/ui/ozone/platform/dri/dri_util.cc
index cb7cdf7..b3eab02 100644
--- a/ui/ozone/platform/dri/dri_util.cc
+++ b/ui/ozone/platform/dri/dri_util.cc
@@ -105,4 +105,21 @@
   return displays.Pass();
 }
 
+bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs) {
+  return lhs.clock == rhs.clock &&
+         lhs.hdisplay == rhs.hdisplay &&
+         lhs.vdisplay == rhs.vdisplay &&
+         lhs.vrefresh == rhs.vrefresh &&
+         lhs.hsync_start == rhs.hsync_start &&
+         lhs.hsync_end == rhs.hsync_end &&
+         lhs.htotal == rhs.htotal &&
+         lhs.hskew == rhs.hskew &&
+         lhs.vsync_start == rhs.vsync_start &&
+         lhs.vsync_end == rhs.vsync_end &&
+         lhs.vtotal == rhs.vtotal &&
+         lhs.vscan == rhs.vscan &&
+         lhs.flags == rhs.flags &&
+         strcmp(lhs.name, rhs.name) == 0;
+}
+
 }  // namespace ui
diff --git a/ui/ozone/platform/dri/dri_util.h b/ui/ozone/platform/dri/dri_util.h
index f2d72b4..174d2aa 100644
--- a/ui/ozone/platform/dri/dri_util.h
+++ b/ui/ozone/platform/dri/dri_util.h
@@ -10,6 +10,7 @@
 
 typedef struct _drmModeConnector drmModeConnector;
 typedef struct _drmModeCrtc drmModeCrtc;
+typedef struct _drmModeModeInfo drmModeModeInfo;
 typedef struct _drmModeRes drmModeRes;
 
 namespace ui {
@@ -36,6 +37,8 @@
 ScopedVector<HardwareDisplayControllerInfo>
 GetAvailableDisplayControllerInfos(int fd, drmModeRes* resources);
 
+bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs);
+
 }  // namespace ui
 
 #endif  // UI_OZONE_PLATFORM_DRI_DRI_UTIL_H_
diff --git a/ui/ozone/platform/dri/dri_vsync_provider.cc b/ui/ozone/platform/dri/dri_vsync_provider.cc
index 9c61762..17f2be2 100644
--- a/ui/ozone/platform/dri/dri_vsync_provider.cc
+++ b/ui/ozone/platform/dri/dri_vsync_provider.cc
@@ -5,26 +5,34 @@
 #include "ui/ozone/platform/dri/dri_vsync_provider.h"
 
 #include "base/time/time.h"
+#include "ui/ozone/platform/dri/dri_surface_factory.h"
 #include "ui/ozone/platform/dri/hardware_display_controller.h"
 
 namespace ui {
 
-DriVSyncProvider::DriVSyncProvider(HardwareDisplayController* controller)
-    : controller_(controller) {}
+DriVSyncProvider::DriVSyncProvider(DriSurfaceFactory* factory,
+                                   gfx::AcceleratedWidget widget)
+    : factory_(factory), widget_(widget) {}
 
 DriVSyncProvider::~DriVSyncProvider() {}
 
 void DriVSyncProvider::GetVSyncParameters(const UpdateVSyncCallback& callback) {
+  if (!factory_->IsWidgetValid(widget_))
+    return;
+
+  HardwareDisplayController* controller =
+      factory_->GetControllerForWidget(widget_);
   // The value is invalid, so we can't update the parameters.
-  if (controller_->get_time_of_last_flip() == 0)
+  if (controller->get_time_of_last_flip() == 0 ||
+      controller->get_mode().vrefresh == 0)
     return;
 
   // Stores the time of the last refresh.
   base::TimeTicks timebase =
-      base::TimeTicks::FromInternalValue(controller_->get_time_of_last_flip());
+      base::TimeTicks::FromInternalValue(controller->get_time_of_last_flip());
   // Stores the refresh rate.
   base::TimeDelta interval =
-      base::TimeDelta::FromSeconds(1) / controller_->get_mode().vrefresh;
+      base::TimeDelta::FromSeconds(1) / controller->get_mode().vrefresh;
 
   callback.Run(timebase, interval);
 }
diff --git a/ui/ozone/platform/dri/dri_vsync_provider.h b/ui/ozone/platform/dri/dri_vsync_provider.h
index f031a8e..edcef00 100644
--- a/ui/ozone/platform/dri/dri_vsync_provider.h
+++ b/ui/ozone/platform/dri/dri_vsync_provider.h
@@ -5,21 +5,23 @@
 #ifndef UI_OZONE_PLATFORM_IMPL_DRI_VSYNC_PROVIDER_H_
 #define UI_OZONE_PLATFORM_IMPL_DRI_VSYNC_PROVIDER_H_
 
+#include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/vsync_provider.h"
 
 namespace ui {
 
-class HardwareDisplayController;
+class DriSurfaceFactory;
 
 class DriVSyncProvider : public gfx::VSyncProvider {
  public:
-  DriVSyncProvider(HardwareDisplayController* controller);
+  DriVSyncProvider(DriSurfaceFactory* factory, gfx::AcceleratedWidget w);
   virtual ~DriVSyncProvider();
 
   virtual void GetVSyncParameters(const UpdateVSyncCallback& callback) OVERRIDE;
 
  private:
-  HardwareDisplayController* controller_;
+  DriSurfaceFactory* factory_;
+  gfx::AcceleratedWidget widget_;
 
   DISALLOW_COPY_AND_ASSIGN(DriVSyncProvider);
 };
diff --git a/ui/ozone/platform/dri/hardware_display_controller.cc b/ui/ozone/platform/dri/hardware_display_controller.cc
index ae9c410..c7c3b7c 100644
--- a/ui/ozone/platform/dri/hardware_display_controller.cc
+++ b/ui/ozone/platform/dri/hardware_display_controller.cc
@@ -22,52 +22,31 @@
 HardwareDisplayController::HardwareDisplayController(
     DriWrapper* drm,
     uint32_t connector_id,
-    uint32_t crtc_id,
-    drmModeModeInfo mode)
+    uint32_t crtc_id)
     : drm_(drm),
       connector_id_(connector_id),
       crtc_id_(crtc_id),
-      mode_(mode),
       surface_(),
       time_of_last_flip_(0) {}
 
 HardwareDisplayController::~HardwareDisplayController() {
   // Reset the cursor.
   UnsetCursor();
-
-  if (surface_.get()) {
-    // Unregister the buffers.
-    for (size_t i = 0; i < arraysize(surface_->bitmaps_); ++i) {
-      if (!drm_->RemoveFramebuffer(surface_->bitmaps_[i]->framebuffer()))
-        DLOG(ERROR) << "Failed to remove FB: " << strerror(errno);
-    }
-  }
+  UnbindSurfaceFromController();
 }
 
 bool
 HardwareDisplayController::BindSurfaceToController(
-    scoped_ptr<DriSurface> surface) {
+    scoped_ptr<DriSurface> surface, drmModeModeInfo mode) {
   CHECK(surface);
-  // Register the buffers.
-  for (size_t i = 0; i < arraysize(surface->bitmaps_); ++i) {
-    uint32_t fb_id;
-    if (!drm_->AddFramebuffer(
-            mode_,
-            surface->bitmaps_[i]->GetColorDepth(),
-            surface->bitmaps_[i]->canvas()->imageInfo().bytesPerPixel() << 3,
-            surface->bitmaps_[i]->stride(),
-            surface->bitmaps_[i]->handle(),
-            &fb_id)) {
-      DLOG(ERROR) << "Failed to register framebuffer: " << strerror(errno);
-      return false;
-    }
-    surface->bitmaps_[i]->set_framebuffer(fb_id);
-  }
+
+  if (!RegisterFramebuffers(surface.get(), mode))
+    return false;
 
   if (!drm_->SetCrtc(crtc_id_,
                      surface->GetFramebufferId(),
                      &connector_id_,
-                     &mode_)) {
+                     &mode)) {
     LOG(ERROR) << "Failed to modeset: crtc=" << crtc_id_ << " connector="
                << connector_id_ << " framebuffer_id="
                << surface->GetFramebufferId();
@@ -75,9 +54,16 @@
   }
 
   surface_.reset(surface.release());
+  mode_ = mode;
   return true;
 }
 
+void HardwareDisplayController::UnbindSurfaceFromController() {
+  if (surface_)
+    UnregisterFramebuffers(surface_.get());
+  surface_.reset();
+}
+
 bool HardwareDisplayController::SchedulePageFlip() {
   CHECK(surface_);
 
@@ -118,4 +104,33 @@
   return drm_->MoveCursor(crtc_id_, location.x(), location.y());
 }
 
+bool HardwareDisplayController::RegisterFramebuffers(DriSurface* surface,
+                                                     drmModeModeInfo mode) {
+  // Register the buffers.
+  for (size_t i = 0; i < arraysize(surface->bitmaps_); ++i) {
+    uint32_t fb_id;
+    if (!drm_->AddFramebuffer(
+            mode,
+            surface->bitmaps_[i]->GetColorDepth(),
+            surface->bitmaps_[i]->canvas()->imageInfo().bytesPerPixel() << 3,
+            surface->bitmaps_[i]->stride(),
+            surface->bitmaps_[i]->handle(),
+            &fb_id)) {
+      DLOG(ERROR) << "Failed to register framebuffer: " << strerror(errno);
+      return false;
+    }
+    surface->bitmaps_[i]->set_framebuffer(fb_id);
+  }
+
+  return true;
+}
+
+void HardwareDisplayController::UnregisterFramebuffers(DriSurface* surface) {
+  // Unregister the buffers.
+  for (size_t i = 0; i < arraysize(surface->bitmaps_); ++i) {
+    if (!drm_->RemoveFramebuffer(surface->bitmaps_[i]->framebuffer()))
+      DLOG(ERROR) << "Failed to remove FB: " << strerror(errno);
+  }
+}
+
 }  // namespace ui
diff --git a/ui/ozone/platform/dri/hardware_display_controller.h b/ui/ozone/platform/dri/hardware_display_controller.h
index af7dd86..5c3f433 100644
--- a/ui/ozone/platform/dri/hardware_display_controller.h
+++ b/ui/ozone/platform/dri/hardware_display_controller.h
@@ -84,13 +84,15 @@
  public:
   HardwareDisplayController(DriWrapper* drm,
                             uint32_t connector_id,
-                            uint32_t crtc_id,
-                            drmModeModeInfo mode);
+                            uint32_t crtc_id);
 
   ~HardwareDisplayController();
 
   // Associate the HDCO with a surface implementation and initialize it.
-  bool BindSurfaceToController(scoped_ptr<DriSurface> surface);
+  bool BindSurfaceToController(scoped_ptr<DriSurface> surface,
+                               drmModeModeInfo mode);
+
+  void UnbindSurfaceFromController();
 
   // Schedules the |surface_|'s framebuffer to be displayed on the next vsync
   // event. The event will be posted on the graphics card file descriptor |fd_|
@@ -131,7 +133,8 @@
   int get_fd() const { return drm_->get_fd(); };
 
   const drmModeModeInfo& get_mode() const { return mode_; };
-
+  uint32_t connector_id() const { return connector_id_; }
+  uint32_t crtc_id() const { return crtc_id_; }
   DriSurface* get_surface() const { return surface_.get(); };
 
   uint64_t get_time_of_last_flip() const {
@@ -139,6 +142,9 @@
   };
 
  private:
+  bool RegisterFramebuffers(DriSurface* surface, drmModeModeInfo mode);
+  void UnregisterFramebuffers(DriSurface* surface);
+
   // Object containing the connection to the graphics device and wraps the API
   // calls to control it.
   DriWrapper* drm_;
diff --git a/ui/ozone/platform/dri/hardware_display_controller_unittest.cc b/ui/ozone/platform/dri/hardware_display_controller_unittest.cc
index 1beb85b..d809b9b 100644
--- a/ui/ozone/platform/dri/hardware_display_controller_unittest.cc
+++ b/ui/ozone/platform/dri/hardware_display_controller_unittest.cc
@@ -210,7 +210,7 @@
 void HardwareDisplayControllerTest::SetUp() {
   drm_.reset(new MockDriWrapper(kFd));
   controller_.reset(new ui::HardwareDisplayController(
-      drm_.get(), kConnectorId, kCrtcId, kDefaultMode));
+      drm_.get(), kConnectorId, kCrtcId));
 }
 
 void HardwareDisplayControllerTest::TearDown() {
@@ -223,7 +223,8 @@
       new MockDriSurface(drm_.get(), kDefaultModeSize));
 
   EXPECT_TRUE(surface->Initialize());
-  EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass()));
+  EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(),
+                                                   kDefaultMode));
 
   EXPECT_EQ(2, drm_->get_add_framebuffer_call_count());
   EXPECT_TRUE(controller_->get_surface() != NULL);
@@ -236,7 +237,8 @@
       new MockDriSurface(drm_.get(), kDefaultModeSize));
 
   EXPECT_TRUE(surface->Initialize());
-  EXPECT_FALSE(controller_->BindSurfaceToController(surface.Pass()));
+  EXPECT_FALSE(controller_->BindSurfaceToController(surface.Pass(),
+                                                    kDefaultMode));
 
   EXPECT_EQ(1, drm_->get_add_framebuffer_call_count());
   EXPECT_EQ(NULL, controller_->get_surface());
@@ -247,7 +249,8 @@
       new MockDriSurface(drm_.get(), kDefaultModeSize));
 
   EXPECT_TRUE(surface->Initialize());
-  EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass()));
+  EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(),
+                                                   kDefaultMode));
 
   EXPECT_TRUE(controller_->SchedulePageFlip());
   EXPECT_TRUE(controller_->get_surface() != NULL);
@@ -260,7 +263,8 @@
       new MockDriSurface(drm_.get(), kDefaultModeSize));
 
   EXPECT_TRUE(surface->Initialize());
-  EXPECT_FALSE(controller_->BindSurfaceToController(surface.Pass()));
+  EXPECT_FALSE(controller_->BindSurfaceToController(surface.Pass(),
+                                                    kDefaultMode));
   EXPECT_EQ(NULL, controller_->get_surface());
 }
 
@@ -271,7 +275,8 @@
       new MockDriSurface(drm_.get(), kDefaultModeSize));
 
   EXPECT_TRUE(surface->Initialize());
-  EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass()));
+  EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(),
+                                                   kDefaultMode));
   EXPECT_FALSE(controller_->SchedulePageFlip());
 }
 
@@ -280,7 +285,8 @@
       new MockDriSurface(drm_.get(), kDefaultModeSize));
 
   EXPECT_TRUE(surface->Initialize());
-  EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass()));
+  EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass(),
+                                                   kDefaultMode));
   EXPECT_TRUE(controller_->get_surface() != NULL);
 
   controller_.reset();
diff --git a/ui/ozone/platform/test/test.gypi b/ui/ozone/platform/test/test.gypi
new file mode 100644
index 0000000..cdfb756
--- /dev/null
+++ b/ui/ozone/platform/test/test.gypi
@@ -0,0 +1,32 @@
+# 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.
+
+{
+  'variables': {
+    'internal_ozone_platform_deps': [
+      'ozone_platform_test',
+    ],
+    'internal_ozone_platforms': [
+      'test'
+    ],
+  },
+  'targets': [
+    {
+      'target_name': 'ozone_platform_test',
+      'type': 'static_library',
+      'defines': [
+        'OZONE_IMPLEMENTATION',
+      ],
+      'dependencies': [
+        '../../base/base.gyp:base',
+        '../events/events.gyp:events',
+        '../gfx/gfx.gyp:gfx',
+      ],
+      'sources': [
+        'ozone_platform_test.cc',
+        'ozone_platform_test.h',
+      ],
+    },
+  ],
+}
diff --git a/ui/resources/default_100_percent/common/app_list_apps_icon.png b/ui/resources/default_100_percent/common/app_list_apps_icon.png
new file mode 100644
index 0000000..e779080
--- /dev/null
+++ b/ui/resources/default_100_percent/common/app_list_apps_icon.png
Binary files differ
diff --git a/ui/resources/default_100_percent/common/app_list_notifications_icon.png b/ui/resources/default_100_percent/common/app_list_notifications_icon.png
new file mode 100644
index 0000000..4bf4c24
--- /dev/null
+++ b/ui/resources/default_100_percent/common/app_list_notifications_icon.png
Binary files differ
diff --git a/ui/resources/default_100_percent/common/app_list_search_icon.png b/ui/resources/default_100_percent/common/app_list_search_icon.png
new file mode 100644
index 0000000..8bb0ea2
--- /dev/null
+++ b/ui/resources/default_100_percent/common/app_list_search_icon.png
Binary files differ
diff --git a/ui/resources/default_100_percent/common/notification_bubble_close.png b/ui/resources/default_100_percent/common/notification_bubble_close.png
new file mode 100644
index 0000000..02e1f91
--- /dev/null
+++ b/ui/resources/default_100_percent/common/notification_bubble_close.png
Binary files differ
diff --git a/ui/resources/default_100_percent/common/notification_bubble_close_hover.png b/ui/resources/default_100_percent/common/notification_bubble_close_hover.png
new file mode 100644
index 0000000..aeafd96
--- /dev/null
+++ b/ui/resources/default_100_percent/common/notification_bubble_close_hover.png
Binary files differ
diff --git a/ui/resources/default_100_percent/common/notification_bubble_close_pressed.png b/ui/resources/default_100_percent/common/notification_bubble_close_pressed.png
new file mode 100644
index 0000000..1c4ad59
--- /dev/null
+++ b/ui/resources/default_100_percent/common/notification_bubble_close_pressed.png
Binary files differ
diff --git a/ui/resources/default_200_percent/common/app_list_apps_icon.png b/ui/resources/default_200_percent/common/app_list_apps_icon.png
new file mode 100644
index 0000000..919a97a
--- /dev/null
+++ b/ui/resources/default_200_percent/common/app_list_apps_icon.png
Binary files differ
diff --git a/ui/resources/default_200_percent/common/app_list_notifications_icon.png b/ui/resources/default_200_percent/common/app_list_notifications_icon.png
new file mode 100644
index 0000000..60eb800
--- /dev/null
+++ b/ui/resources/default_200_percent/common/app_list_notifications_icon.png
Binary files differ
diff --git a/ui/resources/default_200_percent/common/app_list_search_icon.png b/ui/resources/default_200_percent/common/app_list_search_icon.png
new file mode 100644
index 0000000..c3ae54b
--- /dev/null
+++ b/ui/resources/default_200_percent/common/app_list_search_icon.png
Binary files differ
diff --git a/ui/resources/default_200_percent/common/notification_bubble_close.png b/ui/resources/default_200_percent/common/notification_bubble_close.png
new file mode 100644
index 0000000..80f4b9c
--- /dev/null
+++ b/ui/resources/default_200_percent/common/notification_bubble_close.png
Binary files differ
diff --git a/ui/resources/default_200_percent/common/notification_bubble_close_hover.png b/ui/resources/default_200_percent/common/notification_bubble_close_hover.png
new file mode 100644
index 0000000..743d005
--- /dev/null
+++ b/ui/resources/default_200_percent/common/notification_bubble_close_hover.png
Binary files differ
diff --git a/ui/resources/default_200_percent/common/notification_bubble_close_pressed.png b/ui/resources/default_200_percent/common/notification_bubble_close_pressed.png
new file mode 100644
index 0000000..07b69cc
--- /dev/null
+++ b/ui/resources/default_200_percent/common/notification_bubble_close_pressed.png
Binary files differ
diff --git a/ui/resources/ui_resources.grd b/ui/resources/ui_resources.grd
index 6cd4ed9..4096fe2 100644
--- a/ui/resources/ui_resources.grd
+++ b/ui/resources/ui_resources.grd
@@ -15,15 +15,18 @@
            BECAUSE YOUR RESOURCES ARE FUNCTIONALLY RELATED OR FALL UNDER THE
            SAME CONDITIONALS. -->
       <if expr="enable_app_list">
+        <structure type="chrome_scaled_image" name="IDR_APP_LIST_APPS_ICON" file="common/app_list_apps_icon.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_EXPERIMENTAL_ICON" file="common/app_list_experimental_icon.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_ITEM_PROGRESS_BACKGROUND" file="common/app_list_progress_bar_background.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_ITEM_PROGRESS_LEFT" file="common/app_list_progress_bar_left.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_ITEM_PROGRESS_CENTER" file="common/app_list_progress_bar_center.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_ITEM_PROGRESS_RIGHT" file="common/app_list_progress_bar_right.png" />
+        <structure type="chrome_scaled_image" name="IDR_APP_LIST_NOTIFICATIONS_ICON" file="common/app_list_notifications_icon.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_TOOLS_HOVER" file="common/app_list_tools_hover.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_TOOLS_NORMAL" file="common/app_list_tools_normal.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_TOOLS_PRESSED" file="common/app_list_tools_pressed.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_FOLDER_BACK_NORMAL" file="common/app_list_folder_back_normal.png" />
+        <structure type="chrome_scaled_image" name="IDR_APP_LIST_SEARCH_ICON" file="common/app_list_search_icon.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_SPEECH_MIC_ON" file="common/app_list_mic_on.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_SPEECH_MIC_OFF" file="common/app_list_mic_off.png" />
         <structure type="chrome_scaled_image" name="IDR_APP_LIST_SPEECH_MIC_RECORDING" file="common/app_list_mic_recording.png" />
@@ -346,6 +349,11 @@
           <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_CLOSE_HOVER" file="common/notification_close_hover.png"/>
           <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_CLOSE_PRESSED" file="common/notification_close_pressed.png"/>
         </if>
+        <if expr="desktop_linux and use_aura">
+          <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_BUBBLE_CLOSE" file="common/notification_bubble_close.png"/>
+          <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_BUBBLE_CLOSE_HOVER" file="common/notification_bubble_close_hover.png"/>
+          <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_BUBBLE_CLOSE_PRESSED" file="common/notification_bubble_close_pressed.png"/>
+        </if>
         <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_DO_NOT_DISTURB" file="common/notification_do_not_disturb.png"/>
         <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_DO_NOT_DISTURB_HOVER" file="common/notification_do_not_disturb_hover.png"/>
         <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_DO_NOT_DISTURB_PRESSED" file="common/notification_do_not_disturb_pressed.png"/>
diff --git a/ui/resources/ui_resources.target.darwin-arm.mk b/ui/resources/ui_resources.target.darwin-arm.mk
index c9dd188..79777b1 100644
--- a/ui/resources/ui_resources.target.darwin-arm.mk
+++ b/ui/resources/ui_resources.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "webui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -43,6 +45,7 @@
 
 ### Rules for action "ui_unscaled_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/resources/ui_resources.target.darwin-arm64.mk b/ui/resources/ui_resources.target.darwin-arm64.mk
index c9dd188..79777b1 100644
--- a/ui/resources/ui_resources.target.darwin-arm64.mk
+++ b/ui/resources/ui_resources.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "webui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -43,6 +45,7 @@
 
 ### Rules for action "ui_unscaled_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/resources/ui_resources.target.darwin-mips.mk b/ui/resources/ui_resources.target.darwin-mips.mk
index c9dd188..79777b1 100644
--- a/ui/resources/ui_resources.target.darwin-mips.mk
+++ b/ui/resources/ui_resources.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "webui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -43,6 +45,7 @@
 
 ### Rules for action "ui_unscaled_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/resources/ui_resources.target.darwin-x86.mk b/ui/resources/ui_resources.target.darwin-x86.mk
index c9dd188..79777b1 100644
--- a/ui/resources/ui_resources.target.darwin-x86.mk
+++ b/ui/resources/ui_resources.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "webui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -43,6 +45,7 @@
 
 ### Rules for action "ui_unscaled_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/resources/ui_resources.target.darwin-x86_64.mk b/ui/resources/ui_resources.target.darwin-x86_64.mk
index c9dd188..79777b1 100644
--- a/ui/resources/ui_resources.target.darwin-x86_64.mk
+++ b/ui/resources/ui_resources.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "webui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -43,6 +45,7 @@
 
 ### Rules for action "ui_unscaled_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/resources/ui_resources.target.linux-arm.mk b/ui/resources/ui_resources.target.linux-arm.mk
index c9dd188..79777b1 100644
--- a/ui/resources/ui_resources.target.linux-arm.mk
+++ b/ui/resources/ui_resources.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "webui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -43,6 +45,7 @@
 
 ### Rules for action "ui_unscaled_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/resources/ui_resources.target.linux-arm64.mk b/ui/resources/ui_resources.target.linux-arm64.mk
index c9dd188..79777b1 100644
--- a/ui/resources/ui_resources.target.linux-arm64.mk
+++ b/ui/resources/ui_resources.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "webui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -43,6 +45,7 @@
 
 ### Rules for action "ui_unscaled_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/resources/ui_resources.target.linux-mips.mk b/ui/resources/ui_resources.target.linux-mips.mk
index c9dd188..79777b1 100644
--- a/ui/resources/ui_resources.target.linux-mips.mk
+++ b/ui/resources/ui_resources.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "webui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -43,6 +45,7 @@
 
 ### Rules for action "ui_unscaled_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/resources/ui_resources.target.linux-x86.mk b/ui/resources/ui_resources.target.linux-x86.mk
index c9dd188..79777b1 100644
--- a/ui/resources/ui_resources.target.linux-x86.mk
+++ b/ui/resources/ui_resources.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "webui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -43,6 +45,7 @@
 
 ### Rules for action "ui_unscaled_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/resources/ui_resources.target.linux-x86_64.mk b/ui/resources/ui_resources.target.linux-x86_64.mk
index c9dd188..79777b1 100644
--- a/ui/resources/ui_resources.target.linux-x86_64.mk
+++ b/ui/resources/ui_resources.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "ui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -30,6 +31,7 @@
 
 ### Rules for action "webui_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/webui_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -43,6 +45,7 @@
 
 ### Rules for action "ui_unscaled_resources":
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/ui/ui_resources/grit/ui_unscaled_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/ui/shell_dialogs/shell_dialogs.target.darwin-arm.mk b/ui/shell_dialogs/shell_dialogs.target.darwin-arm.mk
index c867725..6c71388 100644
--- a/ui/shell_dialogs/shell_dialogs.target.darwin-arm.mk
+++ b/ui/shell_dialogs/shell_dialogs.target.darwin-arm.mk
@@ -53,7 +53,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -102,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -181,7 +175,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/shell_dialogs/shell_dialogs.target.darwin-arm64.mk b/ui/shell_dialogs/shell_dialogs.target.darwin-arm64.mk
index c71e055..856e886 100644
--- a/ui/shell_dialogs/shell_dialogs.target.darwin-arm64.mk
+++ b/ui/shell_dialogs/shell_dialogs.target.darwin-arm64.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -221,11 +216,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/shell_dialogs/shell_dialogs.target.darwin-mips.mk b/ui/shell_dialogs/shell_dialogs.target.darwin-mips.mk
index b9ae6da..cb58cb3 100644
--- a/ui/shell_dialogs/shell_dialogs.target.darwin-mips.mk
+++ b/ui/shell_dialogs/shell_dialogs.target.darwin-mips.mk
@@ -101,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -228,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/shell_dialogs/shell_dialogs.target.darwin-x86.mk b/ui/shell_dialogs/shell_dialogs.target.darwin-x86.mk
index 9fd53ea..00f8fa7 100644
--- a/ui/shell_dialogs/shell_dialogs.target.darwin-x86.mk
+++ b/ui/shell_dialogs/shell_dialogs.target.darwin-x86.mk
@@ -55,7 +55,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -103,11 +102,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -182,7 +176,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/shell_dialogs/shell_dialogs.target.darwin-x86_64.mk b/ui/shell_dialogs/shell_dialogs.target.darwin-x86_64.mk
index 8504189..c070629 100644
--- a/ui/shell_dialogs/shell_dialogs.target.darwin-x86_64.mk
+++ b/ui/shell_dialogs/shell_dialogs.target.darwin-x86_64.mk
@@ -55,7 +55,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -103,11 +102,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -183,7 +177,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -231,11 +224,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/shell_dialogs/shell_dialogs.target.linux-arm.mk b/ui/shell_dialogs/shell_dialogs.target.linux-arm.mk
index c867725..6c71388 100644
--- a/ui/shell_dialogs/shell_dialogs.target.linux-arm.mk
+++ b/ui/shell_dialogs/shell_dialogs.target.linux-arm.mk
@@ -53,7 +53,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -102,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -181,7 +175,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/shell_dialogs/shell_dialogs.target.linux-arm64.mk b/ui/shell_dialogs/shell_dialogs.target.linux-arm64.mk
index c71e055..856e886 100644
--- a/ui/shell_dialogs/shell_dialogs.target.linux-arm64.mk
+++ b/ui/shell_dialogs/shell_dialogs.target.linux-arm64.mk
@@ -98,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -221,11 +216,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/shell_dialogs/shell_dialogs.target.linux-mips.mk b/ui/shell_dialogs/shell_dialogs.target.linux-mips.mk
index b9ae6da..cb58cb3 100644
--- a/ui/shell_dialogs/shell_dialogs.target.linux-mips.mk
+++ b/ui/shell_dialogs/shell_dialogs.target.linux-mips.mk
@@ -101,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -228,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/shell_dialogs/shell_dialogs.target.linux-x86.mk b/ui/shell_dialogs/shell_dialogs.target.linux-x86.mk
index 9fd53ea..00f8fa7 100644
--- a/ui/shell_dialogs/shell_dialogs.target.linux-x86.mk
+++ b/ui/shell_dialogs/shell_dialogs.target.linux-x86.mk
@@ -55,7 +55,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -103,11 +102,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -182,7 +176,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/shell_dialogs/shell_dialogs.target.linux-x86_64.mk b/ui/shell_dialogs/shell_dialogs.target.linux-x86_64.mk
index 8504189..c070629 100644
--- a/ui/shell_dialogs/shell_dialogs.target.linux-x86_64.mk
+++ b/ui/shell_dialogs/shell_dialogs.target.linux-x86_64.mk
@@ -55,7 +55,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -103,11 +102,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -183,7 +177,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -231,11 +224,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/snapshot/snapshot.gyp b/ui/snapshot/snapshot.gyp
index e34b0c2..a6a997e 100644
--- a/ui/snapshot/snapshot.gyp
+++ b/ui/snapshot/snapshot.gyp
@@ -72,8 +72,7 @@
           ],
         }],
         # See http://crbug.com/162998#c4 for why this is needed.
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and use_allocator!="none"', {
           'dependencies': [
             '../../base/allocator/allocator.gyp:allocator',
           ],
diff --git a/ui/snapshot/snapshot.target.darwin-arm.mk b/ui/snapshot/snapshot.target.darwin-arm.mk
index ef7948f..40b2172 100644
--- a/ui/snapshot/snapshot.target.darwin-arm.mk
+++ b/ui/snapshot/snapshot.target.darwin-arm.mk
@@ -44,7 +44,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -170,7 +164,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -219,11 +212,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/snapshot/snapshot.target.darwin-arm64.mk b/ui/snapshot/snapshot.target.darwin-arm64.mk
index e836cbd..828d93f 100644
--- a/ui/snapshot/snapshot.target.darwin-arm64.mk
+++ b/ui/snapshot/snapshot.target.darwin-arm64.mk
@@ -89,11 +89,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -210,11 +205,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/snapshot/snapshot.target.darwin-mips.mk b/ui/snapshot/snapshot.target.darwin-mips.mk
index 268a8bc..e9cf86c 100644
--- a/ui/snapshot/snapshot.target.darwin-mips.mk
+++ b/ui/snapshot/snapshot.target.darwin-mips.mk
@@ -92,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -217,11 +212,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/snapshot/snapshot.target.darwin-x86.mk b/ui/snapshot/snapshot.target.darwin-x86.mk
index 930a166..b5bc79c 100644
--- a/ui/snapshot/snapshot.target.darwin-x86.mk
+++ b/ui/snapshot/snapshot.target.darwin-x86.mk
@@ -46,7 +46,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -94,11 +93,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -171,7 +165,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -219,11 +212,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/snapshot/snapshot.target.darwin-x86_64.mk b/ui/snapshot/snapshot.target.darwin-x86_64.mk
index 330e78d..93fd3d6 100644
--- a/ui/snapshot/snapshot.target.darwin-x86_64.mk
+++ b/ui/snapshot/snapshot.target.darwin-x86_64.mk
@@ -46,7 +46,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -94,11 +93,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -172,7 +166,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/snapshot/snapshot.target.linux-arm.mk b/ui/snapshot/snapshot.target.linux-arm.mk
index ef7948f..40b2172 100644
--- a/ui/snapshot/snapshot.target.linux-arm.mk
+++ b/ui/snapshot/snapshot.target.linux-arm.mk
@@ -44,7 +44,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -93,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -170,7 +164,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -219,11 +212,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/snapshot/snapshot.target.linux-arm64.mk b/ui/snapshot/snapshot.target.linux-arm64.mk
index e836cbd..828d93f 100644
--- a/ui/snapshot/snapshot.target.linux-arm64.mk
+++ b/ui/snapshot/snapshot.target.linux-arm64.mk
@@ -89,11 +89,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -210,11 +205,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/snapshot/snapshot.target.linux-mips.mk b/ui/snapshot/snapshot.target.linux-mips.mk
index 268a8bc..e9cf86c 100644
--- a/ui/snapshot/snapshot.target.linux-mips.mk
+++ b/ui/snapshot/snapshot.target.linux-mips.mk
@@ -92,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -217,11 +212,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/snapshot/snapshot.target.linux-x86.mk b/ui/snapshot/snapshot.target.linux-x86.mk
index 930a166..b5bc79c 100644
--- a/ui/snapshot/snapshot.target.linux-x86.mk
+++ b/ui/snapshot/snapshot.target.linux-x86.mk
@@ -46,7 +46,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -94,11 +93,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -171,7 +165,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -219,11 +212,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/snapshot/snapshot.target.linux-x86_64.mk b/ui/snapshot/snapshot.target.linux-x86_64.mk
index 330e78d..93fd3d6 100644
--- a/ui/snapshot/snapshot.target.linux-x86_64.mk
+++ b/ui/snapshot/snapshot.target.linux-x86_64.mk
@@ -46,7 +46,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -94,11 +93,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -172,7 +166,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -220,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/surface/surface.target.darwin-arm.mk b/ui/surface/surface.target.darwin-arm.mk
index dc4c180..434e8ac 100644
--- a/ui/surface/surface.target.darwin-arm.mk
+++ b/ui/surface/surface.target.darwin-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -96,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -177,7 +171,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -227,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/surface/surface.target.darwin-arm64.mk b/ui/surface/surface.target.darwin-arm64.mk
index 6c7f73c..fe100e8 100644
--- a/ui/surface/surface.target.darwin-arm64.mk
+++ b/ui/surface/surface.target.darwin-arm64.mk
@@ -92,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -218,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/surface/surface.target.darwin-mips.mk b/ui/surface/surface.target.darwin-mips.mk
index 66fb0ea..f60cb3a 100644
--- a/ui/surface/surface.target.darwin-mips.mk
+++ b/ui/surface/surface.target.darwin-mips.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -225,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/surface/surface.target.darwin-x86.mk b/ui/surface/surface.target.darwin-x86.mk
index 3ad4c04..e899b4d 100644
--- a/ui/surface/surface.target.darwin-x86.mk
+++ b/ui/surface/surface.target.darwin-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -97,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -227,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/surface/surface.target.darwin-x86_64.mk b/ui/surface/surface.target.darwin-x86_64.mk
index e086da8..e25afdc 100644
--- a/ui/surface/surface.target.darwin-x86_64.mk
+++ b/ui/surface/surface.target.darwin-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -97,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -179,7 +173,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -228,11 +221,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/surface/surface.target.linux-arm.mk b/ui/surface/surface.target.linux-arm.mk
index dc4c180..434e8ac 100644
--- a/ui/surface/surface.target.linux-arm.mk
+++ b/ui/surface/surface.target.linux-arm.mk
@@ -46,7 +46,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -96,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -177,7 +171,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -227,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/surface/surface.target.linux-arm64.mk b/ui/surface/surface.target.linux-arm64.mk
index 6c7f73c..fe100e8 100644
--- a/ui/surface/surface.target.linux-arm64.mk
+++ b/ui/surface/surface.target.linux-arm64.mk
@@ -92,11 +92,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -218,11 +213,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/surface/surface.target.linux-mips.mk b/ui/surface/surface.target.linux-mips.mk
index 66fb0ea..f60cb3a 100644
--- a/ui/surface/surface.target.linux-mips.mk
+++ b/ui/surface/surface.target.linux-mips.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -225,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/surface/surface.target.linux-x86.mk b/ui/surface/surface.target.linux-x86.mk
index 3ad4c04..e899b4d 100644
--- a/ui/surface/surface.target.linux-x86.mk
+++ b/ui/surface/surface.target.linux-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -97,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -227,11 +220,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/surface/surface.target.linux-x86_64.mk b/ui/surface/surface.target.linux-x86_64.mk
index e086da8..e25afdc 100644
--- a/ui/surface/surface.target.linux-x86_64.mk
+++ b/ui/surface/surface.target.linux-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -97,11 +96,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -179,7 +173,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -228,11 +221,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/ui/ui_unittests.gyp b/ui/ui_unittests.gyp
index 63c0c98..87f227e 100644
--- a/ui/ui_unittests.gyp
+++ b/ui/ui_unittests.gyp
@@ -41,13 +41,7 @@
         'base/resource/resource_bundle_unittest.cc',
         'base/test/run_all_unittests.cc',
         'gfx/font_unittest.cc',
-        'gfx/image/image_family_unittest.cc',
         'gfx/image/image_skia_unittest.cc',
-        'gfx/image/image_unittest.cc',
-        'gfx/image/image_unittest_util.cc',
-        'gfx/image/image_unittest_util.h',
-        'gfx/image/image_unittest_util_ios.mm',
-        'gfx/image/image_unittest_util_mac.mm',
         'gfx/screen_unittest.cc',
         'gfx/text_elider_unittest.cc',
         'gfx/text_utils_unittest.cc',
@@ -77,21 +71,11 @@
         'base/text/bytes_formatting_unittest.cc',
         'base/view_prop_unittest.cc',
         'base/webui/web_ui_util_unittest.cc',
-        'gfx/animation/tween_unittest.cc',
-        'gfx/blit_unittest.cc',
-        'gfx/break_list_unittest.cc',
         'gfx/canvas_unittest.cc',
         'gfx/canvas_unittest_mac.mm',
-        'gfx/codec/jpeg_codec_unittest.cc',
-        'gfx/color_analysis_unittest.cc',
         'gfx/font_list_unittest.cc',
-        'gfx/image/image_mac_unittest.mm',
-        'gfx/image/image_util_unittest.cc',
         'gfx/platform_font_mac_unittest.mm',
         'gfx/render_text_unittest.cc',
-        'gfx/sequential_id_generator_unittest.cc',
-        'gfx/transform_util_unittest.cc',
-        'gfx/utf16_indexing_unittest.cc',
       ],
       'includes': [
         'display/display_unittests.gypi',
@@ -170,8 +154,7 @@
             'gfx/platform_font_pango_unittest.cc',
           ],
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            ['(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            ['use_allocator!="none"', {
                'dependencies': [
                  '../base/allocator/allocator.gyp:allocator',
                ],
@@ -233,6 +216,11 @@
         ['chromeos==1', {
           'dependencies': [
             '../chromeos/chromeos.gyp:chromeos',
+            'aura/aura.gyp:aura_test_support',
+            'chromeos/ui_chromeos.gyp:ui_chromeos',
+          ],
+          'sources': [
+            'chromeos/touch_exploration_controller_unittest.cc'
           ],
           'sources!': [
             'base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc',
diff --git a/ui/views/accessibility/ax_aura_obj_cache.cc b/ui/views/accessibility/ax_aura_obj_cache.cc
index 43efa1e..ae2df20 100644
--- a/ui/views/accessibility/ax_aura_obj_cache.cc
+++ b/ui/views/accessibility/ax_aura_obj_cache.cc
@@ -5,6 +5,7 @@
 #include "ui/views/accessibility/ax_aura_obj_cache.h"
 
 #include "base/memory/singleton.h"
+#include "base/stl_util.h"
 #include "ui/aura/window.h"
 #include "ui/views/accessibility/ax_aura_obj_wrapper.h"
 #include "ui/views/accessibility/ax_view_obj_wrapper.h"
diff --git a/ui/views/bubble/bubble_border.cc b/ui/views/bubble/bubble_border.cc
index aa9064e..03b422a 100644
--- a/ui/views/bubble/bubble_border.cc
+++ b/ui/views/bubble/bubble_border.cc
@@ -156,7 +156,8 @@
       arrow_paint_type_(PAINT_NORMAL),
       alignment_(ALIGN_ARROW_TO_MID_ANCHOR),
       shadow_(shadow),
-      background_color_(color) {
+      background_color_(color),
+      use_theme_background_color_(false) {
   DCHECK(shadow < SHADOW_COUNT);
   images_ = GetBorderImages(shadow);
 }
diff --git a/ui/views/bubble/bubble_border.h b/ui/views/bubble/bubble_border.h
index 4fb961e..15f0f85 100644
--- a/ui/views/bubble/bubble_border.h
+++ b/ui/views/bubble/bubble_border.h
@@ -136,6 +136,13 @@
   void set_background_color(SkColor color) { background_color_ = color; }
   SkColor background_color() const { return background_color_; }
 
+  // If true, the background color should be determined by the host's
+  // NativeTheme.
+  void set_use_theme_background_color(bool use_theme_background_color) {
+    use_theme_background_color_ = use_theme_background_color;
+  }
+  bool use_theme_background_color() { return use_theme_background_color_; }
+
   // Sets a desired pixel distance between the arrow tip and the outside edge of
   // the neighboring border image. For example:    |----offset----|
   // '(' represents shadow around the '{' edge:    ((({           ^   })))
@@ -178,6 +185,7 @@
   Shadow shadow_;
   internal::BorderImages* images_;
   SkColor background_color_;
+  bool use_theme_background_color_;
 
   DISALLOW_COPY_AND_ASSIGN(BubbleBorder);
 };
diff --git a/ui/views/bubble/bubble_delegate.cc b/ui/views/bubble/bubble_delegate.cc
index 9a8fe31..9784d12 100644
--- a/ui/views/bubble/bubble_delegate.cc
+++ b/ui/views/bubble/bubble_delegate.cc
@@ -48,7 +48,6 @@
       close_on_deactivate_(true),
       anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()),
       anchor_widget_(NULL),
-      move_with_anchor_(false),
       arrow_(BubbleBorder::TOP_LEFT),
       shadow_(BubbleBorder::SMALL_SHADOW),
       color_explicitly_set_(false),
@@ -69,7 +68,6 @@
       close_on_deactivate_(true),
       anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()),
       anchor_widget_(NULL),
-      move_with_anchor_(false),
       arrow_(arrow),
       shadow_(BubbleBorder::SMALL_SHADOW),
       color_explicitly_set_(false),
@@ -174,12 +172,8 @@
 
 void BubbleDelegateView::OnWidgetBoundsChanged(Widget* widget,
                                                const gfx::Rect& new_bounds) {
-  if (anchor_widget() == widget) {
-    if (move_with_anchor())
-      SizeToContents();
-    else
-      GetWidget()->Close();
-  }
+  if (anchor_widget() == widget)
+    SizeToContents();
 }
 
 View* BubbleDelegateView::GetAnchorView() const {
@@ -250,7 +244,11 @@
   if (anchor_view)
     view_storage->StoreView(anchor_view_storage_id_, anchor_view);
 
-  if (GetWidget())
+  // Do not update anchoring for NULL views; this could indicate that our
+  // NativeWindow is being destroyed, so it would be dangerous for us to update
+  // our anchor bounds at that point. (It's safe to skip this, since if we were
+  // to update the bounds when |anchor_view| is NULL, the bubble won't move.)
+  if (anchor_view && GetWidget())
     OnAnchorBoundsChanged();
 }
 
diff --git a/ui/views/bubble/bubble_delegate.h b/ui/views/bubble/bubble_delegate.h
index 8bfd4a2..5cbda57 100644
--- a/ui/views/bubble/bubble_delegate.h
+++ b/ui/views/bubble/bubble_delegate.h
@@ -94,9 +94,6 @@
   bool adjust_if_offscreen() const { return adjust_if_offscreen_; }
   void set_adjust_if_offscreen(bool adjust) { adjust_if_offscreen_ = adjust; }
 
-  bool move_with_anchor() const { return move_with_anchor_; }
-  void set_move_with_anchor(bool move) { move_with_anchor_ = move; }
-
   // Get the arrow's anchor rect in screen space.
   virtual gfx::Rect GetAnchorRect();
 
@@ -165,9 +162,6 @@
   // The anchor rect used in the absence of an anchor view.
   gfx::Rect anchor_rect_;
 
-  // If true, the bubble will re-anchor (and may resize) with |anchor_widget_|.
-  bool move_with_anchor_;
-
   // The arrow's location on the bubble.
   BubbleBorder::Arrow arrow_;
 
diff --git a/ui/views/bubble/bubble_delegate_unittest.cc b/ui/views/bubble/bubble_delegate_unittest.cc
index 699e406..97b4dcd 100644
--- a/ui/views/bubble/bubble_delegate_unittest.cc
+++ b/ui/views/bubble/bubble_delegate_unittest.cc
@@ -234,7 +234,7 @@
   }
 }
 
-TEST_F(BubbleDelegateTest, CloseWhenAnchorWidgetBoundsChanged) {
+TEST_F(BubbleDelegateTest, VisibleWhenAnchorWidgetBoundsChanged) {
   scoped_ptr<Widget> anchor_widget(CreateTestWidget());
   BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
       anchor_widget->GetContentsView(), BubbleBorder::NONE);
@@ -245,7 +245,7 @@
   bubble_widget->Show();
   EXPECT_TRUE(bubble_widget->IsVisible());
   anchor_widget->SetBounds(gfx::Rect(10, 10, 100, 100));
-  EXPECT_FALSE(bubble_widget->IsVisible());
+  EXPECT_TRUE(bubble_widget->IsVisible());
 }
 
 }  // namespace views
diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc
index 8bad29e..1c4d70c 100644
--- a/ui/views/bubble/bubble_frame_view.cc
+++ b/ui/views/bubble/bubble_frame_view.cc
@@ -12,6 +12,7 @@
 #include "ui/gfx/path.h"
 #include "ui/gfx/screen.h"
 #include "ui/gfx/skia_util.h"
+#include "ui/native_theme/native_theme.h"
 #include "ui/views/bubble/bubble_border.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/widget/widget.h"
@@ -223,6 +224,14 @@
   UpdateWindowIcon();
 }
 
+void BubbleFrameView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
+  if (bubble_border_ && bubble_border_->use_theme_background_color()) {
+    bubble_border_->set_background_color(GetNativeTheme()->
+        GetSystemColor(ui::NativeTheme::kColorId_DialogBackground));
+    SchedulePaint();
+  }
+}
+
 void BubbleFrameView::ButtonPressed(Button* sender, const ui::Event& event) {
   if (sender == close_)
     GetWidget()->Close();
diff --git a/ui/views/bubble/bubble_frame_view.h b/ui/views/bubble/bubble_frame_view.h
index b72867b..6521343 100644
--- a/ui/views/bubble/bubble_frame_view.h
+++ b/ui/views/bubble/bubble_frame_view.h
@@ -51,6 +51,7 @@
   virtual const char* GetClassName() const OVERRIDE;
   virtual void ChildPreferredSizeChanged(View* child) OVERRIDE;
   virtual void OnThemeChanged() OVERRIDE;
+  virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE;
 
   // Overridden from ButtonListener:
   virtual void ButtonPressed(Button* sender, const ui::Event& event) OVERRIDE;
diff --git a/ui/views/bubble/tray_bubble_view.cc b/ui/views/bubble/tray_bubble_view.cc
index 31c163d..0dd7491 100644
--- a/ui/views/bubble/tray_bubble_view.cc
+++ b/ui/views/bubble/tray_bubble_view.cc
@@ -327,7 +327,6 @@
       mouse_actively_entered_(false) {
   set_parent_window(parent_window);
   set_notify_enter_exit_on_child(true);
-  set_move_with_anchor(true);
   set_close_on_deactivate(init_params.close_on_deactivate);
   set_margins(gfx::Insets());
   bubble_border_ = new TrayBubbleBorder(this, GetAnchorView(), params_);
diff --git a/ui/views/controls/button/blue_button.cc b/ui/views/controls/button/blue_button.cc
index 66fff2f..86e99a0 100644
--- a/ui/views/controls/button/blue_button.cc
+++ b/ui/views/controls/button/blue_button.cc
@@ -47,7 +47,7 @@
           *rb.GetImageSkiaNamed(IDR_BLUE_BUTTON_FOCUSED_PRESSED), insets));
   button_border->SetPainter(true, STATE_DISABLED, Painter::CreateImagePainter(
           *rb.GetImageSkiaNamed(IDR_BLUE_BUTTON_DISABLED), insets));
-  SetBorder(button_border.PassAs<Border>());
+  UpdateThemedBorder(button_border.PassAs<Border>());
 }
 
 BlueButton::~BlueButton() {}
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc
index bbd8362..691f815 100644
--- a/ui/views/controls/button/label_button.cc
+++ b/ui/views/controls/button/label_button.cc
@@ -50,7 +50,8 @@
       button_state_colors_(),
       explicitly_set_colors_(),
       is_default_(false),
-      style_(STYLE_TEXTBUTTON) {
+      style_(STYLE_TEXTBUTTON),
+      border_is_themed_border_(true) {
   SetAnimationDuration(kHoverAnimationDurationMs);
   SetText(text);
   SetFontList(gfx::FontList());
@@ -165,10 +166,7 @@
   if (style == STYLE_BUTTON)
     set_min_size(gfx::Size(70, 33));
 
-  ResetColorsFromNativeTheme();
-  UpdateThemedBorder(scoped_ptr<Border>(new LabelButtonBorder(style_)));
-  // Invalidate the layout to pickup the new insets from the border.
-  InvalidateLayout();
+  OnNativeThemeChanged(GetNativeTheme());
 }
 
 void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) {
@@ -268,6 +266,11 @@
   return kViewClassName;
 }
 
+void LabelButton::SetBorder(scoped_ptr<Border> border) {
+  border_is_themed_border_ = false;
+  View::SetBorder(border.Pass());
+}
+
 void LabelButton::OnPaint(gfx::Canvas* canvas) {
   View::OnPaint(canvas);
   Painter::PaintFocusPainter(this, canvas, focus_painter_.get());
@@ -349,6 +352,10 @@
 }
 
 void LabelButton::UpdateThemedBorder(scoped_ptr<Border> label_button_border) {
+  // Don't override borders set by others.
+  if (!border_is_themed_border_)
+    return;
+
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
   views::LinuxUI* linux_ui = views::LinuxUI::instance();
   if (linux_ui) {
@@ -358,6 +365,8 @@
   {
     SetBorder(label_button_border.Pass());
   }
+
+  border_is_themed_border_ = true;
 }
 
 void LabelButton::StateChanged() {
@@ -377,6 +386,9 @@
 
 void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) {
   ResetColorsFromNativeTheme();
+  UpdateThemedBorder(scoped_ptr<Border>(new LabelButtonBorder(style_)));
+  // Invalidate the layout to pickup the new insets from the border.
+  InvalidateLayout();
 }
 
 ui::NativeTheme::Part LabelButton::GetThemePart() const {
diff --git a/ui/views/controls/button/label_button.h b/ui/views/controls/button/label_button.h
index 2359dbc..8b76913 100644
--- a/ui/views/controls/button/label_button.h
+++ b/ui/views/controls/button/label_button.h
@@ -74,6 +74,7 @@
   void SetFocusPainter(scoped_ptr<Painter> focus_painter);
 
   // View:
+  virtual void SetBorder(scoped_ptr<Border> border) OVERRIDE;
   virtual gfx::Size GetPreferredSize() OVERRIDE;
   virtual void Layout() OVERRIDE;
   virtual const char* GetClassName() const OVERRIDE;
@@ -156,6 +157,9 @@
   // The button's overall style.
   ButtonStyle style_;
 
+  // True if current border was set by UpdateThemedBorder. Defaults to true.
+  bool border_is_themed_border_;
+
   scoped_ptr<Painter> focus_painter_;
 
   DISALLOW_COPY_AND_ASSIGN(LabelButton);
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
index 9b20f0c..6d513a1 100644
--- a/ui/views/controls/textfield/textfield.cc
+++ b/ui/views/controls/textfield/textfield.cc
@@ -548,7 +548,6 @@
 #endif
   }
 
-  touch_selection_controller_.reset();
   return true;
 }
 
@@ -592,7 +591,6 @@
 
 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) {
   bool handled = controller_ && controller_->HandleKeyEvent(this, event);
-  touch_selection_controller_.reset();
   if (handled)
     return true;
 
@@ -685,7 +683,7 @@
           event->SetHandled();
       } else if (switches::IsTouchDragDropEnabled()) {
         initiating_drag_ = true;
-        touch_selection_controller_.reset();
+        DestroyTouchSelection();
       } else {
         if (!touch_selection_controller_)
           CreateTouchSelectionControllerAndNotifyIt();
@@ -887,7 +885,7 @@
     RepaintCursor();
   }
 
-  touch_selection_controller_.reset();
+  DestroyTouchSelection();
 
   // Border typically draws focus indicator.
   SchedulePaint();
@@ -1036,10 +1034,14 @@
 }
 
 void Textfield::OpenContextMenu(const gfx::Point& anchor) {
-  touch_selection_controller_.reset();
+  DestroyTouchSelection();
   ShowContextMenu(anchor, ui::MENU_SOURCE_TOUCH_EDIT_MENU);
 }
 
+void Textfield::DestroyTouchSelection() {
+  touch_selection_controller_.reset();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Textfield, ui::SimpleMenuModel::Delegate overrides:
 
@@ -1099,7 +1101,7 @@
 }
 
 void Textfield::ExecuteCommand(int command_id, int event_flags) {
-  touch_selection_controller_.reset();
+  DestroyTouchSelection();
   if (!IsCommandIdEnabled(command_id))
     return;
 
@@ -1334,7 +1336,7 @@
   size_t text_index = composition_range.start() + index;
   if (composition_range.end() <= text_index)
     return false;
-  if (!render_text->IsCursorablePosition(text_index)) {
+  if (!render_text->IsValidCursorIndex(text_index)) {
     text_index = render_text->IndexOfAdjacentGrapheme(
         text_index, gfx::CURSOR_BACKWARD);
   }
@@ -1486,7 +1488,7 @@
     cursor_visible_ = true;
     RepaintCursor();
     if (cursor_repaint_timer_.IsRunning())
-    cursor_repaint_timer_.Reset();
+      cursor_repaint_timer_.Reset();
     if (!text_changed) {
       // TEXT_CHANGED implies SELECTION_CHANGED, so we only need to fire
       // this if only the selection changed.
diff --git a/ui/views/controls/textfield/textfield.h b/ui/views/controls/textfield/textfield.h
index 809539c..7635eca 100644
--- a/ui/views/controls/textfield/textfield.h
+++ b/ui/views/controls/textfield/textfield.h
@@ -242,6 +242,7 @@
   virtual void ConvertPointFromScreen(gfx::Point* point) OVERRIDE;
   virtual bool DrawsHandles() OVERRIDE;
   virtual void OpenContextMenu(const gfx::Point& anchor) OVERRIDE;
+  virtual void DestroyTouchSelection() OVERRIDE;
 
   // ui::SimpleMenuModel::Delegate overrides:
   virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
diff --git a/ui/views/controls/textfield/textfield_model.cc b/ui/views/controls/textfield/textfield_model.cc
index 5feca83..a6ca343 100644
--- a/ui/views/controls/textfield/textfield_model.cc
+++ b/ui/views/controls/textfield/textfield_model.cc
@@ -398,24 +398,27 @@
   render_text_->MoveCursor(break_type, direction, select);
 }
 
-bool TextfieldModel::MoveCursorTo(const gfx::SelectionModel& model) {
+bool TextfieldModel::MoveCursorTo(const gfx::SelectionModel& cursor) {
   if (HasCompositionText()) {
     ConfirmCompositionText();
     // ConfirmCompositionText() updates cursor position. Need to reflect it in
     // the SelectionModel parameter of MoveCursorTo().
-    gfx::Range range(render_text_->selection().start(), model.caret_pos());
+    gfx::Range range(render_text_->selection().start(), cursor.caret_pos());
     if (!range.is_empty())
       return render_text_->SelectRange(range);
     return render_text_->MoveCursorTo(
-        gfx::SelectionModel(model.caret_pos(), model.caret_affinity()));
+        gfx::SelectionModel(cursor.caret_pos(), cursor.caret_affinity()));
   }
-  return render_text_->MoveCursorTo(model);
+  return render_text_->MoveCursorTo(cursor);
 }
 
 bool TextfieldModel::MoveCursorTo(const gfx::Point& point, bool select) {
   if (HasCompositionText())
     ConfirmCompositionText();
-  return render_text_->MoveCursorTo(point, select);
+  gfx::SelectionModel cursor = render_text_->FindCursorPosition(point);
+  if (select)
+    cursor.set_selection_start(render_text_->selection().start());
+  return render_text_->MoveCursorTo(cursor);
 }
 
 base::string16 TextfieldModel::GetSelectedText() const {
diff --git a/ui/views/controls/textfield/textfield_model.h b/ui/views/controls/textfield/textfield_model.h
index c420648..00ebc7c 100644
--- a/ui/views/controls/textfield/textfield_model.h
+++ b/ui/views/controls/textfield/textfield_model.h
@@ -48,7 +48,7 @@
 // It supports editing, selection and cursor manipulation.
 class VIEWS_EXPORT TextfieldModel {
  public:
-  // Delegate interface implemented by the textfield view class to provided
+  // Delegate interface implemented by the textfield view class to provide
   // additional functionalities required by the model.
   class VIEWS_EXPORT Delegate {
    public:
@@ -123,11 +123,9 @@
                   gfx::VisualCursorDirection direction,
                   bool select);
 
-  // Moves the selection to the specified selection in |selection|.
-  // If there is composition text, it will be confirmed, which will update the
-  // selection range, and it overrides the selection_start to which the
-  // selection will move to.
-  bool MoveCursorTo(const gfx::SelectionModel& selection);
+  // Updates the cursor to the specified selection model. Any composition text
+  // will be confirmed, which may alter the specified selection range start.
+  bool MoveCursorTo(const gfx::SelectionModel& cursor);
 
   // Helper function to call MoveCursorTo on the TextfieldModel.
   bool MoveCursorTo(const gfx::Point& point, bool select);
diff --git a/ui/views/controls/webview/webview.cc b/ui/views/controls/webview/webview.cc
index 8da7e22..11d8acd 100644
--- a/ui/views/controls/webview/webview.cc
+++ b/ui/views/controls/webview/webview.cc
@@ -10,10 +10,10 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ipc/ipc_message.h"
 #include "ui/accessibility/ax_enums.h"
 #include "ui/accessibility/ax_view_state.h"
+#include "ui/base/ui_base_switches_util.h"
 #include "ui/events/event.h"
 #include "ui/views/accessibility/native_view_accessibility.h"
 #include "ui/views/controls/native/native_view_host.h"
@@ -67,6 +67,7 @@
     DCHECK(!is_embedding_fullscreen_widget_);
   }
   AttachWebContents();
+  NotifyMaybeTextInputClientChanged();
 }
 
 void WebView::SetEmbedFullscreenWidgetMode(bool enable) {
@@ -103,6 +104,24 @@
   return kViewClassName;
 }
 
+ui::TextInputClient* WebView::GetTextInputClient() {
+  // This function delegates the text input handling to the underlying
+  // content::RenderWidgetHostView.  So when the underlying RWHV is destroyed or
+  // replaced with another one, we have to notify the FocusManager through
+  // FocusManager::OnTextInputClientChanged() that the focused TextInputClient
+  // needs to be updated.
+  if (switches::IsTextInputFocusManagerEnabled() &&
+      web_contents() && !web_contents()->IsBeingDestroyed()) {
+    content::RenderWidgetHostView* host_view =
+        is_embedding_fullscreen_widget_ ?
+        web_contents()->GetFullscreenRenderWidgetHostView() :
+        web_contents()->GetRenderWidgetHostView();
+    if (host_view)
+      return host_view->GetTextInputClient();
+  }
+  return NULL;
+}
+
 void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
   // In most cases, the holder is simply sized to fill this WebView's bounds.
   // Only WebContentses that are in fullscreen mode and being screen-captured
@@ -182,7 +201,7 @@
     if (current_fs_view)
       current_fs_view->Focus();
   } else {
-    web_contents()->GetView()->Focus();
+    web_contents()->Focus();
   }
 }
 
@@ -229,11 +248,16 @@
 ////////////////////////////////////////////////////////////////////////////////
 // WebView, content::WebContentsObserver implementation:
 
+void WebView::RenderViewDeleted(content::RenderViewHost* render_view_host) {
+  NotifyMaybeTextInputClientChanged();
+}
+
 void WebView::RenderViewHostChanged(content::RenderViewHost* old_host,
                                     content::RenderViewHost* new_host) {
   FocusManager* const focus_manager = GetFocusManager();
   if (focus_manager && focus_manager->GetFocusedView() == this)
     OnFocus();
+  NotifyMaybeTextInputClientChanged();
 }
 
 void WebView::DidShowFullscreenWidget(int routing_id) {
@@ -262,7 +286,7 @@
 
   const gfx::NativeView view_to_attach = is_embedding_fullscreen_widget_ ?
       web_contents()->GetFullscreenRenderWidgetHostView()->GetNativeView() :
-      web_contents()->GetView()->GetNativeView();
+      web_contents()->GetNativeView();
   OnBoundsChanged(bounds());
   if (holder_->native_view() == view_to_attach)
     return;
@@ -309,6 +333,14 @@
     // the same.  So, do not change attachment.
     OnBoundsChanged(bounds());
   }
+  NotifyMaybeTextInputClientChanged();
+}
+
+void WebView::NotifyMaybeTextInputClientChanged() {
+  // Update the TextInputClient as needed; see GetTextInputClient().
+  FocusManager* const focus_manager = GetFocusManager();
+  if (focus_manager)
+    focus_manager->OnTextInputClientChanged(this);
 }
 
 content::WebContents* WebView::CreateWebContents(
diff --git a/ui/views/controls/webview/webview.h b/ui/views/controls/webview/webview.h
index df0c61c..0bb0c68 100644
--- a/ui/views/controls/webview/webview.h
+++ b/ui/views/controls/webview/webview.h
@@ -94,6 +94,7 @@
 
   // Overridden from View:
   virtual const char* GetClassName() const OVERRIDE;
+  virtual ui::TextInputClient* GetTextInputClient() OVERRIDE;
 
  protected:
   // Overridden from View:
@@ -114,6 +115,8 @@
   virtual bool EmbedsFullscreenWidget() const OVERRIDE;
 
   // Overridden from content::WebContentsObserver:
+  virtual void RenderViewDeleted(
+      content::RenderViewHost* render_view_host) OVERRIDE;
   virtual void RenderViewHostChanged(
       content::RenderViewHost* old_host,
       content::RenderViewHost* new_host) OVERRIDE;
@@ -129,6 +132,7 @@
   void AttachWebContents();
   void DetachWebContents();
   void ReattachForFullscreenChange(bool enter_fullscreen);
+  void NotifyMaybeTextInputClientChanged();
 
   // Create a regular or test web contents (based on whether we're running
   // in a unit test or not).
diff --git a/ui/views/controls/webview/webview_interactive_uitest.cc b/ui/views/controls/webview/webview_interactive_uitest.cc
new file mode 100644
index 0000000..c5f65a2
--- /dev/null
+++ b/ui/views/controls/webview/webview_interactive_uitest.cc
@@ -0,0 +1,79 @@
+// 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.
+
+#include "ui/views/controls/webview/webview.h"
+
+#include "base/command_line.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/test_browser_context.h"
+#include "ui/base/ime/text_input_focus_manager.h"
+#include "ui/base/ui_base_switches.h"
+#include "ui/gl/gl_surface.h"
+#include "ui/views/test/webview_test_helper.h"
+#include "ui/views/test/widget_test.h"
+
+namespace {
+
+class WebViewInteractiveUiTest : public views::test::WidgetTest {
+ public:
+  WebViewInteractiveUiTest() {}
+
+  virtual void SetUp() OVERRIDE {
+    gfx::GLSurface::InitializeOneOffForTests();
+    WidgetTest::SetUp();
+  }
+
+ protected:
+  content::BrowserContext* browser_context() { return &browser_context_; }
+
+ private:
+  content::TestBrowserContext browser_context_;
+  views::WebViewTestHelper webview_test_helper_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebViewInteractiveUiTest);
+};
+
+TEST_F(WebViewInteractiveUiTest, TextInputClientIsUpToDate) {
+  // WebViewInteractiveUiTest.TextInputClientIsUpToDate needs
+  // kEnableTextInputFocusManager flag to be enabled.
+  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
+  cmd_line->AppendSwitch(switches::kEnableTextInputFocusManager);
+
+  // Create a top level widget and a webview as its content.
+  views::Widget* widget = CreateTopLevelFramelessPlatformWidget();
+  views::WebView* webview = new views::WebView(browser_context());
+  widget->SetContentsView(webview);
+  widget->Show();
+  webview->RequestFocus();
+
+  ui::TextInputFocusManager* text_input_focus_manager =
+      ui::TextInputFocusManager::GetInstance();
+  const ui::TextInputClient* null_text_input_client = NULL;
+  EXPECT_EQ(null_text_input_client, webview->GetTextInputClient());
+  EXPECT_EQ(text_input_focus_manager->GetFocusedTextInputClient(),
+            webview->GetTextInputClient());
+
+  // Case 1: Creates a new WebContents.
+  webview->GetWebContents();
+  webview->RequestFocus();
+  ui::TextInputClient* client1 = webview->GetTextInputClient();
+  EXPECT_NE(null_text_input_client, client1);
+  EXPECT_EQ(text_input_focus_manager->GetFocusedTextInputClient(), client1);
+
+  // Case 2: Replaces a WebContents by SetWebContents().
+  content::WebContents::CreateParams params(browser_context());
+  scoped_ptr<content::WebContents> web_contents(
+      content::WebContents::Create(params));
+  webview->SetWebContents(web_contents.get());
+  ui::TextInputClient* client2 = webview->GetTextInputClient();
+  EXPECT_NE(null_text_input_client, client2);
+  EXPECT_EQ(text_input_focus_manager->GetFocusedTextInputClient(), client2);
+  EXPECT_NE(client1, client2);
+
+  widget->Close();
+  RunPendingMessages();
+}
+
+}  // namespace
diff --git a/ui/views/examples/bubble_example.cc b/ui/views/examples/bubble_example.cc
index 03561e1..49a60e5 100644
--- a/ui/views/examples/bubble_example.cc
+++ b/ui/views/examples/bubble_example.cc
@@ -105,10 +105,8 @@
   else if (sender == small_shadow_)
     bubble->set_shadow(BubbleBorder::SMALL_SHADOW);
 
-  if (sender == persistent_) {
+  if (sender == persistent_)
     bubble->set_close_on_deactivate(false);
-    bubble->set_move_with_anchor(true);
-  }
 
   BubbleDelegateView::CreateBubble(bubble);
   if (sender == align_to_edge_)
diff --git a/ui/views/examples/content_client/examples_browser_main_parts.cc b/ui/views/examples/content_client/examples_browser_main_parts.cc
index 16e5eb6..121678f 100644
--- a/ui/views/examples/content_client/examples_browser_main_parts.cc
+++ b/ui/views/examples/content_client/examples_browser_main_parts.cc
@@ -60,7 +60,7 @@
   // Ensure Aura knows where to open new windows.
   window_context = wm_test_helper_->host()->window();
 #else
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
   gfx::Screen::SetScreenInstance(
       gfx::SCREEN_TYPE_NATIVE, CreateDesktopScreen());
 #endif
diff --git a/ui/views/examples/examples_main.cc b/ui/views/examples/examples_main.cc
index 90802d4..d1be4b6 100644
--- a/ui/views/examples/examples_main.cc
+++ b/ui/views/examples/examples_main.cc
@@ -66,7 +66,7 @@
 
   ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file);
 
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
 
   ui::InitializeInputMethodForTesting();
 
diff --git a/ui/views/examples/webview_example.cc b/ui/views/examples/webview_example.cc
index 5a2d89d..feae6b9 100644
--- a/ui/views/examples/webview_example.cc
+++ b/ui/views/examples/webview_example.cc
@@ -6,7 +6,6 @@
 
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/layout/fill_layout.h"
 
@@ -28,7 +27,7 @@
   container->AddChildView(webview_);
 
   webview_->LoadInitialURL(GURL("http://www.google.com/"));
-  webview_->web_contents()->GetView()->Focus();
+  webview_->web_contents()->Focus();
 }
 
 }  // namespace examples
diff --git a/ui/views/focus/focus_manager.cc b/ui/views/focus/focus_manager.cc
index aba46e0..b4bbd17 100644
--- a/ui/views/focus/focus_manager.cc
+++ b/ui/views/focus/focus_manager.cc
@@ -11,6 +11,10 @@
 #include "base/logging.h"
 #include "build/build_config.h"
 #include "ui/base/accelerators/accelerator.h"
+#include "ui/base/ime/input_method.h"
+#include "ui/base/ime/text_input_client.h"
+#include "ui/base/ime/text_input_focus_manager.h"
+#include "ui/base/ui_base_switches_util.h"
 #include "ui/events/event.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/views/focus/focus_manager_delegate.h"
@@ -321,14 +325,18 @@
 
   View* old_focused_view = focused_view_;
   focused_view_ = view;
-  if (old_focused_view)
+  if (old_focused_view) {
     old_focused_view->Blur();
+    BlurTextInputClient(old_focused_view);
+  }
   // Also make |focused_view_| the stored focus view. This way the stored focus
   // view is remembered if focus changes are requested prior to a show or while
   // hidden.
   SetStoredFocusView(focused_view_);
-  if (focused_view_)
+  if (focused_view_) {
+    FocusTextInputClient(focused_view_);
     focused_view_->Focus();
+  }
 
   FOR_EACH_OBSERVER(FocusChangeListener, focus_change_listeners_,
                     OnDidChangeFocus(old_focused_view, focused_view_));
@@ -427,6 +435,46 @@
   SetStoredFocusView(NULL);
 }
 
+void FocusManager::OnTextInputClientChanged(View* view) {
+  if (view == focused_view_)
+    FocusTextInputClient(view);
+}
+
+void FocusManager::FocusTextInputClient(View* view) {
+  if (!switches::IsTextInputFocusManagerEnabled())
+    return;
+
+  // If the widget is not active, do not steal the text input focus.
+  if (!widget_->IsActive())
+    return;
+
+  ui::TextInputClient* text_input_client =
+      view ? view->GetTextInputClient() : NULL;
+  ui::TextInputFocusManager::GetInstance()->
+      FocusTextInputClient(text_input_client);
+  ui::InputMethod* input_method = widget_->GetHostInputMethod();
+  if (input_method) {
+    input_method->OnTextInputTypeChanged(text_input_client);
+    input_method->OnCaretBoundsChanged(text_input_client);
+  }
+}
+
+void FocusManager::BlurTextInputClient(View* view) {
+  if (!switches::IsTextInputFocusManagerEnabled())
+    return;
+
+  ui::TextInputClient* text_input_client =
+      view ? view->GetTextInputClient() : NULL;
+  if (text_input_client && text_input_client->HasCompositionText()) {
+    text_input_client->ConfirmCompositionText();
+    ui::InputMethod* input_method = widget_->GetHostInputMethod();
+    if (input_method && input_method->GetTextInputClient() == text_input_client)
+      input_method->CancelComposition(text_input_client);
+  }
+  ui::TextInputFocusManager::GetInstance()->
+      BlurTextInputClient(text_input_client);
+}
+
 // Find the next (previous if reverse is true) focusable view for the specified
 // FocusTraversable, starting at the specified view, traversing down the
 // FocusTraversable hierarchy.
diff --git a/ui/views/focus/focus_manager.h b/ui/views/focus/focus_manager.h
index 7d7c7dc..ebdc2a3 100644
--- a/ui/views/focus/focus_manager.h
+++ b/ui/views/focus/focus_manager.h
@@ -72,8 +72,8 @@
 // is FocusTraversable.
 
 namespace ui {
-class AcceleratorTarget;
 class AcceleratorManager;
+class AcceleratorTarget;
 class EventHandler;
 class KeyEvent;
 }
@@ -213,6 +213,15 @@
   // Returns true if in the process of changing the focused view.
   bool is_changing_focus() const { return is_changing_focus_; }
 
+  // Changes the text input focus to |view->GetTextInputClient()| iff |view|
+  // is focused.  Views must call this method when their internal
+  // TextInputClient instance changes.
+  void OnTextInputClientChanged(View* view);
+
+  // Moves the text input focus into/out from |view|.
+  void FocusTextInputClient(View* view);
+  void BlurTextInputClient(View* view);
+
   // Disable shortcut handling.
   static void set_shortcut_handling_suspended(bool suspended) {
     shortcut_handling_suspended_ = suspended;
diff --git a/ui/views/ime/null_input_method.cc b/ui/views/ime/null_input_method.cc
new file mode 100644
index 0000000..666d6cf
--- /dev/null
+++ b/ui/views/ime/null_input_method.cc
@@ -0,0 +1,62 @@
+// 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.
+
+#include "ui/views/ime/null_input_method.h"
+
+namespace views {
+
+NullInputMethod::NullInputMethod() {}
+
+void NullInputMethod::SetDelegate(
+    internal::InputMethodDelegate* /* delegate */) {}
+
+void NullInputMethod::Init(Widget* /* widget */) {}
+
+void NullInputMethod::OnFocus() {}
+
+void NullInputMethod::OnBlur() {}
+
+bool NullInputMethod::OnUntranslatedIMEMessage(
+    const base::NativeEvent& /* event */,
+    NativeEventResult* /* result */) {
+  return false;
+}
+
+void NullInputMethod::DispatchKeyEvent(const ui::KeyEvent& /* key */) {}
+
+void NullInputMethod::OnTextInputTypeChanged(View* /* view */) {}
+
+void NullInputMethod::OnCaretBoundsChanged(View* /* view */) {}
+
+void NullInputMethod::CancelComposition(View* /* view */) {}
+
+void NullInputMethod::OnInputLocaleChanged() {}
+
+std::string NullInputMethod::GetInputLocale() {
+  return std::string();
+}
+
+bool NullInputMethod::IsActive() {
+  return false;
+}
+
+ui::TextInputClient* NullInputMethod::GetTextInputClient() const {
+  return NULL;
+}
+
+ui::TextInputType NullInputMethod::GetTextInputType() const {
+  return ui::TEXT_INPUT_TYPE_NONE;
+}
+
+bool NullInputMethod::IsCandidatePopupOpen() const {
+  return false;
+}
+
+void NullInputMethod::ShowImeIfNeeded() {}
+
+bool NullInputMethod::IsMock() const {
+  return false;
+}
+
+}  // namespace views
diff --git a/ui/views/ime/null_input_method.h b/ui/views/ime/null_input_method.h
new file mode 100644
index 0000000..49234d3
--- /dev/null
+++ b/ui/views/ime/null_input_method.h
@@ -0,0 +1,50 @@
+// 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.
+
+#ifndef UI_VIEWS_IME_NULL_INPUT_METHOD_H_
+#define UI_VIEWS_IME_NULL_INPUT_METHOD_H_
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "ui/views/ime/input_method.h"
+
+namespace views {
+
+// An implementation of views::InputMethod which does nothing.
+//
+// We're working on removing views::InputMethod{,Base,Bridge} and going to use
+// only ui::InputMethod.  Use this class instead of views::InputMethodBridge
+// with ui::TextInputFocusManager to effectively eliminate the
+// views::InputMethod layer.
+class NullInputMethod : public InputMethod {
+ public:
+  NullInputMethod();
+
+  // Overridden from InputMethod:
+  virtual void SetDelegate(internal::InputMethodDelegate* delegate) OVERRIDE;
+  virtual void Init(Widget* widget) OVERRIDE;
+  virtual void OnFocus() OVERRIDE;
+  virtual void OnBlur() OVERRIDE;
+  virtual bool OnUntranslatedIMEMessage(const base::NativeEvent& event,
+                                        NativeEventResult* result) OVERRIDE;
+  virtual void DispatchKeyEvent(const ui::KeyEvent& key) OVERRIDE;
+  virtual void OnTextInputTypeChanged(View* view) OVERRIDE;
+  virtual void OnCaretBoundsChanged(View* view) OVERRIDE;
+  virtual void CancelComposition(View* view) OVERRIDE;
+  virtual void OnInputLocaleChanged() OVERRIDE;
+  virtual std::string GetInputLocale() OVERRIDE;
+  virtual bool IsActive() OVERRIDE;
+  virtual ui::TextInputClient* GetTextInputClient() const OVERRIDE;
+  virtual ui::TextInputType GetTextInputType() const OVERRIDE;
+  virtual bool IsCandidatePopupOpen() const OVERRIDE;
+  virtual void ShowImeIfNeeded() OVERRIDE;
+  virtual bool IsMock() const OVERRIDE;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NullInputMethod);
+};
+
+}  // namespace views
+
+#endif  // UI_VIEWS_IME_NULL_INPUT_METHOD_H_
diff --git a/ui/views/touchui/touch_editing_menu.cc b/ui/views/touchui/touch_editing_menu.cc
index 0536e74..b17039c 100644
--- a/ui/views/touchui/touch_editing_menu.cc
+++ b/ui/views/touchui/touch_editing_menu.cc
@@ -39,11 +39,11 @@
 
 TouchEditingMenuView::TouchEditingMenuView(
     TouchEditingMenuController* controller,
-    gfx::Rect anchor_rect,
+    const gfx::Rect& anchor_rect,
+    const gfx::Size& handle_image_size,
     gfx::NativeView context)
     : BubbleDelegateView(NULL, views::BubbleBorder::BOTTOM_CENTER),
       controller_(controller) {
-  SetAnchorRect(anchor_rect);
   set_shadow(views::BubbleBorder::SMALL_SHADOW);
   set_parent_window(context);
   set_margins(gfx::Insets(kMenuMargin, kMenuMargin, kMenuMargin, kMenuMargin));
@@ -53,6 +53,16 @@
   SetLayoutManager(new BoxLayout(BoxLayout::kHorizontal, 0, 0,
       kSpacingBetweenButtons));
   CreateButtons();
+
+  // After buttons are created, check if there is enough room between handles to
+  // show the menu and adjust anchor rect properly if needed, just in case the
+  // menu is needed to be shown under the selection.
+  gfx::Rect adjusted_anchor_rect(anchor_rect);
+  int menu_width = GetPreferredSize().width();
+  if (menu_width > anchor_rect.width() - handle_image_size.width())
+    adjusted_anchor_rect.Inset(0, 0, 0, -handle_image_size.height());
+  SetAnchorRect(adjusted_anchor_rect);
+
   views::BubbleDelegateView::CreateBubble(this);
   GetWidget()->Show();
 }
@@ -63,12 +73,15 @@
 // static
 TouchEditingMenuView* TouchEditingMenuView::Create(
     TouchEditingMenuController* controller,
-    gfx::Rect anchor_rect,
+    const gfx::Rect& anchor_rect,
+    const gfx::Size& handle_image_size,
     gfx::NativeView context) {
   if (controller) {
     for (size_t i = 0; i < arraysize(kMenuCommands); i++) {
-      if (controller->IsCommandIdEnabled(kMenuCommands[i]))
-        return new TouchEditingMenuView(controller, anchor_rect, context);
+      if (controller->IsCommandIdEnabled(kMenuCommands[i])) {
+        return new TouchEditingMenuView(controller, anchor_rect,
+                                        handle_image_size, context);
+      }
     }
   }
   return NULL;
diff --git a/ui/views/touchui/touch_editing_menu.h b/ui/views/touchui/touch_editing_menu.h
index e4fe549..19f0d34 100644
--- a/ui/views/touchui/touch_editing_menu.h
+++ b/ui/views/touchui/touch_editing_menu.h
@@ -45,14 +45,16 @@
   // If there are no actions available for the menu, returns NULL. Otherwise,
   // returns a new instance of TouchEditingMenuView.
   static TouchEditingMenuView* Create(TouchEditingMenuController* controller,
-                                      gfx::Rect anchor_rect,
+                                      const gfx::Rect& anchor_rect,
+                                      const gfx::Size& handle_image_size,
                                       gfx::NativeView context);
 
   void Close();
 
  private:
   TouchEditingMenuView(TouchEditingMenuController* controller,
-                       gfx::Rect anchor_rect,
+                       const gfx::Rect& anchor_rect,
+                       const gfx::Size& handle_image_size,
                        gfx::NativeView context);
 
   // views::WidgetDelegate overrides:
diff --git a/ui/views/touchui/touch_selection_controller_impl.cc b/ui/views/touchui/touch_selection_controller_impl.cc
index 763096f..316fe3b 100644
--- a/ui/views/touchui/touch_selection_controller_impl.cc
+++ b/ui/views/touchui/touch_selection_controller_impl.cc
@@ -7,6 +7,8 @@
 #include "base/time/time.h"
 #include "grit/ui_resources.h"
 #include "grit/ui_strings.h"
+#include "ui/aura/client/cursor_client.h"
+#include "ui/aura/env.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/image/image.h"
@@ -330,10 +332,12 @@
       client_view_->GetNativeView());
   if (client_widget_)
     client_widget_->AddObserver(this);
+  aura::Env::GetInstance()->AddPreTargetHandler(this);
 }
 
 TouchSelectionControllerImpl::~TouchSelectionControllerImpl() {
   HideContextMenu();
+  aura::Env::GetInstance()->RemovePreTargetHandler(this);
   if (client_widget_)
     client_widget_->RemoveObserver(this);
 }
@@ -522,6 +526,21 @@
   SelectionChanged();
 }
 
+void TouchSelectionControllerImpl::OnKeyEvent(ui::KeyEvent* event) {
+  client_view_->DestroyTouchSelection();
+}
+
+void TouchSelectionControllerImpl::OnMouseEvent(ui::MouseEvent* event) {
+  aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
+      client_view_->GetNativeView()->GetRootWindow());
+  if (!cursor_client || cursor_client->IsMouseEventsEnabled())
+    client_view_->DestroyTouchSelection();
+}
+
+void TouchSelectionControllerImpl::OnScrollEvent(ui::ScrollEvent* event) {
+  client_view_->DestroyTouchSelection();
+}
+
 void TouchSelectionControllerImpl::ContextMenuTimerFired() {
   // Get selection end points in client_view's space.
   gfx::Rect end_rect_1_in_screen;
@@ -554,6 +573,7 @@
 
   DCHECK(!context_menu_);
   context_menu_ = TouchEditingMenuView::Create(this, menu_anchor,
+                                               GetHandleImageSize(),
                                                client_view_->GetNativeView());
 }
 
diff --git a/ui/views/touchui/touch_selection_controller_impl.h b/ui/views/touchui/touch_selection_controller_impl.h
index bbb7fee..6145e97 100644
--- a/ui/views/touchui/touch_selection_controller_impl.h
+++ b/ui/views/touchui/touch_selection_controller_impl.h
@@ -19,7 +19,8 @@
 class VIEWS_EXPORT TouchSelectionControllerImpl
     : public ui::TouchSelectionController,
       public TouchEditingMenuController,
-      public WidgetObserver {
+      public WidgetObserver,
+      public ui::EventHandler {
  public:
   class EditingHandleView;
 
@@ -69,6 +70,11 @@
   virtual void OnWidgetBoundsChanged(Widget* widget,
                                      const gfx::Rect& new_bounds) OVERRIDE;
 
+  // Overriden from ui::EventHandler.
+  virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE;
+  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
+  virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE;
+
   // Time to show context menu.
   void ContextMenuTimerFired();
 
diff --git a/ui/views/touchui/touch_selection_controller_impl_unittest.cc b/ui/views/touchui/touch_selection_controller_impl_unittest.cc
index cf0daea..07d78c4 100644
--- a/ui/views/touchui/touch_selection_controller_impl_unittest.cc
+++ b/ui/views/touchui/touch_selection_controller_impl_unittest.cc
@@ -36,6 +36,12 @@
 // touch_selection_controller.
 const int kBarBottomAllowance = 3;
 
+// Should match kMenuButtonWidth in touch_editing_menu.
+const int kMenuButtonWidth = 63;
+
+// Should match size of kMenuCommands array in touch_editing_menu.
+const int kMenuCommandCount = 3;
+
 gfx::Image* GetHandleImage() {
   static gfx::Image* handle_image = NULL;
   if (!handle_image) {
@@ -69,9 +75,9 @@
   }
 
   virtual void TearDown() {
-    if (textfield_widget_)
+    if (textfield_widget_ && !textfield_widget_->IsClosed())
       textfield_widget_->Close();
-    if (widget_)
+    if (widget_ && !widget_->IsClosed())
       widget_->Close();
     ViewsTestBase::TearDown();
   }
@@ -86,7 +92,7 @@
     textfield_widget_->SetContentsView(container);
     container->AddChildView(textfield_);
 
-    textfield_->SetBoundsRect(params.bounds);
+    textfield_->SetBoundsRect(gfx::Rect(0, 0, 200, 20));
     textfield_->set_id(1);
     textfield_widget_->Show();
 
@@ -594,6 +600,9 @@
   virtual void OpenContextMenu(const gfx::Point& anchor) OVERRIDE {
     NOTREACHED();
   }
+  virtual void DestroyTouchSelection() OVERRIDE {
+    NOTREACHED();
+  }
 
   // Overridden from ui::SimpleMenuModel::Delegate.
   virtual bool IsCommandIdChecked(int command_id) const OVERRIDE {
@@ -708,4 +717,128 @@
             targeter->FindTargetForEvent(root, &test_event3));
 }
 
+// A simple implementation of TouchEditingMenuController that enables all
+// available commands.
+class TestTouchEditingMenuController : public TouchEditingMenuController {
+ public:
+  TestTouchEditingMenuController() {}
+  virtual ~TestTouchEditingMenuController() {}
+
+  // Overriden from TouchEditingMenuController.
+  virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE {
+    // Return true, since we want the menu to have all |kMenuCommandCount|
+    // available commands.
+    return true;
+  }
+  virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE {
+    NOTREACHED();
+  }
+  virtual void OpenContextMenu() OVERRIDE {
+    NOTREACHED();
+  }
+  virtual void OnMenuClosed(TouchEditingMenuView* menu) OVERRIDE {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestTouchEditingMenuController);
+};
+
+// Tests if anchor rect for touch editing quick menu is adjusted correctly based
+// on the distance of handles.
+TEST_F(TouchSelectionControllerImplTest, QuickMenuAdjustsAnchorRect) {
+  CreateWidget();
+  aura::Window* window = widget_->GetNativeView();
+
+  scoped_ptr<TestTouchEditingMenuController> quick_menu_controller(
+      new TestTouchEditingMenuController());
+
+  // Some arbitrary size for touch editing handle image.
+  gfx::Size handle_image_size(10, 10);
+
+  // Calculate the width of quick menu. In addition to |kMenuCommandCount|
+  // commands, there is an item for ellipsis.
+  int quick_menu_width = (kMenuCommandCount + 1) * kMenuButtonWidth +
+                         kMenuCommandCount;
+
+  // Set anchor rect's width a bit smaller than the quick menu width plus handle
+  // image width and check that anchor rect's height is adjusted.
+  gfx::Rect anchor_rect(
+      0, 0, quick_menu_width + handle_image_size.width() - 10, 20);
+  TouchEditingMenuView* quick_menu(TouchEditingMenuView::Create(
+      quick_menu_controller.get(), anchor_rect, handle_image_size, window));
+  anchor_rect.Inset(0, 0, 0, -handle_image_size.height());
+  EXPECT_EQ(anchor_rect.ToString(), quick_menu->GetAnchorRect().ToString());
+
+  // Set anchor rect's width a bit greater than the quick menu width plus handle
+  // image width and check that anchor rect's height is not adjusted.
+  anchor_rect =
+      gfx::Rect(0, 0, quick_menu_width + handle_image_size.width() + 10, 20);
+  quick_menu = TouchEditingMenuView::Create(
+      quick_menu_controller.get(), anchor_rect, handle_image_size, window);
+  EXPECT_EQ(anchor_rect.ToString(), quick_menu->GetAnchorRect().ToString());
+
+  // Close the widget, hence quick menus, before quick menu controller goes out
+  // of scope.
+  widget_->CloseNow();
+  widget_ = NULL;
+}
+
+TEST_F(TouchSelectionControllerImplTest, MouseEventDeactivatesTouchSelection) {
+  CreateTextfield();
+  EXPECT_FALSE(GetSelectionController());
+
+  aura::test::EventGenerator generator(
+      textfield_widget_->GetNativeView()->GetRootWindow());
+
+  generator.set_current_location(gfx::Point(5, 5));
+  RunPendingMessages();
+
+  // Start touch editing; then move mouse over the textfield and ensure it
+  // deactivates touch selection.
+  StartTouchEditing();
+  EXPECT_TRUE(GetSelectionController());
+  generator.MoveMouseTo(gfx::Point(5, 10));
+  RunPendingMessages();
+  EXPECT_FALSE(GetSelectionController());
+
+  generator.MoveMouseTo(gfx::Point(5, 50));
+  RunPendingMessages();
+
+  // Start touch editing; then move mouse out of the textfield, but inside the
+  // winow and ensure it deactivates touch selection.
+  StartTouchEditing();
+  EXPECT_TRUE(GetSelectionController());
+  generator.MoveMouseTo(gfx::Point(5, 55));
+  RunPendingMessages();
+  EXPECT_FALSE(GetSelectionController());
+
+  generator.MoveMouseTo(gfx::Point(5, 500));
+  RunPendingMessages();
+
+  // Start touch editing; then move mouse out of the textfield and window and
+  // ensure it deactivates touch selection.
+  StartTouchEditing();
+  EXPECT_TRUE(GetSelectionController());
+  generator.MoveMouseTo(5, 505);
+  RunPendingMessages();
+  EXPECT_FALSE(GetSelectionController());
+}
+
+TEST_F(TouchSelectionControllerImplTest, KeyEventDeactivatesTouchSelection) {
+  CreateTextfield();
+  EXPECT_FALSE(GetSelectionController());
+
+  aura::test::EventGenerator generator(
+      textfield_widget_->GetNativeView()->GetRootWindow());
+
+  RunPendingMessages();
+
+  // Start touch editing; then press a key and ensure it deactivates touch
+  // selection.
+  StartTouchEditing();
+  EXPECT_TRUE(GetSelectionController());
+  generator.PressKey(ui::VKEY_A, 0);
+  RunPendingMessages();
+  EXPECT_FALSE(GetSelectionController());
+}
+
 }  // namespace views
diff --git a/ui/views/view.cc b/ui/views/view.cc
index 2918ee1..bbd1240 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -1104,6 +1104,11 @@
   return targeter_.get();
 }
 
+void View::ConvertEventToTarget(ui::EventTarget* target,
+                                ui::LocatedEvent* event) {
+  event->ConvertLocationToTarget(this, static_cast<View*>(target));
+}
+
 // Accelerators ----------------------------------------------------------------
 
 void View::AddAccelerator(const ui::Accelerator& accelerator) {
diff --git a/ui/views/view.h b/ui/views/view.h
index 314ebb7..027e212 100644
--- a/ui/views/view.h
+++ b/ui/views/view.h
@@ -108,8 +108,9 @@
  public:
   typedef std::vector<View*> Views;
 
-  // TODO(tdanderson,sadrul): Becomes obsolete with the refactoring of the
-  // event targeting logic for views and windows.
+  // TODO(tdanderson): Becomes obsolete with the refactoring of the event
+  //                   targeting logic for views and windows. See
+  //                   crbug.com/355425.
   // Specifies the source of the region used in a hit test.
   // HIT_TEST_SOURCE_MOUSE indicates the hit test is being performed with a
   // single point and HIT_TEST_SOURCE_TOUCH indicates the hit test is being
@@ -509,7 +510,7 @@
   Background* background() { return background_.get(); }
 
   // The border object is owned by this object and may be NULL.
-  void SetBorder(scoped_ptr<Border> b);
+  virtual void SetBorder(scoped_ptr<Border> b);
   const Border* border() const { return border_.get(); }
   Border* border() { return border_.get(); }
 
@@ -557,6 +558,11 @@
   // The points, rects, mouse locations, and touch locations in the following
   // functions are in the view's coordinates, except for a RootView.
 
+  // TODO(tdanderson): GetEventHandlerForPoint() and GetEventHandlerForRect()
+  //                   will be removed once their logic is moved into
+  //                   ViewTargeter and its derived classes. See
+  //                   crbug.com/355425.
+
   // Convenience functions which calls into GetEventHandler() with
   // a 1x1 rect centered at |point|.
   View* GetEventHandlerForPoint(const gfx::Point& point);
@@ -582,6 +588,10 @@
   // the cursor is a shared resource.
   virtual gfx::NativeCursor GetCursor(const ui::MouseEvent& event);
 
+  // TODO(tdanderson): HitTestPoint() and HitTestRect() will be removed once
+  //                   their logic is moved into ViewTargeter and its
+  //                   derived classes. See crbug.com/355425.
+
   // A convenience function which calls HitTestRect() with a rect of size
   // 1x1 and an origin of |point|.
   bool HitTestPoint(const gfx::Point& point) const;
@@ -713,6 +723,8 @@
   virtual ui::EventTarget* GetParentTarget() OVERRIDE;
   virtual scoped_ptr<ui::EventTargetIterator> GetChildIterator() const OVERRIDE;
   virtual ui::EventTargeter* GetEventTargeter() OVERRIDE;
+  virtual void ConvertEventToTarget(ui::EventTarget* target,
+                                    ui::LocatedEvent* event) OVERRIDE;
 
   // Overridden from ui::EventHandler:
   virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE;
diff --git a/ui/views/view_targeter.cc b/ui/views/view_targeter.cc
index 2ad07d7..e4f495b 100644
--- a/ui/views/view_targeter.cc
+++ b/ui/views/view_targeter.cc
@@ -18,6 +18,8 @@
   View* view = static_cast<View*>(root);
   if (event->IsKeyEvent())
     return FindTargetForKeyEvent(view, *static_cast<ui::KeyEvent*>(event));
+  else if (event->IsScrollEvent())
+    return EventTargeter::FindTargetForEvent(root, event);
 
   NOTREACHED() << "ViewTargeter does not yet support this event type.";
   return NULL;
@@ -29,6 +31,30 @@
   return previous_target->GetParentTarget();
 }
 
+bool ViewTargeter::SubtreeCanAcceptEvent(
+    ui::EventTarget* target,
+    const ui::LocatedEvent& event) const {
+  views::View* view = static_cast<views::View*>(target);
+  if (!view->visible())
+    return false;
+  return true;
+}
+
+bool ViewTargeter::EventLocationInsideBounds(
+    ui::EventTarget* target,
+    const ui::LocatedEvent& event) const {
+  views::View* view = static_cast<views::View*>(target);
+  gfx::Rect rect(event.location(), gfx::Size(1, 1));
+  gfx::RectF rect_in_view_coords_f(rect);
+  if (view->parent())
+    View::ConvertRectToTarget(view->parent(), view, &rect_in_view_coords_f);
+  gfx::Rect rect_in_view_coords = gfx::ToEnclosingRect(rect_in_view_coords_f);
+
+  // TODO(tdanderson): Don't call into HitTestRect() directly here.
+  //                   See crbug.com/370579.
+  return view->HitTestRect(rect_in_view_coords);
+}
+
 View* ViewTargeter::FindTargetForKeyEvent(View* view, const ui::KeyEvent& key) {
   if (view->GetFocusManager())
     return view->GetFocusManager()->GetFocusedView();
diff --git a/ui/views/view_targeter.h b/ui/views/view_targeter.h
index 8426727..4cb3476 100644
--- a/ui/views/view_targeter.h
+++ b/ui/views/view_targeter.h
@@ -28,6 +28,12 @@
                                               ui::Event* event) OVERRIDE;
   virtual ui::EventTarget* FindNextBestTarget(ui::EventTarget* previous_target,
                                               ui::Event* event) OVERRIDE;
+  virtual bool SubtreeCanAcceptEvent(
+      ui::EventTarget* target,
+      const ui::LocatedEvent& event) const OVERRIDE;
+  virtual bool EventLocationInsideBounds(
+      ui::EventTarget* target,
+      const ui::LocatedEvent& event) const OVERRIDE;
 
  private:
   View* FindTargetForKeyEvent(View* view, const ui::KeyEvent& key);
diff --git a/ui/views/view_targeter_unittest.cc b/ui/views/view_targeter_unittest.cc
new file mode 100644
index 0000000..3fe0bf3
--- /dev/null
+++ b/ui/views/view_targeter_unittest.cc
@@ -0,0 +1,194 @@
+// 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.
+
+#include "ui/views/view_targeter.h"
+
+#include "ui/events/event_targeter.h"
+#include "ui/events/event_utils.h"
+#include "ui/views/test/views_test_base.h"
+#include "ui/views/widget/root_view.h"
+
+namespace views {
+namespace test {
+
+typedef ViewsTestBase ViewTargeterTest;
+
+// Verifies that the the functions ViewTargeter::FindTargetForEvent()
+// and ViewTargeter::FindNextBestTarget() are implemented correctly
+// for key events.
+TEST_F(ViewTargeterTest, ViewTargeterForKeyEvents) {
+  Widget widget;
+  Widget::InitParams init_params =
+      CreateParams(Widget::InitParams::TYPE_POPUP);
+  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  widget.Init(init_params);
+
+  View* content = new View;
+  View* child = new View;
+  View* grandchild = new View;
+
+  widget.SetContentsView(content);
+  content->AddChildView(child);
+  child->AddChildView(grandchild);
+
+  grandchild->SetFocusable(true);
+  grandchild->RequestFocus();
+
+  ui::EventTargeter* targeter = new ViewTargeter();
+  internal::RootView* root_view =
+      static_cast<internal::RootView*>(widget.GetRootView());
+  root_view->SetEventTargeter(make_scoped_ptr(targeter));
+
+  ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, 0, true);
+
+  // The focused view should be the initial target of the event.
+  ui::EventTarget* current_target = targeter->FindTargetForEvent(root_view,
+                                                                 &key_event);
+  EXPECT_EQ(grandchild, static_cast<View*>(current_target));
+
+  // Verify that FindNextBestTarget() will return the parent view of the
+  // argument (and NULL if the argument has no parent view).
+  current_target = targeter->FindNextBestTarget(grandchild, &key_event);
+  EXPECT_EQ(child, static_cast<View*>(current_target));
+  current_target = targeter->FindNextBestTarget(child, &key_event);
+  EXPECT_EQ(content, static_cast<View*>(current_target));
+  current_target = targeter->FindNextBestTarget(content, &key_event);
+  EXPECT_EQ(widget.GetRootView(), static_cast<View*>(current_target));
+  current_target = targeter->FindNextBestTarget(widget.GetRootView(),
+                                                &key_event);
+  EXPECT_EQ(NULL, static_cast<View*>(current_target));
+}
+
+// Verifies that the the functions ViewTargeter::FindTargetForEvent()
+// and ViewTargeter::FindNextBestTarget() are implemented correctly
+// for scroll events.
+TEST_F(ViewTargeterTest, ViewTargeterForScrollEvents) {
+  Widget widget;
+  Widget::InitParams init_params =
+      CreateParams(Widget::InitParams::TYPE_POPUP);
+  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  init_params.bounds = gfx::Rect(0, 0, 200, 200);
+  widget.Init(init_params);
+
+  // The coordinates used for SetBounds() are in the parent coordinate space.
+  View* content = new View;
+  content->SetBounds(0, 0, 100, 100);
+  View* child = new View;
+  child->SetBounds(50, 50, 20, 20);
+  View* grandchild = new View;
+  grandchild->SetBounds(0, 0, 5, 5);
+
+  widget.SetContentsView(content);
+  content->AddChildView(child);
+  child->AddChildView(grandchild);
+
+  ui::EventTargeter* targeter = new ViewTargeter();
+  internal::RootView* root_view =
+      static_cast<internal::RootView*>(widget.GetRootView());
+  root_view->SetEventTargeter(make_scoped_ptr(targeter));
+
+  // The event falls within the bounds of |child| and |content| but not
+  // |grandchild|, so |child| should be the initial target for the event.
+  ui::ScrollEvent scroll(ui::ET_SCROLL,
+                         gfx::Point(60, 60),
+                         ui::EventTimeForNow(),
+                         0,
+                         0, 3,
+                         0, 3,
+                         2);
+  ui::EventTarget* current_target = targeter->FindTargetForEvent(root_view,
+                                                                 &scroll);
+  EXPECT_EQ(child, static_cast<View*>(current_target));
+
+  // Verify that FindNextBestTarget() will return the parent view of the
+  // argument (and NULL if the argument has no parent view).
+  current_target = targeter->FindNextBestTarget(child, &scroll);
+  EXPECT_EQ(content, static_cast<View*>(current_target));
+  current_target = targeter->FindNextBestTarget(content, &scroll);
+  EXPECT_EQ(widget.GetRootView(), static_cast<View*>(current_target));
+  current_target = targeter->FindNextBestTarget(widget.GetRootView(),
+                                                &scroll);
+  EXPECT_EQ(NULL, static_cast<View*>(current_target));
+
+  // The event falls outside of the original specified bounds of |content|,
+  // |child|, and |grandchild|. But since |content| is the contents view,
+  // and contents views are resized to fill the entire area of the root
+  // view, the event's initial target should still be |content|.
+  scroll = ui::ScrollEvent(ui::ET_SCROLL,
+                           gfx::Point(150, 150),
+                           ui::EventTimeForNow(),
+                           0,
+                           0, 3,
+                           0, 3,
+                           2);
+  current_target = targeter->FindTargetForEvent(root_view, &scroll);
+  EXPECT_EQ(content, static_cast<View*>(current_target));
+}
+
+// Tests the basic functionality of the method
+// ViewTargeter::SubtreeShouldBeExploredForEvent().
+TEST_F(ViewTargeterTest, SubtreeShouldBeExploredForEvent) {
+  Widget widget;
+  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
+  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  params.bounds = gfx::Rect(0, 0, 650, 650);
+  widget.Init(params);
+
+  ui::EventTargeter* targeter = new ViewTargeter();
+  internal::RootView* root_view =
+      static_cast<internal::RootView*>(widget.GetRootView());
+  root_view->SetEventTargeter(make_scoped_ptr(targeter));
+
+  // The coordinates used for SetBounds() are in the parent coordinate space.
+  View v1, v2, v3;
+  v1.SetBounds(0, 0, 300, 300);
+  v2.SetBounds(100, 100, 100, 100);
+  v3.SetBounds(0, 0, 10, 10);
+  v3.SetVisible(false);
+  root_view->AddChildView(&v1);
+  v1.AddChildView(&v2);
+  v2.AddChildView(&v3);
+
+  // Note that the coordinates used below are in |v1|'s coordinate space,
+  // and that SubtreeShouldBeExploredForEvent() expects the event location
+  // to be in the coordinate space of the target's parent. |v1| and
+  // its parent share a common coordinate space.
+
+  // Event located within |v1| only.
+  gfx::Point point(10, 10);
+  ui::MouseEvent event(ui::ET_MOUSE_PRESSED, point, point,
+                       ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
+  EXPECT_TRUE(targeter->SubtreeShouldBeExploredForEvent(&v1, event));
+  EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v2, event));
+  v1.ConvertEventToTarget(&v2, &event);
+  EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v3, event));
+
+  // Event located within |v1| and |v2| only.
+  event.set_location(gfx::Point(150, 150));
+  EXPECT_TRUE(targeter->SubtreeShouldBeExploredForEvent(&v1, event));
+  EXPECT_TRUE(targeter->SubtreeShouldBeExploredForEvent(&v2, event));
+  v1.ConvertEventToTarget(&v2, &event);
+  EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v3, event));
+
+  // Event located within |v1|, |v2|, and |v3|. Note that |v3| is not
+  // visible, so it cannot handle the event.
+  event.set_location(gfx::Point(105, 105));
+  EXPECT_TRUE(targeter->SubtreeShouldBeExploredForEvent(&v1, event));
+  EXPECT_TRUE(targeter->SubtreeShouldBeExploredForEvent(&v2, event));
+  v1.ConvertEventToTarget(&v2, &event);
+  EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v3, event));
+
+  // Event located outside the bounds of all views.
+  event.set_location(gfx::Point(400, 400));
+  EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v1, event));
+  EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v2, event));
+  v1.ConvertEventToTarget(&v2, &event);
+  EXPECT_FALSE(targeter->SubtreeShouldBeExploredForEvent(&v3, event));
+
+  // TODO(tdanderson): Move the hit-testing unit tests out of view_unittest
+  // and into here. See crbug.com/355425.
+}
+
+}  // namespace test
+}  // namespace views
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index 9903370..87c7512 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -263,14 +263,16 @@
         'focus/view_storage.h',
         'focus/widget_focus_manager.cc',
         'focus/widget_focus_manager.h',
+        'ime/input_method.h',
         'ime/input_method_base.cc',
         'ime/input_method_base.h',
         'ime/input_method_bridge.cc',
         'ime/input_method_bridge.h',
         'ime/input_method_delegate.h',
-        'ime/input_method.h',
         'ime/mock_input_method.cc',
         'ime/mock_input_method.h',
+        'ime/null_input_method.cc',
+        'ime/null_input_method.h',
         'layout/box_layout.cc',
         'layout/box_layout.h',
         'layout/fill_layout.cc',
@@ -375,6 +377,8 @@
         'widget/desktop_aura/x11_desktop_window_move_client.h',
         'widget/desktop_aura/x11_scoped_capture.cc',
         'widget/desktop_aura/x11_scoped_capture.h',
+        'widget/desktop_aura/x11_topmost_window_finder.cc',
+        'widget/desktop_aura/x11_topmost_window_finder.h',
         'widget/desktop_aura/x11_whole_screen_move_loop.cc',
         'widget/desktop_aura/x11_whole_screen_move_loop.h',
         'widget/desktop_aura/x11_whole_screen_move_loop_delegate.h',
@@ -650,10 +654,10 @@
         'touchui/touch_selection_controller_impl_unittest.cc',
         'view_model_unittest.cc',
         'view_model_utils_unittest.cc',
+        'view_targeter_unittest.cc',
         'view_unittest.cc',
         'widget/desktop_aura/desktop_focus_rules_unittest.cc',
         'widget/desktop_aura/desktop_native_widget_aura_unittest.cc',
-        'widget/desktop_aura/desktop_window_tree_host_win_unittest.cc',
         'widget/desktop_aura/desktop_screen_x11_unittest.cc',
         'widget/desktop_aura/desktop_screen_position_client_unittest.cc',
         'widget/native_widget_aura_unittest.cc',
@@ -699,8 +703,7 @@
             '../../base/allocator/allocator.gyp:allocator',
           ],
         }],
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['OS=="linux" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))', {
+        ['OS=="linux" and use_allocator!="none"', {
            # See http://crbug.com/162998#c4 for why this is needed.
           'dependencies': [
             '../../base/allocator/allocator.gyp:allocator',
diff --git a/ui/views/views_switches.cc b/ui/views/views_switches.cc
index c62e83d..342deee 100644
--- a/ui/views/views_switches.cc
+++ b/ui/views/views_switches.cc
@@ -16,6 +16,15 @@
 const char kDisableViewsRectBasedTargeting[] =
     "disable-views-rect-based-targeting";
 
+#if defined(USE_X11) && !defined(OS_CHROMEOS)
+// When enabled, tries to get a transparent X11 visual so that we can have
+// per-pixel alpha in windows.
+//
+// TODO(erg): Remove this switch once we've stabilized the code
+// path. http://crbug.com/369209
+const char kEnableTransparentVisuals[] = "enable-transparent-visuals";
+#endif
+
 bool IsRectBasedTargetingEnabled() {
 #if defined(OS_CHROMEOS) || defined(OS_WIN)
   return !CommandLine::ForCurrentProcess()->
diff --git a/ui/views/views_switches.h b/ui/views/views_switches.h
index 9e50294..0fb09db 100644
--- a/ui/views/views_switches.h
+++ b/ui/views/views_switches.h
@@ -15,6 +15,10 @@
 // Please keep alphabetized.
 VIEWS_EXPORT extern const char kDisableViewsRectBasedTargeting[];
 
+#if defined(USE_X11) && !defined(OS_CHROMEOS)
+VIEWS_EXPORT extern const char kEnableTransparentVisuals[];
+#endif
+
 // Returns true if rect-based targeting in views should be used.
 VIEWS_EXPORT bool IsRectBasedTargetingEnabled();
 
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
index a569eae..b2d4eed 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
@@ -20,6 +20,7 @@
 #include "ui/events/event.h"
 #include "ui/events/platform/platform_event_source.h"
 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
+#include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
 #include "ui/wm/public/drag_drop_client.h"
 #include "ui/wm/public/drag_drop_delegate.h"
 
@@ -63,7 +64,6 @@
   "XdndStatus",
   "XdndTypeList",
   ui::Clipboard::kMimeTypeText,
-  "_NET_WM_WINDOW_TYPE_MENU",
   NULL
 };
 
@@ -71,71 +71,27 @@
 // mouse button before ending the move loop.
 const int kEndMoveLoopTimeoutMs = 1000;
 
+// The time to wait since sending the last XdndPosition message before
+// reprocessing the most recent mouse move event in case that the window
+// stacking order has changed and |source_current_window_| needs to be updated.
+const int kRepeatMouseMoveTimeoutMs = 350;
+
 static base::LazyInstance<
     std::map< ::Window, views::DesktopDragDropClientAuraX11*> >::Leaky
         g_live_client_map = LAZY_INSTANCE_INITIALIZER;
 
-// Helper class to FindWindowFor which looks for a drag target under the
-// cursor.
-class DragTargetWindowFinder : public ui::EnumerateWindowsDelegate {
- public:
-  DragTargetWindowFinder(XID ignored_icon_window,
-                         Atom menu_type_atom,
-                         gfx::Point screen_loc)
-      : ignored_icon_window_(ignored_icon_window),
-        output_window_(None),
-        menu_type_atom_(menu_type_atom),
-        screen_loc_(screen_loc) {
-    ui::EnumerateTopLevelWindows(this);
-  }
-
-  virtual ~DragTargetWindowFinder() {}
-
-  XID window() const { return output_window_; }
-
- protected:
-  virtual bool ShouldStopIterating(XID window) OVERRIDE {
-    if (window == ignored_icon_window_)
-      return false;
-
-    if (!ui::IsWindowVisible(window))
-      return false;
-
-    if (!ui::WindowContainsPoint(window, screen_loc_))
-      return false;
-
-    int value = 0;
-    if (ui::PropertyExists(window, "WM_STATE") ||
-        (ui::GetIntProperty(window, "_NET_WM_WINDOW_TYPE", &value) &&
-         static_cast<Atom>(value) == menu_type_atom_)) {
-      output_window_ = window;
-      return true;
-    }
-
-    return false;
-  }
-
- private:
-  XID ignored_icon_window_;
-  XID output_window_;
-  const Atom menu_type_atom_;
-  gfx::Point screen_loc_;
-
-  DISALLOW_COPY_AND_ASSIGN(DragTargetWindowFinder);
-};
-
 // Returns the topmost X11 window at |screen_point| if it is advertising that
 // is supports the Xdnd protocol. Will return the window under the pointer as
 // |mouse_window|. If there's a Xdnd aware window, it will be returned in
 // |dest_window|.
 void FindWindowFor(const gfx::Point& screen_point,
-                   ::Window* mouse_window, ::Window* dest_window,
-                   Atom menu_type_atom) {
-  DragTargetWindowFinder finder(None, menu_type_atom, screen_point);
-  *mouse_window = finder.window();
+                   ::Window* mouse_window,
+                   ::Window* dest_window) {
+  views::X11TopmostWindowFinder finder;
+  *mouse_window = finder.FindWindowAt(screen_point);
   *dest_window = None;
 
-  if (finder.window() == None)
+  if (*mouse_window == None)
     return;
 
   // Figure out which window we should test as XdndAware. If mouse_window has
@@ -425,6 +381,7 @@
       atom_cache_(xdisplay_, kAtomsToCache),
       target_window_(NULL),
       waiting_on_status_(false),
+      status_received_since_enter_(false),
       source_provider_(NULL),
       source_current_window_(None),
       source_state_(SOURCE_STATE_OTHER),
@@ -527,6 +484,7 @@
   }
 
   waiting_on_status_ = false;
+  status_received_since_enter_ = true;
 
   if (event.data.l[1] & 1) {
     ::Atom atom_operation = event.data.l[4];
@@ -568,10 +526,10 @@
     // We were waiting on the status message so we could send off the next
     // position message we queued up.
     gfx::Point p = next_position_message_->first;
-    unsigned long time = next_position_message_->second;
+    unsigned long event_time = next_position_message_->second;
     next_position_message_.reset();
 
-    SendXdndPosition(source_window, p, time);
+    SendXdndPosition(source_window, p, event_time);
   }
 }
 
@@ -644,6 +602,7 @@
   g_current_drag_drop_client = this;
   waiting_on_status_ = false;
   next_position_message_.reset();
+  status_received_since_enter_ = false;
   source_state_ = SOURCE_STATE_OTHER;
   drag_operation_ = operation;
   negotiated_operation_ = ui::DragDropTypes::DRAG_NONE;
@@ -716,41 +675,13 @@
 }
 
 void DesktopDragDropClientAuraX11::OnMouseMovement(XMotionEvent* event) {
-  gfx::Point screen_point(event->x_root, event->y_root);
-
-  if (source_state_ != SOURCE_STATE_OTHER)
-    return;
-
-  // Find the current window the cursor is over.
-  ::Window mouse_window = None;
-  ::Window dest_window = None;
-  FindWindowFor(screen_point, &mouse_window, &dest_window,
-                atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_MENU"));
-
-  if (source_current_window_ != dest_window) {
-    if (source_current_window_ != None)
-      SendXdndLeave(source_current_window_);
-
-    source_current_window_ = dest_window;
-    waiting_on_status_ = false;
-    next_position_message_.reset();
-    negotiated_operation_ = ui::DragDropTypes::DRAG_NONE;
-
-    if (source_current_window_ != None)
-      SendXdndEnter(source_current_window_);
-  }
-
-  if (source_current_window_ != None) {
-    if (waiting_on_status_) {
-      next_position_message_.reset(
-          new std::pair<gfx::Point, unsigned long>(screen_point, event->time));
-    } else {
-      SendXdndPosition(dest_window, screen_point, event->time);
-    }
-  }
+  repeat_mouse_move_timer_.Stop();
+  ProcessMouseMove(gfx::Point(event->x_root, event->y_root), event->time);
 }
 
 void DesktopDragDropClientAuraX11::OnMouseReleased() {
+  repeat_mouse_move_timer_.Stop();
+
   if (source_state_ != SOURCE_STATE_OTHER) {
     // The user has previously released the mouse and is clicking in
     // frustration.
@@ -760,13 +691,18 @@
 
   if (source_current_window_ != None) {
     if (waiting_on_status_) {
-      // If we are waiting for an XdndStatus message, we need to wait for it to
-      // complete.
-      source_state_ = SOURCE_STATE_PENDING_DROP;
+      if (status_received_since_enter_) {
+        // If we are waiting for an XdndStatus message, we need to wait for it
+        // to complete.
+        source_state_ = SOURCE_STATE_PENDING_DROP;
 
-      // Start timer to end the move loop if the target takes too long to send
-      // the XdndStatus and XdndFinished messages.
-      StartEndMoveLoopTimer();
+        // Start timer to end the move loop if the target takes too long to send
+        // the XdndStatus and XdndFinished messages.
+        StartEndMoveLoopTimer();
+        return;
+      }
+
+      move_loop_.EndMoveLoop();
       return;
     }
 
@@ -791,9 +727,45 @@
     source_current_window_ = None;
   }
   target_current_context_.reset();
+  repeat_mouse_move_timer_.Stop();
   end_move_loop_timer_.Stop();
 }
 
+void DesktopDragDropClientAuraX11::ProcessMouseMove(
+    const gfx::Point& screen_point,
+    unsigned long event_time) {
+  if (source_state_ != SOURCE_STATE_OTHER)
+    return;
+
+  // Find the current window the cursor is over.
+  ::Window mouse_window = None;
+  ::Window dest_window = None;
+  FindWindowFor(screen_point, &mouse_window, &dest_window);
+
+  if (source_current_window_ != dest_window) {
+    if (source_current_window_ != None)
+      SendXdndLeave(source_current_window_);
+
+    source_current_window_ = dest_window;
+    waiting_on_status_ = false;
+    next_position_message_.reset();
+    status_received_since_enter_ = false;
+    negotiated_operation_ = ui::DragDropTypes::DRAG_NONE;
+
+    if (source_current_window_ != None)
+      SendXdndEnter(source_current_window_);
+  }
+
+  if (source_current_window_ != None) {
+    if (waiting_on_status_) {
+      next_position_message_.reset(
+          new std::pair<gfx::Point, unsigned long>(screen_point, event_time));
+    } else {
+      SendXdndPosition(dest_window, screen_point, event_time);
+    }
+  }
+}
+
 void DesktopDragDropClientAuraX11::StartEndMoveLoopTimer() {
   end_move_loop_timer_.Start(FROM_HERE,
                              base::TimeDelta::FromMilliseconds(
@@ -975,7 +947,7 @@
 void DesktopDragDropClientAuraX11::SendXdndPosition(
     ::Window dest_window,
     const gfx::Point& screen_point,
-    unsigned long time) {
+    unsigned long event_time) {
   waiting_on_status_ = true;
 
   XEvent xev;
@@ -986,9 +958,20 @@
   xev.xclient.data.l[0] = xwindow_;
   xev.xclient.data.l[1] = 0;
   xev.xclient.data.l[2] = (screen_point.x() << 16) | screen_point.y();
-  xev.xclient.data.l[3] = time;
+  xev.xclient.data.l[3] = event_time;
   xev.xclient.data.l[4] = DragOperationToAtom(drag_operation_);
   SendXClientEvent(dest_window, &xev);
+
+  // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html and
+  // the Xdnd protocol both recommend that drag events should be sent
+  // periodically.
+  repeat_mouse_move_timer_.Start(
+      FROM_HERE,
+      base::TimeDelta::FromMilliseconds(kRepeatMouseMoveTimeoutMs),
+      base::Bind(&DesktopDragDropClientAuraX11::ProcessMouseMove,
+                 base::Unretained(this),
+                 screen_point,
+                 event_time));
 }
 
 void DesktopDragDropClientAuraX11::SendXdndDrop(::Window dest_window) {
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
index 35a4ee9..d409248 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
@@ -113,6 +113,10 @@
     SOURCE_STATE_OTHER,
   };
 
+  // Processes a mouse move at |screen_point|.
+  void ProcessMouseMove(const gfx::Point& screen_point,
+                        unsigned long event_time);
+
   // Start timer to end the move loop if the target is too slow to respond after
   // the mouse is released.
   void StartEndMoveLoopTimer();
@@ -159,7 +163,7 @@
   void SendXdndLeave(::Window dest_window);
   void SendXdndPosition(::Window dest_window,
                         const gfx::Point& screen_point,
-                        unsigned long time);
+                        unsigned long event_time);
   void SendXdndDrop(::Window dest_window);
 
   // Sends |xev| to |xid|, optionally short circuiting the round trip to the X
@@ -202,6 +206,16 @@
   // XdndStatus response, we need to cache the latest details we'd send.
   scoped_ptr<std::pair<gfx::Point, unsigned long> > next_position_message_;
 
+  // Reprocesses the most recent mouse move event if the mouse has not moved
+  // in a while in case the window stacking order has changed and
+  // |source_current_window_| needs to be updated.
+  base::OneShotTimer<DesktopDragDropClientAuraX11> repeat_mouse_move_timer_;
+
+  // When the mouse is released, we need to wait for the last XdndStatus message
+  // only if we have previously received a status message from
+  // |source_current_window_|.
+  bool status_received_since_enter_;
+
   // Source side information.
   ui::OSExchangeDataProviderAuraX11 const* source_provider_;
   ::Window source_current_window_;
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index 914c1d2..d7347d0 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -15,6 +15,7 @@
 #include "ui/aura/window_property.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/base/hit_test.h"
+#include "ui/base/ui_base_switches_util.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/display.h"
@@ -25,8 +26,8 @@
 #include "ui/views/corewm/tooltip.h"
 #include "ui/views/corewm/tooltip_controller.h"
 #include "ui/views/drag_utils.h"
-#include "ui/views/ime/input_method.h"
 #include "ui/views/ime/input_method_bridge.h"
+#include "ui/views/ime/null_input_method.h"
 #include "ui/views/view_constants_aura.h"
 #include "ui/views/widget/desktop_aura/desktop_capture_client.h"
 #include "ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h"
@@ -628,6 +629,9 @@
 }
 
 InputMethod* DesktopNativeWidgetAura::CreateInputMethod() {
+  if (switches::IsTextInputFocusManagerEnabled())
+    return new NullInputMethod();
+
   ui::InputMethod* host = input_method_event_filter_->input_method();
   return new InputMethodBridge(this, host, false);
 }
@@ -637,6 +641,10 @@
   return this;
 }
 
+ui::InputMethod* DesktopNativeWidgetAura::GetHostInputMethod() {
+  return input_method_event_filter_->input_method();
+}
+
 void DesktopNativeWidgetAura::CenterWindow(const gfx::Size& size) {
   if (content_window_)
     desktop_window_tree_host_->CenterWindow(size);
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
index 8735ac0..22bf3da 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -121,6 +121,7 @@
   virtual bool HasCapture() const OVERRIDE;
   virtual InputMethod* CreateInputMethod() OVERRIDE;
   virtual internal::InputMethodDelegate* GetInputMethodDelegate() OVERRIDE;
+  virtual ui::InputMethod* GetHostInputMethod() OVERRIDE;
   virtual void CenterWindow(const gfx::Size& size) OVERRIDE;
   virtual void GetWindowPlacement(
       gfx::Rect* bounds,
@@ -295,7 +296,6 @@
   scoped_ptr<wm::WindowModalityController>
       window_modality_controller_;
 
-  // See comments in OnLostActive().
   bool restore_focus_on_activate_;
 
   gfx::NativeCursor cursor_;
diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
index 99ca833..d927780 100644
--- a/ui/views/widget/desktop_aura/desktop_screen_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
@@ -26,6 +26,7 @@
 #include "ui/gfx/x/x11_types.h"
 #include "ui/views/widget/desktop_aura/desktop_screen.h"
 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
+#include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
 
 namespace {
 
@@ -64,54 +65,6 @@
   return std::vector<gfx::Display>(1, gfx_display);
 }
 
-// Helper class to GetWindowAtScreenPoint() which returns the topmost window at
-// the location passed to FindAt(). NULL is returned if a window which does not
-// belong to Chromium is topmost at the passed in location.
-class ToplevelWindowFinder : public ui::EnumerateWindowsDelegate {
- public:
-  ToplevelWindowFinder() : toplevel_(NULL) {
-  }
-
-  virtual ~ToplevelWindowFinder() {
-  }
-
-  aura::Window* FindAt(const gfx::Point& screen_loc) {
-    screen_loc_ = screen_loc;
-    ui::EnumerateTopLevelWindows(this);
-    return toplevel_;
-  }
-
- protected:
-  virtual bool ShouldStopIterating(XID xid) OVERRIDE {
-   if (!ui::IsWindowVisible(xid))
-     return false;
-
-    aura::Window* window =
-        views::DesktopWindowTreeHostX11::GetContentWindowForXID(xid);
-    if (window) {
-      // Currently |window|->IsVisible() always returns true.
-      // TODO(pkotwicz): Fix this. crbug.com/353038
-      if (window->IsVisible() &&
-          window->GetBoundsInScreen().Contains(screen_loc_)) {
-        toplevel_ = window;
-        return true;
-      }
-      return false;
-    }
-
-    if (ui::WindowContainsPoint(xid, screen_loc_)) {
-      // toplevel_ = NULL
-      return true;
-    }
-    return false;
-  }
-
-  gfx::Point screen_loc_;
-  aura::Window* toplevel_;
-
-  DISALLOW_COPY_AND_ASSIGN(ToplevelWindowFinder);
-};
-
 }  // namespace
 
 namespace views {
@@ -236,8 +189,8 @@
 
 gfx::NativeWindow DesktopScreenX11::GetWindowAtScreenPoint(
     const gfx::Point& point) {
-  ToplevelWindowFinder finder;
-  return finder.FindAt(point);
+  X11TopmostWindowFinder finder;
+  return finder.FindLocalProcessWindowAt(point, std::set<aura::Window*>());
 }
 
 int DesktopScreenX11::GetNumDisplays() const {
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index 6801098..ece2500 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -606,22 +606,6 @@
   return IsMaximized() || (widget && widget->ShouldUseNativeFrame());
 }
 
-bool DesktopWindowTreeHostWin::CanSaveFocus() const {
-  return GetWidget()->is_top_level();
-}
-
-void DesktopWindowTreeHostWin::SaveFocusOnDeactivate() {
-  GetWidget()->GetFocusManager()->StoreFocusedView(true);
-}
-
-void DesktopWindowTreeHostWin::RestoreFocusOnActivate() {
-  RestoreFocusOnEnable();
-}
-
-void DesktopWindowTreeHostWin::RestoreFocusOnEnable() {
-  GetWidget()->GetFocusManager()->RestoreFocusedView();
-}
-
 bool DesktopWindowTreeHostWin::IsModal() const {
   return native_widget_delegate_->IsModal();
 }
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index 449bcd0..5883141 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -140,10 +140,6 @@
   virtual bool CanMaximize() const OVERRIDE;
   virtual bool CanActivate() const OVERRIDE;
   virtual bool WidgetSizeIsClientSize() const OVERRIDE;
-  virtual bool CanSaveFocus() const OVERRIDE;
-  virtual void SaveFocusOnDeactivate() OVERRIDE;
-  virtual void RestoreFocusOnActivate() OVERRIDE;
-  virtual void RestoreFocusOnEnable() OVERRIDE;
   virtual bool IsModal() const OVERRIDE;
   virtual int GetInitialShowState() const OVERRIDE;
   virtual bool WillProcessWorkAreaChange() const OVERRIDE;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc
deleted file mode 100644
index 8471a4c..0000000
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2013 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.
-
-#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
-
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/views/test/views_test_base.h"
-#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
-#include "ui/views/widget/widget.h"
-
-namespace views {
-
-typedef ViewsTestBase DesktopWindowTreeHostWinTest;
-
-namespace {
-
-// See description above SaveFocusOnDeactivateFromHandleCreate.
-class TestDesktopWindowTreeHostWin : public DesktopWindowTreeHostWin {
- public:
-  TestDesktopWindowTreeHostWin(
-      internal::NativeWidgetDelegate* native_widget_delegate,
-      DesktopNativeWidgetAura* desktop_native_widget_aura)
-      : DesktopWindowTreeHostWin(native_widget_delegate,
-                                 desktop_native_widget_aura) {}
-  virtual ~TestDesktopWindowTreeHostWin() {}
-
-  // DesktopWindowTreeHostWin overrides:
-  virtual void HandleCreate() OVERRIDE {
-    DesktopWindowTreeHostWin::HandleCreate();
-    SaveFocusOnDeactivate();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestDesktopWindowTreeHostWin);
-};
-
-}  // namespace
-
-// Verifies if SaveFocusOnDeactivate() is invoked from
-// DesktopWindowTreeHostWin::HandleCreate we don't crash.
-TEST_F(DesktopWindowTreeHostWinTest, SaveFocusOnDeactivateFromHandleCreate) {
-  Widget widget;
-  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
-  params.bounds = gfx::Rect(0, 0, 200, 200);
-  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
-  DesktopNativeWidgetAura* desktop_native_widget_aura =
-      new DesktopNativeWidgetAura(&widget);
-  params.native_widget = desktop_native_widget_aura;
-  params.desktop_window_tree_host = new TestDesktopWindowTreeHostWin(
-      &widget, desktop_native_widget_aura);
-  widget.Init(params);
-}
-
-}  // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index d1695c1..d573fcc 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -11,6 +11,7 @@
 #include <X11/Xutil.h>
 
 #include "base/basictypes.h"
+#include "base/command_line.h"
 #include "base/debug/trace_event.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -40,6 +41,7 @@
 #include "ui/views/ime/input_method.h"
 #include "ui/views/linux_ui/linux_ui.h"
 #include "ui/views/views_delegate.h"
+#include "ui/views/views_switches.h"
 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h"
 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
@@ -74,7 +76,7 @@
   "UTF8_STRING",
   "WM_DELETE_WINDOW",
   "WM_PROTOCOLS",
-  "WM_S0",
+  "_NET_WM_CM_S0",
   "_NET_WM_ICON",
   "_NET_WM_NAME",
   "_NET_WM_PID",
@@ -131,6 +133,7 @@
       is_fullscreen_(false),
       is_always_on_top_(false),
       use_native_frame_(false),
+      use_argb_visual_(false),
       drag_drop_client_(NULL),
       current_cursor_(ui::kCursorNull),
       native_widget_delegate_(native_widget_delegate),
@@ -247,6 +250,8 @@
   x11_window_move_client_.reset(new X11DesktopWindowMoveClient);
   aura::client::SetWindowMoveClient(window(), x11_window_move_client_.get());
 
+  SetWindowTransparency();
+
   native_widget_delegate_->OnNativeWidgetCreated(true);
 }
 
@@ -826,8 +831,6 @@
   if (size_changed) {
     OnHostResized(bounds.size());
     ResetWindowRegion();
-  } else {
-    compositor()->ScheduleRedrawRect(gfx::Rect(bounds.size()));
   }
 }
 
@@ -948,15 +951,41 @@
   if (swa.override_redirect)
     attribute_mask |= CWOverrideRedirect;
 
+  // Detect whether we're running inside a compositing manager. If so, try to
+  // use the ARGB visual. Otherwise, just use our parent's visual.
+  Visual* visual = CopyFromParent;
+  int depth = CopyFromParent;
+  if (CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableTransparentVisuals) &&
+      XGetSelectionOwner(xdisplay_,
+                         atom_cache_.GetAtom("_NET_WM_CM_S0")) != None) {
+    Visual* rgba_visual = GetARGBVisual();
+    if (rgba_visual) {
+      visual = rgba_visual;
+      depth = 32;
+
+      attribute_mask |= CWColormap;
+      swa.colormap = XCreateColormap(xdisplay_, x_root_window_, visual,
+                                     AllocNone);
+
+      // x.org will BadMatch if we don't set a border when the depth isn't the
+      // same as the parent depth.
+      attribute_mask |= CWBorderPixel;
+      swa.border_pixel = 0;
+
+      use_argb_visual_ = true;
+    }
+  }
+
   bounds_ = params.bounds;
   xwindow_ = XCreateWindow(
       xdisplay_, x_root_window_,
       bounds_.x(), bounds_.y(),
       bounds_.width(), bounds_.height(),
       0,               // border width
-      CopyFromParent,  // depth
+      depth,
       InputOutput,
-      CopyFromParent,  // visual
+      visual,
       attribute_mask,
       &swa);
   if (ui::PlatformEventSource::GetInstance())
@@ -1079,13 +1108,6 @@
   CreateCompositor(GetAcceleratedWidget());
 }
 
-bool DesktopWindowTreeHostX11::IsWindowManagerPresent() {
-  // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
-  // of WM_Sn selections (where n is a screen number).
-  return XGetSelectionOwner(
-      xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
-}
-
 void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled,
                                                 ::Atom state1,
                                                 ::Atom state2) {
@@ -1238,6 +1260,39 @@
       data->push_back(bitmap.getColor(x, y));
 }
 
+Visual* DesktopWindowTreeHostX11::GetARGBVisual() {
+  XVisualInfo visual_template;
+  visual_template.screen = 0;
+  Visual* to_return = NULL;
+
+  int visuals_len;
+  XVisualInfo* visual_list = XGetVisualInfo(xdisplay_,
+                                            VisualScreenMask,
+                                            &visual_template, &visuals_len);
+  for (int i = 0; i < visuals_len; ++i) {
+    // Why support only 8888 ARGB? Because it's all that GTK+ supports. In
+    // gdkvisual-x11.cc, they look for this specific visual and use it for all
+    // their alpha channel using needs.
+    //
+    // TODO(erg): While the following does find a valid visual, some GL drivers
+    // don't believe that this has an alpha channel. According to marcheu@,
+    // this should work on open source driver though. (It doesn't work with
+    // NVidia's binaries currently.) http://crbug.com/369209
+    if (visual_list[i].depth == 32 &&
+        visual_list[i].visual->red_mask == 0xff0000 &&
+        visual_list[i].visual->green_mask == 0x00ff00 &&
+        visual_list[i].visual->blue_mask == 0x0000ff) {
+      to_return = visual_list[i].visual;
+      break;
+    }
+  }
+
+  if (visual_list)
+    XFree(visual_list);
+
+  return to_return;
+}
+
 std::list<XID>& DesktopWindowTreeHostX11::open_windows() {
   if (!open_windows_)
     open_windows_ = new std::list<XID>();
@@ -1291,6 +1346,12 @@
   window_mapped_ = true;
 }
 
+void DesktopWindowTreeHostX11::SetWindowTransparency() {
+  compositor()->SetHostHasTransparentBackground(use_argb_visual_);
+  window()->SetTransparent(use_argb_visual_);
+  content_window_->SetTransparent(use_argb_visual_);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // DesktopWindowTreeHostX11, ui::PlatformEventDispatcher implementation:
 
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index e369718..b005f6d 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -158,11 +158,6 @@
   // along with all aura client objects that direct behavior.
   aura::WindowEventDispatcher* InitDispatcher(const Widget::InitParams& params);
 
-  // Returns true if there's an X window manager present... in most cases.  Some
-  // window managers (notably, ion3) don't implement enough of ICCCM for us to
-  // detect that they're there.
-  bool IsWindowManagerPresent();
-
   // Sends a message to the x11 window manager, enabling or disabling the
   // states |state1| and |state2|.
   void SetWMSpecState(bool enabled, ::Atom state1, ::Atom state2);
@@ -194,12 +189,18 @@
   void SerializeImageRepresentation(const gfx::ImageSkiaRep& rep,
                                     std::vector<unsigned long>* data);
 
+  // Returns an 8888 ARGB visual. Can return NULL if there is no matching
+  // visual on this display.
+  Visual* GetARGBVisual();
+
   // See comment for variable open_windows_.
   static std::list<XID>& open_windows();
 
   // Map the window (shows it) taking into account the given |show_state|.
   void MapWindow(ui::WindowShowState show_state);
 
+  void SetWindowTransparency();
+
   // ui::PlatformEventDispatcher:
   virtual bool CanDispatchEvent(const ui::PlatformEvent& event) OVERRIDE;
   virtual uint32_t DispatchEvent(const ui::PlatformEvent& event) OVERRIDE;
@@ -246,6 +247,9 @@
   // True if the window has title-bar / borders provided by the window manager.
   bool use_native_frame_;
 
+  // Whether we used an ARGB visual for our window.
+  bool use_argb_visual_;
+
   scoped_ptr<DesktopDispatcherClient> dispatcher_client_;
 
   DesktopDragDropClientAuraX11* drag_drop_client_;
diff --git a/ui/views/widget/desktop_aura/x11_desktop_handler.cc b/ui/views/widget/desktop_aura/x11_desktop_handler.cc
index 0d764e4..f33d416 100644
--- a/ui/views/widget/desktop_aura/x11_desktop_handler.cc
+++ b/ui/views/widget/desktop_aura/x11_desktop_handler.cc
@@ -182,12 +182,13 @@
   if (old_host)
     old_host->HandleNativeWidgetActivationChanged(false);
 
+  // Update the current window ID to effectively change the active widget.
+  current_window_ = xid;
+
   DesktopWindowTreeHostX11* new_host =
       views::DesktopWindowTreeHostX11::GetHostForXID(xid);
   if (new_host)
     new_host->HandleNativeWidgetActivationChanged(true);
-
-  current_window_ = xid;
 }
 
 }  // namespace views
diff --git a/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc b/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc
new file mode 100644
index 0000000..eb0d1bd
--- /dev/null
+++ b/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc
@@ -0,0 +1,78 @@
+// 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.
+
+#include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
+
+#include "ui/aura/window.h"
+#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
+
+namespace views {
+
+X11TopmostWindowFinder::X11TopmostWindowFinder() : toplevel_(None) {
+}
+
+X11TopmostWindowFinder::~X11TopmostWindowFinder() {
+}
+
+aura::Window* X11TopmostWindowFinder::FindLocalProcessWindowAt(
+    const gfx::Point& screen_loc,
+    const std::set<aura::Window*>& ignore) {
+  screen_loc_ = screen_loc;
+  ignore_ = ignore;
+
+  std::vector<aura::Window*> local_process_windows =
+      DesktopWindowTreeHostX11::GetAllOpenWindows();
+  bool found_local_process_window = false;
+  for (size_t i = 0; i < local_process_windows.size(); ++i) {
+    if (ShouldStopIteratingAtLocalProcessWindow(local_process_windows[i])) {
+      found_local_process_window = true;
+      break;
+    }
+  }
+  if (!found_local_process_window)
+    return NULL;
+
+  ui::EnumerateTopLevelWindows(this);
+  return views::DesktopWindowTreeHostX11::GetContentWindowForXID(toplevel_);
+}
+
+XID X11TopmostWindowFinder::FindWindowAt(const gfx::Point& screen_loc) {
+  screen_loc_ = screen_loc;
+  ui::EnumerateTopLevelWindows(this);
+  return toplevel_;
+}
+
+bool X11TopmostWindowFinder::ShouldStopIterating(XID xid) {
+  if (!ui::IsWindowVisible(xid))
+    return false;
+
+  aura::Window* window =
+      views::DesktopWindowTreeHostX11::GetContentWindowForXID(xid);
+  if (window) {
+    if (ShouldStopIteratingAtLocalProcessWindow(window)) {
+      toplevel_ = xid;
+      return true;
+    }
+    return false;
+  }
+
+  if (ui::WindowContainsPoint(xid, screen_loc_)) {
+    toplevel_ = xid;
+    return true;
+  }
+  return false;
+}
+
+bool X11TopmostWindowFinder::ShouldStopIteratingAtLocalProcessWindow(
+    aura::Window* window) {
+  if (ignore_.find(window) != ignore_.end())
+    return false;
+
+  // Currently |window|->IsVisible() always returns true.
+  // TODO(pkotwicz): Fix this. crbug.com/353038
+  return window->IsVisible() &&
+      window->GetBoundsInScreen().Contains(screen_loc_);
+}
+
+}  // namespace views
diff --git a/ui/views/widget/desktop_aura/x11_topmost_window_finder.h b/ui/views/widget/desktop_aura/x11_topmost_window_finder.h
new file mode 100644
index 0000000..cf8498a
--- /dev/null
+++ b/ui/views/widget/desktop_aura/x11_topmost_window_finder.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_X11_TOPMOST_WINDOW_FINDER_H_
+#define UI_VIEWS_WIDGET_DESKTOP_AURA_X11_TOPMOST_WINDOW_FINDER_H_
+
+#include <set>
+
+#include "ui/base/x/x11_util.h"
+#include "ui/gfx/point.h"
+#include "ui/views/views_export.h"
+
+namespace aura {
+class Window;
+}
+
+namespace views {
+
+// Utility class for finding the topmost window at a given screen position.
+class VIEWS_EXPORT X11TopmostWindowFinder
+    : public ui::EnumerateWindowsDelegate {
+ public:
+  X11TopmostWindowFinder();
+  virtual ~X11TopmostWindowFinder();
+
+  // Returns the topmost window at |screen_loc|, ignoring the windows in
+  // |ignore|. Returns NULL if the topmost window at |screen_loc| does not
+  // belong to Chrome.
+  aura::Window* FindLocalProcessWindowAt(const gfx::Point& screen_loc,
+                                         const std::set<aura::Window*>& ignore);
+
+  // Returns the topmost window at |screen_loc|.
+  XID FindWindowAt(const gfx::Point& screen_loc);
+
+ private:
+  // ui::EnumerateWindowsDelegate:
+  virtual bool ShouldStopIterating(XID xid) OVERRIDE;
+
+  // Returns true if |window| does not not belong to |ignore|, is visible and
+  // contains |screen_loc_|.
+  bool ShouldStopIteratingAtLocalProcessWindow(aura::Window* window);
+
+  gfx::Point screen_loc_;
+  std::set<aura::Window*> ignore_;
+  XID toplevel_;
+
+  DISALLOW_COPY_AND_ASSIGN(X11TopmostWindowFinder);
+};
+
+}  // namespace
+
+#endif  // UI_VIEWS_WIDGET_DESKTOP_AURA_X11_TOPMOST_WINDOW_FINDER_H_
diff --git a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
index fa9b75f..1db4a22 100644
--- a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
+++ b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
@@ -363,17 +363,9 @@
 }
 
 bool X11WholeScreenMoveLoop::CheckIfIconValid() {
-  // TODO(erg): I've tried at least five different strategies for trying to
-  // build a mask based off the alpha channel. While all of them have worked,
-  // none of them have been performant and introduced multiple second
-  // delays. (I spent a day getting a rectangle segmentation algorithm polished
-  // here...and then found that even through I had the rectangle extraction
-  // down to mere milliseconds, SkRegion still fell over on the number of
-  // rectangles.)
-  //
-  // Creating a mask here near instantaneously should be possible, as GTK does
-  // it, but I've blown days on this and I'm punting now.
-
+  // Because we need a GL context per window, we do a quick check so that we
+  // don't make another context if the window would just be displaying a mostly
+  // transparent image.
   const SkBitmap* in_bitmap = drag_image_.bitmap();
   SkAutoLockPixels in_lock(*in_bitmap);
   for (int y = 0; y < in_bitmap->height(); ++y) {
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc
index f428259..2e564fa 100644
--- a/ui/views/widget/native_widget_aura.cc
+++ b/ui/views/widget/native_widget_aura.cc
@@ -17,6 +17,7 @@
 #include "ui/aura/window_event_dispatcher.h"
 #include "ui/aura/window_observer.h"
 #include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/ui_base_switches_util.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/compositor/layer.h"
 #include "ui/events/event.h"
@@ -26,6 +27,7 @@
 #include "ui/native_theme/native_theme_aura.h"
 #include "ui/views/drag_utils.h"
 #include "ui/views/ime/input_method_bridge.h"
+#include "ui/views/ime/null_input_method.h"
 #include "ui/views/views_delegate.h"
 #include "ui/views/widget/drop_helper.h"
 #include "ui/views/widget/native_widget_delegate.h"
@@ -270,6 +272,10 @@
 InputMethod* NativeWidgetAura::CreateInputMethod() {
   if (!window_)
     return NULL;
+
+  if (switches::IsTextInputFocusManagerEnabled())
+    return new NullInputMethod();
+
   aura::Window* root_window = window_->GetRootWindow();
   ui::InputMethod* host =
       root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
@@ -280,6 +286,11 @@
   return this;
 }
 
+ui::InputMethod* NativeWidgetAura::GetHostInputMethod() {
+  aura::Window* root_window = window_->GetRootWindow();
+  return root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
+}
+
 void NativeWidgetAura::CenterWindow(const gfx::Size& size) {
   if (!window_)
     return;
@@ -821,6 +832,12 @@
   if (!window_->IsVisible())
     return;
   GetWidget()->GetInputMethod()->DispatchKeyEvent(*event);
+  if (switches::IsTextInputFocusManagerEnabled()) {
+    FocusManager* focus_manager = GetWidget()->GetFocusManager();
+    delegate_->OnKeyEvent(event);
+    if (!event->handled() && focus_manager)
+      focus_manager->OnKeyEvent(*event);
+  }
   event->SetHandled();
 }
 
diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h
index 0a29b34..69fd4d3 100644
--- a/ui/views/widget/native_widget_aura.h
+++ b/ui/views/widget/native_widget_aura.h
@@ -72,6 +72,7 @@
   virtual bool HasCapture() const OVERRIDE;
   virtual InputMethod* CreateInputMethod() OVERRIDE;
   virtual internal::InputMethodDelegate* GetInputMethodDelegate() OVERRIDE;
+  virtual ui::InputMethod* GetHostInputMethod() OVERRIDE;
   virtual void CenterWindow(const gfx::Size& size) OVERRIDE;
   virtual void GetWindowPlacement(
       gfx::Rect* bounds,
diff --git a/ui/views/widget/native_widget_private.h b/ui/views/widget/native_widget_private.h
index b6b3f78..030344e 100644
--- a/ui/views/widget/native_widget_private.h
+++ b/ui/views/widget/native_widget_private.h
@@ -8,7 +8,6 @@
 #include "base/strings/string16.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/gfx/native_widget_types.h"
-#include "ui/views/ime/input_method_delegate.h"
 #include "ui/views/widget/native_widget.h"
 
 namespace gfx {
@@ -18,12 +17,14 @@
 }
 
 namespace ui {
+class InputMethod;
 class NativeTheme;
 class OSExchangeData;
 }
 
 namespace views {
 class InputMethod;
+class InputMethodDelegate;
 class TooltipManager;
 namespace internal {
 
@@ -145,6 +146,10 @@
   // Returns the InputMethodDelegate for this native widget.
   virtual InputMethodDelegate* GetInputMethodDelegate() = 0;
 
+  // Returns the ui::InputMethod for this native widget.
+  // TODO(yukishiino): Rename this method to GetInputMethod once we remove
+  // views::InputMethod.
+  virtual ui::InputMethod* GetHostInputMethod() = 0;
 
   // Centers the window and sizes it to the specified size.
   virtual void CenterWindow(const gfx::Size& size) = 0;
diff --git a/ui/views/widget/root_view.cc b/ui/views/widget/root_view.cc
index b103943..2a01b68 100644
--- a/ui/views/widget/root_view.cc
+++ b/ui/views/widget/root_view.cc
@@ -207,7 +207,7 @@
   if (event->IsKeyEvent())
     return EventProcessor::OnEventFromSource(event);
   else if (event->IsScrollEvent())
-    DispatchScrollEvent(static_cast<ui::ScrollEvent*>(event));
+    return EventProcessor::OnEventFromSource(event);
   else if (event->IsTouchEvent())
     NOTREACHED() << "Touch events should not be sent to RootView.";
   else if (event->IsGestureEvent())
@@ -700,25 +700,6 @@
 
 // Input -----------------------------------------------------------------------
 
-void RootView::DispatchScrollEvent(ui::ScrollEvent* event) {
-  for (View* v = GetEventHandlerForPoint(event->location());
-       v && v != this && !event->stopped_propagation(); v = v->parent()) {
-    ui::EventDispatchDetails dispatch_details = DispatchEvent(v, event);
-    if (dispatch_details.dispatcher_destroyed ||
-        dispatch_details.target_destroyed) {
-      return;
-    }
-  }
-
-  if (event->handled() || event->type() != ui::ET_SCROLL)
-    return;
-
-  // Convert unprocessed scroll events into mouse-wheel events.
-  ui::MouseWheelEvent wheel(*event);
-  if (OnMouseWheel(wheel))
-    event->SetHandled();
-}
-
 void RootView::UpdateCursor(const ui::MouseEvent& event) {
   if (!(event.flags() & ui::EF_IS_NON_CLIENT)) {
     View* v = GetEventHandlerForPoint(event.location());
diff --git a/ui/views/widget/root_view.h b/ui/views/widget/root_view.h
index ea8da5f..1016be8 100644
--- a/ui/views/widget/root_view.h
+++ b/ui/views/widget/root_view.h
@@ -110,6 +110,9 @@
   virtual void UpdateParentLayer() OVERRIDE;
 
  protected:
+  // TODO(tdanderson): Remove RootView::DispatchGestureEvent() once
+  //                   its targeting and dispatch logic has been moved
+  //                   elsewhere. See crbug.com/348083.
   virtual void DispatchGestureEvent(ui::GestureEvent* event);
 
   // Overridden from View:
@@ -128,11 +131,6 @@
 
   // Input ---------------------------------------------------------------------
 
-  // TODO(tdanderson): Remove the RootView::Dispatch*Event() functions once
-  //                   their targeting and dispatch logic has been moved
-  //                   elsewhere. See crbug.com/348083.
-  void DispatchScrollEvent(ui::ScrollEvent* event);
-
   // Update the cursor given a mouse event. This is called by non mouse_move
   // event handlers to honor the cursor desired by views located under the
   // cursor during drag operations. The location of the mouse should be in the
diff --git a/ui/views/widget/root_view_unittest.cc b/ui/views/widget/root_view_unittest.cc
index f3c729f..f96a45f 100644
--- a/ui/views/widget/root_view_unittest.cc
+++ b/ui/views/widget/root_view_unittest.cc
@@ -15,52 +15,6 @@
 
 typedef ViewsTestBase RootViewTest;
 
-// Verifies that the the functions ViewTargeter::FindTargetForEvent()
-// and ViewTargeter::FindNextBestTarget() are implemented correctly
-// for key events.
-TEST_F(RootViewTest, ViewTargeterForKeyEvents) {
-  Widget widget;
-  Widget::InitParams init_params =
-      CreateParams(Widget::InitParams::TYPE_POPUP);
-  init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
-  widget.Init(init_params);
-
-  View* content = new View;
-  View* child = new View;
-  View* grandchild = new View;
-
-  widget.SetContentsView(content);
-  content->AddChildView(child);
-  child->AddChildView(grandchild);
-
-  grandchild->SetFocusable(true);
-  grandchild->RequestFocus();
-
-  ui::EventTargeter* targeter = new ViewTargeter();
-  internal::RootView* root_view =
-      static_cast<internal::RootView*>(widget.GetRootView());
-  root_view->SetEventTargeter(make_scoped_ptr(targeter));
-
-  ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, 0, true);
-
-  // The focused view should be the initial target of the event.
-  ui::EventTarget* current_target = targeter->FindTargetForEvent(root_view,
-                                                                 &key_event);
-  EXPECT_EQ(grandchild, static_cast<View*>(current_target));
-
-  // Verify that FindNextBestTarget() will return the parent view of the
-  // argument (and NULL if the argument has no parent view).
-  current_target = targeter->FindNextBestTarget(grandchild, &key_event);
-  EXPECT_EQ(child, static_cast<View*>(current_target));
-  current_target = targeter->FindNextBestTarget(child, &key_event);
-  EXPECT_EQ(content, static_cast<View*>(current_target));
-  current_target = targeter->FindNextBestTarget(content, &key_event);
-  EXPECT_EQ(widget.GetRootView(), static_cast<View*>(current_target));
-  current_target = targeter->FindNextBestTarget(widget.GetRootView(),
-                                                &key_event);
-  EXPECT_EQ(NULL, static_cast<View*>(current_target));
-}
-
 class DeleteOnKeyEventView : public View {
  public:
   explicit DeleteOnKeyEventView(bool* set_on_key) : set_on_key_(set_on_key) {}
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index cfc6d59..ca10892 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -789,6 +789,10 @@
   }
 }
 
+ui::InputMethod* Widget::GetHostInputMethod() {
+  return native_widget_private()->GetHostInputMethod();
+}
+
 void Widget::RunShellDrag(View* view,
                           const ui::OSExchangeData& data,
                           const gfx::Point& location,
@@ -1030,11 +1034,19 @@
 }
 
 void Widget::OnNativeFocus(gfx::NativeView old_focused_view) {
+  // Ensure the focused view's TextInputClient is used for text input.
+  views::FocusManager* focus_manager = GetFocusManager();
+  focus_manager->FocusTextInputClient(focus_manager->GetFocusedView());
+
   WidgetFocusManager::GetInstance()->OnWidgetFocusEvent(old_focused_view,
                                                         GetNativeView());
 }
 
 void Widget::OnNativeBlur(gfx::NativeView new_focused_view) {
+  // Ensure the focused view's TextInputClient is not used for text input.
+  views::FocusManager* focus_manager = GetFocusManager();
+  focus_manager->BlurTextInputClient(focus_manager->GetFocusedView());
+
   WidgetFocusManager::GetInstance()->OnWidgetFocusEvent(GetNativeView(),
                                                         new_focused_view);
 }
@@ -1253,7 +1265,14 @@
 }
 
 void Widget::OnScrollEvent(ui::ScrollEvent* event) {
-  SendEventToProcessor(event);
+  ui::ScrollEvent event_copy(*event);
+  SendEventToProcessor(&event_copy);
+
+  // Convert unhandled ui::ET_SCROLL events into ui::ET_MOUSEWHEEL events.
+  if (!event_copy.handled() && event_copy.type() == ui::ET_SCROLL) {
+    ui::MouseWheelEvent wheel(*event);
+    OnMouseEvent(&wheel);
+  }
 }
 
 void Widget::OnGestureEvent(ui::GestureEvent* event) {
@@ -1356,8 +1375,15 @@
 // Widget, ui::NativeThemeObserver implementation:
 
 void Widget::OnNativeThemeUpdated(ui::NativeTheme* observed_theme) {
-  DCHECK_EQ(observed_theme, GetNativeTheme());
-  root_view_->PropagateNativeThemeChanged(GetNativeTheme());
+  DCHECK(observer_manager_.IsObserving(observed_theme));
+
+  ui::NativeTheme* current_native_theme = GetNativeTheme();
+  if (!observer_manager_.IsObserving(current_native_theme)) {
+    observer_manager_.RemoveAll();
+    observer_manager_.Add(current_native_theme);
+  }
+
+  root_view_->PropagateNativeThemeChanged(current_native_theme);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index 87f702d..0d383ad 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -47,6 +47,7 @@
 class Accelerator;
 class Compositor;
 class DefaultThemeProvider;
+class InputMethod;
 class Layer;
 class NativeTheme;
 class OSExchangeData;
@@ -541,6 +542,11 @@
   InputMethod* GetInputMethod();
   const InputMethod* GetInputMethod() const;
 
+  // Returns the ui::InputMethod for this widget.
+  // TODO(yukishiino): Rename this method to GetInputMethod once we remove
+  // views::InputMethod.
+  ui::InputMethod* GetHostInputMethod();
+
   // Starts a drag operation for the specified view. This blocks until the drag
   // operation completes. |view| can be NULL.
   // If the view is non-NULL it can be accessed during the drag by calling
diff --git a/ui/views/widget/widget_interactive_uitest.cc b/ui/views/widget/widget_interactive_uitest.cc
index 6aa255f..ae547ad 100644
--- a/ui/views/widget/widget_interactive_uitest.cc
+++ b/ui/views/widget/widget_interactive_uitest.cc
@@ -6,6 +6,7 @@
 #include "base/bind.h"
 #include "base/path_service.h"
 #include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
 #include "ui/aura/client/focus_client.h"
 #include "ui/aura/env.h"
 #include "ui/aura/window.h"
@@ -172,8 +173,7 @@
 //    another top level widget is created and focused.
 // 3. On focusing the native platform window for widget 1, the active aura
 //    window for widget 1 should be set and that for widget 2 should reset.
-// TODO(ananta)
-// Discuss with erg on how to write this test for linux x11 aura.
+// TODO(ananta): Discuss with erg on how to write this test for linux x11 aura.
 TEST_F(WidgetTestInteractive, DesktopNativeWidgetAuraActivationAndFocusTest) {
   // Create widget 1 and expect the active window to be its window.
   View* contents_view1 = new View;
@@ -462,8 +462,92 @@
   toplevel->CloseNow();
 }
 
+// Test view focus restoration when a widget is deactivated and re-activated.
+TEST_F(WidgetTestInteractive, ViewFocusOnWidgetActivationChanges) {
+  Widget* widget1 = CreateTopLevelPlatformWidget();
+  View* view1 = new View;
+  view1->SetFocusable(true);
+  widget1->GetContentsView()->AddChildView(view1);
+
+  Widget* widget2 = CreateTopLevelPlatformWidget();
+  View* view2a = new View;
+  View* view2b = new View;
+  view2a->SetFocusable(true);
+  view2b->SetFocusable(true);
+  widget2->GetContentsView()->AddChildView(view2a);
+  widget2->GetContentsView()->AddChildView(view2b);
+
+  widget1->Show();
+  EXPECT_TRUE(widget1->IsActive());
+  view1->RequestFocus();
+  EXPECT_EQ(view1, widget1->GetFocusManager()->GetFocusedView());
+
+  widget2->Show();
+  EXPECT_TRUE(widget2->IsActive());
+  EXPECT_FALSE(widget1->IsActive());
+  EXPECT_EQ(NULL, widget1->GetFocusManager()->GetFocusedView());
+  view2a->RequestFocus();
+  EXPECT_EQ(view2a, widget2->GetFocusManager()->GetFocusedView());
+  view2b->RequestFocus();
+  EXPECT_EQ(view2b, widget2->GetFocusManager()->GetFocusedView());
+
+  widget1->Activate();
+  EXPECT_TRUE(widget1->IsActive());
+  EXPECT_EQ(view1, widget1->GetFocusManager()->GetFocusedView());
+  EXPECT_FALSE(widget2->IsActive());
+  EXPECT_EQ(NULL, widget2->GetFocusManager()->GetFocusedView());
+
+  widget2->Activate();
+  EXPECT_TRUE(widget2->IsActive());
+  EXPECT_EQ(view2b, widget2->GetFocusManager()->GetFocusedView());
+  EXPECT_FALSE(widget1->IsActive());
+  EXPECT_EQ(NULL, widget1->GetFocusManager()->GetFocusedView());
+
+  widget1->CloseNow();
+  widget2->CloseNow();
+}
+
 #if defined(OS_WIN)
 
+// Test view focus retention when a widget's HWND is disabled and re-enabled.
+TEST_F(WidgetTestInteractive, ViewFocusOnHWNDEnabledChanges) {
+  Widget* widget = CreateTopLevelFramelessPlatformWidget();
+  widget->SetContentsView(new View);
+  for (size_t i = 0; i < 2; ++i) {
+    widget->GetContentsView()->AddChildView(new View);
+    widget->GetContentsView()->child_at(i)->SetFocusable(true);
+  }
+
+  widget->Show();
+  const HWND hwnd = HWNDForWidget(widget);
+  EXPECT_TRUE(::IsWindow(hwnd));
+  EXPECT_TRUE(::IsWindowEnabled(hwnd));
+  EXPECT_EQ(hwnd, ::GetActiveWindow());
+
+  for (int i = 0; i < widget->GetContentsView()->child_count(); ++i) {
+    SCOPED_TRACE(base::StringPrintf("Child view %d", i));
+    View* view = widget->GetContentsView()->child_at(i);
+
+    view->RequestFocus();
+    EXPECT_EQ(view, widget->GetFocusManager()->GetFocusedView());
+    EXPECT_FALSE(::EnableWindow(hwnd, FALSE));
+    EXPECT_FALSE(::IsWindowEnabled(hwnd));
+
+    // Oddly, disabling the HWND leaves it active with the focus unchanged.
+    EXPECT_EQ(hwnd, ::GetActiveWindow());
+    EXPECT_TRUE(widget->IsActive());
+    EXPECT_EQ(view, widget->GetFocusManager()->GetFocusedView());
+
+    EXPECT_TRUE(::EnableWindow(hwnd, TRUE));
+    EXPECT_TRUE(::IsWindowEnabled(hwnd));
+    EXPECT_EQ(hwnd, ::GetActiveWindow());
+    EXPECT_TRUE(widget->IsActive());
+    EXPECT_EQ(view, widget->GetFocusManager()->GetFocusedView());
+  }
+
+  widget->CloseNow();
+}
+
 // This class subclasses the Widget class to listen for activation change
 // notifications and provides accessors to return information as to whether
 // the widget is active. We need this to ensure that users of the widget
@@ -542,8 +626,7 @@
 };
 
 // Tests whether the focused window is set correctly when a modal window is
-// created and destroyed. When it is destroyed it should focus the owner
-// window.
+// created and destroyed. When it is destroyed it should focus the owner window.
 TEST_F(WidgetTestInteractive, WindowModalWindowDestroyedActivationTest) {
   // Create a top level widget.
   Widget top_level_widget;
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc
index 4150f87..66f225f 100644
--- a/ui/views/widget/widget_unittest.cc
+++ b/ui/views/widget/widget_unittest.cc
@@ -86,7 +86,7 @@
 };
 
 // A view that keeps track of the events it receives, and consumes all scroll
-// gesture events.
+// gesture events and ui::ET_SCROLL events.
 class ScrollableEventCountView : public EventCountView {
  public:
   ScrollableEventCountView() {}
@@ -108,6 +108,12 @@
     }
   }
 
+  virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
+    EventCountView::OnScrollEvent(event);
+    if (event->type() == ui::ET_SCROLL)
+      event->SetHandled();
+  }
+
   DISALLOW_COPY_AND_ASSIGN(ScrollableEventCountView);
 };
 
@@ -1443,6 +1449,7 @@
 }
 
 // Tests that event-handlers installed on the RootView get triggered correctly.
+// TODO(tdanderson): Clean up this test as part of crbug.com/355680.
 TEST_F(WidgetTest, EventHandlersOnRootView) {
   Widget* widget = CreateTopLevelNativeWidget();
   View* root_view = widget->GetRootView();
@@ -1484,9 +1491,67 @@
                          0, 20,
                          2);
   widget->OnScrollEvent(&scroll);
-  EXPECT_EQ(1, h1.GetEventCount(ui::ET_SCROLL));
+  EXPECT_EQ(2, h1.GetEventCount(ui::ET_SCROLL));
   EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL));
-  EXPECT_EQ(1, h2.GetEventCount(ui::ET_SCROLL));
+  EXPECT_EQ(2, h2.GetEventCount(ui::ET_SCROLL));
+
+  // Unhandled scroll events are turned into wheel events and re-dispatched.
+  EXPECT_EQ(1, h1.GetEventCount(ui::ET_MOUSEWHEEL));
+  EXPECT_EQ(1, view->GetEventCount(ui::ET_MOUSEWHEEL));
+  EXPECT_EQ(1, h2.GetEventCount(ui::ET_MOUSEWHEEL));
+
+  h1.ResetCounts();
+  view->ResetCounts();
+  h2.ResetCounts();
+
+  ui::ScrollEvent fling(ui::ET_SCROLL_FLING_START,
+                        gfx::Point(5, 5),
+                        ui::EventTimeForNow(),
+                        0,
+                        0, 20,
+                        0, 20,
+                        2);
+  widget->OnScrollEvent(&fling);
+  EXPECT_EQ(2, h1.GetEventCount(ui::ET_SCROLL_FLING_START));
+  EXPECT_EQ(1, view->GetEventCount(ui::ET_SCROLL_FLING_START));
+  EXPECT_EQ(2, h2.GetEventCount(ui::ET_SCROLL_FLING_START));
+
+  // Unhandled scroll events which are not of type ui::ET_SCROLL should not
+  // be turned into wheel events and re-dispatched.
+  EXPECT_EQ(0, h1.GetEventCount(ui::ET_MOUSEWHEEL));
+  EXPECT_EQ(0, view->GetEventCount(ui::ET_MOUSEWHEEL));
+  EXPECT_EQ(0, h2.GetEventCount(ui::ET_MOUSEWHEEL));
+
+  h1.ResetCounts();
+  view->ResetCounts();
+  h2.ResetCounts();
+
+  // Replace the child of |root_view| with a ScrollableEventCountView so that
+  // ui::ET_SCROLL events are marked as handled at the target phase.
+  root_view->RemoveChildView(view);
+  ScrollableEventCountView* scroll_view = new ScrollableEventCountView;
+  scroll_view->SetBounds(0, 0, 20, 20);
+  root_view->AddChildView(scroll_view);
+
+  ui::ScrollEvent consumed_scroll(ui::ET_SCROLL,
+                                  gfx::Point(5, 5),
+                                  ui::EventTimeForNow(),
+                                  0,
+                                  0, 20,
+                                  0, 20,
+                                  2);
+  widget->OnScrollEvent(&consumed_scroll);
+
+  // The event is handled at the target phase and should not reach the
+  // post-target handler.
+  EXPECT_EQ(1, h1.GetEventCount(ui::ET_SCROLL));
+  EXPECT_EQ(1, scroll_view->GetEventCount(ui::ET_SCROLL));
+  EXPECT_EQ(0, h2.GetEventCount(ui::ET_SCROLL));
+
+  // Handled scroll events are not turned into wheel events and re-dispatched.
+  EXPECT_EQ(0, h1.GetEventCount(ui::ET_MOUSEWHEEL));
+  EXPECT_EQ(0, scroll_view->GetEventCount(ui::ET_MOUSEWHEEL));
+  EXPECT_EQ(0, h2.GetEventCount(ui::ET_MOUSEWHEEL));
 
   widget->CloseNow();
 }
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 9e5e09e..ec3cacf 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -340,7 +340,6 @@
       waiting_for_close_now_(false),
       remove_standard_frame_(false),
       use_system_default_icon_(false),
-      restore_focus_when_enabled_(false),
       restored_enabled_(false),
       current_cursor_(NULL),
       previous_cursor_(NULL),
@@ -919,17 +918,8 @@
       delegate_->HandleDestroyed();
   }
 
-  // Only top level widget should store/restore focus.
-  if (message == WM_ACTIVATE && delegate_->CanSaveFocus())
+  if (message == WM_ACTIVATE && IsTopLevelWindow(window))
     PostProcessActivateMessage(LOWORD(w_param), !!HIWORD(w_param));
-
-  if (message == WM_ENABLE && restore_focus_when_enabled_) {
-    // This path should be executed only for top level as
-    // restore_focus_when_enabled_ is set in PostProcessActivateMessage.
-    DCHECK(delegate_->CanSaveFocus());
-    restore_focus_when_enabled_ = false;
-    delegate_->RestoreFocusOnEnable();
-  }
   return result;
 }
 
@@ -998,33 +988,10 @@
 
 void HWNDMessageHandler::PostProcessActivateMessage(int activation_state,
                                                     bool minimized) {
-  DCHECK(delegate_->CanSaveFocus());
-
-  bool active = activation_state != WA_INACTIVE && !minimized;
+  DCHECK(IsTopLevelWindow(hwnd()));
+  const bool active = activation_state != WA_INACTIVE && !minimized;
   if (delegate_->CanActivate())
     delegate_->HandleActivationChanged(active);
-
-  if (!active) {
-    // We might get activated/inactivated without being enabled, so we need to
-    // clear restore_focus_when_enabled_.
-    restore_focus_when_enabled_ = false;
-    delegate_->SaveFocusOnDeactivate();
-  } else {
-    // We must restore the focus after the message has been DefProc'ed as it
-    // does set the focus to the last focused HWND.
-    // Note that if the window is not enabled, we cannot restore the focus as
-    // calling ::SetFocus on a child of the non-enabled top-window would fail.
-    // This is the case when showing a modal dialog (such as 'open file',
-    // 'print'...) from a different thread.
-    // In that case we delay the focus restoration to when the window is enabled
-    // again.
-    if (!IsWindowEnabled(hwnd())) {
-      DCHECK(!restore_focus_when_enabled_);
-      restore_focus_when_enabled_ = true;
-      return;
-    }
-    delegate_->RestoreFocusOnActivate();
-  }
 }
 
 void HWNDMessageHandler::RestoreEnabledIfNecessary() {
diff --git a/ui/views/win/hwnd_message_handler.h b/ui/views/win/hwnd_message_handler.h
index f4fc19a..bfa1710 100644
--- a/ui/views/win/hwnd_message_handler.h
+++ b/ui/views/win/hwnd_message_handler.h
@@ -484,10 +484,6 @@
 
   bool use_system_default_icon_;
 
-  // Whether the focus should be restored next time we get enabled.  Needed to
-  // restore focus correctly when Windows modal dialogs are displayed.
-  bool restore_focus_when_enabled_;
-
   // Whether all ancestors have been enabled. This is only used if is_modal_ is
   // true.
   bool restored_enabled_;
diff --git a/ui/views/win/hwnd_message_handler_delegate.h b/ui/views/win/hwnd_message_handler_delegate.h
index c110a45..87b9a96 100644
--- a/ui/views/win/hwnd_message_handler_delegate.h
+++ b/ui/views/win/hwnd_message_handler_delegate.h
@@ -46,13 +46,6 @@
 
   virtual bool WidgetSizeIsClientSize() const = 0;
 
-  // Returns true if the delegate has a focus saving mechanism that should be
-  // used when the window is activated and deactivated.
-  virtual bool CanSaveFocus() const = 0;
-  virtual void SaveFocusOnDeactivate() = 0;
-  virtual void RestoreFocusOnActivate() = 0;
-  virtual void RestoreFocusOnEnable() = 0;
-
   // Returns true if the delegate represents a modal window.
   virtual bool IsModal() const = 0;
 
diff --git a/ui/views/window/custom_frame_view.cc b/ui/views/window/custom_frame_view.cc
index 4075f6b..cfb34e6 100644
--- a/ui/views/window/custom_frame_view.cc
+++ b/ui/views/window/custom_frame_view.cc
@@ -192,7 +192,8 @@
 }
 
 void CustomFrameView::UpdateWindowTitle() {
-  SchedulePaintInRect(title_bounds_);
+  if (frame_->widget_delegate()->ShouldShowWindowTitle())
+    SchedulePaintInRect(title_bounds_);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -379,7 +380,7 @@
   // It seems like in some conditions we can be asked to paint after the window
   // that contains us is WM_DESTROYed. At this point, our delegate is NULL. The
   // correct long term fix may be to shut down the RootView in WM_DESTROY.
-  if (!delegate)
+  if (!delegate || !delegate->ShouldShowWindowTitle())
     return;
 
   gfx::Rect rect = title_bounds_;
@@ -538,6 +539,9 @@
   if (show_window_icon)
     window_icon_->SetBoundsRect(icon_bounds);
 
+  if (!frame_->widget_delegate()->ShouldShowWindowTitle())
+    return;
+
   // The offset between the window left edge and the title text.
   int title_x = show_window_icon ? icon_bounds.right() + kTitleIconOffsetX
                                  : icon_bounds.x();
diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc
index cdcc98e..e100fd1 100644
--- a/ui/views/window/dialog_client_view.cc
+++ b/ui/views/window/dialog_client_view.cc
@@ -265,13 +265,6 @@
     const ViewHierarchyChangedDetails& details) {
   ClientView::ViewHierarchyChanged(details);
   if (details.is_add && details.child == this) {
-    // The old dialog style needs an explicit background color, while the new
-    // dialog style simply inherits the bubble's frame view color.
-    const DialogDelegate* dialog = GetDialogDelegate();
-    if (dialog && !dialog->UseNewStyleForThisDialog())
-      set_background(views::Background::CreateSolidBackground(GetNativeTheme()->
-          GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)));
-
     focus_manager_ = GetFocusManager();
     if (focus_manager_)
       GetFocusManager()->AddFocusChangeListener(this);
@@ -304,6 +297,17 @@
   }
 }
 
+void DialogClientView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
+  // The old dialog style needs an explicit background color, while the new
+  // dialog style simply inherits the bubble's frame view color.
+  const DialogDelegate* dialog = GetDialogDelegate();
+
+  if (dialog && !dialog->UseNewStyleForThisDialog()) {
+    set_background(views::Background::CreateSolidBackground(GetNativeTheme()->
+        GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)));
+  }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // DialogClientView, ButtonListener implementation:
 
diff --git a/ui/views/window/dialog_client_view.h b/ui/views/window/dialog_client_view.h
index d780806..e6f0ca2 100644
--- a/ui/views/window/dialog_client_view.h
+++ b/ui/views/window/dialog_client_view.h
@@ -63,6 +63,7 @@
   virtual void ViewHierarchyChanged(
       const ViewHierarchyChangedDetails& details) OVERRIDE;
   virtual void NativeViewHierarchyChanged() OVERRIDE;
+  virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE;
 
   // ButtonListener implementation:
   virtual void ButtonPressed(Button* sender, const ui::Event& event) OVERRIDE;
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc
index 8177be4..7af50a4 100644
--- a/ui/views/window/dialog_delegate.cc
+++ b/ui/views/window/dialog_delegate.cc
@@ -156,10 +156,10 @@
 // static
 NonClientFrameView* DialogDelegate::CreateDialogFrameView(Widget* widget) {
   BubbleFrameView* frame = new BubbleFrameView(gfx::Insets());
-  const SkColor color = widget->GetNativeTheme()->GetSystemColor(
-      ui::NativeTheme::kColorId_DialogBackground);
-  frame->SetBubbleBorder(scoped_ptr<BubbleBorder>(new BubbleBorder(
-      BubbleBorder::FLOAT, BubbleBorder::SMALL_SHADOW, color)));
+  scoped_ptr<BubbleBorder> border(new BubbleBorder(
+      BubbleBorder::FLOAT, BubbleBorder::SMALL_SHADOW, SK_ColorRED));
+  border->set_use_theme_background_color(true);
+  frame->SetBubbleBorder(border.Pass());
   DialogDelegate* delegate = widget->widget_delegate()->AsDialogDelegate();
   if (delegate) {
     View* titlebar_view = delegate->CreateTitlebarExtraView();
diff --git a/ui/webui/OWNERS b/ui/webui/OWNERS
index 56e1ae7..29391db 100644
--- a/ui/webui/OWNERS
+++ b/ui/webui/OWNERS
@@ -7,6 +7,3 @@
 nkostylev@chromium.org
 pam@chromium.org
 xiyuan@chromium.org
-
-# temporarily for refactoring. http://crbug.com/169170
-jam@chromium.org
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd
index dba0606..0df4423 100644
--- a/ui/webui/resources/webui_resources.grd
+++ b/ui/webui/resources/webui_resources.grd
@@ -341,19 +341,9 @@
                  file="js/cr/ui/touch_handler.js" type="chrome_html" />
       <structure name="IDR_WEBUI_JS_EVENT_TRACKER"
                  file="js/event_tracker.js" type="chrome_html" />
-      <structure name="IDR_WEBUI_JS_I18N_PROCESS"
-                 file="js/i18n_process.js" type="chrome_html" />
-      <structure name="IDR_WEBUI_JS_I18N_TEMPLATE"
-                 file="js/i18n_template.js" type="chrome_html" />
       <structure name="IDR_WEBUI_JS_I18N_TEMPLATE_NO_PROCESS"
                  file="js/i18n_template_no_process.js"
                  type="chrome_html" />
-      <structure name="IDR_WEBUI_JS_I18N_TEMPLATE2"
-                 file="js/i18n_template2.js" type="chrome_html"
-                 flattenhtml="true" />
-      <structure name="IDR_WEBUI_JS_JSTEMPLATE_COMPILED"
-                 file="js/jstemplate_compiled.js" type="chrome_html"
-                 flattenhtml="true" />
       <structure name="IDR_WEBUI_JS_LOAD_TIME_DATA"
                  file="js/load_time_data.js" type="chrome_html" />
       <structure name="IDR_WEBUI_JS_LOCAL_STRINGS"
diff --git a/ui/wm/core/easy_resize_window_targeter.cc b/ui/wm/core/easy_resize_window_targeter.cc
index d352e52..445028c 100644
--- a/ui/wm/core/easy_resize_window_targeter.cc
+++ b/ui/wm/core/easy_resize_window_targeter.cc
@@ -24,8 +24,9 @@
 }
 
 bool EasyResizeWindowTargeter::EventLocationInsideBounds(
-    aura::Window* window,
+    ui::EventTarget* target,
     const ui::LocatedEvent& event) const {
+  aura::Window* window = static_cast<aura::Window*>(target);
   if (ShouldUseExtendedBounds(window)) {
     // Note that |event|'s location is in |window|'s parent's coordinate system,
     // so convert it to |window|'s coordinate system first.
diff --git a/ui/wm/core/easy_resize_window_targeter.h b/ui/wm/core/easy_resize_window_targeter.h
index 90b0848..35b9eb2 100644
--- a/ui/wm/core/easy_resize_window_targeter.h
+++ b/ui/wm/core/easy_resize_window_targeter.h
@@ -31,9 +31,9 @@
     touch_extend_ = touch_extend;
   }
 
-  // aura::WindowTargeter:
+  // ui::EventTargeter:
   virtual bool EventLocationInsideBounds(
-      aura::Window* window,
+      ui::EventTarget* target,
       const ui::LocatedEvent& event) const OVERRIDE;
 
  private:
diff --git a/ui/wm/core/focus_controller.cc b/ui/wm/core/focus_controller.cc
index f4d3f3f..37af32e 100644
--- a/ui/wm/core/focus_controller.cc
+++ b/ui/wm/core/focus_controller.cc
@@ -10,6 +10,7 @@
 #include "ui/aura/client/focus_change_observer.h"
 #include "ui/aura/env.h"
 #include "ui/aura/window_tracker.h"
+#include "ui/base/ime/text_input_focus_manager.h"
 #include "ui/events/event.h"
 #include "ui/wm/core/focus_rules.h"
 #include "ui/wm/core/window_util.h"
@@ -230,6 +231,15 @@
 
   base::AutoReset<bool> updating_focus(&updating_focus_, true);
   aura::Window* lost_focus = focused_window_;
+
+  // |window| is going to get the focus, so reset the text input client.
+  // OnWindowFocused() may set a proper text input client if the implementation
+  // supports text input.
+  ui::TextInputFocusManager* text_input_focus_manager =
+      ui::TextInputFocusManager::GetInstance();
+  if (window)
+    text_input_focus_manager->FocusTextInputClient(NULL);
+
   // Allow for the window losing focus to be deleted during dispatch. If it is
   // deleted pass NULL to observers instead of a deleted window.
   aura::WindowTracker window_tracker;
@@ -261,6 +271,10 @@
         focused_window_,
         window_tracker.Contains(lost_focus) ? lost_focus : NULL);
   }
+
+  // Ensure that the text input client is reset when the window loses the focus.
+  if (!window)
+    text_input_focus_manager->FocusTextInputClient(NULL);
 }
 
 void FocusController::SetActiveWindow(aura::Window* requested_window,
diff --git a/ui/wm/core/focus_controller_unittest.cc b/ui/wm/core/focus_controller_unittest.cc
index d460100..d3b8183 100644
--- a/ui/wm/core/focus_controller_unittest.cc
+++ b/ui/wm/core/focus_controller_unittest.cc
@@ -16,6 +16,8 @@
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
 #include "ui/aura/window_tracker.h"
+#include "ui/base/ime/dummy_text_input_client.h"
+#include "ui/base/ime/text_input_focus_manager.h"
 #include "ui/events/event_handler.h"
 #include "ui/wm/core/base_focus_rules.h"
 #include "ui/wm/core/wm_state.h"
@@ -252,6 +254,25 @@
   DISALLOW_COPY_AND_ASSIGN(ScopedTargetFocusNotificationObserver);
 };
 
+class ScopedFocusedTextInputClientChanger
+    : public ScopedFocusNotificationObserver {
+ public:
+  ScopedFocusedTextInputClientChanger(aura::Window* root_window,
+                                      ui::TextInputClient* text_input_client)
+      : ScopedFocusNotificationObserver(root_window),
+        text_input_client_(text_input_client) {}
+
+ private:
+  // Overridden from aura::client::FocusChangeObserver:
+  virtual void OnWindowFocused(aura::Window* gained_focus,
+                               aura::Window* lost_focus) OVERRIDE {
+    ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(
+        text_input_client_);
+  }
+
+  ui::TextInputClient* text_input_client_;
+};
+
 class FocusShiftingActivationObserver
     : public aura::client::ActivationChangeObserver {
  public:
@@ -442,6 +463,7 @@
   virtual void NoFocusChangeOnClickOnCaptureWindow() {}
   virtual void ChangeFocusWhenNothingFocusedAndCaptured() {}
   virtual void DontPassDeletedWindow() {}
+  virtual void FocusedTextInputClient() {}
 
  private:
   scoped_ptr<FocusController> focus_controller_;
@@ -795,6 +817,41 @@
     }
   }
 
+  // Verifies if the focused text input client is cleared when a window gains
+  // or loses the focus.
+  virtual void FocusedTextInputClient() OVERRIDE {
+    ui::TextInputFocusManager* text_input_focus_manager =
+        ui::TextInputFocusManager::GetInstance();
+    ui::DummyTextInputClient text_input_client;
+    ui::TextInputClient* null_text_input_client = NULL;
+
+    EXPECT_EQ(null_text_input_client,
+              text_input_focus_manager->GetFocusedTextInputClient());
+
+    text_input_focus_manager->FocusTextInputClient(&text_input_client);
+    EXPECT_EQ(&text_input_client,
+              text_input_focus_manager->GetFocusedTextInputClient());
+    FocusWindowById(1);
+    // The focused text input client gets cleared when a window gets focused
+    // unless any of observers sets the focused text input client.
+    EXPECT_EQ(null_text_input_client,
+              text_input_focus_manager->GetFocusedTextInputClient());
+
+    ScopedFocusedTextInputClientChanger text_input_focus_changer(
+        root_window(), &text_input_client);
+    EXPECT_EQ(null_text_input_client,
+              text_input_focus_manager->GetFocusedTextInputClient());
+    FocusWindowById(2);
+    // |text_input_focus_changer| sets the focused text input client.
+    EXPECT_EQ(&text_input_client,
+              text_input_focus_manager->GetFocusedTextInputClient());
+
+    FocusWindow(NULL);
+    // The focused text input client gets cleared when a window loses the focus.
+    EXPECT_EQ(null_text_input_client,
+              text_input_focus_manager->GetFocusedTextInputClient());
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(FocusControllerDirectTestBase);
 };
@@ -1181,4 +1238,8 @@
 // See description above DontPassDeletedWindow() for details.
 FOCUS_CONTROLLER_TEST(FocusControllerApiTest, DontPassDeletedWindow);
 
+// - Verifies that the focused text input client is cleard when the window focus
+//   changes.
+ALL_FOCUS_TESTS(FocusedTextInputClient);
+
 }  // namespace wm
diff --git a/ui/wm/core/masked_window_targeter.cc b/ui/wm/core/masked_window_targeter.cc
index 4cc26d5..5cbdb19 100644
--- a/ui/wm/core/masked_window_targeter.cc
+++ b/ui/wm/core/masked_window_targeter.cc
@@ -16,8 +16,9 @@
 MaskedWindowTargeter::~MaskedWindowTargeter() {}
 
 bool MaskedWindowTargeter::EventLocationInsideBounds(
-    aura::Window* window,
+    ui::EventTarget* target,
     const ui::LocatedEvent& event) const {
+  aura::Window* window = static_cast<aura::Window*>(target);
   if (window == masked_window_) {
     gfx::Path mask;
     if (!GetHitTestMask(window, &mask))
diff --git a/ui/wm/core/masked_window_targeter.h b/ui/wm/core/masked_window_targeter.h
index 46cf4d2..61bb3b1 100644
--- a/ui/wm/core/masked_window_targeter.h
+++ b/ui/wm/core/masked_window_targeter.h
@@ -24,9 +24,9 @@
   // coordinate system). Returns whether a valid mask has been set in |mask|.
   virtual bool GetHitTestMask(aura::Window* window, gfx::Path* mask) const = 0;
 
-  // aura::WindowTargeter:
+  // ui::EventTargeter:
   virtual bool EventLocationInsideBounds(
-      aura::Window* window,
+      ui::EventTarget* target,
       const ui::LocatedEvent& event) const OVERRIDE;
 
  private:
diff --git a/ui/wm/core/window_animations.cc b/ui/wm/core/window_animations.cc
index bea416f..a79db3a 100644
--- a/ui/wm/core/window_animations.cc
+++ b/ui/wm/core/window_animations.cc
@@ -46,6 +46,101 @@
 namespace wm {
 namespace {
 const float kWindowAnimation_Vertical_TranslateY = 15.f;
+
+// A base class for hiding animation observer which has two roles:
+// 1) Notifies AnimationHost at the end of hiding animation.
+// 2) Detaches the window's layers for hiding animation and deletes
+// them upon completion of the animation. This is necessary to a)
+// ensure that the animation continues in the event of the window being
+// deleted, and b) to ensure that the animation is visible even if the
+// window gets restacked below other windows when focus or activation
+// changes.
+// The subclass will determine when the animation is completed.
+class HidingWindowAnimationObserverBase : public aura::WindowObserver {
+ public:
+  HidingWindowAnimationObserverBase(aura::Window* window) : window_(window) {
+    window_->AddObserver(this);
+  }
+  virtual ~HidingWindowAnimationObserverBase() {
+    if (window_)
+      window_->RemoveObserver(this);
+  }
+
+  // aura::WindowObserver:
+  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
+    DCHECK_EQ(window, window_);
+    WindowInvalid();
+  }
+
+  virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {
+    DCHECK_EQ(window, window_);
+    WindowInvalid();
+  }
+
+  // Detach the current layers and create new layers for |window_|.
+  // Stack the original layers above |window_| and its transient
+  // children.  If the window has transient children, the original
+  // layers will be moved above the top most transient child so that
+  // activation change does not put the window above the animating
+  // layer.
+  void DetachAndRecreateLayers() {
+    layer_owner_ = RecreateLayers(window_);
+    if (window_->parent()) {
+      const aura::Window::Windows& transient_children =
+          GetTransientChildren(window_);
+      aura::Window::Windows::const_iterator iter =
+          std::find(window_->parent()->children().begin(),
+                    window_->parent()->children().end(),
+                    window_);
+      DCHECK(iter != window_->parent()->children().end());
+      aura::Window* topmost_transient_child = NULL;
+      for (++iter; iter != window_->parent()->children().end(); ++iter) {
+        if (std::find(transient_children.begin(),
+                      transient_children.end(),
+                      *iter) != transient_children.end()) {
+          topmost_transient_child = *iter;
+        }
+      }
+      if (topmost_transient_child) {
+        window_->parent()->layer()->StackAbove(
+            layer_owner_->root(), topmost_transient_child->layer());
+      }
+    }
+  }
+
+ protected:
+  // Invoked when the hiding animation is completed.  It will delete
+  // 'this', and no operation should be made on this object after this
+  // point.
+  void OnAnimationCompleted() {
+    // Window may have been destroyed by this point.
+    if (window_) {
+      aura::client::AnimationHost* animation_host =
+          aura::client::GetAnimationHost(window_);
+      if (animation_host)
+        animation_host->OnWindowHidingAnimationCompleted();
+      window_->RemoveObserver(this);
+    }
+    delete this;
+  }
+
+ private:
+  // Invoked when the window is destroyed (or destroying).
+  void WindowInvalid() {
+    layer_owner_->root()->SuppressPaint();
+
+    window_->RemoveObserver(this);
+    window_ = NULL;
+  }
+
+  aura::Window* window_;
+
+  // The owner of detached layers.
+  scoped_ptr<ui::LayerTreeOwner> layer_owner_;
+
+  DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserverBase);
+};
+
 }  // namespace
 
 DEFINE_WINDOW_PROPERTY_KEY(int,
@@ -59,46 +154,22 @@
                            kWindowVisibilityAnimationVerticalPositionKey,
                            kWindowAnimation_Vertical_TranslateY);
 
-// An AnimationObserer which has two roles:
-// 1) Notifies AnimationHost at the end of hiding animation.
-// 2) Detaches the window's layers for hiding animation and deletes
-// them upon completion of the animation. This is necessary to a)
-// ensure that the animation continues in the event of the window being
-// deleted, and b) to ensure that the animation is visible even if the
-// window gets restacked below other windows when focus or activation
-// changes.
-class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver,
-                                      public aura::WindowObserver {
+// A HidingWindowAnimationObserver that deletes observer and detached
+// layers upon the completion of the implicit animation.
+class ImplicitHidingWindowAnimationObserver
+    : public HidingWindowAnimationObserverBase,
+      public ui::ImplicitAnimationObserver {
  public:
-  HidingWindowAnimationObserver(aura::Window* window,
-                                ui::ScopedLayerAnimationSettings* settings);
-  virtual ~HidingWindowAnimationObserver() {}
+  ImplicitHidingWindowAnimationObserver(
+      aura::Window* window,
+      ui::ScopedLayerAnimationSettings* settings);
+  virtual ~ImplicitHidingWindowAnimationObserver() {}
 
   // ui::ImplicitAnimationObserver:
   virtual void OnImplicitAnimationsCompleted() OVERRIDE;
 
-  // aura::WindowObserver:
-  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
-  virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
-
-  // Detach the current layers and create new layers for |window_|.
-  // Stack the original layers above |window_| and its transient
-  // children.  If the window has transient children, the original
-  // layers will be moved above the top most transient child so that
-  // activation change does not put the window above the animating
-  // layer.
-  void DetachAndRecreateLayers();
-
  private:
-  // Invoked when the window is destroyed (or destroying).
-  void WindowInvalid();
-
-  aura::Window* window_;
-
-  // The owner of detached layers.
-  scoped_ptr<ui::LayerTreeOwner> layer_owner_;
-
-  DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver);
+  DISALLOW_COPY_AND_ASSIGN(ImplicitHidingWindowAnimationObserver);
 };
 
 namespace {
@@ -319,6 +390,40 @@
   window->layer()->GetAnimator()->StartAnimation(sequence.release());
 }
 
+// A HidingWindowAnimationObserver that deletes observer and detached
+// layers when the last_sequence has been completed or aborted.
+class RotateHidingWindowAnimationObserver
+    : public HidingWindowAnimationObserverBase,
+      public ui::LayerAnimationObserver {
+ public:
+  RotateHidingWindowAnimationObserver(aura::Window* window)
+      : HidingWindowAnimationObserverBase(window), last_sequence_(NULL) {}
+  virtual ~RotateHidingWindowAnimationObserver() {}
+
+  void set_last_sequence(ui::LayerAnimationSequence* last_sequence) {
+    last_sequence_ = last_sequence;
+  }
+
+  // ui::LayerAnimationObserver:
+  virtual void OnLayerAnimationEnded(
+      ui::LayerAnimationSequence* sequence) OVERRIDE {
+    if (last_sequence_ == sequence)
+      OnAnimationCompleted();
+  }
+  virtual void OnLayerAnimationAborted(
+      ui::LayerAnimationSequence* sequence) OVERRIDE {
+    if (last_sequence_ == sequence)
+      OnAnimationCompleted();
+  }
+  virtual void OnLayerAnimationScheduled(
+      ui::LayerAnimationSequence* sequence) OVERRIDE {}
+
+ private:
+  ui::LayerAnimationSequence* last_sequence_;
+
+  DISALLOW_COPY_AND_ASSIGN(RotateHidingWindowAnimationObserver);
+};
+
 void AddLayerAnimationsForRotate(aura::Window* window, bool show) {
   if (show)
     window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
@@ -326,11 +431,10 @@
   base::TimeDelta duration = base::TimeDelta::FromMilliseconds(
       kWindowAnimation_Rotate_DurationMS);
 
-  HidingWindowAnimationObserver* observer = NULL;
+  RotateHidingWindowAnimationObserver* observer = NULL;
 
   if (!show) {
-    // TODO(oshima): Fix observer leak.
-    observer = new HidingWindowAnimationObserver(window, NULL);
+    observer = new RotateHidingWindowAnimationObserver(window);
     window->layer()->GetAnimator()->SchedulePauseForProperties(
         duration * (100 - kWindowAnimation_Rotate_OpacityDurationPercent) / 100,
         ui::LayerAnimationElement::OPACITY);
@@ -375,11 +479,13 @@
   scoped_ptr<ui::LayerAnimationElement> transition(
       ui::LayerAnimationElement::CreateInterpolatedTransformElement(
           rotation.release(), duration));
-
-  window->layer()->GetAnimator()->ScheduleAnimation(
-      new ui::LayerAnimationSequence(transition.release()));
-  if (observer)
+  ui::LayerAnimationSequence* last_sequence =
+      new ui::LayerAnimationSequence(transition.release());
+  window->layer()->GetAnimator()->ScheduleAnimation(last_sequence);
+  if (observer) {
+    observer->set_last_sequence(last_sequence);
     observer->DetachAndRecreateLayers();
+  }
 }
 
 void AnimateShowWindow_Rotate(aura::Window* window) {
@@ -451,68 +557,17 @@
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
-// HidingWindowAnimationObserver
+// ImplicitHidingWindowAnimationObserver
 
-HidingWindowAnimationObserver::HidingWindowAnimationObserver(
+ImplicitHidingWindowAnimationObserver::ImplicitHidingWindowAnimationObserver(
     aura::Window* window,
     ui::ScopedLayerAnimationSettings* settings)
-    : window_(window) {
-  window->AddObserver(this);
-  if (settings)
-    settings->AddObserver(this);
+    : HidingWindowAnimationObserverBase(window) {
+  settings->AddObserver(this);
 }
 
-void HidingWindowAnimationObserver::OnImplicitAnimationsCompleted() {
-  // Window may have been destroyed by this point.
-  if (window_) {
-    aura::client::AnimationHost* animation_host =
-        aura::client::GetAnimationHost(window_);
-    if (animation_host)
-      animation_host->OnWindowHidingAnimationCompleted();
-    window_->RemoveObserver(this);
-  }
-  delete this;
-}
-
-void HidingWindowAnimationObserver::OnWindowDestroying(aura::Window* window) {
-  DCHECK_EQ(window, window_);
-  WindowInvalid();
-}
-
-void HidingWindowAnimationObserver::OnWindowDestroyed(aura::Window* window) {
-  DCHECK_EQ(window, window_);
-  WindowInvalid();
-}
-
-void HidingWindowAnimationObserver::DetachAndRecreateLayers() {
-  layer_owner_ = RecreateLayers(window_);
-  if (window_->parent()) {
-    const aura::Window::Windows& transient_children =
-        GetTransientChildren(window_);
-    aura::Window::Windows::const_iterator iter =
-        std::find(window_->parent()->children().begin(),
-                  window_->parent()->children().end(),
-                  window_);
-    DCHECK(iter != window_->parent()->children().end());
-    aura::Window* topmost_transient_child = NULL;
-    for (++iter; iter != window_->parent()->children().end(); ++iter) {
-      if (std::find(transient_children.begin(),
-                    transient_children.end(),
-                    *iter) !=
-          transient_children.end()) {
-        topmost_transient_child = *iter;
-      }
-    }
-    if (topmost_transient_child) {
-      window_->parent()->layer()->StackAbove(
-          layer_owner_->root(), topmost_transient_child->layer());
-    }
-  }
-}
-
-void HidingWindowAnimationObserver::WindowInvalid() {
-  window_->RemoveObserver(this);
-  window_ = NULL;
+void ImplicitHidingWindowAnimationObserver::OnImplicitAnimationsCompleted() {
+  OnAnimationCompleted();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -521,8 +576,9 @@
 ScopedHidingAnimationSettings::ScopedHidingAnimationSettings(
     aura::Window* window)
     : layer_animation_settings_(window->layer()->GetAnimator()),
-      observer_(new HidingWindowAnimationObserver(
-          window, &layer_animation_settings_)) {
+      observer_(new ImplicitHidingWindowAnimationObserver(
+          window,
+          &layer_animation_settings_)) {
 }
 
 ScopedHidingAnimationSettings::~ScopedHidingAnimationSettings() {
diff --git a/ui/wm/core/window_animations.h b/ui/wm/core/window_animations.h
index 1c55d49..422167e 100644
--- a/ui/wm/core/window_animations.h
+++ b/ui/wm/core/window_animations.h
@@ -80,8 +80,8 @@
     aura::Window* window,
     float position);
 
-class HidingWindowAnimationObserver;
-// A wrapper of ui::ScopedLayerAnimationSettings for hiding animations.
+class ImplicitHidingWindowAnimationObserver;
+// A wrapper of ui::ScopedLayerAnimationSettings for implicit hiding animations.
 // Use this to ensure that the hiding animation is visible even after
 // the window is deleted or deactivated, instead of using
 // ui::ScopedLayerAnimationSettings directly.
@@ -97,7 +97,7 @@
 
  private:
   ui::ScopedLayerAnimationSettings layer_animation_settings_;
-  HidingWindowAnimationObserver* observer_;
+  ImplicitHidingWindowAnimationObserver* observer_;
 
   DISALLOW_COPY_AND_ASSIGN(ScopedHidingAnimationSettings);
 };
diff --git a/ui/wm/test/wm_test_helper.cc b/ui/wm/test/wm_test_helper.cc
index 8a3eba1..9a9af61 100644
--- a/ui/wm/test/wm_test_helper.cc
+++ b/ui/wm/test/wm_test_helper.cc
@@ -15,7 +15,7 @@
 namespace wm {
 
 WMTestHelper::WMTestHelper(const gfx::Size& default_window_size) {
-  aura::Env::CreateInstance();
+  aura::Env::CreateInstance(true);
   host_.reset(aura::WindowTreeHost::Create(gfx::Rect(default_window_size)));
   host_->InitHost();
   aura::client::SetWindowTreeClient(host_->window(), this);
diff --git a/url/BUILD.gn b/url/BUILD.gn
index 6445bfb..3736b9c 100644
--- a/url/BUILD.gn
+++ b/url/BUILD.gn
@@ -2,12 +2,26 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+declare_args() {
+  # Switches to using platform functions instead of ICU on Android.
+  use_icu_alternatives_on_android = false
+}
+
+# Sets the USE_ICU_ALTERNATIVES_ON_ANDROID define based on the build flag.
+config("url_icu_config") {
+  if (use_icu_alternatives_on_android) {
+    defines = [ "USE_ICU_ALTERNATIVES_ON_ANDROID=1" ]
+  }
+}
+
 component("url") {
   if (is_win) {
     # Don't conflict with Windows' "url.dll".
     output_name = "url_lib"
   }
   sources = [
+    "android/url_jni_registrar.cc",
+    "android/url_jni_registrar.h",
     "gurl.cc",
     "gurl.h",
     "third_party/mozilla/url_parse.cc",
@@ -32,6 +46,8 @@
     "url_canon_stdstring.cc",
     "url_canon_stdstring.h",
     "url_canon_stdurl.cc",
+    "url_constants.cc",
+    "url_constants.h",
     "url_export.h",
     "url_file.h",
     "url_parse_file.cc",
@@ -42,6 +58,8 @@
 
   defines = [ "URL_IMPLEMENTATION" ]
 
+  configs += [ ":url_icu_config" ]
+
   # if (is_win) {
   #   TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
   #   'msvs_disabled_warnings': [ 4267, ]
@@ -52,6 +70,22 @@
     "//third_party/icu:icudata",
     "//third_party/icu",
   ]
+
+  if (use_icu_alternatives_on_android) {
+    sources -= [
+      "url_canon_icu.cc",
+      "url_canon_icu.h",
+    ]
+    deps -= [
+      "//third_party/icu:icudata",
+      "//third_party/icu",
+    ]
+
+    sources += [
+      "url_canon_icu_alternatives_android.cc",
+      "url_canon_icu_alternatives_android.h",
+    ]
+  }
 }
 
 # TODO(dpranke): crbug.com/360936. Get this to build and run on Android.
@@ -59,6 +93,7 @@
   test("url_unittests") {
     sources = [
       "gurl_unittest.cc",
+      "url_canon_icu_unittest.cc",
       "url_canon_unittest.cc",
       "url_parse_unittest.cc",
       "url_test_utils.h",
@@ -66,8 +101,7 @@
     ]
 
     #if (is_posix && !is_mac && !is_ios) {
-    #  # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-    #  if ((use_allocator!="none" && use_allocator!="see_use_tcmalloc") || (use_allocator=="see_use_tcmalloc" && linux_use_tcmalloc) {
+    #  if (use_allocator!="none") {
     #    deps += "//base/allocator"
     #  }
     #}
@@ -79,10 +113,18 @@
 
     deps = [
       ":url",
-      "//base:i18n",
       "//base/test:run_all_unittests",
       "//testing/gtest",
       "//third_party/icu:icuuc",
     ]
+
+    if (use_icu_alternatives_on_android) {
+      sources -= [
+        "url_canon_icu_unittest.cc",
+      ]
+      deps -= [
+        "//third_party/icu:icuuc",
+      ]
+    }
   }
 }
diff --git a/url/DEPS b/url/DEPS
new file mode 100644
index 0000000..9643291
--- /dev/null
+++ b/url/DEPS
@@ -0,0 +1,13 @@
+include_rules = [
+  "+jni",
+
+  # Limit files that can depend on icu.
+  "-base/i18n",
+  "-third_party/icu",
+]
+
+specific_include_rules = {
+  "url_canon_icu(\.cc|_unittest\.cc)": [
+    "+third_party/icu",
+  ],
+}
diff --git a/url/android/java/src/org/chromium/url/IDNStringUtil.java b/url/android/java/src/org/chromium/url/IDNStringUtil.java
new file mode 100644
index 0000000..32000fd
--- /dev/null
+++ b/url/android/java/src/org/chromium/url/IDNStringUtil.java
@@ -0,0 +1,33 @@
+// 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.url;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+
+import java.net.IDN;
+
+/**
+ * This class is used to convert unicode IDN domain names to ASCII, when not
+ * building with ICU.
+ */
+@JNINamespace("url::android")
+public class IDNStringUtil {
+    /**
+     * Attempts to convert a Unicode string to an ASCII string using IDN rules.
+     * As of May 2014, the underlying Java function IDNA2003.
+     * @param src String to convert.
+     * @return: String containing only ASCII characters on success, null on
+     *                 failure.
+     */
+    @CalledByNative
+    private static String idnToASCII(String src) {
+        try {
+            return IDN.toASCII(src, IDN.USE_STD3_ASCII_RULES);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/url/android/url_jni_registrar.cc b/url/android/url_jni_registrar.cc
new file mode 100644
index 0000000..82a6e1b
--- /dev/null
+++ b/url/android/url_jni_registrar.cc
@@ -0,0 +1,24 @@
+// 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.
+
+#include "url/android/url_jni_registrar.h"
+
+#ifdef USE_ICU_ALTERNATIVES_ON_ANDROID
+#include "url/url_canon_icu_alternatives_android.h"
+#endif
+
+namespace url {
+namespace android {
+
+bool RegisterJni(JNIEnv* env) {
+#ifdef USE_ICU_ALTERNATIVES_ON_ANDROID
+  return RegisterIcuAlternativesJni(env);
+#endif
+
+  // Do nothing if USE_ICU_ALTERNATIVES_ON_ANDROID is not defined.
+  return true;
+}
+
+}  // namespace android
+}  // namespace url
diff --git a/url/android/url_jni_registrar.h b/url/android/url_jni_registrar.h
new file mode 100644
index 0000000..8fe7ded
--- /dev/null
+++ b/url/android/url_jni_registrar.h
@@ -0,0 +1,21 @@
+// 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.
+
+#ifndef URL_ANDROID_URL_JNI_REGISTRAR_H_
+#define URL_ANDROID_URL_JNI_REGISTRAR_H_
+
+#include <jni.h>
+
+#include "url/url_export.h"
+
+namespace url {
+namespace android {
+
+// Register all JNI bindings necessary for url.
+URL_EXPORT bool RegisterJni(JNIEnv* env);
+
+}  // namespace android
+}  // namespace url
+
+#endif  // URL_ANDROID_URL_JNI_REGISTRAR_H_
diff --git a/url/gurl_unittest.cc b/url/gurl_unittest.cc
index 89375a8..489b9d2 100644
--- a/url/gurl_unittest.cc
+++ b/url/gurl_unittest.cc
@@ -43,8 +43,8 @@
 
 }  // namespace
 
-// Different types of URLs should be handled differently by url_util, and
-// handed off to different canonicalizers.
+// Different types of URLs should be handled differently, and handed off to
+// different canonicalizers.
 TEST(GURLTest, Types) {
   // URLs with unknown schemes should be treated as path URLs, even when they
   // have things like "://".
diff --git a/url/third_party/mozilla/url_parse.h b/url/third_party/mozilla/url_parse.h
index cc3f2dd..71dbb78 100644
--- a/url/third_party/mozilla/url_parse.h
+++ b/url/third_party/mozilla/url_parse.h
@@ -75,7 +75,7 @@
 //      return I_CAN_NOT_FIND_THE_SCHEME_DUDE;
 //
 //    if (IsStandardScheme(url, scheme))  // Not provided by this component
-//      url_parseParseStandardURL(url, url_len, &parsed);
+//      ParseStandardURL(url, url_len, &parsed);
 //    else if (IsFileURL(url, scheme))    // Not provided by this component
 //      ParseFileURL(url, url_len, &parsed);
 //    else
diff --git a/url/url.gyp b/url/url.gyp
index 93bbee2..0ffc51a 100644
--- a/url/url.gyp
+++ b/url/url.gyp
@@ -33,6 +33,28 @@
       'defines': [
         'URL_IMPLEMENTATION',
       ],
+      'conditions': [
+        ['use_icu_alternatives_on_android==1', {
+          'sources!': [
+            'url_canon_icu.cc',
+            'url_canon_icu.h',
+          ],
+          'dependencies!': [
+            '../third_party/icu/icu.gyp:icui18n',
+            '../third_party/icu/icu.gyp:icuuc',
+          ],
+        }],
+        ['use_icu_alternatives_on_android==1 and OS=="android"', {
+          'dependencies': [
+            'url_java',
+            'url_jni_headers',
+          ],
+          'sources': [
+            'url_canon_icu_alternatives_android.cc',
+            'url_canon_icu_alternatives_android.h',
+          ],
+        }],
+      ],
       # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
       'msvs_disabled_warnings': [4267, ],
     },
@@ -40,7 +62,6 @@
       'target_name': 'url_unittests',
       'type': 'executable',
       'dependencies': [
-        '../base/base.gyp:base_i18n',
         '../base/base.gyp:run_all_unittests',
         '../testing/gtest.gyp:gtest',
         '../third_party/icu/icu.gyp:icuuc',
@@ -49,23 +70,61 @@
       'sources': [
         'gurl_unittest.cc',
         'origin_unittest.cc',
+        'url_canon_icu_unittest.cc',
         'url_canon_unittest.cc',
         'url_parse_unittest.cc',
         'url_test_utils.h',
         'url_util_unittest.cc',
       ],
       'conditions': [
-        # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-        ['os_posix==1 and OS!="mac" and OS!="ios" and ((use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1))',
+        ['os_posix==1 and OS!="mac" and OS!="ios" and use_allocator!="none"',
           {
             'dependencies': [
               '../base/allocator/allocator.gyp:allocator',
             ],
           }
         ],
+        ['use_icu_alternatives_on_android==1',
+          {
+            'sources!': [
+              'url_canon_icu_unittest.cc',
+            ],
+            'dependencies!': [
+              '../third_party/icu/icu.gyp:icuuc',
+            ],
+          }
+        ],
       ],
       # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
       'msvs_disabled_warnings': [4267, ],
     },
   ],
+  'conditions': [
+    ['use_icu_alternatives_on_android==1 and OS=="android"', {
+      'targets': [
+        {
+          'target_name': 'url_jni_headers',
+          'type': 'none',
+          'sources': [
+            'android/java/src/org/chromium/url/IDNStringUtil.java'
+          ],
+          'variables': {
+            'jni_gen_package': 'url',
+          },
+          'includes': [ '../build/jni_generator.gypi' ],
+        },
+        {
+          'target_name': 'url_java',
+          'type': 'none',
+          'variables': {
+            'java_in_dir': '../url/android/java',
+          },
+          'dependencies': [
+            '../base/base.gyp:base',
+          ],
+          'includes': [ '../build/java.gypi' ],
+        },
+      ],
+    }],
+  ],
 }
diff --git a/url/url_canon_icu.cc b/url/url_canon_icu.cc
index d53d7cc..741bed2 100644
--- a/url/url_canon_icu.cc
+++ b/url/url_canon_icu.cc
@@ -184,47 +184,4 @@
   }
 }
 
-bool ReadUTFChar(const char* str, int* begin, int length,
-                 unsigned* code_point_out) {
-  int code_point;  // Avoids warning when U8_NEXT writes -1 to it.
-  U8_NEXT(str, *begin, length, code_point);
-  *code_point_out = static_cast<unsigned>(code_point);
-
-  // The ICU macro above moves to the next char, we want to point to the last
-  // char consumed.
-  (*begin)--;
-
-  // Validate the decoded value.
-  if (U_IS_UNICODE_CHAR(code_point))
-    return true;
-  *code_point_out = kUnicodeReplacementCharacter;
-  return false;
-}
-
-bool ReadUTFChar(const base::char16* str, int* begin, int length,
-                 unsigned* code_point) {
-  if (U16_IS_SURROGATE(str[*begin])) {
-    if (!U16_IS_SURROGATE_LEAD(str[*begin]) || *begin + 1 >= length ||
-        !U16_IS_TRAIL(str[*begin + 1])) {
-      // Invalid surrogate pair.
-      *code_point = kUnicodeReplacementCharacter;
-      return false;
-    } else {
-      // Valid surrogate pair.
-      *code_point = U16_GET_SUPPLEMENTARY(str[*begin], str[*begin + 1]);
-      (*begin)++;
-    }
-  } else {
-    // Not a surrogate, just one 16-bit word.
-    *code_point = str[*begin];
-  }
-
-  if (U_IS_UNICODE_CHAR(*code_point))
-    return true;
-
-  // Invalid code point.
-  *code_point = kUnicodeReplacementCharacter;
-  return false;
-}
-
 }  // namespace url
diff --git a/url/url_canon_icu_alternatives_android.cc b/url/url_canon_icu_alternatives_android.cc
new file mode 100644
index 0000000..f43efce
--- /dev/null
+++ b/url/url_canon_icu_alternatives_android.cc
@@ -0,0 +1,41 @@
+// 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.
+
+#include <string.h>
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
+#include "jni/IDNStringUtil_jni.h"
+#include "url/url_canon_internal.h"
+
+namespace url {
+
+// This uses the JDK's conversion function, which uses IDNA 2003, unlike the
+// ICU implementation.
+bool IDNToASCII(const base::char16* src, int src_len, CanonOutputW* output) {
+  DCHECK_EQ(0, output->length());  // Output buffer is assumed empty.
+
+  JNIEnv* env = base::android::AttachCurrentThread();
+  base::android::ScopedJavaLocalRef<jstring> java_src =
+      base::android::ConvertUTF16ToJavaString(
+          env, base::StringPiece16(src, src_len));
+  ScopedJavaLocalRef<jstring> java_result =
+      android::Java_IDNStringUtil_idnToASCII(env, java_src.obj());
+  // NULL indicates failure.
+  if (java_result.is_null())
+    return false;
+
+  base::string16 utf16_result =
+      base::android::ConvertJavaStringToUTF16(java_result);
+  output->Append(utf16_result.data(), static_cast<int>(utf16_result.size()));
+  return true;
+}
+
+bool RegisterIcuAlternativesJni(JNIEnv* env) {
+  return android::RegisterNativesImpl(env);
+}
+
+}  // namespace url
diff --git a/url/url_canon_icu_alternatives_android.h b/url/url_canon_icu_alternatives_android.h
new file mode 100644
index 0000000..67306db
--- /dev/null
+++ b/url/url_canon_icu_alternatives_android.h
@@ -0,0 +1,18 @@
+// 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.
+
+#ifndef URL_URL_CANON_ICU_ALTERNATIVES_ANDROID_H_
+#define URL_URL_CANON_ICU_ALTERNATIVES_ANDROID_H_
+
+#include <jni.h>
+
+namespace url {
+
+// Explicitly register static JNI functions needed when not using ICU.
+bool RegisterIcuAlternativesJni(JNIEnv* env);
+
+}  // namespace url
+
+#endif  // URL_URL_CANON_ICU_ALTERNATIVES_ANDROID_H_
+
diff --git a/url/url_canon_icu_unittest.cc b/url/url_canon_icu_unittest.cc
new file mode 100644
index 0000000..b28c30a
--- /dev/null
+++ b/url/url_canon_icu_unittest.cc
@@ -0,0 +1,167 @@
+// 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.
+
+#include "base/macros.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/icu/source/common/unicode/ucnv.h"
+#include "url/url_canon.h"
+#include "url/url_canon_icu.h"
+#include "url/url_canon_stdstring.h"
+#include "url/url_test_utils.h"
+
+// Some implementations of base/basictypes.h may define ARRAYSIZE.
+// If it's not defined, we define it to the ARRAYSIZE_UNSAFE macro
+// which is in our version of basictypes.h.
+#ifndef ARRAYSIZE
+#define ARRAYSIZE ARRAYSIZE_UNSAFE
+#endif
+
+namespace url {
+
+using test_utils::WStringToUTF16;
+
+namespace {
+
+// Wrapper around a UConverter object that managers creation and destruction.
+class UConvScoper {
+ public:
+  explicit UConvScoper(const char* charset_name) {
+    UErrorCode err = U_ZERO_ERROR;
+    converter_ = ucnv_open(charset_name, &err);
+  }
+
+  ~UConvScoper() {
+    if (converter_)
+      ucnv_close(converter_);
+  }
+
+  // Returns the converter object, may be NULL.
+  UConverter* converter() const { return converter_; }
+
+ private:
+  UConverter* converter_;
+};
+
+TEST(URLCanonIcuTest, ICUCharsetConverter) {
+  struct ICUCase {
+    const wchar_t* input;
+    const char* encoding;
+    const char* expected;
+  } icu_cases[] = {
+      // UTF-8.
+    {L"Hello, world", "utf-8", "Hello, world"},
+    {L"\x4f60\x597d", "utf-8", "\xe4\xbd\xa0\xe5\xa5\xbd"},
+      // Non-BMP UTF-8.
+    {L"!\xd800\xdf00!", "utf-8", "!\xf0\x90\x8c\x80!"},
+      // Big5
+    {L"\x4f60\x597d", "big5", "\xa7\x41\xa6\x6e"},
+      // Unrepresentable character in the destination set.
+    {L"hello\x4f60\x06de\x597dworld", "big5",
+      "hello\xa7\x41%26%231758%3B\xa6\x6eworld"},
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE(icu_cases); i++) {
+    UConvScoper conv(icu_cases[i].encoding);
+    ASSERT_TRUE(conv.converter() != NULL);
+    ICUCharsetConverter converter(conv.converter());
+
+    std::string str;
+    StdStringCanonOutput output(&str);
+
+    base::string16 input_str(WStringToUTF16(icu_cases[i].input));
+    int input_len = static_cast<int>(input_str.length());
+    converter.ConvertFromUTF16(input_str.c_str(), input_len, &output);
+    output.Complete();
+
+    EXPECT_STREQ(icu_cases[i].expected, str.c_str());
+  }
+
+  // Test string sizes around the resize boundary for the output to make sure
+  // the converter resizes as needed.
+  const int static_size = 16;
+  UConvScoper conv("utf-8");
+  ASSERT_TRUE(conv.converter());
+  ICUCharsetConverter converter(conv.converter());
+  for (int i = static_size - 2; i <= static_size + 2; i++) {
+    // Make a string with the appropriate length.
+    base::string16 input;
+    for (int ch = 0; ch < i; ch++)
+      input.push_back('a');
+
+    RawCanonOutput<static_size> output;
+    converter.ConvertFromUTF16(input.c_str(), static_cast<int>(input.length()),
+                               &output);
+    EXPECT_EQ(input.length(), static_cast<size_t>(output.length()));
+  }
+}
+
+TEST(URLCanonIcuTest, QueryWithConverter) {
+  struct QueryCase {
+    const char* input8;
+    const wchar_t* input16;
+    const char* encoding;
+    const char* expected;
+  } query_cases[] = {
+      // Regular ASCII case in some different encodings.
+    {"foo=bar", L"foo=bar", "utf-8", "?foo=bar"},
+    {"foo=bar", L"foo=bar", "shift_jis", "?foo=bar"},
+    {"foo=bar", L"foo=bar", "gb2312", "?foo=bar"},
+      // Chinese input/output
+    {"q=\xe4\xbd\xa0\xe5\xa5\xbd", L"q=\x4f60\x597d", "gb2312",
+      "?q=%C4%E3%BA%C3"},
+    {"q=\xe4\xbd\xa0\xe5\xa5\xbd", L"q=\x4f60\x597d", "big5", "?q=%A7A%A6n"},
+      // Unencodable character in the destination character set should be
+      // escaped. The escape sequence unescapes to be the entity name:
+      // "?q=&#20320;"
+    {"q=Chinese\xef\xbc\xa7", L"q=Chinese\xff27", "iso-8859-1",
+      "?q=Chinese%26%2365319%3B"},
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE(query_cases); i++) {
+    Component out_comp;
+
+    UConvScoper conv(query_cases[i].encoding);
+    ASSERT_TRUE(!query_cases[i].encoding || conv.converter());
+    ICUCharsetConverter converter(conv.converter());
+
+    if (query_cases[i].input8) {
+      int len = static_cast<int>(strlen(query_cases[i].input8));
+      Component in_comp(0, len);
+      std::string out_str;
+
+      StdStringCanonOutput output(&out_str);
+      CanonicalizeQuery(query_cases[i].input8, in_comp, &converter, &output,
+                        &out_comp);
+      output.Complete();
+
+      EXPECT_EQ(query_cases[i].expected, out_str);
+    }
+
+    if (query_cases[i].input16) {
+      base::string16 input16(WStringToUTF16(query_cases[i].input16));
+      int len = static_cast<int>(input16.length());
+      Component in_comp(0, len);
+      std::string out_str;
+
+      StdStringCanonOutput output(&out_str);
+      CanonicalizeQuery(input16.c_str(), in_comp, &converter, &output,
+                        &out_comp);
+      output.Complete();
+
+      EXPECT_EQ(query_cases[i].expected, out_str);
+    }
+  }
+
+  // Extra test for input with embedded NULL;
+  std::string out_str;
+  StdStringCanonOutput output(&out_str);
+  Component out_comp;
+  CanonicalizeQuery("a \x00z\x01", Component(0, 5), NULL, &output, &out_comp);
+  output.Complete();
+  EXPECT_EQ("?a%20%00z%01", out_str);
+}
+
+}  // namespace
+
+}  // namespace url
diff --git a/url/url_canon_internal.cc b/url/url_canon_internal.cc
index bbd1484..1554814 100644
--- a/url/url_canon_internal.cc
+++ b/url/url_canon_internal.cc
@@ -2,13 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "url/url_canon_internal.h"
+
 #include <errno.h>
 #include <stdlib.h>
 
 #include <cstdio>
 #include <string>
 
-#include "url/url_canon_internal.h"
+#include "base/strings/utf_string_conversion_utils.h"
 
 namespace url {
 
@@ -245,6 +247,32 @@
       source, length, type, output);
 }
 
+bool ReadUTFChar(const char* str, int* begin, int length,
+                 unsigned* code_point_out) {
+  // This depends on ints and int32s being the same thing.  If they're not, it
+  // will fail to compile.
+  // TODO(mmenke):  This should probably be fixed.
+  if (!base::ReadUnicodeCharacter(str, length, begin, code_point_out) ||
+      !base::IsValidCharacter(*code_point_out)) {
+    *code_point_out = kUnicodeReplacementCharacter;
+    return false;
+  }
+  return true;
+}
+
+bool ReadUTFChar(const base::char16* str, int* begin, int length,
+                 unsigned* code_point_out) {
+  // This depends on ints and int32s being the same thing.  If they're not, it
+  // will fail to compile.
+  // TODO(mmenke):  This should probably be fixed.
+  if (!base::ReadUnicodeCharacter(str, length, begin, code_point_out) ||
+      !base::IsValidCharacter(*code_point_out)) {
+    *code_point_out = kUnicodeReplacementCharacter;
+    return false;
+  }
+  return true;
+}
+
 void AppendInvalidNarrowString(const char* spec, int begin, int end,
                                CanonOutput* output) {
   DoAppendInvalidNarrowString<char, unsigned char>(spec, begin, end, output);
diff --git a/url/url_canon_internal.h b/url/url_canon_internal.h
index e8efd82..71bfc40 100644
--- a/url/url_canon_internal.h
+++ b/url/url_canon_internal.h
@@ -148,8 +148,6 @@
 // |*begin| will be updated to point to the last character consumed so it
 // can be incremented in a loop and will be ready for the next character.
 // (for a single-byte ASCII character, it will not be changed).
-//
-// Implementation is in url_canon_icu.cc.
 URL_EXPORT bool ReadUTFChar(const char* str, int* begin, int length,
                             unsigned* code_point_out);
 
@@ -225,10 +223,8 @@
 // |*begin| will be updated to point to the last character consumed so it
 // can be incremented in a loop and will be ready for the next character.
 // (for a single-16-bit-word character, it will not be changed).
-//
-// Implementation is in url_canon_icu.cc.
 URL_EXPORT bool ReadUTFChar(const base::char16* str, int* begin, int length,
-                            unsigned* code_point);
+                            unsigned* code_point_out);
 
 // Equivalent to U16_APPEND_UNSAFE in ICU but uses our output method.
 inline void AppendUTF16Value(unsigned code_point,
diff --git a/url/url_canon_unittest.cc b/url/url_canon_unittest.cc
index 55f9608..9a766e3 100644
--- a/url/url_canon_unittest.cc
+++ b/url/url_canon_unittest.cc
@@ -4,10 +4,9 @@
 
 #include <errno.h>
 
+#include "base/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/icu/source/common/unicode/ucnv.h"
 #include "url/url_canon.h"
-#include "url/url_canon_icu.h"
 #include "url/url_canon_internal.h"
 #include "url/url_canon_stdstring.h"
 #include "url/url_parse.h"
@@ -84,26 +83,6 @@
   const char* expected;
 };
 
-// Wrapper around a UConverter object that managers creation and destruction.
-class UConvScoper {
- public:
-  explicit UConvScoper(const char* charset_name) {
-    UErrorCode err = U_ZERO_ERROR;
-    converter_ = ucnv_open(charset_name, &err);
-  }
-
-  ~UConvScoper() {
-    if (converter_)
-      ucnv_close(converter_);
-  }
-
-  // Returns the converter object, may be NULL.
-  UConverter* converter() const { return converter_; }
-
- private:
-  UConverter* converter_;
-};
-
 // Magic string used in the replacements code that tells SetupReplComp to
 // call the clear function.
 const char kDeleteComp[] = "|";
@@ -244,58 +223,6 @@
   }
 }
 
-TEST(URLCanonTest, ICUCharsetConverter) {
-  struct ICUCase {
-    const wchar_t* input;
-    const char* encoding;
-    const char* expected;
-  } icu_cases[] = {
-      // UTF-8.
-    {L"Hello, world", "utf-8", "Hello, world"},
-    {L"\x4f60\x597d", "utf-8", "\xe4\xbd\xa0\xe5\xa5\xbd"},
-      // Non-BMP UTF-8.
-    {L"!\xd800\xdf00!", "utf-8", "!\xf0\x90\x8c\x80!"},
-      // Big5
-    {L"\x4f60\x597d", "big5", "\xa7\x41\xa6\x6e"},
-      // Unrepresentable character in the destination set.
-    {L"hello\x4f60\x06de\x597dworld", "big5", "hello\xa7\x41%26%231758%3B\xa6\x6eworld"},
-  };
-
-  for (size_t i = 0; i < ARRAYSIZE(icu_cases); i++) {
-    UConvScoper conv(icu_cases[i].encoding);
-    ASSERT_TRUE(conv.converter() != NULL);
-    ICUCharsetConverter converter(conv.converter());
-
-    std::string str;
-    StdStringCanonOutput output(&str);
-
-    base::string16 input_str(WStringToUTF16(icu_cases[i].input));
-    int input_len = static_cast<int>(input_str.length());
-    converter.ConvertFromUTF16(input_str.c_str(), input_len, &output);
-    output.Complete();
-
-    EXPECT_STREQ(icu_cases[i].expected, str.c_str());
-  }
-
-  // Test string sizes around the resize boundary for the output to make sure
-  // the converter resizes as needed.
-  const int static_size = 16;
-  UConvScoper conv("utf-8");
-  ASSERT_TRUE(conv.converter());
-  ICUCharsetConverter converter(conv.converter());
-  for (int i = static_size - 2; i <= static_size + 2; i++) {
-    // Make a string with the appropriate length.
-    base::string16 input;
-    for (int ch = 0; ch < i; ch++)
-      input.push_back('a');
-
-    RawCanonOutput<static_size> output;
-    converter.ConvertFromUTF16(input.c_str(), static_cast<int>(input.length()),
-                               &output);
-    EXPECT_EQ(input.length(), static_cast<size_t>(output.length()));
-  }
-}
-
 TEST(URLCanonTest, Scheme) {
   // Here, we're mostly testing that unusual characters are handled properly.
   // The canonicalizer doesn't do any parsing or whitespace detection. It will
@@ -1198,57 +1125,38 @@
   struct QueryCase {
     const char* input8;
     const wchar_t* input16;
-    const char* encoding;
     const char* expected;
   } query_cases[] = {
-      // Regular ASCII case in some different encodings.
-    {"foo=bar", L"foo=bar", NULL, "?foo=bar"},
-    {"foo=bar", L"foo=bar", "utf-8", "?foo=bar"},
-    {"foo=bar", L"foo=bar", "shift_jis", "?foo=bar"},
-    {"foo=bar", L"foo=bar", "gb2312", "?foo=bar"},
+      // Regular ASCII case.
+    {"foo=bar", L"foo=bar", "?foo=bar"},
       // Allow question marks in the query without escaping
-    {"as?df", L"as?df", NULL, "?as?df"},
+    {"as?df", L"as?df", "?as?df"},
       // Always escape '#' since it would mark the ref.
-    {"as#df", L"as#df", NULL, "?as%23df"},
+    {"as#df", L"as#df", "?as%23df"},
       // Escape some questionable 8-bit characters, but never unescape.
-    {"\x02hello\x7f bye", L"\x02hello\x7f bye", NULL, "?%02hello%7F%20bye"},
-    {"%40%41123", L"%40%41123", NULL, "?%40%41123"},
+    {"\x02hello\x7f bye", L"\x02hello\x7f bye", "?%02hello%7F%20bye"},
+    {"%40%41123", L"%40%41123", "?%40%41123"},
       // Chinese input/output
-    {"q=\xe4\xbd\xa0\xe5\xa5\xbd", L"q=\x4f60\x597d", NULL, "?q=%E4%BD%A0%E5%A5%BD"},
-    {"q=\xe4\xbd\xa0\xe5\xa5\xbd", L"q=\x4f60\x597d", "gb2312", "?q=%C4%E3%BA%C3"},
-    {"q=\xe4\xbd\xa0\xe5\xa5\xbd", L"q=\x4f60\x597d", "big5", "?q=%A7A%A6n"},
-      // Unencodable character in the destination character set should be
-      // escaped. The escape sequence unescapes to be the entity name:
-      // "?q=&#20320;"
-    {"q=Chinese\xef\xbc\xa7", L"q=Chinese\xff27", "iso-8859-1", "?q=Chinese%26%2365319%3B"},
+    {"q=\xe4\xbd\xa0\xe5\xa5\xbd", L"q=\x4f60\x597d", "?q=%E4%BD%A0%E5%A5%BD"},
       // Invalid UTF-8/16 input should be replaced with invalid characters.
-    {"q=\xed\xed", L"q=\xd800\xd800", NULL, "?q=%EF%BF%BD%EF%BF%BD"},
+    {"q=\xed\xed", L"q=\xd800\xd800", "?q=%EF%BF%BD%EF%BF%BD"},
       // Don't allow < or > because sometimes they are used for XSS if the
       // URL is echoed in content. Firefox does this, IE doesn't.
-    {"q=<asdf>", L"q=<asdf>", NULL, "?q=%3Casdf%3E"},
+    {"q=<asdf>", L"q=<asdf>", "?q=%3Casdf%3E"},
       // Escape double quotemarks in the query.
-    {"q=\"asdf\"", L"q=\"asdf\"", NULL, "?q=%22asdf%22"},
+    {"q=\"asdf\"", L"q=\"asdf\"", "?q=%22asdf%22"},
   };
 
   for (size_t i = 0; i < ARRAYSIZE(query_cases); i++) {
     Component out_comp;
 
-    UConvScoper conv(query_cases[i].encoding);
-    ASSERT_TRUE(!query_cases[i].encoding || conv.converter());
-    ICUCharsetConverter converter(conv.converter());
-
-    // Map NULL to a NULL converter pointer.
-    ICUCharsetConverter* conv_pointer = &converter;
-    if (!query_cases[i].encoding)
-      conv_pointer = NULL;
-
     if (query_cases[i].input8) {
       int len = static_cast<int>(strlen(query_cases[i].input8));
       Component in_comp(0, len);
       std::string out_str;
 
       StdStringCanonOutput output(&out_str);
-      CanonicalizeQuery(query_cases[i].input8, in_comp, conv_pointer, &output,
+      CanonicalizeQuery(query_cases[i].input8, in_comp, NULL, &output,
                         &out_comp);
       output.Complete();
 
@@ -1262,8 +1170,7 @@
       std::string out_str;
 
       StdStringCanonOutput output(&out_str);
-      CanonicalizeQuery(input16.c_str(), in_comp, conv_pointer, &output,
-                        &out_comp);
+      CanonicalizeQuery(input16.c_str(), in_comp, NULL, &output, &out_comp);
       output.Complete();
 
       EXPECT_EQ(query_cases[i].expected, out_str);
diff --git a/url/url_constants.cc b/url/url_constants.cc
new file mode 100644
index 0000000..7df30da
--- /dev/null
+++ b/url/url_constants.cc
@@ -0,0 +1,12 @@
+// 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.
+
+#include "url/url_constants.h"
+
+namespace url {
+
+const char kHttpScheme[] = "http";
+const char kHttpsScheme[] = "https";
+
+}  // namespace url
diff --git a/url/url_constants.h b/url/url_constants.h
new file mode 100644
index 0000000..9d184d9
--- /dev/null
+++ b/url/url_constants.h
@@ -0,0 +1,17 @@
+// 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.
+
+#ifndef URL_URL_CONSTANTS_H_
+#define URL_URL_CONSTANTS_H_
+
+#include "url/url_export.h"
+
+namespace url {
+
+URL_EXPORT extern const char kHttpScheme[];
+URL_EXPORT extern const char kHttpsScheme[];
+
+}  // namespace url
+
+#endif  // URL_URL_CONSTANTS_H_
diff --git a/url/url_export.h b/url/url_export.h
index 177ec28..15ef19e 100644
--- a/url/url_export.h
+++ b/url/url_export.h
@@ -30,11 +30,4 @@
 
 #endif  // define(COMPONENT_BUILD)
 
-// TODO(vitalybuka, crbug.com/364747) url_util is deprecated, remove after
-// fixing depending code.
-namespace url {}
-namespace url_util = ::url;
-namespace url_parse = ::url;
-namespace url_canon = ::url;
-
 #endif  // URL_URL_EXPORT_H_
diff --git a/url/url_lib.target.darwin-arm.mk b/url/url_lib.target.darwin-arm.mk
index b3d223f..c60f2b1 100644
--- a/url/url_lib.target.darwin-arm.mk
+++ b/url/url_lib.target.darwin-arm.mk
@@ -26,6 +26,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	url/android/url_jni_registrar.cc \
 	url/gurl.cc \
 	url/origin.cc \
 	url/third_party/mozilla/url_parse.cc \
@@ -43,6 +44,7 @@
 	url/url_canon_relative.cc \
 	url/url_canon_stdstring.cc \
 	url/url_canon_stdurl.cc \
+	url/url_constants.cc \
 	url/url_parse_file.cc \
 	url/url_util.cc
 
@@ -61,7 +63,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -153,7 +154,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/url/url_lib.target.darwin-arm64.mk b/url/url_lib.target.darwin-arm64.mk
index 24f88cf..c9cdc94 100644
--- a/url/url_lib.target.darwin-arm64.mk
+++ b/url/url_lib.target.darwin-arm64.mk
@@ -26,6 +26,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	url/android/url_jni_registrar.cc \
 	url/gurl.cc \
 	url/origin.cc \
 	url/third_party/mozilla/url_parse.cc \
@@ -43,6 +44,7 @@
 	url/url_canon_relative.cc \
 	url/url_canon_stdstring.cc \
 	url/url_canon_stdurl.cc \
+	url/url_constants.cc \
 	url/url_parse_file.cc \
 	url/url_util.cc
 
diff --git a/url/url_lib.target.darwin-mips.mk b/url/url_lib.target.darwin-mips.mk
index 5ef016b..39ce5b8 100644
--- a/url/url_lib.target.darwin-mips.mk
+++ b/url/url_lib.target.darwin-mips.mk
@@ -26,6 +26,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	url/android/url_jni_registrar.cc \
 	url/gurl.cc \
 	url/origin.cc \
 	url/third_party/mozilla/url_parse.cc \
@@ -43,6 +44,7 @@
 	url/url_canon_relative.cc \
 	url/url_canon_stdstring.cc \
 	url/url_canon_stdurl.cc \
+	url/url_constants.cc \
 	url/url_parse_file.cc \
 	url/url_util.cc
 
diff --git a/url/url_lib.target.darwin-x86.mk b/url/url_lib.target.darwin-x86.mk
index b91c668..21fe698 100644
--- a/url/url_lib.target.darwin-x86.mk
+++ b/url/url_lib.target.darwin-x86.mk
@@ -26,6 +26,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	url/android/url_jni_registrar.cc \
 	url/gurl.cc \
 	url/origin.cc \
 	url/third_party/mozilla/url_parse.cc \
@@ -43,6 +44,7 @@
 	url/url_canon_relative.cc \
 	url/url_canon_stdstring.cc \
 	url/url_canon_stdurl.cc \
+	url/url_constants.cc \
 	url/url_parse_file.cc \
 	url/url_util.cc
 
@@ -63,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +156,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/url/url_lib.target.darwin-x86_64.mk b/url/url_lib.target.darwin-x86_64.mk
index cca0ff7..17babbd 100644
--- a/url/url_lib.target.darwin-x86_64.mk
+++ b/url/url_lib.target.darwin-x86_64.mk
@@ -26,6 +26,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	url/android/url_jni_registrar.cc \
 	url/gurl.cc \
 	url/origin.cc \
 	url/third_party/mozilla/url_parse.cc \
@@ -43,6 +44,7 @@
 	url/url_canon_relative.cc \
 	url/url_canon_stdstring.cc \
 	url/url_canon_stdurl.cc \
+	url/url_constants.cc \
 	url/url_parse_file.cc \
 	url/url_util.cc
 
@@ -63,7 +65,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +156,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/url/url_lib.target.linux-arm.mk b/url/url_lib.target.linux-arm.mk
index b3d223f..c60f2b1 100644
--- a/url/url_lib.target.linux-arm.mk
+++ b/url/url_lib.target.linux-arm.mk
@@ -26,6 +26,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	url/android/url_jni_registrar.cc \
 	url/gurl.cc \
 	url/origin.cc \
 	url/third_party/mozilla/url_parse.cc \
@@ -43,6 +44,7 @@
 	url/url_canon_relative.cc \
 	url/url_canon_stdstring.cc \
 	url/url_canon_stdurl.cc \
+	url/url_constants.cc \
 	url/url_parse_file.cc \
 	url/url_util.cc
 
@@ -61,7 +63,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -153,7 +154,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/url/url_lib.target.linux-arm64.mk b/url/url_lib.target.linux-arm64.mk
index 24f88cf..c9cdc94 100644
--- a/url/url_lib.target.linux-arm64.mk
+++ b/url/url_lib.target.linux-arm64.mk
@@ -26,6 +26,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	url/android/url_jni_registrar.cc \
 	url/gurl.cc \
 	url/origin.cc \
 	url/third_party/mozilla/url_parse.cc \
@@ -43,6 +44,7 @@
 	url/url_canon_relative.cc \
 	url/url_canon_stdstring.cc \
 	url/url_canon_stdurl.cc \
+	url/url_constants.cc \
 	url/url_parse_file.cc \
 	url/url_util.cc
 
diff --git a/url/url_lib.target.linux-mips.mk b/url/url_lib.target.linux-mips.mk
index 5ef016b..39ce5b8 100644
--- a/url/url_lib.target.linux-mips.mk
+++ b/url/url_lib.target.linux-mips.mk
@@ -26,6 +26,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	url/android/url_jni_registrar.cc \
 	url/gurl.cc \
 	url/origin.cc \
 	url/third_party/mozilla/url_parse.cc \
@@ -43,6 +44,7 @@
 	url/url_canon_relative.cc \
 	url/url_canon_stdstring.cc \
 	url/url_canon_stdurl.cc \
+	url/url_constants.cc \
 	url/url_parse_file.cc \
 	url/url_util.cc
 
diff --git a/url/url_lib.target.linux-x86.mk b/url/url_lib.target.linux-x86.mk
index b91c668..21fe698 100644
--- a/url/url_lib.target.linux-x86.mk
+++ b/url/url_lib.target.linux-x86.mk
@@ -26,6 +26,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	url/android/url_jni_registrar.cc \
 	url/gurl.cc \
 	url/origin.cc \
 	url/third_party/mozilla/url_parse.cc \
@@ -43,6 +44,7 @@
 	url/url_canon_relative.cc \
 	url/url_canon_stdstring.cc \
 	url/url_canon_stdurl.cc \
+	url/url_constants.cc \
 	url/url_parse_file.cc \
 	url/url_util.cc
 
@@ -63,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +156,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/url/url_lib.target.linux-x86_64.mk b/url/url_lib.target.linux-x86_64.mk
index cca0ff7..17babbd 100644
--- a/url/url_lib.target.linux-x86_64.mk
+++ b/url/url_lib.target.linux-x86_64.mk
@@ -26,6 +26,7 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
+	url/android/url_jni_registrar.cc \
 	url/gurl.cc \
 	url/origin.cc \
 	url/third_party/mozilla/url_parse.cc \
@@ -43,6 +44,7 @@
 	url/url_canon_relative.cc \
 	url/url_canon_stdstring.cc \
 	url/url_canon_stdurl.cc \
+	url/url_constants.cc \
 	url/url_parse_file.cc \
 	url/url_util.cc
 
@@ -63,7 +65,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -155,7 +156,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/url/url_srcs.gypi b/url/url_srcs.gypi
index 3114620..61db15d 100644
--- a/url/url_srcs.gypi
+++ b/url/url_srcs.gypi
@@ -5,6 +5,8 @@
 {
   'variables': {
     'gurl_sources': [
+      'android/url_jni_registrar.cc',
+      'android/url_jni_registrar.h',
       'gurl.cc',
       'gurl.h',
       'origin.cc',
@@ -30,6 +32,8 @@
       'url_canon_relative.cc',
       'url_canon_stdstring.cc',
       'url_canon_stdurl.cc',
+      'url_constants.cc',
+      'url_constants.h',
       'url_file.h',
       'url_parse_file.cc',
       'url_parse_internal.h',
diff --git a/webkit/browser/appcache/appcache_response.h b/webkit/browser/appcache/appcache_response.h
index 6829fe6..d9695b3 100644
--- a/webkit/browser/appcache/appcache_response.h
+++ b/webkit/browser/appcache/appcache_response.h
@@ -67,7 +67,7 @@
   HttpResponseInfoIOBuffer();
   explicit HttpResponseInfoIOBuffer(net::HttpResponseInfo* info);
 
- private:
+ protected:
   friend class base::RefCountedThreadSafe<HttpResponseInfoIOBuffer>;
   virtual ~HttpResponseInfoIOBuffer();
 };
@@ -176,7 +176,7 @@
   friend class AppCacheStorageImpl;
   friend class content::MockAppCacheStorage;
 
-  // Should only be constructed by the storage class.
+  // Should only be constructed by the storage class and derivatives.
   AppCacheResponseReader(int64 response_id,
                          int64 group_id,
                          AppCacheDiskCacheInterface* disk_cache);
@@ -230,6 +230,12 @@
   // Returns the amount written, info and data.
   int64 amount_written() { return info_size_ + write_position_; }
 
+ protected:
+  // Should only be constructed by the storage class and derivatives.
+  AppCacheResponseWriter(int64 response_id,
+                         int64 group_id,
+                         AppCacheDiskCacheInterface* disk_cache);
+
  private:
   friend class AppCacheStorageImpl;
   friend class content::MockAppCacheStorage;
@@ -241,11 +247,6 @@
     SECOND_ATTEMPT
   };
 
-  // Should only be constructed by the storage class.
-  AppCacheResponseWriter(int64 response_id,
-                         int64 group_id,
-                         AppCacheDiskCacheInterface* disk_cache);
-
   virtual void OnIOComplete(int result) OVERRIDE;
   void ContinueWriteInfo();
   void ContinueWriteData();
diff --git a/webkit/browser/blob/blob_data_handle.cc b/webkit/browser/blob/blob_data_handle.cc
index fd0ae54..8ccba74 100644
--- a/webkit/browser/blob/blob_data_handle.cc
+++ b/webkit/browser/blob/blob_data_handle.cc
@@ -13,44 +13,56 @@
 
 namespace webkit_blob {
 
-BlobDataHandle::BlobDataHandle(BlobData* blob_data, BlobStorageContext* context,
-                               base::SequencedTaskRunner* task_runner)
+BlobDataHandle::BlobDataHandleShared::BlobDataHandleShared(
+    BlobData* blob_data,
+    BlobStorageContext* context,
+    base::SequencedTaskRunner* task_runner)
     : blob_data_(blob_data),
-      context_(context->AsWeakPtr()),
-      io_task_runner_(task_runner) {
-  // Ensures the uuid remains registered and the underlying data is not deleted.
-  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
+      context_(context->AsWeakPtr()) {
   context_->IncrementBlobRefCount(blob_data->uuid());
-  blob_data_->AddRef();
+}
+
+BlobData* BlobDataHandle::BlobDataHandleShared::data() const {
+  return blob_data_;
+}
+
+const std::string& BlobDataHandle::BlobDataHandleShared::uuid() const {
+  return blob_data_->uuid();
+}
+
+BlobDataHandle::BlobDataHandleShared::~BlobDataHandleShared() {
+  if (context_.get())
+    context_->DecrementBlobRefCount(blob_data_->uuid());
+}
+
+BlobDataHandle::BlobDataHandle(BlobData* blob_data,
+                               BlobStorageContext* context,
+                               base::SequencedTaskRunner* task_runner)
+    : io_task_runner_(task_runner),
+      shared_(new BlobDataHandleShared(blob_data, context, task_runner)) {
+  DCHECK(io_task_runner_);
+  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
+}
+
+BlobDataHandle::BlobDataHandle(const BlobDataHandle& other) {
+  io_task_runner_ = other.io_task_runner_;
+  shared_ = other.shared_;
 }
 
 BlobDataHandle::~BlobDataHandle() {
-  if (io_task_runner_->RunsTasksOnCurrentThread()) {
-    // Note: Do not test context_ or alter the blob_data_ refcount
-    // on the wrong thread.
-    if (context_.get())
-      context_->DecrementBlobRefCount(blob_data_->uuid());
-    blob_data_->Release();
-    return;
-  }
-
-  io_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&DeleteHelper, context_, base::Unretained(blob_data_)));
+  BlobDataHandleShared* raw = shared_.get();
+  raw->AddRef();
+  shared_ = 0;
+  io_task_runner_->ReleaseSoon(FROM_HERE, raw);
 }
 
 BlobData* BlobDataHandle::data() const {
   DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
-  return blob_data_;
+  return shared_->data();
 }
 
-// static
-void BlobDataHandle::DeleteHelper(
-    base::WeakPtr<BlobStorageContext> context,
-    BlobData* blob_data) {
-  if (context.get())
-    context->DecrementBlobRefCount(blob_data->uuid());
-  blob_data->Release();
+std::string BlobDataHandle::uuid() const {
+  return shared_->uuid();
 }
 
 }  // namespace webkit_blob
diff --git a/webkit/browser/blob/blob_data_handle.h b/webkit/browser/blob/blob_data_handle.h
index 5f870f2..917a0b3 100644
--- a/webkit/browser/blob/blob_data_handle.h
+++ b/webkit/browser/blob/blob_data_handle.h
@@ -28,23 +28,42 @@
 class WEBKIT_STORAGE_BROWSER_EXPORT BlobDataHandle
     : public base::SupportsUserData::Data {
  public:
+  BlobDataHandle(const BlobDataHandle& other);  // May be copied on any thread.
   virtual ~BlobDataHandle();  // Maybe be deleted on any thread.
   BlobData* data() const;  // May only be accessed on the IO thread.
 
+  std::string uuid() const;  // May be accessed on any thread.
+
  private:
+  class BlobDataHandleShared
+      : public base::RefCountedThreadSafe<BlobDataHandleShared> {
+   public:
+    BlobDataHandleShared(BlobData* blob_data,
+                         BlobStorageContext* context,
+                         base::SequencedTaskRunner* task_runner);
+
+    BlobData* data() const;
+    const std::string& uuid() const;
+
+   private:
+    friend class base::DeleteHelper<BlobDataHandleShared>;
+    friend class base::RefCountedThreadSafe<BlobDataHandleShared>;
+    friend class BlobDataHandle;
+
+    virtual ~BlobDataHandleShared();
+
+    scoped_refptr<BlobData> blob_data_;
+    base::WeakPtr<BlobStorageContext> context_;
+
+    DISALLOW_COPY_AND_ASSIGN(BlobDataHandleShared);
+  };
+
   friend class BlobStorageContext;
   BlobDataHandle(BlobData* blob_data, BlobStorageContext* context,
                  base::SequencedTaskRunner* task_runner);
 
-  static void DeleteHelper(
-      base::WeakPtr<BlobStorageContext> context,
-      BlobData* blob_data);
-
-  BlobData* blob_data_;  // Intentionally a raw ptr to a non-thread-safe ref.
-  base::WeakPtr<BlobStorageContext> context_;
   scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
-
-  DISALLOW_COPY_AND_ASSIGN(BlobDataHandle);
+  scoped_refptr<BlobDataHandleShared> shared_;
 };
 
 }  // namespace webkit_blob
diff --git a/webkit/browser/blob/blob_storage_context.h b/webkit/browser/blob/blob_storage_context.h
index dda669a..a753c59 100644
--- a/webkit/browser/blob/blob_storage_context.h
+++ b/webkit/browser/blob/blob_storage_context.h
@@ -53,7 +53,7 @@
 
  private:
   friend class content::BlobStorageHost;
-  friend class BlobDataHandle;
+  friend class BlobDataHandle::BlobDataHandleShared;
   friend class ViewBlobInternalsJob;
 
   enum EntryFlags {
diff --git a/webkit/browser/fileapi/file_system_context.cc b/webkit/browser/fileapi/file_system_context.cc
index 5492939..0df0a1d 100644
--- a/webkit/browser/fileapi/file_system_context.cc
+++ b/webkit/browser/fileapi/file_system_context.cc
@@ -479,6 +479,20 @@
   return !is_incognito_ || !FileSystemContext::IsSandboxFileSystem(url.type());
 }
 
+bool FileSystemContext::ShouldFlushOnWriteCompletion(
+    FileSystemType type) const {
+  if (IsSandboxFileSystem(type)) {
+    // Disable Flush() for each write operation on SandboxFileSystems since it
+    // hurts the performance, assuming the FileSystems are stored in a local
+    // disk, we don't need to keep calling fsync() for it.
+    // On the other hand, other FileSystems that may stored on a removable media
+    // should be Flush()ed as soon as a write operation is completed, so that
+    // written data is saved over sudden media removal.
+    return false;
+  }
+  return true;
+}
+
 void FileSystemContext::OpenPluginPrivateFileSystem(
     const GURL& origin_url,
     FileSystemType type,
diff --git a/webkit/browser/fileapi/file_system_context.h b/webkit/browser/fileapi/file_system_context.h
index 6e53981..c51f45d 100644
--- a/webkit/browser/fileapi/file_system_context.h
+++ b/webkit/browser/fileapi/file_system_context.h
@@ -291,6 +291,10 @@
   // (E.g. this returns false if the context is created for incognito mode)
   bool CanServeURLRequest(const FileSystemURL& url) const;
 
+  // Returns true if a file in the file system should be flushed for each write
+  // completion.
+  bool ShouldFlushOnWriteCompletion(FileSystemType type) const;
+
   // This must be used to open 'plugin private' filesystem.
   // See "plugin_private_file_system_backend.h" for more details.
   void OpenPluginPrivateFileSystem(
diff --git a/webkit/browser/fileapi/file_system_operation_runner.cc b/webkit/browser/fileapi/file_system_operation_runner.cc
index aa4c435..4674cf8 100644
--- a/webkit/browser/fileapi/file_system_operation_runner.cc
+++ b/webkit/browser/fileapi/file_system_operation_runner.cc
@@ -260,8 +260,12 @@
     return handle.id;
   }
 
+  FileWriterDelegate::FlushPolicy flush_policy =
+      file_system_context_->ShouldFlushOnWriteCompletion(url.type())
+          ? FileWriterDelegate::FLUSH_ON_COMPLETION
+          : FileWriterDelegate::NO_FLUSH_ON_COMPLETION;
   scoped_ptr<FileWriterDelegate> writer_delegate(
-      new FileWriterDelegate(writer.Pass()));
+      new FileWriterDelegate(writer.Pass(), flush_policy));
 
   scoped_ptr<net::URLRequest> blob_request(
       webkit_blob::BlobProtocolHandler::CreateBlobRequest(
diff --git a/webkit/browser/fileapi/file_writer_delegate.cc b/webkit/browser/fileapi/file_writer_delegate.cc
index c1ec7eb..8311278 100644
--- a/webkit/browser/fileapi/file_writer_delegate.cc
+++ b/webkit/browser/fileapi/file_writer_delegate.cc
@@ -21,9 +21,11 @@
 static const int kReadBufSize = 32768;
 
 FileWriterDelegate::FileWriterDelegate(
-    scoped_ptr<FileStreamWriter> file_stream_writer)
+    scoped_ptr<FileStreamWriter> file_stream_writer,
+    FlushPolicy flush_policy)
     : file_stream_writer_(file_stream_writer.Pass()),
       writing_started_(false),
+      flush_policy_(flush_policy),
       bytes_written_backlog_(0),
       bytes_written_(0),
       bytes_read_(0),
@@ -175,7 +177,7 @@
   }
 
   if (writing_started_)
-    FlushForCompletion(error, 0, ERROR_WRITE_STARTED);
+    MaybeFlushForCompletion(error, 0, ERROR_WRITE_STARTED);
   else
     write_callback_.Run(error, 0, ERROR_WRITE_NOT_STARTED);
 }
@@ -192,8 +194,8 @@
     bytes_written_backlog_ = 0;
 
     if (done) {
-      FlushForCompletion(base::File::FILE_OK, bytes_written,
-                         SUCCESS_COMPLETED);
+      MaybeFlushForCompletion(base::File::FILE_OK, bytes_written,
+                              SUCCESS_COMPLETED);
     } else {
       write_callback_.Run(base::File::FILE_OK, bytes_written,
                           SUCCESS_IO_PENDING);
@@ -208,10 +210,16 @@
                       GetCompletionStatusOnError());
 }
 
-void FileWriterDelegate::FlushForCompletion(
+void FileWriterDelegate::MaybeFlushForCompletion(
     base::File::Error error,
     int bytes_written,
     WriteProgressStatus progress_status) {
+  if (flush_policy_ == NO_FLUSH_ON_COMPLETION) {
+    write_callback_.Run(error, bytes_written, progress_status);
+    return;
+  }
+  DCHECK_EQ(FLUSH_ON_COMPLETION, flush_policy_);
+
   int flush_error = file_stream_writer_->Flush(
       base::Bind(&FileWriterDelegate::OnFlushed, weak_factory_.GetWeakPtr(),
                  error, bytes_written, progress_status));
diff --git a/webkit/browser/fileapi/file_writer_delegate.h b/webkit/browser/fileapi/file_writer_delegate.h
index a5dcb57..c046428 100644
--- a/webkit/browser/fileapi/file_writer_delegate.h
+++ b/webkit/browser/fileapi/file_writer_delegate.h
@@ -22,6 +22,11 @@
 class WEBKIT_STORAGE_BROWSER_EXPORT_PRIVATE FileWriterDelegate
     : public net::URLRequest::Delegate {
  public:
+  enum FlushPolicy {
+    FLUSH_ON_COMPLETION,
+    NO_FLUSH_ON_COMPLETION,
+  };
+
   enum WriteProgressStatus {
     SUCCESS_IO_PENDING,
     SUCCESS_COMPLETED,
@@ -34,7 +39,8 @@
                               WriteProgressStatus write_status)>
       DelegateWriteCallback;
 
-  explicit FileWriterDelegate(scoped_ptr<FileStreamWriter> file_writer);
+  FileWriterDelegate(scoped_ptr<FileStreamWriter> file_writer,
+                     FlushPolicy flush_policy);
   virtual ~FileWriterDelegate();
 
   void Start(scoped_ptr<net::URLRequest> request,
@@ -72,9 +78,9 @@
   void OnError(base::File::Error error);
   void OnProgress(int bytes_read, bool done);
   void OnWriteCancelled(int status);
-  void FlushForCompletion(base::File::Error error,
-                          int bytes_written,
-                          WriteProgressStatus progress_status);
+  void MaybeFlushForCompletion(base::File::Error error,
+                               int bytes_written,
+                               WriteProgressStatus progress_status);
   void OnFlushed(base::File::Error error,
                  int bytes_written,
                  WriteProgressStatus progress_status,
@@ -86,6 +92,7 @@
   scoped_ptr<FileStreamWriter> file_stream_writer_;
   base::Time last_progress_event_time_;
   bool writing_started_;
+  FlushPolicy flush_policy_;
   int bytes_written_backlog_;
   int bytes_written_;
   int bytes_read_;
diff --git a/webkit/browser/fileapi/sandbox_database_test_helper.cc b/webkit/browser/fileapi/sandbox_database_test_helper.cc
deleted file mode 100644
index 0c5ef14..0000000
--- a/webkit/browser/fileapi/sandbox_database_test_helper.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "webkit/browser/fileapi/sandbox_database_test_helper.h"
-
-#include <algorithm>
-#include <functional>
-#include <vector>
-
-#include "base/file_util.h"
-#include "base/files/file.h"
-#include "base/files/file_enumerator.h"
-#include "base/stl_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "webkit/common/fileapi/file_system_util.h"
-
-namespace fileapi {
-
-void CorruptDatabase(const base::FilePath& db_path,
-                     leveldb::FileType type,
-                     ptrdiff_t offset,
-                     size_t size) {
-  base::FileEnumerator file_enum(db_path, false /* not recursive */,
-      base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES);
-  base::FilePath file_path;
-  base::FilePath picked_file_path;
-  uint64 picked_file_number = kuint64max;
-
-  while (!(file_path = file_enum.Next()).empty()) {
-    uint64 number = kuint64max;
-    leveldb::FileType file_type;
-    EXPECT_TRUE(leveldb::ParseFileName(FilePathToString(file_path.BaseName()),
-                                       &number, &file_type));
-    if (file_type == type &&
-        (picked_file_number == kuint64max || picked_file_number < number)) {
-      picked_file_path = file_path;
-      picked_file_number = number;
-    }
-  }
-
-  EXPECT_FALSE(picked_file_path.empty());
-  EXPECT_NE(kuint64max, picked_file_number);
-
-  base::File file(picked_file_path,
-                  base::File::FLAG_OPEN | base::File::FLAG_READ |
-                      base::File::FLAG_WRITE);
-  ASSERT_TRUE(file.IsValid());
-  EXPECT_FALSE(file.created());
-
-  base::File::Info file_info;
-  EXPECT_TRUE(file.GetInfo(&file_info));
-  if (offset < 0)
-    offset += file_info.size;
-  EXPECT_GE(offset, 0);
-  EXPECT_LE(offset, file_info.size);
-
-  size = std::min(size, static_cast<size_t>(file_info.size - offset));
-
-  std::vector<char> buf(size);
-  int read_size = file.Read(offset, vector_as_array(&buf), buf.size());
-  EXPECT_LT(0, read_size);
-  EXPECT_GE(buf.size(), static_cast<size_t>(read_size));
-  buf.resize(read_size);
-
-  std::transform(buf.begin(), buf.end(), buf.begin(),
-                 std::logical_not<char>());
-
-  int written_size = file.Write(offset, vector_as_array(&buf), buf.size());
-  EXPECT_GT(written_size, 0);
-  EXPECT_EQ(buf.size(), static_cast<size_t>(written_size));
-}
-
-void DeleteDatabaseFile(const base::FilePath& db_path,
-                        leveldb::FileType type) {
-  base::FileEnumerator file_enum(db_path, false /* not recursive */,
-      base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES);
-  base::FilePath file_path;
-  while (!(file_path = file_enum.Next()).empty()) {
-    uint64 number = kuint64max;
-    leveldb::FileType file_type;
-    EXPECT_TRUE(leveldb::ParseFileName(FilePathToString(file_path.BaseName()),
-                                       &number, &file_type));
-    if (file_type == type) {
-      base::DeleteFile(file_path, false);
-      // We may have multiple files for the same type, so don't break here.
-    }
-  }
-}
-
-}  // namespace fileapi
diff --git a/webkit/browser/fileapi/sandbox_database_test_helper.h b/webkit/browser/fileapi/sandbox_database_test_helper.h
deleted file mode 100644
index 1635c2f..0000000
--- a/webkit/browser/fileapi/sandbox_database_test_helper.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef WEBKIT_BROWSER_FILEAPI_SANDBOX_DATABASE_TEST_HELPER_H_
-#define WEBKIT_BROWSER_FILEAPI_SANDBOX_DATABASE_TEST_HELPER_H_
-
-#include <cstddef>
-
-#include "third_party/leveldatabase/src/db/filename.h"
-
-namespace base {
-class FilePath;
-}
-
-namespace fileapi {
-
-void CorruptDatabase(const base::FilePath& db_path,
-                     leveldb::FileType type,
-                     ptrdiff_t offset,
-                     size_t size);
-
-void DeleteDatabaseFile(const base::FilePath& db_path,
-                        leveldb::FileType type);
-
-}  // namespace fileapi
-
-#endif  // WEBKIT_BROWSER_FILEAPI_SANDBOX_DATABASE_TEST_HELPER_H_
diff --git a/webkit/child/overscroller_jni_headers.target.darwin-arm.mk b/webkit/child/overscroller_jni_headers.target.darwin-arm.mk
index 9071a3a..4fa9ce6 100644
--- a/webkit/child/overscroller_jni_headers.target.darwin-arm.mk
+++ b/webkit/child/overscroller_jni_headers.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/webkit/child/overscroller_jni_headers.target.darwin-arm64.mk b/webkit/child/overscroller_jni_headers.target.darwin-arm64.mk
index 2ff0d92..b53855b 100644
--- a/webkit/child/overscroller_jni_headers.target.darwin-arm64.mk
+++ b/webkit/child/overscroller_jni_headers.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/child/overscroller_jni_headers.target.darwin-mips.mk b/webkit/child/overscroller_jni_headers.target.darwin-mips.mk
index a6c01d1..07a8e75 100644
--- a/webkit/child/overscroller_jni_headers.target.darwin-mips.mk
+++ b/webkit/child/overscroller_jni_headers.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/child/overscroller_jni_headers.target.darwin-x86.mk b/webkit/child/overscroller_jni_headers.target.darwin-x86.mk
index 5aa4cf0..9e4c22f 100644
--- a/webkit/child/overscroller_jni_headers.target.darwin-x86.mk
+++ b/webkit/child/overscroller_jni_headers.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/webkit/child/overscroller_jni_headers.target.darwin-x86_64.mk b/webkit/child/overscroller_jni_headers.target.darwin-x86_64.mk
index 8e1288b..5d79116 100644
--- a/webkit/child/overscroller_jni_headers.target.darwin-x86_64.mk
+++ b/webkit/child/overscroller_jni_headers.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/webkit/child/overscroller_jni_headers.target.linux-arm.mk b/webkit/child/overscroller_jni_headers.target.linux-arm.mk
index 9071a3a..4fa9ce6 100644
--- a/webkit/child/overscroller_jni_headers.target.linux-arm.mk
+++ b/webkit/child/overscroller_jni_headers.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -53,7 +54,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -137,7 +137,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/webkit/child/overscroller_jni_headers.target.linux-arm64.mk b/webkit/child/overscroller_jni_headers.target.linux-arm64.mk
index 2ff0d92..b53855b 100644
--- a/webkit/child/overscroller_jni_headers.target.linux-arm64.mk
+++ b/webkit/child/overscroller_jni_headers.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/child/overscroller_jni_headers.target.linux-mips.mk b/webkit/child/overscroller_jni_headers.target.linux-mips.mk
index a6c01d1..07a8e75 100644
--- a/webkit/child/overscroller_jni_headers.target.linux-mips.mk
+++ b/webkit/child/overscroller_jni_headers.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/child/overscroller_jni_headers.target.linux-x86.mk b/webkit/child/overscroller_jni_headers.target.linux-x86.mk
index 5aa4cf0..9e4c22f 100644
--- a/webkit/child/overscroller_jni_headers.target.linux-x86.mk
+++ b/webkit/child/overscroller_jni_headers.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/webkit/child/overscroller_jni_headers.target.linux-x86_64.mk b/webkit/child/overscroller_jni_headers.target.linux-x86_64.mk
index 8e1288b..5d79116 100644
--- a/webkit/child/overscroller_jni_headers.target.linux-x86_64.mk
+++ b/webkit/child/overscroller_jni_headers.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "generate_jni_headers_from_jar_file":
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/jni/OverScroller_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
@@ -55,7 +56,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -139,7 +139,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/webkit/child/resource_loader_bridge.cc b/webkit/child/resource_loader_bridge.cc
index 41acf98..3303c4d 100644
--- a/webkit/child/resource_loader_bridge.cc
+++ b/webkit/child/resource_loader_bridge.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
diff --git a/webkit/child/resource_loader_bridge.h b/webkit/child/resource_loader_bridge.h
index 51cdf5f..9b97aa3 100644
--- a/webkit/child/resource_loader_bridge.h
+++ b/webkit/child/resource_loader_bridge.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 //
diff --git a/webkit/child/webkit_child.target.darwin-arm.mk b/webkit/child/webkit_child.target.darwin-arm.mk
index 1127ec0..bd426ae 100644
--- a/webkit/child/webkit_child.target.darwin-arm.mk
+++ b/webkit/child/webkit_child.target.darwin-arm.mk
@@ -48,7 +48,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -98,11 +97,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -193,7 +187,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -243,11 +236,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/child/webkit_child.target.darwin-arm64.mk b/webkit/child/webkit_child.target.darwin-arm64.mk
index e4347a3..a39d2f7 100644
--- a/webkit/child/webkit_child.target.darwin-arm64.mk
+++ b/webkit/child/webkit_child.target.darwin-arm64.mk
@@ -94,11 +94,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -234,11 +229,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/child/webkit_child.target.darwin-mips.mk b/webkit/child/webkit_child.target.darwin-mips.mk
index 68f5002..bfb2d43 100644
--- a/webkit/child/webkit_child.target.darwin-mips.mk
+++ b/webkit/child/webkit_child.target.darwin-mips.mk
@@ -97,11 +97,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -241,11 +236,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/child/webkit_child.target.darwin-x86.mk b/webkit/child/webkit_child.target.darwin-x86.mk
index cd04ada..89e11a3 100644
--- a/webkit/child/webkit_child.target.darwin-x86.mk
+++ b/webkit/child/webkit_child.target.darwin-x86.mk
@@ -50,7 +50,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -98,11 +97,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -194,7 +188,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -242,11 +235,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/child/webkit_child.target.darwin-x86_64.mk b/webkit/child/webkit_child.target.darwin-x86_64.mk
index 8a21d87..e8998c5 100644
--- a/webkit/child/webkit_child.target.darwin-x86_64.mk
+++ b/webkit/child/webkit_child.target.darwin-x86_64.mk
@@ -50,7 +50,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -195,7 +189,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -244,11 +237,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/child/webkit_child.target.linux-arm.mk b/webkit/child/webkit_child.target.linux-arm.mk
index 1127ec0..bd426ae 100644
--- a/webkit/child/webkit_child.target.linux-arm.mk
+++ b/webkit/child/webkit_child.target.linux-arm.mk
@@ -48,7 +48,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -98,11 +97,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -193,7 +187,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -243,11 +236,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/child/webkit_child.target.linux-arm64.mk b/webkit/child/webkit_child.target.linux-arm64.mk
index e4347a3..a39d2f7 100644
--- a/webkit/child/webkit_child.target.linux-arm64.mk
+++ b/webkit/child/webkit_child.target.linux-arm64.mk
@@ -94,11 +94,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -234,11 +229,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/child/webkit_child.target.linux-mips.mk b/webkit/child/webkit_child.target.linux-mips.mk
index 68f5002..bfb2d43 100644
--- a/webkit/child/webkit_child.target.linux-mips.mk
+++ b/webkit/child/webkit_child.target.linux-mips.mk
@@ -97,11 +97,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -241,11 +236,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/child/webkit_child.target.linux-x86.mk b/webkit/child/webkit_child.target.linux-x86.mk
index cd04ada..89e11a3 100644
--- a/webkit/child/webkit_child.target.linux-x86.mk
+++ b/webkit/child/webkit_child.target.linux-x86.mk
@@ -50,7 +50,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -98,11 +97,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -194,7 +188,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -242,11 +235,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/child/webkit_child.target.linux-x86_64.mk b/webkit/child/webkit_child.target.linux-x86_64.mk
index 8a21d87..e8998c5 100644
--- a/webkit/child/webkit_child.target.linux-x86_64.mk
+++ b/webkit/child/webkit_child.target.linux-x86_64.mk
@@ -50,7 +50,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -195,7 +189,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -244,11 +237,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/database/database_identifier.cc b/webkit/common/database/database_identifier.cc
index 332dfb8..c4649d2 100644
--- a/webkit/common/database/database_identifier.cc
+++ b/webkit/common/database/database_identifier.cc
@@ -39,12 +39,12 @@
     return UniqueFileIdentifier();
 
   int port = origin.IntPort();
-  if (port == url_parse::PORT_INVALID)
+  if (port == url::PORT_INVALID)
     return DatabaseIdentifier();
 
   // We encode the default port for the specified scheme as 0. GURL
   // canonicalizes this as an unspecified port.
-  if (port == url_parse::PORT_UNSPECIFIED)
+  if (port == url::PORT_UNSPECIFIED)
     port = 0;
 
   return DatabaseIdentifier(origin.scheme(),
@@ -56,7 +56,7 @@
 
 // static
 DatabaseIdentifier DatabaseIdentifier::Parse(const std::string& identifier) {
-  if (!IsStringASCII(identifier))
+  if (!base::IsStringASCII(identifier))
     return DatabaseIdentifier();
 
   size_t first_underscore = identifier.find_first_of('_');
diff --git a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
index 992bcb4..8e3259b 100644
--- a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
+++ b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc
@@ -293,13 +293,6 @@
   gl_->glname(a1, a2, a3);                                              \
 }
 
-#define DELEGATE_TO_GL_3R(name, glname, t1, t2, t3, rt)                 \
-rt WebGraphicsContext3DInProcessCommandBufferImpl::name(                \
-    t1 a1, t2 a2, t3 a3) {                                              \
-  ClearContext();                                                       \
-  return gl_->glname(a1, a2, a3);                                       \
-}
-
 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4)                  \
 void WebGraphicsContext3DInProcessCommandBufferImpl::name(              \
     t1 a1, t2 a2, t3 a3, t4 a4) {                                       \
@@ -307,6 +300,13 @@
   gl_->glname(a1, a2, a3, a4);                                          \
 }
 
+#define DELEGATE_TO_GL_4R(name, glname, t1, t2, t3, t4, rt) \
+  rt WebGraphicsContext3DInProcessCommandBufferImpl::name(  \
+      t1 a1, t2 a2, t3 a3, t4 a4) {                         \
+    ClearContext();                                         \
+    return gl_->glname(a1, a2, a3, a4);                     \
+  }
+
 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5)              \
 void WebGraphicsContext3DInProcessCommandBufferImpl::name(              \
     t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) {                                \
@@ -1138,16 +1138,36 @@
   }
 }
 
-DELEGATE_TO_GL_3R(createImageCHROMIUM, CreateImageCHROMIUM,
-                  WGC3Dsizei, WGC3Dsizei, WGC3Denum, WGC3Duint);
+DELEGATE_TO_GL_4R(createImageCHROMIUM,
+                  CreateImageCHROMIUM,
+                  WGC3Dsizei,
+                  WGC3Dsizei,
+                  WGC3Denum,
+                  WGC3Denum,
+                  WGC3Duint);
+
+WGC3Duint WebGraphicsContext3DInProcessCommandBufferImpl::createImageCHROMIUM(
+    WGC3Dsizei width,
+    WGC3Dsizei height,
+    WGC3Denum internalformat) {
+  ClearContext();
+  return gl_->CreateImageCHROMIUM(
+      width, height, internalformat, GL_IMAGE_MAP_CHROMIUM);
+}
 
 DELEGATE_TO_GL_1(destroyImageCHROMIUM, DestroyImageCHROMIUM, WGC3Duint);
 
 DELEGATE_TO_GL_3(getImageParameterivCHROMIUM, GetImageParameterivCHROMIUM,
                  WGC3Duint, WGC3Denum, GLint*);
 
-DELEGATE_TO_GL_2R(mapImageCHROMIUM, MapImageCHROMIUM,
-                  WGC3Duint, WGC3Denum, void*);
+DELEGATE_TO_GL_1R(mapImageCHROMIUM, MapImageCHROMIUM, WGC3Duint, void*);
+
+void* WebGraphicsContext3DInProcessCommandBufferImpl::mapImageCHROMIUM(
+    WGC3Duint image_id,
+    WGC3Denum access) {
+  ClearContext();
+  return gl_->MapImageCHROMIUM(image_id);
+}
 
 DELEGATE_TO_GL_1(unmapImageCHROMIUM, UnmapImageCHROMIUM, WGC3Duint);
 
diff --git a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
index 0e4348d..429ece9 100644
--- a/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
+++ b/webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h
@@ -477,12 +477,19 @@
   virtual void texStorage2DEXT(
       WGC3Denum target, WGC3Dint levels, WGC3Duint internalformat,
       WGC3Dint width, WGC3Dint height);
+  // TODO(alexst): remove this old function after blink cleanup.
   virtual WGC3Duint createImageCHROMIUM(
       WGC3Dsizei width, WGC3Dsizei height, WGC3Denum internalformat);
+  virtual WGC3Duint createImageCHROMIUM(WGC3Dsizei width,
+                                        WGC3Dsizei height,
+                                        WGC3Denum internalformat,
+                                        WGC3Denum usage);
   virtual void destroyImageCHROMIUM(WGC3Duint image_id);
   virtual void getImageParameterivCHROMIUM(
       WGC3Duint image_id, WGC3Denum pname, WGC3Dint* params);
+  // TODO(alexst): remove this old function after blink cleanup.
   virtual void* mapImageCHROMIUM(WGC3Duint image_id, WGC3Denum access);
+  virtual void* mapImageCHROMIUM(WGC3Duint image_id);
   virtual void unmapImageCHROMIUM(WGC3Duint image_id);
   virtual WebGLId createQueryEXT();
   virtual void deleteQueryEXT(WebGLId query);
diff --git a/webkit/common/gpu/webkit_gpu.target.darwin-arm.mk b/webkit/common/gpu/webkit_gpu.target.darwin-arm.mk
index 2470d88..57008ad 100644
--- a/webkit/common/gpu/webkit_gpu.target.darwin-arm.mk
+++ b/webkit/common/gpu/webkit_gpu.target.darwin-arm.mk
@@ -46,7 +46,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -231,11 +224,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/gpu/webkit_gpu.target.darwin-arm64.mk b/webkit/common/gpu/webkit_gpu.target.darwin-arm64.mk
index 6361072..061d1dc 100644
--- a/webkit/common/gpu/webkit_gpu.target.darwin-arm64.mk
+++ b/webkit/common/gpu/webkit_gpu.target.darwin-arm64.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -222,11 +217,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/gpu/webkit_gpu.target.darwin-mips.mk b/webkit/common/gpu/webkit_gpu.target.darwin-mips.mk
index cce4962..ad25bfb 100644
--- a/webkit/common/gpu/webkit_gpu.target.darwin-mips.mk
+++ b/webkit/common/gpu/webkit_gpu.target.darwin-mips.mk
@@ -99,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -231,11 +226,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/gpu/webkit_gpu.target.darwin-x86.mk b/webkit/common/gpu/webkit_gpu.target.darwin-x86.mk
index b7f9251..71d9c6c 100644
--- a/webkit/common/gpu/webkit_gpu.target.darwin-x86.mk
+++ b/webkit/common/gpu/webkit_gpu.target.darwin-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -180,7 +174,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -232,11 +225,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/gpu/webkit_gpu.target.darwin-x86_64.mk b/webkit/common/gpu/webkit_gpu.target.darwin-x86_64.mk
index 51fcb9b..e4bffc9 100644
--- a/webkit/common/gpu/webkit_gpu.target.darwin-x86_64.mk
+++ b/webkit/common/gpu/webkit_gpu.target.darwin-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -180,7 +174,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -232,11 +225,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/gpu/webkit_gpu.target.linux-arm.mk b/webkit/common/gpu/webkit_gpu.target.linux-arm.mk
index 2470d88..57008ad 100644
--- a/webkit/common/gpu/webkit_gpu.target.linux-arm.mk
+++ b/webkit/common/gpu/webkit_gpu.target.linux-arm.mk
@@ -46,7 +46,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -99,11 +98,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -178,7 +172,6 @@
 	-fPIC \
 	-Wno-format \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -231,11 +224,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/gpu/webkit_gpu.target.linux-arm64.mk b/webkit/common/gpu/webkit_gpu.target.linux-arm64.mk
index 6361072..061d1dc 100644
--- a/webkit/common/gpu/webkit_gpu.target.linux-arm64.mk
+++ b/webkit/common/gpu/webkit_gpu.target.linux-arm64.mk
@@ -95,11 +95,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -222,11 +217,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/gpu/webkit_gpu.target.linux-mips.mk b/webkit/common/gpu/webkit_gpu.target.linux-mips.mk
index cce4962..ad25bfb 100644
--- a/webkit/common/gpu/webkit_gpu.target.linux-mips.mk
+++ b/webkit/common/gpu/webkit_gpu.target.linux-mips.mk
@@ -99,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -231,11 +226,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/gpu/webkit_gpu.target.linux-x86.mk b/webkit/common/gpu/webkit_gpu.target.linux-x86.mk
index b7f9251..71d9c6c 100644
--- a/webkit/common/gpu/webkit_gpu.target.linux-x86.mk
+++ b/webkit/common/gpu/webkit_gpu.target.linux-x86.mk
@@ -48,7 +48,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -180,7 +174,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -232,11 +225,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/gpu/webkit_gpu.target.linux-x86_64.mk b/webkit/common/gpu/webkit_gpu.target.linux-x86_64.mk
index 51fcb9b..e4bffc9 100644
--- a/webkit/common/gpu/webkit_gpu.target.linux-x86_64.mk
+++ b/webkit/common/gpu/webkit_gpu.target.linux-x86_64.mk
@@ -48,7 +48,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -100,11 +99,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -180,7 +174,6 @@
 	-Wno-format \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -232,11 +225,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/webkit_common.target.darwin-arm.mk b/webkit/common/webkit_common.target.darwin-arm.mk
index d8ba371..cc2fc35 100644
--- a/webkit/common/webkit_common.target.darwin-arm.mk
+++ b/webkit/common/webkit_common.target.darwin-arm.mk
@@ -51,7 +51,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -181,7 +175,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -231,11 +224,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/webkit_common.target.darwin-arm64.mk b/webkit/common/webkit_common.target.darwin-arm64.mk
index d4c70df..9c54ca2 100644
--- a/webkit/common/webkit_common.target.darwin-arm64.mk
+++ b/webkit/common/webkit_common.target.darwin-arm64.mk
@@ -97,11 +97,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -222,11 +217,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/webkit_common.target.darwin-mips.mk b/webkit/common/webkit_common.target.darwin-mips.mk
index ebd4978..d19a8f7 100644
--- a/webkit/common/webkit_common.target.darwin-mips.mk
+++ b/webkit/common/webkit_common.target.darwin-mips.mk
@@ -100,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -229,11 +224,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/webkit_common.target.darwin-x86.mk b/webkit/common/webkit_common.target.darwin-x86.mk
index 0a912fe..81a7a0e 100644
--- a/webkit/common/webkit_common.target.darwin-x86.mk
+++ b/webkit/common/webkit_common.target.darwin-x86.mk
@@ -53,7 +53,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -182,7 +176,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/webkit_common.target.darwin-x86_64.mk b/webkit/common/webkit_common.target.darwin-x86_64.mk
index b395315..6a791fc 100644
--- a/webkit/common/webkit_common.target.darwin-x86_64.mk
+++ b/webkit/common/webkit_common.target.darwin-x86_64.mk
@@ -53,7 +53,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -102,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -183,7 +177,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -232,11 +225,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/webkit_common.target.linux-arm.mk b/webkit/common/webkit_common.target.linux-arm.mk
index d8ba371..cc2fc35 100644
--- a/webkit/common/webkit_common.target.linux-arm.mk
+++ b/webkit/common/webkit_common.target.linux-arm.mk
@@ -51,7 +51,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -181,7 +175,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -231,11 +224,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/webkit_common.target.linux-arm64.mk b/webkit/common/webkit_common.target.linux-arm64.mk
index d4c70df..9c54ca2 100644
--- a/webkit/common/webkit_common.target.linux-arm64.mk
+++ b/webkit/common/webkit_common.target.linux-arm64.mk
@@ -97,11 +97,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -222,11 +217,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/webkit_common.target.linux-mips.mk b/webkit/common/webkit_common.target.linux-mips.mk
index ebd4978..d19a8f7 100644
--- a/webkit/common/webkit_common.target.linux-mips.mk
+++ b/webkit/common/webkit_common.target.linux-mips.mk
@@ -100,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -229,11 +224,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/webkit_common.target.linux-x86.mk b/webkit/common/webkit_common.target.linux-x86.mk
index 0a912fe..81a7a0e 100644
--- a/webkit/common/webkit_common.target.linux-x86.mk
+++ b/webkit/common/webkit_common.target.linux-x86.mk
@@ -53,7 +53,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -101,11 +100,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -182,7 +176,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -230,11 +223,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/common/webkit_common.target.linux-x86_64.mk b/webkit/common/webkit_common.target.linux-x86_64.mk
index b395315..6a791fc 100644
--- a/webkit/common/webkit_common.target.linux-x86_64.mk
+++ b/webkit/common/webkit_common.target.linux-x86_64.mk
@@ -53,7 +53,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -102,11 +101,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -183,7 +177,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -232,11 +225,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/glue/resources/default_100_percent/input_speech.png b/webkit/glue/resources/default_100_percent/input_speech.png
deleted file mode 100644
index 16a73a1..0000000
--- a/webkit/glue/resources/default_100_percent/input_speech.png
+++ /dev/null
Binary files differ
diff --git a/webkit/glue/resources/default_100_percent/input_speech_recording.png b/webkit/glue/resources/default_100_percent/input_speech_recording.png
deleted file mode 100644
index 7d3931d..0000000
--- a/webkit/glue/resources/default_100_percent/input_speech_recording.png
+++ /dev/null
Binary files differ
diff --git a/webkit/glue/resources/default_100_percent/input_speech_waiting.png b/webkit/glue/resources/default_100_percent/input_speech_waiting.png
deleted file mode 100644
index 5665f46..0000000
--- a/webkit/glue/resources/default_100_percent/input_speech_waiting.png
+++ /dev/null
Binary files differ
diff --git a/webkit/glue/resources/webkit_resources.grd b/webkit/glue/resources/webkit_resources.grd
index 547ac5f..42654c5 100644
--- a/webkit/glue/resources/webkit_resources.grd
+++ b/webkit/glue/resources/webkit_resources.grd
@@ -10,9 +10,6 @@
   <release seq="1">
     <structures fallback_to_low_resolution="true">
       <structure type="chrome_scaled_image" name="IDR_BROKENIMAGE" file="broken_image.png" />
-      <structure type="chrome_scaled_image" name="IDR_INPUT_SPEECH" file="input_speech.png" />
-      <structure type="chrome_scaled_image" name="IDR_INPUT_SPEECH_RECORDING" file="input_speech_recording.png" />
-      <structure type="chrome_scaled_image" name="IDR_INPUT_SPEECH_WAITING" file="input_speech_waiting.png" />
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_PAUSE_BUTTON" file="mediaplayer_pause.png" />
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_PAUSE_BUTTON_HOVER" file="mediaplayer_pause_hover.png" />
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_PAUSE_BUTTON_DOWN" file="mediaplayer_pause_down.png" />
diff --git a/webkit/glue/resources/webkit_strings_am.xtb b/webkit/glue/resources/webkit_strings_am.xtb
index c405105..1eeb8d5 100644
--- a/webkit/glue/resources/webkit_strings_am.xtb
+++ b/webkit/glue/resources/webkit_strings_am.xtb
@@ -49,7 +49,7 @@
 <translation id="9050748414552849310">የተዘጉ የስዕል መግለጫዎችን አሳይ</translation>
 <translation id="4522570452068850558">ዝርዝሮች</translation>
 <translation id="8451268428117625855">እባክዎ ፋይል ይምረጡ።</translation>
-<translation id="8117451130807776954">በዚህ ሣምንት</translation>
+<translation id="8117451130807776954">በዚህ ሳምንት</translation>
 <translation id="5966707198760109579">ሳምንት</translation>
 <translation id="2901282870647571346">የአሁኑ የፊልም ሁኔታ</translation>
 <translation id="2060505056492490888">«<ph name="DOT"/>» በ«<ph name="INVALIDDOMAIN"/>» ውስጥ በተሳሳተ ቦታ ላይ ነው የገባው።</translation>
diff --git a/webkit/glue/resources/webkit_strings_el.xtb b/webkit/glue/resources/webkit_strings_el.xtb
index c40da89..3c7a0c4 100644
--- a/webkit/glue/resources/webkit_strings_el.xtb
+++ b/webkit/glue/resources/webkit_strings_el.xtb
@@ -20,7 +20,7 @@
 <translation id="8785498733064193001">έναρξη αναπαραγωγής</translation>
 <translation id="7057186640035488495">χρόνος ταινίας</translation>
 <translation id="8199524924445686405">εεεε</translation>
-<translation id="795667975304826397">Δεν έχει επιλεγεί κανένα αρχείο</translation>
+<translation id="795667975304826397">Δεν επιλέχθηκε κανένα αρχείο.</translation>
 <translation id="7789962463072032349">παύση</translation>
 <translation id="6853785296079745596">απόκρυψη υπότιτλων</translation>
 <translation id="4360991593054037559">Καταχωρίστε μια έγκυρη τιμή. Οι δύο πιο κοντινές έγκυρες τιμές είναι <ph name="VALID_VALUE_LOW"/> και <ph name="VALID_VALUE_HIGHER"/>.</translation>
diff --git a/webkit/glue/resources/webkit_strings_sr.xtb b/webkit/glue/resources/webkit_strings_sr.xtb
index 0c22b56..ec4a31e 100644
--- a/webkit/glue/resources/webkit_strings_sr.xtb
+++ b/webkit/glue/resources/webkit_strings_sr.xtb
@@ -4,12 +4,12 @@
 <translation id="4763480195061959176">видео</translation>
 <translation id="5843503607508392247">Друго...</translation>
 <translation id="248395913932153421">Дан</translation>
-<translation id="1729654308190250600">Унесите адресу е-поште која није празна.</translation>
+<translation id="1729654308190250600">Унесите имејл адресу која није празна.</translation>
 <translation id="6015796118275082299">Година</translation>
 <translation id="9186171386827445984">Учитавање документа: <ph name="PAGE_NUMBER"/>/<ph name="NUMBER_OF_PAGES"/> странице(а)...</translation>
 <translation id="1235745349614807883">Обриши недавне претраге</translation>
 <translation id="7223624360433298498">протекло време</translation>
-<translation id="1171774979989969504">Унесите адресу е-поште.</translation>
+<translation id="1171774979989969504">Унесите имејл адресу.</translation>
 <translation id="709897737746224366">Изаберите захтевани формат.</translation>
 <translation id="5048533449481078685">означивач листе</translation>
 <translation id="4202807286478387388">прескочи</translation>
@@ -89,7 +89,7 @@
 <translation id="6101327004457443354">укључите звук аудио снимка</translation>
 <translation id="1822429046913737220">пре подне/по подне</translation>
 <translation id="1639239467298939599">Учитавање</translation>
-<translation id="2908441821576996758">Унесите листу адреса е-поште раздвојених зарезима.</translation>
+<translation id="2908441821576996758">Унесите листу имејл адреса раздвојених зарезима.</translation>
 <translation id="5939518447894949180">Ресетуј</translation>
 <translation id="1921819250265091946">дд</translation>
 <translation id="2613802280814924224">Унесите важећу вредност. Најближа важећа вредност је <ph name="VALID_VALUE"/>.</translation>
@@ -105,7 +105,7 @@
 <translation id="6119846243427417423">активирај</translation>
 <translation id="8444882422881193423"><ph name="NUMBER_OF_FILES"/> датотеке(а)</translation>
 <translation id="6643016212128521049">Обриши</translation>
-<translation id="7888071071722539607">Уврстите „<ph name="ATSIGN"/>“ у адресу е-поште. У адреси е-поште „<ph name="INVALIDADDRESS"/>“ недостаје „<ph name="ATSIGN"/>“.</translation>
+<translation id="7888071071722539607">Уврстите „<ph name="ATSIGN"/>“ у имејл адресу. У адреси е-поште „<ph name="INVALIDADDRESS"/>“ недостаје „<ph name="ATSIGN"/>“.</translation>
 <translation id="1088086359088493902">Секунде</translation>
 <translation id="3934680773876859118">Учитавање PDF документа није успело</translation>
 <translation id="3632707345189162177">број преосталих секунди филма</translation>
diff --git a/webkit/glue/webkit_strings.grd b/webkit/glue/webkit_strings.grd
index 37efcad..2ee843c 100644
--- a/webkit/glue/webkit_strings.grd
+++ b/webkit/glue/webkit_strings.grd
@@ -30,7 +30,7 @@
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 -->
 
@@ -272,9 +272,6 @@
       <message name="IDS_FORM_FILE_NO_FILE_LABEL" desc="text to display in file button used in HTML forms when no file is selected">
         No file chosen
       </message>
-      <message name="IDS_FORM_FILE_NO_FILE_DRAG_LABEL" desc="text to display in file button used in HTML forms when no file is selected to indicate that files can be dragged onto the file button">
-        Drag file here
-      </message>
       <message name="IDS_FORM_FILE_MULTIPLE_UPLOAD" desc="text to display next to file buttons in HTML forms when 2 or more files are selected for uploading. This is not used for a case that just 1 file is selected.">
         <ph name="NUMBER_OF_FILES">$1<ex>3</ex></ph> files
       </message>
@@ -322,10 +319,6 @@
         Clear Recent Searches
       </message>
 
-      <message name="IDS_IMAGE_TITLE_FOR_FILENAME" desc="window title for a standalone image (uses mutiplication symbol, not x)">
-        <ph name="FILENAME">%s<ex>My Cool Image.gif</ex></ph><ph name="WIDTH">%d<ex>400</ex></ph>×<ph name="HEIGHT">%d<ex>600</ex></ph>
-      </message>
-
       <message name="IDS_AX_ROLE_WEB_AREA" desc="accessibility role description for web area">
         HTML content
       </message>
@@ -341,15 +334,17 @@
       <message name="IDS_AX_ROLE_HEADING" desc="accessibility role description for headings">
         heading
       </message>
-      <message name="IDS_AX_ROLE_FOOTER" desc="accessibility role description for footers">
-        footer
-      </message>
-      <message name="IDS_AX_ROLE_STEPPER" desc="accessibility role description for a stepper - a control where you can use up/down arrows to increment or decrement it. The name 'stepper' is how this user interface element is described by VoiceOver on Mac OS X; the translation should be consistent with VoiceOver.">
-        stepper
-      </message>
-      <message name="IDS_AX_ROLE_TOGGLE_BUTTON" desc="accessibility role description for a toggle button">
-        toggle button
-      </message>
+      <if expr="is_macosx">
+        <message name="IDS_AX_ROLE_FOOTER" desc="accessibility role description for footers">
+          footer
+        </message>
+        <message name="IDS_AX_ROLE_STEPPER" desc="accessibility role description for a stepper - a control where you can use up/down arrows to increment or decrement it. The name 'stepper' is how this user interface element is described by VoiceOver on Mac OS X; the translation should be consistent with VoiceOver.">
+          stepper
+        </message>
+        <message name="IDS_AX_ROLE_TOGGLE_BUTTON" desc="accessibility role description for a toggle button">
+          toggle button
+        </message>
+      </if>
 
       <message name="IDS_AX_BUTTON_ACTION_VERB" desc="Verb stating the action that will occur when a button is pressed, as used by accessibility.">
         press
@@ -587,10 +582,10 @@
         Value must be <ph name="MAXIMUM_DATE_OR_TIME">$1<ex>12/31/2013</ex></ph> or earlier.
       </message>
       <message name="IDS_FORM_VALIDATION_BAD_INPUT_DATETIME" desc="Heading or short sentence shown when a user specified an incomplete value or an invalid date (such as 02/31/2012) to a date/time form control in a webpage.">
-	Please enter a valid value. The field is incomplete or has an invalid date.
+        Please enter a valid value. The field is incomplete or has an invalid date.
       </message>
       <message name="IDS_FORM_VALIDATION_BAD_INPUT_NUMBER" desc="Heading or short sentence shown when a user entered a non-number string to a number field in a webpage.">
-	Please enter a number.
+        Please enter a number.
       </message>
 
 <!-- The following IDS_FORM_VALIDATION_* messages were taken from Mozilla's dom.properties file.
@@ -675,10 +670,6 @@
         Loading...
       </message>
 
-      <message name="IDS_PDF_LOADING_PROGRESS" desc="A message displayed on the PDF control to indicate loading progress.">
-        Loading document: <ph name="PAGE_NUMBER">%d<ex>3</ex></ph>/<ph name="NUMBER_OF_PAGES">%d<ex>15</ex></ph> pages...
-      </message>
-
       <message name="IDS_PDF_PAGE_LOAD_FAILED" desc="A message displayed on the PDF control to indicate that the PDF document failed to load.">
         Failed to load PDF document
       </message>
diff --git a/webkit/renderer/compositor_bindings/compositor_bindings_tests.gyp b/webkit/renderer/compositor_bindings/compositor_bindings_tests.gyp
index 53978a2..f29a985 100644
--- a/webkit/renderer/compositor_bindings/compositor_bindings_tests.gyp
+++ b/webkit/renderer/compositor_bindings/compositor_bindings_tests.gyp
@@ -39,8 +39,7 @@
         }],
         [ 'os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"', {
           'conditions': [
-            # TODO(dmikurube): Kill linux_use_tcmalloc. http://crbug.com/345554
-            [ '(use_allocator!="none" and use_allocator!="see_use_tcmalloc") or (use_allocator=="see_use_tcmalloc" and linux_use_tcmalloc==1)', {
+            [ 'use_allocator!="none"', {
               'dependencies': [
                 '<(DEPTH)/base/allocator/allocator.gyp:allocator',
               ],
diff --git a/webkit/renderer/compositor_bindings/web_animation_impl.cc b/webkit/renderer/compositor_bindings/web_animation_impl.cc
index c401d5c..92d2fd4 100644
--- a/webkit/renderer/compositor_bindings/web_animation_impl.cc
+++ b/webkit/renderer/compositor_bindings/web_animation_impl.cc
@@ -95,13 +95,51 @@
   animation_->set_time_offset(monotonic_time);
 }
 
+#if WEB_ANIMATION_SUPPORTS_FULL_DIRECTION
+blink::WebAnimation::Direction WebAnimationImpl::direction() const {
+  switch (animation_->direction()) {
+    case cc::Animation::Normal:
+      return DirectionNormal;
+    case cc::Animation::Reverse:
+      return DirectionReverse;
+    case cc::Animation::Alternate:
+      return DirectionAlternate;
+    case cc::Animation::AlternateReverse:
+      return DirectionAlternateReverse;
+    default:
+      NOTREACHED();
+  }
+  return DirectionNormal;
+}
+
+void WebAnimationImpl::setDirection(Direction direction) {
+  switch (direction) {
+    case DirectionNormal:
+      animation_->set_direction(cc::Animation::Normal);
+      break;
+    case DirectionReverse:
+      animation_->set_direction(cc::Animation::Reverse);
+      break;
+    case DirectionAlternate:
+      animation_->set_direction(cc::Animation::Alternate);
+      break;
+    case DirectionAlternateReverse:
+      animation_->set_direction(cc::Animation::AlternateReverse);
+      break;
+  }
+}
+#else
 bool WebAnimationImpl::alternatesDirection() const {
-  return animation_->alternates_direction();
+  return animation_->direction() == cc::Animation::Alternate;
 }
 
 void WebAnimationImpl::setAlternatesDirection(bool alternates) {
-  animation_->set_alternates_direction(alternates);
+  if (alternates)
+    animation_->set_direction(cc::Animation::Alternate);
+  else
+    animation_->set_direction(cc::Animation::Normal);
 }
+#endif
 
 scoped_ptr<cc::Animation> WebAnimationImpl::PassAnimation() {
   animation_->set_needs_synchronized_start_time(true);
diff --git a/webkit/renderer/compositor_bindings/web_animation_impl.h b/webkit/renderer/compositor_bindings/web_animation_impl.h
index 0c248fc..07d72c7 100644
--- a/webkit/renderer/compositor_bindings/web_animation_impl.h
+++ b/webkit/renderer/compositor_bindings/web_animation_impl.h
@@ -33,8 +33,13 @@
   virtual void setStartTime(double monotonic_time);
   virtual double timeOffset() const;
   virtual void setTimeOffset(double monotonic_time);
+#if WEB_ANIMATION_SUPPORTS_FULL_DIRECTION
+  virtual Direction direction() const;
+  virtual void setDirection(Direction);
+#else
   virtual bool alternatesDirection() const;
   virtual void setAlternatesDirection(bool alternates);
+#endif
 
   scoped_ptr<cc::Animation> PassAnimation();
 
diff --git a/webkit/renderer/compositor_bindings/web_animation_unittest.cc b/webkit/renderer/compositor_bindings/web_animation_unittest.cc
index e5be25a..9d0f666 100644
--- a/webkit/renderer/compositor_bindings/web_animation_unittest.cc
+++ b/webkit/renderer/compositor_bindings/web_animation_unittest.cc
@@ -23,7 +23,11 @@
   EXPECT_EQ(1, animation->iterations());
   EXPECT_EQ(0, animation->startTime());
   EXPECT_EQ(0, animation->timeOffset());
+#if WEB_ANIMATION_SUPPORTS_FULL_DIRECTION
+  EXPECT_EQ(WebAnimation::DirectionNormal, animation->direction());
+#else
   EXPECT_FALSE(animation->alternatesDirection());
+#endif
 }
 
 TEST(WebAnimationTest, ModifiedSettings) {
@@ -33,12 +37,22 @@
   animation->setIterations(2);
   animation->setStartTime(2);
   animation->setTimeOffset(2);
+#if WEB_ANIMATION_SUPPORTS_FULL_DIRECTION
+  animation->setDirection(WebAnimation::DirectionReverse);
+#else
   animation->setAlternatesDirection(true);
+#endif
 
   EXPECT_EQ(2, animation->iterations());
   EXPECT_EQ(2, animation->startTime());
   EXPECT_EQ(2, animation->timeOffset());
+#if WEB_ANIMATION_SUPPORTS_FULL_DIRECTION
+  EXPECT_EQ(WebAnimation::DirectionReverse, animation->direction());
+#else
   EXPECT_TRUE(animation->alternatesDirection());
+  animation->setAlternatesDirection(false);
+  EXPECT_FALSE(animation->alternatesDirection());
+#endif
 }
 
 }  // namespace
diff --git a/webkit/renderer/compositor_bindings/web_content_layer_impl.cc b/webkit/renderer/compositor_bindings/web_content_layer_impl.cc
index e337e48..fadafc2 100644
--- a/webkit/renderer/compositor_bindings/web_content_layer_impl.cc
+++ b/webkit/renderer/compositor_bindings/web_content_layer_impl.cc
@@ -51,9 +51,11 @@
   // prepaint-disabling hints (crbug.com/365885).
 }
 
-void WebContentLayerImpl::PaintContents(SkCanvas* canvas,
-                                        const gfx::Rect& clip,
-                                        gfx::RectF* opaque) {
+void WebContentLayerImpl::PaintContents(
+    SkCanvas* canvas,
+    const gfx::Rect& clip,
+    gfx::RectF* opaque,
+    ContentLayerClient::GraphicsContextStatus graphics_context_status) {
   if (!client_)
     return;
 
@@ -61,7 +63,14 @@
   // For picture layers, always record with LCD text.  PictureLayerImpl
   // will turn this off later during rasterization.
   bool use_lcd_text = WebLayerImpl::UsingPictureLayer() || can_use_lcd_text_;
-  client_->paintContents(canvas, clip, use_lcd_text, web_opaque);
+  client_->paintContents(
+      canvas,
+      clip,
+      use_lcd_text,
+      web_opaque,
+      graphics_context_status == ContentLayerClient::GRAPHICS_CONTEXT_ENABLED
+          ? blink::WebContentLayerClient::GraphicsContextEnabled
+          : blink::WebContentLayerClient::GraphicsContextDisabled);
   *opaque = web_opaque;
 }
 
diff --git a/webkit/renderer/compositor_bindings/web_content_layer_impl.h b/webkit/renderer/compositor_bindings/web_content_layer_impl.h
index a6bb7d2..369af10 100644
--- a/webkit/renderer/compositor_bindings/web_content_layer_impl.h
+++ b/webkit/renderer/compositor_bindings/web_content_layer_impl.h
@@ -38,7 +38,9 @@
   // ContentLayerClient implementation.
   virtual void PaintContents(SkCanvas* canvas,
                              const gfx::Rect& clip,
-                             gfx::RectF* opaque) OVERRIDE;
+                             gfx::RectF* opaque,
+                             ContentLayerClient::GraphicsContextStatus
+                                 graphics_context_status) OVERRIDE;
   virtual void DidChangeLayerCanUseLCDText() OVERRIDE;
   virtual bool FillsBoundsCompletely() const OVERRIDE;
 
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-arm.mk b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-arm.mk
index 78c1179..b1267b1 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-arm.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-arm.mk
@@ -63,7 +63,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -113,11 +112,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -206,7 +200,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -256,11 +249,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-arm64.mk b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-arm64.mk
index 7b0e464..94d6cb4 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-arm64.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-arm64.mk
@@ -109,11 +109,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -247,11 +242,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-mips.mk b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-mips.mk
index fdac678..ae6730b 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-mips.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-mips.mk
@@ -112,11 +112,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -254,11 +249,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-x86.mk b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-x86.mk
index 429e2ee..639a961 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-x86.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-x86.mk
@@ -65,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -114,11 +113,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -208,7 +202,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -257,11 +250,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-x86_64.mk b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-x86_64.mk
index 2cf5b44..5477c3c 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-x86_64.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.darwin-x86_64.mk
@@ -65,7 +65,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -114,11 +113,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -208,7 +202,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -257,11 +250,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-arm.mk b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-arm.mk
index 78c1179..b1267b1 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-arm.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-arm.mk
@@ -63,7 +63,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -113,11 +112,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -206,7 +200,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -256,11 +249,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-arm64.mk b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-arm64.mk
index 7b0e464..94d6cb4 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-arm64.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-arm64.mk
@@ -109,11 +109,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -247,11 +242,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-mips.mk b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-mips.mk
index fdac678..ae6730b 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-mips.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-mips.mk
@@ -112,11 +112,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -254,11 +249,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-x86.mk b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-x86.mk
index 429e2ee..639a961 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-x86.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-x86.mk
@@ -65,7 +65,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -114,11 +113,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -208,7 +202,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -257,11 +250,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-x86_64.mk b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-x86_64.mk
index 2cf5b44..5477c3c 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-x86_64.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_bindings.target.linux-x86_64.mk
@@ -65,7 +65,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -114,11 +113,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -208,7 +202,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -257,11 +250,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-arm.mk b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-arm.mk
index c63a145..25bbcee 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-arm.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -91,11 +90,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -168,7 +162,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -216,11 +209,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-arm64.mk b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-arm64.mk
index 8387b9f..a60a8db 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-arm64.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-arm64.mk
@@ -87,11 +87,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -207,11 +202,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-mips.mk b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-mips.mk
index 07315b5..bcda4bc 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-mips.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-mips.mk
@@ -90,11 +90,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -214,11 +209,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-x86.mk b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-x86.mk
index 925cf05..a72a9bc 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-x86.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -92,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -170,7 +164,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -217,11 +210,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-x86_64.mk b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-x86_64.mk
index 2ae8fd1..2a9287c 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-x86_64.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.darwin-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -92,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -170,7 +164,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -217,11 +210,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-arm.mk b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-arm.mk
index c63a145..25bbcee 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-arm.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-arm.mk
@@ -43,7 +43,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -91,11 +90,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -168,7 +162,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -216,11 +209,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-arm64.mk b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-arm64.mk
index 8387b9f..a60a8db 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-arm64.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-arm64.mk
@@ -87,11 +87,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -207,11 +202,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-mips.mk b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-mips.mk
index 07315b5..bcda4bc 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-mips.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-mips.mk
@@ -90,11 +90,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -214,11 +209,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-x86.mk b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-x86.mk
index 925cf05..a72a9bc 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-x86.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-x86.mk
@@ -45,7 +45,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -92,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -170,7 +164,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -217,11 +210,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-x86_64.mk b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-x86_64.mk
index 2ae8fd1..2a9287c 100644
--- a/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-x86_64.mk
+++ b/webkit/renderer/compositor_bindings/webkit_compositor_support.target.linux-x86_64.mk
@@ -45,7 +45,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -92,11 +91,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -170,7 +164,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -217,11 +210,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/webkit_resources.target.darwin-arm.mk b/webkit/webkit_resources.target.darwin-arm.mk
index c65c409..abfc5ea 100644
--- a/webkit/webkit_resources.target.darwin-arm.mk
+++ b/webkit/webkit_resources.target.darwin-arm.mk
@@ -16,10 +16,11 @@
 
 ### Rules for action "webkit_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_recording.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_waiting.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: Generating resources from glue/resources/webkit_resources.grd ($@)"
 	$(hide)cd $(gyp_local_path)/webkit; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../tools/grit/grit.py -i glue/resources/webkit_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc
 
@@ -28,6 +29,7 @@
 
 ### Rules for action "blink_chromium_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_resources.target.darwin-arm64.mk b/webkit/webkit_resources.target.darwin-arm64.mk
index c65c409..abfc5ea 100644
--- a/webkit/webkit_resources.target.darwin-arm64.mk
+++ b/webkit/webkit_resources.target.darwin-arm64.mk
@@ -16,10 +16,11 @@
 
 ### Rules for action "webkit_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_recording.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_waiting.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: Generating resources from glue/resources/webkit_resources.grd ($@)"
 	$(hide)cd $(gyp_local_path)/webkit; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../tools/grit/grit.py -i glue/resources/webkit_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc
 
@@ -28,6 +29,7 @@
 
 ### Rules for action "blink_chromium_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_resources.target.darwin-mips.mk b/webkit/webkit_resources.target.darwin-mips.mk
index c65c409..abfc5ea 100644
--- a/webkit/webkit_resources.target.darwin-mips.mk
+++ b/webkit/webkit_resources.target.darwin-mips.mk
@@ -16,10 +16,11 @@
 
 ### Rules for action "webkit_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_recording.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_waiting.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: Generating resources from glue/resources/webkit_resources.grd ($@)"
 	$(hide)cd $(gyp_local_path)/webkit; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../tools/grit/grit.py -i glue/resources/webkit_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc
 
@@ -28,6 +29,7 @@
 
 ### Rules for action "blink_chromium_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_resources.target.darwin-x86.mk b/webkit/webkit_resources.target.darwin-x86.mk
index c65c409..abfc5ea 100644
--- a/webkit/webkit_resources.target.darwin-x86.mk
+++ b/webkit/webkit_resources.target.darwin-x86.mk
@@ -16,10 +16,11 @@
 
 ### Rules for action "webkit_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_recording.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_waiting.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: Generating resources from glue/resources/webkit_resources.grd ($@)"
 	$(hide)cd $(gyp_local_path)/webkit; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../tools/grit/grit.py -i glue/resources/webkit_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc
 
@@ -28,6 +29,7 @@
 
 ### Rules for action "blink_chromium_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_resources.target.darwin-x86_64.mk b/webkit/webkit_resources.target.darwin-x86_64.mk
index c65c409..abfc5ea 100644
--- a/webkit/webkit_resources.target.darwin-x86_64.mk
+++ b/webkit/webkit_resources.target.darwin-x86_64.mk
@@ -16,10 +16,11 @@
 
 ### Rules for action "webkit_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_recording.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_waiting.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: Generating resources from glue/resources/webkit_resources.grd ($@)"
 	$(hide)cd $(gyp_local_path)/webkit; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../tools/grit/grit.py -i glue/resources/webkit_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc
 
@@ -28,6 +29,7 @@
 
 ### Rules for action "blink_chromium_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_resources.target.linux-arm.mk b/webkit/webkit_resources.target.linux-arm.mk
index c65c409..abfc5ea 100644
--- a/webkit/webkit_resources.target.linux-arm.mk
+++ b/webkit/webkit_resources.target.linux-arm.mk
@@ -16,10 +16,11 @@
 
 ### Rules for action "webkit_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_recording.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_waiting.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: Generating resources from glue/resources/webkit_resources.grd ($@)"
 	$(hide)cd $(gyp_local_path)/webkit; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../tools/grit/grit.py -i glue/resources/webkit_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc
 
@@ -28,6 +29,7 @@
 
 ### Rules for action "blink_chromium_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_resources.target.linux-arm64.mk b/webkit/webkit_resources.target.linux-arm64.mk
index c65c409..abfc5ea 100644
--- a/webkit/webkit_resources.target.linux-arm64.mk
+++ b/webkit/webkit_resources.target.linux-arm64.mk
@@ -16,10 +16,11 @@
 
 ### Rules for action "webkit_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_recording.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_waiting.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: Generating resources from glue/resources/webkit_resources.grd ($@)"
 	$(hide)cd $(gyp_local_path)/webkit; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../tools/grit/grit.py -i glue/resources/webkit_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc
 
@@ -28,6 +29,7 @@
 
 ### Rules for action "blink_chromium_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_resources.target.linux-mips.mk b/webkit/webkit_resources.target.linux-mips.mk
index c65c409..abfc5ea 100644
--- a/webkit/webkit_resources.target.linux-mips.mk
+++ b/webkit/webkit_resources.target.linux-mips.mk
@@ -16,10 +16,11 @@
 
 ### Rules for action "webkit_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_recording.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_waiting.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: Generating resources from glue/resources/webkit_resources.grd ($@)"
 	$(hide)cd $(gyp_local_path)/webkit; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../tools/grit/grit.py -i glue/resources/webkit_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc
 
@@ -28,6 +29,7 @@
 
 ### Rules for action "blink_chromium_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_resources.target.linux-x86.mk b/webkit/webkit_resources.target.linux-x86.mk
index c65c409..abfc5ea 100644
--- a/webkit/webkit_resources.target.linux-x86.mk
+++ b/webkit/webkit_resources.target.linux-x86.mk
@@ -16,10 +16,11 @@
 
 ### Rules for action "webkit_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_recording.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_waiting.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: Generating resources from glue/resources/webkit_resources.grd ($@)"
 	$(hide)cd $(gyp_local_path)/webkit; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../tools/grit/grit.py -i glue/resources/webkit_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc
 
@@ -28,6 +29,7 @@
 
 ### Rules for action "blink_chromium_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_resources.target.linux-x86_64.mk b/webkit/webkit_resources.target.linux-x86_64.mk
index c65c409..abfc5ea 100644
--- a/webkit/webkit_resources.target.linux-x86_64.mk
+++ b/webkit/webkit_resources.target.linux-x86_64.mk
@@ -16,10 +16,11 @@
 
 ### Rules for action "webkit_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_recording.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/input_speech_waiting.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_resources.h: $(LOCAL_PATH)/tools/gritsettings/resource_ids $(LOCAL_PATH)/webkit/glue/resources/webkit_resources.grd $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_closedcaption_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_fullscreen_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_overlay_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_pause_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_play_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level0_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level1_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level2_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_sound_level3_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_disabled.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_down.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/mediaplayer_volume_slider_thumb_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/password_generation_hover.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_cancel_pressed.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/search_magnifier_results.png $(LOCAL_PATH)/webkit/glue/resources/default_100_percent/textarea_resize_corner.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/broken_image.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/pan_icon.png $(LOCAL_PATH)/webkit/glue/resources/default_200_percent/textarea_resize_corner.png $(LOCAL_PATH)/tools/grit/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit.py $(LOCAL_PATH)/tools/grit/grit/__init__.py $(LOCAL_PATH)/tools/grit/grit/clique.py $(LOCAL_PATH)/tools/grit/grit/constants.py $(LOCAL_PATH)/tools/grit/grit/exception.py $(LOCAL_PATH)/tools/grit/grit/extern/BogoFP.py $(LOCAL_PATH)/tools/grit/grit/extern/FP.py $(LOCAL_PATH)/tools/grit/grit/extern/__init__.py $(LOCAL_PATH)/tools/grit/grit/extern/tclib.py $(LOCAL_PATH)/tools/grit/grit/format/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/android_xml.py $(LOCAL_PATH)/tools/grit/grit/format/c_format.py $(LOCAL_PATH)/tools/grit/grit/format/chrome_messages_json.py $(LOCAL_PATH)/tools/grit/grit/format/data_pack.py $(LOCAL_PATH)/tools/grit/grit/format/html_inline.py $(LOCAL_PATH)/tools/grit/grit/format/js_map_format.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/PRESUBMIT.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/policy_template_generator.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/template_formatter.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writer_configuration.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/__init__.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adm_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/adml_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/admx_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/doc_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/ios_plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/json_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/mock_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_helper.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_strings_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/plist_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/reg_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/template_writer.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/writer_unittest_common.py $(LOCAL_PATH)/tools/grit/grit/format/policy_templates/writers/xml_formatted_writer.py $(LOCAL_PATH)/tools/grit/grit/format/rc.py $(LOCAL_PATH)/tools/grit/grit/format/rc_header.py $(LOCAL_PATH)/tools/grit/grit/format/repack.py $(LOCAL_PATH)/tools/grit/grit/format/resource_map.py $(LOCAL_PATH)/tools/grit/grit/gather/__init__.py $(LOCAL_PATH)/tools/grit/grit/gather/admin_template.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_html.py $(LOCAL_PATH)/tools/grit/grit/gather/chrome_scaled_image.py $(LOCAL_PATH)/tools/grit/grit/gather/igoogle_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/interface.py $(LOCAL_PATH)/tools/grit/grit/gather/json_loader.py $(LOCAL_PATH)/tools/grit/grit/gather/muppet_strings.py $(LOCAL_PATH)/tools/grit/grit/gather/policy_json.py $(LOCAL_PATH)/tools/grit/grit/gather/rc.py $(LOCAL_PATH)/tools/grit/grit/gather/regexp.py $(LOCAL_PATH)/tools/grit/grit/gather/skeleton_gatherer.py $(LOCAL_PATH)/tools/grit/grit/gather/tr_html.py $(LOCAL_PATH)/tools/grit/grit/gather/txt.py $(LOCAL_PATH)/tools/grit/grit/grd_reader.py $(LOCAL_PATH)/tools/grit/grit/grit_runner.py $(LOCAL_PATH)/tools/grit/grit/lazy_re.py $(LOCAL_PATH)/tools/grit/grit/node/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/base.py $(LOCAL_PATH)/tools/grit/grit/node/custom/__init__.py $(LOCAL_PATH)/tools/grit/grit/node/custom/filename.py $(LOCAL_PATH)/tools/grit/grit/node/empty.py $(LOCAL_PATH)/tools/grit/grit/node/include.py $(LOCAL_PATH)/tools/grit/grit/node/io.py $(LOCAL_PATH)/tools/grit/grit/node/mapping.py $(LOCAL_PATH)/tools/grit/grit/node/message.py $(LOCAL_PATH)/tools/grit/grit/node/misc.py $(LOCAL_PATH)/tools/grit/grit/node/structure.py $(LOCAL_PATH)/tools/grit/grit/node/variant.py $(LOCAL_PATH)/tools/grit/grit/pseudo.py $(LOCAL_PATH)/tools/grit/grit/pseudo_rtl.py $(LOCAL_PATH)/tools/grit/grit/scons.py $(LOCAL_PATH)/tools/grit/grit/shortcuts.py $(LOCAL_PATH)/tools/grit/grit/shortcuts_unittests.py $(LOCAL_PATH)/tools/grit/grit/tclib.py $(LOCAL_PATH)/tools/grit/grit/test_suite_all.py $(LOCAL_PATH)/tools/grit/grit/tool/__init__.py $(LOCAL_PATH)/tools/grit/grit/tool/android2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/build.py $(LOCAL_PATH)/tools/grit/grit/tool/buildinfo.py $(LOCAL_PATH)/tools/grit/grit/tool/count.py $(LOCAL_PATH)/tools/grit/grit/tool/diff_structures.py $(LOCAL_PATH)/tools/grit/grit/tool/interface.py $(LOCAL_PATH)/tools/grit/grit/tool/menu_from_parts.py $(LOCAL_PATH)/tools/grit/grit/tool/newgrd.py $(LOCAL_PATH)/tools/grit/grit/tool/postprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/preprocess_interface.py $(LOCAL_PATH)/tools/grit/grit/tool/rc2grd.py $(LOCAL_PATH)/tools/grit/grit/tool/resize.py $(LOCAL_PATH)/tools/grit/grit/tool/test.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_postprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/toolbar_preprocess.py $(LOCAL_PATH)/tools/grit/grit/tool/transl2tc.py $(LOCAL_PATH)/tools/grit/grit/tool/unit.py $(LOCAL_PATH)/tools/grit/grit/tool/xmb.py $(LOCAL_PATH)/tools/grit/grit/util.py $(LOCAL_PATH)/tools/grit/grit/xtb_reader.py $(LOCAL_PATH)/tools/grit/grit_info.py $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: Generating resources from glue/resources/webkit_resources.grd ($@)"
 	$(hide)cd $(gyp_local_path)/webkit; mkdir -p $(gyp_shared_intermediate_dir)/webkit/grit $(gyp_shared_intermediate_dir)/webkit; python ../tools/grit/grit.py -i glue/resources/webkit_resources.grd build -f ../tools/gritsettings/resource_ids -o "$(gyp_shared_intermediate_dir)/webkit" -D _chromium -E "CHROMIUM_BUILD=chromium" -t android -E "ANDROID_JAVA_TAGGED_ONLY=true" -D enable_printing -D use_concatenated_impulse_responses -D enable_webrtc
 
@@ -28,6 +29,7 @@
 
 ### Rules for action "blink_chromium_resources":
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/blink_resources.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_storage_browser.target.darwin-arm.mk b/webkit/webkit_storage_browser.target.darwin-arm.mk
index 79d0724..0076548 100644
--- a/webkit/webkit_storage_browser.target.darwin-arm.mk
+++ b/webkit/webkit_storage_browser.target.darwin-arm.mk
@@ -125,7 +125,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -176,11 +175,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -274,7 +268,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -325,11 +318,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/webkit_storage_browser.target.darwin-arm64.mk b/webkit/webkit_storage_browser.target.darwin-arm64.mk
index a646f91..28f24ee 100644
--- a/webkit/webkit_storage_browser.target.darwin-arm64.mk
+++ b/webkit/webkit_storage_browser.target.darwin-arm64.mk
@@ -172,11 +172,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -316,11 +311,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/webkit_storage_browser.target.darwin-mips.mk b/webkit/webkit_storage_browser.target.darwin-mips.mk
index 6260993..df142fa 100644
--- a/webkit/webkit_storage_browser.target.darwin-mips.mk
+++ b/webkit/webkit_storage_browser.target.darwin-mips.mk
@@ -175,11 +175,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -323,11 +318,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/webkit_storage_browser.target.darwin-x86.mk b/webkit/webkit_storage_browser.target.darwin-x86.mk
index 53bb2c8..c2b367a 100644
--- a/webkit/webkit_storage_browser.target.darwin-x86.mk
+++ b/webkit/webkit_storage_browser.target.darwin-x86.mk
@@ -127,7 +127,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -176,11 +175,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -275,7 +269,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -324,11 +317,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/webkit_storage_browser.target.darwin-x86_64.mk b/webkit/webkit_storage_browser.target.darwin-x86_64.mk
index 9a3b464..04a8bd4 100644
--- a/webkit/webkit_storage_browser.target.darwin-x86_64.mk
+++ b/webkit/webkit_storage_browser.target.darwin-x86_64.mk
@@ -127,7 +127,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -177,11 +176,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -276,7 +270,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -326,11 +319,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/webkit_storage_browser.target.linux-arm.mk b/webkit/webkit_storage_browser.target.linux-arm.mk
index 79d0724..0076548 100644
--- a/webkit/webkit_storage_browser.target.linux-arm.mk
+++ b/webkit/webkit_storage_browser.target.linux-arm.mk
@@ -125,7 +125,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -176,11 +175,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -274,7 +268,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -325,11 +318,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/webkit_storage_browser.target.linux-arm64.mk b/webkit/webkit_storage_browser.target.linux-arm64.mk
index a646f91..28f24ee 100644
--- a/webkit/webkit_storage_browser.target.linux-arm64.mk
+++ b/webkit/webkit_storage_browser.target.linux-arm64.mk
@@ -172,11 +172,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -316,11 +311,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/webkit_storage_browser.target.linux-mips.mk b/webkit/webkit_storage_browser.target.linux-mips.mk
index 6260993..df142fa 100644
--- a/webkit/webkit_storage_browser.target.linux-mips.mk
+++ b/webkit/webkit_storage_browser.target.linux-mips.mk
@@ -175,11 +175,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -323,11 +318,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/webkit_storage_browser.target.linux-x86.mk b/webkit/webkit_storage_browser.target.linux-x86.mk
index 53bb2c8..c2b367a 100644
--- a/webkit/webkit_storage_browser.target.linux-x86.mk
+++ b/webkit/webkit_storage_browser.target.linux-x86.mk
@@ -127,7 +127,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -176,11 +175,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -275,7 +269,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -324,11 +317,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/webkit_storage_browser.target.linux-x86_64.mk b/webkit/webkit_storage_browser.target.linux-x86_64.mk
index 9a3b464..04a8bd4 100644
--- a/webkit/webkit_storage_browser.target.linux-x86_64.mk
+++ b/webkit/webkit_storage_browser.target.linux-x86_64.mk
@@ -127,7 +127,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -177,11 +176,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
@@ -276,7 +270,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -326,11 +319,6 @@
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
 	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_SUPPORT_LEGACY_N32_NAME' \
-	'-DSK_SUPPORT_LEGACY_PROCXFERMODE' \
-	'-DSK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_HEADERS' \
-	'-DSK_SUPPORT_LEGACY_PICTURE_CAN_RECORD' \
-	'-DSK_SUPPORT_DEPRECATED_RECORD_FLAGS' \
 	'-DSK_SUPPORT_LEGACY_BLURMASKFILTER_STYLE' \
 	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
 	'-DSK_BUILD_FOR_ANDROID' \
diff --git a/webkit/webkit_storage_common.target.darwin-arm.mk b/webkit/webkit_storage_common.target.darwin-arm.mk
index 5e12705..f0f3c51 100644
--- a/webkit/webkit_storage_common.target.darwin-arm.mk
+++ b/webkit/webkit_storage_common.target.darwin-arm.mk
@@ -50,7 +50,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -142,7 +141,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/webkit/webkit_storage_common.target.darwin-x86.mk b/webkit/webkit_storage_common.target.darwin-x86.mk
index c5d35e4..fd03695 100644
--- a/webkit/webkit_storage_common.target.darwin-x86.mk
+++ b/webkit/webkit_storage_common.target.darwin-x86.mk
@@ -52,7 +52,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -143,7 +142,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/webkit/webkit_storage_common.target.darwin-x86_64.mk b/webkit/webkit_storage_common.target.darwin-x86_64.mk
index db2627e..f9d66ff 100644
--- a/webkit/webkit_storage_common.target.darwin-x86_64.mk
+++ b/webkit/webkit_storage_common.target.darwin-x86_64.mk
@@ -52,7 +52,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/webkit/webkit_storage_common.target.linux-arm.mk b/webkit/webkit_storage_common.target.linux-arm.mk
index 5e12705..f0f3c51 100644
--- a/webkit/webkit_storage_common.target.linux-arm.mk
+++ b/webkit/webkit_storage_common.target.linux-arm.mk
@@ -50,7 +50,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
@@ -142,7 +141,6 @@
 	-pipe \
 	-fPIC \
 	-fno-tree-sra \
-	-fuse-ld=gold \
 	-Wno-psabi \
 	-ffunction-sections \
 	-funwind-tables \
diff --git a/webkit/webkit_storage_common.target.linux-x86.mk b/webkit/webkit_storage_common.target.linux-x86.mk
index c5d35e4..fd03695 100644
--- a/webkit/webkit_storage_common.target.linux-x86.mk
+++ b/webkit/webkit_storage_common.target.linux-x86.mk
@@ -52,7 +52,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -143,7 +142,6 @@
 	-mfpmath=sse \
 	-mmmx \
 	-m32 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/webkit/webkit_storage_common.target.linux-x86_64.mk b/webkit/webkit_storage_common.target.linux-x86_64.mk
index db2627e..f9d66ff 100644
--- a/webkit/webkit_storage_common.target.linux-x86_64.mk
+++ b/webkit/webkit_storage_common.target.linux-x86_64.mk
@@ -52,7 +52,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
@@ -144,7 +143,6 @@
 	-Wno-unused-local-typedefs \
 	-m64 \
 	-march=x86-64 \
-	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
 	-g \
diff --git a/webkit/webkit_strings.target.darwin-arm.mk b/webkit/webkit_strings.target.darwin-arm.mk
index aea825c..25405b3 100644
--- a/webkit/webkit_strings.target.darwin-arm.mk
+++ b/webkit/webkit_strings.target.darwin-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "webkit_strings":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_strings.target.darwin-arm64.mk b/webkit/webkit_strings.target.darwin-arm64.mk
index aea825c..25405b3 100644
--- a/webkit/webkit_strings.target.darwin-arm64.mk
+++ b/webkit/webkit_strings.target.darwin-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "webkit_strings":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_strings.target.darwin-mips.mk b/webkit/webkit_strings.target.darwin-mips.mk
index aea825c..25405b3 100644
--- a/webkit/webkit_strings.target.darwin-mips.mk
+++ b/webkit/webkit_strings.target.darwin-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "webkit_strings":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_strings.target.darwin-x86.mk b/webkit/webkit_strings.target.darwin-x86.mk
index aea825c..25405b3 100644
--- a/webkit/webkit_strings.target.darwin-x86.mk
+++ b/webkit/webkit_strings.target.darwin-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "webkit_strings":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_strings.target.darwin-x86_64.mk b/webkit/webkit_strings.target.darwin-x86_64.mk
index aea825c..25405b3 100644
--- a/webkit/webkit_strings.target.darwin-x86_64.mk
+++ b/webkit/webkit_strings.target.darwin-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "webkit_strings":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_strings.target.linux-arm.mk b/webkit/webkit_strings.target.linux-arm.mk
index aea825c..25405b3 100644
--- a/webkit/webkit_strings.target.linux-arm.mk
+++ b/webkit/webkit_strings.target.linux-arm.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "webkit_strings":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_strings.target.linux-arm64.mk b/webkit/webkit_strings.target.linux-arm64.mk
index aea825c..25405b3 100644
--- a/webkit/webkit_strings.target.linux-arm64.mk
+++ b/webkit/webkit_strings.target.linux-arm64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "webkit_strings":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_strings.target.linux-mips.mk b/webkit/webkit_strings.target.linux-mips.mk
index aea825c..25405b3 100644
--- a/webkit/webkit_strings.target.linux-mips.mk
+++ b/webkit/webkit_strings.target.linux-mips.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "webkit_strings":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_strings.target.linux-x86.mk b/webkit/webkit_strings.target.linux-x86.mk
index aea825c..25405b3 100644
--- a/webkit/webkit_strings.target.linux-x86.mk
+++ b/webkit/webkit_strings.target.linux-x86.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "webkit_strings":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/webkit/webkit_strings.target.linux-x86_64.mk b/webkit/webkit_strings.target.linux-x86_64.mk
index aea825c..25405b3 100644
--- a/webkit/webkit_strings.target.linux-x86_64.mk
+++ b/webkit/webkit_strings.target.linux-x86_64.mk
@@ -16,6 +16,7 @@
 
 ### Rules for action "webkit_strings":
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/webkit/grit/webkit_strings.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
diff --git a/win8/metro_driver/chrome_app_view.cc b/win8/metro_driver/chrome_app_view.cc
index 3a9d23e..87cdf37 100644
--- a/win8/metro_driver/chrome_app_view.cc
+++ b/win8/metro_driver/chrome_app_view.cc
@@ -777,7 +777,7 @@
   // process. If yes then fire the notification once for when the OSK is shown
   // and once for when it is hidden.
   // TODO(ananta)
-  // Take this out when the documented input pane notifcation issues are
+  // Take this out when the documented input pane notification issues are
   // addressed.
   HWND osk = ::FindWindow(kOSKClassName, NULL);
   if (::IsWindow(osk)) {